From a171ada38b7f6f6e4f517cab0bdecc5b4160a2c8 Mon Sep 17 00:00:00 2001 From: Lord Date: Sat, 2 Oct 2021 13:31:19 +0200 Subject: [PATCH] add prepared venv --- .gitignore | 4 - venv/Include/site/python3.9/pygame/_camera.h | 27 + venv/Include/site/python3.9/pygame/_pygame.h | 350 + venv/Include/site/python3.9/pygame/_surface.h | 31 + venv/Include/site/python3.9/pygame/camera.h | 205 + .../site/python3.9/pygame/fastevents.h | 48 + venv/Include/site/python3.9/pygame/font.h | 15 + venv/Include/site/python3.9/pygame/freetype.h | 123 + .../site/python3.9/pygame/include/_pygame.h | 649 ++ .../site/python3.9/pygame/include/bitmask.h | 149 + .../site/python3.9/pygame/include/pgcompat.h | 180 + .../site/python3.9/pygame/include/pgimport.h | 80 + .../python3.9/pygame/include/pgplatform.h | 91 + .../site/python3.9/pygame/include/pygame.h | 34 + .../pygame/include/pygame_bufferproxy.h | 59 + .../python3.9/pygame/include/pygame_font.h | 53 + .../pygame/include/pygame_freetype.h | 43 + .../python3.9/pygame/include/pygame_mask.h | 47 + .../python3.9/pygame/include/pygame_mixer.h | 82 + .../site/python3.9/pygame/include/sse2neon.h | 3676 +++++++ venv/Include/site/python3.9/pygame/mask.h | 7 + venv/Include/site/python3.9/pygame/mixer.h | 14 + venv/Include/site/python3.9/pygame/palette.h | 123 + .../site/python3.9/pygame/pgarrinter.h | 26 + .../site/python3.9/pygame/pgbufferproxy.h | 7 + venv/Include/site/python3.9/pygame/pgcompat.h | 207 + venv/Include/site/python3.9/pygame/pgimport.h | 13 + venv/Include/site/python3.9/pygame/pgopengl.h | 18 + .../site/python3.9/pygame/pgplatform.h | 38 + venv/Include/site/python3.9/pygame/pygame.h | 32 + venv/Include/site/python3.9/pygame/scrap.h | 148 + venv/Include/site/python3.9/pygame/surface.h | 384 + .../site-packages/_distutils_hack/__init__.py | 128 + .../site-packages/_distutils_hack/override.py | 1 + .../site-packages/distutils-precedence.pth | 1 + .../numpy-1.20.2.dist-info/INSTALLER | 1 + .../numpy-1.20.2.dist-info/LICENSE.txt | 938 ++ .../LICENSES_bundled.txt | 17 + .../numpy-1.20.2.dist-info/METADATA | 56 + .../numpy-1.20.2.dist-info/RECORD | 1064 ++ .../numpy-1.20.2.dist-info/REQUESTED | 0 .../numpy-1.20.2.dist-info/WHEEL | 5 + .../numpy-1.20.2.dist-info/entry_points.txt | 3 + .../numpy-1.20.2.dist-info/top_level.txt | 1 + ...YO3P26ULGBQYHGQO7J4.gfortran-win_amd64.dll | Bin 0 -> 34413408 bytes venv/Lib/site-packages/numpy/LICENSE.txt | 938 ++ venv/Lib/site-packages/numpy/__config__.py | 78 + .../numpy/__init__.cython-30.pxd | 1055 ++ venv/Lib/site-packages/numpy/__init__.pxd | 1020 ++ venv/Lib/site-packages/numpy/__init__.py | 410 + venv/Lib/site-packages/numpy/__init__.pyi | 2277 +++++ .../site-packages/numpy/_distributor_init.py | 32 + venv/Lib/site-packages/numpy/_globals.py | 79 + venv/Lib/site-packages/numpy/_pytesttester.py | 213 + venv/Lib/site-packages/numpy/char.pyi | 56 + .../site-packages/numpy/compat/__init__.py | 18 + .../site-packages/numpy/compat/_inspect.py | 191 + venv/Lib/site-packages/numpy/compat/py3k.py | 136 + venv/Lib/site-packages/numpy/compat/setup.py | 10 + .../numpy/compat/tests/__init__.py | 0 .../numpy/compat/tests/test_compat.py | 19 + venv/Lib/site-packages/numpy/conftest.py | 119 + venv/Lib/site-packages/numpy/core/__init__.py | 166 + .../Lib/site-packages/numpy/core/__init__.pyi | 0 .../site-packages/numpy/core/_add_newdocs.py | 6284 ++++++++++++ .../numpy/core/_add_newdocs_scalars.py | 251 + venv/Lib/site-packages/numpy/core/_asarray.py | 411 + .../Lib/site-packages/numpy/core/_asarray.pyi | 77 + venv/Lib/site-packages/numpy/core/_dtype.py | 342 + .../site-packages/numpy/core/_dtype_ctypes.py | 117 + .../site-packages/numpy/core/_exceptions.py | 197 + .../Lib/site-packages/numpy/core/_internal.py | 873 ++ .../site-packages/numpy/core/_internal.pyi | 18 + venv/Lib/site-packages/numpy/core/_methods.py | 289 + .../numpy/core/_string_helpers.py | 100 + .../site-packages/numpy/core/_type_aliases.py | 243 + .../numpy/core/_type_aliases.pyi | 19 + .../site-packages/numpy/core/_ufunc_config.py | 450 + .../numpy/core/_ufunc_config.pyi | 43 + .../site-packages/numpy/core/arrayprint.py | 1630 +++ .../Lib/site-packages/numpy/core/cversions.py | 13 + .../site-packages/numpy/core/defchararray.py | 2795 ++++++ .../site-packages/numpy/core/einsumfunc.py | 1433 +++ .../site-packages/numpy/core/fromnumeric.py | 3768 +++++++ .../site-packages/numpy/core/fromnumeric.pyi | 483 + .../site-packages/numpy/core/function_base.py | 529 + .../numpy/core/function_base.pyi | 56 + .../numpy/core/generate_numpy_api.py | 239 + .../Lib/site-packages/numpy/core/getlimits.py | 564 ++ .../core/include/numpy/__multiarray_api.h | 1540 +++ .../numpy/core/include/numpy/__ufunc_api.h | 311 + .../numpy/_neighborhood_iterator_imp.h | 90 + .../numpy/core/include/numpy/_numpyconfig.h | 29 + .../numpy/core/include/numpy/arrayobject.h | 11 + .../numpy/core/include/numpy/arrayscalars.h | 182 + .../numpy/core/include/numpy/halffloat.h | 70 + .../core/include/numpy/multiarray_api.txt | 2474 +++++ .../numpy/core/include/numpy/ndarrayobject.h | 268 + .../numpy/core/include/numpy/ndarraytypes.h | 1960 ++++ .../numpy/core/include/numpy/noprefix.h | 212 + .../include/numpy/npy_1_7_deprecated_api.h | 125 + .../numpy/core/include/numpy/npy_3kcompat.h | 585 ++ .../numpy/core/include/numpy/npy_common.h | 1108 +++ .../numpy/core/include/numpy/npy_cpu.h | 119 + .../numpy/core/include/numpy/npy_endian.h | 73 + .../numpy/core/include/numpy/npy_interrupt.h | 56 + .../numpy/core/include/numpy/npy_math.h | 597 ++ .../include/numpy/npy_no_deprecated_api.h | 19 + .../numpy/core/include/numpy/npy_os.h | 30 + .../numpy/core/include/numpy/numpyconfig.h | 46 + .../numpy/core/include/numpy/old_defines.h | 187 + .../numpy/core/include/numpy/oldnumeric.h | 25 + .../numpy/core/include/numpy/random/bitgen.h | 20 + .../core/include/numpy/random/distributions.h | 208 + .../numpy/core/include/numpy/ufunc_api.txt | 333 + .../numpy/core/include/numpy/ufuncobject.h | 369 + .../numpy/core/include/numpy/utils.h | 37 + .../numpy/core/lib/npy-pkg-config/mlib.ini | 12 + .../numpy/core/lib/npy-pkg-config/npymath.ini | 20 + .../site-packages/numpy/core/lib/npymath.lib | Bin 0 -> 106590 bytes venv/Lib/site-packages/numpy/core/machar.py | 342 + venv/Lib/site-packages/numpy/core/memmap.py | 337 + .../site-packages/numpy/core/multiarray.py | 1673 ++++ venv/Lib/site-packages/numpy/core/numeric.py | 2544 +++++ venv/Lib/site-packages/numpy/core/numeric.pyi | 189 + .../site-packages/numpy/core/numerictypes.py | 672 ++ .../site-packages/numpy/core/numerictypes.pyi | 29 + .../Lib/site-packages/numpy/core/overrides.py | 231 + venv/Lib/site-packages/numpy/core/records.py | 1101 +++ venv/Lib/site-packages/numpy/core/setup.py | 1025 ++ .../site-packages/numpy/core/setup_common.py | 449 + .../site-packages/numpy/core/shape_base.py | 901 ++ .../site-packages/numpy/core/shape_base.pyi | 41 + .../numpy/core/tests/__init__.py | 0 .../numpy/core/tests/_locales.py | 74 + .../numpy/core/tests/data/astype_copy.pkl | Bin 0 -> 716 bytes .../core/tests/data/recarray_from_file.fits | Bin 0 -> 8640 bytes .../tests/data/umath-validation-set-README | 15 + .../core/tests/data/umath-validation-set-cos | 665 ++ .../core/tests/data/umath-validation-set-exp | 412 + .../core/tests/data/umath-validation-set-log | 271 + .../core/tests/data/umath-validation-set-sin | 660 ++ .../numpy/core/tests/examples/checks.pyx | 30 + .../numpy/core/tests/examples/setup.py | 25 + .../numpy/core/tests/test__exceptions.py | 58 + .../numpy/core/tests/test_abc.py | 54 + .../numpy/core/tests/test_api.py | 587 ++ .../numpy/core/tests/test_array_coercion.py | 733 ++ .../numpy/core/tests/test_arrayprint.py | 961 ++ .../core/tests/test_casting_unittests.py | 301 + .../numpy/core/tests/test_conversion_utils.py | 205 + .../numpy/core/tests/test_cpu_dispatcher.py | 42 + .../numpy/core/tests/test_cpu_features.py | 171 + .../numpy/core/tests/test_cython.py | 134 + .../numpy/core/tests/test_datetime.py | 2413 +++++ .../numpy/core/tests/test_defchararray.py | 673 ++ .../numpy/core/tests/test_deprecations.py | 873 ++ .../numpy/core/tests/test_dtype.py | 1428 +++ .../numpy/core/tests/test_einsum.py | 1062 ++ .../numpy/core/tests/test_errstate.py | 59 + .../numpy/core/tests/test_extint128.py | 219 + .../numpy/core/tests/test_function_base.py | 409 + .../numpy/core/tests/test_getlimits.py | 121 + .../numpy/core/tests/test_half.py | 554 ++ .../numpy/core/tests/test_indexerrors.py | 133 + .../numpy/core/tests/test_indexing.py | 1395 +++ .../numpy/core/tests/test_item_selection.py | 86 + .../numpy/core/tests/test_longdouble.py | 369 + .../numpy/core/tests/test_machar.py | 30 + .../numpy/core/tests/test_mem_overlap.py | 926 ++ .../numpy/core/tests/test_memmap.py | 218 + .../numpy/core/tests/test_multiarray.py | 8743 +++++++++++++++++ .../numpy/core/tests/test_nditer.py | 2968 ++++++ .../numpy/core/tests/test_numeric.py | 3472 +++++++ .../numpy/core/tests/test_numerictypes.py | 554 ++ .../numpy/core/tests/test_overrides.py | 583 ++ .../numpy/core/tests/test_print.py | 200 + .../numpy/core/tests/test_protocols.py | 44 + .../numpy/core/tests/test_records.py | 520 + .../numpy/core/tests/test_regression.py | 2526 +++++ .../numpy/core/tests/test_scalar_ctors.py | 115 + .../numpy/core/tests/test_scalar_methods.py | 103 + .../numpy/core/tests/test_scalarbuffer.py | 154 + .../numpy/core/tests/test_scalarinherit.py | 99 + .../numpy/core/tests/test_scalarmath.py | 709 ++ .../numpy/core/tests/test_scalarprint.py | 322 + .../numpy/core/tests/test_shape_base.py | 765 ++ .../numpy/core/tests/test_simd.py | 638 ++ .../numpy/core/tests/test_simd_module.py | 97 + .../numpy/core/tests/test_ufunc.py | 2159 ++++ .../numpy/core/tests/test_umath.py | 3473 +++++++ .../numpy/core/tests/test_umath_accuracy.py | 59 + .../numpy/core/tests/test_umath_complex.py | 610 ++ .../numpy/core/tests/test_unicode.py | 362 + venv/Lib/site-packages/numpy/core/umath.py | 36 + .../site-packages/numpy/core/umath_tests.py | 13 + venv/Lib/site-packages/numpy/ctypeslib.py | 538 + venv/Lib/site-packages/numpy/ctypeslib.pyi | 10 + .../numpy/distutils/__config__.py | 78 + .../site-packages/numpy/distutils/__init__.py | 51 + .../numpy/distutils/__init__.pyi | 4 + .../numpy/distutils/_shell_utils.py | 91 + .../numpy/distutils/ccompiler.py | 791 ++ .../numpy/distutils/ccompiler_opt.py | 2535 +++++ .../numpy/distutils/checks/cpu_asimd.c | 25 + .../numpy/distutils/checks/cpu_asimddp.c | 15 + .../numpy/distutils/checks/cpu_asimdfhm.c | 17 + .../numpy/distutils/checks/cpu_asimdhp.c | 14 + .../numpy/distutils/checks/cpu_avx.c | 7 + .../numpy/distutils/checks/cpu_avx2.c | 7 + .../numpy/distutils/checks/cpu_avx512_clx.c | 8 + .../numpy/distutils/checks/cpu_avx512_cnl.c | 10 + .../numpy/distutils/checks/cpu_avx512_icl.c | 12 + .../numpy/distutils/checks/cpu_avx512_knl.c | 11 + .../numpy/distutils/checks/cpu_avx512_knm.c | 17 + .../numpy/distutils/checks/cpu_avx512_skx.c | 12 + .../numpy/distutils/checks/cpu_avx512cd.c | 7 + .../numpy/distutils/checks/cpu_avx512f.c | 7 + .../numpy/distutils/checks/cpu_f16c.c | 9 + .../numpy/distutils/checks/cpu_fma3.c | 8 + .../numpy/distutils/checks/cpu_fma4.c | 12 + .../numpy/distutils/checks/cpu_neon.c | 15 + .../numpy/distutils/checks/cpu_neon_fp16.c | 11 + .../numpy/distutils/checks/cpu_neon_vfpv4.c | 19 + .../numpy/distutils/checks/cpu_popcnt.c | 23 + .../numpy/distutils/checks/cpu_sse.c | 7 + .../numpy/distutils/checks/cpu_sse2.c | 7 + .../numpy/distutils/checks/cpu_sse3.c | 7 + .../numpy/distutils/checks/cpu_sse41.c | 7 + .../numpy/distutils/checks/cpu_sse42.c | 7 + .../numpy/distutils/checks/cpu_ssse3.c | 7 + .../numpy/distutils/checks/cpu_vsx.c | 21 + .../numpy/distutils/checks/cpu_vsx2.c | 13 + .../numpy/distutils/checks/cpu_vsx3.c | 13 + .../numpy/distutils/checks/cpu_xop.c | 12 + .../distutils/checks/extra_avx512bw_mask.c | 18 + .../distutils/checks/extra_avx512dq_mask.c | 16 + .../distutils/checks/extra_avx512f_reduce.c | 41 + .../numpy/distutils/checks/test_flags.c | 1 + .../numpy/distutils/command/__init__.py | 41 + .../numpy/distutils/command/autodist.py | 148 + .../numpy/distutils/command/bdist_rpm.py | 22 + .../numpy/distutils/command/build.py | 61 + .../numpy/distutils/command/build_clib.py | 401 + .../numpy/distutils/command/build_ext.py | 678 ++ .../numpy/distutils/command/build_py.py | 31 + .../numpy/distutils/command/build_scripts.py | 49 + .../numpy/distutils/command/build_src.py | 773 ++ .../numpy/distutils/command/config.py | 516 + .../distutils/command/config_compiler.py | 126 + .../numpy/distutils/command/develop.py | 15 + .../numpy/distutils/command/egg_info.py | 25 + .../numpy/distutils/command/install.py | 79 + .../numpy/distutils/command/install_clib.py | 40 + .../numpy/distutils/command/install_data.py | 24 + .../distutils/command/install_headers.py | 25 + .../numpy/distutils/command/sdist.py | 27 + .../numpy/distutils/conv_template.py | 330 + .../Lib/site-packages/numpy/distutils/core.py | 215 + .../site-packages/numpy/distutils/cpuinfo.py | 683 ++ .../numpy/distutils/exec_command.py | 316 + .../numpy/distutils/extension.py | 103 + .../numpy/distutils/fcompiler/__init__.py | 1022 ++ .../numpy/distutils/fcompiler/absoft.py | 156 + .../numpy/distutils/fcompiler/compaq.py | 120 + .../numpy/distutils/fcompiler/environment.py | 88 + .../numpy/distutils/fcompiler/fujitsu.py | 46 + .../numpy/distutils/fcompiler/g95.py | 42 + .../numpy/distutils/fcompiler/gnu.py | 549 ++ .../numpy/distutils/fcompiler/hpux.py | 41 + .../numpy/distutils/fcompiler/ibm.py | 97 + .../numpy/distutils/fcompiler/intel.py | 220 + .../numpy/distutils/fcompiler/lahey.py | 45 + .../numpy/distutils/fcompiler/mips.py | 54 + .../numpy/distutils/fcompiler/nag.py | 82 + .../numpy/distutils/fcompiler/none.py | 28 + .../numpy/distutils/fcompiler/nv.py | 55 + .../numpy/distutils/fcompiler/pathf95.py | 33 + .../numpy/distutils/fcompiler/pg.py | 128 + .../numpy/distutils/fcompiler/sun.py | 51 + .../numpy/distutils/fcompiler/vast.py | 52 + .../numpy/distutils/from_template.py | 262 + .../numpy/distutils/intelccompiler.py | 111 + .../site-packages/numpy/distutils/lib2def.py | 116 + .../numpy/distutils/line_endings.py | 77 + venv/Lib/site-packages/numpy/distutils/log.py | 89 + .../distutils/mingw/gfortran_vs2003_hack.c | 6 + .../numpy/distutils/mingw32ccompiler.py | 657 ++ .../numpy/distutils/misc_util.py | 2393 +++++ .../numpy/distutils/msvc9compiler.py | 63 + .../numpy/distutils/msvccompiler.py | 58 + .../numpy/distutils/npy_pkg_config.py | 437 + .../numpy/distutils/numpy_distribution.py | 17 + .../numpy/distutils/pathccompiler.py | 21 + .../site-packages/numpy/distutils/setup.py | 17 + .../numpy/distutils/system_info.py | 3080 ++++++ .../numpy/distutils/tests/__init__.py | 0 .../numpy/distutils/tests/test_build_ext.py | 72 + .../distutils/tests/test_ccompiler_opt.py | 787 ++ .../tests/test_ccompiler_opt_conf.py | 176 + .../distutils/tests/test_exec_command.py | 214 + .../numpy/distutils/tests/test_fcompiler.py | 43 + .../distutils/tests/test_fcompiler_gnu.py | 55 + .../distutils/tests/test_fcompiler_intel.py | 30 + .../distutils/tests/test_fcompiler_nagfor.py | 22 + .../distutils/tests/test_from_template.py | 44 + .../distutils/tests/test_mingw32ccompiler.py | 42 + .../numpy/distutils/tests/test_misc_util.py | 82 + .../distutils/tests/test_npy_pkg_config.py | 84 + .../numpy/distutils/tests/test_shell_utils.py | 76 + .../numpy/distutils/tests/test_system_info.py | 320 + .../numpy/distutils/unixccompiler.py | 140 + venv/Lib/site-packages/numpy/doc/__init__.py | 26 + venv/Lib/site-packages/numpy/doc/constants.py | 413 + venv/Lib/site-packages/numpy/doc/ufuncs.py | 137 + venv/Lib/site-packages/numpy/dual.py | 83 + venv/Lib/site-packages/numpy/emath.pyi | 13 + venv/Lib/site-packages/numpy/f2py/__init__.py | 153 + .../Lib/site-packages/numpy/f2py/__init__.pyi | 7 + venv/Lib/site-packages/numpy/f2py/__main__.py | 4 + .../site-packages/numpy/f2py/__version__.py | 1 + venv/Lib/site-packages/numpy/f2py/auxfuncs.py | 857 ++ .../Lib/site-packages/numpy/f2py/capi_maps.py | 838 ++ venv/Lib/site-packages/numpy/f2py/cb_rules.py | 616 ++ venv/Lib/site-packages/numpy/f2py/cfuncs.py | 1362 +++ .../site-packages/numpy/f2py/common_rules.py | 145 + .../site-packages/numpy/f2py/crackfortran.py | 3408 +++++++ venv/Lib/site-packages/numpy/f2py/diagnose.py | 154 + venv/Lib/site-packages/numpy/f2py/f2py2e.py | 692 ++ .../site-packages/numpy/f2py/f2py_testing.py | 46 + .../site-packages/numpy/f2py/f90mod_rules.py | 269 + .../Lib/site-packages/numpy/f2py/func2subr.py | 300 + venv/Lib/site-packages/numpy/f2py/rules.py | 1460 +++ venv/Lib/site-packages/numpy/f2py/setup.py | 73 + .../numpy/f2py/src/fortranobject.c | 1107 +++ .../numpy/f2py/src/fortranobject.h | 132 + .../numpy/f2py/tests/__init__.py | 0 .../tests/src/array_from_pyobj/wrapmodule.c | 228 + .../f2py/tests/src/assumed_shape/.f2py_f2cmap | 1 + .../f2py/tests/src/assumed_shape/foo_free.f90 | 34 + .../f2py/tests/src/assumed_shape/foo_mod.f90 | 41 + .../f2py/tests/src/assumed_shape/foo_use.f90 | 19 + .../tests/src/assumed_shape/precision.f90 | 4 + .../numpy/f2py/tests/src/common/block.f | 11 + .../numpy/f2py/tests/src/kind/foo.f90 | 20 + .../numpy/f2py/tests/src/mixed/foo.f | 5 + .../numpy/f2py/tests/src/mixed/foo_fixed.f90 | 8 + .../numpy/f2py/tests/src/mixed/foo_free.f90 | 8 + .../numpy/f2py/tests/src/module_data/mod.mod | Bin 0 -> 412 bytes .../src/module_data/module_data_docstring.f90 | 12 + .../tests/src/parameter/constant_both.f90 | 57 + .../tests/src/parameter/constant_compound.f90 | 15 + .../tests/src/parameter/constant_integer.f90 | 22 + .../src/parameter/constant_non_compound.f90 | 23 + .../tests/src/parameter/constant_real.f90 | 23 + .../numpy/f2py/tests/src/regression/inout.f90 | 9 + .../numpy/f2py/tests/src/size/foo.f90 | 44 + .../numpy/f2py/tests/src/string/char.f90 | 29 + .../numpy/f2py/tests/test_array_from_pyobj.py | 592 ++ .../numpy/f2py/tests/test_assumed_shape.py | 53 + .../numpy/f2py/tests/test_block_docstring.py | 23 + .../numpy/f2py/tests/test_callback.py | 326 + .../numpy/f2py/tests/test_common.py | 25 + .../numpy/f2py/tests/test_compile_function.py | 125 + .../numpy/f2py/tests/test_crackfortran.py | 117 + .../numpy/f2py/tests/test_kind.py | 32 + .../numpy/f2py/tests/test_mixed.py | 35 + .../numpy/f2py/tests/test_module_doc.py | 30 + .../numpy/f2py/tests/test_parameter.py | 116 + .../numpy/f2py/tests/test_quoted_character.py | 32 + .../numpy/f2py/tests/test_regression.py | 47 + .../numpy/f2py/tests/test_return_character.py | 145 + .../numpy/f2py/tests/test_return_complex.py | 163 + .../numpy/f2py/tests/test_return_integer.py | 175 + .../numpy/f2py/tests/test_return_logical.py | 185 + .../numpy/f2py/tests/test_return_real.py | 203 + .../numpy/f2py/tests/test_semicolon_split.py | 63 + .../numpy/f2py/tests/test_size.py | 49 + .../numpy/f2py/tests/test_string.py | 22 + .../site-packages/numpy/f2py/tests/util.py | 359 + .../Lib/site-packages/numpy/f2py/use_rules.py | 113 + venv/Lib/site-packages/numpy/fft/__init__.py | 208 + venv/Lib/site-packages/numpy/fft/__init__.pyi | 20 + .../Lib/site-packages/numpy/fft/_pocketfft.py | 1403 +++ venv/Lib/site-packages/numpy/fft/helper.py | 221 + venv/Lib/site-packages/numpy/fft/setup.py | 22 + .../site-packages/numpy/fft/tests/__init__.py | 0 .../numpy/fft/tests/test_helper.py | 167 + .../numpy/fft/tests/test_pocketfft.py | 307 + venv/Lib/site-packages/numpy/lib/__init__.py | 61 + venv/Lib/site-packages/numpy/lib/__init__.pyi | 187 + .../site-packages/numpy/lib/_datasource.py | 702 ++ venv/Lib/site-packages/numpy/lib/_iotools.py | 898 ++ venv/Lib/site-packages/numpy/lib/_version.py | 155 + venv/Lib/site-packages/numpy/lib/arraypad.py | 876 ++ .../site-packages/numpy/lib/arraysetops.py | 801 ++ .../site-packages/numpy/lib/arrayterator.py | 219 + venv/Lib/site-packages/numpy/lib/format.py | 914 ++ .../site-packages/numpy/lib/function_base.py | 4860 +++++++++ .../Lib/site-packages/numpy/lib/histograms.py | 1128 +++ .../site-packages/numpy/lib/index_tricks.py | 1003 ++ venv/Lib/site-packages/numpy/lib/mixins.py | 176 + .../site-packages/numpy/lib/nanfunctions.py | 1670 ++++ venv/Lib/site-packages/numpy/lib/npyio.py | 2413 +++++ .../Lib/site-packages/numpy/lib/polynomial.py | 1444 +++ .../site-packages/numpy/lib/recfunctions.py | 1594 +++ venv/Lib/site-packages/numpy/lib/scimath.py | 617 ++ venv/Lib/site-packages/numpy/lib/setup.py | 12 + .../Lib/site-packages/numpy/lib/shape_base.py | 1260 +++ .../site-packages/numpy/lib/stride_tricks.py | 545 + .../site-packages/numpy/lib/tests/__init__.py | 0 .../numpy/lib/tests/data/py2-objarr.npy | Bin 0 -> 258 bytes .../numpy/lib/tests/data/py2-objarr.npz | Bin 0 -> 366 bytes .../numpy/lib/tests/data/py3-objarr.npy | Bin 0 -> 341 bytes .../numpy/lib/tests/data/py3-objarr.npz | Bin 0 -> 449 bytes .../numpy/lib/tests/data/python3.npy | Bin 0 -> 96 bytes .../numpy/lib/tests/data/win64python2.npy | Bin 0 -> 96 bytes .../numpy/lib/tests/test__datasource.py | 350 + .../numpy/lib/tests/test__iotools.py | 353 + .../numpy/lib/tests/test__version.py | 64 + .../numpy/lib/tests/test_arraypad.py | 1364 +++ .../numpy/lib/tests/test_arraysetops.py | 677 ++ .../numpy/lib/tests/test_arrayterator.py | 46 + .../numpy/lib/tests/test_financial_expired.py | 13 + .../numpy/lib/tests/test_format.py | 962 ++ .../numpy/lib/tests/test_function_base.py | 3561 +++++++ .../numpy/lib/tests/test_histograms.py | 838 ++ .../numpy/lib/tests/test_index_tricks.py | 525 + .../site-packages/numpy/lib/tests/test_io.py | 2660 +++++ .../numpy/lib/tests/test_mixins.py | 216 + .../numpy/lib/tests/test_nanfunctions.py | 980 ++ .../numpy/lib/tests/test_packbits.py | 376 + .../numpy/lib/tests/test_polynomial.py | 282 + .../numpy/lib/tests/test_recfunctions.py | 979 ++ .../numpy/lib/tests/test_regression.py | 247 + .../numpy/lib/tests/test_shape_base.py | 717 ++ .../numpy/lib/tests/test_stride_tricks.py | 645 ++ .../numpy/lib/tests/test_twodim_base.py | 532 + .../numpy/lib/tests/test_type_check.py | 478 + .../numpy/lib/tests/test_ufunclike.py | 104 + .../numpy/lib/tests/test_utils.py | 161 + .../site-packages/numpy/lib/twodim_base.py | 1046 ++ .../Lib/site-packages/numpy/lib/type_check.py | 732 ++ venv/Lib/site-packages/numpy/lib/ufunclike.py | 266 + .../Lib/site-packages/numpy/lib/user_array.py | 286 + venv/Lib/site-packages/numpy/lib/utils.py | 1020 ++ .../site-packages/numpy/linalg/__init__.py | 77 + .../site-packages/numpy/linalg/__init__.pyi | 23 + venv/Lib/site-packages/numpy/linalg/linalg.py | 2813 ++++++ venv/Lib/site-packages/numpy/linalg/setup.py | 88 + .../numpy/linalg/tests/__init__.py | 0 .../numpy/linalg/tests/test_build.py | 53 + .../numpy/linalg/tests/test_deprecations.py | 20 + .../numpy/linalg/tests/test_linalg.py | 2089 ++++ .../numpy/linalg/tests/test_regression.py | 148 + venv/Lib/site-packages/numpy/ma/__init__.py | 54 + venv/Lib/site-packages/numpy/ma/__init__.pyi | 229 + venv/Lib/site-packages/numpy/ma/bench.py | 131 + venv/Lib/site-packages/numpy/ma/core.py | 8184 +++++++++++++++ venv/Lib/site-packages/numpy/ma/extras.py | 1923 ++++ venv/Lib/site-packages/numpy/ma/mrecords.py | 770 ++ venv/Lib/site-packages/numpy/ma/setup.py | 12 + .../site-packages/numpy/ma/tests/__init__.py | 0 .../site-packages/numpy/ma/tests/test_core.py | 5355 ++++++++++ .../numpy/ma/tests/test_deprecations.py | 68 + .../numpy/ma/tests/test_extras.py | 1688 ++++ .../numpy/ma/tests/test_mrecords.py | 493 + .../numpy/ma/tests/test_old_ma.py | 858 ++ .../numpy/ma/tests/test_regression.py | 91 + .../numpy/ma/tests/test_subclassing.py | 347 + venv/Lib/site-packages/numpy/ma/testutils.py | 288 + .../numpy/ma/timer_comparison.py | 443 + venv/Lib/site-packages/numpy/matlib.py | 376 + .../site-packages/numpy/matrixlib/__init__.py | 10 + .../numpy/matrixlib/__init__.pyi | 8 + .../numpy/matrixlib/defmatrix.py | 1113 +++ .../site-packages/numpy/matrixlib/setup.py | 12 + .../numpy/matrixlib/tests/__init__.py | 0 .../numpy/matrixlib/tests/test_defmatrix.py | 453 + .../numpy/matrixlib/tests/test_interaction.py | 354 + .../matrixlib/tests/test_masked_matrix.py | 231 + .../matrixlib/tests/test_matrix_linalg.py | 93 + .../numpy/matrixlib/tests/test_multiarray.py | 16 + .../numpy/matrixlib/tests/test_numeric.py | 17 + .../numpy/matrixlib/tests/test_regression.py | 31 + .../numpy/polynomial/__init__.py | 176 + .../numpy/polynomial/__init__.pyi | 18 + .../numpy/polynomial/_polybase.py | 1144 +++ .../numpy/polynomial/chebyshev.py | 2077 ++++ .../site-packages/numpy/polynomial/hermite.py | 1696 ++++ .../numpy/polynomial/hermite_e.py | 1688 ++++ .../numpy/polynomial/laguerre.py | 1644 ++++ .../numpy/polynomial/legendre.py | 1663 ++++ .../numpy/polynomial/polynomial.py | 1529 +++ .../numpy/polynomial/polyutils.py | 796 ++ .../site-packages/numpy/polynomial/setup.py | 10 + .../numpy/polynomial/tests/__init__.py | 0 .../numpy/polynomial/tests/test_chebyshev.py | 619 ++ .../numpy/polynomial/tests/test_classes.py | 600 ++ .../numpy/polynomial/tests/test_hermite.py | 555 ++ .../numpy/polynomial/tests/test_hermite_e.py | 556 ++ .../numpy/polynomial/tests/test_laguerre.py | 537 + .../numpy/polynomial/tests/test_legendre.py | 556 ++ .../numpy/polynomial/tests/test_polynomial.py | 593 ++ .../numpy/polynomial/tests/test_polyutils.py | 106 + .../numpy/polynomial/tests/test_printing.py | 390 + venv/Lib/site-packages/numpy/py.typed | 0 .../site-packages/numpy/random/__init__.pxd | 14 + .../site-packages/numpy/random/__init__.py | 213 + .../site-packages/numpy/random/__init__.pyi | 63 + .../numpy/random/_bounded_integers.pxd | 29 + .../site-packages/numpy/random/_common.pxd | 106 + .../numpy/random/_examples/cffi/extending.py | 40 + .../numpy/random/_examples/cffi/parse.py | 55 + .../random/_examples/cython/extending.pyx | 78 + .../cython/extending_distributions.pyx | 117 + .../numpy/random/_examples/cython/setup.py | 41 + .../numpy/random/_examples/numba/extending.py | 84 + .../numba/extending_distributions.py | 67 + .../Lib/site-packages/numpy/random/_pickle.py | 82 + .../numpy/random/bit_generator.pxd | 35 + .../numpy/random/c_distributions.pxd | 114 + .../numpy/random/lib/npyrandom.lib | Bin 0 -> 110126 bytes venv/Lib/site-packages/numpy/random/setup.py | 147 + .../numpy/random/tests/__init__.py | 0 .../numpy/random/tests/data/__init__.py | 0 .../random/tests/data/mt19937-testset-1.csv | 1001 ++ .../random/tests/data/mt19937-testset-2.csv | 1001 ++ .../random/tests/data/pcg64-testset-1.csv | 1001 ++ .../random/tests/data/pcg64-testset-2.csv | 1001 ++ .../random/tests/data/philox-testset-1.csv | 1001 ++ .../random/tests/data/philox-testset-2.csv | 1001 ++ .../random/tests/data/sfc64-testset-1.csv | 1001 ++ .../random/tests/data/sfc64-testset-2.csv | 1001 ++ .../numpy/random/tests/test_direct.py | 425 + .../numpy/random/tests/test_extending.py | 95 + .../random/tests/test_generator_mt19937.py | 2513 +++++ .../test_generator_mt19937_regressions.py | 150 + .../numpy/random/tests/test_random.py | 1700 ++++ .../numpy/random/tests/test_randomstate.py | 2005 ++++ .../tests/test_randomstate_regression.py | 203 + .../numpy/random/tests/test_regression.py | 149 + .../numpy/random/tests/test_seed_sequence.py | 80 + .../numpy/random/tests/test_smoke.py | 806 ++ venv/Lib/site-packages/numpy/rec.pyi | 12 + venv/Lib/site-packages/numpy/setup.py | 29 + .../site-packages/numpy/testing/__init__.py | 20 + .../site-packages/numpy/testing/__init__.pyi | 46 + .../numpy/testing/_private/__init__.py | 0 .../numpy/testing/_private/decorators.py | 284 + .../numpy/testing/_private/noseclasses.py | 364 + .../numpy/testing/_private/nosetester.py | 545 + .../numpy/testing/_private/parameterized.py | 444 + .../numpy/testing/_private/utils.py | 2519 +++++ .../numpy/testing/print_coercion_tables.py | 199 + venv/Lib/site-packages/numpy/testing/setup.py | 20 + .../numpy/testing/tests/__init__.py | 0 .../numpy/testing/tests/test_decorators.py | 210 + .../numpy/testing/tests/test_doctesting.py | 57 + .../numpy/testing/tests/test_utils.py | 1614 +++ venv/Lib/site-packages/numpy/testing/utils.py | 28 + .../Lib/site-packages/numpy/tests/__init__.py | 0 .../numpy/tests/test_ctypeslib.py | 365 + .../site-packages/numpy/tests/test_matlib.py | 58 + .../numpy/tests/test_numpy_version.py | 17 + .../numpy/tests/test_public_api.py | 474 + .../numpy/tests/test_reloading.py | 57 + .../site-packages/numpy/tests/test_scripts.py | 46 + .../numpy/tests/test_warnings.py | 74 + .../site-packages/numpy/typing/__init__.py | 232 + .../numpy/typing/_add_docstring.py | 96 + .../site-packages/numpy/typing/_array_like.py | 40 + .../site-packages/numpy/typing/_callable.py | 336 + .../site-packages/numpy/typing/_dtype_like.py | 81 + .../site-packages/numpy/typing/_scalars.py | 26 + venv/Lib/site-packages/numpy/typing/_shape.py | 6 + venv/Lib/site-packages/numpy/typing/setup.py | 11 + .../numpy/typing/tests/__init__.py | 0 .../typing/tests/data/fail/arithmetic.py | 16 + .../tests/data/fail/array_constructors.py | 31 + .../typing/tests/data/fail/array_like.py | 16 + .../typing/tests/data/fail/bitwise_ops.py | 20 + .../numpy/typing/tests/data/fail/constants.py | 6 + .../numpy/typing/tests/data/fail/dtype.py | 16 + .../numpy/typing/tests/data/fail/flatiter.py | 25 + .../typing/tests/data/fail/fromnumeric.py | 154 + .../numpy/typing/tests/data/fail/modules.py | 15 + .../numpy/typing/tests/data/fail/ndarray.py | 11 + .../typing/tests/data/fail/ndarray_misc.py | 21 + .../typing/tests/data/fail/numerictypes.py | 13 + .../numpy/typing/tests/data/fail/scalars.py | 76 + .../typing/tests/data/fail/ufunc_config.py | 21 + .../numpy/typing/tests/data/fail/ufuncs.py | 7 + .../tests/data/fail/warnings_and_errors.py | 7 + .../numpy/typing/tests/data/mypy.ini | 8 + .../typing/tests/data/pass/arithmetic.py | 293 + .../tests/data/pass/array_constructors.py | 128 + .../typing/tests/data/pass/array_like.py | 39 + .../typing/tests/data/pass/bitwise_ops.py | 131 + .../numpy/typing/tests/data/pass/dtype.py | 51 + .../numpy/typing/tests/data/pass/flatiter.py | 14 + .../typing/tests/data/pass/fromnumeric.py | 260 + .../numpy/typing/tests/data/pass/literal.py | 45 + .../numpy/typing/tests/data/pass/mod.py | 149 + .../numpy/typing/tests/data/pass/modules.py | 42 + .../tests/data/pass/ndarray_conversion.py | 94 + .../typing/tests/data/pass/ndarray_misc.py | 159 + .../data/pass/ndarray_shape_manipulation.py | 47 + .../numpy/typing/tests/data/pass/numeric.py | 89 + .../typing/tests/data/pass/numerictypes.py | 29 + .../numpy/typing/tests/data/pass/scalars.py | 165 + .../numpy/typing/tests/data/pass/simple.py | 165 + .../typing/tests/data/pass/simple_py3.py | 6 + .../typing/tests/data/pass/ufunc_config.py | 50 + .../numpy/typing/tests/data/pass/ufuncs.py | 16 + .../tests/data/pass/warnings_and_errors.py | 7 + .../typing/tests/data/reveal/arithmetic.py | 291 + .../tests/data/reveal/array_constructors.py | 102 + .../typing/tests/data/reveal/bitwise_ops.py | 131 + .../typing/tests/data/reveal/constants.py | 52 + .../numpy/typing/tests/data/reveal/dtype.py | 52 + .../typing/tests/data/reveal/flatiter.py | 14 + .../typing/tests/data/reveal/fromnumeric.py | 278 + .../numpy/typing/tests/data/reveal/mod.py | 149 + .../numpy/typing/tests/data/reveal/modules.py | 47 + .../tests/data/reveal/nbit_base_example.py | 18 + .../tests/data/reveal/ndarray_conversion.py | 54 + .../typing/tests/data/reveal/ndarray_misc.py | 150 + .../data/reveal/ndarray_shape_manipulation.py | 35 + .../numpy/typing/tests/data/reveal/numeric.py | 89 + .../typing/tests/data/reveal/numerictypes.py | 18 + .../numpy/typing/tests/data/reveal/scalars.py | 28 + .../typing/tests/data/reveal/ufunc_config.py | 25 + .../tests/data/reveal/warnings_and_errors.py | 10 + .../numpy/typing/tests/test_isfile.py | 33 + .../numpy/typing/tests/test_typing.py | 182 + venv/Lib/site-packages/numpy/version.py | 12 + .../pgzero-1.2.1.dist-info/AUTHORS | 2 + .../pgzero-1.2.1.dist-info/COPYING | 165 + .../pgzero-1.2.1.dist-info/INSTALLER | 1 + .../pgzero-1.2.1.dist-info/METADATA | 90 + .../pgzero-1.2.1.dist-info/RECORD | 50 + .../pgzero-1.2.1.dist-info/REQUESTED | 0 .../pgzero-1.2.1.dist-info/WHEEL | 5 + .../pgzero-1.2.1.dist-info/entry_points.txt | 3 + .../pgzero-1.2.1.dist-info/top_level.txt | 2 + venv/Lib/site-packages/pgzero/__init__.py | 8 + venv/Lib/site-packages/pgzero/__main__.py | 3 + venv/Lib/site-packages/pgzero/actor.py | 250 + venv/Lib/site-packages/pgzero/animation.py | 216 + venv/Lib/site-packages/pgzero/builtins.py | 14 + venv/Lib/site-packages/pgzero/clock.py | 182 + venv/Lib/site-packages/pgzero/constants.py | 33 + venv/Lib/site-packages/pgzero/data/icon.png | Bin 0 -> 3646 bytes venv/Lib/site-packages/pgzero/data/joypad.png | Bin 0 -> 30048 bytes venv/Lib/site-packages/pgzero/game.py | 258 + venv/Lib/site-packages/pgzero/keyboard.py | 60 + venv/Lib/site-packages/pgzero/loaders.py | 256 + venv/Lib/site-packages/pgzero/music.py | 110 + venv/Lib/site-packages/pgzero/ptext.py | 495 + venv/Lib/site-packages/pgzero/rect.py | 498 + venv/Lib/site-packages/pgzero/runner.py | 113 + venv/Lib/site-packages/pgzero/screen.py | 105 + venv/Lib/site-packages/pgzero/soundfmt.py | 109 + venv/Lib/site-packages/pgzero/spellcheck.py | 177 + venv/Lib/site-packages/pgzero/tone.py | 191 + venv/Lib/site-packages/pgzrun.py | 31 + .../pip-21.0.1.dist-info/INSTALLER | 1 + .../pip-21.0.1.dist-info/LICENSE.txt | 20 + .../pip-21.0.1.dist-info/METADATA | 92 + .../site-packages/pip-21.0.1.dist-info/RECORD | 761 ++ .../site-packages/pip-21.0.1.dist-info/WHEEL | 5 + .../pip-21.0.1.dist-info/entry_points.txt | 5 + .../pip-21.0.1.dist-info/top_level.txt | 1 + venv/Lib/site-packages/pip/__init__.py | 18 + venv/Lib/site-packages/pip/__main__.py | 24 + .../site-packages/pip/_internal/__init__.py | 17 + .../site-packages/pip/_internal/build_env.py | 242 + venv/Lib/site-packages/pip/_internal/cache.py | 293 + .../pip/_internal/cli/__init__.py | 4 + .../pip/_internal/cli/autocompletion.py | 164 + .../pip/_internal/cli/base_command.py | 226 + .../pip/_internal/cli/cmdoptions.py | 969 ++ .../pip/_internal/cli/command_context.py | 36 + .../site-packages/pip/_internal/cli/main.py | 73 + .../pip/_internal/cli/main_parser.py | 96 + .../site-packages/pip/_internal/cli/parser.py | 281 + .../pip/_internal/cli/progress_bars.py | 271 + .../pip/_internal/cli/req_command.py | 426 + .../pip/_internal/cli/spinners.py | 171 + .../pip/_internal/cli/status_codes.py | 6 + .../pip/_internal/commands/__init__.py | 115 + .../pip/_internal/commands/cache.py | 232 + .../pip/_internal/commands/check.py | 51 + .../pip/_internal/commands/completion.py | 96 + .../pip/_internal/commands/configuration.py | 280 + .../pip/_internal/commands/debug.py | 218 + .../pip/_internal/commands/download.py | 144 + .../pip/_internal/commands/freeze.py | 107 + .../pip/_internal/commands/hash.py | 61 + .../pip/_internal/commands/help.py | 44 + .../pip/_internal/commands/install.py | 733 ++ .../pip/_internal/commands/list.py | 323 + .../pip/_internal/commands/search.py | 167 + .../pip/_internal/commands/show.py | 184 + .../pip/_internal/commands/uninstall.py | 93 + .../pip/_internal/commands/wheel.py | 194 + .../pip/_internal/configuration.py | 406 + .../pip/_internal/distributions/__init__.py | 24 + .../pip/_internal/distributions/base.py | 42 + .../pip/_internal/distributions/installed.py | 25 + .../pip/_internal/distributions/sdist.py | 105 + .../pip/_internal/distributions/wheel.py | 37 + .../site-packages/pip/_internal/exceptions.py | 384 + .../pip/_internal/index/__init__.py | 2 + .../pip/_internal/index/collector.py | 666 ++ .../pip/_internal/index/package_finder.py | 1005 ++ .../site-packages/pip/_internal/locations.py | 184 + venv/Lib/site-packages/pip/_internal/main.py | 16 + .../pip/_internal/models/__init__.py | 2 + .../pip/_internal/models/candidate.py | 39 + .../pip/_internal/models/direct_url.py | 239 + .../pip/_internal/models/format_control.py | 88 + .../pip/_internal/models/index.py | 34 + .../pip/_internal/models/link.py | 245 + .../pip/_internal/models/scheme.py | 31 + .../pip/_internal/models/search_scope.py | 135 + .../pip/_internal/models/selection_prefs.py | 50 + .../pip/_internal/models/target_python.py | 117 + .../pip/_internal/models/wheel.py | 78 + .../pip/_internal/network/__init__.py | 2 + .../pip/_internal/network/auth.py | 310 + .../pip/_internal/network/cache.py | 79 + .../pip/_internal/network/download.py | 202 + .../pip/_internal/network/lazy_wheel.py | 230 + .../pip/_internal/network/session.py | 424 + .../pip/_internal/network/utils.py | 97 + .../pip/_internal/network/xmlrpc.py | 53 + .../pip/_internal/operations/__init__.py | 0 .../pip/_internal/operations/check.py | 155 + .../pip/_internal/operations/freeze.py | 270 + .../_internal/operations/install/__init__.py | 2 + .../operations/install/editable_legacy.py | 52 + .../_internal/operations/install/legacy.py | 130 + .../pip/_internal/operations/install/wheel.py | 828 ++ .../pip/_internal/operations/prepare.py | 585 ++ .../site-packages/pip/_internal/pyproject.py | 186 + .../pip/_internal/req/__init__.py | 101 + .../pip/_internal/req/constructors.py | 468 + .../pip/_internal/req/req_file.py | 560 ++ .../pip/_internal/req/req_install.py | 879 ++ .../pip/_internal/req/req_set.py | 202 + .../pip/_internal/req/req_tracker.py | 146 + .../pip/_internal/req/req_uninstall.py | 654 ++ .../pip/_internal/resolution/__init__.py | 0 .../pip/_internal/resolution/base.py | 21 + .../_internal/resolution/legacy/__init__.py | 0 .../_internal/resolution/legacy/resolver.py | 473 + .../resolution/resolvelib/__init__.py | 0 .../_internal/resolution/resolvelib/base.py | 156 + .../resolution/resolvelib/candidates.py | 598 ++ .../resolution/resolvelib/factory.py | 499 + .../resolution/resolvelib/found_candidates.py | 145 + .../resolution/resolvelib/provider.py | 174 + .../resolution/resolvelib/reporter.py | 84 + .../resolution/resolvelib/requirements.py | 201 + .../resolution/resolvelib/resolver.py | 296 + .../pip/_internal/self_outdated_check.py | 195 + .../pip/_internal/utils/__init__.py | 0 .../pip/_internal/utils/appdirs.py | 42 + .../pip/_internal/utils/compat.py | 152 + .../pip/_internal/utils/compatibility_tags.py | 176 + .../pip/_internal/utils/datetime.py | 12 + .../pip/_internal/utils/deprecation.py | 102 + .../pip/_internal/utils/direct_url_helpers.py | 121 + .../pip/_internal/utils/distutils_args.py | 48 + .../pip/_internal/utils/encoding.py | 41 + .../pip/_internal/utils/entrypoints.py | 31 + .../pip/_internal/utils/filesystem.py | 200 + .../pip/_internal/utils/filetypes.py | 26 + .../pip/_internal/utils/glibc.py | 96 + .../pip/_internal/utils/hashes.py | 160 + .../_internal/utils/inject_securetransport.py | 36 + .../pip/_internal/utils/logging.py | 362 + .../site-packages/pip/_internal/utils/misc.py | 927 ++ .../pip/_internal/utils/models.py | 41 + .../pip/_internal/utils/packaging.py | 93 + .../pip/_internal/utils/parallel.py | 105 + .../pip/_internal/utils/pkg_resources.py | 44 + .../pip/_internal/utils/setuptools_build.py | 181 + .../pip/_internal/utils/subprocess.py | 296 + .../pip/_internal/utils/temp_dir.py | 282 + .../pip/_internal/utils/typing.py | 38 + .../pip/_internal/utils/unpacking.py | 277 + .../site-packages/pip/_internal/utils/urls.py | 54 + .../pip/_internal/utils/virtualenv.py | 116 + .../pip/_internal/utils/wheel.py | 218 + .../pip/_internal/vcs/__init__.py | 15 + .../site-packages/pip/_internal/vcs/bazaar.py | 114 + .../site-packages/pip/_internal/vcs/git.py | 454 + .../pip/_internal/vcs/mercurial.py | 171 + .../pip/_internal/vcs/subversion.py | 346 + .../pip/_internal/vcs/versioncontrol.py | 722 ++ .../pip/_internal/wheel_builder.py | 365 + .../Lib/site-packages/pip/_vendor/__init__.py | 114 + venv/Lib/site-packages/pip/_vendor/appdirs.py | 633 ++ .../pip/_vendor/cachecontrol/__init__.py | 11 + .../pip/_vendor/cachecontrol/_cmd.py | 57 + .../pip/_vendor/cachecontrol/adapter.py | 133 + .../pip/_vendor/cachecontrol/cache.py | 39 + .../_vendor/cachecontrol/caches/__init__.py | 2 + .../_vendor/cachecontrol/caches/file_cache.py | 146 + .../cachecontrol/caches/redis_cache.py | 33 + .../pip/_vendor/cachecontrol/compat.py | 29 + .../pip/_vendor/cachecontrol/controller.py | 376 + .../pip/_vendor/cachecontrol/filewrapper.py | 80 + .../pip/_vendor/cachecontrol/heuristics.py | 135 + .../pip/_vendor/cachecontrol/serialize.py | 188 + .../pip/_vendor/cachecontrol/wrapper.py | 29 + .../pip/_vendor/certifi/__init__.py | 3 + .../pip/_vendor/certifi/__main__.py | 12 + .../pip/_vendor/certifi/cacert.pem | 4325 ++++++++ .../site-packages/pip/_vendor/certifi/core.py | 60 + .../pip/_vendor/chardet/__init__.py | 83 + .../pip/_vendor/chardet/big5freq.py | 386 + .../pip/_vendor/chardet/big5prober.py | 47 + .../pip/_vendor/chardet/chardistribution.py | 233 + .../pip/_vendor/chardet/charsetgroupprober.py | 107 + .../pip/_vendor/chardet/charsetprober.py | 145 + .../pip/_vendor/chardet/cli/__init__.py | 1 + .../pip/_vendor/chardet/cli/chardetect.py | 84 + .../pip/_vendor/chardet/codingstatemachine.py | 88 + .../pip/_vendor/chardet/compat.py | 36 + .../pip/_vendor/chardet/cp949prober.py | 49 + .../pip/_vendor/chardet/enums.py | 76 + .../pip/_vendor/chardet/escprober.py | 101 + .../pip/_vendor/chardet/escsm.py | 246 + .../pip/_vendor/chardet/eucjpprober.py | 92 + .../pip/_vendor/chardet/euckrfreq.py | 195 + .../pip/_vendor/chardet/euckrprober.py | 47 + .../pip/_vendor/chardet/euctwfreq.py | 387 + .../pip/_vendor/chardet/euctwprober.py | 46 + .../pip/_vendor/chardet/gb2312freq.py | 283 + .../pip/_vendor/chardet/gb2312prober.py | 46 + .../pip/_vendor/chardet/hebrewprober.py | 292 + .../pip/_vendor/chardet/jisfreq.py | 325 + .../pip/_vendor/chardet/jpcntx.py | 233 + .../pip/_vendor/chardet/langbulgarianmodel.py | 4650 +++++++++ .../pip/_vendor/chardet/langgreekmodel.py | 4398 +++++++++ .../pip/_vendor/chardet/langhebrewmodel.py | 4383 +++++++++ .../pip/_vendor/chardet/langhungarianmodel.py | 4650 +++++++++ .../pip/_vendor/chardet/langrussianmodel.py | 5718 +++++++++++ .../pip/_vendor/chardet/langthaimodel.py | 4383 +++++++++ .../pip/_vendor/chardet/langturkishmodel.py | 4383 +++++++++ .../pip/_vendor/chardet/latin1prober.py | 145 + .../pip/_vendor/chardet/mbcharsetprober.py | 91 + .../pip/_vendor/chardet/mbcsgroupprober.py | 54 + .../pip/_vendor/chardet/mbcssm.py | 572 ++ .../pip/_vendor/chardet/metadata/__init__.py | 0 .../pip/_vendor/chardet/metadata/languages.py | 310 + .../pip/_vendor/chardet/sbcharsetprober.py | 145 + .../pip/_vendor/chardet/sbcsgroupprober.py | 83 + .../pip/_vendor/chardet/sjisprober.py | 92 + .../pip/_vendor/chardet/universaldetector.py | 286 + .../pip/_vendor/chardet/utf8prober.py | 82 + .../pip/_vendor/chardet/version.py | 9 + .../pip/_vendor/colorama/__init__.py | 6 + .../pip/_vendor/colorama/ansi.py | 102 + .../pip/_vendor/colorama/ansitowin32.py | 258 + .../pip/_vendor/colorama/initialise.py | 80 + .../pip/_vendor/colorama/win32.py | 152 + .../pip/_vendor/colorama/winterm.py | 169 + .../site-packages/pip/_vendor/contextlib2.py | 518 + .../pip/_vendor/distlib/__init__.py | 23 + .../pip/_vendor/distlib/_backport/__init__.py | 6 + .../pip/_vendor/distlib/_backport/misc.py | 41 + .../pip/_vendor/distlib/_backport/shutil.py | 764 ++ .../_vendor/distlib/_backport/sysconfig.cfg | 84 + .../_vendor/distlib/_backport/sysconfig.py | 786 ++ .../pip/_vendor/distlib/_backport/tarfile.py | 2607 +++++ .../pip/_vendor/distlib/compat.py | 1120 +++ .../pip/_vendor/distlib/database.py | 1339 +++ .../pip/_vendor/distlib/index.py | 516 + .../pip/_vendor/distlib/locators.py | 1302 +++ .../pip/_vendor/distlib/manifest.py | 393 + .../pip/_vendor/distlib/markers.py | 131 + .../pip/_vendor/distlib/metadata.py | 1056 ++ .../pip/_vendor/distlib/resources.py | 355 + .../pip/_vendor/distlib/scripts.py | 419 + .../site-packages/pip/_vendor/distlib/t32.exe | Bin 0 -> 96768 bytes .../site-packages/pip/_vendor/distlib/t64.exe | Bin 0 -> 105984 bytes .../site-packages/pip/_vendor/distlib/util.py | 1761 ++++ .../pip/_vendor/distlib/version.py | 736 ++ .../site-packages/pip/_vendor/distlib/w32.exe | Bin 0 -> 90112 bytes .../site-packages/pip/_vendor/distlib/w64.exe | Bin 0 -> 99840 bytes .../pip/_vendor/distlib/wheel.py | 1018 ++ venv/Lib/site-packages/pip/_vendor/distro.py | 1230 +++ .../pip/_vendor/html5lib/__init__.py | 35 + .../pip/_vendor/html5lib/_ihatexml.py | 289 + .../pip/_vendor/html5lib/_inputstream.py | 918 ++ .../pip/_vendor/html5lib/_tokenizer.py | 1735 ++++ .../pip/_vendor/html5lib/_trie/__init__.py | 5 + .../pip/_vendor/html5lib/_trie/_base.py | 40 + .../pip/_vendor/html5lib/_trie/py.py | 67 + .../pip/_vendor/html5lib/_utils.py | 159 + .../pip/_vendor/html5lib/constants.py | 2946 ++++++ .../pip/_vendor/html5lib/filters/__init__.py | 0 .../filters/alphabeticalattributes.py | 29 + .../pip/_vendor/html5lib/filters/base.py | 12 + .../html5lib/filters/inject_meta_charset.py | 73 + .../pip/_vendor/html5lib/filters/lint.py | 93 + .../_vendor/html5lib/filters/optionaltags.py | 207 + .../pip/_vendor/html5lib/filters/sanitizer.py | 916 ++ .../_vendor/html5lib/filters/whitespace.py | 38 + .../pip/_vendor/html5lib/html5parser.py | 2795 ++++++ .../pip/_vendor/html5lib/serializer.py | 409 + .../_vendor/html5lib/treeadapters/__init__.py | 30 + .../_vendor/html5lib/treeadapters/genshi.py | 54 + .../pip/_vendor/html5lib/treeadapters/sax.py | 50 + .../_vendor/html5lib/treebuilders/__init__.py | 88 + .../pip/_vendor/html5lib/treebuilders/base.py | 417 + .../pip/_vendor/html5lib/treebuilders/dom.py | 239 + .../_vendor/html5lib/treebuilders/etree.py | 343 + .../html5lib/treebuilders/etree_lxml.py | 392 + .../_vendor/html5lib/treewalkers/__init__.py | 154 + .../pip/_vendor/html5lib/treewalkers/base.py | 252 + .../pip/_vendor/html5lib/treewalkers/dom.py | 43 + .../pip/_vendor/html5lib/treewalkers/etree.py | 131 + .../html5lib/treewalkers/etree_lxml.py | 215 + .../_vendor/html5lib/treewalkers/genshi.py | 69 + .../pip/_vendor/idna/__init__.py | 2 + .../site-packages/pip/_vendor/idna/codec.py | 118 + .../site-packages/pip/_vendor/idna/compat.py | 12 + .../site-packages/pip/_vendor/idna/core.py | 400 + .../pip/_vendor/idna/idnadata.py | 2050 ++++ .../pip/_vendor/idna/intranges.py | 53 + .../pip/_vendor/idna/package_data.py | 2 + .../pip/_vendor/idna/uts46data.py | 8357 ++++++++++++++++ .../pip/_vendor/msgpack/__init__.py | 54 + .../pip/_vendor/msgpack/_version.py | 1 + .../pip/_vendor/msgpack/exceptions.py | 48 + .../site-packages/pip/_vendor/msgpack/ext.py | 193 + .../pip/_vendor/msgpack/fallback.py | 1087 ++ .../pip/_vendor/packaging/__about__.py | 27 + .../pip/_vendor/packaging/__init__.py | 26 + .../pip/_vendor/packaging/_compat.py | 38 + .../pip/_vendor/packaging/_structures.py | 86 + .../pip/_vendor/packaging/_typing.py | 48 + .../pip/_vendor/packaging/markers.py | 336 + .../pip/_vendor/packaging/requirements.py | 160 + .../pip/_vendor/packaging/specifiers.py | 864 ++ .../pip/_vendor/packaging/tags.py | 866 ++ .../pip/_vendor/packaging/utils.py | 138 + .../pip/_vendor/packaging/version.py | 556 ++ .../pip/_vendor/pep517/__init__.py | 6 + .../pip/_vendor/pep517/_in_process.py | 280 + .../site-packages/pip/_vendor/pep517/build.py | 124 + .../site-packages/pip/_vendor/pep517/check.py | 203 + .../pip/_vendor/pep517/colorlog.py | 115 + .../pip/_vendor/pep517/compat.py | 34 + .../pip/_vendor/pep517/dirtools.py | 44 + .../pip/_vendor/pep517/envbuild.py | 167 + .../site-packages/pip/_vendor/pep517/meta.py | 92 + .../pip/_vendor/pep517/wrappers.py | 327 + .../pip/_vendor/pkg_resources/__init__.py | 3296 +++++++ .../pip/_vendor/pkg_resources/py31compat.py | 23 + .../pip/_vendor/progress/__init__.py | 177 + .../site-packages/pip/_vendor/progress/bar.py | 91 + .../pip/_vendor/progress/counter.py | 41 + .../pip/_vendor/progress/spinner.py | 43 + .../site-packages/pip/_vendor/pyparsing.py | 7107 ++++++++++++++ .../pip/_vendor/requests/__init__.py | 142 + .../pip/_vendor/requests/__version__.py | 14 + .../pip/_vendor/requests/_internal_utils.py | 42 + .../pip/_vendor/requests/adapters.py | 533 + .../site-packages/pip/_vendor/requests/api.py | 161 + .../pip/_vendor/requests/auth.py | 305 + .../pip/_vendor/requests/certs.py | 18 + .../pip/_vendor/requests/compat.py | 76 + .../pip/_vendor/requests/cookies.py | 549 ++ .../pip/_vendor/requests/exceptions.py | 123 + .../pip/_vendor/requests/help.py | 119 + .../pip/_vendor/requests/hooks.py | 34 + .../pip/_vendor/requests/models.py | 956 ++ .../pip/_vendor/requests/packages.py | 16 + .../pip/_vendor/requests/sessions.py | 781 ++ .../pip/_vendor/requests/status_codes.py | 123 + .../pip/_vendor/requests/structures.py | 105 + .../pip/_vendor/requests/utils.py | 992 ++ .../pip/_vendor/resolvelib/__init__.py | 26 + .../pip/_vendor/resolvelib/compat/__init__.py | 0 .../resolvelib/compat/collections_abc.py | 6 + .../pip/_vendor/resolvelib/providers.py | 119 + .../pip/_vendor/resolvelib/reporters.py | 37 + .../pip/_vendor/resolvelib/resolvers.py | 454 + .../pip/_vendor/resolvelib/structs.py | 149 + .../Lib/site-packages/pip/_vendor/retrying.py | 267 + venv/Lib/site-packages/pip/_vendor/six.py | 982 ++ .../pip/_vendor/toml/__init__.py | 25 + .../site-packages/pip/_vendor/toml/decoder.py | 1057 ++ .../site-packages/pip/_vendor/toml/encoder.py | 304 + .../site-packages/pip/_vendor/toml/ordered.py | 15 + venv/Lib/site-packages/pip/_vendor/toml/tz.py | 24 + .../pip/_vendor/urllib3/__init__.py | 85 + .../pip/_vendor/urllib3/_collections.py | 337 + .../pip/_vendor/urllib3/_version.py | 2 + .../pip/_vendor/urllib3/connection.py | 535 + .../pip/_vendor/urllib3/connectionpool.py | 1067 ++ .../pip/_vendor/urllib3/contrib/__init__.py | 0 .../urllib3/contrib/_appengine_environ.py | 36 + .../contrib/_securetransport/__init__.py | 0 .../contrib/_securetransport/bindings.py | 519 + .../contrib/_securetransport/low_level.py | 396 + .../pip/_vendor/urllib3/contrib/appengine.py | 314 + .../pip/_vendor/urllib3/contrib/ntlmpool.py | 121 + .../pip/_vendor/urllib3/contrib/pyopenssl.py | 509 + .../urllib3/contrib/securetransport.py | 920 ++ .../pip/_vendor/urllib3/contrib/socks.py | 216 + .../pip/_vendor/urllib3/exceptions.py | 313 + .../pip/_vendor/urllib3/fields.py | 274 + .../pip/_vendor/urllib3/filepost.py | 98 + .../pip/_vendor/urllib3/packages/__init__.py | 5 + .../urllib3/packages/backports/__init__.py | 0 .../urllib3/packages/backports/makefile.py | 51 + .../pip/_vendor/urllib3/packages/six.py | 1021 ++ .../packages/ssl_match_hostname/__init__.py | 22 + .../ssl_match_hostname/_implementation.py | 160 + .../pip/_vendor/urllib3/poolmanager.py | 536 + .../pip/_vendor/urllib3/request.py | 170 + .../pip/_vendor/urllib3/response.py | 821 ++ .../pip/_vendor/urllib3/util/__init__.py | 49 + .../pip/_vendor/urllib3/util/connection.py | 150 + .../pip/_vendor/urllib3/util/proxy.py | 56 + .../pip/_vendor/urllib3/util/queue.py | 22 + .../pip/_vendor/urllib3/util/request.py | 143 + .../pip/_vendor/urllib3/util/response.py | 107 + .../pip/_vendor/urllib3/util/retry.py | 601 ++ .../pip/_vendor/urllib3/util/ssl_.py | 474 + .../pip/_vendor/urllib3/util/ssltransport.py | 221 + .../pip/_vendor/urllib3/util/timeout.py | 268 + .../pip/_vendor/urllib3/util/url.py | 430 + .../pip/_vendor/urllib3/util/wait.py | 153 + venv/Lib/site-packages/pip/_vendor/vendor.txt | 23 + .../pip/_vendor/webencodings/__init__.py | 342 + .../pip/_vendor/webencodings/labels.py | 231 + .../pip/_vendor/webencodings/mklabels.py | 59 + .../pip/_vendor/webencodings/tests.py | 153 + .../_vendor/webencodings/x_user_defined.py | 325 + .../site-packages/pkg_resources/__init__.py | 3288 +++++++ .../pkg_resources/_vendor/__init__.py | 0 .../pkg_resources/_vendor/appdirs.py | 608 ++ .../_vendor/packaging/__about__.py | 27 + .../_vendor/packaging/__init__.py | 26 + .../_vendor/packaging/_compat.py | 38 + .../_vendor/packaging/_structures.py | 86 + .../_vendor/packaging/_typing.py | 48 + .../_vendor/packaging/markers.py | 328 + .../_vendor/packaging/requirements.py | 145 + .../_vendor/packaging/specifiers.py | 863 ++ .../pkg_resources/_vendor/packaging/tags.py | 751 ++ .../pkg_resources/_vendor/packaging/utils.py | 65 + .../_vendor/packaging/version.py | 535 + .../pkg_resources/_vendor/pyparsing.py | 5742 +++++++++++ .../pkg_resources/extern/__init__.py | 73 + .../data/my-test-package-source/setup.py | 6 + .../pygame-2.0.1.dist-info/INSTALLER | 1 + .../pygame-2.0.1.dist-info/METADATA | 203 + .../pygame-2.0.1.dist-info/RECORD | 563 ++ .../pygame-2.0.1.dist-info/REQUESTED | 0 .../pygame-2.0.1.dist-info/WHEEL | 5 + .../pygame-2.0.1.dist-info/entry_points.txt | 3 + .../pygame-2.0.1.dist-info/top_level.txt | 1 + venv/Lib/site-packages/pygame/SDL2.dll | Bin 0 -> 1561088 bytes venv/Lib/site-packages/pygame/SDL2_image.dll | Bin 0 -> 125440 bytes venv/Lib/site-packages/pygame/SDL2_mixer.dll | Bin 0 -> 123904 bytes venv/Lib/site-packages/pygame/SDL2_ttf.dll | Bin 0 -> 33792 bytes venv/Lib/site-packages/pygame/__init__.py | 364 + venv/Lib/site-packages/pygame/__init__.pyi | 71 + .../pygame/__pyinstaller/__init__.py | 5 + .../pygame/__pyinstaller/hook-pygame.py | 44 + .../pygame/_camera_opencv_highgui.py | 85 + .../pygame/_camera_vidcapture.py | 119 + .../Lib/site-packages/pygame/_dummybackend.py | 30 + .../site-packages/pygame/_numpysndarray.py | 74 + .../site-packages/pygame/_numpysurfarray.py | 352 + .../site-packages/pygame/_sdl2/__init__.py | 3 + .../site-packages/pygame/_sdl2/__init__.pyi | 1 + venv/Lib/site-packages/pygame/_sdl2/touch.pyi | 6 + venv/Lib/site-packages/pygame/bufferproxy.pyi | 13 + venv/Lib/site-packages/pygame/camera.py | 132 + venv/Lib/site-packages/pygame/camera.pyi | 27 + venv/Lib/site-packages/pygame/color.pyi | 39 + venv/Lib/site-packages/pygame/colordict.py | 686 ++ venv/Lib/site-packages/pygame/compat.py | 102 + venv/Lib/site-packages/pygame/constants.pyi | 558 ++ venv/Lib/site-packages/pygame/cursors.py | 468 + venv/Lib/site-packages/pygame/cursors.pyi | 77 + venv/Lib/site-packages/pygame/display.pyi | 88 + .../Lib/site-packages/pygame/docs/__init__.py | 12 + .../Lib/site-packages/pygame/docs/__main__.py | 28 + venv/Lib/site-packages/pygame/docs/logos.html | 44 + .../site-packages/pygame/docs/pygame_logo.gif | Bin 0 -> 25116 bytes .../pygame/docs/pygame_powered.gif | Bin 0 -> 10171 bytes .../pygame/docs/pygame_small.gif | Bin 0 -> 10286 bytes .../site-packages/pygame/docs/pygame_tiny.gif | Bin 0 -> 5485 bytes venv/Lib/site-packages/pygame/draw.pyi | 90 + venv/Lib/site-packages/pygame/draw_py.py | 589 ++ venv/Lib/site-packages/pygame/event.pyi | 28 + .../site-packages/pygame/examples/README.rst | 145 + .../site-packages/pygame/examples/__init__.py | 0 .../site-packages/pygame/examples/aacircle.py | 41 + .../site-packages/pygame/examples/aliens.py | 410 + .../pygame/examples/arraydemo.py | 129 + .../pygame/examples/audiocapture.py | 80 + .../pygame/examples/blend_fill.py | 115 + .../pygame/examples/blit_blends.py | 198 + .../site-packages/pygame/examples/camera.py | 105 + .../site-packages/pygame/examples/chimp.py | 203 + .../site-packages/pygame/examples/cursors.py | 105 + .../pygame/examples/data/BGR.png | Bin 0 -> 244 bytes .../pygame/examples/data/alien1.gif | Bin 0 -> 3826 bytes .../pygame/examples/data/alien1.jpg | Bin 0 -> 3103 bytes .../pygame/examples/data/alien1.png | Bin 0 -> 3522 bytes .../pygame/examples/data/alien2.gif | Bin 0 -> 3834 bytes .../pygame/examples/data/alien2.png | Bin 0 -> 3526 bytes .../pygame/examples/data/alien3.gif | Bin 0 -> 3829 bytes .../pygame/examples/data/alien3.png | Bin 0 -> 3518 bytes .../pygame/examples/data/arraydemo.bmp | Bin 0 -> 76854 bytes .../pygame/examples/data/asprite.bmp | Bin 0 -> 578 bytes .../pygame/examples/data/background.gif | Bin 0 -> 9133 bytes .../pygame/examples/data/black.ppm | 3076 ++++++ .../pygame/examples/data/blue.gif | Bin 0 -> 84 bytes .../pygame/examples/data/blue.mpg | Bin 0 -> 6144 bytes .../pygame/examples/data/bomb.gif | Bin 0 -> 1162 bytes .../pygame/examples/data/boom.wav | Bin 0 -> 12562 bytes .../pygame/examples/data/brick.png | Bin 0 -> 170 bytes .../pygame/examples/data/car_door.wav | Bin 0 -> 3910 bytes .../pygame/examples/data/chimp.bmp | Bin 0 -> 5498 bytes .../pygame/examples/data/city.png | Bin 0 -> 143 bytes .../pygame/examples/data/danger.gif | Bin 0 -> 2761 bytes .../pygame/examples/data/explosion1.gif | Bin 0 -> 6513 bytes .../pygame/examples/data/fist.bmp | Bin 0 -> 4378 bytes .../pygame/examples/data/green.pcx | Bin 0 -> 320 bytes .../pygame/examples/data/grey.pgm | 1028 ++ .../pygame/examples/data/house_lo.mp3 | Bin 0 -> 116320 bytes .../pygame/examples/data/house_lo.ogg | Bin 0 -> 31334 bytes .../pygame/examples/data/house_lo.wav | Bin 0 -> 78464 bytes .../pygame/examples/data/laplacian.png | Bin 0 -> 253 bytes .../pygame/examples/data/liquid.bmp | Bin 0 -> 11734 bytes .../pygame/examples/data/midikeys.png | Bin 0 -> 19666 bytes .../pygame/examples/data/oldplayer.gif | Bin 0 -> 1075 bytes .../pygame/examples/data/player1.gif | Bin 0 -> 3470 bytes .../pygame/examples/data/punch.wav | Bin 0 -> 4176 bytes .../pygame/examples/data/purple.xpm | 36 + .../pygame/examples/data/red.jpg | Bin 0 -> 1251 bytes .../pygame/examples/data/sans.ttf | Bin 0 -> 133088 bytes .../pygame/examples/data/secosmic_lo.wav | Bin 0 -> 18700 bytes .../pygame/examples/data/shot.gif | Bin 0 -> 129 bytes .../pygame/examples/data/static.png | Bin 0 -> 1202 bytes .../pygame/examples/data/turquoise.tif | Bin 0 -> 200870 bytes .../pygame/examples/data/whiff.wav | Bin 0 -> 5850 bytes .../pygame/examples/data/yellow.tga | Bin 0 -> 3116 bytes .../pygame/examples/data/yuv_1.pgm | 6 + .../pygame/examples/dropevent.py | 76 + .../pygame/examples/eventlist.py | 182 + .../pygame/examples/fastevents.py | 101 + .../pygame/examples/font_viewer.py | 269 + .../site-packages/pygame/examples/fonty.py | 97 + .../pygame/examples/freetype_misc.py | 177 + .../site-packages/pygame/examples/glcube.py | 589 ++ .../examples/headless_no_windows_needed.py | 50 + .../site-packages/pygame/examples/liquid.py | 88 + .../Lib/site-packages/pygame/examples/mask.py | 211 + .../Lib/site-packages/pygame/examples/midi.py | 877 ++ .../site-packages/pygame/examples/moveit.py | 71 + .../pygame/examples/music_drop_fade.py | 249 + .../site-packages/pygame/examples/overlay.py | 68 + .../pygame/examples/pixelarray.py | 140 + .../site-packages/pygame/examples/playmus.py | 152 + .../examples/prevent_display_stretching.py | 88 + .../pygame/examples/resizing_new.py | 43 + .../pygame/examples/scaletest.py | 157 + .../pygame/examples/scrap_clipboard.py | 94 + .../site-packages/pygame/examples/scroll.py | 191 + .../pygame/examples/setmodescale.py | 60 + .../site-packages/pygame/examples/sound.py | 44 + .../pygame/examples/sound_array_demos.py | 217 + .../pygame/examples/sprite_texture.py | 102 + .../site-packages/pygame/examples/stars.py | 102 + .../pygame/examples/testsprite.py | 262 + .../pygame/examples/textinput.py | 177 + .../site-packages/pygame/examples/vgrade.py | 100 + .../site-packages/pygame/examples/video.py | 160 + venv/Lib/site-packages/pygame/fastevent.pyi | 10 + venv/Lib/site-packages/pygame/font.pyi | 58 + .../Lib/site-packages/pygame/freesansbold.ttf | Bin 0 -> 98600 bytes venv/Lib/site-packages/pygame/freetype.py | 78 + venv/Lib/site-packages/pygame/freetype.pyi | 127 + venv/Lib/site-packages/pygame/ftfont.py | 190 + venv/Lib/site-packages/pygame/gfxdraw.pyi | 108 + venv/Lib/site-packages/pygame/image.pyi | 32 + venv/Lib/site-packages/pygame/joystick.pyi | 25 + venv/Lib/site-packages/pygame/key.pyi | 28 + venv/Lib/site-packages/pygame/libFLAC-8.dll | Bin 0 -> 441344 bytes .../site-packages/pygame/libfreetype-6.dll | Bin 0 -> 586240 bytes venv/Lib/site-packages/pygame/libjpeg-9.dll | Bin 0 -> 244224 bytes .../Lib/site-packages/pygame/libmodplug-1.dll | Bin 0 -> 252928 bytes venv/Lib/site-packages/pygame/libmpg123-0.dll | Bin 0 -> 337408 bytes venv/Lib/site-packages/pygame/libogg-0.dll | Bin 0 -> 52224 bytes venv/Lib/site-packages/pygame/libopus-0.dll | Bin 0 -> 124928 bytes .../site-packages/pygame/libopusfile-0.dll | Bin 0 -> 46592 bytes venv/Lib/site-packages/pygame/libpng16-16.dll | Bin 0 -> 210944 bytes venv/Lib/site-packages/pygame/libtiff-5.dll | Bin 0 -> 432640 bytes venv/Lib/site-packages/pygame/libvorbis-0.dll | Bin 0 -> 251904 bytes .../site-packages/pygame/libvorbisfile-3.dll | Bin 0 -> 69632 bytes venv/Lib/site-packages/pygame/libwebp-7.dll | Bin 0 -> 447488 bytes venv/Lib/site-packages/pygame/locals.py | 574 ++ venv/Lib/site-packages/pygame/macosx.py | 22 + venv/Lib/site-packages/pygame/mask.pyi | 82 + venv/Lib/site-packages/pygame/math.pyi | 262 + venv/Lib/site-packages/pygame/midi.py | 722 ++ venv/Lib/site-packages/pygame/midi.pyi | 60 + venv/Lib/site-packages/pygame/mixer.pyi | 84 + venv/Lib/site-packages/pygame/mouse.pyi | 35 + venv/Lib/site-packages/pygame/music.pyi | 20 + venv/Lib/site-packages/pygame/pixelarray.pyi | 38 + venv/Lib/site-packages/pygame/pixelcopy.pyi | 24 + venv/Lib/site-packages/pygame/pkgdata.py | 84 + venv/Lib/site-packages/pygame/portmidi.dll | Bin 0 -> 41984 bytes venv/Lib/site-packages/pygame/py.typed | 0 venv/Lib/site-packages/pygame/pygame.ico | Bin 0 -> 145516 bytes venv/Lib/site-packages/pygame/pygame_icon.bmp | Bin 0 -> 630 bytes .../Lib/site-packages/pygame/pygame_icon.icns | Bin 0 -> 53627 bytes venv/Lib/site-packages/pygame/pygame_icon.svg | 259 + .../Lib/site-packages/pygame/pygame_icon.tiff | Bin 0 -> 61604 bytes venv/Lib/site-packages/pygame/rect.pyi | 230 + venv/Lib/site-packages/pygame/scrap.pyi | 10 + venv/Lib/site-packages/pygame/sndarray.py | 120 + venv/Lib/site-packages/pygame/sndarray.pyi | 10 + venv/Lib/site-packages/pygame/sprite.py | 1745 ++++ venv/Lib/site-packages/pygame/sprite.pyi | 154 + venv/Lib/site-packages/pygame/surface.pyi | 130 + venv/Lib/site-packages/pygame/surfarray.py | 371 + venv/Lib/site-packages/pygame/surfarray.pyi | 20 + venv/Lib/site-packages/pygame/sysfont.py | 470 + .../site-packages/pygame/tests/__init__.py | 40 + .../site-packages/pygame/tests/__main__.py | 144 + .../site-packages/pygame/tests/base_test.py | 666 ++ .../site-packages/pygame/tests/blit_test.py | 157 + .../pygame/tests/bufferproxy_test.py | 509 + .../site-packages/pygame/tests/camera_test.py | 9 + .../site-packages/pygame/tests/cdrom_tags.py | 1 + .../site-packages/pygame/tests/cdrom_test.py | 321 + .../site-packages/pygame/tests/color_test.py | 1290 +++ .../site-packages/pygame/tests/compat_test.py | 89 + .../pygame/tests/constants_test.py | 458 + .../pygame/tests/cursors_test.py | 154 + .../pygame/tests/display_test.py | 716 ++ .../site-packages/pygame/tests/draw_test.py | 6468 ++++++++++++ .../site-packages/pygame/tests/event_test.py | 801 ++ .../pygame/tests/fastevent_tags.py | 1 + .../pygame/tests/fastevent_test.py | 158 + .../tests/fixtures/fonts/A_PyGameMono-8.png | Bin 0 -> 92 bytes .../fixtures/fonts/PyGameMono-18-100dpi.bdf | 165 + .../fixtures/fonts/PyGameMono-18-75dpi.bdf | 143 + .../tests/fixtures/fonts/PyGameMono-8.bdf | 103 + .../tests/fixtures/fonts/PyGameMono.otf | Bin 0 -> 3128 bytes .../tests/fixtures/fonts/test_fixed.otf | Bin 0 -> 58464 bytes .../pygame/tests/fixtures/fonts/test_sans.ttf | Bin 0 -> 133088 bytes .../fixtures/fonts/u13079_PyGameMono-8.png | Bin 0 -> 89 bytes .../fixtures/xbm_cursors/white_sizing.xbm | 8 + .../xbm_cursors/white_sizing_mask.xbm | 8 + .../site-packages/pygame/tests/font_tags.py | 1 + .../site-packages/pygame/tests/font_test.py | 640 ++ .../pygame/tests/freetype_tags.py | 11 + .../pygame/tests/freetype_test.py | 1821 ++++ .../site-packages/pygame/tests/ftfont_tags.py | 11 + .../site-packages/pygame/tests/ftfont_test.py | 19 + .../pygame/tests/gfxdraw_test.py | 877 ++ .../tests/image__save_gl_surface_test.py | 46 + .../site-packages/pygame/tests/image_tags.py | 7 + .../site-packages/pygame/tests/image_test.py | 924 ++ .../pygame/tests/imageext_tags.py | 7 + .../pygame/tests/imageext_test.py | 102 + .../pygame/tests/joystick_test.py | 161 + .../site-packages/pygame/tests/key_test.py | 112 + .../site-packages/pygame/tests/mask_test.py | 6446 ++++++++++++ .../site-packages/pygame/tests/math_test.py | 2145 ++++ .../site-packages/pygame/tests/midi_test.py | 475 + .../pygame/tests/mixer_music_tags.py | 7 + .../pygame/tests/mixer_music_test.py | 367 + .../site-packages/pygame/tests/mixer_tags.py | 7 + .../site-packages/pygame/tests/mixer_test.py | 1178 +++ .../site-packages/pygame/tests/mouse_test.py | 349 + .../pygame/tests/overlay_tags.py | 2 + .../pygame/tests/overlay_test.py | 37 + .../pygame/tests/pixelarray_test.py | 1640 ++++ .../pygame/tests/pixelcopy_test.py | 713 ++ .../site-packages/pygame/tests/rect_test.py | 2179 ++++ .../pygame/tests/run_tests__tests/__init__.py | 1 + .../tests/run_tests__tests/all_ok/__init__.py | 1 + .../run_tests__tests/all_ok/fake_2_test.py | 39 + .../run_tests__tests/all_ok/fake_3_test.py | 39 + .../run_tests__tests/all_ok/fake_4_test.py | 39 + .../run_tests__tests/all_ok/fake_5_test.py | 39 + .../run_tests__tests/all_ok/fake_6_test.py | 39 + .../no_assertions__ret_code_of_1__test.py | 39 + .../all_ok/zero_tests_test.py | 23 + .../run_tests__tests/everything/__init__.py | 1 + .../everything/fake_2_test.py | 39 + .../everything/incomplete_todo_test.py | 39 + .../everything/magic_tag_test.py | 38 + .../run_tests__tests/everything/sleep_test.py | 29 + .../run_tests__tests/exclude/__init__.py | 1 + .../run_tests__tests/exclude/fake_2_test.py | 39 + .../exclude/invisible_tag_test.py | 41 + .../exclude/magic_tag_test.py | 38 + .../run_tests__tests/failures1/__init__.py | 1 + .../run_tests__tests/failures1/fake_2_test.py | 39 + .../run_tests__tests/failures1/fake_3_test.py | 39 + .../run_tests__tests/failures1/fake_4_test.py | 41 + .../run_tests__tests/incomplete/__init__.py | 1 + .../incomplete/fake_2_test.py | 39 + .../incomplete/fake_3_test.py | 39 + .../incomplete_todo/__init__.py | 1 + .../incomplete_todo/fake_2_test.py | 39 + .../incomplete_todo/fake_3_test.py | 39 + .../infinite_loop/__init__.py | 1 + .../infinite_loop/fake_1_test.py | 40 + .../infinite_loop/fake_2_test.py | 39 + .../run_tests__tests/print_stderr/__init__.py | 1 + .../print_stderr/fake_2_test.py | 39 + .../print_stderr/fake_3_test.py | 41 + .../print_stderr/fake_4_test.py | 41 + .../run_tests__tests/print_stdout/__init__.py | 1 + .../print_stdout/fake_2_test.py | 39 + .../print_stdout/fake_3_test.py | 42 + .../print_stdout/fake_4_test.py | 41 + .../tests/run_tests__tests/run_tests__test.py | 145 + .../run_tests__tests/timeout/__init__.py | 1 + .../run_tests__tests/timeout/fake_2_test.py | 39 + .../run_tests__tests/timeout/sleep_test.py | 30 + .../pygame/tests/rwobject_test.py | 158 + .../site-packages/pygame/tests/scrap_tags.py | 21 + .../site-packages/pygame/tests/scrap_test.py | 302 + .../pygame/tests/sndarray_tags.py | 12 + .../pygame/tests/sndarray_test.py | 165 + .../site-packages/pygame/tests/sprite_test.py | 1406 +++ .../pygame/tests/surface_test.py | 4168 ++++++++ .../pygame/tests/surfarray_tags.py | 16 + .../pygame/tests/surfarray_test.py | 733 ++ .../pygame/tests/surflock_test.py | 144 + .../pygame/tests/sysfont_test.py | 48 + .../site-packages/pygame/tests/test_test_.py | 2 + .../pygame/tests/test_utils/__init__.py | 260 + .../pygame/tests/test_utils/arrinter.py | 451 + .../pygame/tests/test_utils/async_sub.py | 313 + .../pygame/tests/test_utils/buftools.py | 613 ++ .../pygame/tests/test_utils/endian.py | 20 + .../pygame/tests/test_utils/png.py | 4005 ++++++++ .../pygame/tests/test_utils/run_tests.py | 355 + .../pygame/tests/test_utils/test_machinery.py | 89 + .../pygame/tests/test_utils/test_runner.py | 333 + .../pygame/tests/threads_test.py | 244 + .../site-packages/pygame/tests/time_test.py | 343 + .../site-packages/pygame/tests/touch_tags.py | 1 + .../site-packages/pygame/tests/touch_test.py | 99 + .../pygame/tests/transform_test.py | 1300 +++ .../pygame/tests/version_test.py | 47 + .../site-packages/pygame/tests/video_test.py | 25 + .../site-packages/pygame/threads/__init__.py | 285 + venv/Lib/site-packages/pygame/time.pyi | 16 + venv/Lib/site-packages/pygame/transform.pyi | 50 + venv/Lib/site-packages/pygame/version.py | 64 + venv/Lib/site-packages/pygame/version.pyi | 15 + venv/Lib/site-packages/pygame/zlib1.dll | Bin 0 -> 108544 bytes .../setuptools-56.0.0.dist-info/INSTALLER | 1 + .../setuptools-56.0.0.dist-info/LICENSE | 19 + .../setuptools-56.0.0.dist-info/METADATA | 114 + .../setuptools-56.0.0.dist-info/RECORD | 294 + .../setuptools-56.0.0.dist-info/WHEEL | 5 + .../dependency_links.txt | 2 + .../entry_points.txt | 60 + .../setuptools-56.0.0.dist-info/top_level.txt | 3 + venv/Lib/site-packages/setuptools/__init__.py | 241 + .../setuptools/_deprecation_warning.py | 7 + .../setuptools/_distutils/__init__.py | 15 + .../setuptools/_distutils/_msvccompiler.py | 561 ++ .../setuptools/_distutils/archive_util.py | 256 + .../setuptools/_distutils/bcppcompiler.py | 393 + .../setuptools/_distutils/ccompiler.py | 1116 +++ .../setuptools/_distutils/cmd.py | 403 + .../setuptools/_distutils/command/__init__.py | 31 + .../setuptools/_distutils/command/bdist.py | 143 + .../_distutils/command/bdist_dumb.py | 123 + .../_distutils/command/bdist_msi.py | 749 ++ .../_distutils/command/bdist_rpm.py | 579 ++ .../_distutils/command/bdist_wininst.py | 377 + .../setuptools/_distutils/command/build.py | 157 + .../_distutils/command/build_clib.py | 209 + .../_distutils/command/build_ext.py | 755 ++ .../setuptools/_distutils/command/build_py.py | 416 + .../_distutils/command/build_scripts.py | 160 + .../setuptools/_distutils/command/check.py | 148 + .../setuptools/_distutils/command/clean.py | 76 + .../setuptools/_distutils/command/config.py | 344 + .../setuptools/_distutils/command/install.py | 677 ++ .../_distutils/command/install_data.py | 79 + .../_distutils/command/install_egg_info.py | 77 + .../_distutils/command/install_headers.py | 47 + .../_distutils/command/install_lib.py | 217 + .../_distutils/command/install_scripts.py | 60 + .../_distutils/command/py37compat.py | 30 + .../setuptools/_distutils/command/register.py | 304 + .../setuptools/_distutils/command/sdist.py | 494 + .../setuptools/_distutils/command/upload.py | 214 + .../setuptools/_distutils/config.py | 130 + .../setuptools/_distutils/core.py | 234 + .../setuptools/_distutils/cygwinccompiler.py | 403 + .../setuptools/_distutils/debug.py | 5 + .../setuptools/_distutils/dep_util.py | 92 + .../setuptools/_distutils/dir_util.py | 210 + .../setuptools/_distutils/dist.py | 1257 +++ .../setuptools/_distutils/errors.py | 97 + .../setuptools/_distutils/extension.py | 240 + .../setuptools/_distutils/fancy_getopt.py | 457 + .../setuptools/_distutils/file_util.py | 238 + .../setuptools/_distutils/filelist.py | 327 + .../setuptools/_distutils/log.py | 77 + .../setuptools/_distutils/msvc9compiler.py | 788 ++ .../setuptools/_distutils/msvccompiler.py | 643 ++ .../setuptools/_distutils/py35compat.py | 19 + .../setuptools/_distutils/py38compat.py | 7 + .../setuptools/_distutils/spawn.py | 125 + .../setuptools/_distutils/sysconfig.py | 573 ++ .../setuptools/_distutils/text_file.py | 286 + .../setuptools/_distutils/unixccompiler.py | 328 + .../setuptools/_distutils/util.py | 561 ++ .../setuptools/_distutils/version.py | 347 + .../setuptools/_distutils/versionpredicate.py | 166 + venv/Lib/site-packages/setuptools/_imp.py | 82 + .../setuptools/_vendor/__init__.py | 0 .../setuptools/_vendor/ordered_set.py | 488 + .../setuptools/_vendor/packaging/__about__.py | 27 + .../setuptools/_vendor/packaging/__init__.py | 26 + .../setuptools/_vendor/packaging/_compat.py | 38 + .../_vendor/packaging/_structures.py | 86 + .../setuptools/_vendor/packaging/_typing.py | 48 + .../setuptools/_vendor/packaging/markers.py | 328 + .../_vendor/packaging/requirements.py | 145 + .../_vendor/packaging/specifiers.py | 863 ++ .../setuptools/_vendor/packaging/tags.py | 751 ++ .../setuptools/_vendor/packaging/utils.py | 65 + .../setuptools/_vendor/packaging/version.py | 535 + .../setuptools/_vendor/pyparsing.py | 5742 +++++++++++ .../site-packages/setuptools/archive_util.py | 205 + .../site-packages/setuptools/build_meta.py | 281 + venv/Lib/site-packages/setuptools/cli-32.exe | Bin 0 -> 65536 bytes venv/Lib/site-packages/setuptools/cli-64.exe | Bin 0 -> 74752 bytes venv/Lib/site-packages/setuptools/cli.exe | Bin 0 -> 65536 bytes .../setuptools/command/__init__.py | 17 + .../site-packages/setuptools/command/alias.py | 78 + .../setuptools/command/bdist_egg.py | 456 + .../setuptools/command/bdist_rpm.py | 31 + .../setuptools/command/build_clib.py | 101 + .../setuptools/command/build_ext.py | 322 + .../setuptools/command/build_py.py | 270 + .../setuptools/command/develop.py | 216 + .../setuptools/command/dist_info.py | 36 + .../setuptools/command/easy_install.py | 2290 +++++ .../setuptools/command/egg_info.py | 727 ++ .../setuptools/command/install.py | 125 + .../setuptools/command/install_egg_info.py | 62 + .../setuptools/command/install_lib.py | 122 + .../setuptools/command/install_scripts.py | 69 + .../setuptools/command/launcher manifest.xml | 15 + .../setuptools/command/py36compat.py | 134 + .../setuptools/command/register.py | 18 + .../setuptools/command/rotate.py | 64 + .../setuptools/command/saveopts.py | 22 + .../site-packages/setuptools/command/sdist.py | 235 + .../setuptools/command/setopt.py | 148 + .../site-packages/setuptools/command/test.py | 274 + .../setuptools/command/upload.py | 17 + .../setuptools/command/upload_docs.py | 202 + venv/Lib/site-packages/setuptools/config.py | 710 ++ venv/Lib/site-packages/setuptools/dep_util.py | 25 + venv/Lib/site-packages/setuptools/depends.py | 175 + venv/Lib/site-packages/setuptools/dist.py | 1057 ++ venv/Lib/site-packages/setuptools/errors.py | 16 + .../Lib/site-packages/setuptools/extension.py | 55 + .../setuptools/extern/__init__.py | 73 + venv/Lib/site-packages/setuptools/glob.py | 167 + venv/Lib/site-packages/setuptools/gui-32.exe | Bin 0 -> 65536 bytes venv/Lib/site-packages/setuptools/gui-64.exe | Bin 0 -> 75264 bytes venv/Lib/site-packages/setuptools/gui.exe | Bin 0 -> 65536 bytes .../Lib/site-packages/setuptools/installer.py | 97 + venv/Lib/site-packages/setuptools/launch.py | 36 + .../site-packages/setuptools/lib2to3_ex.py | 68 + venv/Lib/site-packages/setuptools/monkey.py | 177 + venv/Lib/site-packages/setuptools/msvc.py | 1826 ++++ .../site-packages/setuptools/namespaces.py | 107 + .../site-packages/setuptools/package_index.py | 1145 +++ .../site-packages/setuptools/py34compat.py | 13 + venv/Lib/site-packages/setuptools/sandbox.py | 496 + .../setuptools/script (dev).tmpl | 6 + venv/Lib/site-packages/setuptools/script.tmpl | 3 + .../site-packages/setuptools/ssl_support.py | 266 + .../site-packages/setuptools/unicode_utils.py | 42 + venv/Lib/site-packages/setuptools/version.py | 6 + venv/Lib/site-packages/setuptools/wheel.py | 213 + .../setuptools/windows_support.py | 29 + venv/Scripts/Activate.ps1 | 398 + venv/Scripts/activate | 66 + venv/Scripts/activate.bat | 33 + venv/Scripts/deactivate.bat | 21 + venv/Scripts/f2py.exe | Bin 0 -> 106353 bytes venv/Scripts/pgzrun.exe | Bin 0 -> 106349 bytes venv/Scripts/pip.exe | Bin 0 -> 106358 bytes venv/Scripts/pip3.9.exe | Bin 0 -> 106358 bytes venv/Scripts/pip3.exe | Bin 0 -> 106358 bytes venv/Scripts/python.exe | Bin 0 -> 539312 bytes venv/Scripts/pythonw.exe | Bin 0 -> 537776 bytes venv/pyvenv.cfg | 3 + 1524 files changed, 540675 insertions(+), 4 deletions(-) create mode 100644 venv/Include/site/python3.9/pygame/_camera.h create mode 100644 venv/Include/site/python3.9/pygame/_pygame.h create mode 100644 venv/Include/site/python3.9/pygame/_surface.h create mode 100644 venv/Include/site/python3.9/pygame/camera.h create mode 100644 venv/Include/site/python3.9/pygame/fastevents.h create mode 100644 venv/Include/site/python3.9/pygame/font.h create mode 100644 venv/Include/site/python3.9/pygame/freetype.h create mode 100644 venv/Include/site/python3.9/pygame/include/_pygame.h create mode 100644 venv/Include/site/python3.9/pygame/include/bitmask.h create mode 100644 venv/Include/site/python3.9/pygame/include/pgcompat.h create mode 100644 venv/Include/site/python3.9/pygame/include/pgimport.h create mode 100644 venv/Include/site/python3.9/pygame/include/pgplatform.h create mode 100644 venv/Include/site/python3.9/pygame/include/pygame.h create mode 100644 venv/Include/site/python3.9/pygame/include/pygame_bufferproxy.h create mode 100644 venv/Include/site/python3.9/pygame/include/pygame_font.h create mode 100644 venv/Include/site/python3.9/pygame/include/pygame_freetype.h create mode 100644 venv/Include/site/python3.9/pygame/include/pygame_mask.h create mode 100644 venv/Include/site/python3.9/pygame/include/pygame_mixer.h create mode 100644 venv/Include/site/python3.9/pygame/include/sse2neon.h create mode 100644 venv/Include/site/python3.9/pygame/mask.h create mode 100644 venv/Include/site/python3.9/pygame/mixer.h create mode 100644 venv/Include/site/python3.9/pygame/palette.h create mode 100644 venv/Include/site/python3.9/pygame/pgarrinter.h create mode 100644 venv/Include/site/python3.9/pygame/pgbufferproxy.h create mode 100644 venv/Include/site/python3.9/pygame/pgcompat.h create mode 100644 venv/Include/site/python3.9/pygame/pgimport.h create mode 100644 venv/Include/site/python3.9/pygame/pgopengl.h create mode 100644 venv/Include/site/python3.9/pygame/pgplatform.h create mode 100644 venv/Include/site/python3.9/pygame/pygame.h create mode 100644 venv/Include/site/python3.9/pygame/scrap.h create mode 100644 venv/Include/site/python3.9/pygame/surface.h create mode 100644 venv/Lib/site-packages/_distutils_hack/__init__.py create mode 100644 venv/Lib/site-packages/_distutils_hack/override.py create mode 100644 venv/Lib/site-packages/distutils-precedence.pth create mode 100644 venv/Lib/site-packages/numpy-1.20.2.dist-info/INSTALLER create mode 100644 venv/Lib/site-packages/numpy-1.20.2.dist-info/LICENSE.txt create mode 100644 venv/Lib/site-packages/numpy-1.20.2.dist-info/LICENSES_bundled.txt create mode 100644 venv/Lib/site-packages/numpy-1.20.2.dist-info/METADATA create mode 100644 venv/Lib/site-packages/numpy-1.20.2.dist-info/RECORD create mode 100644 venv/Lib/site-packages/numpy-1.20.2.dist-info/REQUESTED create mode 100644 venv/Lib/site-packages/numpy-1.20.2.dist-info/WHEEL create mode 100644 venv/Lib/site-packages/numpy-1.20.2.dist-info/entry_points.txt create mode 100644 venv/Lib/site-packages/numpy-1.20.2.dist-info/top_level.txt create mode 100644 venv/Lib/site-packages/numpy/.libs/libopenblas.GK7GX5KEQ4F6UYO3P26ULGBQYHGQO7J4.gfortran-win_amd64.dll create mode 100644 venv/Lib/site-packages/numpy/LICENSE.txt create mode 100644 venv/Lib/site-packages/numpy/__config__.py create mode 100644 venv/Lib/site-packages/numpy/__init__.cython-30.pxd create mode 100644 venv/Lib/site-packages/numpy/__init__.pxd create mode 100644 venv/Lib/site-packages/numpy/__init__.py create mode 100644 venv/Lib/site-packages/numpy/__init__.pyi create mode 100644 venv/Lib/site-packages/numpy/_distributor_init.py create mode 100644 venv/Lib/site-packages/numpy/_globals.py create mode 100644 venv/Lib/site-packages/numpy/_pytesttester.py create mode 100644 venv/Lib/site-packages/numpy/char.pyi create mode 100644 venv/Lib/site-packages/numpy/compat/__init__.py create mode 100644 venv/Lib/site-packages/numpy/compat/_inspect.py create mode 100644 venv/Lib/site-packages/numpy/compat/py3k.py create mode 100644 venv/Lib/site-packages/numpy/compat/setup.py create mode 100644 venv/Lib/site-packages/numpy/compat/tests/__init__.py create mode 100644 venv/Lib/site-packages/numpy/compat/tests/test_compat.py create mode 100644 venv/Lib/site-packages/numpy/conftest.py create mode 100644 venv/Lib/site-packages/numpy/core/__init__.py create mode 100644 venv/Lib/site-packages/numpy/core/__init__.pyi create mode 100644 venv/Lib/site-packages/numpy/core/_add_newdocs.py create mode 100644 venv/Lib/site-packages/numpy/core/_add_newdocs_scalars.py create mode 100644 venv/Lib/site-packages/numpy/core/_asarray.py create mode 100644 venv/Lib/site-packages/numpy/core/_asarray.pyi create mode 100644 venv/Lib/site-packages/numpy/core/_dtype.py create mode 100644 venv/Lib/site-packages/numpy/core/_dtype_ctypes.py create mode 100644 venv/Lib/site-packages/numpy/core/_exceptions.py create mode 100644 venv/Lib/site-packages/numpy/core/_internal.py create mode 100644 venv/Lib/site-packages/numpy/core/_internal.pyi create mode 100644 venv/Lib/site-packages/numpy/core/_methods.py create mode 100644 venv/Lib/site-packages/numpy/core/_string_helpers.py create mode 100644 venv/Lib/site-packages/numpy/core/_type_aliases.py create mode 100644 venv/Lib/site-packages/numpy/core/_type_aliases.pyi create mode 100644 venv/Lib/site-packages/numpy/core/_ufunc_config.py create mode 100644 venv/Lib/site-packages/numpy/core/_ufunc_config.pyi create mode 100644 venv/Lib/site-packages/numpy/core/arrayprint.py create mode 100644 venv/Lib/site-packages/numpy/core/cversions.py create mode 100644 venv/Lib/site-packages/numpy/core/defchararray.py create mode 100644 venv/Lib/site-packages/numpy/core/einsumfunc.py create mode 100644 venv/Lib/site-packages/numpy/core/fromnumeric.py create mode 100644 venv/Lib/site-packages/numpy/core/fromnumeric.pyi create mode 100644 venv/Lib/site-packages/numpy/core/function_base.py create mode 100644 venv/Lib/site-packages/numpy/core/function_base.pyi create mode 100644 venv/Lib/site-packages/numpy/core/generate_numpy_api.py create mode 100644 venv/Lib/site-packages/numpy/core/getlimits.py create mode 100644 venv/Lib/site-packages/numpy/core/include/numpy/__multiarray_api.h create mode 100644 venv/Lib/site-packages/numpy/core/include/numpy/__ufunc_api.h create mode 100644 venv/Lib/site-packages/numpy/core/include/numpy/_neighborhood_iterator_imp.h create mode 100644 venv/Lib/site-packages/numpy/core/include/numpy/_numpyconfig.h create mode 100644 venv/Lib/site-packages/numpy/core/include/numpy/arrayobject.h create mode 100644 venv/Lib/site-packages/numpy/core/include/numpy/arrayscalars.h create mode 100644 venv/Lib/site-packages/numpy/core/include/numpy/halffloat.h create mode 100644 venv/Lib/site-packages/numpy/core/include/numpy/multiarray_api.txt create mode 100644 venv/Lib/site-packages/numpy/core/include/numpy/ndarrayobject.h create mode 100644 venv/Lib/site-packages/numpy/core/include/numpy/ndarraytypes.h create mode 100644 venv/Lib/site-packages/numpy/core/include/numpy/noprefix.h create mode 100644 venv/Lib/site-packages/numpy/core/include/numpy/npy_1_7_deprecated_api.h create mode 100644 venv/Lib/site-packages/numpy/core/include/numpy/npy_3kcompat.h create mode 100644 venv/Lib/site-packages/numpy/core/include/numpy/npy_common.h create mode 100644 venv/Lib/site-packages/numpy/core/include/numpy/npy_cpu.h create mode 100644 venv/Lib/site-packages/numpy/core/include/numpy/npy_endian.h create mode 100644 venv/Lib/site-packages/numpy/core/include/numpy/npy_interrupt.h create mode 100644 venv/Lib/site-packages/numpy/core/include/numpy/npy_math.h create mode 100644 venv/Lib/site-packages/numpy/core/include/numpy/npy_no_deprecated_api.h create mode 100644 venv/Lib/site-packages/numpy/core/include/numpy/npy_os.h create mode 100644 venv/Lib/site-packages/numpy/core/include/numpy/numpyconfig.h create mode 100644 venv/Lib/site-packages/numpy/core/include/numpy/old_defines.h create mode 100644 venv/Lib/site-packages/numpy/core/include/numpy/oldnumeric.h create mode 100644 venv/Lib/site-packages/numpy/core/include/numpy/random/bitgen.h create mode 100644 venv/Lib/site-packages/numpy/core/include/numpy/random/distributions.h create mode 100644 venv/Lib/site-packages/numpy/core/include/numpy/ufunc_api.txt create mode 100644 venv/Lib/site-packages/numpy/core/include/numpy/ufuncobject.h create mode 100644 venv/Lib/site-packages/numpy/core/include/numpy/utils.h create mode 100644 venv/Lib/site-packages/numpy/core/lib/npy-pkg-config/mlib.ini create mode 100644 venv/Lib/site-packages/numpy/core/lib/npy-pkg-config/npymath.ini create mode 100644 venv/Lib/site-packages/numpy/core/lib/npymath.lib create mode 100644 venv/Lib/site-packages/numpy/core/machar.py create mode 100644 venv/Lib/site-packages/numpy/core/memmap.py create mode 100644 venv/Lib/site-packages/numpy/core/multiarray.py create mode 100644 venv/Lib/site-packages/numpy/core/numeric.py create mode 100644 venv/Lib/site-packages/numpy/core/numeric.pyi create mode 100644 venv/Lib/site-packages/numpy/core/numerictypes.py create mode 100644 venv/Lib/site-packages/numpy/core/numerictypes.pyi create mode 100644 venv/Lib/site-packages/numpy/core/overrides.py create mode 100644 venv/Lib/site-packages/numpy/core/records.py create mode 100644 venv/Lib/site-packages/numpy/core/setup.py create mode 100644 venv/Lib/site-packages/numpy/core/setup_common.py create mode 100644 venv/Lib/site-packages/numpy/core/shape_base.py create mode 100644 venv/Lib/site-packages/numpy/core/shape_base.pyi create mode 100644 venv/Lib/site-packages/numpy/core/tests/__init__.py create mode 100644 venv/Lib/site-packages/numpy/core/tests/_locales.py create mode 100644 venv/Lib/site-packages/numpy/core/tests/data/astype_copy.pkl create mode 100644 venv/Lib/site-packages/numpy/core/tests/data/recarray_from_file.fits create mode 100644 venv/Lib/site-packages/numpy/core/tests/data/umath-validation-set-README create mode 100644 venv/Lib/site-packages/numpy/core/tests/data/umath-validation-set-cos create mode 100644 venv/Lib/site-packages/numpy/core/tests/data/umath-validation-set-exp create mode 100644 venv/Lib/site-packages/numpy/core/tests/data/umath-validation-set-log create mode 100644 venv/Lib/site-packages/numpy/core/tests/data/umath-validation-set-sin create mode 100644 venv/Lib/site-packages/numpy/core/tests/examples/checks.pyx create mode 100644 venv/Lib/site-packages/numpy/core/tests/examples/setup.py create mode 100644 venv/Lib/site-packages/numpy/core/tests/test__exceptions.py create mode 100644 venv/Lib/site-packages/numpy/core/tests/test_abc.py create mode 100644 venv/Lib/site-packages/numpy/core/tests/test_api.py create mode 100644 venv/Lib/site-packages/numpy/core/tests/test_array_coercion.py create mode 100644 venv/Lib/site-packages/numpy/core/tests/test_arrayprint.py create mode 100644 venv/Lib/site-packages/numpy/core/tests/test_casting_unittests.py create mode 100644 venv/Lib/site-packages/numpy/core/tests/test_conversion_utils.py create mode 100644 venv/Lib/site-packages/numpy/core/tests/test_cpu_dispatcher.py create mode 100644 venv/Lib/site-packages/numpy/core/tests/test_cpu_features.py create mode 100644 venv/Lib/site-packages/numpy/core/tests/test_cython.py create mode 100644 venv/Lib/site-packages/numpy/core/tests/test_datetime.py create mode 100644 venv/Lib/site-packages/numpy/core/tests/test_defchararray.py create mode 100644 venv/Lib/site-packages/numpy/core/tests/test_deprecations.py create mode 100644 venv/Lib/site-packages/numpy/core/tests/test_dtype.py create mode 100644 venv/Lib/site-packages/numpy/core/tests/test_einsum.py create mode 100644 venv/Lib/site-packages/numpy/core/tests/test_errstate.py create mode 100644 venv/Lib/site-packages/numpy/core/tests/test_extint128.py create mode 100644 venv/Lib/site-packages/numpy/core/tests/test_function_base.py create mode 100644 venv/Lib/site-packages/numpy/core/tests/test_getlimits.py create mode 100644 venv/Lib/site-packages/numpy/core/tests/test_half.py create mode 100644 venv/Lib/site-packages/numpy/core/tests/test_indexerrors.py create mode 100644 venv/Lib/site-packages/numpy/core/tests/test_indexing.py create mode 100644 venv/Lib/site-packages/numpy/core/tests/test_item_selection.py create mode 100644 venv/Lib/site-packages/numpy/core/tests/test_longdouble.py create mode 100644 venv/Lib/site-packages/numpy/core/tests/test_machar.py create mode 100644 venv/Lib/site-packages/numpy/core/tests/test_mem_overlap.py create mode 100644 venv/Lib/site-packages/numpy/core/tests/test_memmap.py create mode 100644 venv/Lib/site-packages/numpy/core/tests/test_multiarray.py create mode 100644 venv/Lib/site-packages/numpy/core/tests/test_nditer.py create mode 100644 venv/Lib/site-packages/numpy/core/tests/test_numeric.py create mode 100644 venv/Lib/site-packages/numpy/core/tests/test_numerictypes.py create mode 100644 venv/Lib/site-packages/numpy/core/tests/test_overrides.py create mode 100644 venv/Lib/site-packages/numpy/core/tests/test_print.py create mode 100644 venv/Lib/site-packages/numpy/core/tests/test_protocols.py create mode 100644 venv/Lib/site-packages/numpy/core/tests/test_records.py create mode 100644 venv/Lib/site-packages/numpy/core/tests/test_regression.py create mode 100644 venv/Lib/site-packages/numpy/core/tests/test_scalar_ctors.py create mode 100644 venv/Lib/site-packages/numpy/core/tests/test_scalar_methods.py create mode 100644 venv/Lib/site-packages/numpy/core/tests/test_scalarbuffer.py create mode 100644 venv/Lib/site-packages/numpy/core/tests/test_scalarinherit.py create mode 100644 venv/Lib/site-packages/numpy/core/tests/test_scalarmath.py create mode 100644 venv/Lib/site-packages/numpy/core/tests/test_scalarprint.py create mode 100644 venv/Lib/site-packages/numpy/core/tests/test_shape_base.py create mode 100644 venv/Lib/site-packages/numpy/core/tests/test_simd.py create mode 100644 venv/Lib/site-packages/numpy/core/tests/test_simd_module.py create mode 100644 venv/Lib/site-packages/numpy/core/tests/test_ufunc.py create mode 100644 venv/Lib/site-packages/numpy/core/tests/test_umath.py create mode 100644 venv/Lib/site-packages/numpy/core/tests/test_umath_accuracy.py create mode 100644 venv/Lib/site-packages/numpy/core/tests/test_umath_complex.py create mode 100644 venv/Lib/site-packages/numpy/core/tests/test_unicode.py create mode 100644 venv/Lib/site-packages/numpy/core/umath.py create mode 100644 venv/Lib/site-packages/numpy/core/umath_tests.py create mode 100644 venv/Lib/site-packages/numpy/ctypeslib.py create mode 100644 venv/Lib/site-packages/numpy/ctypeslib.pyi create mode 100644 venv/Lib/site-packages/numpy/distutils/__config__.py create mode 100644 venv/Lib/site-packages/numpy/distutils/__init__.py create mode 100644 venv/Lib/site-packages/numpy/distutils/__init__.pyi create mode 100644 venv/Lib/site-packages/numpy/distutils/_shell_utils.py create mode 100644 venv/Lib/site-packages/numpy/distutils/ccompiler.py create mode 100644 venv/Lib/site-packages/numpy/distutils/ccompiler_opt.py create mode 100644 venv/Lib/site-packages/numpy/distutils/checks/cpu_asimd.c create mode 100644 venv/Lib/site-packages/numpy/distutils/checks/cpu_asimddp.c create mode 100644 venv/Lib/site-packages/numpy/distutils/checks/cpu_asimdfhm.c create mode 100644 venv/Lib/site-packages/numpy/distutils/checks/cpu_asimdhp.c create mode 100644 venv/Lib/site-packages/numpy/distutils/checks/cpu_avx.c create mode 100644 venv/Lib/site-packages/numpy/distutils/checks/cpu_avx2.c create mode 100644 venv/Lib/site-packages/numpy/distutils/checks/cpu_avx512_clx.c create mode 100644 venv/Lib/site-packages/numpy/distutils/checks/cpu_avx512_cnl.c create mode 100644 venv/Lib/site-packages/numpy/distutils/checks/cpu_avx512_icl.c create mode 100644 venv/Lib/site-packages/numpy/distutils/checks/cpu_avx512_knl.c create mode 100644 venv/Lib/site-packages/numpy/distutils/checks/cpu_avx512_knm.c create mode 100644 venv/Lib/site-packages/numpy/distutils/checks/cpu_avx512_skx.c create mode 100644 venv/Lib/site-packages/numpy/distutils/checks/cpu_avx512cd.c create mode 100644 venv/Lib/site-packages/numpy/distutils/checks/cpu_avx512f.c create mode 100644 venv/Lib/site-packages/numpy/distutils/checks/cpu_f16c.c create mode 100644 venv/Lib/site-packages/numpy/distutils/checks/cpu_fma3.c create mode 100644 venv/Lib/site-packages/numpy/distutils/checks/cpu_fma4.c create mode 100644 venv/Lib/site-packages/numpy/distutils/checks/cpu_neon.c create mode 100644 venv/Lib/site-packages/numpy/distutils/checks/cpu_neon_fp16.c create mode 100644 venv/Lib/site-packages/numpy/distutils/checks/cpu_neon_vfpv4.c create mode 100644 venv/Lib/site-packages/numpy/distutils/checks/cpu_popcnt.c create mode 100644 venv/Lib/site-packages/numpy/distutils/checks/cpu_sse.c create mode 100644 venv/Lib/site-packages/numpy/distutils/checks/cpu_sse2.c create mode 100644 venv/Lib/site-packages/numpy/distutils/checks/cpu_sse3.c create mode 100644 venv/Lib/site-packages/numpy/distutils/checks/cpu_sse41.c create mode 100644 venv/Lib/site-packages/numpy/distutils/checks/cpu_sse42.c create mode 100644 venv/Lib/site-packages/numpy/distutils/checks/cpu_ssse3.c create mode 100644 venv/Lib/site-packages/numpy/distutils/checks/cpu_vsx.c create mode 100644 venv/Lib/site-packages/numpy/distutils/checks/cpu_vsx2.c create mode 100644 venv/Lib/site-packages/numpy/distutils/checks/cpu_vsx3.c create mode 100644 venv/Lib/site-packages/numpy/distutils/checks/cpu_xop.c create mode 100644 venv/Lib/site-packages/numpy/distutils/checks/extra_avx512bw_mask.c create mode 100644 venv/Lib/site-packages/numpy/distutils/checks/extra_avx512dq_mask.c create mode 100644 venv/Lib/site-packages/numpy/distutils/checks/extra_avx512f_reduce.c create mode 100644 venv/Lib/site-packages/numpy/distutils/checks/test_flags.c create mode 100644 venv/Lib/site-packages/numpy/distutils/command/__init__.py create mode 100644 venv/Lib/site-packages/numpy/distutils/command/autodist.py create mode 100644 venv/Lib/site-packages/numpy/distutils/command/bdist_rpm.py create mode 100644 venv/Lib/site-packages/numpy/distutils/command/build.py create mode 100644 venv/Lib/site-packages/numpy/distutils/command/build_clib.py create mode 100644 venv/Lib/site-packages/numpy/distutils/command/build_ext.py create mode 100644 venv/Lib/site-packages/numpy/distutils/command/build_py.py create mode 100644 venv/Lib/site-packages/numpy/distutils/command/build_scripts.py create mode 100644 venv/Lib/site-packages/numpy/distutils/command/build_src.py create mode 100644 venv/Lib/site-packages/numpy/distutils/command/config.py create mode 100644 venv/Lib/site-packages/numpy/distutils/command/config_compiler.py create mode 100644 venv/Lib/site-packages/numpy/distutils/command/develop.py create mode 100644 venv/Lib/site-packages/numpy/distutils/command/egg_info.py create mode 100644 venv/Lib/site-packages/numpy/distutils/command/install.py create mode 100644 venv/Lib/site-packages/numpy/distutils/command/install_clib.py create mode 100644 venv/Lib/site-packages/numpy/distutils/command/install_data.py create mode 100644 venv/Lib/site-packages/numpy/distutils/command/install_headers.py create mode 100644 venv/Lib/site-packages/numpy/distutils/command/sdist.py create mode 100644 venv/Lib/site-packages/numpy/distutils/conv_template.py create mode 100644 venv/Lib/site-packages/numpy/distutils/core.py create mode 100644 venv/Lib/site-packages/numpy/distutils/cpuinfo.py create mode 100644 venv/Lib/site-packages/numpy/distutils/exec_command.py create mode 100644 venv/Lib/site-packages/numpy/distutils/extension.py create mode 100644 venv/Lib/site-packages/numpy/distutils/fcompiler/__init__.py create mode 100644 venv/Lib/site-packages/numpy/distutils/fcompiler/absoft.py create mode 100644 venv/Lib/site-packages/numpy/distutils/fcompiler/compaq.py create mode 100644 venv/Lib/site-packages/numpy/distutils/fcompiler/environment.py create mode 100644 venv/Lib/site-packages/numpy/distutils/fcompiler/fujitsu.py create mode 100644 venv/Lib/site-packages/numpy/distutils/fcompiler/g95.py create mode 100644 venv/Lib/site-packages/numpy/distutils/fcompiler/gnu.py create mode 100644 venv/Lib/site-packages/numpy/distutils/fcompiler/hpux.py create mode 100644 venv/Lib/site-packages/numpy/distutils/fcompiler/ibm.py create mode 100644 venv/Lib/site-packages/numpy/distutils/fcompiler/intel.py create mode 100644 venv/Lib/site-packages/numpy/distutils/fcompiler/lahey.py create mode 100644 venv/Lib/site-packages/numpy/distutils/fcompiler/mips.py create mode 100644 venv/Lib/site-packages/numpy/distutils/fcompiler/nag.py create mode 100644 venv/Lib/site-packages/numpy/distutils/fcompiler/none.py create mode 100644 venv/Lib/site-packages/numpy/distutils/fcompiler/nv.py create mode 100644 venv/Lib/site-packages/numpy/distutils/fcompiler/pathf95.py create mode 100644 venv/Lib/site-packages/numpy/distutils/fcompiler/pg.py create mode 100644 venv/Lib/site-packages/numpy/distutils/fcompiler/sun.py create mode 100644 venv/Lib/site-packages/numpy/distutils/fcompiler/vast.py create mode 100644 venv/Lib/site-packages/numpy/distutils/from_template.py create mode 100644 venv/Lib/site-packages/numpy/distutils/intelccompiler.py create mode 100644 venv/Lib/site-packages/numpy/distutils/lib2def.py create mode 100644 venv/Lib/site-packages/numpy/distutils/line_endings.py create mode 100644 venv/Lib/site-packages/numpy/distutils/log.py create mode 100644 venv/Lib/site-packages/numpy/distutils/mingw/gfortran_vs2003_hack.c create mode 100644 venv/Lib/site-packages/numpy/distutils/mingw32ccompiler.py create mode 100644 venv/Lib/site-packages/numpy/distutils/misc_util.py create mode 100644 venv/Lib/site-packages/numpy/distutils/msvc9compiler.py create mode 100644 venv/Lib/site-packages/numpy/distutils/msvccompiler.py create mode 100644 venv/Lib/site-packages/numpy/distutils/npy_pkg_config.py create mode 100644 venv/Lib/site-packages/numpy/distutils/numpy_distribution.py create mode 100644 venv/Lib/site-packages/numpy/distutils/pathccompiler.py create mode 100644 venv/Lib/site-packages/numpy/distutils/setup.py create mode 100644 venv/Lib/site-packages/numpy/distutils/system_info.py create mode 100644 venv/Lib/site-packages/numpy/distutils/tests/__init__.py create mode 100644 venv/Lib/site-packages/numpy/distutils/tests/test_build_ext.py create mode 100644 venv/Lib/site-packages/numpy/distutils/tests/test_ccompiler_opt.py create mode 100644 venv/Lib/site-packages/numpy/distutils/tests/test_ccompiler_opt_conf.py create mode 100644 venv/Lib/site-packages/numpy/distutils/tests/test_exec_command.py create mode 100644 venv/Lib/site-packages/numpy/distutils/tests/test_fcompiler.py create mode 100644 venv/Lib/site-packages/numpy/distutils/tests/test_fcompiler_gnu.py create mode 100644 venv/Lib/site-packages/numpy/distutils/tests/test_fcompiler_intel.py create mode 100644 venv/Lib/site-packages/numpy/distutils/tests/test_fcompiler_nagfor.py create mode 100644 venv/Lib/site-packages/numpy/distutils/tests/test_from_template.py create mode 100644 venv/Lib/site-packages/numpy/distutils/tests/test_mingw32ccompiler.py create mode 100644 venv/Lib/site-packages/numpy/distutils/tests/test_misc_util.py create mode 100644 venv/Lib/site-packages/numpy/distutils/tests/test_npy_pkg_config.py create mode 100644 venv/Lib/site-packages/numpy/distutils/tests/test_shell_utils.py create mode 100644 venv/Lib/site-packages/numpy/distutils/tests/test_system_info.py create mode 100644 venv/Lib/site-packages/numpy/distutils/unixccompiler.py create mode 100644 venv/Lib/site-packages/numpy/doc/__init__.py create mode 100644 venv/Lib/site-packages/numpy/doc/constants.py create mode 100644 venv/Lib/site-packages/numpy/doc/ufuncs.py create mode 100644 venv/Lib/site-packages/numpy/dual.py create mode 100644 venv/Lib/site-packages/numpy/emath.pyi create mode 100644 venv/Lib/site-packages/numpy/f2py/__init__.py create mode 100644 venv/Lib/site-packages/numpy/f2py/__init__.pyi create mode 100644 venv/Lib/site-packages/numpy/f2py/__main__.py create mode 100644 venv/Lib/site-packages/numpy/f2py/__version__.py create mode 100644 venv/Lib/site-packages/numpy/f2py/auxfuncs.py create mode 100644 venv/Lib/site-packages/numpy/f2py/capi_maps.py create mode 100644 venv/Lib/site-packages/numpy/f2py/cb_rules.py create mode 100644 venv/Lib/site-packages/numpy/f2py/cfuncs.py create mode 100644 venv/Lib/site-packages/numpy/f2py/common_rules.py create mode 100644 venv/Lib/site-packages/numpy/f2py/crackfortran.py create mode 100644 venv/Lib/site-packages/numpy/f2py/diagnose.py create mode 100644 venv/Lib/site-packages/numpy/f2py/f2py2e.py create mode 100644 venv/Lib/site-packages/numpy/f2py/f2py_testing.py create mode 100644 venv/Lib/site-packages/numpy/f2py/f90mod_rules.py create mode 100644 venv/Lib/site-packages/numpy/f2py/func2subr.py create mode 100644 venv/Lib/site-packages/numpy/f2py/rules.py create mode 100644 venv/Lib/site-packages/numpy/f2py/setup.py create mode 100644 venv/Lib/site-packages/numpy/f2py/src/fortranobject.c create mode 100644 venv/Lib/site-packages/numpy/f2py/src/fortranobject.h create mode 100644 venv/Lib/site-packages/numpy/f2py/tests/__init__.py create mode 100644 venv/Lib/site-packages/numpy/f2py/tests/src/array_from_pyobj/wrapmodule.c create mode 100644 venv/Lib/site-packages/numpy/f2py/tests/src/assumed_shape/.f2py_f2cmap create mode 100644 venv/Lib/site-packages/numpy/f2py/tests/src/assumed_shape/foo_free.f90 create mode 100644 venv/Lib/site-packages/numpy/f2py/tests/src/assumed_shape/foo_mod.f90 create mode 100644 venv/Lib/site-packages/numpy/f2py/tests/src/assumed_shape/foo_use.f90 create mode 100644 venv/Lib/site-packages/numpy/f2py/tests/src/assumed_shape/precision.f90 create mode 100644 venv/Lib/site-packages/numpy/f2py/tests/src/common/block.f create mode 100644 venv/Lib/site-packages/numpy/f2py/tests/src/kind/foo.f90 create mode 100644 venv/Lib/site-packages/numpy/f2py/tests/src/mixed/foo.f create mode 100644 venv/Lib/site-packages/numpy/f2py/tests/src/mixed/foo_fixed.f90 create mode 100644 venv/Lib/site-packages/numpy/f2py/tests/src/mixed/foo_free.f90 create mode 100644 venv/Lib/site-packages/numpy/f2py/tests/src/module_data/mod.mod create mode 100644 venv/Lib/site-packages/numpy/f2py/tests/src/module_data/module_data_docstring.f90 create mode 100644 venv/Lib/site-packages/numpy/f2py/tests/src/parameter/constant_both.f90 create mode 100644 venv/Lib/site-packages/numpy/f2py/tests/src/parameter/constant_compound.f90 create mode 100644 venv/Lib/site-packages/numpy/f2py/tests/src/parameter/constant_integer.f90 create mode 100644 venv/Lib/site-packages/numpy/f2py/tests/src/parameter/constant_non_compound.f90 create mode 100644 venv/Lib/site-packages/numpy/f2py/tests/src/parameter/constant_real.f90 create mode 100644 venv/Lib/site-packages/numpy/f2py/tests/src/regression/inout.f90 create mode 100644 venv/Lib/site-packages/numpy/f2py/tests/src/size/foo.f90 create mode 100644 venv/Lib/site-packages/numpy/f2py/tests/src/string/char.f90 create mode 100644 venv/Lib/site-packages/numpy/f2py/tests/test_array_from_pyobj.py create mode 100644 venv/Lib/site-packages/numpy/f2py/tests/test_assumed_shape.py create mode 100644 venv/Lib/site-packages/numpy/f2py/tests/test_block_docstring.py create mode 100644 venv/Lib/site-packages/numpy/f2py/tests/test_callback.py create mode 100644 venv/Lib/site-packages/numpy/f2py/tests/test_common.py create mode 100644 venv/Lib/site-packages/numpy/f2py/tests/test_compile_function.py create mode 100644 venv/Lib/site-packages/numpy/f2py/tests/test_crackfortran.py create mode 100644 venv/Lib/site-packages/numpy/f2py/tests/test_kind.py create mode 100644 venv/Lib/site-packages/numpy/f2py/tests/test_mixed.py create mode 100644 venv/Lib/site-packages/numpy/f2py/tests/test_module_doc.py create mode 100644 venv/Lib/site-packages/numpy/f2py/tests/test_parameter.py create mode 100644 venv/Lib/site-packages/numpy/f2py/tests/test_quoted_character.py create mode 100644 venv/Lib/site-packages/numpy/f2py/tests/test_regression.py create mode 100644 venv/Lib/site-packages/numpy/f2py/tests/test_return_character.py create mode 100644 venv/Lib/site-packages/numpy/f2py/tests/test_return_complex.py create mode 100644 venv/Lib/site-packages/numpy/f2py/tests/test_return_integer.py create mode 100644 venv/Lib/site-packages/numpy/f2py/tests/test_return_logical.py create mode 100644 venv/Lib/site-packages/numpy/f2py/tests/test_return_real.py create mode 100644 venv/Lib/site-packages/numpy/f2py/tests/test_semicolon_split.py create mode 100644 venv/Lib/site-packages/numpy/f2py/tests/test_size.py create mode 100644 venv/Lib/site-packages/numpy/f2py/tests/test_string.py create mode 100644 venv/Lib/site-packages/numpy/f2py/tests/util.py create mode 100644 venv/Lib/site-packages/numpy/f2py/use_rules.py create mode 100644 venv/Lib/site-packages/numpy/fft/__init__.py create mode 100644 venv/Lib/site-packages/numpy/fft/__init__.pyi create mode 100644 venv/Lib/site-packages/numpy/fft/_pocketfft.py create mode 100644 venv/Lib/site-packages/numpy/fft/helper.py create mode 100644 venv/Lib/site-packages/numpy/fft/setup.py create mode 100644 venv/Lib/site-packages/numpy/fft/tests/__init__.py create mode 100644 venv/Lib/site-packages/numpy/fft/tests/test_helper.py create mode 100644 venv/Lib/site-packages/numpy/fft/tests/test_pocketfft.py create mode 100644 venv/Lib/site-packages/numpy/lib/__init__.py create mode 100644 venv/Lib/site-packages/numpy/lib/__init__.pyi create mode 100644 venv/Lib/site-packages/numpy/lib/_datasource.py create mode 100644 venv/Lib/site-packages/numpy/lib/_iotools.py create mode 100644 venv/Lib/site-packages/numpy/lib/_version.py create mode 100644 venv/Lib/site-packages/numpy/lib/arraypad.py create mode 100644 venv/Lib/site-packages/numpy/lib/arraysetops.py create mode 100644 venv/Lib/site-packages/numpy/lib/arrayterator.py create mode 100644 venv/Lib/site-packages/numpy/lib/format.py create mode 100644 venv/Lib/site-packages/numpy/lib/function_base.py create mode 100644 venv/Lib/site-packages/numpy/lib/histograms.py create mode 100644 venv/Lib/site-packages/numpy/lib/index_tricks.py create mode 100644 venv/Lib/site-packages/numpy/lib/mixins.py create mode 100644 venv/Lib/site-packages/numpy/lib/nanfunctions.py create mode 100644 venv/Lib/site-packages/numpy/lib/npyio.py create mode 100644 venv/Lib/site-packages/numpy/lib/polynomial.py create mode 100644 venv/Lib/site-packages/numpy/lib/recfunctions.py create mode 100644 venv/Lib/site-packages/numpy/lib/scimath.py create mode 100644 venv/Lib/site-packages/numpy/lib/setup.py create mode 100644 venv/Lib/site-packages/numpy/lib/shape_base.py create mode 100644 venv/Lib/site-packages/numpy/lib/stride_tricks.py create mode 100644 venv/Lib/site-packages/numpy/lib/tests/__init__.py create mode 100644 venv/Lib/site-packages/numpy/lib/tests/data/py2-objarr.npy create mode 100644 venv/Lib/site-packages/numpy/lib/tests/data/py2-objarr.npz create mode 100644 venv/Lib/site-packages/numpy/lib/tests/data/py3-objarr.npy create mode 100644 venv/Lib/site-packages/numpy/lib/tests/data/py3-objarr.npz create mode 100644 venv/Lib/site-packages/numpy/lib/tests/data/python3.npy create mode 100644 venv/Lib/site-packages/numpy/lib/tests/data/win64python2.npy create mode 100644 venv/Lib/site-packages/numpy/lib/tests/test__datasource.py create mode 100644 venv/Lib/site-packages/numpy/lib/tests/test__iotools.py create mode 100644 venv/Lib/site-packages/numpy/lib/tests/test__version.py create mode 100644 venv/Lib/site-packages/numpy/lib/tests/test_arraypad.py create mode 100644 venv/Lib/site-packages/numpy/lib/tests/test_arraysetops.py create mode 100644 venv/Lib/site-packages/numpy/lib/tests/test_arrayterator.py create mode 100644 venv/Lib/site-packages/numpy/lib/tests/test_financial_expired.py create mode 100644 venv/Lib/site-packages/numpy/lib/tests/test_format.py create mode 100644 venv/Lib/site-packages/numpy/lib/tests/test_function_base.py create mode 100644 venv/Lib/site-packages/numpy/lib/tests/test_histograms.py create mode 100644 venv/Lib/site-packages/numpy/lib/tests/test_index_tricks.py create mode 100644 venv/Lib/site-packages/numpy/lib/tests/test_io.py create mode 100644 venv/Lib/site-packages/numpy/lib/tests/test_mixins.py create mode 100644 venv/Lib/site-packages/numpy/lib/tests/test_nanfunctions.py create mode 100644 venv/Lib/site-packages/numpy/lib/tests/test_packbits.py create mode 100644 venv/Lib/site-packages/numpy/lib/tests/test_polynomial.py create mode 100644 venv/Lib/site-packages/numpy/lib/tests/test_recfunctions.py create mode 100644 venv/Lib/site-packages/numpy/lib/tests/test_regression.py create mode 100644 venv/Lib/site-packages/numpy/lib/tests/test_shape_base.py create mode 100644 venv/Lib/site-packages/numpy/lib/tests/test_stride_tricks.py create mode 100644 venv/Lib/site-packages/numpy/lib/tests/test_twodim_base.py create mode 100644 venv/Lib/site-packages/numpy/lib/tests/test_type_check.py create mode 100644 venv/Lib/site-packages/numpy/lib/tests/test_ufunclike.py create mode 100644 venv/Lib/site-packages/numpy/lib/tests/test_utils.py create mode 100644 venv/Lib/site-packages/numpy/lib/twodim_base.py create mode 100644 venv/Lib/site-packages/numpy/lib/type_check.py create mode 100644 venv/Lib/site-packages/numpy/lib/ufunclike.py create mode 100644 venv/Lib/site-packages/numpy/lib/user_array.py create mode 100644 venv/Lib/site-packages/numpy/lib/utils.py create mode 100644 venv/Lib/site-packages/numpy/linalg/__init__.py create mode 100644 venv/Lib/site-packages/numpy/linalg/__init__.pyi create mode 100644 venv/Lib/site-packages/numpy/linalg/linalg.py create mode 100644 venv/Lib/site-packages/numpy/linalg/setup.py create mode 100644 venv/Lib/site-packages/numpy/linalg/tests/__init__.py create mode 100644 venv/Lib/site-packages/numpy/linalg/tests/test_build.py create mode 100644 venv/Lib/site-packages/numpy/linalg/tests/test_deprecations.py create mode 100644 venv/Lib/site-packages/numpy/linalg/tests/test_linalg.py create mode 100644 venv/Lib/site-packages/numpy/linalg/tests/test_regression.py create mode 100644 venv/Lib/site-packages/numpy/ma/__init__.py create mode 100644 venv/Lib/site-packages/numpy/ma/__init__.pyi create mode 100644 venv/Lib/site-packages/numpy/ma/bench.py create mode 100644 venv/Lib/site-packages/numpy/ma/core.py create mode 100644 venv/Lib/site-packages/numpy/ma/extras.py create mode 100644 venv/Lib/site-packages/numpy/ma/mrecords.py create mode 100644 venv/Lib/site-packages/numpy/ma/setup.py create mode 100644 venv/Lib/site-packages/numpy/ma/tests/__init__.py create mode 100644 venv/Lib/site-packages/numpy/ma/tests/test_core.py create mode 100644 venv/Lib/site-packages/numpy/ma/tests/test_deprecations.py create mode 100644 venv/Lib/site-packages/numpy/ma/tests/test_extras.py create mode 100644 venv/Lib/site-packages/numpy/ma/tests/test_mrecords.py create mode 100644 venv/Lib/site-packages/numpy/ma/tests/test_old_ma.py create mode 100644 venv/Lib/site-packages/numpy/ma/tests/test_regression.py create mode 100644 venv/Lib/site-packages/numpy/ma/tests/test_subclassing.py create mode 100644 venv/Lib/site-packages/numpy/ma/testutils.py create mode 100644 venv/Lib/site-packages/numpy/ma/timer_comparison.py create mode 100644 venv/Lib/site-packages/numpy/matlib.py create mode 100644 venv/Lib/site-packages/numpy/matrixlib/__init__.py create mode 100644 venv/Lib/site-packages/numpy/matrixlib/__init__.pyi create mode 100644 venv/Lib/site-packages/numpy/matrixlib/defmatrix.py create mode 100644 venv/Lib/site-packages/numpy/matrixlib/setup.py create mode 100644 venv/Lib/site-packages/numpy/matrixlib/tests/__init__.py create mode 100644 venv/Lib/site-packages/numpy/matrixlib/tests/test_defmatrix.py create mode 100644 venv/Lib/site-packages/numpy/matrixlib/tests/test_interaction.py create mode 100644 venv/Lib/site-packages/numpy/matrixlib/tests/test_masked_matrix.py create mode 100644 venv/Lib/site-packages/numpy/matrixlib/tests/test_matrix_linalg.py create mode 100644 venv/Lib/site-packages/numpy/matrixlib/tests/test_multiarray.py create mode 100644 venv/Lib/site-packages/numpy/matrixlib/tests/test_numeric.py create mode 100644 venv/Lib/site-packages/numpy/matrixlib/tests/test_regression.py create mode 100644 venv/Lib/site-packages/numpy/polynomial/__init__.py create mode 100644 venv/Lib/site-packages/numpy/polynomial/__init__.pyi create mode 100644 venv/Lib/site-packages/numpy/polynomial/_polybase.py create mode 100644 venv/Lib/site-packages/numpy/polynomial/chebyshev.py create mode 100644 venv/Lib/site-packages/numpy/polynomial/hermite.py create mode 100644 venv/Lib/site-packages/numpy/polynomial/hermite_e.py create mode 100644 venv/Lib/site-packages/numpy/polynomial/laguerre.py create mode 100644 venv/Lib/site-packages/numpy/polynomial/legendre.py create mode 100644 venv/Lib/site-packages/numpy/polynomial/polynomial.py create mode 100644 venv/Lib/site-packages/numpy/polynomial/polyutils.py create mode 100644 venv/Lib/site-packages/numpy/polynomial/setup.py create mode 100644 venv/Lib/site-packages/numpy/polynomial/tests/__init__.py create mode 100644 venv/Lib/site-packages/numpy/polynomial/tests/test_chebyshev.py create mode 100644 venv/Lib/site-packages/numpy/polynomial/tests/test_classes.py create mode 100644 venv/Lib/site-packages/numpy/polynomial/tests/test_hermite.py create mode 100644 venv/Lib/site-packages/numpy/polynomial/tests/test_hermite_e.py create mode 100644 venv/Lib/site-packages/numpy/polynomial/tests/test_laguerre.py create mode 100644 venv/Lib/site-packages/numpy/polynomial/tests/test_legendre.py create mode 100644 venv/Lib/site-packages/numpy/polynomial/tests/test_polynomial.py create mode 100644 venv/Lib/site-packages/numpy/polynomial/tests/test_polyutils.py create mode 100644 venv/Lib/site-packages/numpy/polynomial/tests/test_printing.py create mode 100644 venv/Lib/site-packages/numpy/py.typed create mode 100644 venv/Lib/site-packages/numpy/random/__init__.pxd create mode 100644 venv/Lib/site-packages/numpy/random/__init__.py create mode 100644 venv/Lib/site-packages/numpy/random/__init__.pyi create mode 100644 venv/Lib/site-packages/numpy/random/_bounded_integers.pxd create mode 100644 venv/Lib/site-packages/numpy/random/_common.pxd create mode 100644 venv/Lib/site-packages/numpy/random/_examples/cffi/extending.py create mode 100644 venv/Lib/site-packages/numpy/random/_examples/cffi/parse.py create mode 100644 venv/Lib/site-packages/numpy/random/_examples/cython/extending.pyx create mode 100644 venv/Lib/site-packages/numpy/random/_examples/cython/extending_distributions.pyx create mode 100644 venv/Lib/site-packages/numpy/random/_examples/cython/setup.py create mode 100644 venv/Lib/site-packages/numpy/random/_examples/numba/extending.py create mode 100644 venv/Lib/site-packages/numpy/random/_examples/numba/extending_distributions.py create mode 100644 venv/Lib/site-packages/numpy/random/_pickle.py create mode 100644 venv/Lib/site-packages/numpy/random/bit_generator.pxd create mode 100644 venv/Lib/site-packages/numpy/random/c_distributions.pxd create mode 100644 venv/Lib/site-packages/numpy/random/lib/npyrandom.lib create mode 100644 venv/Lib/site-packages/numpy/random/setup.py create mode 100644 venv/Lib/site-packages/numpy/random/tests/__init__.py create mode 100644 venv/Lib/site-packages/numpy/random/tests/data/__init__.py create mode 100644 venv/Lib/site-packages/numpy/random/tests/data/mt19937-testset-1.csv create mode 100644 venv/Lib/site-packages/numpy/random/tests/data/mt19937-testset-2.csv create mode 100644 venv/Lib/site-packages/numpy/random/tests/data/pcg64-testset-1.csv create mode 100644 venv/Lib/site-packages/numpy/random/tests/data/pcg64-testset-2.csv create mode 100644 venv/Lib/site-packages/numpy/random/tests/data/philox-testset-1.csv create mode 100644 venv/Lib/site-packages/numpy/random/tests/data/philox-testset-2.csv create mode 100644 venv/Lib/site-packages/numpy/random/tests/data/sfc64-testset-1.csv create mode 100644 venv/Lib/site-packages/numpy/random/tests/data/sfc64-testset-2.csv create mode 100644 venv/Lib/site-packages/numpy/random/tests/test_direct.py create mode 100644 venv/Lib/site-packages/numpy/random/tests/test_extending.py create mode 100644 venv/Lib/site-packages/numpy/random/tests/test_generator_mt19937.py create mode 100644 venv/Lib/site-packages/numpy/random/tests/test_generator_mt19937_regressions.py create mode 100644 venv/Lib/site-packages/numpy/random/tests/test_random.py create mode 100644 venv/Lib/site-packages/numpy/random/tests/test_randomstate.py create mode 100644 venv/Lib/site-packages/numpy/random/tests/test_randomstate_regression.py create mode 100644 venv/Lib/site-packages/numpy/random/tests/test_regression.py create mode 100644 venv/Lib/site-packages/numpy/random/tests/test_seed_sequence.py create mode 100644 venv/Lib/site-packages/numpy/random/tests/test_smoke.py create mode 100644 venv/Lib/site-packages/numpy/rec.pyi create mode 100644 venv/Lib/site-packages/numpy/setup.py create mode 100644 venv/Lib/site-packages/numpy/testing/__init__.py create mode 100644 venv/Lib/site-packages/numpy/testing/__init__.pyi create mode 100644 venv/Lib/site-packages/numpy/testing/_private/__init__.py create mode 100644 venv/Lib/site-packages/numpy/testing/_private/decorators.py create mode 100644 venv/Lib/site-packages/numpy/testing/_private/noseclasses.py create mode 100644 venv/Lib/site-packages/numpy/testing/_private/nosetester.py create mode 100644 venv/Lib/site-packages/numpy/testing/_private/parameterized.py create mode 100644 venv/Lib/site-packages/numpy/testing/_private/utils.py create mode 100644 venv/Lib/site-packages/numpy/testing/print_coercion_tables.py create mode 100644 venv/Lib/site-packages/numpy/testing/setup.py create mode 100644 venv/Lib/site-packages/numpy/testing/tests/__init__.py create mode 100644 venv/Lib/site-packages/numpy/testing/tests/test_decorators.py create mode 100644 venv/Lib/site-packages/numpy/testing/tests/test_doctesting.py create mode 100644 venv/Lib/site-packages/numpy/testing/tests/test_utils.py create mode 100644 venv/Lib/site-packages/numpy/testing/utils.py create mode 100644 venv/Lib/site-packages/numpy/tests/__init__.py create mode 100644 venv/Lib/site-packages/numpy/tests/test_ctypeslib.py create mode 100644 venv/Lib/site-packages/numpy/tests/test_matlib.py create mode 100644 venv/Lib/site-packages/numpy/tests/test_numpy_version.py create mode 100644 venv/Lib/site-packages/numpy/tests/test_public_api.py create mode 100644 venv/Lib/site-packages/numpy/tests/test_reloading.py create mode 100644 venv/Lib/site-packages/numpy/tests/test_scripts.py create mode 100644 venv/Lib/site-packages/numpy/tests/test_warnings.py create mode 100644 venv/Lib/site-packages/numpy/typing/__init__.py create mode 100644 venv/Lib/site-packages/numpy/typing/_add_docstring.py create mode 100644 venv/Lib/site-packages/numpy/typing/_array_like.py create mode 100644 venv/Lib/site-packages/numpy/typing/_callable.py create mode 100644 venv/Lib/site-packages/numpy/typing/_dtype_like.py create mode 100644 venv/Lib/site-packages/numpy/typing/_scalars.py create mode 100644 venv/Lib/site-packages/numpy/typing/_shape.py create mode 100644 venv/Lib/site-packages/numpy/typing/setup.py create mode 100644 venv/Lib/site-packages/numpy/typing/tests/__init__.py create mode 100644 venv/Lib/site-packages/numpy/typing/tests/data/fail/arithmetic.py create mode 100644 venv/Lib/site-packages/numpy/typing/tests/data/fail/array_constructors.py create mode 100644 venv/Lib/site-packages/numpy/typing/tests/data/fail/array_like.py create mode 100644 venv/Lib/site-packages/numpy/typing/tests/data/fail/bitwise_ops.py create mode 100644 venv/Lib/site-packages/numpy/typing/tests/data/fail/constants.py create mode 100644 venv/Lib/site-packages/numpy/typing/tests/data/fail/dtype.py create mode 100644 venv/Lib/site-packages/numpy/typing/tests/data/fail/flatiter.py create mode 100644 venv/Lib/site-packages/numpy/typing/tests/data/fail/fromnumeric.py create mode 100644 venv/Lib/site-packages/numpy/typing/tests/data/fail/modules.py create mode 100644 venv/Lib/site-packages/numpy/typing/tests/data/fail/ndarray.py create mode 100644 venv/Lib/site-packages/numpy/typing/tests/data/fail/ndarray_misc.py create mode 100644 venv/Lib/site-packages/numpy/typing/tests/data/fail/numerictypes.py create mode 100644 venv/Lib/site-packages/numpy/typing/tests/data/fail/scalars.py create mode 100644 venv/Lib/site-packages/numpy/typing/tests/data/fail/ufunc_config.py create mode 100644 venv/Lib/site-packages/numpy/typing/tests/data/fail/ufuncs.py create mode 100644 venv/Lib/site-packages/numpy/typing/tests/data/fail/warnings_and_errors.py create mode 100644 venv/Lib/site-packages/numpy/typing/tests/data/mypy.ini create mode 100644 venv/Lib/site-packages/numpy/typing/tests/data/pass/arithmetic.py create mode 100644 venv/Lib/site-packages/numpy/typing/tests/data/pass/array_constructors.py create mode 100644 venv/Lib/site-packages/numpy/typing/tests/data/pass/array_like.py create mode 100644 venv/Lib/site-packages/numpy/typing/tests/data/pass/bitwise_ops.py create mode 100644 venv/Lib/site-packages/numpy/typing/tests/data/pass/dtype.py create mode 100644 venv/Lib/site-packages/numpy/typing/tests/data/pass/flatiter.py create mode 100644 venv/Lib/site-packages/numpy/typing/tests/data/pass/fromnumeric.py create mode 100644 venv/Lib/site-packages/numpy/typing/tests/data/pass/literal.py create mode 100644 venv/Lib/site-packages/numpy/typing/tests/data/pass/mod.py create mode 100644 venv/Lib/site-packages/numpy/typing/tests/data/pass/modules.py create mode 100644 venv/Lib/site-packages/numpy/typing/tests/data/pass/ndarray_conversion.py create mode 100644 venv/Lib/site-packages/numpy/typing/tests/data/pass/ndarray_misc.py create mode 100644 venv/Lib/site-packages/numpy/typing/tests/data/pass/ndarray_shape_manipulation.py create mode 100644 venv/Lib/site-packages/numpy/typing/tests/data/pass/numeric.py create mode 100644 venv/Lib/site-packages/numpy/typing/tests/data/pass/numerictypes.py create mode 100644 venv/Lib/site-packages/numpy/typing/tests/data/pass/scalars.py create mode 100644 venv/Lib/site-packages/numpy/typing/tests/data/pass/simple.py create mode 100644 venv/Lib/site-packages/numpy/typing/tests/data/pass/simple_py3.py create mode 100644 venv/Lib/site-packages/numpy/typing/tests/data/pass/ufunc_config.py create mode 100644 venv/Lib/site-packages/numpy/typing/tests/data/pass/ufuncs.py create mode 100644 venv/Lib/site-packages/numpy/typing/tests/data/pass/warnings_and_errors.py create mode 100644 venv/Lib/site-packages/numpy/typing/tests/data/reveal/arithmetic.py create mode 100644 venv/Lib/site-packages/numpy/typing/tests/data/reveal/array_constructors.py create mode 100644 venv/Lib/site-packages/numpy/typing/tests/data/reveal/bitwise_ops.py create mode 100644 venv/Lib/site-packages/numpy/typing/tests/data/reveal/constants.py create mode 100644 venv/Lib/site-packages/numpy/typing/tests/data/reveal/dtype.py create mode 100644 venv/Lib/site-packages/numpy/typing/tests/data/reveal/flatiter.py create mode 100644 venv/Lib/site-packages/numpy/typing/tests/data/reveal/fromnumeric.py create mode 100644 venv/Lib/site-packages/numpy/typing/tests/data/reveal/mod.py create mode 100644 venv/Lib/site-packages/numpy/typing/tests/data/reveal/modules.py create mode 100644 venv/Lib/site-packages/numpy/typing/tests/data/reveal/nbit_base_example.py create mode 100644 venv/Lib/site-packages/numpy/typing/tests/data/reveal/ndarray_conversion.py create mode 100644 venv/Lib/site-packages/numpy/typing/tests/data/reveal/ndarray_misc.py create mode 100644 venv/Lib/site-packages/numpy/typing/tests/data/reveal/ndarray_shape_manipulation.py create mode 100644 venv/Lib/site-packages/numpy/typing/tests/data/reveal/numeric.py create mode 100644 venv/Lib/site-packages/numpy/typing/tests/data/reveal/numerictypes.py create mode 100644 venv/Lib/site-packages/numpy/typing/tests/data/reveal/scalars.py create mode 100644 venv/Lib/site-packages/numpy/typing/tests/data/reveal/ufunc_config.py create mode 100644 venv/Lib/site-packages/numpy/typing/tests/data/reveal/warnings_and_errors.py create mode 100644 venv/Lib/site-packages/numpy/typing/tests/test_isfile.py create mode 100644 venv/Lib/site-packages/numpy/typing/tests/test_typing.py create mode 100644 venv/Lib/site-packages/numpy/version.py create mode 100644 venv/Lib/site-packages/pgzero-1.2.1.dist-info/AUTHORS create mode 100644 venv/Lib/site-packages/pgzero-1.2.1.dist-info/COPYING create mode 100644 venv/Lib/site-packages/pgzero-1.2.1.dist-info/INSTALLER create mode 100644 venv/Lib/site-packages/pgzero-1.2.1.dist-info/METADATA create mode 100644 venv/Lib/site-packages/pgzero-1.2.1.dist-info/RECORD create mode 100644 venv/Lib/site-packages/pgzero-1.2.1.dist-info/REQUESTED create mode 100644 venv/Lib/site-packages/pgzero-1.2.1.dist-info/WHEEL create mode 100644 venv/Lib/site-packages/pgzero-1.2.1.dist-info/entry_points.txt create mode 100644 venv/Lib/site-packages/pgzero-1.2.1.dist-info/top_level.txt create mode 100644 venv/Lib/site-packages/pgzero/__init__.py create mode 100644 venv/Lib/site-packages/pgzero/__main__.py create mode 100644 venv/Lib/site-packages/pgzero/actor.py create mode 100644 venv/Lib/site-packages/pgzero/animation.py create mode 100644 venv/Lib/site-packages/pgzero/builtins.py create mode 100644 venv/Lib/site-packages/pgzero/clock.py create mode 100644 venv/Lib/site-packages/pgzero/constants.py create mode 100644 venv/Lib/site-packages/pgzero/data/icon.png create mode 100644 venv/Lib/site-packages/pgzero/data/joypad.png create mode 100644 venv/Lib/site-packages/pgzero/game.py create mode 100644 venv/Lib/site-packages/pgzero/keyboard.py create mode 100644 venv/Lib/site-packages/pgzero/loaders.py create mode 100644 venv/Lib/site-packages/pgzero/music.py create mode 100644 venv/Lib/site-packages/pgzero/ptext.py create mode 100644 venv/Lib/site-packages/pgzero/rect.py create mode 100644 venv/Lib/site-packages/pgzero/runner.py create mode 100644 venv/Lib/site-packages/pgzero/screen.py create mode 100644 venv/Lib/site-packages/pgzero/soundfmt.py create mode 100644 venv/Lib/site-packages/pgzero/spellcheck.py create mode 100644 venv/Lib/site-packages/pgzero/tone.py create mode 100644 venv/Lib/site-packages/pgzrun.py create mode 100644 venv/Lib/site-packages/pip-21.0.1.dist-info/INSTALLER create mode 100644 venv/Lib/site-packages/pip-21.0.1.dist-info/LICENSE.txt create mode 100644 venv/Lib/site-packages/pip-21.0.1.dist-info/METADATA create mode 100644 venv/Lib/site-packages/pip-21.0.1.dist-info/RECORD create mode 100644 venv/Lib/site-packages/pip-21.0.1.dist-info/WHEEL create mode 100644 venv/Lib/site-packages/pip-21.0.1.dist-info/entry_points.txt create mode 100644 venv/Lib/site-packages/pip-21.0.1.dist-info/top_level.txt create mode 100644 venv/Lib/site-packages/pip/__init__.py create mode 100644 venv/Lib/site-packages/pip/__main__.py create mode 100644 venv/Lib/site-packages/pip/_internal/__init__.py create mode 100644 venv/Lib/site-packages/pip/_internal/build_env.py create mode 100644 venv/Lib/site-packages/pip/_internal/cache.py create mode 100644 venv/Lib/site-packages/pip/_internal/cli/__init__.py create mode 100644 venv/Lib/site-packages/pip/_internal/cli/autocompletion.py create mode 100644 venv/Lib/site-packages/pip/_internal/cli/base_command.py create mode 100644 venv/Lib/site-packages/pip/_internal/cli/cmdoptions.py create mode 100644 venv/Lib/site-packages/pip/_internal/cli/command_context.py create mode 100644 venv/Lib/site-packages/pip/_internal/cli/main.py create mode 100644 venv/Lib/site-packages/pip/_internal/cli/main_parser.py create mode 100644 venv/Lib/site-packages/pip/_internal/cli/parser.py create mode 100644 venv/Lib/site-packages/pip/_internal/cli/progress_bars.py create mode 100644 venv/Lib/site-packages/pip/_internal/cli/req_command.py create mode 100644 venv/Lib/site-packages/pip/_internal/cli/spinners.py create mode 100644 venv/Lib/site-packages/pip/_internal/cli/status_codes.py create mode 100644 venv/Lib/site-packages/pip/_internal/commands/__init__.py create mode 100644 venv/Lib/site-packages/pip/_internal/commands/cache.py create mode 100644 venv/Lib/site-packages/pip/_internal/commands/check.py create mode 100644 venv/Lib/site-packages/pip/_internal/commands/completion.py create mode 100644 venv/Lib/site-packages/pip/_internal/commands/configuration.py create mode 100644 venv/Lib/site-packages/pip/_internal/commands/debug.py create mode 100644 venv/Lib/site-packages/pip/_internal/commands/download.py create mode 100644 venv/Lib/site-packages/pip/_internal/commands/freeze.py create mode 100644 venv/Lib/site-packages/pip/_internal/commands/hash.py create mode 100644 venv/Lib/site-packages/pip/_internal/commands/help.py create mode 100644 venv/Lib/site-packages/pip/_internal/commands/install.py create mode 100644 venv/Lib/site-packages/pip/_internal/commands/list.py create mode 100644 venv/Lib/site-packages/pip/_internal/commands/search.py create mode 100644 venv/Lib/site-packages/pip/_internal/commands/show.py create mode 100644 venv/Lib/site-packages/pip/_internal/commands/uninstall.py create mode 100644 venv/Lib/site-packages/pip/_internal/commands/wheel.py create mode 100644 venv/Lib/site-packages/pip/_internal/configuration.py create mode 100644 venv/Lib/site-packages/pip/_internal/distributions/__init__.py create mode 100644 venv/Lib/site-packages/pip/_internal/distributions/base.py create mode 100644 venv/Lib/site-packages/pip/_internal/distributions/installed.py create mode 100644 venv/Lib/site-packages/pip/_internal/distributions/sdist.py create mode 100644 venv/Lib/site-packages/pip/_internal/distributions/wheel.py create mode 100644 venv/Lib/site-packages/pip/_internal/exceptions.py create mode 100644 venv/Lib/site-packages/pip/_internal/index/__init__.py create mode 100644 venv/Lib/site-packages/pip/_internal/index/collector.py create mode 100644 venv/Lib/site-packages/pip/_internal/index/package_finder.py create mode 100644 venv/Lib/site-packages/pip/_internal/locations.py create mode 100644 venv/Lib/site-packages/pip/_internal/main.py create mode 100644 venv/Lib/site-packages/pip/_internal/models/__init__.py create mode 100644 venv/Lib/site-packages/pip/_internal/models/candidate.py create mode 100644 venv/Lib/site-packages/pip/_internal/models/direct_url.py create mode 100644 venv/Lib/site-packages/pip/_internal/models/format_control.py create mode 100644 venv/Lib/site-packages/pip/_internal/models/index.py create mode 100644 venv/Lib/site-packages/pip/_internal/models/link.py create mode 100644 venv/Lib/site-packages/pip/_internal/models/scheme.py create mode 100644 venv/Lib/site-packages/pip/_internal/models/search_scope.py create mode 100644 venv/Lib/site-packages/pip/_internal/models/selection_prefs.py create mode 100644 venv/Lib/site-packages/pip/_internal/models/target_python.py create mode 100644 venv/Lib/site-packages/pip/_internal/models/wheel.py create mode 100644 venv/Lib/site-packages/pip/_internal/network/__init__.py create mode 100644 venv/Lib/site-packages/pip/_internal/network/auth.py create mode 100644 venv/Lib/site-packages/pip/_internal/network/cache.py create mode 100644 venv/Lib/site-packages/pip/_internal/network/download.py create mode 100644 venv/Lib/site-packages/pip/_internal/network/lazy_wheel.py create mode 100644 venv/Lib/site-packages/pip/_internal/network/session.py create mode 100644 venv/Lib/site-packages/pip/_internal/network/utils.py create mode 100644 venv/Lib/site-packages/pip/_internal/network/xmlrpc.py create mode 100644 venv/Lib/site-packages/pip/_internal/operations/__init__.py create mode 100644 venv/Lib/site-packages/pip/_internal/operations/check.py create mode 100644 venv/Lib/site-packages/pip/_internal/operations/freeze.py create mode 100644 venv/Lib/site-packages/pip/_internal/operations/install/__init__.py create mode 100644 venv/Lib/site-packages/pip/_internal/operations/install/editable_legacy.py create mode 100644 venv/Lib/site-packages/pip/_internal/operations/install/legacy.py create mode 100644 venv/Lib/site-packages/pip/_internal/operations/install/wheel.py create mode 100644 venv/Lib/site-packages/pip/_internal/operations/prepare.py create mode 100644 venv/Lib/site-packages/pip/_internal/pyproject.py create mode 100644 venv/Lib/site-packages/pip/_internal/req/__init__.py create mode 100644 venv/Lib/site-packages/pip/_internal/req/constructors.py create mode 100644 venv/Lib/site-packages/pip/_internal/req/req_file.py create mode 100644 venv/Lib/site-packages/pip/_internal/req/req_install.py create mode 100644 venv/Lib/site-packages/pip/_internal/req/req_set.py create mode 100644 venv/Lib/site-packages/pip/_internal/req/req_tracker.py create mode 100644 venv/Lib/site-packages/pip/_internal/req/req_uninstall.py create mode 100644 venv/Lib/site-packages/pip/_internal/resolution/__init__.py create mode 100644 venv/Lib/site-packages/pip/_internal/resolution/base.py create mode 100644 venv/Lib/site-packages/pip/_internal/resolution/legacy/__init__.py create mode 100644 venv/Lib/site-packages/pip/_internal/resolution/legacy/resolver.py create mode 100644 venv/Lib/site-packages/pip/_internal/resolution/resolvelib/__init__.py create mode 100644 venv/Lib/site-packages/pip/_internal/resolution/resolvelib/base.py create mode 100644 venv/Lib/site-packages/pip/_internal/resolution/resolvelib/candidates.py create mode 100644 venv/Lib/site-packages/pip/_internal/resolution/resolvelib/factory.py create mode 100644 venv/Lib/site-packages/pip/_internal/resolution/resolvelib/found_candidates.py create mode 100644 venv/Lib/site-packages/pip/_internal/resolution/resolvelib/provider.py create mode 100644 venv/Lib/site-packages/pip/_internal/resolution/resolvelib/reporter.py create mode 100644 venv/Lib/site-packages/pip/_internal/resolution/resolvelib/requirements.py create mode 100644 venv/Lib/site-packages/pip/_internal/resolution/resolvelib/resolver.py create mode 100644 venv/Lib/site-packages/pip/_internal/self_outdated_check.py create mode 100644 venv/Lib/site-packages/pip/_internal/utils/__init__.py create mode 100644 venv/Lib/site-packages/pip/_internal/utils/appdirs.py create mode 100644 venv/Lib/site-packages/pip/_internal/utils/compat.py create mode 100644 venv/Lib/site-packages/pip/_internal/utils/compatibility_tags.py create mode 100644 venv/Lib/site-packages/pip/_internal/utils/datetime.py create mode 100644 venv/Lib/site-packages/pip/_internal/utils/deprecation.py create mode 100644 venv/Lib/site-packages/pip/_internal/utils/direct_url_helpers.py create mode 100644 venv/Lib/site-packages/pip/_internal/utils/distutils_args.py create mode 100644 venv/Lib/site-packages/pip/_internal/utils/encoding.py create mode 100644 venv/Lib/site-packages/pip/_internal/utils/entrypoints.py create mode 100644 venv/Lib/site-packages/pip/_internal/utils/filesystem.py create mode 100644 venv/Lib/site-packages/pip/_internal/utils/filetypes.py create mode 100644 venv/Lib/site-packages/pip/_internal/utils/glibc.py create mode 100644 venv/Lib/site-packages/pip/_internal/utils/hashes.py create mode 100644 venv/Lib/site-packages/pip/_internal/utils/inject_securetransport.py create mode 100644 venv/Lib/site-packages/pip/_internal/utils/logging.py create mode 100644 venv/Lib/site-packages/pip/_internal/utils/misc.py create mode 100644 venv/Lib/site-packages/pip/_internal/utils/models.py create mode 100644 venv/Lib/site-packages/pip/_internal/utils/packaging.py create mode 100644 venv/Lib/site-packages/pip/_internal/utils/parallel.py create mode 100644 venv/Lib/site-packages/pip/_internal/utils/pkg_resources.py create mode 100644 venv/Lib/site-packages/pip/_internal/utils/setuptools_build.py create mode 100644 venv/Lib/site-packages/pip/_internal/utils/subprocess.py create mode 100644 venv/Lib/site-packages/pip/_internal/utils/temp_dir.py create mode 100644 venv/Lib/site-packages/pip/_internal/utils/typing.py create mode 100644 venv/Lib/site-packages/pip/_internal/utils/unpacking.py create mode 100644 venv/Lib/site-packages/pip/_internal/utils/urls.py create mode 100644 venv/Lib/site-packages/pip/_internal/utils/virtualenv.py create mode 100644 venv/Lib/site-packages/pip/_internal/utils/wheel.py create mode 100644 venv/Lib/site-packages/pip/_internal/vcs/__init__.py create mode 100644 venv/Lib/site-packages/pip/_internal/vcs/bazaar.py create mode 100644 venv/Lib/site-packages/pip/_internal/vcs/git.py create mode 100644 venv/Lib/site-packages/pip/_internal/vcs/mercurial.py create mode 100644 venv/Lib/site-packages/pip/_internal/vcs/subversion.py create mode 100644 venv/Lib/site-packages/pip/_internal/vcs/versioncontrol.py create mode 100644 venv/Lib/site-packages/pip/_internal/wheel_builder.py create mode 100644 venv/Lib/site-packages/pip/_vendor/__init__.py create mode 100644 venv/Lib/site-packages/pip/_vendor/appdirs.py create mode 100644 venv/Lib/site-packages/pip/_vendor/cachecontrol/__init__.py create mode 100644 venv/Lib/site-packages/pip/_vendor/cachecontrol/_cmd.py create mode 100644 venv/Lib/site-packages/pip/_vendor/cachecontrol/adapter.py create mode 100644 venv/Lib/site-packages/pip/_vendor/cachecontrol/cache.py create mode 100644 venv/Lib/site-packages/pip/_vendor/cachecontrol/caches/__init__.py create mode 100644 venv/Lib/site-packages/pip/_vendor/cachecontrol/caches/file_cache.py create mode 100644 venv/Lib/site-packages/pip/_vendor/cachecontrol/caches/redis_cache.py create mode 100644 venv/Lib/site-packages/pip/_vendor/cachecontrol/compat.py create mode 100644 venv/Lib/site-packages/pip/_vendor/cachecontrol/controller.py create mode 100644 venv/Lib/site-packages/pip/_vendor/cachecontrol/filewrapper.py create mode 100644 venv/Lib/site-packages/pip/_vendor/cachecontrol/heuristics.py create mode 100644 venv/Lib/site-packages/pip/_vendor/cachecontrol/serialize.py create mode 100644 venv/Lib/site-packages/pip/_vendor/cachecontrol/wrapper.py create mode 100644 venv/Lib/site-packages/pip/_vendor/certifi/__init__.py create mode 100644 venv/Lib/site-packages/pip/_vendor/certifi/__main__.py create mode 100644 venv/Lib/site-packages/pip/_vendor/certifi/cacert.pem create mode 100644 venv/Lib/site-packages/pip/_vendor/certifi/core.py create mode 100644 venv/Lib/site-packages/pip/_vendor/chardet/__init__.py create mode 100644 venv/Lib/site-packages/pip/_vendor/chardet/big5freq.py create mode 100644 venv/Lib/site-packages/pip/_vendor/chardet/big5prober.py create mode 100644 venv/Lib/site-packages/pip/_vendor/chardet/chardistribution.py create mode 100644 venv/Lib/site-packages/pip/_vendor/chardet/charsetgroupprober.py create mode 100644 venv/Lib/site-packages/pip/_vendor/chardet/charsetprober.py create mode 100644 venv/Lib/site-packages/pip/_vendor/chardet/cli/__init__.py create mode 100644 venv/Lib/site-packages/pip/_vendor/chardet/cli/chardetect.py create mode 100644 venv/Lib/site-packages/pip/_vendor/chardet/codingstatemachine.py create mode 100644 venv/Lib/site-packages/pip/_vendor/chardet/compat.py create mode 100644 venv/Lib/site-packages/pip/_vendor/chardet/cp949prober.py create mode 100644 venv/Lib/site-packages/pip/_vendor/chardet/enums.py create mode 100644 venv/Lib/site-packages/pip/_vendor/chardet/escprober.py create mode 100644 venv/Lib/site-packages/pip/_vendor/chardet/escsm.py create mode 100644 venv/Lib/site-packages/pip/_vendor/chardet/eucjpprober.py create mode 100644 venv/Lib/site-packages/pip/_vendor/chardet/euckrfreq.py create mode 100644 venv/Lib/site-packages/pip/_vendor/chardet/euckrprober.py create mode 100644 venv/Lib/site-packages/pip/_vendor/chardet/euctwfreq.py create mode 100644 venv/Lib/site-packages/pip/_vendor/chardet/euctwprober.py create mode 100644 venv/Lib/site-packages/pip/_vendor/chardet/gb2312freq.py create mode 100644 venv/Lib/site-packages/pip/_vendor/chardet/gb2312prober.py create mode 100644 venv/Lib/site-packages/pip/_vendor/chardet/hebrewprober.py create mode 100644 venv/Lib/site-packages/pip/_vendor/chardet/jisfreq.py create mode 100644 venv/Lib/site-packages/pip/_vendor/chardet/jpcntx.py create mode 100644 venv/Lib/site-packages/pip/_vendor/chardet/langbulgarianmodel.py create mode 100644 venv/Lib/site-packages/pip/_vendor/chardet/langgreekmodel.py create mode 100644 venv/Lib/site-packages/pip/_vendor/chardet/langhebrewmodel.py create mode 100644 venv/Lib/site-packages/pip/_vendor/chardet/langhungarianmodel.py create mode 100644 venv/Lib/site-packages/pip/_vendor/chardet/langrussianmodel.py create mode 100644 venv/Lib/site-packages/pip/_vendor/chardet/langthaimodel.py create mode 100644 venv/Lib/site-packages/pip/_vendor/chardet/langturkishmodel.py create mode 100644 venv/Lib/site-packages/pip/_vendor/chardet/latin1prober.py create mode 100644 venv/Lib/site-packages/pip/_vendor/chardet/mbcharsetprober.py create mode 100644 venv/Lib/site-packages/pip/_vendor/chardet/mbcsgroupprober.py create mode 100644 venv/Lib/site-packages/pip/_vendor/chardet/mbcssm.py create mode 100644 venv/Lib/site-packages/pip/_vendor/chardet/metadata/__init__.py create mode 100644 venv/Lib/site-packages/pip/_vendor/chardet/metadata/languages.py create mode 100644 venv/Lib/site-packages/pip/_vendor/chardet/sbcharsetprober.py create mode 100644 venv/Lib/site-packages/pip/_vendor/chardet/sbcsgroupprober.py create mode 100644 venv/Lib/site-packages/pip/_vendor/chardet/sjisprober.py create mode 100644 venv/Lib/site-packages/pip/_vendor/chardet/universaldetector.py create mode 100644 venv/Lib/site-packages/pip/_vendor/chardet/utf8prober.py create mode 100644 venv/Lib/site-packages/pip/_vendor/chardet/version.py create mode 100644 venv/Lib/site-packages/pip/_vendor/colorama/__init__.py create mode 100644 venv/Lib/site-packages/pip/_vendor/colorama/ansi.py create mode 100644 venv/Lib/site-packages/pip/_vendor/colorama/ansitowin32.py create mode 100644 venv/Lib/site-packages/pip/_vendor/colorama/initialise.py create mode 100644 venv/Lib/site-packages/pip/_vendor/colorama/win32.py create mode 100644 venv/Lib/site-packages/pip/_vendor/colorama/winterm.py create mode 100644 venv/Lib/site-packages/pip/_vendor/contextlib2.py create mode 100644 venv/Lib/site-packages/pip/_vendor/distlib/__init__.py create mode 100644 venv/Lib/site-packages/pip/_vendor/distlib/_backport/__init__.py create mode 100644 venv/Lib/site-packages/pip/_vendor/distlib/_backport/misc.py create mode 100644 venv/Lib/site-packages/pip/_vendor/distlib/_backport/shutil.py create mode 100644 venv/Lib/site-packages/pip/_vendor/distlib/_backport/sysconfig.cfg create mode 100644 venv/Lib/site-packages/pip/_vendor/distlib/_backport/sysconfig.py create mode 100644 venv/Lib/site-packages/pip/_vendor/distlib/_backport/tarfile.py create mode 100644 venv/Lib/site-packages/pip/_vendor/distlib/compat.py create mode 100644 venv/Lib/site-packages/pip/_vendor/distlib/database.py create mode 100644 venv/Lib/site-packages/pip/_vendor/distlib/index.py create mode 100644 venv/Lib/site-packages/pip/_vendor/distlib/locators.py create mode 100644 venv/Lib/site-packages/pip/_vendor/distlib/manifest.py create mode 100644 venv/Lib/site-packages/pip/_vendor/distlib/markers.py create mode 100644 venv/Lib/site-packages/pip/_vendor/distlib/metadata.py create mode 100644 venv/Lib/site-packages/pip/_vendor/distlib/resources.py create mode 100644 venv/Lib/site-packages/pip/_vendor/distlib/scripts.py create mode 100644 venv/Lib/site-packages/pip/_vendor/distlib/t32.exe create mode 100644 venv/Lib/site-packages/pip/_vendor/distlib/t64.exe create mode 100644 venv/Lib/site-packages/pip/_vendor/distlib/util.py create mode 100644 venv/Lib/site-packages/pip/_vendor/distlib/version.py create mode 100644 venv/Lib/site-packages/pip/_vendor/distlib/w32.exe create mode 100644 venv/Lib/site-packages/pip/_vendor/distlib/w64.exe create mode 100644 venv/Lib/site-packages/pip/_vendor/distlib/wheel.py create mode 100644 venv/Lib/site-packages/pip/_vendor/distro.py create mode 100644 venv/Lib/site-packages/pip/_vendor/html5lib/__init__.py create mode 100644 venv/Lib/site-packages/pip/_vendor/html5lib/_ihatexml.py create mode 100644 venv/Lib/site-packages/pip/_vendor/html5lib/_inputstream.py create mode 100644 venv/Lib/site-packages/pip/_vendor/html5lib/_tokenizer.py create mode 100644 venv/Lib/site-packages/pip/_vendor/html5lib/_trie/__init__.py create mode 100644 venv/Lib/site-packages/pip/_vendor/html5lib/_trie/_base.py create mode 100644 venv/Lib/site-packages/pip/_vendor/html5lib/_trie/py.py create mode 100644 venv/Lib/site-packages/pip/_vendor/html5lib/_utils.py create mode 100644 venv/Lib/site-packages/pip/_vendor/html5lib/constants.py create mode 100644 venv/Lib/site-packages/pip/_vendor/html5lib/filters/__init__.py create mode 100644 venv/Lib/site-packages/pip/_vendor/html5lib/filters/alphabeticalattributes.py create mode 100644 venv/Lib/site-packages/pip/_vendor/html5lib/filters/base.py create mode 100644 venv/Lib/site-packages/pip/_vendor/html5lib/filters/inject_meta_charset.py create mode 100644 venv/Lib/site-packages/pip/_vendor/html5lib/filters/lint.py create mode 100644 venv/Lib/site-packages/pip/_vendor/html5lib/filters/optionaltags.py create mode 100644 venv/Lib/site-packages/pip/_vendor/html5lib/filters/sanitizer.py create mode 100644 venv/Lib/site-packages/pip/_vendor/html5lib/filters/whitespace.py create mode 100644 venv/Lib/site-packages/pip/_vendor/html5lib/html5parser.py create mode 100644 venv/Lib/site-packages/pip/_vendor/html5lib/serializer.py create mode 100644 venv/Lib/site-packages/pip/_vendor/html5lib/treeadapters/__init__.py create mode 100644 venv/Lib/site-packages/pip/_vendor/html5lib/treeadapters/genshi.py create mode 100644 venv/Lib/site-packages/pip/_vendor/html5lib/treeadapters/sax.py create mode 100644 venv/Lib/site-packages/pip/_vendor/html5lib/treebuilders/__init__.py create mode 100644 venv/Lib/site-packages/pip/_vendor/html5lib/treebuilders/base.py create mode 100644 venv/Lib/site-packages/pip/_vendor/html5lib/treebuilders/dom.py create mode 100644 venv/Lib/site-packages/pip/_vendor/html5lib/treebuilders/etree.py create mode 100644 venv/Lib/site-packages/pip/_vendor/html5lib/treebuilders/etree_lxml.py create mode 100644 venv/Lib/site-packages/pip/_vendor/html5lib/treewalkers/__init__.py create mode 100644 venv/Lib/site-packages/pip/_vendor/html5lib/treewalkers/base.py create mode 100644 venv/Lib/site-packages/pip/_vendor/html5lib/treewalkers/dom.py create mode 100644 venv/Lib/site-packages/pip/_vendor/html5lib/treewalkers/etree.py create mode 100644 venv/Lib/site-packages/pip/_vendor/html5lib/treewalkers/etree_lxml.py create mode 100644 venv/Lib/site-packages/pip/_vendor/html5lib/treewalkers/genshi.py create mode 100644 venv/Lib/site-packages/pip/_vendor/idna/__init__.py create mode 100644 venv/Lib/site-packages/pip/_vendor/idna/codec.py create mode 100644 venv/Lib/site-packages/pip/_vendor/idna/compat.py create mode 100644 venv/Lib/site-packages/pip/_vendor/idna/core.py create mode 100644 venv/Lib/site-packages/pip/_vendor/idna/idnadata.py create mode 100644 venv/Lib/site-packages/pip/_vendor/idna/intranges.py create mode 100644 venv/Lib/site-packages/pip/_vendor/idna/package_data.py create mode 100644 venv/Lib/site-packages/pip/_vendor/idna/uts46data.py create mode 100644 venv/Lib/site-packages/pip/_vendor/msgpack/__init__.py create mode 100644 venv/Lib/site-packages/pip/_vendor/msgpack/_version.py create mode 100644 venv/Lib/site-packages/pip/_vendor/msgpack/exceptions.py create mode 100644 venv/Lib/site-packages/pip/_vendor/msgpack/ext.py create mode 100644 venv/Lib/site-packages/pip/_vendor/msgpack/fallback.py create mode 100644 venv/Lib/site-packages/pip/_vendor/packaging/__about__.py create mode 100644 venv/Lib/site-packages/pip/_vendor/packaging/__init__.py create mode 100644 venv/Lib/site-packages/pip/_vendor/packaging/_compat.py create mode 100644 venv/Lib/site-packages/pip/_vendor/packaging/_structures.py create mode 100644 venv/Lib/site-packages/pip/_vendor/packaging/_typing.py create mode 100644 venv/Lib/site-packages/pip/_vendor/packaging/markers.py create mode 100644 venv/Lib/site-packages/pip/_vendor/packaging/requirements.py create mode 100644 venv/Lib/site-packages/pip/_vendor/packaging/specifiers.py create mode 100644 venv/Lib/site-packages/pip/_vendor/packaging/tags.py create mode 100644 venv/Lib/site-packages/pip/_vendor/packaging/utils.py create mode 100644 venv/Lib/site-packages/pip/_vendor/packaging/version.py create mode 100644 venv/Lib/site-packages/pip/_vendor/pep517/__init__.py create mode 100644 venv/Lib/site-packages/pip/_vendor/pep517/_in_process.py create mode 100644 venv/Lib/site-packages/pip/_vendor/pep517/build.py create mode 100644 venv/Lib/site-packages/pip/_vendor/pep517/check.py create mode 100644 venv/Lib/site-packages/pip/_vendor/pep517/colorlog.py create mode 100644 venv/Lib/site-packages/pip/_vendor/pep517/compat.py create mode 100644 venv/Lib/site-packages/pip/_vendor/pep517/dirtools.py create mode 100644 venv/Lib/site-packages/pip/_vendor/pep517/envbuild.py create mode 100644 venv/Lib/site-packages/pip/_vendor/pep517/meta.py create mode 100644 venv/Lib/site-packages/pip/_vendor/pep517/wrappers.py create mode 100644 venv/Lib/site-packages/pip/_vendor/pkg_resources/__init__.py create mode 100644 venv/Lib/site-packages/pip/_vendor/pkg_resources/py31compat.py create mode 100644 venv/Lib/site-packages/pip/_vendor/progress/__init__.py create mode 100644 venv/Lib/site-packages/pip/_vendor/progress/bar.py create mode 100644 venv/Lib/site-packages/pip/_vendor/progress/counter.py create mode 100644 venv/Lib/site-packages/pip/_vendor/progress/spinner.py create mode 100644 venv/Lib/site-packages/pip/_vendor/pyparsing.py create mode 100644 venv/Lib/site-packages/pip/_vendor/requests/__init__.py create mode 100644 venv/Lib/site-packages/pip/_vendor/requests/__version__.py create mode 100644 venv/Lib/site-packages/pip/_vendor/requests/_internal_utils.py create mode 100644 venv/Lib/site-packages/pip/_vendor/requests/adapters.py create mode 100644 venv/Lib/site-packages/pip/_vendor/requests/api.py create mode 100644 venv/Lib/site-packages/pip/_vendor/requests/auth.py create mode 100644 venv/Lib/site-packages/pip/_vendor/requests/certs.py create mode 100644 venv/Lib/site-packages/pip/_vendor/requests/compat.py create mode 100644 venv/Lib/site-packages/pip/_vendor/requests/cookies.py create mode 100644 venv/Lib/site-packages/pip/_vendor/requests/exceptions.py create mode 100644 venv/Lib/site-packages/pip/_vendor/requests/help.py create mode 100644 venv/Lib/site-packages/pip/_vendor/requests/hooks.py create mode 100644 venv/Lib/site-packages/pip/_vendor/requests/models.py create mode 100644 venv/Lib/site-packages/pip/_vendor/requests/packages.py create mode 100644 venv/Lib/site-packages/pip/_vendor/requests/sessions.py create mode 100644 venv/Lib/site-packages/pip/_vendor/requests/status_codes.py create mode 100644 venv/Lib/site-packages/pip/_vendor/requests/structures.py create mode 100644 venv/Lib/site-packages/pip/_vendor/requests/utils.py create mode 100644 venv/Lib/site-packages/pip/_vendor/resolvelib/__init__.py create mode 100644 venv/Lib/site-packages/pip/_vendor/resolvelib/compat/__init__.py create mode 100644 venv/Lib/site-packages/pip/_vendor/resolvelib/compat/collections_abc.py create mode 100644 venv/Lib/site-packages/pip/_vendor/resolvelib/providers.py create mode 100644 venv/Lib/site-packages/pip/_vendor/resolvelib/reporters.py create mode 100644 venv/Lib/site-packages/pip/_vendor/resolvelib/resolvers.py create mode 100644 venv/Lib/site-packages/pip/_vendor/resolvelib/structs.py create mode 100644 venv/Lib/site-packages/pip/_vendor/retrying.py create mode 100644 venv/Lib/site-packages/pip/_vendor/six.py create mode 100644 venv/Lib/site-packages/pip/_vendor/toml/__init__.py create mode 100644 venv/Lib/site-packages/pip/_vendor/toml/decoder.py create mode 100644 venv/Lib/site-packages/pip/_vendor/toml/encoder.py create mode 100644 venv/Lib/site-packages/pip/_vendor/toml/ordered.py create mode 100644 venv/Lib/site-packages/pip/_vendor/toml/tz.py create mode 100644 venv/Lib/site-packages/pip/_vendor/urllib3/__init__.py create mode 100644 venv/Lib/site-packages/pip/_vendor/urllib3/_collections.py create mode 100644 venv/Lib/site-packages/pip/_vendor/urllib3/_version.py create mode 100644 venv/Lib/site-packages/pip/_vendor/urllib3/connection.py create mode 100644 venv/Lib/site-packages/pip/_vendor/urllib3/connectionpool.py create mode 100644 venv/Lib/site-packages/pip/_vendor/urllib3/contrib/__init__.py create mode 100644 venv/Lib/site-packages/pip/_vendor/urllib3/contrib/_appengine_environ.py create mode 100644 venv/Lib/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__init__.py create mode 100644 venv/Lib/site-packages/pip/_vendor/urllib3/contrib/_securetransport/bindings.py create mode 100644 venv/Lib/site-packages/pip/_vendor/urllib3/contrib/_securetransport/low_level.py create mode 100644 venv/Lib/site-packages/pip/_vendor/urllib3/contrib/appengine.py create mode 100644 venv/Lib/site-packages/pip/_vendor/urllib3/contrib/ntlmpool.py create mode 100644 venv/Lib/site-packages/pip/_vendor/urllib3/contrib/pyopenssl.py create mode 100644 venv/Lib/site-packages/pip/_vendor/urllib3/contrib/securetransport.py create mode 100644 venv/Lib/site-packages/pip/_vendor/urllib3/contrib/socks.py create mode 100644 venv/Lib/site-packages/pip/_vendor/urllib3/exceptions.py create mode 100644 venv/Lib/site-packages/pip/_vendor/urllib3/fields.py create mode 100644 venv/Lib/site-packages/pip/_vendor/urllib3/filepost.py create mode 100644 venv/Lib/site-packages/pip/_vendor/urllib3/packages/__init__.py create mode 100644 venv/Lib/site-packages/pip/_vendor/urllib3/packages/backports/__init__.py create mode 100644 venv/Lib/site-packages/pip/_vendor/urllib3/packages/backports/makefile.py create mode 100644 venv/Lib/site-packages/pip/_vendor/urllib3/packages/six.py create mode 100644 venv/Lib/site-packages/pip/_vendor/urllib3/packages/ssl_match_hostname/__init__.py create mode 100644 venv/Lib/site-packages/pip/_vendor/urllib3/packages/ssl_match_hostname/_implementation.py create mode 100644 venv/Lib/site-packages/pip/_vendor/urllib3/poolmanager.py create mode 100644 venv/Lib/site-packages/pip/_vendor/urllib3/request.py create mode 100644 venv/Lib/site-packages/pip/_vendor/urllib3/response.py create mode 100644 venv/Lib/site-packages/pip/_vendor/urllib3/util/__init__.py create mode 100644 venv/Lib/site-packages/pip/_vendor/urllib3/util/connection.py create mode 100644 venv/Lib/site-packages/pip/_vendor/urllib3/util/proxy.py create mode 100644 venv/Lib/site-packages/pip/_vendor/urllib3/util/queue.py create mode 100644 venv/Lib/site-packages/pip/_vendor/urllib3/util/request.py create mode 100644 venv/Lib/site-packages/pip/_vendor/urllib3/util/response.py create mode 100644 venv/Lib/site-packages/pip/_vendor/urllib3/util/retry.py create mode 100644 venv/Lib/site-packages/pip/_vendor/urllib3/util/ssl_.py create mode 100644 venv/Lib/site-packages/pip/_vendor/urllib3/util/ssltransport.py create mode 100644 venv/Lib/site-packages/pip/_vendor/urllib3/util/timeout.py create mode 100644 venv/Lib/site-packages/pip/_vendor/urllib3/util/url.py create mode 100644 venv/Lib/site-packages/pip/_vendor/urllib3/util/wait.py create mode 100644 venv/Lib/site-packages/pip/_vendor/vendor.txt create mode 100644 venv/Lib/site-packages/pip/_vendor/webencodings/__init__.py create mode 100644 venv/Lib/site-packages/pip/_vendor/webencodings/labels.py create mode 100644 venv/Lib/site-packages/pip/_vendor/webencodings/mklabels.py create mode 100644 venv/Lib/site-packages/pip/_vendor/webencodings/tests.py create mode 100644 venv/Lib/site-packages/pip/_vendor/webencodings/x_user_defined.py create mode 100644 venv/Lib/site-packages/pkg_resources/__init__.py create mode 100644 venv/Lib/site-packages/pkg_resources/_vendor/__init__.py create mode 100644 venv/Lib/site-packages/pkg_resources/_vendor/appdirs.py create mode 100644 venv/Lib/site-packages/pkg_resources/_vendor/packaging/__about__.py create mode 100644 venv/Lib/site-packages/pkg_resources/_vendor/packaging/__init__.py create mode 100644 venv/Lib/site-packages/pkg_resources/_vendor/packaging/_compat.py create mode 100644 venv/Lib/site-packages/pkg_resources/_vendor/packaging/_structures.py create mode 100644 venv/Lib/site-packages/pkg_resources/_vendor/packaging/_typing.py create mode 100644 venv/Lib/site-packages/pkg_resources/_vendor/packaging/markers.py create mode 100644 venv/Lib/site-packages/pkg_resources/_vendor/packaging/requirements.py create mode 100644 venv/Lib/site-packages/pkg_resources/_vendor/packaging/specifiers.py create mode 100644 venv/Lib/site-packages/pkg_resources/_vendor/packaging/tags.py create mode 100644 venv/Lib/site-packages/pkg_resources/_vendor/packaging/utils.py create mode 100644 venv/Lib/site-packages/pkg_resources/_vendor/packaging/version.py create mode 100644 venv/Lib/site-packages/pkg_resources/_vendor/pyparsing.py create mode 100644 venv/Lib/site-packages/pkg_resources/extern/__init__.py create mode 100644 venv/Lib/site-packages/pkg_resources/tests/data/my-test-package-source/setup.py create mode 100644 venv/Lib/site-packages/pygame-2.0.1.dist-info/INSTALLER create mode 100644 venv/Lib/site-packages/pygame-2.0.1.dist-info/METADATA create mode 100644 venv/Lib/site-packages/pygame-2.0.1.dist-info/RECORD create mode 100644 venv/Lib/site-packages/pygame-2.0.1.dist-info/REQUESTED create mode 100644 venv/Lib/site-packages/pygame-2.0.1.dist-info/WHEEL create mode 100644 venv/Lib/site-packages/pygame-2.0.1.dist-info/entry_points.txt create mode 100644 venv/Lib/site-packages/pygame-2.0.1.dist-info/top_level.txt create mode 100644 venv/Lib/site-packages/pygame/SDL2.dll create mode 100644 venv/Lib/site-packages/pygame/SDL2_image.dll create mode 100644 venv/Lib/site-packages/pygame/SDL2_mixer.dll create mode 100644 venv/Lib/site-packages/pygame/SDL2_ttf.dll create mode 100644 venv/Lib/site-packages/pygame/__init__.py create mode 100644 venv/Lib/site-packages/pygame/__init__.pyi create mode 100644 venv/Lib/site-packages/pygame/__pyinstaller/__init__.py create mode 100644 venv/Lib/site-packages/pygame/__pyinstaller/hook-pygame.py create mode 100644 venv/Lib/site-packages/pygame/_camera_opencv_highgui.py create mode 100644 venv/Lib/site-packages/pygame/_camera_vidcapture.py create mode 100644 venv/Lib/site-packages/pygame/_dummybackend.py create mode 100644 venv/Lib/site-packages/pygame/_numpysndarray.py create mode 100644 venv/Lib/site-packages/pygame/_numpysurfarray.py create mode 100644 venv/Lib/site-packages/pygame/_sdl2/__init__.py create mode 100644 venv/Lib/site-packages/pygame/_sdl2/__init__.pyi create mode 100644 venv/Lib/site-packages/pygame/_sdl2/touch.pyi create mode 100644 venv/Lib/site-packages/pygame/bufferproxy.pyi create mode 100644 venv/Lib/site-packages/pygame/camera.py create mode 100644 venv/Lib/site-packages/pygame/camera.pyi create mode 100644 venv/Lib/site-packages/pygame/color.pyi create mode 100644 venv/Lib/site-packages/pygame/colordict.py create mode 100644 venv/Lib/site-packages/pygame/compat.py create mode 100644 venv/Lib/site-packages/pygame/constants.pyi create mode 100644 venv/Lib/site-packages/pygame/cursors.py create mode 100644 venv/Lib/site-packages/pygame/cursors.pyi create mode 100644 venv/Lib/site-packages/pygame/display.pyi create mode 100644 venv/Lib/site-packages/pygame/docs/__init__.py create mode 100644 venv/Lib/site-packages/pygame/docs/__main__.py create mode 100644 venv/Lib/site-packages/pygame/docs/logos.html create mode 100644 venv/Lib/site-packages/pygame/docs/pygame_logo.gif create mode 100644 venv/Lib/site-packages/pygame/docs/pygame_powered.gif create mode 100644 venv/Lib/site-packages/pygame/docs/pygame_small.gif create mode 100644 venv/Lib/site-packages/pygame/docs/pygame_tiny.gif create mode 100644 venv/Lib/site-packages/pygame/draw.pyi create mode 100644 venv/Lib/site-packages/pygame/draw_py.py create mode 100644 venv/Lib/site-packages/pygame/event.pyi create mode 100644 venv/Lib/site-packages/pygame/examples/README.rst create mode 100644 venv/Lib/site-packages/pygame/examples/__init__.py create mode 100644 venv/Lib/site-packages/pygame/examples/aacircle.py create mode 100644 venv/Lib/site-packages/pygame/examples/aliens.py create mode 100644 venv/Lib/site-packages/pygame/examples/arraydemo.py create mode 100644 venv/Lib/site-packages/pygame/examples/audiocapture.py create mode 100644 venv/Lib/site-packages/pygame/examples/blend_fill.py create mode 100644 venv/Lib/site-packages/pygame/examples/blit_blends.py create mode 100644 venv/Lib/site-packages/pygame/examples/camera.py create mode 100644 venv/Lib/site-packages/pygame/examples/chimp.py create mode 100644 venv/Lib/site-packages/pygame/examples/cursors.py create mode 100644 venv/Lib/site-packages/pygame/examples/data/BGR.png create mode 100644 venv/Lib/site-packages/pygame/examples/data/alien1.gif create mode 100644 venv/Lib/site-packages/pygame/examples/data/alien1.jpg create mode 100644 venv/Lib/site-packages/pygame/examples/data/alien1.png create mode 100644 venv/Lib/site-packages/pygame/examples/data/alien2.gif create mode 100644 venv/Lib/site-packages/pygame/examples/data/alien2.png create mode 100644 venv/Lib/site-packages/pygame/examples/data/alien3.gif create mode 100644 venv/Lib/site-packages/pygame/examples/data/alien3.png create mode 100644 venv/Lib/site-packages/pygame/examples/data/arraydemo.bmp create mode 100644 venv/Lib/site-packages/pygame/examples/data/asprite.bmp create mode 100644 venv/Lib/site-packages/pygame/examples/data/background.gif create mode 100644 venv/Lib/site-packages/pygame/examples/data/black.ppm create mode 100644 venv/Lib/site-packages/pygame/examples/data/blue.gif create mode 100644 venv/Lib/site-packages/pygame/examples/data/blue.mpg create mode 100644 venv/Lib/site-packages/pygame/examples/data/bomb.gif create mode 100644 venv/Lib/site-packages/pygame/examples/data/boom.wav create mode 100644 venv/Lib/site-packages/pygame/examples/data/brick.png create mode 100644 venv/Lib/site-packages/pygame/examples/data/car_door.wav create mode 100644 venv/Lib/site-packages/pygame/examples/data/chimp.bmp create mode 100644 venv/Lib/site-packages/pygame/examples/data/city.png create mode 100644 venv/Lib/site-packages/pygame/examples/data/danger.gif create mode 100644 venv/Lib/site-packages/pygame/examples/data/explosion1.gif create mode 100644 venv/Lib/site-packages/pygame/examples/data/fist.bmp create mode 100644 venv/Lib/site-packages/pygame/examples/data/green.pcx create mode 100644 venv/Lib/site-packages/pygame/examples/data/grey.pgm create mode 100644 venv/Lib/site-packages/pygame/examples/data/house_lo.mp3 create mode 100644 venv/Lib/site-packages/pygame/examples/data/house_lo.ogg create mode 100644 venv/Lib/site-packages/pygame/examples/data/house_lo.wav create mode 100644 venv/Lib/site-packages/pygame/examples/data/laplacian.png create mode 100644 venv/Lib/site-packages/pygame/examples/data/liquid.bmp create mode 100644 venv/Lib/site-packages/pygame/examples/data/midikeys.png create mode 100644 venv/Lib/site-packages/pygame/examples/data/oldplayer.gif create mode 100644 venv/Lib/site-packages/pygame/examples/data/player1.gif create mode 100644 venv/Lib/site-packages/pygame/examples/data/punch.wav create mode 100644 venv/Lib/site-packages/pygame/examples/data/purple.xpm create mode 100644 venv/Lib/site-packages/pygame/examples/data/red.jpg create mode 100644 venv/Lib/site-packages/pygame/examples/data/sans.ttf create mode 100644 venv/Lib/site-packages/pygame/examples/data/secosmic_lo.wav create mode 100644 venv/Lib/site-packages/pygame/examples/data/shot.gif create mode 100644 venv/Lib/site-packages/pygame/examples/data/static.png create mode 100644 venv/Lib/site-packages/pygame/examples/data/turquoise.tif create mode 100644 venv/Lib/site-packages/pygame/examples/data/whiff.wav create mode 100644 venv/Lib/site-packages/pygame/examples/data/yellow.tga create mode 100644 venv/Lib/site-packages/pygame/examples/data/yuv_1.pgm create mode 100644 venv/Lib/site-packages/pygame/examples/dropevent.py create mode 100644 venv/Lib/site-packages/pygame/examples/eventlist.py create mode 100644 venv/Lib/site-packages/pygame/examples/fastevents.py create mode 100644 venv/Lib/site-packages/pygame/examples/font_viewer.py create mode 100644 venv/Lib/site-packages/pygame/examples/fonty.py create mode 100644 venv/Lib/site-packages/pygame/examples/freetype_misc.py create mode 100644 venv/Lib/site-packages/pygame/examples/glcube.py create mode 100644 venv/Lib/site-packages/pygame/examples/headless_no_windows_needed.py create mode 100644 venv/Lib/site-packages/pygame/examples/liquid.py create mode 100644 venv/Lib/site-packages/pygame/examples/mask.py create mode 100644 venv/Lib/site-packages/pygame/examples/midi.py create mode 100644 venv/Lib/site-packages/pygame/examples/moveit.py create mode 100644 venv/Lib/site-packages/pygame/examples/music_drop_fade.py create mode 100644 venv/Lib/site-packages/pygame/examples/overlay.py create mode 100644 venv/Lib/site-packages/pygame/examples/pixelarray.py create mode 100644 venv/Lib/site-packages/pygame/examples/playmus.py create mode 100644 venv/Lib/site-packages/pygame/examples/prevent_display_stretching.py create mode 100644 venv/Lib/site-packages/pygame/examples/resizing_new.py create mode 100644 venv/Lib/site-packages/pygame/examples/scaletest.py create mode 100644 venv/Lib/site-packages/pygame/examples/scrap_clipboard.py create mode 100644 venv/Lib/site-packages/pygame/examples/scroll.py create mode 100644 venv/Lib/site-packages/pygame/examples/setmodescale.py create mode 100644 venv/Lib/site-packages/pygame/examples/sound.py create mode 100644 venv/Lib/site-packages/pygame/examples/sound_array_demos.py create mode 100644 venv/Lib/site-packages/pygame/examples/sprite_texture.py create mode 100644 venv/Lib/site-packages/pygame/examples/stars.py create mode 100644 venv/Lib/site-packages/pygame/examples/testsprite.py create mode 100644 venv/Lib/site-packages/pygame/examples/textinput.py create mode 100644 venv/Lib/site-packages/pygame/examples/vgrade.py create mode 100644 venv/Lib/site-packages/pygame/examples/video.py create mode 100644 venv/Lib/site-packages/pygame/fastevent.pyi create mode 100644 venv/Lib/site-packages/pygame/font.pyi create mode 100644 venv/Lib/site-packages/pygame/freesansbold.ttf create mode 100644 venv/Lib/site-packages/pygame/freetype.py create mode 100644 venv/Lib/site-packages/pygame/freetype.pyi create mode 100644 venv/Lib/site-packages/pygame/ftfont.py create mode 100644 venv/Lib/site-packages/pygame/gfxdraw.pyi create mode 100644 venv/Lib/site-packages/pygame/image.pyi create mode 100644 venv/Lib/site-packages/pygame/joystick.pyi create mode 100644 venv/Lib/site-packages/pygame/key.pyi create mode 100644 venv/Lib/site-packages/pygame/libFLAC-8.dll create mode 100644 venv/Lib/site-packages/pygame/libfreetype-6.dll create mode 100644 venv/Lib/site-packages/pygame/libjpeg-9.dll create mode 100644 venv/Lib/site-packages/pygame/libmodplug-1.dll create mode 100644 venv/Lib/site-packages/pygame/libmpg123-0.dll create mode 100644 venv/Lib/site-packages/pygame/libogg-0.dll create mode 100644 venv/Lib/site-packages/pygame/libopus-0.dll create mode 100644 venv/Lib/site-packages/pygame/libopusfile-0.dll create mode 100644 venv/Lib/site-packages/pygame/libpng16-16.dll create mode 100644 venv/Lib/site-packages/pygame/libtiff-5.dll create mode 100644 venv/Lib/site-packages/pygame/libvorbis-0.dll create mode 100644 venv/Lib/site-packages/pygame/libvorbisfile-3.dll create mode 100644 venv/Lib/site-packages/pygame/libwebp-7.dll create mode 100644 venv/Lib/site-packages/pygame/locals.py create mode 100644 venv/Lib/site-packages/pygame/macosx.py create mode 100644 venv/Lib/site-packages/pygame/mask.pyi create mode 100644 venv/Lib/site-packages/pygame/math.pyi create mode 100644 venv/Lib/site-packages/pygame/midi.py create mode 100644 venv/Lib/site-packages/pygame/midi.pyi create mode 100644 venv/Lib/site-packages/pygame/mixer.pyi create mode 100644 venv/Lib/site-packages/pygame/mouse.pyi create mode 100644 venv/Lib/site-packages/pygame/music.pyi create mode 100644 venv/Lib/site-packages/pygame/pixelarray.pyi create mode 100644 venv/Lib/site-packages/pygame/pixelcopy.pyi create mode 100644 venv/Lib/site-packages/pygame/pkgdata.py create mode 100644 venv/Lib/site-packages/pygame/portmidi.dll create mode 100644 venv/Lib/site-packages/pygame/py.typed create mode 100644 venv/Lib/site-packages/pygame/pygame.ico create mode 100644 venv/Lib/site-packages/pygame/pygame_icon.bmp create mode 100644 venv/Lib/site-packages/pygame/pygame_icon.icns create mode 100644 venv/Lib/site-packages/pygame/pygame_icon.svg create mode 100644 venv/Lib/site-packages/pygame/pygame_icon.tiff create mode 100644 venv/Lib/site-packages/pygame/rect.pyi create mode 100644 venv/Lib/site-packages/pygame/scrap.pyi create mode 100644 venv/Lib/site-packages/pygame/sndarray.py create mode 100644 venv/Lib/site-packages/pygame/sndarray.pyi create mode 100644 venv/Lib/site-packages/pygame/sprite.py create mode 100644 venv/Lib/site-packages/pygame/sprite.pyi create mode 100644 venv/Lib/site-packages/pygame/surface.pyi create mode 100644 venv/Lib/site-packages/pygame/surfarray.py create mode 100644 venv/Lib/site-packages/pygame/surfarray.pyi create mode 100644 venv/Lib/site-packages/pygame/sysfont.py create mode 100644 venv/Lib/site-packages/pygame/tests/__init__.py create mode 100644 venv/Lib/site-packages/pygame/tests/__main__.py create mode 100644 venv/Lib/site-packages/pygame/tests/base_test.py create mode 100644 venv/Lib/site-packages/pygame/tests/blit_test.py create mode 100644 venv/Lib/site-packages/pygame/tests/bufferproxy_test.py create mode 100644 venv/Lib/site-packages/pygame/tests/camera_test.py create mode 100644 venv/Lib/site-packages/pygame/tests/cdrom_tags.py create mode 100644 venv/Lib/site-packages/pygame/tests/cdrom_test.py create mode 100644 venv/Lib/site-packages/pygame/tests/color_test.py create mode 100644 venv/Lib/site-packages/pygame/tests/compat_test.py create mode 100644 venv/Lib/site-packages/pygame/tests/constants_test.py create mode 100644 venv/Lib/site-packages/pygame/tests/cursors_test.py create mode 100644 venv/Lib/site-packages/pygame/tests/display_test.py create mode 100644 venv/Lib/site-packages/pygame/tests/draw_test.py create mode 100644 venv/Lib/site-packages/pygame/tests/event_test.py create mode 100644 venv/Lib/site-packages/pygame/tests/fastevent_tags.py create mode 100644 venv/Lib/site-packages/pygame/tests/fastevent_test.py create mode 100644 venv/Lib/site-packages/pygame/tests/fixtures/fonts/A_PyGameMono-8.png create mode 100644 venv/Lib/site-packages/pygame/tests/fixtures/fonts/PyGameMono-18-100dpi.bdf create mode 100644 venv/Lib/site-packages/pygame/tests/fixtures/fonts/PyGameMono-18-75dpi.bdf create mode 100644 venv/Lib/site-packages/pygame/tests/fixtures/fonts/PyGameMono-8.bdf create mode 100644 venv/Lib/site-packages/pygame/tests/fixtures/fonts/PyGameMono.otf create mode 100644 venv/Lib/site-packages/pygame/tests/fixtures/fonts/test_fixed.otf create mode 100644 venv/Lib/site-packages/pygame/tests/fixtures/fonts/test_sans.ttf create mode 100644 venv/Lib/site-packages/pygame/tests/fixtures/fonts/u13079_PyGameMono-8.png create mode 100644 venv/Lib/site-packages/pygame/tests/fixtures/xbm_cursors/white_sizing.xbm create mode 100644 venv/Lib/site-packages/pygame/tests/fixtures/xbm_cursors/white_sizing_mask.xbm create mode 100644 venv/Lib/site-packages/pygame/tests/font_tags.py create mode 100644 venv/Lib/site-packages/pygame/tests/font_test.py create mode 100644 venv/Lib/site-packages/pygame/tests/freetype_tags.py create mode 100644 venv/Lib/site-packages/pygame/tests/freetype_test.py create mode 100644 venv/Lib/site-packages/pygame/tests/ftfont_tags.py create mode 100644 venv/Lib/site-packages/pygame/tests/ftfont_test.py create mode 100644 venv/Lib/site-packages/pygame/tests/gfxdraw_test.py create mode 100644 venv/Lib/site-packages/pygame/tests/image__save_gl_surface_test.py create mode 100644 venv/Lib/site-packages/pygame/tests/image_tags.py create mode 100644 venv/Lib/site-packages/pygame/tests/image_test.py create mode 100644 venv/Lib/site-packages/pygame/tests/imageext_tags.py create mode 100644 venv/Lib/site-packages/pygame/tests/imageext_test.py create mode 100644 venv/Lib/site-packages/pygame/tests/joystick_test.py create mode 100644 venv/Lib/site-packages/pygame/tests/key_test.py create mode 100644 venv/Lib/site-packages/pygame/tests/mask_test.py create mode 100644 venv/Lib/site-packages/pygame/tests/math_test.py create mode 100644 venv/Lib/site-packages/pygame/tests/midi_test.py create mode 100644 venv/Lib/site-packages/pygame/tests/mixer_music_tags.py create mode 100644 venv/Lib/site-packages/pygame/tests/mixer_music_test.py create mode 100644 venv/Lib/site-packages/pygame/tests/mixer_tags.py create mode 100644 venv/Lib/site-packages/pygame/tests/mixer_test.py create mode 100644 venv/Lib/site-packages/pygame/tests/mouse_test.py create mode 100644 venv/Lib/site-packages/pygame/tests/overlay_tags.py create mode 100644 venv/Lib/site-packages/pygame/tests/overlay_test.py create mode 100644 venv/Lib/site-packages/pygame/tests/pixelarray_test.py create mode 100644 venv/Lib/site-packages/pygame/tests/pixelcopy_test.py create mode 100644 venv/Lib/site-packages/pygame/tests/rect_test.py create mode 100644 venv/Lib/site-packages/pygame/tests/run_tests__tests/__init__.py create mode 100644 venv/Lib/site-packages/pygame/tests/run_tests__tests/all_ok/__init__.py create mode 100644 venv/Lib/site-packages/pygame/tests/run_tests__tests/all_ok/fake_2_test.py create mode 100644 venv/Lib/site-packages/pygame/tests/run_tests__tests/all_ok/fake_3_test.py create mode 100644 venv/Lib/site-packages/pygame/tests/run_tests__tests/all_ok/fake_4_test.py create mode 100644 venv/Lib/site-packages/pygame/tests/run_tests__tests/all_ok/fake_5_test.py create mode 100644 venv/Lib/site-packages/pygame/tests/run_tests__tests/all_ok/fake_6_test.py create mode 100644 venv/Lib/site-packages/pygame/tests/run_tests__tests/all_ok/no_assertions__ret_code_of_1__test.py create mode 100644 venv/Lib/site-packages/pygame/tests/run_tests__tests/all_ok/zero_tests_test.py create mode 100644 venv/Lib/site-packages/pygame/tests/run_tests__tests/everything/__init__.py create mode 100644 venv/Lib/site-packages/pygame/tests/run_tests__tests/everything/fake_2_test.py create mode 100644 venv/Lib/site-packages/pygame/tests/run_tests__tests/everything/incomplete_todo_test.py create mode 100644 venv/Lib/site-packages/pygame/tests/run_tests__tests/everything/magic_tag_test.py create mode 100644 venv/Lib/site-packages/pygame/tests/run_tests__tests/everything/sleep_test.py create mode 100644 venv/Lib/site-packages/pygame/tests/run_tests__tests/exclude/__init__.py create mode 100644 venv/Lib/site-packages/pygame/tests/run_tests__tests/exclude/fake_2_test.py create mode 100644 venv/Lib/site-packages/pygame/tests/run_tests__tests/exclude/invisible_tag_test.py create mode 100644 venv/Lib/site-packages/pygame/tests/run_tests__tests/exclude/magic_tag_test.py create mode 100644 venv/Lib/site-packages/pygame/tests/run_tests__tests/failures1/__init__.py create mode 100644 venv/Lib/site-packages/pygame/tests/run_tests__tests/failures1/fake_2_test.py create mode 100644 venv/Lib/site-packages/pygame/tests/run_tests__tests/failures1/fake_3_test.py create mode 100644 venv/Lib/site-packages/pygame/tests/run_tests__tests/failures1/fake_4_test.py create mode 100644 venv/Lib/site-packages/pygame/tests/run_tests__tests/incomplete/__init__.py create mode 100644 venv/Lib/site-packages/pygame/tests/run_tests__tests/incomplete/fake_2_test.py create mode 100644 venv/Lib/site-packages/pygame/tests/run_tests__tests/incomplete/fake_3_test.py create mode 100644 venv/Lib/site-packages/pygame/tests/run_tests__tests/incomplete_todo/__init__.py create mode 100644 venv/Lib/site-packages/pygame/tests/run_tests__tests/incomplete_todo/fake_2_test.py create mode 100644 venv/Lib/site-packages/pygame/tests/run_tests__tests/incomplete_todo/fake_3_test.py create mode 100644 venv/Lib/site-packages/pygame/tests/run_tests__tests/infinite_loop/__init__.py create mode 100644 venv/Lib/site-packages/pygame/tests/run_tests__tests/infinite_loop/fake_1_test.py create mode 100644 venv/Lib/site-packages/pygame/tests/run_tests__tests/infinite_loop/fake_2_test.py create mode 100644 venv/Lib/site-packages/pygame/tests/run_tests__tests/print_stderr/__init__.py create mode 100644 venv/Lib/site-packages/pygame/tests/run_tests__tests/print_stderr/fake_2_test.py create mode 100644 venv/Lib/site-packages/pygame/tests/run_tests__tests/print_stderr/fake_3_test.py create mode 100644 venv/Lib/site-packages/pygame/tests/run_tests__tests/print_stderr/fake_4_test.py create mode 100644 venv/Lib/site-packages/pygame/tests/run_tests__tests/print_stdout/__init__.py create mode 100644 venv/Lib/site-packages/pygame/tests/run_tests__tests/print_stdout/fake_2_test.py create mode 100644 venv/Lib/site-packages/pygame/tests/run_tests__tests/print_stdout/fake_3_test.py create mode 100644 venv/Lib/site-packages/pygame/tests/run_tests__tests/print_stdout/fake_4_test.py create mode 100644 venv/Lib/site-packages/pygame/tests/run_tests__tests/run_tests__test.py create mode 100644 venv/Lib/site-packages/pygame/tests/run_tests__tests/timeout/__init__.py create mode 100644 venv/Lib/site-packages/pygame/tests/run_tests__tests/timeout/fake_2_test.py create mode 100644 venv/Lib/site-packages/pygame/tests/run_tests__tests/timeout/sleep_test.py create mode 100644 venv/Lib/site-packages/pygame/tests/rwobject_test.py create mode 100644 venv/Lib/site-packages/pygame/tests/scrap_tags.py create mode 100644 venv/Lib/site-packages/pygame/tests/scrap_test.py create mode 100644 venv/Lib/site-packages/pygame/tests/sndarray_tags.py create mode 100644 venv/Lib/site-packages/pygame/tests/sndarray_test.py create mode 100644 venv/Lib/site-packages/pygame/tests/sprite_test.py create mode 100644 venv/Lib/site-packages/pygame/tests/surface_test.py create mode 100644 venv/Lib/site-packages/pygame/tests/surfarray_tags.py create mode 100644 venv/Lib/site-packages/pygame/tests/surfarray_test.py create mode 100644 venv/Lib/site-packages/pygame/tests/surflock_test.py create mode 100644 venv/Lib/site-packages/pygame/tests/sysfont_test.py create mode 100644 venv/Lib/site-packages/pygame/tests/test_test_.py create mode 100644 venv/Lib/site-packages/pygame/tests/test_utils/__init__.py create mode 100644 venv/Lib/site-packages/pygame/tests/test_utils/arrinter.py create mode 100644 venv/Lib/site-packages/pygame/tests/test_utils/async_sub.py create mode 100644 venv/Lib/site-packages/pygame/tests/test_utils/buftools.py create mode 100644 venv/Lib/site-packages/pygame/tests/test_utils/endian.py create mode 100644 venv/Lib/site-packages/pygame/tests/test_utils/png.py create mode 100644 venv/Lib/site-packages/pygame/tests/test_utils/run_tests.py create mode 100644 venv/Lib/site-packages/pygame/tests/test_utils/test_machinery.py create mode 100644 venv/Lib/site-packages/pygame/tests/test_utils/test_runner.py create mode 100644 venv/Lib/site-packages/pygame/tests/threads_test.py create mode 100644 venv/Lib/site-packages/pygame/tests/time_test.py create mode 100644 venv/Lib/site-packages/pygame/tests/touch_tags.py create mode 100644 venv/Lib/site-packages/pygame/tests/touch_test.py create mode 100644 venv/Lib/site-packages/pygame/tests/transform_test.py create mode 100644 venv/Lib/site-packages/pygame/tests/version_test.py create mode 100644 venv/Lib/site-packages/pygame/tests/video_test.py create mode 100644 venv/Lib/site-packages/pygame/threads/__init__.py create mode 100644 venv/Lib/site-packages/pygame/time.pyi create mode 100644 venv/Lib/site-packages/pygame/transform.pyi create mode 100644 venv/Lib/site-packages/pygame/version.py create mode 100644 venv/Lib/site-packages/pygame/version.pyi create mode 100644 venv/Lib/site-packages/pygame/zlib1.dll create mode 100644 venv/Lib/site-packages/setuptools-56.0.0.dist-info/INSTALLER create mode 100644 venv/Lib/site-packages/setuptools-56.0.0.dist-info/LICENSE create mode 100644 venv/Lib/site-packages/setuptools-56.0.0.dist-info/METADATA create mode 100644 venv/Lib/site-packages/setuptools-56.0.0.dist-info/RECORD create mode 100644 venv/Lib/site-packages/setuptools-56.0.0.dist-info/WHEEL create mode 100644 venv/Lib/site-packages/setuptools-56.0.0.dist-info/dependency_links.txt create mode 100644 venv/Lib/site-packages/setuptools-56.0.0.dist-info/entry_points.txt create mode 100644 venv/Lib/site-packages/setuptools-56.0.0.dist-info/top_level.txt create mode 100644 venv/Lib/site-packages/setuptools/__init__.py create mode 100644 venv/Lib/site-packages/setuptools/_deprecation_warning.py create mode 100644 venv/Lib/site-packages/setuptools/_distutils/__init__.py create mode 100644 venv/Lib/site-packages/setuptools/_distutils/_msvccompiler.py create mode 100644 venv/Lib/site-packages/setuptools/_distutils/archive_util.py create mode 100644 venv/Lib/site-packages/setuptools/_distutils/bcppcompiler.py create mode 100644 venv/Lib/site-packages/setuptools/_distutils/ccompiler.py create mode 100644 venv/Lib/site-packages/setuptools/_distutils/cmd.py create mode 100644 venv/Lib/site-packages/setuptools/_distutils/command/__init__.py create mode 100644 venv/Lib/site-packages/setuptools/_distutils/command/bdist.py create mode 100644 venv/Lib/site-packages/setuptools/_distutils/command/bdist_dumb.py create mode 100644 venv/Lib/site-packages/setuptools/_distutils/command/bdist_msi.py create mode 100644 venv/Lib/site-packages/setuptools/_distutils/command/bdist_rpm.py create mode 100644 venv/Lib/site-packages/setuptools/_distutils/command/bdist_wininst.py create mode 100644 venv/Lib/site-packages/setuptools/_distutils/command/build.py create mode 100644 venv/Lib/site-packages/setuptools/_distutils/command/build_clib.py create mode 100644 venv/Lib/site-packages/setuptools/_distutils/command/build_ext.py create mode 100644 venv/Lib/site-packages/setuptools/_distutils/command/build_py.py create mode 100644 venv/Lib/site-packages/setuptools/_distutils/command/build_scripts.py create mode 100644 venv/Lib/site-packages/setuptools/_distutils/command/check.py create mode 100644 venv/Lib/site-packages/setuptools/_distutils/command/clean.py create mode 100644 venv/Lib/site-packages/setuptools/_distutils/command/config.py create mode 100644 venv/Lib/site-packages/setuptools/_distutils/command/install.py create mode 100644 venv/Lib/site-packages/setuptools/_distutils/command/install_data.py create mode 100644 venv/Lib/site-packages/setuptools/_distutils/command/install_egg_info.py create mode 100644 venv/Lib/site-packages/setuptools/_distutils/command/install_headers.py create mode 100644 venv/Lib/site-packages/setuptools/_distutils/command/install_lib.py create mode 100644 venv/Lib/site-packages/setuptools/_distutils/command/install_scripts.py create mode 100644 venv/Lib/site-packages/setuptools/_distutils/command/py37compat.py create mode 100644 venv/Lib/site-packages/setuptools/_distutils/command/register.py create mode 100644 venv/Lib/site-packages/setuptools/_distutils/command/sdist.py create mode 100644 venv/Lib/site-packages/setuptools/_distutils/command/upload.py create mode 100644 venv/Lib/site-packages/setuptools/_distutils/config.py create mode 100644 venv/Lib/site-packages/setuptools/_distutils/core.py create mode 100644 venv/Lib/site-packages/setuptools/_distutils/cygwinccompiler.py create mode 100644 venv/Lib/site-packages/setuptools/_distutils/debug.py create mode 100644 venv/Lib/site-packages/setuptools/_distutils/dep_util.py create mode 100644 venv/Lib/site-packages/setuptools/_distutils/dir_util.py create mode 100644 venv/Lib/site-packages/setuptools/_distutils/dist.py create mode 100644 venv/Lib/site-packages/setuptools/_distutils/errors.py create mode 100644 venv/Lib/site-packages/setuptools/_distutils/extension.py create mode 100644 venv/Lib/site-packages/setuptools/_distutils/fancy_getopt.py create mode 100644 venv/Lib/site-packages/setuptools/_distutils/file_util.py create mode 100644 venv/Lib/site-packages/setuptools/_distutils/filelist.py create mode 100644 venv/Lib/site-packages/setuptools/_distutils/log.py create mode 100644 venv/Lib/site-packages/setuptools/_distutils/msvc9compiler.py create mode 100644 venv/Lib/site-packages/setuptools/_distutils/msvccompiler.py create mode 100644 venv/Lib/site-packages/setuptools/_distutils/py35compat.py create mode 100644 venv/Lib/site-packages/setuptools/_distutils/py38compat.py create mode 100644 venv/Lib/site-packages/setuptools/_distutils/spawn.py create mode 100644 venv/Lib/site-packages/setuptools/_distutils/sysconfig.py create mode 100644 venv/Lib/site-packages/setuptools/_distutils/text_file.py create mode 100644 venv/Lib/site-packages/setuptools/_distutils/unixccompiler.py create mode 100644 venv/Lib/site-packages/setuptools/_distutils/util.py create mode 100644 venv/Lib/site-packages/setuptools/_distutils/version.py create mode 100644 venv/Lib/site-packages/setuptools/_distutils/versionpredicate.py create mode 100644 venv/Lib/site-packages/setuptools/_imp.py create mode 100644 venv/Lib/site-packages/setuptools/_vendor/__init__.py create mode 100644 venv/Lib/site-packages/setuptools/_vendor/ordered_set.py create mode 100644 venv/Lib/site-packages/setuptools/_vendor/packaging/__about__.py create mode 100644 venv/Lib/site-packages/setuptools/_vendor/packaging/__init__.py create mode 100644 venv/Lib/site-packages/setuptools/_vendor/packaging/_compat.py create mode 100644 venv/Lib/site-packages/setuptools/_vendor/packaging/_structures.py create mode 100644 venv/Lib/site-packages/setuptools/_vendor/packaging/_typing.py create mode 100644 venv/Lib/site-packages/setuptools/_vendor/packaging/markers.py create mode 100644 venv/Lib/site-packages/setuptools/_vendor/packaging/requirements.py create mode 100644 venv/Lib/site-packages/setuptools/_vendor/packaging/specifiers.py create mode 100644 venv/Lib/site-packages/setuptools/_vendor/packaging/tags.py create mode 100644 venv/Lib/site-packages/setuptools/_vendor/packaging/utils.py create mode 100644 venv/Lib/site-packages/setuptools/_vendor/packaging/version.py create mode 100644 venv/Lib/site-packages/setuptools/_vendor/pyparsing.py create mode 100644 venv/Lib/site-packages/setuptools/archive_util.py create mode 100644 venv/Lib/site-packages/setuptools/build_meta.py create mode 100644 venv/Lib/site-packages/setuptools/cli-32.exe create mode 100644 venv/Lib/site-packages/setuptools/cli-64.exe create mode 100644 venv/Lib/site-packages/setuptools/cli.exe create mode 100644 venv/Lib/site-packages/setuptools/command/__init__.py create mode 100644 venv/Lib/site-packages/setuptools/command/alias.py create mode 100644 venv/Lib/site-packages/setuptools/command/bdist_egg.py create mode 100644 venv/Lib/site-packages/setuptools/command/bdist_rpm.py create mode 100644 venv/Lib/site-packages/setuptools/command/build_clib.py create mode 100644 venv/Lib/site-packages/setuptools/command/build_ext.py create mode 100644 venv/Lib/site-packages/setuptools/command/build_py.py create mode 100644 venv/Lib/site-packages/setuptools/command/develop.py create mode 100644 venv/Lib/site-packages/setuptools/command/dist_info.py create mode 100644 venv/Lib/site-packages/setuptools/command/easy_install.py create mode 100644 venv/Lib/site-packages/setuptools/command/egg_info.py create mode 100644 venv/Lib/site-packages/setuptools/command/install.py create mode 100644 venv/Lib/site-packages/setuptools/command/install_egg_info.py create mode 100644 venv/Lib/site-packages/setuptools/command/install_lib.py create mode 100644 venv/Lib/site-packages/setuptools/command/install_scripts.py create mode 100644 venv/Lib/site-packages/setuptools/command/launcher manifest.xml create mode 100644 venv/Lib/site-packages/setuptools/command/py36compat.py create mode 100644 venv/Lib/site-packages/setuptools/command/register.py create mode 100644 venv/Lib/site-packages/setuptools/command/rotate.py create mode 100644 venv/Lib/site-packages/setuptools/command/saveopts.py create mode 100644 venv/Lib/site-packages/setuptools/command/sdist.py create mode 100644 venv/Lib/site-packages/setuptools/command/setopt.py create mode 100644 venv/Lib/site-packages/setuptools/command/test.py create mode 100644 venv/Lib/site-packages/setuptools/command/upload.py create mode 100644 venv/Lib/site-packages/setuptools/command/upload_docs.py create mode 100644 venv/Lib/site-packages/setuptools/config.py create mode 100644 venv/Lib/site-packages/setuptools/dep_util.py create mode 100644 venv/Lib/site-packages/setuptools/depends.py create mode 100644 venv/Lib/site-packages/setuptools/dist.py create mode 100644 venv/Lib/site-packages/setuptools/errors.py create mode 100644 venv/Lib/site-packages/setuptools/extension.py create mode 100644 venv/Lib/site-packages/setuptools/extern/__init__.py create mode 100644 venv/Lib/site-packages/setuptools/glob.py create mode 100644 venv/Lib/site-packages/setuptools/gui-32.exe create mode 100644 venv/Lib/site-packages/setuptools/gui-64.exe create mode 100644 venv/Lib/site-packages/setuptools/gui.exe create mode 100644 venv/Lib/site-packages/setuptools/installer.py create mode 100644 venv/Lib/site-packages/setuptools/launch.py create mode 100644 venv/Lib/site-packages/setuptools/lib2to3_ex.py create mode 100644 venv/Lib/site-packages/setuptools/monkey.py create mode 100644 venv/Lib/site-packages/setuptools/msvc.py create mode 100644 venv/Lib/site-packages/setuptools/namespaces.py create mode 100644 venv/Lib/site-packages/setuptools/package_index.py create mode 100644 venv/Lib/site-packages/setuptools/py34compat.py create mode 100644 venv/Lib/site-packages/setuptools/sandbox.py create mode 100644 venv/Lib/site-packages/setuptools/script (dev).tmpl create mode 100644 venv/Lib/site-packages/setuptools/script.tmpl create mode 100644 venv/Lib/site-packages/setuptools/ssl_support.py create mode 100644 venv/Lib/site-packages/setuptools/unicode_utils.py create mode 100644 venv/Lib/site-packages/setuptools/version.py create mode 100644 venv/Lib/site-packages/setuptools/wheel.py create mode 100644 venv/Lib/site-packages/setuptools/windows_support.py create mode 100644 venv/Scripts/Activate.ps1 create mode 100644 venv/Scripts/activate create mode 100644 venv/Scripts/activate.bat create mode 100644 venv/Scripts/deactivate.bat create mode 100644 venv/Scripts/f2py.exe create mode 100644 venv/Scripts/pgzrun.exe create mode 100644 venv/Scripts/pip.exe create mode 100644 venv/Scripts/pip3.9.exe create mode 100644 venv/Scripts/pip3.exe create mode 100644 venv/Scripts/python.exe create mode 100644 venv/Scripts/pythonw.exe create mode 100644 venv/pyvenv.cfg diff --git a/.gitignore b/.gitignore index c88bd9c..00f5801 100644 --- a/.gitignore +++ b/.gitignore @@ -19,7 +19,6 @@ dist/ downloads/ eggs/ .eggs/ -lib/ lib64/ parts/ sdist/ @@ -110,12 +109,9 @@ celerybeat.pid # Environments .env -.venv env/ -venv/ ENV/ env.bak/ -venv.bak/ pythonenv* # Spyder project settings diff --git a/venv/Include/site/python3.9/pygame/_camera.h b/venv/Include/site/python3.9/pygame/_camera.h new file mode 100644 index 0000000..68ae989 --- /dev/null +++ b/venv/Include/site/python3.9/pygame/_camera.h @@ -0,0 +1,27 @@ +/* + pygame - Python Game Library + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#ifndef _CAMERA_H +#define _CAMERA_H + +#include "_pygame.h" +#include "camera.h" + +#endif + diff --git a/venv/Include/site/python3.9/pygame/_pygame.h b/venv/Include/site/python3.9/pygame/_pygame.h new file mode 100644 index 0000000..95f5127 --- /dev/null +++ b/venv/Include/site/python3.9/pygame/_pygame.h @@ -0,0 +1,350 @@ +/* + pygame - Python Game Library + Copyright (C) 2000-2001 Pete Shinners + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Pete Shinners + pete@shinners.org +*/ + +/* This will use PYGAMEAPI_EXTERN_SLOTS instead + * of PYGAMEAPI_DEFINE_SLOTS for base modules. + */ +#ifndef _PYGAME_INTERNAL_H +#define _PYGAME_INTERNAL_H + +#include "pgplatform.h" +/* + If PY_SSIZE_T_CLEAN is defined before including Python.h, length is a + Py_ssize_t rather than an int for all # variants of formats (s#, y#, etc.) +*/ +#define PY_SSIZE_T_CLEAN +#include +#include + +/* IS_SDLv1 is 1 if SDL 1.x.x, 0 otherwise */ +/* IS_SDLv2 is 1 if at least SDL 2.0.0, 0 otherwise */ +#if (SDL_VERSION_ATLEAST(2, 0, 0)) +#define IS_SDLv2 1 +#define IS_SDLv1 0 +#else +#define IS_SDLv2 0 +#define IS_SDLv1 1 +#endif + +/*#if IS_SDLv1 && PG_MAJOR_VERSION >= 2 +#error pygame 2 requires SDL 2 +#endif*/ + +#if IS_SDLv2 +/* SDL 1.2 constants removed from SDL 2 */ +typedef enum { + SDL_HWSURFACE = 0, + SDL_RESIZABLE = SDL_WINDOW_RESIZABLE, + SDL_ASYNCBLIT = 0, + SDL_OPENGL = SDL_WINDOW_OPENGL, + SDL_OPENGLBLIT = 0, + SDL_ANYFORMAT = 0, + SDL_HWPALETTE = 0, + SDL_DOUBLEBUF = 0, + SDL_FULLSCREEN = SDL_WINDOW_FULLSCREEN, + SDL_HWACCEL = 0, + SDL_SRCCOLORKEY = 0, + SDL_RLEACCELOK = 0, + SDL_SRCALPHA = 0, + SDL_NOFRAME = SDL_WINDOW_BORDERLESS, + SDL_GL_SWAP_CONTROL = 0, + TIMER_RESOLUTION = 0 +} PygameVideoFlags; + +/* the wheel button constants were removed from SDL 2 */ +typedef enum { + PGM_BUTTON_LEFT = SDL_BUTTON_LEFT, + PGM_BUTTON_RIGHT = SDL_BUTTON_RIGHT, + PGM_BUTTON_MIDDLE = SDL_BUTTON_MIDDLE, + PGM_BUTTON_WHEELUP = 4, + PGM_BUTTON_WHEELDOWN = 5, + PGM_BUTTON_X1 = SDL_BUTTON_X1 + 2, + PGM_BUTTON_X2 = SDL_BUTTON_X2 + 2, + PGM_BUTTON_KEEP = 0x80 +} PygameMouseFlags; + +typedef enum { + /* Any SDL_* events here are for backward compatibility. */ + SDL_NOEVENT = 0, + + SDL_ACTIVEEVENT = SDL_USEREVENT, + SDL_VIDEORESIZE, + SDL_VIDEOEXPOSE, + + PGE_MIDIIN, + PGE_MIDIOUT, + PGE_KEYREPEAT, /* Special internal pygame event, for managing key-presses */ + + /* DO NOT CHANGE THE ORDER OF EVENTS HERE */ + PGE_WINDOWSHOWN, + PGE_WINDOWHIDDEN, + PGE_WINDOWEXPOSED, + PGE_WINDOWMOVED, + PGE_WINDOWRESIZED, + PGE_WINDOWSIZECHANGED, + PGE_WINDOWMINIMIZED, + PGE_WINDOWMAXIMIZED, + PGE_WINDOWRESTORED, + PGE_WINDOWENTER, + PGE_WINDOWLEAVE, + PGE_WINDOWFOCUSGAINED, + PGE_WINDOWFOCUSLOST, + PGE_WINDOWCLOSE, + PGE_WINDOWTAKEFOCUS, + PGE_WINDOWHITTEST, + + /* Here we define PGPOST_* events, events that act as a one-to-one + * proxy for SDL events (and some extra events too!), the proxy is used + * internally when pygame users use event.post() + * + * Thankfully, SDL2 provides over 8000 userevents, so theres no need + * to worry about wasting userevent space. + * + * IMPORTANT NOTE: Do not post events directly with these proxy types, + * use the appropriate functions in event.c, that handle these proxy + * events for you. + * Proxy events are for internal use only */ + PGPOST_EVENTBEGIN, /* mark start of proxy-events */ + PGPOST_ACTIVEEVENT = PGPOST_EVENTBEGIN, + PGPOST_AUDIODEVICEADDED, + PGPOST_AUDIODEVICEREMOVED, + PGPOST_CONTROLLERAXISMOTION, + PGPOST_CONTROLLERBUTTONDOWN, + PGPOST_CONTROLLERBUTTONUP, + PGPOST_CONTROLLERDEVICEADDED, + PGPOST_CONTROLLERDEVICEREMOVED, + PGPOST_CONTROLLERDEVICEREMAPPED, + PGPOST_DOLLARGESTURE, + PGPOST_DOLLARRECORD, + PGPOST_DROPFILE, + PGPOST_DROPTEXT, + PGPOST_DROPBEGIN, + PGPOST_DROPCOMPLETE, + PGPOST_FINGERMOTION, + PGPOST_FINGERDOWN, + PGPOST_FINGERUP, + PGPOST_KEYDOWN, + PGPOST_KEYUP, + PGPOST_JOYAXISMOTION, + PGPOST_JOYBALLMOTION, + PGPOST_JOYHATMOTION, + PGPOST_JOYBUTTONDOWN, + PGPOST_JOYBUTTONUP, + PGPOST_JOYDEVICEADDED, + PGPOST_JOYDEVICEREMOVED, + PGPOST_MIDIIN, + PGPOST_MIDIOUT, + PGPOST_MOUSEMOTION, + PGPOST_MOUSEBUTTONDOWN, + PGPOST_MOUSEBUTTONUP, + PGPOST_MOUSEWHEEL, + PGPOST_MULTIGESTURE, + PGPOST_NOEVENT, + PGPOST_QUIT, + PGPOST_SYSWMEVENT, + PGPOST_TEXTEDITING, + PGPOST_TEXTINPUT, + PGPOST_VIDEORESIZE, + PGPOST_VIDEOEXPOSE, + PGPOST_WINDOWSHOWN, + PGPOST_WINDOWHIDDEN, + PGPOST_WINDOWEXPOSED, + PGPOST_WINDOWMOVED, + PGPOST_WINDOWRESIZED, + PGPOST_WINDOWSIZECHANGED, + PGPOST_WINDOWMINIMIZED, + PGPOST_WINDOWMAXIMIZED, + PGPOST_WINDOWRESTORED, + PGPOST_WINDOWENTER, + PGPOST_WINDOWLEAVE, + PGPOST_WINDOWFOCUSGAINED, + PGPOST_WINDOWFOCUSLOST, + PGPOST_WINDOWCLOSE, + PGPOST_WINDOWTAKEFOCUS, + PGPOST_WINDOWHITTEST, + + PGE_USEREVENT, /* this event must stay in this position only */ + + PG_NUMEVENTS = SDL_LASTEVENT /* Not an event. Indicates end of user events. */ +} PygameEventCode; + +typedef enum { + SDL_APPFOCUSMOUSE, + SDL_APPINPUTFOCUS, + SDL_APPACTIVE +} PygameAppCode; + +/* Surface flags: based on SDL 1.2 flags */ +typedef enum { + PGS_SWSURFACE = 0x00000000, + PGS_HWSURFACE = 0x00000001, + PGS_ASYNCBLIT = 0x00000004, + + PGS_ANYFORMAT = 0x10000000, + PGS_HWPALETTE = 0x20000000, + PGS_DOUBLEBUF = 0x40000000, + PGS_FULLSCREEN = 0x80000000, + PGS_SCALED = 0x00000200, + + PGS_OPENGL = 0x00000002, + PGS_OPENGLBLIT = 0x0000000A, + PGS_RESIZABLE = 0x00000010, + PGS_NOFRAME = 0x00000020, + PGS_SHOWN = 0x00000040, /* Added from SDL 2 */ + PGS_HIDDEN = 0x00000080, /* Added from SDL 2 */ + + PGS_HWACCEL = 0x00000100, + PGS_SRCCOLORKEY = 0x00001000, + PGS_RLEACCELOK = 0x00002000, + PGS_RLEACCEL = 0x00004000, + PGS_SRCALPHA = 0x00010000, + PGS_PREALLOC = 0x01000000 +} PygameSurfaceFlags; + +#else /* IS_SDLv2 */ + +/* To maintain SDL 1.2 build support. */ +#define PGE_USEREVENT SDL_USEREVENT +#define PG_NUMEVENTS SDL_NUMEVENTS +#define PGPOST_EVENTBEGIN 0 +/* These midi events were originally defined in midi.py. + * Note: They are outside the SDL_USEREVENT/SDL_NUMEVENTS event range for + * SDL 1.2. */ +#define PGE_MIDIIN PGE_USEREVENT + 10 +#define PGE_MIDIOUT PGE_USEREVENT + 11 +#endif /* IS_SDLv1 */ + +//TODO Implement check below in a way that does not break CI +/* New buffer protocol (PEP 3118) implemented on all supported Py versions. +#if !defined(Py_TPFLAGS_HAVE_NEWBUFFER) +#error No support for PEP 3118/Py_TPFLAGS_HAVE_NEWBUFFER. Please use a supported Python version. +#endif */ + +#define RAISE(x, y) (PyErr_SetString((x), (y)), (PyObject *)NULL) +#define DEL_ATTR_NOT_SUPPORTED_CHECK(name, value) \ + do { \ + if (!value) { \ + if (name) { \ + PyErr_Format(PyExc_AttributeError, \ + "Cannot delete attribute %s", \ + name); \ + } else { \ + PyErr_SetString(PyExc_AttributeError, \ + "Cannot delete attribute"); \ + } \ + return -1; \ + } \ + } while (0) + +/* + * Initialization checks + */ + +#define VIDEO_INIT_CHECK() \ + if (!SDL_WasInit(SDL_INIT_VIDEO)) \ + return RAISE(pgExc_SDLError, "video system not initialized") + +#define CDROM_INIT_CHECK() \ + if (!SDL_WasInit(SDL_INIT_CDROM)) \ + return RAISE(pgExc_SDLError, "cdrom system not initialized") + +#define JOYSTICK_INIT_CHECK() \ + if (!SDL_WasInit(SDL_INIT_JOYSTICK)) \ + return RAISE(pgExc_SDLError, "joystick system not initialized") + +/* thread check */ +#ifdef WITH_THREAD +#define PG_CHECK_THREADS() (1) +#else /* ~WITH_THREAD */ +#define PG_CHECK_THREADS() \ + (RAISE(PyExc_NotImplementedError, \ + "Python built without thread support")) +#endif /* ~WITH_THREAD */ + +#define PyType_Init(x) (((x).ob_type) = &PyType_Type) + +/* + * event module internals + */ +struct pgEventObject { + PyObject_HEAD int type; + PyObject *dict; +}; + +/* + * surflock module internals + */ +typedef struct { + PyObject_HEAD PyObject *surface; + PyObject *lockobj; + PyObject *weakrefs; +} pgLifetimeLockObject; + +/* + * surface module internals + */ +struct pgSubSurface_Data { + PyObject *owner; + int pixeloffset; + int offsetx, offsety; +}; + +/* + * color module internals + */ +struct pgColorObject { + PyObject_HEAD + Uint8 data[4]; + Uint8 len; +}; + +/* + * include public API + */ +#include "include/_pygame.h" + +#include "pgimport.h" + +/* Slot counts. + * Remember to keep these constants up to date. + */ + +#define PYGAMEAPI_RECT_NUMSLOTS 5 +#define PYGAMEAPI_JOYSTICK_NUMSLOTS 2 +#define PYGAMEAPI_DISPLAY_NUMSLOTS 2 +#define PYGAMEAPI_SURFACE_NUMSLOTS 4 +#define PYGAMEAPI_SURFLOCK_NUMSLOTS 8 +#define PYGAMEAPI_RWOBJECT_NUMSLOTS 6 +#define PYGAMEAPI_PIXELARRAY_NUMSLOTS 2 +#define PYGAMEAPI_COLOR_NUMSLOTS 5 +#define PYGAMEAPI_MATH_NUMSLOTS 2 +#define PYGAMEAPI_CDROM_NUMSLOTS 2 + +#if PG_API_VERSION == 1 +#define PYGAMEAPI_BASE_NUMSLOTS 19 +#define PYGAMEAPI_EVENT_NUMSLOTS 4 +#else /* PG_API_VERSION == 2 */ +#define PYGAMEAPI_BASE_NUMSLOTS 24 +#define PYGAMEAPI_EVENT_NUMSLOTS 6 +#endif /* PG_API_VERSION == 2 */ + +#endif /* _PYGAME_INTERNAL_H */ diff --git a/venv/Include/site/python3.9/pygame/_surface.h b/venv/Include/site/python3.9/pygame/_surface.h new file mode 100644 index 0000000..016aac0 --- /dev/null +++ b/venv/Include/site/python3.9/pygame/_surface.h @@ -0,0 +1,31 @@ +/* + pygame - Python Game Library + Copyright (C) 2000-2001 Pete Shinners + Copyright (C) 2007 Marcus von Appen + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Pete Shinners + pete@shinners.org +*/ + +#ifndef _SURFACE_H +#define _SURFACE_H + +#include "_pygame.h" +#include "surface.h" + +#endif + diff --git a/venv/Include/site/python3.9/pygame/camera.h b/venv/Include/site/python3.9/pygame/camera.h new file mode 100644 index 0000000..5001061 --- /dev/null +++ b/venv/Include/site/python3.9/pygame/camera.h @@ -0,0 +1,205 @@ +#ifndef CAMERA_H +#define CAMERA_H +/* + pygame - Python Game Library + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#include "pygame.h" +#include "doc/camera_doc.h" + +#if defined(__unix__) + #include + #include + #include + #include + #include + + #include /* low-level i/o */ + #include + #include + #include + #include + #include + #include + #include + + /* on freebsd there is no asm/types */ + #ifdef linux + #include /* for videodev2.h */ + #endif + + #include +#elif defined(__APPLE__) + #include + /* We support OSX 10.6 and below. */ + #if __MAC_OS_X_VERSION_MAX_ALLOWED <= 1060 + #define PYGAME_MAC_CAMERA_OLD 1 + #endif +#endif + +#if defined(PYGAME_MAC_CAMERA_OLD) + #include + #include + #include +#endif + +/* some constants used which are not defined on non-v4l machines. */ +#ifndef V4L2_PIX_FMT_RGB24 + #define V4L2_PIX_FMT_RGB24 'RGB3' +#endif +#ifndef V4L2_PIX_FMT_RGB444 + #define V4L2_PIX_FMT_RGB444 'R444' +#endif +#ifndef V4L2_PIX_FMT_YUYV + #define V4L2_PIX_FMT_YUYV 'YUYV' +#endif + +#define CLEAR(x) memset (&(x), 0, sizeof (x)) +#define SAT(c) if (c & (~255)) { if (c < 0) c = 0; else c = 255; } +#define SAT2(c) ((c) & (~255) ? ((c) < 0 ? 0 : 255) : (c)) +#define DEFAULT_WIDTH 640 +#define DEFAULT_HEIGHT 480 +#define RGB_OUT 1 +#define YUV_OUT 2 +#define HSV_OUT 4 +#define CAM_V4L 1 /* deprecated. the incomplete support in pygame was removed */ +#define CAM_V4L2 2 + +struct buffer { + void * start; + size_t length; +}; + +#if defined(__unix__) +typedef struct pgCameraObject { + PyObject_HEAD + char* device_name; + int camera_type; + unsigned long pixelformat; + unsigned int color_out; + struct buffer* buffers; + unsigned int n_buffers; + int width; + int height; + int size; + int hflip; + int vflip; + int brightness; + int fd; +} pgCameraObject; +#elif defined(PYGAME_MAC_CAMERA_OLD) +typedef struct pgCameraObject { + PyObject_HEAD + char* device_name; /* unique name of the device */ + OSType pixelformat; + unsigned int color_out; + SeqGrabComponent component; /* A type used by the Sequence Grabber API */ + SGChannel channel; /* Channel of the Sequence Grabber */ + GWorldPtr gworld; /* Pointer to the struct that holds the data of the captured image */ + Rect boundsRect; /* bounds of the image frame */ + long size; /* size of the image in our buffer to draw */ + int hflip; + int vflip; + short depth; + struct buffer pixels; + //struct buffer tmp_pixels /* place where the flipped image in temporarily stored if hflip or vflip is true.*/ +} pgCameraObject; + +#else +/* generic definition. +*/ + +typedef struct pgCameraObject { + PyObject_HEAD + char* device_name; + int camera_type; + unsigned long pixelformat; + unsigned int color_out; + struct buffer* buffers; + unsigned int n_buffers; + int width; + int height; + int size; + int hflip; + int vflip; + int brightness; + int fd; +} pgCameraObject; +#endif + +/* internal functions for colorspace conversion */ +void colorspace (SDL_Surface *src, SDL_Surface *dst, int cspace); +void rgb24_to_rgb (const void* src, void* dst, int length, SDL_PixelFormat* format); +void rgb444_to_rgb (const void* src, void* dst, int length, SDL_PixelFormat* format); +void rgb_to_yuv (const void* src, void* dst, int length, + unsigned long source, SDL_PixelFormat* format); +void rgb_to_hsv (const void* src, void* dst, int length, + unsigned long source, SDL_PixelFormat* format); +void yuyv_to_rgb (const void* src, void* dst, int length, SDL_PixelFormat* format); +void yuyv_to_yuv (const void* src, void* dst, int length, SDL_PixelFormat* format); +void uyvy_to_rgb (const void* src, void* dst, int length, SDL_PixelFormat* format); +void uyvy_to_yuv (const void* src, void* dst, int length, SDL_PixelFormat* format); +void sbggr8_to_rgb (const void* src, void* dst, int width, int height, + SDL_PixelFormat* format); +void yuv420_to_rgb (const void* src, void* dst, int width, int height, + SDL_PixelFormat* format); +void yuv420_to_yuv (const void* src, void* dst, int width, int height, + SDL_PixelFormat* format); + +#if defined(__unix__) +/* internal functions specific to v4l2 */ +char** v4l2_list_cameras (int* num_devices); +int v4l2_get_control (int fd, int id, int *value); +int v4l2_set_control (int fd, int id, int value); +PyObject* v4l2_read_raw (pgCameraObject* self); +int v4l2_xioctl (int fd, int request, void *arg); +int v4l2_process_image (pgCameraObject* self, const void *image, + unsigned int buffer_size, SDL_Surface* surf); +int v4l2_query_buffer (pgCameraObject* self); +int v4l2_read_frame (pgCameraObject* self, SDL_Surface* surf); +int v4l2_stop_capturing (pgCameraObject* self); +int v4l2_start_capturing (pgCameraObject* self); +int v4l2_uninit_device (pgCameraObject* self); +int v4l2_init_mmap (pgCameraObject* self); +int v4l2_init_device (pgCameraObject* self); +int v4l2_close_device (pgCameraObject* self); +int v4l2_open_device (pgCameraObject* self); + +#elif defined(PYGAME_MAC_CAMERA_OLD) +/* internal functions specific to mac */ +char** mac_list_cameras(int* num_devices); +int mac_open_device (pgCameraObject* self); +int mac_init_device(pgCameraObject* self); +int mac_close_device (pgCameraObject* self); +int mac_start_capturing(pgCameraObject* self); +int mac_stop_capturing (pgCameraObject* self); + +int mac_get_control(pgCameraObject* self, int id, int* value); +int mac_set_control(pgCameraObject* self, int id, int value); + +PyObject* mac_read_raw(pgCameraObject *self); +int mac_read_frame(pgCameraObject* self, SDL_Surface* surf); +int mac_camera_idle(pgCameraObject* self); +int mac_copy_gworld_to_surface(pgCameraObject* self, SDL_Surface* surf); + +void flip_image(const void* image, void* flipped_image, int width, int height, + short depth, int hflip, int vflip); + +#endif + +#endif /* !CAMERA_H */ diff --git a/venv/Include/site/python3.9/pygame/fastevents.h b/venv/Include/site/python3.9/pygame/fastevents.h new file mode 100644 index 0000000..04098c3 --- /dev/null +++ b/venv/Include/site/python3.9/pygame/fastevents.h @@ -0,0 +1,48 @@ +#ifndef _FASTEVENTS_H_ +#define _FASTEVENTS_H_ +/* + NET2 is a threaded, event based, network IO library for SDL. + Copyright (C) 2002 Bob Pendleton + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public License + as published by the Free Software Foundation; either version 2.1 + of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA + + If you do not wish to comply with the terms of the LGPL please + contact the author as other terms are available for a fee. + + Bob Pendleton + Bob@Pendleton.com +*/ + +#include "SDL.h" + +#ifdef __cplusplus +extern "C" { +#endif + + int FE_Init(void); // Initialize FE + void FE_Quit(void); // shutdown FE + + void FE_PumpEvents(void); // replacement for SDL_PumpEvents + int FE_PollEvent(SDL_Event *event); // replacement for SDL_PollEvent + int FE_WaitEvent(SDL_Event *event); // replacement for SDL_WaitEvent + int FE_PushEvent(SDL_Event *event); // replacement for SDL_PushEvent + + char *FE_GetError(void); // get the last error +#ifdef __cplusplus +} +#endif + +#endif diff --git a/venv/Include/site/python3.9/pygame/font.h b/venv/Include/site/python3.9/pygame/font.h new file mode 100644 index 0000000..9878435 --- /dev/null +++ b/venv/Include/site/python3.9/pygame/font.h @@ -0,0 +1,15 @@ +#ifndef PGFONT_INTERNAL_H +#define PGFONT_INTERNAL_H + +#include + +/* test font initialization */ +#define FONT_INIT_CHECK() \ + if(!(*(int*)PyFONT_C_API[2])) \ + return RAISE(pgExc_SDLError, "font system not initialized") + +#include "include/pygame_font.h" + +#define PYGAMEAPI_FONT_NUMSLOTS 3 + +#endif /* ~PGFONT_INTERNAL_H */ diff --git a/venv/Include/site/python3.9/pygame/freetype.h b/venv/Include/site/python3.9/pygame/freetype.h new file mode 100644 index 0000000..2f75319 --- /dev/null +++ b/venv/Include/site/python3.9/pygame/freetype.h @@ -0,0 +1,123 @@ +/* + pygame - Python Game Library + Copyright (C) 2009 Vicent Marti + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ +#ifndef _PYGAME_FREETYPE_INTERNAL_H_ +#define _PYGAME_FREETYPE_INTERNAL_H_ + +#define PGFT_PYGAME1_COMPAT +#define HAVE_PYGAME_SDL_VIDEO +#define HAVE_PYGAME_SDL_RWOPS + +#include "pgcompat.h" +#include "pgplatform.h" +#include + +#include +#include FT_FREETYPE_H +#include FT_CACHE_H +#include FT_XFREE86_H +#include FT_TRIGONOMETRY_H + +/********************************************************** + * Global module constants + **********************************************************/ + +/* Render styles */ +#define FT_STYLE_NORMAL 0x00 +#define FT_STYLE_STRONG 0x01 +#define FT_STYLE_OBLIQUE 0x02 +#define FT_STYLE_UNDERLINE 0x04 +#define FT_STYLE_WIDE 0x08 +#define FT_STYLE_DEFAULT 0xFF + +/* Bounding box modes */ +#define FT_BBOX_EXACT FT_GLYPH_BBOX_SUBPIXELS +#define FT_BBOX_EXACT_GRIDFIT FT_GLYPH_BBOX_GRIDFIT +#define FT_BBOX_PIXEL FT_GLYPH_BBOX_TRUNCATE +#define FT_BBOX_PIXEL_GRIDFIT FT_GLYPH_BBOX_PIXELS + +/* Rendering flags */ +#define FT_RFLAG_NONE (0) +#define FT_RFLAG_ANTIALIAS (1 << 0) +#define FT_RFLAG_AUTOHINT (1 << 1) +#define FT_RFLAG_VERTICAL (1 << 2) +#define FT_RFLAG_HINTED (1 << 3) +#define FT_RFLAG_KERNING (1 << 4) +#define FT_RFLAG_TRANSFORM (1 << 5) +#define FT_RFLAG_PAD (1 << 6) +#define FT_RFLAG_ORIGIN (1 << 7) +#define FT_RFLAG_UCS4 (1 << 8) +#define FT_RFLAG_USE_BITMAP_STRIKES (1 << 9) +#define FT_RFLAG_DEFAULTS (FT_RFLAG_HINTED | \ + FT_RFLAG_USE_BITMAP_STRIKES | \ + FT_RFLAG_ANTIALIAS) + + +#define FT_RENDER_NEWBYTEARRAY 0x0 +#define FT_RENDER_NEWSURFACE 0x1 +#define FT_RENDER_EXISTINGSURFACE 0x2 + +/********************************************************** + * Global module types + **********************************************************/ + +typedef struct _scale_s { + FT_UInt x, y; +} Scale_t; +typedef FT_Angle Angle_t; + +struct fontinternals_; +struct freetypeinstance_; + +typedef struct { + FT_Long font_index; + FT_Open_Args open_args; +} pgFontId; + +typedef struct { + PyObject_HEAD + pgFontId id; + PyObject *path; + int is_scalable; + int is_bg_col_set; + + Scale_t face_size; + FT_Int16 style; + FT_Int16 render_flags; + double strength; + double underline_adjustment; + FT_UInt resolution; + Angle_t rotation; + FT_Matrix transform; + FT_Byte fgcolor[4]; + FT_Byte bgcolor[4]; + + struct freetypeinstance_ *freetype; /* Personal reference */ + struct fontinternals_ *_internals; +} pgFontObject; + +#define pgFont_IS_ALIVE(o) \ + (((pgFontObject *)(o))->_internals != 0) + +/* import public API */ +#include "include/pygame_freetype.h" + +#define PYGAMEAPI_FREETYPE_NUMSLOTS 2 + +#endif /* ~_PYGAME_FREETYPE_INTERNAL_H_ */ diff --git a/venv/Include/site/python3.9/pygame/include/_pygame.h b/venv/Include/site/python3.9/pygame/include/_pygame.h new file mode 100644 index 0000000..cb7f5a2 --- /dev/null +++ b/venv/Include/site/python3.9/pygame/include/_pygame.h @@ -0,0 +1,649 @@ +/* + pygame - Python Game Library + Copyright (C) 2000-2001 Pete Shinners + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Pete Shinners + pete@shinners.org +*/ + +#ifndef _PYGAME_H +#define _PYGAME_H + +/** This header file includes all the definitions for the + ** base pygame extensions. This header only requires + ** Python includes (and SDL.h for functions that use SDL types). + ** The reason for functions prototyped with #define's is + ** to allow for maximum Python portability. It also uses + ** Python as the runtime linker, which allows for late binding. + '' For more information on this style of development, read + ** the Python docs on this subject. + ** http://www.python.org/doc/current/ext/using-cobjects.html + ** + ** If using this to build your own derived extensions, + ** you'll see that the functions available here are mainly + ** used to help convert between python objects and SDL objects. + ** Since this library doesn't add a lot of functionality to + ** the SDL library, it doesn't need to offer a lot either. + ** + ** When initializing your extension module, you must manually + ** import the modules you want to use. (this is the part about + ** using python as the runtime linker). Each module has its + ** own import_xxx() routine. You need to perform this import + ** after you have initialized your own module, and before + ** you call any routines from that module. Since every module + ** in pygame does this, there are plenty of examples. + ** + ** The base module does include some useful conversion routines + ** that you are free to use in your own extension. + **/ + +#include "pgplatform.h" +#include + + +/* version macros (defined since version 1.9.5) */ +#define PG_MAJOR_VERSION 2 +#define PG_MINOR_VERSION 0 +#define PG_PATCH_VERSION 1 +#define PG_VERSIONNUM(MAJOR, MINOR, PATCH) (1000*(MAJOR) + 100*(MINOR) + (PATCH)) +#define PG_VERSION_ATLEAST(MAJOR, MINOR, PATCH) \ + (PG_VERSIONNUM(PG_MAJOR_VERSION, PG_MINOR_VERSION, PG_PATCH_VERSION) >= \ + PG_VERSIONNUM(MAJOR, MINOR, PATCH)) + +/* SDL 1.x/2.x and pygame 1.x/2.x + */ +#if defined(SDL_VERSION_ATLEAST) +#if (SDL_VERSION_ATLEAST(2, 0, 0)) +#define PG_API_VERSION 2 +#else /* SDL 1 */ +/* for now: allow pygame 2 to be compiled with SDL 1. */ +#define PG_API_VERSION 1 +#endif /* SDL 1 */ +#else /* NO SDL */ +#define PG_API_VERSION ((PG_MAJOR_VERSION == 1) ? 1 : 2) +#endif /* NO SDL */ + +#include "pgcompat.h" + + +/* Flag indicating a pg_buffer; used for assertions within callbacks */ +#ifndef NDEBUG +#define PyBUF_PYGAME 0x4000 +#endif +#define PyBUF_HAS_FLAG(f, F) (((f) & (F)) == (F)) + +/* Array information exchange struct C type; inherits from Py_buffer + * + * Pygame uses its own Py_buffer derived C struct as an internal representation + * of an imported array buffer. The extended Py_buffer allows for a + * per-instance release callback, + */ +typedef void (*pybuffer_releaseproc)(Py_buffer *); + +typedef struct pg_bufferinfo_s { + Py_buffer view; + PyObject *consumer; /* Input: Borrowed reference */ + pybuffer_releaseproc release_buffer; +} pg_buffer; + +#include "pgimport.h" + +/* + * BASE module + */ +#ifndef PYGAMEAPI_BASE_INTERNAL +#define pgExc_SDLError \ + ((PyObject *) \ + PYGAMEAPI_GET_SLOT(base, 0)) + +#define pg_RegisterQuit \ + (*(void (*)(void (*)(void))) \ + PYGAMEAPI_GET_SLOT(base, 1)) + +#define pg_IntFromObj \ + (*(int (*)(PyObject *, int *)) \ + PYGAMEAPI_GET_SLOT(base, 2)) + +#define pg_IntFromObjIndex \ + (*(int (*)(PyObject *, int, int *)) \ + PYGAMEAPI_GET_SLOT(base, 3)) + +#define pg_TwoIntsFromObj \ + (*(int (*)(PyObject *, int *, int *)) \ + PYGAMEAPI_GET_SLOT(base, 4)) + +#define pg_FloatFromObj \ + (*(int (*)(PyObject *, float *)) \ + PYGAMEAPI_GET_SLOT(base, 5)) + +#define pg_FloatFromObjIndex \ + (*(int (*)(PyObject *, int, float *)) \ + PYGAMEAPI_GET_SLOT(base, 6)) + +#define pg_TwoFloatsFromObj \ + (*(int (*)(PyObject *, float *, float *)) \ + PYGAMEAPI_GET_SLOT(base, 7)) + +#define pg_UintFromObj \ + (*(int (*)(PyObject *, Uint32 *)) \ + PYGAMEAPI_GET_SLOT(base, 8)) + +#define pg_UintFromObjIndex \ + (*(int (*)(PyObject *, int, Uint32 *)) \ + PYGAMEAPI_GET_SLOT(base, 9)) + +#define pgVideo_AutoQuit \ + (*(void (*)(void)) \ + PYGAMEAPI_GET_SLOT(base, 10)) + +#define pgVideo_AutoInit \ + (*(int (*)(void)) \ + PYGAMEAPI_GET_SLOT(base, 11)) + +#define pg_RGBAFromObj \ + (*(int (*)(PyObject *, Uint8 *)) \ + PYGAMEAPI_GET_SLOT(base, 12)) + +#define pgBuffer_AsArrayInterface \ + (*(PyObject * (*)(Py_buffer *)) \ + PYGAMEAPI_GET_SLOT(base, 13)) + +#define pgBuffer_AsArrayStruct \ + (*(PyObject * (*)(Py_buffer *)) \ + PYGAMEAPI_GET_SLOT(base, 14)) + +#define pgObject_GetBuffer \ + (*(int (*)(PyObject *, pg_buffer *, int)) \ + PYGAMEAPI_GET_SLOT(base, 15)) + +#define pgBuffer_Release \ + (*(void (*)(pg_buffer *)) \ + PYGAMEAPI_GET_SLOT(base, 16)) + +#define pgDict_AsBuffer \ + (*(int (*)(pg_buffer *, PyObject *, int)) \ + PYGAMEAPI_GET_SLOT(base, 17)) + +#define pgExc_BufferError \ + ((PyObject *) \ + PYGAMEAPI_GET_SLOT(base, 18)) + +#if PG_API_VERSION == 2 +#define pg_GetDefaultWindow \ + (*(SDL_Window * (*)(void)) \ + PYGAMEAPI_GET_SLOT(base, 19)) + +#define pg_SetDefaultWindow \ + (*(void (*)(SDL_Window *)) \ + PYGAMEAPI_GET_SLOT(base, 20)) + +#define pg_GetDefaultWindowSurface \ + (*(pgSurfaceObject * (*)(void)) \ + PYGAMEAPI_GET_SLOT(base, 21)) + +#define pg_SetDefaultWindowSurface \ + (*(void (*)(pgSurfaceObject *)) \ + PYGAMEAPI_GET_SLOT(base, 22)) + +#define pg_EnvShouldBlendAlphaSDL2 \ + (*(char * (*)(void)) \ + PYGAMEAPI_GET_SLOT(base, 23)) + +#endif /* PG_API_VERSION == 2 */ + +#define import_pygame_base() IMPORT_PYGAME_MODULE(base) +#endif /* ~PYGAMEAPI_BASE_INTERNAL */ + +/* + * RECT module + */ +#if !defined(SDL_VERSION_ATLEAST) || PG_API_VERSION == 1 +typedef struct { + int x, y; + int w, h; +} GAME_Rect; +#else /* SDL 2+ */ +typedef SDL_Rect GAME_Rect; +#endif /* SDL 2+ */ + +typedef struct { + PyObject_HEAD GAME_Rect r; + PyObject *weakreflist; +} pgRectObject; + +#define pgRect_AsRect(x) (((pgRectObject *)x)->r) +#ifndef PYGAMEAPI_RECT_INTERNAL +#define pgRect_Type \ + (*(PyTypeObject *) \ + PYGAMEAPI_GET_SLOT(rect, 0)) + +#define pgRect_Check(x) \ + ((x)->ob_type == &pgRect_Type) +#define pgRect_New \ + (*(PyObject * (*)(SDL_Rect *)) \ + PYGAMEAPI_GET_SLOT(rect, 1)) + +#define pgRect_New4 \ + (*(PyObject * (*)(int, int, int, int)) \ + PYGAMEAPI_GET_SLOT(rect, 2)) + +#define pgRect_FromObject \ + (*(GAME_Rect * (*)(PyObject *, GAME_Rect *)) \ + PYGAMEAPI_GET_SLOT(rect, 3)) + +#define pgRect_Normalize (*(void (*)(GAME_Rect *)) PYGAMEAPI_GET_SLOT(rect, 4)) + +#define import_pygame_rect() IMPORT_PYGAME_MODULE(rect) +#endif /* ~PYGAMEAPI_RECT_INTERNAL */ + +/* + * CDROM module + */ + +typedef struct { + PyObject_HEAD int id; +} pgCDObject; + +#define pgCD_AsID(x) (((pgCDObject *)x)->id) +#ifndef PYGAMEAPI_CDROM_INTERNAL +#define pgCD_Type \ + (*(PyTypeObject *) \ + PYGAMEAPI_GET_SLOT(cdrom, 0)) + +#define pgCD_Check(x) \ + ((x)->ob_type == &pgCD_Type) +#define pgCD_New \ + (*(PyObject * (*)(int)) \ + PYGAMEAPI_GET_SLOT(cdrom, 1)) + +#define import_pygame_cd() IMPORT_PYGAME_MODULE(cdrom) +#endif + +/* + * JOYSTICK module + */ +typedef struct pgJoystickObject { + PyObject_HEAD + int id; + SDL_Joystick *joy; + + /* Joysticks form an intrusive linked list. + * + * Note that we don't maintain refcounts for these so they are weakrefs from + * the Python side. + */ + struct pgJoystickObject *next; + struct pgJoystickObject *prev; +} pgJoystickObject; + +#define pgJoystick_AsID(x) (((pgJoystickObject *)x)->id) +#define pgJoystick_AsSDL(x) (((pgJoystickObject *)x)->joy) + +#ifndef PYGAMEAPI_JOYSTICK_INTERNAL +#define pgJoystick_Type \ + (*(PyTypeObject *) \ + PYGAMEAPI_GET_SLOT(joystick, 0)) + +#define pgJoystick_Check(x) \ + ((x)->ob_type == &pgJoystick_Type) +#define pgJoystick_New \ + (*(PyObject * (*)(int)) \ + PYGAMEAPI_GET_SLOT(joystick, 1)) + +#define import_pygame_joystick() IMPORT_PYGAME_MODULE(joystick) +#endif + +/* + * DISPLAY module + */ + +#if defined(SDL_VERSION_ATLEAST) + +#if PG_API_VERSION == 2 +typedef struct { + Uint32 hw_available:1; + Uint32 wm_available:1; + Uint32 blit_hw:1; + Uint32 blit_hw_CC:1; + Uint32 blit_hw_A:1; + Uint32 blit_sw:1; + Uint32 blit_sw_CC:1; + Uint32 blit_sw_A:1; + Uint32 blit_fill:1; + Uint32 video_mem; + SDL_PixelFormat *vfmt; + SDL_PixelFormat vfmt_data; + int current_w; + int current_h; +} pg_VideoInfo; +#endif /* PG_API_VERSION == 2 */ + +typedef struct { +#if PG_API_VERSION == 1 + PyObject_HEAD SDL_VideoInfo info; +#else + PyObject_HEAD pg_VideoInfo info; +#endif +} pgVidInfoObject; + +#define pgVidInfo_AsVidInfo(x) (((pgVidInfoObject *)x)->info) +#endif /* defined(SDL_VERSION_ATLEAST) */ + +#ifndef PYGAMEAPI_DISPLAY_INTERNAL +#define pgVidInfo_Type \ + (*(PyTypeObject *) \ + PYGAMEAPI_GET_SLOT(display, 0)) + +#define pgVidInfo_Check(x) \ + ((x)->ob_type == &pgVidInfo_Type) + +#if PG_API_VERSION == 1 +#define pgVidInfo_New \ + (*(PyObject * (*)(SDL_VideoInfo *)) \ + PYGAMEAPI_GET_SLOT(display, 1)) +#else +#define pgVidInfo_New \ + (*(PyObject * (*)(pg_VideoInfo *)) \ + PYGAMEAPI_GET_SLOT(display, 1)) +#endif + +#define import_pygame_display() IMPORT_PYGAME_MODULE(display) +#endif /* ~PYGAMEAPI_DISPLAY_INTERNAL */ + +/* + * SURFACE module + */ +struct pgSubSurface_Data; +struct SDL_Surface; + +typedef struct { + PyObject_HEAD struct SDL_Surface *surf; +#if PG_API_VERSION == 2 + int owner; +#endif /* PG_API_VERSION == 2 */ + struct pgSubSurface_Data *subsurface; /* ptr to subsurface data (if a + * subsurface)*/ + PyObject *weakreflist; + PyObject *locklist; + PyObject *dependency; +} pgSurfaceObject; +#define pgSurface_AsSurface(x) (((pgSurfaceObject *)x)->surf) + +#ifndef PYGAMEAPI_SURFACE_INTERNAL +#define pgSurface_Type \ + (*(PyTypeObject *) \ + PYGAMEAPI_GET_SLOT(surface, 0)) + +#define pgSurface_Check(x) \ + (PyObject_IsInstance((x), (PyObject *) &pgSurface_Type)) +#if PG_API_VERSION == 1 +#define pgSurface_New \ + (*(pgSurfaceObject * (*)(SDL_Surface *)) \ + PYGAMEAPI_GET_SLOT(surface, 1)) + +#define pgSurface_SetSurface \ + (*(int (*)(pgSurfaceObject *, SDL_Surface *)) \ + PYGAMEAPI_GET_SLOT(surface, 3)) + +#else /* PG_API_VERSION == 2 */ +#define pgSurface_New2 \ + (*(pgSurfaceObject * (*)(SDL_Surface *, int)) \ + PYGAMEAPI_GET_SLOT(surface, 1)) + +#define pgSurface_SetSurface \ + (*(int (*)(pgSurfaceObject *, SDL_Surface *, int)) \ + PYGAMEAPI_GET_SLOT(surface, 3)) + +#endif /* PG_API_VERSION == 2 */ +#define pgSurface_Blit \ + (*(int (*)(pgSurfaceObject *, pgSurfaceObject *, GAME_Rect *, GAME_Rect *, int)) \ + PYGAMEAPI_GET_SLOT(surface, 2)) + +#define import_pygame_surface() \ + do { \ + IMPORT_PYGAME_MODULE(surface); \ + if (PyErr_Occurred() != NULL) \ + break; \ + IMPORT_PYGAME_MODULE(surflock); \ + } while (0) + +#if PG_API_VERSION == 2 +#define pgSurface_New(surface) pgSurface_New2((surface), 1) +#define pgSurface_NewNoOwn(surface) pgSurface_New2((surface), 0) +#endif /* PG_API_VERSION == 2 */ + +#endif /* ~PYGAMEAPI_SURFACE_INTERNAL */ + +/* + * SURFLOCK module + * auto imported/initialized by surface + */ +#ifndef PYGAMEAPI_SURFLOCK_INTERNAL +#define pgLifetimeLock_Type \ + (*(PyTypeObject *) \ + PYGAMEAPI_GET_SLOT(surflock, 0)) + +#define pgLifetimeLock_Check(x) \ + ((x)->ob_type == &pgLifetimeLock_Type) + +#define pgSurface_Prep(x) \ + if ((x)->subsurface) \ + (*(*(void (*)(pgSurfaceObject *)) \ + PYGAMEAPI_GET_SLOT(surflock, 1)))(x) + +#define pgSurface_Unprep(x) \ + if ((x)->subsurface) \ + (*(*(void (*)(pgSurfaceObject *)) \ + PYGAMEAPI_GET_SLOT(surflock, 2)))(x) + +#define pgSurface_Lock \ + (*(int (*)(pgSurfaceObject *)) \ + PYGAMEAPI_GET_SLOT(surflock, 3)) + +#define pgSurface_Unlock \ + (*(int (*)(pgSurfaceObject *)) \ + PYGAMEAPI_GET_SLOT(surflock, 4)) + +#define pgSurface_LockBy \ + (*(int (*)(pgSurfaceObject *, PyObject *)) \ + PYGAMEAPI_GET_SLOT(surflock, 5)) + +#define pgSurface_UnlockBy \ + (*(int (*)(pgSurfaceObject *, PyObject *)) \ + PYGAMEAPI_GET_SLOT(surflock, 6)) + +#define pgSurface_LockLifetime \ + (*(PyObject * (*)(PyObject *, PyObject *)) \ + PYGAMEAPI_GET_SLOT(surflock, 7)) +#endif + +/* + * EVENT module + */ +typedef struct pgEventObject pgEventObject; + +#ifndef PYGAMEAPI_EVENT_INTERNAL +#define pgEvent_Type \ + (*(PyTypeObject *) \ + PYGAMEAPI_GET_SLOT(event, 0)) + +#define pgEvent_Check(x) \ + ((x)->ob_type == &pgEvent_Type) + +#define pgEvent_New \ + (*(PyObject * (*)(SDL_Event *)) \ + PYGAMEAPI_GET_SLOT(event, 1)) + +#define pgEvent_New2 \ + (*(PyObject * (*)(int, PyObject *)) \ + PYGAMEAPI_GET_SLOT(event, 2)) + +#define pgEvent_FillUserEvent \ + (*(int (*)(pgEventObject *, SDL_Event *)) \ + PYGAMEAPI_GET_SLOT(event, 3)) + +#if PG_API_VERSION == 2 +#define pg_EnableKeyRepeat \ + (*(int (*)(int, int)) \ + PYGAMEAPI_GET_SLOT(event, 4)) + +#define pg_GetKeyRepeat \ + (*(void (*)(int *, int *)) \ + PYGAMEAPI_GET_SLOT(event, 5)) +#endif /* PG_API_VERSION == 2 */ + +#define import_pygame_event() IMPORT_PYGAME_MODULE(event) +#endif + +/* + * RWOBJECT module + * the rwobject are only needed for C side work, not accessable from python. + */ +#ifndef PYGAMEAPI_RWOBJECT_INTERNAL +#define pgRWops_FromObject \ + (*(SDL_RWops * (*)(PyObject *)) \ + PYGAMEAPI_GET_SLOT(rwobject, 0)) + +#define pgRWops_IsFileObject \ + (*(int (*)(SDL_RWops *)) \ + PYGAMEAPI_GET_SLOT(rwobject, 1)) + +#define pg_EncodeFilePath \ + (*(PyObject * (*)(PyObject *, PyObject *)) \ + PYGAMEAPI_GET_SLOT(rwobject, 2)) + +#define pg_EncodeString \ + (*(PyObject * (*)(PyObject *, const char *, const char *, PyObject *)) \ + PYGAMEAPI_GET_SLOT(rwobject, 3)) + +#define pgRWops_FromFileObject \ + (*(SDL_RWops * (*)(PyObject *)) \ + PYGAMEAPI_GET_SLOT(rwobject, 4)) + +#define pgRWops_ReleaseObject \ + (*(int (*)(SDL_RWops *)) \ + PYGAMEAPI_GET_SLOT(rwobject, 5)) + +#define import_pygame_rwobject() IMPORT_PYGAME_MODULE(rwobject) + +#endif + +/* + * PixelArray module + */ +#ifndef PYGAMEAPI_PIXELARRAY_INTERNAL +#define PyPixelArray_Type \ + ((PyTypeObject *) \ + PYGAMEAPI_GET_SLOT(pixelarray, 0)) + +#define PyPixelArray_Check(x) \ + ((x)->ob_type == &PyPixelArray_Type) +#define PyPixelArray_New \ + (*(PyObject * (*)) \ + PYGAMEAPI_GET_SLOT(pixelarray, 1)) + +#define import_pygame_pixelarray() IMPORT_PYGAME_MODULE(pixelarray) +#endif /* PYGAMEAPI_PIXELARRAY_INTERNAL */ + +/* + * Color module + */ +typedef struct pgColorObject pgColorObject; + +#ifndef PYGAMEAPI_COLOR_INTERNAL +#define pgColor_Type (*(PyObject *) \ + PYGAMEAPI_GET_SLOT(color, 0)) + +#define pgColor_Check(x) \ + ((x)->ob_type == &pgColor_Type) +#define pgColor_New \ + (*(PyObject * (*)(Uint8 *)) \ + PYGAMEAPI_GET_SLOT(color, 1)) + +#define pgColor_NewLength \ + (*(PyObject * (*)(Uint8 *, Uint8)) \ + PYGAMEAPI_GET_SLOT(color, 3)) + +#define pg_RGBAFromColorObj \ + (*(int (*)(PyObject *, Uint8 *)) \ + PYGAMEAPI_GET_SLOT(color, 2)) + +#define pg_RGBAFromFuzzyColorObj \ + (*(int (*)(PyObject *, Uint8 *)) \ + PYGAMEAPI_GET_SLOT(color, 4)) + +#define pgColor_AsArray(x) (((pgColorObject *)x)->data) +#define pgColor_NumComponents(x) (((pgColorObject *)x)->len) + + +#define import_pygame_color() IMPORT_PYGAME_MODULE(color) +#endif /* PYGAMEAPI_COLOR_INTERNAL */ + +/* + * Math module + */ +#ifndef PYGAMEAPI_MATH_INTERNAL +#define pgVector2_Check(x) \ + ((x)->ob_type == (PyTypeObject *) \ + PYGAMEAPI_GET_SLOT(math, 0)) + +#define pgVector3_Check(x) \ + ((x)->ob_type == (PyTypeObject *) \ + PYGAMEAPI_GET_SLOT(math, 1)) +/* +#define pgVector2_New \ + (*(PyObject*(*)) \ + PYGAMEAPI_GET_SLOT(PyGAME_C_API, 1)) +*/ +#define import_pygame_math() IMPORT_PYGAME_MODULE(math) +#endif /* PYGAMEAPI_MATH_INTERNAL */ + +#define IMPORT_PYGAME_MODULE _IMPORT_PYGAME_MODULE + +/* + * base pygame API slots + * disable slots with NO_PYGAME_C_API + */ +#ifdef PYGAME_H +PYGAMEAPI_DEFINE_SLOTS(base); +PYGAMEAPI_DEFINE_SLOTS(rect); +PYGAMEAPI_DEFINE_SLOTS(cdrom); +PYGAMEAPI_DEFINE_SLOTS(joystick); +PYGAMEAPI_DEFINE_SLOTS(display); +PYGAMEAPI_DEFINE_SLOTS(surface); +PYGAMEAPI_DEFINE_SLOTS(surflock); +PYGAMEAPI_DEFINE_SLOTS(event); +PYGAMEAPI_DEFINE_SLOTS(rwobject); +PYGAMEAPI_DEFINE_SLOTS(pixelarray); +PYGAMEAPI_DEFINE_SLOTS(color); +PYGAMEAPI_DEFINE_SLOTS(math); +#else /* ~PYGAME_H */ +PYGAMEAPI_EXTERN_SLOTS(base); +PYGAMEAPI_EXTERN_SLOTS(rect); +PYGAMEAPI_EXTERN_SLOTS(cdrom); +PYGAMEAPI_EXTERN_SLOTS(joystick); +PYGAMEAPI_EXTERN_SLOTS(display); +PYGAMEAPI_EXTERN_SLOTS(surface); +PYGAMEAPI_EXTERN_SLOTS(surflock); +PYGAMEAPI_EXTERN_SLOTS(event); +PYGAMEAPI_EXTERN_SLOTS(rwobject); +PYGAMEAPI_EXTERN_SLOTS(pixelarray); +PYGAMEAPI_EXTERN_SLOTS(color); +PYGAMEAPI_EXTERN_SLOTS(math); +#endif /* ~PYGAME_H */ + +#endif /* PYGAME_H */ diff --git a/venv/Include/site/python3.9/pygame/include/bitmask.h b/venv/Include/site/python3.9/pygame/include/bitmask.h new file mode 100644 index 0000000..d95297e --- /dev/null +++ b/venv/Include/site/python3.9/pygame/include/bitmask.h @@ -0,0 +1,149 @@ +/* + Bitmask 1.7 - A pixel-perfect collision detection library. + + Copyright (C) 2002-2005 Ulf Ekstrom except for the bitcount + function which is copyright (C) Donald W. Gillies, 1992. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef BITMASK_H +#define BITMASK_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +/* Define INLINE for different compilers. If your compiler does not + support inlining then there might be a performance hit in + bitmask_overlap_area(). +*/ +#ifndef INLINE +# ifdef __GNUC__ +# define INLINE inline +# else +# ifdef _MSC_VER +# define INLINE __inline +# else +# define INLINE +# endif +# endif +#endif + +#define BITMASK_W unsigned long int +#define BITMASK_W_LEN (sizeof(BITMASK_W)*CHAR_BIT) +#define BITMASK_W_MASK (BITMASK_W_LEN - 1) +#define BITMASK_N(n) ((BITMASK_W)1 << (n)) + +typedef struct bitmask +{ + int w,h; + BITMASK_W bits[1]; +} bitmask_t; + +/* Creates a bitmask of width w and height h, where + w and h must both be greater than or equal to 0. + The mask is automatically cleared when created. + */ +bitmask_t *bitmask_create(int w, int h); + +/* Frees all the memory allocated by bitmask_create for m. */ +void bitmask_free(bitmask_t *m); + +/* Create a copy of the given bitmask. */ +bitmask_t *bitmask_copy(bitmask_t *m); + +/* Clears all bits in the mask */ +void bitmask_clear(bitmask_t *m); + +/* Sets all bits in the mask */ +void bitmask_fill(bitmask_t *m); + +/* Flips all bits in the mask */ +void bitmask_invert(bitmask_t *m); + +/* Counts the bits in the mask */ +unsigned int bitmask_count(bitmask_t *m); + +/* Returns nonzero if the bit at (x,y) is set. Coordinates start at + (0,0) */ +static INLINE int bitmask_getbit(const bitmask_t *m, int x, int y) +{ + return (m->bits[x/BITMASK_W_LEN*m->h + y] & BITMASK_N(x & BITMASK_W_MASK)) != 0; +} + +/* Sets the bit at (x,y) */ +static INLINE void bitmask_setbit(bitmask_t *m, int x, int y) +{ + m->bits[x/BITMASK_W_LEN*m->h + y] |= BITMASK_N(x & BITMASK_W_MASK); +} + +/* Clears the bit at (x,y) */ +static INLINE void bitmask_clearbit(bitmask_t *m, int x, int y) +{ + m->bits[x/BITMASK_W_LEN*m->h + y] &= ~BITMASK_N(x & BITMASK_W_MASK); +} + +/* Returns nonzero if the masks overlap with the given offset. + The overlap tests uses the following offsets (which may be negative): + + +----+----------.. + |A | yoffset + | +-+----------.. + +--|B + |xoffset + | | + : : +*/ +int bitmask_overlap(const bitmask_t *a, const bitmask_t *b, int xoffset, int yoffset); + +/* Like bitmask_overlap(), but will also give a point of intersection. + x and y are given in the coordinates of mask a, and are untouched + if there is no overlap. */ +int bitmask_overlap_pos(const bitmask_t *a, const bitmask_t *b, + int xoffset, int yoffset, int *x, int *y); + +/* Returns the number of overlapping 'pixels' */ +int bitmask_overlap_area(const bitmask_t *a, const bitmask_t *b, int xoffset, int yoffset); + +/* Fills a mask with the overlap of two other masks. A bitwise AND. */ +void bitmask_overlap_mask (const bitmask_t *a, const bitmask_t *b, bitmask_t *c, int xoffset, int yoffset); + +/* Draws mask b onto mask a (bitwise OR). Can be used to compose large + (game background?) mask from several submasks, which may speed up + the testing. */ + +void bitmask_draw(bitmask_t *a, const bitmask_t *b, int xoffset, int yoffset); + +void bitmask_erase(bitmask_t *a, const bitmask_t *b, int xoffset, int yoffset); + +/* Return a new scaled bitmask, with dimensions w*h. The quality of the + scaling may not be perfect for all circumstances, but it should + be reasonable. If either w or h is 0 a clear 1x1 mask is returned. */ +bitmask_t *bitmask_scale(const bitmask_t *m, int w, int h); + +/* Convolve b into a, drawing the output into o, shifted by offset. If offset + * is 0, then the (x,y) bit will be set if and only if + * bitmask_overlap(a, b, x - b->w - 1, y - b->h - 1) returns true. + * + * Modifies bits o[xoffset ... xoffset + a->w + b->w - 1) + * [yoffset ... yoffset + a->h + b->h - 1). */ +void bitmask_convolve(const bitmask_t *a, const bitmask_t *b, bitmask_t *o, int xoffset, int yoffset); + +#ifdef __cplusplus +} /* End of extern "C" { */ +#endif + +#endif diff --git a/venv/Include/site/python3.9/pygame/include/pgcompat.h b/venv/Include/site/python3.9/pygame/include/pgcompat.h new file mode 100644 index 0000000..2ba1b6b --- /dev/null +++ b/venv/Include/site/python3.9/pygame/include/pgcompat.h @@ -0,0 +1,180 @@ +/* Python 2.x/3.x and SDL compatibility tools + */ + +#if !defined(PGCOMPAT_H) +#define PGCOMPAT_H + +#include + +/* Cobjects vanish in Python 3.2; so we will code as though we use capsules */ +#if defined(Py_CAPSULE_H) +#define PG_HAVE_CAPSULE 1 +#else +#define PG_HAVE_CAPSULE 0 +#endif +#if defined(Py_COBJECT_H) +#define PG_HAVE_COBJECT 1 +#else +#define PG_HAVE_COBJECT 0 +#endif +#if !PG_HAVE_CAPSULE +#define PyCapsule_New(ptr, n, dfn) PyCObject_FromVoidPtr(ptr, dfn) +#define PyCapsule_GetPointer(obj, n) PyCObject_AsVoidPtr(obj) +#define PyCapsule_CheckExact(obj) PyCObject_Check(obj) +#endif + +/* Pygame uses Py_buffer (PEP 3118) to exchange array information internally; + * define here as needed. + */ +#if !defined(PyBUF_SIMPLE) +typedef struct bufferinfo { + void *buf; + PyObject *obj; + Py_ssize_t len; + Py_ssize_t itemsize; + int readonly; + int ndim; + char *format; + Py_ssize_t *shape; + Py_ssize_t *strides; + Py_ssize_t *suboffsets; + void *internal; +} Py_buffer; + +/* Flags for getting buffers */ +#define PyBUF_SIMPLE 0 +#define PyBUF_WRITABLE 0x0001 +/* we used to include an E, backwards compatible alias */ +#define PyBUF_WRITEABLE PyBUF_WRITABLE +#define PyBUF_FORMAT 0x0004 +#define PyBUF_ND 0x0008 +#define PyBUF_STRIDES (0x0010 | PyBUF_ND) +#define PyBUF_C_CONTIGUOUS (0x0020 | PyBUF_STRIDES) +#define PyBUF_F_CONTIGUOUS (0x0040 | PyBUF_STRIDES) +#define PyBUF_ANY_CONTIGUOUS (0x0080 | PyBUF_STRIDES) +#define PyBUF_INDIRECT (0x0100 | PyBUF_STRIDES) + +#define PyBUF_CONTIG (PyBUF_ND | PyBUF_WRITABLE) +#define PyBUF_CONTIG_RO (PyBUF_ND) + +#define PyBUF_STRIDED (PyBUF_STRIDES | PyBUF_WRITABLE) +#define PyBUF_STRIDED_RO (PyBUF_STRIDES) + +#define PyBUF_RECORDS (PyBUF_STRIDES | PyBUF_WRITABLE | PyBUF_FORMAT) +#define PyBUF_RECORDS_RO (PyBUF_STRIDES | PyBUF_FORMAT) + +#define PyBUF_FULL (PyBUF_INDIRECT | PyBUF_WRITABLE | PyBUF_FORMAT) +#define PyBUF_FULL_RO (PyBUF_INDIRECT | PyBUF_FORMAT) + +#define PyBUF_READ 0x100 +#define PyBUF_WRITE 0x200 +#define PyBUF_SHADOW 0x400 + +typedef int(*getbufferproc)(PyObject *, Py_buffer *, int); +typedef void(*releasebufferproc)(Py_buffer *); +#endif /* ~defined(PyBUF_SIMPLE) */ + +/* define common types where SDL is not included */ +#ifndef SDL_VERSION_ATLEAST +#ifdef _MSC_VER +typedef unsigned __int8 uint8_t; +typedef unsigned __int32 uint32_t; +#else +#include +#endif +typedef uint32_t Uint32; +typedef uint8_t Uint8; +#endif /* no SDL */ + + +#if defined(SDL_VERSION_ATLEAST) + +#ifndef SDL_WINDOW_VULKAN +#define SDL_WINDOW_VULKAN 0 +#endif + +#ifndef SDL_WINDOW_ALWAYS_ON_TOP +#define SDL_WINDOW_ALWAYS_ON_TOP 0 +#endif + +#ifndef SDL_WINDOW_SKIP_TASKBAR +#define SDL_WINDOW_SKIP_TASKBAR 0 +#endif + +#ifndef SDL_WINDOW_UTILITY +#define SDL_WINDOW_UTILITY 0 +#endif + +#ifndef SDL_WINDOW_TOOLTIP +#define SDL_WINDOW_TOOLTIP 0 +#endif + +#ifndef SDL_WINDOW_POPUP_MENU +#define SDL_WINDOW_POPUP_MENU 0 +#endif + + +#ifndef SDL_WINDOW_INPUT_GRABBED +#define SDL_WINDOW_INPUT_GRABBED 0 +#endif + +#ifndef SDL_WINDOW_INPUT_FOCUS +#define SDL_WINDOW_INPUT_FOCUS 0 +#endif + +#ifndef SDL_WINDOW_MOUSE_FOCUS +#define SDL_WINDOW_MOUSE_FOCUS 0 +#endif + +#ifndef SDL_WINDOW_FOREIGN +#define SDL_WINDOW_FOREIGN 0 +#endif + +#ifndef SDL_WINDOW_ALLOW_HIGHDPI +#define SDL_WINDOW_ALLOW_HIGHDPI 0 +#endif + +#ifndef SDL_WINDOW_MOUSE_CAPTURE +#define SDL_WINDOW_MOUSE_CAPTURE 0 +#endif + +#ifndef SDL_WINDOW_ALWAYS_ON_TOP +#define SDL_WINDOW_ALWAYS_ON_TOP 0 +#endif + +#ifndef SDL_WINDOW_SKIP_TASKBAR +#define SDL_WINDOW_SKIP_TASKBAR 0 +#endif + +#ifndef SDL_WINDOW_UTILITY +#define SDL_WINDOW_UTILITY 0 +#endif + +#ifndef SDL_WINDOW_TOOLTIP +#define SDL_WINDOW_TOOLTIP 0 +#endif + +#ifndef SDL_WINDOW_POPUP_MENU +#define SDL_WINDOW_POPUP_MENU 0 +#endif + +#if SDL_VERSION_ATLEAST(2, 0, 4) +/* To control the use of: + * SDL_AUDIODEVICEADDED + * SDL_AUDIODEVICEREMOVED + * + * Ref: https://wiki.libsdl.org/SDL_EventType + * Ref: https://wiki.libsdl.org/SDL_AudioDeviceEvent + */ +#define SDL2_AUDIODEVICE_SUPPORTED +#endif + +#ifndef SDL_MOUSEWHEEL_FLIPPED +#define NO_SDL_MOUSEWHEEL_FLIPPED +#endif + + +#endif /* defined(SDL_VERSION_ATLEAST) */ + + +#endif /* ~defined(PGCOMPAT_H) */ diff --git a/venv/Include/site/python3.9/pygame/include/pgimport.h b/venv/Include/site/python3.9/pygame/include/pgimport.h new file mode 100644 index 0000000..6649865 --- /dev/null +++ b/venv/Include/site/python3.9/pygame/include/pgimport.h @@ -0,0 +1,80 @@ +#ifndef PGIMPORT_H +#define PGIMPORT_H + +/* Prefix when initializing module */ +#define MODPREFIX "" +/* Prefix when importing module */ +#define IMPPREFIX "pygame." + +#ifdef __SYMBIAN32__ + +/* On Symbian there is no pygame package. The extensions are built-in or in + * sys\bin. */ +#undef MODPREFIX +#undef IMPPREFIX +#define MODPREFIX "pygame_" +#define IMPPREFIX "pygame_" + +#endif /* __SYMBIAN32__ */ + +#include "pgcompat.h" + +#define PYGAMEAPI_LOCAL_ENTRY "_PYGAME_C_API" +#define PG_CAPSULE_NAME(m) (IMPPREFIX m "." PYGAMEAPI_LOCAL_ENTRY) + +/* + * fill API slots defined by PYGAMEAPI_DEFINE_SLOTS/PYGAMEAPI_EXTERN_SLOTS + */ +#define _IMPORT_PYGAME_MODULE(module) \ + { \ + PyObject *_mod_##module = PyImport_ImportModule(IMPPREFIX #module); \ + \ + if (_mod_##module != NULL) { \ + PyObject *_c_api = \ + PyObject_GetAttrString(_mod_##module, PYGAMEAPI_LOCAL_ENTRY);\ + \ + Py_DECREF(_mod_##module); \ + if (_c_api != NULL && PyCapsule_CheckExact(_c_api)) { \ + void **localptr = (void **)PyCapsule_GetPointer( \ + _c_api, PG_CAPSULE_NAME(#module)); \ + _PGSLOTS_ ## module = localptr; \ + } \ + Py_XDECREF(_c_api); \ + } \ + } + +#define PYGAMEAPI_IS_IMPORTED(module) (_PGSLOTS_ ## module != NULL) + +/* + * source file must include one of these in order to use _IMPORT_PYGAME_MODULE. + * this is set by import_pygame_*() functions. + * disable with NO_PYGAME_C_API + */ +#define PYGAMEAPI_DEFINE_SLOTS(module) \ + void ** _PGSLOTS_ ## module = NULL +#define PYGAMEAPI_EXTERN_SLOTS(module) \ + extern void **_PGSLOTS_ ## module +#define PYGAMEAPI_GET_SLOT(module, index) \ + _PGSLOTS_ ## module [(index)] + +/* + * disabled API with NO_PYGAME_C_API; do nothing instead + */ +#ifdef NO_PYGAME_C_API + +#undef PYGAMEAPI_DEFINE_SLOTS +#undef PYGAMEAPI_EXTERN_SLOTS + +#define PYGAMEAPI_DEFINE_SLOTS(module) +#define PYGAMEAPI_EXTERN_SLOTS(module) + +/* intentionally leave this defined to cause a compiler error * +#define PYGAMEAPI_GET_SLOT(api_root, index) +#undef PYGAMEAPI_GET_SLOT*/ + +#undef _IMPORT_PYGAME_MODULE +#define _IMPORT_PYGAME_MODULE(module) + +#endif /* NO_PYGAME_C_API */ + +#endif /* ~PGIMPORT_H */ diff --git a/venv/Include/site/python3.9/pygame/include/pgplatform.h b/venv/Include/site/python3.9/pygame/include/pgplatform.h new file mode 100644 index 0000000..659ea62 --- /dev/null +++ b/venv/Include/site/python3.9/pygame/include/pgplatform.h @@ -0,0 +1,91 @@ +/* platform/compiler adjustments */ +#ifndef PG_PLATFORM_H +#define PG_PLATFORM_H + +#if defined(HAVE_SNPRINTF) /* defined in python.h (pyerrors.h) and SDL.h \ + (SDL_config.h) */ +#undef HAVE_SNPRINTF /* remove GCC redefine warning */ +#endif /* HAVE_SNPRINTF */ + +#ifndef PG_INLINE +#if defined(__clang__) +#define PG_INLINE __inline__ __attribute__((__unused__)) +#elif defined(__GNUC__) +#define PG_INLINE __inline__ +#elif defined(_MSC_VER) +#define PG_INLINE __inline +#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L +#define PG_INLINE inline +#else +#define PG_INLINE +#endif +#endif /* ~PG_INLINE */ + +// Worth trying this on MSVC/win32 builds to see if provides any speed up +#ifndef PG_FORCEINLINE +#if defined(__clang__) +#define PG_FORCEINLINE __inline__ __attribute__((__unused__)) +#elif defined(__GNUC__) +#define PG_FORCEINLINE __inline__ +#elif defined(_MSC_VER) +#define PG_FORCEINLINE __forceinline +#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L +#define PG_FORCEINLINE inline +#else +#define PG_FORCEINLINE +#endif +#endif /* ~PG_FORCEINLINE */ + +/* This is unconditionally defined in Python.h */ +#if defined(_POSIX_C_SOURCE) +#undef _POSIX_C_SOURCE +#endif + +/* No signal() */ +#if defined(__SYMBIAN32__) && defined(HAVE_SIGNAL_H) +#undef HAVE_SIGNAL_H +#endif + +#if defined(HAVE_SNPRINTF) +#undef HAVE_SNPRINTF +#endif + +/* SDL needs WIN32 */ +#if !defined(WIN32) && \ + (defined(MS_WIN32) || defined(_WIN32) || \ + defined(__WIN32) || defined(__WIN32__) || defined(_WINDOWS)) +#define WIN32 +#endif + +/* Commenting out SSE4_2 stuff because it does not do runtime detection. +#ifndef PG_TARGET_SSE4_2 +#if defined(__clang__) || (defined(__GNUC__) && ((__GNUC__ == 4 && __GNUC_MINOR__ >= 9) || __GNUC__ >= 5 )) +//The old gcc 4.8 on centos used by manylinux1 does not seem to get sse4.2 intrinsics +#define PG_FUNCTION_TARGET_SSE4_2 __attribute__((target("sse4.2"))) +// No else; we define the fallback later +#endif +#endif +*/ +/* ~PG_TARGET_SSE4_2 */ + +/* +#ifdef PG_FUNCTION_TARGET_SSE4_2 +#if !defined(__SSE4_2__) && !defined(PG_COMPILE_SSE4_2) +#if defined(__x86_64__) || defined(__i386__) +#define PG_COMPILE_SSE4_2 1 +#endif +#endif +#endif +*/ +/* ~PG_TARGET_SSE4_2 */ + +/* Fallback definition of target attribute */ +#ifndef PG_FUNCTION_TARGET_SSE4_2 +#define PG_FUNCTION_TARGET_SSE4_2 +#endif + +#ifndef PG_COMPILE_SSE4_2 +#define PG_COMPILE_SSE4_2 0 +#endif + +#endif /* ~PG_PLATFORM_H */ diff --git a/venv/Include/site/python3.9/pygame/include/pygame.h b/venv/Include/site/python3.9/pygame/include/pygame.h new file mode 100644 index 0000000..bcbf1d9 --- /dev/null +++ b/venv/Include/site/python3.9/pygame/include/pygame.h @@ -0,0 +1,34 @@ +/* + pygame - Python Game Library + Copyright (C) 2000-2001 Pete Shinners + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Pete Shinners + pete@shinners.org +*/ + +/* To allow the Pygame C api to be globally shared by all code within an + * extension module built from multiple C files, only include the pygame.h + * header within the top level C file, the one which calls the + * 'import_pygame_*' macros. All other C source files of the module should + * include _pygame.h instead. + */ +#ifndef PYGAME_H +#define PYGAME_H + +#include "_pygame.h" + +#endif diff --git a/venv/Include/site/python3.9/pygame/include/pygame_bufferproxy.h b/venv/Include/site/python3.9/pygame/include/pygame_bufferproxy.h new file mode 100644 index 0000000..d7c4ac6 --- /dev/null +++ b/venv/Include/site/python3.9/pygame/include/pygame_bufferproxy.h @@ -0,0 +1,59 @@ +/* + pygame - Python Game Library + Copyright (C) 2000-2001 Pete Shinners + Copyright (C) 2007 Rene Dudfield, Richard Goedeken + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Pete Shinners + pete@shinners.org +*/ + +/* Bufferproxy module C api. */ +#if !defined(PG_BUFPROXY_HEADER) +#define PG_BUFPROXY_HEADER + +#include + +typedef PyObject *(*_pgbufproxy_new_t)(PyObject *, getbufferproc); +typedef PyObject *(*_pgbufproxy_get_obj_t)(PyObject *); +typedef int (*_pgbufproxy_trip_t)(PyObject *); + +#ifndef PYGAMEAPI_BUFPROXY_INTERNAL + +#include "pgimport.h" + +PYGAMEAPI_DEFINE_SLOTS(bufferproxy); + +#define pgBufproxy_Type (*(PyTypeObject*) \ + PYGAMEAPI_GET_SLOT(bufferproxy, 0) ) + +#define pgBufproxy_Check(x) ((x)->ob_type == &pgBufproxy_Type) + +#define pgBufproxy_New (*(_pgbufproxy_new_t) \ + PYGAMEAPI_GET_SLOT(bufferproxy, 1)) + +#define pgBufproxy_GetParent \ + (*(_pgbufproxy_get_obj_t) \ + PYGAMEAPI_GET_SLOT(bufferproxy, 2)) + +#define pgBufproxy_Trip (*(_pgbufproxy_trip_t) \ + PYGAMEAPI_GET_SLOT(bufferproxy, 3)) + +#define import_pygame_bufferproxy() _IMPORT_PYGAME_MODULE(bufferproxy) + +#endif /* ~PYGAMEAPI_BUFPROXY_INTERNAL */ + +#endif /* ~defined(PG_BUFPROXY_HEADER) */ diff --git a/venv/Include/site/python3.9/pygame/include/pygame_font.h b/venv/Include/site/python3.9/pygame/include/pygame_font.h new file mode 100644 index 0000000..3fe4500 --- /dev/null +++ b/venv/Include/site/python3.9/pygame/include/pygame_font.h @@ -0,0 +1,53 @@ +/* + pygame - Python Game Library + Copyright (C) 2000-2001 Pete Shinners + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Pete Shinners + pete@shinners.org +*/ + +#include +#include "pgplatform.h" + +struct TTF_Font; + +typedef struct { + PyObject_HEAD + TTF_Font* font; + PyObject* weakreflist; +} PyFontObject; +#define PyFont_AsFont(x) (((PyFontObject*)x)->font) + +#ifndef PYGAMEAPI_FONT_INTERNAL + +#include "pgimport.h" + +PYGAMEAPI_DEFINE_SLOTS(font); + +#define PyFont_Type (*(PyTypeObject*) \ + PYGAMEAPI_GET_SLOT(font, 0)) +#define PyFont_Check(x) ((x)->ob_type == &PyFont_Type) + +#define PyFont_New (*(PyObject*(*)(TTF_Font*))\ + PYGAMEAPI_GET_SLOT(font, 1)) + +/*slot 2 taken by FONT_INIT_CHECK*/ + +#define import_pygame_font() _IMPORT_PYGAME_MODULE(font) + +#endif + diff --git a/venv/Include/site/python3.9/pygame/include/pygame_freetype.h b/venv/Include/site/python3.9/pygame/include/pygame_freetype.h new file mode 100644 index 0000000..f727ee2 --- /dev/null +++ b/venv/Include/site/python3.9/pygame/include/pygame_freetype.h @@ -0,0 +1,43 @@ +/* + pygame - Python Game Library + Copyright (C) 2009 Vicent Marti + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ +#ifndef PYGAME_FREETYPE_H_ +#define PYGAME_FREETYPE_H_ + +#include "pgplatform.h" +#include "pgimport.h" +#include "pgcompat.h" + +#ifndef PYGAME_FREETYPE_INTERNAL + +PYGAMEAPI_DEFINE_SLOTS(_freetype); + +#define pgFont_Type (*(PyTypeObject*) \ + PYGAMEAPI_GET_SLOT(_freetype, 0)) + +#define pgFont_Check(x) ((x)->ob_type == &pgFont_Type) + +#define pgFont_New (*(PyObject*(*)(const char*, long)) \ + PYGAMEAPI_GET_SLOT(_freetype, 1)) + +#define import_pygame_freetype() _IMPORT_PYGAME_MODULE(_freetype) + +#endif /* PYGAME_FREETYPE_INTERNAL */ + +#endif /* PYGAME_FREETYPE_H_ */ diff --git a/venv/Include/site/python3.9/pygame/include/pygame_mask.h b/venv/Include/site/python3.9/pygame/include/pygame_mask.h new file mode 100644 index 0000000..1b25553 --- /dev/null +++ b/venv/Include/site/python3.9/pygame/include/pygame_mask.h @@ -0,0 +1,47 @@ +/* + pygame - Python Game Library + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef PGMASK_H +#define PGMASK_H + +#include +#include "bitmask.h" + +typedef struct { + PyObject_HEAD + bitmask_t *mask; + void *bufdata; +} pgMaskObject; + +#define pgMask_AsBitmap(x) (((pgMaskObject*)x)->mask) + +#ifndef PYGAMEAPI_MASK_INTERNAL + +#include "pgimport.h" + +PYGAMEAPI_DEFINE_SLOTS(mask); + +#define pgMask_Type (*(PyTypeObject*) \ + PYGAMEAPI_GET_SLOT(mask, 0)) +#define pgMask_Check(x) ((x)->ob_type == &pgMask_Type) + +#define import_pygame_mask() _IMPORT_PYGAME_MODULE(mask) + +#endif /* ~PYGAMEAPI_MASK_INTERNAL */ + +#endif /* ~PGMASK_H */ diff --git a/venv/Include/site/python3.9/pygame/include/pygame_mixer.h b/venv/Include/site/python3.9/pygame/include/pygame_mixer.h new file mode 100644 index 0000000..52e76ae --- /dev/null +++ b/venv/Include/site/python3.9/pygame/include/pygame_mixer.h @@ -0,0 +1,82 @@ +/* + pygame - Python Game Library + Copyright (C) 2000-2001 Pete Shinners + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Pete Shinners + pete@shinners.org +*/ + +#ifndef PGMIXER_H +#define PGMIXER_H + +#include +#include + +#include "pgcompat.h" + +struct Mix_Chunk; + +typedef struct { + PyObject_HEAD + Mix_Chunk *chunk; + Uint8 *mem; + PyObject *weakreflist; +} pgSoundObject; + +typedef struct { + PyObject_HEAD + int chan; +} pgChannelObject; + +#define pgSound_AsChunk(x) (((pgSoundObject*)x)->chunk) +#define pgChannel_AsInt(x) (((pgChannelObject*)x)->chan) + +#include "pgimport.h" + +#ifndef PYGAMEAPI_MIXER_INTERNAL + +PYGAMEAPI_DEFINE_SLOTS(mixer); + +#define pgSound_Type (*(PyTypeObject*) \ + PYGAMEAPI_GET_SLOT(mixer, 0)) + +#define pgSound_Check(x) ((x)->ob_type == &pgSound_Type) + +#define pgSound_New (*(PyObject*(*)(Mix_Chunk*)) \ + PYGAMEAPI_GET_SLOT(mixer, 1)) + +#define pgSound_Play (*(PyObject*(*)(PyObject*, PyObject*)) \ + PYGAMEAPI_GET_SLOT(mixer, 2)) + +#define pgChannel_Type (*(PyTypeObject*) \ + PYGAMEAPI_GET_SLOT(mixer, 3)) +#define pgChannel_Check(x) ((x)->ob_type == &pgChannel_Type) + +#define pgChannel_New (*(PyObject*(*)(int)) \ + PYGAMEAPI_GET_SLOT(mixer, 4)) + +#define pgMixer_AutoInit (*(PyObject*(*)(PyObject*, PyObject*)) \ + PYGAMEAPI_GET_SLOT(mixer, 5)) + +#define pgMixer_AutoQuit (*(void(*)(void)) \ + PYGAMEAPI_GET_SLOT(mixer, 6)) + +#define import_pygame_mixer() _IMPORT_PYGAME_MODULE(mixer) + +#endif /* PYGAMEAPI_MIXER_INTERNAL */ + +#endif /* ~PGMIXER_H */ diff --git a/venv/Include/site/python3.9/pygame/include/sse2neon.h b/venv/Include/site/python3.9/pygame/include/sse2neon.h new file mode 100644 index 0000000..7dbb4dd --- /dev/null +++ b/venv/Include/site/python3.9/pygame/include/sse2neon.h @@ -0,0 +1,3676 @@ +#ifndef SSE2NEON_H +#define SSE2NEON_H + +// This header file provides a simple API translation layer +// between SSE intrinsics to their corresponding Arm/Aarch64 NEON versions +// +// This header file does not yet translate all of the SSE intrinsics. +// +// Contributors to this work are: +// John W. Ratcliff +// Brandon Rowlett +// Ken Fast +// Eric van Beurden +// Alexander Potylitsin +// Hasindu Gamaarachchi +// Jim Huang +// Mark Cheng +// Malcolm James MacLeod +// Devin Hussey (easyaspi314) +// Sebastian Pop + +/* + * The MIT license: + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#if defined(__GNUC__) || defined(__clang__) + +#pragma push_macro("FORCE_INLINE") +#pragma push_macro("ALIGN_STRUCT") +#define FORCE_INLINE static inline __attribute__((always_inline)) +#define ALIGN_STRUCT(x) __attribute__((aligned(x))) + +#else + +#error "Macro name collisions may happens with unknown compiler" +#ifdef FORCE_INLINE +#undef FORCE_INLINE +#endif +#define FORCE_INLINE static inline +#ifndef ALIGN_STRUCT +#define ALIGN_STRUCT(x) __declspec(align(x)) +#endif + +#endif + +#include +#include + +#include + +/** + * MACRO for shuffle parameter for _mm_shuffle_ps(). + * Argument fp3 is a digit[0123] that represents the fp from argument "b" + * of mm_shuffle_ps that will be placed in fp3 of result. fp2 is the same + * for fp2 in result. fp1 is a digit[0123] that represents the fp from + * argument "a" of mm_shuffle_ps that will be places in fp1 of result. + * fp0 is the same for fp0 of result. + */ +#define _MM_SHUFFLE(fp3, fp2, fp1, fp0) \ + (((fp3) << 6) | ((fp2) << 4) | ((fp1) << 2) | ((fp0))) + +/* indicate immediate constant argument in a given range */ +#define __constrange(a, b) const + +typedef float32x2_t __m64; +typedef float32x4_t __m128; +typedef int64x2_t __m128i; + +// ****************************************** +// type-safe casting between types +// ****************************************** + +#define vreinterpretq_m128_f16(x) vreinterpretq_f32_f16(x) +#define vreinterpretq_m128_f32(x) (x) +#define vreinterpretq_m128_f64(x) vreinterpretq_f32_f64(x) + +#define vreinterpretq_m128_u8(x) vreinterpretq_f32_u8(x) +#define vreinterpretq_m128_u16(x) vreinterpretq_f32_u16(x) +#define vreinterpretq_m128_u32(x) vreinterpretq_f32_u32(x) +#define vreinterpretq_m128_u64(x) vreinterpretq_f32_u64(x) + +#define vreinterpretq_m128_s8(x) vreinterpretq_f32_s8(x) +#define vreinterpretq_m128_s16(x) vreinterpretq_f32_s16(x) +#define vreinterpretq_m128_s32(x) vreinterpretq_f32_s32(x) +#define vreinterpretq_m128_s64(x) vreinterpretq_f32_s64(x) + +#define vreinterpretq_f16_m128(x) vreinterpretq_f16_f32(x) +#define vreinterpretq_f32_m128(x) (x) +#define vreinterpretq_f64_m128(x) vreinterpretq_f64_f32(x) + +#define vreinterpretq_u8_m128(x) vreinterpretq_u8_f32(x) +#define vreinterpretq_u16_m128(x) vreinterpretq_u16_f32(x) +#define vreinterpretq_u32_m128(x) vreinterpretq_u32_f32(x) +#define vreinterpretq_u64_m128(x) vreinterpretq_u64_f32(x) + +#define vreinterpretq_s8_m128(x) vreinterpretq_s8_f32(x) +#define vreinterpretq_s16_m128(x) vreinterpretq_s16_f32(x) +#define vreinterpretq_s32_m128(x) vreinterpretq_s32_f32(x) +#define vreinterpretq_s64_m128(x) vreinterpretq_s64_f32(x) + +#define vreinterpretq_m128i_s8(x) vreinterpretq_s64_s8(x) +#define vreinterpretq_m128i_s16(x) vreinterpretq_s64_s16(x) +#define vreinterpretq_m128i_s32(x) vreinterpretq_s64_s32(x) +#define vreinterpretq_m128i_s64(x) (x) + +#define vreinterpretq_m128i_u8(x) vreinterpretq_s64_u8(x) +#define vreinterpretq_m128i_u16(x) vreinterpretq_s64_u16(x) +#define vreinterpretq_m128i_u32(x) vreinterpretq_s64_u32(x) +#define vreinterpretq_m128i_u64(x) vreinterpretq_s64_u64(x) + +#define vreinterpretq_s8_m128i(x) vreinterpretq_s8_s64(x) +#define vreinterpretq_s16_m128i(x) vreinterpretq_s16_s64(x) +#define vreinterpretq_s32_m128i(x) vreinterpretq_s32_s64(x) +#define vreinterpretq_s64_m128i(x) (x) + +#define vreinterpretq_u8_m128i(x) vreinterpretq_u8_s64(x) +#define vreinterpretq_u16_m128i(x) vreinterpretq_u16_s64(x) +#define vreinterpretq_u32_m128i(x) vreinterpretq_u32_s64(x) +#define vreinterpretq_u64_m128i(x) vreinterpretq_u64_s64(x) + +// A struct is defined in this header file called 'SIMDVec' which can be used +// by applications which attempt to access the contents of an _m128 struct +// directly. It is important to note that accessing the __m128 struct directly +// is bad coding practice by Microsoft: @see: +// https://msdn.microsoft.com/en-us/library/ayeb3ayc.aspx +// +// However, some legacy source code may try to access the contents of an __m128 +// struct directly so the developer can use the SIMDVec as an alias for it. Any +// casting must be done manually by the developer, as you cannot cast or +// otherwise alias the base NEON data type for intrinsic operations. +// +// union intended to allow direct access to an __m128 variable using the names +// that the MSVC compiler provides. This union should really only be used when +// trying to access the members of the vector as integer values. GCC/clang +// allow native access to the float members through a simple array access +// operator (in C since 4.6, in C++ since 4.8). +// +// Ideally direct accesses to SIMD vectors should not be used since it can cause +// a performance hit. If it really is needed however, the original __m128 +// variable can be aliased with a pointer to this union and used to access +// individual components. The use of this union should be hidden behind a macro +// that is used throughout the codebase to access the members instead of always +// declaring this type of variable. +typedef union ALIGN_STRUCT(16) SIMDVec { + float m128_f32[4]; // as floats - do not to use this. Added for convenience. + int8_t m128_i8[16]; // as signed 8-bit integers. + int16_t m128_i16[8]; // as signed 16-bit integers. + int32_t m128_i32[4]; // as signed 32-bit integers. + int64_t m128_i64[2]; // as signed 64-bit integers. + uint8_t m128_u8[16]; // as unsigned 8-bit integers. + uint16_t m128_u16[8]; // as unsigned 16-bit integers. + uint32_t m128_u32[4]; // as unsigned 32-bit integers. + uint64_t m128_u64[2]; // as unsigned 64-bit integers. +} SIMDVec; + +// casting using SIMDVec +#define vreinterpretq_nth_u64_m128i(x, n) (((SIMDVec *) &x)->m128_u64[n]) +#define vreinterpretq_nth_u32_m128i(x, n) (((SIMDVec *) &x)->m128_u32[n]) + + +// ****************************************** +// Backwards compatibility for compilers with lack of specific type support +// ****************************************** + +// Older gcc does not define vld1q_u8_x4 type +#if defined(__GNUC__) && !defined(__clang__) +#if __GNUC__ <= 9 +FORCE_INLINE uint8x16x4_t vld1q_u8_x4(const uint8_t *p) +{ + uint8x16x4_t ret; + ret.val[0] = vld1q_u8(p + 0); + ret.val[1] = vld1q_u8(p + 16); + ret.val[2] = vld1q_u8(p + 32); + ret.val[3] = vld1q_u8(p + 48); + return ret; +} +#endif +#endif + + +// ****************************************** +// Set/get methods +// ****************************************** + +// Loads one cache line of data from address p to a location closer to the +// processor. https://msdn.microsoft.com/en-us/library/84szxsww(v=vs.100).aspx +FORCE_INLINE void _mm_prefetch(const void *p, int i) +{ + (void)i; + __builtin_prefetch(p); +} + +// extracts the lower order floating point value from the parameter : +// https://msdn.microsoft.com/en-us/library/bb514059%28v=vs.120%29.aspx?f=255&MSPPError=-2147217396 +FORCE_INLINE float _mm_cvtss_f32(__m128 a) +{ + return vgetq_lane_f32(vreinterpretq_f32_m128(a), 0); +} + +// Sets the 128-bit value to zero +// https://msdn.microsoft.com/en-us/library/vstudio/ys7dw0kh(v=vs.100).aspx +FORCE_INLINE __m128i _mm_setzero_si128(void) +{ + return vreinterpretq_m128i_s32(vdupq_n_s32(0)); +} + +// Clears the four single-precision, floating-point values. +// https://msdn.microsoft.com/en-us/library/vstudio/tk1t2tbz(v=vs.100).aspx +FORCE_INLINE __m128 _mm_setzero_ps(void) +{ + return vreinterpretq_m128_f32(vdupq_n_f32(0)); +} + +// Sets the four single-precision, floating-point values to w. +// +// r0 := r1 := r2 := r3 := w +// +// https://msdn.microsoft.com/en-us/library/vstudio/2x1se8ha(v=vs.100).aspx +FORCE_INLINE __m128 _mm_set1_ps(float _w) +{ + return vreinterpretq_m128_f32(vdupq_n_f32(_w)); +} + +// Sets the four single-precision, floating-point values to w. +// https://msdn.microsoft.com/en-us/library/vstudio/2x1se8ha(v=vs.100).aspx +FORCE_INLINE __m128 _mm_set_ps1(float _w) +{ + return vreinterpretq_m128_f32(vdupq_n_f32(_w)); +} + +// Sets the four single-precision, floating-point values to the four inputs. +// https://msdn.microsoft.com/en-us/library/vstudio/afh0zf75(v=vs.100).aspx +FORCE_INLINE __m128 _mm_set_ps(float w, float z, float y, float x) +{ + float __attribute__((aligned(16))) data[4] = {x, y, z, w}; + return vreinterpretq_m128_f32(vld1q_f32(data)); +} + +// Sets the four single-precision, floating-point values to the four inputs in +// reverse order. +// https://msdn.microsoft.com/en-us/library/vstudio/d2172ct3(v=vs.100).aspx +FORCE_INLINE __m128 _mm_setr_ps(float w, float z, float y, float x) +{ + float __attribute__((aligned(16))) data[4] = {w, z, y, x}; + return vreinterpretq_m128_f32(vld1q_f32(data)); +} + +// Sets the 8 signed 16-bit integer values in reverse order. +// +// Return Value +// r0 := w0 +// r1 := w1 +// ... +// r7 := w7 +FORCE_INLINE __m128i _mm_setr_epi16(short w0, + short w1, + short w2, + short w3, + short w4, + short w5, + short w6, + short w7) +{ + int16_t __attribute__((aligned(16))) + data[8] = {w0, w1, w2, w3, w4, w5, w6, w7}; + return vreinterpretq_m128i_s16(vld1q_s16((int16_t *) data)); +} + +// Sets the 4 signed 32-bit integer values in reverse order +// https://technet.microsoft.com/en-us/library/security/27yb3ee5(v=vs.90).aspx +FORCE_INLINE __m128i _mm_setr_epi32(int i3, int i2, int i1, int i0) +{ + int32_t __attribute__((aligned(16))) data[4] = {i3, i2, i1, i0}; + return vreinterpretq_m128i_s32(vld1q_s32(data)); +} + +// Sets the 16 signed 8-bit integer values to b. +// +// r0 := b +// r1 := b +// ... +// r15 := b +// +// https://msdn.microsoft.com/en-us/library/6e14xhyf(v=vs.100).aspx +FORCE_INLINE __m128i _mm_set1_epi8(signed char w) +{ + return vreinterpretq_m128i_s8(vdupq_n_s8(w)); +} + +// Sets the 8 signed 16-bit integer values to w. +// +// r0 := w +// r1 := w +// ... +// r7 := w +// +// https://msdn.microsoft.com/en-us/library/k0ya3x0e(v=vs.90).aspx +FORCE_INLINE __m128i _mm_set1_epi16(short w) +{ + return vreinterpretq_m128i_s16(vdupq_n_s16(w)); +} + +// Sets the 16 signed 8-bit integer values. +// https://msdn.microsoft.com/en-us/library/x0cx8zd3(v=vs.90).aspx +FORCE_INLINE __m128i _mm_set_epi8(signed char b15, + signed char b14, + signed char b13, + signed char b12, + signed char b11, + signed char b10, + signed char b9, + signed char b8, + signed char b7, + signed char b6, + signed char b5, + signed char b4, + signed char b3, + signed char b2, + signed char b1, + signed char b0) +{ + int8_t __attribute__((aligned(16))) + data[16] = {(int8_t) b0, (int8_t) b1, (int8_t) b2, (int8_t) b3, + (int8_t) b4, (int8_t) b5, (int8_t) b6, (int8_t) b7, + (int8_t) b8, (int8_t) b9, (int8_t) b10, (int8_t) b11, + (int8_t) b12, (int8_t) b13, (int8_t) b14, (int8_t) b15}; + return (__m128i) vld1q_s8(data); +} + +// Sets the 8 signed 16-bit integer values. +// https://msdn.microsoft.com/en-au/library/3e0fek84(v=vs.90).aspx +FORCE_INLINE __m128i _mm_set_epi16(short i7, + short i6, + short i5, + short i4, + short i3, + short i2, + short i1, + short i0) +{ + int16_t __attribute__((aligned(16))) + data[8] = {i0, i1, i2, i3, i4, i5, i6, i7}; + return vreinterpretq_m128i_s16(vld1q_s16(data)); +} + +// Sets the 16 signed 8-bit integer values in reverse order. +// https://msdn.microsoft.com/en-us/library/2khb9c7k(v=vs.90).aspx +FORCE_INLINE __m128i _mm_setr_epi8(signed char b0, + signed char b1, + signed char b2, + signed char b3, + signed char b4, + signed char b5, + signed char b6, + signed char b7, + signed char b8, + signed char b9, + signed char b10, + signed char b11, + signed char b12, + signed char b13, + signed char b14, + signed char b15) +{ + int8_t __attribute__((aligned(16))) + data[16] = {(int8_t) b0, (int8_t) b1, (int8_t) b2, (int8_t) b3, + (int8_t) b4, (int8_t) b5, (int8_t) b6, (int8_t) b7, + (int8_t) b8, (int8_t) b9, (int8_t) b10, (int8_t) b11, + (int8_t) b12, (int8_t) b13, (int8_t) b14, (int8_t) b15}; + return (__m128i) vld1q_s8(data); +} + +// Sets the 4 signed 32-bit integer values to i. +// +// r0 := i +// r1 := i +// r2 := i +// r3 := I +// +// https://msdn.microsoft.com/en-us/library/vstudio/h4xscxat(v=vs.100).aspx +FORCE_INLINE __m128i _mm_set1_epi32(int _i) +{ + return vreinterpretq_m128i_s32(vdupq_n_s32(_i)); +} + +// Sets the 2 signed 64-bit integer values to i. +// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/whtfzhzk(v=vs.100) +FORCE_INLINE __m128i _mm_set1_epi64(int64_t _i) +{ + return vreinterpretq_m128i_s64(vdupq_n_s64(_i)); +} + +// Sets the 2 signed 64-bit integer values to i. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_set1_epi64x&expand=4961 +FORCE_INLINE __m128i _mm_set1_epi64x(int64_t _i) +{ + return vreinterpretq_m128i_s64(vdupq_n_s64(_i)); +} + +// Sets the 4 signed 32-bit integer values. +// https://msdn.microsoft.com/en-us/library/vstudio/019beekt(v=vs.100).aspx +FORCE_INLINE __m128i _mm_set_epi32(int i3, int i2, int i1, int i0) +{ + int32_t __attribute__((aligned(16))) data[4] = {i0, i1, i2, i3}; + return vreinterpretq_m128i_s32(vld1q_s32(data)); +} + +// Returns the __m128i structure with its two 64-bit integer values +// initialized to the values of the two 64-bit integers passed in. +// https://msdn.microsoft.com/en-us/library/dk2sdw0h(v=vs.120).aspx +FORCE_INLINE __m128i _mm_set_epi64x(int64_t i1, int64_t i2) +{ + int64_t __attribute__((aligned(16))) data[2] = {i2, i1}; + return vreinterpretq_m128i_s64(vld1q_s64(data)); +} + +// Stores four single-precision, floating-point values. +// https://msdn.microsoft.com/en-us/library/vstudio/s3h4ay6y(v=vs.100).aspx +FORCE_INLINE void _mm_store_ps(float *p, __m128 a) +{ + vst1q_f32(p, vreinterpretq_f32_m128(a)); +} + +// Stores four single-precision, floating-point values. +// https://msdn.microsoft.com/en-us/library/44e30x22(v=vs.100).aspx +FORCE_INLINE void _mm_storeu_ps(float *p, __m128 a) +{ + vst1q_f32(p, vreinterpretq_f32_m128(a)); +} + +// Stores four 32-bit integer values as (as a __m128i value) at the address p. +// https://msdn.microsoft.com/en-us/library/vstudio/edk11s13(v=vs.100).aspx +FORCE_INLINE void _mm_store_si128(__m128i *p, __m128i a) +{ + vst1q_s32((int32_t *) p, vreinterpretq_s32_m128i(a)); +} + +// Stores four 32-bit integer values as (as a __m128i value) at the address p. +// https://msdn.microsoft.com/en-us/library/vstudio/edk11s13(v=vs.100).aspx +FORCE_INLINE void _mm_storeu_si128(__m128i *p, __m128i a) +{ + vst1q_s32((int32_t *) p, vreinterpretq_s32_m128i(a)); +} + +// Stores the lower single - precision, floating - point value. +// https://msdn.microsoft.com/en-us/library/tzz10fbx(v=vs.100).aspx +FORCE_INLINE void _mm_store_ss(float *p, __m128 a) +{ + vst1q_lane_f32(p, vreinterpretq_f32_m128(a), 0); +} + +// Reads the lower 64 bits of b and stores them into the lower 64 bits of a. +// https://msdn.microsoft.com/en-us/library/hhwf428f%28v=vs.90%29.aspx +FORCE_INLINE void _mm_storel_epi64(__m128i *a, __m128i b) +{ + uint64x1_t hi = vget_high_u64(vreinterpretq_u64_m128i(*a)); + uint64x1_t lo = vget_low_u64(vreinterpretq_u64_m128i(b)); + *a = vreinterpretq_m128i_u64(vcombine_u64(lo, hi)); +} + +// Stores the lower two single-precision floating point values of a to the +// address p. +// +// *p0 := a0 +// *p1 := a1 +// +// https://msdn.microsoft.com/en-us/library/h54t98ks(v=vs.90).aspx +FORCE_INLINE void _mm_storel_pi(__m64 *p, __m128 a) +{ + *p = vget_low_f32(a); +} + +// Stores the upper two single-precision, floating-point values of a to the +// address p. +// +// *p0 := a2 +// *p1 := a3 +// +// https://msdn.microsoft.com/en-us/library/a7525fs8(v%3dvs.90).aspx +FORCE_INLINE void _mm_storeh_pi(__m64 * p, __m128 a) +{ + *p = vget_high_f32(a); +} + +// Loads a single single-precision, floating-point value, copying it into all +// four words +// https://msdn.microsoft.com/en-us/library/vstudio/5cdkf716(v=vs.100).aspx +FORCE_INLINE __m128 _mm_load1_ps(const float *p) +{ + return vreinterpretq_m128_f32(vld1q_dup_f32(p)); +} +#define _mm_load_ps1 _mm_load1_ps + +// Sets the lower two single-precision, floating-point values with 64 +// bits of data loaded from the address p; the upper two values are passed +// through from a. +// +// Return Value +// r0 := *p0 +// r1 := *p1 +// r2 := a2 +// r3 := a3 +// +// https://msdn.microsoft.com/en-us/library/s57cyak2(v=vs.100).aspx +FORCE_INLINE __m128 _mm_loadl_pi(__m128 a, __m64 const *p) +{ + return vreinterpretq_m128_f32( + vcombine_f32(vld1_f32((const float32_t *) p), vget_high_f32(a))); +} + +// Sets the upper two single-precision, floating-point values with 64 +// bits of data loaded from the address p; the lower two values are passed +// through from a. +// +// r0 := a0 +// r1 := a1 +// r2 := *p0 +// r3 := *p1 +// +// https://msdn.microsoft.com/en-us/library/w92wta0x(v%3dvs.100).aspx +FORCE_INLINE __m128 _mm_loadh_pi(__m128 a, __m64 const *p) +{ + return vreinterpretq_m128_f32( + vcombine_f32(vget_low_f32(a), vld1_f32((const float32_t *) p))); +} + +// Loads four single-precision, floating-point values. +// https://msdn.microsoft.com/en-us/library/vstudio/zzd50xxt(v=vs.100).aspx +FORCE_INLINE __m128 _mm_load_ps(const float *p) +{ + return vreinterpretq_m128_f32(vld1q_f32(p)); +} + +// Loads four single-precision, floating-point values. +// https://msdn.microsoft.com/en-us/library/x1b16s7z%28v=vs.90%29.aspx +FORCE_INLINE __m128 _mm_loadu_ps(const float *p) +{ + // for neon, alignment doesn't matter, so _mm_load_ps and _mm_loadu_ps are + // equivalent for neon + return vreinterpretq_m128_f32(vld1q_f32(p)); +} + +// Loads an single - precision, floating - point value into the low word and +// clears the upper three words. +// https://msdn.microsoft.com/en-us/library/548bb9h4%28v=vs.90%29.aspx +FORCE_INLINE __m128 _mm_load_ss(const float *p) +{ + return vreinterpretq_m128_f32(vsetq_lane_f32(*p, vdupq_n_f32(0), 0)); +} + +FORCE_INLINE __m128i _mm_loadl_epi64(__m128i const *p) +{ + /* Load the lower 64 bits of the value pointed to by p into the + * lower 64 bits of the result, zeroing the upper 64 bits of the result. + */ + return vreinterpretq_m128i_s32(vcombine_s32(vld1_s32((int32_t const *) p), vcreate_s32(0))); +} + +// ****************************************** +// Logic/Binary operations +// ****************************************** + +// Compares for inequality. +// https://msdn.microsoft.com/en-us/library/sf44thbx(v=vs.100).aspx +FORCE_INLINE __m128 _mm_cmpneq_ps(__m128 a, __m128 b) +{ + return vreinterpretq_m128_u32(vmvnq_u32( + vceqq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b)))); +} + +// Computes the bitwise AND-NOT of the four single-precision, floating-point +// values of a and b. +// +// r0 := ~a0 & b0 +// r1 := ~a1 & b1 +// r2 := ~a2 & b2 +// r3 := ~a3 & b3 +// +// https://msdn.microsoft.com/en-us/library/vstudio/68h7wd02(v=vs.100).aspx +FORCE_INLINE __m128 _mm_andnot_ps(__m128 a, __m128 b) +{ + return vreinterpretq_m128_s32( + vbicq_s32(vreinterpretq_s32_m128(b), + vreinterpretq_s32_m128(a))); // *NOTE* argument swap +} + +// Computes the bitwise AND of the 128-bit value in b and the bitwise NOT of the +// 128-bit value in a. +// +// r := (~a) & b +// +// https://msdn.microsoft.com/en-us/library/vstudio/1beaceh8(v=vs.100).aspx +FORCE_INLINE __m128i _mm_andnot_si128(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s32( + vbicq_s32(vreinterpretq_s32_m128i(b), + vreinterpretq_s32_m128i(a))); // *NOTE* argument swap +} + +// Computes the bitwise AND of the 128-bit value in a and the 128-bit value in +// b. +// +// r := a & b +// +// https://msdn.microsoft.com/en-us/library/vstudio/6d1txsa8(v=vs.100).aspx +FORCE_INLINE __m128i _mm_and_si128(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s32( + vandq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b))); +} + +// Computes the bitwise AND of the four single-precision, floating-point values +// of a and b. +// +// r0 := a0 & b0 +// r1 := a1 & b1 +// r2 := a2 & b2 +// r3 := a3 & b3 +// +// https://msdn.microsoft.com/en-us/library/vstudio/73ck1xc5(v=vs.100).aspx +FORCE_INLINE __m128 _mm_and_ps(__m128 a, __m128 b) +{ + return vreinterpretq_m128_s32( + vandq_s32(vreinterpretq_s32_m128(a), vreinterpretq_s32_m128(b))); +} + +// Computes the bitwise OR of the four single-precision, floating-point values +// of a and b. +// https://msdn.microsoft.com/en-us/library/vstudio/7ctdsyy0(v=vs.100).aspx +FORCE_INLINE __m128 _mm_or_ps(__m128 a, __m128 b) +{ + return vreinterpretq_m128_s32( + vorrq_s32(vreinterpretq_s32_m128(a), vreinterpretq_s32_m128(b))); +} + +// Computes bitwise EXOR (exclusive-or) of the four single-precision, +// floating-point values of a and b. +// https://msdn.microsoft.com/en-us/library/ss6k3wk8(v=vs.100).aspx +FORCE_INLINE __m128 _mm_xor_ps(__m128 a, __m128 b) +{ + return vreinterpretq_m128_s32( + veorq_s32(vreinterpretq_s32_m128(a), vreinterpretq_s32_m128(b))); +} + +// Computes the bitwise OR of the 128-bit value in a and the 128-bit value in b. +// +// r := a | b +// +// https://msdn.microsoft.com/en-us/library/vstudio/ew8ty0db(v=vs.100).aspx +FORCE_INLINE __m128i _mm_or_si128(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s32( + vorrq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b))); +} + +// Computes the bitwise XOR of the 128-bit value in a and the 128-bit value in +// b. https://msdn.microsoft.com/en-us/library/fzt08www(v=vs.100).aspx +FORCE_INLINE __m128i _mm_xor_si128(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s32( + veorq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b))); +} + +// Moves the upper two values of B into the lower two values of A. +// +// r3 := a3 +// r2 := a2 +// r1 := b3 +// r0 := b2 +FORCE_INLINE __m128 _mm_movehl_ps(__m128 __A, __m128 __B) +{ + float32x2_t a32 = vget_high_f32(vreinterpretq_f32_m128(__A)); + float32x2_t b32 = vget_high_f32(vreinterpretq_f32_m128(__B)); + return vreinterpretq_m128_f32(vcombine_f32(b32, a32)); +} + +// Moves the lower two values of B into the upper two values of A. +// +// r3 := b1 +// r2 := b0 +// r1 := a1 +// r0 := a0 +FORCE_INLINE __m128 _mm_movelh_ps(__m128 __A, __m128 __B) +{ + float32x2_t a10 = vget_low_f32(vreinterpretq_f32_m128(__A)); + float32x2_t b10 = vget_low_f32(vreinterpretq_f32_m128(__B)); + return vreinterpretq_m128_f32(vcombine_f32(a10, b10)); +} + +FORCE_INLINE __m128i _mm_abs_epi32(__m128i a) +{ + return vreinterpretq_m128i_s32(vabsq_s32(vreinterpretq_s32_m128i(a))); +} + +FORCE_INLINE __m128i _mm_abs_epi16(__m128i a) +{ + return vreinterpretq_m128i_s16(vabsq_s16(vreinterpretq_s16_m128i(a))); +} + +FORCE_INLINE __m128i _mm_abs_epi8(__m128i a) +{ + return vreinterpretq_m128i_s8(vabsq_s8(vreinterpretq_s8_m128i(a))); +} + +// Takes the upper 64 bits of a and places it in the low end of the result +// Takes the lower 64 bits of b and places it into the high end of the result. +FORCE_INLINE __m128 _mm_shuffle_ps_1032(__m128 a, __m128 b) +{ + float32x2_t a32 = vget_high_f32(vreinterpretq_f32_m128(a)); + float32x2_t b10 = vget_low_f32(vreinterpretq_f32_m128(b)); + return vreinterpretq_m128_f32(vcombine_f32(a32, b10)); +} + +// takes the lower two 32-bit values from a and swaps them and places in high +// end of result takes the higher two 32 bit values from b and swaps them and +// places in low end of result. +FORCE_INLINE __m128 _mm_shuffle_ps_2301(__m128 a, __m128 b) +{ + float32x2_t a01 = vrev64_f32(vget_low_f32(vreinterpretq_f32_m128(a))); + float32x2_t b23 = vrev64_f32(vget_high_f32(vreinterpretq_f32_m128(b))); + return vreinterpretq_m128_f32(vcombine_f32(a01, b23)); +} + +FORCE_INLINE __m128 _mm_shuffle_ps_0321(__m128 a, __m128 b) +{ + float32x2_t a21 = vget_high_f32( + vextq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(a), 3)); + float32x2_t b03 = vget_low_f32( + vextq_f32(vreinterpretq_f32_m128(b), vreinterpretq_f32_m128(b), 3)); + return vreinterpretq_m128_f32(vcombine_f32(a21, b03)); +} + +FORCE_INLINE __m128 _mm_shuffle_ps_2103(__m128 a, __m128 b) +{ + float32x2_t a03 = vget_low_f32( + vextq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(a), 3)); + float32x2_t b21 = vget_high_f32( + vextq_f32(vreinterpretq_f32_m128(b), vreinterpretq_f32_m128(b), 3)); + return vreinterpretq_m128_f32(vcombine_f32(a03, b21)); +} + +FORCE_INLINE __m128 _mm_shuffle_ps_1010(__m128 a, __m128 b) +{ + float32x2_t a10 = vget_low_f32(vreinterpretq_f32_m128(a)); + float32x2_t b10 = vget_low_f32(vreinterpretq_f32_m128(b)); + return vreinterpretq_m128_f32(vcombine_f32(a10, b10)); +} + +FORCE_INLINE __m128 _mm_shuffle_ps_1001(__m128 a, __m128 b) +{ + float32x2_t a01 = vrev64_f32(vget_low_f32(vreinterpretq_f32_m128(a))); + float32x2_t b10 = vget_low_f32(vreinterpretq_f32_m128(b)); + return vreinterpretq_m128_f32(vcombine_f32(a01, b10)); +} + +FORCE_INLINE __m128 _mm_shuffle_ps_0101(__m128 a, __m128 b) +{ + float32x2_t a01 = vrev64_f32(vget_low_f32(vreinterpretq_f32_m128(a))); + float32x2_t b01 = vrev64_f32(vget_low_f32(vreinterpretq_f32_m128(b))); + return vreinterpretq_m128_f32(vcombine_f32(a01, b01)); +} + +// keeps the low 64 bits of b in the low and puts the high 64 bits of a in the +// high +FORCE_INLINE __m128 _mm_shuffle_ps_3210(__m128 a, __m128 b) +{ + float32x2_t a10 = vget_low_f32(vreinterpretq_f32_m128(a)); + float32x2_t b32 = vget_high_f32(vreinterpretq_f32_m128(b)); + return vreinterpretq_m128_f32(vcombine_f32(a10, b32)); +} + +FORCE_INLINE __m128 _mm_shuffle_ps_0011(__m128 a, __m128 b) +{ + float32x2_t a11 = vdup_lane_f32(vget_low_f32(vreinterpretq_f32_m128(a)), 1); + float32x2_t b00 = vdup_lane_f32(vget_low_f32(vreinterpretq_f32_m128(b)), 0); + return vreinterpretq_m128_f32(vcombine_f32(a11, b00)); +} + +FORCE_INLINE __m128 _mm_shuffle_ps_0022(__m128 a, __m128 b) +{ + float32x2_t a22 = + vdup_lane_f32(vget_high_f32(vreinterpretq_f32_m128(a)), 0); + float32x2_t b00 = vdup_lane_f32(vget_low_f32(vreinterpretq_f32_m128(b)), 0); + return vreinterpretq_m128_f32(vcombine_f32(a22, b00)); +} + +FORCE_INLINE __m128 _mm_shuffle_ps_2200(__m128 a, __m128 b) +{ + float32x2_t a00 = vdup_lane_f32(vget_low_f32(vreinterpretq_f32_m128(a)), 0); + float32x2_t b22 = + vdup_lane_f32(vget_high_f32(vreinterpretq_f32_m128(b)), 0); + return vreinterpretq_m128_f32(vcombine_f32(a00, b22)); +} + +FORCE_INLINE __m128 _mm_shuffle_ps_3202(__m128 a, __m128 b) +{ + float32_t a0 = vgetq_lane_f32(vreinterpretq_f32_m128(a), 0); + float32x2_t a22 = + vdup_lane_f32(vget_high_f32(vreinterpretq_f32_m128(a)), 0); + float32x2_t a02 = vset_lane_f32(a0, a22, 1); /* TODO: use vzip ?*/ + float32x2_t b32 = vget_high_f32(vreinterpretq_f32_m128(b)); + return vreinterpretq_m128_f32(vcombine_f32(a02, b32)); +} + +FORCE_INLINE __m128 _mm_shuffle_ps_1133(__m128 a, __m128 b) +{ + float32x2_t a33 = + vdup_lane_f32(vget_high_f32(vreinterpretq_f32_m128(a)), 1); + float32x2_t b11 = vdup_lane_f32(vget_low_f32(vreinterpretq_f32_m128(b)), 1); + return vreinterpretq_m128_f32(vcombine_f32(a33, b11)); +} + +FORCE_INLINE __m128 _mm_shuffle_ps_2010(__m128 a, __m128 b) +{ + float32x2_t a10 = vget_low_f32(vreinterpretq_f32_m128(a)); + float32_t b2 = vgetq_lane_f32(vreinterpretq_f32_m128(b), 2); + float32x2_t b00 = vdup_lane_f32(vget_low_f32(vreinterpretq_f32_m128(b)), 0); + float32x2_t b20 = vset_lane_f32(b2, b00, 1); + return vreinterpretq_m128_f32(vcombine_f32(a10, b20)); +} + +FORCE_INLINE __m128 _mm_shuffle_ps_2001(__m128 a, __m128 b) +{ + float32x2_t a01 = vrev64_f32(vget_low_f32(vreinterpretq_f32_m128(a))); + float32_t b2 = vgetq_lane_f32(b, 2); + float32x2_t b00 = vdup_lane_f32(vget_low_f32(vreinterpretq_f32_m128(b)), 0); + float32x2_t b20 = vset_lane_f32(b2, b00, 1); + return vreinterpretq_m128_f32(vcombine_f32(a01, b20)); +} + +FORCE_INLINE __m128 _mm_shuffle_ps_2032(__m128 a, __m128 b) +{ + float32x2_t a32 = vget_high_f32(vreinterpretq_f32_m128(a)); + float32_t b2 = vgetq_lane_f32(b, 2); + float32x2_t b00 = vdup_lane_f32(vget_low_f32(vreinterpretq_f32_m128(b)), 0); + float32x2_t b20 = vset_lane_f32(b2, b00, 1); + return vreinterpretq_m128_f32(vcombine_f32(a32, b20)); +} + +// NEON does not support a general purpose permute intrinsic +// Selects four specific single-precision, floating-point values from a and b, +// based on the mask i. +// https://msdn.microsoft.com/en-us/library/vstudio/5f0858x0(v=vs.100).aspx +#if 0 /* C version */ +FORCE_INLINE __m128 _mm_shuffle_ps_default(__m128 a, + __m128 b, + __constrange(0, 255) int imm) +{ + __m128 ret; + ret[0] = a[imm & 0x3]; + ret[1] = a[(imm >> 2) & 0x3]; + ret[2] = b[(imm >> 4) & 0x03]; + ret[3] = b[(imm >> 6) & 0x03]; + return ret; +} +#endif +#define _mm_shuffle_ps_default(a, b, imm) \ + __extension__({ \ + float32x4_t ret; \ + ret = vmovq_n_f32( \ + vgetq_lane_f32(vreinterpretq_f32_m128(a), (imm) &0x3)); \ + ret = vsetq_lane_f32( \ + vgetq_lane_f32(vreinterpretq_f32_m128(a), ((imm) >> 2) & 0x3), \ + ret, 1); \ + ret = vsetq_lane_f32( \ + vgetq_lane_f32(vreinterpretq_f32_m128(b), ((imm) >> 4) & 0x3), \ + ret, 2); \ + ret = vsetq_lane_f32( \ + vgetq_lane_f32(vreinterpretq_f32_m128(b), ((imm) >> 6) & 0x3), \ + ret, 3); \ + vreinterpretq_m128_f32(ret); \ + }) + +// FORCE_INLINE __m128 _mm_shuffle_ps(__m128 a, __m128 b, __constrange(0,255) +// int imm) +#if defined(__clang__) +#define _mm_shuffle_ps(a, b, imm) \ + __extension__({ \ + float32x4_t _input1 = vreinterpretq_f32_m128(a); \ + float32x4_t _input2 = vreinterpretq_f32_m128(b); \ + float32x4_t _shuf = \ + __builtin_shufflevector(_input1, _input2, \ + (imm) & 0x3, \ + ((imm) >> 2) & 0x3, \ + (((imm) >> 4) & 0x3) + 4, \ + (((imm) >> 6) & 0x3) + 4); \ + vreinterpretq_m128_f32(_shuf); \ + }) +#else // generic +#define _mm_shuffle_ps(a, b, imm) \ + __extension__({ \ + __m128 ret; \ + switch (imm) { \ + case _MM_SHUFFLE(1, 0, 3, 2): \ + ret = _mm_shuffle_ps_1032((a), (b)); \ + break; \ + case _MM_SHUFFLE(2, 3, 0, 1): \ + ret = _mm_shuffle_ps_2301((a), (b)); \ + break; \ + case _MM_SHUFFLE(0, 3, 2, 1): \ + ret = _mm_shuffle_ps_0321((a), (b)); \ + break; \ + case _MM_SHUFFLE(2, 1, 0, 3): \ + ret = _mm_shuffle_ps_2103((a), (b)); \ + break; \ + case _MM_SHUFFLE(1, 0, 1, 0): \ + ret = _mm_movelh_ps((a), (b)); \ + break; \ + case _MM_SHUFFLE(1, 0, 0, 1): \ + ret = _mm_shuffle_ps_1001((a), (b)); \ + break; \ + case _MM_SHUFFLE(0, 1, 0, 1): \ + ret = _mm_shuffle_ps_0101((a), (b)); \ + break; \ + case _MM_SHUFFLE(3, 2, 1, 0): \ + ret = _mm_shuffle_ps_3210((a), (b)); \ + break; \ + case _MM_SHUFFLE(0, 0, 1, 1): \ + ret = _mm_shuffle_ps_0011((a), (b)); \ + break; \ + case _MM_SHUFFLE(0, 0, 2, 2): \ + ret = _mm_shuffle_ps_0022((a), (b)); \ + break; \ + case _MM_SHUFFLE(2, 2, 0, 0): \ + ret = _mm_shuffle_ps_2200((a), (b)); \ + break; \ + case _MM_SHUFFLE(3, 2, 0, 2): \ + ret = _mm_shuffle_ps_3202((a), (b)); \ + break; \ + case _MM_SHUFFLE(3, 2, 3, 2): \ + ret = _mm_movehl_ps((b), (a)); \ + break; \ + case _MM_SHUFFLE(1, 1, 3, 3): \ + ret = _mm_shuffle_ps_1133((a), (b)); \ + break; \ + case _MM_SHUFFLE(2, 0, 1, 0): \ + ret = _mm_shuffle_ps_2010((a), (b)); \ + break; \ + case _MM_SHUFFLE(2, 0, 0, 1): \ + ret = _mm_shuffle_ps_2001((a), (b)); \ + break; \ + case _MM_SHUFFLE(2, 0, 3, 2): \ + ret = _mm_shuffle_ps_2032((a), (b)); \ + break; \ + default: \ + ret = _mm_shuffle_ps_default((a), (b), (imm)); \ + break; \ + } \ + ret; \ + }) +#endif // not clang + +// Takes the upper 64 bits of a and places it in the low end of the result +// Takes the lower 64 bits of a and places it into the high end of the result. +FORCE_INLINE __m128i _mm_shuffle_epi_1032(__m128i a) +{ + int32x2_t a32 = vget_high_s32(vreinterpretq_s32_m128i(a)); + int32x2_t a10 = vget_low_s32(vreinterpretq_s32_m128i(a)); + return vreinterpretq_m128i_s32(vcombine_s32(a32, a10)); +} + +// takes the lower two 32-bit values from a and swaps them and places in low end +// of result takes the higher two 32 bit values from a and swaps them and places +// in high end of result. +FORCE_INLINE __m128i _mm_shuffle_epi_2301(__m128i a) +{ + int32x2_t a01 = vrev64_s32(vget_low_s32(vreinterpretq_s32_m128i(a))); + int32x2_t a23 = vrev64_s32(vget_high_s32(vreinterpretq_s32_m128i(a))); + return vreinterpretq_m128i_s32(vcombine_s32(a01, a23)); +} + +// rotates the least significant 32 bits into the most signficant 32 bits, and +// shifts the rest down +FORCE_INLINE __m128i _mm_shuffle_epi_0321(__m128i a) +{ + return vreinterpretq_m128i_s32( + vextq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(a), 1)); +} + +// rotates the most significant 32 bits into the least signficant 32 bits, and +// shifts the rest up +FORCE_INLINE __m128i _mm_shuffle_epi_2103(__m128i a) +{ + return vreinterpretq_m128i_s32( + vextq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(a), 3)); +} + +// gets the lower 64 bits of a, and places it in the upper 64 bits +// gets the lower 64 bits of a and places it in the lower 64 bits +FORCE_INLINE __m128i _mm_shuffle_epi_1010(__m128i a) +{ + int32x2_t a10 = vget_low_s32(vreinterpretq_s32_m128i(a)); + return vreinterpretq_m128i_s32(vcombine_s32(a10, a10)); +} + +// gets the lower 64 bits of a, swaps the 0 and 1 elements, and places it in the +// lower 64 bits gets the lower 64 bits of a, and places it in the upper 64 bits +FORCE_INLINE __m128i _mm_shuffle_epi_1001(__m128i a) +{ + int32x2_t a01 = vrev64_s32(vget_low_s32(vreinterpretq_s32_m128i(a))); + int32x2_t a10 = vget_low_s32(vreinterpretq_s32_m128i(a)); + return vreinterpretq_m128i_s32(vcombine_s32(a01, a10)); +} + +// gets the lower 64 bits of a, swaps the 0 and 1 elements and places it in the +// upper 64 bits gets the lower 64 bits of a, swaps the 0 and 1 elements, and +// places it in the lower 64 bits +FORCE_INLINE __m128i _mm_shuffle_epi_0101(__m128i a) +{ + int32x2_t a01 = vrev64_s32(vget_low_s32(vreinterpretq_s32_m128i(a))); + return vreinterpretq_m128i_s32(vcombine_s32(a01, a01)); +} + +FORCE_INLINE __m128i _mm_shuffle_epi_2211(__m128i a) +{ + int32x2_t a11 = vdup_lane_s32(vget_low_s32(vreinterpretq_s32_m128i(a)), 1); + int32x2_t a22 = vdup_lane_s32(vget_high_s32(vreinterpretq_s32_m128i(a)), 0); + return vreinterpretq_m128i_s32(vcombine_s32(a11, a22)); +} + +FORCE_INLINE __m128i _mm_shuffle_epi_0122(__m128i a) +{ + int32x2_t a22 = vdup_lane_s32(vget_high_s32(vreinterpretq_s32_m128i(a)), 0); + int32x2_t a01 = vrev64_s32(vget_low_s32(vreinterpretq_s32_m128i(a))); + return vreinterpretq_m128i_s32(vcombine_s32(a22, a01)); +} + +FORCE_INLINE __m128i _mm_shuffle_epi_3332(__m128i a) +{ + int32x2_t a32 = vget_high_s32(vreinterpretq_s32_m128i(a)); + int32x2_t a33 = vdup_lane_s32(vget_high_s32(vreinterpretq_s32_m128i(a)), 1); + return vreinterpretq_m128i_s32(vcombine_s32(a32, a33)); +} + +// Shuffle packed 8-bit integers in a according to shuffle control mask in the +// corresponding 8-bit element of b, and store the results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_shuffle_epi8&expand=5146 +FORCE_INLINE __m128i _mm_shuffle_epi8(__m128i a, __m128i b) +{ + int8x16_t tbl = vreinterpretq_s8_m128i(a); // input a + uint8x16_t idx = vreinterpretq_u8_m128i(b); // input b + uint8x16_t idx_masked = + vandq_u8(idx, vdupq_n_u8(0x8F)); // avoid using meaningless bits +#if defined(__aarch64__) + return vreinterpretq_m128i_s8(vqtbl1q_s8(tbl, idx_masked)); +#elif defined(__GNUC__) + + int8x16_t ret; + // %e and %f represent the even and odd D registers + // respectively. + __asm__( + " vtbl.8 %e[ret], {%e[tbl], %f[tbl]}, %e[idx]\n" + " vtbl.8 %f[ret], {%e[tbl], %f[tbl]}, %f[idx]\n" + : [ret] "=&w" (ret) + : [tbl] "w" (tbl), [idx] "w" (idx_masked)); + return vreinterpretq_m128i_s8(ret); +#else + // use this line if testing on aarch64 + int8x8x2_t a_split = { vget_low_s8(tbl), vget_high_s8(tbl) }; + return vreinterpretq_m128i_s8( + vcombine_s8( + vtbl2_s8(a_split, vget_low_u8(idx_masked)), + vtbl2_s8(a_split, vget_high_u8(idx_masked)) + ) + ); +#endif +} + + +#if 0 /* C version */ +FORCE_INLINE __m128i _mm_shuffle_epi32_default(__m128i a, + __constrange(0, 255) int imm) +{ + __m128i ret; + ret[0] = a[imm & 0x3]; + ret[1] = a[(imm >> 2) & 0x3]; + ret[2] = a[(imm >> 4) & 0x03]; + ret[3] = a[(imm >> 6) & 0x03]; + return ret; +} +#endif +#define _mm_shuffle_epi32_default(a, imm) \ + __extension__({ \ + int32x4_t ret; \ + ret = vmovq_n_s32( \ + vgetq_lane_s32(vreinterpretq_s32_m128i(a), (imm) &0x3)); \ + ret = vsetq_lane_s32( \ + vgetq_lane_s32(vreinterpretq_s32_m128i(a), ((imm) >> 2) & 0x3), \ + ret, 1); \ + ret = vsetq_lane_s32( \ + vgetq_lane_s32(vreinterpretq_s32_m128i(a), ((imm) >> 4) & 0x3), \ + ret, 2); \ + ret = vsetq_lane_s32( \ + vgetq_lane_s32(vreinterpretq_s32_m128i(a), ((imm) >> 6) & 0x3), \ + ret, 3); \ + vreinterpretq_m128i_s32(ret); \ + }) + +// FORCE_INLINE __m128i _mm_shuffle_epi32_splat(__m128i a, __constrange(0,255) +// int imm) +#if defined(__aarch64__) +#define _mm_shuffle_epi32_splat(a, imm) \ + __extension__({ \ + vreinterpretq_m128i_s32( \ + vdupq_laneq_s32(vreinterpretq_s32_m128i(a), (imm))); \ + }) +#else +#define _mm_shuffle_epi32_splat(a, imm) \ + __extension__({ \ + vreinterpretq_m128i_s32( \ + vdupq_n_s32(vgetq_lane_s32(vreinterpretq_s32_m128i(a), (imm)))); \ + }) +#endif + +// Shuffles the 4 signed or unsigned 32-bit integers in a as specified by imm. +// https://msdn.microsoft.com/en-us/library/56f67xbk%28v=vs.90%29.aspx +// FORCE_INLINE __m128i _mm_shuffle_epi32(__m128i a, __constrange(0,255) int +// imm) +#if defined(__clang__) +#define _mm_shuffle_epi32(a, imm) \ + __extension__({ \ + int32x4_t _input = vreinterpretq_s32_m128i(a); \ + int32x4_t _shuf = \ + __builtin_shufflevector(_input, _input, \ + (imm) & 0x3, ((imm) >> 2) & 0x3, \ + ((imm) >> 4) & 0x3, ((imm) >> 6) & 0x3); \ + vreinterpretq_m128i_s32(_shuf); \ + }) +#else // generic +#define _mm_shuffle_epi32(a, imm) \ + __extension__({ \ + __m128i ret; \ + switch (imm) { \ + case _MM_SHUFFLE(1, 0, 3, 2): \ + ret = _mm_shuffle_epi_1032((a)); \ + break; \ + case _MM_SHUFFLE(2, 3, 0, 1): \ + ret = _mm_shuffle_epi_2301((a)); \ + break; \ + case _MM_SHUFFLE(0, 3, 2, 1): \ + ret = _mm_shuffle_epi_0321((a)); \ + break; \ + case _MM_SHUFFLE(2, 1, 0, 3): \ + ret = _mm_shuffle_epi_2103((a)); \ + break; \ + case _MM_SHUFFLE(1, 0, 1, 0): \ + ret = _mm_shuffle_epi_1010((a)); \ + break; \ + case _MM_SHUFFLE(1, 0, 0, 1): \ + ret = _mm_shuffle_epi_1001((a)); \ + break; \ + case _MM_SHUFFLE(0, 1, 0, 1): \ + ret = _mm_shuffle_epi_0101((a)); \ + break; \ + case _MM_SHUFFLE(2, 2, 1, 1): \ + ret = _mm_shuffle_epi_2211((a)); \ + break; \ + case _MM_SHUFFLE(0, 1, 2, 2): \ + ret = _mm_shuffle_epi_0122((a)); \ + break; \ + case _MM_SHUFFLE(3, 3, 3, 2): \ + ret = _mm_shuffle_epi_3332((a)); \ + break; \ + case _MM_SHUFFLE(0, 0, 0, 0): \ + ret = _mm_shuffle_epi32_splat((a), 0); \ + break; \ + case _MM_SHUFFLE(1, 1, 1, 1): \ + ret = _mm_shuffle_epi32_splat((a), 1); \ + break; \ + case _MM_SHUFFLE(2, 2, 2, 2): \ + ret = _mm_shuffle_epi32_splat((a), 2); \ + break; \ + case _MM_SHUFFLE(3, 3, 3, 3): \ + ret = _mm_shuffle_epi32_splat((a), 3); \ + break; \ + default: \ + ret = _mm_shuffle_epi32_default((a), (imm)); \ + break; \ + } \ + ret; \ + }) +#endif // not clang + +// Shuffles the lower 4 signed or unsigned 16-bit integers in a as specified +// by imm. +// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/y41dkk37(v=vs.100) +// FORCE_INLINE __m128i _mm_shufflelo_epi16_function(__m128i a, +// __constrange(0,255) int imm) + +#define _mm_shufflelo_epi16_function(a, imm) \ + __extension__({ \ + int16x8_t ret = vreinterpretq_s16_m128i(a); \ + int16x4_t lowBits = vget_low_s16(ret); \ + ret = vsetq_lane_s16(vget_lane_s16(lowBits, (imm) &0x3), ret, 0); \ + ret = vsetq_lane_s16(vget_lane_s16(lowBits, ((imm) >> 2) & 0x3), ret, \ + 1); \ + ret = vsetq_lane_s16(vget_lane_s16(lowBits, ((imm) >> 4) & 0x3), ret, \ + 2); \ + ret = vsetq_lane_s16(vget_lane_s16(lowBits, ((imm) >> 6) & 0x3), ret, \ + 3); \ + vreinterpretq_m128i_s16(ret); \ + }) + +// FORCE_INLINE __m128i _mm_shufflelo_epi16(__m128i a, __constrange(0,255) int +// imm) +#if defined(__clang__) +#define _mm_shufflelo_epi16(a, imm) \ + __extension__({ \ + int16x8_t _input = vreinterpretq_s16_m128i(a); \ + int16x8_t _shuf = \ + __builtin_shufflevector(_input, _input, \ + ((imm) & 0x3), \ + (((imm) >> 2) & 0x3), \ + (((imm) >> 4) & 0x3), \ + (((imm) >> 6) & 0x3), \ + 4, 5, 6, 7); \ + vreinterpretq_m128i_s16(_shuf); \ + }) +#else // generic +#define _mm_shufflelo_epi16(a, imm) _mm_shufflelo_epi16_function((a), (imm)) +#endif + +// Shuffles the upper 4 signed or unsigned 16-bit integers in a as specified +// by imm. +// https://msdn.microsoft.com/en-us/library/13ywktbs(v=vs.100).aspx +// FORCE_INLINE __m128i _mm_shufflehi_epi16_function(__m128i a, +// __constrange(0,255) int imm) +#define _mm_shufflehi_epi16_function(a, imm) \ + __extension__({ \ + int16x8_t ret = vreinterpretq_s16_m128i(a); \ + int16x4_t highBits = vget_high_s16(ret); \ + ret = vsetq_lane_s16(vget_lane_s16(highBits, (imm) &0x3), ret, 4); \ + ret = vsetq_lane_s16(vget_lane_s16(highBits, ((imm) >> 2) & 0x3), ret, \ + 5); \ + ret = vsetq_lane_s16(vget_lane_s16(highBits, ((imm) >> 4) & 0x3), ret, \ + 6); \ + ret = vsetq_lane_s16(vget_lane_s16(highBits, ((imm) >> 6) & 0x3), ret, \ + 7); \ + vreinterpretq_m128i_s16(ret); \ + }) + +// FORCE_INLINE __m128i _mm_shufflehi_epi16(__m128i a, __constrange(0,255) int +// imm) +#if defined(__clang__) +#define _mm_shufflehi_epi16(a, imm) \ + __extension__({ \ + int16x8_t _input = vreinterpretq_s16_m128i(a); \ + int16x8_t _shuf = \ + __builtin_shufflevector(_input, _input, \ + 0, 1, 2, 3, \ + ((imm) & 0x3) + 4, \ + (((imm) >> 2) & 0x3) + 4, \ + (((imm) >> 4) & 0x3) + 4, \ + (((imm) >> 6) & 0x3) + 4); \ + vreinterpretq_m128i_s16(_shuf); \ + }) +#else // generic +#define _mm_shufflehi_epi16(a, imm) _mm_shufflehi_epi16_function((a), (imm)) +#endif + +// Blend packed 16-bit integers from a and b using control mask imm8, and store +// the results in dst. +// +// FOR j := 0 to 7 +// i := j*16 +// IF imm8[j] +// dst[i+15:i] := b[i+15:i] +// ELSE +// dst[i+15:i] := a[i+15:i] +// FI +// ENDFOR +// FORCE_INLINE __m128i _mm_blend_epi16(__m128i a, __m128i b, __constrange(0,255) +// int imm) +#define _mm_blend_epi16(a, b, imm) \ + __extension__({ \ + const uint16_t _mask[8] = { \ + ((imm) & (1 << 0)) ? 0xFFFF : 0x0000, \ + ((imm) & (1 << 1)) ? 0xFFFF : 0x0000, \ + ((imm) & (1 << 2)) ? 0xFFFF : 0x0000, \ + ((imm) & (1 << 3)) ? 0xFFFF : 0x0000, \ + ((imm) & (1 << 4)) ? 0xFFFF : 0x0000, \ + ((imm) & (1 << 5)) ? 0xFFFF : 0x0000, \ + ((imm) & (1 << 6)) ? 0xFFFF : 0x0000, \ + ((imm) & (1 << 7)) ? 0xFFFF : 0x0000 \ + }; \ + uint16x8_t _mask_vec = vld1q_u16(_mask); \ + uint16x8_t _a = vreinterpretq_u16_m128i(a); \ + uint16x8_t _b = vreinterpretq_u16_m128i(b); \ + vreinterpretq_m128i_u16(vbslq_u16(_mask_vec, _b, _a)); \ + }) + +// Blend packed 8-bit integers from a and b using mask, and store the results in dst. +// +// FOR j := 0 to 15 +// i := j*8 +// IF mask[i+7] +// dst[i+7:i] := b[i+7:i] +// ELSE +// dst[i+7:i] := a[i+7:i] +// FI +// ENDFOR +FORCE_INLINE __m128i _mm_blendv_epi8(__m128i _a, __m128i _b, __m128i _mask) +{ + // Use a signed shift right to create a mask with the sign bit + uint8x16_t mask = vreinterpretq_u8_s8(vshrq_n_s8(vreinterpretq_s8_m128i(_mask), 7)); + uint8x16_t a = vreinterpretq_u8_m128i(_a); + uint8x16_t b = vreinterpretq_u8_m128i(_b); + return vreinterpretq_m128i_u8(vbslq_u8(mask, b, a)); +} + +///////////////////////////////////// +// Shifts +///////////////////////////////////// + +// Shifts the 4 signed 32-bit integers in a right by count bits while shifting +// in the sign bit. +// +// r0 := a0 >> count +// r1 := a1 >> count +// r2 := a2 >> count +// r3 := a3 >> count immediate +FORCE_INLINE __m128i _mm_srai_epi32(__m128i a, int count) +{ + return (__m128i) vshlq_s32((int32x4_t) a, vdupq_n_s32(-count)); +} + +// Shifts the 8 signed 16-bit integers in a right by count bits while shifting +// in the sign bit. +// +// r0 := a0 >> count +// r1 := a1 >> count +// ... +// r7 := a7 >> count +FORCE_INLINE __m128i _mm_srai_epi16(__m128i a, int count) +{ + return (__m128i) vshlq_s16((int16x8_t) a, vdupq_n_s16(-count)); +} + +// Shifts the 8 signed or unsigned 16-bit integers in a left by count bits while +// shifting in zeros. +// +// r0 := a0 << count +// r1 := a1 << count +// ... +// r7 := a7 << count +// +// https://msdn.microsoft.com/en-us/library/es73bcsy(v=vs.90).aspx +#define _mm_slli_epi16(a, imm) \ + __extension__({ \ + __m128i ret; \ + if ((imm) <= 0) { \ + ret = a; \ + } else if ((imm) > 31) { \ + ret = _mm_setzero_si128(); \ + } else { \ + ret = vreinterpretq_m128i_s16( \ + vshlq_n_s16(vreinterpretq_s16_m128i(a), (imm))); \ + } \ + ret; \ + }) + +// Shifts the 4 signed or unsigned 32-bit integers in a left by count bits while +// shifting in zeros. : +// https://msdn.microsoft.com/en-us/library/z2k3bbtb%28v=vs.90%29.aspx +// FORCE_INLINE __m128i _mm_slli_epi32(__m128i a, __constrange(0,255) int imm) +#define _mm_slli_epi32(a, imm) \ + __extension__({ \ + __m128i ret; \ + if ((imm) <= 0) { \ + ret = a; \ + } else if ((imm) > 31) { \ + ret = _mm_setzero_si128(); \ + } else { \ + ret = vreinterpretq_m128i_s32( \ + vshlq_n_s32(vreinterpretq_s32_m128i(a), (imm))); \ + } \ + ret; \ + }) + +// Shift packed 64-bit integers in a left by imm8 while shifting in zeros, and +// store the results in dst. +#define _mm_slli_epi64(a, imm) \ + __extension__({ \ + __m128i ret; \ + if ((imm) <= 0) { \ + ret = a; \ + } else if ((imm) > 63) { \ + ret = _mm_setzero_si128(); \ + } else { \ + ret = vreinterpretq_m128i_s64( \ + vshlq_n_s64(vreinterpretq_s64_m128i(a), (imm))); \ + } \ + ret; \ + }) + +// Shifts the 8 signed or unsigned 16-bit integers in a right by count bits +// while shifting in zeros. +// +// r0 := srl(a0, count) +// r1 := srl(a1, count) +// ... +// r7 := srl(a7, count) +// +// https://msdn.microsoft.com/en-us/library/6tcwd38t(v=vs.90).aspx +#define _mm_srli_epi16(a, imm) \ + __extension__({ \ + __m128i ret; \ + if ((imm) <= 0) { \ + ret = a; \ + } else if ((imm) > 31) { \ + ret = _mm_setzero_si128(); \ + } else { \ + ret = vreinterpretq_m128i_u16( \ + vshrq_n_u16(vreinterpretq_u16_m128i(a), (imm))); \ + } \ + ret; \ + }) + +// Shifts the 4 signed or unsigned 32-bit integers in a right by count bits +// while shifting in zeros. +// https://msdn.microsoft.com/en-us/library/w486zcfa(v=vs.100).aspx FORCE_INLINE +// __m128i _mm_srli_epi32(__m128i a, __constrange(0,255) int imm) +#define _mm_srli_epi32(a, imm) \ + __extension__({ \ + __m128i ret; \ + if ((imm) <= 0) { \ + ret = a; \ + } else if ((imm) > 31) { \ + ret = _mm_setzero_si128(); \ + } else { \ + ret = vreinterpretq_m128i_u32( \ + vshrq_n_u32(vreinterpretq_u32_m128i(a), (imm))); \ + } \ + ret; \ + }) + +// Shift packed 64-bit integers in a right by imm8 while shifting in zeros, and +// store the results in dst. +#define _mm_srli_epi64(a, imm) \ + __extension__({ \ + __m128i ret; \ + if ((imm) <= 0) { \ + ret = a; \ + } else if ((imm) > 63) { \ + ret = _mm_setzero_si128(); \ + } else { \ + ret = vreinterpretq_m128i_u64( \ + vshrq_n_u64(vreinterpretq_u64_m128i(a), (imm))); \ + } \ + ret; \ + }) + +// Shifts the 4 signed 32 - bit integers in a right by count bits while shifting +// in the sign bit. +// https://msdn.microsoft.com/en-us/library/z1939387(v=vs.100).aspx +// FORCE_INLINE __m128i _mm_srai_epi32(__m128i a, __constrange(0,255) int imm) +#define _mm_srai_epi32(a, imm) \ + __extension__({ \ + __m128i ret; \ + if ((imm) <= 0) { \ + ret = a; \ + } else if ((imm) > 31) { \ + ret = vreinterpretq_m128i_s32( \ + vshrq_n_s32(vreinterpretq_s32_m128i(a), 16)); \ + ret = vreinterpretq_m128i_s32( \ + vshrq_n_s32(vreinterpretq_s32_m128i(ret), 16)); \ + } else { \ + ret = vreinterpretq_m128i_s32( \ + vshrq_n_s32(vreinterpretq_s32_m128i(a), (imm))); \ + } \ + ret; \ + }) + +// Shifts the 128 - bit value in a right by imm bytes while shifting in +// zeros.imm must be an immediate. +// +// r := srl(a, imm*8) +// +// https://msdn.microsoft.com/en-us/library/305w28yz(v=vs.100).aspx +// FORCE_INLINE _mm_srli_si128(__m128i a, __constrange(0,255) int imm) +#define _mm_srli_si128(a, imm) \ + __extension__({ \ + __m128i ret; \ + if ((imm) <= 0) { \ + ret = a; \ + } else if ((imm) > 15) { \ + ret = _mm_setzero_si128(); \ + } else { \ + ret = vreinterpretq_m128i_s8( \ + vextq_s8(vreinterpretq_s8_m128i(a), vdupq_n_s8(0), (imm))); \ + } \ + ret; \ + }) + +// Shifts the 128-bit value in a left by imm bytes while shifting in zeros. imm +// must be an immediate. +// +// r := a << (imm * 8) +// +// https://msdn.microsoft.com/en-us/library/34d3k2kt(v=vs.100).aspx +// FORCE_INLINE __m128i _mm_slli_si128(__m128i a, __constrange(0,255) int imm) +#define _mm_slli_si128(a, imm) \ + __extension__({ \ + __m128i ret; \ + if ((imm) <= 0) { \ + ret = a; \ + } else if ((imm) > 15) { \ + ret = _mm_setzero_si128(); \ + } else { \ + ret = vreinterpretq_m128i_s8(vextq_s8( \ + vdupq_n_s8(0), vreinterpretq_s8_m128i(a), 16 - (imm))); \ + } \ + ret; \ + }) + +// Shifts the 8 signed or unsigned 16-bit integers in a left by count bits while +// shifting in zeros. +// +// r0 := a0 << count +// r1 := a1 << count +// ... +// r7 := a7 << count +// +// https://msdn.microsoft.com/en-us/library/c79w388h(v%3dvs.90).aspx +FORCE_INLINE __m128i _mm_sll_epi16(__m128i a, __m128i count) +{ + uint64_t c = ((SIMDVec *) &count)->m128_u64[0]; + if (c > 15) + return _mm_setzero_si128(); + + int16x8_t vc = vdupq_n_s16((int16_t) c); + return vreinterpretq_m128i_s16(vshlq_s16(vreinterpretq_s16_m128i(a), vc)); +} + +// NEON does not provide a version of this function. +// Creates a 16-bit mask from the most significant bits of the 16 signed or +// unsigned 8-bit integers in a and zero extends the upper bits. +// https://msdn.microsoft.com/en-us/library/vstudio/s090c8fk(v=vs.100).aspx +FORCE_INLINE int _mm_movemask_epi8(__m128i a) +{ + // Use increasingly wide shifts+adds to collect the sign bits + // together. + // Since the widening shifts would be rather confusing to follow in little endian, everything + // will be illustrated in big endian order instead. This has a different result - the bits + // would actually be reversed on a big endian machine. + + // Starting input (only half the elements are shown): + // 89 ff 1d c0 00 10 99 33 + uint8x16_t input = vreinterpretq_u8_m128i(a); + + // Shift out everything but the sign bits with an unsigned shift right. + // + // Bytes of the vector:: + // 89 ff 1d c0 00 10 99 33 + // \ \ \ \ \ \ \ \ high_bits = (uint16x4_t)(input >> 7) + // | | | | | | | | + // 01 01 00 01 00 00 01 00 + // + // Bits of first important lane(s): + // 10001001 (89) + // \______ + // | + // 00000001 (01) + uint16x8_t high_bits = vreinterpretq_u16_u8(vshrq_n_u8(input, 7)); + + // Merge the even lanes together with a 16-bit unsigned shift right + add. + // 'xx' represents garbage data which will be ignored in the final result. + // In the important bytes, the add functions like a binary OR. + // + // 01 01 00 01 00 00 01 00 + // \_ | \_ | \_ | \_ | paired16 = (uint32x4_t)(input + (input >> 7)) + // \| \| \| \| + // xx 03 xx 01 xx 00 xx 02 + // + // 00000001 00000001 (01 01) + // \_______ | + // \| + // xxxxxxxx xxxxxx11 (xx 03) + uint32x4_t paired16 = vreinterpretq_u32_u16(vsraq_n_u16(high_bits, high_bits, 7)); + + // Repeat with a wider 32-bit shift + add. + // xx 03 xx 01 xx 00 xx 02 + // \____ | \____ | paired32 = (uint64x1_t)(paired16 + (paired16 >> 14)) + // \| \| + // xx xx xx 0d xx xx xx 02 + // + // 00000011 00000001 (03 01) + // \\_____ || + // '----.\|| + // xxxxxxxx xxxx1101 (xx 0d) + uint64x2_t paired32 = vreinterpretq_u64_u32(vsraq_n_u32(paired16, paired16, 14)); + + // Last, an even wider 64-bit shift + add to get our result in the low 8 bit lanes. + // xx xx xx 0d xx xx xx 02 + // \_________ | paired64 = (uint8x8_t)(paired32 + (paired32 >> 28)) + // \| + // xx xx xx xx xx xx xx d2 + // + // 00001101 00000010 (0d 02) + // \ \___ | | + // '---. \| | + // xxxxxxxx 11010010 (xx d2) + uint8x16_t paired64 = vreinterpretq_u8_u64(vsraq_n_u64(paired32, paired32, 28)); + + // Extract the low 8 bits from each 64-bit lane with 2 8-bit extracts. + // xx xx xx xx xx xx xx d2 + // || return paired64[0] + // d2 + // Note: Little endian would return the correct value 4b (01001011) instead. + return vgetq_lane_u8(paired64, 0) | ((int)vgetq_lane_u8(paired64, 8) << 8); +} + +// NEON does not provide this method +// Creates a 4-bit mask from the most significant bits of the four +// single-precision, floating-point values. +// https://msdn.microsoft.com/en-us/library/vstudio/4490ys29(v=vs.100).aspx +FORCE_INLINE int _mm_movemask_ps(__m128 a) +{ + // Uses the exact same method as _mm_movemask_epi8, see that for details + uint32x4_t input = vreinterpretq_u32_m128(a); + // Shift out everything but the sign bits with a 32-bit unsigned shift right. + uint64x2_t high_bits = vreinterpretq_u64_u32(vshrq_n_u32(input, 31)); + // Merge the two pairs together with a 64-bit unsigned shift right + add. + uint8x16_t paired = vreinterpretq_u8_u64(vsraq_n_u64(high_bits, high_bits, 31)); + // Extract the result. + return vgetq_lane_u8(paired, 0) | (vgetq_lane_u8(paired, 8) << 2); +} + +// Compute the bitwise AND of 128 bits (representing integer data) in a and +// mask, and return 1 if the result is zero, otherwise return 0. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_test_all_zeros&expand=5871 +FORCE_INLINE int _mm_test_all_zeros(__m128i a, __m128i mask) +{ + int64x2_t a_and_mask = + vandq_s64(vreinterpretq_s64_m128i(a), vreinterpretq_s64_m128i(mask)); + return (vgetq_lane_s64(a_and_mask, 0) | vgetq_lane_s64(a_and_mask, 1)) ? 0 + : 1; +} + +// ****************************************** +// Math operations +// ****************************************** + +// Subtracts the four single-precision, floating-point values of a and b. +// +// r0 := a0 - b0 +// r1 := a1 - b1 +// r2 := a2 - b2 +// r3 := a3 - b3 +// +// https://msdn.microsoft.com/en-us/library/vstudio/1zad2k61(v=vs.100).aspx +FORCE_INLINE __m128 _mm_sub_ps(__m128 a, __m128 b) +{ + return vreinterpretq_m128_f32( + vsubq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); +} + +// Subtract 2 packed 64-bit integers in b from 2 packed 64-bit integers in a, +// and store the results in dst. +// r0 := a0 - b0 +// r1 := a1 - b1 +FORCE_INLINE __m128i _mm_sub_epi64(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s64( + vsubq_s64(vreinterpretq_s64_m128i(a), vreinterpretq_s64_m128i(b))); +} + +// Subtracts the 4 signed or unsigned 32-bit integers of b from the 4 signed or +// unsigned 32-bit integers of a. +// +// r0 := a0 - b0 +// r1 := a1 - b1 +// r2 := a2 - b2 +// r3 := a3 - b3 +// +// https://msdn.microsoft.com/en-us/library/vstudio/fhh866h0(v=vs.100).aspx +FORCE_INLINE __m128i _mm_sub_epi32(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s32( + vsubq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b))); +} + +FORCE_INLINE __m128i _mm_sub_epi16(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s16( + vsubq_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b))); +} + +FORCE_INLINE __m128i _mm_sub_epi8(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s8( + vsubq_s8(vreinterpretq_s8_m128i(a), vreinterpretq_s8_m128i(b))); +} + +// Subtracts the 8 unsigned 16-bit integers of bfrom the 8 unsigned 16-bit +// integers of a and saturates.. +// https://technet.microsoft.com/en-us/subscriptions/index/f44y0s19(v=vs.90).aspx +FORCE_INLINE __m128i _mm_subs_epu16(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_u16( + vqsubq_u16(vreinterpretq_u16_m128i(a), vreinterpretq_u16_m128i(b))); +} + +// Subtracts the 16 unsigned 8-bit integers of b from the 16 unsigned 8-bit +// integers of a and saturates. +// +// r0 := UnsignedSaturate(a0 - b0) +// r1 := UnsignedSaturate(a1 - b1) +// ... +// r15 := UnsignedSaturate(a15 - b15) +// +// https://technet.microsoft.com/en-us/subscriptions/yadkxc18(v=vs.90) +FORCE_INLINE __m128i _mm_subs_epu8(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_u8( + vqsubq_u8(vreinterpretq_u8_m128i(a), vreinterpretq_u8_m128i(b))); +} + +// Subtracts the 8 signed 16-bit integers of b from the 8 signed 16-bit integers +// of a and saturates. +// +// r0 := SignedSaturate(a0 - b0) +// r1 := SignedSaturate(a1 - b1) +// ... +// r7 := SignedSaturate(a7 - b7) +FORCE_INLINE __m128i _mm_subs_epi16(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s16( + vqsubq_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b))); +} + +FORCE_INLINE __m128i _mm_adds_epu16(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_u16( + vqaddq_u16(vreinterpretq_u16_m128i(a), vreinterpretq_u16_m128i(b))); +} + +// Negate packed 8-bit integers in a when the corresponding signed +// 8-bit integer in b is negative, and store the results in dst. +// Element in dst are zeroed out when the corresponding element +// in b is zero. +// +// for i in 0..15 +// if b[i] < 0 +// r[i] := -a[i] +// else if b[i] == 0 +// r[i] := 0 +// else +// r[i] := a[i] +// fi +// done +FORCE_INLINE __m128i _mm_sign_epi8(__m128i _a, __m128i _b) +{ + int8x16_t a = vreinterpretq_s8_m128i(_a); + int8x16_t b = vreinterpretq_s8_m128i(_b); + + int8x16_t zero = vdupq_n_s8(0); + // signed shift right: faster than vclt + // (b < 0) ? 0xFF : 0 + uint8x16_t ltMask = vreinterpretq_u8_s8(vshrq_n_s8(b, 7)); + // (b == 0) ? 0xFF : 0 + int8x16_t zeroMask = vreinterpretq_s8_u8(vceqq_s8(b, zero)); + // -a + int8x16_t neg = vnegq_s8(a); + // bitwise select either a or neg based on ltMask + int8x16_t masked = vbslq_s8(ltMask, a, neg); + // res = masked & (~zeroMask) + int8x16_t res = vbicq_s8(masked, zeroMask); + return vreinterpretq_m128i_s8(res); +} + +// Negate packed 16-bit integers in a when the corresponding signed +// 16-bit integer in b is negative, and store the results in dst. +// Element in dst are zeroed out when the corresponding element +// in b is zero. +// +// for i in 0..7 +// if b[i] < 0 +// r[i] := -a[i] +// else if b[i] == 0 +// r[i] := 0 +// else +// r[i] := a[i] +// fi +// done +FORCE_INLINE __m128i _mm_sign_epi16(__m128i _a, __m128i _b) +{ + int16x8_t a = vreinterpretq_s16_m128i(_a); + int16x8_t b = vreinterpretq_s16_m128i(_b); + + int16x8_t zero = vdupq_n_s16(0); + // signed shift right: faster than vclt + // (b < 0) ? 0xFFFF : 0 + uint16x8_t ltMask = vreinterpretq_u16_s16(vshrq_n_s16(b, 15)); + // (b == 0) ? 0xFFFF : 0 + int16x8_t zeroMask = vreinterpretq_s16_u16(vceqq_s16(b, zero)); + // -a + int16x8_t neg = vnegq_s16(a); + // bitwise select either a or neg based on ltMask + int16x8_t masked = vbslq_s16(ltMask, a, neg); + // res = masked & (~zeroMask) + int16x8_t res = vbicq_s16(masked, zeroMask); + return vreinterpretq_m128i_s16(res); +} + +// Negate packed 32-bit integers in a when the corresponding signed +// 32-bit integer in b is negative, and store the results in dst. +// Element in dst are zeroed out when the corresponding element +// in b is zero. +// +// for i in 0..3 +// if b[i] < 0 +// r[i] := -a[i] +// else if b[i] == 0 +// r[i] := 0 +// else +// r[i] := a[i] +// fi +// done +FORCE_INLINE __m128i _mm_sign_epi32(__m128i _a, __m128i _b) +{ + int32x4_t a = vreinterpretq_s32_m128i(_a); + int32x4_t b = vreinterpretq_s32_m128i(_b); + + int32x4_t zero = vdupq_n_s32(0); + // signed shift right: faster than vclt + // (b < 0) ? 0xFFFFFFFF : 0 + uint32x4_t ltMask = vreinterpretq_u32_s32(vshrq_n_s32(b, 31)); + // (b == 0) ? 0xFFFFFFFF : 0 + int32x4_t zeroMask = vreinterpretq_s32_u32(vceqq_s32(b, zero)); + // neg = -a + int32x4_t neg = vnegq_s32(a); + // bitwise select either a or neg based on ltMask + int32x4_t masked = vbslq_s32(ltMask, a, neg); + // res = masked & (~zeroMask) + int32x4_t res = vbicq_s32(masked, zeroMask); + return vreinterpretq_m128i_s32(res); +} + +// Computes the average of the 16 unsigned 8-bit integers in a and the 16 +// unsigned 8-bit integers in b and rounds. +// +// r0 := (a0 + b0) / 2 +// r1 := (a1 + b1) / 2 +// ... +// r15 := (a15 + b15) / 2 +// +// https://msdn.microsoft.com/en-us/library/vstudio/8zwh554a(v%3dvs.90).aspx +FORCE_INLINE __m128i _mm_avg_epu8(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_u8( + vrhaddq_u8(vreinterpretq_u8_m128i(a), vreinterpretq_u8_m128i(b))); +} + +// Computes the average of the 8 unsigned 16-bit integers in a and the 8 +// unsigned 16-bit integers in b and rounds. +// +// r0 := (a0 + b0) / 2 +// r1 := (a1 + b1) / 2 +// ... +// r7 := (a7 + b7) / 2 +// +// https://msdn.microsoft.com/en-us/library/vstudio/y13ca3c8(v=vs.90).aspx +FORCE_INLINE __m128i _mm_avg_epu16(__m128i a, __m128i b) +{ + return (__m128i) vrhaddq_u16(vreinterpretq_u16_m128i(a), + vreinterpretq_u16_m128i(b)); +} + +// Adds the four single-precision, floating-point values of a and b. +// +// r0 := a0 + b0 +// r1 := a1 + b1 +// r2 := a2 + b2 +// r3 := a3 + b3 +// +// https://msdn.microsoft.com/en-us/library/vstudio/c9848chc(v=vs.100).aspx +FORCE_INLINE __m128 _mm_add_ps(__m128 a, __m128 b) +{ + return vreinterpretq_m128_f32( + vaddq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); +} + +// adds the scalar single-precision floating point values of a and b. +// https://msdn.microsoft.com/en-us/library/be94x2y6(v=vs.100).aspx +FORCE_INLINE __m128 _mm_add_ss(__m128 a, __m128 b) +{ + float32_t b0 = vgetq_lane_f32(vreinterpretq_f32_m128(b), 0); + float32x4_t value = vsetq_lane_f32(b0, vdupq_n_f32(0), 0); + // the upper values in the result must be the remnants of . + return vreinterpretq_m128_f32(vaddq_f32(a, value)); +} + +// Adds the 4 signed or unsigned 64-bit integers in a to the 4 signed or +// unsigned 32-bit integers in b. +// https://msdn.microsoft.com/en-us/library/vstudio/09xs4fkk(v=vs.100).aspx +FORCE_INLINE __m128i _mm_add_epi64(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s64( + vaddq_s64(vreinterpretq_s64_m128i(a), vreinterpretq_s64_m128i(b))); +} + +// Adds the 4 signed or unsigned 32-bit integers in a to the 4 signed or +// unsigned 32-bit integers in b. +// +// r0 := a0 + b0 +// r1 := a1 + b1 +// r2 := a2 + b2 +// r3 := a3 + b3 +// +// https://msdn.microsoft.com/en-us/library/vstudio/09xs4fkk(v=vs.100).aspx +FORCE_INLINE __m128i _mm_add_epi32(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s32( + vaddq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b))); +} + +// Adds the 8 signed or unsigned 16-bit integers in a to the 8 signed or +// unsigned 16-bit integers in b. +// https://msdn.microsoft.com/en-us/library/fceha5k4(v=vs.100).aspx +FORCE_INLINE __m128i _mm_add_epi16(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s16( + vaddq_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b))); +} + +// Adds the 16 signed or unsigned 8-bit integers in a to the 16 signed or +// unsigned 8-bit integers in b. +// https://technet.microsoft.com/en-us/subscriptions/yc7tcyzs(v=vs.90) +FORCE_INLINE __m128i _mm_add_epi8(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s8( + vaddq_s8(vreinterpretq_s8_m128i(a), vreinterpretq_s8_m128i(b))); +} + +// Adds the 8 signed 16-bit integers in a to the 8 signed 16-bit integers in b +// and saturates. +// +// r0 := SignedSaturate(a0 + b0) +// r1 := SignedSaturate(a1 + b1) +// ... +// r7 := SignedSaturate(a7 + b7) +// +// https://msdn.microsoft.com/en-us/library/1a306ef8(v=vs.100).aspx +FORCE_INLINE __m128i _mm_adds_epi16(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s16( + vqaddq_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b))); +} + +// Adds the 16 unsigned 8-bit integers in a to the 16 unsigned 8-bit integers in +// b and saturates.. +// https://msdn.microsoft.com/en-us/library/9hahyddy(v=vs.100).aspx +FORCE_INLINE __m128i _mm_adds_epu8(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_u8( + vqaddq_u8(vreinterpretq_u8_m128i(a), vreinterpretq_u8_m128i(b))); +} + +// Multiplies the 8 signed or unsigned 16-bit integers from a by the 8 signed or +// unsigned 16-bit integers from b. +// +// r0 := (a0 * b0)[15:0] +// r1 := (a1 * b1)[15:0] +// ... +// r7 := (a7 * b7)[15:0] +// +// https://msdn.microsoft.com/en-us/library/vstudio/9ks1472s(v=vs.100).aspx +FORCE_INLINE __m128i _mm_mullo_epi16(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s16( + vmulq_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b))); +} + +// Multiplies the 4 signed or unsigned 32-bit integers from a by the 4 signed or +// unsigned 32-bit integers from b. +// https://msdn.microsoft.com/en-us/library/vstudio/bb531409(v=vs.100).aspx +FORCE_INLINE __m128i _mm_mullo_epi32(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s32( + vmulq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b))); +} + +// Multiplies the four single-precision, floating-point values of a and b. +// +// r0 := a0 * b0 +// r1 := a1 * b1 +// r2 := a2 * b2 +// r3 := a3 * b3 +// +// https://msdn.microsoft.com/en-us/library/vstudio/22kbk6t9(v=vs.100).aspx +FORCE_INLINE __m128 _mm_mul_ps(__m128 a, __m128 b) +{ + return vreinterpretq_m128_f32( + vmulq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); +} + +// Multiply the low unsigned 32-bit integers from each packed 64-bit element in +// a and b, and store the unsigned 64-bit results in dst. +// +// r0 := (a0 & 0xFFFFFFFF) * (b0 & 0xFFFFFFFF) +// r1 := (a2 & 0xFFFFFFFF) * (b2 & 0xFFFFFFFF) +FORCE_INLINE __m128i _mm_mul_epu32(__m128i a, __m128i b) +{ + // vmull_u32 upcasts instead of masking, so we downcast. + uint32x2_t a_lo = vmovn_u64(vreinterpretq_u64_m128i(a)); + uint32x2_t b_lo = vmovn_u64(vreinterpretq_u64_m128i(b)); + return vreinterpretq_m128i_u64(vmull_u32(a_lo, b_lo)); +} + +// Multiply the low signed 32-bit integers from each packed 64-bit element in +// a and b, and store the signed 64-bit results in dst. +// +// r0 := (int64_t)(int32_t)a0 * (int64_t)(int32_t)b0 +// r1 := (int64_t)(int32_t)a2 * (int64_t)(int32_t)b2 +FORCE_INLINE __m128i _mm_mul_epi32(__m128i a, __m128i b) +{ + // vmull_s32 upcasts instead of masking, so we downcast. + int32x2_t a_lo = vmovn_s64(vreinterpretq_s64_m128i(a)); + int32x2_t b_lo = vmovn_s64(vreinterpretq_s64_m128i(b)); + return vreinterpretq_m128i_s64(vmull_s32(a_lo, b_lo)); +} + +// Multiplies the 8 signed 16-bit integers from a by the 8 signed 16-bit +// integers from b. +// +// r0 := (a0 * b0) + (a1 * b1) +// r1 := (a2 * b2) + (a3 * b3) +// r2 := (a4 * b4) + (a5 * b5) +// r3 := (a6 * b6) + (a7 * b7) +// https://msdn.microsoft.com/en-us/library/yht36sa6(v=vs.90).aspx +FORCE_INLINE __m128i _mm_madd_epi16(__m128i a, __m128i b) +{ + int32x4_t low = vmull_s16(vget_low_s16(vreinterpretq_s16_m128i(a)), + vget_low_s16(vreinterpretq_s16_m128i(b))); + int32x4_t high = vmull_s16(vget_high_s16(vreinterpretq_s16_m128i(a)), + vget_high_s16(vreinterpretq_s16_m128i(b))); + + int32x2_t low_sum = vpadd_s32(vget_low_s32(low), vget_high_s32(low)); + int32x2_t high_sum = vpadd_s32(vget_low_s32(high), vget_high_s32(high)); + + return vreinterpretq_m128i_s32(vcombine_s32(low_sum, high_sum)); +} + +// Multiply packed signed 16-bit integers in a and b, producing intermediate signed +// 32-bit integers. Shift right by 15 bits while rounding up, and store the +// packed 16-bit integers in dst. +// +// r0 := Round(((int32_t)a0 * (int32_t)b0) >> 15) +// r1 := Round(((int32_t)a1 * (int32_t)b1) >> 15) +// r2 := Round(((int32_t)a2 * (int32_t)b2) >> 15) +// ... +// r7 := Round(((int32_t)a7 * (int32_t)b7) >> 15) +FORCE_INLINE __m128i _mm_mulhrs_epi16(__m128i a, __m128i b) +{ + // Has issues due to saturation + // return vreinterpretq_m128i_s16(vqrdmulhq_s16(a, b)); + + // Multiply + int32x4_t mul_lo = vmull_s16(vget_low_s16(vreinterpretq_s16_m128i(a)), + vget_low_s16(vreinterpretq_s16_m128i(b))); + int32x4_t mul_hi = vmull_s16(vget_high_s16(vreinterpretq_s16_m128i(a)), + vget_high_s16(vreinterpretq_s16_m128i(b))); + + // Rounding narrowing shift right + // narrow = (int16_t)((mul + 16384) >> 15); + int16x4_t narrow_lo = vrshrn_n_s32(mul_lo, 15); + int16x4_t narrow_hi = vrshrn_n_s32(mul_hi, 15); + + // Join together + return vreinterpretq_m128i_s16(vcombine_s16(narrow_lo, narrow_hi)); +} + +// Vertically multiply each unsigned 8-bit integer from a with the corresponding +// signed 8-bit integer from b, producing intermediate signed 16-bit integers. +// Horizontally add adjacent pairs of intermediate signed 16-bit integers, +// and pack the saturated results in dst. +// +// FOR j := 0 to 7 +// i := j*16 +// dst[i+15:i] := Saturate_To_Int16( a[i+15:i+8]*b[i+15:i+8] + a[i+7:i]*b[i+7:i] ) +// ENDFOR +FORCE_INLINE __m128i _mm_maddubs_epi16(__m128i _a, __m128i _b) +{ + // This would be much simpler if x86 would choose to zero extend OR sign extend, + // not both. + // This could probably be optimized better. + uint16x8_t a = vreinterpretq_u16_m128i(_a); + int16x8_t b = vreinterpretq_s16_m128i(_b); + + // Zero extend a + int16x8_t a_odd = vreinterpretq_s16_u16(vshrq_n_u16(a, 8)); + int16x8_t a_even = vreinterpretq_s16_u16(vbicq_u16(a, vdupq_n_u16(0xff00))); + + // Sign extend by shifting left then shifting right. + int16x8_t b_even = vshrq_n_s16(vshlq_n_s16(b, 8), 8); + int16x8_t b_odd = vshrq_n_s16(b, 8); + + // multiply + int16x8_t prod1 = vmulq_s16(a_even, b_even); + int16x8_t prod2 = vmulq_s16(a_odd, b_odd); + + // saturated add + return vreinterpretq_m128i_s16(vqaddq_s16(prod1, prod2)); +} + +// Computes the absolute difference of the 16 unsigned 8-bit integers from a +// and the 16 unsigned 8-bit integers from b. +// +// Return Value +// Sums the upper 8 differences and lower 8 differences and packs the +// resulting 2 unsigned 16-bit integers into the upper and lower 64-bit +// elements. +// +// r0 := abs(a0 - b0) + abs(a1 - b1) +...+ abs(a7 - b7) +// r1 := 0x0 +// r2 := 0x0 +// r3 := 0x0 +// r4 := abs(a8 - b8) + abs(a9 - b9) +...+ abs(a15 - b15) +// r5 := 0x0 +// r6 := 0x0 +// r7 := 0x0 +FORCE_INLINE __m128i _mm_sad_epu8(__m128i a, __m128i b) +{ + uint16x8_t t = vpaddlq_u8(vabdq_u8((uint8x16_t) a, (uint8x16_t) b)); + uint16_t r0 = t[0] + t[1] + t[2] + t[3]; + uint16_t r4 = t[4] + t[5] + t[6] + t[7]; + uint16x8_t r = vsetq_lane_u16(r0, vdupq_n_u16(0), 0); + return (__m128i) vsetq_lane_u16(r4, r, 4); +} + +// Divides the four single-precision, floating-point values of a and b. +// +// r0 := a0 / b0 +// r1 := a1 / b1 +// r2 := a2 / b2 +// r3 := a3 / b3 +// +// https://msdn.microsoft.com/en-us/library/edaw8147(v=vs.100).aspx +FORCE_INLINE __m128 _mm_div_ps(__m128 a, __m128 b) +{ + float32x4_t recip0 = vrecpeq_f32(vreinterpretq_f32_m128(b)); + float32x4_t recip1 = + vmulq_f32(recip0, vrecpsq_f32(recip0, vreinterpretq_f32_m128(b))); + return vreinterpretq_m128_f32(vmulq_f32(vreinterpretq_f32_m128(a), recip1)); +} + +// Divides the scalar single-precision floating point value of a by b. +// https://msdn.microsoft.com/en-us/library/4y73xa49(v=vs.100).aspx +FORCE_INLINE __m128 _mm_div_ss(__m128 a, __m128 b) +{ + float32_t value = + vgetq_lane_f32(vreinterpretq_f32_m128(_mm_div_ps(a, b)), 0); + return vreinterpretq_m128_f32( + vsetq_lane_f32(value, vreinterpretq_f32_m128(a), 0)); +} + +// This version does additional iterations to improve accuracy. Between 1 and 4 +// recommended. Computes the approximations of reciprocals of the four +// single-precision, floating-point values of a. +// https://msdn.microsoft.com/en-us/library/vstudio/796k1tty(v=vs.100).aspx +FORCE_INLINE __m128 recipq_newton(__m128 in, int n) +{ + int i; + float32x4_t recip = vrecpeq_f32(vreinterpretq_f32_m128(in)); + for (i = 0; i < n; ++i) { + recip = + vmulq_f32(recip, vrecpsq_f32(recip, vreinterpretq_f32_m128(in))); + } + return vreinterpretq_m128_f32(recip); +} + +// Computes the approximations of reciprocals of the four single-precision, +// floating-point values of a. +// https://msdn.microsoft.com/en-us/library/vstudio/796k1tty(v=vs.100).aspx +FORCE_INLINE __m128 _mm_rcp_ps(__m128 in) +{ + float32x4_t recip = vrecpeq_f32(vreinterpretq_f32_m128(in)); + recip = vmulq_f32(recip, vrecpsq_f32(recip, vreinterpretq_f32_m128(in))); + return vreinterpretq_m128_f32(recip); +} + +// Computes the approximations of square roots of the four single-precision, +// floating-point values of a. First computes reciprocal square roots and then +// reciprocals of the four values. +// +// r0 := sqrt(a0) +// r1 := sqrt(a1) +// r2 := sqrt(a2) +// r3 := sqrt(a3) +// +// https://msdn.microsoft.com/en-us/library/vstudio/8z67bwwk(v=vs.100).aspx +FORCE_INLINE __m128 _mm_sqrt_ps(__m128 in) +{ + float32x4_t recipsq = vrsqrteq_f32(vreinterpretq_f32_m128(in)); + float32x4_t sq = vrecpeq_f32(recipsq); + // ??? use step versions of both sqrt and recip for better accuracy? + return vreinterpretq_m128_f32(sq); +} + +// Computes the approximation of the square root of the scalar single-precision +// floating point value of in. +// https://msdn.microsoft.com/en-us/library/ahfsc22d(v=vs.100).aspx +FORCE_INLINE __m128 _mm_sqrt_ss(__m128 in) +{ + float32_t value = + vgetq_lane_f32(vreinterpretq_f32_m128(_mm_sqrt_ps(in)), 0); + return vreinterpretq_m128_f32( + vsetq_lane_f32(value, vreinterpretq_f32_m128(in), 0)); +} + +// Computes the approximations of the reciprocal square roots of the four +// single-precision floating point values of in. +// https://msdn.microsoft.com/en-us/library/22hfsh53(v=vs.100).aspx +FORCE_INLINE __m128 _mm_rsqrt_ps(__m128 in) +{ + return vreinterpretq_m128_f32(vrsqrteq_f32(vreinterpretq_f32_m128(in))); +} + +// Computes the maximums of the four single-precision, floating-point values of +// a and b. +// https://msdn.microsoft.com/en-us/library/vstudio/ff5d607a(v=vs.100).aspx +FORCE_INLINE __m128 _mm_max_ps(__m128 a, __m128 b) +{ + return vreinterpretq_m128_f32( + vmaxq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); +} + +// Computes the minima of the four single-precision, floating-point values of a +// and b. +// https://msdn.microsoft.com/en-us/library/vstudio/wh13kadz(v=vs.100).aspx +FORCE_INLINE __m128 _mm_min_ps(__m128 a, __m128 b) +{ + return vreinterpretq_m128_f32( + vminq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); +} + +// Computes the maximum of the two lower scalar single-precision floating point +// values of a and b. +// https://msdn.microsoft.com/en-us/library/s6db5esz(v=vs.100).aspx +FORCE_INLINE __m128 _mm_max_ss(__m128 a, __m128 b) +{ + float32_t value = vgetq_lane_f32( + vmaxq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b)), 0); + return vreinterpretq_m128_f32( + vsetq_lane_f32(value, vreinterpretq_f32_m128(a), 0)); +} + +// Computes the minimum of the two lower scalar single-precision floating point +// values of a and b. +// https://msdn.microsoft.com/en-us/library/0a9y7xaa(v=vs.100).aspx +FORCE_INLINE __m128 _mm_min_ss(__m128 a, __m128 b) +{ + float32_t value = vgetq_lane_f32( + vminq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b)), 0); + return vreinterpretq_m128_f32( + vsetq_lane_f32(value, vreinterpretq_f32_m128(a), 0)); +} + +// Computes the pairwise maxima of the 16 unsigned 8-bit integers from a and the +// 16 unsigned 8-bit integers from b. +// https://msdn.microsoft.com/en-us/library/st6634za(v=vs.100).aspx +FORCE_INLINE __m128i _mm_max_epu8(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_u8( + vmaxq_u8(vreinterpretq_u8_m128i(a), vreinterpretq_u8_m128i(b))); +} + +// Computes the pairwise minima of the 16 unsigned 8-bit integers from a and the +// 16 unsigned 8-bit integers from b. +// https://msdn.microsoft.com/ko-kr/library/17k8cf58(v=vs.100).aspxx +FORCE_INLINE __m128i _mm_min_epu8(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_u8( + vminq_u8(vreinterpretq_u8_m128i(a), vreinterpretq_u8_m128i(b))); +} + +// Computes the pairwise minima of the 8 signed 16-bit integers from a and the 8 +// signed 16-bit integers from b. +// https://msdn.microsoft.com/en-us/library/vstudio/6te997ew(v=vs.100).aspx +FORCE_INLINE __m128i _mm_min_epi16(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s16( + vminq_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b))); +} + +// Computes the pairwise maxima of the 8 signed 16-bit integers from a and the 8 +// signed 16-bit integers from b. +// https://msdn.microsoft.com/en-us/LIBRary/3x060h7c(v=vs.100).aspx +FORCE_INLINE __m128i _mm_max_epi16(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s16( + vmaxq_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b))); +} + +// epi versions of min/max +// Computes the pariwise maximums of the four signed 32-bit integer values of a +// and b. +// +// A 128-bit parameter that can be defined with the following equations: +// r0 := (a0 > b0) ? a0 : b0 +// r1 := (a1 > b1) ? a1 : b1 +// r2 := (a2 > b2) ? a2 : b2 +// r3 := (a3 > b3) ? a3 : b3 +// +// https://msdn.microsoft.com/en-us/library/vstudio/bb514055(v=vs.100).aspx +FORCE_INLINE __m128i _mm_max_epi32(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s32( + vmaxq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b))); +} + +// Computes the pariwise minima of the four signed 32-bit integer values of a +// and b. +// +// A 128-bit parameter that can be defined with the following equations: +// r0 := (a0 < b0) ? a0 : b0 +// r1 := (a1 < b1) ? a1 : b1 +// r2 := (a2 < b2) ? a2 : b2 +// r3 := (a3 < b3) ? a3 : b3 +// +// https://msdn.microsoft.com/en-us/library/vstudio/bb531476(v=vs.100).aspx +FORCE_INLINE __m128i _mm_min_epi32(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s32( + vminq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b))); +} + +// Multiplies the 8 signed 16-bit integers from a by the 8 signed 16-bit +// integers from b. +// +// r0 := (a0 * b0)[31:16] +// r1 := (a1 * b1)[31:16] +// ... +// r7 := (a7 * b7)[31:16] +// +// https://msdn.microsoft.com/en-us/library/vstudio/59hddw1d(v=vs.100).aspx +FORCE_INLINE __m128i _mm_mulhi_epi16(__m128i a, __m128i b) +{ + /* FIXME: issue with large values because of result saturation */ + // int16x8_t ret = vqdmulhq_s16(vreinterpretq_s16_m128i(a), + // vreinterpretq_s16_m128i(b)); /* =2*a*b */ return + // vreinterpretq_m128i_s16(vshrq_n_s16(ret, 1)); + int16x4_t a3210 = vget_low_s16(vreinterpretq_s16_m128i(a)); + int16x4_t b3210 = vget_low_s16(vreinterpretq_s16_m128i(b)); + int32x4_t ab3210 = vmull_s16(a3210, b3210); /* 3333222211110000 */ + int16x4_t a7654 = vget_high_s16(vreinterpretq_s16_m128i(a)); + int16x4_t b7654 = vget_high_s16(vreinterpretq_s16_m128i(b)); + int32x4_t ab7654 = vmull_s16(a7654, b7654); /* 7777666655554444 */ + uint16x8x2_t r = + vuzpq_u16(vreinterpretq_u16_s32(ab3210), vreinterpretq_u16_s32(ab7654)); + return vreinterpretq_m128i_u16(r.val[1]); +} + +// Computes pairwise add of each argument as single-precision, floating-point +// values a and b. +// https://msdn.microsoft.com/en-us/library/yd9wecaa.aspx +FORCE_INLINE __m128 _mm_hadd_ps(__m128 a, __m128 b) +{ +#if defined(__aarch64__) + return vreinterpretq_m128_f32(vpaddq_f32( + vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); // AArch64 +#else + float32x2_t a10 = vget_low_f32(vreinterpretq_f32_m128(a)); + float32x2_t a32 = vget_high_f32(vreinterpretq_f32_m128(a)); + float32x2_t b10 = vget_low_f32(vreinterpretq_f32_m128(b)); + float32x2_t b32 = vget_high_f32(vreinterpretq_f32_m128(b)); + return vreinterpretq_m128_f32( + vcombine_f32(vpadd_f32(a10, a32), vpadd_f32(b10, b32))); +#endif +} + +// Computes pairwise add of each argument as a 16-bit signed or unsigned integer +// values a and b. +FORCE_INLINE __m128i _mm_hadd_epi16(__m128i _a, __m128i _b) +{ + int16x8_t a = vreinterpretq_s16_m128i(_a); + int16x8_t b = vreinterpretq_s16_m128i(_b); +#if defined(__aarch64__) + return vreinterpretq_m128i_s16(vpaddq_s16(a, b)); +#else + return vreinterpretq_m128i_s16( + vcombine_s16( + vpadd_s16(vget_low_s16(a), vget_high_s16(a)), + vpadd_s16(vget_low_s16(b), vget_high_s16(b)) + ) + ); +#endif +} + +// Computes pairwise difference of each argument as a 16-bit signed or unsigned integer +// values a and b. +FORCE_INLINE __m128i _mm_hsub_epi16(__m128i _a, __m128i _b) +{ + int32x4_t a = vreinterpretq_s32_m128i(_a); + int32x4_t b = vreinterpretq_s32_m128i(_b); + // Interleave using vshrn/vmovn + // [a0|a2|a4|a6|b0|b2|b4|b6] + // [a1|a3|a5|a7|b1|b3|b5|b7] + int16x8_t ab0246 = vcombine_s16(vmovn_s32(a), vmovn_s32(b)); + int16x8_t ab1357 = vcombine_s16(vshrn_n_s32(a, 16), vshrn_n_s32(b, 16)); + // Subtract + return vreinterpretq_m128i_s16(vsubq_s16(ab0246, ab1357)); +} + +// Computes saturated pairwise sub of each argument as a 16-bit signed +// integer values a and b. +FORCE_INLINE __m128i _mm_hadds_epi16(__m128i _a, __m128i _b) +{ + int32x4_t a = vreinterpretq_s32_m128i(_a); + int32x4_t b = vreinterpretq_s32_m128i(_b); + // Interleave using vshrn/vmovn + // [a0|a2|a4|a6|b0|b2|b4|b6] + // [a1|a3|a5|a7|b1|b3|b5|b7] + int16x8_t ab0246 = vcombine_s16(vmovn_s32(a), vmovn_s32(b)); + int16x8_t ab1357 = vcombine_s16(vshrn_n_s32(a, 16), vshrn_n_s32(b, 16)); + // Saturated add + return vreinterpretq_m128i_s16(vqaddq_s16(ab0246, ab1357)); +} + +// Computes saturated pairwise difference of each argument as a 16-bit signed +// integer values a and b. +FORCE_INLINE __m128i _mm_hsubs_epi16(__m128i _a, __m128i _b) +{ + int32x4_t a = vreinterpretq_s32_m128i(_a); + int32x4_t b = vreinterpretq_s32_m128i(_b); + // Interleave using vshrn/vmovn + // [a0|a2|a4|a6|b0|b2|b4|b6] + // [a1|a3|a5|a7|b1|b3|b5|b7] + int16x8_t ab0246 = vcombine_s16(vmovn_s32(a), vmovn_s32(b)); + int16x8_t ab1357 = vcombine_s16(vshrn_n_s32(a, 16), vshrn_n_s32(b, 16)); + // Saturated subtract + return vreinterpretq_m128i_s16(vqsubq_s16(ab0246, ab1357)); +} + +// Computes pairwise add of each argument as a 32-bit signed or unsigned integer +// values a and b. +FORCE_INLINE __m128i _mm_hadd_epi32(__m128i _a, __m128i _b) +{ + int32x4_t a = vreinterpretq_s32_m128i(_a); + int32x4_t b = vreinterpretq_s32_m128i(_b); + return vreinterpretq_m128i_s32( + vcombine_s32( + vpadd_s32(vget_low_s32(a), vget_high_s32(a)), + vpadd_s32(vget_low_s32(b), vget_high_s32(b)) + ) + ); +} + +// Computes pairwise difference of each argument as a 32-bit signed or unsigned integer +// values a and b. +FORCE_INLINE __m128i _mm_hsub_epi32(__m128i _a, __m128i _b) +{ + int64x2_t a = vreinterpretq_s64_m128i(_a); + int64x2_t b = vreinterpretq_s64_m128i(_b); + // Interleave using vshrn/vmovn + // [a0|a2|b0|b2] + // [a1|a2|b1|b3] + int32x4_t ab02 = vcombine_s32(vmovn_s64(a), vmovn_s64(b)); + int32x4_t ab13 = vcombine_s32(vshrn_n_s64(a, 32), vshrn_n_s64(b, 32)); + // Subtract + return vreinterpretq_m128i_s32(vsubq_s32(ab02, ab13)); +} + +// ****************************************** +// Compare operations +// ****************************************** + +// Compares for less than +// https://msdn.microsoft.com/en-us/library/vstudio/f330yhc8(v=vs.100).aspx +FORCE_INLINE __m128 _mm_cmplt_ps(__m128 a, __m128 b) +{ + return vreinterpretq_m128_u32( + vcltq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); +} + +// Compares for greater than. +// +// r0 := (a0 > b0) ? 0xffffffff : 0x0 +// r1 := (a1 > b1) ? 0xffffffff : 0x0 +// r2 := (a2 > b2) ? 0xffffffff : 0x0 +// r3 := (a3 > b3) ? 0xffffffff : 0x0 +// +// https://msdn.microsoft.com/en-us/library/vstudio/11dy102s(v=vs.100).aspx +FORCE_INLINE __m128 _mm_cmpgt_ps(__m128 a, __m128 b) +{ + return vreinterpretq_m128_u32( + vcgtq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); +} + +// Compares for greater than or equal. +// https://msdn.microsoft.com/en-us/library/vstudio/fs813y2t(v=vs.100).aspx +FORCE_INLINE __m128 _mm_cmpge_ps(__m128 a, __m128 b) +{ + return vreinterpretq_m128_u32( + vcgeq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); +} + +// Compares for less than or equal. +// +// r0 := (a0 <= b0) ? 0xffffffff : 0x0 +// r1 := (a1 <= b1) ? 0xffffffff : 0x0 +// r2 := (a2 <= b2) ? 0xffffffff : 0x0 +// r3 := (a3 <= b3) ? 0xffffffff : 0x0 +// +// https://msdn.microsoft.com/en-us/library/vstudio/1s75w83z(v=vs.100).aspx +FORCE_INLINE __m128 _mm_cmple_ps(__m128 a, __m128 b) +{ + return vreinterpretq_m128_u32( + vcleq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); +} + +// Compares for equality. +// https://msdn.microsoft.com/en-us/library/vstudio/36aectz5(v=vs.100).aspx +FORCE_INLINE __m128 _mm_cmpeq_ps(__m128 a, __m128 b) +{ + return vreinterpretq_m128_u32( + vceqq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); +} + +// Compares the 16 signed or unsigned 8-bit integers in a and the 16 signed or +// unsigned 8-bit integers in b for equality. +// https://msdn.microsoft.com/en-us/library/windows/desktop/bz5xk21a(v=vs.90).aspx +FORCE_INLINE __m128i _mm_cmpeq_epi8(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_u8( + vceqq_s8(vreinterpretq_s8_m128i(a), vreinterpretq_s8_m128i(b))); +} + +// Compares the 8 signed or unsigned 16-bit integers in a and the 8 signed or +// unsigned 16-bit integers in b for equality. +// https://msdn.microsoft.com/en-us/library/2ay060te(v=vs.100).aspx +FORCE_INLINE __m128i _mm_cmpeq_epi16(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_u16( + vceqq_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b))); +} + +// Compare packed 32-bit integers in a and b for equality, and store the results +// in dst +FORCE_INLINE __m128i _mm_cmpeq_epi32(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_u32( + vceqq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b))); +} + +// Compare packed 64-bit integers in a and b for equality, and store the results +// in dst +FORCE_INLINE __m128i _mm_cmpeq_epi64(__m128i a, __m128i b) +{ +#if defined(__aarch64__) + return vreinterpretq_m128i_u64( + vceqq_u64(vreinterpretq_u64_m128i(a), vreinterpretq_u64_m128i(b))); +#else + // ARMv7 lacks vceqq_u64 + // (a == b) -> (a_lo == b_lo) && (a_hi == b_hi) + uint32x4_t cmp = vceqq_u32(vreinterpretq_u32_m128i(a), vreinterpretq_u32_m128i(b)); + uint32x4_t swapped = vrev64q_u32(cmp); + return vreinterpretq_m128i_u32(vandq_u32(cmp, swapped)); +#endif +} + +// Compares the 16 signed 8-bit integers in a and the 16 signed 8-bit integers +// in b for lesser than. +// https://msdn.microsoft.com/en-us/library/windows/desktop/9s46csht(v=vs.90).aspx +FORCE_INLINE __m128i _mm_cmplt_epi8(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_u8( + vcltq_s8(vreinterpretq_s8_m128i(a), vreinterpretq_s8_m128i(b))); +} + +// Compares the 16 signed 8-bit integers in a and the 16 signed 8-bit integers +// in b for greater than. +// +// r0 := (a0 > b0) ? 0xff : 0x0 +// r1 := (a1 > b1) ? 0xff : 0x0 +// ... +// r15 := (a15 > b15) ? 0xff : 0x0 +// +// https://msdn.microsoft.com/zh-tw/library/wf45zt2b(v=vs.100).aspx +FORCE_INLINE __m128i _mm_cmpgt_epi8(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_u8( + vcgtq_s8(vreinterpretq_s8_m128i(a), vreinterpretq_s8_m128i(b))); +} + +// Compares the 8 signed 16-bit integers in a and the 8 signed 16-bit integers +// in b for less than. +// +// r0 := (a0 < b0) ? 0xffff : 0x0 +// r1 := (a1 < b1) ? 0xffff : 0x0 +// ... +// r7 := (a7 < b7) ? 0xffff : 0x0 +// +// https://technet.microsoft.com/en-us/library/t863edb2(v=vs.100).aspx +FORCE_INLINE __m128i _mm_cmplt_epi16(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_u16( + vcltq_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b))); +} + +// Compares the 8 signed 16-bit integers in a and the 8 signed 16-bit integers +// in b for greater than. +// +// r0 := (a0 > b0) ? 0xffff : 0x0 +// r1 := (a1 > b1) ? 0xffff : 0x0 +// ... +// r7 := (a7 > b7) ? 0xffff : 0x0 +// +// https://technet.microsoft.com/en-us/library/xd43yfsa(v=vs.100).aspx +FORCE_INLINE __m128i _mm_cmpgt_epi16(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_u16( + vcgtq_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b))); +} + + +// Compares the 4 signed 32-bit integers in a and the 4 signed 32-bit integers +// in b for less than. +// https://msdn.microsoft.com/en-us/library/vstudio/4ak0bf5d(v=vs.100).aspx +FORCE_INLINE __m128i _mm_cmplt_epi32(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_u32( + vcltq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b))); +} + +// Compares the 4 signed 32-bit integers in a and the 4 signed 32-bit integers +// in b for greater than. +// https://msdn.microsoft.com/en-us/library/vstudio/1s9f2z0y(v=vs.100).aspx +FORCE_INLINE __m128i _mm_cmpgt_epi32(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_u32( + vcgtq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b))); +} + +// Compares the 2 signed 64-bit integers in a and the 2 signed 64-bit integers +// in b for greater than. +FORCE_INLINE __m128i _mm_cmpgt_epi64(__m128i a, __m128i b) +{ +#if defined(__aarch64__) + return vreinterpretq_m128i_u64( + vcgtq_s64(vreinterpretq_s64_m128i(a), vreinterpretq_s64_m128i(b))); +#else + // ARMv7 lacks vcgtq_s64. + // This is based off of Clang's SSE2 polyfill: + // (a > b) -> ((a_hi > b_hi) || (a_lo > b_lo && a_hi == b_hi)) + + // Mask the sign bit out since we need a signed AND an unsigned comparison + // and it is ugly to try and split them. + int32x4_t mask = vreinterpretq_s32_s64(vdupq_n_s64(0x80000000ull)); + int32x4_t a_mask = veorq_s32(vreinterpretq_s32_m128i(a), mask); + int32x4_t b_mask = veorq_s32(vreinterpretq_s32_m128i(b), mask); + // Check if a > b + int64x2_t greater = vreinterpretq_s64_u32(vcgtq_s32(a_mask, b_mask)); + // Copy upper mask to lower mask + // a_hi > b_hi + int64x2_t gt_hi = vshrq_n_s64(greater, 63); + // Copy lower mask to upper mask + // a_lo > b_lo + int64x2_t gt_lo = vsliq_n_s64(greater, greater, 32); + // Compare for equality + int64x2_t equal = vreinterpretq_s64_u32(vceqq_s32(a_mask, b_mask)); + // Copy upper mask to lower mask + // a_hi == b_hi + int64x2_t eq_hi = vshrq_n_s64(equal, 63); + // a_hi > b_hi || (a_lo > b_lo && a_hi == b_hi) + int64x2_t ret = vorrq_s64(gt_hi, vandq_s64(gt_lo, eq_hi)); + return vreinterpretq_m128i_s64(ret); +#endif +} +// Compares the four 32-bit floats in a and b to check if any values are NaN. +// Ordered compare between each value returns true for "orderable" and false for +// "not orderable" (NaN). +// https://msdn.microsoft.com/en-us/library/vstudio/0h9w00fx(v=vs.100).aspx see +// also: +// http://stackoverflow.com/questions/8627331/what-does-ordered-unordered-comparison-mean +// http://stackoverflow.com/questions/29349621/neon-isnanval-intrinsics +FORCE_INLINE __m128 _mm_cmpord_ps(__m128 a, __m128 b) +{ + // Note: NEON does not have ordered compare builtin + // Need to compare a eq a and b eq b to check for NaN + // Do AND of results to get final + uint32x4_t ceqaa = + vceqq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(a)); + uint32x4_t ceqbb = + vceqq_f32(vreinterpretq_f32_m128(b), vreinterpretq_f32_m128(b)); + return vreinterpretq_m128_u32(vandq_u32(ceqaa, ceqbb)); +} + +// Compares the lower single-precision floating point scalar values of a and b +// using a less than operation. : +// https://msdn.microsoft.com/en-us/library/2kwe606b(v=vs.90).aspx Important +// note!! The documentation on MSDN is incorrect! If either of the values is a +// NAN the docs say you will get a one, but in fact, it will return a zero!! +FORCE_INLINE int _mm_comilt_ss(__m128 a, __m128 b) +{ + uint32x4_t a_not_nan = + vceqq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(a)); + uint32x4_t b_not_nan = + vceqq_f32(vreinterpretq_f32_m128(b), vreinterpretq_f32_m128(b)); + uint32x4_t a_and_b_not_nan = vandq_u32(a_not_nan, b_not_nan); + uint32x4_t a_lt_b = + vcltq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b)); + return (vgetq_lane_u32(vandq_u32(a_and_b_not_nan, a_lt_b), 0) != 0) ? 1 : 0; +} + +// Compares the lower single-precision floating point scalar values of a and b +// using a greater than operation. : +// https://msdn.microsoft.com/en-us/library/b0738e0t(v=vs.100).aspx +FORCE_INLINE int _mm_comigt_ss(__m128 a, __m128 b) +{ + // return vgetq_lane_u32(vcgtq_f32(vreinterpretq_f32_m128(a), + // vreinterpretq_f32_m128(b)), 0); + uint32x4_t a_not_nan = + vceqq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(a)); + uint32x4_t b_not_nan = + vceqq_f32(vreinterpretq_f32_m128(b), vreinterpretq_f32_m128(b)); + uint32x4_t a_and_b_not_nan = vandq_u32(a_not_nan, b_not_nan); + uint32x4_t a_gt_b = + vcgtq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b)); + return (vgetq_lane_u32(vandq_u32(a_and_b_not_nan, a_gt_b), 0) != 0) ? 1 : 0; +} + +// Compares the lower single-precision floating point scalar values of a and b +// using a less than or equal operation. : +// https://msdn.microsoft.com/en-us/library/1w4t7c57(v=vs.90).aspx +FORCE_INLINE int _mm_comile_ss(__m128 a, __m128 b) +{ + // return vgetq_lane_u32(vcleq_f32(vreinterpretq_f32_m128(a), + // vreinterpretq_f32_m128(b)), 0); + uint32x4_t a_not_nan = + vceqq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(a)); + uint32x4_t b_not_nan = + vceqq_f32(vreinterpretq_f32_m128(b), vreinterpretq_f32_m128(b)); + uint32x4_t a_and_b_not_nan = vandq_u32(a_not_nan, b_not_nan); + uint32x4_t a_le_b = + vcleq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b)); + return (vgetq_lane_u32(vandq_u32(a_and_b_not_nan, a_le_b), 0) != 0) ? 1 : 0; +} + +// Compares the lower single-precision floating point scalar values of a and b +// using a greater than or equal operation. : +// https://msdn.microsoft.com/en-us/library/8t80des6(v=vs.100).aspx +FORCE_INLINE int _mm_comige_ss(__m128 a, __m128 b) +{ + // return vgetq_lane_u32(vcgeq_f32(vreinterpretq_f32_m128(a), + // vreinterpretq_f32_m128(b)), 0); + uint32x4_t a_not_nan = + vceqq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(a)); + uint32x4_t b_not_nan = + vceqq_f32(vreinterpretq_f32_m128(b), vreinterpretq_f32_m128(b)); + uint32x4_t a_and_b_not_nan = vandq_u32(a_not_nan, b_not_nan); + uint32x4_t a_ge_b = + vcgeq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b)); + return (vgetq_lane_u32(vandq_u32(a_and_b_not_nan, a_ge_b), 0) != 0) ? 1 : 0; +} + +// Compares the lower single-precision floating point scalar values of a and b +// using an equality operation. : +// https://msdn.microsoft.com/en-us/library/93yx2h2b(v=vs.100).aspx +FORCE_INLINE int _mm_comieq_ss(__m128 a, __m128 b) +{ + // return vgetq_lane_u32(vceqq_f32(vreinterpretq_f32_m128(a), + // vreinterpretq_f32_m128(b)), 0); + uint32x4_t a_not_nan = + vceqq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(a)); + uint32x4_t b_not_nan = + vceqq_f32(vreinterpretq_f32_m128(b), vreinterpretq_f32_m128(b)); + uint32x4_t a_and_b_not_nan = vandq_u32(a_not_nan, b_not_nan); + uint32x4_t a_eq_b = + vceqq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b)); + return (vgetq_lane_u32(vandq_u32(a_and_b_not_nan, a_eq_b), 0) != 0) ? 1 : 0; +} + +// Compares the lower single-precision floating point scalar values of a and b +// using an inequality operation. : +// https://msdn.microsoft.com/en-us/library/bafh5e0a(v=vs.90).aspx +FORCE_INLINE int _mm_comineq_ss(__m128 a, __m128 b) +{ + // return !vgetq_lane_u32(vceqq_f32(vreinterpretq_f32_m128(a), + // vreinterpretq_f32_m128(b)), 0); + uint32x4_t a_not_nan = + vceqq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(a)); + uint32x4_t b_not_nan = + vceqq_f32(vreinterpretq_f32_m128(b), vreinterpretq_f32_m128(b)); + uint32x4_t a_or_b_nan = vmvnq_u32(vandq_u32(a_not_nan, b_not_nan)); + uint32x4_t a_neq_b = vmvnq_u32( + vceqq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); + return (vgetq_lane_u32(vorrq_u32(a_or_b_nan, a_neq_b), 0) != 0) ? 1 : 0; +} + +// according to the documentation, these intrinsics behave the same as the +// non-'u' versions. We'll just alias them here. +#define _mm_ucomilt_ss _mm_comilt_ss +#define _mm_ucomile_ss _mm_comile_ss +#define _mm_ucomigt_ss _mm_comigt_ss +#define _mm_ucomige_ss _mm_comige_ss +#define _mm_ucomieq_ss _mm_comieq_ss +#define _mm_ucomineq_ss _mm_comineq_ss + +// ****************************************** +// Conversions +// ****************************************** + +// Converts the four single-precision, floating-point values of a to signed +// 32-bit integer values using truncate. +// https://msdn.microsoft.com/en-us/library/vstudio/1h005y6x(v=vs.100).aspx +FORCE_INLINE __m128i _mm_cvttps_epi32(__m128 a) +{ + return vreinterpretq_m128i_s32(vcvtq_s32_f32(vreinterpretq_f32_m128(a))); +} + +// Converts the four signed 32-bit integer values of a to single-precision, +// floating-point values +// https://msdn.microsoft.com/en-us/library/vstudio/36bwxcx5(v=vs.100).aspx +FORCE_INLINE __m128 _mm_cvtepi32_ps(__m128i a) +{ + return vreinterpretq_m128_f32(vcvtq_f32_s32(vreinterpretq_s32_m128i(a))); +} + +// Converts the four unsigned 8-bit integers in the lower 16 bits to four +// unsigned 32-bit integers. +FORCE_INLINE __m128i _mm_cvtepu8_epi16(__m128i a) +{ + uint8x16_t u8x16 = vreinterpretq_u8_m128i(a); /* xxxx xxxx xxxx DCBA */ + uint16x8_t u16x8 = vmovl_u8(vget_low_u8(u8x16)); /* 0x0x 0x0x 0D0C 0B0A */ + return vreinterpretq_m128i_u16(u16x8); +} + +// Converts the four unsigned 8-bit integers in the lower 32 bits to four +// unsigned 32-bit integers. +// https://msdn.microsoft.com/en-us/library/bb531467%28v=vs.100%29.aspx +FORCE_INLINE __m128i _mm_cvtepu8_epi32(__m128i a) +{ + uint8x16_t u8x16 = vreinterpretq_u8_m128i(a); /* xxxx xxxx xxxx DCBA */ + uint16x8_t u16x8 = vmovl_u8(vget_low_u8(u8x16)); /* 0x0x 0x0x 0D0C 0B0A */ + uint32x4_t u32x4 = vmovl_u16(vget_low_u16(u16x8)); /* 000D 000C 000B 000A */ + return vreinterpretq_m128i_u32(u32x4); +} + +// Converts the two unsigned 8-bit integers in the lower 16 bits to two +// unsigned 64-bit integers. +FORCE_INLINE __m128i _mm_cvtepu8_epi64(__m128i a) +{ + uint8x16_t u8x16 = vreinterpretq_u8_m128i(a); /* xxxx xxxx xxxx xxBA */ + uint16x8_t u16x8 = vmovl_u8(vget_low_u8(u8x16)); /* 0x0x 0x0x 0x0x 0B0A */ + uint32x4_t u32x4 = vmovl_u16(vget_low_u16(u16x8)); /* 000x 000x 000B 000A */ + uint64x2_t u64x2 = vmovl_u32(vget_low_u32(u32x4)); /* 0000 000B 0000 000A */ + return vreinterpretq_m128i_u64(u64x2); +} + +// Converts the four unsigned 8-bit integers in the lower 16 bits to four +// unsigned 32-bit integers. +FORCE_INLINE __m128i _mm_cvtepi8_epi16(__m128i a) +{ + int8x16_t s8x16 = vreinterpretq_s8_m128i(a); /* xxxx xxxx xxxx DCBA */ + int16x8_t s16x8 = vmovl_s8(vget_low_s8(s8x16)); /* 0x0x 0x0x 0D0C 0B0A */ + return vreinterpretq_m128i_s16(s16x8); +} + +// Converts the four unsigned 8-bit integers in the lower 32 bits to four +// unsigned 32-bit integers. +FORCE_INLINE __m128i _mm_cvtepi8_epi32(__m128i a) +{ + int8x16_t s8x16 = vreinterpretq_s8_m128i(a); /* xxxx xxxx xxxx DCBA */ + int16x8_t s16x8 = vmovl_s8(vget_low_s8(s8x16)); /* 0x0x 0x0x 0D0C 0B0A */ + int32x4_t s32x4 = vmovl_s16(vget_low_s16(s16x8)); /* 000D 000C 000B 000A */ + return vreinterpretq_m128i_s32(s32x4); +} + +// Converts the two signed 8-bit integers in the lower 32 bits to four +// signed 64-bit integers. +FORCE_INLINE __m128i _mm_cvtepi8_epi64(__m128i a) +{ + int8x16_t s8x16 = vreinterpretq_s8_m128i(a); /* xxxx xxxx xxxx xxBA */ + int16x8_t s16x8 = vmovl_s8(vget_low_s8(s8x16)); /* 0x0x 0x0x 0x0x 0B0A */ + int32x4_t s32x4 = vmovl_s16(vget_low_s16(s16x8)); /* 000x 000x 000B 000A */ + int64x2_t s64x2 = vmovl_s32(vget_low_s32(s32x4)); /* 0000 000B 0000 000A */ + return vreinterpretq_m128i_s64(s64x2); +} + +// Converts the four signed 16-bit integers in the lower 64 bits to four signed +// 32-bit integers. +FORCE_INLINE __m128i _mm_cvtepi16_epi32(__m128i a) +{ + return vreinterpretq_m128i_s32( + vmovl_s16(vget_low_s16(vreinterpretq_s16_m128i(a)))); +} + +// Converts the two signed 16-bit integers in the lower 32 bits two signed +// 32-bit integers. +FORCE_INLINE __m128i _mm_cvtepi16_epi64(__m128i a) +{ + int16x8_t s16x8 = vreinterpretq_s16_m128i(a); /* xxxx xxxx xxxx 0B0A */ + int32x4_t s32x4 = vmovl_s16(vget_low_s16(s16x8)); /* 000x 000x 000B 000A */ + int64x2_t s64x2 = vmovl_s32(vget_low_s32(s32x4)); /* 0000 000B 0000 000A */ + return vreinterpretq_m128i_s64(s64x2); +} + +// Converts the four unsigned 16-bit integers in the lower 64 bits to four unsigned +// 32-bit integers. +FORCE_INLINE __m128i _mm_cvtepu16_epi32(__m128i a) +{ + return vreinterpretq_m128i_u32( + vmovl_u16(vget_low_u16(vreinterpretq_u16_m128i(a)))); +} + +// Converts the two unsigned 16-bit integers in the lower 32 bits to two unsigned +// 64-bit integers. +FORCE_INLINE __m128i _mm_cvtepu16_epi64(__m128i a) +{ + uint16x8_t u16x8 = vreinterpretq_u16_m128i(a); /* xxxx xxxx xxxx 0B0A */ + uint32x4_t u32x4 = vmovl_u16(vget_low_u16(u16x8)); /* 000x 000x 000B 000A */ + uint64x2_t u64x2 = vmovl_u32(vget_low_u32(u32x4)); /* 0000 000B 0000 000A */ + return vreinterpretq_m128i_u64(u64x2); +} + +// Converts the two unsigned 32-bit integers in the lower 64 bits to two unsigned +// 64-bit integers. +FORCE_INLINE __m128i _mm_cvtepu32_epi64(__m128i a) +{ + return vreinterpretq_m128i_u64( + vmovl_u32(vget_low_u32(vreinterpretq_u32_m128i(a)))); +} + +// Converts the two signed 32-bit integers in the lower 64 bits to two signed +// 64-bit integers. +FORCE_INLINE __m128i _mm_cvtepi32_epi64(__m128i a) +{ + return vreinterpretq_m128i_s64( + vmovl_s32(vget_low_s32(vreinterpretq_s32_m128i(a)))); +} + +// Converts the four single-precision, floating-point values of a to signed +// 32-bit integer values. +// +// r0 := (int) a0 +// r1 := (int) a1 +// r2 := (int) a2 +// r3 := (int) a3 +// +// https://msdn.microsoft.com/en-us/library/vstudio/xdc42k5e(v=vs.100).aspx +// *NOTE*. The default rounding mode on SSE is 'round to even', which ArmV7-A +// does not support! It is supported on ARMv8-A however. +FORCE_INLINE __m128i _mm_cvtps_epi32(__m128 a) +{ +#if defined(__aarch64__) + return vreinterpretq_m128i_s32(vcvtnq_s32_f32(a)); +#else + uint32x4_t signmask = vdupq_n_u32(0x80000000); + float32x4_t half = vbslq_f32(signmask, vreinterpretq_f32_m128(a), + vdupq_n_f32(0.5f)); /* +/- 0.5 */ + int32x4_t r_normal = vcvtq_s32_f32(vaddq_f32( + vreinterpretq_f32_m128(a), half)); /* round to integer: [a + 0.5]*/ + int32x4_t r_trunc = + vcvtq_s32_f32(vreinterpretq_f32_m128(a)); /* truncate to integer: [a] */ + int32x4_t plusone = vreinterpretq_s32_u32(vshrq_n_u32( + vreinterpretq_u32_s32(vnegq_s32(r_trunc)), 31)); /* 1 or 0 */ + int32x4_t r_even = vbicq_s32(vaddq_s32(r_trunc, plusone), + vdupq_n_s32(1)); /* ([a] + {0,1}) & ~1 */ + float32x4_t delta = vsubq_f32( + vreinterpretq_f32_m128(a), + vcvtq_f32_s32(r_trunc)); /* compute delta: delta = (a - [a]) */ + uint32x4_t is_delta_half = vceqq_f32(delta, half); /* delta == +/- 0.5 */ + return vreinterpretq_m128i_s32(vbslq_s32(is_delta_half, r_even, r_normal)); +#endif +} + +// Moves the least significant 32 bits of a to a 32-bit integer. +// https://msdn.microsoft.com/en-us/library/5z7a9642%28v=vs.90%29.aspx +FORCE_INLINE int _mm_cvtsi128_si32(__m128i a) +{ + return vgetq_lane_s32(vreinterpretq_s32_m128i(a), 0); +} + +// Extracts the low order 64-bit integer from the parameter. +// https://msdn.microsoft.com/en-us/library/bb531384(v=vs.120).aspx +FORCE_INLINE uint64_t _mm_cvtsi128_si64(__m128i a) +{ + return vgetq_lane_s64(vreinterpretq_s64_m128i(a), 0); +} + +// Moves 32-bit integer a to the least significant 32 bits of an __m128 object, +// zero extending the upper bits. +// +// r0 := a +// r1 := 0x0 +// r2 := 0x0 +// r3 := 0x0 +// +// https://msdn.microsoft.com/en-us/library/ct3539ha%28v=vs.90%29.aspx +FORCE_INLINE __m128i _mm_cvtsi32_si128(int a) +{ + return vreinterpretq_m128i_s32(vsetq_lane_s32(a, vdupq_n_s32(0), 0)); +} + +// Moves 64-bit integer a to the least significant 64 bits of an __m128 object, +// zero extending the upper bits. +// +// r0 := a +// r1 := 0x0 +FORCE_INLINE __m128i _mm_cvtsi64_si128(int64_t a) +{ + return vreinterpretq_m128i_s64(vsetq_lane_s64(a, vdupq_n_s64(0), 0)); +} + +// Applies a type cast to reinterpret four 32-bit floating point values passed +// in as a 128-bit parameter as packed 32-bit integers. +// https://msdn.microsoft.com/en-us/library/bb514099.aspx +FORCE_INLINE __m128i _mm_castps_si128(__m128 a) +{ + return vreinterpretq_m128i_s32(vreinterpretq_s32_m128(a)); +} + +// Applies a type cast to reinterpret four 32-bit integers passed in as a +// 128-bit parameter as packed 32-bit floating point values. +// https://msdn.microsoft.com/en-us/library/bb514029.aspx +FORCE_INLINE __m128 _mm_castsi128_ps(__m128i a) +{ + return vreinterpretq_m128_s32(vreinterpretq_s32_m128i(a)); +} + +// Loads 128-bit value. : +// https://msdn.microsoft.com/en-us/library/atzzad1h(v=vs.80).aspx +FORCE_INLINE __m128i _mm_load_si128(const __m128i *p) +{ + return vreinterpretq_m128i_s32(vld1q_s32((const int32_t *) p)); +} + +// Loads 128-bit value. : +// https://msdn.microsoft.com/zh-cn/library/f4k12ae8(v=vs.90).aspx +FORCE_INLINE __m128i _mm_loadu_si128(const __m128i *p) +{ + return vreinterpretq_m128i_s32(vld1q_s32((const int32_t *) p)); +} + +// _mm_lddqu_si128 functions the same as _mm_loadu_si128. +#define _mm_lddqu_si128 _mm_loadu_si128 + +// ****************************************** +// Miscellaneous Operations +// ****************************************** + + +// Shifts the 8 signed 16-bit integers in a right by count bits while shifting +// in the sign bit. +// +// r0 := a0 >> count +// r1 := a1 >> count +// ... +// r7 := a7 >> count +// +// https://msdn.microsoft.com/en-us/library/3c9997dk(v%3dvs.90).aspx +FORCE_INLINE __m128i _mm_sra_epi16(__m128i a, __m128i count) +{ + int64_t c = (int64_t) vget_low_s64((int64x2_t) count); + if (c > 15) + return _mm_cmplt_epi16(a, _mm_setzero_si128()); + return vreinterpretq_m128i_s16(vshlq_s16((int16x8_t) a, vdupq_n_s16(-c))); +} + +// Shifts the 4 signed 32-bit integers in a right by count bits while shifting +// in the sign bit. +// +// r0 := a0 >> count +// r1 := a1 >> count +// r2 := a2 >> count +// r3 := a3 >> count +// +// https://msdn.microsoft.com/en-us/library/ce40009e(v%3dvs.100).aspx +FORCE_INLINE __m128i _mm_sra_epi32(__m128i a, __m128i count) +{ + int64_t c = (int64_t) vget_low_s64((int64x2_t) count); + if (c > 31) + return _mm_cmplt_epi32(a, _mm_setzero_si128()); + return vreinterpretq_m128i_s32(vshlq_s32((int32x4_t) a, vdupq_n_s32(-c))); +} + +// Packs the 16 signed 16-bit integers from a and b into 8-bit integers and +// saturates. +// https://msdn.microsoft.com/en-us/library/k4y4f7w5%28v=vs.90%29.aspx +FORCE_INLINE __m128i _mm_packs_epi16(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s8( + vcombine_s8(vqmovn_s16(vreinterpretq_s16_m128i(a)), + vqmovn_s16(vreinterpretq_s16_m128i(b)))); +} + +// Packs the 16 signed 16 - bit integers from a and b into 8 - bit unsigned +// integers and saturates. +// +// r0 := UnsignedSaturate(a0) +// r1 := UnsignedSaturate(a1) +// ... +// r7 := UnsignedSaturate(a7) +// r8 := UnsignedSaturate(b0) +// r9 := UnsignedSaturate(b1) +// ... +// r15 := UnsignedSaturate(b7) +// +// https://msdn.microsoft.com/en-us/library/07ad1wx4(v=vs.100).aspx +FORCE_INLINE __m128i _mm_packus_epi16(const __m128i a, const __m128i b) +{ + return vreinterpretq_m128i_u8( + vcombine_u8(vqmovun_s16(vreinterpretq_s16_m128i(a)), + vqmovun_s16(vreinterpretq_s16_m128i(b)))); +} + +// Packs the 8 signed 32-bit integers from a and b into signed 16-bit integers +// and saturates. +// +// r0 := SignedSaturate(a0) +// r1 := SignedSaturate(a1) +// r2 := SignedSaturate(a2) +// r3 := SignedSaturate(a3) +// r4 := SignedSaturate(b0) +// r5 := SignedSaturate(b1) +// r6 := SignedSaturate(b2) +// r7 := SignedSaturate(b3) +// +// https://msdn.microsoft.com/en-us/library/393t56f9%28v=vs.90%29.aspx +FORCE_INLINE __m128i _mm_packs_epi32(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s16( + vcombine_s16(vqmovn_s32(vreinterpretq_s32_m128i(a)), + vqmovn_s32(vreinterpretq_s32_m128i(b)))); +} + +// Packs the 8 unsigned 32-bit integers from a and b into unsigned 16-bit integers +// and saturates. +// +// r0 := UnsignedSaturate(a0) +// r1 := UnsignedSaturate(a1) +// r2 := UnsignedSaturate(a2) +// r3 := UnsignedSaturate(a3) +// r4 := UnsignedSaturate(b0) +// r5 := UnsignedSaturate(b1) +// r6 := UnsignedSaturate(b2) +// r7 := UnsignedSaturate(b3) +FORCE_INLINE __m128i _mm_packus_epi32(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_u16( + vcombine_u16(vqmovn_u32(vreinterpretq_u32_m128i(a)), + vqmovn_u32(vreinterpretq_u32_m128i(b)))); +} + +// Interleaves the lower 8 signed or unsigned 8-bit integers in a with the lower +// 8 signed or unsigned 8-bit integers in b. +// +// r0 := a0 +// r1 := b0 +// r2 := a1 +// r3 := b1 +// ... +// r14 := a7 +// r15 := b7 +// +// https://msdn.microsoft.com/en-us/library/xf7k860c%28v=vs.90%29.aspx +FORCE_INLINE __m128i _mm_unpacklo_epi8(__m128i a, __m128i b) +{ +#if defined(__aarch64__) + return vreinterpretq_m128i_s8(vzip1q_s8(vreinterpretq_s8_m128i(a), vreinterpretq_s8_m128i(b))); +#else + int8x8_t a1 = vreinterpret_s8_s16(vget_low_s16(vreinterpretq_s16_m128i(a))); + int8x8_t b1 = vreinterpret_s8_s16(vget_low_s16(vreinterpretq_s16_m128i(b))); + int8x8x2_t result = vzip_s8(a1, b1); + return vreinterpretq_m128i_s8(vcombine_s8(result.val[0], result.val[1])); +#endif +} + +// Interleaves the lower 4 signed or unsigned 16-bit integers in a with the +// lower 4 signed or unsigned 16-bit integers in b. +// +// r0 := a0 +// r1 := b0 +// r2 := a1 +// r3 := b1 +// r4 := a2 +// r5 := b2 +// r6 := a3 +// r7 := b3 +// +// https://msdn.microsoft.com/en-us/library/btxb17bw%28v=vs.90%29.aspx +FORCE_INLINE __m128i _mm_unpacklo_epi16(__m128i a, __m128i b) +{ +#if defined(__aarch64__) + return vreinterpretq_m128i_s16(vzip1q_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b))); +#else + int16x4_t a1 = vget_low_s16(vreinterpretq_s16_m128i(a)); + int16x4_t b1 = vget_low_s16(vreinterpretq_s16_m128i(b)); + int16x4x2_t result = vzip_s16(a1, b1); + return vreinterpretq_m128i_s16(vcombine_s16(result.val[0], result.val[1])); +#endif +} + +// Interleaves the lower 2 signed or unsigned 32 - bit integers in a with the +// lower 2 signed or unsigned 32 - bit integers in b. +// +// r0 := a0 +// r1 := b0 +// r2 := a1 +// r3 := b1 +// +// https://msdn.microsoft.com/en-us/library/x8atst9d(v=vs.100).aspx +FORCE_INLINE __m128i _mm_unpacklo_epi32(__m128i a, __m128i b) +{ +#if defined(__aarch64__) + return vreinterpretq_m128i_s32(vzip1q_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b))); +#else + int32x2_t a1 = vget_low_s32(vreinterpretq_s32_m128i(a)); + int32x2_t b1 = vget_low_s32(vreinterpretq_s32_m128i(b)); + int32x2x2_t result = vzip_s32(a1, b1); + return vreinterpretq_m128i_s32(vcombine_s32(result.val[0], result.val[1])); +#endif +} + +FORCE_INLINE __m128i _mm_unpacklo_epi64(__m128i a, __m128i b) +{ + int64x1_t a_l = vget_low_s64(vreinterpretq_s64_m128i(a)); + int64x1_t b_l = vget_low_s64(vreinterpretq_s64_m128i(b)); + return vreinterpretq_m128i_s64(vcombine_s64(a_l, b_l)); +} + +// Selects and interleaves the lower two single-precision, floating-point values +// from a and b. +// +// r0 := a0 +// r1 := b0 +// r2 := a1 +// r3 := b1 +// +// https://msdn.microsoft.com/en-us/library/25st103b%28v=vs.90%29.aspx +FORCE_INLINE __m128 _mm_unpacklo_ps(__m128 a, __m128 b) +{ +#if defined(__aarch64__) + return vreinterpretq_m128_f32(vzip1q_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); +#else + float32x2_t a1 = vget_low_f32(vreinterpretq_f32_m128(a)); + float32x2_t b1 = vget_low_f32(vreinterpretq_f32_m128(b)); + float32x2x2_t result = vzip_f32(a1, b1); + return vreinterpretq_m128_f32(vcombine_f32(result.val[0], result.val[1])); +#endif +} + +// Selects and interleaves the upper two single-precision, floating-point values +// from a and b. +// +// r0 := a2 +// r1 := b2 +// r2 := a3 +// r3 := b3 +// +// https://msdn.microsoft.com/en-us/library/skccxx7d%28v=vs.90%29.aspx +FORCE_INLINE __m128 _mm_unpackhi_ps(__m128 a, __m128 b) +{ +#if defined(__aarch64__) + return vreinterpretq_m128_f32(vzip2q_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); +#else + float32x2_t a1 = vget_high_f32(vreinterpretq_f32_m128(a)); + float32x2_t b1 = vget_high_f32(vreinterpretq_f32_m128(b)); + float32x2x2_t result = vzip_f32(a1, b1); + return vreinterpretq_m128_f32(vcombine_f32(result.val[0], result.val[1])); +#endif +} + +// Interleaves the upper 8 signed or unsigned 8-bit integers in a with the upper +// 8 signed or unsigned 8-bit integers in b. +// +// r0 := a8 +// r1 := b8 +// r2 := a9 +// r3 := b9 +// ... +// r14 := a15 +// r15 := b15 +// +// https://msdn.microsoft.com/en-us/library/t5h7783k(v=vs.100).aspx +FORCE_INLINE __m128i _mm_unpackhi_epi8(__m128i a, __m128i b) +{ +#if defined(__aarch64__) + return vreinterpretq_m128i_s8(vzip2q_s8(vreinterpretq_s8_m128i(a), vreinterpretq_s8_m128i(b))); +#else + int8x8_t a1 = + vreinterpret_s8_s16(vget_high_s16(vreinterpretq_s16_m128i(a))); + int8x8_t b1 = + vreinterpret_s8_s16(vget_high_s16(vreinterpretq_s16_m128i(b))); + int8x8x2_t result = vzip_s8(a1, b1); + return vreinterpretq_m128i_s8(vcombine_s8(result.val[0], result.val[1])); +#endif +} + +// Interleaves the upper 4 signed or unsigned 16-bit integers in a with the +// upper 4 signed or unsigned 16-bit integers in b. +// +// r0 := a4 +// r1 := b4 +// r2 := a5 +// r3 := b5 +// r4 := a6 +// r5 := b6 +// r6 := a7 +// r7 := b7 +// +// https://msdn.microsoft.com/en-us/library/03196cz7(v=vs.100).aspx +FORCE_INLINE __m128i _mm_unpackhi_epi16(__m128i a, __m128i b) +{ +#if defined(__aarch64__) + return vreinterpretq_m128i_s16(vzip2q_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b))); +#else + int16x4_t a1 = vget_high_s16(vreinterpretq_s16_m128i(a)); + int16x4_t b1 = vget_high_s16(vreinterpretq_s16_m128i(b)); + int16x4x2_t result = vzip_s16(a1, b1); + return vreinterpretq_m128i_s16(vcombine_s16(result.val[0], result.val[1])); +#endif +} + +// Interleaves the upper 2 signed or unsigned 32-bit integers in a with the +// upper 2 signed or unsigned 32-bit integers in b. +// https://msdn.microsoft.com/en-us/library/65sa7cbs(v=vs.100).aspx +FORCE_INLINE __m128i _mm_unpackhi_epi32(__m128i a, __m128i b) +{ +#if defined(__aarch64__) + return vreinterpretq_m128i_s32(vzip2q_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b))); +#else + int32x2_t a1 = vget_high_s32(vreinterpretq_s32_m128i(a)); + int32x2_t b1 = vget_high_s32(vreinterpretq_s32_m128i(b)); + int32x2x2_t result = vzip_s32(a1, b1); + return vreinterpretq_m128i_s32(vcombine_s32(result.val[0], result.val[1])); +#endif +} + +// Interleaves the upper signed or unsigned 64-bit integer in a with the +// upper signed or unsigned 64-bit integer in b. +// +// r0 := a1 +// r1 := b1 +FORCE_INLINE __m128i _mm_unpackhi_epi64(__m128i a, __m128i b) +{ + int64x1_t a_h = vget_high_s64(vreinterpretq_s64_m128i(a)); + int64x1_t b_h = vget_high_s64(vreinterpretq_s64_m128i(b)); + return vreinterpretq_m128i_s64(vcombine_s64(a_h, b_h)); +} + +// shift to right +// https://msdn.microsoft.com/en-us/library/bb514041(v=vs.120).aspx +// http://blog.csdn.net/hemmingway/article/details/44828303 +// Clang requires a macro here, as it is extremely picky about c being a literal. +#define _mm_alignr_epi8(a, b, c) ((__m128i) vextq_s8((int8x16_t) (b), (int8x16_t) (a), (c))) + +// Extracts the selected signed or unsigned 8-bit integer from a and zero +// extends. +// FORCE_INLINE int _mm_extract_epi8(__m128i a, __constrange(0,16) int imm) +#define _mm_extract_epi8(a, imm) \ + vgetq_lane_u8(vreinterpretq_u8_m128i(a), (imm)) + +// Inserts the least significant 8 bits of b into the selected 8-bit integer +// of a. +// FORCE_INLINE __m128i _mm_insert_epi8(__m128i a, const int b, +// __constrange(0,16) int imm) +#define _mm_insert_epi8(a, b, imm) \ + __extension__({ \ + vreinterpretq_m128i_s8( \ + vsetq_lane_s8((b), vreinterpretq_s8_m128i(a), (imm))); \ + }) + +// Extracts the selected signed or unsigned 16-bit integer from a and zero +// extends. +// https://msdn.microsoft.com/en-us/library/6dceta0c(v=vs.100).aspx +// FORCE_INLINE int _mm_extract_epi16(__m128i a, __constrange(0,8) int imm) +#define _mm_extract_epi16(a, imm) \ + vgetq_lane_u16(vreinterpretq_u16_m128i(a), (imm)) + +// Inserts the least significant 16 bits of b into the selected 16-bit integer +// of a. +// https://msdn.microsoft.com/en-us/library/kaze8hz1%28v=vs.100%29.aspx +// FORCE_INLINE __m128i _mm_insert_epi16(__m128i a, const int b, +// __constrange(0,8) int imm) +#define _mm_insert_epi16(a, b, imm) \ + __extension__({ \ + vreinterpretq_m128i_s16( \ + vsetq_lane_s16((b), vreinterpretq_s16_m128i(a), (imm))); \ + }) + +// Extracts the selected signed or unsigned 32-bit integer from a and zero +// extends. +// FORCE_INLINE int _mm_extract_epi32(__m128i a, __constrange(0,4) int imm) +#define _mm_extract_epi32(a, imm) \ + vgetq_lane_s32(vreinterpretq_s32_m128i(a), (imm)) + +// Inserts the least significant 32 bits of b into the selected 32-bit integer +// of a. +// FORCE_INLINE __m128i _mm_insert_epi32(__m128i a, const int b, +// __constrange(0,4) int imm) +#define _mm_insert_epi32(a, b, imm) \ + __extension__({ \ + vreinterpretq_m128i_s32( \ + vsetq_lane_s32((b), vreinterpretq_s32_m128i(a), (imm))); \ + }) + + +// Extracts the selected signed or unsigned 64-bit integer from a and zero +// extends. +// FORCE_INLINE __int64 _mm_extract_epi64(__m128i a, __constrange(0,2) int imm) +#define _mm_extract_epi64(a, imm) \ + vgetq_lane_s64(vreinterpretq_s64_m128i(a), (imm)) + +// Inserts the least significant 64 bits of b into the selected 64-bit integer +// of a. +// FORCE_INLINE __m128i _mm_insert_epi64(__m128i a, const __int64 b, +// __constrange(0,2) int imm) +#define _mm_insert_epi64(a, b, imm) \ + __extension__({ \ + vreinterpretq_m128i_s64( \ + vsetq_lane_s64((b), vreinterpretq_s64_m128i(a), (imm))); \ + }) + +// ****************************************** +// Crypto Extensions +// ****************************************** +#if defined(__ARM_FEATURE_CRYPTO) +// Wraps vmull_p64 +FORCE_INLINE uint64x2_t _sse2neon_vmull_p64(uint64x1_t _a, uint64x1_t _b) +{ + poly64_t a = vget_lane_p64(vreinterpret_p64_u64(_a), 0); + poly64_t b = vget_lane_p64(vreinterpret_p64_u64(_b), 0); + return vreinterpretq_u64_p128(vmull_p64(a, b)); +} + +#else // ARMv7 polyfill +// ARMv7/some A64 lacks vmull_p64, but it has vmull_p8. +// +// vmull_p8 calculates 8 8-bit->16-bit polynomial multiplies, but we need a +// 64-bit->128-bit polynomial multiply. +// +// It needs some work and is somewhat slow, but it is still faster than all +// known scalar methods. +// +// Algorithm adapted to C from https://www.workofard.com/2017/07/ghash-for-low-end-cores/, +// which is adapted from "Fast Software Polynomial Multiplication on +// ARM Processors Using the NEON Engine" by Danilo Camara, Conrado Gouvea, +// Julio Lopez and Ricardo Dahab (https://hal.inria.fr/hal-01506572) +static uint64x2_t _sse2neon_vmull_p64(uint64x1_t _a, uint64x1_t _b) +{ + poly8x8_t a = vreinterpret_p8_u64(_a); + poly8x8_t b = vreinterpret_p8_u64(_b); + + // Masks + uint8x16_t k48_32 = vcombine_u8(vcreate_u8(0x0000ffffffffffff), vcreate_u8(0x00000000ffffffff)); + uint8x16_t k16_00 = vcombine_u8(vcreate_u8(0x000000000000ffff), vcreate_u8(0x0000000000000000)); + + // Do the multiplies, rotating with vext to get all combinations + uint8x16_t d = vreinterpretq_u8_p16(vmull_p8(a, b)); // D = A0 * B0 + uint8x16_t e = vreinterpretq_u8_p16(vmull_p8(a, vext_p8(b, b, 1))); // E = A0 * B1 + uint8x16_t f = vreinterpretq_u8_p16(vmull_p8(vext_p8(a, a, 1), b)); // F = A1 * B0 + uint8x16_t g = vreinterpretq_u8_p16(vmull_p8(a, vext_p8(b, b, 2))); // G = A0 * B2 + uint8x16_t h = vreinterpretq_u8_p16(vmull_p8(vext_p8(a, a, 2), b)); // H = A2 * B0 + uint8x16_t i = vreinterpretq_u8_p16(vmull_p8(a, vext_p8(b, b, 3))); // I = A0 * B3 + uint8x16_t j = vreinterpretq_u8_p16(vmull_p8(vext_p8(a, a, 3), b)); // J = A3 * B0 + uint8x16_t k = vreinterpretq_u8_p16(vmull_p8(a, vext_p8(b, b, 4))); // L = A0 * B4 + + // Add cross products + uint8x16_t l = veorq_u8(e, f); // L = E + F + uint8x16_t m = veorq_u8(g, h); // M = G + H + uint8x16_t n = veorq_u8(i, j); // N = I + J + + // Interleave. Using vzip1 and vzip2 prevents Clang from emitting TBL instructions. +#if defined(__aarch64__) + uint8x16_t lm_p0 = vreinterpretq_u8_u64(vzip1q_u64(vreinterpretq_u64_u8(l), vreinterpretq_u64_u8(m))); + uint8x16_t lm_p1 = vreinterpretq_u8_u64(vzip2q_u64(vreinterpretq_u64_u8(l), vreinterpretq_u64_u8(m))); + uint8x16_t nk_p0 = vreinterpretq_u8_u64(vzip1q_u64(vreinterpretq_u64_u8(n), vreinterpretq_u64_u8(k))); + uint8x16_t nk_p1 = vreinterpretq_u8_u64(vzip2q_u64(vreinterpretq_u64_u8(n), vreinterpretq_u64_u8(k))); +#else + uint8x16_t lm_p0 = vcombine_u8(vget_low_u8(l), vget_low_u8(m)); + uint8x16_t lm_p1 = vcombine_u8(vget_high_u8(l), vget_high_u8(m)); + uint8x16_t nk_p0 = vcombine_u8(vget_low_u8(n), vget_low_u8(k)); + uint8x16_t nk_p1 = vcombine_u8(vget_high_u8(n), vget_high_u8(k)); +#endif + // t0 = (L) (P0 + P1) << 8 + // t1 = (M) (P2 + P3) << 16 + uint8x16_t t0t1_tmp = veorq_u8(lm_p0, lm_p1); + uint8x16_t t0t1_h = vandq_u8(lm_p1, k48_32); + uint8x16_t t0t1_l = veorq_u8(t0t1_tmp, t0t1_h); + + // t2 = (N) (P4 + P5) << 24 + // t3 = (K) (P6 + P7) << 32 + uint8x16_t t2t3_tmp = veorq_u8(nk_p0, nk_p1); + uint8x16_t t2t3_h = vandq_u8(nk_p1, k16_00); + uint8x16_t t2t3_l = veorq_u8(t2t3_tmp, t2t3_h); + + // De-interleave +#if defined(__aarch64__) + uint8x16_t t0 = vreinterpretq_u8_u64(vuzp1q_u64(vreinterpretq_u64_u8(t0t1_l), vreinterpretq_u64_u8(t0t1_h))); + uint8x16_t t1 = vreinterpretq_u8_u64(vuzp2q_u64(vreinterpretq_u64_u8(t0t1_l), vreinterpretq_u64_u8(t0t1_h))); + uint8x16_t t2 = vreinterpretq_u8_u64(vuzp1q_u64(vreinterpretq_u64_u8(t2t3_l), vreinterpretq_u64_u8(t2t3_h))); + uint8x16_t t3 = vreinterpretq_u8_u64(vuzp2q_u64(vreinterpretq_u64_u8(t2t3_l), vreinterpretq_u64_u8(t2t3_h))); +#else + uint8x16_t t1 = vcombine_u8(vget_high_u8(t0t1_l), vget_high_u8(t0t1_h)); + uint8x16_t t0 = vcombine_u8(vget_low_u8(t0t1_l), vget_low_u8(t0t1_h)); + uint8x16_t t3 = vcombine_u8(vget_high_u8(t2t3_l), vget_high_u8(t2t3_h)); + uint8x16_t t2 = vcombine_u8(vget_low_u8(t2t3_l), vget_low_u8(t2t3_h)); +#endif + // Shift the cross products + uint8x16_t t0_shift = vextq_u8(t0, t0, 15); // t0 << 8 + uint8x16_t t1_shift = vextq_u8(t1, t1, 14); // t1 << 16 + uint8x16_t t2_shift = vextq_u8(t2, t2, 13); // t2 << 24 + uint8x16_t t3_shift = vextq_u8(t3, t3, 12); // t3 << 32 + + // Accumulate the products + uint8x16_t cross1 = veorq_u8(t0_shift, t1_shift); + uint8x16_t cross2 = veorq_u8(t2_shift, t3_shift); + uint8x16_t mix = veorq_u8(d, cross1); + uint8x16_t r = veorq_u8(mix, cross2); + return vreinterpretq_u64_u8(r); +} + +#endif // ARMv7 polyfill +FORCE_INLINE __m128i _mm_clmulepi64_si128(__m128i _a, __m128i _b, const int imm) +{ + uint64x2_t a = vreinterpretq_u64_m128i(_a); + uint64x2_t b = vreinterpretq_u64_m128i(_b); + switch (imm & 0x11) { + case 0x00: return vreinterpretq_m128i_u64(_sse2neon_vmull_p64(vget_low_u64(a), vget_low_u64(b))); + case 0x01: return vreinterpretq_m128i_u64(_sse2neon_vmull_p64(vget_high_u64(a), vget_low_u64(b))); + case 0x10: return vreinterpretq_m128i_u64(_sse2neon_vmull_p64(vget_low_u64(a), vget_high_u64(b))); + case 0x11: return vreinterpretq_m128i_u64(_sse2neon_vmull_p64(vget_high_u64(a), vget_high_u64(b))); + default: abort(); + } +} + +#if !defined(__ARM_FEATURE_CRYPTO) && defined(__aarch64__) +// In the absence of crypto extensions, implement aesenc using regular neon +// intrinsics instead. See: +// https://www.workofard.com/2017/01/accelerated-aes-for-the-arm64-linux-kernel/ +// https://www.workofard.com/2017/07/ghash-for-low-end-cores/ and +// https://github.com/ColinIanKing/linux-next-mirror/blob/b5f466091e130caaf0735976648f72bd5e09aa84/crypto/aegis128-neon-inner.c#L52 +// for more information Reproduced with permission of the author. +FORCE_INLINE __m128i _mm_aesenc_si128(__m128i EncBlock, __m128i RoundKey) +{ + static const uint8_t crypto_aes_sbox[256] = { + 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, + 0xfe, 0xd7, 0xab, 0x76, 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, + 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, 0xb7, 0xfd, 0x93, 0x26, + 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, + 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, + 0xeb, 0x27, 0xb2, 0x75, 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, + 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, 0x53, 0xd1, 0x00, 0xed, + 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, + 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, + 0x50, 0x3c, 0x9f, 0xa8, 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, + 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, 0xcd, 0x0c, 0x13, 0xec, + 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, + 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, + 0xde, 0x5e, 0x0b, 0xdb, 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, + 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, 0xe7, 0xc8, 0x37, 0x6d, + 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, + 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, + 0x4b, 0xbd, 0x8b, 0x8a, 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, + 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, 0xe1, 0xf8, 0x98, 0x11, + 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, + 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, + 0xb0, 0x54, 0xbb, 0x16}; + static const uint8_t shift_rows[] = {0x0, 0x5, 0xa, 0xf, 0x4, 0x9, + 0xe, 0x3, 0x8, 0xd, 0x2, 0x7, + 0xc, 0x1, 0x6, 0xb}; + static const uint8_t ror32by8[] = {0x1, 0x2, 0x3, 0x0, 0x5, 0x6, 0x7, 0x4, + 0x9, 0xa, 0xb, 0x8, 0xd, 0xe, 0xf, 0xc}; + + uint8x16_t v; + uint8x16_t w = vreinterpretq_u8_m128i(EncBlock); + + // shift rows + w = vqtbl1q_u8(w, vld1q_u8(shift_rows)); + + // sub bytes + v = vqtbl4q_u8(vld1q_u8_x4(crypto_aes_sbox), w); + v = vqtbx4q_u8(v, vld1q_u8_x4(crypto_aes_sbox + 0x40), w - 0x40); + v = vqtbx4q_u8(v, vld1q_u8_x4(crypto_aes_sbox + 0x80), w - 0x80); + v = vqtbx4q_u8(v, vld1q_u8_x4(crypto_aes_sbox + 0xc0), w - 0xc0); + + // mix columns + w = (v << 1) ^ (uint8x16_t)(((int8x16_t) v >> 7) & 0x1b); + w ^= (uint8x16_t) vrev32q_u16((uint16x8_t) v); + w ^= vqtbl1q_u8(v ^ w, vld1q_u8(ror32by8)); + + // add round key + return vreinterpretq_m128i_u8(w) ^ RoundKey; +} +#elif defined(__ARM_FEATURE_CRYPTO) +// Implements equivalent of 'aesenc' by combining AESE (with an empty key) and +// AESMC and then manually applying the real key as an xor operation This +// unfortunately means an additional xor op; the compiler should be able to +// optimise this away for repeated calls however See +// https://blog.michaelbrase.com/2018/05/08/emulating-x86-aes-intrinsics-on-armv8-a +// for more details. +inline __m128i _mm_aesenc_si128(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_u8( + vaesmcq_u8(vaeseq_u8(vreinterpretq_u8_m128i(a), vdupq_n_u8(0))) ^ + vreinterpretq_u8_m128i(b)); +} +#endif + +// ****************************************** +// Streaming Extensions +// ****************************************** + +// Guarantees that every preceding store is globally visible before any +// subsequent store. +// https://msdn.microsoft.com/en-us/library/5h2w73d1%28v=vs.90%29.aspx +FORCE_INLINE void _mm_sfence(void) +{ + __sync_synchronize(); +} + +// Stores the data in a to the address p without polluting the caches. If the +// cache line containing address p is already in the cache, the cache will be +// updated.Address p must be 16 - byte aligned. +// https://msdn.microsoft.com/en-us/library/ba08y07y%28v=vs.90%29.aspx +FORCE_INLINE void _mm_stream_si128(__m128i *p, __m128i a) +{ + vst1q_s64((int64_t *) p, vreinterpretq_s64_m128i(a)); +} + +// Cache line containing p is flushed and invalidated from all caches in the +// coherency domain. : +// https://msdn.microsoft.com/en-us/library/ba08y07y(v=vs.100).aspx +FORCE_INLINE void _mm_clflush(void const *p) +{ + (void)p; + // no corollary for Neon? +} + +// Allocate aligned blocks of memory. +// https://software.intel.com/en-us/ +// cpp-compiler-developer-guide-and-reference-allocating-and-freeing-aligned-memory-blocks +FORCE_INLINE void *_mm_malloc(size_t size, size_t align) +{ + void *ptr; + if (align == 1) + return malloc(size); + if (align == 2 || (sizeof(void *) == 8 && align == 4)) + align = sizeof(void *); + if (!posix_memalign(&ptr, align, size)) + return ptr; + return NULL; +} + +FORCE_INLINE void _mm_free(void *addr) +{ + free(addr); +} + +#if defined(__GNUC__) || defined(__clang__) +#pragma pop_macro("ALIGN_STRUCT") +#pragma pop_macro("FORCE_INLINE") +#endif + +#endif diff --git a/venv/Include/site/python3.9/pygame/mask.h b/venv/Include/site/python3.9/pygame/mask.h new file mode 100644 index 0000000..45ad8c5 --- /dev/null +++ b/venv/Include/site/python3.9/pygame/mask.h @@ -0,0 +1,7 @@ +#ifndef PGMASK_INTERNAL_H +#define PGMASK_INTERNAL_H + +#include "include/pygame_mask.h" +#define PYGAMEAPI_MASK_NUMSLOTS 1 + +#endif /* ~PGMASK_INTERNAL_H */ diff --git a/venv/Include/site/python3.9/pygame/mixer.h b/venv/Include/site/python3.9/pygame/mixer.h new file mode 100644 index 0000000..3650612 --- /dev/null +++ b/venv/Include/site/python3.9/pygame/mixer.h @@ -0,0 +1,14 @@ +#ifndef MIXER_INTERNAL_H +#define MIXER_INTERNAL_H + +#include + +/* test mixer initializations */ +#define MIXER_INIT_CHECK() \ + if(!SDL_WasInit(SDL_INIT_AUDIO)) \ + return RAISE(pgExc_SDLError, "mixer not initialized") + +#define PYGAMEAPI_MIXER_NUMSLOTS 7 +#include "include/pygame_mixer.h" + +#endif /* ~MIXER_INTERNAL_H */ diff --git a/venv/Include/site/python3.9/pygame/palette.h b/venv/Include/site/python3.9/pygame/palette.h new file mode 100644 index 0000000..1ae4cf6 --- /dev/null +++ b/venv/Include/site/python3.9/pygame/palette.h @@ -0,0 +1,123 @@ +/* + pygame - Python Game Library + Copyright (C) 2000-2001 Pete Shinners + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Pete Shinners + pete@shinners.org +*/ + +#ifndef PALETTE_H +#define PALETTE_H + +#include + +/* SDL 2 does not assign a default palette color scheme to a new 8 bit + * surface. Instead, the palette is set all white. This defines the SDL 1.2 + * default palette. + */ +static const SDL_Color default_palette_colors[] = { + {0, 0, 0, 255}, {0, 0, 85, 255}, {0, 0, 170, 255}, + {0, 0, 255, 255}, {0, 36, 0, 255}, {0, 36, 85, 255}, + {0, 36, 170, 255}, {0, 36, 255, 255}, {0, 73, 0, 255}, + {0, 73, 85, 255}, {0, 73, 170, 255}, {0, 73, 255, 255}, + {0, 109, 0, 255}, {0, 109, 85, 255}, {0, 109, 170, 255}, + {0, 109, 255, 255}, {0, 146, 0, 255}, {0, 146, 85, 255}, + {0, 146, 170, 255}, {0, 146, 255, 255}, {0, 182, 0, 255}, + {0, 182, 85, 255}, {0, 182, 170, 255}, {0, 182, 255, 255}, + {0, 219, 0, 255}, {0, 219, 85, 255}, {0, 219, 170, 255}, + {0, 219, 255, 255}, {0, 255, 0, 255}, {0, 255, 85, 255}, + {0, 255, 170, 255}, {0, 255, 255, 255}, {85, 0, 0, 255}, + {85, 0, 85, 255}, {85, 0, 170, 255}, {85, 0, 255, 255}, + {85, 36, 0, 255}, {85, 36, 85, 255}, {85, 36, 170, 255}, + {85, 36, 255, 255}, {85, 73, 0, 255}, {85, 73, 85, 255}, + {85, 73, 170, 255}, {85, 73, 255, 255}, {85, 109, 0, 255}, + {85, 109, 85, 255}, {85, 109, 170, 255}, {85, 109, 255, 255}, + {85, 146, 0, 255}, {85, 146, 85, 255}, {85, 146, 170, 255}, + {85, 146, 255, 255}, {85, 182, 0, 255}, {85, 182, 85, 255}, + {85, 182, 170, 255}, {85, 182, 255, 255}, {85, 219, 0, 255}, + {85, 219, 85, 255}, {85, 219, 170, 255}, {85, 219, 255, 255}, + {85, 255, 0, 255}, {85, 255, 85, 255}, {85, 255, 170, 255}, + {85, 255, 255, 255}, {170, 0, 0, 255}, {170, 0, 85, 255}, + {170, 0, 170, 255}, {170, 0, 255, 255}, {170, 36, 0, 255}, + {170, 36, 85, 255}, {170, 36, 170, 255}, {170, 36, 255, 255}, + {170, 73, 0, 255}, {170, 73, 85, 255}, {170, 73, 170, 255}, + {170, 73, 255, 255}, {170, 109, 0, 255}, {170, 109, 85, 255}, + {170, 109, 170, 255}, {170, 109, 255, 255}, {170, 146, 0, 255}, + {170, 146, 85, 255}, {170, 146, 170, 255}, {170, 146, 255, 255}, + {170, 182, 0, 255}, {170, 182, 85, 255}, {170, 182, 170, 255}, + {170, 182, 255, 255}, {170, 219, 0, 255}, {170, 219, 85, 255}, + {170, 219, 170, 255}, {170, 219, 255, 255}, {170, 255, 0, 255}, + {170, 255, 85, 255}, {170, 255, 170, 255}, {170, 255, 255, 255}, + {255, 0, 0, 255}, {255, 0, 85, 255}, {255, 0, 170, 255}, + {255, 0, 255, 255}, {255, 36, 0, 255}, {255, 36, 85, 255}, + {255, 36, 170, 255}, {255, 36, 255, 255}, {255, 73, 0, 255}, + {255, 73, 85, 255}, {255, 73, 170, 255}, {255, 73, 255, 255}, + {255, 109, 0, 255}, {255, 109, 85, 255}, {255, 109, 170, 255}, + {255, 109, 255, 255}, {255, 146, 0, 255}, {255, 146, 85, 255}, + {255, 146, 170, 255}, {255, 146, 255, 255}, {255, 182, 0, 255}, + {255, 182, 85, 255}, {255, 182, 170, 255}, {255, 182, 255, 255}, + {255, 219, 0, 255}, {255, 219, 85, 255}, {255, 219, 170, 255}, + {255, 219, 255, 255}, {255, 255, 0, 255}, {255, 255, 85, 255}, + {255, 255, 170, 255}, {255, 255, 255, 255}, {0, 0, 0, 255}, + {0, 0, 85, 255}, {0, 0, 170, 255}, {0, 0, 255, 255}, + {0, 36, 0, 255}, {0, 36, 85, 255}, {0, 36, 170, 255}, + {0, 36, 255, 255}, {0, 73, 0, 255}, {0, 73, 85, 255}, + {0, 73, 170, 255}, {0, 73, 255, 255}, {0, 109, 0, 255}, + {0, 109, 85, 255}, {0, 109, 170, 255}, {0, 109, 255, 255}, + {0, 146, 0, 255}, {0, 146, 85, 255}, {0, 146, 170, 255}, + {0, 146, 255, 255}, {0, 182, 0, 255}, {0, 182, 85, 255}, + {0, 182, 170, 255}, {0, 182, 255, 255}, {0, 219, 0, 255}, + {0, 219, 85, 255}, {0, 219, 170, 255}, {0, 219, 255, 255}, + {0, 255, 0, 255}, {0, 255, 85, 255}, {0, 255, 170, 255}, + {0, 255, 255, 255}, {85, 0, 0, 255}, {85, 0, 85, 255}, + {85, 0, 170, 255}, {85, 0, 255, 255}, {85, 36, 0, 255}, + {85, 36, 85, 255}, {85, 36, 170, 255}, {85, 36, 255, 255}, + {85, 73, 0, 255}, {85, 73, 85, 255}, {85, 73, 170, 255}, + {85, 73, 255, 255}, {85, 109, 0, 255}, {85, 109, 85, 255}, + {85, 109, 170, 255}, {85, 109, 255, 255}, {85, 146, 0, 255}, + {85, 146, 85, 255}, {85, 146, 170, 255}, {85, 146, 255, 255}, + {85, 182, 0, 255}, {85, 182, 85, 255}, {85, 182, 170, 255}, + {85, 182, 255, 255}, {85, 219, 0, 255}, {85, 219, 85, 255}, + {85, 219, 170, 255}, {85, 219, 255, 255}, {85, 255, 0, 255}, + {85, 255, 85, 255}, {85, 255, 170, 255}, {85, 255, 255, 255}, + {170, 0, 0, 255}, {170, 0, 85, 255}, {170, 0, 170, 255}, + {170, 0, 255, 255}, {170, 36, 0, 255}, {170, 36, 85, 255}, + {170, 36, 170, 255}, {170, 36, 255, 255}, {170, 73, 0, 255}, + {170, 73, 85, 255}, {170, 73, 170, 255}, {170, 73, 255, 255}, + {170, 109, 0, 255}, {170, 109, 85, 255}, {170, 109, 170, 255}, + {170, 109, 255, 255}, {170, 146, 0, 255}, {170, 146, 85, 255}, + {170, 146, 170, 255}, {170, 146, 255, 255}, {170, 182, 0, 255}, + {170, 182, 85, 255}, {170, 182, 170, 255}, {170, 182, 255, 255}, + {170, 219, 0, 255}, {170, 219, 85, 255}, {170, 219, 170, 255}, + {170, 219, 255, 255}, {170, 255, 0, 255}, {170, 255, 85, 255}, + {170, 255, 170, 255}, {170, 255, 255, 255}, {255, 0, 0, 255}, + {255, 0, 85, 255}, {255, 0, 170, 255}, {255, 0, 255, 255}, + {255, 36, 0, 255}, {255, 36, 85, 255}, {255, 36, 170, 255}, + {255, 36, 255, 255}, {255, 73, 0, 255}, {255, 73, 85, 255}, + {255, 73, 170, 255}, {255, 73, 255, 255}, {255, 109, 0, 255}, + {255, 109, 85, 255}, {255, 109, 170, 255}, {255, 109, 255, 255}, + {255, 146, 0, 255}, {255, 146, 85, 255}, {255, 146, 170, 255}, + {255, 146, 255, 255}, {255, 182, 0, 255}, {255, 182, 85, 255}, + {255, 182, 170, 255}, {255, 182, 255, 255}, {255, 219, 0, 255}, + {255, 219, 85, 255}, {255, 219, 170, 255}, {255, 219, 255, 255}, + {255, 255, 0, 255}, {255, 255, 85, 255}, {255, 255, 170, 255}, + {255, 255, 255, 255}}; + +static const int default_palette_size = + (int)(sizeof(default_palette_colors) / sizeof(SDL_Color)); + +#endif diff --git a/venv/Include/site/python3.9/pygame/pgarrinter.h b/venv/Include/site/python3.9/pygame/pgarrinter.h new file mode 100644 index 0000000..5ba096b --- /dev/null +++ b/venv/Include/site/python3.9/pygame/pgarrinter.h @@ -0,0 +1,26 @@ +/* array structure interface version 3 declarations */ + +#if !defined(PG_ARRAYINTER_HEADER) +#define PG_ARRAYINTER_HEADER + +static const int PAI_CONTIGUOUS = 0x01; +static const int PAI_FORTRAN = 0x02; +static const int PAI_ALIGNED = 0x100; +static const int PAI_NOTSWAPPED = 0x200; +static const int PAI_WRITEABLE = 0x400; +static const int PAI_ARR_HAS_DESCR = 0x800; + +typedef struct { + int two; /* contains the integer 2 -- simple sanity check */ + int nd; /* number of dimensions */ + char typekind; /* kind in array -- character code of typestr */ + int itemsize; /* size of each element */ + int flags; /* flags indicating how the data should be */ + /* interpreted */ + Py_intptr_t *shape; /* A length-nd array of shape information */ + Py_intptr_t *strides; /* A length-nd array of stride information */ + void *data; /* A pointer to the first element of the array */ + PyObject *descr; /* NULL or a data-description */ +} PyArrayInterface; + +#endif diff --git a/venv/Include/site/python3.9/pygame/pgbufferproxy.h b/venv/Include/site/python3.9/pygame/pgbufferproxy.h new file mode 100644 index 0000000..1507608 --- /dev/null +++ b/venv/Include/site/python3.9/pygame/pgbufferproxy.h @@ -0,0 +1,7 @@ +#ifndef PG_BUFPROXY_INTERNAL_H +#define PG_BUFPROXY_INTERNAL_H + +#include "include/pygame_bufferproxy.h" +#define PYGAMEAPI_BUFPROXY_NUMSLOTS 4 + +#endif /* ~PG_BUFPROXY_INTERNAL_H */ diff --git a/venv/Include/site/python3.9/pygame/pgcompat.h b/venv/Include/site/python3.9/pygame/pgcompat.h new file mode 100644 index 0000000..74139b9 --- /dev/null +++ b/venv/Include/site/python3.9/pygame/pgcompat.h @@ -0,0 +1,207 @@ +/* Python 2.x/3.x compatibility tools (internal) + */ +#ifndef PGCOMPAT_INTERNAL_H +#define PGCOMPAT_INTERNAL_H + +#include "include/pgcompat.h" + +#if PY_MAJOR_VERSION >= 3 + +#define PY3 1 + +/* Define some aliases for the removed PyInt_* functions */ +#define PyInt_Check(op) PyLong_Check(op) +#define PyInt_FromString PyLong_FromString +#define PyInt_FromLong PyLong_FromLong +#define PyInt_FromSize_t PyLong_FromSize_t +#define PyInt_FromSsize_t PyLong_FromSsize_t +#define PyInt_AsLong PyLong_AsLong +#define PyInt_AsSsize_t PyLong_AsSsize_t +#define PyInt_AsUnsignedLongMask PyLong_AsUnsignedLongMask +#define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask +#define PyInt_AS_LONG PyLong_AS_LONG +#define PyNumber_Int PyNumber_Long +/* Int and Long are identical in Py3 so only check one */ +#define INT_CHECK(op) PyLong_Check(op) + +/* Weakrefs flags changed in 3.x */ +#define Py_TPFLAGS_HAVE_WEAKREFS 0 + +/* Module init function returns new module instance. */ +#define MODINIT_RETURN(x) return x +#define MODINIT_DEFINE(mod_name) PyMODINIT_FUNC PyInit_##mod_name (void) +#define DECREF_MOD(mod) Py_DECREF (mod) + +/* Text interface. Use unicode strings. */ +#define Text_Type PyUnicode_Type +#define Text_Check PyUnicode_Check + +#ifndef PYPY_VERSION +#define Text_FromLocale(s) PyUnicode_DecodeLocale((s), "strict") +#else /* PYPY_VERSION */ +/* workaround: missing function for pypy */ +#define Text_FromLocale PyUnicode_FromString +#endif /* PYPY_VERSION */ + +#define Text_FromUTF8 PyUnicode_FromString +#define Text_FromUTF8AndSize PyUnicode_FromStringAndSize +#define Text_FromFormat PyUnicode_FromFormat +#define Text_GetSize PyUnicode_GetSize +#define Text_GET_SIZE PyUnicode_GET_SIZE + +/* Binary interface. Use bytes. */ +#define Bytes_Type PyBytes_Type +#define Bytes_Check PyBytes_Check +#define Bytes_Size PyBytes_Size +#define Bytes_AsString PyBytes_AsString +#define Bytes_AsStringAndSize PyBytes_AsStringAndSize +#define Bytes_FromStringAndSize PyBytes_FromStringAndSize +#define Bytes_FromFormat PyBytes_FromFormat +#define Bytes_AS_STRING PyBytes_AS_STRING +#define Bytes_GET_SIZE PyBytes_GET_SIZE +#define Bytes_AsDecodeObject PyBytes_AsDecodedObject + +#define Object_Unicode PyObject_Str + +#define IsTextObj(x) (PyUnicode_Check(x) || PyBytes_Check(x)) + +/* Renamed builtins */ +#define BUILTINS_MODULE "builtins" +#define BUILTINS_UNICODE "str" +#define BUILTINS_UNICHR "chr" + +/* Defaults for unicode file path encoding */ +#define UNICODE_DEF_FS_CODEC Py_FileSystemDefaultEncoding +#if defined(MS_WIN32) +#define UNICODE_DEF_FS_ERROR "replace" +#else +#define UNICODE_DEF_FS_ERROR "surrogateescape" +#endif + +#else /* #if PY_MAJOR_VERSION >= 3 */ + +#define PY3 0 + +/* Check both Int and Long in PY2 */ +#define INT_CHECK(op) (PyInt_Check(op) || PyLong_Check(op)) + +/* Module init function returns nothing. */ +#define MODINIT_RETURN(x) return +#define MODINIT_DEFINE(mod_name) PyMODINIT_FUNC init##mod_name (void) +#define DECREF_MOD(mod) + +/* Text interface. Use ascii strings. */ +#define Text_Type PyString_Type +#define Text_Check PyString_Check +#define Text_FromLocale PyString_FromString +#define Text_FromUTF8 PyString_FromString +#define Text_FromUTF8AndSize PyString_FromStringAndSize +#define Text_FromFormat PyString_FromFormat +#define Text_GetSize PyString_GetSize +#define Text_GET_SIZE PyString_GET_SIZE + +/* Binary interface. Use ascii strings. */ +#define Bytes_Type PyString_Type +#define Bytes_Check PyString_Check +#define Bytes_Size PyString_Size +#define Bytes_AsString PyString_AsString +#define Bytes_AsStringAndSize PyString_AsStringAndSize +#define Bytes_FromStringAndSize PyString_FromStringAndSize +#define Bytes_FromFormat PyString_FromFormat +#define Bytes_AS_STRING PyString_AS_STRING +#define Bytes_GET_SIZE PyString_GET_SIZE +#define Bytes_AsDecodedObject PyString_AsDecodedObject + +#define Object_Unicode PyObject_Unicode + +/* Renamed builtins */ +#define BUILTINS_MODULE "__builtin__" +#define BUILTINS_UNICODE "unicode" +#define BUILTINS_UNICHR "unichr" + +/* Defaults for unicode file path encoding */ +#define UNICODE_DEF_FS_CODEC Py_FileSystemDefaultEncoding +#define UNICODE_DEF_FS_ERROR "strict" + +#endif /* #if PY_MAJOR_VERSION >= 3 */ + +#define PY2 (!PY3) + +#define MODINIT_ERROR MODINIT_RETURN (NULL) + +/* Module state. These macros are used to define per-module macros. + * v - global state variable (Python 2.x) + * s - global state structure (Python 3.x) + */ +#define PY2_GETSTATE(v) (&(v)) +#define PY3_GETSTATE(s, m) ((struct s *) PyModule_GetState (m)) + +/* Pep 3123: Making PyObject_HEAD conform to standard C */ +#if !defined(Py_TYPE) +#define Py_TYPE(o) (((PyObject *)(o))->ob_type) +#define Py_REFCNT(o) (((PyObject *)(o))->ob_refcnt) +#define Py_SIZE(o) (((PyVarObject *)(o))->ob_size) +#endif + +/* Encode a unicode file path */ +#define Unicode_AsEncodedPath(u) \ + PyUnicode_AsEncodedString ((u), UNICODE_DEF_FS_CODEC, UNICODE_DEF_FS_ERROR) + +#define RELATIVE_MODULE(m) ("." m) + +#define HAVE_OLD_BUFPROTO PY2 + +#if !defined(PG_ENABLE_OLDBUF) /* allow for command line override */ +#if HAVE_OLD_BUFPROTO +#define PG_ENABLE_OLDBUF 1 +#else +#define PG_ENABLE_OLDBUF 0 +#endif +#endif + +#ifndef Py_TPFLAGS_HAVE_NEWBUFFER +#define Py_TPFLAGS_HAVE_NEWBUFFER 0 +#endif + +#ifndef Py_TPFLAGS_HAVE_CLASS +#define Py_TPFLAGS_HAVE_CLASS 0 +#endif + +#ifndef Py_TPFLAGS_CHECKTYPES +#define Py_TPFLAGS_CHECKTYPES 0 +#endif + +#if PY_VERSION_HEX >= 0x03020000 +#define Slice_GET_INDICES_EX(slice, length, start, stop, step, slicelength) \ + PySlice_GetIndicesEx(slice, length, start, stop, step, slicelength) +#else +#define Slice_GET_INDICES_EX(slice, length, start, stop, step, slicelength) \ + PySlice_GetIndicesEx((PySliceObject *)(slice), length, \ + start, stop, step, slicelength) +#endif + +#if defined(SDL_VERSION_ATLEAST) +#if (SDL_VERSION_ATLEAST(2, 0, 0)) && !(SDL_VERSION_ATLEAST(2, 0, 5)) +/* These functions require SDL 2.0.5 or greater. + + https://wiki.libsdl.org/SDL_SetWindowResizable +*/ +void SDL_SetWindowResizable(SDL_Window *window, SDL_bool resizable); +int SDL_GetWindowOpacity(SDL_Window *window, float *opacity); +int SDL_SetWindowOpacity(SDL_Window *window, float opacity); +int SDL_SetWindowModalFor(SDL_Window *modal_window, SDL_Window *parent_window); +int SDL_SetWindowInputFocus(SDL_Window *window); +SDL_Surface * SDL_CreateRGBSurfaceWithFormat(Uint32 flags, int width, int height, int depth, + Uint32 format); +#endif +#endif /* defined(SDL_VERSION_ATLEAST) */ + +// Currently needed to build scrap.c, event.c, display.c +// with Windows SDK 10.0.18362.0 and SDL1 build +#ifdef _MSC_VER + #ifndef WINDOWS_IGNORE_PACKING_MISMATCH + #define WINDOWS_IGNORE_PACKING_MISMATCH + #endif +#endif + +#endif /* ~PGCOMPAT_INTERNAL_H */ diff --git a/venv/Include/site/python3.9/pygame/pgimport.h b/venv/Include/site/python3.9/pygame/pgimport.h new file mode 100644 index 0000000..34654c9 --- /dev/null +++ b/venv/Include/site/python3.9/pygame/pgimport.h @@ -0,0 +1,13 @@ +#ifndef PGIMPORT_INTERNAL_H +#define PGIMPORT_INTERNAL_H + +#include "include/pgimport.h" + +#if PG_HAVE_CAPSULE +#define encapsulate_api(ptr, module) \ + PyCapsule_New(ptr, PG_CAPSULE_NAME(module), NULL) +#else /* ~PG_HAVE_CAPSULE */ +#define encapsulate_api(ptr, module) PyCObject_FromVoidPtr(ptr, NULL) +#endif /* ~PG_HAVE_CAPSULE */ + +#endif /* PGIMPORT_INTERNAL_H */ diff --git a/venv/Include/site/python3.9/pygame/pgopengl.h b/venv/Include/site/python3.9/pygame/pgopengl.h new file mode 100644 index 0000000..6440f32 --- /dev/null +++ b/venv/Include/site/python3.9/pygame/pgopengl.h @@ -0,0 +1,18 @@ +#if !defined(PGOPENGL_H) +#define PGOPENGL_H + +/** This header includes definitions of Opengl functions as pointer types for + ** use with the SDL function SDL_GL_GetProcAddress. + **/ + +#if defined(_WIN32) +#define GL_APIENTRY __stdcall +#else +#define GL_APIENTRY +#endif + +typedef void (GL_APIENTRY *GL_glReadPixels_Func)(int, int, int, int, unsigned int, unsigned int, void*); + +typedef void (GL_APIENTRY *GL_glViewport_Func)(int, int, unsigned int, unsigned int); +#endif + diff --git a/venv/Include/site/python3.9/pygame/pgplatform.h b/venv/Include/site/python3.9/pygame/pgplatform.h new file mode 100644 index 0000000..2d5ed86 --- /dev/null +++ b/venv/Include/site/python3.9/pygame/pgplatform.h @@ -0,0 +1,38 @@ +/* platform/compiler adjustments (internal) */ +#ifndef PG_PLATFORM_INTERNAL_H +#define PG_PLATFORM_INTERNAL_H + +/* This must be before all else */ +#if defined(__SYMBIAN32__) && defined(OPENC) +#include +#if defined(__WINS__) +void * +_alloca(size_t size); +#define alloca _alloca +#endif /* __WINS__ */ +#endif /* defined(__SYMBIAN32__) && defined(OPENC) */ + +#include "include/pgplatform.h" + +#ifndef MIN +#define MIN(a, b) ((a) < (b) ? (a) : (b)) +#endif +#ifndef MAX +#define MAX(a, b) ((a) > (b) ? (a) : (b)) +#endif +#ifndef ABS +#define ABS(a) (((a) < 0) ? -(a) : (a)) +#endif + +#if defined(macintosh) && defined(__MWERKS__) || defined(__SYMBIAN32__) +#define PYGAME_EXPORT __declspec(export) +#else +#define PYGAME_EXPORT +#endif + +/* warnings */ +#define PG_STRINGIZE_HELPER(x) #x +#define PG_STRINGIZE(x) PG_STRINGIZE_HELPER(x) +#define PG_WARN(desc) message(__FILE__ "(" PG_STRINGIZE(__LINE__) "): WARNING: " #desc) + +#endif /* ~PG_PLATFORM_INTERNAL_H */ diff --git a/venv/Include/site/python3.9/pygame/pygame.h b/venv/Include/site/python3.9/pygame/pygame.h new file mode 100644 index 0000000..d7eaf73 --- /dev/null +++ b/venv/Include/site/python3.9/pygame/pygame.h @@ -0,0 +1,32 @@ +/* + pygame - Python Game Library + Copyright (C) 2000-2001 Pete Shinners + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Pete Shinners + pete@shinners.org +*/ + +/* This will use PYGAMEAPI_DEFINE_SLOTS instead + * of PYGAMEAPI_EXTERN_SLOTS for base modules. + */ +#ifndef PYGAME_INTERNAL_H +#define PYGAME_INTERNAL_H + +#define PYGAME_H +#include "_pygame.h" + +#endif /* ~PYGAME_INTERNAL_H */ diff --git a/venv/Include/site/python3.9/pygame/scrap.h b/venv/Include/site/python3.9/pygame/scrap.h new file mode 100644 index 0000000..725f22f --- /dev/null +++ b/venv/Include/site/python3.9/pygame/scrap.h @@ -0,0 +1,148 @@ +/* + pygame - Python Game Library + Copyright (C) 2006, 2007 Rene Dudfield, Marcus von Appen + + Originally put in the public domain by Sam Lantinga. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef SCRAP_H +#define SCRAP_H + +/* This is unconditionally defined in Python.h */ +#if defined(_POSIX_C_SOURCE) +#undef _POSIX_C_SOURCE +#endif + +#include + +/* Handle clipboard text and data in arbitrary formats */ + +/** + * Predefined supported pygame scrap types. + */ +#define PYGAME_SCRAP_TEXT "text/plain" +#define PYGAME_SCRAP_BMP "image/bmp" +#define PYGAME_SCRAP_PPM "image/ppm" +#define PYGAME_SCRAP_PBM "image/pbm" + +/** + * The supported scrap clipboard types. + * + * This is only relevant in a X11 environment, which supports mouse + * selections as well. For Win32 and MacOS environments the default + * clipboard is used, no matter what value is passed. + */ +typedef enum +{ + SCRAP_CLIPBOARD, + SCRAP_SELECTION /* only supported in X11 environments. */ +} ScrapClipType; + +/** + * Macro for initialization checks. + */ +#define PYGAME_SCRAP_INIT_CHECK() \ + if(!pygame_scrap_initialized()) \ + return (PyErr_SetString (pgExc_SDLError, \ + "scrap system not initialized."), NULL) + +/** + * \brief Checks, whether the pygame scrap module was initialized. + * + * \return 1 if the modules was initialized, 0 otherwise. + */ +extern int +pygame_scrap_initialized (void); + +/** + * \brief Initializes the pygame scrap module internals. Call this before any + * other method. + * + * \return 1 on successful initialization, 0 otherwise. + */ +extern int +pygame_scrap_init (void); + +/** + * \brief Checks, whether the pygame window lost the clipboard focus or not. + * + * \return 1 if the window lost the focus, 0 otherwise. + */ +extern int +pygame_scrap_lost (void); + +/** + * \brief Places content of a specific type into the clipboard. + * + * \note For X11 the following notes are important: The following types + * are reserved for internal usage and thus will throw an error on + * setting them: "TIMESTAMP", "TARGETS", "SDL_SELECTION". + * Setting PYGAME_SCRAP_TEXT ("text/plain") will also automatically + * set the X11 types "STRING" (XA_STRING), "TEXT" and "UTF8_STRING". + * + * For Win32 the following notes are important: Setting + * PYGAME_SCRAP_TEXT ("text/plain") will also automatically set + * the Win32 type "TEXT" (CF_TEXT). + * + * For QNX the following notes are important: Setting + * PYGAME_SCRAP_TEXT ("text/plain") will also automatically set + * the QNX type "TEXT" (Ph_CL_TEXT). + * + * \param type The type of the content. + * \param srclen The length of the content. + * \param src The NULL terminated content. + * \return 1, if the content could be successfully pasted into the clipboard, + * 0 otherwise. + */ +extern int +pygame_scrap_put (char *type, int srclen, char *src); + +/** + * \brief Gets the current content from the clipboard. + * + * \note The received content does not need to be the content previously + * placed in the clipboard using pygame_put_scrap(). See the + * pygame_put_scrap() notes for more details. + * + * \param type The type of the content to receive. + * \param count The size of the returned content. + * \return The content or NULL in case of an error or if no content of the + * specified type was available. + */ +extern char* +pygame_scrap_get (char *type, unsigned long *count); + +/** + * \brief Gets the currently available content types from the clipboard. + * + * \return The different available content types or NULL in case of an + * error or if no content type is available. + */ +extern char** +pygame_scrap_get_types (void); + +/** + * \brief Checks whether content for the specified scrap type is currently + * available in the clipboard. + * + * \param type The type to check for. + * \return 1, if there is content and 0 otherwise. + */ +extern int +pygame_scrap_contains (char *type); + +#endif /* SCRAP_H */ diff --git a/venv/Include/site/python3.9/pygame/surface.h b/venv/Include/site/python3.9/pygame/surface.h new file mode 100644 index 0000000..bbd7f28 --- /dev/null +++ b/venv/Include/site/python3.9/pygame/surface.h @@ -0,0 +1,384 @@ +/* + pygame - Python Game Library + Copyright (C) 2000-2001 Pete Shinners + Copyright (C) 2007 Marcus von Appen + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Pete Shinners + pete@shinners.org +*/ + +#ifndef SURFACE_H +#define SURFACE_H + +/* This is defined in SDL.h */ +#if defined(_POSIX_C_SOURCE) +#undef _POSIX_C_SOURCE +#endif + +#include +#include "pygame.h" + +/* Blend modes */ +#define PYGAME_BLEND_ADD 0x1 +#define PYGAME_BLEND_SUB 0x2 +#define PYGAME_BLEND_MULT 0x3 +#define PYGAME_BLEND_MIN 0x4 +#define PYGAME_BLEND_MAX 0x5 + +#define PYGAME_BLEND_RGB_ADD 0x1 +#define PYGAME_BLEND_RGB_SUB 0x2 +#define PYGAME_BLEND_RGB_MULT 0x3 +#define PYGAME_BLEND_RGB_MIN 0x4 +#define PYGAME_BLEND_RGB_MAX 0x5 + +#define PYGAME_BLEND_RGBA_ADD 0x6 +#define PYGAME_BLEND_RGBA_SUB 0x7 +#define PYGAME_BLEND_RGBA_MULT 0x8 +#define PYGAME_BLEND_RGBA_MIN 0x9 +#define PYGAME_BLEND_RGBA_MAX 0x10 +#define PYGAME_BLEND_PREMULTIPLIED 0x11 +#define PYGAME_BLEND_ALPHA_SDL2 0x12 + + + + + +#if SDL_BYTEORDER == SDL_LIL_ENDIAN +#define GET_PIXEL_24(b) (b[0] + (b[1] << 8) + (b[2] << 16)) +#else +#define GET_PIXEL_24(b) (b[2] + (b[1] << 8) + (b[0] << 16)) +#endif + +#define GET_PIXEL(pxl, bpp, source) \ + switch (bpp) \ + { \ + case 2: \ + pxl = *((Uint16 *) (source)); \ + break; \ + case 4: \ + pxl = *((Uint32 *) (source)); \ + break; \ + default: \ + { \ + Uint8 *b = (Uint8 *) source; \ + pxl = GET_PIXEL_24(b); \ + } \ + break; \ + } + +#if IS_SDLv1 +#define GET_PIXELVALS(_sR, _sG, _sB, _sA, px, fmt, ppa) \ + _sR = ((px & fmt->Rmask) >> fmt->Rshift); \ + _sR = (_sR << fmt->Rloss) + (_sR >> (8 - (fmt->Rloss << 1))); \ + _sG = ((px & fmt->Gmask) >> fmt->Gshift); \ + _sG = (_sG << fmt->Gloss) + (_sG >> (8 - (fmt->Gloss << 1))); \ + _sB = ((px & fmt->Bmask) >> fmt->Bshift); \ + _sB = (_sB << fmt->Bloss) + (_sB >> (8 - (fmt->Bloss << 1))); \ + if (ppa) \ + { \ + _sA = ((px & fmt->Amask) >> fmt->Ashift); \ + _sA = (_sA << fmt->Aloss) + (_sA >> (8 - (fmt->Aloss << 1))); \ + } \ + else \ + { \ + _sA = 255; \ + } + +#define GET_PIXELVALS_1(sr, sg, sb, sa, _src, _fmt) \ + sr = _fmt->palette->colors[*((Uint8 *) (_src))].r; \ + sg = _fmt->palette->colors[*((Uint8 *) (_src))].g; \ + sb = _fmt->palette->colors[*((Uint8 *) (_src))].b; \ + sa = 255; + +/* For 1 byte palette pixels */ +#define SET_PIXELVAL(px, fmt, _dR, _dG, _dB, _dA) \ + *(px) = (Uint8) SDL_MapRGB(fmt, _dR, _dG, _dB) +#else /* IS_SDLv2 */ +#define GET_PIXELVALS(_sR, _sG, _sB, _sA, px, fmt, ppa) \ + SDL_GetRGBA(px, fmt, &(_sR), &(_sG), &(_sB), &(_sA)); \ + if (!ppa) { \ + _sA = 255; \ + } + +#define GET_PIXELVALS_1(sr, sg, sb, sa, _src, _fmt) \ + sr = _fmt->palette->colors[*((Uint8 *) (_src))].r; \ + sg = _fmt->palette->colors[*((Uint8 *) (_src))].g; \ + sb = _fmt->palette->colors[*((Uint8 *) (_src))].b; \ + sa = 255; + +/* For 1 byte palette pixels */ +#define SET_PIXELVAL(px, fmt, _dR, _dG, _dB, _dA) \ + *(px) = (Uint8) SDL_MapRGBA(fmt, _dR, _dG, _dB, _dA) +#endif /* IS_SDLv2 */ + + + + + + + + +#if SDL_BYTEORDER == SDL_LIL_ENDIAN +#define SET_OFFSETS_24(or, og, ob, fmt) \ + { \ + or = (fmt->Rshift == 0 ? 0 : \ + fmt->Rshift == 8 ? 1 : \ + 2 ); \ + og = (fmt->Gshift == 0 ? 0 : \ + fmt->Gshift == 8 ? 1 : \ + 2 ); \ + ob = (fmt->Bshift == 0 ? 0 : \ + fmt->Bshift == 8 ? 1 : \ + 2 ); \ + } + +#define SET_OFFSETS_32(or, og, ob, fmt) \ + { \ + or = (fmt->Rshift == 0 ? 0 : \ + fmt->Rshift == 8 ? 1 : \ + fmt->Rshift == 16 ? 2 : \ + 3 ); \ + og = (fmt->Gshift == 0 ? 0 : \ + fmt->Gshift == 8 ? 1 : \ + fmt->Gshift == 16 ? 2 : \ + 3 ); \ + ob = (fmt->Bshift == 0 ? 0 : \ + fmt->Bshift == 8 ? 1 : \ + fmt->Bshift == 16 ? 2 : \ + 3 ); \ + } +#else +#define SET_OFFSETS_24(or, og, ob, fmt) \ + { \ + or = (fmt->Rshift == 0 ? 2 : \ + fmt->Rshift == 8 ? 1 : \ + 0 ); \ + og = (fmt->Gshift == 0 ? 2 : \ + fmt->Gshift == 8 ? 1 : \ + 0 ); \ + ob = (fmt->Bshift == 0 ? 2 : \ + fmt->Bshift == 8 ? 1 : \ + 0 ); \ + } + +#define SET_OFFSETS_32(or, og, ob, fmt) \ + { \ + or = (fmt->Rshift == 0 ? 3 : \ + fmt->Rshift == 8 ? 2 : \ + fmt->Rshift == 16 ? 1 : \ + 0 ); \ + og = (fmt->Gshift == 0 ? 3 : \ + fmt->Gshift == 8 ? 2 : \ + fmt->Gshift == 16 ? 1 : \ + 0 ); \ + ob = (fmt->Bshift == 0 ? 3 : \ + fmt->Bshift == 8 ? 2 : \ + fmt->Bshift == 16 ? 1 : \ + 0 ); \ + } +#endif + + +#define CREATE_PIXEL(buf, r, g, b, a, bp, ft) \ + switch (bp) \ + { \ + case 2: \ + *((Uint16 *) (buf)) = \ + ((r >> ft->Rloss) << ft->Rshift) | \ + ((g >> ft->Gloss) << ft->Gshift) | \ + ((b >> ft->Bloss) << ft->Bshift) | \ + ((a >> ft->Aloss) << ft->Ashift); \ + break; \ + case 4: \ + *((Uint32 *) (buf)) = \ + ((r >> ft->Rloss) << ft->Rshift) | \ + ((g >> ft->Gloss) << ft->Gshift) | \ + ((b >> ft->Bloss) << ft->Bshift) | \ + ((a >> ft->Aloss) << ft->Ashift); \ + break; \ + } + +/* Pretty good idea from Tom Duff :-). */ +#define LOOP_UNROLLED4(code, n, width) \ + n = (width + 3) / 4; \ + switch (width & 3) \ + { \ + case 0: do { code; \ + case 3: code; \ + case 2: code; \ + case 1: code; \ + } while (--n > 0); \ + } + +/* Used in the srcbpp == dstbpp == 1 blend functions */ +#define REPEAT_3(code) \ + code; \ + code; \ + code; + +#define REPEAT_4(code) \ + code; \ + code; \ + code; \ + code; + + +#define BLEND_ADD(tmp, sR, sG, sB, sA, dR, dG, dB, dA) \ + tmp = dR + sR; dR = (tmp <= 255 ? tmp : 255); \ + tmp = dG + sG; dG = (tmp <= 255 ? tmp : 255); \ + tmp = dB + sB; dB = (tmp <= 255 ? tmp : 255); + +#define BLEND_SUB(tmp, sR, sG, sB, sA, dR, dG, dB, dA) \ + tmp = dR - sR; dR = (tmp >= 0 ? tmp : 0); \ + tmp = dG - sG; dG = (tmp >= 0 ? tmp : 0); \ + tmp = dB - sB; dB = (tmp >= 0 ? tmp : 0); + +#define BLEND_MULT(sR, sG, sB, sA, dR, dG, dB, dA) \ + dR = (dR && sR) ? (dR * sR) >> 8 : 0; \ + dG = (dG && sG) ? (dG * sG) >> 8 : 0; \ + dB = (dB && sB) ? (dB * sB) >> 8 : 0; + +#define BLEND_MIN(sR, sG, sB, sA, dR, dG, dB, dA) \ + if(sR < dR) { dR = sR; } \ + if(sG < dG) { dG = sG; } \ + if(sB < dB) { dB = sB; } + +#define BLEND_MAX(sR, sG, sB, sA, dR, dG, dB, dA) \ + if(sR > dR) { dR = sR; } \ + if(sG > dG) { dG = sG; } \ + if(sB > dB) { dB = sB; } + + + + + + +#define BLEND_RGBA_ADD(tmp, sR, sG, sB, sA, dR, dG, dB, dA) \ + tmp = dR + sR; dR = (tmp <= 255 ? tmp : 255); \ + tmp = dG + sG; dG = (tmp <= 255 ? tmp : 255); \ + tmp = dB + sB; dB = (tmp <= 255 ? tmp : 255); \ + tmp = dA + sA; dA = (tmp <= 255 ? tmp : 255); + +#define BLEND_RGBA_SUB(tmp, sR, sG, sB, sA, dR, dG, dB, dA) \ + tmp = dR - sR; dR = (tmp >= 0 ? tmp : 0); \ + tmp = dG - sG; dG = (tmp >= 0 ? tmp : 0); \ + tmp = dB - sB; dB = (tmp >= 0 ? tmp : 0); \ + tmp = dA - sA; dA = (tmp >= 0 ? tmp : 0); + +#define BLEND_RGBA_MULT(sR, sG, sB, sA, dR, dG, dB, dA) \ + dR = (dR && sR) ? (dR * sR) >> 8 : 0; \ + dG = (dG && sG) ? (dG * sG) >> 8 : 0; \ + dB = (dB && sB) ? (dB * sB) >> 8 : 0; \ + dA = (dA && sA) ? (dA * sA) >> 8 : 0; + +#define BLEND_RGBA_MIN(sR, sG, sB, sA, dR, dG, dB, dA) \ + if(sR < dR) { dR = sR; } \ + if(sG < dG) { dG = sG; } \ + if(sB < dB) { dB = sB; } \ + if(sA < dA) { dA = sA; } + +#define BLEND_RGBA_MAX(sR, sG, sB, sA, dR, dG, dB, dA) \ + if(sR > dR) { dR = sR; } \ + if(sG > dG) { dG = sG; } \ + if(sB > dB) { dB = sB; } \ + if(sA > dA) { dA = sA; } + + + + + + + + + + + +#if 1 +/* Choose an alpha blend equation. If the sign is preserved on a right shift + * then use a specialized, faster, equation. Otherwise a more general form, + * where all additions are done before the shift, is needed. +*/ +#if (-1 >> 1) < 0 +#define ALPHA_BLEND_COMP(sC, dC, sA) ((((sC - dC) * sA + sC) >> 8) + dC) +#else +#define ALPHA_BLEND_COMP(sC, dC, sA) (((dC << 8) + (sC - dC) * sA + sC) >> 8) +#endif + +#define ALPHA_BLEND(sR, sG, sB, sA, dR, dG, dB, dA) \ + do { \ + if (dA) \ + { \ + dR = ALPHA_BLEND_COMP(sR, dR, sA); \ + dG = ALPHA_BLEND_COMP(sG, dG, sA); \ + dB = ALPHA_BLEND_COMP(sB, dB, sA); \ + dA = sA + dA - ((sA * dA) / 255); \ + } \ + else \ + { \ + dR = sR; \ + dG = sG; \ + dB = sB; \ + dA = sA; \ + } \ + } while(0) + +#define ALPHA_BLEND_PREMULTIPLIED_COMP(sC, dC, sA) (sC + dC - ((dC + 1) * sA >> 8)) + +#define ALPHA_BLEND_PREMULTIPLIED(tmp, sR, sG, sB, sA, dR, dG, dB, dA) \ + do { \ + dR = ALPHA_BLEND_PREMULTIPLIED_COMP(sR, dR, sA); \ + dG = ALPHA_BLEND_PREMULTIPLIED_COMP(sG, dG, sA); \ + dB = ALPHA_BLEND_PREMULTIPLIED_COMP(sB, dB, sA); \ + dA = ALPHA_BLEND_PREMULTIPLIED_COMP(sA, dA, sA); \ + } while(0) +#elif 0 + +#define ALPHA_BLEND(sR, sG, sB, sA, dR, dG, dB, dA) \ + do { \ + if(sA){ \ + if(dA && sA < 255){ \ + int dContrib = dA*(255 - sA)/255; \ + dA = sA+dA - ((sA*dA)/255); \ + dR = (dR*dContrib + sR*sA)/dA; \ + dG = (dG*dContrib + sG*sA)/dA; \ + dB = (dB*dContrib + sB*sA)/dA; \ + }else{ \ + dR = sR; \ + dG = sG; \ + dB = sB; \ + dA = sA; \ + } \ + } \ + } while(0) +#endif + +int +surface_fill_blend (SDL_Surface *surface, SDL_Rect *rect, Uint32 color, + int blendargs); + +void +surface_respect_clip_rect (SDL_Surface *surface, SDL_Rect *rect); + +int +pygame_AlphaBlit (SDL_Surface * src, SDL_Rect * srcrect, + SDL_Surface * dst, SDL_Rect * dstrect, int the_args); + +int +pygame_Blit (SDL_Surface * src, SDL_Rect * srcrect, + SDL_Surface * dst, SDL_Rect * dstrect, int the_args); + +#endif /* SURFACE_H */ diff --git a/venv/Lib/site-packages/_distutils_hack/__init__.py b/venv/Lib/site-packages/_distutils_hack/__init__.py new file mode 100644 index 0000000..47ce249 --- /dev/null +++ b/venv/Lib/site-packages/_distutils_hack/__init__.py @@ -0,0 +1,128 @@ +import sys +import os +import re +import importlib +import warnings + + +is_pypy = '__pypy__' in sys.builtin_module_names + + +warnings.filterwarnings('ignore', + '.+ distutils .+ deprecated', + DeprecationWarning) + + +def warn_distutils_present(): + if 'distutils' not in sys.modules: + return + if is_pypy and sys.version_info < (3, 7): + # PyPy for 3.6 unconditionally imports distutils, so bypass the warning + # https://foss.heptapod.net/pypy/pypy/-/blob/be829135bc0d758997b3566062999ee8b23872b4/lib-python/3/site.py#L250 + return + warnings.warn( + "Distutils was imported before Setuptools, but importing Setuptools " + "also replaces the `distutils` module in `sys.modules`. This may lead " + "to undesirable behaviors or errors. To avoid these issues, avoid " + "using distutils directly, ensure that setuptools is installed in the " + "traditional way (e.g. not an editable install), and/or make sure " + "that setuptools is always imported before distutils.") + + +def clear_distutils(): + if 'distutils' not in sys.modules: + return + warnings.warn("Setuptools is replacing distutils.") + mods = [name for name in sys.modules if re.match(r'distutils\b', name)] + for name in mods: + del sys.modules[name] + + +def enabled(): + """ + Allow selection of distutils by environment variable. + """ + which = os.environ.get('SETUPTOOLS_USE_DISTUTILS', 'stdlib') + return which == 'local' + + +def ensure_local_distutils(): + clear_distutils() + distutils = importlib.import_module('setuptools._distutils') + distutils.__name__ = 'distutils' + sys.modules['distutils'] = distutils + + # sanity check that submodules load as expected + core = importlib.import_module('distutils.core') + assert '_distutils' in core.__file__, core.__file__ + + +def do_override(): + """ + Ensure that the local copy of distutils is preferred over stdlib. + + See https://github.com/pypa/setuptools/issues/417#issuecomment-392298401 + for more motivation. + """ + if enabled(): + warn_distutils_present() + ensure_local_distutils() + + +class DistutilsMetaFinder: + def find_spec(self, fullname, path, target=None): + if path is not None: + return + + method_name = 'spec_for_{fullname}'.format(**locals()) + method = getattr(self, method_name, lambda: None) + return method() + + def spec_for_distutils(self): + import importlib.abc + import importlib.util + + class DistutilsLoader(importlib.abc.Loader): + + def create_module(self, spec): + return importlib.import_module('setuptools._distutils') + + def exec_module(self, module): + pass + + return importlib.util.spec_from_loader('distutils', DistutilsLoader()) + + def spec_for_pip(self): + """ + Ensure stdlib distutils when running under pip. + See pypa/pip#8761 for rationale. + """ + if self.pip_imported_during_build(): + return + clear_distutils() + self.spec_for_distutils = lambda: None + + @staticmethod + def pip_imported_during_build(): + """ + Detect if pip is being imported in a build script. Ref #2355. + """ + import traceback + return any( + frame.f_globals['__file__'].endswith('setup.py') + for frame, line in traceback.walk_stack(None) + ) + + +DISTUTILS_FINDER = DistutilsMetaFinder() + + +def add_shim(): + sys.meta_path.insert(0, DISTUTILS_FINDER) + + +def remove_shim(): + try: + sys.meta_path.remove(DISTUTILS_FINDER) + except ValueError: + pass diff --git a/venv/Lib/site-packages/_distutils_hack/override.py b/venv/Lib/site-packages/_distutils_hack/override.py new file mode 100644 index 0000000..2cc433a --- /dev/null +++ b/venv/Lib/site-packages/_distutils_hack/override.py @@ -0,0 +1 @@ +__import__('_distutils_hack').do_override() diff --git a/venv/Lib/site-packages/distutils-precedence.pth b/venv/Lib/site-packages/distutils-precedence.pth new file mode 100644 index 0000000..6de4198 --- /dev/null +++ b/venv/Lib/site-packages/distutils-precedence.pth @@ -0,0 +1 @@ +import os; var = 'SETUPTOOLS_USE_DISTUTILS'; enabled = os.environ.get(var, 'stdlib') == 'local'; enabled and __import__('_distutils_hack').add_shim(); diff --git a/venv/Lib/site-packages/numpy-1.20.2.dist-info/INSTALLER b/venv/Lib/site-packages/numpy-1.20.2.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/venv/Lib/site-packages/numpy-1.20.2.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/venv/Lib/site-packages/numpy-1.20.2.dist-info/LICENSE.txt b/venv/Lib/site-packages/numpy-1.20.2.dist-info/LICENSE.txt new file mode 100644 index 0000000..04619f5 --- /dev/null +++ b/venv/Lib/site-packages/numpy-1.20.2.dist-info/LICENSE.txt @@ -0,0 +1,938 @@ + +---- + +This binary distribution of NumPy also bundles the following software: + + +Name: OpenBLAS +Files: extra-dll\libopenb*.dll +Description: bundled as a dynamically linked library +Availability: https://github.com/xianyi/OpenBLAS/ +License: 3-clause BSD + Copyright (c) 2011-2014, The OpenBLAS Project + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + 3. Neither the name of the OpenBLAS project nor the names of + its contributors may be used to endorse or promote products + derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +Name: LAPACK +Files: extra-dll\libopenb*.dll +Description: bundled in OpenBLAS +Availability: https://github.com/xianyi/OpenBLAS/ +License 3-clause BSD + Copyright (c) 1992-2013 The University of Tennessee and The University + of Tennessee Research Foundation. All rights + reserved. + Copyright (c) 2000-2013 The University of California Berkeley. All + rights reserved. + Copyright (c) 2006-2013 The University of Colorado Denver. All rights + reserved. + + $COPYRIGHT$ + + Additional copyrights may follow + + $HEADER$ + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer listed + in this license in the documentation and/or other materials + provided with the distribution. + + - Neither the name of the copyright holders nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + The copyright holders provide no reassurances that the source code + provided does not infringe any patent, copyright, or any other + intellectual property rights of third parties. The copyright holders + disclaim any liability to any recipient for claims brought against + recipient by any third party for infringement of that parties + intellectual property rights. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +Name: GCC runtime library +Files: extra-dll\*.dll +Description: statically linked, in DLL files compiled with gfortran only +Availability: https://gcc.gnu.org/viewcvs/gcc/ +License: GPLv3 + runtime exception + Copyright (C) 2002-2017 Free Software Foundation, Inc. + + Libgfortran is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + Libgfortran is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + Under Section 7 of GPL version 3, you are granted additional + permissions described in the GCC Runtime Library Exception, version + 3.1, as published by the Free Software Foundation. + + You should have received a copy of the GNU General Public License and + a copy of the GCC Runtime Library Exception along with this program; + see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + . + + +Name: Microsoft Visual C++ Runtime Files +Files: extra-dll\msvcp140.dll +License: MSVC + https://www.visualstudio.com/license-terms/distributable-code-microsoft-visual-studio-2015-rc-microsoft-visual-studio-2015-sdk-rc-includes-utilities-buildserver-files/#visual-c-runtime + + Subject to the License Terms for the software, you may copy and + distribute with your program any of the files within the followng + folder and its subfolders except as noted below. You may not modify + these files. + + C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\redist + + You may not distribute the contents of the following folders: + + C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\redist\debug_nonredist + C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\redist\onecore\debug_nonredist + + Subject to the License Terms for the software, you may copy and + distribute the following files with your program in your program’s + application local folder or by deploying them into the Global + Assembly Cache (GAC): + + VC\atlmfc\lib\mfcmifc80.dll + VC\atlmfc\lib\amd64\mfcmifc80.dll + + +Name: Microsoft Visual C++ Runtime Files +Files: extra-dll\msvc*90.dll, extra-dll\Microsoft.VC90.CRT.manifest +License: MSVC + For your convenience, we have provided the following folders for + use when redistributing VC++ runtime files. Subject to the license + terms for the software, you may redistribute the folder + (unmodified) in the application local folder as a sub-folder with + no change to the folder name. You may also redistribute all the + files (*.dll and *.manifest) within a folder, listed below the + folder for your convenience, as an entire set. + + \VC\redist\x86\Microsoft.VC90.ATL\ + atl90.dll + Microsoft.VC90.ATL.manifest + \VC\redist\ia64\Microsoft.VC90.ATL\ + atl90.dll + Microsoft.VC90.ATL.manifest + \VC\redist\amd64\Microsoft.VC90.ATL\ + atl90.dll + Microsoft.VC90.ATL.manifest + \VC\redist\x86\Microsoft.VC90.CRT\ + msvcm90.dll + msvcp90.dll + msvcr90.dll + Microsoft.VC90.CRT.manifest + \VC\redist\ia64\Microsoft.VC90.CRT\ + msvcm90.dll + msvcp90.dll + msvcr90.dll + Microsoft.VC90.CRT.manifest + +---- + +Full text of license texts referred to above follows (that they are +listed below does not necessarily imply the conditions apply to the +present binary release): + +---- + +GCC RUNTIME LIBRARY EXCEPTION + +Version 3.1, 31 March 2009 + +Copyright (C) 2009 Free Software Foundation, Inc. + +Everyone is permitted to copy and distribute verbatim copies of this +license document, but changing it is not allowed. + +This GCC Runtime Library Exception ("Exception") is an additional +permission under section 7 of the GNU General Public License, version +3 ("GPLv3"). It applies to a given file (the "Runtime Library") that +bears a notice placed by the copyright holder of the file stating that +the file is governed by GPLv3 along with this Exception. + +When you use GCC to compile a program, GCC may combine portions of +certain GCC header files and runtime libraries with the compiled +program. The purpose of this Exception is to allow compilation of +non-GPL (including proprietary) programs to use, in this way, the +header files and runtime libraries covered by this Exception. + +0. Definitions. + +A file is an "Independent Module" if it either requires the Runtime +Library for execution after a Compilation Process, or makes use of an +interface provided by the Runtime Library, but is not otherwise based +on the Runtime Library. + +"GCC" means a version of the GNU Compiler Collection, with or without +modifications, governed by version 3 (or a specified later version) of +the GNU General Public License (GPL) with the option of using any +subsequent versions published by the FSF. + +"GPL-compatible Software" is software whose conditions of propagation, +modification and use would permit combination with GCC in accord with +the license of GCC. + +"Target Code" refers to output from any compiler for a real or virtual +target processor architecture, in executable form or suitable for +input to an assembler, loader, linker and/or execution +phase. Notwithstanding that, Target Code does not include data in any +format that is used as a compiler intermediate representation, or used +for producing a compiler intermediate representation. + +The "Compilation Process" transforms code entirely represented in +non-intermediate languages designed for human-written code, and/or in +Java Virtual Machine byte code, into Target Code. Thus, for example, +use of source code generators and preprocessors need not be considered +part of the Compilation Process, since the Compilation Process can be +understood as starting with the output of the generators or +preprocessors. + +A Compilation Process is "Eligible" if it is done using GCC, alone or +with other GPL-compatible software, or if it is done without using any +work based on GCC. For example, using non-GPL-compatible Software to +optimize any GCC intermediate representations would not qualify as an +Eligible Compilation Process. + +1. Grant of Additional Permission. + +You have permission to propagate a work of Target Code formed by +combining the Runtime Library with Independent Modules, even if such +propagation would otherwise violate the terms of GPLv3, provided that +all Target Code was generated by Eligible Compilation Processes. You +may then convey such a combination under terms of your choice, +consistent with the licensing of the Independent Modules. + +2. No Weakening of GCC Copyleft. + +The availability of this Exception does not imply any general +presumption that third-party software is unaffected by the copyleft +requirements of the license of GCC. + +---- + + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/venv/Lib/site-packages/numpy-1.20.2.dist-info/LICENSES_bundled.txt b/venv/Lib/site-packages/numpy-1.20.2.dist-info/LICENSES_bundled.txt new file mode 100644 index 0000000..00b7473 --- /dev/null +++ b/venv/Lib/site-packages/numpy-1.20.2.dist-info/LICENSES_bundled.txt @@ -0,0 +1,17 @@ +The NumPy repository and source distributions bundle several libraries that are +compatibly licensed. We list these here. + +Name: lapack-lite +Files: numpy/linalg/lapack_lite/* +License: BSD-3-Clause + For details, see numpy/linalg/lapack_lite/LICENSE.txt + +Name: tempita +Files: tools/npy_tempita/* +License: MIT + For details, see tools/npy_tempita/license.txt + +Name: dragon4 +Files: numpy/core/src/multiarray/dragon4.c +License: MIT + For license text, see numpy/core/src/multiarray/dragon4.c diff --git a/venv/Lib/site-packages/numpy-1.20.2.dist-info/METADATA b/venv/Lib/site-packages/numpy-1.20.2.dist-info/METADATA new file mode 100644 index 0000000..c0d3099 --- /dev/null +++ b/venv/Lib/site-packages/numpy-1.20.2.dist-info/METADATA @@ -0,0 +1,56 @@ +Metadata-Version: 2.1 +Name: numpy +Version: 1.20.2 +Summary: NumPy is the fundamental package for array computing with Python. +Home-page: https://www.numpy.org +Author: Travis E. Oliphant et al. +Maintainer: NumPy Developers +Maintainer-email: numpy-discussion@python.org +License: BSD +Download-URL: https://pypi.python.org/pypi/numpy +Project-URL: Bug Tracker, https://github.com/numpy/numpy/issues +Project-URL: Documentation, https://numpy.org/doc/1.20 +Project-URL: Source Code, https://github.com/numpy/numpy +Platform: Windows +Platform: Linux +Platform: Solaris +Platform: Mac OS-X +Platform: Unix +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Science/Research +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: BSD License +Classifier: Programming Language :: C +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: 3.8 +Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: 3 :: Only +Classifier: Programming Language :: Python :: Implementation :: CPython +Classifier: Topic :: Software Development +Classifier: Topic :: Scientific/Engineering +Classifier: Typing :: Typed +Classifier: Operating System :: Microsoft :: Windows +Classifier: Operating System :: POSIX +Classifier: Operating System :: Unix +Classifier: Operating System :: MacOS +Requires-Python: >=3.7 + +It provides: + +- a powerful N-dimensional array object +- sophisticated (broadcasting) functions +- tools for integrating C/C++ and Fortran code +- useful linear algebra, Fourier transform, and random number capabilities +- and much more + +Besides its obvious scientific uses, NumPy can also be used as an efficient +multi-dimensional container of generic data. Arbitrary data-types can be +defined. This allows NumPy to seamlessly and speedily integrate with a wide +variety of databases. + +All NumPy wheels distributed on PyPI are BSD licensed. + + + diff --git a/venv/Lib/site-packages/numpy-1.20.2.dist-info/RECORD b/venv/Lib/site-packages/numpy-1.20.2.dist-info/RECORD new file mode 100644 index 0000000..f58ce01 --- /dev/null +++ b/venv/Lib/site-packages/numpy-1.20.2.dist-info/RECORD @@ -0,0 +1,1064 @@ +../../Scripts/f2py.exe,sha256=y-oV9A05qDQK4__y5vmuaRa0EO_OpmGNZLnNX4lLLqU,106353 +numpy-1.20.2.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +numpy-1.20.2.dist-info/LICENSE.txt,sha256=VDW_78UWZhzN_Z729vbkkr7MzLGzi7lj3OKbwZkxrP0,47238 +numpy-1.20.2.dist-info/LICENSES_bundled.txt,sha256=LIMgxkCENPlSsRND8mqjqWqU-7nkH-bRMqz8H8d0M24,505 +numpy-1.20.2.dist-info/METADATA,sha256=C9dW_Bj-d9shYrQjrjYnSx9-8CwaO-AmNDfodZwMsA0,2043 +numpy-1.20.2.dist-info/RECORD,, +numpy-1.20.2.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +numpy-1.20.2.dist-info/WHEEL,sha256=jr7ubY0Lkz_yXH9FfFe9PTtLhGOsf62dZkNvTYrJINE,100 +numpy-1.20.2.dist-info/entry_points.txt,sha256=cOAXaHCx7qU-bvE9TStTTZW46RN-s-i6Mz9smnWkL3g,49 +numpy-1.20.2.dist-info/top_level.txt,sha256=4J9lbBMLnAiyxatxh8iRKV5Entd_6-oqbO7pzJjMsPw,6 +numpy/.libs/libopenblas.GK7GX5KEQ4F6UYO3P26ULGBQYHGQO7J4.gfortran-win_amd64.dll,sha256=Wi7hVl2YvdZbh6_fNPFs6Dexq0CuvhcLCAiAKymecoc,34413408 +numpy/LICENSE.txt,sha256=VDW_78UWZhzN_Z729vbkkr7MzLGzi7lj3OKbwZkxrP0,47238 +numpy/__config__.py,sha256=IHRa3rupkgR7i9orKgDOiGPeOriQOaDHFF5q7kCETEc,3016 +numpy/__init__.cython-30.pxd,sha256=kg17mANuYQtmc1DmNYwOYCyWcPidN_TCcP0KU6oe4No,37385 +numpy/__init__.pxd,sha256=u2NusfQDgMzoxakO9ePcl81ioWdFfMPa0i6p1xXxU3I,35718 +numpy/__init__.py,sha256=5c-ypjhSjsBLzPlh6eL4BWvuY3b8R6dqMt9JkIaghw4,15676 +numpy/__init__.pyi,sha256=XYCrKbKG0Zf77HLlf3x9vkR3iu5radGeGrNIPTIyKsw,63409 +numpy/__pycache__/__config__.cpython-39.pyc,, +numpy/__pycache__/__init__.cpython-39.pyc,, +numpy/__pycache__/_distributor_init.cpython-39.pyc,, +numpy/__pycache__/_globals.cpython-39.pyc,, +numpy/__pycache__/_pytesttester.cpython-39.pyc,, +numpy/__pycache__/conftest.cpython-39.pyc,, +numpy/__pycache__/ctypeslib.cpython-39.pyc,, +numpy/__pycache__/dual.cpython-39.pyc,, +numpy/__pycache__/matlib.cpython-39.pyc,, +numpy/__pycache__/setup.cpython-39.pyc,, +numpy/__pycache__/version.cpython-39.pyc,, +numpy/_distributor_init.py,sha256=JOqSUAVCNcvuXYwzfs41kJFHvhLdrqRfp3ZYk5U71Pc,1247 +numpy/_globals.py,sha256=Hn6HQltNo4q5i1uia9p4o0l4H8RCAa9y9DG9rEF5J_M,2384 +numpy/_pytesttester.py,sha256=l1KszmXKpS0O-_nGwVPbM71bt3LiZj6J_OUzH464uhU,6954 +numpy/char.pyi,sha256=1q4RiJ6LG9U8E0wic6eMz-X41aeZ0uqBgQf6Atx6Bxg,771 +numpy/compat/__init__.py,sha256=kryOGy6TD3f9oEXy1sZZOxEMc50A7GtON1yf0nMPzr8,450 +numpy/compat/__pycache__/__init__.cpython-39.pyc,, +numpy/compat/__pycache__/_inspect.cpython-39.pyc,, +numpy/compat/__pycache__/py3k.cpython-39.pyc,, +numpy/compat/__pycache__/setup.cpython-39.pyc,, +numpy/compat/_inspect.py,sha256=4PWDVD-iE3lZGrBCWdiLMn2oSytssuFszubUkC0oruA,7638 +numpy/compat/py3k.py,sha256=rNPRSpbICl4N5Er9N8Du7IgNY2mKgw8jrH__5-pxfRM,3527 +numpy/compat/setup.py,sha256=PmRas58NGR72H-7OsQj6kElSUeQHjN75qVh5jlQIJmc,345 +numpy/compat/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +numpy/compat/tests/__pycache__/__init__.cpython-39.pyc,, +numpy/compat/tests/__pycache__/test_compat.cpython-39.pyc,, +numpy/compat/tests/test_compat.py,sha256=6i0bPM1Nqw0n3wtMphMU7ul7fkQNwcuH2Xxc9vpnQy8,495 +numpy/conftest.py,sha256=yzmbZ_hizvOf-RT3PLYIYrvhNpj7L2CLBMoPiHMCNQ4,4150 +numpy/core/__init__.py,sha256=D3i0c-7P6m6hvSRyJRXM_u2fp4U35HEKo6YlMkgGceI,5470 +numpy/core/__init__.pyi,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +numpy/core/__pycache__/__init__.cpython-39.pyc,, +numpy/core/__pycache__/_add_newdocs.cpython-39.pyc,, +numpy/core/__pycache__/_add_newdocs_scalars.cpython-39.pyc,, +numpy/core/__pycache__/_asarray.cpython-39.pyc,, +numpy/core/__pycache__/_dtype.cpython-39.pyc,, +numpy/core/__pycache__/_dtype_ctypes.cpython-39.pyc,, +numpy/core/__pycache__/_exceptions.cpython-39.pyc,, +numpy/core/__pycache__/_internal.cpython-39.pyc,, +numpy/core/__pycache__/_methods.cpython-39.pyc,, +numpy/core/__pycache__/_string_helpers.cpython-39.pyc,, +numpy/core/__pycache__/_type_aliases.cpython-39.pyc,, +numpy/core/__pycache__/_ufunc_config.cpython-39.pyc,, +numpy/core/__pycache__/arrayprint.cpython-39.pyc,, +numpy/core/__pycache__/cversions.cpython-39.pyc,, +numpy/core/__pycache__/defchararray.cpython-39.pyc,, +numpy/core/__pycache__/einsumfunc.cpython-39.pyc,, +numpy/core/__pycache__/fromnumeric.cpython-39.pyc,, +numpy/core/__pycache__/function_base.cpython-39.pyc,, +numpy/core/__pycache__/generate_numpy_api.cpython-39.pyc,, +numpy/core/__pycache__/getlimits.cpython-39.pyc,, +numpy/core/__pycache__/machar.cpython-39.pyc,, +numpy/core/__pycache__/memmap.cpython-39.pyc,, +numpy/core/__pycache__/multiarray.cpython-39.pyc,, +numpy/core/__pycache__/numeric.cpython-39.pyc,, +numpy/core/__pycache__/numerictypes.cpython-39.pyc,, +numpy/core/__pycache__/overrides.cpython-39.pyc,, +numpy/core/__pycache__/records.cpython-39.pyc,, +numpy/core/__pycache__/setup.cpython-39.pyc,, +numpy/core/__pycache__/setup_common.cpython-39.pyc,, +numpy/core/__pycache__/shape_base.cpython-39.pyc,, +numpy/core/__pycache__/umath.cpython-39.pyc,, +numpy/core/__pycache__/umath_tests.cpython-39.pyc,, +numpy/core/_add_newdocs.py,sha256=khECrR7Rf1cvVcocZXeuIBf-1nylFJKpX8OpQUij2WQ,190584 +numpy/core/_add_newdocs_scalars.py,sha256=Z_1yGo28WECk5w0rN7e7n0GSrh7gsgSRrp02bRUwH_g,8818 +numpy/core/_asarray.py,sha256=APygHZC-8_LtPS4e1DH8uy_AoXW3D4drHKIN5OIBa-U,12595 +numpy/core/_asarray.pyi,sha256=dyUZzE1AIyyuEWY6KYYXlVbzyX-bdFDNUlZiEh4gxeE,1849 +numpy/core/_dtype.py,sha256=rrmrfzsthRMpG42judFTK7s6FJLfuYhMp5NY3F4lAaU,10185 +numpy/core/_dtype_ctypes.py,sha256=O8tYBqU1QzCG1CXviBe6jrgHYnyIPqpci9GEy9lXO08,3790 +numpy/core/_exceptions.py,sha256=AKdiXex1lQsv-tdKzhBbW-m5anJJFXpsWisjz8S3tAY,6342 +numpy/core/_internal.py,sha256=pmRIldMwdXHB4Pe23_utM0mEw0G9TrEUYX4ngBt16xg,27048 +numpy/core/_internal.pyi,sha256=fi4i96SaeVYEbpT5H2EY_A4n7TssO3NRU3qI4oa6PDo,543 +numpy/core/_methods.py,sha256=38u8LpNQ0PlsHXE5BJIuF0rguEFct_hUmQyRizzcIaY,11081 +numpy/core/_multiarray_tests.cp39-win_amd64.pyd,sha256=bIDU1gtqb97z-FdH3kkrUyxr4bl2jOsAPJO324JHzCY,110592 +numpy/core/_multiarray_umath.cp39-win_amd64.pyd,sha256=v_I7ioKHVqTLQkx9OlSaBGQAm0j82j7KxXad8Jn-fyQ,2818048 +numpy/core/_operand_flag_tests.cp39-win_amd64.pyd,sha256=beFnuuycmsBplqBaFttiFVn3bGvi0pQZjkKGGSz_gbE,13824 +numpy/core/_rational_tests.cp39-win_amd64.pyd,sha256=7vToKyl1HeDEaFgGiktoM7M11Noc7Bgnks_ckJt8oYA,47616 +numpy/core/_simd.cp39-win_amd64.pyd,sha256=GAOjVe9VRpDBaWWavI35W5d42O0Cnj9CdWbaZSNoACE,1216000 +numpy/core/_string_helpers.py,sha256=xFVFp6go9I8O7PKRR2zwkOk2VJxlnXTFSYt4s7MwXGM,2955 +numpy/core/_struct_ufunc_tests.cp39-win_amd64.pyd,sha256=tOqy1HnN6JXzfyxmhsd0mFnO46YyYln2XHDQwEaoGH4,14848 +numpy/core/_type_aliases.py,sha256=r_1GCfxyoTUGZ7eqB9rFyk4wDNcckZmTbn67Diuonlc,8050 +numpy/core/_type_aliases.pyi,sha256=lhTyivGJcuyja-I-1rGx0Op_d_UdFt9kavPeCn_o49w,539 +numpy/core/_ufunc_config.py,sha256=K_L35alWVK-CBKiQDp2Bp2-7LgXPBNmGHVAg5gNJbCg,14271 +numpy/core/_ufunc_config.pyi,sha256=3AvHaqwY0JdSIk-vkagBwag-jh-5ZPdSnPiXAv-Fhf0,1293 +numpy/core/_umath_tests.cp39-win_amd64.pyd,sha256=1iOClIZI8wKrYhWyvu4Hetz0LG7i0ehlWNAcOgzjxWA,32256 +numpy/core/arrayprint.py,sha256=pNPRgU7-6sxGfFjgIwGwq63e1qBwC1DOYI9_FdNEE-U,61525 +numpy/core/cversions.py,sha256=FISv1d4R917Bi5xJjKKy8Lo6AlFkV00WvSoB7l3acA4,360 +numpy/core/defchararray.py,sha256=A1P1Nn3MwVaIOgeFsrHXVQMLJINdth9gHnE4CU-j4gY,72530 +numpy/core/einsumfunc.py,sha256=iHjDbD_IKRWVFzph2DFfPCEQnSrJhkIQLzv5wv6hVgY,52884 +numpy/core/fromnumeric.py,sha256=YM6L4CbxCAehD4ffYDPhcj0gGp2BlUCTKwQmTGqmK-U,125761 +numpy/core/fromnumeric.pyi,sha256=Wo1hVrGgkJNZYy5-uUfE88YPPj5cyDgF_uumbo8xick,13126 +numpy/core/function_base.py,sha256=kER123X44kuAaFvsJs9-dOMGHcexPCEWwFhF0UQg77Y,19550 +numpy/core/function_base.pyi,sha256=vJ2H4u6uwReiKTWEZUkIoUFcdh3ymofLxavxh2Qr9JI,1602 +numpy/core/generate_numpy_api.py,sha256=5auy8-Wg0VUIwCepuDwAL11gL1P-oiZl7exPIi5BfbU,7348 +numpy/core/getlimits.py,sha256=ifS2q5tI2upbxC3ayqitKERnFT0LjA0rY9hRWPpzdj8,20338 +numpy/core/include/numpy/__multiarray_api.h,sha256=MUlrBTUSGh-t_l7iNOXx9ibJHUYddbKudHdFp6Oxd-4,63548 +numpy/core/include/numpy/__ufunc_api.h,sha256=Jmeal3EUlXxBZFX1zAUFvO7jWFVhvIOyf2DG_TW0X2k,12739 +numpy/core/include/numpy/_neighborhood_iterator_imp.h,sha256=9QiCyQf-O1MEjBJQ7T4JUu_JyUyQhCBZHbwOr7sAlyk,1951 +numpy/core/include/numpy/_numpyconfig.h,sha256=2T66Co5gkAN9DD_kuhsoU9GsKfg5lIFuTi4GxtE71tw,891 +numpy/core/include/numpy/arrayobject.h,sha256=Xt8fnhPhTkbhB313Xj315N3fLi3uYBEPbqNrsF-MUXE,175 +numpy/core/include/numpy/arrayscalars.h,sha256=y624UltRg9QkKVAsdbxZ_nI2td9myIMr44TZk01P-3M,3912 +numpy/core/include/numpy/halffloat.h,sha256=AaeF7vnfAjeoIg5krxbhDn7j_T6CAQIx-HfMBYYmGiQ,1948 +numpy/core/include/numpy/multiarray_api.txt,sha256=XwNLmbQ19nX5b2rOH6cDsFLl6_JrUt1UfQDSBIy9lS8,58809 +numpy/core/include/numpy/ndarrayobject.h,sha256=3GqcdPD2qgESrcH1O5oFlY04HC3aZ_VdN2tuLl65BrQ,10956 +numpy/core/include/numpy/ndarraytypes.h,sha256=nZcsXab2tkm1OAgkKy4FmIqZ_lqQthtsAy7nIjf-WMM,71451 +numpy/core/include/numpy/noprefix.h,sha256=fg28OipEj4EaPsrNGWu4YNZoGK7Bxdm5o45pAO5HaSk,6998 +numpy/core/include/numpy/npy_1_7_deprecated_api.h,sha256=rVhu81d2cL3I3u7eMpWs5qKlYpxaq84VPK4gP0Yk1QM,4394 +numpy/core/include/numpy/npy_3kcompat.h,sha256=LT1FbrrMzRyz4IE_Kxl3SbQ58p5Bp3x1QUHW-PCiPag,16101 +numpy/core/include/numpy/npy_common.h,sha256=vKyvBMPV3BiJGqSYsvUhJoS8qok_VNBMaOkzhLIaOjU,39413 +numpy/core/include/numpy/npy_cpu.h,sha256=LqrGxmouzu91yaBRzpaGAC_WGi7x04EKB1yRYjsXP-0,4042 +numpy/core/include/numpy/npy_endian.h,sha256=_vfSgtUccP2UrI6ag77Gj2mWbBnMKQfsPS2ggNwmJ2A,2714 +numpy/core/include/numpy/npy_interrupt.h,sha256=CjwMAXyJjxLbpbPFpyHrTgT1QDa2mrzQ-5EhGA-feqk,1923 +numpy/core/include/numpy/npy_math.h,sha256=6Ayeks6UG8_61SA4Q1k9x2nCcm9tSmKgBG7hJZQ-AqI,21569 +numpy/core/include/numpy/npy_no_deprecated_api.h,sha256=4-ALjOYp43ACG7z4zdabmQtFsxxKDaqYuQFTbElty1o,586 +numpy/core/include/numpy/npy_os.h,sha256=g6I_-QEotWP0p9g1v-GA_Qibg5HRAhQj46WsZ19fIuw,847 +numpy/core/include/numpy/numpyconfig.h,sha256=k1lxNkL1fQLbGr8rqgUX-D8OzykzWrTiZPF1Qcg4FMU,1453 +numpy/core/include/numpy/old_defines.h,sha256=gxn96tn2uCpdL0yBFEO6H_JDkhikf8Bj-w3x8sOz5Go,6493 +numpy/core/include/numpy/oldnumeric.h,sha256=b2lR7L8Lajka8FQ3HrrkSnekPKYK0v4vsUduS8gWZqc,733 +numpy/core/include/numpy/random/bitgen.h,sha256=V0PTeCTsLhKTq_z0hM8VgDa7jTQUTPASD0MkMaGXrgk,409 +numpy/core/include/numpy/random/distributions.h,sha256=9JVj1WgcIBxzXhez8EO3JUlyMmCKGfCoQbS9PUCNE_Y,9910 +numpy/core/include/numpy/ufunc_api.txt,sha256=8gADu8fBcUgFZV0yMbJwa1CtJKJsPVrx8MjuXsu18aw,7397 +numpy/core/include/numpy/ufuncobject.h,sha256=P5b7oDLvsE4sYGLxQ8gNDSN-f__LR064FV4duDq97Uw,13127 +numpy/core/include/numpy/utils.h,sha256=LX_d9Fbe_BleyoYLy4wQgwrsF924qKLs7mAjejkdUCw,1161 +numpy/core/lib/npy-pkg-config/mlib.ini,sha256=mQBSOI6opCVmMZK4vwIhLe5J7YevO3PbaHsI0MlJGHs,151 +numpy/core/lib/npy-pkg-config/npymath.ini,sha256=5dwvhvbX3a_9toniEDvGPDGChbXIfFiLa36H4YOR-vw,380 +numpy/core/lib/npymath.lib,sha256=9xBVdFOOiXhOG15eLaaTPx9_jneMqJN9ct_czQbTEvg,106590 +numpy/core/machar.py,sha256=AhzxGy1gnrp-M-ikLzi9nm-Rb1vuUZsmqmnud8qen_g,11157 +numpy/core/memmap.py,sha256=WB-4tIRvywLS3rP2ueuroj4pbySSGWJe-Ww88D5mm4g,12061 +numpy/core/multiarray.py,sha256=1AcQPxGOSLkFEXSAn_PFX7l-W1ZyxIBHaRcXYHtoIu0,56546 +numpy/core/numeric.py,sha256=tJHnnSa6GLuDl6p7dJiRaAoqqMuTKEwEV-s_tu0loNk,79200 +numpy/core/numeric.pyi,sha256=BXJKW-n1k4xxRevqiCysWeyk8DQDBRgYARczr3hfibg,4933 +numpy/core/numerictypes.py,sha256=K9TPRmuwMuOJkpgPnKOhtyFTLe0YgQzg-0pM4XbZhnc,18039 +numpy/core/numerictypes.pyi,sha256=9Z1EQNv6G_Nd3rbQpidEUQzdlunUe6a_wrHiFiUZ19M,1077 +numpy/core/overrides.py,sha256=kF571-2fsMrWD1JgHIc_phB4nNPXTdRxoyLktEm2z18,8504 +numpy/core/records.py,sha256=LcIJr6jw3LmRq4aeKwHmQA4gMYn_7h_yMhKleGzW1eQ,38985 +numpy/core/setup.py,sha256=aDmpYk-1NFj8TE-83cJVTx60yLcQYOwNmhVdyletDFQ,45605 +numpy/core/setup_common.py,sha256=VyODljaWE-HUO8LJc90eac9gwNhsZUnfiooWHfUq8IU,20096 +numpy/core/shape_base.py,sha256=gHxRwsy1nLum7iEK_JyXfkswQByPUmFwASL1w4Jxz8c,29922 +numpy/core/shape_base.pyi,sha256=IZbT7mAiA3unDXKgd_tz3pp-Dg2p41sWInS5MWbbsuA,1180 +numpy/core/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +numpy/core/tests/__pycache__/__init__.cpython-39.pyc,, +numpy/core/tests/__pycache__/_locales.cpython-39.pyc,, +numpy/core/tests/__pycache__/test__exceptions.cpython-39.pyc,, +numpy/core/tests/__pycache__/test_abc.cpython-39.pyc,, +numpy/core/tests/__pycache__/test_api.cpython-39.pyc,, +numpy/core/tests/__pycache__/test_array_coercion.cpython-39.pyc,, +numpy/core/tests/__pycache__/test_arrayprint.cpython-39.pyc,, +numpy/core/tests/__pycache__/test_casting_unittests.cpython-39.pyc,, +numpy/core/tests/__pycache__/test_conversion_utils.cpython-39.pyc,, +numpy/core/tests/__pycache__/test_cpu_dispatcher.cpython-39.pyc,, +numpy/core/tests/__pycache__/test_cpu_features.cpython-39.pyc,, +numpy/core/tests/__pycache__/test_cython.cpython-39.pyc,, +numpy/core/tests/__pycache__/test_datetime.cpython-39.pyc,, +numpy/core/tests/__pycache__/test_defchararray.cpython-39.pyc,, +numpy/core/tests/__pycache__/test_deprecations.cpython-39.pyc,, +numpy/core/tests/__pycache__/test_dtype.cpython-39.pyc,, +numpy/core/tests/__pycache__/test_einsum.cpython-39.pyc,, +numpy/core/tests/__pycache__/test_errstate.cpython-39.pyc,, +numpy/core/tests/__pycache__/test_extint128.cpython-39.pyc,, +numpy/core/tests/__pycache__/test_function_base.cpython-39.pyc,, +numpy/core/tests/__pycache__/test_getlimits.cpython-39.pyc,, +numpy/core/tests/__pycache__/test_half.cpython-39.pyc,, +numpy/core/tests/__pycache__/test_indexerrors.cpython-39.pyc,, +numpy/core/tests/__pycache__/test_indexing.cpython-39.pyc,, +numpy/core/tests/__pycache__/test_item_selection.cpython-39.pyc,, +numpy/core/tests/__pycache__/test_longdouble.cpython-39.pyc,, +numpy/core/tests/__pycache__/test_machar.cpython-39.pyc,, +numpy/core/tests/__pycache__/test_mem_overlap.cpython-39.pyc,, +numpy/core/tests/__pycache__/test_memmap.cpython-39.pyc,, +numpy/core/tests/__pycache__/test_multiarray.cpython-39.pyc,, +numpy/core/tests/__pycache__/test_nditer.cpython-39.pyc,, +numpy/core/tests/__pycache__/test_numeric.cpython-39.pyc,, +numpy/core/tests/__pycache__/test_numerictypes.cpython-39.pyc,, +numpy/core/tests/__pycache__/test_overrides.cpython-39.pyc,, +numpy/core/tests/__pycache__/test_print.cpython-39.pyc,, +numpy/core/tests/__pycache__/test_protocols.cpython-39.pyc,, +numpy/core/tests/__pycache__/test_records.cpython-39.pyc,, +numpy/core/tests/__pycache__/test_regression.cpython-39.pyc,, +numpy/core/tests/__pycache__/test_scalar_ctors.cpython-39.pyc,, +numpy/core/tests/__pycache__/test_scalar_methods.cpython-39.pyc,, +numpy/core/tests/__pycache__/test_scalarbuffer.cpython-39.pyc,, +numpy/core/tests/__pycache__/test_scalarinherit.cpython-39.pyc,, +numpy/core/tests/__pycache__/test_scalarmath.cpython-39.pyc,, +numpy/core/tests/__pycache__/test_scalarprint.cpython-39.pyc,, +numpy/core/tests/__pycache__/test_shape_base.cpython-39.pyc,, +numpy/core/tests/__pycache__/test_simd.cpython-39.pyc,, +numpy/core/tests/__pycache__/test_simd_module.cpython-39.pyc,, +numpy/core/tests/__pycache__/test_ufunc.cpython-39.pyc,, +numpy/core/tests/__pycache__/test_umath.cpython-39.pyc,, +numpy/core/tests/__pycache__/test_umath_accuracy.cpython-39.pyc,, +numpy/core/tests/__pycache__/test_umath_complex.cpython-39.pyc,, +numpy/core/tests/__pycache__/test_unicode.cpython-39.pyc,, +numpy/core/tests/_locales.py,sha256=PAV24baH5MIl_gH_VBi5glF-7kgifkK00WnAP0Hhc60,2266 +numpy/core/tests/data/astype_copy.pkl,sha256=lWSzCcvzRB_wpuRGj92spGIw-rNPFcd9hwJaRVvfWdk,716 +numpy/core/tests/data/recarray_from_file.fits,sha256=NA0kliz31FlLnYxv3ppzeruONqNYkuEvts5wzXEeIc4,8640 +numpy/core/tests/data/umath-validation-set-README,sha256=hhKRS9byn4eKEJ_LHoHDYQnVArbEXPIKQtPdPBUtGbk,974 +numpy/core/tests/data/umath-validation-set-cos,sha256=WO94BFik3VcliW2QBStw3Srpfd5Ykcxd-7phRf0be4Y,23898 +numpy/core/tests/data/umath-validation-set-exp,sha256=mPhjF4KLe0bdwx38SJiNipD24ntLI_5aWc8h-V0UMgM,17903 +numpy/core/tests/data/umath-validation-set-log,sha256=CDPky64PjaURWhqkHxkLElmMiI21v5ugGGyzhdfUbnI,11963 +numpy/core/tests/data/umath-validation-set-sin,sha256=0nDRTZc1YG_zbDgpGYtMrf63nUTc8bzcCwEVWqkBqio,23705 +numpy/core/tests/examples/__pycache__/setup.cpython-39.pyc,, +numpy/core/tests/examples/checks.pyx,sha256=nZXyjisKEKm2vVXM42k-P4h0BGLoa42ABHIGENJegC4,618 +numpy/core/tests/examples/setup.py,sha256=JvbvFHHdkZx_eajlwMTtqHijLD-TZwXCZlRySAe-y94,521 +numpy/core/tests/test__exceptions.py,sha256=_jJh6Xunn9GVkkRab3PJ5xzRn5mCdb5RHxE77F5ds5I,2063 +numpy/core/tests/test_abc.py,sha256=KbyIH9nsGOnXQ8VtnwU6QyUgaFDC0XfEs476CnJ_-Wg,2382 +numpy/core/tests/test_api.py,sha256=LOzoU-9GSjU6D0Tz2SXQEIaMG8GKmQJu98hM7lrbeuk,22227 +numpy/core/tests/test_array_coercion.py,sha256=x7g0Y9POUoVQJJRJ7iGjsVZsY0KHHgmZ760V1pjwpk4,28578 +numpy/core/tests/test_arrayprint.py,sha256=9YfFGZL22BAFQW-Zh3wzZlugzJuU_dN64hJWVDU1eSU,37869 +numpy/core/tests/test_casting_unittests.py,sha256=AvWa8TevaT9OY1vic6-7v2zmKCagKgbHHLUNe9Y1ois,12192 +numpy/core/tests/test_conversion_utils.py,sha256=HB-6IpP4XD5tL_FM5Oat--gQ02MI_WG8BX0P5eyvUZg,6616 +numpy/core/tests/test_cpu_dispatcher.py,sha256=gEEzMPLo057xBh7GmwXwV4ikBC2X1P0XtHUlAkbppU0,1561 +numpy/core/tests/test_cpu_features.py,sha256=wcKrzblzXmZxGg8gdtw1Vn3XAG3d0Kl7TW6Lz0oyprQ,6956 +numpy/core/tests/test_cython.py,sha256=SkCZWMLnSnDUKJjWLfbUHYx5EEgcZ8mghpAJbYs5fX0,3663 +numpy/core/tests/test_datetime.py,sha256=B5ufTlNeIAETvkIYaspc_RZ2lnn2DeJtmdCsSEfSWaY,112219 +numpy/core/tests/test_defchararray.py,sha256=VhAlRKEJSrcWcrZbZruagw1170409taptPGauwxp-HM,25256 +numpy/core/tests/test_deprecations.py,sha256=Ni2OF0djqEcSu0NbC6xmIEZoBHBkQAM-OkMmyOayhEQ,35158 +numpy/core/tests/test_dtype.py,sha256=07ZiqOtBnoj8E2Ss7eNDWB6dLpKNzulmnm1Xk9qsuq8,56019 +numpy/core/tests/test_einsum.py,sha256=GsmB2gxsAu9NQ3gg3ASWoYaUhFui91uHig-B5CXRqT4,47891 +numpy/core/tests/test_errstate.py,sha256=kNCMfKs1xgXUrIRQM4qB8fEkVbREVE-p-yG2hsuHjd4,2125 +numpy/core/tests/test_extint128.py,sha256=b8vP_hDPltdHoxWBn2vAmOgjJe2NVW_vjnatdCOtxu8,5862 +numpy/core/tests/test_function_base.py,sha256=FjbJ8JMRcbBxllRXRZhxbE6nlfP1HL8I4kfyW8RKr0s,14820 +numpy/core/tests/test_getlimits.py,sha256=m2xfs_MhozzD88pqRoD00GlMbA-biaK0tEMmBW0vt9g,4418 +numpy/core/tests/test_half.py,sha256=7vZngTRJJ45h4XUFws9fpHI_gYKPq9pz_DKUhZf8lEk,24370 +numpy/core/tests/test_indexerrors.py,sha256=iJu4EorQks1MmiwTV-fda-vd4HfCEwv9_Ba_rVea7xw,5263 +numpy/core/tests/test_indexing.py,sha256=uAOckiHJcPqVbEOTXDaJspUfYqWgshWxllWd5WtxQDA,54782 +numpy/core/tests/test_item_selection.py,sha256=8AukBkttHRVkRBujEDDSW0AN1i6FvRDeJO5Cot9teFc,3665 +numpy/core/tests/test_longdouble.py,sha256=0xWqtJdc-MUfxxZutfuI9W9d-hv_LouFb3355QU0UHE,13410 +numpy/core/tests/test_machar.py,sha256=o4LNEPRU2p0fzok8AiO2Y9vIoZUfWQvqMN2_rJqLoKE,1096 +numpy/core/tests/test_mem_overlap.py,sha256=Sc29ERD4HWExeUA43J96-4QBTkZS4dS_RUrb_DJLbwM,29781 +numpy/core/tests/test_memmap.py,sha256=kJauOy8Wr7iakTXmS-RTaOWZAlglrn7aFGEcP-ThHuw,7808 +numpy/core/tests/test_multiarray.py,sha256=_5Kz-Tbq3nB6MZ-L2PLfwctaALXaMwHzCdi9Hu7JBTs,337726 +numpy/core/tests/test_nditer.py,sha256=ro5vSnqWmgsWRAB4d9Q5fMDEdRSu5qBMzMFNasV-fOc,119521 +numpy/core/tests/test_numeric.py,sha256=K3v2uCXEQDrP95gXMqCYBUlmOmbuoK6lrGE6DWP02d0,135870 +numpy/core/tests/test_numerictypes.py,sha256=c-xwoz-oawJff09G0tri2Q9FJQ0NLkH3vf_zmwGnheg,21400 +numpy/core/tests/test_overrides.py,sha256=_NnwFNETDokYrVxt2eFJfzPxx2qWtvbC0mJDVS2YFuE,20648 +numpy/core/tests/test_print.py,sha256=I3-R4iNbFjmVdl5xHPb9ezYb4zDfdXNfzVZt3Lz3bqU,6937 +numpy/core/tests/test_protocols.py,sha256=Etu0M6T-xFJjAyXy2EcCH48Tbe5VRnZCySjMy0RhbPY,1212 +numpy/core/tests/test_records.py,sha256=910AOqDvIhCDsrmCQk737UhxDnQU3GSB5a2-w0h9hWM,20782 +numpy/core/tests/test_regression.py,sha256=qO4gCWkcfFbBam5BWVuumjGntBT-Hevih2BH1CU2bo4,92275 +numpy/core/tests/test_scalar_ctors.py,sha256=ilVfUULT72ALjt1WH0B54winaYbWrRy62AewkvugJao,3803 +numpy/core/tests/test_scalar_methods.py,sha256=3uNPtYl73DJBLGQxJJ1df4cyr90A5Sp0pcRtXMVTjac,4166 +numpy/core/tests/test_scalarbuffer.py,sha256=E7nYL8Hnbr3d_9-oxvGtkWte2q6ZeteJhmi0kOQ_u8k,5790 +numpy/core/tests/test_scalarinherit.py,sha256=xea-dgKGvMr-HjM9my-KpMN797sOegNhXni-62kw7m0,2504 +numpy/core/tests/test_scalarmath.py,sha256=dDGy7iZIcKokbyTytjG5N17tF3TQ-sMBEjkFHEZblwY,29768 +numpy/core/tests/test_scalarprint.py,sha256=VmPnnhMyFScjwUjEknjt5oF1YXR43oESZSYDuqbo614,15480 +numpy/core/tests/test_shape_base.py,sha256=fxb8d5kMhn9YazVg1h-prGUAO62FFImam250AP8DS4I,28251 +numpy/core/tests/test_simd.py,sha256=6YdEn72Nx_l0rw_z7ZEUUjOJf3ofsCqtF9aWOsJ4wjI,24568 +numpy/core/tests/test_simd_module.py,sha256=Bpbg_3YKO4Nu4Jm8p_QIlhrz_3tLIO6ketPhJmA_hZU,3855 +numpy/core/tests/test_ufunc.py,sha256=SPPnaYt2H7kG2zXknZu2sTSMmRrHN-UEcyuKlXO_qHg,91879 +numpy/core/tests/test_umath.py,sha256=VmybQuYViPMP7w8yEIUpZsEL1YgtRw7KaWOlcm45NEU,137309 +numpy/core/tests/test_umath_accuracy.py,sha256=_3N9e6662AmFLqIkyvTYFxeGL0HzM4lF4z2R00LnSoM,3103 +numpy/core/tests/test_umath_complex.py,sha256=7DMz_aYMufNED9OkyVHHbZP7akoZO6nR_ySWxPJ9JXs,23701 +numpy/core/tests/test_unicode.py,sha256=c6SB-PZaiNH7HvEZ2xIrfAMPmvuJmcTo79aBBkdCFvY,12915 +numpy/core/umath.py,sha256=IE9whDRUf3FOx3hdo6bGB0X_4OOJn_Wk6ajnbrc542A,2076 +numpy/core/umath_tests.py,sha256=IuFDModusxI6j5Qk-VWYHRZDIE806dzvju0qYlvwmfY,402 +numpy/ctypeslib.py,sha256=VdpIB-ytRoeVZfnt5TaJYn6y_rTc8GTvb9alp9d7B7w,17739 +numpy/ctypeslib.pyi,sha256=twksdb42mpN3Nc4WRJpcnwMqjNnvp_v02cZ9QiLQcI0,154 +numpy/distutils/__config__.py,sha256=IHRa3rupkgR7i9orKgDOiGPeOriQOaDHFF5q7kCETEc,3016 +numpy/distutils/__init__.py,sha256=kuNMyZmAP8MtuKKOGG5pMz5wWcLVzHkU7wW7CTwzNxY,1610 +numpy/distutils/__init__.pyi,sha256=6KiQIH85pUXaIlow3KW06e1_ZJBocVY6lIGghNaW33A,123 +numpy/distutils/__pycache__/__config__.cpython-39.pyc,, +numpy/distutils/__pycache__/__init__.cpython-39.pyc,, +numpy/distutils/__pycache__/_shell_utils.cpython-39.pyc,, +numpy/distutils/__pycache__/ccompiler.cpython-39.pyc,, +numpy/distutils/__pycache__/ccompiler_opt.cpython-39.pyc,, +numpy/distutils/__pycache__/conv_template.cpython-39.pyc,, +numpy/distutils/__pycache__/core.cpython-39.pyc,, +numpy/distutils/__pycache__/cpuinfo.cpython-39.pyc,, +numpy/distutils/__pycache__/exec_command.cpython-39.pyc,, +numpy/distutils/__pycache__/extension.cpython-39.pyc,, +numpy/distutils/__pycache__/from_template.cpython-39.pyc,, +numpy/distutils/__pycache__/intelccompiler.cpython-39.pyc,, +numpy/distutils/__pycache__/lib2def.cpython-39.pyc,, +numpy/distutils/__pycache__/line_endings.cpython-39.pyc,, +numpy/distutils/__pycache__/log.cpython-39.pyc,, +numpy/distutils/__pycache__/mingw32ccompiler.cpython-39.pyc,, +numpy/distutils/__pycache__/misc_util.cpython-39.pyc,, +numpy/distutils/__pycache__/msvc9compiler.cpython-39.pyc,, +numpy/distutils/__pycache__/msvccompiler.cpython-39.pyc,, +numpy/distutils/__pycache__/npy_pkg_config.cpython-39.pyc,, +numpy/distutils/__pycache__/numpy_distribution.cpython-39.pyc,, +numpy/distutils/__pycache__/pathccompiler.cpython-39.pyc,, +numpy/distutils/__pycache__/setup.cpython-39.pyc,, +numpy/distutils/__pycache__/system_info.cpython-39.pyc,, +numpy/distutils/__pycache__/unixccompiler.cpython-39.pyc,, +numpy/distutils/_shell_utils.py,sha256=9pI0lXlRJxB22TPVBNUhWe7EnE-V6xIhMNQSR8LOw40,2704 +numpy/distutils/ccompiler.py,sha256=_sx0zV6AlYpxqN7Pr_7Wwc4k98a3GM6MFBdDPironCE,27805 +numpy/distutils/ccompiler_opt.py,sha256=aMyFbrZDK-ykCsT8mEN2XgkHYHtmveeGwVTBsbhOlTc,97804 +numpy/distutils/checks/cpu_asimd.c,sha256=sUn-v9fLpUUEtsrAfbGor76uYGhCINzXgkz0v3alZhQ,729 +numpy/distutils/checks/cpu_asimddp.c,sha256=7_HRp5jMJBSz02PcmAaH6m07zAbtcjMgkw7-4vhTZI4,395 +numpy/distutils/checks/cpu_asimdfhm.c,sha256=I7dTWSITAGwxHaLULZkh0nqnf-v9NF2kfQu7Tu90aB4,448 +numpy/distutils/checks/cpu_asimdhp.c,sha256=BD9NPwN4mcUZE_KydEQ0b7GtTkfEljl4u0KbrohLYcU,343 +numpy/distutils/checks/cpu_avx.c,sha256=AchhlKaX-7TJBTdLPxizv0kBQgpDlJfHsgu0vAVpxiw,180 +numpy/distutils/checks/cpu_avx2.c,sha256=ceEOVmmjXG3RvOJ5CFm_Ci3migjjxyXMkGootol5f5I,165 +numpy/distutils/checks/cpu_avx512_clx.c,sha256=6YL7X8fPLx4tdmVf87yEJcE0scrWmN8GKMWbU2H_eI4,232 +numpy/distutils/checks/cpu_avx512_cnl.c,sha256=FQgnUfGPJIxwb_QgggyN_eqDbVIO0Fg5S8yTSOVavBs,336 +numpy/distutils/checks/cpu_avx512_icl.c,sha256=NiAeMDgsiY3xjJ2orMHxrFJSbE-ZCxuq38dtjnQ_Zf0,336 +numpy/distutils/checks/cpu_avx512_knl.c,sha256=9bdrxCQfeL8sNAX8cQ_9lr_JxDU1TSl2J4XUQu9xjP4,292 +numpy/distutils/checks/cpu_avx512_knm.c,sha256=AWsXafv1lP1BI_APmXFYOXk5SyHGYBvjodVcxduOfHA,432 +numpy/distutils/checks/cpu_avx512_skx.c,sha256=drVMoRW8SWhwgcTMiVjMuN34v6ZSZmWe3cf0JGa7shM,281 +numpy/distutils/checks/cpu_avx512cd.c,sha256=ToPmk0tu_6gPdWNcKJYILjtRx4vIc6ShECfNM2-l7bY,167 +numpy/distutils/checks/cpu_avx512f.c,sha256=KewXn3NHK7SGboqTSBqO-64rYDY161pMeGY833MCoaw,165 +numpy/distutils/checks/cpu_f16c.c,sha256=pSq0FnDJYTbx2K9Cs7bJX2vGfEc8q7cvw5lC8rdevP0,260 +numpy/distutils/checks/cpu_fma3.c,sha256=mh3efYJ-hmv6z7b1j9I_WChae1RFMGtXWHgLqQp7_pY,227 +numpy/distutils/checks/cpu_fma4.c,sha256=tbalvI_RCIWy4X-BzRbZ9AVV1eCgm7UMJYbN7NM9vfs,290 +numpy/distutils/checks/cpu_neon.c,sha256=3lc70da2_XbT1hA36YY7vGbapW3dDZlG8xoNXp2rMzY,387 +numpy/distutils/checks/cpu_neon_fp16.c,sha256=XeOsWVVTmFecSl_luw2lNBGKxHaB2TtL7YnyIv8W0OU,262 +numpy/distutils/checks/cpu_neon_vfpv4.c,sha256=oJ1NvRYfF7Yf6S_bZuaUntE0iOnkbmTNNVR_sbE4NV8,512 +numpy/distutils/checks/cpu_popcnt.c,sha256=PuEpVkvM-tAyA8TzERvODpvEqWU0qhxLJLyW-Lj-Zc4,393 +numpy/distutils/checks/cpu_sse.c,sha256=WG79fJMG4JcbZnxVNUGSuGF8tHJ6IUyAVNFZM3eDSDg,147 +numpy/distutils/checks/cpu_sse2.c,sha256=Urd4Xcq_2oXqMxftLWnr7fXfnaPyCHxMb1dLOBxgCU4,156 +numpy/distutils/checks/cpu_sse3.c,sha256=FQCCU27JvQvNPmhlEr6kA_omlT6R6PFSk9Fz4xptyXg,148 +numpy/distutils/checks/cpu_sse41.c,sha256=S3IVKzcRmYp0Gjtc_LTfdAjjg9HjQgP_DDJTLVz6Ii8,131 +numpy/distutils/checks/cpu_sse42.c,sha256=NsXFPtSuGygm-KdkPcJRAncKQz58S5qXpa8SG_urgwU,148 +numpy/distutils/checks/cpu_ssse3.c,sha256=wWm9_w0v8Y4230p83AGXJgiDlAjg3UZ2dVX-T9ebBDs,162 +numpy/distutils/checks/cpu_vsx.c,sha256=gxWpdnkMeoaBCzlU_j56brB38KFo4ItFsjyiyo3YrKk,499 +numpy/distutils/checks/cpu_vsx2.c,sha256=ycKoKXszrZkECYmonzKd7TgflpZyVc1Xq-gtJqyPKxs,276 +numpy/distutils/checks/cpu_vsx3.c,sha256=pNA4w2odwo-mUfSnKnXl5SVY1z2nOxPZZcNC-L2YX1w,263 +numpy/distutils/checks/cpu_xop.c,sha256=sPhOvyT-mdlbf6RlbZvMrslRwHnTFgP-HXLjueS7nwU,246 +numpy/distutils/checks/extra_avx512bw_mask.c,sha256=7IRO24mpcuXRhm3refGWP91sy0e6RmSkmUQCWyxy__0,654 +numpy/distutils/checks/extra_avx512dq_mask.c,sha256=jFtOKEtZl3iTpfbmFNB-u4DQNXXBST2toKCpxFIjEa0,520 +numpy/distutils/checks/extra_avx512f_reduce.c,sha256=loHAibDU3STIihz3VNshKx0_cA2_yxq2aWc5nS6ILnc,1638 +numpy/distutils/checks/test_flags.c,sha256=7rgVefVOKOBaefG_6riau_tT2IqI4MFrbSMGNFnqUBQ,17 +numpy/distutils/command/__init__.py,sha256=DCxnKqTLrauOD3Fc8b7qg9U3gV2k9SADevE_Q3H78ng,1073 +numpy/distutils/command/__pycache__/__init__.cpython-39.pyc,, +numpy/distutils/command/__pycache__/autodist.cpython-39.pyc,, +numpy/distutils/command/__pycache__/bdist_rpm.cpython-39.pyc,, +numpy/distutils/command/__pycache__/build.cpython-39.pyc,, +numpy/distutils/command/__pycache__/build_clib.cpython-39.pyc,, +numpy/distutils/command/__pycache__/build_ext.cpython-39.pyc,, +numpy/distutils/command/__pycache__/build_py.cpython-39.pyc,, +numpy/distutils/command/__pycache__/build_scripts.cpython-39.pyc,, +numpy/distutils/command/__pycache__/build_src.cpython-39.pyc,, +numpy/distutils/command/__pycache__/config.cpython-39.pyc,, +numpy/distutils/command/__pycache__/config_compiler.cpython-39.pyc,, +numpy/distutils/command/__pycache__/develop.cpython-39.pyc,, +numpy/distutils/command/__pycache__/egg_info.cpython-39.pyc,, +numpy/distutils/command/__pycache__/install.cpython-39.pyc,, +numpy/distutils/command/__pycache__/install_clib.cpython-39.pyc,, +numpy/distutils/command/__pycache__/install_data.cpython-39.pyc,, +numpy/distutils/command/__pycache__/install_headers.cpython-39.pyc,, +numpy/distutils/command/__pycache__/sdist.cpython-39.pyc,, +numpy/distutils/command/autodist.py,sha256=i2ip0Zru8_AFx3lNQhlZfj6o_vg-RQ8yu1WNstcIYhE,3866 +numpy/distutils/command/bdist_rpm.py,sha256=9uZfOzdHV0_PRUD8exNNwafc0qUqUjHuTDxQcZXLIbg,731 +numpy/distutils/command/build.py,sha256=48vCxFz9tA0EWAtP9BiFTzpz6l91qXa0z3O3pC_QMis,2627 +numpy/distutils/command/build_clib.py,sha256=tKyaJypY97T4KJ2IAyUKhCU09diq8JaPeEh_JKX_5h8,17587 +numpy/distutils/command/build_ext.py,sha256=Vm6ZMSBPeljNp5AMJxiFEVpqUHbIuvu7djcxGjY9Bpk,30893 +numpy/distutils/command/build_py.py,sha256=xBHZCtx91GqucanjIBETPeXmR-gyUKPDyr1iMx1ARWE,1175 +numpy/distutils/command/build_scripts.py,sha256=AEQLNmO2v5N-GXl4lwd8v_nHlrauBx9Y-UudDcdCs_A,1714 +numpy/distutils/command/build_src.py,sha256=TbN3yNLm_FafCLv2Dx0RHkvYzaPsF1UwPINe1TUepgI,31953 +numpy/distutils/command/config.py,sha256=zczmFmKmYMnv1DMlJzUGtFTOascA1ZLh6Sr-EEcXSVk,21144 +numpy/distutils/command/config_compiler.py,sha256=I-xAL3JxaGFfpR4lg7g0tDdA_t7zCt-D4JtOACCP_Ak,4495 +numpy/distutils/command/develop.py,sha256=5ro-Sudt8l58JpKvH9FauH6vIfYRv2ohHLz-9eHytbc,590 +numpy/distutils/command/egg_info.py,sha256=n6trbjRfD1qWc_hRtMFkOJsg82BCiLvdl-NeXyuceGc,946 +numpy/distutils/command/install.py,sha256=s_0Uf39tFoRLUBlkrRK4YlROZsLdkI-IsuiFFaiS3ls,3157 +numpy/distutils/command/install_clib.py,sha256=q3yrfJY9EBaxOIYUQoiu2-juNKLKAKKfXC0nrd4t6z0,1439 +numpy/distutils/command/install_data.py,sha256=r8EVbIaXyN3aOmRugT3kp_F4Z03PsVX2l_x4RjTOWU4,872 +numpy/distutils/command/install_headers.py,sha256=g5Ag2H3j3dz-qSwWegxiZSAnvAf0thYYFwfPVHf9rxc,944 +numpy/distutils/command/sdist.py,sha256=XQM39b-MMO08bfE3SJrrtDWwX0XVnzCZqfAoVuuaFuE,760 +numpy/distutils/conv_template.py,sha256=q60i2Jf0PlQGHmjr7pu5zwBUnoYiLhtfcdgV94uLSaw,9888 +numpy/distutils/core.py,sha256=baf9SXdCVV8fA0lhLpOV4yEEWQP4ZwMTeeWoXHMg9LE,8374 +numpy/distutils/cpuinfo.py,sha256=frzEtCIEsSbQzGmNUXdWctiFqRcNFeLurzbvyCh8thY,23340 +numpy/distutils/exec_command.py,sha256=xMR7Dou5VZp2cP23xNd2TlXqexppXzBUd1wLMEAD2is,10668 +numpy/distutils/extension.py,sha256=E6m-GBUisj8kWbZlKlQhe6UUQvZOQ6JBGS5eqaSU7lY,3463 +numpy/distutils/fcompiler/__init__.py,sha256=vxt_-VqmNldCccva6d5WNVU_ztPIHipvny0NaYT8CGc,41110 +numpy/distutils/fcompiler/__pycache__/__init__.cpython-39.pyc,, +numpy/distutils/fcompiler/__pycache__/absoft.cpython-39.pyc,, +numpy/distutils/fcompiler/__pycache__/compaq.cpython-39.pyc,, +numpy/distutils/fcompiler/__pycache__/environment.cpython-39.pyc,, +numpy/distutils/fcompiler/__pycache__/fujitsu.cpython-39.pyc,, +numpy/distutils/fcompiler/__pycache__/g95.cpython-39.pyc,, +numpy/distutils/fcompiler/__pycache__/gnu.cpython-39.pyc,, +numpy/distutils/fcompiler/__pycache__/hpux.cpython-39.pyc,, +numpy/distutils/fcompiler/__pycache__/ibm.cpython-39.pyc,, +numpy/distutils/fcompiler/__pycache__/intel.cpython-39.pyc,, +numpy/distutils/fcompiler/__pycache__/lahey.cpython-39.pyc,, +numpy/distutils/fcompiler/__pycache__/mips.cpython-39.pyc,, +numpy/distutils/fcompiler/__pycache__/nag.cpython-39.pyc,, +numpy/distutils/fcompiler/__pycache__/none.cpython-39.pyc,, +numpy/distutils/fcompiler/__pycache__/nv.cpython-39.pyc,, +numpy/distutils/fcompiler/__pycache__/pathf95.cpython-39.pyc,, +numpy/distutils/fcompiler/__pycache__/pg.cpython-39.pyc,, +numpy/distutils/fcompiler/__pycache__/sun.cpython-39.pyc,, +numpy/distutils/fcompiler/__pycache__/vast.cpython-39.pyc,, +numpy/distutils/fcompiler/absoft.py,sha256=4UKxvpWQIphSdi6vJb3qILML_zyM3K_m7ddhAMS5dBI,5655 +numpy/distutils/fcompiler/compaq.py,sha256=i3kdLom13ho1QmwmjkPUane66lPqp_X4p_UbTH7z5gM,4027 +numpy/distutils/fcompiler/environment.py,sha256=PVS1al3wahDNnneNVSl1sQhMPfz2dUXaIDVJfy0wZBU,3168 +numpy/distutils/fcompiler/fujitsu.py,sha256=g4dTLDFfLRAzhYayIwyHGBw1Y36DKtPOCYfA823ldNA,1379 +numpy/distutils/fcompiler/g95.py,sha256=1TJe4IynWYqqYBy8gJ-nz8WQ_TaSbv8k2UzUIY5Erqc,1372 +numpy/distutils/fcompiler/gnu.py,sha256=k0PYSVpEbgjFszkaMTcD0HvQim_isx8KK7gQYW1_GDI,20775 +numpy/distutils/fcompiler/hpux.py,sha256=SLbDOPYgiixqE32GgUrAJjpDLFy9g7E01vGNZCGv6Pc,1394 +numpy/distutils/fcompiler/ibm.py,sha256=jL9fOpUU9g1Qx3wFqv34ow6LMq8TOSZ3EAwUb1bXs_c,3638 +numpy/distutils/fcompiler/intel.py,sha256=3nBmdhH8pRMyNZfkMU0MaJGkRxVQg3wh8AOduXCjRRs,7029 +numpy/distutils/fcompiler/lahey.py,sha256=EV3Zhwq-iowWAu4BFBPv_UGJ-IB-qxlxmi6WU1qHDOs,1372 +numpy/distutils/fcompiler/mips.py,sha256=mlUNgGrRSLnNhtxQXWVfC9l4_OP2GMvOkgbZQwBon0A,1768 +numpy/distutils/fcompiler/nag.py,sha256=3ViQnBrZBhgm-t-jvjZ_Hl_fq9s2O5FBMNwW6wOmU2Q,2624 +numpy/distutils/fcompiler/none.py,sha256=auMK2ou1WtJ20LeMbwCZJ3XofpT9A0YYbMVd-62Mi_E,786 +numpy/distutils/fcompiler/nv.py,sha256=ml2xco_01pGH9x23Qv-3yalFzTk-GK45BVJoDMlGod4,1627 +numpy/distutils/fcompiler/pathf95.py,sha256=ipbaZIO8sqPJ1lUppOurnboiTwRzIasWNAJvKmktvv4,1094 +numpy/distutils/fcompiler/pg.py,sha256=cVcSFM9oR0KmO5AIb4Odw9OGslW6zvDGP88n-uEwxvQ,3696 +numpy/distutils/fcompiler/sun.py,sha256=JMdFfKldTYlfW1DxV7nR09k5PZypKLWpP7wmQzmlnH0,1628 +numpy/distutils/fcompiler/vast.py,sha256=JUGP68JGOUOBS9WbXftE-qCVUD13fpLyPnhpHfTL5y0,1719 +numpy/distutils/from_template.py,sha256=lL0BhwJHz7OrMwocJnnUElgzv8vVkZdr6NupI1ZnsLw,8224 +numpy/distutils/intelccompiler.py,sha256=kVXrdCVY7YA6HdYI89De3Fy5lCjAwDpy2mrbpK7Lc10,4336 +numpy/distutils/lib2def.py,sha256=HQ7i5FUtBcFGNlSlN20lgVtiBAHQbGXxmYdvkaJTjLI,3760 +numpy/distutils/line_endings.py,sha256=hlI71r840mhfu8lmzdHPVZ4NFm-kJDDUMV3lETblVTY,2109 +numpy/distutils/log.py,sha256=9tqE2Tq55mugFj_pn-RwV1xFoejmk0yWvVQHBL1e-Gc,2652 +numpy/distutils/mingw/gfortran_vs2003_hack.c,sha256=FDTA53KYTIhil9ytvZlocOqghQVp9LacLHn1IurV0wI,83 +numpy/distutils/mingw32ccompiler.py,sha256=Pt2fhKRw6axhlV2ahCS3Ep0vj-LfCdnCOEfvLRsCMFM,26073 +numpy/distutils/misc_util.py,sha256=RYrU7Fhutl-ClKdWkgllGzXPL1Ky7hsjbrgkDD5elJ0,87912 +numpy/distutils/msvc9compiler.py,sha256=bCtCVJmGrBHPm9sOoxa3oSrdrEVCNQFEM5O5hdqX8Hc,2255 +numpy/distutils/msvccompiler.py,sha256=sGGkjB-iSQFEfsMfQY8ZJfPKs6vm2DY9Y_OKi0Fk__0,1986 +numpy/distutils/npy_pkg_config.py,sha256=4CMG6sN7HAFSmw2ljPAAN5f04wdnZECkFXZcKoX06f0,13409 +numpy/distutils/numpy_distribution.py,sha256=nrdp8rlyjEBBV1tzzi5cE-aYeXB5U3X8T5-G0akXSoY,651 +numpy/distutils/pathccompiler.py,sha256=a5CYDXilCaIC85v0fVh-wrb0fClv0A7mPS87aF1inUc,734 +numpy/distutils/setup.py,sha256=zd5_kD7uTEOTgC8Fe93g9A_5AOBEySWwr-2OxHsBBEc,651 +numpy/distutils/system_info.py,sha256=4V-OxZ6-rlUBGTuUPn0_sFiQ4MHsuNCdCxXMDCOW6_U,111097 +numpy/distutils/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +numpy/distutils/tests/__pycache__/__init__.cpython-39.pyc,, +numpy/distutils/tests/__pycache__/test_build_ext.cpython-39.pyc,, +numpy/distutils/tests/__pycache__/test_ccompiler_opt.cpython-39.pyc,, +numpy/distutils/tests/__pycache__/test_ccompiler_opt_conf.cpython-39.pyc,, +numpy/distutils/tests/__pycache__/test_exec_command.cpython-39.pyc,, +numpy/distutils/tests/__pycache__/test_fcompiler.cpython-39.pyc,, +numpy/distutils/tests/__pycache__/test_fcompiler_gnu.cpython-39.pyc,, +numpy/distutils/tests/__pycache__/test_fcompiler_intel.cpython-39.pyc,, +numpy/distutils/tests/__pycache__/test_fcompiler_nagfor.cpython-39.pyc,, +numpy/distutils/tests/__pycache__/test_from_template.cpython-39.pyc,, +numpy/distutils/tests/__pycache__/test_mingw32ccompiler.cpython-39.pyc,, +numpy/distutils/tests/__pycache__/test_misc_util.cpython-39.pyc,, +numpy/distutils/tests/__pycache__/test_npy_pkg_config.cpython-39.pyc,, +numpy/distutils/tests/__pycache__/test_shell_utils.cpython-39.pyc,, +numpy/distutils/tests/__pycache__/test_system_info.cpython-39.pyc,, +numpy/distutils/tests/test_build_ext.py,sha256=te4h-jzABgSF_efL2LC-Hwc3hlq8lfqg5JEeHGQgV3A,2736 +numpy/distutils/tests/test_ccompiler_opt.py,sha256=XSKyD1o3GsQOO0MiVBHSrIOBwTk1Z1f9_3BfdpZWlSA,28676 +numpy/distutils/tests/test_ccompiler_opt_conf.py,sha256=LmFqpGwqGFgUwLQdV5xJQhs_xB9gnL7_P-7oOOUqa78,6521 +numpy/distutils/tests/test_exec_command.py,sha256=Ltd4T3A_t3Oo_QSYjOkWKqPj-LttXEumEVKhLxVfZEU,7515 +numpy/distutils/tests/test_fcompiler.py,sha256=SS5HOLIg0eqkmZTRKeWq9_ahW2tmV9c9piwYfzcBPmc,1320 +numpy/distutils/tests/test_fcompiler_gnu.py,sha256=RlRHZbyazgKGY17NmdYSF3ehO0M0xXN4UkbsJzJz4i8,2191 +numpy/distutils/tests/test_fcompiler_intel.py,sha256=4cppjLugoa8P4bjzYdiPxmyCywmP9plXOkfsklhnYsQ,1088 +numpy/distutils/tests/test_fcompiler_nagfor.py,sha256=ntyr8f-67dNI0OF_l6-aeTwu9wW-vnxpheqrc4cXAUI,1124 +numpy/distutils/tests/test_from_template.py,sha256=ZzUSEPyZIG4Zak3-TFqmRGXHMp58aKTuLKb0t-5XpDg,1147 +numpy/distutils/tests/test_mingw32ccompiler.py,sha256=7X8V4hLMtsNj1pYoLkSSla04gJu66e87E_k-6ce3PrA,1651 +numpy/distutils/tests/test_misc_util.py,sha256=YKK2WrJqVJ5o71mWL5oP0l-EVQmqKlf3XU8y7co0KYc,3300 +numpy/distutils/tests/test_npy_pkg_config.py,sha256=1pQh-mApHjj0y9Ba2tqns79U8dsfDpJ9zcPdsa2qbps,2641 +numpy/distutils/tests/test_shell_utils.py,sha256=okNSfjFSAvY3XyBsyZrKXAtV9RBmb7vX9o4ZLJc28Ds,2030 +numpy/distutils/tests/test_system_info.py,sha256=ALNf8Vqw6d9Gv6ELtWmQT9Byy5LWv4ZIPMOVXQfIqsk,11065 +numpy/distutils/unixccompiler.py,sha256=9ug-F8LGBrrwuC8U00JhjokgH7L0BPvLhFJLg6REQ1I,5517 +numpy/doc/__init__.py,sha256=llSbqjSXybPuXqt6WJFZhgYnscgYl4m1tUBy_LhfCE0,534 +numpy/doc/__pycache__/__init__.cpython-39.pyc,, +numpy/doc/__pycache__/constants.cpython-39.pyc,, +numpy/doc/__pycache__/ufuncs.cpython-39.pyc,, +numpy/doc/constants.py,sha256=OtjYHSs9p_DxLDqhlbauLMt-WWVrnewaHlUJCi3Qw_Y,9592 +numpy/doc/ufuncs.py,sha256=jL-idm49Qd8xNns12ZPp533jorDuDnUN2I96hbmFZoo,5497 +numpy/dual.py,sha256=RgoFIabqn8Hu9lSRakjO1plfDdYBJQq_8Gn__rE8TqQ,2297 +numpy/emath.pyi,sha256=-9BhMfuGE3vYfdpqbHDXyQsFeUzydkfHbRWxSFJhLA8,161 +numpy/f2py/__init__.py,sha256=eBq1wR_5aSMEhbF4COOM2uBW70GBP_WLBlgyFZBVj1M,4377 +numpy/f2py/__init__.pyi,sha256=c7BkZSruptvVxdLmt_6FgxgMSVS4A8FgaQnx9V4dYdw,102 +numpy/f2py/__main__.py,sha256=XSvcMI54qWQiicJ51nRxK8L8PGzuUy3c2NGTVg1tzyk,89 +numpy/f2py/__pycache__/__init__.cpython-39.pyc,, +numpy/f2py/__pycache__/__main__.cpython-39.pyc,, +numpy/f2py/__pycache__/__version__.cpython-39.pyc,, +numpy/f2py/__pycache__/auxfuncs.cpython-39.pyc,, +numpy/f2py/__pycache__/capi_maps.cpython-39.pyc,, +numpy/f2py/__pycache__/cb_rules.cpython-39.pyc,, +numpy/f2py/__pycache__/cfuncs.cpython-39.pyc,, +numpy/f2py/__pycache__/common_rules.cpython-39.pyc,, +numpy/f2py/__pycache__/crackfortran.cpython-39.pyc,, +numpy/f2py/__pycache__/diagnose.cpython-39.pyc,, +numpy/f2py/__pycache__/f2py2e.cpython-39.pyc,, +numpy/f2py/__pycache__/f2py_testing.cpython-39.pyc,, +numpy/f2py/__pycache__/f90mod_rules.cpython-39.pyc,, +numpy/f2py/__pycache__/func2subr.cpython-39.pyc,, +numpy/f2py/__pycache__/rules.cpython-39.pyc,, +numpy/f2py/__pycache__/setup.cpython-39.pyc,, +numpy/f2py/__pycache__/use_rules.cpython-39.pyc,, +numpy/f2py/__version__.py,sha256=TisKvgcg4vh5Fptw2GS1JB_3bAQsWZIKhclEX6ZcAho,35 +numpy/f2py/auxfuncs.py,sha256=d8xZkZ2Jom_FX4ALxQO4v2Uqsfi62rZEiqSH30AGpyA,22701 +numpy/f2py/capi_maps.py,sha256=pGERvcXuv3wpq2ab3inTTTdv20G1XZz2tMVn0_yVYDM,32247 +numpy/f2py/cb_rules.py,sha256=BYaZ0xIcL2tsKbHL3aak61vXY3EChSQbgmJSZKf4Lw4,24862 +numpy/f2py/cfuncs.py,sha256=h57r6lALK2NURzMYW7H1eHw8EFCcCanEiu7RWzUylPo,48009 +numpy/f2py/common_rules.py,sha256=pRpoVr457G3JcTD_W4V0AmgQBzAIKcqPw4j_Hv3elF0,5070 +numpy/f2py/crackfortran.py,sha256=EGernuGKvWb5wkyMoIcbliQEJrkIDIpEHfUQHrmahY8,134370 +numpy/f2py/diagnose.py,sha256=LmGu6iZKr9WHfMZFIIEobZvRJd9Ktdqx0nYekWk4N7g,5384 +numpy/f2py/f2py2e.py,sha256=an58iVb6nFOhUwT4xYN6GJcmabo-fNTxXtj7CkUICVI,25033 +numpy/f2py/f2py_testing.py,sha256=vybOK-G_b0KYFNNZdhOCUf5pZExEdWfcIueIKODu024,1503 +numpy/f2py/f90mod_rules.py,sha256=umkXYf5Y6TrJ77DIZX0L0xemyFQ2sfe7M63f71A94hs,10017 +numpy/f2py/func2subr.py,sha256=-e2VG2t0YDEOO_jIhLZRFLg5uoIoPGtcjir-4BzdNCs,9655 +numpy/f2py/rules.py,sha256=El8aYnKkj1gAgjQ15lzRW6E_uyMdLI1FEGS13Nvw1kI,60201 +numpy/f2py/setup.py,sha256=Qoa3e1-WsSeayGHlVqZ9x5eIEOBeMAOtqTP331STQAk,2533 +numpy/f2py/src/fortranobject.c,sha256=IeezP69rVbNBR7umIUirrEZyGThU5Yhx3fV2olh9TMs,37559 +numpy/f2py/src/fortranobject.h,sha256=kwkaaaO0nsg7I-I0HpVAlOy-eiuvhKbhSZrEUWJvBaU,4656 +numpy/f2py/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +numpy/f2py/tests/__pycache__/__init__.cpython-39.pyc,, +numpy/f2py/tests/__pycache__/test_array_from_pyobj.cpython-39.pyc,, +numpy/f2py/tests/__pycache__/test_assumed_shape.cpython-39.pyc,, +numpy/f2py/tests/__pycache__/test_block_docstring.cpython-39.pyc,, +numpy/f2py/tests/__pycache__/test_callback.cpython-39.pyc,, +numpy/f2py/tests/__pycache__/test_common.cpython-39.pyc,, +numpy/f2py/tests/__pycache__/test_compile_function.cpython-39.pyc,, +numpy/f2py/tests/__pycache__/test_crackfortran.cpython-39.pyc,, +numpy/f2py/tests/__pycache__/test_kind.cpython-39.pyc,, +numpy/f2py/tests/__pycache__/test_mixed.cpython-39.pyc,, +numpy/f2py/tests/__pycache__/test_module_doc.cpython-39.pyc,, +numpy/f2py/tests/__pycache__/test_parameter.cpython-39.pyc,, +numpy/f2py/tests/__pycache__/test_quoted_character.cpython-39.pyc,, +numpy/f2py/tests/__pycache__/test_regression.cpython-39.pyc,, +numpy/f2py/tests/__pycache__/test_return_character.cpython-39.pyc,, +numpy/f2py/tests/__pycache__/test_return_complex.cpython-39.pyc,, +numpy/f2py/tests/__pycache__/test_return_integer.cpython-39.pyc,, +numpy/f2py/tests/__pycache__/test_return_logical.cpython-39.pyc,, +numpy/f2py/tests/__pycache__/test_return_real.cpython-39.pyc,, +numpy/f2py/tests/__pycache__/test_semicolon_split.cpython-39.pyc,, +numpy/f2py/tests/__pycache__/test_size.cpython-39.pyc,, +numpy/f2py/tests/__pycache__/test_string.cpython-39.pyc,, +numpy/f2py/tests/__pycache__/util.cpython-39.pyc,, +numpy/f2py/tests/src/array_from_pyobj/wrapmodule.c,sha256=56WWwGvAipTqHyshtz8jLLZ7gNHpzC5h_jCyIciFGLc,7511 +numpy/f2py/tests/src/assumed_shape/.f2py_f2cmap,sha256=zfuOShmuotzcLIQDnVFaARwvM66iLrOYzpquIGDbiKU,30 +numpy/f2py/tests/src/assumed_shape/foo_free.f90,sha256=fqbSr7VlKfVrBulFgQtQA9fQf0mQvVbLi94e4FTST3k,494 +numpy/f2py/tests/src/assumed_shape/foo_mod.f90,sha256=9pbi88-uSNP5IwS49Kim982jDAuopo3tpEhg2SOU7no,540 +numpy/f2py/tests/src/assumed_shape/foo_use.f90,sha256=9Cl1sdrihB8cCSsjoQGmOO8VRv9ni8Fjr0Aku1UdEWM,288 +numpy/f2py/tests/src/assumed_shape/precision.f90,sha256=3L_F7n5ju9F0nxw95uBUaPeuiDOw6uHvB580eIj7bqI,134 +numpy/f2py/tests/src/common/block.f,sha256=tcGKa42S-6bfA6fybpM0Su_xjysEVustkEJoF51o_pE,235 +numpy/f2py/tests/src/kind/foo.f90,sha256=6_zq3OAWsuNJ5ftGTQAEynkHy-MnuLgBXmMIgbvL7yU,367 +numpy/f2py/tests/src/mixed/foo.f,sha256=Zgn0xDhhzfas3HrzgVSxIL1lGEF2mFRVohrvXN1thU0,90 +numpy/f2py/tests/src/mixed/foo_fixed.f90,sha256=6eEEYCH71gPp6lZ6e2afLrfS6F_fdP7GZDbgGJJ_6ns,187 +numpy/f2py/tests/src/mixed/foo_free.f90,sha256=UC6iVRcm0-aVXAILE5jZhivoGQbKU-prqv59HTbxUJA,147 +numpy/f2py/tests/src/module_data/mod.mod,sha256=EkjrU7NTZrOH68yKrz6C_eyJMSFSxGgC2yMQT9Zscek,412 +numpy/f2py/tests/src/module_data/module_data_docstring.f90,sha256=-asnMH7vZMwVIeMU2YiLWgYCUUUxZgPTpbAomgWByHs,236 +numpy/f2py/tests/src/parameter/constant_both.f90,sha256=L0rG6-ClvHx7Qsch46BUXRi_oIEL0uw5dpRHdOUQuv0,1996 +numpy/f2py/tests/src/parameter/constant_compound.f90,sha256=lAT76HcXGMgr1NfKof-RIX3W2P_ik1PPqkRdJ6EyBmM,484 +numpy/f2py/tests/src/parameter/constant_integer.f90,sha256=42jROArrG7vIag9wFa_Rr5DBnnNvGsrEUgpPU14vfIo,634 +numpy/f2py/tests/src/parameter/constant_non_compound.f90,sha256=u9MRf894Cw0MVlSOUbMSnFSHP4Icz7RBO21QfMkIl-Q,632 +numpy/f2py/tests/src/parameter/constant_real.f90,sha256=QoPgKiHWrwI7w5ctYZugXWzaQsqSfGMO7Jskbg4CLTc,633 +numpy/f2py/tests/src/regression/inout.f90,sha256=TlMxJjhjjiuLI--Tg2LshLnbfZpiKz37EpR_tPKKSx8,286 +numpy/f2py/tests/src/size/foo.f90,sha256=nK_767f1TtqVr-dMalNkXmcKbSbLCiabhRkxSDCzLz0,859 +numpy/f2py/tests/src/string/char.f90,sha256=X_soOEV8cKsVZefi3iLT7ilHljjvJJ_i9VEHWOt0T9Y,647 +numpy/f2py/tests/test_array_from_pyobj.py,sha256=kxy7M9V0YHzRl9Cpn0J3WEnDZ7NRA4wL_6yrKVegLu0,23243 +numpy/f2py/tests/test_assumed_shape.py,sha256=TDLfEzJc7tlfiqFzmonD8LO85PXySgJ4JE_5IZTzinA,1637 +numpy/f2py/tests/test_block_docstring.py,sha256=AFgfCimjB0gcmqfyHhTmfRVCrMZunkIueoZGrV9SbaA,650 +numpy/f2py/tests/test_callback.py,sha256=QFvuUSetf9OA5yD9ti5MhNitIJE7n9wZXM_wkVacz1U,8513 +numpy/f2py/tests/test_common.py,sha256=tRwTdz6aQ0RYREFC-T-SfEyq25wWYo5pknVAqvvvBjM,827 +numpy/f2py/tests/test_compile_function.py,sha256=d2zOi1oPKwqSMBILFSUuJeIX3BY6uAOBZnvYw5h3K54,4434 +numpy/f2py/tests/test_crackfortran.py,sha256=QwNp0PHGmN00A3RTwDekXzTfTDQ2uDjK_-Hupxc-YpU,3700 +numpy/f2py/tests/test_kind.py,sha256=eH_sM5X5wIwe3T9yVMH6DH8I4spsgRaeIork_FJG-8Q,1044 +numpy/f2py/tests/test_mixed.py,sha256=faYM1laPKwStbz-RY-6b9LCuj2kFojTPIR0wxsosXoI,946 +numpy/f2py/tests/test_module_doc.py,sha256=Qz_TonbInzgdY8KsnC2Y8mxmiqLWMruZKDPa0FPMbrE,980 +numpy/f2py/tests/test_parameter.py,sha256=S1K9K9Uj5dWjmWF8euBUMJdGilIqn1nNH2FftcS1INU,4026 +numpy/f2py/tests/test_quoted_character.py,sha256=81CR1ZIyKygz7noFJMcgaLdg18nY8zcFfrSN2L_U9xg,959 +numpy/f2py/tests/test_regression.py,sha256=AbSCx5JfsiM2VeRRmVk1G3AbHPOS7FIqhCYBlSVquSY,1690 +numpy/f2py/tests/test_return_character.py,sha256=bpuHEjBj53YpvsI_aLQOcSVdoGAEtgtmAK8kbHKdcgc,4064 +numpy/f2py/tests/test_return_complex.py,sha256=jYcoM3pZj0opGXXF69EsGQ6HD5SPaRhBeGx3RhnJx8c,4778 +numpy/f2py/tests/test_return_integer.py,sha256=MpdNZLxeQwER4M4w5utHYe08gDzrjAWOq_z5wRO8hP8,4751 +numpy/f2py/tests/test_return_logical.py,sha256=uP9rWNyA3UARKwaQ6Fsc8grh72G5xnp9XXFSWLdPZQ8,5028 +numpy/f2py/tests/test_return_real.py,sha256=05OwUsgmI_G_pr197xUXgIgTNVOHygtY2kPqRiexeSY,5605 +numpy/f2py/tests/test_semicolon_split.py,sha256=Ap6S5tGL6R8I2i9iUlVxElW4IMNoz0LxIHK1hLIYZhQ,1577 +numpy/f2py/tests/test_size.py,sha256=ukbP0NlzqpfD6M_K58WK6IERSXc_6nHpyUqbYfEbk8M,1335 +numpy/f2py/tests/test_string.py,sha256=w2GiZmdwNAaWOBhak9IuUnnVktMhUq_Y0ajI0SX9YNY,632 +numpy/f2py/tests/util.py,sha256=QkIepB1CsYTTHl-F9Quvwg2uV5gBmpuGMn-VOVrJLvw,9947 +numpy/f2py/use_rules.py,sha256=ROzvjl0-GUOkT3kJS5KkYq8PsFxGjebA6uPq9-CyZEQ,3700 +numpy/fft/__init__.py,sha256=bxBM1d7FfUlcIr0dF-zJ_UjXDNzc0FFnopv6WdwcQvg,8287 +numpy/fft/__init__.pyi,sha256=ETk_OFyBtOJDyQ7ImyZOnm_dXUdE89wSkyxxbLU0Sq0,249 +numpy/fft/__pycache__/__init__.cpython-39.pyc,, +numpy/fft/__pycache__/_pocketfft.cpython-39.pyc,, +numpy/fft/__pycache__/helper.cpython-39.pyc,, +numpy/fft/__pycache__/setup.cpython-39.pyc,, +numpy/fft/_pocketfft.py,sha256=2AvZn4Oga8NNVxxu5Kjq692QElycysShG3jqhbJvHWY,53572 +numpy/fft/_pocketfft_internal.cp39-win_amd64.pyd,sha256=1n84fjYm1j1Euqt8s_fqyf4Vclz3KHKctOftJ1pliXQ,112640 +numpy/fft/helper.py,sha256=divqfKoOb0p-Zojqokhj3fQ5HzgWTigxDxZIQnN_TUQ,6375 +numpy/fft/setup.py,sha256=-aF3b5s_eL6Jl0rS_jMFtFPzbYyT55FQE2SgblAawf0,750 +numpy/fft/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +numpy/fft/tests/__pycache__/__init__.cpython-39.pyc,, +numpy/fft/tests/__pycache__/test_helper.cpython-39.pyc,, +numpy/fft/tests/__pycache__/test_pocketfft.cpython-39.pyc,, +numpy/fft/tests/test_helper.py,sha256=iopdl7-SHA5E1Ex13rYdceskgoDI5T8_Kg12LfqK1HA,6315 +numpy/fft/tests/test_pocketfft.py,sha256=GraHId7HW81sK62wFoF2y4nt2bL6MqkPjkG12OPmgNo,13135 +numpy/lib/__init__.py,sha256=D_APB98cfipadeVf9KXXCg4MRYwNl_JrjbrJ_Fityhc,1840 +numpy/lib/__init__.pyi,sha256=jj6Fi0pQKDKMc5CZnKTB6_gwUebBguoKL79CLK1hGFM,2874 +numpy/lib/__pycache__/__init__.cpython-39.pyc,, +numpy/lib/__pycache__/_datasource.cpython-39.pyc,, +numpy/lib/__pycache__/_iotools.cpython-39.pyc,, +numpy/lib/__pycache__/_version.cpython-39.pyc,, +numpy/lib/__pycache__/arraypad.cpython-39.pyc,, +numpy/lib/__pycache__/arraysetops.cpython-39.pyc,, +numpy/lib/__pycache__/arrayterator.cpython-39.pyc,, +numpy/lib/__pycache__/format.cpython-39.pyc,, +numpy/lib/__pycache__/function_base.cpython-39.pyc,, +numpy/lib/__pycache__/histograms.cpython-39.pyc,, +numpy/lib/__pycache__/index_tricks.cpython-39.pyc,, +numpy/lib/__pycache__/mixins.cpython-39.pyc,, +numpy/lib/__pycache__/nanfunctions.cpython-39.pyc,, +numpy/lib/__pycache__/npyio.cpython-39.pyc,, +numpy/lib/__pycache__/polynomial.cpython-39.pyc,, +numpy/lib/__pycache__/recfunctions.cpython-39.pyc,, +numpy/lib/__pycache__/scimath.cpython-39.pyc,, +numpy/lib/__pycache__/setup.cpython-39.pyc,, +numpy/lib/__pycache__/shape_base.cpython-39.pyc,, +numpy/lib/__pycache__/stride_tricks.cpython-39.pyc,, +numpy/lib/__pycache__/twodim_base.cpython-39.pyc,, +numpy/lib/__pycache__/type_check.cpython-39.pyc,, +numpy/lib/__pycache__/ufunclike.cpython-39.pyc,, +numpy/lib/__pycache__/user_array.cpython-39.pyc,, +numpy/lib/__pycache__/utils.cpython-39.pyc,, +numpy/lib/_datasource.py,sha256=cfOLMUd6-hFI7HYrm8DJHJSGOBZZ49kEWWXB9aagPr4,23337 +numpy/lib/_iotools.py,sha256=PYVfEUIITyUmIvWS8-0CSLegJjKgDysKwYmro1yVrZ8,31834 +numpy/lib/_version.py,sha256=syCq5PJX3QCmhjIR4nO1HG2YWPTarArAR-7m8dv93gk,5010 +numpy/lib/arraypad.py,sha256=V4iW49CT3KyPHdVK-4Q2kjJqgEb-N35LusA6G-Q2LKU,32102 +numpy/lib/arraysetops.py,sha256=_mkMzedSHws9E5Dnw0s6fUyaQAvFeRqbuQuw4XsNdII,26111 +numpy/lib/arrayterator.py,sha256=29pO5S0ciEZwt1402Q0-5cRbyKspV4tlPX1-m_D_Hgc,7282 +numpy/lib/format.py,sha256=sSf6H4mcz-SI7cMw31VYJwIwapFCLWacCObkccP3pYw,32192 +numpy/lib/function_base.py,sha256=oa092RcFcRJp7JN1jP9eLOzTLbzOYEsW908IAUW9FPc,163639 +numpy/lib/histograms.py,sha256=sJNjLvJLQCmPTIlwMsrtOmFK2SxxyQn6-9gmBBsQa14,41261 +numpy/lib/index_tricks.py,sha256=kPia5ya0_USggzPtyvPNFwGmz1-WNk4Gtjrf3XmDXbQ,31655 +numpy/lib/mixins.py,sha256=j_Hfrfp6d6lJAVFlM9y2lu6HHsK_yDInyU74SJWsZDQ,7228 +numpy/lib/nanfunctions.py,sha256=j4ziL7zNzjW4YMOadZxaa6kRcauErJCOBGZhZLbbwq8,60599 +numpy/lib/npyio.py,sha256=AeeyiEWUX1QdkMi1HuwMzS2NB221hLQXeCiK_zjIg2M,91899 +numpy/lib/polynomial.py,sha256=uDsiJVN8lrKVyZcVfqAMTudO7otOMCoLd9G3tHKq6NE,45253 +numpy/lib/recfunctions.py,sha256=G_GYahtsPjRK7uknYmXMpm1p96eHPzguzWBVtldi_uw,58119 +numpy/lib/scimath.py,sha256=JSMIr5maF4dBwvCHM6MOHa7kgOSXtwxb1QxEV09qs6A,15484 +numpy/lib/setup.py,sha256=1s3corE4egZnDZ6I8au_mx7muRPgb3ZxL4Ko2SHt_2Q,417 +numpy/lib/shape_base.py,sha256=7p8SSRXNk5BdcwuEwINFtq60mYQY6vFfMvTO8Cubvro,39627 +numpy/lib/stride_tricks.py,sha256=-hzSjUTw_0VXfzdHZ3afGQlP6UP3oHBdX0VcGE0PMgg,18389 +numpy/lib/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +numpy/lib/tests/__pycache__/__init__.cpython-39.pyc,, +numpy/lib/tests/__pycache__/test__datasource.cpython-39.pyc,, +numpy/lib/tests/__pycache__/test__iotools.cpython-39.pyc,, +numpy/lib/tests/__pycache__/test__version.cpython-39.pyc,, +numpy/lib/tests/__pycache__/test_arraypad.cpython-39.pyc,, +numpy/lib/tests/__pycache__/test_arraysetops.cpython-39.pyc,, +numpy/lib/tests/__pycache__/test_arrayterator.cpython-39.pyc,, +numpy/lib/tests/__pycache__/test_financial_expired.cpython-39.pyc,, +numpy/lib/tests/__pycache__/test_format.cpython-39.pyc,, +numpy/lib/tests/__pycache__/test_function_base.cpython-39.pyc,, +numpy/lib/tests/__pycache__/test_histograms.cpython-39.pyc,, +numpy/lib/tests/__pycache__/test_index_tricks.cpython-39.pyc,, +numpy/lib/tests/__pycache__/test_io.cpython-39.pyc,, +numpy/lib/tests/__pycache__/test_mixins.cpython-39.pyc,, +numpy/lib/tests/__pycache__/test_nanfunctions.cpython-39.pyc,, +numpy/lib/tests/__pycache__/test_packbits.cpython-39.pyc,, +numpy/lib/tests/__pycache__/test_polynomial.cpython-39.pyc,, +numpy/lib/tests/__pycache__/test_recfunctions.cpython-39.pyc,, +numpy/lib/tests/__pycache__/test_regression.cpython-39.pyc,, +numpy/lib/tests/__pycache__/test_shape_base.cpython-39.pyc,, +numpy/lib/tests/__pycache__/test_stride_tricks.cpython-39.pyc,, +numpy/lib/tests/__pycache__/test_twodim_base.cpython-39.pyc,, +numpy/lib/tests/__pycache__/test_type_check.cpython-39.pyc,, +numpy/lib/tests/__pycache__/test_ufunclike.cpython-39.pyc,, +numpy/lib/tests/__pycache__/test_utils.cpython-39.pyc,, +numpy/lib/tests/data/py2-objarr.npy,sha256=F4cyUC-_TB9QSFLAo2c7c44rC6NUYIgrfGx9PqWPSKk,258 +numpy/lib/tests/data/py2-objarr.npz,sha256=xo13HBT0FbFZ2qvZz0LWGDb3SuQASSaXh7rKfVcJjx4,366 +numpy/lib/tests/data/py3-objarr.npy,sha256=pTTVh8ezp-lwAK3fkgvdKU8Arp5NMKznVD-M6Ex_uA0,341 +numpy/lib/tests/data/py3-objarr.npz,sha256=qQR0gS57e9ta16d_vCQjaaKM74gPdlwCPkp55P-qrdw,449 +numpy/lib/tests/data/python3.npy,sha256=X0ad3hAaLGXig9LtSHAo-BgOvLlFfPYMnZuVIxRmj-0,96 +numpy/lib/tests/data/win64python2.npy,sha256=agOcgHVYFJrV-nrRJDbGnUnF4ZTPYXuSeF-Mtg7GMpc,96 +numpy/lib/tests/test__datasource.py,sha256=OYm6qsPy7Q8yXV_5GfSMMNQKon4izf_T9ULaqjHLJA4,10837 +numpy/lib/tests/test__iotools.py,sha256=q44VFSi9VzWaf_dJ-MGBtYA7z7TFR0j0AF-rbzhLXoo,14096 +numpy/lib/tests/test__version.py,sha256=WwCOmobk2UN6Hlp93bXsd7RR1UmjJlE4r9ol8d87ctg,2053 +numpy/lib/tests/test_arraypad.py,sha256=ZoqM25xb5iI_K6ampX5cov2zFUwQZ8i0Xu3gY_ncdk0,55647 +numpy/lib/tests/test_arraysetops.py,sha256=ovgWXCWzaKvC-OXtWJx8MrSsdQsLTj3NjqLbxhhHEv0,25173 +numpy/lib/tests/test_arrayterator.py,sha256=IRVmzxbr9idboJjOHKuX_8NQhMAKs7pD1xWqmU3ZERw,1337 +numpy/lib/tests/test_financial_expired.py,sha256=JfDHAoEDLPcKzcpzRsj8pijDSaFmQRWM6BiOjL4QFTs,371 +numpy/lib/tests/test_format.py,sha256=E5ISt5uKyqXCwLD7UZK1TM4SagXAdxxHav7yKz6TIls,39223 +numpy/lib/tests/test_function_base.py,sha256=N78mv4u7xUGsRgR6hBQ0zoZNFxSWOj3cwUoFwIkqJqc,136484 +numpy/lib/tests/test_histograms.py,sha256=_uKM8dtMWCwGtIgIwog3s3jyPb8w804TWqy9iOkYeSI,34510 +numpy/lib/tests/test_index_tricks.py,sha256=eqVGE3ML61U9zOepbPF2X24qVDCaOr2eWnR5p5CzFcw,19832 +numpy/lib/tests/test_io.py,sha256=ZEYwCEDx8SEa_EPhHjCRLlNsa-ONI1Cis_opkGs7V3Y,105599 +numpy/lib/tests/test_mixins.py,sha256=nIec_DZIDx7ONnlpq_Y2TLkIULAPvQ7LPqtMwEHuV4U,7246 +numpy/lib/tests/test_nanfunctions.py,sha256=d26Ynihtb2BIZ1N-qfBagm8lkba0hR-m3g2GtngbTRE,39066 +numpy/lib/tests/test_packbits.py,sha256=XpFIaL8mOWfzD3WQaxd6WrDFWh4Mc51EPXIOqxt3wS0,17922 +numpy/lib/tests/test_polynomial.py,sha256=fxIQBimaH0ZYXcWJYPBBtpWDpYzstABF_BBROu-vCfc,10995 +numpy/lib/tests/test_recfunctions.py,sha256=f9J49n_8ot0zG0Bw4XXFx3l1XN2VeAu9ROgn0dV4GLY,42134 +numpy/lib/tests/test_regression.py,sha256=NXKpFka0DPE7z0-DID-FGh0ITFXi8nEj6Pg_-uBcDIg,8504 +numpy/lib/tests/test_shape_base.py,sha256=kC4k86CdiwUoqBs_KjAc_JekFJLVtlbanlPrXXXpWRU,25020 +numpy/lib/tests/test_stride_tricks.py,sha256=1zeBcvhltePbeE6SBoF4gomAYaZzwaHjvbWqcgI2JiY,23494 +numpy/lib/tests/test_twodim_base.py,sha256=USISKs6mDYgEl20k4_k899_pWSkFjZkPkafA_BUQxng,18890 +numpy/lib/tests/test_type_check.py,sha256=ffuA-ndaMsUb0IvPalBMwGkoukIP9OZVJXCuq299qB8,15597 +numpy/lib/tests/test_ufunclike.py,sha256=rpZTDbKPBVg5-byY1SKhkukyxB2Lvonw15ZARPE3mc0,3382 +numpy/lib/tests/test_utils.py,sha256=3uWGoBytyV-jtAt6Fnp812iVWKZw5KI9TV_7ApS3u98,4407 +numpy/lib/twodim_base.py,sha256=TCNDw28Hs8bze0v4dosVW0vqtDtSfac69EA51Wb8a9Y,29405 +numpy/lib/type_check.py,sha256=WK5a3RgaIVoKqskfvG-U6VHiZyMNrfswV-9SBb5RxbU,20500 +numpy/lib/ufunclike.py,sha256=D6NgciDjA0ETqfzX9lDzuArgPOWccl3-nws48_IMwYo,8211 +numpy/lib/user_array.py,sha256=5yqkyjCmUIASGNx2bt7_ZMWJQJszkbD1Kn06qqv7POA,8007 +numpy/lib/utils.py,sha256=DYd-12yhdzf1l8CLSZ8gOBNBItYLvsX0mHgXMaehuY0,32675 +numpy/linalg/__init__.py,sha256=nziJvIBC-t0x_9SjOrlgcorUR03gdviaCWhbvvPIT7s,1836 +numpy/linalg/__init__.pyi,sha256=WL2hPYvsgtbNG0rKAhZl9h6eLL1nw1ZCp8dNiarGHYk,306 +numpy/linalg/__pycache__/__init__.cpython-39.pyc,, +numpy/linalg/__pycache__/linalg.cpython-39.pyc,, +numpy/linalg/__pycache__/setup.cpython-39.pyc,, +numpy/linalg/_umath_linalg.cp39-win_amd64.pyd,sha256=6bzuRvWkT0lNbLutvrsJbYRgd745nS4rT9wboPbIvPo,155648 +numpy/linalg/lapack_lite.cp39-win_amd64.pyd,sha256=gfj5jrP42QmGHLx9z1x-BVUJE6w0rx06J7jYrzJ4RcI,22016 +numpy/linalg/linalg.py,sha256=o3Z3tshOr_bUalTPpD-oAy4ESZDIg-ZlqBGCjqfcLto,92311 +numpy/linalg/setup.py,sha256=fxvs0sWTe4atefglbXBWPei5KSWhHsqSXXJ_3DphVYk,3186 +numpy/linalg/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +numpy/linalg/tests/__pycache__/__init__.cpython-39.pyc,, +numpy/linalg/tests/__pycache__/test_build.cpython-39.pyc,, +numpy/linalg/tests/__pycache__/test_deprecations.cpython-39.pyc,, +numpy/linalg/tests/__pycache__/test_linalg.cpython-39.pyc,, +numpy/linalg/tests/__pycache__/test_regression.cpython-39.pyc,, +numpy/linalg/tests/test_build.py,sha256=8cUlHATPUuy3Y2zYWuWhYQnNjdAAegcPRsUUC_tgujE,1671 +numpy/linalg/tests/test_deprecations.py,sha256=GaeE3JnQlJLoAfbY93LmgCFUlV5M8IFmQ7EhF4WbqwU,660 +numpy/linalg/tests/test_linalg.py,sha256=lczSdwO0vQWSfIUxQyScg8wRbYtC2yfKUJ973G3CBM8,76437 +numpy/linalg/tests/test_regression.py,sha256=T0iQkRUhOoxIHHro5kyxU7GFRhN3pZov6UaJGXxtvu0,5745 +numpy/ma/__init__.py,sha256=9i-au2uOZ_K9q2t9Ezc9nEAS74Y4TXQZMoP9601UitU,1458 +numpy/ma/__init__.pyi,sha256=yEFwLhZ5m-kJ6gBqlqCMZ_3vDlxV3QW5iOYzPD2ohck,3484 +numpy/ma/__pycache__/__init__.cpython-39.pyc,, +numpy/ma/__pycache__/bench.cpython-39.pyc,, +numpy/ma/__pycache__/core.cpython-39.pyc,, +numpy/ma/__pycache__/extras.cpython-39.pyc,, +numpy/ma/__pycache__/mrecords.cpython-39.pyc,, +numpy/ma/__pycache__/setup.cpython-39.pyc,, +numpy/ma/__pycache__/testutils.cpython-39.pyc,, +numpy/ma/__pycache__/timer_comparison.cpython-39.pyc,, +numpy/ma/bench.py,sha256=wOg52Iu6JHqHWzKS2N0LpdPPUJciEZAePgmZd_mMgpM,5014 +numpy/ma/core.py,sha256=BsqLJF6ljQXHA6wDm7xUgJ-ajgCR1CnPOPLHjqs9wkY,272664 +numpy/ma/extras.py,sha256=NSaXcpGtjv5PoXQ2j3kbKiE6018TDY0pGQ88WZol2oo,60269 +numpy/ma/mrecords.py,sha256=B3HcVpKf0kRu4DG3YreZ6NY5zrBD9kTMBkU7tRJCKKY,27449 +numpy/ma/setup.py,sha256=DCi5FtZTlkhR3ByJH5Sp5B962bfcWpaOjA-y7ueyoog,430 +numpy/ma/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +numpy/ma/tests/__pycache__/__init__.cpython-39.pyc,, +numpy/ma/tests/__pycache__/test_core.cpython-39.pyc,, +numpy/ma/tests/__pycache__/test_deprecations.cpython-39.pyc,, +numpy/ma/tests/__pycache__/test_extras.cpython-39.pyc,, +numpy/ma/tests/__pycache__/test_mrecords.cpython-39.pyc,, +numpy/ma/tests/__pycache__/test_old_ma.cpython-39.pyc,, +numpy/ma/tests/__pycache__/test_regression.cpython-39.pyc,, +numpy/ma/tests/__pycache__/test_subclassing.cpython-39.pyc,, +numpy/ma/tests/test_core.py,sha256=aQX5giSjLTRwHzyUbTUdoDpXeJzP3ZAajDVEB8CIeXM,206935 +numpy/ma/tests/test_deprecations.py,sha256=Dv-fqcxKJ_tfxyk-DyK2rA5onOl-7YC06Pu9nkvECt0,2326 +numpy/ma/tests/test_extras.py,sha256=_uTlvEtwEcLyYw3dS657rlP3nUz2p697aspFW9kze48,68630 +numpy/ma/tests/test_mrecords.py,sha256=KeUfhLLwjwhX-Wh1UvViiFdOO3JFj44BQDtiC4ZZUrE,20363 +numpy/ma/tests/test_old_ma.py,sha256=v99zHnxhbwdxqnzmUCZFy5hbzAPkZG6UcA3ijmnuvlE,33123 +numpy/ma/tests/test_regression.py,sha256=Hi-p5QdcivsxUDSpTl3MGtAnmJCJPhhIj3c5nYI9rw8,3170 +numpy/ma/tests/test_subclassing.py,sha256=_7LEDWP0uruXofBfuKotk_xPz7JSPd8FZ-WfF27IrOs,13181 +numpy/ma/testutils.py,sha256=94gtPCIs6pBrtt1w51rG-aH3Z_XCdYzete8uu1oeQdc,10565 +numpy/ma/timer_comparison.py,sha256=xhRDTkkqvVLvB5HeFKIQqGuicRerabKKX3VmBUGc4Zs,16101 +numpy/matlib.py,sha256=l-292Lvk_yUCK5Y_U9u1Xa8grW8Ss0uh23o8kj-Hhd8,10741 +numpy/matrixlib/__init__.py,sha256=OYwN1yrpX0doHcXpzdRm2moAUO8BCmgufnmd6DS43pI,228 +numpy/matrixlib/__init__.pyi,sha256=gkHjB8o5QIAq39IumANapcGnYj2FCihAUrqvIADp0t0,103 +numpy/matrixlib/__pycache__/__init__.cpython-39.pyc,, +numpy/matrixlib/__pycache__/defmatrix.cpython-39.pyc,, +numpy/matrixlib/__pycache__/setup.cpython-39.pyc,, +numpy/matrixlib/defmatrix.py,sha256=zDXeDEu5DcW3R5ijl_MjGzp9bXM36uhWm3s0hbMTzJc,31780 +numpy/matrixlib/setup.py,sha256=DEY5vWe-ReFP31junY0nZ7HwDpRIVuHLUtiTXL_Kr3A,438 +numpy/matrixlib/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +numpy/matrixlib/tests/__pycache__/__init__.cpython-39.pyc,, +numpy/matrixlib/tests/__pycache__/test_defmatrix.cpython-39.pyc,, +numpy/matrixlib/tests/__pycache__/test_interaction.cpython-39.pyc,, +numpy/matrixlib/tests/__pycache__/test_masked_matrix.cpython-39.pyc,, +numpy/matrixlib/tests/__pycache__/test_matrix_linalg.cpython-39.pyc,, +numpy/matrixlib/tests/__pycache__/test_multiarray.cpython-39.pyc,, +numpy/matrixlib/tests/__pycache__/test_numeric.cpython-39.pyc,, +numpy/matrixlib/tests/__pycache__/test_regression.cpython-39.pyc,, +numpy/matrixlib/tests/test_defmatrix.py,sha256=nbY_HkwzoJbhYhACiEN-cZmR644sVJvMKWUcsANPayQ,15435 +numpy/matrixlib/tests/test_interaction.py,sha256=C1YtIubO6Qh8RR-XONzo8Mle4bu4SvwsvBnB0x0Gy4g,12229 +numpy/matrixlib/tests/test_masked_matrix.py,sha256=aKC-imVpBSyjnokr0Ntn-e47P1MXhKzOSnGz1ji9J_c,9156 +numpy/matrixlib/tests/test_matrix_linalg.py,sha256=9S9Zrk8PMLfEEo9wBx5LyrV_TbXhI6r-Hc5t594lQFY,2152 +numpy/matrixlib/tests/test_multiarray.py,sha256=E5jvWX9ypWYNHH7iqAW3xz3tMrEV-oNgjN3_oPzZzws,570 +numpy/matrixlib/tests/test_numeric.py,sha256=l-LFBKPoP3_O1iea23MmaACBLx_tSSdPcUBBRTiTbzk,458 +numpy/matrixlib/tests/test_regression.py,sha256=FgYV3hwkpO0qyshDzG7n1JfQ-kKwnSZnA68jJHS7TeM,958 +numpy/polynomial/__init__.py,sha256=SG2szESWgc9tqBY4dO_2EcidOI4EWX25cM1E-7cqCS4,6603 +numpy/polynomial/__init__.pyi,sha256=40ANjRQzcm84vUs3wqe0BJ7e2XuWFpcvVB7o9ZPf96E,352 +numpy/polynomial/__pycache__/__init__.cpython-39.pyc,, +numpy/polynomial/__pycache__/_polybase.cpython-39.pyc,, +numpy/polynomial/__pycache__/chebyshev.cpython-39.pyc,, +numpy/polynomial/__pycache__/hermite.cpython-39.pyc,, +numpy/polynomial/__pycache__/hermite_e.cpython-39.pyc,, +numpy/polynomial/__pycache__/laguerre.cpython-39.pyc,, +numpy/polynomial/__pycache__/legendre.cpython-39.pyc,, +numpy/polynomial/__pycache__/polynomial.cpython-39.pyc,, +numpy/polynomial/__pycache__/polyutils.cpython-39.pyc,, +numpy/polynomial/__pycache__/setup.cpython-39.pyc,, +numpy/polynomial/_polybase.py,sha256=0wJm5LbxcKNDEGa0xlho2LGkdOavwCBebsDaWmr8Vjw,37563 +numpy/polynomial/chebyshev.py,sha256=ylrydE6-AZb_jA-l8O3verfgVb6Ixgab32kXczyS5Bo,64492 +numpy/polynomial/hermite.py,sha256=72K9DSzx_Vcc5vKWIeW_zqV882_MQGcbGzBK_BhdBao,53820 +numpy/polynomial/hermite_e.py,sha256=LKEsRUkJvWizLngby0-qX_rnIgHHX5xZBYelDTkCsrM,53936 +numpy/polynomial/laguerre.py,sha256=wDRL-qxMLaIogQvT_ANjOaRDfJqE3cdbAfx-K9F6DT4,52096 +numpy/polynomial/legendre.py,sha256=nGumaDhnaAyargOW-G9g_AaJvnDR5oRmNlDePhVo1v0,52880 +numpy/polynomial/polynomial.py,sha256=ZWG5Z_11BwDFPLll6ksYbYiIfx4HYSCHjxKKBjpYWko,50100 +numpy/polynomial/polyutils.py,sha256=psxFjmYv1nrpFewtEPNIQfCE-umH6PumsQ1_CB0Vu9k,23932 +numpy/polynomial/setup.py,sha256=3MP1VT1AVy8_MdlhErP-lS0Rq5fActYCkxYeHJU88Vg,383 +numpy/polynomial/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +numpy/polynomial/tests/__pycache__/__init__.cpython-39.pyc,, +numpy/polynomial/tests/__pycache__/test_chebyshev.cpython-39.pyc,, +numpy/polynomial/tests/__pycache__/test_classes.cpython-39.pyc,, +numpy/polynomial/tests/__pycache__/test_hermite.cpython-39.pyc,, +numpy/polynomial/tests/__pycache__/test_hermite_e.cpython-39.pyc,, +numpy/polynomial/tests/__pycache__/test_laguerre.cpython-39.pyc,, +numpy/polynomial/tests/__pycache__/test_legendre.cpython-39.pyc,, +numpy/polynomial/tests/__pycache__/test_polynomial.cpython-39.pyc,, +numpy/polynomial/tests/__pycache__/test_polyutils.cpython-39.pyc,, +numpy/polynomial/tests/__pycache__/test_printing.cpython-39.pyc,, +numpy/polynomial/tests/test_chebyshev.py,sha256=PI2XwvGGqQKEB1RxbsYRgeTG0cunB_8Otd9SBJozq-8,21141 +numpy/polynomial/tests/test_classes.py,sha256=J6abNzhFKwaagzv_x53xN0whCfr5nMwqZ---Jrd9oxY,18931 +numpy/polynomial/tests/test_hermite.py,sha256=zGYN24ia2xx4IH16D6sfAxIipnZrGrIe7D8QMJZPw4Y,19132 +numpy/polynomial/tests/test_hermite_e.py,sha256=5ZBtGi2gkeldYVSh8xlQOLUDW6fcT4YdZiTrB6AaGJU,19467 +numpy/polynomial/tests/test_laguerre.py,sha256=hBgo8w_3iEQosX2CqjTkUstTiuTPLZmfQNQtyKudZLo,18048 +numpy/polynomial/tests/test_legendre.py,sha256=mJcXkot3E2uhcIZY-Bvb3EfWbOo601NG_gq0OwObuNk,18831 +numpy/polynomial/tests/test_polynomial.py,sha256=BHR8Cy7nhcxdsgrhEwyPRdswgQhDRZmnaoT9gb5O1VU,20628 +numpy/polynomial/tests/test_polyutils.py,sha256=F9Tghiw2LM1wqEHFHxCuFAR9rueLe-i-dakoEvsLgJE,3105 +numpy/polynomial/tests/test_printing.py,sha256=o0D4bNFYlFo0YpPYMB6RZwH5zEFpE6qjdeZ-j-D0YsI,16176 +numpy/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +numpy/random/__init__.pxd,sha256=g3EaMi3yfmnqT-KEWj0cp6SWIxVN9ChFjEYXGOfOifE,445 +numpy/random/__init__.py,sha256=rYnpCdx2jY6FC1tn4ev_5SekdgjT_xgl5X0dinpzLj4,7673 +numpy/random/__init__.pyi,sha256=uszjens-em1PfQ4dxIl0Tm7taoKi2dxI7C6_g40cWNI,990 +numpy/random/__pycache__/__init__.cpython-39.pyc,, +numpy/random/__pycache__/_pickle.cpython-39.pyc,, +numpy/random/__pycache__/setup.cpython-39.pyc,, +numpy/random/_bounded_integers.cp39-win_amd64.pyd,sha256=D0rJbIdMqTf48ztchRyTnAQFHzhVZJAMofz6hdtyXu8,239616 +numpy/random/_bounded_integers.pxd,sha256=ugYlh8FvGggHCjEaqgO4S_MeRcZg3mw40sDYEqx07QQ,1698 +numpy/random/_common.cp39-win_amd64.pyd,sha256=OuUirfZRHBHNsULel9XLlPJImMfghBrGPepLH_aAd38,181760 +numpy/random/_common.pxd,sha256=N2NZYlMYNh7FzFbJ6Mr2DH3MkrG67HUwqOu-XX_ouAA,4855 +numpy/random/_examples/cffi/__pycache__/extending.cpython-39.pyc,, +numpy/random/_examples/cffi/__pycache__/parse.cpython-39.pyc,, +numpy/random/_examples/cffi/extending.py,sha256=BgydYEYBb6hDghMF-KQFVc8ssUU1F5Dg-3GyeilT3Vg,920 +numpy/random/_examples/cffi/parse.py,sha256=Jb5SRj8As2P07PtoeuiZHZctaY0oAb065PXbG4-T8fI,1884 +numpy/random/_examples/cython/__pycache__/setup.cpython-39.pyc,, +numpy/random/_examples/cython/extending.pyx,sha256=_pKBslBsb8rGeFZkuQeAIhBdeIjDcX3roGqV_Jev7NE,2371 +numpy/random/_examples/cython/extending_distributions.pyx,sha256=1zrMvPbKi0RinyZ93Syyy4OXGEOzAAKHSzTmDtN09ZY,3987 +numpy/random/_examples/cython/setup.py,sha256=dvXjPDXSiWZwgq_Myapi2VggTzV0AGdSrEhrMmJmT0s,1366 +numpy/random/_examples/numba/__pycache__/extending.cpython-39.pyc,, +numpy/random/_examples/numba/__pycache__/extending_distributions.cpython-39.pyc,, +numpy/random/_examples/numba/extending.py,sha256=vnqUqQRvlAI-3VYDzIxSQDlb-smBAyj8fA1-M2IrOQw,2041 +numpy/random/_examples/numba/extending_distributions.py,sha256=tU62JEW13VyNuBPhSpDWqd9W9ammHJCLv61apg90lMc,2101 +numpy/random/_generator.cp39-win_amd64.pyd,sha256=F3vybRv_5nerQhwLZtNIwRxv_hHmZnNbVnjfLS5x780,666112 +numpy/random/_mt19937.cp39-win_amd64.pyd,sha256=BiOgJS8L4ddN6zjKnEqZjyAT7qDH2Z9XmaIOZ6zHvuM,79360 +numpy/random/_pcg64.cp39-win_amd64.pyd,sha256=o_e0I5EbWm2m_bAfMMOQrDx34vpec68NtpnV7xgmhzY,65536 +numpy/random/_philox.cp39-win_amd64.pyd,sha256=bfcTzYEwuufFnyZaHTgx-hRkYca_0_ypuwuT-mUjE-U,72704 +numpy/random/_pickle.py,sha256=X1IKY4xyLBsWLG1vubCWyRRn-QsV-jm5McUH-Zc-uiU,2329 +numpy/random/_sfc64.cp39-win_amd64.pyd,sha256=jyYrU6GKTHqVQq_NyfR4r9gX23V0Ny2abJ3cd0XNF-I,53248 +numpy/random/bit_generator.cp39-win_amd64.pyd,sha256=yVpvvudF6RcHSki-0RH2akhLMrajTo8Ljpzg7kx7S70,152576 +numpy/random/bit_generator.pxd,sha256=LJpeB-EKeVV8_JO69sS33XJLZQ3DAhrUCNzs_ei7AoI,1042 +numpy/random/c_distributions.pxd,sha256=N8O_29MDGDOyMqmSKoaoooo4OJRRerBwsBXLw7_4j54,6147 +numpy/random/lib/npyrandom.lib,sha256=QBBwG0Tp74cje_CPV4D2TeVGP_gc477KUp4wU6OHDqA,110126 +numpy/random/mtrand.cp39-win_amd64.pyd,sha256=EAlCx-JnJJ4YBSeB00n1QFAk_EsqWQKsYiRZjdNVl6Q,564224 +numpy/random/setup.py,sha256=5JHmw9X-POJdt07i8sFUMpZLB2p0vh4dRU05xtEdtS0,6258 +numpy/random/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +numpy/random/tests/__pycache__/__init__.cpython-39.pyc,, +numpy/random/tests/__pycache__/test_direct.cpython-39.pyc,, +numpy/random/tests/__pycache__/test_extending.cpython-39.pyc,, +numpy/random/tests/__pycache__/test_generator_mt19937.cpython-39.pyc,, +numpy/random/tests/__pycache__/test_generator_mt19937_regressions.cpython-39.pyc,, +numpy/random/tests/__pycache__/test_random.cpython-39.pyc,, +numpy/random/tests/__pycache__/test_randomstate.cpython-39.pyc,, +numpy/random/tests/__pycache__/test_randomstate_regression.cpython-39.pyc,, +numpy/random/tests/__pycache__/test_regression.cpython-39.pyc,, +numpy/random/tests/__pycache__/test_seed_sequence.cpython-39.pyc,, +numpy/random/tests/__pycache__/test_smoke.cpython-39.pyc,, +numpy/random/tests/data/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +numpy/random/tests/data/__pycache__/__init__.cpython-39.pyc,, +numpy/random/tests/data/mt19937-testset-1.csv,sha256=bA5uuOXgLpkAwJjfV8oUePg3-eyaH4-gKe8AMcl2Xn0,16845 +numpy/random/tests/data/mt19937-testset-2.csv,sha256=SnOL1nyRbblYlC254PBUSc37NguV5xN-0W_B32IxDGE,16826 +numpy/random/tests/data/pcg64-testset-1.csv,sha256=wHoS7fIR3hMEdta7MtJ8EpIWX-Bw1yfSaVxiC15vxVs,24840 +numpy/random/tests/data/pcg64-testset-2.csv,sha256=6vlnVuW_4i6LEsVn6b40HjcBWWjoX5lboSCBDpDrzFs,24846 +numpy/random/tests/data/philox-testset-1.csv,sha256=QvpTynWHQjqTz3P2MPvtMLdg2VnM6TGTpXgp-_LeJ5g,24853 +numpy/random/tests/data/philox-testset-2.csv,sha256=-BNO1OCYtDIjnN5Q-AsQezBCGmVJUIs3qAMyj8SNtsA,24839 +numpy/random/tests/data/sfc64-testset-1.csv,sha256=sgkemW0lbKJ2wh1sBj6CfmXwFYTqfAk152P0r8emO38,24841 +numpy/random/tests/data/sfc64-testset-2.csv,sha256=mkp21SG8eCqsfNyQZdmiV41-xKcsV8eutT7rVnVEG50,24834 +numpy/random/tests/test_direct.py,sha256=7pjpeUADs8HTtEtbNbBTKi1EMsmO21lvYoMqHyoucdQ,14827 +numpy/random/tests/test_extending.py,sha256=FSv8xJt8fd1-clX6rOwrMhn66PfMn4JJRbJH46ptwVo,3598 +numpy/random/tests/test_generator_mt19937.py,sha256=NZp5ePTiw0N2R8j1wNTshrv8Gq3qdPxRFlmxYwzpEiM,108419 +numpy/random/tests/test_generator_mt19937_regressions.py,sha256=NErTZy-83MM4jMdguaE_5msKf1dhD2UyyXZsvTjtKS0,5803 +numpy/random/tests/test_random.py,sha256=wwyX-oMKUOp17kuObzZFrWYC_ImhVc79NPdqm1ufJlU,69907 +numpy/random/tests/test_randomstate.py,sha256=XLhtIFIhM3vWtXy6hQUTh-ek44kibgnbcdwm8jYne9U,82720 +numpy/random/tests/test_randomstate_regression.py,sha256=t-4vAs8vZbrmIHzMcSpzsgelRVu5gjYq8ZqDUY0PfHc,7758 +numpy/random/tests/test_regression.py,sha256=yRzgK9Nz0kc5gZgzoNKJExc8voyXIU0GworGVFQ2-QA,5602 +numpy/random/tests/test_seed_sequence.py,sha256=zWUvhWDxBmTN2WteSFQeJ29W0-2k3ZUze_3YtL4Kgms,3391 +numpy/random/tests/test_smoke.py,sha256=C9khpy2DZnpE5g0s5bSliun4GOTq-576faz0jmxpsWQ,28621 +numpy/rec.pyi,sha256=pEAReiHy1PylZO3YYKqJY-8nHM0Rq6Jgdcxyw1orbKs,181 +numpy/setup.py,sha256=fBEg6S2o6H9mmLBfVJOonPwEIN70qlxH5TQVdSb3yao,1012 +numpy/testing/__init__.py,sha256=s9TGtO8tH0kG8emfVLC1pBRUrgsb4ueWAwtIb6XQXLg,586 +numpy/testing/__init__.pyi,sha256=Ixqmb0Ve3ZxTLgJjN2l6Izh2uoJYiDjELFooTPCLXmU,956 +numpy/testing/__pycache__/__init__.cpython-39.pyc,, +numpy/testing/__pycache__/print_coercion_tables.cpython-39.pyc,, +numpy/testing/__pycache__/setup.cpython-39.pyc,, +numpy/testing/__pycache__/utils.cpython-39.pyc,, +numpy/testing/_private/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +numpy/testing/_private/__pycache__/__init__.cpython-39.pyc,, +numpy/testing/_private/__pycache__/decorators.cpython-39.pyc,, +numpy/testing/_private/__pycache__/noseclasses.cpython-39.pyc,, +numpy/testing/_private/__pycache__/nosetester.cpython-39.pyc,, +numpy/testing/_private/__pycache__/parameterized.cpython-39.pyc,, +numpy/testing/_private/__pycache__/utils.cpython-39.pyc,, +numpy/testing/_private/decorators.py,sha256=e_ylVQtyN_MjuOsd0AFaFmQ9wB7mtdHy8f0LBKj8u6s,9005 +numpy/testing/_private/noseclasses.py,sha256=OqMSWVZEg5GGgz8bsoDWKa3oxvXYoqPst6U423s8yBM,14880 +numpy/testing/_private/nosetester.py,sha256=35S7suLWVzYBZ-zOt3ugthNZcMBCP7AjA-Z-4jqmtus,19980 +numpy/testing/_private/parameterized.py,sha256=c5BMUIU86FLdsvouqOBT4t8BLk1q8F32KaXEcPgfi-c,16958 +numpy/testing/_private/utils.py,sha256=dH7BXvx3q55ktBlhM6f7pjc9H2phBr3SzfQP_D2xCdw,87843 +numpy/testing/print_coercion_tables.py,sha256=GnC-nt2Sw2D7TJOoIgK3b2Nj63r9VFqGzPStMfdOBgs,6367 +numpy/testing/setup.py,sha256=LRtPNvo1V4Eh_gCq0ScQXSxv3P428c4rAKOVj1JK3MI,685 +numpy/testing/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +numpy/testing/tests/__pycache__/__init__.cpython-39.pyc,, +numpy/testing/tests/__pycache__/test_decorators.cpython-39.pyc,, +numpy/testing/tests/__pycache__/test_doctesting.cpython-39.pyc,, +numpy/testing/tests/__pycache__/test_utils.cpython-39.pyc,, +numpy/testing/tests/test_decorators.py,sha256=zR2-CPT4vK_KE1st9LuaAAkP1PFthUkBCefjng088uI,6045 +numpy/testing/tests/test_doctesting.py,sha256=wUauOPx75yuJgIHNWlPCpF0EUIGKDI-nzlImCwGeYo0,1404 +numpy/testing/tests/test_utils.py,sha256=GwIHxAcqT570qsnTIo4lNZq8NJP5_scLS7-YmcreToU,57311 +numpy/testing/utils.py,sha256=LhIaw_3hG1jUW98rUrBhOxRi1SjOUgVIr5--kwp0XZc,1260 +numpy/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +numpy/tests/__pycache__/__init__.cpython-39.pyc,, +numpy/tests/__pycache__/test_ctypeslib.cpython-39.pyc,, +numpy/tests/__pycache__/test_matlib.cpython-39.pyc,, +numpy/tests/__pycache__/test_numpy_version.cpython-39.pyc,, +numpy/tests/__pycache__/test_public_api.cpython-39.pyc,, +numpy/tests/__pycache__/test_reloading.cpython-39.pyc,, +numpy/tests/__pycache__/test_scripts.cpython-39.pyc,, +numpy/tests/__pycache__/test_warnings.cpython-39.pyc,, +numpy/tests/test_ctypeslib.py,sha256=4hdwdxDArcTLHpinigBSLLGb_ppGtksPWRsvkRD0Z84,12535 +numpy/tests/test_matlib.py,sha256=TUaQmGoz9fvQQ8FrooTq-g9BFiViGWjoTIGQSUUF6-Y,1910 +numpy/tests/test_numpy_version.py,sha256=EzH8x1xpoowIlHlXQ-TEQaIJlmnx_rgrJtOCwdBXYyY,598 +numpy/tests/test_public_api.py,sha256=kmxV9zHfd3YZRuuaXXux-iGuQCsQGq5UIJPk8bBnnfQ,15456 +numpy/tests/test_reloading.py,sha256=WuaGiMPNSmoS2_cKKcsLFNI2iSIvxxR0O0f1Id7qW40,2007 +numpy/tests/test_scripts.py,sha256=KNmMlcO0sube9TLF3McxJZwzM87lLBzXZpjA6qJQkq0,1619 +numpy/tests/test_warnings.py,sha256=IMFVROBQqYZPibnHmwepGqEUQoBlDtdC8DlRulbMAd8,2354 +numpy/typing/__init__.py,sha256=SlrqSQGbOqvd6fkem4mHf7nyU1y75zd0AIwNNVJEzbc,7379 +numpy/typing/__pycache__/__init__.cpython-39.pyc,, +numpy/typing/__pycache__/_add_docstring.cpython-39.pyc,, +numpy/typing/__pycache__/_array_like.cpython-39.pyc,, +numpy/typing/__pycache__/_callable.cpython-39.pyc,, +numpy/typing/__pycache__/_dtype_like.cpython-39.pyc,, +numpy/typing/__pycache__/_scalars.cpython-39.pyc,, +numpy/typing/__pycache__/_shape.cpython-39.pyc,, +numpy/typing/__pycache__/setup.cpython-39.pyc,, +numpy/typing/_add_docstring.py,sha256=1qcfzFKkMl7vms4mztFapPC0Wwvjhe8ANxUOpYi_Fu4,2701 +numpy/typing/_array_like.py,sha256=na2mbjXRfOGOIHY5R7mxx7_Jr8__hpCKuIRdJGC7w1Q,1061 +numpy/typing/_callable.py,sha256=skqiR8PkO1NHBUCyrzqS26e07vMslOtqQg3jLeBfkhY,11835 +numpy/typing/_dtype_like.py,sha256=MUQRBlzWwksVcLhvTduFxLr0No5VjIYEgJ1wyumX61I,2557 +numpy/typing/_scalars.py,sha256=pq1Y9MH0THa2Y0WZ26HDb7NGNIB5p-khAy70B8M8zuI,694 +numpy/typing/_shape.py,sha256=XHT8qONsphjVLrJVhI7KoiUBVIwzWhKgESvs9E_pPcw,162 +numpy/typing/setup.py,sha256=NpNqwxDwSxWBInw-7TJHIqEf3scDAczZwmzGxI_Ftn0,385 +numpy/typing/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +numpy/typing/tests/__pycache__/__init__.cpython-39.pyc,, +numpy/typing/tests/__pycache__/test_isfile.cpython-39.pyc,, +numpy/typing/tests/__pycache__/test_typing.cpython-39.pyc,, +numpy/typing/tests/data/fail/__pycache__/arithmetic.cpython-39.pyc,, +numpy/typing/tests/data/fail/__pycache__/array_constructors.cpython-39.pyc,, +numpy/typing/tests/data/fail/__pycache__/array_like.cpython-39.pyc,, +numpy/typing/tests/data/fail/__pycache__/bitwise_ops.cpython-39.pyc,, +numpy/typing/tests/data/fail/__pycache__/constants.cpython-39.pyc,, +numpy/typing/tests/data/fail/__pycache__/dtype.cpython-39.pyc,, +numpy/typing/tests/data/fail/__pycache__/flatiter.cpython-39.pyc,, +numpy/typing/tests/data/fail/__pycache__/fromnumeric.cpython-39.pyc,, +numpy/typing/tests/data/fail/__pycache__/modules.cpython-39.pyc,, +numpy/typing/tests/data/fail/__pycache__/ndarray.cpython-39.pyc,, +numpy/typing/tests/data/fail/__pycache__/ndarray_misc.cpython-39.pyc,, +numpy/typing/tests/data/fail/__pycache__/numerictypes.cpython-39.pyc,, +numpy/typing/tests/data/fail/__pycache__/scalars.cpython-39.pyc,, +numpy/typing/tests/data/fail/__pycache__/ufunc_config.cpython-39.pyc,, +numpy/typing/tests/data/fail/__pycache__/ufuncs.cpython-39.pyc,, +numpy/typing/tests/data/fail/__pycache__/warnings_and_errors.cpython-39.pyc,, +numpy/typing/tests/data/fail/arithmetic.py,sha256=aVKC-80x7Jj3V7cn5vaM2O-Sewsj0lT9NBnH7wQvANA,399 +numpy/typing/tests/data/fail/array_constructors.py,sha256=QWbSPp90Bhczb0Lz9pfnilQh7MeCgwzdXhQIUXUBQU0,1021 +numpy/typing/tests/data/fail/array_like.py,sha256=kpQ9GYpCyNQnpCVNJfjzcjuyRaWcRSk5I3vwobto5Ik,486 +numpy/typing/tests/data/fail/bitwise_ops.py,sha256=6cpzCLl1EH81UiJwo5Qs-HkvUByG9V5MNLpk8nVrLLo,534 +numpy/typing/tests/data/fail/constants.py,sha256=rm5lDmBIS2M3CYKKvrZuzW_jKwGknLgc2Ih8bpDrOPc,274 +numpy/typing/tests/data/fail/dtype.py,sha256=mijyTgWwSqw6pgvd_cJ8XUYfjbsVa0-RfBhZkfynD2I,344 +numpy/typing/tests/data/fail/flatiter.py,sha256=YpW-SsU6ti1Pt2Adj-BgE0wQ9PAMYBylSN7y61Ujtfw,867 +numpy/typing/tests/data/fail/fromnumeric.py,sha256=weUR_bwWaqesICBarUC0-K7beFnUZ-nt00mld6zbogE,7908 +numpy/typing/tests/data/fail/modules.py,sha256=E2atmSaRx4Q8XOog-5WsqlFLpAr2FaO90WPegzg5Yd4,553 +numpy/typing/tests/data/fail/ndarray.py,sha256=2I4smD6MlUD23Xx8Rt1gCtjj_m-tI5JEma-Z0unrgas,416 +numpy/typing/tests/data/fail/ndarray_misc.py,sha256=_DySvTQjAbHH460tAURU_-EqOkfGFiR_10F20DMSd4w,587 +numpy/typing/tests/data/fail/numerictypes.py,sha256=S6Xn_z1KoI8tSVSZ0aM7alvDfyAxNxEQuhMjXVW1Uws,397 +numpy/typing/tests/data/fail/scalars.py,sha256=0SkWYaG2yGON82lcOzoU1EX2UrNrbtVvQA9MsxyV_V0,2558 +numpy/typing/tests/data/fail/ufunc_config.py,sha256=V5R7wY_P7KWn4IRxbLx42b1YF3wbIYzHEMr9BC41JHE,754 +numpy/typing/tests/data/fail/ufuncs.py,sha256=nJ0vP3zPzaC7-U8veFZlSXEjRFlhJTPaFgRJBGM39sc,235 +numpy/typing/tests/data/fail/warnings_and_errors.py,sha256=UhM-s2DqkkD-Nd2O7_y_34_ygn4w4nEip6AXsQ1kQ4k,287 +numpy/typing/tests/data/mypy.ini,sha256=eiFW-OwC4m5btqviLfeISc-OZHWfnzQWOo9gdDi4Ic8,108 +numpy/typing/tests/data/pass/__pycache__/arithmetic.cpython-39.pyc,, +numpy/typing/tests/data/pass/__pycache__/array_constructors.cpython-39.pyc,, +numpy/typing/tests/data/pass/__pycache__/array_like.cpython-39.pyc,, +numpy/typing/tests/data/pass/__pycache__/bitwise_ops.cpython-39.pyc,, +numpy/typing/tests/data/pass/__pycache__/dtype.cpython-39.pyc,, +numpy/typing/tests/data/pass/__pycache__/flatiter.cpython-39.pyc,, +numpy/typing/tests/data/pass/__pycache__/fromnumeric.cpython-39.pyc,, +numpy/typing/tests/data/pass/__pycache__/literal.cpython-39.pyc,, +numpy/typing/tests/data/pass/__pycache__/mod.cpython-39.pyc,, +numpy/typing/tests/data/pass/__pycache__/modules.cpython-39.pyc,, +numpy/typing/tests/data/pass/__pycache__/ndarray_conversion.cpython-39.pyc,, +numpy/typing/tests/data/pass/__pycache__/ndarray_misc.cpython-39.pyc,, +numpy/typing/tests/data/pass/__pycache__/ndarray_shape_manipulation.cpython-39.pyc,, +numpy/typing/tests/data/pass/__pycache__/numeric.cpython-39.pyc,, +numpy/typing/tests/data/pass/__pycache__/numerictypes.cpython-39.pyc,, +numpy/typing/tests/data/pass/__pycache__/scalars.cpython-39.pyc,, +numpy/typing/tests/data/pass/__pycache__/simple.cpython-39.pyc,, +numpy/typing/tests/data/pass/__pycache__/simple_py3.cpython-39.pyc,, +numpy/typing/tests/data/pass/__pycache__/ufunc_config.cpython-39.pyc,, +numpy/typing/tests/data/pass/__pycache__/ufuncs.cpython-39.pyc,, +numpy/typing/tests/data/pass/__pycache__/warnings_and_errors.cpython-39.pyc,, +numpy/typing/tests/data/pass/arithmetic.py,sha256=yffdMBRbA2DSbEl9zh2ebMi_9G-3ToVKW9CDT5auezA,2495 +numpy/typing/tests/data/pass/array_constructors.py,sha256=4PUMvHtZQ0f1-qgba_-CmJNaCQ9KaHTeDjWgAtug7ww,2490 +numpy/typing/tests/data/pass/array_like.py,sha256=PvPiNZmIbiwTNa5pleaF_azkp8Wkt-FnWMxhb90tnZc,976 +numpy/typing/tests/data/pass/bitwise_ops.py,sha256=zYz-ZNXpxjXDdo4fYWv_RQZq5af581dnaZrlu0-sSC8,1101 +numpy/typing/tests/data/pass/dtype.py,sha256=sFp19iFTqL2BvDVYjfMahdfxSXtaW9LG5W2AKE-g7i8,1000 +numpy/typing/tests/data/pass/flatiter.py,sha256=IeJY7T1G2yE5sYFwEylBQxqzr8bBGnzWm1Uxx-aRooY,140 +numpy/typing/tests/data/pass/fromnumeric.py,sha256=eM6RUBjVInsShXlblqq07-I0QwoST8n6g8WWuPSgYtA,4002 +numpy/typing/tests/data/pass/literal.py,sha256=wtFjvftYilKJcuehgIWJTL0yXOO72gJKZBfrw_yjNMY,1344 +numpy/typing/tests/data/pass/mod.py,sha256=Intb9Ni_LlHhEka8kk81-601JCOl85jz_4_BQDA6iYI,1727 +numpy/typing/tests/data/pass/modules.py,sha256=UZnvViLGUfRQVCR8-OJ7MWphQBlArWPBcoUgaz-86IM,618 +numpy/typing/tests/data/pass/ndarray_conversion.py,sha256=-1iJDSvdD86k3yJCrWf1nouQrRHStf4cheiZ5OHFE78,1720 +numpy/typing/tests/data/pass/ndarray_misc.py,sha256=fvfAffZ5ebefXKZzTm2SMmi0xrhjlBVTd6dieI_fjsQ,2414 +numpy/typing/tests/data/pass/ndarray_shape_manipulation.py,sha256=yaBK3hW5fe2VpvARkn_NMeF-JX-OajI8JiRWOA_Uk7Y,687 +numpy/typing/tests/data/pass/numeric.py,sha256=VCJ993mY9u8v4eNhJOJuOtc9Ics8AsAlAQtrsaTXth8,1567 +numpy/typing/tests/data/pass/numerictypes.py,sha256=cyObIdejhEzrwA_awjstkvO-_b79iBJZ20nf9XlCMY8,749 +numpy/typing/tests/data/pass/scalars.py,sha256=i56q74NseMyjboftJfWw_BkRp-lDzQuM2cpYMQR9oqY,2662 +numpy/typing/tests/data/pass/simple.py,sha256=ChlX7VN0SPpa877JwPRb-JpBUgpwhDHJuQLbRBY75FM,2855 +numpy/typing/tests/data/pass/simple_py3.py,sha256=OBpoDmf5u4bRblugokiOZzufESsEmoU03MqipERrjLg,102 +numpy/typing/tests/data/pass/ufunc_config.py,sha256=l1JiZe3VXYLzgvbuk42Mk6fd_nvLsc9aJ233W0_MLm0,1170 +numpy/typing/tests/data/pass/ufuncs.py,sha256=NUCjNCXprCD0iQHbmCyft_vLGrCb5dwyf-86dNZF4S8,460 +numpy/typing/tests/data/pass/warnings_and_errors.py,sha256=CtuAoGmmjsiWw34jjPsFUMZDrmMsVssQ6KHBWsDk7Jw,179 +numpy/typing/tests/data/reveal/__pycache__/arithmetic.cpython-39.pyc,, +numpy/typing/tests/data/reveal/__pycache__/array_constructors.cpython-39.pyc,, +numpy/typing/tests/data/reveal/__pycache__/bitwise_ops.cpython-39.pyc,, +numpy/typing/tests/data/reveal/__pycache__/constants.cpython-39.pyc,, +numpy/typing/tests/data/reveal/__pycache__/dtype.cpython-39.pyc,, +numpy/typing/tests/data/reveal/__pycache__/flatiter.cpython-39.pyc,, +numpy/typing/tests/data/reveal/__pycache__/fromnumeric.cpython-39.pyc,, +numpy/typing/tests/data/reveal/__pycache__/mod.cpython-39.pyc,, +numpy/typing/tests/data/reveal/__pycache__/modules.cpython-39.pyc,, +numpy/typing/tests/data/reveal/__pycache__/nbit_base_example.cpython-39.pyc,, +numpy/typing/tests/data/reveal/__pycache__/ndarray_conversion.cpython-39.pyc,, +numpy/typing/tests/data/reveal/__pycache__/ndarray_misc.cpython-39.pyc,, +numpy/typing/tests/data/reveal/__pycache__/ndarray_shape_manipulation.cpython-39.pyc,, +numpy/typing/tests/data/reveal/__pycache__/numeric.cpython-39.pyc,, +numpy/typing/tests/data/reveal/__pycache__/numerictypes.cpython-39.pyc,, +numpy/typing/tests/data/reveal/__pycache__/scalars.cpython-39.pyc,, +numpy/typing/tests/data/reveal/__pycache__/ufunc_config.cpython-39.pyc,, +numpy/typing/tests/data/reveal/__pycache__/warnings_and_errors.cpython-39.pyc,, +numpy/typing/tests/data/reveal/arithmetic.py,sha256=HZaJeMJXIYvFR9fac7k76jpAbDHmx6aiPiFasmQnrXk,16426 +numpy/typing/tests/data/reveal/array_constructors.py,sha256=6py1-UOF4LMel4ps3AdQGppTWNM_EfGcP99x25OOVuc,3936 +numpy/typing/tests/data/reveal/bitwise_ops.py,sha256=GJ4oIEaoqniGRnMJTo1XgJ1pJpKgNPnB_OqS4GFWg3M,5786 +numpy/typing/tests/data/reveal/constants.py,sha256=KA1cM3BLqwq4cjoFt2-oOkOEyEj05kv1Zm_usnN7POI,1794 +numpy/typing/tests/data/reveal/dtype.py,sha256=zEZAjKXcWyYeoFB8GYZI3N55N7XopAO9XzDduM9dxoo,2311 +numpy/typing/tests/data/reveal/flatiter.py,sha256=6XVwZ8MESoV3IGF0C8mUZg87ZPmsuGtm5yS7FCWphEE,485 +numpy/typing/tests/data/reveal/fromnumeric.py,sha256=_PEc6fW9IlzCASf-fjen65e3Nq_j5pGr3eIajHCqq0s,12859 +numpy/typing/tests/data/reveal/mod.py,sha256=wlCsZkKMoiA3Oh1M2Azr5hC3aY77cyRLtLahaiDZ3-o,9037 +numpy/typing/tests/data/reveal/modules.py,sha256=faHLlqquClwykUILg8OTJ01km6MYEoICsVgIWyqrCtY,1943 +numpy/typing/tests/data/reveal/nbit_base_example.py,sha256=lV-J8KPlamCkRIkTm8Lzgywq7zOz1elplWw2516lmIo,544 +numpy/typing/tests/data/reveal/ndarray_conversion.py,sha256=mTbv2cNYU05dH7wxuPWFlhhMi4N0adi5ocF6MUyNCtc,1630 +numpy/typing/tests/data/reveal/ndarray_misc.py,sha256=Lb_5aX89zEuWrgYkr0_9k9c3S16DK_oeNUCGlQLqWIE,6148 +numpy/typing/tests/data/reveal/ndarray_shape_manipulation.py,sha256=hRbNwpFuiWKPZ5YcOlFeER72qLOJzHle_IZQ0wj-Rfk,1041 +numpy/typing/tests/data/reveal/numeric.py,sha256=2bACWCxtfKFGgfrhy2UHlauX3Pq2zU2F-USR7Fx79F4,3066 +numpy/typing/tests/data/reveal/numerictypes.py,sha256=NXDYYJTvLP-aCNbSNQe7yuFWSmp_sbdCKVkYsQPd0Hg,666 +numpy/typing/tests/data/reveal/scalars.py,sha256=TG-L69AUViCSeSFSGkCV5FMnNc_8IugMXO4417AlCks,1156 +numpy/typing/tests/data/reveal/ufunc_config.py,sha256=dcIwOjSa4B2DWffbRTCFsgRUxQJWkfeKlTAgIlcLDeQ,1416 +numpy/typing/tests/data/reveal/warnings_and_errors.py,sha256=vgKMl6HOqJqp0kijIx9bOVY1p_0yNxZqnNJQHl4Bw3U,438 +numpy/typing/tests/test_isfile.py,sha256=_QxXdUtcEpjFYbJSL9JlEP73ghbS9QjvUgtCw04GDb0,914 +numpy/typing/tests/test_typing.py,sha256=St99JVX9g1U7yyWe--IFnhJJuu_uCNwgpzh7PLEnJy0,5452 +numpy/version.py,sha256=yw8bH1GdAHP27riBK_7o9dMpk62HrClGJtC1UDkn6sk,332 diff --git a/venv/Lib/site-packages/numpy-1.20.2.dist-info/REQUESTED b/venv/Lib/site-packages/numpy-1.20.2.dist-info/REQUESTED new file mode 100644 index 0000000..e69de29 diff --git a/venv/Lib/site-packages/numpy-1.20.2.dist-info/WHEEL b/venv/Lib/site-packages/numpy-1.20.2.dist-info/WHEEL new file mode 100644 index 0000000..d1267fc --- /dev/null +++ b/venv/Lib/site-packages/numpy-1.20.2.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.36.2) +Root-Is-Purelib: false +Tag: cp39-cp39-win_amd64 + diff --git a/venv/Lib/site-packages/numpy-1.20.2.dist-info/entry_points.txt b/venv/Lib/site-packages/numpy-1.20.2.dist-info/entry_points.txt new file mode 100644 index 0000000..1010c24 --- /dev/null +++ b/venv/Lib/site-packages/numpy-1.20.2.dist-info/entry_points.txt @@ -0,0 +1,3 @@ +[console_scripts] +f2py = numpy.f2py.f2py2e:main + diff --git a/venv/Lib/site-packages/numpy-1.20.2.dist-info/top_level.txt b/venv/Lib/site-packages/numpy-1.20.2.dist-info/top_level.txt new file mode 100644 index 0000000..24ce15a --- /dev/null +++ b/venv/Lib/site-packages/numpy-1.20.2.dist-info/top_level.txt @@ -0,0 +1 @@ +numpy diff --git a/venv/Lib/site-packages/numpy/.libs/libopenblas.GK7GX5KEQ4F6UYO3P26ULGBQYHGQO7J4.gfortran-win_amd64.dll b/venv/Lib/site-packages/numpy/.libs/libopenblas.GK7GX5KEQ4F6UYO3P26ULGBQYHGQO7J4.gfortran-win_amd64.dll new file mode 100644 index 0000000000000000000000000000000000000000..5d370267651ada44dde0660788d17ffbb7910776 GIT binary patch literal 34413408 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

QjIA;!k@7h%O2 z_;rO3yTW_0RP+IK;8&OmrfXUm~oonR#;`ONx@vM zR-o$vF6{rYEmo?1gN9q;kK|u~DBoNDzzRL^jyGJ3nY@0q4&J8qhWZ0%Dk-_t9GS}h zFln2euw*L7DRL`^qo<{#<`eBvKaf-n!l$&SD-SLfs!Es)7PF0U{UWuPk#4YkiW5!I zy6XpZ(3wV2N2bau4xK}ZhfV!ywZfOINJo<8y^VVe0gKWC!KJk>6<{3ko58YekK0wF zzrYr^^fN6ujjNTij-a2VP1>3#mTLuGYo6B3WuoTH-~R?@-eJF&rjnIF z0SiRR*yU%Ts8S0=l8}>xtte!bZnYrSL7)e|W3kNGvfh}Z&rtWNB#|-5Fv{bGEazQH zsrGZRGr5BL5Ln_yv?eSu0T-qqWg+>2iykO{IOe83@&<20uSwArm$4`^0`-*aO!ol< zMdHH`(7(OXdl0W%^mzCJDogA2z!uR3yx~=ZCQWt%omG{$2FhzAZY;8El_&7tn81Jh zGzu=*UVGx7ryjpmWm%^zg+ZLclhmCDHHg=9Q z9aD2U7h}*K`5e^RcBR;Nmb?bB_T&wK1xmH6PYnY=rmuo4W$URHyoLn%ClWvY6aB{* zeoHCh71XplQcHnBAgyS7SgA=OB$s282#scvNG8xnZ;(L^6h}f0R31!fU?HjD*LVli za61OAJwnS_3z2~#pT@E%Le;u+Y9RJHqlP%jEo#`AtEhoYgdMwv!95g85vhSyNewwP zWlUy#xrSDla>de*h<_Z>@wMQeqiKi#>oE@P5oR@RIn8onEOs(9iWG-^f>Ply`cX{|V_|0i)I!hV33-n?rubED zP6TiM3at4`#9DSon%deD|Jk{O@dojD(D+#Wg{8Jq`2n1ZP3|&n()KDM7e318psP!dpqN z7B@i0Fjd63Jdtxf5oBHmMSvi*g(aAGt$6GW48`W@R+l!a-W@G&9af5~m^(V0?n_)Y zVu`i;FL&dWF8p2aY91O})|Wq>x-K$ZMgJ7F)$qkrZT;w&zAkz!#n|EE3z`vE7Yp%X z**N$v%S4F6&*j`7|J^y_=JE#Cd8y=y*RmjUA1zQ!wFz(0e+eNgQ?KVe7cy|gMOhYZ z7lLeHh>SCZD5E-5&c;JI>p@Y)e43~`H{GMf#uN9+W9U<+&^d-Z`iw^WLkzS%VOP_B zD-!Vd_;f{z3=EP@flp5gpZ-A3zk|urzO=SLqAf=k#6&5b9qd8v-3eBCm51ghZjACyNr+o zei@Q5Jk|TfgMCUNf76(ncveDwm!SL0j**AwQAN=G0xp1V2|Tb6frsnBygxJp4`AN- znZz_4(r-a%XYS*=XfWsezK9G3T8K}!Lq%XAensou9^VZL0UC9aUyXRf9l&3{$&c;h z4Q!^ZDotKXya8kFD%_Ch1N>zul1cStN98g@c`^0Zl3U|ZLTuLScMjQkex+wt)AOmE<8Oncg}u1&kX^Lr%(wq5i;+ig`By!CB8d zC?{(^ufqu=6R?ZJXH%l3>%jc+Dbj?gOjTyV33x5vZu@JlUvz574mCv5#AeqKfGC`poD)3m74n4 zOZiaelgdt0|T*`oTuz<&jJCFJ%waE zU%3HHdyG64(|=Clxwi~U3|bK~x(HWYkGTaWC^ewcrDIlK7!HAHw@S#P(K4XMHc3coNTy zlBZT5_#iP1uLz8dj2U0pUm0)c4{Jtc%wS@b%$NzHIVF=AzchR$dSKE}Jy5QTtauwk z5LxjoE|63yfuJP-GG;p}c9mz`;!KQD8(D+QG>JgCYmknnVnQ`x&)dklnpZ7Mgq<4= zXd~RDM`jo60c2L~26-cVH5>mt#dQDHy27yt-oaM9%TN{XE{JhI%7U7n^;+mk6w%I; z!;NZWo46J_m-XO@>w`WRe&Tq;W1AwLCM#ct>KyWA-jjS8f0N3WLEhUlsG7#0FZ|wM z&?cS9V0zW3k}s2uru~6N?7gT36(Kr{bCM1^axm-1co+kMucH!mPO@jD7Znar%O({Z z1miMyMZy-vC@SXOKVepwWSqM4fz@Mt5zl*)KSRb{fqSI0WS%69+Y>+Wt9z1ho3Nqu zGM*gw-2qtpqIblpu|QjKbAE5*EfkJ@+w$Yad*IC{PqS4`(PL;+3X_Nz+Y!0nLS%~# zk;KD1n%clh_$JUBdc^DTd4U7I0@nOFwJ6hc|FY{EiP z%OtgjD?Vj<{Eo-EI}*G3cEHml`8O)#&4FA%pjCUh&UD)&o6Eql_LFn)LgG~XNzKm{ zErxkzIZc@2rGR&oID1+g}dOQpOohg zdvd~K2gZMteF449D2RA+^ziD)*nx?aY5YYW33$xSoxnS-+yF=-?bABsjNYM}2?Bax zcBz)P4<1%;WDd!fKtuF@4lOlaPr*xv@e;46;`)8#x#{T}udyu7=^^%UoTAN9T!7ZK$T!iS z*m^jxj2gr|CRPecm`2d5f#d^geF6Va6*Sg%Sd#t=_6r^bVU9B*#>GB^7s-@DmXPwM zzf2_(B;xCU-M0J`eLrhATAZ!G)m( zkmj&Vk>;={N%oqn>fpU)rxv#07pf+cB@O)7cKLc&-QD5Eu)6-9_ZlW}#vru6ZTXb}9N= zd0?A4LmPel40TV8z9adWI;35R*S6v>OHD0CLXAsn2$ zOdm%4g5Dr5I50p|NUVh~!|-9y9_~e8(ubkaMM;4i9ijOGehptnF37W;FQXDqB_EQ% zq^48`jKNM9-2nO90zEdi-Kjn;%j#uEV~5eC*} ze4IkB!WNK-#%4_QRhBkUUzMGXd>P<~S>7u_jz+w}CkoFXw#f|Gd|a3^gM4fYIPj=V z;^eFt+F;s$%ypj(MozS?+}16mpUB^eK%KoKs7;-`SFKo!ii z#JO^!FLo+jJ~;|{xV2AOWrZ(75o;I2YYL!7ek_$E1K%ot3h|0RS@Pr8DfyAEj|C<9 zC9xfEtMRm-m5iS5AN#a^h~ZIc&?}ct4%J5BX$lB}JQaCEq^;1!9O964!BFfm>4Mld z=%NXY7^V$9(#o`{4eeKIk%~wOgzb!qkh}g`{j0vIFf3g}jRkQV8Ft26HBU zElOF4hbE;E`SHFd11A9$!8Ry{b%bJAK`lZTzKcbOB(s{wwratX(WV917^;C>C|w(I z=?2}vb)!Hk-rf9pPEs(qh7AQ4gb=TWekX+J z#D&XP#O^KY1ARwaCTGI)hJ^?Mo)XN;+&YEoP6PDwX#dNg@i2SL%-%BT5mA#CGim}Y z#+Ifsi)ml;MzTX$oG!&xcsG1;LJEjSo& zxx*iO!UsTc!Q4EQL(|s}EvKgrC(QTogYv?Mu~!Vbz7Qp=NRmj_f0!h~d?_JM?7$?2 zqt!`R^Xn@**xF_e7VmL-Jk%;4Hk25hQ`ifw%h}l1p z+$FRH2LMF=7}+irr`xTv2W*LRz(KPxFIkaiSvLEM1K^+!P67w1L%+?Kgv1bqQ0~P( zL4$UnLi5N+(2UyvL>kdh&U8vOElP@kYOHMnz;`;;d{l9kP)ukWY*>yJGj}9LaeXw_ zk6D1fqN>nP6kByJ!cDb1{4Y=V)5KeNS?Z_l+av!HqKPpU|4MvCA=9+*g92^x@FnEo zf6zrXOiewp1r9FW4+KaOOdG+5Bm7P5H2V`!-DlYki6%TX%br^4I5L@5iFPwTzO%|5c!P4Cv7a-r@ZANeD2{(fDFzACKcxBNt z?G52lHqHL5*e-AKs8=-_PpC3I`vr9i@Mj|4>P#(QwA{O1?{36P@j}QLC|9yH8r2Q` zSqq9HYuBNTLsDe@B>w;>O2E^Zn?Kq?3XUCEvV8~I~nJp z(UX-ntn~FuzE+}KQBx&Hhcb}>f#V4jPb>>XJ_#HMMKT`Ir8DUyRHtd)ixkPdB>=Ic znwRl)ZX@AZVv?PK*Wd*x6SAYW1+u$opG9^@H*-OO7sn(!RyhXQ9Y5=^6%E+Q4w-jt zdr57D7zJZJnfwK(Y)3_d+V;m6d^rdlx|X6m2mT_%9)o{;wMk=aQzQpFp!N{MuOhK% zk8<=N`wzCqA4v`ZY}0bo+vTU@Jy{J>J47zP>+y{s`1UVW8@?o}PwBp-dxS<(^aXbk z_3;k$W!qv(aomc&joo#XxO9lW$reAYM;S%&4vW4dQqgWcDH1d7Gj%+*P!dfjp`?9i zORR~xEIHyN;hY4*0U(vtMU2pB3tfSW!u_V*RfqRFx4U9^B3d;!ogilqsoZq`+W4m$ z4=nY%5;rL;?3E*fV1=#i!V25G-trxCH87FA5KT~<#!4ZnKx|*A3!-GvZb3R7^-qy} z48sdp=)|FOKPtyR|0-2Y*+Vp4uLBIqub_YRLA1`-v9iJofE!LWOg}kGDM#A=XkOu^ zvgdfidTmb_@&c`d<{7OpI#ak`nxO68wha0_at+Vw*aOqY+n%F+#{jIWs`X1(RjdaS z41Ecn-f3GuLHG;Nt^fppX>Yo{^iP3F;#0I}+KZfxF^)kfP88tYq@ZKibJt^HLPx|$ zXZ9SOIh-Tus;9X`V$2gc<$0I#bsB7pCz%py3#xZcTHGKhq{Z$3T$K1e#RUC57DX+@ z!!(0!;vo{1nD%@IDW{HbSBBby>y&A~TFf*DT2cbTkRCQO4Z3ErNmuhex0@%DX_zw5 zE&>&s;vVN;0hgWFXIG+y_?)A*nx=oxu9^O{;+@*a+kHT^6 zGZ>=oT&~eS+hqrUVVWh;0P>k+ufIVxC6SlJhQm6xSP=87r0$6nssgZudblCPWi4oZ zk&g(@aUne7I`FS=cAJ&0nA&4Q?OLha zvRW!1^&k#P)=Rs?=><#zE0lbn3kkvfMOn5j{#>?&6yZqpAQ9?={n+Ef1h;pP3#Afm z`m7QEv=6Q(igM7Zv1_FVdIWeyIbu5!0ht?&^QFf#9+Zcc@)0;GQAd*9Gjx_I1-`{REI|A^|Q&Kt#D1hr(q&od{=l%KpFt z7vUY|0SBW=&vyT!2QQ@i7cWbdh=1{X+*5(H03efX4~2P{4BbzMQ9GU9+%OFnq5sYZ zZW;zA1XqNMPE~qyqBd?qAKe<~!x>nd~slSXamKM`u9RhNO6Bzx;B?BYIw!9y(M0@}107yMJmeVu>)!%@Cd@%xbXg0zFdi}& zH|F|e>gP7{O8GNw{_7j?PC9+LQYAuPg}66YHuYgAhjs2L`+d%6RP3& z#w;mikKvj#u*Ey5Pn}@A!so87jvipZ+p7_>!iet|>o{x74+xA1Fj!kdG+)Bp-UJ6#2}Uh3dfw?qvrC z4|HlrH_rW5NbJc_rsfsC*JRWMaHz%+;{yePqi?h6dW4-%Z1 z5P-K-FiM?_1Rd-RD;86V=cT^z^AdaG>r=3$N_(wehjVL&jl_vDm^lxvnT=nhg=<0P zQwd2{9!7B$?y$L4;OP&)u3KE!78VJhkM8hRD!Mfb2Fy+SPH7ZQW-p%c8N1-XHsup$2YU4z67fGN6JwdwF>Oz4+b-Yeq)&@dZX?@VN@)>4DKbqZxA!Z1g%0om;Oz z&5HPTQ{R(8Y(8hb?rfZ_;qc-r=I0=BYHF;`33}JDCzqNY|I0*r9FFxf&P)+2f$=3h z>dP&zTAxLj=OEPu&JmU0n#Y&G6Tkb&GCj}uCx|+FM=Je80{8YSP?-#Tf$P6DOm}l*C6Ky@!YTNe1*vYTFVKywga>2} z?CtV})mO*7MUAe-eelGi`D^GR7>2wmWTW@QPceiNJrGyoO>Pb^W-cxAB+U;ds84+P ziq+lJ<8B#(e79&tM-Ekv4%^;JQ@)zR*VXR>YV})3V_sV+k^BV)L zEJ;!jqquE<68b1?aJIx>PsrLL(e}uj2n$6_);3t0jBIC1J5wu02K&D91_Mee@sWg` z&bAv^B5b=h!(iK%4s1L4L$NHV*#z2zZB=S#%D-Y{eIsV;!?)Asp;1Dwn!k3aVd4rq zI5Z3p)E?u0GoeAwUlbN&L!m54>FhLbJJ>0(v(x_V{3O#!46%7@jP=MkLNi6DjToOt zdkx>(EeBQlbzEYzQ9oZ`Fh~kc({d1kFSn%f2%nC_#v{z?rQC&hOAquy6_9mVZbkI| zR#qE_Iwjhu_g&Fxt=LIa3QF{bktw5OF3wHcighnK6}u0$QL9{d$;Eap8pE!EM`gi6 z&G##h__W}~fJb4n^2lhHB&`2r?)ajRzEE1;!omc^% z{{*gsXvQy4gx~&Gssze=NaB&65f|1ySO3WMSns?U(Ts-=Z1Ou3=Qiqr>wD@?n+##7 z7uw4UgiiH2hm+t~Z9W}nV3&uNFxmACsuwYoc;Nts0L4}KP|c1EQY2IqgwblYOEz@@ zHp65#6aRTt4c(wPhE}4kJM$B)b~k;n9C_C~N5q}E70aO>$=EGC7XL>R+;0fw42TbM zNRk=IU*)GDzl{<_+y(3mz6u5}a8_mFeUSg{5D5utbml&vvwi`yPh&zcL_Sz7GDHg~m>dzeb~Gm;B|~Y~!yKUy-v#tBOog3f3fUh=&rRl$XfZ z5~x{NZ5V-u)-_4@2cXQYqP11QD%k8Ww%CVH)Z_V-=y;sShePf9MaRk7gzsLfC9AN7 zwwPMWRh*1_-$g<5844N=D5m3xZcHmGSIKlyFhxQ0VjGUPsBSUOd4l2<+9W;~T^qU4 zTeL~#t#MK5(n#X!(TaCPkNOA~rjf)#tRDDyy}8jubf&7-l+JV$NbNt392wU1R!n5=;#_0sSWrEye?2P;161{R`(n7w(ti zlvF&Uqdvsb`$SdmL|>;K#9h|jKu>%y9C{2a>`7CgrgIHk`}k}{Zk#UI{<1O0k5`%qXiU4D# zl}@dO8a%Wbu!~O=`6TXz0K20%Q+;6}H5WSp#xvdrdPHG=mn77c!cIRb|Las?cf3;P zg!laP256Ac{%6kFz8f{6Ktu=pzInN`s-_=Q316iDUO082n((Ly!a9auuavwbC5V~S z?C34}3Kn-!P%@h#XsCb`PzdD2zm3(KI{jlG*lDUGeR5ZkrJxx4xm`h_-2w$A-URxr z1OIhNpY%kh=#wJ`JcX4?L@!D=Jn;3r#3X}i`Taj03n}V(1VY9w(|3r=i7 z`9idZ{bH`@XsFkROF?Rzyn$?3|3St>(f+W}h@r(?2b%DBWZBvHJG$%}_&cWTV*I_P z?1EvV7qi8(OWTU6fu4%j3S&j5&OVQQQ3)=LwVhVYM=#(}QE%9#L0yY+co0JEa})xDxY~;=9tMZxf(9+T6L-Ey-)BJtdf-fOls}TqT#ibV zb3=7D`KUnQUiQ1i7|3{t5ReWo_Sh``-zaDIP?^hFwT!$p-L2ywMLem#Mzg- zF}>bu(43x2u@WX09R@gv9VPKvnSA0@lp!8p7)yK;SC)T5AlO?VM=+KzG2y@_rNy@2 zn_!?#3uqAo=E>(>o{y5{M@ZlTV*N1 z(k1!v`(M!6M@y!^xUCp(1N^lhv-iY*MHia*V7`kB*PHAEF9iL#^BA-=k+cLl5n`H1 zVseRHMRpVkRe}phDB1qTLT|w1h-gLiTJTQXY4h*m-J@*%DFER;$Tt{}zlAZBlSLj$08T`J%XkY3YdG=Eo?eKeY-_S)k?0DJXr9Dr)VQwX##6}XjEXGcnm$5<0t!N z68oWAHDnA?cu=MwE;mn+A7ku}ml8LD5&+h+8Ods)+Q7+rU@XvZb@`v`oZdj6ToaB4 zXxDFMpvK&I50H{O5^66*5d9H1!XBz2wvhNihxrqji8V54)E5SeoZTHg>M4}^BHi0U zm@fsWrbw0)9QqDMOsr7;$&?i26X&6v@dp^%OJ3sG8z|GVNJ+-GF|qp(q*RuT`Iesz zHa*CpKZ8-QU?2+OESQG^Tst&e&r;XBSJH#~CM%HU}BaC zgggTn#Xn#;9PO(w`^A($gM&KmX*MNi`gB!1X3R}`)Kkp#Udu~Mo-0MEL|LYw7l~4) z=ffS5kz#*lU=pG?Am`c0FZ7pE1Xy7k1ZT#IUt}s;#mO-pz{F57*l`x z3$%iN#RFVT(?Y$lHh_D);d%jDVT-q@#`T5;BbPREg}j+yF0427t)x)hAvfcjaJibEAbQ+`DzTS#aO@BKL&&cT4Le$m>f1EI@Faez0 zf-9KQLYgqcE>;gvna){3-z*d{W{b+q5A=tdR9NLQcUnu);m308rt6nRVMK z)u2 z)$8vav9IT>U$_Ym5rPSFHAyVNbLkyZE1!&BAyedDA?6o&%udS(F{DPOB0yfmn7BZ# zhyOM43*4CNIjY`QekC4pwig4;COIU|!3|%19-~ArjGBEHZL3xiPCRv0twRkIz!SgG zwSR@Pyf?aYhj%2dLJ$0H!GPi8Z)>*T!4_Y~^b?;QCfx2Te~u-;LkapwY(pVCSgU5p z!D*qNq7gvaHb;WUq(njR@7UN{^&OVP1~M<_juL4hn1{h8MxmIK)@0wK+UklOJofSFOo)9eI5Ds>1j zQD&WZMdW-Oj1?e&?v7Oo6RBY&wZdCeiF3h#%b6lHi%OT^MYs)TNi^uQr zbt#YE9ltq-(}gZ2{@1C~CGsokwJJ&~G10W-h6cQLT#sM8!SeWBy}lj36d{@VkGXAF zQ5Z-M6b9&N^EY8qBnVNx)u%R0d5=Sh3~y|E=&SeBC=|hNZT>x!54VbpOj{3Ce3bd| zDJ8Le{3ePJz0wjJId$gc1n!0sGj=Ex8H@z3Jf+u3rp-$hKO;NGLp9PzKP3wrHY5Nl zN4TmgKEyx$MO#ww&;7@Xf2Mt)O65&6^+fD+rl=^RKnt@_uTn}f2zr2VOYaSCnHeYa z{Yry`Wd6=#74Ce9wEDjr?wrZ)A_Ja$j^UVol*uu6Ah|q0!n2xBGTfPUM!XYyjl+8o zID`lh8&3I?{O|^#fqpCp(AnKn zkx9jLJMp|noIqE~^#qCs_Ej^)=nuckG@VMwYL=DgQJf5k3z!>|pcE;kB9#Y>Shr{* z8?icwCPFWoC>6}5wjIQSr2*!B5!NSML7&)*deq7w7a>LABp2xlrJ>PV^tQM-htVet zx4b-XYa_8ZHTa6wYmbh@tA6bG6mL=n2bz{82m>-Wox|aVzXx$)WC?~DJ4aP5xEdFt z2E14UHTQ^))0R6jd$HFpm)e9hda0naZ;skuYZUwUBsQkEPqu>I>AL(Sb2zp+lZ z%k+a0Mi?%dupi=dJ?h6_T9H;0aD_!m$D#>WS*wl#+LSWpE840>>C5J;)D;rXa#`a6 zKuk`+h6!U?CmPH85QSyW;P15Zu-TbEun|Fm$9XGC2%sO5Q(92~5I7RwktGnX_{>*4 z;f-oJ{gP|AaQH>ZC@h>cT0rG0(0!D29G}iI_dSkqe6oEw z{vCwl4=gvr@kxZ^4+Fah#|JQ)^l!Yo)d? z-iQIjuZLiOikzx0WEP@N#Y9CX%$0_X6m$6vfhNIT;WU16lyHC{~+$+ z&P~^snLqH747gYw`Dkk{QEKs{&&H2Jxa3DVzbxez7dMLggjonMf>oM<59eJ`1emR2 zZNVZEBfmTqJJ1vzQ7zupT2!G^RdPtH4mq`->}CmRWi=+e4AV`LVrx*Ek{@P>SBM|` zyKTt>Tq<@+6S&xe3zPU+2#fAk((6Hl*6JC&B10ooW%#rrmwE#m8HOkzyyV`Zz4LwURGAtg=#h7euUh@ffnPqx3vU92g1usz5Yz^$XbXvAZ~%fJk7 zGQ1p9Sr=+4FG~K@$P3^sl0P+40(c|cd*Bg_>PD~PbGb@}Ta4)&=>e=O<3~+~Va>V9 ziTSDV2^teuqJpyT%xcn&q)OPSDV1*kIUm2t8#r{MxGzXwQ{-Dv%pzc}0Z^yTL*r?t zttjAeJaPQ81N4?8)p6V9p*z&kxzXW@?9K#j3EB1I1;G3hFE73V*=+$JUCa40579aU z#gnT;Nn5JQt`xPY&E6yBRgl|gT$t_)7D`BH8ZNXbPf`gt^c}w~0Jg zc)z>oQ*HhSC})`vG+lI)t5Gde-sSl-1Y>Xfx&(hu1zWVNIl%)ouJTCxqe*D+Zw$p!(o8twZnj5vPtRc5lmc3f3+p%7!^ zQ{X^UD2Boy$R%)qG=ciU*j10_E<_=Y_rw)-xFy_85p~CsaK}SDQ=^&3{i$*;2&I8_ z2t6OhW=um$K`9=V-Hf^YC<4|B#BlsO4m1aM7}=Lb=9rHOnpr$lY9ZQDsRmpEkm#v` z%)Eh_Wh#?cOp#t;WFd^Jlk*JlqN#uMl*_(1zJ{4^gfoaDx6a7z)kdv3fw^JW72l!C z##2>@E%1-+JZYAYKTvH(#Ckl(ihr5U*}@cC3-Zl%h+6ui?2#xv0K{|44gwyG$cNz2 zLW&IcOJX%Fu?#xdHfDx7=tY07R(owz&4=A2WQ3HC3-D^iU}dJ2W1G;Vp{uEqQtK=q zf$w`nCLL^0=bMOWfnsI*ae9VbWbEh2|2u%U0Im&2I@r*Grf_$&1vnJTUQx*_ulx=0 z#hL7p9&^LT&|$gI^FJfH(VS-X{rM*(d`36QJa&_>>>9!#M=Y3hpum2T#*Ph;KIE?>Z5Vl- zfIZOUV_Jz{S4r%FY&LA}HRHn)q~kG3#|YoG+a>i7AcK&UKoo{MDAZfDMtd$+)7srz z)F6zf`D&0)ZhYl~{5K3QX!GO*L+V_#R*j&P9BZh921`+fDSAqHGle&+`G<+=+}50g|C;>b-mP#S|Ka&cG$IvE@UZ>}7px+fkYtyv?+oJ{+;LpqE>#ARqEz5(u>)LZ7xq={!H z6O^NtzD{LX*g!}wZ8ZK4qeC#&;>&i9)|O}L*kMOPn53Ax>QE`a3dhM-P{Nw= zvMTIaxV`F-uly2lqe%hvdeNF$Ki~{8DwSnKUY%~vS%qUea_!$5FE^h5PYR#UqvsDO;rI;*FO{7u?$YMCion zLUwaozMjPon{;uaOb@!)u}HFCFfSyAPbYQS=4acq+!fQKiA81;Hm?7FKptme*zt_N z9#yK8I`UBjqY<}WIw|n2mT`~ z#5at+K*>oEi4wP80{y1A6(0CMO#h~X;P~{v?=PhPMPD2J)17Lg{|8O_e+e#soDZeo zO!@c-sX3C>HJtYx56&P>4@N&c*}oBPmT-6SWc*3Nrp3ahz`@!yXXiYi(GLN`g-C6% zz}iFvR}jIzKu;Do;!?-<@mSgPP{V`Me37$@AHqnZS0w(t-06y(=?d4mYTC{j89D2H z=Cw{H%CTcTDCb;pF)Kh)4hwZXD$eaOv}4vRq4q;xHWNh0vD0D{Nbf`C0&nERJv4XK zNxYOnJUrdV7hr=p{Gr9(Q=UHzp*RMc1k`tKirK7c4HpG$)|K3BZ_fmW?K}@Xy!8eh zAAhsukVZU6c;teN4_2S1^edSUKid%kjbm{ZsRotH*tHKZViA^wT_r^pVPHyQT}&$r z`*yGyxqb;MXcj z&fw9bh=TaT+bK^l8<9EC)Ckjx!cFmKu@8sfqVfG0CdA#wfA|xqB~q>va2=+SrqQ7% zp7V2@KCVS@UiDGFP!F6Wue2KxMI6Qi!j6XrUg(gsBSe2ZZuJpoqWbquCE&k}{JZQ$ z%0B?|Yg+%il7D~bApd564e~Ga#}4xEkD!Uv5^pm6|6zEGRenPH){Ykd?|Z;fUlY8$ z(6@ZQ2N*=(I***!RiNMniW&UZX$qM>gFO517+F}6PR0DN;a=%mC%uq{j5L-64}l+* z{%%v;(M0PXj3(OYTkV6X(3rL5(3tVnY!5VMG$k6dw-qvBC=})ftZr2Yp+oDfxKjy% z+?1(&0@R`zUOVJ7!fQy6sX928MsvjuK3Eukb;!Qxkxb>S}2xJm{e-Ih;e)| z2{zU5080tt{1F#Qo@*f%uBLrKi|s-6g;tz~^2g_q$ADw|luAG$`M^v99826Ww1Pt? zpcQQRy%Eto6h4XaEdC&=A$muvv1m*Z|Htu6p*zt^duoJ$!8UH zPHa&+(;M+1i!6qZ4XjC)48^J0dw$1Ltm%)I^%0o-;5S$yBV!TH#^IklnhM9+c%3zd z#!Q3>f2Daa+R9Dl(t=N-$8;k%DkbEQG_&$bbZz4m7`fq-c=*~cK}x`mT`4dX0?f86 zTetpsAb7{`(hzKKq9ePe4Wl*h$dzxNW2- zW-|l?oNcljJDL&0-fScWFQp!attX&Yb3+P+2KOd9)CunD2sIulBg8rg7bcCeFr^n- zI-wy|K(#B-3aIw->Fud@lcL%qza`b)fo6niv4_Ot{3t$Xp`u*MA)Nby@2qt~yrhG) zg(8iR&$~ZG$g41jbV80vNe4pS^_%vz!$9#nzwSWBrv8t^)J6fXi95vsqx4tO2+)|&!swBW+xc!$q+~m%z*MjE(Oh`S@ z=7sSDWLR-0?y%VODyws1_M}Yc^tf>K#Aj41bKw2O5dd=zWnJiSJXAprrk{&e5W~@= zK^^x%GlH&){fl`|;ST>LzPFleG%PM8+q#lo?d2MLShTyIuatfs8SKXE>QNmZdGli! zgciOX5Nunk;z@}6HcZ8#-70~7I-XGJM&gHR1)Z1DsHCf!4~B}ZDGLma1mIxvjKP+0 zaMq|fzyiLI6Mq*jiNt6TR~Qe0Y&O1E`xcH59N)CprHvoBR~v_a*#pfv8A1vOz>w#2 zX=i8zN4UZ4zlZxED^Ubl!+5|5Uu3{B$XR5TsU|uhIj+r=)E`%!`^uxzi!@-pu%8&vZoB-16kR7uqM*JIwVmg7T9F71~%)p0Pt+2ztab*`Q@ zTIdM?13SdE`J`FE7i8FD0!9Qv^+o385i)@qq)fZ!9CkRe91l*$h<|<$J_;P^$Bzn? z-AGCpXQu>$+$0#cP!E8fP8%eWV)Q4}V)-Nr;;+DD1|llzaF7fLr*Kmm8+3dLCE|K8 zV7F1;Js!Mgf!J;E?)mS+oAhgkIr<}N2Lf>CvS}`U_vI!MyXW_mb63c&(^T^WjUtD{^i|JgYDb zTEY*6m;L<&2ui^%SzUjE?-SmySnmPev15;y_2<~@FFJO8`}n-pd&%n76C9uY{Y=~Y zjmLZc27`bLd=c#L*6|0fu!aXK4AF7DAv%VFue*a8|9rQQGXy7i3UV|H?su?-+z-9k z8+mvj2pn{1olnqSxV+xEa9P;4Rjm&<+ld|WjQS!3MULUdTL?DBP_p@jXLX&eGKRJ( zr`)z~TK*fdur=2-Z&&}CYMR%y>}jrR+0y)Z^STdqZflu&b@^4>n#}(JRiFHPIWj;T zUM4zGP8dG`9#ptI)s>c~8g8g-hWqlL$)8c3wZ7M4c;$mI z-e%Xffq;6p6U`RlU$4Y1Sm>J9wDmIAgXT3K?A?a#mwELMY;KM>?MXGLjx1{XNAsHI z)@^EIBQ7}%m2a8&F`HV~g1ugpvN^aYX~qYRu~6U=t1|QgTuh~9H?-vqnN9p3p`|z^ zfVJ%^IiWU!JSw z&&tgrVRhp&Op^`k2;e=q$LMFE=&H3Oh@`Hk@d&Fk`z!&mx?vlJXm7!fI6s14pr`@o zhwy-4S9q;9_k17|&D3a*oDS@&^K#hFZ3Jl6ge+g6v9N(lpi7KS6P|q7A39kc0hQ6q z<%~gtSOevu9=~-!L7!f@sYSKyj7*<%qo=5D_F63u6UoCwlvI-3DvWC$&**W<9kd8- z9?!htFy#>AxjeE-4e+oG@C*EfmFN$&s9|z7Rznq~Alm=k>!SUeU841;_zj~ReNcvr zfe%0Es;U94*anPojyULb*2{(R=u>FFe=oEB zjLgpAG4a^&aOJOs%G2aRKuW$jm%kQwyy1c1sVUFwX-;{X;OIwLoVW}y$CoyJmJR2u z-@(84)ts|NfD6Yr;$JiVt;9cIaNK76t3mbb(FzDD04z&e<@No=^sOVRp^y z+j4LeO?Q`Agcf}a2U&Epx&~mc(X#pw=ACyvT+8m?4Rx|JoL*DKb0 zD}fJj;lmy~%~OLb82fHM$3JNN2u;Q&=VvTLmR!eO45XG9&nL48r#S4lG z8Xaq~Vnv#0uxf+JRK_tjT0BQv?V&xkwXLVx9<^xI=7Iv^1@Hz^HD0PSMp~2>0jqhx zzh~_|vnLmUzMl7g-p~K#^C7eM+Iz3tb6L-AJ!==bvxeUT8*Y9?;`Ms^Oqa&)pqFL| zFUNkfTz@~)JJ!bEn1p?w&dZ6+Hie0ddX;pNzx0s5*1Jl2x1_uMf{1tUuq#G2H2e9b zfSmB-MLNCmJHMmmF_jek?E*e~d|lMLdc=;@{a(~NV<~U_okt&D5c4XRbMp}wr!J$u zQ#bJEOPjoFCuw+Gc6!(TjLY}Dv)3_{eSSHQ8oaaL=Hrj}?n6-U1Mc7A`UQTUW_X|B z+3Wm{($F*)tdT^qkY~!@_Rh+ekeJc8E=@R3H%O4 zjyd#h@4jKdID^K{_#6NKA7ur@1~yW!IM3zway z-i)hKw|GOp1^*INiQ9Z^Bh2k8)wWXodgXF))&sAn8Gd(g?2K**0Gm5^O$9KJBi~P?X&#IsY8tSwBe@BBFSX<+BY8?QK-QlvsZ9HeVE*z-e0psy& zs_YcNJ3!t=m%pKJ)rVy_(T6Yl`mK{4gvR_|&HokgMIeLg?az5rSeCsy5pStW|-g=Xs z?a!N^(KV%i=l(N-%t#u4LoJQW|2s{f&-tJ| z2lsf_oz5Oj@`mtNZ3JV=Cn*TjRLPr?GLbjgt1F??T4K)={qVxPbW;p&`y7cyph zfB6zw_elD*3SCgW9U=kNUi2r+Pf7`!DXDY{m$y{r*I5f z-{nDl634f?zP;(up{gN;h@Z{1~n1M@6G*By^Uy+<`+}VBj=)fV@FD@Or}=Fv2n6C zhGCn)G!aj&h$EWCtL9nN`Ez;2(Fe~7XOH6i_p=Kp57zU5 z*6L*uQXjD-_@*WV)+EQX@(`1gb0nGQOSgr07TD0wtU%vu^+9>=8@FR}I#PWy{X3|A zaC?)DG9U-!4P<7J=5*PW4&(p6Xj#YB2ha{o2WVC@)%5kqUW9EZY%hAMpA9KlwSoY# z1-;M8Uf)lh8oa$1&KaaVnJTuvz5e)U>XR2={z>SQT3bw;6!uLjRVhXG zzD7Aei-_d?s5|P#R>xY|Pt?k@h!n}|#2erwH_YJzl*X9pR7vmJFG$EUJyIz$ytMXH z)TLIk;1yI!JVmTTPESzzu41^RKjND~3JW_a1)^Wp1{L(K>JBP=kiKLVbD0$DQVE36-Z5+@}p&?(RBr$Ywg zr(0XCO4@v&O8Rs0hx`#H9LXQz&&L%b2U91DXu@J9W>8_NFvHv-6gYeo)48kne2}N((h?+v-+fs*ViYD@JBZE^+`X!wOQ`!CBjLe1UFZb zUVD5&m2^rZ>nCbUms2PEsgf7)jZ{f;Jw>}vB~PQS{hiSHtRusoD=uk77y8oT%Pynm zWB1^N5;gM4Yn=egl2TA3FV!rJz0lOi{d;$6JP!HlKHf`Y$_kT*@IhcKR{(EgU`^@W#741vscg`mzw@~5j9JHl%&4Z`r~_yXWS^&;GNw|Q-S`tiF@gf zukah_kFPOC(;qbn`~2y9rcY@yjvVQ_FlMyJg~azje>6*m-guL@o!-YZJNcgP=;|kWE)gk?HJFB`xe{|SAEYvKz6C_<6D3+-#Q)iY zWMJRzo3+7$vHZivA}1@vZ_YdSKoN=T(dBj7^D4cn#(NUkD<;%s&m3QuofXgS70<-x z^0c-tdorgSjH*k05mVb3c{_h_lJYBkPAgzFhq^F5ku1T1hsU$+6Ck*FX7YS4Yu)9Y z?nFJPsd?iG7-ik8=Q)akg<<>}S-3g^E>Yw`~$I*Lqq z>GejRUVM3G@;pVtydv?qWh3#LuW^;7aD|tCnM>u*yiUJtfWC%bF^=?4xQJxli)3Db zZS0e3ex&S*Z5l4kY)WQsp9zg7Qcrho+Ao^9S-Bu0+R<9q8mZo(9P;G_LXA`{3&qMH zYz0OGy-~Vjfep?KKAE-3$;RIr&05toe&}Dmt01mnK%e2x9vf*pT2_sP@mnOJC91m9 zeY3|z+H}C{qM+=tw&<5X*V6NkOzf6y?3N?7VePW*7sccj8@4ER+gEn!_-=OcEtc$C zv(U=(cuU8A@y^_EDjlBNcJzZ~@v4P zo5w5}lp7iDJgOq*X!5*>ZO33Y#93Dp9rosxB;dNu&`XhEoyWE%NA>0Jpgu4)ku2DQ zl+dFtr8wV7h^BLiQBLx?#u#Ue?EN=qXoJRfz6?Y}L1}=DZP$*%&{_`^f-G2TJsJ1f zRcs4y8?B$*(-%Kj=Ej`fiFbN;As=&yA??b$$)UISajr;_<531aRELq8dW+&djt0+1P>t zZZF_laQh*L+Y1V~9jEOQ-2U7SK5j2aw#^W3|JiW6R__&Ydsz9fVOL)QLQFW$M~H@V zg$df7Bj^j#aa$270RwzIcY$2Cha`9P(ZiX5hYZCVXVO=p_Y!&udUt@{%Y@#B+|#t> ziS=IFT4?g?;Gn2TR#7E}pl%DErpZZaiQU6cl*(z&QcmDw$2$oJ3EFFDk1SY7Q{?w~ zmuQtI+DIzIQP{>v3o@^3wklg4&t7kFkMUGZr0uvKV#SvaIQO{U=IFoDd2(SWPM2tYeihCC*s*O5hbikc zH3uh4Zc6gNKUuQFPk)K6nsKGqcqcwr^PWqMdSX|4O)+G*Bps>?+5HU-x(xuo<0^>R zRcU%n!^!EsrkTXs+LS2h_MQd>{&U9mlZG9{-YN~M%$Uj4W7uI}FBe~-vqY}92o;53 z&ZjD(y|wA-cbA!zSX)e_I5V=;7?nuNFhP!WnO^xO$~* z^w_o;2kC5Im(J9O=X%a7t$Diu&-FvV)1|k4N}X=`5CLHYSHLqVI#FqQeZvgSgPD6h z*9K4vq+XNz(=3B&GWBRY^%T1Rpxsel>n`I2bpV>Rgf*=iHBcT8eAhHN_;yev5=JET z&z^>g%MH@6<`#n|$nTRvkS^$pKD^&F>Jz-bRtj%bY`G(f@V5LD8r4twZYM8NJ=c@`>*>5P z0RX6cCf9rW*G+Dd$-sk{5hiWf+q0vkXNMT%&wA#P-Ez8H6izTgJv&ibNv3K|J06^D z(P4fkash@+6^5u#tCzCvN?5$%a^$t^I`pL-9UvL*8kJ>_6iTPp%pS{9#`^ZC6W9Fp zZA^H5qs;9#<&?Bs<4mBVT+`r~b`1UOn1YN#B&@KDRfAKYGd-*toN|X;BE~|H6)p1%QQC|z$a`P%EvNQ%MVj(=sA`7p*yEmOf9THHGGi!%C}i# z>cq!dmEbVHAizgu^hV_^*NV)ZO_R+C_*JVCVQlospEI;j!f6?Oef~o}_VH7a(B#vT znWvS+Ny2R0W42{)CjnltwoC1kL_Etu%3vZ9uLjUp@g|E`Qk|`JVjc<5u&@uZ6X83YQAi}BGbHU1;srrqA}Ie-M~NdS?V4k8ks1(Et9L|_dLQi6!C zd(=$oGn)gBdTGGP^%rBqFfv+~JYg_e$3;NvDjXC>Uiv?HBsTCP{SJhcOMvhF4!${hX5w$5OMVAJT?#>b72oS2Sbih59t%_!i4l8+})q&+;Ud04%k||b_Ik zI}joeHQ;J?u25@*L<4C*OH`v0?JVO0m{>WB#1q`gz@W^Uh!U-5=@+kJhTlkLQzS!> z&cXY9aH-iDW&-^B+U~N<+Z-(h3pP{3sTEfyvwO(Ypc9z@Rh%Y=Rp$ykIj}ZNP&rEr zNPvXVT45Rx?~k`~p+=0f5>*_fYY%M0=qTi^sgTcX%exubtihghZN*|WkzHHKd0 zvQThuOIURJF?AQ#Q?FIKo$^Zg=IeWI@@xtUqb|%tVbq0ruwe)D@W>^ahXGTN*Xmlz zPi=XdDbfNV<{8ro^V4b*wdNUP5oH;fiRn7oYhH!yN623V5}Hi1#?=#({uXKpQ6qU< z1mrAo1P!loLU)}Ozko_4FF_)wQJay-nOp>nRfVFD`>9Bjus?(Iu6u|(FYT8dI!l7;;H8(8r5=Aq~_D+T<=MeaP}PJ+hr6K z@UVv)ao6%-{=fAt+i=YRkGW5Q^n)>0kpC8t-MhW2^#)xUYbVni&NXu1@Af?F4OxJ^uYrE9^|~oV12$AG<}2a=9PGp;4UGg5*i9)Odd*R zo^*nGlO*wh*g|>~LlDi!L^*IxY7)A9Jc`IJD-;<8@ZhnG#IQl&G;C1ryZ{?iC~UZc zZ-foU&};8H#h-cUU%0YE|3zil!-vEM0dFvD$WdOvhP}S-ut8*$$mD#Le1fDT@gBV^ zY$%tu6JSFng3C{5_^{9Cb_byX*f#}?#`$jm|E-6ALf}_d`h))~^uoJN0&VZ1($BU4 z{;Mt${OPh;bi7tY!{z@Fz&|7n*Jt-KDOf0Q4{ZmsSN0G#UQg;lDVjLB;pB> zI;*#Y-h^gh?mRwgl1>lBWD!gS`p0Ufzk~}T#z@N$iEWRBQKYapDK!f7(;t}9s=`4h zkW+7YB;r#RKC`=qtPF{&g@^!-!xr?A5;1ml?y++<$4{F{_WiyTS}w@1 z0R;DT-N-jUG7g9(@+-bpteGxLfy=Xn4=k45Kb9qu*=5+m^~DmbyB>O*NKH_tKPCB# zw$=7btmmpD+IDo0jG!FLz!G~x!)V(Pq}&8+`D6%t7}iemnvB*@k^~ucCQjJ2F)C8? zS33-yfr|i~DkRs*x3wP6 zy^)&`NVhrLK#CxbpyaGhU#jjdll>aP4s4qe&w!+fr-Fn@qeAa6j4!{SpoC(|-k5s} zY#9J(SUm6p+-CyrqJ8t&5;u^;rTk>T?cU!4c(3|8@cvsp@Xm(e&1C5O3m-jQznxXH zwDX(zTt>}fjOLxa$fW6b$l9&tv1skC0!6maW$^?b#;Vu&E(?C;vhXe0>&?Qg6A&?Q zhlyHnc1(Vaf&0TS^*YbQ9lT=TzLN{UJyB*#72=pU9^(B*;Fy4T_n0b3W3YY_o;_-v zmPMa9&t~kvTJTgo5(MV+>)WZz!4SY059rnRM|>UlRR#3e-yflBdRvP67w~iWh=x9? z_<{3*-&Y*U6x#}eG7w$@`PD6^L&K*gTeYR|d4>LN9eh}Xi}2|i3O@Hzufa#cLI58X zLXPLA*EG3oQI5GbooVnf>)z8&X!+SejuHbh)S-I7OmgWCOjiIf6I}a2?VCWm1Zt4n zd4Oy;(Nwzy5rmd?!7HzDhoV1WbMU$_1-x3P^=l;zFXuaKrfNjO5x4TbFJTWrGdrCi zBrdgoYY{@b6sKv0!l;R}JzEeM(AH-`k z>{*D_IO<&Uo9iccK+=!ZXspr_R&fUF$$t1RVv>alQ_-3t8m$foIjwKnS16S3#^&TlzvQ*4si;4>_!xUhj+Ee~ z;Jgq&p60H=9#)7)xrpTw`vL@0RaFq?bq)kp_Ur!wkZ??TCgI%@k1oCvAy zhQa+oHk)_ z+lVFDkEmf>&5Ee`9@ROnB>$$byTwzS+Q#{A#w(r$jK(W|#05c@<`}Z`iY4M75u37L z6lmj}&`IQ)c_gBpgsV9pQD-LhEHPPg+l_?S$RUezW~Cjynni@oYGn=X ziex&ne8bkZFY_wj&g;;Aka?XW7klZ$D3YFs6@_Fwown=ROUtGTPno+TjmRJMjM|vI zG8wWw0xK#&2 zPcGk8p642z#w^bD42)QjXX7<9lp|(qE(kyKLw~g7i>K#y-FNt~{91jUimkK&9ficP zo*&%@RK2^q10z1sUOtGu@0IgPepkI0qPJSqtAfo$Az)tS4UyY@)?a!LRE5!AW)WZd zqcQuDKc9N8!P?PwZm>mrw^0|-xYH`5nOJ#d@*cS#o^+tB%oJo}<)kjnPTs=~nJdzl zWNv6Is%^FJ6k-S9L`Qv2F{NLR2LS}})K&G&+Bz((iR_#yEXbNP!UN{G@PKH=biUg2 zvkDK;i5b}uA2Rp4cE`l&3>+g`nW8PVtIp!nsYILnBih3%^^Pq$)^`~)iva^iOrGHM z>teuw+&m`fox=r^o@_6f4>d=u={g`Q!{B_xuY2V*o z%a_BP{n*xKXEwIgxzzDKMdJ!vip!|p<*&4LS?570qUA+?4Jz^?kDdh9rKR-;^?(X$Eb!xmxh@z`oLo5A`SAn4M4c}z=FOum3kn!u#5k+ zGoiSXPSJ{42uN57jmiozty}Xy+iPtG-F#5^Xa4F48$^>r0KuotQZIFf8IosSj%7+H$D(A`AI_n>q~TL`*fTQ1FL>9N$I(q9 zb2hdzW*rZ%>lUsHI;5ElG$Uqq2Vr6PCq93K3uPEAD5^x2bU{&js*6lV>poogmV=D8 zi%TSxK^}C%uif7jvzRA_S5jj7a{pDQV?UE@Md;vx+%H&(vLpUf-Y-~6lwtVPHllfo zG#Ni?%&dXvpVF5!+w%8u@K)|eCz_&BFdB7(17?R7h82y?yHZ!~ufpz-fl2wmnCRJ- zSXT4x!~&aU4o;m95(Kk9(`&tvTb&2k$oX-0Hk0wYz~039-)(AIlZ}EK$anU^-d0O~ z5*1k8m-=qA{8x)5H+R3kI)5BBE_B%RqXTsWyP zP`%S^O1brI8K;7tC0cPv-{mdiR}%{o!Ufcs`^gCdKB*m6&BO|y-2Bda)It(@o85E!D`KA<~PAHZbJ_*0V+H-rmlT{~y zDz{Lvp~x8mfKWstq4iHg2puCFh_AM?nfU7TbmC`#k)psK1s#2VL(&AE168MDAgZ_s zc!oGa*x{hmk8JH!wk}C-`mj}rBB^w)b}JkAh?2IunL=viNENUOLB@wd(-`Oz}wHyo93?{(-;Z*9HFZlfw6rwi0>F zWwFa^4*;)3)$h^~Z&o|ZG9!`y%@NV^mte8Ug1(OzE2+d+ZDf&ls!dmVy_1TZN6Ikd7}YKeIhKn+Eb8x)3Sr1=RBRZsiVI=L z(R?TQWiNgUm@=P-0j3D}xrxUD6b?95zs&3B&Z;wv(F<-BI&CjjA)(A7r4jX7x1-L& z%y#ga%`9`YjO!?fg#7Jh_8%uZYn!nY2}H7;ptlg1?=MiB;)WK}P35q7N9yP&|NNX< zawi=ZdNEi(eEiYcqs!n(=)8m>AAg+qbUr z27a`LO#ldni1BTFMBJ8(h`)$&A~y1lS>C>YpwB{tq#zDfh~(N?;?5Gp^R`{TjKniW z&qh+Wye2+A;x$kR9nJK_GJlI?9#iO)^qfX2 zmPFm!Vi&AhSJ=fGul1{Z70vuPmU$n9YptlHT!Q}YCz+uCb>yEb!Mw~S_L3p$8&c{W z3lbUgPX>u7e9EwsEt(4PqSosze211t|7?P2t6TxM`1O{vOM`m4BETjNg~+@)JF4 zel0bjTMx|N;y@c{{H-?kqUrra(+|sJHqnhg|0o78-S5G?e5ad~0}WBp!#v%WF9VAoZ;Lxey(3 zaOSp0zi%~GY>QZ+ff&`QZZ(MB>pS(0gb}os`A;NloI%SLC6mv66e%ugqD4D@WDxy- zH$KUobWFdOwZ54=?X{X<8)Kl5i5j9+eGwkY}Xy*)3OyWFT` z@_K>ld%G@Z_tK&VBtTog-55&NGvcKJ)6`6h*%61-bRaUU1LXx}L&=)}fuZCXTnuSk z+K$(ytM4F`)MgZB*kaMYtCked0JU}a7Ps47$ zi1|W&^H&cwAtAPdUlodBRMUj*P^P`F}Kz@hh|=RqVKjck`p*+yQ>+dB~r-nCD`}3UF}vC0T4hw+bj0 z=xZ*Cv>}pIDnq2dt6$PCu2sngWx|{7z#HbvX<^kWM`lbP%0>11Ko5JA?}pIBI(cML z_5$^DwIaQxe}o9Aod*WeKrt(7Wy_9`$iNxigKA~(?Od=V?oM|CNYAIfKyR_&AT?mv z1<1b@H;_va`!8XSuZRJZK}ek1=r_V@GW6j8H zu2R9dS4_n1aM^T4!;f`CXNUF9^WjM?>A8L_^43(Zw<@H|_x=HXMCjq(16#O8k8e|d z{%<` zV>W<$^d>{mdR6l^S=)*VTLLr=7=Aaf9E6{&kAZ4GnHYMnpT5=!97^;x*?#_ceeET_ zcJkej`r3oMvN?SXz0?i)H2N>Za?{|eYQuy!!Tu|gttMsfvR7Ef#1ABCY4I>FBxT32 zM|&S5h4pMS@rjUI#Jl;i$onq`)-IH_z;^v>UPplZIHPsTN5wEVt%FB6qlEOfLiA#B z4~|6a0l|w}5ETYjYJj?v&a4ZQI>#+WqbBfeHI2up$5gCP!w(nH(oz!oG|f*&~eGX|l}V=-3^H z^~k57NyOmo+plAMP-<`da5VqaUyW09+bdl(~MFR^G0Bi}iNwxE}JUl7`(M@ugDFre{1zmU*2Ul&8G1G@YP1=rkk2Ds-F^BG4wV(y?B z!>fGmdmygA3I=#pv}X^3Uh5&?-12`J@DcuzkFjU}2ha}Y9ORM-yI{}0mK&enxz*IS zXZz??(8t60bqe2<;#Z_tV)#|feXz2*-?0B9n!Tf9K9c~~61y@sC4IoK<^V1VTq^9+ z4Mq_1e@LG4=WBDUDirOfB~o@E1>lyjBe#>nEKkneh#}DW4 z@Y&BqCTA#r$4tH{#gDU#C59hT6B+eeM~Thi2`a2{MQ4vik{59(j6ZOl`LrHJAL-AA zKGJA5gFd@j-!Ldm=iPvRZYBO84-J7n+JbE8Bfq^vpV?RPdaE{6*oF+Hf9i)fW$Ozr zvM-Mp-k|G)Iz96@5=%-k=ba9lgV=bT zaKvG0sWFOdP}(kbmU5D%7O`52CM7fTDw_2!1&WE7u8T=r#FME#_#xg&@d140d{Zuy z5+c|`1=mbH&+C(!JIoiS&!@A+%DaD;0eNmFo`BH8$h8SXdCCYA_gcrIuNX=;Z=$$` zJGQ>seAZ>2tgGpxBy0X^hE0y7Ow=rOc5t0exgxM*l3hPo;y4p7WXN>f z>wa1_^pm^S=U!IA>m*Jy;VyjD49s+Z&*JLo`D15gE)ychRAZ}XZy+v!4Qs zz8RCfMj>wA-Pb5*7nvqI^*(2)>NHBd<@88*j%w%o%M)cAbpoYcL=70-c_h58Y;nA7 znG(EuEz)O*DZ6f1cNth8KD=@iL31Pn^fRrPsu0o3ZAp#}erk+nzMSY63?we-wUSZr zbi_Fm3+m@rz65G>(rO_n#a|x?o=zGxK1YR0IRq%=(N1PM4HS7}TI)0GT3#=+_v(45 zw=DFhdDF>_he|Q|cBP=S=`U zzdf&9(9V^8RlT|{^IU$tGdveK?8tzE;si$&+5727K)fpkj!^zZHav?f(4}DmXH^rJ zmw~LXo@+!G(Ft0Yh)Me@`5M#VO3tUGdNmWho+4q4wsPc;r&QDM7**vDvzx|P%hJ9D zYPR>emZ$pi(r!JENUP)RTW(v7iCHn@xoT zG>+CS{}f4R?&pxH$&e>53MHFiV~>uU)%|prjWF2sSiPD(R#Iq4MCS)`3`{FS74;lH z#o@H>pd8f$bC^7xlOlv~GdTxYqy+mAaj@4*$I{+H0q4g?7VN}D%&Y5^iC`izRz#%$(qNnHb^VPG+ER2-Qzj3ZMKz2h@}VaW?OEI zrsZ=oRsM@y;MSUmTPv+XzH1nvvn}>01WgKqTLI+7;#duFY1RM`;GUJlOYWCWxwq({AxPuN^$CyC^R)wbbfrA=9+)DE`RQ{|u?dMv) z7-~6W-wDx^4J3bP$XesCM}Er9BAzaz!I*bHXTdgtm3470*?hE1GIcO0g}bd0L`YUl zYW_e^r?3$T?6|99K3~OCJMao<-B8ig_U#_MHidUMF8Sq1+pHdT7S)4^i43M!$8E{8 z_B`ue+e~&NdM7>>;iHJ^E#MfN2;5O|y!mqT2T8A0^TFxJADkSq0JdTnRmtW>@hZ#0 z_Cb(^?StZB>$b;faznqpPO-G(04`s6!izo+T--_Dk1p7e`XaIktcVz>65a_b5;e;o zw76<5Z5_^w;|^Yy9m_;3v^Ue_qFq3+#BLzj{2);Rl1HnIQ@$dXRw31i5|%U`03|H; zR{_gO$qq#?{aIf5gU}+sC*WiST=-c`2W`V|r-?Wy_Ln5g*f{vFNBbS?$LD%OeD1 zE7?eN)blKd@$B%mMq{}b_P_>5tlgI?*);wSvHL>2Fy!F$JL2EOVNAbMvxMHsmq9wY zTMvUA8ekE5XBA_Ko7dg8_w7s+j2U(vt0o9P|0GxJ$AdmP_>TD;*7=rC<190is#jz_ zqLVYIEKWPNL`O$GX1#sWby!Jdw47*3ZyRwmZwABhUnq{~zTN1KHmQa4ll?z>`@fgo zPCZ~SdfON3_+;tri|aozdh7g35kX7o?Hl79z5TJ`pP{z|_2!1de?AF%+ndU^jNaZu zTpg0$VxJ1pTanI0=_Yk$r#S&^nl{iQ*usd5>j_zRrXr8D5#Cdv;Y z&r43yuIxl=WL*jmM;#jYwCTw4lO*WGGwfMlDUk#fPaVOd@sfIk7+{?fjo2fZtpnva zQf{hth)g5;-hRN_^wo-{?;&g?+|dPbsB0o`t^m``0oHzy%U*T0hz8dq+H)%=DL z?w&Bhox%q))orsA!iJE63rqC}hB49_L#Y=>hgpbq%xg<@{ zmxIg@a9dgn#2fRPA=!ixFgJW(z+(dai$b1{M?P6w^>0vte$(2nGHmR7EwB1f5MA!#p=P{;--MO?+)D7QbiTf$$ulhZCcunZ z1-p@eGG45pJXg({F8s{w7s9L({8ZMhg23X-?_q&OdJO{0-0|RNH}p3oe#%l^#835= z`7|OTehp(nsY=4xb@`N!waPL{X8bY}--(Qp<^i^_jS{*XHP(Gh>_LoK4PDcFR zR1d1HNTkLhIZU>#>dtXd4DC3PiWYOzb7~B&filTzR2HW8a_MmRWo*Y{9p_($~--n3q6PSPvBYu6H-(@Wg7 zP^)DFOzkgR06VVU<4U>Y2tHWiW!~W~nH~M3cg1@?4Mo*u$13cjnR0Ew9xFN;@1U-@ zU-V)e9pcUsSj+XQC{y!U>81b1B>|07cBVv800d(%rjAcSS_j+d};xH_FCC7-2j#!l;e8K2+kmkk@8hhktxAsqh?*800TePN8Jx zQCn)?@y&{|hKobWMZS_>#xa$#_nEno69|GAHiE`8r133j`m3=Brf{e z4ee6f7r#4l;a|GS>N4+Qha9)$i}JB-Z=A>+bjAWA{#QhfksdA_jGC{fn*qL|`-lW} z-Z_`in%%GZyuc!C%9y+z9Ju zQ<;Q_slweYT~=coC$@?6$pW zo{NEc4rPVG>BH%q%;tG%N3zfVZ-cbeey{nG9n!%Ru2_rmA}a;Go4n< zi&+{k_ks14{hX<3cy~bOtB5?*^8` zd2aN`D_XZ$57^~(1g*^+RXXIi`|netCBja(c|3r48{wQvR#S zZhjD-Q&%w?$~NoIk0y^9JJrpYKR>>orZ_(j6|^nG4u5`ZE`Dv3!tCgr9nDz7t~Oh( zT|D4wmY3d(wE^l$WER_`Rj*FebVeR3%u&QUVPRcOcf?dNtZ!WyQ>4Uh5nFbraVsxyGpX*IkBiYu%q? zW%-2MT91FO#I1GB+d{pN)p&3(jNmh<59>RhE%>lz?%EI9&?CYBURo|?fx-nB8#vM_ z<_FE%uoR6<_E7OV2chTrz@T{*#d7fi&y%^V%dB)>m5@0Pw!nd>E!IwJeQHepBjDrYp=#%9v(6ptqgv}P=$Z{w!DsR_ z-A(^{zoqez4Fp`E1NfMFcfFvU@lo(K+(jz*FZ|c$x^uH552KqM`BvqK(VkUisd~K) zyLaby@YXJE&~=$*`C8S@4vQJgL?ZJKoMJmtc|jg@^LeqW28^#>&l@}0gf!EJ>$U_d zrq+G_#0TN^UGG<~;2|!XR;@1iU-H~%HkUSDK&$W=yLXUjAm=@@?D%@(HhA+ISd`G}XR};6`MjuERl<eC5ZSA06(JK()GRLg3gMF`XJG4E60ceA9!RLKWiI{eATdST9KZrJZLG1RqJK{FVl(6wW(a4&)K3F3n;?0JY=T^< z5p&|yJhPHmejWPC6d=p9YB7*bd0v|mHJlNfT%05g4du*Hoy}1#9n>5J-Yw15z&T3R zbQI?(?q`6(4b>G7CeI89=@rE}q7&ZSKY>KH#AqoorA9&9!CLbdu7kB^qkpZnW)0V7 z0i3f_(E>R6wapq~WN6aAL5(ntuSnW;NoJPtQmF;7TP2&b0M6RKU;+Hx&LOBdR0<@b zVBfLBF^~@&WB$AwmN6`$gbCx_+&F&izV>}v{bt{NU4o%F$GscACH`=(@yL>u(b)%& zfS8LyV}Jin8!mk(H7?Vj6~~jh7@=nJ1OyvM0@I$6FHaD2?kdnT(L6DUl}Wy0_FRy@ z(fDy%WwcFNyDAepqvbuJQ8Vu)GxwSxuR1W`b*bu&R;r6l31;Ornf7)(J2XDMuqVfCp3f5ig(nltU26n&#mG2 zPez%`<~|iW_vj_U(oe=c+Mq_Wz1Gk2&Ni~TvDXPs{jkB;j0{iAGH&b*6z z5k@{fGU`vAZ|)%OQ90^e-$%NL59(5H;8c8a-@wUnTy}VmJ}A#U@IeKT&gaJN$mY~9 z3P%8wW@UhF$k;^N=;>6FOF`WOT*()-CsL2srPd9FK$_VAf%-e!4S{5276KJ{W?=B51aAx58`L;hPPxWt9a)G~$F?V~9SM_NTky+!su zrG-;~1z10;@eoALU8od!jJto~PRZ)fPpoGyznk{168|pWvE)Ca7o~Qy7}Wf;JndIB z+{q+z4v(--$kz>Ai=h1RhKgbN@l;k|Apehl{Ey`y=Z@&lKfbj3lja{suKZ;A$A5l$ zApe;CzT+Rux7$Mg5vP*e0VDr^%0Irj*Z% zc3Q2>P|6oc2D^H#BnTet!j{XiF7u*1)y?o~m62YP%#vK7ZcIZcazaHhZW!OUNg_S0 z4kn4ndTm05Vy{Dqd{`RL@e?dhTp>@CaV41yz6ck^Xl~q9!H9{PXU*g}Q8r@C^!6a? zoxtL>Bw6#6cfHI5b!-roU3B7bb+ja^5MJGyR(G^Pu#F2psxY(Az3L8FG%?_ZWr(>S z#5sf|JK|d}Y^|94t|EeiSgCP0JX;iVl^>>5%#}K_SuytuK-L`H@8)W^H4-aY$D(e! z7y|W#18AS$1B$$Hc**NbG0LeNgTWNrvh^{uT$Ia_HP3r(x3doEQ?u%~b0d3&<%3b| z0{boeRbEhS*hvs=xS7AR8q-08b*bg}5ZZKWA_>4q9|NpaK);6N53?1KPwIkCVwvS` zb^Xgw^0oXBMgM}m9Qrsf<=uwf`ctl2p6=^?HF(TT_~<>SU;Fe?5`ynU^AZY~BAMIy z14R&c^hG48i)V^ZoXR$p3?g{@MIW-p1_Wc2GZV@|o_G6$B-cw@(i<-E<8DlkQBE_{ zGBoAfE?`4`wugs;3$%2su`0Mw z^3eeKRfujE5vFdy^|n~fEfF-XEZ@eJJtUD@E;q$^%@;dRT|kaS7I>|X^R7&NilOcM zS3jnJ43gx7q~n*7-_g3Q{?p_16nY-3dHkv!Gy@{t434r@-VL>stH{vh%iN%!=)F<) z^=tNZ!*?A!VH(n7te%zL4cmu5REDhLe5gLdm!U%oMturOs1U(hD$DNl>c*PBfA!-A zG>X1|^+N`9W6j5~5Vq<3?qCFYSxK~>^!=+JKA?B4|GX(TZQ;%1xGDC}z-a4+)Axec ztQiZX2xC(*9$|7Kl{-C=+IX6oGlXB$?QAJU87LM3(7Eht$KV@mW?^TAa+2EdDC)<vbs+ASbK6RG>%`r0iXp^5vxb_++i*e)#^;XGB_Hu{%41F6Hm6GS6)aHWO9l#jQ7 zfr(IZjlsyxkw6&1;_8kguCJI+A?ZT7k_>0*(c7XOWKi#fJxijQtNpE(S47;Pkknoe zJ7&)!R7KV{_Ir{n04E(nkhs1Kb{n%gc#K*T_Y;?QnaEWZn z%A(q#pHO~km54rgZFaWsxR~!Xc&-|zhib4h-eI+}PlY{G@f3j9mLD7-ifBk<;39-Z z`z=`wClwSt+jbVXJ!DnCt;@TAMdxeVm>*VX{``zV`PD zA_LtR!@l<+KTj*+f_+|cx}SqjNuUa`pS%bH?qXr?Y@kdM-%eODai7dRU`i_Nq%JP_ zH6>GHRc)|WO%Ep#uBRX#-H2fF{PanxbP^6x5K|Q_qm&(Kc7x3!~w+GS- z8T)4V^{Z<%J&>4V+P~{Ictx{E+x~qqib|na$tM3q*(&V|1?a3hFp^{CkihV8^A?Y3pCsiaf zW>y3u1;-M4%3>yn&lJRU(WHxHY9w#e#@V#q(J(8$oq4^vkpr$$mPL z>5g>v?sr0V@0S%VTQ3yAycc81Lrf#AM+NbCn=ini_&jbam#pE^=BKE!S~aGN33kC3 z<+*hqTF?D831y^J&)_XCs+04b|H?icaI`K1!({)6f5c90u^uWMuWurK&lFkxAo!;o zGN+#w&pdxhoWtirF{unAZVNaEX7A?YF~4~PGq9b-+_)Yhnx7?rS!B^RLBIuB*3da8 z;4Y9>#y+4<0wNxesW6bzP;|eS>UrtEYW-SpH(?C08@0n$Ax^UKoNOPJOFCKm7c|pBO*wjkhHCl&-xx# z4qzvr%?I`&U~H9q7SuDCeAeGti$vi)g2X*Whg~T$sMaLzL=W6z0s{9E7QdDa$l&oF z?r`^t$FR6K6N991`Rg_&eSaO{H!T|`D`g|U#S|EDT(iB~@}}s*1YvWxbx>?atTcOZ zWAn;C=(YX|o@L6~Z@6&$-b<@+k(3m1@2jseu1j{7nl~!Q@bJ1XGKhU{|DdLR^%h7C z8@E7e*!ZDfvJ#0ovz_={ZseN=mmYsY@S~%R_0fNCtfxiKKR2aaAq*)Jho6H_`1$4lc zsQnVz81ZQx9EI>W+h$mUmB)J@rp3#C4lO)@=0&fuie@L{GAALa5@kViiL%ZTG8E9v zFj8U_x%9q(-~u%{oDl0KdZQJnpW;0A9}o9aP&3;pEnEdi1&B(;2mDoA0P6e)fckv+ zNC?#7dIqXkB`WjVd>&G^z`V?M`3qV9jQ(-z$X1zk8nEUx&W_ZkWZTh593)KYYuB!v z0n2*tslu%YemC zIV`>xn#!vNv)+dBtI}coSJ^I2&$AWEM)?NkjTK5V3Fh zT@kS#;*GGj&u#)M8GzW^Zt9Olaz@v^IsmQ7@Ky(8^WTtN$LyVqqY&O{0q~`klFUZ% zyA?7W0>7zj;xUDQ-MqIo_M$fGE=B%)OtNBOzbB`&4ubzPw;2E3hT)l6w)Q#hfP{QQ z7Xx1BjoC}-`69OAkh`OYdk3%LJlTjBTiUv$VHfY<&cdCS{=Q~C>yBKDW%rC`M@2KM zqobBOKU@s&>)ac81@~{$CEUfcqi6k>wo$IbN66fC^B|rb#Z_l)~!?i3_+W&4Gp?L3>l(9`f z&ZKP;RgdR&=%euu_i$NaEG zG1`zAXs93C!Q8RfH}ca2$M$vXA|0te^~0I%73;juFI(rGv6TNk>%6H?@cTGVr|iI= zvHEkyF#VY_e4RI?n}=O`c=T{RJ$iUB-~w~w;{QAN-t^m#gKyLS9QY=F^GU<^8z{^F zhv17T26VkaLG|*nlY$U4(iOozUDhJ`qw12`aod8$vVqiPiH^sFB1!^%{bS!t@l|UV zVN{qySOCgJVz|ua3Sun_r*}u&PU?$!cQ1>Tt*A?_NZ>=Nt6JWBo6}!0O!sjBbVsZV zM^s0mvuB%R6%IOQ(s14JGE#SY7a09@hmn2MQgziPapn^FJ# z*Ii|?>@GTXtKr9j&J-9>p`|bvigHu0mbR$v+`}l4)?fezl4Q=Mi_A#`cC64In+rNQ z;?i{wmr?PRDg)xOW${59Dae6~7Zv|Bi~^4zP^-QC$>#rd>J8)_XH96*$oGZ<)K zc~D(2Tbsw%>+dST*ZQr+*SKZ%gZN@uElr<`$Y1m)Z~`r0e` ztft#ba?<$1^0Rb4aLH&4zQK4p3*RyR@-1&KQ~0j0ef;LyJH-d^_+*y+3UU5mI$m;h zlg|oI@>$^o2y$B(!$GP$yNfZ8TBLw6II>{dc0b{)ME08LuAc>Yu|Ko?{ou@Ue(&>+ zpPv;5E@&@(2_87!H+#>AE>@MTiVWA0?7E>}v$%Q4Otjn_9`&kRcBfUHt6tUrmpfPe zWz~{b@-MBt;^@ZOmsY;CGU9y8355+dA4T75_fRzFGA^MB^5C)CKQrTHCc0erwJW2s1zS%3cmzgj@R*)v&N zS+%cHFWV_1b(+L~2_u*NqN@z#I2kc^%nl}z(CNAirZkXVXnYJ$SP#b+P`cdiS@Lh% zgIFx6)lx#$l55q3k>y2UBw6*02_tU(jJ72tk1URrVYOS5K>V+(T3p&AFY`^t(tDpV zb^3iIG`LC;N0{hajAJbNxh-OjUBqj;XN^G|X&fn@fz7L1{!lLC95a7bcRvO)XnmIl z^@$y9b$xro!wyvqDTdUcNUwk$Bj5Dr$NqUxO@dDcK!~E|EjIXgH)wSS0H)^k)ABf{ zxx2NaVXP^6?#4@J^gSE;M=kSOwI5uH(%c_W$b#S0WE$Lv+kPgg|J_7t6K1qWdB9xK zMJaaCkx$Z7DRzxJ&Dkim&inpVd>vYnnelL#!a# zHzemD&HsHNuiftmupQ)?0x-~gTdSX zxBnQVeThE*`|S^uhXxz}VC_p3`sCXe|Em=cW@@c&0uomV5>xnJ10>qOEk~z5B#`iL z(oAH!;+?s2&}kwR$luJTKx_kX?OCQ_4Fu9Xir*dzK0oMv+~7lPBUZlkFx++Qwz^*C zu7jG5Uw=%0U;4=){ngCX~CZ-HksWbl$Bm@Q+bH_W4J{ zzl(SHjDt`6>u7$&!C(wzK-;+kUh1crIimOVGfm5nJJL%4GiGLVF)A>{Y~(U8eY=~c z5yRfZ414fm??+vjeOuYspe{2-8~(kk%&TOH8*G-Yz8J0Su-gNz>>S7Pq?I`<7wRSB zu&D`;Zy?(qFeKGfo;&_eMXe0}TV(#gWf0~+pcZSH(sIT!40!koUceH;g6RtOmB0Zp zo-Shi4*ySw7>6-#izHqWGK2u7p$#GGGGY_fkf6n|Ata#3fuwrV=J=_XnV}V^vz z{=!zXW_;lKA$jWu{l^=U$Lgw6^77nOSE3B+hfFb7$U1PL=_7&O2iem*Ux( zwaIM#1h49<`N`}Qf_`f!p&iBUsY`vaB9XnK+^cGAw^M^goJR9?+2bm+d&M&kPXJSx z9S$t1%bq+wl0_?QZ-=WPPm?V>p1FCFz0iIOWq^BM{(p@``Zvpj&8zcOj7a^}bus@z zy?byc4|q*c=Dc=~yPN6m7Pz}6ch_Nelbd;MvAdk>j!5AEoQ-(1ENY>7BWbj?RSRcR z*#jfF*mFh8Ydgkts`2vlYV!npT7FA%bEyrua~Rhhh1K5c`F}J z;bZUM$BG5VTERzVTETYZ#o&$&r=cc3R=A6Mm5uFQ?QOY*S-hHF-*CEnMBH9o zJhdXSfQrbFy)l`&y__cE7nOT2eFN^dE<#*dbXgf8P4xTQE*;hriY2ygGv*r zr*+sb6Qdc6vMmK=wlZ4%8gr` zST)1Ms(xl$mF5qnEAXrI%`Dh%^X0$OeI|`00wYdjOm&&H#?_PAwqVZLYH+^h*b;b3 z;im_jP`Wlev8~E68(E-Dc5DTH@}-A~;T-)GKe-)#|3F!B#-AhYNkF|BYS4Rx}LdNU3YloBTz2eNkCWDJ#;j@wBy_*%$Zo(6Z~dl zcR*z6#a7htSv{ZE)v&L$bnoD`1#VO29lSv|(PgbG8uo_u+ym?Bfa@$1*D;=>aLp(c z_s!nbKQnSsz%b%fu?d_vIu`o_$BhQ1iK@=F;h)aL?##ySbev=RMX@{S>aazzyNqW{ zzSA)bSY%9a4l|6uo$MG!?9OD{3~`G;8@D(}@1>T)uKturJv--vVeC=6`Wz5&_z!#p zY&gk~PiaM=WQ)Dm974?viX6uxWh5U73{p)JOYyIR7xfi^4J@^idnu{3!f9wu14>Dgcdw1{^pH04_uu-f|U(W5KqhdX* z2c!+V(~$o+?%v1$y2@lGR-XIuBSLm=vaxbfVC8j0W+1t`-~WfN{~W$XiLBNFx25=c zYWqKfuOEFJzLx#5h_5%_^uLF%D+kBdajOhp^^?1XZFF0XuiG2uj(&0_U#?U~w+LVV z@`uggYsq=ewK|K#&eyx%or6LA6j}A_BiX8Kbr2mAPt`=oI8SWe@&V^w_S@X{S31pJ zX2n4fJ;|@4Cm%but>G|b5vAtfWU)<29xObz?feRz1?bY5dGoXh4(ap6=W5<_sqRkf z3Lhh0lHSgRL@Bz`1zi4)s~{#yrRg;dC#U+mANlKVNtl!RUGyu#V|cWyEwWUh*W-N7LQGV%xG*UeInw zmWMdKi+#7F4sAU^FSSrh^?JYtHXrCC=|t}JhX*tl>|*ne=DJDDD9~Sm6;u26@88A` zgqwg463JG_vgI(aILb#NH9IPFxvm-gl`_}h2dUtn{ zDy1ztY)sp(Gtn9{u?5-Kg2Lh|p_#??A-A|L@E6yHk*o;|v?i1+us=B7XIKlgz@8H< zuu8CO@p9|yQVZj$r=p`iFcc$bRR(J14?wWn?fHkxqO5NSDcbl;f&h0=jn=wdS7u`m z*^1h*XJo<7_QANjo-@YrpZw$!|0%|?K*ImabQmdP;Q4lv6C4^Q!3r!w71=HVC3bMV zc#X0nCC*>2f^EF-zsc+N=!Qi+Y8!rEB?T=XjddDUU6-XDF?_Wn(L?wgs|`*5_q4^n z_r^uBd$s1;5%sLP0;5*ldkeDq3(qo)UEodmqac!gX#69j#iD;uls5eV-W*$Y-2;PlQEO2L-fj8UY=NwM5-I5k4mOK?;@55o-&$V z?IMyz*acx!8g?L!B48H8Q5~j%7%FwmH0qDkD-}WoDny??K!T_PQb-#8f-jAlTD-5a zG}L>Q@<2LUTajULWP~)>F$kVgV4VXdUWMCd&Fpcm&>c{{O&lli2HJFlm0F*hcV7ht z3{q+=RVIz>h=p^5_4sP!M{Fal6(gC8L?%aa3@M7pj`#yru6iW!S%gwK0Nn$0Fo2@N zNc(I0J@8hTB=CkmP7Sobk-BlnWanY{>~YC6VAH|{d^47Bf|gBb@+x0QWb$er$&({9 z{j>r>53El*cKzp6p&o!mYfW%02z3SgaCV@@g25rNY?XkmG~aTS&)0xBjC=z3<}Sa- z3g%VRQ-Hn4$BnqXey^D}eIz;xl2lDocr>wI2A*T(D;l$xk6SY-*FCX;1*9t7KQ2MI zg+uL?n`6(8mY&f{uo3M#rtMUcE!I5l^6V>#tdCc5F4qK1mz7p3veN9gR$R{&-_E^D zH7b{nI4$6^a!}4CBWbt*6V7?-yRqQ>gbyN_4_WC zfzB`T4(?~ZkyE~CzL}!n0qJ@Q9+=Os1rKOmL1F=+1c`Or%9p6raXcktF4!|8nRSuO zru>!1}ABjHK&?En`Ly%)(Xw3rqHz5@yzL08Nb<0oJA^7FA?ahojaJ6 zI9cW=VyF0n*(rX4d1NAHia(f{;s?5mI*XGRU71H_>!<#;hvexw@64yi;ue(}_eeS; zZqZDkg0;)JH*O&`7m?S9{v*SaDQp`Jw$A9YJ$TJn0{kK11S%g-c|3KvztXIpIGJoq zt0yM?Jxho=M*3n2JIaFF6|4EPle)wV))eSIS}{XJ|1)YcqW>iqEHX2+$fyw0;wd8U z)~AOe?+@vI33zhrh~W?4UqsNNu? zH)^O_=FEk)jCB}`ZqSf*hL?;IREh`ZMwt#RJrOJo{>9@N0jZDF4V{C|Ppz0yAo2&E zgvjsxExl7(r@~6+E`*ElRQwy`NJ|x(6VoS zYa8(y*K%)b34}}J6>>clls^}GhXNSO?jOre2+o#635;aXK3Xe!7}{3qgF=WQ^n0fc zj@D0-NFvMeEv6)yP53b?Qu9|!Zr>Mdcan%wPzFnM`=p_cGiCsI!&Qiy<$8jX!wmqgWPs4MwO`aMj+hQ3($fL;Lo;Bg0y7H!8BWgF2FSG!wB@?$^Ox|{$*(Ry;2`rVjRx>Whr==&bbWh>w-$6*n`(V8_n?R`xE zUxdw%1Fv#B8hBseA^@)nkvG2$h~5695QumArGXeBES`GKDIrH)*;OWc4y3)>7sDQ= z1|W+G+rdS06cLiG7DN}o{1;0k7O()AX=h{ZeXwT$;2r-3{AW7wzYcJ)@09xfBrXcO z@~0U1Yb_mOSbwo}V&c~%EA!z$iq><(!L{COKlnFG9x3U#I@!PX7xKNd-=hs5$!+1| zMm%KAyN5o>2ozZJw%COC1Rut#*Z3wMer57`^w_o;2Ps>>igm&Z=j4WoTyS=az#22{ zd{{K?Xv3|Pi#vG5zZS@1?0-uy+m)k6SYO+;ZYGQqb-fkUySfq>a=^F|@_foIHX8{)hd{hWIo||6N z)D)t`xj!@bh`FYo7Id;B?rU0yRkPJO{G> z#ooKXSyh$)|1$~-Ds99YUdl1YuTW}?Suu$@N9WiXI|CzvVxpo)jZ72$&eUL_gEM0s zkE5gEH@jF^*4N6?N(~EghEW0W0@wv470vP-M@mtVi#q@J=UIF2v(K3sE=s@p|98+dUS@_<3iOZ@WoGE0pHfA%5T=T(;i8vS)!!cJI=wojwG{ES$CZi|XtRN~&oa)~LmSnj$54DnY8E zc~#npHC;vk$rUP!?UPDeEbE!`dJ_#umz^pT!KmAjFAt!LQcVa+Re)O5c>zr&)JaI( z1nN}rdWq9iM(ffvl|Vs>JJUp5^gXHQ$?ppdcBG2_)WT3B``B#&-Jw8Pem?dS1Rk; zhYRhG;K$bV^}%#FI{-l)gOG?NW$xS$1yU ztW5ec+l}a;e9V;0R<|Rl=C&i&m`v)84aIg-;gh1wzow2+=HGAuJevBY!oId38m2+7 zF9tB2PfNshv&iHI5y0`cN()D1UyCTAvJZRQ(;`7sv(gHd6?U|#)we+))Rk_s41)(VOk%qI&N%!qAe zF!XZze%SATr~=TD8MbemulSu$R#s;>-{KgGS@w>)IFu@0po>m|YB8I7ZF)^Yk_Fa1 zId}v{UTG-v7NAv{odAH+hP=$ZfBiP_ArDMQ)mH)3_s&7oZ3$f_X^Fms=3cp#`SRvA z@Q>Vl!1qCL$xf>`!y)MkF>){SMm!;Cwhu8L(Zw#r_%X?bg8`wj^gKzWk_8M?{&y)ANK~|p#eLX8Zqqp4 zVwwY5KE=`UF4El(@7#QF^IzX??i$E0RI>ZwD1WuDRIF`X-FR!Cyy$KS-JQMtD-$Cf zFUl_YA2FiGjS)$A-T1|T44uHD*i=c!>4O<~HfvakpUXZ7*cJEN^hf4jZ=0y`9L?S87T{WADcQNA|V}XCR_c5 zt_Ov#1-9({#h*ydQ}9W3`r%Wn$x`b=P?DJ{j-Q)W<%gi)*gRzt41)lN%)sXXTcS`# zC<>)Eb5U7s>SSQIgqRcbL_Y{+p5jipa}g)=6mi1cB%^Bc6llWT6nCfS5@(ih<_Dfk zbx#y&5-~yWzy+Pmb3rEy8eKIPbTYFkk(uX$PG-)wgC~9q4X}eJ&gH`LlX4spo0ps( z&JlO#V4ErkK-r`DrBd^0=qCnceeW2QdHMoN+_I31^t$vj=_kWTl=K^7BlwT)!ZYOB zmUpe8CEe7~rrd1N2(w@Fk68_9Q-J z7VVF5(Kg`Y?9g&7b;T6=P=(*4!r;C$G?kEk>JA-9oN*-z^u*eZ8FUk>PbG*T<{@2SBX z1>0k~or>KHIDM*N{|CT@lH5&%ndtVQ2f!kB^QC`Npi_w#wavJyCwCbY@+D&yupB+P zAts)+2&f#xDvXaIGDe|2>6=ALvR}F$MphgjLlBUvWUNYVD%}cX0J9$}Ke-8AM)+^x zGZyWVQg+l!FdDmHmkJT#=>v?Yz6lf>QB___VrJ*@Q*u9_K#U&Oacq3jJe*@oys@3F z>+jdLlULn|ob8SmsqQ55MJI}MFbTZt&3>7;v9!THYO4}yxp>y3-bkctu`6W5qkb$h zCM`E7-fdB`NWD9!(`%W?wIs11LZ;JYqHqy1i(80q`?%F!>&-rrPl_apDz^<7wxwv7 zT0h!_*X0geK=XDf%SR8KuV|MSEZXH`v|gK9Mttu=e0Vt$o-|(@%uV=)z12i!pPvJp zE+z%*xdgL11$irE2>a?J$;(WDvqf?NJnByIFv?@0RN~x@Xx@CG*YZ~y#5B4F<`@R5 zK&t#emBW5*q)I>8^eo@;zu{w&9IpjHx(^HBmmn3E2V$ilm0*KVZ~gTKqf|j)(Mn`v zd7Yod=|=g*CQWW+t+m4bVzcaYOv`RjPOPy^&B~-9nD--Ny3?|M?6dJ~@Kq_jyq2eU zXrtRl)5Tb;G&hK`U?tgW00?HwpOGp}S;FilHY+Yd=(-sLOLEg86>OTrl z{TVH60jeibZwl2DsSSBlm*;&tK~L+u(WmF%bxA4>7%g6N9+}jfO?|NVB zyWWH8w^F+R(+@f*?{*)-^nLor^xf1%W}hygx_?ZUy1xyW&g#2Jw7i49kKpxp8G`F4 zdk3k!%|XB6C?WVyfTHg5K%b9m6IJ+)JNzKK8ghnS+8G-Jl1K-EgUi@_T4VUVCG2KR z`#|n{jDY{0hK1ZG7>Jt#e)o0eKgLY#e`bi^FYr79!7KYkYcq#L(7N?&(ViWvug52+{0pYX78fdWE zvJD=~z17BBfX~lfQ-IG)h0plY#1-ow*Iupd%+GpRc4s+sR{=Ww$kj6N^OpKI)$W~t za^{{ww{Icq@rl%(<&9MG9lEt!tIb;D)Z%!Cy(_3-J48Arv zPG{rkH)83BG3i|A15GtwrUl2x^ts;&d*$=jwS%CPgn$(}1=k>{x*!oW0ZtvBk9;?m_ zS2~S4T8VK&jo0#J-WTK|&9sz@h9y|DY4$tc9PcG!PI9o_Ht?;V$&So{0CIPp;yYyH zK`iD5fiNRl-V?h~+pJ4~s_r8K{C4xrP{8pb@9QSo&K@{hc)lIZ?K;sIjl%~OU_@KR zz(}<}R|P;KJn0ik{3vIjBy_`KX?sD*+QttELR!}f|MnC96?m6>t%oC0Mm)@O`*Dx) z;es=;h`xloopXS#)(j>y!+U$dX2Tul{=8sqX|NSW&7$9s7p#228|}REczRtt{c^5R z_}f-pUhEK}7II5?X!?TO`5jaR7AQGsO`;CamDZu>?E8fI2&D}i;GE*?C6?>{K)2Va zqc^n}mzj_CnLW8vsSps7*3wHo{a#WE)+x86v_F}@pMnfWXkL@7nz~0f6=QkW6UCK*2 zTx6?Csr`JCB_?bnOSvCRacbT)-40vWbVZ;kfoh?{`5vNHibAPA_I7in&O4sJ5JH@G zw88GP)ix{Davm4{E<{>!qar|xcoL!cEYs9?Y{_xFRX}Ktu!1cUn*UYvC>`z8)z+ry zxldtwvcGH6{=s8J$6GwQ?>ibeV`wr*QC-5VxnCd<2L^U6DU@fZJw`3ilR^GX8H;`H z9Wq01(2nK*TrJy#@2_+*-GNv{UAXt9YWCG;QHp;20XO%A9Lw1%JDt9 z3&j$H9q68(hHvSHE|qlO;L|H`_a_s<-KQAy7M#~tZWV29R*KNpIj`$n+R%Pt@vvP{ zOw^0Hnba|UZOba$A39Qd%apH{8hjiGmyb|p-EOI?8IJioj{_ohocPc=3HK162VQRCr7Je3%q%na-~#obDS=eEp$I@jI4>Oa*|nrJYWnJ_&2EEkr%#NpX` zx1{(`f29XE5)=C@H;?L_@?%b~#+3%reAC?(G&Gz$&ASi;iFd{pL7 zZ3GL&_V{sswoZxo1-8ygE7&rMNr^QR=U=ES@n15ik7Mhzr_VIsr(~*jG#>bY^HYo} zEFM}nWH5-)fa4}2&QDb$kA`@#b9cCp+nVp0@cJ}u(~Y?b%o>@e=K^^8QjA|e0>5qq z)5VFk^z#4e;Me@W3^WRJcZBfE$=pJ<27pnQLN)Vk&x!DhUk2EQzi1}Jw*2|PvGfKu znuJYte6B>nRQW)Wgo+ea#p5bnS8URyaY8?$Dh#BWh{$5GQ!ZpGcai%(AYC~ww7317 zLI78;R7|Vwc2?;?6ki^S2NKQszJmj9R07@HuXxYdb9;HPP0D@3J#0}2OL}enqmK7@ z={>2_tz47Z@+QM9BA1ZB!2Ar>*}%Mv3uCnca~-*~=?b5<23oC&wr0U{4!%m=vfhGa zAChg$?Pe!UIf&B&hM${=Bj*V@Gsz1O1XSuum1dCdT{+Q)9h zO;*Nb!_EHa3V)B#CF})b+yi&C)}mTwe5i=O;j%0zf1p_>Q^E!2a^sCy%6eJcg{D}~ z#1tO=fxp+x?yJr)oiPK{XeK)@2VeO7AxU+E-@MECS9mMCTv+5+&BG_N2z*LC%1`Kl zJ-MG!5VVIttf^}F8L%bMzNGuM@O{}=B1vc@Dj7sP=f7V(CQ}S0Z$t;RAKlY#@<&;t zh^(SZ)3K82$AO9mne1%egC!u*>riRk%^vpDxHQf8k ziG!%8<_e^OP>$OZeYUh7wRTLp}@B&Q_K7ZOh+_$zSySfi)E_TkSx zkGRyj8IdU8PL=KlG%+TWY0`+LGUqYdW4O+rJAYEutS@X!SZf>D`F%HWmP%kDjTyYk zUthjmwiC-XtS~%~`2vwz>ZioM0#Uj$k(%!d-pFuHwg^QKBZN)7Vo*Jji@u>+UZaQ@ z=D)KWVzqdx`Q(`k&pB#9V4LD15T0M4Is~mn23~RYix^hl!gCdG6$sCYq3-1|U9^k& zU79t{eiM}i?icZEU@q{U*&xnNT%A1n?oNb^=o%^o3nQ{`t~Uz1#L^MS$XbJ$-$Nk+ z%1f+{LUrKx&IKozo$^&6`CtI14~|~Wi`fT2u5FW;LwaYh?X}EdxeMqe9&-V`4E;CT z^l3U)(%l@s&oIAuGV=3#4*s-R;RB;--!MP)1`=lvzgOr>A@ZyjbIN$-^vAqo(gybjW>>3d-D5ETTPtzazK9=0-$oe!I3dnlE-(8x018YIE zfweHuxY18l0&{O2&V{5-fdgYz_QM|Yq&F)3Axa~3Ho~nRq9r56^SQv6h$wxLi2^;M zokt@+yOnwQ=h6gBTXSO}S889xMO^!|?`kGq5yM_u zpXb6({_BHZ??V0TAz#VY4A)bX^;qVnemBhrpD*ct5Pv0!eQtJCq@kykv_+-j-raKp zdQRPgg1Qy!t>XP!=Rf-TodnES^P0C~%^d@)>3uSHp6G07@6fy0R@^7F+uZ#fn#=`F z(qQAYE|21QH0%6h=ThIMh3P3~{gc0AGn13N@b3A&bPfZdAzbuJ85LqS2%;Fo7`k|4 z&B1K3Pos>LTm%e#u|Lk1KXDNOwEh_ST~rf=8$lal=psrXgmv&x6fZNa4~BltG;N%SG(>{1I)cA3}U9 z=oj;DemM5#GiGFsHE+07>IlDBTYpAP0_V{ms8;wJ%X6sagreiM*9>at$7ZN8^lJ~*5AAW@j6`%P)!g#n z@`g`28|>xW>w6-CmS5^x-7%1o?k3}ZR{3Bf8M!!>Z5hpC>lUfJJ{wU;G~@ z^>y$?rdAfxdH~s1ZUZ>8_3azjuAzZ!=a+lELcVdPSGH<5%X1#Gz-1rSe#i<2a}KOY z1~l+F*1=kf7B~PlX2RD?FL?V*L80L72(=shD~Jcq++IGHDS(QJ zd>Ppi{WYjLjEj(J?e5#2ZhkmQv-S#T*4L@))AOy7uDA2iz+$D6>=O%%NR*4%meUVN5G2ODZcLPwdr&!vR<29wVLasWy`@R}7H!($^yV?qsg0L^5-e{oS=;6wI2 z;3I0wvuT7Db+Awo_>fnA6h0IHY3Iv|7%?*qZTd7lkLm|edL+5I7kr#qP$>AQp(Ia_ z+6Lz4I1^EsD3MJ=eg<+I)rrWzC_F)h=F*!eILUru;3VOGE8w(u08Ue>8_1j62~UVm z{eY9yQv;_r)kOoR=~q&{rHy-Y5bqV}t+AJ`4-x}p_xyt3h>&wY2?i%_=hKtZHDfL< zK+$|jnA#us+XjeP_YENCl8cJ!ZV6u2uoe+`S3%|Wf>WrM!0;{(E@_*}d{bT0ZN;fW*tfK)S1YN^x zbg^2@Xnlkk>Dp&TF5f4V!xzPM8|g(*L^w0iJ6 z)q~d)T&YodEzj9N1`ekC)lRmnWiJJFmLvkBrT=4Cd8LnJqqp1$`m_!C7C+g)ObU{X zw!Q;o{Q<8gxOCebSeZ8lAuBI3}UkAU2U>CC{hG24W zUBLe>NO>W@{wDRdkzZpERHGq!DWNVNK_YV@ibZ6-0#(ED@!fdeWId&p4fwbbU5tjZ z?)4pHCyB&_JU5?n&UKO=Nj2fgdGafkJ+Iv-zwS8kB>N(Lkl~wBMWi*5@A}~0C(&Z| zx$}Fy0Q_x1zPp>Xj?iQAYXcu&zLTnvr^mj0=lFNu^4%0($dg`QpZHusq3Cg?+714N z{@mIJd*Kxf$Q?|i_AYfID2FAdhH_Kowwm#UZxj!!q6kM2m&8K_+Q6Hti#jfd02D5LAlrXY)|mszTm_knj=S@>;Z^SFt3!?>XgWz`=;K zWL?7hh|QbQ&^~?4!crC3d2T~9SC?Sh^6t8N06*)zGdfj2bMhX^)X4)>%b5ccsqur_ z26Vo;yry*HA&V2Ys3PZu4!Q9LB+t^tiPB{kdLLWtT|JB5B=CJQF@$~~i0D?bsQwLp zCeg+zn40D?NHES6F3X=74V+`(3D-++G@Ic!rx-8E`*7#!AIWa&Y~tluZ>CY3eTmn} zbf?X}?<^s61e38o{YvwiQhVhTUQz9qGwou0!^b!d=BwQk$DHW3p0DOuODeFc(}S8H z0alwfjjykmM+wiU`BAQz>Q)J8`lMdU`)g9!YkkrlEw4@g(P>KmggE;2%bqLJoL9r= z;sbg6(ijm`*1ErR=NqpB*_ z;KuRyiq#bzHm&qeqpYB7^fPw^zYM?O7+@UmcB9^p!iv>QBIl)Pv=ys!11J(8s`=c@ zIDqlAoTp?B&HasAjybWd_+aKVr7e%@!O|X^3|W1y?%|lZjI~2~{9Vc==AoSrSHs$o(!qmRneu^M|to)z4)UGymyMJcg=1JH_gBj zQ!fQt5}86$;FAC$eiVbFM8F|F(AIsV68pMv2$7*eC|jZup?&jGj_fkbU)>AyXJ^b} zB-!cK$%gr^>yn=|Va%E~cbTo(G#C00MQ4qHyVc>;1!mB@VIY!C?p}aU<2QuzlT8`} zlQ&sj_sw1lLjCZp$d~i;7F(a*Sd-~NeA15jC;;F4r> z!;-0^04X+)8W>Wtysl}po=zh19HY9ke6A)dMZ#-=b$xkb+kdZ7wMo>e^Ts_BYrA}n z^3wr{HEHAuN1Zum;!p6&wrOj|O!3A&9OI>!+6`fhbDFL*K&9q0O`DTmi{^t<3O0{- zvZr%VJRVFQGq&DO$^%3DqsE|9C^iSDP;6FiJO31lK6Bf}TOAI^jP=!c)qi4L65hDZ zn#zaf?M{0!*?d>TY^iFzu`6mSm;crRufz&FoPd^CsKtaKh1NJB0lT_Dykm55^( zk-`LsXN#N(5Y{Z~iVA5?n6RYb&|XT3vSI%hRUB>JpXG#OzHmB*VbmTz#qZvqbUU=a z5O8M(Wo9`(IZJ#pa|-;iWSB?EzKRWERi~8P~w&VA$+04yUU%P&2eHqe9OCD zJOOl>{}Fj(A0VNmgOVC^!S3QJy|MGJ0|b`{Hj~RocRpv~R-=e-9=u9WFk;q{orX&I z^jaUKdiCJH!!v&|dqF9uRDw~}gZ~6mO=JeZKtZ$Y>oshh{v#jW4{9 zZ%qIHukfvYLSOjy8L(r=;#>0Y9f@yeUz3N?LVRmE$>G~yCT=&r<%p5amP3Db1isCu zv2DY*o2VJkj$Zh7L3IS*@_bF0Zc-OEGZVnhQi5HC94FjlCe|T_!Hwh^j#PG5qBeD4 zGX1b~4wgj4%T-C`>YI#|cE%dc%dAZeYnx=et4oZki7!;FmTu>Gz4M#U(K#l-C4B)- z3fYCw97MPYfr}|5-y}%w27(OZI%+Dr=IzEca#`yNQ_BmQbWR z`P7JDlh^0_7l)?vZgvj%8ICZK`cuVvI}*X@{oV9H^xnxsN@r0h59Q%Slcg-XHK{?h zDIAw-(a6u5ikx02K_-zVZyBsY5>g^{ERWdBc0wLdPfr2F4N2_K)xp2li^qX0Fx2%r!j44|Ai zBRM8fxyVHQVmT&eQcO+dlQGlpm*)YjBT(uk)JTBG-VcLLn)LE2_Xc2Za1lr^DwN<7 z1+Z*<9Lr(y`hkaS6}V)I(!W0C^;El&8v@jS5Wkha>G1RPtok8P3PEetYAL9nEihj#sZYW=}`?4{6Uf z@Y@%^1_b^9j0#`cVf@yjo7h#6`74q6uGu@02GuF##valljzNfXf*RRbVr}Ei#)T-i zq9(N`miZR>y28)LjK>GDBlhM>gf@hK#mjMpol3SQcc3MPot6i=Yh7`beL!}j)+O#* zq8BGPBGo@&R~xvJ*~OQ-(kf+tWWj+8OC|Qyrgm1ZWZzZ1BO(nO!a8OwwX;UybQ3w? zP*|ptCTbE*aHhh7_wri)#%)|XGo{$t`0mbL%VF*ciRu>m-qSw!0~lq`V+`ym$Ysc# zyeQ+;7$zoGxx07WKWU|MubDO&iAGF=ZP^A(N>6)RaisAeL!EjBYx;PCHB|@{u~IFR z^A(%D)56)CuQJn(Vti>&wJd|2E5cu!3_aY^nYJH0V`@?zu}qqt`8#NkN_p%CY0jg~ zI>}S}Gw1~jGIs^z3BIrKov5z|lV8gqMFCG&b$QEq^{r@!OtuZUTyCav#UdXYOY zZ_l#%Yx!Swz@>At4VIHMgO*23^Vs$&Zu27(DCEkm`6{|NRbBkEwOFk#H|bufG;DmX z74`bZ*t-gP?H=Xipp@tDe9x^{Fs|S6xTn35M%_ZVWu_soZ7z@U-2yyHEEK4x{T6kh zTJ5&?w9nSfr?|2H^t4aY{o&ke*7l@RdF6{Mmv6c71S=hJt8L9B-j~wIl;B|{zkGW# zo$Imf&IE2yYbcCo2BYY3fH4YMoO8%=lFCwyU0uldbCwQ^;CS!mt~Xa3D1C^28y;#u z%o&umPH*WQ?DrsnA>d>oBd+J}#$h8vvU;WhNuvZAm3=v_mr0yblJP1RdoBC(#Jm0= z{k>~(BDEyZ`P|Ogdq_@NlkQ-z!)uvD+sTxNDYYgw(U6t>;190bk9?1*J<1cAou!pvf0dd3RFnxFIY|dH&KjWGq^Jlzki9a{FXAM{!zS|o8nMQ4meoy0W zjjAiXnR^KU4BO48$>7U&P^&BBC0<*MW>muvUTLu0dNM-}-!((>mvS?7DpwBQqcik9 zKBy^K%2Rz(q|82v4cTHKg8SSb>;rTY;Mru|6le;Re#?{GJpj7CZ~KK`u<6!w!}bIh z&f`V1-d4$N(5&wWV`tg;_#=F`E>2{(Z;$e1X7?m;$HpNvp8aq0z$JUx(0wL0U`nHO zgdnGk)JA&K)ooTDb+$0`=U(N`eCYmC)}to17%Tr*_E}hJmi@OGiJv(QUV+^U(2GEw z;H|Y%qv^SEv-p}f)o)LzO3?dZQXdk(?KZO{K9pD}_ml+YPd3}} zMV(8TXst|6txFJTmYZjaOL!cwB&Eb~+jH^8E{at?6*H$0B6DRQn%uggacb+5#%Ycu za$dla`nuK?^+{xu{rAG8o$>ebq0opRY>u+I4A7p0{J}9MN>j3n1Qwm(Y33LrJOy`? zjM@$DX`jacVMt0L-K9m_F{JV)mEu7A#R2lWXj zT)E0}g%`K-yZS!gl>dWr%Q?4^3sQReo_&w9t7K9AfoETB<@14OU$U|@@a#+EL)!`{ z!|KQ;fb;D8sfMfVCP{ISdy5-s<~q^Lne-)I%k}DZ zcE;u-b@bT$$Gou*)>bZz**+heFYNg}nO}m?jYO*<1%%BPtp*?P_hH6VSN@f(f`}9X zNIr)^_4oc9@8(_%;(o2Npzi=2dsj0ZeAbeG_$;82Q_ux`RStM3PLU6=L97p-zF%bk zpP`2;yPoX^xDGzaYv;9eQvet?oaUf)5Blh!RiF?~4%a2QXBY<0F85jw;NIR=ynwm$ z86@ApU2S@$&1X)YeHSW!o7eg^_aa|gOAXh&AdsC}H}{&D+*Q=d+cV{W{o80pY~ z$8R$+JgQFrRXyE>(m>$uy?+Ujf$U5)iX%=6f1HzdXs5tfs|#;Bim5Tyx=~Z4d78DU zjlbFqpS9_FuFS9#OsSIE5G%7m@wY@$!b?Xvd*J=@cZDVYmLc^xejK>T;&%Z-_L9qC z)sxUl#w1b`6ADrK0g#)>%&ZHzvAh}_wNq;0%*-lL$wW=%;=C^`wAyqooH>>xDwn$l zGDq;Bz(3YYmopfVa05QkCfSPunl9tYFx_axcD#<0JutK6y+C)G3U$Br<3`={{->H3 zn;|cpp}>WhiJ5Mv``QG#G-u3-8BCo=uvsMOD^tLZI9!2&bjq{1u?C*yB^MKyG>LNN zsMhAFiVkXy0`E=DRqr`UR(9m)DB5S90qkQkwX?&b8+cBD!=7+^MI}HiiqavU!PtG_m<|j+?G(O(8Z-oC0lcG zx%|R#%k2xJBCF;=DUkSr#9I!=06t)h`SY$9yAnu9D9?3q;`8Uk^)_CB5Wq!^PEaKomXkP=>3eMJ!hy8c5(8T*dK}_| z;)~vVHod9&`BEbc2Hm?`IL{SE6hsL&URv+@#9<=>^K*Ow&N6G}C>a|S52@>Bu0uy* z0$hZ2wO;j;Z0`Z2%M+E$jBJ=gupM#lswD9TuC4rI-XD1V*8G7Z@sZ4x0km>9m_M)* z@&nnHYgV{QH3F!Ck)pFM06Nui`$-B9Dp<{!8cIcN6s(G5FQI5AYv&r#AHh zezT9H0zbZ!GXvJ>owDru4?1teu}6{@0z+6y10Z^;Um$X) zCIduI)mA=jS&&VhjQR&L!38eLOfB{Ih(Q@w|7b>W2HRvF1nR4E@Hr!J@Lr z`E`B#0NgSUrG7|I`uB%^pPu}i>B)_U7t@n--tOGN^yHFFJDi?;drAO$dAR%W{*Io! zGh!R*$tP$eTlbOw7wO68&-o9eCl8$+ENTHgxpLoL^rR+*g!;GMCOc#g%y68$B6G(S zu^Ge;VzcCuTbq7LHjE}nxyp!}J8N{pmo-!{g#v`9`M&6a@3%=R^0zffMf-UsbST%z zZZ6NDHkjcY*Z@}X)R}y^N9uTjdr5B6J!(_SVIJ%P8x=;pSeB^#vu%it(e7#77e6Fh zBrE^q9ykSJbzV5;^?ZOGsR6LX#nm<0?Q6IoC$u8$(u*}dZ8$4Gnu!d*I205oe~%re zI%}h_dwU}3UR5}45ID5YZR>g8kEE0MQYaI9D%qM${LWdvO#Ev0)WZz<0vlW4f1!z^ z_cRsNeSXY)+1viB;0@m%vs!BsNj`j_)O1$m3S*5MrZvesI}$%WUj;!ExubbGxN&QqJGh{|-tzT7c^>Uk=p?>kUhVAuK%Vy(owkYv^_pG)o76YFoQD4zLAUm zAzP7QQOJISdq!`bQN1C%rt*&lz)30Jg^=w)-aK~#FgHJ)T5>^#u22D(C#54hFh5)U z6qujK1z?^On9Fy`z+4_37@L=r0T%}0-xq{#8N%oBj{f;tUm=7)@LDH!y|;>-&trrC zfcN++A8!u&soVfc%Q#IT>XAETk~Oq>-=t%rdWLx4&-x2 z??eZ(w}Q}!!1=m;oL>_CCJSO(lCOOO*fp&~M z#zxA2kUaJw^y5$-dsQ&AWo}gjbA{Y$&$W4&dzbRqmnVkuSl59DbK545?aO=FJu%|I zi-I?{O&+`KKUW@0wp}nKAKJ1^3|NT}q*X{?NX?AMWSnrq!`?Dky=1ZmWU@d6dQ3A%sRU&w4lseuJAL4& z2@6WCIN7IO@+xhF(i?d2BKP{57;*p7TXlcZTeU3Ff%H}#RZ^<8bsb1=)p_Y{orWdp zO()SKy;VzkQ=v(3a;Qam+kHQv$fURDUfwD`Y*BhEeW`!x?Qi4zl-{1BGlkOIYAe|W z>Fwj5`u%D)BPlK_k!gwpjY6_*HRGfP!w-{Leu~~?S75U!c+u@I_ovUC;N-c>8qNyV z(3j`rdY#v2TwzcpcffYYYexYWlGhACeC0;xI7Y>_c8ixta`c#VkYs93`CNW^$;3m0 zVZ}pKbO?%X?s#*h?RaZ@*fx@%;TcbygTtIIuVn!<6|Y=%+@j*K~RL?D)7lR zt)O`m&?Jj2fdyX6FS*DhQ3{rLX;+9qE{iX4*78kSZr+3o@Bsj%A|Omh$_)G(P=Zw( zKiHboa$+aMcR=tUW_XkWa)bA931`(8MrQHrs-5 zh%H1zwAKL;9YO_*hRCm{&7aOow)uOUwr%p_l?!L?t!dZS+;kq?#AS)??!_xtde`5_ z(&v7{AI*j~4Qw{9V_G7!aY^ny&Bpb#27JgRSEgq6m&~z2ZVa}={ttEhksh0*|Dr4Y zyik*U+?KkOv4%Gu44l3+6NEco6x@ljyhI1@)q&=28b$&O%s_TFZ&z(Rwof{ly|mV zzYMFOe-jiSf4%|>$T2Fn>~qX5dq4LD%PGE+ago3s`g$_s;R@1Q$CaavNw~c==mHit ziJHpid!Oe%CwKl={Zq!FvlfV-lOvsz9}RR~q@l{!3~wwL!-!hNT5{J~{!guj5KuY2 zg;n_kOLZHBzNI8nr+b#hM$*Ny+$>Pb>^ z{ECL%(p7FYdh5bbY%yK^1^RY%<%{0+C(=gllOhQ^z2^nJY4dY~nbnH#>Ul_cQl2cuYva!_Q0Ac>x`*A4;(VSZqo5SDJ5_8xl zaj57k{@P`z;RmstWMj2>y)V&>!M|X(VfUVP3s+Hmk5F3$7OnCN3VPZtSmlTAnN_w} zm75}!EmUQeRklc#uW$)gKJZzv@}l-2Qsot{H0OiqQUI84-}>*H_>BE?)YyrcMs0f- znGJOX7YK*ufJIcw;);%Aue1D-95Tq2#63Gnv#q+L2e&3{lmxAKvv+3|c+H#r3Ki1J zIIS_3?g%KUa@P>W(m;iJOy>i~uIVJywj+^xL{#t$qk?-TmGfn|P7A!7>N0*p>RcXC z-Bjs`zOGkJ2;yD1_5+QmD%sfuzL@DW*7FTN++}K)7LBI?IU8h`L+(3?iMwrxBWGQH zvLJ8VBik@$hSK3@pLfKxvkcIAw-Ri`je%RXynesC(7SI%=kq(6i#w6J|HZ3~ zM>$uK2GabVHF^_OFDA=&1>%uU8hGOS)BHZ_#G5q|i(~pNt?me*Fg2B|# zn=8{h2QA?LSpQ3t$+8utP*RR}&kWr4&s(+Z7VUJbD)2lx{0|cUmBYC{7WF!*Ki=dg zb2};Af6g9r1s^A$Uz*8UmHqop<=7oeUO()D;PvhYoFMA|)qZusQ2?Z_ z;5#@T4YM?pq>@e&U`^V;F;lccER!twWDwN)H6~Mgs#ig-Xg#bWy#?~ATy7;77G*iU z%9bd|4k?MR24mEBJ380wTvNHk9TlJKB;liF6Y&y~bI0IX@6CRlH_iIKfeQp&#qG7K zFo8@rgx>=+@L0aM!4F_SGex;)0%(KtxQl$UWJaZu+mm>GM^*yEMP}cWh z*7xu~ZgGA4^tCv3MX;vWYH2;Xt{fw0C0ZPg9FtcO%ZuCTXO3G?8p+CUM@YSz9V9>t zyUTz=j~=OZGAr-Mn#1bz5wWV7XD6jHY5Xoo*(p==seXlMP3LjW*{vkS$JBJ~HDRjf)yC z98|dam0;K|e5Ci7Pt=&tW~KxR!dS+h)dJ%~UDW){0}`DZj&EM`PIJcqfm8Rrd3#mx z;fnRV)Oc-3L+bB#Kr!ZR0fmlo8202AfkG2og!FcLL+EaH^s)dz>Q9aWM?L#tePb;E za>=nKgfcqB&{y7}FZogSvz|V5MOKk^J`uFjeP4bpb*1(E52w%RPqWhXAg5M(3-tNM z&6*xN@0S(uw$Yik@LdV4#(Yu3vmF0~LKF)Eih z72c%u{a0F-TzPpi^TD}~($lt2oWWOOnFC|#u2^UH!DBNAJwqy) z`U|!AY>KzoDWzg|qiWOiMAnfuS{5^8SM8Del_efaAYO@bVC17!`lv2O+XZiwWq-6g zFf{8ybyPH}E8I`9ub9=e@JkR)+E1np1{1xTrTH>7AM1HC+OEN$J8LbG{?n<6^wPpp ze%SUG!zM4&zE1wK@sJ+?7HiDgs2(C&%(6Nsm`2Pp#`tCFY$W1Mj+|ob^R#77VqOj# zSbYBgt^;Y!OB&PWtewUf%{JCJX5CPuQB0wt7_|*)s%{*kreZ@1;Ace^(IoahT)WL4pKyG;f%w6R`QsA2|cXwM`6D#NYy)qt=0T()V?$txhY0!ykBA>rmq^V!M4Op^q8>EJj z6}}VT#`G?tso8mg5ghw`*5b}+vJF>131A;8)q|q|-=5b)@D)SJH;@GCUjv_wPn zGd76$#57?GWL_F95RBL@(2`(*l-XzbVmt6vUv070{qEO%4 z%F+*}-RuBh#;07xvP1#PWrmBowOb$E%AF5CGOm#1I9|Bz8@TTJ%2xI49E29bCeU*|%6P(C4X$?oL=>Q0CTo(xLACsmW=XS;e zj+hdaGYyjjq!`@n%(URRH0Kq^DODeEZg@J5@j4d2Vs%whkDchiZ$L&k;mW|4pD2h1 z7QN-N^gIax!I)>qHK1~Fcms(Ng0rW9=OAg2h>H2ua152fu)Ho0;mZchhj9_WunO~X zC6bksDSfH~R6pjRdIAtu2-Pb>sGfI}pjsh02GyN^-8o+RLiU8U4zitp^We?z8n`Pv z^1!{I7jXZ^N_s(2`H{uIE$7UC{G%6Wb3o%*|4i5mfGo+&3?z&_w*(!9_RgOi0eqK( zxBb93U^3=JB@{TRt^7y8ZI4CC1pZZ#gj5m`i-3PEZAUB*7_@S7zs%#G*Lq7I@IP&v z;olsZU!Il;Gcv+xu78jLb3*0;=ut~zzvD)CCk(pKJ8G5poz9pSU)r*yelKo2!&|TQ z2C5}8?nu~pX8-EU;Og}1>cLCBmf=iboD?dvRfUAQjhAwl$P5|UDTl7tYEm1Soh}|E zGK0D5j1O9x$b2iyu3I9txMA1hh8|v0a@AL)UyZ0(;S2nA>XiUBVHb$$RYEqx1nSF2 zty9v-GBmm72d81c>S{~$;O?}fltd=x&r>t-OIlC)}bZ2b7VH+Yj5_gzrcf7RJ-|qXZ zepeJ&xn?|atQrCHy7E-I&(1~T$7)hL$y&BA!}!a5JZ>_>)VUF{o*yg*h>~qfXjYZl}R;#vXji)zJsmNUtX7;BnTv!T6{%ONfcjjp43dY;#MS&@6B84IBAew(6T<(2dmN6#9>Xw8AdvUHg-pvz zy3XlV-gi3S4V{A)daas6o6M`ZfQB9hj_DwR%xuk8BGs9nuq!VnugnGWz(La$&vtN! zNpPAC#iy>l2Hgv2`yOIh_6l_7CE@u2HfjBFk-nEl4VN(taA5h8aH9MPb0)!;tI%`> zx6`D~UH^3|bC4IZSmP9#n;K>J1AtG!NP6IJnF&<2QMDP)1OtlA;}I9Hl}rpX4AL>1 zJKNQ0u1*wLuhIbsP3l9U?c|<>^2m2SHvl%){qscI2?F*`0ej8Jj>zYx-`KspU28V= zumz>G#Q&iK&v(}`zg6NjWYXM@{+|gb_Syes|FZtiE6?};9(Nt~A9^8DF&r4{1cprb z2H={MthQ&(h3!Jz=$b|9-x#gmvGw}rM(f|b_4*aj`t4h;Kf+&!GRCp-H^De?mgcp} zE-%>y5R{$C{(D8iXpCNl;}73s{I_iT_tN2eJ?(dF?R%&C1bS35g9~qhKbX3gT-oT8 z>Qj7D4df2x1d@G@RNI+hKp&J3DTRnNu@$=?eP&JO>NT#PVZ3=UG5<~9#C&e|pPc>l z%;@5Rla7A9JjyrI&jn?kE`2&S$QyZ2xo+s!<=o6Sb(ot^S9>Gf7RRd2RnO`FGo7pc zv1-Y)xu;iNabiR4>6K5fWKH59UQk-&EbBFkVuNT1Q@4<+lK+Y_ikxyzG=5`DFKZ!~GP@j*_1i$4jv~E~(+DklK-p z3wz|HFOvLpuMLQP9|umZk{2>t49zc#g8b&!#%&$>NK|%RJ{0cLAd+8(&8|yMH(Vy# zPV70etB9cV+1?j|_Cy}GyS;(jv^RAbp$Z0qA) zFV&s}FtxN;EA8;&U4+RDb4sbZ^IBWgLV9ua;AO%2D5R0peh{)rW4&pd1F!v+w3JtC zQkyUYKEwlNlTJzztse9kq%_N*8wSnVXlm$H5dnhv?k$BlO;ofoqKPhJz8lSz0?`yz zbYUsG;&AMpYesh2(T?HzyXT$x=N%HG(x+&}kpY;yA(eL_D-CYeAw_bw0X?Q54Vn&G zBoaO)VrzS-MRI6iC$pzx2Faa4TYc%H%lpztcbCSgKYi(=AOlZLaB+k7WhMP2QiwbN z*%zdjoWTDNfnK}*GJuXiw1+b+HqIb?0UwHVjiupy_0~m_BUj+>@{{g|`qVE1c}MJP zS~A6Mp#-*T3?!B`ULd&885Iq8`%+FKg^mNAVh7RokBR#1Y0ryliL_+j-qKpwKcusw z_3obQ%8J%_db;~b)))95m_1NIF>2UEw&%FzIuv;#v)LZXZ(AA9kANAI+WH(%UUd7H zjAumQcn;a}co0UlE`(Q*jYzs}n#D;ku1P;BkU3u~baEoKj73`Zi(pV%9!?0UO)Vzx zv8_~ek@{RAU!HdMpGPA0pC#S5L4#Se#gW3Le3ljR<>>=#LA2@v&v(~>ly33Q+uHx3 zTkL;+QFe6y=k1^G|2^(H>_0ToyIvGhzw)wk1ox;9euIjInsB|-ga_9AT=FXC@mjca zrfCC+J8Prq!V`=jCDSB1+a`5bt5~QG_ZaES`*$>4i!aiUPyW;=f%V@L`SWQX?-r}Y zzQadfG_aSlm#xbcDZ^k|R3Fyde6OQ*3G0EKKh%QJfd?(~TEFimYv2{b7hq^PYO(j7 zg;?8L*tZiG0$dNdQx=#JudFgHgU|j+pa!4rNVn8rXI(_CXD~KF(LwfRK)uGL zmddjKos}Bgo@ZaIN+0a2*W32RPzCN;R-^#~15*{yB!LOCK1n$GHU6ItSs(Q?0Y(RW zKVo=diTXD@sjF4`;^^>;QNt7Tv2T8GQ%G<7;Rjy&VsX&UcKRrJ0RX0WuL_BCwXZMQtvyS>i_?J4SayW7)x3{(pd`OvB3 zeXK{4L>UOOFT4`#xqL%1z0CISPLG{dn|@r|# z<+cyP_K7~wv=MdW<~pm;K9n++`$POcX%NMeT=8%fqY`{(UEF^##XTsK{WN{EqU30C zgu9#O?nb#g?Jw|bwB1c?;BIAlzc&%f( zYh7LcWw!V(s#^arrzB|8IK4n=7h>sW8S;>$_g>&m6a%@}L-1C4-(Kj&m$&ft>AX$J z!}*f9D|ttUot9uH^x{y)`Uz4_9}aKh-iU^FZ^X>GsL%1c*>aZmaqRPQUb9@zHEri@ z=xW-CyZK`*uZsljVfQP2tLs*eZ3{C2(}!nTRn(jcu ze2M0cgA<+E0kXtpC#2?;CPqH!+DW#}D8H(v`NcILX3OU_wd?CobB}PJOd^xT=F!kj zNku~6s=Rm!jOxks%_DRvyK>1+)#)}3De0ZGQ2uQb??zI1OQ!63BDK`J>)Ax= z&$HO#WvXu&XPD3`piUz8Pl5wI3kg>IJ~}p=+KRn~=2~JCIH*YQh;`Lwi|(28hG0Eo zqdrc<_F5;=UeI-~^<<`>UT1%_91Y?)?U%L+vKXSEs)4D~Ew5m>G~fzz-2C^R?3(^# z1+OX7N7Kd=8+Nm>`P`9&8aHhm=e17fwcpDTGIxMQA2)GX5>KyTUWU_XP3nnQ=Z1rs z7fl#(x|Wxvy5f1JQ1ezja-oscvI5y7g(n{A3*4?pLM@8ZR0S7il<#Sm2*bSUGt8^n zXR_63?o)IHf^qL{Flx6a_Ixyqw2{_TQKKL@%fr!ltK%1cLM6( zuSDmybe6XAAYjGdklxVjC-E3=QZg?1t63=TVo^xK-0#FEXqLUCU*-V*i9QxPP7LoQ3sevNAxBUI|If2<|rMu6kL^iuwZ}JaZO)Kt^QJz`opZvCFLb0SDpg^9`k)4 z0P9aN;KKu0u$2({Y7T+4dQ7umyu)Zaxifn|Cd62Nrk!#REc#>MLlT5=0XZW@bf&Ba+9jeji?q(QOaB)=%C( zcy0OayMfndwgj&gOY`vh(D&XWyw>#%uRq$|;8j1_UoO~wcs)xm4tjK3;q^m{w+62< zgH_*3TE(gKd*Z7mw;NF!`KxiD_>@>?WTrxek}49Z${5FC>-bhXC>zH{cRDr&MZtvs zq&f*VtUHpKUw8yr%-1;?GZvjgSb>KtBw#g+W0M37Y4y0(6NYfs~}&cE(tC@l}Nl0|ZK zeJzoC%zW%|B-1e`l2?+chs~F9;BmW=vw(r$O%rkooXamxQzCCWEivuBN@iF`;6>kY z_nPVg7k7sIT-e?gFQoJ?_P}hkW=}*|u=ok}y1#SwZW+v??*-|>>KpxBQ4HZtB1VD! z5^zk^X%^IXJRFS<63bM?Gi4C41j z`pJ17{(8!hkY!u+*|r(Sv!19D{xWaWYPw}EUd{F1xIa~MK%~@V?~eg(dHoOqe{b!lobTVmMG zJKq)>mt+RDoz(NKH#f4a&0)xG)g^nh?L7^ZAswHWiO&m}tDqa^I^QwZc|LQkN0^Au z6Hh2$uwAG71Z$oc>^T90oyq5cv3TkF+SG%I)Z^8IHyeoIG%N%AaXdz_`|+R!rPZ)E zgcJo@Ukt<%!D~z*Zs$eJYhQCwY9$mkPM{NV{9YI0!J9|3y zs&-*+1;qxhOk|jsMx;X(yo&gE96h(uWjhb{e zk=`U#5%^|DQxSV=M-rd;gp~;&cJY^#gf3G5e$3M4;#woOZ32eIeoD% zgb!y2TC6oVI-VJ+#U4eo+WMcX;gG>^H21dsFK(d|$)`|&y~l@*gjK)COq)Is9S=&X zB`LvUrpUnaS##bzz=y4AlndDK#SDRJHU8d1EZ3miz4xF7xybCq-Tgb7*9=iUvg(B= zwoN#UG;xo(vtMgvrwH7*S=xZ;!fBP00rE@i$#q=u?(93&qWrlK z9WMd&`^DHzi`aPdXey6TzFEa%v>5LLcRo7p8GZce#L$6zCIM{oWXnmYy)iIScD z&P*hCP@?$G80ecBc;7eR9&}@d-0aLqqUab6ob7NrRPmBCjU>R(I@&0~SmK*W61v4A zWo8n=x+X*Qs_X%8`!1uSb?;0i)oj(xsKx=Kv0B5;Ew|1z*$a{BoD$Apon~2csu{Fd zMzwTvswp%rb`*2^_)eNr>?Y126=;|KwB~MSQWBguItDw%@61kd8|INQm??f|W{Pj< zuG-NZuX<$;nXO3uYmdm&vtFJ{k3}s;XxxM7o~T6=g(41R+#9tJhzrRph5xZZ$rQGY zdgC*CZ8+8R^Z@8XKnYYnN~2AE+UGQ@;WQjhI40@Gj3MS2>Wd`oE(`9$c;(-m)FooD zHpKht@{5J^_tKgnz2F=sbFr9=3c>i(h2DEJbN!&VLY4~A`%OkfNfCN~st~Hla5C zpwj{$Y|5BivxbKH6MZtD76`sV4YJNeI8zZ2!k2_a0>WL9)h$+NvcOFV+6~+!#{@Es z3IVr%WSYYZWSadWGEMW#O;Kp+neI6uHSmae2mspK0Z?9)$?~xfNZy<$ivEP)#O0T{ zF0{tZq+S3O5?gB1*<>1%urItAY^W{4(1-v)cI}yu9D$bjYW6R`W!}dbfHYCfl4M5L zs}FhR{&(gR|0BTKkM{(mPF`YbPe59m&KX-U;fAhZoolh=!0Li;oNF66hejk4n-MIs z<^}Rh^UIS$<utSJ z&Pvy32mZ!X|C-dJH7O)T)A~mZel3Y9fT6DBE$RPI3>*4l-TTP@rMLaH&1FmOH)GL`;{`s)jS3f8waRkl6$0G+|M9qX%&#ry(SSFUA&VMQVlh@c3gp)H_~ z<$cmklGpNQE`sG%A@b;dv&7zPd6z_%_`~8pJ)Z2>O@ zNTg+#oP{rPi#Z7fYrY>VVC=w6^9wkf`oV(fT*>i2z<*$1RI?QSVprzDU6d29IoN`_{fh#M*Z^eTrK9 zw%Nq@C@;n<*7_zPeq|DR=(BAXAE}dFRr~?_EkJUuvttTt&Ghqj6q}tT?{=yfHs8So z%WZ}{6=KNy9LW5Iz>o(rkN&k*x*IzlM11gT1Ud%`cO^q-t+k$NM@(xjzqX9eWvhS? zmN60FuW!G*z^&hZF%NE2jPm;H!YZDNQvgF zq3`{fTbFEPy>7p!=qp9*rR`O_&lZAAVe}R40{7Y)n5Ba$x!T^H~ zIxEu?W`?t4nODq5UI!Z2~|8w1Khkxr( zYoF)*ThS6K|H{7=fJE$JL(JI(MWuB)527r8H&JmmWZlWt-nb{LD>pgjFit_{Gh_@~ z0LL+~>*NBkn;|BzLX2UiryRrL^`oaK6unSS5&!C~r;IJsQ;wGzqJzFlRncOYs!nyMp^CtQdjDqL6am zKEsI-+iMVm?5URy&8NM6KQhr zA}+uT)8JJYXz-V>?-w%;qFNzl?B+^}H2Cp_m~rB^YVbme3AE^_^oOJH_MVjc<9{X` z*|Ey~N8bo_x3ZrDgK~TU-tGb3{*_Ao4L&~sKendNfAMwjV*unKCpQQ9Qmu?W2i;0X zdvXtf9sw-tSNnhy+1Pl3jScn!-L8hHm{j{Z-waKr_epytxBk${m1S%y&Wu^Tx?i4+iz0g4%}}N z}+;sBK{Sv7=yXb!G$px z6$T9E6o%4|=(P*g3K@(NL-!WFVucLm=xt>%`Tb)0JbgcmeLz4%S?KL zs&XPy#2#+g6Oh=C(~7JNAMgR$k-PRN_nDG8z_^ZJQc6O=eKJRr2+MM;v5PT&OtRr% zKx!;KPf`ivHGlBmOQ}Gjqh*}#!%p_c(69=1q4&`F_^hK{GMZ@uuv&ABZtMZj4FFZMGqxO0i(Nqy+WF z9nPZ9J$qwPelGhfK(Dyxj=$(-6J7llf+??ZFL!tPa~;r+|J&^Odpdi5pgh%#ltsUf zEuk#)6k_tBw-ws-PpuCYWoCfL8>qic_Wb?U8f?p+zsC>3lkK$UzYJVXV0GV%J^vmW z5qcHd^ZScm34&Lu(+{6oO-c?I!jjBXC6cLWRelHyj?q&l!9WO($P8Qo)Dp!qLQyQW znTrU1Jel2%5@J@+BK;tid5T-%&PA-uQ^X2)+FDO!<|$BxyD9EY(J9Vs;mi{}nd+V> zQYB)d;DHNTndgF57HEhx=Ym#dHgV~KR%Xt&1G$uU&JN@{j|Wt? z{UUt3D)6O9-y4Z&ncF?TzlfHv^0s4$L5#}fw8@Jf?kCy=dY5|AyXzU0I?^`> zAtxIcbRx6GkP~y0=sV=(?V^wqdDZ!05m)74)onwX_{ko6Q$8%B;Yc|l9rArd{6k&D z36ugWMPbBAO0UhBE2_QqFr&b}A~3zQ{sTVT0NHqh{W?$D=`4tBU}3edF!| z*48u7{JQsw#LK8K0WRfZW^$F>{<|Yy_M@M9c`b;wdNcP3&J44ji~(f(p%NZlt>5EA}|+$LVdKG#RAR&D`b4%R0c=oR`0)!@y7 zZ8ANFirou1sk34K2f%}p+)ae3==LC;ELM^`M*6tUw8UVwsBOkoJ-N%MkS`gtfcfvq z4WU}_JzL?z_!=T>6dIJiS)?R;=C|Qv#ql)+5vfYXs^l)FTY(5*_GNT_r}7)&zlE+@ zv`k9bZ7;#7?1E(~M1-dgGNSq>P-sMTz7ZHADR}9AK7k-TuH)GFqHrZ?F$JwZ?G~tx3I+NGq**PHnoh55exAGp2We7u~{3;(f9_VA(?%?19T!8 zE2;$pyF{}(1&J%_2x}vOEkwhqROU%807=~`q()hblntKS5zU(~^jg-?DNLr5;E!Rb z3&cu#I4;1K|ILV%ezIR_^Fs$3j*#g1RbZt1!_J>Pu1zxPM}l0=&?`@V#|Tvrmb4Pt zSYGRAak^uEu}O0rS!=DZzt}9hZPVIX+Zw;dSCmOaFz-j!bf+b+?vuL+d{yo>ujMa1 zw4v>zF)&aRsCXS>ELd5G%QNVSW0;$cD$Q5I>?k%RF2ZQcUV}<<|1gAUvVjHhIiInz z67$vz5f!`os6rs{u6YN<&#g1;uV#MRs)}^OcopE2?xaHZuQ-p&#S3YO>EGmsmiw7~ z4*QTFPsGS&)%Hi8yUrfdzTtB zE0<}ZYUNraNF$)Ff_9{60x6t<87NAjl@_Z3tdFRLC&8ffMiT5WObN)%N5rbAC@P>u zi&jWzDJ>N&<oQx`fl;GrZuqU&QJA^v&rqyMXIE!1Y!* zU2Ej+;B)}sV%Z8l{+_|xo;3#7pN?xY-p9ZGa54CG0IBm}vrmrECad@xclrT#wdXJN z#_QJ`f435LxSWltcH{4@aW`Yy3vbD!zcU?>??YA}4l-Py+a=sDT|h1GdP&g@U~Jz6sRef%}aj5A2bz^lwMK#W(i z_HpOE{fTqf9a#SmTac9!o9NoHZ10`Y+xWdeLZ_DkR4O#%-$oU0}}pQZvUp zeCPTHPs_4QDk!;3PnKIA+o5!e$&}lvlm9oe~-J3-Ek2@Ee=*zg{IiFcMm6Nh^9VdyA8KMHaW7C(Lvis5afs3 zj|CMoc^K5rvmJ$?_QrzflHMWFr97QOCAO-R+R%%vTX@?<)@fYW!l`ld#dcW6=5K{7 zCD<%-Sl>g^N>MB|$J}gw-UY|?=Oe^vha1j5Uv)E5O&T=6?VVXmYb1cw2ML<%SNADs zB$`SE&8OU*Z3vp5>JuzGZltufJL~xCB}`Yx&#%xf!h=NETS&Y2FD*EokD#yytJLXy zsNL1TlK*Is|3T=0+tbpJ4`ax0eNu+NjVX39XU;)r90b(Qr!k0&VyEwODAw`Jm68>G zc-d>9BhRUS7{R^}t`kuwtE-dCuy_mniTFd-x&x_UvZu^E2%bY@y&Q@D5 zv*%_ubN1V6l*=;m#?mf@RxGL7b5W%iRJ7`M?X<~)I+y4 z#Rp{BQ=00Ta=TKltf^ef=StT|xS4Xe(#bM2DbG(iT!jbCq_X{|e~EdCr(!RDp6Y*U zMbFQv{^wlxv)cdEz?!Ns7fKl4oydhHLveh!-i_gyjE)a{G_|H4VIfr z)n@WsNpUR*Zs)J(x%C|%&zQedsy00eC;rf3>R5^}fGooijVSMgcyL-CfgmLgQ&ke0 zSh;P2cSklkU;eJs-Qem1xO}23uZckOXUK2(D`q2pn-#rZo!Q8~lelRtpDR;vRw33T&@F{& z@wiIYBRA{PW=0>O6$NIEWBRaIEEj^6Ki_>He*VB&k^N2iE})WZ8IaWWKdW@eRY9RpaNcf~XBrA((%GiytnjJv2`VgiHt z1jg84K8y>SdIfVGp|$y2eyR;uxu)vcD%Uv#D;3Oo3%Z?BnQ7v3{;)_C?t_he{Xdf<+x%lw|<6%{ji0hVzO z+*xTqn*hlNX&x|UmMKN9?hKFxW{9SMd6~#=6U1C@L`y8q68#^u?IN8@`}x^0MkD!x zIk?2m+fGr~W{X0I!S5dhzjug(!h)fFQd9(=S}qj`x?flRm)t1vmm&V>RO==f;~QAGQG*0mDOPBlUShsKOQ8^10OaX`+GWJk>Ao ze4PvLLz7v>+lG*rxF|+ZA&rpI4V#fuf!p!syD2C^cP6z++4(4cBS^LKP|KN5HTjLs zD@@`z|LSwk3<0Dzn=S6+yexW}X1RvDpec~1w_Fuv*6Eq8Z`%3omnx3>Lm!bxgL%rV zlr>@i*zF`tOZ?1`Po%uzsSuLAcm;U+;&+_(G1-NlM`2nE4O7Jox*txm&J6X(zNr0b zMC~qfQwZ^?@9)C*ZPoEj-qsCzT4v{BpGW+S@K>VVx9jPh9)Iq6N&KMbA=O^_G&=7Q zS*kR1@Sg>fi*$b1;R;VXPgGUx)o<}-u7B6Vj&PQo;9jcp{&@2JIzv0NY|DzlrQ=Ea zi^4-$ib?@2`1VNO2x=F2MI4RJ=@yX+VuG-lR}9sfPkTqTyh?ZFi}LSz4{EmNQ}fv~ z7oW+hK(IZBi%^+fM{(p?ldM#l*?&o=`f&643`I(nY2};Z&NgQDpYaKs+2>GPfEWMx znSFJ~gjt%|3C)w!-xa4vlhLIV(%^`C68+|oLnNmhat7FMHwt$xXOTpiGP@_~!ffvx zbMhUd8^LmAVf_YtdYj*=qT?zUZTqxoFEr)TSt2y2b3-5SfUW-@{h(E4oh>1r>0D^--*Pz6L=&Bo*#g#AlSlq@7#coa$7nfxfs-ixP8 z<}M3rd!4;IPKz*l08I$x>RhS_XE=+v(+9#C?wW^0i8Y$Ae=)N#4=evgFZ1;Yls*BUlGHv&9oQS77X%8{&_$`-f#muD61BX`CPP z{`*oes~g+ju5N7YUqjDQ`7c5968=fao@j5L$fM5hQ)ND^lG_cJyS$8FqFU$QG?((y zUPz)he3>}4m@wae&JdL zpXm@oN`XZ+O~_ zuGNhjzaedhzgS;yr8oh3)w4Ef!Be-7yKdw<3Y=_wrw}HqN&1)t7LBTC*@Ce?O5#%8 zSQ0+zf}w}2QRaSs1Xtnm<(GU#b}_d^!G&&2cimk0F+jQ;Rvk}Wtk69|X31>wpi?d1 zlO`9)z|Iu1PYeKJeJJf3<4u?HlLr^pf701xHSy?s z5`vbm>T>;}BW0a4ZT_>u2bsvokD;&)qgimh!FEK+&54+G59CgSZ^1JnhIL#5u2tRh z6nS!~1EDs#(GQFB@r|uvoqIcFdjsHww9)`5kt8o7&5iiMy$Tts;@94{;i<6SMd%BIMTc?}tnA%>@oZA^eQMj=h|7Js2+{XF3fXqh&$+;z zmN{3+#7c~F5&mMYg20Zmzj;WR0(+lGI{goljnH|oo~U5Yku=1jC+T63G$ga(EZ=cD zK=zB<5NF}~r5CU*ULyJTtsbv%UKZq)?b=cKn)@u!*<tTkzX zL$E;|v*$Rh71?tHPLH?G@j?&0$?u_XQ+PW<^@jgkypI`4f|~5j6?36AQcU8@#Fpf* zq2^F7BB`~zw>@3ExL9WG6UwabP}a-yZHca;=wVHz((0AmuS7(-2ygk%n1m8oz{qGR zCCUn}cbd$;PU7v}_GiQqp^zf{J5divl)8cKBWFJOa$q8=AewgN6JSF!|JM5*HdKj} zj$!gf*CGs{Nc%b*$N`i>P&gwtn#U%NMn^%4HB{3vqoG?_@F9C1_$apJ85xm9tqfEV zK4eTQ#>bB|j{2G{53u*;^n;cc+t-Wb(Ntb2K*7r+Y2}5R!iO^37UWT`enXt|BCU16q-wGis5uD%`-SjwciGuhJEh`WZ_4r8{Kb0&hO6(f^h|B~@xuT{jf; zj+l>8Nk{skZe_QImv+XY2rm!wvluUJ8meNvTp8h|IU4U`ytME_0U91J-!8c+yeL;< zgn%$!T{v)Sv+>zU`0;&htcjB}ShevV(%1M`o2x6$_=a>HbpR#kGG3#J*pHaLizXvo z`^m`V4@Gh~V}k`GNjG0jVE8fPs-g^{s|yoRQPz+#^OR6D-t@NcslAGFzGxXlFRs&q z@lu8!AB8Y5yU0E?h9iqu2wFDLi!Q+3W#1ZQ&itT!bnCtxWzF0|*36OAsoT@X=E{FC zoEjV7iZW()e!=w*hY}tjJc`m^zPtz|952*#Pu+>VY5^_AAk_c(6T;M`$NSW!qJ_&{ zI{u%`UAkMp&;=^UT~hIdpz$ShcKjfpj;*h5duf+cExwAi%W4L`Q!{XVP`h5ej5j@N z9qFH>`87_rO9!@YBk8~>*#R)Btm!3r>B@z$Pj1gu{OMS5PMEy3`5ka3iF?-tghs68 zhxGm4_`$&j0s2>M*oSyxhP_9>nK0wcb7)$%bHe>4H;dMz&c8<(X#OVO2pxRB>c40F z@#$*k&if5sWs2xfd$k_LL(v=(nIp!HQk337ENE@!=~(o2hA(q}{x8(y+INA^g*&4w ze;D-?-8>=Z9e?9$?*dR$mRA_Nn5;y;&a0R!5@Y9U<*zZ=`HYD%n9R3-=D)3IdC`1* zJ>|A@zQ!J?N+b4Cf?hm?B<3O(E7J9Pna8ypHC<1sYQuTlgf2$I8>y%FusdlarsO$# z)_u)sdJoymR1m+KvNzuA#ji_1onl+07cqR{H@b<|P`~SC_P&f7JKCo9cme!vMZde9 zu`ZIwny(E$Ucb{)qacsHe&^=z-u1i5ywF1)pImZN@>u(0rSdqG#m}$7fZPfp<$KW^U$o zKiB}zC!;5u@99Ll<*}W=C*2{SJeBx|IVQzZ_a+m|oU>Z$-gNVd&|8hekVDDOnchWi zAx^t|UZ|Ad?t0H-L^N2maeL_ejJ>fgYpb<$py z=sgTsj8}!r7^oSCDWw0!t!5#UDE<2RHmMYxyIV+(Gu8+%M|(4k8ug`Kr!s9u{rofl z7V2Xo*Jsu=w#V!hx$CHO(^+=$+4_%iy398_$BjNd-mD!0v*TIGi^Gy1rmC5nKU+6) zK6iMTl818zshg#s>62P3=HFwVWd5gcyjgpjU?H7(%&nCEfpGNl%bqJODX&J)H4hZ* zOOd`jAk=^43R6(k6ZgREk9Mbwf1e3HF}f|*ljOB~E7Oh1nMUouHqc@lhsK8n<)wMM z`F-T-k*!8n+NWNQq-nG>e*}N&e*IC_uLoVP75XxAHALjxHT8Dn>U=r31jKJpWBwH! z!gyN2Q?iieU*IRlrsV&NXCdW8(x$)Y!Llx+apz@}9=W>nawj6BubG|}$p*{kKW+q> z{ZhRIzKV8)WTC|N60aFd;>o65L@bW@23rrTI6CMA`)cgD#a8GW(ckx_ycxF15A z$pGz#nO#El;;}LskCkTKF(D%K%ysD;9iHg-F2wfSS@(%9;bC(g5#fu*^= z6|{5{1)&JAAd%As6!R{E00GdG@qyjF31tj+aT3ea>=L-$r#oW%#%1N6^H=xa{Coav zrXz8F-4x?|*9TFpO7w$tS9sESC!%7~(R(*UoZJ8z<5!lU-sCmQ73ojmder9^wfU@+ zzdk@KI_kbs^!;LCW}UFWGXrRk^@QPcIlUbd|NRGoY(1z<2V9bzZtqm>M}X7_?$R4h zcAoi`o{lF`9q9N~#az*-mIT^@bzMb6?!VhrY&>Pg#!r2^I(K2aPOkuo$qaghlg^x5 z@i_BjZfg7J$?;PcSMyS}>WwhQxldOZP$~KJ%(qhUrhuu6QxD$ytkXT6%i?F? zkEstj)#9!2RExKi3(ucw(Q7WeG0l#Lt8MB_#%msDNZ^&WWa7U0yHj7aY`!b1ZIqJn zQ&uDs5C2i1XI9jtr=48Z!x~5JxrEj@F#*;%5MN@L(`+aY0$UhKokUqnNoMIL)rk|9 z)*sSiQKFREvL`#)tjzh$n2TyL4CjV?!tKglCoGrFkKLFe9m|(6LJdnMnpqakgtEfS z)bIFh*BD|srmTyP#^*e#yV>`C_Y-o_-dEa5D|eFSm;C@&nN4kfFBc-wa3)raYJ1j# zutu=GK5&)bFnre1euJcix_PE%;ET+eFZ^*qjAJk1sG5O~GpPpIa`xVsU^|wLWA_E; z%0td&Rk8+NKp>cT7_wQ$IJ4O4d$`YN09e_4liE5iL`dZC;e~FQ;yRG<1%6^#FtRJJ zXd^d&h*i`dx?0xul4o`Je(cBPi0 z)0nN~Mvm4tDM;7um&z=5&co8Uc)2Pim)41BaT7SwlZ1hL=f>OIwont6+A82E_$Qa4w>7V@WqS}m z<>6#vh4anQoYd!hlcD|iH z2+EwQ#4(rIG!WZQ5Mqrx3BO*iD)Oq-ttvffsLp-99fjx-sZJ5RZmgI~0|YOpG09e- zRjcLw-4oLWvbG3dKkWuE)C~ieQ-7rQ1d01?Y0zEosWz=AnRuky>;VrK0M{BC0i*;; z;YSH#9#5IxuXUpVt{-0xwH@7*qEigGjyFHgaF~9-Oc>d!Dx)Ei^-BM?qTfGvWLu2A z)DLht_b$01`^|cG4dqcba_=2*=YrU*wtY}a&^%JvA?vUrvBFgTY7xIx_1c}R-C;|; z?eDvrhQsV{D$T%ENE+!YBP1w>b-a)1-PZpTi%=EXznu2s@mQ?AXqkidGGQKgoCm*k z!{a1$8N;I*1ObgX#+sH?x)Q1GT9KdbQTm_t=f7b6dFJ?nFg*Mt+k;PWq5f?JpT`|u z5QaOs{+#jKNEp5`p$I?!yX((YcYxnF#K7SizNZjX;*)6oS&*Ntkm%oS{yqNRV*Y)e zWe}U8CKBfhDccl@+X1=14lh7%C+FYuZ;v21>&&7d-+}peAXRiMf~5+0`G0EujR5v< zH2>Dy1g2x;POjV@ux-cu`=t-{HUG~3&AUDSUUxER!V34==|!m8-uZXcufgL{XB55Z z^ue8)e=RzST^X6rg6xg9b%S;&BL*U{i!_U)QR3hHAGWSvwfZev^D< zncqi$79Yme>J2MV;#eFg2LxAa+{jkt4%oyn)U=3S%`0Zu2V{3@Uh1x;igBVOTK_$E zwUMiZTzM@lqq~guq{G@`(tgsl{nRS0O%yMQX2XW^MAVzwe(Hr=yU2luo5OTxCMDTd zIZI*2`^1}G;O7|a?8H#M`EI{>)1mGP#p(vy-qq5+7e?JL(FgV<>j^D=hY_mnP#1las(M{%QrLu(bAqaAgzedqCWR4M)B(!e}zzyOSp;qe8s4DMnt^@ zx@T*rYQ8jBHOrvqZYkc}G-4W)`@2h{u>+4~^^fi>n{17_r;tQ<-`EvK0_I|eRTh*5ON#pw}ANI*=X7Z-`14e$X zE0-S1HfT-|1uZX`=$QK?KMOq*6!H~TeHBf-MNNDn>`zxqt9~mrhxO0ZqE;)izNFRe zkp&_b>}h<@jaS$&MXGhR%%@T}5N?>MD4v_kqe8Q^O0!U+u9lT*LJd#PYw2oPq930O z+tbx@yM73Qfr(R`Qo`Po!~Owp|+FM%B*E zG1-C93Cd$Q79A(64sK(T7c>5vp~If|+4!{!H>@@&9Z0*454E4>4AL5>EqVw437Ehb zaH5zI*LC;9aU&$Qa<(LrMh`Pi!~mSp%Oqkc%f=H+;!PjmNqo-!`u}Z9g4(4)+q2~z zr#~`3mdv!WR}ya;Pu;27I2PDs?Kopr_LC2|`VjI**6vXeWcz820{?1xQkzCFa`J#J zTNH+OwjFT!zIcY$Ff1~Zpqpq6-g?}|J3>p|DM3R z&fP;u830Xd61&B(IEdRdiFBDEVxky_9k!P>t{(~cL1Uni57*}tc?I^h^F%!-fA1DJ z`DP3@04PchUVS!aJHanwL?QEsylttcP5v1Ji{p12qbI1;#z+BtZj5RY@oD?$19oU-0n6h}Tnrc+S7+z_$+;~DE$M2$${H+{?KF5{g_hJg�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℘j%uWD$AfWgxonqm*` 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

qZbDjgqy+{QFs1ugTDGEJOQA{V6>pm|` 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

jaiw*YjiQZz3YyS!dr2|G_n7>DBkY5 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

mZbdm^;Fo`fLjKOh##rH?|$$>T9xH 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¬Er`+a@=0IAZBr`>C%VQibL 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%0D7$Zp8rXfgFyM(8wT@ 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
33U+J#xX!5+YE_p zGbFMNh)$PSf(Map90Me>&5+18Ln7ON==1_hQB%7FVw%Y|%wZ+6&5+18AUf?RrXpLE zkl8xf{<>J%$@ckvagnWJpUE~uBHMs)rP(G+sF=t$jsX(cW=Le4A(3rBbUMruJcw-L z7$A{thD5d*64?esr{gR|P3;m0bk1zU99AOR42f(5qSFDru@Tv_RIrUxSX<_qY%?UX z4G2z;OtOSJh-~8+Adzi`M79|c*#<V1a zk!_g6N@SZMk!?V9+EPqKwu-5ft=g-|R;OjM&5+18AUHp^z!K^rvW;VaM79|c*=9&& z8xWlyWeFZcws8!Q$TmYF+YE_p1ESLtEJaQ25{PXk+c1Zf$TmYF+kohFMzIyyDz=$y zWuD14Ln7ON;Pm8KmQV+gZ5#t6vdxglHbWxYfar9IC3q0o#xX!5+YE_pGbFMNh)yrC z6g9O=Af}mY!yHy3+YE_p1EN#@j&4~~mZf?WQ>C)!IH@ymi zP%qy|Jr%5ue&Gj4xB{&WC7GZ7*~Y=&!{1tuZW%EXT9cu1;?sgzzR>7))jT5_>C)u4|og_fV9dh@DB7&fsgjK`XzZ&BXmC*a?ac zlMaLU{Jjl)gO@gD7x51imsDCniB^=?u-^>DZ>i$1OZeFFJbt_xn^JasFaC%A%e9Ri zFW%12ecQPmXU9vn^7B?~T!oemt;c9R2J11i9y9APw;nU=F<4VBii!-IE`79d$5%dn z>C(ghl8Z=Uy*h%}d>+2z)z{m4dhA!n->)6QJ!!rOJ7})nI>;2iBJn2xzV?+7VTLPZeUAvc2^Uk<=ml%(-cZm&NMsKnW$Vyjc*ep@4b3D;T zL0@!jWg7x_PsVW@|90>2G98WcEE}VDPlc6xv4zgb%XA!fFSgM69Kg|8t3%;vv7;JU z1M^(x_6&KhW8De$HY?9{?hGq3#w4reDcR9D0LVQa&yagOks7Dnm(iBvjz2zU&(wFn^zKVVxzoKP_�YhBjhlZHGZGF4}0=Y;+zV9fFxdCFb2Mv z^Q}>BFsZYWwFF}j>VO4r1XolTB69**zywXG*J8id+&H)uy%se^f9E*k`$yPRZT|=% zD2ch0*QoCwiT?hpY#IIgJDq5-GS7p&S+*l3_h+;6{%cm`J-3?Yz2t52{z^mjPcs~% z;YSTk{n5(a|IDftR*N0E^Ug-Y`RG}+-8NcY`si}o=rd+(Y+zp|)?|AJq2I;m4Q9Kc ztizK0CfjJ|W@{bKzLl*@Mtf@I=KSv=BynhV!P` z)}y^*V7#2e+Ev>*bX~O--=u7n-WKok7T8#SImaRxV!XL(>jK1oeslBOg-w_Kq;bdi zN2x<~4;mWufwm5+y;b)&t*z{DdMQ$knx zvZj6z)$oSZe|+K0}tX#~r1ib;0mh8oI}1*r|A&>hh@JnwPeY z8XikS_m~WqDjui1Jnk>+Xx%wHmWJ*z8QQoCL;Kc7PJE64rJ}#j;A%E}-GJe%Z-4JG ze({c4yY(hG$atE${E)i-lRlEA9Anh( zj@2>|#JHn~Q+F;K1mUS38wqWFEGavc-CE}e?|Rlz%qk_dZe<*ilG^0U8oyf^N4PI* z(8-rIXtV0d$2zE8nUArq)}W6SzvQ&~@oS~HE8nuF+H3ss=e;uD!Xu}vJTD)|?$2$p z$fSDYO9#+Oo?gCmAA-<3U*cE9uLa?rQ-g2k#wHtu(=0ISz^-JsahOJD&3?#Ct>v6E zz$o@J{L@pJ(=@n&cYoBAADnu>9UiwMcJpmx@U{&G*nM^fQ_4Kz#!XO}JnJ1Vo6p$y zKjq_e=oOFeg)Bt*hTX5v^~pDIkD&Lv;}dqTbf4^pqmkz#%g}rY@{89YzleAuzrc+_ ze(@sAc-#GX0DGrn!}Mm)a?5;tRnND~d_QY>M3BVm?e@2<=bhsCH>9a}lidZu1+V&` zYP@Q970Ro;cQmN>WT%e@8L`ciwBe7q=o!qN*sXR0yGIn(^#`Cl0{g^|wF0~K?=41P ztJLgKgooa}BOCd+Suw17)rxV+S;1P$Cs?)j7GtH=?#NQbo3$S|D+WNXV+-NpMa412 z5J#m_KA!#2O8M-v_T*t~(%UHA!DV*4`NGF7GlvaC^I-yR5C1cWwr^+%#r+=bjE96iG?kzd|_3Zdxxs zF#cYN5bSOlOBc_xFR~7*=UM!et;YXm@jTn~=UKLo-F8114=8}+^Gbf~8s_H>#Z$w+ zJ)VC7+{yNbpHhzdVjXvMV~c=23vO=FjQs$=v>YMd&G3%iVBxh#yIsz%-U)6wW|>Tn z@$knppQ64yUw|RXCUu&dOC3)~`KuWB#@7d3=)kPU~Y{v)#pS zq|@;XbzdeRkHek6TMl3KF|5c>K%iPq1%gNZ^69n)qCySw-4dZ{XBD?>%8G;>`H#1 zCE?QqpU2Q#@b@0JsHD(6hQ3Y-@l#VuYlk2-`gBLzI8di z@yj0g(&e{Zuko_$dwPB8R@aAbw5bnUyMk|<6@c$|+^h5XOR{(To@HwR1d+@8d54_{^%bqV>7wg~QyXrgM_A|Y{-?jFYUSlohHTg?; z{r+}|-XB~j>hq(yJ_ypfE4?Q7@b}%{@o?lfm>L}6?=nLu3BSt>p(Ok+^Ef_VKhnbI zjU$uze53td^Gzeu`1=DRGq?fx_HzSQU+1k0zdGP;tp{*5*sANenP!JI3)b)xyW#NqkIC z;bZ@F`|#T1=x^4SIRnS%TkB&l^Y?A)U$<>v_I=QGaqZ1^?WC6aLqvZbr&N%(2N#pU?_HJmLT=J;V5(3^ArcfIfV$LtP( z0(8IDwt1Tl+}qMUy6qObKg+&Gd0Tj>&+TvuM&J)K@ckoPMAD)PrLEuO_XEKW-1gJU zE?mSfB2~l(al!r4@5>hPSzn&dTw?5U>VbnVDUe<%;n^R2cv&XR^*Ts%Ere*^+(8rMTUnp$Lq9=UYNhd*=hHjx z_eby#76sfi%as8$%nc(;{Whz1{g~>6@5Fa&;Os)h>j!=e$pli){!`@4d69JHdGGWb za>l+EnbBWN_L)M*;fK4NeAUYK#OqFm>E!E%GBwX{>Fgo)43B$N>^a8D-E(I?1@F&A zrI$2kZfAL2N-tg)dl<61)GA&t+&#^EU^9S^@t*A7?`5>&cuVjE4}`9cFXhrI04?Q0 zW8-OgDOZNHlq(=OuT{JdGBk88&%qp_Y zkY%Uyb`EZbS&3}J3U{wo@$$wivQ=m@*=9&&n;}bU7xxE*nAR#@B3lLpU0!6X5amq@ z84}rMNMsujVq2?tRmfJMv4KTon<0^HhD5djk-JEN8YE64_=*WE&9LS*_yb?M#`iLX$Jw42f(r zB(e?2$d((#V_0ZuySS4rg*tFZWUJFM*=9&&8<3GLOYq?N;!GR^}AG0}w6B+WF-W3p?nnBdG;#AWJVGb*0wi)u8R-Mi$ zwjx`_Hj}M9WU|eW$TlF2Bjohg(y!WWJqM2A(3rBWbhfiVHDYFRdyy@nP;-i zkjOS5BU_eG)6a7h`A{d00rH3QGa1sHZHD~e{9HhEY7$%U;1p&h3}C6I=ffOUnzPN2 z*YsjQbXu!;@d3P8jPGyjht(wf;oM3HwDIC8dtR?qyvpecr?5%&8zVZWupI%Roz*H{ zPGJjbTFPt{qC{c0XGocChMdCg3<$A3c9bP_d1bb743OvG$1|kNHbW0tvU^uRbb5j% zc<`FqC5m)enQfTEN@SZMk!?V9Izvg6sHv5z6m~}DnQSv8vJD7MYZWh#sWMwcxK{BR zS36T?%TmGMnzPN2GTRI(vkeICtXA>zcBaf$p~;zThLqW6NSSRwh-t0jrOcK=DalqL zO2fkO42f(rB(e?2$QFtTiELTwB3qefvdxglHXtKgmQYh=ws8!QGTRI(v(1n)+koiw zyI#dBt+&Q{Uapy4F6#9=Tw=H2JcXdFZa=;yr4MrW{zstab<4jkw7hQFi#D=M^$OTi zQ08hM@KwfZxy2zQy8ea|UH>~mrTs6xu7joTp>4CWI>6J@#OhtMe}$TvJ`UcfLdWgk z$N8?q)_-@c-!^5p8QkdAtl#FYnC|7)r>L6sTeu8&Dsf!HMu%tPCzG?jjy0*LuugiI zq~OEt3>z}4b&im|BdqnZ5DDw0^LHsYuE;V~Mr}X~p=?0)H><_cT!TK!J5nkH@x)IU zbWR?V=7JB=OL3sM58n>Gtls>#@6APjE%GpXk}h;HP{I4G#WkJ(ig0C8D>nsf;qE8w zf^q$!s$Lf2k`zQ-|0?rAq0mt6`C03#=-rq3o+sP2llZ&XFZ>4Ye?9hRTw(h&_;q}L z277w3i@2vMR?q(ZRwnTosP(aoa=h~}LW?9_HYVv(u)nNIAFEIME%w9G zrOyPdbRVQw(L*1rY@gmLyY#P$#I-M0CHB$Fr65+k#H2IrQK+D1&tnHw(Ps`mK$F z{l_!QS6igJRqQwHo3Fm1-*{%@zJ=k8U8C&(scS#!BThLx?}~TsD-l4sJI{Tk-FY*J z1MfgJeJv9)PhUO1n(XQbW@U+(cLcYxyw0*P?*+-%UccdNG1H~5a(A5jO1tAas+}iw zEUl=I)u+8KAHPP*1J|+JI?O*6XNu6^(XG(iTA5EUx)pL-Mf0?w%v2@* zZ|G`Kj~GpCMLx0dYqjmG@A#GYB-)cGRNwQtp|`b~`&a#5NXa!G^w8Vt!zZS%RopTg z1@!zM{Qt6*`QL=8BHwsgDqKAnV&9bU0UKq>13Rr_KU;cSed7D0gG!MfWga=%@grYjU;K~?m+;_xJp_ZU9lEwLblvu$ zSK@Ok%9|m<@#Rhotp_@5IUT^)3`v^fg|##Xi2AF>Z7KP;c~>0p#XietVT&td#Sc22Ep0Aky&+ljD z!63b#4T!Ws!sZRr``I`KNbhGer1!HK()-zf=yZuCc+kqjI0ndf|8NE}DzBA?8S!lGn8Aw4<16F$_wzG{?ANqQx+3XEtG?#V{GNSXR~43Si0iwKRuT9x5_Mm0Ee2A+0J-+BV}LA8 ztU9$!vFg;4#V)5)bOR5bFIuTu)4lmRUeoCec}=S-8fFkRtvL0XR-AfGD^9(pRi`b* zRGF<}>Khmb{YyB7-LC2-3R}pKQ`nsWA-2cN05$e}aVCxd^2O5?r=BlXoO-@kb$XO; z;KB1nDtAcBHMsi(-U&4%r=fiO^;_tnQex=rgsHIr!$JJGF!zqQP>%o z=gc-kPGRQ)g42^{Swgjx*~T$I%4{>_6lUijNOm2ku&UD~IaOwxJt(uykjOSeBHMsi z(+ey`P3;mz9lWOJ!yHy3+YE_p1ESN8Vyes*rCOR}Trm;Zs-5M`HbWxY42f(5LZD{{ zxNR2qMP#c@w3%#Wp2;>tBHMuAw3g=Zn2Kx_(^{It#_>Fjphjbm$TmYF+knutj?JjO zifk3zOtv!5WSb$8Z9rt3vn&OL8TV8vtfKcJvJDS7QDhqsoi53#$Tp6_Tx6Rek!^-V zwgJ)U1(u?wc8O|D&xbjzM79|c*#<ZkC3Hy%|zwn;~Vk z0im58nPv&i^0Su3PsK4n%4{>F%r-;HYy+ax7B~39gUD9feQRlsWn`+XM z42f(rB(e<%?d-@jOK6rN+c*YDWSb$8ZH7d)0nurTTan>GWUGzIPPX6chcu0#(~NEW z;d~)O{&0S0KyZG{4B*@!&W(G}ky5^Rdziz@^Tmo&r?9HiqdW)ZPGMFmoN5{&JN25L z$dK3cu7FrmGl-g2oce^v@i32?R-B4#!-`I46kCyPZ2E==r?85OhEv#Cc`*JJ*#-os zC(QsJM7D7Z(3gyVD^5kW*-B&^5S=cu1P>zHI2JWMpCOTLhD5dj(dh-2qNa9f1bKsIM=t6UF8?IHTCm@ioHEr+d{7SW`-VQ zygFHT7YA!oK3Qf8YWWwrsKogJBG3GGaoZ5#un%r-;HY%`?HHXu4}=`ENt zTb9swJ+pnjUr(8>PRp5XhCE-qGaxuWw!jjqC$f!WfIMHkJwqbf42f(5qSK=+!Gki} zI0i_WZHAQDX2@%LS3q=nf~BabU4mgCq|7$V0eMaBoWja$T6H?3*ebJCZ1XgNoaSkS z3^|3J3kWqmd6p&A!6}Sv!y9HEM79|c*=9&&8xWl?u>_|g+c*YDWSb$8ZH7d)0nzCN zmZGM1iE2&HhdHc7wiy!H21KVF#nfxc5`Q(^{<(+$w0~j%(+)q|xa09ZyL1UZqi5R! zHgeG{mymro>Txt?=kd)7O^(Lw4AVCuX)a>{}T%0?L zdR#y6AX|AqV|Ca5wT*TAwm0`&+gQJE`_Q9#4?hdH;^%>1*;s$;)*zSb}HUzQJC%pB0#?Sbp*>LQr8(#vR+?U`-Mc$Dpd zZA-Zf+P9?oqnb4n^v7Di;{-blB4OLX{TcVJfWSH1rWk8I;A&}98p_Ye)*v6sZFw#{ z8stOyxv-)~+Y{>J_);9eMNadHrPlAjudROXp2qsu3|5&S_x;|z-Pk_(DfXpu{}^r@ z_K&^QIwgLO_#Q@jHOd_rIk+CVeW0_Z+Q0Y1WB>k*236~KAjI1?u=BVkN42RlLeEwG zj-G?#6;ywC;(eUINl%F=s(?Q0IdWF7X{vYnq=s_J|EATpe)z6aX# z(^m2*8+f^&$Of=Kw!Sih#&7i4Uw;ZWvexskQPvbh;+JlHwvz$m@N$lNC^i{Y5Pcz- zh4{@b(26~UytKPzC$MZ!cG>W#4DI39;f2c z?$Ndpoda0wd6f5KkU_H1{ad2v(UV?gNiQ3F=ic9Vf~s^S-^70Da=hamjGeaqe@VQ5 zKFgmW?LXeJ*%tXMuVnkeJs)i{SoTiA^U)zM(`uL@waluYDjluHY4v2e?d*)2aW%ay z6SZQCA3SceEqvb9tYegk+OjQrmZhc5b*Wb*EjITx9nHd$zWnRgMJMy5kEQ2;zDLh? zs3&UaHb#zB(UXXLOZp$rM!v;7yJ!2eOm2{Eq}Kar?6@0&*m-ZM_tEnnTB;IUvS#7g z*8f=5^K(-A=$nIVHPW&1GxQkP$;y5GwY~>i{>Kp%Oy(k5EQzx?GX?}Y9If`HGmY6l z`ew{`^qvpfm-S}8HToVso1+bFS5}5L)BZRK?TVBt-X2!pzWR@6-Fy=5OG6pr z*ilnMY-eXcKa6b}(>B}il?JuVHd6U`W+|Kx1EW0eZu;8A(Ps2WN4|X27`G!+G;(`O zC3j6%?7Phan&=Pk5RA#S0K3e|iBHxAF=KOFZDwP{8^^3;_- zO2()>mhXF$wHHQ|?YGwd_@}P_(SH0rHh;6_@QWWp3mn)q_un?1`o?9A`Coz#Na&Sq zo_nD3ynV%{!#@twCpMjW0;Ydj>wkcoY&lPn;-hR&w@JM3tHv+g$^F+29cG8LM*yGr zehO38iBd~1UYF8~*Tsm`uHtnu9z8=EnB_P~KDFx1TM0E<{%`=3Cw(lihX)^GjpWUX zKUKH+J+1r*zqdc0Tlq07@9^WOkxwc=VdzwxRe89Gy7YgnNE6BF5yk7WH@tdXN-tiQ z{ZW_58>~9D{)fM=J_@#Ai1JI|4Cy6shV&9RAl&C;GirHy3Ct3l=9j=S&o6;9q?f<} z!D+4k;k{Weff3VM|D)FbFoJgqn^HF`3BD@TVI03`@*V|YTk2iwe`v*x;^)6xbCe~F zMp|(b#{g-?O@_4MCPP|r6A*c^*8i}WYQ>F0lZJ&_|3e$&Eupi7Z+XS2gBp{07}XC-v`G8dg64Rcu8)BXH-hV1#iORB>RU~Z54^A)FF(~48CX~n76 zbVFQ+HRS^RvZhul$jS1;s#J$l*rYrd(K&_f2nbGV{SS|+GFxr`_2rFt^~!KNh25^G z<>ieTath;`9?uC$VGAt5gXfDgaSV_z8mu_=e9_LqZMEx&Y~w^aJu0Un+c*|AJ)R+v zZH7d)0nzCRmZGM1iJ}f#-WcYvQf8YWujyR@(dmrZt1?@~Hc{9andi(lL&|Ieg40_6 z!*7%_Tg0^1|ETpptnVtbRX59-ZHAQDW=NTBKqksF0zedfJC+# z64_=*WE&8j9%Tt0M7D7Zkk|BhhD5d*64?esrzcp7n%X70$TrMjC9=(s$TlE4ol$H> zwu)^gTbXCF&5+18AULh{Km10CY!TC1|6^S3Oqs3PS<1mjGo;KmL&|IeLOYus&>mOK zzG|y#qOi8i4N_*CA!W7!!Re7nme7Hm!i;+ga&ii*ICToMa|$b`upJerQ*tV@jbpfu z=iqxYB(lwr$TlF>beg58sa>L|gUB|_VI{K7kjOS5I&CSYB3s4O$(CDu;Ynnx(=yp+ zNMsujoF7|Y2_8hYaSV{iHbWxY42f(5qSK=+!Gp*)jzvw6XGmn5A(3rBbb5lNsHt6| zi)_OjRwCOBiEIO+(;3B9WUJU_vXyxz+YE_p1A^09|HE&T$QCiJ^*_ed&P29qXPIm> zB(lwr$TlFfvsv4NkG3wd)mGI^wldFTn<0^HKyZ3wk|j75*~T$IBHIj!Y%?UX4Tw&s zSb_(UZ5#t6vdxglHbWxYfar9ZrKqW0qKj<999AOR42f(5qEp+0A2qcSS;kiM*7_d| zw+{=)6*U`cM79|c*#?Bz*7_gbUO&$#u@5aNG&ZnkOL~U1OEN=`+ldzgLQGF~w9QOp zi&CxsF|L@1Y{iS2Y%?UX&5+18AOw1LKzm$8w%V$i$yVl>Y%?UX4Tx-0>wlzSp{1BQ z*-EcQnXRIhGusS#zF6yjq$%qewO3`fifztp6~LU?W=NTBKxCV_HLW^rDW+aiE5WIg?eqP5B3pUNWSb$8Z9u4Tt^eTx6xpi1X0lbZ zGTCNGWE&7-TI+v!OhvYcX|4Zp8`cIE`X9IK14Zoo6hA)CkH`6O2_Iw6Qm@2$5@8o#mWz`eum1E+^=f5zWY@~TpQ4He;VRm>wRFPF89#*SliK(R@2?Eb>Z{3XXrjY z*v{L=Xbee7o#W21f>Yni>3PP{I8cOq{&k^h6dCtK1Y z|0Y|vMSlx^@cAS74dHu+vDxe$zhBu83ZtF(^5X%1I6Gy2cxHMZ=f|4;xvu8G3Ej`8W=pk77J%KYkAy zBHJSp7W9nn{YF)Nj~C#*(YHe1qf4Nw*7vYM$MvyHxx=^9IOo}BA{%sUMQ5^#?J^JB z05zlLU+a7Lv#qNhoU;M{0%L;#!k%z<+YY3pL1H_Q+|YJp!O)*tJ2B*I z%Qs*$et(_w0=DsMn~hI?p9c-)J^Mk{DGhBVjf~pm%qV-@mPRE$I0Mw8UaV z^DfVd%kx*Sr+}Mw{csXhsO-LP9IW*^$je8T(ALXwZv&hAC;0K+VnFj~&09w%uWK}~8=1oA#K<&0-#sz|hQJ^1sr5Pf=yQy%UZ3OrKhgcX z94yi$T|M*UEY#Z5_{wK#c8s?Og}-Ee@_rS*%p)f|e&lOB@*x#2abz573|%{PZDZ)V z?L)7`=T?+ALpt`$9d$y|f2hbFSh`4Q&zCk1{=kpnN_=D~QX)%+=>6$U#l66s(TP91 z`jZdK_Q;y%^XxTip3fVmmAzo?r^tun=?U3h>H4go4RiL?<%)fp73`|ZXq3G!_MB~A zye_4eTD0SZ{>W@kGxqW}D+;!d;qhka%`Ho4LjLBK>l1KDZ*JLId5DlNt6s>E-rNSn zwr>V7|6JMl3lF~1@AfcDCo<$UEhg*T zsTo8~D^9(p6{lL0n4Nk}t4?PWTfMneZ1bC2dB|^WGo&}S0g*M%vV@xY;*(As1LTWO znBnk7nNuy3$&fETITsL}F0lj;{yx-7g$FH@33FI!nM{VfrWXUE(+ey`O_$VcN(FBzxe z7$7Z^$&i-GWJt?o0;1Cvo|xGqM7AuE4>?}n$>kY1B(l|MnQSv8vJD8%k1enS4B%LMS*#T~-#eK2)iFqr*JmrgRnH%K!;$((AU)&K8oE|X) zIQ4wdxTkRH`C`SX=Zh7mo-bCNPVo|O>J(}wJ2j1<5E%(-8X-eI;c+5EKH+g!Ky+#baOx8tb_uYJIaOvG z=CBgkW=Lck5S`BG4Wr05_Cv#iQ`i}qXR^(Z$TlE2J$aTTco5mfF+fgX6{jNGY$dV{ zh)$Q}RAd{+qNe9FB(lwr$TlE4y}(k`)GkplxX3olVI{K7kjOS5I<<}SFc;Y(rnP8C zE!vUER^2R61a$X2n+XM42f(rB(e?2$d;v&Y~xr-wiy!HW=Lckkddw4f{AQdVoGPL5o*znM7D}rCff{& zYy&c~RcuAJiftxanP;-ikjOS5BU_em%az&2F+j>}Go;KmL!K|53y4maSb_&-ws8!Q z=iuivq|7!$Uek*K(dh-2qNa9)vPEe%q8<77BYW@n``O09 z-{G>e1vYu=mT$O7a;pdzyV)~!R8n*0hhIP(2`{9e349l-s&o0IzsJ=Sa6wzL_<`AK$-*m~_= z%d1aayu5Mnw{RK8pY7vWT3r21)wZAEO+=Pizl z#p+gHvtq%EP`0o%3=}s5N1NVx&j3ocf%%sBJ>%Ydwy(N>8Se7VW#01pY*T>IPj3?Y zcIk0&=a6Y`RQHQ+_5RkQKVLDh`S8nUSbg6G#%BBiY_G6yv~3uF*`B!FEBEKOB9uM* zGu>%lgI#0LqGjkX8@xr!eiC@gxRuSyqIDmw=6SDpzZaAL1>)0Q5mjFi`S>!GV;v{r=;2 zH&!06-q3Hnvi>v3TYko_QTF%LNuTr)#YZ*sWqr?mr4H|79s8pDvc6|l(cyj3h;{!M zSL~a$Sv$*aTw~1})uf~Fn37VrvOb@ZQXiwt*WS|CG;5O@s9B}dv{ydWK?f-FDc05U zsbk+P^ilfcQ`cAYU~t_^K2_z}EzmAA{jw(Y%Ra^|BlH4oUo{he;yLbt{Pa|)mqkv* z_Jtb{y{F&u``<4gYB4y^Bp*7>t8_izm`}@pYCVnWe)z`v%UwU{nd)WqxSzAkZwIU| z4OK2Ne!uette|^^SguXe#Zfi8H-2TuLL+^lHX|wS~$1XR_4&@I9gFI$; zeY26kSsGM(y3@;p=46s*-c1|-IeK?8#A9w?ebu!pI%sLkSWHeGrx|T*AwlkB8oKkn znrGNym6|;Y^RlClmS&dO;(V`KF%CIv7+bke##xBOwXA|)Vm#{4 z7d9TPwte+&T8S^BJ+Y-?pE>RcZylRfZZzH|i0#~LEiDa7-pEo*a2mHq8{W8`yC&)D zNT<>m>@M%J!NTorP}*f}O`}J_^#|^08PQK*8Vy-<8LvKk|I>-@3#!-mLP{-uA0)qj zuAATc>Sq|M7kvJ*mHC`nM$LFmXco`6O@F@S!QIyX8I{d;Gq2>IyN3CBL%*kneN#AW z-Fmd__dBg4k8W&P?>C1nnz8$g?y}x*w_rEJJ$i$M+a6$dO(6~~Oi?nlw;c25_dfCb zQN10UmU z6gOak6S5uaOtxd4$#$$W*^YIEY{$AnwqxDzjvPhXzOJ$EeIq0`{PBU2j{ot&5pr02 z?t%8)Cnx6aZXbHr$OhD50-2g>ca_l+#U!Ir}>ehB{z z;L-FS`0u7Qr`nA_xVw#i<~}fTo<~l7(Eh!wG5^M&@+aH&+`C3NKc(kj%2IO3TB7xu zi|x6OkRVPiU9tJ_NU8nudzK5&zy=rR;mg}&2hB};?tJlNJb~(&=fgKWlHh(HZLb95fa7^ECbV?~yJ`KN0sA zcjLg)^L}>UwMG8O*!c`u)9%NzxU1I>FVBzJKn|Q=)3=ep_2||7z?+lCjc4)yr@zB1T8@W>$3>h*Z(@FKouc*%CYO2F#{2$%EhvE7(*{PG&qSK}q#AN(TM zt1ftZUAuC7wGniNO(qz+XNJaH?X&b)wAV%J7~T0;wY@S}Pfx5Rw`cQW$&x+U`Pl32 z8{dD~GhBLQ)z#kVsD7VNglzsUa2ngR&tTbD=#RbC=~PB-@r-QK?7t-Ishi@mO7{yWBMfn@k;)f&5P9E5Y(o`q0O{NhXPd0WHh%6v0xZ#?kKbk)eF1Ao(5 zCGpVg*bJHn@7(+O2N9E;BJ!aQ5I#OGfu;TuQ_cMM%O*L+zrJR&Q~c|a7)&Ztje|qA z$P{|ySFJ;&X|Uo6^y@s(C2vm1S+wlB{#K}Df-EpQiI$_cvaRUwKKI&=vQ4=rFOS(( zcKC6UiP6&&hEByJ5L=DCE~OW*%XE14y6lg-gw(ZFXOVd;kNHX? zE+@qI^_A(jdqb^7rVtUWq0bS~N~3_RlQWty*GePBHm@|2d0uIhA+0nDh&*9K6`X3N zQ5*xLl|~uTN}~*ErBOh1y2KJZXr)mc1EiHk8PZCl3~8lNKy+$DVAOOejzvw2Vbi|8 zRvKk1tuzXVPCJUJRvMucB2$Au;*HnyHZ60qNrL%7#lB3s=J~kDrf!f;dCU(5ge%RO z0qR=KBh1`hhE<(DZ0u5TYE0DSbeNZbQzs)U6?O2Mjz%3|W$EGkc!s>De9rXBv!-Sc zHLW=HnpT{8O)E~lrd6i{$cf9ETB*ozJn7-Ht@8*jZEUqTnITVl_@wJrsOb?ifVpQ< ztvCkAm}{}()X1yq)c9+$>U4^3;K3=(O4XX~&DZgoPG`t#x<4S+)C{7g6{lX)ic_y? z#i`e{>a?YpifmazO`UAjUPZR5i>+()Z9oeddWfy<{dWe08rLFI-U>vviftxaMJtnS zhD5djA*LtKvV>M3vW;VaM79|c*=9&&8xWl?u>=ny+c*YDWSb$8ZH7d)0nzCNmZGM1 z2{bMHu3ppgVGb*iZH7d)0nuqk?Nwxp5;iQs;-!uG|6>@}!xfxt2mRtATg5(;ZH7d) z0pUusO_oqGk!>6UB(lwr$TmYF+kohFm?d}+*~T$IBHIj!Y%?UX4Tw(1S&Ew4B^U-m zBHJ(rB(lwr$TlE49k@K#)Jkw_8J);h=4G0?IGG`lZ9s5(#0*dek!>6UB(lwr$TmYF z+kohFiY0gu*~T$IUemo964_=*WE&8jPO}s>wM!IVUt}BRuoBs3NMsujowgKHku6Jb z>SU|-DzepSnQSv8vJD8%k1eo-x_r)vcqWbk@@+u3XUOwKJBL-^iJmX=C*`bG_`vQ^ zIduxNQeo~jtwp9RS}9*Vs{k4#vJD6^{q7K%dg=FjGjXz&XphKN?K+cfhD5djAttj; zme2-8ws8!Q$TmYF+YE_p1ESMmmf%5T8^-{NY%?UX&5+18AUYjqDQaq$K##~|8|JVQ z*=9&&8xWlia7H<5Y9%<$WGnMbwiy!H1_YA+ z>PE)k%4`Ed&pLU5B?QoO@TE8gNSSShl-XuTnQcIH+7SmRvqdRHrcQkyu1A*PVwj=t z@r#RW)vhzyW=Lck5ZR{566z|ljbngBwiy!HW=Lck5SzHI0i^$n<0^HhD5dj z(djr#QB%7_7ukk6tVFgM64?esrvnmF@S0kwi)>|{$u>hG+koKo$RtasgEHGV21uE0 zhLqW6$n(V=0nzCcOYoq~HjV*OW}6{pwi)u8?hlAgr&)@c+9iswugo^gVWrGALtfLW z)0Sc?vX#b!ldamTGFy4dnQexY*#?9fA6sAvbx~#;#{em_&5$zN3@Nh>h)$2P1P{t= z;}{@iwi)sXj}sa4n%)%UfrWL1N)2h=M#nx+TB{(&5@`v+^ z9+XqqSzRYl*tvjE(^_Q8@4m7um)!KqA`=iEJ|@vJHq%hgpILk!>6UB(lwr z$TmYF+koh_7MZe`ifk2{Otu*k*=9&&8xUf8WSS-1mCy2Z)8bSd1EkD0L&|J3q|7!T zI&JAKm@-?In9|uEFtt~wu-kQ7&TKQ}6lOn@WjP_7A6uXSs;A60n>&S7oH~WsIpzT; zI)zo89+gv(ZFVZM&5+18Ln7ONSkn_MMNRDzMIA)8VGb*iZH7d)0nzD1Gr*SDP?S`eV?Y8o#Shm&OZ`#Y_e}xPD z4Nv#tmr(o$i?>Yi=-;9Er)BYR6#v|=HOb4I;m0|ax3y{gAP)a^S;S9g`-<~7wRrRk zDE~+2No2{+vH~SQp3Z?$Hy8UKPWygH6f9FrFL$|v2Q+wuxe2s(Vs|FD}+x@h2 zBX>VZ4+vPXu?(!YahOJD&3*_*J2#FKIA=hMz-RcUOZ(WS=o=>KYq5h0(DHseZ2Nh9 zL#AyB-)5`PZ(xhx;SPL<<~#41!Fj#+zoz{jFDv$YST*8%VE3H%Ynh%w|NX8{vUiK! z0eiQwYs=dI0NVK3WxKUtGj_G_&0?L4{aKBJr_oHTeQ-bFYW8O_j8Aoc*3H(C`rcp0 z)$-M1e-^LMBx)&Zt+#=A#1?H&Av?H-#UAX`3`@O@)c&gb2iXYw#aa7_R?ydYl6^%j zkYgUliqYw2>_m<+kh zm*Mbd$qr6iSwAZAMY%r_S6p2_ZIVE~+0|<@$ST`I^CKXYVMq}esT?o*>yzZe-8@pw zfD@~rhPFL-^k(0mXnPYarDZm2T;qwXk&Wf7We(ewvvwt^ukx(aPOK)RT^Z=BEaf!2 zO1c?r_LP%L+_-|}5XUk5hGRE#tD~obKllXG!B)zb@L*BogDoCuKYkAy0P?@zM*pei zf1B4l*p>Pf+8Ni|Fg=6wo`Sx>Y85p~w%qrNuCHfX*}qkK8L2)0Fup%Vy;bRBJV~xK zfV!Ex1Jx$vC91FF^j3l(QTi%M_ptQ#DU`mB(x>d4Nt8H8(tJxB ze?0>HBX&*;rN>bEq*;xke!__v|MHAL;oX5C+7#7=029ChQO|cxKN=wH20CItdiQxybp6#=#fW zA_*A(>}BAV4J4p5jPq=f?)#fSE8$rA)~Xgs06S^5S__?sk@GiYdcM?~GBj5^L~DQl zWY3wjCZsoIVZ|nH1~{fSWpNCU-jroXZ^|;HH)R3Q=~0&8L2t_97$ChV%aGobWk_$z z0;1CsEJaO^#<8gB@eJurS%&ncEFe0aVKk$rRzkG$n=+Z_H)R>po3eo5v=&M5m}*%9 zN&kPIL4dGtw-!m@a56uvKFm4AV!>^Od?ty*sBx#DzsVE zGq9ZNWCi#Wp!ob?Or|c203=f7xGkIwhz6vfoOD`DsRE zv7%?-HJy%Xp*C8U5D>n8Es~%$V2Z8CRw2r3z%nGV&5+18AoAh~mJoLz7LLX-Kw6fN zA(3r{M79CZsclq-2d}A>y2w`MnQSv8vJD7MYmo%MQ6gJ#KrNCmE?)H2YQy5iOtu*k z*=9&&8xY!AEs~Ijg(-z54GR_J1s@isvz69>1%#N^A_>mmCm58HY!xD7aFK0>M79|c z*#=}}%N?gB*~b1;K)$l-jLb9HW=LckkdZA*@SrtdaSV{wfMrN)z%ryYU;)wT5=-!) zHDGZpYI;6HzFO@6qBw7VgWA<)|0 zkRf}YH9wxA2aQlS1cX4>A_N1VZH7d)84}qBWMs<{Zq(<=4Vq1aK!Fnz(exfV$%C!9sL3X)N>$TlD&Tg6nF zZ5%^PeRg?ohLqW6NSSRwbXtofAln4lGAIb7=4=(BJdKbcWwseoW*ZQl)*=a+Y!w<~ zaFK0>M79|c*#?A|)*=a>+49{r9%wvWu0;~8o#_RcLX$Jw42f(rB(e>Nyg1Dg2ti~U z$4auzkjOSeBHMuIw51)Jnnuu`PoGARsE5Dfzg?#p0eQZ-kRi_(?e`uz4`CE$20>xQ zJ$4L`Kb%*bI)zo7I)zo8nt}m5D6`FV@S0Zi43ybsD`mC;krz*}6g9O=RBKvsDzXg^ zI8kI95S`8_wwgvzY*W5?M&@}MAw!-oo(l+0Po8B77xa9w6UP8Kg;kt7h1ogyK6V|a zu&UD~IaOwxo!)DC>G=#Pv(1p#^kP7)=>?Xergn*<4kFtyhn2`SLn7ON=(MAlDzinY z7D*UaOqAKGo#i>(3~A0bLz=S<2!Wm*(57>r@URl@UZSwJ%nfo1o6L|?*p7hU^oSYY zW;=x$_Y_XG8X?SKJ(OWI>mEfF0#!Yv>G8pBHIj!Yy)CVr&)@c+9j$r-5cgn zQ#+@y64{0oowgKHku6IwuSF6(3=FsCY!$UUXPY6BZ9s@^Es{_nTZJZPwiy!HW=Lck z5Mp|=qxLGYMTv{j?Vo%2Px~hZFzwJKlEB|r|L&0$DO*|{0zPy4bx`Tc9d;MO`BP5JoR6?I|rlDSB=L=>c1|RyzK4rQtl#k zFZ=yCyv$l1P;XBjI;zqA^zE-;ZqJavf+-eEo0Y$UxihTbblW6P_r&RF90-rcGvpp^ z-7+GPJl+*n^f*;|9MICXlr^1^ZOWR?X2^4qa{}lEz0QE z%1^0XYJWee_#MBGU1{b14)8?Yw_oMsV!!RGeh+ljJo+jV0RX9y3kyC9trh=y;ivFB zp!O^92TnJaafs;%kwY#^`}6Vp#AqnkANy9Y03reY;6s=H?l3!0@yqZp^k0T2giYp| zKYo=htv`S8jQaPnq42PQUCDmfzN;%SLW>uQZpZL@M|Rs5!i)CW>i7HD>K_}s`^QRg zhrdB=MYs0iEw4!+Fwdn)_4UdM}IH^w_`kUzj0Q{iXd|ON@{= zbjI8oI-zZB-d#Eu!`zn@Bjz7lUztI@Y+&j?Uh)Dq9vVB<`W9@<>;(@q;N`$x>s#1l z!S0lB7#)x=7^&T5W@1wn+0e#$7~129={FUdcat2>4gV1NqMnbc<0)IcwNua2d{pI? ze~@=84XsaE-(vZAniSlM@f4~!sKJxzSJ;3`GTK&oD6!{`@-d|Axg%*(R39?lRDG(* zA{X|=P(DGtDugqN!5NWRSriRX>!n+q#GpQ%*MOXOa8H%jVNR*PrDVrJ<+7R>F15#I@M7$yPc^!<6)! zRZ9A;f%@=ixqA9ZY42l}^t;t`>B~A;@?|~IcQJKTyE64h2V*5MAoCxSJxh91{l?>! z;;ejh1-+@Rew2DnMNg_vAMq5kS9*yM6fJe-#F4ENzb_y8;%}i}wf;sySsO@=pWw%Pivj-QC}DOU;UXJ}vx*_S zm;T1`_U5uBHhy>L%_mQM)JB?bs#D$i8{XC`d45lQ4O4kRD{Q`H5Gojd9aXtU&PK}tqN9h5U-c%}Qj7vGgH90n*bOBbBK5f3KRN>eGoGKh2Gu#wCs4GK#4Ip^h zFkKn`*+W~y##9%{>6$LPGRD)NM*36ecNXL6>EJI585pU*jDxlB$o`k{SF~?YJnkd! z1EpqgH)c6V@ZP30YV$CGG^lR2kv{9Pf&GN2E`U>$w9|3Jl-8Drcx3~7S z%f_{`CGq-r*lYFC=j_p*s^0^TFdCn%5%t&SL_K=w2lZ(|t}Dd*obE9^7|ZpUyx<+Z ztg7b`0e{CsTPsF#G)|_j?Fi zZM#KJD4z9)Os?Se6VMu#~2--eDG(ZB5iqs2NtaaKCAU)1~`o5 z<+A9l0cizShP0?4AnW1aOOEVX!Nn4s+FNyB7gfB@G04|N6|Zv)@^w+g>zr@0Q`CAg z9#btUKul{rnQ^rH%VjgU3C6zs?8Ac`Fs>_DXtwG&{Y|tj05BbE)$i z0wOP(LDaP3RGDp2(hj8WV{o6o|N&SC56Va zcx?pBkoG2INP80kLQGF~)Lxa@qJ+#A=>x>OPJN#fg0Bht9>2I#*r3|AWqVFx%?vq( zRi$6d03AtWo6SYG84}rM$SJJqbeINkDzeSyBHIj!Y%?UX4G1x*^<+GzB3p$f4GXoN z413`FZ&zdzg)L-A(+B~P!j7_p_Nr-wI0i`52pQ5eLWVSr5D=Z7Uy)01aef>Wn3hm}*9 zol{sjg`Ep4I$e@er!XrO=03Z8KFs0NXO}Nz$ZJ}aeldfnX~n6?HhU1+W=Lck5NlfN z$uK3}AlV1c!D~Gk>k%Sbg(j12hLqW6NSSRwXlF;JSwiFeEO}~iDvkkCW}6{pwi!}p z8xWngxPcrVl-X)Kxo5WD>xZ1eZr5o>Ku%!`8FC7{GaxuWW(IKX6jrcJqOginr?84s zk!{84QI_CTWE;l-iEJ|@vdxglHXzpY1WQpEx;}{@iwi!}pn;~Vk0nzC&OYoq~HjV*OW}6{pwi!}p8xWn2vlKP8 zOE3(Cyr!dJ4#;b2=M+|6(+y!orvrLp<2AJs%oByRWuB)IGUODtBOo|EGRYF^;1t%1 zV}LY`kRhiqJEyp`Q&`pMl$?revxn10m3uQJvdxglHXzn?nx&|zU81Oi$TrMjC9=(s z$TlE4Z7HTATWu$IvaR)G7;e2FQ`C%qMYb6d*#?Bz)_OADUVT_tQfTrtLWV@P84}qB zgqYTPGNh0B4eF=LY}JQ-SQw6DXuKlZ42f(rB(e<%fv)vrDrBqB*uWyP&5+18Ln7ON zjBE$psmPWkFu0TL^Zk%ATb-6O+YEWWcxOOln+29|%az&2v7oTqGo;KmLr!5;r$^;f znQb;#W}6{pwi)u8-W3pQdV-~>sa=9$NMsx4uoBs3NMsujoz5t>%4`+eJdGgpoY`i` z^Tl%k!Rg7fETIm{Y~vUpWwseoW}6|Wu&UD~IaOwx&6U|^NSSShyrvfeVofiw6g9O= zAf}mY!yHy3+YE_p1ESM^Dta>buGrIzPv3ojUHkZZ7gxBB;^(^Y`4-zrfZzDW-*2C$ zE=q?Vf5H#j^!Pdc^%wm3TYi{m%O$Kcf8muV?xgX~Gc01$Ae2_l(B{Fid>_l)xADRo zxFcofS(g8zESLK#p^by%=Xm@v9{2L6S$=}$jidO}&Ua-OEYpSk{XG5!9{2J`S$^33 zbA$cPkF)$}SuT}dHrnr)FVX3FJKy$s+V}oyS^gN$|2oSXZQthw+F!&-weER{*!t@S z`R8k!{QI>-k6zbU_aYdq-#W-Yf3C^De{Sf}>l^Dvw(q&VvHp$Q2U)mjdy}P`whukJ zv9a#uTlZ{itlx)oP`Gt#lcig?4#DM^-MTTmbz^qx#_ZOO*{vJ1TQ_F6ZtU&TEAJ-# zjZK$6+PLGr5Q?enZ_s{H=*9dZXW44K80H|gUd#*U2efo8J%XOmdgSy7S}ZU&$RF&A z1;%Mltv`P*<_VmrL9L#gNf zb_^5t{9o*IM%fC5{*;YF!Z5N|Ank^f_b3$Kc8?(F7 zUClj>8?njr#!vU!c={vQ6Z&Upz|EU0`%d3h*>`$dW#8$Z*mrt!W#8%BD*I0N#J3RMXkrI?qj>KBXUKVo7mq@eH*B@l^Qpnz3_Kz*GP1Jfe>-nk}@6&S>$KR*;%(QWcj~i$CaSoAs3eOy9$~~VRR(?v@Xio`$T>%@N7aOuFo$2jaeTq_V<^14P+1>=E&zyu1~m3 zuOal>%oEe_9VVf%(K2|KB?ETG4inqCahOJD4d8S7&W)Csv5UU&Rh(7X`5FG{soiOo zZ)cftQjU+cr5wQK-kOZWujWzCI3QrnT`r}ZtYP|-pXnc>Sq&I_n#kEy$0k)_#ViIR?dVrF4Ny*K6F{+N1;#iGk6aj`49AIBHwv6 z_hsaKhk@;v=J+;w(|4%#Xk2K<9um;vC?hg@WQjQnNAr&|Bzo>l0-IG@Cw!ykoyPq0NF+P~76BKZEF zfS$`XNaNf{`J3jI;8xecVZg+xy#-x*^68rIsHV$8`VaapO-{P$neD6ts|pte2lkI+|XFJZ={7e@R3O*3fGNH;d5eS8lUeTnE_GZkN1o$ z_#eMJa@7BL-^dC7;{zid|Ko!r1U4XDEe6k$1CIDvB8{(bkz zB>rt5df&(n{yX=+ktLkCEi}8uiK^}AAFiU05(qMK5)uFk)efP=H2hGVO zQ5!-0`PrRVD&z*1!?>1N2Tt-6usgFX$x@^DF6b&&soA3{`G_>i%emPJ9q_8z^cN~& z)4;nellu0IZx(0%q{P0L@l8sEtxsJ0=&jkj^!YXY?>%P3o~`lk)Y290H3zM2*|>MR zO^zQ#IMGfE{j*P4qd~jv)gDbMoZoddiI$X}PhGscaqwff1fvxBn#GH)VF*iKm;~Ef z!{?GdT95l*{T{2J|zYj3vB&hE)K&ti_9 z)@es?m?B`(=DYl9$EE3RIp*WPk9yYMei+{j)mW82TL0MUyJD1m^6~c6(&c4TXRN;* z`0|>Vqy24cM(i4YtNgzf{Qv61Yq#;tO=G7p4sa$n#)3OAb-V2RUj1*DTImd8-~QKI zpS-wHje{S+uwzPjh+jPKGV+!8V7!3cN8|HapPcCegH+GwqTl6d+Hd20ZppWA(0FSr z1HVQ3<=kc| zq_r8>0Q6kdGREY~rasJSmPF5s_?lBIp_b)Bi09UPaM^#ZjsCMT?{C3`>__nbJuB#s z_wOf`yA*8${RADgGGAQG3Pm+Nvgw%VD%w8?wOxKmA>ScO>_Tk)2VM<)|meybXn2X(u*yZ&tB}2=Lxf#3NM~g?Txb6Wje~X z7A}dcrk`RnowvMZv8CA{?tDPA;8e7(q zt={v}!sTfNsigTXbyYJc$bNAun;Xa0lC9b#rO2f1TqiQ5O;Q1o7tH{%71_oyK-!U- zA(3r{M79AL+2VmUku6JIWGnMbwiy!H24rN*5~`(5QgIBBHc4ejo1`-2TaV5KM5jwE z!GktQ#W6tIB$Xj;lFE?R^kP7CdV!^=sa>M@`d-uXVGb*8lFE?RwCc2@n2KysswG=% z$yRG;o-a zXlSjx^!srLbnY`vlEAdt&G|u|#X~&R9`5Ix8M2wuTC%kW5&}Itz#S8amL>#PLI4wm zRn%3T!Yb;jPGMDbRWpE7r?8f8fjM;wt2lKEt2lKEt2&*c8#oo&W~Zk)eXv+dwlWOw zzg>~BB-Hc8g$#MVcxOOp1;>uEgxLDSxs}ig%!4x9Fo)I0>^dhhB(e>NPR#)3%538p zAZ4~0Qf8YWWwrs)>5ST|rV-R$6NR0TdCqJz

%;AUHjFmL*h6nQa^cq|7!$PGNQq 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�<6e<`<3gIb+>cRwtsw!)_LXtvglBBr!E+;AU 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

{%7p( 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�`3 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

VIhp7z{NRx(4?V~K)fwoo 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

D`+n=x>CNB%4%um8r4(NH#Y$b*1GW(RU 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

7n?Y4!!@G zmp>c}y?5u!kb2M2m(K7Bt^WxYYzn+*ruW{-Nt-^*flo=MW)JggsCQS&2TlowNN-H} zz?uIRGyg-%3w}WJwZmZ>6r0GCyuVJ2Ag|!zvTeL?7R$)%ynkG>_VRmbF@jh1@NyqtZI!GE z-v5F3yX4aiyjL*T#Y+~Q4ufdb8A=MF8El8>f#Rf2W$=*Pj zY>4Dys*UH7KV802pw&YZFMtD}hd*-Ve}Gmvd)`hAIOpb2F|cnGcK1^Gy*V^pes2wh z@q75}@gD2@A19(Bk7hn!ncxK-iuzpJtKRkYbwwa(T(2Pff@?lB_VtH7)^!KTKZKaP zBE>rKiOd`gXD}(m;uM34TquKyTq=W!TxK?yxYNyZbXc>-_avQJdx=UVDiH&sJLt$-TCTy_4)CSYsYl z4DLKeS=@O8!{bbzTTO*eF? zSVRuL?E1odEpk(WD~X=l!8|d8%zlG<0X}3r9A)3Q6sX-%_U-~Ruk9O}1`~x7=)LFC zD~?n+bMO8|SN}Go?v_~R81)}<@K^mpp;rg!NTW5!VG;5@{v*TT9;~7?gDR#h&3Foi zdXk(~pWmL)}U)*^qCgD#zdp?I{c0x%4<2p0+=mEF+%^i6`hU}=vpnW zjt;(067~a@kraK-0lBqN8Fb9}`=!9UQFI;9z-Y~s0KNA2gK+0HdmW$yA4SN+>$tZC z%Ezq`QY3~gT!r(t61&>*b0#PsRzP2X_#pKQ*Y146A0U?kKDE915664#&AXtSb@6cv zOUAgT$V7)t|LU_RJM-NXVt;6r9^Rhp5hTuY1c{kq9m0At@`FoXpan`17(8_5G+Bop z`($SQ4=gC1qqLxa!R*r3Li`^6_8w<`y!6KyQrW%H4oqfyPa6I4aJz>7)Y8j)1Otv@ zTovWP+^cu!v=Z6@;AdT5nJE#xny z6vu*Oh}m$SGlq(>XNSjdGYtDimkyVAyB{_kkG<1j*`84=BYiz#NQ?u!z=rT^-gt#B zzh=PXon&u!;dxprKcywqQQF)6kn6%K#s?gdV?ZAoFkRca0U4M7aRG$dNRKDfu!i$t zS(YN1^l>TrZijy{_L0%?FRAlw$h6-c^-l1wNtticP=}uwwSP?t=P-oBjF&SQm7~nC zgdV0E5_-@2%s}tM-u)?{_gJ`aDa+OV%9zj0^!*6gSM~VAxay(r!`W9!-(g*KNc#np z9n3f6kALjk#9;?enW)-W8vhCc(`vHDR$B5wN zy}VbpoZY+>Th4>>N?C|7hm&bYnoMJK!67ovfbgX=&0lkvW~H$BZ`y1G6FT(n(lOAx z`Y$50viE0%uS03?b>TzSkAja;+j|8lNRd(uxI;t0<$lSQo0(vy0@fK7keZ(mw zE9?b|<5|BBy*YO*S(b${zx+x)h-AcF>ue%HzO>tEiU009oj@Y?aOqcvp8@JP~V14La zd4AX7vp+IiCwBHaTY&ffjVqwKLTE?6ECq#6vi3(nw%Xi#1niH$$pfndtwTD0k+na< zB8q)s#^=j}HWyU$ z+9t?WOEG;ckPPjlD#wEOD9e(sMGd5C7F`dA1>3@KT$pvrx%r~)u}+y=h>Jxz)+vkl z|LL*?`Mh4afSaLKE|3@Xi*j&NkI%Vr%50OeO0ZqJ1nQF#%t#4l zqy#fkf*C2njFdDFn4>~6@CRQLi`-dqgc$Up;J1`LZh_Yx_rt6`ZZ~AWAoyYnWbMhalNCoFIJ3@pX|LtN;NHPyI|O*Sr&lev zr+Ht!p7*=?US(AaN3wD=@6!AD>M6;37w={LPzE&XLOvCRr(gj3?@bD;Mc{#d4fZL} z?f|%gY4ofFJuA6xqd7z+0}Ri0>9Hd(d?RaLgY0qe@ibE4*DKEqwI{9*q7HWh8Lx6& zsX!x{>}!<#TktVe3rMf)WGZR|qcMXtssm&|DNqBI1-B~V@&P2vlDNg5Mch8hTl{hJ zB5p}95K{wJwHug4v=0yR;VaB?7vDU_TPiD-)~Er7w`KR|@qeTh&I`}l9@h$4z}f%#Ehy`Bc^-Y8 z#QkZy(kDNA?PI(?y^3e4b4{ZwIM|B1F6rlC@X9Ue6CTuQoErl*;~$ z$nJbAU7z=jG3b}9wp4qDI}Ahm91XeW6L~?p57&NCcm5C3exySXgIzMrSaNZv;O!I!2`)@Z zMEwdj7mNQKSOwTCb^JTue4vhu{-H;Y{Y3^*#?Lc!T&K#~B|{~6Gkuh18~YUC731^C zG2qMkW5-?sB)Ej=4jVv$^WYgq*pmTdvZO_jTl(NlF!Ux>x&(g9QPvZM-?H|RzvBKZ z#7q4XfIEl5QX_#xG&T^CD}+rQus>!T5*-rM2Nf3aLkqKD&Ji~zQj!qqAvHJ-zDwCm zzCz9S;gFwv^vS^DSoV`wmh7O@g9$a)FH5}*y+l8S-lfDCO^Y$-+w&?ym6wE>CW)uk zf1ps0Jetvd?Q?(lEBi;7#>;-^snCltkfd=e%g|8mW(b`-cB5z7?>hX}b4DQ(;5l^U zPxhlrAlLwc#)^9OBcy!>zbpD@{0}nCcUlZicfM0eq!}*Eb^WE#9Auo|L+PJjDm=LT z=)+G6!&kbKGCFcS6hkt@^ z{QdEx4!}P_br?%$*id~F%zS_bkBU5-$;efc;lV#DWP{6(J1Vg)I(~=`-{%d5@57iN ze=xMei0^&=>)!Eq;)e{UFN=nXK=&3AxkpMs=_KZ~gZtCsO=p77H2j|)<4A~rN5y8E zDKy{|Auug$LPq>B7PoGXwgXy^qu<}%43yxr!x!IZ_y8QFLITn*xl^WDM_H4qj`J$m zsJo$IRn&1}-07w|j!}M>-KXUcsN=Me_Mp^pW?_$)g)OvgjxQbp@U5b6Cf;8rcuu2l zDez3Bn<-}cXybRhll;$p@MZWJrDPnN|G7cc!$T5Drw5YK)O}i~Cm=&0QQ+bMlF_L9 z3=}9@>$6ul^!6Dozh;{MGIIVam%btG}ErBy703qmXAx%J>G9qu>;LvtS}5X8eu4M-U4!- za{5KCf}eN2f1DS74)OUHU`xJ9o*)BTG83Y=n%_+8H;o?|^2`fyt21g=mpze~=fbj# z7{bH!pNve$%K{W$|2@sm0F`Cqd1w#5p!UZDd2!>L(u1#PC=b3;xk@r;+pjOuBX8F|P8Q8^7N0tUsSJP z9$t#8pm-oAc)N?=(1ljJ9Cqg^QLfUVuXrWyexUeW=D>cU!0qt17zgj!+|4SIL@C zoxKh=I^4jz-4<$rK!J;!L!Ij4)=-zaxGl6%UECf@sEa#7z3Sr5P@lTk6dJ&V9lJSH zh4Sp!t)XiCMq_QE8u`6BR4c#rq3X)^KU*C^IH}mNz0p{IB=&G5b|1`%J0jit$3SX}`eRTst-~6ph_$cRz*8g*XE;z9<08k7eRAgoQOIF)|B4?y*i`8)_(5c#eg(id7=Vg8`1yS9 z(u}lr2Z6$-;_q*5T-&XigM8aKz_c2t)olyo-FevS5S$|}w6hY>3N`g0S>20d)ovs_ zVz6L&Ka#}*Nai8inou~W{_k1H=}ZcFC~U!%mW;+L#tUgEw&PKCm2bxv;z|ub2P4-`9VHw?85*QVE~GFSKZGyW*CTyuI^)c9(ozP8olJ0;Qk7E zI)_iM;8P3|@|ANy8hg0@8`t6zz6-d-QGQ63uNKZ@!FBZprd1o6+IKMxb9n1Gvb7x9 z8Wx1M;3JN#Js4@-oL5=)YJCVc&X&ruoz^WM!Pwk5jn5;2*CT;JJMg+4cmv-w{MxKg zI~U(`{Hl^qLqluqVQ6j%{yxNU;CQg*b*M176pqiEF%%dcD|kNpHixy>cG~Msd+mzr z0=TYYw`$hgvFa9kd$62r6D-axbK;YW?OgR7r?f`nd5;4-Z09Em|LnGR?6@p`ZA~8-R2GYZ#<6p7`Q*fe3KPzR!uigyUJr#Kw4b6Xb&U>O6j0js;av&B?9e z`Uegzi?ZIHm;4wQ3 zsu@K7h6G|p-9Sud2j0dIu>FDhsdjvEFjBVFy5-+dkahEBQ{1}oA4a>8c^38@A7{sQ z8Tg2_ZXKsbFkrRaf^N$Q{#-^beFS;7Z9H$g-Ks_`rwJ5dlOAV-#P`~-?L{As|7q=Y zfoOc`YC-X5SWSL3y|^1gF>#oMJ<8iVeXjHUy{G5S(I7aBjMX6z;<17hhDqto)+# z<>eP|G5A+-sG3!c%Ia@GqrZ$62d@D>eJj^$|2>+3+bcNLXWVzW4D50sC;;*HSw(n> zw*?=;-(q}GFs~5Fiee;9rASs!x3}{X0DWB%<`zdo$@ew5XG|K|tnq`rE z7NLUxf5`|IpuKMVQ!7kIg6MZu~C9Zzuj8UHr-b5mA<3xrOH?`uUYx ziS-q~@&(R*8Iz@6enrTZmtUz9ex=IrD-odA;0)r}CIaE=9we)Jk*wH_WO*Nw#RSHA z1jbp0UHLfcc^?z-LBg)Q2gMNP(sBrXPvckq1`Qu2zXD>T*_9lSJjJdg@5M49^RYCa zjrg)~VoMA8q?AdOJg$?+RfXUdK)#VgxH`TF3=xdT!w>P{3_iRh$ZTb}n!z_D+DLIA z6VgUuNov;fx>}f#Dq%*jxe8ChccIsf9J@M>T`kA1hGXZYS;BK@-a#=7iiQ>W8I->z zgA&Tjpty|5>sZ8W?R%Io6kxEHU0~zEvw>`~gP*|P1-zTXJJl&$Iuc%s#x-^#sap@k z*+qFufFOs2IlH{pmM;v@>#a9tBhvP?*=!L_-49Abq z4MV8u>nt(_F%Qd++~M*gZ`t7UJ2s$C9)9FYiXRa^cKJLAn#8m1&UDSdQAvEQg2H00rB%Z;Im248KthhGVy3 zIL;u$@hsTEeDoOgqK9Z%FFNji)bPZSVm%Zd!sQMJAVM_Tvv2 zGAv+7ICywHf`|I}jt^i`7UT1Rd3aqgs}RZRVkA7`y>-RtQtVFVlX*Fn2)pulT-RAUTJ=hBaFeyz=24ysD##3w!oNWc=A9E!vjJ6e%^tq_5d zVzE~tQi^*hM0R-;B1O?y4~l{Y1My$x#`7Xd1yd0!9+Rfzk8A}*zx-(IX|$?{*TH%5 zJh>>I$0u4v@;1Jt&ZzAUTu?<4|0&UrVmZFZwzURi==auT9Us-$sfYs`-JI0K|@@ z7~K8~kXsSk3EC1zRZ;{5=r9~qrexNSpyQY1v->l^0Cg8p3BYk+kAh$Bql!ROCb)y0 z&lwXEY^V*8LYDQ63!i*Zo=4=lGd?JvB;qjYM_zFCBR5k&(j@v3s70V0frXQ*Z&pX(YRm`Pd-2342CFz&}(}TRB$ce2{3rt(@U=l;I>n4w};ou zFH|MybzK+rBzU<|zr2gTcu|``QqzOCy?DD@KlSokq9J)dx}))v)p0Swb~t|Iem_5A z5Rm9crhU~_k1!^Ar0h3Vyq_heup>Yc+hpZy^@zxf6CVd9-R|Iy*zU-VH!9m7u{vUC zc@(N)Dp;`S7P#t>2db$ac_wdPSmAFBoLOun*fyJM<0PGL+yt^EJtTBKC3zGEk-c$&V0Y&D3Q=sOl?;660l zU260l@~wjNM1JyO@*th)Xt}^HUexpnvDhB&*9$icf&q10(ndzWSnnb; zAR{SA4382N9wm6zx0q88tVct_k%We1D_VkfyoX=p5Mc4x)sTFal|w`F3H&Pk$kD^E z{8scM$1uP0ssQn5_!ZiKgkPcRS@@Nk1nX&&juku`ATSl=nuLn$Pl(icK5nH}@G7Vj z;g9Q9?nMth79GjQQ2MF(D=^H8AOWJ!G#yE28n^Nn;0WPX7*c7J+)AFqttj;fm=Dna zTpuJ?GL^}BB+^%luA`Vthb?WYl?SKuLAkp689z>iOfN^VWQ-g| zIajnYBl$UC@VPD&o_m-FtDQKpui*EAPIGGt8w|b&A5ErE-oMV=8h1p0=T#n5%A?= zQ>X|RRIjwi@2#P=_>ICFq*H!x4y~78wL@GSLcRcn2Q>?^SK$zXy>?VFK$H=u5IgtQ z&;}`}EkwL%$9kaV5SI|xZ{c4Yjje$!-TlmXQA%*$)#nRCrSuCSlHmjDPv{?li5&md zTnK$|0f7&PE<8T56r>=aG$uVf3snkHT9cpZY*`(m&xhGaPiq;KCH&J{+VJ{so^u)>cNa`fz#iU5vVVspIH_v zvf8?kBl?-!q_7*m!rE3iq&Evq4|~ZX@$}FIV2Op zRYZbT{4u}>-!_UR=4{Mp9uWmp14wD-Em#vG2lC~@XpFJuf|tmLFyi3)ykI28h=k|%hW9cEn z*f!d^YeKb28)(YtH-S`I&}LMRRv8Wf?Zu@}b%Em16nveDN6>l;zIJ$ol=kr5U~&~} zj(?hLy?{vlr5urQ9NO!lYTGVsDYzQkUm;xC>AY07Fj#+ZE%vQ~*o@B@)#wg6HBBSJ|;Q07J)rZ8kIs1{=}$!ZHwn00bXy zCEfM&$d_WRHb0Myfw{2j%!`K#toWl?ha3zUk!p+$J{QXlmq5V`Xn~)??-G|IoWrj(npaof>;B$lUM4`u*+U;et90PKyh+s7%>o&UUZ`%Z$N)UE0Cgl zQ?W_IP&&AwC`wm+b0~p|;E!S`9o$g*)DuJL;D(Ze((#RG<)vq3C6E zBY%Ur9MSh!?PYA7XY#hs&PNr3iP7ehYG+atIXfuNw$Coqzoq(jI)5=4r{HgX5t1dv zNQ&%uBX6oXS5-lv1Id>x1IM5$CsMcC#<8L6&dO7DsCrFZu}`B~Rb6a*a{udEA44GL zBd^^T)}V2x#q1ehLMV-!GWc2jB%T z+uLXK>#oiqVwf|Sd>;9rn3-K61Ed-cB!pJ?%HYIiCvd%6=bGPV$7c8A!GOHnK6{YA z$&aF69OeK@$uJA3=@jJgjehdG?4^Nwtbt^X;FmptEOd~ZQG@qzGP8`Z_F8azvGGmO~n8azwxFpSuph7sE&j2QW^ zI?f=xaU1bV{);Owisx(Pw?0%S%vZq(%$Lj}_?1R*Ud9>M<-8DGPH|rO&e|tqWjHTp zHk=nZE}JV^N_06c`ty?GlE)s73q;z-alw`%oK>+?Mh1>c3TfRe92ZPWzl?PM4)YTY z)!MO#$SKy?0b#>R*<22gX0*V@nR{Whs`p(@Hm6t?QI3br2^%&C<}v#8Dz>&+mU_P7 zuwF#LhQq3II4tm59u6xK__gw%T^1^|+OE(X7GdJXc2*6(h&-F{cgjjM-C^%+?NF;K zZ)z1DYjEEg#vVe>Cym7_+hw)=j-cnTS4yjY9(buU!Cp-hkvoV*QeIdYKc~>=5I zFB7HL6tYmt)uS}ZHSkj0X~q8;h4LeZ&%(9ltVFW|{SBUgDFch7d_WZc1a1gVl#`3n z-)Q}Y@KWO4f{4N3Xc9<_Zo_D9Dr19{u~+b-s=qQuZ$q2d0umXz+5SFqRA8cNIFPl; z8mwbgxnZ5s_$D-DjLMa3M7cu604e9Gpq!krs+{_ZIY8piaSgebFmJ(pBE_H}6)qM8 z8P2$-ZX_4?Az9LoWIlU1TNtHk#G3mb%_yD9lFnyU zMZAK;4N`dAWXPIqMIP+@ch>5^t@{z-NdFi#ZX zEJF|pq81OMB(FjDnaQAk$I1?G?;U@!+n=yHIxuu(lmsEgCoTu0L1`P%{S~3KP7wA$P$zrt~+w~;h{Tno)Oc-WY{BC zpVPFMqooGf;Bm4?Q4Bq6@v=to$&c?lUicg`MPP_djg$>Ezl=f2fdvZf%X`&uLC=$U zX+iml3+lv`IOBGyi<=EQWatgJpkDRL&>L_;1L}#PH{gPT?AlHD6ywLo1-brMYGrV4 z08uxg06xeU#;AZ#Bl%W40gcziOlshVJ6l#xHJBRBD5a2RJTFC2@DiInoxgfImK1SL zijhDF7UrmiGsSW=bJV1nqkII60&~><3NyPk^RgOfuwcSaHShZucL6ywsTYN2kfxHa zas1JS{#>(4GSwbd>0z)FXn}yNha(cuoiUjFqk27o=mm}JVfXRN$>OhJg_aO?%unZq zZWLZ<=>FN@1DE0(@;(C8Q6*Ax;Uz-ZLSulUypg3$gobyP1a z;8skKRkA76f~JG#0Yy_6H;1~^#jP4D!TcoDliLj!bcf-B?lfG`CgFm}^wgqmGCf>R zWO}$L$q3Yli_MF~W3k=XSOhBG0S_C^q`|H>UL8+yxR?wTCUs8bdL^6 zR7Gr>=4iqMI(07`jlJ(GN8Th^48r-w;bn{xXL_ZxKdJdju!l-x6n~S0r@a@#V7>{b*Sz-)g%aSP}-L8^6h_=;{J80LG1;LPlFv6m|CkHGRXz7KzwElFD7t z|7(8^jIW}aSdmzlaHd5XDYQD0_>kAv3v)3YN+i+s)QK*q1g;~1)pJ6~em0qp&%?=y zM-Bv+3P&;tekHt{BVW%5M(~pA9emC_YR?Q96IfH$lW}Mi^-kReJkXnFgmXzSt?6M} z-HUg&Ff>pE;{n_%k&11(5zdv#`j05S>wYW#0dgmz08?%{df>CC#!ALf&Dj=f?Rp=089MO~0=Iuiqz(gYO=_7vu(N@mO!wr^Gf^)~g`;BIPh zwVEv$dPABG?&jYF-H5vtl|bU;4IL2XjGRr{KDOkS@x9Yt7r|77YQWjje})JF)aNzy zP%Jrju}4@Uf*7#6i72pa9se159>AUp*MCMWeC|Aks`DGIVe>TBTrB7jVqG@~DmF!;Ts56J}sNJL>%f2v|{w%z!Dv=S@kM-)R1 z&qGn{@t9$Q0`(t81>?(DbJ;fQmMv0a!Ew?63>?M`j`P|>hJygs#PN_}yr+zVz>cdO zLaZaFNjzlKP#L^#b_o4yTDphK`{C@2d}xDVLg0>}wh2w5d8?PW%v@mC^V@^G;9#fpHTV{wOcei zDt_WZU^R!Im@clf(eYR*;ybIad<@0^M_nQqiuDeG=zP>^$+KWl(&=`Q#J0 zgIzHTqP`f8S#Vuz6{7�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 |d3Raq#(Ka|NH?@d@ZPg>Fkd}T# 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%0DO&5;S?G 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 su|ha%KoRCq9jDaEOY+fTAR=FSdU*c&i9je z$Nf*+@IS>vb%Om*C+4Vyi@g_mE!63+;~dPxuI9D9-i8DZ&2#qfyyx8Rs%^Lp>)Qbr z3iUgP;l2xey82UWEc(RD-qKfI@>&lQXYgT`oU771Hp_EYflfF428o0D%JwHr_BMQl zkLJ_M-jgYs2NPVbp79dr7Van9pn$2joZ) z=wGX~4yUj!mlAKym6lgZl$RWdNKO$otk(GspMX*>R#$*}QcRJbM)TS|Ug!5oQcOyN z7N_O2-fwo29dZikC!hlrr;R9%H}InkAN<(v6ey=skNln%{GJ~Cew1Hm2hxFZARO?_ z!uHZ#{O#fI0Pr2;?>Pr26eEHWy@*_(mb})Ej5EcaT>=H<)`_iOmW%{=h*EyX)j>Ia zXZyVK5Cg`&rElgnW;>0z&!vy+mxn`qldO-wz5H#y*t@3pC2tXbODEQUo<46%&gPm) z&Yc*BmhKyvobG#UvJB)ylXQKRaLun0|Mi?{lY(H*a|qs%?s$!`&Y$GY58^ieJMD`< zmENiJQoFs>KAa}D^LHPAY$b1f1bldHd%dZZoE=jm>eUWhxZue5J@gwM-mNU0-TPw%O&gt7Sgbs1?h&*{hbUa`iNMb=Hu^ zW!x>EttPEf(0V*h>Moxh>`fhibF%G1ueIpMJ-W3Qx=B zn~~LC*yC(mb|a+)?fda2?sH9~b*bz1S*={f!w>acH7`@mtNiOWxAP)>U7vnzKA6KU zEP^APXh*)o9XLMt>9M??qKoqT=6DD$EKg)+6lTN~hx2IuA#jGqe?ntDSj_&vyn-f9 zwS$=$jv9gV45Sa$yJ1x@_+y4xUdt*qm}poukkYd>nyEm;doh2M9w-2CPCa|QK{$Rz7vl67K|cF6C6;@pU6UYdm}XLL`?SAAeP~>3Tun zLk9-LLIKg@h`l7QoeGIe|2o^~r;6cDzns1C;~xapP}pv5dZl=iHFlL6dsU7-&4MEp za^R^Vq3K^|gZ;%#B%Pb;@s1}zEV)F5>!{k@bG)yltkA= z3&+O?MDx|D*L>;1BNRfwPDs z63qk8LmBECgff^3yh0BFKbep@Vc39I1!+biTuO6<)yHr&PBjrT#qePs%^4vdwt3@E z-ri=1vq|J9^~HkvN1aWk)-WO$O$nzIoByQ0cpJWhdzzIsM$vt+kqmkB$=>nJCss>s zqbwJQ47G~`!$lKE1_pKuZWqrrA-;!M=H$*VQ!Bmc1`ETiw$b;d0@HM00=R{M0bd

5V>UajHV?^)_)$ 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 z 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

@-_527T9zr<}3!<8fU!fiRg)sgdsP~Wg3F(Ahs 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Ⓢ}oL#p)8f(~@p?N%qo3cesnucIPg4 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%0AW8M6fLWaF&+qim`H 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®5bPb+@@`$*sMSwK%n#o#|5EYuGorTL87EhWEo&Y{YwI^ofx@z(~Qd z0v7xUvA~Fa2rA@z2^Zc~93Ue0Dnu-Bgn~SPKy=aK`&%9~m-O#Ncm(tnt@dGmT~NYd z6pD;L<84Y3%A;e_A4GmZ%3+Ch0;@O3y`b@@Ha!_R7pq5-k)=LJ=6{RK@#E+A$PHCR zsm|?@NoN$LihmxdI|DC^e;Ap22HqCik>)e_dRt`59NhjSV$I>}??>kIc z1_|dfS?a^gMcEub(;KQ%9j#@P&PaJ$%TOkNP$Yj)B416J!yA;x9~8$Qlm<1qCOG_n zvFh`12Pk_scp$CzcmC(oVaOavLydz~^AVUV>it;yUitW(;o-_~sM=%edl`N0xQv&Q z8LtYvUZd3)6g+F~pqplL^tW|xEk=zx+ay{XJ}q6F!~3N$ue-1u0_+)Cm}(M2RiLT% z^0lMT=8$oYVl^ACiIdDqm=3p8!A(Yv z(Dx%fg@~Zr*NC2jAM|7_`7j?-4=xalJI?Zfobz>UMk+DT?dG|;Vj!DYbNL*Rk;~3@Z%cJLv&&R ze22^v1)p4iWz;+d+=vS zdhlnSXLK0;%uRhV{5i+ge;fUG_;1w3{6^=$nr7ULdUQVP@Y5BpB1hq;ns0JW@96pF zyWd67n6IUgKWnXy+{mc(gTBIiZDzWo5WfQ)nY%V;x`+yBPVCT$9=}tVuYFI?*CO08 zU*9Xt*JcQiqJ5j5J1ET8Qk;Q1IT4pRe5=RJx84!373OP2qYwe%48gk-BjBFw$eAC@ zolEN`O6Y*xbtBOOI?;PIq@plioAK|BA|DF#wKCb;PLy^ccXCx(h4{`iiJM%6CY+CQ z$whtij?WDmh56d|UN}G$WLDJw0M~|P<2@XI;t4fhI|{!j%-3dTd?~%18Q;QuZDu0; zEr6vkU;B>E@ylez`)6)n`0GDl&UO_3nvK8v0L<5p!k-KCwb}5VcW-*RFkhPup?asL z@Za0>wZY+E8>`OUh<(1W8M_~G7W+TRW$4_$Vf&j#^!Fc;s0+7#xWx&ng{p}C5@jWK z*-2cq3!h#IS2*v-#$b9Lc$CGui?G>JwmhdWeCx|uuZtBPYD)WmAJuwY8uqf@7XAur z?Z8N5=~bFKh`bxIQdgd=q4&sHBPvhUxo6niZUbxWpkzp}K*y>g8abu+@Y-34D_L`9 z@#IO){2fadk2~59EObrRi1S7JzvMgWEV*U-N3^^uzvZ$XR^U=1h19rPUg~Oj{fN>V zN0i>=E*&ug81+O=0s03cyA^J|8_&@D~ zI~p;MvL5GH_@U-?C2c82UK2zk_+8$5KNm;Cx}40iaqumFH&~Qf&-Yg&;=gnFQ#2F* zEnPas^?YOZ&ppK5ZWf`r5#Ni>UUyp#vvN&ZTWb}E5uW833|j5h{3LH}-n-wN=#;lW z{~uIX34Q&u#AIjaOUGl6hK$EVUz(b{ZI3JYoJ&udkc5DQbU-t{obo|GYJJ;ZjaUzx zLqFO1RWv!@CF$~CI`UmywF8U}m+i5f#bvaz)l@^?nl{OgeO2>Tvx)mf*2C4^ma~El zIkiKEROb{=s&b0YS+6F=bCp@{N;OiMlRw9Et?5p!OFQwqk(pl=c`d*=@jLZC>4p&% z{;+8*`I}E{qpVjthOyNAVqDv1#V<$_M_8XF>o{shEXV>YDY=I7SFOK#1Z*UC{Z$VC znBtbdM_PY%xc<<+MlyCg#j{-EuufVET7J61#W6Go(Dbg>Q@wlD8_`l{ebl?xh$GU~ zJ39oL9$v|nmtW4<<~hjIefY*|Z1=S7bnJH`KnCCSdL=<{EK!GSUVy~l|5!8CTt!%nA;i(2`+hp=-gcB+KG8yi(__U8J#N86n8i&$8mwU3>`=qq>o zyJzY3Oj*nAzamtgKG(aKTvuKmxFr%Ba~F$d)H zea;_92t+?lrkrEGejwpcfIzgIHvVtNULP*@{s`uR^U-Bq=$NqvMCcKR=CAVjQ?7k7 z>V9)BbH6sbV;oqs@>1^NzV4axV4!~}f8`~oy8M-&hcjS=zcPoPuGacUvNz9Fnb%%W zkLb)tNks}=ieGAbUwG3x#j{w7!&bFdU=*&Z3Q>%&*Twh-R3Vzd<@p%L9HKvIlcLj< zU%)lj`rc^R(XoI(Ev!`h5A+n(j*4p3w6f?9mAST9(2=gqLQMN`gqR5WJl|Ljy1nh9 zqdd9rFtq=+D;OIu-)_-ZFR;`(B{0h`9sK&jsDn2uercTYw(SL`uvJ-nA|e5WeA)6d z{-lxiU=IE`_TUKX*1bQHvh>=46UxDp@fnHMkK<~f8D_WC$askGe1vbP?l$cYl22*p zxjjL3w`uQ>#wq3ZdH1R}qUDYq`0h1AAocE55B&Xu*no9z`^dpx;g2JbN6rgy%+pcu zMx*k$G3-ITKaJRfwRCs@w@dQuLC4>*mx3;5|G*slp0D|19&c28pX39T78VgQ>(dzF z#~|-x7VW#xc&hvr$FDdedN26hs006=X(Qt0eky#e9Zk*n(}kbq06XK~%EJeZ1D>{h z99aT2;}77#W5~TOd2HHGnK7LG664t~F`oT`s|n%^;CWt^CK8-h#DiaaJov>Y2fv_9 z9Q@*wgI{p88e586=inEdP_#xpaSndL;i?JsL?8UpktzZLZR&Q;pE1g&1bC>74`;*F z1^h^Hcr;QR9*uOa95ypw4x3phhs~%%F7RrD9HVShZsO4~Cd%ZYaP|1T#`wcFvum5N z^6zmYrzG8u3*$3MqiZ>u;`ld0_Qs3i-sLzTizm1&sd=T=C>zJ*Jg=lBl9o#9leApY z36fR>J2(2_0$IA%DUSu=Sd=AaX#IrQ#vvCSB}-q%c}>IjFOBt|Bn{+wMY;7GD~X@( z{byd8Vfe-|ndxPEaS7AQN||2eW4fT6>5UVZE~m<%E} zx`{-JEt6u)q}VbkwoHmGlVZyjIo&i?U612Sa`Y*uzc|aJ9ZfG{GsdxsgjC`5ye|Wv z;roqMCrc@kA7`2yK8!u^3S$qv!q@|^F!nwfd!LNGPsZLSV-H;7m&l;T-pt?<&oru? zQ+sL9e!O;eF!`oepYhc3dV-7AnQ>ukFadOFVA~yl;0JBi2SY(G$3DyhdW=&<2P*_ z1itlxczMvmVV2w9#QE8Abgihf*F!YsH&8xb<0BrRnc#2S``^3|#!J5x@;qtcB+7Ms zjH-M2J2A--iI<*Y;%KiP{ict<`rJJ$?yWX)td`Rto`%SV4)8bb{k%0XfuAnip|Aln z`TLXkmZw+Yn9Egi5-0A9&<$jJf+u+LeF^VDfzo8p5L-I|kAl?j0Sz8j1x&Y!RSxUZ zt5r_4ekV%Cp?J4l7@zh%e&$D3+~Z)Vs2mB!v$IrNH^?b`A^Q(_je|aMq%X2mAv>;D z@w!HR`UJ1Z3Y<^nyqiz!#_8|s@xK2IX6oD^fJNx|7} zxghTSD;@=gQ@7Posd7w~<=M&mI|(ryo8^~#oKMP|O8v53zpUatpiDdk-j>VxuTz1* zr}MC_8XN+7nw;H=!;NsZAdbts2q$>+9NLBp;!{rNnR$&kEb6a#gjXaOpY$c3Mb?B9 z)IW^_*DPC|1#hgJ0-4DJ!4)+`6jKCBCvtZ44JUTg*E z3!H=FQE{>x-&?BEa#jk#%-0p?GM)BGWCGam+#<3e1zw?HjY#JPrn0;WKT{TgpSn-T z&n(rvN$0Q?l!=l(!XmwAvqlumBAa+UB2e(F$f?V_^l+k>5{5?)=t8Z^NZ>(J9c1E0*k6W6oQd0a1!GHt<8(D-Hr)2q9g z&c2K3Vr-i_ca5mxQ-`4r=FelaP-S5XX9@Xb{><#Iyita0+D)WbKH zhhKPc_N%Xsmt~6*@IIH|;>Hw`1zV9^^&pbVdXQZFD3X~wk(~Eb8t2USBDrxNk_CN8 zu6iEHWdleq#!|zwnS)5qI~45f1J3;o6f-mKeSv^+z-cCb2heUYJ)2F>rXc@s40@8L zCmHm-08kT_kQov`15gtxXyq4zooPSWtG@pXo}Gg~Qk(B%Og_xy6g*-F%M^{YxM<|+ zF=<4PFV4N2>>6K^hztq!e~z;rUlIP$JNOPK9tXD{H0@0sQ_HhGMEhV3`F#$I@%tf)A8HY6Z#u?FV(sM-~S@5kE z@bUO&wkSl94MEckb?sO(p9k3rknKLpelleDbfcz^;;#(A!Ah8939e_-*sldEOZb3V z4aBs1Vwy=zs}W3V*@_-NmfPb!Ui3KRc`VykQop;e&<<9pam2D4)FJGB22YYL3k~XS zd72lnk%9r+hhXSEjm5woiBA5ilr~h?l=XnPe^m~l*UcUcdNW^pP zfY1S#5&Z&azJDv;%aO3OpE8Hz!f-;9#GK(T;L0AdhzNfHSMp&wG`BIBJP7agM5t!U zoWkHLb4p#PbKCJmpUB=i5fD(X00DKOPTEBtebg@MAqt2pD5UyFjr^<~#|`sLUb)=< z1{GQ61=Xif7=EYyGJ%d+_RgSvKZf*VYK>;+UQful?-9z*8k}4ojDwHjdHw#&Gx}fG z?&j%MY^oJ&0zPl7v0@RpL>eJUBYrd13W?bSDOoesvKJ*R`^K%7y`aakuYx#U&}-U@ z`b_)A0n*J|+VWruqlUb)F@PjeX?DKY zj*F&ANLs6qG)zTeP6N>dnB!#pUF*f&!T?fV{S+iOfDE8VGHnZRqxzefETx^&N{P|L zH**8!xQvt{X(UBj0h%ujd{{pL_jQ2^T$)U3{J5VFy^OV>Qj}eZv@L)}L7~LgzB%Pc zuEck~iz<+O8SV2e#RtBdnIGCPE^oj`zH9l-+yI+7hsl+AgSycv)X1+cV*em!9)_U0 zf(qf>K&k1WD7#cCgOqO<-h~$ydc3IYd@6o0#)ityZ^!MDD3Y6&Bl-FYBv^`xEcYO} z@JC24g%($K#X5WepBB=E0tBdvxNbv-asF#Ba$K_>_sWd3&|#GIGd!4uUb8uq@ZhEm zxSTI$-9mI`5!6Jsn_WN~5=hQZA-QlXl1m>%azzi4YaT`N^_@s=dJ1*jv=7PG`;c7o zJd!I0kX-sIk_!isoDW|40;KPNXnasT&0^R^mZzux>-tFpF!-dPCqb$OmP55sqE8`x zFy7=hK?7a8jg`M6@>Asz!bt}0UC>?Hp~on)u+cbQHU7RKF(kOSt^~=~N|A&Kr>~SF z2@*=R6_)48R1(>ld_$z&b!557%{1&|`jv8~K}s8Z0Xcy#w-PE%gi3@^X(Ut{2$gz5 z#UxZ}2$j}eBu)E}LlmAi;yeY*1Jz<_pD4 zQmj81Gkw8W&4i#mVA&VOT+y%8xS6U4MgXFv%Tkk0DDkxi7&>WL$pD4o?4M>bVz*#zl~9_2}Av==?j zV%a>3-tT~hv-UyuJ%(!^-&;sVdk@U6p=jRbh~^ymtj}#v55jSd1m4p$&Kd;g#<7B6 zR;}Q~HAv^eEznvvAFhB_aCC@f9Kqf$J<^_YS~4bja$&qwT#rF}2lPE-rL2E~d>DE!0Y&$ z14($pikfeB;ti6=+~4FewHt7+5u+eee6hamVieU$WLcRh)G3r22?MlH#j(b0&0}B;o zlR1}WG}cRw7fm>NrD^wIF6T`+8Im|U6CP?sB4&J&CKZ@QZx}1D13)wI3E8QO;**44 zOnVSfvS8FZg2^F}O$XrK&7*d8_9#~(5 zKS;N@H-ZZv{u-PcKW-wL zUtW0-zeP)M2C7qDh@WSRz*i+OQuTQz4*nrOl{u!!kAPzQT?h%ZIe$Ky$D#hK8-J66 zzjHJ`1KxnM;#y12Mtp}fgAHK4gcw1P#b2lXGgSSonPJSC@jG7l`qhlpcEy#L=FI$a zU-Kc5>;B0Jh_Ga^1Iv?dD7tx4=bqx`Q{?WfqMJYdGj3V3h3BZG%!581zt!W%ELdia~Lx*pReTAo4A@JS3|fu8&^TN z{LqQYp#3O@xGqo?Ozs&c(=X=a9p;uTL`Cz!0or#HIJw|Y-vZ$`RZ^I8AhMv8y7UYo zS;*@V@$E<0&xI2^Vm^+tvr9Xt^f=+;3Uc>l&U7FrAI)0pUW?wN z!Z!J3!Y}pdhK;JougOP-P0_Yd^dm&X9DB%Oo zhnju;`?1%HOMj>Qp*%U+h;~pI$|=XP3fr3>$J~zhn!_J&4hBA%yWdNCXSg?=2oI(! z!#!zVxG&v>xEjo5u3C}yf}hb|H=>t-`@kP`B>p9O!6!w9{B))buyg$ZfFLy6TquJSYMc`gB&9g)7&f{fA0>ngW;kiT*x<6m<0gY*y% zw#76c^!Rp=javURYi(iwn0I9xoWlMw3wHPgB{8uEl*}$VQzn+PhtRvRMG^SNmcz^M z5ya-A?_;Gi%}?_7k4f)>`SL}WD?4Ded@9@n=kchAcngogau2Smib8C|W9h7?Dn1(d zjRiiVGndb~Wp~apAhBw)^M^<5ud`YxyB5nm#3R;aspH4g_!st z5Yonj_gx+W(940t%iFh(Kbks5>^CFy0oqV>(ZQ`|gcLj=1#CFu+W$rNo4KtoXTKQ} zzJG^aM)>28u-^>Si81~0RpUq6`z4}v9LW{`c_;(SIAX(yZbyF8=5EjPkW-Ks_MiCx zK_L1eu;l_K6d=I!c4hAwvCqZ-s{9Kh7>L_mJ_ddP#(UWPW-|T-?O%2K7izPc%m`D? zI!%9z)f9R9L&kslU+(>8&WG|cy8qP0PY>fdy;Z9(BR2dvR(`6$SJ;2%Xk^a^99Gz0 z;Rm7z)d6=i`zdApe>0ST&vWA+fj%`Ij@W<3p+6Vh39X4MFVEiq-2(o+=@cC!{dq2W zI*cptU!ZxY=I43wj)tDxc;Rx{jr7uSPX13w*oSBx6v9LV~s3j5X26pSJ^ zWC7PY!8kmG)a^cbAMM#Q`hGQ8{1$$ik3rps#~Y36BlfFt{4Fj&iy*#st+@Dk*1vKD z{2$Y`vOx3F9IH6vuN}4h&Nyd%C?otPWD+hv0XoX?dgU9)C!@Ds+=;iJO%`8-ALamE zuZMCxRGQCd9Ld?whWH`4Ay}ck4DIx{y+`)5d7s5&UYd!=v@-FS=N-p*%vJA5JZ3lJ zG2?2%1A=_HUpLXOhU;8hahJg(#9ij-kB&UdwRw+aeppnhHH;@LoVQ1ZnG?k#a4E!J zx`TCmBjEGii1{nTUl!soX}A>PFF&~Pm)xlG(~LEBB244iNfpt`vTnv!iOq~sJsTrF zb2EG*+P^ruyoOsOvrb~0JJ4c;M={Tz`S#_t+d^NXW_U*8zPLynNk-kE5RWPHyvHrU z6eQnLxM?9CQ>GRb;uYdCk44{x{m5AKw-%2%2A5M#V@9BhgVz;r0)K?^?>h0Cqw_Pb zi=T1-f(#dZYx|9l4G%Z>>K=uA@%>28uZsG>GATF73XgMQg7q>g0GA7*^7bfy_nT8V zzwfAr?!6M9IR>ez2@aB)c)c_JZYN%Ibov_SqOY)9U&wb*I{Jb5`3muv`{>4Y2ZUuD z*mQDBjG%UPl9@PBtF&325W(YeEMXxYvk;G|5Kc?)w-}E(Do@cYfGp)O^9jy;+UWen z)13iNR zPq)Np-kcks+3-%rXJ+Y(=Sz&{pRa~Ot>(^0EMcw5%una~<8uzl5kpjT-(jEI`7YOb z+XJ`B&gnS%_Yz87mg^o~>(6_Y?_QqkeGT~es5=@+CZFqL?ZB1idgB6qoLw}pLN01t zb=SK-*Zy(&T<=T(4k>%N6(C>~;xP-DAP_iF;xTiW@|gb9of4)Q&Gnyd8Y4b)bbjjg zpE~}AQCz3T%ukhnpb(E)h{sfNtJfvB29(^=^2z^h$77D9wLCAL6Hll8cRHSEbb508 z@BVG9U`)odKq{|IfN~Ebo!vClt>8DhS8j~J!*{ai_uct`dGSXh+^uRba`ZDGVU{;O(jUyg8HaX%9Wzr@bW4=nq@#3mNb6HJu6%ki1{ zgfP;}(oO|tM7-wc{MGGW;r^O3KLTTwlgtO6HV?SZyLUV&?ckltBl*??Dn})ww_e-_ zK0Y%aEAku;HHCQ1cVz#}PiEpZD>Ct#AAY;>n&yGI*p)t(*+jDmL7Uwp*6SW&|4i%{ z+OdV4AY|_kCf~qT?0=6aP1pLIEI)9^Yr5rOAzrhvU#523(GyqLt&~vEySQqfpn?k& zSG8MdAzrf(uSvtE5U*K?*UUs3x#BgkOGizR8?7(VyJ%+RG4yq8q>1&ae>cW{nn#w` zg?P>EA_vWq{kcAyvE!v=qDP!UPH?H)L9r(5Ey^YBb;|WdF_4hD{?y^9g?LTO7do+W zg?Pzg?>YXsqa|=RIlG*{ z8FJ?PLVPCKnG=kve6t@MSe*#*nIJ8nTECI;Z%+rA9UXlY;xkXUZ9fa~nT7aFD3<_& zme$8VJ`*ejn`ma|3r5bDjpZLK#A7=1AS1S>G@_-LO!;8Pq`pV?$IO`-p=L>Y9MdDf zd#`Ifk>2)X_}9j&+jFBb&qGw^H6#7+N7yfOr2qYk*d;S-@4NJ2_k6T_KCTdt32juz zf)?U24+nulJZ2#t^ZgKy37)L{qrZ_z%o-QJ%=kyg+AlNfUl@y@I{t-1Jf?PZB$QiI ze4jnqlLzw^Ek4#U6 zcua-UE*IHI528a%>lCfQj3cAYTgRP4I?7Y|){6$dEtPY85w+;jH#6tK9H0F$bJS{y zs26`Nu*&De_adAU^I0S9$+7rzA^uWrWq2o0Ma9?E-F6qPf9#^B(59pifB7DbzXaaX zi;|@`@KZ=g;D7O9TR80o*#eNczoh7zm*$*DH~*F zm8`<~6pE${Iau)fz@7FHA+WQ zr5DaGA8W1ki39yYJZ2#tQ(>$7OlQZ{k>wS=SGyy z;#l#PN085lIfSQhetE(-rPN(!xGGan3KN_cq_(pyDm3>v+o}@GtS!jeZ7d;rwzH0y)x|o3S|*LLbF(>V^F= zPq_Ut>B7E-@yp78?d*SfSb9>6utz7S!g=M6JNv{tcD)dPS%|-cZTPn1FV*xwUOa=E zA8_W!4$EKQP9B}P6wWI@s-waS@t6tkdn6tcq`;HPUGbJb%#FAF@NtT_{8VndWgdOG z&i|C%E=MP?!ujNd_{*b!Kq3CJ5Px|>#b1I6t3b=&IVY26{GoTa_q+T&oC*58pt1Sq zVO*hw^T>{(xyEzVfgzc$fFL1mfqcM|I*S$Ks!3x<(4;jjsUX zL?H2r7*7c-pqC)a|K9ER$xF=SGsR}d^J@^)YsR91o%l@;PMi`z(iZSp@$Lk4Wxna< zo7RbS0Y6eJP-Vp%TKT+3J)ae*!SlI+dZhCMjlpYPNXwrb9{RBh#)9jRLXoZYF~33K+PYJGEFNY$3ic|BEIG-ufCJXq9x zp-4FNosmBvK#kFtj08}lP&+8O1AnuOoBe9U-2^ySEUDi=iu*eS;^nAj$5iy zwXJi}?54SBc4RJ^-8dJ`ZkUT^*Uv?>&ADiH&D>$O@w{oNq<`}R!>MG^<|l^J1L3Xd zzHkqZpASw;50zbl*Ne(dV{(a?6`svxfwbU8X~81)s5ODUJlVR>kG`~SW4~H4oi}}3 zE8}~%wZ4w)Wb1BRCtHX8!OrJuf}Q(Ir245+{g0*kALmp*mDS_*J6in|seZOpKRc)T zDXbo^-_h!;r1~PMz9^^qDprrzhpGN3z@7u@NvUMz=KC?yC7U159qCD|46l!4WtCDH z#ub(2j%y_=!|UT%SwJeoD5A35Q4Fv$ygrVV0qX%qj2SA+9Wy^G!|PEi8)LL`MyMi{ ztlGQ{BjnrsSndc_uxPw~%SBI+qA?yQI(IxKuxPw~%SD$<(SSaR&V_zCi^l7>Tr~I$ z00LN}=v-LiD8I5x@H($(7nE}#TbfEv-Mkf$ov``QT*#KPAiO@xf=Z+yz!3%I!m)$} z;q_4#1a68J0ct2H7iwM>gx5z`&^RdvAVN7gAUXxbobD~dG_k`>%wU?UP2Ww~7&YC^v z(n}z(mm`B2`|F2xpNge6D?|uevGsvLKDJkj7`I}7$y4T<%&vs7^2QRr*lO9Yh3r3s z?9FC!P|l!eqzLz6%Fgs`W$p;?OL)(t4e+30|Fqz|FZ<2dU4bG#wv(p4F=*WPYty(- z=j=o;JZ5}h9Gg&hJ54((IgRN5g62>gn^R%M<_9A2^M=hk%`T-c7+use%+9tzW6_c| zD8IstZ3qlVpXLS{t=PTN27BXyUFN(U<~ggSgXYAIroCP2j!#*|FQi5BY2VB0Q=xem z`9nBb+}>!}3j_Y(#02s`YS}M^?E7(*uqHkeGVa@ozemk@`FGLaTQ7`TXgRuCY1tU3 z3*&X)!9t6Jeb2l;JZ#3sFW7ae$BIprMxy5vQz+(fGr4D+Iq`86(S=4AnG>HdJNJ89 zI{JIC6sL2@W2`)I5`lHEj7aS-0l6Z}UN1^i$o_q{y;j$~(l;Zz5qT`T&y1~>Tp55I z*lC`lpk`?;%$nE-;P-?k4q(%d?`7fOy^X!733Vlw)CcFy!I*7OLy4zVmfeqiTmF3E zCr<{#^q6*AU@G4eVbGz?0EB!E81(7;TUnaFcKCa0T*iOx$x}U{i7yfs@fpK2Hh6ZiI_9IUd8dkjYyQW4)Wcv?3GY|aM0<2l}md%HT0a^4507MmLEs8Vk z=0JTYUfzK&{Ubjx&T8imsLS_Zvun4pawG1{7)U4-uc(SghL!&|{ao0)EQr%JCT}Al z)*J#!dY5%2mY%Xd!1Gfq`x!hBSJ>!$>9?%-*F5Q$=RSZ;rQb5EA8P3}i)RHILe)E4 z{>SX>^H{}JzzoH`U$XGHzH@Nc=(+`M<=BTjFId%m#;OZ2z#;op6DUg9k?4By+y9q; z93JNUUu=B!PQVGd70$>*1vhXb?%44Q>8Cx_Idmq=^lR?G$fN3?x<*Gb`d>879ScDT+0^D)>F< zytT+!IiJHG8-FG~9)abtB6FTu!LCQ_tsuijpvRpK;+qq<65(^O9r)6~{cd<5OT8JN zlt$Ztc>zU_c-YE=9>4=k7TRQ-6=epDmjX*@;vnhd>%=I)YAy-`NmOOHpGIGjO!YY= znL5ym-2+tLLY~2UkjfyMmBc-u3Q}QHBE#L9Tt53ayXoo{Iu)GwuoWW~$x$c$aQyc1x4$#B5koroO2jkZXLEx^e zbh%aiK+A8eV(<{N`sJ4YCPjoiFOx*fkY|5a;+trZ0-xnMAYG@Bm;0;+uQ8hX7)hn*NymoHw<+WGTUb!jD|2hwXSMJ6Kgo$8ojfH_Q!C5sgQS9Is z*CXg_1Kvs6$Ndw;#L<$=c(+5rd43TMZyhB!4bW}5ecEjpuHtHF&#Yc zTNi))sA&&f7!ORY1y@Y{@G3Awvoq<1^*vNpdnolojQ+A282*#@pUwTAc9I{Kcc4e5 z%V5KE`0q!~(q(3K8vM}nvQ_;|%g=%`_6JSRlOfM@wcvy;-%(T&8y|iIi0#=exLsdi zR_`)a{Vj&wiecFLeZWkS_x&Hox`f);Y=3|G8^goh&cA$rLl1#Ve}e_slfP)c1GrW% z@5JGdaVCfwH8IcCaGaeC3v&E3C!oLKsMXcu=4{vqXTv7tY&d3}`#AVIT-6`5?Qndn zKSmoU-^p_{jvZHLkI{5{o3$OI4f-}~J4R#rZPs>-UV*GzZY=kkYn0%vI2LEdF_j%S zHm}Svl@0$9+I`gSrDG}^j<93#lhFa{c5b?$3;!K_t1uJbTg|b}gQL3l4pR~wktpe? z{gj6(X{wY2$e~TS4vbM9u7@dUnv?{c?#Q0wU~%tX`fdVNV7tua<*#qJRW&YYLj`VsW2M=X0jlym#ZkljypD`XFf+9nq7 zEa?39kf`&0jR(X&`R4sJZmNRw&WAk$Yb+UxFNA*P*@TZDqpld7cd6g(e9_bLPf+$6 zsL#6`8>fw<&6Tyiq^-t%8$)8NXpaf*sWC_3HE}six(sOb=x;;(d|f0JA|rYyz-13? zA2jFn5qdVEhZ?9l(JT~=QM+?8?i1slX3Z>(`ByFC)Z*`mw-QMs40!+KA#O$~c0c?p@Q3{7b@_VS`p%6|@IT`#CDi zzK=MD6Iv^+L=Bbd1WjCty;PsEm&QqpGWJqEjX)D+X${rgd~VdbkVLP%z#)oZb`m{@)<1qhMzeQ$34d zA3^!Wqw1|j+`t!>oe%}NQxxQ^a*Q2PI7hVCs(#2=xfyM+JbU*4r29zr&Gv)lyqDOT zKH4~9*~AvYHU*^WEr7Ps89@hMyVh&drjB*cxTR@wsRLqqwSciN5x(onj||_&41E7- zi?&DWK?@jZ;x6G|y1NtQL{N0CvJj(e2^04R) z)W#=?m`^~dG+c27ggNNo5fGA}nO1z#FNr0!KNot`ABW;C@H-^b0KjwwX~JUyJXvPh zk8!+FwUFb5@rr60|BStA*;|1cj=^eGKfHu1L9_U=%)t*>x5SSvpheFftNO{7U%>wd z}Ay)}#}_SP__*jvMxVs9-Q$7H6D>BWAgmvJ_}%)j4P)BAH9XAk&t?L<0x5J` zq>C_xQ+5vi5D3s(hCqPUvRe=vaD1nHWWFa~-})Ko43j;*N#%8|A!TFIhpL6eNgn03 zg6Cv?U=6auJ5(FH99}3rvxDDmJhtx&$gB}{h>sSt2xwrhfFM72^M_7`#&b_#Dhn2k z>@^b~wc{hwk$SAAgChGIGk$Bpj4^iD;Fcr!h_9N_H)cX6%$sNLHrF_RTY8D-tk7XCzPwTr&fn6k5Bzdq`NgQ;^*7e zI;V+{)lCGVDq$ypkp?@41A8aczXsf6?gxGCdcjz^76T4PqDU0Weq!?O8IyMh<8=WD zZ!k%g+bG&wF#flm3*x0`19#4#e5eW9`$O?bKUSh3UVf+YjHk_sJ2{PrIU1bEwAl;x zem=$jII|kXEvbe&;S1S)WbvFF_npFd9B}yua8q^)=VBsOHJs5cPg~V5Exrs+O>9)R z(YyaX+_t@BL63qcau5&xRMi*djBk*J&WwB4vDs#jO29IVOUOQCVGN-6G_ioz{#r?8AWS+A!HMu zBoh*F+frU*opSXBF^@TU_ZA)hcyW$lwX_L%yV5YkZd~c6X zIi|h=7xt;M&!ZGRB1B6h^Q}XB9-@dE0nz$|IfBb_>=eCh0WzS2G6g5>uo7Ga2=b;f8Q|reDASCeFVO%PJ#Z|U zKh*klmRnhDr-Kc3v;kVdIIUj*Q|%%0E1<$>N~lzVQ&EM)psK!csu@p!AH+;tW$;7L z7Y{A_k25B}z`4zKw1%ddSQj8=-8~k@hFbA@FMHT(PDJCu8$jV=v;^(V##wcWB*>1a z3tkitRD~w)CkkD52!Q=jFu8Xe43Z-9nP9xM*s^z!)ySlA5jD;~?@kYeKa8H7LUhs! z=P9P=CA0dGmVLyOP<3z12F?ygOrQ%e<&Pl`OoxYCZlw@n>$3xoj=5P9h!PEVSW>I7 zB$+SUPSX$_rF_d0EaXD}5AnvCIZ?m)`sYs6DDx+J-XvaM!=ifmI5$|cgwN?S!1KHr zl+66f@eJ0yO2*>^oIg43c<6=HG!qG?+j^Mp=w-TlfKizYn_?Zs&??`iihI1(&u*=M zx+0Ax5Gy|&4XhFRUlHi$Jygz!{AR`7o$`KlV7WYB5oqKu99>jHn{X}aDS2a1+hC1q zK0Sf^Wn@Hsz)f(Jq5lz0CPp`fVpJK0lT{kge}m+c5Suj=fm=W)c#I}(bp-IB6a>zO z=L|E^&P4Dv{VXGt|FA!ZXKRo@!@b#Tqw6tjYAV^KON-Xmtb0+Zruir%u{K#81s zhtGfyxAI$bQU(cVl#sIS3jBz_TQ)%*A2ug$V$OCv>E`tPPFzq0xhXS%0De8?&96Pm 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

R3+)*c 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

mJ_$9~y`JX0dz`?uDpXjkBSMyhM!JJMPW z?@MYeKbQRXs9mAe0v9Q!l_?7-oj}9n<-h+OwnC6EM|vx4Nf1D`EJkuEPd^nvTb*vQ zYz0x2X{%|Vn--4h{w-Z|&0K-}cUz(SmpioLcla_Z#g>KNM;y$2%k&je83fcs`EMX; z;sFxyg;dR%r$?d#Z9~kQjmiD~5H*RB)@;-_O^F~+2|UsCiYz+ z@iom5)8JrE%m@+Aai5o0F7|%AS~qR`=nU<|qx_o1XY;!PZx->JR$wu^#uZNb5lfdt zPi5Z^N^gIRrH)5g8-_OJwhe7CX`t*<_mPPEwo|hIEH^{(swZCg7npT^sQ&nm8V0{2 zT{d3DxS@9MH;bpAuKf14p^ZuAuTN$M;a~CiC^t+WB>$tC!OzzZU86g%$Fs%vWtkg; z+*+s~YN{ya5~qSWxDd!LDO0m{QI}Kwschypg6ansnTZ!>2WK1hedj~(Y}og=xmQYw zjVCoqZ~rpY3K*0~v3pr_4NXY&=)T;r`Mah4Unf<==Ht8nDBrrlSzcg&MP_ZbA_3~2 zPhS*=bS+|qgMc|)hL!GIH&g7H1tC)d26>|JTpM^r)Hni!b zxO?ABHm>j;5p$pwG3a*-Cyv(DR#=!%cJT}a3Poyc`NGRNB*0AUr^Xt|@1FY4rTf2+ zQ;^goGTn%F+n4z@1wFNIUpbj{9@Hi2G35hPCDvW*e&CxjW>)SbxMB0>O80Ab5V2?& zz`zPK7^Gv_;#o$)?Wqt{v!qtR0vTY{WS`$$wi-g1@ET}ZTJy^)P>QL^^}*s zkM#;w4pt&tlO9Fs1Vy{!xyvc{Ltn>=3ctPIGJTa8*Y)+x-ec8QPOh+aQlQU?8ptO2 zf%*P8yWU5##dE6n!qxP_nfegVG(X&2Z=4_Mz18Q(37a4D!uz4#F1qE%iB)-WmNGkR;; zX2lOa)T~+Y3e6~+79aU0wJRO^it0G{x#j-!Iq}7Y%?qXd-yu?SVmx!(x{BBePW8n$ zDID&eF~*#Q;Z%+Dx9uRL&vTs}Z_UpRY!Q`h%;7+dse9~lLGW$Qe=)R44#mU zslDH>%nW8LI%QPKHVKwyo*{J-PBWv=dL(KAh?di(U3d-}^Jy7P>?(t~vXZQRIn+l9y@q+e-Z)Dc$aHEZIVQWD5 z8rz$wW$T>jeFv(HfEqR`HkDI<=<~JoBTrIodY`SsHlbgnIk9zW*1p#Oa(R7-pM(`$}_eJ+2b30 zeBsv%_6OTrp41L>>R#Iqd1$_1t2pUMtC zA)J5X@CtlCVwVsY(rZL5Z8-R|p#CCnP0O#K> z1daQDoTY0*EkWftSsyWUejBNu0g2!L?2vd%Ari}STtMD`z6XnY;HlxINSi;~{hd|O z*hrf*aaIkmV}>@+e1~mWWXn@GFjZ6E?=+7&TKx&g&Hj5XBrd>TXzX|B)w}ba2c9jx z^993Z3_(83>Mp8>ISyrG#E%G_xW3cyi{>x;iz1Oak;Y+n-=ISPYx)8Y3Cv^$kCXku zEN5NznUeaUZN9=6Pc`US2?+4|p@x+tkJj@%#Z!Lj{rT}1siJq03Mil76fXaApnN7v zKe9wGmJZ!d1Ju{4KD9dDr5g)qf{0J7o}3Y&hvrNBHBlNi&+h(RTWe{=v<8Izd<8-D z?|HBL)JvE1PbE4gfX$%w$=o&u6||m=?*(ppsYspO8P&pW_gu@c>#e}=(sNR5UiGa& zAa(suQ90$d4ln$SPXYFOGN2Exx0*Ofob^`I2T7+ELGp!0?R%}whjY_C`>oN?Jx6e? zLP(rV_v~1m?x8&wed#4DP6bB)T%^UA*=h#?qk5ha)w6pm8AQH3Gu5N9v%&&){y@l$@PML3hJJTt#fbL5xenfW8%pc{pe%#+^@^TdqEEOTHA@SFL; z8T#SUeo5nWUidFe4I}P2BE&OviAbT3W(L1?YK1vcZl~qyeM(H(l<*5?Is$|nZaS^( zHY2#_HAM=bu0PfxIn0PF7)$N%%!hNCm+K|Tu#N;=B?wK}_a>VS=QtwgK4iz^|4cJi znFwbej~iE?2n7cKKNe$Dlm{=F1v(02RP=Kzjf&<^!hgOB#ZUXTidk!zuR9UH0p_n# zJCNKD!8_FI<-Y=a|2xwA#~s59>3w#D^U(Vj&86q1_t_g>D0+W+e*iTL=$$;h-xBcO z>HYmr1pKc-ymxDu031T0`T1N1O_|?s3W*^J*+dNe?#cte!EgY0lkicqs-|Smb^0x5 zg?nkB<#F0-Un8oXLJ$<|8ZVzlF@PjFH1dD<|2BHwb`)bPtswvZC4)K+os#yYM{QApEX~=h^+b(k%=$uC|o2@Kt-QBP%d=GJ<(+6p=h!b4KSi4Ehq=D zqy&{J2!FNt5BMb=v3CxY7D3dntIvx3e=s}vz*~nl4q|V7J-0-@oSFIxCxA^(1ca9n zb@M+9M4f}{#i=o_00>QpH<>XVsuYRioM!Mtwuvv7|pE>&TDwU z>`m_dCZN&ARd4hpFaMAKjCF^sajZONa?6hB>GyhNn3&J(7_ z>w1kEmsmI7=@uu+Qy#i~(b7S^|Ah)JBD7)fs9LLj`n91Aul%*4b#Ih-Th-^5)D_4C zVASK`7-4QzmW^|*!qwHhRbb&KadUNPZRzd*b))Jqf90dd{VFQ3Pqo1R_p-Oq5exqw zg%ZE)uZi7sqDnv66V>|ZJz>j5?u53yt<5Wh9u^jI};vX5(F;*7($MRuoQ z*Va(yECTc%ifrU7mHQsjwDOhdyPjmz<2Yr^QMKykyT783t|BJ;xJv7NTvNE|aY`dZ z<+MFc2}#T2)I#?$JaNaQqu$^$1zTd%j>|r( znjgqt+G#m%#dJLC^(qQLnjSSYXgf~d0lO*!IZkcxSLe&}&MFE14Z_5JyANS?IIhB2 zdP4NZ;|48**T6Ko<3L4CNYHZJ@Uw2#FtT^n6lt!SC2@a6Ye-W!TaN#L8H-bUTV_>t zloj*wsv{EiykB)hmY?^lzu+?mKS4d=Tjq+#sWK?vcMyVS#Nn4u@fO-pGO(#A_^Tt-3j`ta%dO%h*;>WBos-n^B z3%HQSqwa1Bg+)x<@PJbGpyc5wmkx-dZ?NXQ!ef*6OA9=Pn>e1r2M8Er!X&crWSOdn z8hf8*;evtxju>pJH7h@bj(GU!xcdj@{I}1F1mL2@CpOgqYxM_xne$84E{>j9ssm!i zlKA8+LX}&zF>XFyy6=6i@lp3M(>2g-ShE@nt0}^G*7F0s_=}ra{QU5-gZl9qjo_K zWLa@1s3#pMQXZkF{|+bqJ5Xk@(t%3Hb@RHR?F_)B^MQd0>| zRJQmFoZT+rwzeoeO(!l2{C=1S{X5XgFTMRY@Y07F@Fn?GZ9^ZFt5dyuqg=aiA>_vO zZh3WMm0K&Md!LY8PwPQ1(T~a1!t38sYNy6NAg66434#+@XzWS0QxpgbIwoBue14Np zAjyo(Bd&&IXu^Wx&BWC$6J)?@JXYJ2n1bk)a^0K=hk2!$uWM#quj)XvDfYK5Jemgs zYLS)I&6nMmu28mXZPJ+DtZOGKXEibD?wV<>mzrm?#-aVv!>JbG%}UdynU~(EYUwEl zz72_`*BXLeslGQ>>f2SN?{0_C3IwN5=_x_jPNfnT8VvcCmt<}3r+2BML^jzZPltSW zB32VSz03DQVl|u79i60Pv$Lqtn6XpdAz#YL*e>s`c2Y79a^F4dDO*st#e3J7d+)61 z!(n;naFE`q1ciKZAVl4z4M8EFo(zuP*Pg48yXS*r=yY)GTf`ymlhpSyearuS{2%3# zf-Wjd@egOp&3>{dFTaCc+Ak29%@3CLe}270F8`lH^jlzg#1cyN7_J#wiB_^#^9)g6 zNdw+x^xV%=J9PaRkK{@@>&;nByp7;?c{Pr-!N+v#`A4%xDf5_sdzazHj#hK|KJL8A*0L%d0eC&f^D9lGBfSuaLzmx8 z8p6LfvjBw|0wabjS$ z_!;Di7Z>rz?cq&#%vnmzs$8IkEoankegOUW= zAyZ#lW7=C&U%ikKsz>{=c&fe_p~MWMrD0i<>#5)T<{q`GvJZb5SwF|0{okK|rmzxn>I|D&N?$0$!qZ<0%2N9eos`bDLlNB5`e zN!Wz&I~$6>AO==O3@!~(!Qd3xVRsA0nYWeQ6un7o;Pt>4MNVUMwuWzYj7=H_yR6^3&bb;|OtHv?eZDZ2a+A#QOkthQE`=h~Oga;8KYZP(! zTyP9UvSXiUhJ_*2?h&z}&%o@v^3jFA`YYGs{CV2+3jQT3vkg^J>16#MexGgv+>O== zyR6L+0fg+ZMsBrcZ?95FL$%%VARAL{{f!|fQ&hv>#Qk=~kT9`zjU?MblI@nnKzIRV z3$mt%O4pTNSZD%oaBao;4L!q_|NAGy&%ZAD$>rxi{+FzaaM5)X%Jb;q=ZgbBDRL+9 z_2K7Bb}^!4Bp1ISCXal4Q?m|_YCSV6-;Qj9&ySVw2gNg3`NP`shN;&J#LK_vQdan< zEB^+5K1}@Y!_)um*Zi3OZ!g>_PX5mpF!MWBuxP~-2NWm zt3TR|TYspc&vK>vgGq;E)90yaG^zmGTSqGcKWmPpLh^%tXXf|dnDh91oSCm$PI|(e zWGjeW)I!N%Y8eCLxWh{zg@&mYjyu71#?uetnz~1;t*u%~aeOAvNbhx$Iw#=()hz)H z1tWXhU^G3dT?o;Xf>o4L-bSla%d!w$cf4Ggu6WcyR|goq#^S#-|H3__yw#yR#6#<= z%~g1@59HqSlybR!e&lnEmYv#VcmN zQg!B23C*xXkoSX=`1^u?gP8f)b)!E`!erPE2a02chMUJ!dQx^8ibtYEAb72l1%Zux zI9YH4X{GWULm>avyPd*EIXL6K6wx2z_bEXzirM!~IZi z^$COc9VxP3Qq!AMCgZh>{Cq7J0uss`5$;Y4cB^V!W{Cl94uDziCD`#JUYB9RHzFL% zhzN}e(tvcN*#QOyJ}@gSAn@%4s@w{};!=ock2xG>I?@>f+>wrSd&)kc8I^4^*#%Nr zZ@;a540Wgaa=?@D7_=favaKQWu*Zb;f}|rcX_2QGnDl_K{*YocrU-2qn2jk)Jj?J{ zOySK&#^V8Dh5}3mkeUB_4m*X+ z{M;j2p?e>OnG)0C&pyoBk<`JBXJP+SeLKWQq(Uv@C1x#B@9 zJ!2&{^34`7IXmF^)l$@hmHNp!(;qp60e_%eflUvH@=RK0CJ>1+}~%cf0*Ls^255X^xtSw&{_Yl+4wN4n+v z_)hGkf@0SE0B~`N*N>qvg}2rGoI3P z3DRKxkJ3ApZ#3r97!3z$fhz%wj9FYdu&CdU@66gdA78M_KSF161M;2@sa{CbMUrR6 zP5SUK2a-bRgC-SnhHvxFBONY$h%yGkehe-6&9h|?E^`nmtXa$*mjZdiN-@M2qzHSK z?BT!Y{ErZ>|NofmVHaNdqm@BUw(7$!xs){M^Xu}yTO({!?E)OOnZfkzNj{+2_**4} ziJ%Mz?5mYHYkR~VL4dor#KbGdxl+~;L>HXldw?l~?hx`Muf>HZ<5+EvUciA|)abjw zJjmN_*5tN{aJ^1$$rhWO_2!oSSLR=Osyk&(NQQL(#KDLJb1b&-P~r*G8EPP;1g-E9zdiQ0p)0n9c-zAGxG zSt(t9V5fY#NZ>!IS`gKtDaUzVYhe1>Q4j2Ov4QdZEsd6rc;px1lz!4TNV3<+dzWp} zOHc=WK(GWS9aM*lPCh&4USF}&Wfp7QioUS2=tt!4gtqrOJ}*%A@EjdO=3FeNFAnJahHX(U?^z}3OYOX{H8n34bc z{}<^)Y5&J)l}R9U;Zj`bmLKYtJaPt+M<%6EX!dEXlIxFs6_!_V&(4jDe3K17JoXB) zv8R`IenEM1E}OW@1Qi|bX+uzfe58*LR$e)K3{P`J8R648&Zm8XPwPn_=w#PChT{Po zjkA0*l2(-N+eyWqtHk1iAmTr|#G+HP;qNT5STBM$VD9-O7FSc+3W-J8SCCk2aen6C zL0(avmsiyJh;A^k#j#u71r`Ls#Wi!&U)VXxkeTH%867*)HS??`7_Uaw@?0bs+m|I6 z+gyV2y14=ghUxpSF28tLf&AjPcCK3lv(q}4V*L3(v=oEs^so5eDk=fvAU(;2`2MX3 zln*Ef`XYI+Q3kddxGg~24BqaWfp!Gr4!q?~wOhqRrk*ZU{H!z>=bMgpNk?+Y3~0Q#|w> z<=aat)=Pm{Qy0=-ONc%y$!Z-b(yYx$qQtxHJz9dKbOprMiC+glen}87o3WmmHs-h#BXCA7UZQE;LfZLM7R9hZ?A=r;w>R$C|_QZ$q-Jc0;BWyw5K z%D*MO`0S)RG`5&@vutGx`&@{E4CRkO)F4i|c7-_QEc+Day&rM#AMt*~6XAY@u0?Q1 zf(sI|2_sz#zaa5VWXWGyzuF~<44VI9s?<+?gF6Pir?Grdf|~*ZI>EhWM!+OH#)9f& zpoZ>HOzW2$mfE9CnvMu$gw(ZrzrpPYzs3Njz3D$a`4qPbev}26xI7sIDGgLG0L%;? z)kTGqo)Nu-uh~ThF_|*OU&<7JxxV-d*g;k93BvN(iZOEGcOSBY4^w2ZQd6qfLP|WQ z-+2E*Hz=r`PP6fzg9=SV8}cjdIYE2Y}O8?x>NSL5=E*<=qz*3ntNlh!UYfI77JJ7GeehSVDsgdsN}C+Ihnm} zQ$@HP@oza+fYiNHwlLOB3cGWiXaYwe6`|gy;LH9 zFTt-!$ZWb6U`~+$Y~^d}(=5Q9R+DbQZVJsfV(TpJQ1xhterSn))D&@|`shaaX^(!q zLE$CjTKq?>&Mil@ODr>^+K!Z~oQ@-^q-&KcckhuZ1=k&^CfF6atvW{y$fhHNx~(!C z2cpJvykG(Eeo~cDsYltQNue_(j)Q@NN=deelHv-MI;0?To&aoe$DPJZwyGSp*0vn= zW*wzQN!?LvdYk_=9aZIB?7|dkIjV8)wZH?;j0XjdR%snqZmL%X3X!JezH+|V`;@)k z1TlhrpHfz+S_e&Hg0GHdfIvru5O)T3?4<2Jyh+o2Y!I}t+(1%`DmhSkxsS-+`^ZOc zS6diaYdqC~C|SWku!r=UWJSf_uR7)KQ!`ucR|(nsX%F>lx0EE%4!-ez1KjFix%*X4 zzll@~hLFv#N0?Ww?hm}-1l;UNuL0fBjwBq-n#A$)ni|3!kqF>@COu95e#1u{bKvlsV=2A2&r>)G1L)QP1&H@OX))=?!ZvO)&-4?sp8g(xE~F>@ zs4$Q8d6~hMcIt3*C!c$VEh@cZ)bgYs)dsJc&-w2ip(VF2%1_ZF{`=8+kN;Sa4~I?s zB;12wqH2!Q>{dYC;TRyghepRagmA>rW-0wx;vfR*k--s!q$M7cN7VgMNc1s_>7hVx zYx=SB2qYs%Px=Y}r5I~GPy^ziYGg^%PqcfMdm=)9xY8qTHQZfFKicP@KIU^L{g_o4 z(9Hor0CY#UrDHtl)+9*BgeablAqO|<{4wh?m}b`TBM#)li@?C6KUNEFP9}=)E!@|d*y{-EFl9S%S?RKtsYP@!rDd#uM!w*-(l#Bj z(%Oz%X=kj}s#Kj8Gr2Frf@!wl#L%fMVK!_p- zdN^ECxVPDh?zQ=AeBJb#F*V9I_?riCN=(g6ZuOKtYB%%|AsH}B&9J3u#(B+*C$}%>;i;~4x*^RiLvjAZW6j? z*B*2lZD`%*c+&yG^hzZ+nhsM)LmMngv>K$In`SAO9v(3K z{#I%Kr6zdLGX=th))E?(DdXdBvrGOU+*OLz|MB=K3-qA@FSU-oe&gd*8*9v$U0fvN>*>2@@ z@)eE)>m6mF+a=R>>q5GPxFiqpgR@Dhl7B6~#3!8pq)C2N z098$9TMd3BqEtd8CE;ik%44-osH7*$STfO&)@A%iS&^S6+RKm6bl^402P2vU0AOVV_}mUY|mFZ-`V8y zYqpBL(`ZJy4%k*8mp>UMSHErdEG&KjVy`Yj=t9KNa$Sz_OA_~UG2&Q}E!-e68}K(V!np`B4@);0aA= z;kx9y8lfu^NA0?VUz@le|F`?#R~B5AxWPK(73*O?z6(&*07|O#vBq12Uq-kZsmXAm z3UWq`8iyw|&es5ImQ}A(aRH%eR{h>%HJPlw@7 zxh_#~fuc$mC=kl}C5p>wB#U3TM8U~&;RK_fw7&j?Xpoe73_(` z-(JbTGj|RD>J?Vbzh9|%UWn)BOLSR?CNcv+#KM~uSJ};q(;$-z2(&YpWxD*$3ZvYZ zafa^N&Zaa|%YdZI6+R^Se}$-8`H7 zf0l(5i)P7=5n6ex;xx&+o>*Nb!5GCWFU7f6*{zB{VSetuRO6#jutnalWU(63__ME7 zU}5hw;abI;T_`bje}PcqvfUd5%x_ezJH}|(g^G=;_t)iJ7XO>D-&0DcE40|WTm1m@N0 z3;4fS;d*Cg>TlP+<0r^I&S!#s93IK5NuoYI7X2Q|+sFAD_HnNI+sq34I2)(wP57{~ zkAoEgZBFN~k8@J&ShJ6VrXcCWVAW=(S1tSk)tUBjK4Tl)-mewf$9dBq9+N&jbXsB7 z)%5APmzLM3KM?fky`(JRId3E?azFmJH}FDt{An8w*}$BKr*sk}b@TZgWC#aoB2SmyU)crefJ zeH->9wH&I;c+fh}@5MGwp5Kej9PxXjZJfOR{7^R}nsB@0xb3dJ$8BD?s)ZdRG{B5d#tucS0V}N_0va(t1{-TlgvBngqoJu32wrq5Q#TQF+Q)e8#q^5q{abCp$DV7bI>7%wJXJKUzKoxk(Q8B z)$81+msf3=cL2`vonEq=4m9NiTo0sO%-F+k$T5gbqo>qZrGsc8UarA6f4_{tE zYTFuIf4&uDO~POjk&qf#K13Yld(w9LHf>aYH`gd@qrf+l$=DktKCQ$ku5^;|6dk$#ZdoUV9Q1(1U)xQV5sHGB9etzz^dY?dseUIOCX9@f6V_R66e5 zPGBr5rYFs`@~LSDTC{@W3iecJ&hn-MhKy1&b-!D`LF0VH{n1L!xYvp<)zF0}HC5Y6 zA0ieDN{RaOqlP++qaD!$V|WQAUnK^?j4k$=fM9tuIV>)~J{Wnn6W(qLGd$L?IPRw7 zq0mDSzs|Or6Y%X|m^M6a>-GGMGk|;2;Svi-2OM}*#z*_t>X`P$vN}E8M7RGA_t`IP zsG_n+6s@1&#*WFs8Y4anRW&eDANJ&Ns;0xk9^kBsgMsmjy08b|Y1cvwvNs{^n^cVW z_qOmXC2;|vr^+l-UL8J8Jc_qkq9{M$DMrWqcVyguU0)t`>KXZa(vevYch!4zpyxb% zc;3TT)1R;4tdiHC*Tf6fV_F_8(4bd%(*w3Gbzs0|@6N9)q|SBFa}Q|d`Y9sX$;q0w zxL^Bi0eX;85J4$V$AjV{nW-Co+E7DZVu!IKX%i~>jt9>0Xy6Es1di~qae~pTH;(aMQ?zrn zc+keU!`wd54Fz?L=5AyJ*HEHQ_fcaOFC}fZ#`#P1dr?uLt!Zl?$>6r(9B^JTQ$r1D z9kz&8!3=!uUM&-8>xe~kQ+IoGTS21)g^d|F#_-;YZu)?A8a9WlPC=W!2fGL48F4;4 z#(z9=S-HQ2*x?!vZ5;!0la^`PR|a1C6H_!79I!^Wle%V}7^LxDoU{*_=zZ?XjFX^q zlG@hH@aa5>w{eb7`)TELdp&<8BIwGTRlQidNr^KxepB?X_VGG41^SZjNw%a1C2h?E^MrEVt9dDV4VLy4;dw6Ue_2K+l!@&{F%UG3i`;4LC1lS>JcVIc|tdraf( z*GQa(vFdT70NY8CY%L>!CUI1YR|8Xw6!oy3*T}t9!%yujO@=IpJ`|3P3clE=;OjOj zxLb~U7gG*JFLhCRqgI)8D=i^cD{yF^;M~|r2ukzX9;y}4rKQ1lM|w~p%c}G0x^!1J zInmtd#E&(IG1kR>ULCQtH;^Q zD{b|>?fJ5q|7%#io;90!Y6Y7aW3LNBt@jO=4xQ6l55snqO!BmtNuJ*0n!GKXc56AA znModO^{A^jgz6_+>oNO27zkAu20`_c^%LaZo3)`tm>2 zBDVg}r{Jd*M}7J1Vu{q|>lSGv8uPc%sKv5l!03HC(ND+IWeRLV*Peq&AD_%9pPI>O z&KNU%I_LPb&+}mw|!oFq8Dhv4+lHd{Kl4j7zk4nGZfa+Oq4n3QFv^dQ=U6bQ6L8qj(87YdRay)9OIne7D zmat_R+Vn+BC&32cd$IEcBYH9BV&Ahbw%OHovEgsi#X{Jm<>E^Ez3!6g zX*+NzD0^|0e(Ek(81nY%rDT(6q>f8j3pj2C)OH_LHk}5)UI8+^K__}tJ-|#h39`LOcmA$l* zZ{4M&PjZ(UJ$J<=s%+aO*2E?X6YO?t+9lS|td$q8_|{RN3h7pYoR#Z*0{J_v7Y>Fa za8kj8ot$&R8KCJhwLUVfla|X=658qD6P3wcrap)Uo0GcB)W&F11_tk>B?Foc00zg_ zBSFx@V|nM?fwI0ilH6r#Y{zA4Y};kl*p0S7x1`qCY^o|8iW)0PU25&krC#=F2Y1jI zme#zqQa^1e0I5k4SR{W_s(wct6a1HZ!;;|5YR98xWx-#Uc&X*VpG(y8dyH9WrAUAd z_-f(}ZjC$g9L7B7`cU9pleyK?95i;MRWh-^+9*5IaPt~c5|xZ1LxY(c3UXLN6YF|gM!lu z+sjlbicKd120ANeLZ?g12l#YiH2NqZofwP0PWb{JafMsH36J|sMV~neSlnJ(I^nnp zQ`id(7GuPc_A)W>9bt?H7;`beOHL=|V}KW)PMnSbUVb{U7y~BFkxmr(kRZSe0m4LD z7&+nTgmBRUy!^oIR*Jchr97ta^3#dR7~thcYc6E*@-b{3Q+WC5L`@9v@-aaX1H62A zYB4~QL4DdB1HAlbXFZ*0jS*fCEaZnA?J=Ut14d7Vh|U<{^-4$PLPU3r@cLozB1H7X z2(M>gRa2{h7~%B=fntEyH=P)X0bWngC zc(eyo{KNXqPnGt6fGxXz^LI-3wfWt|y31^}y24hpHeb=2Qrn?gG?9~DTX0eSprhG^ zv?{E#Z-=c&>_ZC5rncd<*{Y;n30dK#n#GqXw#gPJwkCO6OtmL>nep8=T?|-RHenMJ zahY7sa-ls)?k08D|DwTXpCZK$*5 zCu@6GuNE8Cm!+bb{Nsstpt1RwC+^cdqIA40M%e42GLMD-WUti0vBXF>3DMt)ruF8 z0%maxRl~+6&4*wvhN=OhGa+;!hN=xwI5IvQL$%@!pA2b7VyHSi8Xg)SjiIfC_RWX1 zWBR2|i~KJ1LO)AES%pbCS>WOFN`F}$T|dYJKBw!8zsI$_%OJOYSv1)M5vU@6O0=a^ zHeY58-rMjpZZ)?5-e3rLy$@>h> zuiyt|g_}3gaf!IFAQupmoeU{zp?tL6z(*#=NhWPN37gImR1BFYK)rh|g6VAn_CXc? z7Hhz3RoHv2{_iR`nC%LA2VPorYu zPD#pU_m5Db#kabDH2T%eq#uj^PWO*Tf4BQ5-0xNJph<${3Tnt8v+%!A-MCnoEDRoZ z41S6nhQXD_^nJtuBwMN(NCWhOV3=v#>O*Oe>e8ufc(NNs2F zg7KuLe{Y({QNgTR55a3~I9tK^Mr(MZSiU=_Vfpe;li@EUd^C;J$;0{o>4CKlaruD;odv?`Z|X%pBF!sdZ}Zf=sa=n{^NjheND_yZZ+WFDnh!+JBuN zrO?4z@2=~httHG4uXD{d&B&FuR@>Fr&#yq=fDhA#iK z654@~CuY}Q`9Owaw;kHU@q0nDWBI-JQaAC_lk~ns%TDekT6a2LVqD>hlo`p!X1k&` zX?$5u8~m)hSeVf3C(N9mFgyH&>3eodVmQ>4XvJW+)DYCYL@V_RYuzFknqH`1=C{gy@ZCc6glhaFSE2cF% z`}iN@f0lseIX;c^d@`pA;-$lfx^Bys{t-8!?Xrvw+SE6=RV_>JXuFHarsbc+}3O;7kf*$h{b;@pQOF-N|RA`AsI&5Uj~I=Rno;&Q$Uk_}S+?*N>fz;F ziMg2MRV@d^&*ae)QV7pgz^Pwd#;4t~t#rBg22BuHQ|J!aDAb8YvV)phVmd)-4cg#5 z&Wms>TYQ9<;B&80cm8i>T9+z{go@&)Rf^-~IBHIlu-71_;Rxzhg4Gm%0>Zs3XaEc(d%T_3rfIMYWif>WssGSmHP{^8H!GfvD~&3U!v75jS) z>iw?|5D!-L(R&IVEz05Q)vEiqb}E98~wLiyyM@MKUml(j&7J#G8En^ zX6`>3{_Sb!-$stDS&Rq_TfK__yHiB97`fu_YX8zsEG8}+#+$Z}h=F^R?^2e2b;d1+ zdo4kOk1X?SSMqAb5yp(f7a4K3yTH#Ky2|*x#{%y9HCM96DmE5Uv*!tHJ2AUHV zH8*KipH(6;yie*3$8WA7q4RHV5JJm>rrls85WlQaq&GKO8u3nU0+rM2<+={kPOkxj zQ%*8miBmt`+-wO|>dmd@WDwJv+s#QW&AJ1CEp4}jQha*2&qj-gjC|VOERJH+!vO>B zD4QM*2q+~c;znaiN=Oec9}ndlk8zZf9(G(z;^{O!Jn7N#P?{c|i2+_b?7~mzRhv#E}7oHwI9Rs}l^zdQ~m^261<9$f-{M*ANF~G}D4+|IR4&T4k zma-Ty7hnh*Erpk#9EY@a;N^3#KL&XD+}Do*UVeJGF$Q?~>EY%W z;N_?H&R9TtxHU$2Juv+dBHCkw*C+kh$q>;QBfMVeN9RIBcZ~4*rP1EQ;l3E*^-OO) z9dZoBh{g~w90R<*;7|f>SnA3NuXC1J-5TvZEf?6KbmLkk zuwR2`JF=iU+e9eNZ84#WDHX%OvSsQjtv8!QoF^Scwl?RAtW|AAwj{UMn#hb* ziaKA~dW*DX9P<5yy~ma!6a}ZXx~ZD5(s1W&Q41H|ZL>a5(Pv1{+NSj+uY9aiRh_!D zfUU$bsWL{D0o`LY@`f5dGO7151B2O#0mb&DcTDP+yRsQRw+?&Ytuy-FyOU>(mXapP zxL_Bn*jvL=kTn9~jv_~fCKK-7TH-#g^^x+9B*xV!UzvQ;M6Q&tJf^Hx%Ep+oQE{0V zrwTQ^MJfL?mI>eNP4SH6$+bl|KVBxz4xU5eqzplKQ`~b zA3g2AHgOh?K>SPJ<-FYIr;YpkUAWJs=i)y17IL4Pje2;$q2|9a%zTd_W~~OnSOCej z8Y{n=pVTwL2^<4(Fv0af4STDmR3Z0S=C8$ao#K?l=q0i!$=m{B@|JQkz%~oqXK~B| z_Zh}>kMYeQ56N^+a?h`!829;|s>}zh0l%ce&gMQ}T@BD8pfTi1;oN6<(njg=T_*92 z?+jy_WGlJPY8lIf-9UYA+~+gd&Q-^1d*~=tm?D~~{7<>hJuFk&cg670EIE_={N2^K z&pTIepKCS9%Qyu(o{#%%hC=_1;rsgw@cmjx*GgfDA^ATf_t}w)rTm$=&%d|+AD#Q$ zX!^&`gZpgHaC4S^e%$9v8S)j}XO6Sy;66VJI+fl&;j47-dfS=Sv)v^f>z(IZ%sga| zbe=P3Uwm24zWl5+BBIw%Q4kKoh7LbGRTRn7;+uGrZ{pb^R<@*Wy*7*&)(D2!$r!;X zJ_*0l^^~)l7fScN3SD5Uh9AhA*1%5mqzd)wtiR%SU@!OVY+5fAPBvI;*Kt%qOPNHW zaht3;fhK9=eLzxX_}nzd=Z1Mc*PjN6^pvj~!vR&1UNg&Qn|Rc& zr~DlF)R77Okv|lh_xyb7H8Lvw0`sYVfyL(8@Tu>idU-yzAzkECAKNEBHOFN&faS~h z)Ne-r*7(ypV>UVOfgzydodP@iHBs@WkHCbU6o2|xGMgWE{xr#zYeTWIslTuj1`o;9 z=X0cuCb}6B(>Q*x>%Qm2upWU+`@9*}H!U-)|8*h5`cwUXCx$f!y#vE~`Y(4D!>&Gd zi&)z5vb)@%_dg)hT3ugT!VtdhOM973C@3rBMSN21Q3eI&tjl+~cC>J{=_2>D=0FNA zB`+USuCMLXBtvMqFh+FVK93;1U9jI~K(E$*_40qK46ih8%N0zf;_@rX3Okq=ZDYSz)%&=sDmTGU__*sT2U}MpcBa$9 z2gC@E?;|)r{NC@Ik};&&3bCge^8)h2|I*EotZ)CYD@4Z*ya7fxC9iKJoV6zgU$&Ax zez(+|3)tgp#2#PCA0IrCaeL2_Q{?rTqmuLAgI;q~q&}B^bJ$7sPH|b}k8d)K=Cka6n!Eb;FPeZ}|I`2({ofg3Km z49@#wF?J%xqR70=E7#eEJlVmi73$2VGgIFP>de8m^QyYcCa#_V1o9U~Pz}{8ql!r* zId6vp`C;A;2lfH;b~rfft3SfyEe19;oN5m?C`qO z&JsBn;&r%Oxh=8tkg0e{{{Vb%N{md*x(aEXQ~@{-F{3%O*pzm$aEA#brGi49Hgvb3 zB}}_CoQ+UMQ_NKf8Ks&c$kO35O;qL3!eHv8;fN%aQ+9b%Ej^b`bDk$IaM{$L)}>YQ z<-B=Um|Q(bsaq~q=|Qcz$))Sri?z)}wPv)q)w*tjaB&r$0<~sS$cZdL&Gi=3TyMHmt=)inIXd2I zZHFn7=h@+Pmnpu@RLTzoqY6mE32QOE@;p0yf1Vv~s^VFxil+tY%qYDCc6fn4Gwm-_ zXV#HyRdwceD)CcwW{{qKN43fvKUHV8`SVkC=KdWJCdLhyIcS1>u_;F zaVP`pr`Pn0R%kS%Agq`U+bzN-6jho{OE~UAep|;cTf}XMMPK^`6WF$_o^S)gw3@Xe zsbE${Hi>H7+L2hj4QioIv-89KmQB=Y_8UMQ7hCPye5r2nrMk(MYQHcP6q{{1(Ak#`sPfmBdY}xwF;6S(E%uMQ6MD**|rsVkzzHG(Yv$dW65*{4{cvn-)E;1I@h* zRDO-wjY9N@&sH}$5-ux*mvL1iEog3phqT(x41SFulsjJg)3!>RA?;{o2sJK+LK_Jk zsS2TU5d!T^hpR*Ad<<z8cj5nq5MHL|&!@e-X#C^T zZyVZhAtujCMT3dlLwosuftU50A1m#D^NYn_`46I>mlEe6o5B;Ckis~>V+lJq@{f(l z8?==rabaIrijsp%(Z!ahJ zxm1`}&`0$)MeK_5zp;XA4K1%XFvxJ1B4u=qN}{=d?Nl4LS!(3HngSqG0Zp{UK$v3d zN*;G$g)nYb2GV-?b>MtAj zSenSS?1`Kh`9Tv|Kj+h5F1&0Rt|p=NJk4?B?_Gb{_{e%6lG1W0WG|tL9k|HzefZi? z%%0-x=BHn-Imws3n95M_{nKLJ!t^V@KA4L7- z-eu+Fk09&V{T^z>W^fkE$!gVTvoDjVhOV>xJXA2Bf%UvcwRnM9&p*e8dS2G^Mpu#E zO4-JG-te-ZZ68_B*Z$@ztmnF5Uto{%pY4vS-(B8dC;qyNwOwf(8|BC(e9q91en9%s z@So}Mx=Xlvu)2QqeEsGJo}+&B%f!I9F|#3if%Kz4@a)*ldw#<8quF&@MH)04O#{)I zWJLMYR5A?RRYLx1VfeXs8N>hT%x!Pja-$otX!A=@Efq;UhM!rCpdE~oK<`36Wbx#I zb`TjON}^u2q2+!C8~sWG!Lx9Hqe-5gR1LL`h>kO5fU_^cV4?XBI)aMxr^2zO)9|52 zHA&iS*K9Sa$|=gX3sE=e7Nzg8_2u|=z)?r=F*+Wl9-PpZMhl8$wBD=2&t@)?(csor zW^Q}=t0|u#v`bXrP1dE|wsgG5ioI4D&^=YGU%=aDDYsPB5BgOIH_)m6vm;0#GP zoCYRW(Oi#?vW_hBEpi!rea|0BEy>Grw5_m{S1 zEE@`Mw()DUF0_YK)*rpW75rUS1nO0B&NJ1}$m1Q%z^MNjjGBdBL?gH{2LqDa5+E?p zb{pWUE)LLw6|bg{>RlmKlc#b>R#sg_*}@*XQIJ=e|2@zxk_l3o-vP*FTi|EeKlw?P z56t|XN#6pSFdPwJuu8i{{|Q0{;}KUJ5vsrOTL z`Th-Os>_G{ro}g;Cf|@cifoz7vI*5{%h2?-3EAR%(DH3BBAQ%oT~}lqoL~LwaKUwl z-Jt0$)|}MwVM;rUB}0?lwjpgsZKh9d>~XdvP5!20O;g6f<~qLn-mIh*KVUb-6qwx;L{eYT{AJ%8JuWDG!q&S|I|`zS7gI0B0@A_mk~o_ z>vnC|_m=MZ-gEc)p0v;1$F}zEBuw~c)c~!6Rt>0aMzkVY2%z#l-*bPznF%C7_@meY znfv?Q`@4V7J?Gqe&pr3tM$?6#HHTcBa=p9!RUcIQA8X{aXqEC=-Skbc{jo+(`$own zKi24HKFTfm@pAc;=XCit2Hz;Xnaq)>sa_pJ65)mTEtvweNn0RujJE$mxcB`TH5g)S}v!o^HEB zUEx#J>7bv#zhTq5y!{O9Lh~`Vc=h))BE>4|>msGxLe}5UaH{xu`x%aSP&lJRM?Bo7 z$2(^ql#AQXFdbI6pHXjw8d%vNqOa+3fc*@2#|z^-kX4?}EQjrC^xe;(j?~#5avz*t z`~ce;s_T*LXUsFY<^Y|`2ZUwbQ7Mm8kTZYO`9r4dTym z-+khuNay#-3xjCRZv>{@{U#E+pp^giV0P`Dvlo*y5tB0sa~S&>D}T@SGe+8G8La+b zdh!4K!S83>c({7;Jx8>kacA*9`xyi4#Xk)K>ip0Fb>p>NWm@h$q~*>7wQ@ZUq#JJv z&i<;Fl`IG^jrvZOJMW8byxC;Q>c+d(_rALER-IvE5=a3}Hy+* zi=(^;@;MFEhhQdV8D;mce*e|0``H7j#NM~t|2PWz_n-tafdlH__t5oKoMIiU{{2ly zvLP~%{{59#9npr!@uYtb=;vr0mz8iPO>(B&6bWJs)oLOYWs)7L9HTfhjb3LM@w(Ys z!qyVC_BG1HJ#_vTCPVnAO;ZSSjB(`ur7%G-HtjO3Ko6cbUy3imH9mJrn7NgS=e2P_ zpfA8iVMjS3P1EBBn|_hNW(V%9Aych6`lizXU($BTX9InDmHp6_+Ktduam6%M<^X#q znYh1Uk|-v>P-U6i>3tfgkQt?&QnF8vMzaWQm#u(EE)3Q z@3wJ1-okfc1LWy6#ot;{-~AIyD))f}3m7euzwrfKTX3piObTTBw|6)`87$*?BX1S z+fkXxjtU<_c3<$Y?_D8`Fl5N?rcGNx`=%RS2m36_=>WUjxs4S?1X(j>{{D))S9J`f z@Fh4vp-Ay?ab~gGXR(^pG8~57hRzUIC+h`MeFw#hmBz^nNLrd1(RaJ$^ZRVK?B#Rc z?H0~sM3Y^StE20BBUeQxUsZSYmC@$cN~4&Any%winwm$G+zTE}g2~Z^DR0RI3>MMk zQ?cX|al&TClTSw1aRKVDiz3ah6xJj=q8PJlB3Uf?UM#tX>VGm(``dzvt>-*JAO|LX zUBt10i*#Ht-WrZv);jO}g3ev#ulf7sm$jmG5nafIt5;b$&tg>TLU)Jq86C7XxcPcy zN}lSJmVf&n<4U<>T;o?a{&|!WOaGy`SZHrf$w)}w>x+Bh<5$mq78^(BUfx=CK^zNX z7`0#cdgGbV@vFU-pHbyIupt{dRat-&C8zPbm~lu~ptldfB4d2~W^dsH-3zigY@t7%1j5M}mn z`oRi^$Q!1ih~Xo1MmM@;@52yse8eHgVc~~FN(1tT0Ks7n5Y;EA#q%&DxyLbwa3q#o z>-fX)i?aNIqfEl*cx&}X9DkUU#g7ZzB(t3y*)H*3ak@fKb(I9%XX8RHIdhYRB`6)qSL%di2nb}iTVA%JJy;3Rycfk$y@k^!QsOcA0H<9_z>HdH{{{N{3GTM9H`YOIW+TSA;JFm z5V_i)DMXV`Um0EZo|`Xdih#vg%@^WK9_B<*Vq(64soDtr#0ke(^5?+HO)O9Yjjekp zhE+hO7)>OJCEt~Sz?$UdNb_$BG4=Tx2O$3{mV7SOzIm7!#Z}SYa?|%n><^w7<_eZr zMW>rH6x1wy*<128Lj^8H8@p!fmkvwgE?T%dI{wYZium|VzC}{{-f7(N32@|DBqieP zXD)4>{IP;~;S*@+*DT!Ic$W3Ql$YmA*H21rRhpV`m(iY*3Gf!(TL%I#ZGbU^YR13i zEsPizVA0GGcd{1{6va4@$q7jTg_#3jbnkB3P{++X^CxMZF^2*^QhAA6V!FuA7Ae!E z(;ZJx$<>`4+)Ne5uo?`umkN2eD1bZBO5#s2A5r-1o_;nNLAhV6HPKB z%bX(Auzz{>E)NkOCLaJFYUtYiP$57P^?w#0zD(0W5#fW646c5L4}W9$@G3SI*KEDW zpFEoV!N3N9N#(1}Jk|b_M`r^7Ra9Zb7o%XrW5ywzA&TL2Vms-XKje%65Vb=fNRN=?>4~jHXXhb@U4bb6afb@)4>`m?#5=@84wHXeE#$Z&iyUPa z_lq0@@{iGm6SO;?&sJt<`ay>*e$g1DMq(m36N)qEf)(*(7dSD@c*x-Sht`DyjVA-( zgBxVH890XzRR`i9f0xfc{2L36WlZ*YfH9M5)0jF4|F|&6Kb-W^IEQ5x9|DT_Rz&g` zNDqLj67QLvhJobch%u1o4um6)fw+59je&e-&&0+Ho z!NzNTpi<|DMF-dn-Gpl+_~B1|{i zX@gxi+jZO1DcVM{Pn|HS!~gR)fV6e48|=36oY*?tWEb(XANI{--Dlz43)imAFvY1! zz7{|GL05?P$hw-=3saiz=sEzCoG_*<8iVi2K{6Fl(|TSi)>{28HDeQ7BfrJkxsk!Y zb2aU@$gSsL+yU92ovcwVtygnL-A=>{>rkH@f_I3$qk}xg4;UH*l=%TgK|rk^Ff0fd zhgk;ls5{98a5Y<$c>(o_syPl`1z|yN4zC3BQqD0l*d{xJV`HOxNO^A%D9c& zUTPVz?PVO4XD^koWP6FmTF*PFCTaG>Q~+6_BMj9o_*&*<9=Y{Rw0V_gPsOq36u%CB zEAZ>Ll6S4zUezLJ9DuFlIde76j4qt%8*%dO_v6)-;#<6y`za8PV5~sPdyl3f6 zS0IZ4|B*a}(S_^1Z_gD8aW^>cEwk+XiD>igynxD7;V_!igYPJNTgcbiX;J)B3g=U#F49V5uK7J5rvX{BSu??uk0tHP_=JF zY>Ze$D+ML+vz@UVofU?s4GR_-G9`P0-tokHiU}ryKvJrf}ode^xVm$`}^(mM#<6 zMm2Q*!bYClzwowSNd-sG_LT@EL_N*eOwa><7kQ63)r06z*H?gHgXD>p8hx5><3Fc+?md6##HLkJsaRfOex*X&<$ z(}Il*<%|qtQ(Tjux<)#7prL5O{KK} zQ^a^H>nBlz*D~B}Jv|oG;bdl|;(~vg7mTFtnNR0l(J zFl5`v<+H&2Av&2q+G-euU-ccAFH8x;1*affpy@MSvvBwE){WQO#LqP+@W*S$&qp2c z?l)d%hv#54&JNGPc%2=dEB*1>AD$b+!FYW#d|;iM7r60yOdd_zw8M?p@#Ib$vd1!H z$6EigxTf{Xp_M4k*!a5e?I!by+iTdp#(bI^XxyEQ z&&?Dx@W#xyQr{rHzp$9?#WwWrH{`~Lq9Pw_Udd@`H{=$33m-kSA@|IIhTMN2Dn57+ z5=Gz%yK__pu`%<>k@-qyhryTXRdyl8ArFtA&olvdPx}XqYYb@&W(;F~2M#ngesO@Y z@iCis(JlYx23n1dVz6QXjSs1Fw*I#~Ogzx|_zR&|KtyNfjgNn{&-mzbwA`>KVhqN| zZspP%f5yP&#=wp^^PMh*=a4!W1Km)u;LNSHTK^ZWjtiCd8~r*OKi+5bd)ly0!=Ku^ z^@+R|9%%f#S9S0iP@g&2e8Uu1woc~`$6Ma z3n&QMyxk9i6P>3Z2=rz@2*x!0~?6EvKcY&v$Fk4GDUU?{h|tq zH}WYc1>oJ&Z^Q@On9A_03~f|x>C>9rSgks0s+@VlhmTd7Dv3C9lf=SjGf&&N>?2t& zf}d64#>`(^4nYKe)XKu6a9d_pp9ub(G#8;aGmQug@sYY%@|nohv2}a<>J!-hfIAf6 zs|~P85NFw4jBM0fGR&x<#r6+sl261?Du8Gf(T>afE9C}9Rt+hY~1$&i3+ST5{{?%W72cPVd+<2|w=-g;pNMm4dqb5T@wAOD1! z#E`{v!P~+$3(B@e+=@agiG6qkTY!ya;t|2JA+=zGEgMpePic|xr0rK0?vPMM8vyab zH(;1U;^SYMy+qtYHHfl$D`u9vkD&jKpoU@@f`Tw>$#?t&Gc{t(u~n1h0g_o9&{g@( zi6y&Y6{|tWcS%6fHS<4{FOP#)M*aD5)VrL$F3pcuYJU7>*2f*Qe{~>vUM!hGhz(7| zTao5HZNwn~3+=Hwc#o)R)W~Wk0@5-$Hv>EXe#BvPN@e&VuBXXD4n^#`OLQ}m+d+_; zsds%fEh*MSZmQ~x=B{+HqD3Pt(O%0=<%mpt73)E#x#`fha4Ll|4hi?6h}zB;FmUB zGJ-s1W8}|0jmPoA_axYj7qUUS3c2n}v)k0WOw!K#vfK2zjw2L((4dJr1n?GK#|nW1 z+9pVpx2fyfHxH%z)$O0Uu}$Lvli^@I*ssI2AbPH!4iET$EcvR}a;hdzi${i;(toTV zQ-F^xx;KM525y}mbyj$?cW@m%B{!J?cb;`(vEFOQA&i({?&r5K#)ByrZioM(HC@~ z2D2il|Lp%ZVeA?*2>h{CMJdbOPYX%5>sHP9__Yf*D&g#V$C_%?;Br; zdv?F=%lN^AY+py;_H7zW`#Kin+PCIF?c1-ApndAO+tqXbSzYv5nsD`%w|`UbpZ1%h z<%sp7xA^<&Haa#MU(Df{vCjqlTf-)hx&VB4{imK&A2R*Y4&(y15Y&TjnskpYd{UZB z^kF6UBGMzdJSU7@4_~w5Tz;0darjm0R?X*>;p@;^p>m6lU%%ivm)pW?4UJ8%N%gQl z5Y!Ky=3M>I6x05H-}*TWLtd#IgZhc92|f*iPu(0$;?(TRRG*mo z=zGLe1dMn)fj5TAQ6aEUi46iE+(Jnj{WdUJ5Ol#Bpihv%FICgHW zHwMj9yr%>MSrTDOT)lDj^RdER(Zcs?3en?vcEKZG8Jn7R&5FGKTY)?n#0L9RUQKc} zA}x9(7SMwc81w*vv2YRgKIiiA7G5DvPF2z29Q&NBkMtSXx1fSypI%izb|lHuv`zce zZL_1>y!!oz%R7s*2G73<;5na{I!au3wV>qSnMa1eFbgjqP|waE<3sLn;I*kgcxCIR zm%RN)X}->}U87n}HZ_T+;coF|+ep)`F@LQ-PX1gpHeWP0<Gl zJ;x1g^A*xf8txjtsPoN&vCN#@y_p8z*y58I_}R_jLikv68@=Ah(ZpTlPsNj)nHxk` zv9rRAv>@{Da^rntF zR|^#J=Ttlpp6OCN7;bVeXrEis^H%Yh!^AEW8^FBSQsB%Gb%7Wb&kkkfiS*NS2^CR) z?wmV+*f+y;e*3SHw)yj4THoG_Wp`;mC7*8oH8-hB5ttNQ6rtd#1+$-rBCs;I%Tu-I zmV8DXi z&XT&%d{uEyulwXw7x$jOT43^juf>ng7C5F&+%pD#o4=S*nkSa+m+<(Qu`o4R%g~ zNFhJcR6o+g;b=C}^dOS3Ksk-e7BVCFWQf40k7qy43_b}plxj%!)12UwFhieyQ|4-Y zL%7MRY}i5gQ`zuE7A~|<{QsK`Z?ka248s2*8-9Q1=DLr!;kECEFnnL2fK1)TzNP1z zbsxD!&s}xHzQ$8fYY2DiaYJ~iB@=q7xTybma#-ld=ZEaGp%b4g{Lk^Q%?@q|FSF0f z{nV%WpR2>da8fU~&xT;6-uj84?I{a4{33iqHhi^(8-@}7(`u{1$l;A95m^|&21TN*Z-}G zfj(OGgf15936$<|#g<&NQFw5RLidCoa5Mr!Oj7{KulA#TD<$-Z`o3FMtAMX{$-Txf zrOpuIa@D)!64)gNs(}0buyL}rYxK_6J_Mgbrk-Fs)qt2j*%QK)QRo6yvghNJ3QW57 zq_P|Jq_SOlQk&I!Qr#3!l{7yk*x8!`CY)W!o%n2VB-w-Z# z;~Ox!SZC&hu$3Ter4V*C&P`n)EIT?D!U18%x$bnNunt6lwHuQosZe_ooc5HuZRto! zorWtZeuK2>$mw+?IJ0ge-oHxWd}DPwQc>4s>BaxlOBd_I^emzGNCE6U?apj%(pZOMc2@nX^Hr9F@ebyvS%TSrfP-7iFdutMmgTkD8Q#l;;h zj4bhrBbwLcD@JJE9{Vc(XI`2_WU)Q-Iv9w{$!oWbwPXj!Dp!!Wm3?&$7I!kQD_7je zyslg^A@jO&#e2-_$`#8ouPe9B_eN4yt3`p=mD?0}UAc1tuPb+E;C1EB2)wS`>4Ddk zn+UwF+*;pT>B@};URQ2q;C1DW3%st}F@e{WTON2_xn+UZm0KEkUAZB=bhF>wV&CUV zE%1G=P|5QZ)0OEjNFuJt9{-ywvD^2#0yp|TS6-L%eK}>|UG4i^c`4uL%3JRHTzSiU zpDXVn-{;C(>ib-IKEq<3qN@RJm)-x{W$gdkOrX(XGtF$!91C&;mz%M z*{{pS6-8KI%*c;h7KBdE4=oQu6ZxTIg3#Lh&~ZU%G(WU52-Qor4vJ!RP@-(8va?VX zkPTJQ7OKi*Lsd-+Ez1v`5rmfJht3Q_L;0a|g3#jp(54`?AU||b5UNhe)}bv3RR?B6 z?+-%N+1b#gL1=e==tDuMkSH5>Sr96O%Z4rwLWP{!&{Pnb$`4%~gf7ny?FvGd<%ezz zLLbTx?G8eh=7;tKq4(#9ZVN)&@xT|BiczWAG^fuxm4!=ghcl*N(WAtF$3#oFH;8g2a>^(}jwBTRC@ zJ6aj0rSo?Zs~~Y8x3ZdKS3J21Im4HRjg*k-*_vcV(gu)jQV3^aDN;E%%h|(phLG!Q z?%+=|s2=N)EZVyG7JDpkgBH`@T(<;KR(6XHsHglzCEPuaS=P){j zW~p`$x|s-brl$zHiD}jNx>c67!xr)qGHE`=@-=4FL~q+=A7elY)!P({YKE?5#zk?; z_8wcX%Ui3dZ7AAh#S4e!HQnF`eLe~V+@SZ6|Fx2QuJs$T)DNp=CR}fg#!RXo7Nz9d zthTpAHB+OBp@-dc^7az6OK+`vO0&N=7z=MHruKn+V zgmT|tJ%R8gke(rzg0w#!ax2-dh%~iynNe&=ZUm!+#8ZS#4;g(LWf&b0hRtu$rh(WH z(@4_LR)tOKmOIfAq+YAGMVlv-mGO#C1R>2X82O^=4KEtDsR zZKWI!Kcv9w@G@mHFT7ljo5P|n5_IX&5Z>6iCxlU5w_3qGMK=rn_w*_51R&K2IwDHl z3q;Y9{wG0R5Zx1ExhpxtiV*Ke6{xkO3OdlTs!~1#3b+#?I@;6QnZ1t!IBxkPNfaiO zK~e#q$ODat*>5syd|GdW3FVSg$+xWjw^;SRwoxJdEzhYe3eBet%T|`|UsHRIU8C3wx6I%H)s>B!9lto+rp$Ry}7f&r^ z&D_Z=$2Zr+kf@`-RwK=oD=8oq_jH(uoe}v7c_AMv*`rcF$W0)YC*2Wq= zgmB{Y)5X>k;^E@$ZY=QE#bWD(i-!x}9ODo9{M-1w&)nhNa>ZwBdwbM4l+j<*Z7#* zp}ar48>?;n4rxdZAj*g6HXIGz{ovJ}l8bVHrN_TjjB^W> zE%_SID7gmqQ&LxsbNLvYOU6m<8PzCn;cbYUW43`ap-jloc)2mF-Sdata;o30lq&Ak z$7IhYWILOY7G;p$?5Z=B6|+dckJ+B;aH)0LXZ%b*_Q!sv)GRm$`exl)vgi;DJvo;Y zt0NjeW=Zz2KZ_XerBj@6?!-{Z~f|O_85aL#;GgXw7V&Wm(S=N^9n&mnZJ#YYr1MxN`x5Z2@n|0M3;z*kQ$L#vVVt+@dVRYPHq7%1jnSfZ#Lr<;5VnQ(2RT9nxO)!hDFSwW)| z=)qqO=Ex4o{{RGd{#Z0Wl66W;xQxn!#X{^_;kmTXxcoy$l=KNoLz`RC9yL^K!oFbyc)A_}UW8>F(EoFTw zN0O2ft5QbWSpN8G3rx11s|8vxaR)M4Fcrk0^|>^2mE?rd!nx1P5m zntVQXeGx`3R>`cE4g^R)R#Vs5_0{1b_UJj4>I0j|+rYD$nWkEzBZY zrGae3gvFCb7S~)KA30oRhn7g2R2jst;zr8Hy_Utfye;3Y|J_KS@G+}3nkS6<{|s0vgjex4->5xI$BW()HwX2cwukm4%P*vu2&W@Wg#;G z5LV`^mPKV={+UVQa=FNvD*5+mWo2<@23h9oH!{1vO1;#0g|eoH^f)au6?RJf<*9bP zmYGP9{BiRaW-h>=mw!R#-~9+A$b38(Ia9*BuLXk+Mgbk*VR+GF?h&f?nB14)Vo@3w z;>Lvu;ocCQj(c->Caz=9ygX)-+8ez$QVfwpjUjJ>Om3XuHSWDJ;>~)d@GUPigx|!X zING>-*F?O@tN1xy~a6!J#h zRO*$#?X7%ek+<@9&y&q>`0ex(zxJ+46Ju_fH)?MA_G*tgZnZb6YFxEf{#3+U*}G_h zw{o@O@0~!=5ihaJyJnTmfcLIm@W732x$>gTn@{$Z>`-NPwxc6a(0Kl#SAiVM0zR;_ z9WWF$eu1W+#qXvfoLR*=USj84w1FRIgF8Yuwoy8DU^7s*DYAJ4 zDM_K|nalVnt*^ZLODm*zsJEn9sXtMm$^&?Blw3R*B*A0u0RV{|JYvZeFwsu#0G#e| zAbr{#a>RWf+&15dI5F6RoOLahKa{R1_CXX7UZg5}m>R&(!~ zc2Ls$Xv%+CnF4{YX=m_l0ib}CvC9h?p@fW3LPjVdBb1O4O2`N$WQ4*xxQSE%(Gd!V zO+{`wmCoN6`kOjf`kQ*x>2GTK22K;Wp+5uU;m{udJx265HGKs1=YV=J z`kR^#=x=I3f9}QTZ|aAE{-WsJYCSS{7{Yw5YH#I5gJLZCcr3Yo@FU{)VR*45BA#7C z=g$fF&!G=S#2oy17~8w1zwvNC{(Wde@)6QwKjY!R{5zQcCQ)MDGyoUZgu_8}h__@5 zeEG&UpmeG?YNF;BlbByjVt%p7Te+6`#j~0(FjtuTqL+Bw>sSpFuiX^exq^HD3TCtM zB8ACRkpTA7%=eU+jUNmzr}CSm;eLvS`|F0|+!Vr@H406qfoT2o7{?Dikewxc< z=LF1CR(XlFUgB3?;>Yc9Uhv+7b%Ef$*K64c=Ik>MxrDO! ztr&F(?OO*|W>DDwCZnLRf8-rLus4;tpEn;dy(Nojdfxm=_&LbIog|0D@2*)T*neo} z8-vDI-GJ@z)!=(7E|B}EdCWZ|#PtHC{kP1W>bZD@W>FUyQWiPSr-iHj`ycauo&WC8 zXJ3Rl1f*@e$>C7rb@uFOoMO-3#!0zx<)SQp(jeabf^A+WBFqv=K7uxu_!*xfyma%o z<92>_e2ou>IbS=Phj)C?;^AjZt!(k|sAgN<8*BKj=l5LR^1;>=CNtZMD1kkyrl>5K>_X`CZwlDi zVREaFGm2IGePTVHNz?Jrv5DvKOqpq|Wtn@w zUyfghUx1%^ka3V_kX?{d^v;eZwMysXkh6V4?@Rv7K-V6^(|E2L?3bW+`=t=NG#9$e z4+UYf^3I|2Kb@1;DZQVJi5OV3;B{iDxf31B}2i7&fagO zJ8mm2loKmTx6iCU)hoT{F4MW{4V`mWTW4=*-d&;2IidJn6d7u`YfSp3+lpTKk=&g> zN?&|iQMT zHRG)Ogo)+)8n@lakolot>30`e^XGuYzX!(IwN%G}8lO5vPq^J@u1!pb6KlNJf=vF2T<8T_MyuvWE0#mH-p{yIB!lzgSxKA@7toonkW-|pPqfd0YU#KmvpmR$U{0(*%Wqs=!DE!E3vP9;xRP_l39~~G@F6yrRYO@B8M~fC!)Us)Y1U%*#%pb<3a}Sj*tw;? z@|~dIqVFpEqVEz|pmN{AJY!IF^>?AHxg|W}h3n&(qyL#15y_V4ZvBn7a_1K+P0{3= zox9nPD#x7{KBwnbQZQg|bBW!t(OUHR%=5X;E%vyg;vW}@ha3m|V@~~$KXm>f5S-v2 zM~{EV+SvQRKYT9H5C3Rb1NG|QoZ~S*4_Q6{4>49T82;f3?w^0SqG23C**PBa?>-Nq zyhG$4mrAQ;fBqr;mhz*sNoVtR*>SbG`=4>qb*y?&S$NU}B zKe3toTM@4$(!`Xo2#r3Q&ujil9GiE3iiw+M`y(t099Z@kHJO(>MxK0@)xmI3##^|8 z@a!c2e=DfGib?)NCi#!2+&TS|I0~#gVX;bz2pWCN8KDKU(oD4xdp&ZVx#*zdv7}ul3VDa1ZAB0Jvbjm)Cb{CsM$pw1phh!&ZCV!b_Q3 zqVmv`?bGenrxO>^H}}&m578sb>5SF%!$!KGM+>&w+PszRms#^@XD=Hc@>s_fdn-4{ zW1U;-t^Acd*1_fIU&v#fJkDGBTY0Rbqu$D$@>pjl(7TYwI(&xu%=(TFUrav?P;R!& zY*{0F@j*YTcKOXXvy&Aa$eTKKL}+&o2+HK+2-FV}Ms` zx3}=8!mIMT=7~L;ZV57hi$HAvaSy2V0I2masP!1A^>a|`SD@Bwpq95p^Vu8QsHgON z#)Amr8&&TRu-03-MgfLr+8*2Btz54F!?iOA_?5TvIRzNLokPGY-pZF1U^sUn0l)QD zzODenyEp+my_Gu@V7S*n0NA`&0fv7!2RNdtefw)UeLW%`pniPK)eTRsUU+hK!jr2H zo?Kn<=pRy)*f0d?;Kbsq$E9|d*Opzbd~-Ion@W&bNjXY@n+cR?h>-?v>~ ztW|*FuQqz=j|~bi{M9Zmc=9U+82*L{09Rg7fZ^|X1b{EURe<4dH38tvP6ZhLP9^}n z=~aN??+pR&^pC#-)sJj)b;FaZ7oJ?5@Z{=)Cs!9dxq1Y37yy6!z?6hJxZweReVE}H zpiT$DU(0{sd=HAhEq&5{NbuJo?$G%Qe0*elkRG1X#>1m+U~klZo56hfWBVdk!-=f< zMZD2^$a{+O>LG85^Xeh*>CUSM_-5mEFrHm>fC?P27{C5mKG8RyzDeD<=;lv~XASV@ zJ4bE)

0;+DjH=(nGY;B|Jo)hw!ir7u7yoRQqsI?ZZX24;R%wT>p@QB!`mXAUWL2 zknb&#qPGd+uvxIJZcS%T-TKb%y5~AK*1g=>Rrh-5>bf1BsXG5Yy{tT7PN?WEL}c;1 zLOD@kWKM{4dAK(>QK``6tdNnQMw0@D<{>rgIDL64-BE(T5P>67G2GXGl#a%U>BqjPoQ zWl72kt^o`=V=eCnuyO+!LdGWGL|_0gQ|4ZAD6q=i z*Peru0P{YAXLie>fhN<9019Mnp{)f4k~+CdwJUw8b)`uG<<2vdsy390qy3Myy)vcI zOL_1zCU_ZVFWMxU0fMoJL`e98VmIG0hSv>xO+FbnWi#&IMP9fKyE~uv7RH2+Ae;7;jh*|oo=6!*xb23@oIGZ&ISL*BD|B>KkwXKznAAz(SKKk!Kl5RyXLPo zc>s+DU23Cet_BIL-Czu-9=_TWJ%vM3^EZu%!sF zZVq3F=u&BRqft+M^zDg{Uj2E1(fjr{z@E&qtPJx6e>%aR4vl@E;7o4OvL=7iWg>drI>sf9Fst(dvw5ueNE8|0RkOE#?*cYc4nb5y41auyhJqk00!69d(X zN|bH5vPJhr?~6j2Sp=fj5#Y=Jas961wWM+?6+ASL;2{lWb(|JwdfJMNr!;frx7FB` zm%$hi27Cd&DSm7Ct>=gJZE!`XV)X-2geO81VF^f**UAIKO7bn;Kbc!^K}7|PbqA_= z07{;N>X@ATvQhgFd4K`Z-jsLq8nco{Je6D5?b{zO1oLI0ao8iVfnUdsrebmhY9>>T zme9P-_H*cKm>_PPW1dIl0A#SYb7QqPb6bJjT};e(u^QYn!Y1qN^KAa8-n8TM3~$k$ zP66vnEN(-m0KFkz`8uzBW5lap$q$|9`ltDE_@Lcu*x-#|$7Mu`uoiJ|u`#tDk~6ue zd%cA>pGM|8+uh#I=Z5jc5Vy!%GKGTy5wH9de)XXVUU{qxr+y53ILN?4)yQPaa3+m0 z?)Ec~-sH_*`DWF^D}T!>QQpI2rB}Y2hpP2!ewN}!uPeF4_ZMJ%I~so6_aYc^6%)I z%BfU2H0!WhlUzzJeuKWhjQ3odXioWE`mAQn#Pc0}SBcYA;>@ViUW?t?-bA=D`pa1^ z`1C&bc7Le*jsD8(CpzdzdnU+F*ky=iIMpBIv*U{n1bItFghY+DS>!GGf7WB=r`Sd* zWG70aXTW%n-BD2=BJYQy@>(`TG(^L)^b;!+)q;8=<4ODuH|MG{k&a+SZcq*U#kRdn zpHYlu{?{nwm^6c;%G_>i6XghWwtw&izq|u7!wPLbiy7L6Z2tZj``z4*Fc_AanL>hK zoQGYGpxKr_;*E+G>#ZKxkE$n92G0qYd!j_qw2@?&qn_=JKr26J*vD|rHYP% z09JafN>2n>z7J0w0Zxp*wwSR&jCJ&_rGRhH+|^nJdmR;! zesNTI{(khW0%8yzTu5Vpl?U}1CpsDZ!HE9kNdOydR5x`}1RTOx*DgUUuY+xDzbVg4~5Ny+bZ`5}* zHmPp!|M)XP;2K>uLqPJ^38U`Ps3rITw9%91=##A)0O5BucB!V*4?Z@1+s39Q61?Ad z2Q|N6Bi8$fdD+p%^YMxvGDJFBn3F%A1$dD|gM;_F&GX&3cBSkG1moHtNjRDv*Rnh- zH@Jym_~sHeAKt3QaiV|$QPq8CvMS#n=_rkria4Zd;D$TZU<@2Wv(Ce;0eQlK#C61U z1g$dBNZyP#JN9Y3(75O99emKB2}Z-5{B8av``77!gQ5dJZSFfT=EgC$Oe~7snQEeo((Us?)0^bZSSojBO75KQ^!0a0sRS3L5?oYCaQFVmjz6_% z;K{e2hVsfH9dqk!&{dZ6FpE05ezj!^ZSe^%(;2VtvH~hQtLryfA=5k0sNdW{!ccmkr>v}pJ`Bc}7>Bzj2O4MQIm0-0Iw>Bj=F<=G#c3C|a z-XJ{$>ZIzZ0xDXCT7j-)zfddCm3)9gkFpL-R$t_3^>61pb*Urn-p1QFcSs+){&Rhn z>#uZVL08&=Zh`ABg*@#*w;0zKm9|m{|-~Gn*=`YY# zOhfKcbH$ZPD!cOm@!U~vU_L**ymjO$Xak`*g$2w@TZ>9;oBPihE9)4-TH&6Ijom}8 z#(Hs4yfsmD<;2$Wo=_+UEOn**-)h!@q7$b|Igwe>m+8~ebo;FO@Higs4$&^nDzHpocms&9S2f;3&AYDir-W7Z&v3Z?aLh89CR*}qN}nD|O{W6%?;oPHJ<-OFkhO4GGcuOYHq1hH$CTdilT>M6D$^1ESWlF4h^EPkE52=-P4Fz$+ z*E)w+j`@0bzsxtM?`SQIwsI^lmh6ou*LZi|WIc5QZqNThB~KByahL8Xx8LAHW4A%$ zZ9xO;$E`nNyNsiLe-~{XIYsA~dH!9zVy(%ys3se?c5XVV26Ik&cS-aetU}LzIWvcZ zR>28l*Nk0n<;;Cx_7D70?v=P^;bL4X<B-YVZzv#Igma6C2z@-tmJcjusfvA3$b;aF6`W1 z|8(c>`WJaV#dBrntBDOdKS?t~YVSMr4Oz@yo4K1j+QzOovxf6$f`6-oK0+FB9|h83 zP5<+Ck%VEB;Sv0ZEKe0haLRj<;5SjuM+pUU))H7Nzd<$x_KPr{aD>s-moOYEolF%d z_!)GlKlV{d%Qh)HUxI1TU!a#xm0SIBinI8&664CzI_QR(gVZ@@o)&GSi~FQU}>3XOWhAh^BZaSEOOHg)+m zzh~6KZ7xOwI;JJltzul}o|?UsuD!dcrZpZL631Bfl0R4d_D98B|57?I4MkO-;sf-Z z!L^d}`(3ktp6P-L{B?_=q7+qwQUuNb=>^uG{xh8@Wgjgi*%-rjx~A{ zeq}my^)>%*c4zHVb4UE-@VGcOxG|>?=k{zYsMj7noeeDWJEPS%i)`&+?nlv~h&Jy* zO`}+EGOgnuT{IIrd&EWjgSqIOarhGriBPQREw5yvUi+TWZ6hl3;sVo;scOdJ8U8OjKHuZjR}k?QUdzan)$ROcCZwB?Z3@Auh-@PycTQLONY}u!{CXls2~q3$btGw05}YHdFvM?L*17xzZ+9;E zVEL2Q--DLuOQW?r7u+`;vHI*Y(*wklOe(KGiBxQTD)k)rAo(Stl*Bae58aY}v`iXCLZBq)1K z+55H*a`^b_E%`3JdAtBChx5WS!}rUNM&0_Mhc6sTz8zjUH*y42(gdW?ww>8E9w)UI zs<^^2#zj=th(}7dRreS(1o=ip?tvrTBMK7nWc6xt^mC7~Sh*#UdxYKh9CiB1GT6td zA);o-o5ZQ1pCMWLc~@AFFAo4bi-dD+H+m~O3XPZX_IM$b!@2XS`-QPf3F*?eD->%J z-=^G8x`&i*SvH+wS-OWvw_NE`*>s9!>6VjjwbFHE(7TRiw=O-iwv*jmP8f_uNNJ4y!OvO3oV*#T<9|# zeAb48eEAa1ZxNofIUd^aT|;TdL)VN4t6RX9`;^^M$3(jn;|fKGi9Sb+DV(dG^q}%s zmY;{B!-p-82g&16<&nzIL(zjgIFmgotvtH&^HB64k2HDwLV0xO=b`999-QZ%^s@5U zmY;{B2YI|q9&Z!F9}iqp6g$Y`?LPS5-*|9b04qluea3?$u3L^ql&{f;#)E_A+m}j= zzTo(iS{M)L{}B`QlGTvyo_7UJE7&d##;zrm7##@ z4HH_{H%@Ee0LQ1m1r?%om=QqMer3gt zZIlp4xqpbu^~N@u>trclqhu++L;~=FNdwe;kEf4Jev77eQv-z5d=(eDO!)i>DO(L^p-I`ev1mg)R=? zG(o!Kj#3Pd-ccGYl3UAp|2s+(!{tuL62Kj$Ge*jtSt@r9cT;EszmR^DJ>SxMzSG1j zn?s?Z@5qgRr%a*W4MInLSD_8xE#pz&osKlt_vr0Sz3mDjc9QzLIB}v~{Q8WSm!>a% zWyb5cug}=AOz(S_5%qh@lUO6ahtu#qqCP+4<)-w-znt+p?(;KtwCQ~>?h}?pr)BYk zWzk6%s@J{QdfjXFx|dvR?-~~a2$4^8b*3X;*Hh`pIqV%r!U;B==aqyNx#Z@1%fO>h zw7CcIPob!#c~{Zw>B`5o-P#&7GOry$^G1HJZB4y>H{6@jfBd@Xj|9ckc_YRxF}u?-}zicW&N$azTNQiGIe>q^z#6@yWETNS;JA*{(h9 z=+FsK!YQ>nJV$f1Y_$V9S zipwr_OSs!2w1iW7;x7>LRH4v!wM%wR8><+n1j0p zgGd(_nXicE%jQne+2$?wz13$kpMJ}Nh7&~mlgtxxo-ez^BZI`BwU4^zT6tA}mc%U(&0r6aTI$@`BRUP(tj%{DyW-_~mG=jq7Y z`mI{hZBfE)e!N-rTl8Ul-xTkpBNrsn#JjH7Pj+46Sq6xD^eAW5|3VA5$H~5dm8y&> zPfEPXGPNrUB2(N^?CE-RSu5|Dhmq!LnxE^0h`ge z@4|6$f|`Xpyq1l;L>JG74?5}?`&=x!Q}~(UgIkZ*Bzq10w}ZJopV+R6<%+_1;loCT zvF24}dUvGwuuqB)8!5)dzc9Nao+Uf&a+C2Ql?dVOaF{h@cG!OdZ8xy#PFZG*%8KjK z#{AEuQQ&hRJ~>*X5}}?q*{P2XZ46g#{b{a!G-q7qla>ayhiB`3hWn3hFA>2kz*29xJGEQ2*B^V59@Un(xo*8iqc zDlV_WE?!N9uweFceo@gnl0K=nh)PQc*i!!_4QMlEnC%T~iKR&@!Xn2R@W351r8bj3z>unbB_PM@EcO#tV1R=#TQ7QgjeLIlLb}S$se~IZ|k5e3Ho~ z>=hx90CFg-vfcakWI8?5rGZC-!w_#_2?K?w;}i`T(3{$0w1BzCs8Pwk5u*MTmB7L< z3D+)#%20I*a56#&Q_n~Vw^sx6mn7G-NW;alSG$E{caMj>K@y|m6`;q z4#SZ~hR#4+6#9D_DP^eI;jUFfmF=f4uO@y0a4l@)6zu2+6}nqs==P%35QBf z?F;VCJZwzV%>@EP2r3y=&Cmc1%h2hX81TGFz>Am^72H=R9vFHt6y_ew{ESsi0EeLc znZIY;YHPcCZ0bsX4ckZHvsiM(M{N{x%i8GTNu{P2%WAP=P=-z=J&0V$@q);CbujRA z>fp~|&5_Q~{Ags|>*>hwx*h3AQJr>+89cO1Y@Zhj-zE2)X1V7zrC++E=shkVmp-IOT#&|O-Axq{_w4!q|y%i9!q`>RS2-KrF1by!tX`8V8ErpL|A z_GrX#YkzHTY%ZgOdBh!j>ycRM7O0aT@${D4N>7q=S&@W|YcTwJN6~ZUa(;(*$v`ja zYS%FrM&3_!G57SkcBb2J51lFJ>&0?!MPd8)&~2q8IK914?gn#TF?T0+HODa2M#>WO zeF)>Qk%9z0K7QqDzErGy7Wed(ui>7u^1T7#&J>HA!y%!_%=%~bMou&9U(*}e&8&Y< zZ#!hWR!z9gnqYQqc~=v@s3x4PCj5z-a2idBBvhwb)hVhvRjN+6W3?9N3I>PUv0W?o z)>0=OI9hTO30$-L4S_vjs1FizQheR`WGlfVkl_zNbpeH4><}FcI>*SYKdc@IvHFtF z5BDdZJPJ7Hu7eWKK*ji^KoxIx1ko=g43wHm`dEIAu$&v&hRV6LFP7&pI}e}paX1fe z^RYFD&HdnIJ`U#LT@Kr_ICgaL3ejYN&&#z0;_yeDiN;YyqyT-!(kqTX9}IEwk)`pL zJj@6W4l^jw=ZgnLgP`kY->V)+`gj|s7RAco4A$Y+*RGdc|GKWVPR;hG>qXap)^+sS z(eJN;<%`o9jpB=IDwz&WH~HdB3&@u*DvHS$H8$~bkF8#LVawcwJP=;yULFjm+{?q^ zE?!K&_^g&?k}s}v>$6(qfHlDta`%~xE!O_)Ve!_-O#a3U{Q)NhVoMysn8YcUwicOO zZYl4~0-Lv(Y%yiNwK~M>%M}&w%h)QOiB_zOCNcWWfhIe;lodxVzN!{^HzLM++(K4o zEw}(FD{>^!^mwuZDdLloCdLs(vPPPW49@W$juut~%rw~!t8T3$0x_mZFWK5g z#yCzg#a_O}ha$^k~sb zw)B<6k$D{{l$|6`tCbDcVV(x{f56oyny)3hd{A%{%pYY*?tYOX{`g@7)e{OXMO;v2$qY7j&weX&AvWli#V zCx3{oBAyDEfQa(VSaWBg>ML->R(+ZB>>1KiixxqE@KWc$$H`EEXIamq$P$>J4rM0p zgqIQ-8Z>#T&0r57O`u5(iSiUfAkb6ICWgeFp`tHZCK7TIBwwidi+muNlX8}rH*`|G z@FfckxtPd4LlSusPa;p!$`>m73k#CiQ`zAQRsV&HCb=hJc;kh?j*oYO7H?q>)8+VL z2P+^CVBV`qJ{9LA0eJO*!-=6&O}Lp7B)pb3+<4MWmn8ub{KoExtwN*@;3VPPRg>(F zt-8b@8c$~I%EeWe7+?uDfX0)^D|^1EHRI3+3}w>obMqjIuVko#1SKDa3cI){R=7v< z&=iHuzFXyYt62JLxjh{onZSXiCDilFC@XQqp3&Hy?;7H^oNr=JN$VG~MwKeM*4==r zgkL=q<=&xQOO@oFESl6>f*&*r;^ko@2%VYHVz&~h=o>?c31?|30Rm2FaMd_n{wT?+ z7B{QOLI9O8L+hI=ti`8>q|an!cq*-{e~Y!vZk`=HAMfmFcn`VZTap5?;#+N!aI~n_ zo4U*H`W2l&ZrIT|tDdc|xh!(GvnN(npGNoPU5PTn>T$#^k++0b48q68ulDY#u|+ZGf!JfPh6olqiPYR)Xvg#< zUgq04=UD^L6C5O(KT9h+HQFspCnSRTA8ki$8kz-&+mZX}@EpQ!w0PFmZ|Awfs-+rj zuYa2#3Os)O*Ea0zT$>m}O|#NfJjhU@g}pj)_urYVK5E-czBqKIkX_=?CifBy7KlTa zx{zS7C=Uh;#Gze6g?+`LLV`tVjJmkfP-n0_4;UG@5{70OpIGKH0=$J2R4mMFsXmJq zRh+n>x9}9!t$BRzTZ*}OHeB3oU9ioNoEM%EY)JS5R}rLX+C)WUjvS-O-B6-rtdhC* zY~QB+54UNjr1E3dZgbidEc>ig-kFutEuj zN~(VW26Yt1#{Y7`3z=t-fB555EcpbzwBSDi7-oKIvJs!fTUD$cj<-wh>*{iYFZ_*W z{sNTG$$w)>2ArwmGJ9=Lg%L;c;E#wZR6EIgs1=A9np0%h@fmRfZM3itHxL6r_7|!& z1^^L@sKI)u9_p94cOw#y%Hf^JDHRRjEjtBsO}%YZ=cgOi;eXQjMsbnb6oDWB2$J9* z&J7h6!!sT?zA+amGW3*=oW(Vek-3SDE>W>6=>@$xga<(%VS>|%0k}fCZ zY6c->exY)H(~ERxhuY%C3nuxr2ek)wxu}B;6zVbC0Ta4xBx)6__)kl{?9=t@s2lqS zIEegbNlk(VsN1x8rX#JPDv8mjj1&`|TmK4sZm+3rJfC+PXe3zC`2&Xm9i0>F*D=DZ zVWimzuSSl*#zg0*6O5PEw-F%%o)S^$F2r!&whHLlIZ+YeoXfyZG^o_5x3g#!iJmG`T2mDvYObL&UM4fc-`hZ8+@pdh+RMe^u-tmgz zbOYa?Zq1Vq(VxduKhSH@gzaeP2p+gU4yG^YEu5pdi8|!mfprG^0spbm9Q5hQq;qa# z1#u0NKiolWs+`al^cBWW=nJ-K1$07R5IM{7qc1q@Uw`lQ1!sLY^aW32PW^|jFPM7&wyj9{?(f_bGKlD?oT==jnX%(dZA^#ucPeaQ6%^SIt2>I>$jICOo% z{aED(t1pSl(DAtYcLb2}TE)??u>FGXk^YpHGJ)uW9i1U|- zY1^{;UMKVi_tXAuH&t2`$Bw%GU>57KJnv(AK7Qxn^oLlNun7t734KCT$_LaZ1Pu%U zT;Cr@T7|j&`V;zv;4pf1Zd3e(e&L5zzp&+me&Ny4FFgB%ej#cd`{)-Y^7IQE`qM8= z1p0-j!~CA<7or%syWxa>A#{bAq+f`JSY&R)A?X)#DZo$QD8KLeg@Q4fn*Hh*qA!@!F9a6HxqhKL@QZ#SdZ`D{ zFHA_kuwfATg$R;Ka6-RuVEck6^b65b4{Qyd&@ZeoD`gcogr}oAb#r(ot~&?C%VX|{ z%0cW6p3pBm%7!FQ=odOo-@pQ5;Q`b;kClF*XK1ELuuFIYW8OD) zx?}1%4r)5XguUgz>s(!T{{M-*?%QYSW1djw175;p2MYE&QGm8RD)$`tIF{xK*W~M8 zV92!fsxk4_spGIuDC30KDAd__OcLhVC7d;QyM(#jj{Y>n4{D=uNuE+_zcva7P)ZFf z6+VrIIp-k;mhai&%VTPv@C!Pns`JC2)yoO{gy&V$3Ee|O7%B5Cg}zC2|ufIy3K>JPdF9=mT@ZCDRd`PkH|h@ zo>t5u+9%9QaZL3M?QE6~k(r6Iz(66|VcS`HI;(~K*eKjLl`~Q(Q6N8OxsX)(b_(}R zVa5s@IxT^jK|FT03Uzo?r)p(4z*#7~pHp|id7dM(Px#{dt8cjM!1{*mgVZixJ zbRZjrcAl4+s$FQoQ!GRDZgvVU^v~KpBpkxnM_)UIL_TyQg?X&+15rABT%!-8g^U!Q zj&VYfh>R5;TO);kFiMA5RWu`ocC+igX!JWfjGt!%5Zl2z04%f$4E5y<70U8FsCDSZ z3Uh>Yq{@f?Agctv;o_rctgt`j!+&LAv!AiTC1$LUD^O0@D?DMZFyCHbRuc;yoZN~$ ztCjU()<0C!ZYz?y8>9o_Ww8!i#kbJ+Hn2U!>&fDMw1+tPgudeMkG^83#H{<>+;s=-5L%0)0g!lV%SQYlkw@W_A!eOc3JiBKEb3XjT(t1Q88EXALnF$1tLk zgXGyooM2W~25q!#{$J+IU1=383;zeRhd7YFV#2qFs4HTecy~-zUgO(D{KsQx6EUy{ zn{OKNC&$7x;>3KJe_+6 z;`x$9?Rt?rZ;#!Q;<=IC(H>bbY z1>R@vBR+{_b5-ZLi8X!n7tci+wHy0~KQz;b7y;C7yjcOnrr!pBSX?|y_V5R%zj!WY z@?_x<`-r-qnB%KC`-pg)eMESSnMTCcD@u=eWFwJ;W+(Aquqr4Ei&Q6TBhe&gvW^&v zV<^#QIXOFtFPVw8L9-lh$xdWRIkw}h>}BooQ<~czI*`4@qoB`7$2fb5CQ+72L##!* zHs)+5-Xe>E(Ic~&NX`c|nD_xIG-7qp3?>@KjyZ#g4g@))iC+>3CO}NN9&-al)-K{& z2sZa|AESw%0ZD?Z$?bXk+D|-je{x`{ZTi7Y=bgAeSqeda{ceUzT$U29QulfVIT4LPG9l(y-#^xJ;G=0dgK%OiidWeviJVp zr+g6mh?|d3eZ>>^DIbsbDIdT3ih0cP5cL)FQXIOG#QpA{4~!&!F#3vrFqbNSkot-_ zRx}8G#o%i9tnE=5OFTyUiVc{(1VFy2NoOqagudd5`<3^-U3y@9iN6Q;D`)k+K7@LS zC+sCYb=5#>k00jyma{ndf$1Oy`~N5O4=V?>mpIt_m)|eV!-Aat!@%dMPv{>;KXmso z|KaK%p0JmAlLyoHl_cNb& zyyze1?q}{#{}4UDeEW%}f0(_Rc>w*x2I(IT>VD=wH2p)t{0Q%BK5q06Kfnu{KM4K9 zNL}RW$W@WatTTRDclDL1z9dXbyCu9$&*VMfr93&j_Gma{FXh{#iysK5EYhRljqc-P zb}%P8Z0~5rE#HI9yB52sKALRTo$}p^HmBmAaHZ1Sxw!z|DLXMecneiXO1cidy`six zN}^(8$tPpUHBzQjL>T~3M$y*C+V^_$5BuNuZR6qU7`^j1mhECr=Ad;&#DcwTwVc7x z#LMg;B_DI;G{0BaI8BB}tki5-+f+c8736Y^wLZ4eFK7Y<)g=Evd+!1tM|s{0Yb6;g zL0@)7d>Ws`DLQ4pRthw+6Vq74X|-5#X6#ub8((B&6B8372%&Kp-G=X!o@x0S4$fdphoz%eC=OF;642t%-Z!8-r{^S}qxMMaK5> z!=u@`yq9O5=lMUkdFSmB`;c2rA84I3uu9*u%G7RfbB?^mg^!H$L~BnzC)~q{V+e8# zpAg6K$s`(1^{1R_ZLormc9K>DJf4_xiIvE2<8|HoI_WPl7rF$X*O1kB57u?X5BwC%#iIdpsluA5lat zeJ2|KycIhhvVzy`wG#Qi!AX$3E?jFR7Ej8t@-RTQjR8Hz``j+JE9+D=y%*fP6UV?Y zzqH)NVXG3$R=E2}4&H)F>@b^IpScug+O#(te^$2xPZctyB|AFQwEEE;g3^96N(uyHB6weW~~ zaMVi71YK13e1oE9USeh`cj~RgT_Gote+~O>z?F7vFtG8z+wMLmzA{|1AW>NAKfpMm?qSRQse=i*o%Wvn_}X#6ZhbZXxu`V3x;94h3PhfKk4_`Nc&6iG~5Q1Ztv$ePgx7u;|4_Amtmrl@U{UmyLMO1F=caN~mCvnJz-@V9G|(F@`$@3rtDvnD z=#B=Sa{_yucn;2nF6CxUz8(Ll9iLO+xPgviMK&9Z6x!~Tu#LxC(D$dT>UV!(xhsV= zgkQjLEg&7P1b>pLk_=P<7Q|`cbU!OvJSt3YSe9Hu4l3a@tyN4#Ro0J|c`=tvvI0;< z@_Un(*R4wW-A*g8Rmnox?qK8J@tRl*q+Z?EXXB+5yh6bGQE1uSIGq!0WI;C`AT+A) z(Je?!;}e;Re^pqHuqDI?haVOnOu0OS(_k&`unZT)ZgGY3@!3FHh80UlTz~FZ&BJ%=SIQf z85Ap(j>n+zXhsWm75bpGR$&fy4A8U_%x<{x%c~+QBda1eM!wu;yKQ|pff-B@zK4Gb z{488g>i6KUfF9K(x)9K#*1*A?1__TVz@tuX=6z6YxV4*C5&w#LOoI}%--G;#r$NXJ z2pCT15ePh=k9l-;^Ffvu5+F-r$1?;U+dWDE)<;W%w~FSSPtTLfuk=!qR&8tHC8-{{lpD^nkGtJeoK7MjWlZl0|1?Qyn@SE5>Q zl>bpaYGp^GN;eN;G;(30A}80tje6qxL>fZMIKklC{5N}uX`l+S$KJItJgl$f00jz( zfBKvfv`JsvqyTULmty@&f*h}QuEY|Ff^^W3At!jn zM!*5pA7e*}75#*{2JGYFlUAZ|D)mMU8RP+8V0as(dl0{!L|q_cC%yzzsOO|rx{D-{ z5u=f2oIfykZF4kHesUc|EoAjmAm6pST8I;nJ*?>KjizaINZFiRgJ&uWX;}RTN{chClauPTBbM6;KnSFjm|bMK8^ZOD`wUzyC}wQtKpV9|8?}X~rf*;)q3cfoaTKf^3w@0Q zSwj$+&r#07I(_Sl=Jj)Xt#rIXI$i{c$1j^4aX246;B_dV8Gj4y7Rs(I8Z}bb_Xz?}oaPh- zh7SzZ5i~X|VHNjH`whD`Oh#i#q&_iwsvW8!mIojs`csfE_!L|9PkMs2&ovib!8#W(Q89wV#qL zTeu6>r?fkXFxXrv9~l*Uckz0J<@Q+t7#HjxrXUQiV@X&wNJ^8f#0*Fob(fG7xE69Y zi^E_$;7`#kc{_w)=~JvrnbchiWO9Yv!Ren9IR24Rayv3d|L&olVNe zy0@LMl>&1H-kSaSBisEMQ7+crz@?bs>ajh%Sxp&6SRl;Y{y;~r9TnJkkvR$}# zOUm)aJhbgj19W$xt0;kPShw+>a$}Bz79pqf4XbQjD7bmKz+5FHBlN|uzj=^Pd$K<8BDA7VM&uAZ_i^-#GC8eV`VpJ8}=tiv}D`(k>dtipX z1vXecFEQ;9+J}qwhPY_W998U@fDNw~p7LJ&bV}bb+Lj#9jYIPivpety)ZSxvbrFIc z_Yvha;|fuUAb&7hfEJWC~5?=?7_v(7gY1X#vjUA4d#gz zu;sTZS1!;=Wm16C@E3PTEAZxKa9_2gq8o7PKD)6g3c_5uMXq+B2H7Qix*7E8I7T{j zE%+-A-MtuOl&bR?$A#W(gI54He#7t7t!)OA-vE#b%`a3QT^o&rr93jXPYo7`Bj?_ss+VC-d=++ebWshE(i{=b9=8 z9;1W(#TR@SjihkB_=1n|sFs)2+<_mc*wyf_IQiP#g&!!&0G@v>ok9u-!vHWXJ1u&E zjM?&jGCFbF7kQWxtE(_YA2d&#H@i z+9~97rXx5Hj^JS)r?pm84o9%xE^Ax&|G^Q&fl!{I{js7z-)qV_RqxxuHv}nv);G`d z4*?%_pMk=y#^Op<3M~N)?G1#`E!vKbLdSu8b>s5~p{NZil^9eiF{o6cQ7Q4&-9S>~ zFRl`Yu?)PW5!H{U0;UJ6G?*&!)?jM9L@U0^f>0eZp5l_Jn5}jV=`I34>r2`^Pt$-= zOkt?Pcigc>1x}%9MC75^_>k-7fH42-+aQeJR|IStKT)A(DqK>b@n%nd&_`TAGe>C? z!X^Ae1(#^pz~vnDGqPVuxYRl+cF$D!gO??N^6JGs2gN6(u<$?nhvZ`ZXS_f1seq*4 zC49gf)b3z|`R$>rg4XGV{U1{oOilIoV9I(KehPke=^>IO`~1;^xWX-`Va-?c!m@r&tg4I4oef*aStDX@8)i z*-F?a*FiUhuI-O>%@u`Zb+r<2C|H+JNw8ZhPlsls@Ei?n{1KZt zVa57#X-m1#c%c=P=y?Ot#2t{Ht>Pcjd)$rYaANVt2b{$0j{@iZfM;bc?$hjaZXp%4 zwdW*%{Pu!G{^!idcwj*Rr`v-@_{#~44zCD{2evpoKs|Z_C!v1`VOC;pAW9Y58Fi1- zV6xq3?ZmW8Jmhs>Lo=ZjRKuZpz#O`OyTk>&o=w8dGdKi12rXi7q1y(yKVSCOh{jqj z(1UYDwqOs=7cG>L0bPz2T`%B+ojHO%fSLKAP0<=6&u?MpMk3DwBF|EIf6C9okI&%W zb@|xb!c$+uDfP@9kbf_y*i=ps($Eh6gSGYO7G;AZ3Ulp1mmTPE0zJ_{HzECTMV39)i$vyE)v8+3u1$rk*{BVd@?{T2Kuy3EN@uL{pf!|mI_46_f zDR9m<^hm?_Vf?ic(coj>^#W!Rh905(s0Nhsu z^TjvB1+%=N@CZCO@fOR$VYEnPAT%t|jP?(W-KG7+m-+0r;cDF~dw~V&Yt>kreuvmJ zt$akKz#vPT!VPH2LIAy2483kMN>a9wL?-?}L~p8NpBC)~^t?R}h+S6Mqrs zig`h`_;d;&Eo20hzc`0bJtlt z{6&1NB9p&}tl>b(tMIVjB#G2hx`|J&#~f2x+?yDbHwi@X8@&Xg_>Div@RM)OQET9AI_e?2*lNpm5#Vz0mujQjh_XpWx`+OKdzoI{}J%I zRqQu9E4|buen;{vcYrNXolh6D2ySJ4$v!!QUvMaS z>;#VehrYUKIbFybc-dYa>Nr+J)GI=U5{H>}{4M-jkdH%m5UAGr-OI~yU>Q$cH=KL< znNx5tKdjwLNh^kY?qyJ`>NhYyIG5ah72c(&>NhY74q~-HCxfVIbv1qe1UFOSi*P6D z@LbfcW@;+(jJld)xW-Pw)m$@ztNG2ZDRA6I3_w;)f~lwKYJ%4_s-z(1Y3q`Hc=Q z#lJcEh#bs#Rss=-exL@>3LNM-y!@9EF>nHJO00kl@S9!yVd)>8{Gmb-hnGLYAJZ}1 zoQ_vl?!%iJSPfdmCu#|5v9|*2He=Et0k)Vn0yX!xlRlZ#xjLWg(NvQ(b`arDq;z8k zYmqlChsTFxIOqy0BK~|Vv~D_n?hH4eU98MpjjoPkWw9EGMbr8BXu0ZEP0ORU`~EPr z{2SbWFzsqQ_%6`$Q@EvL*0M=|`y_x_3Vb9tSy^T27*8gGGJphv9tS~RRv{RWsR|8~ zn$LUGgyLD=;wR_RK5|wMA*YjfGYd07)40$S)WlykZ;V#e#0(o65fg0!`1R;5H{NFGC{J1hm+B;_4c>-A7~tmABuzerTzFXXVT<9KLOxCTEg_ce^Wp%{Dj zzRsc%B!hB7Xczxku|ebtuD+amC$V>>>>b12f59HKl0>2rx)eP+9a|@ikAJ_K$8wz# zYsRxyR~L-f9P7vt8t79QA1R&L57@28bAydP#rG3XHJG$FO=GBiF77z-O|;2xdBwp zy;#dbgSFCbk7~Ey*Dm&x?Y=v--GQO)p76KJahI!c=ikrf!`pqWhy1PQ4{g0*XzPXk z)@9ViYSd`UqsDZ9yHkd?J9TKg)BNqSE*<&9VvIgZebUnK%*0Z^@gsS{`PpZ1?w&zb z0#dc+gi1hNsP8yFACQ7i1dz$W#_ti+MgkBOZ#-Lg0S(F5Lkc$h6}|o>-cc9B!Qmg^ zaC>BWCl^&I?tBs3Q0F0Rb2AoEGvwAWbtG*@F9w@1v z^0D?nL3Q27LTIE2$LouDyuOIX>x*z4rFq5n;8VfxR1Pql!FcVF4(K3Q8_#`Me$bQ% zHm-%Srsz8yzAr|pM(X3qJym=sEt8mzA4xRF4-d!XNp~wO1Zoot{U~U#TkbcgE%$4@ zPFes4qE*KRmgPnR$a13=1-Y?bb*w>H-D!YV?lh1qcWSWJFdG^J%&HcRVIwUXlSW!R zsNnm2CPHH|m@7*PlpJP>03y^)>3dm{aL__Y{i+;@$#wAH{LVv~a!Fn<0@0#`Q~L{J z6eX?U^Ed2V>%$-3Je+<{>U6&*PipU^&h}ji{j4;zsAN&b(83{;FNOYv_XCxCJyb3{ ztKszR%rt$wrzc(AHlmrNe8Klj_oK#07rAq{qUb5-##51T_7X55_xE+Cd+J(sz`%a znG#-5_Na;}XnPca1Z|HZeBis%ix-GJip?#_sK6f$#Sbq&@I3_d@k7N2=0ckdi4Uac zyGC4?N}@Cqehl${O)q7)Y8@x^)KLJf-PC!l(URIPqxC7LwJ)z#mbzW5DXpOBp$(^? z&dG2ZXO2yyoRh(Q&}dZvfbILC6zrf-LgI;a%SL3z5#=?7rdm4lH$1QSpC^aaiMlp{J@+RMu*M#d#du{+50r| zm3d#`j~7X<|39oa$^qgm2Z*yA0DDu#-gmGv0A4g^Edb1a)B=R079b?G03oRb2uUqK z$kYOaOf5j@q3|})rK3J%Y5_u~761iW-8hB9rE+jpn<;gczuEePY<+^%C)A72Q$I?5 zLcP={)Q_V+A+24}-KiNoT0&mCLJc6R%xpjnk`7Nb9e6Xn#zoc>T#dw9l+zO6Gz6q|ZzXG_BnWocgC%pO8kY z>@xr}dHNtL0n`)F8A>_qK4D+nF!;rPq<)7F?vy)3W~5^`3(q-kl@p*|F6pcr9hrufDL|DS^y6oc!496E0X1 zjHN!|LY@2s)F+HcI;~H$^$Fny1~2)o0^j>OXT3gw&qn;;q@8>7cG1tn)hBp&oN5e9 zdKyc8g4Yvx#oW=SC#Rx>RY<nGHYvVKCnWaR73yYLL@54(PXX%{xo+g`f_(zJCMsJqkJr6uIGo7uNBt%v-rn-?{u z%ALqvx1AWtt>y)KiDH%an=NE>Lz%^$DiGZhwE~B~RZx z80t%#N0$1enc>CE)E`rQLiQQlpOpYVFI_(#VGX(7X=Z{PQAj|NvAdbIO-LW zIzFk{{rWtq!^gL>Lb-1}3Ge-yv%J2-*y-etZ1rpPH!i)K8u{`%9$oM9M&J4h-koFB zyTjHmcrA^tZ+&6C^KJ4Y)-PNfBp9ZC;i8!Q*{NR`JL$B39Y_7b>FHPR&8xsjD=olZ|SO87zB zrwBSI`&6yJa2hKuTy0ib@ZtqO^sle5bi&qG0KJk)a74jH{(bce-g&LjlKLT|*Dt4i z^$XtZT1{yMHEjKYcfD3h6E&PM)i0c@!40nh&c&mvEA0C_c~_iegr~i}LOM;gbdFNL zAd)FUspN6QMHW)t7x(#JpG4D)+!?tV*{hS=ef11p^Qm$*q@KaM&d8I` z|2m7q7`dL|91Tin*g}y}rCaA{7?7W?QRHVF>n)^DLd(x6^$erPk7xRuMHl?*qhMvu z?0O6JMQ8VW5ZQW$44}vLUBU0L3DW#ChMiE$L#M{S-a>|q`mk^On|4#YI4aGwc1puazvM^B0>mZy4=Q~&hp8M4p7)Hh`%AP3^)`yP$a6VMsS7!?x+X*_eT_0I&> zGo;OYG>rufnXPAl^Q6{)JV*5md}dM{V4ju~2WVswOwo}G;E0qJ__*C*x!iA1T<+KS zoy4S}kqxh7BOr34hGw}@$2>GBE5F>RA?eaUu-vJ^SHtf3>KVMTTxdiXe?7wmON#N- zGhC=dn1FhQ5lN>tezu-LSqY-VGO8S3Na>XH?g)`D?*V1hyS#C@dIs;#5%liZ>KVM2 zF0{#yy`JHMCBazg87|bxPe47xh@{i{HCxXRW+LTmt;b+Iziz+hXKZ1Z$3wptVeWt~ zPx^{tBbx}@sm8d(P}b2aQRtbXS7KC~p1>ogR?k4rJAY<(di4zF*IYBib+y$1_DGBC zo_BmYf%OdDQ-_RX>lt93W=QIRMxt|cR6x9bf8N!cmq>I*uix+6Yn7#Zd#$Flf*M;r zgXwMphBN+ph6xAbM&8OSR>uP>uqjqKHpSkIuymT`Rs z7$>PbGBLv#M?J$uN1L-)&ybX#i>96-vTS}L|3i_bktMeK^T=Ym_5Iu>j@z+p>Gk-s z#4LPnqGOX z3Fq+kdbAf(J3GV0*s?Yil6LsH-y%})ae!KOxNsjv)p09D- zXYeJw$Dz*Y{hoUHG6Cj=6Q=saE{1eml0S+;N?7C>po=d9)Zu2Y93eM+Tzq z`rZ6YNU`m%Z^4gl`DTdi-qnvEd--E()Sbu6diW!RonDTiCZ`S!JykMzG#Re>qB?;U}N`o94o2- z`D1+z__^>PHp}~Q43o$1P4D8a2yQJ}9G;3@`vf+Nc+bsYwt5?{FYoPGUsM+^!S8zh zzV&tdcEU5UThHCa_=?Kbw}-3H&|Mfq=vwwZ zZ=gN0K2+7it%bWowY;w`ytut}eW>Oju2_UYVGh+iP}|GxYBhtE+^>F@TWf&Z@)KyK z=uXZQZ&E_QvKS60KaNNC4-r{gQ*zQs%k^j-Yf57MM ztaxL%fua?EMC8m4KH6>tI^KiWL+WyajVq`Ha1phD72m3~Lu*g2)p|VFNvxcd69q?G zO)myFKaVRMx7%@lVY&NlcW*Ojat;37h2$yOcULiftN@RN799jLmt(5y$sKo*J63=< z$pGNG9&BzRgMg>kha%*RTX~)Eu+8ftxUQ(a1)JJ-Y-)C6v-&64RCi-j^)qa&z1WoF zQ54npU{m`#HZ|n;)o8D%ntWA-ev2%$S5$t&j`f0E^C^e!UaR%BOQ4!2*@1l^g&k-E zHK-JG>#lO*m7u~Bh*=vnPe;g(&+oV6a|WmfAoZRGfHoM=cj2R>*9#4o zg*c}W=L8wSrkujGo^!v8bH9yq{|e{6f^%QQxzFR=uLZ001=ju0#)O?fM>Md@n=Mr6 z63n&|v)!d;n;bQV8K|3#v(S9G9Rno_m}azK*FaK~G7)UBHkc5^L zB%z&R67Jr1V&4rnetA`7Wn@+4#>ki3)c4mwN6n|8-?#AW`u^o4Uc>kPi{Qg=-I1kM ztmi~zi4}abHL`dK4n4EfY8}kIetu%whcvGG;8aZmK&vJZO-$Q`MgWv*E@UVC#fyc++YCc-(Q1<6y2JFc7!z z7wA;@O~GxjF@Xb4{6j=tqOC$*g|v_Z0a(KE0098?6D}qO z8!#TQ-9Kp|AeKbk`TVh)KMJtZZN+DX@pmr|OvO$QcZ#vo%bgH*fb)I~h8z|v47S|L z9?OmPTJ93`R5@S=UIO|$?nx{5Yp}@e0>X=7SD>MKJ5dM)_HRPsz%DjfodaZ^?j&YT z4Q|c>J2`PDTn$l*#nDA<2J)!z6_|%Jw*!9#4>kJLg{R|p^}E;*`inLQ9$VCu5lVLjK$*SF z#&$9Am~B^Jt8o1*)Cae5Yn+*T7XL|5Q40*{7O(T%qQEO7)7i>;{4IwCnb zCUk|UNzn|n>y1+|22Nys(Nb)Hz9H-`n1)?WdVSGcDtwZo=nwI0V?H+D;PE>Ov02ND z=Z3LafC(2Zy$YKfIaLmvfJ-u{$#crbioS6(u2@TBgi~f8vvJ@K?sDE7N(Byl14q$@ zg)L@+t&AR^x)>)n;<}=_yleq3C|Zj1MK@MqvzBM?sK(|SE78}+)!5uogU#C8vAMAp zo27NwEU3q3?gl6D1`I7A#xDV|^Am-ia@<}!G3CS2ME+%c9e`COKXEO=0A6jdLuGVX z0cFx!?f~R&vYphp!Nx6Acp7b;_$CF(iS^}He222fA*gns)q=r|z5-U$d%?{IsU!?C z<6fG}j{BtLz6~Io1PYKuKG2Y-3hp|H!vGCo1abiO2pWoa2^t}SMu?z6CI!2anFt!8 zYsLP$raiL0=&pQjZ!6&TD}~&y2ywe;3b*s7a(nGGa8A*BF?a3?bN{vyZohIBw=1S| zyJ#l2^JZ~-?QBA?5crFP>ON0O$-#IL6cOxUDkpUaK0(Ne zTLpGJ0`+n|O!Dgi&hufO&mk~t(EYEP+-yYP+&$*0;W)rOKurRz;=}TnL>a0UG)@OM z-zSe?lYqAwl;iHQT3?w2YC%AS{$jt60N9-RHQa!v*n+0mf~MGlrr3g}*n+0mUOUYW zJZZ)D2iE;SLARQ>N1V&eI6R72q)0h*>_kt{5o+xF1Q|9M&DS0_zO#|J%jX%_k#3*YiJ6}NI4!Perk`vGJ3n#NhoeoeZ+yujoV}*MpA6B0an0?Ov_B~V{ITYBZdbrl zMZgSuiw<%-zn9xNbQoZEb9)yZhS1k!e~s*~pz{DLoZI=bKZk-&jj-NlYK!H4diJ&z zI{@wZ1qye(0%XYp_&bRyupUS-aVtQK#&_`CXS8rQ({j08oJ+|F73OhUk(b|btZ3R? zY!=Vut~0j)+lsk`n0bLyHn6Uf?ZRSE)NK0SXw3;eO6NbYJN7Cpg1^Tzv)w1{)?=`@ zpWV35au34-f){=^?QJ3l?d?}5MFZVV;Q81qd39H)Sr*D%D_S_4!cI=6la;3dt8DkW zmm!$M!+{cTH|*^C65;O>;cwW}4VViK3ZuiSW|#;+4Sz$XRd@(ibqh|xs;165^QfGC!E$%o{QqY(<0(kC`$8o4 zI*efoAGygLn3uRp8N$IwTkO_XAZz<03_+DXNhIb3Z1*h(7b8|w0o5T;OwqOQNR-@y z7u5hLxWxxnuWg0|*3EF@*A`gu8d$>giCTa&w?QN+)$wvb#jTL;fCDbZ-&;eD8<`qy z8mzlaqD7Z6(QmnPaoJMw7~yN$6okfHndhE)2nZnnRsg-T@z2-@?BDkx`{)ECZ59~E zMmkpxpujlnF~V~#;kkzJyqebG3J7gz(d*d2?pz|86S8 zW_bvkg|P98?5Ws9ra6IDaO6EX*sLRiex1_x)k17mg|JyN1)JzpY$|bShaEcv3AeR` zLpd)Fmk7aWcZ--?bg%dJ{SQc`{+>K$IST^1n`+bvY?8-MYl+Vbh(PWDu?k2mJVi2z zmfYax{|Q#2`z#y;!-;!q7xv7& zjj*;ENzch014Wluu`Z|kim1;?K`qmnd9Fp(&@jvJk_-HRVzFfQ=|zu<<#y zvM?{OOp9osSbg{YAJ9I&l{j-d#4689%)VcL`{hb$2_S-?#z3&~(^!PSe}leQZangm zb!2ZdYJaxpfRL;K%7HH}N!k|Xk3AvJybO>3cuV z@XQBY{|tRUk9b4ym>g{UE+NM4uo71(v>5^(!OP3f8eTv{p4R($U+Bi#!dG@Wij)jN7`8 zLAL{k^X*tyu|4=y@H?N!O2XQ|_tpo>!=h^5`*-(E%E?LE%cJ0Z?(lfOAV2+)$;IQt zdsUEQG@SRI2sJf+47=Vic;2rQ43^9N2F2xmjo(R&Kq~ckJ5Jxe-N3ZmXaHJn)X*$9 z`rgm;?lfvh?lcfAcWUs}usiDed0vYbG!e%1e%{4FiqVbW3tuQQzn|yfK^+2Vek@2+ zEGFJ7!r4MUh6qPipf_s|-_Li>4M8oeLEm3SORRec?4w$v88r z|E1RU$?Sf8CQTiuuLFekjR)Xg%t-rPW2BqEaltnd86-rJ@3x3 z>fvGE*YjE$UH|&(MbEd%kNCdc#X*8$-q*V*CZG9zy^6;etY{UNyfV@wDTJryZAg8p8FR1*!40 zB9bq2Jnc2;;tcv6v3sK0*GbFK<7xjUB|FI*hPXr{#?!Qd0z_u`POTT2O4`Mvd{5cC z<5Xi{(vyyEiJ|R#f6t4_iP0@@-_;y~V>t5rdl1|UVRmDBfA0dBYlgV*g~O*q-``8> z*RT2|e~2I({Ub7>?b)%>1u`b5S9gq%NbIDjzUJF z&ACu@}*{`rI=V>O>7^Oz-n~w795gmHIwkQht|=$cQ7zZwmiu zX&vQ#K9N)lJ&fnJQ;P)+_d|Gb}tY!w5EpRZdfKn|>QPOPkd9`-YLHbWY3YZ)BpS zmZwqP?;Bp8;4h?j3LOLA%&t$2qO0+)PkhSt5}zmr#7j*>k?b9VE}M)!R4vK70I1RG zKn)v;)=-=mo`p)7Jn~S9HRD;Us|yM%$2xLEmuxLY+4tQU>m}|u3RuWe8Ex) z1m!q13z>E)%w%2*MG0iBKbM3Q5iioB@)-|mpBtP_eosu(2Ask z{)!}#Wbw1I^;t>%ldX?9JM|HKed0zK^c$KZRCoA4`IYq|rHUEjOr^u|I@lvK&v|g5`pVMOzDfvU=pZQ}v+4>0++#4N~ zeDOFF&Vkiv3jKA|jtEz`J!28y$YDcuqXgzn^`Ha{U##^96t(B5aMXB<(xvee1wvAb z_zHsA`iYC0`7g5iiQ)9G){a!ay1JqQxxVE4*Q~GjerkQitg}&H@eZ^$^Bqb39vUY8 z_QYsK6l1l&wZa)9i_E|=%j3Y z#cMyR>^%t4t&+l*EnkIka_BS)iozJn- zR)^xXY`w*hwWd9tb%D}GQ& zXMFvN1!t`uLkcjGO1RjcdGV!uGQU7|`s-Jiuiwz_t~X&V6BZM1k7`+EY%+Xb+FP+f z>?mJ;)U*rTpKLe9GgIwS_ouZhTJFVKx^#oJnSD*uddS~;KFvE*iLY9xmzmbOj<2cK zWz^auMO(vvUplQ_#@*7|oyOkHsK;8LVdl~8pGTJZeril1T~nXxn5jRe`i$%|xIZfa zRG)EikYbdg!Ha?jXQw`6?4;8OFpl*sk~%-B>HYfsR93d|;$i1_ zJ&Uo^O)3L+Qv)Wy0GPqY5~Y|?52uzScpV$}Np8%jhk2uKJqz#7vFhPr*R$|i8Xbgu zVZ&1bp>sI-5$iE74iXHrp2bBm`Lk1xF?P~veLIfzEKX0~W?tFCX1&FaCa~TjExwlF zeeMy~hdurEEbx3__-6RduNTuu+Qn);3v&n5TQYJcHnfR?oN7!=deXkWD0ts`7GCUc zT=f@btlj>x8c#r?hv&uY##DcCfy{N77yU1c*`4|IEJmjb^y(Pbvk-kM;RJ)2qIVz_#X(eM8o03cFsPy%+jll*BbJztX zKyT&TYmJxG9~q+ta@x1Pg?GDFV|X|$AY(=T2WmKDTHnH(jMk_!SzoP+cm9H=)tO!2 z!lRj{sg~YR*0&JJ6`@t~I`SeH8SDE^y~Swqr?SeK#qTuMyGWn6--{G4FDrV~Vw);=L)N=EN5dF-y^C`+D4}6Xsw1DG8hyU*S$sricD;*qT59n$d@-eP{SS^pv;dtCqG^VmDH>tAd<Yv;SyaK{Q0-DTVIh{hCAc~UuiF(Op)>n-+G@P zko7P;``Fk3l5XpzW-xC6A7sTF-T-FVgZB1K8- zEOSbFdF0622zr?}X6r9*-VUpfmHMPq(t8vfG=8JNnf4g95*lSa46nV>aXI_^N%`}x z_~@dozZg#cW_*85>ND<7tn+YuJw~d29c^WdOHr=jTR+=duk#)M`WW|}v-L4NJ4ow9 zk>ZQ4<{+4@&rqLw(P1F1zm>(Ub+*>lXLx;#bpF%QeA@LH!wcyUCp2|^F!Q|<`*GP3bpwE*vWIm7VEEY<9K0+Lxlq>2u#T(@TTZ+#Jk^#Dq+Ew0jv?Qt9KiP}2ju&d2n~0JQom2R&~l%#VqN7? z_ki7cJU7^QNL6hl>sx*6C;Go%;$JT;`~4DcH9dM~-eR@GW`^@!_0;rm&Z#cN-7Z(MJwho(|Ac|GI`^m%4h1hNtiIpMJ*pt zy|f!^VWA;Ybgk@UZY!~g8} zOEjPv!4N1jB7q+pwx_1XM$ONIsVP^tZ#QaRS~Ln@TGXoEA1;Dom*rM7sCT)at{R0@ z?$2Db;&p6n7rBwq2=7LTM(Ao6U(t$p=h%rbrg{yp-3yu&ql40g&ktv(USsV1qY+>n z>tiH!zF*UiaaD{|huvRZCjm03>=5JWL)Oa}T_0z^S3-SdRyZ0#4-dOO#@Lz0A0|8{ z{hL~x;&nW_{!J@R@$MX}{vD-0!)tGJz3Ynxo^K==W_^r{V)AFFK4a{p)B1KC>tmdX zzV%kc7*5}+04daMLGW^9BBZQ2SE@4pF|{h=vq-J3Z5|R|JC69;afz=Xm)=>B8ec0) zkFUM2zDkm`zkTtw;qn{V?~{1mCU_?MeG**?21%2sSGV6ce^*1F#EHZ?&=DXp{xd~@ z#1SywJYU<-erX1dm%-m89gAs!->kmBtLZr1PkEiC<)K6P0EwxrIn(tRqd#@@J;wDh zM4w8yLfNk>Mlr@!F;eyEkSYu>Mw>{FC%H+4yO;Z-zNcsYOzg9f@B`p_r{FYFUn0l!-E@UEfH@rTItDTeWf$r z`7=D6^ZffH^emJ1hv#2TaJ_~1aLmK=c@Y_TX=F!9{4iasFX1W^K}%)yA?stDqhXA^ zKE^p3RC>L|IU2^9t+z;@ght0v>MaBr6)2`HJp+GYIOI!u625xFY`w(<*IWFh_kEJ@ zdfz9x|IB=!B)#6^^3$)kcxgzzMcR5r6a9S>$O~{(t)G$2J{xMJSo$WyCYC-8p1SQO z$cRIxZebcdvGIPN#PpZq)0qgIuRoIt^7VJn-(S)!RId%0c45U`%(?$;{e|*hkp%Q{ zj+jV>Q-yQ1uNxvuW%6~i5|9Hr`PR=cR0744@|6-pP@TOYJX$+z;^ z4ax|f8GONy4cj%ch-T34HE`s-Dm54(uyOGaAzN<&=Wk5wV?do>_(E}!)mt#^6}&uI zPjS6|A9^(XtGxQm>%)E~P5tVZE%+J9BQIG;_M$%%Q}qW|#;J0Ak+D%KXsik8pHY)r&Ukkg%CcK`THVm{`D%>CfBPNUH^>`KiGKM-xu**C9U)P zQG$$lT-FQ-mz`e0!UwG;AX`5nPks!wCTI5hBI*36rFE3`D~8YS))!5tr-i=>}m|>gwQblvtonL zTgSb6h_}6Zh&RtpJ;VjQ{zSdhNY@{#qOPdhZZagkOdj(j^^!-eAIIDGY3+(GPtDJ= ze9>!noZeGf>%-(9z19W8ikGL;cACY_?Wa8JK;4@4?dr5L>oENMdxgNs1-=MnOukl>&A0`sw-Dm_x zZe(5#kSaH7M_Yrm@?VTvk|7&VkUKRPYZxBi`V-z*3=2z(7XT5)Uk`D?l43mdF&8Qk zCZHZ-MAB&l$gV#zG(|ij-TaZTe)=IO-tkpoGA`}ipHUBw5GnI+%&3QbaiUYw!(*$D z@Wzl)|8fjE40ygxzA=RCgYgLEDYhujb4ZE61xtdltUqy~PJROFBSs{h*0Fwe?~{n>$W5CMG@UXqPDXOz%2~(QSGH z&z#!&6X)0LPOo0#{F-ZqNTdc*;ks@=*BM*l{Nd9x{yh*QjlMgSCPq-ac;wrVEZEH`Sm6(0M z<-HNrJd!<>tpE^o)*fj{#WHayTYq7yYG}5OV|_yCTNP8F4O}D8i#DX1y=t!b41A2TObNB{`Dt3-prW)J%5GbBCEGx*bDKxWW4JGwEo1% zEar=hos!-iIdV3F-sO!trWVqL9nj0SZ#M>rXzZyxW4>yXTIZInugKO{Y|r5@&9T`IDy}J{>vK8$bVMm#wGp))7sKtDJXFast<%@M4!b zBb!}+;saH%FucM_QNa>Yo`7L;W?!qjVc{^AE|{Rzx- zf|Bum%iTDi;sa{vn4n=~>m}5C6+-&dQnG@xxc)>^o=&G;f}X(#dHo4`sKKI{;b75* zaHt|!R1q%5)(KC?c5%2I+m+!eY;O*)#`gAbEw($t4Jd2C&dzW%c7i2shl5xWq6AH? ztqlHpkjqF^;fI4|C93h)YI-8LxlwkW4Q{?0J9g_Ud6D3!yVl) zTkdYFbs%?RS@S!QU{NkN*XGN%K(>Xl4as(jY^Tb0njPC!jL#o_TUvQO8=_2WG|R=@H@dlso4vL@UTPjutV~&L-Mdg@~}hlutV~&L-Mdg=3$4_!?x~i zC(E=o^S|q@)>m?|1jsgw(ZWOLq9Ppwr8C1$d~0~G`hlJ-{OaMa`cm{5O-yN>(Sm*S zi!J)a7X4z2ez8Tr*s6Z9qx!|tEug}O@bAO;w*9h}_Q>>QPqar$mOa}ZDPHy>zHz_o z_4Y_;*`fAG!Ls+-BRR_kt=Lg4LGmU#Hh9*)>swRv8@P2E^7&_RLjnJ+Y$$}S6yAl+ z?Yj`|`$c_A4!2KWe^33h*xytCq8xv{n8y!I=aKiYzo&k1Ix4F2t+Lj2e}ge~KJkwj zPv?u+hB^;no6|Xn?dQ5N;48W@){k~$n0ejrb+jxSY>&+0@i{y`hsWo1zt`Sc9|~|| zhq(P6Zf*;8%&KnbD5>7lF}3>jj)Lmnv`6ZT0^BSNar-;m+!X?iFA$5t6y2OyW#CycsK(rg$nj_0Bw>z@b+A|PY5?Q=t+0yIrum^C? zieH`cuW#kxS?`c1YsLS-ayNy^qn5iRY~iotDkWgyFImBI>%vu5Q%i93i&#t!a^7() zboC9teISSO&WmA<5q;L53Kg|sTJQTrB=L#3df4?kacXV z;GA@zX$L$lGu!2-?mEI(AFUw$O$}Qfm#GAYYld{h9AVPlPFB^ zshem75MkH{Akmm;O09qpvuIY!KizT#9<4L+ZheCL`$EvOLsf&;&3gB z&2k-g_kzTfCKg8XSbg&Q3ur5Zf8|(QVON0@$Mp_atG;93@_il8F5hhjcG-az{A%HS zHMV;UN1t^-#?`#8rsLI>Pjnos-qmreXx;!e*Pg(p0RPJKE1O=dyRNyt^{(ZY*|C-a zqFa0G`sFK5bnIXGBKAU61K4{Gdqq_Pyll}4Igg{&>O8Mh=TA6g=yBcuw(=ldR@wew zQ-v@sL=jVpxbN7pz5*+6XSe}Btvp3QE7pgl9T!i^iJcq_Hnp7`9ISBPu)x!NW=>o^ zERv0Uhlkxs`L#>i6ZwAtE=M)CT`D5jg3ANJrfX49-uL@tGWX|^#GecvXyEtfW5)u) z%|HGS2JvrbCC6#nq2#ae+kAQRa*(^sgk&AzW^x3QDmHLV*!+X4EuYY;8J*qkp&Y zcgf&i6pJ>Q^s^tml@l#JQkhtK(zH>TxQ~45xI2Z)Ry?N?jJ2l4^2rhfXvI#A`?gUS)j6(155Z7{WW0R z9A7>7XMN}jZoZapk>h7$@)hp0)K{ym_=a%31K|ri3xTUl+!k<3ccJSBEAWif`dThj z)1Q;&!QY0*TMKMZEiol8nwXt$n4Bz47WXl;O=gbxnfcI0htHdgT0~i~W39r^%Y~oO z#Uf#6+_p%#d7*Iga^Ys46=vqy6L#4P>mJvfd^Ff}qi}LXxHb~oAFyM+xmI3XxW)k! z3l$QDlOwTXCxcCg!NAn`D0_lS$}YI@EFb;_G@Ycw?Z4f|IgHhLd&WH zPcZ)PK6Bu^a(mp51|D8Pa}ph(QxupGCxeZ@g=MAPy?X|%HG8R^I0VAvATb6kOi;xf zul~%(l34ke46`u>7;6tKB~+*x7(CRfn(~*(2UiZk!6ZhCOeh$%_9#jO8`tYWNUMN9 zj<~MJ49m*Xa1CyP^h`RqLkJRoKp=DBpta^%t7(hI%<6Rb!Qk2E#zT z=Ak|+(3M;VHDW=HXuAL-c^?0ih8HE0n9`+SID#ik7OqhSR~K~)CR%NDN@*7csJh+& zpD@u(HC7pTHoE3nm=1rAF%eWh0#IGs97)UvdP2}cSK{BAd?A#K`WY+mM6~oLPU#*8 z2nrNU6yP|J6xSJb0yO}InkdY75_OYuphxyWkLeQP zu$m@ol~W@GCj1E{OB>~xYvKi3Qc#dQ2Nc{y6#P6;(AXmbu+4i&uzTBScF$@;Ea8EurFZ`{lA)TxjWQT118W&3G(|- zPSZ{esGkF%I<#}N!K@8N3s+yE1lY)eQ;Ms$8Z>Pa^*sg~2o1xbKNzlGzJs8NQEeL83O=l29nCjTKo69SQvsN&Ge0 znutJF54>otdC_+FIf-e1WgppRx4xPy^s8{6q^MLcNL*D`nYbwctR$LV$ql%@be~fS z&2*LEB=OD1+{8*S_Z0B{h7p;2C|JI}@jA^P#7pou@iL9S)9^BlzkPUV5igxUzf;y1 zY+8v)M`C>ea`|Yc zzw@`` zY;6s4&{hq&57!IS5O@CrDvAIi4Xin8yMrcjK<&vhB9^OFv$VJMc17@z4 znB;%p1Gv->vv{L+AnBLW%5k6yOXT>PcPyi+HXYvEs9wHUF+=t|ST`eFbzGXDz)YrnOmX?pL6|Zw^=eD~Oac<5>nZscz{sO{M>&2sO zgVt#aj9})^rK=oZ$R1XWWQk3XSH2S)+KI{BNXoBxAM2*s75(% zSX0iU({1b&;M8h?_jzHk>3XP3umqpF=NwQvf{ow81Eq7|tQnvX+~yYo9XMlqrVqpZ z)dvdUkJx(#gN>iZEd+YDS9b^+d+y(p0XNAw#C=irTwJ^z42e?~@hC1}!#hMA$gxTs zHmLy08W7gZQwb|6S4$*^+xT`+>ZNzUN_O8Ltt4gVf|{Eyo;i1AcM>d^#3n6wW#z9IpRfE6%Y7 zABEiw0b_omn9=|d!Vq2-DXN_D1Rl~)(F8=S7Lr7*!B8(ms)oO+nyob*^Al4(glT*R z|8BvlPS~n3*ts}c2{9~v9^4JFdev%u10M5LdARH{{JS&v35*FXwID9EoCfUB@DHzoC@!ylH&gJ(F6&tL zqiER+!ObVhTd-xT`<6m@M1S7fPVJp$b|&LnG`*l^cERvL2(27VV0k(K+&%KwVPj0VyZGX54kY>}_V|3an(8}KB#=NpE5z%}45!$TnD zCx5TN$3QSchcb|6X~RPeXw&1Nvi~7GkCSdhDUAH@iVz!B40y^u}95=H{iTJoc?&>=0WIb>yzQ?Vi9zaEJk z(a=|sZ^{4QvK%~PsH&?1@MPV#XyRtYX7yGnB0$F&k+DH8#Z*70*XaaP`jaE)eSAWN|6w>HG}AAX>P5JUDMbR_a)>OnWXf&TO*DX6mU`egeGQOI@#2yzx05Wo;!hTCal=;IRC z;dOnNqG`(VcV=SDeNj+VcSNb{g&h6B_&#))6lYU}wd!=59?|j_)bhs(QvQ}xjj~JN z$0a|c$j~{!@YHa?{&m#gBnw!2mc;K@BEJXuyg#4vS;xr67U|LmuaQAT#ukuy2<1uPFnpk-W#OvMpiHhGx-s16-u?|DDiv=7oomyWE{7sU^@V39At zLcEW^mGMI~#}6fHxWBIemrL5%+hEn0ZX_2i_g9f+k)_NrGQ}7>h?MH<{not)`=!Az z{`odAoEt@cvvfyT9s488T{0EFcM88EORRK<<5m_^%D~Y(!@azlNOL@yaQt{Km=Sgp z!geQlA!28h)sk%_y2mT4lmVquj|XNme6d#sfp+8T$|2?yM1&RBS(aN_E_d))>~>T- z$QifN3O4>w;{J^?1P36wIwgx(845OiR~wKr$QU#Z+-DUtt_atWnCun?tyYY3S$qix zF^k$v2DRpK`UUQQN*q>(EMzvkSm-*-arZ~v_bo(2d(al71;fUSqwbN2E0eEx;w0A= zX)RjX3qcQV{;z7fRWe=os02AFg>1t}E-6>;xV;qb$8$hY71)%V3bG)*noN*ZZMJdv zgUux>8`Ak#0=Wnm2;{0+aLT+2ah^Jx!&9TOOW(H=Ujmn{0b_M8wT^=n0HkY}_~Z5S6Emko12kxrgJm_L(&YyjN`-_#k5dwO zi{m~MW#sd@Xlbj1C-XRu0n{D08`&Ej1l_7~$Coo+1lSdC3;4Tl`7fYsy7BJ`>>~hL z{cOjvm94N00mnL_g4ikitfm)(jo)RG5@jk>Sd z0gPpnB(r&zM-?8nx8An=QstkuN&NJN6CHnw$;rw@ z6Xt?&d<*fNj~NagjcigC?CPx9X3Sg;$4*q51S6XMIsUaHn(!Q@O?(!eQiOCN5bQxM zqNb3}-E6#Tm*g2scOj07^S{C|h>oiL;YDOV5~BrwVV@CUui%Cm_Sb`(S5ZKiZ&c($ zwy`pCSAfLg4Jz|!vW_rtk$HryNHkUPC+K)e@=@9J-o}*_3QLle2*4t72?6OO!+$6( z0SSgiKgcnFpCMiIfa%vPw@m_4pA~NBS(AX&#VcjVLDHMz6iKmU8ghqdU1lPMNM0s# zF9Q#tfXFB`J)a!!=JSdM4tYt*-r(k)M{y~6v}uhX@ub`To6@YHI4?f{MttT#qq$q> zB!Mr+z6UbZQM;nDrE+Sp@%Q0bx&ur^0+M%1&qM^~Cn01^%Ur$h*nXzRPnytMgN!Z- zo1Ei;xu$)pY&Cwu=RJf^<{`U8fRga3jsZBCcjWcK#=q6@D0gFUb+2;-Rvy6G$X0yP zJrBxsQ`3!0K#ncE8|66-XbT{^P9DId1#-EFFG38fED2dl@eSK-#-(mQ)c!W?Fiofy zZvt%~<`(iAf~+cs+KWpdC@+vxWrVo+K^{Yn&tw@J^>a0;2AyEUlWdSHm5*RRje3O1 z6SrSLm}xX27))k%-~n%Z6@Xc(XbcFIA)!xx{wNd)LNDb+X*Dv|BdlZ`B_+?uDWv8Z zIcE=+Kl6Q$d3ani8Yr`kzwoz(fAK`+Z>cH#+9?Xx>q_SwxA9t?b2Pa|p_EoHIH${g z?tl&;hf1qmt)fpPhTCP8w&J+7#2n-%K@Od8B!BKjA43z5PTnS=0^5GjDt8YF2X138m5Jkiph!j=#SHvEe#jDFcw0NniraJL)(p1{5ze-W(I)j0}( zS)C*LMZk;I5J>hI{em@oQxcL&gD5;jGxW%>S#Ftxq&{o(iw*tq3=@({oj7HOwSEC& zk{&uOY2|6%3-!{C!%R~OhVIu!e+v$R9Uzt(HOao3+AwgWLWf`~q%wihU=uC=zTfry zVQ2znkfWY+pv2hXCEAZqe04X{l_p!cs%@>xSFXYBMltA2Cna-h^I_wqN-1` zdl%sp?4FXJ%m}Ax>^{%1`@9o6KRMu(z3t0SA}h(10qsO`y#<+X!C#^&iKP;iZwap( zGicIve+K>LPgGh=RQ`Y*-Ay2+o7Q(LvXq{C+B}+n%05vF`NmB_YNvnk2+_-?PyH$ZtcF6d?Lv z?1o?=39{Q@YNlk!JP%7*q-;lSR7e8})tK{)EP&!5{%wo&vko104|Ts8J!!`$=IwhhS3+1S#sC zwA~kYl@4q&((xs-wX`2C*A5I)WKl1EBF9Yp1R+kuPnxbkV~8-WPDDK8bPEu`-R&j9 zng|HmDE(@`-zZHBNy2Be~R1;>xyjE7lHhU4b*~P+6L;zF2-U40BJT56-_e!OT3b2 zi{fgbIPxKOtOL2T)?m|h%$?C#N?uRNq6G91E?D>F06d^UcZ&X4+w3%b6}HkB$>6+{ zY**)JJI8&6ocI48Qk=I9L-jcCG5sTz^9*yQab8|raUOWGHW{~E?J)_om^2Pdt(ROG z!y0(A>yrME;KJxi!h`p9)usjqpWXMfdr$4B&@IV0VZ!|+$a?&5)@e5OrMYa zN}xd}(t?}k29zwY%VZ*Lwn?N(zE(Hq<ks#!KTNcf@!^OL(6@$kykSL zwdN#0g15AZp%p^Bau#`jjr9EnMit){U;})6fZax7?O^cE0?DgA4F*RG7@Jl|UP4U= z_7wU^G>!8bfy7^e-h3ZjK+hv&Z@d`FP%ZsUr)eGJ?{`K1lA3=p>>HSFlb*hxLK77y z<8S*Yg7_b~QCfi*r7n~N&>)2FWw?0~BB?2aA0@`NGD;pHeSCMD6IbdQk&S=w<7#7d$#@HV2D|sWc-}&u^?eeSwk$ z+F`qFAlP&hts#th8%K>Cnv;jPu?>#3Vv4;B>_8XtXZR)5cFGg+Bzvuto+WRKsCbhku)9Riz)pROum^61v7yxw#LKWaj*Dnf5c)oj3+bg~>nShZ zddh|vv{5IZ&I#g9!2o3?{20&0y0uXe3IMD(lcy zash-*b;+el8xARJfQ_&#SvsNLTaiM!#{Vg?XxKJ<#Y|GmfP4-M>7a)T^#n}*xeE1i zTBdo4z2>J#AHhdS%9P4g+isV(Um5ekcv;kdS08DP6yAws zV!L>#MSK#8X+Os`(4%cL4oPt$yiAzmERJ!HTZwz{wy>8~q2>mjye}>@>$xft`G17G z52`pD_)=6ADph$+tpwhro>Me;72Z(nWQK7sqCQVbbd#@HB;P+=kaS&5E$0^iT^qmd zzz~|L;N_91-^&sM{_XnG%GmnC)Rw2-Vv~5NF z_VDU7{%l+gJzC-R>f#u@lSEZa@;L6zsH1RymMn^Q0JyxQlDs_x7 zlxaJ&q!D#6Q(7gR_IZjWMqVv1WJKMkW*{kd)vwSDxTq3515?3D+${`qB}u;~9|SA~ zi&*aQ$m6&>N2qr%(h$mjIu>Hwyb9Hd693){4tWy)TEHP5cc3AOK&st;1hwwJy7$z^pWq|{Izk(csABE-3L5BO9enPA6$9T*#KQ#C4 ze`e7qC}y-2qH!cD<&XqhEzc5WUoU@ENfFE&WD~eHV3Sw-rooCe{o8>)d0D~w_lk(2q1wiSyDCzQ4gD{cEB3uQQs zKjuA6kBFw1n%=waAq%PcD#>ekC9xa;^}i^T{aSq@XlSZpw}=Hzl`QHMZHW3L2@s-# zE#fP>6a8;0u7o&v1j1HIe|iFPJ14|(C&gkvp7kf6`X%v1O9Pb_mx4`~Yp_#r%jbrQE}1>JS&DJ0Kq`sgdCC%J;6@=9 z9c=nTaxBiL6eR|mz7H}d#lwJ_M(_YukN|nLxM*FcpS>L4gZdqnG!+1EnhV*HkjXYS zJ8FF~1kg+oRVp&eG7PitKT+(PIa)6wSS_;`R?yXxiJ6Dc2^fwMb{XU}*c$y-02sJ6 z+#shK75gK=i=40I9hGTrCFUy5X6ZadGuZgo*m@ier%tbT0T&MHV^aUOupS0jy!S=r z*?}|5DM5e$Q_P9F!lXQin

0mEa9-!{#!4yiG?Gs-H2qK-U{PK(A`XhUx7>J#}$` z6;6PbANd?!UMJ!|iDdyqID%vyt>94!bD8750Fz=mEQvn_6JwApWLyNLZalCl(C5SI z_8~=#4vHA(DttK1*Uwbxxp}kFug|Nf&smf%B@_$&`ur6eE2jLri}pNi5@=d`n~pCya$1 z`BEDbY`)+BU2E^zBZRS=OP}xgtmo05wbovjz1Mm#|My*&tyKAtiu4Cn>-|H5mUv!_ zcs^o8EC=tVc_NT`(3wgFSkNTANjQkTzEH{Sx9z9@pPXM4IlRUw;4BPy<7H-n`IX7k zYQLuLvGwgHlQNdLH8@gccSd$OX=YnV$YKbX@gjEs%eElQ9+Gy86j4YMpJ*|a)#=tb zQn;IZ;Yl)TGS-nsBipjGq*ODG9C0{zsLxKqN>OYQanZ7#D-=_ZeUQdHu7QJW?q|dE z$#)CILm}RzW;VTWy05}&_V3xP$bC0^0N|Z&ZWU@uhaUW+&D{8Owr1#woAIByUXaF> zSlySJ#s)X%_i?KU?Ct&I>ONRQO?BR6=8s=+V0}ha_KOjxmmEhmdU$o9@%#=F6#gDLeiy|-U^1;On8EQt;?s5HfnKWjj@wF`Ks z2Mh>Sm7exu?xE{<)9A*s1MSb1>HdhaUU7hFpJP^Mn;g4>L~J+f$or&`No6NGQK0|prqtr ztGa5Y%Gmo8neI#u=SVd?Yrv|TssoKP@ei*Z4XkuK=lhkh+eK8Bsw1)b4PQCOB}&NN zp6$Z~ttU-dt33+pjq7+w>n%LMLso(K1Jd?~F*uax*H`jp?))7CWuKUY!qIQtC+UI-q0 zHC^*yfX9Ydgl81$UZ^(rOs4Gh;{1;D&}(bSVu8r^*U(e%3G$2FG{EZARtU(?xkC2z z`Ym)?nVGje3Smg(%fD_6f;EE{E4<5Woi=XTD48VFntDG2Wm83dIl5#4ef+6~_d`A2 zr(rWye!snx_>&co#yq$^rquYQbdGFG0}?+HK#{FeCRbO?WV9hZB^ffc0G?V^I4L3 zSD52xzY36U@6F5h5D)A(S=)^%uvSwR_l`)PM@i*4YYN23X8u?034oJToTBwABlR%< zuU?R^dkwoAZcFDEJ_w7{^`RLuuTe51Q{OFqKD7N6A(DyvuTihgq{_(7Uwexy{$27h zGwnz^Kc54%*yr|oDqqRoy8U!@8;_|5^#s0|Wqr1sG`3|cPZ>;1urf)4jT5sZ)Z8&y zT`KF3$(pvOHosX?O}@h&+|ZEkbR)SVouAsCzG64+I3mDwzd_^6dn{(|>ou}NH$&r9 zwwrK-Us-f=xfz%44l3#N+Wb5O@DJ#UyWv~!{l;CiIJDO(U&jB1c0N{?9?4IBBPUex zoDa5KR@8C`)`8}FI|D&b7OwQ?dx%quT&xVy^AASzvEXKFrp9UBmR*{f%hWs-?5A) zgV6+HB*?9epHhbDxEJoujbw7d|B!^lD;AGmdB99?*p`v_D0tfL)=fwW5x zEtqz>fq=>yg=^!F{8)j8G1basvBXT$T2O8xkZnZIO1}`7kqKF{blka2OvQ+zLlyJD zYOi8KB&6GDJ`*5luEvyTMHNY3Sn4zmzbhB<;}zWtMegRbI-mqQ%(RX{>!@Q}Hi|vH zI_GiIS3H{0N-547gZyLP`9*kW*(*OHx(o>`hVX!q879mmN6f%f0CYtVN zEhKxv+F`G!Nuv`SigW%BXgAnT&uaEyC2KeN@FJM*GQHJodJBIP`SmY#(EEh9 zs=As>_m6R0mTk=}dRvQ>k3WIUm`9hmbFxO$z3HzX2Kwtza8{Nxe@%b=Lgcdr*iuhkUcAfMrndgFEayc&VjfF z_WHd->!UUw4qtR-bA1*$kD-!(F`L_K@vktlic5ss^BYtZUIeDNu{JWk z?-!iw0s$FjJjC-EPUKlFkMLu@@;^wHjbsLaU92Y~1y4vtbYST{7zwh+?YuZcx3JygZm? zl3G+|&o&^!Cx{|l+#WHlX6w=YGLsA|>(GDp`u2>n?#_d)F|sZgjR@=9G7i6A zB*mVlZBu!_TGoVJkWZZB5Fu+ob4Q~3#POF2@!SC<$Vs6g8id6bqt2nblPTrVK5FsJ zoA=Qj2{B=&=E>NmVE(C%9;wY03=_Il8o{a!!-ObWhY3#~jR`Zh2UC6LrR&NRR7+=U z|FOVdHS1N2^Ka?gJ+=9(jt}Sk64sNgUrqY`m2Mm_fgH2(ROcUkd<7%TzDkgT+eqmb zZ*+dhEMCif#Xko-mN@f%n&Sgo)T$vR5G;RQ7FpQ31Xu&+hax|9bU#b=*2X73#c!Iu zT#>Dq2#h&w@1EL6Mcn(*@I_saSQim^Nd9vzCcFzia0@!vqQq9!ZfUB!AxVDd{Io>th?Th^O7o%Dd z*lp%ATG!UfMvo*=o2)ua%8)`cLgv_ZcK!eeZl8JjKMJb=!pzbYYpQXMyFTZ5I$xK7 zY5anY{9JQ~`?XR^-eOPLZ|4tuo=WoNA~_gJ%8)@`SL1dZ6j+YH&~=UMmX3n zv8T9S@r5NnusNgRe#MK#c(#bo?UzWg>PGFZ{}YycaHJN1EURsQebXC$$Py2BWCc3T zFVH(J*j#v8-#@WH*6BEZFI^toOk<-JQfxldgSLD(Q}g=zOPJ?$6Gu9Kkd$EUt21|n zt^sC(1fmE5ws5WM^#N_fHkG6J+_Yjk_h8{-7}3!KE_yA(lKjpx3-v8!D@n3LF*cJt zoRfa?&4f$(K0-}e&8NP|=6>$i^S!L0j8Gb8mM9JT;K_i-B<#2MN!WY9rr{nZdIhs3T%d_b3iQc*pXmy5J}8LRyu0=U7nMZ&|aei zWa0eMHVMf#!$}hJ?x7srIQ>>S896^cYg*}KBqV3ut{w$yhVAiJ+oBW9I{(}-H7VQ#QBF(oNsjNO-GASzc`M)XMVk@9S`luJzeu-zuvTzo`q#51>$iM zOHCsbt$V3ZcBW1?-xyHe&uAmI$>9}8)#@O9WAURL%E8wAP|+95@$dF$-cBx&4al9)h+ad%y)eL>aw3 zP3r|1B+30EkNu2UM|;r^^N@w#f}!=K64-Wzk(+Z2Xr?8}IvW#zB6C&bo>wPM9kE$Q zP?0EerFOX#=Nm;AoN^G-eu!t?deVP^e4?DNfL?L(Upp9DFA*g>;VPck^6&73HZ%Ag zp^h!UBmwW}4%UD~Iw!OQ=p%Rs@7DmtF#TxWIQ56zAH2)HjE>C$Zs-V2GmO$0+n%yD z`6wDXOLL71u(>k#Fvs9c(i|kf&QCs$UjC`c$1w%@DVBdeyrC9(&7PZJ{&BRtW+Ano ze;h+zkD7nHQfRe1%XU$<6I7>aCbXqY#ztBMEB8C$XFEpra zW;!WF1q`ECDWD@#rV~J=_Nr(%O_$7Bd4F-|#E*W#WMgsK>UOgFX)CFii^0)0WtA16 zcDR1_zd?1(UWvtMB;2_sYOj~%j*z>X&MN91ON?Md64bnD;K~BH3h1_`=@( z%hZ+H)7lmL4W_OJW83}-KeH@ZOW(9;N;9ZZ;$)|rZ$dg**U?>_od&a~vB}e`CO<(n zWL3|p&-p!b!Oh&z%1niiP&l?t^VjnKx?%D=MRN~juJ9(bgYPLr z0aC_(#;Qv#YwMGmWJ3fQ49BN(Or3a-jN2f)-=2{z?bGhcUx4R}C3*RqXmlf zZLhRb4J*H?TTGU5rtb69s#z+xOjNFcR?R`RSxu}^2qvVWQ&rBQXMF*}Z>6~p+bui8 zN>A!t1K}bG^wIw-2^4Hw^?-Cl1t10_kNH2mdiJB>bcR#YZg2y+G;zn`Qcdk{2ZKWM zMjDWa^%{b(O)c5+er1MJ^?0&?wkRF-REIO@N@N(=WWOHYo{Wi^*2tXHA>|DY|6@1@ zi97#YWPa*flhlyA8Tk9sxxLwZ)ZZ8A^XOF78|rgg>~8xY*|GeR|nBxu+!l_7lWMp=}#I1m&s`x0=hZw*44BzgH1wj+NZNi>0gw1I6!& z-?OqTs8MI2IYxZWnC=iA|PygjCoj>w-sMUG^q-Rd})H)-QGQ&!iS z#m><$z*;mxUmzHUxUH(AY2B9Q{d~++Z6OXp`Z@97&`qN-f7}y->a1WrpqoDi3#NEd zN8*@ZkpSUdrI6OXp^wR;#PB5oQ@7% z#B=FGF&fleRDMBz;l4@urqelQYMdP8%q}UXH7YthWZ|sLIm=gn#fcMV9+M zgV(h9|9iMSCpTO?qRE|T#L?lB7OJGyCIy}d1%zMvz)-RxTVD;(_>UF{H;Ar9d8|J~ zAb=<3Qn}XVwBg%*bMjXoFElek5&qN&8!f@!CZ2LXw?k{XQg&9vznIN?qa!o4K4b;Z zF`f|bVWzqzWRQev3HYK9ez^KJ@dGoccABAI!{PAqPHPIK0GKzP7{CaHHo~Q7SeT>O z;)x55EkeJFyDdlF5ql2D2|CAKJZkLcc~eevj$<(bLppoKBXYdlqT21u|9v_rgUK(but$mE@)I7_o*|rv@cWSSm1e)#e1=Mi zoEb9B41Znkr*US2jU5v_%!|SK3$UtV5&AGtkT?gDdO8ZJ5*>0T*S%Aaa@&vC{>s2# zsQr}(viWk&hrJOuxb2m2gYB*iwBw!4Y0<|C{u^VsfE!L}@8Y}n`q9oOyVTH|n=_r0 zds4hIz?)>tm{;^T623S@k{$En^y5*;U+x|o1B09)8;DXMp5l5gQ6FhXlxATpS)3}{ zKLsPm`Yk8QiaBj?7wpDbnS+)Z9snG_lzHit!C%^o7;kW&Km>&xX zPQ6JHnmUbOX01$Br^`+FvtfV(qIf_Jq6ekCh@E2MOt@jOZoNLlT;;dM+Zg{tS} z`zp>p2K(+Hu4k*0FI(I_q70Brn|||?IdHG|K^i~$eh%;~-=DO)pUi=!tzJ1qTqGTy zq4qKx(mj*u9-cg7GQJGOx&vb}Ub%$D0KRXE#rB=RVjIrW{^eiBpEPQ2EZA>3$dlJH zaRPt!=q1W*-dXRi4wG24=`mD*KeN;saz~T_IjI-dS-k3DBL^E?C*QEZvzuOyZU1Ls z&D)+AJ26A{)#JmP&EQU5f7lF=+|)#h6&8q~D-&_8wV0w=oGLBCuGV&`={AEJt3WI0 zJE{5}D(*|J?0w?utS16)2_b=-6Wu%w0e4CX0jEF-c-G6^o5B#ppyLh1y~0H^?bj_U z*EDL1I3HJiG3Gz6n#%ozCvL0eeXl<_4i$;PJ+6v|_){?Mf}q`W?&TL_73B#onFJpN z<#8ujcrxE@YvcPR6ZC@dR4*Ti93R{EKhLJhyeCekxS5sXlUHh8ry>^dd2Q_7ZAr9i zZLE3<|E=*kvFgQDTw15c-n~tCz7%WPqs!fkxZM8_Tpl~ltu}Y-XS(%s-Fij07}06( zh)ug79-DS?RczX&(__=Vl#EULlls`SuQbM{ZD^uok4n~Btz4;=EA?`IdHA#5XQ|Eh=Q0{Jta~cWt@nOOgHa+1$M>Zmi%~vUL6y zbze3&obLU_gxIzNAL6~bG$wkC*t_TGKbdNOwk=jYm;Vde^rhXNSoNh{3fvj1UeTk# zfmrn?^!pe?HGir?2MJ{o7JT+xf(;gYS;2)CJRYkSKH|l|8s&X-0JJb`Gcq3ZF!%|+ zPxd<+S5X4rvyCmuZ0@RyE$)fEyJNG~EXS&M6MZsPo!QqNTXKJF$uhft7qyZ;9IIZo zZ&#$;K&-lMb2oRMSBaiTiAPENg|d@nz?axX8ZQ~PFy!+qJ=(%ZB)^({K9Vo2Hy*2g zAhzV`*pk(om1l3Pdh5P6-ZobK6w#++)vNba`Et5X{SWYCZ!kSl?txhKm79mS^B*da zjFbplsxP)Q604rEnas2nw$kX!jErif$+x0(HBAGz8W~3N`!;s&Gn%e`D7J)m&1{a7 zeP68l1%4Qct^2z5UT!pWi+5SKIT@>dh%hg-bD!}*vFJmw>gLT=++*>Q}>H z7gWB@V5a%rX0W#z?AM{eo{hiFU~e-R$SpvnZ)-4AxB=2%jRxEL?zb82Z3cUr!SFH2 zkowizU}v#S`fVGGu6-LKz6}w79Sn9C3n$)Yu(uiPZHV}5(qLCHA@VkZz0F{6GuW?# z!9Ew;dgP$iB6Z;2htaBMF>ySQ`g`WVILqg+@#m-b)^du`l*e@-^u^{ zIG2VhE|*Q$)b&t36Sqx0M-@J7;e$tGOMX@tThbp}@^gNE7F(pq9KVvSl^Y6We3eUKvnzR+uNn0_K`pXksG6}V}Frfz70isr(v{vr4 z7N527v%bZ9U5h_=E#B!`9H#mNRh@BVLTyqZ4P+8(b+xKJV|7C9u1=`o)rpzs(sBcr zOhcUO!iFlY%NnfZr>wOD*79=}e%ZIoM4aCB71#28uH_fcrDdu*C(8CNb;%gYw3V;}~-9ojzZsE*ydw(+BzBidZes^s99}G!o za29i)lN5W<(!qj@I?d>FY3Skd9{w*)a{0EXm*4OA@cSjE`uV?;{{#GUSe4djOo(-y z#mr)4J;9vVlKr)!i+9`9JjE|yWGwAYMOdn_WIug+-gI)^N6NNwh%CZ`gy(i~caX>) zBA3?t$lZ!GDxz{t+`gZbZ)pxSDALqz(x@$D`i*T;XLc(;#J`i5PE$@ier+aeY0 zqQDVu^mF6;1FnGL_bNW*t^?>n${_fv8wM!wC=qqQx9VL1#nlJjYV>hcAa5S&t|uZD3{k-|+;BbN3MlS+ z!pBv?E?0r;iAV(_RB)66t|wdp#a&PMxGETN6}X;=RKUWOQ0|e;ij&wT9akH!Uon-{ zKJ?DdH81#57p)n+@P4NtlnatPg`*OVWDZudZ2Z1fT^82|%|V{=KR?c*7=)N)n1t1m zehLrq-y2FQ0&|ffapf+W^- zz?FR1m%J|`EeIkl;8Uc9N-k8%g(`_4U^S5|`D0)5kqEaFgxe_zx5L#{aCMdIPxzTm zM)QAjEPn2$Ti+r-Urlu<=Vw-T#Eau(u_`}=_gQSZVhYXO!h1ZTka0N4#@I?Ia<;`9 z{k{7w)})w1bGxYEF@=oPNj45wLJ5moLbqd4<#^B%#ONxb$lM(yKViw@d6JFQl~BU# zmN4WBD#yc?AdXiNMdtR9{9{WN^OJ1cu7nbHw}gP-DPn!IZMrX_yA8LH?7N2^rzT^2 z-74XGO9&XBBGyUY68Ec!)wGLb-%qY4BcwiwVA;e1g?$exO^rFEMcga;QPrZSWRLz-%r#8zuIy(1tkvt7vi9ZhsKl#s^zT`+6Amm>t}O= zEpyxWFScGx@&Mi%sz(a&OgvWzRA74UJQ=wY019Jk?mZRUi!iYQj<&Y?$-|OX{Xy!lVZ+NnGoaRO40^f5L9G(TTcoL`nThGR_T??zN;LU)*v% zY)Rr?mrFHvtN4%YMvt%YE+zFU$v9YfEy+60bat3zeP>+kk|@(~ql)|PV@!18Q6*XT z87GHH)`O zN1xY{d_P8$d_RUss&SW!`+lTG*se-uj)LOv6{qHJb$F4#EmlR}?WbN(qKYYfZU<@B z!^YqGOoW!Pdj5W4ECyHN7|i{`*nDlt3r}Ear(fsiC;wUMI0`?u{gV4xy#2~PUJ`cR zt6jmP*DG(=ty8R5{eW5!~l5#;6fkV30t+F6jGd+aR?Ut3=6}_cWfmNb{o7JsF zd=E}va&bMCnvs$ua2J^zau06(gp^AgxrK3D-7rM$R;no|rCU~NBzjAw0<%U1|Dwk= z+~W+3!_@wFT_jQ1;C-75-$T|FaVm;tc$!4Be8^0C^$Ky9Wsr;wYUqyCFnv@8t3h(t z*YLl_5vCi)ao!49U*~DQJK)NjtPKbx8Hr{_QP*?I&=_Qpd?wLq7>d-; zG%ADDAerrJ_+FAQmWCcGx>EjeSsD@j3jv*gFL?5|MmQ$l94nmE-azCu(8uzh#F_?# z=kcDznjTk3z7u>2xK6O^1w#h-#}ZjA%qQQ;8Q38WlL&Z=gwSPGq+M1`XvK6wD`uKZ z<6^E3`A!JScM@y5Pi^2ii8Vc;ko+dJhTBA51m7AKjI}1eNu~TI3lnNDv}6b`Gr!5Q zgxbV!LLU4kB|d}?*`CNc*!>fMJP7>>e<0!S1tKF{Wd1ki`4jyK3}|HhAcL{^y~w&< z%ApbEflqWObaU6-2KC%EhHWGe^886X3fPcKV8JCfMft7U(Wf!)K#;++Q`Dnimi!PI zj;e+zk9Z0XS>G~v7KpkOtcGO7kQS9ovp&n-KD;=^{x6~LPda-#O5c%=f{JA|OQ3HY z48||EcsJe!NGY_MJ?%P*rLzY3m(@I)MkDlCq(Mh{zLc!yv1l!@U?tB(`*lqE`A^ud zUpSF|^a5UI6wL~S%tpP_(%>csJ}fp}G0V|K;Wx5kEtBlayA^V7Dq^E;*&fnLY}ts7 z233ieRNkz@A1D-ft(33CqILOpkz8WYMl3Z~-%+bi7TvuH1x_sGE3s=`z9Eu}b}f_w z@fEipeb1<_jf&YB8Ih-+-YDCvHXNQ)DB7`97T}1D_jMKN4Wb#qhLWQM67%F`L}lbu zyc3X6U|p5ae`sI*UPS&FZ2YC{EA6NE_M`JpdHN~B))1O{3oD=>%VG3mIkxb6MeB-8 zgCuy{N-@i{l{9Z(`5fN53UhRmqi9=^Z1khTfiL74MH+4-U(veq`HHrc5-gu6wrE+A zZ1kgBfk))1<=aWVqHX2#6)h_zSU%BX(XKLm`PS%1wK)1w$S}X}SSl0dH?ehJ*NYGk z|91ztzl4NB+<#w$uqqQ#JOG}*Fd7HYGt{!rb;w5vpl1)}^K%g*E?F^}ij$OvRtSH%U{f9mdo*V)?_V)d-S=&1e}OJ$!ai1rrndI?h3 zZs4MRfi&~m5aoQtzAc8h{9#;=ILMd=mZF3p#*^!+|qB$VC$sG7=~_pu(X}B;d^g z0jE*^g%CfD+5dEsx4BQ+|Bs!t|3gJSTDj}pBB;soNujuWVn~ObdV+j5a3ni_^(`dt zQ6ZZLDEhFA2+F119_AB+xwIkDET3a5hf~7g`MeEJiG5NsJ|3@(elbQ!2*pO|$D{g} zx6(+B304e{1peJ<|CKJK_4hay;zm>Z)z1y_jz{o)-DQ*GleWI4VQliga#3$0%s_By9(cb10%ZUFWk5 zDqkn(p73jjB+62>LlTEvz#S+-iaSV%z)p9fV(YY<6ICkJI_*|Fx`DuL_OVL>cW~l3 z;))}rcG)k->hP-ri@K>+4|Y4hb{5eMEQRG1kWB6c&Un#xQaIfw-TT`3Oz!UXrza3Q zpo2#A9@*UCRPRqF>KGA4=jA8caft$n41dv-7_UoU0@|4n+3 zHX7ukfM4O(e-Py1bRd~1=SUCN%H2es^;!~^}1 z|A*-Be+ZA*A{$2&k#mc3>U@_>?oc}SEYI{#9awUUl6C3~kKL~C#xV57c$u>7AWLBy z_n}1HQkxu{mE~}y{N#5k#p=#i+R1@U9I|3xkT_fYvgz4a#~}H$HTT7~{hasE$?lEd zNu3{?>8wb1u0*!7ItgVhM_}kUhTRD>8r;6*fb?vXBz_9{=6 z{a64z^I1MK6YKa4FPY`z$ocy~FzTE(YD(vL40RX0rek&Tl@?gZCm8Izzz>i&lY1?j zd$e#q5VWX2b(YNH$+|YuBfZRQ_f#pi@+Do9N9d(0daH_lx$0ow(fF4S^&PEPmQXi- z^)QK-j}V9L310XT7d|v{v;ql0Fs;MN=uHyp5~^VKh!W}#^{pkx+0?M=Ae|C#rC!b` zsV2vlhX^*?DLre{(7MD7vaO{d+L%d(2AE?rl( zag%4ayEoh2=?bs9(Nb=)lo<*y-=XV*ZcD#aW!HA-x@L>jvsLM9cImqIHcCMsT-A?9 zsb9Uv`zq(`+pV4<%TvvDSt6s97K-Z-YC}qK*u1g=cvLjYX6j3qnh_17brP}+-Gd2IwoJhAn)0VC& z#J2wvuyp-&rKigVQ)Q2&${yvwWAd~-u5%?N2PBGj@mrXqGapTp@Fdgt|A6RD^ry}j zF)gkPDeq|f@`Geqpo^$N^uU-6aY-H|E2FD%)pM=dQrkZperWqVza6wRPN~bSx0iM) zyue0ko{i4zo#g6PE`D$JzdWavzEyFR2u4Z$!Dw)ucL(`CteyuH zSE-;!DLdrz9Q413{O@7^JK}#|^1nxXUHXdNxWe`DayZ`;%l`xXoX(${bb>Dvn==^7 z7n1o**_^?`cR4sdut$$dX53CifezHi(qASCaXLQMp$|Uj%;WqwG+~bV=_V`6ya6G!EyJ{tzSi-S=klX*JMFv`I;dzm$Ymw8QPBu( zR4kTIsuz>P**Y~5>KdP|+28!T5@p$%{*60g`4`l0q^HWBPnEsE-Ik})`SPVwv+1(O z=n!eFvgS`@^XJCXHT|*ee@KVKw$8I|8K3Uwx9#)DXpVW@Q+$3f>3H9n91@{%&h+(qouj=ZtT$`O)ZVxaD}($x7D`FmZ`a~`3y!Ado}+Qbtx@XwwvUZf}JGSLzDg_ISAIB zBsb&&0s5&9&`))MeyRiXQyrk6>Hz&zd-QYtUZJorTzc6hwaaQRslBxJvOSLe9F_9a z;`+_JouT5zFW8dlG%B%IUw~8w!>-vSbt`}A6 zdj1q$&z+j?Kevka;Ener3BzG+pVyshO_qJ_C2{1rM|3^^*zlt0_`NnEwn<+Z@=qGd zqqop_%k|Redgj=s&vNjd6}4xna?e7z|6I77XW|Jivgi21u|iCFb;4r^^UC=gPUQ`S zC!EP&SHh9MBYj2@13eOu%IW5&WUc8acz031V;Xx{bcM5m% z>%Ugy@VsI9RPMos6j=D;i#YHs3h5#J(*jIyhn)BDj)5%u4dQtx)l#`z-N}Fe(QWU= zhndOsaHd;2_d_7P#xmXey6}AMC_oyS$%Tk|B}znvJcVXWh?NX&Fj z%XT&v@jMt)XzxPM$ZoVn4|smH@cOC|kLQ=__VQy~TBSddAbYb@R|4pPS=r8&yxbK4 z`m1|nx5iB#93l#!C!;avVWI$fvMc%p3S2#?&=n>_zGisnT%I7n^i`+A^e004e)v=d zO#X+)E7(wm=ha=n_|W``Kzfc=75vZU9>n6joBs#0xySi=qHsAH20<5Zm1vANsk4wo z4%9Cego`&8K|LxJRT)o9RdNm>!CLj$Rp?n@xJ2(-y^5uB6gJE>4G`z=i)a#Cos@lyM_)n?4Fh0420TyBy9E}44WGM*h#upE9CB1{v z3loNl*Co2h#GCVAyzq@gcx{($hh@tsvMkZ2pG?BQdtJitWOJfhrPd{GcKLTIwk&ar zey&X1s-M+~UAlK=;x=nV-P3HH=w5*{gmrse;&xY2kL9YSUDs7S(OxTZw!1%M_h%~7 zoH%HA4F9i7&<(sr(%sPjG$-m*^|FM9Q}0iix`bif4ytv`!(-O=*Co1nQ}H0hk8qDia2YW->Jm2xH%~??s@szUBc>uf zDx$#NAmELSx`bI9Dsi%LRI#C;*ufy+4UW2mw>awT=u~UN6ux`-V}*AiV`BMMf!0%4 z7-wQ(Xr?Yu#1dOFGD?k$4@krd2mijI=wHsb_y6j{0-R?Yt&1p zwkLi&v?p$&KrG+I6%TuI_^Zffe(#_cEd7#Z$n*CYBz8QcxW$FU@xq% za5lhzOoM91V#BkL=p_D=Vz@C)h?c?MxUCSbZ;~=Kj~==|)Aumj`4OyJe`|>-)&0Exem3z z4r*UKHfk5AT|J`fwUQ$h=Sw?QTy(5ZZO3aP&!TpR@|}N3*NYD8`UNXliW`Qvp9uKN zZzv?hcv{ICvA{#T|BwmK4#wK#r}?BH;7Z(aemx5=F$kGe4zV0tlU|4WAHWpp63v%r6l?ma#} z-TO39y}XI@djC%?X8_|*Mc#0xIp>+*Z0e0l_Tf%-~IQ{ak%g82&S`F6VpMaEbr@$-w`vj~(U)U0;1jU1VdJpG

Z@(e0nhL}T1X-B!~W*=77N=nP8HM<M@f> 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 `Dt0;NXAvg${%bPe$eI#0nJ;sSBP06j)r zR)tm^!kG`U@aEbd==>-F&pTY!8T7n@S?59#h-X;Y`FR^`7l|ytz*#c(Z9+&Fu;ngD zdO8<#I`0HcA=vIPVCw?cqU2N?zZDFA4DA}PL6zHM#ln}SfGU#J2uOd7DAKTmbrGyL zs$HSAHdC~5~7!Aw7*~P?JyYq>6@UBZ+Xl(p&=<#ect&bj4QT=e}@f)lA z=&{NwrsatfMUQ{7s*fJ`(c|9HaRJ6e4q_|g% zfWD@8vA3jTpTH7I=46zeBw?3}JQa*Q?Tb7$FmxgRkt) zS)M%FJo$83KcvWdYJJnp5HjE)_1Ai^q)Mz^@5~=I8V5TeBg7WSfK9dk?(@9Nz2=v_ z=CK;M;T`OZ7Zx#LB3l~t9E7!QK|ibhFUs)!J?tWs1|Rcusx>RoHgQT0c!bqt-hGBO6@P8}eZ{^oOK(Di!2}=#Z1l zw#+6Kh;LcPTQd1&5NetT5TpFjVa+sg%BRaZ-jN4Q#{dz5q7r}f(q`0Yt(wVH3Hq%7 zjK_Riz~f1plGor0umSkkH_#*j^)(&shnx)>vXCH=DNKA3Bx7iyK2~5#!DtN#c;X`C zVrSBCFwaAP%k4Y*^F0t=Zf_cC_eZuQJ_R9AtvB~ALlHSv{llmkV0F8!d!7SPi>nP| zg`B<_NAchqWG85%{3o}39ehxRd(CBdcx{JR*!PC6JxE~FP&O@w*_qse!-Q5G#z0x} zUJVJ;d)rZd?UyocKFIU(LpHUDjlr*s348Rv zV32%NsscduV(2GG#1MUSDF({t*~0^7E`!k3*0PFk=a7x*aN^_m*Oe zUzwzI==9zwL)eNTEW;3%;qg_d*E^b{ac#^D9+TOb!9x-GNPqxw(~CoyOv}7>_I8ep z*bEuN3dxpWW`j>dQX0`chkdMnoq6RZTrkI>$kl)iB^c+AgnKhUw(5Y|BEMl8_ z;uo>aAHB7VNI_~1OT$3uY91lh+}4+i*!W=}vKerIU1^bVcK}9X9_GV4rw^DvnpX>S9Em#^Wsw{s2z7H;802tWW>IPwA+1PGv& z440Hr%;Pj7Vg7^?9>Q7V8|+|W;DGt(C>N2?>VN^>GTWN;5F}5L6WZ(5QF_d z6y7s)1uT|pHx}|aa6`}6bTm$IrVAdLq&-$W{ayS@uE_1 zy~Z~^NkFx&GW3de`a$o44Y9hg$r^--5IVMJfb!>1SHpzpd63cPe$r|RK&;f@VJ_6* zVJ^^iG(=B<%*F%`NB)=szh?`T;M#}$Agn>p27Azkv*qJu(57P0)PPOwke+Zb*bTKy zy%~Y9#ZLy}5E`F{rvrr>0bJIH(zua7lEhe;-iLQ2JeWAG1!j;pU@j0(<085nwR=pY z3=uc9q(R6QCuGow8#wqxKZzmFEZRg`QSInon6*L`zRdTFAcAk zUn3lFPh$!PbOuv6AopIw^K|h*KF%s0e3_X^ARh27GIstt;sFac;z18$L81A&2eAOa z<%k83v%!k7ehE{279{{m0%ZNTzUB}|)7L>7Le9@C(!KmloE|)!?4Iu^Izz6aShx@o z7auRk33CH%v1NG;7w3nZZDG*Dsxx!xvxUA3mkw(#O^)nl(HCpBZLRtwpT{vmAl&ScsYt)26 z3ad=#l2@QZ8Mx#>f_W-<*1Ylo#Vf%h1D*#JU@Be-DnzIPI!=&*1fw(w&V^BG7$n2= zdzuu_)clf$KJrTedBE%%UPmCi3)9s0Lv)<1vjX$FuFOrc%Lp1-SR+Itdm3;yT3%I5 zZ?Z7JG}c%99kM;2M+?xx`-nOH!sSFJHjHz15*eKWUUjpOcSYJ!ZN!Xdu*8{2o0AV> zfLIimlt%{0DGp|H*dilIgX(B0>HhemI80<7c@7M|qozdtiNzS^HjT_Jb>JYW?-|gD zLdEMsNZ*Cw*BfJe1Wx42*UeA9W~GTmR*L~ofFO|-d}bT8~RFXNpYJRS%V z=}Ti=j2ChGYkC-dE^&^{z&;ZEYi%BeS~O;v_w4+uMzFhbG^b3qJ3#t$0I4X#@11|m z)b&FNmip89SD+uO%SDV#cK(G803806LDfB&fq@CXQ~Ya>;$OS|&iL1_FzuRu%>fuw z)AL>f=}mDlBD)U*M*-Nyz&IHh8Q4L5eYL1r{)0j&r>ka=xl6x>P=o=0L;~8-JgwtjWJ}IbL9tUW#V9% z4yNK~D>1~~u&{n`wxFsWAJ@t74`ZOd#WZbe~k_05)FGnk95Rqc3N>2Qq%n+yA) zjYUd*E0_GMacnu#KQBI6$(zWUinkWw#)xX{1F_IMM0EHtjL2=(3EXVOJ|i{F>zgKr zUXDKzdNqCtc5=9cHk|wmN5^-=NVmIs51!Tl;irZ6#M?sq;?4N5xterh7L3h%p$+V< z-WlIrvmfS+Kg4&3c4J$JJ@}_|T{GH?jM44*-x}Xr^Srh@ZNrmF?&Txw*lM^K^W&(L zRs-|y+O}zq4>ikrnIK5BjGoM-Tw1F(=)nPZ*81Tv;nLw8Sd^80dWfAlwzGOK0*T+j z|8C^(cmo}H2_1MrI&h?VKkmJXX2QnaSIr{g zWQ-&3m?pICh<7I--|~$sV^$vJJ5m!H7W!n zxKB`^Xr8f{OUX2$MI;N$@%9%t2*rw(+QLtU4JIGQpWWHe>U=Q(UdFAV9@l;bd@ z&!)bvP3X&1k1qgnUBj6yr0R?zxbYC~Tt#jyg2(#uh1J}y#~bP}O7wz*@%hzp-m9Rh zV0Xr*IE4$%Oo zp4wcIt<510=FKwRSIcUfTh3|#t+kdN5zP;or0mULQ)_v^nQXp z`&u5<97u9J7sht8=z6-IcSI(j4B(b%J0Z~?5s9`7Z!!|?RMtl*M}6NBpjXvv!=|+= zfoC*sDoik*J6m6gcOqM!!Us1lXrR)lV1P>FLXQlYlm3C@f>u+lhEfR3j=N9*O8HpL zxNAU~Dze;Hj`niM&rX|RGvbr;%nXM|a56v5!*rtcvly5pez)LveLPw79Q=|^P!(c; z3+;V`im<4tLhmLDu^YRI&co42*~MDQzH2?D{1h!g+wT<+nK=*tC~*of$|wu?&7d#4 z0%(-S-O-m@Q41hIZGoGjFF&X>YnQ&9sv{r4mp$mnkKz@#jx6#|M*TQ~H?@9@)<`@R zv|otqqW2CKbr=Cw5J}oN*ea%KF4W=X>bKUH&#Xp3Q~9)N?BA#dzZrwSgCY_nCkd|F zg1K3kkNEH-HJfpZzR|YoC*z&+0(QUEN^R|3ZiV)0w?fO#D20|Y1B%s#pUevFH*{~H z(3S~NQ}I@4p3-M$Ru94LY1P=~6jE3W!W#BtB(O+phCp{!Th%IS^l#JkRMzhaBce*{ z%QLHUFj7!hr&aqP?@J+04AvjAE2U6GQ+KgtdjVOhf{ip;|7$Ylf-Rn!y=f)(?ygtv z;V3{EZI{ugmtUidijD_mlt7lEj4FbKnO>=s*lv|kDVfSB)y580RF+t-l3Y%SY6MkK ze(I>8Y=%)md!u?v#mAv~E&%m~JfoG*1E>u>yb+!q@0}?o?|EW|rLsvL*F@g?E}?o3 z?UxWYsDy%m>;nmgv2tPc=nh=b+Odti!9cZWk_Q0PV`3tuYt<2!iJCS5kf@7L5}{8? zu}VR_4XPuxQwYIA3vVVZd>3_;cc3B zh^nd1iTWm0YNn@a?8olqWvWp0G*&p?R4B~PRMt(1?7s3Z{gfv@WoKp>Yf{DSTv?B%+Jvy292tX8kJ0q(xRX_ zHDRdQc{C7_4hb?@<@2k3E$hn{R+q&xjh1Lc9IdiKQyJwjGg_kdK-mEtP-*bD;0#b8 z)(EBb00uDsC|lGXfSrZ`1!$B;P<9!neTEO89Wa$txGNDo1-c3Pa)KH=bKz8^|CV%@3(trivG3x+dB4o`Yd_lHS(=dl{MbS!d z-bc8~FxMDdr92$K0Ot4S(D0UM3o_fh5)A=*0ccJ;4x$qfm^rOVB>)gBln3Yv5T~QO z)KknUU_E05s-z+ttfV4Gq^JAKcuQp1#NAKoi9ub8AH47VI1jghFlcv)9xmRsNfBB? zpF#&dDMWMiu%YqWFd{k92{s-0kmtrWk=45+P?%!21_JW;Fk`GzNKv)O-;k%sGFYi$ zFj8Y@H3{>aJRFp*P9g7XOjEwd+?;h3NxL?K30Q+IbKj2(%G{}tApr$W$22U6h)sZy zIT8sQ0HNjxU_k80vsC(zKJ*3_j3Z}-apZKMU3xV7g|9IEb`QG5@?l#HyZapd)FC(@ zBOo%c3~Kn}rWkyagIDPa5*ef$iPv}6dI}C%izI7^0k#D6!Bi~BTKC<$y(*w7BD;+TMt#sf- z$hWS#L=@5Tt*T55BC4`cK(qHM-vZEfhq}nOs*(y93{;!|`PS8=IU3+7->S;yxhwm7 zlW+CNbdhO7De`TImY??}-@5A&pfd8UuE+)}spu~)-#YM;BHs$Ui1FE`gfsw)DE2<& z+t7YZSO3EDt$U90h$fsP=sKBU;e^V!_7LG^WVvUp@Ry?et$+7ozA(s{wV`pM()oN%a{^-Zw0dP^WE=nalW# zrBqnE$aHslA(r(>GeY%$$5b##meCeOk~@ENe1Dub2e=C{zLWa?%$1=1v7TiE7llUN zL6(gTzTr<}@m(w!9gl1;+i|BkfOVDyyod5ywec7`0Ao=k9(a9`+#=c=u}!rs_TqMt z)YX|UCYL8(tY4LrJS+&qikUsw(48j9FD9aByY0VFDP)=@jSQ@52y4%pH_umkI9x&b zS{63Q?(BKIgpqk>=vtiK8seg``61avD1=x%B$)Z0&ZhTWzX#gso9~A2lWc2mz7zhY z-?KB>=<9!B5i)V)`j^Gaf}TIY@|7DXeb;IzqVZTy6uX16}vCQy^- zha_MY3wxP-W@FH^6Te|B=4(%)2F@fF1IOW|>!-Wr34b+!g~}uJYF%at+{wmSkA&G& z1AHn$qd%HE9)Pit=|<4zRwvy^-EgpUsQawAOO8O~F@%1ZKMu`pt=$0&_NcUw_+WHO zhgHvQCW6uHU`s{VYW**G1?XA!?mJff&*V|in|K%}0nAJx@-cqS3@;k1+KDw-{V>qa zu+OFD>4a!yzkVF)#5bXka$04c1S!miSnA94hZ_^;2?VIY2zs_9{G!8_S7pQRIpUU) zb(F0bHVlF?OGunn8Ik;uy6p;OtRPKT%RvS$h{+$uT2IRSEK!JiBhX&aA-(TTB-X4NM1^!Qr4wDnmklaEC|3@dz0gm*9|HZJb6ar9a zSjnG3qfG^Nao=v$Kaa)}z)#}=0qIFZOEMfrVjW@1ZL4{OtdLKqsX&>w(966!U0Zq& z$*Wsx{$yT5pzmG;)@%tK=4)R48dhKul&hFr9R5&@J4%f-$_9)8XGsSNbUPkMAOppW#3 zpyj4V1Rl^MuBFlRNWj3*qup+L#3ycg6ytR|J>t!t=}}@OUL*Y{&34hF^E5rW21$=v z!!u-HZ7CepwTfr?uM3)i+2JfV9a#UGETe6c`Edb5nBQ+>|si9 z=@iL>`h@uKO2l_urhUg1pnY>v3}`?J#LsH_2NSr9{_)DDfAWa*4<{+~k6jV^$G&x; ze|+lDzjNL6kB`8Rlo)E$zds7ZDc2zB-%ik5`VX_wzvGo}zKZ$iLfbyF@=Z~8`6iXV zU7VbEoHEVjM1yphhO)~qwe0ekkzIajWS1XNc6mtTuPpM*SkRPiDlvyq`^cT3E(}URZd2dm5)8Qy z9;}q$63Q%Va3heaw=h9O7rb681w1aYj$3Boed;GY=`F11IAoUY^%f(u%TFxGTGN0Ph6XG*G~h1MfTh{wg#wNLoJzO6z?p=+APFLr{vuOg~3={(iEi54=hKJ{+I)@%Ie&ixa}%X`fi=m83O#lVfF{0B@IU|Bo2_{;|RD{~&%p zm;t}VKG6ez{~advL*?(m%=n#ZpOAn~wTxF;CAMm8eu~)qWEX6vvBeXc z?j?sGq2z0DuO96Z(AB!wC5(LV(c$lk!uRoaWXu!Eu&Yht!{P4>g}=`yf1gkOKA-%3 zq40OHJP3ami-GX>5cvCi^7qi+C4XNi{Cz(8`$FOGYCOQ-Lw_0menj*4&Mf?0+?0L% zUHD0gZE}go`Qsh`1m*Z_z6mAY51AK;Y=9UK&qOPOu1LC}Dj;c#Ufj)BU}MDC z4E_h^zJlBi|3ij7XHpyx+cPkFRtMM`QVb;t5;!j*6V?pKQND8*aF+uBir51AB^{DGUgbG%YFS_)1oz~L>-N8-HJ8|%I#`O%~U2viRdno{@Lww zAB2D66d)8_j9qC!J0{Mp=kq!<4UjkABMsI>yU5g+Z1&;-b;Ctwjz6S+7s@@_VI^dJE>yFcPEhQ{TO zu<6k*H$95sC80+OIvje$2R+lHa}(4LQV5dU{m>r1k&~lig-?+C;hTn#tq?+ngpg@Q z$+c(_91wJmXky0Bi4lTZoY=%H#=Ge@_YA~rJcyZcK)8t6aeE+s-761-*po@`6#3f* z2ZN@D!+-`Es-kX0S18oz^o)&wNnYO(j`KEi?mRY{BvdK5eMFyW?Zs@IiGnVL+ z$uIGQkz;;t%P~JyK0wGZ|0QzFgQmU=^rJWSi=PlIocIcxew4nPKvJz88r zXpSw%e%c!V5HwU^_)L7~~cW*jk|xeB2FE|D zKt?CcO_TUj3bo)XiL-Fa76AJAe>8)ALinC<#KZC% z-&FO+#AxNeA-W7Z^sbKmWFJqmjF_xjG{3t~LazZ5m$hr+!$t7;v z$2cf1hR+8?GH&}`lt_Lm8G%mb8H!ryJsT`-$#?zH%Rdfx$lHrY;vN=m(0w44hAMDA zGc+wv%oZwaIywPXT-q=q$C8modQq(Uud#Os@~sc@M1rdsuxZL+nJ9rPL>OWfdOrCx zBkua6&d8u2+G5r|@X>W>at zVtVP*d(omdG3<@I$yp$R)ht)o`XG`GaEk!=#n1^fIX|}uey==kNsBB7UhIGuTe90~ z_yy`mQ=2eM$>&6iDZ>$|xFGq=>9T}mB9@SRoSI5>>LDLg7FfDPZ{Y>v?oX3P)4hqo zIB`Q9o$?C66D#mY=~tnR9G|O@{_U7T1O3K3FnG>xRG-JOH4;HI?Ug^^6|{PEUV`B| ze6>tq+n`Y)UM^Cunry^Ju72p{DpFZ6uz) z$bOS5s!Eg4yIv9NmD+c-jQf~lg2rJUhKGyFa2oUlR(!ca(NlL?;;vbUap%FJHJs7~ z!`0e1oG9wYZP7`5^8%4!MM8Ve2D;1s$Jn1+?TS7yu;QkYz=)ebOZLC2Gu_RYD*GJ>KcrW_84+o=q9(` zbaGoP_7@;-uwkFIYQ5yLg6EQ3qG@tFL{4CR%f)7uM*^_AF<*`%Dnn~V1S|XR`ecpn%~?^R^q); z^@yEiw&dOD-M4C9l|)Ut&vTGfcqY=IKPLU!qkG8@&^x5qVE%LDLVpaEva8a&2?)Po z4ms6N+PyUcxov=9Ac>REDws`PLx!3^D^_v}CyuP-Uc#NQl46{(nOMZ~-yz8$y#Xs( zBn7XOjgj4^x&ayxKfNZ&9+25Qry9K*!|_-Rnu#o>d1&Jvr_qmL#J1GzV}lblXiFnm zP%$VV_|Zo2qcHZ_BR~4WtfCUD;d_GN*uj1Ub}5VI!n`DV+k+X6!PH|krZ>I1^ihG3#FMQ!mXYW9J=qDslfasvXa0aDESwB z@8Z5?<4XFyF|Gj2jy7m}Ai2Ahu)8w|57r}~DQTOIlVD@OVrsOo>%yM?l%g(6&Q$yB z-6;GG)k|Jy49xEdFobl&^QK@KRa|&pNxaj08r^$bP{i*3&T8nu+@kjf@D-uRT{EeY{+i07CNIhwO}<;c}@9s<t7nMK8Eb#`0d zV$>H$szE}j0udBvCOL7Y5)rTh4Ue%R5kSoKa!=H}!WvzmEtC=*Al?jm0tC|{#{GK8 z&^A6W=!r7W^w2I8gqcEG0(_1LT#yg}XHbgZC>6T07z=D2x#L1o3P&YMusP*!QAyVt*VQzP?m%li9yW-KkUL*fS0!Ajkt*j@5nzd*E7+m-# zI^ulsLnh+ueRTThmCJ^Z&oWyBOf^-aY5F6-gb*ON`a zCykBW=nKnUDf6W&3qeO&7?(v^=qmq@0GAhT{1=!15t5PF+yY$ymX#FwzlhQTWG-N{ zlK+Y5BL71paLNBmZb^Is7~2P4)sODM{a23=~d{fGRP$8>y39BS^5!99c5{;&xkBd>j(tl>Tfby;pe{hQ2g;_|oJZ93H*Z z5F|5Rfh!}uXI2UK3JyQaUxr{TeUcYSwLpoKXHjVKM;S%d2I;Ss z{cVx;8I;hy$O=QH%P@0ZvJACftK?Ovon7TqCe=KRjox83yo);V`twE>-75Byqs6oa zWJr_l>ndW(dUwi~yCEz%^5u438Tpb?Xu&At%O`On@@4hSwBfx#NEuDdgAggwAHaub zk(eR2n|d@44b-4KPuXt-r5q$8O7V-Iv23G%qkJvvNvRG3IN$M`uj3mTE%rarsl+rc zX|SgZXS=l&_9rw+qY;HIG%C5D@OfOq*6mdPG74K4qIM%}eF1M#*g62A>v-rhj5mfn z9~}{MASFp`+aWtNG*S$EmIynPT6T$Y*mvEp~)cNA~H?+Yi) zN&^`zGnE#jc(F0i?3E6{N^S@=D0LxMV5gnJ+?0w2accEEj>(IU ztl9#zZ5!;JTjIy65bU02AYYgd+!EtT1qrl|2J$ix=)+e1GSot1{5_i(U+S*PU5%Ue zj|Cln{CwPEAqe=99-t5m`+8Mw@)4u&bW3kzS?Mho-Djk?J{jis zNN-bVZCxFJ=$sJ)_o>-9R@|1ng!Wf^J*C(mUa#7WpGBBl^;DcF{e6rE z5e&jp8f2R8sEQ@(@rJqPsDsL^FCSU8iT42fiK-m{{AbYEjfsAE)zDKLJqU7eYH0X_ z-u`;k(|CJBq8+4^g(y5KH`ejX6-~u$4nQ(-+ywJ~(2C3ibGD0M-ifzJFsGswlHVkg z|4?m}plscA3LPR*V2T9plAvtf0eBSkE`2MD@_5@tL4C-gKxYt>CUg*4QXPz+0-E@v zwuAAgyt#!gL7v)MahNS6;Ka0{?`M)4NjB%y$rs zj>BSE6CE-o@haM3i3`RmRv5h{Jb)<|8(Q0Sz@0 z8)65fC{MhRvV{OgLnPK%UJGzfE}z|qoA6js z6ahG28b28@h&soS*!>(!V8K z0@T!q!cI5{cO#N;kms$27SxS5AuzA=CZBbS!x`d1w3ISiAs_!E~X!ixJSWCBh3EJ-PNhu>OZYMDnwW?YSY$m>huh9I&g=n&ifOcd5 z{R_p5oFalLje^D4Bc=GtKA|@CuA^txT z9ijpcQo=*P$t46~0<^nna4@Eahae1r@_>q&aN!6A?|-~dHv1*2hfUn!y~{^qhIwg#!lkkPnhTb4@o^FlDwL5a`e z3h^)+1l;il@okyoLj+lb_I;NwsR^OO62-s(k&)m|tfIRB5ho~% zff_;;H9h2)2th%q5|rhN5J|1&B}8m!`B3$TIR1)e@CNTOtEyjFLPTsTtZQW$Sk@XB zxMD;U+-#9hDhVS>c$AO;#Ivz(Hy$^K-s}qW7%F}w{K5zsbY+leg7~!6yoLz6t&E}r zJ*{~${ul%Dn7(Qzkd;9qn_-4SxQ8Yg2q$Bt>S9=p9J%8n<~GqWWyov~nd1qZd5_FjGa2aX_;<(r6GUOxk`dmIS>vNY<QHIrg zpT}3W#?XzvaDw7RxMxC7@ggqye-y|P7SkB7W4 z368ym_G`%h;2O%7$IxS#ugQYa&F5KU_b#^cUt*54+0Iw_jR9snE9#Z)oSLqt99Hzd z&?_TP&rdO*$2e2;Qc6&U$kJTD15TvFL&#Ab6Z%oHaPq0KpZ_cE=Q>`R^6)6PJj{4$ zQDZa3hwMR*-Tq2j9=>0o=Xm5{5%W^y;V&c>qj*~$hEbIAaEiIy5qI6z^5$@wwYhh9H;FaF!@q`%_y&) z3&B*vL)xtdDF*Y9aVVu4%x}Xdm_ThX ze_4raT@2<%BzpmEQizR_Ru*&EeU4x7x`sR;qu@mwxl8am2QO0adI|!VO|3t;_>ngW zfApevwbD58BbrRZU4BL7fxU!Rhf>2i{SsnFHsbdWAEwpDO|a?z>q4-tRZM;+YeHeq zPx>&6UM^$bK_O-JxbL!r>}! zmiQCKp&%YbK+`71RSq#ue#40ui5Ni@I%F7Q!TXZ}A!f<{gK&S=!o;?LC1wn=|%3zlt3%We|{JA*SCDN2G+ z5HAZBx5y?fAeTUrmN5*{mbPx!?c&zouk6-s`EA{Q)2-c2!VFh00lXmC8ZK%EP$F1~ zfbxHT&iQ`l62h(0ZM!Wma^{@#J>PSA&htFyInQ~{^A)Ng0V`DaAAPAtmZ(r_3X2FEFKuTCMn2SD${C_IR#9 zDSmskSV!*u-WZE`{Psfkx#hRV)BG0Pwul3Go`dUhA1%>_{Yawi-tp^GGk7b5S6nKF zZPI;PF143h^wi>;o^f?l86NFWc3o!WB>SMuz`noi~;k`M39ZQ`tu6$iGi#SZ-=oj{MspHYfS_JBk>tJBgSC6`4m{1MjqnG~#cree^?u zU*G4Gk#g>@KMam~rb?pYUiKrq7%vD+Kp44)D$?&r}GO`%q*kYajiZ66p$!h8O$jj1cUdSL%d| z^U81VlQmv(^JVXdANM)d6V5Ah#o>?ayUshWbmieJbLot^NT2esDT%K3bndMq%xotseV8dT5! zDbIfT>r|fE?_}g*s?9PW$-HN*w0VcQL>`v?be24vvr+O`x)d8iBV(s!4X88cpoT|f zor4NFv-Oe2*K!)4y>rmfRGB#kwR|quUMTf0MJ#@JG?3CdCszN6m6LUad)aqrPlUW| z8IkdL8v*JSLwD$Vo}o~4ZLm5LuSOj@3U>u{0ch&zB@$;npzgZBzCDJ@;2tJ1PberKUwCrHP zTr3Kp|M|l;BSUv+PJZz`V`{Fe@Njndnc%AhHg|!}9AC5gn?wG~&$7Q){x_*jjsqb`fN4BWsj1s&zDZ zdElD3$B@xOw}kmpHvBLWTR(beYsP;8l@;)3oaq>*3s;b52ka_vWU-Ia<{kKzfInbO zHN{@nh?KW2T+g=JhjC-1e9OW|voSi|-@C=E?#yi+ebMRLKUA}eWpN*xv`zfB_tk!T zR{NWC+cyY!*dn04x`Kh@M*Lyz%7>9gf}(%%Q*06QCEAALf9sF>wzGI^$7=Vs7isTw zEw>WZ_%OvBNKg9gkya#q&n`gG@)s7|8H#n^wH&ZncM!VhqOZ74=~iv*#DJp;m#9Ry z9_T~5oL~cLz^q3y9)r2BkYS2R;>tNwh~=H0pol5b|r zC0kLj$m=4HR-r+qxs79q_K?d)l7R6QPt3_8+9{Bl&W`T$pGdFOTwk#CIhmYr! z>t<~;7VXzLuDO&nMY zUr-X*YlU@|t=4O1IW0XZVh+WgjWjHxXUkc8oyLEnl1TGk zY`Xo`ena0%(|@=byW6$Ckh~Wr=aj7ptz%b2Nf<@z&@GYJPGy9Y5%KL)yh3qBhI zj!^|7!II<4doJK<`L7rL0JN&*x~eW7&oqWl?&xQi+ChgFB?PRTPi{*dz}C8$3hC(w z)zjl)b`qwO>r5wyhhuM;wuS(R=jmU>_pa%d>BQTmPti@Dvnf}uz})Zn@{)_ysdpCs zG<6pUpCf>YKY4QqEXRj8AG;+Kdk*38m3L9JyuqBVqz)rXvQLB&RD@zte<-g`tlC_y z?tM9znO+gB=OrQ!*$FKWj|CjRL7Kz;vEHI|0??~x`yOP+ZaO}Bg>}mNe;R^40 z;n=g%(1+XJ?JvMoHoWY!cY!tFSO@$F_a;XgI{Qb;HYVpT_{&L8N@kby!`L?L3)UJv zpWK49b)FZBwT0MTm2FTaZMTMEOkt`Jm}TU#Py=R-{hY>cYdlB&Z1<1)al_tP!VzK# zaYP5c#@<6PmMySUI4F`9D8d?q9R7wyYLQsiA(AR3m&|sCi#@*7j z>efglidFNis)d$5uU~4v-mU#wTl*I}spOU}f*a_1;JTiW{CokdhW+TMz5pyjvA0n^ z4d)g!Q}dRyOqvnxdC~ghe>xgF2=!v`%2$VgN(E4sopn4m@nDqoBxpNj6e;`p= z#+A&Y{<+%-#&Gj&;P_V)l^-1c5=CaVs@L7Rzxi~cvV1&7?DrCDs~nF~#y^u@`ls>6 z1>+ABli=&G2Fl?1aH3=N7^vSDz+q>YBKHO4$n7SYY^$M-w%gQ3;5OE#>EoZ5@_!x4 znqq>RN(jQG1eF5koZ%s3$`A+vVLzVxw5|+s`*L5vh?0RRTH^xM#R{uR6ox2*I%K%M z)7G%p=QO=)^zrDFrL8Fr#S70jnz4v)d&IXb^#h~O5{bYbo#(ueZ}bpE z&bLPUf&VDr&zf5-4~WM3U<*V+gqUD_X(ME-@k<`yK&*~7dsem#j< zeqhv}$lb+>hwlpnFH|`3!UFw_yU?$n$c4orABP?Sz#JG21h*;Vi$blt&*OutI5X>C zdp&^iSDO{SN(v=`k1i;re~jaY8?+-GJtU_u93mx;BC6v6!A=`_#NO_eZ%T8!SH3BYHG_DkSbQk9G+1wb zR|J>vt4qDhm6kH_7x}_6zEY=*_$*w^ZHmU{bcZ${jd168W+*;lbtv{&u%5O;vB!f; z%P8yiN1%Vx^^_ z_>BdjvV+Z^RcZ>WO2aO=wUlR@-wo-8LpVOp*By%0Vs1yW0Lx8!g!7uis3c9LJZ*dR zyl_0SnPRNNq4=o3pqHb9)nnqLt|TUpt0bqTr0KNh$C%yptDTsHP4j0yC*n8g#%FfR zH#&{~8*_Rdl=COf>i;-@f2{%m`Kbzg*+l=wQ21TNAP?7k0yhci9R5Cs>TYd`Xtp@S z=G8AFpVE-8E96Us8fGBps51pl!ZCeE5r5Yfgm2#zy`8&IhS8UV^8B(02Uz8uhgngvN< z=4SIz|K0x2#Rpw7s`-{XM9&y6elY0^AA)2^v(94*=u@7 zd^J8s^sg>6PFR9cRmEWq?|mm3o(7Z|l^sm#V=m-pBj`we@Qn)2#Ko{E3Etae=I|j) z5X~-OK}RC22u_yknUm%`%@@}q*M+3?-F#fr?`sXmhZTh$#LPTlKJ(dMHO01taMm5a z6-TlMn=A5tttwEMV1u;pOOg0Af3$p`)A%DOPGI4SbrvSp{Ye+jtl)-{drI zBSQAw8n=O9-~$?;`IvX$0!8_j_wDG6+mTXQbsYXg`1Xyo_C%=RHDB$F=8Hx(--jr- zMsos=ThW1U${+Pt6#F)O4mwo(f)@_`_|%NkGyzbdr&WuPRbVVVdckR2ctS_q*7wzW z`&a09Ko}9#_iklFr?2)Cv;j-@Uq`jSavDqB@v8s!W8?u@#RhIMXehl8NC(@t{L}32 zJ?V%} z1Qb>pLpqz8aA@TO(orwV6+nka0~kjz6De7Oi64=gRzfgERYGgjmZ3FLmcUZqH^rfE zkv*=+BouJLvnrAYufvV?`Kb?azQg{2S7xienX0c^^;N09GX4y~S}v9PyjLIjC$yjX z3-eS6+-H5M%QDY3uB<7!!7#?_ic@czD+gwL7t+Q^5CY7Uogt|#%p9l+ZYnTl7A`yt z^^P>slZ&^h8xV*rf8*^5g85kU+{J*D?n$bmixpf~kV<8jck4@CKxXFk)DZ@OzHQNd z&AbyB7IXqEE~6Y|#u7rDS`&^7RuE1MRuSG2oI*GwIFrz>heWLRIcIz;=XXs4m|0Wr zg3a7D+NnK$SEV!SdEX(&-``o=+ON_Xx6UbD@04~prQ0ID_Rw+G-%nFE+|ZNnG<6H% z8ur$Q8s5%xmff$^;dWN%ezgOsVNAWVc7v*Tn%AIRdwxWT0+qPppyMA~?-ZeP9`}5x zAth6CPVC?-NR2%MoMm!@>y%EdcS`SG?v&12>6Ff09Xh^#!QTk#nf(l}zv@g*P!dJ; zxC74QCwZZR=wWB_bG+9{^tdzmC0_4Nm%Tbu)SoF@k|~N(h+!RHzi?&xoinfBt=z5H ztyC47_55&~U*rFj#+I)9?&a=F8marD2AqDmy~6w6%;7czzpMIwUp&&RtD(bfW+t3W zxo3FjCm$YV;SX?&_SinWXu)5>47M?kY!E-e53^`Hc?b}v^nK0cc7B-d29>%>MXm-j zREr9c{HRSHAo(Q8Yi#l`$>&IZ+9r>aeCfTstI25)zPRK3?0c!q)??su)v4=Q?!u?` zirjL~ch3XuHO)@-w-aFG6>gi2-j~2*KY{d zZwS}#5w72L8@VVU^3R+(|A`;;!4D>7_`#$MKbVx^2a_`VKxHjIFhwmtFhwmtFhzUu zgR`q2+Bo1$dXk^R&ZOt~Iqpn)>E!%CmAm{vJ#zVhdgSs0y?hFOkn{d2_`#%8@PkRG z84o5eiNa2xQ!B1%idJri?&fzQ^ne1b*JO0)ZY`M&AWnQUm%l@rW*}G{OT~-4olYO?*wyLn6pAUk zqs9JgL%8kj`~{zL`LPu??Uwa!37dAyI!nT)-LlRdVnjqOIqenU;~N$}ao6(9emB&x z(^+sgSZj8H1N*E_#6Sse|96dBHQ9dQfmv5BVO{yOQ*=DjR)I?jwT0QkjKnxJe&N(y z7l3*oD&gG=UC>Z9TmM$)`+^ z7c{%txqNB?wFv1+-tBiTzq^>UFrW0S66f++rKE-aq~{KCE}uJ`wA3~W)ET(h~sC1OccoOujtQ*PVy6#ovVZu*(fvyf}S%)Qi)Xm4;Va{&s5o z{j&EKBfFcp#osB!(i7ESAS)63ccR}CqcZxfhMni9@g4Z}tNqLO(xo*2KT|!I;U1)ne~d-FSIJZrw@rqlfJ~JpC{d+^!sg^?FWpTbOzq- zol0jEitSxWXS&ngt#n4E*xu7m+`2y%iYF6qZ)GXi=-l$6bIa?M&MiHx3(hSEoLipE zS{XDUygWwmMkpDRzEP>aeT8uqKrl_w`X=gE_kkS8Z0PjXNK`%k0y zpXA9u$&=u_s}%Z!lqW}`rO44w4kg3tCy|}CS84P<^ko@!jgnLgR`3sbGRw4Nl z#axBtC6eEDa^eb)MlR3T*GM1fOis&=M*g;xmA~Lq8GR)0qwD8@Os7~Jkm(d_NS5y9 z#cX|r(LYY`bT0v&2c%!`EhnbcE9|3q!{{9^M!_Myqpd$JBTDmTMsk+=#$s(hJki+| zmo}q@g5Ov;d|UPn^c@5$~m6Tm!eV`bAH-csjk}GpPs6JN1Ox zm)d5DoJt>)Bj;uHsL+eE73}B5*$TcXtk6KEH}v9c1z+^yYy~@PJhfiGuH62)J~~9( zY5m|s-uq}omV0s9ZuH``J=@l2=F#l?T)1ZRg1303sbvgtt5>NY=HcCq1`9L#0nowd z2eWm9*?PfjonRJDuFuv7;<&)o1%B`()ft)1wCuq{=c+~z=pyN9@KbnZ@N?hAlI}A7 zKSO*?FK91<8`<$FAknfv+A2KyjCE z^o?(?h#9)IY$tB*ca_a>Ud6IO1tt9PzXsj(A1~_nYb8 z?w0;7jo;Fy8I|7I>fa1nz~$qL5bYnmILQ7@FAlPQ&5QT&Ny6i; z`{ri$eV+yXC)KCfwq3nhhpRW+R{I%~-&y;KEd80}=B#?$H-CG2vvXrFn5{4S?aMc5 z#JT)3tQbQgT}PCbzm%$u|~By>;{?`02_w z=%M#2>MIqbtHXFEyrM|49UGim!G!cemFkyT)%x_Ka`k-rW)ZmDeoY&3=Jc;o@Y^ z$2Wc@KiNHgQ^dzJzI%rYs+ZSjr|0^+!Q^63Cl{ZG1&vP+e`wL$$Ekbaosu^icH(8= z?em=n{vGMsYlQ2Y^Z$HIJpX>RwYGV;K9G99X^#tlUUM8e=iBz$>t5zwpsL5ghJOQX zH&Q><(cd-U*yhTX5>mK?sBGAIRkV!H9(DES1|n{RKT4xquw85#-o{rhkN5}NLVH%9 zK`PVUdeh$a>Yd^8wz`)iWo_kBo1 zh;^XJ`bP3tX%~Op{B2AAddG0SC0L)_Q~eV0*(;MzR3BEPHTg{S0Yy5K$Ew$b%UkQ7 zq0CdsH>;oIZ+&9-{DJFz$)4&B$wTw(AN@-9e1%!q5G~(0e{?ini7y-Z9Q)FhYwzEU zH`M%ZM9Vq=5YE9md+;Q9LwwZYlH|@Er3|Yi*-gbeci_LGr#h+TULj|Fy7Gh7iPUs1 z+j>w+y{iOm8K1FuQA$6!kNrnxe~*KZQe9ufBjUJVRo6doCr?)zXC{vX@cqcw5KEb= zEPVjphBo7Z1m`jGR>x&M?NFNsG=1RJexcikG`!12+!r*Fi{4)ORbM}6*%KrTs+xVu ze_XJ0^V+}{-zbwA_u;+PnESJ#wj&pZ%G&vieaN}tV8~RmLY2e^Oro=)_(Q>ZlH5C= z5{hj!*U7n)9h~;E8|D1`vG%YH+Iw=!qrgstzVcV7ge&Ch;8he%}qrwS8wh+ zn06;%{e^uBlr@9?7!gC6lp5Mm@)zi?~=`1^+@}UQl zU^!q0{Sy4W$RB3&U39K%0A6zO&T#$>@rT}D&lvSR-`QOJU2}7B*zXHBr0SKPzB0ML zdb7z~&G%}^XazN2Fc}>-LrB|ZGP-@q7pr%28?^2*@)Eqcm7&vE=K#{}(c8C#%i9-x zA{^s32jfpXJlj9${>1n1ERNi-7TXF`Q?z{ZyqD!jB3#xUW-#3Lhb)iJYc+phw8)`V ziZ2Cl2cX=a5J2IiEIt7e2; zH6!Gz86j8A2)SxTXs?w~51Q#ou zvA9G(wTmnCGjH(}N(9VX0sB_Kz7^mt(JCgNC3XKtgVg^t*W)^~>1V0wXQ}CDsp)5_ z>1V0wCs&>|wG>WYiPMN({LArI(Xb!412}fzaisa7po&4a4+S42q7NdiHV>8t<%I-W z;surAhNHf^8^R55`|3hsidYdh?CNxyt_Sbnq)W}4iHB#^jQSQcJ-0glJA{G!?-*}| zN#rDGL{(&yxj_l=pSd%E4PX*@3m8S%*fqGp1eey`n)wG_U++JNmUup(@ zS7FgVDJ=Yti0>c+=E2nJK}*!tK}(W*tBW2ali*-=;c8-qt0TUyXnDuNpNO-SghfiY zZYb3fgTDvpvm?YIMXZ~cxi&1-R>+56+%{*~Mc^M^iu#A*`Co(b_#O8xKvi=gP858& zhoKSNm;~^yzg~VFUrucYiz9Ih$uM6SkL``bHh0NaaI}1@^T4-->Hi;rJ3e`>+V{N- zh8s^k=SGR)9m?>vC#jnxC~&Fy0~acGgjj%>z1sX86Wd!a1`>7^0GFe<8Cid*(g{@7 z!y5A;^?VK@c+BxmzuJ$ms~cHg>0D}_;%1|*K!(oFvSubf$3CmQkn&E`8uBf_=koK9 zlvO&i-YFf!<>#?0F>PMW1)^4SCqox9xQ)S$fdw_oE1j}RiuLC=Owloz0F~WD`LP%P zmDTXl1k8WRZsX0V6-1_YP(>Ayd#PjA6e4rFscfc3=G}RIRB{hbD(eZtYT>4p1U0J( zZfhl&-a&A0C&8TV^o#ah^Ma4}?lz@Ps0esf0Fer-2NS#&aG%)@H&b4lT1u68`v#%i z0`5@>tklV49PYIF?YiUcZx_hEw-?;K_W^Lf1v-EBrp?%C3~fC}CTU(j%nf*028*wA z`N;b8oa(D3OwbbM=0T=q6*JPpWN^EF);6Y~OY=ErxwE$I1~WXy+2gF;sDzo=0%z@3 zCCua&J8NH5!c1_fv-V{r%p?zY*1oQUndp$S_OKFWva6l7JxZ7fpQgz+bH_cdX6E4} z?WWsIx0h}!-A=jPK_ETe^jJ@9vozshjP{2HUp}5bzjW)P9v56L zx;dro84U8y!N9Yt>X`^T6JFaMDp`D#)RZn~(CMH@<%W)P@aYP-zAUr?Df5?eJLO#C zmB#Hf{akoex>)Oe8nr$PYJ*x!L9K^Ctw%wv$3d+pK&=-+t^J^uv+SRE{jTNovkeQ2 zau7j$W8^V1HsYv383xaE{b8%Kc8f9$t_>pNMQ7~}Wf*)LOvcO3+C9oJI5&cf*PXSm zDZ}7hgp9+^+P9QpaBm_RVDoWh82p>z;fT8Sz+W?%3>;6k?9YK zOkYT3`r-8<8&5quv)+KtVKa#=Ur8)0raJZg{ z_Rh_I@9-GZt<6SVd4vPjjiBxdQ1=l~_c2fxi-cLvfVz7O>i&QM<={u#H$fzWzi-;P z*r*JHzxj4PwkpHmugvVglNXg?@Ha>Xxbm_x4E_!y1AKX183unxkpa#eR))dfab$ou zJ<2fndxwWRedF)R`bRb3irY65nSPPT^oc~KKO{1JA(82a*N2nfZw^d(5&U)gMFRYF zVMgL4eL4;Pn)**(?`iS3G3VVs5d5_~H^={pOn4Yd)+rvTEbDqwAGJm7fvvf)aEK)Z z2j`phdx85KaDNB7zaMme%iQ0g?r%B2;GMl6f}#L5P@2wZ%=E{tUd8sGTRA5qiz|jG zz6$C*2m8(Bi|DSN8UI@HiSchG6XQMqNo+qCC)s_X>0$G^xPnj{%=Rl=*kHC_)}jq& z`}v5tx3wiL{HAuH$%7L%$PYD}sfD|Vv?q^FXw|ONa|yOa z7~IhLuG9Di?cEq3j0?WtC!^-RY$!hX*XqQW_=u!_)z;7*fWnXCs=5B6pWtJyf7rJ# z(Kf5*!o;GxYtSD0j}ufOhb=4UJU4{!!oFsP9Fo zI6j3-#Qr$jdpO+I*&j9JH(dU%b}mRBtikbXD<52W1H#GF-L|k(L(!1Z!->Qr!NKM$ z51YHbB#&9Z#=vOrgmJ;aW>2|IdrE0fkncth-6Lfm12Z3_&){$6&q_4n_o_ANjm4mA zaFOtLk-^_Z27eb#N$diD7bkXszvxbOfxqZZc7ea3_It$IlH|G7s|af|`cUu}*roBe z8i3WxmF8pCdz~C!S7hUIjlpHaJ#hIha5)-#0&mx$7)}S0ajF}F(QrNL#X^r z5Zr4MSFw18U(-L)cK3u!!0`zesbSL_a*BSESTuFQpv8PcVJkEs#6JY$(CcNqmP@Qr-n;!@^k_vDzyU z`7lkL@a93M=B+dLM zLV`c;$4+>TznA)W1+N-4tqL|Mkduv?9r%r`ZdI^B!4?IuQd9LpqfhKz?-^I(s#~Q` zwS8x#&V+aFVzB%nC04KH51AwP9>4T}S5wrMtCpcwfsunf|AyZOguNk`(r0LM={YU$ z>)tK$gI=-1d>=Bsd-qrdi)J^#ueof?uiXz!*uzA<#@}1~9X~YMnb4|WgMuvzb})&1 z_=UE1_fIb>_9zL-Kt=Nf-MSmn0@JuaBz2C(VH1; znS7c7Oi0lC2~R3`PQe*Bm}y7)vs&5f<^XB}JM{_gWDV;nhVy)my+;lfyY(@*ZT#`I z-RkzcoO!JWotyZZaITbV=6g2!(8o$Tojl^db2!00$P+oI{hW#Y1_x-yJIzR-ArZ)F zT1+g|Fn(zwPg@(U^> z77I`l7n69i<{(Y99MZs&J%M37nLn_WCy8Bmez!wy74hc$fqE0^t$>5zg+JDWMeQl? zjXLG!)N8?CX5?q>*YX!97O`tvl-yF&k=Rx9^UXvykfrK&-TQY59n|G7HV0_fX*`+y z%@0XK&69f42cPk@%I@Gn7btT(DLLs}-`F zm@QL@;h0KzrW5KbN3I)x*1tjq4ihm3L71+hJEX>8M4|K9u1m_p8o;82`kS`jG0#kY z003Yp?YbYw*O_uMD=`KpL!45&e=eLm8@_YLfXuBk2^2C)T-&Pi1C}@|L}>qS&o_-9 z30IupTr ze{NB4J;a{}^_l*ES5n}|Jb2luyV$HHp6BgWMjUddPxlGN)E{zc*7Ne1`t(GOqZTXw z*m=AP`3Q%cHS2+&DdtY-V6U8+PmZE@Xmq6%EgicY1^r4C^s7<*{wEaO4}`{{{vhs0}rn~w=uUNw-L7iw{lx?x>D6=?sHsa z=I;{%sq38k8av<#bpCF7jZaT^RHpjnw&N>pPge`2O+5wFQ_DHFM$fA`uUJeTl|d2w zavSgqSlRe2xz#*K&r2F#EMCigAa{;av&q8SU0PI?Ig5uc6t(!>huasPokECZ0H9F^ zf7|%$YLw7+~4=RzgN4zA9a7PaeqIp-_cG0MPR#;P-VZC zGoMU>rKj&R2#=n|o_Z9$I(nLZrQvD#hq+f~1$rZ@d!z1EiAR^_{yG;s4S8Lt_4J&b z^IE++-w@{0@Ul4M^VSi+>JeYstLzD*PkCJJ(z zZez`H*_qQ+B(n5)k=7}f&%+U@vovgNK`hG|iLFYhF<7ZwP7c&Na;0(z$|_fq11*ol zilsCxQr?z?MdKDuWg^#)>5N5;% z9q)2xzEJL5I-wCWtGqPENWYxJUs#To@=}cqA>?X8773Lgw11PccGEWj8%7i(A5yg| z$?Wh9AyoVYXYC7=n1G4J*hf{z>g+mH+^YivjFFG4j@IltRNSir^Ng`isE&^8I#k@N z1LKX6FRG5t>^fB3s{_-HvHMj=cXk~r?$xoMI*w7|g6t|(+NVPPSA=+)k|-(%y9{w z)grS%imQ=J4e@|{msT!?BQ6yMiFnfMQHFk&!dv}eg@H<}JOX2uo^$$1GuTb^P~MengIci&Sf^Bxv*W7q4wj`VvfW!}SbZsaz-*O`7#rObO+)Q#=Z zd)?{xRLZ>9#d|$GyCD6V3Ypiq$B{ORa~|-+#$9??u#gJ>TL+%O`FiFcjrX7XP5Y6- zb+0~cRkUuLYFxRP4&SYGu3*v6#_J^puYt{_l}o_uC8xmaB?hk*1}c{bua}&2ymsx2 zgckK?UC3Dubl)IXzsv9&g(u4`4{iUZL21iFHo&GbO$9S zV7D~(5!JCeyABnH51Tq3p^nE?M{9N+D(=;R&C}R~>gdR>L&d#164ddG>gdd_L&d#1 zu$LOk=X}!ZfgOvAdv)xgjyEact_OA~-C0$54?U)oi%lD5e@=!$$)1mO%&n;VD}L8I z_qPl7O^*{&p!UPMp239{?GN3Lw@G2z>RTrq;(OjkIr}=_d)M1@N7r4ex4O++eEQq_ z-W!z+$>>j#du!PKVOnt{Kn+~F+FZAv8W2hvRjFzCUriOd<)Lb<-dI^ffQw9lOa*-7 zm%56%w#1DW)zzW8I;l(g$VPprJJWyF<<&H_)vcoyd${$yi<)_h)XZJ_a{c(Bt>#1Q zE9pz5`I1QU1gSQoU*XIG zg|iEF7plUqFjS@gb|B$J1yBU{Dg%=7HP;6=f+ zty2H-_coeSS=*-T=c-r!B3<~3EW*yt7%dUXXo)r%65)&nW5J~Hz0W2Fv;@B@Yo-}r zrIEjrlO8%% zr02k()k)B4abIYYi!xai33a?#?1eIm`$CNjTGZa1?#^$D5}3Pz61pnrO|7QYU{?U_ z5{_ts>%M*NW>wR8>lfB!-?#GYRhivT^H|GFbUCntqIPC~vsp#0=`Ya=`60!o=&uvZ_`3f(hW-tL$T$4% z*q<1MeFJ|_V%}HqIlg83^-jXb*MUG+L0!V5g{w>@=5@U&fL-eZf?wCoM@lk^bHW5% zNL6H=FX%34?f-UfINr}vw%|$~mU0kTtxuNblL+)<-3pbr*S*5YzlPMLUmkh^K1fBg|Dw%JH3VzV{m{YtsoRN2DAN?m{mY;S24}Q7TcT-0(FuQeqm- zSMcq1s$Ob7F3*M14lV1VOEqWi>@pPR$5=2ox}SAlPqICf$D3r;o01H6*8py+u2s8J zOs$9_#H&N`Mk^#xcD>4ymhG0_-A3BV*^BIb;eKer{!>9{U1Lyq(XWCMODY6Vj?ne( z_|;_U-A?@~4=fasUB&X38k@%gZ;n=$oU}9nMSg@5EB4ov0jUf0eH>rE3gky{(Y&E@aIQ zMw+8j_;9&T&1$FutUv(%SQyA4A%B=g)k=2Mcg#G=2Rf=?v@KYmBnA0qebo1kK2~31 ziWQRIwWbFF&u70>tzQd;-XnSLwQstjn(O{61oLktruH=@Ast6^hoJ6|JF$BY95aJ;I=ddBISB zr*U6@^K>{SK_4KyvDIn3)F9Y6R3hYH>EvF%VL~V{gv3Enw^MX}Tq5C6-{IH6OfQHb; zHs+rBF__?CH@4gycdYew{qzux_#U^E%CE)E$6eff+~8)!#m%}OX%k@)LXES}VgBb~ zE0Q;V$Xk|Sa#$w+8*Zw9UDS<%GXEdrQSa$aIMxbI+8%*9iy@HIcMNva!UUV%avGm8 zDKS6zhHx*nQYdN&y|u3aQA|DS`s86DnN39Ui~)RWLF&s8)yZED`(9Er=Kafmoq7MH zL@Q*1kVUwu099N5C{EOT^N`eSa`Isk^M|DNXj08O1B=gEXUihW>rMRfRJWt8doPCb2Fk4}~^$gu0_EWe-;T=n~87fI`ubI{b>Q#3Vo3fu+ zXisui^)ErqC-}t_d9HurlEUP!nrS@*)yH_i4s)(QvZR2*Q@SCLe7*H1E)!nn;U<2! zs1Wrl_$>aEaATNqypFHv9;mQZkx=9{bOC|79kl(4G?Vh$8g3q)rrEA_B} zG|Uj16#e7Ng{fZ+RCPiugGKDB4Dm~65%RrFO%S!5E!?bEfqI_Pv=+(|gZWQ>LwXNS z&M=sdm`TWmda`r;j-dvSh4@ba^2-JJA;5d)i;QMkM{-N`>q?m^*h6ZEvY#OcZ8Oi9 z3;SZBioHpmfv}l|<(h_RT@s$WdU`aK$Gm#XoOXNlc<+YFH#$qFY1wE<;eAEljBE1& zr?5LGLyU-lBZ~ACF~$Yg0$sSsdOJ6VxrGF~27NU>OX$bdrWUkuppM2iwTEB~{IU8O zJ5%cy67jR%h~aIo*<@yEyE{v)1LSSQvr`kZA?&RR`IvC)@4u5%sj?=E0!yfcJ zAa~9z8aq5)e0o2i_L)hn8I#X^W{{?B;ftxYhGU$f9y51Z5L6eVvvs+H6W))(6^ANy z$Je%SYw80))hsO8j6c<%E_-yCx`cMUgqlb_0>w*z^?8}H8SB{-x65phjdlhJ7y~)N zv+_S9nYh=LKyN$n;Y8(Zd8KhRECY@5V_?fLG!O$@Ml5F3AZ$iwLUH57rrlFtNFj5j zDSo9bp4NWUe!0>qURqxdk+?7MDpw4ZyV&GrRiexWn|WEw9abfRG9;aw)kgaDU6-}g zN?&prSG`K;DC;#_-uut^(wD9$Zk_j9a?`xGl56H2H`f)j(ok67g9@gboyolgiq9!D z`=fKRMOq1--?}EFKV(BP&E4)uaFYzmM5nhs#Ag_%L$$`~5UclSXZ#lac6f975jI7` z7J1vF!EBFeUg7U`O(I(*JUgZI`%CGjYOg;@VHH#%9@j4NQ`sGh*Tyb@Gv zCcEz6F`b_$`}ui0GBMdEU7}!u*;4l2lCd!}qbW6`DP=Tl(x&Cwt9tM#)b?+j+5Sy5 z$bW}{!wdrlc1FNpgJ9vo;r$*6v_q`fojrUr^daUs0S3qnO{LuN?WX*%H7<=2aOwA{ zx(>q4>5=JjK_Fnand%wNm9)(?Ju5XmV`LTNXwRlGrS-q&jw(ATMw7dvWu1y3<;uI> zXSAIQ$BUN8-xm5{OqYdz)!1Xt)hPj&_T=BLH#p4>Hxx%!9@>hg#D57|gDw3SS5Si+ zgr=lsmkS4W%tC{}#6{h8zhW5s{>|Or$Uk4-`(wXZ=<4j&*d(+yenL`)w#I7|i9K)D zhDk_x_YB8)*lhUN>uwV_j~zv*#l2aP@w@c1eih_7(aoW@qlH|!(`H1H4I2^s9$g%X z7hWEU9ckE|C#Ow#Y-4+ip>Qe9>w|bI@-ZmRH%7A z`}ke-3;BidJxGa2YG=K0jzXeD)5;5E*uR@eVE`}V48_Y>=CmEj>h&YtDY>*GorDbTqb5Fnc}Xi5L&|x34g@*nCXFjd-N*5 zYE!>zBwGG*-C99h`;zq(0CAqu@@{6FP4!ChG<_vh-}TQ3Ws$r`>?E)q)l{;95Y8bT zucAIT#kTMsQpgRVtSuBW1Olk@2ja<-lop+!dxa2r=h3deI7-2iIZVEjt$HY1&y z{p^a?D+V&s2YGrg?Y5kze>LD$DUdJKfRH1R8rN^#?A(L_e=Z?tV~thvh^6HR#nbYG zsk_`NLz-tHMHr0(Y=K3vTVv2{cl}CA5uPt0NBgwlebyEBB~1PvN@ce}e(DVge4Z8r zeULjZ*$8a*%Pad;(1eTHX7lMG@r1X8#K|*2;{6theEUH7A(T<$Y+#aLjFj(RoXaBx+bE%Go*Y+up+_+IyFl>k}RrsDLz`Ejdm4>l;7h% zGvX_{3{<J+GEcpj5b_*VqO7C220gNP!8zY}eEgkZe)ZBq_}fGA%j zN-+2sFG6{_3wiyB7Qo4PgIhO5hH?~n|iXd6>Ad7F{u_g3E|61l0{lM>;qX$!TF+m<#lTltfsCvX!meBNoAto@Ug67~Hv zmWG^o3v-bM0XE-dG~^p@)9vMFI8Ki$727fOWLVEP&B$261RLp(eb0M{!uRBbcRUl! z4sS=yLFZUg*iKdB*uvVnxXcA_$_3C1smXei1smZ2xMYugWqRx=*uh?Nz+hn@<`WOg2|I6kj}xb&lo;xmpP|TaP#rFPLQ+{P?S zM|<@Je!oz_qKd4F2RtYK{odtX;(mMdzDwGGip|_~2fYV6JA>47x&dl~u;^%4pWc_LwpsQ8ng) z=5Nr)L%zdaDb3$lIOlUN=cIF5c-^_|wsUzn!$`km)UujOO~t9Fp-9q9QLZ$zF7@Zs zAhk;RU$*^=Ijhw!yNgcfyjFsSRk4UGbgFBhwuBLOYpm1KWJ^vZb=InvV<@TK#23qc z-0AEYzeAQTA6D=;`3k>Wpm0GUJGWeWN@-0B8x-ctZBuZuqJz0yJda&I86z4JQ?G1! zLPiL!iK&;hJShv3^@*wPYk5j;oH`Oy2edpbPfpu-B~aJ^tP8ZKt^2R1BT;q`Q zNU*|29t~F6$Ya4NHu89ICK0D;A0a1KjdPM~CQ^ECQQrIWfC*mqf$r zP??Ts@mJMo_BE8J;6&{eT^(usI&*rwlHRJ25dzY#jqT1f8V{lY?T}-e!`q|r5vX}x zt{@dWtxSu?j)Z+%RR*1EH1-l)o`Z)K_DD8?Mj?sq zqsf;TZ1NGODE5SsXzs%eFZVc2)7g53%YW@Gy%~X3BKw0p7FiouaE8U+a0yxBANk8z z+I&>CA<4l3fBDVSnBR;;ai_7B34y`+^OxvUw(tRl6E1(lS@xhNDt1us7p;hJ`5k^% z^iAF?`X+h)q7@wf6@5pG6h|IT<8+EgV(t5$7A2zysfe(`;?{(coIuk%|k^=2yL zBkT^1X${A3JO-ROXLlWF$BWL3#)mDUTop6;bX8gJS(2e1kqn;i*JDYRIsVk(QW07ee51bok=TY*3A;yop4QMd zKzqiOf<;3Y7q1TZ1ySLGv$*5ZL%!|6>+g=lUNtDvCs9DSmq@OUCa2#E)AP6|UCnJ3agR4+B8N9o3(zC)oJ zHYMi<+~;%Y>NXWrpGB`cvISGpuVn03VHY#Cx5O-Bb2Qc=W>gZ1?ZWIroTNgJIDVZd z1(vL9b(*X)I00A@tf$_txn>VdmyHSc*jpDo{tm1wFc}f zQop9hp?FmuJ``vNhPzpZf(yO{883w}anBx!?NmoH{bTGywXxO43^lKxG-{nA{^_ze zK)Uu<9!s`Y&y|!mw_D=u%Q?%J1ZRX@n*1_TCYQIFu zPUgi5NYUnsVhKlG%1H}HS~E$VwQ!^pJgC}yGlbKy#I89Kj^-HQXpRw%<{%u2-jlO+ ze9duHeoSHTeuaaZ$sX3M=!hkWsRJbs4U{|-kUSKSJamENp$jAr`6LhdTDIXBrI2j| zUgpa;)~y24AK@=s8al0%BP=+Gl(QEpXV-s|l#?sp$bM~#E7l11I_sBIW26~n7)5n+ zUC2l@{otm|PNOHkEcN7<6`uU^kda@kf1P&jjT_O(Y5FPANPGf#jd@ihI1L_ukTsr_ z230y53ov*0F=tu6(d}3gg$Eo;wvLB&qIgEXt~I&xzbJr4c$e88H}TDpCq35e$v5Hn zs34LDPD8>@IAJ!MF5j@4i%vBAuHp${XQde-4YqaWMdHJdYexClEm;P}r%PlWSEY2T z3X%vZvD!^k2%p5-wKgO^IHo4@U)_>WR9OFnkwW_A#PxX8f4!;4>&-(R|65J}NX+WK zA*DPO8TVg&ilh*RXIDdIP5iH8Toi{Jy8Km)Ry}|~^OFBjGpc`nI6nRzD!7)to3(Z` ztoJdM5qs9cL*Z-L|9rG2kF1A+y1}3~Bqd$Tk>u4iqw?~_d1ouPFj6M+zqXLGq>C1O zJkfTIKCcmpPxbLM|Jyvu|F+m3nc{R3T-Ha+U#-Q$aM!-gXILCl2OqPkSDvIs7sTziKdC#Pu`9o`>Dzpko?bSG)e zx#3%L{q~56)qF+J0-S|Y0N1>)_&f{z%1 z1BXdY(*((5NBlr;W6d6oqn>eKx&@K0%O?+7&TET(qyAh1TzO^I~VXCiv zGwj<$H*RJ9V7-wdhu~T*IAk3O+^CiPq4l}Jl8+&N0N)z%J$f|JsR65%v9~8esnBa{yI*^JUO?UW?VVfa#ZA8zhSM& zxg|E@aa82o3UW@6Vbk;xjo-(ubH{Lb(uq&b6T94}0j2Q|HB1rT zq`5micJ;j%}mc5A(aN0Kv#8MlK z#4XO$i}tY|UGI{7=+q?7yOs(>EYSX5k^7NTl6$m#m$PiR_Ia^R@e1U(YiedR^~)v5 zaby@$6Ge*qP_?B)2*aaRO|OXbt30&iCt8NAJ^C}GUZ18rL+O@;J;F2eHrLRb3x)KM zh`7Y-5ohYJp_1j|(j4U0@?D_V+em{lq^j~ZEb@NEQ872cRII{o^huU>-N~VoKGnlf zB%6OmVS!G> zA4^<8GF0u=k>(VT$Z)lxNU0)`*bIzjHrD*Fkni>5 z%U9}A!#-c#|3i{;IU}G!7{<2L<`9fYS-A+oY@(Gx{aO|jP97- zKoue0;Rsn62p72%=NE_q1 zo{!UJEPZ(=1i>V-}MHX+mJeQBrq{pC~?(~lKdZN4d|F}%Nd1tuo zZKS}%$zLAWlYI8TYsn`Myp>EIIG(8d%L8Z%{^G!fMCG3!KrirT2X-VXuRO3PQF+;c z*AkWQJMdPba=-x&lHV?H7JnRuCIkGT$CK|~azXOl%L7hvOkX;r3j?px4ZfWU_9{6U zP4S&AZzwpD_^0^;2mJuQk1cHqHu843gx7Hw*w9vCO8fO-vx4m=U99L%1$*`O#2=Uf zZz$skG|bz-;|_!yj{jA7-MYVGzM{^kp5J+Ye&-!JYAKSxO)Do!o1|X0J|wpD@@Vw;TMq!ck&aB zy&P_P=e>{{h8%RWUR@2Nk7;-ZLjFiT+m77?|!f6!=f`izoiT z(40$yCZjNi2#W{3Dgv@Z$Z(4%zM8KLm+nkPfilvBM~OmZSi+;-Fdr41=O4GzQm$#E zSZ!oC%Jt|h%BKoLyVtn+<9eCrd5%<#`$VJL&wipv3}OA8^@2Kygxc%IK`K; zDt})44@a!{<|~f*}r87dF)yfWZ1Pn)=7W=02p+`eQ&byI7fTl53{}P zwSQqHVndp{Tnc#IHEHYc& z?e13hhF+88N>^uzE{68l?f#o575$!Wc|EZx^=AXlos#L2J_v5tADw!s7aqZN|M(Pa zo*wD-KPo*^ny5O^4zuAv@2Wfe?|nU!D(=f3Ui}6-IB(fwqmfy*tVSt&)iTRono}FC z-Tl(q{VsKLiMGK-+{77t*$&irTT$cf(Dv_AZTALg$9SpsdV^ez-=Lyr6K#XgBHn`* z@gB5@6#bBjqD5r8sG?Sjm}o03dY%A1;yvgQ??I19(NCx-dc=9?5h-f*h~A_!pZU(> zMDBdPfKGlhI{6Lg~lyva7Ne6!$I{1h0yF|Od+q6r(t!1Oq5@Lumo428MR{`{c zdY@pgDIg(6H4sScZe|k`u{FtUXj-=cqZBYoNz*!K)ra_2657@|z$x)CehjUqbv>Ha z^*|^Egi_M9&RO*d3ZiYD1C&(I)3gqkrgb=)*6C^6Px@pKC4A=M420ySjVak04obSn7 z)v}*)*r4i)Pk+Y9`t)T)wzFHG?0KR-yXY-QXLgcE>FkXZQW1)(Y|Yoe$yxgP8OR9Un(%};(&L=VJ;u4*qnyh zPk)5YBn$s~t*08(HD|m|dL!a0%Wq+oV+2_%$NhcwTmAj8Se;oLur9uU5AkVjuq(p! zmVMqjfIXD@_#W4R91dK6LYLH?51iN?kH@}zZh7oUxLLj&9m-rH&DC`2`uQ8;MZciK z{laAj#pmE@%i(pfFdtUFFeSqbu@`z?`oxpiNEFPf%fcPkK0<>Io`MdT8nY6=s2Mm@ zJkLhozik%k&ib3Ird_mE(;qrHx_T|+ALPvOGaKz@-QIVbA7%~5okJTkYp=pL3Dw?G+Ui6()V#DaHZi5ZB+nh1eQCTerH21XZ1Rh4jc$utKI;!G8Jbgw~ z@V7rVv-{bss+e6{RgbAkV|1aMRn;7->M>QNxx}n%`>N!GsY+LpGe6nW@#z!mc|R~0 zm&xZ>v+*low%`_Dm9i<+?J|` zEXnjNr?@S((&kvpDf|=5K#L1gle`;K_=~gx2cGv%Wz>YgF*;XHJOiU9!T#n`5H!|Qin(Z9E_-^-?tWSITlz1r{HtIf9E z>fur894zsG>OF4tvN(y;xV_K8YLG^5vHRN-2f5edE|Ock&D8JLzAVG-ayC;1G9S(r zKL%Lwf1&Ow z*^5^GOmFZp56^0}%~*|gLZ!yeRPLG0$2E>pOmYuJul)IeUHzQ<)g7nl0AVOz)2YgE zksEI78W4`pG~dEzKX-nlY|V1+`mjrU`zmMIzfoH_))tO!>N*q;jfQ)Pdq*dJIm&`B2*dE%B^?3a zfzNUjsr_z4qSTrLuUQ_7ZEDzgK0eyyi`+PF3&noLU9z?0 zG5L?EI0jIBbw3El^RJ=t+6Jt9hiBcVwC%C-QZj-k=GRkS&;hHwvc=jc`z?)r=$5YA zhssBIdZ6C@3Z^UdZ5VjQ{@F8r#<|@sp|<0Bx*xd>7@9kF*8KU=V1*7>42%y6WOVAA#MOhlTT`_p|*GP8u-#Zm&+s>fC%9m;z2W&;n=Ua zHQQuM;ccF4Yq~Fm$Grh+)0m{=udeNtf~YTPFXJ^D2W|557awMfs#Q>i@45qAw%)j^ zb6sax-#>UV*-dRrttC5!`_Xf*$E!bnGswq+#pd@RV;3JGe+Yxz$0wRc(R+M#b*h6- z)AtcIBYF0=wH(SdJZi>@ljtjSRS~oEF3N@Dg++Qv1HqC$AHOz@b|mpa6E~gZuCVe= zU*dyIyg;3BfG*(?2AJESD6)bpKS4 z+&^o7*hsEz%8{ED{{-Rmj38gCGNo|ZHrHR-Ngg)>xVck8@}@3=>7s`_g81n$dG~gc zH-}G&t)->_swk?O4pI2$h#tlTi$Vi5jzrsBKO{ES9~OyC3>Fhcf`hm}H!2t;92Xo+ zI0LVlbE#w)q5P+*Ln8?Bc}+MfIEws8uryIQ*B?SLKG#2`OBGL%$1HypH<0K0tGRE? zQ+iLykmB6ds5I@)rP~q3Z|YK5V+T^D`1Edt_X-5#g5&hoba~kF->X63*-`Pi=B+uM z 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Ÿ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%0DgW?o$p+C@QqtDON1VIa* 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ính8xW%=q@~7 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�=_ew*Eh+KG5L0YO(cn_Zy*5AsxcJ4 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

Zds6B@a3a*Nr&oV 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

vZy+sj=A07>)w9bju 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

YGJ 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%0D|^x64j?df{-zA1_Q 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'MfqOkz3jbsQ8`n$XPXt4eY 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

U>}E)#6E6e_tHZ3oicEtU@Se&1sLno+0t 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%0AAix0&y4rWt6of&j;eYZ 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

4iX8oP>*g5QOsrB3v9q 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%0AK(ddYMQ+H3;A-0Gv!e60H2A!>}wu z+um^|FW4!|z_1pn0DZ4+CwpEOE^P@+iDN#CO|uMQLNDc$)u*Rg>!Eyd8l`tDpa6-2 z1%Bmxo}Ho^yfM3YG`C{nl}Ygc3&E22L#r)g#9-NbHnaw!!|$PNImn~&SN$%P-mL|* z;PLZ}T5iji>bVhqf(y&5+!fsCUfz*ws^_+l|G^hX8qgcuWCb{mPVIy+W*fK}gpx@! zHHO)s^*-Yz2gaHg6v0eh&0*$v-t+yJGs6rg+T=5rf#uPu+JG&?s)5vAWE1l0wKr|< zk8q9Hlv+uAP#wUStR}NphzoCV8#9<}r!I7=B^a83TvL7nG0SqN!Z;mzk1~Iv32#=Y z6uRs-pn0wDXoe|^4zrA0`Lw`4;tlH23d#=5UFRm>#H;?I4z`?Y===jk;tbv|LwpTF z$C!&9I-2fv6!LKn4;8%N)Bbpv4H&XEc>EQ2#vo1S@xaLi{|g?j&f(#6VMTddKwTjs zzE#|F_+BXZnAC4hkNN*YLG#psC}72?Vq$QaJ#9K5GYrDYHn_osXwfUr=VlOsyo(%y z>h3Xm`P`t_?_KC#pKPza)&y{BI5lr7#^X_j51NOSl|@vNwG>D8j2DyRcY@TZ;L?xl zi!#GndLs+ZwxVKl6A`ZNljVG(bG*~L;cyd!iB>pQWoZ0;*UIeX8!K}-WsH|iFkUu3 z`v;U1*ZIq*2qn4Bf3JV%zsb#teef$6Kh^TaoSc0(7u^KIu9-fV@**paI!~5-FrK9X zSa+@fR-Fp$#j`?stmTwp!j{roO?@#fWdMp%ZBSbL(LbL7qNTe$^m|9CKc&*lP=v$v zp&4g-HyUC!^f{@G;(0S}c12@eo+GRYlAXMf56=W&tT;bV%;q-yzOBQ14pM%XPt;!; zrN3l@V<#I`IsK)v=h0MT*QqdQueAtn6RJl&s|Iw!AN|@lG>W@}QiDFU%#`0DuTOc) z9$*0CbSBhXgif=*IJL0CbeOwU2|7$8iVoD%$mhhId6PTSYw6CVs4j8uHm$jk(LUu4`U)4t5i%0i(tudObUs7f!)LM_9qAu3pdLB{>J?(>fSQ7T| zxVzo>D8;E&7tc6L>N#e;v!vdE!pVb>-chim64BnKok>J{vgM898voo#L5;cp>lmCU z0G#d?PqPhsa)+PTGp@a7xbaKrGg3a-0um}T=rfBEL&b|_OKz`?yjz3L_E%w3%1dKT zc_GH=L$B487o<{-c{a*E+8LagvL4GC2hV#cZl3}qjpk{0xxU(IdVAYPjm|!57A9zV zrUut(ENA;8?&GPA<_xlM$^%-h8QPfgF99=HDLrg^GgVt!i#fScY4(Nej72xVNPae5 z5U{y#e#J~svVnO&BPjns&N;Ji-VVM7n@bIaFl$KCaj&rhr6>af*$ZG&gGMiD_3aKW z|DE-y?L=rfJBD(5>o4V@{=(9887p5ndHOK~Vnmvb7p{#FI36JVWpACOV87tZllsyh zA{G#t^WF7QUmhN8y=?mJn;#D>{63jW<=@c|@ZC@NPBV2i1@%~w+wshoOq-o4mB2qU zBHv*(iz8zNEZEEWJ519R2We0xaPr2?ezyMyM~A#V-sH{DqTCw)i8wQNPiVIrQCY*iAUNK{xyAk)1FccM$XYOX#&l~((lHqo^b1r2VnG>c5((P z-txZM=tExXEXLprf5ZqlKtx!4lvD}J4rVp5M&@aUDveb=syVEjEs-rf2ZZ>*vNye_ zIaetL3ybJH8)<9l-3bndd^*XY^2x|Ec;0N;tFS(Z|133hRz)@bvxL_+mhNY@k2}xb zBtpDpXY)vQk0Xi&{fHtoBAGVMfni<^(Z?C*la!HooTKAa+u0du9zeKo9HDZKKjSW} z;sD0IWVm_%oGSPHUM8`Ll%2uf&l)IFV)!)Vov4nVIt#E{?_wf~8%$tznRKuj2ecNj z;(j%j;Rm4a{c{M{DPGYDo|yz3#VEYs(XJ&vu#r>_j^VH@QtO}F7yGMAxqXYQRF0>37MCa0%yMl~L@>;?w=QllEv0^9&qOf9mD9hbd^iXz-2k=-cy8 zN~L$W@v^aM-S=2&;;dajdQW`@$G!3xR6QJ{*qhHMBhblvcsS*E$qeaPlIITqV{tNy ze@O&)o(WsSzlWzkUQvyI?{9!79(}KC-*E33{V3Th)`Fa2F#AU87JPYcSmRaO#qH~< zlbXntXEi+>Yo1s!j#CQuW|ODaxv6>PuN-H&l!=whGycqe@=!HmyPap8LpmUi9&MhU zM!d8xoVf8*nO8vuQDEf&VkjL+4Gw>o%n7nYPEFml&@OK1(|bcj06@Tc?KSls_h z8;drXY1uYHa@5lT{-synZFopZjoituUr zJ=JCpMjjP_&Avq^#0#^>g?`1ofo4F7HTp!k^fZm#rjA@mkAifExCatviForw@{? zg?JHv^iQX{sdMcw1m|AzbwT+0TlN~I0#-SQ^y(>M`d?V&0szSjlORbmesPju3-uaD zQyprN57udQ_c(pq&;{d;aGS~yp5lZh0xf|Z9<=;pc#%49H)H- z%m`)Y&3{xs!n}7QTD2;mxcL{(@Qa5d03toBkWUgN$%YLz(LS$jwPr{UqAqi&VsfRB z(~3ZKqmg&{CIskpQ^IkH`NgB+RY5$ueg4;z4NoBN+-PtF=KL17x@AEw(LHm=@!=Hp zD7U(WJ}uAf`_(ocZgmTNx*(r3hvusHXGWyz$`71q%4E*~I>}c9^(1aM)>ckXfs3eX zEq3(U--PHu-Z5#K1$j)V2M_tUlH1bP>WB7y!w)SmY_T0N}Av4Y8_?l5}!v zX#0RAJke6tETGFA(sQk`jNqx$3_plQlR%Fb@Pj8NzHm)nzZ?fU3Eg^tzsd&+_Mg5mH}|`y9t;Gxa1J$ir*&cjCsYhuAD4 zBE}-d%IYd+kskF*rlij0fTU((#o_#$zL}v{_BYm$XAKw=fApGj9DllfwT3DEj zPk!L$#-_6jeW+i266?*K5mp|fxPF@M))=ByyiYEW>?!a&$@zZr^>gCSY2%~WZD>{d z@OS0yTjVR639EGd=R3USK|2La{`M2J7sK=>`^W#bn4&5F3b-WP9Rwx)nm!lo z$dqd|hKSBCvfP{`?2#tY8>BBot9c=tltO;oCkWXWgU_BiP{=xej6eFjR4DuPvj*N? z^0hX6JtTzwk-g<>r4`v7yzn#EL7gY%qjtw zMvhpL6SmtWXloeP(0L~Xlj(;J=q<{9zW*p;VaSKif6?4E$gmAs`-Bl7m7 zGyR?A@1*SuPRvTiR)jJ(6?un%5hLDdGT|~Kdw!C~m*g#gf!5%g6J$zqh3#kj7g6~D z{?*$D$y+Hm<}BP#@^*mvh)K6IID&epqTnoa=3^x|9K@HucBY#d`~7sE()Q%=b#RL# z`;~*FEpxsgQsEyFD=%sLN4_Y$5>K#ALc`J>M$or2f3&JF6aVmUMTJh}T11Ai0*-z7 z9)yRGCFdi@Q=WxI$l{-PwTv{>j~Ou38s&UjZ@x$qw^%odwew3B)u>-PoWN%srDBXV{@Vy_@PY(%$( zhYPnO2dQ?J=6NX9_8FGP8g1^YO83=1mUNIGwuyz92O?6Edo4(R?+lZ8gFL#d1XwO~ zf}(;qRt^+?&~jUsk?-g)@v-E}rhOE-Swh6kJDs1$qSAEo{K{^(aucNNZ~ z$UY3gjp6I*_S$QGo*@}Dp>MY$JA+fgB4fxZKB&liE0PTk35%rIH>}xHuhE76OD~~7 zrYy6cX>#+}L9RV2@rwEMeA!Xc&X&2tjz1^D(@8!n=JGfi4osIPn}vfYo3*oy8m?}cS@mf{{Immy&Vrq@HnTVi-Nr*w1JX;p7qJCr?} zH5Y4KQ=3!c10{peiSc*6=oTELI|eU(8P5(;giWjH70uh+CN|()w2bLHv#Vi;@N>|9 z8TE@PM1DMQs5NW+(J9`Ff!)KP2hZQEkuh|6t)Iow9nVZKf5M-KgJ=Sl#HOaw(#hp~ z7A~AIjq9C3tEnV7CJp1QlQ$X9dGljKuw!XwGGUwE(jQ}CryAO;I%<)yk&d(d@hup) z8S~{6Os5^A_#5U>irR)Du5t#~Jo)l>28W)MSA`T$x4EF-(xa=ZU4KW?nf}D#`a6TS zvGn@jotqrfzedC^`p9*)!AYG-r>h_%AhTlhIBt@i8&USm)!;05rf6rzGf#tmF8zBQ zJ7sb=$@IO}lLa~v7j+f$&~}z?wEnKGvV%ahbwPdRymG%Tqm@S72kj)#ti!sf?~qS{ zW78nXdGy*_{1v`M(z;-p_iLhWVXP|=n!|5!ob@9dvd=IVbNvt_%MY2j%_k4n1*gfk z-VDtb6;@y3RWIh3U%I@dLt*3L@(V-O9u6705z8-yA$ty*+4qn&j2$>+VS92blLkX1 zxGanOK;VdgHhh(E2qAtA7a`(f=}vW{fP3kG84p(p>zB43V5q-ZAUM>U82TE36K2CE zzk7xgx?)G0bE5c&ygqb*y!Qp{cMrh+Kd5a0_Py3K0l8)ehGW^u zLkwzL%V2g)9W*nA*3d7zg8+N;VbW^J zLaVSBZ^X*tLjRdqtk$@U7w>SKw#{B+QMr^4vD}hmX*D&(s@jDpT;-{j-k3k5B0>Oh zP5Nnqhr5yu9kJ+^1svv7=3<6%5a3Wpg&rxtI^RXtE_w-r#l`sTj6Tz}c0gobE_hgx zegE*5>acU^-{kV`$M2-_e&K{q8qeI)RYFTwQ@z$-QHL=DBhajZ35Ba}lgw zHjplV1pOObmXRm622ZKlE_p2~Lhn7tuUlgIS#tE)-2^?FSw|}PKSSsE6OOzOF!WXF zy?hlX5F_S~+CP!*ibpy0XUY@N&GU`=TEfWE!PK|lB~HH}X8qX|u^H>Li}p5=Y7Lrf z@QUxmVU~uCeuQu}{ACJc4vS|hLwzac9jn6-r7+=@^BMVA%SZSaTSQf+28GK$2`N+j zhocg0C*f2mrya#B@DW{u9u?ShFm=f^tDgNG?H-mXs$vx=3@e?Aqbk~sru54RQupN^ znzEKvSk!$6Zg#M0TR*kvAy`X_9URrM=yOfK&u$0xbmQbXe41U#K5iS3MY_;{t`l`9yJ1ONZW;~_U5I)BUHd5az5#<+mTF|1F3=YQc? z%f9@7;aH0*3-cY^d?N2!(4Tj0ZCaB(4S16e=7&|HTaj_$zJx`R3ha=OuACFu=4sLF zk_!_J8QV}-=HQ*0UyZHCHCAJ};8tV~GmgxNtL8Zj`X5dqpV8T@QxNMpz8=H^ZLI?wc5zsuSeWJWu&e9*{rOl*J8a-oI`p04E1NTw-L}!oA4T}WVi}&s2I6Xgny~$qV;(-2X>WUUgcaEtw1h>bV~=KriMt}_>ct-URbp6FrDNM6;0eZEXP^r% zB#MhTb&DNYqY{PC2N5K@PiI%86pW9MHD)RAP&!K;sYJs@rq0SQ!7u%~7CR1LYA|Oj zqsHj3zGv6+siSOnPbz=eY?B5qZ*H4LJdqmEE zewm=4e=jcHSN~GHO?L+Cd8wY=N;l(~FKEoTa^n4;2x$vx$aQnl7x>7`mm|2)oRO)> z+DY4b%JGwe~_8g*mdKKTUeuwFj12nVraBR+)& zjOLB139A5eFL}$)2PkW?X_+H5VplhM{;*to=BoeX_WJ8nJwNgWIS_9 z0TJw-(eV%Jts7yR+6={{!^efgjDB~zKdM~tE!zr-u(}QD+UoXP;@S5a%e!RC?Q<+g zA2V<)L6) zH%qcU7JbCLC;!xkD+Ck&h5!#dWnr~HW8Lznit%$dH z2(@X<-29721410pD>H`zTzZS(Xu2*pa%z5g)HRP?F7Aps*ZRx>n(d<)SnKL z4NvOG_lY+$3t5Y?C6YrOzRdp99+WE{6w2=NQ#<0fnkr(mCk@V#eDx9lv1Art_7 zPQ2j0qYc0(03R;hvk69bhT4OT+<)C*HX%3K=Xopsa2JgSD=CsWMYl1=OuNd~D~~p7 z=hRnHLQxiaa7e5yUNOKPO)`OvhvYh0`rHXp`>P`v1Q_=(Ga(R<_7ctp+s_^jyoRrMW|)z{ zzRNxjd(OUr=AUn0IP)_?chgDw zI{P~1^Yyv+UvTe_v9Av`E>q~Q6e@kEs7>&x0kd*FIV-KjD#U=hnhP`FI(Vf?lwHF` z5H#n8ON%ucuF*gnCljQG>-^($!*%-rdu?sgJGq&aY*{zNEVg842TizRP~t>A^L^>3 z_`bkDwT}qp8~m?^qlFq-0jIbFF}Ms!R^bxyQ*TRb3Q)bpBZU8o+g(gG&hg zM1X1{9kHrSf+pGWIzci|H~lRx*`4=tn4Z#eM4|u2AJ#>*k?~$qsHygXx1;{5?NUxA z9BGr!#fR4SJgiQ(P&m$ZOV`Qeuv^FP``c@4+0wvak2ZsxVk!LJa%_M6b6|>_G5zqZ z_#)wZ(1dw~6H&F?%zAZG7lWyeWsk{YF0Z;CO9SE=|FO_X#?9au$te1A{M)H`LOtG{ zW8KDZ*6luK4rdrUQ}W{Jx7|{MP5p#Fg)M8Sc(N}n8YdOPTeX(pl|+6i!7YWQOv#gJ zLD`c3s1m_q8c9I|=sx&q4`$Y5{&*!tARwZfdbSEGYnHN*$B3 zs(z4bM1cR5^l72S`VK5$-+-S=w-^30TP+GHNdNw8n{b4hHk5&*3{-ry{os}D1=bAL z=*(;tl-ohDU|q8ONbVOY(0<9;K&--3gUSL_7YZtn8H;r0SzfU4f$TkCj@g=B3V-=u z_NV6Tu{o9}D|4X>fWd%FXiIJ^8rf^}7aLF_W}dAUrD;*|ZZ6=Tr%OzJVg#yLXzmj% zG<~v{g=YDDs^t!2iRn?IW(L_i7k$yJG)^_Mm1B-4Vt;!tb23~{tPXCyW}tLL2)6wi z(nmyoj*m6Hf4Gk#O=y#${dO6blz#sUuJk$kDE&QWzdaEasieq0?6*ILulKjtSSWk1 zCoZ=lyMx!Rc2oC4Y!!|Bz+@->=S=9HJK)9_L|~s3~N3ObA>sKHzL2H zINMEeZJdMUnA=2jHq-eGXay%2;p>_mEU?%8keDH&@T69$L^Xcj(1XC)c#rjHi+r4h z_lvUe_-*L%na?Y-Wjg2Zu*xS2F}Lm0}nJNVV7-Lg1#!aGfO z4Oqc%N1j{%8GtLOKX~Ma1Ba842wv6mO4`j^Qg(h#5#L9yEi23yvKTs?yf}{w< zx<)=`@0r*7A^H*Y+4f4)N*Z$XN$uLT#=b>w*{}G-_Ab&CV6%DAHD&nEwWkmvYYu<< zK>P2i0v0Z2su~trY0|AVGTK5#VXZMySo|^)IPP;GBKieR^a@9IGc@Byw%=mX!1b=& z_)>D;<2!8BCylRx_bOZ%Dv8vL%Z-t?;!j$Aj5E${fR=NU8=xx+^ie}{@!UwU#<={V ze#kQ`uCcPnZs0~$qoT5*9%X{c4>&e)c_kc}o zJsTmE9`)bq?{A;yY?np>d)3dRGB=tU7QA^d4o}G^;-#+VQ+U;&{aS{f>9Qo4ij+8c z$!9SP$Gu|SZn2JPjca}aU(Q=ehrE8C8Rq{m!lu~e^8YZ5lYJ&=RaYvq9lpjC)#|Vd zn1eFq4b}qJz!_==R~$$I(ivQhJ)3g+ox%5cj6lIB$}&)h;mgBTa3^(_JK)G_BX7|- zT4QlF4CF)Phl|w$CnbKN%z2*x&V3^Xf&nf}1Ji zEWkL8NP&GB9ES#Ah1Ik}anhLX{nme!+K2-#yk!d44+h`;qX+?4^Ug$AyqR z1nRf=6o@rAvrOnFYyv()S9z5EBA2{p$TwvV=2|%XJ(CX{vRYuclfBYk|5thzGP#5) zTK-9jmY(8*9q@rH-YTsw!vw>`e7r026Cjz~7OH;(${X!%e%TK*f-X8+#57@zc+~xk5`%TF$*Kznt56)eG9ka)D>mmESKwC)+i5vszCy16AvZ z5(8!`2WS02)D)v{LXyTl`e=GHogkY|IjkI%l{|Ko$a5b=6@7GJ6$%51(l(#t7cZuG zigR&9d;7qj_N;yi6Nf`b5*-eMcDNiSo|65RUQR2ZEBe&@3a5|ousFZ^xY(_IllUHG zIJ!}*k85%7eVB-DZrYSx3n}eOxjKM4gIV8q8dxc_hg=|JffG_3QzT-lJH3UxRH#~78Ag@|YhKp%UW&(>$3DOhYE)syL zotA1w?8fVb;$o>p8x)z@K2CJr)}^lEO^Pb z(0UiUC%t98W*0dXm67X*Q3(KBrgK`VQUTgpE+j7oJVBv^>F3$W=px$P`qqS4^unU_ zGhh{^gLHn1&LkMtlvAuabl1<&7a`cLxk5Ls-sL@6Z zehshs!5J#iBOZi9P^dFpS_D?35WsaR_1+*`t*~0{h5%B4yY^F}aR9DjYcB8tH)Nax z_qYPMGvQhVaQ~S7Jp-I$;maq%-?FnwOC7Q#Z~3LnX**eoAzprz_-ZY$2Uv$;K9KWk z(~rickx7VTmhkvXIai} zt!SnUw=QwJQXW-vM>rCHu@U%tXT@q)?`y#8-;OtmD(KsuNrbBsn!!_@a;R^jNM-4Yh+^j2sQpy4u6_7jmO^k zpP#Is6F<88(x&gwULSjrF4kA2=Z7ugIWi2nBu;glK?;&;ymQ-W{oI`)nyR^(z9Yn) zRu3VFngr)@zo+YLCzRGtK9j0_T)S7v4k?mJRa$GoVQv}Zi;QdCS4|IYP{*3<1}(s#qlJ*`lr_-|3FZ5 zX|tNC-@&&#Bqq7JXkCzPw8t0WSesrlLSK8wlVPiJeQ>eI8)e9<829+NcGW(*{ZMtW z@)_FQCi&-8KIT1PT65musMKIYIv1T)7~TA`K1Yi z36ukq`Uh~+k2*sIy>p-CdYxCfl`eBRl4zfcdi8ycpuyKL9m@JAWBsaE`LI{{2E|^X zn6{=&@1oJ^>nO4wOO7;`mEFAMeuiam8K$>F*}MD;_@`Mg{Tcmvk-H}Zh#o)02PBVG zDRo|@>Yw*2+0r>3`kF!T^z=8Nc0C{YX+D}k$@)jadC&dG@f9*8DONgXwDn!nhUW)e zy}wtD8C`_f`HKoqY^e>hurx>Uq~a;s!@B zeW<}{oej+!r_3J7mGr1D>(|Enx$IoTYtFs^wb|H!`<`rhzk7xNgr55>Gw@BER~p>o zY33hsukN85@BBxg)cT!t=b|@3uq9cWs{*77ql-33BpjKcy@MkU3XX0J>EU?p%dkOh zi{U}KAuREkjCA@^6E8{^;F@ zh_{ryt)COSy&KlTo4ht9`lBqg^rlz&ajr2wQF5~^|30Fd?fmbthtK1Dh^&i=2^AW>xuAMKjK4-@({xecWri1G)eSFsbaXxTNOndvt!E@-j9pRww!B z1me_|C`aa9KGs`ykm!hQ`}m)5Xg);1j(K;HrnTt~ylTvQ0_=SjID$jSu1<5qNO4Ni zY$v32Du6;NW>=I08ahJo$ftE&!)zT|p_7Z~2*$A6Q3++lDeYZQvgTkJYI7@6_E9|O zI*bEF_9N>r_Av@Y%B5Pw%j~C$A_fBa=bwSOdc zJt6x=>myk6Lu@&>*8kyfX<5Uy-8wFvW&^wGXIBjOT7N{jSZ2nr`%(=X+MZqX>aJ%K z4O?Sr9wa#8I+mIE2M&LHOp16T;fXbVlk7$O{0mR1_3m1i^zPbvjz6LtO)!neaA%5@ z6Mw{V5GtgOSONZq^RIY?iw5p$dNtjfYFNiv-woZdbnzbwZFtMSgJ5ST@qfu)ZCQUf zn!|-ob%DN*%y{{6oDBg_6( zQVHFVN%ZY{I-MY$^UkJwv;Rgv2F;&Aes*9hZBz3b#t;j7Wt@Cm$<7?>^Ibz^wwjVWnR zH7#1&*ZdL8PjSu6%UlisSD=m`&;GP_4kIR+ede^hpQ~K0NJ&gJyh=u8#Kj&KO8L7- zIZCjJ=8yob+JNp-<>@Y4LyuJj1cU=j>iRx&%EZ0N?a>dsDSwYeyBD2>#eG<^VTX=f zG6l41ZGzR?2xfZmwNv~NMOMtBziun6k!MnDbFEB7 zIdI5py8_4rasV(Ji_Yj7>EvPI(PYz>q1VI!dL4+&lJN(j4}mD}y8omip{tqSM8h=v zhKJ>rIFJ7s44Bp)uujCPx|8XxHA9cYxT;%8Q2dca7UpU57i5rjYG^FITM_c{D7xg7 z%@!!XX%QJWHEi+g)H||2h=pB8+D&`~9SdHIi4#U%k43jN-CyX%dD)X`y1>5#;i^1@ zM>|)2f;re9!W4MXAhE_7tJ>nA%uK8R(ungGMjp$_f1E|9`y;%Xv^3DN;Q+lQ9z`*m z@(?+}W6{lv(72Q-z>UXrgS{WrFU4%_oBafW{Auln&kf1xSxfw$@gsWsj)MidH{X`=Dh|MtO%uhzhv$HN-YzvNkwlJM;;FYG+p*&N|E2tNE zHJz@}tLvV#2W~p84qvLEP$*Kf>9pS6j85@MemW_~9@A+&&#t(-CR1F&$S!P%+q@kdl6T+cExgDhh75k;b4v^2FisQ5SGIpG<-Ldc-=R0{@@SSbnD3Y7|UQ8zxl4_Jl z7=9Cb1VV2&)>6si`=dpXrm2-~x9Mv!IN?Y7USh6<5knttk$^&nhZ&fkp;-gD*HpAHA2$OocQf7FlE&t^Ih_QTfZR>^l)u8;6xGDok?AtN{}645vup0Sew z=I~l83R~ewWI{*uO)l16oPhe|YO3)sCdJX;W4oT>WTrR*Ob5|2#n1L9{w`Uyl_Hg# zl923pd5AP+HrG7F-i{lJu>#6Qf3)9X_JotUG5uW67&kt(Wtow2B<6CR6{eGOotuTW zET=VVHIdhn(dXxW2c(gF`NU0lNifOENEluDxGhs&grro0l^GbgV>WwB%-4kH;s&up zuadVHvD;TArW1a-SzUe2a3_vS)5D^e~5)&@e^i2z@+TboLZF$ZGNAZaOF; zG|tK~KX-Gj|AKFCmB6myMEjpR#qiW}&wpjO^+3IsC0=&&(Nv=m82yFtqVxnVz)Nn6 z6%aI2ofx0&dqH%Eelyd`V}4v(Yso#ui;Jo{c%ioAnPZWH47Zhr?o>J!*Xv2i&k@C~HbHkGDgr;F+QJ4dz&{@b2nh3Dq}+F~WAM zQNsj2@J_9XKH~Wo!-BLJC%^%wT+>svbI7OwW$&}vv3C8^X|x0HYYCqCP?m$kTq@lz zGf2qtM@_KB`w=(N(Zda7Qa~AbkwNSE-N6%2NL4?;QewVGo2a!!gtCUc-~S z&qz!xpGgl1h#Ah7~imnCcJ9K5~2bC0A2Beme3Q;FN$Wqm10wd6r<| zu3jb|TR!PAGINx$^B5vnxc)u#}cc?L`{4iIwl5fG7v@#u@* z@~1Y}yzBMaaTY;;9<{dn`k`L%Wg< zkKoWk+u%r0UZpoCAi>q@s2|Q{?nR{18D^#$UPBhIX7JAH3$FQEGX@@Na7YBOgw;g| zn2l_s%b^WYQ?! z8MxhDxWlqd28t=}B?E0V7~sPI1ObJZ3U2B}JpBc9)i%76GB#6NMwSch3KiRV3R2lm z?Ch02ZO{S&jSRcWpKzGeog0IaVVdf87~s4d89^;!2Vqga=Pl#x6ree%W!FO14rf7E ziSda9!;_fok64|npe8dN1&u&x_T6$qZ9MZWt#6kVFRw{|6LszD)G%$P@KVgisj}i5 zH2TGV$UcRa65-woE;OZH6uB!b!X|~NlP+p@YrG1a#G_-PLnhdE@jvwwo+z$O|2Ily z)AngMg*5kAFSie>bJGb{8BQn7Fh|r}%;E9saF$K}qV@Ff9GPc^XFrQ{6?x*65Rh>^ z6r|^GcqK<0@QO9SP?I@C?SsIvur7|A51-#L~1hD6K9G#es5Wof~&t! zn6}y9f_rVGjgTL9`3%iIP8Ut@#HIFCIyn={BJcNGoG*P-MKf*JM!F``g`O|u$BVa! z-eckMU5xd}INOrYW5_rb-7^0YjXnv?*nr`kxX#p29uVR5n)8HT)Xho*YUoSyptB@U zcO%oKo@3{xKhD30-|;SHF=aa2jK-|JVkJ5#XR~$lz?KTARt>RIe@k0?%)6;QdmC#U z@MTenM%a2KYHD~qB$}G49jW~EM=69Rp6L@!*icM08h~r(xPFagVHe+qCUjypc%Nf# zxrkz%SBTA5Yc~_m8;yyQ0#$;y8WBuXHnfQcy5u`FA;J_<7~kZxv7!siuhPlZejO~{ zAAO!(OZ8m!eLGNFJ;{ECUhxIYbzFP)#l8Lc{d~_8+<`sN)UC#z#28N(J4rvu(s<~9 z#Q&Q+@S?Pw7R~=SHYnL#aFUGXv7973H#sNCYT#hL%1JVeS3fuc`(Q`ToaO~?kBwf- zI`yyZeRUJk%MOYO-TWbl*6|p3PIhrC8!4vvoJ|X_Nj4N$xZ-htI@aCswqsm-M4TA0 zt%9*Cl#se5z4!}a>9=L&rCQ)A9dbb7dEyL(`NzmU0vV-JQ#-iyxpEv&q-n7idS0u0OAFRCvzmyGPdb=dTu{rZzVkG6@AaO)B|+7L}> zkq4S6_@p0#632fajnsq$@jMeD1UysC&0q@HMF>ansz3Cfwv(Eos@qPeti>IQ z)Xl@6JyipkUs)QPpWV(Ks*yZAH@hDWXZJcr@`m0vIYxt%HWo(mI-Y4HKf^OM5e}F} z@(NxRMp9S+MQ$X2&JAAFa7w?}zyI*7FY}>xGXzhc?MC$%`BD9v;wf`}M7Pn4938p& zm0H$o4!qob!CO4of2WbfN0ZF??^X>Q*_>ljV|w?leq(x8IHs;P}q5Gpo(pYY*HL6MS#`duHfQEJ9C4Nv+2J zV>$73pUAXnXx!n84^)&{kp-M3&@>g3xwWF42Q?_C+$^ma%MBMdRaCo+TPvn=;S3y? zA*%IvrDDcQE2csyDTL$oMlgI~ze_8$C%dKhKsNAEP+iaity`$T{a@4gbLP4t15%lv zHQR0JdGEJjIo?$9bDnZ!>zW!K$1|R-4@tK{c?S|+;sDn{o2I zGw(lNRq|qjqJ`KybbYHewq~*`2bKNfy|yBrYKbt|apyPG(*5U8n>LLtnd$aiOUd*H zmWx@c(jAnH5sryM5n$`}jJT0)V#gOBMG=m%U7WLx=lxM;xT6 zOigBp6buJt`!H&Xb@U#+>vdu{kHdrJv|RmaCZ^JNn%=O590Wgi4v8v)FS}DHncHbY z?^jbU3Px|TgU!hoCoQj0ile>}Nk+T$hy!P*%|zhn8>2Cv;fB1aqK}HwJpOq_Gle^{ z;ESwu{;1(PMqp0MOPpR>)vfd4Qk?)U`$UJuqST)Iu0+PIwsM5BI8RtGpl+>br=}E? z^GbL>+Mgx^32M8UM9ma#nILm!J6B$7($jbL*hXA*>5p!H2M(4a2@REo zo*|vD=g!t`HA?PBF6d_>evMx+^Ve`#(o;aWkhu{MlgUklur`5XBm~5o6V!f8|5gXq zOvP_d9iYAXb{p|qs-OFQ^^?X+>##Xsz2siick*SvQ+rjv!&Sdn)&Iw@G@V>uBu!SJ z+_vD8s?j(<0kFvie65aY7#PTc*cwf~RC+-|ezuZ@)Wi8%`2PN$`D!Yyu*$Y(ny5|x zlK@v7cp4r4$2dP1lW;46PhIf5skjQ{XT^+GGrP9Nb_KDH51_nTD^~CXraS2js!n%d z&u`-a3^74%tGVR=qK@F`2y*jrY8}R)6P~`-rdwnakWZilKkxEGBdT`S>*@bT+`GU@ zUDx~n3@nPa+jmzXH8J$PQCWGC%F+sJFX%2{vOwvA9!0I35w-PlVnu}i^Y#9Gzq7ks>~{M7eaO!D^7(!) z@6Y@5zJK1IF6h9veSCs0LSt2%Nkm4l?Y7J|5Z*63e&Oy&RoBnis5S(BE|@F2*T;iw zX{L__&>C6Tcf6Nu`*iC&xTb+38eqf8*C_(FxFwwg5!!YS(`^HfsE5u<342fBD%BC_dxZ%pwDFMAtbB+m$nqvcttNL!uHiA9+< z#_Vq!0i;lPdQ?q(t-UdwD|t8p#I8PSBnWL3rEv_wEZTW6I&bA!!J zk+-6cF48fPCl=7;_5ga-z4Im@rIN~!hD5X+NL#}X=br?UpG}omgEQ+u9y+!Bc7B;D zJ%$USx;X0ZD{u5N>wx%CC9ks|PGX+9k4E*omfy_FTrA*KJp0oH+*d)%?lEGevlV2_ z>EbE;a&}Z%<{-{^9@McM-$XOr=!3ifsAM#PcFZJ{Wif6{m^7cZ>QlR~kNSoOpH)kB$=9Bt9#SNXvOJk+b}fC&7ayQ=nW&#_Tz*@M&;PdzD;XYlwp zxt$V_bbeW!ZqL*&_Z!uh%tLxKJ9yL@6ln_XHw5=Hg8M#xP2XcdAFEZJ{57_;D@csB z%&HaTP+eaA!(Kg3g=H1`(gG(v?8T}c+RBFnpz^0(=U^3oSLTR`398Wr2(+rg+7}Cn zFMJUW4|7d$p@_V=mQxLi2^LbTnrbx=d!iBMR(50h8n(emTfEvWRWE%J%N!pOvQBf2 z=(Om2h*u%{Ih*QD+0dxs?^;$DiS8leI5GhB>(aHByneN4Gn)mB zDWJ91T0F$5+Ni;yyP`=&W?jI|3rgoS zpiFO_Vik)m-o{ZU&`m^W0CftyWWeWS0mHjH7_V&0YKF>s`IQ+-d|4}81c1SX_Xp)jJCh;uDQ-3Jn@^4y0mfvz|j)Q=LP7WeT_IV>SaliC&r9G<@G z9W|}x=cA6*dM&p?uvGmNy(@*cE?-C175M0%F+kp9lAi6ypUuRx>*1aXX;d<|ON}yf zyVNHxLe;4U5ah9sNBJXhauo%BLk%&bpmv0=E#RM%ZFt5gZY@ua(H^fQg_x z9e{8r5)X`7Y`U8g0y>^sUdpbP1PiEOPvzZgsc;Lz zs?zWv0{CyRcdUvS8YitFzGw-op$zBTphrg*?%@D*%;1|4WZL4X$2g1#G=37h6ei<% zWDDe|l%pxMV(-BCi|MPrRpzzDn&F@i`ESt(f(s#N5?k^yZdYo;MJb}0*Q1$zwN)M2 zaVU1IIAp-us$G$;ZGBPXj%6+C3+qGFLZ9J6b`04c;K`MG ze5s64asHIXiQ_M;(H}d_<4RrW%QBTKyYy9rG&UkXHzGltQ%4u^K_ zu6B&YTmEI<#RKC7By2Wrw7dR5-GJATwR#Ctqi)wTxFB@#s@bA-<%Jew9TNv-kTu-+ny-MrT=3YBf=c|=A%D}e~e~J?jpmIAT z9C($#VdupoJfu*=W)R}~cW_m9ZOeWpPFEFnJX@pHRaOrWm~GN9uV&wCta=xjxNr(# zs_|N`gG}Xr#$Dj@VJAyjB)Rv=fhWG9JCSe~$@2geVZIu`?Oz5#d6}h_r)y;=h4JgomDw z1^6ODhGw>YW-dCcA}?#I*HEBe%+KV?6OOAJX(>{8Fi!E#6O3S)};M#wrafUU3* zw7#O8j6Nz^qmq?Yy?UODbVBr^%Rmr>io6Z1cQF#nA(21xct?Rm@|C$pnM&-~~C zuZrzdRdXv8tOMAj^e>k1lt|&Z=NEcWdOZJzKm4?;s-<&^NQmH7K9%s|tvWAMBf|z! zTa(CipuIzN{-8%3BFEO6SH1dfubwc5hDSKSKDb)=+R#}arl#vgAieUc-5WFfCMutE zZu2>bPAC+srSrTI`t>Tc*ULIrN#{0ocwa0vtuQ8d_q!+&j;b# zB(xL555#ZA(>#t>yS>Us)w62!fJPE@*nY8TySeDq;~KeB-p)U8x$zmg*T5Es241^2 z+U=#CJiD!|Ug1<~h!=BP_D;T_!bbMsG?L%Bk!?AuWt!I6v?;}u>)@a5V?q+;gNsI3 zE-ae1$m#L)7ggf?{?0ZEE^%6E!~?4Ou7(b%uhyBXwaJYJr@clgb*OAk(0Mwp{^U1; z_Q8JGU{8v3{e<@BCLtf`k}Rw%o0bTw&@Y93xmQ1xJj~7zmb0WwMR?8R8*s#}OAGvr zbL)%|ToCf00@-q;7Nnipa-Q8@v7Tq_AtF``Uecpx6g4{}dm?s$$GPS85R9FoGl9%e z!y{>zE5+)2eeFzuaL#SJMItUAC+W!QoSi)(yiRxXh?RlnTw7UP>aDo$ zSoP~fiy6O$YeG*9vEeKgswcf&(Xp)}Ss1U{&3%GO$0@3DI^9KWiM=R_!S>!~vFoyJ zP)cKru8OtA`L(6!F0N*t%GTN2T;^+66!vd)Jc*(0PCln&<+1EA(6k3!e4m3!sk+PU z)vehPneNPvsxE*Mt411_+*;K^M+BI7s)O9g+-#s%$<$-0N|FF&E3;9vSU_Qe#8E2)_b&XR-g@6&I1!@ItoQ%C&S^>US8?Ll%fgGSc_aRn`o915NC% ztEo%t5--4w2Cd{Z4wFHoE1&q3L$0XqMO1}e(D7pDzUu%+&9?0H61=`+ChT+n(7-xQs0ejS_ks4jyqL|34s< zU-C!&h?Y~(RU&oBAHF?!UY^_iezLRCt^_OT4cHd?^ab*TRSmoQ9)+p$dizGwj|)y{ z3hLBX<@$u+f#H_~6~}pLy^Zw5hdD0|C2Dx;W|YVf>sPLvjLZRy7xoRCKL-24{+M5L zz&z9h@_ZXL*$xyqub7J=o#&P62L%(|x%pWZ==`_)aiY$;*<=NxJw((p32{4%Zc{PX zEL$Zl<~%SKKZawy$Jxg_KLn#p{b$(;XkV$^g+vTe(TEvo~#$DoKEmz6mRrOSzUq4EDKo2G( z+X&rY1r#s0Q0Qa4mXA=RF4BWI?>^^S!c8t=!*4wVT!EzQ1oj%XSoxE$@#eG5IrcCe z8=|pzrS5`$?7$~x6YVEI5{Z-iK+#pu;?kn5{*Jtbn#4jLQO#<_8{6$Ip7&Nr>zGz= z=`1cNH;snIcHK~3%R?I5d`--o-{xJsjo}Y!P_q2Z?=X6J`Al*mXNH<$_D85byt(Bz z-q7Qh4EEmF+Pv7dC95ia$;2QcXjKK1fkkck_u#kwY_ga}?XaHV@yE1AH<%ekGKggG zn12Hn*V|32_NNVvR@260o-497wIh*f!*ccz8}$;AZ5Lp$UhXaZF>vKPLHgUF14Bc1~6}hD1HER1rH1f*x`7l+4iJ?syqw+;8W}k z`t+kN3US`pWNMv@4uw{<@&ZV#b36n3+06rj-D^;>I*S%_!(D;<%IMNWT{5~j(V^0b z4zRsYXu#;QmLfcHlEPs|mm~aP%WG{4nb=YJuY0=&~e z=*b6(frK=58v(eOO%_11Xb}VHrA9&`4+3ZSNR+*$?@U%bU6(?}e=dP75lRvw-W!H^ zd-)sB-oJqF1bJrRei7MV(6P+c>a92Ouy!VPts44~#dk9ItqV5Tn#1EW0c*Dwq-}2X zzS{1^M4{%7XnD*_pT%6@MNyw3^FK<>Mn+PORY6%=4BQ~&hXrcIaR*Z&4rVi;K)ABA z)IP@mzH|srf*I963b};~z>EUpA~%xk*3+h5l;=KhOM&Cc)}Stgfr4gmn8N_4I!mf2gIc`=#&?=Gur z^b(!7lD4juR>PqPcBs>ScS2UvtrYPlJu1OKs80;Si-;@N%H`b;2n>M^6;*78ifJyU z@VVBp#4BUf;^;OXA-k`E-7o!}o6<@+g8-~E?LM0zK9z2;y}pkShE`P)N+y~_n*hJ$ zV*3;mg*sHuc~DmjIm1CVJ`AmtuSmTKxjG&4h41Z7Rbz9b7!I%H+qA|#J2EA(mTR9$ zdM#yY{p%vxi38^7Mx1|{uJPMrRlWUl6UF+t;uBWI21iCxjDs$TfbBcK=m`=AK{o$?DsO!qy4=;3))OHYsDfy_?4qb#*g{h=)Fn4oT zTrp&r!~4N=ccRUm0!3x4`Ieh995I@*2AeYBExMX^P%OC{oyg5pcXaQoQBD|90Ptt@ z6|>VrNoNSCOFa*mkEO#g0z|a5;{Jr)+vS=^hbn+QJ8uTIfo}C(lay%t1J2pI+}yd< z!xXp2_j1xqdtHhn<=U|xG$s7eD`T0bYcs#yb5aZ|69e1zdL!x|FKRR|+D zSrZGBg=71O6J?8Y&^+}o#6j!N&D%;E*ZgSJjbyBDu7+OlSFN=tx9J1iwQj9Fuuy{ap75=&xc=2)5AKp?>tKZjGHA^t=1%dw-aghVTd zM3VBL3%(6^+LK!r6yrEH$!Y6=kPD< zGfZ4F)NWHyZ9w1X)(yPY8)nNbCcd^MsE4AO;Y^8Osz-WW!}a>$8ZYti_XU-d=bHXw z=#Zcw5kt5JdShN)Z;a)n{>3nP%RG_);-3ciV~`<8sZ@^-L(0J>#9fIBqtPbndw8I9 zLjl7oHqVYp++O{$}V3y-nF1~R*Cr66L z5RM0+n>yr%6$n1uFq;9F;$|FUTB9nt*4%|aDbG#5d4v>TAqQO}<#U-F`l_*(vrSqQ z9F7bf#k_#bL>`JA98SnU$t+ZSo3~W?K)tliSFas^Fu#aoZTQ0wY1-yUD`L<8K&{Bd z4oIJQ41EUeYRe7(5~wsgQ3~gGM7@i*97%~HaLPJt$`kVVmjaCmZE3T2^ZgnZDkEr~ z8Jh2XN&LwHG=!WmDun3g9u^iFppODjP4Yhi(Ki+VQMcT1S+?lx2LWdvM@Kn-Q7qG; z2QOoP^-hnO+@yI8dd2k0co0sWUvmF%z=6UDn80x69VR3DhP?%q9g679(Wkso9duvC z(25|Zwt+;oWQXMM?xkBC$kzfOU4Q*)!%PR!^hyIskYXMP214mU+AbCLB0Wy=op`fK1__t5__yq}*x5Z*%% zf%mzPk_U-iWmuMsH~%>%;68vc#B4746QL9kQ3+f7JTT0G;OricQ5c1q3}5!W(7e8nRY9(TXdG5~C&>{J)EU~0N zp^>L7ChLXvuleh2^_zbYgflwmpL2!2&E6`)lH0Y_Y{a)?Qzx4#$#=Yh_M^bFS%)xgKNz| z5ay1@G!pa>A!}y;r$OCn%Ic;5B$%#p)g>u4c9#>Y6^H%%`Kb~mAAwt z+2I@uzhpdhnimBR3JwH3C+0@zQl)!2>CpvS<-UK*-{L$;-rVmzdHlijkld&FoQ{?M zpEyrmL7?iTe~S9DQ4eySpo(@%4K-IYXO8oKD>Oo87FS%1+lD7E3#OP>4b@H(8sI?b zWk0BDDL7E_I8bnmEOr8LfJuisQ50T^WZ;+dKH%1hupl0{q#%Lo#Bg`+O$DnB^I218 z2j4h)6M8Y;++Py@%qPEpaXK3yuQ(mzdZM&k+@5;hR>qIRAKu^bYc5NP!N7gVKzB$3BG~2mUP;+ zr~-tpJhx$v(C5}Anki%&=N};?wMNSn$>nT*z2&n{;12lCF0}WObsP#pE3u&ZnYtaY_!ihmOiR$8IJ@6y17^*nIX&nM_cFpk^_Z{r!JRuK$aUii^)n(Yn< zpL34MPctFmPd(gE6U2iMJJ)$scg?9saMzH@ay7j{&v&*J=P(F7H|DDON(VELMvSk2 zF7((0o*G!8;6(;&7PuY68mOKHzYTIhAC>pVtC{=eRDE;=_l?C?40PYfTzv%h4c?UE z6=)ut=HS2iDrExyjeSo)|6%{l2Lk`i+y1iurZ@E8Jo|U}Z{{0G9_YXML*T!eUW$%( zWdDs*Pm!zzd-S&D-^I1!&t#{ebJfTSlLP3Qyy1_xVXDE^Q1IQ%KRD2Rv+@Z3n+t8j z!O|iPEPVjz60@`HEZQizZ)^vy2!}DZH*?=;rWR|ayrs{W8U26sSN@w5G59+FP4(;E z3ZdYexNkJEiW8Lk=B&VdV@Pm_|3+>$0^j}$2abImcyQ=II*#?l`t^_;IIl!AeLP+M zA3O~Jt+QCuV}!WKBQerHIRA}5KXl*xn3)r#`n@*~@kIUx_(ghwCIl}|vejh9zuj|l z3)A5|HyKULU+K9ae2Ip|r&{^N=oajm2>k};x#|5Ud2XD35qNJL*8WBB&BOEOBvSxa z-kV8>dvBPwqQ#7+m(lpKV+!t@R}OLCfG{E6UCD%c>3aSK+ei>?iWYG#9?(ge9R7=C z97|pAYMC!N5aJR++Pp^ zj^@7k{1*y>z(3!8b6fi%?wbpU5TN%3_s!1?+y(c|PsPx(A419!#b6~ZSw{h+C_xDK z%`1c4HyhDXmrbHzGIf`I(C@yP@cRvL_>76#k|>1-Y&M9q@#??19D?H}nR)KWz8j9d zd4HPEYcqdLX1{H6n?KlvgOG{~$BgfJ)@&;ka!7~-3{y{?3upS@;=&P=ALPPuN+Mhz zL1Osn^hQEMzYFKN+z-YEW@WGd#a4YV2?uZh;erci_b&wpGb^L8=9+K7g>xh~!0Ax1 zKs9mm<6Jl^sgC<2xNtrZLE{jyTXG4c+W7=_NB902JA|F0dxd@J$VejfAc0h}p^3>O zENAL*zE4`D4#(E!kYQpJa<*ip~%t-~`Ext88I2iw5&afY_IX=k#Up~NJ6WIT2 zLWd1NGOceG)?&Zpsb9!pBd|D!jYKei)R%Y~UHHOZ?XU@qr&8vb8?>N;Jc>Ly{L|EC zbC!#YDL4RLldN8lX`xSn8T=y@F2tmk=e9OGoQzrslP_`_oUUG=wm)T9m3?TMPKG6W_GlYZDYcUC|MrO+8 zq%prt$F~Z88D_wUNk}|K-KaYJk}vRs<6~T)VVH#pf9fxsFZ$pt@*rG=LVYWL6R8;+yWP$^SSW(MJJ zv%@-B=~GlksC8)wgS0Mn7R}FfRt$dt{dGc_c5mBiRaXXdYh3OoR$0)HwneLua}yE3 zm3%qy5+Q%rJqUmvr|$gn7Y`mhf`bTQWHjo^;SQn`0teAP^QA1H3K~4Be<%V-LN7p)*O|InZFuN>JwWW5>aA9~{_ z-~g0t3R7WZAe?z&0X+0?_79z{9v;;{Gzp_99wDhU9}FBqdx5E3MrHavoluN|Z|KE- z-;ne$ZG2efoI{evSO5R(9QysO1x+r$+Q9Gpu`JzjqOlGO4uiM<lNfC@Gsp4=Y17hZ@nhyxmD7#EO2_-5|C zq`l3rd;y=|%0b?!Z{nW1PnhMrQ8A`G^hP~l-YBHNjq*n6D7O4vxTIE^JLAECk~-a!4ToO3cXq)R@f?98#RBN1+-4FXUVT>I|68=cr%L2Qn~|`1P>j)I4*<-G@#qRjq^olorM zP4h*)8#AH!W1NE8T2jNW<%^PdwN792&}zv#&pml={~NWWkT2>j!cVj3C$sBphp$9X z@W7>;BJR-AHYv?gt*!RT!}3KTJ1#jaU)1w=r3?9@T0ikI@+}ot9G)<$F7tGB1MtKU z^v}u|m7*iHUXp{84$T;KId52p`)NLR8eRP7WQ>wkSZkaFr9sB1-`k`P%orsRH^>;( zq>NGeM$4f;W7Ld8GDb~N7AYMCMam2c9wA$lrZFC*j6!bS$Vg4?bvdK1`hj$fH_aKf z+q!wXWla$d%%I5zg|h9p7gBtX&V_KMDD@{AFylz0#DB=38qt!??dcMa`P)-QjdR{q zjZzg>x|C7=_n|QTm|I90mCqaroSg;)YyTo4z8Js zf3H@EQ~h3=^XEVQcchH^EngM}by)SiuKHV4{b#9uV9KbkyOdE;uXbZ1waZ*dvFv-4 z2#RU{Ed$1nRF@(0+wFD6QM|)tkV<3_Al6yZ8s(45&YNQ1i_g*s&TbJ9{)e)p7w|*k zDD4JX!y_e-s#Pwjy*ntkHYkT)aL#3XYH6hgCXyo66RDs6-)4*Ar1rlvT~w@^l-8fc z;qJ9Og)J`X$CTRK?TshhIqvs2%^0wU7=Je03?NK^X>Zsbx zQ<=Xyb<`X5mL7_hg_}8FWl{>Mqejq>bXPr$WsaOW>U%-zsBa#cI?CmU(cT_hPLETA zJlo~`X5SHJ#tSpxWp=UN7w{_B>aWyMciF}TmpaN(9PRCoTIwjt&__)jHEU4nD3{Gn zrc04isa(Bkhx>8C@11)7rm3Td2{>x%sFQW1kHzvAT=G5I;xU4xu0<^v~phea09X3%}=xn!>@ay>{0g+)KJJUlGz<2eUvjt z(^4NJ8Js>!`A7cI^idyxn#MAJBw&1S0x4yE5Qg#7pFk?dof1ezt2cVf9-#Y))Z?-t zi-yDx%OIsBoc$T3l78$CmqF@J>&z%sI_fzt!VFT0Dy*999KrS7MQzF;B~eMpM+T`6 zL5n7Qm*VU)i$^d>&YMz4uH7JmRMnOQ3B(eaM|HX%5i^HnkZMx@;B_1Io7pNa?u_73 zt3B#ZGPNPNpB=pKXGQ>Z&8pQf?1?2Tn6e0s2|HSY>NrCF zsL#~M7a(R(z^o7l2PKf=@G)sQOH>W8dS1W5@*k8y>bx*Flmvz~Ds{93Qo^Bl;1wm| z3VQ;Nls_t#c}7&FRhVWer0%lFKt0pqRSKzVkD5YC!O!ZcrH~?jO^`cExpGniaz}|+ z<|uZg#8Hg-WL`le!nAgQbC9_;TJ#Sjj@tcA%npA!ag;k3T9jiZ#ASvqW^mD@izbm9 zU0|0e@;E|L*S4~>HU{U9s?-x^rG{UvOPfoIS85@a+sl56Ri67ZYoF4)c~Kxs%S=qT zk4JxP0;$hJvqJeSTPkk5{L5yj7?44VG0bN6|0(&S*8Yw8qr{|;X3c&f5KFt~4y%QO zb38ZcK@2;8A%9c~BTIig4&aqQcS!!IyD?OPU6Lf3jEMp>G@VOvU1&QF+DQ*96{IDQ zI)TJ4p*%r-;w4APAN4lCYul9junK9-Y87f3F_|m5tm=rT$RBkv$)kFecEBZ%vQ68Y zSgcQw@c(bfAN36yL3#=EN1e;<%24#I%{&9y_&f7QT{29(<@}*k;_^quIOu1^Zn8Ah zr5*|sNa2$9$RG7qj$H8i{-5QKN~AVwgAnPX7Lz_|s-=&*WN`W@sM$Y|K8o0Dk??89OdJk7t3+0RQ~!C&}z)E2K2 zNUh?5vlmuz{sL5%G-@P{s@kHfa>XGTkzW(@Q=m#$oNVg@6Gy?^O>Ln;=!^_21CvHU zc#Q!0C4ahIeA(rY`d|Y&q`+|ZD$FItCPOL-vl9`m*s4#Q*>L2scA^Ki9Cd+Q4fZOj zMY-)wGDBHLIQo?PX8QqzD$;P!LT%)kkdPT#T5hP?>c_q1Z)gmxDp5qbr*Q|lq2}N- z0BRC2E}&_WLn%Mqk@7?7_|4M##V$RRrhoL}zcM+LP9!h8c2OZYlsI7{6?tVN7sr`L zGDCem%nbEhm>Fs|-qQTzhh~QQ#ZfXt#WLmj+jytZt~gVlezTAoYBlsCBojKo7y z^G3L!cpFe`sd$LK=}6a2Ej8U978E%f-UiI0x$!Xmhe9Qs=nrxz!Ur ze~LX}t0pRVN*2uiFM`LK*z%8{2Z32bKEi25N+DT^E!8BrA8{N(Vutfl`iyE znF^I%Np8JX{)uaQMw!zw)_Z}h@hlc8CFW=Us*k%=sDAG#&@6CLy zz4RJ{k>G6ytNLR8=o=Z>bUq-JdaZx)ff&Q>riec`a?ro%0Nc8O$2uNlx-Rr%r@kQ@ zAf@>fc#UMt(Y@M$st_;s0tN3L@pDYoEN@)CF!5}Qz~a3f;5zScZ6ELrbZMqk$M7?6P5Mo$q=gy zPNbf+mx&IWY}Mo@TiPOt823KOkeaL(jQ-9Ps{K6zqP|$KVt(w#VPPzjfEV|RZq&=Q z?)rYpSYa6jkQv_K)haHb=nE(T`PW@E(i-U?giuqQQ8FlDz_G&$@*1}c%k2LraBQ;TA@1Z6?WogL zeHlGj&*k2HrkCRls@gH%^>JUl$`H(3{&{*%Lwe?4DCuB^u8M91Pt`a9`WiCNr|`q+ zPTtR2xtXn38>}sF#myrb1L03I07 zfAq1M+9moJflWKx1i`p}){1zlPYigbUQzFE{YE;a&wF!mQU& zKEXLMb^e*!a!CSQ<_Ahc_g2|86l^susO}!hQsx3BnJcZe%Mqq3P1s05pVw-NY7TD_5cTeN)6`#7N%%vHB!?x>4&5Qjb5 z-g!&ksqp0VX#G9CM!gKWiy$$y6Oe-KowfEWR24+;qn_x(&PW_vfMzQmfzGOZP?vD5 zwOq!S=01MCWuy5kTuk~`7ex^n(qBbaIo~fj7w_B@4Rm4@rb){E_Bh9ABS{cMjOm}R zYiOi=FPnQ72MBL+PlI3i*XX>mJx@HW^L?ZG~+@I?K`v3J>Ubl(^_n=>LGUKyQg)OWM zheC?P72L=RmhjKI&A$vz#O{pJW8x7UuMT+&7)}0%`xMauy+!0@D|z5c@)1q1 zD9_!!*xrQrUv`W;?l>Tkoo6^o6)Xbzxp8@^@$9^DJnZH&nHn3CS#QzQz-c*-7p#5Z zNS5OxXC1G_(Mm4}zXWVKo^yP4!b?7&Ji&H2Xh3K1de$%bEX3mc`e2Rc!yv_a=( zk(RRbQvHd)iax;ajOURXI>5VKFy(1GF$X>X8ByxWY3FfjDhVhXb6oG{AL$RuRJ`$V z{&jKFpdH%rR}IYiP;EH8lDMK=}BEf6t=+5CW-=?HP-{S)$pMU6Y- zm1g2TN+A`*9>{bCBgIO1Cl9?9Pq03yM`A_*B!spX!bxDZ*HBEer{eKUhs~3q+>h+V z$^#|v1#{w${22To@^Z|de$23he?d_^wO15XT?fTx12F8KNOAgv70Qp_a9|;s2!cHA zE*uhSQ=u<{(xqJQAwfdmZ&}zrEE#z%TK!wEC{c zn6y1s{iwI14G6^iD-W`}ij#%gqgDGjG@QKJiO9=*`)`PR4*j^9R*b!*hksrCYt;+k zA&Y7l)(42;2NP^~gGgySbyYoLC>*~^R=Uz5uUvpmxWG2?FJW#sYW7KGfiYOK4?Zx- zmK3#1Z%A}8t%Jg4#S|_bL77H!ULce!Y1RTm2fbV%5G1PGo4?*a!@t9Dr=B&?2h@bx z^b1}~9vTRIXT-86^D|Q!polSAv7N^;|I&m0c^Y_KYLEIpM13b~@0!{w*iPO+5Dt9@ z!`3`^sGxifGQ;=iH$rMY=8xOm++vtHBSA7>O6e9jEYKI4RxMtAQCGEt{D;}PD&*)v z&{^}hK!?JA5jt%^r+^aa7tr(utdh8(v~4UQb=Mj= z4AUVyizEyfqIpZ-z^&$`_wtvz?xe2T>IdczLzicj&fpe;HDFPU-_DZj<}vC=#0hQT zQhd-`_M}!}Ahy-lyrJfUz5-AovjJJZ)H;P<|LhydCxSMnp+!2QoD+??Pv>;1O>VVW zzDos7QWmucF&t4W&D5}%o!O9kyB0X&5q2BjW8FuA*z?YQ`=*yJp^s6QQW!|Hrdm$n zNvwJ^CxR*1A=Mi5n+RcQ)3LIg_j!>&`V`j1yC(bOw*YL%dt-jX@+7f(2U+a(q~aSY zlZZV2%7xr~ht=WLKY{Y{TQY02Xi!-Hha?T&(yjE?OK;*Y>|_4viOkl?e#ObjGd9>1 z)d6Kf_6eR%zrZ^=$O=pfZfC^WNsi;kKK| zTRrGiAWP5ZHFD>XUJL5;M~Qx|!8&FiFAD1AW?I{L%!>!TuadC8^M+%|A~VdZ?35pA zY@2uUS6H=)NDsNhHMT|C`B(ph_tiFU>`rg-=LC3^dL?+19nl-R#anz47kY3Wzf|A& z`|+E+G23OIs(;WvZ1)zwO@%9Wsn}cWI}&HULNE1T55E9k>6Q6MMrUu@4(?%I({_1d zpA38WBvjVRYJow*T;As`>eRyBJaUMUepbs5d={q4A|WJIhMe{MTF_7wY9DGn&+$Uq zF?vsRJ15#s?y7dNL*5FJkdXJ(r8erMIRwm=6b=O{*3eAdngeQ;W9gX=t(NW#b%39(3UIQ)5> zMAA;cw4H+rEW0^&Tv-mwMv8`CI>MOyG?@)JDIj?7mzlSG=F=DOB_rv{Yf{7Ul4vOZvjO*@+hh4vJfO)t=^w-n z1=E|iO z#Lhrc=U3CnR;%qW^6nU0|JQKutvG-Sf;l$%fVOLRs5zg=FR=c%5i$SF6S+Ux-A^m7 zOTEDK=3;)a9yjqA*3Xl!m|t`v5jL1|xNEJ8Y^kgI4by+BSl(`04pN_pw+VV`y|${m zE<>I*S0IoDN>wEx+*O?8Jn|Oo$8=+$G;k*f@mEU&6#k3+4rw6YhY#RxB5k6EK`%A`QYOGJJvrEVe`*>^aDS?2d~ zGQ5^kC>|<+uyphrJZFB%f26Us^{$oR;TogsM8Sh(yiD>^aOwh(Qc?m%uA0Ycq#Ri% z(Ba-e%&BUqq?^=0@*8RhRcfiWLJ5JCgBVPz_Db)vRzy_a?$`$qM&ESolA`M>&Zdr9 zum0&IJH#|`5H_8A{Tqp1BIS+b&Z!Sou5ab<5Gtf1$wq-3aFF;PAA<_xz&(5}Ko&MMI~ z@xGfMZ}ImCga#%uVX>U_4QkV*zWjRkT&n|qnCT=M@Qr+hV$7XRii3yeJT*1zj|Axx zydz~$Rvj%)tR%7$g!+Uv{g6U;nnDsGypWJE;)I_HE($ z8Dj8a9vt0*3?y&@ZLz@!Z@fd-A0;dWlRVENm)VmL+Q@j+*%^G;pPT{jz2wT%g-ms0==u+iLb5N~y_ zY<6wceRJmq?*zDBURJ#ZR+LT~!6{eRLv>t+_IE~J4$UF)y-$!I4k~k-Dfr3TP>`gT zr~}0-9q<%U66g*Nn0iqv`#gAOnqz!_oP^?CAwGGFP8-3T(Uk^u^W^knUdtso1f?UG zjT;pKZ#}1@e3YlzRgPU}cDSx45otiXA?p1W_FK<}?de!H&H#jth;v5vsr!9Gti4a7 z3}{Z{zWOeG*-l&eyZWEMOStTKh0_Y-bRz$G_H^)6qQU^C!D{K#=ngA>6@lMK32W6o zVzErYCBSszFdi_^>lSF9Tg|*x@-=Q06o3`&{x$l*0tEbX76;GEbMv-N1(JWY1$p_e z@&;#)XFv(n6pW*jC}y>qgm1#g^{kbqqLu@K0ku+q|M5QXM!hBF@wd1S=>e$Ps@Eao zob`?vR^J7DGIwN19yU08_wvuvKrHjrL8ASpk`n<#a6b3MmC5${oBxeBAQVc9EA>MWUIGSoJ1v zStr*bH>z1ft>Kp~ksrDdj^Lm3UVgAP2-Mp2e5VR2k7?#nSrsO7i{PLRD@7f(sAg$C z>Y0#Bhw66eS@ttcwVB7o`*PgMf&EBTkCf0}ZlmN)BAdKylQe`2W1HP(mKg|i))wfy zTUBP~H5l%WUX5FkU8ALpGC?vHQe$htkWcw*EJ<-I7unKiHHTQtlEa!Ep;(vFT|DO8 z)BZHYu)izkGfGfy22EfneBR8Z4T6S^1NUW<*x(dCUrPzOrpF~!?+3~(3Sy_0%DW;+e~cB@Bty<}#QLx(dQHb?iq zVmXR0If-7R$O5e)fnNbGyidLI&pA~Cak!xAEKD=Da?OvBfq=aNK5!g7nF-bzG}uIi z@_Jh$wL>m74MWPShQ(u>^LXk}n_RIvp+sTEDQ6H4XPC1XwAW_z>KIuN3mEVuGk+gr zwY}NnL^EyZ+0p1;^CtxnhX^Hx2%&kYRL8xv++>0Ttm9-^mkPiD4+MSn&XC|SQ3z;46}c2& zk^L#bcga-Xtm&WrGt?LVoYDLQ(_fc)gY%7X7m$|HO?)!b8BDy`eySswZOyWqy@9hl zo7L^M4C(VeAg^+U6~Qd468|jnTZb!rf9AagzC20{Gp`xlq8rq(AQg z=XYsRk-6ReLCrFOi#v$4I&_}XYk6mrqQW+h*7I=AnZon}iu5n+cg+DHl$}WQOYV=) z7uI$!dC7yq!6wVXN@t1h{DS)mN@3kq4duD-o<&mY!3%xi>#TE5^E#OS5!zOO#|7S> zm-;2KZE$2Nzf(y(do4TXQq)qdj|Sel+}*8C2rnS;o@y*t z{YgEIaV@`)grE82__j9lh<2B#a-?0MQ9eZ!4GqzZTC=9AcY4cDM=Q>!BoI0dCC6(= z+n&=S9W*c8+4g$Xldw`&$p}Ep>2+jj*-%l;bw6W0S$9s@r`%}nlx9{;_G@KsK@lz( zFj?cU|Ay5P!&RUiETDgh)JrU=EjNG(DaSJ*7otfp-uv~Gafk>a`^z&atQGf_5>0nz z@B;%T`)Qb$U*1YyoU9teA-%g_QWS=IDi7ms`ygPZJXfDXCo9@wgSM8$RX5r9HW*S} z!-w$6YMu0nlMsj8?#;L-j1;9eloy)7BupBdcG4&ILo?z_~?&X7$*pPZ=V`lQe> zgSDu(z#;m~;&z!VL?B^nle#f3S(5YAreH0y5@t}EGv$1CygF^7DTe7E={?XRQr833 z$jh9ah>dBLAxZ9o<6Zolz&5ZEYgMJz@B#t!UHUet=TxpmQ7Utz9$>3z2+PKbDHJ?` zm*E(sii{H}5}7w6yT%i;9(qP^Z{07Ir=0YCJDX`jM6pJtXbbw|uVug?eeI`KRMA8s zD^(LEaFjE6*65xW4faA7PWV#EA}U4K!V6Xpjq*n|bDw)ytOxMgM2h_(7)gEC#A#qe zE|*;FK3p$dOyiiMZD!?eH@lO7RAr4GpaEJ&jKatQB`#nh^hq;A&C?af>l7EdlAA?W ze)8Y41ewx3Rmo^8&{V9ANMHw@_P*AH6pk{8@dTEZX^SS9`;gMl=jEs$X zE|Axz!qt&ptIh;p6#8seZZu}{k0HnCULElv67P6TLlx$;tG?Uxt)K|{_eV_x{T$aVIZ1DjjCM8J&tnQuM;$a`MWb1 zreQ$tYwsto7kg;*5b71@x5|-6cSc92@e3#WiX{GxvhQ1Qz)I{nW3cQyhsWAWA)X5B zK*DW+=8IY@c*=UnTai>qcd7M0kYsr*iYh}5;)|nv&W@$}47*d0LfN1BPll{H=?yAf zuV0GTG%`nyPTw97Q8!o6;F(s;NkUpfGq{gsAZ_=UK^9Ie)}>x{S;^Cu(opDrA`_O_ z$DR`qoyO@Xj6fv-1n6RdE%T^R3f+vEQBNiJWG(_pb5=7Vmax#K$E)j(`WJyWmp6el z?tJJ+&~{gm{tb z-oVjLiTam@D?=nDTxaSyOJ%!J6uQfH7wDk%yTcxb*Xq??+}tn@ycG4bg~HIAWb^@C!Vd|u4WbCh5^jMrf7bng zKnJXwdSNxUh73fX0#Xf%`PDEHoz*nWsIwE-dR ziB|1^NQ%NwRPEuQ2hN!|a(RIihMg_YNirA^GH$HT@qiF)#v%cW)(TWPoD!QfbX{??*;WrTUA0-HThqg; z62)P_hNK`+VF21nqQxiF1TG3p5>O5uI#@Cch<$x6?M{Z=3qcy#Gpg08#(|xjE)ef{ zVTIyw5dRI=Cci>L*6~u&1u<#HE0~Cv!7PM70)p`rJt+r&azB33aw@_m2sYg(ln^>O zE!!_yf2|-Wlduq8Z|~GwhUeJCtoMrFJ7UGlI4^4>Pxx^i2AF>90G%Q@V5{X*zjqc@ zmtXwodT~|3R@NIDM#l1K$PJ+JCRhh#zgF?>{o1Ro0RP>4Kg~`j7y`s}4ILwuae>gM z9)+gcKm%bLe$q;D1MUz5z#($Cz{}*Qnf1I+WZ2i(&uDV`gwB|V?T!r_z#2sS2e5|E zsUdJi6Dt-mgWo+TWV%_CGob@A7iEu&W#1mF+Ln|>ocp>Ii9+U9j3e{BgR*or@daCG z0g(@91%+F>*c7Ujo~`*2QwikM1$-5-0eA;EAuupHV*&&sSi%dfRh>Yt6=~oIhL68C z?k7h?kl}BUhV2(G7mkThq(8-)n*MHah1&!2_jCbKtn)%2O$2gUJ%#z^5`J8JkdDgS z1wR*8aJ@}R{dHq3P=6o*ec2i1oW@|Sh{*I%r5X}A9b?d57h??C@(>agp*?|}jwor_ zmfJ}BmnvgXLUw`sFrGm5O|E)d+YNSY0{(aY!*K~EW}pQzh%fOd_uSL0D>}@=+RX}7 zN7X?sEH*=94l$*YC-@FeV!_Tfji!Gbv?#n_Gw)en7M*t-#4IfuNj#uV#{9TmKv7%R zp^4xD9gC#hEtrI5#fEK2uzybV{2WPNYp9AUg=kCNuXDF;Cb30y99x6oiBk zg^EH%lTX`pz5-7OXDr|gKhy4AGCfQe<&Afvh;TWpE8##2lE9<5v1$NeRpSIK4WGr!&BPI z19X;3$+xcoevHuwe}NN-H{?G1FO~#2PDdocitxnLHoqLOC01}ctRVl{CkR;Rw;{hrm5He zM==^ThFY3uGXL0Fg3s_=RfN{r{Osoj*uN~!tu-i8XeECwH3l1^4$F_Uk+8$x_r`B} zUW2FRanUTfknS;9U=CunH#cO*Wh2@ZCG53bQ6dP;e2-=Yb&+RoBcL6}vC@^gJvgVd z%0(sc%0;s}mwEbN^Hc?Lt5pSZyQ(XlrSOB?uL)nzo{l$nLNlM5tGS$F zUS%I{m2_4gup3S9FSqxlLkJxss%vbgx4L!wL88cNysvg1*Ey?LH?4f9dr=>Cf$$LX zKUm9{5B@i${+2wiAJ;oKWV0FL5Y3IFJF0u}RN{zr-0oz4>D2~{Ok&v6_Hh>3>)ztU z*dR$-`IxtK9#`?y6Zg>^eZ^wOFXJn7>4tRbK_~JL@4Q4uwrtReCfx#+K3uqut#Zez zB0n}8+sB#r+ZRYktz3+MEardWK-}ll5G0%$z_W+V2_2+A!s*4RPPgGG1+3mBBQNHv zJ_W<#JsmEKeS-+v$D1DxDYA4{Xe0FoPTBNYoLBT<{zo7}2gbJwXnRWfCY6z|Kqs%Rmr}RtjZu*3<4w2`jT)VopMwQKF zYjOPnK>3=t`1Vl(Ty0!HD?pGgYAI!_1yXf(VJ}&w%kXNMN9JU@ELv0wXdxrZHxl&| zbvVnHU1~Yg+~5uwKnQ8&fzFlLj%hpGX{Ab&ep3;Fuq7Gi&V)fX(-3$C}6)mnind-)1 z-G9Pc8s&OreBpzUdDA6N~@u%@LE0&;m_=i`BxKU^XIuev|LKdAzrC7)X8Z- z%Qq8T$BBQJ73pw|`?=AS7vIZ4)kCf0z~?I`s#Ok=Ude?)_#!GmY&PgV%0P?P^QTeZ zRFo0>JT&aZH{wyXvmmbLLi16WhiUBw_(=>Ez`v#GFu*I}R{(hS(grYBV3$ChyZ)0} zGQ)R#-1g+0$!r<)B>?L^vlV=yH8_I4P={OQM*M)q=zEQflU!QQ~*zk{0T6>W-xq3E5VBKw{OD?mThR#oO z`8k$ALJ)$4TvbDthKW)U??wO?Jr!I*GXjBqN4d9qOBZq_2;leQty&UQ7ddIh-6dJ@ zKC1JtWBXTggOLx#R|p#nkFL4nUwi8^W4PR_m zQcOnMQ$y?g(IYrcd;|n%XMFF@xWXzQuM=r{YN#VmjwAEg@oc_WBD%De>N0(a%wzc< za%E&kw%X=0?XG5sUg42?`ht9w>M8N$TIlr;TSywqaP$TWqL%TkSGmK5n>)H9AV5?G zQIdH^Nsi?W&>QoBw-gc$0vyNRSSIK4E3jX4dCZb=-~^-~X?&m`j_4*L2NIF}Pz;nY z5s_%-f2%ug{0+EOBbrcjFFhX-QV{kX7oF%%Q`gIpix<8QTP(w43#T1f0brl=mi~&A zWM29{{uTzD_bAfOuVCBD@3Azn!DOX6{To23RW_ZP)>id0^=D11rth@l8?`8~tn?)P zk+<@ag!XrL#rO8mBopRN8Bq7**!Y>en-YGF%`4MJ@LIg83;(*6YkPXACaaaQb^f(w z`euN{v@}O-n8Te z@T7=&-8g@a?Ob=Hs>MhZgyUCN3Pvpz3n;9QYQTvkTwbJ51O;L={J$tOkcc%w*lxD( z&~^$04P8zSi~kH>#QE?u`Veh;wrJH%{h6XVYxHNLQ>M8px7b~ER!rB(u19F1k*^!R zEAr(Mg-O2?B9h+oC}eDtVQ~k4nE^KzF5Z-gEp9Fa{^D5Iaser6z5c=h97|NjI9ALA z0D2g5tZ%9m^fJ_zcK@4+6lJDlpiZDf+Gn+>-k1AB@ob$;1l?qs2NO5U*_(;5>dlepw&!G z;&duu%~4-Pk(P`qQ3Jtu1M1tE`#g1o;#r*?LmRNj+|DLBMT4#k5cu*J2SomR#5soX z_EIkfk>T_gAm$>&FB0x6v=Jc_>22kA{GX%0WB?-ErKere;LZ!gfxtHP>|M^iLRc)~ zAy7&cB)a&*oNc^QO`^#Gc=EMFZ7%z+{{S=d*T{Fp>rKkIMmxpPqo>MX1gH=fpm3TS zspI8Z7*5n6B#OL&OjDp+c~@;b5Y1lBaNL97D@N0}+b=#zRvS#tM3x}dRop8PYx;`) zIBLk@=a+nl=B$1yCEA^ObH8p>eYHZYhZGCzk33cuAOE6*GWIiF7wunoFygg*7%>aW z)I@?YH0{OrIypSZ=u-4!qsYcA8#hw`=FQ(}$HFzvBXGHlKlYV)s#jXdlT{Wy;TVeq z-&4KHr@i_=@+M?1M4Ut2jH?*?c?d~v5QUSNx@Dl4dV(jY;vNEybe{tcrtUBtmxIQq z&%8U?U@T(5jkuWgMZnH=oOs0$!IpMiIWF+&@+$JE##D4~JS9=IEct62PLT;H8c{iA3UxtB3aUlQ>c3arl`SK$3IU4I8zkjeD=d%kZap^gp z$Eu&4+es1^O<+X;Yo%CYmLwFpHrYt#-^hX}h|1S-gRMms2;BAe7IBIdJFG0u2ox}8 zE=~^ZK!)x>H#N%g3oZ&WbQe<@Xeg!i>lK(EDku;r_`A3GVmz}ZL+g}3y3{X2U)^aH zU#U&m{_xIvww?R+hTT$CL>)wt3+SE9Y)38z4MlcZc^hDJuF5C_=3Jgh@9|5%NL_~H z;B8PU;TMerk;A1S60puubz%LztXHihaQv}pZq10I3~1%>HDfi19oT{i77vXdxGY#V zwrC(0FXa{ob;kTF*rM*%qE#4lF6tMb(7zb1;)#b>{Oti1yM-RI#N2ymfSHhJhAV+j z;h}RVZjFe|CNkaPm0BN^DPFHt%0V;VV{v`xBnov}MxWsU)&BB7TD zOq_jdl+$jF(vt)}@!3(4RJj&?aFZpM~r2!suRY1c7i%(Ngx z`=x^80A5Zp5}yRzT8w;MP@<*+qezBEGl|XCSvH7 zCbZ1Pw+e;>354#G_ZB&VXX_99Q>fN-q1Lp9Y7LtjQEMJVJ&}dtS5i|@YktPBlb69Z zt&3RXIn{{CrJkCZD0Qib5W$frj{}j{*hKe2ht4A3Q=wWCc?3gHzIo1rk75=L_f&xcoz&35A(` z+#OD~9)On2wblzy+yS3lII~9};o(d%#L4~Y>r8yV+@^^KKpL0?5)I!;adl0d5twzq zG8)?2vSr@VuMqX`rElSHKSub;Q9~lTxDUiStwT+Bz+VSq${{){z%FZC0UA7^t9qlm z!t?^+y%MXF5#CF<7$^$XiSU{z_#+yQ{YbVT1A#MM{Fk~ZQBeJ5l@AsLbLccC3jRQ1 zk6#j>Y)RcEuHnr!47hhclP;KuWUb{_XKXV`m2k=q6Wk{G^(PxW&}Vh{Av5e`!(dEV zI?^u-8s<=$;GO&a6p3rM2k2C?b&``o;g_nLrqm=&SqlmOG9*K%8>?B6KxpAA+$Wq} zLusm34+?GOE}#vIdf=r9xq1}ToIQb#1|OW~7r(Ec?h5NyphPhT0OZ5;%X*|y2R#rH zm8%;9Q8>Wd&dCEB^G6-1Baycog*10{l^pun6M{DV;MmUzssk#|ZkwT4#j_eY*G znGCFCi!e^#xEhi$jXhB#S5TkfF44}aS7 zGl(#D^ookx7#qh*_F=>Y!8>vK{veqa1`}sM<7Go~AHHPcf&95RUanb*$q_S4A4_A9 z$x+1gL0c?i`4A~(o)(K_Zp6pNPHG9|6f>k^J(7$wmzBakKU){a5VnnqG>)bjI@H4+IyEICz+K!uYT)2}6giqy(pBf4sOoaES0gw@0HT+wkZd^X3I%*-Jo zY^a`P&8S~=Z=}a@v!u((IFMBh1hR>OM+dUgW*(vMm~+hBGDhbI`J=X6B+cf0O92%E zTFZfRSrGX!A}|v~$~f4v7iF0(_i*(i7z(t8;^A5m@EwtGv_pwjL?Uu$CLMS+ZbXPn zXgPeB$h1YXCxn{h(blPhsavPPDyRK^62&&mV7=1y-2E3j!A!NP$#BVPQLIm-hWaB< zW)W+>_6y#cSXQC@APpXW%JgTNS+7{mNZd*u$T;{J##+hjss5+>@bxtovnb=?m{QGV8cs^6rEZL$NIP z<$h)uj2FeWPEHHAB$o}zUn+Mf6C|rCEBB?ieZ%1~lIc}ZZcgy6BriQUypCJ2r-kin zfBen4f%lv9Kf|%x|DI!!abG-sMIHJ)sBer{zh( z&4UdT?CJ|JOtv4s8j-(sqJfk+jUWcUk?p|8l4v zk7nx}MR9#ZMy{~VmX3(LriS5rYCF!ZHfwmc=vpEFLpaU>&HVQThC{h%(127e6J&#t zF~t56X(*qvp|mh%TH~&}14a>IA|tqzs&n~^93~V%<@D$Q_&K=x$#8}Ozw3wBwb+py zyj+XGDzZ{91d$*doc!#(?P8vV_{5; z3&P=$1j3PLD2GnIKHiKtUZ?5CQ058nQ)L-kNi|?{Mg;n-^h^OIh}3pQ26;eYXzHdWdV{e|dv z@f1Fy$D-Mju)o03V=?~=5tNXc$TpHUAA69?vy=-5DH^NzL~hSkHpYd0m^h2*Cef-Q zX3SP{iHKEh1ES1?e~*fwmHvy3tMYko>icVXV*FUpX-vC;k^f_hVRidM z!@c^Q-sQjXt}wSzvSmNxMbo)@OJU4Fp-h8i%rP5t(M^~xxt#OX=3>Ks#Xc(-mo zVz+J%yA`EhUw8c?DoLzxNM0$0!u4(#Sx$5e(~qaBkscG(X}gGA@TE0~ujoWJ_{Q9?&u{~V_|)q8+38jr z+6XWG>M$$@DC5*Pkq~=X^XM68a`Hg1pdz=USPRy=YVkw_1`;>&T|7e3`*3(-l$%w= zUagPd&sNnlW0@gy%9?SXPup7fzHCH5q%tSl+)(rH#`IQfwx`v zmS_e)#BM$)8!D_-jMXoLE;&F!6&$4?FC~P6u*BIh|9mML=QNxH&!Jyu+wLS0W7TtR zrZf}Ba08l>BxbQ5ePO@0t*0Mn0mJ}og(9oc59_YF-CI$IQdpOgG3))uQ=|65*7=`0 zXc-!RD0xhs_bRt}Qy-w$sxOK(+VH5dwiVrFJaQT-hM<{?kC$$|@VTKRdE1j*sTvwr z7gY|2WwUjHi7xJGm0UBZH&re)JhkLhW8tvxOq$K{>wa-vrWcl9b^y|mj>v4F>1 zkeS+Dgetk1cJlYt&DtdMF<5zVUy|>xCj>Q9_G%VbsSr9ZPd=zV1iWHrt zA|61k^kmfSJu_A|-=IOoZZ9IQkJ%Wm7LMvL5DmGk=nlc;jv~2jW59%egqS?cHx2R} zqAJP9vua6?mHM4JRUeY68?WQm*cYP^)iXOBMBEASuXycSV2^FyJLy2K~ECQ8P zBCRp95|jb1FIw)$B50y0f1}dima+T;!niz^rN_V%(wMJu&Vd$Y6+**47kLhJ@`?yl z=Ma&tVD&qKwCr>CF1>)_K%qR}$9*`yL~3hiY`LN@^{)7~{A(5rlXlp6hn_?8g8C4@ zh}+Y0xyo^s2EIw&A-sS8iPa(`M(*5lDc$oK^wH)oKxq2Ibc$OT*ws=Xix+!Sf5V81 zg(3BKAV5^^6o$|MKTkL+(V!$t)3&ijw%dQ95If)JyFf%=w zT|$uL?fbu&jzzjO{SvvtruN*zNCpfoGo>j1Wj-IMznZ+sNb`y%S{c#^w&&=(^E!*} zb}$*5e*iEd5z_q$@0pk$lCM=*Qy`OB4g}c;LXk0lni)lgjNhI=2~CNgPw-QaC_W`M zCs5W)q8^EjO7jWl?QS9Ml}bWIV6IN=Oy`IX>Zid>C}kiYo! zM6{PbY$Zs(&2JPCj^7l7zosA`&Il&Sy6ulcISZlf8F|J=%V1nuOmVU}ay1gTmlnbJ zN@tabs({$9E7KOd5AQy`2$lOQw{o zd2<3+{NC+#k!|PG#*(5rQ=2c3r;bZ-fLvsg2DxNTZS(o`?OX)C$$rri1V0OOgXhnG z7X@mH=2SGl(~el&^H!V%BG0jv`{#JgCDH2b^Ik|qBvCeZGZAjTL>*T7`yleDj|n0d z{ZYdwph`MLGMU-ppciP9GfASxme+X*b)Sjn_P4xnKm+i`9K&LnP8CDuoZ5WKVVf30 zdZu%m_a##&*?c6t+DCBQ5d5m1A5WZ1l+iN<+)YLGqu1H}bLyHeuFZ5OtG2O+1mQEg zzb@5^9F|sFiM>4uLi+ZM4(kU(=K-OJx3rz{cx+0c7Y?Qi|k+H6on?U(HQ zpx&G6GyExC`z4!$M>Wt58nMm7ECqSU*|d2ryXs0^R6z}k_89g?>0u4RXT`Mwk;06S zjrn+rJ|5>y9lkcG5zUhzGS(nPb3Y(vDDTsAr?04gHY_(LYRY{D0;(Y)EzV%{%QZ}^ z)_?a0tVSEwtYBC~k@OF1XwV`W-SFde?Ux)IJUaTYsvFFbVZ*YKFf4li^asSuZFFvE zF5RbgwMm<{9b&oS!YK(3q>ZjyvC`$Z-;T31+vIAcsQH7VxY6+EN1oT+jR_nfidrH1W=@ z4ZKJ3)TznTM_3>4W-z%SH@|Se6%Px%hV9~%*4pteEZn_sVQW46MOfAUQU6X64lL~P(p$uEQZ8A49=qk(1!NBypzgW6M6 z>k{>mkDAa=>?uJIEjE3&T*Id|>htu9a{A_vT1^FLWa=d{9>DlaP$TQk0ZvN|1Vt&$ z{pe2NwM)8^JtkX*19ruFdZeP(aVzSNI!$%>C8z2~gBalk@h&CC11J4_{1u8e`2WuSCxjqX4 zJ3|yt&jIYR0$>AhV@A3Y5KRIM!vnOU&@L+7rGK`ytKXJw?N-|)pak#_ z;J<)Y@&AmVf}%u0_`N^pKF`bquudYl?@ipe zN^(W2O1S!B@zqHZo%2V0bCl5YZYDBAd^Tl6V;ADoacQA6fY;wA_xq})Ezo1~Ue zMW%21U|x4T{5ToK!#A_np7{}3#KWIBfQO|9IUbfyDU=Xzq=238qMDGMVc?LXV=2y$ zJ6*Is^+rSLwM6Ru97k8=^_6fe*p(yptnoH;V*zjfF&^Qvr_}|#{r%Ca_SV<#`e5Fc z1d-Go#N&HD1)K$>_+;?zsEiUq6*T#R(*G77pHBtG;~WE6o$%v_TIe?;R14p8=C^|u za_m&V^Y<-3kmpw)BX%0h^EIjir!D;y@cgN~|NVJ>msY@J% zlO$?2v&hMx)CrGPSz_&yv(5f&M1d4rP$TppB^v zoW}vaqC{kO<};^&q}sRJp9yEqQ0>W)qJQRHH39i)-egd34&H5?m`AVS9hRD`7&wIVdE{RLagOL4Q9%b22a`WplzEe;iBiN z|2Mei`DF(J`3b3sg{%$IK4;Jrf0>`0yaKoXNAFw|sh>f(gyw^pQp*7tW zkeK5SYB(4oKUWB&5#2Fe5RW<> zISo*1<@X90A)J(0a}`WV$9zJQpwsjeImOgO0#@M`9x9$&Q8g8rMZ97++oOKof5k%6 zFBS73#ZmR`#t$puhu1SFep3AKY@Q!fuQbVn@WtYj29Mpc;N8ZFA^tM&@WoUm4;o9q z?7|>xZtw;TsS|D#$q(tD;){Q|{XmjCBADR|HOL_bPuY%-2VhHsgx1#Z{`a3v*4}m? zkjpvkv_D^*WY83!7y=o{oVecovg7qL2$$ju)89!Qgv1K*1wZiGWV2uL+#oK}p;A(}FEPSZe*oYssCEbE>`cKQHm@L%6wm)`< z%vWw=bi7sxfp zV<9wIRY{T0DjQ)Q!`x7T7*-fAK(sXyQj8E|sLg>KBHU2x#6o~oTL6)t!4HuhU{xql zO(Kys9~InMT>Z<(RfTI5K)%CrXEUGqmJ{#$f@69@3zsz4>j3VLfj`uA zLIEH1FGkfVx{XgcT_^Sj3W0z#KWUYQqJ2fxGLqw|-HoZ&(RCE|JVC~W)cp;qZ3Ht( zJ(OR6xC4uzO@YIR16=%UCF<%*t`B^@A+jxVO4X{pwY%GiOPDtwsB+y6qdJ8cLz#c( zzfsT#I1o&;g7;7vx`KD=Z&NbZ%G(h9vWY>~oMaj#ul^FDFTSgEgK+(lygZGus&(qn zr}vkr48?GRsO-Iu1b_!(egYYRR9UBHvnz%RsN+aPv2jwXR zPzDiC<~QQtnEtGc1=5CO@)yKnC$aY&ex0#^(_zw!7NQqzY~XCS+5b7Wc33jCw(Ff4 zAF=nmKE!orPA96f>quUXA?F(-JJ?i_kzjT93A}js^Hr~od{RWjm)23bb4XP`pz(|&hYpBfQ7gVyYc z;{(dnkV6S42JdcO&)elZrSDGzIhy+kCLD|3urfInfowP zTPWvLjkC>t4MD2zm^?7G4AYis@yl+|540BA=4SK$_h+%mOc)1(c_imOl`1d?Tjy3C zJ7}f8iC3h=3;G$nQdd`UGacyt%dK-x0QhBBS*3%ps|n=yHi0+_koeVJS)yh}Mn1FJV(#ZOk@aM^PDf%)st_ki>n$OAe_tX0po}~iWfm>P$*#7BzL3*3|sqd`+sGBz=@On`1Qlq zfo$gIS2%vXjw~VM7CC6X+yO#9H3kLM@^=@vu>&4xq7{MF&FP2m^X*4LD#7fUND+eI zb#bd>;D^MpY;gq|X(F|YATTNJj)hkhMT0=9Y;F0)mr#d{-i?uM4UuOuKRH^vS-aY~ zlqau-Isw7aOIP_pG}0)w7!d~=)6v1ZiEfDcu@Pd@;vM`9Vp7q+(*6P_6~ z(?d=p&G>nu$ZMpZg|%`bC73R+Gl-5o;=%eS*sEh(yT@E%%B$for=Yr*^dN5JhZQ7PN5>iY}_i=^Smr!rAm5~!t z&brX_At7{-abknp03fk0Z&VY#+P%&`1HA}RK>Hw5&_AnmZU9`T!S~34* z7^G^swT7Md%wuveTvj8yz+Qk!XWTLJ8H~w6Rv!o9-(*m`=0-62KE@oA1$MjNJh$-_ zGE#_03)>Qy(xkLoU_0ZY+|Wxl7=R(aI971{;(&Fc;dJ#Aez8S}V=D2BU$*B6eF(_) z1JQhh6+b{U{A4D5X}87n!Hk1B`9?1fE*f(150VR^q{stHiev&1Gr}eZP|Rgit%DG2 ztqXxHFhu$Bh;4d0Y_P?7P`Qx30qCQgNBtj)cP6+rDmEBlubk}tb3=1| z*#Se7gV=<~2ad{AD|x`El&fFgGRN5cM`e(}{=iWoT#(j1A1t&TPXyHTmkaH?OI=S* zXdir_uy0$Y0$Z@CvobSo2Az7F&4fSziE;c9pR>%N5O?zDV8SP4Vq{=Nd}&1qor6a-L#w{PfgT6jva zDex<;Qw(nO2f0W$nTzy9bCI6R-$hk3hv3IK5Sj6RxJxnVUs*Lyo1ZB-_S@>P4iQN>Rjro&YDNRGLFT>C%Z@Hl!kb>I_Ptw!)orjcrvz5Gqui451s z0iLVO__+4l`4Vl*6XHtK!1D2gC&MLPA4bfkDT`O^Rc|M8BX@3Z_AbPawyaS=kfpep z2k)XsX>4ugp2sf9h2%a(>D2?7<)rCM3B@^f(5$dS*ImO4Av!qN0`O=P1is)}R|F8Z zizHJxb>qX`%HgPsb*`uQNHtaOP1rztEjsAMNe>RP;Ku{1fO)JTV_fEvvQ>NY_I46K zlg;8^8Q5n8Y}xAJU2=?1`rH^KfB=kBCZKZk)?u-ZeHBy2rH28Jfsxg^h+y&v$#EF% zGrLPI>@n`%c#H%6_``uyJ)(lc)vMpD>=wo=D5Q7?KlZH9XLOK~O(ew#2I-m4w_F5r zUQQn+1W?EGRu2#!LhIf|tJq`?@d4(6U@T}6mgMKo#pr!PMYoW`X}61o7~=VW6OPvD zCz?4QV6~BP50iOto)R~A)Xv)8_P4WJK+6H~xf|eX9yO`U21#MT05UdwDzQb zdDXZWU^k>54@s98|Lk@=5*Gq>dUZ`^$q_(Bm{5m>>s#9|p)=8X=#97mHyvh2XZ}KJ zhTa?m2at7mKGLY0>f2c)XBqSyh4)@0npx-bF0@_8pw~{9$xB_A;xniM_+gWM+ zqq(8DA5`r}Zu1VyksF5^dO+0pMlmK(Hrw&9M#A6@Tz8LZfN7q~5#8p@X)uBi+djm| zj_wC!*LR_M{tPudrCPj;Rzh9Mc_GOUaM&e`zgu3lw%Qyqjds;Aw-Ex@i+{PCl{YHf2OTL}?O5$1XZ>;IG}-z7r72 z+lOR_LzX%Fs7lAv!>njsOcL^hM4RV=r{ngqkg}_BBSx!>tc%sIZ+`<%?2=)O7^@se;J-vcqE)clBoxD*4@n_H*Sk+jb=Xc zE)1EoGI4r_Q25N)%fN)&4Uz-4nQZ(K)pP+@ZQTlC#l1woZiA?#Dmb{)1^i1rD_@oE zlqYSTb5p_T6jM@0*d=bW%~MSjO1AwUT)vZD0)Lh5f#YW%nKF-j$=SA^#3wG6J~W;l z1xVd|kvrKx%iEg`RT+ms?3o*jx`w!z_hfSR-g*utzwr({_$2>U^Y4*FM|VkRr>5Hp z-tnn%5vm$etIiGGyh++Zy&B_$KNY83;OZCfrXB@Bk!LE$>TU)MDd2(->R0_Mq_?_Q z?c1@`t{C^Hd&$?mQBw$#n|{fp(mX@yewMwphhXalck8Jq^WZA2lDa?{O9?c=L$Z`7C@uRp&1SY1opwsLEk&fL-J?4s*S+J~i9*7i;# zK(<{gL3FN!f=hM2rHBC3t=`4_3oLx?fSx&rW+oV(Wx(3PFWX_Z>(#Hc$Ob|_r9j)l za6ZIeP)H>vG_0ubyxq{b+Y)>sUb_`W-3P_SQyK64m6AFb=e7|TWADAJT#$|{ItF3lKL5Kw{+$xdi$546Znv+}@ zIaQ)Y)UfW5Q6p-3G{xvx*{+D9$DkNlzl!(pio%@L54lu1heyg@(>r}@DhY~L>Map2 zW9sB2sxAo9O!X*fxi+E%V3wqcSM9N&VZT?l+O6IK8F^)V-OjJVxZb08U3Cyy;rNl= zlPyY%aHTiD@mhELhUcGw#Pg~hr|V)C$K} z1YV>^5NjT7V9Z=^?gBD-T`B%1Yu;4TGnEx%eB@31n7+65s4Et7Nh#-_#{ANo`xVRF z%3t_}9qX3@lya$sW0EHi6%HAmfMQXE_7Z)cUGJfo)908@v=B*Dq_ey|-o;V@Sux5e zhkEpKj`-Idl=z?B*LfiE2Xt>#uCa%pjSTY)AR;iH$kTsFaS0IeuqoF9B-(fF6>hkCnvN7obZ&)_Ho**2{m5#pY&%yd^ zo|Nm&uFZ)EA!XdX^ym5&-%`2mplV~bbURX{>i6dcO*W>Ukx6(ehXa{m#&9Va_T{bD zE@UVcQjEwZ3-0Gv%seajW~u%o_w$CW5mJP5P3jZwvZ*q=QR!#ot*tN zW1#B9yTT|$8Tf-j5{R_B9M@(EtPn(xu zwsP|+Ql$sp5+v~&LVIwawa=Tk`w-@sHjA;Ki7?TI?itL11gaJl#A-G$Q| z?TWf{vs3K@UgHDxHEe^7_}Olu(Ful{o@5((8}>H|#FUFEDK3%&pBP$VU?vqAANXZo zr>qz_H{;s0BpUBlCe9fqxPeW-lbPq|>MQeDBOa1TO;z)Z&gk`;P|OfSK?Q>8GAyG> z^6mGK59fbG@`2hEa^p&2WhU)}0#$|m;#bL-#^<_~rotJJ+ajItrlMc-9cPFD(nj4` zYCVH^wyQD+8ePs!m@=3Jk;Rp0lV>8rrC=4mrM}tJ=i;3DBfcUaH!+h3B*L-kGw>&+ z+G$7RsBytR>wu_B&VE_Xn=N=`zwnFng!*(EdkwE%*GfyoY!Y0@lq6s<-8PZn7cJRZ znuzpi0vaN6WkRlfq8;tbF(`AP+=+}>lZC{}`RHIAV>RpRBkPH@IPWYP;)E!Q;J$`7 z0;)WVfOF%67e;P)P}ZP77nVUYlyn6&4Vb33clt{Km5E>iB3x$_sHq42Y}~t@Luwx| z4Ncc%iyaIxjiWSnGXh1Y~^8mxS`M878Tz0mte3HHxUVu)?@vTdZgr=Q^$Y<9Ys9m5}V#&)a?IeuayfSSbytUVSBG_1hjmkpmUNVIb#t^&-5GSWFDV=1D$czRTDL$ucasxc zcKohRHk%$|4Jj(uN-@C-u_5(r!>%VYd+N2Mn^GN1AJy^RVczU8(MK>W{_id5BWp^H&Ad|{D75aNVK|P+gAP#Tp z^`hetvoCnn?RyFf_ zRSB{dvWaR1qY4%c-YyT`WL_Nqm?d#^|21!Z z5=v_Ht1fHs#~jCY#7~M~lM@pDmA@$>X3MeX`cv-Uq4XFglf^s~9Zh6w&ZqdLBhR<} zZ(=4V{rCc6T_+dwr}>yj%)gYq@ruRVS=O-Y>4ZP+j*@fz<9?(806=j#?wR-V?}4I* zj+Oi)B63F$|7=1^jvSx|s}iKhi4&aY0)sWSh@9gU|HQTBiYw8*V|iBNs*k&4 z0A?CPVhNyFfJYO`9DdWSMhYidPO2AeEd10Oej*h*Df~1s{A8)o^9sLR?!F-_EjfB_ z;m1k2kCsdXeS?MQF2a^UU2bV1lziD6G&bHWZU$#i46u3f)P#$ydoIqj176oy=q3AM z1QFkk;2*}#bZHe>$LOhl(Xz95b~4hfeezg(9qD8zo%}EC!R?RFbwwDCT-NeB{094V zW+|&M{e1kYNMscMt}RlnUNwy~*53G+RoM>*S7xTNJbzNENh(dEga#BH3KPEtNg1yQ zQP|0z<+Y!Gs{l^-Gl(%%qCCN+U;^X5?B{7AT<=j;0XV$PC=pChD8${bKZ?up ziohFs5b!A0BA}WC6u*g5i^5aAQ6-otC8!sRVR zngI?5KEj|p!OSi2Z_dsn&}z=!Lu;1`ohR|{D#37V2tQ$fs)>$O4HBX=O4aTv{dp*a z=~?w=40RQZoHJ=c@)L{57HtXo(}ehmCZd413aGcLhSvg^4C zBX>q`85p$nC7#MB7LoRx(zYn=X{EK4khWQA8aOd#e&lGmJQ207dtF~axzFCniHFc2kbznIg&)6#?ST5#kc)8=AkS z+jhV(LzN-yA`rIAPy^jQX^ak7+m&)fRDZ9kpcjfRG+tLFjo(StQ>vPRB=(TXaW1g5 z<{<4Y<%Ofk)+&5Hq|i<}3h4xd<7uV!?i*z<&)sI=#}bH z9`OR}a!tN@)QcZN)MI=8HNh?#bH zg{h2Jjnt=WkF!#ABsv2eGd^f@8cq$Mb&kQhTqt}js8JdrDqt|MyRFQX;qXqWnrxrx z0s}im1A8H1n)e@AwOpqmof-@&R$rxAqtVGi+oY)K?B;2r@Y5n_$E)8>Kpag-q18BP zh#2($r$ZfRT1*WZdvpi>61&zksczb99iVqpHQZckG-@FLnOAOIyzpe@Ev zBe~s3fV3-Y+^;%L->ce)@nyY}0FP8@tAR#aX zG+ zAEOg<%-;gKqD__jNmS8ps7_C$QpiVi!YAXgK$(|_2R_Y-f18BJlZ`a?a@PZbJ*wqC zplvl@i#lUgLTxEIPfhC6G$RV&bJQf#F@DO+6Ls}U;XhAJBAv@YaRD_61Fb@}QIkV= zAwhwh@&rdAQRTd@1tO^bJ1G7?#S2MmFlB{gG=YX0+ZLk=k(CkDRjQjCJxP^f8NIfO z_x}-XN&4hy5>|@Npwl6NsV;SOfFx%(Ro$3okx-Kd-`s2ams>QG7rA~u2)d&#ck51O8Ov(}9M4`V$1lUC9qls!G zEY&7%GQBKMmbQ{AAWI=GSYwJx)mNuBgv!QWGj-(&Q!1!dA^@X_7z$i3!jz4GwTY5h zzbmoRc64e3WUL?XDz!!WW1&`pL)`wh*E)~GkfU>HWgXJLyxgH^-T!D0T z2Y0rR-RuJ{tL@eHw!fPF4{{L?d(e6&mOjF(ev6Ed+4w(-csj_%UfN~co}oLQ{W$gr zHbV%fQIg=ysLCg!dkUJkUyCj?hP1F))M9Ks|8Sjfv9qI~P%CA(P)yiS(%)r|7c8NE z8rXZBjRwn1eR>!+91J|vBiJZB{&8;c_U6Bgb2&zn%VO;4(bc0P1absK>?Yhhjj`l> z&PoF2a|QQZ3f__&ya|jU)TX7U1eP;Wbc;65+M{=)$8NrgP8~(yIYo$Jdy^pb%9ABQ zmzXU3G-#^5V12Lf)~W0nfEvUX*}s2ezqYhqn17GDwXMFJU(so}f@D!^Czamet^=$^ z^fwz}P)0UJdN3}{<^XSh-cqFakFN8Kk;W%54ms100#hf40I_x2mdA=&OSDru{YC4v zq6fS8f3$bSJGI5MIEvAvpKDn_O6Ku)78p={f%!vUtX7S>&|~Ou)(?eA-QW7rP}@T= zVCn2f(>bF@yUqpTj!qEiUcodSy$bvsh0zMUNa?*cO65Y<8va>pD+SDh`lE>358J`a zK5n_d$Og9XFY`-}Zj7u2TM7ds;&28wg@VbW&Y`V&amk?duHjFHG?~xdI*0kDWFR1% zmGt%nwfekpvwJd$vU{WI{Rd0n1>>_(V*~>TD#oX9 zw9dCh#bYE{XKb+E08ysrVqKt$YfEG4&(dXENMRi09`;TehY&_7JR%TPVYIIXc9X|z5SKa5~R!8Xy!HMs?5V`p_HS&B~1>dd=L zt*E)6zE1OkBr~s}(OGkNq0#x>+YrJq^l$jWE!J(oA1uLLH@*oxY;9b|DLr;IxO4V@wwV#^ zWh5eR$x%al843S5^VC@A=p(;@LA#JgD1A-r(wC_@>Hs2*gChakr*Jx?L;xENe3nmZ zA;kn5sG}JAuj#&kWSqT=v|yXVS-kW&jYvHGWZh{?$JVEWh-SEFd zQLDYK?~9^-{=z}^5xRL!#X;!F=_Alkefp%3pe9u2a`*5lcFjNb*J{gvBityLzI5|OQmU4IN|?iXn5sOzDM zbl~2ZP5DkjG0TYj=w`5Y7LbkYl{r%yy>WYGfiW#dgSs>=M}r_s^3IVgQVSF~qYi+? z?A5K$MMiF~EWc0pH_+gI8)B^?c^+g#%nS%7*#>Qh{qImHyJ24!g%0O_F#Pv8>NT2p zcXmVqA3t0xv! zvqugTxMBmvzZn#dvSTh+Q%-X@C%n3(e`W`t*c_j#9CC#Tds3;mH3{AMT9-L**s8tO z{{j5apperqBDZK}4AEhx;Rcb~lv(`L%DpPW1*SMq;APFxcCwy%sw(!07;Z;M#&7p7 zmhl$zR_2x`SDFuuizFzzb-{9Qv9O5b*#M#SV{<6Roy1@d?#iZV>LPPy&2Ze>pJT}6 zFk$x>%s+{q2-A4+yd-aQyj&VbH?~E&9XKLXYYfGA$KUp(Hv5m}Gv}Pf5aIawq3YwU zBqvFh)dECHdkF3)Xg`rwkH(*+A+jl{|2M{KaVOJ8xOx%sM)iJ2*S;L)jaqyChuX_m zt0jFZKbnF=x8Bcw8G5$Y{JPitvUlpXYfr<+zlTjWcO}FYHZ@=1_L>(--G-ohkV1#? z%g#u7jcSQ(?cfvsHxzh|5BwWcV3k@S{UK$p;bnOC0u=3>y+s#6aBt7Rnw4%oFTDFf z_}l+{&5hfZ0l$&wjoXIcu*OA9^7}}iCO;7+B-8gTBq5&u5TDlbB#Mpl0SA)Ks!I1T zuWGb=SX5Q#9+p-$xrgOd6Wzm|Rg>MrimI9J0slN6aE1C5Zg}q4gp|S+BqmaQe(7g* zJ$Cw*ZW_gZs~=QHb`YQ1FZJoNj`GhfS}g}Y;P2(W*bVJF@Yqyc6q0*gYR9e(e(4U& z80>%Sm%pLy&HuIvbOT)1I|;AhiS+OUS28F}+M=qc>e|KIimFN;JKn{Y@CKlhwE}NG zIfnVoN8wcYUq7W5v=#g?d+~-cGvrf zi2RNQsGl1#dTOvRlpXeXrvjT$fs(nSMMEO)z#FhQ`&b}$@MX#z_tA@o*cF46>gPjd z-EEi1i>!%xWIO*dnhCadC|GcPA}tLIt6qjmz0PZK+J};hdsJV#ei9UAbf}lfP!^2S z8%qH6M<mK!<#o=RT?I?{+HYEXys&7 z-*w01{(BtX_QF%7MCJrU_3}VK;6&yG1Wsg5Kv0ha!~rv5GJT8q%|c;i=R$aSdkSc2iq}@& zFr0^$cx`n05h8+mCaFkv2SA?f7kw5gT}E+^rV+5dZDTs#A(L9`&HQD+=F$85+SjLl zBhC@mHart|;ET8tj>j<-NwQAnf}!52SX9Y)-BDb`b%i(M0q@)umH@3Pojhk1X$;-- za(nPj-Ev*2%fHe)w?Ea7*ea3O`bCfv$A0;9H?;jRUbEefKS7UF5Mzhd&*7K-W*z)e{N7=x!i2brVAsJAHiW z>ZTmeMRT(4jFMUuILWlH54yrw&?J!n!jrC+(s2agkM&v?S@vihk>u3!hBQ~fV;A}**GKVBgRFF_>tt#)=xu;k`X z>w^}FNJH0;0Xd>GE`eM+q)Vb;wMh!Q6A-Z~(Ku&BF*s6$8Rj5~dn8IfIe8NQKg~}= zn~AseB!R9j6PSp%LpWQ?u{34mKXHDaa=7alHJXww8ks}v-bC_lBcHM>uNWNIG&zc5 zjK$Npb@P==LE@BtP#KprMEWT>jm-Kl;Y0J9pER(lrODOuDSqOqm1Jf$C#JUT{M;a{m>*DRi({~zv z)2-VFxH)b+S2w=qbzV`bob^rV(PS5>e#Ienn(Z41HU_fxiRtB%BA9nAhUodd{$v7R z;o&Nnm!M;aQ4&6$xg_W$kqwmYW-*l|(e@6m?RnnP!3TgP?VY6mshe;`{merm?PkTP zThB@A%pV?J$sq>E(1}Bw&XGv_YQ_#KQ99<=?W32PRjijJaSs^Q%^P8r7aj~*CDkqN zQm)L`sT5)|SgCV6C0G;OYgykzYq*^!$(5?R13kkoOUkJzq1JItzV4pPk4IiS1Vk*O zu3AT7h~#d-^!&q*$U_FxDU0S!P2id@HK)tXT!F;IC9s)Y>&Z`2Vpxu^ELTx(lQSic z?an`Wm*4O>$5Of}L4e$@+sk08rB$owU%Ym=x8QT6bJB|r%mIkT)D!B^@!Qww*pCs- z)`~#?i*?)|sjq#*n-`&o9y5mZ6 zwB9?vA7QnihUVokpKM#_e}`{w^v@4&PD>BJz(4LN0dma%Qg5o7Y?G((imDYnC;fl2 z@V=9I#)*HvrcE-pa8G9YR2dt`{J6t$eMB7>)B;ug_V=-(3RtR<6G-GUt`b%0q1K5R z&%X;fMVj~w!V_bXRRa+rRRV>alEB{lH;z9V8)nJxfYGZ zd}~z;pA94$8A~=T=($|X>33Q=kP9VGDWlZ@DNRb@q-v5QJ5nkyM@?jUy^JyO%1$8>GEsTdr=W{Tx@h?2TT>popksV&QQLHDlHtmAPZiNu^(WU+!<*qI z-{s5|$6O>zY@#0ZA>c|tH%4WfD1HXtZQN%Z6ZhkXLz0)a=qh$(vm?=Aa-=bPEUr_N`16s>wT(U+S>Dam+!@~Bn(iL<0bSDLkwO%dO zK)Wg&x#wC&3683oyA8DH^#dGiGPdvh4u#0Zp+Tx~o7ZTp_wYjK1}-qJS|NU`x?ZK3l^sm@L$MfCt}R`SdAzY1{lA6+Ux zYk)&TlKf?_-_IE@uH_K-LX!hzBCi&B`j107yj4?y5-#wQ^Wf3thCZp5OGrhA^zn^s zA_)C=fnWN=oai9eLUIwuO@q5$1tM!Gqe+%+#}qeztKB(#NC*s`qddoTK+R3wQocn0 zdN)bVdz0$n{Y9noK00`RI(Q!&ygwMc4++ZO8@wli?>mF{>fpUQc(3FAE$@??)Q0e> zHd>S?-6dSJU;Qx0$HLgsV6jf=w94FUM5p!0+4vt`QgUYvpfl*sYhUy z0W!u@>)?6ePnQSyBkEUaI)1KWyB51U$-vJZzDhDo)GzPL)Bx}5y52>tCOLxlg~7YJ zuJ4-e^<878_nE=_LVJ%R4EZR$NOZ7fX4r$5NqP}Ra?&XjM=km?C-`FPW+BPRo?y{k zrz}kdL$GF^8Dtr)FMYg-AvK^XSFJ<|G`&=2?wQV}IAnTfl}1*#i2sC)@Y^CI1(EWd zc4&*ySXA|5&?SwAs4eR9y7QRv^rQg?jF(O$60j<2r&_G;kezx zKKFR6a0F@qRe_A)iDvO8K(o96UssD)L=EFN5#$FvO z1G5y71VWoA3nm%EiO@tNz0>=Q(tHDRqh)^0WtQJOjSc;$&Hx$ zu38Y2N$;78OpzuuS?55vTk}+4AGI?$K3)r`kqmCVx>Dv891U3^qQ}d6PRZ!0syXhN&Fnvg+MB3>xLu6ryPWB})ND zrD#c@j(7{^(sxnzS%1*EY)+8&*_3uHuTl-RP=+(+8qQ~!bhOR>Fmp3!TQ`AbAui!p z+``ci?Bk_A^kF1bgm)7wt5yQ4G!r4o@j=m1yvYFqap1Ms#&l6RujNJMp+S8my8cL7 zj4-rYs2c$E>Q_t%OufM*+qNd2;_l#h3M*RnySP+`%VNrzP97|Y72SDWppH8U>KC1m zSb~|kQ)cGJ!1`H!(dY6h{Tc_bIEh~laCVBOrjm0q?|<5CDwSR1gw+2#SxW2CvY`X& zX9G-9o_W>avTuk3)3exl~ZZ2z_ilt|XvxfKB z?K)i=R45{bLAkX~e`2^#w$||{dhSleD4YEnIlNJ8ytyx0*79?A2GtVt{tS#y4A~7A zp=qj#(1r(j%(7)7UPV+IjVlUqpo_NJOZ`-uu?1FZ{MJ3z(7dpr4%bk_fUUnWzHB?c;Ut6(B9R?Wz1o=C9sj7)523*l z5)}bNlP7kBAU~Nw>v8XQX0wt(oF6QMzf_>zD=Xe34O4^Sq{J z`sya3$l6%yi%iPw9w`}iIvbHwt zZM^;p>igmz;{J%*@a)1XoGPaRO6@a=wkHza1&^}Gf~2DHo2lZqnIKQ~>4j|*3h{;@ zYCU_vJ9YJS$9bdnUH@Tyy4yaLe`g>&nmTa|-Fge|>04ja5>mZxXnQc2U`VK@J+PsX zY4qcVVYJ_H0heLc6Uc7YhPXoa5QHNz+%?ZFiMePE=@qTd2fA-(`h^71W zIBQ4IyryY*h;kAs%Scfhck`ZbTj<$uQ9_&W1^?k6l7^!Rl#)o}CE3+I1BS)g(a<(l z&J0A+llMXrb%pDelWpa4Rj_?8ccYTVx(G8tv~(B;wUZH6_0eOHInj^8Cpx-o?oSFt zpaaxQ`(6tU%wn_hBNadf>BJ=qn_{(n?f*rPhLwSTKx1lkOhRo)>>}bcKt3=18sT$c ztodSGPh8jru7j7~1?R}yP8RIlQ7+kba^{OgukDqBOSpy_Z`3evu7=3# zx?X>)UA6;u_7;-y`k_;vZR~o@_T{m(v?RG0!b`lG^grGP6zmeQvwpemi`bH6zfAW$ zV`QghA;)5rf1E@- zYc4044Jpj(%u0T96g{_9Q#-M@{j#_IO9plnK}BBe>9-aWp!^8pqpE0i5&=DpgwtOn zCuY4C)m7pV@=!PS!^#1@>>%BNSS2Pn5A! zJOS!oUNy~b{>+T~wapsjX-qT{!P75$bA|dW9MBS|)?AGp(lBR>Uz!qr!zjn2S$dv) zsA_A{7UU8jwTR^ZY4wN==Q!t}0CBhiQMqu%^&d%H*h3zn@P`xta{;=}{*};0&5S!= zhuQWfm`Vaw`qG59sIHX7^Idv48cflw_7ebvbx6>Ub***KnhOy38~fm{mH>>e^Fa~EpJS%CG(}1khB5*snHLzBf|%)bLEbuju_31*q=&hZFN#Wqj0kX5)5C59U)28s zMoHOS1#qx~-nb!i)JGLk%5BW34&3O=vsw~d z>Knh73KKIi2B{M@*C{VxvnUHvTf$V}ccUl+d!_MEX2d5}?G^3Mn4&HiikP1mQMuG< zb*>f(*c^7y?nMqRN=|V&V}rXRxsI_d0xP`=*nIrp`;j>h6XC2u5c~5Lsc6J+Y9zAa zIsv4ib$9%g!of;$EOxIURDOpC465K#F?E5_bX+Z$EMz`@6L7=b=60oP1thj+v%!I2 zQ_iVDF~gf-GelP+_+nUcfn~*A3@_|-`1{+8olY|4#MR_z`L~o5ONoHAEp1@=rT38x0aO@6#q8oHD19>3 znaFf8`*drXNK#=2wJ1y~zAWAeE_z@*#qH1p%y#lFnc538BGxoM!HtJVX$&=4Hj+QA zidUj~yqt`@k$L|vcCc&TYVViKQ^n#&XS8*dso^D-p5xA!{xjsx9{Z5v&IkFBA4Pw} z-Mrgi9h5DNzBS2fm|fqbHbI_li2fvtrjIbz40&=U)i|E??ph5cxN9ebXy#gW+RGXR z8soVipI)Vl;pF8dwIxn->ZIkcE4s%nfp zmOPm_19N|z|=s8%FJ|C)L>?tcRh>Ibf0*S>~g(=Z53PsD4o39fndD}IyU z)bAjN-nH#Jw%&CQ{RTw*xA+aUp0byJX6sp{W$r0`mEbai1K1s~vIzADzqp5@G>X4@ z$LgWlKCjdMJ5l>&npB0!6kSVSIvTSo*I&fhbvJdo9#*KAreku=FKeeBDF#hgraE`|wk2R# zOv_~CJr~yU9$Vu;ud}E%GyE~U|25iF!L(Ul?M5?O%Bo`FJ+RJ@?4^1vpnn(7kSW8C zKdhP=_?K@tK2R7Ih0lrdc>5*ia$onFj zQh8Wvn|NtuUv9b!4|keaa1Q0TdQCZu6~gHBv0YEKPZXV~G5M&vR;pbq?7#$Vc-3L$ z)vj_rg;iI(st=&9oPOQd_GV+-Zu87IZKI;nw`DXDv?SY}V-fpiV;BB9>qHG0)ygjW zY3C5Tf`U))vE;=MM=RaNt{1UhiUqyI^9{QmwY`4P2vk9Bt*jB}L3Yb5+Rz`v#vZ@te=x+wtBZUgu}g^*Y`w@;bMJ zUcDIX4(n@*5@gh}Zl8+k%wP_SfRx)7EJB>jyoKRVZk27%;QTap(DA*A9nxDW> zyxyDrInvoV?E0*}gS~Dx3h?_~ImWk~!PT zs#1L;`SjS2ZD-a>O$zY?N{MJ4py-04u;+Q)egK{lxvU^*5GsYM3rZM|V3-aZp8Byi zvL#`T-h&L_WB{BD61!Kpd(`|VyY!oFjVTl#tgUsgvKy|oKL!OQ>6#-!U1w~rk{~UXd zqq_AfW%T!ASYGxAgW*9}5fphT<{cDb&3RJ+h`DT<^ey@gjh^clVfVse*s{kvitGSM z0)w^9wPazUVTmi@L{! zCSYN5!Y`eDS~rmV6N2WkT+!j{Dbme0ixug{@aK5sDsnv@=IR~3-s}1t>Jr7jC~3rT z{ZJaMC0Py{z51Ld?4R-K2zy!Z0r?A7(4T{|$O8}u^cIoU7pYC+> z$3qb1#ScT{m_kaBioyuj{!lDab`3w7cYXx){9$}L*7)P0&1q&b(6&M-Na%Q`_jk;}vMqe)L!+?2K`)_qvR zpCc$E2lia!+p4o%R~9eSOO3A=!JaB=P$>2$3WO zUfn7uH8}@^c(iGc?KZTEM0kF$c#7gvM$cs*r#rfpGfBk$VLP*-cHNXC^`U;q)&+&< ztE9SOE=Y6?luo&pGCC;}Jwi(pBrP8$*e7MLwlS$gxX2Uf47kLJnbVA4qNikT17Ysa z;e-s3R0AKH&iMPYI!cyrkIIRlK;$E602K9^%M-m=WYb$R&6FaM=p@Ir#|9WBr@{vX zlb}N@m7jTS*eX2iEY{*?JWe(E#@C`Es{eSLoYb;O5|sBlZ6e~qtq{?DHD1772?f5v zzd!QN)HXO8es6w;e=pPdSFih`Yho1@D=%;3Gpf}-j&UC~XWK`F#Ma!$53BQgNH;l- z`uLtVYcV-t&{J0i^T|_8AmQZDjlA@Jz%&DOJ%#>Ddf92+;GJvLs>#?*`U~FdDnyN@ zg5xBHIRE+8rNK~m$Vs3>B$m550+cZ}BpBz;q-i}l)sajgQcy+a@l8w2$(nsxk8(_q zl-PeGbx3EMMy|3Qy(sByMNW8?N*`k4qJQNLr46FNG0D_=7?a>qMdHW!P;FWE@-H|5 zA`)=fnT6XQkFiLZav}-QFI6{mWZ{>s6|kd~P2Rk-0nXfdv+R`us)Z;EC9!*;JRKA+ zNwf{+OgFQ>n|?F}&Fd7nbZI#MI_*WZ!3)g#nMnJClB!J6lgaDU4I>37%W#^M>?FnQ z#ZZOmnf%f`i+?DBseNL?H_e+B1S_Xz&e}_1le1!ZQ;Bg&2eqIfTt6c(sE1_F+hM!R zJ=q6jGe+OA9k_P%-}pp8FE5%!!$_E}nJV49ohmgUM6*Xy@QQ`ZiP<6vUyYk-YI=B4 z@Y@S za;LJ@Ba|UdJG1(qsPwkax^vui)UHpTwLo^K&H%4P6D&5P6)!oH+0r6aP(Kno71o(} zx+K+yg=ZUC;x&Eo)Whh0wLLfB;?Gf?rsGWWnV;Y{;X4HzE{n=OG1y;1LYbNA_?`eDftya@WdQGH%|Gii)V^!O1JC3S~v!pB|75UYLK>%3F=pjVAJ$h19GgUQZK z({c-$Ls@RE!G(wiygAuePO|OMwh?%jktCcnavcqO&+EvS_rw;)8zS9YJA!MC9PyPv zpg09fK-p7u4Y(nk%{p^FQF{)-ax|7(X=X7=7A=weev#?!WGJ@`^J!K#jY?r^CZ#jK zUA%HHu5p5PA@6dc5VSMC>VL^>#A;B5{Ni6N#t7)zl-tsFK482I+|X?A9uuyxkIyJ4 z^Rb492H{3OIjbmh0WF2qhs~+uVPyfj)7bCVbD__IH#plCujz&+fK@%E`eppYBU?@m zFth{!I^7LV_zp>~V;ww1SNZrAv#GlY1z~|OEocyUnZs|jGpwRGxo&myn{*cish^;K zBNxZmXj3xkb$$afh-1gaJe#1=K9vhvYHVAnLr=<#)%K_abkWVTLduoiK?)h&6&^~d zP|7gL+NwJ`-W}>Km{Mw^j#0OF*Hev=zQ%~Cue{<`WY~nx8%E3@Gd!MJ8&7q|YdApNCnoBfHoP8h^m!+PLm8+~)H%VncQhcv z5@=iDI@7j>=imY%zj*yE+CABo@W&wIoCM=K;@@y-MZ5(62e$}rOl2A2S<0Z%Hr!^e zzQvZcl9&E1CYL zPQ5qihx+jT66Px8ok^HqQCt!R{t?co;_je|0+};`-12Z%4&2`uXz^IQ zc9YjBF&+vO&W1H$^lW=dTQ?$GCiBMBV~k@jTL`b5?-!Nengn4rMjmX4^kWRL1x3+f zRP#?HBYla;fadn1#qrc;WX9~8wPr|>V+^;OItE9E%w|}+Z$`0Rd~-0gLvU^tY~F&M zx`8r~0g!dV9Cm1xWaM6_+xgE)an&;r{yD1QX z7Y{$zA6I# zNOINf+H6wb4&a+(>_0ozv?mn>Qo}ZaKs=_oa=kb2lNF*9oLhfr=YcuHNnN3Ui`C#h za{AlfWqKr*h`b6ETtJQ(2sQ66^Ji5L;-PTo+WJt)B{`recGQ9R2zQ+Afb;KQWV(iA zW`0*>ap_1_Ng#r2L0kM&+h~W#6Swh0P%B>wnaXtn6z|N;E$#FFsjCn zAG(h-vlMDuCt3=rC?FoBlEy`wcFnKErCB|Rlz^-zJjkE%oG&|dhu85fW*8e|CpsJ* z>ig3SenZ+Ymh`a1(F*IpC7*5LB*JW4wh~BgO zQ{=Pbm;0!bOWoqg!gEdF$_*lO>D*K+Yqbej;U_#DtKIC)dypkngFody`r#z_1^$#D zNweUXDAK6v58?bvy%nc?#H`f z8PG?bsd)lVoELe_UP!aC8qC_zD|6T#3|GwmN2x16otIOE9b;cJ&k;YwF8YP>1o(m@ zKy`|G2!o6!Gc*v>Hkjg^zCjbpY z=lD#Hne4MUjaih}#M-D-IsCGB(@qlBK@U!7N{Q2eCnMZC=*HYG!gNL&=APNAB2U$! zR)|74k}%B96Sgu_^$TWY*Y)h-TGR&iL1ph(^{L&7lLN8BjJ|~=%}x?QVDl2d!q4H5 zkelcWhZ_0D^=aI-2IVc|g(in8PWFC^=eu(qTWukWWRcDhY6y&r7(EsQ*z25D6Y89~ z2GnNLfD};YD47oAt_)WMqpp#VV<|uPBcAYhM6HmlQCyQWK|-yQVWZspX505 ztEE6QXz?n>%+^sD?%TmXY(mlFKL(gAZn$Y^!cP2W{@30Dvhim7HTW8D)DGr|iM zmy;^9WJaA(G(Q{?R*0;ocT$mAZuF3eS~KD5p(pzg=j@Zna|I`A^O)GPR+}Mn!eCl5Y`xjaKcsmffc&N zuA|lZvB)T`?`^u#V)umEj$%ViegDO`t+cb>=TKP4ui#@Dkju}pn_oY+@B6V`@5ZE` zOpRbu(MVbB`VXKwxI2~%bdhdqdbP59%$AkrlI z?pD3Hmn8fzYVYE!WJguhpqW_41_7)DM9s^5KIy2g;(Z7o(DtV&WV)Bbl&inFs!~E# zsLI^@la+fp93~v#6QO09dg2C(wX67<)!UmtomY%faaiF;=n24mta{#0W zUnt?hj~^l2G^m}R9Ai^_I`7I*tvZZEc&W@>@fIemJKfTb52DAQt0%krRRhZH7})1^ z9xb4R3@1RaLGs30D*G#JuLU0(Q!g{tKK$o9iv+=BM`|ZnI*5oG01KaV*T!!b@7nAqhJq835J%qDr~1fs!)6+)j-Tv=OFV@Zzrswn z@{@8FTl}OdAzZd2LbEJ>QgtrH*<|??7-9Xd_Hq0m)*8DsHX(M|r7QFDBv#X{@iY3e zbszIkYEwwES^`D}8VIzf^-0AnB-8v%_NJA4>(fP5AW|@AKcTh!t7ac`3{(8`j-2u% zdRs;=q)uj`q>W8u%tf=^T(s)C!`Kjc(Myj(Aq3zp*^_x_OzllQ0HvuuqN@<##fh6h z8)Ua6^#Zaa)xYZ*c2{cF?|O&KB4yUx_Z3-lP7O?^r#Dev0-~E_KsFFl*uNR5RPVz2 z)cROWe~c+7R=Ym#UC@iIY^1uMA$#pJ-u%yiQDQ-1Peu$lrH4lBAa^3N8r)%Yg)os8 z8uEtJ{S4gbB+C%LYGEj^w5AAIBV->(o>~XK+?d+dka|D0dh4-QEDVT_mV{d!qZJ^E zZ|WB}-^6UJ6Zlim-}qv@27OC^OY#kiGUuy!FwYJ|UPH$!=Ey5CYJai_#20`XWVbI^wql`K!Y*SC-1mYp>_5$!G=|Qiq%Di}Vqs88Z4E4R5l! zQdp9q#y?H_u8@!`=H$xsx~->hGNaMdi^LL5=ddUX49<$MTG}skV@Ty@?z#fohwPgYks`e|dw$oK0oRR3DfCZN>i)e5eDBgVz?I{_Nc10zBFH zU{LVOzNRt8xc5_78$o2|%QKwHCqs`$8$62SlBtz2ATlGHB&dqy@1K&s zb7Bx@JhlF`jWzwdRyZnl3@*~0e=W=6>{*U}1HuUPbhZY-^4#g_lA9SEqcl&?F$!y4 zu?1pbNcOH5g^=kZ=@-SmM6vYejrddVGGz;SH5<@NLcWFeZE(E1)@mzE!va!l0gg?` zr*%kp1Ixr`AE09~Sr>+rphz&BxHR?X;S2 zu=ZJL%=(PIH!)H*%^TJ68e$)L3o%t8V_TS!8>v$<#ZxzdBL% zyZu$`QMkW4S?PoJSG(0=x4&w5$nUSl&%R{vX$5vSIAAr6P2uY8na}oZ(}0T*UcZanpb&6(`Q*4J+E7JThvf!;rn2gyL?OQyEsWuvoD26sU2 z1j66^9p`A>4LzUvE-%@ahN6dJ4?-EhJ8E&1P-E=gzDP*^RbD##VcHDFn0+h+R3*nS zLv7b7?0xCakv=jWc_bOxaq{OZ5_X(R06Q0er3Q2`?KH3tpkoCUB{58jz3e=!v32py zs6Wi)_iNrSB|D@x7NE2mO>_8+PY)#{XhQ2*mUpOgmWe|W{!h~TByIF_gcWS2=9 zcczZ(;WK#5R9zjC)JBC~)DR2IVJOpXnxa?-Ek1C)sm%9d7UUZZW$IK#x{-a03&)0; zb!HJY9ub^c8_=o5vMLS@#xo!Q0zu+btgyE9 zk<1ax_OCWj5;&?3S2nr2Wk8knYaSY6CuhCGb~4>l9SR&NWND(0MJK~!G3VMxh{*1> zH9*Xt44Vi0%WV&bJEhX9M8}xhBoP?6L)n<|*zAawE+Qo7VKTv2EY*9(qDEqjpp9Xc z__R*SXp9OU(LU$Dn^S<#kZ^h(i*@qwL?5SyIsj~NO^17>IyZ9rNbzj>Fp$7Y6sHt`)Dcl1op;2}aHM#3C9Glbt{N61kN+6(%m|o}> z)Kb2tQK!>dL*=W%FDg|E%Nn=c%7#SI5zKD&LDtI5zu=ES{{?HPl^{Z6=|%}LQ+(7I zYK85E6?KNxqzU0ffOEq9Kgd%c%s)v~+K?TgWU&}O1F8u2O+xO%8r*5aP(!$wQf!SC zooH$VKmfTxmop!2&p{`UxE+B>TupaldJ4xI@YRBNUOde(syErUQBJ&%#AW-~%e%@q zM%J_c05V#b?>PUgy}J<38Z5QYgftCTp8x`yLWo03VEZYuRzPQFPRYwZgD|yH3f9+9 zrt|ju4a`I87oI)=DM3EA+V0F;1~*Gj6UYLko8Ne(n^v(x_cju}G7t`lwmz^TE<`?- zn><{a=fQj25to1mf5uy$2lucJF&^xg;&@OC4iOgeVZ7tTS#v0%4R8}wNNgi=)O3MU z10-N37?b?QRAc}eWUDE#oHV1g#1kZnQVsx~rvua+Y3#yn<@B|oNKHA9ppRo^5FN62EZUi~!^ zsAXsI6R+tFspY4i^V*< zS?s1@BZX3xnY}ntgz(n;=V{e!h0Oxq_Q9%%G=F)+IH;W}bw2X{XSnxj}6%SVtB_^csAcU^EfO zx&|`Jt*jGEj{GHORSGW1RDv>o#v*Ic>s)(?1OanF$H(wK)ps?=fe=6y{K^fXXinIm zWsN#qpT5wIzP4u~bd$f`FbZrXwj-B>ZrIV0-x3K0CV_xmxUU8l$zBSdTR&2pslQKM znSVO`2l{lznz|Zozf9HPF&EbOGMo#bBCrrsLR~!4&w@J1w2c=Ys4B#OrY+ENS&w&4 zXE-K?ayd!sW^=b65=&2aJu@dFS#i462zc1TZ_Sgb_k;`W&x*@jueG(^g!Ij>xM$e<}UfhV_Iz%V%uHxf;amVRe$*Jy~AbeL*3)Kx$*Se%rUCo;s*t$2!x51ktUA9 zG;5FiHn=E@`z7{dK6RDlZjx>xfFybfb9d%*FWQsY`^`Lp?It0oBZqEP))gIV#}cmL z0waC$_7Ofg$cTL{@Q3p&B9cCxH8OHSNLtQ!lgT7?C;Q=qKxRtCaRFB&tZk~yblc8w zShM%<}qV^JOZjgXa zVd<@86(36Roi#}DoxdmB$Ig6iz6$v_o_aO}4Pp@{!{t~=zd}N+mQbx9rD9HZNhfJr z3(XZ!3S5Qa!I zrUjWr0&-F7nOClqSBP6wsTD2FtQ^FkU$?{(>9EdnbhGmtR>bHgEMj!CUy;tB2*lGv zkx+#dt^|0%oiZ+2Y45InE!86ZzZ=Te?ElBw*}zFzR{fuWMKM`#2vAeht=6X<-@trh z%W_9&Y({65bWtc&YSnnmifmCbKx}t`akv2!70Zgs%F@c7$BNW)d0iA=023ET1qBO5q`kq1Q<#Z{t6U)~>u3TiwOjiOFgM%B$o&Esx8})_ob32sb?_9u#|kKFIiI zJ^~dN@{3bGf3M}!Vy^XuI7*D9-+Csf>c}~!7@Db9yP-&27{zlh7k^m@STKsUEUt$R z{x(+%KchG@wk%pU;~^>4C6q|Psx%SXl88SeMwUmaa1JeuL@bkAfmK&7SQp@kyO2?& zCQf~0RiW8uwb%UC5DM~6dg8_dyp{u?4xq?+d-33OZMe`+ekdlJtYUVS18ZWe5gXKte#=%0QxjO|mGOM#Q$MwtiyR#?ur;PqQSr|hZWtb!^{Gmz8Q{ky z6U8|n!UA7P&>O=xvMew#cnjLRKs~PUeWw4x_pA)QxLP8kR2+_Av$6hHc(WplWkGE zt|{qo9JFJd+JR{)NQWv>6iqX>kLIBeeG?O+?h!8JxYhoDOfH#QhU~bV`!cs8TT5@i zs3lwLzoV=U( zjuo2eMyo*4l8Zdi)YRb|%7osN3xSNQ3xB|M1v zQA_HH@pB#3z7=Z=cb4!GDx`3gk?L8erToh0`5h^%=(wg_}>5(HFA-PG76x-mRPgTd<4HGe&N!V9o=UG#cdWV&`j-6 zjm*>`dJ0`I61U`#iaWz8HUcTGM6B!`Hi2L6rdU~THp2?6_#I28S-WoPBgLuPRZDAZ zYJHoba|H3Tc`^wU=dARV3`R(fpuMp~26zvkzBj)?p((cen=hQ$((plW=xq{nc0m^> z;Yv_$(Ios4zDW6F_on@ZJShR;>})=qb=lT8q`&s?+oa1$A>BH5@8!aqGIUz*;@`qx zf-(4Gyq0Uovs+k8P|D^LMox+g-(Dv7ybj+=fTg%Akz1SS+6@Y6c@h|s&cIM_bx^?k zKMry@Bpu8rHIot$Nhfxooq+&=_+hgA)Mbs9s0!c&HzFV%tSLNH2N(h=0R#yf_IAAC zEO=x8Fu0NTnF%`fZiArQ#NB5WahTba$cv+7$sxCIl2MKUU^^I6! zk175)37UvD+I5xZuqs}FGoRo;z>e~wvLX|uA&MGk(SM-@jGq38>u8ql8}2BrxUmWa zrCu?+)cDfAlJSvNG7u8*kEQBt9UmS{q^5E>rRh`M91U6fsdTPuN*;45rfpBjQgTD* zI_`R_!P6M#)&iCgi^}bzzschrz$)Tr;1W$9UkZzKy*V)J5QKNYA<1bcii0E(Q_I^~ zSVRd|FN97e3Mapwc$635&dpxSVO%LLFn=j`vgBFUD{^s>3%=77>|UG2GtzvJU}zUdxFrVO4)#+s z!xrLRqE%(>Y;m*Rrl2NlUDR_EpmTZ(dogqpxfN>Z{7W2n0>N@i!(@&$B`&Hf2v(IS zsN+;eyNh`d^2$YSdBiDQ?$JGABFH`vtZ+W5Z|o?{re4O8{)%OjY^zkrR8kVIh=h0A ziOLf9=#?A@g7}&QP>!zcd?j9iDSt=Q7J*R6dB#{BY!@kx@GGf0#Ym(-9r{Ul`y9$* zlSr1RB^}0vkAr{ukchUOw}gK>on8QTfTdUyIOUrz;h(TGiufndKEyw18%BtK5?ea_ zQ(v8C9VGN!!at2P{FAJkqG}6wxG5;*5B$kxXcKvO1%UD^7xPnchNc>LH`hRg{K`38 z{NLiAOe;{OT2!HdHbN+qdPnF?2eN^5XkCjwjNUxAG zg_r5$zu;$N(62$qNwY}{6xCWYKT;>Zn*_A<2&^Sj&NK`d`xZI(HRu08AHXD4>BZp0 zTe-%w+t7+@Z+me3=hP(kQ9|zU+9#S$pXBS^uEXx?Bz@pV1#y31*D3}|QyRu-->Sz_lMWf!SG~9h~PRduOEso+gJmxX1|b~ z*F(roKvsiZs2z@~C(lUS>3_|`$YGoKuxnkW>o59c`p;!cj3$S;n;gO%2uqIHA4X@- zc!$yX&OI(e!Y@(tXp1`cQAuwwi&?G&DIvT@eR3rpTUE>)R^33@(CC5IrXui z9G~OEkH8ZZiZFN%fUf0)B8C%?UE^>$D??^Buj8E#kn@CvBD4efg-c{5i1gBV#7`C!(K#<);<&2Yx+}S7ov$CVAVKF0ETVJxOtnm-7CmFpIZ%6y<^(@h z5&s&UBOZxSl%8$*!d94YjB&v za@cG%{Ck$w;I{hQONx@8@1J>`l3S~4OK)(>a9JTP_QYBRpxM+q!d*%NL;Rc^GD@a` zmsi1yI}_~{O0*-hKt7MN+biblC*P#m1+CNvb8^FHqf0e}0_;@GH@preBIYveV?yyC zgspH$9Ub2uA$3$5P1)FBbH6!VLS-8w zb!@nYjW?u@&7}^h!(OuC6dNIRgt#dob%Yoyp#*d^x1j`nMJ4zo%8@$X?Ss_W$rMo9 zU!WeMW9rJ_IyNV2yN}w1E;@=brEe1abvmgL6?DH-MftBB-p;`hyvb;zs^oyz0;qQT zO@`ok;t0&tr@RG^9V&LZ$5d{7M>IUkFJ^dP8fi5wUmMBBcQJOAsFm2F8K*@AkF6j~ zfS5H&x-96G+NcA)m1lWyGs5|Y;1?Ga9ZdToc-T6OWqJYi{$C<^Xc79QH-ZP0k#nv$ymR4Lsa#r^&JCXfZ)%7NRam?>|5?g}5+aB& z<~lisgL;&PmaTeQG-~57s05lu664MFxekS&jfD*nBxy$>ALLYVN!C{%ST5_r2bE-f z3)Y*-`m(VRBFLTB2E`*p&>eiC2#u*8q|R!j>uQb=K~j$R)x&X)P(iEN!J3VAFw?kb zZkDx>=>VlFGT~x^elN&esEH}G&g7h&k6g1RR+1R$;h#>qjZUbsadWQ&tb#Oqx7kDMjr81XNP%lJKSTf)0 zk-0%tg%CkZ7K5Ar6GV{q88=6WpraABazv1d^;*^x5kV(~h#=ipxNQH3AT`S&f*5@e zLG>|g%McNyFbu+in7WD2b@YIGv5?!p7m14@f;RtqM9}tLh@gmcf01lEMOt)f^+5!Q zR6+zr6zGKrQV&DAO2--^$nqcLry|I1sbF%W0hDHlZNGT!N9DWtqe6QDf>O0lcr9lzP8{2pi2tPw5tL|ttqc;ROlGP` zldQ_cG&g&EfvjR@j5{kb#01HXWu_VfHpnnR=zaJZ7o5rXRp&bySIZbar!M*(tQE&CdRzS=Vz4=Mmfy z|4O>W+o{}NiyQ~1h>X$tFXH14?inEHBhm`FjUgatW5g+96WBvjA0~o>S34zm1|+8u zYPK5IOhRAiB?=9mKq+3XIZS3?t=*0?qaQqU}7~C zp1|WHdPC>JZDsxy8RLbs`r?Du7AEcoAM|$GVwL*^24O<46YRzx`LI|~jKofb3;gPz z2$69wKf&BA04VgRkP0Ig$^5FgEeuco3j`2R$-&>T_$1-UI~AU+T|eUyS&u5SFi|c( z7!V_`P@u`+Z5Hi=x0#g8A1Xk0h__j3gIzQU{DFV{409|c8uz0p#C*0+hn?mGyU&Gr zB7D~}Ri>Sh2W!3AUNM_jwW>6+XEn(x(jjn`gJd!O{{ON7^Acor0i9Z~V=>=r<^8)&Wy$FZ_+ZmqAg6zcKr{Qkuk> zmWIDssxBG+#ta-R%_OuAUIZiHRNEI3)g(LVa z_>ECP%W5Yk%;OX+k#Oi6`F|p1Zs;3Q8c3<*D@tgGT_ar*`X-478ojKxLHKAl1NJ~0 z?uj#!5{Dfyj{IJLZz8p?rISEep%p~cM~cWPe!QR|DV7&Vn7NRZ#-TGzPU?Bc3!9RN_#HMFP5mKrMH)Pk zf?#YJAwnt$ee)~OH^uUpag-nIC6|?G$Wc|4N5FtQKrWGoa5!oB+r%nbq530lV_P62 z8^SOA;Wo*MXy)^`X>DH|j`Y9Hb_R2)_)a+6{cAAJozY}>M-hvodexr7;7*}$#Mlh3 z1fJ;B9Hpy2BEhK8WhsRqQ&&D=*~Yw!SZ~9Jn0qS`I-C(~x*B|^=HPPhO~oKv$KwK- z!TVn84O*o$-xY?Ku{MjsQBwB_U2}nOU1(5#JO4}@c9V|~BVetF5#T$a z7%EVWYxH?B^yyY)$=udra*jbpAHX!s?bn<|*!8n9^86^&oR;i>3qwErgo3ldLBw1tt{4JNEuJ9KIRAf^v~^Kbp`tAH=h>!g%Eqe zXP_a5?PC#Q2I^Qyxp8%*-<5%5J4GnE04Rp7z<48c24z{anXH`QpcJFc=nHjpk_c9p z4&gJ$QoCsqzhM|`qEs9_9t|-Mv?q=xWszlNkoQOI{S=Mn#VSPu&7C;wK1YXA|6Paa zy;zeDinZfzMMURY-}PF~ zP|*_Fl?4eSW=+yoEi=VSiZYME_>jq`cXHbu6l9ajwAIEfO;UP<4A=YhP;|!VdcvSC z`LAW7nQL$9fI&3MvxH`bD>Ne-k@NQZ{6W2ptf-HHr>F?CvpV!Pufm{CIzgG}gdAV5 z>vJ&};wI#>{T8hwxhmN&xi#_aXanNl7cM7mL|I~^+;g>WdGjk_W(l%*SU|YkPT^ow zZYH*hEIYX7Rz|@+l`PtnORVUlP8%eOcRLRSPZIiU*fPtd>S9Ygxkx@~>2eT20ZD$y zFDJubOt=OphYb7S-8v_$O_Ej4Hb&sdr?awmJ{@p`(>Y1l?a7rUS6j;ERc#H9naG+E z?B5!GD4EU`h$c}DWhYh3B5+v#VE@bm6ezEKdgdhHBW*krCQN@d&)M*W+?ubxOPa9Crg0S1Qe zmr1|8qIdjUiyjxX7NH6o>B+wk2_i)P%Q8zAI(g+72Y%Vy*u#=ZAcf~@X<6gy{evj5 z1m6om6z;G#15pgAEg5d+!OE@HQhoL-a_oF|FW`|m2odT0l5+-i9_-@hHfK{`Z}e*h z$nML9vCPa6R^#|SqCfX=IL5FS+ey2k7kR&pKXh<@1zjqP((xAJ{&eHvKr_NAUB_6g-k;N{Lewm#$H{^(qc2Mz0&XixE`)JrNn z88)4(9}?{S_G`A>2%BoI1KP0o3?e7FcE(1c8g#g~s`|WjoxQa(_#=;bbsnz@oZO=Q z@~PIpdo9m!A*Oau9-Dd!E1SNBoIoML4U|C6`eAA%Q&W!}ty0j&_Jw`w?9b~;f|If@ zyq3#M<#Hb75O7m-ALR>3I>yeko_oDLt50*L)x1`&RXQBnvvd%z6_)Ui;gRcy^r_=} zr_-dr-)v}=)>HUEAM&Ti$kTa^)@OY_`EPyl+whZvcy&MToU3>I@ExJYR4jjbEYjaO z%*mH-5`gYmN@M|cSX6yCe~YKoR!|0{*1h0^cNFZD+9muDq*IK-;yB`xnutqkTn1Ji zMO;!7aY;?YCCvU+qSiin_WII)=4p=pt7bX!%nJK~==LlH*we3I&{jGDxT|L=`Ca=J zPUot${vjZS4bYk**XP!}vFXnsXb`lFX&k$Z|xEq%p$XGc>dK z0LiZFJjjhF#|tL%71c>hOC-Ubk`J3^Bx|>OSw#Zb$Q5Qv!H+`-=>{#Ni9uZvu#ZPg8ZH=Xor&>-P8>@~qX6JDUTqDL}c1Dd2I13e^JsoWch zheZu{5WJn_qE00_@|l9%zDr`U+r3*p(jUIGL!nM?qg79{`dl6!GSy>;Okrh6Gl&Z| zl0_N?pmSi`n5Wvwb$}w-=237iNXECPYTxh{JWH!6XpPsrmaF>4r^tc8*w#0)&U+eE zRdxVCdCpJkkIP{XakT}QjBD#jH#sLn1rx zN#;j~?4(-a42GlKI|D4;>bOCsFJwTOoKoUqOiyQL2S0dlw1)ZnpJgKA^0iq6R5w0Hu zMcK|XVUyWt9<}QG7$JbiG+N*IFnn=Qx3=1H0wgC7UjDews`~?*ZaV*P^+FwJ!pEy! z)|?BFaISWHbM84foJ2a&DvljubTgHEGZpVLcF-iD@NmAquDoh%OL%s869 z0=fUI?w)uMcX8YOH9cS={1M71_}8>wakJi@Qus1_P+Sjjg9e?t*iJfW;5?;Kk9o6y z4>Qvn68mhSS~{^>QLTwTr(f$Np~;_hLywKTyiQ}pPN;To_7^FZUu0)D0xk1Kb$D~K z_WjU#)r%muqEC`C?euB6nb%7))ZEP~_YXW1>m-_AXT!nWrugMllqo^A6PkY3oeGa| zR;Hu?DNK47v|*_38bzlue&}BfCDbLnOLwMpc+PTJ!uGv4^g%1Io_(y18!qsZzwb`R zHtQ^D;yx7%!D9qRpP(R-4v0p7v9_>6+mgBa?ZYf78>fF9WfBQ~q)enp5+r2E4v@kk zzBh~Zg8W6M`$I^P4uUBTEv8Q8UQXry0U<>}_9f%^(X3)hL|0zx*X?&mT1R)I@SGp; zzzJrDH~TmIaH_6y_ettK-jfk;a}|8-BwJXs@7a-?23vj@GI$R)+PAi-9{G=;)o77& zt2h5a+D3U0e-*A_!s@T*hhE@c`|ECYY|cM}enffX^S_9kMh z89~u>`tQYrrQs+{qgM#n>v||&9rdI)`$e2;Na6&faQ*d{i8W!`j_YMZvq_>Jx5Xl3 zO}g{oiAF_Q=D0O@5q6+QlBqEJB`!H@Jy={F8rpX+~T)Eg4?urRkA0HCt-%zBm z9NR9O?h*L~%dmDM&L|wgXf1TAZWo4AneKj)C-se;s5u%_m&v_=+vA-~;|8(VH0iiw zkEJ=LruU}mo2 z3`!lEIck$P`}0mYGdI7$WWfktzLpa>dY9ylYWL<$RgEY0c(+{3MWmnP(3nNdrk*A- zAn5t_RPGgxeKPmAu*KB&)C~vm@r{xc&IPG?N$`;db8q5#ZX$r|`ZQtWy_AMu*yfrw*Xxwd%XdGVR{V%&wb4UbE@@#zh;|I| z@@K&tp{*uE?KOI$fn$_3K+(9^uF)U!tiG{bux-YZQOm~J1ahHNM4LtprO(Nh{fY1V zz`_a^Kfu5l%r1=yPpLcETX!icfW5O!8(v>3e3aVNUJ+cQxG&LX=Xu4e*;SawU-Ms} zU&-i$R*P=}E_s1Y3=``}9`@2ZwWhGvJe25T`nrzO&NOhXTB1-7q}*IML8anfrzh`Q z-b`|Yr0V?hdPuqPvxi_3q6y0esC=x$d!2nw^r#+A9OG}cbkZ%^9{I#&Csr#USoPQc;I9EYK2e?$`z(Gr4x%n9mSTH^zpEytM^k< zN#pAL<-iD5hmitto=0^>_KZL9^^eIa!Y!SZdWZ0JkR@$ic?imCB~@iu{e1lpJ+&j% z$Lfiwr`OW5LD(>v;&$2(CmI& zmjny`3nhLzc!`pKm1*u%yr)gSR()vfn8sl%=Xrj^y@NP3<^w) zu0LnDJt4Yz^d+o%nEf=kF3GUFB`2HZ`euZ_|1f}{?xvo_FO?%n{T?+rh)AF?s^tr6fO`_|e zVUjevadK?1e7u9#(V;9K=W&&3Tz!r|{AikxozqQtknhH?q4mq8M89k=tkq=3x{+Dz z&d%zPetd9VHwzqKxy4Ux;d4e<{B_S4PT(>culH%&5xv{Co8fnD+s+kj)4=YxeFaq2 zDz&lQUhLJz8vI$-K7HN0jrN(fb3s_ubC-d9=u z+4&Xi(w#8Pa+qd)FQ!2qQ`xSFXK=5T4WF-aIYN5W3eB9HVmU0V@L>D9yf8p*DGm2A zIB5%S@=-FkBN;E)ApZkBU)W*|oTWyTJsPD)Z9MAgC~SBwbj0?~cb(2{yqJx1W5Xkb zm2kSbw!fU9+B0YQrwJY)`f0gZXK7I6XIlh26|-IRMDy5RG;5VK@3i34 z8wi~rz!;u3kHWY$#d24Cf!bv*OwRh>KzCh+Y5Y$FXiBKiayw-Mju^)$tZ7?mpxEHF z48QfDGOY&`hLEOM+D+oHQ)g`H=Gaaa0psx`wj-S1>dqf3^;yM=ggkg#)$AHlo~QF! zOzwjUS=+MtUqm!|Vg)syj?WCzG# z@qV*C6MGA2=RFEiF)zH0rx zCc$a9^*J3zPD;1&@9D&IoqV1ha4qag4#B2j5J&BSLYd|_NY}3c@`m2ytp8DOGSM7< z{ZSDkFyw%)7>Fy6VIBV_Ovd@Pcp@h7Q-L$)n)A3c33D5X#%4LWBa|?cPbi1oBBu~n zRlydrSRe;7hU)Aym41Mgp~n+{cL_G8(+%>fJDq@6-RXpyNGIS`mrmHnV=mE>M~C8B z^EtA2AElPs25kn>sfJ)Fb%x*XD1HC&@NNx-kUiC! zLIdt}C14~34}8ddr#DRbOhhmGBfjb02yWG5^17(~=m?QvG=^&x^@}bw=5PtVwe&q% zg7#KDth4{O#_^Ul?Jd3z<{YiA?Q-m(^8~KvhBs=vH+zH3DUpH-OYeW_NKDT^@Tjz3 zyBoyH7 zaTgA2$sGr$;ld$ZxVWc!t9$2uVoQ&cYLVQPlX}=-9aa5Sdt%7cogI!m@ zwzoWDVrOrRIK|#*4>t3Z*RCb4iq|rOg3agrQ!WsyYq4)em48cL-aAq@?~dR{e8}S= z?E|1x7}M+Evp%ms&FdP3>+E%}MQ7GCfMH1QZq+jYKS1l{?Anu?^bU*>7b)^9zst8l zd|N3rbUQcD^lO6Q+=M|twOFOI+;NqnR|yV9Vb0IGntA^@m{+Oa2@G{!Ws$9xnIa&~ zNanA_`fVgEME5^isW!~Kidc|sUICRsZX}p=V)b+j0FkA;3r7n|jCInA&WeSZ+(sSE z1{R3Q?9hj%>gh7byU+HgpAicNBNZ9{5+xuXTJd1EcIVV50i0DCi`Z&%;8REF!BXD?5#{ar+mmfjMJ;92P+RlV=!;bf^9T!I3Z@6B-caNM9?=!bJf5$%Y>ippd!KsZdAbSN%|MmeI!uO9>e_kI92tPQ359n6ki1rx0 z^Wqm>p~I|D%TS3m}02gmq)xefS8&9HW zvPR&uF{Yj$GWC1c_lh{qB^D+DyX7V>#Kq%F5yu~5E^g@jQPDrZ&o+#;FrIewAk?)t zYB}*VB5VFP=-tlT_GQ5_vDNDd^&%+Uh?^70jl7Y{y^x5%U=sN*gCMOxJOMHzV?{EkzA0?V7-qvVZxF^nET7|n6x7Tohe*C>$!SH3HeAA{hj32k&t z<|IVo^+9T(m_@OpB9|1N#fs2*a=j|y!^+2oX@Dz##-FgVGfI_-CsZMhClynOB(&Io&vUNgle$^R0~(&C}Q6tRKgkxylg&_^qO{V`Ib%CLIQUR^A`Bw`~Nlg@1cvK3*qC&UxRC)(rnd+Z- zbGI0&Phdz#XL+OccyrFhCjupV#f4m1IQNOFe3}<+Vz@;|3pn9@jqvsK>hX!#3yJ1# z1oS975XRaTna$QKsyG(u>3Z*69oZqU0D3AQ@@QV>S%bngt zp8q|bsqFZ2h$RO(fu5W3T0DAkTjzjuP6zG{89Xb^A`(HsUonA`;|cI&YL`vjR=Avx zReRq6PZ{-Q>vRaZ(pE4PcG7d+EfdtP){FIT7_V8xJF;I~FlDtHkI<9-Mb+VgDMDyK z8C=bRELCFeqjGlzS0h!ucv>9OTX}>*lt;S@!ziveAL1{>_`Zd5NK44NQUGDr`JAW# zMI??W1GaSd4L2k5Sp;|wRTU;n*O>gdd}W(xuRM?bIeW#uq~&Q`rUFQxb~9A0EZIY% zC*-`joSZ;zMb0+jWgZ0=JLuFmPQA)k4?%C=T-m3S<+{F?Jzh1_zR^z$voA(|GX3-^;ujTsbOqt29;h7<`O0yTa6QXe5P1E3QO)a*+jl z3bW*)7JXcU%=|38&Q0~r#b54cVyBbE9!;?mBNKVA=sd@0$S&yRJbzry^ZGOtm@eCg zfD4iNwsujnU*RKY-G#a-P8aRq4~bqIw0mqY>XoTRMi&R@0x%+wGWOtz>`6gI3L^>G zByumLoCW89f}mVs6a+52cO0)2jx3K)lv%$!Q7)k^NQ+7)@BL({bIYh7bH$>JZlCQB zKc2=7$+lSZ#2YV*tr(oRk@qra=$m19qU<}1P9(yru6wR< zI+s^3EMG^K+V`Pe?He3^vJ%7bjnEnbplLKr%o`OVZ}dl)adjrdk>Q_`)0 z{cge^y}~7@svhb)p{zcJzc8}wcj@ylF{*_ak4m>*L0c5w;C@Lzl^!0ahwJqa7A#y3 z^ASfG1B>?pwD*puD3~%j45mB)&*uBP*ooWaBIi{bcX30x%`LcX<|j~{B9b;))#pe& zwmOSCb5^mHlt+9ho zHaLIH0M*ktEPpyDOD?LuhevVcmTlpJ%{u-=SQ_M(Mf8SzYS%%URi2mKF!1kO7w&|e zLjO0P=-XQNrRRTJ>myQPMEh29tK&}%IHPu%H~$JgiZ8%f4~FpLKtFeLI)T=~%A(7AG^Dbg za_A(DUZlkocQw0MTXD{-t;xkiwltYML|h**khQCE9UeBDAFhO3tzvSqMb$EGKVl7_ zp}P*WjAb7u{4$8bTxKGYl_cj?Nc|{#P@-!uyTvy$bpY1hrmezO2V1m6cMz`*o1yF# zj0@t7uL)MN9&)UeGR?B~z;IHAfEJ1!JP&S)!A3*1-D);1kd#w*#vl1{90F;kr7O9s zeyNwE4VjSkn|?q9?x=I^NmhRU%Cp0_s>DZQF~<33qV{Dr0oLGZbnv#2emYeQ>u5^U zc7TWrzQ=-$$)e5$Lv|b>))wPiv!Rd-8#-S-P{suzkFeV`Z58j*fzw{*FTsGYtLi&? zTWcaL2I{U-6j*si?EFp+rQ4*UBI+sFIkCEi*SA~#S%%^(t~?bKk(l5Wqx}qM z-NHp{+sxmmeV6RPykn*TUK+>00TtzIa0~;y*qwkWuC;S)*I`SIEf?FgYKAxJpi3oJ4e&yK99)8Q@ZMk;V}!lZ zAog+4RVO2N0HFvQrPdV3v~pVoMMmNnFSY^977YsE(O^pTPVXy4dv^^hHjPBr2f)mn|&s50Eh2sQuu#8oR_nW7~Huz)va|8;<9J4EW zy)DZtN2%DwX19*~Ky(@)jC-D+ytx~#a(5VCuL{1tbFUq2q;Vz)io>1L6Y65>6j_Ln z(~p}fTBfs7kX0b*MR8^Kx%3bQjKnpWKT=>wXk0%!5nrLPPNSa=|@`b0+UU(o!_ohcrfE!8- z3#|dqMdbW2Pa^qzKgx-pj1{1u*hj3_T^s`=U`SX-G8*tF`l(8zv{NL;EI~c(i>!eB zFvjx%-lNdEI9UhRL@j~T;yJfewv74V80y@_hP);iX4=+%!JqdoS9%)pcYXkZ@Wrq+ zO*1pOwnM8*G}mIPNmDiJ=?x-?Fbz-dD|)eYXbDSi!p0lf&DD(pIj2KUpP8ohH{uz^PC!u(fnJlBufTKEj@5O>)gRdY@(#C6!4}?TCnKLPQguV@_dz7^bu<{bm?t%|9It zG~q?pnrF<0janc(6(V85(K?;iB>!`$Ije%ovex+{ZlFNQoyZ^8&P%x354kwIFzz-(TR~W_ZN7g;KXiGOl;tU|{+40c=FWoq%xW?mRUiDVq<-!5NxVSsohI~)7 z4f+1+Dr_+xJ!nUckPy3?Z%mqw@DyT%g*F)VeM;&s2~n= z!%eZT$Wz|hvy{e$PzSAq{mRc%x_k_7Q|z>0R9gx8a6Zp4i`N84a8ris1$r62*&p)Z zK%NPV&J^{L)sze(u_aOZE^i|eeG*g$-gB|v+b(0 zc}3e*kLX?=?rxnO!XADBQh_CeTOfyTkGHos2d`14cCu)oW!|55z8<*P3NsDeatH`E zmTZK|k;Twh@e-}V;RPm2kEfCrgIOxTsCcg^3o zp0m=KwVnp3H-OoB42#vLFVKlioJvNdxn6&?!F6!H_XgKfX(09!Y9hT- z0Gr1gb2~=w&Ckk(;mfG^M@~pAmbBaU#_>>YTI3&+~`RcbkpjWJAz$#vTlQaKzwZX*k=s z`g9M3rv4|N^Fa!^?Ys4OC#{kfq_p*T483$)kNX0CmJ0CmzdApPvBzHPQ4aBbg)c*H zxkHhM5JBv^&(=q)cP;UlE}JFzzmx!nD4{Fk9#AXNb^nq=hFzuFQFe z2MmWpXgtmjO-&$OG2o`5`+mO@iufb`mp{QBJDAg$n`w71V8*n~b;`!?)-R;^g)p z!-4{k^su#6>pt6md=(5@1|Wf6(HbqJTag1H;8a==Oxzw)E+oA++%AC}P_iss>V}k$ zg(aCLDd^4qg>E?&72jjPD#uW8I95^hRCfS()%Ri(g01jkanwAv5W9*ESu(BAL6KK4 zjJoE{o~0_lYm}IPb`;m3RPfUsHW|8Ng62};QNi!uqryj{_B#c1Iz%l~K$8jPn8Mwa z$&n?BjcaTbNK2haEghStVnc4Afq*OeiN+_npLg9jPmFa(Lid|G4+D9X(o0A-@}IzzwA#O@Z*PkioEf! z0Y9Am9$`OBaT)gGUcEpT=cDOOU&zP(DngKtCbTny(F^k7ig1vROL@^jKI*x$1Pet~ z;Zl@IWt3FK@FM&J0NjU(-y=)ke`_yA$KyF6bP-2?+h3A!0m%VF*cNq=l@CMvK(#d(# zot`1&#-7UIe=PbdkfXs5Ar!)aWXWU3>q0No?wawkor@NcR0Gs|WQ?q{e?hr)sIBlz zE|_0E!9mVf6I)aIH-v*IGl5$_+2-2SZm`10dWwh0N(V%_yISPaqI;T{2&wtn8=3(+ zf{R}(3Zo+iEe|=WmnuL9gdNj*F z*W2JQ_3TE|S7`R5^f7Y+s^9GoR`jq=4wbQt7=D3NRS5;6NET1rmSEW<{BV#ER6$j6 z8OS?G;3nh3cB0E-^<^O#BwP$g?4|!+ll}|$1M6OJ)2p=WctX%6dRp-B79NW9N&lL? z(Rx!U8>O$b?qp=>0p}F6wKwCZ`a94@Hut72Mqg&Z$~?TX^8nd<`9tHop;!%-V?~D~ z(h@bcC%6f^z;ww!8{cPYyQdPfQRq6#S;*qFaY%de4hIssn7xPPYsA9OiN3494j?iU z;z9muunE}@!e{(Nz>RQyB7Tvx zC&Ytv5P-dHKX{O6POym!- zFa-F3gntw5bsj@ow#FY%asZgDD16o~hC*0X7zisFmKK6wmTJL2KRFxQQ14gVmd?Ez ztbxh|SHR4U!HM_kD`*}JBxy}m2A<}PirhNoWv#P{lJQ+4R62|8I)yE482)-#qd=Bf zXwu9BsV8y#p<(Shp^B&K4GV;@dx~Jr(jENXlQXg9=Ua26rN6|kSe-l~>n2V56PXN3 zgR+Fb^|{U39#nua(l@Wvcz^!#D=te+Ok9?@JaNSeV(5XY(rB>Q25Rx`UI;gG3Us!Y z+|LUWmu7NLCoa)8D1SuHKk(zSKW^Nm*<8EZhIL8VPPyjS#;5Zx>9)f7s#{r|+xXj_ z;vcQQtAg`Jvs*2(Uo4KuuF^)2jN$l}pvK`qnnMx{UyL zx@)~TNjB(iBO4i4VP?OXi9Km2AGW+oo7vTyNcmsiTc6wG(vsNeVPEZUnIP-qD>$~q zIGFj0#CrWX*yb+Pk*OcQ1^$_d3;YwTH-F+&PIH_1a0R(E`q%qYE3iBtPPn~__~4r^()^5P znYo&7wc4!SxC$J_9FDS${6DNNV}`5l&&J}miY&0&&a?e%N8l>zOyyo8*k3Af>Tlss z7lp4$Xs(3?ETDoMW~-B6_^Y$xv~@HriO40xV2k5D-Lbc;bd_c6^}~UW6R7Z{nO-d# z5)R>egNV_6bfw{c$*|t9Pyem{`q)2JyQ{&PpxPPL`$S9E3V0E-D+INm6>9!fQ?OKn zXISzTl%6J;TUR)SkpR8-A%2$0o-T{}I~#?6%4Co92uS5O|JK}3+f+N~j^u3$9HypB z;;-U04{$$<{3x%lY(F<>c@)^ZY6W&^{`la56MF9>6;gwQwiKVptqi`i&(j?|-TRVT zWe4BT;~aYv|L(OM45uJy6gtJCH=ogOmH_goKMLD}gW_`Tm68A&Dov`K72e#v@QkcA zHNAC%lMBKu2YT~X^2F^UojcIhM=cleHQ%(Hrvj-7>;6 z3VN9L`WYA*Y>_l3b)W-i?qbS@4q7yjYF&>om7e8hyq$R^S-aX>@G>u_8?)8p-Hb>R zWm~6n_nRUGG%f&?zRc!cN4-y1+3D8Du#HZ8bsOfnmsy4!+|FH!;V920c6vu{!qBR> zq%w-;5(st^8si34KVZ^cU8h=+4eGo*H2 zHBC)7K9lyR-_GQJ9-j}nsaxA@y`eXBYtUMUqu?UufkM_*x_P%gcRkj47L?4lUAq#U zZ(aT&-7n4~iLE7%{j5*BjJzf=VLXF5w1fA1%`Sa3@IPPF`s=;m>v5-nk4B2i_Dpwj zppfHnO>v@LpYI>xdrK2IB{(T8Vl@pe+XY%k(SCS70Wu0iLFS&H6}Cb_h3|+ zjI{7ZBqP)L&TIKGcjE2I+Ew0yb}Gy^a$7x=U?^kL^h6Fl5C6Z=tO?VCi{b~+j~J8F zwO=DdIdT)`30agM<5|=`z*l;E5)lc&!`OlaSw{G#*4?ZW5%C& z^xncdjGX45(tg~+g*?YnReuYOT8y$^B>HWMHThjqZI*IMV@l8Z6+Xj|*#44TIU6H? zA~ybxpMoiCwr4m^_@E$~48AWc!at0_v7$8O<-+fjj8czH74Ka+bl zS-WidKwN9zoXDdhcT1Q}-Yrix+Val7nlS5L@V}qfH@)^g(M3vAZ;gnZ4-mYr$`5PZ zFl}I>cHN9acnEDAV4(B1*2fa2p~=d(J_#ay-igd7^7eg~L;(=bv3A!paiHyZ;9K9F z`6WE9W(4Kda3rEcp=XPH@T~8%KdeZ1J)^VG7T5bTyIslYWq%`g-^e)#%fXnY!_B`| zvPZO^Yexbr5Ff$NQ%LMv&sFVPQ`c!${h-F|>{!C)w{&g>i;Wp$;M^-ESE7fipGEcj z{nT9k7H1TmOZDovRBzh<%%Ehh3zv&oFyrZ2GQLa>r7Ti2i#OsMV|zh!HNKE;T+fmT z{?%^T$tVXaC$_oXpD2KIWlYu4)>H5BFCnweCMSOK$7tGNdNl#ZlpDBZvlI3zNhEB+ zRwejc&DK&y%~H%`TJSXaVuiJ!)FB7rCHV>8*^*0Auh(MRy-T&f&hrW(^r zoDh?U?<7of2d6hD?BVT=UdqwT^>MKdM0sBC?Do(oi9ZU;9A#g5oY?%Tj zHsdlv)vif%(owil*FwD{FAHfbz9B#rGe9woJ3N*DfCNUjB`{0)n?KBnikKC{RygyY3g1U$$|dHvnZ_eqw@6$%W>l6- z%VOH%Qc$EgE-6{N*_-$CP+WeHZhR~0e;#GbKCmXHjIQStCeN3 zgWP7MYAi;m6YCESsC3Mld3|AVhI4zNTF_GKCmT&o9 zMI<$7G7XX(O;N+x4MDncv%k_^xB^c#BQKLf-MYcyhht3O4UG{H^Py`7p zhjUvB0g)d!1mT_-y!BnScjU(nk-0Jvu>pbtDe@l>HRiu1`C(sRid-U>w(A>1oRYqc zaWMrEdnu{~#qiKZjZm1+h_xtGCRvbaiw#qmGr;hE(5tXnEce zwQF+hFQ8BCmKn`!^lM%Xf0=x}xnE*=7lsR%14QT6wq)*A@4|J7+M&~HQ?+b0U1S7A z6YXSi$e%Zowa3jkJ<+_or)hMl86~@H52PsFFFK$Kf3y3GY{c>(RE%yVwM!$+{tMhp zJ%bo1`0nF2Apav_tz`?{V%9s&yJFsgvru2E)@!-SMsyqo1e3QcHjSm%@>N~A;XDO> znV`%5yY3^TKSgczjpQPHF~!l}ncQDFY|t9Ioo;8k{z}YuPiEQQ`y-hcz8}&nnBTFU#6r&`=x3hpC0EB^Yi_R#mPA5SZ`*F#T`;+adN*24K`HCgxiQ> zteN_TydT-v%jx)w>G%uvu|2qt`cM6xNTiy1cQkGvpnwbZeh=2PvM-Y)ORB)NaZ z!ys_4AlVB$v*4&Y@fmi179$0X$a3;Qqo2OGR=i@j86cNUM|URc#TwnwKKb) zY6;W!?BJTC$w7Ql#NYCVtD!bB3GX;dp;0&$NeJhM=oy_T9K~(e&71d0h~NAkB)@wu3|7p!n3KX;D=f0UcKu zf6!lXjgc$K9T*~9p&4QL0Ylj8ti|D#`EjjLQMZj=;uD)@O8pwVIQY4|fG>#$7FxaL zuuyQ*ZEb`z2j08RdHFRuX%c8spgBC`H8MrEZxzAzBPlj1I;%7GR_{VDexE|s9hGO= zNHy$Rc;OYAi~Pcjl`2IwKrO4pn6V^H5i^F{Xhf47P@wPGJ5$e@f zsa+&=lNHPso))x@h?n&?>ZnnwPOoa{6en>MEE~9g)6?J}7RQAob^QM>cxnfz292>~S!}I+k ze7ts8B;su{j5KGmww&Z<$P|kW@4^kNByXx{ZM$iLK7ezg8Q2}IQ=EiPf2w4qZ$7?c zr85<)VZEl}-e}kd?W9AN0u{CEXL@?ZNQP_L#mU-dX4t*rx}>v3J*;8qm|aue1GOSzK#MC-=NpFYVXh@n`=*UAF_ZfNU`xQPdX5&D%g!&k=O z{Dy}IUa8+EtNc@?t7*Y6Z=8VAd(h}*;Cv?SBwD_SpwLsf$GzXIQxmJGWT$r=lNFOs z-ofv8Noy-Nolv(aC~vdt)6#~GqmubgbMOK?&y{upXK{)Y`)_*wv6Q28sv7@^Q{J+c z6Nv=Sska)EG@6#!s2YxwHJ}0%XZ^2LxcP{+Omk0c=EuzAl=Q#(&w7El zIK%JEM?A%=Oa6dt?XIaiYM-1wDv^8hd_Vbp`0Qx{LD|@*djHIMWKm7WcYtRLC-b>3 z*s^OX9y008*t%5h^65hsmdbPa#0h&-mmi_8V%jRJI%G z*JQfZvk18(V^D>L*@F`Pb=r16^k3Ak$qAMsJvbZ2S-7sA`V?JgB5HagS?H#u(PvVD zoa?1y&b{Ak##wWUf-Vvn?ayT8q!o~DQ__9$soTHB&UL9_-E^~>GP+>GFi&Y6C38T} zMB9uU0*_(tuhslnSnhx8?MYa|%SwUG!Y7TF zfbAg%DZyx8_Zu0J6)bfg%}8e+atdG7)?UFx}6b|^~ZPTws);N+aEcI(>Bw7azGEBIQZtzTN1=C{!V;OknM0@$DP< zU9$Hntxolx9)Am65_W%!ddcC zH^{@$pgsNLB8gS*Z9c1FUYZt+xrL4F^uhuyf?kic6H;1?8f1ql2)7yfpOjx)8`$P= zLyimTMtkYJ$ijWxEOVxFDX*Y%6XPd*);#Lt(*B9xpm`3@Ge+tKy0_Wi7E5?9Lu9dO zk;j;F&*9ztXczC5MOeeM`!RKo9#ye2AF1nT*4Bm1&1t|cql06+wKKBJ_54i=9TJVZvzKKlzaS>t^qflgb(C6nY>GQFI9W+^h-!b zFk`Y7_l@lXWUf3sh-y0*x%t%v<{oB6-mmj!w>Wf}z-hlc$NgDU<&Ha05pq85afzeG zapeLt4~tWt?Uor^=#t{7BsGJ-2%b{fYau57n`MB zT!*>dn{Tmgx2COq&s%U1AH_TTi(~OkMC(-))Wh9Hr$Jlkw`hAW-6g9Zo=za(9ZW^b zb=`={nsR6Rwnqcl_@IUQOYo`|jF5HQ?S)27BWuAuYlfNL?= zv(;vi!-h2n%mTwrcjEk*uZdd}I}eM6kLW@>=24o{mUEBGg=l?60i}^0>mv6YofcJZ z)%%dBitkna_VBkOnREI?1lRXA27GTs7Z8+t9aiU}>VUsMST%rK?Q(E+d^6U}Qr!^= z(2mL4S21;;jc;-aOwEXG{^SsE{%#e*dn(LUa2WuwVcXR|J$AaxiJ=;$&X_q7t}Zo> zrn!O*IJ{8KGjX-u?fOd5);@`CzeH?H%0IscuP}7^cn8zQ zdPB=>F)K3IIH0Ghq{>*FlcOf=T%FdPjvUxmS>6>HP=pdd!jMtq}Tp>T}@uH^wLBCK6}tj3~JcebHs52B=Q3XE@xuh-zsGg(rYNhF^l z2RqO|eXYjvMw*c8LN3c%foG3%?{Tjar{-;h&$XVs5Vv#-hq09R_1)a?JIVEAwKM8H zW{@+{^<dNKFj$>j9i)wQW> z2Z}+aLdy%hTzE@!x_3;{)ycMjflZG#V+3uZ@i%f+ny~y4pAUb#H6^Oa9V8GbtKf6j zPC(=iN#(UjRHMZUUV26CvfOHK{?GZ5%(1z~%~sNXRWzN11I*!0kt^8yQ(mjxo7?5p zudZD)V`?rup*Sx5swouo&0SqR%!B^OF?0ooSWoR*VqX#Y<18_s@xLth)(|XC777iw zvW6VoO2Keu1>40|%ouuguk{$I=PVi%dn;M{uxkVF2Il%^mkYuS*mLjT#D;2ho zzcOOx@|W|Ao$bOj-=L#-Hqv8BJ^_%5+GR89`&biFxFC+Im?N zW%GRJp9O2pD|wu1n2uxSo0a7T!w*^?Gu`N2uqILaq&M%g$gLVIW_M=>yOx1Y;*J)k zwY0#_j&`OQf}uC0)1smPx-Oq_gv&L(9W$cLW+@ymYr+hStvqq>jByr*Rm8z*aegNA z2NE5ed62L;^D3+@t{&4o%;bZ04}u=fUkRxQs~Jtdr5DVzDfPiSYPn`a`x_}BNwru_ zl$2>;QyULW)o8d(y97PYmz21Q!=@@a+WHk{!U}j+-+dVQ#rc6PGU7$9#jEgS9q)_( z*6Oie`Go#Ntm+h@td3yboJD#VH((kodK$EgtjKk$1S?Vr%JiBI3~4U?6XahoVbCC}9f5vF z0@S?BOuMbzE76lSB=WO>T$PHyn8egW&Dps5gOA~?W=2u9(O!w0 zpJdz`*JJNK$Jmio(jR=A#cs4-<{gtdf5ft-hz6`62~%U#C~Y{XDvGj`NG15SxLzF&;Q_hZOqw5WqP3wa(p*@ zV2tU=(NaB&7YMyMI*G)_f6!?f3mCgw73^W>WsxFArbK>NtRuELzJ~Re2t?{F8ld)K z6wuw`c(NM1H5x_=?@*a^y3NYg9L?|)rATF{T^TKeLOalnD{hD2_6|4iYFs1>`7soz z%9FYG@HpVQ^iLg>sC{bYH&bw9Dz`3`Tb}~s5##@?C6$aM(k1Is;Je(CajRNFFQkvM zG3P%W{%slk7-Mqn&>Z|l>E8YW?ku>f#~U@19o>tE#lQ1r;= zx0WwrGGI=8fBw(p8sDe!l#J49Bj-VxZrn;Hv2L8ljs6! zqDdy2TFNF9<`Gzu0%1&4*d_zDh^cmuF^JVVCX(=r+E={=7w`p!{JbZb(lz4k_)NoVDgHGS_dHbvpYZ@{YzhfodbyaLsMDPbpGELjM~))aqp|Hw z_{el~q|#tdRTkTv_~bBezK(zhl`e_kiQ(xixll1lMWeF7gXxY34uMkf~L65DQckTpY+e)n^T+Qa8e(OI%u|Zkf-&a^pCt2@2`Id-3U>z zG2WT*Q+B9A%M0{~5h^?_3pAXyirw0#Mrt6`q0tgJI^?FJXtKELx0(gR;jnJ|BfiBw zDdsAPWoaH|MLkk~m&s6?{*araTM{Dk+ z+wEx2~ zYv@d{sRnO@#zmC@?_(EdG$Z!*K1>n?9m^U$$|h3z8;T4eUxPp5;s-=HHw)W!G`|K* zrix65sE^yj#;K9c!7vp&F46V8%>}u@c??#W#{kfM(RJjM+Hp?jnd|5Z{0aYux;KHZ zt19>Yb7(pU4ZA=CRT<(nY9donkRAcafphQ#k~V13f(-QruqbG+Hd?hUZIeijr@PIS zsUS+cqEshh-Dk2w;Kwgq{0Kpi`>$$sCX5-b4+1msNQy2stuw%+d**dBQ-W0~7 z58ltz^k;AOP@kk`WA@m<1R^Mk3QXH#Ljry3fSbytdst=fVRgbMd&`DqGdfTcb$#wk zsAV()GrJNyrmrv0e7`MNJcU+SV2~&o3K2-=1UGR&h7N1gGG|<+-xqUH(9B5y7ANna zkQN}@%#5M+M|fZz9D~V$Rmesdlil*Q!IGEhe`D+V@MK2eq}1f_K$B)DIrnE1eOl1O zR3q;qodcw;itt|~WybB+zJc=@J8o@H6t19l>=!7Z4lEVFZm-zNotL|x#>46-e+Afx z7s^j*+H)Yf;H=?O`sYe;DjZ5f+y#=z-P6QDVJ;+P#t~f*c9^NEeiMTk$c}I(#QKdK zdE^2PvWUb9B`SmM*d>KKAV^e}O{fQP)gXlps~;m}idw=u@5gon7VWeux`9qYuz8uq zJy-j&`qbDuDt7R8&Qj*?_&g>VT)`)BC>I?)Ily-89yIq3ZX>&H1Ty|o&mX_5Zbkg9$uJmk+O$Xvs8t7upquU5+SLA zbI9@FR0k|rXfS)J+ecr)nF&?epy?$$lHyWwC)xa9x54VQ29~ytXw=bfF44;5oC#UR zsB`DkGcJRAN5nx|iT82UlLSYqHtKZ50q$f(T*vI_k3Y32CLA*u?N3EuW2E-8<@&@B zOGhMhcts;gY)`5s0FCC>`d~V2^y#c&$KT#fHt(UHz<_yA+lxBE(%8PbGJPD=LC|rL zmgiiC49OLK14{b$Ai)ReJdDTwJwyk~;k=5%f%cB5@@FW<@*dk0y)jYJSKK&XteU^U zX+*HVOiPcqu@;#C&QHiE`cV|2@%+(>-`S-w6xrNE$L%q%p?{Rv>JBIzyj@|6UD2$# z_UEvbQ}&{!QKtW@-63YhZ0^sR_|$HGABo&MsEIAXu3Py{*|91)DsP9ElJ^CRK91f% z4?6ba7aQ4EX+hLg!+iNUp4sRTG1%N=LkX)+Bblk=c;$pd8feHK{Pry~b~ODAXDib( z24Rl5SkB=$JUy{ykQt|_sbvO?jA4tuuZ5LCDh!3 z(pyo`ZFc>mc-?h}{%qY;P$UZcd-5Oae7$XptK=Dyaw~xTGZbNTi|->rmKKss*>I;> zP00mk8d#choTi3fOOcH1nLRu}9MXcdwIVa-7&2-~pUtn3qj!PF*3KFXd1MCFgl@kv z=p?{posycaiQUw7KAIs)B%@ktqAb%xyccD#kr`8CFoj}o20@2tUrB{lhRy4w*-rK35s{xCj27X za1jb&e6=pZIs)O4PQH-lruBTl{)A2Fe^w`Ry?7bcZy|gDR>joTwf7C6>)czpCq(kSwAV;f*l^Z&ifgj0 zx7-RE6-I!uUC1kmGR#tT9c69(L$m;y6x0ZP!MK=zZ#o%)Pz;Rsu_*5$W4iu60_MCw zop_p(VgMP0xdkv*QwVsle1}x$#XnV(P_mXGKt%i?QG)_5y7!PWJEDgj;ZJT5q5DOW z@eE|{_ESlfQGbPUkZ3kVZ&1ftNfXhpuhtZGg~5gU+|(i8v~b7=^%k?^JgR_;^pnc( zsS+j}5>KWM-BZ1q$>}dMG4kA^T2wm}WDKnXzVRB=3kAcwU7^Mo*Xh#6tFf&r5kY8W zGF|0OxHwYb*ng=;St`To=YA|GD858lg2(z@>86ZXQM8>RW%tany!qzh1Dx49I+%Ls#uynKrC-&$o zx?an-$hFbMCUvyvVbaxBx_*5+@nm8}DtXtOi_?m!5RRRI#juHOdy~|$vaT!Y z$Bn$~-`Xn*r^;x^EE9Bez`KP7y!MZhQgDZ~q{3tp6=ca74cD2`(AahH>9QAUzE81WXT3LW8F0I3z*elF6Jsvk zNaxp(;tYhl44d?4$mu;$h^;=?#%5zc`)wOi}0YQ6P^X2S0TH~pnK@oM`{WV{w**<3`tty9wB zxjQpQt!>f~^h@zRIQlYz*vJ-8(VV<%)>(F*Crs_pzAZ5?NnoH6%^YyF{R`ZyUM5)L zo{ja)+v%%ych-_7PT3tomxmt~YbJg(HmI_i+kVlUc$!J)XO%c&UN2J!J+d7~JRI`r z+Os)Zro~SS=R^A|Z<3`%6gUI0&eCFLIu9O6h<-u4A*OiY7}4g%{18Q;LeSt#UDWl2 z<3I;ue5j8_u6X+?*lPZvVe1q8M2DYxChQ5cV|rCXD(4M2Z^0-ARkQH6ZW62kWmB%V zG5ivK9UGg%DNNY6n*ocsQBO+~NE3bnlLFUpQQwm zo}8~O7~wqLinc8RcQ$0X=pct$Csr~jYgTUnV8C3HoR*tXZ8UmP@lf}!fC4NDb2xNx z3K!TIn=mP%16~$A|5s#eH}G?<7w{G0aE-AhCnUtjh3k>kMe|58z7c@bdD_o@CY!rQ zdnY1s=ObT0TC-x__u(A#mY%?RleBgqd70%|VUq1f+fR!9d zIb%mm$17Lrtlgy}GaZk%Wm36^v=Y+1pT=0l|81xPJ$fbi27W&oj!!ya%W(&3$#QL` z3wL7Knfq=knKiyY!EK_umTSwlptYJm&&TrbQ~=7^)5(O93_4B_pg|pKN5q8=c1R{1 zdFc10qOqc;G-0D98igTaxf=P&@tujYLfJ$)(ZbDV@bO~BX)Wlq7gt(|An>46VT@;XZcDWUnPzb%=>a{RcuHH=7 zc&5pYVj>><+xf_eo~!n($X`;?`TV@*rtkxwq7rT6Tg9B)$s9!xi@(r;9xB1S(ky7a zq>?p_iJh#ixO=rffkw_vHR06u9Z}*+uChqJ)pobmlI98{6tIRIQMeib4?P`mIjpe=%zG=w=iF zSHDfVSUjo!JJgSt*B$zpTZ4~ohir8mI=6UT5_UER&7O!M$PABvBS{*cppoA<`SPV> zFlOYQB-L%j{Xxpt;8^0@FtlBNP&ep-j7>tIevA4<6>Uf3Uvs)dH(!e8$lb7BdDl~U zZh3LTVhF32Qq5aWIK4pulAI@(4Rx?Rmfz*&Db!6NAP}wg<@UF7(EhGJ$kbC%j2;&* z>JOEApQJAg8A`aqh0J_Cm0JsQb1Z4kIsc?o2_LBLX$^+pw z*#CrpZ#4NY^X9^<1)5$IlQ}YWOYAaft!~Di5!_Ue12C*M?No2j*LIjmWD;A%W@>v% zSX-}LGh;p_)@K*)>CeMB+&V9Avf0KKwOA8Xu8VRiGo!GAr*8It>enY8hIaHpV!|O@ z^9=Eoo=b2AnR#or&_6Tu;%~sJ<7$TR5qRt4e)95CLCBHNfgik%(4Z8AmA+WRsCy$9 zUL|RR7MG=&>BMze7PU@ut1}Tir$$B~D)QshHG4{`9#m#<_A zaz@!LP)wOlJecj%RtWEDDNBHS9w9M9*w-@}h?fk{22YQ?&*>WU3y*@41IF z`MC(7>g87;E7m_+CM!nMs*n40*^n|}^&&EJ;Sv63F8@K~>>mxj+=8Z{HA>Onpnr5} zu0D z#6#x=k{5`Fq4I)V49SaB?ylquLB|Kl<3?g_yL}6xt3a!g4uY*+j2)4{HVm=ga0U#P z5S`>=k%_2mQ8Fi!<=f)uWtPX5+vR~nk zHlpzbjrTUTa#67Me32rJxwq1}N1bs+lEksMcRLa*I*S=%K=)(Wx!M=A30rSZQd{Ai zWgPBwWB4NpaBD~HeEpIrdTh!8dMCBS$fyk`nQkz%u#&GO|2($g)4Au<_0M97L@82H zhIcGnd}6kh3(qaA+;m!CEh2GK5*5Ks@}KEJNfR`8}uLV0)I9L;jlR#ZOzH#A8jcC~D6PCs;J6g2~Pkp%OMI z)49Ro0EE=S$BlZ_zN~l}Q(?by`C@nuCy-QF4!JV1WO9!zr;wX#9Ks9hXoXdFTT%8% z0u}dH*wFYadm}JY?qAz0h*7oRxotEg7|dpjk}{j^-5DokZPnPFgwi@fvPf5wEHXB5 zlq!^UlTKzS0;;UbvXP)+D4~Z0DJ1AJ!N#HT$pt9g-YwhAs_3PM5KvyOf7ryz(uc^w$JC$Y+MGg%{tP`~U`mS~8+3ATvpy|Y zB@_&ie=_uBg3N1$Ba9}je%Hs3GFY^`wv=0?3>)pOOElU-bmN0g=)EYRP=vlnWjUj$ zD4fSre*fY^hn5C^H>|3Qt*SSo&-kV@`1x1m(Nw5Ixxvhtj85#2vp7?vrolq)JlFnbGfYO(e zvEA+cvISJkI_o`J)>ZdcysEK{6__Sj6UcMB!VA`|Nv?BAiRq>kYiic-KeD5Ryc+hkkts>Ad86go6*jX&De-M#y!f> z_)tnt9Fy5~bE3hYKJ1|q+Z4iuTBkanrgBBkeJ1F5j>n@mDA2*ytuW{^a(3!kZxv~5 zT^V$Iql%6cFIZ+`n-5?b-IhHor#Yb}P>%MIKO5d?gsVOCjl65t5WICmLQ{D7Ib@Y6 z*F0`mRxi~cv5AmTI-1tQ+u$KFJxIV#qdfeT-$yTE=KQJv?hx3s*`K;XEQi*#(mg)T=M{4SR~(8=4$q?Po| z{6?3bFx5)Tri7M)R6lc!YT;pqXh0LbVI!<+r#khoMVnnS)dZQQgI{}?2DpJ2+vl1e z8t@Y-@*IU+pQx6mb2|y)x8lt; z)o#k3My={wG+4n|cFjp~w*;^(v(-Xd4_j~aU8ZsypN3T&pX@<3LRXJf^K7($%cNo~ z0K-f33_1onH;OxKgs0l#zF!J3Z@s%j@6)s$ehLC-Ow^e_||(J9+?3*}zM z^BNswsH)Tv2+shVZ6$6afK*y@m|n6&oip;Gx|s$k-RRAd2_L9&4ze){r-YRY9EjFN4DhS7>N=$nH-s!JSky?TD8&UNN}kHSz9{D19m%`95FC zL{*|}su2~+P3lgI%5Cf8h9B>*p7Mss0j3A7x6JdxDLj&Oo#UB~HGJ`ciQONN@5nlasv0P=bNupRj2m8|7D+eko{7()wYdYK2-nbCcPm ztx_A{2**|?FaeN=8Xk)Ns>|6N$n7kX(u=Uh%#6M9JMDN$Ug72_Nj42^sDOGly8hUy z7^M~aK+}eGRKzaj-$+*w!W4TaWn+<{Os<1Y8Z;E;xJo(R2aGyYMyD~NR~LJgainB0^w+lK;fFFLIHpq^=RnlKh!%GHX@llv7rA%?fE)3(Vf zdOY2F>yU2VWE=KSol{^Msdn>lGCme#2~^Bs(n;bGal{UZ`i-1=t6lwbaw?50u-Ci>_mljKMP+{fVe$#N zgw6ooV-X_#MKpqlGS=Cxh(dG~@oNW)W905mPF+IBkW=3?IW^QB|fW5^E=WHju2qc8TbCzftwL|1DBDN7}1U3}Y4$)uCn-j~V*Q1Q2!|Jot z_%XUo&Iv423hY}<=`b{aAzMjcA$fNvuwM8G0&Bmw39J%8!;ymvP<5TmQiCnV_DCdv zauwW(XgAq}-V_fM+W#JfY!;(klMhb+`Wnfq+pxhw1IZ|-d@c50oLu@Fmw-xv->U={ z09_PFPR)uBWk^|->;zu)b1ls}aYTp&6Z0YtK{P`MKCd52`k1sa6ue}D#;IcBZV?h| zuqK??OpFPNnqqP7mf-OdZ7h(GVvC(HVvNB3m-EH;!f9B26VK6ixtdLMArzs7X-G~U z(PK1LFO=A5^aVlqvx0O@)N<56BAiZ@aQZHb(ZJ#%ynWfV8V#7^&L0>_1I@V?V%CrO zK9&qxaY-HMrJu{;Yeuo#r52HS<0aOJp-U_Z8y$LFiQq({w$gGs3@a`6zhVd&3ZRhY z#1@(|wI%m5%c=QZbulqt_1R0^TFa>|PRogonJ97Kr&a2U#lb#gR{c&Ka2KTB!>WJs z$t5wMHI>n`*H|#u;Rr2_C2YZiq{A-_;susiFr3<5oKt@@56m{`N?k_CV#@7Uy48nM zS;FccktY@qj`<;WjDBt^WuxR~5iN^4nF{#?#Z=8z8I7m7lrp(y^Q%)@oZ%}v`fpwU zh^9rI0#*!I&d5-64J!|-JU~?r)l?pdUONKDx05tR;zbDh&N;}0BVU-?UJ);@yjZM* zZ?z_4^-&a%j*BU4T22gpb;ol$D^i=t>CV+usV}yw^~==HDGi>Hw$jRT^j9uwlp=ag4PN@3P#$v&* zvN)^k2?)McIFx9P>=ocHURlx2Ris5X{Y82QY#gtyyj4=%OSvDAM|ByyO9V*qw*^Vm zcDP$z8Bz142Mj`VVxQQdsPrWtm;4=Gm#`N0vmf%MXJ^-S3r@e8kzF(Od58+~9(u2jR_p za)(LH|3bHLtI5Ilcz>X>yMp3x&JJsLo>y)CmYHHzBs%>;XNnbYF~th@Lrk$IuZP)2 ze?)niSu-n~nROpTciCM*ag&4jc>OAf7Qtmh6d*m^W~GKzpR(%Ti2mB^s{c7gMHe8& zuBMBtFDPmVOXT$1jNS)Pf&B4)VimOY_)Cb~4C6orc|L2_&G`&?xY7LaZ@TgqSovAK z!fEGWWG^WGwD$W(6z#CZ-jv&833TC(_<*(K`e0ED#e`*%s(nCTpWK&B%()Q22n@VW zSr^kC(~Q!R>x?s z@tNJVe6RBFgP7`L{J8CdE3wo!p=Ylmn^~sVJu-&^iH91x?)O2Oa@)mC+e9Y+&HXjCr>n#YfUaC@a$MFbbX1ZebSIf?QoS7zX+aif}{@y(`6 zfwIP?Wpk|dx&Vf0wFlT7Y~#QT$af9SL@MeqW>jy%j=?@%-RDb-zKBlEw~;ocOVb03 zGfA_FLUmYHQwr*$L*B=08E^}~Vhw78Isn8+EeS^#zDF@V7$wBi;xKyF*U`tLgf7`3 zm-9>wtBxo2Z4`4Ti9;x6w}cYazVGdHQFt1(bF?S%?nm37-rl})YS(qOe_}*M6fOE8 z-7cZ%eQ=JA=2&44+&C9@^Q`fB637H~7a@`Ex4PL$$3S|i+M`Nf@9Zr?KFIcY-0GC3 zLn*q5Awd9%@xYwkAQbD`5m~lL7cNRTAr<7hy-B4O5d=ToVuvis$U#HRa>s$7R~P;J zShjgiL{daQ-!;#$*h1B@48h11VcVz4D%mPV8Op4HCIjJce5C25T zvi4|)0mrSzO{yu`)WhnODhjJU!jIKpEjliL8)fX{8?~+tZ{77gsyaku;VO`=rw5o6 z?uKe(d1#8G-21f1;rd9AMkKhvqgsUlqrmAR{cfM?A&=e|GlaklOU3KLauYFM8uUd~ zDH}M98PtnH$CJX-e;h;)uLf>zzKeTgU9`p8Zu-M4VaSdtLJDMyZ|nbX|I~Ane+;80 zIv2mO!m~0&#qi|93C}8?dr;3&`w53o=w(pyCz8A)8-Z|6k6BFK6ot2#Y2}dYr@Ui` z_gLD`Z_M3~f8n2<{=mlmy(p4voWi87eMwVwEvr$3XYrU6$(t?x3Uh^%X?zmtWs0T5 zt%?c!Ma7Z>)`xOUM)mrCF>$0BCdw?AzF0g@VRP3kMe^x{$x+-2nAPrIYTor}msoM0tA^NTVc!+)Mpes_F zw`Yj28%$x_cs+OSCEu8L;1He7mys`{vnM(a$h7v(hbY!QV;>o%xQisDyV)lD5Ut8* zyoQXBjv&(6>(>(EO+2WGCpvNN2V#X|)_aF&biVjm)**jK?Dv?5q>l+lwqX2w`WRkp z57SQc*A4a)~6)O4W#N!J(e!)CT*f|uY!vz5ER@YHuFV5@R90CFo#BLMy+gc&Z zM(YM+p)-^fiE#tXHukRo!K^G@>?8%0YIPR;)PL}q8ir4cFueNcCf`o%Y+mgV4$;!? zYEGD`&B?8^C8e)3Nul|tM>T4;)iPXj&U6;fw(^!O%%o^6R$0%_H%r4rEDgGMTiGUQ z>Q}e3i2=X(Gd-A;9eQ#8aFv4wv!(sKOKgo2{gvICt!EE@BWZtm=DCMHKSadI#)qQy3I zj&3=y5~GbMSQWz3=gCjeDne`BtoNIfCDQF^=H!|NcMW-+AwEhpzCQ zFZfwBfq&<3`B?7XITuHGu4~p%GW&e~gDpSk@oq^9_FeK9 z9PZy~*c3yHB2xs+4yLS?EBJrUzq18-C7++a=ij+Md3Nu)CnwMQ>CO-*&-+L)C(p;s z$+L$6zJrtJE#}TCC(qA)(OHl?pO0NR<+NGm-?=-#P8t5D!@U2aPMso4o6r7#;?IdB zG7)8JcfRP*dGLpK@6fp~0$!GpPe5zCbLdQp25o$Pa`6U>22lENCU>_`8XgWx3j+u^ zN8m=8&S|0WEcIij`7R%w8+q}s^XDwTzwnDQ?EXT32xX`m=+r-Sc!)_teha@+12y54 zseP-wK-g%>%rny9qR;<&sI-xPNLan&3$iEnlc`skj#nmUIE*Nr&e!NJ#*Wo|Gn3&h zdKgXar6R?}eDBnrw#bhDbrS~$CkXmctUEIvV>5W0u)Tc+#95#I(m zH5z{eWZn-Qk2=!<;Bx&I{V>yXot~(!XlkF6SAqn_KLKi(@z2c{1Q9e1)J+50=nkv5 zUugB%&}7Zi(4vq2%89QDbfeTMUYz4)+~dN9q?A`leZQnW85OtO=&INxUN4S|m-r;E z8&~1|q{QosQa)%UJ_79X$q!R-7506|64_B7;$lTsTo>Ho*=r~#I zv?9C2>#rEzML+jqt~|M5B!Pq2D8ZC%nq-VBl9T3sP_EFkYD%pXoh^&yPgD63%ut$$; zeT!8GsWe6^WRlOphy6#hz(kvaGjX_YNagyLH&A;zXhxUmsNGB#GQmyTQw#bV#yL%J zYe^HlA5*0B`u+hFX_tGl#3^7waaTk>!INq+Vjsh*Mrz`n`s^UbP&7u4gkmJShx9aN z)Wxfn;W`6t3{?D3AIVpQm!C)i(+AxGVD167JRfWY8J%qB-(qg! zxlK$~>zX@X=eXYhCCP`r+PFq5RY9F(Rj6cbey-E6?&9z}>2e~SDF8hdzW zMCxjmxC}(?;WC>(9apew0E-4EJgPd|;KWnnwtq&i2}kP3Htsem58GqvqIo1pah}Qk zSWJVWaN}daQy*vOiG|*7*-zB-#f%)!>NEZ+}je^~M8%Vz7c@VQWIVOft|aE{~&4!&)6mPbEz67v#34yKzDy3CT{Si}<`p zK!dC_!cRI`5KQn_aLmbK_RsY%3j`Jo)?$@7a7vP^!$t^n#cqQDc=rizLOpuDi}6?0 z`gy?0c{97Q8R}9=w+%RTsqGreAK+LrMR$IR_{nZ|lPEgWgeW~x3D#Z0D##TE%P}iv z!OOVtL7#my?|uz)C6cnZ{%0ZUtZSM|`~W46W{}_H(sX+O`k=ze8bQ28FNRuPFob$^ z^3tFeHym$B>$R?U^a;R4lnD!ZsfjXdsl@f$@@tFtuRL5LEuFu?aSD5vKq~6yb;!Au$L)#izpaRC8f>Zs3p9U13M4V6?&&l(E{*Vac(<04|Ojuw_qkx%;ByVW21IbRi3u%Dws90}y6rGrQ+*UNBQ+rh`d;{DWRwm3Pq z=%d%iFfik)dXA}5N{&`6cPg2IVZo{iR6R^3ORH;@wQk^SbEfj2a8L$XSGt;dRMXFX zEJdpA3~!91BH-zJw%{GW_ZiAZU$%llr!=QBGhAG_kV41mbP65k0t_n32-8RYrKbn1>4e%zfxwv+wEwpSZ{y7S1( zod9=3D*Tc!F}({^TCV+4 zj$rXrz9^!w-r`PUVCyGhp=s=XJT=0>wA1s!wHX_((tN~(?N=GSc9NvN}} zn-I%4lAaD{Bn-^y+>1b6>>#~nUnyq!@wG6Rrc^3XW>#@sWB5|9+pSy@r)anwWXZ|u zdh3m5GM8B4;7M;|>jSd3bpetl#yFi{J5lKja8f*kW0V*?4ISik26HxPncQ=7Peyoc8}Z zEZ)DG>m@~7MU#m7B%kNApcT3JXf~GkLXoMpG^s2_P~cXn>J4njf74f%DL2yve&JqG z=}|AxIJ#*==kWDm8hhoBpQ%RtTxdfeQx_S=_)K+bNdt+4c2SX)sL`||EL2204&1pb zJ>mv~eRc$Q)+h@)i{Pl3RUJ)aOA+UZ?FP4eR9TA;jUAMbZ5pPjCPD(FDO>5p_N_esfS@^JaP0J8M)Cq9uR9Wkh zUW~^0g3{?X{&=xTyvvs{42Z^6rY3sgcBf@XgqW6b5EH2it7*XLg!izeofB$)X~zyA zJCV_-r?3FyI95a44)Z!3dCO-3Rao_N{Vif1=ga$O=tw$3O9m-l6{n^9`2VQC_KxD?)v_%n~vJRm0qtq zF&MrHnA16h;*rPA8 zwMylJ#V6_$h8wLpTueK2Op>P9Lx#bFbl-OTd5FDApT(Q{E!wLp={kKT+x{)m#7cm zMh(7-$4u4q)B;CkV01F z5itT=MuO;#c?@VDbrWpY5PVii;- znXLZiKRT1u;crdboylq)6=AY^IkjL-Y_f8jm)7-Lq#0QR6n8a~PQV8px1#?zlhuu0 zi8G4Vs!JxTtM%DI4w4#21I}diebUWj^*v>XJq{dDS*5*<$?B?Dy$ew9h-sHVyAyK; z9XpkPJX*z@Uy0c{e>g)Kq{hkKWag;}G)cO$$`18o(!CwZO0%+C6D(P(u48bK#4!64 z0d<;M-K9!`qyQsLZoYoQ58QS-knZHLfhkrOYGHt&*nF~)ZVj25 z5$T0Vadw`xq# zPg$Hkj(SoZ^xz zvHfYONB070#(2E<6*9>p=*$jOGu*w+9gay6SM1Q%}DT1osG{YJ?sr}}n{mGGq zlc(69Fc8zhceFpfY%{#dM2|dFv_IiDx&^g*pc&YQ)xXmZLmjFsTA#wIW&UHCuK48E zY3>Tml5Q2-pH#@%pU|zm{pr>C6n3E=bunI#=l6qo#dd|3cd$RL3Bt2V_NTYo>t}j< zy>7)5Wee6$SwkfqFq4#G z+Yo%zUWlH)c6Lg{G=`3(^J8pl@MUY<%`f?J$!A^Iy5~qOvpNk{m-N{o_NJ+|bBfB; z-%g_w1ow*0`l-{T=2M9xQQ7zwtP&W8XjFc`%Xdg>hlW_LT`{yJ)JnA8kNvAtrVc~* zDKk11zRCNr66aDv?h7M)5#5haW@;*!`@@K$a#Z-3)G47{?wU0`a3>ghYkisI2p7L@ z5@}4xQ;7JyM;yP-#e{TLtfJE6;!&Z?2A$8kG99m?zL+P{AP<^dpXS$T;{>qd;*U(O zFSwHS(vJ|sZbNWuZu~ACw@7cZv$?IBaVsb&FNVyi3RPtR=j8USK##D$zS?!0 zYYI;Zb8&nC#hXhf3Upw0E^2IjT!H4M3tM#*h=a{F@SG;joCU*uNLL|A6qf~^3&;OJ zAkQXVk$f_lCb;TEw8f*4u9esJ2w!daJ5gT|CgK{{#}S9Vn$#1XoS=K`T`mmWI8t&2 zMWCaz=@A##PSttv;HG=CiMvu^Q|&IK;L+Ec*Zg^`3{ttf8OIFa>OJb0r$QwD3fj0h z9`c;R7`|%kb~`KnQ$&#`E|?%6D(G-Qo(jl`EsU<{ueAGM)f=+z);lK;{FWFr*Fw*C z&+b{mRMIg4w`ixP(^1{xp;CY_o3P5)s9#~8_SDzhYKA)NQ|bJ%W^}goS0G#S90R8l z0{L-L>>lwcf*_$`Gs!KNa!Lr>^Ljp%OMxlz`Dh7{7$w8F@5N7IeaTOZIzzJ%FDzr$ zLFeye@h_L7HZo-li)VKWg%QHn@huwvZx(9yZBk=cd-Ey6@S|#LFX+^2tBl(RzhCCh zIk?#SzfG`_N&wEz0H(I%xZGim3!KJr&94h=EDJ z;E412sc?QQwu@pk{Sy+I2nD)yz0Lq5EY3$*Tu(Yz-r`WAjhH3BpgKjdn}wWExXYF1 zyd;Om^=S;LUBXJ|>x8x=F47vb)IVpp65)DQ?fGK184?dG{)(&e_)|5D8XNOnUh(ZI3zgv6DB^ z9l6~}ns-w{X(#Mj<#8q-bu(Y5N$Yp?H$`aNyx$3f*8oY6QneG7%I!3{w8^p^z-HL- z@n)FQ`Mr5<=w_J6tV|%usQPPq)@35@+%gdtH$J$axF0=CUTr?f$*T*jaL}pCYs%zRTtVRk@Eqv; zA&&Vj5??T7Yhl207j>6n?!a=-r&k~pjf>8D5?~7~IeN~annsq9N~CL4n{={b?y*C* zz#Jg$GWsDKU_SjO+AUlE3eEC3e}6mo3LHFS1I!oDRp#EFIYJEbL5w%?{?~DpZvSg% z3Q*9mo2f0{|9T73IhV3Ns&WUe0>%BWQ+ST|ztXJG#J<7eCK({8Wj?iN#ZcM+`v_l# zZ-8N=Su=HVYYA@daQ+zol0ZlyKLgElWi(1qo-frMWLi%-;Ep2$|UM31E)4Mmc zKefHRZ)(>SwS&sc9@s`Qd-I8MFh3{n36>n}doLKU{iPXE1;mwIB*}2GPVc0fwDJ^> z5XCXv?{F!T7PHE1Ws9U|KZ=c%4etmO7Q7$N95onaH6dFaNL`hdl~}zj$ffW_GL`0=Sf=QK{KqnT z#ZiAV+wa@@6^O07?aQ7`%bzX+1SA5(A zgNj7!ulUclw9@p+JUlQ~=0BRrA6DxbDXhMbilRSVYAVj>%8rW^JCt+t`!M}xBE{rt z-DxEQyP~HoHh5gx?h!Ek21q&l2a}`121ustKuIyTmgq(OgSnZ}Imh4GpOpWPFoVla z+cDgSKIa%M;Z&s?ifv={vIhHD|7hsR-6~S7cm)k|)^YA#{iC5hcg0BY;|+Z57Bz`X zN}AJz{?Wyd2gSUz$*Zg)igdDWZXKG6=tBC@=wf(8@sd6J##`=-3H0Y?Mf=s>=LSrZC0A7d{V}_=^c&2U5aM(3(G}CCXSbI&XtB1Ps zV|dVa#YJBcEWVa+?#cjl9%05+$m#HV+Cxgo@A+B!6Mog)o(1Tj<56iyt_iOpp|C&BY z&_2_BQh&O6Az8Dck~yQM%N!eXctHCtoz@3MUBXD?RxTmxWp{xfV4g>H9!~0uwwFx8 zpjo-?sQZ*8a?p;G#;Ny>{@v|BK|20@g8v@r-Rrr9!$>rK5f;@?P^*4o`>!IYB&9~mUN*Yyn=Hm}bbipE#bGe$xJ0c|O%K1hhl(U#U&yw;#wLYrL0wGHIff)W zBv;7pIf+Y2RA@OVrR^shW;mWpuie^2^Qw6nLA`#n>C49ml(jalURo50YoLXji=NII zazr%?OdAu|h{@%^r%IQquk17lf1pvgD#xKX1eL3BJlQYoCPH3wZZobe=4#*!_3F_~ zav9J8rIQg#oe`)0U)@}qK=h@!RnyC^GTmlAJ)%o)OUX&!VXjARzVci2FGt;fbY41m z9X%X0p+0~D~T{9b?GYGTQCCzNKGy)MeeLhxl z^H-*C6mDl;D6U^@f6N9Evo+fLJE&%FfhHJPEk&ztA2yb%kJwnM4;ea^a?b-sI7BrY zOV;SF$70pYiCC|i^#_YyLJJev1qZ2ScO~Bl7C$D{EcdMD0;YiAriThGjH;y1r!ZyH zM+t^Zm`W5b<10Q$=A(^ErhK$bvW7q9gL&6`(Jqb6?2FfI#j~k@>l0qc$IhR*7Yq9s z{9-s2W@%GQ`(cf_2f@=ne*}B9d1uFJn-8Pl5A&9XQJ5ywGLws{rLT!c%g)b9mT2S+ z8oBhfMFRQzzA;o^<4zKqeeNhUpw&^OK02$En8HfUr<8n-)S4Zh>+tnXBq5!jgf7x{ z;xL8gI;zuUC%1gvRG}JgtbsQPDd=W6l>0mt?N%R}ZpELB+N^lc@dGkiD27H!SG6k_ zr=Y7^Pm5~RA?-tHpe~xz+Foh`v7bhnX?vO1x?Bm0R|07CkH|=+A8h+5(z_`n{0OJM+!+5_)XwtA;Jr>oWLPThf5W<-nYw4FKb%VI6z?lUibIEa)|doCCwowKl4C#nO&xVu}1JLV?M zJq?9uJ}vH=l`1n<6|1{Pf;O(N%q&*S@GCOJ-<`dF6*`eFce{aFCH%Si?H%G-y=-<) zT`?odyA(Trbj|X4(12nAEK_k$MMZfxG@O;PK=48z^6}s!5sdMaDKM*)$&mOkzMmy= zV4;L<&sT3c!i1`RqDwYTGXm4svak!=Oi%;4>C~yv3uOoH4no4j01P_*$eTH2b?l+$ z(T0qOInNMuY@t$e3b~1(L%WC?^R#rt?4eOv5TY~dZbkf%#q<{+l4%@kS$V%#`Tk}sW{E$QqdK5{~&9^#4J26p2a4|lW;Neho z>fyVKPjwinjC?2wyqCmc7X|y>Vm|74@a>2$>3e_Ma`l{PoSCvKCC517ikuDOKS+$ z3@EalByodsd3noWfj~UYG6^ZK2Cz z2z`fcZ*fFQY0<9*?DBEBj6^8_CA&$3K{!!C7%l`$k5z)cZ4{3`w7^pr{r*no`Xd>J z3xA{%g#mOpwvf1F^e^%$)`R&yr}LQC`nap0 zMD7(0!WVhU<};HJSZwK!s|b$V7F>2&B^k}t@=Big+#q(OK7^8v_y$Mxe`{3GaXgQ= zjU^otd#)a7cyD1E&mFZg&an1ar84}Z-eW2myH;tUm~>D#pltg7N}8qlRtoE*=u#hg z`CZdtF|j5qy~n5D&99~joeNXCNUHE2a9GmMgbLH_Cr%_PJ&}&@EdZWG-oA>ZIGrF^&7!TvzVdz(a zGhIdK;7)T6j#v|X_e)Fy?iM#X+>~!_VYQ=Z>zK)xvaV|9ngfT5qU1BsiWh$ zL+*bVA-&N%BIF{gvighslp|!8lK%?`i9@J+^4L8>l61qY{uX~`6mx?2Cr4nInQ}SS zC=IahgEs#tE$W!>RL9M{$g9h-bY0BSb^cnn@PYv}%GBAZb5iG~&O2vi_b`3(%Ty_K z`hqVxeR5ys%l=XH!1-VmX7kjq9dH+FqAhUS~n-3 zkK5xYNzSowmW(Yu6gqB?Ak@1~p9Y-=^CTYm7MW#2`5wPwxYl*t4X7(@#*OVzv&$(7 z8)@`=*4`_@>Co%bss%FGO#bORvdO-- zzwu!$|2L?zn{9~a-l-uDez4zI;x@ojfvM`S*u#-Wcw%qrkG?S%=cM*klZGswcDw%D z^nTHMA!?i9=>2ohfTMR?-VOdRZr%}fJTf7ieEK;pl-m2G8f95 zC^&M&*FI?hj5%N3hfR0Ud89JrL~vxfecM+DbNd&Xm5=g{xo%@7tSB5znma~w8^+d( z!rr`FYvezO=dF*}kr99L+Wk2FK&~b3z|mL+Sat&2-Nf8OZC)*?5V7PlSpAyE6`f4- zZ8Nj^xwBbvi$$AqnHpyXYio~m+fZEYf ztKswD2G2u0;yOR#pe`P6T|C^nc(~Nlt*#Ci%GrGLxM6bn6#5dayTB3YTlBfuf4c8w z^Km>ClS?AHwmcab=r3lkvgAzmxG{4-+>}3OTIYu4^reEW?o@Kb+#`w=70(nE9xZPc zo1DJ^eig}7FoR;g5dL&!R|#sHrle14CoSk)H3np&{I&CITO{2j>c4;`3_S zE0XIj%mgn!Lw{}?O~0V4%|gWOPhfs?^L*8bWCP?Iqo0w8m{10JGzE3rPy;`_S@Xk= zpl&O_=f0xdm&Hk%$sENo=6h2FB~$|z&eJUDljfzA8!Y&{A8NWOvENiFQEBQdtSsWI@8?QO{S3S>0_nw|@f1xtliQ8*- zKoL-jzIRfn!f)!URuh-9`%_m^kwcFYadnfc6&6uBp; zV*)&LB_-&V>m2p7^rMHazh{zR+B$YP`}vU0Z_`_I;-%(OAy*tR zy{yfKW7~~a2ZIZ{J2$i)Yt<$D=6w994NT2cghHj7hZ>PiwD=~kA@qj^K3Dm znsC|TabK0tt#2&>5h zDF&_<(HO$q2xJ?lL0ea-E2(;}#cBci>vibH#8+bd;Ar_zgOq=a26O9tzl;R4$@Oh3 zV<0qYKQ6HqDzw16arB$Gt-{v;rZ#KDwy@>AY$~XGEERqV=bw!D!WmNf+O#tN%+Q?sP7wSd?Lwx=yY$TICeueJgt&@TNB8qE!3@l5|SDqrxVY9 z4)H5p`$pyjH519=7b#MzNUB$%m=`I%aUZ({~XF-`YRh-Vb~qn)Pl^jaoE){Vz&I zQ1PMdZz(O$_Lw!^w&18o8Qs!sAGYP1n94?I4okSWyGrE|=Xg`7fG^C&)0#rbz3O*&sEg#sN9Q-G_N?K~1@ z(>E|0n~M<@Pv-ux?Kn4ZrZTo`9nxJJF$BGTk@iMlk&;IVDV&XZfbor z4a)$I*Kx*pqOo=0w6O9$*~AKyKudxnw*>8%&~9V>o7r$y?ZuG#w5IUl+Vh(exLja6 zZ6b9>Hpj$0?u0w`*HY|p%_uE{N5u27#+J>!pey5Pi59YnLbm>`vIca21`9=2UH7KL zFYQVt39MIj4wZ3Y{sHpsQ@I3-2E;soUkd}8kwHHV2drO_s zE^V4DC@qudctw~^r0Z8o?ygPObAV#x7%J9HQ(@&tvaR=J^SU;JU0oe;Xy9(Z%jBQI z$R=jPV;-*73|93BKP-2zR&tG;D=`1P936c;SI8xSN6`6hruIBf90@s_n1_=9Y-8*A zT0vFvXlWJ{*?2EAfWDvcBB5$8R^tuXkV6jw-=%5|Dbv6yk9p>j9xL{s8rp=1V*48Uk3cTim|05u>cfy~)J=Ax>;o$62#D1aeh zt;t{=R=qJ^Ew7W2vWD8wZ2-j8l5$I%5?dMpv1xQs>bSn0$=Bw5PIcM9^fj@wG_-|N zq)vNw$W0tP%AW@k5u4K1Ujf(ZxYxzV_S%b!E47R0LA3A^Ez#g1t;}DpTN{{4~#APO~)_YXC%@;oBm`un%i}D*epqgNT0R1=RUON^4ZhFVOHjR1w2Al7ib9j?NQ3f+HOmprr;}aqHhx^H% z)j#+_0qm1#CQmkvK;>?%$1nq*X&I)TYu?Pgk{{<-;-Ti)#oWXC1^FA>~ZuTYw0zGA@AvfOGVPy}0g7oD;JJ6tHVwu`BlH`un^dSd(pi z)YbJwmZLZg-1P9nN*y!=VRewiRnW=?N-3btF-d5F&6S|@2rw$2cJ*6a(45=q83A8u zGjoj=jBSi{0zCZLVDv3WUM$FTsM7GjKMI`LFg+V>k;PGSc=TnBOmPB)Xg`%Ca#}FC zvKIOmC_cHvbHRB*-QN%yAEp-FMUs0KKG@7ICxbtq!GCd2)XET%sHitN?yJ`_g;+)V zF#d4lHhzj=VSq0w864KRdAoU%Xg*lfipC_ojcQCh(U{nz(JX9bw67|S9e9;2Eq4JrG!AikQR5hPo~${(5=B9V941S*>P@E$GPd=qagaOT-klnc zX--`+dlX9{O+uoFz&nJ*iposV%|k@WrV8}L3ATYl!a5SX<*w$_LmhwwiLiQbZxFpY z8o@_tC~9dKhVN94{^-e1$wg?@yWVo~iPYL`Rql4&X}@Ak#bi5ODI;G>v07%I?DXQG z>#HQG`WAkj3y%<>6hYy*M6hUvy~iC!OWkEr1qb(2Lv9q}#O0!TZ7XO!S)|ru)kSAS ziQe@EXB+G#gXSK??K|D4rygh&!-l-EiWzLn>4Q6C+tvUHG_Z_1qk+4p4b5+G{4F`K zbVavOieQh^O5LW{-Xxgj=^cPPOD)c`vO(vcAgNOMB8L_#DUXC5d9JlZ48(J{7QQ|Ie(S*C$o1biP|KhL+%mIo)(nO; zj{S?TKYTcf)kVZggQLnsSakMMu>Isk!rZ^RAy{UQ0n3%jh`oto18lSxK+d-13BuM49*dTKjL%AkZKfroV!AH^P zQC*OBs+enJbL;D0LOD1o9M7@0k!R5x)ETsxYJ8F&$tDKTVHSy-ddQBq$<@&l3GP?L z(OIKDj?;Jiv@LF?vtGE$aMGa8dWq7Ui?~6tIETcXsma9+#P65SR2iEP&e^+E+IBjY z?1?p8_4Sg62}hNw38^l6o}}k2#He^osSQj8RD$5p3_bKEljg0@u3W=)sIclhH@@br*ZjdrPwh5?O` z;0RnW3#;xOQ#O*NzHY0o+rQLAcij5vVZc_U8bRD=Ri5SDy4j!+sp(>$<9cl}jJs)# z%qTWeI7rpGIfAYUVsC52`I5MHI%?;uy%>1Ff3{v?Sk2VSa$oxlz1-|yrt2l{p2_#P zdoB7B4?C+D0~}S`km8O{(wDg7Hl*pkY8%ot|56jJd734t6M(XZ{n7Wgg$(KZIJ3C? zoHRua(>!mICX+uT#krGM$gE9;r|m+}45&@(rwJK$IS?`>d#DB~89wh2XP-h8|2=tw zZ|#;gvrG#pGBHxXg-J)wcUQ{4z|4nCP1D1B?WBj2->-NRJ%-C6QjAS zr?JJoCiu>2s8w>lfkW4k5#g2_UHBM@l1xp^UaatcMOU3P(Qy@nR{qAK$Pu@z9Wj6S zEhNSV>S!gFPdNgqyudOq4s5GjF&{MM)(r0H?a$0&X7HAhXW)Ugh5=vP%I-)#F`EOiPYld@blzr=p0dMHZ!2Smjs zH2j~5is!HW|4dZu@$f$^DsHGO8;Q|kEcChog~nJDUH;qu0a0)#7dI2MV;_6 zR6B`XAdn9A`IN|RdF4Z;f{6E$o?-mH<~WGA7aO+tbPFLKOe zcCr`_T5~zfeDg6Kms@0&+nKo@Y$;-BD$rhD8?UfUVG;Uc%;;{#QD`GV<$r1OVi`Dtl>-j9-?&f>p={!Jh|p{e#!C((2WW+CG755oV?v z$p7#66xV&NKK?NV33n{~J+x8gquhl1vRPVn-bhoL)cP?r>Gwmfv&d)hen_gnvX(q( zC5J{UPLh4Vc0|^YU)PiB?yasb@{(=EIu&$nlH}MAt9STU6B>4(L+9%}+bvz<;^x)| zY%jzulh(78blV{tg30TfbL$$nYR}+&J0mU+JT?Smj+EJyJ8PxAEH=~RQtE69F_%vX zk8Vllw%gGxKA&*f&V_t1n=g^v21j5ptA9i`Nw#UGtYdOVYpGl;YpgU6?K!cLacVdo ztvQVmQ&#wM2b#P=7B{UG+LURLq|8!MI~QwTLmy~meJXcS>CQ40nrW6*%q?#%geLFQ zE5`YkWU39vE=DD~ULV*tB^F#b{wmv-$maT@>)y|j23v1SD*42m(*Pp_X0Q}(PCQr~ z?!u3;VoT)?tR1WqMr1HB1O3}g^GDE3^tUtq0n_|${qtVf0rc?Te4xS6q>fUnMH<{? zcp6+pr$z}Sh6demla}miO!hFD?hf6lfmj=3K|T*!8~p=0cYKAB#SGqM@o|1o`|yf!|ZY z9TYfRiN|qvH!~>+pXSAxSi*76AM6fQ9gh4cRhhdHJLcnLb_Y@o)@)c^rEg)?Sp5iq z7(&P^2=k{dI_$^ODsn5^x77qo9^gy+w#2+K$wPurFE$pCQUh0MZ-(L%tyXz0Im>=s zbQ-W5OhSy#exNdL+i5u*PRm!+)@Tf|lirnFvipM+sEL>9iy(|^>^69%>DP+ssmGm$G_0*?z~!+9)))sMX)P%}!$@F1j-?18^=2K%y&Xn> z{qyJ035t3rj=r|%8yEBncG(4eQfvqR>~<|I5`5uy5okU*Y6Hhtx4uHF8_6QiJlno% zUD=ew5Ek6z``f>Ux_6~+7m~31Ji|{TfsQDqA*=K5Ft*$E()&0+m~H-he0V=n4FiJ{ z74Jk%>Iw{1Cr<{|rJZee{yQ_F{e^`01W$rj6}p|N!Z0`3O# zYJq8EXF%?dNpO=7set>5$Vx+X$6^v(N_e*9?RC}{E_c5YDwB>+JY3ZUw`NHV#mwjU z1hZEd>Zqr9MxsWwPOGH)_@uOc1zQB^c#1~9zfgPkd+Q{bdLfSx^;5V~ZO|G|0x0Ds zxE~ciDXe@S+v_p8G3nxhcYsg?ERNamx|1-|WTBR45D>eKG#z})HnsNF4+v_L=>9dz zxm3PD5-zyZPZ4g_>lVpiM*L-RFxXBCBgr_G;DptA7vTgzryYiv{?CQcxxpa(6ofLj z#(9(p>b+D0jTud_SGT>7GlHl z^{cjZJjU`Zo!o@~BD{Svo*OAP7M5~DD#( z(z$JBQeLn^?Piisx7|pu#CItjqCM!c*QEbcov$DI*h40rX-tHs0W{iw?gK%}KJ z$RubCX7B5zVMlAPz$4m2akTbmu=r)HLn1yAm1spH5GLIu(v)js?c!)k)~|K?in%Y7 zTz~0IXl3k((Fh_2k*Obm_6e~CG_jR;a?JqyyhZ;V979mhI@(1qo_Nv=D&-URm)sWa z(oAF>!Df;VxBXZRsvA-`JP{R6Q#TRa_c{GAo!eMg1ea(^xOquGLMbZiLjqSaA zG~qGXaSUJa)$H$BsJ8i{87h%nIrn)v)iOJEkTiHdS9v*PwZx*`%L-wqE)_QH5-q4^ zdL-e&8JbwO3q3dzNvTGEoSt1;f2S%DtfX4gBaKEBFq2In;@EIYe2hF2O;Qr2M)R!% zb`g!!K;vg$c4#!~Zm+6w_;sByA~pFHR_&vlLP4=|DV-1p$d&l>)jGPb^wmy`zV}&a z`fg~Foa$;J1!#xN&zk)-Ki8VE#nA!2FOB`H04kuFJ3-DX8`VG2K<*NZIG!)V%HOdp zb&d#1lzjNF&e@G&2CsBC-$Mk)bZZT+o&sidEwL$^a7sjDVio=Dn8P|1ooND#Gfbw+ zlCP-W5~DT-iNpi*d2(YgWhJ$X1&~%kl$)rFv$vXCP9-cAdh{Ie%<5j?uZeoD9x{3V z9AQtbrOEqUtl|h=94t}%*;M^Y`G8%r`aU_b={J?c19vi$Irqx0VB%f@z4&>1K%tn# zsag~202s3yeMa6)+9Gj!yJghLL*{Ly>nKYdIhr5NSv4g#m&;L;U({_gpT7z=e+GE6 z^-$Fa3T4B}g<2vqn^nK?VoZ3DrOG(M157;(UO*60307{V2NZRBbMrM1)7<(~M_dm+ zPZRV0+M5DlTPP=r8_;i9eTf>Px*lKMH1UX?o@QwkOUt4C_ToxCni!7#h$dwqFiETN zrF8v6s*xTz0UF%oSP^g_nD#<-I|oreHjj5zy9ST2ta|vMmrOh7FH09Dw1GLcD6y9iLB)aeAyE6lXRS!NdDjN9^KZtN0M{bY^5MrCc6YeJ& zbenD+j=YCAp!1l1fIFrKmaqVOjS>L%(CKmalt8=zglQC<1H(8XN5cIJ6^Oo{qt%SG zw=(V0O_*`OR7WEzkv6mH^rp~FziMlSh$fvsWVdvZ2~RextKW6d3l5+rt8trCG*@$d zQ_pIUT`{dZCC7fF(8LPdHZOWf?fg~Z%tM9h$5&S8Xx5jBUF8dhbfSg4zX35NmJ zNK1$n^2TuLehD426t*Dr>M_M0c~Wo|pRoFsLAv+gxgz)*J$*kPEWT2+Za8lj3n6tm zRvc38s}oS%Qj%Dv)Wxd84YmgrlXt9Q#(rZ=?U~#oQ2Kg#(a%G9z)EcduAxKU5%Qe&O%4(pq4&j4RxcN z_reN%e7YU04r14sJ1I<0+{Lb6qlGb@JL#k_U8DCT?-*0};Yaq%A^zO%?zaAv^$q_j z1yXwW*@YFK&gSmIeks0h@^F-BlQ>uVVo14m3%9BM41YB*fwc3ZHxKt#%vrPS*4ZPR zp+p{O=F${&UCZNfnTlZ1kCjGgaN|xe5ANNqch=M;kGj&0A1Bir8V z>{O@I-z()`=uqg!!&vsF3=4+n0(zwd=|!5kXo4SaoA|z75r@tmF}O&tn&y{RQhniD zJPH3Ac z{~Q>I$$W!?QfaQ5wS^^=_SqtJN6++3&kz+A6pfnNDlD|krh*K%;f{wlV3A^x(I+b_ z6Dvw8%?*?d{0CSHT8e+t_hF_WCIbZIBHB(YW~%Lmz#F~+)_&qDipiDP`~wXUE8i=<;Bc5jE}#PQ{@6*iO? zj4iHO{NmH}BPJmlql={DSJPQ1@@Ea5_Qbv(IEq!9uduMPp{}yGg0M1?p?_c5)v64? z*!skH683v-=Q8N*<+A?dTj<~A|5o*W@z36SE5qKs%W+rPMNwt%Vf-IFK$m~Rs^74fX^bJ2M|%DbdE7Nb2Mc>Je0(K55MFKQJ9qFPjTdRh2_9e z{uJ{}K-5ryRC*h3>^Q1trE{?!Szy>(kv0aaR)5qG{jlt&8UFdj`~KnXO>C4tKGEb6 zTNN?_y9H^-NCbC3Pl9h1aW(!n{B(xELDhfIy2 zg9nx=oZhS*>$C>mp?VoXRXF-7!Ey9JJjuq4pPVZrdCl|$%a$S=fY+v=P?N`MlXz|H zmn}uqSXG;vZh+>-+;WV&as&POsbx#i+=xt?;Td%`Og_ZG+`zf8q4vv`GRJ634*c_8 zGVp&_KRKBA#W#od?*;tFZ|MX66T(j;@E>O_6rU14&VxUqH2>$||J8HkM$s-uWWUl% zV6*XjR5}{(KVP{cEm~td>HQaCubr&XZSfFoOf36*dwIpwt z&4oPe$7T+$sY6bfs`xJ$1X=K?PgCA*`z0o9V9o7JRCdh#P}|zZGm{yR+Lh8SO!Fx? zjgP$;hK_ttcz{nqdW_NG`bhfX+!XuO-WQd~x|W?$=VG5#A=|^j^I+o<7`FYpkPZ zTYkeV%CF&aXfAjjj#ijMbHDr=Tj&#bht}lsYqS^3BE)_xGVySIok*$O4J8Ywji@VI9fQuDTx{dINiA#}UrPOOa0Jcb6RRbqECkj(mc*MPh)_{)WD<=x^R=ds%$U3Cx>qZyjZ1xj=4UwIXI zHx8%UmMla2BHaSyElcxRGIl*XS3ukp%;BM&$W?;CfjIcSqnb1s%A3MMD@>KaW>EtT z)Yd&ZZmn`$ckoF~-Ok#!wPK#Qmm7X!G*(?WeXiB1R7e=j+%ookmOufc2DQ8A`ID8N+Gz;q^5%V)g^<287%F)@Za z`2k-ro6as$t_&4j#=RxT@JHSIcWfq@;xMtA<$#13>tz>Ek(4FISo=gLMz0~rBN@ty z*G^P@DvnvJwhV4_jjKeD;Q!ivegj>YaX2BwL=G$@=jnSS0rthBY#7t`sd6QVTJUxB zmM9fQ4Pe0EmUw&FkKQF2M!3q`Hqjl~*94$i|Du6$BZsNMS2y6`&;fNNDaP=kIf#yweC&Ua@uFKbPNJ$TytK4wYA zBL2>J$PvIxBD-DsixlQNBSbo|4kqdHUs(E!wfXcHwp|tGzv%q8`7a97UkIJyO{BjN z$;hX__!4(yP8Dj9{9+P!Ntbv)<|O2CO>z}ao!OuLL*{tFGn%}VCXW;smIZ@ZHX)Cv zC7Sl&>+9f1nM2Lj0eq?B6PN7bobcl^4Et%eXURK=a2g!?IKCwyoBG)jqAIASg*7m% za}(tcP1Xulc{@dF=$>(xXtp(7n$*1hCVa7pCI)-TCPo}3sIdGLHCV4(TcHG0OIC_7 zA4N+qVagvzMj7Yk-(X#|9|jb)080HcJTb4xaaW~iaVbv}Q?f=IF-(6gc_tLahjnOz zGD(2cQ6dS3oheGzt;_jiP@CnGX#Y?7B(%k3`6MtBv#Qqv4*jQe5}L*czhtz!hx=SQ ziDnh*pH9NaU7vIk9V(`IWNv~Zzi)E7+K`<7bADN)vQF1^DBao~6RiGANVIEU<9x<> z3S){kUod&Ik`#Hnb2A|(-@zZtsA43~f`@(cNszxFq54du?CG(v|J8ohM_O1;ZV?={*kj5I0;A z%!9!(;LiSwC5;do)Wo`zeo+R`&#TN$iW~7o1I8kY3Qm<9_|AxqahtHyO03-4|pmkIw&OoRO$j7@zx(Cry2r8hqeW z|2{tVPZU&q?nkU&E^|?VP`+P$ZcbRT^FI}Z+t?ueoN$P&9j#yiQ?@UsYR6p59s-5D zwr^=VrO1<0#rEWO%jBv>C_7$B7gbu^Nm)A=F>T^y6JIos`7FWpOOSF3L^=>gJ0Q$>v>N8eEF_v zr)3F0>Rr1%=7BhM@cfY&vy6PZ`XzGsqo&g+$At!~_4eQ{a_A=zP!{t6>C3}NX7d?;ccg0`eL*S=p!Bu0NHetX=3+Uh>W^m0>A2T>BesHBVC~r=8ieta- zAH-|HZG!d3YqNtMEe)lKPR6|oGmBmZA~`FgGmB5+zF(EUc|w-J?ZMllZ24Yb4#}qs zWj+oUt-6w{d{}EL%@*dQ#s4m>b$vsMf%Fe+rPju~UFzlEqd6opL^nInZxf*u*>(1y z%Gj*(t|2(F?^`KDS@x%p01I8ciBGzQf2q0mybsxS{)P4b3_yA0wXM|AD$#z?}Vuwq2-e6fuAJWBlHn=WYP0hKQ_^v6uDGADNAntE&_M5Qo*BmGp(O9Ij-nU*3(?sO;_+doeIT*__ zgOLBzL$cLehyFg9D}_@xT&dVY(aDwkfyWhh3S^D4eQfYYnfJ@~=SO0&pR7Su2UY5$n z$NuwD*?ZmpwWV_S{r`VlDnH=pricwM=$2_3w3jqsXrCD$_rI2pxb@G@1>D+dEeyDg z^c%zewtY8zIE*)a7yKu)S&07$@ZXLY6KRlZ3ST&t34LG@67hcVwyPSqW{;+;qMu^C z+7Vi&Ulx&3Z4_3~Cpn`?<~GWU%*H;mg-DoFO0Xl)$X$G~Mg1u>!=3!)|mx{HM*_GW5TSYQGoOTu2b-g0Hu2E#ybm?VZcH0^7 zHvu+#ID*)_2w*3u(uGti$yq8@*AV^*({KC^7LStR;lF$rhTPuH7(}a61R=8JN z!N%==^6&uKh_VO4L!3)esHKc_O}9QmKTT6PJ+~`+{(xCE?vNz6B|E7!70Gj4!eoE3 zj=ul+!=`pjbfOzu9nRkG@(KMBIb%T2L&zT{J+g87|h7igjYq0DP zjQgu4=buhtQ}pwj;ql6mrL(SyYBI=onIi{oGbuF|M!2{;X5j?-7aU#UWNNi43%y!H zrdIFz$kaJ|O|AjWkPD>g`GIg${kOzCZNDS{iOISXgXas~b8)Yfn)3)(q4%_{8amL) zBa^}UhWv<}lmsVygSa2JGjHapUYf(Qh9mHTe`y_u}rX{1$l zFcN^;EMd$>G;l?LbR5JS@FWSTT4Y`H3m#{X6<8AAw7lr|Ag_dDuj)kzQ=$PB$jKs8Zdq!9-rq z@TMeq|8VL($i(}q{C21jV#49US;xG{O%AL*tDBv`_;6gwK-^x=N~=*T98M~qgV-LlKqvrOmV~w=gGbV2PI6mJ(tc=@2aKNQUqS&gZ zTlG=QO)R2|?g?}0d}SbnYEBB*zOT{+Fy<7EI&rT#C2!$t0Gr&CBpgmRnMuFa7SM>) zy;72@_GCzwcp)*czqW&Z)Oohz-9paDjlx~(iy?%rE_}s$BX%bo-hx8iaVu+Rbyn%TkIXVZQxJtCL`|6Uc(6j*G z6F2Jh5xn+VhVe=$%^4`OUZeu=_D=8jYok^YL-)nHpwQEkbru_(ctG>xpl|Wd2kCRI zIrb4v-lsxura2_Qb*|^hjBTqDz^Gw+%h%i51lcv4M688PgL7#+a#wsi zN_F<`5gEnY1LWWM0Fr^5X*?#)EJ znTD>VA;2*B=k|MPh`R!#KFb`&Le?0R(RTM32P8VAs)I{^uliVKDp-*nEvzNjoaI?c zW##Ka8bB_wi15iNI|fW$dTzFMZf1--9}p(kCZJov(b{}$MW@B&h%97#(R&s_9V2}3 z=KqWKgip{xTy3s-C3?xOtMKKe>|exY%hqKdVP>Kkw^IepjNJ2kvC7X;MqF5fP5DO| zXN))^U^(gA);YHXYyI=~7?+F~U2XcWd0zLof6JkcP1QYwbI@7j|25|1>^TSKPf{Dj zpW0#P$-2KQv+fM}Lp3G+^Vnd;`%|3-1@sG&K6$2J^g(`iBsnli8NZ3Mi*558_vu&- z*pSFxD!oP=wNFdPxy_f{T99P zi$=&1!bk|u0-kyDH-lG-prxPXLWH35ZExWmep4(j^+I^i%r6x8hsvx?Tb z#`Qu7q8`M{IT~r$O+0TXZm5mpB~|TlT^a4`s1}uIgd3Zf5Cp2n(GTb|ndosNCtbo+W_7WoAfff+G&T_}6+5;j^qh#gpmPVv4aljI_Zg1xGXsCs0*7@x@!XL}aFbIofKu z&ulH;g4+d@6~+x=uG^>pIZNT}=VHA87Gjgx^WXq({ZWt5^u6$_wm%6@;#ZZR(SH2u z3SN6HuWBs+dwzAH*>*yHwf;88ug+w=*|X@r^m!+;GeUJc625XggyA&vT!Pv%evR)8 z)&sxzzyAnD-detswJq8W>22eMA(c1|+``ZV)wx}dK?oSt;3mG(brshW!)usNNCoiF zNkVdl>w(F2EZe}o=6DB?{L|qV1lKw46inX$TFLsb8S{xg6L!c_q|dS5^y5B4=4Di9 zId(PT@@>qa`X9WoypZ>(Dj{6E>^Hwph7`@G}#ti%N%}5B<`1pllzJ?)DOT!R~N_JHXg}56I!;Pza6T^7*UK@t?kA(b&vUQ}M zCyHM~H+gLmz%g57jDah*(V_3J_|%Q1?x7_47<4#>KWbt4RNbB(UY7)aE$h?mU$QLI zcNwF|e%oDZCbC~)lMwUO=6^=!E88Ep&GB5e>0S!f)LBm4X1XXF)p{H5Qrkv~VmLzU zMQ(MD`Uss7r=G}1PL`GxWwP!Jg@O&eTlc0Pk~!;E4ILnBU1Y|#z17572#c-gN}h0r z*_z6Mdaw3pUFpnPwh^oS;zuYE8Mlg;|K6lcJqzN+`-gjA+tPUY*tVjY3(~^${4`o0 z&Rw&77-osL8h-6xfWqK5#I0uvcT0y#tJL!yRmU zmEDamRJX2e7)EpMgjQUvoZ)Hr)il^@UJH4nlYkp40&C1T)U1K@vt>{Cop5k_Fly&k zvpk#PRkDM_Xe3Lwrtw1mrG<#(KYs7b~c`Z0r+fr~9mp#VlA3#Oat z-FU(Kz=)ZpGbQMLpKJd@WZmltA;-w$)Jf>yt>GX-8_9NUSzpMKbdZIr2ptTS?h?9ui`zX5td8by^q#t~MPjdce z@?A~8!@rkR?pD4nOiIto!!eoeHTjadx#Mkt1xX zGmw}77(*B6O1A97nO_k(;LBzHu){*rF$bCWMZ*cStS#@XsqCKpIh-ri1RCfgztsxt zxcWoc^U=7Syx`jB<#JwnE$1R_ICkGT>m@#qd$)H~d%y2c8<9kPs^2hRA2F$Q@(kth zFB53F)Of|43Y-XRm`Fs=W#ero3oMSJQq6@m9hZFpxMpVA$wN3?Q$+|TbBOy4P zQ3UDh7U>j$5M^9O>6#d+V%@GfQYx7VoJ>v!kWxh@d3g`zaIBzyn`M9GAN17K5^7|c z)0Cfb0o%=#4?g=d$9sisk=vdGd37;k(!esVD&O!HPDfNqzcGfCaZ#s`sW1EuL_FUn zU8!eahoKgg7Qs+CH_?ql9afd103{K2MSQuL7s0Q7>N>JarReuGIwUCnX^*;P-=gzm zQh(q`vXO%neIAxLQ`3<8Qz*Ai+>^%GL#uk5p0v`gH8_)7HCH-71dUjil3ULxs@yvJ zGn^QOzvk<;u~%yem5EZ%vfMoX1US7atXGA@vn%l2GyFA3_{Eq1+Om|C7Uj4&6VR=8 zm=MA?Q+V9AfiDDu840Yt_dP^xRvh=Lc${AchViT z=?&?18ZI@%kF((b#hIEZ6MQ6`x(J7s@h~$ydnc5y)-S?LCZkWMH~-g2TTCfOEK0`@ zqIag_ch34p_GZcQx%?{S^8MVo9O%(c8!`iJrs@zV{sqb&Bge^-n%EO0a0f3InZom> zJMyR$;j-obpz)9fDEO5k-qmwTD{t zDtRc2ivEDw{yh~vAx}l;-R-F8=xh-KqIySMzrka#<(Pj%KZ!qwZmwdgn%;$We$BXN zNIU;~zT=9@>z5JA`Der`vtH|khP22Csk-eZamvgsETt=_15r$1gV+4ZVf~!~lk&EZ z`bq$nED|BoS^mf)M21B$HP!Enqo(pS6NsF-M|4b&GO3k?G%}vKU{5?f0qx#VM}bOGm6mUwN*u#=3P2(9V&8 z=8t;BJ)|;h(6|s!&}Mhb*&!L+zDjfH6zW>`Y|6SKU#1*w%oD};h2$_A-7W@XedGM6 zQ3Xih80ek!HmkEjB7$ec@TLDi3?Jk@AZ(JxTOR>Tny`8)atM1J!Ujl$LQp@`ejUH> z$7QuUlKP<(Ux)P(r_X+cIg9kymR}InM7q)7(_fwpB7CBubf)G(Xp!N5$~K@jliwA_ zJG0+F0d(3-_Tz}J;ibp?iy~&%LLYJOxQyJn&L5y}eBlHdlXg{;exx8}u3|>3!t=X3 zG|8DpLX7i~ge%NyM&Nvfl&$rYAPmr1Ft~7ec*21BSv^~EGcl#=HYd_6PDKbVyxhgjt0gvn@8C!O0ge;*P)-ZAnS1FfddKj(EpGmG zUJ@y;90L|7->#QzP0W<*(_P%8{5$MzDjn3O|HU}~*?;j=M6-(hdInbY^zY=p+t)H;Ui$4@To;FmE)ylB& z!m3x24y!ndk0%Dns!uACB^=%q>$3nLGOnA7;3`@NM9yl-3UKd?9%yk}XuMBXytW(p zSIx*#p@eh@ikT)zN)phLq|fQaT2akm#n2;1P1Q5m~1Tlunx*n_eRyR| z=)AnG)1*Ev*Sk+jU}vYLVJrdgb*m)*O=?4AUq!`W@V5rzsdqg`9&g}`scRlnVQe+p znOP5IMKd1ZdB?B!S_acPeLDJ)JHjA%WD7ob@$YQxjJV7lXpVExKX}!_-&!pQ2@Gy( zb$l|x|CfH@lK9m4CGksF_aUK$834XS8({x&!G*hDkrP|tM-lxsNGQr9goJt4t>m6y zLLfoZ{)TV;m&X5TY*~zdL&J%&ZqjOzbg{0ZFA%;H0^yMm2xLrO<$$oE@!>)s%zYa? z_KrW?Yxynh80-;_TDe9DS|y#xj@T0jk0(a->Yg+w8u#gaetsOXgnRKMUj4E7K{ojA zOO79G0WAyoLG~F@gb_*K+G}N+asAbVmsiw-tToxHhFYjgzxg`|;!X=p4_e&2jj=ltEz2GoOj=8S$ zOnPX=Jee!^3^WT9c7G!GESDD{dj!v%p|}d117=?9!CXk1I*M13sM)=&Ag*6@Hu&?@ zd|dypdCL$t1wZFubU2*mqcFA~eK#N1PyGv&fLj~cs*c$HI!90~UVjc1k})Y4vTwoo z#Py?bH&fc8_s^${c;yVb$;oa>g5VoaFwoO<0dh7b6}Dg7#(~hu?O1J+3euN|QlCV+ zl0bE4fy1P!Jv?_pM2a9$MX=JKsC&x)BIeYYSONTNED|44Y(CGKHux2GQ+X{c(~W=9 zuYc&aNe}~g%sH(H77Cs2#g0eZ^k)|aR00rj-OsKsYGB&Z<~9FF)A{gT0+gw@%frk43{#4k;X(*E)1@qL^!Q3Hh(u*@YNr< zsV)gh4;NmIn!*DR$52X&Fq+{qzC++Sg*R{{Y0O|6ML)}fltt;+FGPf@#)SezR*$G4 zJ2{kx;Psal;Z_rKft~iRCQEZ_`S@Z4G{te06ymtKe)q_H9mPq7MCOAds>PDZkLz%i zHPf`Ya^MyMr{dvb`Sc9$EjT}WC6g?`FQY2L*3W*o@cf)TlI~z%8(#F@;`3S2TKf8r zcy!yT35_99Jbo?Sni~zQIWw+k16sm&SfH}u@_~t}+@MSB3U0dC6a>{Pp-&`+W!gU& z|NTtAg7FtJDo%1=X9ngD7le<+{ZuPKAjyugV|HS{jFiZ{gE}CPf}C)WWxu92Sb=Ul2~+J z^O7Djm%JfhM-uU>-~Jiwu@3r$gB zQ*tGdE(>o;g4^V@-I5DA>34#5E>@=ai6ti9r-G)}OuUa`RQid;zoeM9Wan;ng3O^z zSz&zsFA6e<_57gl`0hnJH}%Yq1l#b}9UBwrZI8OP!ua@!wA42~zFUK0a3a@I=9cg) z2LTOMLZ>D~@$n+x1@ZCi;b-;s7*SMIHR#-g+ULmVN?u6LhYbJiRwy=s-tO<3`MSK(vj8Pp#eZl&tw&vpJci!TL zdDpr9@8?KBle=u0(Z=JQ!NWb)TTtXnrN z7E(wWp7bdfX-qPXth}JBbVMiwFrYXEhMnhAvD&0gaR_G?`ybWt&_zlud1Wy6| zhp%%c5Uwt*chPh%Y*Y8FQZkuYxO1bD?7FS5td&oE+w%WB&N76YuY zwBn58-zK!0`Bo*83%|p!*5IMx8uS)6$sUpO#E zaJOR#sf7)_5wU-yP5z#!#ZjVw5?<$)K_GLr(WeEs(3)mbU~qPp>{D0>tm7J?tAGMk z(FinX-B@jE)vcdMmkF+Fbs@zn(~o#}FM@sCyg_EtuIvy98!}Up*4~BN+^XVVqPXOm zUjhBDA$jA)a4t#cm;DfST#hQt7V!%K@32E4A5vlGaBll7Gq~>~F+|7AVHbNe6ceV< z+68#)JEL8645S_ZD4C#{5yzG0RTJrgdfe!Oj`i53EWUM~Ot+ci1#IWL{~+Cu1?KV1BKhG0LHH<0qhc=~NC#f0!zIJmD-~ zRQAqp&K#O1*Y0{tiNH~Iaew;ISb3+sApIHpNDj!9+{!l-{LlZ6`UjxmPeq_S(;qpW z`3lz0VXYjIp)O5F(QhkP-SFe`Rp7&Tb2BrvF>!=WCkaNvPg`T~iznI-);Ki`+kltu zk2IkBREGUQ$_A%{GioO*VYy4O(77csHNPY%Ui?^w;ybszvNx+K-EV*TZe9x?20!BP zL4L1Y2T`5dL+H6%j;mMjFn+%v>f|&LpGhJ^lR1{|Mrug;4W(0^yjR1x(k~dt!3$Kr zMkE|GH@`&bq~Pw^^m|h2WSEu%xwr6ODzElu#p1DtYU}p3a6aaJ8Y#Xy_z?Pok5csn zjYrgnAr)Jn6?Ui96s_cQ$`M$Lg`F6hG`IP?dh>VwS(h(UguQthXeH#N) za9Y5x)4pr!t{f1&u`Y+QUuNtMWsl~HFn$v?pq>GSx>GO~3b3(NzkDpH8+LSM|r|gPF1^F-br_WbWcktC`%^J|uXPxKh zZ$CldWb4hY;PSN&Kd%vf4$9-__nmRzk0>w$EMFh+`J}$_Kly2X-V1#CjI97Zr`~@+ z`24B;0PyJpVTw(8 zxRoZ`>+qwOQnaS?#eqHV3+YMAs-hjI;b=bGoAfY-PyEcCeLrz{QElZDjnCmK_*-Y4 zK9#C3T_whS>YkoM!u}@l*AsX~HdFgBlD}R$Y_2!y32I_v+`QI{TG~2hZ-UgkU%iyy zL2X&^yBp+oRm;{3pFzYJ_H~%?|G-RnlLqgcM@isHZM{@}X(eN-$S&11GBd(XV>6Bk zTfW-tqx#ZZcC{ftsAplsPvuL+r2mzrcMsKGh~ya^Kwg;1(Uc18q!K6H#&B@X8e0>s zKW8?u1BoVei^?E$ij-B4d&y+Y1&50$$%NPzW0~NaBD%DWk~Rw;;%&TT&p@yBi(J*D zcPVyN!hSZGF%*m#PVglLiyM-b>zV)tOx{I{ke4t9hM7qfLh@Q%H2kA+Ke;zL zsuOusVFCmZxYIg`Q^N1yAJDvz9L{$^YZ$F0#Egu;S*EEZ5_@g zc^`8)fP;Anl=J_I*w=Lsx=?s-)9pF>JE(d<`k=nmF;5M*YeKeAfmFlhQ$%W=Jl=0S zueZ4I{BE_z)A&UvOSskWS(;lEVJC{lqm(rZ##Uo3GNUj*f8wbo4q_JtIZ9me2mdsD zQ4+LwP8yIs*EX=inQ2#M`odv*3y!9>+|WfW8G2UvQ&2VU(n@vzIe!Ru)HvyG<<$uJ zo%8B4^@elDxx7c0nQC&S&w~28)2tZOP|BnmHFMBIk$uOuKfvcqYa&Y~M%|HR+9+!`e1BVLEy= z93P2T;+2ni^Hnrn+3oo%rxv>gBY1&_@ZQn#Gbp}_r>yQNo$<^--frP9U`zGVElkUTji8f|0n$)g_oOl& zCoy-aW*z32R0T($Kn2n_Is9}E{s$|JSn18ELwS?*Pq5uR5vhqdB#6++9B|^ln%!!s zPj+=M3iGCvSHnb=oW=%Um241d%1$R>K+RmI{HsjyChSA5$NuR>E|C<+qgJqEYOd;{ zPSxqBXat|}DHjy!6i_kB2}Q(W)i4yVEXy_@Ja_6=e&LvtH?-^~hW`UhCM@i0MQ-VH zc{ssCnb1w@^=EnxCHH-tdgV8XZZ(c9_|K^3R71LNU* znh}S$>>lVXXr_^bf6+VRI!x|SW_mG`sY8kkXhYb(o^shiMPS@6fsfxEdNH-A$SZr5 zhAta23{0H5x7wSu!z+720DX*4{sMAMeTOf4n7K!Fvpbx|b=-`Y8KaRAsX=V&u5O&4 zM44p&`1~pq*Wr^E?n%WIzBhc>T)CdBgQO@=E~)j88fZRW>~`iH32WD;V+8y`m?xMP+uKn|tB z-y1sj*49<$97${aBn^+SI1Gso`cwjpx1df4CLsplbd3^bv0>aZco9B>HZQ}Dw6QyZ z6px4z$fKmkX?zY;9E(Aq#Uw{W(o?-li_*MThM09d%&wD1huz3{M@k+YIk%uD35O<- zKBW%(gR?V5uCl?g^xFuF@QzfgloBt1?o>xYmpzg+3+-5!%U%El)9s*~$(sB^>rZ6^k z>$NzGa@+bULk11^I2j}BS&AM1X{neZh)87A%==^|GMm>{kC8U}J+t_p54h}924bHC zteY51)t>Ag$D`$g`&XTEX-d)L41Rm=WE3gU9aNY((&_Btk3Z(Vnl;J(Xw#RI>Bl1e zXhP5YZ}S#cUbsBl&6t!dnfun@redVrK`@t#CH{@Y#)nWsjw=nsSiiYo$%L*gjzc)g}3k%k#ZA?dLAy^(EfA3^F3=&1qx4dvh<5O;&TXf zOG>$uAqf!LJd)&K1PcI-Hk#--uuK~=!8-BpI?tQ2!36R>=!wQ0Npy!W6sXwPVBDv}y*ed*%nU*FNDsB6chXVm2Pt1j7nzxPu8=J^2)-|ERu>h#&m&(7GH%Ig|a}P5A>lz{aWy14a zAm9t!3N=I{q&~0Ly+3Mo__(5PcGKYE58&Xz*x9)=KKXsVil;m9ieE5|^@XqCxQ&s4 zGrn_MP2E!j>ApegM!(2x=57PVCf(Oo2UnAOigWs>sxBu^)J=gKtZ)jrs(Hn z7l8MgJn-`Z_=NJql%hG5O3jfha_O*UzV9|)$`L$*m2Hl*7nh7}u8BPzCj(ep6XS(z zRfyiMZv2;)rpA*@BZ>|m95iUgvHhtsh+79;k>PJZJ(l(EP*DzlOc7mh4Y*>O^ZDVv z09LHOm?_-$gxEZ_1E~GtAE@e1W0SN1G0!A>}0YH4XO;^^}R$gP#r;;=EEMk#GflyO7n+355pJ&v&4 zO_3=$o0e_xCOt*u$2A^)if?$|!zs1;q1KMZQ>=U`B_E?uHyBU{KU@+x_u86*e}{tXgA0oxU2@kbT$F+og0 z&#$-cb)o~VYuZt3y$@0-x1rV-xvZ zgbc;r*!$vdJ%~QJj=Mx=y!=Mm9^+aX`$>EwWwZ5BE~1dg>#s%#NF9f&ZsvBs_!=H~ zW!r)Zp0TfHhD+m_#xVTiFYq3G*_NYj#sNjom|U>cpYKk<>WU>cO6fX8E_P9Ce)-HEZn6 zwFDZdxr(GO0a*=$T|~|saK9&?i zlp7XV;GzJp6@`rxGAYj~no6pq#6&rGU`+`5u6=8L;`MNS$j!fl)Ka{AgcWVlm*ib# zHNZLbF@g}%Krs1aGFi9mi#2{FGYJ1;=+nT=5%i@&<*gBVhnSb*iC_Gi8OF~C-)+B_ z0vcO$GlQ$@SZ^OI5b!jp{PFS^P@c}t3=V$K$(cfKESb_#`pB7maNQqu6yM3(J#e|( zV)`(0L7`-MTfg%E{D#W!3O3&D%I{|Xq(B6=psT#Sw?MqlDn!fX_Fnaju?r1AD!UdO z7^nfW^(4`23TT3y#WkzA9r16T+Ju5~6%z7f)DWsc(xb^UWY(uS#Lod50F?xH9((?P zta3LA5fOLF-Sv_e`c_B9-)?$6+cZ71&I-r`l6L2kRuMF2OxMX z&VJsy4_^r?-{-t_$9KM0Z{2398j$YvM>dm+DB)i>DB({%Gp1H`_?kPUvwc1d%1~ZG zN5+rv{5`x%((Q@r77&Vfq{`~~ zh0lFrMBD zes0!Bt=qG$6bTXbJy5JBCaAhxe2EniqHC@v@hc>1{cHi-Dq$%gm?2=GMm6+2D`ON?8e4Wi|1I80pwTA_Pk+D(@H9^AeW5qd!i2gpH&9Cg6 z7{wwmM{GeAJGOwcU{pYZ3faQ*_D#4Hjg|YwcYj43N?VyUY{T=XbHW5SGt?X4gX*_I zKo=l*z;16S5vXhC&*mfo_D-FXE3gX29nQuE)lM_}23w$m&#;Ef4`|dVy9Q&TnL)Ww z6KayrLSWl;k^#USJM(}f%4`E#dmdztChJfjzxWEiXGR8p z$$m+aDxrdD2_q_=x(H$a2$}-5HSas0%a&1>I9~k1T5JVQx+c`xQm0^OC~z-LKLINl zr7_HT)q2l7jb;If?+svx3U?c7_xG8wgr4L?08U=#+8OJD#83M(Lk#Al9{94E-@54& z`MwTRVyP=}r%DVsV2PP3(G|S-ldZT5ZSN-xO>>{$qt824Lac?(rXOMyYSwuHia36R zvG7nW9o*YELOfER>43-9-*X{v*wy@6Fj~`psiu4M$-z=8WY5q#>)?0%`@H#|wEI?T zt7|~c8Muez1fz#JxkiLRY%aIc`IjpUDtZ?D?GKK<3ewu49L_HaSO{V5bdFV1a~{;x z^bsT7eowwVrr#MsdlvKq(n+)@Ie6I}PGbB3CG+2bg<)v+d0h4TG{&d$54b%1^iRU) z+z=@r?wO9}$~y-8Y5paIAw2Y5=?o;AXg(sV?%C^Q|2$SHh1N5&c;(@nJQYU27Y@rmq6Ns?H3GSFWFZu;N%2dcz7^&!65nOEq*fd{)!9iH}%Eqyu%w z-+0Fly!z;TvpJ)3Hpxffcoy3vn{3kdJc5J1)%wtr8$ct6XLODG7eCLlQ)nH}B_&d00-)=}36TcX;!@r(2CudxxQG4j*c%i(*lc5C z<`jZDR!tZmR(q*5*+geLrMF6*kJ?28j@*3^B}52@3lM(sho~n=51G^lV)XBt!!V(_ zPYfDc7%f7^BmAfbgi%00TuN*p78M*mR1ddMg0H*z6Da40aAj12X-(ZbEBP^)0zQG4 zoVYnik`_0fImNb<^Fj+EioUT_xvixgT$1`uucxUqu`ap7PbYgPgM3NlFo^<|$?A;O z9^S||vpM*NtmhLY$V4#f=B1c1dS0lW3yQiixi5lVNpK``50z3PjO` z%p4r#PQ4@4Ybm!-SP5Zej4fI|m=0p=iELI^XWnSCf?g+OL(uAOU154dIOE6}(?nGj zVycY^VWv8YFxd;kOahR0J)$303%X3R6+z4s6kZK)3r{=+1PFtB7`VYm zY|vHubW3_|Db~uS+EK&IsCefKw6_ZLiNP>4wW1 zgt>xg#?>=bFimZZ+j}{@!_8vm%sq+pnR`$J;%TdaL;wtpzz)t(kkGAh+m!l) zYc2)eWIhe1pA95=?kK5i%iK0wC&Rw<#t?7N9rhc~Oe)=zNiFH6g;E{#(3>46&VT$G zZ=Ou0@SSbYGtL+S2+oHjlS-JId008d_<#jQu281cl4En{-OjStJHcX%5VJ_nzG)iy9 z&*oeCU<6aas_*8h3>~K-7i6DDBvC6uxGo#2xRX&{p6XW|nf2WE4X$~luZ0*2aB2N< z__ZcI)Yle;k3_oSng6OB>$P3VH0A6QYOI%c-tiUQ-19Vn{)tD?{fO$Yt}Xcos~mfG z@XuOH`XXUkE&D|min5Dd$Zu)VjSz2w%g&@iBMj_elNMNp@(@U1x4{Z`2b~(~(x(Nt zQmZ_F?xaeL12iadC={(tuMg5?=z(-o_leAKvw-}SlEzlhS$G^xQ+kNkb~~bA_8XBr zhrK@g4pSHTkAg(v9{P_a3Q->5AOEpffgwa;8bl!+u#%G=fZKK=zMdKs3;B@3=E0 zU!x5c?0t)PPPqsICCs7u2!>HLT0e%~!U0j(3JNh9ArE(CSS0m3I2;RtqTftV1b#)* zrFY4*kaW(i4pDp0VtU|I?DJ#0u^kW1Mf8b82pX!28ZuVoI=ms*uyu!Clmy@N3a4|Z z(h0OFB-8XT$D3C`NNl)DoFScW=9arlW~4G#!nLAAq!|FABxRVBDPU$~e(^R_jxyvnZY)QcI|2(} zPvZ%nRN3Jt%J?2UdrN;ET4#gaHd!X;HGDByh5kSxw`0Z=GoO(5(CVn?wcHX~OPgKQ zW9^)P%WPBN4|E!I)d!*-f44DIm*8Q{>!wraNLeCNl1SfShdyb~rQPHxyd16aDyocE zJ~(qIU#DN->#jjL6;Mt(AhXjm&D^ZQk(18fE;R8$PX56ozX;9E+(;k3hhNi&1s*OO zaQ5@z?WeZ3Q=`<@yT9u+-cs5w*i*?~EBq?la`Z=Cz$a3YuMahFuk|TWwB>Flnb4WMXZC~uz`yObuYo#sT{;3(h?7cR zSplaRKKKV0Xp~*!I&j6UM_cSgxnRFo+s)gm)2~4CCQ_XL6%~doeV^Nu+=<5EVn32~ z;UTweN_WQR&m@(LJUr`l=aX_R7FSMk+L%|fgM%#fM2HuvC)2phkj~oSq4+f27TDtc z$RS}EIpO208IyXhXkjkPQ~@3wg1=};6F2wU&Ccg^KUpuSi*}s`gr5R#&VWbHC@TY} z?!{8v`Yfksp`K895NVwqjkQh1?J)`g9TZehZDw()u0V9u?%2%K0yykOLrYk1g5V}v zyxTdFWEzPnxXZes#NBqDjyrM+C~_>2ZQ~-6asDjrX;dpAp*o3EJ>-$J0x5UgB{Fvy z;B>Z{9S9fjuAKRDe*CtXukiwiQ`nyM7M!h*G^*3XuT=}qJ<O*&sR7dBbPidlZ2^*&Kf@cZzId(e0}W9{2iyB=3R(QtV`!QY<-ZW7Cj60O z4gHatV2SH_tvRgrmTxHE238BttNqe}WVuU}Z(%sM#dq$q#n{dpzl#0J<(rN#TfUCu{baQ} zzd{FIOr!Q%zv$aFcutd=Ag`}g31A1y5!%c!Bk-`8Qgm}Nwo8I@73Z>cbG&KeUm4Yc zn`pBJk^pE_U3Ki)>ak@gC>_!x7b-o3_;dw#C#&<%O5$9oBEo% zHN2Py_NBt?1UjZ`CLaX@$g3_k3knL_AeL}W>6#3cIN9kLZ($G1jmKl-{ujuZi5FaA z%zdUwFc(R_QZ@#EfIi0w6WO9V4PoCaJgnOxROE0~byy8*A?g#Y5KTo*n&xNG-B!27 z&tr{C_oMmsWZzAsJ79Bq41UBm-3E5JkBQ8?j)nYT|EyRw$46+$EQz|c0?-nHCIVWt zY?HB0&Zq<|H%i7;1LToIy+qll_{VI73RBg9sN2ITHDBToXO#xgtu3__U!Ej=6< z@*4RZp7q+Mz$2>DYk=ZpDw26$bufeKH8l!%Lt4!gw_gPA*-_dmMRu(5cNiXe3l%yo zXQcu9h3)BmP2FFr{aV6o*4hzDn;BJ?&Ryhpow%TN9jHe(5)Dfwsiv1^Q-0AQ2!@kE zF=F_MN4$t&zV!)grrz>RsWG7u61XqrJ7^dKmNg6z54VbX(>s&p56i1BnSM5rev#9Y zdIn~Or#Hl&W*_U$36gp)BN;^b)snrC)l9kt6I*z)FC-n` z+TFpIsyp{$QZaagcBw(mjXQJABY9Zt8A|0+V}YEX>JU3&&E9WI0*~#`zNIT`UzX zg?1H6KN~G;1wH3yU|S-Me|1;S$ecZ2BC=LwS!O8hH}f(0pTLKdB>)d%-L19NkR0SN zJ5j!k5fXQ<#{Qk8MtJBxux;@JxtY2OP-~9^e|bf>hhu8zx863@EZl>w8uC@+U& zFhW%z|Hw>K6!$K~WH$n_AjdzoZ&f9*$u;FRgfcax2g-vaO&+WZQ~eWEpE}I>+gPO3Re$onR9%3Yu;5vCg~0mS z^vgBrJ=OB)b~}(Y>BmF-PNX}_w*z(m5jgzsnRO5XoMx8P56BO>qM94-}y!YcCzqchM7ojtf_mhwr+K8-D8}tT)wH+KkogY5F#YYqVt7;Ied}r zS5`oY5=BdtIiRRrHrt{*YhvpqRy^w(X)i5kWcF9JI_v374O<{&^a&#{SzGtok@4R0 zC&1<%$?#|%0^wGuRo0K%JIx}(l6xYFhNck?PxGcE+V_xkR9!i(h|{jr{NrGQ5D8@_ zfoukj3D*+ky_MT;uqZU4T%}V`W`0E7G8Emp36Y6B1aSD16=4wY9Ga(fW1%HM5St)X?&)9eQb5QyL^*Lu5VL=cvU#l>e3^j_yilwNl&Vs zB0`aPOwzQgg9QHw((Az;ro>dZH9`8(`KkaOts_fsd`i$o%4JwO^c z2of{ZD!&k%nKik#Zewk11Jck!KKfPkQI#6-uOs2nbVLeT$fiREO$bj( zaPH@|GvWlH61B+UQ@1ih;|lP&1;iKPu*EqUoC+sB?45}N71>k4e~@lMjudB=|E*dE zM$s3PoNXd8{tw`lX2#Z8Be%LlUk9{i zf~IwAYwKRx52KVBu$lhWl3{}*Wz0C@pbYXDsB|t`J0^CnR~-u|Vh~K8 zD&(pyW2WygswEk58egXB%2U_}OSl9^NLdz~b04=*P<$)zGHIhG{Z2ByGm(B-tg>f_ z!D?s-KZa9M?jnqIo)2pyl$y$o#f*h#%+EJQI%Jtp*?^}vtN(7B5#5br_=eWR9%YoMl5YK>sm$TNL?NJI z!Vs~#u(2r99MTc^cIO1YXjxFTO9==O3{8*A49&u#n9t|k>~EHe>(-Nh53`xWr?z`c zG!lDdGNkIIA1mZx0&j~#ga?&`))xVCjFSn>voyp)U}_)=#oTzh`-(*&;WVLwVQAFY z1jeUVJA=SRh^>f1`P&JZ1a?>Z#~lWVU67?KiFANKSx-Y+zp1*nlS^3MY60?ye_sLF z*22h>%dVc`IsO>6neIS}@25Xr8TS*#15AMoOlHMe5Vgk4jCE3lHYoPPZj{MXtXD_? z!0Lr1nk03@R7MNU5M8|Tx=5NJY0B#{LHe^$xNIc^rTGu=+Ufn>lCHLCPW_^T3C2$Or@xsR zgMBes-kU7njjgJ?+CP1-WGD;-P`pXE^wwa5OqF-ml8|rbCf!)r>ei>1_O4_AJ`W$#2^wB<;!$VZ(}TG4-#nEpR?q6p0@aj*$n^adg;t8D%4T zm?^Pta}waMN`dw)t{F)M=Hu?IWopv3w|sRHS}wvbuHs*}&x*29rhzjz41SS__!hlA zbs$$OxdMPfsunx(if8xm%;bv@vXLnE~$?7R+qm~T~5g0y5t~&$7QQplU!2%YzmW&%s3{m zHrA(Pxk2)qwP!JT~H_6nq5#u z`kMu{{sr$bOU+)p5?HX-O^Cvx3$!E~0$Rykh*M9;R%7r%lG!GanXm?4we!ju0#|V- z+8f)%#b_SOUOg4LHkvg5s2Q>Y3i4DVJ7B!>nS_^m1_NJIC8pBI5J*z-6ZN$-Jmd_4 zZzzOtp|ixjt?e@Hb=Fg-gk^M=G0q+c$^I^#830#Whh2~)5_R~9I5S|XobW@^azyr5 znFNzDb}q4YasG8p9fwOhdJD`3^4H%w_=i;Nc^25fRBWB3=*^Oz7R;x$MEdD!)&dpD znnBlvPvviD#pjHHbkkezY?M)ls>^$8VjB^=kpRio!0`&shL~Jph$ZR=4+77W4XP}% z5SnfkY@TE^41>#EHW`)zs02h)$ic!7BCCmMU=7O&xS9Z_D9KN}a;N7X#06chPj4C% z5_6PU38|o92wUw6Oyh}8=+lCO#NW6FJASh6ZE3nCuCTX!7em92_Y?=X|)EhPCxt zAsQZ*i5t(}QL|EE)_hKT zhh{B&Avj^2la33lgf=M%$r>ZrXj1YbR)pzrjzP+fey4_wu(O5VqGW7^5l=WEuj(~| zawn>xgI00tEqG23B}I+RzK&V3I{jKa{Y)XzNI#5N6%q|IDQ@UvQtXnroHB7a!7|WV zjbs@4s7$|ck40SnXavpFt#+YOKq)ddMi5otGoW`CMy-mO>X)B5XrM5gqwH^#z|*dW z;ZhUQM_U7FR3{Skt}$`9L?^sf*TuG`}AAvi}2 zkMjN3q@X;>qV2YGXOuD zzF7e`OXAI~A^$!mCHoA*E@g8@zyla;crEL)?0_>4WCy&Mb!c|LjvFR2<}%Fz_}eW+ z;{dMmRV|1W09a}^tUZ)eFpOZFnMdV)41gUnZY;vM;rKyc`yczMkwH&80z%LT6{Prx zWUvsMd7NJ341rFLEZ@sI*E(=~K^v(%g(i-vI|G64M^l8sxRTDg@ZQaTza1>SAZPwV z5|i~$TtfZKi{qiOr2J8)#biVAjRi%NvArVl$)lOMJtdtzGL0Acc(ceJc&cAie%nqN zSR!-aQU))-A!o=+l=om3Od!kFJ)!+SU3A+#JR_sW5~Dfn)~&|O0q;l=1BAi>azWQX zEOPRsZrp<$KhJi1LQE5QQn443u_uu9Z!xD8D+ZrG~6gS73g3k&}qnFD)FT3VABiX0SA|0|Jxi?gLuZs#<;E)mO)aVA0} zK_F<75c1FX>exT95Por7p@k571h@pc{VarI%ihgGNZfDZt;je@KEptGVIKpbU?!H9 z8J!&)83;pSot=PvFrMDj&pvo7JQO0)b}kGvG!H^`cJ9bN!HfNi-!F;hVdzTIut-Ld(kk@IK?CtlLX?mOi6Mj&1_yzl08s*x43L+B%G;#N zYimf_o8BVVV;69}1iPDq(tm`4(r8|nU>m%KNn<}}fAioP&tJ)0=CG+vISO;~JYV;> z4{8Vo=@*GsGw-Yd`=HC01Gy5BXS@O%$Ae%SjMO&daJ?(E5Mrjpr{`n@Fnord23i&R zs(ddt!p#XY5^^LM3h^;KmV|?)aEwzdY-Dk3R3r(YU2 zo5k5dB^lcevAhvU!<mrii_K3NB`%{lAl2ymSQo#@Ye5_l{{Mz`k@HKH+wwoz z7ki$h)jG#z!3Mb-%HK1@D$S$G-Yjadp(XY@v=EVpVLqY`ph-&O6BrP~C*5Ot8|%4a z_Cw@cVXl#?VVa&(yC^4?d|}`0ls*qhX$76QgLh+`@NY5t395t$nB8vDEu_C{rGPcY z=#=5qa$8mHQIgKBRHaH+@;4yPrg1rO3on7|TN0Ho&pbC0`EmYH=E)}X`dqKd*XPM2 z6wwGl(V|59g^*q`IOPlon?ri-z-xUg2%z>nensox zPRDUkvI$MMP7w6Qm`@P1QvvM8M7>~8lTi8=AdyMzWSaMwQ;l1uDXq9 z%2oR(d*Y0k^%b}bBnh1QwZ^3;fNeUlJ5~4GRsW*>Z$4E1F={k0s{)tHOdr-g)cQnH z=cXj~DWx!BS9te5pE{dh5^7>WMb44QN3a%|O2Xk*xa9FHSbeHS;bCl^LNY&^h|DCZ zL%B!%Ck;8wlNT{5x0n!E3pzMmQ&Z=fa5R&6FgfrjLeNuyFA;B^r4w5vD7vX!SiLk= zyD7G`W%A@WaQn;Whf^oi?GG{!5z4Uqi_+6XG?^AK-Oj!eCFBqm(_kzqNZbr$E$7~!jym>D?ckk|pG**KvzUqv`O@%sGWo{{_~_i{=W zd9Muxb2c%cxwKN(fAvy1YzaXcTmER|Pp|cgB;>J8oH_M=eIopOWJg>;38Xc2l`;rn zTVp~RpYLFMs&*p}u689=le-$3adL9nm*LNk4CESrae}{ z#IpCptMHzLA%zzYo#Ng%QH6%cUpU@HvtWOju=$z_F#d=lO9C=-am%q}dSw(b?yrZeU2!ZY4I6xTMleigL# zsaYzC(o>YzL|-$iRaP)!y;WZFN-0?{Wx3PUQZ1ANF{{!hx`U*K$6q%y@XJs|g zAjBL63o%Dc+(?oLRuA#4Xu0(WAOILvqQVIQaPb%<4@%P*RR2_mI+u7zlk7$q{KuRlN;|uWOc7FZn87{XIAIJfZNe`^3M@JQ|lMH2vNkVEf&-TqBliTC_Y{Z}v_v?wDbs zm5EGkrHo_~f%-oXDVEQp<~0n%j2cAOd79P$$}~C65n4@@O~ zl_ONRmb2t~O(VJu^6~=mPiBbV&?`JV=CPSjrp`&ERrh?Gl%9(#Ei!ezDAU@Ls>$m# zrL=(OFHLi&=IEJbxORu6Jv0pMvDr4Xx@Q32X8n9hU0$PS;22J~nH*{%+o-gH3EL7b z*P!%Y@n&sqq^hf;|DI)9{cup5Z(d^=4*4k5uouC6jXj$W!GzIJ29kjH7_0RWgK)nL zNPeV(ZVXzyGX!w!vK#W=e+1>eqkwX3?+&_1e+ZOYtALllVSpa{pH=kfojN#fJJotf z!s7&*+)I#*BhS_ajfvmEIMsLUDggD?dGQ92pDwJ9|HbfZZ8VUDlakb4i?lCY$acol z>hE-`B!h1TBxW)us&91ZyBsh@G;Ne9^<&YTjsog$WwhwHiF0lXZ%4}wI=UX<@-1Al zb!gF)Y~BcRHn#+|HRb-^kb9O*0aeET#;EGKuxPj2Ph?WViY&DfxKcCNK%|@SN2sZY zH|U?b^eNQakst{hENdpWo@{`}Ozcm&!P*^lT!aK zK}v{02{8cm@Eu3nt?zL5eKn3RXuQs={g(08cePXG$^b`m!~Z;scSRg$#uYJ{P#jm4 zK4|IHPL_@_5i1eL26>3$E7>y%Zb#$x;WutU1iUNLux=_@#}@_=Kwu~pPW&o}q0y#t zL;|id%L@hfP%zfVG@0ri5ZACWEicERO6G7=!!xp}9M5a@QK3QGh%}kRdZ#9W)xSNd ztPGous%&@TNSF&$b{`e%6WNAUb1-`VgYe$k{#GIxN`CNj~}p-$fW*rsId zW`(SGoLNDiT-aq;@uu3X<|?b+gqd+eb*~0<{(wg`wWtbwB%DFQVwq5%aWOuf&HX)i zc%|x|T2>U(rAW1GV(&MkyGY@g8Z72Aw?1wbgR-3rdsxPM!e-bh*p!1C_n}@v;9%Yj;E32v7vB7|K z0t^;E7c5>Z#b1}u+{Q;@4Q$Vq+s0!(}tPgnV-&F%BgYn z@#VriDCzv6cA{0@$xf)u>;h)Yidy=Ub=bLF+61?yq(I|Y6v_BtCAXdC)$vl>PtdheC=wyax#3D|6-dGljX?!Q-EG-byMgTCnU)RdHB1H@ zQ#)8P*qDlK?mT3B#|Ccp!Aq-TOqYWOR-VCR`Gibjm)Rc0b`vi#z2O0@N7p+e5q+9V zb5Y-i{yqdGiqT5%H)+d_Rj$MHC}bIL#2%P74a9><&Irn%nHx0h8gP7EE`-kotDa(b z#Z{BNNj28k@|c!eNxCEf9}ZQzKaHVZ?ivCf8BRX)M)FgHOTJZ1?IOT?`PeU~Najv3 zNQapzeCtH8Gz6J@t|>ex&wd&v_H^z27MukCvOpvm)n#L6@S1Mc{R*0riFOIZNk}B& zkIgs4Cffbc6O)NSa(!3)kOT-3i}k0W_31oJ$bX>UMt(4HlkjI|udkBxth6yvsRmU8G}6XT?ZZN85Z#mR-3W-!Adu)3*9X{S?I!i_VM@F& ztT>|~_Yx*A9CG570!(7@SVX`??AIjYrK8W*Sq6{u@R&iE+c1(hE4vB2xq`B4S zwJF1)U_#Plo=wAvUE0~H()0>WY!@i(HXP-W|o@;63@7) zoqhr8HvDe-Zm7LX4bg2%BB&}_UFk$Kh?MO(+@0EE$lOx9jcD=6k`Zn?l4HjK2Y4ZqK zf-An-lz7<5FFsak7c-gWdxDiNpv@XCVeF!d++d==ZrfF-BL|8rFN3%ul>J1%eA`eF zT6W-TivdR8i=4|-%9P1P_z&qAlD6pM`HULggH*r&(_W(XoG8qU*?G<}mc zPpnt_nq@jRnIE@F<`yj49zaN+y-{?6jCtZv?jVy*!g;Fcq%eYXEk{BHt9P>)HE?i! z*fNx2CRATT-P1vMG#9bB!;-IlA}~o;^o$*5&5?OAd+!?yJYQel`H7<`Ecx+PrinWE z;p|Fc0P%Dttb{J;v;4GCkz00hv(t896No-+e&TQwPW`Gr5U!ZwEFX>94TJ@0m7WZ;%Gd&|ZOV%VmX0^l z0g$bYAIMGJk?+i)mx*fo5sCB=Co|k!SG@oP#0<)Klxexeb-#u5Js%kYJNIZCN6HOu z1B4!ZpTZ2zVVN-81fSY_A*BETX8Ak`Hn?N1mJN9gH6r`4`v`@T6V8Pq^&MgBr$!^9 zWf??3JSQVqZA9R*EotN(wwfg@PS#Vh?O==!)Mmj%$z<=tXcU46QrYxj5|0r3Tbcz!v&3n2k-?+uDA zvL!0kHgILZ!XUCxSdoSVD#^O5`9m=YQ7_=;sp-HT+p1!si|z@Sge+6l{OT%LwswW5 z^HHj{rzwY9IV*(|qEgr&e*9L)wbL!rWvlQDqzP7kW4<%t(ggk!%(|q-|iem{BjS&4~3cywR;2vbqY}eYh$YR>81pE zFg7O;nw%7Zh=j>XR!AudIGM-^TqYGKdM4#5>T!_u$C%a-$__Sbd?1S80M^7xkT|%O=U5raSBCFH1M-rUmfZXKw+S{d zOUjKjqWh7p*u}(E5Z&fFRitsUP+JsmtQeK3h%?F3+ra2+x8aNz4h?g#`*Uocs#lsAe0@RkQ=CS?g5~TLj$2U7y5|LL*^3<8VS4q#Obya_O`>wdmOz4d zL<>Q0?xETzZH3?1kb6La)1T>Zyvm5t3t5Dd_4eCOMvn}_RLc+(#h!uTm#1JXOEXGE zrmL2>53929b;&WaXe*U_DxS;N)n+fPVoq_T!U4mSS2S1nlsQ_81eY-rVTPE%1TM)! zGsQ_b`Ij00dUSHb-_hgQOC@|tA=e*)Q)_ONAXKRc0Ot_Rzx4>Ckg_AoINwmZ{T8=TidiTh;!2d1Kg60cW_Ol4LIFmH;%F z;{6ra|D8gZH9`#MWAW~L-N>5ZagCx$zVS*A*y#|hivVpD9T zYQ%;K_TNRydL$cGsVz+=annV?nKky_MR&m+(teL!ddzy7j_uqYyO{Axo(4`oDB8a? z{McG`h!HH&EBEJP4mE&1>6|EqfI>u#G!>pX)B8DD>*f?G<5v>vrQ|b~D{r}?E1i5% zG=6Q7#irv%mJfJ_Iwa#)Z*I^_UtwnaP^ykJ({t{N&0m=5;`kk8#LsIfHse=h#;?M% zFR@n{?}#_GY`_G6Bav(Plb@3XFcRY*Xv#f}1#CwwEh7Bc)}0d?uaOZfEdyAa%1d(8 z?(E^sUzWkA3`apZwmy*EchzS#dy5!HQ_B{i(TGJPHiglL9+|KgP!1<{ka-p{Ih{&| z$Pz=`^-97YT#lYpf^0UdFW$8)YQm+J@*uQ}oy`+4O_ClvfC8FO1kPqp;7B*AQ~c`P zH-@BfLHIZWigl-$FKG8nG!wgHK~_Z;0k`TK!-iH^af0UyDME5a@P#kJ7sw|Q^8?PW z*in0r$!hGODw4)6I|x0aeEJeQ1@~}j7k=8TH`lVYQ(S7$#G9(*=H}Rdg&~aq!!b!S zY9;F)3$pXgpydW3tI0eDW9caZE)eO&^km6;04W&lOe#-=^4!}{_m^N*9}v-+QYHv! zbHQy|;8roODfgI+aT44tF`H+bOw1Y;2Fg|X4aa_W{59HO_5z*f;9gv8Y^UgMLrrU@+zDw(lH9a@Z`h7SCDVD0pS9NGpz8sRMYfpfg@>Im z*1>Z@jJ!X4OGqvkvc#eNjIu8kf-a@eDGc%_rh2-BxKr!icD6d{{QI5kKkcG-Bs zi*W1GMjD7vajZZpvB9LJKOU+6co<`*2JsH!Ul7w%?69P~1>wS#l_<_DC&nm@le6m5 z@P*}KIHVgf*S&ZWD{er!WD?1=g=C~?6~Wui5yki%Bc2S03nlcS5s!p%WBb;MsQW$0 zLEdkt^?zc&o-|%LI2qD+4aSVw5_=3;P_NCIl)%eurQVwVR&#enew-osD00_pd2*uU zDj3F5Lv+cnV-clL>E#iEa@4}I8^}||>z&_d}B-`&=x**%{cY5C9 z^vfW7%_KcScKFbrorWqYT1%LqiF2$xLfW_#fcIzw09Z;aNhxA0kzQ%Ew%$O1-WH?^ zpfp=JYX6ehl<1F5QD9f4%6I&BEVDn_6r}H@;+iSwH9969)$ z4?!c5PjD`$PaNL<^K*I*<3bddxln>k?W>uV?Z&RQCu@6HwPrar)msETw>xR9R+f|-L3Xd)%H{*6?B(35RXUtYixkQu=AIPi65-Z` z<4cX6w_uKN0!D2AX>2)wsYk?Xh@BvIc|Y413`I;!9(J<&=m-e7-2%PBBGiaV z#`MQFAh&@3L;DYluv@@mgj~`{Q--f2tUqVO)}ND0tUt2+>`@~r0I`OPDag6Q@fD~B zstEhfOVDbQjC0Q#eZBmYqc0H;t;ycgklT+TC?+3=zl^nBC7cN7bZPwkL`CR0iN8tk zmjwv3-uYqbOgQtiql`d1YagW0>MdpjdWig{hy`9Et?LcKgFrGFUUpD~EW-9^qx2o7 zKzl}tp#sp^epOJ(mF$iBz z$O)OhXi=S`2zW?jmc-B<5Lt}c2NaN-tovKA>MsmZ48DwFO)bx+ zTOK6g?V<+ajWH!@h%^;Uh|EFudUf#Ek-L?@eKnzzT%B zdGY);mIPFGTzpu!;5;WO%B=RDkwzS6>UqP^3b-^9f;9R4ES=1m>P@_qO6(i8o;@8s z@QP%HTMSuUz8SS-D~G^V)Nnf<^*dYfLV#*jxY&$6Z9wG^dykMm=H9E%bM~H-3hAP~ zhjg8#<{sEm*C%A%`7G3;^9ei`2)g#^>Ay+3Xn7*HU*`8X!%V7{ZBVV+v8|_Q)7&As zp1slp2htJ|;5Kp;3+Px&CPA#5&q2fP4NoW2Tlo4{lKCTSAIWyCRorM8qxjBI1_jd9 zM8BFQ1Z%1ZKg^GBgPkfaZ5m_AH-AJLZqA_)B5)^k-RJShn#JbPULg6#Bie};ziZ09 zfW3I8@>YiP+bbmuq{CF_M15~Hhp`mnWVwtIt0`HaPIqt^BJCOg^bcdm^>FKEtUe}2 zPG`6_&KN&5OazYUF+RD{HTZ7Hl{xy(S&WoKjB360rc7?IDfeduXt~}FXhRmH5fC&Y z+v##cwN-YM(6gojUWdIGJK6{%+DrwtU=$ERk9>m#O7al0kc1-Pv-%q~{>;fk&RNRY zb~hF#gDwu&p%P;yu-*{g!df9uF-m8=YU-bp!zL@=-T$99XPCz0o81s2gtdhM>3NW!? z@-Gpl*C@@|Yn@Ceo@nKjCeV^j;5D30bGqxrjX7bpGSZ<>KyiTcEE=|jP0Ln4p z-4qcQs8kdAi)O|)mc*dMh4)t=u~P$*rI>+?N#t5-sKK+wd86m2=f~he-}17WB*nAV zKGL%(*&KzHz6E_b%ZHaJtFq*WJ=fl8m@S0QwX- zuw5Blafvhw2T)siAo|qTN)y^R+pe0AZNl_0wT4)o61X(wHUOFg4b?vBK*NDk;Ot88 zP=>{4r2&ZUY%zEUL~Pw+MFvyIz`0!HD1d1mDo+_NSXsYI0Jicl0MjImN^n!yD|?}* z+@gO(ktaCiQw&?AT=?dbu5c$ev9cO#w8cUj_d*HIceT@LWthmi7I8iVWUpRJ9+rVH zJWt}UHwrR4G78Gs_*J&3HB$_f9cnB~<1pj1)kg0tfQ&~ka*y_yv>F~LOmLNJXA>!? z>p8kf57ZV-sVWFX*o>BtAkk@JTjCxtmmH_cZCdOCnmovCy>Ph>Ml`m;8oS{@AtxZ< zFyy-E{cC8)K1BOaLsU8d8l=&srG;p;Jo4f{s|EXp@&ul&3~7GLmyKA!Tt#OQ8E)YN z_Ki7>Kv%N2w(&yJfUE#)JVKT#nm)yWQd@IjMLGYjVc_Z++t_lBW1#XAZ@#f2wg(m+ z-Am)Sw2paZBBoqd9?UNHNKn^%^#`n~xD&u=0S)+egp~Q_>ZLTjk{Yx~gmV(Z@*aa6 z8PBz&PVpPwfV?zuUO1x?2+id?8NIq*09`yKZp%8JOWSvKK#J+$0^VOVjD6oO2C8HXX@Ygw;`anTmA)f+{I zg%!3+FVd@8wt5L?`}iy-awpy~8HqDss(q)7=_m-EPGSUSnq@grSDV6x9UMYcF}bm~ zhXrORQ%kUzqV3Wu6rPF7AkiR0NUU3FQ@E8%e)M1lj3>(bnzw3@tCdrdvf>GIgw=9$tZ6fbQ=~E$BX%z<8U#3 zovPc_`lM;G2{xh?BT?`ZE7_)pucgVLOQGln6(GM>*5zEgCkDPD@pP(|+#Vc_kQ>g9oJ1JC&nLsmg!3_iv@{cNAy&ekjNzxI z6ilKQqK7mnwlsz(7Lj9;b-Po>nY!Pv5!ZJ<~rR1}h?8Tn81Yhiy~ z77JJqJ^AP|pgO4Fvd0>cZIf`*hPnrqj7{b?_I)D;t|nHYC;|pkGmjqxxa{%@yEWbd zmpH{yBZS>X0k@`CaYb8VxIVh9uwj=NpDSya>#{c65kT5aUT@@iCEPmaKX(R3^dk$PVxA`6kBIG3xle$=QiJ1 zsW~}JjI4tc6K-cTb$wc}g>T!KJu(Y%1?d=}y^LZwuJmZm1}-#i-wKP{2M?=c){P%? z2?W*ACNet2CQcMOMJ={542UgVyE7Foz+nL~KRW;n;~Y@(U)Kop@FnbN50> zC{2!lNb-%mLY{kaSmFHBNVa?tJ?JWPT{r_CUNm+IDFN*-EB%Z@m2zD&it}vYec{4) zCI%iPR{%J#g`j=wMEpZ!o83V|M)nMQaPq!7MS4Ze`1KAaAr?&=3gopJ>HLzVH6cI` z0BJK}FMm z2D-+obpjLNK;tQbLk~KgB7#)^AcKG$?s6Mm%tS(qC$=(UQ>rG~|3nYF>UWr*n`K$} zmcGe1%oWa*Q9|dw`)D0DsDALm3ZiVx``Ys?6i}|LOPo+94Y9u1G2mloUL#JJ@ zyhQ2Y0id4fQ++yJ!wu2Eby(;;_PC&Pi-*oLS6xA?3l0MrO|nC@v01D9A3y;yS5OGY zUaXS%+f?eoOy>mc4VQY0kp6*jXGT^NhVv_biK!4vN!0myYAB zU^W@?p6Aunq{sDRjpZBWabB^m1>o)ec~vywtvZc34n-S|QsWswuZquSD;&Jex-p+_ zl*CTa4Q>Av*5BjSK1aaLew9;9cHGZz5#Gjpi0$yGM&GRX*&&ZE|F(@rvt9TZRpO1a zyD;NxCHYBu%Q%GhL&Hu2V-dItxxtgtKi*!=o$7jI|QBd-DZ#fe^w4S)Jvcj9VQh80f9ckLN2IF$w#;e|t z+_#w>6L~e{%hl~}uH-242LFXx&_-&F_I~7W>f@=YOdLvxE_yK3u8N}V2ZvP8lB3GU z<;n|NFg+FJb2eT*rILXNK4{iA`*Oc(S*%(>Q&}Vz=)oeZb`9xCIpEs&9RSO~i5iru zo~wsyTQ?Yk95i%eOmMn?gRJCqd%b~kx$Pa@)ab?r!A({4LWn~d$*wy7NJrF*d9I(F z?W%$To!Xu&-;%ugUF;*DTl>}-o-VMS^VB+0&mHVSpFk1t1=S|9D|TqIzp)Ng`kSig zn^RS0J|775h0;#o=I5DSTo=u%A*fGqu>U)Qn*IN3P+JLfl-8-v zHj3k-DLSifl>Zt1{2CbFTh1AtL+d9poWe)Bhw~_yMu&Em{Fl7A3HLvD)MI>z=S6nF zwP!j%`txX}vz{95luiK(0k@4#L<>(k9P{}MACnb1dY|4ZXQDQj zZGCY4mi#!!pW5Y%_%7Zk?_yRd@>Aq#EG2x7u9TI#O&tiQO`wtJnYTR8I_I82fgMx% zK56Ml%wtQUZk{uLzxeS{3`_feMTWKM8Dm&_7PY*~AGE1PR&3UwM=&mLU%@MTYMbnc z;YZ3-;gSmzG`Hm4$^5a9f2RvRcFr*QBkJzq?9c5%?k1`#VWWjsrm0BZrNe|%C~BgO z@(lA|=v?&oH*1*gnHWtC-SB%~6Go&APoZ!Kkxn<(hVU&*OqV`dlL%#hi^z@v2I%Ut={hP&{ zhv#6)BxBM$ZA-DfEPra;Z;(`HNoZSlzXiNeMJjA1k7AKg7nxsh`-`c>D@`r?Y9l9O z2nA)PwFMq_w;;_z+NOsdVqzEbbR%Hv#u)ire`Ac)jmz^-ji|_CG#uR+xML=2{LTi< zo2uxfP6wR@l+|dpii1yXu|D%jjSpA{iuE4BxxJBzfrw!d9gTVb-?;* zoj!!&t6dnrz8Yru>C%qJqp*(0qaZ(l_ry{Kn%22u{8TSM!8E-kDV+4!9!ZqTZne=Y zwZcoZKrbVAAAOITvMw&>wYgTQ)AgDdn;>pxMR(>9I9bvbpl4{d!?7KzSxX;O`)RxO z)8po9=kWZi0!?BJf<@}1o0)KI(tk>ymQ<(Je7$)PM3wc3);y~sn}J#^Vu6iQGtIyz zjq{(|BwGWtRukR3@`E;?Z7Ri=0@EnUD^%ECq)J$4Si(IX$4!l#RDfIT`2TK3hgZ88 z%+|}-nbF;>VVV+kb$GSYm(jO=)La}*;qAr@hgZEBC|0a`)A%W_cuu}fHaF&echSWe zHc!_JTpxC)RzLZ~in0%7a`!qWoL=!lBnZ&*4hqT4(!;MM9$3eVXz`50t$E+15|+FV z9r6+_blTN==}y^=PCsmke{&_)s)69JCC;IQ7S+9P(xS>1Hal|kOEH2-oi7F*mFlJQ zmP;KGwH{$Y{(tgP?xqs<&E50|T;z{N>OWUC2tiDy?R*1Qk}-v>ELz*#qBYT;#w`KS zAv>MA@95#?iwlXg?Z>FSxUPQlaT~RsMH6P4A|S{fZap2Y4(>c;*%|w8AF(Kg)6S(j z3H|+VbV9#7YC7&4jM$x{U0A}^s817os)Mh8;XnPOUjrNfDL-WRP^jZ7I5FjB-@Sw; zhSraz+l3iiX`K|(ONppfr%Z-k=ZqMzq2a^+W3`_56PSyi=f-;?ZY(6fVf`6b#PkQ=Z+f&+wl6>O6}e83#&fcN-jcz{(SkU@c!d;qT})vS>pXtN z$&5P-IJ&8dCfHM+(mg1TGhVIb zl{}n8DK+_Hbd60TE z5Y?-uRf*u+&9C6mY40suY?0ot=Q;9%K0D7rgNHUef>I<#@!lG;aj#P?yyz}@Ve@}0 zFO+7m&6hSj&|tNoFIL3{oi$cWIyO(LOq&*z)6wrf+06F~tLK`t$;0ZI2Ia&Gs;JT! z)K`7DK(8a+z)h^LJT#zlV3+u@5_&$sy->#cxdeTtTx^+9TJU~sJDMwqmqFC0Rs zG@UMkRkw$4JY17F^Y2X%6X3r*&_cL@+j`Cv~VcC}JLuUAI-JO-&)q)C)#v>BJHk zP@|7NPlaqKs&S=+UCVDPJ|}LF#pSrN{Z;hEA7ZA_D~&c4e!@<*O;hu4u*BF9^tDE& z!8W#UDbIw}Ssw9>6Mw7=&&f|j5Y;Y6^DhVM_AWbvQ3f>|8&211S@KZ>)QTL%(GuoY41^;r%K+a~krQI|gkSG%sJ` z=9L_mbf)#j93(Uba*v-$TT?Q>9L!%x^u>iZh!#kOLrM=usX-)jRD(hL9S;IkkV>P) z7tlEVS`AE?8Qr!OAo7Kf(D0&TKKxxzBAzJfLchuUhY#d4>jsm#*#~mX>jn$&vO*w_ zKATV%1lj2<@7Vi zU4udR*YrpnF}!dnoN63gC&S8HP4p}y?rC1 zdKD@%q1Rzj#W8s%)u4~+RkOe;UR27YjJgH<(M+nyk4l+TktGS3#-w0LFel?nQQhTO zgmOqDG33>KBgnn?YqDbT)(1*JptES$MsBTbQ#a_WwbJQts-kPY49DSk2jv)lO0_tc zyK{L&=JjzcHkh@gRqiOQGOoWWy1lbxiYBX0eT5+*dnrOkeggSGPSn$g&%+OZZbYIu z!9+V@%2aF~6C&qaW#Jj-Fz#1x*|1u0DHeAViT4O5YJ~FHUBBWlxytUzm(^{%x+2?i z_4MJ7ad8@2AMn0V#mAzyTPaN}=Io6Uk*}_-yC(?0>Z>y}DjT*yyhziiAU~`J8m~>-3fk1hPhV)_Eo5TxZ{q zB8Fe#^lp9|@*gkD*F+nF=MVDrT>>fQj}x^wA5NP{dn1J8+}`L$N;*OSEhTtR3H-+F zcWN##dB$y<#d?AIhEP*!Z$TCv2Sj5P+?xUJ(`t<|sPB21!8-qatb3vg(=E2`keQ)J z9D&3m*&I|`DnG8FZg;TilT?u1ekV_uq@BsSi^`TCxzG15$Zq9Jv$t zHWa~eWa66B&sYT&)~&@hzGJXDnBj6CVh>Q8u8#6wc-a_)wfXI@607?sUg5+5X)M)S zz_XhlSrcY(FY4Uk?^QLGv~jDFTz2@&nDgmyU7KrGXU#RSHG%XMK&(owD`(LjQ?Ve= zz5qTc^JO1ZzY@LdDz{Mz9T(9 z4o5StqJn7EQzz#qyOEeZvzw56ZfOtD6WmT{(2RGdYX`_a_hX71 z;R(RPj&AOg;gw_ueuyYbyz>(;rps?LxHD;;s+~!c$vI}R1a68NdwA40N&G@1#IqrP z#7zoGH7RG{u4+*a09q>9u?8?NswLK*Y>MP(SH{-O=iTp5KepQUhs_olBGx3LL#bW%-LTeE7VRaj^s6;PUY9|D)tS;O{7kbAt)*)LU3P*A^qD$nM zF-{&%JD$p-|M4HE_3_8;V+4$$JEbfXc5>M}UM8+PS#!z?8@Mm-&&atiooRss33b`T zoUUoq980+nF2X?W7Jh=bL+QjTror&Ik-UqI9JA@MAJ6W|8Qey=HAH{`p!Q&ZCbCRL z9cJMC?Pb`|c}#j82}0K!eMwMNC#298y>#^fc_gSm!o=J7m9Vjf-~5}xsc)*=5ro=- zQKla)tnJa56#bshlD7H0@SN#zLs7pSCaS3wG3VaFqCn1!;nV51>iw!UyiXfS>RiX$ zY?)VMZYaHQSCI3WG3xCi5^7zLE=LK}R<&@jZ$do(>6XblAJ@hnPJFj1lYjs!$?KGm zOzu@!n?4~1D)DS4@n;L^kV72#ZlayPm3~MIN##EL(J-^}QpWX;y$W#_odVYa0CP4{ z;bbZlgzBW6IrgnZLUR|7C6(9%3ucaNy+GKBd)!2F7Z%TT>JyfXmP%F*Bm_H!RNXHJ zA>*0JC~zs0BW1`HC_ssw?S+IU%beSBB=l+M(b%H#j3n-U;d|HzhxJ8(yo5ft#S`*9 z@KS8mb6Dm^hdF93Bu4gN5PqBYg|`md?=v{7E)wIgE_*DJ3zoxMBgX3;bCpev&5wrg zlS576=a?3=Ryh1?YIzZSM%5ui&^VY<5!u3*ctXx*0-i%(#p7Ht7D%4+V~`EE;r&ti zNd-K)Ro;sr0=TU;m8mdw1R;()g083FQ!#Ra77*GZ;bu6IlMPu{u7x;tD*WGaTk0~b zP^;&V2GAiPMd#8zqUN^nvx8(AF9`imm*0go!%LO-P}uL7ow|{^BzI8 zWnuMv5!*K1_?cB+FiT_l2iZl`5omC;(O~$tkb?4}JJ`esIP6q$lQv=QY$nW&lsC%{ z&Yv<~&CGBMV|1Y(9`_in)ol=z#$0tiKocl8{!5X{YmdzlhT zhj1zjk4qON>Ryz4Je9wqdWmEy&ANK6J`(&(q678V7ze-NRvMf1c9-AB0WKLfp9O0= zCb)TH@ISk1cR&)7nMrm0F(?FZWUA+))+Q986x^=0Qtq$&Hwv>A>=lUIoZ#`)C(7xgs^A$05az24?)P` zxkH8DpwOk5MH6#lZl|uXay#rlFI;lQ(0SqfGqA}Rr|^ne3jwZ=vN4S4i;(&YEgxL( z73Wga6*wqaPOw4jT*ogve>&w6j+1yWoI9qyr(6aShDVM%WfuJ^Qql?urB(XKu=Zz{ zy3i$oSmKtd!+dno<`vpba3vk~(quTdTpG328BRPpoj~FkJGe>m=7SP5D)Py2_TK^G zH;rciL>z{ZVXY~YQZa3iCwlvxJqHUzj3>6AwM#g{P36apU>iwcE-!p}ti+2z6NV^H})+%~#W z_&wK@n9stwWSIBvR;1<@orT!UQ2W*!n__FOup3_9E_ap=cwvcFsD{GDW29J_X80*y z!xl4H|zdRsUi;p;!MzQTx9WY1>xzxzKj2fE;{}SpS*&%%s-P;(R6LthzfRRhJTsUgW-z;A zd5KLdpB+4B(w0)u5_I*||6#@fYUP`5-jP!y$ZkaR0Mtu8>lCb5wO8Lo59IJI5r#!X zk_y_ZIUrEd)O{4tE&AB2Gt0aJDkov}lF4o3ht)DOfS566gc9n%sq{*yiz6H3HPM%Y zIZr4VLgz2p))S%#n_^9LK)kvP6;)8_p@F8BzbaG&O%(pd{b4oH2mU{3qJ$HcYND(; zrD`V`p;GG1Kh!<1uWnP%M7jXj)XzPKQ9li*it6XFPW>$W_MfVs!k?)2e@fNQTMQPB z=$?nDpPFnqUaWh1iPx`Z!lPLCJOB=$a~eMJD|ABlWL^e%0rd6Ykf~X%foeWXgl}wl z$QBJvmN=qZDKG*Q^-v|gOuQNk4_YvE3`f<%Lqr9 zvDU;CYNcg_JZS?2xcM5*5~9M@>t2QrEnKIWS33|1T(O3=9a>Xd(kyf75(#i; za;(veiKJRO9U!{Jg&F)7!!IKoyd3c`!9JwpOHG`465akeR48X7llR&U-heFpKuMig zCM)kb6~p`|JP)xQ-iDakYbq3hU#36(kS2tXxxH| zRQoJ3Ikxsoc95Wo3_#Yc`8Q2;!dZnGrqX!?DpD7ql8U||Tgj?3oU~?(u%xvNiAEED zXVE_YE>S7_VMwl$*1q{OFRg8fxu|AYc*4llXiPRv)GNrclXR zc3^KoQS(X@eb?C-4{EBl!lw~7*>uYsjp*$x9zp;mBT`7IpIP;CCY|p3wcIq2zYtKa z;o5p1?fEIfM49V^lp>M2LHP)<-d5$C?HK^~N)ZdQR^_q0FRbPd`O2`JK*2&ISims; zooR=lD8G^vaY)YkoERW!vgvP9VPF5979E9t3? zSe0U$Bof>Sv{J}723?PfVL7uo&=WE(h|HytGG{En$T12AWa7=+9Pt9K$* zq+7s(RDL0|!3IprrWj?^3mM&uL&z04fgp{>(?~Kba@d>0jxbvBk)pj!3&}T3>KEQL zCSFL@5>_EsxCFU2EmcVs!pj5I!$SKf)NB-?Nd?DXxax|4#NH`LyP zrf#~@uB%dMVeOFeP{Y_3L4K6;#ihPbsWCLII!;a|dY>Bg&YD(zk%j^%RQ(Xd zxagc8!=q{$yvKjjhP7#!v=l4kypflIfX>t<(Tj7h>G->1z9i2K06CiiHc{v|%u4N! zT3oH*Jc-@7(zrP??aVPEbXxHs<=!DT*ro(4!YZ^gPG5O7y6G=WTHWKVw-nZB3lce+ ztX)!3cDpTXg1Rt1f9Drs^DtZjyjF8iLmjpA&4PcD~LgvZhEfP@zgT z4T(!D{`rT6W?C5rqqD@2iGO^sDg%HEcW4{?uu%Rfac_mMBOmpS2i`+>n&03BzR%fz z=b~^q&%4!=>|EUzIPY`dk-|w_7rk4%{eE&I@ng*wWuV3N45JK3S0Cf?VYZg<$E1GN z9YA}<3!S_aK2D}oP|IGXR_iiulD!qxyeo@V?Jda36wRySKY1>P(V%l4SDIIerE=qk z=x{^q4^}DxQ8HgqP4VpUFew$1VA`v?Oi$B9sc8E-T-YxB&0GkjTQ-teixaaqCU*`F z(*u*e@&Ly)WOrQ^G_`CyFF18ccp%9Cf{(Pt%#Ij4^*9&F2$XaA6f@zn>V;t00=0?d zKu%g)`p)z65-;lcm|?FnMwB5YNQN#9MF<=J@^fJ!_5`;ALU2{laUWyc<(QA;Q^ApL zD*_2|x~#88kk?*>xxP|!^}=}1X3{l$469lg^;Rf0Mbounv!?JLZQ5k`h%rW+ z{#vkzx_48#+Mo&N>)Q7X%}(2U`+lr=H@!ma^`5TF;zG_jg7>LB*?yC`9`=2&nm~p; zHz8l1PQE7XJ1Iph0Ur-Dp@sjTrS72PL)6i?C$_%?9p`gjsOOzRA-OI=UM}Si(UiL{ zX$>YX0*i;^AG?3LVpRO22Cv1wh`-Tee-XZJc9BF(!AZU*qXQ7Xi8>Tucn9T#)VG19 zql%njMP7}*>Wln}A_|WTI^XM2S`^}(>~`>EH~?@Xcd7g-7J73uG7H~yoX#^P=<4_* z7k6SFV7-{MV;!4NZ~nx^Wp|>2>A}4`;K03T63?1k9Dxg%s}!P#lkVU>xY94~IaBDX z3oTa0GpnMp7m#ZFw6R}THP=Qwe>wQTeZgtlf@>eOo6ELw7)qF_zQP2zNtaX3opetc z2`uKh9UGz(F^z(5i*^ozV^@HTnd(K+x4w&y*0@ZF?=4>bZ zy@Rn4Eh-!J@=h~giQ!Z~?bPU@IE^(Lz4I;-zo|BRZ9#wf!U#B~UM)zbSH~RTF!h|U zu$e5ze^0c28U`?T2z(loKZXG=EPf2ct`J}svV={(-At)tC))322o*pPSVkAG?K#+Y zN+5l0MEDus7K!_pKQZFIB6_~;9}stUN&HsdZ=60p>1I9!IqqZ5x8s-?TzetZRT$5o z%ezP6_FRer(C8O^jvG`Xsg%Z#ErK9RL%Qa1udx~$BAWj zpeZJ%9gU7UzKkcuF_^-?@`y~N(0zg{NB5)Y{ca(O!ZX-ho%V+xuTb#M?=K!1^}L=U z3P9}Ed_(q zh$#VEd4!Fig2RwEGgS^l?xvq*g)iGZ zg5A*F<8}XkxMF2H>-~IZ79c0+3KnT#k;>KSQuGgMoUUulOWl;^#~GV!vg#1AhVB+C zv=u>xG+(K@x?t6hxUiBZQAShpCVmCKj-T=-W~jIS2!^_&WtgGM9}sYf>za@pg(YBa~ZrY=vbrXd>MK; zQ`c@TXBEB$!w9FE)aNGJkW`twoqT0ewbZx@0`Jh>6EvxuzY^<1MP{Lf#VkYtY2K@m z8lHJxLFP_Asiz+<4@vnrChbo@1UEf4X%MP|EYK8jgOx4~nC9`g3?s&xbhwOz2q-9Q z!U*X#K3Q)3kkE}gDC~h(Fa6Hl18kKMITsj&iJe}(oO_jF&|`p+Ae%AAMLK4^mGT#7}8RMzy%(Dmc^0l?azr(evy7K2%r;fNlMVhaK|)LchVh zt+%?B$NgUBHi3YyPrmTbO(>-&Q^mmJgJ?$bx??dE8Y-a6ht9bP3&0`ZA4Iad84v+5ChT0euqu=SG~hARS4 zVp02g+i@#0*6&d(UDhsK^x;<>W7SZ_Sls|?;sMsU0m5npqkklgpH8Kc#?PXwVrF+! zdwx7uohvI%EDAcFSEqZH94{`op6cK^X1?xG+ovUh_7u9IUTOfg)MSseT_=u$popGa zHCdy6nu_FC@d&@e10IeKQ*w%KRn*OABPJxA*7;xX)9ydHB|r{P!xiwA50WEI#Yiu! zaM}m?PUE}Ce_BQ1;ZLDyADY+2r-sk6-*%j8r8s+;j`#z(IOPV<>YZ21Re1GlHsW~7 zFbw+mImLQw0DJhZmw);ig@dQIK+I)aq z__1eex#|tB-HUYbazpTeo>XvJPjKziy47I#L$@Tp<&PB)Q7tfzUs1~;OO#645@kEk zutfXKZHQLi;CAxjq0-`&M_GnWeNr4ao6xs%uMPu)CGQe+{P<%badM>|IzZr|8C;^T zS5-TJ&`|*+m4B-ySMU%3W;p=3uHz3<4Li@^ni5t_#Y~;VpOw9b`4$bA37ZLxL;kN4 zLw|<4z)9n)O}U+l|C0nM52kherXlhkexseItG^c6spqo4s+`MIA=GT2#p2j7R;Bg@ z*$;A|L8yQ1ND&yn_5erX(Bn#;pc$c0$wG$(;;Y2zEn8vXZdV}0=_?VhdYIN!Bhx*p z7SSx~m48-XP`5hu%LrbudmkFMhn`5cS)c*2lkbpCH@0H!u-E8rN(!Q-M6Id!@woL6 zlSPTT6hnf@6m{dg5y2=-W;YM1fEwTe|LslkW2O3p5CQJXeLSq0&Y7(8dh)C~q({y5q)FO*aXmy!Zc#CE#U?_WrCMC%jBP7~W6xeIZ3`%BV{%NlV=lI= z86$7;i-(~Me(U;8<}dbeRijaiXiWke zWLKoQ(d0&XO@q;*`nKq>1n5b{g1BCX1|gg^0F0sA7>jf`I-+YdEgnK+Uz~|t9%ERx z)wYh@pj<$o46PU^)K4*L*jmI7%>A)%D_oO(l8sVH^iWFyack}herv+buU0FDF39Q# z%)&7x)%TXkeC`rwJ&sk{$>WXzYuPe3*vSC3h-a_nLeLhcCnh~uc?lPiLpJfLUI+`k zbid9&+QFlIP*)jbf5^6OT>oyXVODU>w|Gck>Qu&IEP^Z)gz_O2n|?HsjYrpXp+TVx zxD^8eirJ56M=TW0aAUx;&Ah8b&3h>oWbSR6rb zG8)sCa4S0Y6T@84?Lw$9l1uhTUaM1%RO4C99TQ}Kto?wwh$`TT_`Uw)a?o9s74|X_ z*mp1r7QW3TuSEL#uka@%AOW<8&NB~{vh!W@HIs!L=Ya&udkymnUoLs96IC6K6dv*# zm%86uCT-rOI8#iTs`iVTBFkZs^)zIPmmU|T2W1g+o|?AyS&vi>o{ah2^J~Y>J=YWl z7`;a~-1_$+xo6s3+KM5FF|FA2fwc)7zOQZuhF32?6W6Wc01(%dGR~-VqjTn@n`VUf zanJu*XJ*YEp1#t>OL&r>oZZ#>e>8=zU4-i@;h1<)3NK|sHda(P*)!d~p`x*Fn_>_T zo$lv=v8CZEf$r$GiePlJLhEIP|2BGb-s$Avo4qZ6l=4W)nST(E#dz4gWt1CQZzhy? z@I1EzD_boWn9u$^+Qz2jCnHR1?Jv})+n?!2$6HIAN`#-zT{In~>?hwqNJhnTkDI2; z%BG1j<*vtFxQ$|GQHw5pNY*!P0Wp#7gJZ7zsIxV>oK#}EH}h3d$C^w1%D$?H(cV6% zWUb{!N|tK~C98)Ai0JW-^vAcMVI}7$FHK&S{P#(P0wC#J5lM2?Aj>$b$qaKFBigJ>wh)e{ zAaVS3j-Wb0x1Yz3qfMr8+P|w!FgVQ+@S=asuo*pXSQfS|Dw(vaw4yDh&r2bEC$8y~ zL<8zw_x4~C+-h6L&;*ipufF4xr_wOUPE}4m(KYIx`^4(dz@r`4io|Ra+N>PbGdjz7 ze!&MN^u->!TBwTah+f$wK8d-XHr14xENSo4CGAC@pc%buqfOgVdx{=qN=qD@gSBf% z9RG;La6CUoHV+nI4U;PgF~$!TS(aT6YNe47Vao)Ex3lwd8K zJZUV==wfUc7rBkpeeV7nwc2nDi-QiQv-MRC??KgJV*jd)gIWA*k zZfEVoN}$e35$_AHIF3U+C$>@LXE~d}&r47vWru&4?d92L52WfIU49!%=1#0r$=XNL zIUO8vnG^>(^k@c^V@q-b`3ju(GfTPM=l0_`Q3a^pOouJ;)VarUMYWE|qNi5&90VSh z^e6MjAS2s!=um0RZKnL=*qC_6ywnoIy@%1NHI`XPK1+j(2dL-{D;sU=z=MVTBQmIB z?@~PoGlmBL{q+@PwYGU$<15f*toanv{RMj( z8UYQjaJ*ZP1tP-}7)r+?iIL&)8!4E|J#6@6hHig8bG))*$96h%ts9f-b}6=;xyK>)EM2ghYn%?t&8qzae|HRr2U$B+Qnesemw z_&^ao9R%BURQO^ip=?pxI~VXd6>SDvqnt*|KV-C5@;fEU2SEi z&%NzBwHT}DW53UBV~*I-KdKvGg%ke8Prk>iVU&PZCBp`mh{q*83TTF*YnoafXVmXg zt$x0Zk$k(j9=t;>*sP0{(vup43nngy?jr_m3qo=7)z3D{MFD}p9u(=knFwr)l*wd^ zgytXp8rC2*3CgIv>?@A8Y|=$ZiGE`v25UbRmav;yjJ`^&hpJrwfBw?zS;KcFrN`3+fotA_B71CS3SdW9Gr36gWAZoiZC7f=wxzR zlg4Ibb$2M@lkY-jRm?@Er6zj$_lGlu&!#dN%Kyk)Cz9z1v3yY+t1sC=3(q-)y_@&Rs*zE+TL%S=j0=ZrJc(DF z_RBwhucL-%DO~DLu*U9(%?O>`kE-HZR>j`vExwA|>=XX@t%8fVENS1vY+QTK>>|vX zR4Z02%l8`tPMK5UX)A&(Nn?O)CO;0JwTpLHcp>N&LG};9b?0y3Ugh$}u6wz4U10-* zMfds+KQX;G;?LwfnMCjRgpS_vY4C1Nq@3L32p)RBRkH$G3yotZ2MuK&_vV_vG#cDK zn)Hbpoc4L@h1jD<^w#af=QgV*P4p-~h+W*{2eC1kAD8THphZeJeQl2JfxVNH<6Xug zmzY8$tR}1YAWA+l>}>$UP{&6wj6nV_#wISN2Mt-ALgXLlT&Zs2DjueDrMiai9na`Z zv@Z3T=(D?!-R*qCmw9cKUC5WIu;PRAmk5`Atvt7rSe?Z7^TJG09ut-UNYWmQjghV- zmYkW!1&F%J<)@lzcphWaShY*-((eacb?Xsa+pE&>BU=r{BI;%>e~W!t>Ays~9$G(% zZWWY8();^biD$W&@7ELh98#;|bI9Z+QlaA}D0VlUCsEbF!J%aSB6Aaah7#q+By$&) z6>jCLB0VEPoV6~$qRjS7&4t*~&==p2ASU_x!_z^A|KO8oM{mJWBrIcBEW3bICSL}Zf=sc-6zz)D^CZsG1qyp_CE6v3MT@>r#^SLUn z$(N8=MSH5#HvWYNx~W$Qp^9z{L)5lz3~_4wO-*$1qYe!mTFKXSYq0WjytWO%PpF)4 z3t0BN9K7u>{9<=MnO((`%{;gAOe@_JeB~4_C^2ZbJV2j?0U4qxmu7ciPr8#QWx?!m zP1zoH03gs~$cWaC)9=+#{m1QK`I zmZ9Q7M6H?d?H|vrAUVavEO&Au0j^7ts+MIqZ9VrK=aDz&9>XV{)KiVQS8`k9_zm$# z@D{brueX{n^8KX~j~~h(ks)8{WJO>;1S>QP3naED zpv1|CQ;JZ`%_{sSN|)@x?7tR%4=Tm@Cwu7XlKU7C1*_!1>(Edwht>0-a`c=d@$JEDv<|w16ILp z4e*uo+j@Rk7qGkYB6@t&=%s;!CFaFKmZi&8o*th5KmfG)7?N=YR z#0>j>YxGgx#xf^}`#LhGOMF^fQ2MX6>VK!|`yVpNQzIO)kjST~;|wHnhOK_2j_7Y4 z3!`1~F(ab+eoIwkEpzSCvk|10e3RfHupX*#8@1T~`_aCBFBnfL`a?-T{sX9_3XLh6N@!FnE-1#Q$^;bQX$e;? z6qEvs4GcVIji;`&vd%G2yHjiF2#@%#bPLPtgw%Pf)j7N`ERMNU{aC9P-t?e{i(}B} zW|3~Xt%R(r+;sYzdAe!yH^#P?`Ws`{i~UW#iY@Xt#;zCm8)Mg+XSHJ@x`wZts_0Gd zZbP8&vHWP#t|A{7(fkxZcro;aoMii9o!8Vg3RW zvi4rnrIK z4dQHXwrYl@vyHYOu<$vZ$>jgT&%m!J`Ojvc^%|Rjh5GsbZ3fm6TI*)uopb?~0=@T^ zv(@R-fDgg);rxS+^GiGE?soe#WTXR}{VQP89Kup^`cqSGv(pSNCUVDb&$ykM9s^wi zjulOlr6;)iRtRhPqD%`E(J)WDH9II~yES{P{H2S{9Z$M)UeA3NLr3%Je721jJoX2o z2er2tTjI%W#zDBa!;p`Qy9`quAB#SIH~T)$8U_w@L{!s|A5Sj8rKx0oYBhYWGZ5}_ zMlKJvW|ir{yShZM>PYu|ULCFi)_xF5)aflN0u89X+6AzerM4IVv)czA=nmmF;!f7@1 zCHml9P9^@EF=^j_aKSszoy}EoSnv$5?J6#(_;}dUZ4!@-WU`;c;%7M)-^PX3kE3~Y zC)f0B(*InIUfU4-^_ditA%!fu>z%l~O>}R+!&}C>JNf|+m9J4HG(GsiC6Ng68#{Rq zX0l5T1T_QvUiLEecl})b&ykdq!l#qJ`;O|hTxrwftj|zkGCy7|4mAWd5AyFmvC!OI z)os4a+s~(rSk_{?Nm83M`v*!u0%z0(tiN@xGLHT0O!(0Qjp4HDicENA1)bT#0w&>?X`?XVv&x#eRyX0f z-?<6{vko_8x5M@uWMEvwx|j(w?FXVWKdqgK@%pOXZ&_$f5e83|I2?}sn6E(WL$1cD zc8hqKMf~FXc_pT7>you+OVQ%*t4^H^)OGn-jGz}fRN&Z2wvNX*ej$rzMMpAd-iko1 zD%Hoj4Xw{HU7fTq4m(Ik8pAJ-Nv_AF<~=tXdpE)`hf?9^#&G(lY{&DjJ)p|iP@uLa zT#c7(;?2BN`yfBmKA5TNUGgasN?wCB&c+Yft_p}sIqzmv(k zNUwa2xJS<0LC9CHYHn^H#Lu>|{do?H?@1=qk10HBqUJ>FLFb0jl>8RX(31Z(72#O!UNk4 zK0v5xrW72N@-kv0<9n!HKdq&rz)~Y}&aL1BDE^v`xV> zyO#FYu{()3bk-@Rpw6^6@*pD&ispZUO}hpHYQS~%jtUC1VGr?o4md8WXkz=)IZ)eQ zO&*YWLi$oNu{{|khd3F&IQL-EC2ai8o1bS2=iSdV;=$F(8r$(DNSg}hcU6Ehs)a-D zvt_5_`Krp=Xx{dq0Q@2NP{Ap&Q}kzY>RO#cIszSpuv@|DMB!6Rx+Y>RRpB}@hpo=X zz+Hq zHSSPB7Ap`0nU-y-<#V-9LKy#IQ56Hcv9d4dhJwCyY-9UY;Pv2=Hwr1n0aGYw!qNFa9rw`kjBZp^9N@0R+r)x#8q>_Q>)8dbUnwB`;45WJ^rr zf!xztDC`Em1&qQA$YWY7pTo2V`kmgR+;ZwQYwbnMCD(hH z5aMr8Ew;<(vy_mqt5aY`jdCeP6lOWw7x^!WSd8HL-rn1Jff+4UnN%Im_?#VeQ-W1L zwm!yTazUtjcS`J?3a09t;2?A-70B1q770HI?vBaW---bG-L3x%`@Dm_Z5Q`9Shln61LlEB2f|5&1&&#bWx=zi`9M9AoO0qugt{I#7r*f zwfUJ8=|e36nHQG0wYw_Xb;N6KbI`Xy9g+&fd#hY4sw?g4^7dgh0)KH*rO3nxNM($G zqN{!*>D^gfESs%6kqsk}(Wp8@A3ovxU?0zlKh}5Zxud@7H|lhSn1-XcQh7X<^ll^} z7psacf3xbb9d&#pUeecYYzvV?K-gB9+kKG~}iHS}zvp={(;hGt$iUH*@3u zsIzI^#BJB>CLV?vX>8B}RWw=Yzj!Tp#Tv^;KW~w1GozzVzS!*Q*ES;U=XePril1_hk4!DadALkK1*#xwjl7E!8Sm(iB=>tr+9^zfeBu=k?` z2Nu%$Os=WM5kkx)%)f_Y-=+4hr4;(FoM+pl6S(MmcPu}q!g?gz`FJ?IoHY~D{} zA^R}xNKKrj{O3#2tQzfs=q{#BjhYEl8V*rzG+~W%T4b42A^{pYtI9r-zW|b$17EcH zqpldXH_~-s43$?6Hib3=qzd*YgNt1-fu2R1F4YIii-5j%!9+jf}~!80}vo3Jh0j>*mDFB9)m@Y6y|~G@qG0vjDI*nv6S0SdI#+? zXL=Uh(KF2KW%5|dLv;NZNoyRE9%8)cMuHaZK#^s*?ks7SY`YCKln0Y4wv9ns9?V~I z=Vzp-#3;y|2nP+{Ht9|7Qx>_psPC+}|BPx5ShBnZ?Mg`2#ge54xt_SXu_b71IfyUT z63!E#(IgYWM6+8zX+G7NkKB?Tk zGsXwdRvwJ-dw)`wd{A9*Jw)G70k-#pX#$Se6DiwEQcPW)uy!Nu<6;SO_J;=zRx zbTX|Vd`y@ebSIY8)nfmr3>MiZMoGuzH=Ql7F7a z`?NIB5uS2wW|c*F*{~zw&mmSSE=#+?A34stfE>94crkl*(mRPw>Sesjs<)2ydIyHI z4J;2kz3g==g5mF&L6jkRbJD+5Yk7e5%FsQ0fg8Xu88jlC+`xmaPXuPe|yBAJsRl%{1TKXH*ogS(~icF03pHD0i-3 zdb-xqh`S@&U^(hCQ2N)RFJeSYV1(kz0T`wB--PI>uOTz8Z|Y*+tiMXKYbRo|tuH8> z#vJ32y`LB?+YAOCQmF`&>B&7;4;R*jYQwpg)#+$nSA|0W>ThY6OlZG>zi#Y5uuGKM zKMlu9WX9x<=hy8w^f!^K-}xolr-3Mv7j5_dEAj#f5>ah+M77ls)mA&I-AAT?5v)P? zthGQwGr(%|ZSMF-{;b7mfBKqJPRbtRK_aAgMmYcJb|a8G0}VeTaN_sL z3(@@rl?NlE$nJHp_o#PcuR2K-_Jt2f+tQ7=$?9`5Q&*ta>`K<`PWsIU4@lJR^cEfj zmKgV>e;Kx-Ic_w$o}x|FkJoTKPPQA4U^Lcw+3%3q;rc^61oUr-%-G&L)VV|rn_vhn z2Kn_F46^*Sh3J&;e%+8CGSv}f^LhU0v4lBv!#=eQX~-PL!UpiqUHwTlcI^@BwnqEO z>=5hqEjpav+>+DESV`5Z?JF@^_UwT?Pa-TSlcq6Q`|iAx6PaBF`x!>6ShqQnxAoQZ zAarF(j(cBR1wwlgwQtUTDYKpfor){}CN?eXDa60Nrz4T+fIlQ+9UFGUYdYiplvup> zF>m3EgTQ^#o3>fl)+B$#YfUl9^|}$8A*Wc{q|Xf0l<-bo<+UDdEMRNgzj^>L`iUX2 zWbH<;{XLQy8FZdR?GA78&!k~6N*tZozWD;bbVa&pcVEj@s>7;+NAfv}J z>pR~(Dz<*Zu0-t3MD5laPE7jaVtIbfsf*Yu77JmQ!`_O7x)Yqm+H$U+I1y$zZ%<7p zbC(#Z>*Ad`I=XJdPNE*i6x_*M`~&Dl-Q1vlJw-R^$f=l&z;un09>uFu+@Q1#zEx-Z zD&>0I>9w9tVSM@tny)nrioSLDKrkoQTduLX0U10`U4`_v6RNKCW_5MK4zu3pT4*Pk zd7p6lyNz|y!im4XQj~trX5yhpLW^!&A3z-vuUQ@6@F7pb8=9U^ExXV^ z^>*N_NVoNo_4E|HR=n#0r6t<>An$42^?ssi2cahQB3`qOannJRsgJ>fQ6Q!T#y?R0 zD^MNulgRcZxMhzqSl`gJ%Bz0PtKOn3hg8tax36s2i3ZCFj{_6|n+8Up#7^DBl^^_Y z<_GmK&G8>1vD9?K_)$_`tgq?TaY|GGM8K5Sdk<1Wr7d)N=mHWRfk=7A?i64wo$@sG zVE&!j39GNO`~7;fIGGM$nGJfHx~Q)nh0dHZJ!I*1%2YaiUFZ`gT0S5-MZ zUf7Ojdg3;hR&CgI9%H31=iAtjuQq&x``f7KPfs)&-1k%%joNMA!spOR;+aR%P0uvg z&AIWK_Y?3RMCHc@P!VTF7AEj)C)nrGsJ}K3Zrq`tiSv=Qo8tb2-E77%cEou@WNY+Z z(Vxv>&^H==bpwMlb(4rjAwxSfH2iDLOI1^hHZK6!;Djim5X=#36P!v0~KX|XfnOv z{Jy;O2luJak4=ns76M%gLfpSJ27kxu6Zg{xV_`b&Qi^Jgpx{WvY1Ar=CF@eo(1a?5 zpI*pCsyp-Q1e$P%)Z}U@Ck2IKZ5I6%HqGJ?V=^?nXya8u1 zZ5sU2rTz%rTvoxhL2E~8&3iaG`HBf8|s zFZnE0w-(|F{xQvX}9%- zocihmom?MI&my>`_X|CRMx7xG&s zwa5@?Yq1-Coa3Od^$6!IyagUUNug=@UD0!JQpBg5B9&gL&u^Q zy-J++0$hHBcIPijP0s^X@BRZc!nW^20>b0)^~3ys!StGGh)Qi`Pkn}8bQ{!aZyF+R*fb^& zP7Ielp-E@ez=CaX-edeUG7OL#oT+Axx_hc|!Q!zIVj@1AK{aUpGxi@L7XCOV_{xRC z4X>&!?H@Ut3PA3a{OGKpnXnk5%azQ))TwA_&eAxgWl2($1tw%lM3_hV?Kf)V%Z{X= z8>O_yM0G^tWCo~w{&X5Ms>a8lVMuM9sNwl9h<1QA%E}PCp_3MSfhpaUL3vc%`jL4r zD*e;_l(qx06b7RPPtbUQkN`;{>(v?hPcg9ZRh5pqX7~UXj0zS*mF>CV*&TI^SIUn@#x7$WdgS^>3=sCcN=U9%F;Cmiu(sP z;GbPySkvG8yMJX(zt4KTYmi3te*IaYKjKpP^%a-Z|DX?ZXQoFHpJ7nlVo-}=P_M%N zVw-UCkcdFT%p8nzh>&=Us0xlp>8Q(BMtS$(KU8trU;q_MqQ4bogLo0EI#|%J()zB) zSqr$JVpyW)dAR2ynKt6tp;ei+SZ!HA5v+c*EmvzgxbI>d*8!j~C9~h@yU;)LW-2?s z&kQ(c&;>Z2a8 z@%TFvHQW4)SQ*!AWxPIN>(7K1pz)d~leJsD#VNL4{R>$kKYo2(5(v=`^Z4S1g&MJe z64Te#gPw$cRj9E22q>MxCPixi!58-_KM2>ag!`>m@6#@*c&Jvp7d)qb--i5MzXzec{B=$Vz-5b9%KQnqoD78o6c1%}n`#ukqz4RAyV7FI#p%ABC< zTxtK{M9pce=j5gq)t^5D)eo<@KL9)mC+bZ{4`pA8hIMJ5^6L;B%6PLNz~xt>s%uauXcG* z+1iOztk(9A<~<=?>NW)o(KVZ?zA#&0LdHk%m`( z1j~7s^O3fRwNZ4hz29f96S{VRS3-oRK*%U^piY;lW6afRUL8LVKJw*SutwWKe^VyB zDU{jve-kBO#xO%K?gjXC(~EK#8Uq9g|0}V2 z|6G=Arw|s?Q%R2C7 z^rL~5_Ga1~Lu>A&d3Pc)Y z9c+U1!|iK?OljC^I{2JC!9+4p5LCmELQqCZ_pmg@P8m_rHkxFa2W2mkGMjGdkxQir zCZ2gKK|rp0|KdIInuk+OL%%PBHRN(AC)Sj_~hc~FMNrAb5UODSoGX#7)H*iP-{my^BH7G)pST6maQ83&|e>l1j{ zb}$~AhH-ypm3*8QpJ)23V+GE}VLT^WlG6?w=W+eAGWxE8LSHeeu+?21A6{sHc>VGX z{Ae{d*+Sy@iQ^R zQ`wT*HQr(!k4rVJN%&V_5ttVf34|nv^N1Pg;<2{~-^%R(qvxxr<`uNIq>uOp@~~Pw z+K8|0XaoJM;|<=D2n zjlp)z4Wd`bK`TK!+2c&AxiNpsnguWJYi%JVfw{l#zRXKYu=F{H<+k zDAR*ifVEH))V%3-mS;dwYzhN|waN$`+gE5BxmYZ9gXh0cXuy_^QT#At9&nA^W2_GF zDL$L?s7sb`2zL{-Bar3*67G|a@~VH%dn*Onm-D6!vy8Y5sqP@X5@(R8gY{DHcm!YW zAicgdhTrZi`X(W(Z?S z&Rp%sV{_6%=bNOo>dK(qJVd8qHz!fLfBNC2`8(J)lAt@-GNj>C8J?U$v0=8Jf%+{DpwCcHEJ1^8Lt%qt^hqT) zNIl_~%HZPdmz3bOHhX&EDzn32juQn1e>lqnyg;)#VYb;a_scD2lMz+|>HDAI7PDjB z=?@EaXNB_KWo?vWs!t7SmTDox7~(TICtA8h=ZBD!uz=)W zB$EhOxY4X_IXjmoiGY1_qw7z=THhDlM_6=Gj?+%rf8=^HcTvv0=emn>mQiPTo968{ z&9vHYAu;&;^>(O8jcbzSqjFXAl04-#7nSSb>>zgrNhG`ILw(XN;*C_0Srx|b!I#6I z8yo0P9ELZ)yNxn?fOLcyB##TmfpNQa?0pKmTgOV#dob*Opxm0$gxq4xYakYnJr53{?OcZUz3-EI=p2m?@!#gT@mXwTD6+@Y_S_`iQ!Fmj z!P?Jx3w?gA@)!@Anmei4rsl0AL{sxy)EW%fQJ9)nk)X?3-r26Hxvg-tMxbkIUQ7n2 z=8oXZYiw#>#QR?Nc74ue>3?rmiggF>+<{KhW!{APhgvSX`|uZIn5RTpeN!`JCf~Nk zHBYx%&)htn8O$YZfw~vdx(+}p)#2MDSSp5E4w>7c>BsLEV zjo)$9vyilbh$5*&sB~?`ydy35-}wk|Z!7n3Y# zHep|mMAOI5L^OSMTR}7(N`gewC8R-85-)ZjYUF`@pjXql)4F;SE}rl49~)TVE-@m& zhj)psqX7#g*ueuF8S~?QXbD!<+6e9ko~Aha&bJjoDh9%{K_zXWPdQ;OA(itxocYxjeN6USZs!3-KA3}^;nL6jAd zU!Zfn2My{u_Dn~b3BNIRo$;OmO>^syUe6KBwsn{4>mMaet3A5AgKWxW%Px_X zaxEcIoz@3if(cW)RBJ()Xd-fxCEiul5+>FOupz1fQQN4pW0j(-SoC5l{|?IN1=&$p zq!B-}`;vUOwAiOKLr6SL(TYJu8Edqf+VsV23Ia>DS<997WxCo~Y6340fps33Dy`+< zy&qhpYl>`S-I-Q_saEnAVZBDh7T{7BVMzog{aNf15THpdX78#}W45$N`^WrXEE3)B z!FrQG749CaGj$jqKwW8t#kF2+?@4F4ZezP5jaXHo5Mq8qO5uH2SW~v@J}miL5aEXi z81H*mbbIG>MpbcRI^(q++=umKb4rE-An&FnPOF=O3|P<~Aw$p$cAd^t@a}QvVo2rA zD|adzpH4P8M$Ff4%xTA9Rlr#{75k{ZcDuXOF_}%4ZiXpb=*N`xgzq(!B^(@1$g*Di`&p1!+8rzXgAdgJq*xfBU zk`;0ic+lTO2-x91E1UJE@Qy1bikUh7rFNZm5Nxb+cU*l9o}RmcF^Jk1sG4yS+Quqo z@uJvR8h*vuYX73qrW5TF=Qr1qAg1w4{8d$4L>p?wi%C+1(y^>aML3$IXJC@Jn(m-- z(;tu|O^mdeq+zoC{b|Gkf?JYXG@)7M*uqSC+y(oxP^k#2LdGBg8Du`Cz6lb&N;}YJ zTyTL?bGp(kh?)C^DeUw?Rb^G2M-}pj%izty%^Hq8gSy?9Sar%`c;eT^uWG-8M|atl zCSWx3nPFc0ZHVRERQ|aBhP(ay+w`S9tqFiFnIGTI17_tP4AKEJVaP_uq_mf6INo+R_j82 z9g8r$FEMjNPgi?fSPD>Czd0i`3;m%FMf?)@euSgtlh+^Mopg$qZBQXjwxna7>;k=-^5y*N zW15hR-l8fp?lQ)-&v}&k%tm7Mps>zT?Y-wApB0LvPRwtsGW%t(jSNT(-Z(t z+Vf^H;MsGyh3CAf!XEarN4kqd!gxpbo{Yt!U%Vs7xo@}CZRCO!xgG_7{Mz2e09>L+ z&ZH8p_iyE^Gec(92q_wXM0TuXWZPk^DfN2}zh++gnucl&Im|ZZjayS2oA;HXP|D&z z+H#9#Px;}r0#mb{_nq_pHOCjD|Kjja{|5cI*jUFf1ei@$o+M?!;(0(ab--in2kXkn zWqe}7{vUqK49a)2#W?mPwiF!w*ri-fpq{9&tsMh6?#E0VhXcd$TZIBu2px>^6BlES zvtD`&b=cmSSbqyP2v5s^>ON~tsbl%oPLy9{z4aQoZco4F!bJc=OZ|X^9FtvLZ*P)iZa^gPr&-ElxP2T?bWnQ`q zg}D=z>GumVX$Fl=b7^R1rwyknu9M~^9*fF#4S5911P6jm$;kT&^tb?f!FM0M*s$p+ zM@vdMaA;ZzSnava;oJ{LkR!}0DV47`5o4dfgK!f~Pmc5Fw)A0lP5V=q*oNvD6PIkC zxVxIno6rFXq_d*>u+J?u9HG{Pn<2uUawCa_t1-9O^3YrbQsNBS`<>&pM{8fhKk`w< z(4n*sapK?6b2&2HHj%WbCDBCgbDGNg#LqfvwD9>#ki62_$JZiEio%`c{=$2)M1WG? zK0zFCXK+YZwg5sc|svQpk&H3jXT_th&Dq`DtNu>d+`BI*cT-JPqBi<0VkyBgc!RE6U!r zUoM#vh0@88v1}QI(f2YcHYU-wO#8T-ah2)k+|wv`kLtyj%H9QZylY(OJM`Z z9iOnVIZ7Y2{c{NqrlfpB97=O9QdZco`C8W?I%u!V;m6;iWlbD^

8qk7o*a*sxr8@O*vTR?o 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

S#k6iBc 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%0A#sIpm*r} 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

ZrHAo6X7$V(*T5qZbALgXnJBlK|< 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

C+UyJp9?D}QcQUz>wEc|==e``msDPn{@l8M5 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�f-?H;LVXu@n15$|^bC%IoSNXR#7B0V>b|rwl2B zxIhv41a(GMQY2wa8LIPT@aW@GRDW6^wNtWqR7q@O3N%)n)Ba(y2Dgn)l*ITm$El}o zM3m=f>0hPqNZBz>XSFKvplCjb35!l6_PfUBZfQFbWVuqk9vpVsc5COcS^uVMU)RU; z#al`TG5hkW>&vpmYqOb~a!tEdbdqC?wqtV4KXz98D&X}D5Z~}Sr|qa2X*)~!&0lhz zpc|v@pl?(^!1}N9hs6PE0L^DA4~QO2YNEXCi84bxJpbrsD&aUeD@J#G=i22n$(CqB zFjLN7U@r^icYgfI?Z~erhBBgwsv0ETC@`#5=yP;C0@DEQTR__ zONZFbNd`VP-Jo>2(MzkH8j46TncQaIRVyJeNP)TEF{PiL+04u~1CZQ;urdI`5i?Hu%rnc$uL_s3rRF$A>zK{A0U3>2aBEpUpJrHP&YglWlu{!ZN2>^gL4Gq@}f%!gQ z%>-!b_~&r#N8h;^M&)Z!Dfy@9uuum3)B~~gVJICL85oJK)AIZ5O75=9SZ<+cok-xc{k_@ z!i`|U+L^gq$WNNr{RuogjiJW@vF6X`)6qpdqAtfS+7Y~X**KmN8sc+kl=FdVOh7O# zeUL(?Dp9-cT2Yz!y;+Wvw@jLI0NVykZ_%_<$fd~(%xc1_s`0gCW%PyfQOO*}Tn6gI z3i0jRn7R(gmCl1<+*G1I3Ew=`hCh(ul5;A;y3YI*O-I^Ey6kis$+^~@p}4bZ9mf;$Y1F51$tn9*Q^qb5FlNZP*BIc;5FG>YdEoeU0J7Mysu zsB9yL0|MBe-B1e%Muh$8`SV>FafQG~x_Mky2{WlvxYt$nLYyM7Q3|Ch0*pxE#ukAM zK2RTj@z()S>Tvm|XbPo+ONZy8kEF6P2$IayL5b zWWbf{x8|QAa%$xE(iX;2?@H=KOrbb}>8npFO(WR~sXp$#f~k9Kf;b~Ow{H|HEQPy$ zVSb=SWinI$G-qk(saH&3)2@4t#wnxD?RlBA7nBap6(7^u$&8`0gyy18$PW5#GH0-E zKaqLFZM8U&_k8>le4|U#MU%Iy99JO%tSx}eQvOQ+^avr$iIiOWN_cP+*gRyrh_dI);U#nbf0 z^#!E9xH9+2Q5!=hx}Mwh*C}&p?RQYCX7tT!dC#T`*0*w!zJ#^<`fO%<)7E9va!uQo zk5%hdT3*grn?koG*L1@;h3>=Dr!&~;v$kZLoVHg{=-xr1upos_rYNV-Z8Y{S%|^p( z+5%Oj#H8COj_Iqd4;d4*xv32+|G01IkyLxw1ZB?pLvp(31v5*b%O&cZ8Ka!7$P8Cq zWAr(vPs*Qkl!m4Ejqod09tAB@i3-t1lhPVv2kv!jzEf#o2(09hc~)aVS*X(I#;a~_ z$=2HWlb9pH)+soB*daTKWuu%e>p4vwDQ#7DlczZ&F!cahjo1 z?bHWT??|_yOL}a5tXB2*r{cYqT7-204ioyHb3Z!-4As&?H1 zCkR1@*S|rvJNFmWs@+ee+A+rm-R^!JYy}+6CYnzrxHt0)1|?2J9SsRL#>Xpm0T!&< zeeu-Os&usNV&rn8k9TPN$RM>b~_#kB8QpZNjmd! ztq*h9Rd`KfdkV^(O-XdeT@dcDeaX|+Q_=3?5KDEb0P}<@FXXgGl^Us10t$!d}i zhKvC-KxuqHd1fas7aQZp{!6;nd91^yOT#l)scs>bdQjVjQMfeMsZvm_8hn#ZWvl3U zzMYCfiF(oq%Utsm99z?K8>2rS4818!_Fp9qnseusd6&Fz8e|gE>lRb=9E7% zhh`hLYmNyDow5%5TIP<^?i`mFsKvORcJho%uUij`DLSNlFpIEOisPAD5E)+Ii6pCi z%ahXH?hjk(Hc|kf*BaA$>b1CAm!`An7WB8wmZsh5wa=iz3DVj0+F2bTgSk9;?575-lA@m}Ba~a_OcZ ztxx?B&EQv$XGy21HV>G_$PyDmw^$k7f=mGi-6~sQ&nnf;8mi!AYV_&tK`qHbi=o;lG z$7*cuzM$;;-R(ftcLL1^*KEeK5N&HLl>SX1NljC9u0+!<&C=F76ijEFi-X+>)NL6s z&1DB#D5G1`x>le@VU8;ugn5khA{H{KQ`;^!b!v$+j#1@=j${||=07BpYJB35Q{@DN z>~gMkuI*W3U^Kez@(I`Wr~&%!wYu-K@tIas#WeR-ck|7v8`-{;Rjvgk?hs|EnB^8x z-g$Yj0m)4|gDp)ryF3+Tu9-Y+CwJ57?8+GD=*RmY-O0e#QaVDn_1Z>bTR)#EHY(X{ z+>%S5$uYI_x)|xl%f)g^Rtnt_EloEqKU4rz>~q>=lzmPL-6-F!o%gotSlVR`YR~L* zOBv&xPq#_(F~BT#n^bSnPHNuTX?CZ?LL>pJ-1Fz*I%2CJ$(e& z^LyE=JnD9P%a%qZIrGs6Cg-C|y{nk_6DBOQsgg~ql&~}O`8^K8%|5-?r_b|Y6GJ6k z+v-GLYxKcU2asF-dn=w3%X?0jgmiH8)TXLJgW?x3_ zL_@!YU_B$jDrrn+R^c)J6^9CPrGsS)z`_>II)#GS%&uH<5Q$e$0Ps9a@yyr#(+k+8 z+9D=Z=`6LANT--nTZCufjth3$&3-{i@!d|E2{ruYZfyunm&vNExy$Vz7q}*t+WzAa zZ=PGwP+x@xL9cDDVd~-33w*aF{v7qF%SzJ}%2i!;HSx^f*r9-YsMp-(pFEx0)@H`9 zCJmLzKS}@Etskb>XdW$dAxEf5WOhtn`x;=8LUby9Q*}bLO^D6zV=n3+MnRF)DU^=3 z_Ga~@kuVKh=o)Y^aWrpXvsoW4C#tkMC(L?;3&zHH=jEE-3&jf?K+pYh z`I3)YJrxRL;Nco$QtD7c#)JT%27T{^(Ozm53o@exXUO#@VpwBa4v)j)14)gZ35sR- zU@>)8(S9>^2&DQpuDlf!sIB<(y8sVc>_S0D!vc)=mg=T9h-4>YmyZL@?45h{UFx9U zGaRK-&I_xj;HND%u2U*=-ooap*4==j^#q-Cr#V4?{O|v&wL{vL4zY&=8*wsSC%AFM zko(|`T=?5i#!y?|th1 zVq-whPbGsRF8xxvEJwp=Px642shmffUjB^vf3E6VaY9f>SH>{V!X>Rd*PHma=Lb;W z;GC7rFkC7*BASSuBn^?I5|x6)+~PWKY?bpOj;Z7_d{l`@+vZ$oGOt4w1Zq+n6PRQp zZ#&*daoiTg8PTkh9(I@|Rm{MjdbT9u?;_9P`z6}8k7{QqQ#7lVpLkNExyWMg)@)>U z<@JU}#x_~+e~3IcBd&IG&&fN6Kq@|!sEW9ocfB&uPN|Ip=cB^L zu;476Cnt?J(;5Tebbd5`-ayWFh{k9LRtLD#@GWlie5p~v4spWkXtMJvJn-#JzSGv4 zKc5=S8hVhHLJ<&QD2D%Sy9yZ@)e4MZr#Dk!EDGUv*?g(F7{*LYlLdU!elkysz>5U9+_?*O*N8W zDUw7o*+@VsXQLRq7`GLlVPkgBLB2mN#rtx)2Za?$OY~tZQTMAQmDRdLZrg6+^(+N4 zSyea2@59%-beJf5k=s3UJz}N@acBQd8t!==P%9|FPa^=Maxu?8Ry=4h2rH_ zmDolslm-T_SZx+DRds9U4R}>x2wBvRVP#u>io5^X?KB9S@zmclgC=J)sk9XD)in}_ zvtF^@>muCHr(%4Dw|!sQWDt5m`+*-c)Sos`p8BWwGdbQAbN@1h2jp;Nw`X{8ir2g z-##&BM*)Cx0e(xZZ)ZB=V&hR zI$J-F-&_eqJAa-5l9d6MQcF0HCD!VHBMQ3)o+t0e(xFw?>Z^!qDV@;Jvg)z)+V5K6 z7~P1z_Gf%&ooDR!Z2HU{*`}fNnr{$^dkE{oY}1YD=tl$xCUF;yyU}&e%Lc}-m34=5 zvR1zJK2sMJ7fTh$&h+4RciplW=_6ai}Nh z6K_a=^*-2z*U0%Rp;ttNmgA$7)P76-C4Wl?(DX8$>sUygID6vr$!LD--`&ev=vPul zG@iTl%XXf=CEC3|Gbhc{z; zYr3#u*|L|F4r^U`eX1;3A)HDj4SFj2+=T*BE?l zxoBk7jVn%w-eU|a#Bvw+OVES-`4ad|nAb@2ILtC0xp4S6ZZ$Ggv24Q8e>LBJ1o$dw zUU_Ul^K13G;;L8jw}R&Llhgw(bqaqC&FM9xs6GfJ!}YD;ddzlh>IhDMx9&E9sknICFDD92Zqsy5 z!*(aQx`GH5VqR2)UREta*R8LXp_f$2(DJ8|jGS+-mZTptNs3`gs5|YD6)&%rq%z); zUp@!x1%^p89hseW1bvVMsF!H%CQVyz!lXZgyI5vC#p^#x;L@WS;!CdNSs99`^T-)%Du=USb(hU6Oh=hY2>56ZP?>RBkmn;H&$iW7@BCm7loZ z%8f9gDx3M#jijY6AE=LCZ;gmEj9Ut&g8ZZWM7e*axbUZXYe>WvM?l$xEj&k5GlAi$ z!U^%~DGcS^euMFX*hNfQyX-D)*6O`$d6%8zoJsg_?8h=h4}-VsA-EUPD?f|$Vvc_6 zn<$hn-OChPVmIjkO~LmNz%GEdHl~t+8u(=lhYVgcVmH%YPqwtydt>YcTP4pOmsc@P zLOt;Q{X31QKhRG#^Ej>|<}Y&1FSRH8;#{-9HLy@We>>NFh{|7rYxdq@(2we8Lgjxo z*F1NsOg_uBTPlsoM9coTrnUH7l{9(d&w<$lFRJedNbyPoSv zgocwgo=JGTydpH*t}#45=`X)mj$yFGilb#F(rrne-e`L?%dT0zX{YH^+W2T7 zw@5D}NSSg^92tKoyDjWZpDI6(X3M7E#@oFp@q-`IH>(1Z0MY9%QF2uKNq#Dr#;&e# z;F}-=<|iZ5>9L$Gw}BI{KZOI*Z;)l8r-xR{hokz4dwb57s^s4P1e7BTlpyEqO7<#H zY9HBQMBk&IYNDIqb1+CE0+q?PaWKpf48Lc*?caZER3xO^>lsgZE%@~t&H6cwX}5ho z!R%)8Fz0Yd4xtk9ToI`FUnt(LO(diR{t&+uy3p6zM^LNfIw)q3gf#nvQ4%a7?;~nL z4&x}mX(Yla6!E)%cnjRhr7sk6O*(*pvJNO|Pez8g!Dlmw4YDL#dAnshLD~NN16Nz6 z14*_mE}N#v_)ed#V`8J1xoq>4?Fyf5v9cMO9E1S1h;%^w6uDQ9$lB4U0xPV*H4U@r zUkgexdk8Q@*B9iz)FrH-?RFigWn!ddq9`L&WH-w)I50_nHKRYO%Bi!S-z;z4AiDL* zY&DJcv^rM~_b^Jl`#-k6fKnq$k5Ouzzhb2ct@xa_GQNpD->X{B0BN@%J$2QyT{!BE zEPq|43aucW4m7@s@)R?##8t>!Z}`Dc_LTZXj~$_ zv*#4c#nB*gopyM7?W-*u5X~d3bU}Y7bm8k#u2(&qEj|aRx3YM@_#MaUQ!y%E%uk+X+xg8E_e%D6@fpuJ z=2^Y>e!|Oy({3mv$LqPI=%AdebE**wA$oZ;SU|OA57EuL>9d}Vg&V- z#N?tGZ=)e~h9853Ju79UVl}Ufef;XA$TbFXeD}+qWrOPzw&)Q&0`BDk&VZWJsMaSz zP(2*f%jjD5m?YySzBGYpMFQTqI~C)+7?yT7(}2>XyXK-pPgL5lPaE`U-74?PNWa-k zm?X-{97DpOP(#9%RSBkhYpBaL!7ZIIa4Gj@B87=Am2X#!#DfC!71-nhc?EiXpjm+p z3V_cpeuX5>G`69v#Pt@5t^Sa1cdOcb z!}7+4Zl5T@CSv97ca3{{8tTv2aA8AXqp_mM+HNHmiKRB0KvfRdXrnQt0@lHR=BXOT!U)w$UR+7*xx)560{BAa}`3>Liv#>*|`Y*w)i$_XQO_!72~ zF=0jyTYyW5B`X@Sw*vL?zO^V3a0*?}GAcC+zGyOlA3BnmFpUtIVtr>*HS^RM^z7*W0j6- zXZb#f1PLG$`ZTP}fLm{n<=k>Hkgz_UY#ppLC?u&!sBjMZVxjO-b0Urn3ZxjnRX_Qb{HbZB_d?pp`QTOWU8mUX{_x=`;9QCX432)XX(wR~M=G+OoS(pPA?q(sAu%tq^G zr-MC+as~hcv4*<%XH$(n>>EIb6~|C889`XHo~YAJhUz)YQHqMf45p!?DN31pedd_3 zRqV*h81fl3>$n;y)#oEOR7Y<1k(#)YoRS`@e|>f2CLg(`Iq~)xLyGpj2%8uAFp_iR2a`0HSF~q{Hz->sr0J< zs1ZYG-yywr2CE%XG^V+}^Mw&tN|okHHK78|)1!{Bn3I)L0-OypS~7#Y)|ri(Q}5zR zy%hHN;$)^2ypg7IHtV7%bD3?d`?TP=%JTE#ZazBn%QzKh26L3!OoNpo+)s4TlR&$O zSP7^dK&Zyml29k~BWyK{G|1}t6(Ba8)_8@z_OvbM8zvf6(h*R@CHJGJ_LW~v$29B8 z0;2tso_5N&@S*;(LeS7XL0|+S7${R8-}^5WAt+E)4q+HXgecamk)=7g zTJH5JJVx%B>?FH&YiB~>$M!u#kJgwJ)Qwg>8hU@N7)<+KZKApap%Z!~9u@4NR|Y{v z4E}MGy7)gT1`~vMF*p$$ZbXT$kG>!T^tfHIiGuL0(-DNud05yv7~|puVYqe_V<@9K zOcKU4JQDI77)g8!EyR5rgog>(5l;$t#u03a1QPWoB-;JYjt7)OHY_1axGYU7%}na! zjxfdz_a&lx-ve5M#y9yFqlCpy>zQk3g)# zqfINu;XwHp=C%2PHGotZwLj%j*77-6+LHY*ULJ2GFK?JRM<~809bv1gIzy_3s&;}9WhE(h9mk`yXF1L;b+1kYGvP9TE1v9S?&5GbXX54IZCujO7_S4B~3y} zwQ9hHv|*nnm0fvlq9m_l*Bg&UB@(ArnV-~pEfS9)A8GU11|L`~Sc4?! zP(YGIWVG38y$>)U0*Vjh73lJTW(B%^V4eh_ILYw=0UMCiRv&*B8&~;btaa8yOBp@H zYDe_(p**4^l$gyY|5($UrC{KP{m?V;hR`sco~lB%C~erI$mlta4+3pR1^zfb81&^F zUEDHV_4WC9(O2x&t1$7KeSDy^*ifk1X{f32LExheK7H7yzZl&`frRe!edcaoSQHW6 z+Z7Mpjs9TUl$k*HycP0#%myF$3v}=E*^KU+eSj_K3PEko6A4A?adZcw4qpcS1weV1^6$`$^rLKLcrvBxR=g>efnmP?6-)R~M zzT}xfZlJYtiO$kAc+pc}qLIqb1bQ}lOlhbGrepQ6>lfNHaIBY1n{=d6u!%$(Wy9)& zMw9PleY|A@8c2!dv$CnmAWHwDO0$>-_ahuHxftZU_xF_wt6)6k{~e4cs>*SToAk#6ReDbEhiFmuf#ot0MYbLu!q(c9T-7S@~RQMOHy&BB^%&4jHMpQ4>XTLomo)4)4iTssiyoR@hZbKfEN>#*cR?Z~= z;YsJ%m{r7L7w7QcrpNpkHLlqp_q-x(sAzqB!*u4k1+w4du_#?gre6rE1mgjgJZ8Ui zej7xA59j|^LWBQt+|L*a%o`v1!!b1Y-OvATp~3#t#6S=so$oP(2rTy^H28<7xpaGg z6+#s_-87&?UkpqaoBQ>8&xn!IRbGL2p9i?ccBHf!Z9XEUdB|)t@BE z)x^qNJ6=s&(rY_`1ebr$l8LNv+W-kLv~9xF77$(`OSrL5+~_w93?Y73ql%N~s)6~{ zOzCtFG3D2u0wMRXy%oI&%~blSRK6>f8L#FI8d;V(AVS({m8Oa=EH6NE2{A!K4UpUQ z;)AMCBDla)glMW!?Xs&7b@*DVSf8Oz!Xg29X#?^BD=R6esW-$cE^|1Q6fm4lD)+JX zSD9-Z&C1gsU})KYmHSu<>}T1=w_UVXqsG96M30P!Z z*?57fa`0d{H0>wI)wgjPQcDEUq>Ds+_PK>S)6W)t4Lls3Tqkrm0i4~;+H2py0s7n2 zpFXoc*Tm7{GY2zUvrXIBAl|CkYnXP;;5>wV%B%W#gXk$I8J7*4{Hp6G^?6&dM<*vc z^4N>_ZZmv2wi4cqUqO=xUbgUdiqCNtDVAICHT1Rt)OiOp6&7A(a1VJXy^|jm<|iK& zTvC?;0Bg`#Bmtr1jHvKOER|S)Ec?4_j6?LTkqLg9Fs}UTp~6|)q^7}i&%Yl*?T2TJ zJM2Qno#~zv={C(dLz~@B-cewW^JeOh1n8y?4ItHJ+hbh({fM?L1rpGjxC?p~W0a`5 z28ud`s8}N2G_aY27yJ9;Ojj59$}wL#415CUY`V=?B8J#r8g-(DfEZi>lOOASzyzKf zK$0K--e=Zlv79Dt!6>WFPxx)&3K4T){l41eZpt6>S(W2D)u%qFWc=IR|HvysrSuP%!alK8QWKeB+R%hTfoo|OFQ-nCyRghTo;F1VAAbJ#e;M~a*kxSgr8~|X~ z+SnN)V@0p%phh2c4orz57U)(zcZXn{!;ln^y62Tu{ww&%087$&xLf4VT^9BHI)CM! zTlo}IGm|loX#}s;F%F?XxeUeprpjD(uTE?Rh-5~Hrv2kjX+Z=Bu$xAO3ZXvkczh!V zs5xxoYH2C%Xqm&+Gn^V<@fKz3Ak&%AjE6+;7B1I0BU@Y{^=`=huUj(I#Z z)KGTi9w_M=k+*@UoSQRKP4rPyD?40ajx!bsL|6Ob4^drh8;PZhf{YeRMu!I zI4WQLZ&3N_Z_WdafeUFYAc(_Zb&77J`f;Sq&fyB8{gPJz8+nZ*+(9D4tVbgBb8GA^ zd>K3A(X5#G9e;j?b7=wD>UeFQ>4!R)y#Ujfvgu!jIC8TMdKhJVFkWmK&$WC~?oF)nh|;HK$Km z>w#LCtw}>-L(FTLZDNPc?R4J8Du?ZWUwF{Tg7g)){4JL>?%9fhMq56~kL)GYvc#1(}~9r70$SMi|+8QFwnMCD*Y?x^-e zz|~~|#~Z|Mo^VWrJlQEM1cvLifTxflT=FE)N9=28l6)~@6?DT%f1KqFd9^3D(yTX> zn`7uO(#%;{5eO`#3N%sZj|5+FEvZ_%q_z7sT>XLnQy`&$RddM161ud#w4?BHp41Ot!A?!qise}iR?&8MrAM~ z4jI;~CMR(HsgCSbl|-(tjx-w&k=;oo8yALb>NbN9WEoXr*v=;1;oY76kt=DJ zr87;7C>`KkK1LXLF7swPZSj)Q?o$>kWs_LLL1Cpz(P1Ll99q%Ep3-YE-Kg@IQd$VHHS|uN7fW5R zKC#W%ev&2iWfP0cNH)+47&s;?$SQOt3<;vKlSZCSM)rFeHXS~B^a z(aFciRe>z;ir#WSj&E_wyP}hi)s6mQr4TP(3-Myi5HD_SN&QjTH41`G*^=71s!ucC zCL$$%H0)X!nCY|nvMEju;Cy$3;>AbA(+?hw=FC|7tg@n|B z_Bf&x@f5l(nqA+IwSY2DE;J21;r()xV>=_17GHLQZpjJQD`=TqO%}w7Qsybe39+TH zBr$Upv)&3W#o9~^j2u>POHpHqsn-HDuRqQ4tAFm@dAPFdGFt_ubiK4G+LSYq#FH?0 zFRhi1DSEEk@@jPen-yR>Z$@|0N?qtx$0=9OFH~DvryC`*$S@VWvB4F5ltg7V?)S>0 zXBbCsq((b=_-E$E@9URY^_%>v+-8-hk@@@vZ1`E-qr`~={40aZb&@vee4}W4CB@_G ze^-&c;##$9JSTK0hnqdsBt(Z@rPnBvxetO5IC*=CtG*cX#41aP_S&`>b8%xN(u ziupzsZ`~+ayvA>Wta0A%UPUH)wR%ZOC$g?`dn3emD?X}SZ>0+oR?ZJiYvewq>3EeQ zuQcj2C0gWFPTrDflMna$UlXLno6H2|HGs#zu~R|yEWmdn_4y8hy(0XBL7&q@0z?AS zu^OY_$-ROEr_&yd|0EaY(x`w(a5@Fpglt7H7qs{a@^z_rJ_u&9J41-~qfUa0<%uY& z867AfI%qHs@k>xFO=}v-?~DpZW66EIuO-UO-52GK-$#Oonrqr!?8gi3##~f5C3)?q z3CHj@)VDeCx#rR!<BZf1dxzQ1zo3*`&gjOAikoE6f=_plre zA~n021ndX;TmB_hDesTZz*3iGRqhCKty-!;qM*x20BHa%38P5^1#&nQTLCEWKeqgx zyvaEmXa>@>A?Z@X+_SE%MZR5~DDk1kbR}qnA;a+;C zqB|_v*}!D!4htZB(>hYl!W|vTy|yE=c;hc0?uX%`4pi8IDswkx?(r2SS|$D)-uL2TMFY9S%*aryvBmYEW+-GKXhvAPDX)K zYsoX@0{hot6Cq|DLrO`c@sBP|)L}=7w=`4JUqXjX#9pX1$iDwAeb&kF7uRQSt^ z-L7H=ql#4Z=1J*xm{Xc*-$d*<(R!hCe(N^;NzVSaEQ`Nimsl22zGg_eYS?98W;m!f z94tMU8*0%=lyH|z2*`=ZAmkXiG|{a6qK`4WlxDsDGI2qjWbOx)@k&c(B?B>}73q!VLmedV!vllYks2ciED`*AOYbM0V1CBu~@#5We$P&cn#XeMH0lSho

f<@Pp24Af z?22D=iit)9TMfndM^Wcb!zt4x-#uSbkz4&MF{C?@$qR4FJg7oc9G3kRDM-nRGB?iG zv|9NKO;n_ych#U)t*(6k;1A!_`s&C{K5|WUWUr50T^(r}Ds^^ON3K`SXxi%Uh!t7c zSkSFT6z*2I3Xxq3IG*q;DJLs)&e3!;6g5u}af=g@Ip?5$rSTC$PGZ7|La!8UvNC3y zW-VaZyoNMifI>ZFVpy^HO#SkfUBX`FU0^zZoyF1{D=Eo_LY`O+zcZ>yK4R-Ucs#g^>0 zA-#yZ9;%4P--(*YvP$KgX6dv{q#OReFQH$ml&jV`OGw`ga!%&}tK=N5IH{&qyu_2) zoo7J4#f%j-m}E0n^^#3Tc9@sV;Sv$Z01f3*OVQabbvCrRq#XJ0v97+$=mS{Qzs zP>x&d_AdusoGBP=`zCUXy*K}BV%}P8q zl(K;omNT;V<(dviN8g&};zx+jZpMd=g}DBf-!NRQXF6++RK%$EcVCyP>6ENQoC?P_ zNaO1`UswJD9-X41ri4HOxf?^8^~%Y7Fjq;5)PSfq*hP_`7)7;9X)0+#pt~kM@&&g= zWQqrit({cmBmlMo+ZgRt4B~uPjZk+*HL;ZvU^voiBLi5vLe*>!#h)3fSk$zdw{02M z6)hplf8t1m3;CFqH2ul$mjNE`+AqMSga)Y9wM4`wT^J*3g+7OY9}eS@ zbR>(D%KkLmWBMmhn~d=D3JiFjAWX0wSjsJ549%OzA>R?kUg^9HAM1kHrDH$D%xN5B*** z^27$Xr@9Tc&#v3gV5{KmU7tjExfh0X<%fLvZuKO=&=`JvB^3(ihNwa13&W$rkEzcw zzUaBeRTv(Ad{r$1!uS&ETtz(GU5yMIo}qSu=4k!$TR=vco(CK!6m}*lDE!5>`=xM2 zC-@5#ZvL#J@RR?aQTX29(y6`pc_#X8pr#i*3LhjMn%dg9yCFJypI?mBD)!mLD1`O zxs{^2j|4$i=)A_3D#go9FXBgXw45V{_zQErK#!(fzlNU3+^W^+h?oQ_v#;ZJeCVy) zRnZ!CUb2YQo?{{gNPz)^OTbcX^yq*nF^&suqelxAZ7hYo9!)4(pv0Ga-R=2kze6~3 z+c%_2d&lIu^po0&WSU!XzNnxw#=c&>0tx#n)dQMl@3hz{DZ!*X?$1OJ2h;!BEEmrG;Covn^g^0IyWS`xo%g+Dl`MX^f=i| z`uvTRneV@~mlXCc++GGRDarn;eI6~{vz3h{Z{`iISk;?KjvirWsIsf%Mo-ur^1Djl z%?aDES>(5uOrj?{M}B+BA%hJaL!-N*Pq5j#yxK0ox3JGYglW}TA-+e53-Q5-P_aCW z+eUK2QC!S`v>^nucOd3g6`gQzH}d!mq+aSBx3%Ofp&zu|VUh1Ql{!>3s(lk_Dm2eu zHmgbJgNG-3N}e8=HpMexPpSOR$b>3+m5lF)R_}j&yCL(Ec6e6?KJQ)atPF2C@wkz!lBsI9JRS8=Od)p3BR3s4rjdTf4gU_)qg30E{WLQc_#9z8gOHXH( zcCGQcVlG|SscS6!^%K-52_m4T>V-pJ{{%_mt^?4GqY^fPho!O;7GVc(teo&7+zlEN zk6x5P;(B^4@#Q!=v~Fc3&H7e7*ddB7H*Mfnk9-oAsDx3g zS`3h|SP3R@NC+}P)a+1##Mwjv;RIr313ZYeAjbZ}o;Q`Zt8yn35ipw7Od^mnUn#xT z?1dVP6-!^UQXKbb=_@`6tY{A~#IJmLmE;g*0;v+o@rnE0dcxIj_i>mLNO1m$PWe%f z2w-!5kO`jEHyBJy$2x)l;NRl*p*=}4Z~WtKCn_MPCVwh1rKxJ~;5Ay|!jfXm{ds#( zq@E;=oUg+WVK}GP_7I}l|A8S5?wwT6Rn544x^DK1SFX zqq_%neViWPiQ>jL_jA~uE^vk+7RFY5ZvWUJ?D%3f+9pG`&J9_F)RnaR*9=|kTwnUq zeuggO2&1cps`xi%9ESm>gpk(lyR0!bW};>k*f_TFF>biZgftBROm(%PLUk%VVdx4q z|7$}x(G4_fwEJN=X6TNwT1_0fVYtgI)pUvLPkp%wm$nHEQ~ni3qGZ0$42BuN>x!lo z`&BT)ooOj(Rr?Y9;{-hd*d~I?w!MZ;;2~`?i(Mp;+xd;J#KaP0igOMKOq^}n!OXUs zneFAyaY^}khJwf^%Nw*1N%rsI6fwC$uV)|p>=ULh5#1j*pet1hzRj>eq%PQsz|9Wv zD*(#t`S`n=3Lc=6gSr{b&cmI`EB)m=cJ158lodJ|ZuOQ0!B6`_iMBq(v;jW72nI== z@1++n{1`rgvcrHnx1rv;h08z(PsX`f)&_1{G=tM0Tm3j)_09tHEod{JuN2 z$i?!7WmJF5AG#?V7URU2J1^E&yd}G!wRrQwv+c0hZ0mvB)sQ!8H{nD$(B^uD;T_?o zr8Kpnl+Kk7c4xHYAF|q(X5>@4U13@fNWx3$7(DE*15`bSA&JG^rZ|lbQCXj2w=bRA zwBzEBQ;TsP7cvg<0QbkM?^u7?xCb$2P_4V#loh~7mfJBf#l=sYXBVBSGh=*Us~^Dl zb@hGi|BgK~ciI|*FTF-YmKYXTeM^7tKTq0DPt*b3{w6lH=RDw)^ZzT!@d(*`aj1)ek_1D98-%;{>iV2Mr`Qhf%mCVw@-21LC? zkJEINi`w#2yytkzY+H?O(Xu;i+7>E!MkGFry(Lv8hLT^Z+QtEeH*RpnT{j!9R;nOr zDIJ{IrSqHVD}0N-?py}EYkQ2wm++)vK6NMklYE(%)j0#oZ=iN=qko3(tZ5K7@$#(w zB8x!I2=SB5kz#*xIQ)ARQ;-tpkWjnp3og6$a+oBYEof)5|BX*T-$a}!fw^`)zf@@r z)GK0jh~T?B`DPk-xt5_!gU5XQ_}h8v>PQG${i;CBq~|Yp=4ax2uXFP&9~|L1oIWaU z?F0jD0COHo=7qEE0Rc{M7K$zPZL2uR)Y4p>wueYa&85)QlY23);SVcs@sE#6XM_q^*(o7Fd6{L7l|tlce5 zyV7ff7c4zz^*7z%?mwnlq~5;GEbS)knVHso??lo6eVSWfI3^i>lh+7z~BeQzlJ> z&<(`k9G_~9rru0YsF0b_maN4A<=8~j9=mK=d3AWEm*3Wv1H93GT|PB%nk$v=`4=#& zRekZP;7)5I5NAw;%zZMPD=){dN+{$aY zb8^{0T|Rop6h(^BerY2OdEafNdOS-yQfrzL)@+z7AZ(e$4f<-fG==;BPX)x82SCwV zF48j*b-DZSSX$JO&+L>0!7PoDl9@)^)%AgmL}&c;Jj`+A~% zgVa7xwa+&$RFfAUKUYO$Um!;PG zMoHvOk84wUdAOVJ^r|f|NcqididTetqQ7Mqc+E}aT02jYawd30X#MIo{>2u))FytJ zm<1+}>fy4{!B=bNvCflP`rB8iMY^xD+8eGvlFgX!}60?tzBN4NIx74trxOmwD zce^~_W0WpE0d69`t;iMCT-lD4#~1(BWpm8f)t76!cKO_a$rbVb9YiqlePD7T-uHZY zV6x6And~ipmamngI9mM%-GIX>#XimDjlAF6|H!eXX0+NTe#M(j58Q$nxmFrbAvIj!ww7qdUC55> zoyVBqv~00|&wu7S**~HUajCHs5DS1pboA!G z7ZYni8%_HczVmW#l?tl7!r^ZkQHw_#=V*AU=NHltw}X|su=%3 zhU16>l%w=x*oNe$*zYbWjI4++&8l z>Icm?L#Xd9u~&T!yF}^TVMA;*?enAr;j66-^w-*ph*Mu+4DD2kumai>Y$DXceTQJo zn?Q`0AH82x9c)c`1{U9es>#-ro7^A$6rccIrNyZBPU0puxIZ*i*popVfAv**wmcc7 zyvnHSTj+s9!BwVr6rvB;G0qsZjJ4EO-e2|WDQ%~=v~~`;6Vy9kzFS!`9GWU{_Mb5V zadWqE66Fcr*t|*m$&6qAKX)>tw?>Z`GnAW0^IXLBunvK?Gz~4SMRe`i6z0d|VnaVh zL;xcf5Nk|`z#0?IZMhL@i7B~m6u}orN0BR)b&8vR3(EQ_D1}9LE6DIML8d(Q`{N0dZO8=^ zUgm5WfBKbU$4?*ip)0x}qgmA52`TK$2sJ;T8~;h07Km%ir+6+hH!!Nh^(n`^)+rx7l$K@Gh{-ayVy06R(rK~m$V^gN>R-v4v{r1%%@ zta>+4EDYN6ZIvaj-hcJ?9_ba>w&L|p?eONUe31!u)&SL*p(_?GVIAQ}q}ia~PFu2d z@i~BGP=u}4R}*1(9*F_s>rTA|{M=uCuMib~ii$A;#Xlx>OcD+p(X9893e)tee9wM! zoMh#%i!UG*L*LTQmQvabVT>niVTUsZ?WD9;G8l6%`ukOV7kzSIiZmp<3WVf)lS@$kUd-3P6#ne9dduw=W?8fEYGJpWx3KiO ztEVbFk1tg!)uQxv4s#6>yK3KxQ?pIaEm!py^S-LnW}R&mn*nEcn+{*zFfc`|b9IfX zc><(J{tQf!N_n*`2Ib!pr?Mg~;#3u%b~x|XPLZqU)jFbCzS?IIvHd||YCdvc3Ql?Z zuAZSR-zH1NKdJq=%!p=Uc!ka9gw@Z3{<-BFC z_;73Sx;=Pa^%%v)3I6tMqg9;}dMTUD;H`8af-9Q#@x_b>TlllMlZaWOOzY{TzZ6S? zU|#0Am49H3pL3hXLcI)f(X8VrEy0K2M0%;DC?~0e0Fe$tj7F}^bwUyXV)SFkKGK?% zrjC##BrpiJ`y{4=DwEq^vbM#g6Q173!b~L5d)G2DscafO~UB%Xh~B&gzw2`6oEwesREe5jQrb zYp|1uvXl7Lp_M?|?_~GBa1tWxiW{Q#RCX`Vhh3+=kdIO>r}sb*4KWAFH$dGXZXE2B zMq#7-EqBljCL{RA4{%6fv`=4w+1x`0KXiy6(pNlENZpB%8}YFB46H*|cpM|NMY%bt z*5V(}(9ybR>CmVkVEt$#rucZ^y+ZM~TG=@UaT9{Vy;ND;@>dB2cu1N|H0_*4fhSlJ z?4KuC%4Bv;US2A9Ptto;o;7498r-7eLm@Lln9@1e0tv;C#3T*MjvR%BOx3^ zIG+{A5Wf>c6q%DCl#nHM_yR!_^`GYBrT79OORE%byi-~2`af;J=OOQ2wm5Et#{Ihd zJUY}7m)XH)1-F$3^|k40%)s?YZBYX|rnuyL1CS<;^cA`VYJmT5lN>SnqT1)9+;ptO zUa&xD^^8Rh>Tm!3Q(B{wx96kRt^26F7TCA+OZ@091I9f2mnW^oy@8p6U|~q8f0!_i zm8_ObDcKaF{^5nINSjy8TG>lh46TU%c207x++rIyV;P8@AU$`sNFrtD_zA^Hl-k=q zvVZ;=FHz{UCKTqNA5dbcE>BQ231@dgLG$azgEu~}JR!xq5 z+8et*ohu!Lij0=kb&jf4F|L<}(CIU`v6;+n?Pt%c+A@`}IDtIL{_FA%Q*jj+f4bQe zPJuW^;jG%R*~9)Tik079(f+Hg11Vt}#gBp-Y-J|^57w@xUCWNM{Sku2-S$@B9n0&h zwuH)`psK3|ttu@N0laf2l*)f$O4bU#>C}&)mo_Fv|L+PF- zK0t+FaZ|Iwpo7fvv628E$ah{Zp==b~%iCjrR!DShWlZuZ+3&A89kN)=m56NTK`vp5;g&4J5Gz8hY^# z=S^Z{bwfrxKl-V%mb%Sks9C$MC* zJ&1dsGCNzMLLDOGQu7G*+sNvW$!eJ}tT!k)>V?!b>!o&n!-jDm^%bJG45<=B7lni? zX?ydKP|B$$nEEWI+gdgxP-3&?3GqPu zcD}V7Qioa3`0eF?0f}x;nWQ1hUi-cC5Pz9|X0)&KC51xLlQef{9T?|R)vFKm*Qn$b zJmu~sTDbvnYj{VFZ`TuThxd^v>~%4P+d3R;OHHN!TD+^C4WS-?*WD(8hw|Ml0|fg} zwa=XEd9e6eWA+ecoX-nc^T34VxzWz{F zM%}FHChj+LPk`+=*QsQwg*Mud^KI?gS5{o1bbh|jNmL6!|3BQl3!Gd(}FN9-P!{^As}E-(Ak}c*%f!AW;ALNMl&Pn?VKdLtGiKI9hF_9 z@)}fh1ENk6l9?nV3<;MI6vItVGav~8W&lav@9(KPr@JQ;j4rzG|DVq%bNW=(se0CB%tm#cK-fls8 z;I^f`30}N>`kvkS$^5P`i1Zmsr(T*@+ndl-cjZ``94MmTFWH$+?VdX!_42$o_9pOA z>|J>XSxzz~aJcQYxw%Ouv!`Vfe2iq9HEOQh+_o{-_Hw@1J|$oH5E^c?OuKINXz+oH zg5&QSXFpkKca}N}fM@64uQ7HSgj1h6`d|}lU%5SCMBX()w{z!_7NVG?XmYy4Ee=r@3hyBE`wy=31voxZ4`6(?` zYgh}`;qUYD4vAh|hs_*8$-mx49IZ@ep7p{_}7OD_I6$i%g(Pfa`&TXJw%G)3Lk z5?neyD`W%{urRVYIXgK)$bzzvC?R#{f-!ygZ_Rg`PrPKV+h!b?1Nh)>x(b{ZudwBi z>9lTqFip&WOLBsa`u-=C0Ji1Igt(gv>z&J=+HbKB@^Zk}{=Jp66$d!b{Ijw#EdB)U z+dg3&(i2-Azn=Zr3+2r>@t%m-6UokIqZ%@Yj45Dl1tp9 ze#;VEN|rj24?afU*VA`9>`Z-U1?XAtzoq~3TVKU8)bs?^Q}o5=)IIHwGhj{T*wczS zJ%_c`B_Ucufhu+hNOd;u5gN;h5IOS!VF#Jvd+)euPiZy0tNm5kiINCdfN3r7Exue+ zYWmhqK^dhQ%d8wDr=L7sLl7On7Ogy;_wJlu(iUr+t}?+G=NJhlTqFxt^V6A_v19PS z?=hpvs%{|!#?1?*Rz+KOsXRTIqXdIG$lo(Anrbx%bALZxp9mtAFlB^lG}4KgBJ%h8 zz!|EW_3VYo@%ejMTK~W}ViPoY@t~E@Q(4V@_7Al01RwR;;4{Qmz9{oJJDyp0CiPNs zD(8v!HTDNrC1}Zj#eE-q9QD1KT^qYl&4{RNc;UI5nT2XJiontl1q)VS(e$K$1vRQ5qtS@Y_EZSv!*{gQJ&lq*K4>dKJ`O z=07zq<4Z9HEC!W0#`Z+#RxXGRxfiPEz<*EvT)?O$1YEYPtiF2|>EMP>Zz zkQ!7ML@I#Z!&7QXsC906@6%sOLgeH(^QK#0v`r45IB_KR{?7N94Pi99h7y%7ex1+H zS`;PHg|*>-j+pyH%e^zafm|&?sv>RFyiOQwrD?os#+MwKpDF6BHF)_X%|b3YazFll zo0i1>e!VgN7t>Do>|c)@iIL@Wj!&yWVWZsInRu;;$@r^uG3nMC)ZyRLV% zY_Qu28L27#oOcnnh(MkgtLxmiYC(Y0#rEFL&efXImwh1-MmlvgbH&lxYJ7XGGUxit zThv@d$g&C^(>q!li*M&J#G2B3DCpu@+yV1!X6e4ng{RK?T(W%oXnSW3O{@YqGf}de7uC4;)>g*0i>8=4$qdtZwHa> zjso*-zmsz&q%jWTewxhyJYI=c3WC!|Un(IV*@14A;iBNYr}>~J?Yzw7ikmfiU#NCy zPh2jAy^Qzf!gGan1E<^kzSAh(JC6mFclH?dV2X9x_;MF#V@dN-778>UC1Qxfkh6&r zKx@U?=A#_liI(ekGg9M()TVidaWY}1v6Kn&1P)T$N`nWvi%$rV`L=12#ftX`>Q3f2 z>@rag6nTe1>}Qx-tCVJ&qdJxgOazGG$X(trOX(&qDA}r#GnFD@k|Z`$5H9gTsA7Vs zqB&)V|ElJKPLF!$Zsp{Tj4B_chI1jnhEpNr3_eJaZsqEPjfG#eu+@n!sH*fkSc#P= zw=j{+;epugmm{PtkqgPr6QCqbN$NyVH(I@pqBtE{E)StTA{MPlt<{>8^CfCoVhF`- zWTEvX5gNAF^Lzq&ee?{|G80k|iU=dO>bKZqPV*PG`3Xjub{s7^GQ|m%##_ko*p7mn zw@^qNk$@nu#_d=$9M&vXk)t2y&)7fxq&Chw6!O6tV$`FFG$b=-Dnfn1(=jzg;~DO z#0X0!PxO1K{~eRg(PL|BFpC`J-0Zm5Q;e23dMKY>@CwTsi$ppU*1Br=-U%Hig!uk^INnJ% z^aJSP)B~olOHtJ52a`fsew$)Dj~@p>T6HQ`*pY8r18KGO=Qvp{xneb1EOg7C&JEYB z)h;P~5m$3?8m`$PUv4NWC;Fk>`S3a-mU0pOnJkm_Dlp52pE6@O8Ab|JVvaB6#u zcn+3Te#)aNoZ9b)i{q&^f-)$ZAcb`C{I0#p#rKSJgPSAC4!2wU3!frmrZ`cu?*I4{ zr=7GrIJxl4K5aRr*l$NbbdFtjc0-#4kc71hRnkRBZBruYhMBVP-C(nAqEaM@e1MXu z)8dgj_%b}}s7-skKH!x($emK-|3I6SlN2g@hbk+S!qM)7g(}TI328p4V829@v#RhobP_qG?0O zqm?94)0X*v`>RX0yG z{%y(+#;j%1i$B)ce3%;FQZjLyt@-vO>xSgxaN$?!B3m@-k~At8hnmn*j#U`c zzL+6y_~4w5NA@2pAX2~8>T(sPLfjfYbjN|~ZJ_BYvy3tosPR^@4NeRtUpJ|&>yop2 z<4zlrC^0#F6PKq&GgK89xe(VMflV)(0hcgx+fvdH0ZQbi2t{8CJlS=IAvaiBOpgFz zU(6~a5!q3U#LE|I7BPc3m&8s9clB2TW!YxC1!q4(8R=g}%S(S=7$CQ-svNrJHp%LR zalF-!duAP8M)hmzPUjdC?pYL(99g`;qgZ`Z2RnF*z9YhQLZmoZc<3-_Pg~2whDE*1 z1Xu3mCcpl1Q6#TL>~83KVLlN)K3;kH@Ob4_#4F=!Zx)%qm?d!6E@O&DnGFWD;XCPV zQ1_S~F}(-1n|T-2NW7^}Aj40aBGf7sthnGVeX3!#vNrM>3#A&3#zQZJ=*37}n9xgo z`2FW!9bcmC4r+J!I?WheI22y0@TMA>nheL)wM(00Y@KBG@P6XE_rVvDS}wBOG1cv9 z&;&3NzcH0^AsP&K_7BK2|DPvQ2wCVcc7aaHEVWcn#<&In##Tm(`yf|66pjq1GyMxB z=S2-UMlfYmZhd-RmSTJp0?tbV$4@gRv9!V2#y3ssrZW+1>3SgtbF{}vG~QtS5*)3{ zmeDO~XB~;=M^&Ae1*8VIQHa4^*|oR>7X@Q>sM^WlaR#@OKrwQl&s>wk>SPxreJ-!? z@muuZyH_F0sL^V&G>QD`WNCtuy6eMZcbCc1nGB26Eij-m%@Epxb;I;ibMI<21IF(} z71QWx6HzY64M}5_<4>jJ-U>}+*gCf?&&pUZp?9T_=JzW|U#(^X!mv$5#N4fdo42!+ zlTPhwzm2=1w((I_oQBbNr5(WV?>S%iDurtg*|dkD7WtO$!um!zcJdo8GK0qP66H5j z9(yMIk}EH)l|J$+<-cL|zZiaq@-hx)fCDoQroPb`2VGAbAyMeIidcL`S{l@&vK&EF zM9y7?iGYJ>>S_mx%Fjp^Iq%PVa5aL4K_>99Um*_&;*YDt1Bm{acDnqbKzf`u5y-x z-J#NHCPNveb!*RavO`}YI}UaRLYtFCIz&-6pN1j}1LfHbLazt^~FkKyUOJ zrIKTkJ7=Iv+Wb`ow2{#;Ut13vX(4>(T z)~d~fO2a^gg0@7NygWerU?luF`#>;gEX6`W-M^+l4-iPuqOKP33g;YT#P11>qdN4B zkuEkyq?l$=hf!3ka*YG3X^zx==?o!)5BKad)NDj^%c;qfw_^&vGYXCfPdHRgec1g( z*<|n%z%qlnyQY+_?`Z@=RPczw9n^k@5;1S9Is86}1{ zeC2V+$?B7dEhzB}-?U+jIoL^h59%i9L3Pu>`@#AhA*>ROO-eNpORB_*ePU*bi3d{k zv{W;G2=G9>gkuLB9Lgm8PD?Is|s|G(CKt5+lg7c!sa3c zYrYR_{+?!n8>EWf#`YlS@Q_U7mJHG3ZCj)(h@U%_(IMX{W?QJ*zw@eA zz@ti|nTxcnMtrzxJwtn?wNW||mQ`zoeN)~aT`?a=ziwzpFSvMkr(fTFjw3P~>1bXJ z1)QezpzaiVuzSz+sy-E&NS#8j#z8^tD`$%;Mw)`#c#{KBR!+gCAj^auQ%OV^jvQVv zk-e|(4C?-w_9S`?zZDa1^i2g5IdWETL&P~kt<$fh{85~CCqp4Y%nL<2R^n;r-9APtWDhH2Mr5DQ)#UGw> z8*Pw{K7;w);WD+nFOGsq97*T1zYJ*>tuP829S zn{SOXF}{hTto_wwu_HZ_pqv~QIQk@_)|fP**q^9agf;Z;xAh*>eZzlkmar27wKw>p zg3ziq%^#s%xUf_MOM==7@CeEeV*nZ^y=KWPV#ZOtW~WD$u2GZJiCK8yJ6 z)$#mzMD5$0TG##?W`!*Yf{Hh`f3NgWz!Ay>qOhxGkvPorix;GW_i%d2zO&k*dB?Y9 zf@w^9x8NDy!me2&ru~c-Klp`v7xc!W)lJmpOh7uh$?k&ExXALwT3C(yyD9R2KQyxc z+nq-OqtBH!^+>%V>X}^r^v&es;{8QuUKu zxsRL{jjXhV6og1V&m$%xh;=8P(n#=o?h>+WUMd=Fh|w5PnxjnK95M03=qLQR=`+V! z&Pi9Nw!oitfu|~FlIO=oJ!yz|4o|XUhrD>t@39HabMAe%YVwVmD?=X5YsHfWuV$W)5k`-O^XpgRWrmxSRCb0bUb(!z!%&3HMtLx^gdLY9OJm|m` zY|+&9f5qRu&-|>~-wokDf2!!Qb{CI|QN8ESplfZQB2u0v-11T%t~PDqjPVFpH)u#0 zBP+#lckuov`?_D7`K)854Q~cb03;@nK68C?{_a)e8P$5S+poX7n~y7S?d{s-BT}0r zknjWpb;f$kl&`5poX*CNlo+OjAG%*8=nU={l|kJh0@4F6yVfSe_`NGw#mHVK;#At< zj_Un_wx(rOZ}1qFY=B5L*(i8oL8|_li>*Gq;Fo1~b$;zzOVx_Y2$6{_{%y@))l2W$ zcKQdx6;6aDH|v`=l7G8+aM`^bxmGLYfBW-qbKXo#;wAHMmyQE4ZSB(NTjb@TBv`P? zCs}_M4C-mNc!sD{P%|sf6v9mL6eS27tURMySz*qkp5(yCC)4+?b8H{1q=x;kH^=%mSGnH27X5nNDHU=EQn*U*5NEdrm6c490-ZD( z^4ix8WKegiiaJfo)X905HA!;x>`*3h#~{1a&B`E$GLb}cDx$~NwG zbQY0T__B%o%C)hty{XJ-}-8p<7IMq+ZIuMtV>n92nL>e{EcPEV`Xa0=j@m$EI6exguL8p60q~^t#DSl`2kP{6AOe#Ae?sU}8aOj>g+eVrr z(CGM{NX~W8qe?Gv)#|9q{sBL6v>r6FKXiZd+w%HyZ{@&he!FmzsI+c@9&wj~+JE5v zFQ;>-KCmz5D(w>uOb6KclXdQat}pLnpMbAQ9(vy!gss}k^#G4x0S6K9wQh8v$bIeHM@nf(o>ddVkyU) zz-Umnm8F;Z@IUV@6ROk9uY0ttng4_p=ZK&Gg!N`QWh>U3IrOvrwo;L+Qy3NzrZ(Bn z^*5G!1 z!)GccsQrrNdOhsptDs}Qx+^|6O5=MY#}PHNqXh5mG75XF*c1y>3qb$y19iCj*@*xG@>YR1@+TRI-HvPcUu2@F>1 z5l4yP`K^v=)VlQv0BPR)$_W}tKkv0(F;8y=Q4jiza>s0G?bSOaBFI@Q;^9j-I39Mq zpy03hpHYbp+JDtG+yi$vAE)>PV!rmLk0XETw)Tx`Sr~{U+R*VLh`QZ+#3PCCkM}== zJ{ArtTzKnDaX7onSuj=Ww|{=Q zxr7UgmO01BJ;tul9K&FAR>>!2B8%utBPF^trZFPsW!Ox2SFh;HXj$&rKktK0u1 z2lH#=U(U0l>;20aLX^K(ss$RB*rb27lV{I^elGm?6?0*cZO(cyUh!qclQiKS$?@#M zsr>Y~JR$y+DliI(L$J%sdM^07a$}gTZwO{S+7GVW-b(GN85p`CWT<-9OXO4A*)F9&5c*nFS@~STr zJ~ShGw|td@US<$9^@_=O$AivO)=iC(qbV|e-NCcMWtA3-oX!>eM$AZl73KF;ars5AgoS z>R2A zRTY}|fukH{>NCxK`}7{vt=5BvO!Zoo1b_LWs?;*Ay>7h##lDnivQw4BVpsk2PU-Ki zEz_i%`ku74JoVM+8~y(APH9^YvH5TDf9{ViZn0w_7t%+?InU)aQX&6?AZE8aHdZi1E<8yF!_T`;jI{OhGYY^s1b@>_Qq&f`gOWJ9{h zT{nM^b@xhYqE{}!Id~UA9Qjq_IDRqjPf(RV=rz;N+iHcuy3Kl&N4EB7y#KNK*}#qv zB@$7E)lyM|STO_nFVh{)ba66p9$jYxt1R#i%0_V>wl3$kXzJ`Aji58igLiZAPKHCM z2HDm8$mqO3Q)}tP!I;tcf+OPb+ZynIHe~aM0rwvY#JU zYvHQcX0uUaWP%YRyIVA>)nr$ptt!|+!6L!gm#N7Jn-Ui?T5Za0v}Z(2w$Yx@>S*uI zmHTRAH^qPEu(C85DYhAlyAn79*%7#J){KXl){tla>DG*Cf9APH)C1Rlq^l=wN1qTSy(XPn#eJuv%BM;mR&fQEjvx3v zSc}iw?LNd#q*7X#D6QYaJ}$vuwU4Xf>MqXP9i{V@?1;<(owu7#4J8+~GXoGbtJ3V1 z=4?I2#`XGU8|lG8ZGoRdy)6U^_O7LZz1hNjDyFg4rKi0d(9uV9IXcnZC5k@p;UGRc zn4`dv9XFb%)gAC+N76@&Ddl@l&8p@cy{AMLk)M_Ko&LQ~Pu_?8d%u5w&cAQtIdBfA z{3KpZH@*@b(yxmVO+xsix^)~*=Y5=M5?Ku#c;zfE)t^q?XJS+bO(v(_$JK@Cb5VlW z#YBR}9LYv7vcc)SD9Uc2>l%p2;t40~JIF-jq1Xd`z)`!w;S;%5b;*0cqH@)3j<#-F z56f;oSjWn)&JyF9D9MDdFt1r0W22G_sfTveU(VcBlQYw7vQd^mB+Hs7y;W%%LY=!P zd|_pMg1U*P?#puyCAmhsoEWf_Tnf^`%cZaDT2zcGOg320DYP&yV--ki*ZVmcu{-*$>)O`QsYGV`tuajDLeUF52Z zF1dp)%6EzWk~ZV>V`m&>oTjw!-=8o}6HHZ{1|QpjY6M^Qv%PQbN!irB^Jt#4{r#n- z%PX1js}=Xz4J=-u%j~{|1Fog(ajo2Qcwea{ncJZ=OhH{e2NdT9w+I0u=fY~Pxl62$ zZne{C}@nEc}V{0Lw zfX9gp;R?<*gcA1)NO9=xqlJp&*I-=#L_aChICOlFL$3!6JJi#pcp|oIo$dEGD;l11Y>8Yov4q{Se|!;=M~mGSOE>^Dv7HP{#crVXv10# z@D%?zX4*UdAH`WCGt;|Zra@z-7j#?Xh|FaBi$}4&+m0RY1tZ`j!J)-Rj>;#th_im} zIP2H5j}d46C~7W_Hxv08Df8^+YlM!5Mne)&hBmh%j-b~bQZtP^D=2pvDO`@%l3ejz zq-gVro%!HA3wiD%*CAHK71ryH6DoI|XUAK&>VqKMu=@iBVYunyEf6C?XAAaVOgvI? zhi0Wcc)q(!6O-dkCfN4@0D-bHI^dcY$BM@SVffGA18T0k z_9o%fm2kxW}bBlyHfYf8QTw)Xye^Nz$6B+jZC!Kl%Z!Nv_e%w^cz< zx762T(3v=^y}qiceX#F5N2*?A>%@eg9;%H?XrrV{#umId%H22)hU&#K$(Ftdxw*o2 zs1PplrbUoxU=}lGO_+ERt7k1+C@W8#8g^e@)irfB0Bg5=3<>9q-5iZSW3Zg3rX;d& z{B+7)TDOpd=sep7eX)!LJ0wc16ej!b8sXBque>s&Mwiy@>b>|70v2|-;lHo&4;wWL9eu|^q9Vtc%7H;+pWkf3{m! znrYm0YOIi+=UsT#v{`tyQ)7P(F_dOQt7ZME+wBBGmu=ouLx{VgYpojW(_Hz&zOR~iPVZy5qn=3VgDDN!^U ze02&RSmD8Z;W7E&)maWp_te;2xJ&g5egd%?!7u!Si>fYFt)^zBBY68gv_*&$S*}Amtxp?d24syy={~q{WJI> zlQSCr{ak)`qzps5{EkJV+QAv{!U5cYCm@7k69@hdJOdPwG)w*4?;Uv74L|bxy93Y2 zPIus){h1eLpl$66ydE{lq|ecxzpaONM`Y2=e4w#{UjXocdAAbV|WaP+4cP8pe z*3wZ}RAqY}{hlB}`sGE8rB^4PwK@@Ri;CI(cvbh}c{igq-ez~>=|)8E!V}YrKv+BE z9-Swl6WxP%H~)2REGrd}An@l3+npihvxz%ITOiNq53h+R#a)jVU7TkWNeM?T{^A2R z0_&@ll-9+0d}vhTFU}*!37^vsdu|4|;-RM?y+in&DVVxCfhk*thCMwYkA|O3teP9Q zn`(;g$cuzg%H|@HMc4-BJ1mVPiEw*3nCfoW?I>a&VWc$=s4mu0qS8O3AgcZEn2;hl z6lp4LXV(yz7_!?}H*jn}hq``~M{HtO-baOye=qkVxdpB(^M!Tq$rZNd7CaT*P&HWt z%T+*JzSOGQsr1e@G`+e!SZ7x((k;yqKm054i{p>r=?Go@?GN}yr*R;N>= zlfeW01~54m({~8IfukLLkO)hWh~zaykcT)%U}uf_86-679UI)b{7QX#zzfBaMHO4r$HyZ0de0)hZ8&2cF*fYW!3 zR?4;fjQtN3mMxsVV~nyc<|o&qa7%o$WtBR*=x;dgjlek2)OE&q^=Ry#oil1u8@L4p zD{GN=Zr@>Z-F$Gfzl0}`f6%TPV=dCKf)1Ex0j?&;bUu_G1)%HlyqzYl|tNXOV0Z93|(5bcQ|o zHpjO>zzkX*T@tX~xD_p$6&q|Bz7tiHHS$eoI0&26af3yTsgr`TUTzip09(uT7!=Uw zj7|b*;lj?kyPpw9UoPjS+*pNYqc*}4D6a1OS1Egdou5t7{dK;oPdP2!^c#ZAYRT$m z8@*RzK`<@!Wz0+B?A33du6wOKf}<0ObO@l~l)K~*isGo^A@nz$%yV~)LkFiDygNAU zP`#?DcLigP!YMZIIQiPYaL-udAzl5LzQb<+z6(;!7T+Wbw(BLX|FB{|p;#tWn%6Gi zdZ>lRooeie;^?fH6Ph6j60DzbX%@)Qbpq@(#&d zNf9K2y%{ArDrmC74<~*+Ra5!|u&_Qy&or*G5qo&@k=h>ke55bkv^1z4M~(82?;tn) z@ax|0Zg!!molnoGxi;CbGrWvMykE7WD5d->eW>aI<`WnJp(rf+)Zc68@@^jW-%I0{VR^vr1vI%0iZM-0ZOwEDIVnC3?A5CIl$E< zk~5$f04_2Cu3b-+;WBfoK3w?;4_C-ng6oq<4}SCbdBKb@vk6TJvo;n>uLe zdYaR*LqT=W%$AU8@0jV6fdC7MiFT@K4a zBR%$wF{xW_fLX%~M@6h1_bHrcpwF zXPZn2AsUtsI26gYFo0uO6io=q9Rs7E^TqKON{~eYj2{i*D~;-0Hb+2_hC-IF39;$= z!9?bKeal95UqzF^(4AG3o#to>*Qx4Nw`{nabVN3TC$(@fhs9tYnyH4HTQD1TKnKzM(~IwOVc7*Qvef@Q450-t?n!pNo>@XDirpUylv- zIC3I+Y8+nX%x4{EN}0mVJrIesKI)SrUhL(;@Vlo%ON)##p~7+d&E95Kzk|zHjc;aRWGk~i-fcWf)$@*x{H1OYDYu}9 z`v?2mcgoq7cv8DY?u&$ub#j8f3+hg+>T6JYtcP+sV!ncS_;4D=Ts*oM$c%&=;^#O`$IUaA zy!b3yWi$qcv`XneBg&CNLaov2ryqAnaC{ro&D48PyF?G@CB}Hn#W7#UV=!E+wbOjI zc#wSYOFm8eZee2n)tTaP@U>%VTtZklnZh=P#-Kx=#$C{oxD2(q^rapXrJ$&~anvUxiS;wC^5>gWmRha7{M!lH(*7b>s z#Qz>DNg*eI#*h;Jt6CU?W{X>(>~9`1N_|WZ>i~*Nb?LiG%8db;qM1UuX2p#fL5^70RgtG55P_Uu)%HIgHw9pcNP91 z7w>7op4_c%4xrCHwNSXl>o;Uich|218P!)UIE{x=wBEXdcQ}*a)^zWfNxW#;Yn06r z--K09^yH{BpXRkG`EP3(&Y3EaJ(JsKUfPrFTumjJ;u*!m(y2{cWk+w7El}WC6FwI8a1wCV_>5_gmvRL(L`KL?e z^}K?oa3+VJ z;3qOX@oQLT<J~N-~@md6*F_NTr%N=~SP>Qtq(ZtRV@m&U}cVMIpF&Y&I1p7yUDi zx)S&PMfUW*`0pcA`0wFajejH4()UO&+hf8v=-z97ic%3I*-)i_A*_H&7~@tFOPkEy z(PTs-hv4mF$S>)7ROX%qZgE(#wRAc)L;5Vc@6M*~PcG@84jsLzVSbL^a+r3$pC2-! zn9SkHk9;h5n8N|eohggI2u6Jw%>dp#&c9?PU8mRaRM`0#?RTv=u$@hIhxr!qpHnj@ zjvaZhkZ>O$iS2?fTJdD(og@gs@~-59_co;Z#FstEMK34;cxr%;ofX_Gsuc@n`HDGV z>gJp*@})3PrZP7+Ujan?@CR;5Y1=A-konTpgb;u zX$_@MfMLg9;4`jGa0@(w)3?hZyhgn&)v4?mQGF5GO5Kj$jmtm9Z(-vfd1}C=Om81Y zhf7~!ECt&*>or%0tIKoEasp=bera3O%`S^2f4EY>f zDr>RD7}mLCLEooaoJ-vW{4ifo^hxYd-?801c}fdAZZo-|)~e)&^M{*69{4#65Sd~N zBDinv(Y*&TFg_UnKfSywa+UGp^Bc0M9rM)s^(S_%x2XB#B@bfK)%PA0?+hsYBOg2W z`AXxK5AvSjyYbGPS!pA15s3=bnnF*r$rU?_ct9VWHxbD-oA%}WTxq_~*YgYcShI7Qma#;l}Z{?TW1<$q z^@0K1IjP>iG=%L}Ap?3CPvy-dPCMIZF3E-9ve1`l?1|d=vQ?WNEH`stEi~#@I88M3 zsI1^`SY0h?Aw-j&aA-O`D`r{aKO)L!x8bY~EPg}5`A(651ULuN}9telA9I@?*989jH> ztaERi)WN68uD@mYwFN|y4$RR@J`_IFse|X`Fbk57mO5iv(mDM#rR}h5S)LTOWeeNS z+>&YBksjQh9(-2V4ZaB>7%m2G7Br$J6abMM&sva-!l2<{VMtyX8`WU!We>=xtw4Y% z#RN%?;Bx%3Nkr#N)55tRa}XWA)e&GYhG5lOV=`^ZwYh!>yY&=ZXM;02{M>A<4jfTB znT}V;oAi}V(v(*gb9OELmiuSaU|(*Ood4WY5`gMUH&2<8t?HAB1g$g*hqf-bTz#V0 zEo8@WdrIh0LPOZnUA@An%9()D6!BE)!c*aCaRJ=Q=~YjiVvUa;@fzRq7D_b0esC5OfE=EOL zAyqK=iq#tRlPTNYm4}h!Y*gllQBEw%OD}?qNMDxoA^W{fPCqzeK2x>5E9I~#-8N!= zS?=pj`lx<^Dq>MYqG1X6)xmia%PsF#&9$oegM7(cz%)LX*rHp#sX)Y~Z^og-3ojjM z1{4cFZ+=!HOSQtde{HK`7f=Dt1Dn4P`?#Hn!B**lQ%G0gITR*8QyirtEv`s@D;KpV z7bj3sW-ARbSIV{BY71LFj_d_)6@|H|IwmvRw%3=y~K6~S) zbmN9Xh>ibJVJ(6^q&xv+K(hEvf}ru9$Wl4kjg`mlel>yie=-;u6N zj=TqpjTKSkq$mtsa1I=4{N8Cqg~>!0(hHtRpb9ltn&S0fA0<%^cQ+>Td{-{wzkxxh}*d+4a2fmlHMGN~0ka0*F6R{n0#( z_O8)8H5e%x@scTYTB^~Za2@x~4UX?ox6d(hTjpO3N(Z{1nTRS>!Q@Ip97cSfz&=p6 zKtOyY= zK6v9zWVIyNwj0TdTPO91XoJ&>72r$=MK-4po-aJ3s!XULF+|h@Nuw_@2m27b z$TI=a*oTbREYBjVH#q$@FHvP_9e|Md^$0>@UpewB!eVAl(x+0g{|WMf2=nVE&C(y_ z#y$eWLWN#UU_AOs2@Drpi9f^yhQ}coQ)fk#Vl`ZQ8v4}4)ZpS`(OGH>RRxZyIVz*EsS=cAAYZQ*7r5OlE}oee zCxNb(fW6U%nTf<(h1w~CzQfmApAF_S>v7ueqqN)7W;4eIHdeAr)0q|*1(%<1R=x?c zV8Z>%SZXyOg5icU4PfT3;eRo^DNV(~TAFJET)O7%l83NMwl^2Hb60X6HWC?|M0g|S zh&(GN$UZ4NoMn|Y_$;bvbGmUok<5sI7qLe?<8ie*hRHc<*-O84<5tn5q=N=T-$tu< z!qZZkA=y}^L(ev@QxFc9-X5_54>DZj64Y&5?@CpSnH#FrK4X}!IE9&& zU=iaEGgMXyp^bNQWI~ondA{xLY~$+W!r$OAWg*Ng6()_`yPjO~BR+0vdr2Yo@hLEk z>#&YmtWm#t09FvB(8SylM7Dx zT_1h*7E5HvKzT_h&q*?(jJbU89d}Z$LOwZrMxE{hoHVvoWY<6#o6M4tj2g*;sgz8j z9*yf9&HkxO1MVjNE%Bopp;}7|KxfhfMwO`~BaY(FmVMdvlI^j5vheU||>A{C^56Nr}*0Ww;%Hv$aet0_B`5eC_EuP{D*=nR2TTy$t zUr|@gjQH}pea(nysAsA-*89I?r;%7?Gh%S<4EExFA|WPG;8gepJZJ)I7z1Y;*A>TQ z@TS7L*}|@LVtwPLKi*J;Zi+h{TvU7F92$ zrT8maN6Kv-&cBxgv$qdLQm@RRr{^gT8$Xm+=(^kOlr8)w$BnJp@-tJT5a}qo*rP^h zQ`{~Vo<%=~bHh8JytyG(mbrnEBj7r$em9aZ?}$uY zJvZ5G%q&tj>h3o3sZh+$B)fJQH#-CibHZ%4@SNOfB9hd>EN0@0FbS)AlPk7WD!WJl#w;Jy{>vI*shnUj zUL91WDjWyQl>%hDhQT=(1;~qyTyXhGu>{7NvMa4!DH$l3fUPQO;*u8-dWSbXbTR@j z8g@*NQ>+wCW`ntt5?C2BFd&Butny`Q)>ppNKyZe|1FMBYMVnKTh&LB-tEdn;r5dZj z*jub9B2pP@RHazo_$UJ8X9@(t`(1dz@yf3U2c_wPW0;tf?qoW}{CH&f^AY5av&BmX zdzn*s(rZh3S;cfg5!=rP=}%|q-1>vS=mU)2nqBf55f@)mYJ5tg=G=jilc#vpK5oI% z;{#OqUgr;ODct3@3S7Zzit|jpH&;Lr)@@kDu4dNW*)gZJ8PjkyD)A;)Xg4huCx$bM z!yTQP>@MM3ZB>5PKDly(e%x|-CcFMVNccqqB*%@hhKJTX0v(DF;U z?5A^*7V!`P%XpaFzMdai2p1*mlX{-0XD<6geW%?<>*68ugwA1l*!~G2Pi1?n-Jx=| z$0s)3-BVsLy5#H59okI+PHqw^suqqIU-?5{FXd<*_Sn%@R*(a7;DEmD>8Phjw60v7Pby4g-3LH0%npQMbRad3X%I-0FnTvw~hUmGw@jyDmoa&r1(l0}rOm-_IbX^sMX=O>pw3l&u8GiuGfI=n9IlL}2X zckr~|)ILX$w0fu!er2c;%$*k1>iR=j>)|vHmUSxUU#3@fVVa=E$LW}Jg#LW?HweR1 zjjSDmiXudZFlv9cc=)8^A!&C2ROvkucwRnTA!#HrBpI|&eF4Dnf&i$8c#q7*OR1!3tjZjZ-^#I2icLLe;!XSc!eN`JMD`jib;9TaYjsC1!phWOlpC3 zw{&6inLSv5vw25n_Id6K=8P3JjqAjARF;a$gTCZ#yioi)61dAFHrmZBa4hA zF$?p@LBxv`Kbju<$4{w8k=(r+7S6-CaFakY$0MbSjZt)M8)vd+E!W za9V`B&SHgNV1Pmo6)2-gb(eksOV{UkM#GW5O~Em}H3}RmX^NLg4I~#|#@q0IBs^(^x5R*B;eERXu|TU4U> zpQQW{8c>2?W-Ioh$&h5EKg33E#CvV^4!?L5XO)436=zktjkU&U%SMi~Dvv#c z;FamX?ZfMbV9Aq~8u(gSenq6pSZ*^~EnQM2-)vbKGA(H7iX#};^I-jRRY`llq)#EQ zB_E~(();R2ws;t&l3kOGO4*$Jb`mWLhUkbm!YEn@&#;PaAx2RNMG7^I6GvGJp*loW z5Mrb{JMX3oKADpUzG%TWlpiG`e$3O}qJN^07_RdkQdDXu3AqKU8=%bDwK1QL2CN8i z`M~08Yzq;QHV9BL=nj2XF;$n?7Qvui%5gUJ;gdIOEER}op-@Pj*mbMsU#eVyC@;6)Owl+X>FYl+`%-D)GhZ|Y+sCd{4OHOG z$U7|Veg4_`!Y1}cj_F$8{$|;?*pTzy3V#@{Bdi}$+|XJ2G&Uy(KDSiw^wtG2m6#V2 z0G2hbbZgyLlag9D?Wqd|=Y+ z_*G3`QNWudE9`=0$x#BGM^jGJc^FTz2CB2~dSbaaMN7wbi|`3~?{uMG5|QGGdf`3d z0U=*6lT~c8e`yFG{0e!~! zw(&09Ep)_urHwn&gU_W4t23#GlS^by2omc++Y2pioH^;qk*Bmkj`bBNQxwWneJ2y& z9r|FYAPF*)nE<=^nJDTBKj%6{KwGSn#Snvm4lC`pbNaxh$T*!dFwW*L2NMyk=qB77 zL^tV>3O`6f@^r1w@T`h%vT+(Yx=Ev^nViTUWx4oAQFIey@0}fP$cb&rDUeyiRUaO7 zJjE@#iNlHbG}$!+Dw0qaCcrMp04hy^6y0hXw3Mj92O3tV(lfFvsH%oZL!a|;1Y zc(|Btdz=T0pdmxdz>g4CZax)t7JWrH=!0}W@57I*``Qnxu?PEptbo^~mm^lzvqW1B z>P9Yjmko*`*oQkYQZCZT$k|6aMMQ71&c+jCqy8fHh_MPW_I*E;eL_qWRZb3{dY$#Z zbSU_cNYi;`y>4)ZZL~D4&|>f8*v6}ieezCFQ(HGtSi8{GfY}KDYG1S8S;ebm^x>*73W-WOz?2qV zyd*k>!8u+KZcZCZvf&gE{;He;azr@r6q)7Wk(;0}!Qs)h&UktG-jTIa&gOhFTRa{Y z!9(tF>d2wv0;PTo`6nFF7zYw6-hLAuF}+^50fhNM=?^jC{Zy||5nxU@>G2k zKxk+kNM$|oB%Dyz*De>v@$pf2nXE1Ihs!Vf3vM1UKh{bm@ma)Qf?b3qOV0o=2S>ST z%T9tT_)J@@LmSR57>1mL&A|b}M(QYnqxL2XwS=b0Qn`q-BgH{o9HmRSFV&X{f+`+t zp;Gy+X?Ab~Q^!CyiW$%HBZ`B{1sJS=!+tyh*8)O$4N<=LH4rw-@#9HPgp3&OQ}GmQ&zzOcmuTd z*KMcNbltxw z9ie9SuISk$9199_eTJEP9X_Kz{MZ{PLfslhzbdKB{f1B7vu|+3&8n>JA$KI?{TzX} zOUn+;3@ysj!R%KY{5V&wS+fL!JU#1Ipb1$0U6p(&#Io|Z_U0L!y*zvKP|&_t3!R;l zBvA5&!Ir`vO84_sbK%znP<(}gYS4AfJMx*{^iX`DHtJ&W2n(<(FGMo#$}<8{IGxio ziiwRByAV$ue)+;$C&`EyJV&8b2ChP@T!-h%|L(n3Ho{d4-hXHfW4Zdyv>7+mEd6PX z)OxpNIRE?d@41m~68!N5Ge}8mHk2>dpr|FCzWQVtDFzoyrsWR7eerr?RC`3#n2(m6k#em#p>? zmn?-6aoJ8%zKx~O^+Z*<-Fw`(0>_D;BPK^oa+p}eYPZ_dUMH1{2xYZ)7?L0 zebA>5E5=Tcmq((K#K=HTDJo0qe|2Q%n2m#RG&Z5|tg4ZUM@dw!muXezk}RZLrBTFC zC{p|GE<~pA-Y+(L|sh~P9R=0kDp9%>lyJ(d~Yi&#y?sCyu z8`)2lT&Sap%F$ZSS+rJ(N?O{ULpVip3-p+U#98vs@_$1vmP01LOjaSgBnFX4&d7)t z`;S3{-ReY`7k>)|n9QDb|3$%B&+|o1;~H5|J^WHZv1AMW4R141tp*#h_OWlt$$s{= zJTS$Muv#6rIAPn&IiR#|9HrAEgR{@q7u*(8cq&I^NZFc-!cUF1IF}P~C<|%|6aBj+ zyBg&GalNRPh~8IJAr2MWWfIYuP?1;^ZA{mIm^kD)%LwL=5R07AR3Qz`q^c5$GOr{O z*?6VKn$%d#!QrJ7p##h)Q%s0MAvbgGO@_*3*KXutBnS1K@SrY>dSt8wb%}3E%F$0! zzQ^g&J{jZo+fA>v{mA~Wg2l@Ll7$y70cQq)!>u%<`OEpaa{77CPRXWe$ zQ^}$?@hnGsso&+^MmCv6d%fIUZR7~oWhC&@DvXHc;vsi5Sz%I|{r6f}l`hcBWL{AB zK_HVjgh8I7m*LcJl#QDaM1T((pH9&DgBCQtUP0sEA1(Ix@m{+Nt1aT|ha~3P1~}%F zps&alK?JN7o9?77L;!mvoRO|AL8215j7?E+f{`#jB*H;58wC>GRW@_h@HwZ_Wk$!Q zO+Gkl%|-rX@v=z+T2+VWlP7a07VfV5x|lyRG2t%d;=;f+2=L&9D@eyCYcBjQQ_$@# zJM^WOAc8`4P*T8*s?%_%i-!{_;%e8cyqtt~n$He{C=vksvx;VDrd1&ZA{ii270CcU z>}4^4xpjb6ku5$}vcDNg`>}|w{F>v0;bC4&vB6&rKJPd-n2LkWR!>XKi1x_8 zCO|b#mGNSS1CV?#mOe^QmF{}duZTtQ7yFM7d+DnO5+9cN&~T@);=_Kyw~7yY(>}R! z8GqAqd&6J?PL&efW_tI~6~j6qX=fH9pLi>V!!tRE@Wm ztHd4EcBP&8VOs>|2=%Sj7GZJvs=;2oR92fK1c)KPJE)XQgVDrt&VOgYVo`sljnJQq zpFsGXYU>cy@nOjoSFob7|M)OFIb;gWC<1Jmo|qRa)vOnJY(dW<6&6|&TaI{gETiJa zr2NgM;pyVW@@*&P+m2=tV$OV7DfUg_?jpy1&$&hk`a`lbGT)+PQV((dh(%%<6r~S?RTqJ?l4*BM>Ak#jM#*>=wBc6z zFC;BpD-ch|3>-vr4=sq8o>@VP_o^Rs`O$ZEkpNu9Dw*Z|&Bzk!IW7c}@3ev&d zx-w)LVC;Io5KL2?CKIGpu4*Fh1s_z^8`#7HY!ceyGTec3!WZl6B+Cp%RkB4Em zQU(J`UDizrf>W*~fvyPq9hUB5>UGe4=LF=G2v8Kn$xiM{5>bygG;J)$XB+J{67C>@ zp6*F=lu6^NY~n@QS4Z9%Tz=?Yi*U`Jxt=t2Hk<05cW5KmlniBqyj%tT-cYtm+j*Bn z5P9sF+~B2;uWTYKRUcV8P5N*-IcB#3ybi7wa_w?3$(K`k(PgLtqt=JE(f{yQ} zt6UG6a(d2DirI0Z89VMsDU+=(U#2X7$I+CK*`zY{;U}9BT8}7-sPg^-9cEO%tw7Lm zdL9Gw(WZQ%r6E^n8P6d{ZR64egyaj^dXBE0u84XSq}Ev!MnGOM(T=YJ0;y+RftsCI z#CJC5eYxVi`jpO-BV6=Bf{;>MKk>KeVKPYc9)}tg{>5aF(!$PJ&Qvj|f)Di}h|*W5 zuStI({lRP2Pzz-10+t3=^2Uo_oc=EBvL<1$5+1}_op%J;@lx(UF_U7UXYMgN&TebeaAm*EE&G$;A1$e5$h^s*AGPtaP1Ab1?$EsZ=3SinY`e4_S&P@;A5k7 zD9v-0<=4D;*BnQu26yw!7k05krwTM>t>MRK4r-Ka!GwbW>W~$K2|QoSY-m z=?*BIfb*~RsHJkO5e4hK^0AO%k=MkIB#W@z3|v9&Q%f{%j%_9T#iQX#zxx(jJseL0 zRc@TR#ueSyCf~bR>B}etlmR`sqO8yaT`HETm{7iqwo(TE;cP1 z8bgZktjys)eZAL_>Pnlx9V!{@YW=EYbJ_?0Q#>9L9 z;SjuI^J1{mHdiu0Te6X10(~6+O>JcBMf$5K#MLJZ&mD#t?w4U6UJ={|#ya>U7o4@0 z2hTAV=D4gQA6(A;w80190WHdsk_$3x_&8D++j4>PANd7a7hrEkOfym|ttzjgsbOY} zB7Z&HFEoXW=9@&%jz3hM6ZPNbY#PjX5SQXBZFZ45&52#97u%o71pl~~IS5A>r0zo* zZfe|`YulO$E=ptwZGeQt0NKED#f@M5&cGk88+N6#Ia#W9r;!h97uZyLD1Q45f9R^Nie9kgDepzOv<_b$rbnJMk{VkH>~0; z3dVkBkvPv5&L*6cPdt`e&}&=so45|1E%y#6pq}usTt0oiHWLC39^Oa8_9sQv*@@h{ zZb!&DWC$q&JX3I%k#0PaUUTrCsyD-l%y1J0!Gsgpqyr%e++gh8MS*6HYY&EE{va@E zX8st8Oy-E+>ceMB2E{bDo*uQ1bXlT`qLD%4FZLDtT0o3)kRDdW1)+=;k^1bub-j zeKe2y;?ev?AiSY;4-T89plG~>-AOi3UJrER;%WGVWczpUE*-ca9K~6n1j3`+SU7nv z41N80mSAl0Bp+Njln>f=GGEZ)r^!y;*o8~?;$XrA-BKMKPS8%j>91N8agfmrQb?AA&B!&k*UY|mh0P3P>BweIQOvm^}VBI;oWY>pgn-i*gIMV-t8

XEd5T)qPDPi;YCa(ev+TtjcbR1^!2WEuf~F^0}x)X_7_U$&tB9zth))&eaTN40q9u zx8ppINwtm&*&85_R+AL3^Xa)<^S?R|ugR0~pbCj1FZS#RF3}9+O0nI(;{R%!=8D07$UFDM_wnpFXwo2wN;R(&IkW>Flt|7wa zX#N7O^yC_T1FHl>EQ1>O*rY0Jf-$_OoeSzU<0XrG$y9G~k&R$Wt8DB5_SK1!Oswqc zl-ogE%Su?+TWVCqOK2BfO}p2b-Dw->0UCAM(kNJGSpE%OZss$ywoAB}hGI2C`)c_r zCUroMlR^0}#!=CYenBL{2p*t&akv<2#rYA)YV%_G;$Gmy$4THONo4}(AeH*jUy#a) zpK(%ooyAm=ou4F&gq4rtGr&Q$NLaZ-x9C%`7?N1Le2YA4dDHT$c@Imef- zH~TG^l*ls+CK zU^NKH;3w*ahQ-_N5VS-w6xxQyes z!U19?{iP`Ms<&}GA!~2RsPjIjXwk8S=-Y%4N9l0wnO0%cHk9!rl)Bbyc=>v3g|9+% zCf?;Hp~-v3@|RmSsn7HfftN3e-}e&e;3LBCitXcTbQ^Xz2o*$cFxMp>P~D3Z{HySW zXTeiPjcGi{3uE`-$3Fcpt-vy+b{)TbfcBV1C~HZSzgM3@8+;$ZO?ZpazowLo@dQ1Y zzfY~6Cpg5^kQAcH_eN*b-W)0d^5=0D@D``sO@mxdg#Z$smAT6NuWvtdN*k8q#J zd(k2!;mDBXNFir^|Cx#;6D88wPO4gox{m)02Jv zw0-x{D}S{tcwjk5IIRaB2BycOOMYA>cWwxr3LO9k_fbZwG6EL#!A?C>=b#sn0<6G3 zfcN;l8AfYBSJ`CRqt1KG+Na<>x@Rf=Wv(vWa%J!aBPcwTD&#t7#&=u3;ANDNFL*J( zQP=l~6M51@Er)J+c3Cukh&&+{08^}H-qlVY;Tb)5MR*9py;qQVUH&ZYB8W`NqnTij z4r+i|LGvs%mhX|_n1&SCh_|O=C$R9hMVH=3q0qZvSG-9G8m|iBSdHn^#TMRPTy4|A3zy@(~N2jj~@4{WFksPMR5@A;QO;Tim4cIX5LIH7_8s;&j$D zw2iq--6RdBnO}2PNWp7tfXBa06=D{F&cy6l|BttGfwQtI_y25}(NUT9kf5lclTyui zEV0xWFEv~D$R6CIn3zK$&N*aFC+$xL$|rT*8A=~19L)X4fn>gI@n zckeA(4JVG3{asfL)~uKGq!MqR1w6mY!I*r z*R`7Acv6qM(4dH}?DdKMP>ht4Noxl}5fDBs5UxStknjMCEe{mFO|${EObI7Ab4c3hh35NyUG(ww8G>BGp30!XU5C7XF>s28R$HIl;6O`9MbvSF4;p z$Z!!&hr`%gnwgG)*vhA`UFJZZDZ$j+?U{ESg3JA<#8UA!GV%C2lt7bZ78qxR`^dJ| z8XDJx|8}P$y)Wi-0%;`^ZI-=0Bf66BWEyR0FEK)~0U|k-TTcfWsjUqRgvu}Sy|kz@ zBQ$G15}@JE-#9Aq*ob%~0u2vV)rVAHP<1FjzTe49PCb%40d|hLV&v70WNtP{Gnl+{ z`i5)A2!(wo+#o7eOrk;xNa*@8RNbX#j(Cms8ON18>cyDQp zG|*`!HU!pxmGT;p+==Qr!+1N^NDzueCl>yfPf|GiQ`5fb_f*vckW1-z+o$zxpY%Ip zWR0f-L*AHvZ5oQiTO0mlvD>EM@SM+@QPm87L8<@Bk7(0XD3M1QgD)xnTXcqK4pdS{9y1(+X$g|!O)fA*^LW!7oG+gN>u{M|46jo zNba+_aW%d%H?zgY{A#{uBp+^pTq46zbmMGCSct{&w9v3cb_soi;)MPBQGj zO^L#Hu4?6VgRum03D4h^bR<%TOGLzZzI;ts!6x*7R_Qazb|ONa;S2q|`O{x`-0XM( z24&=WE0rF*g|&Uo;xrGdY0q-Dupa5vXL(b%7rwwo9obLdS689Vbm?|Thv9pG+KNiW zzkU*k1ZVvlKN1c??r`Hd`{w=iDl6cYK=jp%_3WSH{XhS?!o1Lsy;AM)JyxkTO|YOp zsHJEDA=2t12@%TyTStfx0A4(vubR-jB~IX3qrn(N02rXVTIM|b7vFj+f3X1vCDZwN zi9Bl)ihBtYd6*Ub2p_r~NEs!Fg&`-JgY-HKkvE%y?4b#gZ>>hSlpAoAl2tm*j;uUi_tzbUT{T8rJ5C7JIQjLJr#NviQh-viARv+1%HB1Oiw#r*9kMX znF2^mZGTbY6~80RIV;5vZ?-Uia!%Al&G5jf((zIkzZft!uu3u zxoO>T!rvfVJc=#yeY$uaE*6q~lhXx_!GHk?B4PH<@@3tH0x4K3AW7kn*rx#>l@f^=F+dawNgF}X)*>Ww==U7& zeDGR^XgwA}*3&*K2c$)~CYBEFc0hJ*0b3~@g&#V58i?*Gynl0y4~Ab&#rp{Dzs`!F z_-!;^Vx)+VLXs<3sl*V^=C7=k03P45t7-Cq_1lVZOO$<;vRL9z(mwG#8qwD-kv7oF zb6B4nVs+Jqajj+l;xY?srKXFwnZ$P3+!AuJ-3a_FTsb)&t;tdu4wQkmT ze80-RzsI%0E>Ldig!)3E=iQw~!Q#+1ev+NHZP-KVp!amBYvO~D`EH`@VvB+voWnv` zEf5fr&G!!44X6nR;tQE3U&zW*e`gw{D_)mF_t5M^xcl&T-f;m4V)WESnedA}hY&n? zAgCR2F2C5HncNFz3`yUzivem$i>{XQQ@=AATqtfO8d}O|!0#86vu+2!>s`oA^8B5Q zUS;`YiH7Y0tdhZ}adxuEqS_LL3m$j#jX5@KG@XK={u;5olcg1IQ8(R^M`2fyA2~Cu zqHsP8skNa$!|N^7fLOjn4<+Q-Izxp#$7_ITMhF%WlrbD_3FxI?HU-iho%tVBeBEk6 zsb-ixC4)SqQ9h@%vqHHT$8z;OD+=g@bJ5dMOf7BC4r zh{K!C_t7$=unorb7v2CfY3&Ij2{L->LjSmH;0`<&!X-OLf>Z$UNf%tW1>ymSTSYE~ zX9Rxz{N&@E)IP;!=q$7Y3mE=YK*l2Gew(G=qHyTmbBxcTvn z#YIumN41pD3dUwGuCC;Xx{*M?Zkl{J3Zg1Vvr##?hKoAf7G%&P!LegVeLTwq)t?!RzDI|8B*vb3NToih>E5tE29*J2M&W98k$K0{4rc9Ne zxnQ?(#v$kID)fP_O_Nzz`v+%_A>TuD+6;CdzjQ;>3|>XZ#Qu;Q7V;*WV^^y;#BBFT zHu&Iy>PhgvgZN>AV^@%x{o3;XW7yPQj%S<=DdN}+g#RxjlM z4zh%GFl*X5T!XZOqLrqK%&^oSUUust7Hm$fxN=zTR6px?%*<)mEzMcj5L;*Npvxtr zAn4yh`@g4=09MVZkc{pxbZnJ^W)^mWjAvBP){E z9fKCmE4ML5zM14n$>epFJWVN2`OFVSDgwKv4E-3FQBSh^;LNOU)WQicr6EmhS6DOc zB}N2Kxpq2F4)VOr(YD0K=c@JhnxVWLQyy_T-BiX!htn@T8C)z>73R=KX{?vB@bY)F zSL&wwiIwSOU(Kg^9O)C5uIBIB6!lJ1^rdiJ;z-l!|YPxZ;VypkPk?mMijfSGQe?i9+3GxMYfU)!zWwiif_0eIBX@3OI0NpRZFkJT{ZAu- zmhFE!nhPep+knD6u|@6#z0>Ze5nTM&yPtNdVe9{)TUQQ{pBMlh?hU&8%z z2H9tL0Hix?`>Rs?Kf%kmi%i%m`U6C(Ke#0-sUAjqVYOUfLAFEU9k72+&bqV5rXT&} zLPBvu#_$qtxZnpaqCi_vY$|n0H>C*0crd>BU@I?h3QWR;yYL13Od7G3YOyX*qb8&9 zI)tTd6z$xoNLi-yb#}fIS?S$_#f?m9?M7N;;!7NsvV21i7Oz0@D5v~5)q%dxv-5Qd z$Zcw1KA_%*LPM#t!U-5+5)E)5rzy9OsKBssW) z#5@NzTsir><`yCR8)vPsnUTAT!fUG;aO7C@%wKmYmcqK=m6&->LNf{FFUs$=xX z766_;dq6i3UQ^Wt^ziV|Nj`m#*nQ#OX~-hvUctDqZE!>E$>yux%}$TxtiRb~BIwrJ z#roto)^Gv7x{0LgxDK>0&bGr9BoS&KN?x~}^KuA}D(v7FKUOPXn8Lm`_U(FsriBeo z1E34i0yprhM7QHdW}0%VB0Z1~TO?;kr(NziMj?k3ZZW2<&p!3x2;8@qQ5C<_^_)0z zv-2t2fL_;&bJay51G%?S0u$?!a&Jx1R#>6CGUJic5+@)4ZWHLGFlP|qVw@@pu@n5{ z)F&M*05GSk!3Fj{O|CTXZ8p8&o_s97q)u&|&mV)vq46n$@a_CI=HD&N!}_T@aEQA> z(pJ0Pvl(deI;F)|Fs6p7_1C5RHc#G^MIn_Va2~g6yq&hP$;BM&7`Z@whvdDiRiQ!N zhhNgUS>33hbohcGI}Bgqm2H{HcnjS|y-Z?_bc+juiGS`xhg#Oq3TP&doFY}zAmO73 z%r`hTAZHfJBZph}=WdXo#l-Gi`1B7!@ zN*P|QJPe=wg@%3c6jTTSt4(ErquLPsaLj1r8nqyv=FkbSLUY(sw^j~PTBXZ=vUKVt zpi=*+OY?=Iy^a*z7t_7ZI9Kd+sn;5yP=lUd+`?1~`1D4PGHO6W;1kBkU4vnY?l|Ft z-NOKQE`8w>tD{D<=EeqjHs^X7cDUzHT10Y?E@FmyWiua)wfy%>sUw|O+dO$SeRx%U z$Tv@E*3l9}qB&0m=iuaR+QZzF4%NCTbVM(_v@JVmj%kqTI#XQRqN!u1TO*7Tn@BJ3 zqd0RHsli3`)zGFy!0I={7%bWZ0(vfIC$X4e zP=2E>aELWRW96%ijwC{T)I|*!&LE;zAxPMKn`Zn&09OWy#2%O9c+=o6Rj7i?!V`Af z8?PwJHneY9j4t2qhZF-ptv8L8!fZ^?~tVk}C zSgVBjnk34(DQSdvupG!ERkfL4KI~6)cK8`DTn_JyVqhXrwZPLvdZO{^6e0QjvsA6> zBEAoKKGYXYIJ9{7S*<`h3u1fDDW>L77T(pEdnRJ8DI;*t5IiRX7OG0%$|lyp=wN5! zSy1M5txp)8#zbAp%4{n2hFQC~4dPxVjG3*D3ioX_feWVYVx-Vu*oWg|BI6r>Dl6a! z2=P(M3-dKreZQ37I{I;Go6xL{I{={xpqeSEx;27};M~YrB+$F(bjC~^8mppo9ei>b z6YK`&ksF4}PSu!8PF}}>GV7ssw<86LK~j%JqQm{OgB9{_^xz0~9Pbty69qTeYi2=s!;|@a$PHVWmz*b1Yd07yX0%! z=H4`Ll#->9VfgBgH1Vcgs4<;@A&Sy)qA4$S-eFpiV06e(q=Sfs&4cLF5?V*b^mbt0?;T;eCowD)1 z`(nemr%XvWmts(s6_(u@nbIL6m*=JM>3e0@NvD^;WWzNFE2l;NM4sY0DU9Sd&N)Ti z&pk^AtDdh=Py86q{GO#%dOVrOX1-qM=wZ5AD7AHDMmT?MWYNBoTz1d_ky*<|35pMC zC@-9D4JgRC>b<8aesUYojxBZU^OsL;1xuY`F>Qau3LJ(=UtP?S_-!MgHwOOc_v^_4OY6d z9f0%Lt)X+_B&*Nhr&Mqh)rts6HHFtKIP#2(MLvBlmrLw$7%oU0;6B*K2jQ<@>ec-dZsHl_~_DfctV(aty( zI^DI|;@kWJ-RW0xFzi}ub7NS&cXia&>guXhT`v~~_KIV4hJDW4k6p=(^=s;pqF0ztCVxnMW%A~(TCl2QrS?trgvR*|0Yc-|sE+bGF@`lwosnKa1yMx$zKMX8B@b>+7Ug_W28zKXIi6$if%# z?8WiN18RTjWFgBN;WSrXfGn)RySKmccl+{HW`L1}uwSVm1?H}%o{Md@n{(OfYo2GK+ zk6U83z>wz!mbnooz$s{-M|%p}-vM5CjdH}*=-ThNmCs~1R5L8g82=y-L~7}LtuS!5 zf+o1nunEj!gE?kv3QP#~?o??vFh zp^h-^E2u81;6STDOAm!#$wPdseeVW!kiBDBZcpJ`rT7JGTGD6KT53rn$wRCl(IR^a zZ4}i0d|{=sLe@}tO25Jq4h__utP8pU59ap zl*p}h*S%a*kx1~+IYt5p_fn)%#qoCYHre^I%DC0P1SGSvGLh@L6gQ8vagjXI)Zwm#+@W z-#x4Epk%h2xSH(BbbT+0n3tszWc9gs0p;*OACSr4B?g`Py$G@~+5D$GX~_>y23lWL zLIkyH2@#IB7Vfe+8^TMMw!D5-@`gLWfC%D;=}nmq5iWd>$K-ov{h4QC-YF2BTh9?X zKFn<@@nquZp!}G0{flP@gO3LQFS6cfjGz22U9fAmX4B~%z#+S>{^4YHd%FGwioL)X zt!ue0%E>q4{Z#E>?P0w zIgVez?PX=>bMz+5p~VeMsI6HTpl3o2|UuDeWMc>cuVLd|-fBfffx=m<~Kb3R0R zRjuTC)6PHfYE^g)&uKXWDDb&gpS6y6C;=T5RcUfS2uOMC;l>6MEwP9LJWkNgR${R% z52#y&nL}xQQG4L*Xr<#lxCRu3FKrlyK z8qcvzsjX0^xKN*wWHnZRt`{;q^!k822b<}}tT4d>Jjn*=p$0A6gibRwsX5^--~NG? z(bZ<*5WbG(t;aT7%A-F$4V8QhKn*nqKJ^QHJq^QEsIU>PEfZ!swVDf0mO9SI+qjn% zLSXcW8FgkL$wfQc9{b~f9g@pnZjhELI}=OE%+!gptg$NPa|>xFoOjl4#zi6Agcw_| zBv167!(hY+s@G?=ssIxg#}bQ5jCwO4%Gj;+eHk6@IB&nTJYKt>S_H}dwcNw8UQz(m zvA83&C(;xp(du+C>`?1_+RSxaDOF?aeulH!fo)@};J8%XGmB9o6~&~>KM-m5 zI|^E*WZq{=eH1nyO}TD8Yv)V4fg1T4tvJmXIVF7YM`A#odZXTrqg!A50KMZH6SZoI zT{|BFi^ll!^*zvA5~GSb+M-v2l=V~{11&z|2EtaH?xtLqn!_hCm7Pql9IO)n8#62w zpXe4=r0sR_wWdeo%?}UCKaxspOewv6b`{95nWw3G(lBHnP9SHa$C|s+d(C=qN{h!H z|A9pB_fXQjaJ6LEvvwbZc#dSqPkD=ed9MkIBMR$;19OpVG#65rMwYH8im&-)NyBFG z_K0|FIW#7bG;j?n&VIkeGvs81mz_v}LfWHj%Fr#vvs=;!d{Ax=%rg7d=mn~2hhkB}kU_CrlOIPY^sI?khMP%HW2nh13u zp6U8Wg7P!c!Qevyg65-=HcG&IfxzqJv;*%Rz#EI`F|2z7Pd@9VPLypE38~}-9LWhh z&p{i7(psrfWOa&ey{46TQYz9X4j23%N1J%FzK43ziJG^?^YQ}EUqv4~Ms?jmQ$?CQ zb?HcEf+@;qIkrJv*59 zJ!MSep72wDy?=M%LwMVaA8QQxQA$z#iHd%5TxnLj5avrv5CcxhO8zsw z)ui5*vZGvGv&cBCyyOIgQ7kwYlyMn}-=~zrbwq`Bk%Tx&H0w2W%27PhO!p{J@zLl@ zL^yO`y$(fc>$)hOS4oML>BA`x!MTxg(m|4Z9^Y)eqv}=3e2PvH%i}T!T~z}r*U(>j zZv2cc(X(2f@H2{^S-Z(te0YuK!&wiO^M1yW7Q?)WuSGh?JN+Cb?I}LnOeHi*-cT+? z5OXOaKs`?@T|Co20YD8a3d-dLR!LC>TM&gV2r%fVGT#w0FjZkJ6@RN~RY3nnsR8O=qyoA=ev7y97}cQ2sf7&G^PsLbQS zSYg`{_R1j!UT$R!qw4v*XS@P%I$x8#P8t78@Z2H=mz~B4u{2sJyOjT#^|StbEMp8# zU1vWde#B2Ue{Jj5TB9fWE^N7q$U%%^W>`vBsZE0+VHrFca zU57P=wt9`K2U`SVAdr_{}iPG^3`%MLZJJ&!33eWIF{*&BBPwC2pRhd*+`Pw3t-=Dc|AlReAr?Y`b%+AhFAgC# zEuz;ON$hL+B^i#@K5Ym*O5i>xC?DCmE}cwoF2Pirx#78uv)&?1^Yw|v>V&xssy2UZ zgELos{n`Azx6x~`c<=}@l|?oK+5E5O@swcgafD(!eLc4dysYabCV>Tl$?L#tf^%+B zW@+^|d^?97b+e&7(|;V%Cj!B^|t*R4MWFFP2yIBRCrf2Pn*^FTAxXbgQ0(}yYS z?6g!cUJ3Wd&n@qvERQAoNaw!Yng%%PymuvGIXgQ|wsZbt+7u<4_EW<`S^i!@U3v-3 za*4x?x@V=eGQkX3VO&N_(v7bDAM12teN+2CvR~oe{MMm zj7ejxB*s<0oxl{2Av|G`3E50Ac!kOfr>JzoDq*;0@Vp>>?E$GA$KgHF9E@BUVJb=2 z)5*IRnpb%1(aP^bRAN(Ncj_Ju0Cbr1v-i=L+@I(U?KcM3?%Askxw|L8C{F7B^73@< zZ)tLaf-FKD362Pn8an{Q*&~hl2t3S&rYzT!oxIT2-cDZE-1$5{pl7q3wCBQC^}S;2 zx6zYKXBPpky$V2-N|D*gvbfvNQ~y@7TL`sWbq>c&R=y z=RnCIl`Tr|`VGk&J`V#b9VvQy{rYL|%S>KBpc0#=hH_FSy>Nt0d_y^N-bRJu=NYsR z@p(KXi)QTL0<`*Q>l~SXk;!0_da(ctNxe%p{<9BROt}S5@$W;os z_d1&@7E?Z z#zXqxo_|bGixA8rnu_*VXg4K9@KBhof((TtCqNN>MkTc3XmpnsxM=jZ}wVh=h}2)4OrDqh!>XIx1IbSAm6Cm zb2tS4;iZ9lv&w; z3r$yyiY14%4pphv;XIL?M?gNv4~kJ2KS+5~WO9}1-1PF?l*%K!X01x(*k07k-f~-C z^|qH`N73u*TuOgC3?>v*Jj0KsMJ}b`L)~?&NcA?smlws!{@->f-5L~mj|R-}H}exY z4)Vie*Fg$R9SyxP!3l5X$V)s0+$$M@_bBn{20l$ZRpMdVNHT`P>6Ufo*bZKTc%8q) zHNcnR7*geT)EJu*J?i!vZvEtB{-E71w&Nu?oG+aAKDE9$chf85il!c?6M$8Vj{oH( zJ4bCLRkRFF(?wxIW9RErITqN{V*|p}+SK%`&4_>Lis@;oEVMoy`~Q7EQi*M1su!^` z$CEA!%GDJNJ}Q|7KBWI|UXiZv!kg07SihNNzRjunM|t?D%mbH!nO+_OeKe%;U?(=w zvo=8hJK#B%TX_MpIG-1ys6kmDrt=6HAKDJs+z1XaSZf1>H3HH{^7!7 z=1pwp1&Pbw*_Hf>&CF1QMZu|8z6%Zvq|A6h)}gT9@WmIB$Iifewc2dlw8Se zcK^TYO0JykIe?~^KK-aleJZ+=AGP~vx`jXcnd+DiINB?v%>l0D%Lh4EvY*Dtgd_Q3We87$2xoA5ug z+NU$dv`krd_nC1BB`u{S=ER`p90#%Plp$El_sP4Lm{CW{k4X8Ig*u8?TTdk^{-2ZA ziydH~P9;suNe^+n3%4nml7n2vZ;MnxAHQ+ViM+`56pz$F^L(v36?|=v%ag9#p+)8O zE4N_|<{K-E~Zs+u8rDATA-m3wmbL24DDO<7w!Ez8_U?pCV zK_74Dr?8C3U5oFKkdyFf$Ib@cp&-ZYm)x!R7%G=OK_40{G_D_>?0B*Us6o&I2qx0> zu|fKC%GI>eOCAAD-H-$th6(Jag(nJbxM2&wvJBdI5V@Dk;6ftR9V!}IWD=bn3DZ%V z)x``E0Xk^<2-#9~mT{pQ6A4r6!N~MNGgF1QCGCjLR$V7HW)j_Il@8@tj*15lX*GJR zX=XbN&Abu*e&-K&=a0Z^#0|q2i1ulF-JeNpuzJR?AfM#SeHdS7IOluvh8AYR!_4z& zJUgFM%aF`y8Yr8!6_-PHWR1e#W&cRiTVTIcZyxM=2#q-qGJbm{>B03viiOiYtNfB~ z8O656!IE&>;6bWbuJ40kcj^bImkO=ve6oPn;X|9P6^ROW;;wkq6kbcc7jK~TOHKL} z4GJ$wS}8SKrKnuL8jik3>6C8JU-;qm;(-Q6i3a_t3IAi3*pan_{wzbHt<;cEkhU}3 z!aesw3ivq0I-NRA&rhJ|4AnYU%j0(1_r_99_|OCIHf6JmhZZ$>6Y>P+P+j#_WvkW! z3WclChl>1z)?+`rlGx$=kok%wxH@^=4WX%)o2iWH)JP$WM#Tl{y6}H^EzXwVhQT+K z;5cSQ9x8e9-LCZ!*U~yP{JL=e4mgn_VCM2!{3ST-WEsv@j4j3H;Mcd* zDi=np9eO%JIX-de=xy@4b0HAGv7s==U2H3SiVN94u8v8|3TMLRb8pVw`9xs|*T%o$3;4-9+(anDXV$_ zC7{0nnNmsu@tjUrN&zMVO9-GO!lJX?aK0VDn&hQhBdi;uz@X|AzKftamU*mj{c{l( z-wLaRmi;0uTx3P0ctsHw#dTX-QQu52z0p+~R$)q3N!W!Ht9^!9jM;#ge&uP6xWgfG zP|;SwBrq^>a$7T$FTkzARp}Lg*5FOAYT&{q2hda;?ca_n-ZS=z(4(7Mg-Hqu{(OUh@VXfrF1^x}O;&itD3eoZ5+uY0U&v z$}>TFZe>&MRa+u{c9wi!RDWvZv#s%pTm$6|SWw zoXp&Ww=KZQJb5sbGl_KuIhn3rO3SOZE`_V8XE?Gatd@6CeS$_D;YgCJQ|!$}n2P-5 zYa=t#$z2Fpr%9gxNmY+Hw!BrJIlrxG1o%%k)6j#(WUUg!buXD*(i~_7{lydzKxVdb zA4?{SivDN=Pq1agd7HJ6EG-E$Y(naG}J5Mi232h z9I8z}>tk!^N=WvkS+Z2qp>xSgAsM;sz66K(9XX`0MYVYUWY zOAYcwlOK((JgnK2CjfRxHkxjt&tr&kvB=5K#_b4w2h>vDICFt;Fq#SV#q}xb3mavI zBYOlFSOO?ZyMUwW+yelINA_rGqruBKL1Z*@h@dsGISgvi504N3sk*wn$a85H599Gc6T$1a(#X zIiXHAPUkz-U9pyXt{V`($Urf2-nPPk0hmG?kRt0*8A5Jg# zLisE7t&5U9Wz@l;UVe#-uQ;#J9e{LBRMy*oC4LbcBKR&)EWJiB1TV}I=gxV3Y7G?P z&~?8)nBo?Jj!KtjXPzdd$N6CjuRdflyo+ZXBHO&o$7wg#ufUD6!h2H)<|`~A{U%eW zf^<@AxlwtRWmouxQc{d&mz#}3A0>5Vw&Xy)?EUrIuq`)G!%`ln>Inr_3tJ0kk$e*( zs|Gd-W9m58(J{IRAqLPde)A1Q#l!sObH+mTUruyxid5v_t9$Ttn*SUveiT*7SuVXM zia6*n-XS+Syh0E&YD-?Q(#(*|teyizQ8m1P8;anwxmUc3esWh+ZbcNoQnWg}lYQ;p z?)44dpCCg)wTRg)hnIDAcFp`8IqsZCe(Oc?dVaCKv-9PzID_ZxeEO9V&wGyQ#1yZp zW{j`&?B#i1naI}fnR;-#e)o(!zV_tSmuB$*H+zEyfvqJ5O4dD%IoWv@Y6M*qKWNH5 zB?8uKaZ(K(WKyR+HwEJ)(xcT*H1Kv_Y8_TD=S!eVFMZ-n;uU8gdJ) zoRWTQJDpWbob~eWS#)Yn@ z_@#Z=KG4UURw;A7mcrUCD0K4sPhz=`16ynTG9OEPEn4+sxo?7!^~6hkg=(C;K(P!6 zVQD6ryO04Z&ihLvih|1I(-roB9ElXL^~q23fDZ&3gJKDYf#l=6E>k@>JV)_}qy$-^ ziO8Z=zmXuyUl|8H*m*4%^QzR~MBqI94hCm7@k~F1^V76#JRRoRMnZ#CvN_K!{BXA= zXf{D6rXjhyH{@w+Wj4Vq_Oil3NYfkP#3}m*{tXui^Bn|&F&2O@oGO*T1C#oRw=Odx z5Qc)n3;40zzs~3^L25w+d3H7BCErGK%l_C9i8_WY%2P2|gOMCdc`3e3XKPExtu=!& zeC86_q?gJL#ge?oX?_ekKM3LxrR9ms0Twexjz;E2p#sF|Uomo2Zlh;Qa;Iq)-L7sI zLNMQm(YA7Lz=p6`-*?Ejr-s3Wf9ofXQtnxM!RcHxsfH}Duf~rYW z9c_2ljxUaeIN!}=bgYehkF@vJ_8c7i!v}&fwk0%v} z#ELgAi;zLP5X9%`@>ktc2i?Xg^w3YSEFob)_{PPW=X*7yrY!{(K$03Xd3W&hK9_cHjDvQ($JLKsM&X6HOl2ORo!HP zLeHW}nxZ}#fXp#ZZBBVCf@IT90X@AERZ`J54is8`NZV90pxC3UVSC+tl%~ue6n6i$ z8YR&Om&v{Q)JF|v)Lo;G5-O7FFV6tv@=e+mGo48Xg>=S55wOE~4H-3lDQRx4y6<~B(uqdLfC2S{R5fOH<=Q(;p$(fb1zHp zX>ikl;pDoa2%^q63NVT&VyFu>|AWuJcA1O-XKA_+qRrXdbD5n4i_CXQ%w#efX|SCf zwb^9x(k3NbkdbD+uy&J4Zjtu!PWvpzZ2+Rpe4WkzL?mcxlY1pzrFG$i zdaN(}>I*-#jJbvu3Z&`DFb53)=35XTM=>&YLJ^cA~!m`OEg~i z<`ezn`$qFn;;zzum79*CBwG^-vhz#64?YDr4B#S2~i@%FuB-=)KAK%c=2DNcLUnhtrYt7$m#`Qbbxu|VAG(ov25r-!?qq_g*Ow=? z|H{Ur*mK{@eUC|VpfMd2jY$vo8q=Mn(T*0k#GcOk!@^G{V6vYdz=xpF1)uC05 zHt=$vfdeJW_mbDen1KbrTW;8e{Dy~ff~eIMFBjrKePUZ_&w{Ed-_tf4W~8ijG8@t} zY(!K(PCaqmGz}u^mzTh92AptotL5PjUXTk_+Z#VK5=U5Z>!P%U1{1t8AN{^X^dmG5 z8kMKY`$pUZey5xuS6;Tn{f8wSrTz!Q4zZuA3;0npNGcSOQhzfQcDV}M^#d1?D&Pib z`j1@3rHYIjBm?m=2Le8`APs{dqd7S#D7oknA<_vH=k)~fgZ=wTColgSeI+eoQ1KbA z_S;XfQZI)8$NTx=z4}S-x?VPz-fcfsZ}GF=zKSRPZ}s)Mwjw()k_d(!qb|mDMf{)c zJ$~8}fT1z?a!(xArFjI`w1`hZugMu&LpTm&V^ppQZ|aqL=fmCN&<(l%MN+cU7w~J= zb2ppqs5{z=ETyoEcjUm>$X*6*s31}+6`XQZx_%vD6pe{hDYuPcGo{D}rw>GE!BAq4 zHl!8L)!a>deRZmy)3uvd)omE$wp6H~aK!dEq!PWs;L{0f!h6=G_>5J&73q*Rq1#n( z9FMcz3}Uk$6Y#gz9;AI(hu>gECOxf9r0Q`}Hm|MUk!;?P%55)f!y8zl!kRjllKiod z<@16W*P^R^veIpw7#o~o?zK$!i-S0$xu-dp__3kc;M_jx5a*H|+{c>{v3q(p*PG6* zj^(X6P=_l?;;gPp#K>4VRF6|7{;=oPJ_MU>9XN`Mv&#ustbgEI0=gc+F-vC#DZ^q@ zVuwCabAy@^ukiBPZxgbc#iUe2dk{6E4F7`;{K z-{GuKkLEQga=ark-=lZ2V56Iov`CuXmmJBA(t-~T1!u#WiiqB36+bKFH4!!a4vY5Rin`JioLedC)Jna2 zz>l?k|GDvkz0oMVYN);mh8<=rZcw-fZ#x0I>pcVK(^n;^SLU|x2;^y z_SdM_o$da593w-<#4^Ik=2ktCWGH1Vs2&mst0x=t5>|mq`hS0czZd*Kao1WvVR=5N zYA;--<$D^xjc;Skrq~zGXI}JfAzXFUM9P}wwSK+X64Ih%lm0>(=|K|#QTU;$H#M%% zjAOr_t>ZOzXHlBQzGP%O#dA9gkJ-Wig9}DH5DMx`+(I!kD`cc*#ZLqk%XmrWTj~5Y zDhE)+bQ|cqW^J?{pf>rCVs2_ADMy8OpP|`BtfGQxy)42QIaY(J5BaLZv15U2fUXJ8 z{QQBA^_CGmB2A5*(0GGUh;1VCf#y&iHQ?Ho|F}9zFNhp5XNqKmbS**0I}2tY7^3|{ zwiFelyZdAtS>MA&Ggz^#D7e(_Wdc8b| zg80Zoi!hO7*vu#KaImdDa2)f~R-LROg0=XI_K7g*F@s~tvp=_qeB9yrXB%E>wv~Cq`(c@MVHK_?d;_CF zo&3>KI#FMRSC-}3O+2->8iqNa>^|@+w^43_1{D%%gqO~En}dY53$t=hL|iARx@rsE zFOJON%ydUhp6AqrCw~@F(5M+7qh`uQy#rD+KKcA*%9R2q(D3;&#!zG_AY+HQq+EZR zQw{(g&lO4|C};CQI}m`Tri1!EwCSZs1sr)1@ivOfBypU4HRm^VDk z_{K_h2KmE)5<8;MG>p3NIfpC&a&5S&H};+xQNH6c4>4}rqKd-pm+Z^k+?TxJ3UfC* zH?u$m>T0G~cG#Djc@n+x(-nzmc;Zm^v}E=SXPA8fa=mq-iRZC_UhAeN+_Sv8tneYCg9J=EX?BhnkiBQpWAPZ*SyLG2f>uIG0a$?m6>~Fp z`p2c7=pTHjmmh|b;RzVG%01MFypuw~L(@Hv{$tF0yEZe-X!u1A1s+QIELkM8;h3T+ zL=CDg;=}!_n$hZ5_|TaH7_dj;W+qM29Oc2ow`6hT9-A*O&$YljPdGLj`MbPS{s;ELNdu7|KY?`hfOZe3o0H&&O6)?lxl zuC56e|H(Mt=bv(PTf<(8NvtN*7y&e0q=H_6WQ+3;Jg&^m{erSua<1b{VV{VI|-v zFIbkDwfq3u-bTryV?K|eVjCgz=a$5j@A{8^u^lVvcF3@9xP@=E+M^az7E`kIKg@q0 zuSyWczJ>5N#f#{&B*5b~>cpYich%|8&lWQXx%8vX;XrR3ig3>{0L01*T8SWsEf7p{3wt8PzAC)Ss&K4SiE zfTA^g&=Zr>Ram!{qbaC~I=iS%y`#2roS)Bdo&g*G=W$xc3i&d;O0trBVY7-I)P)?Lw#3ZFjhJLF|P3A|qmgs^+RA6+F9$gYc zCoK$im<`hF4fe3n4qIz+6T!JWPk08P7Y)>80(e=8OunaMM8w$!2ki&52cGgYwzu2kGld zQZ6*%aM|wWO2Fr{xr{Uz%n3esY0MF1ym~4HT>`b#CgbEA51G1Ek=)|JLaHP7i?b@U z{Din zOgP_c?!yVE60hzEPkoPdBF76N*jDC0QUrJ7bon!Pz-EPWo*5(;KZ43_Py}N|f4Uh} zwanA}2<}wRJGzQjl|Igdfc?^!I@Ver8zT(nOtLaNo4P6|sXE0*x{kcp2upIuy z#a%)9xU@yJBvuh07BQ6nSS5z?VxApSZ@@}6gG8Fmn3d$ZIq@baPw`2j7sszqo#XF{ z>|>#!YuLRaW*;~w;W#Qt`kNc3?VEi>(*<0Pd;Bs9)JOKmJC>1u!Oxs2uR;0Qi9Xnm zc**2-;v|l76p?f<{_%&$_RT*w{YH_wC5(d{XD7`u@tmBMK=^yqgDj*Oq;hXbD_H&! z07Md~P0qV2g}?%n<{Q;_xP^A4`}x68Qvy;;58#c&`dMS?NK^2sKKKcKsqD(?EPp`t zH5@&QsgRPl`AD)vk?ddTGag9RZbtW*V1JhD3QjihK_c#!BUK;af0l-aR61YvkOq#) zTsH0H6bPJ6tZhnc%qG^Q>bFh%DH@t%QAR+LLp0;|z2vKlj4Ka!T)aN!NJ_kut|LhH zq(75#hQnvgSYF?ky#Aq+jHQcDfr72naC>Q;vWmnDd2LiS8meu#YrLRTNBXYL1$GYw zMmE(H9va)^WA)H|oW`UA_(re1XfJs|vohkwW7I&FUW+F5*fvnbP>sY;%h*NBgk-+9>hssm+IuD<+A_R$EX{H9HRerDXzj% zV^k%&fGV;|w03~B_{J_lg%})oTp>JWSxllO5`J6qhR;Ew2FwA*A&2=~t=1zO6Bhpw z-3P;t_nk7R%M1;wCi;@CjEPx~T+)22$+IU7ijTTt1w#o2vL z_1)7pTd=fq;}Ik+>6YyL8k0xIj4#9c1rf3U-FPCQPK-cgsC7Tq{2s}lrkR{Vf#Q^w zh)Ea1R=2Ed6dfE)tdFf{RRu!UD~C;nB*;)T)oH z6+)v18QyUEmPs+_82x70`d+;>w%{BUC3;5@NovA%E8TXe{BUV{q@S?pdntR$5Cg=V zE-2&dKDO<_ZnrROK&{OuS7zL_6%k{)kjdsE{}YE2Eqy7nm89XEf+*fR;aCxGbe9RH zS8Dk{{6E5<5>}wa*c)!59MjxRkrd}P<=8m4c7Y#lyDDP>KW;(bhTF-n3{L$B&(_SuT zgD+RY27^ary%+H9hgZQ+Y}1vthiH+}>(a@Iz4RhVSGe{X(q6XoXwTD8VmpTPK~*F5 z;E)!N`Te~=+zpmy2KC3%j`xuZqcPuHR@k&Vc1D!IO7rw}baKov)miFd2p@hY7lSjU zMhyNWviez?jjcIvLFgKQ!0x1+dZJMpzNWh!30o%joXi2V%v*-oqs zU1B}n&!FwZ*PZ=Njs}JI>X;OvmG?B*X({g|(+Gl}cx-bwOj>696wwy65WbϤ}E?<&?^ApogP9yFbfghd@xe*m3Q2 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℞YsaG6VBn?UAB%sEN`66YUHTvn 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

4t_-uT{>Lk-J*O=)nv{2U4%(q?fq+q*L(|) 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 z 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�V+lyKpPg+14c(9rlCkr*&v#6*mZqPZ>q^xx51Gz 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 z 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

!l91^yUKGFaytS-G`Z7~|10N<>* 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�cxHql|@?@4DH$CRnR-S8N{y-fWs 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

W>MC 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 z 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

~AzX$cpy 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ȠaZz;bF|z+~3iOEgEP7A4iCdO0;iKa9J%7DFI@3*XXy)N< zt-TF}VWwDV=3jd`O zfFrpi-t~1LLrAP40`Y z-X;*Cdg_I!)iQo_t?XxcNQR}Xat<-+&&zGj{#qx;L`cfBZMoQekl9j%7F!9T!_X#z ztKhYgUK6v;sJNiGqgL`Tvg}YO0q;Vfl}k-~VCE^^iO zNT`bJi%znV1u~fNHqy%Gvui>&8D*GMnwpy)cNQH*25Wvr9cDVIGcqq?_78Sy9w2?U zsHY*njuQA7`5w%Y!;AO?zc1rIAc1st3ARKq>4VxqEn0@XFgBh}U4K2i(eq!lolcM^ z<1a+zwXWw7!Q?uRxW3kPxbaOaK)ZwoM4UQ`jxes{qQ_0M2{#d&#FSeiVql2^V#KWv zr-QO}S>-OApjgweabzH{71;|sNvnC2LDY71J zOksRntp%yLV?;KtKR&0JSdC6zwDI$9cf`Qo-A1vAwON9QHE1!?H z!$PWcKOed0S_IEv@`w1+ERIS`m$Dn<|4y(+zdA7o3K6+aA^! ziNoM1c-bBxU9ht#!4IL}<1CA3$mX+#{Ex(bOh^E^jThlGH25wzAci2b0Pc(TC^b*v zyOK>!AJSHaB0Tx3jds#OGkmr`9bB^0g!NJqK|-ztutHG@cURgd0&+GCmUP?gK&n8Y$!COF_{x(YN2)!cJN9_CZeU- z`aE@Kf=i}iq5CLd*tjxDjdh!Kko=JuG!|`WSV<|H9qp6<5T|Hh6*u2;WJ*yqhMP$- z|NOVtBR z2d3ue=`e!cRBcs2m-`B5^lHhu43BrNAG79tjVUV1FK)d=_B;$QGU(Zw>iH3~Sa|pi zEqW5dB^k)j|M$J`bm}-OIiW`=^ZUY}zE$*A0~LfLqn?d`SrpnuMm~&trqAddB9a&+ zW1YO0ZPip>ZlIE9EOi?YDhk3lohj` zqpW1Uagi9Y`!LAj zBK_Q8+PzHv6z8+y{L~NhMus~F`J&;jl7Y)`*Wk9_$Geh{-pGn)J4$u>u85_~cK$Y` z4vq9?9xy_UD!I;%k1(U1oH#7~*Vyf_`m+=XA&_o8m}`B`ne0>*+6yMT=To?47!Z?J z$wRaM7fp5G?<}x2S_mshzkZIh=1nl!$(5M!>dN&qtuBSq&J}U)X0%h>S4BCiTffB0 zZcB9>I^O=Eb@%f~H|nK?JFQUb0SLBCJpo^A{Yi^r6^r`ts*P8uU>jNA@3w6mG3H>G z3*BQQX*S57r#P_$`5XCL0eFy1-on3MD85WWR*39)6^JhK@PD;f$fM7z9+@RGHp ziR~THYB2jrxp`RS4gL#3Gs%DVW|W&?MV)L3D=AvyZwSiH4TU4c){YmB;yr&& z31(Fe5%RJjABmh-CD+q^t#gd>v4KcXBC+;wL{yrJ^;%m+5tW3dhL$ET{lVR~qGfw; z@V8)}GuzxORxc*@P;QdgWZOZZCC$ZaksVHE zBol5hlt{jj9S-q68?-n(oJSbb1XCQsJaUb=vM>RO=lW~pNZp|)!j{k~x2FvHo(N&b zn)(0|P9r7dHb@T0q1&*;i@lg4Fy{FiA&|0}+<6WN>=@U4gC>kg_l~9+SV6}6ElTCh?+wMKXm+1Ue zvoOPH3V(_5PQ+C5C^?dqCK)Qz^Qw$?SHnPc6G$dnAel(V5F+pgAiXmY zN^?tWxiNCHnna^kns652L1TT&JEK)0B%sdy>^@H9Kk`#n2ySxWOZ#_W-quB0p$Q0& z`XH!Fu+m6eYi`5CSc@&dS+W(dUNW)CcKVtjB!}- zE&bUPp;0Z@q(hup2Q|d2242g|EX6`Lv~zzNZYK?$YFNV$72XB56!-VBF;lXcGY2D> zY4!GKpMDWxyXJ$P#quyb>^4)*3d5E}>sYQhQi@rZLX%qLp<|jwJR{5j6C`*!cY8<| zok6XZS1K7B?&?j&=k<|MIYlU}jB0&mQQIpd3D08?7T=<3K|Gy2w}-$G_H~m@C-@w) z|Kod33+Zpz1lEd+-#|CT`i}f-w3j9Do7PS7i_1~Z6bZZRtW)Wxul+l#!#tWwpuZ3@ zp}CaYzK19skMqCS7`-{hz9r#WylYcvIBW3Pfm>^Hu>XmZY-c-p^vm1MjNU-$ep&lj z#_VTbqK)4R%4QWV#ig!z>9R`;%aOz*eg{EyLhXrp|1j`b&ObQ>=0Q)}Ejz#b$RIn^ zdWxd1u=Q=u*Zj-WD6kQnSjDu{OSi2@mDd0f9=HuZvB9LdCM6&(zbK)gfA6A7+5io0 zbvlZX=7Ytu3|5NtBKtgmP{ffTb|y|9kn(s5k7di*>Lo{r!b-QYiEBkI_Mm8Gp(C`;1f;%@nX=l5Yuyb(8zRk8o@@iAPj@==r9Dmm94|cGYr>WkaFmSp=)_VT! z;%$qpV}#Su3&cs_%pk)faky^*{PE~yoRjkZMPZVKI}m;~n#V+fQ{GCiX7*7Aj67Hf^OV4=UptPT=+vLXM}4<*z%dxUtn zq;q=hj#}m7R+mT;EaB!_Z4_ZWR0;t6+bU#{g+UAxSmgQl0LYT@@p&7rC_7}B6wB)WYcx>mtM{a!G1mG#IBj9MF7k(?k+%X*ptE z%*HsLqMsoM&t`J?!%$i2Y74t!+aGZRI{%4Ton4O4MsxL|>M6P!Rh71&fKFWLJRKbV zhFFvu+Q%w5gn5fX! zk6z7!{+@do<|K`2_fd2XMB1iBv?nAG06>rv{;-j2l&_^vaktS@G!j1<$~bLci=7wXtrizi)k#QMedn&?Kar4#DY$%Y|xt%@$HkQ1-jYEwpB)ffHO8 z7zD=1rpCP>>ONh!;nCsy>Apr|v9_<73298zupW zjbd|f#;!285iU(krpiJoED%j*oTcf$%gSkk>tcd{Qkbwp<>Ni-7=^}i1UxIdzTSmU z7lBDwP3*k%HwO!k>rA+rt6jep`p=40Q_1~UTx6n@pyohbhc@yy#pT%UM0WQy?X-OC zTG2FWn}Gyk2w!9`{d>`9YzRn9ii=!dj4n`*oRUqB!oNTU=8sG@*fN~qN z_3<)$=Qb1Nf@%U}4`qB@OksAMB;HUqID#QkJwi0ijBL*`i-L%mcw_z9?&Z~sNsE&< zi$4?2gxWG2{y5fk1eTTRBR(onuJxf%Hcw|k$h0a+-YX;Y0xp#-1|@jXu4zIbfQ#$K3*;geux6Q)W{_jdYI)vHaH1umvjZV z!NejYXqePO)&Q=QvG_S%D4}59)fsPkP}`RCeDacB_0qJRrbmpv@)5ukB#pG}QIk7W z;z`|7j2!?7H9Pg(5)&NJb9zoLgs8l=4?k=n#Rr^D#koK6i>9TfRKkN)k(4go<1p)K+il$ zNv;$0(||K^O?fyY(5l4m5XrzK$=s=}lE}`*BnHJTlbR3-^!hz9fx(bhe{cJ3+U%MN z=CA?biKXROmka;LEIJN`QD`ABT0)nw8g}*JE#Owu0IUQ#`fGg0G!pgPmM=C8+BHfj zL^vUNL1FMd@ki%q7yB#n#vuV(AtYfix}vm0sAjd@HKgoJj*Dbbf?Otow#IQsW-sGo z0ERgls&l57?Hq&`amG$OaT$4XE~}&^;8~#_kBO zD=VInP7=I?AttoRCne_|BL+?1tfUS3QXGnnMxe1dgZLO1G&u1Du169A?f8Df4f+Bl z@^6e?G53>DCt`sss)8lP0;k63O$BmV4**KkmplZkzd|Q$6f61rg4mH zu{4h)8X%K5PLd#d+KKGibNsC)?Cmd~{%2jWx16!%7~E|#6Sg{QiJ~%z@C`d-yyfPc z$C`Cc$qdIp`J1A}nLH+5Bv7(tI^uF-8{kPBV<7=E#s=j!T1Q5F8wwsw(SW%@w!|HY zEE5|LTEIi44^Yzb&{H)+B*reBm@fJy2Td?;wDh!uJ`jFuIWDcP#0?Mo(M=?)r1UWC- zcu`NK6v23F=(3blb)DM8Zp3yR%VG3xH$R{m<2gLlnY8TYH=wmnkM*gwaJY+gb zdA)`O5$)_x$DI7&)xXRM4@zq)Np6QlgB9ra}rbA(&pu|U! ziHPYSrhdxcrs4!s;itNSBfi~pdmScMyF%*K3_6Eee=D#^} zQThZRCmJ==ZQm6DwXS4O4q*;;4fiHt3l5jO%__|~E zZl|;&gL-L8mRv05wJKFY*C+BOlp`G+ZN^SOanWr^V!caz@KrCa|mZ|?#hXI1TgCr#6aOPCZ|s7Edlq9%aQa%}{T8JNHX zCnabLK?+7wuqtZ*+CtT~1d>38;c3GWj#W@|j-VA$>Jc<@(eyekatQ^bT-3dEymf4(KId0wmpWy7SGm3HcC?TYbGgSR! zoIP;oIGnBgl6pN3UzMM>dbM+3@Jw)y#TDU3+xXS=cQ-hqlbR5A7Ni&(VSKPl4g}b^ z%J=z;+PLa|BWspu(PebukJSUiqA8j??+@rQf-=)soy;-{lfgDL^Dn2<|Df_l{eW%N z*_vXL&SO5~Qxn~CpcffA5!#cT7U2b5=JmzoO144s9xMo1=lvB$j zre-Sg_d6}SrVmloidyyW?~1xL!}i;O(k}Z3kN!rho_9eNG5#sQ617v0;B_oKvWXy(y0s8L*a$4zT@ zC9l{dfX~11lNZDn#4m_n82{wPaR3K14xvagoeS^0`p4RA?_NOV*)sl&S(k=yoREJc zq5N-#-9G>EmLD-QW?o8ji!97`)L6gBCfCZBq=zI={G>@Msx{d)b|+OVugR7%q+|Vi zDC5z5$$pY8WB+ulf2!i%%a`)c5mxM2&970i>Nl+1GycXV*zY<*nKFU>3%;74eU+cZ^LqYf$1qJRKVAQ_=X z0b`0YeaalA2!l#t-ue471Z=0)dPJZ){3|bq=v-6R3qU21c)40Yn{mR;EuDnR2!3Fd zXt$3x`=AN~Na%(yC>N8#0~SGPfF(UF23V~R7+?{U2AE`mDyR-GouRJo$h*}-r$;EM{ps1 z^(mb3$jp-5CCrO#*=wTjz3E@>B*Jj2rHNlVO$wg)`BNI=Q%s)59g{gia zu5sKBhCpThs_t;sy@afL+ObRuhN>8Lxl&QJ}{M_ElgFfyUX}NsPy?-;g;(D`)b)&F*qP9~}2t(w_c(F!{#V?Zc%n zCxRvArJVz1u%jMJ<;C}Pe5fWtZPU5uEWU&y4RB`P`oZNDOyYDCq3o1A+so-zWq!Pi z`4KNT>1diw$6&_72CcB189IFa${(YvxPV=^q7E^Nd-=^yVFWyXYfl7U!3>E{|hf`7QdcT3(x-QsBMkkE^f1e@`P`WfoD!@!vA!Q2mY-@ZT)__jOo&W{S}I zHeWi*$$u-cSS6w@jl*AO0d@GUWVWG#UZFKjGgi?-9=?r-^zxmqP+KCv`q~xm(Fua? zXX#sZ3U@%q`uCw^?mq}ClL#|WKWoLImg`>2HKJTq%5^Q_JiREpNY_JCU$NpKE7W6! z*pC_O-&cjsB`o=4iJvEsnM%jHKE;=+5Za{5B2chuab>5#vt}s?o~2*U?*6<#0tLh@ znN~J6JtcRb)!juha2yi#lEW=J3PDYp5Rxm`lMYP>pXYgBE`4wtt!@V=d_Ac|9hW;L zFKmP?YkRRi>Oz;|uF)#0;HlnSn~yh|jV-_i+rhp6RRO;o<;WT)#I(t0i90`7e< zWKnZ1c4Z8(B)y_$4U?85-@_mgj;couc3)LpBw(;c15+KYpU+V==?Sc(bm%lF|K3Sz ze*uFQ%;>gnKW47b!v%%Iss;o@R=(A!jWz>)IVuJ*tTW2b@s&Z&I*ESSp|~2;mp!O5 zDzrEfF&#%ZlX^MZ7cvTPRic4}xBi>XEIA6p#vl%AQ`}GYXmG|&^*Ol;_`Bv?RI-R# z@+1;bLveqMWTRdR2*addTp>>+Cei=j(Zz2O%^J)OYQyR(r5-t=p$%Jpix8g%%g9bC z2=RkC*oP25fFB8PC%+}U?=P0x^5YuJ7^_c|d_0x@t(VzXyc7z48XKf~bCbxgt(PQH z!|LVZWw%>k+)X9v&0*QQ5?`T(?~%xQBYghr6N@VKaus#U=Wye0bF^9c&EYMik~0$7 zqrjB~B&6KSv91b1>8eTW5iXr30jr#HhR`KHaJI_%As?CjSmm6e9=2G|V5vRsi8|*! zE3-%aR)qexSbA^LmCv;VGRJIHGrV6RGB4P)@Ohfr^8)qpIo2=5g?F#Eg^w^hL4bA; zRn!Jd*)3XzZ!ebepy>jt(;}zuYi?0=0yzs{el9SS*U!pem zh>!1ykiROyVoM9ChBr1Nz)v6~OHNlKA3Qa5jG*ZyGgcwP)Ed4ojvZa{<(UOI3*vZ5 zQM0BWbT6eIJ}OILA* z#bhpKw#L?l9Pzg5@RHab`7ss*h+vKxaF&1^tnHp*^aS7#K{?*dOLNg@3QO4z(FhDj zHCmNz%DzLXFycjOq*XCOskVf-`fSFR#52b6WaCQ_a1AOa@bkQ11MFBbDPms=Sch7D zpgMf-=e2Qoteh_kVjas8a}a%4+Yxi*>@Hrw{N^!{s;(qn`n%4*bM1b+fNy=zKoUjU6N8W$(=Yp=BT@bBd}R7)pey0C>3eEI$_6c^m{2jOvJhW*^*hO6`8VGYov%bsRsEynQNNO+ z0jl^NRS0>#2JkB>4iUG?@YJI&l3#TqT9oZn;bD;?`<0nB!y01ww81k3S+_~(ElMza ztRtH|$9MSLb5zY*i(FE(EKdpQy~Oe2JUOhfJl=#*9X_6(Nj(c|T69cRJ9ANwmPo{N z+FgAy@PM^V$s@jkY6&xgj}#;1L2Jwp*j67fz|?7jApGF@IwbFU>=pvwhC>V4q7lp= z_D+osnGaCLOPDw>O0p_dm8szPnq%Rqb}ZvIH=Ba@mnw=fCS-zBUOXlNf&bm~5X=Nk z>747GJZpvJ-@}%P+MDF%B8?fq^cZ-{p-FDE1(iRfxaM9f(GF~7>QL*HYf!aNF$d_? zrRwm}|DZzlPSm*GE*F6jWv->#p-P$_$-jPvmi1@Sr=3~iD_J& zZR*@yrrker9gP9!gH=}8WIe`GsA?Wp0$y2u6rE&CVngHX0Y#=B=aA~r>~3GMH4!@l z7vFZ?W_|s`EB*xGFFnAX(<=RY6PH`N4g{XeUc*19KDHVgGpRd91^EC_aP4W@yzD41 zK6Mk4(Vt=C3Qo$bN}o!ttByYQav77 zKY%#5^{G3C$I5X)k|uWL!6YPuQ=Xb7FdVTqqlC$xVjAjb82(nWxgYg=hJH0j3z60$ZTda~+!l+}pqlQ*!G@bAq2DZ-~}GZsN@4XSM% zcGVl3($*WbZY)cMqeiO3?57<68aHrNvM^}bpVYLX)*$o@JDwB0S z4@;h7f9Z-`j*(PQwPi~RD}jsHX^_oHz{-r!H3W{7Q5fysZu<+dv+m23)Nj3fa`(XH zGYgfxBAqBkxm-1sh@v$vyeGnI>!`?=SJdAZ3$F9kxpoWoj+X&}703(xNCG;pgRb)i z5xp#zpO4lg=bq!1A^jg>8Inx@Hre@7OS1F15iE*}Y0hovG*&x9qb!Mv#fuR`wqlXY z4$ZYr-IaAw1I!#60cZ-&NyO@$>d1#X;?13iSRL4K`9kuAXMKrPMWSZ8EGwU^pkOfL zL%=dlhvuc;TC!zP3qY@9YE&U}rS@(zlI?C2v6g5x4RO`*Y3rs@a=O%NqRbYtRt>S2 zmB>`fHr}(6npKls+Ti9YOOpP>Tus{DR8`!K#ixAi+CD3~w3TxGMC04{tWEV(R_ybJ z2P@XSe+>=GQq+AQUuJthlln8RlihC~O2uqs8J5yp@Pg8f=aJ-yL>aFy@D_$FIUF1k zdMvGpH(8g|jJY`qjVYcp93In&^j2NC5_mj;!+lVnM-YHi)KSk96 zea8uI{&C5j>}p1b6+w|5ILRia&_xw_XHslc7e(*~ffue>GUhd=bGURq<;f##an(V# zRB*~2gs4^`MK$xe)_>~2MV9cUC>+y%JmlX&gn{%jx*I?Y5zgD^NEh(Z+xRKXvb(Fg z$+lI|t^+6ueS|>s>IGo8^B${XQmlIx>kV1H3t8p(SVIU>RH2Hrl1WR{0m8OK-5+k9 z$jqx*ZnN~CSn$)ly20dCs{%k5T88vQEJ-(HIBG=-fdDOgJfh5P2Q18?4^~nTpNz5a|vgIe?_`Br5Hi zbgGia7Wba6y`XCGZW9m!PWidX&T*e}2mC4A7OY6_h%g^rwm{|v(hj=SqFZ;hdO?y) zcVeKu)DZ6TFsng~dVK`6>#km*>PM5o z#cei~O8M<4y41$^ha`9^Yc{t52^NP z-cJtq9{t(KHm+Mf#nt_NdF%xxk^_D^PrsgX?{%1=Ry6qIE|~D}T503ON_`Lh=lw-S zu5-{V4MgvF3nqhEBBB5 z@I9s+{$~gt^|IaUvgFe_fn}@1n?TF-HP$01a?5 zBNiJh;63@^j7jFZUDPi)H9N$`{KbM6#cP}t?MKR7%Z7wA$K~Yq>rj$ zh;D>mT^-^m2d9l0S`HxD(_QE3c&tWA=am^p9g(%M1Pr@((^4Ta9-zF4v-=&+JZRA% z_b;w;Z{6U2#1NTcU3(u$4krnl+e1wn_5P#51S9880%t3OWFr7u(u(z+ysWV4Mmf>nPcl5YpRtksaH*=c@U2~r%r=T z1&i!>^bS(&RAK3h;USGvjbIT#s#&gw9T!goi9K+CFc@2PKikq$s04d(>KOf1Z#Z@x z>^)PyNEeigNy{1GX6_1D+Unatt7@`YLfva9AwAlrA_~Adh0|F&F~n5e#s9%Gg9V3i z8C*Bq?NZXLRNXWA3s1qxuTuiHf;)3~xa7L&s$Pmp23UWCQ&9w+pyu3nbNV$r2_@2h zefN9U(VB>3B-(-mRDpzdsHW1_Ol~6dW`^&(&k4Ih(j>x#Ir(_HC$BGc4cZc-vD)ZT z=|?!uj0xu?#}i}0CnVII-UVM5M<|VyDzX8uP!9pGT1#cA_Q+w;(gtqc%xdD{vt)4K z7Fm7_olF;Zgs@FU6Ez7MdE%F+)7`x+p6WcMq^S;P6H9BGf_ZS1i1Il6ht-mOI7fZ> zcN4{N@5<4YR|#fuWlOd&Je_Y<{%Vtva8LOmTVM8vqd60t+R8s;umHuOMaLEO9`M}3WX4Kr#I4BHr>rGC@lNLaE zp-yU_`*k{uOiNyAl#r5Z6<8A#EwxYo|y z3+I>$oJkI-Cea$m)Fp!_!_C<}3_8(Wq(~(ZEP_T3Z`VXLqlnWhA$ zOu~$WrUZH(zV6ZU(ph}nul@iTnxx%nS?9IAXk>7CVB!=fDQqX2Q(>>1b1+M{cZ6d6 zx{6Q2P09>j(4=XM%Uh?v=wN5CWFI-hXb{g3-tDf)3zPB4mMmL}^76-2a2(e9N1D^G z<5|w%??-r_Hp-um!fMz9awG*`>X3hz@y9MtS6Tzt+NKS6>!H5fX`!A~=6&(V31D231+MQAWJ zlfamhW+{9)fbd?$NudndAOl1!448+8ZM`R!3adQMOzy0tB6)Ws5q{w*%SWd zE1(F6Dk8t7n{r>l2o*P#TGzSf(7VoEfctaw2=OD4M|wj%{Tj2pI&bOEtf1oCYWhgz zH3aBD(<;xe7tb@^iXlI*D_?w%POwK)d-_#&SiBl5S#Asb&l!;(gRe;=6v$24(<}Iq$wwok zf5GBO-p=9-NU}L`bxQ^$ksDh78&LQ>v^oiG4Pj&Yuawt_tBN9P5ubfNRXGY^o$!HbzPhUpx@PdyH(p1C>H*# z+-8a>BQZcG*@R!EHGnh|=)NlN6jX9(PHFh_#wbT3^^e5UW3kke@y@@>@-!-ej%v`S zj1}JUG&adwp8gO!i=&J$$9it4w5nC7r^v|i^tu$5f5!5Z!ggd1r`m5e64SZ-Uh?x^ zm=xH-+7;<%fmBTN%dHz72VWwsCQj9>6#(_D-Nf}3?zU_6~d>I}B2KgWa15zf!y zAnBqu3{>gggXAIQgEL3QsWpU$_qP3@##-5(DiZi!G-Kq#npt4rTbjqU1q0Mp3UCh< zDg15=R3B-j51RQ2&x!ka6O@KYZpE!ho6nPHaun*>{k1AYDuCD)ae$zFP*IY~W%FC2 zSuX&?-~1Xa0l6nM$*d%rkj|!FODj^3F)t1A6YD+(%8d-lVt{_;v&7$_Y*S*ZW|cum z1-p{y54#ehcN7T>n@sXC%-2Rw!sK~A)Svo>8BZ%H)_9gk5 zeOm(=*_iNP_@pUIxQ|Etaz9c}3yZ~}ij+wdnt92|2N~)jn-V%0V$7MFutf~e=Xub&D};(#YOqkJX6Bu`FJ-_ui(xAg~7H29$z} zn}U^9;$9MG4b0St>986-mM83I`DL`snxui@N}_qi zR`t`SEAzC}2^AvA?k{6R=l&ro;~S#d1K<59rJx|WluOQ8Fx`b#S!OOk9x?oJDU zd7IIJC$rk~lEmyqv@wO3kEbQZuo&&ZoQZYo{)uD=0<_ z?N9)0RCr_H6^(~tGjHs`P1-By=fQ(y$^8PWQ*VB=#Vef}Y1s;-w`nuQPP=F&BC(K^ zKRmtPv`{LSxiqSBj-VFmICl_m+iQzc@wbmj#jN_6J_L50M{5 zg{iql~!i|y&+9fxPew9rY za2PFPxxYm6wfB-NZE}=foVg}DH?rI4j5RE&o+p-M$NeJB7gqBc&H;s|L6YrQgcvL2 zZWfW?Yv`j6hfT7U=twjVQ@*ZdgbqEo2kvHphC?uduu_F%&z`0;cG6EvhxPQYW8Tgw z4bG;*_xwt0RVSCVHodpNg~zW=hiKslM^6*ire|`94onI)5f6x#rIBSQfswX-P&;WH zGCEbRuD0<1cc~z?-z3JatgLA5Y3vp_(KewJCt7A{9jfydRZak5=qNwOe@htIy0n?w zQMo&@Peu9*8e;>`NG9sSh+^e}96;FCGcTbh|1BcvXniD-h9VtF>qu*)C=0dd;;+cX ziYBsCm2vXm0Ss@Sjk*u(%*^yu6-^#R4gr6)p8rD!Zd(xX#j4Wb;?YV-kxCC z)RKZJd7w^SiH6WkF(D00HgNB^(koP&i@}|;7&xZDedV#GzsZHrK!Kk(riaGa3-AOH z3!Z>e=X$Uxn158Ekm2d!2UVwm)i<=$p^zqDa2#f|jmhBLDmxzS7yA;$Wfx!?pd;vZ zoNEuSyZ|qS9IT*VetEBF86@X}_}>vxQ?;}%(X8c|&PDKcMJp(^ zD(agPp~tKztO4pmBSJg{8>Dj1Gr=6NXOI+&oUp_nvN>M*q^7t$v`z!=M7`U}TzYk` z0wAG3zy5Zn&PcHs;UzQN;%CvugUh6T&emiOg;4bMm(_ z9lqN>@Htu>zC%p&_4Jn9b%-FzS65?mHCM1t+*3y+cZ8q0w6IwJjI8k5O66?Jst2D_ znP?|tKD#j^cI-%MMM0m(S;GLto49Wj_Zz(EcK?c8?s`gE6&XGvf!Wml07^NZf_0M%_;@nWvg0O5i-?9h&ZAu-UgDx3F!IRusG=m%nv zJZvetM1H!DuMX#3ZlcFtL=Z3MNRC)5syjda>`w0Ap4Ju``1iMsfBG!l$Jjv4t+^M? zilLq48ZuBS84psZ-$80?MKTLG&|K$0MY4YV(vjT0WO3Whcd&={Uu6Ea+h+52oWh99 zj&meqnA^kloPcMEk zm5SN`N9Sx>v4_~ZXq2Sjm_apsMa-Qyxwb}|$1$3}jnd6@2ii^^nVTFANK z)gToh>B)m%n-c4)p##K}zhCVzqlJ1_j?CW+EnH>cX(hS0kxWjXI_1rB!Bn3MwSLkX z5S7t}uyOV_JtdsTB)$m-2MmL=!Pfu?T;JF=uw;Ll{Xar!6cg+IK9%TfGw$o^2Ul#$ z{Yq1%u|#{=cj-oP?lWZA`DCt5jrsdj&FKd{mCg4TtDJv^#Q-+mKSRGE)*a5)WD&*d zuwoy-;lrm-yb~pV4M$Q5Dr)$1Qk}mBTr+_gSu0siNgM0>U>QWm@5lJnz0PHy)#zzP z-pl`z*xb$ar7JEfa@C+?4boSl*;V<(WINWNxbQvayZL3n)jHsqXM%mgjim(hwczhz z_(!rYo4G zdaJtX>R3>dWDcH9F5#<1tst}N37d@K5IR_vX4m1{uXYNFo2zJcV2Pv8B!<(!G_|B( z6;R}o%s#0A1}hF>FXyTwI@YXK5z)GC(iVKSG*gwwdi%?YOeR^jXu>zBWrU?uF_Y_` zpUj&^7#@WP@-3I@E6)nHUE$Z(Q4b6?;xBW;L%zqD0S`ni>u($R+hW~y292*8g+nWI z=e{7k@LwPiGRe}`^>4&S0E!%<3*EV+nX3_hD;5XLu7^t9eYp9jxkE3%K=>5-7s)+B zctVlyP(-)y4)sMcRs=TT554peF6f7j@Xi6WY+2#r+j8YG`67!HE<7AgL<3)^dY~`r zNmcomTpXKpxTCWfzkmv4{*py&+UXU!6k)4R!!pNqk3l!~Q#VUAM(FlfsH0(ZSdV69 z_}E_iz&VVw>-snZQ>~nuvYcnm4{VfQeBHy0DZyRKawIxW?YNN+M~>OkMkjXx*opk- zmvR3AzCS6mKaegf)Z!SD1k*BTI$k0yRF!wzFK&!Pv~=Gsv%)uiapkUD6}9%-6z^)r zhKd67etyK1i~c!%rof+#A(|JR#~A*jsQ%ny-xVA>zv3kc9dT!A^ipBgS=cQS?Hu_C z3E`pfiR?N@jlUl|4R*aLoUBxx#R6iA=Y3YJ@d5K$v6evN?3bO-ip|brg_PW`)0Lo$ z>Wlf1(}rc2i4Q7dlQwqNMmYLcio8%n^exW574Y(${gVL1non`zN9H@uu8!%z+7Q2X zU`-u@#jE4vSp3DkMSdcNzc2o7{uF*dMsuxE$%i2Bew2?y@bS`k`YE?^g8dKeI*o}c zA$FgAu?`ZK2r4%cGy|$k)OniXW6pRHAa@pWIv^{ciKe4&o{7-&k*qcqS-LS%{|M9I z@VDb^Lm?afmb-yyPj3?@??-4^XY4Neh@0=HNB&kS&@VN!ECxnauujxqJHM` zk4Lp7>gTNZDs3#isQBji&!pm{cO-(7@tLx*F<5X$X(E{3%6+%8+`-gt{3bi4z|}e^ zpjxW3QwnQ~&l4H7lM#?BV@5+=Um+oP0cbRMyIc5DH@nX#K68M?^x1rwnEq&yn7-ki z(@Me@zE=>@y+r72|3ElMtjXxnBzLJiS|PW~$YBZw{gyAr3kMXMrBGfZX=)iy46oVS z3F*&K>e9U+th2Y8gg!vrxtU0!w4E_gM7tW;(M3e>LpBq=CYN(Y1*+YI^8oF_;+}ci zLDk~mFa|9%JlU$Dk85j`FTCV4Ec!DCs5hbpF=aIr4?e~oq+&Igjj`Le$GLh@HyAJ7 z9!FD3)IF@NM5%1Z0v6HHOu{0050MlF1J-gKN4~bF^pY@~Lj}lpu zm4e9m#9KDR?D`Ox?*oX~jig`PtF|-&o7=ROL^BJ@y1+#T8sN93{>T;{Q zap`8awqhN2kkv|UQLWZXMr9GT<7;p_L%=x$y9(%rLe?XMtJ%akGopQOV~Ta`(<`k- zyw(xE8wea~K#Qq20U@YN@S|IVDxzU&P{VBz>O>9#*?=|PvzU-#^=q-{Qyw_Gek}5a zSUF-F_I!OGsw8OMyhc^0l~$riD5xwG3>2S}uPof}!m^TFJ!~X1CDI5Eh!985)~VGX z+KqBDjY*RpWpEgm&Gw64FhD+r&=uLfRk@i++Q~9 zo=(UBB{~}+DO(uQU}ra!D02L&YE6elccNWIl--<@nHUb1ZZ@ z29;y4-R4NR99xwmccPtd-@&)Av=%Jo)gyW7Q^3@ttpplpzv0v)j_k5YCyZupHiKp6 z2xlZSg{d2iD4ja@aXVQ^fu$Wp&gOjvVhQ`S`d>DCut) z{B2ykOfKeQCHEBZItk?l6I)%C_l+b(+9mJqGg+?-u3jI5l5wq3N%yvbe-DTE!d+H2 zU&j)`!Vi_0waEDvY7CA%GD!TyxRp&a>8bJc&zGfw8GWyLE@oP4P}xEll|}4umOQF& zOT^~BSUR9^ZMXeYb3qpRBpzuo<6QD1C0~Qg!iC?$MM5y6nJCw=)k3C^sF9%ZwZD;f zvv}tC$!?YFPj&b{s>tlexrW2Bf^#OCuGeplrNU%3UO^L@4{D0-hS=>dChDI@J?8lU zyq(3S%~pYR6wncfJro!qkhX=M=3}D1dd2%Wh`#h=g~2ZPBKs)gUaU`wfD-k!vEY+j z>Cy4^?t8GQ6iU9Nk(>@FxoMPCyk@pqRY|F^b+J{KvZv3x&Vo3$`m+S0@@{|?V^#l^ zd84Fd6m<+h)AF-Q717RK@#=aH`@h#LB_9-YhzMKu2U|yh@^! z!y)C^p|c%t>5pC%A_qF3{dot)4{iGB(b(0WqA3iBW3g+__0+c*n8Xy+L;7KIX%3SQ zgZJTrxy7gJyVbrCTuCyhkmYV6pj3^GZn6|)rn$PBMY8FD4Wx_Y1|XHOSDfrHwMvXk zf}}d!cQ$%#Ja+Uz?5fK^o)lT$nmR(dZ0xETD_~umUkRExkeQ!Oh{Z_d51?EOs zU}C61anM(y{>7EQP{jgCn-SK!m)YPz7+y@0&~7NYbYD&vISW&M(Ad+^AcBJ-ey9}_ z>yi_ThB3-tWqP<9Pdz1Yo`%x-rx-V;YiY4DSZZEyG)&TV)N}43Y&b2LeAKDIk+pPJ z+C!qw)-ReKrv|AHp>6(!uGJbMp3I7V zIp?SDQI+uIrHufz&o}1=HKCOGnO1vr&Pz%>k*-OYkV>f{DVnxMF^yhi>ZolY?pSrs z!lXKvY!JF~mBT50vUDO+yH0{@N&-tpn-{}45jrMl-SGS<8C>!(3Z&ylWR}vA3Z`Gd zmj915&%b~zSD*|UDCUc9hver0*5!p#c)e#3dfTJk(h1EPLD{O3;v4GvBHeZ%(sXb2 zL;7@wN)XwgVw$-Mm^!@3=P+Q2wC<~Kc*9WR=5_~-jY;l{Rgd$B0U7mDIcd~+2{tbN zEDnEqDjqxd!fnhDW{Ie0BHaONP$y$RgIbjhuUhc5>BO_BL}H*tD?;m2khtm{+rGC$ zPn1?(>vFFT*dX@!z?|@v{hZec(WTi_-$FC)c-h3yb^LH?0m@otAoH;}`mhBG_ZJ+o z>A;BKR@WSK;J_lI=8fnGxK)mC-j;|FEP3k6qdV!d8JZh>z^xm7pgNrPrG28S_K??q zDBh265#P$p=^SH=bzh~z;zmGQKmW1O;dS{A!H0y)$ zxW8E3je~Hl;Di%9`B!;7*VKAgXF$!1K;`zF(^s5~1^r4AxNbEOZvP%$h}vvW;=ia45B-booA+)g)!;HjYbvXN>PZoUSMXti%Gp9rTl`%8BbPxen+#p2 z+le8l!ngHh>QCBAoP7CK7Z$g=hO9}Dycb2i{Z^ZAxjxK^BKbw6XZEX~7VG{wXG{&h z3}{GoT{cEVv!^%J~a^8eVrAh9}+zIFK zunmcxBM_UZ#>aZqSQTeW zUX<3oKW*i1WXZ#v8sc03a$oZIiCf7B6>!=bmGH{AUwuiKh$BtS+SJU|5pR0l7L5X( zZ&2qUMKKfI0-Zwv*`q}>?KMC>pKZ#Wgf9#Zjt1{?Rz|Kxm4&B# zJkPVnt8-h`f@^8KTE_&-9qH+#4G4tMl@;~tW2=rcxE%Y+me6PK%KuufIf-)B(P*|s zQ!T@z4IYbz<&xYYk#X>$g)gWV?mz-VMfV*IKpqioKs_Q4$W1Cvfi}V&H(qJh7g3uy zl+hWAkIC?00SZr=tHVz;%ZrygCm!BH5muf9v$xx=sKX%+48N4;kiC{G=j~vXa`bx? z>uS{ze#UqmEi)`gZVW5_JN6B(nc{~Ih;+0ruX07ImdHh%-HxP^sYm4rTV{IGr!Wl( zAuN?B5YMLwlL z0S&3sR0*{D0Q??Dk_z~_CEKx0E9$6KVzuRD83aq^Wx5u_73o|pO70a9 zj8&^97xECqI!>$rh;?#L0n=`imfZ`|1|I;Ck-Dt)VPWPEN7a0Eu_E}3--zi3gzvU&-}@-qPXzs6P&%Wih%5u8a?bOZV|?ZJ5#`3v&dqc zQPSy4h4v6T-v9Bch(N{-S}DgRhk$GC35vc~$SK@Yhzh>!I70*rBB zv|>%Z*eIjoDAOIRm@Rm8xaMlEphb4I(LaK>_A3i^wZ9P|MJ=35q|9fy**V+!KzfZN zS=9z)OM69sILk+x9)iTC#;vZid6hwDDt}1}nA6^fUGo#W?#6`&fDyfVnnqD|x>;mS zn@G==VU*sgkOfMpL1?Z8N#o3EL1hxa#93#N#Y}1gd?0cW;95RVNb}2-MEw$39e(LA zlQn73=4UWGW*E$zBteXgtz0qcs8n!&YmNn{*p?WI>_|`Zqt?c)Ep1{y$~Z7nS9K{B zQ`%axrQfp2t&1_5S-Lf&)vMVC2oF!S`I*_TZi6oPRG#$*Z8^WjXV38 z9~XxN#-c*iiQ!-yE7-@}K!GZi4bH&!%p*vQlhmoLL?r^rCOC-2!QF||M)*C>s>jf^ z5W^)~E?lr!qT|Wn$SeYJh*)(VRn>hml!{`Btm`|ETC$gdYB0$IoVqAt<}fb|FcZ|);(8<{_Q+N50PS?q3=Vd*E#jI6ww%WZzm$6MI1-W z4HgcWN9b$KIw{62Izj8jaRQea7}HCxWA(q}3Y}ezb!{wn#Wi`&ekFQF>_0*wsdsI% zdqly60%QhF+r0YSvn2@lub>lAvWe<}T;kRu#0VnK_m$ z+ZX)Pjf?M%IIFTXC|iXO7|gSLpf=pQ)ET*q0)!@6y7Ja6YSd7olvO-sO4;9^lwRxW z?*sI_@}*eAn6*j`%c4Ffi<>uCjH<|Qu!xpb*l;%B1IA$7Xo#_#zQ9abHj!docTT2+ zAFU#`k(p)QD?TTDa3_8M=tME7G~B`QzMLUP_1!C9!726hr$hQF1!k0sYM2b2HREMD1BCTzEQ(3oj? zhl^m3acAo&_)F6$fz6GX^WJGppN(_$)PAMj685<#G)nWhCZ_9e3@1e4hhDRryFVg> z=uUh;&4)Lhs=Fvoeme_Svm`nuRDr3U{d%xEJ zG!Zg;vEuHoK^OA&2~|BJOva9$6T9+25>mm3Htqn-Jhig0(D?r=QGampl~8nWybdqcH&G9q6170MthhXy5^CqaGp(zP}MAwX7kY5lcJNg zj8#c)AC^Le{4DslJ+6}`PSMx&X`lfuee~@P_ysd=BoAw#Z!0U@V3r*p(Vyz@%;k7lfw?(dtOp_rDYIcsSyZ|_4Nh#kEpc9r~SpycSv zJ1)m*B=;9A5bpetV|ehQJpazKZngr%*T>saHKRR`F4$Aw&DSUJ=sbHD^DgGmyJztc zugMm$>xjIj~qeMH)UNNQ&1GzC<1#s_&Jeg_T+p(i@n_3~| z)yNjx(OzTOqIlI94KnsK9XvG}mgn``A3^@$CCf7^WtaSnvfIR^cwPa|Q(q*`3z|4o zSRMZU#4>}$iSs858~|A`N2-HK=SbT2SNmYELYL+bNA|oX5W!}BiaJ;wwWRugUFNhE zp;}J9ySFXEkIj7?5AZy7s3*h^_e1Q49t!d{uQyp(x+8Y;@fj`;?oH{3 z^iXYl9v1~u>5bmN)A>?^ci=uKXt@T8FK2Y>`7`t9>w_6jJd6-%|G;?n?L*`@Gmm&D z8jM+bN`O$ROg!62EZ^xr@c>N04vFu%_IfUV&rEjX?;trEuAHV*_#5Mysahe7PP+6{ zDoQup9X|$lfNCN`h6_QpO+Xax`+@)Du)J9^1kSshy5c*aY3J|k%-N(0$yiuP&kG#4 zu%i*Nvj*$;U;a9;r;oHru=wT{er(=G{%>0oT`=J}sb$LW~-*)rv{lm8@uHX=2hH zcRCoR>#W@DD5$aU>!0YtQeL}-bI#~ltT6EqxR7eJws5XeRle3|mn;lH1y_~JmBJ#k)XWiAwkN@5FG|!YYjBU+`tDStyZMhMWFOv*0swTcd%Hy5fH!= zWox1}_WS+56F^Eh`$PsXtp708lr6+_LYcjz=-irtLf7%=oOB95R}9v91N_I8^Ry}Q zc-TQzCoQj880)?iHk>;dacPvY*;C39M6h981DRYf2U%NH`SSCe)trflO(65WuA z5E*e<68L}NE0SGHtMDQ81DTf|P6dmr>fYjkb4cA)tYYNV& z;#zrwm=j`e4Jr8|m?gp|4^u98QUfql($v-zJfZF_Db6aQnbyItZ;Krw>I?Td27!;- z0<=;KxchGNMpH((WgUC{{io5KYHx^&1})X%_^MT%HF<px1g&9 zRW*A43#8g?+mFWd(O})9u36z-^8_p7GGQ#jD`-^L1{bApGqTu_l-BVW%fHSRDtw{_sW|KMiCkDB5|Yt7n1SuTw4oGn)djO@)d9RkcVJaNn=f|!Du z9>bM|^$<6K5qY&Z6c!~<0&HtWTYYY)P0=Sdmp<$cJMA^d(p@jv9>QB4I?F612+N0ImI-AT?B=PpYjt0ZA7dB8wy+~^BOdmhwsa- zivOae$+TpXTcAf}FRw0Rp$UMY`ZJ!hhR?uuL8{&0&6j9aiR>AYK%n#7(jqSFuS(!= zrNCviEiUgm9m)=$T^#FvulVevTHBdDR`MH~8@mf@A3N{F3jq^0F2b!k&~uX!OZa4k zyb!nmq}qKSWmF6GIv)nP`NTx$ZAHu%6E-GJ)h6pD(#3!P_cUM4I!5~{b^Nwy3pW#z|BW?sJxUFZrv!<(^|^;5(rkYe{rLr)cGn-$G7O6mKK1uz5Txd?UP; zL6BP1w(+Y?M3nWPNV8Pp(G0Qk{Y-qj$S{<`ZM}>OM)?@_&lg z+a+&xW5tnK)A{?Q^ABHLfJJJ5Kjk=}!&h`)x#bVgZOsOHMWX)U*s3N)wPSxhn(3n_ zp>Ru*9JD1>Q&uXV^t9y8?UA^%_n(}qjRzA3r;qd?J{I5ks@7gS@EPm60S?>L&XI=O zth8b6I<*tKJ(MxJm7d7{5mHpX21Qm$7A3*Fa(Z!_4UK!w0G>qpR)N4)kg*>?8c;ZP zI}G7wANN+WH0wrIY)n4>$+p9aU2n%JRL!8m!6{QW2}!)o*LS+_nR|GUm?pgZso#3H(3_bC_ZWOC)@8{zx)ELazCZZ|03N)Tft+=OA% zI4%ZDHlT}ao)IH@x0qIt1!fSf;v?_{)--mO2u>uVG1MokcA%H`AnDR?zxNpK!q9vPezko+_l;PXXk2y%0p>FfT~~i(I$HJU@fSbl>nzU zV=nrYYYr*ynsX=RTyxw_+aQEvwQ&1XR)JVuiw-;Y863t@x>zMDNI9*Vg5LEx2-d)|_#X}gbs~}Ie0Yx&xuZDTedM%sEzoj3* zoI}+)zQ>Pnq^lK1Sg3TQv72EIkG)M@vEqZA-=SGeW&WY4m3;=#i!q zdMwvN8PPDQ6HBBH5E<=2FcNDm=;((PSzM3YlWPaj(hf9N5~YK>ytK%;@$I+2N9Re!R17Y8 zX$xjl4rnNEc2f*qB`(oNGb9~KQl#}1v!V_qv$T~Ll*sf>l(8qfl99g6;WT1vungh0 zUt^T#ea5f~d`=TijcJTvSm)3!xukEfkuly4|1shb69Ui1b>J2{+^%7QEK4b5+(-N) zC_j^+<36yG6#HN5w)l#an^5gAMAj~&;y9CSkq4Cr3aOeW#?inJD&O|u0!vc;1(u}oLK%g8>{NuAy7Fy)5KueZr*lifzu8Fjq0Qg5Is z&2Ruy%j5adx}4)n;yA3-#F_^9WX2omPGJQWY(k- zR}%R$4T7izW2;XLzh^d8qt)*?JE{Q?|DnK%}UBx zw-77{SuAhW16$%;!dBAUU<7Gaz$n&Fz5YsreUfbb)syI8A!1GjExDG5KD zwH$t3T`g_1eLHN!IVtm;0zp&sVni?r7(0 zTqkT|`ypix0-%Ug!-`rp4{%X9H-?!r7!b!9m7-G-DHs}3sx&v>pLhP;zu_+8LgJO`x2!& zQJB%S4z2NCj|fh(l&NXcgHg{DoFB1=$IY%}F!>mfiWAvFm+pEp%c@nENnzcSg{9aq z+WhjA1+A`^Lzh09< zLO@;9934IeZ_kaVBRsUF5y`BTg#BAcASIQ9WnXb4M^VJxS zNY^jYs>O_>C6zF1@(OY@SQ+zWEZXKhrf2 z&m33}G;{u)B9`?@u_Pz>m=+fkDWYc*0;88k1%3*R9Z8M?TlH*~>?{(+T%*Bnrdh~H1qW@oLxjIT49fMj(K9F> z1+tnV#^w1fYS}-S$3bca6oBg?E!_3?z(TqKXVrjbiMRImlKD$I+EcG>p?NntD0 z@UdHqq0LXY$RUm~QsDJ)`mqA;pmIN}6kt7{1%XjVRE?8A?b}5`cws7HMJ5VM*^ZjA z_2=#R$YXc$f_4 zRhqna6l@stl84c7E0T!fjnm}E2-muK@hmbo3E`xb%}i#Sm@ji_mO%408_iK+UNVc= zkYtq){){m=xX&?3%?NcyQ#tfiSQRAx9;Y~%Fn1Op579!AvLR&Fd_3eC=QgVjb|El{z}Ilnu>f{ ziq~GNyyjemo~)o6Ir zKE$p^d}|UGhcdMLv3^{fl;rx^oN@Bd!7FF8mT`at8ETb5>_Hu8O0a>*8q?vy6nXK; zYSO}+-avmS+zr;Qhp8sBAFq{w!?{yEQHqW^Q6Tp&SG|u4I!DW5 z-9IF!UM4W52R8ldpGwv0s=*CK$$JL;^3w5$pz=o~8qXJ)okM%&8F%NvX+5q?zWaIB z0L(3lHM|i(h&p7dYu3*QcbEdoQ)Q7T9&lUoX#nlclKaH`y{i zynFah^EqMg2Y;e!UkUGg$qoK$vJ|;o&K*tINU-a4zTi3stBxYP{D2DnAzrRi?R0pN z!^`VMc$xdZgqP#215#VY;pO>nckRkOD`LmrymvG2_~UyiApU5MT8n(MrXnZXA7@)= zD+m^I>=UA4mOXSpcLl|N!}Rb(W+``Qn{E@c%!Z#Q6~gMWl3gah_+y08buZp(8_7LX z!?FCMiNZE()NPw!!HidLbqc9^9R5pA-FGV|nU0i4Cf}0)w|L5YdK|xW{CnkO z9Vy~PFMBi1t%BJUKKu>+dAnFRh%z)?n9RoBmhqiPS1GzppY^j=9H`qq2U$l765}Pd zKBN10i!I~K6*HCbH4?IA93md;uLR=UM#2&K$@lBQ%Jh(BDqIu%E@3BslqyH9iOdwK z=E6jy&Io)*)f5B}HbnfLMC)=k0VIILr^EM-NB~8MLl9M#O+gS{KzW1L$&(Ren3pFS zHdST3oEB7zEeq7PV}ZVIV}a_6#$SQzu##nwW~qV}A29J#0BXlA4&}-lA%cS-IySx~c6C6kyO-Fh z;#A|t-_o(JjGikSk0foPcxu6uiNUWD~&dM-wTAs_p z)-4xc8Uh$V;j4hxS%j3^>BkX*HRut2a)1Eh#QsHR=TA5CH_F`Z`WPUd(#r z~*PoKdb_{^5+5Vjr2$X#OM zqHq>t!36Puz=uX)D37@pG@ZMOAi5E4HaZEh7?TR7o^QyuNp+9TJOa>-@;V*x-Iw$ zjw{bGahRZYWkT~1$u8rClC$7$9mUGP+UGF*=N#}4)=+}Vz z%IdAo+gh-UN_thd2G7=YCWJ9sIuns9G)zT8*dZxu#*jro1aC+Sd!N+J99z%1rQwK@ zIJ(vkKKQh6>7w?{Y+s`|stA3)wMA)WAs}r?X-t4V<)uuIFC%;^+~LE9dth3o3PmS^ zX|VzWKCnmuO--e=DIlaOVA6lB5191t^8u6oYkZ(VWqN(Uq<@bOnDk#vAWvP?YFfY| zpQAcF=5FWbsOu>p)-bQE)U6u90NYAW5&w#op?@Ze$>rPm&~gh|{M|mtl%X(bB55oR zrlqKP?o>M><_@2$O<^yjP1L%jsLH4pTRm9T*$6?_*$$s#on7VwT7e#}n(3DHHNu?r zQEe%uI{Zu8Ek_55DVE5&Zz6hQS|1pFcl8iNBDF~%yWS0a@4wT#fA_h3?@YS--f2Pk zKj>XbHUAgA>%Epm?TwLAF1|g z5*875N6`3i2PFBp*`_@ow;A`~152VS%(gNgI30ES-N{V1rn2K*Ve`|rIvykjKGzlU zi`AAD#j=FIhtw0JG^am#&~HGKRU6g=azC?=i*MjNc#nPiiu1B{82;wtkQ~l@C2Qnl za_7Z=@Eub$6c?@@apGS{`^U~?xQi7bpf*B4ZG?c@2mvg&9Rg|{0^W6Ti#}D2lfJ=> z5?~2G{FF1jyk?@*!w>l0Kg>yd<+}yP_71V#n|?kw#Ne_z(1%Jqaat2lyFT6V~t0N&V|c1cYe7X?ODV1W1w-=UpVdi_M~ zUIjQC+V1>rCc0b zaEt7c8XwG$3)<{TTK6`xZH3TV)a-z&=nSiDyM!)Ea_Mp7AhD%Fmic9o$l;=Fja`)0 zp zZfZIpQt4YdNTzr4FG2=8gn!WAzfIRW2dY$j9g$);1N!xGLwq*{rvtn5`UM~V0Yy@o zphLOPXjDooZ}D&3=jqYfHIv}tlH;6a z^%<~Bxr$^=Fcq|-@C|X1Og9if)LNxOth_?f3t?8ZkLd4dD3tSFQ0ufj1V~fd_j#L0 zZ9R3AzW|e}AC7hL;0P0B2&IfU@Kh@OWZjNr=?=V4Y~jKhC8tq4ec4dO`=jbyQ%F_6 zPt9+Y1_ZO1XS1u6ERKCf)fp9|y5yp1`ecSLfZV0D@3qc#N zA6VWpo0sE`+6Ew#C{i_Vi(vW$_uc1hiG6!L+Wq5v{sFKyUbd&&(#&q9&lheWZT+R| zRF^K-`TAC@`o_e&AlO2c$=pV(DzK~2=KjcI%I6R|6Y2{LM;`_3^ONIXT@j*3B( z+zNP6XCWPvGYW(pljP7w+uh$3@tN7CyMrjBWT-P4k!gdY$^*Jd3(Bu0J5wQ*$!9k8 zX2>e5{Gux3eNta%b@->ZI(O;T%fXx^5OBHgu`bdfg#iNbV3~Qu6@Hx&RH~s!5zbQ! zZnq143u}b=CLz?1`Ho(&T^47QUBr1igx>QQgH}CJ zHSO%tc>UY4uG=WBdOuN(!Heg@*{)FV)LJpZcc}9L0Z?4;@V@@MIrTSHsaIc}N&181 z2$k4lNI$iLYUXjti+RY$8{}>s(WMzC#(C^|MZ`)w>jhqxKe|EMIw(s0ZmRTch_fnH zx}~XeeMRmFC{q$bh{`QTz@;*`bnp#_Sa}hxVatniDIMOBVn(rxt=gV$3Q~Jl$$m%< z{ZCf#XJ3Grcc1<+H(EV0)-s>Y`>n#4l?$2yy2PBDHp%!20No2uHHJ!~O~I0ys$_7` zl{aYHPx`9nNJvT?$4SrzhYod&f}tEG(vy)_qM`>##Yyps6<#+oNoNaHwcdzjy6g^uS9@q9e+YHY!y z>MI>=88Mcj_kHimPZt~~h@%&#iw-~7%R4q_)S-smOprIOa3JSiMm)=a2-GWBwV-9T z=}1fueG^HUbPMK9sfzgTa13s-{c9f-(v$UrOO613&(AeZ>-7g_VuQ8e(npj{og?eg z$4EQsv9C>9GF_Dk-IV43g$%BqFI*xaz8sOx<*xx!6|*ea*=3BRLS?opmI#%tNS3;T zMatf<1RjIv;5XL&EqoH@UdNRFKgH4@_2q?|?CkFzSIyu5h4IW?MD1eGxqDecNk2Ot z_=7XYW)BRP=`Dlo8R~J0YTzJTE z9xIUtunTG-^2>kWIV0_hX`Cgot0Cc79U~xiHZ6QZMSbVw2zB>`A@QnEwydB`UqCAFotr(Up8haO-46i|6ma}XHJgnt-cLJ0rSWJ@3A4j+ z@l?xtXG9V8x>+i_yjaf&F($aAdNojWN%;D4Aep9?eljyPUO$<~t{<^X3v^YM3#%w| zwizPCs@_OQsv5Ioh)XFjE1GNynE1=L7LKeC^wUm=AkW<(Wj!drxz~`Tey(xG=4lkMtM)}rb{{u z>-yz%QL6rL_pAQ~M9*O$pBdryi<{FActV-iq{qqKG#FgXG)P5{muo)k5R#b>qG2t8 z*ID>BTLEjuJwVt^iSXkOU@}kJD^qL9ZBHw|vGlMB^!P=ZKxT*UC%5{q3MOPpkp;~% zoaD3IN)~ORE;}PyLCe5o_DS7(5MS>eNZ*HNka+!mv1|33isD;|S440x5yf+CuOgDy z>RGcjKg<5K%2v;c3(x+OTRp4OT0IZ&%bXKV#?86n`SjBXo#~)Hb>{f{-TXV2Q7D?? zHpPmM@O<9V3-;&p39C1YU2m3G+eHr-SaDdfg=IE5ZT`Xl{VAJ+`C@mO5k&o<435iq zN$FwjiZY+aY(5u^%Oj#eKc8>J9&Iks+a{UdgTfmt=(n`4!(WAXm&$6#lzy5*s(u~S zM;9phq|X!H+aZz#bWb33_=%^HQ=mFL_uG^CVlM042^XBGu*VYRxCDlvu^cz0?KFf2 zNxGyaM848C0>J0=Em!+zI~7!7*Y$9Iih9cF$N z)R09cl$$f=v}R7Y{0JFJ@PIlsGliv5TAXhweRAZKy9rW(gi@8fMg{23P7^m`4u%{O3I64fZZO>z`!MG}KQpwJj+PpD!fc_*i zD=>OA*NUAh+|)ihmAR>#U+Aghfa!+cpn6RiClWbZOfW~aiYyff^;&Rcf>7`d-_ z+_w1M(uQ37M!CV|D1Geq-z7^2rTlYYswtb8YP^uSxJHn5-L1^nwfYFjGn;@HoobnR z&{I8*uPoEbQt*m^M@8QewCyFbfVDAre7W%blB@;Z$cFkEg)?Ybs8REcip~pYrE`Qx6*yx z>TYe9TDu!Ak|16{R03*^SapVYiJ%fL!u$RG&+|+sh}+w~pVyCMp38a8<$wO?e?R|Y z-@6d-M1+H#D^5&wPPUp5(MBK7%uLubnUixi^)qqH_Co0;O)D4jkz37BpuIdcboPR8 zK{<2wKn34{|ype z)b07#h>l*H&l`z+ zm)~I`jpx>_b0XJQpp>1%S^t5e2; z@l}Xhwi`j^1`|Jx7eT;Q@!qMJ;pzua(J{}r2AO1fxKLRCO`>+}-h9rqGMDR2g?;qAd7q+xM9@2&2 z)@%J0bU`FE?l;;(lID=kJk7vU{-h5wt{QgPrK9wuHW_&%97T3#I?|nt>=%(uM|Pwm zTY4Hj!CT*ZTx6QMdbgbcRyru&}FEA%F9WfS^jGQ~Ld?=8s@j023(wUBckaTjp zU-%Lbl*16fRHTD}j#fS?n|!4*YT6kPmWKXZ?JF&Z)gL~6P8&ZR_(eF@TaW0T+f`;A z7E!6`3VK8<>k^r@AT3ur#4Tks%P>7gUdWErQ>tF>(7}^J0r1rbjdmLEuzq5)JV^Jz zP!@=2PKV*mDw@$fn+!)(>MyET(XJHTdjW z^#sgNZy@&%!77E8HEy42LLzcFvGygIe50k8Fw*$?{`?36ga+u7 zEs5TTk@&V^dI|mKgXFzqc+LCh1&E0(I%^!V;H^uhnEI~A$a|9VoWO*X7lpc+lvn94 zZnwZxlk)1^lRJ$G^5kyQ4Y;_^)CVpeF#X5LrUSlslL@E%7EkzkiG)8Wv(Ai*w@;|g z_DQ_DO~N-Yb&??t@Qw20){`n)F=w4a28o9`9u>sH|GL@4Lp{s=+g2wYYE%*r-H;Fu z-H;Fu-H;FuC)h|358aTe!y)0_p5tDHL!zD~Jb9N08OBqpo5hJQJ_%oOF6AGN<+Fk` zncSGb7{W5?qIZ_z$2l&Mi(9{isAW>-$M{(DuVo@eFzL0$Q-pQC42SN)pX`1=|Ua4^zL~j={J?(HMsCp$;Rx4$MXi752w|c zoKXUO-$KEd^6Iy0_ff*X7GW&di^{r*`B#w7z06}+sqEHN0~iNJCNb%> zTAl(~rwjmDHW4$G_^w1PsJUzg1>}%tc{i6{V#+KNWb-)zFA<5(deT|4FR=d@^Rn7k zl0v}O!=+`gP?E!YxiL_8a{)@|CHHqaKt2p#(JoAt(x)l}@BYz3iNoC#7r23a?u-{( z4%SMp z4T`Lyx!z9=&@aQ+4~5fHz}InxuO~Wug)%s_CCGF^NtRSjPIM_?E3l8%_7fsQuQk{% zjVbeTh^TS@n-P%p3GlQe?VocYXEX@xfS6erdK9iw&$7>hs>#e#u^Oxj!N&6d(CpAx z$vxBT@y3+W*+6sljxH@L2b7LZ&}>|qe;%took0%!rVBSsik@~D87cwy3I$>!7i(WmQRZxu^vKr`_!VM18KeeP{Un{bBx z_{1a7MDLz}ci?{Ppp4v*s&fF_B(MqiI>)MhoY4G;;kqXIGDlnSJobCbZ$oVvz!0yQ zymDUS8_?2?UdxY>`a?J<+E4J+YZB=O(L%rpMMG+cGl8TcYE;76Or%W?bNcQ`7(D5R z1sAV1O@(pjjzFBu?nQ;ZNklJ>JJJd){UW77X5G{}0DAtRQS<_tN*~GYse#f!^-HN> znn`C&FI@MCH*t${leS#hY-qFl^QEztd?bE$P)lTgIG z%H*Ls1ZUY6$O?Rnf~cc3~h0 z7fUd4fnXs_R|Ao*#7dM{MDh+{xAoh}0WJGcD6~N+KyV?OLvDxBXMs`_a6$oerx>H3 zQSSmA(u^4x24OVau(oQz>K)4AQ4l_iH_uRO4z*iKOC+-AB=4`L-ek>|Y1l_nFg*>R z-ft$6tWIE^Sv4nK>j3Mu{k5=JPU;{pF4ZSPIRROz#9O|dYUzdMK}r4PVpDzlx+iDj zKRuL<|M<`vN({+=5}7~51ju*((b8+Jf#5bt8@^44Jf z!iAoy>6-43R0PoizD=U>Yea@-0k^xZM+C_|3#SYF%^+AY0SOb-WGb5ZSP;W|tSQNzq41zHy%VXUUBhzoE1I`rKi8I@sz&z7hb3>5TO zvxw;Otdi=8ctSYZT#^5L(=6u6!ju7fAMPu<`Jw3*)u9dQDy%C!AZa3;GT}`&wa1kaYd!1ty6N^ zc{C}5&z$_3LQfi7MTb&KoxId!fE4JbUMKtuhlS=}6W*NZAi5BxDIs zru(HINk$%2oEHID)R?sCF(3zWW z)b~6PRs>ye4Atxp0)|C49v9a+Ng|wtH|pC0q8;_%=P5d+HRi_@)sOuWlHj>$#^W6plbY zH{sw%;}fcToksF3caP}~RB3#TKH=Yt&S23rX*!T&nlzyGDzSq<4eRxWA{v>hR4g5F zgNO}!zy%>={a%|Q5R?~?PbzAYExQS1e49a4e4!kVQ?ey*5w~B9>e1)MA>J?&NL=JC zmmyHwrsE1-OSQ8kg+r{xd<9z=0)C`))51)x=_UFt&?E;2OGtpbg>l8%Nn zqHK=Qh|lmSIzE&bMWs5ZGa1=5%`ZJ)XGRXt6p3UprN`D_ANn z4TO82Wf#;_LRHE$q<2nNbav;eLj3b)&M!?l8SSsav zG^0RSa64GFZ>kJjS3izjP>40gEldKyfPDcyV3FhiN?{@9DO6ZfO|NOCy{WoIDrI~C8!3yu?$zJLR7ooLlD^cr@+N=RqW20PVwub185u7cm5yIqX48(?t z0&=xgfZR;AcIv9WYS3XRqDt?gNOblg)%5tlN{@XB+@KR(8p$q=@I^{Ay`d5h^KAC0 z(<$L-!Fi!R4Y!ptQK~@XrVGk(fJR4-(BHWu&@TdDQ{V5L&D|nO)vnPToV<-9*p1KV z5x{F;$k7=PlqRkI0zJ!9?on#%=51Y{y=7R?HIa;_C;2COpzkW``eL6L~^TnS6};**Y=N42N8xjoFh^x zsIZ43{{igX5}!`|BEa~;9!U_66i9WH6f7Y<5Kr^JB!@%H{{%wte6~1Z;Bqa8@f0j0 z$#2MIcYFb%7#PV^HP38mV*crDH&M(8WS;3c?2`%Ae!0FS`*JVxBn{@D9+Nm}dugbH zPOaiat>bQ5uqx**zd1r_UW(Gl!DI3x821tg`)vIojaUcvz(`r}pG)SY<=P|iD z?N!zUWI38RE_jQATPK_>XsRFqBmz?0O~1Gx1UFXB<&gO!kxvDH{Hwc}$4p=`>~wmN z^r*7~Y04iBfeE$}0W?RZU0{K9c?dRcM*dAk`4&GM$3HPDoc8kB^GE+UKJac3M%eSj z=fNH&Tm?H03mt?x0e0kH1n=;m{QPBJTfUr_qJI@7^IJYsCNYctt!64??GYEBATdu? za(O%CP>`U#f?o-<@(?(OuQa!ny6Y^h5(G56H*ycw-IS}lQ(-X=N-({bXYzlrt9y}! zm)~@KA)U)`&;Kc(stP$iVmiDOzIc0;jQR!7#~6AV&)#VdbH7^STp!l4?`%-V2ZbaK z&~w#_{za_1%%JUsRd`Dq-w3^9};b7$RxcNh9 zvq$EisT5TrsSiR_l(r@0gGA zyeE9)JbuE!TDPlRMsjoL<-Rzav}CggM6aqMK?1W;PDSig4>zf=<~FpcfFr>C_g>q- zfS>9t+Z2EXp~|gtS|u_t;Wg@JLfhn$*brTiMv=oNR=aJ{2!tEXl)s;XgaoKP^*v6E zik(dTZ?d6bJ=Ae-y~$4B@8Sp0aVEFju5SC&*! z98UU8az=)!J#DOhiANv?>0~5852n8O9jdw{MHlhAFHxoY04Z zu!dPoP+TO>Ixf5l4SBNSiKFC>yfmE87FIRH{FzmzsayB>))GI4tVT7@P`|9xyq%+( z72jZ}nh3irjH(;J+n}R1D8n^)w2ROTJLQkL?sL$Yd7n}&goC8!OnnQDOjn|&V;;wP zP|sOKA6Wq&$G7#tVEQQ}Y>pwXL?ej^GE7DMDRu;|i^OWT+`K*3@+!vPI~{HSc$;7Z zlP*<0^bVUY+lJ8gJt#o$aQY;C3zurROv4p7c)3E1t*~4Sg#i~9jwT}a^{3cn(+B|v zKMh5IpQt|5EZn5I96iC3uG2vm-S7ijjx58F0`A+dCl=UHCva^+DnpLC5aH_PJ^`*Kvn9LN!rJTyk8{cAb7aHH4|F3rh$3mCgq zI9xpRXAAeCYXTFSkV#}*^Ntag*-(dB;2U&sTnw&{bfE%0JZ1+r1y<9icnuVq)s@cf zKx!Kgyb4%bM>B);t-ig?T_w%Ushgx@%ZL7Y$n&To2FP@*e@t177PMh z$D>5o!kX5?5B6gkXZ3W+n7?)xwo8SNBDHELk!^{{QyNf*T2z#k`4RM9;K=tQ5rs=j za^#TnIS8N!eg`{a=7p58mP4E%^=p=0{%?ZJ*`_nF zVeJ#24mPZ3#fxw!n?zPgicZ?=B(4E^1mfiW@dpx6i9~935i;%7 z%4GOuMM&TD$xuFZ+pXI8rgIowJ#xRqQ`X@f{DjhJ5C-Uv`mZMF`?#Mw>2wt(*f66$ z4w6nghcN~2Y`)%K9VLh^q5^GLE2V3a8*ij!=P>@b6Nh_m8R)EzcfR>#+n5&Z9HuN8 z?ik=XT(zH!Akj98t`Zx3A$97U5`RpkT|sFThw6_S%WWuT)@hE4h_3dciQMN792z@B z3CM4^Ot2DM+!~B45q#(5ay}b^=4)FEE^zJsz38TGd3%eIw)96h2)xT%Iz*3uD>*z? z`{3f?EKIFs%e8e8t&0`i&VzuqiG;4;R>wvxAKdyL<(Ziy0bcsy&6loC=|7B!(Uc$IYGdp`i$E!&tp)`|PFG zqk3kd^$a>5bggaE;&~{->d3-nj%{h{@blW&M-vmQ358WR0l%p`m<~sZ+D`y>8Y1CI zALf~c#ZKE(v%`A-Ij|2ZGnHD7kx*vY&0K^7VCfG?y#x6hk;heBEz+yUQC(#=h#@1!#iWxE&`kkE^G%@*jw+SE|K zM7T#sN6l|PB+AIptR;w!78@z>y`}f6uEGq=)UFjxiuqSG2RGUrID%Q28_l3imrYCV zA1XNu){|*L1La2m6rL?O5u7v-KE8PPWPfJKk?hI!n3L;u==^;k9(1gQGh2f`;zDcb z9X;8P4>^+6=I~N{+Ft8YQNt2+xtEZ`8By;GVgZ%(Q|bMg!-4rkI>{~CPVqu#B*N>X zU{>?jYvqO0>MeT|ts^@u-^ouwAJjS$ez^X^;`!lGk4{FEm`)T$Gvop4r%7{Iv1J46T^)&wmUeCrz{-3o@m*y zB-kt?oFYcEE{LHVO8p|NdYsJED)!N)*{f--s?>aIr;J9%#qB|yVU0^e&XYUC(8;@v zD|SK&w0P?)9Zfzec5?Xb#7=J1qWdzNY-F{z?UYDlKjO3Ez{yVSBG&MV63ohUVA|&z zQF_SS)Y%3aJS9w%FJB}CiSbV0^D>N!492gV?q4V_i#;w5A47q+y$z4#1V zx+UHZwU6YX)=l$Ab33`baPPI{>2-FfqL&p)U)!;u(@l}f@~b7>O|LODU3A$eq*O;I zox!gO1eh|7T*#jJsQzrsHw(C@FVR4;vT~rhQ$OGm&Fex>FN90ffs)c{$az5w<+6j^ zVI}#;S#rhBK@3e#l+-E`TUqaag>&W+l$>oL895Zs-fa_|AgY=48US(?-{*e)8yvL$ zsIRFK(GoL0xP2|!nK9L#&z0sDS|nYhl<6LtYXGkt{lre`dk!UZ&E)#ta0x+9B1#`+j3Y|_;u0%R?`3$W+#BlhWx4W`t~p3%&Z_{HMh3^ z^w{|i#%dm{uYJpF`@l##W9aW9zeo@4Eu92C;o*d2=IxY!>b>FQs1mdXV#|=c12Ycu zwngKKbjSSW2-6_(P@WZYqEM>C-pVr=JxNB3j+N>DYKq_)XoeHimD3D8YE;@5910EO zys@_M7|1E2JRPc9UW8^=J;dYQh`zS}o}{v4yt1*H%c-q1>~tDHtNC zgLS}hod7O+lKyCU+#m}G{4{7atWQHD9jRGsmVhX2r@ zXBA*uezhjR&iF`2ffBHNafZZrQ+a1q>uZB&Wuf;2!VZL}Q1S9tRk1^7AYp_hn1K*t zVOarK9;j$T(U`Rq)ZN_mzYgG87_O?dk;n!?5k9SGkPiVv@|O?tw+6&Zu@gXj4d#I){purf{bw0&sznTm zjg5mC68BzP1NDj_vAHp_j{HEe+Q$~LC#b5gkn9dKmve zL^t}zzlzN@XzUm$I=D@_v*aMA^zkK039_!-#v3JDs>HewIGmz0 z2nHZL)J2DCJ3>W5zR?r;CkNHKL~YlCjcmLl3_@Oc7a#gUIwF5>bc*w=vBajR;^X

$h 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 zⅅ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ⅈL7}#+F?7TT;y?-;K5T}^MO|4tXdKVqC`doyD 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 qiGBIq@%D}K=G36b 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

ma7kq%yYiWsCV$99bDtqAvbCLYXzfR?))n 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≧fk#6adfd+-HuOkF#*;~L{ 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≤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Ù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
  • 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

    TT2+=N|5c$*xnFT_`4}@r4 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

    2q$`*_wa5o2AU&S11oh?& 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

    Fp7DEdPCaYx{OYQK9)Sh6Bmo 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

    6;jlTIHG4_AAgMJ%?aZvq6dO?b@ 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

    V9LH1^5+ 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�!}tJ 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

    mhzFgL>!mNlzaxQGFQa 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¸URi8MfD+7S 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�matRhY6F1VVHz6yv2N zEjsf3vrrQfdji2i8#Hz!V%3a8G?UhbVQTxgAHN%OuxefRPX9ajJsv`L{9@=11i&0R zZOt8)$6;)*f#at?=8%`K#CEdt7IHnyU$mR#A3+h~mR)%%Urh<@HLX<1f9{h3*#}Xk ze39~uUlCW&myhPv)qA(^!Qc+Q#@PkGj^4lT~(A|AllyCIBJj^dUdgm$QOx{^W2pClN9%VbLlAoRWqjK>wV)M zsCjg7syD@%$H(Y1@elkBGlqL$A-Pn4k*xW6+Xiyr@JEa#U)l$J6II=I{ zb$8j`cTvXcPt#Up(+X#d=oYU?6AwvQy4CoNB2NWLBG`5kUe}Ohk5gPbukT7ZLDh!L zPNaKP+$0UXSfGw|6*nzk*@}MP%aegO-CW5!4&!dKQ@ZP4!<-yU-^`Y8Hbxrj=*N6K z_%3=NC+=-VZvT}s=aOj~9&4JT89GtvzfrpMZ27cQatC{}i~fA$^!TXW-8?40_Dw6@aI^inRfX%8 zcHf_y@uRrT>9RkEZ5G_!Z*PC@0y=n|{kf4Jjr((ZY;Fj8L;G_w9wmC-wLtb@Zhvk= zxBa($VZ%bZF8itLz#fWM5 z0Sv@U&sS2^9OZ9uL+;q^mb~Q+xzhv#GT@FM3M1uY zo;`^h({p^fA?Nl=1XlKFy8*r7o!gI_yzLSXitD}~SNjpfLMIob3!*OjaoYxf`|^ys za0iuN8q0Uzk9+RJ24Cv8 zUez}Hp~rIAI-4_su0rH?GM=qo@&8RQl4q2YGd-Q9zZXd&z%Ep?@*HSf%LtmG+zzcr-xA(gB3 z1!-Z@`83YWay7HZ@;XOk8LxeCbIwNGubKHHxh)Uc^cIe) zxEOfLW+^D&jFbaH_U0J+6SmO+FS4M29AD``IT7$+yZKC+(c(@`1!Bmy5*m0H+I8us zPIp+~x)5)R1T{M}41=E~)z%o4Ud`_?kyXjpz`1`8{MX}C&9-9*=#IfB;p1J=A@HZ2 zqk9sMW9RfKL;pQUaXirCV+WzDShqA*}== z1L4$&V|pb&u$-}%ly{`1So~X|!^iYNaEC=j z75zdAHM_4YT(^J)OEI1pb~37K+j=ut!{}^%a>J`W^wmJ;_wmiN9=$X5bC{V_eX%AZ9*q;;aGr^JIMxo-R(V5^fh?UA;uQDb3#Lr zlttMX8|7NE5dMNa!nZN$XOJ}R5Kj!lL?V~6&SsgQxP>?3u6b1?fhw2pLd@pof2EIb zABL__U#osJMY372F+?`)J`3yEb{6b6(n6dGKL-xz0o$65I?aZ&=k9+?=c6~CtbJZ_ z7>;L=UjDXL;h7jbB*1qSLm1rpLiq;l(d_%6D?SkIr_(oX-mAQh25dd=A1Qg1SJ#*R zk@tIekCC94tERjLNq^P+3t3_9uLsfJt~T1i7=v2J1IL-{13AuC+tZIs^QxJ3{~1S= zZ9P4yuRFSwGiL;Ul5-xgF}7R+6Uzmb>tC z`S}$K0K9=dL3S^uzx7$O1Y0@?9-T%q*Pj!p;WsC@uJp6z(vEn_B%}(Hp4!rmk&BuO zlQ!sOR==I>n!QNEaiDl#?(l*IO^$ z=Q(!X3J-68QwDBN`qhE8pi3Y+<3i?gA!^u>;$VzdFhS4z)>|S+bIRG$6BA zlM~I}eW_;7GSYQmF1373#gJ%J;Po`av@P-wc*(zCq;8w*G__GLi*hx&f^BBGYe{$_1OTPmaF`2VwALJYD}k3=fV z|Edw#*bEyNEq7V>gTRJaPNU~E%OI#6^@$fYQ}H9m)ZO}b=^T!L~Iw=D-mORy7a6Ve6A_EYekkFFEH?9 z0aHY^%Q;R|@8cO4Jx6WFqU3MSvM4dHvy)mRG>=cI#MhVaaeVCz$}4kfL(a?O0IV2< zsTT*?$1#~EQCfKyl%fb#8F{k1hbSu3hvK^unQx4{DO|zW;y@v-LGmE-8j`}rkaC79 zrx=Qrlp{J(PPK9(x!Kml>+!#EyteO>&e!JAJ(f9--i5g!y_Z8xz)I`7^5${;DXonX zhy81**KL3bHS^9JMpXbS21qH;tT=|TX=QLBks8{$(y&79QmaU_zl1yFx%>UbS{39e zK@~YEA}G@XUnX>{{BK}S?LEP7^2zvXp8)?;f}gRQM695W*7fBrF>ccOb1-zY|1oPD zNb}%zalI@A%z4(cE>l)NWhtRNSXtqg*7KG1Ze`hxH+v{cH{Q_T2xa|?Km$KlT~L;+ zDzZw-x>s3BC_e|sq!t$TRqNdx@>@#S`EAFPTJI&krD*q3CKoO=hxP6?vq2~%6pqxL zgO#TJleQzUOkwe7lhK~CpOlf^QOTById8ak+qtd$30g4vx8s2LEQ)~*{q)?wQh4az z&d)U>B!-(oj?3BS zF$i82cV>mBgu)Z7uzx!X-trXDot6*;W%P%AKr1LbsZphNe zx*{u&CyP5VNE~TlqhE*+Vl+oCfs(z^iHyvR)&&NDSpntq=s&>k>;1_R!(s-+@cO=B zrH(KQ@vD%_eA3p8HoJ{cM?_v1?P@hKoaW zHSfG8JlKop|9039{HpGYEVQ@LCixztfPcc`R(-K%{9Kd%XW}U~;xO(v8)?fa&XDVK&Iy(9wj(08E9EtX*7p-f3R`Dr=?@so$;*ACW=*%$L zuc{?%uM;!`e-M>j23VOqEQ-3&&() zF#G;Z^Om6XuY8uwMb*ma&#?(ub4RMLP2jD$F~zuV{Rl$QYCN1FX*N~8f#{h$g=i$( z1p5iTs}0`?%%ClDMa;-FY2w{0OEedB0qG^5>ld%MGX;2*`*a}wMqk@u7?Mh7JT(T7<@+b%v6EW4! z9eW&NB1TQ;!vJ!fr}9QnTKCUORv=%FV;E7cWbvgP>Yq7gY3e|wzy#pL#cE#wm}RTZ z^^%9{lA4TbbLWvmJWBHx(8G2AtPojt9yu`YNaar^-+92lrJbzMh znNr>gP_ox4*f%}if6zELST$YmKj^Z5!nr^@WuaqDt7#g-3bw%R+;o@m`OPi^F@4ri z3JYfg599NP(P}l^lSE`6jJ_nfe2y{t@U}0^9kkO~$CldOKcmlkdlmiyjrI9{srRzZ z)iTU$#$&@aOC##W0QhaNPDrl9t3p8fW2U>JU2W`Hm0bUX%Ysiqj@TyZ-@awF-Wb^7 zs^y4{i>BJvIG*hs^g6`RBSNj4^+hMx(JHU57eU;h3omMeKNZn*&%&ux`rg1Q9@N*Vs-JD~2P2qpM>}`FYw$@yq!CwL2b)iO;@FfKC z-m82%J*V=|c5nw{eW&?8bccA!KfD)RCsH0ly(y&;x7C;+^J0wKN>&cO?NA$fGC5Q~ zOV#z^oKaJTjDVh;ysS=dr=~TnVZVg-dqQVuvHTSpiTd`Q-tgr^k42W%tuIsF#P`gu zf?5#KjeE!TdT(Y&rt0aUGijz>#8V2EI$kpNiBe=3;Mup`u#z3KYkpYW*8+#fpHj^fpaYm;tQLE{8Ov(vv1DCz|t zi}zPK9DqOCdJA>d&FoBQ?q(2k!tNdr$_HtLP02<3nMCDvxmC;kZQK3P*ymvPsxjbg z5!i}qb5`O?Dx37Ae5EBH8&^}0dGc~k-Z%BadFYk!apEdtV=^NS9 zx#p1+;GX<(FqaNzI)^3i`Os1iQrg6QRs;c0_rPb2QO!k+*p}Z-6OUDTR=rN*bH$gu zZttG?BzxqZhx?1;;JU4>f zIw)4x`;OWJmydl)O~DV@Az=HkWQR?BX$0QH!jbdxU(&w6K^*QI!B5fUM2eVXj2sRR zPB4&Ylz}Q1rkIRD+)3{X$WrTzz78Y@t|sDEQ_dHhT&+ou8uqQ?XYQ|iHMFRnhz|_W z-?X0cGu;&VF1vVnWAY6EG+x$0?DW2=u=1ocs5UTh5B*7+2>Rr&_tm}1d=527jIS4? zUY)gp`F@0u1?5K)hKY?iJx9_|H|=ZsS-q7xrXaW#X z@Tk^%; z%Ae<60L)H84r~N#?vF6W@9WgZ5W5MGF=j+bm5qEq63KTxDbgBEJdKiCVti^HVW*ni z!sL@F9KuffBu!ryRk;D$j|?ahsY_keNq6jOm3D=Vv>Zi&{R%7>00KpfH{V%yFNFtp1@Ch+%Vs{m_r8xT7zo+rflj5)%Z@Y0@`Y!Js@DJpIE)2wPb?OG=@sF5BJyOKjLFpQk=B`%H zovOS-^Ys|<{v}w^OuF7n^~-a>Nk(UK`U>_8`|;~0&1HFK{^X|6{fAxshQU`TbD!>= zPfr1Hre@5a=VEY&8Re8xvIz^z{G!WtqdP(yX5VX? zR1IxYu>vyyMM)RdF6*2~U<@=p;XW(8KKX=(Gk)P{(GViCI+c$*{M%PgV81hYfRF~& zOiO0=fq1<>b8_a_#0=Po{%t`YwW$Ws@dY2ig)aep)A)OB6Tu+Q;2FQBH!Ps|pJd1h z;u8sv#_dwbMIw25ve&c7lNSh1(D>{Y-FT2`dva9zMPcB+SYo4jK{A5ueqSQf7Qbgd z-CY2@cL1^MHX%gcykJ*`j zN=6(dlGVii)~YNl%qUdiPnz7`3%?Q%_lH+nLnd;kF&*b>=Fv2F@EI+<= zX!9(1%ivA1V6d-p{CCH(Z-Dr&7t(N7c+hUt2 zO!J`NSz}33SJRS(!4td>gEfUxwx>8yy)fgWDW|X_em1C1RY;eQPu_LXEdXh!kghTc zIU?QWFGd_msVG*4bn^gi2%S|W!%5Xw3l=1Y12Tp~atP00E_?{TjS!Ss3^iZo63TM& z5z0i1;q<4Y#ju(fhBbG&g|P6Lh?~an#jONMIBH4&1ZnjQc+jO%E49xVOoRwmG1)If z0AE4(VNf2Lq0%~pW=b)RubA|)@?+1YtPmqFKUTgJjc`MG&dXZx(AWlw2&cIsLaP<| zg%v3@Z!hD+LVjN4SF|~r)<&D-c_JOkkEoEOeOaI0vXJWXV*Rp><9Ymo-h%(nC96+@ z7PkT%BShonwsr}1{j>D~8zF9o{E;8B0#sJYI@~ztUqKiwtHkp_;rNc;Ez4^?qFHhS zx7aKmGJ8~0&zpJj1qC6eF!{R#RPrJ;6eeHB3oB{S4d2kJR@$ULdx4==U?nfCc882$ zy%O#=c;ZW$*xac49*-vjNgc;4F-3Fv$meUVny-^L+am3j)5}y8q#iIWQ1aEzvTFV{ z`!(v#sT>p>HO)ipblv4N|J+lI0y)Ggxz}x!R}yMuQ)kAPCLo5qK>^|uVMu5f?2*nQ ze-)EDS;g9*ql89kI{`A|dT2@L?b?z^&1Ly!))MFSXh}m)_Y}nZswOM|fO^uTFhv2R zVsZfD%@%3oX=2m5rS5e#hxxiM5;-N4Pei9ShDuGT2hK)9bS4Y4k_c6a z16fiFrld3R1}9+?_^&`cdZQcGg)YZB@J7Ti^-fzp1>}hK^ir*y{^7-JldAAy%Y|Zi zF(I5W$92`|Or;C;++c0Jpnx0f!P+NN{3s=vep`yk@`H%Z=pT){GdpDEZG)yUSN`|; z^7@(t?LYp{w0)%{wYl===F5lgG0n=#+xM7u$d&(MuDtvWKH=rFw8InTSWATRqa@_s zb(Zx%bxu!D+jD*L1kdt~l#Ao5D8D|rRr&fRSC9D{lV68+ey(!gqFkka!oFo7jjeAP zOy!A5bJm#PDU&(#;mf0^?8EwW0TFR*t#f!=PV6GaoLCg)>jE8P^mCU5j~qQ?hpQ=ue5fxDarjdX4qY|VEprq6ZJ&gxdh)kT`v-IWfFDOMmCvPAw9mg! zj;7ky$A69`y7_y%#ov@f%cc!@N>R#O@8B8N$J*CeCeY-Y)0St&`gqTuRjiL|ZGG&E zUY5EQ>*Eeo1GCm5#?g1dibu36c*d?JZoW0QcGhl*dhB8CEI)GxSz0q2u$x*te}O`_ zVZ|g>uAQR_`PO5gauN{@?s6u&x0WhG-~9<%a7Lyaf!fAz?3d#J%I^^=^@mS{Is+2CHY_r|zIeVe+kN!`G-VqHs}| zbT4UcwfUVm^9~dD`5I_dR^F{Pn^0M8!`ar1Cfj7I;r#k()sQBuu-9yAAmthK2oZ~G z1&|DZc26?K73Q6qr(vnn%o%1arDoEiP)AVEj7%(z0j#upN-??9i&DOJ+b0#e}fy`&?Jr$%N`8YAhlBj%f6kP+E+cqK|{EOC75 zO!8s0x=1?iG@U8PqXndbf*~7;Swb4G>Q)IAJd4S5hzOZM!wxms!YH+<8lKep`|#k) zzeN?tFC2%r4;L)-7m4%nM~s_CLXDltlXDHpBST3?TP4OE!Iek@Rsk0AmZ6M6%Kqqx zP)9Uq2*u>IBOIAI0hPhWI7Ic*$H}9XHRH>)xllID+yhGe}OueQeUNbp;B zBsEG(k7i^wzhy;|ZVE3Nk>Wntkfc}fb6fw(dYvD>lX2Y_gp!TPZ+QmS#I9J;!fxi8 z@cl>?Yob{6P7HrIdM6IK8Slg$?w$CgH7FcM??k)Vc-6v!U<9RHcCk{2MSSs-b5caO zi^*h+L@A8t0fdQo#ZKG;zz;9?bg4`l6#Arpg*tg9#H3-s#bi&5Un;a{ffDN<=JlIp zP)5woIhz87xqXv8Lgqrtywr^On%Ok1Vp5OMN)c-LD|HnCG`3}t({gT;S9>uSyn(P_;9|_<|ISIG; zJv92-3C*_F#sa>JT>Ufu$2on1p5hDVCip}@n(Ea5VG{(HL!7p{_&+2LVTBbuq!w3( z=R-Vkd6a0ZFc~4ImwJ04%un)C7{dQCPHB@`yubu2FoTz_{*UTRxBc#2)c2vujiHXC z|3i@G9U0eJHRtW?Rn5C~|A!!T|A#=yS3Aq9x&Pw|RrC3DP3ncs|DiFa%JdMcQm9ONL)A;U(&KLBnlPmkwPMCU)|S~^28%M~+Fio-CSlYlcU zQ!(r$PEoV8&~AytWmIG`aH=IX_iGA;rr5irAk7*^0eXyHG(l29Ci+H)Vnfw%LwGSa zh6q5#uoHsT)2Q_#47d&(TSABVc$visKgHFTV)az&C$%Jz(=w@B&K{oAd>1SgPHCF5j_`=n^%1trlD(W4S3$?S+R)){puCTvi>nEdW0 zt3JW1xg#bvlg+VJZ^~5{X07_^RF@@k=jY5J<0K%5%+12XEK()Yud(O)WV)A9o;ze} zqC@8U51`>s{)@q)M%L_>-=7>wZjdy{sm^4-tRR|1;wkgT7zmgzLZm3Aom?Strrx^{ z;HGJ>E7`q4iW3?|BV*KKMA&Fi&$y6df9q&8Q6t6ce%>%Pe(Crd7IuA44*PMJSb+}|UL zD4(Qv;jsa1rRw+!uhOh5T*z~@V)MTyI||=X#%e|+6HRZ49m`ms<-Rm0{F34F1P^QQ zS~y|mIh;b8=-46+nqH6dT}*zeCcnbcQT{3o#{5E>Brl0>K*V`^;f4z@?H#MB7KK7 zWRL!;KFe)2<^HPQ&O}%USaUTQ+;7}pb@g!$e=4D@ktlCo&tG-kJfGix?62AuD_l0hRQR&1ziI_!oW^?mZ~RqXS_Uc~x;C=U+x1s{j3u-A ztJWggFeGL$%D3#VYN0WtQU?%7bBc8C6p&^a_8~Bl~6i z`fow0HS*i@SFN3GtnlXjRUc=<#X0YYzv{SCji6YLq`m z3atuMxT9$z+t?BcYd&4+XnN4!qoZk|DvmctQ(SItx5OCGT};i_7+#`_DUAp8A^+EW zO-GD$MC62v`I`2L@+I$Y>dTO#H9G8Wm|^Mf9q96*m>`w@rv1p5-^lz;zm4TSLb`?3V&1XKH_3&;u-9Zu;p_?_>zR~W#6O8jyY_@c?Rt0;WwDVENYcC z280*w{LjXd+=pcQI^}`PMcmbi_lCsr#>u(#F2?uF)sflni;I5k?^M^yUp#?(9%?7B zS_0fbwCJn*m+i-?jl0E$PNE@|VC0?2FK7_T83bU}+TOtafu$_4l3Uys6^`Pqt<+ml z2!4fF>7H_O!hnnmm(#q_Ux|uiZq!mr@yqqv=7BX?t`K?0!HR(;k1 z4J%3x^BYLHUZ0-fz2@i*LXY(Pb}qYLW3fv2rY`5A|<0pmt+!cmW-O3 zBCOS-rnaK1BBiKHsVZ8R$&BuNwWdL74f(&{pU?R`&w0K{+VsM2|GZx9_j#Ukc|PZJ zKKJuE=K=E1p4cHhv|CT>%k{G+@(I?{s8o4g4@El9>6wOK2$0luV{oBD1bc*Db{||N zM6-tqksg0j!=r(%xWI92U6$!oU&7Kq4J-_cypX4EvNx44n&ZZ|K+rtP#WB8_i)Bst z1#?8J$AxDUo|!!o59MTt+>&T*xqLQ;eDU2zZ!k90KhgEE*%3cjeyJ|jAoN(v_tvU& z4mvBvtxBdvP~c*3P~1SRjYWYhjX|w7;o83O$>&%Li%*C+6}Cc6Gfs%W`I6zLpqYD; z4%MF6P3;M`ReOS0^~XSx!K9GG5GlzTq=nl5PZ0{AEFK?(sPm)%QRf1-Y3Rv=OZnz@ zzy!!@R|bW|vX_E>=m_@l-H=v3Kp~CJp_YbdlD*1^0>pXQvbL4jtK6HxwEiC}9#T<>2Kxgx;b!;k6M z12!d8Sf5w>KvKw^+atCQW<3r1ec;auS9TD;#2vB z9CcsB-3zc^2yKU72Bp0Zw2uf8kkr7u6PqlQw=;+EZQ=5Y<@g{!%+}P5Zdc% z4VfI!*OSmad&=Crc)u3}#V~~i`fuk-^st$*7}ErNB5QfkY*Xk&49#d_%p`>aVN3h{ zBy{9Bv#;$Ac)`N$_LIziGT`6qn!qP3*-v6%9bG5e#{zJZABz&QC4^l8_lDCH-1fUi zf}Hhj0RJlYjC99X+*8;tEPF;s8u9)U`#$jdGj+V&!{lzZx|=462XvIoU&r^hd8%F` zuxa1hw%xvT11<}8`Tn?EGGbBTU(S@kkC6Og@hk^u8F7d+Byl(EfAVI1i*40WR#Mg9@#%ZN4D>47yW2 z{H0vro1Qaq!HlnpB;|9nBxQ7};nI-uPuwl0`~#Hoi$^hM3^EB{&`|34)XwI1hVWua zk$Q=gh5KMVPsk=*#-aoRXfAo(A606 z1g3E#4{!Du(4%eKJsTyg4Q18lJ{YGX%J#~k*fplt%P#4VUcUlsd@J<&x5qKiA7U8O zFoHJwJp8vuuYdm0n$hdQkcAPlB*L!yD0=<4U1Jig4QY1La1iik8l89dSvl{K_HIctVJ`;E73rG~^@8GCXZux!v z*J?r?hQ~Caw#BcRP|v41vAV{;2<-zC>H!p4{?1dLg@>sbh0Gw?_M6WaA(v+aC0CKA z+@#q%Zptvp+p)X|b~>)N@Xt$d-Cdt&_`I8cUV!W6cn#`{l3waxNrmt9xd@OJ|2*w@ z%z;{FhsY>axIXv|b^{S1LCOvH53g`rppKbm;~q8hY#ui9+HRnScQKq;zRgnDQr;dT zD6q%y#ZctiP~;IF_>z>bn@*`N>|*gJI&jrp>&9 zE3x`~{tFEbT6~00qnmg{hBm> z#-j{Blk{gYevsBe6r>uC$delqOse4=+`#SPYmwtZB1?@PsTKN4h4Hw771=C@fYr@( zc|VNB(`+_YY||JWk4`MXMMw$`tnCY$v$IWfs+!-^@$b|G7ec8CE`%dYaQUM&(*&34 zY^H>(uCi8^1Q!l4N^m(#8mYIupEhb@ITe0n>k`8x6;B5weWHghX+%8>Xaa!a^6`*^ zYuDIQ2pbcfiN?1|W8KEX0ZL=OkzC7~1RvzZ#>6`?6216hNFj06QO2P~ZF{$G%V`SR z?#s3?1xP#WBjb00S5N|!qB4zQnI72c!~!F}k}4zk1VqDFvxGG{_DI@f z5^`*>Oc8es#dduGZ-_N^AXzR={wD1X=hC8rh^ed{ra=&n#1IoKBY3Qcox}07Kh6jd zgUhrlyoK0W=9@+v={;S}fB2@9>)11oC2e<2AMzjYo2^8>_WS>#nkV;c0!)m{Qi9Nfnb*07e`A-&~)o27&<5<*+gCYaiNc7@QAUz}~ zvV!yrJ=BO2uNPmaY4&ju`^+N|nQHib9CpRBFGr01LU6KqN^AJ4n#^R#;a7wYaDi;>cL=!akL z?(7UbPkaXMj>Pj)OoT^@{!#=vTl(^usBWgBb`DrvPYAyAsU|uPz47 z>hTEopr!d!^X@l)YSQ)ar}#;F4X#)7N)BJ(4uc?e&P(r4EdXp(7JL_!gU>U*Bk5Mg8mfSwDYH$Q5}RkOMhnT&x`npj!D3j@`jjCHSC8Q2sjQM{!|&C zjmCKctT0R}l;Z|EBl4%FZb6DrMKh4u_zFAq7~g6B6k!V;qpPKvGUr)rrtegLicqRQ zML5D{M@lpGr+&$1I!mh7w6ge99AKo`wvz$>cxs7Ap0|C53)8 z@3l8=(2aSuoE6<8aQS&kkq8v9TLMmZBwp7n^?eXF-z|}f;YPh40TD>4%*mz0Q%1>7 za42v@@Sx|hyoc7~tGR9`W5t`~L{xUg$|kiMp|F);Pz9iK_iA-2VuR z=is61eXe4$qFu?hT2lRUl;G6`cpG&&vBQr?pNrPP42eMO>mi~*6sjl3z66zwd!nB8 ziM?Pa0P)Ak;pj?(=E5y(eg{M#%7#g^cqah6iDy!p4+)x+2+?iYm7zHuyynft!PAMR zgEyI@zZXv_qVJO5R`(~Z#WHp9juL;x`*+p%K>zmtoxsD6a{ar(DEE>=Oo*OwRmgpc zm)O4(K)Oh5G$M$n_H>p@VqKvwVv>|HgeW(hf$&YUdQ!8=C|Nn(kt~$%&|6=BBQASy zeX$6WHKSZ#^l(r=+yauZ~cky$@pC?0?H{dw*h7UlQEL z2lcNC>)ZJZaeXhBoTk2p;8|Ibzq<6)rLPw}76|0f2r z7xSJNCNoF6^HyzAeIZIwMoh-6r}+-KtY-+$NBw5>EX02ze5LG9v=bE&2+Bl}s4dWK zr0-SiayEmW({4-la61f2PuJq(EA>Hc>`8ReoFD@%YWoLOsrBqAvVjmQ9kf zYCtN{N+LtJ49vKV?_+b;t3{Xe_rbeu-Y>9uxM9uUhD0@S)21(mr{cw3Qz_(N8v?2KYt|V6P{Bk(`cge zM^8;t}r6Edw8LMaRGX{zE%bVHR(?dq0Qtl@dBU;P>Lc5|h^FF3FDeLUyt zjjWGf;mbQZuQkYr?ex6h9w&85f8(&>Ze7sd0FL8j?8f~L>91tNwV}Ux)V`~rzr#*w zj?Ok&gY$w#zqh)U@2#5tdfpY#-*wllF8$qfyaF1jEu-(MRh$<*`A*DR5C6V^{>I>W zM1Nmgt?;ZV{oQ;*r}VcIe4%wge|a27f57=2(%;+-)`tF0s9QDtT|*NYQh@gH>eJuS zS}*?q=c?r2{5t~r+i1k<(%)--Q`KtI-$1 ztXs?y=fsuO5f`Ub_Y}qPNc%5QMr0@#XK)omrFk^4ky@)BHW(b1+)SSj z{PoxTNV+7_UK<347vZr#yS|Jw)?1TUEEjkZ@rpH(zCIUN@XU#oBw&2s9_1Q$eNFmr zb#w3=BmifEperrbzo6J6uGjy`BCf+O2X$1<3M*UwuXHP5&({3kqu~V7zu|NfoWf~9 zg3s^mevnEnem;1i+oVe5TXieEL`~tnP}-{hWAv3rDDb?^eK;I$7wu%t2008@LCkU` z`Mv`IfQBfS%f&h6J+1eLZ;{y_C@-kP3&;_k!ofpi8lM!&O;P%w-M*;8uWas8)l917 zM5W^;9?gg(ONzz5FMK63hUEMvcmg%ZytZay>F_e|85Blr%Nw0~MsuFLN_b)*b@koy zdR^Xm@4v#!#eO*QPGdr!z>6i(HGAiA{+&5|2u2!6kJT1uP8kd4+oxR7njMdc#^S%u zFYH4VG890?Za)vK?&5mF!yL?SZhm8$`M8xBF7t6~<#(ze7@T*-rQA{Dzgco)M)Di| zw!E9*(LizT&oo?42X@UM@TR+F*b5G6WFBrME&+qzl*bQEXAj0B`*un29D5H~IXbVa z`eqFI@XI27X+!7|eJ(~vSbB}=^GNhYqzZjzFI_YGyb}ipo4fo0-mr4|yb->X&4b=qd56m?Yb-j!E(+d83kKe?S5bOOT|!gCuD^Ctnw@t>(ODtba`o z70UW}E-8L>6Xsy+;s$$l3b7(pdPW}8R~(P|>_*c!S6&Q#(;bDnTJ{Ya z&@0G(#w!M2vmfHhGq_(b8;kca|Bx_q-Hb!Ry4h^}AmXQ@&nu%Hv4$Xd7XO01O7*}t zwh>NH@g@%+@9z-B9Y_jV_2`a~W4DI4rfpc_n-Ca16P8 zL7sc@Hjox-hhrU+Eouo!l1fG?995L#M@GqMOLT>8 z`%BxQs!+8is5;gzTA*S5wXr7u59Z zM#jno4VeMdlr{M@YjP8G#PZw86Q7>ONHt3&J&gnAO#$Cq>u-9yE2yRw5LySz(FC^~ zy&=R_tzvA5d@$jXkLv6jU8h|yNKZNmb)P~~+VHX{8sRR-Bd!_!T7FyIxvYW$T`*CDRK8y-NA?!P60fr>kYK?4Jl@FK z1wZl_+;bu)w0ilEUpZAFQJ!@*Qoh1n?duI^y&s|^O#5}>Y z{my*u_d8F)WomS1`<-9;I2Px-X{>{7RmSqF-G1jgq=m}Zj`urHLNm$)0z|6EC4unZ z3bpS6bVt&UGA0s|O}JrWzT2G$FDg?H&O`8lf-S9FgeQr_x%}A8(YLxcM~cx{8mG%~ zUo)XFz${%ZhDx}TunTuW;%GSIT8I=1+a{D)48$BV15{af0-O`dw1@s90t*o!wNxkQ zy#+pQ=PRmwZd@g9B59U4S}gQZ5L25w3h5UBBC-G3?AxSq3o*@+84?71Ld>y*`EhCY zRHdRNk}wJe0ELOG`<<766ib%!Q6SwXkfuO5vX=oW&9}D7(SB#Yo?L|bER)6L>#QB) z9}%g`MQHzyTtYGt#yuMJ#}J1;Ahw$*q!7@oK+BK1@h2mxb^inLr}mqVpI}sDtZ?;q$z4vT$Zr0 z>4pq%Os5v`#&m;N&!!uM;FkNh=cCqAT%)hFy9%AE?R-8)L)-Z*{CeAY2jn^kYb~H| zD;!vO`ctfNIBJ;r{8pWr&+B0u^x~H^!R-TlhQ-H){O5hRIU4e)Aochcnse5Qb9mKY z<~Mw3FcUt|^gYnm5DGQTxCNvfHHncUMk-sDj1WP;`4Fv3Lbq;vX}8t;;*ExoXgPi} zU%0IlY6?u@G<3~3?~*UQRa4Wbkb9&NSWunv!3b(X~DBFLi@W)TBvT=NL#2twQMxf47rE& zB4|H-BuSkbx26Jl31 z0N~+^M4mhfDS-O|lu2G0EOn1=>&=??4Vn{ZX+8qYBRrpjr|wsWE1oX}T*;CGEve2& z330LoI;6TJ@=bl(1QJesA5Uz7h3=Yviz}d0#tgD?eA5s-r4d;szpbuRYq8860uIaA zy|r5GU3LQ2ZgcCE$;hSCV3$lp8(k!e&M6|?F@)i)f({6((g9FoxCU{m2w;im4x2>L z9UW7M;a29_B&s6xSal^h=19>8V?USnIt$I2_}-#eF zLf=-t&oe%#cRT7?Ja)Rz{~8?E*Zi-b{;z}j5d}#;*EfeKZ9NWwpZyp83q;pI4g@*- z1tP+Y94=WUQXnsAlWKlk$8Zr7ot}!EB)S!FZL&w8y2Oj<8C(5G)R1zmk$aBy??uSQ z=UW;6vQJ?g34E?_54}&4ZFTqKH~Z(@@~pc_%2&90U$2Jsm_KJqh})S@kxe%FRfs^B z1QF;h_X#7=KLAwlX10SlnXl1j_$jB=wZbk)d>=bsyx=HaZp`xjNKE#-1I;yQmv5CR zB1PBYi#xFD4gvaA*}Wqd=alDLKaf?~-eP*NLZgI=^cbuh{G7VZ35*cu^h2EA9c8;ragSK3=gG z2lsrb5zX4gE1rQ26}$KrT)^aL1S6YSJQmlT#w&Wke5mQb{N454n2wgQPmL6)P0HTe z#VbDk2V1C3dLvsfc#sGP(@dhECqNK*9mOlI1iHHrulVy|QZLNB)s0td^4oP5uXq`9 zhf#>VFm8-BibCw7_ZEfVU?KCE@et*Y7L5=-*Z9M;CkuVA)A+-WeOM;oG6Dc`Y#{|# z@lI@vOuY)Ec({k73-O0))Q{p18(F&!;txT-X$drJ>bf037+8IK9Y=)}W2f$YduZt4 zVIWC-=bE>!*(8cFY~XHvn=yu2NNFp-jGC%|=Uc2ONIm{Kt&b^ag)sdmsV)41IEjh{ zBs9sU=qpwmo;2YJO4E+#xfLVe_>{W>eFv*#CALcT)Vb05wdUqez0%zL9ZtfeSIvqm z`@RVh*Q9ZD)B<_WC1;7;K%l?%C+E~4S*xUkeMZzZ%lFKrI%q#lq%7v0Wp#WLUq6hs_t zrb2Fbj`$CeJq}KRuqkzW7tc$p&zVb3vdp4QtXM4WtUkubsoD=w#lKcONAuV^1kb{a z-3S}ZlVNWv`-*vzs%GM(XV-XraaKjZuRTs| I?AjS?T^!;y`|1#Ln3zU7#El%k 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 z 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

    q*pFP}Twb}G2mKAL_^V1sVJAI~4g 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/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

    rmIfI-<&LQWK3&=&}5^@>2f?P$e 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�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

    ~0`*?!(ncirh#GUBog0yyM-DQ>&k^bXY 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

    L*#tlpWBbm z*x|>JDp$yMia|TPs8aBAhuGLdUCr4N>wM^7Ka$%U8G8eMFW_p~PBCcz2OLMSZJS_6 zUFUaWX1${F-ND{x+m{ce@6lij*uUanS21XR74%0HTjxV#FKaGaqCIx7kJil$GjPoL(W|-bYfs3P3!tU*r$wr zv-F?G*dqt~h0MN~z4nXt#qjI%?dxSb#h~lWP#8H^d{6d{u~%~Kv4i~zX3vZ?XyQnN zsUOI8ib4BbV9&X`@njEn(r14Dlu!R5)EVGV`3&$)ZcmRiXyQnN=r-9-F=)RH&ipXg z()yTu_hc^_dw#ix4)$BPoh3Zh`9Vnd>Rqy(V$gmfoanZ*rws%wv+Q(oPqnsHYJlQ9WeNc1R678{r{UL5ok2Giw!bpSgDcMdj zXn*o8xo>=XvX^$&`Ofbk^&ddx`(bjvKhEvxkp|5{7->-1sZ=l1kSgXSQNG^lMR+bIU^hr-3Z*lXORvFD%bA_x0=|FC*;nuF<)2CxOL zac`3C6od8~;R2U4y2ewvcZ_|8J9-EE8@N3^(x5pABMs_1$aacB`(*y8Do^&xE;`?< zI>p&i<@@1szHiIz>0aw5K5Z|}lkF6P_DA46zla@+@9TSH?9gF0%?ItFgMB`?+b;sD z_B^}@2rqEUc8Wp!AE3?`dwriYc4$gW^Fe#$U=O)H{dBT92u~+_N62=HLHpJDPb)mt z`6*+ECge09w8swiBba?CV;=(hWL36P4BDRnJ3l7hbv`zBKu+^f`F@0)?;m9L@l1Pu z9NP2kcguE)L3<0}Z(>K}+ukwuknKmWsC;*@FXQ%1dwv|BO21#WQw-X#f*YB#J`A<= zZ7zm4V2m7Vmo@vjIV|)HI*-kNN@4&gPSbJ$#o$vYmHj#sUirLx23e~oO zhZRBPEZI&mXva?41FTZ;-*-_q_WZU@>|p;sw`Z>J_{$oV&pX&v4BD@Sd)S;OHJ;9O z6=TouqYkQazTe60%}krN32oZ$7iBxep#4y2+W_DC_|Esx*k{Oh2mAfZo*6yc#L=^r zi)A~-p#6Hde}@U{tdDPd&DaO6y(C}pTo*amA4}}`)8+h$yxIco`7g_Mia~p?@b-Mi z*m-VgJ=$Xj`?HB1<~>Ng1*x_`oxei1Qw-XF37s}MZ-jZu_pY(eaQ}X!obNCDr|Gu= zX=)|}wFTOBH_3L2LHk~C;n_zQfm-^m^OcIe#^u{X2m8j%o|*{(>^Kub@Kf1NF=*ci zlARxuZ+m3yHTE~wD=Oa|>}6(8W9NTky;GI% z4)&cB`)EH-1HtA#34$+tX`P_*lx(LMwDY&Y@OXUL@!vvM@NPMm7bUKYs;RcX^Ckxu z#h?q@5^x%~KE7R{gX^Hg1!Kcn!*y%u42~9qEqyfy7sa6KIB1aYwt_F09y3sZ!S>kd zf%_fnua|sPdFo()Z^~}J+ClbaU;MOOS1AUM=L1lnyp8DF9vOQj0bAcxo;uhE68qv6 zV=!oewMK*B3dqy)-(@?+pnVw}MKSeRm;02l!>!&lAC=4Rk#l)@Vjo((V)4BAHuvm+B-p@Zur;~Jc{OsAksgJ=XIsPgczqaZ={uJ@#{M0)AH9P1*uj2bVu#iRpJ{DS zZGmUvn_eJ37p54rp9RlKitR&d&)4Vh{PS4wUOAVqV0J#!8rpHDwa#qWPBCa71p91V z1cj7)Z0vQmAHAaT-NF9N#IEL5vo75M)_FD4+FaQlsu;Adgg*0{J`A<=UFRzcbh%%} z_M=x+zB|}&VRn9hfp+!FKA~)nRSepXpA!UQ`Y;Nyca6Qx_M=x+zB|}Ei9IvZ+Thxm z)+$S7JH?=VUFb_G>BA_*Uf)fZdztM=ub@3RO3wF(5_@K*wZXMBt%b{FJH?iF82fVRNXWV1z&0j7UP)eUH97W*7+%KUvs^q+(+)j7f8@AK;C zbzc*>QZucoEzsT4Y32WYw4Gwm{vl}0=e(isscw`P>T^QK%z8zg6W%AE6E~Ptc=7aXo!M+`{^YPDU$MMf$B-<$l?K8}@=BeD< z#(wZLa=PD%9PGPsI~y;d?2zuYvt>KQp#47RR)FT8_3>TqU1R6hTfIw_?+*6;xSfrc zP7{g}eX1Xg#K z&vl`L{WxxC<0X_G#!Ez3%65uD`z>1)Jx-==>_@Zm)+<=q3keTqIbJ&rx>*F57#)}x9-~>?xE{^e%mHE zTF&<~xSfrER(2Tw9R5W$4&$FI56E_k zLHnst;kRYS;=A0t#$IFl(JLz79qeD`b~e+RvcpVk@uRYxV$eRrOlzLXJzS*gd_{BF z678{r{TtlQ#(pb1jQy@ZF54*v?K8}@=E+`num{J;`5rSnA1i`(94pfPyKJWzw7(kK zb;X|NCyhO1<*ip#zB|}|X4_LUt$|(5v^M#iY^NBsp9S_}@8h}-_Q=8hTW+@>$Kl<& znrW@_FWF8pXy0+Y+?m!q)%o(CI^V0hsM%8GyMz5P+n$#H1@K!m*gwjBM1A&+@8KiQ!}kq*OToO zgZ3#n2q=2%o|zm4V z2m8_7&SqLuc9?0cv#En!#h`s5jCEXO9f`j&Z~8o6H}<31e)J03gAdC2zJ%M^Ol!&x zGp&_&mF*OR_5(F65isHN|G?-+Z;_M=zO9y-`t+|I^zD?5zytQ{`fDF*GkLb4Y- zroFnCKG%(CE?c5KaUJm$Htz2u8SS)ZEj~X zttmUqv=$sE+bIU^hr)?2=NDd}8IP&>|2x-E&)D^O3QaHJ2?_ zzB|}&wC$;x*09`hrnP8^Y^NBsp8<6qrX#REzVm(3*h6bC$yc<;4))ubozJv}cAROg zv@G9lW?Iv^Y-U=c{|f&a7sFqJw?3!&Yw)T9kpIg}YhCl#;QP^k5BzHc$H`}a`|Q6) zYNj>#Yp9vlrpEIB8hWGw#h`r$*mKTZZP(M;&)CbF%a-a4;9&nFv-6qO(2g^$byvuC zib4B6P^LMv(0HI~pu{~NPsMjEJ@*2=48JH?=VhMCqp*+XOJy}!0S zcCgQS!RpC@dDYlROPp;CMjG@Y*-kNN{|%h^b7oreWUm@~sJU#Z^1V;a_YJu{J<>qU zwAMLIwo?q+AAl3kcI;TpxvuLc-`mDsXZz7BD&HOKZ{qfJFP55VZR#_!onp{_R{l(D zp6tOsI^S1oE?cU6cd+lo?dg#QG}GEuvOQEWX#eE)xg!lc*&|~=nwj+q+G7X%p4^@u zX`p6W>)b8dDF*HDgzJ0GNJ3BcuCX7ixooNOy(Z`TJGebP(m>6$R=!8JQw-XVg^PQ! z*SN~Qy3U8ptXEXNJJ^rn_Vh>tHPc%3YuQdQX#X?Z(U)yNQ!%$1#_So3ZVEfT4D&HOKKjQXGdmd+6 zo7zscQw-Wiq1!g+xBR+(^1b?YeV)&6(?$;Vd$>K*p2wNi$`#p8F=&4fMvy|2-un11 z_bCT^>|lSG+cWKXoM|oCOSV%C+HZi9FFyzQwwLzP<-VEq7f!yad|xc*`%~PWY0u+K zYw`ZFonp|wA++a|q6tC~LyQilB3_Y^NBsza1JJ2PB06-+Y&Q zXzcmr9y!=w^P=5n)yTAMaHh5LF|wUv(Efe6hs}9X)Ae(%s~LNK+a`9fZ_ey|ZVN1T zHPhM$WqVh}pnZm!);!tk#-3m9!JwS)+cSG+^eoM^cARXls2H^W1M)rRskA41+t^1S zqp}}$eRr@gOzfGN)&|$kv{o5(u&Wrf&w>+OvFEyAe|?_kxuyRKXpbE1`zLmo_aOBa zq}l>+Ni31=6odAIpwM$>TI>4B_mZ*KG?y*W9y{2NWOhE&8qNZNGa7{a`5fBMY^6jXh%f(JLz79qePw z&SzS~a>tq0DwoK1ib4A!(3qdA4?`_|mwW91o$ocaAHAaT-NC*lu}?eG+KpdYCy2f# z+bIU^ypI--$Cn-dEtSg-uG11%W~MbYxdqJVGU?!=7<6G<0tT5_AK$KEiJYhBCoVN! z!k%dj+9YbGwJ8S|#h|MV?XjGh*1CSq&#|ei`TeV*gZ+|}-F~%$?9IOLI=QY=4BAJb zKzSR{SDES&lBEN6o`zPA!3KW#`luH228ca=UyA6EkUHEJZaURUXLE37*!Ks zI}h|#6L5!E%E7Rl-9I(1rSOIt|8;fR0wV+*Toi+@Yyk;{}~(Ej1V%QP5~ z^YjJdT0PVl813)FS5np_=j2~NUF|ryCI)j>U`-gx!frR?Q=2(;j7&7AI35bmdUw1Vq8#y ztA^O48rlNAmkut9K^MO>#$)mA3LRW07#GYap1S*^Eqy_42A7J#`K<0_EpyT8s?b>JG?{^#1G4vOEJn015S9qjBk6**!kaB z^Hp{qFK729wtcj@+Qx$&wm|FjMcGazAf92UQzk(V84Ug?e1R4cd*yN{w4>zib4AY&_z@1*n>%9=jRpM9*oNQ z{+q-;+CS3Z<*v3sZ`fSfPBCa7hC07cABI}`F87{;J#?@?YTH{AW9(cv+7DacioZy< zQw-W~g)@!rL}e#-87+AB@TQz7ezYwhh{`ZBsi^wo?q+|5kY0 zrUb9#;63=dvsSbErB~GT-NC+XhwJ`^~ioxUQ72dXK8+)X=Y>D>B!M=-a zPql5puG%)$lVm%^puPCEO$jDjpmGnHS+A(;yMui%%bsrA46be4)K8P`6od9x!2``= z+cs5W&u`lV%jJAOgxgu$M%kfl6P+#FDF*G|D!gqI8GB6^HCw8Dcd)-dv1i&g@T?YE zJJ3^cv23Rpw2u_tw&^<9BM1ACZBMmrz^>XhQ&-7$ib4C2if`K-=8*3W_GV(wv~330 zwr!$oWIM&6{j}oSHV*b+g`DrF8vEi*+eU4H>wD>IvYlek{tV>%ku3jww`pTzKbY-D zuc&-?u%FB9ylsPaY}=G>cCf1$w7+%pAUHxFhFbczmk!r;zQ*>WSJd_0!Tv?to@(2G zo%(I=m+e&*gZ58BxgVkrLoI#V>&70j{pb~SeRr^5W7|`08?dXkP46$Vonp{_5}fCY z9i`JVcHU25+k?8C?>AWXblYaJZreN~+v_R@?QbZ&Z4(}$>wJFOCUmg>gxgu$M%kfl z(|%F5Qw-X7hx@o<^Sy5DHC@zfsq)>y{;R~EY1=Gb+qUU!c%j%=Nik^O2p%ObV#ne; z-#f;h-%lGm*#BVLQ*9fttF}#VbJUYm`8`uv{ zqc;9c`rX041iiQA%dhAG#~~~==Qha**_)f_cBx_eQ{Lw`75V^hxqpugbNV02_1(d~ zV%9!jZbSBDZWHaI+ogu>f2O(3cImH?{9AOtw_tA=KPUZLg`J)wnmWmN;6_I1b573H?NY<`(e%*8bff=@zQ)yIuNgll z{g0&I9qgx>c03`+-zTxtCzD4{>2|4M`>*KFj*LxzjpW~=?QPh5Ja02q@AnH#yYVz# zVyE|nmfqIwQp5JA=rQHvz1k~3O^^A|_&Mo+aPFaleYR;gKKCH8)8`&^zjJ|l4=Xin zKimH?4|^@;8vn9AaJN>dlm16?U3Rb!H|^icWlEnvR=QTV zOAXr_)THaAzee(J(e~0l={c&$Jp4$#Pq)t64<0`;`zOIDcOE&gd5dnB8n(|**CxO3 zP^-gkKSzZQ_MKqoS5M4)PZ^=>@@=|ZYS`YlTM#_vHTMSW_Scdk2m8LJ-MIHm>@+8- zEOMcG4epG5bb2YIyzKTD5!`|4NjX6nT=Q+vBx?O76{?lE8V3t>V7532h zIq82S*X5)1em~r_8*`GxPIHoAf^L@@w%_Fcn1|hd%!dy46SDRJ_nu@=?mgo>bi35B z{at!k!ta_xuy1k+-7OrE;Vdl+50iygq`Pg^!CXC zThi|i_K&jmDTf;G>EmObKFceJm)Gr5!}e?G9o~M|Te`5XF+eT3yt=m+$ z)9q5j_E+fj6u*BjAcoz(ZWB4!x6axJtlN-1S+}X|YPZv02;5||&FOmni+Mem?EFP8 zqfcZ#AUm=&jf5B(voU?u78}vuBu#7Zc^Apg;(b`76S&`JO3Ud_AF}q>d;*88<;D*C za3}1;WQEhXR>}yy7P*&wAEtJxVSAhA#`JPzW-GjR(!7TJkbcV7Un_%O>gSDpO}p`T z#1i{v^d9hib-UEC{ZTq+n(J{z+glFy(7`?~Yo`z88nE6=BeeGQ3*9a?Y@a~Kp`X_# z(zWj3!1P*4FMoZ_mdq0z?1vk6bB;v0Cv&9cfx2C4*nV;DI4nB%66|YyjeK6eJJ?Tv zo!<#)uJ_6ay)Uw++ogu>CwhPGB80uiI>51dzn^8=jrE_zPU}DIi*>uyuziO2XN_90 z+h2zb9qgBxc4NIavD3Y9{YKp`HEf@6gzt5~axLxm(0a^A4)*IzyKyg^*lE2t`cSt^ z4cq_Z{g|)8Za?N@2m75_`+)UcvM1}k)eSFJ*FdC(?PvLa)(Cd{XFde~r}z6KhTUBA zWIL~UcDL2-Qp5HU-k&w9j!chvd+wow{n@O2z?vu7lQqxE&bnP{*nXY&HP0CKvc2CO z>~Ci61J*pro~(IxcGK-r!}br!?)O=v4(#@0K6bEwWZ2C$Pqy=#XJ=0bds4&p^}Ii8 zR2!8Z^N}_8;5fbChs>X@|0L3Z=lNvKv$Vf%mm0PYqY16wwXY8B=6yrDBa(Fh2m2CP zJ3U#HozK(WNS-yS{6e=&4cq-cYZN)ShMF#8T`O_Xx>i`zT~fm?|IZr54z9IKm$7D* zxcF}!j@DgL!>-wM0Qr5^C>WjgseLXQM0%fYYTAu8tHe%gR;?p-yVS7#CTh}k)0Rp8 zE&Bee4ttO5vV(oQtbM?m71@(DtNQV}U253w|5>9B>}6vgr~i@McRSd3hn?TeWZrwq z2+hM!)a_Ek_LHi3ReU|rQzA{!n<|7CDsagAgdrz___nzVDx?O76{sVel#_zL6E!Z1hllr`M zHV6B8hTVMDi0%BWQR5ojE;Vf5eo5cY8ifa?x!di*uk?POW!TO8Znh`y@wr2{caj>m zzeDd|-rC5c=<9nM_Q?1->3<~s?qI(uYaejmP4?uzyZyLsmm0Re=Ka3AIxfwS^I!z zjVSlzS)0&j z+OVH*uOH!|(Ux=muIb(`k$m#X(NQp5J$=o+_H`fDWr7Jbau4@vvI$GWoEz`70DlXaW!>UMkjtWi91-tUuW`B|fQLUts1)(9i%vqmAlDt+EYeirY;XXvEi z_gSML{e6a1`HnxgCFhNk^z+8<*oVm~pYg1bjL_@v>)H2VYL^vpMO`+xjDYvf>$9PE>__5sftkv)0VsP$b3ds4%8 z{=3rVp;+{JBRDk8y_7rN)7)bR`!R;yeAbBVJVz>jPq#}A+h@{`H;==j?IqalbEM$c zdcU6xJN=2vk)tP!J#gM%jT%5%n(2<9ZKA8XZ za3b4)T%8^+{#ifZGk<5^-+$+Uph_d%^sDgqc4yu`{5seFhrI?nEwg>i#`f63eiQ8cO->=HxlN^!*7tS0)UbVf`W9xcMceDJ zoBKHZ&6Df<$$G!v3wzq{eWS+ojTxQhekt#b5xQM!*#2|+0`vS^w7mhlJ@?STJ{NZ0 zYxm}Izm7&~+v;|yVf!u=`q$6viaO?-u-kKw9PBT{p3Qyolr;Be`Iz5cw@VG%`G{L0 zJ^Ye?i_SfU-JW~wV1EyG{x$!b%l+>((%nI~OAXs+(P^4Ko;R}htO{`zwsLt zW#@0ouGqmf3@-kv!*ZGKM=oGU z=jX`5{u9_UxsN{V&@}hE$zH1IcBx_eb96A%M_y#MqK@bE9;6DpJ@?qbz7OpD%f6b+ z{c#%Uj@0c^!}go$nEysb-v3!%Mder9d?d;uUzgSjg$`2?NT#1xyP{E=VQTXdcR)+dnWfO2lb`> zK9TJ0iMm~C*gl7v#LT1Ue(%8Equ(9u*TBxXPtWCk42?vG>2|4MdrbFVtMWI)RM(*itckm+TevEFH8n(|R z`||0pk^EcqF(1O-qu(9uufxv2=9jtL-=&e#ak^b<*gl3HJlN2yy$XAees{2c2zw^? zsZ$P08-AH9=$Jo6w@VG%-zK-;d0icLd+xD={VUixs?A7hZmZKs{Z!p9HEchLzJ=fU zd<45a_uve@-g^Qp5HWz4vr(54(~3#PmFW57}Gi=ys`L`|^}K zEn8)_qL2AtayqZG=N>xP_k^8)+1GNpKS3ky8M<9+*nX_{xlIXnd+w2geI)GJ-22yQ z|3mib1-e~o*nSb^P9Is2*^17+0=qr;*uj1n?EK5FICJ3jePJ5uUZ~rphV2Vc?tZWD zA?)_tgXwy|9}9aX_slx&M!YvJ)$LNl_8FABd4E-O?lsu$xrYw+(_rV^f11lZq><)j zx?O76zOnc7d>wXs?vaE20@yRTXVz&CA$#X?-7Yn3Uxae^JD+dBZqGe-u+N5_b3Y@O z`!pKqUZLBihV6TK&%Ft|J@=rY_xmldo4Kd!v@^+Gou%8QW^i(kVK>(WIX&Kz*UcU5 z_ruO#^>8ltn`or=JKZidgOht3cKbSQ>LkIiku=B6Gc`o-g*nYEvJ*i>)^0Ywh zH}?wc_Vaw?U|)3M{JPE9vHk1wyOO`4vVL&}~0)JSG4`k1f5-lN}ttM~hwuxI=I2=x1jWbfXm+ogu>f2Mx-d!CPA@6qoL z_Dx{tpl0WCKbuD42X(vDu)RYMz5C6*0eg>rcd%~@dnWgT`|scHB75@*-7Yn3-_?7+ zw_vyD9y{1~gPn8ly)R)d_dtBcg>?gy{2~~5sZ%rfhH*~wy zu>CLI`@IZ%kL&w6dcV(r-N=38H2AS(ufC<*rH1XiZu9l;e=q9UgAn!}{qA6&2|MS0 zN-p=QG*Ww8w@VG%*YKWu74{ze?qI(Gb|ZJZ{(dRh8}I6NsbTvF@BLnf-JW~wV7~`; z&i&q8?$^;s`#s$*HEciDd+rhJ_S}ORdcQvodp7s}b(?3&Uj3(Tmm0P|O1aZVA7r+o zuW?P-?dSQ>!Tuub{LB6)m;0MEQts+@sbTx}^gb8!{9ClW1-tok(%sE#R*{4K9oUWB z@xF;Aen;21k9E7$u>ETK$z~rGZEwSF{+z5mcCdd6JAY+`q~^8~jg&vt?NY<`Z_#?4 znMcv~4(vVp{an4@7hL3P)@>&Cq2Yf-_V9nYU253AqxW-NFg2am*>eva>`TMWd5_QK zz88%&zSQkf!}d45_j?I;d+w2geO1_vexH`k>y9IPH2-Dl=i5ll;N)I`-JW~wU>^=U z=YB;l_cLjvy`XNFn!(9Egx#KdaGu`pTf?5oeNz98+-+o!7t`%h!*+h(y5DCHYOvdL z4;}0~!OpqAn9Kbk8YwTK+ogu>6*|wGc@%w~ufuNs92W4FT;Cn+`@){hz5jjdACkTL zE!{3PY(Io@_xrx}2JH6SV+Z><*m;jFGkf6mJ)n_z8Qm^5Y=7AMdAzz26Uq z-OPRJyc7MpWN!@B?NY<`Vcv6(Vej$!yMz4%*g5yza=C9wBdry6yVS6qukW5euK;%Q zbw3vHmh`)W{Vdosxlf*m`}c#$-Yn~OsbRbS`}Z#FJ^J0jei`h%$4<@VemISER@LoN z!*>7o@4?~eoVG{5U!eEn7c z^AYSl`rX0)5$wFjHX^CHtxO~F2D)8p*zSLQz5#oWes{3*pRD@ws~{LR#K;}j_Z`UI z9j@D@hVA~Z?=9HvxyKInC1K~h56R`eH;q&_((O{icK_G+76&bhym%l$DLX>G3CrH1Xh(lcg$-xpbiy+^-a ztoQp~u$#H37x+(jZ+u_3OAXuapnd4~eG?(t(fj=j*fY6jKHp{%*~9I0yVS6KU)p_U9!0NFH(|G*=R*hkMX+<;4U(GM zFKMK?y>6EpwwJwszD)~u`*}Wcu+M=#oBL$U=YL1`cqiR1HEj1kpKrr%&pmdq-wHeD z{Rm0T?G_%{MYl^0+x^eyJFwex4=&aF{Q=lBx%Z91a~H3WJ=#sTOAXtoUQS z`n)c5us;nu=RF@kFk)=~BzwHOZkHOi-%Jk{ZftyyqR(|D*zLJT4)#}J&*t9$ewpQI zZ$$g)cBx_er{wngc~%wJd#u+v*gt@squL^u`*+yBzk@xgVf!jHpEuXhiq1WR-TXP} z!IrGoU8eW@7qA<-qu+NWd-FiuE;Vf5jM~QU=N{Bxx1Z-j2m9iSrE6Ba*Cyw3KY&I$ zBXzsfu>Ea%zsx#m1j)Ze=U#`sN54DRhr({=o<2c;GTGbXb-UEC{WLn}%|0yJ-hkbl zKc+jJkNMcaz838KmDiHg+|Hws+9cgBHEds-&hu*<-=t`J6ZRhS`KI3Qo5F79p1wiu zezG@?(Ct#g_8sXpXtNKCw#TsBa}OQt+riFJy-iYcdzwZ%N9%T}Vf%gbewo#cZ&I|q z4ZA(}$icol>_+Z~q_4w%MfTPSx?O76KALu)-+u4HZXRFh4o~{s!G0j@{FSR+GcfmW z(n$H&x?O76eibcPt(5*6$-hPC9vqd2|4M`*b?b z`~AGiGVJ!;LkIgYuyaKF<#OMFMrzY_yVS7#MC$hqz2;tl-JW~oU_TZ1Ozu+;N|$Ma z$z<=Ir`x3_Ip)djcb&EhyFK^V!G0d>9Mw6w+#?!kp0C@bhV2W`DZ}$KrLfy`53bPr zeHQH5-1|SL^lGxVF4XN(GdQ_Nu-kJF9qc#3&bdFH%l&p5sa>SorDkw)Z@_NPJ#w($ z3%i+n+VHQFy?%*qmzu%Jy#>2{UKcyq=fcjpFTx+pV{9Lhy?m)|mzu%JJ%-&ruM1}C z{r)oSM(*R&dEGGD8>T$Ga=C9vBelzQyVS6Kg!l7& z7xo_g?qL56b|ZJZPwHo6Z_d>1Qp5J;D0jc>b){+PoYtOu>|kGb@$9b zKjd=1oJLx6bi35B-T(VxtFYV8^O1vnBiQ?MAD8(&>c@F+{9d<94co_2zkmJTv@Pm$ z59+Y@=ywPE2-rFIZZ7wiXrz9I*!e4Kx!iZ*k-K%f z)UbUDt=p`b{u;@@Md#ju-R!OOhbFJb{Z8-qlVCS;Pam@i4kvr`pl+9%!O1;1TA$a2 z4)(KQ=e>4*F832@r1Yq6mzu%Jy##xYes{264!e;%)@grF_Qq4XU252V5xp*B{!T?7 z^A*_b=lR&dem(4*`;)oc@1l{)v$|bs*nS|r9_P2;L)guI%mUt$exI%P`(3bSbMJrd z;w{d-quZs1?MKte(eLNm)L^%t=R*hkW3clcTjcixukW9bz4W?nmm0R8PUm^gufM}? zKhH-F_UBsdoW!f9f_jJ3|3{LJ1*n9N5gZ(YoIrlJ^`}#Ce{-cX)p-GKSrrd+1=F{~OtLn`yb+$I?jsf4W_2*ghXU zXyo@i--g|ud*onW3ieFy<0ei@*J-DdJzA)#f4)sp!}fLQbm{jssV?mH++zp(Fxa`@ zZ_MR>DUGxi(d|;h_6NLw-bHXsI;XYg9?a4EeFNAtxgR_R=lO>@_a$_@)UbUqx{vew zdDLat?YV~z_N`#&+~3RP{w$3&O1fQY*gk}=@5A|*@Nwyl$5ow(sb@->b0ObB`VD`@qgItwBG(+Y=4awD*fhOgWaBcaJAm= zV`0zaKCy3XdY<2s?48wgyVS7#r?mV0K0hD9ZqGe*u=l~vc^{C={Uizx<>_+bRK&w@0Z-hV8 z?NY<`A9_F6g|ORm4;}2U!_G1ND3|+2G}8F7ZkHOiPxqdC6?S{>k%Rq1*!y#zn)y4S z2avtIr*4-Tws+|IZk~UOKIZGNn?EOQvgGwR2m2SW^H)Z>+$ZwLUbEMzYcI`yxaPv4T%C+H?F(aprq`mKuY3N`d z3Onzy+jE)DqLJ>;^h~9O?J=Fl{Jy^2fW61H+rhpT?3vvA|71`wm+Y+rbi35Bo&Q!8 zElp&$qH}M-Zhy@scCc>>JO8rXT<$OP$bq_DYS_LheSzO~$QX9}Yc9d>^?u(Db|ZJJ zy)SqJUAsr>cBx_e4C;5k?}h2WZa;^I4))z)=iJvOsktpfBb_n2U253grhfOk4%vmh zN54DR4}d+B`_%q>^KHo98n4@>hV2j0&ZC!IGFwso&fhY*E<3o!!^K}UGMDKtG!h-6 zyQGF)JJ9#>d|kd?@6#jUGV;R1Pe+og?ckCcc0E8SdL$sT6_r=*T?BOqUyVS7#3%b1dy*AZhx91)@*zba!WBSI81Fy^fVf%3o_N0dGF}+se_Zim+ zc6;uTgZ(ksv$^;G4T#lvZ=9^#rH1YN8kyhMN}90SbB`VD&%@5SZ=cJ3BO0lms@tW8 z?MKmsWCi|a*oyA=7VP%igB$dIe-n1(K5^veL({h^2K$k{eWq@g8n)j_W}1#>wxaC( zEqOi`I=DWBi@)msa+w}NBaP|0OKRA)C4C>i^RdXm^%Y#%yz2PdOy_W34lb!-*K_3Z zGk;F!V{II(J^IwazQi}vH6qUR)?B7DX{6QAGnE>)PoSg8@3pA|dyhW7QSZ~CuxE0g zH2UE5y8JlV%V+C$sbM>>k@!8HLkHKIaB-&HT&6G4NX5Y=HSAi>yDM^VZ30&&uS3V- z*@J~{qHBtSOKRA)C57epdK&y+df#NOqi{03CHKM(_HAM3uUdzs=C&-2G|thFRjFY+ zeM8TmQ(AVg2RG?`x*P1--1~5T9zpizxw>6y*nT19?)MxOI@m)8`vI_X-lKB4?@A-# z`MOUDI4cq@n`_S)vEQZ}a9}6Aq zGhpZ3|B}l+rjhV6-7Yn3|C9HAZ^Le%k3|mlnXntV<8Lm!OZL*`x?O4pC-*Mw_S|C! z`wg&j?n~S}@cRB4+1n0wsTrKygX7YIyP7=SS(TOy=qi_BUbYuRJc7=>#5`rDrNNY#&bF z$8V;=AM`%`2(C<~Qw|!H&c|kutK#628g^|@O}civdy{{Q&NM`(_VaV-U>~w%cAez5 zT&7pjNOX;!snoE22YUTt6R-9v?Dq3>-wcqDL7sThV=5 z$FbU@PaW)=!p^_!x+FEXZ_`M4tDdRUu>FVrpLv75N1r;_w}ait9nb%SockTRU253A z8RhQxn%jiko_p+I-yL?&dvq@M-DsqJr*4-Twl747jyVq~`j~IQZqGfqP4D*uV9(}$ zC_ZFi8reH{>2|4MJKrn&J&%PBuJLejrWfZjJ%vWP4lb!-*XrI~k%Q}SxUzXo9hd%1 z$s5U4zFW^rYS?uqxjbJ_9bCu5#d$rO%j-TGX*sy0hFul!c?GxY{dERhW?tz7TmK|i z$H65v?7Ed)e%7OS&nNeu4z3H};;&lz4+F22Uy`eNkA56V4ZF6Y@8kEp5jnVK!gcr{O2P>|lQq zcK*s==W?GyBc+FQyVS7#@6^bC=RXnb_W4ibV1F6*Z0=K#`^CIB9?|Vm!}gtNA5zO_ zwxW)C{+3BEJGkC~i@)j~Rv6ngG*WeNNe#O;qObRReh%)``}7mIvU&BTf0`+HhFlE? zm(;LpHn}`sPaRxCO4&7{|K##|gGRzf_2W=#*yVpcA#!jn30F3+Bh%?>@XcH4bB!Ea zQo}Bu|M;1&rfa!PoLlVY)!4zlGVI)X8vpMO`}wr<{Pby>dmDCp?xBNy3)ngDLvp$AO(R_gyVS7# zDeu?Q4(#^aBM18qup{@w>f`#KyNJl%o~!3BHEiFM?0(k|gX7aVq&@f8!M+#locqjN z?$c?c^rUW=8n#cNem8%oqUI9mF<*k+o_lbY-tVJf&*VO-Klj_o-gsKKOAXuqOSzlx z=PcS@f!*B4oE~q<{Mo@i8Fv1vmvXs3%=Tv->`4vVzef{D&(D~_ZqGe(upb9|f9_L8 zjlt`B{~~+)Io&QbZ2t?{{pMbS-JW~wU_S$P&VAY2243HX&`9eg-7Yn3zmJZ2zjK>9 z?DpJ)yY+s*2=+|wqx-`tz9+jEZ`?6(^BBXjmKG*bP$ZkHOi@8iASW7zHQk&hkh4;c0D65BkJCu`-@09D*#4aN`?wP9J^J0j{sHXS+z&?XpYq=LOt(u7 z+xZ!Czqwanx1Z-@2m2SWbM7nLKJfa!5REkctJ|f9?dN;XJ%rt!dl2jWzW7q*| ziCAZ=kiGJSZkL+D$-M@!QH-(*ZKRuWGQ9LrgZkL+D$-N1?J@?>Vz2CQk z-N+s1`76lYT2Qx3&EVu7!*0(#bg=IZJLmpDF83Q~BwSdxOU>Zq-iF6L1==%Om-7Yn3Kg9dIt_-_9_t3$9D(sy5W+XMY)oG-;q;8j*#P0q2UV+`7 zd*on05B5y%llt%Db|HJ|Te@9p*#0Ql%{+>}hpobH{+u+m!+W7rU%Np$V+=Kh|e!mI!Z0`N{aldB!PzQTblOFSapKFR>x91)@*zbj% zbDxvTeFlwGSJLfL!}e<^cXKVN=wrSCyFK^F!9ExEZ0`N{arf}vSXH-64cq;Hj!+AB zd+xD={bkrW_t$c{Kf$@LuG^(%aB`1fx91-GN$>afV9(~>e;@ZB-WzM{cBvVh+&i$_ za}OQtpTW+#uXra(jcs8XsjjQrrH1YN_agoFdlz>T$`bGe5!5^kj1rDkw)FT-xnJ$OLx_tjy~_Iv+*+#zJ| zY^vL(hV5HY+xUIfD1_afd+1=_2zJi>j9l*1Xr#QkZkHOiPoRGH`+40}*zLJT4)zhS z8@c0iL1&V^@qOJcHEjR6_uT8S+jEZ{?7P6uxj&f8{YDz;Zll|!hV7?$&pm?Oo_p}1 z-tYUtp3S}g{{1DgN89OksY!G9JD+dDZqGe*u#bnGbN?!r`+GFf*w61! zd+w2g{Yco6dwo>qZ*465M_QlXQMXGC+i#(D8^6!nv|+dB9y{1if}L~UoTTQq28~p9 z*6mWm_7lCI>pHO8a}OTU`~7U#Gr5nQe0cgk`d!H$@2cCShV6?`?tY)A4NlVMb)kd( za@aZV$+_GQppo`&x?O76KE`|QCD`q`M-KMuVbA2A`8zBplRex+w@VG%Cz0L!TSrB& zT~uK2(eDoSyI|+sug>LuE{(K)s@tW8?KOHs)~fu?uoZ0&VYlZVJgoQoW3Xp(@0)s1 z+V3&hOZ(||sbTxIWcJ(dHQ4RBhYt4VVdt1$&*eUsMq&rM)Ue(E`zGqJ+jEZ`>~F!I z%^h#Y4?ZJ%=Kwu-sbTwCbe{M7KEwv><~$;8vSfYU!Tt&C{FN)*HSqerFpZQB)a_Ek z_A}|(LcjC6ChX?V$=ZWQ^nRaz>D;zep)W~BWWZ$RJThF+x?&CgI}j}T6^xnqk6w@1-p@Z`mqqfva{_?YTz|_I+UQ&;6iGzrR5C z^5ME&YS?}X?L)uwx+?7U++zp(SlBuDFLJrRLnAE*yVS7#NSfRDeQ#h5c6;u@V|u^$ z!EWR}KAq1meK)OL9I59nHG`9T1iL-=(7}E@?40}eNNR4Y(MarImzu%Jy#c#D_sGFM z9d;vkoac8YdpJ$cU253=DeXMJ^Z6F+_S|C!`z5e*-iPIK-;eD_JJ^#Nw!h|m?IMQV zo_p|Tz2C2ay+8NEGV8P_k-c)PZkHOi&!BUid4E;(+C>L;d+wow{dU+n_p5TbpF<<< z|I_VK!}g6ScfYSic44>Y9y!<_f<2RaW}WtKvX_q6?NY<`+i4&Ay}p-DPUp1t++zp( zGq7{+ujX=poO5@uOAXuKpkv-|?q%5Rxd)Hy{r)=aX71@5p+6;ie1e|4)C^AUA?)UQ zFsH}cHq>>YgZ)F;`KwmCXW;dHVH$}})a_C;IJsA0H=o~R0dH)N9PD4gp2%Z3RQp5J0=qH>n1;IG#(jeG7m-`QBBtAvAOAXsg-q+_N z*n9N*6MDa|2zw^?%->0$NcQ%bx?O76zA)`Yzw^2#?B+az)8j4acL)1Au=7`)k<0yP z8tF{e?NY<`ZM?5lwqUof(?$;V&0sfj$2#p5WG|ns+ogu>uTsC8zf;lu-iEzLzdP8s zhn;hOAeZ|MG*UWOw@VG%oAmcs{jSq?VDHiIbM=1T6ZTB*nRS~N$=DIqW%zwvrU|<}_uxsr-|vULKlgfO zz3x7?&vCFPHEciJ`+8jryFK^N!Tu!doco)(+@GY8_-frQHEe%|?0#RDX~S;MJ#w(W z0(&O+%zEADWN%)p+ogu>x6wZIyI$9Y-JW~wV1FNW&V7}82VUP7qmkNmx?O76eyjJ~ zgHzKvtv&bPDZSr6hdq;fX5HqyWG`Q@+ogu>LuvP!^R1%qTgFTabX5D5I*{grh?NY<`XUXh$-KGk= zecdK@u&)U_$8=^c_hV?Ja;t8a8n*N6aehCuu?D-jMv@+Ad@mC`t@ryTup7B!-DW1) z%XjE@sbTxs^pnlsspw-qg1tw-JJ`2{o%h;uygL4lhoYSppmA7U1|m= z_b%-A+#?73$*>!_0wu_Ws=aGUxe|`IvuH&s}QRzL)oNT?o59_t3$91MHmp)w$fy z<&i(@cBx_e_VfjQpS!5SZqGe(u-^lFf9_K=>ozgjt54{5sbTy4lso--<;+&}+@=n@ zJ@?qb{uu21%f6n=eJ+jE=IVB-Vf!BReTbjgin8;!Oy=r;)qDAQxH6fJ?f(pu&&U-! zxTJ<%cM!_&d)p(2OhX6zTd?yUTj_pkL}OcoMxrP6Or?hHKcsKr*WQ4=M=v|rKY=}y zduB~$W3soO*6mWm_N~co-ZK|5smgMBO5d9VE`mwSsw;#YLL)Udro{qA=yt_*vRet%By_Z?u*$+WP*gl^2A@MU?QMvQCOnTYDwI^KsRbS*XeTPQEH*}ZOu#2CK@;e`k99$#eGV;Pb z_0oT$XIvdzQo}C)=jRZ|s(C)(WO(CDV+Z?Tu=7`akEG_d8jUpG)H9VDw);OnS7Gnb zr_bwsdMxb7y>Ham{?8)Vne6dfx?O76egGZJeqR@^!`|b%>|j3)cFucJF880)NckPz zE;Vfbgr0FVpGhj}9F@*RBiMUfmmTaE820mW_Fu96eFu9|!}fc;=iY?f+{bCRCjIVU zpKaJ5&e?xYBb|ThcBx_eEV?k6zf;k<$FQ%Ea*co49=xFU`z^2={f@us_6FG-AL(|f zVf$9}ll|U%c3`)k=R*hk{jl?{Tlj&2=lPGw-u^_lOAXsMrx%I*=H7+fex8pU>`xl@ zO>*{?X{7YIZkL+D$-Q)XIuHN0ajd8Rk@UNR{T0K0P|m&+ja0wT?NT#1xmRFcG36Tn zCjI`R-tX_jZuC3uzfK@~W4Kc)qTvXMj4=lL4!J^J0jzUXq^=J3!M-i*+1&f@=R(;+;7h1-sF+>bi35B{R?{L&GR#^u=nV9 z2m3VGjodM>dz9@PJJ^#Nw(slx{kc`x?YYMe_LE`f+~3dT{ydG;Hr4G?!}f@-?`!fm z!&dY$UxVGAd+;~C-)F#{$$jb+^!xk|(cETh-7Yn3pGD_+zkjPYg592b=wP1-JIC}L zlA7DMXrwVhw@VG%@1QxYIo~Qe_Xh0t+#?734Y2p;e$bQ&8;+j03%*bG>JN3h)Uf?h z@7MPh?B?|(O)a^9cd*|BJAdT?x!iZ8k?!`oU253A5S{D%-owVQ_qe{lqWAmbu=nSl zeb3qy-WxyB?NY<`lPGsHkD`zH4(vVp-NF7M?40|IT<*uyNMlFcE;Vd_+xs!!g}q0= zJJ{cWJ(GLpb(w3(9__5#rH1Xxlilw#ZzcLDW@;?@S?2M@>G78IyMz5x*!ipeoXh=o z8fosL+ogtopAEeCdl~i~{oc|0eZl3^bsHmhT;E?Md%LRJrH1XFQ|^A(=R??g^t*$7 zY1ldU1s)!Feebe;4+ncv!}c${=U#=qN54DRSB2fk9rO7WXm7OlcCaTkY>#O7`Mt)~ zVYlZVJJ^TA&be=$%Y7XhsqU-WrH1V9qQ z9oTzZ-(S=F{czZg+;M%skL?FJ*pnKz^WX9_^C;RLOi$-^J^J0jegf>A`H-N+r+_s_}RnxxyMhV9Q&?&h&rbnX?{?YYMe_RC=B z+*f&oesN=4j7A!D-7Ymr?zBEX)c77n+e6sxxd*T7{eB(nncOq)cla*ZYe(pIsbRbS z&!DKmZqGe*u-^$gN3~Bb_w8sTI!d=o4cpiD{<=&Zc6;uTgZ&ZMGr4Ep?=Xq%tz&h& z)Ue(EXTmpNH?JpYqb1jO2m72S zNAtd*_nDEsevWRJ8n&NBcE5Al7VP%iV+Z@Ou(R~_T<&veq;#Hcmm0ROO8rj%m)VNC z#__l0`;_14)zOR=RLO4W4z0<+afg5 zxKOuC4cqUcdo=Ujsi;iT_rA4Z@6pQ+_Svv!b00S)&3$9CS1;A=Qp5HqyxY65_vmE@ z`z^3@+I!`4-V9npD=-h*|9Omk8>-~N|?AhGMADZSqf$XK(x?O76 zK9^2ne(h!0&7YI@Dxd2@2m6z-^H-jk%l&8?>0G7TrH1Y2&`2%VyAxhyCzeG-JW~wV1FNW&i$cW?l;j$`Fh#*t5C!f5z0yY`@vTp471YYU+2t&(cJ&oBNp4<1OiT2m7Kcr0Y@1m;HI* z_5B}YZ{MQZrH1Vv(zoz?eQ&^S&pmRmFAIA%_bFJD`8Ms1_H7RKq=xPOKYJv0aIFd# zXSzi$(=}-%yj^!m4ZGH+@8fwM{;uAq!{N&2)&DHSZse*vxTJ<%;|S&V^O0IOR_(8q zgbwztVdqTixl9kBkK;Ha}2wAK41ZFe2$77>^s43qyVS7#V(NFl&$x!L+jEZ{>}SEwxv%gz{o=;95RW{e+ogu> zTho2F-`uOP+j9^8q4)b`u=nRaE%W)k6|#p<>2|4MJHKbm@42oHyFK^N!G0a=9QU5N z+(*zz_i5cOHEiFW4ivw0n+SG$?vaE2PT0-d58OmnT*hF=zKnzz9E2H9IL>vpMO``Xm+eqR$Wot@6>?77Dd_8}`~*IO2Sfww{h<8=ys`LyZ`s7 zwqWlupLekD1v~fqi@Dq%V*7gz_N0dGyV1Ih-+qr_?=hcuu#YzE3(p;Rjr)-7@jrFD z)C^AU9oX%2+StK9*|2Y!vk#+@xa(j~Y6d6w;GA@BV}8a7AGy5oH7@At{eB$mM!#dd zZXdFjKGyA0!}h<>G4FTXrVM+Jes{2+0Xy%pqjR|*L?hi#b-UEC{T+I9uHW}ARbcPY z?+*5h4EyhL_6Ch~zSQkfGdQ_dVeirJ4)!^Q{rQ~zZW@W_o2h8rW-Iz!7tBcKHa+^?!Tts8 z{L9{!%l%3ksSeZaQp5Hy>6GDjZc~E2N54DR7hfq|v&!b)zi#sc+gEe2CpBz;mvZ;~ zOd#y`b(`41J`{G&{exWYFVRT2hHjS{wttIWk2BX(iazE;*v+5A0^XAO{6~7fuVvVW zJ~{9jw*ZaQ*4FJ(GdQ`|V7IT^gbwyi4f~Ecdxb`->*{u?8JyfB*zM~!k%N6Z*o}V2 zy3IjkuWzW^rH1W?(4k}YVbRBY6L$M~K6bG04m)?sskz(_r;$!Yw@VG%WAFXmg57?e z4?foW{Xp1_+%ccOjO@)#b-UECeFN|IHthD?LkIgL*g5z6a=HJWM%r8GcBx@|NS_s4 z=5L0r=wrSEyFK^F!F~+vncOp>ShQ zx!m8Pk@^pHyVS6~LKE6mkvad5qU|Nv?YRe^=>2{k?3vs%pFOe^z3sBOqi&ZPwm<5B zUI)8*JxOxmR_&)C^AUHQ0MRZ{uLU7j};O&|L06-|30uwR<9 z|C)2(TenLM+kZ}N#XxgkvzdP7pHtf&j?6>jAzPep%*nS8-XykW&K8D@= zTN7D(+;5 zmm0R;MP|Rx(>7qYpXWmd`!29^Oz-D%f0jn-N9cB`Vf$%xjr03#VGDNqc|LNm?+1G( z_snO?E%+C@>K&!qrH1Xl^lop%-lN|g?BikQ+}CEQu`NR*(KOvIHEe%|zJ=d8Z3p%q z{r;KW??=LJ>T&VT<*KjNb^|TE;VdF z+I#LL*zLJT4)(JR`>8qmku*|{bi33HPVN=h&DT8BX65_1*uj3eVZS+Nzl26=$Ln^f z8Jyg!urHT#jenEZYP9G}1Xiw@VG%{ml(1HV*IY@f3Q7rus>$lchA{J&`9M}-7Yn3_y4|$ z7VJIx-NF96VgF^$K9)urztQbd!}hDapXb}K_vrV}^?rZLu+PcaXV6G^hHjS{w)?-n zcVV|*<3b1fCx-pGoc$geiO$sRQp5H^xV~SI&TZ`Hy2!yk|0?OajWMsoXU2ZSd*dwK zE;VdlgywaA-yc_j-9E329qdcN&S%MQ|8?Mbem)v0{Z_Y24cnLT-tQso_G3QypWg4o zU^jE$c;5RW*C%`B9NjK8gVXOd*v<8!>@_ZQux|i6f93AE+`msF^%=TdY6hp@>#*CO zHHsYUTfsgc_jxOJ2a~;fo^F>KwwJy4djocJ4wcP4cCh~hcK*ugx!kAGNa+IIE;VfT z|32sz?Dln=;0wLq_krEaJ^kE+*<=qd((O{i_6sR@ziSt5*zLK84)(FIbM8;%a=(p6 zIv4A9sbTxwbe{M7{2ZB` zupbXQ=f3E(1F!F&kiFg1?NY<`Rp>s>yvHc|KCTRVkL&xFdcRMH-ON3`z7M0l(VeN= zrH1WeDR;kX)FJFWuI~=^OJL{Rf0)aCIE~b1>2|4M`!?QlufpEr`tD%A26i*|^gO>G z*_&7CcBx_eK9oDXES1@cKIZGN+t2f{gZ*~c`Ir4wF87H%a*-ut}` zyM5gza}$|S>1N$7HEiFM zp0_c7r=rhwrHj(JjeVV#-@iZyApJfg(pJE~8y+-%;#m5xuMGPUIr}IYsotjBrG|f& z|9M>ncKh5Wbg(ZmEM2qW-7+g@Kb=OR+jYCtu-*T>t_r((e5Ju|Lya3b*jI!d*Y~NT zGM`%*lfC&z-7Yn3zli$X@4ZYN_8#+j2m3m(^Im&Bm-}2A3GdeJQp5K1Xs`RdhmByj zAM?Qwz27&3J(GLpeG{LNy%XzpsbTvFvYUAneXeW5ZvLF?F&{eEw}+j-a;4`7UgH*_ zk@EezU253=GkVa-e1CG$_7?2++#?73p0H^as;D-@kWYx91+rr}z6|u=nSFP~W6^tMfrHfpdRc zw@VG%r+c5*1sA7tn;!3%aj+i?JLi6SF866PQktvVrH1W$Q|{)yWzqd!g5CZsapYh> z4fag#Q>WndxXa02e@eGY4cl*{edzbO$_nf~`rW~P0qmUnpK`gkXr%JAZkHOi-%7{4 z=QS(Xd-VJKdcV(xJ)8T~dfMhMLoyp#LLAOf{+sBjLTsJTJ8W+QE z&pmXozYja-eONB{{b;26vTm0ewr@i3f8WSBc#5{SVYlZVIoLmkJ)8Sc$o(X;H{R6k zQp5H?c|X^6VYlZVJJ=U3XV-16%H@6zjnv-O?NY<`RVnw?z2+WVlFn)Exd#jC{k|OR zncVxv;_p1(&AE4VyVS6KDoyIlxn|MFd>M9o?xBNyP1rfAS97^PP9vp%>vpMO`*rky zncv(iu-kKw9PFFGp3VJ`dGCG?f=|gFf2G@{hV5_By^Q%9VbQr)VYlZVJJ`2{opWE| z#evuNg=nNT|CQ?JRZ0!pyEK{qK7TW8McZqz+j9>V())ck*t5AGirgz?Z+=s^OAXsE zq}L|=u31H}+j9>c><7TkG3}YleFTk!OY3&2VS9zn^XnjU{vSo>-hkbnd*ooB0DCs~ zX%o}?xbbAKuc+IlhV83+e-C&Ic6;uzgMAw8oY3jH+>fG><}lqZHEh3x&hs1aH^WwR z?lJ84+=GSnem@!Z{@m-C*JZBYV}2doE;Vf5&-?2#9oX%;hYt1`uyafgPWF<-hgozt54 zi)oYbYmu>o{RY^RuY76X_5D4vmn*tmYS`YO7baFqe~skdqU~ka%{f&1L)jiIqWAkf zuxE1bk3Cq9_D1V_x?O76KEwZ7CG0)=-NF7i?7Y{u%;o+a8mVrs+ogu>Q|KCJevV|( zxmRH~dn=oJ@sm_Zp9EquZs1 z?HhZ~J%YVQzb~ry`=_vHa-VWg`e(#~)5#wGK(|W`+qWRQ`OII@$9xm^9{uiMUvSmz zy3O^u+%KY$=tsI;YS?}atz8UDTQB*yXnPCx9{uiMUmA8Jcf9`o0NE=$>vpMOJ1qcu ze(s_TyFK^V!M-Z&9MRjk-2Xx&)m?SF)Udrl$GrLcQ_;D1V7KQUET;GSaM&}sXI_W> zlI)#5bi35B{e0SoeqVUODN`;p$~HYM2Y zxknE6onSX|N55~zdt)!%E;Vdlj_iJ)x2eEx&pmdq?+ZJp{qtPzKcbQH-nw0C*ghZK z%b0VHqWe9B-JW}}xZdyMV9(}06`yZYCwpaI-7Yn3AB5N6VYlZVI@k|~opV1sm-}%v z(sr;*4ciCd^>^6qxknE66JR%T$LsHN$llpc&s}QRei7|MzvuY|?DpJa2m4vDbMAl6 z<$fEDMEmP@sbTvMyw7c#u-kJFzM=Q~Ww7_>J|(kW_ZlDbztHVc!}epmuh+$}+j9>c z?AO80xi9#)f!FsB$zHALcBx_e82T1|pQCQWZqGe(u-^%LCil#97c0`c6;uzgZ&ZMIrnXHxvxtj-7&gdYS><)HwLcD-wa#P*Y}{A&S~wr2TSPv{w(a- z-20!q_$lv=iMm~C*gk>!-S6KOD#LEiJ#?_Y2|LGhWG?s7G*X|W+ogu>3)6j^`MI%0 z=U#!`o_pkA{|NR>?wR*ZoI&b0ObB`VDLsrYK+q81IUrZx$pKg~L zwl6{x8^5nX*I>8j9(+^p_a$M^BIoWHc z>vpMOyZ`q=cVM^Y9y-|ff}P{uFPHlcJaVRPmm0R;;(eXA3%fn{$iY4u_Dt@Xb=t{f zkAJJ%rH1YP-!D_TJe||pbB`VDlVRuF&&lN;(MWW*ZkHOi^SX`S`?xaf_S}P#-tWi3 zZsd-2+N;Uln4#OHhV46eU#AUWx91)@*w28SbALRS`|UK+Iajw!4coWzKDVjDZqGe( zuwMjwHuwH@+SkcmzEHPI4cq@n`_S)tT^)9N?y-Y?4(y!!LY;xv_kVHj4tA+wyZ`sg zM6la)50=vV{Z`nG-0}Xnm1u9&F41$B8n$2MJ@+Q;_S{1U`vb6Z?jv%!uSX-LOLe={ zu>A*g=$OA#(f2Yf*zLJT4)&*E@6Y|{DM#aVnY}porf!!Sw)_8F;x_E&KIZgz+lKaj z>|lQtcK)iPa=DM8k>=&PU252VtoQ4C2X=ez!MF5&{{Z$h_tB$9jqbzW1wNDPAQ_;tKaD_gv3mxoVz|OhfkjwoN8j0rUcBx_e_LMtK=`&l=_7d#oK2Com zAM=reeeu=PHLL#I$Mj9c>v0c}y?u>tmm0S7Pxkv>;0o+L`rW}k6n5Tg@8)v4)#p$nb%>rAbaB;-7Yn3e~#|s z{N~<(-JW~wVBZ~f&U^n{?mwoH`n|ecYS?}=9XfvR-HV}yo3Ez*!ip4x!muhk;WssU1|m=_h4o^r|t3l z{IYt#p9gy;_sr|CZ;`$FXWcF}Y@b8tIx~-=ukU5pd-S`5eHQGT`(m#RyuSaNkA%6p zU251K)4Xm~{$|*UwpU>9(eDoSn_$o6-giWLnh(mfH{xe>yVS6KGwac6s*@x=e_Z^ZkHOizfE4h^ST!7_S|C!`)9CoL^tMgzm!J04tA+w`$@F3{LbfN z*zLIo%jx~T@EW;wn{lHupHuoU*`xRL+@*%?`*=UkcVM^Y9y-{Ug`IPMFPHnXG}8Hp zZkHOi`~RHMF6{Q)BM1BHu=n@-*ij=Vq!;)huhTtjSGP+I+x@>Ewsd7Wr?uxEJJ>gZ zopWD-cGU252VqW69;!*0(#SYGe<5wIJ%<8w~7Bzxs!-7Yn3U!MA%maQ^d z(bu>Tc6;ujgMAm+`IkK)m-|m>r22_&mm0Po>wRuhh25Te$H7jZ~sTP zOAXuk^XL73)<+$7d+xD=eLU=(`?2|4M`^MhS^DWrz zxknE6vtiHVo>`}TlaG1Ia!61P=A%RhZW~S=d(>1Klp414--q=(pKrr%&pmdqUk*E~ z7I|af_5EW$=I7JxQp5JWyyxD5-JW}}g5K}f!*1rDuG6kUd!w^}ZkL+D$vv2r&g;x| z!StBqb(_$^ei!WgmD}ZV-;hSS3+i^M8Jyfpu-n&ZBM19quxE3}W0k?r$zEMVw@VG% z|3`b>{GEzE&sShKuP52uV+Z^5u=7_QLsD})nC*)@*pnKzuRtd{zxELJ9_w{0>izx} z>_+ZbuWOLKUefJS!}k4YZsXTpgWZ0f4;}2Ez|MK!L{f9Rj7Hi^>vpMO`_=KPx?O76-lF$G`^~)#dyjs1ux|x>CijE;@835kdwYG|E;Vf5mFDw) z@87$y+jEZ{>_35>bKj4o=C%WklsDAvQp5K1>09`{e-D0_&S~wr2P^CSz7On~+z;u0 zA$Bs^33SFT;KR6 zMcXT|+jEZ`?0v9ja-TRkU7ioFCVP7a-7Yn3-^qKwS7GmQeRr@Q4?9Qo7)j0THX14a zM7K)~+yCOd-)pe zy#u@bJRdsPpMjlo@5|+0qmlMcb-UECeS3PdjCuYo`drtA-TXN$;EmTRBM1BIup7DK zeG{jUy}Yk(mm0P&M)z@kKj)-0JDt<^=ywPEhp_V=yC#?Wc{EblU$;vQ+egs4jhRQ$ zxtC$@(eGuw-@k(0$Q=!TFWKuOb-UEC{a19vnRyg#4`DZd4yVUkvOe!%U*bFIniYT5 z8@b%uJTgYNOAXt<q$$fJQ2Px?O76UZH+B^Cf!&^au$tcQhrw>< zp8j2-S!8b>r`x55?Zdq19$b~q>w3KY?qEL_cFz6LT<*8fNPN6*mm0Re>HYJpO0b)+ zd9r}Fq~9Ivr@@}deey)yzrRZM)~|KD)Ue(E{d)!W9{uiMzW{dLV+*`J@cP~*d-r7B zE;VfTfBzoB-lN}F*ZX}o?AhGwo22u)6=-kNf1}%_hV6f(^*X=j`5Nr@+(QTZEwFR$ zTjz3Lhej%=>vpM0`rZ57rVhJ3_sGG1KkV7u@o^Wyo@6gi*X>fncK_@14cP7LHnD^K zN!U5}skz)o(n!6b+ogu>{@3T5u$$`yEZ~jL^T8T=zrO;zkvrDsPbGWxY~3z3Z1=xD zAH&|G-yQ7l!_Ir`+Fb7E(@5JJ>&m-N+r+_xs4+I9Inz4cq-+ z-@CBebB`VDi>{Sjw|O&{`;#=%K2Ntx4cq-+--9{noYtOuu%_Pc%fW8uo_>Jc=VY&5 zsN1DxaB?rh-eW%RU|$n^r!DeJH zU8>uqhV5HSelJYS_N3_tz$Bu=nWq@96!$8|-H8 z=>@({_U0A3U252V2kk>zw#sZpuUSQ~_vm*A`vI`?FFPZbdqg9(nYvwS*#0*fZfbJy^*_??BVZpyVML$?k(8uxyKInX|QwdPv&y}Bah71?NT#1xyP{E za}UG zind3vn?EPr-N}00I(ol<3cHaz`u!2!8xQGrsbTwZ^aXy`=bNzi=ywPEf@^2jZT^wV z{W%(m9?|Vm!}kBt`(@TiBS`)&I`j~whf!EWS!NcuYL(QN;RgFUHX`+d|le&=-+*zM=}*ulOp>>Sl4x!h0X zkq>mc)Uf?+TCiHlYwjWJ_VawOp5E`{U^jA4+da66?A?!byVS6KI-TeJeqLn_c6;uj zgZ*&WIjX7+@~ItF4G48AbV-Z@6^w? zks7vNMQ*?Av<=wpxyKInvtZ|_mi))S>-*YG!iYK+ofi3a&NM>2|4M`v~vn`3mek z`rX0)5$s0pc%RhMWRJh0+ogu>%Texr*XydV+jEZ{>_gVcuG{=Om-}lp(pf^cOAXt3 zz0U7FYz=mM?!kt7zb^@UHut`XY4G28pAO-rbi35B-T(VxBiQZd`Ov|>GVI*%8?n^b zR-%#iw{*MIu-*UrVH>d9&-0OkeLdLwb03%aJnA2ly}X=mmm0Q@qkgC5%FI^u+C>ZY z9{uiM-vW02Whdlv--kvT%jN} z4$rSmbYQpV9y-|ff}L}}GM9UUM(Qi;cBx_eFuK64%ij!J(Z_rjc6;uTgMBpYncT;w zXZawwgOB;ub-UEC{YARQEeALMkD~3R>(V)``8q)QLzDG+2m55$`72+{<^C||zLsv6 z8n#cNb(=NQUnBXqXnPs<9@qE;WObdkA}ves{2+0Xs*u z^gjn)-@hVzdlTI*HG`9T74{ze?qI(Nb|ZJJ)2>5%qxyZ_E;Vd_&-;4=>#*B%j~(oD zVCUR-&gH&2jfC6kcBx_ef%JNu-+qr^x91*gr1$%+uxE4cf9_%w*_%7+cBx_e9BLc$ z{9E+7t_i#Ob2vTT_&gsv*dKtMzv_fs?sXce?xNeJhV7@*dEW2qur1i_=lRIN{xs}H z?l{k%Pxj7Ux?O4pC-*k&J^J0j{wnO8`<=PmXVXaIXS!W#1}FCp>^=H@W4+%$fZfO) z=lLheULL92rH1Y6dVi)g_L+JWG+&FlOp4-%6x91)?*tdf{n|uG~QU8+c(FwX; zYS_M`_kM4{ZqGe-u-{)y#*zLK84)#f~bMDXOa{m*JlpDHTYS{ja_w#%kc6;uT zgZ&uTGr3Rhf9~R+yfd{6K9xv(3#;{&ZOCVTUG z-7Yn3f5ZDaZ3MeL_t3%qGVC1Fy}8`4rIE(Xx?O76evkLu8?f7Rj~wjp!QP+y)Xd)r zeU9wadvv?hu>EZB*Y_6e_Vaw~VE+_$&i(UT?r+gZH`eV^!}bP!AL3`WqWYb`W%Ay) z&GcSgaJ~GR%+$<#+n4%~?$PemT~foYo#-5H9%n_lHk>kM2|4Mdrapszt2#$VefJ6cCfDsd#0EB|71|GBiS2|=ys`LJO8aHTAIjg zMd#jy-JBz&KQei3-N8N_cK*rZM$!57S8PuewWW z*tG+FAJ5n2E%ZK}4407?9)9{4xmpe`sbSXxgrY|RGF#E-=PHiX9)0RyKMr>OWtaWe z!0Yl58i}6MGnE>)`+wH4278Y_b+DfSJ90mGROWBCu1EIDi@IHE*nSP=?sx4pg1yIe z*};Ah?40|~x!kv)k+=0%58u}9Qp5Jg=qHnDS|G=30YFT890Noc$3Ri5AiAQp5K1X`#t)?k(7R^t*$7Q`j^8 zKCW+SdVL@AG0kn3((O{i_D^X(Z_cxeKIYr7_vm*A`*yJN5wiwK&8@`tr5)@^4ci-Z zefRsBGacA_^!wI&zwZuvHuwH#+P5ToYkA!+HG`9TaAP{RF^{h_wWQx2><7ZmU%6i{ z_aC!;1qXXl!*+gC_R8t6k^EcqF<*k+ejgV(*eAhmy?|yR+VeirJ+vxp%D(pt?nAgoAdt*J_E;VdF zgL3!#Ud0;h_S{1U`+2Z)?tjkZejDdLT(?UN+naQK_xntH9d>)}k%N5}?3vuB_CMqL z8rkE`bi35BeHLBc{XX;7fZd*Z>|nnMcFujlPX=D!KO}qo|M7P3@p4UPAHcV&TM6S< zmsB%^N)QH(6eU}UAi@x&sG3|(PJ+ZFC!uI+yOmOmSJka*Q1_})b#K^;s#}dqUbkXG z-Kv^FN!2Cq^UP!a&R%D~Yo7JTtl6LU^QPA4Idjf;|K{0y?KOL5w%6@a!}hyrPHWD$ zI(?k4!fww!7_ImF{jm4v-jli)VleHE!p^!~YS?}tUODN`{R_md41LC<9rEr^Y^6fv4edm?EI6>Oztn!NOLdU zE;Vdlp60ZEUy~}sZoiHTcG3HNYs0?&#{=g!%kjuQx?O6zlY0er`*S{Yu#YzE<1+TG zX{5fdZkHOiKji&5UxU5P>v0bD@vs~Hj_dbcvRC)l?NY<`L&>gpb=d9my4b;f zDD2$tXJ&FghDQ$6?NY;bT1@lY?+w`P^Sa=BdcV&w?6+s^RT_!EuiK@jJGlpc(C0Rx zgZ)^;{!YgJR~pG5s@tWeJGtj!H?J4@naf-2^*9InX|NmpJ||h9Uw#SAZGNcRrH1Xh zdB5i*guP9_JJ`>Mo%h&qlA7DvG*XzN+ogu>6KTC}J>x+-eXJ|O-lpGo)%*Pl!+v1K zKAJ`_)$1 zo%U+7=a13tQp5H&sNemr)7D^b)9()U$6)6c{YxhIKhQ{cyl$5ow!c8H%lPg081^>( zzMJ0fFBtZJXY8+V?kDMXsp(Gc4cOcCyMz5L!@lW%1|H{Ep^@-3-7Yn3{|n{rx8H-? zlDSQres{2c1beFAQ?I}8M)us#b-UECeFeIHCw^+{^f@jMdz*fDurIr1dflcslluf3 z$)By;rH1Wa&{N0n`iyRyHK}F zO?PsSV7IT^#18fy4f`h<`>QlkzF4ZqtO_o_p+I?}MG=o}J14FdC`fpxdQ}?Pc%x zRR*^w^E!L(!C1ZDPl7#_d+L4br;|OrRkuqG+x@T8=3%$z9y-|1g`IQ1A(Q(rX{36a zZkL)?zte zIi^LK-2ckCFVO8$!}g8*&+A|}&nL+fjpud29(upu1-p^^;gcrGO6|v-`~A9IYPyqq z1iLwpNZUgP`@^vFPj0{y6JuL}Mye0!cB$!3?p4_BYZsA&eW76=pRtdmk@~~BU252V z2<<+<_uIs7dwFO3u))$LNl_9JLs=XbrX0lRtMZrUE~srUQ) zu$%op=Sb=ItH@q`QnyPD+x>r*U_c*VMlX2M?`qTU4)&$6^Im&2llvcNBzj7>OAY@$ zqrD&J^RTz+cL)2Rt&%k>BX`W_Un6_GP`67B+b2>aeqVnNVYkogVh8(R*g5y*J{@?R zf1m967j(PSusx>NWrp&DVe9m~t_Zt*UKi}8_xo_z)43lzsr=|??gX@cjM(*(?9l?NZa7+zYUq z_c(}L?7`l8zh7+Fcg)x~qLJKU-7Yn3@4~tb?B+F7+8#RCuQlv*GxmdMq|wyvQp5JS zG^aJ^937wA!2ZpIYy8`KJ?n_<5uWB&z>l>V*TrH1W4@P3@Hz}}|c9qbPn_NOxT zyJ;l;NViK3+i&oGoUg&&rr*cw{r;3;{~}}m2aS~fquZs1?f%d2b=d9axX{7=s$n1T z`M~4+S~ODoM7K)~+q-anhuwaxiyZ9l!EVg!W+eC1?m_m#XS!W#*uEn5yWjUo|p;Cc0N=dnaO=3jf9`;cBx_eTHgCT54-(2AMB&|`$~oXXWeG*oEh7E8T?6P zFD=#WQq!G&4`DaghmsQ=pW{LY`#P}mPhOMB{X80}2G^;d?ISha>GvY+_Ipku2m2i^*a{nuhgkRO|Qp5I5y!U$r zcKf_lyTESdp1cqGGqRVL*X>fn_Dd*tzpu;GV7KQUI@tGxopT@h#lZ9XAR5W7 zsN1E6?f23{_)}k%Rp(*p1xrxx_n?z5X@bE;Vf5lydibKW!8CHs^N-`;oA7 z?mx`rz88IP-ON2X&ezCZUsJbB z4cjMD?)0)$YU}iKz6iVhI3GLMuY#Tb*yl32-%lfjwROAHbSL*R?Dpe)u%F)Vw;1+i zmJU3}Ehc+;UEMA-*zYs!TV(8O(@40!ZkHOi|ImBC*I>7= z+e8lbCk*=!GxjkwQr$qeOAXsE^xp4v*zIc0@0JcKbSQu)p5#?-=&SGWI)YBpRyQrH1YP=XJSz^tnywU|(X`|C_NdqLJFhx?O76 z?tflafZcq4rH^%ygMGQJv+Fj~lAEmP!Pcfbn(CYCcBx_euf5OfimT?TEC3|gq-7Yn3AL+f{Yp~mMj~(peVCTJdZ6^2gX{5P>ZkHOi zFZ6DYVYlZV9H966!LX-tPkpb@0rH1X}y&vbBu-lLGk%N66>_+Z*U*v~mukNDTrH1WC(vikoPwDirF89Y|Ue~7I z9qgyT&bfbm84AtVzCt6p-E_Ouu>CNa&-*>U=V5Qt?+5Dreje;b?zoS73$mB@(Ct#g z_9rQKb4{VsxreaZa}OQtm&49+@0-beM;Zyo>2|4M`{$IqxsKLpdl7bf?vaE2CfHNC zr#|nZhwViNd#i@+chElcyFOor-JW~wV7~`;&i#x`?sIu$Kiw`hY~Prk^X9py)44~m z+j9>N();}p*weZ9f8NEf$zGVC+ogu>x6%3Cue}Pp`Fl7$-dgK*4)*6@=bySSllyOJ zqPt^OJKQjG`r9sfUjFCIe?}NTVbJ|I| zU251qoSrD=+Ht3I4;JY2y3oPC8tj~Vfu!d44H}82>UODN`+MHs7ny_Io_pkA-vIVh z?y1i`*q!XT?fHBzrttw@VG%m(V`+JFhFj-sb%7U>^%R=U&a^em2|ZIM`b? zZ0CpYdyXr^-sb%7U_TIcBX=C5o^F>Kw(~t^ey`svu(#=V2m2J*Irrx?xj)Dw zKho_|!}g1)--qynVe53iS7C3{?+5GsJ{$H_?y2`h{)_C@`MOxPPlTQS*wvREcz*w!?4_URcBx_ewcgih>#*B%j~wi0!*1k`_eE|>dm|U=cBx_e z8MF`m=H7(eo_p+IzZ7=PeXmUJ+tEnX!7epypW{9E;NE0TYtKD6MDO?OVK;Ke`zA_c z&!4R4E;Vd_oA#mK_f6zsx91)@*zbUyb3Y}M`_VL#J4Lrk4ckxlo_hgyd+w2g{UO+m z+;Knc#r&K+j9>c?2BRN+&{|XzKHE-IoMk@ zZ0FB8*^D0yTc_<6*v);M{KD4j?+*6QVNd5i8{apv@>gkn{(RjoHEiFEa`*c>Yz=mM z?y-Y?5J9?8yD7NmF{U zK))N=<4bhA)UbUo+Ii+4?3A5TX|26GxQ4>TKh>MbbOMd!F4bL9!>*z9ICT0>ZJl;S z4z8`>O6N5zdAma}pIo7XOKRA4J&EXLh1Aw*SM1>05ib5is+qigP9seRm(;Lp1U-)5 zyn@5@{@N3+bY5lTbvwE8ztW$FQp2w2$>sODsexmQ{kR%B*eAlynZA(8^dTO(Ot(u7 z+xZ?3zw2X7*zL#F$idzNyOH~G$vkQ?*~^#fcB$!3?z#JtYeswSv4g!2cFui`<;=4| z5PU)QVpX?GO?Pt7!*0(#_@UnKC&8Z1ea_4z_hGa*;wyE#)Ue(E`_V$!?YV~z_H$w9 z+{a~dA4MaD-{^L!Vf&8s)bab;UlDeD?vaE2GT2kO_ilsxmM4+De64Pm8n)j}`_S)k zz6`rP_t?RHBkY{}shQl%ocndUU253=JMYK&2zGn!!Qpzp-vxUr_gTF?Nxxr0_Qnmm zU253A15H}|UN==?w|@?B=wN>scFui4Cim-UB>!98E;Vdlm2&s{8c^(Dj~wg^VNd5i z9l1Zl&-vf!cBx@If6jp4xlO~t9y{1yhn;i(IFtKpG*Z7=w@VG%&m_Cw&sYfJWNu@B z&IcvE-`|HloqHeVb*s=@ZA!Q3cB$!3?s*4$=wM$8JLkR?zp2RB2J^_Rx?O6zlY8i3 zj~wiSzMZTQrE{N)^|3Kzulzx`OAXtP_kNr&IoM+d`(W5P?&+D_51^6U?YdoR*v|KK z`90P}4)$P@-tWU^lL=YB;d_p^EA zZrv_5Y=6-EalQt-eO?zi*vG(b)}v4edA?40|HncV+O zBb7hucB$!3?hV-Oxd)T=exC$;D)%{4aQ)sSd+A=?E;VfTfBhcZpUiFSxrYw+qhaUV z*IZ%X`F$xr=kL?)Qp5Jm=^^}Hzvp1L=N>uO=fj@PecI%t--q+wctE#H4co`iO^m~M zM`G*Ly84!LrcRnWiS96l-JW~wU_T3X{!{nPAjguZ=jLfLOoNdVf$`$Q1ko# z!7}V^`gE$^r%%9cfn_OUbz)$_`)aUrmNPP$9!MkMtGZok*v=o_YaTl~^;}Knkl~+_ zYlk*{>R{gh_Eewt_29gGBHLecu(xX1z5+d&J--hKc5@$ddc3uI*}=X!?EF(#W^zA= zMvAZNcBx_en`HNUd@jRo&pnu?_xmW=)4BJ}PWt^$&ixJDE;VewmiD2a^)XJT)yod9 zUE$)NdMT6X!!*)#a7hijx-frsaP0?IIbgh*Jo^t~lX*k%WhV5(lpGU#orcZnIKAj1BD))Kwu&%Wk?~Ql#+@*%? z7tucS)2B)9G3@r-LkIf_uygL?Gr4b1BUJ~x)Uf?&@5kpl?DpIv2m8-pNABgxsn1oL zLiXrgJ$I>LyZ_JMXu@vKJ$A5P2s`Kg(@gGjXe4}3w@VG%PxapK!2|kyESRqM`_-_g za_^ZvFFDTtitP2px?O76&fjc?6<30YF{jjHUPkj!)a_Ek_L*e&drwXgc6;uzgZ)X^Irsl$a{oJx#2@K)sbPDG zE#q{*_S}ORdcVI6dn)(7xp;r>s$Zjd-DkR8YS{i;GW+fK2zGn!p@aQh z*g2-HNosBz&`90EE;VfTKd-C6ZqGe(uzv!3I(ICO1!KwH{6f!NYS_Lh9q0XCch_LI zfBr`7U|(UoWUYzwo}S75KpM#h*Q?)eB{gh6hn_m-=VEla-(%R#-;+FJ`T8_CLhtvr zVK;KediZ>@*Ot}oQp5ITz1thGx9N8W`%u_>is?*b|ZJZAAd2~Ypd&asbRbS<9rCaJ@?STekkmm`x+|`JimXz&-pcU zyVS6KA9@JCpO;&N-JW~oV4nedf9}&#{XUHLM&awaU252V2JJ(?^SUzZ_S|C!`?0Wd z?&C7KkD`&-!7epyKbGb;e!tr*g592baFpKfr@?OIj?Z10MD}o9J$I?;PVQCM?YV~z z_VZ!q+)vHqUZ#<{gI#L6lY0$zd+w2g{R-HP+;N=0gzUxj_1vX~?fyS^r4GA2_t?RH zGwhuEf=uq$vwg6Gy;Z~Z*SxP?G+?*q9?aDHeF5zKxgVWcr+tR(;Wu@=)Uf>mI@X!j zSDn6=2_Dktb)kd(G1xixk2ATyMk9?Ox?O76P9J9C`SsHr?DpIv2m1@Kr*coN)2^}# zUBhmq+ogu>chNrddwws#-lpFj>~F!&xo<^Ma~n(}4F|i_u>J4!ocH^>c?i2b_h6RZ z?;pW#=APVeJcjJ`jrH86raQTpU^mx;lhj(TtvlG49hF|UIU#Zc~Td{5@%VBRo__l7B8n!Q@emDQ7PTQNX zx9N8W`$X7zudO*~;Q4(i+4G}xyVS6~N}s3acbzu)b26uG)9+=y-+N$B<(^u%8BTj6 z-dVRx4cq_H$w9+)vNsK8Hpc4tA;OPVObx?en@|w%+fT!EWS^^}1h^ zJ>FH%U23|Mdjxx%es{3n2s`I~erH1Wa(A>uF>oPIy_S}OxdcQA(y+8N# z_toZBCHr0u_Erts=XqbRYrt;LJ#?_Y4m;<*ElJI72#wUo>2|4M`$F%p%QRuP=N>uO z--kVwduqLIPqNp>>vpMO`<=A&{I1vK9!}=8_S|C!`%>6B@1rugf1gIm`{;J5Vf!84 zbI-$W&pqhV`+d-Nk~OPT?x}T~lgVBv>UODNyZ`UE3SqbB9y-_u!_K*1oyq+?8Y%9t z+ogu>E7B9*@Aq33VYlZVIoOB8p2|J7ZgUUWOA~dw)Uf?I+J}DcuPeiDU$==J?4w}k z-2axz{Sg`ozpvY+hVA@%oafJdg56vrVF7Qg`|IZF{XPbEBX_LZyifMRp}Jja*nYnE zb(<>eZTj88J^^;#V{5H8@cbUoNc}L~E;Vfb5k28I<_E*p={2hw>}~qp!9EH0RPL#D zo6X2xoT}TUre!Cy-}8GNc6;uzgZ*gOIi~TM+_&f49qdxW_Wiw|-y5*oa}Va}{XQRd zBX?ZCPa%6@nx4DVbSL-VFZ#SLbg-WVJLmq>Ozv}Nq~>6kn(pMDgWaBc2*!y$uOC9GI@^k)3J$I>L`+?q%btTyCxrYw+2Vm#i|C7o6?=+H|soSN7?PDl+ zzxQ2~VYlZVIoO|qy+8N4sr#%}&Cz`RXx%O~Y+sgg_xpWz71-^$#}4+FVdvbpCaJk? zKqKX{ZkHOi?@tdv{M6Q|e&>g5&DD?9d-+|sQknMje|Obba@8GNQp2vh3FY@QXQ~dF zh7R^mVCOw{L?+XNXrwYn&s1vIz8m$jUwaMqHofd%Ut#;~nhYJnaqf=D-k7V~rH1Wi zlilz7a~<|Jz3gCL8+Ok9s!Z1>Nu8smPPPLGFP{+$%GE}tzqXs_Qg!@57S8f$GTl=*uJs% zb9WAQ`^;;kvrC87W3XXQMXGC+pj0P`8Rbs_X6x~`rW}k9(K-sjnxO9yT9P) z{7Jf9YS><&e)qc;7sB4A-;dM#{b1Nrxu@pp!)R|bPSfpD!}b}p5B+>*5vS9-57xoe z0~i0)xJ;&_Xr%a4-6b{b;(Md~&c`ALS07wPUN|pLB3I<#k{WjLdlmg2pG$bIw&_y` z`$@2Krl)2yEz?NtbUjn4VY~n1a~bwFeR{m!r{}_s-22k6iC;qY#?N%S)UbUd2|4MyZ_h3tFYU1j~whb!k)@KH4lG=_r}?}U253A z9-Wu{t|P^;+jEZ{?03P=xqqC={WZ@0T-`1;Y#-+Rwb454_S}OL^nQOB_EhevdH5=8 z(D~~Zx?O76?*F}tP1xJa!yW7kVdvaOkks7PXZr;X_Ertszd{e;cRm(8np}gJbKc}H z=Xp!yV1FHUBX`Whzeo1cMY>&T*uIJPe$T_+rr#ax@59b}ttXTFel$|KM7K)~+b^Pi zACg4S`nTiPAh5UT_aE#1z7+OU?x}hB31lx+b-UEC-T!A16k)gL9y-_u?U1ZBaYVn) z=Y=4{fq2D$02zGn!v4ed$ z?40{^ncN?sk-}BFU252VviIC8u-kJF=Ii}F3U(uRT*tk~&-vfzcBx^z|MPndc6;uj zgMAF_oO^D~f#>(n*nYKxy;Z~Zr@f!!V%Y7uM-KK0u=nRaw`b~kCNS-b9DL~*MQxgd+cDJ1UpOj%;Y|jM#?wpcBx_e2wG_JYj47C&pr5w-tR}l zp3c1&-*tF6=YF$pmm0SJmDD*_`O8WgGvX}1E?NY<`C+QsL*B-)d{vJ+`H@=pM9qbpw&Odce zCiiP;q;R)xmm0SJf`0SL{9xERoqG{>d+x!BdcR)_dph_2?>2pk?DaqDcByIEso(vs z+mvCq=N>xPZ-bp<`gbPx291vpMO`}^MKHZ|Doxd)Nn z@2|q%pZjsCd!Ke?`=bu_Rt?+z-}6?7-JW~sV1EyG&U;!W_x))kdQ7)V4cq;H##94# zd+w2g{ZrV@+z;PY&hS4bd;ElMmm0R8Oa1Qme!t-HWL{^ki6-6J>URhGN;{_4ZLZ4X zem0F1pVaMA!*>7oI_6>jdcrmSWqWXv-tX(cZswkRI`}UWO2M za~_fG0Jet?_Dx{tpKN4ue~d<=r**s3u-*UbutnJIpG6Qk*tdl}l{>vhHTi6@C1kHX ztJ|f9?Zc?w{jS%QVYlZVJJ@%Dopb-j+5^w;E6_+|p>CHNw);QMN3h#-4^GzmeP7s9 zx#Q}c-lbU^*6Mc$`(d#2Pwk({J*1J+3%Xru*#2kl z=eQc|=6#ne;EnB(gZ)U@)4BKG2Rn`Ig_m@@)Uf?f`psq^cKTYT4!eC`7dzOGgPr%- z&oa5sqmjzXx?O76Uhw{zat+w+^Sa;^z28rVJ(YXv_4muk9>1>JrH1W~(sSPL+C}h0 zGOug%`n!Yu0@ykCIFtKLockNPU253Ak@t1l9PH+rC<}ON^}B=pD%g$O51%wi=JN|V z_jh!=)O08J0_<((^A7e~VCOydStj>4Irn#UyVP_i_af|V=JTiO{eGWe-{R{7=QeB6 zNW56LOAXr(q2s*Y>$o!P>vCY3t#y8Pus>ngr)2EA(@6dU-7Yn3KY}h~%

    c^f|5q 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¬?&w`zEzt_tB8X9Sg)9q5j_9|VNSc|_Iwr<;_U9&l@Ifu%A z;EwdlOFZnS!=B51Aol24&i!!RE;VeQ8-A@4_745-VLuOc-fN#)xxc|96Lq`PuzfO} z<5tTeX#d;o+)J>Vy_Nk?&ON$Y@AoTVH*?SKt6cWlg`#AVZkHOihrjQl5B3iI?qR=h$-7Yn3-y(SKW!O9PyNCS`u;+50d`R}V%4iR=x2EfMsbM?)5s=8d z=datZ`2_Y3{qA9Z0(Q=OqLurBG*X(S+ogu>*U{QV*uN)Lg}p<+-=p{Y%di`{`+V;gQ+8U251~rPsW9|5LZ^ zDeUgt6A$}mu;+5mU5CA!?A23syVS7#eAo%`gxj#Z9rPFk~ z)UbU<@VQM3c6aX4y?Vc|47-s#`u$_F*H72&Qp5ID$R757o5F6{oYtLt>|tLUcJB9Y zUN`vszA%k6ey-c4hV2W|w=m}%-R}1y?C#tX5Buh@=X0NWNVaaXDcPH6>UODNdk?O^ z!|u*K^|0>*JLkT)mHQ4flKeuqOAXt5aQz*2cka=BdcW@pyOBGtzxR{9TGj1R!}g14 zABH{7S73MN9(&kF!p^z>+{%4Ajg-#T?NY<`?**URB(S@4Pdw}sU?0eRa_&Cr8o%bx z)$LNl_F2K#>uRvOb5A|&GhpZ3=Ucho#3OTcyVS6K9OWMPv%s*sbB|KJ-%o)(mwWEM zix-3zH)Wd!g>>SfDlA7C4 z8c8nG?NY2{V?77@?pPLxL_TPHg+cj+8Joq`T1bc^m z_pm<#JLi3*mHR<7l3uObrH1W`)5Iq1HRu?2ckYRY{RP-_x##Y;IhpK@8+5zWu>FAG z=eRQL?%Y!k`&+Pc?pIm4pGza9x^9;mwjV>eo1atdcE49(cjq4cQSbMUVbAA2aNor} zWUt?*+ogu>y!;XNHD86@oqOzIU+BdAx=qu{{ZSez-=W*3hVA9x*W+riyK_%G?90QR z&wb#&i+__ny-&AG4co(i4myS1oqOtG9|Ak~`>Hn#KEE$QBjrEncBx_eZNb-R8?d`` zkLK(Bz6tEP+;i)+n~}ZvC*3YJY!Cl=nHKEs++z>>_ONsA`&hZ}NFz-TyVS6q*KNYS zkBf$9b6R)qiHCi6*p1w=PJ1ZXTYuJbmm0PY557)Ygx#Hc>S5m>cFui{mHP}Di67SO zQp5HhJl_U(cka>sdcTi{J)ir)I_;%oPaf0lQp5JUX&;7Nuj_-|oqOzIp8`AQe!rD_ zopXO&w@VG%!+&0;47)q`#KV3f>_+bReB6sjYS?~t@Z1yF-MOb8_OoE;+`q7L ze}_gYPwIB5VSD&>+A8es+@lBde!m#@f!vRodckZ!= z{W{n=_pM24Zfo(#v$|bs*iH}72z-7|VRz@Ac-ZfN9l1|Ca?Ci~Z}UU4C(r42sbTvw zw6o05rFZ*1Y!h~O?x~0ULD)I(qpaLV(n$Fw-7Yn3|0B(9XiA^kx@~X4?#?~>liu&o z!k){0?38hvj+I~j6tb6I*6mWm_66xZtob{2+g|uVHm7yx9(&kdhn=lgTe<&|M&j3X zyVS6KHuZbh+>5ZA`#5{4weP3(uzzUSpS0}v(n#Y?-7Yn3|CsvSe4b#pbB|#+KZlpM zrylmN4EvXs{cmi4$HU&PVf)tf2U1JfuhIUu+x9Z-=5>JVhqmvheNgZBWlqZ0taAO{ zKL*#|zj+fq@8V+Y@9s1qFzB=r@*S06Axvftl^?&PjsbTx`!O!ni z*gN#QhkZlX^SK|2-1jDX^)uZrHEjQR@Z9ULyK_%H?AyT3c~7-+FVjfzzq(y&*nWQS z+*8=yxkrE2`+Yaq^SK`}DLcRaob2frx?O5|lY0|(ckZ!=eP7r)_ZzI-FQAdWuXMZA zu>Jbrxwl|<=bm`jN5h`aeG)zwIiL5&f_JFTvyz(L3u-2Z0f{uGT= z7t-xg)0^Cju)A}Q9@6{$IM|Kcah(60?D3+yU21xhdklMre)q7?ft_<7QXhPNUy4Q= zi|KZ$=}qo^u)A|lJnR?1p3i+Uj`PFFo-C=`rKUHzS73MNo_g4?f}L|ez{-7B8YwKT z+oh&AxhJr@bB`X@`~5c9^SMt&zaL5VbXnalHEcgD_`I$LyF2&T!#*E&&i!mF_v2`! zRM72G)3ygczt>@R=bm`jpM*V^`^16waaWPOwt{Y#8n$0Z_OR=94cOheryllKVCUQ) zwsQYHjl?VKcBx@|g)T^i{cKFLd+Z^ZN&6FRr26rH1X-(PEvsmelQan*!|a+!GJ`6124Vq@Y9=ywnMDzJ0z-?ehzfJO@I=ys`Ldx84h%%j`6$FQ3} zhXuT~*XthD`+Z&5^SKYakK2dr#SL}4)UbUI$~|nqmtlA39(&lggq`=;G%NSfG*a1E zw@VG%FACo871-UmCm!~lVK;KeylxJ^=1aO=YI>7<6?S*-sfT?p*g5wbt=uo9k@6P0 zU21xhdkuDX?$KjHKKFt5arg7y*haTY4co&X=Tq3-xyK&%!(r##-?DOlnnvPn zb-UEC{c!5{u+JfH!0ygH@vzT?-N^lzY@PNCve$Re?NY<`gMy#mTd=!xPd)6X!p^xD zZy7wVTbf1+v2K?dw$BNkdo&`O)4Fqy9@qPQF6{Z-2j0JLP4?QZx?O6r+{2#Vi?F+M zk3H;{!_K)MXyv{ej||uCQj_H#c0ON%-JN^lVZRynf!r(o1GyhX_UZ`TE;Vc)M(Z|V zpW)UAyF2&P!+sy^oclRe?#I(e(w_xoe8=W?Goko(nS@7qha zOAXuqL%D}tw@F}k=N^05UxJ-;f5ggt9^3c!u(xa2zBL^n!rpUIh25Qd;$eRW_AK`) z{ryv><9^y#$zJ`jZkHOie@W-}uydO_?C#uC5Bn#ubM6b@I{5tFV*CCc_I3^1#|D2+ zX$reL_o$)w`ywX~UbkuIj{ECY}9_O2|yK|2{>?^{~x$j`*z9Ego zV|BaKuzj=Oxwl|<=bm`jhr&M4@8c&`a3A%)WUm~d+ogu>-=yO_@pD_Z*Q^RZ%;vQ2 z+*1$xX0Y=wJKf5C42@JL>UODN`&Pl<%M@XE=N>(&_xld8XSt6vj`L@by>XOomm0Po zNCyb>cj|WTG3@T#V-NcX*g5x`tlTf6kt%v2%#LHEa)moUg;~&OPz4 zpACDK`&i>RzYWAtsedfL0-9FAYV0Y)9de|?4opV3P%KiH^QaDSuOAXs+ z2cOq9VRz>qJ+1fq4X_)z<2YX-d+mJPE;VewjpjCC-@iwD>hrqT!+sa+ocp;}?kCVl z`6AseHEiE2cEkF&xc*7Ey3QQ-#zTl!Opoq zYUO@AjTC>Y+ogu>9^KH%~ zd+h<;E;VdlBKSG31-m=<)Wbd;cFw(S<^F3LsXwUOrH1XN(WxTvbB%tK&1v1aNB^hy z`+l(Ja_{dSpWS!yC$h(n=ys`L`v$?+X^XJCbB{gjV`1mq-?4IkmPRU%>UODN`>ynw z5Bpi*6725W6A$|&*z>thnVIGO71`6rb-UECeevMA_rdPYJ@v4k06XWt*6#<;>z1XF z#uK_-YS{iJ*~8{uhTWZe^qk)BXTqN4KF&DKe~0Yple%4M*dG2kpTO?UJ@&9)1Uu(G z(#m}}=l-;Amm0Q*Kh9TScjumX*sp;-mwWCwKZ)$+=XAT&us!^7z7D%P_te8a4|dM| zmsaixjZ~l4?NY<`@W=TSc6aX4^LoEO0DC_7f#dwOWN*Hx+ogu>;g9o8*xk9u9`>hU z=iDE&a=(K{S}*B#sbPEg<9rKtckYRY{Z-hr+{YTn`PVu3mvy_;us!^7zOYv|r*-F^ zde}dJopWDw-r)25KRNeTbi35BJ^XRL2)jG?=movszkofLd+s>@E!rE&>$+WP*dG2k zAH(j>J@&9K^|NfvigVw|%6(%RslTDyrH1X{kMn)7yK_%G?5o0_&;3xmkK2#;##_2w zYSyK_%H?4w}k+~2iw|3A+C1Kln)Y!82aZ^G`*J$gy+_ldCQa?hRLquXhn z_Mf_4YSJ_~lveQlDO+j2D0_(-=)4co(?-wUw2b5A_%r^BAlec=4Q zE!m6z*6mWm_VDNT66_uN-NSw!?40*ctlWP)mzv(>UWVPBd+cGq6?V>ju9f?Vocn)tyVUe1_X_Op+!GJ`eTF@??ALMb zpX+w1Vf#;MjoRG0b$=aySH4d;^>966xZbf`&(TQoh3=9Xc3l2ro_g*yhH zo4z1d=_}nOHSAg^xGVN>y>7U+w_F?2NIAMweU75kuq=sGBlZ!t7pWC|aN<3Uc4A)Y3ntM8mJ|kD( zf_i^R4Z9k_U8#p_W5czTS zk*0@BYS?uixy++aw~vQWQ}3^S!?nO&=5G{5ACN0qSU+w^4ZHpo+!cGcrWmdbEZ533 zk}TrkYS(0W5iPfMJFmpUb%NpA$8zmJBgI8^m(;K;{CPR`aLqAXvn!!_jY!N>V!Xr$!fk{Wh}pGQTn>HYPf;rfB)+LA^p z9xkcrQGa>3o;F;QEY~O+sd~7ihF#(3QHh7^6~lF*#b~;>~2xk%UExhOUndT~AxO{t8QCBX`~qOxMJr_nv!vePihQ%+mEHEU6f}1k*Kfn2MpR+nn&Z zP47o?^IV6wCW5sTjKUHFP~@>G}&SiJtEM z5)5@UfVp#ZrDNzi#L%_c()9`~O`ExO35L2}gs5#pvscI8cgV!hb+n=D7mw!V!=Iq5 zwwGI%V5sXC=&v4~s>^%dJ-$vdbRA&n+69)zt=+l=LtXPQzBcSsU8xwlCK$RVSh|jb zCE44pOEA>czw^ge3|-R&nE?b(W#)K1kzA-3c6RF$40U~Lio$Oltt%5l*PjhtCtJFXq^@7Z(B)&O zYhI`8@;-EruLlfW=Ucj_!jg%hOEA>c`OgESV(5Cp(Di3a*LAS8#Ly*}uF;i_q3cCM z*K$kOW3Xgn=n@QdO+p-+*{8$DR}5YMF?4wuvqhfwF?5ymb&oH>P*)e+|61)HUmqH} zcC&PC150ZRU4o&mF1Y^{L)Vvvt`bYvLDaR2yT1fOT^DzHK1|2Z^^>9Ncb2Y7Skk+? zbqR*Ly5Rm-3|*W2K71Z^tEKBoSd#tRx&%XAU2y;FBlq~)#?ZCQ()9o>{oT3*LtR~P z|0{;BUm3c-vUI%%OCp9Y!BAHh-2aN9YcE6B4v**N`Hf&Hi=j&})YS#&hcR>=Xy`i9 z(zPEfjWKiyhPt}o{P4f-@pYu3tJczWDl9EAbP1-5##anozcF-OXX&~Gmev@$1Vde2 zaQ`cYu2MtSKP_Ec`SWrrhOP??T`5b~9<=P?)+HF~>il^*9Yfa@hOR10*GaG> zV(1bKb#;E;$i&cfgQ4pxOV`=3l*G^_80zZ$yy2~JkFProU5{G2?t-N`hAzQSSLd%c zQZaP>-O%-+rR!B#vN3cChPpa`y^)Tg>oG%D@e{fE@PE*i7~swuf}yU?zh9Y&q3bzA z*HBAWKUxO5bqR*LI{$v9_lbLay>93lZ|OP)mUPmsOEA>c`S&YRF?79W=(^O>H4B!K z!ERlGp{~xqUzv`f>oY^wVoTS}u+$E5>k3R;9;se~e1Vde$ zcK-dZPu=5d!#{-2Z8mr^Hy?fuU5R0CU4o&m!JV!v6+_pShOWIVUE9M_cCcHQV5sZl zPS=%=p=(F2OTBNsx~_bx{x~9UICN!FZe4<*t^qg~HE->8`1yPcU3+L?4Px`rFNmRP!Og(WlG ztxGV}^$9!PC>`Bj=@`0>HFUjW>3R{C<`HgPf}yU?zYm*`Yl*P~`n6A;4ilM8{&^6A|btEjcF?0!rx;peb`J4U6&fV{%YyE8J6@B?(roU>gxRau-@nH@pY}CYlWrj zDe5{hhAtmNU1u3Np1*W-o=?Tlb*rIky{B{Y;U`o&(ydD{)YbXtz3CXb?lpAnVd>fy zmgX3`1Vde&f8Lvkq3a)pt}&LbLtsh&+TCA*p{~w9@AbZLkFRG8U1wXmrohq^LziHv ztMl)}ref%N#n5$!rRz#qvN3cChPpccTr?d+*V~4!7cE_nz*2maI}QayU7dd}nu($7 zV?)iqjD=@_~;H*}q8=_;q?X!rOM40Uz>yqt-l>z9VEn=M_J!O|QvK!j+psjn&?Ok^>ioQsj-l%i zL)UgobMxW)u(ZU`B^c`J{JfEgq3dWv*AbSky-#H@vUhiqRaDu%8JhOYURt_xskilIv|)YbX-Vbd{mO*3>oZt1!gmh`diI1~(Z zb^d+WOblIT8M^*!>3Wrxs~;?_C%bhChPpccK5ROMuA2>Am6opGz|wfCTbE#{tMl)}W@702v!Uy9 zOV=z|noe`;5)5^1)amyty>Hy(>j6X81D3AaVQDUP>kbqR*L_V09EsTjJxGIX78=^6`5%S5*>!BAHhe1>)mT}5-lXFFG0y3Tim1P zsTjI;F?9Xnx!ipCJ#-aMcE_P$sH^kO;?gm6?QQ5fz|z$pmP`y?f}yU?Ka0!6&~=cZ zYl5X~G%Sr(?*0-Cb#=iR$an7X^=m`dTuayQ*k3Vp35L45;0z>&t`iJh_gT7{XgS^8 zUxJ~o&ObX%$Iw-7=z7c2wG5U-3|)euuFgL@&BV|()zG!!vfO<51$33f&?Ok^>ilO{ zy#Kk!*DOO<($cj9EUhtg35L2h!1~biPDkx!xa06Y!!3rciws>SS-M8hQXOM_`55ZD zi}Xh6XkFIooDH)hNU@%F2PV&=g-TT7`kpWblq*~nh#6aRCj*~hPpa`UiQ9s zkFUE7U9VWW9)%@YgxPFpNgUDK10{{mahN8QW8U#V5qC}pIu4E(Dk^XYnSKE zOy+sTur$WdB^c`J{B=|&hOXxgU85~s!(hq8&?Ok^>il(-_k(+Uy1u|hC5A4+P}eH#zj)@`Ryum0l8T}0a6{LpmadhsWTv~vmtd$13AU4UrDNzi z&d{~Zi@Eu5Jy=R+xOEAJx}HO4b@FFu$Ix|}p(|zS8VF0`EVnMfP*>+a3xUkM66wB+W)b?mQ;-MR!rT?37=#a}vne8teU=(_N__b5x(Ua+KM=n@QdnK`~Q zbfpXEBHv`Rx%uvg{qL3TX5Gan!t;I)O!2=3g8)Oh1(xI=!&%XrU-QFDJ-vWAMoVJW*hT=QwLqzx4_U`ZGr zyONf_hOfF87Vj_0GO)g~p&tEF=0_bP%I_ZIM@Np7=fN(~LaxUQ9`(ywV7QLP5(XIa z8Y~zaxN=s3Ydr+8%x}9+(sig}BZGrVN-uTus18Jd^8A zplwG!1`MCc60Tyrvdi1RRKr||>nC7jq>ziBLQJ$-wqGv(Da17lm0;U#!Db!zIupS53manQTL9Ran zZI>i492>%AeshaLj|OG|ekr7@8W_nx=P+&5^6yiD&7|F)u;s~)z zJuvKxLj83$Fw20+$EBWZEIzJ#unS-W*yV4iN9F>y=eG#dO)XFhFt@=f?dfg(orceV zS%H7^wTGC^URSdWxgMs;D*FP%zZBAbGBB%vDa3UyFfxCU>n}jtv3e^oPin5{Jhl{= zRtMK7z{t!}FA4a^V+*BD@A zjYO{K+|mFH`@Im?jlhg>aQzb)S$&bK9%#GoKLDm!b4BNkP5y%uAqQ6y7`@KSvyM6z z7`>v#8a}E_2F9BotQeyq-fUp9dfnTVt4fuz8+FDW5+%Z$t5wkR2SJB<-olIS0H#0w zQfQ<+4$L@U3T1$m+8gBJ9?f>!7r+eCT+z|H(aLV#WCvFQn6d*O@%LZr*)+Z{_64R< zVSLNcup|u2Z(;F<1@(CUKYFl5_u$ih8*_h5*GlQt0r)dooKr3ZW|+gPw*$kGSEvUc z14cYXuBl+zAcx8G-UNo@y--g09+z8k;z9837@YuQr0W-?MH5!4xB!=$2b+#p<6<)=IIFzI zHv2Kp_Asm2?fDKE8F9oM56nhZJzKql(*sAF_XcKZfi|D(ID<7Y@> zrUAJb{x{3|?{)JQX|CvTu_G|W4z8iZ_*s-(lR#qYItiG?4z4qS>Eqz~BQTP~71ze5 zDExLmFdWN;VtxfM{T*E20VA^mxkjR9JLb1vh26S?>rh|@Ik+l;k$Hz)W5KnFrRySK zmN~fY04C+&dIlJo(a5zLHTJQ%Rs+MFAU=$a`HkPls>#7M02rAo$;EZg<`&n{z^u?* z(J?;-n6VD7OM#JDm|Q9F*n5z_0JBPSMaO&#Fcl82FM*Nyom@$9q0*eP)d!M)3i)sd zFtrY@Q-P6{1Gydt%P(@6JZ~m2tqxuDfSK*!`YSMc9hGNS`%hqM)r!%U?YHeKU{VXh z>z^JU!t!o-g|-DOC5ELBEKPbHRaH~v9}i~q8gfE)WqHkvTCY`Gx_TXzL<>bb`yyI= z6)>C&3ibP~z~HL|3+C`Qfe{~)i}@QDk9iuJSRv0n@B44atFfC->cZi1&VYEbj+Qa&h>o!(b_S zFN`?`mc&!xoG>1iV#9JCESa6cyRDmGX?-bt)nZtZM$M1Gk}@pM!ICg6uftNdN4Vxs zVae_uwru!cSpFI2+69)R(ZZu)X>L`Rn#!3okf!Q9gR26V)_23&&tT1l^8n6R!kjfaZ$!^KHPac5poajErS+-32Gx zr{wj7Y@9b7L1 zBXcFWPL1Sh1?D!*745^#TXD|j;2H>w%);cl4?g7kIn8n?FkFik8eb;>bD@K)3K*H+ z$rYUsF9L?^%tCSaCtw;KT#o@GD+h9ogCN^SD}i}fb4AC-cfc%gaP|HifcJwHQJ(c` zKVbBl&DU=Fn7<7LMz8epV2%bxuMhn*Si7Ea!06R!QS|&Z6&Sr{%hTp_fzd0yJeaG1 z(d)yA_5Ao56HDu=epi_|G+61`Db*Kn3+gF;QLP52R!%LgudJ?adO=wTS_Dk9VR;ai zdDX#T%n7X7u$04+Ff3DemFhuO>@~pBq%G7%&nL7lV$KJq zV1q=;qC+nNl-tW{sCI z>Uo#-814BKmJ%Zp*1_T#nDxGdK&pmjJi5_K50bMrmSbF+PP50 zKw91iTMmb%#IT$OOOs)#ho!}^%!MW62|JP(%I&=Bi?9!yVeyK>n18{NGBB^f(roMy z*RY=N!!2BYEi%BGaLt>;l35JFJm&4NJxa;~i zV45A6*MKR0CS3F9uw;#WWsk4m4P!67BP_LsWe_Y)uZ8P59+nnEdo?WSAP%K3eh*8^ zxW~E>mNKKB3@rxc4c22|zJ{elokRM)y!qF-N?W>mFT5MrC5Ll9}xqw_p+C;Ea0kh1(brvv-9bA_IBeP6?T?>HWp1RPQWDzhK2iL>E z$oxevfFsI_z$|xgy$8%P2iG^i$jnHtt-xeYyc>RldlQ<=ULUb}y@_#f?FNj@x#Z${ z)#e%kOxD3Q5*XZ?DI6QX$ZSroDUn>0f#ErT^jEa5S-^0KSSSwvKrTP4lWSxo*Y&K& z!S!cgzAwO~&ScUj1)0{rrwO{8@-XU=RSMhlApUCKi);aAooK(0lRK5PYMuI7sN;fCKK|2VjI07mu~|DsTO{5RU19O|^LWL1!1~Bs-TyubtJrTJML@lT^r_2Xtq2`L7ckW_)99$0p zBfBkf?GF|^M?DWrv*wD9!*_^raD4@g?BmE)5}A9~{~yjt99&xy~_}xgZ~1q=)7?~0P7rFPXi;nb#kG?h_V8ho~TE3*}8ej$G~(4fPc-W>qlVZ93Vf} zWyg? za&UbGjGW|Q9;zdMx4VVfC*IL%2xkg0Pf)mc4us(Ef?F~$=gR2A>IWeQI{*hc$ zff?)Ix)hk%4z9a^k+V2*?HkGU3@}`07V_Z-z|3)Qt&a>Qr+nl}fy<7KzQB}euIRBm z0+@LYt_on}w2)jQBe^aFrrN=EJ1|WSuBU;KQ%7>`8Oil7Fb$e3dVKu^%pwO@AKbH$ z^GtGWgBpJcKC>JMOj>hA-zzy4m?aLbvw)FvQF3vQV&}u_fSIqk@FJot0p>{u*XzK@ zi7UB&g<9;`_!^i6nk(9eTd&vMYjJQ521d?u^K*>>hHF|>h4w^q)d928!F3fda!Sm4 zUPoVau+aLors?l+N(dDou5 z9snlg;CdaH3mshF03&y@$OUjj*#-yHBOF{qfN6AaoeYe=gNe_hiYliAqwgK(nZITM zqwiej$*UItqwi&7{*5Y^1EcT5`fDxwJo6S{^!?mCn7^|g^`t=_%u}pqt-7Z$63wx> zUI(T)6WryryWE$shL}ggcS5^w1kW4qb=?k@5(ATj#d|z_)e*Ej7PgebQf6Szgr!!s z$7jD3mS%lbSKs%%6YSz2#wzb^**Wu{z>L(f8a>Co1--qPlySZ(y-Wwwy zYA$Wu9e}CVT+#h?ATY}uTw}@QM`nIqvw%r!u4r910JFlu^$0LB zQpj~OblGJEFx*$-KVZ?W8+9*S{+;yfRWKn zuIT$97XhTv{3xRz8H*7-`9dR8n z2?tjO7>NX57p}6$&Prf-o`C<*o@lObff?Z7+In*pW31;O)MnQ;1ek|4SM=C96__Co zu5*Bq=q1;#Y&rfn%bmbH>EL<^m=O-H{{f@NV1$3_>ZjLK;GL3b^<<;%V!vVA;s8IX z-*HLP09aa{3y;b}V5v2p4I2YX##ob7!IChZ4Z8@Ik|)FUEP$m^f3incj&AB|2D^BJ zy>lomcJDk2%rf0O(X-z3)aB@%mB5Hs$;A^qyL<)A3e9ClC9l~07g$|5xOM|Z`iopA z;woF$VZf}^T+zD50W;abbtW(p3FP9FA$Gg31coO|_z#%qS?@2v)ED4V**JBITABAp zZFYGU^++6&iz`oC`zm18>GnjAZf^_3MuGN_xeqWB;p9rdVsjk~3{Rg#do))$FmoMT z7Xl+=hg_LRu3LcVp}Fjt3Kw~g0W;sh^(HVfD#^7c@`T-|-vHA`bJ?>HxwhC6vz~)% zPhg4<44$>llaUSrCV8EDa+ozA4NF;F*m4RiCB`QL)x(m|pB3Ddxkbflt&Y_T*=VcG zK?_AY{oEISw|6c#0W(PZIXZss1E$&G=Vic%56N{IJZ+D|EHFF`D>P2O0_I@{*T%Rl zE4@Rm&!Efxbb=j$8Kt?R^Ur?3EOl@l4UF_VxthRb`)CRE^10EtE=kjy%xRdmft-utu5r*Xe;a{^t%A~ z`3ZRJzP9<%@YvZJnCvoTspVxT#qWjJ^E&~PT%j=4<#qM7)9Sot&BeDom)6Xfnl`Q) zfU8OjuA#JOuF9H zZQ*YxvCaCO6tqlcJ;t->=fl#ZYbNGOV)VPPyE1Q(eKFhP_d8?kVp!Ir*(gr~GuaVi zZveB#5o2qBk=P&?cgJ=D{s|bKxE7kfw%i)?X#p;k54}^>-2EOz)f<}lOFz^jk;(SV zhJ|CyEQ5imceLjSV7em>aP;NdNu3Cc#5^%a0!f8tnFP#i%@v)aW&u;|;JOqT89U^9 z10?pHtOdZ#(Ol7a;~rr8IJh#v$cQ5s`_zt~SAdzTx$JyNFMJ40e+Sq9$mNe^a$Sb2 zY#;W*4di(au7SV|a&V0VMsfnVcIt+A2CuC1;^$F z4}ZBF7@igu8W(o}Gs?mBC@_+d$Tb2r+x_(xFwG9GpMV+b;7Z^TCdq8%;?vG{oc$V@ zB@V7SU@9D3Hv*%xal~$vKD-kco%!=%76a4rZZH$&!Tb{#J?rJU6Y&BtdcMe0&zr=k zxgZbbQ*t>lKLFFL+YCqL6#x4j`qsA1uzA|N$+n@nsi+Lexlc|_o|gb7oshXQ->15=dwEPj4jByTdA1q0uo>yT>8&`b}OR;JXtMRtj4&GQ3 zWPab$2bQc+^Fg#2m?L3nG-|GfrPyfmMX=NwTsOheY+UsWEG5QOAHmXMT(!wB5v%`S z&KT*A?ZGZR$Wb}k_fYPSBY@!>)^T!m_-h*#lXl|&hNw5fLX1% z?6%Mu-vYD5!PRF6l_ki*j zS{z&(@2Ij?ejn}!%=elr+K1)9taNZ)28`rGa@qH&>8?e)`6Wb7=0)bGo}5FnSFTfl)ie*3;AuF}mLmKs{vzPDSX{!-1*&d-(L= zShlbwY&n_rycV`hgr!w~E(GgofF=EDc-?XVEG28hSN#!|rfYD46gTK$r|;v!r~cMdA~vi_*eLT$~Lg149mW-v>KKZh%r86VJa+XzJHW>2INl-3pA1IC341V6u1F{{Uu`=CXaL@`m@@AP)WS;eE?$ z^K#Tv=4j6+z{u!kd)~$ojlC9Me;4esb$g=kdh7s9wS#MaU}WTyYXI77$IlpGYBg81 zpQi)U;NWTmMsfnV7J|#p^?zeMn#=Yx9r`LT7dp7s0VCOlTwK@L`-{Y`sK>$eYhW53 zT+@M(JVvhP;Xo{^a!MoX(Ol7Y#O?)VfrIM>U?fA5>q3aKKZ|<}Ft=&0=rOoSKb#sl zxON9daxb|)g(9v7%yJ|!i#1ntY*Z5C;JScZe#RzObidyM4Da|9T5Dy1$vC*)21d_l zMF~?-@Z0CW=sBfmmq<*H{^)l#SNfmJXT!D!M$g@OzI|*jVD#Kwl&~v-<#1s1Y+m%M zNK7d(dVbH-<}-oOb9a&bS#hlRGS;K!cYmK^)7=J)o`s82HUO6Ufhl=BSf$u$#lL1L zFpcW2t2d*rbmsJ``pVQ1>NBtE>MH%?`PyO1!poN9s$}quMcw>*van>X53h(mg{A4F z@Kx*YhW5N3#%u#i>#xI@oroD8w(JW_W@y-Q1TFW=nnc(q!qW2hu;o%%^ogS1!kb`8 zE)HXsTA2T^9s~0uEX{|7*|*spE!;;`NKP9FOX34H?{EyZIa_7D6M!k!DhzYzQY@fnXte(^JwfEcuEi^FwU@0>!BVlO{d?@u) z!qOOcLo9P(DK;#3!%}NlUS>UpSqfSUgr*3}P|CWHM5SW?DS<+K>j4W0!{ z!dRWohsC=oT=PA!lo*z0VQINDjQI~N#fD`qERA=BFxX0G zG+y;?aBA)MMXhDI0G5)T;j3;oFc_8oN2axo2uI7`fN9z+YUa}DTK$UHQc~WylueAmMv%(z^ZX?1X235?9tRZN}z{q-xTsK8>tp#R?=8E16 zZ@LdK4z68+k(C~~js=&!k2?gI63rDoE=~q!goCS&T>kopT*Ki!I}Wb{hIhBchxWLj z$1`k?gX=?JWOYieR3z6H`ywZ3F1&~+2Lm(C!F4(?Nq_Z4t^*>ut_P;U!Sx(4lO0^& z1Jk0pqJ6l_Ak52}E82(00#oncngxuk!>MaQgm>^oxxmbIa4lhb99%1akrh6$-vBaa9s$D>^R7E8o2Bn zbq6pDHCJ?wdKQ@599(OFk-ZGLri07QQ5y`F`-6pY)K0)OJGh1cBfBJW@%<@wISrVl zT32*`oeRvv4z62(k^NVGuBE{6{$Qd0YGr#IT)p>)E}f&IKZA5IFe@~d-JkTt3BW9O zaMc4Ndq(Pt=9&)-??sBPXs$quZ^pPQen z1{mJ=EYx4u0JF})^(Zj1gC-a6wb^sZJHWJRu4o^wKNR;*ajeL{=3CqB227*Qz0q99 z1H*f)h5BnYFvSk8JBV>`y#UNQ2iG^i^l@+{4p8R_`F%JVnC~52X9LsU!LGwR|1zmP|6PN*-D|&77BQUiNt{o48fBaJ{>f+PRb~y}~A(|`NhZBLB?cn+Y zFmgUduA@L?hsPbj@Lr_&Fk06Wz|3)QWr2~CxBRhDbg<0|*)k+*juX|4dW~GB`7BF&_ORi-gv3+y{FtasR z^!R!dnAHxhcYu*IVRG@aXW4qQdRCa5T3io$P|!0=veq5ir6n4S))^T=7&+A^*K^>p`|D<4Ryw#I z1SaX=dWBs6{Q`0=+0^qUS-RE$v(~}2!Enqw4z2_+a;{FU9V2xO0j4L`>Jl5#ad;ds z?14gYcsek0VoxqUac}$Z0$_MHScvOJV8%GO9sow}1(546NQV5LU9-FhOdrjK3M0yD zV9Fd^MI*58_3tu}>owG3`)CJX`fD!x@1!0EOtpjS6kz231-bS?jzSRRlm=ju4z6o~ zX>f4e4~*OyAs4^x0F~yH=Yiolr1V$xSbiUv3msfP0Hg0N`Jdfq$41Y?q5X4pW}ZSz z>^W|GVDufRJoO9&M&JJ`imvBiVDufaqFQj-XQ#)qo>tYKBrtZH$Fn`^PG6q(%mBu` zr+K+$xzn;_EXx~~COuZ&|Dt8HBM?7dgzw^Q2a9J|`oU5* zCVbU_uw+jRTSoJ$QDMt(VJWE(-=RAlmR7?u6P9A*`GnuYlGWdv%og4TOG-awLCfQ? zGz|%Jy$DOvu)GONMn8$ct3HJ#dtbOc-@{U-zxR!pEsunXF=5PZuoNF3wj2#h>tSKb zZ(&K@5VlN%C3`}+g=h1slCWhyEG5P>9(TZ!SrhJyzrs>$e7EwGu%z}9E{VW5X&Dr@ zw8D}!EZs&z*WO{w*03b@3tM)BrFE#Xln>l{@8nQ?&ajGSy2l#^Os&Syax5$*qrvUiw*OBXJ5ZQBl8kl*SD|%0KEijn^TcP>ZeWOJFjZE4sh78HKZ42iJkX$XrRT=y7o@Fub2qC^jm9>4Dt| zRp;A#&H_eeVPa|`bzKHbi-YS=!1Qu(Jphc%@8sGYL5NLwPI&>C6`CtLw|oFh!ol?; zFtTzW*Ir1NyX7$9{kg};{S@(GU+eEQ^aEyqgKHQtvL+!HbEe(*Cj-O#4#I^1h$u6G z8RFpjBQUbsA=hBkV#oYnf#H3JLNWgWFe4mX9|I%nC~~ci%o|&dMqg;I=>8f8Oo@Z5 z5*S&bk*gQp5W)SYSu6^j>B@FykCte*;F=e&pH}6*2D3@+>gC7a&~RJJ{tN zU?w}bz6C~BmE`&XmDqFlrpL-Tb|GCm15@wd+8-EMuaavD#uqNgDPw`**>WMS-vN_$ za4i5vR>I^u6fAZ=YzBtsy~1UW2{!F1VCFiw{tb+*sLAy#bRj|HlrMofLW@!qSpx%fw|4Wbuqd8)iSyG9%p-Az8RPmnk!n@gTOR9 zxLyH9_7~)0kJx!*4KQmo7iSH-Y;YXrQwLW97}>dy>o5?J&n!cMY1LfOKKu|yhBtpjG1gKLZ5U>uO+l23yF7_W;x1!SyUKvZK$>^&T)|9b7*GGswZU?HF}dK(2ie z81|g8A28!IS9Ba64@}CzH4PX!g&@~ZBwjn_uLP!Eb4BNk#lVbmaJ>$UoNtheyDa;= zpgsm>j^>Ki<(&XOJGiz2Mov!1bxNcU2LaRM;2Hx=g@dae7&((6SMw#I~;CdXG zS_ju^V*Jw{a&bm_a|qd-GG_x;5rHzeWq8G;AK`B2aG;vi+Eo@FPH+1 zKBvv|*(~R<g4?Um2u-wzXR{iK`&u6sf``a-e zcs_|$igz^ehmI*KS41XN*k{al;#`|%CGrbuqp6yXf*G+}eTBS6PH~4+^=>@sokgLeftd1=~ zsC1Y&)Tq=d>~|uoQQ4?HX3xUPW5Wt~jLp9mN;84de53Mq#>S1g-jJ*4jk{2fx#sUM zZv?TiP%E|PN~Ls+L+SnOccmht-&O7v40YXOp*mU@pU9Ay&)oN^ z(XDg|hPvjX9#dLJ>uS-u?0G=-SA#>>o6yy?Yj9`HY%ba_<$GYt6h^NlGQKycRN>nG z?I@+Jafh+0h2-K1r(K2vvr>D5xyvq9z+C9?#udPb()?Tx0K?t7L{v0a7MMl{*G4B} zS28BJ%NgNAD%b{?lA7?H(4Apvst#L{u$0XXTMmV#R(=w4HfF-qE z*z!Ist#60fKZ7N)br`e$Daf>j_5>_V{dL_RH}4=T2B!{qOrr1ljv(*7KCQPtD8Tg{AD@%Azt!SBTBIp} z1ln2sd|=iV;8Lrdq+TZ!W7~hJRnfJmXR)I_i-3`F%JzH<6;?Ig6Tt8zu_d=eYyS^0 z83)&wz(@ul*HPfI6U_SK@RXo~t2Z#q99(+2r!bv$#p7%5S8YX(ZKK&E8nV#@Je8Mpc(W^zPrh@fsxsP zm|1}GomytO0vMhw30L%~+O5F!a&SEWjLbXa+Rob1ll5P~G-$5q@%0uk+?5v6^#w38 zqmgR{nr^Qw*Z(cn8=A}hJKM7@FasQ1djcbKCAs*lKtEn;l!Jg-;NTh!%n%1xDKIh% zlj|rvs%rbF7MR7FE4shV2WEtWYaTE%zmw|)#GxG>%j0{y>LbQ@JnFQ4zA71)C!GU2^{V2 zZ0Q;Z3{NVAD|&p524=2#ye{6bv+0A{{}>s?@ERY|V-kv{wm z81Ax#%RbenBepEZ-DC&X0AOUjO0GqSdGln6^&AS!IL(C$Bg#pv$H6rf7+K|#>pawA z&tF#o!(DbEA1(prVF%Y+Y>&TwCfBJTLYm4g<7KZ`$cMiIW~qbg2w-GoPOeR{QXHAf zMF7yi<(oqJrgGQA7kb<8JLsF{z>?%3Rn_`Wg0EIJzX8)XMtTJfl+rD zg;`|*Fx)d1in>RESyv$H)c!Q}`@kDTr<=F20@f_*k*H&Py2I(evfA@GFx*!bYEQRH zJY|7p8Y&1zE|zUMWh-DLo{9MglaBpP+P#3`zEZfN*FQ%AQ|#cX1V%;yxpoHE(K)U0 zyt9GHYOd(feGM>u99;JTqenqe5m3c6HCzl?lc`zS>OXrQEGPIdJXO?e)(fKEju1zPRJt_m_ z;o`f-be70d58pMW^G2R}wg;Ea8+q#40~noc^3*d77@ckM)H50woqzK5dl@jr`vqr} zZ3*3Q;_0l%I8i(kmR2K+o)1fjaWZ)|EZ$Bsr$|iR4NKE5Vavm?H2)(!%PfZ_^-$RI zDJ;p};j6q!Xmj_lWeZqRy+nm@?FdU^(=cX#UbSu5attg@#bHY+ui9Q&x-vhjoY{P} z%9-hIQQyIL237d|#oSVX9<%Rso(Ietom-HoBg$34^mpWzTY-^2CD*iwT0HL|V0gA8 zIWu}+@G>xi99;heMxupW4}c5ubIOL3k>??&5Z5liq#Rtsfsr^Q*Q1eKrvlT{!Br2; zCu=hUZ9y=AC~5GuFZN5il}#$TbOE=$M?cQ5E`Kb4B;p?!Z(y zxQ+%!MkTpk0*jq{ClI5#Y~5_yY+z~~Tz>>c#yh!=fiA>KPWcNk!!%d)-2F5#vmIP- z10$J)TyKEOj>9j2;n|M#7hXh^4Nk|Cat^NTfRP+Uu2~?m&t!%GQ>MA1&l64pW}buV zOkgDYk*f#}w3lR80n^~%x)+!x2iG!U{Jcu8IavSL?Op{;ql4=QU=}&Jww|IgHn~2E zjE#Z7EYw`lad;#!OB`Hf!01^o&px+~?NM`O9?ZqS$bB^2eM5_*$~C|gH>u|?h`60K z8QLSR7A_d@Krm) zk~S;@VaXVl19;V4;j50|RfgqwSiHN#m~pU_7?vtnivJwOoC!;030O)V3|n4@CHc>=a_S~t&5A()nhkBm*$z>fjE`q0+ zcuFJl#e8eTtC;t;PI3a{W2B<-wz884IY7O31KXB;2Lk10Qd*;@^x(}|(sH=R-Kv=S?)Ofc~ zgi1?E?s>^o%JaPJXk4YA)YZ@JNPE~9F9Ktp3EO>PaB?qh*WNASduElcl0wfm z2mPMa?U__pS~sJ%c3QYa_=YKXUfPp?-l+j5@osc`Bpc#hHZVyC<}PC15BK}Su#_nk zz9XK8C51;Exr33qv&38T@sC?L}eQ5mI|3&#wvllh6`;DSvV}Xv1 zgz#J2totJWIBnK_5iw4OA3vt=*ij>fC|&;eG6&*7!3<9p!UWIdrd4DX zjkLA<^^7=0`!H%O3+7Pm`Mj7>r;x$#o&1r23w6$|=m0T=7Nb7GUrvzvRUP zxn*k|s}rhf@Lfa=m2J_gVx!fM7ILXt+y4DIvC*nyqwRY2O8RTKudA?sh9Amn3S)kK zO2Umf6jOKpdIJCKqWv?qs%Fy6(#e(8wUyKBw37y7G>L!m=iVcL@jg^J)Ap*pt8JfG z^UsXS^@wBKm_=p3<$A<%ROV#Az#B(sZ`9UR&ZwBS=k&_zX%nK$J7e*U!$ zF`Lz5J}rPzJt!(TE-po-eR-)aKc@$^im03!XUG6TnbBnBQ~xl25&-<7~@s9(PCikfhGB=sz>#*u+ytE z;o|nMQWA=*sL5P5pe@R)#qgM{U=wVjQIuEtOeh+H_Aug@2iuBTrL^9lBHUbY6RB1y z)3oO?UDQvWUJ>#-aZkY;iB|DOROTn9`du&)%XRqQQaAJp`FQV!Ra`?HrJ*=Y=er_v2r#;>~ zYB$k#y?SN0#|n8Jhu7%#)K((zhuz~>Hw!Hk|0E*)L(tWX7T<@Mh5f7UfThK-+y_hI z%W#bSi&q(z4`E5J4P$W z>H>(TF?#nW7RJ0e!>|!5<~zz83$-`G(Jpe8H&$wIM9g}@*m+QUV`BM~%8R?eRU6 z=g##t0R{)WXwMB+duX^Nz;NY_&t%3=GcTy9dsh3ox@!ES2^02d3pyP?8Lgc)o24VQ zvrpNR(x?B%FtKBZeafDcKHbmkte|Q1p_(PS6(wM`VeEJIw)Fd*7C`yu{Q~~M<=#E0 zNBo0)Xw`!8g^gZ4aBV&;!EZTz(ZLyMQH(LTy3iO5R>Ix_wYIVQf!f($J@8T0(qF?- zqj_h981~n%;TP$zh6oRN-V$I~u+T-UX8F=8>{EKK(70fq?hMyTpYr=bY&wn$js_VQ zjFOzb2=Y(S4eDgc9v5uf6R4;7oBY{W^}ArG>o}XMgZrH)IkKj;`%C5CwK4j=SoeDm zO0^36{pfw&{r)&y>+1I`YIpT}8W>l<_k(0tzjN+&_51b(`n|NYqUy~0s(ou?^t)i# z@3XBS?5Lcn*3XM|zf+xARKI&TH)d4idq)rZ^ztKBpMJD;?k=0Pax4!;CDNx`nFA-F zG!R%xUpRA&w~qbq4awh zUYX5Sd46cYexEw60{z~)&OP1*!#49fCC$>&{r+T(e(xEh-)H_-_50`O_g&3K<2UyE zX!zOH?{@$r{a%VRWcrzvvfs1#*VXUrZRz(iys``X{V*)*rQZ+9+wVQl1Jdu4QHj|e z)$b=1=yx*z2V9Ncx%*u(>~}t)WR{NZcb*?go~I|xqQ-mg82vtZhU)i+^N#lkm;$8V zzq53and5zZG(-CRO*YFa?Dt|^?dtayTp~O zzaAss-dnQYQ!)BI35@i6qZKVD^3K5^gBb_aLy#8&)+ zyWa)Fem@rxX}YMR`<iJztqiQ*c7YYB;sS{nciV`C7A zBsLl_E7(oqewn*u*)NY|)mCBNNPt1|#vJ_Jq*L=nvyPw2GwLUXcgr5)$G3Tn8~p=k zjETtoU}#zf{rkD|E5xXI{i;c@O_ev>Z&6 zRTwP`b+qK4WnR?LGKsw&PBw@Z-{v)LQYcy`)%($+Fm2J|TNo`LcY3t+($Qk(6}m;` zmXR@{<*s{FwA_Jy+ST$Zqh%5XvP8@2cGutv=9cS+t7u8*jh2=e(Nc^dAkordwS@*o z%Zs>sBDtk3Z?xu%cnY8sw1Msx8d`;3q?z{A1xZAqeU!?mY$Z1 zj?OK8V?@iC7}0X<-`&yj5?tzvmhFyG(K0)4w6H^5xg{GTTJ}n)XgSUDGrHZ+Eu}G{ zr7T9YY_>q1P)(gtZLMU)*0_28Xi+Crf?;g*!o%}9k=el~RJ@DlTFI2fSjq4?G^7y5 zGk?;xM&W73S9lAIoJ@|z9_Do8@BD??=0Hq35pFLY0BQ}o7sMz=$dIbq0r!Y2nx+1Z0nJFs3awa(5O=4^ut79Yo znzlv9#z=7Cf>2RApouy*>L%9iS=lh5vbMfzT8(~C?>lg1_j1REU>F;hg9XH)($TR| zA0sv{ED#&&X`d!NH*rMUh4aq&&#Cy?9ini+l2aHzPrxkkvozjzc*jJ7)z zFy@wwBYqegdmN%-<2zhsSH+yr84sU3-sKbsvDg7Sx zbPbga1g0gx2+J^7S`EuluoUkd#1Aj>PKG66SSG=eG%T}VNg0+)U@0*ycfwL;SRRF? z*08LErOB{-2}`qK*%+UMoiQv4SX%ZCw|Re95`)5)BZx69Ww5jwmKnTizwlL;!IIJz zwPq7PbL{j(Zehl6D;+&{X6vytuZ<*lrSfW{9y_b>m!TGp<6_Z^YFr#x=Xt-kFdP?` zZllJR;P52>#PMv{=0K?;k7u<|qZW=88o^R~j158$7e3pk`8HuMPIK9Y{@)<^p zVR;#r#Qx!k`VbcVT$5kV=dcVhuKEF%)*JqrxwbEoWIJijLacD zR90UNBYp`L6`9ZI$gHTYuB@q_KFf^Ft?>z|iJ?IxM6_7NhG5tij7GEkoY*K)aTvuF zJaIQf$A&#>RYtl^$A;e{MuU|0SHs$K-sLxKXw2togR1EFBlPNhNf4_fjXrE{VJhe}Rl9CwO1w-w- zce?fwTDv)pL9EYUm&VY}ulMbYHimy% zw13S0WaE{8c5d@eUGCeWC%`fp*s_E3`-d3TmrdoaF61hDY!y7#{xxmE8AQFuM=LF1 zV~nC!AUsEsOdE06HCTbH(OzXlnKPgA*uI9xaw3WzLr9ezTG(TZy7cf|kI7Z^*zKL? zv0%=fqrH(Zyv1MC80?PKyX4*oZv>uC-l(1_P1^MY&t47>dF%}1T^yb_p$-;aIU>Ku z)S5&v^v}g;7Vj^%l@1$&fvz&GYit`y@JdD0LhZx+5!FZgF#r7Z8`D2VNcsLjxHOJ* z`$sVJ&r`u_vaRVI=AR&bp48eSa&Iu2`WMn3_&KBfJff|!%FjXkRBHd!)laXVR#7v( zZK5kJ6Achos$?dxv*q2P2+2 z2o`;n_Muql!`pCGv=4PX{&!b}MB$}+4^$iq1`JC`6f-plb%I6TBZ z6TR$l?r|X)`ez3G6TKtrsJxMg;h%Xi{L`ZSGcuIrYO`L!%2o8( z@$lFN1nSb!9!o3sqEgMFUMP=^)EYL8*(S%Z5lp+Of|ywpkgJ*HME zg7G6tHC6xHVg3nrnq^wMxmqNl+C{d+(0-`aKC`^8uF^<2rGcrofc8?k%4;4Q_(w;J zTt#p2eTdAzZKcD!5sa^_j+Sg2N$^TVONI7WUmFud%S!FBh<#;{pO4iZtFEi8oHBS& zC|UxG*Lbo!S_DJ?aJ7j66)GL(A9XgUwdaqPwOV`rbFI^~cKHObx|-VQRWj#2Qy7-9d7QG*;q9XF4q3ZpA&|~@Xz1F{xL=c?g35n zZ_#^=r@C{3VCWw-tdr-0jMi@UgYTbU4KOl>_D90nt4lEjR!*-euO9dtR)lgd@?mof z?Si59q+A&K*js|Fn;wzI$NO4f|=+g#;KK_SgO4;ZBZ*>sfW7m4k?nC z9i}T-+whqR$#r-PGN-7O@EF~vT>F{NhN=1eZS5bNS{s=TpA09DU3iU3skvnFStkTt zSo@B;pE6-@X^!4y>$S1eL;tKoO|EmBgj5sy8SAV&$O$bvC-e{1ATL!;SgC!OKPNP3 zALd^lex`kh6V4nT!s3&rf9uW(f}wvB@K5yKJgxi;L~i*x{_$>6IWv)4jn0{?WBBL7 z82<5YR%bgn#meyy$sgnTxm5fU^^_^D^4pjyQ)5t#IJt@*`v!vnANdq2YQ+7YJr<0( zwb~mTO=eLeu2FjfFLKWcg2+s0&!^2w@S7Ty#oA*zDGL}_{Og)3-4P`i`X~P^{D1aO zpsPvi%0CPD#%@cpR{jyUQ2Q|dh}$9TpPX43{_#&rnWHhYuu_t*3@ zk3E|0YYs4SFa8r;m71b*0{{L4EVYKE=b5OvI*i#GmgWMV?aX?Tz%>0S$dEL62f$M7 zxauTeG6gUyYl%{N{-^{R=hv@(beQLZs2iZ8Zj7SP|EjE&(NQ-Hf8)E#+lqRJQAUsM zG-jTGZ2-JdS?jpAUY;>EBG1o&e@ZUN-^)^s>&2!T1uPeHO+Br7YwzZgF}*>z6jp+{D00!LB>wqs@4EyArH$-wMOE-Emy|w zv90?Y={)TpIYX=E7Y3KN-RL49v9x{jk@%4Dv-wW=+C`&Z?XiQv&MC3h zkU?(YeLabd)|^_96M}tZFC7~hV9foV$}LSg4tc-(RHH7HTQ1e{gI&o!ZF^3FeG6+} z6nF!*7LxcAYEUkuR4J^g?=4LIanUOFX zvtIO!|9_6&AQI;5NHDVz+pDrxR!0IcjE1(NGSbW1W0NZCr)y>e< z_kT^Uz{zq|+scqNdEPK6ZBj}tRp1If&s;Fnehsebq)ZZwrWQS#kS=nH8coIcllaGM z3*pK?{H8qDXxhBZKa~wN<>7}leC9D6DKF)Z7Udto&_CB<6CHgYwxcpF*M6cs|411X zL;Jp3d*ndz%Aq~GT(n2+9q6Dbz_j#}=#$ff23}=YE`p``)u0~VtJlKfy{5+3#Oall z)m3%%Y2&KffYBcFuet}8w0gg=Z+VFIysqk@>1kMM4a;&^5-Y-(w_qtTEFZy=enVku z_mlf^Wd_$eU_5+~9aW0b^=85HA9WSkH>YJ~*s?7wDZ|nimgYCZn1Qfl-U?fWz>m?4)sEfudzDD7UEBQ zPi$LJdl2n0|IDH7?|h|Z{KIt|)f@eX*Dp-u#C_c)PqOf z@IHn2!}UA^jP{0}Q=~oAH3S2SpW4t?R6PGYKbtE`)~5X29kD7oGu1{Cyi$H1rv03M zby}tUJQH6yHErs6V||KbM5Q0(_j7QSmkBU3Q>?;O-iOL#Dh{O{`sX1;P|p1RGvcsB z^-h5}9HIRKa86PFsn-7K3xt_E)L1V6lUi@goKTnZ^kZQ0yw!oysP+Ww4Z%?RPC2bX zpLVeJYOS54%q&WKqt?zCll-rcs=t!HF8Kzlf_=vE_QyZiOJq`fN?Qj7f@i@l*;?EFl4L)U)uE%uDXUT?9d+r>V>VsEtAmssqlTkLb%#opgypJTB% zTkK^Pdt3i@le{US_e+vDgP%>`U6k&d*gdwU4#f(-wPQi#^jW z_MR4diN)SvvG=jqm$r+&hs8e9Vz0H>ds*x)?PBk4v8OEd$rgK0i+x4A*uTfIq1o?A zi+!xc{v94346X`RR@rv3ud~?uTkItkd#lC1x?Sx2&O1|k!eSq3v43E(x3-JD)ne~$ zv8OEdl@|NDcCoLq*o!UpAr||~7Q6Qm_h>(NFT-z{G(F$LVozG^OD*;u?PAYb?Ca1N zqdkKX7W@4cdvUwi`7O5w*M6-QdvA+L;!(yLju_xNa-eR$@u-H9| z{SOv<|8}u2v)EfK_I22@!^pk4?7Ii2E%s!)*q2)DOD*pkF?mw zwu`;lVxMoZXDs%EE%vf@u`jaN8!h%F7W-g}eR8|l7h3FdEcRxLeW1l&+b;IoEcUd; zzR+UtYq2-9i@nKWZ?M>#EcWdz_H?`07g+4I7W;gQeG7|yPP^FWTkMl9_C||+V~f49 zUF`EL_A-loj>XQm;{e8aCsZx?%`#Xi|-qUti|5LVn5MhU)L`7 z5{rF>#f}g#BVq6;i{1Ngd-m_6EcO`N_ne$$7^p0wDD z+r>V@V$WFY{KgNHy|2aIyIt%li+zd3p0(KfSnP>*u@AG@n=SSg7W)Tu-F?d_9YhkDvLeUF800_d)i{> z_uiT@|D?q}vR&*6i@m{O$Ky6R>~k#k^DXwV?P4#s*vDGzX^XwO zjXiko>kR$84c;ZuP*q=AUp~INvhAUyPw`|?ncu=hSuBip&I0+dM0OqekP|c{(yt# zP*Kk#ovZy*j_0*XtEP=Foj9YW?diDvp|nLQE$}>&V5pt%hBtvqd&@iOnLzp`2czEK z)ZhI~V58P<`k3;R_KemZ@jOxx8-LQ;CzemCxgnB zGKuJl&a^YfSC`jJsq<0`)idNXe^)tuT4kM=(3Sw=)oM!s@yfJ?)F*>0`)O`|Zu9D= z=sB~M9X3wYyS;Rd8esWC<)~#kM@76pC3vq#*`4a0QwhX^`3yNLo&u%b+CXVUv=DOv zJ%5+-DlOOWD#LOYEE&UxkHC`E78RMo#avg4{yvC$07478^edr_0-P%qST%TH=Q z=YOxqD(z=`E?|8xL221W595ArA~J^)^A0dA8wVH~yl-GhY$6s6dz7AMVVzLmU1P)y z2Byh@IRThN0gUPkX*2uc6-@BIW%asrSYHJ3yi)r)e>}HpKchLh>y4mK6DsP8Qo60- z7d6nH8W?yrBA%6Y!BG2o;miHk9j(0wbRkKC3sXr>QDeCm-n57@1&keIRs3j}Gw|Nq z7`g<*dXCItYJ09*&sI_X`5Eh|-da~g<`3RSpD3scZwP~~#9r?H5)5?>?{r;>7`g@& z&{bD8sb+jt{Ta0}bO}cFyD6=sSCK!OWXeKur{l8RNK6>e;Z5NtLHfH`0a^ao!V`l(ROk0s>9kG z%(-K=pE;+PMUD5#1^mn_-hr-63|)d@UtDJr;kS;~RiSm|kDq#nuCJl1>;U(;5Dax) zft_K_8A$Lxsg9aY>$R@@<2~)rwb5+6fAAo;F2PXOt)1RqbG5Gg{WaI2YbWSxI@qmC zFw}Kmr|aVRn5^sauYcw{bPa~CYz$q3p|0yYUDs_|SN{IG&7o^Fbfph*_m^O(>wr$z zwOH%Q-(SrRT@#=yQ$QC*TntQ0D$uTtd-{9Z9S}&Mw}i5 zC!GJ#XH8Qpr%!J?^;S)9g3_iD`FokT`+?CX(*A`{!qTd)@=Eb>YLijBcX+PHq-J_- z9A@~<6siAj`#cuW@4;NTT6?Uo!NXtFT)A9(jF_CcAXq0fWz~603T?(QQK+ah^XIi! ztE_Z%a}L!5zVhkay#uEd`R^d_ zR@8t`ZNOBRQ>Frw!O=Z?saw&&h*o>vCBX1m8h?jdlmOC(odwKk*fQYQ6ZOou0Lq8o zXdh0joK#tFeQ()+5M$!Q!t1d%Kl77R&C+3h4q~h);>R^#tkW^(d&y{!ij9Pd4SQv! z&)#*vtEXA^_tg2Svg|iRoysc9pfWg(V?>|E5AJTgU#5S%*jHGm->X4na1AQ9*l)6) z?n}0dJ!7#ivDmYSOrt%6$6M?}+Qr_-Vz0GM{^wgK|94m?|6ARrPX4FPz^$WD){rpy z05PBPTbPK<8$^8#Oml#dUEW4#V+C@g%Du$w1WU=U!xC7~^9 ze2EX4e?G%-HS>y4u3o$mPB9SjY$XBmF(Yhr?#`dl3w^^>PpmK)#U z$P2E5(qy1CYEB{MHegB=hKB#g+uJ~SdS-Qjf5Ny#WuX;3n-#_8!`a4_*pto-%{e1> z(rG3mousMhgv_8+cUM)?HL0#Ds;ZMt3q$iIK@l4q-QcLSIx+!~(;%{0P_}VdjSA9; z$Bi6in_-afxvdTo1Yv*oxgXEH&%IBN)bZG7Cg**B_w)I9pXc89x%K`R-wnjFo5j}V z%G&bQxp!|Ll0BvI+yKvkM|`jTD3I5GlHVfmPVo~!4hs(>9|rQG=~-VriSH9F7S{|R z)xQCrYeDLN{xZBF4?Ld+@|3M(v0&*Xa8-K#{oB;B2u>J&)zaNmNft>jw zFLfEnv1N~ZJ&@}G`5T0s@jTao+z7}&0&*)LKL%uR)=PZ|$l-weCm?46@-bh5(Fw>O z0P=&O6@LWC)xh&MAlCwNnviqe`n!R=67;+W$gRNhjX(~pc&Tp%vMmTdJAWU@&A{^` zK+ddssarr6YaaP9=?Tb3e)!gW0XYzm-}6i{mgpEpI-$R?+Bv8vVg@0WzQ{aX+Pi8aj$r! zpWli+j{6yb>+nzedGRS4lYBZjhFn-;l9#Q2cAneVT6ty+SpPKjkF<0all&#{+^y|u zzWj9{2lu#tc#XPFdIIu~f!qqnPmt6_FZGK+js@gbfZP;>dzkh(>#=72xBY2o4m=+Z zv&^7TM&2jnFnSH8mA`a#kYkbgx|U&%bY*3n90BS;P|eg-_JzRK(Q zFF+1{jhFh^uZ3nocxC$(Ag8|8OT8J$l|SQ=lR&QhS&w`Xkb{5DYkmgE_SbvlYk-`( z>ZSe~kTZtpT;(yPx%xgFGt_H>wY2TRt-1D}JXh(BS^TGK!uf+bSARV+;7-?sJ)5g{ zk1@Y$O1Azc%|Jp9vkZMT-9UG~Hs{GjH->ho=zhf*Q=S*z*o-0k#s?jCH)cf)Fb zJNIw;+d0{DKjv>~Op>cZwI;di(VApuOKOs@Xe+8!Le4#{T@{b4*w)gDM{1JM8QiWr z)FgMGwWiehENy@NTjp)o(fRM#uKN$_cvZ8P+y3U)b(H5kpLJg6Mo}4?+VxwSb-(@z z!;E_K!|BcB_FV(dTTb^klQLUg(An}^vi^Fqek@r(pR9jQvVL`6)<2xAA5GTJB#yv~ z`m4!09gv0{?fyf_`isf>&3#$_m&y9;sNjp%4<_q>CRu-VU)FCX>$j8jdy@4pN!D-e z%lZ!`>#rs22a@&eWc{^$S$`#2zm=@toveRRvVMDC)_*Wre>GXB7b;;UyycH4>#y(2 z`i*4$X0rY|VxwsNXtKWe28yVEt5N0OPu5>a)^8{4hm!TX_htR%Wc^06{#vqrFj+sa zFYDi(tiPPB-%8f+O4je$m-Xw(`t@Y})nxsb@R5F*39`c;+?VxlPu5>b)^8^3Kc1`~ z+L!g0lJ#rJ`YXx$jb#1szO27LS${EEzmcq8Pu7p_%lfrs{c5uQa+Nl4SkiWPLkX|0TRAi@VGV`?7v1SwEJnpHJ3*JXycG zFY9~B`q5$j8jZ%Nkg-k0^G$@-0C{k3HMy~+B4 zeObRhS${cMzm=?CPS)?)m-WNR`t@Y})nt7&SwFZh>wh>|e<@kNnXI2q)(`E=`k`d~ zTC)C1vi{a&{qVl5e|ob1VzPcCS^wl@{ph}|A57M-ChIRJ>u*TbkL}C)?@QKSNY<|> z>%a6n#&!PTeObRJS-+C3zm%;1c(Q(KU)Db{S-+I5UrW}1Fj;?cU)B#K>)Xlti^=-+ zWc|#(tbc5>em+^hnykN=te@YP^}CbxGs*f3$@-s8*0=X%{SC?blgav(WPLMPzqBvw zi)8&&vVJL9|Dt65%D$}sdavJ*dVq(M_3dQ+k0B^AGnJpW z8Kubmhfp3Ikhgq)`diNZS$`o}e;9^>t^2o8su_^C{KNr6r0uWltL+=f`hjHqXtI7a zS--h2>qnFImvlZ`&)?LiK#{lHm8`$IFYAYr^%s)$>&g1R=oM44Zk)DfXXW{)>GAnY ze7F{W@TPyA@WWKm`i0+*)AoZ{qulhDOI=%TX)7w8|3(#(Wb)vNh4@2jCbo&;sU)7C zgwLy=qBX9$HlBEHgXc>=P3y7oVhVMnJbwbn%kut^k@o;OCiD5O#q#dj9<5RQq|h2g|GpkP zhot8j`I|tl{~Xul-nH1<+Sqz-ZD(;xe%+6Gz6U%HBaDMN(epz<^w%z!=f{EEy2W%x z{sWLp<_}q4{8{{MSFrv`Ku!hCZwB(BtVpcqK_E{Co_7H`_?r4miZ1}Ufxmp9F+tl` zws+Py_ny*kp0l1W1J9|S^HNuV9R7Ka{7oQN0`k2;Xx8+x_*X!>EwcX0K(5Kt#I}AD z$l-tIHNWxeVEv~(@<)Lj2s~$iEPlrGd@&Gx^TwLL7RVWE`^wo3{MiI%c>6U69p!7_ zd05`pvD9}0x$?z+bp8<#jY*j2RUp@c^`8fF`)Adk<>gBo%dmAAEye)JO!#eo4nBvr ze;N=Phu&jv0&*pc=^q1f%QS;|@r6L146|heh`w=U55E-1OY(f(wb-hYAH_0)4a>w9bX z3x^=}%Vg{4wa3W2yT2ZYwRCUm;`TP4uZP3)^-17)J@n!K3gl?$jiW#`v*T8r2BL8t zBhLc4ZF7UHe=U&nn7&XYx3AU~SIR$zj(|-trzty0<`eQ)!eZpOf3u_lvwx7qE z*jhn6%TMj@o!xuO{rcM$?9VSkYCFus{|rQbbCY>K=Fejuh93L9Ky+_no<9QQT9}y+ z0(to-xlPP-j(DWTjFBxM@j3l-Kn@3g{xaza{rmwS`kSPz=evPi554-2f#{cJndj$# z9J5y73j*!2c{Pm1fvZ5mSp0q<`ft7c6;j?oJ_9_5z{IQZvrq9_cg)6u z$`!RF=SrVkW7TW#-5Un$3pZ^w+TSwJrYWK@PUJIjq6Uf1^ z`uzkDtw3fyzXF7RBSUA)UEc^>AM`W)4*)qB`tUH2>j8Ny5dKXi)$_R|^#Q*kod&Y7 zeemh6y)As#dzV)AzQ2Dlc&>)FUjd?3F?TKAv9@>O*|p8Rqk-o|@LaL=nR??}NKe@D z|1Oa2;PdwbIrt0S!yg6mg7x7A+2a;rM*SRkt_SPC3FPok`yTt)zkr!wYdH3=_2siP z#(u4PBk=_5pAF>2Fn>+}Ira@+^AkW0*pq^}y19Z_>r9wY7r?Wy=Yo3UOMvLtr?F<9 ze|~!lGn{{kNyqEGq&ciM9{}>YwSx5gA3*f4T6q5a7?2mj9J>XCfBQo;J5hMdl|?ryrJs-{B=O|ck#IG-vosI^Ao}i|dHyfr z3ATO|$bm5De-X$lp~vp}OYkSO^!EViw$^vgZfst>u(+o^O*$5z1D<1{?T-W54m0YU z=m97rxCi7)u>RFRZU(9M0(mm`X2kS?G&_BE|6g{5u1dKD0t3_aml2mw>zZS@)VC%g=w!=(#3CQ6f^?g8&g?9ZA zNrid%vq1Qls)oZDSHyR&kBaVf+J-#}9K zW&p|--woty=%1TF4uaB0=Yv2V4*mQ~Kwc02{AVDyZEld}-~K*mwy}7}#@ZUKNq2`Q z<@bT-M%eZ4143QVTY3!0LF;GI{5bK*`33jtSsRn(L&3vu1#;_# z_89T}10Y9(^;du#3)VjfL@VX)THwXfg{{@K1^;U5K^dK21<%7_Mt$;Mfm9gNdx6{& zdgB-nJu$p%At^ORM}IqpJbVXuu7wEgDIhn(y73&4mxIq=3FP2k_bt6jNa(Q-0J&;o zft_)04_Ph$DyX*W|0bTWX8vm+6qEGb;okvyDOmqiAo|x{^6dOov?BD+8-d&mGwKMC z?Xdbi3gl4eu{DyiwQhNr--5gxdh9*mITbX29gr*5hbtRfyK88{;joTF1ac|#*y69@`3lxQ9?0!5 z%AX447$Pg`QN+*moi$lA$u9Tvo4|AH+x+hE0Fc9B+@A!p2%4V(@=|EUdw^UDWAR=f z2dodt;s=1d7<%KofGjTimE`+@Xk|5f_+voy9X=x;1QMg%{{ZBA=%3#Natb#4n)&hH zJg#hS0&+F1^A7?!Y`YBk`~^VtZ~xi)I*@CD=Q5C2!(9Ca;t6B=cYwTRbF5`RcqQ~? z*bBZ7JXikH_qM;hV_UBPxfS~P|0N`h#eW3yf@vn7e*?%XLF#v3gJwfoe2C2M5O{n4 zdYhxdu4r-!nk`N-FxFG zcy5GI{yZR`2p)8`JUdSTxov9;;KdanFNO8zy@Z6(xd!AwK)wSAP3Yb~{|Lwn;pzTy zAXm<7EASINxLzz?4D;ugz;oW(MfBeQa@}^Tr=HrlxC^-_L$7}9-$4JE&xlg6VJ#N7 zg62N}o|l3@_X0U&<3+aK2IOe4z6>PB61za+8;`Fb9(x9t_cnHEnL_ut{o*fz=TzwD zzYFBpN9jyBy|McMy+G8zR_59J&q#Avk$wWmcF?ovD^AwATO96dfuO-vy$+w;4dI4;~{_6fV>_&d=|*3g97E!imw53 zFi5>fdTfrJJ-4+(S=$TN8}xo2ucH>PhdKYZA$2(T{7--!4c7k+kgK78evxe5r!x~~ z@G(>92_twA$Sv!iU7iToiF_3Inc&$DQlAIps?AJN{4OB3gY^qQE}75E_|E<27EWqH z-124Mc`=Op*8w>b^jrh-ig`%3z5~e3!1Dt@t{|qTvn!rI{~8GW>rd0a2XZhxalh+Z zFzbTmPX@9Gal)H`9Q|zH^Nx_@8CHTp5-3`aw;IVfb`QY(((TR(XTgf|NL6x@pI#Md;oL9W+qAf zejuc)_v#-8axCnp#|a7j^CXa$!<>INkZaiE$ue7i50Eo~=PF5s`TTc)916(y0l5*R zehA1Fn`7kjPXRe&d#=0`0pjQLhr#ot^)pG`^%C`%&XyLFAQF5SNFUQr0MD^7>;4ds z>;KO8&)Y;#ANR9Bu7y^736Mj<`qu(Eg9+5vjrRdL5Pbd?;`vs!wR3j8WdX0)+qJ`&_C}4av(_U0*Nun*8zDrJUbr%@=BNq-$zo& z345=;0%SWx4*wF!ivjt0Am@XJzXIe;KtB50Fjs@r0U+nYm>vXjJGAQvknNw<9(!tM zZH@ZzsEzXS#r7FRsZTe}vGY6dFwC)k3Z84> zN%%x zXvI1`DF>|;vgs{e4SGHkQdfh|4+A+BG=Cuw`q$qlyqkE;XL#6NZog#KiTgd^xfPzK zZvgUAu>L+EuUP*`3WDD7bK~!U=R>!&=SlMq1KAFYzv_5)V}a-0TR#GxgF*8#AO~!Yk>)3W+zij@3Xs=KGx6*Ii816?0eRh` z<&CYU-*gy!cZWWFA9${Yx%v{21Hsn!0g3Czj{>&-ga(vIP}k3!1GF2B_0Jr|9VWa0_2LdlxXh(@}eJiM536hAr}2h z;JIZ_CDGpxWIK5Hy~GoGE%h`7?k#X`0`PyL(sH&Ru+Z`7ENEr}4woa*JPg-O}r`=g#e{J*#&c>ziwO{nQTq zqP&RUklpAuBmZttuuuPnD5`Yg&#*Y}q9&Ys&?TeLUMZ-4adr}5@#duMB98Ltb^ zuAE<6UGVoUKmFdFwWqfCcJ5tX-aNav{_GkhTRVFfw|SxbNKBNO!NK;ULQd7{^P4S+ zB!8Bv-0R#~th$M8;_h_-^APXcd+-FQ(A`;iwodf#%b8@ z*5=|P3UaOW+3oG+z2~>l()OwFw?FUzj6S`x0yR(LM=aKMmU*NYTwNRB!ELQx7@eew z22=rFT*gu7In-N;*yYQY7b}g1m%SIxUUE0l57U5u_W?LK#QTdy~FF5IWr@aLR5w7!cT6#}lUHM`{h z(`y%=UFP31S?ulf>!JU4cb_-f^5fb~I*|kQv9aV|T`}F$hbEaZ}+)rU#8q1zz z+1u{y(uL%#w(x0;mcZnjUQ-+T^{!pR5rxSoy(XXZde>jWxZ&Gf6uv4GiTpNv z8~E-PetL~2#qwfz-7b5RY?RRsyGA?Q^{!pR`Dau+HN%*{v9=+%c&YX@)-4p7>^#+Jd@Hn#vllO3=rq0++TPCI&U&Zut)n@6MB7~!8utMH zAgfPFy0N*s>K?FF_kgXs2W-_nQ~fzwb`yk&2DOw&2BTIiq(?d z^X!%xwc=+KZfr(j#QU1P;-=J!n^G&7QY)gDt}nXlmF3-w=iL28fA8kg%5J!Ei}Z?{ zUF1QZT`S$s^_4!mc2|n&g=oSS$GjW|>dA3x2I>=cq&~91FGlJ*jZ0gn&%3qxd|%3O zX)HVzD{fNbddE5z*VeIany#Ght7>ypI~&&B<$ZSDXYvZHci0|+6*rS{Z8Ler&176V zyzd|@{EYP(zM}I^XE?P_XYY!e;gIaOo8jQG8BW(W!>O^R2#wWs9k^psPqdxtj^6vn zpt*KLb*^9b4+U=Qp;*1_9*WEEp}6cGip%byplcnwhP#KL(fqx84ler@_p)DcFT00= zJm?R_5KDHh65-(zQ)(YOD#ksoh$u^V~eqCaXJo@27Ti&8GIHwH<`&ctL}uWBJj?AGfPV z_3ETyClxzwe5W5b%=k_-->&IvSB;OZn6F(aCi;MhKDshK)<=sb`^Q%#+pZcPUn$1= z2xEQi%J@VddC=N{F~(Jsr7PxZSBi-~V4{z%jF0tE_|N+Iie%eWb{vq4wJNBZb-TYhG3XA^PjZoA>MWqEVl!&>6@#TVCC zo>^X9e|CL!O%wCwHT~ zjusX5zTF7-Cgu*&S%oIU&D-#{o{3#`dL>@xne%@p7oi3ymmIb%`25{`r<0t63jkdDaVw%MMy}YA}(r_ zim6;9+TBTF^($GpC2C*0NV4BC&8=iav|CWe)oTE>r}Zhajx=E4;NhfB7mhv(3XD2h zAI236UUm)SrMvADRefmBiRWk*0zh6mpig3TYSh7xh!>$5;g_P#c)N#wcS{2egS(|R zxLbL6dmCvriX5#CUZl-P2XGq#FzArSyj!83Zi!lZI`zshm=w(T$OvOJj&fyuUEh-N zEg9dE@hzFYLRjapt4vkNMhFvrAXZ*RB*3|A2{qbY*>pn#AN$uZ z=7Z1TU%P62bj5btm15!_F!7JBj8FUnCjPZ6l@0|#0WB>R{^|5~qV}0?`ixkUJCi! zt$2%E+EaJq?JC{ceuOo_-5n2iPlUUN7WBHtHUkLyTfCEvFB8J;K!sw@jQ0a!zw~!a z(tC?^Sosri`yEO4JJ8%+q><9j z$vVvhE45pev|Cndw*!?G8x@+zxL^SE+0iZ79yJ37j{YFK9XBZLkF|2x(=9-M$PE~* z$RpJ!Tz~RKq%Qyl3_AL9pd93f4@g>1cN?uQ`)%v#emhWGPj@QyG_BlXs&6X>kawP= z^>hFR4q4K>(!TSEQd!^~N9$>)RF?bB!K;?%82ykvpo_>>;DNzY*%%xL`4MBRa7*i( z3wUUKbGNj^YzV?@-|fb%b6S z2Db$>K58su)JnNBK57?Z)F8bw%=l<_GL@XxE5nSBc34oc>xzHv$}r|5%=pAVVB#NL z8K3wEO#EwCs*k#ut%-l2ihu1&`KTM2kNu5Bd1E9GPV8peF^Ui@oUjgPL_Zo5)U`~xQb(UtLuf561QcBQi7A7N%! z`~yZ2XnQZ;A}GBgjAA|ZkFN}Cb{p38(G~m0SIWo!HO%rqVjJvV!;FvpBaHoP zS7w*Tm*Y+vbB#ddiuuqso_{UcZ1b6~nq5%EzjmdV_y$B6CEjku+l%pbH{Pz&?T&7g=o@!;Jls7I?jBmusfz8e5cIbv7wwG5 zsr51DK!svYeS}nbkKA38^t2Fx(vggsY)b8pb>64M=IxH%vR1nVHAbM}mK7T_Y3{Kj zDeiZqx8IT4eivz^w9{CpnP8=M%aV4>YVCHQvSOn`^B92+K%1L=TzP4she;zRd*U?e z;RmI2@OtA!`eUskqmKTN>n3T>x&rnn8!&j<7Xabt>wp5Ijzli!_08SV`sQwFeRH=L<1MXkj*9iohn(~*IVz2z zyQL9!w*!?%*imVO-7SxB0BD3g(0U~R0|$?=vL! z^9VZ;9$^oRI%tIHy!FEJN$Lr^>?kA@?Yz`tL8+~J*?Fmbj4pM(xa_F$F7c@u`LNXW z;?j6&B@$(#cene?myNewGA~~mDtZYOz3sB|cD?E^7}Vc(X}sz$p66c%B~h2_;9RCezy);Bk8OKqpk z7jz%k+#K$4gxDly3hfQ_JKbB53z_sr$P`L5MPR-tO-bZAikvFGHyNmc(Do z&GyuQfiD|xyJWq5X{h*1sPu2U?7ZSHq2e!Jng;Q=q3kbRiobkmyy9;|jaT~@XnPvj z_4YK{rD|wTqoCd2CEDB+?RvYv+P`F?`-@A{+x^x4CEo5Y_b)$>)crbpY|=Yd7F+4)N=K=PTNto)>g6V%J&`s1ZI_}e z{c@*U!`Bj&fvP)2*$#MV1%w8gFM5fdmP>5BcG>#hc#)(xv5pe2pja833EiKyGwfcx zv3v2^?!`sD*KV`>L0+40^g&)bLh0HYc0btHE>gOVpxqDlwa<+X`@_x>@1=*8U%T1v zrC0Ty28X)V?gzSdz0#@w+mj^mk365Y6Jak7ba_^dPCHY3)|`B}KOX7!tZBRjy3W`0 z^yNtZI0%oM^osPEtB8yv&2ZMEGr=J;77j^z{PV+lbVhV3of8g8dURfN9-SEuN&e{U za6B?UI^rHbY3WIsBb`TQi9=)_bVO&0LlTe9md=CuLT`Ss3UJ~omz0oNBx09_(oQKT z?L2x37wpnd+Ia-!6twB(*9&rKytMNOufDdS{j=+BFA$n%ZKq`3wo~e*@wP}r(C%-G zL=^43w6hD^{cSs?qMcV>=C(k?{B1j>@OFROP6>3k_b*>IYweQt@};5TFQL-E?XvTV zzl4gvd}$h_e;dkeqf6;uzBFF(x1q+X{R>q4w_TbK+P{Q$f3<%b+IhRb=+rjG#31vb zU3OmSUqZXT+P@9$ylp;ktU>cou1@O}wT3aQYwh)Ii$wGaFSaHA0H0g|YwM@({PC7v z1;t1t-m^vvG|0Z^N0cD`1ob^KVg3D{8pV#Ofce}bk;p+dWCh0NtCv`<^b!lHULq2) zOFmnmogI;gqKHKF5-X`)b`+6_q5Tr;o}yT8?XrtuIW-i#8h&7A=p}lhM0B?KZm~kJLbobGPd-3P!d-on*;1dkH_rB@Aw|w@S zj>54$`Xod9e#Y*CzTQATzULtNoNd$f)E3g)^Z0z(2Hv(7+S||n7~XZ70@ceMzRNoB zWxTDO=a*Xpq_yoUMuO8vHrCH>tY5}QJfNSJziy|(2|{B#z+%rSBX zeE0mtJ#_76YkA{rpBd4wShSChsQuwD&l~sd+74bmFQ0w(>^lC)Uw*k`8GjPB$G<>$ zuY7St?%J2jtV8e_%+}G;AMnso2V)+YXB zZf9#7(hf7kd}Bm-!OkRM{C>cGfoO+b)IR=#+gRA@C|Xc&e~h^4!^-O?*|M z+iKsAl6mSGF-+&^BgUO-r__s-+vIeQm(HkY40yK!-CLBF+tPl95Z zxTI@v@uc1F`TX^L{^reZ8gG}+J@uxy^u=doOCG;ry|UHm)Y6G}9DnTe>9NC%;n5Qh zKXCHIBUAeE$CggqH>E!Kz|!#(Cm(zCfhos39(eSjcRslE_J`hfV#@R2<0nr(^w_&j zEKNC1z5V2ghnC*{#2r{3e&8KnZ~{T#tS8=a`osf|EIoGejt)@y8xJbz+Hl`Uv6+Q}}FveDTUgMbWmo-~f}pAtN7n;j_=P ztIwX@Tv=PysmUmIO{n4r?cVj>owN5IcB}iF=qNONjb`YpT|AV}Z7*-*yUuhz<&4Um zF3MvISDheUw>d$%n+dKsK}4EPQ0``emz|(@Tdwhe18Rd~l4~Y-vvSP@uU4*^(0Xon z`B5DOxj#MJKia?8V;t6m)`?Ds+?x)gj}oW5*4Cd+huoVExnEMhf_7zX4mL5T~tQWUb5w}q&KE*+*RkDb>Ia+ zspDju4}+grZpd%*Q|{;e!{_lBmBEJAV9-2KoijgKNA{C-G(WN0h5nR#^V8@v8+;m* z{lvWDH_(_@AIVSFffs{ATUiI*uRprL;v4*wd-K!iGe42>m*cMQ#L)uNd1oEjPu9`= zL_)N;e%~_QA?p>^5ytS^L9Z}&#-~??fln~B8(kp!^vW>s2}b>6e0pUVz3vbX*cW_9 z?(zNrfkZ&x$rv~}a-1AFpkvliXy+~-COWbih7`LXrUl-0j(9)hp-y6tKBD^cbU+sB zaaLq4MLRx{8g$Ua8&Jd>wEiQinR-L}gEY!|RRQZ&0eZhHFml|X-yt&Tcf=B9ze9pM zj3?cl``y&1mYN!C=^grA)#QFxHK5>`gRW&KW%47XB0kSK;mjy~U2 zWImI?G3j^2PG!GCLi=6S&u5saPc1byyed$KePl0lzpENh#G5cutQzSV=8%CI@%%Kqj7~=Va1D{@D7d_Ms_Z(3P>w zM}CcbyeGR*b2Vt)J#EBO5QDW4xd#r*ggmi2}CC46CiDOUIw=9lsn{!!1_ z{8GNczc9brhvt``S+@7!0Pxj(58wl+@jlY|TlJoUkdbFl(!LJwW!iV`1AuR>hI{%( zYyjHF&Ap@eLTq4Y-@Ern0(R*Wu%3fHiy!XkOR^EbXO#ocz8o76gj&xoZ@MmRz@7te zj{hv)+4N3tz)1(tpY!^*weU?!h`Lxq&#mp94U!1x);C-444muyLHGgPDtYlaYWjHm zz`MG>v$o<}(mW7!_nGH6&OWnt35P?R)(XD8wuAHX3uiZHf}MdxTSRKrQqF@wI6WcY zA?QAP3H%_lCm>F)Z8*YAVzALA1{*XG7dI~s9od`$K6X3f8x#JG3ID~tiT=Hb{t5p^ z&A&DAA9$&MYvMofnt$Ry4xDTLjoSaM%6|+@+5e1Z{e)NkGhXvo{x|)F|4mQfKjWqT zvj4$f_CMhh|I7YwdTM{l{%`sx{JH;IaoRe5l{u~>3~!V$tXA9@+yS;PNI$c@;#XRS zkm&0)+-TC!9&{%_meuoGB4iEYr9`v{GN{0o0bM5Knv6Xy0H_VInQ#-WJ zUs%KM(a`Umw;OXFOKAIX3$MNXz(oLt{g{4a!qfTpF-BzM8I<7XDI!PvEe)@v{h&qw z+PJ!nj(%DrFpN7i{hCH#7OiIPxy2H z*PA1)D%8#6Q{UjUIWl+J9PMXou*CVz%j16Y^0?o;JnlEI{)0P%e!toI#nj2#;Ud+Yj-0U_G%A68Ek4gFRlT{c2AFRsu5aWbGGy0tfwqNdU&Z zZDmY9@tdJB{am3RFbO)+=0?BV6FAylCd>K#m+o(W@2B64U%vm+n*?wpMu#+E`(t3I z?}rSmjKJ0iTpWSj5mfBHYV|mj^Tr#!$N|$nB5+Zv@GC_1h=(E z!qQCQ_=MntfuPC<1CcPZvE*%Ff?imT!4%3C(~9`JD~oV-sE{*;fao^cB^e4>BCpSC>KlecWcOZ|Dv7XFF<*d&Md zA*z22IaJStKl{&n^O&LXUyG+Lo8h!&3p{S{v}#c}Ha@Nl*W6im<4)lK+KCxh&Kt&a zzZ0H9CDBv$d(%_&BjXeO6aL)q&Hr-VKz|PP*w1p_5dXyga^5uk#k^^HYX9?lsJ0Rx zL65e67#DdWv{A1JO=8C_t+ec!L`7&4>obXh!23pFoZtUegqc??QFz5RD&wu?of75;H>Xs~}N%)l?P6b6>gld_E;wakx*3JnmB#kNcFx<13p! zEDi=Hgq6JsVJ8q=x)j>r@X!W_hc-Aow87!A4UVuA8s`YH4UQ1okW#yqBDF((Ed7~9 zTW9)G)_zLT2jT7KBt5{tHaQ|OwQD~+=~>!uPbMJb1MMd%0}C>_$T6mN?YAYP$nf6s z@|fDS-=+*ADYc{Dp9~x=PjmSPRe6QPjRE)UFyQ7J11@o6z$I=BxWtVCm$=d2C5N<( z0hgB1-xo)Y1|$xbxUq;!++a2)ZUn?(7!x<*2#FiHZlU$iafT1wWw=Y+f*!XcFg_+@ zf)3FgqcMrWv3>W?Cuou2l9)(Xa?eXpb$mkbNlZ}XlbA@D+3-mWBzCRehITkYY=DK53*8OQ zx*1No<#|rYSX+#bK>wJG8KI5Hj$1}mRgFyNEF6%U#Y~HbD38&LQ2M>MB#2qT%&|{*X2Y$k+C1+ zMu_VZ8ISu!#^XMb@pwpNJRu}9o)8ilPY8)j|K0L<2Ile52A2_qHaI-A!QrtDju6}6 z2(b;05ZjQFvCBm=hCc!I^4p!J?|$7LaU)ABFAu~N}~8>n7TD?~-jSx$ZA zF5DnZqQX!i$uXSVaW#qF?D|_R1{I>5#mOBfYjPu*n%?mVoZM-SCb!rVsPxm{?dcts zAxeQ%4Igb8Cl!y_P0s;5)KUcx$N^D++D;KPNjBoSc&!gyQmg5?a`~oELuT=)stM@n z3Pq4!Xh5c6=&ny1DzxPFdb4#dusL2OGI z#GWLe+eNTxXRzz^oRxUjsT+`J>${Hte(PaKD;w?3?H{Xt`;byZ=Cf+Xe(U5=w%Go{ zL5W-pq89vCqveZ23tNp8E($5^CQ`B}q_CT4v7%bLw0*AcWm2Xnw6L{Mbs)XyQ=NWm z(b7bd>st#K6}o+d0eQP&0+@|q(+IVQ!WC9~UDvq`P0!#@t9zc;*6P4(Yc&_9sRpMP z&yu1}Z%4gehdSQ82e1oR$oxtqU|b6fEI8wur8>i!rQ%^NFfi*J)-2{6)+_-lKZi9- z#S81hnx#4`&bVfQ6TLj_0R|2&BF^L|g9T^m&t_=s&n7CKK z3+uT*o6d@J=+9ygh}D4oQ76}Zm>25+h0iVbwqA#dK3&8;XnTMMZM_}}|HP16?rjeU zoVH4NP6Oi};41w@ecl7KfR7opc#rR_y0725m0s)mRMIC7t;CN`6NDHRcdg|Unw<8? zU0Cb2gimN;vDe}~p~cie%Jzg77JI57=!-qy?WmuPwi52P!rjGiw;S$O^)BQlT6QPC z;3Y!OTeRTL)1FW*jq?$`lj9m|Q9G;YcT{25@931q?yyqJTCbCo%h?3;GQhIB8|9V()_>qK-(z480u$>SAjyIIg+yJSR5y*S12t#W%l zgs~_U4REMyfJ2=jhngX;*EgW^`UW_()EgUc#5|T(wLTp7AMTc6KNm2r>jwJ0LdC;s zZD7F}b0yUob}9yk{l~zpbJ%}`Q{V6Vwqp>KTcb#p1KlSj~da^4_g8F+X6x?;QuZF<*B z-Vx;$cl3c5-Gny1qc!GDXz2sH=zu@mCz!eRW{> z)q&kt2RdIJ>U?#m^VOlw*BIx!vM*^%j`OwPiy5@qi|?$|tKYgfUyHm{(#QF&-mAy? zTH7V8i0mCL#Q9p%rJVkVK#RGACV!;U&AXR6Qo|**7QIU-Mt_?_r?la3a~RMtnC~=q z;yaz?e5Z4R?=%zOJIw_6PBQ_%(@cO)ID53ucPC}O(TSd;wYx~uOn^Bx6M%(QxMgj2 znE=sxCO~&R6Clql?DJh^4bm^q?L+IeNr zA9yWhj%cYD)l1TyUa!T>(11O^@YkVEuS1<)haT_NI_mv(XsOrx>v&DCgc#znZ`u&! zbKeXxpMWvuGq8mLy#XAT`UpvNh6qW;Lo8)r);Yv{%sISc60q`fi1}2!us+0ms{Xzb4>KKjXE)|vYgoVh;4IA_^7VXMIrNvIR{&K_{V*Iw^9f74b z5Mf;`YS71No4nY zG}~`ml&`l|Pvn7tBP!6UA{Efj&e=U5_u4Jj7Om}Uu5B#icV%{^*2w5`N?`Y`z^Jpg z+vS>ium4%8U9Cn^-tk_)RHtM{6_ZLzXdc>DCNvD-1cSf zO$$wGZheJ0Dv_`%!L{z1Tf?xZ!~(_ySGp}|9Jp)05o~e7FmP)L)d1@Y*aRm}Fb)=w zJ8p(cZVh$^?!xb;B>T;9t-Izf`Ws5B{${w+UG+C{*M3+1-E>Pz5gTtWyc0ZlLSc~w z*v8DLgw7GwAbUVZUKbHylQw1t<5gS*W23HMY}E$4t=8*yu-ENiuiL?1w{F;Gte0RJ z?c5 zapQw>ctyK?ac^xw8@Bw8-%}SiSN7JoHWyOaWy<8d-|qQEpxq8Tu~v8)ecXwq%FF0+ zm%X2UXw2`T_l>}t1n3itCHfTNf-v`%k%7Js^L^ikp}_CMT>cfdT!uuYcU?0`o4?E{ z=j@Sl*oT>O*oV0yslUiF4PmS8TVCLITVBKiKh~8}zr!c|QGe%mTPoX4OT58xff9IJ z;tejj$E`_q4@;#g8J2j1E8S^{XKs576GtO0@xnbW@v5Zs1S@Xo$+)Ge?#zvGsQR1X zq?_QPzZovMi~er9YflQlo9>dk>ThsY{Y`M~ciK|XRZU6mZ-%Q@rY%*JjG+M6p6Qos zY(A7*D)Ww8s-VM`>I=}^w&!8D?RnU3dmeV%UZ_rU%ckEXYuM}d+-|KMw^UcrX1!Bw zsan;hOj_5b_g2~Ffv{<6b(=EiN9)2poo*R0Y>QguW^_6Kvio7@(^@y94_lwsyBU4l z`lRN~=xwL#JIz`r~BXdSBCqo;r`-qj~``}pLAt?tNngRPqhxt`0ythWY@2wGE>b`}&{&OC`EPG+~ckptLE#O?RG6fUEhzaOFvgs@P;TKbn%# zlWKkt_ZSVT?$K}TY`!|rI$ZI#&p6iV`^JlwywwL(j{A$GYd~d|{gm1+4 zY-_~zlyAiKe9Le>4IBGM@YFwn-_4W2pYhZ`f#3C;>L2?@`6qblpTJ-EBd333KcxO~ zZ{}Qf;S2R#cHv={0eIMD7apdQK=Z}fq_e;ZrxUgcr!zLgUE<+=cd+-}!QOWVd*2-# ze0O;8-QmG^hX>!s?8wytTKlT(NNWL=Nvi?%-s%B85V9k!2~-CC?pwI`(YRIy8UwPS zKp(Ortq<({@x`Fl2pV0g1nqvzj-*o1=tFiy6%h1SL6P2{38wdX!}mQq;`^Q*@qN#Z z_`YXHRB7O|AHMI|57+$l?1=A2de4rS-m@dv3)vCfhyEV2Bcl84i2Sv{wr58Hj=f{t zJv$2AeSc+m$c_YzIS+$Fb|hfM8L|s5<;vMb#CvuT@ufZ$CJ9sEciBb6C;CyrXH(7V zci9E>Ajm2GcX-h6@Sxw}$GzQ-NB{-0uchor;4#ZEIL4f+ zWQZaSF1g1jQgsheB*Q8CHMr89qF>=2-{Go~((e@gs*;*}%#Of~;i>wY;p8{LMSn9~ za*x@Dn#?`elw`jdu5?%Z4epeUvdOByiM#0UrljhGqc=1%?1d8hnMm(6-chxf9r z-VBWy*0RPsW}~fsD`lgCj(RDw%X%3ddF3(X^>|pNk7%}2;BB~uJ;3-2yz%!awk_kv zpYbs}QvNYJGJN9Cm>os_!tRhASxw*&{VP63|B8>X=^r1%*9D?VmNifheZm|^J8 zF*}O`3*D(SMtPG>&8cXm&BdQ~v~h=a1m2e*(W7N97-~AoVl#PvFmX znLp#Hf7G8LYx0$dF2nG!%P>6bG7Jy948y}d!|=GzFg)%v43GN^!&fnS-+e;jf^wTS3zmdOqCsJ73G5uEFC{_^07xBK%pWROgMxKAwAIY zqYhX#WrPyfs7PxnyO>s0I)v*g9Uvtd4w2I+hfp=fGs_;3FSvC`>m)m(m68tOM9cwl zP~{P>mvo4xV-9K=*QR%lWNFGk05i2?V=4$<7Ow>;Fckbprj%R=52X| zB^^m{%`NqfBX=%)bR0e*Kw;vHa(YHVFh7yOVMn0sT1Sm`9Azpq+UYW*o%SAGN*jX% zOyI~b5i|-d2onj7M3aQR`A!6l{tH5F!y?jA!eY`yn6<;=(j+l!hsCBzV%83XkwrT& zQkD?}RZN&jl)nIlWf(AWWhv}I{9<9afJX(I~khHf; zQKe&%;u439+xBYOwzas@3FU2D3M?H@+Q+H%klv*_p0tl^k)-1p_i?UZ95!qQ<&{zp zri6D~Q$i7>Ds~u%N`U9x)D;x zv>ve6JY&}s3%aUG%bF2pHf9oeA!Jp>f^LM`MzNraMBbQG)x@h}L045XiLxCSsd_w^ zP_%;xd1HccCQKx9pdb=C;89goJDQCYD6m959*`(DSdo~uqu5~8#>A_7Jji$sc+_}q z$7F+*a?7+~#?ngna5O#oV$R`i9}SydD4FydtS5xc&lAGtHyFlW;E0 z^hvlDYmQQncw5-usbJIb02xLQ2o-Hc9y*u|NYC&6gy*tJ*;L2=vwe7Drs`ZGr1t`B zK}tABk5cr(-2DF8>z+m*s9)+WJL#i>NLiX{J3ga?NFrzpkwm0S?ckJhZ2b_YK@k>d z4RCzu6DdO@oy=g|QG#)AXKZAb85`*+Q#-klN32Dz^&ClEOfNUMD-i^YJGT(>9%+P$ zMBeMwM%wXIRoYdJP}?Z>dX^~mdLhi(QS9}qYT{L~*Q<@0M2@{;F{m3SjsenM9}7Z9 z{=C;q`KKJ&IevQmj|gsj3n(R^6aGSfJg#*Hlu(QurgITHqVt$AktpXAN#xj3RaN8A zY*aH4gnB+Pq4uhX<=J>WpPH(PSM_`%i5xqsjoc3Gy}o$V4Tw_Okf+__2s*Mgac5jB ziPB_BN|RZi%2X6RD$Ty>VQE2``lbh_GnvwZ)}BD2=Z#t_$A3#ZiW~ILgo#M;Y3Zb4pjH>RM3elv=9V z8MRooBUY{&p&_T#lGVlw_>^REMo=zFt<0w-*D0g)a zocB7mM?ykrQ4pc*AZLl(YekkQgq&R&VT_+uRf>jQq4kpw#>hXX?k+rk& zdOS#?9FL}I;#EB!P1Q`I7!Qh}De-J?aNTpmc*?3sp|c=4#pxj=*{w)E&RT1euc3WPEJi_6yS1>{OJTC8|u$5{)wTEoX^Q zrt~2DCb?7260O`cWjjjA*^W|jmZ+4RB`PIniAu@Yj#6@#sFa)~Durdjm}(!SY$wWu z9;JCmqn&$4DBPYf--1l=AjnjdqThl{>08PL+fxOvi+)qzQkEEHO5bw7sc)I$^0bgy zg$mdZ0D1|ZSp|t1A!b%VBxH%65;H4LiJ8?expNxgJI6}yHy{eEUdcx2arz>WO zK_=w2o-(v0XNj&{*EOxq618Oa9S=PE&^sSodiz6fJ7Gn;0pn`h2(>)XLsq&wf(2(* zs0F-USW9>V#znjVLbgXgSQ#)m(+n7w@LMR6~KWf2u{rGya@k(jneDZJPmaw7b4=o3 zw;*W{UXrF#8i*HCdf-uzG&w3sGg}srXDJKG3(~w@7M2%M^LANiUP#T`h3K|y7sk>O zra>W-rc#r3k(8zzl|o4$O48icTx#B~*?7Uj*?19Y-mckrHHA|TXXDju&85nAQBY|K zPv}CXNJ^C{n)DQuO2&sr!;0@nc<~vnHZkI2w?QAUq3pVd%e4Mt3Q?!mb7_8zHsbvm)Md+gS%z>{6 zU9_e-@Ws#ts_2iE297F135Cv?zX)AeLW+~JL=n2M1ZVQmrx0PpC<0ZM@K@j2#%LhW zhG-ztk{s4J)tT%$+8yMwy)HLIAM8uHn;9wZFhZ(UeIre!s$E)b75l9!ELMFZ&1{vs z8B3MBnULn~Dt9wgIQ6jH&D7Rhs@lyUg|VEC7n91~Akw5=Oqxnf#;e(?$Ezu<+r^}r zt=V`%YBpX(nzw5TXU&$yr$7dEV&M=RFkQq4=Kkkq7Pp!JwybaG(-fR zG(;bsG(-eL0d{cRg&3nPM;dK8(rBxSK3pkwFg}Yuv>e+rYeBZhtR#B`Qvji5*`84f zvvu3nI_<F)7~;SP@`o33uT0AqDA=_btX)-l^gB5{@88 zB%(DoRu1-qH&sL;1>=FQh)B3ZJO;Cj?L@mxcBR0!3hZKm?H1T-#EM8ri^xMe@KSbs z*`tNzneT~cqscxJF@#c7bP;5MrHKZNO3Ft*DgYR;9@oU|f(yANJjp$5k;}$h;kklT z#Bgk>h~bz}#Bf5$ub)uS*xQ4@?hb7Yv=~!GxurYE9iP*NSS;uqVzEfOgFT$Ihc?u2 z_Mi?MRvk)4T57hFOKv#Y;D)!Co89GdvmNaY_Nrzdu@;6NX`@<3N!-aG2pGD;HCyj^9Kqzb1VmQj-0noCttQY=*uBgyeo5%I)w z^(>=D(}6Nb`2h=3i4dZP#r6HCuD3vR$--9zox?jw*I2qP2}>LThq6c~v&K z39ZSk-$AaXX#qo++tLOtVJK;L@Kehe=5iBXTE7f5dTOcdaws2k3QdpYD;moUeHP?u znjX$qI<>5!qG@46Mbjhtil)U46-~<pn!djx=Pjq3C@`IlR=IM1=#vM=y2<8WloJ z-a?R`EW7No8hbq?xTUvl6MQszenQ zIg*j)w&qe*W(9?q9_5=DBbByDYBF9-no3n~V$@dM^G#vhE+)-v&BhB-WhTsS%*KnP zCgarE5XK?6svHPsos#VO!X$F6*Jd%DBiE_G)ifQDV1-s zlvJ60+g6UiR%=qRdl9V-{Z4%NRcDi%(3)J#I-M#3~X7#K;g;w@wkQ@3l$PN7&kpDI^m_SU{et9>c^Q~fM5d(~O?r^~2^>^J=V zz!3a;sUhWXq#^tD3dii%)98-^LJZ?nj@fUJ8?s;jM+0Nqe9}C$&5?$4cdu}4o0l5> zceKVoEJ|g(jpDu=Vn=;`M!JoBv9%QJo>9n!xiDlpe%zpsx zg(*zn$ZX`5W8)E))H1;w(u}ZvuY53>|60KbhSTIneOm(se_h?RdJ2-O8D)^!y|9eT zZ+C0s*|p`Z?Y+gW&!^}U=H399dp3OT;>O167RpFbfXh<&z}ievwyKIwFK0z?f1+q? zSoa8&LebPCq|lS5fiftf31WX}?)!rYY3}f;v1T2?3`uBgo(P(86oi=#iOQ3N#^fWx zGL3>z+psJnNzB@T$eJ_VB%yy5k_ejR7KFkp40=5tOqfWN<3SQ-JDRGh9ZZ+(hmDe7AMiNHv2>K{&+Ahxzxz7*;m3dzmIal zX5k1pVR4!q0g*~gK%C+TE}}q0R1=~NFELXUZD?fTwD-8gfj%m6u>R$PLGJG!470y_ zaL5>6$X`5k4*PqD2#tY?eze_27++r>c=Ycax+445x=HEZI5?g$E?L#@$9ADHU}$0*t4yc({WeMsZgr^;2(S$N z=}|*aQ+O)Ihs_>R^=5B`aZwgR-dv0@k;t2*+DMDCs!EHp5o#O7=E4&8Qqj%9*79O= z5sAFHsH%xqSm7sL<;`AgR1z5SVzY+?6ABwdD93{d6Nz#>nvI!PWjmUUi9|gfkf_Il z2(xw+n>}|)vDq7;ZaMb!FE(g`>44*rN&ttXeOv!%!11Ja1@_%{n@!~6uyN~m-#bs+xMdZm zvwtevjypLce!LjLCr<`7_-NmN;G=y5f{*qM2tL|3AoyrsN79=Mt>Je(csm*2ZfO1f z$b*meb zUhQf?$*l;nUsN=0#Sr^Nsc9?n03ERob|W_nBw>Xk%yBaoLf-I=Fp|KH%^nlCH_^w$e#ljsryfXPW*cS zr-#m^5cj1OjPdjq1TDrBPz1t8C`OJX%5h-AM53He&3HARnyP9Xm{8lO=MyCA`9y?S zJL>t=R8739=ToyWlPKmBt;|Qzzpa63e_cE)wyWJ*et!AIfx9;6;LI~7H1 z0J4l$02Gv|Z+iMalPNvOzR~kWEtQIXr%fn&>YpikMx7~o;-4uj6MPGHDvF*>XKj2^ z9L7}JBj?gHnJ}h7rt&~fq@6Ze7wUc!O3`mYCU_8JDoW9BK_+;ucI4bXdtLNfkf}Ui znTn#d5i>i%w^>5zi||9T=LsR9^n{S?c|!Z7Uw=lO_4Y}>l0xU(t}R|BQe1u--ctMW z`PddO5fULsh;4C%p)HOww8c?|wm3@rJYjEtPLN&wz3YuSLDt&)&Zw359kIIm2n`9c z*4%d{EwLYvm`!PUy<?FA6kb*sbt|A7OKI z?s9r}ZYB86)v@M)YQJK}&4{09jQFRR5kKP@@fkNGKI3M@XWWeVjGOACVm8f)uN9!0 zpMj?#na5|`Eafw9SRXQOLWc2A88`97jGJ0v>4VR>17YkxlkgdLknnpH6H*Q>@ECzI zJmj1x0_|>w#5z)Zt`#Xue!2y1J}V3|Aq9+-sU7;Pye%?OX0Wq6(GHTxxtmCo?PxYCub42iF_S3A1FGurU_x!99uJb3wWA)7 zW}_O9rfSlTYCI^9z<8t;obmJyq16u;?;Hfr{1l^C`Wc__=XV;d&K8}N{L~D#b$8ma zj=**kDJe~6$3Oe3t;v*>CgZaMU3%C~Maem|%H$l{C{y2Z4jpAm4_bQyMf1m$L${Gc zzvWy|DLIE$O3tB`l5;_&uuSP&$^}hkO5waNjGVMI=Ypy&=YmSfIkeV$b9=(9q8VNH zn^1~=3o^m$AQO5g$W)a4?m@lIIkZxWep5T?twfZmJSh6jWuzhR3`OQ4c=Zx{{vmaQ zkav1jG4J%0n0ID5|Jn_)d+n;b{?jGXuv4FG`+96iyK46(IDbr$iC#lu$9^%x~ zBU10~Avv@55LcE3M84|pFs*rakQTjrh!b^>$WeBH_=El)(!*?zN#>lOy=4z!^`l%h zK_>%*oDygEp2_Ew32&KQLghR*`gl!Q)zi-Z58#-a)HD_fXpS zrFPu$SQ+|&r6@uQ(E}S-qB}@S(F4SPBj=$UGsyS$J(HBRc_;+~T9EFUD~AVKm+rYzc)*3?V;I1w?0-?7_K>u8F~8JnCH@>9Fh3{2p%q~x z54$z0P+?lP3ya)7Ic>4-pxC&*b}? zWr{sS?d1JHwdHl%C==hRJ%nYdJwzzQ9%7WKotbad9-`W&GWrfM_8W$7GCoYHd?QNT z9;VD>>hWoI%JFI1%Jwj2VrMcwkeQ4RQKs#w_IUJl(>C*MGCs}DRHhoA*&Z(?=y}JE zwdQ`Pn<{<(=m~Bok9%(@9uIrGr^LP2Q{vtm>c^utzh6%&gB>pucZ6b(ci*`8EuZZ1 zT6peQwes9SR(d{Q<4&!`=Z;OQ&qs((PCb_QWi3GWTyntfp}bdX4Z7#bnY&h@d#+-$ zmO6CLl{aguP98REhIT?58`nyPwlZ`vL%SJT4Nwjbv;f_Ek2i(GI|eO5Ph3v~^-b`R z03p<%Ds(RhXdGHVREIur(Xn`h`raQN3@-haO+0m|ZSNaXZRav2hc|2`hc}Gp@J8_T z_Jb=`%a9|ILdX$GOTpm~6dj+EVxSTf#y};K=C*KVo5p7hBB2Wl{j9Z)G`7}}Mh_e* zdf;uP)^@4XT1T4ODq4HQTITyf!Y}!bTt!J+HTQTGMi^x#Q-l#BQ@qMiZF$=@%EV3; zMzBm3MhK+{BaAY&GxMzqBUIZ|rU)Zq-M1eejxTZ;5i7rwL=i^B+HWsG$1sQ&^QzDY z#p?)GRoRGV@7{<~sy@bCpUg9+%w+0$Ml$t0Yud_jVamkLWS&80GS7%o&oib>?aX|e z%(JF#DpSofZ05cm+z*hF+BC?!&k^)$^Lr;PutaK7HK|Fh&!tL|o@f^y>XCLuntP~+ z+Ec08jn=M6qDPXNEa%!@p^)@oyCCTaZ9&qb?SjNor5k#cb!v-3U@8sp`WZ6`faGMIWlvoK*E;kg7eLca$D?`$3te zg}%}|zLNEnn67zBObb1Q&b%is&_VHpL?^`)5*-zLl1mz6syh^q&tyWP8DyrEu}#i} zu}zLNw#kvkHWlfvD9qyLcqb4oW2U40#(MxG>=P1%QP>NLYfyzOMZ2Vq~lXkO!IBURX> zYEqL5xk1}*%vMP%(pQx#(pMwRJuK4KC{?@B+7(Hfu;ui%jV;<$q+UuY(pM!F>8p~8 z)JsW4`l=)?G9KqEd6-kLC>4iNnp~u>QL5~yBK5NJ&mwi>B)qw2#TRk~62;WT{>WzjLp^fDo#3o=v6km?1Yn7(?_km`BTkm~tb z>zKZJN=(T;C8p$_5>s+d8QbI&(VZDlLO#@aW!{@q@3G>TF>n< zE$9vyC&~emgW-sAO?SZbXgGk_^XTuPGlri6@Ixf2YR2&EUY-wmB2GmIsOO29&=R!_ z%kgGG;J76dBtt9+GYKi=&Jwx8JMe_#%tvEm0}Ve3<@?6dkUq_6Np9Dtc!Qjy-9awf z>vG6L2c15_DoGrP79&x687v zLTcVFi{}R^jHM-9C8_KUlA5%ONmHpwyP6x4bro(*+SP1LrDo#=so8iDY2L2ccr}HR zd}ZfnIK@`102I<#Iq z@a3q3YqwKy!LYnk98}PzmsdQNkgBRIQA8aq!8v+tjt>Cvt~O{3w9|9iu#s~eu{3Dd z$hq#dzw;jKVd+v@ve#+Zo}(qXS>V8KVvj01xV608h(t+t-3pT32L2A#7 zz`<9A51Y9s4V$?q4S|Cv4V(E;XC7R4(ZOiTkw#mNG}@{H2Ulz!jL!lGEjRbfT5s+# zD>xs)wD)Vtxo6ax^Muh+Z2*gnUdzq{pVXZPtl0gv@;vYrZy2=pJn&W9zf_+GzGC~Q zV&rlAXAD1_=#ps0@S}nW!%vmr2>GoI7t?CY662>xi*ZS$Ek(aW+=bu%_HFXCAr1;Uhqx=!?qCl` z-oYN80r|1N0Ect@)NE`d+9j#kj+WeTw80H;FE_i(im)rQ(C_J1ao5sHy!w#o=aq^bx-6&A6Ek>YG2C!^e?N22-lH@ z>@gIv@5P7KOU+4i&K~;2i`{`nC+$(QFAqx++>_fA?)X)G&8Zu+AFtyE#jcs$Z z)HX+>GJ??VDie2g@PT)hiEAaiXVy}9k6A7J2&PP2tKmJPmcu7(%*wPNJ}^o}{D_TN zp4P-izWgFytKtJ+@gm;p;v-`#j1N$eiBl!nn29qMpIOG@xH1+qamHdM&RERE8H<@X zRb-7BHe)fv)*AWHHmpU@E?0ap6W22NAX{YO@UIohk9=b$PJCk~PHnRUCqA%&lzZ5u zVkRD>;-1E&BCi%g&a0V_&Pq^r+MOPbD;} z+^%(RZl9y2_BmRz=V+;YotE3@Xm_xO0{SokeH+I1NdPKu2L`cOUd_E(<~2g9@){$x zz;twxbG4j9sjVVIR)t0UZ={*6GOuB&GOrQRyj^8pqY9@UBITKSSiLV$H)<(NkMg7j zQcNms5oyvcCQYTP_aJI(?%||e&DKMoG7Vjyd+{Di&SNl@s)xNBK$UQx2$g4eRIF6M#rM5X*YMY~_wmI6ES7SZm-|!9{ zRhPzHp5@hAqJQGa;}1OX!0E@97C>6A>=3Sh^T5DirTLwQpu{yQ(xUt>rX~3f;evbz zNIAYkEY=h<0w;^(N32c?X+l6PBDW6OyIaP5j4Ur2onj7+LMIlB8i}p zZ9%AQShPM$Sgf81vvydVo+M`Nu$(GM%-Uh+L_q>0W!Y3gC|XVuWjmNKkto~Ij7!## zjF;_bHYO7FctD~a4?~VKxa1=vt{F_iGrx}% z!h-7vh-I86N5F1h6R_7ig4>l5G1Y`ruh zA>$q`rS6@>3f&_#ZuU~-?wQ7bKnvVE&uZG+SJU1urR`2gO4}SVZrfVa?pWkaxTvC+*`@08Vev9Z%ZFwT#{IjQcp(kq;X-gR*A@VS0qdRfxHz_-f=%`#5u_eVmJn zt8Fq;PWuK=x8ooawn;9)o!G&WqLjf-r-bb|XdCU++cCRluRdLWwbm5Nzes4=Lz2kL zzuHKPxvEObrV-NMHm{21pCyXrUkG{mH^R)u#H(WYS5-5Ky!=A~V_0m*Mku@@iLxC` zm`If4(TrE)(NtCKU_x!99uG*=<3WU3JBsa?y9C|NuOq{RYc?kBuosv~q8N|Kb{vb$ zoubB{x8qn~?)d%Y>bJ^JCO#vC?Knt;1=nw`L6swf?Kl*o&s2r&7|SIm+pcNVcD!0| z$683LcFN7fGd{~3F?<+`pMTaX`fo*ik)m3BQ=xHI}h zR903+o;-EB`-MS~6v;G2(tA^~rLS*XCNReUuq3}odyRFgT@?qJHni#mFCJPQIbps`=DH!z4f)uRb3<+rX~TG23kRQN ztB#lKe*GJl>~SHyvi<{Y$#g)k34n|sr3MAj<7bx9!)HQdv|D2*z6pNKdL`8IOUC1o zs&_4+%|6^hn|(OkW*-Z#dk%6DaQiQ(w2(7O!C3)w{(i{$`6z{E5~Pi05}a~qN6uxz zYiXV9k~e^Oj9W7){rWWZ5#x|jj6(_;M^4S;=G06=%AuW}$+zh@WptidEH- zZ7I!{wX1v_Q39?97sJxtuUyA5XqE4C3BIBY@<($=DGF(|b9>T+u|0XhP;;hgDpgN7 zV2tg_Y)tJ*66W^g3A2s4Jt<>sPp0Z1A9H&$RY#1WJ!$XuR?64hZDWL{SO-6*80S>` z%H)hG#(6m8Oet|V46SH+9Y@1M%As#@EPTWnJy=J=z|r?jbGi;NdrBN%_7vw(=`3w= z6nw-X--t7%#369k7DtvnB@TdlN*w?86z5DH#8D-1;$XCw+e#VAjW|?p#FZsFTH0`A&|aw87;cC-e=yV0~h!US4_VFIm>FhLJL!DFzlN1tLzdh7`)u%x4{SG?8Cc|iuQ^@wqlQ1Sx0N?stPg6?9wv; zwmQUxkY3{9HKil?{yT!L&JkQwI)ZCTM{rH)2(Bsh$_uX-9l`aYUs1+mU`M*lf5Us> zGPtG`>t#);NU6cLrc@bTQ)(`9a$k!w6KeTo0m%VboP#J3{ zTsm?JE*&}L?^v9)-2C|{g;rIhjaF5ha%hKERl+%EA<`<5Q%Zh-Q|v%W$a&uM)k~hFSee=(GAvun8QyEPzHilWf zGlm`Em2i}gVOAfi4!jy>^8k){Ea)iPn$56&r1pm?>7NCw!Abn{mbz8r%x^i^V}9QxK* ziOd;2=)SErT3;nvO-i}-)lQ`JRbr&{Rbr&{)lQ`J)lQ`NDuhPz<#k^rGKXr8I8#br z?S!_zO0@Q@t*WgOBV{PJwRRfHZKVw5MjWbB;!G(+xdo@K62oifQ0Wk7N*T(HIOH3w z(`aQy_iJeahzwjn5#uOWmT^I!ej#%W0V(2pcOBwq7^SDl)Qj0 zUL_KT*0q>Y^3qp{5QQ7EHm?%ng75$QxBvBj{_@wq=Jnou_WM5j(bk6Xm=}8yC=#q7 zuJi`sO0VzA?!e2(*V_wwc)dT#S?cBck5AXH56@5Hk>BtQ#<@JMD?ypOPBQb^ulnxC zbF?&AFHS@JypB8fvtR$s=Q!$2Kt?RR`peI+`&oKFT@z-y zJ^yt-%Zf}6`7&7tz&Ils!JmHr;qw0K{M+s0sFeEtgo{pz|-EAFqD7{XGTO z$sUWYb3F#vdW}J!hW&8a^!lh+^096Pvxr|bKVPrs;kna=H1XGjwc4qg8BZ|)PYwvA)f zKPrno-rCUC-A`O^xt3bROzCljI26PM;(RW%g>`v2lh*~OeCEMEt_^4M+J(;NI@qrZ!dBfii9L+&Q>p8QvW%!@Gmd{t1WoC2b4XoiiL>fB5~U z3%@GbM@qs)Fs3dt;8D_F|1s-^fso{3s1sbehS4SLkV49*k=1?A&CaYdE5_E-FX=e;FVeNA58b8j4ke|>Ot>@@^Q86kF5P)YYbd`$P~cU~$k(yhG5k(I9#rwWs;BP(AePFWl)_vlBLf@c^;R+5Hp7{^Lb z0x*oM)1Ob6Z#eJx>(4U| z132k{IRoPd`sIL=tAeIxqC&dUF-w3`mH;P{fP+cY&so~?oF%{y^w%uC%^XlpHw+sN zGVAeTYol$#JjN}!j#>$i(sk4d-DT7YC1s3Dc+%ZQTbFL5?Sf~&+h`j~Mo-%8CUnoz zb+qLxy;(&*2A8!dU*~1nI2KG)j|tlPm@o3OY#qh<5^u`RvoXoEG|e{qUGPxODqUy4 zp`@3b>F({rl+4ntoXx?heTb5&eJDKpJ+%*0GI}z#57RwMH@{^>#4Ea44}n`RT)OtR zQn>bdoVa^a+~fz`?J01tF)t@+SZTNvdanw4?4|dIe!1Ybhe67R6)U)t7Dy(=M z6jnTr2`ldM-LA`bJPrt}o;X&mcpMH^+~uLZBENRb*zLw~YU)|Xg{^!R-pYsM!7j;n zyp<2hgP);)9g|i+TltWDx7*5xnDlW~2P+Xaf z=e#hB0IjOxvTO*%Ratt*S$tfRO@Vbu7N2ny5Eo>3I&VtG<=9Lwo054kb_>|G*nG5A z(ym#(oPw(=f8OtkKks(q&wEwn&wEwn&wEwn&wEv+S2u9gw5rl)s*kd&(sW!^slPev4*55|9KhO`W5|Nkr&*(qk8ZRGp8cN6+mwu+OyzC5XX#enIxB6fO}pYJwm#wQKw1@ zHMHq@6kszSc5suDl&r>?44 zez0r)10Ji4vZ}IL694O}A@I7Y3cRkW0#8Aem+$3J zR}FckvzCvxwyAs;-pYsMq5Y6N_(Sp?Z{-v6Wwn+58{X}<@(F*+sx$Po@_`i&tW4;> zCrr#xdM`mpdWLajLgKKhLL65nh~vrxFLI*qxR3$g0frSJDuERt!sI(>!BrK>!^#hF z^1ZIA;G$_xRHju`Tr&Ot{_?lHU~0epa)|%5Rh0hBOQrDuDVq=%NsYX&h}v(z9_q0F zF?9RA&aUjYUkUY}>pG}D#8psBSZ7!E+ZR~&a~)avZ@=1UzvHON9;DyaE1moItN&gr z8z<{3=dU57S2#mFr>`5ZDf)g~s{jCe5Zu6;{R2=X)-B2{(XUln8XcJY&7CCdA03l< zapTIIeqra#pnSL1u|aO@+uW_s<_7B~;x?PR#Q?=zh9I9K0TgpDf|^v^fCH(Rw`?fq zS_D;HImZI2*u4g*`<3%5km`QrZNeobWtekUg2*qGD&^%+lPZ3h`ZZ4l^~EpK)ud{9 ziB!%@x2{@VDpktMh--EU#JD{QQ1^?=i{_rjb7al=HWG6~Ku`upq1812B)fpd14#P& z3Q1pY5cKCVhEynYp;RY^uISTE%f8iTkJy(h5V!f(@9dY?B|L-u{+<5J+k5el@^Nd= z6E-7m>zN|yQ9rLEH1)RLWBMJZ*yZ>~ zms>q1$*msKZ}$W@^~oC(SnAu@)(2S1)gIW*QV+Z!>`@Ye;<3CwV2={Ipsxrbyx$2` zUDTtv6!jV8p=62xYadf?F2rEp{rDJethffFL{RjT;qP?IXw)>Un7u_NgFP_c5;Ga>TfNt$`(7PdJupeFt^xbj zMFeQ|z~v^GIe}737xut#`^&^@4;;6?G%;>`>F>Pl6%X0h#w{;r>^{|Qd+ENnCBW=B zZgm;HZgkmi=xyUBm*FrajvHKt9xFPyd_irLn~OZDsuAwjJ?%VWmiPe$MGfyMmg0RO- z2&%7-e4z_^@*qNwnNZb5J-JI!Prjh;7xm;pY!;~}4_#dfdvd;wWF^?<(tHbP%f#NT zA-Z3b`?i3>*!-&XXS%u+`K7bnw^A0CA?T?Tvw|*|$({Dwo^k~a(_V`17l)#tSjYuts!9yMaI|B6`bO(Pcj(ul>LG-9#eikR<(u5u3l z);?>OTjfl0oVVCpHLkuPHNOj^{F2j$fWkL` z(l@};H^9<2z|uFIvBJ$7^SjPi<3^1p#%&t?oi}OXA!n>{gT@(q#%ecdV#XS`W=v?^ zn2FzdTgHCFjP(m_5X21`lYtF_ycy#Ob}Pny!i-hVx?;xazrD@*Z?8N5?K4*Y?K4*Y z?K4*Y?K4(AABq{P|Mq=hJ^x7Dek1NPR+sS^tLV%btNzZilHW07RXk>_>O)Rwyg?DP zbCyy*VjL)p>j3O@ETBr{jL;9|c}B>X&)^vQyH`C;bbs#Hnh_FrO<)-t z^sO18$epub)>bxS=^x0YKETqyjcxw`8}zLiE7=YI))2W$&|31EWx{T`=ayzX3&NR2 zLN>HQanfE*=z z;fyupaK@V0U>9esELUt;J{A@;J(#h^?E{>_1%@-$z;MPI7|!4V!x?K}IAaYAXK;bJ z+$z)MGtS^xj`QYn3)33cI>P)ejPgrz%Pz?=M)@VVVi#ttd|P3)tFQ|*be1c2O^$6) zeqlzrW`%UoU=89Z<+DPP>QKxINo>tn5sO(NVlgYkTLa-6P9B$U0Ik_H64#6sq4W)y zF=HjUHFHKReZv_m+*+{Sr_Na8w!;7V_y6~=|Mu^H`G4}t!Up^r0zBK~HJ|ea10hwW zD2WRV$%(*M8}Ku${k)FIHn6sFH{ge5@Vu@&BocQX5{UR$8}O60{k-;j0q}be8;G6X zjo7SN{)%!IsR6G5NH3ss-7R6jUjdMrt4!>-fcEXNVK}4T|5@(IM%;_bw{le$f?XBL znz~lhN2!83`2C+#cWPeK+am8>d3AkVxG1vy8pal&N$uaNzBSL|Ok0F6;{5}7m>@IG z*^*3)G2xtrE_2?4gd;|=u~iitHi=l1R5anZ&x0x+)0~da@-Y#s@^MF?;<0Jh@lk(H z&We1_&?DYpe1H{^xB6l$VOhNpHt{epP<*-|<;~^55*P*>JTx`EUAX z`LX;(ek^~*5Bwj?-}J1haPf02f75>;AM@v}M<+x%`K|Dp-4-~e!4+=OI5oij7;xG5 z+G+ro;d;bn%-%Q*(lQAcang_S2YN_<4CGt$zO%A19MU%$fAcmF>9ylVOF;P-Z#Phe z=@noq)AN=KA!V#z7i2)hFTErXH(vnojjs*Vv3-TA+5&60YXfEAj(ag%VC{WvpbgwB zVAYneaeIw4@)gQ=59ia>cYnI@doxhs4nU2@ZJMpB4)8*u0p4%I*mlq+jf1{R?(y#p z4$Pidhxdh+;oZ?`c=wb#yf3tB!C@5#NxvYn{FI1QJ6p)WL6R6aNcxqLQ1v%bCB01~ zu#KHiY(N4t#(~(K$}OXki#`x6`M9E2<=a3I`fJA?dTK|Sco}FM?*l>NvwRx}mi&SL z()HTvld3?J)-iTG6v=po2P>L41I zowmff@w9G(O{wjNY-!O#-S1B|iT|#Y{{TQndOf7uN(JDG5R~$IM8jaEsN6toH+RXnqg4qgujD} zr0VB`1e^wtDx7L?!jTO*blUl_SsKsWM2mF3k%hm3FeSkBgBffWRH0o|Rr0nOC2x>$ zWTWNnZRTX>*$TW5)?Rvjvb69vSSMZvyU$l6Iw<#`GM>_jaRw z)mtf1^RssHnqaHDDZv;g=*dErF{T7#JRC8Ggg8LljceJ6Q^cNd&D%jfkNI5@oYA z?g(y)x>=gH1wq8F4DM&?tM$Xe0>Gk9?{$2-gqO+zXjTruqRs(W)Hwi)ItO4;r?)9+ z$>sno+58qEEc+a260oRq30TyLSzgpBz!g;&bt*xNI(0p#)}`PQ*Wg;Ps3T4(%H+VJ zj^trjcf2m@7Fu?A9j%MHg^sek81ma^!(xaNU@^oAe}^`8w9q34E`~Va$c9`j-0c=^ z;9^Kr$z*HJ2PCi!NMIX~@G}|T2_+wpaAc$80~lyy&8k*TO2+%5&Wo^5&KKS$=ZV|o zjPm9Si?V|p`s-vn^wi01;-mgPId}QK1H148|NG=T^vwSB$$98MkZ+T7k(UY^%ir;y zU&SZ?9iQdf4tUrd%HQ-1{yRSEAIo3l$MRSF!2hxQP0#GlSpKH}K)#p1&eHqB*RJPD zG1s2Xq}#&RrQ4#~?!gVZb@n*uHn{6{xOuYP=eDS`F8ZzLH`i@*y{w3VWkrl3p_f%K z>S{0C?PW!b!QEa~#6YiLZG{UWx;u(h%kW`M3_JeBD_mV zdB7DE<^gbA)S({A1Ipw2lL$u%oCi?Fd1#9|xB$CnI^&`)uEPHOpa1z^fBC!KhRw^c z2>BHmLTp(FNM4C8SeI+c;$kc?<7zBIemNGAbv+iLb^eEtUy&tbU6KVXuE_!v7iAIh zMI<8YY>*(oE{jl{47vzy%HoHt1j(O%AmgzBnO9C7CSm2lXSIgZj~w!~7i7k7-*gkmmJ4 z{g|CYPOMu{o6b0MbnilHUM3Zo|s449e7>;Nf{BAdPkDKbMiNRc@Lrohl%>_AGf z11ZH0q!c?bQ$XAMdM%Fy#x#axN*fPW%FyR#$`NN6L&8oU4?#=I#&}HO zu@_T#>@D|o(E}W>*$$)>JCIWB3}Zap+(o+wV|?7+1<|;_3sBzREm$3?;}$Q7#Xa5% z=~*ITeO!*)yePHq^CHy8>bTR3Qhntf_j*xk7_8UbUX<#Cb=>c5QYXrz5wAP++@X&h zI(O)Xpgui_`@ZOx?C_O6hPdm*WiNk<=9s=0+EnqV=jdH^i;0ByD0ZdS`JBpurta{D%OhUH+@F-;@9 zTqUIq)hlHfb~ELOGfX4GPM=1Ewm$4;%7L9}8sVI28nIFi^D|8&LfesV(=;ON9CC(f z1m7ISiu3tJU-czZ1XlG*Qpq**TVSWzUnQ1%9&p|sgJBOSpKiVI@mD0A-=|hYr ztz&7dRbri52b-)p$!t9wv&N)2pdQ?aBkC#1Y>jTjG4&y9c4Hk?BTHXN&GI^c9g^Y* zc1Vf?>mezQVTUAVv4_hIXN^g57&|D8qw66l4rGUNTq*67AmhKI{Sylc!`vY5ilHB8~<8m8zW zHlqPSwbF`AuO*eeX@}@Fb%Y^l?4E_ew}%aD~aOxrW1Eh$1ZJmrWp z=f^x4%i6S!`SFwkI|ub6oN1ZpIX$Q!<;?YC+KzmimWg5KkTcbf?>embxY!Ilp>Idn zbydk{?`n-PY)9Dr&uKeiB@8xnnmpR@gn_Yoh+(;FL&Mu~xtmE=&nN1QLZRhzPBIov z;!~lq#-w4n8?0fun@PtW4$EC;&29`HY6WUR_2q8fQ9e#`78le~I4pNV;jmPTq+z)m zNyBnCl7^*PBn`{mNE()Eku)rKBWYNwS(82}Lv6c~G%RT!(SnmGw~qPm&<(6pUh3lzSHz@K=J|AezIpTR^Yw@i7+mZ?&zOx;z#xH4^@^iIJ`L$Z+ z%9l1m2iLD?nMU`Pnd#B$EX^7)A=EOZu(D-}t<^I1m$ytwkCrK5K4i-rKxu3PDlKzD zRagsXH-q)KT4p?X%e*NqQ&O=7*<-dnd)lqd9(T(WRnRi+31z8e3Kd$W90#seCBIgy zQY;&f2}HN%(yPO=hiFOiup5s&WaCk()p(2`s-*GQPir#qOPY-Rv=$}5R^yRhtMT|R zZ80Y2eVP6A7IXc0b$^?vkf0OWjA%TY7|8kRy%{RX0@vw2rowgtwf#jSxY9!xt!K7qlELy79t7#*Mr0w_I9Bhzvhx2uepHvkgxdw%9}f&@|sVm3hQgLU-R{NfBWWM2B3KI*ZlgP z2Ovqs*W4cSHMghz>e}Oe%|#Ww=JtfL^qLD5UUQl4uSO-mR-;lZUvm?PR^`&Gx!6NA zBzf3vM;^3lt?jAQYCA^o*W7+u+lXJ%HteUhBKfsmbNRJeiT~18VsidM+fQ$9U-oOB zqS0tJgAi&)i@&^fW!fVNzNd!quyJ$9+PBUPWxW`M81JKE_-4u@l&-h$WmF%sK>cB> zkMi^vC>gt;<1NZ8x^B@x2xnSkqIO)|vYbqHUVV}w+zfn>7I*Xvc#1~)k z&6HpHW=a{ZH&cK4nW(t@O`DPBFylew1Z{~!mFu$4WalM)GM+h&RT%@kGeX4(_V(wiw%cr#_*`*41`dXkx`oYuZOpJfJpvwvmk!{gQM)2FE7 z-)~Rv95P;-9w zPTD}q_~Yeo&!=B59CrSKO#{c8!@m( zd{>z7CaQzXJ-t68RUR8NFeaWqAy0aln#l!K7S!b3yR*Elo#z-6WzvN9bPiRCfmI@9 zPm>wZC%^@eG02A*S;h;QQUajRU~OdFSR=lo zuflxoHUnhtua8uZ^4OSx72?ZVwE64H+fH0qA;S27cROTqL6t=f_19BxsDV`?XRr?$ z;)7?p5nm{Wr}r;CivdRV(UA9`sd)VW0hEJP9}%RmF^0lMO}v0A_|Nx@~lh`4?1yt#YB=#%JW2Z zuo`_JZ)N@4yj@r&(ugoj1tka5i12!TWTrfKn*oy1JDx`BV`U~*i8zfEp*D?7jET4C z>s_B;1yotsg@{b+K@zJ(Y;_{kT3up=h_CZqpO^(yS?uSh!Ow+NBKz5AbYgILJMQit zKR|oa$5w-ZvBmova#bE1F|b0UIpkf;7oks1jERruTXa<(o5jGGC<7r9V_ZawfiY3K zcqB%TkHo;3D4idbjy^YM6RcdCg4~@y^*P7}i7OXyaCxqe)oNl)h!bWZwz=fSkob6Y{RG2~Jr;`_E5sLA6o}AET@-ALi65@-cj3q;>-BxJ7#I_u z?%-X1ypqR846G1w{UXG+e%V+dzMjz4r`J=rxG*NZd?2DcHez6v2(x9`dHhgUFB>bw z&s2{upX=;FhzqMk=yg=6b~+nl;^{qXcsyRoW6NV;mAE%!Wh43Y{%#;TR*6(Nr}w>Z z0;@#mI@DtAIyP2_PcS5l&{N%l*jORH-oc7Vq~y8hGQh@#e#f}A;{lMl=WCcF$>Gp- zog;0m5O1k$bswGQkV0HoA)c7n*4si{SRtNaF(E>7hR`f7tPp>rqLrIcowzV2e*6gY z7CFh0Z+NQ3z>xU-a)cC(}rMZ~a1 z)Z0;eo|4y6M!89=-LBFSWyak*=nUm%(7RR$i522K6Xg_+>r0d^tPpYENrc+I)5Z$% zS9pCy=-2xCY^)O5)i(Yr(cLe^6TAf?bgFN`#tM;|mfQp!3TGIbo=+dRI^?mHYG7>f z16PMUcH&qav<)Z@4Al`>vB=f&VW^J4Dv_$A?;na6V|9Gs>X65t$AuM(Cz$ey_S2Vv z=vX0gJw|tc?_pp_e9?2XJvp(*VsT?kq%)3}cm0fGV@#w8|I53W+;3Mm#>De0tchOU z$zyXhutJ34S9o>wO{lV9xL27v+;5DDv{HC^*H;P~t3(*FRj3Zw8zbU-wy2M_WD=`H z*zM#f(bGfZP4{bFu zCgS4s<+(SxfGP`{oXE5$mlzYd0Xz>4AhAY#1Mj~|y=fJaVC7=t5o&8ZiB%#t9uaDd zCov+vaO2U(>T6<5Zks82DZvX*R7B&EpX$>GTCUOIK85%%h zm57xnLah=Lt3<3s5o(o~7!l9xsy^0AOpJ)U#q^TfNic9E#zfi2fHwZxw>4f8VL42gWKB&vZZwZ!BQ#u#v5z$%f7@op%_z?di( zm$BXIJ?83ZU_^W`H~8|d-dUb1Eg)j?cy-RP392wLCerKm(#~+s0aX^}PGnl{601Zk zPZ4U(GBGA{gL#R@ff)>}5V66$^ac}9Wl;vBage#;%=s+ZD1*^BnAm&PvkvZ1@j2Eb zF-8S;6-R(`4E9JHMgWx~Kl}J^BG&lW95-wkd3)6dR*A5vIt#Im#v7|dm^i3Voj7c) z5~)c0#6gKZ&=T?W_8lya&-z&3!o&&@uht52U89BCNURX=VB#ReySi7gu|mWX7!hhG zFdHjG-0~Npw&lOELc}?a2(_)FjTIsuQHoG+0ErbMzQV7)j|!-=@D&!B)=(3xM6QcZ zLtQMa67ii9?X7c5jEMS41HAk8NnaT(5^KcEx0U*~HdZ4$+UQucD%S?o4Ki03w`h4- z?8>Khu>vk!vf3+DKGEwvkAi;t9$u#nRtxb>K`qGCGFreUV;>53x;LY0E~aAaTcAhM zt)}492(?^!*f7Pt)-V%m#Ifk&(~2YM!M&i2rH9R5Txrcev1%}8id=eu9!U@G1!ZuL zXAqxbwtyxBV}ms1)XzF=o0z7Y`}0pS5KXvRIBKn;dVO)yn}bYB@C6*^DB{G_T6vBl zLcO8_V?TM0@;T-sn8U!BNOKhZqNx_)G)M6-pD>FeC0}3-+=W)7`|DJ6(Y1K79y1Qi z9M* zCyMfwTN{59t3;eAicp&JK!J~X1dKP19NR)JB>aZy(8$aZV zj|sb9eR*g_Gqy0(TAEm3gJ%8Uv{rS9kEMi@bn&81(i5x39^POh6K35PwofD->|7di zl-!&5MjM@HPwI7_J#Dnoad{!x^Q8p0KgSxeWcfU0d4Y{vebz5Zdrbw}>Gc)Sk60(E zQR&#zYS#19*qZ-L7;V5ya7Y}Rn}6F|IlaSF-?C?%#GCe4KB~0GQWhJ-Ougz6<8I6L z*oe~r`Kl*yNbGINM7pc*&u~TLRi3K7fXGihegkvEY20gKh4>10Sw!fy-euWXCBjgm zLUr!CF(S&9Uiez|RUc~>6D!2unfUuaTo@D2x3C&}y_3ggF|b1XCw!_Z#DCVg%Ek&2 zzi}0zr-8VzLi`N(KZN+X-v8Jb5qZDxHTMSh`>`=5>IX{DbY6xJmR>i=+(M1dXwYb2 zjR+m)>x)R$4iiA;(zU-=*;lJavKy;Jd?kksIVJY){Z%)pu!MB@;O^N(3}cJj3FO`s zmQQpHg^2eRM0>lhu(3+Sw^EN_x~s#boYxcWSlDAFsz}e{iC<@ZY{bCG)zdA#&idGi z)9ZZVK3N|dF)+5s{lF>Sd8m%W3Xxvt)9^YcR*3XEpN7{tF(z`8I}J@Pu}Z{7E<(L< z0xLvna;KrmC02-(5mAE~x_@S+-!|=qiRfWFZDtiTmv^q4IVBMnnodAb(P< zeKQ7FCGG*;gvx*pSRulBqYBm4HegKTCYNCbpf(a?A~(4VGl0ag$yrnZsE-|GpisRX z7Nb}p5odsSZA6xw%O`DQuzum@BK_@<2m!<^`&LS88`TD~xw_-xB7->$Js?8uvoXN9 zSTOW}2t}9yESSKU2p5lqS1-D5sIvBS%w)=J46sVXH!;Hupq~+rpb)9v>&KgFZ>o2R zD}ePEVFt)tzg%wGioN#Yi^19A{>sSol&_2c;|$`RV-bq`#pr5ag@}XH4l_W+esx$) z;Bs$7ZztPx8->-xy4{+c!}S4l(};JmJQ z1kB|LKo312R>ujzEq-*WLN)XNU~CaX4~S5N89-kHD@5wa`;LRN0!TH6pckk?P}5f|a}1=4PO*%>k=K8WCbqMA=-6r$WTg1FAlv3=lOy;%Zz0 z=q)qM05B7)M4U!um;omG)RKu1df@s_nr&_F0aX@uAtK{FIGPKr60y|@v9-Fy3K3st z*#PW*4zIJwv7a^cfM&Ue9x#;s>@zwc4sQpA9uPedW&lejFwP)`9uQ)L89-uSg-8p5 z3^PE)wK!lRh8_@$5oQ31fiV$74+wD>D-&ZPj{@>3SzDJS#zg7-s3P^bwSWXGm!=>) z$^d3G;}H;-?uB3964hTxI_c zr#<>ui#0L!Q~E=+ICPIf^h_gB1A14H% zdb?aBY7X_TjjHPXx`I?$aqET5^_wuJjfydDy)d!ADEG2oL>AlS2GJcDWl;B0puy+X z3Rq065#iuh1IEh!dhPWPWx8y|z&@XZ*^QfdXgR^c#Y%}S58@4#qH^ARi{$VcY}wk( zN=o$$D?vo-?A${Qx0l-_C*R`DZD#Ni7H20Y{Us19ux3?Pe1*#VzG`*J$-TIHSKSMI zC_GB4JZ$^oUh6^ z2BHa93rFoCwTu?1wGN$>cs7hEf>K2dos^0U7HQUTpG$GfVa!B0gE;H3nDMm;hgpZo z$<>nhcty%yq}Fv2G`Z1gbhty3TBcsZHF=63qqoIHpMF5MWCa&oLy0>G2jp&MC@ zsk$lY$kbtlD;qA=EuVSA$MZ2X11Ar!m?hw)y3orPHvt_T&kIVmlwh|)ovXVQ8*4<^ zA~C7DMFL>wQsWl0^-`VXC(uUcd5U`7=P4VlbXZ8Jk9DQAu|_Oeu9xb}>3*rs;p%f- zpW}ufXfxejk#ebS85z1m&EbM4t>Y^Kx9z^d8Cn_;$HrVP)h(~fr8+=I6LVw64;!!V z<10oe-he1avai2C#k$^M=zympJu`H}>H5CkZ~}}h%J+xRJrhc6;k7p<}Mu@y{U#ZQ{P2(f1{FedW! zB`;f{r{nZRzHP(|uDJ@*7R2Ug)8sy*A24qi(&e5OReg-VNDPcE%HV;H>R3`HTB6&r zO2lzNFPsfT$0`wf*M7rH>N$E`B2u8o>mkr1V1df?29i4Q2^gAwr-j6{>d=0b?Qt zvlO8ST#0!MtP6j$5jRKO~6$D}l&5|a|JN~AnS z{7EdFz$y{ODRs4W;~OhPh)Jn#)lW!34k_YZg_c*M)wZ0T%OH4X~IPfyxJHMDVo~#OGZuui-|Fj z+gnCXL*m%pEP5Jba)_oTeh9T+6MWH7X-JKBiADosZ>h;e=rp7aQ%8-uhD|Obr!lWj z9bY8)7&ZWXtPLPB_ERKbvSNzrYz4r|#l|BB>g-XOefFp*mFm!VRHQdoUW>g9Yq5=y zs~Rc|>M3he_N4$@ z9us3C)qb3R0JoaEgs%!-iDntktq(U`V5MYIf z%YPxRTe`c2Z;Xf2L0y2e;HoLHUyk9LEW zb8-UN9Yf;C-{C$X@zg9j!mjcw*`sl&*46VdkzUCbjl=(zcrRFaPw{v!{xET^6%#Z6 zt5MzN_Tw2W50~%fJ)s{CbdG4VH9X#nzo$Gn+hZko0q8DvFnfhNIO?yxc%glK!t23;K)NDKd1F-rm2YdW_#7Q5& zAc1yzeMRc|pV^LszN&OM|4aGl6@g>C$&=$(1c-AH4vpE*1iPI)=Bv5M1mti~jq4pi zW3xBLL>lLYpcw}5>DIUbnKx#(XU@m>dXHhW9 z=(Vv%gbowpXQ0uHw82~qs&TyoXdpArGAa=kOFMuD6MOg0K{dqU@Ny-_7HL3HqH9Ns zffXWdTkilGL|lP3DiPnx9#li!??E-LIjDv|)~cL>YKSDi&ONAxi?kkJi1a%5pc+c- zK{W*BKDh_gaFM|x_X8O~14=b9Dpie`0ljMm&>&)ukt2S{`%A?BI!{40gvkAQ2GBr@ z(G1yDZgM@ShUp#}xkk)DS6fgGB~DFFBW5tM1l2I2W8^9Y)wmvlY5<1Bk5Bjqzpm}E zwAGC<5&z(q5aW+~?NZ%XBhnxIaY$JBMX1F=*jTa1)e(Q(i(Fk*REbm_ zGPbt{5Lh8{b+kYDrFras@XJuRGNMBD%E-owMXtyA<6e}|W^e9xWb ziXd`t9&jkUvB#3ljUkca65R}Oi2!3F?#7CcetJY3Pk=EI5AZ}t9vd;RM%>>kIkUti zLXf#QIT5K?9PX0c7!zS*RCw!P0%;4XET~DPmCX`UgJG^bS3Ut zv}lj{D-+uUV=Ju|&0`Y9vB! zY6Msz;>b9}B~oIaa5}oLD6Z#Ljnig`$YNX~e{9SlE|E&Uyv2%)7)01m1LJIRF5B=g zn%fLV%|Touf9!ttxI`vN4YkEua1m2h{d~Wdh%QyuhzM3LRfy~f4czU3MTSzsh!iSRBT@jy-eO!L5sDZ@n9slpai2CTulMBB zltZKcU~`qnRwIE`b2mFKkr})xe=!)r#>I)w4nah@jCpM3?zlu|p~NKutP+dOK4!&) zi-{PQNVG=`BJ?$|LZn$)|58$wO|vpZskQ5KtCj?-(S3Gc2FghvV3kNC!Y~!gZ|DjU z;}WU*2th<86d-XaF44_h#vlS_VwH%~$R3x-l(o1-f3*#vnqAF)}bw z`dn&o`rLAvVCB*jWQa>7d6?o7-B=(ZD58u(1P&)gMx`^t-a{X&yNNN8R?6+7q_{K< zTXa#ZVj+PgwM}ZsD6G1SRukDqzctdNWhqgpPz|Pd}_8|#*I}X zOtbf=W=!nUY?1s7^A3A#r79wZ6^oytyHaB9tv1F)JpYwE##t}A8dxRn@79c1zFPyV z5~*m^wh_83B)DosVw+czHap~0(vHor) z$XxthPMmAs%K=u1@V%T0)$ip1D@6EPAS%=rh8rtH_|Q&?^+P+r3K2fEQ=$5y9binv z5A8%KKB~j^6BrVo=@jF}9!p(rjEQ)PA;dVb*cLZN#1kH^-aPALwU`(a@n}_u?PwLS zMx>)v7c57s8*J_z9IXlik5>J$k%yyIm4vfAf9%A5mZy@qb!d;B*pF6~2xocz*oplt z&m>Q~hfzJg;{z3)7#BMpt*V}Sv`IKURlq4Pte~CL_5zY|4o`I9gThLv;jJTs`fhRU?+8Rlo|7 z>v8BJPJtnjzy7`1U;6GmZj6a^I5K?wE6S$B5&PVCm+J8KuMlJPz!vfAUlEEgebLpx z3K5pl`Kd3_`cm3H?L|LhZ-{w)xVO)Jkr>MfBnHNQ;%y(vU|(WvjEHhU6c#nZ*S|L# zt3=o=QlYw8w6RKr$%P8lxy8naNMHZn3}62O#zby!{p(*Lj_u7p?1lQ+ANoRtY>(857`%7Qu4I_?z?u!|e$L42X>?gm8xq*cir%F6yu9 zBvy%75hB#ub7D;7mX_fKF@s}Elc0Z?!QRqD!17$o;VJjIha8klN9(IZ%HYt_ggCS` zoxGu=eF}KaX(3yrF=vNDz>2{lH??WT!Qm046#A5NV{DFJB^fJwn+dEEVX)FD z2X(O8SS7+@MTP2AWn+~H!?+67VSHmme7$`K%W;V>@UAY$H&%#v3s{8OE#Qq6A_Qc( z5up`)0ct<7LWF<}N^FNk8!JQz$e_d;kO8nl#N81gw#}-I6(Y`7M5s4_#0n8#sn_1Q z1yots=Zj2hsEJh~Z2yR#HR`^W%)%-WI}H(Py<%cSq)-(%J1hm%eul4TMELA@QQy|i ze-2gQ(pa=A*G7&FvT0d2!S!knUC|7yQ16yM(`Y46oi}vmD%WO_8!X<1?4`%icdVL=$sg94@`qWZ=>;EV%2;gJFhxz>CYD;58m6IB(Z%0(sF?|T$UP-h9yWh5 z+M0i2jX2h9%vg`42ls+9lpaq#KF2fzOFu9+NK=o`ed-ZVWes@}^3)&_ZaLzVYJpm7 zOk^lSs|8mgRa8u5m^e&sG#Cs_ZZb9u6301;1SCOTpQA(w8TM1;AYP30R|d2)+UP(Z zD#7Kadcc$eGw|LvYY;ESovnWdfY46Icri;&b=Z_t zF$9`fKJzC$UM@oebMiqxD9}vkZEeg{v_LZ;K5EBFx>Qh`q$gI33IffTjT&eM!Oo?| zEoN(=nZ=&EGj;MUc1#8g)inf~F}2hi4$BM4a^DHHxGb>w?$3kObKiV7+3ItIl)-LT z4f{N>mY4=`sge|n$#WL(LKht?AHu>6jH$0x5A*Gra$iz=K6+zrfo4`-vS+NmWddsF zKr=TxsLW<>jEOWr?w~SAoCZh^G$R(H-5@bAvWS6ZZhD}Z4KYg^`fm3-s0^6PGr>ZH zFae^x1)2e@5@GH-1e!6T&u589fo5)oKr?_9B1EQ8p&DogFeYMv2@z_6W&kTh2sEQY zHP8%Tg$R);RHz1;0jv-qGKC7&$P|DPkvAHLKr=TRW1@aG1x@EAKcj-Svq9z-YX1so z3^XII=vO~zRG&+i0numJC|xuh0?ml}>7t=UmO-2G-eNujV~hN94f|C)_)I0jfHDM{ z5m(1fK!U-*)|$qKsWYaH6^nR%M1|^#a$`i)C^Aqu8B_)eCov{spqU$sJ5wt%gU=Kq zz0Mg_1}(-b&P48$d!QNdVys7vB7=Dx`hh9XjHsip>+P}SFu@exfc;V4# zU`)gc=>Z)?)hg-A+RGA?DO+KHF;SLYyX6c49fYW>v+^Pvx?f~}Y}Fy}dM9cG2e8-! zI()I14n*M#Lt!V>c9P z+vJu!zz2u+RO@31=wNc#ax!=W+3Nuvl(@Ip?5Ue;d+H{~=IWlUiww1oALEHo`xp-} zE>aBWAVLwm0W%mF6X902@aiq#4OP~jIhstFI09CQ_$Ky%4n`c_L=5PlGXBnC_If}E zliP!oKeh^#m=8lmJVHPRBTfdV7yl8yYcgU9=l~d(3|`0

    `n~utLOPaR+a}vWdIa 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 literal 0 HcmV?d00001 diff --git a/venv/Lib/site-packages/numpy/LICENSE.txt b/venv/Lib/site-packages/numpy/LICENSE.txt new file mode 100644 index 0000000..04619f5 --- /dev/null +++ b/venv/Lib/site-packages/numpy/LICENSE.txt @@ -0,0 +1,938 @@ + +---- + +This binary distribution of NumPy also bundles the following software: + + +Name: OpenBLAS +Files: extra-dll\libopenb*.dll +Description: bundled as a dynamically linked library +Availability: https://github.com/xianyi/OpenBLAS/ +License: 3-clause BSD + Copyright (c) 2011-2014, The OpenBLAS Project + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + 3. Neither the name of the OpenBLAS project nor the names of + its contributors may be used to endorse or promote products + derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +Name: LAPACK +Files: extra-dll\libopenb*.dll +Description: bundled in OpenBLAS +Availability: https://github.com/xianyi/OpenBLAS/ +License 3-clause BSD + Copyright (c) 1992-2013 The University of Tennessee and The University + of Tennessee Research Foundation. All rights + reserved. + Copyright (c) 2000-2013 The University of California Berkeley. All + rights reserved. + Copyright (c) 2006-2013 The University of Colorado Denver. All rights + reserved. + + $COPYRIGHT$ + + Additional copyrights may follow + + $HEADER$ + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer listed + in this license in the documentation and/or other materials + provided with the distribution. + + - Neither the name of the copyright holders nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + The copyright holders provide no reassurances that the source code + provided does not infringe any patent, copyright, or any other + intellectual property rights of third parties. The copyright holders + disclaim any liability to any recipient for claims brought against + recipient by any third party for infringement of that parties + intellectual property rights. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +Name: GCC runtime library +Files: extra-dll\*.dll +Description: statically linked, in DLL files compiled with gfortran only +Availability: https://gcc.gnu.org/viewcvs/gcc/ +License: GPLv3 + runtime exception + Copyright (C) 2002-2017 Free Software Foundation, Inc. + + Libgfortran is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + Libgfortran is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + Under Section 7 of GPL version 3, you are granted additional + permissions described in the GCC Runtime Library Exception, version + 3.1, as published by the Free Software Foundation. + + You should have received a copy of the GNU General Public License and + a copy of the GCC Runtime Library Exception along with this program; + see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + . + + +Name: Microsoft Visual C++ Runtime Files +Files: extra-dll\msvcp140.dll +License: MSVC + https://www.visualstudio.com/license-terms/distributable-code-microsoft-visual-studio-2015-rc-microsoft-visual-studio-2015-sdk-rc-includes-utilities-buildserver-files/#visual-c-runtime + + Subject to the License Terms for the software, you may copy and + distribute with your program any of the files within the followng + folder and its subfolders except as noted below. You may not modify + these files. + + C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\redist + + You may not distribute the contents of the following folders: + + C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\redist\debug_nonredist + C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\redist\onecore\debug_nonredist + + Subject to the License Terms for the software, you may copy and + distribute the following files with your program in your program’s + application local folder or by deploying them into the Global + Assembly Cache (GAC): + + VC\atlmfc\lib\mfcmifc80.dll + VC\atlmfc\lib\amd64\mfcmifc80.dll + + +Name: Microsoft Visual C++ Runtime Files +Files: extra-dll\msvc*90.dll, extra-dll\Microsoft.VC90.CRT.manifest +License: MSVC + For your convenience, we have provided the following folders for + use when redistributing VC++ runtime files. Subject to the license + terms for the software, you may redistribute the folder + (unmodified) in the application local folder as a sub-folder with + no change to the folder name. You may also redistribute all the + files (*.dll and *.manifest) within a folder, listed below the + folder for your convenience, as an entire set. + + \VC\redist\x86\Microsoft.VC90.ATL\ + atl90.dll + Microsoft.VC90.ATL.manifest + \VC\redist\ia64\Microsoft.VC90.ATL\ + atl90.dll + Microsoft.VC90.ATL.manifest + \VC\redist\amd64\Microsoft.VC90.ATL\ + atl90.dll + Microsoft.VC90.ATL.manifest + \VC\redist\x86\Microsoft.VC90.CRT\ + msvcm90.dll + msvcp90.dll + msvcr90.dll + Microsoft.VC90.CRT.manifest + \VC\redist\ia64\Microsoft.VC90.CRT\ + msvcm90.dll + msvcp90.dll + msvcr90.dll + Microsoft.VC90.CRT.manifest + +---- + +Full text of license texts referred to above follows (that they are +listed below does not necessarily imply the conditions apply to the +present binary release): + +---- + +GCC RUNTIME LIBRARY EXCEPTION + +Version 3.1, 31 March 2009 + +Copyright (C) 2009 Free Software Foundation, Inc. + +Everyone is permitted to copy and distribute verbatim copies of this +license document, but changing it is not allowed. + +This GCC Runtime Library Exception ("Exception") is an additional +permission under section 7 of the GNU General Public License, version +3 ("GPLv3"). It applies to a given file (the "Runtime Library") that +bears a notice placed by the copyright holder of the file stating that +the file is governed by GPLv3 along with this Exception. + +When you use GCC to compile a program, GCC may combine portions of +certain GCC header files and runtime libraries with the compiled +program. The purpose of this Exception is to allow compilation of +non-GPL (including proprietary) programs to use, in this way, the +header files and runtime libraries covered by this Exception. + +0. Definitions. + +A file is an "Independent Module" if it either requires the Runtime +Library for execution after a Compilation Process, or makes use of an +interface provided by the Runtime Library, but is not otherwise based +on the Runtime Library. + +"GCC" means a version of the GNU Compiler Collection, with or without +modifications, governed by version 3 (or a specified later version) of +the GNU General Public License (GPL) with the option of using any +subsequent versions published by the FSF. + +"GPL-compatible Software" is software whose conditions of propagation, +modification and use would permit combination with GCC in accord with +the license of GCC. + +"Target Code" refers to output from any compiler for a real or virtual +target processor architecture, in executable form or suitable for +input to an assembler, loader, linker and/or execution +phase. Notwithstanding that, Target Code does not include data in any +format that is used as a compiler intermediate representation, or used +for producing a compiler intermediate representation. + +The "Compilation Process" transforms code entirely represented in +non-intermediate languages designed for human-written code, and/or in +Java Virtual Machine byte code, into Target Code. Thus, for example, +use of source code generators and preprocessors need not be considered +part of the Compilation Process, since the Compilation Process can be +understood as starting with the output of the generators or +preprocessors. + +A Compilation Process is "Eligible" if it is done using GCC, alone or +with other GPL-compatible software, or if it is done without using any +work based on GCC. For example, using non-GPL-compatible Software to +optimize any GCC intermediate representations would not qualify as an +Eligible Compilation Process. + +1. Grant of Additional Permission. + +You have permission to propagate a work of Target Code formed by +combining the Runtime Library with Independent Modules, even if such +propagation would otherwise violate the terms of GPLv3, provided that +all Target Code was generated by Eligible Compilation Processes. You +may then convey such a combination under terms of your choice, +consistent with the licensing of the Independent Modules. + +2. No Weakening of GCC Copyleft. + +The availability of this Exception does not imply any general +presumption that third-party software is unaffected by the copyleft +requirements of the license of GCC. + +---- + + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/venv/Lib/site-packages/numpy/__config__.py b/venv/Lib/site-packages/numpy/__config__.py new file mode 100644 index 0000000..2b2ee70 --- /dev/null +++ b/venv/Lib/site-packages/numpy/__config__.py @@ -0,0 +1,78 @@ +# This file is generated by numpy's setup.py +# It contains system_info results at the time of building this package. +__all__ = ["get_info","show"] + + +import os +import sys + +extra_dll_dir = os.path.join(os.path.dirname(__file__), '.libs') + +if sys.platform == 'win32' and os.path.isdir(extra_dll_dir): + if sys.version_info >= (3, 8): + os.add_dll_directory(extra_dll_dir) + else: + os.environ.setdefault('PATH', '') + os.environ['PATH'] += os.pathsep + extra_dll_dir + +blas_mkl_info={} +blis_info={} +openblas_info={'library_dirs': ['D:\\a\\1\\s\\numpy\\build\\openblas_info'], 'libraries': ['openblas_info'], 'language': 'f77', 'define_macros': [('HAVE_CBLAS', None)]} +blas_opt_info={'library_dirs': ['D:\\a\\1\\s\\numpy\\build\\openblas_info'], 'libraries': ['openblas_info'], 'language': 'f77', 'define_macros': [('HAVE_CBLAS', None)]} +lapack_mkl_info={} +openblas_lapack_info={'library_dirs': ['D:\\a\\1\\s\\numpy\\build\\openblas_lapack_info'], 'libraries': ['openblas_lapack_info'], 'language': 'f77', 'define_macros': [('HAVE_CBLAS', None)]} +lapack_opt_info={'library_dirs': ['D:\\a\\1\\s\\numpy\\build\\openblas_lapack_info'], 'libraries': ['openblas_lapack_info'], 'language': 'f77', 'define_macros': [('HAVE_CBLAS', None)]} + +def get_info(name): + g = globals() + return g.get(name, g.get(name + "_info", {})) + +def show(): + """ + Show libraries in the system on which NumPy was built. + + Print information about various resources (libraries, library + directories, include directories, etc.) in the system on which + NumPy was built. + + See Also + -------- + get_include : Returns the directory containing NumPy C + header files. + + Notes + ----- + Classes specifying the information to be printed are defined + in the `numpy.distutils.system_info` module. + + Information may include: + + * ``language``: language used to write the libraries (mostly + C or f77) + * ``libraries``: names of libraries found in the system + * ``library_dirs``: directories containing the libraries + * ``include_dirs``: directories containing library header files + * ``src_dirs``: directories containing library source files + * ``define_macros``: preprocessor macros used by + ``distutils.setup`` + + Examples + -------- + >>> import numpy as np + >>> np.show_config() + blas_opt_info: + language = c + define_macros = [('HAVE_CBLAS', None)] + libraries = ['openblas', 'openblas'] + library_dirs = ['/usr/local/lib'] + """ + for name,info_dict in globals().items(): + if name[0] == "_" or type(info_dict) is not type({}): continue + print(name + ":") + if not info_dict: + print(" NOT AVAILABLE") + for k,v in info_dict.items(): + v = str(v) + if k == "sources" and len(v) > 200: + v = v[:60] + " ...\n... " + v[-60:] + print(" %s = %s" % (k,v)) diff --git a/venv/Lib/site-packages/numpy/__init__.cython-30.pxd b/venv/Lib/site-packages/numpy/__init__.cython-30.pxd new file mode 100644 index 0000000..a2c451b --- /dev/null +++ b/venv/Lib/site-packages/numpy/__init__.cython-30.pxd @@ -0,0 +1,1055 @@ +# NumPy static imports for Cython >= 3.0 +# +# If any of the PyArray_* functions are called, import_array must be +# called first. This is done automatically by Cython 3.0+ if a call +# is not detected inside of the module. +# +# Author: Dag Sverre Seljebotn +# + +from cpython.ref cimport Py_INCREF +from cpython.object cimport PyObject, PyTypeObject, PyObject_TypeCheck +cimport libc.stdio as stdio + + +cdef extern from *: + # Leave a marker that the NumPy declarations came from NumPy itself and not from Cython. + # See https://github.com/cython/cython/issues/3573 + """ + /* Using NumPy API declarations from "numpy/__init__.cython-30.pxd" */ + """ + + +cdef extern from "Python.h": + ctypedef Py_ssize_t Py_intptr_t + +cdef extern from "numpy/arrayobject.h": + ctypedef Py_intptr_t npy_intp + ctypedef size_t npy_uintp + + cdef enum NPY_TYPES: + NPY_BOOL + NPY_BYTE + NPY_UBYTE + NPY_SHORT + NPY_USHORT + NPY_INT + NPY_UINT + NPY_LONG + NPY_ULONG + NPY_LONGLONG + NPY_ULONGLONG + NPY_FLOAT + NPY_DOUBLE + NPY_LONGDOUBLE + NPY_CFLOAT + NPY_CDOUBLE + NPY_CLONGDOUBLE + NPY_OBJECT + NPY_STRING + NPY_UNICODE + NPY_VOID + NPY_DATETIME + NPY_TIMEDELTA + NPY_NTYPES + NPY_NOTYPE + + NPY_INT8 + NPY_INT16 + NPY_INT32 + NPY_INT64 + NPY_INT128 + NPY_INT256 + NPY_UINT8 + NPY_UINT16 + NPY_UINT32 + NPY_UINT64 + NPY_UINT128 + NPY_UINT256 + NPY_FLOAT16 + NPY_FLOAT32 + NPY_FLOAT64 + NPY_FLOAT80 + NPY_FLOAT96 + NPY_FLOAT128 + NPY_FLOAT256 + NPY_COMPLEX32 + NPY_COMPLEX64 + NPY_COMPLEX128 + NPY_COMPLEX160 + NPY_COMPLEX192 + NPY_COMPLEX256 + NPY_COMPLEX512 + + NPY_INTP + + ctypedef enum NPY_ORDER: + NPY_ANYORDER + NPY_CORDER + NPY_FORTRANORDER + NPY_KEEPORDER + + ctypedef enum NPY_CASTING: + NPY_NO_CASTING + NPY_EQUIV_CASTING + NPY_SAFE_CASTING + NPY_SAME_KIND_CASTING + NPY_UNSAFE_CASTING + + ctypedef enum NPY_CLIPMODE: + NPY_CLIP + NPY_WRAP + NPY_RAISE + + ctypedef enum NPY_SCALARKIND: + NPY_NOSCALAR, + NPY_BOOL_SCALAR, + NPY_INTPOS_SCALAR, + NPY_INTNEG_SCALAR, + NPY_FLOAT_SCALAR, + NPY_COMPLEX_SCALAR, + NPY_OBJECT_SCALAR + + ctypedef enum NPY_SORTKIND: + NPY_QUICKSORT + NPY_HEAPSORT + NPY_MERGESORT + + ctypedef enum NPY_SEARCHSIDE: + NPY_SEARCHLEFT + NPY_SEARCHRIGHT + + enum: + # DEPRECATED since NumPy 1.7 ! Do not use in new code! + NPY_C_CONTIGUOUS + NPY_F_CONTIGUOUS + NPY_CONTIGUOUS + NPY_FORTRAN + NPY_OWNDATA + NPY_FORCECAST + NPY_ENSURECOPY + NPY_ENSUREARRAY + NPY_ELEMENTSTRIDES + NPY_ALIGNED + NPY_NOTSWAPPED + NPY_WRITEABLE + NPY_UPDATEIFCOPY + NPY_ARR_HAS_DESCR + + NPY_BEHAVED + NPY_BEHAVED_NS + NPY_CARRAY + NPY_CARRAY_RO + NPY_FARRAY + NPY_FARRAY_RO + NPY_DEFAULT + + NPY_IN_ARRAY + NPY_OUT_ARRAY + NPY_INOUT_ARRAY + NPY_IN_FARRAY + NPY_OUT_FARRAY + NPY_INOUT_FARRAY + + NPY_UPDATE_ALL + + enum: + # Added in NumPy 1.7 to replace the deprecated enums above. + NPY_ARRAY_C_CONTIGUOUS + NPY_ARRAY_F_CONTIGUOUS + NPY_ARRAY_OWNDATA + NPY_ARRAY_FORCECAST + NPY_ARRAY_ENSURECOPY + NPY_ARRAY_ENSUREARRAY + NPY_ARRAY_ELEMENTSTRIDES + NPY_ARRAY_ALIGNED + NPY_ARRAY_NOTSWAPPED + NPY_ARRAY_WRITEABLE + NPY_ARRAY_UPDATEIFCOPY + + NPY_ARRAY_BEHAVED + NPY_ARRAY_BEHAVED_NS + NPY_ARRAY_CARRAY + NPY_ARRAY_CARRAY_RO + NPY_ARRAY_FARRAY + NPY_ARRAY_FARRAY_RO + NPY_ARRAY_DEFAULT + + NPY_ARRAY_IN_ARRAY + NPY_ARRAY_OUT_ARRAY + NPY_ARRAY_INOUT_ARRAY + NPY_ARRAY_IN_FARRAY + NPY_ARRAY_OUT_FARRAY + NPY_ARRAY_INOUT_FARRAY + + NPY_ARRAY_UPDATE_ALL + + cdef enum: + NPY_MAXDIMS + + npy_intp NPY_MAX_ELSIZE + + ctypedef void (*PyArray_VectorUnaryFunc)(void *, void *, npy_intp, void *, void *) + + ctypedef struct PyArray_ArrayDescr: + # shape is a tuple, but Cython doesn't support "tuple shape" + # inside a non-PyObject declaration, so we have to declare it + # as just a PyObject*. + PyObject* shape + + ctypedef struct PyArray_Descr: + pass + + ctypedef class numpy.dtype [object PyArray_Descr, check_size ignore]: + # Use PyDataType_* macros when possible, however there are no macros + # for accessing some of the fields, so some are defined. + cdef PyTypeObject* typeobj + cdef char kind + cdef char type + # Numpy sometimes mutates this without warning (e.g. it'll + # sometimes change "|" to "<" in shared dtype objects on + # little-endian machines). If this matters to you, use + # PyArray_IsNativeByteOrder(dtype.byteorder) instead of + # directly accessing this field. + cdef char byteorder + cdef char flags + cdef int type_num + cdef int itemsize "elsize" + cdef int alignment + cdef object fields + cdef tuple names + # Use PyDataType_HASSUBARRAY to test whether this field is + # valid (the pointer can be NULL). Most users should access + # this field via the inline helper method PyDataType_SHAPE. + cdef PyArray_ArrayDescr* subarray + + ctypedef class numpy.flatiter [object PyArrayIterObject, check_size ignore]: + # Use through macros + pass + + ctypedef class numpy.broadcast [object PyArrayMultiIterObject, check_size ignore]: + # Use through macros + pass + + ctypedef struct PyArrayObject: + # For use in situations where ndarray can't replace PyArrayObject*, + # like PyArrayObject**. + pass + + ctypedef class numpy.ndarray [object PyArrayObject, check_size ignore]: + cdef __cythonbufferdefaults__ = {"mode": "strided"} + + # NOTE: no field declarations since direct access is deprecated since NumPy 1.7 + # Instead, we use properties that map to the corresponding C-API functions. + + @property + cdef inline PyObject* base(self) nogil: + """Returns a borrowed reference to the object owning the data/memory. + """ + return PyArray_BASE(self) + + @property + cdef inline dtype descr(self): + """Returns an owned reference to the dtype of the array. + """ + return PyArray_DESCR(self) + + @property + cdef inline int ndim(self) nogil: + """Returns the number of dimensions in the array. + """ + return PyArray_NDIM(self) + + @property + cdef inline npy_intp *shape(self) nogil: + """Returns a pointer to the dimensions/shape of the array. + The number of elements matches the number of dimensions of the array (ndim). + Can return NULL for 0-dimensional arrays. + """ + return PyArray_DIMS(self) + + @property + cdef inline npy_intp *strides(self) nogil: + """Returns a pointer to the strides of the array. + The number of elements matches the number of dimensions of the array (ndim). + """ + return PyArray_STRIDES(self) + + @property + cdef inline npy_intp size(self) nogil: + """Returns the total size (in number of elements) of the array. + """ + return PyArray_SIZE(self) + + @property + cdef inline char* data(self) nogil: + """The pointer to the data buffer as a char*. + This is provided for legacy reasons to avoid direct struct field access. + For new code that needs this access, you probably want to cast the result + of `PyArray_DATA()` instead, which returns a 'void*'. + """ + return PyArray_BYTES(self) + + ctypedef unsigned char npy_bool + + ctypedef signed char npy_byte + ctypedef signed short npy_short + ctypedef signed int npy_int + ctypedef signed long npy_long + ctypedef signed long long npy_longlong + + ctypedef unsigned char npy_ubyte + ctypedef unsigned short npy_ushort + ctypedef unsigned int npy_uint + ctypedef unsigned long npy_ulong + ctypedef unsigned long long npy_ulonglong + + ctypedef float npy_float + ctypedef double npy_double + ctypedef long double npy_longdouble + + ctypedef signed char npy_int8 + ctypedef signed short npy_int16 + ctypedef signed int npy_int32 + ctypedef signed long long npy_int64 + ctypedef signed long long npy_int96 + ctypedef signed long long npy_int128 + + ctypedef unsigned char npy_uint8 + ctypedef unsigned short npy_uint16 + ctypedef unsigned int npy_uint32 + ctypedef unsigned long long npy_uint64 + ctypedef unsigned long long npy_uint96 + ctypedef unsigned long long npy_uint128 + + ctypedef float npy_float32 + ctypedef double npy_float64 + ctypedef long double npy_float80 + ctypedef long double npy_float96 + ctypedef long double npy_float128 + + ctypedef struct npy_cfloat: + float real + float imag + + ctypedef struct npy_cdouble: + double real + double imag + + ctypedef struct npy_clongdouble: + long double real + long double imag + + ctypedef struct npy_complex64: + float real + float imag + + ctypedef struct npy_complex128: + double real + double imag + + ctypedef struct npy_complex160: + long double real + long double imag + + ctypedef struct npy_complex192: + long double real + long double imag + + ctypedef struct npy_complex256: + long double real + long double imag + + ctypedef struct PyArray_Dims: + npy_intp *ptr + int len + + int _import_array() except -1 + # A second definition so _import_array isn't marked as used when we use it here. + # Do not use - subject to change any time. + int __pyx_import_array "_import_array"() except -1 + + # + # Macros from ndarrayobject.h + # + bint PyArray_CHKFLAGS(ndarray m, int flags) nogil + bint PyArray_IS_C_CONTIGUOUS(ndarray arr) nogil + bint PyArray_IS_F_CONTIGUOUS(ndarray arr) nogil + bint PyArray_ISCONTIGUOUS(ndarray m) nogil + bint PyArray_ISWRITEABLE(ndarray m) nogil + bint PyArray_ISALIGNED(ndarray m) nogil + + int PyArray_NDIM(ndarray) nogil + bint PyArray_ISONESEGMENT(ndarray) nogil + bint PyArray_ISFORTRAN(ndarray) nogil + int PyArray_FORTRANIF(ndarray) nogil + + void* PyArray_DATA(ndarray) nogil + char* PyArray_BYTES(ndarray) nogil + + npy_intp* PyArray_DIMS(ndarray) nogil + npy_intp* PyArray_STRIDES(ndarray) nogil + npy_intp PyArray_DIM(ndarray, size_t) nogil + npy_intp PyArray_STRIDE(ndarray, size_t) nogil + + PyObject *PyArray_BASE(ndarray) nogil # returns borrowed reference! + PyArray_Descr *PyArray_DESCR(ndarray) nogil # returns borrowed reference to dtype! + PyArray_Descr *PyArray_DTYPE(ndarray) nogil # returns borrowed reference to dtype! NP 1.7+ alias for descr. + int PyArray_FLAGS(ndarray) nogil + void PyArray_CLEARFLAGS(ndarray, int flags) nogil # Added in NumPy 1.7 + void PyArray_ENABLEFLAGS(ndarray, int flags) nogil # Added in NumPy 1.7 + npy_intp PyArray_ITEMSIZE(ndarray) nogil + int PyArray_TYPE(ndarray arr) nogil + + object PyArray_GETITEM(ndarray arr, void *itemptr) + int PyArray_SETITEM(ndarray arr, void *itemptr, object obj) + + bint PyTypeNum_ISBOOL(int) nogil + bint PyTypeNum_ISUNSIGNED(int) nogil + bint PyTypeNum_ISSIGNED(int) nogil + bint PyTypeNum_ISINTEGER(int) nogil + bint PyTypeNum_ISFLOAT(int) nogil + bint PyTypeNum_ISNUMBER(int) nogil + bint PyTypeNum_ISSTRING(int) nogil + bint PyTypeNum_ISCOMPLEX(int) nogil + bint PyTypeNum_ISPYTHON(int) nogil + bint PyTypeNum_ISFLEXIBLE(int) nogil + bint PyTypeNum_ISUSERDEF(int) nogil + bint PyTypeNum_ISEXTENDED(int) nogil + bint PyTypeNum_ISOBJECT(int) nogil + + bint PyDataType_ISBOOL(dtype) nogil + bint PyDataType_ISUNSIGNED(dtype) nogil + bint PyDataType_ISSIGNED(dtype) nogil + bint PyDataType_ISINTEGER(dtype) nogil + bint PyDataType_ISFLOAT(dtype) nogil + bint PyDataType_ISNUMBER(dtype) nogil + bint PyDataType_ISSTRING(dtype) nogil + bint PyDataType_ISCOMPLEX(dtype) nogil + bint PyDataType_ISPYTHON(dtype) nogil + bint PyDataType_ISFLEXIBLE(dtype) nogil + bint PyDataType_ISUSERDEF(dtype) nogil + bint PyDataType_ISEXTENDED(dtype) nogil + bint PyDataType_ISOBJECT(dtype) nogil + bint PyDataType_HASFIELDS(dtype) nogil + bint PyDataType_HASSUBARRAY(dtype) nogil + + bint PyArray_ISBOOL(ndarray) nogil + bint PyArray_ISUNSIGNED(ndarray) nogil + bint PyArray_ISSIGNED(ndarray) nogil + bint PyArray_ISINTEGER(ndarray) nogil + bint PyArray_ISFLOAT(ndarray) nogil + bint PyArray_ISNUMBER(ndarray) nogil + bint PyArray_ISSTRING(ndarray) nogil + bint PyArray_ISCOMPLEX(ndarray) nogil + bint PyArray_ISPYTHON(ndarray) nogil + bint PyArray_ISFLEXIBLE(ndarray) nogil + bint PyArray_ISUSERDEF(ndarray) nogil + bint PyArray_ISEXTENDED(ndarray) nogil + bint PyArray_ISOBJECT(ndarray) nogil + bint PyArray_HASFIELDS(ndarray) nogil + + bint PyArray_ISVARIABLE(ndarray) nogil + + bint PyArray_SAFEALIGNEDCOPY(ndarray) nogil + bint PyArray_ISNBO(char) nogil # works on ndarray.byteorder + bint PyArray_IsNativeByteOrder(char) nogil # works on ndarray.byteorder + bint PyArray_ISNOTSWAPPED(ndarray) nogil + bint PyArray_ISBYTESWAPPED(ndarray) nogil + + bint PyArray_FLAGSWAP(ndarray, int) nogil + + bint PyArray_ISCARRAY(ndarray) nogil + bint PyArray_ISCARRAY_RO(ndarray) nogil + bint PyArray_ISFARRAY(ndarray) nogil + bint PyArray_ISFARRAY_RO(ndarray) nogil + bint PyArray_ISBEHAVED(ndarray) nogil + bint PyArray_ISBEHAVED_RO(ndarray) nogil + + + bint PyDataType_ISNOTSWAPPED(dtype) nogil + bint PyDataType_ISBYTESWAPPED(dtype) nogil + + bint PyArray_DescrCheck(object) + + bint PyArray_Check(object) + bint PyArray_CheckExact(object) + + # Cannot be supported due to out arg: + # bint PyArray_HasArrayInterfaceType(object, dtype, object, object&) + # bint PyArray_HasArrayInterface(op, out) + + + bint PyArray_IsZeroDim(object) + # Cannot be supported due to ## ## in macro: + # bint PyArray_IsScalar(object, verbatim work) + bint PyArray_CheckScalar(object) + bint PyArray_IsPythonNumber(object) + bint PyArray_IsPythonScalar(object) + bint PyArray_IsAnyScalar(object) + bint PyArray_CheckAnyScalar(object) + + ndarray PyArray_GETCONTIGUOUS(ndarray) + bint PyArray_SAMESHAPE(ndarray, ndarray) nogil + npy_intp PyArray_SIZE(ndarray) nogil + npy_intp PyArray_NBYTES(ndarray) nogil + + object PyArray_FROM_O(object) + object PyArray_FROM_OF(object m, int flags) + object PyArray_FROM_OT(object m, int type) + object PyArray_FROM_OTF(object m, int type, int flags) + object PyArray_FROMANY(object m, int type, int min, int max, int flags) + object PyArray_ZEROS(int nd, npy_intp* dims, int type, int fortran) + object PyArray_EMPTY(int nd, npy_intp* dims, int type, int fortran) + void PyArray_FILLWBYTE(object, int val) + npy_intp PyArray_REFCOUNT(object) + object PyArray_ContiguousFromAny(op, int, int min_depth, int max_depth) + unsigned char PyArray_EquivArrTypes(ndarray a1, ndarray a2) + bint PyArray_EquivByteorders(int b1, int b2) nogil + object PyArray_SimpleNew(int nd, npy_intp* dims, int typenum) + object PyArray_SimpleNewFromData(int nd, npy_intp* dims, int typenum, void* data) + #object PyArray_SimpleNewFromDescr(int nd, npy_intp* dims, dtype descr) + object PyArray_ToScalar(void* data, ndarray arr) + + void* PyArray_GETPTR1(ndarray m, npy_intp i) nogil + void* PyArray_GETPTR2(ndarray m, npy_intp i, npy_intp j) nogil + void* PyArray_GETPTR3(ndarray m, npy_intp i, npy_intp j, npy_intp k) nogil + void* PyArray_GETPTR4(ndarray m, npy_intp i, npy_intp j, npy_intp k, npy_intp l) nogil + + void PyArray_XDECREF_ERR(ndarray) + # Cannot be supported due to out arg + # void PyArray_DESCR_REPLACE(descr) + + + object PyArray_Copy(ndarray) + object PyArray_FromObject(object op, int type, int min_depth, int max_depth) + object PyArray_ContiguousFromObject(object op, int type, int min_depth, int max_depth) + object PyArray_CopyFromObject(object op, int type, int min_depth, int max_depth) + + object PyArray_Cast(ndarray mp, int type_num) + object PyArray_Take(ndarray ap, object items, int axis) + object PyArray_Put(ndarray ap, object items, object values) + + void PyArray_ITER_RESET(flatiter it) nogil + void PyArray_ITER_NEXT(flatiter it) nogil + void PyArray_ITER_GOTO(flatiter it, npy_intp* destination) nogil + void PyArray_ITER_GOTO1D(flatiter it, npy_intp ind) nogil + void* PyArray_ITER_DATA(flatiter it) nogil + bint PyArray_ITER_NOTDONE(flatiter it) nogil + + void PyArray_MultiIter_RESET(broadcast multi) nogil + void PyArray_MultiIter_NEXT(broadcast multi) nogil + void PyArray_MultiIter_GOTO(broadcast multi, npy_intp dest) nogil + void PyArray_MultiIter_GOTO1D(broadcast multi, npy_intp ind) nogil + void* PyArray_MultiIter_DATA(broadcast multi, npy_intp i) nogil + void PyArray_MultiIter_NEXTi(broadcast multi, npy_intp i) nogil + bint PyArray_MultiIter_NOTDONE(broadcast multi) nogil + + # Functions from __multiarray_api.h + + # Functions taking dtype and returning object/ndarray are disabled + # for now as they steal dtype references. I'm conservative and disable + # more than is probably needed until it can be checked further. + int PyArray_SetNumericOps (object) + object PyArray_GetNumericOps () + int PyArray_INCREF (ndarray) + int PyArray_XDECREF (ndarray) + void PyArray_SetStringFunction (object, int) + dtype PyArray_DescrFromType (int) + object PyArray_TypeObjectFromType (int) + char * PyArray_Zero (ndarray) + char * PyArray_One (ndarray) + #object PyArray_CastToType (ndarray, dtype, int) + int PyArray_CastTo (ndarray, ndarray) + int PyArray_CastAnyTo (ndarray, ndarray) + int PyArray_CanCastSafely (int, int) + npy_bool PyArray_CanCastTo (dtype, dtype) + int PyArray_ObjectType (object, int) + dtype PyArray_DescrFromObject (object, dtype) + #ndarray* PyArray_ConvertToCommonType (object, int *) + dtype PyArray_DescrFromScalar (object) + dtype PyArray_DescrFromTypeObject (object) + npy_intp PyArray_Size (object) + #object PyArray_Scalar (void *, dtype, object) + #object PyArray_FromScalar (object, dtype) + void PyArray_ScalarAsCtype (object, void *) + #int PyArray_CastScalarToCtype (object, void *, dtype) + #int PyArray_CastScalarDirect (object, dtype, void *, int) + object PyArray_ScalarFromObject (object) + #PyArray_VectorUnaryFunc * PyArray_GetCastFunc (dtype, int) + object PyArray_FromDims (int, int *, int) + #object PyArray_FromDimsAndDataAndDescr (int, int *, dtype, char *) + #object PyArray_FromAny (object, dtype, int, int, int, object) + object PyArray_EnsureArray (object) + object PyArray_EnsureAnyArray (object) + #object PyArray_FromFile (stdio.FILE *, dtype, npy_intp, char *) + #object PyArray_FromString (char *, npy_intp, dtype, npy_intp, char *) + #object PyArray_FromBuffer (object, dtype, npy_intp, npy_intp) + #object PyArray_FromIter (object, dtype, npy_intp) + object PyArray_Return (ndarray) + #object PyArray_GetField (ndarray, dtype, int) + #int PyArray_SetField (ndarray, dtype, int, object) + object PyArray_Byteswap (ndarray, npy_bool) + object PyArray_Resize (ndarray, PyArray_Dims *, int, NPY_ORDER) + int PyArray_MoveInto (ndarray, ndarray) + int PyArray_CopyInto (ndarray, ndarray) + int PyArray_CopyAnyInto (ndarray, ndarray) + int PyArray_CopyObject (ndarray, object) + object PyArray_NewCopy (ndarray, NPY_ORDER) + object PyArray_ToList (ndarray) + object PyArray_ToString (ndarray, NPY_ORDER) + int PyArray_ToFile (ndarray, stdio.FILE *, char *, char *) + int PyArray_Dump (object, object, int) + object PyArray_Dumps (object, int) + int PyArray_ValidType (int) + void PyArray_UpdateFlags (ndarray, int) + object PyArray_New (type, int, npy_intp *, int, npy_intp *, void *, int, int, object) + #object PyArray_NewFromDescr (type, dtype, int, npy_intp *, npy_intp *, void *, int, object) + #dtype PyArray_DescrNew (dtype) + dtype PyArray_DescrNewFromType (int) + double PyArray_GetPriority (object, double) + object PyArray_IterNew (object) + object PyArray_MultiIterNew (int, ...) + + int PyArray_PyIntAsInt (object) + npy_intp PyArray_PyIntAsIntp (object) + int PyArray_Broadcast (broadcast) + void PyArray_FillObjectArray (ndarray, object) + int PyArray_FillWithScalar (ndarray, object) + npy_bool PyArray_CheckStrides (int, int, npy_intp, npy_intp, npy_intp *, npy_intp *) + dtype PyArray_DescrNewByteorder (dtype, char) + object PyArray_IterAllButAxis (object, int *) + #object PyArray_CheckFromAny (object, dtype, int, int, int, object) + #object PyArray_FromArray (ndarray, dtype, int) + object PyArray_FromInterface (object) + object PyArray_FromStructInterface (object) + #object PyArray_FromArrayAttr (object, dtype, object) + #NPY_SCALARKIND PyArray_ScalarKind (int, ndarray*) + int PyArray_CanCoerceScalar (int, int, NPY_SCALARKIND) + object PyArray_NewFlagsObject (object) + npy_bool PyArray_CanCastScalar (type, type) + #int PyArray_CompareUCS4 (npy_ucs4 *, npy_ucs4 *, register size_t) + int PyArray_RemoveSmallest (broadcast) + int PyArray_ElementStrides (object) + void PyArray_Item_INCREF (char *, dtype) + void PyArray_Item_XDECREF (char *, dtype) + object PyArray_FieldNames (object) + object PyArray_Transpose (ndarray, PyArray_Dims *) + object PyArray_TakeFrom (ndarray, object, int, ndarray, NPY_CLIPMODE) + object PyArray_PutTo (ndarray, object, object, NPY_CLIPMODE) + object PyArray_PutMask (ndarray, object, object) + object PyArray_Repeat (ndarray, object, int) + object PyArray_Choose (ndarray, object, ndarray, NPY_CLIPMODE) + int PyArray_Sort (ndarray, int, NPY_SORTKIND) + object PyArray_ArgSort (ndarray, int, NPY_SORTKIND) + object PyArray_SearchSorted (ndarray, object, NPY_SEARCHSIDE, PyObject *) + object PyArray_ArgMax (ndarray, int, ndarray) + object PyArray_ArgMin (ndarray, int, ndarray) + object PyArray_Reshape (ndarray, object) + object PyArray_Newshape (ndarray, PyArray_Dims *, NPY_ORDER) + object PyArray_Squeeze (ndarray) + #object PyArray_View (ndarray, dtype, type) + object PyArray_SwapAxes (ndarray, int, int) + object PyArray_Max (ndarray, int, ndarray) + object PyArray_Min (ndarray, int, ndarray) + object PyArray_Ptp (ndarray, int, ndarray) + object PyArray_Mean (ndarray, int, int, ndarray) + object PyArray_Trace (ndarray, int, int, int, int, ndarray) + object PyArray_Diagonal (ndarray, int, int, int) + object PyArray_Clip (ndarray, object, object, ndarray) + object PyArray_Conjugate (ndarray, ndarray) + object PyArray_Nonzero (ndarray) + object PyArray_Std (ndarray, int, int, ndarray, int) + object PyArray_Sum (ndarray, int, int, ndarray) + object PyArray_CumSum (ndarray, int, int, ndarray) + object PyArray_Prod (ndarray, int, int, ndarray) + object PyArray_CumProd (ndarray, int, int, ndarray) + object PyArray_All (ndarray, int, ndarray) + object PyArray_Any (ndarray, int, ndarray) + object PyArray_Compress (ndarray, object, int, ndarray) + object PyArray_Flatten (ndarray, NPY_ORDER) + object PyArray_Ravel (ndarray, NPY_ORDER) + npy_intp PyArray_MultiplyList (npy_intp *, int) + int PyArray_MultiplyIntList (int *, int) + void * PyArray_GetPtr (ndarray, npy_intp*) + int PyArray_CompareLists (npy_intp *, npy_intp *, int) + #int PyArray_AsCArray (object*, void *, npy_intp *, int, dtype) + #int PyArray_As1D (object*, char **, int *, int) + #int PyArray_As2D (object*, char ***, int *, int *, int) + int PyArray_Free (object, void *) + #int PyArray_Converter (object, object*) + int PyArray_IntpFromSequence (object, npy_intp *, int) + object PyArray_Concatenate (object, int) + object PyArray_InnerProduct (object, object) + object PyArray_MatrixProduct (object, object) + object PyArray_CopyAndTranspose (object) + object PyArray_Correlate (object, object, int) + int PyArray_TypestrConvert (int, int) + #int PyArray_DescrConverter (object, dtype*) + #int PyArray_DescrConverter2 (object, dtype*) + int PyArray_IntpConverter (object, PyArray_Dims *) + #int PyArray_BufferConverter (object, chunk) + int PyArray_AxisConverter (object, int *) + int PyArray_BoolConverter (object, npy_bool *) + int PyArray_ByteorderConverter (object, char *) + int PyArray_OrderConverter (object, NPY_ORDER *) + unsigned char PyArray_EquivTypes (dtype, dtype) + #object PyArray_Zeros (int, npy_intp *, dtype, int) + #object PyArray_Empty (int, npy_intp *, dtype, int) + object PyArray_Where (object, object, object) + object PyArray_Arange (double, double, double, int) + #object PyArray_ArangeObj (object, object, object, dtype) + int PyArray_SortkindConverter (object, NPY_SORTKIND *) + object PyArray_LexSort (object, int) + object PyArray_Round (ndarray, int, ndarray) + unsigned char PyArray_EquivTypenums (int, int) + int PyArray_RegisterDataType (dtype) + int PyArray_RegisterCastFunc (dtype, int, PyArray_VectorUnaryFunc *) + int PyArray_RegisterCanCast (dtype, int, NPY_SCALARKIND) + #void PyArray_InitArrFuncs (PyArray_ArrFuncs *) + object PyArray_IntTupleFromIntp (int, npy_intp *) + int PyArray_TypeNumFromName (char *) + int PyArray_ClipmodeConverter (object, NPY_CLIPMODE *) + #int PyArray_OutputConverter (object, ndarray*) + object PyArray_BroadcastToShape (object, npy_intp *, int) + void _PyArray_SigintHandler (int) + void* _PyArray_GetSigintBuf () + #int PyArray_DescrAlignConverter (object, dtype*) + #int PyArray_DescrAlignConverter2 (object, dtype*) + int PyArray_SearchsideConverter (object, void *) + object PyArray_CheckAxis (ndarray, int *, int) + npy_intp PyArray_OverflowMultiplyList (npy_intp *, int) + int PyArray_CompareString (char *, char *, size_t) + int PyArray_SetBaseObject(ndarray, base) # NOTE: steals a reference to base! Use "set_array_base()" instead. + + +# Typedefs that matches the runtime dtype objects in +# the numpy module. + +# The ones that are commented out needs an IFDEF function +# in Cython to enable them only on the right systems. + +ctypedef npy_int8 int8_t +ctypedef npy_int16 int16_t +ctypedef npy_int32 int32_t +ctypedef npy_int64 int64_t +#ctypedef npy_int96 int96_t +#ctypedef npy_int128 int128_t + +ctypedef npy_uint8 uint8_t +ctypedef npy_uint16 uint16_t +ctypedef npy_uint32 uint32_t +ctypedef npy_uint64 uint64_t +#ctypedef npy_uint96 uint96_t +#ctypedef npy_uint128 uint128_t + +ctypedef npy_float32 float32_t +ctypedef npy_float64 float64_t +#ctypedef npy_float80 float80_t +#ctypedef npy_float128 float128_t + +ctypedef float complex complex64_t +ctypedef double complex complex128_t + +# The int types are mapped a bit surprising -- +# numpy.int corresponds to 'l' and numpy.long to 'q' +ctypedef npy_long int_t +ctypedef npy_longlong long_t +ctypedef npy_longlong longlong_t + +ctypedef npy_ulong uint_t +ctypedef npy_ulonglong ulong_t +ctypedef npy_ulonglong ulonglong_t + +ctypedef npy_intp intp_t +ctypedef npy_uintp uintp_t + +ctypedef npy_double float_t +ctypedef npy_double double_t +ctypedef npy_longdouble longdouble_t + +ctypedef npy_cfloat cfloat_t +ctypedef npy_cdouble cdouble_t +ctypedef npy_clongdouble clongdouble_t + +ctypedef npy_cdouble complex_t + +cdef inline object PyArray_MultiIterNew1(a): + return PyArray_MultiIterNew(1, a) + +cdef inline object PyArray_MultiIterNew2(a, b): + return PyArray_MultiIterNew(2, a, b) + +cdef inline object PyArray_MultiIterNew3(a, b, c): + return PyArray_MultiIterNew(3, a, b, c) + +cdef inline object PyArray_MultiIterNew4(a, b, c, d): + return PyArray_MultiIterNew(4, a, b, c, d) + +cdef inline object PyArray_MultiIterNew5(a, b, c, d, e): + return PyArray_MultiIterNew(5, a, b, c, d, e) + +cdef inline tuple PyDataType_SHAPE(dtype d): + if PyDataType_HASSUBARRAY(d): + return d.subarray.shape + else: + return () + + +cdef extern from "numpy/ndarrayobject.h": + PyTypeObject PyTimedeltaArrType_Type + PyTypeObject PyDatetimeArrType_Type + ctypedef int64_t npy_timedelta + ctypedef int64_t npy_datetime + +cdef extern from "numpy/ndarraytypes.h": + ctypedef struct PyArray_DatetimeMetaData: + NPY_DATETIMEUNIT base + int64_t num + +cdef extern from "numpy/arrayscalars.h": + + # abstract types + ctypedef class numpy.generic [object PyObject]: + pass + ctypedef class numpy.number [object PyObject]: + pass + ctypedef class numpy.integer [object PyObject]: + pass + ctypedef class numpy.signedinteger [object PyObject]: + pass + ctypedef class numpy.unsignedinteger [object PyObject]: + pass + ctypedef class numpy.inexact [object PyObject]: + pass + ctypedef class numpy.floating [object PyObject]: + pass + ctypedef class numpy.complexfloating [object PyObject]: + pass + ctypedef class numpy.flexible [object PyObject]: + pass + ctypedef class numpy.character [object PyObject]: + pass + + ctypedef struct PyDatetimeScalarObject: + # PyObject_HEAD + npy_datetime obval + PyArray_DatetimeMetaData obmeta + + ctypedef struct PyTimedeltaScalarObject: + # PyObject_HEAD + npy_timedelta obval + PyArray_DatetimeMetaData obmeta + + ctypedef enum NPY_DATETIMEUNIT: + NPY_FR_Y + NPY_FR_M + NPY_FR_W + NPY_FR_D + NPY_FR_B + NPY_FR_h + NPY_FR_m + NPY_FR_s + NPY_FR_ms + NPY_FR_us + NPY_FR_ns + NPY_FR_ps + NPY_FR_fs + NPY_FR_as + + +# +# ufunc API +# + +cdef extern from "numpy/ufuncobject.h": + + ctypedef void (*PyUFuncGenericFunction) (char **, npy_intp *, npy_intp *, void *) + + ctypedef class numpy.ufunc [object PyUFuncObject, check_size ignore]: + cdef: + int nin, nout, nargs + int identity + PyUFuncGenericFunction *functions + void **data + int ntypes + int check_return + char *name + char *types + char *doc + void *ptr + PyObject *obj + PyObject *userloops + + cdef enum: + PyUFunc_Zero + PyUFunc_One + PyUFunc_None + UFUNC_ERR_IGNORE + UFUNC_ERR_WARN + UFUNC_ERR_RAISE + UFUNC_ERR_CALL + UFUNC_ERR_PRINT + UFUNC_ERR_LOG + UFUNC_MASK_DIVIDEBYZERO + UFUNC_MASK_OVERFLOW + UFUNC_MASK_UNDERFLOW + UFUNC_MASK_INVALID + UFUNC_SHIFT_DIVIDEBYZERO + UFUNC_SHIFT_OVERFLOW + UFUNC_SHIFT_UNDERFLOW + UFUNC_SHIFT_INVALID + UFUNC_FPE_DIVIDEBYZERO + UFUNC_FPE_OVERFLOW + UFUNC_FPE_UNDERFLOW + UFUNC_FPE_INVALID + UFUNC_ERR_DEFAULT + UFUNC_ERR_DEFAULT2 + + object PyUFunc_FromFuncAndData(PyUFuncGenericFunction *, + void **, char *, int, int, int, int, char *, char *, int) + int PyUFunc_RegisterLoopForType(ufunc, int, + PyUFuncGenericFunction, int *, void *) + int PyUFunc_GenericFunction \ + (ufunc, PyObject *, PyObject *, PyArrayObject **) + void PyUFunc_f_f_As_d_d \ + (char **, npy_intp *, npy_intp *, void *) + void PyUFunc_d_d \ + (char **, npy_intp *, npy_intp *, void *) + void PyUFunc_f_f \ + (char **, npy_intp *, npy_intp *, void *) + void PyUFunc_g_g \ + (char **, npy_intp *, npy_intp *, void *) + void PyUFunc_F_F_As_D_D \ + (char **, npy_intp *, npy_intp *, void *) + void PyUFunc_F_F \ + (char **, npy_intp *, npy_intp *, void *) + void PyUFunc_D_D \ + (char **, npy_intp *, npy_intp *, void *) + void PyUFunc_G_G \ + (char **, npy_intp *, npy_intp *, void *) + void PyUFunc_O_O \ + (char **, npy_intp *, npy_intp *, void *) + void PyUFunc_ff_f_As_dd_d \ + (char **, npy_intp *, npy_intp *, void *) + void PyUFunc_ff_f \ + (char **, npy_intp *, npy_intp *, void *) + void PyUFunc_dd_d \ + (char **, npy_intp *, npy_intp *, void *) + void PyUFunc_gg_g \ + (char **, npy_intp *, npy_intp *, void *) + void PyUFunc_FF_F_As_DD_D \ + (char **, npy_intp *, npy_intp *, void *) + void PyUFunc_DD_D \ + (char **, npy_intp *, npy_intp *, void *) + void PyUFunc_FF_F \ + (char **, npy_intp *, npy_intp *, void *) + void PyUFunc_GG_G \ + (char **, npy_intp *, npy_intp *, void *) + void PyUFunc_OO_O \ + (char **, npy_intp *, npy_intp *, void *) + void PyUFunc_O_O_method \ + (char **, npy_intp *, npy_intp *, void *) + void PyUFunc_OO_O_method \ + (char **, npy_intp *, npy_intp *, void *) + void PyUFunc_On_Om \ + (char **, npy_intp *, npy_intp *, void *) + int PyUFunc_GetPyValues \ + (char *, int *, int *, PyObject **) + int PyUFunc_checkfperr \ + (int, PyObject *, int *) + void PyUFunc_clearfperr() + int PyUFunc_getfperr() + int PyUFunc_handlefperr \ + (int, PyObject *, int, int *) + int PyUFunc_ReplaceLoopBySignature \ + (ufunc, PyUFuncGenericFunction, int *, PyUFuncGenericFunction *) + object PyUFunc_FromFuncAndDataAndSignature \ + (PyUFuncGenericFunction *, void **, char *, int, int, int, + int, char *, char *, int, char *) + + int _import_umath() except -1 + +cdef inline void set_array_base(ndarray arr, object base): + Py_INCREF(base) # important to do this before stealing the reference below! + PyArray_SetBaseObject(arr, base) + +cdef inline object get_array_base(ndarray arr): + base = PyArray_BASE(arr) + if base is NULL: + return None + return base + +# Versions of the import_* functions which are more suitable for +# Cython code. +cdef inline int import_array() except -1: + try: + __pyx_import_array() + except Exception: + raise ImportError("numpy.core.multiarray failed to import") + +cdef inline int import_umath() except -1: + try: + _import_umath() + except Exception: + raise ImportError("numpy.core.umath failed to import") + +cdef inline int import_ufunc() except -1: + try: + _import_umath() + except Exception: + raise ImportError("numpy.core.umath failed to import") + + +cdef inline bint is_timedelta64_object(object obj): + """ + Cython equivalent of `isinstance(obj, np.timedelta64)` + + Parameters + ---------- + obj : object + + Returns + ------- + bool + """ + return PyObject_TypeCheck(obj, &PyTimedeltaArrType_Type) + + +cdef inline bint is_datetime64_object(object obj): + """ + Cython equivalent of `isinstance(obj, np.datetime64)` + + Parameters + ---------- + obj : object + + Returns + ------- + bool + """ + return PyObject_TypeCheck(obj, &PyDatetimeArrType_Type) + + +cdef inline npy_datetime get_datetime64_value(object obj) nogil: + """ + returns the int64 value underlying scalar numpy datetime64 object + + Note that to interpret this as a datetime, the corresponding unit is + also needed. That can be found using `get_datetime64_unit`. + """ + return (obj).obval + + +cdef inline npy_timedelta get_timedelta64_value(object obj) nogil: + """ + returns the int64 value underlying scalar numpy timedelta64 object + """ + return (obj).obval + + +cdef inline NPY_DATETIMEUNIT get_datetime64_unit(object obj) nogil: + """ + returns the unit part of the dtype for a numpy datetime64 object. + """ + return (obj).obmeta.base diff --git a/venv/Lib/site-packages/numpy/__init__.pxd b/venv/Lib/site-packages/numpy/__init__.pxd new file mode 100644 index 0000000..fd704b7 --- /dev/null +++ b/venv/Lib/site-packages/numpy/__init__.pxd @@ -0,0 +1,1020 @@ +# NumPy static imports for Cython < 3.0 +# +# If any of the PyArray_* functions are called, import_array must be +# called first. +# +# Author: Dag Sverre Seljebotn +# + +DEF _buffer_format_string_len = 255 + +cimport cpython.buffer as pybuf +from cpython.ref cimport Py_INCREF +from cpython.mem cimport PyObject_Malloc, PyObject_Free +from cpython.object cimport PyObject, PyTypeObject +from cpython.buffer cimport PyObject_GetBuffer +from cpython.type cimport type +cimport libc.stdio as stdio + +cdef extern from "Python.h": + ctypedef int Py_intptr_t + bint PyObject_TypeCheck(object obj, PyTypeObject* type) + +cdef extern from "numpy/arrayobject.h": + ctypedef Py_intptr_t npy_intp + ctypedef size_t npy_uintp + + cdef enum NPY_TYPES: + NPY_BOOL + NPY_BYTE + NPY_UBYTE + NPY_SHORT + NPY_USHORT + NPY_INT + NPY_UINT + NPY_LONG + NPY_ULONG + NPY_LONGLONG + NPY_ULONGLONG + NPY_FLOAT + NPY_DOUBLE + NPY_LONGDOUBLE + NPY_CFLOAT + NPY_CDOUBLE + NPY_CLONGDOUBLE + NPY_OBJECT + NPY_STRING + NPY_UNICODE + NPY_VOID + NPY_DATETIME + NPY_TIMEDELTA + NPY_NTYPES + NPY_NOTYPE + + NPY_INT8 + NPY_INT16 + NPY_INT32 + NPY_INT64 + NPY_INT128 + NPY_INT256 + NPY_UINT8 + NPY_UINT16 + NPY_UINT32 + NPY_UINT64 + NPY_UINT128 + NPY_UINT256 + NPY_FLOAT16 + NPY_FLOAT32 + NPY_FLOAT64 + NPY_FLOAT80 + NPY_FLOAT96 + NPY_FLOAT128 + NPY_FLOAT256 + NPY_COMPLEX32 + NPY_COMPLEX64 + NPY_COMPLEX128 + NPY_COMPLEX160 + NPY_COMPLEX192 + NPY_COMPLEX256 + NPY_COMPLEX512 + + NPY_INTP + + ctypedef enum NPY_ORDER: + NPY_ANYORDER + NPY_CORDER + NPY_FORTRANORDER + NPY_KEEPORDER + + ctypedef enum NPY_CASTING: + NPY_NO_CASTING + NPY_EQUIV_CASTING + NPY_SAFE_CASTING + NPY_SAME_KIND_CASTING + NPY_UNSAFE_CASTING + + ctypedef enum NPY_CLIPMODE: + NPY_CLIP + NPY_WRAP + NPY_RAISE + + ctypedef enum NPY_SCALARKIND: + NPY_NOSCALAR, + NPY_BOOL_SCALAR, + NPY_INTPOS_SCALAR, + NPY_INTNEG_SCALAR, + NPY_FLOAT_SCALAR, + NPY_COMPLEX_SCALAR, + NPY_OBJECT_SCALAR + + ctypedef enum NPY_SORTKIND: + NPY_QUICKSORT + NPY_HEAPSORT + NPY_MERGESORT + + ctypedef enum NPY_SEARCHSIDE: + NPY_SEARCHLEFT + NPY_SEARCHRIGHT + + enum: + # DEPRECATED since NumPy 1.7 ! Do not use in new code! + NPY_C_CONTIGUOUS + NPY_F_CONTIGUOUS + NPY_CONTIGUOUS + NPY_FORTRAN + NPY_OWNDATA + NPY_FORCECAST + NPY_ENSURECOPY + NPY_ENSUREARRAY + NPY_ELEMENTSTRIDES + NPY_ALIGNED + NPY_NOTSWAPPED + NPY_WRITEABLE + NPY_UPDATEIFCOPY + NPY_ARR_HAS_DESCR + + NPY_BEHAVED + NPY_BEHAVED_NS + NPY_CARRAY + NPY_CARRAY_RO + NPY_FARRAY + NPY_FARRAY_RO + NPY_DEFAULT + + NPY_IN_ARRAY + NPY_OUT_ARRAY + NPY_INOUT_ARRAY + NPY_IN_FARRAY + NPY_OUT_FARRAY + NPY_INOUT_FARRAY + + NPY_UPDATE_ALL + + enum: + # Added in NumPy 1.7 to replace the deprecated enums above. + NPY_ARRAY_C_CONTIGUOUS + NPY_ARRAY_F_CONTIGUOUS + NPY_ARRAY_OWNDATA + NPY_ARRAY_FORCECAST + NPY_ARRAY_ENSURECOPY + NPY_ARRAY_ENSUREARRAY + NPY_ARRAY_ELEMENTSTRIDES + NPY_ARRAY_ALIGNED + NPY_ARRAY_NOTSWAPPED + NPY_ARRAY_WRITEABLE + NPY_ARRAY_UPDATEIFCOPY + + NPY_ARRAY_BEHAVED + NPY_ARRAY_BEHAVED_NS + NPY_ARRAY_CARRAY + NPY_ARRAY_CARRAY_RO + NPY_ARRAY_FARRAY + NPY_ARRAY_FARRAY_RO + NPY_ARRAY_DEFAULT + + NPY_ARRAY_IN_ARRAY + NPY_ARRAY_OUT_ARRAY + NPY_ARRAY_INOUT_ARRAY + NPY_ARRAY_IN_FARRAY + NPY_ARRAY_OUT_FARRAY + NPY_ARRAY_INOUT_FARRAY + + NPY_ARRAY_UPDATE_ALL + + cdef enum: + NPY_MAXDIMS + + npy_intp NPY_MAX_ELSIZE + + ctypedef void (*PyArray_VectorUnaryFunc)(void *, void *, npy_intp, void *, void *) + + ctypedef struct PyArray_ArrayDescr: + # shape is a tuple, but Cython doesn't support "tuple shape" + # inside a non-PyObject declaration, so we have to declare it + # as just a PyObject*. + PyObject* shape + + ctypedef struct PyArray_Descr: + pass + + ctypedef class numpy.dtype [object PyArray_Descr, check_size ignore]: + # Use PyDataType_* macros when possible, however there are no macros + # for accessing some of the fields, so some are defined. + cdef PyTypeObject* typeobj + cdef char kind + cdef char type + # Numpy sometimes mutates this without warning (e.g. it'll + # sometimes change "|" to "<" in shared dtype objects on + # little-endian machines). If this matters to you, use + # PyArray_IsNativeByteOrder(dtype.byteorder) instead of + # directly accessing this field. + cdef char byteorder + cdef char flags + cdef int type_num + cdef int itemsize "elsize" + cdef int alignment + cdef object fields + cdef tuple names + # Use PyDataType_HASSUBARRAY to test whether this field is + # valid (the pointer can be NULL). Most users should access + # this field via the inline helper method PyDataType_SHAPE. + cdef PyArray_ArrayDescr* subarray + + ctypedef class numpy.flatiter [object PyArrayIterObject, check_size ignore]: + # Use through macros + pass + + ctypedef class numpy.broadcast [object PyArrayMultiIterObject, check_size ignore]: + cdef int numiter + cdef npy_intp size, index + cdef int nd + cdef npy_intp *dimensions + cdef void **iters + + ctypedef struct PyArrayObject: + # For use in situations where ndarray can't replace PyArrayObject*, + # like PyArrayObject**. + pass + + ctypedef class numpy.ndarray [object PyArrayObject, check_size ignore]: + cdef __cythonbufferdefaults__ = {"mode": "strided"} + + cdef: + # Only taking a few of the most commonly used and stable fields. + # One should use PyArray_* macros instead to access the C fields. + char *data + int ndim "nd" + npy_intp *shape "dimensions" + npy_intp *strides + dtype descr # deprecated since NumPy 1.7 ! + PyObject* base # NOT PUBLIC, DO NOT USE ! + + + + ctypedef unsigned char npy_bool + + ctypedef signed char npy_byte + ctypedef signed short npy_short + ctypedef signed int npy_int + ctypedef signed long npy_long + ctypedef signed long long npy_longlong + + ctypedef unsigned char npy_ubyte + ctypedef unsigned short npy_ushort + ctypedef unsigned int npy_uint + ctypedef unsigned long npy_ulong + ctypedef unsigned long long npy_ulonglong + + ctypedef float npy_float + ctypedef double npy_double + ctypedef long double npy_longdouble + + ctypedef signed char npy_int8 + ctypedef signed short npy_int16 + ctypedef signed int npy_int32 + ctypedef signed long long npy_int64 + ctypedef signed long long npy_int96 + ctypedef signed long long npy_int128 + + ctypedef unsigned char npy_uint8 + ctypedef unsigned short npy_uint16 + ctypedef unsigned int npy_uint32 + ctypedef unsigned long long npy_uint64 + ctypedef unsigned long long npy_uint96 + ctypedef unsigned long long npy_uint128 + + ctypedef float npy_float32 + ctypedef double npy_float64 + ctypedef long double npy_float80 + ctypedef long double npy_float96 + ctypedef long double npy_float128 + + ctypedef struct npy_cfloat: + float real + float imag + + ctypedef struct npy_cdouble: + double real + double imag + + ctypedef struct npy_clongdouble: + long double real + long double imag + + ctypedef struct npy_complex64: + float real + float imag + + ctypedef struct npy_complex128: + double real + double imag + + ctypedef struct npy_complex160: + long double real + long double imag + + ctypedef struct npy_complex192: + long double real + long double imag + + ctypedef struct npy_complex256: + long double real + long double imag + + ctypedef struct PyArray_Dims: + npy_intp *ptr + int len + + int _import_array() except -1 + # A second definition so _import_array isn't marked as used when we use it here. + # Do not use - subject to change any time. + int __pyx_import_array "_import_array"() except -1 + + # + # Macros from ndarrayobject.h + # + bint PyArray_CHKFLAGS(ndarray m, int flags) nogil + bint PyArray_IS_C_CONTIGUOUS(ndarray arr) nogil + bint PyArray_IS_F_CONTIGUOUS(ndarray arr) nogil + bint PyArray_ISCONTIGUOUS(ndarray m) nogil + bint PyArray_ISWRITEABLE(ndarray m) nogil + bint PyArray_ISALIGNED(ndarray m) nogil + + int PyArray_NDIM(ndarray) nogil + bint PyArray_ISONESEGMENT(ndarray) nogil + bint PyArray_ISFORTRAN(ndarray) nogil + int PyArray_FORTRANIF(ndarray) nogil + + void* PyArray_DATA(ndarray) nogil + char* PyArray_BYTES(ndarray) nogil + + npy_intp* PyArray_DIMS(ndarray) nogil + npy_intp* PyArray_STRIDES(ndarray) nogil + npy_intp PyArray_DIM(ndarray, size_t) nogil + npy_intp PyArray_STRIDE(ndarray, size_t) nogil + + PyObject *PyArray_BASE(ndarray) nogil # returns borrowed reference! + PyArray_Descr *PyArray_DESCR(ndarray) nogil # returns borrowed reference to dtype! + int PyArray_FLAGS(ndarray) nogil + npy_intp PyArray_ITEMSIZE(ndarray) nogil + int PyArray_TYPE(ndarray arr) nogil + + object PyArray_GETITEM(ndarray arr, void *itemptr) + int PyArray_SETITEM(ndarray arr, void *itemptr, object obj) + + bint PyTypeNum_ISBOOL(int) nogil + bint PyTypeNum_ISUNSIGNED(int) nogil + bint PyTypeNum_ISSIGNED(int) nogil + bint PyTypeNum_ISINTEGER(int) nogil + bint PyTypeNum_ISFLOAT(int) nogil + bint PyTypeNum_ISNUMBER(int) nogil + bint PyTypeNum_ISSTRING(int) nogil + bint PyTypeNum_ISCOMPLEX(int) nogil + bint PyTypeNum_ISPYTHON(int) nogil + bint PyTypeNum_ISFLEXIBLE(int) nogil + bint PyTypeNum_ISUSERDEF(int) nogil + bint PyTypeNum_ISEXTENDED(int) nogil + bint PyTypeNum_ISOBJECT(int) nogil + + bint PyDataType_ISBOOL(dtype) nogil + bint PyDataType_ISUNSIGNED(dtype) nogil + bint PyDataType_ISSIGNED(dtype) nogil + bint PyDataType_ISINTEGER(dtype) nogil + bint PyDataType_ISFLOAT(dtype) nogil + bint PyDataType_ISNUMBER(dtype) nogil + bint PyDataType_ISSTRING(dtype) nogil + bint PyDataType_ISCOMPLEX(dtype) nogil + bint PyDataType_ISPYTHON(dtype) nogil + bint PyDataType_ISFLEXIBLE(dtype) nogil + bint PyDataType_ISUSERDEF(dtype) nogil + bint PyDataType_ISEXTENDED(dtype) nogil + bint PyDataType_ISOBJECT(dtype) nogil + bint PyDataType_HASFIELDS(dtype) nogil + bint PyDataType_HASSUBARRAY(dtype) nogil + + bint PyArray_ISBOOL(ndarray) nogil + bint PyArray_ISUNSIGNED(ndarray) nogil + bint PyArray_ISSIGNED(ndarray) nogil + bint PyArray_ISINTEGER(ndarray) nogil + bint PyArray_ISFLOAT(ndarray) nogil + bint PyArray_ISNUMBER(ndarray) nogil + bint PyArray_ISSTRING(ndarray) nogil + bint PyArray_ISCOMPLEX(ndarray) nogil + bint PyArray_ISPYTHON(ndarray) nogil + bint PyArray_ISFLEXIBLE(ndarray) nogil + bint PyArray_ISUSERDEF(ndarray) nogil + bint PyArray_ISEXTENDED(ndarray) nogil + bint PyArray_ISOBJECT(ndarray) nogil + bint PyArray_HASFIELDS(ndarray) nogil + + bint PyArray_ISVARIABLE(ndarray) nogil + + bint PyArray_SAFEALIGNEDCOPY(ndarray) nogil + bint PyArray_ISNBO(char) nogil # works on ndarray.byteorder + bint PyArray_IsNativeByteOrder(char) nogil # works on ndarray.byteorder + bint PyArray_ISNOTSWAPPED(ndarray) nogil + bint PyArray_ISBYTESWAPPED(ndarray) nogil + + bint PyArray_FLAGSWAP(ndarray, int) nogil + + bint PyArray_ISCARRAY(ndarray) nogil + bint PyArray_ISCARRAY_RO(ndarray) nogil + bint PyArray_ISFARRAY(ndarray) nogil + bint PyArray_ISFARRAY_RO(ndarray) nogil + bint PyArray_ISBEHAVED(ndarray) nogil + bint PyArray_ISBEHAVED_RO(ndarray) nogil + + + bint PyDataType_ISNOTSWAPPED(dtype) nogil + bint PyDataType_ISBYTESWAPPED(dtype) nogil + + bint PyArray_DescrCheck(object) + + bint PyArray_Check(object) + bint PyArray_CheckExact(object) + + # Cannot be supported due to out arg: + # bint PyArray_HasArrayInterfaceType(object, dtype, object, object&) + # bint PyArray_HasArrayInterface(op, out) + + + bint PyArray_IsZeroDim(object) + # Cannot be supported due to ## ## in macro: + # bint PyArray_IsScalar(object, verbatim work) + bint PyArray_CheckScalar(object) + bint PyArray_IsPythonNumber(object) + bint PyArray_IsPythonScalar(object) + bint PyArray_IsAnyScalar(object) + bint PyArray_CheckAnyScalar(object) + + ndarray PyArray_GETCONTIGUOUS(ndarray) + bint PyArray_SAMESHAPE(ndarray, ndarray) nogil + npy_intp PyArray_SIZE(ndarray) nogil + npy_intp PyArray_NBYTES(ndarray) nogil + + object PyArray_FROM_O(object) + object PyArray_FROM_OF(object m, int flags) + object PyArray_FROM_OT(object m, int type) + object PyArray_FROM_OTF(object m, int type, int flags) + object PyArray_FROMANY(object m, int type, int min, int max, int flags) + object PyArray_ZEROS(int nd, npy_intp* dims, int type, int fortran) + object PyArray_EMPTY(int nd, npy_intp* dims, int type, int fortran) + void PyArray_FILLWBYTE(object, int val) + npy_intp PyArray_REFCOUNT(object) + object PyArray_ContiguousFromAny(op, int, int min_depth, int max_depth) + unsigned char PyArray_EquivArrTypes(ndarray a1, ndarray a2) + bint PyArray_EquivByteorders(int b1, int b2) nogil + object PyArray_SimpleNew(int nd, npy_intp* dims, int typenum) + object PyArray_SimpleNewFromData(int nd, npy_intp* dims, int typenum, void* data) + #object PyArray_SimpleNewFromDescr(int nd, npy_intp* dims, dtype descr) + object PyArray_ToScalar(void* data, ndarray arr) + + void* PyArray_GETPTR1(ndarray m, npy_intp i) nogil + void* PyArray_GETPTR2(ndarray m, npy_intp i, npy_intp j) nogil + void* PyArray_GETPTR3(ndarray m, npy_intp i, npy_intp j, npy_intp k) nogil + void* PyArray_GETPTR4(ndarray m, npy_intp i, npy_intp j, npy_intp k, npy_intp l) nogil + + void PyArray_XDECREF_ERR(ndarray) + # Cannot be supported due to out arg + # void PyArray_DESCR_REPLACE(descr) + + + object PyArray_Copy(ndarray) + object PyArray_FromObject(object op, int type, int min_depth, int max_depth) + object PyArray_ContiguousFromObject(object op, int type, int min_depth, int max_depth) + object PyArray_CopyFromObject(object op, int type, int min_depth, int max_depth) + + object PyArray_Cast(ndarray mp, int type_num) + object PyArray_Take(ndarray ap, object items, int axis) + object PyArray_Put(ndarray ap, object items, object values) + + void PyArray_ITER_RESET(flatiter it) nogil + void PyArray_ITER_NEXT(flatiter it) nogil + void PyArray_ITER_GOTO(flatiter it, npy_intp* destination) nogil + void PyArray_ITER_GOTO1D(flatiter it, npy_intp ind) nogil + void* PyArray_ITER_DATA(flatiter it) nogil + bint PyArray_ITER_NOTDONE(flatiter it) nogil + + void PyArray_MultiIter_RESET(broadcast multi) nogil + void PyArray_MultiIter_NEXT(broadcast multi) nogil + void PyArray_MultiIter_GOTO(broadcast multi, npy_intp dest) nogil + void PyArray_MultiIter_GOTO1D(broadcast multi, npy_intp ind) nogil + void* PyArray_MultiIter_DATA(broadcast multi, npy_intp i) nogil + void PyArray_MultiIter_NEXTi(broadcast multi, npy_intp i) nogil + bint PyArray_MultiIter_NOTDONE(broadcast multi) nogil + + # Functions from __multiarray_api.h + + # Functions taking dtype and returning object/ndarray are disabled + # for now as they steal dtype references. I'm conservative and disable + # more than is probably needed until it can be checked further. + int PyArray_SetNumericOps (object) + object PyArray_GetNumericOps () + int PyArray_INCREF (ndarray) + int PyArray_XDECREF (ndarray) + void PyArray_SetStringFunction (object, int) + dtype PyArray_DescrFromType (int) + object PyArray_TypeObjectFromType (int) + char * PyArray_Zero (ndarray) + char * PyArray_One (ndarray) + #object PyArray_CastToType (ndarray, dtype, int) + int PyArray_CastTo (ndarray, ndarray) + int PyArray_CastAnyTo (ndarray, ndarray) + int PyArray_CanCastSafely (int, int) + npy_bool PyArray_CanCastTo (dtype, dtype) + int PyArray_ObjectType (object, int) + dtype PyArray_DescrFromObject (object, dtype) + #ndarray* PyArray_ConvertToCommonType (object, int *) + dtype PyArray_DescrFromScalar (object) + dtype PyArray_DescrFromTypeObject (object) + npy_intp PyArray_Size (object) + #object PyArray_Scalar (void *, dtype, object) + #object PyArray_FromScalar (object, dtype) + void PyArray_ScalarAsCtype (object, void *) + #int PyArray_CastScalarToCtype (object, void *, dtype) + #int PyArray_CastScalarDirect (object, dtype, void *, int) + object PyArray_ScalarFromObject (object) + #PyArray_VectorUnaryFunc * PyArray_GetCastFunc (dtype, int) + object PyArray_FromDims (int, int *, int) + #object PyArray_FromDimsAndDataAndDescr (int, int *, dtype, char *) + #object PyArray_FromAny (object, dtype, int, int, int, object) + object PyArray_EnsureArray (object) + object PyArray_EnsureAnyArray (object) + #object PyArray_FromFile (stdio.FILE *, dtype, npy_intp, char *) + #object PyArray_FromString (char *, npy_intp, dtype, npy_intp, char *) + #object PyArray_FromBuffer (object, dtype, npy_intp, npy_intp) + #object PyArray_FromIter (object, dtype, npy_intp) + object PyArray_Return (ndarray) + #object PyArray_GetField (ndarray, dtype, int) + #int PyArray_SetField (ndarray, dtype, int, object) + object PyArray_Byteswap (ndarray, npy_bool) + object PyArray_Resize (ndarray, PyArray_Dims *, int, NPY_ORDER) + int PyArray_MoveInto (ndarray, ndarray) + int PyArray_CopyInto (ndarray, ndarray) + int PyArray_CopyAnyInto (ndarray, ndarray) + int PyArray_CopyObject (ndarray, object) + object PyArray_NewCopy (ndarray, NPY_ORDER) + object PyArray_ToList (ndarray) + object PyArray_ToString (ndarray, NPY_ORDER) + int PyArray_ToFile (ndarray, stdio.FILE *, char *, char *) + int PyArray_Dump (object, object, int) + object PyArray_Dumps (object, int) + int PyArray_ValidType (int) + void PyArray_UpdateFlags (ndarray, int) + object PyArray_New (type, int, npy_intp *, int, npy_intp *, void *, int, int, object) + #object PyArray_NewFromDescr (type, dtype, int, npy_intp *, npy_intp *, void *, int, object) + #dtype PyArray_DescrNew (dtype) + dtype PyArray_DescrNewFromType (int) + double PyArray_GetPriority (object, double) + object PyArray_IterNew (object) + object PyArray_MultiIterNew (int, ...) + + int PyArray_PyIntAsInt (object) + npy_intp PyArray_PyIntAsIntp (object) + int PyArray_Broadcast (broadcast) + void PyArray_FillObjectArray (ndarray, object) + int PyArray_FillWithScalar (ndarray, object) + npy_bool PyArray_CheckStrides (int, int, npy_intp, npy_intp, npy_intp *, npy_intp *) + dtype PyArray_DescrNewByteorder (dtype, char) + object PyArray_IterAllButAxis (object, int *) + #object PyArray_CheckFromAny (object, dtype, int, int, int, object) + #object PyArray_FromArray (ndarray, dtype, int) + object PyArray_FromInterface (object) + object PyArray_FromStructInterface (object) + #object PyArray_FromArrayAttr (object, dtype, object) + #NPY_SCALARKIND PyArray_ScalarKind (int, ndarray*) + int PyArray_CanCoerceScalar (int, int, NPY_SCALARKIND) + object PyArray_NewFlagsObject (object) + npy_bool PyArray_CanCastScalar (type, type) + #int PyArray_CompareUCS4 (npy_ucs4 *, npy_ucs4 *, register size_t) + int PyArray_RemoveSmallest (broadcast) + int PyArray_ElementStrides (object) + void PyArray_Item_INCREF (char *, dtype) + void PyArray_Item_XDECREF (char *, dtype) + object PyArray_FieldNames (object) + object PyArray_Transpose (ndarray, PyArray_Dims *) + object PyArray_TakeFrom (ndarray, object, int, ndarray, NPY_CLIPMODE) + object PyArray_PutTo (ndarray, object, object, NPY_CLIPMODE) + object PyArray_PutMask (ndarray, object, object) + object PyArray_Repeat (ndarray, object, int) + object PyArray_Choose (ndarray, object, ndarray, NPY_CLIPMODE) + int PyArray_Sort (ndarray, int, NPY_SORTKIND) + object PyArray_ArgSort (ndarray, int, NPY_SORTKIND) + object PyArray_SearchSorted (ndarray, object, NPY_SEARCHSIDE, PyObject *) + object PyArray_ArgMax (ndarray, int, ndarray) + object PyArray_ArgMin (ndarray, int, ndarray) + object PyArray_Reshape (ndarray, object) + object PyArray_Newshape (ndarray, PyArray_Dims *, NPY_ORDER) + object PyArray_Squeeze (ndarray) + #object PyArray_View (ndarray, dtype, type) + object PyArray_SwapAxes (ndarray, int, int) + object PyArray_Max (ndarray, int, ndarray) + object PyArray_Min (ndarray, int, ndarray) + object PyArray_Ptp (ndarray, int, ndarray) + object PyArray_Mean (ndarray, int, int, ndarray) + object PyArray_Trace (ndarray, int, int, int, int, ndarray) + object PyArray_Diagonal (ndarray, int, int, int) + object PyArray_Clip (ndarray, object, object, ndarray) + object PyArray_Conjugate (ndarray, ndarray) + object PyArray_Nonzero (ndarray) + object PyArray_Std (ndarray, int, int, ndarray, int) + object PyArray_Sum (ndarray, int, int, ndarray) + object PyArray_CumSum (ndarray, int, int, ndarray) + object PyArray_Prod (ndarray, int, int, ndarray) + object PyArray_CumProd (ndarray, int, int, ndarray) + object PyArray_All (ndarray, int, ndarray) + object PyArray_Any (ndarray, int, ndarray) + object PyArray_Compress (ndarray, object, int, ndarray) + object PyArray_Flatten (ndarray, NPY_ORDER) + object PyArray_Ravel (ndarray, NPY_ORDER) + npy_intp PyArray_MultiplyList (npy_intp *, int) + int PyArray_MultiplyIntList (int *, int) + void * PyArray_GetPtr (ndarray, npy_intp*) + int PyArray_CompareLists (npy_intp *, npy_intp *, int) + #int PyArray_AsCArray (object*, void *, npy_intp *, int, dtype) + #int PyArray_As1D (object*, char **, int *, int) + #int PyArray_As2D (object*, char ***, int *, int *, int) + int PyArray_Free (object, void *) + #int PyArray_Converter (object, object*) + int PyArray_IntpFromSequence (object, npy_intp *, int) + object PyArray_Concatenate (object, int) + object PyArray_InnerProduct (object, object) + object PyArray_MatrixProduct (object, object) + object PyArray_CopyAndTranspose (object) + object PyArray_Correlate (object, object, int) + int PyArray_TypestrConvert (int, int) + #int PyArray_DescrConverter (object, dtype*) + #int PyArray_DescrConverter2 (object, dtype*) + int PyArray_IntpConverter (object, PyArray_Dims *) + #int PyArray_BufferConverter (object, chunk) + int PyArray_AxisConverter (object, int *) + int PyArray_BoolConverter (object, npy_bool *) + int PyArray_ByteorderConverter (object, char *) + int PyArray_OrderConverter (object, NPY_ORDER *) + unsigned char PyArray_EquivTypes (dtype, dtype) + #object PyArray_Zeros (int, npy_intp *, dtype, int) + #object PyArray_Empty (int, npy_intp *, dtype, int) + object PyArray_Where (object, object, object) + object PyArray_Arange (double, double, double, int) + #object PyArray_ArangeObj (object, object, object, dtype) + int PyArray_SortkindConverter (object, NPY_SORTKIND *) + object PyArray_LexSort (object, int) + object PyArray_Round (ndarray, int, ndarray) + unsigned char PyArray_EquivTypenums (int, int) + int PyArray_RegisterDataType (dtype) + int PyArray_RegisterCastFunc (dtype, int, PyArray_VectorUnaryFunc *) + int PyArray_RegisterCanCast (dtype, int, NPY_SCALARKIND) + #void PyArray_InitArrFuncs (PyArray_ArrFuncs *) + object PyArray_IntTupleFromIntp (int, npy_intp *) + int PyArray_TypeNumFromName (char *) + int PyArray_ClipmodeConverter (object, NPY_CLIPMODE *) + #int PyArray_OutputConverter (object, ndarray*) + object PyArray_BroadcastToShape (object, npy_intp *, int) + void _PyArray_SigintHandler (int) + void* _PyArray_GetSigintBuf () + #int PyArray_DescrAlignConverter (object, dtype*) + #int PyArray_DescrAlignConverter2 (object, dtype*) + int PyArray_SearchsideConverter (object, void *) + object PyArray_CheckAxis (ndarray, int *, int) + npy_intp PyArray_OverflowMultiplyList (npy_intp *, int) + int PyArray_CompareString (char *, char *, size_t) + int PyArray_SetBaseObject(ndarray, base) # NOTE: steals a reference to base! Use "set_array_base()" instead. + + +# Typedefs that matches the runtime dtype objects in +# the numpy module. + +# The ones that are commented out needs an IFDEF function +# in Cython to enable them only on the right systems. + +ctypedef npy_int8 int8_t +ctypedef npy_int16 int16_t +ctypedef npy_int32 int32_t +ctypedef npy_int64 int64_t +#ctypedef npy_int96 int96_t +#ctypedef npy_int128 int128_t + +ctypedef npy_uint8 uint8_t +ctypedef npy_uint16 uint16_t +ctypedef npy_uint32 uint32_t +ctypedef npy_uint64 uint64_t +#ctypedef npy_uint96 uint96_t +#ctypedef npy_uint128 uint128_t + +ctypedef npy_float32 float32_t +ctypedef npy_float64 float64_t +#ctypedef npy_float80 float80_t +#ctypedef npy_float128 float128_t + +ctypedef float complex complex64_t +ctypedef double complex complex128_t + +# The int types are mapped a bit surprising -- +# numpy.int corresponds to 'l' and numpy.long to 'q' +ctypedef npy_long int_t +ctypedef npy_longlong long_t +ctypedef npy_longlong longlong_t + +ctypedef npy_ulong uint_t +ctypedef npy_ulonglong ulong_t +ctypedef npy_ulonglong ulonglong_t + +ctypedef npy_intp intp_t +ctypedef npy_uintp uintp_t + +ctypedef npy_double float_t +ctypedef npy_double double_t +ctypedef npy_longdouble longdouble_t + +ctypedef npy_cfloat cfloat_t +ctypedef npy_cdouble cdouble_t +ctypedef npy_clongdouble clongdouble_t + +ctypedef npy_cdouble complex_t + +cdef inline object PyArray_MultiIterNew1(a): + return PyArray_MultiIterNew(1, a) + +cdef inline object PyArray_MultiIterNew2(a, b): + return PyArray_MultiIterNew(2, a, b) + +cdef inline object PyArray_MultiIterNew3(a, b, c): + return PyArray_MultiIterNew(3, a, b, c) + +cdef inline object PyArray_MultiIterNew4(a, b, c, d): + return PyArray_MultiIterNew(4, a, b, c, d) + +cdef inline object PyArray_MultiIterNew5(a, b, c, d, e): + return PyArray_MultiIterNew(5, a, b, c, d, e) + +cdef inline tuple PyDataType_SHAPE(dtype d): + if PyDataType_HASSUBARRAY(d): + return d.subarray.shape + else: + return () + + +cdef extern from "numpy/ndarrayobject.h": + PyTypeObject PyTimedeltaArrType_Type + PyTypeObject PyDatetimeArrType_Type + ctypedef int64_t npy_timedelta + ctypedef int64_t npy_datetime + +cdef extern from "numpy/ndarraytypes.h": + ctypedef struct PyArray_DatetimeMetaData: + NPY_DATETIMEUNIT base + int64_t num + +cdef extern from "numpy/arrayscalars.h": + + # abstract types + ctypedef class numpy.generic [object PyObject]: + pass + ctypedef class numpy.number [object PyObject]: + pass + ctypedef class numpy.integer [object PyObject]: + pass + ctypedef class numpy.signedinteger [object PyObject]: + pass + ctypedef class numpy.unsignedinteger [object PyObject]: + pass + ctypedef class numpy.inexact [object PyObject]: + pass + ctypedef class numpy.floating [object PyObject]: + pass + ctypedef class numpy.complexfloating [object PyObject]: + pass + ctypedef class numpy.flexible [object PyObject]: + pass + ctypedef class numpy.character [object PyObject]: + pass + + ctypedef struct PyDatetimeScalarObject: + # PyObject_HEAD + npy_datetime obval + PyArray_DatetimeMetaData obmeta + + ctypedef struct PyTimedeltaScalarObject: + # PyObject_HEAD + npy_timedelta obval + PyArray_DatetimeMetaData obmeta + + ctypedef enum NPY_DATETIMEUNIT: + NPY_FR_Y + NPY_FR_M + NPY_FR_W + NPY_FR_D + NPY_FR_B + NPY_FR_h + NPY_FR_m + NPY_FR_s + NPY_FR_ms + NPY_FR_us + NPY_FR_ns + NPY_FR_ps + NPY_FR_fs + NPY_FR_as + + +# +# ufunc API +# + +cdef extern from "numpy/ufuncobject.h": + + ctypedef void (*PyUFuncGenericFunction) (char **, npy_intp *, npy_intp *, void *) + + ctypedef class numpy.ufunc [object PyUFuncObject, check_size ignore]: + cdef: + int nin, nout, nargs + int identity + PyUFuncGenericFunction *functions + void **data + int ntypes + int check_return + char *name + char *types + char *doc + void *ptr + PyObject *obj + PyObject *userloops + + cdef enum: + PyUFunc_Zero + PyUFunc_One + PyUFunc_None + UFUNC_ERR_IGNORE + UFUNC_ERR_WARN + UFUNC_ERR_RAISE + UFUNC_ERR_CALL + UFUNC_ERR_PRINT + UFUNC_ERR_LOG + UFUNC_MASK_DIVIDEBYZERO + UFUNC_MASK_OVERFLOW + UFUNC_MASK_UNDERFLOW + UFUNC_MASK_INVALID + UFUNC_SHIFT_DIVIDEBYZERO + UFUNC_SHIFT_OVERFLOW + UFUNC_SHIFT_UNDERFLOW + UFUNC_SHIFT_INVALID + UFUNC_FPE_DIVIDEBYZERO + UFUNC_FPE_OVERFLOW + UFUNC_FPE_UNDERFLOW + UFUNC_FPE_INVALID + UFUNC_ERR_DEFAULT + UFUNC_ERR_DEFAULT2 + + object PyUFunc_FromFuncAndData(PyUFuncGenericFunction *, + void **, char *, int, int, int, int, char *, char *, int) + int PyUFunc_RegisterLoopForType(ufunc, int, + PyUFuncGenericFunction, int *, void *) + int PyUFunc_GenericFunction \ + (ufunc, PyObject *, PyObject *, PyArrayObject **) + void PyUFunc_f_f_As_d_d \ + (char **, npy_intp *, npy_intp *, void *) + void PyUFunc_d_d \ + (char **, npy_intp *, npy_intp *, void *) + void PyUFunc_f_f \ + (char **, npy_intp *, npy_intp *, void *) + void PyUFunc_g_g \ + (char **, npy_intp *, npy_intp *, void *) + void PyUFunc_F_F_As_D_D \ + (char **, npy_intp *, npy_intp *, void *) + void PyUFunc_F_F \ + (char **, npy_intp *, npy_intp *, void *) + void PyUFunc_D_D \ + (char **, npy_intp *, npy_intp *, void *) + void PyUFunc_G_G \ + (char **, npy_intp *, npy_intp *, void *) + void PyUFunc_O_O \ + (char **, npy_intp *, npy_intp *, void *) + void PyUFunc_ff_f_As_dd_d \ + (char **, npy_intp *, npy_intp *, void *) + void PyUFunc_ff_f \ + (char **, npy_intp *, npy_intp *, void *) + void PyUFunc_dd_d \ + (char **, npy_intp *, npy_intp *, void *) + void PyUFunc_gg_g \ + (char **, npy_intp *, npy_intp *, void *) + void PyUFunc_FF_F_As_DD_D \ + (char **, npy_intp *, npy_intp *, void *) + void PyUFunc_DD_D \ + (char **, npy_intp *, npy_intp *, void *) + void PyUFunc_FF_F \ + (char **, npy_intp *, npy_intp *, void *) + void PyUFunc_GG_G \ + (char **, npy_intp *, npy_intp *, void *) + void PyUFunc_OO_O \ + (char **, npy_intp *, npy_intp *, void *) + void PyUFunc_O_O_method \ + (char **, npy_intp *, npy_intp *, void *) + void PyUFunc_OO_O_method \ + (char **, npy_intp *, npy_intp *, void *) + void PyUFunc_On_Om \ + (char **, npy_intp *, npy_intp *, void *) + int PyUFunc_GetPyValues \ + (char *, int *, int *, PyObject **) + int PyUFunc_checkfperr \ + (int, PyObject *, int *) + void PyUFunc_clearfperr() + int PyUFunc_getfperr() + int PyUFunc_handlefperr \ + (int, PyObject *, int, int *) + int PyUFunc_ReplaceLoopBySignature \ + (ufunc, PyUFuncGenericFunction, int *, PyUFuncGenericFunction *) + object PyUFunc_FromFuncAndDataAndSignature \ + (PyUFuncGenericFunction *, void **, char *, int, int, int, + int, char *, char *, int, char *) + + int _import_umath() except -1 + +cdef inline void set_array_base(ndarray arr, object base): + Py_INCREF(base) # important to do this before stealing the reference below! + PyArray_SetBaseObject(arr, base) + +cdef inline object get_array_base(ndarray arr): + base = PyArray_BASE(arr) + if base is NULL: + return None + return base + +# Versions of the import_* functions which are more suitable for +# Cython code. +cdef inline int import_array() except -1: + try: + __pyx_import_array() + except Exception: + raise ImportError("numpy.core.multiarray failed to import") + +cdef inline int import_umath() except -1: + try: + _import_umath() + except Exception: + raise ImportError("numpy.core.umath failed to import") + +cdef inline int import_ufunc() except -1: + try: + _import_umath() + except Exception: + raise ImportError("numpy.core.umath failed to import") + +cdef extern from *: + # Leave a marker that the NumPy declarations came from this file + # See https://github.com/cython/cython/issues/3573 + """ + /* NumPy API declarations from "numpy/__init__.pxd" */ + """ + + +cdef inline bint is_timedelta64_object(object obj): + """ + Cython equivalent of `isinstance(obj, np.timedelta64)` + + Parameters + ---------- + obj : object + + Returns + ------- + bool + """ + return PyObject_TypeCheck(obj, &PyTimedeltaArrType_Type) + + +cdef inline bint is_datetime64_object(object obj): + """ + Cython equivalent of `isinstance(obj, np.datetime64)` + + Parameters + ---------- + obj : object + + Returns + ------- + bool + """ + return PyObject_TypeCheck(obj, &PyDatetimeArrType_Type) + + +cdef inline npy_datetime get_datetime64_value(object obj) nogil: + """ + returns the int64 value underlying scalar numpy datetime64 object + + Note that to interpret this as a datetime, the corresponding unit is + also needed. That can be found using `get_datetime64_unit`. + """ + return (obj).obval + + +cdef inline npy_timedelta get_timedelta64_value(object obj) nogil: + """ + returns the int64 value underlying scalar numpy timedelta64 object + """ + return (obj).obval + + +cdef inline NPY_DATETIMEUNIT get_datetime64_unit(object obj) nogil: + """ + returns the unit part of the dtype for a numpy datetime64 object. + """ + return (obj).obmeta.base diff --git a/venv/Lib/site-packages/numpy/__init__.py b/venv/Lib/site-packages/numpy/__init__.py new file mode 100644 index 0000000..6021e6d --- /dev/null +++ b/venv/Lib/site-packages/numpy/__init__.py @@ -0,0 +1,410 @@ +""" +NumPy +===== + +Provides + 1. An array object of arbitrary homogeneous items + 2. Fast mathematical operations over arrays + 3. Linear Algebra, Fourier Transforms, Random Number Generation + +How to use the documentation +---------------------------- +Documentation is available in two forms: docstrings provided +with the code, and a loose standing reference guide, available from +`the NumPy homepage `_. + +We recommend exploring the docstrings using +`IPython `_, an advanced Python shell with +TAB-completion and introspection capabilities. See below for further +instructions. + +The docstring examples assume that `numpy` has been imported as `np`:: + + >>> import numpy as np + +Code snippets are indicated by three greater-than signs:: + + >>> x = 42 + >>> x = x + 1 + +Use the built-in ``help`` function to view a function's docstring:: + + >>> help(np.sort) + ... # doctest: +SKIP + +For some objects, ``np.info(obj)`` may provide additional help. This is +particularly true if you see the line "Help on ufunc object:" at the top +of the help() page. Ufuncs are implemented in C, not Python, for speed. +The native Python help() does not know how to view their help, but our +np.info() function does. + +To search for documents containing a keyword, do:: + + >>> np.lookfor('keyword') + ... # doctest: +SKIP + +General-purpose documents like a glossary and help on the basic concepts +of numpy are available under the ``doc`` sub-module:: + + >>> from numpy import doc + >>> help(doc) + ... # doctest: +SKIP + +Available subpackages +--------------------- +doc + Topical documentation on broadcasting, indexing, etc. +lib + Basic functions used by several sub-packages. +random + Core Random Tools +linalg + Core Linear Algebra Tools +fft + Core FFT routines +polynomial + Polynomial tools +testing + NumPy testing tools +f2py + Fortran to Python Interface Generator. +distutils + Enhancements to distutils with support for + Fortran compilers support and more. + +Utilities +--------- +test + Run numpy unittests +show_config + Show numpy build configuration +dual + Overwrite certain functions with high-performance SciPy tools. + Note: `numpy.dual` is deprecated. Use the functions from NumPy or Scipy + directly instead of importing them from `numpy.dual`. +matlib + Make everything matrices. +__version__ + NumPy version string + +Viewing documentation using IPython +----------------------------------- +Start IPython with the NumPy profile (``ipython -p numpy``), which will +import `numpy` under the alias `np`. Then, use the ``cpaste`` command to +paste examples into the shell. To see which functions are available in +`numpy`, type ``np.`` (where ```` refers to the TAB key), or use +``np.*cos*?`` (where ```` refers to the ENTER key) to narrow +down the list. To view the docstring for a function, use +``np.cos?`` (to view the docstring) and ``np.cos??`` (to view +the source code). + +Copies vs. in-place operation +----------------------------- +Most of the functions in `numpy` return a copy of the array argument +(e.g., `np.sort`). In-place versions of these functions are often +available as array methods, i.e. ``x = np.array([1,2,3]); x.sort()``. +Exceptions to this rule are documented. + +""" +import sys +import warnings + +from ._globals import ModuleDeprecationWarning, VisibleDeprecationWarning +from ._globals import _NoValue + +# We first need to detect if we're being called as part of the numpy setup +# procedure itself in a reliable manner. +try: + __NUMPY_SETUP__ +except NameError: + __NUMPY_SETUP__ = False + +if __NUMPY_SETUP__: + sys.stderr.write('Running from numpy source directory.\n') +else: + try: + from numpy.__config__ import show as show_config + except ImportError as e: + msg = """Error importing numpy: you should not try to import numpy from + its source directory; please exit the numpy source tree, and relaunch + your python interpreter from there.""" + raise ImportError(msg) from e + + from .version import git_revision as __git_revision__ + from .version import version as __version__ + + __all__ = ['ModuleDeprecationWarning', + 'VisibleDeprecationWarning'] + + # mapping of {name: (value, deprecation_msg)} + __deprecated_attrs__ = {} + + # Allow distributors to run custom init code + from . import _distributor_init + + from . import core + from .core import * + from . import compat + from . import lib + # NOTE: to be revisited following future namespace cleanup. + # See gh-14454 and gh-15672 for discussion. + from .lib import * + + from . import linalg + from . import fft + from . import polynomial + from . import random + from . import ctypeslib + from . import ma + from . import matrixlib as _mat + from .matrixlib import * + + # Deprecations introduced in NumPy 1.20.0, 2020-06-06 + import builtins as _builtins + + _msg = ( + "`np.{n}` is a deprecated alias for the builtin `{n}`. " + "To silence this warning, use `{n}` by itself. Doing this will not " + "modify any behavior and is safe. {extended_msg}\n" + "Deprecated in NumPy 1.20; for more details and guidance: " + "https://numpy.org/devdocs/release/1.20.0-notes.html#deprecations") + + _specific_msg = ( + "If you specifically wanted the numpy scalar type, use `np.{}` here.") + + _int_extended_msg = ( + "When replacing `np.{}`, you may wish to use e.g. `np.int64` " + "or `np.int32` to specify the precision. If you wish to review " + "your current use, check the release note link for " + "additional information.") + + _type_info = [ + ("object", ""), # The NumPy scalar only exists by name. + ("bool", _specific_msg.format("bool_")), + ("float", _specific_msg.format("float64")), + ("complex", _specific_msg.format("complex128")), + ("str", _specific_msg.format("str_")), + ("int", _int_extended_msg.format("int"))] + + __deprecated_attrs__.update({ + n: (getattr(_builtins, n), _msg.format(n=n, extended_msg=extended_msg)) + for n, extended_msg in _type_info + }) + + _msg = ( + "`np.{n}` is a deprecated alias for `np.compat.{n}`. " + "To silence this warning, use `np.compat.{n}` by itself. " + "In the likely event your code does not need to work on Python 2 " + "you can use the builtin `{n2}` for which `np.compat.{n}` is itself " + "an alias. Doing this will not modify any behaviour and is safe. " + "{extended_msg}\n" + "Deprecated in NumPy 1.20; for more details and guidance: " + "https://numpy.org/devdocs/release/1.20.0-notes.html#deprecations") + + __deprecated_attrs__["long"] = ( + getattr(compat, "long"), + _msg.format(n="long", n2="int", + extended_msg=_int_extended_msg.format("long"))) + + __deprecated_attrs__["unicode"] = ( + getattr(compat, "unicode"), + _msg.format(n="unicode", n2="str", + extended_msg=_specific_msg.format("str_"))) + + del _msg, _specific_msg, _int_extended_msg, _type_info, _builtins + + from .core import round, abs, max, min + # now that numpy modules are imported, can initialize limits + core.getlimits._register_known_types() + + __all__.extend(['__version__', 'show_config']) + __all__.extend(core.__all__) + __all__.extend(_mat.__all__) + __all__.extend(lib.__all__) + __all__.extend(['linalg', 'fft', 'random', 'ctypeslib', 'ma']) + + # These are exported by np.core, but are replaced by the builtins below + # remove them to ensure that we don't end up with `np.long == np.int_`, + # which would be a breaking change. + del long, unicode + __all__.remove('long') + __all__.remove('unicode') + + # Remove things that are in the numpy.lib but not in the numpy namespace + # Note that there is a test (numpy/tests/test_public_api.py:test_numpy_namespace) + # that prevents adding more things to the main namespace by accident. + # The list below will grow until the `from .lib import *` fixme above is + # taken care of + __all__.remove('Arrayterator') + del Arrayterator + + # These names were removed in NumPy 1.20. For at least one release, + # attempts to access these names in the numpy namespace will trigger + # a warning, and calling the function will raise an exception. + _financial_names = ['fv', 'ipmt', 'irr', 'mirr', 'nper', 'npv', 'pmt', + 'ppmt', 'pv', 'rate'] + __expired_functions__ = { + name: (f'In accordance with NEP 32, the function {name} was removed ' + 'from NumPy version 1.20. A replacement for this function ' + 'is available in the numpy_financial library: ' + 'https://pypi.org/project/numpy-financial') + for name in _financial_names} + + # Filter out Cython harmless warnings + warnings.filterwarnings("ignore", message="numpy.dtype size changed") + warnings.filterwarnings("ignore", message="numpy.ufunc size changed") + warnings.filterwarnings("ignore", message="numpy.ndarray size changed") + + # oldnumeric and numarray were removed in 1.9. In case some packages import + # but do not use them, we define them here for backward compatibility. + oldnumeric = 'removed' + numarray = 'removed' + + if sys.version_info[:2] >= (3, 7): + # module level getattr is only supported in 3.7 onwards + # https://www.python.org/dev/peps/pep-0562/ + def __getattr__(attr): + # Warn for expired attributes, and return a dummy function + # that always raises an exception. + try: + msg = __expired_functions__[attr] + except KeyError: + pass + else: + warnings.warn(msg, DeprecationWarning, stacklevel=2) + + def _expired(*args, **kwds): + raise RuntimeError(msg) + + return _expired + + # Emit warnings for deprecated attributes + try: + val, msg = __deprecated_attrs__[attr] + except KeyError: + pass + else: + warnings.warn(msg, DeprecationWarning, stacklevel=2) + return val + + # Importing Tester requires importing all of UnitTest which is not a + # cheap import Since it is mainly used in test suits, we lazy import it + # here to save on the order of 10 ms of import time for most users + # + # The previous way Tester was imported also had a side effect of adding + # the full `numpy.testing` namespace + if attr == 'testing': + import numpy.testing as testing + return testing + elif attr == 'Tester': + from .testing import Tester + return Tester + + raise AttributeError("module {!r} has no attribute " + "{!r}".format(__name__, attr)) + + def __dir__(): + return list(globals().keys() | {'Tester', 'testing'}) + + else: + # We don't actually use this ourselves anymore, but I'm not 100% sure that + # no-one else in the world is using it (though I hope not) + from .testing import Tester + + # We weren't able to emit a warning about these, so keep them around + globals().update({ + k: v + for k, (v, msg) in __deprecated_attrs__.items() + }) + + + # Pytest testing + from numpy._pytesttester import PytestTester + test = PytestTester(__name__) + del PytestTester + + + def _sanity_check(): + """ + Quick sanity checks for common bugs caused by environment. + There are some cases e.g. with wrong BLAS ABI that cause wrong + results under specific runtime conditions that are not necessarily + achieved during test suite runs, and it is useful to catch those early. + + See https://github.com/numpy/numpy/issues/8577 and other + similar bug reports. + + """ + try: + x = ones(2, dtype=float32) + if not abs(x.dot(x) - 2.0) < 1e-5: + raise AssertionError() + except AssertionError: + msg = ("The current Numpy installation ({!r}) fails to " + "pass simple sanity checks. This can be caused for example " + "by incorrect BLAS library being linked in, or by mixing " + "package managers (pip, conda, apt, ...). Search closed " + "numpy issues for similar problems.") + raise RuntimeError(msg.format(__file__)) from None + + _sanity_check() + del _sanity_check + + def _mac_os_check(): + """ + Quick Sanity check for Mac OS look for accelerate build bugs. + Testing numpy polyfit calls init_dgelsd(LAPACK) + """ + try: + c = array([3., 2., 1.]) + x = linspace(0, 2, 5) + y = polyval(c, x) + _ = polyfit(x, y, 2, cov=True) + except ValueError: + pass + + import sys + if sys.platform == "darwin": + with warnings.catch_warnings(record=True) as w: + _mac_os_check() + # Throw runtime error, if the test failed Check for warning and error_message + error_message = "" + if len(w) > 0: + error_message = "{}: {}".format(w[-1].category.__name__, str(w[-1].message)) + msg = ( + "Polyfit sanity test emitted a warning, most likely due " + "to using a buggy Accelerate backend. If you compiled " + "yourself, more information is available at " + "https://numpy.org/doc/stable/user/building.html#accelerated-blas-lapack-libraries " + "Otherwise report this to the vendor " + "that provided NumPy.\n{}\n".format(error_message)) + raise RuntimeError(msg) + del _mac_os_check + + # We usually use madvise hugepages support, but on some old kernels it + # is slow and thus better avoided. + # Specifically kernel version 4.6 had a bug fix which probably fixed this: + # https://github.com/torvalds/linux/commit/7cf91a98e607c2f935dbcc177d70011e95b8faff + import os + use_hugepage = os.environ.get("NUMPY_MADVISE_HUGEPAGE", None) + if sys.platform == "linux" and use_hugepage is None: + # If there is an issue with parsing the kernel version, + # set use_hugepages to 0. Usage of LooseVersion will handle + # the kernel version parsing better, but avoided since it + # will increase the import time. See: #16679 for related discussion. + try: + use_hugepage = 1 + kernel_version = os.uname().release.split(".")[:2] + kernel_version = tuple(int(v) for v in kernel_version) + if kernel_version < (4, 6): + use_hugepage = 0 + except ValueError: + use_hugepages = 0 + elif use_hugepage is None: + # This is not Linux, so it should not matter, just enable anyway + use_hugepage = 1 + else: + use_hugepage = int(use_hugepage) + + # Note that this will currently only make a difference on Linux + core.multiarray._set_madvise_hugepage(use_hugepage) diff --git a/venv/Lib/site-packages/numpy/__init__.pyi b/venv/Lib/site-packages/numpy/__init__.pyi new file mode 100644 index 0000000..d275ad2 --- /dev/null +++ b/venv/Lib/site-packages/numpy/__init__.pyi @@ -0,0 +1,2277 @@ +import builtins +import sys +import datetime as dt +from abc import abstractmethod +from types import TracebackType +from contextlib import ContextDecorator + +from numpy.core._internal import _ctypes +from numpy.typing import ( + ArrayLike, + DTypeLike, + _Shape, + _ShapeLike, + _CharLike, + _BoolLike, + _IntLike, + _FloatLike, + _ComplexLike, + _NumberLike, + _SupportsDType, + _VoidDTypeLike, + NBitBase, + _64Bit, + _32Bit, + _16Bit, + _8Bit, +) +from numpy.typing._callable import ( + _BoolOp, + _BoolBitOp, + _BoolSub, + _BoolTrueDiv, + _BoolMod, + _BoolDivMod, + _TD64Div, + _IntTrueDiv, + _UnsignedIntOp, + _UnsignedIntBitOp, + _UnsignedIntMod, + _UnsignedIntDivMod, + _SignedIntOp, + _SignedIntBitOp, + _SignedIntMod, + _SignedIntDivMod, + _FloatOp, + _FloatMod, + _FloatDivMod, + _ComplexOp, + _NumberOp, +) + +from typing import ( + Any, + ByteString, + Callable, + Container, + Callable, + Dict, + Generic, + IO, + Iterable, + List, + Mapping, + Optional, + overload, + Sequence, + Sized, + SupportsComplex, + SupportsFloat, + SupportsInt, + Text, + Tuple, + Type, + TypeVar, + Union, +) + +if sys.version_info >= (3, 8): + from typing import Literal, Protocol, SupportsIndex, Final +else: + from typing_extensions import Literal, Protocol, Final + class SupportsIndex(Protocol): + def __index__(self) -> int: ... + +# Ensures that the stubs are picked up +from numpy import ( + char, + ctypeslib, + emath, + fft, + lib, + linalg, + ma, + matrixlib, + polynomial, + random, + rec, + testing, + version, +) + +from numpy.core.function_base import ( + linspace, + logspace, + geomspace, +) + +from numpy.core.fromnumeric import ( + take, + reshape, + choose, + repeat, + put, + swapaxes, + transpose, + partition, + argpartition, + sort, + argsort, + argmax, + argmin, + searchsorted, + resize, + squeeze, + diagonal, + trace, + ravel, + nonzero, + shape, + compress, + clip, + sum, + all, + any, + cumsum, + ptp, + amax, + amin, + prod, + cumprod, + ndim, + size, + around, + mean, + std, + var, +) + +from numpy.core._asarray import ( + asarray as asarray, + asanyarray as asanyarray, + ascontiguousarray as ascontiguousarray, + asfortranarray as asfortranarray, + require as require, +) + +from numpy.core._type_aliases import ( + sctypes as sctypes, + sctypeDict as sctypeDict, +) + +from numpy.core._ufunc_config import ( + seterr as seterr, + geterr as geterr, + setbufsize as setbufsize, + getbufsize as getbufsize, + seterrcall as seterrcall, + geterrcall as geterrcall, + _SupportsWrite, + _ErrKind, + _ErrFunc, + _ErrDictOptional, +) + +from numpy.core.numeric import ( + zeros_like as zeros_like, + ones as ones, + ones_like as ones_like, + empty_like as empty_like, + full as full, + full_like as full_like, + count_nonzero as count_nonzero, + isfortran as isfortran, + argwhere as argwhere, + flatnonzero as flatnonzero, + correlate as correlate, + convolve as convolve, + outer as outer, + tensordot as tensordot, + roll as roll, + rollaxis as rollaxis, + moveaxis as moveaxis, + cross as cross, + indices as indices, + fromfunction as fromfunction, + isscalar as isscalar, + binary_repr as binary_repr, + base_repr as base_repr, + identity as identity, + allclose as allclose, + isclose as isclose, + array_equal as array_equal, + array_equiv as array_equiv, +) + +from numpy.core.numerictypes import ( + maximum_sctype as maximum_sctype, + issctype as issctype, + obj2sctype as obj2sctype, + issubclass_ as issubclass_, + issubsctype as issubsctype, + issubdtype as issubdtype, + sctype2char as sctype2char, + find_common_type as find_common_type, +) + +from numpy.core.shape_base import ( + atleast_1d as atleast_1d, + atleast_2d as atleast_2d, + atleast_3d as atleast_3d, + block as block, + hstack as hstack, + stack as stack, + vstack as vstack, +) + +# Add an object to `__all__` if their stubs are defined in an external file; +# their stubs will not be recognized otherwise. +# NOTE: This is redundant for objects defined within this file. +__all__ = [ + "linspace", + "logspace", + "geomspace", + "take", + "reshape", + "choose", + "repeat", + "put", + "swapaxes", + "transpose", + "partition", + "argpartition", + "sort", + "argsort", + "argmax", + "argmin", + "searchsorted", + "resize", + "squeeze", + "diagonal", + "trace", + "ravel", + "nonzero", + "shape", + "compress", + "clip", + "sum", + "all", + "any", + "cumsum", + "ptp", + "amax", + "amin", + "prod", + "cumprod", + "ndim", + "size", + "around", + "mean", + "std", + "var", +] + +__path__: List[str] +__version__: str + +DataSource: Any +MachAr: Any +ScalarType: Any +angle: Any +append: Any +apply_along_axis: Any +apply_over_axes: Any +arange: Any +array2string: Any +array_repr: Any +array_split: Any +array_str: Any +asarray_chkfinite: Any +asfarray: Any +asmatrix: Any +asscalar: Any +average: Any +bartlett: Any +bincount: Any +bitwise_not: Any +blackman: Any +bmat: Any +bool8: Any +broadcast: Any +broadcast_arrays: Any +broadcast_to: Any +busday_count: Any +busday_offset: Any +busdaycalendar: Any +byte: Any +byte_bounds: Any +bytes0: Any +c_: Any +can_cast: Any +cast: Any +cdouble: Any +cfloat: Any +chararray: Any +clongdouble: Any +clongfloat: Any +column_stack: Any +common_type: Any +compare_chararrays: Any +complex256: Any +complex_: Any +concatenate: Any +conj: Any +copy: Any +copyto: Any +corrcoef: Any +cov: Any +csingle: Any +cumproduct: Any +datetime_as_string: Any +datetime_data: Any +delete: Any +deprecate: Any +deprecate_with_doc: Any +diag: Any +diag_indices: Any +diag_indices_from: Any +diagflat: Any +diff: Any +digitize: Any +disp: Any +divide: Any +dot: Any +double: Any +dsplit: Any +dstack: Any +ediff1d: Any +einsum: Any +einsum_path: Any +expand_dims: Any +extract: Any +eye: Any +fill_diagonal: Any +finfo: Any +fix: Any +flip: Any +fliplr: Any +flipud: Any +float128: Any +float_: Any +format_float_positional: Any +format_float_scientific: Any +format_parser: Any +frombuffer: Any +fromfile: Any +fromiter: Any +frompyfunc: Any +fromregex: Any +fromstring: Any +genfromtxt: Any +get_include: Any +get_printoptions: Any +geterrobj: Any +gradient: Any +half: Any +hamming: Any +hanning: Any +histogram: Any +histogram2d: Any +histogram_bin_edges: Any +histogramdd: Any +hsplit: Any +i0: Any +iinfo: Any +imag: Any +in1d: Any +index_exp: Any +info: Any +inner: Any +insert: Any +int0: Any +int_: Any +intc: Any +interp: Any +intersect1d: Any +intp: Any +is_busday: Any +iscomplex: Any +iscomplexobj: Any +isin: Any +isneginf: Any +isposinf: Any +isreal: Any +isrealobj: Any +iterable: Any +ix_: Any +kaiser: Any +kron: Any +lexsort: Any +load: Any +loads: Any +loadtxt: Any +longcomplex: Any +longdouble: Any +longfloat: Any +longlong: Any +lookfor: Any +mafromtxt: Any +mask_indices: Any +mat: Any +matrix: Any +max: Any +may_share_memory: Any +median: Any +memmap: Any +meshgrid: Any +mgrid: Any +min: Any +min_scalar_type: Any +mintypecode: Any +mod: Any +msort: Any +nan_to_num: Any +nanargmax: Any +nanargmin: Any +nancumprod: Any +nancumsum: Any +nanmax: Any +nanmean: Any +nanmedian: Any +nanmin: Any +nanpercentile: Any +nanprod: Any +nanquantile: Any +nanstd: Any +nansum: Any +nanvar: Any +nbytes: Any +ndenumerate: Any +ndfromtxt: Any +ndindex: Any +nditer: Any +nested_iters: Any +newaxis: Any +numarray: Any +object0: Any +ogrid: Any +packbits: Any +pad: Any +percentile: Any +piecewise: Any +place: Any +poly: Any +poly1d: Any +polyadd: Any +polyder: Any +polydiv: Any +polyfit: Any +polyint: Any +polymul: Any +polysub: Any +polyval: Any +printoptions: Any +product: Any +promote_types: Any +put_along_axis: Any +putmask: Any +quantile: Any +r_: Any +ravel_multi_index: Any +real: Any +real_if_close: Any +recarray: Any +recfromcsv: Any +recfromtxt: Any +record: Any +result_type: Any +roots: Any +rot90: Any +round: Any +round_: Any +row_stack: Any +s_: Any +save: Any +savetxt: Any +savez: Any +savez_compressed: Any +select: Any +set_printoptions: Any +set_string_function: Any +setdiff1d: Any +seterrobj: Any +setxor1d: Any +shares_memory: Any +short: Any +show_config: Any +sinc: Any +single: Any +singlecomplex: Any +sort_complex: Any +source: Any +split: Any +string_: Any +take_along_axis: Any +tile: Any +trapz: Any +tri: Any +tril: Any +tril_indices: Any +tril_indices_from: Any +trim_zeros: Any +triu: Any +triu_indices: Any +triu_indices_from: Any +typeDict: Any +typecodes: Any +typename: Any +ubyte: Any +uint: Any +uint0: Any +uintc: Any +uintp: Any +ulonglong: Any +union1d: Any +unique: Any +unpackbits: Any +unravel_index: Any +unwrap: Any +ushort: Any +vander: Any +vdot: Any +vectorize: Any +void0: Any +vsplit: Any +where: Any +who: Any + +_NdArraySubClass = TypeVar("_NdArraySubClass", bound=ndarray) +_DTypeScalar = TypeVar("_DTypeScalar", bound=generic) +_ByteOrder = Literal["S", "<", ">", "=", "|", "L", "B", "N", "I"] + +class dtype(Generic[_DTypeScalar]): + names: Optional[Tuple[str, ...]] + # Overload for subclass of generic + @overload + def __new__( + cls, + dtype: Type[_DTypeScalar], + align: bool = ..., + copy: bool = ..., + ) -> dtype[_DTypeScalar]: ... + # Overloads for string aliases, Python types, and some assorted + # other special cases. Order is sometimes important because of the + # subtype relationships + # + # bool < int < float < complex + # + # so we have to make sure the overloads for the narrowest type is + # first. + @overload + def __new__( + cls, + dtype: Union[ + Type[bool], + Literal[ + "?", + "=?", + "?", + "bool", + "bool_", + ], + ], + align: bool = ..., + copy: bool = ..., + ) -> dtype[bool_]: ... + @overload + def __new__( + cls, + dtype: Literal[ + "uint8", + "u1", + "=u1", + "u1", + ], + align: bool = ..., + copy: bool = ..., + ) -> dtype[uint8]: ... + @overload + def __new__( + cls, + dtype: Literal[ + "uint16", + "u2", + "=u2", + "u2", + ], + align: bool = ..., + copy: bool = ..., + ) -> dtype[uint16]: ... + @overload + def __new__( + cls, + dtype: Literal[ + "uint32", + "u4", + "=u4", + "u4", + ], + align: bool = ..., + copy: bool = ..., + ) -> dtype[uint32]: ... + @overload + def __new__( + cls, + dtype: Literal[ + "uint64", + "u8", + "=u8", + "u8", + ], + align: bool = ..., + copy: bool = ..., + ) -> dtype[uint64]: ... + @overload + def __new__( + cls, + dtype: Literal[ + "int8", + "i1", + "=i1", + "i1", + ], + align: bool = ..., + copy: bool = ..., + ) -> dtype[int8]: ... + @overload + def __new__( + cls, + dtype: Literal[ + "int16", + "i2", + "=i2", + "i2", + ], + align: bool = ..., + copy: bool = ..., + ) -> dtype[int16]: ... + @overload + def __new__( + cls, + dtype: Literal[ + "int32", + "i4", + "=i4", + "i4", + ], + align: bool = ..., + copy: bool = ..., + ) -> dtype[int32]: ... + @overload + def __new__( + cls, + dtype: Literal[ + "int64", + "i8", + "=i8", + "i8", + ], + align: bool = ..., + copy: bool = ..., + ) -> dtype[int64]: ... + # "int"/int resolve to int_, which is system dependent and as of + # now untyped. Long-term we'll do something fancier here. + @overload + def __new__( + cls, + dtype: Union[Type[int], Literal["int"]], + align: bool = ..., + copy: bool = ..., + ) -> dtype: ... + @overload + def __new__( + cls, + dtype: Literal[ + "float16", + "f4", + "=f4", + "f4", + "e", + "=e", + "e", + "half", + ], + align: bool = ..., + copy: bool = ..., + ) -> dtype[float16]: ... + @overload + def __new__( + cls, + dtype: Literal[ + "float32", + "f4", + "=f4", + "f4", + "f", + "=f", + "f", + "single", + ], + align: bool = ..., + copy: bool = ..., + ) -> dtype[float32]: ... + @overload + def __new__( + cls, + dtype: Union[ + None, + Type[float], + Literal[ + "float64", + "f8", + "=f8", + "f8", + "d", + "d", + "float", + "double", + "float_", + ], + ], + align: bool = ..., + copy: bool = ..., + ) -> dtype[float64]: ... + @overload + def __new__( + cls, + dtype: Literal[ + "complex64", + "c8", + "=c8", + "c8", + "F", + "=F", + "F", + ], + align: bool = ..., + copy: bool = ..., + ) -> dtype[complex64]: ... + @overload + def __new__( + cls, + dtype: Union[ + Type[complex], + Literal[ + "complex128", + "c16", + "=c16", + "c16", + "D", + "=D", + "D", + ], + ], + align: bool = ..., + copy: bool = ..., + ) -> dtype[complex128]: ... + @overload + def __new__( + cls, + dtype: Union[ + Type[bytes], + Literal[ + "S", + "=S", + "S", + "bytes", + "bytes_", + "bytes0", + ], + ], + align: bool = ..., + copy: bool = ..., + ) -> dtype[bytes_]: ... + @overload + def __new__( + cls, + dtype: Union[ + Type[str], + Literal[ + "U", + "=U", + # U intentionally not included; they are not + # the same dtype and which one dtype("U") translates + # to is platform-dependent. + "str", + "str_", + "str0", + ], + ], + align: bool = ..., + copy: bool = ..., + ) -> dtype[str_]: ... + # dtype of a dtype is the same dtype + @overload + def __new__( + cls, + dtype: dtype[_DTypeScalar], + align: bool = ..., + copy: bool = ..., + ) -> dtype[_DTypeScalar]: ... + # TODO: handle _SupportsDType better + @overload + def __new__( + cls, + dtype: _SupportsDType, + align: bool = ..., + copy: bool = ..., + ) -> dtype[Any]: ... + # Handle strings that can't be expressed as literals; i.e. s1, s2, ... + @overload + def __new__( + cls, + dtype: str, + align: bool = ..., + copy: bool = ..., + ) -> dtype[Any]: ... + # Catchall overload + @overload + def __new__( + cls, + dtype: _VoidDTypeLike, + align: bool = ..., + copy: bool = ..., + ) -> dtype[void]: ... + + @overload + def __getitem__(self: dtype[void], key: List[str]) -> dtype[void]: ... + @overload + def __getitem__(self: dtype[void], key: Union[str, int]) -> dtype[Any]: ... + + # NOTE: In the future 1-based multiplications will also yield `void` dtypes + @overload + def __mul__(self, value: Literal[0]) -> None: ... # type: ignore[misc] + @overload + def __mul__(self, value: Literal[1]) -> dtype[_DTypeScalar]: ... + @overload + def __mul__(self, value: int) -> dtype[void]: ... + + # NOTE: `__rmul__` seems to be broken when used in combination with + # literals as of mypy 0.800. Set the return-type to `Any` for now. + def __rmul__(self, value: int) -> Any: ... + + def __eq__(self, other: DTypeLike) -> bool: ... + def __ne__(self, other: DTypeLike) -> bool: ... + def __gt__(self, other: DTypeLike) -> bool: ... + def __ge__(self, other: DTypeLike) -> bool: ... + def __lt__(self, other: DTypeLike) -> bool: ... + def __le__(self, other: DTypeLike) -> bool: ... + @property + def alignment(self) -> int: ... + @property + def base(self) -> dtype: ... + @property + def byteorder(self) -> str: ... + @property + def char(self) -> str: ... + @property + def descr(self) -> List[Union[Tuple[str, str], Tuple[str, str, _Shape]]]: ... + @property + def fields( + self, + ) -> Optional[Mapping[str, Union[Tuple[dtype, int], Tuple[dtype, int, Any]]]]: ... + @property + def flags(self) -> int: ... + @property + def hasobject(self) -> bool: ... + @property + def isbuiltin(self) -> int: ... + @property + def isnative(self) -> bool: ... + @property + def isalignedstruct(self) -> bool: ... + @property + def itemsize(self) -> int: ... + @property + def kind(self) -> str: ... + @property + def metadata(self) -> Optional[Mapping[str, Any]]: ... + @property + def name(self) -> str: ... + @property + def names(self) -> Optional[Tuple[str, ...]]: ... + @property + def num(self) -> int: ... + @property + def shape(self) -> _Shape: ... + @property + def ndim(self) -> int: ... + @property + def subdtype(self) -> Optional[Tuple[dtype, _Shape]]: ... + def newbyteorder(self, __new_order: _ByteOrder = ...) -> dtype: ... + # Leave str and type for end to avoid having to use `builtins.str` + # everywhere. See https://github.com/python/mypy/issues/3775 + @property + def str(self) -> builtins.str: ... + @property + def type(self) -> Type[generic]: ... + +_DType = dtype # to avoid name conflicts with ndarray.dtype + +class _flagsobj: + aligned: bool + updateifcopy: bool + writeable: bool + writebackifcopy: bool + @property + def behaved(self) -> bool: ... + @property + def c_contiguous(self) -> bool: ... + @property + def carray(self) -> bool: ... + @property + def contiguous(self) -> bool: ... + @property + def f_contiguous(self) -> bool: ... + @property + def farray(self) -> bool: ... + @property + def fnc(self) -> bool: ... + @property + def forc(self) -> bool: ... + @property + def fortran(self) -> bool: ... + @property + def num(self) -> int: ... + @property + def owndata(self) -> bool: ... + def __getitem__(self, key: str) -> bool: ... + def __setitem__(self, key: str, value: bool) -> None: ... + +_ArrayLikeInt = Union[ + int, + integer, + Sequence[Union[int, integer]], + Sequence[Sequence[Any]], # TODO: wait for support for recursive types + ndarray +] + +_FlatIterSelf = TypeVar("_FlatIterSelf", bound=flatiter) + +class flatiter(Generic[_ArraySelf]): + @property + def base(self) -> _ArraySelf: ... + @property + def coords(self) -> _Shape: ... + @property + def index(self) -> int: ... + def copy(self) -> _ArraySelf: ... + def __iter__(self: _FlatIterSelf) -> _FlatIterSelf: ... + def __next__(self) -> generic: ... + def __len__(self) -> int: ... + @overload + def __getitem__(self, key: Union[int, integer]) -> generic: ... + @overload + def __getitem__( + self, key: Union[_ArrayLikeInt, slice, ellipsis], + ) -> _ArraySelf: ... + def __array__(self, __dtype: DTypeLike = ...) -> ndarray: ... + +_OrderKACF = Optional[Literal["K", "A", "C", "F"]] +_OrderACF = Optional[Literal["A", "C", "F"]] +_OrderCF = Optional[Literal["C", "F"]] + +_ModeKind = Literal["raise", "wrap", "clip"] +_PartitionKind = Literal["introselect"] +_SortKind = Literal["quicksort", "mergesort", "heapsort", "stable"] +_SortSide = Literal["left", "right"] + +_ArrayLikeBool = Union[_BoolLike, Sequence[_BoolLike], ndarray] +_ArrayLikeIntOrBool = Union[ + _IntLike, + _BoolLike, + ndarray, + Sequence[_IntLike], + Sequence[_BoolLike], + Sequence[Sequence[Any]], # TODO: wait for support for recursive types +] + +_ArraySelf = TypeVar("_ArraySelf", bound=_ArrayOrScalarCommon) + +class _ArrayOrScalarCommon: + @property + def T(self: _ArraySelf) -> _ArraySelf: ... + @property + def data(self) -> memoryview: ... + @property + def flags(self) -> _flagsobj: ... + @property + def itemsize(self) -> int: ... + @property + def nbytes(self) -> int: ... + def __array__(self, __dtype: DTypeLike = ...) -> ndarray: ... + def __bool__(self) -> bool: ... + def __bytes__(self) -> bytes: ... + def __str__(self) -> str: ... + def __repr__(self) -> str: ... + def __copy__(self: _ArraySelf) -> _ArraySelf: ... + def __deepcopy__(self: _ArraySelf, __memo: Optional[dict] = ...) -> _ArraySelf: ... + def __lt__(self, other): ... + def __le__(self, other): ... + def __eq__(self, other): ... + def __ne__(self, other): ... + def __gt__(self, other): ... + def __ge__(self, other): ... + def astype( + self: _ArraySelf, + dtype: DTypeLike, + order: _OrderKACF = ..., + casting: _Casting = ..., + subok: bool = ..., + copy: bool = ..., + ) -> _ArraySelf: ... + def copy(self: _ArraySelf, order: _OrderKACF = ...) -> _ArraySelf: ... + def dump(self, file: str) -> None: ... + def dumps(self) -> bytes: ... + def flatten(self, order: _OrderKACF = ...) -> ndarray: ... + def getfield( + self: _ArraySelf, dtype: DTypeLike, offset: int = ... + ) -> _ArraySelf: ... + def ravel(self, order: _OrderKACF = ...) -> ndarray: ... + @overload + def reshape( + self, __shape: Sequence[int], *, order: _OrderACF = ... + ) -> ndarray: ... + @overload + def reshape( + self, *shape: int, order: _OrderACF = ... + ) -> ndarray: ... + def tobytes(self, order: _OrderKACF = ...) -> bytes: ... + # NOTE: `tostring()` is deprecated and therefore excluded + # def tostring(self, order=...): ... + def tofile( + self, fid: Union[IO[bytes], str], sep: str = ..., format: str = ... + ) -> None: ... + # generics and 0d arrays return builtin scalars + def tolist(self) -> Any: ... + @overload + def view(self, type: Type[_NdArraySubClass]) -> _NdArraySubClass: ... + @overload + def view(self: _ArraySelf, dtype: DTypeLike = ...) -> _ArraySelf: ... + @overload + def view( + self, dtype: DTypeLike, type: Type[_NdArraySubClass] + ) -> _NdArraySubClass: ... + + # TODO: Add proper signatures + def __getitem__(self, key) -> Any: ... + @property + def __array_interface__(self): ... + @property + def __array_priority__(self): ... + @property + def __array_struct__(self): ... + def __array_wrap__(array, context=...): ... + def __setstate__(self, __state): ... + # a `bool_` is returned when `keepdims=True` and `self` is a 0d array + @overload + def all( + self, axis: None = ..., out: None = ..., keepdims: Literal[False] = ... + ) -> bool_: ... + @overload + def all( + self, axis: Optional[_ShapeLike] = ..., out: None = ..., keepdims: bool = ... + ) -> Union[bool_, ndarray]: ... + @overload + def all( + self, + axis: Optional[_ShapeLike] = ..., + out: _NdArraySubClass = ..., + keepdims: bool = ..., + ) -> _NdArraySubClass: ... + @overload + def any( + self, axis: None = ..., out: None = ..., keepdims: Literal[False] = ... + ) -> bool_: ... + @overload + def any( + self, axis: Optional[_ShapeLike] = ..., out: None = ..., keepdims: bool = ... + ) -> Union[bool_, ndarray]: ... + @overload + def any( + self, + axis: Optional[_ShapeLike] = ..., + out: _NdArraySubClass = ..., + keepdims: bool = ..., + ) -> _NdArraySubClass: ... + @overload + def argmax(self, axis: None = ..., out: None = ...) -> signedinteger: ... + @overload + def argmax( + self, axis: _ShapeLike = ..., out: None = ... + ) -> Union[signedinteger, ndarray]: ... + @overload + def argmax( + self, axis: Optional[_ShapeLike] = ..., out: _NdArraySubClass = ... + ) -> _NdArraySubClass: ... + @overload + def argmin(self, axis: None = ..., out: None = ...) -> signedinteger: ... + @overload + def argmin( + self, axis: _ShapeLike = ..., out: None = ... + ) -> Union[signedinteger, ndarray]: ... + @overload + def argmin( + self, axis: Optional[_ShapeLike] = ..., out: _NdArraySubClass = ... + ) -> _NdArraySubClass: ... + def argsort( + self, + axis: Optional[int] = ..., + kind: Optional[_SortKind] = ..., + order: Union[None, str, Sequence[str]] = ..., + ) -> ndarray: ... + @overload + def choose( + self, choices: ArrayLike, out: None = ..., mode: _ModeKind = ..., + ) -> ndarray: ... + @overload + def choose( + self, choices: ArrayLike, out: _NdArraySubClass = ..., mode: _ModeKind = ..., + ) -> _NdArraySubClass: ... + @overload + def clip( + self, + min: ArrayLike = ..., + max: Optional[ArrayLike] = ..., + out: None = ..., + **kwargs: Any, + ) -> Union[number, ndarray]: ... + @overload + def clip( + self, + min: None = ..., + max: ArrayLike = ..., + out: None = ..., + **kwargs: Any, + ) -> Union[number, ndarray]: ... + @overload + def clip( + self, + min: ArrayLike = ..., + max: Optional[ArrayLike] = ..., + out: _NdArraySubClass = ..., + **kwargs: Any, + ) -> _NdArraySubClass: ... + @overload + def clip( + self, + min: None = ..., + max: ArrayLike = ..., + out: _NdArraySubClass = ..., + **kwargs: Any, + ) -> _NdArraySubClass: ... + @overload + def compress( + self, a: ArrayLike, axis: Optional[int] = ..., out: None = ..., + ) -> ndarray: ... + @overload + def compress( + self, a: ArrayLike, axis: Optional[int] = ..., out: _NdArraySubClass = ..., + ) -> _NdArraySubClass: ... + def conj(self: _ArraySelf) -> _ArraySelf: ... + def conjugate(self: _ArraySelf) -> _ArraySelf: ... + @overload + def cumprod( + self, axis: Optional[int] = ..., dtype: DTypeLike = ..., out: None = ..., + ) -> ndarray: ... + @overload + def cumprod( + self, + axis: Optional[int] = ..., + dtype: DTypeLike = ..., + out: _NdArraySubClass = ..., + ) -> _NdArraySubClass: ... + @overload + def cumsum( + self, axis: Optional[int] = ..., dtype: DTypeLike = ..., out: None = ..., + ) -> ndarray: ... + @overload + def cumsum( + self, + axis: Optional[int] = ..., + dtype: DTypeLike = ..., + out: _NdArraySubClass = ..., + ) -> _NdArraySubClass: ... + @overload + def max( + self, + axis: None = ..., + out: None = ..., + keepdims: Literal[False] = ..., + initial: _NumberLike = ..., + where: _ArrayLikeBool = ..., + ) -> number: ... + @overload + def max( + self, + axis: Optional[_ShapeLike] = ..., + out: None = ..., + keepdims: bool = ..., + initial: _NumberLike = ..., + where: _ArrayLikeBool = ..., + ) -> Union[number, ndarray]: ... + @overload + def max( + self, + axis: Optional[_ShapeLike] = ..., + out: _NdArraySubClass = ..., + keepdims: bool = ..., + initial: _NumberLike = ..., + where: _ArrayLikeBool = ..., + ) -> _NdArraySubClass: ... + @overload + def mean( + self, + axis: None = ..., + dtype: DTypeLike = ..., + out: None = ..., + keepdims: Literal[False] = ..., + ) -> number: ... + @overload + def mean( + self, + axis: Optional[_ShapeLike] = ..., + dtype: DTypeLike = ..., + out: None = ..., + keepdims: bool = ..., + ) -> Union[number, ndarray]: ... + @overload + def mean( + self, + axis: Optional[_ShapeLike] = ..., + dtype: DTypeLike = ..., + out: _NdArraySubClass = ..., + keepdims: bool = ..., + ) -> _NdArraySubClass: ... + @overload + def min( + self, + axis: None = ..., + out: None = ..., + keepdims: Literal[False] = ..., + initial: _NumberLike = ..., + where: _ArrayLikeBool = ..., + ) -> number: ... + @overload + def min( + self, + axis: Optional[_ShapeLike] = ..., + out: None = ..., + keepdims: bool = ..., + initial: _NumberLike = ..., + where: _ArrayLikeBool = ..., + ) -> Union[number, ndarray]: ... + @overload + def min( + self, + axis: Optional[_ShapeLike] = ..., + out: _NdArraySubClass = ..., + keepdims: bool = ..., + initial: _NumberLike = ..., + where: _ArrayLikeBool = ..., + ) -> _NdArraySubClass: ... + def newbyteorder(self: _ArraySelf, __new_order: _ByteOrder = ...) -> _ArraySelf: ... + @overload + def prod( + self, + axis: None = ..., + dtype: DTypeLike = ..., + out: None = ..., + keepdims: Literal[False] = ..., + initial: _NumberLike = ..., + where: _ArrayLikeBool = ..., + ) -> number: ... + @overload + def prod( + self, + axis: Optional[_ShapeLike] = ..., + dtype: DTypeLike = ..., + out: None = ..., + keepdims: bool = ..., + initial: _NumberLike = ..., + where: _ArrayLikeBool = ..., + ) -> Union[number, ndarray]: ... + @overload + def prod( + self, + axis: Optional[_ShapeLike] = ..., + dtype: DTypeLike = ..., + out: _NdArraySubClass = ..., + keepdims: bool = ..., + initial: _NumberLike = ..., + where: _ArrayLikeBool = ..., + ) -> _NdArraySubClass: ... + @overload + def ptp( + self, axis: None = ..., out: None = ..., keepdims: Literal[False] = ..., + ) -> number: ... + @overload + def ptp( + self, axis: Optional[_ShapeLike] = ..., out: None = ..., keepdims: bool = ..., + ) -> Union[number, ndarray]: ... + @overload + def ptp( + self, + axis: Optional[_ShapeLike] = ..., + out: _NdArraySubClass = ..., + keepdims: bool = ..., + ) -> _NdArraySubClass: ... + def repeat( + self, repeats: _ArrayLikeIntOrBool, axis: Optional[int] = ... + ) -> ndarray: ... + @overload + def round(self: _ArraySelf, decimals: int = ..., out: None = ...) -> _ArraySelf: ... + @overload + def round( + self, decimals: int = ..., out: _NdArraySubClass = ... + ) -> _NdArraySubClass: ... + @overload + def std( + self, + axis: None = ..., + dtype: DTypeLike = ..., + out: None = ..., + ddof: int = ..., + keepdims: Literal[False] = ..., + ) -> number: ... + @overload + def std( + self, + axis: Optional[_ShapeLike] = ..., + dtype: DTypeLike = ..., + out: None = ..., + ddof: int = ..., + keepdims: bool = ..., + ) -> Union[number, ndarray]: ... + @overload + def std( + self, + axis: Optional[_ShapeLike] = ..., + dtype: DTypeLike = ..., + out: _NdArraySubClass = ..., + ddof: int = ..., + keepdims: bool = ..., + ) -> _NdArraySubClass: ... + @overload + def sum( + self, + axis: None = ..., + dtype: DTypeLike = ..., + out: None = ..., + keepdims: Literal[False] = ..., + initial: _NumberLike = ..., + where: _ArrayLikeBool = ..., + ) -> number: ... + @overload + def sum( + self, + axis: Optional[_ShapeLike] = ..., + dtype: DTypeLike = ..., + out: None = ..., + keepdims: bool = ..., + initial: _NumberLike = ..., + where: _ArrayLikeBool = ..., + ) -> Union[number, ndarray]: ... + @overload + def sum( + self, + axis: Optional[_ShapeLike] = ..., + dtype: DTypeLike = ..., + out: _NdArraySubClass = ..., + keepdims: bool = ..., + initial: _NumberLike = ..., + where: _ArrayLikeBool = ..., + ) -> _NdArraySubClass: ... + @overload + def take( + self, + indices: Union[_IntLike, _BoolLike], + axis: Optional[int] = ..., + out: None = ..., + mode: _ModeKind = ..., + ) -> generic: ... + @overload + def take( + self, + indices: _ArrayLikeIntOrBool, + axis: Optional[int] = ..., + out: None = ..., + mode: _ModeKind = ..., + ) -> ndarray: ... + @overload + def take( + self, + indices: _ArrayLikeIntOrBool, + axis: Optional[int] = ..., + out: _NdArraySubClass = ..., + mode: _ModeKind = ..., + ) -> _NdArraySubClass: ... + @overload + def var( + self, + axis: None = ..., + dtype: DTypeLike = ..., + out: None = ..., + ddof: int = ..., + keepdims: Literal[False] = ..., + ) -> number: ... + @overload + def var( + self, + axis: Optional[_ShapeLike] = ..., + dtype: DTypeLike = ..., + out: None = ..., + ddof: int = ..., + keepdims: bool = ..., + ) -> Union[number, ndarray]: ... + @overload + def var( + self, + axis: Optional[_ShapeLike] = ..., + dtype: DTypeLike = ..., + out: _NdArraySubClass = ..., + ddof: int = ..., + keepdims: bool = ..., + ) -> _NdArraySubClass: ... + +_BufferType = Union[ndarray, bytes, bytearray, memoryview] +_Casting = Literal["no", "equiv", "safe", "same_kind", "unsafe"] + +class ndarray(_ArrayOrScalarCommon, Iterable, Sized, Container): + @property + def base(self) -> Optional[ndarray]: ... + @property + def ndim(self) -> int: ... + @property + def size(self) -> int: ... + @property + def real(self: _ArraySelf) -> _ArraySelf: ... + @real.setter + def real(self, value: ArrayLike) -> None: ... + @property + def imag(self: _ArraySelf) -> _ArraySelf: ... + @imag.setter + def imag(self, value: ArrayLike) -> None: ... + def __new__( + cls: Type[_ArraySelf], + shape: Sequence[int], + dtype: DTypeLike = ..., + buffer: _BufferType = ..., + offset: int = ..., + strides: _ShapeLike = ..., + order: _OrderKACF = ..., + ) -> _ArraySelf: ... + @property + def dtype(self) -> _DType: ... + @property + def ctypes(self) -> _ctypes: ... + @property + def shape(self) -> _Shape: ... + @shape.setter + def shape(self, value: _ShapeLike): ... + @property + def strides(self) -> _Shape: ... + @strides.setter + def strides(self, value: _ShapeLike): ... + def byteswap(self: _ArraySelf, inplace: bool = ...) -> _ArraySelf: ... + def fill(self, value: Any) -> None: ... + @property + def flat(self: _ArraySelf) -> flatiter[_ArraySelf]: ... + @overload + def item(self, *args: int) -> Any: ... + @overload + def item(self, __args: Tuple[int, ...]) -> Any: ... + @overload + def itemset(self, __value: Any) -> None: ... + @overload + def itemset(self, __item: _ShapeLike, __value: Any) -> None: ... + @overload + def resize(self, __new_shape: Sequence[int], *, refcheck: bool = ...) -> None: ... + @overload + def resize(self, *new_shape: int, refcheck: bool = ...) -> None: ... + def setflags( + self, write: bool = ..., align: bool = ..., uic: bool = ... + ) -> None: ... + def squeeze( + self: _ArraySelf, axis: Union[int, Tuple[int, ...]] = ... + ) -> _ArraySelf: ... + def swapaxes(self: _ArraySelf, axis1: int, axis2: int) -> _ArraySelf: ... + @overload + def transpose(self: _ArraySelf, __axes: Sequence[int]) -> _ArraySelf: ... + @overload + def transpose(self: _ArraySelf, *axes: int) -> _ArraySelf: ... + def argpartition( + self, + kth: _ArrayLikeIntOrBool, + axis: Optional[int] = ..., + kind: _PartitionKind = ..., + order: Union[None, str, Sequence[str]] = ..., + ) -> ndarray: ... + def diagonal( + self: _ArraySelf, offset: int = ..., axis1: int = ..., axis2: int = ... + ) -> _ArraySelf: ... + @overload + def dot(self, b: ArrayLike, out: None = ...) -> Union[number, ndarray]: ... + @overload + def dot(self, b: ArrayLike, out: _NdArraySubClass = ...) -> _NdArraySubClass: ... + # `nonzero()` is deprecated for 0d arrays/generics + def nonzero(self) -> Tuple[ndarray, ...]: ... + def partition( + self, + kth: _ArrayLikeIntOrBool, + axis: int = ..., + kind: _PartitionKind = ..., + order: Union[None, str, Sequence[str]] = ..., + ) -> None: ... + # `put` is technically available to `generic`, + # but is pointless as `generic`s are immutable + def put( + self, ind: _ArrayLikeIntOrBool, v: ArrayLike, mode: _ModeKind = ... + ) -> None: ... + def searchsorted( + self, # >= 1D array + v: ArrayLike, + side: _SortSide = ..., + sorter: Optional[_ArrayLikeIntOrBool] = ..., # 1D int array + ) -> ndarray: ... + def setfield( + self, val: ArrayLike, dtype: DTypeLike, offset: int = ... + ) -> None: ... + def sort( + self, + axis: int = ..., + kind: Optional[_SortKind] = ..., + order: Union[None, str, Sequence[str]] = ..., + ) -> None: ... + @overload + def trace( + self, # >= 2D array + offset: int = ..., + axis1: int = ..., + axis2: int = ..., + dtype: DTypeLike = ..., + out: None = ..., + ) -> Union[number, ndarray]: ... + @overload + def trace( + self, # >= 2D array + offset: int = ..., + axis1: int = ..., + axis2: int = ..., + dtype: DTypeLike = ..., + out: _NdArraySubClass = ..., + ) -> _NdArraySubClass: ... + # Many of these special methods are irrelevant currently, since protocols + # aren't supported yet. That said, I'm adding them for completeness. + # https://docs.python.org/3/reference/datamodel.html + def __int__(self) -> int: ... + def __float__(self) -> float: ... + def __complex__(self) -> complex: ... + def __len__(self) -> int: ... + def __setitem__(self, key, value): ... + def __iter__(self) -> Any: ... + def __contains__(self, key) -> bool: ... + def __index__(self) -> int: ... + def __matmul__(self, other: ArrayLike) -> Any: ... + # NOTE: `ndarray` does not implement `__imatmul__` + def __rmatmul__(self, other: ArrayLike) -> Any: ... + def __neg__(self: _ArraySelf) -> Any: ... + def __pos__(self: _ArraySelf) -> Any: ... + def __abs__(self: _ArraySelf) -> Any: ... + def __mod__(self, other: ArrayLike) -> Any: ... + def __rmod__(self, other: ArrayLike) -> Any: ... + def __divmod__(self, other: ArrayLike) -> Tuple[Any, Any]: ... + def __rdivmod__(self, other: ArrayLike) -> Tuple[Any, Any]: ... + def __add__(self, other: ArrayLike) -> Any: ... + def __radd__(self, other: ArrayLike) -> Any: ... + def __sub__(self, other: ArrayLike) -> Any: ... + def __rsub__(self, other: ArrayLike) -> Any: ... + def __mul__(self, other: ArrayLike) -> Any: ... + def __rmul__(self, other: ArrayLike) -> Any: ... + def __floordiv__(self, other: ArrayLike) -> Any: ... + def __rfloordiv__(self, other: ArrayLike) -> Any: ... + def __pow__(self, other: ArrayLike) -> Any: ... + def __rpow__(self, other: ArrayLike) -> Any: ... + def __truediv__(self, other: ArrayLike) -> Any: ... + def __rtruediv__(self, other: ArrayLike) -> Any: ... + def __invert__(self: _ArraySelf) -> Any: ... + def __lshift__(self, other: ArrayLike) -> Any: ... + def __rlshift__(self, other: ArrayLike) -> Any: ... + def __rshift__(self, other: ArrayLike) -> Any: ... + def __rrshift__(self, other: ArrayLike) -> Any: ... + def __and__(self, other: ArrayLike) -> Any: ... + def __rand__(self, other: ArrayLike) -> Any: ... + def __xor__(self, other: ArrayLike) -> Any: ... + def __rxor__(self, other: ArrayLike) -> Any: ... + def __or__(self, other: ArrayLike) -> Any: ... + def __ror__(self, other: ArrayLike) -> Any: ... + # `np.generic` does not support inplace operations + def __iadd__(self: _ArraySelf, other: ArrayLike) -> _ArraySelf: ... + def __isub__(self: _ArraySelf, other: ArrayLike) -> _ArraySelf: ... + def __imul__(self: _ArraySelf, other: ArrayLike) -> _ArraySelf: ... + def __itruediv__(self: _ArraySelf, other: ArrayLike) -> _ArraySelf: ... + def __ifloordiv__(self: _ArraySelf, other: ArrayLike) -> _ArraySelf: ... + def __ipow__(self: _ArraySelf, other: ArrayLike) -> _ArraySelf: ... + def __imod__(self: _ArraySelf, other: ArrayLike) -> _ArraySelf: ... + def __ilshift__(self: _ArraySelf, other: ArrayLike) -> _ArraySelf: ... + def __irshift__(self: _ArraySelf, other: ArrayLike) -> _ArraySelf: ... + def __iand__(self: _ArraySelf, other: ArrayLike) -> _ArraySelf: ... + def __ixor__(self: _ArraySelf, other: ArrayLike) -> _ArraySelf: ... + def __ior__(self: _ArraySelf, other: ArrayLike) -> _ArraySelf: ... + +# NOTE: while `np.generic` is not technically an instance of `ABCMeta`, +# the `@abstractmethod` decorator is herein used to (forcefully) deny +# the creation of `np.generic` instances. +# The `# type: ignore` comments are necessary to silence mypy errors regarding +# the missing `ABCMeta` metaclass. + +# See https://github.com/numpy/numpy-stubs/pull/80 for more details. + +_ScalarType = TypeVar("_ScalarType", bound=generic) +_NBit_co = TypeVar("_NBit_co", covariant=True, bound=NBitBase) +_NBit_co2 = TypeVar("_NBit_co2", covariant=True, bound=NBitBase) + +class generic(_ArrayOrScalarCommon): + @abstractmethod + def __init__(self, *args: Any, **kwargs: Any) -> None: ... + @property + def base(self) -> None: ... + @property + def dtype(self: _ScalarType) -> _DType[_ScalarType]: ... + @property + def ndim(self) -> Literal[0]: ... + @property + def size(self) -> Literal[1]: ... + @property + def shape(self) -> Tuple[()]: ... + @property + def strides(self) -> Tuple[()]: ... + def byteswap(self: _ScalarType, inplace: Literal[False] = ...) -> _ScalarType: ... + @property + def flat(self) -> flatiter[ndarray]: ... + def item( + self: _ScalarType, + __args: Union[Literal[0], Tuple[()], Tuple[Literal[0]]] = ..., + ) -> Any: ... + def squeeze( + self: _ScalarType, axis: Union[Literal[0], Tuple[()]] = ... + ) -> _ScalarType: ... + def transpose(self: _ScalarType, __axes: Tuple[()] = ...) -> _ScalarType: ... + +class number(generic, Generic[_NBit_co]): # type: ignore + @property + def real(self: _ArraySelf) -> _ArraySelf: ... + @property + def imag(self: _ArraySelf) -> _ArraySelf: ... + def __int__(self) -> int: ... + def __float__(self) -> float: ... + def __complex__(self) -> complex: ... + def __neg__(self: _ArraySelf) -> _ArraySelf: ... + def __pos__(self: _ArraySelf) -> _ArraySelf: ... + def __abs__(self: _ArraySelf) -> _ArraySelf: ... + # Ensure that objects annotated as `number` support arithmetic operations + __add__: _NumberOp + __radd__: _NumberOp + __sub__: _NumberOp + __rsub__: _NumberOp + __mul__: _NumberOp + __rmul__: _NumberOp + __floordiv__: _NumberOp + __rfloordiv__: _NumberOp + __pow__: _NumberOp + __rpow__: _NumberOp + __truediv__: _NumberOp + __rtruediv__: _NumberOp + +class bool_(generic): + def __init__(self, __value: object = ...) -> None: ... + @property + def real(self: _ArraySelf) -> _ArraySelf: ... + @property + def imag(self: _ArraySelf) -> _ArraySelf: ... + def __int__(self) -> int: ... + def __float__(self) -> float: ... + def __complex__(self) -> complex: ... + def __abs__(self: _ArraySelf) -> _ArraySelf: ... + __add__: _BoolOp[bool_] + __radd__: _BoolOp[bool_] + __sub__: _BoolSub + __rsub__: _BoolSub + __mul__: _BoolOp[bool_] + __rmul__: _BoolOp[bool_] + __floordiv__: _BoolOp[int8] + __rfloordiv__: _BoolOp[int8] + __pow__: _BoolOp[int8] + __rpow__: _BoolOp[int8] + __truediv__: _BoolTrueDiv + __rtruediv__: _BoolTrueDiv + def __invert__(self) -> bool_: ... + __lshift__: _BoolBitOp[int8] + __rlshift__: _BoolBitOp[int8] + __rshift__: _BoolBitOp[int8] + __rrshift__: _BoolBitOp[int8] + __and__: _BoolBitOp[bool_] + __rand__: _BoolBitOp[bool_] + __xor__: _BoolBitOp[bool_] + __rxor__: _BoolBitOp[bool_] + __or__: _BoolBitOp[bool_] + __ror__: _BoolBitOp[bool_] + __mod__: _BoolMod + __rmod__: _BoolMod + __divmod__: _BoolDivMod + __rdivmod__: _BoolDivMod + +class object_(generic): + def __init__(self, __value: object = ...) -> None: ... + @property + def real(self: _ArraySelf) -> _ArraySelf: ... + @property + def imag(self: _ArraySelf) -> _ArraySelf: ... + +class datetime64(generic): + @overload + def __init__( + self, + __value: Union[None, datetime64, _CharLike, dt.datetime] = ..., + __format: Union[_CharLike, Tuple[_CharLike, _IntLike]] = ..., + ) -> None: ... + @overload + def __init__( + self, + __value: int, + __format: Union[_CharLike, Tuple[_CharLike, _IntLike]] + ) -> None: ... + def __add__(self, other: Union[timedelta64, _IntLike, _BoolLike]) -> datetime64: ... + def __radd__(self, other: Union[timedelta64, _IntLike, _BoolLike]) -> datetime64: ... + @overload + def __sub__(self, other: datetime64) -> timedelta64: ... + @overload + def __sub__(self, other: Union[timedelta64, _IntLike, _BoolLike]) -> datetime64: ... + def __rsub__(self, other: datetime64) -> timedelta64: ... + +# Support for `__index__` was added in python 3.8 (bpo-20092) +if sys.version_info >= (3, 8): + _IntValue = Union[SupportsInt, _CharLike, SupportsIndex] + _FloatValue = Union[None, _CharLike, SupportsFloat, SupportsIndex] + _ComplexValue = Union[None, _CharLike, SupportsFloat, SupportsComplex, SupportsIndex] +else: + _IntValue = Union[SupportsInt, _CharLike] + _FloatValue = Union[None, _CharLike, SupportsFloat] + _ComplexValue = Union[None, _CharLike, SupportsFloat, SupportsComplex] + +class integer(number[_NBit_co]): # type: ignore + # NOTE: `__index__` is technically defined in the bottom-most + # sub-classes (`int64`, `uint32`, etc) + def __index__(self) -> int: ... + __truediv__: _IntTrueDiv[_NBit_co] + __rtruediv__: _IntTrueDiv[_NBit_co] + def __mod__(self, value: Union[_IntLike, integer]) -> integer: ... + def __rmod__(self, value: Union[_IntLike, integer]) -> integer: ... + def __invert__(self: _IntType) -> _IntType: ... + # Ensure that objects annotated as `integer` support bit-wise operations + def __lshift__(self, other: Union[_IntLike, _BoolLike]) -> integer: ... + def __rlshift__(self, other: Union[_IntLike, _BoolLike]) -> integer: ... + def __rshift__(self, other: Union[_IntLike, _BoolLike]) -> integer: ... + def __rrshift__(self, other: Union[_IntLike, _BoolLike]) -> integer: ... + def __and__(self, other: Union[_IntLike, _BoolLike]) -> integer: ... + def __rand__(self, other: Union[_IntLike, _BoolLike]) -> integer: ... + def __or__(self, other: Union[_IntLike, _BoolLike]) -> integer: ... + def __ror__(self, other: Union[_IntLike, _BoolLike]) -> integer: ... + def __xor__(self, other: Union[_IntLike, _BoolLike]) -> integer: ... + def __rxor__(self, other: Union[_IntLike, _BoolLike]) -> integer: ... + +class signedinteger(integer[_NBit_co]): + def __init__(self, __value: _IntValue = ...) -> None: ... + __add__: _SignedIntOp[_NBit_co] + __radd__: _SignedIntOp[_NBit_co] + __sub__: _SignedIntOp[_NBit_co] + __rsub__: _SignedIntOp[_NBit_co] + __mul__: _SignedIntOp[_NBit_co] + __rmul__: _SignedIntOp[_NBit_co] + __floordiv__: _SignedIntOp[_NBit_co] + __rfloordiv__: _SignedIntOp[_NBit_co] + __pow__: _SignedIntOp[_NBit_co] + __rpow__: _SignedIntOp[_NBit_co] + __lshift__: _SignedIntBitOp[_NBit_co] + __rlshift__: _SignedIntBitOp[_NBit_co] + __rshift__: _SignedIntBitOp[_NBit_co] + __rrshift__: _SignedIntBitOp[_NBit_co] + __and__: _SignedIntBitOp[_NBit_co] + __rand__: _SignedIntBitOp[_NBit_co] + __xor__: _SignedIntBitOp[_NBit_co] + __rxor__: _SignedIntBitOp[_NBit_co] + __or__: _SignedIntBitOp[_NBit_co] + __ror__: _SignedIntBitOp[_NBit_co] + __mod__: _SignedIntMod[_NBit_co] + __rmod__: _SignedIntMod[_NBit_co] + __divmod__: _SignedIntDivMod[_NBit_co] + __rdivmod__: _SignedIntDivMod[_NBit_co] + +int8 = signedinteger[_8Bit] +int16 = signedinteger[_16Bit] +int32 = signedinteger[_32Bit] +int64 = signedinteger[_64Bit] + +class timedelta64(generic): + def __init__( + self, + __value: Union[None, int, _CharLike, dt.timedelta, timedelta64] = ..., + __format: Union[_CharLike, Tuple[_CharLike, _IntLike]] = ..., + ) -> None: ... + def __int__(self) -> int: ... + def __float__(self) -> float: ... + def __complex__(self) -> complex: ... + def __neg__(self: _ArraySelf) -> _ArraySelf: ... + def __pos__(self: _ArraySelf) -> _ArraySelf: ... + def __abs__(self: _ArraySelf) -> _ArraySelf: ... + def __add__(self, other: Union[timedelta64, _IntLike, _BoolLike]) -> timedelta64: ... + def __radd__(self, other: Union[timedelta64, _IntLike, _BoolLike]) -> timedelta64: ... + def __sub__(self, other: Union[timedelta64, _IntLike, _BoolLike]) -> timedelta64: ... + def __rsub__(self, other: Union[timedelta64, _IntLike, _BoolLike]) -> timedelta64: ... + def __mul__(self, other: Union[_FloatLike, _BoolLike]) -> timedelta64: ... + def __rmul__(self, other: Union[_FloatLike, _BoolLike]) -> timedelta64: ... + __truediv__: _TD64Div[float64] + __floordiv__: _TD64Div[int64] + def __rtruediv__(self, other: timedelta64) -> float64: ... + def __rfloordiv__(self, other: timedelta64) -> int64: ... + def __mod__(self, other: timedelta64) -> timedelta64: ... + def __rmod__(self, other: timedelta64) -> timedelta64: ... + def __divmod__(self, other: timedelta64) -> Tuple[int64, timedelta64]: ... + def __rdivmod__(self, other: timedelta64) -> Tuple[int64, timedelta64]: ... + +class unsignedinteger(integer[_NBit_co]): + # NOTE: `uint64 + signedinteger -> float64` + def __init__(self, __value: _IntValue = ...) -> None: ... + __add__: _UnsignedIntOp[_NBit_co] + __radd__: _UnsignedIntOp[_NBit_co] + __sub__: _UnsignedIntOp[_NBit_co] + __rsub__: _UnsignedIntOp[_NBit_co] + __mul__: _UnsignedIntOp[_NBit_co] + __rmul__: _UnsignedIntOp[_NBit_co] + __floordiv__: _UnsignedIntOp[_NBit_co] + __rfloordiv__: _UnsignedIntOp[_NBit_co] + __pow__: _UnsignedIntOp[_NBit_co] + __rpow__: _UnsignedIntOp[_NBit_co] + __lshift__: _UnsignedIntBitOp[_NBit_co] + __rlshift__: _UnsignedIntBitOp[_NBit_co] + __rshift__: _UnsignedIntBitOp[_NBit_co] + __rrshift__: _UnsignedIntBitOp[_NBit_co] + __and__: _UnsignedIntBitOp[_NBit_co] + __rand__: _UnsignedIntBitOp[_NBit_co] + __xor__: _UnsignedIntBitOp[_NBit_co] + __rxor__: _UnsignedIntBitOp[_NBit_co] + __or__: _UnsignedIntBitOp[_NBit_co] + __ror__: _UnsignedIntBitOp[_NBit_co] + __mod__: _UnsignedIntMod[_NBit_co] + __rmod__: _UnsignedIntMod[_NBit_co] + __divmod__: _UnsignedIntDivMod[_NBit_co] + __rdivmod__: _UnsignedIntDivMod[_NBit_co] + +uint8 = unsignedinteger[_8Bit] +uint16 = unsignedinteger[_16Bit] +uint32 = unsignedinteger[_32Bit] +uint64 = unsignedinteger[_64Bit] + +class inexact(number[_NBit_co]): ... # type: ignore + +_IntType = TypeVar("_IntType", bound=integer) +_FloatType = TypeVar('_FloatType', bound=floating) + +class floating(inexact[_NBit_co]): + def __init__(self, __value: _FloatValue = ...) -> None: ... + __add__: _FloatOp[_NBit_co] + __radd__: _FloatOp[_NBit_co] + __sub__: _FloatOp[_NBit_co] + __rsub__: _FloatOp[_NBit_co] + __mul__: _FloatOp[_NBit_co] + __rmul__: _FloatOp[_NBit_co] + __truediv__: _FloatOp[_NBit_co] + __rtruediv__: _FloatOp[_NBit_co] + __floordiv__: _FloatOp[_NBit_co] + __rfloordiv__: _FloatOp[_NBit_co] + __pow__: _FloatOp[_NBit_co] + __rpow__: _FloatOp[_NBit_co] + __mod__: _FloatMod[_NBit_co] + __rmod__: _FloatMod[_NBit_co] + __divmod__: _FloatDivMod[_NBit_co] + __rdivmod__: _FloatDivMod[_NBit_co] + +float16 = floating[_16Bit] +float32 = floating[_32Bit] +float64 = floating[_64Bit] + +# The main reason for `complexfloating` having two typevars is cosmetic. +# It is used to clarify why `complex128`s precision is `_64Bit`, the latter +# describing the two 64 bit floats representing its real and imaginary component + +class complexfloating(inexact[_NBit_co], Generic[_NBit_co, _NBit_co2]): + def __init__(self, __value: _ComplexValue = ...) -> None: ... + @property + def real(self) -> floating[_NBit_co]: ... # type: ignore[override] + @property + def imag(self) -> floating[_NBit_co2]: ... # type: ignore[override] + def __abs__(self) -> floating[_NBit_co]: ... # type: ignore[override] + __add__: _ComplexOp[_NBit_co] + __radd__: _ComplexOp[_NBit_co] + __sub__: _ComplexOp[_NBit_co] + __rsub__: _ComplexOp[_NBit_co] + __mul__: _ComplexOp[_NBit_co] + __rmul__: _ComplexOp[_NBit_co] + __truediv__: _ComplexOp[_NBit_co] + __rtruediv__: _ComplexOp[_NBit_co] + __floordiv__: _ComplexOp[_NBit_co] + __rfloordiv__: _ComplexOp[_NBit_co] + __pow__: _ComplexOp[_NBit_co] + __rpow__: _ComplexOp[_NBit_co] + +complex64 = complexfloating[_32Bit, _32Bit] +complex128 = complexfloating[_64Bit, _64Bit] + +class flexible(generic): ... # type: ignore + +class void(flexible): + def __init__(self, __value: Union[_IntLike, _BoolLike, bytes]): ... + @property + def real(self: _ArraySelf) -> _ArraySelf: ... + @property + def imag(self: _ArraySelf) -> _ArraySelf: ... + def setfield( + self, val: ArrayLike, dtype: DTypeLike, offset: int = ... + ) -> None: ... + +class character(flexible): # type: ignore + def __int__(self) -> int: ... + def __float__(self) -> float: ... + +# NOTE: Most `np.bytes_` / `np.str_` methods return their +# builtin `bytes` / `str` counterpart + +class bytes_(character, bytes): + @overload + def __init__(self, __value: object = ...) -> None: ... + @overload + def __init__( + self, __value: str, encoding: str = ..., errors: str = ... + ) -> None: ... + +class str_(character, str): + @overload + def __init__(self, __value: object = ...) -> None: ... + @overload + def __init__( + self, __value: bytes, encoding: str = ..., errors: str = ... + ) -> None: ... + +unicode_ = str0 = str_ + +# TODO(alan): Platform dependent types +# longcomplex, longdouble, longfloat +# bytes, short, intc, intp, longlong +# half, single, double, longdouble +# uint_, int_, float_, complex_ +# float128, complex256 +# float96 + +def array( + object: object, + dtype: DTypeLike = ..., + *, + copy: bool = ..., + order: _OrderKACF = ..., + subok: bool = ..., + ndmin: int = ..., + like: ArrayLike = ..., +) -> ndarray: ... +def zeros( + shape: _ShapeLike, + dtype: DTypeLike = ..., + order: _OrderCF = ..., + *, + like: ArrayLike = ..., +) -> ndarray: ... +def empty( + shape: _ShapeLike, + dtype: DTypeLike = ..., + order: _OrderCF = ..., + *, + like: ArrayLike = ..., +) -> ndarray: ... + +def broadcast_shapes(*args: _ShapeLike) -> _Shape: ... + +# +# Constants +# + +Inf: Final[float] +Infinity: Final[float] +NAN: Final[float] +NINF: Final[float] +NZERO: Final[float] +NaN: Final[float] +PINF: Final[float] +PZERO: Final[float] +e: Final[float] +euler_gamma: Final[float] +inf: Final[float] +infty: Final[float] +nan: Final[float] +pi: Final[float] +ALLOW_THREADS: Final[int] +BUFSIZE: Final[int] +CLIP: Final[int] +ERR_CALL: Final[int] +ERR_DEFAULT: Final[int] +ERR_IGNORE: Final[int] +ERR_LOG: Final[int] +ERR_PRINT: Final[int] +ERR_RAISE: Final[int] +ERR_WARN: Final[int] +FLOATING_POINT_SUPPORT: Final[int] +FPE_DIVIDEBYZERO: Final[int] +FPE_INVALID: Final[int] +FPE_OVERFLOW: Final[int] +FPE_UNDERFLOW: Final[int] +MAXDIMS: Final[int] +MAY_SHARE_BOUNDS: Final[int] +MAY_SHARE_EXACT: Final[int] +RAISE: Final[int] +SHIFT_DIVIDEBYZERO: Final[int] +SHIFT_INVALID: Final[int] +SHIFT_OVERFLOW: Final[int] +SHIFT_UNDERFLOW: Final[int] +UFUNC_BUFSIZE_DEFAULT: Final[int] +WRAP: Final[int] +tracemalloc_domain: Final[int] + +little_endian: Final[bool] +True_: Final[bool_] +False_: Final[bool_] + +UFUNC_PYVALS_NAME: Final[str] + +class ufunc: + @property + def __name__(self) -> str: ... + def __call__( + self, + *args: ArrayLike, + out: Optional[Union[ndarray, Tuple[ndarray, ...]]] = ..., + where: Optional[ndarray] = ..., + # The list should be a list of tuples of ints, but since we + # don't know the signature it would need to be + # Tuple[int, ...]. But, since List is invariant something like + # e.g. List[Tuple[int, int]] isn't a subtype of + # List[Tuple[int, ...]], so we can't type precisely here. + axes: List[Any] = ..., + axis: int = ..., + keepdims: bool = ..., + casting: _Casting = ..., + order: _OrderKACF = ..., + dtype: DTypeLike = ..., + subok: bool = ..., + signature: Union[str, Tuple[str]] = ..., + # In reality this should be a length of list 3 containing an + # int, an int, and a callable, but there's no way to express + # that. + extobj: List[Union[int, Callable]] = ..., + ) -> Any: ... + @property + def nin(self) -> int: ... + @property + def nout(self) -> int: ... + @property + def nargs(self) -> int: ... + @property + def ntypes(self) -> int: ... + @property + def types(self) -> List[str]: ... + # Broad return type because it has to encompass things like + # + # >>> np.logical_and.identity is True + # True + # >>> np.add.identity is 0 + # True + # >>> np.sin.identity is None + # True + # + # and any user-defined ufuncs. + @property + def identity(self) -> Any: ... + # This is None for ufuncs and a string for gufuncs. + @property + def signature(self) -> Optional[str]: ... + # The next four methods will always exist, but they will just + # raise a ValueError ufuncs with that don't accept two input + # arguments and return one output argument. Because of that we + # can't type them very precisely. + @property + def reduce(self) -> Any: ... + @property + def accumulate(self) -> Any: ... + @property + def reduceat(self) -> Any: ... + @property + def outer(self) -> Any: ... + # Similarly at won't be defined for ufuncs that return multiple + # outputs, so we can't type it very precisely. + @property + def at(self) -> Any: ... + +absolute: ufunc +add: ufunc +arccos: ufunc +arccosh: ufunc +arcsin: ufunc +arcsinh: ufunc +arctan2: ufunc +arctan: ufunc +arctanh: ufunc +bitwise_and: ufunc +bitwise_or: ufunc +bitwise_xor: ufunc +cbrt: ufunc +ceil: ufunc +conjugate: ufunc +copysign: ufunc +cos: ufunc +cosh: ufunc +deg2rad: ufunc +degrees: ufunc +divmod: ufunc +equal: ufunc +exp2: ufunc +exp: ufunc +expm1: ufunc +fabs: ufunc +float_power: ufunc +floor: ufunc +floor_divide: ufunc +fmax: ufunc +fmin: ufunc +fmod: ufunc +frexp: ufunc +gcd: ufunc +greater: ufunc +greater_equal: ufunc +heaviside: ufunc +hypot: ufunc +invert: ufunc +isfinite: ufunc +isinf: ufunc +isnan: ufunc +isnat: ufunc +lcm: ufunc +ldexp: ufunc +left_shift: ufunc +less: ufunc +less_equal: ufunc +log10: ufunc +log1p: ufunc +log2: ufunc +log: ufunc +logaddexp2: ufunc +logaddexp: ufunc +logical_and: ufunc +logical_not: ufunc +logical_or: ufunc +logical_xor: ufunc +matmul: ufunc +maximum: ufunc +minimum: ufunc +modf: ufunc +multiply: ufunc +negative: ufunc +nextafter: ufunc +not_equal: ufunc +positive: ufunc +power: ufunc +rad2deg: ufunc +radians: ufunc +reciprocal: ufunc +remainder: ufunc +right_shift: ufunc +rint: ufunc +sign: ufunc +signbit: ufunc +sin: ufunc +sinh: ufunc +spacing: ufunc +sqrt: ufunc +square: ufunc +subtract: ufunc +tan: ufunc +tanh: ufunc +true_divide: ufunc +trunc: ufunc + +abs = absolute + +# Warnings +class ModuleDeprecationWarning(DeprecationWarning): ... +class VisibleDeprecationWarning(UserWarning): ... +class ComplexWarning(RuntimeWarning): ... +class RankWarning(UserWarning): ... + +# Errors +class TooHardError(RuntimeError): ... + +class AxisError(ValueError, IndexError): + def __init__( + self, axis: int, ndim: Optional[int] = ..., msg_prefix: Optional[str] = ... + ) -> None: ... + +_CallType = TypeVar("_CallType", bound=Union[_ErrFunc, _SupportsWrite]) + +class errstate(Generic[_CallType], ContextDecorator): + call: _CallType + kwargs: _ErrDictOptional + + # Expand `**kwargs` into explicit keyword-only arguments + def __init__( + self, + *, + call: _CallType = ..., + all: Optional[_ErrKind] = ..., + divide: Optional[_ErrKind] = ..., + over: Optional[_ErrKind] = ..., + under: Optional[_ErrKind] = ..., + invalid: Optional[_ErrKind] = ..., + ) -> None: ... + def __enter__(self) -> None: ... + def __exit__( + self, + __exc_type: Optional[Type[BaseException]], + __exc_value: Optional[BaseException], + __traceback: Optional[TracebackType], + ) -> None: ... diff --git a/venv/Lib/site-packages/numpy/_distributor_init.py b/venv/Lib/site-packages/numpy/_distributor_init.py new file mode 100644 index 0000000..84263b8 --- /dev/null +++ b/venv/Lib/site-packages/numpy/_distributor_init.py @@ -0,0 +1,32 @@ + +''' +Helper to preload windows dlls to prevent dll not found errors. +Once a DLL is preloaded, its namespace is made available to any +subsequent DLL. This file originated in the numpy-wheels repo, +and is created as part of the scripts that build the wheel. +''' +import os +import glob +if os.name == 'nt': + # convention for storing / loading the DLL from + # numpy/.libs/, if present + try: + from ctypes import WinDLL + basedir = os.path.dirname(__file__) + except: + pass + else: + libs_dir = os.path.abspath(os.path.join(basedir, '.libs')) + DLL_filenames = [] + if os.path.isdir(libs_dir): + for filename in glob.glob(os.path.join(libs_dir, + '*openblas*dll')): + # NOTE: would it change behavior to load ALL + # DLLs at this path vs. the name restriction? + WinDLL(os.path.abspath(filename)) + DLL_filenames.append(filename) + if len(DLL_filenames) > 1: + import warnings + warnings.warn("loaded more than 1 DLL from .libs:" + "\n%s" % "\n".join(DLL_filenames), + stacklevel=1) diff --git a/venv/Lib/site-packages/numpy/_globals.py b/venv/Lib/site-packages/numpy/_globals.py new file mode 100644 index 0000000..9f44c77 --- /dev/null +++ b/venv/Lib/site-packages/numpy/_globals.py @@ -0,0 +1,79 @@ +""" +Module defining global singleton classes. + +This module raises a RuntimeError if an attempt to reload it is made. In that +way the identities of the classes defined here are fixed and will remain so +even if numpy itself is reloaded. In particular, a function like the following +will still work correctly after numpy is reloaded:: + + def foo(arg=np._NoValue): + if arg is np._NoValue: + ... + +That was not the case when the singleton classes were defined in the numpy +``__init__.py`` file. See gh-7844 for a discussion of the reload problem that +motivated this module. + +""" +__ALL__ = [ + 'ModuleDeprecationWarning', 'VisibleDeprecationWarning', '_NoValue' + ] + + +# Disallow reloading this module so as to preserve the identities of the +# classes defined here. +if '_is_loaded' in globals(): + raise RuntimeError('Reloading numpy._globals is not allowed') +_is_loaded = True + + +class ModuleDeprecationWarning(DeprecationWarning): + """Module deprecation warning. + + The nose tester turns ordinary Deprecation warnings into test failures. + That makes it hard to deprecate whole modules, because they get + imported by default. So this is a special Deprecation warning that the + nose tester will let pass without making tests fail. + + """ + + +ModuleDeprecationWarning.__module__ = 'numpy' + + +class VisibleDeprecationWarning(UserWarning): + """Visible deprecation warning. + + By default, python will not show deprecation warnings, so this class + can be used when a very visible warning is helpful, for example because + the usage is most likely a user bug. + + """ + + +VisibleDeprecationWarning.__module__ = 'numpy' + + +class _NoValueType: + """Special keyword value. + + The instance of this class may be used as the default value assigned to a + deprecated keyword in order to check if it has been given a user defined + value. + """ + __instance = None + def __new__(cls): + # ensure that only one instance exists + if not cls.__instance: + cls.__instance = super(_NoValueType, cls).__new__(cls) + return cls.__instance + + # needed for python 2 to preserve identity through a pickle + def __reduce__(self): + return (self.__class__, ()) + + def __repr__(self): + return "" + + +_NoValue = _NoValueType() diff --git a/venv/Lib/site-packages/numpy/_pytesttester.py b/venv/Lib/site-packages/numpy/_pytesttester.py new file mode 100644 index 0000000..813e069 --- /dev/null +++ b/venv/Lib/site-packages/numpy/_pytesttester.py @@ -0,0 +1,213 @@ +""" +Pytest test running. + +This module implements the ``test()`` function for NumPy modules. The usual +boiler plate for doing that is to put the following in the module +``__init__.py`` file:: + + from numpy._pytesttester import PytestTester + test = PytestTester(__name__) + del PytestTester + + +Warnings filtering and other runtime settings should be dealt with in the +``pytest.ini`` file in the numpy repo root. The behavior of the test depends on +whether or not that file is found as follows: + +* ``pytest.ini`` is present (develop mode) + All warnings except those explicitly filtered out are raised as error. +* ``pytest.ini`` is absent (release mode) + DeprecationWarnings and PendingDeprecationWarnings are ignored, other + warnings are passed through. + +In practice, tests run from the numpy repo are run in develop mode. That +includes the standard ``python runtests.py`` invocation. + +This module is imported by every numpy subpackage, so lies at the top level to +simplify circular import issues. For the same reason, it contains no numpy +imports at module scope, instead importing numpy within function calls. +""" +import sys +import os + +__all__ = ['PytestTester'] + + + +def _show_numpy_info(): + from numpy.core._multiarray_umath import ( + __cpu_features__, __cpu_baseline__, __cpu_dispatch__ + ) + import numpy as np + + print("NumPy version %s" % np.__version__) + relaxed_strides = np.ones((10, 1), order="C").flags.f_contiguous + print("NumPy relaxed strides checking option:", relaxed_strides) + + if len(__cpu_baseline__) == 0 and len(__cpu_dispatch__) == 0: + enabled_features = "nothing enabled" + else: + enabled_features = ' '.join(__cpu_baseline__) + for feature in __cpu_dispatch__: + if __cpu_features__[feature]: + enabled_features += " %s*" % feature + else: + enabled_features += " %s?" % feature + print("NumPy CPU features:", enabled_features) + + + +class PytestTester: + """ + Pytest test runner. + + A test function is typically added to a package's __init__.py like so:: + + from numpy._pytesttester import PytestTester + test = PytestTester(__name__).test + del PytestTester + + Calling this test function finds and runs all tests associated with the + module and all its sub-modules. + + Attributes + ---------- + module_name : str + Full path to the package to test. + + Parameters + ---------- + module_name : module name + The name of the module to test. + + Notes + ----- + Unlike the previous ``nose``-based implementation, this class is not + publicly exposed as it performs some ``numpy``-specific warning + suppression. + + """ + def __init__(self, module_name): + self.module_name = module_name + + def __call__(self, label='fast', verbose=1, extra_argv=None, + doctests=False, coverage=False, durations=-1, tests=None): + """ + Run tests for module using pytest. + + Parameters + ---------- + label : {'fast', 'full'}, optional + Identifies the tests to run. When set to 'fast', tests decorated + with `pytest.mark.slow` are skipped, when 'full', the slow marker + is ignored. + verbose : int, optional + Verbosity value for test outputs, in the range 1-3. Default is 1. + extra_argv : list, optional + List with any extra arguments to pass to pytests. + doctests : bool, optional + .. note:: Not supported + coverage : bool, optional + If True, report coverage of NumPy code. Default is False. + Requires installation of (pip) pytest-cov. + durations : int, optional + If < 0, do nothing, If 0, report time of all tests, if > 0, + report the time of the slowest `timer` tests. Default is -1. + tests : test or list of tests + Tests to be executed with pytest '--pyargs' + + Returns + ------- + result : bool + Return True on success, false otherwise. + + Notes + ----- + Each NumPy module exposes `test` in its namespace to run all tests for + it. For example, to run all tests for numpy.lib: + + >>> np.lib.test() #doctest: +SKIP + + Examples + -------- + >>> result = np.lib.test() #doctest: +SKIP + ... + 1023 passed, 2 skipped, 6 deselected, 1 xfailed in 10.39 seconds + >>> result + True + + """ + import pytest + import warnings + + module = sys.modules[self.module_name] + module_path = os.path.abspath(module.__path__[0]) + + # setup the pytest arguments + pytest_args = ["-l"] + + # offset verbosity. The "-q" cancels a "-v". + pytest_args += ["-q"] + + # Filter out distutils cpu warnings (could be localized to + # distutils tests). ASV has problems with top level import, + # so fetch module for suppression here. + with warnings.catch_warnings(): + warnings.simplefilter("always") + from numpy.distutils import cpuinfo + + # Filter out annoying import messages. Want these in both develop and + # release mode. + pytest_args += [ + "-W ignore:Not importing directory", + "-W ignore:numpy.dtype size changed", + "-W ignore:numpy.ufunc size changed", + "-W ignore::UserWarning:cpuinfo", + ] + + # When testing matrices, ignore their PendingDeprecationWarnings + pytest_args += [ + "-W ignore:the matrix subclass is not", + "-W ignore:Importing from numpy.matlib is", + ] + + if doctests: + raise ValueError("Doctests not supported") + + if extra_argv: + pytest_args += list(extra_argv) + + if verbose > 1: + pytest_args += ["-" + "v"*(verbose - 1)] + + if coverage: + pytest_args += ["--cov=" + module_path] + + if label == "fast": + # not importing at the top level to avoid circular import of module + from numpy.testing import IS_PYPY + if IS_PYPY: + pytest_args += ["-m", "not slow and not slow_pypy"] + else: + pytest_args += ["-m", "not slow"] + + elif label != "full": + pytest_args += ["-m", label] + + if durations >= 0: + pytest_args += ["--durations=%s" % durations] + + if tests is None: + tests = [self.module_name] + + pytest_args += ["--pyargs"] + list(tests) + + # run tests. + _show_numpy_info() + + try: + code = pytest.main(pytest_args) + except SystemExit as exc: + code = exc.code + + return code == 0 diff --git a/venv/Lib/site-packages/numpy/char.pyi b/venv/Lib/site-packages/numpy/char.pyi new file mode 100644 index 0000000..0e3596b --- /dev/null +++ b/venv/Lib/site-packages/numpy/char.pyi @@ -0,0 +1,56 @@ +from typing import Any, List + +__all__: List[str] + +equal: Any +not_equal: Any +greater_equal: Any +less_equal: Any +greater: Any +less: Any +str_len: Any +add: Any +multiply: Any +mod: Any +capitalize: Any +center: Any +count: Any +decode: Any +encode: Any +endswith: Any +expandtabs: Any +find: Any +index: Any +isalnum: Any +isalpha: Any +isdigit: Any +islower: Any +isspace: Any +istitle: Any +isupper: Any +join: Any +ljust: Any +lower: Any +lstrip: Any +partition: Any +replace: Any +rfind: Any +rindex: Any +rjust: Any +rpartition: Any +rsplit: Any +rstrip: Any +split: Any +splitlines: Any +startswith: Any +strip: Any +swapcase: Any +title: Any +translate: Any +upper: Any +zfill: Any +isnumeric: Any +isdecimal: Any +array: Any +asarray: Any +chararray: Any diff --git a/venv/Lib/site-packages/numpy/compat/__init__.py b/venv/Lib/site-packages/numpy/compat/__init__.py new file mode 100644 index 0000000..afee621 --- /dev/null +++ b/venv/Lib/site-packages/numpy/compat/__init__.py @@ -0,0 +1,18 @@ +""" +Compatibility module. + +This module contains duplicated code from Python itself or 3rd party +extensions, which may be included for the following reasons: + + * compatibility + * we may only need a small subset of the copied library/module + +""" +from . import _inspect +from . import py3k +from ._inspect import getargspec, formatargspec +from .py3k import * + +__all__ = [] +__all__.extend(_inspect.__all__) +__all__.extend(py3k.__all__) diff --git a/venv/Lib/site-packages/numpy/compat/_inspect.py b/venv/Lib/site-packages/numpy/compat/_inspect.py new file mode 100644 index 0000000..9a874a7 --- /dev/null +++ b/venv/Lib/site-packages/numpy/compat/_inspect.py @@ -0,0 +1,191 @@ +"""Subset of inspect module from upstream python + +We use this instead of upstream because upstream inspect is slow to import, and +significantly contributes to numpy import times. Importing this copy has almost +no overhead. + +""" +import types + +__all__ = ['getargspec', 'formatargspec'] + +# ----------------------------------------------------------- type-checking +def ismethod(object): + """Return true if the object is an instance method. + + Instance method objects provide these attributes: + __doc__ documentation string + __name__ name with which this method was defined + im_class class object in which this method belongs + im_func function object containing implementation of method + im_self instance to which this method is bound, or None + + """ + return isinstance(object, types.MethodType) + +def isfunction(object): + """Return true if the object is a user-defined function. + + Function objects provide these attributes: + __doc__ documentation string + __name__ name with which this function was defined + func_code code object containing compiled function bytecode + func_defaults tuple of any default values for arguments + func_doc (same as __doc__) + func_globals global namespace in which this function was defined + func_name (same as __name__) + + """ + return isinstance(object, types.FunctionType) + +def iscode(object): + """Return true if the object is a code object. + + Code objects provide these attributes: + co_argcount number of arguments (not including * or ** args) + co_code string of raw compiled bytecode + co_consts tuple of constants used in the bytecode + co_filename name of file in which this code object was created + co_firstlineno number of first line in Python source code + co_flags bitmap: 1=optimized | 2=newlocals | 4=*arg | 8=**arg + co_lnotab encoded mapping of line numbers to bytecode indices + co_name name with which this code object was defined + co_names tuple of names of local variables + co_nlocals number of local variables + co_stacksize virtual machine stack space required + co_varnames tuple of names of arguments and local variables + + """ + return isinstance(object, types.CodeType) + +# ------------------------------------------------ argument list extraction +# These constants are from Python's compile.h. +CO_OPTIMIZED, CO_NEWLOCALS, CO_VARARGS, CO_VARKEYWORDS = 1, 2, 4, 8 + +def getargs(co): + """Get information about the arguments accepted by a code object. + + Three things are returned: (args, varargs, varkw), where 'args' is + a list of argument names (possibly containing nested lists), and + 'varargs' and 'varkw' are the names of the * and ** arguments or None. + + """ + + if not iscode(co): + raise TypeError('arg is not a code object') + + nargs = co.co_argcount + names = co.co_varnames + args = list(names[:nargs]) + + # The following acrobatics are for anonymous (tuple) arguments. + # Which we do not need to support, so remove to avoid importing + # the dis module. + for i in range(nargs): + if args[i][:1] in ['', '.']: + raise TypeError("tuple function arguments are not supported") + varargs = None + if co.co_flags & CO_VARARGS: + varargs = co.co_varnames[nargs] + nargs = nargs + 1 + varkw = None + if co.co_flags & CO_VARKEYWORDS: + varkw = co.co_varnames[nargs] + return args, varargs, varkw + +def getargspec(func): + """Get the names and default values of a function's arguments. + + A tuple of four things is returned: (args, varargs, varkw, defaults). + 'args' is a list of the argument names (it may contain nested lists). + 'varargs' and 'varkw' are the names of the * and ** arguments or None. + 'defaults' is an n-tuple of the default values of the last n arguments. + + """ + + if ismethod(func): + func = func.__func__ + if not isfunction(func): + raise TypeError('arg is not a Python function') + args, varargs, varkw = getargs(func.__code__) + return args, varargs, varkw, func.__defaults__ + +def getargvalues(frame): + """Get information about arguments passed into a particular frame. + + A tuple of four things is returned: (args, varargs, varkw, locals). + 'args' is a list of the argument names (it may contain nested lists). + 'varargs' and 'varkw' are the names of the * and ** arguments or None. + 'locals' is the locals dictionary of the given frame. + + """ + args, varargs, varkw = getargs(frame.f_code) + return args, varargs, varkw, frame.f_locals + +def joinseq(seq): + if len(seq) == 1: + return '(' + seq[0] + ',)' + else: + return '(' + ', '.join(seq) + ')' + +def strseq(object, convert, join=joinseq): + """Recursively walk a sequence, stringifying each element. + + """ + if type(object) in [list, tuple]: + return join([strseq(_o, convert, join) for _o in object]) + else: + return convert(object) + +def formatargspec(args, varargs=None, varkw=None, defaults=None, + formatarg=str, + formatvarargs=lambda name: '*' + name, + formatvarkw=lambda name: '**' + name, + formatvalue=lambda value: '=' + repr(value), + join=joinseq): + """Format an argument spec from the 4 values returned by getargspec. + + The first four arguments are (args, varargs, varkw, defaults). The + other four arguments are the corresponding optional formatting functions + that are called to turn names and values into strings. The ninth + argument is an optional function to format the sequence of arguments. + + """ + specs = [] + if defaults: + firstdefault = len(args) - len(defaults) + for i in range(len(args)): + spec = strseq(args[i], formatarg, join) + if defaults and i >= firstdefault: + spec = spec + formatvalue(defaults[i - firstdefault]) + specs.append(spec) + if varargs is not None: + specs.append(formatvarargs(varargs)) + if varkw is not None: + specs.append(formatvarkw(varkw)) + return '(' + ', '.join(specs) + ')' + +def formatargvalues(args, varargs, varkw, locals, + formatarg=str, + formatvarargs=lambda name: '*' + name, + formatvarkw=lambda name: '**' + name, + formatvalue=lambda value: '=' + repr(value), + join=joinseq): + """Format an argument spec from the 4 values returned by getargvalues. + + The first four arguments are (args, varargs, varkw, locals). The + next four arguments are the corresponding optional formatting functions + that are called to turn names and values into strings. The ninth + argument is an optional function to format the sequence of arguments. + + """ + def convert(name, locals=locals, + formatarg=formatarg, formatvalue=formatvalue): + return formatarg(name) + formatvalue(locals[name]) + specs = [strseq(arg, convert, join) for arg in args] + + if varargs: + specs.append(formatvarargs(varargs) + formatvalue(locals[varargs])) + if varkw: + specs.append(formatvarkw(varkw) + formatvalue(locals[varkw])) + return '(' + ', '.join(specs) + ')' diff --git a/venv/Lib/site-packages/numpy/compat/py3k.py b/venv/Lib/site-packages/numpy/compat/py3k.py new file mode 100644 index 0000000..f36aaca --- /dev/null +++ b/venv/Lib/site-packages/numpy/compat/py3k.py @@ -0,0 +1,136 @@ +""" +Python 3.X compatibility tools. + +While this file was originally intended for Python 2 -> 3 transition, +it is now used to create a compatibility layer between different +minor versions of Python 3. + +While the active version of numpy may not support a given version of python, we +allow downstream libraries to continue to use these shims for forward +compatibility with numpy while they transition their code to newer versions of +Python. +""" +__all__ = ['bytes', 'asbytes', 'isfileobj', 'getexception', 'strchar', + 'unicode', 'asunicode', 'asbytes_nested', 'asunicode_nested', + 'asstr', 'open_latin1', 'long', 'basestring', 'sixu', + 'integer_types', 'is_pathlib_path', 'npy_load_module', 'Path', + 'pickle', 'contextlib_nullcontext', 'os_fspath', 'os_PathLike'] + +import sys +import os +from pathlib import Path +import io + +import abc +from abc import ABC as abc_ABC + +try: + import pickle5 as pickle +except ImportError: + import pickle + +long = int +integer_types = (int,) +basestring = str +unicode = str +bytes = bytes + +def asunicode(s): + if isinstance(s, bytes): + return s.decode('latin1') + return str(s) + +def asbytes(s): + if isinstance(s, bytes): + return s + return str(s).encode('latin1') + +def asstr(s): + if isinstance(s, bytes): + return s.decode('latin1') + return str(s) + +def isfileobj(f): + return isinstance(f, (io.FileIO, io.BufferedReader, io.BufferedWriter)) + +def open_latin1(filename, mode='r'): + return open(filename, mode=mode, encoding='iso-8859-1') + +def sixu(s): + return s + +strchar = 'U' + +def getexception(): + return sys.exc_info()[1] + +def asbytes_nested(x): + if hasattr(x, '__iter__') and not isinstance(x, (bytes, unicode)): + return [asbytes_nested(y) for y in x] + else: + return asbytes(x) + +def asunicode_nested(x): + if hasattr(x, '__iter__') and not isinstance(x, (bytes, unicode)): + return [asunicode_nested(y) for y in x] + else: + return asunicode(x) + +def is_pathlib_path(obj): + """ + Check whether obj is a `pathlib.Path` object. + + Prefer using ``isinstance(obj, os.PathLike)`` instead of this function. + """ + return isinstance(obj, Path) + +# from Python 3.7 +class contextlib_nullcontext: + """Context manager that does no additional processing. + + Used as a stand-in for a normal context manager, when a particular + block of code is only sometimes used with a normal context manager: + + cm = optional_cm if condition else nullcontext() + with cm: + # Perform operation, using optional_cm if condition is True + """ + + def __init__(self, enter_result=None): + self.enter_result = enter_result + + def __enter__(self): + return self.enter_result + + def __exit__(self, *excinfo): + pass + + +def npy_load_module(name, fn, info=None): + """ + Load a module. + + .. versionadded:: 1.11.2 + + Parameters + ---------- + name : str + Full module name. + fn : str + Path to module file. + info : tuple, optional + Only here for backward compatibility with Python 2.*. + + Returns + ------- + mod : module + + """ + # Explicitly lazy import this to avoid paying the cost + # of importing importlib at startup + from importlib.machinery import SourceFileLoader + return SourceFileLoader(name, fn).load_module() + + +os_fspath = os.fspath +os_PathLike = os.PathLike diff --git a/venv/Lib/site-packages/numpy/compat/setup.py b/venv/Lib/site-packages/numpy/compat/setup.py new file mode 100644 index 0000000..c1b34a2 --- /dev/null +++ b/venv/Lib/site-packages/numpy/compat/setup.py @@ -0,0 +1,10 @@ +def configuration(parent_package='',top_path=None): + from numpy.distutils.misc_util import Configuration + + config = Configuration('compat', parent_package, top_path) + config.add_subpackage('tests') + return config + +if __name__ == '__main__': + from numpy.distutils.core import setup + setup(configuration=configuration) diff --git a/venv/Lib/site-packages/numpy/compat/tests/__init__.py b/venv/Lib/site-packages/numpy/compat/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/venv/Lib/site-packages/numpy/compat/tests/test_compat.py b/venv/Lib/site-packages/numpy/compat/tests/test_compat.py new file mode 100644 index 0000000..2b8acba --- /dev/null +++ b/venv/Lib/site-packages/numpy/compat/tests/test_compat.py @@ -0,0 +1,19 @@ +from os.path import join + +from numpy.compat import isfileobj +from numpy.testing import assert_ +from numpy.testing import tempdir + + +def test_isfileobj(): + with tempdir(prefix="numpy_test_compat_") as folder: + filename = join(folder, 'a.bin') + + with open(filename, 'wb') as f: + assert_(isfileobj(f)) + + with open(filename, 'ab') as f: + assert_(isfileobj(f)) + + with open(filename, 'rb') as f: + assert_(isfileobj(f)) diff --git a/venv/Lib/site-packages/numpy/conftest.py b/venv/Lib/site-packages/numpy/conftest.py new file mode 100644 index 0000000..e15ee08 --- /dev/null +++ b/venv/Lib/site-packages/numpy/conftest.py @@ -0,0 +1,119 @@ +""" +Pytest configuration and fixtures for the Numpy test suite. +""" +import os +import tempfile + +import hypothesis +import pytest +import numpy + +from numpy.core._multiarray_tests import get_fpu_mode + + +_old_fpu_mode = None +_collect_results = {} + +# Use a known and persistent tmpdir for hypothesis' caches, which +# can be automatically cleared by the OS or user. +hypothesis.configuration.set_hypothesis_home_dir( + os.path.join(tempfile.gettempdir(), ".hypothesis") +) + +# We register two custom profiles for Numpy - for details see +# https://hypothesis.readthedocs.io/en/latest/settings.html +# The first is designed for our own CI runs; the latter also +# forces determinism and is designed for use via np.test() +hypothesis.settings.register_profile( + name="numpy-profile", deadline=None, print_blob=True, +) +hypothesis.settings.register_profile( + name="np.test() profile", + deadline=None, print_blob=True, database=None, derandomize=True, + suppress_health_check=hypothesis.HealthCheck.all(), +) +# Note that the default profile is chosen based on the presence +# of pytest.ini, but can be overriden by passing the +# --hypothesis-profile=NAME argument to pytest. +_pytest_ini = os.path.join(os.path.dirname(__file__), "..", "pytest.ini") +hypothesis.settings.load_profile( + "numpy-profile" if os.path.isfile(_pytest_ini) else "np.test() profile" +) + + +def pytest_configure(config): + config.addinivalue_line("markers", + "valgrind_error: Tests that are known to error under valgrind.") + config.addinivalue_line("markers", + "leaks_references: Tests that are known to leak references.") + config.addinivalue_line("markers", + "slow: Tests that are very slow.") + config.addinivalue_line("markers", + "slow_pypy: Tests that are very slow on pypy.") + + +def pytest_addoption(parser): + parser.addoption("--available-memory", action="store", default=None, + help=("Set amount of memory available for running the " + "test suite. This can result to tests requiring " + "especially large amounts of memory to be skipped. " + "Equivalent to setting environment variable " + "NPY_AVAILABLE_MEM. Default: determined" + "automatically.")) + + +def pytest_sessionstart(session): + available_mem = session.config.getoption('available_memory') + if available_mem is not None: + os.environ['NPY_AVAILABLE_MEM'] = available_mem + + +#FIXME when yield tests are gone. +@pytest.hookimpl() +def pytest_itemcollected(item): + """ + Check FPU precision mode was not changed during test collection. + + The clumsy way we do it here is mainly necessary because numpy + still uses yield tests, which can execute code at test collection + time. + """ + global _old_fpu_mode + + mode = get_fpu_mode() + + if _old_fpu_mode is None: + _old_fpu_mode = mode + elif mode != _old_fpu_mode: + _collect_results[item] = (_old_fpu_mode, mode) + _old_fpu_mode = mode + + +@pytest.fixture(scope="function", autouse=True) +def check_fpu_mode(request): + """ + Check FPU precision mode was not changed during the test. + """ + old_mode = get_fpu_mode() + yield + new_mode = get_fpu_mode() + + if old_mode != new_mode: + raise AssertionError("FPU precision mode changed from {0:#x} to {1:#x}" + " during the test".format(old_mode, new_mode)) + + collect_result = _collect_results.get(request.node) + if collect_result is not None: + old_mode, new_mode = collect_result + raise AssertionError("FPU precision mode changed from {0:#x} to {1:#x}" + " when collecting the test".format(old_mode, + new_mode)) + + +@pytest.fixture(autouse=True) +def add_np(doctest_namespace): + doctest_namespace['np'] = numpy + +@pytest.fixture(autouse=True) +def env_setup(monkeypatch): + monkeypatch.setenv('PYTHONHASHSEED', '0') diff --git a/venv/Lib/site-packages/numpy/core/__init__.py b/venv/Lib/site-packages/numpy/core/__init__.py new file mode 100644 index 0000000..2534e5f --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/__init__.py @@ -0,0 +1,166 @@ +""" +Contains the core of NumPy: ndarray, ufuncs, dtypes, etc. + +Please note that this module is private. All functions and objects +are available in the main ``numpy`` namespace - use that instead. + +""" + +from numpy.version import version as __version__ + +import os + +# disables OpenBLAS affinity setting of the main thread that limits +# python threads or processes to one core +env_added = [] +for envkey in ['OPENBLAS_MAIN_FREE', 'GOTOBLAS_MAIN_FREE']: + if envkey not in os.environ: + os.environ[envkey] = '1' + env_added.append(envkey) + +try: + from . import multiarray +except ImportError as exc: + import sys + msg = """ + +IMPORTANT: PLEASE READ THIS FOR ADVICE ON HOW TO SOLVE THIS ISSUE! + +Importing the numpy C-extensions failed. This error can happen for +many reasons, often due to issues with your setup or how NumPy was +installed. + +We have compiled some common reasons and troubleshooting tips at: + + https://numpy.org/devdocs/user/troubleshooting-importerror.html + +Please note and check the following: + + * The Python version is: Python%d.%d from "%s" + * The NumPy version is: "%s" + +and make sure that they are the versions you expect. +Please carefully study the documentation linked above for further help. + +Original error was: %s +""" % (sys.version_info[0], sys.version_info[1], sys.executable, + __version__, exc) + raise ImportError(msg) +finally: + for envkey in env_added: + del os.environ[envkey] +del envkey +del env_added +del os + +from . import umath + +# Check that multiarray,umath are pure python modules wrapping +# _multiarray_umath and not either of the old c-extension modules +if not (hasattr(multiarray, '_multiarray_umath') and + hasattr(umath, '_multiarray_umath')): + import sys + path = sys.modules['numpy'].__path__ + msg = ("Something is wrong with the numpy installation. " + "While importing we detected an older version of " + "numpy in {}. One method of fixing this is to repeatedly uninstall " + "numpy until none is found, then reinstall this version.") + raise ImportError(msg.format(path)) + +from . import numerictypes as nt +multiarray.set_typeDict(nt.sctypeDict) +from . import numeric +from .numeric import * +from . import fromnumeric +from .fromnumeric import * +from . import defchararray as char +from . import records as rec +from .records import * +from .memmap import * +from .defchararray import chararray +from . import function_base +from .function_base import * +from . import machar +from .machar import * +from . import getlimits +from .getlimits import * +from . import shape_base +from .shape_base import * +from . import einsumfunc +from .einsumfunc import * +del nt + +from .fromnumeric import amax as max, amin as min, round_ as round +from .numeric import absolute as abs + +# do this after everything else, to minimize the chance of this misleadingly +# appearing in an import-time traceback +from . import _add_newdocs +from . import _add_newdocs_scalars +# add these for module-freeze analysis (like PyInstaller) +from . import _dtype_ctypes +from . import _internal +from . import _dtype +from . import _methods + +__all__ = ['char', 'rec', 'memmap'] +__all__ += numeric.__all__ +__all__ += fromnumeric.__all__ +__all__ += rec.__all__ +__all__ += ['chararray'] +__all__ += function_base.__all__ +__all__ += machar.__all__ +__all__ += getlimits.__all__ +__all__ += shape_base.__all__ +__all__ += einsumfunc.__all__ + +# We used to use `np.core._ufunc_reconstruct` to unpickle. This is unnecessary, +# but old pickles saved before 1.20 will be using it, and there is no reason +# to break loading them. +def _ufunc_reconstruct(module, name): + # The `fromlist` kwarg is required to ensure that `mod` points to the + # inner-most module rather than the parent package when module name is + # nested. This makes it possible to pickle non-toplevel ufuncs such as + # scipy.special.expit for instance. + mod = __import__(module, fromlist=[name]) + return getattr(mod, name) + + +def _ufunc_reduce(func): + # Report the `__name__`. pickle will try to find the module. Note that + # pickle supports for this `__name__` to be a `__qualname__`. It may + # make sense to add a `__qualname__` to ufuncs, to allow this more + # explicitly (Numba has ufuncs as attributes). + # See also: https://github.com/dask/distributed/issues/3450 + return func.__name__ + + +def _DType_reconstruct(scalar_type): + # This is a work-around to pickle type(np.dtype(np.float64)), etc. + # and it should eventually be replaced with a better solution, e.g. when + # DTypes become HeapTypes. + return type(dtype(scalar_type)) + + +def _DType_reduce(DType): + # To pickle a DType without having to add top-level names, pickle the + # scalar type for now (and assume that reconstruction will be possible). + if DType is dtype: + return "dtype" # must pickle `np.dtype` as a singleton. + scalar_type = DType.type # pickle the scalar type for reconstruction + return _DType_reconstruct, (scalar_type,) + + +import copyreg + +copyreg.pickle(ufunc, _ufunc_reduce) +copyreg.pickle(type(dtype), _DType_reduce, _DType_reconstruct) + +# Unclutter namespace (must keep _*_reconstruct for unpickling) +del copyreg +del _ufunc_reduce +del _DType_reduce + +from numpy._pytesttester import PytestTester +test = PytestTester(__name__) +del PytestTester diff --git a/venv/Lib/site-packages/numpy/core/__init__.pyi b/venv/Lib/site-packages/numpy/core/__init__.pyi new file mode 100644 index 0000000..e69de29 diff --git a/venv/Lib/site-packages/numpy/core/_add_newdocs.py b/venv/Lib/site-packages/numpy/core/_add_newdocs.py new file mode 100644 index 0000000..e2bf6c4 --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/_add_newdocs.py @@ -0,0 +1,6284 @@ +""" +This is only meant to add docs to objects defined in C-extension modules. +The purpose is to allow easier editing of the docstrings without +requiring a re-compile. + +NOTE: Many of the methods of ndarray have corresponding functions. + If you update these docstrings, please keep also the ones in + core/fromnumeric.py, core/defmatrix.py up-to-date. + +""" + +from numpy.core.function_base import add_newdoc +from numpy.core.overrides import array_function_like_doc + +############################################################################### +# +# flatiter +# +# flatiter needs a toplevel description +# +############################################################################### + +add_newdoc('numpy.core', 'flatiter', + """ + Flat iterator object to iterate over arrays. + + A `flatiter` iterator is returned by ``x.flat`` for any array `x`. + It allows iterating over the array as if it were a 1-D array, + either in a for-loop or by calling its `next` method. + + Iteration is done in row-major, C-style order (the last + index varying the fastest). The iterator can also be indexed using + basic slicing or advanced indexing. + + See Also + -------- + ndarray.flat : Return a flat iterator over an array. + ndarray.flatten : Returns a flattened copy of an array. + + Notes + ----- + A `flatiter` iterator can not be constructed directly from Python code + by calling the `flatiter` constructor. + + Examples + -------- + >>> x = np.arange(6).reshape(2, 3) + >>> fl = x.flat + >>> type(fl) + + >>> for item in fl: + ... print(item) + ... + 0 + 1 + 2 + 3 + 4 + 5 + + >>> fl[2:4] + array([2, 3]) + + """) + +# flatiter attributes + +add_newdoc('numpy.core', 'flatiter', ('base', + """ + A reference to the array that is iterated over. + + Examples + -------- + >>> x = np.arange(5) + >>> fl = x.flat + >>> fl.base is x + True + + """)) + + + +add_newdoc('numpy.core', 'flatiter', ('coords', + """ + An N-dimensional tuple of current coordinates. + + Examples + -------- + >>> x = np.arange(6).reshape(2, 3) + >>> fl = x.flat + >>> fl.coords + (0, 0) + >>> next(fl) + 0 + >>> fl.coords + (0, 1) + + """)) + + + +add_newdoc('numpy.core', 'flatiter', ('index', + """ + Current flat index into the array. + + Examples + -------- + >>> x = np.arange(6).reshape(2, 3) + >>> fl = x.flat + >>> fl.index + 0 + >>> next(fl) + 0 + >>> fl.index + 1 + + """)) + +# flatiter functions + +add_newdoc('numpy.core', 'flatiter', ('__array__', + """__array__(type=None) Get array from iterator + + """)) + + +add_newdoc('numpy.core', 'flatiter', ('copy', + """ + copy() + + Get a copy of the iterator as a 1-D array. + + Examples + -------- + >>> x = np.arange(6).reshape(2, 3) + >>> x + array([[0, 1, 2], + [3, 4, 5]]) + >>> fl = x.flat + >>> fl.copy() + array([0, 1, 2, 3, 4, 5]) + + """)) + + +############################################################################### +# +# nditer +# +############################################################################### + +add_newdoc('numpy.core', 'nditer', + """ + nditer(op, flags=None, op_flags=None, op_dtypes=None, order='K', casting='safe', op_axes=None, itershape=None, buffersize=0) + + Efficient multi-dimensional iterator object to iterate over arrays. + To get started using this object, see the + :ref:`introductory guide to array iteration `. + + Parameters + ---------- + op : ndarray or sequence of array_like + The array(s) to iterate over. + + flags : sequence of str, optional + Flags to control the behavior of the iterator. + + * ``buffered`` enables buffering when required. + * ``c_index`` causes a C-order index to be tracked. + * ``f_index`` causes a Fortran-order index to be tracked. + * ``multi_index`` causes a multi-index, or a tuple of indices + with one per iteration dimension, to be tracked. + * ``common_dtype`` causes all the operands to be converted to + a common data type, with copying or buffering as necessary. + * ``copy_if_overlap`` causes the iterator to determine if read + operands have overlap with write operands, and make temporary + copies as necessary to avoid overlap. False positives (needless + copying) are possible in some cases. + * ``delay_bufalloc`` delays allocation of the buffers until + a reset() call is made. Allows ``allocate`` operands to + be initialized before their values are copied into the buffers. + * ``external_loop`` causes the ``values`` given to be + one-dimensional arrays with multiple values instead of + zero-dimensional arrays. + * ``grow_inner`` allows the ``value`` array sizes to be made + larger than the buffer size when both ``buffered`` and + ``external_loop`` is used. + * ``ranged`` allows the iterator to be restricted to a sub-range + of the iterindex values. + * ``refs_ok`` enables iteration of reference types, such as + object arrays. + * ``reduce_ok`` enables iteration of ``readwrite`` operands + which are broadcasted, also known as reduction operands. + * ``zerosize_ok`` allows `itersize` to be zero. + op_flags : list of list of str, optional + This is a list of flags for each operand. At minimum, one of + ``readonly``, ``readwrite``, or ``writeonly`` must be specified. + + * ``readonly`` indicates the operand will only be read from. + * ``readwrite`` indicates the operand will be read from and written to. + * ``writeonly`` indicates the operand will only be written to. + * ``no_broadcast`` prevents the operand from being broadcasted. + * ``contig`` forces the operand data to be contiguous. + * ``aligned`` forces the operand data to be aligned. + * ``nbo`` forces the operand data to be in native byte order. + * ``copy`` allows a temporary read-only copy if required. + * ``updateifcopy`` allows a temporary read-write copy if required. + * ``allocate`` causes the array to be allocated if it is None + in the ``op`` parameter. + * ``no_subtype`` prevents an ``allocate`` operand from using a subtype. + * ``arraymask`` indicates that this operand is the mask to use + for selecting elements when writing to operands with the + 'writemasked' flag set. The iterator does not enforce this, + but when writing from a buffer back to the array, it only + copies those elements indicated by this mask. + * ``writemasked`` indicates that only elements where the chosen + ``arraymask`` operand is True will be written to. + * ``overlap_assume_elementwise`` can be used to mark operands that are + accessed only in the iterator order, to allow less conservative + copying when ``copy_if_overlap`` is present. + op_dtypes : dtype or tuple of dtype(s), optional + The required data type(s) of the operands. If copying or buffering + is enabled, the data will be converted to/from their original types. + order : {'C', 'F', 'A', 'K'}, optional + Controls the iteration order. 'C' means C order, 'F' means + Fortran order, 'A' means 'F' order if all the arrays are Fortran + contiguous, 'C' order otherwise, and 'K' means as close to the + order the array elements appear in memory as possible. This also + affects the element memory order of ``allocate`` operands, as they + are allocated to be compatible with iteration order. + Default is 'K'. + casting : {'no', 'equiv', 'safe', 'same_kind', 'unsafe'}, optional + Controls what kind of data casting may occur when making a copy + or buffering. Setting this to 'unsafe' is not recommended, + as it can adversely affect accumulations. + + * 'no' means the data types should not be cast at all. + * 'equiv' means only byte-order changes are allowed. + * 'safe' means only casts which can preserve values are allowed. + * 'same_kind' means only safe casts or casts within a kind, + like float64 to float32, are allowed. + * 'unsafe' means any data conversions may be done. + op_axes : list of list of ints, optional + If provided, is a list of ints or None for each operands. + The list of axes for an operand is a mapping from the dimensions + of the iterator to the dimensions of the operand. A value of + -1 can be placed for entries, causing that dimension to be + treated as `newaxis`. + itershape : tuple of ints, optional + The desired shape of the iterator. This allows ``allocate`` operands + with a dimension mapped by op_axes not corresponding to a dimension + of a different operand to get a value not equal to 1 for that + dimension. + buffersize : int, optional + When buffering is enabled, controls the size of the temporary + buffers. Set to 0 for the default value. + + Attributes + ---------- + dtypes : tuple of dtype(s) + The data types of the values provided in `value`. This may be + different from the operand data types if buffering is enabled. + Valid only before the iterator is closed. + finished : bool + Whether the iteration over the operands is finished or not. + has_delayed_bufalloc : bool + If True, the iterator was created with the ``delay_bufalloc`` flag, + and no reset() function was called on it yet. + has_index : bool + If True, the iterator was created with either the ``c_index`` or + the ``f_index`` flag, and the property `index` can be used to + retrieve it. + has_multi_index : bool + If True, the iterator was created with the ``multi_index`` flag, + and the property `multi_index` can be used to retrieve it. + index + When the ``c_index`` or ``f_index`` flag was used, this property + provides access to the index. Raises a ValueError if accessed + and ``has_index`` is False. + iterationneedsapi : bool + Whether iteration requires access to the Python API, for example + if one of the operands is an object array. + iterindex : int + An index which matches the order of iteration. + itersize : int + Size of the iterator. + itviews + Structured view(s) of `operands` in memory, matching the reordered + and optimized iterator access pattern. Valid only before the iterator + is closed. + multi_index + When the ``multi_index`` flag was used, this property + provides access to the index. Raises a ValueError if accessed + accessed and ``has_multi_index`` is False. + ndim : int + The dimensions of the iterator. + nop : int + The number of iterator operands. + operands : tuple of operand(s) + The array(s) to be iterated over. Valid only before the iterator is + closed. + shape : tuple of ints + Shape tuple, the shape of the iterator. + value + Value of ``operands`` at current iteration. Normally, this is a + tuple of array scalars, but if the flag ``external_loop`` is used, + it is a tuple of one dimensional arrays. + + Notes + ----- + `nditer` supersedes `flatiter`. The iterator implementation behind + `nditer` is also exposed by the NumPy C API. + + The Python exposure supplies two iteration interfaces, one which follows + the Python iterator protocol, and another which mirrors the C-style + do-while pattern. The native Python approach is better in most cases, but + if you need the coordinates or index of an iterator, use the C-style pattern. + + Examples + -------- + Here is how we might write an ``iter_add`` function, using the + Python iterator protocol: + + >>> def iter_add_py(x, y, out=None): + ... addop = np.add + ... it = np.nditer([x, y, out], [], + ... [['readonly'], ['readonly'], ['writeonly','allocate']]) + ... with it: + ... for (a, b, c) in it: + ... addop(a, b, out=c) + ... return it.operands[2] + + Here is the same function, but following the C-style pattern: + + >>> def iter_add(x, y, out=None): + ... addop = np.add + ... it = np.nditer([x, y, out], [], + ... [['readonly'], ['readonly'], ['writeonly','allocate']]) + ... with it: + ... while not it.finished: + ... addop(it[0], it[1], out=it[2]) + ... it.iternext() + ... return it.operands[2] + + Here is an example outer product function: + + >>> def outer_it(x, y, out=None): + ... mulop = np.multiply + ... it = np.nditer([x, y, out], ['external_loop'], + ... [['readonly'], ['readonly'], ['writeonly', 'allocate']], + ... op_axes=[list(range(x.ndim)) + [-1] * y.ndim, + ... [-1] * x.ndim + list(range(y.ndim)), + ... None]) + ... with it: + ... for (a, b, c) in it: + ... mulop(a, b, out=c) + ... return it.operands[2] + + >>> a = np.arange(2)+1 + >>> b = np.arange(3)+1 + >>> outer_it(a,b) + array([[1, 2, 3], + [2, 4, 6]]) + + Here is an example function which operates like a "lambda" ufunc: + + >>> def luf(lamdaexpr, *args, **kwargs): + ... '''luf(lambdaexpr, op1, ..., opn, out=None, order='K', casting='safe', buffersize=0)''' + ... nargs = len(args) + ... op = (kwargs.get('out',None),) + args + ... it = np.nditer(op, ['buffered','external_loop'], + ... [['writeonly','allocate','no_broadcast']] + + ... [['readonly','nbo','aligned']]*nargs, + ... order=kwargs.get('order','K'), + ... casting=kwargs.get('casting','safe'), + ... buffersize=kwargs.get('buffersize',0)) + ... while not it.finished: + ... it[0] = lamdaexpr(*it[1:]) + ... it.iternext() + ... return it.operands[0] + + >>> a = np.arange(5) + >>> b = np.ones(5) + >>> luf(lambda i,j:i*i + j/2, a, b) + array([ 0.5, 1.5, 4.5, 9.5, 16.5]) + + If operand flags `"writeonly"` or `"readwrite"` are used the + operands may be views into the original data with the + `WRITEBACKIFCOPY` flag. In this case `nditer` must be used as a + context manager or the `nditer.close` method must be called before + using the result. The temporary data will be written back to the + original data when the `__exit__` function is called but not before: + + >>> a = np.arange(6, dtype='i4')[::-2] + >>> with np.nditer(a, [], + ... [['writeonly', 'updateifcopy']], + ... casting='unsafe', + ... op_dtypes=[np.dtype('f4')]) as i: + ... x = i.operands[0] + ... x[:] = [-1, -2, -3] + ... # a still unchanged here + >>> a, x + (array([-1, -2, -3], dtype=int32), array([-1., -2., -3.], dtype=float32)) + + It is important to note that once the iterator is exited, dangling + references (like `x` in the example) may or may not share data with + the original data `a`. If writeback semantics were active, i.e. if + `x.base.flags.writebackifcopy` is `True`, then exiting the iterator + will sever the connection between `x` and `a`, writing to `x` will + no longer write to `a`. If writeback semantics are not active, then + `x.data` will still point at some part of `a.data`, and writing to + one will affect the other. + + Context management and the `close` method appeared in version 1.15.0. + + """) + +# nditer methods + +add_newdoc('numpy.core', 'nditer', ('copy', + """ + copy() + + Get a copy of the iterator in its current state. + + Examples + -------- + >>> x = np.arange(10) + >>> y = x + 1 + >>> it = np.nditer([x, y]) + >>> next(it) + (array(0), array(1)) + >>> it2 = it.copy() + >>> next(it2) + (array(1), array(2)) + + """)) + +add_newdoc('numpy.core', 'nditer', ('operands', + """ + operands[`Slice`] + + The array(s) to be iterated over. Valid only before the iterator is closed. + """)) + +add_newdoc('numpy.core', 'nditer', ('debug_print', + """ + debug_print() + + Print the current state of the `nditer` instance and debug info to stdout. + + """)) + +add_newdoc('numpy.core', 'nditer', ('enable_external_loop', + """ + enable_external_loop() + + When the "external_loop" was not used during construction, but + is desired, this modifies the iterator to behave as if the flag + was specified. + + """)) + +add_newdoc('numpy.core', 'nditer', ('iternext', + """ + iternext() + + Check whether iterations are left, and perform a single internal iteration + without returning the result. Used in the C-style pattern do-while + pattern. For an example, see `nditer`. + + Returns + ------- + iternext : bool + Whether or not there are iterations left. + + """)) + +add_newdoc('numpy.core', 'nditer', ('remove_axis', + """ + remove_axis(i) + + Removes axis `i` from the iterator. Requires that the flag "multi_index" + be enabled. + + """)) + +add_newdoc('numpy.core', 'nditer', ('remove_multi_index', + """ + remove_multi_index() + + When the "multi_index" flag was specified, this removes it, allowing + the internal iteration structure to be optimized further. + + """)) + +add_newdoc('numpy.core', 'nditer', ('reset', + """ + reset() + + Reset the iterator to its initial state. + + """)) + +add_newdoc('numpy.core', 'nested_iters', + """ + Create nditers for use in nested loops + + Create a tuple of `nditer` objects which iterate in nested loops over + different axes of the op argument. The first iterator is used in the + outermost loop, the last in the innermost loop. Advancing one will change + the subsequent iterators to point at its new element. + + Parameters + ---------- + op : ndarray or sequence of array_like + The array(s) to iterate over. + + axes : list of list of int + Each item is used as an "op_axes" argument to an nditer + + flags, op_flags, op_dtypes, order, casting, buffersize (optional) + See `nditer` parameters of the same name + + Returns + ------- + iters : tuple of nditer + An nditer for each item in `axes`, outermost first + + See Also + -------- + nditer + + Examples + -------- + + Basic usage. Note how y is the "flattened" version of + [a[:, 0, :], a[:, 1, 0], a[:, 2, :]] since we specified + the first iter's axes as [1] + + >>> a = np.arange(12).reshape(2, 3, 2) + >>> i, j = np.nested_iters(a, [[1], [0, 2]], flags=["multi_index"]) + >>> for x in i: + ... print(i.multi_index) + ... for y in j: + ... print('', j.multi_index, y) + (0,) + (0, 0) 0 + (0, 1) 1 + (1, 0) 6 + (1, 1) 7 + (1,) + (0, 0) 2 + (0, 1) 3 + (1, 0) 8 + (1, 1) 9 + (2,) + (0, 0) 4 + (0, 1) 5 + (1, 0) 10 + (1, 1) 11 + + """) + +add_newdoc('numpy.core', 'nditer', ('close', + """ + close() + + Resolve all writeback semantics in writeable operands. + + .. versionadded:: 1.15.0 + + See Also + -------- + + :ref:`nditer-context-manager` + + """)) + + +############################################################################### +# +# broadcast +# +############################################################################### + +add_newdoc('numpy.core', 'broadcast', + """ + Produce an object that mimics broadcasting. + + Parameters + ---------- + in1, in2, ... : array_like + Input parameters. + + Returns + ------- + b : broadcast object + Broadcast the input parameters against one another, and + return an object that encapsulates the result. + Amongst others, it has ``shape`` and ``nd`` properties, and + may be used as an iterator. + + See Also + -------- + broadcast_arrays + broadcast_to + broadcast_shapes + + Examples + -------- + + Manually adding two vectors, using broadcasting: + + >>> x = np.array([[1], [2], [3]]) + >>> y = np.array([4, 5, 6]) + >>> b = np.broadcast(x, y) + + >>> out = np.empty(b.shape) + >>> out.flat = [u+v for (u,v) in b] + >>> out + array([[5., 6., 7.], + [6., 7., 8.], + [7., 8., 9.]]) + + Compare against built-in broadcasting: + + >>> x + y + array([[5, 6, 7], + [6, 7, 8], + [7, 8, 9]]) + + """) + +# attributes + +add_newdoc('numpy.core', 'broadcast', ('index', + """ + current index in broadcasted result + + Examples + -------- + >>> x = np.array([[1], [2], [3]]) + >>> y = np.array([4, 5, 6]) + >>> b = np.broadcast(x, y) + >>> b.index + 0 + >>> next(b), next(b), next(b) + ((1, 4), (1, 5), (1, 6)) + >>> b.index + 3 + + """)) + +add_newdoc('numpy.core', 'broadcast', ('iters', + """ + tuple of iterators along ``self``'s "components." + + Returns a tuple of `numpy.flatiter` objects, one for each "component" + of ``self``. + + See Also + -------- + numpy.flatiter + + Examples + -------- + >>> x = np.array([1, 2, 3]) + >>> y = np.array([[4], [5], [6]]) + >>> b = np.broadcast(x, y) + >>> row, col = b.iters + >>> next(row), next(col) + (1, 4) + + """)) + +add_newdoc('numpy.core', 'broadcast', ('ndim', + """ + Number of dimensions of broadcasted result. Alias for `nd`. + + .. versionadded:: 1.12.0 + + Examples + -------- + >>> x = np.array([1, 2, 3]) + >>> y = np.array([[4], [5], [6]]) + >>> b = np.broadcast(x, y) + >>> b.ndim + 2 + + """)) + +add_newdoc('numpy.core', 'broadcast', ('nd', + """ + Number of dimensions of broadcasted result. For code intended for NumPy + 1.12.0 and later the more consistent `ndim` is preferred. + + Examples + -------- + >>> x = np.array([1, 2, 3]) + >>> y = np.array([[4], [5], [6]]) + >>> b = np.broadcast(x, y) + >>> b.nd + 2 + + """)) + +add_newdoc('numpy.core', 'broadcast', ('numiter', + """ + Number of iterators possessed by the broadcasted result. + + Examples + -------- + >>> x = np.array([1, 2, 3]) + >>> y = np.array([[4], [5], [6]]) + >>> b = np.broadcast(x, y) + >>> b.numiter + 2 + + """)) + +add_newdoc('numpy.core', 'broadcast', ('shape', + """ + Shape of broadcasted result. + + Examples + -------- + >>> x = np.array([1, 2, 3]) + >>> y = np.array([[4], [5], [6]]) + >>> b = np.broadcast(x, y) + >>> b.shape + (3, 3) + + """)) + +add_newdoc('numpy.core', 'broadcast', ('size', + """ + Total size of broadcasted result. + + Examples + -------- + >>> x = np.array([1, 2, 3]) + >>> y = np.array([[4], [5], [6]]) + >>> b = np.broadcast(x, y) + >>> b.size + 9 + + """)) + +add_newdoc('numpy.core', 'broadcast', ('reset', + """ + reset() + + Reset the broadcasted result's iterator(s). + + Parameters + ---------- + None + + Returns + ------- + None + + Examples + -------- + >>> x = np.array([1, 2, 3]) + >>> y = np.array([[4], [5], [6]]) + >>> b = np.broadcast(x, y) + >>> b.index + 0 + >>> next(b), next(b), next(b) + ((1, 4), (2, 4), (3, 4)) + >>> b.index + 3 + >>> b.reset() + >>> b.index + 0 + + """)) + +############################################################################### +# +# numpy functions +# +############################################################################### + +add_newdoc('numpy.core.multiarray', 'array', + """ + array(object, dtype=None, *, copy=True, order='K', subok=False, ndmin=0, + like=None) + + Create an array. + + Parameters + ---------- + object : array_like + An array, any object exposing the array interface, an object whose + __array__ method returns an array, or any (nested) sequence. + dtype : data-type, optional + The desired data-type for the array. If not given, then the type will + be determined as the minimum type required to hold the objects in the + sequence. + copy : bool, optional + If true (default), then the object is copied. Otherwise, a copy will + only be made if __array__ returns a copy, if obj is a nested sequence, + or if a copy is needed to satisfy any of the other requirements + (`dtype`, `order`, etc.). + order : {'K', 'A', 'C', 'F'}, optional + Specify the memory layout of the array. If object is not an array, the + newly created array will be in C order (row major) unless 'F' is + specified, in which case it will be in Fortran order (column major). + If object is an array the following holds. + + ===== ========= =================================================== + order no copy copy=True + ===== ========= =================================================== + 'K' unchanged F & C order preserved, otherwise most similar order + 'A' unchanged F order if input is F and not C, otherwise C order + 'C' C order C order + 'F' F order F order + ===== ========= =================================================== + + When ``copy=False`` and a copy is made for other reasons, the result is + the same as if ``copy=True``, with some exceptions for `A`, see the + Notes section. The default order is 'K'. + subok : bool, optional + If True, then sub-classes will be passed-through, otherwise + the returned array will be forced to be a base-class array (default). + ndmin : int, optional + Specifies the minimum number of dimensions that the resulting + array should have. Ones will be pre-pended to the shape as + needed to meet this requirement. + ${ARRAY_FUNCTION_LIKE} + + .. versionadded:: 1.20.0 + + Returns + ------- + out : ndarray + An array object satisfying the specified requirements. + + See Also + -------- + empty_like : Return an empty array with shape and type of input. + ones_like : Return an array of ones with shape and type of input. + zeros_like : Return an array of zeros with shape and type of input. + full_like : Return a new array with shape of input filled with value. + empty : Return a new uninitialized array. + ones : Return a new array setting values to one. + zeros : Return a new array setting values to zero. + full : Return a new array of given shape filled with value. + + + Notes + ----- + When order is 'A' and `object` is an array in neither 'C' nor 'F' order, + and a copy is forced by a change in dtype, then the order of the result is + not necessarily 'C' as expected. This is likely a bug. + + Examples + -------- + >>> np.array([1, 2, 3]) + array([1, 2, 3]) + + Upcasting: + + >>> np.array([1, 2, 3.0]) + array([ 1., 2., 3.]) + + More than one dimension: + + >>> np.array([[1, 2], [3, 4]]) + array([[1, 2], + [3, 4]]) + + Minimum dimensions 2: + + >>> np.array([1, 2, 3], ndmin=2) + array([[1, 2, 3]]) + + Type provided: + + >>> np.array([1, 2, 3], dtype=complex) + array([ 1.+0.j, 2.+0.j, 3.+0.j]) + + Data-type consisting of more than one element: + + >>> x = np.array([(1,2),(3,4)],dtype=[('a','>> x['a'] + array([1, 3]) + + Creating an array from sub-classes: + + >>> np.array(np.mat('1 2; 3 4')) + array([[1, 2], + [3, 4]]) + + >>> np.array(np.mat('1 2; 3 4'), subok=True) + matrix([[1, 2], + [3, 4]]) + + """.replace( + "${ARRAY_FUNCTION_LIKE}", + array_function_like_doc, + )) + +add_newdoc('numpy.core.multiarray', 'empty', + """ + empty(shape, dtype=float, order='C', *, like=None) + + Return a new array of given shape and type, without initializing entries. + + Parameters + ---------- + shape : int or tuple of int + Shape of the empty array, e.g., ``(2, 3)`` or ``2``. + dtype : data-type, optional + Desired output data-type for the array, e.g, `numpy.int8`. Default is + `numpy.float64`. + order : {'C', 'F'}, optional, default: 'C' + Whether to store multi-dimensional data in row-major + (C-style) or column-major (Fortran-style) order in + memory. + ${ARRAY_FUNCTION_LIKE} + + .. versionadded:: 1.20.0 + + Returns + ------- + out : ndarray + Array of uninitialized (arbitrary) data of the given shape, dtype, and + order. Object arrays will be initialized to None. + + See Also + -------- + empty_like : Return an empty array with shape and type of input. + ones : Return a new array setting values to one. + zeros : Return a new array setting values to zero. + full : Return a new array of given shape filled with value. + + + Notes + ----- + `empty`, unlike `zeros`, does not set the array values to zero, + and may therefore be marginally faster. On the other hand, it requires + the user to manually set all the values in the array, and should be + used with caution. + + Examples + -------- + >>> np.empty([2, 2]) + array([[ -9.74499359e+001, 6.69583040e-309], + [ 2.13182611e-314, 3.06959433e-309]]) #uninitialized + + >>> np.empty([2, 2], dtype=int) + array([[-1073741821, -1067949133], + [ 496041986, 19249760]]) #uninitialized + + """.replace( + "${ARRAY_FUNCTION_LIKE}", + array_function_like_doc, + )) + +add_newdoc('numpy.core.multiarray', 'scalar', + """ + scalar(dtype, obj) + + Return a new scalar array of the given type initialized with obj. + + This function is meant mainly for pickle support. `dtype` must be a + valid data-type descriptor. If `dtype` corresponds to an object + descriptor, then `obj` can be any object, otherwise `obj` must be a + string. If `obj` is not given, it will be interpreted as None for object + type and as zeros for all other types. + + """) + +add_newdoc('numpy.core.multiarray', 'zeros', + """ + zeros(shape, dtype=float, order='C', *, like=None) + + Return a new array of given shape and type, filled with zeros. + + Parameters + ---------- + shape : int or tuple of ints + Shape of the new array, e.g., ``(2, 3)`` or ``2``. + dtype : data-type, optional + The desired data-type for the array, e.g., `numpy.int8`. Default is + `numpy.float64`. + order : {'C', 'F'}, optional, default: 'C' + Whether to store multi-dimensional data in row-major + (C-style) or column-major (Fortran-style) order in + memory. + ${ARRAY_FUNCTION_LIKE} + + .. versionadded:: 1.20.0 + + Returns + ------- + out : ndarray + Array of zeros with the given shape, dtype, and order. + + See Also + -------- + zeros_like : Return an array of zeros with shape and type of input. + empty : Return a new uninitialized array. + ones : Return a new array setting values to one. + full : Return a new array of given shape filled with value. + + Examples + -------- + >>> np.zeros(5) + array([ 0., 0., 0., 0., 0.]) + + >>> np.zeros((5,), dtype=int) + array([0, 0, 0, 0, 0]) + + >>> np.zeros((2, 1)) + array([[ 0.], + [ 0.]]) + + >>> s = (2,2) + >>> np.zeros(s) + array([[ 0., 0.], + [ 0., 0.]]) + + >>> np.zeros((2,), dtype=[('x', 'i4'), ('y', 'i4')]) # custom dtype + array([(0, 0), (0, 0)], + dtype=[('x', '>> np.fromstring('1 2', dtype=int, sep=' ') + array([1, 2]) + >>> np.fromstring('1, 2', dtype=int, sep=',') + array([1, 2]) + + """.replace( + "${ARRAY_FUNCTION_LIKE}", + array_function_like_doc, + )) + +add_newdoc('numpy.core.multiarray', 'compare_chararrays', + """ + compare_chararrays(a, b, cmp_op, rstrip) + + Performs element-wise comparison of two string arrays using the + comparison operator specified by `cmp_op`. + + Parameters + ---------- + a, b : array_like + Arrays to be compared. + cmp_op : {"<", "<=", "==", ">=", ">", "!="} + Type of comparison. + rstrip : Boolean + If True, the spaces at the end of Strings are removed before the comparison. + + Returns + ------- + out : ndarray + The output array of type Boolean with the same shape as a and b. + + Raises + ------ + ValueError + If `cmp_op` is not valid. + TypeError + If at least one of `a` or `b` is a non-string array + + Examples + -------- + >>> a = np.array(["a", "b", "cde"]) + >>> b = np.array(["a", "a", "dec"]) + >>> np.compare_chararrays(a, b, ">", True) + array([False, True, False]) + + """) + +add_newdoc('numpy.core.multiarray', 'fromiter', + """ + fromiter(iterable, dtype, count=-1, *, like=None) + + Create a new 1-dimensional array from an iterable object. + + Parameters + ---------- + iterable : iterable object + An iterable object providing data for the array. + dtype : data-type + The data-type of the returned array. + count : int, optional + The number of items to read from *iterable*. The default is -1, + which means all data is read. + ${ARRAY_FUNCTION_LIKE} + + .. versionadded:: 1.20.0 + + Returns + ------- + out : ndarray + The output array. + + Notes + ----- + Specify `count` to improve performance. It allows ``fromiter`` to + pre-allocate the output array, instead of resizing it on demand. + + Examples + -------- + >>> iterable = (x*x for x in range(5)) + >>> np.fromiter(iterable, float) + array([ 0., 1., 4., 9., 16.]) + + """.replace( + "${ARRAY_FUNCTION_LIKE}", + array_function_like_doc, + )) + +add_newdoc('numpy.core.multiarray', 'fromfile', + """ + fromfile(file, dtype=float, count=-1, sep='', offset=0, *, like=None) + + Construct an array from data in a text or binary file. + + A highly efficient way of reading binary data with a known data-type, + as well as parsing simply formatted text files. Data written using the + `tofile` method can be read using this function. + + Parameters + ---------- + file : file or str or Path + Open file object or filename. + + .. versionchanged:: 1.17.0 + `pathlib.Path` objects are now accepted. + + dtype : data-type + Data type of the returned array. + For binary files, it is used to determine the size and byte-order + of the items in the file. + Most builtin numeric types are supported and extension types may be supported. + + .. versionadded:: 1.18.0 + Complex dtypes. + + count : int + Number of items to read. ``-1`` means all items (i.e., the complete + file). + sep : str + Separator between items if file is a text file. + Empty ("") separator means the file should be treated as binary. + Spaces (" ") in the separator match zero or more whitespace characters. + A separator consisting only of spaces must match at least one + whitespace. + offset : int + The offset (in bytes) from the file's current position. Defaults to 0. + Only permitted for binary files. + + .. versionadded:: 1.17.0 + ${ARRAY_FUNCTION_LIKE} + + .. versionadded:: 1.20.0 + + See also + -------- + load, save + ndarray.tofile + loadtxt : More flexible way of loading data from a text file. + + Notes + ----- + Do not rely on the combination of `tofile` and `fromfile` for + data storage, as the binary files generated are not platform + independent. In particular, no byte-order or data-type information is + saved. Data can be stored in the platform independent ``.npy`` format + using `save` and `load` instead. + + Examples + -------- + Construct an ndarray: + + >>> dt = np.dtype([('time', [('min', np.int64), ('sec', np.int64)]), + ... ('temp', float)]) + >>> x = np.zeros((1,), dtype=dt) + >>> x['time']['min'] = 10; x['temp'] = 98.25 + >>> x + array([((10, 0), 98.25)], + dtype=[('time', [('min', '>> import tempfile + >>> fname = tempfile.mkstemp()[1] + >>> x.tofile(fname) + + Read the raw data from disk: + + >>> np.fromfile(fname, dtype=dt) + array([((10, 0), 98.25)], + dtype=[('time', [('min', '>> np.save(fname, x) + >>> np.load(fname + '.npy') + array([((10, 0), 98.25)], + dtype=[('time', [('min', '>> dt = np.dtype(int) + >>> dt = dt.newbyteorder('>') + >>> np.frombuffer(buf, dtype=dt) # doctest: +SKIP + + The data of the resulting array will not be byteswapped, but will be + interpreted correctly. + + Examples + -------- + >>> s = b'hello world' + >>> np.frombuffer(s, dtype='S1', count=5, offset=6) + array([b'w', b'o', b'r', b'l', b'd'], dtype='|S1') + + >>> np.frombuffer(b'\\x01\\x02', dtype=np.uint8) + array([1, 2], dtype=uint8) + >>> np.frombuffer(b'\\x01\\x02\\x03\\x04\\x05', dtype=np.uint8, count=3) + array([1, 2, 3], dtype=uint8) + + """.replace( + "${ARRAY_FUNCTION_LIKE}", + array_function_like_doc, + )) + +add_newdoc('numpy.core', 'fastCopyAndTranspose', + """_fastCopyAndTranspose(a)""") + +add_newdoc('numpy.core.multiarray', 'correlate', + """cross_correlate(a,v, mode=0)""") + +add_newdoc('numpy.core.multiarray', 'arange', + """ + arange([start,] stop[, step,], dtype=None, *, like=None) + + Return evenly spaced values within a given interval. + + Values are generated within the half-open interval ``[start, stop)`` + (in other words, the interval including `start` but excluding `stop`). + For integer arguments the function is equivalent to the Python built-in + `range` function, but returns an ndarray rather than a list. + + When using a non-integer step, such as 0.1, the results will often not + be consistent. It is better to use `numpy.linspace` for these cases. + + Parameters + ---------- + start : integer or real, optional + Start of interval. The interval includes this value. The default + start value is 0. + stop : integer or real + End of interval. The interval does not include this value, except + in some cases where `step` is not an integer and floating point + round-off affects the length of `out`. + step : integer or real, optional + Spacing between values. For any output `out`, this is the distance + between two adjacent values, ``out[i+1] - out[i]``. The default + step size is 1. If `step` is specified as a position argument, + `start` must also be given. + dtype : dtype + The type of the output array. If `dtype` is not given, infer the data + type from the other input arguments. + ${ARRAY_FUNCTION_LIKE} + + .. versionadded:: 1.20.0 + + Returns + ------- + arange : ndarray + Array of evenly spaced values. + + For floating point arguments, the length of the result is + ``ceil((stop - start)/step)``. Because of floating point overflow, + this rule may result in the last element of `out` being greater + than `stop`. + + See Also + -------- + numpy.linspace : Evenly spaced numbers with careful handling of endpoints. + numpy.ogrid: Arrays of evenly spaced numbers in N-dimensions. + numpy.mgrid: Grid-shaped arrays of evenly spaced numbers in N-dimensions. + + Examples + -------- + >>> np.arange(3) + array([0, 1, 2]) + >>> np.arange(3.0) + array([ 0., 1., 2.]) + >>> np.arange(3,7) + array([3, 4, 5, 6]) + >>> np.arange(3,7,2) + array([3, 5]) + + """.replace( + "${ARRAY_FUNCTION_LIKE}", + array_function_like_doc, + )) + +add_newdoc('numpy.core.multiarray', '_get_ndarray_c_version', + """_get_ndarray_c_version() + + Return the compile time NPY_VERSION (formerly called NDARRAY_VERSION) number. + + """) + +add_newdoc('numpy.core.multiarray', '_reconstruct', + """_reconstruct(subtype, shape, dtype) + + Construct an empty array. Used by Pickles. + + """) + + +add_newdoc('numpy.core.multiarray', 'set_string_function', + """ + set_string_function(f, repr=1) + + Internal method to set a function to be used when pretty printing arrays. + + """) + +add_newdoc('numpy.core.multiarray', 'set_numeric_ops', + """ + set_numeric_ops(op1=func1, op2=func2, ...) + + Set numerical operators for array objects. + + .. deprecated:: 1.16 + + For the general case, use :c:func:`PyUFunc_ReplaceLoopBySignature`. + For ndarray subclasses, define the ``__array_ufunc__`` method and + override the relevant ufunc. + + Parameters + ---------- + op1, op2, ... : callable + Each ``op = func`` pair describes an operator to be replaced. + For example, ``add = lambda x, y: np.add(x, y) % 5`` would replace + addition by modulus 5 addition. + + Returns + ------- + saved_ops : list of callables + A list of all operators, stored before making replacements. + + Notes + ----- + .. WARNING:: + Use with care! Incorrect usage may lead to memory errors. + + A function replacing an operator cannot make use of that operator. + For example, when replacing add, you may not use ``+``. Instead, + directly call ufuncs. + + Examples + -------- + >>> def add_mod5(x, y): + ... return np.add(x, y) % 5 + ... + >>> old_funcs = np.set_numeric_ops(add=add_mod5) + + >>> x = np.arange(12).reshape((3, 4)) + >>> x + x + array([[0, 2, 4, 1], + [3, 0, 2, 4], + [1, 3, 0, 2]]) + + >>> ignore = np.set_numeric_ops(**old_funcs) # restore operators + + """) + +add_newdoc('numpy.core.multiarray', 'promote_types', + """ + promote_types(type1, type2) + + Returns the data type with the smallest size and smallest scalar + kind to which both ``type1`` and ``type2`` may be safely cast. + The returned data type is always in native byte order. + + This function is symmetric, but rarely associative. + + Parameters + ---------- + type1 : dtype or dtype specifier + First data type. + type2 : dtype or dtype specifier + Second data type. + + Returns + ------- + out : dtype + The promoted data type. + + Notes + ----- + .. versionadded:: 1.6.0 + + Starting in NumPy 1.9, promote_types function now returns a valid string + length when given an integer or float dtype as one argument and a string + dtype as another argument. Previously it always returned the input string + dtype, even if it wasn't long enough to store the max integer/float value + converted to a string. + + See Also + -------- + result_type, dtype, can_cast + + Examples + -------- + >>> np.promote_types('f4', 'f8') + dtype('float64') + + >>> np.promote_types('i8', 'f4') + dtype('float64') + + >>> np.promote_types('>i8', '>> np.promote_types('i4', 'S8') + dtype('S11') + + An example of a non-associative case: + + >>> p = np.promote_types + >>> p('S', p('i1', 'u1')) + dtype('S6') + >>> p(p('S', 'i1'), 'u1') + dtype('S4') + + """) + +add_newdoc('numpy.core.multiarray', 'c_einsum', + """ + c_einsum(subscripts, *operands, out=None, dtype=None, order='K', + casting='safe') + + *This documentation shadows that of the native python implementation of the `einsum` function, + except all references and examples related to the `optimize` argument (v 0.12.0) have been removed.* + + Evaluates the Einstein summation convention on the operands. + + Using the Einstein summation convention, many common multi-dimensional, + linear algebraic array operations can be represented in a simple fashion. + In *implicit* mode `einsum` computes these values. + + In *explicit* mode, `einsum` provides further flexibility to compute + other array operations that might not be considered classical Einstein + summation operations, by disabling, or forcing summation over specified + subscript labels. + + See the notes and examples for clarification. + + Parameters + ---------- + subscripts : str + Specifies the subscripts for summation as comma separated list of + subscript labels. An implicit (classical Einstein summation) + calculation is performed unless the explicit indicator '->' is + included as well as subscript labels of the precise output form. + operands : list of array_like + These are the arrays for the operation. + out : ndarray, optional + If provided, the calculation is done into this array. + dtype : {data-type, None}, optional + If provided, forces the calculation to use the data type specified. + Note that you may have to also give a more liberal `casting` + parameter to allow the conversions. Default is None. + order : {'C', 'F', 'A', 'K'}, optional + Controls the memory layout of the output. 'C' means it should + be C contiguous. 'F' means it should be Fortran contiguous, + 'A' means it should be 'F' if the inputs are all 'F', 'C' otherwise. + 'K' means it should be as close to the layout of the inputs as + is possible, including arbitrarily permuted axes. + Default is 'K'. + casting : {'no', 'equiv', 'safe', 'same_kind', 'unsafe'}, optional + Controls what kind of data casting may occur. Setting this to + 'unsafe' is not recommended, as it can adversely affect accumulations. + + * 'no' means the data types should not be cast at all. + * 'equiv' means only byte-order changes are allowed. + * 'safe' means only casts which can preserve values are allowed. + * 'same_kind' means only safe casts or casts within a kind, + like float64 to float32, are allowed. + * 'unsafe' means any data conversions may be done. + + Default is 'safe'. + optimize : {False, True, 'greedy', 'optimal'}, optional + Controls if intermediate optimization should occur. No optimization + will occur if False and True will default to the 'greedy' algorithm. + Also accepts an explicit contraction list from the ``np.einsum_path`` + function. See ``np.einsum_path`` for more details. Defaults to False. + + Returns + ------- + output : ndarray + The calculation based on the Einstein summation convention. + + See Also + -------- + einsum_path, dot, inner, outer, tensordot, linalg.multi_dot + + Notes + ----- + .. versionadded:: 1.6.0 + + The Einstein summation convention can be used to compute + many multi-dimensional, linear algebraic array operations. `einsum` + provides a succinct way of representing these. + + A non-exhaustive list of these operations, + which can be computed by `einsum`, is shown below along with examples: + + * Trace of an array, :py:func:`numpy.trace`. + * Return a diagonal, :py:func:`numpy.diag`. + * Array axis summations, :py:func:`numpy.sum`. + * Transpositions and permutations, :py:func:`numpy.transpose`. + * Matrix multiplication and dot product, :py:func:`numpy.matmul` :py:func:`numpy.dot`. + * Vector inner and outer products, :py:func:`numpy.inner` :py:func:`numpy.outer`. + * Broadcasting, element-wise and scalar multiplication, :py:func:`numpy.multiply`. + * Tensor contractions, :py:func:`numpy.tensordot`. + * Chained array operations, in efficient calculation order, :py:func:`numpy.einsum_path`. + + The subscripts string is a comma-separated list of subscript labels, + where each label refers to a dimension of the corresponding operand. + Whenever a label is repeated it is summed, so ``np.einsum('i,i', a, b)`` + is equivalent to :py:func:`np.inner(a,b) `. If a label + appears only once, it is not summed, so ``np.einsum('i', a)`` produces a + view of ``a`` with no changes. A further example ``np.einsum('ij,jk', a, b)`` + describes traditional matrix multiplication and is equivalent to + :py:func:`np.matmul(a,b) `. Repeated subscript labels in one + operand take the diagonal. For example, ``np.einsum('ii', a)`` is equivalent + to :py:func:`np.trace(a) `. + + In *implicit mode*, the chosen subscripts are important + since the axes of the output are reordered alphabetically. This + means that ``np.einsum('ij', a)`` doesn't affect a 2D array, while + ``np.einsum('ji', a)`` takes its transpose. Additionally, + ``np.einsum('ij,jk', a, b)`` returns a matrix multiplication, while, + ``np.einsum('ij,jh', a, b)`` returns the transpose of the + multiplication since subscript 'h' precedes subscript 'i'. + + In *explicit mode* the output can be directly controlled by + specifying output subscript labels. This requires the + identifier '->' as well as the list of output subscript labels. + This feature increases the flexibility of the function since + summing can be disabled or forced when required. The call + ``np.einsum('i->', a)`` is like :py:func:`np.sum(a, axis=-1) `, + and ``np.einsum('ii->i', a)`` is like :py:func:`np.diag(a) `. + The difference is that `einsum` does not allow broadcasting by default. + Additionally ``np.einsum('ij,jh->ih', a, b)`` directly specifies the + order of the output subscript labels and therefore returns matrix + multiplication, unlike the example above in implicit mode. + + To enable and control broadcasting, use an ellipsis. Default + NumPy-style broadcasting is done by adding an ellipsis + to the left of each term, like ``np.einsum('...ii->...i', a)``. + To take the trace along the first and last axes, + you can do ``np.einsum('i...i', a)``, or to do a matrix-matrix + product with the left-most indices instead of rightmost, one can do + ``np.einsum('ij...,jk...->ik...', a, b)``. + + When there is only one operand, no axes are summed, and no output + parameter is provided, a view into the operand is returned instead + of a new array. Thus, taking the diagonal as ``np.einsum('ii->i', a)`` + produces a view (changed in version 1.10.0). + + `einsum` also provides an alternative way to provide the subscripts + and operands as ``einsum(op0, sublist0, op1, sublist1, ..., [sublistout])``. + If the output shape is not provided in this format `einsum` will be + calculated in implicit mode, otherwise it will be performed explicitly. + The examples below have corresponding `einsum` calls with the two + parameter methods. + + .. versionadded:: 1.10.0 + + Views returned from einsum are now writeable whenever the input array + is writeable. For example, ``np.einsum('ijk...->kji...', a)`` will now + have the same effect as :py:func:`np.swapaxes(a, 0, 2) ` + and ``np.einsum('ii->i', a)`` will return a writeable view of the diagonal + of a 2D array. + + Examples + -------- + >>> a = np.arange(25).reshape(5,5) + >>> b = np.arange(5) + >>> c = np.arange(6).reshape(2,3) + + Trace of a matrix: + + >>> np.einsum('ii', a) + 60 + >>> np.einsum(a, [0,0]) + 60 + >>> np.trace(a) + 60 + + Extract the diagonal (requires explicit form): + + >>> np.einsum('ii->i', a) + array([ 0, 6, 12, 18, 24]) + >>> np.einsum(a, [0,0], [0]) + array([ 0, 6, 12, 18, 24]) + >>> np.diag(a) + array([ 0, 6, 12, 18, 24]) + + Sum over an axis (requires explicit form): + + >>> np.einsum('ij->i', a) + array([ 10, 35, 60, 85, 110]) + >>> np.einsum(a, [0,1], [0]) + array([ 10, 35, 60, 85, 110]) + >>> np.sum(a, axis=1) + array([ 10, 35, 60, 85, 110]) + + For higher dimensional arrays summing a single axis can be done with ellipsis: + + >>> np.einsum('...j->...', a) + array([ 10, 35, 60, 85, 110]) + >>> np.einsum(a, [Ellipsis,1], [Ellipsis]) + array([ 10, 35, 60, 85, 110]) + + Compute a matrix transpose, or reorder any number of axes: + + >>> np.einsum('ji', c) + array([[0, 3], + [1, 4], + [2, 5]]) + >>> np.einsum('ij->ji', c) + array([[0, 3], + [1, 4], + [2, 5]]) + >>> np.einsum(c, [1,0]) + array([[0, 3], + [1, 4], + [2, 5]]) + >>> np.transpose(c) + array([[0, 3], + [1, 4], + [2, 5]]) + + Vector inner products: + + >>> np.einsum('i,i', b, b) + 30 + >>> np.einsum(b, [0], b, [0]) + 30 + >>> np.inner(b,b) + 30 + + Matrix vector multiplication: + + >>> np.einsum('ij,j', a, b) + array([ 30, 80, 130, 180, 230]) + >>> np.einsum(a, [0,1], b, [1]) + array([ 30, 80, 130, 180, 230]) + >>> np.dot(a, b) + array([ 30, 80, 130, 180, 230]) + >>> np.einsum('...j,j', a, b) + array([ 30, 80, 130, 180, 230]) + + Broadcasting and scalar multiplication: + + >>> np.einsum('..., ...', 3, c) + array([[ 0, 3, 6], + [ 9, 12, 15]]) + >>> np.einsum(',ij', 3, c) + array([[ 0, 3, 6], + [ 9, 12, 15]]) + >>> np.einsum(3, [Ellipsis], c, [Ellipsis]) + array([[ 0, 3, 6], + [ 9, 12, 15]]) + >>> np.multiply(3, c) + array([[ 0, 3, 6], + [ 9, 12, 15]]) + + Vector outer product: + + >>> np.einsum('i,j', np.arange(2)+1, b) + array([[0, 1, 2, 3, 4], + [0, 2, 4, 6, 8]]) + >>> np.einsum(np.arange(2)+1, [0], b, [1]) + array([[0, 1, 2, 3, 4], + [0, 2, 4, 6, 8]]) + >>> np.outer(np.arange(2)+1, b) + array([[0, 1, 2, 3, 4], + [0, 2, 4, 6, 8]]) + + Tensor contraction: + + >>> a = np.arange(60.).reshape(3,4,5) + >>> b = np.arange(24.).reshape(4,3,2) + >>> np.einsum('ijk,jil->kl', a, b) + array([[ 4400., 4730.], + [ 4532., 4874.], + [ 4664., 5018.], + [ 4796., 5162.], + [ 4928., 5306.]]) + >>> np.einsum(a, [0,1,2], b, [1,0,3], [2,3]) + array([[ 4400., 4730.], + [ 4532., 4874.], + [ 4664., 5018.], + [ 4796., 5162.], + [ 4928., 5306.]]) + >>> np.tensordot(a,b, axes=([1,0],[0,1])) + array([[ 4400., 4730.], + [ 4532., 4874.], + [ 4664., 5018.], + [ 4796., 5162.], + [ 4928., 5306.]]) + + Writeable returned arrays (since version 1.10.0): + + >>> a = np.zeros((3, 3)) + >>> np.einsum('ii->i', a)[:] = 1 + >>> a + array([[ 1., 0., 0.], + [ 0., 1., 0.], + [ 0., 0., 1.]]) + + Example of ellipsis use: + + >>> a = np.arange(6).reshape((3,2)) + >>> b = np.arange(12).reshape((4,3)) + >>> np.einsum('ki,jk->ij', a, b) + array([[10, 28, 46, 64], + [13, 40, 67, 94]]) + >>> np.einsum('ki,...k->i...', a, b) + array([[10, 28, 46, 64], + [13, 40, 67, 94]]) + >>> np.einsum('k...,jk', a, b) + array([[10, 28, 46, 64], + [13, 40, 67, 94]]) + + """) + + +############################################################################## +# +# Documentation for ndarray attributes and methods +# +############################################################################## + + +############################################################################## +# +# ndarray object +# +############################################################################## + + +add_newdoc('numpy.core.multiarray', 'ndarray', + """ + ndarray(shape, dtype=float, buffer=None, offset=0, + strides=None, order=None) + + An array object represents a multidimensional, homogeneous array + of fixed-size items. An associated data-type object describes the + format of each element in the array (its byte-order, how many bytes it + occupies in memory, whether it is an integer, a floating point number, + or something else, etc.) + + Arrays should be constructed using `array`, `zeros` or `empty` (refer + to the See Also section below). The parameters given here refer to + a low-level method (`ndarray(...)`) for instantiating an array. + + For more information, refer to the `numpy` module and examine the + methods and attributes of an array. + + Parameters + ---------- + (for the __new__ method; see Notes below) + + shape : tuple of ints + Shape of created array. + dtype : data-type, optional + Any object that can be interpreted as a numpy data type. + buffer : object exposing buffer interface, optional + Used to fill the array with data. + offset : int, optional + Offset of array data in buffer. + strides : tuple of ints, optional + Strides of data in memory. + order : {'C', 'F'}, optional + Row-major (C-style) or column-major (Fortran-style) order. + + Attributes + ---------- + T : ndarray + Transpose of the array. + data : buffer + The array's elements, in memory. + dtype : dtype object + Describes the format of the elements in the array. + flags : dict + Dictionary containing information related to memory use, e.g., + 'C_CONTIGUOUS', 'OWNDATA', 'WRITEABLE', etc. + flat : numpy.flatiter object + Flattened version of the array as an iterator. The iterator + allows assignments, e.g., ``x.flat = 3`` (See `ndarray.flat` for + assignment examples; TODO). + imag : ndarray + Imaginary part of the array. + real : ndarray + Real part of the array. + size : int + Number of elements in the array. + itemsize : int + The memory use of each array element in bytes. + nbytes : int + The total number of bytes required to store the array data, + i.e., ``itemsize * size``. + ndim : int + The array's number of dimensions. + shape : tuple of ints + Shape of the array. + strides : tuple of ints + The step-size required to move from one element to the next in + memory. For example, a contiguous ``(3, 4)`` array of type + ``int16`` in C-order has strides ``(8, 2)``. This implies that + to move from element to element in memory requires jumps of 2 bytes. + To move from row-to-row, one needs to jump 8 bytes at a time + (``2 * 4``). + ctypes : ctypes object + Class containing properties of the array needed for interaction + with ctypes. + base : ndarray + If the array is a view into another array, that array is its `base` + (unless that array is also a view). The `base` array is where the + array data is actually stored. + + See Also + -------- + array : Construct an array. + zeros : Create an array, each element of which is zero. + empty : Create an array, but leave its allocated memory unchanged (i.e., + it contains "garbage"). + dtype : Create a data-type. + + Notes + ----- + There are two modes of creating an array using ``__new__``: + + 1. If `buffer` is None, then only `shape`, `dtype`, and `order` + are used. + 2. If `buffer` is an object exposing the buffer interface, then + all keywords are interpreted. + + No ``__init__`` method is needed because the array is fully initialized + after the ``__new__`` method. + + Examples + -------- + These examples illustrate the low-level `ndarray` constructor. Refer + to the `See Also` section above for easier ways of constructing an + ndarray. + + First mode, `buffer` is None: + + >>> np.ndarray(shape=(2,2), dtype=float, order='F') + array([[0.0e+000, 0.0e+000], # random + [ nan, 2.5e-323]]) + + Second mode: + + >>> np.ndarray((2,), buffer=np.array([1,2,3]), + ... offset=np.int_().itemsize, + ... dtype=int) # offset = 1*itemsize, i.e. skip first element + array([2, 3]) + + """) + + +############################################################################## +# +# ndarray attributes +# +############################################################################## + + +add_newdoc('numpy.core.multiarray', 'ndarray', ('__array_interface__', + """Array protocol: Python side.""")) + + +add_newdoc('numpy.core.multiarray', 'ndarray', ('__array_finalize__', + """None.""")) + + +add_newdoc('numpy.core.multiarray', 'ndarray', ('__array_priority__', + """Array priority.""")) + + +add_newdoc('numpy.core.multiarray', 'ndarray', ('__array_struct__', + """Array protocol: C-struct side.""")) + + +add_newdoc('numpy.core.multiarray', 'ndarray', ('base', + """ + Base object if memory is from some other object. + + Examples + -------- + The base of an array that owns its memory is None: + + >>> x = np.array([1,2,3,4]) + >>> x.base is None + True + + Slicing creates a view, whose memory is shared with x: + + >>> y = x[2:] + >>> y.base is x + True + + """)) + + +add_newdoc('numpy.core.multiarray', 'ndarray', ('ctypes', + """ + An object to simplify the interaction of the array with the ctypes + module. + + This attribute creates an object that makes it easier to use arrays + when calling shared libraries with the ctypes module. The returned + object has, among others, data, shape, and strides attributes (see + Notes below) which themselves return ctypes objects that can be used + as arguments to a shared library. + + Parameters + ---------- + None + + Returns + ------- + c : Python object + Possessing attributes data, shape, strides, etc. + + See Also + -------- + numpy.ctypeslib + + Notes + ----- + Below are the public attributes of this object which were documented + in "Guide to NumPy" (we have omitted undocumented public attributes, + as well as documented private attributes): + + .. autoattribute:: numpy.core._internal._ctypes.data + :noindex: + + .. autoattribute:: numpy.core._internal._ctypes.shape + :noindex: + + .. autoattribute:: numpy.core._internal._ctypes.strides + :noindex: + + .. automethod:: numpy.core._internal._ctypes.data_as + :noindex: + + .. automethod:: numpy.core._internal._ctypes.shape_as + :noindex: + + .. automethod:: numpy.core._internal._ctypes.strides_as + :noindex: + + If the ctypes module is not available, then the ctypes attribute + of array objects still returns something useful, but ctypes objects + are not returned and errors may be raised instead. In particular, + the object will still have the ``as_parameter`` attribute which will + return an integer equal to the data attribute. + + Examples + -------- + >>> import ctypes + >>> x = np.array([[0, 1], [2, 3]], dtype=np.int32) + >>> x + array([[0, 1], + [2, 3]], dtype=int32) + >>> x.ctypes.data + 31962608 # may vary + >>> x.ctypes.data_as(ctypes.POINTER(ctypes.c_uint32)) + <__main__.LP_c_uint object at 0x7ff2fc1fc200> # may vary + >>> x.ctypes.data_as(ctypes.POINTER(ctypes.c_uint32)).contents + c_uint(0) + >>> x.ctypes.data_as(ctypes.POINTER(ctypes.c_uint64)).contents + c_ulong(4294967296) + >>> x.ctypes.shape + # may vary + >>> x.ctypes.strides + # may vary + + """)) + + +add_newdoc('numpy.core.multiarray', 'ndarray', ('data', + """Python buffer object pointing to the start of the array's data.""")) + + +add_newdoc('numpy.core.multiarray', 'ndarray', ('dtype', + """ + Data-type of the array's elements. + + Parameters + ---------- + None + + Returns + ------- + d : numpy dtype object + + See Also + -------- + numpy.dtype + + Examples + -------- + >>> x + array([[0, 1], + [2, 3]]) + >>> x.dtype + dtype('int32') + >>> type(x.dtype) + + + """)) + + +add_newdoc('numpy.core.multiarray', 'ndarray', ('imag', + """ + The imaginary part of the array. + + Examples + -------- + >>> x = np.sqrt([1+0j, 0+1j]) + >>> x.imag + array([ 0. , 0.70710678]) + >>> x.imag.dtype + dtype('float64') + + """)) + + +add_newdoc('numpy.core.multiarray', 'ndarray', ('itemsize', + """ + Length of one array element in bytes. + + Examples + -------- + >>> x = np.array([1,2,3], dtype=np.float64) + >>> x.itemsize + 8 + >>> x = np.array([1,2,3], dtype=np.complex128) + >>> x.itemsize + 16 + + """)) + + +add_newdoc('numpy.core.multiarray', 'ndarray', ('flags', + """ + Information about the memory layout of the array. + + Attributes + ---------- + C_CONTIGUOUS (C) + The data is in a single, C-style contiguous segment. + F_CONTIGUOUS (F) + The data is in a single, Fortran-style contiguous segment. + OWNDATA (O) + The array owns the memory it uses or borrows it from another object. + WRITEABLE (W) + The data area can be written to. Setting this to False locks + the data, making it read-only. A view (slice, etc.) inherits WRITEABLE + from its base array at creation time, but a view of a writeable + array may be subsequently locked while the base array remains writeable. + (The opposite is not true, in that a view of a locked array may not + be made writeable. However, currently, locking a base object does not + lock any views that already reference it, so under that circumstance it + is possible to alter the contents of a locked array via a previously + created writeable view onto it.) Attempting to change a non-writeable + array raises a RuntimeError exception. + ALIGNED (A) + The data and all elements are aligned appropriately for the hardware. + WRITEBACKIFCOPY (X) + This array is a copy of some other array. The C-API function + PyArray_ResolveWritebackIfCopy must be called before deallocating + to the base array will be updated with the contents of this array. + UPDATEIFCOPY (U) + (Deprecated, use WRITEBACKIFCOPY) This array is a copy of some other array. + When this array is + deallocated, the base array will be updated with the contents of + this array. + FNC + F_CONTIGUOUS and not C_CONTIGUOUS. + FORC + F_CONTIGUOUS or C_CONTIGUOUS (one-segment test). + BEHAVED (B) + ALIGNED and WRITEABLE. + CARRAY (CA) + BEHAVED and C_CONTIGUOUS. + FARRAY (FA) + BEHAVED and F_CONTIGUOUS and not C_CONTIGUOUS. + + Notes + ----- + The `flags` object can be accessed dictionary-like (as in ``a.flags['WRITEABLE']``), + or by using lowercased attribute names (as in ``a.flags.writeable``). Short flag + names are only supported in dictionary access. + + Only the WRITEBACKIFCOPY, UPDATEIFCOPY, WRITEABLE, and ALIGNED flags can be + changed by the user, via direct assignment to the attribute or dictionary + entry, or by calling `ndarray.setflags`. + + The array flags cannot be set arbitrarily: + + - UPDATEIFCOPY can only be set ``False``. + - WRITEBACKIFCOPY can only be set ``False``. + - ALIGNED can only be set ``True`` if the data is truly aligned. + - WRITEABLE can only be set ``True`` if the array owns its own memory + or the ultimate owner of the memory exposes a writeable buffer + interface or is a string. + + Arrays can be both C-style and Fortran-style contiguous simultaneously. + This is clear for 1-dimensional arrays, but can also be true for higher + dimensional arrays. + + Even for contiguous arrays a stride for a given dimension + ``arr.strides[dim]`` may be *arbitrary* if ``arr.shape[dim] == 1`` + or the array has no elements. + It does *not* generally hold that ``self.strides[-1] == self.itemsize`` + for C-style contiguous arrays or ``self.strides[0] == self.itemsize`` for + Fortran-style contiguous arrays is true. + """)) + + +add_newdoc('numpy.core.multiarray', 'ndarray', ('flat', + """ + A 1-D iterator over the array. + + This is a `numpy.flatiter` instance, which acts similarly to, but is not + a subclass of, Python's built-in iterator object. + + See Also + -------- + flatten : Return a copy of the array collapsed into one dimension. + + flatiter + + Examples + -------- + >>> x = np.arange(1, 7).reshape(2, 3) + >>> x + array([[1, 2, 3], + [4, 5, 6]]) + >>> x.flat[3] + 4 + >>> x.T + array([[1, 4], + [2, 5], + [3, 6]]) + >>> x.T.flat[3] + 5 + >>> type(x.flat) + + + An assignment example: + + >>> x.flat = 3; x + array([[3, 3, 3], + [3, 3, 3]]) + >>> x.flat[[1,4]] = 1; x + array([[3, 1, 3], + [3, 1, 3]]) + + """)) + + +add_newdoc('numpy.core.multiarray', 'ndarray', ('nbytes', + """ + Total bytes consumed by the elements of the array. + + Notes + ----- + Does not include memory consumed by non-element attributes of the + array object. + + Examples + -------- + >>> x = np.zeros((3,5,2), dtype=np.complex128) + >>> x.nbytes + 480 + >>> np.prod(x.shape) * x.itemsize + 480 + + """)) + + +add_newdoc('numpy.core.multiarray', 'ndarray', ('ndim', + """ + Number of array dimensions. + + Examples + -------- + >>> x = np.array([1, 2, 3]) + >>> x.ndim + 1 + >>> y = np.zeros((2, 3, 4)) + >>> y.ndim + 3 + + """)) + + +add_newdoc('numpy.core.multiarray', 'ndarray', ('real', + """ + The real part of the array. + + Examples + -------- + >>> x = np.sqrt([1+0j, 0+1j]) + >>> x.real + array([ 1. , 0.70710678]) + >>> x.real.dtype + dtype('float64') + + See Also + -------- + numpy.real : equivalent function + + """)) + + +add_newdoc('numpy.core.multiarray', 'ndarray', ('shape', + """ + Tuple of array dimensions. + + The shape property is usually used to get the current shape of an array, + but may also be used to reshape the array in-place by assigning a tuple of + array dimensions to it. As with `numpy.reshape`, one of the new shape + dimensions can be -1, in which case its value is inferred from the size of + the array and the remaining dimensions. Reshaping an array in-place will + fail if a copy is required. + + Examples + -------- + >>> x = np.array([1, 2, 3, 4]) + >>> x.shape + (4,) + >>> y = np.zeros((2, 3, 4)) + >>> y.shape + (2, 3, 4) + >>> y.shape = (3, 8) + >>> y + array([[ 0., 0., 0., 0., 0., 0., 0., 0.], + [ 0., 0., 0., 0., 0., 0., 0., 0.], + [ 0., 0., 0., 0., 0., 0., 0., 0.]]) + >>> y.shape = (3, 6) + Traceback (most recent call last): + File "", line 1, in + ValueError: total size of new array must be unchanged + >>> np.zeros((4,2))[::2].shape = (-1,) + Traceback (most recent call last): + File "", line 1, in + AttributeError: Incompatible shape for in-place modification. Use + `.reshape()` to make a copy with the desired shape. + + See Also + -------- + numpy.reshape : similar function + ndarray.reshape : similar method + + """)) + + +add_newdoc('numpy.core.multiarray', 'ndarray', ('size', + """ + Number of elements in the array. + + Equal to ``np.prod(a.shape)``, i.e., the product of the array's + dimensions. + + Notes + ----- + `a.size` returns a standard arbitrary precision Python integer. This + may not be the case with other methods of obtaining the same value + (like the suggested ``np.prod(a.shape)``, which returns an instance + of ``np.int_``), and may be relevant if the value is used further in + calculations that may overflow a fixed size integer type. + + Examples + -------- + >>> x = np.zeros((3, 5, 2), dtype=np.complex128) + >>> x.size + 30 + >>> np.prod(x.shape) + 30 + + """)) + + +add_newdoc('numpy.core.multiarray', 'ndarray', ('strides', + """ + Tuple of bytes to step in each dimension when traversing an array. + + The byte offset of element ``(i[0], i[1], ..., i[n])`` in an array `a` + is:: + + offset = sum(np.array(i) * a.strides) + + A more detailed explanation of strides can be found in the + "ndarray.rst" file in the NumPy reference guide. + + Notes + ----- + Imagine an array of 32-bit integers (each 4 bytes):: + + x = np.array([[0, 1, 2, 3, 4], + [5, 6, 7, 8, 9]], dtype=np.int32) + + This array is stored in memory as 40 bytes, one after the other + (known as a contiguous block of memory). The strides of an array tell + us how many bytes we have to skip in memory to move to the next position + along a certain axis. For example, we have to skip 4 bytes (1 value) to + move to the next column, but 20 bytes (5 values) to get to the same + position in the next row. As such, the strides for the array `x` will be + ``(20, 4)``. + + See Also + -------- + numpy.lib.stride_tricks.as_strided + + Examples + -------- + >>> y = np.reshape(np.arange(2*3*4), (2,3,4)) + >>> y + array([[[ 0, 1, 2, 3], + [ 4, 5, 6, 7], + [ 8, 9, 10, 11]], + [[12, 13, 14, 15], + [16, 17, 18, 19], + [20, 21, 22, 23]]]) + >>> y.strides + (48, 16, 4) + >>> y[1,1,1] + 17 + >>> offset=sum(y.strides * np.array((1,1,1))) + >>> offset/y.itemsize + 17 + + >>> x = np.reshape(np.arange(5*6*7*8), (5,6,7,8)).transpose(2,3,1,0) + >>> x.strides + (32, 4, 224, 1344) + >>> i = np.array([3,5,2,2]) + >>> offset = sum(i * x.strides) + >>> x[3,5,2,2] + 813 + >>> offset / x.itemsize + 813 + + """)) + + +add_newdoc('numpy.core.multiarray', 'ndarray', ('T', + """ + The transposed array. + + Same as ``self.transpose()``. + + Examples + -------- + >>> x = np.array([[1.,2.],[3.,4.]]) + >>> x + array([[ 1., 2.], + [ 3., 4.]]) + >>> x.T + array([[ 1., 3.], + [ 2., 4.]]) + >>> x = np.array([1.,2.,3.,4.]) + >>> x + array([ 1., 2., 3., 4.]) + >>> x.T + array([ 1., 2., 3., 4.]) + + See Also + -------- + transpose + + """)) + + +############################################################################## +# +# ndarray methods +# +############################################################################## + + +add_newdoc('numpy.core.multiarray', 'ndarray', ('__array__', + """ a.__array__([dtype], /) -> reference if type unchanged, copy otherwise. + + Returns either a new reference to self if dtype is not given or a new array + of provided data type if dtype is different from the current dtype of the + array. + + """)) + + +add_newdoc('numpy.core.multiarray', 'ndarray', ('__array_prepare__', + """a.__array_prepare__(obj) -> Object of same type as ndarray object obj. + + """)) + + +add_newdoc('numpy.core.multiarray', 'ndarray', ('__array_wrap__', + """a.__array_wrap__(obj) -> Object of same type as ndarray object a. + + """)) + + +add_newdoc('numpy.core.multiarray', 'ndarray', ('__copy__', + """a.__copy__() + + Used if :func:`copy.copy` is called on an array. Returns a copy of the array. + + Equivalent to ``a.copy(order='K')``. + + """)) + + +add_newdoc('numpy.core.multiarray', 'ndarray', ('__deepcopy__', + """a.__deepcopy__(memo, /) -> Deep copy of array. + + Used if :func:`copy.deepcopy` is called on an array. + + """)) + + +add_newdoc('numpy.core.multiarray', 'ndarray', ('__reduce__', + """a.__reduce__() + + For pickling. + + """)) + + +add_newdoc('numpy.core.multiarray', 'ndarray', ('__setstate__', + """a.__setstate__(state, /) + + For unpickling. + + The `state` argument must be a sequence that contains the following + elements: + + Parameters + ---------- + version : int + optional pickle version. If omitted defaults to 0. + shape : tuple + dtype : data-type + isFortran : bool + rawdata : string or list + a binary string with the data (or a list if 'a' is an object array) + + """)) + + +add_newdoc('numpy.core.multiarray', 'ndarray', ('all', + """ + a.all(axis=None, out=None, keepdims=False, *, where=True) + + Returns True if all elements evaluate to True. + + Refer to `numpy.all` for full documentation. + + See Also + -------- + numpy.all : equivalent function + + """)) + + +add_newdoc('numpy.core.multiarray', 'ndarray', ('any', + """ + a.any(axis=None, out=None, keepdims=False, *, where=True) + + Returns True if any of the elements of `a` evaluate to True. + + Refer to `numpy.any` for full documentation. + + See Also + -------- + numpy.any : equivalent function + + """)) + + +add_newdoc('numpy.core.multiarray', 'ndarray', ('argmax', + """ + a.argmax(axis=None, out=None) + + Return indices of the maximum values along the given axis. + + Refer to `numpy.argmax` for full documentation. + + See Also + -------- + numpy.argmax : equivalent function + + """)) + + +add_newdoc('numpy.core.multiarray', 'ndarray', ('argmin', + """ + a.argmin(axis=None, out=None) + + Return indices of the minimum values along the given axis. + + Refer to `numpy.argmin` for detailed documentation. + + See Also + -------- + numpy.argmin : equivalent function + + """)) + + +add_newdoc('numpy.core.multiarray', 'ndarray', ('argsort', + """ + a.argsort(axis=-1, kind=None, order=None) + + Returns the indices that would sort this array. + + Refer to `numpy.argsort` for full documentation. + + See Also + -------- + numpy.argsort : equivalent function + + """)) + + +add_newdoc('numpy.core.multiarray', 'ndarray', ('argpartition', + """ + a.argpartition(kth, axis=-1, kind='introselect', order=None) + + Returns the indices that would partition this array. + + Refer to `numpy.argpartition` for full documentation. + + .. versionadded:: 1.8.0 + + See Also + -------- + numpy.argpartition : equivalent function + + """)) + + +add_newdoc('numpy.core.multiarray', 'ndarray', ('astype', + """ + a.astype(dtype, order='K', casting='unsafe', subok=True, copy=True) + + Copy of the array, cast to a specified type. + + Parameters + ---------- + dtype : str or dtype + Typecode or data-type to which the array is cast. + order : {'C', 'F', 'A', 'K'}, optional + Controls the memory layout order of the result. + 'C' means C order, 'F' means Fortran order, 'A' + means 'F' order if all the arrays are Fortran contiguous, + 'C' order otherwise, and 'K' means as close to the + order the array elements appear in memory as possible. + Default is 'K'. + casting : {'no', 'equiv', 'safe', 'same_kind', 'unsafe'}, optional + Controls what kind of data casting may occur. Defaults to 'unsafe' + for backwards compatibility. + + * 'no' means the data types should not be cast at all. + * 'equiv' means only byte-order changes are allowed. + * 'safe' means only casts which can preserve values are allowed. + * 'same_kind' means only safe casts or casts within a kind, + like float64 to float32, are allowed. + * 'unsafe' means any data conversions may be done. + subok : bool, optional + If True, then sub-classes will be passed-through (default), otherwise + the returned array will be forced to be a base-class array. + copy : bool, optional + By default, astype always returns a newly allocated array. If this + is set to false, and the `dtype`, `order`, and `subok` + requirements are satisfied, the input array is returned instead + of a copy. + + Returns + ------- + arr_t : ndarray + Unless `copy` is False and the other conditions for returning the input + array are satisfied (see description for `copy` input parameter), `arr_t` + is a new array of the same shape as the input array, with dtype, order + given by `dtype`, `order`. + + Notes + ----- + .. versionchanged:: 1.17.0 + Casting between a simple data type and a structured one is possible only + for "unsafe" casting. Casting to multiple fields is allowed, but + casting from multiple fields is not. + + .. versionchanged:: 1.9.0 + Casting from numeric to string types in 'safe' casting mode requires + that the string dtype length is long enough to store the max + integer/float value converted. + + Raises + ------ + ComplexWarning + When casting from complex to float or int. To avoid this, + one should use ``a.real.astype(t)``. + + Examples + -------- + >>> x = np.array([1, 2, 2.5]) + >>> x + array([1. , 2. , 2.5]) + + >>> x.astype(int) + array([1, 2, 2]) + + """)) + + +add_newdoc('numpy.core.multiarray', 'ndarray', ('byteswap', + """ + a.byteswap(inplace=False) + + Swap the bytes of the array elements + + Toggle between low-endian and big-endian data representation by + returning a byteswapped array, optionally swapped in-place. + Arrays of byte-strings are not swapped. The real and imaginary + parts of a complex number are swapped individually. + + Parameters + ---------- + inplace : bool, optional + If ``True``, swap bytes in-place, default is ``False``. + + Returns + ------- + out : ndarray + The byteswapped array. If `inplace` is ``True``, this is + a view to self. + + Examples + -------- + >>> A = np.array([1, 256, 8755], dtype=np.int16) + >>> list(map(hex, A)) + ['0x1', '0x100', '0x2233'] + >>> A.byteswap(inplace=True) + array([ 256, 1, 13090], dtype=int16) + >>> list(map(hex, A)) + ['0x100', '0x1', '0x3322'] + + Arrays of byte-strings are not swapped + + >>> A = np.array([b'ceg', b'fac']) + >>> A.byteswap() + array([b'ceg', b'fac'], dtype='|S3') + + ``A.newbyteorder().byteswap()`` produces an array with the same values + but different representation in memory + + >>> A = np.array([1, 2, 3]) + >>> A.view(np.uint8) + array([1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, + 0, 0], dtype=uint8) + >>> A.newbyteorder().byteswap(inplace=True) + array([1, 2, 3]) + >>> A.view(np.uint8) + array([0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, + 0, 3], dtype=uint8) + + """)) + + +add_newdoc('numpy.core.multiarray', 'ndarray', ('choose', + """ + a.choose(choices, out=None, mode='raise') + + Use an index array to construct a new array from a set of choices. + + Refer to `numpy.choose` for full documentation. + + See Also + -------- + numpy.choose : equivalent function + + """)) + + +add_newdoc('numpy.core.multiarray', 'ndarray', ('clip', + """ + a.clip(min=None, max=None, out=None, **kwargs) + + Return an array whose values are limited to ``[min, max]``. + One of max or min must be given. + + Refer to `numpy.clip` for full documentation. + + See Also + -------- + numpy.clip : equivalent function + + """)) + + +add_newdoc('numpy.core.multiarray', 'ndarray', ('compress', + """ + a.compress(condition, axis=None, out=None) + + Return selected slices of this array along given axis. + + Refer to `numpy.compress` for full documentation. + + See Also + -------- + numpy.compress : equivalent function + + """)) + + +add_newdoc('numpy.core.multiarray', 'ndarray', ('conj', + """ + a.conj() + + Complex-conjugate all elements. + + Refer to `numpy.conjugate` for full documentation. + + See Also + -------- + numpy.conjugate : equivalent function + + """)) + + +add_newdoc('numpy.core.multiarray', 'ndarray', ('conjugate', + """ + a.conjugate() + + Return the complex conjugate, element-wise. + + Refer to `numpy.conjugate` for full documentation. + + See Also + -------- + numpy.conjugate : equivalent function + + """)) + + +add_newdoc('numpy.core.multiarray', 'ndarray', ('copy', + """ + a.copy(order='C') + + Return a copy of the array. + + Parameters + ---------- + order : {'C', 'F', 'A', 'K'}, optional + Controls the memory layout of the copy. 'C' means C-order, + 'F' means F-order, 'A' means 'F' if `a` is Fortran contiguous, + 'C' otherwise. 'K' means match the layout of `a` as closely + as possible. (Note that this function and :func:`numpy.copy` are very + similar, but have different default values for their order= + arguments.) + + See also + -------- + numpy.copy + numpy.copyto + + Examples + -------- + >>> x = np.array([[1,2,3],[4,5,6]], order='F') + + >>> y = x.copy() + + >>> x.fill(0) + + >>> x + array([[0, 0, 0], + [0, 0, 0]]) + + >>> y + array([[1, 2, 3], + [4, 5, 6]]) + + >>> y.flags['C_CONTIGUOUS'] + True + + """)) + + +add_newdoc('numpy.core.multiarray', 'ndarray', ('cumprod', + """ + a.cumprod(axis=None, dtype=None, out=None) + + Return the cumulative product of the elements along the given axis. + + Refer to `numpy.cumprod` for full documentation. + + See Also + -------- + numpy.cumprod : equivalent function + + """)) + + +add_newdoc('numpy.core.multiarray', 'ndarray', ('cumsum', + """ + a.cumsum(axis=None, dtype=None, out=None) + + Return the cumulative sum of the elements along the given axis. + + Refer to `numpy.cumsum` for full documentation. + + See Also + -------- + numpy.cumsum : equivalent function + + """)) + + +add_newdoc('numpy.core.multiarray', 'ndarray', ('diagonal', + """ + a.diagonal(offset=0, axis1=0, axis2=1) + + Return specified diagonals. In NumPy 1.9 the returned array is a + read-only view instead of a copy as in previous NumPy versions. In + a future version the read-only restriction will be removed. + + Refer to :func:`numpy.diagonal` for full documentation. + + See Also + -------- + numpy.diagonal : equivalent function + + """)) + + +add_newdoc('numpy.core.multiarray', 'ndarray', ('dot', + """ + a.dot(b, out=None) + + Dot product of two arrays. + + Refer to `numpy.dot` for full documentation. + + See Also + -------- + numpy.dot : equivalent function + + Examples + -------- + >>> a = np.eye(2) + >>> b = np.ones((2, 2)) * 2 + >>> a.dot(b) + array([[2., 2.], + [2., 2.]]) + + This array method can be conveniently chained: + + >>> a.dot(b).dot(b) + array([[8., 8.], + [8., 8.]]) + + """)) + + +add_newdoc('numpy.core.multiarray', 'ndarray', ('dump', + """a.dump(file) + + Dump a pickle of the array to the specified file. + The array can be read back with pickle.load or numpy.load. + + Parameters + ---------- + file : str or Path + A string naming the dump file. + + .. versionchanged:: 1.17.0 + `pathlib.Path` objects are now accepted. + + """)) + + +add_newdoc('numpy.core.multiarray', 'ndarray', ('dumps', + """ + a.dumps() + + Returns the pickle of the array as a string. + pickle.loads or numpy.loads will convert the string back to an array. + + Parameters + ---------- + None + + """)) + + +add_newdoc('numpy.core.multiarray', 'ndarray', ('fill', + """ + a.fill(value) + + Fill the array with a scalar value. + + Parameters + ---------- + value : scalar + All elements of `a` will be assigned this value. + + Examples + -------- + >>> a = np.array([1, 2]) + >>> a.fill(0) + >>> a + array([0, 0]) + >>> a = np.empty(2) + >>> a.fill(1) + >>> a + array([1., 1.]) + + """)) + + +add_newdoc('numpy.core.multiarray', 'ndarray', ('flatten', + """ + a.flatten(order='C') + + Return a copy of the array collapsed into one dimension. + + Parameters + ---------- + order : {'C', 'F', 'A', 'K'}, optional + 'C' means to flatten in row-major (C-style) order. + 'F' means to flatten in column-major (Fortran- + style) order. 'A' means to flatten in column-major + order if `a` is Fortran *contiguous* in memory, + row-major order otherwise. 'K' means to flatten + `a` in the order the elements occur in memory. + The default is 'C'. + + Returns + ------- + y : ndarray + A copy of the input array, flattened to one dimension. + + See Also + -------- + ravel : Return a flattened array. + flat : A 1-D flat iterator over the array. + + Examples + -------- + >>> a = np.array([[1,2], [3,4]]) + >>> a.flatten() + array([1, 2, 3, 4]) + >>> a.flatten('F') + array([1, 3, 2, 4]) + + """)) + + +add_newdoc('numpy.core.multiarray', 'ndarray', ('getfield', + """ + a.getfield(dtype, offset=0) + + Returns a field of the given array as a certain type. + + A field is a view of the array data with a given data-type. The values in + the view are determined by the given type and the offset into the current + array in bytes. The offset needs to be such that the view dtype fits in the + array dtype; for example an array of dtype complex128 has 16-byte elements. + If taking a view with a 32-bit integer (4 bytes), the offset needs to be + between 0 and 12 bytes. + + Parameters + ---------- + dtype : str or dtype + The data type of the view. The dtype size of the view can not be larger + than that of the array itself. + offset : int + Number of bytes to skip before beginning the element view. + + Examples + -------- + >>> x = np.diag([1.+1.j]*2) + >>> x[1, 1] = 2 + 4.j + >>> x + array([[1.+1.j, 0.+0.j], + [0.+0.j, 2.+4.j]]) + >>> x.getfield(np.float64) + array([[1., 0.], + [0., 2.]]) + + By choosing an offset of 8 bytes we can select the complex part of the + array for our view: + + >>> x.getfield(np.float64, offset=8) + array([[1., 0.], + [0., 4.]]) + + """)) + + +add_newdoc('numpy.core.multiarray', 'ndarray', ('item', + """ + a.item(*args) + + Copy an element of an array to a standard Python scalar and return it. + + Parameters + ---------- + \\*args : Arguments (variable number and type) + + * none: in this case, the method only works for arrays + with one element (`a.size == 1`), which element is + copied into a standard Python scalar object and returned. + + * int_type: this argument is interpreted as a flat index into + the array, specifying which element to copy and return. + + * tuple of int_types: functions as does a single int_type argument, + except that the argument is interpreted as an nd-index into the + array. + + Returns + ------- + z : Standard Python scalar object + A copy of the specified element of the array as a suitable + Python scalar + + Notes + ----- + When the data type of `a` is longdouble or clongdouble, item() returns + a scalar array object because there is no available Python scalar that + would not lose information. Void arrays return a buffer object for item(), + unless fields are defined, in which case a tuple is returned. + + `item` is very similar to a[args], except, instead of an array scalar, + a standard Python scalar is returned. This can be useful for speeding up + access to elements of the array and doing arithmetic on elements of the + array using Python's optimized math. + + Examples + -------- + >>> np.random.seed(123) + >>> x = np.random.randint(9, size=(3, 3)) + >>> x + array([[2, 2, 6], + [1, 3, 6], + [1, 0, 1]]) + >>> x.item(3) + 1 + >>> x.item(7) + 0 + >>> x.item((0, 1)) + 2 + >>> x.item((2, 2)) + 1 + + """)) + + +add_newdoc('numpy.core.multiarray', 'ndarray', ('itemset', + """ + a.itemset(*args) + + Insert scalar into an array (scalar is cast to array's dtype, if possible) + + There must be at least 1 argument, and define the last argument + as *item*. Then, ``a.itemset(*args)`` is equivalent to but faster + than ``a[args] = item``. The item should be a scalar value and `args` + must select a single item in the array `a`. + + Parameters + ---------- + \\*args : Arguments + If one argument: a scalar, only used in case `a` is of size 1. + If two arguments: the last argument is the value to be set + and must be a scalar, the first argument specifies a single array + element location. It is either an int or a tuple. + + Notes + ----- + Compared to indexing syntax, `itemset` provides some speed increase + for placing a scalar into a particular location in an `ndarray`, + if you must do this. However, generally this is discouraged: + among other problems, it complicates the appearance of the code. + Also, when using `itemset` (and `item`) inside a loop, be sure + to assign the methods to a local variable to avoid the attribute + look-up at each loop iteration. + + Examples + -------- + >>> np.random.seed(123) + >>> x = np.random.randint(9, size=(3, 3)) + >>> x + array([[2, 2, 6], + [1, 3, 6], + [1, 0, 1]]) + >>> x.itemset(4, 0) + >>> x.itemset((2, 2), 9) + >>> x + array([[2, 2, 6], + [1, 0, 6], + [1, 0, 9]]) + + """)) + + +add_newdoc('numpy.core.multiarray', 'ndarray', ('max', + """ + a.max(axis=None, out=None, keepdims=False, initial=, where=True) + + Return the maximum along a given axis. + + Refer to `numpy.amax` for full documentation. + + See Also + -------- + numpy.amax : equivalent function + + """)) + + +add_newdoc('numpy.core.multiarray', 'ndarray', ('mean', + """ + a.mean(axis=None, dtype=None, out=None, keepdims=False, *, where=True) + + Returns the average of the array elements along given axis. + + Refer to `numpy.mean` for full documentation. + + See Also + -------- + numpy.mean : equivalent function + + """)) + + +add_newdoc('numpy.core.multiarray', 'ndarray', ('min', + """ + a.min(axis=None, out=None, keepdims=False, initial=, where=True) + + Return the minimum along a given axis. + + Refer to `numpy.amin` for full documentation. + + See Also + -------- + numpy.amin : equivalent function + + """)) + + +add_newdoc('numpy.core.multiarray', 'ndarray', ('newbyteorder', + """ + arr.newbyteorder(new_order='S', /) + + Return the array with the same data viewed with a different byte order. + + Equivalent to:: + + arr.view(arr.dtype.newbytorder(new_order)) + + Changes are also made in all fields and sub-arrays of the array data + type. + + + + Parameters + ---------- + new_order : string, optional + Byte order to force; a value from the byte order specifications + below. `new_order` codes can be any of: + + * 'S' - swap dtype from current to opposite endian + * {'<', 'little'} - little endian + * {'>', 'big'} - big endian + * '=' - native order, equivalent to `sys.byteorder` + * {'|', 'I'} - ignore (no change to byte order) + + The default value ('S') results in swapping the current + byte order. + + + Returns + ------- + new_arr : array + New array object with the dtype reflecting given change to the + byte order. + + """)) + + +add_newdoc('numpy.core.multiarray', 'ndarray', ('nonzero', + """ + a.nonzero() + + Return the indices of the elements that are non-zero. + + Refer to `numpy.nonzero` for full documentation. + + See Also + -------- + numpy.nonzero : equivalent function + + """)) + + +add_newdoc('numpy.core.multiarray', 'ndarray', ('prod', + """ + a.prod(axis=None, dtype=None, out=None, keepdims=False, initial=1, where=True) + + Return the product of the array elements over the given axis + + Refer to `numpy.prod` for full documentation. + + See Also + -------- + numpy.prod : equivalent function + + """)) + + +add_newdoc('numpy.core.multiarray', 'ndarray', ('ptp', + """ + a.ptp(axis=None, out=None, keepdims=False) + + Peak to peak (maximum - minimum) value along a given axis. + + Refer to `numpy.ptp` for full documentation. + + See Also + -------- + numpy.ptp : equivalent function + + """)) + + +add_newdoc('numpy.core.multiarray', 'ndarray', ('put', + """ + a.put(indices, values, mode='raise') + + Set ``a.flat[n] = values[n]`` for all `n` in indices. + + Refer to `numpy.put` for full documentation. + + See Also + -------- + numpy.put : equivalent function + + """)) + + +add_newdoc('numpy.core.multiarray', 'ndarray', ('ravel', + """ + a.ravel([order]) + + Return a flattened array. + + Refer to `numpy.ravel` for full documentation. + + See Also + -------- + numpy.ravel : equivalent function + + ndarray.flat : a flat iterator on the array. + + """)) + + +add_newdoc('numpy.core.multiarray', 'ndarray', ('repeat', + """ + a.repeat(repeats, axis=None) + + Repeat elements of an array. + + Refer to `numpy.repeat` for full documentation. + + See Also + -------- + numpy.repeat : equivalent function + + """)) + + +add_newdoc('numpy.core.multiarray', 'ndarray', ('reshape', + """ + a.reshape(shape, order='C') + + Returns an array containing the same data with a new shape. + + Refer to `numpy.reshape` for full documentation. + + See Also + -------- + numpy.reshape : equivalent function + + Notes + ----- + Unlike the free function `numpy.reshape`, this method on `ndarray` allows + the elements of the shape parameter to be passed in as separate arguments. + For example, ``a.reshape(10, 11)`` is equivalent to + ``a.reshape((10, 11))``. + + """)) + + +add_newdoc('numpy.core.multiarray', 'ndarray', ('resize', + """ + a.resize(new_shape, refcheck=True) + + Change shape and size of array in-place. + + Parameters + ---------- + new_shape : tuple of ints, or `n` ints + Shape of resized array. + refcheck : bool, optional + If False, reference count will not be checked. Default is True. + + Returns + ------- + None + + Raises + ------ + ValueError + If `a` does not own its own data or references or views to it exist, + and the data memory must be changed. + PyPy only: will always raise if the data memory must be changed, since + there is no reliable way to determine if references or views to it + exist. + + SystemError + If the `order` keyword argument is specified. This behaviour is a + bug in NumPy. + + See Also + -------- + resize : Return a new array with the specified shape. + + Notes + ----- + This reallocates space for the data area if necessary. + + Only contiguous arrays (data elements consecutive in memory) can be + resized. + + The purpose of the reference count check is to make sure you + do not use this array as a buffer for another Python object and then + reallocate the memory. However, reference counts can increase in + other ways so if you are sure that you have not shared the memory + for this array with another Python object, then you may safely set + `refcheck` to False. + + Examples + -------- + Shrinking an array: array is flattened (in the order that the data are + stored in memory), resized, and reshaped: + + >>> a = np.array([[0, 1], [2, 3]], order='C') + >>> a.resize((2, 1)) + >>> a + array([[0], + [1]]) + + >>> a = np.array([[0, 1], [2, 3]], order='F') + >>> a.resize((2, 1)) + >>> a + array([[0], + [2]]) + + Enlarging an array: as above, but missing entries are filled with zeros: + + >>> b = np.array([[0, 1], [2, 3]]) + >>> b.resize(2, 3) # new_shape parameter doesn't have to be a tuple + >>> b + array([[0, 1, 2], + [3, 0, 0]]) + + Referencing an array prevents resizing... + + >>> c = a + >>> a.resize((1, 1)) + Traceback (most recent call last): + ... + ValueError: cannot resize an array that references or is referenced ... + + Unless `refcheck` is False: + + >>> a.resize((1, 1), refcheck=False) + >>> a + array([[0]]) + >>> c + array([[0]]) + + """)) + + +add_newdoc('numpy.core.multiarray', 'ndarray', ('round', + """ + a.round(decimals=0, out=None) + + Return `a` with each element rounded to the given number of decimals. + + Refer to `numpy.around` for full documentation. + + See Also + -------- + numpy.around : equivalent function + + """)) + + +add_newdoc('numpy.core.multiarray', 'ndarray', ('searchsorted', + """ + a.searchsorted(v, side='left', sorter=None) + + Find indices where elements of v should be inserted in a to maintain order. + + For full documentation, see `numpy.searchsorted` + + See Also + -------- + numpy.searchsorted : equivalent function + + """)) + + +add_newdoc('numpy.core.multiarray', 'ndarray', ('setfield', + """ + a.setfield(val, dtype, offset=0) + + Put a value into a specified place in a field defined by a data-type. + + Place `val` into `a`'s field defined by `dtype` and beginning `offset` + bytes into the field. + + Parameters + ---------- + val : object + Value to be placed in field. + dtype : dtype object + Data-type of the field in which to place `val`. + offset : int, optional + The number of bytes into the field at which to place `val`. + + Returns + ------- + None + + See Also + -------- + getfield + + Examples + -------- + >>> x = np.eye(3) + >>> x.getfield(np.float64) + array([[1., 0., 0.], + [0., 1., 0.], + [0., 0., 1.]]) + >>> x.setfield(3, np.int32) + >>> x.getfield(np.int32) + array([[3, 3, 3], + [3, 3, 3], + [3, 3, 3]], dtype=int32) + >>> x + array([[1.0e+000, 1.5e-323, 1.5e-323], + [1.5e-323, 1.0e+000, 1.5e-323], + [1.5e-323, 1.5e-323, 1.0e+000]]) + >>> x.setfield(np.eye(3), np.int32) + >>> x + array([[1., 0., 0.], + [0., 1., 0.], + [0., 0., 1.]]) + + """)) + + +add_newdoc('numpy.core.multiarray', 'ndarray', ('setflags', + """ + a.setflags(write=None, align=None, uic=None) + + Set array flags WRITEABLE, ALIGNED, (WRITEBACKIFCOPY and UPDATEIFCOPY), + respectively. + + These Boolean-valued flags affect how numpy interprets the memory + area used by `a` (see Notes below). The ALIGNED flag can only + be set to True if the data is actually aligned according to the type. + The WRITEBACKIFCOPY and (deprecated) UPDATEIFCOPY flags can never be set + to True. The flag WRITEABLE can only be set to True if the array owns its + own memory, or the ultimate owner of the memory exposes a writeable buffer + interface, or is a string. (The exception for string is made so that + unpickling can be done without copying memory.) + + Parameters + ---------- + write : bool, optional + Describes whether or not `a` can be written to. + align : bool, optional + Describes whether or not `a` is aligned properly for its type. + uic : bool, optional + Describes whether or not `a` is a copy of another "base" array. + + Notes + ----- + Array flags provide information about how the memory area used + for the array is to be interpreted. There are 7 Boolean flags + in use, only four of which can be changed by the user: + WRITEBACKIFCOPY, UPDATEIFCOPY, WRITEABLE, and ALIGNED. + + WRITEABLE (W) the data area can be written to; + + ALIGNED (A) the data and strides are aligned appropriately for the hardware + (as determined by the compiler); + + UPDATEIFCOPY (U) (deprecated), replaced by WRITEBACKIFCOPY; + + WRITEBACKIFCOPY (X) this array is a copy of some other array (referenced + by .base). When the C-API function PyArray_ResolveWritebackIfCopy is + called, the base array will be updated with the contents of this array. + + All flags can be accessed using the single (upper case) letter as well + as the full name. + + Examples + -------- + >>> y = np.array([[3, 1, 7], + ... [2, 0, 0], + ... [8, 5, 9]]) + >>> y + array([[3, 1, 7], + [2, 0, 0], + [8, 5, 9]]) + >>> y.flags + C_CONTIGUOUS : True + F_CONTIGUOUS : False + OWNDATA : True + WRITEABLE : True + ALIGNED : True + WRITEBACKIFCOPY : False + UPDATEIFCOPY : False + >>> y.setflags(write=0, align=0) + >>> y.flags + C_CONTIGUOUS : True + F_CONTIGUOUS : False + OWNDATA : True + WRITEABLE : False + ALIGNED : False + WRITEBACKIFCOPY : False + UPDATEIFCOPY : False + >>> y.setflags(uic=1) + Traceback (most recent call last): + File "", line 1, in + ValueError: cannot set WRITEBACKIFCOPY flag to True + + """)) + + +add_newdoc('numpy.core.multiarray', 'ndarray', ('sort', + """ + a.sort(axis=-1, kind=None, order=None) + + Sort an array in-place. Refer to `numpy.sort` for full documentation. + + Parameters + ---------- + axis : int, optional + Axis along which to sort. Default is -1, which means sort along the + last axis. + kind : {'quicksort', 'mergesort', 'heapsort', 'stable'}, optional + Sorting algorithm. The default is 'quicksort'. Note that both 'stable' + and 'mergesort' use timsort under the covers and, in general, the + actual implementation will vary with datatype. The 'mergesort' option + is retained for backwards compatibility. + + .. versionchanged:: 1.15.0. + The 'stable' option was added. + + order : str or list of str, optional + When `a` is an array with fields defined, this argument specifies + which fields to compare first, second, etc. A single field can + be specified as a string, and not all fields need be specified, + but unspecified fields will still be used, in the order in which + they come up in the dtype, to break ties. + + See Also + -------- + numpy.sort : Return a sorted copy of an array. + numpy.argsort : Indirect sort. + numpy.lexsort : Indirect stable sort on multiple keys. + numpy.searchsorted : Find elements in sorted array. + numpy.partition: Partial sort. + + Notes + ----- + See `numpy.sort` for notes on the different sorting algorithms. + + Examples + -------- + >>> a = np.array([[1,4], [3,1]]) + >>> a.sort(axis=1) + >>> a + array([[1, 4], + [1, 3]]) + >>> a.sort(axis=0) + >>> a + array([[1, 3], + [1, 4]]) + + Use the `order` keyword to specify a field to use when sorting a + structured array: + + >>> a = np.array([('a', 2), ('c', 1)], dtype=[('x', 'S1'), ('y', int)]) + >>> a.sort(order='y') + >>> a + array([(b'c', 1), (b'a', 2)], + dtype=[('x', 'S1'), ('y', '>> a = np.array([3, 4, 2, 1]) + >>> a.partition(3) + >>> a + array([2, 1, 3, 4]) + + >>> a.partition((1, 3)) + >>> a + array([1, 2, 3, 4]) + """)) + + +add_newdoc('numpy.core.multiarray', 'ndarray', ('squeeze', + """ + a.squeeze(axis=None) + + Remove axes of length one from `a`. + + Refer to `numpy.squeeze` for full documentation. + + See Also + -------- + numpy.squeeze : equivalent function + + """)) + + +add_newdoc('numpy.core.multiarray', 'ndarray', ('std', + """ + a.std(axis=None, dtype=None, out=None, ddof=0, keepdims=False, *, where=True) + + Returns the standard deviation of the array elements along given axis. + + Refer to `numpy.std` for full documentation. + + See Also + -------- + numpy.std : equivalent function + + """)) + + +add_newdoc('numpy.core.multiarray', 'ndarray', ('sum', + """ + a.sum(axis=None, dtype=None, out=None, keepdims=False, initial=0, where=True) + + Return the sum of the array elements over the given axis. + + Refer to `numpy.sum` for full documentation. + + See Also + -------- + numpy.sum : equivalent function + + """)) + + +add_newdoc('numpy.core.multiarray', 'ndarray', ('swapaxes', + """ + a.swapaxes(axis1, axis2) + + Return a view of the array with `axis1` and `axis2` interchanged. + + Refer to `numpy.swapaxes` for full documentation. + + See Also + -------- + numpy.swapaxes : equivalent function + + """)) + + +add_newdoc('numpy.core.multiarray', 'ndarray', ('take', + """ + a.take(indices, axis=None, out=None, mode='raise') + + Return an array formed from the elements of `a` at the given indices. + + Refer to `numpy.take` for full documentation. + + See Also + -------- + numpy.take : equivalent function + + """)) + + +add_newdoc('numpy.core.multiarray', 'ndarray', ('tofile', + """ + a.tofile(fid, sep="", format="%s") + + Write array to a file as text or binary (default). + + Data is always written in 'C' order, independent of the order of `a`. + The data produced by this method can be recovered using the function + fromfile(). + + Parameters + ---------- + fid : file or str or Path + An open file object, or a string containing a filename. + + .. versionchanged:: 1.17.0 + `pathlib.Path` objects are now accepted. + + sep : str + Separator between array items for text output. + If "" (empty), a binary file is written, equivalent to + ``file.write(a.tobytes())``. + format : str + Format string for text file output. + Each entry in the array is formatted to text by first converting + it to the closest Python type, and then using "format" % item. + + Notes + ----- + This is a convenience function for quick storage of array data. + Information on endianness and precision is lost, so this method is not a + good choice for files intended to archive data or transport data between + machines with different endianness. Some of these problems can be overcome + by outputting the data as text files, at the expense of speed and file + size. + + When fid is a file object, array contents are directly written to the + file, bypassing the file object's ``write`` method. As a result, tofile + cannot be used with files objects supporting compression (e.g., GzipFile) + or file-like objects that do not support ``fileno()`` (e.g., BytesIO). + + """)) + + +add_newdoc('numpy.core.multiarray', 'ndarray', ('tolist', + """ + a.tolist() + + Return the array as an ``a.ndim``-levels deep nested list of Python scalars. + + Return a copy of the array data as a (nested) Python list. + Data items are converted to the nearest compatible builtin Python type, via + the `~numpy.ndarray.item` function. + + If ``a.ndim`` is 0, then since the depth of the nested list is 0, it will + not be a list at all, but a simple Python scalar. + + Parameters + ---------- + none + + Returns + ------- + y : object, or list of object, or list of list of object, or ... + The possibly nested list of array elements. + + Notes + ----- + The array may be recreated via ``a = np.array(a.tolist())``, although this + may sometimes lose precision. + + Examples + -------- + For a 1D array, ``a.tolist()`` is almost the same as ``list(a)``, + except that ``tolist`` changes numpy scalars to Python scalars: + + >>> a = np.uint32([1, 2]) + >>> a_list = list(a) + >>> a_list + [1, 2] + >>> type(a_list[0]) + + >>> a_tolist = a.tolist() + >>> a_tolist + [1, 2] + >>> type(a_tolist[0]) + + + Additionally, for a 2D array, ``tolist`` applies recursively: + + >>> a = np.array([[1, 2], [3, 4]]) + >>> list(a) + [array([1, 2]), array([3, 4])] + >>> a.tolist() + [[1, 2], [3, 4]] + + The base case for this recursion is a 0D array: + + >>> a = np.array(1) + >>> list(a) + Traceback (most recent call last): + ... + TypeError: iteration over a 0-d array + >>> a.tolist() + 1 + """)) + + +add_newdoc('numpy.core.multiarray', 'ndarray', ('tobytes', """ + a.tobytes(order='C') + + Construct Python bytes containing the raw data bytes in the array. + + Constructs Python bytes showing a copy of the raw contents of + data memory. The bytes object is produced in C-order by default. + This behavior is controlled by the ``order`` parameter. + + .. versionadded:: 1.9.0 + + Parameters + ---------- + order : {'C', 'F', 'A'}, optional + Controls the memory layout of the bytes object. 'C' means C-order, + 'F' means F-order, 'A' (short for *Any*) means 'F' if `a` is + Fortran contiguous, 'C' otherwise. Default is 'C'. + + Returns + ------- + s : bytes + Python bytes exhibiting a copy of `a`'s raw data. + + Examples + -------- + >>> x = np.array([[0, 1], [2, 3]], dtype='>> x.tobytes() + b'\\x00\\x00\\x01\\x00\\x02\\x00\\x03\\x00' + >>> x.tobytes('C') == x.tobytes() + True + >>> x.tobytes('F') + b'\\x00\\x00\\x02\\x00\\x01\\x00\\x03\\x00' + + """)) + + +add_newdoc('numpy.core.multiarray', 'ndarray', ('tostring', r""" + a.tostring(order='C') + + A compatibility alias for `tobytes`, with exactly the same behavior. + + Despite its name, it returns `bytes` not `str`\ s. + + .. deprecated:: 1.19.0 + """)) + + +add_newdoc('numpy.core.multiarray', 'ndarray', ('trace', + """ + a.trace(offset=0, axis1=0, axis2=1, dtype=None, out=None) + + Return the sum along diagonals of the array. + + Refer to `numpy.trace` for full documentation. + + See Also + -------- + numpy.trace : equivalent function + + """)) + + +add_newdoc('numpy.core.multiarray', 'ndarray', ('transpose', + """ + a.transpose(*axes) + + Returns a view of the array with axes transposed. + + For a 1-D array this has no effect, as a transposed vector is simply the + same vector. To convert a 1-D array into a 2D column vector, an additional + dimension must be added. `np.atleast2d(a).T` achieves this, as does + `a[:, np.newaxis]`. + For a 2-D array, this is a standard matrix transpose. + For an n-D array, if axes are given, their order indicates how the + axes are permuted (see Examples). If axes are not provided and + ``a.shape = (i[0], i[1], ... i[n-2], i[n-1])``, then + ``a.transpose().shape = (i[n-1], i[n-2], ... i[1], i[0])``. + + Parameters + ---------- + axes : None, tuple of ints, or `n` ints + + * None or no argument: reverses the order of the axes. + + * tuple of ints: `i` in the `j`-th place in the tuple means `a`'s + `i`-th axis becomes `a.transpose()`'s `j`-th axis. + + * `n` ints: same as an n-tuple of the same ints (this form is + intended simply as a "convenience" alternative to the tuple form) + + Returns + ------- + out : ndarray + View of `a`, with axes suitably permuted. + + See Also + -------- + ndarray.T : Array property returning the array transposed. + ndarray.reshape : Give a new shape to an array without changing its data. + + Examples + -------- + >>> a = np.array([[1, 2], [3, 4]]) + >>> a + array([[1, 2], + [3, 4]]) + >>> a.transpose() + array([[1, 3], + [2, 4]]) + >>> a.transpose((1, 0)) + array([[1, 3], + [2, 4]]) + >>> a.transpose(1, 0) + array([[1, 3], + [2, 4]]) + + """)) + + +add_newdoc('numpy.core.multiarray', 'ndarray', ('var', + """ + a.var(axis=None, dtype=None, out=None, ddof=0, keepdims=False, *, where=True) + + Returns the variance of the array elements, along given axis. + + Refer to `numpy.var` for full documentation. + + See Also + -------- + numpy.var : equivalent function + + """)) + + +add_newdoc('numpy.core.multiarray', 'ndarray', ('view', + """ + a.view([dtype][, type]) + + New view of array with the same data. + + .. note:: + Passing None for ``dtype`` is different from omitting the parameter, + since the former invokes ``dtype(None)`` which is an alias for + ``dtype('float_')``. + + Parameters + ---------- + dtype : data-type or ndarray sub-class, optional + Data-type descriptor of the returned view, e.g., float32 or int16. + Omitting it results in the view having the same data-type as `a`. + This argument can also be specified as an ndarray sub-class, which + then specifies the type of the returned object (this is equivalent to + setting the ``type`` parameter). + type : Python type, optional + Type of the returned view, e.g., ndarray or matrix. Again, omission + of the parameter results in type preservation. + + Notes + ----- + ``a.view()`` is used two different ways: + + ``a.view(some_dtype)`` or ``a.view(dtype=some_dtype)`` constructs a view + of the array's memory with a different data-type. This can cause a + reinterpretation of the bytes of memory. + + ``a.view(ndarray_subclass)`` or ``a.view(type=ndarray_subclass)`` just + returns an instance of `ndarray_subclass` that looks at the same array + (same shape, dtype, etc.) This does not cause a reinterpretation of the + memory. + + For ``a.view(some_dtype)``, if ``some_dtype`` has a different number of + bytes per entry than the previous dtype (for example, converting a + regular array to a structured array), then the behavior of the view + cannot be predicted just from the superficial appearance of ``a`` (shown + by ``print(a)``). It also depends on exactly how ``a`` is stored in + memory. Therefore if ``a`` is C-ordered versus fortran-ordered, versus + defined as a slice or transpose, etc., the view may give different + results. + + + Examples + -------- + >>> x = np.array([(1, 2)], dtype=[('a', np.int8), ('b', np.int8)]) + + Viewing array data using a different type and dtype: + + >>> y = x.view(dtype=np.int16, type=np.matrix) + >>> y + matrix([[513]], dtype=int16) + >>> print(type(y)) + + + Creating a view on a structured array so it can be used in calculations + + >>> x = np.array([(1, 2),(3,4)], dtype=[('a', np.int8), ('b', np.int8)]) + >>> xv = x.view(dtype=np.int8).reshape(-1,2) + >>> xv + array([[1, 2], + [3, 4]], dtype=int8) + >>> xv.mean(0) + array([2., 3.]) + + Making changes to the view changes the underlying array + + >>> xv[0,1] = 20 + >>> x + array([(1, 20), (3, 4)], dtype=[('a', 'i1'), ('b', 'i1')]) + + Using a view to convert an array to a recarray: + + >>> z = x.view(np.recarray) + >>> z.a + array([1, 3], dtype=int8) + + Views share data: + + >>> x[0] = (9, 10) + >>> z[0] + (9, 10) + + Views that change the dtype size (bytes per entry) should normally be + avoided on arrays defined by slices, transposes, fortran-ordering, etc.: + + >>> x = np.array([[1,2,3],[4,5,6]], dtype=np.int16) + >>> y = x[:, 0:2] + >>> y + array([[1, 2], + [4, 5]], dtype=int16) + >>> y.view(dtype=[('width', np.int16), ('length', np.int16)]) + Traceback (most recent call last): + ... + ValueError: To change to a dtype of a different size, the array must be C-contiguous + >>> z = y.copy() + >>> z.view(dtype=[('width', np.int16), ('length', np.int16)]) + array([[(1, 2)], + [(4, 5)]], dtype=[('width', '>> oct_array = np.frompyfunc(oct, 1, 1) + >>> oct_array(np.array((10, 30, 100))) + array(['0o12', '0o36', '0o144'], dtype=object) + >>> np.array((oct(10), oct(30), oct(100))) # for comparison + array(['0o12', '0o36', '0o144'], dtype='>> np.geterrobj() # first get the defaults + [8192, 521, None] + + >>> def err_handler(type, flag): + ... print("Floating point error (%s), with flag %s" % (type, flag)) + ... + >>> old_bufsize = np.setbufsize(20000) + >>> old_err = np.seterr(divide='raise') + >>> old_handler = np.seterrcall(err_handler) + >>> np.geterrobj() + [8192, 521, ] + + >>> old_err = np.seterr(all='ignore') + >>> np.base_repr(np.geterrobj()[1], 8) + '0' + >>> old_err = np.seterr(divide='warn', over='log', under='call', + ... invalid='print') + >>> np.base_repr(np.geterrobj()[1], 8) + '4351' + + """) + +add_newdoc('numpy.core.umath', 'seterrobj', + """ + seterrobj(errobj) + + Set the object that defines floating-point error handling. + + The error object contains all information that defines the error handling + behavior in NumPy. `seterrobj` is used internally by the other + functions that set error handling behavior (`seterr`, `seterrcall`). + + Parameters + ---------- + errobj : list + The error object, a list containing three elements: + [internal numpy buffer size, error mask, error callback function]. + + The error mask is a single integer that holds the treatment information + on all four floating point errors. The information for each error type + is contained in three bits of the integer. If we print it in base 8, we + can see what treatment is set for "invalid", "under", "over", and + "divide" (in that order). The printed string can be interpreted with + + * 0 : 'ignore' + * 1 : 'warn' + * 2 : 'raise' + * 3 : 'call' + * 4 : 'print' + * 5 : 'log' + + See Also + -------- + geterrobj, seterr, geterr, seterrcall, geterrcall + getbufsize, setbufsize + + Notes + ----- + For complete documentation of the types of floating-point exceptions and + treatment options, see `seterr`. + + Examples + -------- + >>> old_errobj = np.geterrobj() # first get the defaults + >>> old_errobj + [8192, 521, None] + + >>> def err_handler(type, flag): + ... print("Floating point error (%s), with flag %s" % (type, flag)) + ... + >>> new_errobj = [20000, 12, err_handler] + >>> np.seterrobj(new_errobj) + >>> np.base_repr(12, 8) # int for divide=4 ('print') and over=1 ('warn') + '14' + >>> np.geterr() + {'over': 'warn', 'divide': 'print', 'invalid': 'ignore', 'under': 'ignore'} + >>> np.geterrcall() is err_handler + True + + """) + + +############################################################################## +# +# compiled_base functions +# +############################################################################## + +add_newdoc('numpy.core.multiarray', 'add_docstring', + """ + add_docstring(obj, docstring) + + Add a docstring to a built-in obj if possible. + If the obj already has a docstring raise a RuntimeError + If this routine does not know how to add a docstring to the object + raise a TypeError + """) + +add_newdoc('numpy.core.umath', '_add_newdoc_ufunc', + """ + add_ufunc_docstring(ufunc, new_docstring) + + Replace the docstring for a ufunc with new_docstring. + This method will only work if the current docstring for + the ufunc is NULL. (At the C level, i.e. when ufunc->doc is NULL.) + + Parameters + ---------- + ufunc : numpy.ufunc + A ufunc whose current doc is NULL. + new_docstring : string + The new docstring for the ufunc. + + Notes + ----- + This method allocates memory for new_docstring on + the heap. Technically this creates a mempory leak, since this + memory will not be reclaimed until the end of the program + even if the ufunc itself is removed. However this will only + be a problem if the user is repeatedly creating ufuncs with + no documentation, adding documentation via add_newdoc_ufunc, + and then throwing away the ufunc. + """) + +add_newdoc('numpy.core.multiarray', '_set_madvise_hugepage', + """ + _set_madvise_hugepage(enabled: bool) -> bool + + Set or unset use of ``madvise (2)`` MADV_HUGEPAGE support when + allocating the array data. Returns the previously set value. + See `global_state` for more information. + """) + +add_newdoc('numpy.core._multiarray_tests', 'format_float_OSprintf_g', + """ + format_float_OSprintf_g(val, precision) + + Print a floating point scalar using the system's printf function, + equivalent to: + + printf("%.*g", precision, val); + + for half/float/double, or replacing 'g' by 'Lg' for longdouble. This + method is designed to help cross-validate the format_float_* methods. + + Parameters + ---------- + val : python float or numpy floating scalar + Value to format. + + precision : non-negative integer, optional + Precision given to printf. + + Returns + ------- + rep : string + The string representation of the floating point value + + See Also + -------- + format_float_scientific + format_float_positional + """) + + +############################################################################## +# +# Documentation for ufunc attributes and methods +# +############################################################################## + + +############################################################################## +# +# ufunc object +# +############################################################################## + +add_newdoc('numpy.core', 'ufunc', + """ + Functions that operate element by element on whole arrays. + + To see the documentation for a specific ufunc, use `info`. For + example, ``np.info(np.sin)``. Because ufuncs are written in C + (for speed) and linked into Python with NumPy's ufunc facility, + Python's help() function finds this page whenever help() is called + on a ufunc. + + A detailed explanation of ufuncs can be found in the docs for :ref:`ufuncs`. + + **Calling ufuncs:** ``op(*x[, out], where=True, **kwargs)`` + + Apply `op` to the arguments `*x` elementwise, broadcasting the arguments. + + The broadcasting rules are: + + * Dimensions of length 1 may be prepended to either array. + * Arrays may be repeated along dimensions of length 1. + + Parameters + ---------- + *x : array_like + Input arrays. + out : ndarray, None, or tuple of ndarray and None, optional + Alternate array object(s) in which to put the result; if provided, it + must have a shape that the inputs broadcast to. A tuple of arrays + (possible only as a keyword argument) must have length equal to the + number of outputs; use None for uninitialized outputs to be + allocated by the ufunc. + where : array_like, optional + This condition is broadcast over the input. At locations where the + condition is True, the `out` array will be set to the ufunc result. + Elsewhere, the `out` array will retain its original value. + Note that if an uninitialized `out` array is created via the default + ``out=None``, locations within it where the condition is False will + remain uninitialized. + **kwargs + For other keyword-only arguments, see the :ref:`ufunc docs `. + + Returns + ------- + r : ndarray or tuple of ndarray + `r` will have the shape that the arrays in `x` broadcast to; if `out` is + provided, it will be returned. If not, `r` will be allocated and + may contain uninitialized values. If the function has more than one + output, then the result will be a tuple of arrays. + + """) + + +############################################################################## +# +# ufunc attributes +# +############################################################################## + +add_newdoc('numpy.core', 'ufunc', ('identity', + """ + The identity value. + + Data attribute containing the identity element for the ufunc, if it has one. + If it does not, the attribute value is None. + + Examples + -------- + >>> np.add.identity + 0 + >>> np.multiply.identity + 1 + >>> np.power.identity + 1 + >>> print(np.exp.identity) + None + """)) + +add_newdoc('numpy.core', 'ufunc', ('nargs', + """ + The number of arguments. + + Data attribute containing the number of arguments the ufunc takes, including + optional ones. + + Notes + ----- + Typically this value will be one more than what you might expect because all + ufuncs take the optional "out" argument. + + Examples + -------- + >>> np.add.nargs + 3 + >>> np.multiply.nargs + 3 + >>> np.power.nargs + 3 + >>> np.exp.nargs + 2 + """)) + +add_newdoc('numpy.core', 'ufunc', ('nin', + """ + The number of inputs. + + Data attribute containing the number of arguments the ufunc treats as input. + + Examples + -------- + >>> np.add.nin + 2 + >>> np.multiply.nin + 2 + >>> np.power.nin + 2 + >>> np.exp.nin + 1 + """)) + +add_newdoc('numpy.core', 'ufunc', ('nout', + """ + The number of outputs. + + Data attribute containing the number of arguments the ufunc treats as output. + + Notes + ----- + Since all ufuncs can take output arguments, this will always be (at least) 1. + + Examples + -------- + >>> np.add.nout + 1 + >>> np.multiply.nout + 1 + >>> np.power.nout + 1 + >>> np.exp.nout + 1 + + """)) + +add_newdoc('numpy.core', 'ufunc', ('ntypes', + """ + The number of types. + + The number of numerical NumPy types - of which there are 18 total - on which + the ufunc can operate. + + See Also + -------- + numpy.ufunc.types + + Examples + -------- + >>> np.add.ntypes + 18 + >>> np.multiply.ntypes + 18 + >>> np.power.ntypes + 17 + >>> np.exp.ntypes + 7 + >>> np.remainder.ntypes + 14 + + """)) + +add_newdoc('numpy.core', 'ufunc', ('types', + """ + Returns a list with types grouped input->output. + + Data attribute listing the data-type "Domain-Range" groupings the ufunc can + deliver. The data-types are given using the character codes. + + See Also + -------- + numpy.ufunc.ntypes + + Examples + -------- + >>> np.add.types + ['??->?', 'bb->b', 'BB->B', 'hh->h', 'HH->H', 'ii->i', 'II->I', 'll->l', + 'LL->L', 'qq->q', 'QQ->Q', 'ff->f', 'dd->d', 'gg->g', 'FF->F', 'DD->D', + 'GG->G', 'OO->O'] + + >>> np.multiply.types + ['??->?', 'bb->b', 'BB->B', 'hh->h', 'HH->H', 'ii->i', 'II->I', 'll->l', + 'LL->L', 'qq->q', 'QQ->Q', 'ff->f', 'dd->d', 'gg->g', 'FF->F', 'DD->D', + 'GG->G', 'OO->O'] + + >>> np.power.types + ['bb->b', 'BB->B', 'hh->h', 'HH->H', 'ii->i', 'II->I', 'll->l', 'LL->L', + 'qq->q', 'QQ->Q', 'ff->f', 'dd->d', 'gg->g', 'FF->F', 'DD->D', 'GG->G', + 'OO->O'] + + >>> np.exp.types + ['f->f', 'd->d', 'g->g', 'F->F', 'D->D', 'G->G', 'O->O'] + + >>> np.remainder.types + ['bb->b', 'BB->B', 'hh->h', 'HH->H', 'ii->i', 'II->I', 'll->l', 'LL->L', + 'qq->q', 'QQ->Q', 'ff->f', 'dd->d', 'gg->g', 'OO->O'] + + """)) + +add_newdoc('numpy.core', 'ufunc', ('signature', + """ + Definition of the core elements a generalized ufunc operates on. + + The signature determines how the dimensions of each input/output array + are split into core and loop dimensions: + + 1. Each dimension in the signature is matched to a dimension of the + corresponding passed-in array, starting from the end of the shape tuple. + 2. Core dimensions assigned to the same label in the signature must have + exactly matching sizes, no broadcasting is performed. + 3. The core dimensions are removed from all inputs and the remaining + dimensions are broadcast together, defining the loop dimensions. + + Notes + ----- + Generalized ufuncs are used internally in many linalg functions, and in + the testing suite; the examples below are taken from these. + For ufuncs that operate on scalars, the signature is None, which is + equivalent to '()' for every argument. + + Examples + -------- + >>> np.core.umath_tests.matrix_multiply.signature + '(m,n),(n,p)->(m,p)' + >>> np.linalg._umath_linalg.det.signature + '(m,m)->()' + >>> np.add.signature is None + True # equivalent to '(),()->()' + """)) + +############################################################################## +# +# ufunc methods +# +############################################################################## + +add_newdoc('numpy.core', 'ufunc', ('reduce', + """ + reduce(array, axis=0, dtype=None, out=None, keepdims=False, initial=, where=True) + + Reduces `array`'s dimension by one, by applying ufunc along one axis. + + Let :math:`array.shape = (N_0, ..., N_i, ..., N_{M-1})`. Then + :math:`ufunc.reduce(array, axis=i)[k_0, ..,k_{i-1}, k_{i+1}, .., k_{M-1}]` = + the result of iterating `j` over :math:`range(N_i)`, cumulatively applying + ufunc to each :math:`array[k_0, ..,k_{i-1}, j, k_{i+1}, .., k_{M-1}]`. + For a one-dimensional array, reduce produces results equivalent to: + :: + + r = op.identity # op = ufunc + for i in range(len(A)): + r = op(r, A[i]) + return r + + For example, add.reduce() is equivalent to sum(). + + Parameters + ---------- + array : array_like + The array to act on. + axis : None or int or tuple of ints, optional + Axis or axes along which a reduction is performed. + The default (`axis` = 0) is perform a reduction over the first + dimension of the input array. `axis` may be negative, in + which case it counts from the last to the first axis. + + .. versionadded:: 1.7.0 + + If this is None, a reduction is performed over all the axes. + If this is a tuple of ints, a reduction is performed on multiple + axes, instead of a single axis or all the axes as before. + + For operations which are either not commutative or not associative, + doing a reduction over multiple axes is not well-defined. The + ufuncs do not currently raise an exception in this case, but will + likely do so in the future. + dtype : data-type code, optional + The type used to represent the intermediate results. Defaults + to the data-type of the output array if this is provided, or + the data-type of the input array if no output array is provided. + out : ndarray, None, or tuple of ndarray and None, optional + A location into which the result is stored. If not provided or None, + a freshly-allocated array is returned. For consistency with + ``ufunc.__call__``, if given as a keyword, this may be wrapped in a + 1-element tuple. + + .. versionchanged:: 1.13.0 + Tuples are allowed for keyword argument. + keepdims : bool, optional + If this is set to True, the axes which are reduced are left + in the result as dimensions with size one. With this option, + the result will broadcast correctly against the original `array`. + + .. versionadded:: 1.7.0 + initial : scalar, optional + The value with which to start the reduction. + If the ufunc has no identity or the dtype is object, this defaults + to None - otherwise it defaults to ufunc.identity. + If ``None`` is given, the first element of the reduction is used, + and an error is thrown if the reduction is empty. + + .. versionadded:: 1.15.0 + + where : array_like of bool, optional + A boolean array which is broadcasted to match the dimensions + of `array`, and selects elements to include in the reduction. Note + that for ufuncs like ``minimum`` that do not have an identity + defined, one has to pass in also ``initial``. + + .. versionadded:: 1.17.0 + + Returns + ------- + r : ndarray + The reduced array. If `out` was supplied, `r` is a reference to it. + + Examples + -------- + >>> np.multiply.reduce([2,3,5]) + 30 + + A multi-dimensional array example: + + >>> X = np.arange(8).reshape((2,2,2)) + >>> X + array([[[0, 1], + [2, 3]], + [[4, 5], + [6, 7]]]) + >>> np.add.reduce(X, 0) + array([[ 4, 6], + [ 8, 10]]) + >>> np.add.reduce(X) # confirm: default axis value is 0 + array([[ 4, 6], + [ 8, 10]]) + >>> np.add.reduce(X, 1) + array([[ 2, 4], + [10, 12]]) + >>> np.add.reduce(X, 2) + array([[ 1, 5], + [ 9, 13]]) + + You can use the ``initial`` keyword argument to initialize the reduction + with a different value, and ``where`` to select specific elements to include: + + >>> np.add.reduce([10], initial=5) + 15 + >>> np.add.reduce(np.ones((2, 2, 2)), axis=(0, 2), initial=10) + array([14., 14.]) + >>> a = np.array([10., np.nan, 10]) + >>> np.add.reduce(a, where=~np.isnan(a)) + 20.0 + + Allows reductions of empty arrays where they would normally fail, i.e. + for ufuncs without an identity. + + >>> np.minimum.reduce([], initial=np.inf) + inf + >>> np.minimum.reduce([[1., 2.], [3., 4.]], initial=10., where=[True, False]) + array([ 1., 10.]) + >>> np.minimum.reduce([]) + Traceback (most recent call last): + ... + ValueError: zero-size array to reduction operation minimum which has no identity + """)) + +add_newdoc('numpy.core', 'ufunc', ('accumulate', + """ + accumulate(array, axis=0, dtype=None, out=None) + + Accumulate the result of applying the operator to all elements. + + For a one-dimensional array, accumulate produces results equivalent to:: + + r = np.empty(len(A)) + t = op.identity # op = the ufunc being applied to A's elements + for i in range(len(A)): + t = op(t, A[i]) + r[i] = t + return r + + For example, add.accumulate() is equivalent to np.cumsum(). + + For a multi-dimensional array, accumulate is applied along only one + axis (axis zero by default; see Examples below) so repeated use is + necessary if one wants to accumulate over multiple axes. + + Parameters + ---------- + array : array_like + The array to act on. + axis : int, optional + The axis along which to apply the accumulation; default is zero. + dtype : data-type code, optional + The data-type used to represent the intermediate results. Defaults + to the data-type of the output array if such is provided, or the + the data-type of the input array if no output array is provided. + out : ndarray, None, or tuple of ndarray and None, optional + A location into which the result is stored. If not provided or None, + a freshly-allocated array is returned. For consistency with + ``ufunc.__call__``, if given as a keyword, this may be wrapped in a + 1-element tuple. + + .. versionchanged:: 1.13.0 + Tuples are allowed for keyword argument. + + Returns + ------- + r : ndarray + The accumulated values. If `out` was supplied, `r` is a reference to + `out`. + + Examples + -------- + 1-D array examples: + + >>> np.add.accumulate([2, 3, 5]) + array([ 2, 5, 10]) + >>> np.multiply.accumulate([2, 3, 5]) + array([ 2, 6, 30]) + + 2-D array examples: + + >>> I = np.eye(2) + >>> I + array([[1., 0.], + [0., 1.]]) + + Accumulate along axis 0 (rows), down columns: + + >>> np.add.accumulate(I, 0) + array([[1., 0.], + [1., 1.]]) + >>> np.add.accumulate(I) # no axis specified = axis zero + array([[1., 0.], + [1., 1.]]) + + Accumulate along axis 1 (columns), through rows: + + >>> np.add.accumulate(I, 1) + array([[1., 1.], + [0., 1.]]) + + """)) + +add_newdoc('numpy.core', 'ufunc', ('reduceat', + """ + reduceat(array, indices, axis=0, dtype=None, out=None) + + Performs a (local) reduce with specified slices over a single axis. + + For i in ``range(len(indices))``, `reduceat` computes + ``ufunc.reduce(array[indices[i]:indices[i+1]])``, which becomes the i-th + generalized "row" parallel to `axis` in the final result (i.e., in a + 2-D array, for example, if `axis = 0`, it becomes the i-th row, but if + `axis = 1`, it becomes the i-th column). There are three exceptions to this: + + * when ``i = len(indices) - 1`` (so for the last index), + ``indices[i+1] = array.shape[axis]``. + * if ``indices[i] >= indices[i + 1]``, the i-th generalized "row" is + simply ``array[indices[i]]``. + * if ``indices[i] >= len(array)`` or ``indices[i] < 0``, an error is raised. + + The shape of the output depends on the size of `indices`, and may be + larger than `array` (this happens if ``len(indices) > array.shape[axis]``). + + Parameters + ---------- + array : array_like + The array to act on. + indices : array_like + Paired indices, comma separated (not colon), specifying slices to + reduce. + axis : int, optional + The axis along which to apply the reduceat. + dtype : data-type code, optional + The type used to represent the intermediate results. Defaults + to the data type of the output array if this is provided, or + the data type of the input array if no output array is provided. + out : ndarray, None, or tuple of ndarray and None, optional + A location into which the result is stored. If not provided or None, + a freshly-allocated array is returned. For consistency with + ``ufunc.__call__``, if given as a keyword, this may be wrapped in a + 1-element tuple. + + .. versionchanged:: 1.13.0 + Tuples are allowed for keyword argument. + + Returns + ------- + r : ndarray + The reduced values. If `out` was supplied, `r` is a reference to + `out`. + + Notes + ----- + A descriptive example: + + If `array` is 1-D, the function `ufunc.accumulate(array)` is the same as + ``ufunc.reduceat(array, indices)[::2]`` where `indices` is + ``range(len(array) - 1)`` with a zero placed + in every other element: + ``indices = zeros(2 * len(array) - 1)``, + ``indices[1::2] = range(1, len(array))``. + + Don't be fooled by this attribute's name: `reduceat(array)` is not + necessarily smaller than `array`. + + Examples + -------- + To take the running sum of four successive values: + + >>> np.add.reduceat(np.arange(8),[0,4, 1,5, 2,6, 3,7])[::2] + array([ 6, 10, 14, 18]) + + A 2-D example: + + >>> x = np.linspace(0, 15, 16).reshape(4,4) + >>> x + array([[ 0., 1., 2., 3.], + [ 4., 5., 6., 7.], + [ 8., 9., 10., 11.], + [12., 13., 14., 15.]]) + + :: + + # reduce such that the result has the following five rows: + # [row1 + row2 + row3] + # [row4] + # [row2] + # [row3] + # [row1 + row2 + row3 + row4] + + >>> np.add.reduceat(x, [0, 3, 1, 2, 0]) + array([[12., 15., 18., 21.], + [12., 13., 14., 15.], + [ 4., 5., 6., 7.], + [ 8., 9., 10., 11.], + [24., 28., 32., 36.]]) + + :: + + # reduce such that result has the following two columns: + # [col1 * col2 * col3, col4] + + >>> np.multiply.reduceat(x, [0, 3], 1) + array([[ 0., 3.], + [ 120., 7.], + [ 720., 11.], + [2184., 15.]]) + + """)) + +add_newdoc('numpy.core', 'ufunc', ('outer', + r""" + outer(A, B, /, **kwargs) + + Apply the ufunc `op` to all pairs (a, b) with a in `A` and b in `B`. + + Let ``M = A.ndim``, ``N = B.ndim``. Then the result, `C`, of + ``op.outer(A, B)`` is an array of dimension M + N such that: + + .. math:: C[i_0, ..., i_{M-1}, j_0, ..., j_{N-1}] = + op(A[i_0, ..., i_{M-1}], B[j_0, ..., j_{N-1}]) + + For `A` and `B` one-dimensional, this is equivalent to:: + + r = empty(len(A),len(B)) + for i in range(len(A)): + for j in range(len(B)): + r[i,j] = op(A[i], B[j]) # op = ufunc in question + + Parameters + ---------- + A : array_like + First array + B : array_like + Second array + kwargs : any + Arguments to pass on to the ufunc. Typically `dtype` or `out`. + + Returns + ------- + r : ndarray + Output array + + See Also + -------- + numpy.outer : A less powerful version of ``np.multiply.outer`` + that `ravel`\ s all inputs to 1D. This exists + primarily for compatibility with old code. + + tensordot : ``np.tensordot(a, b, axes=((), ()))`` and + ``np.multiply.outer(a, b)`` behave same for all + dimensions of a and b. + + Examples + -------- + >>> np.multiply.outer([1, 2, 3], [4, 5, 6]) + array([[ 4, 5, 6], + [ 8, 10, 12], + [12, 15, 18]]) + + A multi-dimensional example: + + >>> A = np.array([[1, 2, 3], [4, 5, 6]]) + >>> A.shape + (2, 3) + >>> B = np.array([[1, 2, 3, 4]]) + >>> B.shape + (1, 4) + >>> C = np.multiply.outer(A, B) + >>> C.shape; C + (2, 3, 1, 4) + array([[[[ 1, 2, 3, 4]], + [[ 2, 4, 6, 8]], + [[ 3, 6, 9, 12]]], + [[[ 4, 8, 12, 16]], + [[ 5, 10, 15, 20]], + [[ 6, 12, 18, 24]]]]) + + """)) + +add_newdoc('numpy.core', 'ufunc', ('at', + """ + at(a, indices, b=None, /) + + Performs unbuffered in place operation on operand 'a' for elements + specified by 'indices'. For addition ufunc, this method is equivalent to + ``a[indices] += b``, except that results are accumulated for elements that + are indexed more than once. For example, ``a[[0,0]] += 1`` will only + increment the first element once because of buffering, whereas + ``add.at(a, [0,0], 1)`` will increment the first element twice. + + .. versionadded:: 1.8.0 + + Parameters + ---------- + a : array_like + The array to perform in place operation on. + indices : array_like or tuple + Array like index object or slice object for indexing into first + operand. If first operand has multiple dimensions, indices can be a + tuple of array like index objects or slice objects. + b : array_like + Second operand for ufuncs requiring two operands. Operand must be + broadcastable over first operand after indexing or slicing. + + Examples + -------- + Set items 0 and 1 to their negative values: + + >>> a = np.array([1, 2, 3, 4]) + >>> np.negative.at(a, [0, 1]) + >>> a + array([-1, -2, 3, 4]) + + Increment items 0 and 1, and increment item 2 twice: + + >>> a = np.array([1, 2, 3, 4]) + >>> np.add.at(a, [0, 1, 2, 2], 1) + >>> a + array([2, 3, 5, 4]) + + Add items 0 and 1 in first array to second array, + and store results in first array: + + >>> a = np.array([1, 2, 3, 4]) + >>> b = np.array([1, 2]) + >>> np.add.at(a, [0, 1], b) + >>> a + array([2, 4, 3, 4]) + + """)) + +############################################################################## +# +# Documentation for dtype attributes and methods +# +############################################################################## + +############################################################################## +# +# dtype object +# +############################################################################## + +add_newdoc('numpy.core.multiarray', 'dtype', + """ + dtype(dtype, align=False, copy=False) + + Create a data type object. + + A numpy array is homogeneous, and contains elements described by a + dtype object. A dtype object can be constructed from different + combinations of fundamental numeric types. + + Parameters + ---------- + dtype + Object to be converted to a data type object. + align : bool, optional + Add padding to the fields to match what a C compiler would output + for a similar C-struct. Can be ``True`` only if `obj` is a dictionary + or a comma-separated string. If a struct dtype is being created, + this also sets a sticky alignment flag ``isalignedstruct``. + copy : bool, optional + Make a new copy of the data-type object. If ``False``, the result + may just be a reference to a built-in data-type object. + + See also + -------- + result_type + + Examples + -------- + Using array-scalar type: + + >>> np.dtype(np.int16) + dtype('int16') + + Structured type, one field name 'f1', containing int16: + + >>> np.dtype([('f1', np.int16)]) + dtype([('f1', '>> np.dtype([('f1', [('f1', np.int16)])]) + dtype([('f1', [('f1', '>> np.dtype([('f1', np.uint64), ('f2', np.int32)]) + dtype([('f1', '>> np.dtype([('a','f8'),('b','S10')]) + dtype([('a', '>> np.dtype("i4, (2,3)f8") + dtype([('f0', '>> np.dtype([('hello',(np.int64,3)),('world',np.void,10)]) + dtype([('hello', '>> np.dtype((np.int16, {'x':(np.int8,0), 'y':(np.int8,1)})) + dtype((numpy.int16, [('x', 'i1'), ('y', 'i1')])) + + Using dictionaries. Two fields named 'gender' and 'age': + + >>> np.dtype({'names':['gender','age'], 'formats':['S1',np.uint8]}) + dtype([('gender', 'S1'), ('age', 'u1')]) + + Offsets in bytes, here 0 and 25: + + >>> np.dtype({'surname':('S25',0),'age':(np.uint8,25)}) + dtype([('surname', 'S25'), ('age', 'u1')]) + + """) + +############################################################################## +# +# dtype attributes +# +############################################################################## + +add_newdoc('numpy.core.multiarray', 'dtype', ('alignment', + """ + The required alignment (bytes) of this data-type according to the compiler. + + More information is available in the C-API section of the manual. + + Examples + -------- + + >>> x = np.dtype('i4') + >>> x.alignment + 4 + + >>> x = np.dtype(float) + >>> x.alignment + 8 + + """)) + +add_newdoc('numpy.core.multiarray', 'dtype', ('byteorder', + """ + A character indicating the byte-order of this data-type object. + + One of: + + === ============== + '=' native + '<' little-endian + '>' big-endian + '|' not applicable + === ============== + + All built-in data-type objects have byteorder either '=' or '|'. + + Examples + -------- + + >>> dt = np.dtype('i2') + >>> dt.byteorder + '=' + >>> # endian is not relevant for 8 bit numbers + >>> np.dtype('i1').byteorder + '|' + >>> # or ASCII strings + >>> np.dtype('S2').byteorder + '|' + >>> # Even if specific code is given, and it is native + >>> # '=' is the byteorder + >>> import sys + >>> sys_is_le = sys.byteorder == 'little' + >>> native_code = sys_is_le and '<' or '>' + >>> swapped_code = sys_is_le and '>' or '<' + >>> dt = np.dtype(native_code + 'i2') + >>> dt.byteorder + '=' + >>> # Swapped code shows up as itself + >>> dt = np.dtype(swapped_code + 'i2') + >>> dt.byteorder == swapped_code + True + + """)) + +add_newdoc('numpy.core.multiarray', 'dtype', ('char', + """A unique character code for each of the 21 different built-in types. + + Examples + -------- + + >>> x = np.dtype(float) + >>> x.char + 'd' + + """)) + +add_newdoc('numpy.core.multiarray', 'dtype', ('descr', + """ + `__array_interface__` description of the data-type. + + The format is that required by the 'descr' key in the + `__array_interface__` attribute. + + Warning: This attribute exists specifically for `__array_interface__`, + and passing it directly to `np.dtype` will not accurately reconstruct + some dtypes (e.g., scalar and subarray dtypes). + + Examples + -------- + + >>> x = np.dtype(float) + >>> x.descr + [('', '>> dt = np.dtype([('name', np.str_, 16), ('grades', np.float64, (2,))]) + >>> dt.descr + [('name', '>> dt = np.dtype([('name', np.str_, 16), ('grades', np.float64, (2,))]) + >>> print(dt.fields) + {'grades': (dtype(('float64',(2,))), 16), 'name': (dtype('|S16'), 0)} + + """)) + +add_newdoc('numpy.core.multiarray', 'dtype', ('flags', + """ + Bit-flags describing how this data type is to be interpreted. + + Bit-masks are in `numpy.core.multiarray` as the constants + `ITEM_HASOBJECT`, `LIST_PICKLE`, `ITEM_IS_POINTER`, `NEEDS_INIT`, + `NEEDS_PYAPI`, `USE_GETITEM`, `USE_SETITEM`. A full explanation + of these flags is in C-API documentation; they are largely useful + for user-defined data-types. + + The following example demonstrates that operations on this particular + dtype requires Python C-API. + + Examples + -------- + + >>> x = np.dtype([('a', np.int32, 8), ('b', np.float64, 6)]) + >>> x.flags + 16 + >>> np.core.multiarray.NEEDS_PYAPI + 16 + + """)) + +add_newdoc('numpy.core.multiarray', 'dtype', ('hasobject', + """ + Boolean indicating whether this dtype contains any reference-counted + objects in any fields or sub-dtypes. + + Recall that what is actually in the ndarray memory representing + the Python object is the memory address of that object (a pointer). + Special handling may be required, and this attribute is useful for + distinguishing data types that may contain arbitrary Python objects + and data-types that won't. + + """)) + +add_newdoc('numpy.core.multiarray', 'dtype', ('isbuiltin', + """ + Integer indicating how this dtype relates to the built-in dtypes. + + Read-only. + + = ======================================================================== + 0 if this is a structured array type, with fields + 1 if this is a dtype compiled into numpy (such as ints, floats etc) + 2 if the dtype is for a user-defined numpy type + A user-defined type uses the numpy C-API machinery to extend + numpy to handle a new array type. See + :ref:`user.user-defined-data-types` in the NumPy manual. + = ======================================================================== + + Examples + -------- + >>> dt = np.dtype('i2') + >>> dt.isbuiltin + 1 + >>> dt = np.dtype('f8') + >>> dt.isbuiltin + 1 + >>> dt = np.dtype([('field1', 'f8')]) + >>> dt.isbuiltin + 0 + + """)) + +add_newdoc('numpy.core.multiarray', 'dtype', ('isnative', + """ + Boolean indicating whether the byte order of this dtype is native + to the platform. + + """)) + +add_newdoc('numpy.core.multiarray', 'dtype', ('isalignedstruct', + """ + Boolean indicating whether the dtype is a struct which maintains + field alignment. This flag is sticky, so when combining multiple + structs together, it is preserved and produces new dtypes which + are also aligned. + + """)) + +add_newdoc('numpy.core.multiarray', 'dtype', ('itemsize', + """ + The element size of this data-type object. + + For 18 of the 21 types this number is fixed by the data-type. + For the flexible data-types, this number can be anything. + + Examples + -------- + + >>> arr = np.array([[1, 2], [3, 4]]) + >>> arr.dtype + dtype('int64') + >>> arr.itemsize + 8 + + >>> dt = np.dtype([('name', np.str_, 16), ('grades', np.float64, (2,))]) + >>> dt.itemsize + 80 + + """)) + +add_newdoc('numpy.core.multiarray', 'dtype', ('kind', + """ + A character code (one of 'biufcmMOSUV') identifying the general kind of data. + + = ====================== + b boolean + i signed integer + u unsigned integer + f floating-point + c complex floating-point + m timedelta + M datetime + O object + S (byte-)string + U Unicode + V void + = ====================== + + Examples + -------- + + >>> dt = np.dtype('i4') + >>> dt.kind + 'i' + >>> dt = np.dtype('f8') + >>> dt.kind + 'f' + >>> dt = np.dtype([('field1', 'f8')]) + >>> dt.kind + 'V' + + """)) + +add_newdoc('numpy.core.multiarray', 'dtype', ('metadata', + """ + Either ``None`` or a readonly dictionary of metadata (mappingproxy). + + The metadata field can be set using any dictionary at data-type + creation. NumPy currently has no uniform approach to propagating + metadata; although some array operations preserve it, there is no + guarantee that others will. + + .. warning:: + + Although used in certain projects, this feature was long undocumented + and is not well supported. Some aspects of metadata propagation + are expected to change in the future. + + Examples + -------- + + >>> dt = np.dtype(float, metadata={"key": "value"}) + >>> dt.metadata["key"] + 'value' + >>> arr = np.array([1, 2, 3], dtype=dt) + >>> arr.dtype.metadata + mappingproxy({'key': 'value'}) + + Adding arrays with identical datatypes currently preserves the metadata: + + >>> (arr + arr).dtype.metadata + mappingproxy({'key': 'value'}) + + But if the arrays have different dtype metadata, the metadata may be + dropped: + + >>> dt2 = np.dtype(float, metadata={"key2": "value2"}) + >>> arr2 = np.array([3, 2, 1], dtype=dt2) + >>> (arr + arr2).dtype.metadata is None + True # The metadata field is cleared so None is returned + """)) + +add_newdoc('numpy.core.multiarray', 'dtype', ('name', + """ + A bit-width name for this data-type. + + Un-sized flexible data-type objects do not have this attribute. + + Examples + -------- + + >>> x = np.dtype(float) + >>> x.name + 'float64' + >>> x = np.dtype([('a', np.int32, 8), ('b', np.float64, 6)]) + >>> x.name + 'void640' + + """)) + +add_newdoc('numpy.core.multiarray', 'dtype', ('names', + """ + Ordered list of field names, or ``None`` if there are no fields. + + The names are ordered according to increasing byte offset. This can be + used, for example, to walk through all of the named fields in offset order. + + Examples + -------- + >>> dt = np.dtype([('name', np.str_, 16), ('grades', np.float64, (2,))]) + >>> dt.names + ('name', 'grades') + + """)) + +add_newdoc('numpy.core.multiarray', 'dtype', ('num', + """ + A unique number for each of the 21 different built-in types. + + These are roughly ordered from least-to-most precision. + + Examples + -------- + + >>> dt = np.dtype(str) + >>> dt.num + 19 + + >>> dt = np.dtype(float) + >>> dt.num + 12 + + """)) + +add_newdoc('numpy.core.multiarray', 'dtype', ('shape', + """ + Shape tuple of the sub-array if this data type describes a sub-array, + and ``()`` otherwise. + + Examples + -------- + + >>> dt = np.dtype(('i4', 4)) + >>> dt.shape + (4,) + + >>> dt = np.dtype(('i4', (2, 3))) + >>> dt.shape + (2, 3) + + """)) + +add_newdoc('numpy.core.multiarray', 'dtype', ('ndim', + """ + Number of dimensions of the sub-array if this data type describes a + sub-array, and ``0`` otherwise. + + .. versionadded:: 1.13.0 + + Examples + -------- + >>> x = np.dtype(float) + >>> x.ndim + 0 + + >>> x = np.dtype((float, 8)) + >>> x.ndim + 1 + + >>> x = np.dtype(('i4', (3, 4))) + >>> x.ndim + 2 + + """)) + +add_newdoc('numpy.core.multiarray', 'dtype', ('str', + """The array-protocol typestring of this data-type object.""")) + +add_newdoc('numpy.core.multiarray', 'dtype', ('subdtype', + """ + Tuple ``(item_dtype, shape)`` if this `dtype` describes a sub-array, and + None otherwise. + + The *shape* is the fixed shape of the sub-array described by this + data type, and *item_dtype* the data type of the array. + + If a field whose dtype object has this attribute is retrieved, + then the extra dimensions implied by *shape* are tacked on to + the end of the retrieved array. + + See Also + -------- + dtype.base + + Examples + -------- + >>> x = numpy.dtype('8f') + >>> x.subdtype + (dtype('float32'), (8,)) + + >>> x = numpy.dtype('i2') + >>> x.subdtype + >>> + + """)) + +add_newdoc('numpy.core.multiarray', 'dtype', ('base', + """ + Returns dtype for the base element of the subarrays, + regardless of their dimension or shape. + + See Also + -------- + dtype.subdtype + + Examples + -------- + >>> x = numpy.dtype('8f') + >>> x.base + dtype('float32') + + >>> x = numpy.dtype('i2') + >>> x.base + dtype('int16') + + """)) + +add_newdoc('numpy.core.multiarray', 'dtype', ('type', + """The type object used to instantiate a scalar of this data-type.""")) + +############################################################################## +# +# dtype methods +# +############################################################################## + +add_newdoc('numpy.core.multiarray', 'dtype', ('newbyteorder', + """ + newbyteorder(new_order='S', /) + + Return a new dtype with a different byte order. + + Changes are also made in all fields and sub-arrays of the data type. + + Parameters + ---------- + new_order : string, optional + Byte order to force; a value from the byte order specifications + below. The default value ('S') results in swapping the current + byte order. `new_order` codes can be any of: + + * 'S' - swap dtype from current to opposite endian + * {'<', 'little'} - little endian + * {'>', 'big'} - big endian + * '=' - native order + * {'|', 'I'} - ignore (no change to byte order) + + Returns + ------- + new_dtype : dtype + New dtype object with the given change to the byte order. + + Notes + ----- + Changes are also made in all fields and sub-arrays of the data type. + + Examples + -------- + >>> import sys + >>> sys_is_le = sys.byteorder == 'little' + >>> native_code = sys_is_le and '<' or '>' + >>> swapped_code = sys_is_le and '>' or '<' + >>> native_dt = np.dtype(native_code+'i2') + >>> swapped_dt = np.dtype(swapped_code+'i2') + >>> native_dt.newbyteorder('S') == swapped_dt + True + >>> native_dt.newbyteorder() == swapped_dt + True + >>> native_dt == swapped_dt.newbyteorder('S') + True + >>> native_dt == swapped_dt.newbyteorder('=') + True + >>> native_dt == swapped_dt.newbyteorder('N') + True + >>> native_dt == native_dt.newbyteorder('|') + True + >>> np.dtype('>> np.dtype('>> np.dtype('>i2') == native_dt.newbyteorder('>') + True + >>> np.dtype('>i2') == native_dt.newbyteorder('B') + True + + """)) + + +############################################################################## +# +# Datetime-related Methods +# +############################################################################## + +add_newdoc('numpy.core.multiarray', 'busdaycalendar', + """ + busdaycalendar(weekmask='1111100', holidays=None) + + A business day calendar object that efficiently stores information + defining valid days for the busday family of functions. + + The default valid days are Monday through Friday ("business days"). + A busdaycalendar object can be specified with any set of weekly + valid days, plus an optional "holiday" dates that always will be invalid. + + Once a busdaycalendar object is created, the weekmask and holidays + cannot be modified. + + .. versionadded:: 1.7.0 + + Parameters + ---------- + weekmask : str or array_like of bool, optional + A seven-element array indicating which of Monday through Sunday are + valid days. May be specified as a length-seven list or array, like + [1,1,1,1,1,0,0]; a length-seven string, like '1111100'; or a string + like "Mon Tue Wed Thu Fri", made up of 3-character abbreviations for + weekdays, optionally separated by white space. Valid abbreviations + are: Mon Tue Wed Thu Fri Sat Sun + holidays : array_like of datetime64[D], optional + An array of dates to consider as invalid dates, no matter which + weekday they fall upon. Holiday dates may be specified in any + order, and NaT (not-a-time) dates are ignored. This list is + saved in a normalized form that is suited for fast calculations + of valid days. + + Returns + ------- + out : busdaycalendar + A business day calendar object containing the specified + weekmask and holidays values. + + See Also + -------- + is_busday : Returns a boolean array indicating valid days. + busday_offset : Applies an offset counted in valid days. + busday_count : Counts how many valid days are in a half-open date range. + + Attributes + ---------- + Note: once a busdaycalendar object is created, you cannot modify the + weekmask or holidays. The attributes return copies of internal data. + weekmask : (copy) seven-element array of bool + holidays : (copy) sorted array of datetime64[D] + + Examples + -------- + >>> # Some important days in July + ... bdd = np.busdaycalendar( + ... holidays=['2011-07-01', '2011-07-04', '2011-07-17']) + >>> # Default is Monday to Friday weekdays + ... bdd.weekmask + array([ True, True, True, True, True, False, False]) + >>> # Any holidays already on the weekend are removed + ... bdd.holidays + array(['2011-07-01', '2011-07-04'], dtype='datetime64[D]') + """) + +add_newdoc('numpy.core.multiarray', 'busdaycalendar', ('weekmask', + """A copy of the seven-element boolean mask indicating valid days.""")) + +add_newdoc('numpy.core.multiarray', 'busdaycalendar', ('holidays', + """A copy of the holiday array indicating additional invalid days.""")) + +add_newdoc('numpy.core.multiarray', 'normalize_axis_index', + """ + normalize_axis_index(axis, ndim, msg_prefix=None) + + Normalizes an axis index, `axis`, such that is a valid positive index into + the shape of array with `ndim` dimensions. Raises an AxisError with an + appropriate message if this is not possible. + + Used internally by all axis-checking logic. + + .. versionadded:: 1.13.0 + + Parameters + ---------- + axis : int + The un-normalized index of the axis. Can be negative + ndim : int + The number of dimensions of the array that `axis` should be normalized + against + msg_prefix : str + A prefix to put before the message, typically the name of the argument + + Returns + ------- + normalized_axis : int + The normalized axis index, such that `0 <= normalized_axis < ndim` + + Raises + ------ + AxisError + If the axis index is invalid, when `-ndim <= axis < ndim` is false. + + Examples + -------- + >>> normalize_axis_index(0, ndim=3) + 0 + >>> normalize_axis_index(1, ndim=3) + 1 + >>> normalize_axis_index(-1, ndim=3) + 2 + + >>> normalize_axis_index(3, ndim=3) + Traceback (most recent call last): + ... + AxisError: axis 3 is out of bounds for array of dimension 3 + >>> normalize_axis_index(-4, ndim=3, msg_prefix='axes_arg') + Traceback (most recent call last): + ... + AxisError: axes_arg: axis -4 is out of bounds for array of dimension 3 + """) + +add_newdoc('numpy.core.multiarray', 'datetime_data', + """ + datetime_data(dtype, /) + + Get information about the step size of a date or time type. + + The returned tuple can be passed as the second argument of `numpy.datetime64` and + `numpy.timedelta64`. + + Parameters + ---------- + dtype : dtype + The dtype object, which must be a `datetime64` or `timedelta64` type. + + Returns + ------- + unit : str + The :ref:`datetime unit ` on which this dtype + is based. + count : int + The number of base units in a step. + + Examples + -------- + >>> dt_25s = np.dtype('timedelta64[25s]') + >>> np.datetime_data(dt_25s) + ('s', 25) + >>> np.array(10, dt_25s).astype('timedelta64[s]') + array(250, dtype='timedelta64[s]') + + The result can be used to construct a datetime that uses the same units + as a timedelta + + >>> np.datetime64('2010', np.datetime_data(dt_25s)) + numpy.datetime64('2010-01-01T00:00:00','25s') + """) + + +############################################################################## +# +# Documentation for `generic` attributes and methods +# +############################################################################## + +add_newdoc('numpy.core.numerictypes', 'generic', + """ + Base class for numpy scalar types. + + Class from which most (all?) numpy scalar types are derived. For + consistency, exposes the same API as `ndarray`, despite many + consequent attributes being either "get-only," or completely irrelevant. + This is the class from which it is strongly suggested users should derive + custom scalar types. + + """) + +# Attributes + +def refer_to_array_attribute(attr, method=True): + docstring = """ + Scalar {} identical to the corresponding array attribute. + + Please see `ndarray.{}`. + """ + + return attr, docstring.format("method" if method else "attribute", attr) + + +add_newdoc('numpy.core.numerictypes', 'generic', + refer_to_array_attribute('T', method=False)) + +add_newdoc('numpy.core.numerictypes', 'generic', + refer_to_array_attribute('base', method=False)) + +add_newdoc('numpy.core.numerictypes', 'generic', ('data', + """Pointer to start of data.""")) + +add_newdoc('numpy.core.numerictypes', 'generic', ('dtype', + """Get array data-descriptor.""")) + +add_newdoc('numpy.core.numerictypes', 'generic', ('flags', + """The integer value of flags.""")) + +add_newdoc('numpy.core.numerictypes', 'generic', ('flat', + """A 1-D view of the scalar.""")) + +add_newdoc('numpy.core.numerictypes', 'generic', ('imag', + """The imaginary part of the scalar.""")) + +add_newdoc('numpy.core.numerictypes', 'generic', ('itemsize', + """The length of one element in bytes.""")) + +add_newdoc('numpy.core.numerictypes', 'generic', ('nbytes', + """The length of the scalar in bytes.""")) + +add_newdoc('numpy.core.numerictypes', 'generic', ('ndim', + """The number of array dimensions.""")) + +add_newdoc('numpy.core.numerictypes', 'generic', ('real', + """The real part of the scalar.""")) + +add_newdoc('numpy.core.numerictypes', 'generic', ('shape', + """Tuple of array dimensions.""")) + +add_newdoc('numpy.core.numerictypes', 'generic', ('size', + """The number of elements in the gentype.""")) + +add_newdoc('numpy.core.numerictypes', 'generic', ('strides', + """Tuple of bytes steps in each dimension.""")) + +# Methods + +add_newdoc('numpy.core.numerictypes', 'generic', + refer_to_array_attribute('all')) + +add_newdoc('numpy.core.numerictypes', 'generic', + refer_to_array_attribute('any')) + +add_newdoc('numpy.core.numerictypes', 'generic', + refer_to_array_attribute('argmax')) + +add_newdoc('numpy.core.numerictypes', 'generic', + refer_to_array_attribute('argmin')) + +add_newdoc('numpy.core.numerictypes', 'generic', + refer_to_array_attribute('argsort')) + +add_newdoc('numpy.core.numerictypes', 'generic', + refer_to_array_attribute('astype')) + +add_newdoc('numpy.core.numerictypes', 'generic', + refer_to_array_attribute('byteswap')) + +add_newdoc('numpy.core.numerictypes', 'generic', + refer_to_array_attribute('choose')) + +add_newdoc('numpy.core.numerictypes', 'generic', + refer_to_array_attribute('clip')) + +add_newdoc('numpy.core.numerictypes', 'generic', + refer_to_array_attribute('compress')) + +add_newdoc('numpy.core.numerictypes', 'generic', + refer_to_array_attribute('conjugate')) + +add_newdoc('numpy.core.numerictypes', 'generic', + refer_to_array_attribute('copy')) + +add_newdoc('numpy.core.numerictypes', 'generic', + refer_to_array_attribute('cumprod')) + +add_newdoc('numpy.core.numerictypes', 'generic', + refer_to_array_attribute('cumsum')) + +add_newdoc('numpy.core.numerictypes', 'generic', + refer_to_array_attribute('diagonal')) + +add_newdoc('numpy.core.numerictypes', 'generic', + refer_to_array_attribute('dump')) + +add_newdoc('numpy.core.numerictypes', 'generic', + refer_to_array_attribute('dumps')) + +add_newdoc('numpy.core.numerictypes', 'generic', + refer_to_array_attribute('fill')) + +add_newdoc('numpy.core.numerictypes', 'generic', + refer_to_array_attribute('flatten')) + +add_newdoc('numpy.core.numerictypes', 'generic', + refer_to_array_attribute('getfield')) + +add_newdoc('numpy.core.numerictypes', 'generic', + refer_to_array_attribute('item')) + +add_newdoc('numpy.core.numerictypes', 'generic', + refer_to_array_attribute('itemset')) + +add_newdoc('numpy.core.numerictypes', 'generic', + refer_to_array_attribute('max')) + +add_newdoc('numpy.core.numerictypes', 'generic', + refer_to_array_attribute('mean')) + +add_newdoc('numpy.core.numerictypes', 'generic', + refer_to_array_attribute('min')) + +add_newdoc('numpy.core.numerictypes', 'generic', ('newbyteorder', + """ + newbyteorder(new_order='S', /) + + Return a new `dtype` with a different byte order. + + Changes are also made in all fields and sub-arrays of the data type. + + The `new_order` code can be any from the following: + + * 'S' - swap dtype from current to opposite endian + * {'<', 'little'} - little endian + * {'>', 'big'} - big endian + * '=' - native order + * {'|', 'I'} - ignore (no change to byte order) + + Parameters + ---------- + new_order : str, optional + Byte order to force; a value from the byte order specifications + above. The default value ('S') results in swapping the current + byte order. + + + Returns + ------- + new_dtype : dtype + New `dtype` object with the given change to the byte order. + + """)) + +add_newdoc('numpy.core.numerictypes', 'generic', + refer_to_array_attribute('nonzero')) + +add_newdoc('numpy.core.numerictypes', 'generic', + refer_to_array_attribute('prod')) + +add_newdoc('numpy.core.numerictypes', 'generic', + refer_to_array_attribute('ptp')) + +add_newdoc('numpy.core.numerictypes', 'generic', + refer_to_array_attribute('put')) + +add_newdoc('numpy.core.numerictypes', 'generic', + refer_to_array_attribute('ravel')) + +add_newdoc('numpy.core.numerictypes', 'generic', + refer_to_array_attribute('repeat')) + +add_newdoc('numpy.core.numerictypes', 'generic', + refer_to_array_attribute('reshape')) + +add_newdoc('numpy.core.numerictypes', 'generic', + refer_to_array_attribute('resize')) + +add_newdoc('numpy.core.numerictypes', 'generic', + refer_to_array_attribute('round')) + +add_newdoc('numpy.core.numerictypes', 'generic', + refer_to_array_attribute('searchsorted')) + +add_newdoc('numpy.core.numerictypes', 'generic', + refer_to_array_attribute('setfield')) + +add_newdoc('numpy.core.numerictypes', 'generic', + refer_to_array_attribute('setflags')) + +add_newdoc('numpy.core.numerictypes', 'generic', + refer_to_array_attribute('sort')) + +add_newdoc('numpy.core.numerictypes', 'generic', + refer_to_array_attribute('squeeze')) + +add_newdoc('numpy.core.numerictypes', 'generic', + refer_to_array_attribute('std')) + +add_newdoc('numpy.core.numerictypes', 'generic', + refer_to_array_attribute('sum')) + +add_newdoc('numpy.core.numerictypes', 'generic', + refer_to_array_attribute('swapaxes')) + +add_newdoc('numpy.core.numerictypes', 'generic', + refer_to_array_attribute('take')) + +add_newdoc('numpy.core.numerictypes', 'generic', + refer_to_array_attribute('tofile')) + +add_newdoc('numpy.core.numerictypes', 'generic', + refer_to_array_attribute('tolist')) + +add_newdoc('numpy.core.numerictypes', 'generic', + refer_to_array_attribute('tostring')) + +add_newdoc('numpy.core.numerictypes', 'generic', + refer_to_array_attribute('trace')) + +add_newdoc('numpy.core.numerictypes', 'generic', + refer_to_array_attribute('transpose')) + +add_newdoc('numpy.core.numerictypes', 'generic', + refer_to_array_attribute('var')) + +add_newdoc('numpy.core.numerictypes', 'generic', + refer_to_array_attribute('view')) + + +############################################################################## +# +# Documentation for scalar type abstract base classes in type hierarchy +# +############################################################################## + + +add_newdoc('numpy.core.numerictypes', 'number', + """ + Abstract base class of all numeric scalar types. + + """) + +add_newdoc('numpy.core.numerictypes', 'integer', + """ + Abstract base class of all integer scalar types. + + """) + +add_newdoc('numpy.core.numerictypes', 'signedinteger', + """ + Abstract base class of all signed integer scalar types. + + """) + +add_newdoc('numpy.core.numerictypes', 'unsignedinteger', + """ + Abstract base class of all unsigned integer scalar types. + + """) + +add_newdoc('numpy.core.numerictypes', 'inexact', + """ + Abstract base class of all numeric scalar types with a (potentially) + inexact representation of the values in its range, such as + floating-point numbers. + + """) + +add_newdoc('numpy.core.numerictypes', 'floating', + """ + Abstract base class of all floating-point scalar types. + + """) + +add_newdoc('numpy.core.numerictypes', 'complexfloating', + """ + Abstract base class of all complex number scalar types that are made up of + floating-point numbers. + + """) + +add_newdoc('numpy.core.numerictypes', 'flexible', + """ + Abstract base class of all scalar types without predefined length. + The actual size of these types depends on the specific `np.dtype` + instantiation. + + """) + +add_newdoc('numpy.core.numerictypes', 'character', + """ + Abstract base class of all character string scalar types. + + """) diff --git a/venv/Lib/site-packages/numpy/core/_add_newdocs_scalars.py b/venv/Lib/site-packages/numpy/core/_add_newdocs_scalars.py new file mode 100644 index 0000000..b9b1512 --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/_add_newdocs_scalars.py @@ -0,0 +1,251 @@ +""" +This file is separate from ``_add_newdocs.py`` so that it can be mocked out by +our sphinx ``conf.py`` during doc builds, where we want to avoid showing +platform-dependent information. +""" +from numpy.core import dtype +from numpy.core import numerictypes as _numerictypes +from numpy.core.function_base import add_newdoc + +############################################################################## +# +# Documentation for concrete scalar classes +# +############################################################################## + +def numeric_type_aliases(aliases): + def type_aliases_gen(): + for alias, doc in aliases: + try: + alias_type = getattr(_numerictypes, alias) + except AttributeError: + # The set of aliases that actually exist varies between platforms + pass + else: + yield (alias_type, alias, doc) + return list(type_aliases_gen()) + + +possible_aliases = numeric_type_aliases([ + ('int8', '8-bit signed integer (``-128`` to ``127``)'), + ('int16', '16-bit signed integer (``-32_768`` to ``32_767``)'), + ('int32', '32-bit signed integer (``-2_147_483_648`` to ``2_147_483_647``)'), + ('int64', '64-bit signed integer (``-9_223_372_036_854_775_808`` to ``9_223_372_036_854_775_807``)'), + ('intp', 'Signed integer large enough to fit pointer, compatible with C ``intptr_t``'), + ('uint8', '8-bit unsigned integer (``0`` to ``255``)'), + ('uint16', '16-bit unsigned integer (``0`` to ``65_535``)'), + ('uint32', '32-bit unsigned integer (``0`` to ``4_294_967_295``)'), + ('uint64', '64-bit unsigned integer (``0`` to ``18_446_744_073_709_551_615``)'), + ('uintp', 'Unsigned integer large enough to fit pointer, compatible with C ``uintptr_t``'), + ('float16', '16-bit-precision floating-point number type: sign bit, 5 bits exponent, 10 bits mantissa'), + ('float32', '32-bit-precision floating-point number type: sign bit, 8 bits exponent, 23 bits mantissa'), + ('float64', '64-bit precision floating-point number type: sign bit, 11 bits exponent, 52 bits mantissa'), + ('float96', '96-bit extended-precision floating-point number type'), + ('float128', '128-bit extended-precision floating-point number type'), + ('complex64', 'Complex number type composed of 2 32-bit-precision floating-point numbers'), + ('complex128', 'Complex number type composed of 2 64-bit-precision floating-point numbers'), + ('complex192', 'Complex number type composed of 2 96-bit extended-precision floating-point numbers'), + ('complex256', 'Complex number type composed of 2 128-bit extended-precision floating-point numbers'), + ]) + + +def add_newdoc_for_scalar_type(obj, fixed_aliases, doc): + # note: `:field: value` is rST syntax which renders as field lists. + o = getattr(_numerictypes, obj) + + character_code = dtype(o).char + canonical_name_doc = "" if obj == o.__name__ else ":Canonical name: `numpy.{}`\n ".format(obj) + alias_doc = ''.join(":Alias: `numpy.{}`\n ".format(alias) for alias in fixed_aliases) + alias_doc += ''.join(":Alias on this platform: `numpy.{}`: {}.\n ".format(alias, doc) + for (alias_type, alias, doc) in possible_aliases if alias_type is o) + docstring = """ + {doc} + + :Character code: ``'{character_code}'`` + {canonical_name_doc}{alias_doc} + """.format(doc=doc.strip(), character_code=character_code, + canonical_name_doc=canonical_name_doc, alias_doc=alias_doc) + + add_newdoc('numpy.core.numerictypes', obj, docstring) + + +add_newdoc_for_scalar_type('bool_', ['bool8'], + """ + Boolean type (True or False), stored as a byte. + + .. warning:: + + The :class:`bool_` type is not a subclass of the :class:`int_` type + (the :class:`bool_` is not even a number type). This is different + than Python's default implementation of :class:`bool` as a + sub-class of :class:`int`. + """) + +add_newdoc_for_scalar_type('byte', [], + """ + Signed integer type, compatible with C ``char``. + """) + +add_newdoc_for_scalar_type('short', [], + """ + Signed integer type, compatible with C ``short``. + """) + +add_newdoc_for_scalar_type('intc', [], + """ + Signed integer type, compatible with C ``int``. + """) + +add_newdoc_for_scalar_type('int_', [], + """ + Signed integer type, compatible with Python `int` and C ``long``. + """) + +add_newdoc_for_scalar_type('longlong', [], + """ + Signed integer type, compatible with C ``long long``. + """) + +add_newdoc_for_scalar_type('ubyte', [], + """ + Unsigned integer type, compatible with C ``unsigned char``. + """) + +add_newdoc_for_scalar_type('ushort', [], + """ + Unsigned integer type, compatible with C ``unsigned short``. + """) + +add_newdoc_for_scalar_type('uintc', [], + """ + Unsigned integer type, compatible with C ``unsigned int``. + """) + +add_newdoc_for_scalar_type('uint', [], + """ + Unsigned integer type, compatible with C ``unsigned long``. + """) + +add_newdoc_for_scalar_type('ulonglong', [], + """ + Signed integer type, compatible with C ``unsigned long long``. + """) + +add_newdoc_for_scalar_type('half', [], + """ + Half-precision floating-point number type. + """) + +add_newdoc_for_scalar_type('single', [], + """ + Single-precision floating-point number type, compatible with C ``float``. + """) + +add_newdoc_for_scalar_type('double', ['float_'], + """ + Double-precision floating-point number type, compatible with Python `float` + and C ``double``. + """) + +add_newdoc_for_scalar_type('longdouble', ['longfloat'], + """ + Extended-precision floating-point number type, compatible with C + ``long double`` but not necessarily with IEEE 754 quadruple-precision. + """) + +add_newdoc_for_scalar_type('csingle', ['singlecomplex'], + """ + Complex number type composed of two single-precision floating-point + numbers. + """) + +add_newdoc_for_scalar_type('cdouble', ['cfloat', 'complex_'], + """ + Complex number type composed of two double-precision floating-point + numbers, compatible with Python `complex`. + """) + +add_newdoc_for_scalar_type('clongdouble', ['clongfloat', 'longcomplex'], + """ + Complex number type composed of two extended-precision floating-point + numbers. + """) + +add_newdoc_for_scalar_type('object_', [], + """ + Any Python object. + """) + +add_newdoc_for_scalar_type('str_', ['unicode_'], + r""" + A unicode string. + + When used in arrays, this type strips trailing null codepoints. + + Unlike the builtin `str`, this supports the :ref:`python:bufferobjects`, exposing its + contents as UCS4: + + >>> m = memoryview(np.str_("abc")) + >>> m.format + '3w' + >>> m.tobytes() + b'a\x00\x00\x00b\x00\x00\x00c\x00\x00\x00' + """) + +add_newdoc_for_scalar_type('bytes_', ['string_'], + r""" + A byte string. + + When used in arrays, this type strips trailing null bytes. + """) + +add_newdoc_for_scalar_type('void', [], + r""" + Either an opaque sequence of bytes, or a structure. + + >>> np.void(b'abcd') + void(b'\x61\x62\x63\x64') + + Structured `void` scalars can only be constructed via extraction from :ref:`structured_arrays`: + + >>> arr = np.array((1, 2), dtype=[('x', np.int8), ('y', np.int8)]) + >>> arr[()] + (1, 2) # looks like a tuple, but is `np.void` + """) + +add_newdoc_for_scalar_type('datetime64', [], + """ + A datetime stored as a 64-bit integer, counting from ``1970-01-01T00:00:00``. + + >>> np.datetime64(10, 'Y') + numpy.datetime64('1980') + >>> np.datetime64(10, 'D') + numpy.datetime64('1970-01-11') + + See :ref:`arrays.datetime` for more information. + """) + +add_newdoc_for_scalar_type('timedelta64', [], + """ + A timedelta stored as a 64-bit integer. + + See :ref:`arrays.datetime` for more information. + """) + +# TODO: work out how to put this on the base class, np.floating +for float_name in ('half', 'single', 'double', 'longdouble'): + add_newdoc('numpy.core.numerictypes', float_name, ('as_integer_ratio', + """ + {ftype}.as_integer_ratio() -> (int, int) + + Return a pair of integers, whose ratio is exactly equal to the original + floating point number, and with a positive denominator. + Raise `OverflowError` on infinities and a `ValueError` on NaNs. + + >>> np.{ftype}(10.0).as_integer_ratio() + (10, 1) + >>> np.{ftype}(0.0).as_integer_ratio() + (0, 1) + >>> np.{ftype}(-.25).as_integer_ratio() + (-1, 4) + """.format(ftype=float_name))) diff --git a/venv/Lib/site-packages/numpy/core/_asarray.py b/venv/Lib/site-packages/numpy/core/_asarray.py new file mode 100644 index 0000000..a406308 --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/_asarray.py @@ -0,0 +1,411 @@ +""" +Functions in the ``as*array`` family that promote array-likes into arrays. + +`require` fits this category despite its name not matching this pattern. +""" +from .overrides import ( + array_function_dispatch, + set_array_function_like_doc, + set_module, +) +from .multiarray import array + + +__all__ = [ + "asarray", "asanyarray", "ascontiguousarray", "asfortranarray", "require", +] + + +def _asarray_dispatcher(a, dtype=None, order=None, *, like=None): + return (like,) + + +@set_array_function_like_doc +@set_module('numpy') +def asarray(a, dtype=None, order=None, *, like=None): + """Convert the input to an array. + + Parameters + ---------- + a : array_like + Input data, in any form that can be converted to an array. This + includes lists, lists of tuples, tuples, tuples of tuples, tuples + of lists and ndarrays. + dtype : data-type, optional + By default, the data-type is inferred from the input data. + order : {'C', 'F', 'A', 'K'}, optional + Memory layout. 'A' and 'K' depend on the order of input array a. + 'C' row-major (C-style), + 'F' column-major (Fortran-style) memory representation. + 'A' (any) means 'F' if `a` is Fortran contiguous, 'C' otherwise + 'K' (keep) preserve input order + Defaults to 'C'. + ${ARRAY_FUNCTION_LIKE} + + .. versionadded:: 1.20.0 + + Returns + ------- + out : ndarray + Array interpretation of `a`. No copy is performed if the input + is already an ndarray with matching dtype and order. If `a` is a + subclass of ndarray, a base class ndarray is returned. + + See Also + -------- + asanyarray : Similar function which passes through subclasses. + ascontiguousarray : Convert input to a contiguous array. + asfarray : Convert input to a floating point ndarray. + asfortranarray : Convert input to an ndarray with column-major + memory order. + asarray_chkfinite : Similar function which checks input for NaNs and Infs. + fromiter : Create an array from an iterator. + fromfunction : Construct an array by executing a function on grid + positions. + + Examples + -------- + Convert a list into an array: + + >>> a = [1, 2] + >>> np.asarray(a) + array([1, 2]) + + Existing arrays are not copied: + + >>> a = np.array([1, 2]) + >>> np.asarray(a) is a + True + + If `dtype` is set, array is copied only if dtype does not match: + + >>> a = np.array([1, 2], dtype=np.float32) + >>> np.asarray(a, dtype=np.float32) is a + True + >>> np.asarray(a, dtype=np.float64) is a + False + + Contrary to `asanyarray`, ndarray subclasses are not passed through: + + >>> issubclass(np.recarray, np.ndarray) + True + >>> a = np.array([(1.0, 2), (3.0, 4)], dtype='f4,i4').view(np.recarray) + >>> np.asarray(a) is a + False + >>> np.asanyarray(a) is a + True + + """ + if like is not None: + return _asarray_with_like(a, dtype=dtype, order=order, like=like) + + return array(a, dtype, copy=False, order=order) + + +_asarray_with_like = array_function_dispatch( + _asarray_dispatcher +)(asarray) + + +@set_array_function_like_doc +@set_module('numpy') +def asanyarray(a, dtype=None, order=None, *, like=None): + """Convert the input to an ndarray, but pass ndarray subclasses through. + + Parameters + ---------- + a : array_like + Input data, in any form that can be converted to an array. This + includes scalars, lists, lists of tuples, tuples, tuples of tuples, + tuples of lists, and ndarrays. + dtype : data-type, optional + By default, the data-type is inferred from the input data. + order : {'C', 'F', 'A', 'K'}, optional + Memory layout. 'A' and 'K' depend on the order of input array a. + 'C' row-major (C-style), + 'F' column-major (Fortran-style) memory representation. + 'A' (any) means 'F' if `a` is Fortran contiguous, 'C' otherwise + 'K' (keep) preserve input order + Defaults to 'C'. + ${ARRAY_FUNCTION_LIKE} + + .. versionadded:: 1.20.0 + + Returns + ------- + out : ndarray or an ndarray subclass + Array interpretation of `a`. If `a` is an ndarray or a subclass + of ndarray, it is returned as-is and no copy is performed. + + See Also + -------- + asarray : Similar function which always returns ndarrays. + ascontiguousarray : Convert input to a contiguous array. + asfarray : Convert input to a floating point ndarray. + asfortranarray : Convert input to an ndarray with column-major + memory order. + asarray_chkfinite : Similar function which checks input for NaNs and + Infs. + fromiter : Create an array from an iterator. + fromfunction : Construct an array by executing a function on grid + positions. + + Examples + -------- + Convert a list into an array: + + >>> a = [1, 2] + >>> np.asanyarray(a) + array([1, 2]) + + Instances of `ndarray` subclasses are passed through as-is: + + >>> a = np.array([(1.0, 2), (3.0, 4)], dtype='f4,i4').view(np.recarray) + >>> np.asanyarray(a) is a + True + + """ + if like is not None: + return _asanyarray_with_like(a, dtype=dtype, order=order, like=like) + + return array(a, dtype, copy=False, order=order, subok=True) + + +_asanyarray_with_like = array_function_dispatch( + _asarray_dispatcher +)(asanyarray) + + +def _asarray_contiguous_fortran_dispatcher(a, dtype=None, *, like=None): + return (like,) + + +@set_array_function_like_doc +@set_module('numpy') +def ascontiguousarray(a, dtype=None, *, like=None): + """ + Return a contiguous array (ndim >= 1) in memory (C order). + + Parameters + ---------- + a : array_like + Input array. + dtype : str or dtype object, optional + Data-type of returned array. + ${ARRAY_FUNCTION_LIKE} + + .. versionadded:: 1.20.0 + + Returns + ------- + out : ndarray + Contiguous array of same shape and content as `a`, with type `dtype` + if specified. + + See Also + -------- + asfortranarray : Convert input to an ndarray with column-major + memory order. + require : Return an ndarray that satisfies requirements. + ndarray.flags : Information about the memory layout of the array. + + Examples + -------- + >>> x = np.arange(6).reshape(2,3) + >>> np.ascontiguousarray(x, dtype=np.float32) + array([[0., 1., 2.], + [3., 4., 5.]], dtype=float32) + >>> x.flags['C_CONTIGUOUS'] + True + + Note: This function returns an array with at least one-dimension (1-d) + so it will not preserve 0-d arrays. + + """ + if like is not None: + return _ascontiguousarray_with_like(a, dtype=dtype, like=like) + + return array(a, dtype, copy=False, order='C', ndmin=1) + + +_ascontiguousarray_with_like = array_function_dispatch( + _asarray_contiguous_fortran_dispatcher +)(ascontiguousarray) + + +@set_array_function_like_doc +@set_module('numpy') +def asfortranarray(a, dtype=None, *, like=None): + """ + Return an array (ndim >= 1) laid out in Fortran order in memory. + + Parameters + ---------- + a : array_like + Input array. + dtype : str or dtype object, optional + By default, the data-type is inferred from the input data. + ${ARRAY_FUNCTION_LIKE} + + .. versionadded:: 1.20.0 + + Returns + ------- + out : ndarray + The input `a` in Fortran, or column-major, order. + + See Also + -------- + ascontiguousarray : Convert input to a contiguous (C order) array. + asanyarray : Convert input to an ndarray with either row or + column-major memory order. + require : Return an ndarray that satisfies requirements. + ndarray.flags : Information about the memory layout of the array. + + Examples + -------- + >>> x = np.arange(6).reshape(2,3) + >>> y = np.asfortranarray(x) + >>> x.flags['F_CONTIGUOUS'] + False + >>> y.flags['F_CONTIGUOUS'] + True + + Note: This function returns an array with at least one-dimension (1-d) + so it will not preserve 0-d arrays. + + """ + if like is not None: + return _asfortranarray_with_like(a, dtype=dtype, like=like) + + return array(a, dtype, copy=False, order='F', ndmin=1) + + +_asfortranarray_with_like = array_function_dispatch( + _asarray_contiguous_fortran_dispatcher +)(asfortranarray) + + +def _require_dispatcher(a, dtype=None, requirements=None, *, like=None): + return (like,) + + +@set_array_function_like_doc +@set_module('numpy') +def require(a, dtype=None, requirements=None, *, like=None): + """ + Return an ndarray of the provided type that satisfies requirements. + + This function is useful to be sure that an array with the correct flags + is returned for passing to compiled code (perhaps through ctypes). + + Parameters + ---------- + a : array_like + The object to be converted to a type-and-requirement-satisfying array. + dtype : data-type + The required data-type. If None preserve the current dtype. If your + application requires the data to be in native byteorder, include + a byteorder specification as a part of the dtype specification. + requirements : str or list of str + The requirements list can be any of the following + + * 'F_CONTIGUOUS' ('F') - ensure a Fortran-contiguous array + * 'C_CONTIGUOUS' ('C') - ensure a C-contiguous array + * 'ALIGNED' ('A') - ensure a data-type aligned array + * 'WRITEABLE' ('W') - ensure a writable array + * 'OWNDATA' ('O') - ensure an array that owns its own data + * 'ENSUREARRAY', ('E') - ensure a base array, instead of a subclass + ${ARRAY_FUNCTION_LIKE} + + .. versionadded:: 1.20.0 + + Returns + ------- + out : ndarray + Array with specified requirements and type if given. + + See Also + -------- + asarray : Convert input to an ndarray. + asanyarray : Convert to an ndarray, but pass through ndarray subclasses. + ascontiguousarray : Convert input to a contiguous array. + asfortranarray : Convert input to an ndarray with column-major + memory order. + ndarray.flags : Information about the memory layout of the array. + + Notes + ----- + The returned array will be guaranteed to have the listed requirements + by making a copy if needed. + + Examples + -------- + >>> x = np.arange(6).reshape(2,3) + >>> x.flags + C_CONTIGUOUS : True + F_CONTIGUOUS : False + OWNDATA : False + WRITEABLE : True + ALIGNED : True + WRITEBACKIFCOPY : False + UPDATEIFCOPY : False + + >>> y = np.require(x, dtype=np.float32, requirements=['A', 'O', 'W', 'F']) + >>> y.flags + C_CONTIGUOUS : False + F_CONTIGUOUS : True + OWNDATA : True + WRITEABLE : True + ALIGNED : True + WRITEBACKIFCOPY : False + UPDATEIFCOPY : False + + """ + if like is not None: + return _require_with_like( + a, + dtype=dtype, + requirements=requirements, + like=like, + ) + + possible_flags = {'C': 'C', 'C_CONTIGUOUS': 'C', 'CONTIGUOUS': 'C', + 'F': 'F', 'F_CONTIGUOUS': 'F', 'FORTRAN': 'F', + 'A': 'A', 'ALIGNED': 'A', + 'W': 'W', 'WRITEABLE': 'W', + 'O': 'O', 'OWNDATA': 'O', + 'E': 'E', 'ENSUREARRAY': 'E'} + if not requirements: + return asanyarray(a, dtype=dtype) + else: + requirements = {possible_flags[x.upper()] for x in requirements} + + if 'E' in requirements: + requirements.remove('E') + subok = False + else: + subok = True + + order = 'A' + if requirements >= {'C', 'F'}: + raise ValueError('Cannot specify both "C" and "F" order') + elif 'F' in requirements: + order = 'F' + requirements.remove('F') + elif 'C' in requirements: + order = 'C' + requirements.remove('C') + + arr = array(a, dtype=dtype, order=order, copy=False, subok=subok) + + for prop in requirements: + if not arr.flags[prop]: + arr = arr.copy(order) + break + return arr + + +_require_with_like = array_function_dispatch( + _require_dispatcher +)(require) diff --git a/venv/Lib/site-packages/numpy/core/_asarray.pyi b/venv/Lib/site-packages/numpy/core/_asarray.pyi new file mode 100644 index 0000000..8c200ba --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/_asarray.pyi @@ -0,0 +1,77 @@ +import sys +from typing import TypeVar, Union, Iterable, overload + +from numpy import ndarray, _OrderKACF +from numpy.typing import ArrayLike, DTypeLike + +if sys.version_info >= (3, 8): + from typing import Literal +else: + from typing_extensions import Literal + +_ArrayType = TypeVar("_ArrayType", bound=ndarray) + +def asarray( + a: object, + dtype: DTypeLike = ..., + order: _OrderKACF = ..., + *, + like: ArrayLike = ... +) -> ndarray: ... +@overload +def asanyarray( + a: _ArrayType, + dtype: None = ..., + order: _OrderKACF = ..., + *, + like: ArrayLike = ... +) -> _ArrayType: ... +@overload +def asanyarray( + a: object, + dtype: DTypeLike = ..., + order: _OrderKACF = ..., + *, + like: ArrayLike = ... +) -> ndarray: ... +def ascontiguousarray( + a: object, dtype: DTypeLike = ..., *, like: ArrayLike = ... +) -> ndarray: ... +def asfortranarray( + a: object, dtype: DTypeLike = ..., *, like: ArrayLike = ... +) -> ndarray: ... + +_Requirements = Literal[ + "C", "C_CONTIGUOUS", "CONTIGUOUS", + "F", "F_CONTIGUOUS", "FORTRAN", + "A", "ALIGNED", + "W", "WRITEABLE", + "O", "OWNDATA" +] +_E = Literal["E", "ENSUREARRAY"] +_RequirementsWithE = Union[_Requirements, _E] + +@overload +def require( + a: _ArrayType, + dtype: None = ..., + requirements: Union[None, _Requirements, Iterable[_Requirements]] = ..., + *, + like: ArrayLike = ... +) -> _ArrayType: ... +@overload +def require( + a: object, + dtype: DTypeLike = ..., + requirements: Union[_E, Iterable[_RequirementsWithE]] = ..., + *, + like: ArrayLike = ... +) -> ndarray: ... +@overload +def require( + a: object, + dtype: DTypeLike = ..., + requirements: Union[None, _Requirements, Iterable[_Requirements]] = ..., + *, + like: ArrayLike = ... +) -> ndarray: ... diff --git a/venv/Lib/site-packages/numpy/core/_dtype.py b/venv/Lib/site-packages/numpy/core/_dtype.py new file mode 100644 index 0000000..4249071 --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/_dtype.py @@ -0,0 +1,342 @@ +""" +A place for code to be called from the implementation of np.dtype + +String handling is much easier to do correctly in python. +""" +import numpy as np + + +_kind_to_stem = { + 'u': 'uint', + 'i': 'int', + 'c': 'complex', + 'f': 'float', + 'b': 'bool', + 'V': 'void', + 'O': 'object', + 'M': 'datetime', + 'm': 'timedelta', + 'S': 'bytes', + 'U': 'str', +} + + +def _kind_name(dtype): + try: + return _kind_to_stem[dtype.kind] + except KeyError as e: + raise RuntimeError( + "internal dtype error, unknown kind {!r}" + .format(dtype.kind) + ) from None + + +def __str__(dtype): + if dtype.fields is not None: + return _struct_str(dtype, include_align=True) + elif dtype.subdtype: + return _subarray_str(dtype) + elif issubclass(dtype.type, np.flexible) or not dtype.isnative: + return dtype.str + else: + return dtype.name + + +def __repr__(dtype): + arg_str = _construction_repr(dtype, include_align=False) + if dtype.isalignedstruct: + arg_str = arg_str + ", align=True" + return "dtype({})".format(arg_str) + + +def _unpack_field(dtype, offset, title=None): + """ + Helper function to normalize the items in dtype.fields. + + Call as: + + dtype, offset, title = _unpack_field(*dtype.fields[name]) + """ + return dtype, offset, title + + +def _isunsized(dtype): + # PyDataType_ISUNSIZED + return dtype.itemsize == 0 + + +def _construction_repr(dtype, include_align=False, short=False): + """ + Creates a string repr of the dtype, excluding the 'dtype()' part + surrounding the object. This object may be a string, a list, or + a dict depending on the nature of the dtype. This + is the object passed as the first parameter to the dtype + constructor, and if no additional constructor parameters are + given, will reproduce the exact memory layout. + + Parameters + ---------- + short : bool + If true, this creates a shorter repr using 'kind' and 'itemsize', instead + of the longer type name. + + include_align : bool + If true, this includes the 'align=True' parameter + inside the struct dtype construction dict when needed. Use this flag + if you want a proper repr string without the 'dtype()' part around it. + + If false, this does not preserve the + 'align=True' parameter or sticky NPY_ALIGNED_STRUCT flag for + struct arrays like the regular repr does, because the 'align' + flag is not part of first dtype constructor parameter. This + mode is intended for a full 'repr', where the 'align=True' is + provided as the second parameter. + """ + if dtype.fields is not None: + return _struct_str(dtype, include_align=include_align) + elif dtype.subdtype: + return _subarray_str(dtype) + else: + return _scalar_str(dtype, short=short) + + +def _scalar_str(dtype, short): + byteorder = _byte_order_str(dtype) + + if dtype.type == np.bool_: + if short: + return "'?'" + else: + return "'bool'" + + elif dtype.type == np.object_: + # The object reference may be different sizes on different + # platforms, so it should never include the itemsize here. + return "'O'" + + elif dtype.type == np.string_: + if _isunsized(dtype): + return "'S'" + else: + return "'S%d'" % dtype.itemsize + + elif dtype.type == np.unicode_: + if _isunsized(dtype): + return "'%sU'" % byteorder + else: + return "'%sU%d'" % (byteorder, dtype.itemsize / 4) + + # unlike the other types, subclasses of void are preserved - but + # historically the repr does not actually reveal the subclass + elif issubclass(dtype.type, np.void): + if _isunsized(dtype): + return "'V'" + else: + return "'V%d'" % dtype.itemsize + + elif dtype.type == np.datetime64: + return "'%sM8%s'" % (byteorder, _datetime_metadata_str(dtype)) + + elif dtype.type == np.timedelta64: + return "'%sm8%s'" % (byteorder, _datetime_metadata_str(dtype)) + + elif np.issubdtype(dtype, np.number): + # Short repr with endianness, like '' """ + # hack to obtain the native and swapped byte order characters + swapped = np.dtype(int).newbyteorder('S') + native = swapped.newbyteorder('S') + + byteorder = dtype.byteorder + if byteorder == '=': + return native.byteorder + if byteorder == 'S': + # TODO: this path can never be reached + return swapped.byteorder + elif byteorder == '|': + return '' + else: + return byteorder + + +def _datetime_metadata_str(dtype): + # TODO: this duplicates the C metastr_to_unicode functionality + unit, count = np.datetime_data(dtype) + if unit == 'generic': + return '' + elif count == 1: + return '[{}]'.format(unit) + else: + return '[{}{}]'.format(count, unit) + + +def _struct_dict_str(dtype, includealignedflag): + # unpack the fields dictionary into ls + names = dtype.names + fld_dtypes = [] + offsets = [] + titles = [] + for name in names: + fld_dtype, offset, title = _unpack_field(*dtype.fields[name]) + fld_dtypes.append(fld_dtype) + offsets.append(offset) + titles.append(title) + + # Build up a string to make the dictionary + + # First, the names + ret = "{'names':[" + ret += ",".join(repr(name) for name in names) + + # Second, the formats + ret += "], 'formats':[" + ret += ",".join( + _construction_repr(fld_dtype, short=True) for fld_dtype in fld_dtypes) + + # Third, the offsets + ret += "], 'offsets':[" + ret += ",".join("%d" % offset for offset in offsets) + + # Fourth, the titles + if any(title is not None for title in titles): + ret += "], 'titles':[" + ret += ",".join(repr(title) for title in titles) + + # Fifth, the itemsize + ret += "], 'itemsize':%d" % dtype.itemsize + + if (includealignedflag and dtype.isalignedstruct): + # Finally, the aligned flag + ret += ", 'aligned':True}" + else: + ret += "}" + + return ret + + +def _is_packed(dtype): + """ + Checks whether the structured data type in 'dtype' + has a simple layout, where all the fields are in order, + and follow each other with no alignment padding. + + When this returns true, the dtype can be reconstructed + from a list of the field names and dtypes with no additional + dtype parameters. + + Duplicates the C `is_dtype_struct_simple_unaligned_layout` function. + """ + total_offset = 0 + for name in dtype.names: + fld_dtype, fld_offset, title = _unpack_field(*dtype.fields[name]) + if fld_offset != total_offset: + return False + total_offset += fld_dtype.itemsize + if total_offset != dtype.itemsize: + return False + return True + + +def _struct_list_str(dtype): + items = [] + for name in dtype.names: + fld_dtype, fld_offset, title = _unpack_field(*dtype.fields[name]) + + item = "(" + if title is not None: + item += "({!r}, {!r}), ".format(title, name) + else: + item += "{!r}, ".format(name) + # Special case subarray handling here + if fld_dtype.subdtype is not None: + base, shape = fld_dtype.subdtype + item += "{}, {}".format( + _construction_repr(base, short=True), + shape + ) + else: + item += _construction_repr(fld_dtype, short=True) + + item += ")" + items.append(item) + + return "[" + ", ".join(items) + "]" + + +def _struct_str(dtype, include_align): + # The list str representation can't include the 'align=' flag, + # so if it is requested and the struct has the aligned flag set, + # we must use the dict str instead. + if not (include_align and dtype.isalignedstruct) and _is_packed(dtype): + sub = _struct_list_str(dtype) + + else: + sub = _struct_dict_str(dtype, include_align) + + # If the data type isn't the default, void, show it + if dtype.type != np.void: + return "({t.__module__}.{t.__name__}, {f})".format(t=dtype.type, f=sub) + else: + return sub + + +def _subarray_str(dtype): + base, shape = dtype.subdtype + return "({}, {})".format( + _construction_repr(base, short=True), + shape + ) + + +def _name_includes_bit_suffix(dtype): + if dtype.type == np.object_: + # pointer size varies by system, best to omit it + return False + elif dtype.type == np.bool_: + # implied + return False + elif np.issubdtype(dtype, np.flexible) and _isunsized(dtype): + # unspecified + return False + else: + return True + + +def _name_get(dtype): + # provides dtype.name.__get__, documented as returning a "bit name" + + if dtype.isbuiltin == 2: + # user dtypes don't promise to do anything special + return dtype.type.__name__ + + if issubclass(dtype.type, np.void): + # historically, void subclasses preserve their name, eg `record64` + name = dtype.type.__name__ + else: + name = _kind_name(dtype) + + # append bit counts + if _name_includes_bit_suffix(dtype): + name += "{}".format(dtype.itemsize * 8) + + # append metadata to datetimes + if dtype.type in (np.datetime64, np.timedelta64): + name += _datetime_metadata_str(dtype) + + return name diff --git a/venv/Lib/site-packages/numpy/core/_dtype_ctypes.py b/venv/Lib/site-packages/numpy/core/_dtype_ctypes.py new file mode 100644 index 0000000..6d7cbb2 --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/_dtype_ctypes.py @@ -0,0 +1,117 @@ +""" +Conversion from ctypes to dtype. + +In an ideal world, we could achieve this through the PEP3118 buffer protocol, +something like:: + + def dtype_from_ctypes_type(t): + # needed to ensure that the shape of `t` is within memoryview.format + class DummyStruct(ctypes.Structure): + _fields_ = [('a', t)] + + # empty to avoid memory allocation + ctype_0 = (DummyStruct * 0)() + mv = memoryview(ctype_0) + + # convert the struct, and slice back out the field + return _dtype_from_pep3118(mv.format)['a'] + +Unfortunately, this fails because: + +* ctypes cannot handle length-0 arrays with PEP3118 (bpo-32782) +* PEP3118 cannot represent unions, but both numpy and ctypes can +* ctypes cannot handle big-endian structs with PEP3118 (bpo-32780) +""" + +# We delay-import ctypes for distributions that do not include it. +# While this module is not used unless the user passes in ctypes +# members, it is eagerly imported from numpy/core/__init__.py. +import numpy as np + + +def _from_ctypes_array(t): + return np.dtype((dtype_from_ctypes_type(t._type_), (t._length_,))) + + +def _from_ctypes_structure(t): + for item in t._fields_: + if len(item) > 2: + raise TypeError( + "ctypes bitfields have no dtype equivalent") + + if hasattr(t, "_pack_"): + import ctypes + formats = [] + offsets = [] + names = [] + current_offset = 0 + for fname, ftyp in t._fields_: + names.append(fname) + formats.append(dtype_from_ctypes_type(ftyp)) + # Each type has a default offset, this is platform dependent for some types. + effective_pack = min(t._pack_, ctypes.alignment(ftyp)) + current_offset = ((current_offset + effective_pack - 1) // effective_pack) * effective_pack + offsets.append(current_offset) + current_offset += ctypes.sizeof(ftyp) + + return np.dtype(dict( + formats=formats, + offsets=offsets, + names=names, + itemsize=ctypes.sizeof(t))) + else: + fields = [] + for fname, ftyp in t._fields_: + fields.append((fname, dtype_from_ctypes_type(ftyp))) + + # by default, ctypes structs are aligned + return np.dtype(fields, align=True) + + +def _from_ctypes_scalar(t): + """ + Return the dtype type with endianness included if it's the case + """ + if getattr(t, '__ctype_be__', None) is t: + return np.dtype('>' + t._type_) + elif getattr(t, '__ctype_le__', None) is t: + return np.dtype('<' + t._type_) + else: + return np.dtype(t._type_) + + +def _from_ctypes_union(t): + import ctypes + formats = [] + offsets = [] + names = [] + for fname, ftyp in t._fields_: + names.append(fname) + formats.append(dtype_from_ctypes_type(ftyp)) + offsets.append(0) # Union fields are offset to 0 + + return np.dtype(dict( + formats=formats, + offsets=offsets, + names=names, + itemsize=ctypes.sizeof(t))) + + +def dtype_from_ctypes_type(t): + """ + Construct a dtype object from a ctypes type + """ + import _ctypes + if issubclass(t, _ctypes.Array): + return _from_ctypes_array(t) + elif issubclass(t, _ctypes._Pointer): + raise TypeError("ctypes pointers have no dtype equivalent") + elif issubclass(t, _ctypes.Structure): + return _from_ctypes_structure(t) + elif issubclass(t, _ctypes.Union): + return _from_ctypes_union(t) + elif isinstance(getattr(t, '_type_', None), str): + return _from_ctypes_scalar(t) + else: + raise NotImplementedError( + "Unknown ctypes type {}".format(t.__name__)) diff --git a/venv/Lib/site-packages/numpy/core/_exceptions.py b/venv/Lib/site-packages/numpy/core/_exceptions.py new file mode 100644 index 0000000..5e17ed3 --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/_exceptions.py @@ -0,0 +1,197 @@ +""" +Various richly-typed exceptions, that also help us deal with string formatting +in python where it's easier. + +By putting the formatting in `__str__`, we also avoid paying the cost for +users who silence the exceptions. +""" +from numpy.core.overrides import set_module + +def _unpack_tuple(tup): + if len(tup) == 1: + return tup[0] + else: + return tup + + +def _display_as_base(cls): + """ + A decorator that makes an exception class look like its base. + + We use this to hide subclasses that are implementation details - the user + should catch the base type, which is what the traceback will show them. + + Classes decorated with this decorator are subject to removal without a + deprecation warning. + """ + assert issubclass(cls, Exception) + cls.__name__ = cls.__base__.__name__ + return cls + + +class UFuncTypeError(TypeError): + """ Base class for all ufunc exceptions """ + def __init__(self, ufunc): + self.ufunc = ufunc + + +@_display_as_base +class _UFuncBinaryResolutionError(UFuncTypeError): + """ Thrown when a binary resolution fails """ + def __init__(self, ufunc, dtypes): + super().__init__(ufunc) + self.dtypes = tuple(dtypes) + assert len(self.dtypes) == 2 + + def __str__(self): + return ( + "ufunc {!r} cannot use operands with types {!r} and {!r}" + ).format( + self.ufunc.__name__, *self.dtypes + ) + + +@_display_as_base +class _UFuncNoLoopError(UFuncTypeError): + """ Thrown when a ufunc loop cannot be found """ + def __init__(self, ufunc, dtypes): + super().__init__(ufunc) + self.dtypes = tuple(dtypes) + + def __str__(self): + return ( + "ufunc {!r} did not contain a loop with signature matching types " + "{!r} -> {!r}" + ).format( + self.ufunc.__name__, + _unpack_tuple(self.dtypes[:self.ufunc.nin]), + _unpack_tuple(self.dtypes[self.ufunc.nin:]) + ) + + +@_display_as_base +class _UFuncCastingError(UFuncTypeError): + def __init__(self, ufunc, casting, from_, to): + super().__init__(ufunc) + self.casting = casting + self.from_ = from_ + self.to = to + + +@_display_as_base +class _UFuncInputCastingError(_UFuncCastingError): + """ Thrown when a ufunc input cannot be casted """ + def __init__(self, ufunc, casting, from_, to, i): + super().__init__(ufunc, casting, from_, to) + self.in_i = i + + def __str__(self): + # only show the number if more than one input exists + i_str = "{} ".format(self.in_i) if self.ufunc.nin != 1 else "" + return ( + "Cannot cast ufunc {!r} input {}from {!r} to {!r} with casting " + "rule {!r}" + ).format( + self.ufunc.__name__, i_str, self.from_, self.to, self.casting + ) + + +@_display_as_base +class _UFuncOutputCastingError(_UFuncCastingError): + """ Thrown when a ufunc output cannot be casted """ + def __init__(self, ufunc, casting, from_, to, i): + super().__init__(ufunc, casting, from_, to) + self.out_i = i + + def __str__(self): + # only show the number if more than one output exists + i_str = "{} ".format(self.out_i) if self.ufunc.nout != 1 else "" + return ( + "Cannot cast ufunc {!r} output {}from {!r} to {!r} with casting " + "rule {!r}" + ).format( + self.ufunc.__name__, i_str, self.from_, self.to, self.casting + ) + + +# Exception used in shares_memory() +@set_module('numpy') +class TooHardError(RuntimeError): + pass + + +@set_module('numpy') +class AxisError(ValueError, IndexError): + """ Axis supplied was invalid. """ + def __init__(self, axis, ndim=None, msg_prefix=None): + # single-argument form just delegates to base class + if ndim is None and msg_prefix is None: + msg = axis + + # do the string formatting here, to save work in the C code + else: + msg = ("axis {} is out of bounds for array of dimension {}" + .format(axis, ndim)) + if msg_prefix is not None: + msg = "{}: {}".format(msg_prefix, msg) + + super(AxisError, self).__init__(msg) + + +@_display_as_base +class _ArrayMemoryError(MemoryError): + """ Thrown when an array cannot be allocated""" + def __init__(self, shape, dtype): + self.shape = shape + self.dtype = dtype + + @property + def _total_size(self): + num_bytes = self.dtype.itemsize + for dim in self.shape: + num_bytes *= dim + return num_bytes + + @staticmethod + def _size_to_string(num_bytes): + """ Convert a number of bytes into a binary size string """ + + # https://en.wikipedia.org/wiki/Binary_prefix + LOG2_STEP = 10 + STEP = 1024 + units = ['bytes', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB'] + + unit_i = max(num_bytes.bit_length() - 1, 1) // LOG2_STEP + unit_val = 1 << (unit_i * LOG2_STEP) + n_units = num_bytes / unit_val + del unit_val + + # ensure we pick a unit that is correct after rounding + if round(n_units) == STEP: + unit_i += 1 + n_units /= STEP + + # deal with sizes so large that we don't have units for them + if unit_i >= len(units): + new_unit_i = len(units) - 1 + n_units *= 1 << ((unit_i - new_unit_i) * LOG2_STEP) + unit_i = new_unit_i + + unit_name = units[unit_i] + # format with a sensible number of digits + if unit_i == 0: + # no decimal point on bytes + return '{:.0f} {}'.format(n_units, unit_name) + elif round(n_units) < 1000: + # 3 significant figures, if none are dropped to the left of the . + return '{:#.3g} {}'.format(n_units, unit_name) + else: + # just give all the digits otherwise + return '{:#.0f} {}'.format(n_units, unit_name) + + def __str__(self): + size_str = self._size_to_string(self._total_size) + return ( + "Unable to allocate {} for an array with shape {} and data type {}" + .format(size_str, self.shape, self.dtype) + ) diff --git a/venv/Lib/site-packages/numpy/core/_internal.py b/venv/Lib/site-packages/numpy/core/_internal.py new file mode 100644 index 0000000..449926f --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/_internal.py @@ -0,0 +1,873 @@ +""" +A place for internal code + +Some things are more easily handled Python. + +""" +import ast +import re +import sys +import platform + +from .multiarray import dtype, array, ndarray +try: + import ctypes +except ImportError: + ctypes = None + +IS_PYPY = platform.python_implementation() == 'PyPy' + +if sys.byteorder == 'little': + _nbo = '<' +else: + _nbo = '>' + +def _makenames_list(adict, align): + allfields = [] + + for fname, obj in adict.items(): + n = len(obj) + if not isinstance(obj, tuple) or n not in (2, 3): + raise ValueError("entry not a 2- or 3- tuple") + if n > 2 and obj[2] == fname: + continue + num = int(obj[1]) + if num < 0: + raise ValueError("invalid offset.") + format = dtype(obj[0], align=align) + if n > 2: + title = obj[2] + else: + title = None + allfields.append((fname, format, num, title)) + # sort by offsets + allfields.sort(key=lambda x: x[2]) + names = [x[0] for x in allfields] + formats = [x[1] for x in allfields] + offsets = [x[2] for x in allfields] + titles = [x[3] for x in allfields] + + return names, formats, offsets, titles + +# Called in PyArray_DescrConverter function when +# a dictionary without "names" and "formats" +# fields is used as a data-type descriptor. +def _usefields(adict, align): + try: + names = adict[-1] + except KeyError: + names = None + if names is None: + names, formats, offsets, titles = _makenames_list(adict, align) + else: + formats = [] + offsets = [] + titles = [] + for name in names: + res = adict[name] + formats.append(res[0]) + offsets.append(res[1]) + if len(res) > 2: + titles.append(res[2]) + else: + titles.append(None) + + return dtype({"names": names, + "formats": formats, + "offsets": offsets, + "titles": titles}, align) + + +# construct an array_protocol descriptor list +# from the fields attribute of a descriptor +# This calls itself recursively but should eventually hit +# a descriptor that has no fields and then return +# a simple typestring + +def _array_descr(descriptor): + fields = descriptor.fields + if fields is None: + subdtype = descriptor.subdtype + if subdtype is None: + if descriptor.metadata is None: + return descriptor.str + else: + new = descriptor.metadata.copy() + if new: + return (descriptor.str, new) + else: + return descriptor.str + else: + return (_array_descr(subdtype[0]), subdtype[1]) + + names = descriptor.names + ordered_fields = [fields[x] + (x,) for x in names] + result = [] + offset = 0 + for field in ordered_fields: + if field[1] > offset: + num = field[1] - offset + result.append(('', f'|V{num}')) + offset += num + elif field[1] < offset: + raise ValueError( + "dtype.descr is not defined for types with overlapping or " + "out-of-order fields") + if len(field) > 3: + name = (field[2], field[3]) + else: + name = field[2] + if field[0].subdtype: + tup = (name, _array_descr(field[0].subdtype[0]), + field[0].subdtype[1]) + else: + tup = (name, _array_descr(field[0])) + offset += field[0].itemsize + result.append(tup) + + if descriptor.itemsize > offset: + num = descriptor.itemsize - offset + result.append(('', f'|V{num}')) + + return result + +# Build a new array from the information in a pickle. +# Note that the name numpy.core._internal._reconstruct is embedded in +# pickles of ndarrays made with NumPy before release 1.0 +# so don't remove the name here, or you'll +# break backward compatibility. +def _reconstruct(subtype, shape, dtype): + return ndarray.__new__(subtype, shape, dtype) + + +# format_re was originally from numarray by J. Todd Miller + +format_re = re.compile(r'(?P[<>|=]?)' + r'(?P *[(]?[ ,0-9]*[)]? *)' + r'(?P[<>|=]?)' + r'(?P[A-Za-z0-9.?]*(?:\[[a-zA-Z0-9,.]+\])?)') +sep_re = re.compile(r'\s*,\s*') +space_re = re.compile(r'\s+$') + +# astr is a string (perhaps comma separated) + +_convorder = {'=': _nbo} + +def _commastring(astr): + startindex = 0 + result = [] + while startindex < len(astr): + mo = format_re.match(astr, pos=startindex) + try: + (order1, repeats, order2, dtype) = mo.groups() + except (TypeError, AttributeError): + raise ValueError( + f'format number {len(result)+1} of "{astr}" is not recognized' + ) from None + startindex = mo.end() + # Separator or ending padding + if startindex < len(astr): + if space_re.match(astr, pos=startindex): + startindex = len(astr) + else: + mo = sep_re.match(astr, pos=startindex) + if not mo: + raise ValueError( + 'format number %d of "%s" is not recognized' % + (len(result)+1, astr)) + startindex = mo.end() + + if order2 == '': + order = order1 + elif order1 == '': + order = order2 + else: + order1 = _convorder.get(order1, order1) + order2 = _convorder.get(order2, order2) + if (order1 != order2): + raise ValueError( + 'inconsistent byte-order specification %s and %s' % + (order1, order2)) + order = order1 + + if order in ('|', '=', _nbo): + order = '' + dtype = order + dtype + if (repeats == ''): + newitem = dtype + else: + newitem = (dtype, ast.literal_eval(repeats)) + result.append(newitem) + + return result + +class dummy_ctype: + def __init__(self, cls): + self._cls = cls + def __mul__(self, other): + return self + def __call__(self, *other): + return self._cls(other) + def __eq__(self, other): + return self._cls == other._cls + def __ne__(self, other): + return self._cls != other._cls + +def _getintp_ctype(): + val = _getintp_ctype.cache + if val is not None: + return val + if ctypes is None: + import numpy as np + val = dummy_ctype(np.intp) + else: + char = dtype('p').char + if char == 'i': + val = ctypes.c_int + elif char == 'l': + val = ctypes.c_long + elif char == 'q': + val = ctypes.c_longlong + else: + val = ctypes.c_long + _getintp_ctype.cache = val + return val +_getintp_ctype.cache = None + +# Used for .ctypes attribute of ndarray + +class _missing_ctypes: + def cast(self, num, obj): + return num.value + + class c_void_p: + def __init__(self, ptr): + self.value = ptr + + +class _ctypes: + def __init__(self, array, ptr=None): + self._arr = array + + if ctypes: + self._ctypes = ctypes + self._data = self._ctypes.c_void_p(ptr) + else: + # fake a pointer-like object that holds onto the reference + self._ctypes = _missing_ctypes() + self._data = self._ctypes.c_void_p(ptr) + self._data._objects = array + + if self._arr.ndim == 0: + self._zerod = True + else: + self._zerod = False + + def data_as(self, obj): + """ + Return the data pointer cast to a particular c-types object. + For example, calling ``self._as_parameter_`` is equivalent to + ``self.data_as(ctypes.c_void_p)``. Perhaps you want to use the data as a + pointer to a ctypes array of floating-point data: + ``self.data_as(ctypes.POINTER(ctypes.c_double))``. + + The returned pointer will keep a reference to the array. + """ + # _ctypes.cast function causes a circular reference of self._data in + # self._data._objects. Attributes of self._data cannot be released + # until gc.collect is called. Make a copy of the pointer first then let + # it hold the array reference. This is a workaround to circumvent the + # CPython bug https://bugs.python.org/issue12836 + ptr = self._ctypes.cast(self._data, obj) + ptr._arr = self._arr + return ptr + + def shape_as(self, obj): + """ + Return the shape tuple as an array of some other c-types + type. For example: ``self.shape_as(ctypes.c_short)``. + """ + if self._zerod: + return None + return (obj*self._arr.ndim)(*self._arr.shape) + + def strides_as(self, obj): + """ + Return the strides tuple as an array of some other + c-types type. For example: ``self.strides_as(ctypes.c_longlong)``. + """ + if self._zerod: + return None + return (obj*self._arr.ndim)(*self._arr.strides) + + @property + def data(self): + """ + A pointer to the memory area of the array as a Python integer. + This memory area may contain data that is not aligned, or not in correct + byte-order. The memory area may not even be writeable. The array + flags and data-type of this array should be respected when passing this + attribute to arbitrary C-code to avoid trouble that can include Python + crashing. User Beware! The value of this attribute is exactly the same + as ``self._array_interface_['data'][0]``. + + Note that unlike ``data_as``, a reference will not be kept to the array: + code like ``ctypes.c_void_p((a + b).ctypes.data)`` will result in a + pointer to a deallocated array, and should be spelt + ``(a + b).ctypes.data_as(ctypes.c_void_p)`` + """ + return self._data.value + + @property + def shape(self): + """ + (c_intp*self.ndim): A ctypes array of length self.ndim where + the basetype is the C-integer corresponding to ``dtype('p')`` on this + platform. This base-type could be `ctypes.c_int`, `ctypes.c_long`, or + `ctypes.c_longlong` depending on the platform. + The c_intp type is defined accordingly in `numpy.ctypeslib`. + The ctypes array contains the shape of the underlying array. + """ + return self.shape_as(_getintp_ctype()) + + @property + def strides(self): + """ + (c_intp*self.ndim): A ctypes array of length self.ndim where + the basetype is the same as for the shape attribute. This ctypes array + contains the strides information from the underlying array. This strides + information is important for showing how many bytes must be jumped to + get to the next element in the array. + """ + return self.strides_as(_getintp_ctype()) + + @property + def _as_parameter_(self): + """ + Overrides the ctypes semi-magic method + + Enables `c_func(some_array.ctypes)` + """ + return self.data_as(ctypes.c_void_p) + + # kept for compatibility + get_data = data.fget + get_shape = shape.fget + get_strides = strides.fget + get_as_parameter = _as_parameter_.fget + + +def _newnames(datatype, order): + """ + Given a datatype and an order object, return a new names tuple, with the + order indicated + """ + oldnames = datatype.names + nameslist = list(oldnames) + if isinstance(order, str): + order = [order] + seen = set() + if isinstance(order, (list, tuple)): + for name in order: + try: + nameslist.remove(name) + except ValueError: + if name in seen: + raise ValueError(f"duplicate field name: {name}") from None + else: + raise ValueError(f"unknown field name: {name}") from None + seen.add(name) + return tuple(list(order) + nameslist) + raise ValueError(f"unsupported order value: {order}") + +def _copy_fields(ary): + """Return copy of structured array with padding between fields removed. + + Parameters + ---------- + ary : ndarray + Structured array from which to remove padding bytes + + Returns + ------- + ary_copy : ndarray + Copy of ary with padding bytes removed + """ + dt = ary.dtype + copy_dtype = {'names': dt.names, + 'formats': [dt.fields[name][0] for name in dt.names]} + return array(ary, dtype=copy_dtype, copy=True) + +def _getfield_is_safe(oldtype, newtype, offset): + """ Checks safety of getfield for object arrays. + + As in _view_is_safe, we need to check that memory containing objects is not + reinterpreted as a non-object datatype and vice versa. + + Parameters + ---------- + oldtype : data-type + Data type of the original ndarray. + newtype : data-type + Data type of the field being accessed by ndarray.getfield + offset : int + Offset of the field being accessed by ndarray.getfield + + Raises + ------ + TypeError + If the field access is invalid + + """ + if newtype.hasobject or oldtype.hasobject: + if offset == 0 and newtype == oldtype: + return + if oldtype.names is not None: + for name in oldtype.names: + if (oldtype.fields[name][1] == offset and + oldtype.fields[name][0] == newtype): + return + raise TypeError("Cannot get/set field of an object array") + return + +def _view_is_safe(oldtype, newtype): + """ Checks safety of a view involving object arrays, for example when + doing:: + + np.zeros(10, dtype=oldtype).view(newtype) + + Parameters + ---------- + oldtype : data-type + Data type of original ndarray + newtype : data-type + Data type of the view + + Raises + ------ + TypeError + If the new type is incompatible with the old type. + + """ + + # if the types are equivalent, there is no problem. + # for example: dtype((np.record, 'i4,i4')) == dtype((np.void, 'i4,i4')) + if oldtype == newtype: + return + + if newtype.hasobject or oldtype.hasobject: + raise TypeError("Cannot change data-type for object array.") + return + +# Given a string containing a PEP 3118 format specifier, +# construct a NumPy dtype + +_pep3118_native_map = { + '?': '?', + 'c': 'S1', + 'b': 'b', + 'B': 'B', + 'h': 'h', + 'H': 'H', + 'i': 'i', + 'I': 'I', + 'l': 'l', + 'L': 'L', + 'q': 'q', + 'Q': 'Q', + 'e': 'e', + 'f': 'f', + 'd': 'd', + 'g': 'g', + 'Zf': 'F', + 'Zd': 'D', + 'Zg': 'G', + 's': 'S', + 'w': 'U', + 'O': 'O', + 'x': 'V', # padding +} +_pep3118_native_typechars = ''.join(_pep3118_native_map.keys()) + +_pep3118_standard_map = { + '?': '?', + 'c': 'S1', + 'b': 'b', + 'B': 'B', + 'h': 'i2', + 'H': 'u2', + 'i': 'i4', + 'I': 'u4', + 'l': 'i4', + 'L': 'u4', + 'q': 'i8', + 'Q': 'u8', + 'e': 'f2', + 'f': 'f', + 'd': 'd', + 'Zf': 'F', + 'Zd': 'D', + 's': 'S', + 'w': 'U', + 'O': 'O', + 'x': 'V', # padding +} +_pep3118_standard_typechars = ''.join(_pep3118_standard_map.keys()) + +_pep3118_unsupported_map = { + 'u': 'UCS-2 strings', + '&': 'pointers', + 't': 'bitfields', + 'X': 'function pointers', +} + +class _Stream: + def __init__(self, s): + self.s = s + self.byteorder = '@' + + def advance(self, n): + res = self.s[:n] + self.s = self.s[n:] + return res + + def consume(self, c): + if self.s[:len(c)] == c: + self.advance(len(c)) + return True + return False + + def consume_until(self, c): + if callable(c): + i = 0 + while i < len(self.s) and not c(self.s[i]): + i = i + 1 + return self.advance(i) + else: + i = self.s.index(c) + res = self.advance(i) + self.advance(len(c)) + return res + + @property + def next(self): + return self.s[0] + + def __bool__(self): + return bool(self.s) + + +def _dtype_from_pep3118(spec): + stream = _Stream(spec) + dtype, align = __dtype_from_pep3118(stream, is_subdtype=False) + return dtype + +def __dtype_from_pep3118(stream, is_subdtype): + field_spec = dict( + names=[], + formats=[], + offsets=[], + itemsize=0 + ) + offset = 0 + common_alignment = 1 + is_padding = False + + # Parse spec + while stream: + value = None + + # End of structure, bail out to upper level + if stream.consume('}'): + break + + # Sub-arrays (1) + shape = None + if stream.consume('('): + shape = stream.consume_until(')') + shape = tuple(map(int, shape.split(','))) + + # Byte order + if stream.next in ('@', '=', '<', '>', '^', '!'): + byteorder = stream.advance(1) + if byteorder == '!': + byteorder = '>' + stream.byteorder = byteorder + + # Byte order characters also control native vs. standard type sizes + if stream.byteorder in ('@', '^'): + type_map = _pep3118_native_map + type_map_chars = _pep3118_native_typechars + else: + type_map = _pep3118_standard_map + type_map_chars = _pep3118_standard_typechars + + # Item sizes + itemsize_str = stream.consume_until(lambda c: not c.isdigit()) + if itemsize_str: + itemsize = int(itemsize_str) + else: + itemsize = 1 + + # Data types + is_padding = False + + if stream.consume('T{'): + value, align = __dtype_from_pep3118( + stream, is_subdtype=True) + elif stream.next in type_map_chars: + if stream.next == 'Z': + typechar = stream.advance(2) + else: + typechar = stream.advance(1) + + is_padding = (typechar == 'x') + dtypechar = type_map[typechar] + if dtypechar in 'USV': + dtypechar += '%d' % itemsize + itemsize = 1 + numpy_byteorder = {'@': '=', '^': '='}.get( + stream.byteorder, stream.byteorder) + value = dtype(numpy_byteorder + dtypechar) + align = value.alignment + elif stream.next in _pep3118_unsupported_map: + desc = _pep3118_unsupported_map[stream.next] + raise NotImplementedError( + "Unrepresentable PEP 3118 data type {!r} ({})" + .format(stream.next, desc)) + else: + raise ValueError("Unknown PEP 3118 data type specifier %r" % stream.s) + + # + # Native alignment may require padding + # + # Here we assume that the presence of a '@' character implicitly implies + # that the start of the array is *already* aligned. + # + extra_offset = 0 + if stream.byteorder == '@': + start_padding = (-offset) % align + intra_padding = (-value.itemsize) % align + + offset += start_padding + + if intra_padding != 0: + if itemsize > 1 or (shape is not None and _prod(shape) > 1): + # Inject internal padding to the end of the sub-item + value = _add_trailing_padding(value, intra_padding) + else: + # We can postpone the injection of internal padding, + # as the item appears at most once + extra_offset += intra_padding + + # Update common alignment + common_alignment = _lcm(align, common_alignment) + + # Convert itemsize to sub-array + if itemsize != 1: + value = dtype((value, (itemsize,))) + + # Sub-arrays (2) + if shape is not None: + value = dtype((value, shape)) + + # Field name + if stream.consume(':'): + name = stream.consume_until(':') + else: + name = None + + if not (is_padding and name is None): + if name is not None and name in field_spec['names']: + raise RuntimeError(f"Duplicate field name '{name}' in PEP3118 format") + field_spec['names'].append(name) + field_spec['formats'].append(value) + field_spec['offsets'].append(offset) + + offset += value.itemsize + offset += extra_offset + + field_spec['itemsize'] = offset + + # extra final padding for aligned types + if stream.byteorder == '@': + field_spec['itemsize'] += (-offset) % common_alignment + + # Check if this was a simple 1-item type, and unwrap it + if (field_spec['names'] == [None] + and field_spec['offsets'][0] == 0 + and field_spec['itemsize'] == field_spec['formats'][0].itemsize + and not is_subdtype): + ret = field_spec['formats'][0] + else: + _fix_names(field_spec) + ret = dtype(field_spec) + + # Finished + return ret, common_alignment + +def _fix_names(field_spec): + """ Replace names which are None with the next unused f%d name """ + names = field_spec['names'] + for i, name in enumerate(names): + if name is not None: + continue + + j = 0 + while True: + name = f'f{j}' + if name not in names: + break + j = j + 1 + names[i] = name + +def _add_trailing_padding(value, padding): + """Inject the specified number of padding bytes at the end of a dtype""" + if value.fields is None: + field_spec = dict( + names=['f0'], + formats=[value], + offsets=[0], + itemsize=value.itemsize + ) + else: + fields = value.fields + names = value.names + field_spec = dict( + names=names, + formats=[fields[name][0] for name in names], + offsets=[fields[name][1] for name in names], + itemsize=value.itemsize + ) + + field_spec['itemsize'] += padding + return dtype(field_spec) + +def _prod(a): + p = 1 + for x in a: + p *= x + return p + +def _gcd(a, b): + """Calculate the greatest common divisor of a and b""" + while b: + a, b = b, a % b + return a + +def _lcm(a, b): + return a // _gcd(a, b) * b + +def array_ufunc_errmsg_formatter(dummy, ufunc, method, *inputs, **kwargs): + """ Format the error message for when __array_ufunc__ gives up. """ + args_string = ', '.join(['{!r}'.format(arg) for arg in inputs] + + ['{}={!r}'.format(k, v) + for k, v in kwargs.items()]) + args = inputs + kwargs.get('out', ()) + types_string = ', '.join(repr(type(arg).__name__) for arg in args) + return ('operand type(s) all returned NotImplemented from ' + '__array_ufunc__({!r}, {!r}, {}): {}' + .format(ufunc, method, args_string, types_string)) + + +def array_function_errmsg_formatter(public_api, types): + """ Format the error message for when __array_ufunc__ gives up. """ + func_name = '{}.{}'.format(public_api.__module__, public_api.__name__) + return ("no implementation found for '{}' on types that implement " + '__array_function__: {}'.format(func_name, list(types))) + + +def _ufunc_doc_signature_formatter(ufunc): + """ + Builds a signature string which resembles PEP 457 + + This is used to construct the first line of the docstring + """ + + # input arguments are simple + if ufunc.nin == 1: + in_args = 'x' + else: + in_args = ', '.join(f'x{i+1}' for i in range(ufunc.nin)) + + # output arguments are both keyword or positional + if ufunc.nout == 0: + out_args = ', /, out=()' + elif ufunc.nout == 1: + out_args = ', /, out=None' + else: + out_args = '[, {positional}], / [, out={default}]'.format( + positional=', '.join( + 'out{}'.format(i+1) for i in range(ufunc.nout)), + default=repr((None,)*ufunc.nout) + ) + + # keyword only args depend on whether this is a gufunc + kwargs = ( + ", casting='same_kind'" + ", order='K'" + ", dtype=None" + ", subok=True" + "[, signature" + ", extobj]" + ) + if ufunc.signature is None: + kwargs = ", where=True" + kwargs + + # join all the parts together + return '{name}({in_args}{out_args}, *{kwargs})'.format( + name=ufunc.__name__, + in_args=in_args, + out_args=out_args, + kwargs=kwargs + ) + + +def npy_ctypes_check(cls): + # determine if a class comes from ctypes, in order to work around + # a bug in the buffer protocol for those objects, bpo-10746 + try: + # ctypes class are new-style, so have an __mro__. This probably fails + # for ctypes classes with multiple inheritance. + if IS_PYPY: + # (..., _ctypes.basics._CData, Bufferable, object) + ctype_base = cls.__mro__[-3] + else: + # # (..., _ctypes._CData, object) + ctype_base = cls.__mro__[-2] + # right now, they're part of the _ctypes module + return '_ctypes' in ctype_base.__module__ + except Exception: + return False + + +class recursive: + ''' + A decorator class for recursive nested functions. + Naive recursive nested functions hold a reference to themselves: + + def outer(*args): + def stringify_leaky(arg0, *arg1): + if len(arg1) > 0: + return stringify_leaky(*arg1) # <- HERE + return str(arg0) + stringify_leaky(*args) + + This design pattern creates a reference cycle that is difficult for a + garbage collector to resolve. The decorator class prevents the + cycle by passing the nested function in as an argument `self`: + + def outer(*args): + @recursive + def stringify(self, arg0, *arg1): + if len(arg1) > 0: + return self(*arg1) + return str(arg0) + stringify(*args) + + ''' + def __init__(self, func): + self.func = func + def __call__(self, *args, **kwargs): + return self.func(self, *args, **kwargs) + diff --git a/venv/Lib/site-packages/numpy/core/_internal.pyi b/venv/Lib/site-packages/numpy/core/_internal.pyi new file mode 100644 index 0000000..1b3889e --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/_internal.pyi @@ -0,0 +1,18 @@ +from typing import Any + +# TODO: add better annotations when ctypes is stubbed out + +class _ctypes: + @property + def data(self) -> int: ... + @property + def shape(self) -> Any: ... + @property + def strides(self) -> Any: ... + def data_as(self, obj: Any) -> Any: ... + def shape_as(self, obj: Any) -> Any: ... + def strides_as(self, obj: Any) -> Any: ... + def get_data(self) -> int: ... + def get_shape(self) -> Any: ... + def get_strides(self) -> Any: ... + def get_as_parameter(self) -> Any: ... diff --git a/venv/Lib/site-packages/numpy/core/_methods.py b/venv/Lib/site-packages/numpy/core/_methods.py new file mode 100644 index 0000000..fc11832 --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/_methods.py @@ -0,0 +1,289 @@ +""" +Array methods which are called by both the C-code for the method +and the Python code for the NumPy-namespace function + +""" +import warnings + +from numpy.core import multiarray as mu +from numpy.core import umath as um +from numpy.core._asarray import asanyarray +from numpy.core import numerictypes as nt +from numpy.core import _exceptions +from numpy._globals import _NoValue +from numpy.compat import pickle, os_fspath, contextlib_nullcontext + +# save those O(100) nanoseconds! +umr_maximum = um.maximum.reduce +umr_minimum = um.minimum.reduce +umr_sum = um.add.reduce +umr_prod = um.multiply.reduce +umr_any = um.logical_or.reduce +umr_all = um.logical_and.reduce + +# Complex types to -> (2,)float view for fast-path computation in _var() +_complex_to_float = { + nt.dtype(nt.csingle) : nt.dtype(nt.single), + nt.dtype(nt.cdouble) : nt.dtype(nt.double), +} +# Special case for windows: ensure double takes precedence +if nt.dtype(nt.longdouble) != nt.dtype(nt.double): + _complex_to_float.update({ + nt.dtype(nt.clongdouble) : nt.dtype(nt.longdouble), + }) + +# avoid keyword arguments to speed up parsing, saves about 15%-20% for very +# small reductions +def _amax(a, axis=None, out=None, keepdims=False, + initial=_NoValue, where=True): + return umr_maximum(a, axis, None, out, keepdims, initial, where) + +def _amin(a, axis=None, out=None, keepdims=False, + initial=_NoValue, where=True): + return umr_minimum(a, axis, None, out, keepdims, initial, where) + +def _sum(a, axis=None, dtype=None, out=None, keepdims=False, + initial=_NoValue, where=True): + return umr_sum(a, axis, dtype, out, keepdims, initial, where) + +def _prod(a, axis=None, dtype=None, out=None, keepdims=False, + initial=_NoValue, where=True): + return umr_prod(a, axis, dtype, out, keepdims, initial, where) + +def _any(a, axis=None, dtype=None, out=None, keepdims=False, *, where=True): + # Parsing keyword arguments is currently fairly slow, so avoid it for now + if where is True: + return umr_any(a, axis, dtype, out, keepdims) + return umr_any(a, axis, dtype, out, keepdims, where=where) + +def _all(a, axis=None, dtype=None, out=None, keepdims=False, *, where=True): + # Parsing keyword arguments is currently fairly slow, so avoid it for now + if where is True: + return umr_all(a, axis, dtype, out, keepdims) + return umr_all(a, axis, dtype, out, keepdims, where=where) + +def _count_reduce_items(arr, axis, keepdims=False, where=True): + # fast-path for the default case + if where is True: + # no boolean mask given, calculate items according to axis + if axis is None: + axis = tuple(range(arr.ndim)) + elif not isinstance(axis, tuple): + axis = (axis,) + items = nt.intp(1) + for ax in axis: + items *= arr.shape[mu.normalize_axis_index(ax, arr.ndim)] + else: + # TODO: Optimize case when `where` is broadcast along a non-reduction + # axis and full sum is more excessive than needed. + + # guarded to protect circular imports + from numpy.lib.stride_tricks import broadcast_to + # count True values in (potentially broadcasted) boolean mask + items = umr_sum(broadcast_to(where, arr.shape), axis, nt.intp, None, + keepdims) + return items + +# Numpy 1.17.0, 2019-02-24 +# Various clip behavior deprecations, marked with _clip_dep as a prefix. + +def _clip_dep_is_scalar_nan(a): + # guarded to protect circular imports + from numpy.core.fromnumeric import ndim + if ndim(a) != 0: + return False + try: + return um.isnan(a) + except TypeError: + return False + +def _clip_dep_is_byte_swapped(a): + if isinstance(a, mu.ndarray): + return not a.dtype.isnative + return False + +def _clip_dep_invoke_with_casting(ufunc, *args, out=None, casting=None, **kwargs): + # normal path + if casting is not None: + return ufunc(*args, out=out, casting=casting, **kwargs) + + # try to deal with broken casting rules + try: + return ufunc(*args, out=out, **kwargs) + except _exceptions._UFuncOutputCastingError as e: + # Numpy 1.17.0, 2019-02-24 + warnings.warn( + "Converting the output of clip from {!r} to {!r} is deprecated. " + "Pass `casting=\"unsafe\"` explicitly to silence this warning, or " + "correct the type of the variables.".format(e.from_, e.to), + DeprecationWarning, + stacklevel=2 + ) + return ufunc(*args, out=out, casting="unsafe", **kwargs) + +def _clip(a, min=None, max=None, out=None, *, casting=None, **kwargs): + if min is None and max is None: + raise ValueError("One of max or min must be given") + + # Numpy 1.17.0, 2019-02-24 + # This deprecation probably incurs a substantial slowdown for small arrays, + # it will be good to get rid of it. + if not _clip_dep_is_byte_swapped(a) and not _clip_dep_is_byte_swapped(out): + using_deprecated_nan = False + if _clip_dep_is_scalar_nan(min): + min = -float('inf') + using_deprecated_nan = True + if _clip_dep_is_scalar_nan(max): + max = float('inf') + using_deprecated_nan = True + if using_deprecated_nan: + warnings.warn( + "Passing `np.nan` to mean no clipping in np.clip has always " + "been unreliable, and is now deprecated. " + "In future, this will always return nan, like it already does " + "when min or max are arrays that contain nan. " + "To skip a bound, pass either None or an np.inf of an " + "appropriate sign.", + DeprecationWarning, + stacklevel=2 + ) + + if min is None: + return _clip_dep_invoke_with_casting( + um.minimum, a, max, out=out, casting=casting, **kwargs) + elif max is None: + return _clip_dep_invoke_with_casting( + um.maximum, a, min, out=out, casting=casting, **kwargs) + else: + return _clip_dep_invoke_with_casting( + um.clip, a, min, max, out=out, casting=casting, **kwargs) + +def _mean(a, axis=None, dtype=None, out=None, keepdims=False, *, where=True): + arr = asanyarray(a) + + is_float16_result = False + + rcount = _count_reduce_items(arr, axis, keepdims=keepdims, where=where) + if rcount == 0 if where is True else umr_any(rcount == 0, axis=None): + warnings.warn("Mean of empty slice.", RuntimeWarning, stacklevel=2) + + # Cast bool, unsigned int, and int to float64 by default + if dtype is None: + if issubclass(arr.dtype.type, (nt.integer, nt.bool_)): + dtype = mu.dtype('f8') + elif issubclass(arr.dtype.type, nt.float16): + dtype = mu.dtype('f4') + is_float16_result = True + + ret = umr_sum(arr, axis, dtype, out, keepdims, where=where) + if isinstance(ret, mu.ndarray): + ret = um.true_divide( + ret, rcount, out=ret, casting='unsafe', subok=False) + if is_float16_result and out is None: + ret = arr.dtype.type(ret) + elif hasattr(ret, 'dtype'): + if is_float16_result: + ret = arr.dtype.type(ret / rcount) + else: + ret = ret.dtype.type(ret / rcount) + else: + ret = ret / rcount + + return ret + +def _var(a, axis=None, dtype=None, out=None, ddof=0, keepdims=False, *, + where=True): + arr = asanyarray(a) + + rcount = _count_reduce_items(arr, axis, keepdims=keepdims, where=where) + # Make this warning show up on top. + if ddof >= rcount if where is True else umr_any(ddof >= rcount, axis=None): + warnings.warn("Degrees of freedom <= 0 for slice", RuntimeWarning, + stacklevel=2) + + # Cast bool, unsigned int, and int to float64 by default + if dtype is None and issubclass(arr.dtype.type, (nt.integer, nt.bool_)): + dtype = mu.dtype('f8') + + # Compute the mean. + # Note that if dtype is not of inexact type then arraymean will + # not be either. + arrmean = umr_sum(arr, axis, dtype, keepdims=True, where=where) + # The shape of rcount has to match arrmean to not change the shape of out + # in broadcasting. Otherwise, it cannot be stored back to arrmean. + if rcount.ndim == 0: + # fast-path for default case when where is True + div = rcount + else: + # matching rcount to arrmean when where is specified as array + div = rcount.reshape(arrmean.shape) + if isinstance(arrmean, mu.ndarray): + arrmean = um.true_divide(arrmean, div, out=arrmean, casting='unsafe', + subok=False) + else: + arrmean = arrmean.dtype.type(arrmean / rcount) + + # Compute sum of squared deviations from mean + # Note that x may not be inexact and that we need it to be an array, + # not a scalar. + x = asanyarray(arr - arrmean) + + if issubclass(arr.dtype.type, (nt.floating, nt.integer)): + x = um.multiply(x, x, out=x) + # Fast-paths for built-in complex types + elif x.dtype in _complex_to_float: + xv = x.view(dtype=(_complex_to_float[x.dtype], (2,))) + um.multiply(xv, xv, out=xv) + x = um.add(xv[..., 0], xv[..., 1], out=x.real).real + # Most general case; includes handling object arrays containing imaginary + # numbers and complex types with non-native byteorder + else: + x = um.multiply(x, um.conjugate(x), out=x).real + + ret = umr_sum(x, axis, dtype, out, keepdims=keepdims, where=where) + + # Compute degrees of freedom and make sure it is not negative. + rcount = um.maximum(rcount - ddof, 0) + + # divide by degrees of freedom + if isinstance(ret, mu.ndarray): + ret = um.true_divide( + ret, rcount, out=ret, casting='unsafe', subok=False) + elif hasattr(ret, 'dtype'): + ret = ret.dtype.type(ret / rcount) + else: + ret = ret / rcount + + return ret + +def _std(a, axis=None, dtype=None, out=None, ddof=0, keepdims=False, *, + where=True): + ret = _var(a, axis=axis, dtype=dtype, out=out, ddof=ddof, + keepdims=keepdims, where=where) + + if isinstance(ret, mu.ndarray): + ret = um.sqrt(ret, out=ret) + elif hasattr(ret, 'dtype'): + ret = ret.dtype.type(um.sqrt(ret)) + else: + ret = um.sqrt(ret) + + return ret + +def _ptp(a, axis=None, out=None, keepdims=False): + return um.subtract( + umr_maximum(a, axis, None, out, keepdims), + umr_minimum(a, axis, None, None, keepdims), + out + ) + +def _dump(self, file, protocol=2): + if hasattr(file, 'write'): + ctx = contextlib_nullcontext(file) + else: + ctx = open(os_fspath(file), "wb") + with ctx as f: + pickle.dump(self, f, protocol=protocol) + +def _dumps(self, protocol=2): + return pickle.dumps(self, protocol=protocol) diff --git a/venv/Lib/site-packages/numpy/core/_string_helpers.py b/venv/Lib/site-packages/numpy/core/_string_helpers.py new file mode 100644 index 0000000..45e6a73 --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/_string_helpers.py @@ -0,0 +1,100 @@ +""" +String-handling utilities to avoid locale-dependence. + +Used primarily to generate type name aliases. +""" +# "import string" is costly to import! +# Construct the translation tables directly +# "A" = chr(65), "a" = chr(97) +_all_chars = [chr(_m) for _m in range(256)] +_ascii_upper = _all_chars[65:65+26] +_ascii_lower = _all_chars[97:97+26] +LOWER_TABLE = "".join(_all_chars[:65] + _ascii_lower + _all_chars[65+26:]) +UPPER_TABLE = "".join(_all_chars[:97] + _ascii_upper + _all_chars[97+26:]) + + +def english_lower(s): + """ Apply English case rules to convert ASCII strings to all lower case. + + This is an internal utility function to replace calls to str.lower() such + that we can avoid changing behavior with changing locales. In particular, + Turkish has distinct dotted and dotless variants of the Latin letter "I" in + both lowercase and uppercase. Thus, "I".lower() != "i" in a "tr" locale. + + Parameters + ---------- + s : str + + Returns + ------- + lowered : str + + Examples + -------- + >>> from numpy.core.numerictypes import english_lower + >>> english_lower('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_') + 'abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789_' + >>> english_lower('') + '' + """ + lowered = s.translate(LOWER_TABLE) + return lowered + + +def english_upper(s): + """ Apply English case rules to convert ASCII strings to all upper case. + + This is an internal utility function to replace calls to str.upper() such + that we can avoid changing behavior with changing locales. In particular, + Turkish has distinct dotted and dotless variants of the Latin letter "I" in + both lowercase and uppercase. Thus, "i".upper() != "I" in a "tr" locale. + + Parameters + ---------- + s : str + + Returns + ------- + uppered : str + + Examples + -------- + >>> from numpy.core.numerictypes import english_upper + >>> english_upper('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_') + 'ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_' + >>> english_upper('') + '' + """ + uppered = s.translate(UPPER_TABLE) + return uppered + + +def english_capitalize(s): + """ Apply English case rules to convert the first character of an ASCII + string to upper case. + + This is an internal utility function to replace calls to str.capitalize() + such that we can avoid changing behavior with changing locales. + + Parameters + ---------- + s : str + + Returns + ------- + capitalized : str + + Examples + -------- + >>> from numpy.core.numerictypes import english_capitalize + >>> english_capitalize('int8') + 'Int8' + >>> english_capitalize('Int8') + 'Int8' + >>> english_capitalize('') + '' + """ + if s: + return english_upper(s[0]) + s[1:] + else: + return s diff --git a/venv/Lib/site-packages/numpy/core/_type_aliases.py b/venv/Lib/site-packages/numpy/core/_type_aliases.py new file mode 100644 index 0000000..de90fd8 --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/_type_aliases.py @@ -0,0 +1,243 @@ +""" +Due to compatibility, numpy has a very large number of different naming +conventions for the scalar types (those subclassing from `numpy.generic`). +This file produces a convoluted set of dictionaries mapping names to types, +and sometimes other mappings too. + +.. data:: allTypes + A dictionary of names to types that will be exposed as attributes through + ``np.core.numerictypes.*`` + +.. data:: sctypeDict + Similar to `allTypes`, but maps a broader set of aliases to their types. + +.. data:: sctypes + A dictionary keyed by a "type group" string, providing a list of types + under that group. + +""" + +from numpy.compat import unicode +from numpy.core._string_helpers import english_lower +from numpy.core.multiarray import typeinfo, dtype +from numpy.core._dtype import _kind_name + + +sctypeDict = {} # Contains all leaf-node scalar types with aliases +allTypes = {} # Collect the types we will add to the module + + +# separate the actual type info from the abstract base classes +_abstract_types = {} +_concrete_typeinfo = {} +for k, v in typeinfo.items(): + # make all the keys lowercase too + k = english_lower(k) + if isinstance(v, type): + _abstract_types[k] = v + else: + _concrete_typeinfo[k] = v + +_concrete_types = {v.type for k, v in _concrete_typeinfo.items()} + + +def _bits_of(obj): + try: + info = next(v for v in _concrete_typeinfo.values() if v.type is obj) + except StopIteration: + if obj in _abstract_types.values(): + raise ValueError("Cannot count the bits of an abstract type") + + # some third-party type - make a best-guess + return dtype(obj).itemsize * 8 + else: + return info.bits + + +def bitname(obj): + """Return a bit-width name for a given type object""" + bits = _bits_of(obj) + dt = dtype(obj) + char = dt.kind + base = _kind_name(dt) + + if base == 'object': + bits = 0 + + if bits != 0: + char = "%s%d" % (char, bits // 8) + + return base, bits, char + + +def _add_types(): + for name, info in _concrete_typeinfo.items(): + # define C-name and insert typenum and typechar references also + allTypes[name] = info.type + sctypeDict[name] = info.type + sctypeDict[info.char] = info.type + sctypeDict[info.num] = info.type + + for name, cls in _abstract_types.items(): + allTypes[name] = cls +_add_types() + +# This is the priority order used to assign the bit-sized NPY_INTxx names, which +# must match the order in npy_common.h in order for NPY_INTxx and np.intxx to be +# consistent. +# If two C types have the same size, then the earliest one in this list is used +# as the sized name. +_int_ctypes = ['long', 'longlong', 'int', 'short', 'byte'] +_uint_ctypes = list('u' + t for t in _int_ctypes) + +def _add_aliases(): + for name, info in _concrete_typeinfo.items(): + # these are handled by _add_integer_aliases + if name in _int_ctypes or name in _uint_ctypes: + continue + + # insert bit-width version for this class (if relevant) + base, bit, char = bitname(info.type) + + myname = "%s%d" % (base, bit) + + # ensure that (c)longdouble does not overwrite the aliases assigned to + # (c)double + if name in ('longdouble', 'clongdouble') and myname in allTypes: + continue + + allTypes[myname] = info.type + + # add mapping for both the bit name and the numarray name + sctypeDict[myname] = info.type + + # add forward, reverse, and string mapping to numarray + sctypeDict[char] = info.type + + # Add deprecated numeric-style type aliases manually, at some point + # we may want to deprecate the lower case "bytes0" version as well. + for name in ["Bytes0", "Datetime64", "Str0", "Uint32", "Uint64"]: + if english_lower(name) not in allTypes: + # Only one of Uint32 or Uint64, aliases of `np.uintp`, was (and is) defined, note that this + # is not UInt32/UInt64 (capital i), which is removed. + continue + allTypes[name] = allTypes[english_lower(name)] + sctypeDict[name] = sctypeDict[english_lower(name)] + +_add_aliases() + +def _add_integer_aliases(): + seen_bits = set() + for i_ctype, u_ctype in zip(_int_ctypes, _uint_ctypes): + i_info = _concrete_typeinfo[i_ctype] + u_info = _concrete_typeinfo[u_ctype] + bits = i_info.bits # same for both + + for info, charname, intname in [ + (i_info,'i%d' % (bits//8,), 'int%d' % bits), + (u_info,'u%d' % (bits//8,), 'uint%d' % bits)]: + if bits not in seen_bits: + # sometimes two different types have the same number of bits + # if so, the one iterated over first takes precedence + allTypes[intname] = info.type + sctypeDict[intname] = info.type + sctypeDict[charname] = info.type + + seen_bits.add(bits) + +_add_integer_aliases() + +# We use these later +void = allTypes['void'] + +# +# Rework the Python names (so that float and complex and int are consistent +# with Python usage) +# +def _set_up_aliases(): + type_pairs = [('complex_', 'cdouble'), + ('int0', 'intp'), + ('uint0', 'uintp'), + ('single', 'float'), + ('csingle', 'cfloat'), + ('singlecomplex', 'cfloat'), + ('float_', 'double'), + ('intc', 'int'), + ('uintc', 'uint'), + ('int_', 'long'), + ('uint', 'ulong'), + ('cfloat', 'cdouble'), + ('longfloat', 'longdouble'), + ('clongfloat', 'clongdouble'), + ('longcomplex', 'clongdouble'), + ('bool_', 'bool'), + ('bytes_', 'string'), + ('string_', 'string'), + ('str_', 'unicode'), + ('unicode_', 'unicode'), + ('object_', 'object')] + for alias, t in type_pairs: + allTypes[alias] = allTypes[t] + sctypeDict[alias] = sctypeDict[t] + # Remove aliases overriding python types and modules + to_remove = ['ulong', 'object', 'int', 'float', + 'complex', 'bool', 'string', 'datetime', 'timedelta', + 'bytes', 'str'] + + for t in to_remove: + try: + del allTypes[t] + del sctypeDict[t] + except KeyError: + pass +_set_up_aliases() + + +sctypes = {'int': [], + 'uint':[], + 'float':[], + 'complex':[], + 'others':[bool, object, bytes, unicode, void]} + +def _add_array_type(typename, bits): + try: + t = allTypes['%s%d' % (typename, bits)] + except KeyError: + pass + else: + sctypes[typename].append(t) + +def _set_array_types(): + ibytes = [1, 2, 4, 8, 16, 32, 64] + fbytes = [2, 4, 8, 10, 12, 16, 32, 64] + for bytes in ibytes: + bits = 8*bytes + _add_array_type('int', bits) + _add_array_type('uint', bits) + for bytes in fbytes: + bits = 8*bytes + _add_array_type('float', bits) + _add_array_type('complex', 2*bits) + _gi = dtype('p') + if _gi.type not in sctypes['int']: + indx = 0 + sz = _gi.itemsize + _lst = sctypes['int'] + while (indx < len(_lst) and sz >= _lst[indx](0).itemsize): + indx += 1 + sctypes['int'].insert(indx, _gi.type) + sctypes['uint'].insert(indx, dtype('P').type) +_set_array_types() + + +# Add additional strings to the sctypeDict +_toadd = ['int', 'float', 'complex', 'bool', 'object', + 'str', 'bytes', ('a', 'bytes_')] + +for name in _toadd: + if isinstance(name, tuple): + sctypeDict[name[0]] = allTypes[name[1]] + else: + sctypeDict[name] = allTypes['%s_' % name] + +del _toadd, name diff --git a/venv/Lib/site-packages/numpy/core/_type_aliases.pyi b/venv/Lib/site-packages/numpy/core/_type_aliases.pyi new file mode 100644 index 0000000..6a1099c --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/_type_aliases.pyi @@ -0,0 +1,19 @@ +import sys +from typing import Dict, Union, Type, List + +from numpy import generic, signedinteger, unsignedinteger, floating, complexfloating + +if sys.version_info >= (3, 8): + from typing import TypedDict +else: + from typing_extensions import TypedDict + +class _SCTypes(TypedDict): + int: List[Type[signedinteger]] + uint: List[Type[unsignedinteger]] + float: List[Type[floating]] + complex: List[Type[complexfloating]] + others: List[type] + +sctypeDict: Dict[Union[int, str], Type[generic]] +sctypes: _SCTypes diff --git a/venv/Lib/site-packages/numpy/core/_ufunc_config.py b/venv/Lib/site-packages/numpy/core/_ufunc_config.py new file mode 100644 index 0000000..454d911 --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/_ufunc_config.py @@ -0,0 +1,450 @@ +""" +Functions for changing global ufunc configuration + +This provides helpers which wrap `umath.geterrobj` and `umath.seterrobj` +""" +import collections.abc +import contextlib + +from .overrides import set_module +from .umath import ( + UFUNC_BUFSIZE_DEFAULT, + ERR_IGNORE, ERR_WARN, ERR_RAISE, ERR_CALL, ERR_PRINT, ERR_LOG, ERR_DEFAULT, + SHIFT_DIVIDEBYZERO, SHIFT_OVERFLOW, SHIFT_UNDERFLOW, SHIFT_INVALID, +) +from . import umath + +__all__ = [ + "seterr", "geterr", "setbufsize", "getbufsize", "seterrcall", "geterrcall", + "errstate", +] + +_errdict = {"ignore": ERR_IGNORE, + "warn": ERR_WARN, + "raise": ERR_RAISE, + "call": ERR_CALL, + "print": ERR_PRINT, + "log": ERR_LOG} + +_errdict_rev = {value: key for key, value in _errdict.items()} + + +@set_module('numpy') +def seterr(all=None, divide=None, over=None, under=None, invalid=None): + """ + Set how floating-point errors are handled. + + Note that operations on integer scalar types (such as `int16`) are + handled like floating point, and are affected by these settings. + + Parameters + ---------- + all : {'ignore', 'warn', 'raise', 'call', 'print', 'log'}, optional + Set treatment for all types of floating-point errors at once: + + - ignore: Take no action when the exception occurs. + - warn: Print a `RuntimeWarning` (via the Python `warnings` module). + - raise: Raise a `FloatingPointError`. + - call: Call a function specified using the `seterrcall` function. + - print: Print a warning directly to ``stdout``. + - log: Record error in a Log object specified by `seterrcall`. + + The default is not to change the current behavior. + divide : {'ignore', 'warn', 'raise', 'call', 'print', 'log'}, optional + Treatment for division by zero. + over : {'ignore', 'warn', 'raise', 'call', 'print', 'log'}, optional + Treatment for floating-point overflow. + under : {'ignore', 'warn', 'raise', 'call', 'print', 'log'}, optional + Treatment for floating-point underflow. + invalid : {'ignore', 'warn', 'raise', 'call', 'print', 'log'}, optional + Treatment for invalid floating-point operation. + + Returns + ------- + old_settings : dict + Dictionary containing the old settings. + + See also + -------- + seterrcall : Set a callback function for the 'call' mode. + geterr, geterrcall, errstate + + Notes + ----- + The floating-point exceptions are defined in the IEEE 754 standard [1]_: + + - Division by zero: infinite result obtained from finite numbers. + - Overflow: result too large to be expressed. + - Underflow: result so close to zero that some precision + was lost. + - Invalid operation: result is not an expressible number, typically + indicates that a NaN was produced. + + .. [1] https://en.wikipedia.org/wiki/IEEE_754 + + Examples + -------- + >>> old_settings = np.seterr(all='ignore') #seterr to known value + >>> np.seterr(over='raise') + {'divide': 'ignore', 'over': 'ignore', 'under': 'ignore', 'invalid': 'ignore'} + >>> np.seterr(**old_settings) # reset to default + {'divide': 'ignore', 'over': 'raise', 'under': 'ignore', 'invalid': 'ignore'} + + >>> np.int16(32000) * np.int16(3) + 30464 + >>> old_settings = np.seterr(all='warn', over='raise') + >>> np.int16(32000) * np.int16(3) + Traceback (most recent call last): + File "", line 1, in + FloatingPointError: overflow encountered in short_scalars + + >>> from collections import OrderedDict + >>> old_settings = np.seterr(all='print') + >>> OrderedDict(np.geterr()) + OrderedDict([('divide', 'print'), ('over', 'print'), ('under', 'print'), ('invalid', 'print')]) + >>> np.int16(32000) * np.int16(3) + 30464 + + """ + + pyvals = umath.geterrobj() + old = geterr() + + if divide is None: + divide = all or old['divide'] + if over is None: + over = all or old['over'] + if under is None: + under = all or old['under'] + if invalid is None: + invalid = all or old['invalid'] + + maskvalue = ((_errdict[divide] << SHIFT_DIVIDEBYZERO) + + (_errdict[over] << SHIFT_OVERFLOW) + + (_errdict[under] << SHIFT_UNDERFLOW) + + (_errdict[invalid] << SHIFT_INVALID)) + + pyvals[1] = maskvalue + umath.seterrobj(pyvals) + return old + + +@set_module('numpy') +def geterr(): + """ + Get the current way of handling floating-point errors. + + Returns + ------- + res : dict + A dictionary with keys "divide", "over", "under", and "invalid", + whose values are from the strings "ignore", "print", "log", "warn", + "raise", and "call". The keys represent possible floating-point + exceptions, and the values define how these exceptions are handled. + + See Also + -------- + geterrcall, seterr, seterrcall + + Notes + ----- + For complete documentation of the types of floating-point exceptions and + treatment options, see `seterr`. + + Examples + -------- + >>> from collections import OrderedDict + >>> sorted(np.geterr().items()) + [('divide', 'warn'), ('invalid', 'warn'), ('over', 'warn'), ('under', 'ignore')] + >>> np.arange(3.) / np.arange(3.) + array([nan, 1., 1.]) + + >>> oldsettings = np.seterr(all='warn', over='raise') + >>> OrderedDict(sorted(np.geterr().items())) + OrderedDict([('divide', 'warn'), ('invalid', 'warn'), ('over', 'raise'), ('under', 'warn')]) + >>> np.arange(3.) / np.arange(3.) + array([nan, 1., 1.]) + + """ + maskvalue = umath.geterrobj()[1] + mask = 7 + res = {} + val = (maskvalue >> SHIFT_DIVIDEBYZERO) & mask + res['divide'] = _errdict_rev[val] + val = (maskvalue >> SHIFT_OVERFLOW) & mask + res['over'] = _errdict_rev[val] + val = (maskvalue >> SHIFT_UNDERFLOW) & mask + res['under'] = _errdict_rev[val] + val = (maskvalue >> SHIFT_INVALID) & mask + res['invalid'] = _errdict_rev[val] + return res + + +@set_module('numpy') +def setbufsize(size): + """ + Set the size of the buffer used in ufuncs. + + Parameters + ---------- + size : int + Size of buffer. + + """ + if size > 10e6: + raise ValueError("Buffer size, %s, is too big." % size) + if size < 5: + raise ValueError("Buffer size, %s, is too small." % size) + if size % 16 != 0: + raise ValueError("Buffer size, %s, is not a multiple of 16." % size) + + pyvals = umath.geterrobj() + old = getbufsize() + pyvals[0] = size + umath.seterrobj(pyvals) + return old + + +@set_module('numpy') +def getbufsize(): + """ + Return the size of the buffer used in ufuncs. + + Returns + ------- + getbufsize : int + Size of ufunc buffer in bytes. + + """ + return umath.geterrobj()[0] + + +@set_module('numpy') +def seterrcall(func): + """ + Set the floating-point error callback function or log object. + + There are two ways to capture floating-point error messages. The first + is to set the error-handler to 'call', using `seterr`. Then, set + the function to call using this function. + + The second is to set the error-handler to 'log', using `seterr`. + Floating-point errors then trigger a call to the 'write' method of + the provided object. + + Parameters + ---------- + func : callable f(err, flag) or object with write method + Function to call upon floating-point errors ('call'-mode) or + object whose 'write' method is used to log such message ('log'-mode). + + The call function takes two arguments. The first is a string describing + the type of error (such as "divide by zero", "overflow", "underflow", + or "invalid value"), and the second is the status flag. The flag is a + byte, whose four least-significant bits indicate the type of error, one + of "divide", "over", "under", "invalid":: + + [0 0 0 0 divide over under invalid] + + In other words, ``flags = divide + 2*over + 4*under + 8*invalid``. + + If an object is provided, its write method should take one argument, + a string. + + Returns + ------- + h : callable, log instance or None + The old error handler. + + See Also + -------- + seterr, geterr, geterrcall + + Examples + -------- + Callback upon error: + + >>> def err_handler(type, flag): + ... print("Floating point error (%s), with flag %s" % (type, flag)) + ... + + >>> saved_handler = np.seterrcall(err_handler) + >>> save_err = np.seterr(all='call') + >>> from collections import OrderedDict + + >>> np.array([1, 2, 3]) / 0.0 + Floating point error (divide by zero), with flag 1 + array([inf, inf, inf]) + + >>> np.seterrcall(saved_handler) + + >>> OrderedDict(sorted(np.seterr(**save_err).items())) + OrderedDict([('divide', 'call'), ('invalid', 'call'), ('over', 'call'), ('under', 'call')]) + + Log error message: + + >>> class Log: + ... def write(self, msg): + ... print("LOG: %s" % msg) + ... + + >>> log = Log() + >>> saved_handler = np.seterrcall(log) + >>> save_err = np.seterr(all='log') + + >>> np.array([1, 2, 3]) / 0.0 + LOG: Warning: divide by zero encountered in true_divide + array([inf, inf, inf]) + + >>> np.seterrcall(saved_handler) + + >>> OrderedDict(sorted(np.seterr(**save_err).items())) + OrderedDict([('divide', 'log'), ('invalid', 'log'), ('over', 'log'), ('under', 'log')]) + + """ + if func is not None and not isinstance(func, collections.abc.Callable): + if (not hasattr(func, 'write') or + not isinstance(func.write, collections.abc.Callable)): + raise ValueError("Only callable can be used as callback") + pyvals = umath.geterrobj() + old = geterrcall() + pyvals[2] = func + umath.seterrobj(pyvals) + return old + + +@set_module('numpy') +def geterrcall(): + """ + Return the current callback function used on floating-point errors. + + When the error handling for a floating-point error (one of "divide", + "over", "under", or "invalid") is set to 'call' or 'log', the function + that is called or the log instance that is written to is returned by + `geterrcall`. This function or log instance has been set with + `seterrcall`. + + Returns + ------- + errobj : callable, log instance or None + The current error handler. If no handler was set through `seterrcall`, + ``None`` is returned. + + See Also + -------- + seterrcall, seterr, geterr + + Notes + ----- + For complete documentation of the types of floating-point exceptions and + treatment options, see `seterr`. + + Examples + -------- + >>> np.geterrcall() # we did not yet set a handler, returns None + + >>> oldsettings = np.seterr(all='call') + >>> def err_handler(type, flag): + ... print("Floating point error (%s), with flag %s" % (type, flag)) + >>> oldhandler = np.seterrcall(err_handler) + >>> np.array([1, 2, 3]) / 0.0 + Floating point error (divide by zero), with flag 1 + array([inf, inf, inf]) + + >>> cur_handler = np.geterrcall() + >>> cur_handler is err_handler + True + + """ + return umath.geterrobj()[2] + + +class _unspecified: + pass + + +_Unspecified = _unspecified() + + +@set_module('numpy') +class errstate(contextlib.ContextDecorator): + """ + errstate(**kwargs) + + Context manager for floating-point error handling. + + Using an instance of `errstate` as a context manager allows statements in + that context to execute with a known error handling behavior. Upon entering + the context the error handling is set with `seterr` and `seterrcall`, and + upon exiting it is reset to what it was before. + + .. versionchanged:: 1.17.0 + `errstate` is also usable as a function decorator, saving + a level of indentation if an entire function is wrapped. + See :py:class:`contextlib.ContextDecorator` for more information. + + Parameters + ---------- + kwargs : {divide, over, under, invalid} + Keyword arguments. The valid keywords are the possible floating-point + exceptions. Each keyword should have a string value that defines the + treatment for the particular error. Possible values are + {'ignore', 'warn', 'raise', 'call', 'print', 'log'}. + + See Also + -------- + seterr, geterr, seterrcall, geterrcall + + Notes + ----- + For complete documentation of the types of floating-point exceptions and + treatment options, see `seterr`. + + Examples + -------- + >>> from collections import OrderedDict + >>> olderr = np.seterr(all='ignore') # Set error handling to known state. + + >>> np.arange(3) / 0. + array([nan, inf, inf]) + >>> with np.errstate(divide='warn'): + ... np.arange(3) / 0. + array([nan, inf, inf]) + + >>> np.sqrt(-1) + nan + >>> with np.errstate(invalid='raise'): + ... np.sqrt(-1) + Traceback (most recent call last): + File "", line 2, in + FloatingPointError: invalid value encountered in sqrt + + Outside the context the error handling behavior has not changed: + + >>> OrderedDict(sorted(np.geterr().items())) + OrderedDict([('divide', 'ignore'), ('invalid', 'ignore'), ('over', 'ignore'), ('under', 'ignore')]) + + """ + + def __init__(self, *, call=_Unspecified, **kwargs): + self.call = call + self.kwargs = kwargs + + def __enter__(self): + self.oldstate = seterr(**self.kwargs) + if self.call is not _Unspecified: + self.oldcall = seterrcall(self.call) + + def __exit__(self, *exc_info): + seterr(**self.oldstate) + if self.call is not _Unspecified: + seterrcall(self.oldcall) + + +def _setdef(): + defval = [UFUNC_BUFSIZE_DEFAULT, ERR_DEFAULT, None] + umath.seterrobj(defval) + + +# set the default values +_setdef() diff --git a/venv/Lib/site-packages/numpy/core/_ufunc_config.pyi b/venv/Lib/site-packages/numpy/core/_ufunc_config.pyi new file mode 100644 index 0000000..e90f1c5 --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/_ufunc_config.pyi @@ -0,0 +1,43 @@ +import sys +from typing import Optional, Union, Callable, Any + +if sys.version_info >= (3, 8): + from typing import Literal, Protocol, TypedDict +else: + from typing_extensions import Literal, Protocol, TypedDict + +_ErrKind = Literal["ignore", "warn", "raise", "call", "print", "log"] +_ErrFunc = Callable[[str, int], Any] + +class _SupportsWrite(Protocol): + def write(self, __msg: str) -> Any: ... + +class _ErrDict(TypedDict): + divide: _ErrKind + over: _ErrKind + under: _ErrKind + invalid: _ErrKind + +class _ErrDictOptional(TypedDict, total=False): + all: Optional[_ErrKind] + divide: Optional[_ErrKind] + over: Optional[_ErrKind] + under: Optional[_ErrKind] + invalid: Optional[_ErrKind] + +def seterr( + all: Optional[_ErrKind] = ..., + divide: Optional[_ErrKind] = ..., + over: Optional[_ErrKind] = ..., + under: Optional[_ErrKind] = ..., + invalid: Optional[_ErrKind] = ..., +) -> _ErrDict: ... +def geterr() -> _ErrDict: ... +def setbufsize(size: int) -> int: ... +def getbufsize() -> int: ... +def seterrcall( + func: Union[None, _ErrFunc, _SupportsWrite] +) -> Union[None, _ErrFunc, _SupportsWrite]: ... +def geterrcall() -> Union[None, _ErrFunc, _SupportsWrite]: ... + +# See `numpy/__init__.pyi` for the `errstate` class diff --git a/venv/Lib/site-packages/numpy/core/arrayprint.py b/venv/Lib/site-packages/numpy/core/arrayprint.py new file mode 100644 index 0000000..ad15304 --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/arrayprint.py @@ -0,0 +1,1630 @@ +"""Array printing function + +$Id: arrayprint.py,v 1.9 2005/09/13 13:58:44 teoliphant Exp $ + +""" +__all__ = ["array2string", "array_str", "array_repr", "set_string_function", + "set_printoptions", "get_printoptions", "printoptions", + "format_float_positional", "format_float_scientific"] +__docformat__ = 'restructuredtext' + +# +# Written by Konrad Hinsen +# last revision: 1996-3-13 +# modified by Jim Hugunin 1997-3-3 for repr's and str's (and other details) +# and by Perry Greenfield 2000-4-1 for numarray +# and by Travis Oliphant 2005-8-22 for numpy + + +# Note: Both scalartypes.c.src and arrayprint.py implement strs for numpy +# scalars but for different purposes. scalartypes.c.src has str/reprs for when +# the scalar is printed on its own, while arrayprint.py has strs for when +# scalars are printed inside an ndarray. Only the latter strs are currently +# user-customizable. + +import functools +import numbers +try: + from _thread import get_ident +except ImportError: + from _dummy_thread import get_ident + +import numpy as np +from . import numerictypes as _nt +from .umath import absolute, isinf, isfinite, isnat +from . import multiarray +from .multiarray import (array, dragon4_positional, dragon4_scientific, + datetime_as_string, datetime_data, ndarray, + set_legacy_print_mode) +from .fromnumeric import any +from .numeric import concatenate, asarray, errstate +from .numerictypes import (longlong, intc, int_, float_, complex_, bool_, + flexible) +from .overrides import array_function_dispatch, set_module +import warnings +import contextlib + +_format_options = { + 'edgeitems': 3, # repr N leading and trailing items of each dimension + 'threshold': 1000, # total items > triggers array summarization + 'floatmode': 'maxprec', + 'precision': 8, # precision of floating point representations + 'suppress': False, # suppress printing small floating values in exp format + 'linewidth': 75, + 'nanstr': 'nan', + 'infstr': 'inf', + 'sign': '-', + 'formatter': None, + 'legacy': False} + +def _make_options_dict(precision=None, threshold=None, edgeitems=None, + linewidth=None, suppress=None, nanstr=None, infstr=None, + sign=None, formatter=None, floatmode=None, legacy=None): + """ make a dictionary out of the non-None arguments, plus sanity checks """ + + options = {k: v for k, v in locals().items() if v is not None} + + if suppress is not None: + options['suppress'] = bool(suppress) + + modes = ['fixed', 'unique', 'maxprec', 'maxprec_equal'] + if floatmode not in modes + [None]: + raise ValueError("floatmode option must be one of " + + ", ".join('"{}"'.format(m) for m in modes)) + + if sign not in [None, '-', '+', ' ']: + raise ValueError("sign option must be one of ' ', '+', or '-'") + + if legacy not in [None, False, '1.13']: + warnings.warn("legacy printing option can currently only be '1.13' or " + "`False`", stacklevel=3) + if threshold is not None: + # forbid the bad threshold arg suggested by stack overflow, gh-12351 + if not isinstance(threshold, numbers.Number): + raise TypeError("threshold must be numeric") + if np.isnan(threshold): + raise ValueError("threshold must be non-NAN, try " + "sys.maxsize for untruncated representation") + return options + + +@set_module('numpy') +def set_printoptions(precision=None, threshold=None, edgeitems=None, + linewidth=None, suppress=None, nanstr=None, infstr=None, + formatter=None, sign=None, floatmode=None, *, legacy=None): + """ + Set printing options. + + These options determine the way floating point numbers, arrays and + other NumPy objects are displayed. + + Parameters + ---------- + precision : int or None, optional + Number of digits of precision for floating point output (default 8). + May be None if `floatmode` is not `fixed`, to print as many digits as + necessary to uniquely specify the value. + threshold : int, optional + Total number of array elements which trigger summarization + rather than full repr (default 1000). + To always use the full repr without summarization, pass `sys.maxsize`. + edgeitems : int, optional + Number of array items in summary at beginning and end of + each dimension (default 3). + linewidth : int, optional + The number of characters per line for the purpose of inserting + line breaks (default 75). + suppress : bool, optional + If True, always print floating point numbers using fixed point + notation, in which case numbers equal to zero in the current precision + will print as zero. If False, then scientific notation is used when + absolute value of the smallest number is < 1e-4 or the ratio of the + maximum absolute value to the minimum is > 1e3. The default is False. + nanstr : str, optional + String representation of floating point not-a-number (default nan). + infstr : str, optional + String representation of floating point infinity (default inf). + sign : string, either '-', '+', or ' ', optional + Controls printing of the sign of floating-point types. If '+', always + print the sign of positive values. If ' ', always prints a space + (whitespace character) in the sign position of positive values. If + '-', omit the sign character of positive values. (default '-') + formatter : dict of callables, optional + If not None, the keys should indicate the type(s) that the respective + formatting function applies to. Callables should return a string. + Types that are not specified (by their corresponding keys) are handled + by the default formatters. Individual types for which a formatter + can be set are: + + - 'bool' + - 'int' + - 'timedelta' : a `numpy.timedelta64` + - 'datetime' : a `numpy.datetime64` + - 'float' + - 'longfloat' : 128-bit floats + - 'complexfloat' + - 'longcomplexfloat' : composed of two 128-bit floats + - 'numpystr' : types `numpy.string_` and `numpy.unicode_` + - 'object' : `np.object_` arrays + - 'str' : all other strings + + Other keys that can be used to set a group of types at once are: + + - 'all' : sets all types + - 'int_kind' : sets 'int' + - 'float_kind' : sets 'float' and 'longfloat' + - 'complex_kind' : sets 'complexfloat' and 'longcomplexfloat' + - 'str_kind' : sets 'str' and 'numpystr' + floatmode : str, optional + Controls the interpretation of the `precision` option for + floating-point types. Can take the following values + (default maxprec_equal): + + * 'fixed': Always print exactly `precision` fractional digits, + even if this would print more or fewer digits than + necessary to specify the value uniquely. + * 'unique': Print the minimum number of fractional digits necessary + to represent each value uniquely. Different elements may + have a different number of digits. The value of the + `precision` option is ignored. + * 'maxprec': Print at most `precision` fractional digits, but if + an element can be uniquely represented with fewer digits + only print it with that many. + * 'maxprec_equal': Print at most `precision` fractional digits, + but if every element in the array can be uniquely + represented with an equal number of fewer digits, use that + many digits for all elements. + legacy : string or `False`, optional + If set to the string `'1.13'` enables 1.13 legacy printing mode. This + approximates numpy 1.13 print output by including a space in the sign + position of floats and different behavior for 0d arrays. If set to + `False`, disables legacy mode. Unrecognized strings will be ignored + with a warning for forward compatibility. + + .. versionadded:: 1.14.0 + + See Also + -------- + get_printoptions, printoptions, set_string_function, array2string + + Notes + ----- + `formatter` is always reset with a call to `set_printoptions`. + + Use `printoptions` as a context manager to set the values temporarily. + + Examples + -------- + Floating point precision can be set: + + >>> np.set_printoptions(precision=4) + >>> np.array([1.123456789]) + [1.1235] + + Long arrays can be summarised: + + >>> np.set_printoptions(threshold=5) + >>> np.arange(10) + array([0, 1, 2, ..., 7, 8, 9]) + + Small results can be suppressed: + + >>> eps = np.finfo(float).eps + >>> x = np.arange(4.) + >>> x**2 - (x + eps)**2 + array([-4.9304e-32, -4.4409e-16, 0.0000e+00, 0.0000e+00]) + >>> np.set_printoptions(suppress=True) + >>> x**2 - (x + eps)**2 + array([-0., -0., 0., 0.]) + + A custom formatter can be used to display array elements as desired: + + >>> np.set_printoptions(formatter={'all':lambda x: 'int: '+str(-x)}) + >>> x = np.arange(3) + >>> x + array([int: 0, int: -1, int: -2]) + >>> np.set_printoptions() # formatter gets reset + >>> x + array([0, 1, 2]) + + To put back the default options, you can use: + + >>> np.set_printoptions(edgeitems=3, infstr='inf', + ... linewidth=75, nanstr='nan', precision=8, + ... suppress=False, threshold=1000, formatter=None) + + Also to temporarily override options, use `printoptions` as a context manager: + + >>> with np.printoptions(precision=2, suppress=True, threshold=5): + ... np.linspace(0, 10, 10) + array([ 0. , 1.11, 2.22, ..., 7.78, 8.89, 10. ]) + + """ + opt = _make_options_dict(precision, threshold, edgeitems, linewidth, + suppress, nanstr, infstr, sign, formatter, + floatmode, legacy) + # formatter is always reset + opt['formatter'] = formatter + _format_options.update(opt) + + # set the C variable for legacy mode + if _format_options['legacy'] == '1.13': + set_legacy_print_mode(113) + # reset the sign option in legacy mode to avoid confusion + _format_options['sign'] = '-' + elif _format_options['legacy'] is False: + set_legacy_print_mode(0) + + +@set_module('numpy') +def get_printoptions(): + """ + Return the current print options. + + Returns + ------- + print_opts : dict + Dictionary of current print options with keys + + - precision : int + - threshold : int + - edgeitems : int + - linewidth : int + - suppress : bool + - nanstr : str + - infstr : str + - formatter : dict of callables + - sign : str + + For a full description of these options, see `set_printoptions`. + + See Also + -------- + set_printoptions, printoptions, set_string_function + + """ + return _format_options.copy() + + +@set_module('numpy') +@contextlib.contextmanager +def printoptions(*args, **kwargs): + """Context manager for setting print options. + + Set print options for the scope of the `with` block, and restore the old + options at the end. See `set_printoptions` for the full description of + available options. + + Examples + -------- + + >>> from numpy.testing import assert_equal + >>> with np.printoptions(precision=2): + ... np.array([2.0]) / 3 + array([0.67]) + + The `as`-clause of the `with`-statement gives the current print options: + + >>> with np.printoptions(precision=2) as opts: + ... assert_equal(opts, np.get_printoptions()) + + See Also + -------- + set_printoptions, get_printoptions + + """ + opts = np.get_printoptions() + try: + np.set_printoptions(*args, **kwargs) + yield np.get_printoptions() + finally: + np.set_printoptions(**opts) + + +def _leading_trailing(a, edgeitems, index=()): + """ + Keep only the N-D corners (leading and trailing edges) of an array. + + Should be passed a base-class ndarray, since it makes no guarantees about + preserving subclasses. + """ + axis = len(index) + if axis == a.ndim: + return a[index] + + if a.shape[axis] > 2*edgeitems: + return concatenate(( + _leading_trailing(a, edgeitems, index + np.index_exp[ :edgeitems]), + _leading_trailing(a, edgeitems, index + np.index_exp[-edgeitems:]) + ), axis=axis) + else: + return _leading_trailing(a, edgeitems, index + np.index_exp[:]) + + +def _object_format(o): + """ Object arrays containing lists should be printed unambiguously """ + if type(o) is list: + fmt = 'list({!r})' + else: + fmt = '{!r}' + return fmt.format(o) + +def repr_format(x): + return repr(x) + +def str_format(x): + return str(x) + +def _get_formatdict(data, *, precision, floatmode, suppress, sign, legacy, + formatter, **kwargs): + # note: extra arguments in kwargs are ignored + + # wrapped in lambdas to avoid taking a code path with the wrong type of data + formatdict = { + 'bool': lambda: BoolFormat(data), + 'int': lambda: IntegerFormat(data), + 'float': lambda: FloatingFormat( + data, precision, floatmode, suppress, sign, legacy=legacy), + 'longfloat': lambda: FloatingFormat( + data, precision, floatmode, suppress, sign, legacy=legacy), + 'complexfloat': lambda: ComplexFloatingFormat( + data, precision, floatmode, suppress, sign, legacy=legacy), + 'longcomplexfloat': lambda: ComplexFloatingFormat( + data, precision, floatmode, suppress, sign, legacy=legacy), + 'datetime': lambda: DatetimeFormat(data, legacy=legacy), + 'timedelta': lambda: TimedeltaFormat(data), + 'object': lambda: _object_format, + 'void': lambda: str_format, + 'numpystr': lambda: repr_format, + 'str': lambda: str} + + # we need to wrap values in `formatter` in a lambda, so that the interface + # is the same as the above values. + def indirect(x): + return lambda: x + + if formatter is not None: + fkeys = [k for k in formatter.keys() if formatter[k] is not None] + if 'all' in fkeys: + for key in formatdict.keys(): + formatdict[key] = indirect(formatter['all']) + if 'int_kind' in fkeys: + for key in ['int']: + formatdict[key] = indirect(formatter['int_kind']) + if 'float_kind' in fkeys: + for key in ['float', 'longfloat']: + formatdict[key] = indirect(formatter['float_kind']) + if 'complex_kind' in fkeys: + for key in ['complexfloat', 'longcomplexfloat']: + formatdict[key] = indirect(formatter['complex_kind']) + if 'str_kind' in fkeys: + for key in ['numpystr', 'str']: + formatdict[key] = indirect(formatter['str_kind']) + for key in formatdict.keys(): + if key in fkeys: + formatdict[key] = indirect(formatter[key]) + + return formatdict + +def _get_format_function(data, **options): + """ + find the right formatting function for the dtype_ + """ + dtype_ = data.dtype + dtypeobj = dtype_.type + formatdict = _get_formatdict(data, **options) + if issubclass(dtypeobj, _nt.bool_): + return formatdict['bool']() + elif issubclass(dtypeobj, _nt.integer): + if issubclass(dtypeobj, _nt.timedelta64): + return formatdict['timedelta']() + else: + return formatdict['int']() + elif issubclass(dtypeobj, _nt.floating): + if issubclass(dtypeobj, _nt.longfloat): + return formatdict['longfloat']() + else: + return formatdict['float']() + elif issubclass(dtypeobj, _nt.complexfloating): + if issubclass(dtypeobj, _nt.clongfloat): + return formatdict['longcomplexfloat']() + else: + return formatdict['complexfloat']() + elif issubclass(dtypeobj, (_nt.unicode_, _nt.string_)): + return formatdict['numpystr']() + elif issubclass(dtypeobj, _nt.datetime64): + return formatdict['datetime']() + elif issubclass(dtypeobj, _nt.object_): + return formatdict['object']() + elif issubclass(dtypeobj, _nt.void): + if dtype_.names is not None: + return StructuredVoidFormat.from_data(data, **options) + else: + return formatdict['void']() + else: + return formatdict['numpystr']() + + +def _recursive_guard(fillvalue='...'): + """ + Like the python 3.2 reprlib.recursive_repr, but forwards *args and **kwargs + + Decorates a function such that if it calls itself with the same first + argument, it returns `fillvalue` instead of recursing. + + Largely copied from reprlib.recursive_repr + """ + + def decorating_function(f): + repr_running = set() + + @functools.wraps(f) + def wrapper(self, *args, **kwargs): + key = id(self), get_ident() + if key in repr_running: + return fillvalue + repr_running.add(key) + try: + return f(self, *args, **kwargs) + finally: + repr_running.discard(key) + + return wrapper + + return decorating_function + + +# gracefully handle recursive calls, when object arrays contain themselves +@_recursive_guard() +def _array2string(a, options, separator=' ', prefix=""): + # The formatter __init__s in _get_format_function cannot deal with + # subclasses yet, and we also need to avoid recursion issues in + # _formatArray with subclasses which return 0d arrays in place of scalars + data = asarray(a) + if a.shape == (): + a = data + + if a.size > options['threshold']: + summary_insert = "..." + data = _leading_trailing(data, options['edgeitems']) + else: + summary_insert = "" + + # find the right formatting function for the array + format_function = _get_format_function(data, **options) + + # skip over "[" + next_line_prefix = " " + # skip over array( + next_line_prefix += " "*len(prefix) + + lst = _formatArray(a, format_function, options['linewidth'], + next_line_prefix, separator, options['edgeitems'], + summary_insert, options['legacy']) + return lst + + +def _array2string_dispatcher( + a, max_line_width=None, precision=None, + suppress_small=None, separator=None, prefix=None, + style=None, formatter=None, threshold=None, + edgeitems=None, sign=None, floatmode=None, suffix=None, + *, legacy=None): + return (a,) + + +@array_function_dispatch(_array2string_dispatcher, module='numpy') +def array2string(a, max_line_width=None, precision=None, + suppress_small=None, separator=' ', prefix="", + style=np._NoValue, formatter=None, threshold=None, + edgeitems=None, sign=None, floatmode=None, suffix="", + *, legacy=None): + """ + Return a string representation of an array. + + Parameters + ---------- + a : array_like + Input array. + max_line_width : int, optional + Inserts newlines if text is longer than `max_line_width`. + Defaults to ``numpy.get_printoptions()['linewidth']``. + precision : int or None, optional + Floating point precision. + Defaults to ``numpy.get_printoptions()['precision']``. + suppress_small : bool, optional + Represent numbers "very close" to zero as zero; default is False. + Very close is defined by precision: if the precision is 8, e.g., + numbers smaller (in absolute value) than 5e-9 are represented as + zero. + Defaults to ``numpy.get_printoptions()['suppress']``. + separator : str, optional + Inserted between elements. + prefix : str, optional + suffix: str, optional + The length of the prefix and suffix strings are used to respectively + align and wrap the output. An array is typically printed as:: + + prefix + array2string(a) + suffix + + The output is left-padded by the length of the prefix string, and + wrapping is forced at the column ``max_line_width - len(suffix)``. + It should be noted that the content of prefix and suffix strings are + not included in the output. + style : _NoValue, optional + Has no effect, do not use. + + .. deprecated:: 1.14.0 + formatter : dict of callables, optional + If not None, the keys should indicate the type(s) that the respective + formatting function applies to. Callables should return a string. + Types that are not specified (by their corresponding keys) are handled + by the default formatters. Individual types for which a formatter + can be set are: + + - 'bool' + - 'int' + - 'timedelta' : a `numpy.timedelta64` + - 'datetime' : a `numpy.datetime64` + - 'float' + - 'longfloat' : 128-bit floats + - 'complexfloat' + - 'longcomplexfloat' : composed of two 128-bit floats + - 'void' : type `numpy.void` + - 'numpystr' : types `numpy.string_` and `numpy.unicode_` + - 'str' : all other strings + + Other keys that can be used to set a group of types at once are: + + - 'all' : sets all types + - 'int_kind' : sets 'int' + - 'float_kind' : sets 'float' and 'longfloat' + - 'complex_kind' : sets 'complexfloat' and 'longcomplexfloat' + - 'str_kind' : sets 'str' and 'numpystr' + threshold : int, optional + Total number of array elements which trigger summarization + rather than full repr. + Defaults to ``numpy.get_printoptions()['threshold']``. + edgeitems : int, optional + Number of array items in summary at beginning and end of + each dimension. + Defaults to ``numpy.get_printoptions()['edgeitems']``. + sign : string, either '-', '+', or ' ', optional + Controls printing of the sign of floating-point types. If '+', always + print the sign of positive values. If ' ', always prints a space + (whitespace character) in the sign position of positive values. If + '-', omit the sign character of positive values. + Defaults to ``numpy.get_printoptions()['sign']``. + floatmode : str, optional + Controls the interpretation of the `precision` option for + floating-point types. + Defaults to ``numpy.get_printoptions()['floatmode']``. + Can take the following values: + + - 'fixed': Always print exactly `precision` fractional digits, + even if this would print more or fewer digits than + necessary to specify the value uniquely. + - 'unique': Print the minimum number of fractional digits necessary + to represent each value uniquely. Different elements may + have a different number of digits. The value of the + `precision` option is ignored. + - 'maxprec': Print at most `precision` fractional digits, but if + an element can be uniquely represented with fewer digits + only print it with that many. + - 'maxprec_equal': Print at most `precision` fractional digits, + but if every element in the array can be uniquely + represented with an equal number of fewer digits, use that + many digits for all elements. + legacy : string or `False`, optional + If set to the string `'1.13'` enables 1.13 legacy printing mode. This + approximates numpy 1.13 print output by including a space in the sign + position of floats and different behavior for 0d arrays. If set to + `False`, disables legacy mode. Unrecognized strings will be ignored + with a warning for forward compatibility. + + .. versionadded:: 1.14.0 + + Returns + ------- + array_str : str + String representation of the array. + + Raises + ------ + TypeError + if a callable in `formatter` does not return a string. + + See Also + -------- + array_str, array_repr, set_printoptions, get_printoptions + + Notes + ----- + If a formatter is specified for a certain type, the `precision` keyword is + ignored for that type. + + This is a very flexible function; `array_repr` and `array_str` are using + `array2string` internally so keywords with the same name should work + identically in all three functions. + + Examples + -------- + >>> x = np.array([1e-16,1,2,3]) + >>> np.array2string(x, precision=2, separator=',', + ... suppress_small=True) + '[0.,1.,2.,3.]' + + >>> x = np.arange(3.) + >>> np.array2string(x, formatter={'float_kind':lambda x: "%.2f" % x}) + '[0.00 1.00 2.00]' + + >>> x = np.arange(3) + >>> np.array2string(x, formatter={'int':lambda x: hex(x)}) + '[0x0 0x1 0x2]' + + """ + + overrides = _make_options_dict(precision, threshold, edgeitems, + max_line_width, suppress_small, None, None, + sign, formatter, floatmode, legacy) + options = _format_options.copy() + options.update(overrides) + + if options['legacy'] == '1.13': + if style is np._NoValue: + style = repr + + if a.shape == () and a.dtype.names is None: + return style(a.item()) + elif style is not np._NoValue: + # Deprecation 11-9-2017 v1.14 + warnings.warn("'style' argument is deprecated and no longer functional" + " except in 1.13 'legacy' mode", + DeprecationWarning, stacklevel=3) + + if options['legacy'] != '1.13': + options['linewidth'] -= len(suffix) + + # treat as a null array if any of shape elements == 0 + if a.size == 0: + return "[]" + + return _array2string(a, options, separator, prefix) + + +def _extendLine(s, line, word, line_width, next_line_prefix, legacy): + needs_wrap = len(line) + len(word) > line_width + if legacy != '1.13': + # don't wrap lines if it won't help + if len(line) <= len(next_line_prefix): + needs_wrap = False + + if needs_wrap: + s += line.rstrip() + "\n" + line = next_line_prefix + line += word + return s, line + + +def _extendLine_pretty(s, line, word, line_width, next_line_prefix, legacy): + """ + Extends line with nicely formatted (possibly multi-line) string ``word``. + """ + words = word.splitlines() + if len(words) == 1 or legacy == '1.13': + return _extendLine(s, line, word, line_width, next_line_prefix, legacy) + + max_word_length = max(len(word) for word in words) + if (len(line) + max_word_length > line_width and + len(line) > len(next_line_prefix)): + s += line.rstrip() + '\n' + line = next_line_prefix + words[0] + indent = next_line_prefix + else: + indent = len(line)*' ' + line += words[0] + + for word in words[1::]: + s += line.rstrip() + '\n' + line = indent + word + + suffix_length = max_word_length - len(words[-1]) + line += suffix_length*' ' + + return s, line + +def _formatArray(a, format_function, line_width, next_line_prefix, + separator, edge_items, summary_insert, legacy): + """formatArray is designed for two modes of operation: + + 1. Full output + + 2. Summarized output + + """ + def recurser(index, hanging_indent, curr_width): + """ + By using this local function, we don't need to recurse with all the + arguments. Since this function is not created recursively, the cost is + not significant + """ + axis = len(index) + axes_left = a.ndim - axis + + if axes_left == 0: + return format_function(a[index]) + + # when recursing, add a space to align with the [ added, and reduce the + # length of the line by 1 + next_hanging_indent = hanging_indent + ' ' + if legacy == '1.13': + next_width = curr_width + else: + next_width = curr_width - len(']') + + a_len = a.shape[axis] + show_summary = summary_insert and 2*edge_items < a_len + if show_summary: + leading_items = edge_items + trailing_items = edge_items + else: + leading_items = 0 + trailing_items = a_len + + # stringify the array with the hanging indent on the first line too + s = '' + + # last axis (rows) - wrap elements if they would not fit on one line + if axes_left == 1: + # the length up until the beginning of the separator / bracket + if legacy == '1.13': + elem_width = curr_width - len(separator.rstrip()) + else: + elem_width = curr_width - max(len(separator.rstrip()), len(']')) + + line = hanging_indent + for i in range(leading_items): + word = recurser(index + (i,), next_hanging_indent, next_width) + s, line = _extendLine_pretty( + s, line, word, elem_width, hanging_indent, legacy) + line += separator + + if show_summary: + s, line = _extendLine( + s, line, summary_insert, elem_width, hanging_indent, legacy) + if legacy == '1.13': + line += ", " + else: + line += separator + + for i in range(trailing_items, 1, -1): + word = recurser(index + (-i,), next_hanging_indent, next_width) + s, line = _extendLine_pretty( + s, line, word, elem_width, hanging_indent, legacy) + line += separator + + if legacy == '1.13': + # width of the separator is not considered on 1.13 + elem_width = curr_width + word = recurser(index + (-1,), next_hanging_indent, next_width) + s, line = _extendLine_pretty( + s, line, word, elem_width, hanging_indent, legacy) + + s += line + + # other axes - insert newlines between rows + else: + s = '' + line_sep = separator.rstrip() + '\n'*(axes_left - 1) + + for i in range(leading_items): + nested = recurser(index + (i,), next_hanging_indent, next_width) + s += hanging_indent + nested + line_sep + + if show_summary: + if legacy == '1.13': + # trailing space, fixed nbr of newlines, and fixed separator + s += hanging_indent + summary_insert + ", \n" + else: + s += hanging_indent + summary_insert + line_sep + + for i in range(trailing_items, 1, -1): + nested = recurser(index + (-i,), next_hanging_indent, + next_width) + s += hanging_indent + nested + line_sep + + nested = recurser(index + (-1,), next_hanging_indent, next_width) + s += hanging_indent + nested + + # remove the hanging indent, and wrap in [] + s = '[' + s[len(hanging_indent):] + ']' + return s + + try: + # invoke the recursive part with an initial index and prefix + return recurser(index=(), + hanging_indent=next_line_prefix, + curr_width=line_width) + finally: + # recursive closures have a cyclic reference to themselves, which + # requires gc to collect (gh-10620). To avoid this problem, for + # performance and PyPy friendliness, we break the cycle: + recurser = None + +def _none_or_positive_arg(x, name): + if x is None: + return -1 + if x < 0: + raise ValueError("{} must be >= 0".format(name)) + return x + +class FloatingFormat: + """ Formatter for subtypes of np.floating """ + def __init__(self, data, precision, floatmode, suppress_small, sign=False, + *, legacy=None): + # for backcompatibility, accept bools + if isinstance(sign, bool): + sign = '+' if sign else '-' + + self._legacy = legacy + if self._legacy == '1.13': + # when not 0d, legacy does not support '-' + if data.shape != () and sign == '-': + sign = ' ' + + self.floatmode = floatmode + if floatmode == 'unique': + self.precision = None + else: + self.precision = precision + + self.precision = _none_or_positive_arg(self.precision, 'precision') + + self.suppress_small = suppress_small + self.sign = sign + self.exp_format = False + self.large_exponent = False + + self.fillFormat(data) + + def fillFormat(self, data): + # only the finite values are used to compute the number of digits + finite_vals = data[isfinite(data)] + + # choose exponential mode based on the non-zero finite values: + abs_non_zero = absolute(finite_vals[finite_vals != 0]) + if len(abs_non_zero) != 0: + max_val = np.max(abs_non_zero) + min_val = np.min(abs_non_zero) + with errstate(over='ignore'): # division can overflow + if max_val >= 1.e8 or (not self.suppress_small and + (min_val < 0.0001 or max_val/min_val > 1000.)): + self.exp_format = True + + # do a first pass of printing all the numbers, to determine sizes + if len(finite_vals) == 0: + self.pad_left = 0 + self.pad_right = 0 + self.trim = '.' + self.exp_size = -1 + self.unique = True + elif self.exp_format: + trim, unique = '.', True + if self.floatmode == 'fixed' or self._legacy == '1.13': + trim, unique = 'k', False + strs = (dragon4_scientific(x, precision=self.precision, + unique=unique, trim=trim, sign=self.sign == '+') + for x in finite_vals) + frac_strs, _, exp_strs = zip(*(s.partition('e') for s in strs)) + int_part, frac_part = zip(*(s.split('.') for s in frac_strs)) + self.exp_size = max(len(s) for s in exp_strs) - 1 + + self.trim = 'k' + self.precision = max(len(s) for s in frac_part) + + # for back-compat with np 1.13, use 2 spaces & sign and full prec + if self._legacy == '1.13': + self.pad_left = 3 + else: + # this should be only 1 or 2. Can be calculated from sign. + self.pad_left = max(len(s) for s in int_part) + # pad_right is only needed for nan length calculation + self.pad_right = self.exp_size + 2 + self.precision + + self.unique = False + else: + # first pass printing to determine sizes + trim, unique = '.', True + if self.floatmode == 'fixed': + trim, unique = 'k', False + strs = (dragon4_positional(x, precision=self.precision, + fractional=True, + unique=unique, trim=trim, + sign=self.sign == '+') + for x in finite_vals) + int_part, frac_part = zip(*(s.split('.') for s in strs)) + if self._legacy == '1.13': + self.pad_left = 1 + max(len(s.lstrip('-+')) for s in int_part) + else: + self.pad_left = max(len(s) for s in int_part) + self.pad_right = max(len(s) for s in frac_part) + self.exp_size = -1 + + if self.floatmode in ['fixed', 'maxprec_equal']: + self.precision = self.pad_right + self.unique = False + self.trim = 'k' + else: + self.unique = True + self.trim = '.' + + if self._legacy != '1.13': + # account for sign = ' ' by adding one to pad_left + if self.sign == ' ' and not any(np.signbit(finite_vals)): + self.pad_left += 1 + + # if there are non-finite values, may need to increase pad_left + if data.size != finite_vals.size: + neginf = self.sign != '-' or any(data[isinf(data)] < 0) + nanlen = len(_format_options['nanstr']) + inflen = len(_format_options['infstr']) + neginf + offset = self.pad_right + 1 # +1 for decimal pt + self.pad_left = max(self.pad_left, nanlen - offset, inflen - offset) + + def __call__(self, x): + if not np.isfinite(x): + with errstate(invalid='ignore'): + if np.isnan(x): + sign = '+' if self.sign == '+' else '' + ret = sign + _format_options['nanstr'] + else: # isinf + sign = '-' if x < 0 else '+' if self.sign == '+' else '' + ret = sign + _format_options['infstr'] + return ' '*(self.pad_left + self.pad_right + 1 - len(ret)) + ret + + if self.exp_format: + return dragon4_scientific(x, + precision=self.precision, + unique=self.unique, + trim=self.trim, + sign=self.sign == '+', + pad_left=self.pad_left, + exp_digits=self.exp_size) + else: + return dragon4_positional(x, + precision=self.precision, + unique=self.unique, + fractional=True, + trim=self.trim, + sign=self.sign == '+', + pad_left=self.pad_left, + pad_right=self.pad_right) + + +@set_module('numpy') +def format_float_scientific(x, precision=None, unique=True, trim='k', + sign=False, pad_left=None, exp_digits=None): + """ + Format a floating-point scalar as a decimal string in scientific notation. + + Provides control over rounding, trimming and padding. Uses and assumes + IEEE unbiased rounding. Uses the "Dragon4" algorithm. + + Parameters + ---------- + x : python float or numpy floating scalar + Value to format. + precision : non-negative integer or None, optional + Maximum number of digits to print. May be None if `unique` is + `True`, but must be an integer if unique is `False`. + unique : boolean, optional + If `True`, use a digit-generation strategy which gives the shortest + representation which uniquely identifies the floating-point number from + other values of the same type, by judicious rounding. If `precision` + was omitted, print all necessary digits, otherwise digit generation is + cut off after `precision` digits and the remaining value is rounded. + If `False`, digits are generated as if printing an infinite-precision + value and stopping after `precision` digits, rounding the remaining + value. + trim : one of 'k', '.', '0', '-', optional + Controls post-processing trimming of trailing digits, as follows: + + * 'k' : keep trailing zeros, keep decimal point (no trimming) + * '.' : trim all trailing zeros, leave decimal point + * '0' : trim all but the zero before the decimal point. Insert the + zero if it is missing. + * '-' : trim trailing zeros and any trailing decimal point + sign : boolean, optional + Whether to show the sign for positive values. + pad_left : non-negative integer, optional + Pad the left side of the string with whitespace until at least that + many characters are to the left of the decimal point. + exp_digits : non-negative integer, optional + Pad the exponent with zeros until it contains at least this many digits. + If omitted, the exponent will be at least 2 digits. + + Returns + ------- + rep : string + The string representation of the floating point value + + See Also + -------- + format_float_positional + + Examples + -------- + >>> np.format_float_scientific(np.float32(np.pi)) + '3.1415927e+00' + >>> s = np.float32(1.23e24) + >>> np.format_float_scientific(s, unique=False, precision=15) + '1.230000071797338e+24' + >>> np.format_float_scientific(s, exp_digits=4) + '1.23e+0024' + """ + precision = _none_or_positive_arg(precision, 'precision') + pad_left = _none_or_positive_arg(pad_left, 'pad_left') + exp_digits = _none_or_positive_arg(exp_digits, 'exp_digits') + return dragon4_scientific(x, precision=precision, unique=unique, + trim=trim, sign=sign, pad_left=pad_left, + exp_digits=exp_digits) + + +@set_module('numpy') +def format_float_positional(x, precision=None, unique=True, + fractional=True, trim='k', sign=False, + pad_left=None, pad_right=None): + """ + Format a floating-point scalar as a decimal string in positional notation. + + Provides control over rounding, trimming and padding. Uses and assumes + IEEE unbiased rounding. Uses the "Dragon4" algorithm. + + Parameters + ---------- + x : python float or numpy floating scalar + Value to format. + precision : non-negative integer or None, optional + Maximum number of digits to print. May be None if `unique` is + `True`, but must be an integer if unique is `False`. + unique : boolean, optional + If `True`, use a digit-generation strategy which gives the shortest + representation which uniquely identifies the floating-point number from + other values of the same type, by judicious rounding. If `precision` + was omitted, print out all necessary digits, otherwise digit generation + is cut off after `precision` digits and the remaining value is rounded. + If `False`, digits are generated as if printing an infinite-precision + value and stopping after `precision` digits, rounding the remaining + value. + fractional : boolean, optional + If `True`, the cutoff of `precision` digits refers to the total number + of digits after the decimal point, including leading zeros. + If `False`, `precision` refers to the total number of significant + digits, before or after the decimal point, ignoring leading zeros. + trim : one of 'k', '.', '0', '-', optional + Controls post-processing trimming of trailing digits, as follows: + + * 'k' : keep trailing zeros, keep decimal point (no trimming) + * '.' : trim all trailing zeros, leave decimal point + * '0' : trim all but the zero before the decimal point. Insert the + zero if it is missing. + * '-' : trim trailing zeros and any trailing decimal point + sign : boolean, optional + Whether to show the sign for positive values. + pad_left : non-negative integer, optional + Pad the left side of the string with whitespace until at least that + many characters are to the left of the decimal point. + pad_right : non-negative integer, optional + Pad the right side of the string with whitespace until at least that + many characters are to the right of the decimal point. + + Returns + ------- + rep : string + The string representation of the floating point value + + See Also + -------- + format_float_scientific + + Examples + -------- + >>> np.format_float_positional(np.float32(np.pi)) + '3.1415927' + >>> np.format_float_positional(np.float16(np.pi)) + '3.14' + >>> np.format_float_positional(np.float16(0.3)) + '0.3' + >>> np.format_float_positional(np.float16(0.3), unique=False, precision=10) + '0.3000488281' + """ + precision = _none_or_positive_arg(precision, 'precision') + pad_left = _none_or_positive_arg(pad_left, 'pad_left') + pad_right = _none_or_positive_arg(pad_right, 'pad_right') + return dragon4_positional(x, precision=precision, unique=unique, + fractional=fractional, trim=trim, + sign=sign, pad_left=pad_left, + pad_right=pad_right) + + +class IntegerFormat: + def __init__(self, data): + if data.size > 0: + max_str_len = max(len(str(np.max(data))), + len(str(np.min(data)))) + else: + max_str_len = 0 + self.format = '%{}d'.format(max_str_len) + + def __call__(self, x): + return self.format % x + + +class BoolFormat: + def __init__(self, data, **kwargs): + # add an extra space so " True" and "False" have the same length and + # array elements align nicely when printed, except in 0d arrays + self.truestr = ' True' if data.shape != () else 'True' + + def __call__(self, x): + return self.truestr if x else "False" + + +class ComplexFloatingFormat: + """ Formatter for subtypes of np.complexfloating """ + def __init__(self, x, precision, floatmode, suppress_small, + sign=False, *, legacy=None): + # for backcompatibility, accept bools + if isinstance(sign, bool): + sign = '+' if sign else '-' + + floatmode_real = floatmode_imag = floatmode + if legacy == '1.13': + floatmode_real = 'maxprec_equal' + floatmode_imag = 'maxprec' + + self.real_format = FloatingFormat( + x.real, precision, floatmode_real, suppress_small, + sign=sign, legacy=legacy + ) + self.imag_format = FloatingFormat( + x.imag, precision, floatmode_imag, suppress_small, + sign='+', legacy=legacy + ) + + def __call__(self, x): + r = self.real_format(x.real) + i = self.imag_format(x.imag) + + # add the 'j' before the terminal whitespace in i + sp = len(i.rstrip()) + i = i[:sp] + 'j' + i[sp:] + + return r + i + + +class _TimelikeFormat: + def __init__(self, data): + non_nat = data[~isnat(data)] + if len(non_nat) > 0: + # Max str length of non-NaT elements + max_str_len = max(len(self._format_non_nat(np.max(non_nat))), + len(self._format_non_nat(np.min(non_nat)))) + else: + max_str_len = 0 + if len(non_nat) < data.size: + # data contains a NaT + max_str_len = max(max_str_len, 5) + self._format = '%{}s'.format(max_str_len) + self._nat = "'NaT'".rjust(max_str_len) + + def _format_non_nat(self, x): + # override in subclass + raise NotImplementedError + + def __call__(self, x): + if isnat(x): + return self._nat + else: + return self._format % self._format_non_nat(x) + + +class DatetimeFormat(_TimelikeFormat): + def __init__(self, x, unit=None, timezone=None, casting='same_kind', + legacy=False): + # Get the unit from the dtype + if unit is None: + if x.dtype.kind == 'M': + unit = datetime_data(x.dtype)[0] + else: + unit = 's' + + if timezone is None: + timezone = 'naive' + self.timezone = timezone + self.unit = unit + self.casting = casting + self.legacy = legacy + + # must be called after the above are configured + super(DatetimeFormat, self).__init__(x) + + def __call__(self, x): + if self.legacy == '1.13': + return self._format_non_nat(x) + return super(DatetimeFormat, self).__call__(x) + + def _format_non_nat(self, x): + return "'%s'" % datetime_as_string(x, + unit=self.unit, + timezone=self.timezone, + casting=self.casting) + + +class TimedeltaFormat(_TimelikeFormat): + def _format_non_nat(self, x): + return str(x.astype('i8')) + + +class SubArrayFormat: + def __init__(self, format_function): + self.format_function = format_function + + def __call__(self, arr): + if arr.ndim <= 1: + return "[" + ", ".join(self.format_function(a) for a in arr) + "]" + return "[" + ", ".join(self.__call__(a) for a in arr) + "]" + + +class StructuredVoidFormat: + """ + Formatter for structured np.void objects. + + This does not work on structured alias types like np.dtype(('i4', 'i2,i2')), + as alias scalars lose their field information, and the implementation + relies upon np.void.__getitem__. + """ + def __init__(self, format_functions): + self.format_functions = format_functions + + @classmethod + def from_data(cls, data, **options): + """ + This is a second way to initialize StructuredVoidFormat, using the raw data + as input. Added to avoid changing the signature of __init__. + """ + format_functions = [] + for field_name in data.dtype.names: + format_function = _get_format_function(data[field_name], **options) + if data.dtype[field_name].shape != (): + format_function = SubArrayFormat(format_function) + format_functions.append(format_function) + return cls(format_functions) + + def __call__(self, x): + str_fields = [ + format_function(field) + for field, format_function in zip(x, self.format_functions) + ] + if len(str_fields) == 1: + return "({},)".format(str_fields[0]) + else: + return "({})".format(", ".join(str_fields)) + + +def _void_scalar_repr(x): + """ + Implements the repr for structured-void scalars. It is called from the + scalartypes.c.src code, and is placed here because it uses the elementwise + formatters defined above. + """ + return StructuredVoidFormat.from_data(array(x), **_format_options)(x) + + +_typelessdata = [int_, float_, complex_, bool_] +if issubclass(intc, int): + _typelessdata.append(intc) +if issubclass(longlong, int): + _typelessdata.append(longlong) + + +def dtype_is_implied(dtype): + """ + Determine if the given dtype is implied by the representation of its values. + + Parameters + ---------- + dtype : dtype + Data type + + Returns + ------- + implied : bool + True if the dtype is implied by the representation of its values. + + Examples + -------- + >>> np.core.arrayprint.dtype_is_implied(int) + True + >>> np.array([1, 2, 3], int) + array([1, 2, 3]) + >>> np.core.arrayprint.dtype_is_implied(np.int8) + False + >>> np.array([1, 2, 3], np.int8) + array([1, 2, 3], dtype=int8) + """ + dtype = np.dtype(dtype) + if _format_options['legacy'] == '1.13' and dtype.type == bool_: + return False + + # not just void types can be structured, and names are not part of the repr + if dtype.names is not None: + return False + + return dtype.type in _typelessdata + + +def dtype_short_repr(dtype): + """ + Convert a dtype to a short form which evaluates to the same dtype. + + The intent is roughly that the following holds + + >>> from numpy import * + >>> dt = np.int64([1, 2]).dtype + >>> assert eval(dtype_short_repr(dt)) == dt + """ + if dtype.names is not None: + # structured dtypes give a list or tuple repr + return str(dtype) + elif issubclass(dtype.type, flexible): + # handle these separately so they don't give garbage like str256 + return "'%s'" % str(dtype) + + typename = dtype.name + # quote typenames which can't be represented as python variable names + if typename and not (typename[0].isalpha() and typename.isalnum()): + typename = repr(typename) + + return typename + + +def _array_repr_implementation( + arr, max_line_width=None, precision=None, suppress_small=None, + array2string=array2string): + """Internal version of array_repr() that allows overriding array2string.""" + if max_line_width is None: + max_line_width = _format_options['linewidth'] + + if type(arr) is not ndarray: + class_name = type(arr).__name__ + else: + class_name = "array" + + skipdtype = dtype_is_implied(arr.dtype) and arr.size > 0 + + prefix = class_name + "(" + suffix = ")" if skipdtype else "," + + if (_format_options['legacy'] == '1.13' and + arr.shape == () and not arr.dtype.names): + lst = repr(arr.item()) + elif arr.size > 0 or arr.shape == (0,): + lst = array2string(arr, max_line_width, precision, suppress_small, + ', ', prefix, suffix=suffix) + else: # show zero-length shape unless it is (0,) + lst = "[], shape=%s" % (repr(arr.shape),) + + arr_str = prefix + lst + suffix + + if skipdtype: + return arr_str + + dtype_str = "dtype={})".format(dtype_short_repr(arr.dtype)) + + # compute whether we should put dtype on a new line: Do so if adding the + # dtype would extend the last line past max_line_width. + # Note: This line gives the correct result even when rfind returns -1. + last_line_len = len(arr_str) - (arr_str.rfind('\n') + 1) + spacer = " " + if _format_options['legacy'] == '1.13': + if issubclass(arr.dtype.type, flexible): + spacer = '\n' + ' '*len(class_name + "(") + elif last_line_len + len(dtype_str) + 1 > max_line_width: + spacer = '\n' + ' '*len(class_name + "(") + + return arr_str + spacer + dtype_str + + +def _array_repr_dispatcher( + arr, max_line_width=None, precision=None, suppress_small=None): + return (arr,) + + +@array_function_dispatch(_array_repr_dispatcher, module='numpy') +def array_repr(arr, max_line_width=None, precision=None, suppress_small=None): + """ + Return the string representation of an array. + + Parameters + ---------- + arr : ndarray + Input array. + max_line_width : int, optional + Inserts newlines if text is longer than `max_line_width`. + Defaults to ``numpy.get_printoptions()['linewidth']``. + precision : int, optional + Floating point precision. + Defaults to ``numpy.get_printoptions()['precision']``. + suppress_small : bool, optional + Represent numbers "very close" to zero as zero; default is False. + Very close is defined by precision: if the precision is 8, e.g., + numbers smaller (in absolute value) than 5e-9 are represented as + zero. + Defaults to ``numpy.get_printoptions()['suppress']``. + + Returns + ------- + string : str + The string representation of an array. + + See Also + -------- + array_str, array2string, set_printoptions + + Examples + -------- + >>> np.array_repr(np.array([1,2])) + 'array([1, 2])' + >>> np.array_repr(np.ma.array([0.])) + 'MaskedArray([0.])' + >>> np.array_repr(np.array([], np.int32)) + 'array([], dtype=int32)' + + >>> x = np.array([1e-6, 4e-7, 2, 3]) + >>> np.array_repr(x, precision=6, suppress_small=True) + 'array([0.000001, 0. , 2. , 3. ])' + + """ + return _array_repr_implementation( + arr, max_line_width, precision, suppress_small) + + +@_recursive_guard() +def _guarded_repr_or_str(v): + if isinstance(v, bytes): + return repr(v) + return str(v) + + +def _array_str_implementation( + a, max_line_width=None, precision=None, suppress_small=None, + array2string=array2string): + """Internal version of array_str() that allows overriding array2string.""" + if (_format_options['legacy'] == '1.13' and + a.shape == () and not a.dtype.names): + return str(a.item()) + + # the str of 0d arrays is a special case: It should appear like a scalar, + # so floats are not truncated by `precision`, and strings are not wrapped + # in quotes. So we return the str of the scalar value. + if a.shape == (): + # obtain a scalar and call str on it, avoiding problems for subclasses + # for which indexing with () returns a 0d instead of a scalar by using + # ndarray's getindex. Also guard against recursive 0d object arrays. + return _guarded_repr_or_str(np.ndarray.__getitem__(a, ())) + + return array2string(a, max_line_width, precision, suppress_small, ' ', "") + + +def _array_str_dispatcher( + a, max_line_width=None, precision=None, suppress_small=None): + return (a,) + + +@array_function_dispatch(_array_str_dispatcher, module='numpy') +def array_str(a, max_line_width=None, precision=None, suppress_small=None): + """ + Return a string representation of the data in an array. + + The data in the array is returned as a single string. This function is + similar to `array_repr`, the difference being that `array_repr` also + returns information on the kind of array and its data type. + + Parameters + ---------- + a : ndarray + Input array. + max_line_width : int, optional + Inserts newlines if text is longer than `max_line_width`. + Defaults to ``numpy.get_printoptions()['linewidth']``. + precision : int, optional + Floating point precision. + Defaults to ``numpy.get_printoptions()['precision']``. + suppress_small : bool, optional + Represent numbers "very close" to zero as zero; default is False. + Very close is defined by precision: if the precision is 8, e.g., + numbers smaller (in absolute value) than 5e-9 are represented as + zero. + Defaults to ``numpy.get_printoptions()['suppress']``. + + See Also + -------- + array2string, array_repr, set_printoptions + + Examples + -------- + >>> np.array_str(np.arange(3)) + '[0 1 2]' + + """ + return _array_str_implementation( + a, max_line_width, precision, suppress_small) + + +# needed if __array_function__ is disabled +_array2string_impl = getattr(array2string, '__wrapped__', array2string) +_default_array_str = functools.partial(_array_str_implementation, + array2string=_array2string_impl) +_default_array_repr = functools.partial(_array_repr_implementation, + array2string=_array2string_impl) + + +def set_string_function(f, repr=True): + """ + Set a Python function to be used when pretty printing arrays. + + Parameters + ---------- + f : function or None + Function to be used to pretty print arrays. The function should expect + a single array argument and return a string of the representation of + the array. If None, the function is reset to the default NumPy function + to print arrays. + repr : bool, optional + If True (default), the function for pretty printing (``__repr__``) + is set, if False the function that returns the default string + representation (``__str__``) is set. + + See Also + -------- + set_printoptions, get_printoptions + + Examples + -------- + >>> def pprint(arr): + ... return 'HA! - What are you going to do now?' + ... + >>> np.set_string_function(pprint) + >>> a = np.arange(10) + >>> a + HA! - What are you going to do now? + >>> _ = a + >>> # [0 1 2 3 4 5 6 7 8 9] + + We can reset the function to the default: + + >>> np.set_string_function(None) + >>> a + array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) + + `repr` affects either pretty printing or normal string representation. + Note that ``__repr__`` is still affected by setting ``__str__`` + because the width of each array element in the returned string becomes + equal to the length of the result of ``__str__()``. + + >>> x = np.arange(4) + >>> np.set_string_function(lambda x:'random', repr=False) + >>> x.__str__() + 'random' + >>> x.__repr__() + 'array([0, 1, 2, 3])' + + """ + if f is None: + if repr: + return multiarray.set_string_function(_default_array_repr, 1) + else: + return multiarray.set_string_function(_default_array_str, 0) + else: + return multiarray.set_string_function(f, repr) diff --git a/venv/Lib/site-packages/numpy/core/cversions.py b/venv/Lib/site-packages/numpy/core/cversions.py new file mode 100644 index 0000000..00159c3 --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/cversions.py @@ -0,0 +1,13 @@ +"""Simple script to compute the api hash of the current API. + +The API has is defined by numpy_api_order and ufunc_api_order. + +""" +from os.path import dirname + +from code_generators.genapi import fullapi_hash +from code_generators.numpy_api import full_api + +if __name__ == '__main__': + curdir = dirname(__file__) + print(fullapi_hash(full_api)) diff --git a/venv/Lib/site-packages/numpy/core/defchararray.py b/venv/Lib/site-packages/numpy/core/defchararray.py new file mode 100644 index 0000000..9d7b54a --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/defchararray.py @@ -0,0 +1,2795 @@ +""" +This module contains a set of functions for vectorized string +operations and methods. + +.. note:: + The `chararray` class exists for backwards compatibility with + Numarray, it is not recommended for new development. Starting from numpy + 1.4, if one needs arrays of strings, it is recommended to use arrays of + `dtype` `object_`, `string_` or `unicode_`, and use the free functions + in the `numpy.char` module for fast vectorized string operations. + +Some methods will only be available if the corresponding string method is +available in your version of Python. + +The preferred alias for `defchararray` is `numpy.char`. + +""" +import functools +import sys +from .numerictypes import ( + string_, unicode_, integer, int_, object_, bool_, character) +from .numeric import ndarray, compare_chararrays +from .numeric import array as narray +from numpy.core.multiarray import _vec_string +from numpy.core.overrides import set_module +from numpy.core import overrides +from numpy.compat import asbytes +import numpy + +__all__ = [ + 'equal', 'not_equal', 'greater_equal', 'less_equal', + 'greater', 'less', 'str_len', 'add', 'multiply', 'mod', 'capitalize', + 'center', 'count', 'decode', 'encode', 'endswith', 'expandtabs', + 'find', 'index', 'isalnum', 'isalpha', 'isdigit', 'islower', 'isspace', + 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'partition', + 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', + 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', + 'title', 'translate', 'upper', 'zfill', 'isnumeric', 'isdecimal', + 'array', 'asarray' + ] + + +_globalvar = 0 + +array_function_dispatch = functools.partial( + overrides.array_function_dispatch, module='numpy.char') + + +def _use_unicode(*args): + """ + Helper function for determining the output type of some string + operations. + + For an operation on two ndarrays, if at least one is unicode, the + result should be unicode. + """ + for x in args: + if (isinstance(x, str) or + issubclass(numpy.asarray(x).dtype.type, unicode_)): + return unicode_ + return string_ + +def _to_string_or_unicode_array(result): + """ + Helper function to cast a result back into a string or unicode array + if an object array must be used as an intermediary. + """ + return numpy.asarray(result.tolist()) + +def _clean_args(*args): + """ + Helper function for delegating arguments to Python string + functions. + + Many of the Python string operations that have optional arguments + do not use 'None' to indicate a default value. In these cases, + we need to remove all None arguments, and those following them. + """ + newargs = [] + for chk in args: + if chk is None: + break + newargs.append(chk) + return newargs + +def _get_num_chars(a): + """ + Helper function that returns the number of characters per field in + a string or unicode array. This is to abstract out the fact that + for a unicode array this is itemsize / 4. + """ + if issubclass(a.dtype.type, unicode_): + return a.itemsize // 4 + return a.itemsize + + +def _binary_op_dispatcher(x1, x2): + return (x1, x2) + + +@array_function_dispatch(_binary_op_dispatcher) +def equal(x1, x2): + """ + Return (x1 == x2) element-wise. + + Unlike `numpy.equal`, this comparison is performed by first + stripping whitespace characters from the end of the string. This + behavior is provided for backward-compatibility with numarray. + + Parameters + ---------- + x1, x2 : array_like of str or unicode + Input arrays of the same shape. + + Returns + ------- + out : ndarray + Output array of bools. + + See Also + -------- + not_equal, greater_equal, less_equal, greater, less + """ + return compare_chararrays(x1, x2, '==', True) + + +@array_function_dispatch(_binary_op_dispatcher) +def not_equal(x1, x2): + """ + Return (x1 != x2) element-wise. + + Unlike `numpy.not_equal`, this comparison is performed by first + stripping whitespace characters from the end of the string. This + behavior is provided for backward-compatibility with numarray. + + Parameters + ---------- + x1, x2 : array_like of str or unicode + Input arrays of the same shape. + + Returns + ------- + out : ndarray + Output array of bools. + + See Also + -------- + equal, greater_equal, less_equal, greater, less + """ + return compare_chararrays(x1, x2, '!=', True) + + +@array_function_dispatch(_binary_op_dispatcher) +def greater_equal(x1, x2): + """ + Return (x1 >= x2) element-wise. + + Unlike `numpy.greater_equal`, this comparison is performed by + first stripping whitespace characters from the end of the string. + This behavior is provided for backward-compatibility with + numarray. + + Parameters + ---------- + x1, x2 : array_like of str or unicode + Input arrays of the same shape. + + Returns + ------- + out : ndarray + Output array of bools. + + See Also + -------- + equal, not_equal, less_equal, greater, less + """ + return compare_chararrays(x1, x2, '>=', True) + + +@array_function_dispatch(_binary_op_dispatcher) +def less_equal(x1, x2): + """ + Return (x1 <= x2) element-wise. + + Unlike `numpy.less_equal`, this comparison is performed by first + stripping whitespace characters from the end of the string. This + behavior is provided for backward-compatibility with numarray. + + Parameters + ---------- + x1, x2 : array_like of str or unicode + Input arrays of the same shape. + + Returns + ------- + out : ndarray + Output array of bools. + + See Also + -------- + equal, not_equal, greater_equal, greater, less + """ + return compare_chararrays(x1, x2, '<=', True) + + +@array_function_dispatch(_binary_op_dispatcher) +def greater(x1, x2): + """ + Return (x1 > x2) element-wise. + + Unlike `numpy.greater`, this comparison is performed by first + stripping whitespace characters from the end of the string. This + behavior is provided for backward-compatibility with numarray. + + Parameters + ---------- + x1, x2 : array_like of str or unicode + Input arrays of the same shape. + + Returns + ------- + out : ndarray + Output array of bools. + + See Also + -------- + equal, not_equal, greater_equal, less_equal, less + """ + return compare_chararrays(x1, x2, '>', True) + + +@array_function_dispatch(_binary_op_dispatcher) +def less(x1, x2): + """ + Return (x1 < x2) element-wise. + + Unlike `numpy.greater`, this comparison is performed by first + stripping whitespace characters from the end of the string. This + behavior is provided for backward-compatibility with numarray. + + Parameters + ---------- + x1, x2 : array_like of str or unicode + Input arrays of the same shape. + + Returns + ------- + out : ndarray + Output array of bools. + + See Also + -------- + equal, not_equal, greater_equal, less_equal, greater + """ + return compare_chararrays(x1, x2, '<', True) + + +def _unary_op_dispatcher(a): + return (a,) + + +@array_function_dispatch(_unary_op_dispatcher) +def str_len(a): + """ + Return len(a) element-wise. + + Parameters + ---------- + a : array_like of str or unicode + + Returns + ------- + out : ndarray + Output array of integers + + See also + -------- + builtins.len + """ + # Note: __len__, etc. currently return ints, which are not C-integers. + # Generally intp would be expected for lengths, although int is sufficient + # due to the dtype itemsize limitation. + return _vec_string(a, int_, '__len__') + + +@array_function_dispatch(_binary_op_dispatcher) +def add(x1, x2): + """ + Return element-wise string concatenation for two arrays of str or unicode. + + Arrays `x1` and `x2` must have the same shape. + + Parameters + ---------- + x1 : array_like of str or unicode + Input array. + x2 : array_like of str or unicode + Input array. + + Returns + ------- + add : ndarray + Output array of `string_` or `unicode_`, depending on input types + of the same shape as `x1` and `x2`. + + """ + arr1 = numpy.asarray(x1) + arr2 = numpy.asarray(x2) + out_size = _get_num_chars(arr1) + _get_num_chars(arr2) + dtype = _use_unicode(arr1, arr2) + return _vec_string(arr1, (dtype, out_size), '__add__', (arr2,)) + + +def _multiply_dispatcher(a, i): + return (a,) + + +@array_function_dispatch(_multiply_dispatcher) +def multiply(a, i): + """ + Return (a * i), that is string multiple concatenation, + element-wise. + + Values in `i` of less than 0 are treated as 0 (which yields an + empty string). + + Parameters + ---------- + a : array_like of str or unicode + + i : array_like of ints + + Returns + ------- + out : ndarray + Output array of str or unicode, depending on input types + + """ + a_arr = numpy.asarray(a) + i_arr = numpy.asarray(i) + if not issubclass(i_arr.dtype.type, integer): + raise ValueError("Can only multiply by integers") + out_size = _get_num_chars(a_arr) * max(int(i_arr.max()), 0) + return _vec_string( + a_arr, (a_arr.dtype.type, out_size), '__mul__', (i_arr,)) + + +def _mod_dispatcher(a, values): + return (a, values) + + +@array_function_dispatch(_mod_dispatcher) +def mod(a, values): + """ + Return (a % i), that is pre-Python 2.6 string formatting + (interpolation), element-wise for a pair of array_likes of str + or unicode. + + Parameters + ---------- + a : array_like of str or unicode + + values : array_like of values + These values will be element-wise interpolated into the string. + + Returns + ------- + out : ndarray + Output array of str or unicode, depending on input types + + See also + -------- + str.__mod__ + + """ + return _to_string_or_unicode_array( + _vec_string(a, object_, '__mod__', (values,))) + + +@array_function_dispatch(_unary_op_dispatcher) +def capitalize(a): + """ + Return a copy of `a` with only the first character of each element + capitalized. + + Calls `str.capitalize` element-wise. + + For 8-bit strings, this method is locale-dependent. + + Parameters + ---------- + a : array_like of str or unicode + Input array of strings to capitalize. + + Returns + ------- + out : ndarray + Output array of str or unicode, depending on input + types + + See also + -------- + str.capitalize + + Examples + -------- + >>> c = np.array(['a1b2','1b2a','b2a1','2a1b'],'S4'); c + array(['a1b2', '1b2a', 'b2a1', '2a1b'], + dtype='|S4') + >>> np.char.capitalize(c) + array(['A1b2', '1b2a', 'B2a1', '2a1b'], + dtype='|S4') + + """ + a_arr = numpy.asarray(a) + return _vec_string(a_arr, a_arr.dtype, 'capitalize') + + +def _center_dispatcher(a, width, fillchar=None): + return (a,) + + +@array_function_dispatch(_center_dispatcher) +def center(a, width, fillchar=' '): + """ + Return a copy of `a` with its elements centered in a string of + length `width`. + + Calls `str.center` element-wise. + + Parameters + ---------- + a : array_like of str or unicode + + width : int + The length of the resulting strings + fillchar : str or unicode, optional + The padding character to use (default is space). + + Returns + ------- + out : ndarray + Output array of str or unicode, depending on input + types + + See also + -------- + str.center + + """ + a_arr = numpy.asarray(a) + width_arr = numpy.asarray(width) + size = int(numpy.max(width_arr.flat)) + if numpy.issubdtype(a_arr.dtype, numpy.string_): + fillchar = asbytes(fillchar) + return _vec_string( + a_arr, (a_arr.dtype.type, size), 'center', (width_arr, fillchar)) + + +def _count_dispatcher(a, sub, start=None, end=None): + return (a,) + + +@array_function_dispatch(_count_dispatcher) +def count(a, sub, start=0, end=None): + """ + Returns an array with the number of non-overlapping occurrences of + substring `sub` in the range [`start`, `end`]. + + Calls `str.count` element-wise. + + Parameters + ---------- + a : array_like of str or unicode + + sub : str or unicode + The substring to search for. + + start, end : int, optional + Optional arguments `start` and `end` are interpreted as slice + notation to specify the range in which to count. + + Returns + ------- + out : ndarray + Output array of ints. + + See also + -------- + str.count + + Examples + -------- + >>> c = np.array(['aAaAaA', ' aA ', 'abBABba']) + >>> c + array(['aAaAaA', ' aA ', 'abBABba'], dtype='>> np.char.count(c, 'A') + array([3, 1, 1]) + >>> np.char.count(c, 'aA') + array([3, 1, 0]) + >>> np.char.count(c, 'A', start=1, end=4) + array([2, 1, 1]) + >>> np.char.count(c, 'A', start=1, end=3) + array([1, 0, 0]) + + """ + return _vec_string(a, int_, 'count', [sub, start] + _clean_args(end)) + + +def _code_dispatcher(a, encoding=None, errors=None): + return (a,) + + +@array_function_dispatch(_code_dispatcher) +def decode(a, encoding=None, errors=None): + """ + Calls `str.decode` element-wise. + + The set of available codecs comes from the Python standard library, + and may be extended at runtime. For more information, see the + :mod:`codecs` module. + + Parameters + ---------- + a : array_like of str or unicode + + encoding : str, optional + The name of an encoding + + errors : str, optional + Specifies how to handle encoding errors + + Returns + ------- + out : ndarray + + See also + -------- + str.decode + + Notes + ----- + The type of the result will depend on the encoding specified. + + Examples + -------- + >>> c = np.array(['aAaAaA', ' aA ', 'abBABba']) + >>> c + array(['aAaAaA', ' aA ', 'abBABba'], dtype='>> np.char.encode(c, encoding='cp037') + array(['\\x81\\xc1\\x81\\xc1\\x81\\xc1', '@@\\x81\\xc1@@', + '\\x81\\x82\\xc2\\xc1\\xc2\\x82\\x81'], + dtype='|S7') + + """ + return _to_string_or_unicode_array( + _vec_string(a, object_, 'decode', _clean_args(encoding, errors))) + + +@array_function_dispatch(_code_dispatcher) +def encode(a, encoding=None, errors=None): + """ + Calls `str.encode` element-wise. + + The set of available codecs comes from the Python standard library, + and may be extended at runtime. For more information, see the codecs + module. + + Parameters + ---------- + a : array_like of str or unicode + + encoding : str, optional + The name of an encoding + + errors : str, optional + Specifies how to handle encoding errors + + Returns + ------- + out : ndarray + + See also + -------- + str.encode + + Notes + ----- + The type of the result will depend on the encoding specified. + + """ + return _to_string_or_unicode_array( + _vec_string(a, object_, 'encode', _clean_args(encoding, errors))) + + +def _endswith_dispatcher(a, suffix, start=None, end=None): + return (a,) + + +@array_function_dispatch(_endswith_dispatcher) +def endswith(a, suffix, start=0, end=None): + """ + Returns a boolean array which is `True` where the string element + in `a` ends with `suffix`, otherwise `False`. + + Calls `str.endswith` element-wise. + + Parameters + ---------- + a : array_like of str or unicode + + suffix : str + + start, end : int, optional + With optional `start`, test beginning at that position. With + optional `end`, stop comparing at that position. + + Returns + ------- + out : ndarray + Outputs an array of bools. + + See also + -------- + str.endswith + + Examples + -------- + >>> s = np.array(['foo', 'bar']) + >>> s[0] = 'foo' + >>> s[1] = 'bar' + >>> s + array(['foo', 'bar'], dtype='>> np.char.endswith(s, 'ar') + array([False, True]) + >>> np.char.endswith(s, 'a', start=1, end=2) + array([False, True]) + + """ + return _vec_string( + a, bool_, 'endswith', [suffix, start] + _clean_args(end)) + + +def _expandtabs_dispatcher(a, tabsize=None): + return (a,) + + +@array_function_dispatch(_expandtabs_dispatcher) +def expandtabs(a, tabsize=8): + """ + Return a copy of each string element where all tab characters are + replaced by one or more spaces. + + Calls `str.expandtabs` element-wise. + + Return a copy of each string element where all tab characters are + replaced by one or more spaces, depending on the current column + and the given `tabsize`. The column number is reset to zero after + each newline occurring in the string. This doesn't understand other + non-printing characters or escape sequences. + + Parameters + ---------- + a : array_like of str or unicode + Input array + tabsize : int, optional + Replace tabs with `tabsize` number of spaces. If not given defaults + to 8 spaces. + + Returns + ------- + out : ndarray + Output array of str or unicode, depending on input type + + See also + -------- + str.expandtabs + + """ + return _to_string_or_unicode_array( + _vec_string(a, object_, 'expandtabs', (tabsize,))) + + +@array_function_dispatch(_count_dispatcher) +def find(a, sub, start=0, end=None): + """ + For each element, return the lowest index in the string where + substring `sub` is found. + + Calls `str.find` element-wise. + + For each element, return the lowest index in the string where + substring `sub` is found, such that `sub` is contained in the + range [`start`, `end`]. + + Parameters + ---------- + a : array_like of str or unicode + + sub : str or unicode + + start, end : int, optional + Optional arguments `start` and `end` are interpreted as in + slice notation. + + Returns + ------- + out : ndarray or int + Output array of ints. Returns -1 if `sub` is not found. + + See also + -------- + str.find + + """ + return _vec_string( + a, int_, 'find', [sub, start] + _clean_args(end)) + + +@array_function_dispatch(_count_dispatcher) +def index(a, sub, start=0, end=None): + """ + Like `find`, but raises `ValueError` when the substring is not found. + + Calls `str.index` element-wise. + + Parameters + ---------- + a : array_like of str or unicode + + sub : str or unicode + + start, end : int, optional + + Returns + ------- + out : ndarray + Output array of ints. Returns -1 if `sub` is not found. + + See also + -------- + find, str.find + + """ + return _vec_string( + a, int_, 'index', [sub, start] + _clean_args(end)) + + +@array_function_dispatch(_unary_op_dispatcher) +def isalnum(a): + """ + Returns true for each element if all characters in the string are + alphanumeric and there is at least one character, false otherwise. + + Calls `str.isalnum` element-wise. + + For 8-bit strings, this method is locale-dependent. + + Parameters + ---------- + a : array_like of str or unicode + + Returns + ------- + out : ndarray + Output array of str or unicode, depending on input type + + See also + -------- + str.isalnum + """ + return _vec_string(a, bool_, 'isalnum') + + +@array_function_dispatch(_unary_op_dispatcher) +def isalpha(a): + """ + Returns true for each element if all characters in the string are + alphabetic and there is at least one character, false otherwise. + + Calls `str.isalpha` element-wise. + + For 8-bit strings, this method is locale-dependent. + + Parameters + ---------- + a : array_like of str or unicode + + Returns + ------- + out : ndarray + Output array of bools + + See also + -------- + str.isalpha + """ + return _vec_string(a, bool_, 'isalpha') + + +@array_function_dispatch(_unary_op_dispatcher) +def isdigit(a): + """ + Returns true for each element if all characters in the string are + digits and there is at least one character, false otherwise. + + Calls `str.isdigit` element-wise. + + For 8-bit strings, this method is locale-dependent. + + Parameters + ---------- + a : array_like of str or unicode + + Returns + ------- + out : ndarray + Output array of bools + + See also + -------- + str.isdigit + """ + return _vec_string(a, bool_, 'isdigit') + + +@array_function_dispatch(_unary_op_dispatcher) +def islower(a): + """ + Returns true for each element if all cased characters in the + string are lowercase and there is at least one cased character, + false otherwise. + + Calls `str.islower` element-wise. + + For 8-bit strings, this method is locale-dependent. + + Parameters + ---------- + a : array_like of str or unicode + + Returns + ------- + out : ndarray + Output array of bools + + See also + -------- + str.islower + """ + return _vec_string(a, bool_, 'islower') + + +@array_function_dispatch(_unary_op_dispatcher) +def isspace(a): + """ + Returns true for each element if there are only whitespace + characters in the string and there is at least one character, + false otherwise. + + Calls `str.isspace` element-wise. + + For 8-bit strings, this method is locale-dependent. + + Parameters + ---------- + a : array_like of str or unicode + + Returns + ------- + out : ndarray + Output array of bools + + See also + -------- + str.isspace + """ + return _vec_string(a, bool_, 'isspace') + + +@array_function_dispatch(_unary_op_dispatcher) +def istitle(a): + """ + Returns true for each element if the element is a titlecased + string and there is at least one character, false otherwise. + + Call `str.istitle` element-wise. + + For 8-bit strings, this method is locale-dependent. + + Parameters + ---------- + a : array_like of str or unicode + + Returns + ------- + out : ndarray + Output array of bools + + See also + -------- + str.istitle + """ + return _vec_string(a, bool_, 'istitle') + + +@array_function_dispatch(_unary_op_dispatcher) +def isupper(a): + """ + Returns true for each element if all cased characters in the + string are uppercase and there is at least one character, false + otherwise. + + Call `str.isupper` element-wise. + + For 8-bit strings, this method is locale-dependent. + + Parameters + ---------- + a : array_like of str or unicode + + Returns + ------- + out : ndarray + Output array of bools + + See also + -------- + str.isupper + """ + return _vec_string(a, bool_, 'isupper') + + +def _join_dispatcher(sep, seq): + return (sep, seq) + + +@array_function_dispatch(_join_dispatcher) +def join(sep, seq): + """ + Return a string which is the concatenation of the strings in the + sequence `seq`. + + Calls `str.join` element-wise. + + Parameters + ---------- + sep : array_like of str or unicode + seq : array_like of str or unicode + + Returns + ------- + out : ndarray + Output array of str or unicode, depending on input types + + See also + -------- + str.join + """ + return _to_string_or_unicode_array( + _vec_string(sep, object_, 'join', (seq,))) + + + +def _just_dispatcher(a, width, fillchar=None): + return (a,) + + +@array_function_dispatch(_just_dispatcher) +def ljust(a, width, fillchar=' '): + """ + Return an array with the elements of `a` left-justified in a + string of length `width`. + + Calls `str.ljust` element-wise. + + Parameters + ---------- + a : array_like of str or unicode + + width : int + The length of the resulting strings + fillchar : str or unicode, optional + The character to use for padding + + Returns + ------- + out : ndarray + Output array of str or unicode, depending on input type + + See also + -------- + str.ljust + + """ + a_arr = numpy.asarray(a) + width_arr = numpy.asarray(width) + size = int(numpy.max(width_arr.flat)) + if numpy.issubdtype(a_arr.dtype, numpy.string_): + fillchar = asbytes(fillchar) + return _vec_string( + a_arr, (a_arr.dtype.type, size), 'ljust', (width_arr, fillchar)) + + +@array_function_dispatch(_unary_op_dispatcher) +def lower(a): + """ + Return an array with the elements converted to lowercase. + + Call `str.lower` element-wise. + + For 8-bit strings, this method is locale-dependent. + + Parameters + ---------- + a : array_like, {str, unicode} + Input array. + + Returns + ------- + out : ndarray, {str, unicode} + Output array of str or unicode, depending on input type + + See also + -------- + str.lower + + Examples + -------- + >>> c = np.array(['A1B C', '1BCA', 'BCA1']); c + array(['A1B C', '1BCA', 'BCA1'], dtype='>> np.char.lower(c) + array(['a1b c', '1bca', 'bca1'], dtype='>> c = np.array(['aAaAaA', ' aA ', 'abBABba']) + >>> c + array(['aAaAaA', ' aA ', 'abBABba'], dtype='>> np.char.lstrip(c, 'a') + array(['AaAaA', ' aA ', 'bBABba'], dtype='>> np.char.lstrip(c, 'A') # leaves c unchanged + array(['aAaAaA', ' aA ', 'abBABba'], dtype='>> (np.char.lstrip(c, ' ') == np.char.lstrip(c, '')).all() + ... # XXX: is this a regression? This used to return True + ... # np.char.lstrip(c,'') does not modify c at all. + False + >>> (np.char.lstrip(c, ' ') == np.char.lstrip(c, None)).all() + True + + """ + a_arr = numpy.asarray(a) + return _vec_string(a_arr, a_arr.dtype, 'lstrip', (chars,)) + + +def _partition_dispatcher(a, sep): + return (a,) + + +@array_function_dispatch(_partition_dispatcher) +def partition(a, sep): + """ + Partition each element in `a` around `sep`. + + Calls `str.partition` element-wise. + + For each element in `a`, split the element as the first + occurrence of `sep`, and return 3 strings containing the part + before the separator, the separator itself, and the part after + the separator. If the separator is not found, return 3 strings + containing the string itself, followed by two empty strings. + + Parameters + ---------- + a : array_like, {str, unicode} + Input array + sep : {str, unicode} + Separator to split each string element in `a`. + + Returns + ------- + out : ndarray, {str, unicode} + Output array of str or unicode, depending on input type. + The output array will have an extra dimension with 3 + elements per input element. + + See also + -------- + str.partition + + """ + return _to_string_or_unicode_array( + _vec_string(a, object_, 'partition', (sep,))) + + +def _replace_dispatcher(a, old, new, count=None): + return (a,) + + +@array_function_dispatch(_replace_dispatcher) +def replace(a, old, new, count=None): + """ + For each element in `a`, return a copy of the string with all + occurrences of substring `old` replaced by `new`. + + Calls `str.replace` element-wise. + + Parameters + ---------- + a : array-like of str or unicode + + old, new : str or unicode + + count : int, optional + If the optional argument `count` is given, only the first + `count` occurrences are replaced. + + Returns + ------- + out : ndarray + Output array of str or unicode, depending on input type + + See also + -------- + str.replace + + """ + return _to_string_or_unicode_array( + _vec_string( + a, object_, 'replace', [old, new] + _clean_args(count))) + + +@array_function_dispatch(_count_dispatcher) +def rfind(a, sub, start=0, end=None): + """ + For each element in `a`, return the highest index in the string + where substring `sub` is found, such that `sub` is contained + within [`start`, `end`]. + + Calls `str.rfind` element-wise. + + Parameters + ---------- + a : array-like of str or unicode + + sub : str or unicode + + start, end : int, optional + Optional arguments `start` and `end` are interpreted as in + slice notation. + + Returns + ------- + out : ndarray + Output array of ints. Return -1 on failure. + + See also + -------- + str.rfind + + """ + return _vec_string( + a, int_, 'rfind', [sub, start] + _clean_args(end)) + + +@array_function_dispatch(_count_dispatcher) +def rindex(a, sub, start=0, end=None): + """ + Like `rfind`, but raises `ValueError` when the substring `sub` is + not found. + + Calls `str.rindex` element-wise. + + Parameters + ---------- + a : array-like of str or unicode + + sub : str or unicode + + start, end : int, optional + + Returns + ------- + out : ndarray + Output array of ints. + + See also + -------- + rfind, str.rindex + + """ + return _vec_string( + a, int_, 'rindex', [sub, start] + _clean_args(end)) + + +@array_function_dispatch(_just_dispatcher) +def rjust(a, width, fillchar=' '): + """ + Return an array with the elements of `a` right-justified in a + string of length `width`. + + Calls `str.rjust` element-wise. + + Parameters + ---------- + a : array_like of str or unicode + + width : int + The length of the resulting strings + fillchar : str or unicode, optional + The character to use for padding + + Returns + ------- + out : ndarray + Output array of str or unicode, depending on input type + + See also + -------- + str.rjust + + """ + a_arr = numpy.asarray(a) + width_arr = numpy.asarray(width) + size = int(numpy.max(width_arr.flat)) + if numpy.issubdtype(a_arr.dtype, numpy.string_): + fillchar = asbytes(fillchar) + return _vec_string( + a_arr, (a_arr.dtype.type, size), 'rjust', (width_arr, fillchar)) + + +@array_function_dispatch(_partition_dispatcher) +def rpartition(a, sep): + """ + Partition (split) each element around the right-most separator. + + Calls `str.rpartition` element-wise. + + For each element in `a`, split the element as the last + occurrence of `sep`, and return 3 strings containing the part + before the separator, the separator itself, and the part after + the separator. If the separator is not found, return 3 strings + containing the string itself, followed by two empty strings. + + Parameters + ---------- + a : array_like of str or unicode + Input array + sep : str or unicode + Right-most separator to split each element in array. + + Returns + ------- + out : ndarray + Output array of string or unicode, depending on input + type. The output array will have an extra dimension with + 3 elements per input element. + + See also + -------- + str.rpartition + + """ + return _to_string_or_unicode_array( + _vec_string(a, object_, 'rpartition', (sep,))) + + +def _split_dispatcher(a, sep=None, maxsplit=None): + return (a,) + + +@array_function_dispatch(_split_dispatcher) +def rsplit(a, sep=None, maxsplit=None): + """ + For each element in `a`, return a list of the words in the + string, using `sep` as the delimiter string. + + Calls `str.rsplit` element-wise. + + Except for splitting from the right, `rsplit` + behaves like `split`. + + Parameters + ---------- + a : array_like of str or unicode + + sep : str or unicode, optional + If `sep` is not specified or None, any whitespace string + is a separator. + maxsplit : int, optional + If `maxsplit` is given, at most `maxsplit` splits are done, + the rightmost ones. + + Returns + ------- + out : ndarray + Array of list objects + + See also + -------- + str.rsplit, split + + """ + # This will return an array of lists of different sizes, so we + # leave it as an object array + return _vec_string( + a, object_, 'rsplit', [sep] + _clean_args(maxsplit)) + + +def _strip_dispatcher(a, chars=None): + return (a,) + + +@array_function_dispatch(_strip_dispatcher) +def rstrip(a, chars=None): + """ + For each element in `a`, return a copy with the trailing + characters removed. + + Calls `str.rstrip` element-wise. + + Parameters + ---------- + a : array-like of str or unicode + + chars : str or unicode, optional + The `chars` argument is a string specifying the set of + characters to be removed. If omitted or None, the `chars` + argument defaults to removing whitespace. The `chars` argument + is not a suffix; rather, all combinations of its values are + stripped. + + Returns + ------- + out : ndarray + Output array of str or unicode, depending on input type + + See also + -------- + str.rstrip + + Examples + -------- + >>> c = np.array(['aAaAaA', 'abBABba'], dtype='S7'); c + array(['aAaAaA', 'abBABba'], + dtype='|S7') + >>> np.char.rstrip(c, b'a') + array(['aAaAaA', 'abBABb'], + dtype='|S7') + >>> np.char.rstrip(c, b'A') + array(['aAaAa', 'abBABba'], + dtype='|S7') + + """ + a_arr = numpy.asarray(a) + return _vec_string(a_arr, a_arr.dtype, 'rstrip', (chars,)) + + +@array_function_dispatch(_split_dispatcher) +def split(a, sep=None, maxsplit=None): + """ + For each element in `a`, return a list of the words in the + string, using `sep` as the delimiter string. + + Calls `str.split` element-wise. + + Parameters + ---------- + a : array_like of str or unicode + + sep : str or unicode, optional + If `sep` is not specified or None, any whitespace string is a + separator. + + maxsplit : int, optional + If `maxsplit` is given, at most `maxsplit` splits are done. + + Returns + ------- + out : ndarray + Array of list objects + + See also + -------- + str.split, rsplit + + """ + # This will return an array of lists of different sizes, so we + # leave it as an object array + return _vec_string( + a, object_, 'split', [sep] + _clean_args(maxsplit)) + + +def _splitlines_dispatcher(a, keepends=None): + return (a,) + + +@array_function_dispatch(_splitlines_dispatcher) +def splitlines(a, keepends=None): + """ + For each element in `a`, return a list of the lines in the + element, breaking at line boundaries. + + Calls `str.splitlines` element-wise. + + Parameters + ---------- + a : array_like of str or unicode + + keepends : bool, optional + Line breaks are not included in the resulting list unless + keepends is given and true. + + Returns + ------- + out : ndarray + Array of list objects + + See also + -------- + str.splitlines + + """ + return _vec_string( + a, object_, 'splitlines', _clean_args(keepends)) + + +def _startswith_dispatcher(a, prefix, start=None, end=None): + return (a,) + + +@array_function_dispatch(_startswith_dispatcher) +def startswith(a, prefix, start=0, end=None): + """ + Returns a boolean array which is `True` where the string element + in `a` starts with `prefix`, otherwise `False`. + + Calls `str.startswith` element-wise. + + Parameters + ---------- + a : array_like of str or unicode + + prefix : str + + start, end : int, optional + With optional `start`, test beginning at that position. With + optional `end`, stop comparing at that position. + + Returns + ------- + out : ndarray + Array of booleans + + See also + -------- + str.startswith + + """ + return _vec_string( + a, bool_, 'startswith', [prefix, start] + _clean_args(end)) + + +@array_function_dispatch(_strip_dispatcher) +def strip(a, chars=None): + """ + For each element in `a`, return a copy with the leading and + trailing characters removed. + + Calls `str.strip` element-wise. + + Parameters + ---------- + a : array-like of str or unicode + + chars : str or unicode, optional + The `chars` argument is a string specifying the set of + characters to be removed. If omitted or None, the `chars` + argument defaults to removing whitespace. The `chars` argument + is not a prefix or suffix; rather, all combinations of its + values are stripped. + + Returns + ------- + out : ndarray + Output array of str or unicode, depending on input type + + See also + -------- + str.strip + + Examples + -------- + >>> c = np.array(['aAaAaA', ' aA ', 'abBABba']) + >>> c + array(['aAaAaA', ' aA ', 'abBABba'], dtype='>> np.char.strip(c) + array(['aAaAaA', 'aA', 'abBABba'], dtype='>> np.char.strip(c, 'a') # 'a' unstripped from c[1] because whitespace leads + array(['AaAaA', ' aA ', 'bBABb'], dtype='>> np.char.strip(c, 'A') # 'A' unstripped from c[1] because (unprinted) ws trails + array(['aAaAa', ' aA ', 'abBABba'], dtype='>> c=np.array(['a1B c','1b Ca','b Ca1','cA1b'],'S5'); c + array(['a1B c', '1b Ca', 'b Ca1', 'cA1b'], + dtype='|S5') + >>> np.char.swapcase(c) + array(['A1b C', '1B cA', 'B cA1', 'Ca1B'], + dtype='|S5') + + """ + a_arr = numpy.asarray(a) + return _vec_string(a_arr, a_arr.dtype, 'swapcase') + + +@array_function_dispatch(_unary_op_dispatcher) +def title(a): + """ + Return element-wise title cased version of string or unicode. + + Title case words start with uppercase characters, all remaining cased + characters are lowercase. + + Calls `str.title` element-wise. + + For 8-bit strings, this method is locale-dependent. + + Parameters + ---------- + a : array_like, {str, unicode} + Input array. + + Returns + ------- + out : ndarray + Output array of str or unicode, depending on input type + + See also + -------- + str.title + + Examples + -------- + >>> c=np.array(['a1b c','1b ca','b ca1','ca1b'],'S5'); c + array(['a1b c', '1b ca', 'b ca1', 'ca1b'], + dtype='|S5') + >>> np.char.title(c) + array(['A1B C', '1B Ca', 'B Ca1', 'Ca1B'], + dtype='|S5') + + """ + a_arr = numpy.asarray(a) + return _vec_string(a_arr, a_arr.dtype, 'title') + + +def _translate_dispatcher(a, table, deletechars=None): + return (a,) + + +@array_function_dispatch(_translate_dispatcher) +def translate(a, table, deletechars=None): + """ + For each element in `a`, return a copy of the string where all + characters occurring in the optional argument `deletechars` are + removed, and the remaining characters have been mapped through the + given translation table. + + Calls `str.translate` element-wise. + + Parameters + ---------- + a : array-like of str or unicode + + table : str of length 256 + + deletechars : str + + Returns + ------- + out : ndarray + Output array of str or unicode, depending on input type + + See also + -------- + str.translate + + """ + a_arr = numpy.asarray(a) + if issubclass(a_arr.dtype.type, unicode_): + return _vec_string( + a_arr, a_arr.dtype, 'translate', (table,)) + else: + return _vec_string( + a_arr, a_arr.dtype, 'translate', [table] + _clean_args(deletechars)) + + +@array_function_dispatch(_unary_op_dispatcher) +def upper(a): + """ + Return an array with the elements converted to uppercase. + + Calls `str.upper` element-wise. + + For 8-bit strings, this method is locale-dependent. + + Parameters + ---------- + a : array_like, {str, unicode} + Input array. + + Returns + ------- + out : ndarray, {str, unicode} + Output array of str or unicode, depending on input type + + See also + -------- + str.upper + + Examples + -------- + >>> c = np.array(['a1b c', '1bca', 'bca1']); c + array(['a1b c', '1bca', 'bca1'], dtype='>> np.char.upper(c) + array(['A1B C', '1BCA', 'BCA1'], dtype='= 2`` and ``order='F'``, in which case `strides` + is in "Fortran order". + + Methods + ------- + astype + argsort + copy + count + decode + dump + dumps + encode + endswith + expandtabs + fill + find + flatten + getfield + index + isalnum + isalpha + isdecimal + isdigit + islower + isnumeric + isspace + istitle + isupper + item + join + ljust + lower + lstrip + nonzero + put + ravel + repeat + replace + reshape + resize + rfind + rindex + rjust + rsplit + rstrip + searchsorted + setfield + setflags + sort + split + splitlines + squeeze + startswith + strip + swapaxes + swapcase + take + title + tofile + tolist + tostring + translate + transpose + upper + view + zfill + + Parameters + ---------- + shape : tuple + Shape of the array. + itemsize : int, optional + Length of each array element, in number of characters. Default is 1. + unicode : bool, optional + Are the array elements of type unicode (True) or string (False). + Default is False. + buffer : object exposing the buffer interface or str, optional + Memory address of the start of the array data. Default is None, + in which case a new array is created. + offset : int, optional + Fixed stride displacement from the beginning of an axis? + Default is 0. Needs to be >=0. + strides : array_like of ints, optional + Strides for the array (see `ndarray.strides` for full description). + Default is None. + order : {'C', 'F'}, optional + The order in which the array data is stored in memory: 'C' -> + "row major" order (the default), 'F' -> "column major" + (Fortran) order. + + Examples + -------- + >>> charar = np.chararray((3, 3)) + >>> charar[:] = 'a' + >>> charar + chararray([[b'a', b'a', b'a'], + [b'a', b'a', b'a'], + [b'a', b'a', b'a']], dtype='|S1') + + >>> charar = np.chararray(charar.shape, itemsize=5) + >>> charar[:] = 'abc' + >>> charar + chararray([[b'abc', b'abc', b'abc'], + [b'abc', b'abc', b'abc'], + [b'abc', b'abc', b'abc']], dtype='|S5') + + """ + def __new__(subtype, shape, itemsize=1, unicode=False, buffer=None, + offset=0, strides=None, order='C'): + global _globalvar + + if unicode: + dtype = unicode_ + else: + dtype = string_ + + # force itemsize to be a Python int, since using NumPy integer + # types results in itemsize.itemsize being used as the size of + # strings in the new array. + itemsize = int(itemsize) + + if isinstance(buffer, str): + # unicode objects do not have the buffer interface + filler = buffer + buffer = None + else: + filler = None + + _globalvar = 1 + if buffer is None: + self = ndarray.__new__(subtype, shape, (dtype, itemsize), + order=order) + else: + self = ndarray.__new__(subtype, shape, (dtype, itemsize), + buffer=buffer, + offset=offset, strides=strides, + order=order) + if filler is not None: + self[...] = filler + _globalvar = 0 + return self + + def __array_finalize__(self, obj): + # The b is a special case because it is used for reconstructing. + if not _globalvar and self.dtype.char not in 'SUbc': + raise ValueError("Can only create a chararray from string data.") + + def __getitem__(self, obj): + val = ndarray.__getitem__(self, obj) + + if isinstance(val, character): + temp = val.rstrip() + if len(temp) == 0: + val = '' + else: + val = temp + + return val + + # IMPLEMENTATION NOTE: Most of the methods of this class are + # direct delegations to the free functions in this module. + # However, those that return an array of strings should instead + # return a chararray, so some extra wrapping is required. + + def __eq__(self, other): + """ + Return (self == other) element-wise. + + See also + -------- + equal + """ + return equal(self, other) + + def __ne__(self, other): + """ + Return (self != other) element-wise. + + See also + -------- + not_equal + """ + return not_equal(self, other) + + def __ge__(self, other): + """ + Return (self >= other) element-wise. + + See also + -------- + greater_equal + """ + return greater_equal(self, other) + + def __le__(self, other): + """ + Return (self <= other) element-wise. + + See also + -------- + less_equal + """ + return less_equal(self, other) + + def __gt__(self, other): + """ + Return (self > other) element-wise. + + See also + -------- + greater + """ + return greater(self, other) + + def __lt__(self, other): + """ + Return (self < other) element-wise. + + See also + -------- + less + """ + return less(self, other) + + def __add__(self, other): + """ + Return (self + other), that is string concatenation, + element-wise for a pair of array_likes of str or unicode. + + See also + -------- + add + """ + return asarray(add(self, other)) + + def __radd__(self, other): + """ + Return (other + self), that is string concatenation, + element-wise for a pair of array_likes of `string_` or `unicode_`. + + See also + -------- + add + """ + return asarray(add(numpy.asarray(other), self)) + + def __mul__(self, i): + """ + Return (self * i), that is string multiple concatenation, + element-wise. + + See also + -------- + multiply + """ + return asarray(multiply(self, i)) + + def __rmul__(self, i): + """ + Return (self * i), that is string multiple concatenation, + element-wise. + + See also + -------- + multiply + """ + return asarray(multiply(self, i)) + + def __mod__(self, i): + """ + Return (self % i), that is pre-Python 2.6 string formatting + (interpolation), element-wise for a pair of array_likes of `string_` + or `unicode_`. + + See also + -------- + mod + """ + return asarray(mod(self, i)) + + def __rmod__(self, other): + return NotImplemented + + def argsort(self, axis=-1, kind=None, order=None): + """ + Return the indices that sort the array lexicographically. + + For full documentation see `numpy.argsort`, for which this method is + in fact merely a "thin wrapper." + + Examples + -------- + >>> c = np.array(['a1b c', '1b ca', 'b ca1', 'Ca1b'], 'S5') + >>> c = c.view(np.chararray); c + chararray(['a1b c', '1b ca', 'b ca1', 'Ca1b'], + dtype='|S5') + >>> c[c.argsort()] + chararray(['1b ca', 'Ca1b', 'a1b c', 'b ca1'], + dtype='|S5') + + """ + return self.__array__().argsort(axis, kind, order) + argsort.__doc__ = ndarray.argsort.__doc__ + + def capitalize(self): + """ + Return a copy of `self` with only the first character of each element + capitalized. + + See also + -------- + char.capitalize + + """ + return asarray(capitalize(self)) + + def center(self, width, fillchar=' '): + """ + Return a copy of `self` with its elements centered in a + string of length `width`. + + See also + -------- + center + """ + return asarray(center(self, width, fillchar)) + + def count(self, sub, start=0, end=None): + """ + Returns an array with the number of non-overlapping occurrences of + substring `sub` in the range [`start`, `end`]. + + See also + -------- + char.count + + """ + return count(self, sub, start, end) + + def decode(self, encoding=None, errors=None): + """ + Calls `str.decode` element-wise. + + See also + -------- + char.decode + + """ + return decode(self, encoding, errors) + + def encode(self, encoding=None, errors=None): + """ + Calls `str.encode` element-wise. + + See also + -------- + char.encode + + """ + return encode(self, encoding, errors) + + def endswith(self, suffix, start=0, end=None): + """ + Returns a boolean array which is `True` where the string element + in `self` ends with `suffix`, otherwise `False`. + + See also + -------- + char.endswith + + """ + return endswith(self, suffix, start, end) + + def expandtabs(self, tabsize=8): + """ + Return a copy of each string element where all tab characters are + replaced by one or more spaces. + + See also + -------- + char.expandtabs + + """ + return asarray(expandtabs(self, tabsize)) + + def find(self, sub, start=0, end=None): + """ + For each element, return the lowest index in the string where + substring `sub` is found. + + See also + -------- + char.find + + """ + return find(self, sub, start, end) + + def index(self, sub, start=0, end=None): + """ + Like `find`, but raises `ValueError` when the substring is not found. + + See also + -------- + char.index + + """ + return index(self, sub, start, end) + + def isalnum(self): + """ + Returns true for each element if all characters in the string + are alphanumeric and there is at least one character, false + otherwise. + + See also + -------- + char.isalnum + + """ + return isalnum(self) + + def isalpha(self): + """ + Returns true for each element if all characters in the string + are alphabetic and there is at least one character, false + otherwise. + + See also + -------- + char.isalpha + + """ + return isalpha(self) + + def isdigit(self): + """ + Returns true for each element if all characters in the string are + digits and there is at least one character, false otherwise. + + See also + -------- + char.isdigit + + """ + return isdigit(self) + + def islower(self): + """ + Returns true for each element if all cased characters in the + string are lowercase and there is at least one cased character, + false otherwise. + + See also + -------- + char.islower + + """ + return islower(self) + + def isspace(self): + """ + Returns true for each element if there are only whitespace + characters in the string and there is at least one character, + false otherwise. + + See also + -------- + char.isspace + + """ + return isspace(self) + + def istitle(self): + """ + Returns true for each element if the element is a titlecased + string and there is at least one character, false otherwise. + + See also + -------- + char.istitle + + """ + return istitle(self) + + def isupper(self): + """ + Returns true for each element if all cased characters in the + string are uppercase and there is at least one character, false + otherwise. + + See also + -------- + char.isupper + + """ + return isupper(self) + + def join(self, seq): + """ + Return a string which is the concatenation of the strings in the + sequence `seq`. + + See also + -------- + char.join + + """ + return join(self, seq) + + def ljust(self, width, fillchar=' '): + """ + Return an array with the elements of `self` left-justified in a + string of length `width`. + + See also + -------- + char.ljust + + """ + return asarray(ljust(self, width, fillchar)) + + def lower(self): + """ + Return an array with the elements of `self` converted to + lowercase. + + See also + -------- + char.lower + + """ + return asarray(lower(self)) + + def lstrip(self, chars=None): + """ + For each element in `self`, return a copy with the leading characters + removed. + + See also + -------- + char.lstrip + + """ + return asarray(lstrip(self, chars)) + + def partition(self, sep): + """ + Partition each element in `self` around `sep`. + + See also + -------- + partition + """ + return asarray(partition(self, sep)) + + def replace(self, old, new, count=None): + """ + For each element in `self`, return a copy of the string with all + occurrences of substring `old` replaced by `new`. + + See also + -------- + char.replace + + """ + return asarray(replace(self, old, new, count)) + + def rfind(self, sub, start=0, end=None): + """ + For each element in `self`, return the highest index in the string + where substring `sub` is found, such that `sub` is contained + within [`start`, `end`]. + + See also + -------- + char.rfind + + """ + return rfind(self, sub, start, end) + + def rindex(self, sub, start=0, end=None): + """ + Like `rfind`, but raises `ValueError` when the substring `sub` is + not found. + + See also + -------- + char.rindex + + """ + return rindex(self, sub, start, end) + + def rjust(self, width, fillchar=' '): + """ + Return an array with the elements of `self` + right-justified in a string of length `width`. + + See also + -------- + char.rjust + + """ + return asarray(rjust(self, width, fillchar)) + + def rpartition(self, sep): + """ + Partition each element in `self` around `sep`. + + See also + -------- + rpartition + """ + return asarray(rpartition(self, sep)) + + def rsplit(self, sep=None, maxsplit=None): + """ + For each element in `self`, return a list of the words in + the string, using `sep` as the delimiter string. + + See also + -------- + char.rsplit + + """ + return rsplit(self, sep, maxsplit) + + def rstrip(self, chars=None): + """ + For each element in `self`, return a copy with the trailing + characters removed. + + See also + -------- + char.rstrip + + """ + return asarray(rstrip(self, chars)) + + def split(self, sep=None, maxsplit=None): + """ + For each element in `self`, return a list of the words in the + string, using `sep` as the delimiter string. + + See also + -------- + char.split + + """ + return split(self, sep, maxsplit) + + def splitlines(self, keepends=None): + """ + For each element in `self`, return a list of the lines in the + element, breaking at line boundaries. + + See also + -------- + char.splitlines + + """ + return splitlines(self, keepends) + + def startswith(self, prefix, start=0, end=None): + """ + Returns a boolean array which is `True` where the string element + in `self` starts with `prefix`, otherwise `False`. + + See also + -------- + char.startswith + + """ + return startswith(self, prefix, start, end) + + def strip(self, chars=None): + """ + For each element in `self`, return a copy with the leading and + trailing characters removed. + + See also + -------- + char.strip + + """ + return asarray(strip(self, chars)) + + def swapcase(self): + """ + For each element in `self`, return a copy of the string with + uppercase characters converted to lowercase and vice versa. + + See also + -------- + char.swapcase + + """ + return asarray(swapcase(self)) + + def title(self): + """ + For each element in `self`, return a titlecased version of the + string: words start with uppercase characters, all remaining cased + characters are lowercase. + + See also + -------- + char.title + + """ + return asarray(title(self)) + + def translate(self, table, deletechars=None): + """ + For each element in `self`, return a copy of the string where + all characters occurring in the optional argument + `deletechars` are removed, and the remaining characters have + been mapped through the given translation table. + + See also + -------- + char.translate + + """ + return asarray(translate(self, table, deletechars)) + + def upper(self): + """ + Return an array with the elements of `self` converted to + uppercase. + + See also + -------- + char.upper + + """ + return asarray(upper(self)) + + def zfill(self, width): + """ + Return the numeric string left-filled with zeros in a string of + length `width`. + + See also + -------- + char.zfill + + """ + return asarray(zfill(self, width)) + + def isnumeric(self): + """ + For each element in `self`, return True if there are only + numeric characters in the element. + + See also + -------- + char.isnumeric + + """ + return isnumeric(self) + + def isdecimal(self): + """ + For each element in `self`, return True if there are only + decimal characters in the element. + + See also + -------- + char.isdecimal + + """ + return isdecimal(self) + + +def array(obj, itemsize=None, copy=True, unicode=None, order=None): + """ + Create a `chararray`. + + .. note:: + This class is provided for numarray backward-compatibility. + New code (not concerned with numarray compatibility) should use + arrays of type `string_` or `unicode_` and use the free functions + in :mod:`numpy.char ` for fast + vectorized string operations instead. + + Versus a regular NumPy array of type `str` or `unicode`, this + class adds the following functionality: + + 1) values automatically have whitespace removed from the end + when indexed + + 2) comparison operators automatically remove whitespace from the + end when comparing values + + 3) vectorized string operations are provided as methods + (e.g. `str.endswith`) and infix operators (e.g. ``+, *, %``) + + Parameters + ---------- + obj : array of str or unicode-like + + itemsize : int, optional + `itemsize` is the number of characters per scalar in the + resulting array. If `itemsize` is None, and `obj` is an + object array or a Python list, the `itemsize` will be + automatically determined. If `itemsize` is provided and `obj` + is of type str or unicode, then the `obj` string will be + chunked into `itemsize` pieces. + + copy : bool, optional + If true (default), then the object is copied. Otherwise, a copy + will only be made if __array__ returns a copy, if obj is a + nested sequence, or if a copy is needed to satisfy any of the other + requirements (`itemsize`, unicode, `order`, etc.). + + unicode : bool, optional + When true, the resulting `chararray` can contain Unicode + characters, when false only 8-bit characters. If unicode is + None and `obj` is one of the following: + + - a `chararray`, + - an ndarray of type `str` or `unicode` + - a Python str or unicode object, + + then the unicode setting of the output array will be + automatically determined. + + order : {'C', 'F', 'A'}, optional + Specify the order of the array. If order is 'C' (default), then the + array will be in C-contiguous order (last-index varies the + fastest). If order is 'F', then the returned array + will be in Fortran-contiguous order (first-index varies the + fastest). If order is 'A', then the returned array may + be in any order (either C-, Fortran-contiguous, or even + discontiguous). + """ + if isinstance(obj, (bytes, str)): + if unicode is None: + if isinstance(obj, str): + unicode = True + else: + unicode = False + + if itemsize is None: + itemsize = len(obj) + shape = len(obj) // itemsize + + return chararray(shape, itemsize=itemsize, unicode=unicode, + buffer=obj, order=order) + + if isinstance(obj, (list, tuple)): + obj = numpy.asarray(obj) + + if isinstance(obj, ndarray) and issubclass(obj.dtype.type, character): + # If we just have a vanilla chararray, create a chararray + # view around it. + if not isinstance(obj, chararray): + obj = obj.view(chararray) + + if itemsize is None: + itemsize = obj.itemsize + # itemsize is in 8-bit chars, so for Unicode, we need + # to divide by the size of a single Unicode character, + # which for NumPy is always 4 + if issubclass(obj.dtype.type, unicode_): + itemsize //= 4 + + if unicode is None: + if issubclass(obj.dtype.type, unicode_): + unicode = True + else: + unicode = False + + if unicode: + dtype = unicode_ + else: + dtype = string_ + + if order is not None: + obj = numpy.asarray(obj, order=order) + if (copy or + (itemsize != obj.itemsize) or + (not unicode and isinstance(obj, unicode_)) or + (unicode and isinstance(obj, string_))): + obj = obj.astype((dtype, int(itemsize))) + return obj + + if isinstance(obj, ndarray) and issubclass(obj.dtype.type, object): + if itemsize is None: + # Since no itemsize was specified, convert the input array to + # a list so the ndarray constructor will automatically + # determine the itemsize for us. + obj = obj.tolist() + # Fall through to the default case + + if unicode: + dtype = unicode_ + else: + dtype = string_ + + if itemsize is None: + val = narray(obj, dtype=dtype, order=order, subok=True) + else: + val = narray(obj, dtype=(dtype, itemsize), order=order, subok=True) + return val.view(chararray) + + +def asarray(obj, itemsize=None, unicode=None, order=None): + """ + Convert the input to a `chararray`, copying the data only if + necessary. + + Versus a regular NumPy array of type `str` or `unicode`, this + class adds the following functionality: + + 1) values automatically have whitespace removed from the end + when indexed + + 2) comparison operators automatically remove whitespace from the + end when comparing values + + 3) vectorized string operations are provided as methods + (e.g. `str.endswith`) and infix operators (e.g. ``+``, ``*``,``%``) + + Parameters + ---------- + obj : array of str or unicode-like + + itemsize : int, optional + `itemsize` is the number of characters per scalar in the + resulting array. If `itemsize` is None, and `obj` is an + object array or a Python list, the `itemsize` will be + automatically determined. If `itemsize` is provided and `obj` + is of type str or unicode, then the `obj` string will be + chunked into `itemsize` pieces. + + unicode : bool, optional + When true, the resulting `chararray` can contain Unicode + characters, when false only 8-bit characters. If unicode is + None and `obj` is one of the following: + + - a `chararray`, + - an ndarray of type `str` or 'unicode` + - a Python str or unicode object, + + then the unicode setting of the output array will be + automatically determined. + + order : {'C', 'F'}, optional + Specify the order of the array. If order is 'C' (default), then the + array will be in C-contiguous order (last-index varies the + fastest). If order is 'F', then the returned array + will be in Fortran-contiguous order (first-index varies the + fastest). + """ + return array(obj, itemsize, copy=False, + unicode=unicode, order=order) diff --git a/venv/Lib/site-packages/numpy/core/einsumfunc.py b/venv/Lib/site-packages/numpy/core/einsumfunc.py new file mode 100644 index 0000000..e0942be --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/einsumfunc.py @@ -0,0 +1,1433 @@ +""" +Implementation of optimized einsum. + +""" +import itertools +import operator + +from numpy.core.multiarray import c_einsum +from numpy.core.numeric import asanyarray, tensordot +from numpy.core.overrides import array_function_dispatch + +__all__ = ['einsum', 'einsum_path'] + +einsum_symbols = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' +einsum_symbols_set = set(einsum_symbols) + + +def _flop_count(idx_contraction, inner, num_terms, size_dictionary): + """ + Computes the number of FLOPS in the contraction. + + Parameters + ---------- + idx_contraction : iterable + The indices involved in the contraction + inner : bool + Does this contraction require an inner product? + num_terms : int + The number of terms in a contraction + size_dictionary : dict + The size of each of the indices in idx_contraction + + Returns + ------- + flop_count : int + The total number of FLOPS required for the contraction. + + Examples + -------- + + >>> _flop_count('abc', False, 1, {'a': 2, 'b':3, 'c':5}) + 30 + + >>> _flop_count('abc', True, 2, {'a': 2, 'b':3, 'c':5}) + 60 + + """ + + overall_size = _compute_size_by_dict(idx_contraction, size_dictionary) + op_factor = max(1, num_terms - 1) + if inner: + op_factor += 1 + + return overall_size * op_factor + +def _compute_size_by_dict(indices, idx_dict): + """ + Computes the product of the elements in indices based on the dictionary + idx_dict. + + Parameters + ---------- + indices : iterable + Indices to base the product on. + idx_dict : dictionary + Dictionary of index sizes + + Returns + ------- + ret : int + The resulting product. + + Examples + -------- + >>> _compute_size_by_dict('abbc', {'a': 2, 'b':3, 'c':5}) + 90 + + """ + ret = 1 + for i in indices: + ret *= idx_dict[i] + return ret + + +def _find_contraction(positions, input_sets, output_set): + """ + Finds the contraction for a given set of input and output sets. + + Parameters + ---------- + positions : iterable + Integer positions of terms used in the contraction. + input_sets : list + List of sets that represent the lhs side of the einsum subscript + output_set : set + Set that represents the rhs side of the overall einsum subscript + + Returns + ------- + new_result : set + The indices of the resulting contraction + remaining : list + List of sets that have not been contracted, the new set is appended to + the end of this list + idx_removed : set + Indices removed from the entire contraction + idx_contraction : set + The indices used in the current contraction + + Examples + -------- + + # A simple dot product test case + >>> pos = (0, 1) + >>> isets = [set('ab'), set('bc')] + >>> oset = set('ac') + >>> _find_contraction(pos, isets, oset) + ({'a', 'c'}, [{'a', 'c'}], {'b'}, {'a', 'b', 'c'}) + + # A more complex case with additional terms in the contraction + >>> pos = (0, 2) + >>> isets = [set('abd'), set('ac'), set('bdc')] + >>> oset = set('ac') + >>> _find_contraction(pos, isets, oset) + ({'a', 'c'}, [{'a', 'c'}, {'a', 'c'}], {'b', 'd'}, {'a', 'b', 'c', 'd'}) + """ + + idx_contract = set() + idx_remain = output_set.copy() + remaining = [] + for ind, value in enumerate(input_sets): + if ind in positions: + idx_contract |= value + else: + remaining.append(value) + idx_remain |= value + + new_result = idx_remain & idx_contract + idx_removed = (idx_contract - new_result) + remaining.append(new_result) + + return (new_result, remaining, idx_removed, idx_contract) + + +def _optimal_path(input_sets, output_set, idx_dict, memory_limit): + """ + Computes all possible pair contractions, sieves the results based + on ``memory_limit`` and returns the lowest cost path. This algorithm + scales factorial with respect to the elements in the list ``input_sets``. + + Parameters + ---------- + input_sets : list + List of sets that represent the lhs side of the einsum subscript + output_set : set + Set that represents the rhs side of the overall einsum subscript + idx_dict : dictionary + Dictionary of index sizes + memory_limit : int + The maximum number of elements in a temporary array + + Returns + ------- + path : list + The optimal contraction order within the memory limit constraint. + + Examples + -------- + >>> isets = [set('abd'), set('ac'), set('bdc')] + >>> oset = set() + >>> idx_sizes = {'a': 1, 'b':2, 'c':3, 'd':4} + >>> _optimal_path(isets, oset, idx_sizes, 5000) + [(0, 2), (0, 1)] + """ + + full_results = [(0, [], input_sets)] + for iteration in range(len(input_sets) - 1): + iter_results = [] + + # Compute all unique pairs + for curr in full_results: + cost, positions, remaining = curr + for con in itertools.combinations(range(len(input_sets) - iteration), 2): + + # Find the contraction + cont = _find_contraction(con, remaining, output_set) + new_result, new_input_sets, idx_removed, idx_contract = cont + + # Sieve the results based on memory_limit + new_size = _compute_size_by_dict(new_result, idx_dict) + if new_size > memory_limit: + continue + + # Build (total_cost, positions, indices_remaining) + total_cost = cost + _flop_count(idx_contract, idx_removed, len(con), idx_dict) + new_pos = positions + [con] + iter_results.append((total_cost, new_pos, new_input_sets)) + + # Update combinatorial list, if we did not find anything return best + # path + remaining contractions + if iter_results: + full_results = iter_results + else: + path = min(full_results, key=lambda x: x[0])[1] + path += [tuple(range(len(input_sets) - iteration))] + return path + + # If we have not found anything return single einsum contraction + if len(full_results) == 0: + return [tuple(range(len(input_sets)))] + + path = min(full_results, key=lambda x: x[0])[1] + return path + +def _parse_possible_contraction(positions, input_sets, output_set, idx_dict, memory_limit, path_cost, naive_cost): + """Compute the cost (removed size + flops) and resultant indices for + performing the contraction specified by ``positions``. + + Parameters + ---------- + positions : tuple of int + The locations of the proposed tensors to contract. + input_sets : list of sets + The indices found on each tensors. + output_set : set + The output indices of the expression. + idx_dict : dict + Mapping of each index to its size. + memory_limit : int + The total allowed size for an intermediary tensor. + path_cost : int + The contraction cost so far. + naive_cost : int + The cost of the unoptimized expression. + + Returns + ------- + cost : (int, int) + A tuple containing the size of any indices removed, and the flop cost. + positions : tuple of int + The locations of the proposed tensors to contract. + new_input_sets : list of sets + The resulting new list of indices if this proposed contraction is performed. + + """ + + # Find the contraction + contract = _find_contraction(positions, input_sets, output_set) + idx_result, new_input_sets, idx_removed, idx_contract = contract + + # Sieve the results based on memory_limit + new_size = _compute_size_by_dict(idx_result, idx_dict) + if new_size > memory_limit: + return None + + # Build sort tuple + old_sizes = (_compute_size_by_dict(input_sets[p], idx_dict) for p in positions) + removed_size = sum(old_sizes) - new_size + + # NB: removed_size used to be just the size of any removed indices i.e.: + # helpers.compute_size_by_dict(idx_removed, idx_dict) + cost = _flop_count(idx_contract, idx_removed, len(positions), idx_dict) + sort = (-removed_size, cost) + + # Sieve based on total cost as well + if (path_cost + cost) > naive_cost: + return None + + # Add contraction to possible choices + return [sort, positions, new_input_sets] + + +def _update_other_results(results, best): + """Update the positions and provisional input_sets of ``results`` based on + performing the contraction result ``best``. Remove any involving the tensors + contracted. + + Parameters + ---------- + results : list + List of contraction results produced by ``_parse_possible_contraction``. + best : list + The best contraction of ``results`` i.e. the one that will be performed. + + Returns + ------- + mod_results : list + The list of modified results, updated with outcome of ``best`` contraction. + """ + + best_con = best[1] + bx, by = best_con + mod_results = [] + + for cost, (x, y), con_sets in results: + + # Ignore results involving tensors just contracted + if x in best_con or y in best_con: + continue + + # Update the input_sets + del con_sets[by - int(by > x) - int(by > y)] + del con_sets[bx - int(bx > x) - int(bx > y)] + con_sets.insert(-1, best[2][-1]) + + # Update the position indices + mod_con = x - int(x > bx) - int(x > by), y - int(y > bx) - int(y > by) + mod_results.append((cost, mod_con, con_sets)) + + return mod_results + +def _greedy_path(input_sets, output_set, idx_dict, memory_limit): + """ + Finds the path by contracting the best pair until the input list is + exhausted. The best pair is found by minimizing the tuple + ``(-prod(indices_removed), cost)``. What this amounts to is prioritizing + matrix multiplication or inner product operations, then Hadamard like + operations, and finally outer operations. Outer products are limited by + ``memory_limit``. This algorithm scales cubically with respect to the + number of elements in the list ``input_sets``. + + Parameters + ---------- + input_sets : list + List of sets that represent the lhs side of the einsum subscript + output_set : set + Set that represents the rhs side of the overall einsum subscript + idx_dict : dictionary + Dictionary of index sizes + memory_limit_limit : int + The maximum number of elements in a temporary array + + Returns + ------- + path : list + The greedy contraction order within the memory limit constraint. + + Examples + -------- + >>> isets = [set('abd'), set('ac'), set('bdc')] + >>> oset = set() + >>> idx_sizes = {'a': 1, 'b':2, 'c':3, 'd':4} + >>> _greedy_path(isets, oset, idx_sizes, 5000) + [(0, 2), (0, 1)] + """ + + # Handle trivial cases that leaked through + if len(input_sets) == 1: + return [(0,)] + elif len(input_sets) == 2: + return [(0, 1)] + + # Build up a naive cost + contract = _find_contraction(range(len(input_sets)), input_sets, output_set) + idx_result, new_input_sets, idx_removed, idx_contract = contract + naive_cost = _flop_count(idx_contract, idx_removed, len(input_sets), idx_dict) + + # Initially iterate over all pairs + comb_iter = itertools.combinations(range(len(input_sets)), 2) + known_contractions = [] + + path_cost = 0 + path = [] + + for iteration in range(len(input_sets) - 1): + + # Iterate over all pairs on first step, only previously found pairs on subsequent steps + for positions in comb_iter: + + # Always initially ignore outer products + if input_sets[positions[0]].isdisjoint(input_sets[positions[1]]): + continue + + result = _parse_possible_contraction(positions, input_sets, output_set, idx_dict, memory_limit, path_cost, + naive_cost) + if result is not None: + known_contractions.append(result) + + # If we do not have a inner contraction, rescan pairs including outer products + if len(known_contractions) == 0: + + # Then check the outer products + for positions in itertools.combinations(range(len(input_sets)), 2): + result = _parse_possible_contraction(positions, input_sets, output_set, idx_dict, memory_limit, + path_cost, naive_cost) + if result is not None: + known_contractions.append(result) + + # If we still did not find any remaining contractions, default back to einsum like behavior + if len(known_contractions) == 0: + path.append(tuple(range(len(input_sets)))) + break + + # Sort based on first index + best = min(known_contractions, key=lambda x: x[0]) + + # Now propagate as many unused contractions as possible to next iteration + known_contractions = _update_other_results(known_contractions, best) + + # Next iteration only compute contractions with the new tensor + # All other contractions have been accounted for + input_sets = best[2] + new_tensor_pos = len(input_sets) - 1 + comb_iter = ((i, new_tensor_pos) for i in range(new_tensor_pos)) + + # Update path and total cost + path.append(best[1]) + path_cost += best[0][1] + + return path + + +def _can_dot(inputs, result, idx_removed): + """ + Checks if we can use BLAS (np.tensordot) call and its beneficial to do so. + + Parameters + ---------- + inputs : list of str + Specifies the subscripts for summation. + result : str + Resulting summation. + idx_removed : set + Indices that are removed in the summation + + + Returns + ------- + type : bool + Returns true if BLAS should and can be used, else False + + Notes + ----- + If the operations is BLAS level 1 or 2 and is not already aligned + we default back to einsum as the memory movement to copy is more + costly than the operation itself. + + + Examples + -------- + + # Standard GEMM operation + >>> _can_dot(['ij', 'jk'], 'ik', set('j')) + True + + # Can use the standard BLAS, but requires odd data movement + >>> _can_dot(['ijj', 'jk'], 'ik', set('j')) + False + + # DDOT where the memory is not aligned + >>> _can_dot(['ijk', 'ikj'], '', set('ijk')) + False + + """ + + # All `dot` calls remove indices + if len(idx_removed) == 0: + return False + + # BLAS can only handle two operands + if len(inputs) != 2: + return False + + input_left, input_right = inputs + + for c in set(input_left + input_right): + # can't deal with repeated indices on same input or more than 2 total + nl, nr = input_left.count(c), input_right.count(c) + if (nl > 1) or (nr > 1) or (nl + nr > 2): + return False + + # can't do implicit summation or dimension collapse e.g. + # "ab,bc->c" (implicitly sum over 'a') + # "ab,ca->ca" (take diagonal of 'a') + if nl + nr - 1 == int(c in result): + return False + + # Build a few temporaries + set_left = set(input_left) + set_right = set(input_right) + keep_left = set_left - idx_removed + keep_right = set_right - idx_removed + rs = len(idx_removed) + + # At this point we are a DOT, GEMV, or GEMM operation + + # Handle inner products + + # DDOT with aligned data + if input_left == input_right: + return True + + # DDOT without aligned data (better to use einsum) + if set_left == set_right: + return False + + # Handle the 4 possible (aligned) GEMV or GEMM cases + + # GEMM or GEMV no transpose + if input_left[-rs:] == input_right[:rs]: + return True + + # GEMM or GEMV transpose both + if input_left[:rs] == input_right[-rs:]: + return True + + # GEMM or GEMV transpose right + if input_left[-rs:] == input_right[-rs:]: + return True + + # GEMM or GEMV transpose left + if input_left[:rs] == input_right[:rs]: + return True + + # Einsum is faster than GEMV if we have to copy data + if not keep_left or not keep_right: + return False + + # We are a matrix-matrix product, but we need to copy data + return True + + +def _parse_einsum_input(operands): + """ + A reproduction of einsum c side einsum parsing in python. + + Returns + ------- + input_strings : str + Parsed input strings + output_string : str + Parsed output string + operands : list of array_like + The operands to use in the numpy contraction + + Examples + -------- + The operand list is simplified to reduce printing: + + >>> np.random.seed(123) + >>> a = np.random.rand(4, 4) + >>> b = np.random.rand(4, 4, 4) + >>> _parse_einsum_input(('...a,...a->...', a, b)) + ('za,xza', 'xz', [a, b]) # may vary + + >>> _parse_einsum_input((a, [Ellipsis, 0], b, [Ellipsis, 0])) + ('za,xza', 'xz', [a, b]) # may vary + """ + + if len(operands) == 0: + raise ValueError("No input operands") + + if isinstance(operands[0], str): + subscripts = operands[0].replace(" ", "") + operands = [asanyarray(v) for v in operands[1:]] + + # Ensure all characters are valid + for s in subscripts: + if s in '.,->': + continue + if s not in einsum_symbols: + raise ValueError("Character %s is not a valid symbol." % s) + + else: + tmp_operands = list(operands) + operand_list = [] + subscript_list = [] + for p in range(len(operands) // 2): + operand_list.append(tmp_operands.pop(0)) + subscript_list.append(tmp_operands.pop(0)) + + output_list = tmp_operands[-1] if len(tmp_operands) else None + operands = [asanyarray(v) for v in operand_list] + subscripts = "" + last = len(subscript_list) - 1 + for num, sub in enumerate(subscript_list): + for s in sub: + if s is Ellipsis: + subscripts += "..." + else: + try: + s = operator.index(s) + except TypeError as e: + raise TypeError("For this input type lists must contain " + "either int or Ellipsis") from e + subscripts += einsum_symbols[s] + if num != last: + subscripts += "," + + if output_list is not None: + subscripts += "->" + for s in output_list: + if s is Ellipsis: + subscripts += "..." + else: + try: + s = operator.index(s) + except TypeError as e: + raise TypeError("For this input type lists must contain " + "either int or Ellipsis") from e + subscripts += einsum_symbols[s] + # Check for proper "->" + if ("-" in subscripts) or (">" in subscripts): + invalid = (subscripts.count("-") > 1) or (subscripts.count(">") > 1) + if invalid or (subscripts.count("->") != 1): + raise ValueError("Subscripts can only contain one '->'.") + + # Parse ellipses + if "." in subscripts: + used = subscripts.replace(".", "").replace(",", "").replace("->", "") + unused = list(einsum_symbols_set - set(used)) + ellipse_inds = "".join(unused) + longest = 0 + + if "->" in subscripts: + input_tmp, output_sub = subscripts.split("->") + split_subscripts = input_tmp.split(",") + out_sub = True + else: + split_subscripts = subscripts.split(',') + out_sub = False + + for num, sub in enumerate(split_subscripts): + if "." in sub: + if (sub.count(".") != 3) or (sub.count("...") != 1): + raise ValueError("Invalid Ellipses.") + + # Take into account numerical values + if operands[num].shape == (): + ellipse_count = 0 + else: + ellipse_count = max(operands[num].ndim, 1) + ellipse_count -= (len(sub) - 3) + + if ellipse_count > longest: + longest = ellipse_count + + if ellipse_count < 0: + raise ValueError("Ellipses lengths do not match.") + elif ellipse_count == 0: + split_subscripts[num] = sub.replace('...', '') + else: + rep_inds = ellipse_inds[-ellipse_count:] + split_subscripts[num] = sub.replace('...', rep_inds) + + subscripts = ",".join(split_subscripts) + if longest == 0: + out_ellipse = "" + else: + out_ellipse = ellipse_inds[-longest:] + + if out_sub: + subscripts += "->" + output_sub.replace("...", out_ellipse) + else: + # Special care for outputless ellipses + output_subscript = "" + tmp_subscripts = subscripts.replace(",", "") + for s in sorted(set(tmp_subscripts)): + if s not in (einsum_symbols): + raise ValueError("Character %s is not a valid symbol." % s) + if tmp_subscripts.count(s) == 1: + output_subscript += s + normal_inds = ''.join(sorted(set(output_subscript) - + set(out_ellipse))) + + subscripts += "->" + out_ellipse + normal_inds + + # Build output string if does not exist + if "->" in subscripts: + input_subscripts, output_subscript = subscripts.split("->") + else: + input_subscripts = subscripts + # Build output subscripts + tmp_subscripts = subscripts.replace(",", "") + output_subscript = "" + for s in sorted(set(tmp_subscripts)): + if s not in einsum_symbols: + raise ValueError("Character %s is not a valid symbol." % s) + if tmp_subscripts.count(s) == 1: + output_subscript += s + + # Make sure output subscripts are in the input + for char in output_subscript: + if char not in input_subscripts: + raise ValueError("Output character %s did not appear in the input" + % char) + + # Make sure number operands is equivalent to the number of terms + if len(input_subscripts.split(',')) != len(operands): + raise ValueError("Number of einsum subscripts must be equal to the " + "number of operands.") + + return (input_subscripts, output_subscript, operands) + + +def _einsum_path_dispatcher(*operands, optimize=None, einsum_call=None): + # NOTE: technically, we should only dispatch on array-like arguments, not + # subscripts (given as strings). But separating operands into + # arrays/subscripts is a little tricky/slow (given einsum's two supported + # signatures), so as a practical shortcut we dispatch on everything. + # Strings will be ignored for dispatching since they don't define + # __array_function__. + return operands + + +@array_function_dispatch(_einsum_path_dispatcher, module='numpy') +def einsum_path(*operands, optimize='greedy', einsum_call=False): + """ + einsum_path(subscripts, *operands, optimize='greedy') + + Evaluates the lowest cost contraction order for an einsum expression by + considering the creation of intermediate arrays. + + Parameters + ---------- + subscripts : str + Specifies the subscripts for summation. + *operands : list of array_like + These are the arrays for the operation. + optimize : {bool, list, tuple, 'greedy', 'optimal'} + Choose the type of path. If a tuple is provided, the second argument is + assumed to be the maximum intermediate size created. If only a single + argument is provided the largest input or output array size is used + as a maximum intermediate size. + + * if a list is given that starts with ``einsum_path``, uses this as the + contraction path + * if False no optimization is taken + * if True defaults to the 'greedy' algorithm + * 'optimal' An algorithm that combinatorially explores all possible + ways of contracting the listed tensors and choosest the least costly + path. Scales exponentially with the number of terms in the + contraction. + * 'greedy' An algorithm that chooses the best pair contraction + at each step. Effectively, this algorithm searches the largest inner, + Hadamard, and then outer products at each step. Scales cubically with + the number of terms in the contraction. Equivalent to the 'optimal' + path for most contractions. + + Default is 'greedy'. + + Returns + ------- + path : list of tuples + A list representation of the einsum path. + string_repr : str + A printable representation of the einsum path. + + Notes + ----- + The resulting path indicates which terms of the input contraction should be + contracted first, the result of this contraction is then appended to the + end of the contraction list. This list can then be iterated over until all + intermediate contractions are complete. + + See Also + -------- + einsum, linalg.multi_dot + + Examples + -------- + + We can begin with a chain dot example. In this case, it is optimal to + contract the ``b`` and ``c`` tensors first as represented by the first + element of the path ``(1, 2)``. The resulting tensor is added to the end + of the contraction and the remaining contraction ``(0, 1)`` is then + completed. + + >>> np.random.seed(123) + >>> a = np.random.rand(2, 2) + >>> b = np.random.rand(2, 5) + >>> c = np.random.rand(5, 2) + >>> path_info = np.einsum_path('ij,jk,kl->il', a, b, c, optimize='greedy') + >>> print(path_info[0]) + ['einsum_path', (1, 2), (0, 1)] + >>> print(path_info[1]) + Complete contraction: ij,jk,kl->il # may vary + Naive scaling: 4 + Optimized scaling: 3 + Naive FLOP count: 1.600e+02 + Optimized FLOP count: 5.600e+01 + Theoretical speedup: 2.857 + Largest intermediate: 4.000e+00 elements + ------------------------------------------------------------------------- + scaling current remaining + ------------------------------------------------------------------------- + 3 kl,jk->jl ij,jl->il + 3 jl,ij->il il->il + + + A more complex index transformation example. + + >>> I = np.random.rand(10, 10, 10, 10) + >>> C = np.random.rand(10, 10) + >>> path_info = np.einsum_path('ea,fb,abcd,gc,hd->efgh', C, C, I, C, C, + ... optimize='greedy') + + >>> print(path_info[0]) + ['einsum_path', (0, 2), (0, 3), (0, 2), (0, 1)] + >>> print(path_info[1]) + Complete contraction: ea,fb,abcd,gc,hd->efgh # may vary + Naive scaling: 8 + Optimized scaling: 5 + Naive FLOP count: 8.000e+08 + Optimized FLOP count: 8.000e+05 + Theoretical speedup: 1000.000 + Largest intermediate: 1.000e+04 elements + -------------------------------------------------------------------------- + scaling current remaining + -------------------------------------------------------------------------- + 5 abcd,ea->bcde fb,gc,hd,bcde->efgh + 5 bcde,fb->cdef gc,hd,cdef->efgh + 5 cdef,gc->defg hd,defg->efgh + 5 defg,hd->efgh efgh->efgh + """ + + # Figure out what the path really is + path_type = optimize + if path_type is True: + path_type = 'greedy' + if path_type is None: + path_type = False + + memory_limit = None + + # No optimization or a named path algorithm + if (path_type is False) or isinstance(path_type, str): + pass + + # Given an explicit path + elif len(path_type) and (path_type[0] == 'einsum_path'): + pass + + # Path tuple with memory limit + elif ((len(path_type) == 2) and isinstance(path_type[0], str) and + isinstance(path_type[1], (int, float))): + memory_limit = int(path_type[1]) + path_type = path_type[0] + + else: + raise TypeError("Did not understand the path: %s" % str(path_type)) + + # Hidden option, only einsum should call this + einsum_call_arg = einsum_call + + # Python side parsing + input_subscripts, output_subscript, operands = _parse_einsum_input(operands) + + # Build a few useful list and sets + input_list = input_subscripts.split(',') + input_sets = [set(x) for x in input_list] + output_set = set(output_subscript) + indices = set(input_subscripts.replace(',', '')) + + # Get length of each unique dimension and ensure all dimensions are correct + dimension_dict = {} + broadcast_indices = [[] for x in range(len(input_list))] + for tnum, term in enumerate(input_list): + sh = operands[tnum].shape + if len(sh) != len(term): + raise ValueError("Einstein sum subscript %s does not contain the " + "correct number of indices for operand %d." + % (input_subscripts[tnum], tnum)) + for cnum, char in enumerate(term): + dim = sh[cnum] + + # Build out broadcast indices + if dim == 1: + broadcast_indices[tnum].append(char) + + if char in dimension_dict.keys(): + # For broadcasting cases we always want the largest dim size + if dimension_dict[char] == 1: + dimension_dict[char] = dim + elif dim not in (1, dimension_dict[char]): + raise ValueError("Size of label '%s' for operand %d (%d) " + "does not match previous terms (%d)." + % (char, tnum, dimension_dict[char], dim)) + else: + dimension_dict[char] = dim + + # Convert broadcast inds to sets + broadcast_indices = [set(x) for x in broadcast_indices] + + # Compute size of each input array plus the output array + size_list = [_compute_size_by_dict(term, dimension_dict) + for term in input_list + [output_subscript]] + max_size = max(size_list) + + if memory_limit is None: + memory_arg = max_size + else: + memory_arg = memory_limit + + # Compute naive cost + # This isn't quite right, need to look into exactly how einsum does this + inner_product = (sum(len(x) for x in input_sets) - len(indices)) > 0 + naive_cost = _flop_count(indices, inner_product, len(input_list), dimension_dict) + + # Compute the path + if (path_type is False) or (len(input_list) in [1, 2]) or (indices == output_set): + # Nothing to be optimized, leave it to einsum + path = [tuple(range(len(input_list)))] + elif path_type == "greedy": + path = _greedy_path(input_sets, output_set, dimension_dict, memory_arg) + elif path_type == "optimal": + path = _optimal_path(input_sets, output_set, dimension_dict, memory_arg) + elif path_type[0] == 'einsum_path': + path = path_type[1:] + else: + raise KeyError("Path name %s not found", path_type) + + cost_list, scale_list, size_list, contraction_list = [], [], [], [] + + # Build contraction tuple (positions, gemm, einsum_str, remaining) + for cnum, contract_inds in enumerate(path): + # Make sure we remove inds from right to left + contract_inds = tuple(sorted(list(contract_inds), reverse=True)) + + contract = _find_contraction(contract_inds, input_sets, output_set) + out_inds, input_sets, idx_removed, idx_contract = contract + + cost = _flop_count(idx_contract, idx_removed, len(contract_inds), dimension_dict) + cost_list.append(cost) + scale_list.append(len(idx_contract)) + size_list.append(_compute_size_by_dict(out_inds, dimension_dict)) + + bcast = set() + tmp_inputs = [] + for x in contract_inds: + tmp_inputs.append(input_list.pop(x)) + bcast |= broadcast_indices.pop(x) + + new_bcast_inds = bcast - idx_removed + + # If we're broadcasting, nix blas + if not len(idx_removed & bcast): + do_blas = _can_dot(tmp_inputs, out_inds, idx_removed) + else: + do_blas = False + + # Last contraction + if (cnum - len(path)) == -1: + idx_result = output_subscript + else: + sort_result = [(dimension_dict[ind], ind) for ind in out_inds] + idx_result = "".join([x[1] for x in sorted(sort_result)]) + + input_list.append(idx_result) + broadcast_indices.append(new_bcast_inds) + einsum_str = ",".join(tmp_inputs) + "->" + idx_result + + contraction = (contract_inds, idx_removed, einsum_str, input_list[:], do_blas) + contraction_list.append(contraction) + + opt_cost = sum(cost_list) + 1 + + if einsum_call_arg: + return (operands, contraction_list) + + # Return the path along with a nice string representation + overall_contraction = input_subscripts + "->" + output_subscript + header = ("scaling", "current", "remaining") + + speedup = naive_cost / opt_cost + max_i = max(size_list) + + path_print = " Complete contraction: %s\n" % overall_contraction + path_print += " Naive scaling: %d\n" % len(indices) + path_print += " Optimized scaling: %d\n" % max(scale_list) + path_print += " Naive FLOP count: %.3e\n" % naive_cost + path_print += " Optimized FLOP count: %.3e\n" % opt_cost + path_print += " Theoretical speedup: %3.3f\n" % speedup + path_print += " Largest intermediate: %.3e elements\n" % max_i + path_print += "-" * 74 + "\n" + path_print += "%6s %24s %40s\n" % header + path_print += "-" * 74 + + for n, contraction in enumerate(contraction_list): + inds, idx_rm, einsum_str, remaining, blas = contraction + remaining_str = ",".join(remaining) + "->" + output_subscript + path_run = (scale_list[n], einsum_str, remaining_str) + path_print += "\n%4d %24s %40s" % path_run + + path = ['einsum_path'] + path + return (path, path_print) + + +def _einsum_dispatcher(*operands, out=None, optimize=None, **kwargs): + # Arguably we dispatch on more arguments that we really should; see note in + # _einsum_path_dispatcher for why. + yield from operands + yield out + + +# Rewrite einsum to handle different cases +@array_function_dispatch(_einsum_dispatcher, module='numpy') +def einsum(*operands, out=None, optimize=False, **kwargs): + """ + einsum(subscripts, *operands, out=None, dtype=None, order='K', + casting='safe', optimize=False) + + Evaluates the Einstein summation convention on the operands. + + Using the Einstein summation convention, many common multi-dimensional, + linear algebraic array operations can be represented in a simple fashion. + In *implicit* mode `einsum` computes these values. + + In *explicit* mode, `einsum` provides further flexibility to compute + other array operations that might not be considered classical Einstein + summation operations, by disabling, or forcing summation over specified + subscript labels. + + See the notes and examples for clarification. + + Parameters + ---------- + subscripts : str + Specifies the subscripts for summation as comma separated list of + subscript labels. An implicit (classical Einstein summation) + calculation is performed unless the explicit indicator '->' is + included as well as subscript labels of the precise output form. + operands : list of array_like + These are the arrays for the operation. + out : ndarray, optional + If provided, the calculation is done into this array. + dtype : {data-type, None}, optional + If provided, forces the calculation to use the data type specified. + Note that you may have to also give a more liberal `casting` + parameter to allow the conversions. Default is None. + order : {'C', 'F', 'A', 'K'}, optional + Controls the memory layout of the output. 'C' means it should + be C contiguous. 'F' means it should be Fortran contiguous, + 'A' means it should be 'F' if the inputs are all 'F', 'C' otherwise. + 'K' means it should be as close to the layout as the inputs as + is possible, including arbitrarily permuted axes. + Default is 'K'. + casting : {'no', 'equiv', 'safe', 'same_kind', 'unsafe'}, optional + Controls what kind of data casting may occur. Setting this to + 'unsafe' is not recommended, as it can adversely affect accumulations. + + * 'no' means the data types should not be cast at all. + * 'equiv' means only byte-order changes are allowed. + * 'safe' means only casts which can preserve values are allowed. + * 'same_kind' means only safe casts or casts within a kind, + like float64 to float32, are allowed. + * 'unsafe' means any data conversions may be done. + + Default is 'safe'. + optimize : {False, True, 'greedy', 'optimal'}, optional + Controls if intermediate optimization should occur. No optimization + will occur if False and True will default to the 'greedy' algorithm. + Also accepts an explicit contraction list from the ``np.einsum_path`` + function. See ``np.einsum_path`` for more details. Defaults to False. + + Returns + ------- + output : ndarray + The calculation based on the Einstein summation convention. + + See Also + -------- + einsum_path, dot, inner, outer, tensordot, linalg.multi_dot + + einops: + similar verbose interface is provided by + `einops `_ package to cover + additional operations: transpose, reshape/flatten, repeat/tile, + squeeze/unsqueeze and reductions. + + opt_einsum: + `opt_einsum `_ + optimizes contraction order for einsum-like expressions + in backend-agnostic manner. + + Notes + ----- + .. versionadded:: 1.6.0 + + The Einstein summation convention can be used to compute + many multi-dimensional, linear algebraic array operations. `einsum` + provides a succinct way of representing these. + + A non-exhaustive list of these operations, + which can be computed by `einsum`, is shown below along with examples: + + * Trace of an array, :py:func:`numpy.trace`. + * Return a diagonal, :py:func:`numpy.diag`. + * Array axis summations, :py:func:`numpy.sum`. + * Transpositions and permutations, :py:func:`numpy.transpose`. + * Matrix multiplication and dot product, :py:func:`numpy.matmul` :py:func:`numpy.dot`. + * Vector inner and outer products, :py:func:`numpy.inner` :py:func:`numpy.outer`. + * Broadcasting, element-wise and scalar multiplication, :py:func:`numpy.multiply`. + * Tensor contractions, :py:func:`numpy.tensordot`. + * Chained array operations, in efficient calculation order, :py:func:`numpy.einsum_path`. + + The subscripts string is a comma-separated list of subscript labels, + where each label refers to a dimension of the corresponding operand. + Whenever a label is repeated it is summed, so ``np.einsum('i,i', a, b)`` + is equivalent to :py:func:`np.inner(a,b) `. If a label + appears only once, it is not summed, so ``np.einsum('i', a)`` produces a + view of ``a`` with no changes. A further example ``np.einsum('ij,jk', a, b)`` + describes traditional matrix multiplication and is equivalent to + :py:func:`np.matmul(a,b) `. Repeated subscript labels in one + operand take the diagonal. For example, ``np.einsum('ii', a)`` is equivalent + to :py:func:`np.trace(a) `. + + In *implicit mode*, the chosen subscripts are important + since the axes of the output are reordered alphabetically. This + means that ``np.einsum('ij', a)`` doesn't affect a 2D array, while + ``np.einsum('ji', a)`` takes its transpose. Additionally, + ``np.einsum('ij,jk', a, b)`` returns a matrix multiplication, while, + ``np.einsum('ij,jh', a, b)`` returns the transpose of the + multiplication since subscript 'h' precedes subscript 'i'. + + In *explicit mode* the output can be directly controlled by + specifying output subscript labels. This requires the + identifier '->' as well as the list of output subscript labels. + This feature increases the flexibility of the function since + summing can be disabled or forced when required. The call + ``np.einsum('i->', a)`` is like :py:func:`np.sum(a, axis=-1) `, + and ``np.einsum('ii->i', a)`` is like :py:func:`np.diag(a) `. + The difference is that `einsum` does not allow broadcasting by default. + Additionally ``np.einsum('ij,jh->ih', a, b)`` directly specifies the + order of the output subscript labels and therefore returns matrix + multiplication, unlike the example above in implicit mode. + + To enable and control broadcasting, use an ellipsis. Default + NumPy-style broadcasting is done by adding an ellipsis + to the left of each term, like ``np.einsum('...ii->...i', a)``. + To take the trace along the first and last axes, + you can do ``np.einsum('i...i', a)``, or to do a matrix-matrix + product with the left-most indices instead of rightmost, one can do + ``np.einsum('ij...,jk...->ik...', a, b)``. + + When there is only one operand, no axes are summed, and no output + parameter is provided, a view into the operand is returned instead + of a new array. Thus, taking the diagonal as ``np.einsum('ii->i', a)`` + produces a view (changed in version 1.10.0). + + `einsum` also provides an alternative way to provide the subscripts + and operands as ``einsum(op0, sublist0, op1, sublist1, ..., [sublistout])``. + If the output shape is not provided in this format `einsum` will be + calculated in implicit mode, otherwise it will be performed explicitly. + The examples below have corresponding `einsum` calls with the two + parameter methods. + + .. versionadded:: 1.10.0 + + Views returned from einsum are now writeable whenever the input array + is writeable. For example, ``np.einsum('ijk...->kji...', a)`` will now + have the same effect as :py:func:`np.swapaxes(a, 0, 2) ` + and ``np.einsum('ii->i', a)`` will return a writeable view of the diagonal + of a 2D array. + + .. versionadded:: 1.12.0 + + Added the ``optimize`` argument which will optimize the contraction order + of an einsum expression. For a contraction with three or more operands this + can greatly increase the computational efficiency at the cost of a larger + memory footprint during computation. + + Typically a 'greedy' algorithm is applied which empirical tests have shown + returns the optimal path in the majority of cases. In some cases 'optimal' + will return the superlative path through a more expensive, exhaustive search. + For iterative calculations it may be advisable to calculate the optimal path + once and reuse that path by supplying it as an argument. An example is given + below. + + See :py:func:`numpy.einsum_path` for more details. + + Examples + -------- + >>> a = np.arange(25).reshape(5,5) + >>> b = np.arange(5) + >>> c = np.arange(6).reshape(2,3) + + Trace of a matrix: + + >>> np.einsum('ii', a) + 60 + >>> np.einsum(a, [0,0]) + 60 + >>> np.trace(a) + 60 + + Extract the diagonal (requires explicit form): + + >>> np.einsum('ii->i', a) + array([ 0, 6, 12, 18, 24]) + >>> np.einsum(a, [0,0], [0]) + array([ 0, 6, 12, 18, 24]) + >>> np.diag(a) + array([ 0, 6, 12, 18, 24]) + + Sum over an axis (requires explicit form): + + >>> np.einsum('ij->i', a) + array([ 10, 35, 60, 85, 110]) + >>> np.einsum(a, [0,1], [0]) + array([ 10, 35, 60, 85, 110]) + >>> np.sum(a, axis=1) + array([ 10, 35, 60, 85, 110]) + + For higher dimensional arrays summing a single axis can be done with ellipsis: + + >>> np.einsum('...j->...', a) + array([ 10, 35, 60, 85, 110]) + >>> np.einsum(a, [Ellipsis,1], [Ellipsis]) + array([ 10, 35, 60, 85, 110]) + + Compute a matrix transpose, or reorder any number of axes: + + >>> np.einsum('ji', c) + array([[0, 3], + [1, 4], + [2, 5]]) + >>> np.einsum('ij->ji', c) + array([[0, 3], + [1, 4], + [2, 5]]) + >>> np.einsum(c, [1,0]) + array([[0, 3], + [1, 4], + [2, 5]]) + >>> np.transpose(c) + array([[0, 3], + [1, 4], + [2, 5]]) + + Vector inner products: + + >>> np.einsum('i,i', b, b) + 30 + >>> np.einsum(b, [0], b, [0]) + 30 + >>> np.inner(b,b) + 30 + + Matrix vector multiplication: + + >>> np.einsum('ij,j', a, b) + array([ 30, 80, 130, 180, 230]) + >>> np.einsum(a, [0,1], b, [1]) + array([ 30, 80, 130, 180, 230]) + >>> np.dot(a, b) + array([ 30, 80, 130, 180, 230]) + >>> np.einsum('...j,j', a, b) + array([ 30, 80, 130, 180, 230]) + + Broadcasting and scalar multiplication: + + >>> np.einsum('..., ...', 3, c) + array([[ 0, 3, 6], + [ 9, 12, 15]]) + >>> np.einsum(',ij', 3, c) + array([[ 0, 3, 6], + [ 9, 12, 15]]) + >>> np.einsum(3, [Ellipsis], c, [Ellipsis]) + array([[ 0, 3, 6], + [ 9, 12, 15]]) + >>> np.multiply(3, c) + array([[ 0, 3, 6], + [ 9, 12, 15]]) + + Vector outer product: + + >>> np.einsum('i,j', np.arange(2)+1, b) + array([[0, 1, 2, 3, 4], + [0, 2, 4, 6, 8]]) + >>> np.einsum(np.arange(2)+1, [0], b, [1]) + array([[0, 1, 2, 3, 4], + [0, 2, 4, 6, 8]]) + >>> np.outer(np.arange(2)+1, b) + array([[0, 1, 2, 3, 4], + [0, 2, 4, 6, 8]]) + + Tensor contraction: + + >>> a = np.arange(60.).reshape(3,4,5) + >>> b = np.arange(24.).reshape(4,3,2) + >>> np.einsum('ijk,jil->kl', a, b) + array([[4400., 4730.], + [4532., 4874.], + [4664., 5018.], + [4796., 5162.], + [4928., 5306.]]) + >>> np.einsum(a, [0,1,2], b, [1,0,3], [2,3]) + array([[4400., 4730.], + [4532., 4874.], + [4664., 5018.], + [4796., 5162.], + [4928., 5306.]]) + >>> np.tensordot(a,b, axes=([1,0],[0,1])) + array([[4400., 4730.], + [4532., 4874.], + [4664., 5018.], + [4796., 5162.], + [4928., 5306.]]) + + Writeable returned arrays (since version 1.10.0): + + >>> a = np.zeros((3, 3)) + >>> np.einsum('ii->i', a)[:] = 1 + >>> a + array([[1., 0., 0.], + [0., 1., 0.], + [0., 0., 1.]]) + + Example of ellipsis use: + + >>> a = np.arange(6).reshape((3,2)) + >>> b = np.arange(12).reshape((4,3)) + >>> np.einsum('ki,jk->ij', a, b) + array([[10, 28, 46, 64], + [13, 40, 67, 94]]) + >>> np.einsum('ki,...k->i...', a, b) + array([[10, 28, 46, 64], + [13, 40, 67, 94]]) + >>> np.einsum('k...,jk', a, b) + array([[10, 28, 46, 64], + [13, 40, 67, 94]]) + + Chained array operations. For more complicated contractions, speed ups + might be achieved by repeatedly computing a 'greedy' path or pre-computing the + 'optimal' path and repeatedly applying it, using an + `einsum_path` insertion (since version 1.12.0). Performance improvements can be + particularly significant with larger arrays: + + >>> a = np.ones(64).reshape(2,4,8) + + Basic `einsum`: ~1520ms (benchmarked on 3.1GHz Intel i5.) + + >>> for iteration in range(500): + ... _ = np.einsum('ijk,ilm,njm,nlk,abc->',a,a,a,a,a) + + Sub-optimal `einsum` (due to repeated path calculation time): ~330ms + + >>> for iteration in range(500): + ... _ = np.einsum('ijk,ilm,njm,nlk,abc->',a,a,a,a,a, optimize='optimal') + + Greedy `einsum` (faster optimal path approximation): ~160ms + + >>> for iteration in range(500): + ... _ = np.einsum('ijk,ilm,njm,nlk,abc->',a,a,a,a,a, optimize='greedy') + + Optimal `einsum` (best usage pattern in some use cases): ~110ms + + >>> path = np.einsum_path('ijk,ilm,njm,nlk,abc->',a,a,a,a,a, optimize='optimal')[0] + >>> for iteration in range(500): + ... _ = np.einsum('ijk,ilm,njm,nlk,abc->',a,a,a,a,a, optimize=path) + + """ + # Special handling if out is specified + specified_out = out is not None + + # If no optimization, run pure einsum + if optimize is False: + if specified_out: + kwargs['out'] = out + return c_einsum(*operands, **kwargs) + + # Check the kwargs to avoid a more cryptic error later, without having to + # repeat default values here + valid_einsum_kwargs = ['dtype', 'order', 'casting'] + unknown_kwargs = [k for (k, v) in kwargs.items() if + k not in valid_einsum_kwargs] + if len(unknown_kwargs): + raise TypeError("Did not understand the following kwargs: %s" + % unknown_kwargs) + + # Build the contraction list and operand + operands, contraction_list = einsum_path(*operands, optimize=optimize, + einsum_call=True) + + # Handle order kwarg for output array, c_einsum allows mixed case + output_order = kwargs.pop('order', 'K') + if output_order.upper() == 'A': + if all(arr.flags.f_contiguous for arr in operands): + output_order = 'F' + else: + output_order = 'C' + + # Start contraction loop + for num, contraction in enumerate(contraction_list): + inds, idx_rm, einsum_str, remaining, blas = contraction + tmp_operands = [operands.pop(x) for x in inds] + + # Do we need to deal with the output? + handle_out = specified_out and ((num + 1) == len(contraction_list)) + + # Call tensordot if still possible + if blas: + # Checks have already been handled + input_str, results_index = einsum_str.split('->') + input_left, input_right = input_str.split(',') + + tensor_result = input_left + input_right + for s in idx_rm: + tensor_result = tensor_result.replace(s, "") + + # Find indices to contract over + left_pos, right_pos = [], [] + for s in sorted(idx_rm): + left_pos.append(input_left.find(s)) + right_pos.append(input_right.find(s)) + + # Contract! + new_view = tensordot(*tmp_operands, axes=(tuple(left_pos), tuple(right_pos))) + + # Build a new view if needed + if (tensor_result != results_index) or handle_out: + if handle_out: + kwargs["out"] = out + new_view = c_einsum(tensor_result + '->' + results_index, new_view, **kwargs) + + # Call einsum + else: + # If out was specified + if handle_out: + kwargs["out"] = out + + # Do the contraction + new_view = c_einsum(einsum_str, *tmp_operands, **kwargs) + + # Append new items and dereference what we can + operands.append(new_view) + del tmp_operands, new_view + + if specified_out: + return out + else: + return asanyarray(operands[0], order=output_order) diff --git a/venv/Lib/site-packages/numpy/core/fromnumeric.py b/venv/Lib/site-packages/numpy/core/fromnumeric.py new file mode 100644 index 0000000..d65e268 --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/fromnumeric.py @@ -0,0 +1,3768 @@ +"""Module containing non-deprecated functions borrowed from Numeric. + +""" +import functools +import types +import warnings + +import numpy as np +from . import multiarray as mu +from . import overrides +from . import umath as um +from . import numerictypes as nt +from ._asarray import asarray, array, asanyarray +from .multiarray import concatenate +from . import _methods + +_dt_ = nt.sctype2char + +# functions that are methods +__all__ = [ + 'alen', 'all', 'alltrue', 'amax', 'amin', 'any', 'argmax', + 'argmin', 'argpartition', 'argsort', 'around', 'choose', 'clip', + 'compress', 'cumprod', 'cumproduct', 'cumsum', 'diagonal', 'mean', + 'ndim', 'nonzero', 'partition', 'prod', 'product', 'ptp', 'put', + 'ravel', 'repeat', 'reshape', 'resize', 'round_', + 'searchsorted', 'shape', 'size', 'sometrue', 'sort', 'squeeze', + 'std', 'sum', 'swapaxes', 'take', 'trace', 'transpose', 'var', +] + +_gentype = types.GeneratorType +# save away Python sum +_sum_ = sum + +array_function_dispatch = functools.partial( + overrides.array_function_dispatch, module='numpy') + + +# functions that are now methods +def _wrapit(obj, method, *args, **kwds): + try: + wrap = obj.__array_wrap__ + except AttributeError: + wrap = None + result = getattr(asarray(obj), method)(*args, **kwds) + if wrap: + if not isinstance(result, mu.ndarray): + result = asarray(result) + result = wrap(result) + return result + + +def _wrapfunc(obj, method, *args, **kwds): + bound = getattr(obj, method, None) + if bound is None: + return _wrapit(obj, method, *args, **kwds) + + try: + return bound(*args, **kwds) + except TypeError: + # A TypeError occurs if the object does have such a method in its + # class, but its signature is not identical to that of NumPy's. This + # situation has occurred in the case of a downstream library like + # 'pandas'. + # + # Call _wrapit from within the except clause to ensure a potential + # exception has a traceback chain. + return _wrapit(obj, method, *args, **kwds) + + +def _wrapreduction(obj, ufunc, method, axis, dtype, out, **kwargs): + passkwargs = {k: v for k, v in kwargs.items() + if v is not np._NoValue} + + if type(obj) is not mu.ndarray: + try: + reduction = getattr(obj, method) + except AttributeError: + pass + else: + # This branch is needed for reductions like any which don't + # support a dtype. + if dtype is not None: + return reduction(axis=axis, dtype=dtype, out=out, **passkwargs) + else: + return reduction(axis=axis, out=out, **passkwargs) + + return ufunc.reduce(obj, axis, dtype, out, **passkwargs) + + +def _take_dispatcher(a, indices, axis=None, out=None, mode=None): + return (a, out) + + +@array_function_dispatch(_take_dispatcher) +def take(a, indices, axis=None, out=None, mode='raise'): + """ + Take elements from an array along an axis. + + When axis is not None, this function does the same thing as "fancy" + indexing (indexing arrays using arrays); however, it can be easier to use + if you need elements along a given axis. A call such as + ``np.take(arr, indices, axis=3)`` is equivalent to + ``arr[:,:,:,indices,...]``. + + Explained without fancy indexing, this is equivalent to the following use + of `ndindex`, which sets each of ``ii``, ``jj``, and ``kk`` to a tuple of + indices:: + + Ni, Nk = a.shape[:axis], a.shape[axis+1:] + Nj = indices.shape + for ii in ndindex(Ni): + for jj in ndindex(Nj): + for kk in ndindex(Nk): + out[ii + jj + kk] = a[ii + (indices[jj],) + kk] + + Parameters + ---------- + a : array_like (Ni..., M, Nk...) + The source array. + indices : array_like (Nj...) + The indices of the values to extract. + + .. versionadded:: 1.8.0 + + Also allow scalars for indices. + axis : int, optional + The axis over which to select values. By default, the flattened + input array is used. + out : ndarray, optional (Ni..., Nj..., Nk...) + If provided, the result will be placed in this array. It should + be of the appropriate shape and dtype. Note that `out` is always + buffered if `mode='raise'`; use other modes for better performance. + mode : {'raise', 'wrap', 'clip'}, optional + Specifies how out-of-bounds indices will behave. + + * 'raise' -- raise an error (default) + * 'wrap' -- wrap around + * 'clip' -- clip to the range + + 'clip' mode means that all indices that are too large are replaced + by the index that addresses the last element along that axis. Note + that this disables indexing with negative numbers. + + Returns + ------- + out : ndarray (Ni..., Nj..., Nk...) + The returned array has the same type as `a`. + + See Also + -------- + compress : Take elements using a boolean mask + ndarray.take : equivalent method + take_along_axis : Take elements by matching the array and the index arrays + + Notes + ----- + + By eliminating the inner loop in the description above, and using `s_` to + build simple slice objects, `take` can be expressed in terms of applying + fancy indexing to each 1-d slice:: + + Ni, Nk = a.shape[:axis], a.shape[axis+1:] + for ii in ndindex(Ni): + for kk in ndindex(Nj): + out[ii + s_[...,] + kk] = a[ii + s_[:,] + kk][indices] + + For this reason, it is equivalent to (but faster than) the following use + of `apply_along_axis`:: + + out = np.apply_along_axis(lambda a_1d: a_1d[indices], axis, a) + + Examples + -------- + >>> a = [4, 3, 5, 7, 6, 8] + >>> indices = [0, 1, 4] + >>> np.take(a, indices) + array([4, 3, 6]) + + In this example if `a` is an ndarray, "fancy" indexing can be used. + + >>> a = np.array(a) + >>> a[indices] + array([4, 3, 6]) + + If `indices` is not one dimensional, the output also has these dimensions. + + >>> np.take(a, [[0, 1], [2, 3]]) + array([[4, 3], + [5, 7]]) + """ + return _wrapfunc(a, 'take', indices, axis=axis, out=out, mode=mode) + + +def _reshape_dispatcher(a, newshape, order=None): + return (a,) + + +# not deprecated --- copy if necessary, view otherwise +@array_function_dispatch(_reshape_dispatcher) +def reshape(a, newshape, order='C'): + """ + Gives a new shape to an array without changing its data. + + Parameters + ---------- + a : array_like + Array to be reshaped. + newshape : int or tuple of ints + The new shape should be compatible with the original shape. If + an integer, then the result will be a 1-D array of that length. + One shape dimension can be -1. In this case, the value is + inferred from the length of the array and remaining dimensions. + order : {'C', 'F', 'A'}, optional + Read the elements of `a` using this index order, and place the + elements into the reshaped array using this index order. 'C' + means to read / write the elements using C-like index order, + with the last axis index changing fastest, back to the first + axis index changing slowest. 'F' means to read / write the + elements using Fortran-like index order, with the first index + changing fastest, and the last index changing slowest. Note that + the 'C' and 'F' options take no account of the memory layout of + the underlying array, and only refer to the order of indexing. + 'A' means to read / write the elements in Fortran-like index + order if `a` is Fortran *contiguous* in memory, C-like order + otherwise. + + Returns + ------- + reshaped_array : ndarray + This will be a new view object if possible; otherwise, it will + be a copy. Note there is no guarantee of the *memory layout* (C- or + Fortran- contiguous) of the returned array. + + See Also + -------- + ndarray.reshape : Equivalent method. + + Notes + ----- + It is not always possible to change the shape of an array without + copying the data. If you want an error to be raised when the data is copied, + you should assign the new shape to the shape attribute of the array:: + + >>> a = np.zeros((10, 2)) + + # A transpose makes the array non-contiguous + >>> b = a.T + + # Taking a view makes it possible to modify the shape without modifying + # the initial object. + >>> c = b.view() + >>> c.shape = (20) + Traceback (most recent call last): + ... + AttributeError: Incompatible shape for in-place modification. Use + `.reshape()` to make a copy with the desired shape. + + The `order` keyword gives the index ordering both for *fetching* the values + from `a`, and then *placing* the values into the output array. + For example, let's say you have an array: + + >>> a = np.arange(6).reshape((3, 2)) + >>> a + array([[0, 1], + [2, 3], + [4, 5]]) + + You can think of reshaping as first raveling the array (using the given + index order), then inserting the elements from the raveled array into the + new array using the same kind of index ordering as was used for the + raveling. + + >>> np.reshape(a, (2, 3)) # C-like index ordering + array([[0, 1, 2], + [3, 4, 5]]) + >>> np.reshape(np.ravel(a), (2, 3)) # equivalent to C ravel then C reshape + array([[0, 1, 2], + [3, 4, 5]]) + >>> np.reshape(a, (2, 3), order='F') # Fortran-like index ordering + array([[0, 4, 3], + [2, 1, 5]]) + >>> np.reshape(np.ravel(a, order='F'), (2, 3), order='F') + array([[0, 4, 3], + [2, 1, 5]]) + + Examples + -------- + >>> a = np.array([[1,2,3], [4,5,6]]) + >>> np.reshape(a, 6) + array([1, 2, 3, 4, 5, 6]) + >>> np.reshape(a, 6, order='F') + array([1, 4, 2, 5, 3, 6]) + + >>> np.reshape(a, (3,-1)) # the unspecified value is inferred to be 2 + array([[1, 2], + [3, 4], + [5, 6]]) + """ + return _wrapfunc(a, 'reshape', newshape, order=order) + + +def _choose_dispatcher(a, choices, out=None, mode=None): + yield a + yield from choices + yield out + + +@array_function_dispatch(_choose_dispatcher) +def choose(a, choices, out=None, mode='raise'): + """ + Construct an array from an index array and a set of arrays to choose from. + + First of all, if confused or uncertain, definitely look at the Examples - + in its full generality, this function is less simple than it might + seem from the following code description (below ndi = + `numpy.lib.index_tricks`): + + ``np.choose(a,c) == np.array([c[a[I]][I] for I in ndi.ndindex(a.shape)])``. + + But this omits some subtleties. Here is a fully general summary: + + Given an "index" array (`a`) of integers and a sequence of `n` arrays + (`choices`), `a` and each choice array are first broadcast, as necessary, + to arrays of a common shape; calling these *Ba* and *Bchoices[i], i = + 0,...,n-1* we have that, necessarily, ``Ba.shape == Bchoices[i].shape`` + for each `i`. Then, a new array with shape ``Ba.shape`` is created as + follows: + + * if ``mode=raise`` (the default), then, first of all, each element of + `a` (and thus `Ba`) must be in the range `[0, n-1]`; now, suppose that + `i` (in that range) is the value at the `(j0, j1, ..., jm)` position + in `Ba` - then the value at the same position in the new array is the + value in `Bchoices[i]` at that same position; + + * if ``mode=wrap``, values in `a` (and thus `Ba`) may be any (signed) + integer; modular arithmetic is used to map integers outside the range + `[0, n-1]` back into that range; and then the new array is constructed + as above; + + * if ``mode=clip``, values in `a` (and thus `Ba`) may be any (signed) + integer; negative integers are mapped to 0; values greater than `n-1` + are mapped to `n-1`; and then the new array is constructed as above. + + Parameters + ---------- + a : int array + This array must contain integers in `[0, n-1]`, where `n` is the number + of choices, unless ``mode=wrap`` or ``mode=clip``, in which cases any + integers are permissible. + choices : sequence of arrays + Choice arrays. `a` and all of the choices must be broadcastable to the + same shape. If `choices` is itself an array (not recommended), then + its outermost dimension (i.e., the one corresponding to + ``choices.shape[0]``) is taken as defining the "sequence". + out : array, optional + If provided, the result will be inserted into this array. It should + be of the appropriate shape and dtype. Note that `out` is always + buffered if `mode='raise'`; use other modes for better performance. + mode : {'raise' (default), 'wrap', 'clip'}, optional + Specifies how indices outside `[0, n-1]` will be treated: + + * 'raise' : an exception is raised + * 'wrap' : value becomes value mod `n` + * 'clip' : values < 0 are mapped to 0, values > n-1 are mapped to n-1 + + Returns + ------- + merged_array : array + The merged result. + + Raises + ------ + ValueError: shape mismatch + If `a` and each choice array are not all broadcastable to the same + shape. + + See Also + -------- + ndarray.choose : equivalent method + numpy.take_along_axis : Preferable if `choices` is an array + + Notes + ----- + To reduce the chance of misinterpretation, even though the following + "abuse" is nominally supported, `choices` should neither be, nor be + thought of as, a single array, i.e., the outermost sequence-like container + should be either a list or a tuple. + + Examples + -------- + + >>> choices = [[0, 1, 2, 3], [10, 11, 12, 13], + ... [20, 21, 22, 23], [30, 31, 32, 33]] + >>> np.choose([2, 3, 1, 0], choices + ... # the first element of the result will be the first element of the + ... # third (2+1) "array" in choices, namely, 20; the second element + ... # will be the second element of the fourth (3+1) choice array, i.e., + ... # 31, etc. + ... ) + array([20, 31, 12, 3]) + >>> np.choose([2, 4, 1, 0], choices, mode='clip') # 4 goes to 3 (4-1) + array([20, 31, 12, 3]) + >>> # because there are 4 choice arrays + >>> np.choose([2, 4, 1, 0], choices, mode='wrap') # 4 goes to (4 mod 4) + array([20, 1, 12, 3]) + >>> # i.e., 0 + + A couple examples illustrating how choose broadcasts: + + >>> a = [[1, 0, 1], [0, 1, 0], [1, 0, 1]] + >>> choices = [-10, 10] + >>> np.choose(a, choices) + array([[ 10, -10, 10], + [-10, 10, -10], + [ 10, -10, 10]]) + + >>> # With thanks to Anne Archibald + >>> a = np.array([0, 1]).reshape((2,1,1)) + >>> c1 = np.array([1, 2, 3]).reshape((1,3,1)) + >>> c2 = np.array([-1, -2, -3, -4, -5]).reshape((1,1,5)) + >>> np.choose(a, (c1, c2)) # result is 2x3x5, res[0,:,:]=c1, res[1,:,:]=c2 + array([[[ 1, 1, 1, 1, 1], + [ 2, 2, 2, 2, 2], + [ 3, 3, 3, 3, 3]], + [[-1, -2, -3, -4, -5], + [-1, -2, -3, -4, -5], + [-1, -2, -3, -4, -5]]]) + + """ + return _wrapfunc(a, 'choose', choices, out=out, mode=mode) + + +def _repeat_dispatcher(a, repeats, axis=None): + return (a,) + + +@array_function_dispatch(_repeat_dispatcher) +def repeat(a, repeats, axis=None): + """ + Repeat elements of an array. + + Parameters + ---------- + a : array_like + Input array. + repeats : int or array of ints + The number of repetitions for each element. `repeats` is broadcasted + to fit the shape of the given axis. + axis : int, optional + The axis along which to repeat values. By default, use the + flattened input array, and return a flat output array. + + Returns + ------- + repeated_array : ndarray + Output array which has the same shape as `a`, except along + the given axis. + + See Also + -------- + tile : Tile an array. + unique : Find the unique elements of an array. + + Examples + -------- + >>> np.repeat(3, 4) + array([3, 3, 3, 3]) + >>> x = np.array([[1,2],[3,4]]) + >>> np.repeat(x, 2) + array([1, 1, 2, 2, 3, 3, 4, 4]) + >>> np.repeat(x, 3, axis=1) + array([[1, 1, 1, 2, 2, 2], + [3, 3, 3, 4, 4, 4]]) + >>> np.repeat(x, [1, 2], axis=0) + array([[1, 2], + [3, 4], + [3, 4]]) + + """ + return _wrapfunc(a, 'repeat', repeats, axis=axis) + + +def _put_dispatcher(a, ind, v, mode=None): + return (a, ind, v) + + +@array_function_dispatch(_put_dispatcher) +def put(a, ind, v, mode='raise'): + """ + Replaces specified elements of an array with given values. + + The indexing works on the flattened target array. `put` is roughly + equivalent to: + + :: + + a.flat[ind] = v + + Parameters + ---------- + a : ndarray + Target array. + ind : array_like + Target indices, interpreted as integers. + v : array_like + Values to place in `a` at target indices. If `v` is shorter than + `ind` it will be repeated as necessary. + mode : {'raise', 'wrap', 'clip'}, optional + Specifies how out-of-bounds indices will behave. + + * 'raise' -- raise an error (default) + * 'wrap' -- wrap around + * 'clip' -- clip to the range + + 'clip' mode means that all indices that are too large are replaced + by the index that addresses the last element along that axis. Note + that this disables indexing with negative numbers. In 'raise' mode, + if an exception occurs the target array may still be modified. + + See Also + -------- + putmask, place + put_along_axis : Put elements by matching the array and the index arrays + + Examples + -------- + >>> a = np.arange(5) + >>> np.put(a, [0, 2], [-44, -55]) + >>> a + array([-44, 1, -55, 3, 4]) + + >>> a = np.arange(5) + >>> np.put(a, 22, -5, mode='clip') + >>> a + array([ 0, 1, 2, 3, -5]) + + """ + try: + put = a.put + except AttributeError as e: + raise TypeError("argument 1 must be numpy.ndarray, " + "not {name}".format(name=type(a).__name__)) from e + + return put(ind, v, mode=mode) + + +def _swapaxes_dispatcher(a, axis1, axis2): + return (a,) + + +@array_function_dispatch(_swapaxes_dispatcher) +def swapaxes(a, axis1, axis2): + """ + Interchange two axes of an array. + + Parameters + ---------- + a : array_like + Input array. + axis1 : int + First axis. + axis2 : int + Second axis. + + Returns + ------- + a_swapped : ndarray + For NumPy >= 1.10.0, if `a` is an ndarray, then a view of `a` is + returned; otherwise a new array is created. For earlier NumPy + versions a view of `a` is returned only if the order of the + axes is changed, otherwise the input array is returned. + + Examples + -------- + >>> x = np.array([[1,2,3]]) + >>> np.swapaxes(x,0,1) + array([[1], + [2], + [3]]) + + >>> x = np.array([[[0,1],[2,3]],[[4,5],[6,7]]]) + >>> x + array([[[0, 1], + [2, 3]], + [[4, 5], + [6, 7]]]) + + >>> np.swapaxes(x,0,2) + array([[[0, 4], + [2, 6]], + [[1, 5], + [3, 7]]]) + + """ + return _wrapfunc(a, 'swapaxes', axis1, axis2) + + +def _transpose_dispatcher(a, axes=None): + return (a,) + + +@array_function_dispatch(_transpose_dispatcher) +def transpose(a, axes=None): + """ + Reverse or permute the axes of an array; returns the modified array. + + For an array a with two axes, transpose(a) gives the matrix transpose. + + Parameters + ---------- + a : array_like + Input array. + axes : tuple or list of ints, optional + If specified, it must be a tuple or list which contains a permutation of + [0,1,..,N-1] where N is the number of axes of a. The i'th axis of the + returned array will correspond to the axis numbered ``axes[i]`` of the + input. If not specified, defaults to ``range(a.ndim)[::-1]``, which + reverses the order of the axes. + + Returns + ------- + p : ndarray + `a` with its axes permuted. A view is returned whenever + possible. + + See Also + -------- + moveaxis + argsort + + Notes + ----- + Use `transpose(a, argsort(axes))` to invert the transposition of tensors + when using the `axes` keyword argument. + + Transposing a 1-D array returns an unchanged view of the original array. + + Examples + -------- + >>> x = np.arange(4).reshape((2,2)) + >>> x + array([[0, 1], + [2, 3]]) + + >>> np.transpose(x) + array([[0, 2], + [1, 3]]) + + >>> x = np.ones((1, 2, 3)) + >>> np.transpose(x, (1, 0, 2)).shape + (2, 1, 3) + + >>> x = np.ones((2, 3, 4, 5)) + >>> np.transpose(x).shape + (5, 4, 3, 2) + + """ + return _wrapfunc(a, 'transpose', axes) + + +def _partition_dispatcher(a, kth, axis=None, kind=None, order=None): + return (a,) + + +@array_function_dispatch(_partition_dispatcher) +def partition(a, kth, axis=-1, kind='introselect', order=None): + """ + Return a partitioned copy of an array. + + Creates a copy of the array with its elements rearranged in such a + way that the value of the element in k-th position is in the + position it would be in a sorted array. All elements smaller than + the k-th element are moved before this element and all equal or + greater are moved behind it. The ordering of the elements in the two + partitions is undefined. + + .. versionadded:: 1.8.0 + + Parameters + ---------- + a : array_like + Array to be sorted. + kth : int or sequence of ints + Element index to partition by. The k-th value of the element + will be in its final sorted position and all smaller elements + will be moved before it and all equal or greater elements behind + it. The order of all elements in the partitions is undefined. If + provided with a sequence of k-th it will partition all elements + indexed by k-th of them into their sorted position at once. + axis : int or None, optional + Axis along which to sort. If None, the array is flattened before + sorting. The default is -1, which sorts along the last axis. + kind : {'introselect'}, optional + Selection algorithm. Default is 'introselect'. + order : str or list of str, optional + When `a` is an array with fields defined, this argument + specifies which fields to compare first, second, etc. A single + field can be specified as a string. Not all fields need be + specified, but unspecified fields will still be used, in the + order in which they come up in the dtype, to break ties. + + Returns + ------- + partitioned_array : ndarray + Array of the same type and shape as `a`. + + See Also + -------- + ndarray.partition : Method to sort an array in-place. + argpartition : Indirect partition. + sort : Full sorting + + Notes + ----- + The various selection algorithms are characterized by their average + speed, worst case performance, work space size, and whether they are + stable. A stable sort keeps items with the same key in the same + relative order. The available algorithms have the following + properties: + + ================= ======= ============= ============ ======= + kind speed worst case work space stable + ================= ======= ============= ============ ======= + 'introselect' 1 O(n) 0 no + ================= ======= ============= ============ ======= + + All the partition algorithms make temporary copies of the data when + partitioning along any but the last axis. Consequently, + partitioning along the last axis is faster and uses less space than + partitioning along any other axis. + + The sort order for complex numbers is lexicographic. If both the + real and imaginary parts are non-nan then the order is determined by + the real parts except when they are equal, in which case the order + is determined by the imaginary parts. + + Examples + -------- + >>> a = np.array([3, 4, 2, 1]) + >>> np.partition(a, 3) + array([2, 1, 3, 4]) + + >>> np.partition(a, (1, 3)) + array([1, 2, 3, 4]) + + """ + if axis is None: + # flatten returns (1, N) for np.matrix, so always use the last axis + a = asanyarray(a).flatten() + axis = -1 + else: + a = asanyarray(a).copy(order="K") + a.partition(kth, axis=axis, kind=kind, order=order) + return a + + +def _argpartition_dispatcher(a, kth, axis=None, kind=None, order=None): + return (a,) + + +@array_function_dispatch(_argpartition_dispatcher) +def argpartition(a, kth, axis=-1, kind='introselect', order=None): + """ + Perform an indirect partition along the given axis using the + algorithm specified by the `kind` keyword. It returns an array of + indices of the same shape as `a` that index data along the given + axis in partitioned order. + + .. versionadded:: 1.8.0 + + Parameters + ---------- + a : array_like + Array to sort. + kth : int or sequence of ints + Element index to partition by. The k-th element will be in its + final sorted position and all smaller elements will be moved + before it and all larger elements behind it. The order all + elements in the partitions is undefined. If provided with a + sequence of k-th it will partition all of them into their sorted + position at once. + axis : int or None, optional + Axis along which to sort. The default is -1 (the last axis). If + None, the flattened array is used. + kind : {'introselect'}, optional + Selection algorithm. Default is 'introselect' + order : str or list of str, optional + When `a` is an array with fields defined, this argument + specifies which fields to compare first, second, etc. A single + field can be specified as a string, and not all fields need be + specified, but unspecified fields will still be used, in the + order in which they come up in the dtype, to break ties. + + Returns + ------- + index_array : ndarray, int + Array of indices that partition `a` along the specified axis. + If `a` is one-dimensional, ``a[index_array]`` yields a partitioned `a`. + More generally, ``np.take_along_axis(a, index_array, axis=a)`` always + yields the partitioned `a`, irrespective of dimensionality. + + See Also + -------- + partition : Describes partition algorithms used. + ndarray.partition : Inplace partition. + argsort : Full indirect sort. + take_along_axis : Apply ``index_array`` from argpartition + to an array as if by calling partition. + + Notes + ----- + See `partition` for notes on the different selection algorithms. + + Examples + -------- + One dimensional array: + + >>> x = np.array([3, 4, 2, 1]) + >>> x[np.argpartition(x, 3)] + array([2, 1, 3, 4]) + >>> x[np.argpartition(x, (1, 3))] + array([1, 2, 3, 4]) + + >>> x = [3, 4, 2, 1] + >>> np.array(x)[np.argpartition(x, 3)] + array([2, 1, 3, 4]) + + Multi-dimensional array: + + >>> x = np.array([[3, 4, 2], [1, 3, 1]]) + >>> index_array = np.argpartition(x, kth=1, axis=-1) + >>> np.take_along_axis(x, index_array, axis=-1) # same as np.partition(x, kth=1) + array([[2, 3, 4], + [1, 1, 3]]) + + """ + return _wrapfunc(a, 'argpartition', kth, axis=axis, kind=kind, order=order) + + +def _sort_dispatcher(a, axis=None, kind=None, order=None): + return (a,) + + +@array_function_dispatch(_sort_dispatcher) +def sort(a, axis=-1, kind=None, order=None): + """ + Return a sorted copy of an array. + + Parameters + ---------- + a : array_like + Array to be sorted. + axis : int or None, optional + Axis along which to sort. If None, the array is flattened before + sorting. The default is -1, which sorts along the last axis. + kind : {'quicksort', 'mergesort', 'heapsort', 'stable'}, optional + Sorting algorithm. The default is 'quicksort'. Note that both 'stable' + and 'mergesort' use timsort or radix sort under the covers and, in general, + the actual implementation will vary with data type. The 'mergesort' option + is retained for backwards compatibility. + + .. versionchanged:: 1.15.0. + The 'stable' option was added. + + order : str or list of str, optional + When `a` is an array with fields defined, this argument specifies + which fields to compare first, second, etc. A single field can + be specified as a string, and not all fields need be specified, + but unspecified fields will still be used, in the order in which + they come up in the dtype, to break ties. + + Returns + ------- + sorted_array : ndarray + Array of the same type and shape as `a`. + + See Also + -------- + ndarray.sort : Method to sort an array in-place. + argsort : Indirect sort. + lexsort : Indirect stable sort on multiple keys. + searchsorted : Find elements in a sorted array. + partition : Partial sort. + + Notes + ----- + The various sorting algorithms are characterized by their average speed, + worst case performance, work space size, and whether they are stable. A + stable sort keeps items with the same key in the same relative + order. The four algorithms implemented in NumPy have the following + properties: + + =========== ======= ============= ============ ======== + kind speed worst case work space stable + =========== ======= ============= ============ ======== + 'quicksort' 1 O(n^2) 0 no + 'heapsort' 3 O(n*log(n)) 0 no + 'mergesort' 2 O(n*log(n)) ~n/2 yes + 'timsort' 2 O(n*log(n)) ~n/2 yes + =========== ======= ============= ============ ======== + + .. note:: The datatype determines which of 'mergesort' or 'timsort' + is actually used, even if 'mergesort' is specified. User selection + at a finer scale is not currently available. + + All the sort algorithms make temporary copies of the data when + sorting along any but the last axis. Consequently, sorting along + the last axis is faster and uses less space than sorting along + any other axis. + + The sort order for complex numbers is lexicographic. If both the real + and imaginary parts are non-nan then the order is determined by the + real parts except when they are equal, in which case the order is + determined by the imaginary parts. + + Previous to numpy 1.4.0 sorting real and complex arrays containing nan + values led to undefined behaviour. In numpy versions >= 1.4.0 nan + values are sorted to the end. The extended sort order is: + + * Real: [R, nan] + * Complex: [R + Rj, R + nanj, nan + Rj, nan + nanj] + + where R is a non-nan real value. Complex values with the same nan + placements are sorted according to the non-nan part if it exists. + Non-nan values are sorted as before. + + .. versionadded:: 1.12.0 + + quicksort has been changed to `introsort `_. + When sorting does not make enough progress it switches to + `heapsort `_. + This implementation makes quicksort O(n*log(n)) in the worst case. + + 'stable' automatically chooses the best stable sorting algorithm + for the data type being sorted. + It, along with 'mergesort' is currently mapped to + `timsort `_ + or `radix sort `_ + depending on the data type. + API forward compatibility currently limits the + ability to select the implementation and it is hardwired for the different + data types. + + .. versionadded:: 1.17.0 + + Timsort is added for better performance on already or nearly + sorted data. On random data timsort is almost identical to + mergesort. It is now used for stable sort while quicksort is still the + default sort if none is chosen. For timsort details, refer to + `CPython listsort.txt `_. + 'mergesort' and 'stable' are mapped to radix sort for integer data types. Radix sort is an + O(n) sort instead of O(n log n). + + .. versionchanged:: 1.18.0 + + NaT now sorts to the end of arrays for consistency with NaN. + + Examples + -------- + >>> a = np.array([[1,4],[3,1]]) + >>> np.sort(a) # sort along the last axis + array([[1, 4], + [1, 3]]) + >>> np.sort(a, axis=None) # sort the flattened array + array([1, 1, 3, 4]) + >>> np.sort(a, axis=0) # sort along the first axis + array([[1, 1], + [3, 4]]) + + Use the `order` keyword to specify a field to use when sorting a + structured array: + + >>> dtype = [('name', 'S10'), ('height', float), ('age', int)] + >>> values = [('Arthur', 1.8, 41), ('Lancelot', 1.9, 38), + ... ('Galahad', 1.7, 38)] + >>> a = np.array(values, dtype=dtype) # create a structured array + >>> np.sort(a, order='height') # doctest: +SKIP + array([('Galahad', 1.7, 38), ('Arthur', 1.8, 41), + ('Lancelot', 1.8999999999999999, 38)], + dtype=[('name', '|S10'), ('height', '>> np.sort(a, order=['age', 'height']) # doctest: +SKIP + array([('Galahad', 1.7, 38), ('Lancelot', 1.8999999999999999, 38), + ('Arthur', 1.8, 41)], + dtype=[('name', '|S10'), ('height', '>> x = np.array([3, 1, 2]) + >>> np.argsort(x) + array([1, 2, 0]) + + Two-dimensional array: + + >>> x = np.array([[0, 3], [2, 2]]) + >>> x + array([[0, 3], + [2, 2]]) + + >>> ind = np.argsort(x, axis=0) # sorts along first axis (down) + >>> ind + array([[0, 1], + [1, 0]]) + >>> np.take_along_axis(x, ind, axis=0) # same as np.sort(x, axis=0) + array([[0, 2], + [2, 3]]) + + >>> ind = np.argsort(x, axis=1) # sorts along last axis (across) + >>> ind + array([[0, 1], + [0, 1]]) + >>> np.take_along_axis(x, ind, axis=1) # same as np.sort(x, axis=1) + array([[0, 3], + [2, 2]]) + + Indices of the sorted elements of a N-dimensional array: + + >>> ind = np.unravel_index(np.argsort(x, axis=None), x.shape) + >>> ind + (array([0, 1, 1, 0]), array([0, 0, 1, 1])) + >>> x[ind] # same as np.sort(x, axis=None) + array([0, 2, 2, 3]) + + Sorting with keys: + + >>> x = np.array([(1, 0), (0, 1)], dtype=[('x', '>> x + array([(1, 0), (0, 1)], + dtype=[('x', '>> np.argsort(x, order=('x','y')) + array([1, 0]) + + >>> np.argsort(x, order=('y','x')) + array([0, 1]) + + """ + return _wrapfunc(a, 'argsort', axis=axis, kind=kind, order=order) + + +def _argmax_dispatcher(a, axis=None, out=None): + return (a, out) + + +@array_function_dispatch(_argmax_dispatcher) +def argmax(a, axis=None, out=None): + """ + Returns the indices of the maximum values along an axis. + + Parameters + ---------- + a : array_like + Input array. + axis : int, optional + By default, the index is into the flattened array, otherwise + along the specified axis. + out : array, optional + If provided, the result will be inserted into this array. It should + be of the appropriate shape and dtype. + + Returns + ------- + index_array : ndarray of ints + Array of indices into the array. It has the same shape as `a.shape` + with the dimension along `axis` removed. + + See Also + -------- + ndarray.argmax, argmin + amax : The maximum value along a given axis. + unravel_index : Convert a flat index into an index tuple. + take_along_axis : Apply ``np.expand_dims(index_array, axis)`` + from argmax to an array as if by calling max. + + Notes + ----- + In case of multiple occurrences of the maximum values, the indices + corresponding to the first occurrence are returned. + + Examples + -------- + >>> a = np.arange(6).reshape(2,3) + 10 + >>> a + array([[10, 11, 12], + [13, 14, 15]]) + >>> np.argmax(a) + 5 + >>> np.argmax(a, axis=0) + array([1, 1, 1]) + >>> np.argmax(a, axis=1) + array([2, 2]) + + Indexes of the maximal elements of a N-dimensional array: + + >>> ind = np.unravel_index(np.argmax(a, axis=None), a.shape) + >>> ind + (1, 2) + >>> a[ind] + 15 + + >>> b = np.arange(6) + >>> b[1] = 5 + >>> b + array([0, 5, 2, 3, 4, 5]) + >>> np.argmax(b) # Only the first occurrence is returned. + 1 + + >>> x = np.array([[4,2,3], [1,0,3]]) + >>> index_array = np.argmax(x, axis=-1) + >>> # Same as np.max(x, axis=-1, keepdims=True) + >>> np.take_along_axis(x, np.expand_dims(index_array, axis=-1), axis=-1) + array([[4], + [3]]) + >>> # Same as np.max(x, axis=-1) + >>> np.take_along_axis(x, np.expand_dims(index_array, axis=-1), axis=-1).squeeze(axis=-1) + array([4, 3]) + + """ + return _wrapfunc(a, 'argmax', axis=axis, out=out) + + +def _argmin_dispatcher(a, axis=None, out=None): + return (a, out) + + +@array_function_dispatch(_argmin_dispatcher) +def argmin(a, axis=None, out=None): + """ + Returns the indices of the minimum values along an axis. + + Parameters + ---------- + a : array_like + Input array. + axis : int, optional + By default, the index is into the flattened array, otherwise + along the specified axis. + out : array, optional + If provided, the result will be inserted into this array. It should + be of the appropriate shape and dtype. + + Returns + ------- + index_array : ndarray of ints + Array of indices into the array. It has the same shape as `a.shape` + with the dimension along `axis` removed. + + See Also + -------- + ndarray.argmin, argmax + amin : The minimum value along a given axis. + unravel_index : Convert a flat index into an index tuple. + take_along_axis : Apply ``np.expand_dims(index_array, axis)`` + from argmin to an array as if by calling min. + + Notes + ----- + In case of multiple occurrences of the minimum values, the indices + corresponding to the first occurrence are returned. + + Examples + -------- + >>> a = np.arange(6).reshape(2,3) + 10 + >>> a + array([[10, 11, 12], + [13, 14, 15]]) + >>> np.argmin(a) + 0 + >>> np.argmin(a, axis=0) + array([0, 0, 0]) + >>> np.argmin(a, axis=1) + array([0, 0]) + + Indices of the minimum elements of a N-dimensional array: + + >>> ind = np.unravel_index(np.argmin(a, axis=None), a.shape) + >>> ind + (0, 0) + >>> a[ind] + 10 + + >>> b = np.arange(6) + 10 + >>> b[4] = 10 + >>> b + array([10, 11, 12, 13, 10, 15]) + >>> np.argmin(b) # Only the first occurrence is returned. + 0 + + >>> x = np.array([[4,2,3], [1,0,3]]) + >>> index_array = np.argmin(x, axis=-1) + >>> # Same as np.min(x, axis=-1, keepdims=True) + >>> np.take_along_axis(x, np.expand_dims(index_array, axis=-1), axis=-1) + array([[2], + [0]]) + >>> # Same as np.max(x, axis=-1) + >>> np.take_along_axis(x, np.expand_dims(index_array, axis=-1), axis=-1).squeeze(axis=-1) + array([2, 0]) + + """ + return _wrapfunc(a, 'argmin', axis=axis, out=out) + + +def _searchsorted_dispatcher(a, v, side=None, sorter=None): + return (a, v, sorter) + + +@array_function_dispatch(_searchsorted_dispatcher) +def searchsorted(a, v, side='left', sorter=None): + """ + Find indices where elements should be inserted to maintain order. + + Find the indices into a sorted array `a` such that, if the + corresponding elements in `v` were inserted before the indices, the + order of `a` would be preserved. + + Assuming that `a` is sorted: + + ====== ============================ + `side` returned index `i` satisfies + ====== ============================ + left ``a[i-1] < v <= a[i]`` + right ``a[i-1] <= v < a[i]`` + ====== ============================ + + Parameters + ---------- + a : 1-D array_like + Input array. If `sorter` is None, then it must be sorted in + ascending order, otherwise `sorter` must be an array of indices + that sort it. + v : array_like + Values to insert into `a`. + side : {'left', 'right'}, optional + If 'left', the index of the first suitable location found is given. + If 'right', return the last such index. If there is no suitable + index, return either 0 or N (where N is the length of `a`). + sorter : 1-D array_like, optional + Optional array of integer indices that sort array a into ascending + order. They are typically the result of argsort. + + .. versionadded:: 1.7.0 + + Returns + ------- + indices : array of ints + Array of insertion points with the same shape as `v`. + + See Also + -------- + sort : Return a sorted copy of an array. + histogram : Produce histogram from 1-D data. + + Notes + ----- + Binary search is used to find the required insertion points. + + As of NumPy 1.4.0 `searchsorted` works with real/complex arrays containing + `nan` values. The enhanced sort order is documented in `sort`. + + This function uses the same algorithm as the builtin python `bisect.bisect_left` + (``side='left'``) and `bisect.bisect_right` (``side='right'``) functions, + which is also vectorized in the `v` argument. + + Examples + -------- + >>> np.searchsorted([1,2,3,4,5], 3) + 2 + >>> np.searchsorted([1,2,3,4,5], 3, side='right') + 3 + >>> np.searchsorted([1,2,3,4,5], [-10, 10, 2, 3]) + array([0, 5, 1, 2]) + + """ + return _wrapfunc(a, 'searchsorted', v, side=side, sorter=sorter) + + +def _resize_dispatcher(a, new_shape): + return (a,) + + +@array_function_dispatch(_resize_dispatcher) +def resize(a, new_shape): + """ + Return a new array with the specified shape. + + If the new array is larger than the original array, then the new + array is filled with repeated copies of `a`. Note that this behavior + is different from a.resize(new_shape) which fills with zeros instead + of repeated copies of `a`. + + Parameters + ---------- + a : array_like + Array to be resized. + + new_shape : int or tuple of int + Shape of resized array. + + Returns + ------- + reshaped_array : ndarray + The new array is formed from the data in the old array, repeated + if necessary to fill out the required number of elements. The + data are repeated in the order that they are stored in memory. + + See Also + -------- + np.reshape : Reshape an array without changing the total size. + np.pad : Enlarge and pad an array. + np.repeat: Repeat elements of an array. + ndarray.resize : resize an array in-place. + + Notes + ----- + When the total size of the array does not change `~numpy.reshape` should + be used. In most other cases either indexing (to reduce the size) + or padding (to increase the size) may be a more appropriate solution. + + Warning: This functionality does **not** consider axes separately, + i.e. it does not apply interpolation/extrapolation. + It fills the return array with the required number of elements, taken + from `a` as they are laid out in memory, disregarding strides and axes. + (This is in case the new shape is smaller. For larger, see above.) + This functionality is therefore not suitable to resize images, + or data where each axis represents a separate and distinct entity. + + Examples + -------- + >>> a=np.array([[0,1],[2,3]]) + >>> np.resize(a,(2,3)) + array([[0, 1, 2], + [3, 0, 1]]) + >>> np.resize(a,(1,4)) + array([[0, 1, 2, 3]]) + >>> np.resize(a,(2,4)) + array([[0, 1, 2, 3], + [0, 1, 2, 3]]) + + """ + if isinstance(new_shape, (int, nt.integer)): + new_shape = (new_shape,) + + a = ravel(a) + + new_size = 1 + for dim_length in new_shape: + new_size *= dim_length + if dim_length < 0: + raise ValueError('all elements of `new_shape` must be non-negative') + + if a.size == 0 or new_size == 0: + # First case must zero fill. The second would have repeats == 0. + return np.zeros_like(a, shape=new_shape) + + repeats = -(-new_size // a.size) # ceil division + a = concatenate((a,) * repeats)[:new_size] + + return reshape(a, new_shape) + + +def _squeeze_dispatcher(a, axis=None): + return (a,) + + +@array_function_dispatch(_squeeze_dispatcher) +def squeeze(a, axis=None): + """ + Remove axes of length one from `a`. + + Parameters + ---------- + a : array_like + Input data. + axis : None or int or tuple of ints, optional + .. versionadded:: 1.7.0 + + Selects a subset of the entries of length one in the + shape. If an axis is selected with shape entry greater than + one, an error is raised. + + Returns + ------- + squeezed : ndarray + The input array, but with all or a subset of the + dimensions of length 1 removed. This is always `a` itself + or a view into `a`. Note that if all axes are squeezed, + the result is a 0d array and not a scalar. + + Raises + ------ + ValueError + If `axis` is not None, and an axis being squeezed is not of length 1 + + See Also + -------- + expand_dims : The inverse operation, adding entries of length one + reshape : Insert, remove, and combine dimensions, and resize existing ones + + Examples + -------- + >>> x = np.array([[[0], [1], [2]]]) + >>> x.shape + (1, 3, 1) + >>> np.squeeze(x).shape + (3,) + >>> np.squeeze(x, axis=0).shape + (3, 1) + >>> np.squeeze(x, axis=1).shape + Traceback (most recent call last): + ... + ValueError: cannot select an axis to squeeze out which has size not equal to one + >>> np.squeeze(x, axis=2).shape + (1, 3) + >>> x = np.array([[1234]]) + >>> x.shape + (1, 1) + >>> np.squeeze(x) + array(1234) # 0d array + >>> np.squeeze(x).shape + () + >>> np.squeeze(x)[()] + 1234 + + """ + try: + squeeze = a.squeeze + except AttributeError: + return _wrapit(a, 'squeeze', axis=axis) + if axis is None: + return squeeze() + else: + return squeeze(axis=axis) + + +def _diagonal_dispatcher(a, offset=None, axis1=None, axis2=None): + return (a,) + + +@array_function_dispatch(_diagonal_dispatcher) +def diagonal(a, offset=0, axis1=0, axis2=1): + """ + Return specified diagonals. + + If `a` is 2-D, returns the diagonal of `a` with the given offset, + i.e., the collection of elements of the form ``a[i, i+offset]``. If + `a` has more than two dimensions, then the axes specified by `axis1` + and `axis2` are used to determine the 2-D sub-array whose diagonal is + returned. The shape of the resulting array can be determined by + removing `axis1` and `axis2` and appending an index to the right equal + to the size of the resulting diagonals. + + In versions of NumPy prior to 1.7, this function always returned a new, + independent array containing a copy of the values in the diagonal. + + In NumPy 1.7 and 1.8, it continues to return a copy of the diagonal, + but depending on this fact is deprecated. Writing to the resulting + array continues to work as it used to, but a FutureWarning is issued. + + Starting in NumPy 1.9 it returns a read-only view on the original array. + Attempting to write to the resulting array will produce an error. + + In some future release, it will return a read/write view and writing to + the returned array will alter your original array. The returned array + will have the same type as the input array. + + If you don't write to the array returned by this function, then you can + just ignore all of the above. + + If you depend on the current behavior, then we suggest copying the + returned array explicitly, i.e., use ``np.diagonal(a).copy()`` instead + of just ``np.diagonal(a)``. This will work with both past and future + versions of NumPy. + + Parameters + ---------- + a : array_like + Array from which the diagonals are taken. + offset : int, optional + Offset of the diagonal from the main diagonal. Can be positive or + negative. Defaults to main diagonal (0). + axis1 : int, optional + Axis to be used as the first axis of the 2-D sub-arrays from which + the diagonals should be taken. Defaults to first axis (0). + axis2 : int, optional + Axis to be used as the second axis of the 2-D sub-arrays from + which the diagonals should be taken. Defaults to second axis (1). + + Returns + ------- + array_of_diagonals : ndarray + If `a` is 2-D, then a 1-D array containing the diagonal and of the + same type as `a` is returned unless `a` is a `matrix`, in which case + a 1-D array rather than a (2-D) `matrix` is returned in order to + maintain backward compatibility. + + If ``a.ndim > 2``, then the dimensions specified by `axis1` and `axis2` + are removed, and a new axis inserted at the end corresponding to the + diagonal. + + Raises + ------ + ValueError + If the dimension of `a` is less than 2. + + See Also + -------- + diag : MATLAB work-a-like for 1-D and 2-D arrays. + diagflat : Create diagonal arrays. + trace : Sum along diagonals. + + Examples + -------- + >>> a = np.arange(4).reshape(2,2) + >>> a + array([[0, 1], + [2, 3]]) + >>> a.diagonal() + array([0, 3]) + >>> a.diagonal(1) + array([1]) + + A 3-D example: + + >>> a = np.arange(8).reshape(2,2,2); a + array([[[0, 1], + [2, 3]], + [[4, 5], + [6, 7]]]) + >>> a.diagonal(0, # Main diagonals of two arrays created by skipping + ... 0, # across the outer(left)-most axis last and + ... 1) # the "middle" (row) axis first. + array([[0, 6], + [1, 7]]) + + The sub-arrays whose main diagonals we just obtained; note that each + corresponds to fixing the right-most (column) axis, and that the + diagonals are "packed" in rows. + + >>> a[:,:,0] # main diagonal is [0 6] + array([[0, 2], + [4, 6]]) + >>> a[:,:,1] # main diagonal is [1 7] + array([[1, 3], + [5, 7]]) + + The anti-diagonal can be obtained by reversing the order of elements + using either `numpy.flipud` or `numpy.fliplr`. + + >>> a = np.arange(9).reshape(3, 3) + >>> a + array([[0, 1, 2], + [3, 4, 5], + [6, 7, 8]]) + >>> np.fliplr(a).diagonal() # Horizontal flip + array([2, 4, 6]) + >>> np.flipud(a).diagonal() # Vertical flip + array([6, 4, 2]) + + Note that the order in which the diagonal is retrieved varies depending + on the flip function. + """ + if isinstance(a, np.matrix): + # Make diagonal of matrix 1-D to preserve backward compatibility. + return asarray(a).diagonal(offset=offset, axis1=axis1, axis2=axis2) + else: + return asanyarray(a).diagonal(offset=offset, axis1=axis1, axis2=axis2) + + +def _trace_dispatcher( + a, offset=None, axis1=None, axis2=None, dtype=None, out=None): + return (a, out) + + +@array_function_dispatch(_trace_dispatcher) +def trace(a, offset=0, axis1=0, axis2=1, dtype=None, out=None): + """ + Return the sum along diagonals of the array. + + If `a` is 2-D, the sum along its diagonal with the given offset + is returned, i.e., the sum of elements ``a[i,i+offset]`` for all i. + + If `a` has more than two dimensions, then the axes specified by axis1 and + axis2 are used to determine the 2-D sub-arrays whose traces are returned. + The shape of the resulting array is the same as that of `a` with `axis1` + and `axis2` removed. + + Parameters + ---------- + a : array_like + Input array, from which the diagonals are taken. + offset : int, optional + Offset of the diagonal from the main diagonal. Can be both positive + and negative. Defaults to 0. + axis1, axis2 : int, optional + Axes to be used as the first and second axis of the 2-D sub-arrays + from which the diagonals should be taken. Defaults are the first two + axes of `a`. + dtype : dtype, optional + Determines the data-type of the returned array and of the accumulator + where the elements are summed. If dtype has the value None and `a` is + of integer type of precision less than the default integer + precision, then the default integer precision is used. Otherwise, + the precision is the same as that of `a`. + out : ndarray, optional + Array into which the output is placed. Its type is preserved and + it must be of the right shape to hold the output. + + Returns + ------- + sum_along_diagonals : ndarray + If `a` is 2-D, the sum along the diagonal is returned. If `a` has + larger dimensions, then an array of sums along diagonals is returned. + + See Also + -------- + diag, diagonal, diagflat + + Examples + -------- + >>> np.trace(np.eye(3)) + 3.0 + >>> a = np.arange(8).reshape((2,2,2)) + >>> np.trace(a) + array([6, 8]) + + >>> a = np.arange(24).reshape((2,2,2,3)) + >>> np.trace(a).shape + (2, 3) + + """ + if isinstance(a, np.matrix): + # Get trace of matrix via an array to preserve backward compatibility. + return asarray(a).trace(offset=offset, axis1=axis1, axis2=axis2, dtype=dtype, out=out) + else: + return asanyarray(a).trace(offset=offset, axis1=axis1, axis2=axis2, dtype=dtype, out=out) + + +def _ravel_dispatcher(a, order=None): + return (a,) + + +@array_function_dispatch(_ravel_dispatcher) +def ravel(a, order='C'): + """Return a contiguous flattened array. + + A 1-D array, containing the elements of the input, is returned. A copy is + made only if needed. + + As of NumPy 1.10, the returned array will have the same type as the input + array. (for example, a masked array will be returned for a masked array + input) + + Parameters + ---------- + a : array_like + Input array. The elements in `a` are read in the order specified by + `order`, and packed as a 1-D array. + order : {'C','F', 'A', 'K'}, optional + + The elements of `a` are read using this index order. 'C' means + to index the elements in row-major, C-style order, + with the last axis index changing fastest, back to the first + axis index changing slowest. 'F' means to index the elements + in column-major, Fortran-style order, with the + first index changing fastest, and the last index changing + slowest. Note that the 'C' and 'F' options take no account of + the memory layout of the underlying array, and only refer to + the order of axis indexing. 'A' means to read the elements in + Fortran-like index order if `a` is Fortran *contiguous* in + memory, C-like order otherwise. 'K' means to read the + elements in the order they occur in memory, except for + reversing the data when strides are negative. By default, 'C' + index order is used. + + Returns + ------- + y : array_like + y is an array of the same subtype as `a`, with shape ``(a.size,)``. + Note that matrices are special cased for backward compatibility, if `a` + is a matrix, then y is a 1-D ndarray. + + See Also + -------- + ndarray.flat : 1-D iterator over an array. + ndarray.flatten : 1-D array copy of the elements of an array + in row-major order. + ndarray.reshape : Change the shape of an array without changing its data. + + Notes + ----- + In row-major, C-style order, in two dimensions, the row index + varies the slowest, and the column index the quickest. This can + be generalized to multiple dimensions, where row-major order + implies that the index along the first axis varies slowest, and + the index along the last quickest. The opposite holds for + column-major, Fortran-style index ordering. + + When a view is desired in as many cases as possible, ``arr.reshape(-1)`` + may be preferable. + + Examples + -------- + It is equivalent to ``reshape(-1, order=order)``. + + >>> x = np.array([[1, 2, 3], [4, 5, 6]]) + >>> np.ravel(x) + array([1, 2, 3, 4, 5, 6]) + + >>> x.reshape(-1) + array([1, 2, 3, 4, 5, 6]) + + >>> np.ravel(x, order='F') + array([1, 4, 2, 5, 3, 6]) + + When ``order`` is 'A', it will preserve the array's 'C' or 'F' ordering: + + >>> np.ravel(x.T) + array([1, 4, 2, 5, 3, 6]) + >>> np.ravel(x.T, order='A') + array([1, 2, 3, 4, 5, 6]) + + When ``order`` is 'K', it will preserve orderings that are neither 'C' + nor 'F', but won't reverse axes: + + >>> a = np.arange(3)[::-1]; a + array([2, 1, 0]) + >>> a.ravel(order='C') + array([2, 1, 0]) + >>> a.ravel(order='K') + array([2, 1, 0]) + + >>> a = np.arange(12).reshape(2,3,2).swapaxes(1,2); a + array([[[ 0, 2, 4], + [ 1, 3, 5]], + [[ 6, 8, 10], + [ 7, 9, 11]]]) + >>> a.ravel(order='C') + array([ 0, 2, 4, 1, 3, 5, 6, 8, 10, 7, 9, 11]) + >>> a.ravel(order='K') + array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]) + + """ + if isinstance(a, np.matrix): + return asarray(a).ravel(order=order) + else: + return asanyarray(a).ravel(order=order) + + +def _nonzero_dispatcher(a): + return (a,) + + +@array_function_dispatch(_nonzero_dispatcher) +def nonzero(a): + """ + Return the indices of the elements that are non-zero. + + Returns a tuple of arrays, one for each dimension of `a`, + containing the indices of the non-zero elements in that + dimension. The values in `a` are always tested and returned in + row-major, C-style order. + + To group the indices by element, rather than dimension, use `argwhere`, + which returns a row for each non-zero element. + + .. note:: + + When called on a zero-d array or scalar, ``nonzero(a)`` is treated + as ``nonzero(atleast_1d(a))``. + + .. deprecated:: 1.17.0 + + Use `atleast_1d` explicitly if this behavior is deliberate. + + Parameters + ---------- + a : array_like + Input array. + + Returns + ------- + tuple_of_arrays : tuple + Indices of elements that are non-zero. + + See Also + -------- + flatnonzero : + Return indices that are non-zero in the flattened version of the input + array. + ndarray.nonzero : + Equivalent ndarray method. + count_nonzero : + Counts the number of non-zero elements in the input array. + + Notes + ----- + While the nonzero values can be obtained with ``a[nonzero(a)]``, it is + recommended to use ``x[x.astype(bool)]`` or ``x[x != 0]`` instead, which + will correctly handle 0-d arrays. + + Examples + -------- + >>> x = np.array([[3, 0, 0], [0, 4, 0], [5, 6, 0]]) + >>> x + array([[3, 0, 0], + [0, 4, 0], + [5, 6, 0]]) + >>> np.nonzero(x) + (array([0, 1, 2, 2]), array([0, 1, 0, 1])) + + >>> x[np.nonzero(x)] + array([3, 4, 5, 6]) + >>> np.transpose(np.nonzero(x)) + array([[0, 0], + [1, 1], + [2, 0], + [2, 1]]) + + A common use for ``nonzero`` is to find the indices of an array, where + a condition is True. Given an array `a`, the condition `a` > 3 is a + boolean array and since False is interpreted as 0, np.nonzero(a > 3) + yields the indices of the `a` where the condition is true. + + >>> a = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) + >>> a > 3 + array([[False, False, False], + [ True, True, True], + [ True, True, True]]) + >>> np.nonzero(a > 3) + (array([1, 1, 1, 2, 2, 2]), array([0, 1, 2, 0, 1, 2])) + + Using this result to index `a` is equivalent to using the mask directly: + + >>> a[np.nonzero(a > 3)] + array([4, 5, 6, 7, 8, 9]) + >>> a[a > 3] # prefer this spelling + array([4, 5, 6, 7, 8, 9]) + + ``nonzero`` can also be called as a method of the array. + + >>> (a > 3).nonzero() + (array([1, 1, 1, 2, 2, 2]), array([0, 1, 2, 0, 1, 2])) + + """ + return _wrapfunc(a, 'nonzero') + + +def _shape_dispatcher(a): + return (a,) + + +@array_function_dispatch(_shape_dispatcher) +def shape(a): + """ + Return the shape of an array. + + Parameters + ---------- + a : array_like + Input array. + + Returns + ------- + shape : tuple of ints + The elements of the shape tuple give the lengths of the + corresponding array dimensions. + + See Also + -------- + len + ndarray.shape : Equivalent array method. + + Examples + -------- + >>> np.shape(np.eye(3)) + (3, 3) + >>> np.shape([[1, 2]]) + (1, 2) + >>> np.shape([0]) + (1,) + >>> np.shape(0) + () + + >>> a = np.array([(1, 2), (3, 4)], dtype=[('x', 'i4'), ('y', 'i4')]) + >>> np.shape(a) + (2,) + >>> a.shape + (2,) + + """ + try: + result = a.shape + except AttributeError: + result = asarray(a).shape + return result + + +def _compress_dispatcher(condition, a, axis=None, out=None): + return (condition, a, out) + + +@array_function_dispatch(_compress_dispatcher) +def compress(condition, a, axis=None, out=None): + """ + Return selected slices of an array along given axis. + + When working along a given axis, a slice along that axis is returned in + `output` for each index where `condition` evaluates to True. When + working on a 1-D array, `compress` is equivalent to `extract`. + + Parameters + ---------- + condition : 1-D array of bools + Array that selects which entries to return. If len(condition) + is less than the size of `a` along the given axis, then output is + truncated to the length of the condition array. + a : array_like + Array from which to extract a part. + axis : int, optional + Axis along which to take slices. If None (default), work on the + flattened array. + out : ndarray, optional + Output array. Its type is preserved and it must be of the right + shape to hold the output. + + Returns + ------- + compressed_array : ndarray + A copy of `a` without the slices along axis for which `condition` + is false. + + See Also + -------- + take, choose, diag, diagonal, select + ndarray.compress : Equivalent method in ndarray + extract: Equivalent method when working on 1-D arrays + :ref:`ufuncs-output-type` + + Examples + -------- + >>> a = np.array([[1, 2], [3, 4], [5, 6]]) + >>> a + array([[1, 2], + [3, 4], + [5, 6]]) + >>> np.compress([0, 1], a, axis=0) + array([[3, 4]]) + >>> np.compress([False, True, True], a, axis=0) + array([[3, 4], + [5, 6]]) + >>> np.compress([False, True], a, axis=1) + array([[2], + [4], + [6]]) + + Working on the flattened array does not return slices along an axis but + selects elements. + + >>> np.compress([False, True], a) + array([2]) + + """ + return _wrapfunc(a, 'compress', condition, axis=axis, out=out) + + +def _clip_dispatcher(a, a_min, a_max, out=None, **kwargs): + return (a, a_min, a_max) + + +@array_function_dispatch(_clip_dispatcher) +def clip(a, a_min, a_max, out=None, **kwargs): + """ + Clip (limit) the values in an array. + + Given an interval, values outside the interval are clipped to + the interval edges. For example, if an interval of ``[0, 1]`` + is specified, values smaller than 0 become 0, and values larger + than 1 become 1. + + Equivalent to but faster than ``np.minimum(a_max, np.maximum(a, a_min))``. + + No check is performed to ensure ``a_min < a_max``. + + Parameters + ---------- + a : array_like + Array containing elements to clip. + a_min, a_max : array_like or None + Minimum and maximum value. If ``None``, clipping is not performed on + the corresponding edge. Only one of `a_min` and `a_max` may be + ``None``. Both are broadcast against `a`. + out : ndarray, optional + The results will be placed in this array. It may be the input + array for in-place clipping. `out` must be of the right shape + to hold the output. Its type is preserved. + **kwargs + For other keyword-only arguments, see the + :ref:`ufunc docs `. + + .. versionadded:: 1.17.0 + + Returns + ------- + clipped_array : ndarray + An array with the elements of `a`, but where values + < `a_min` are replaced with `a_min`, and those > `a_max` + with `a_max`. + + See Also + -------- + :ref:`ufuncs-output-type` + + Examples + -------- + >>> a = np.arange(10) + >>> np.clip(a, 1, 8) + array([1, 1, 2, 3, 4, 5, 6, 7, 8, 8]) + >>> a + array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) + >>> np.clip(a, 3, 6, out=a) + array([3, 3, 3, 3, 4, 5, 6, 6, 6, 6]) + >>> a = np.arange(10) + >>> a + array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) + >>> np.clip(a, [3, 4, 1, 1, 1, 4, 4, 4, 4, 4], 8) + array([3, 4, 2, 3, 4, 5, 6, 7, 8, 8]) + + """ + return _wrapfunc(a, 'clip', a_min, a_max, out=out, **kwargs) + + +def _sum_dispatcher(a, axis=None, dtype=None, out=None, keepdims=None, + initial=None, where=None): + return (a, out) + + +@array_function_dispatch(_sum_dispatcher) +def sum(a, axis=None, dtype=None, out=None, keepdims=np._NoValue, + initial=np._NoValue, where=np._NoValue): + """ + Sum of array elements over a given axis. + + Parameters + ---------- + a : array_like + Elements to sum. + axis : None or int or tuple of ints, optional + Axis or axes along which a sum is performed. The default, + axis=None, will sum all of the elements of the input array. If + axis is negative it counts from the last to the first axis. + + .. versionadded:: 1.7.0 + + If axis is a tuple of ints, a sum is performed on all of the axes + specified in the tuple instead of a single axis or all the axes as + before. + dtype : dtype, optional + The type of the returned array and of the accumulator in which the + elements are summed. The dtype of `a` is used by default unless `a` + has an integer dtype of less precision than the default platform + integer. In that case, if `a` is signed then the platform integer + is used while if `a` is unsigned then an unsigned integer of the + same precision as the platform integer is used. + out : ndarray, optional + Alternative output array in which to place the result. It must have + the same shape as the expected output, but the type of the output + values will be cast if necessary. + keepdims : bool, optional + If this is set to True, the axes which are reduced are left + in the result as dimensions with size one. With this option, + the result will broadcast correctly against the input array. + + If the default value is passed, then `keepdims` will not be + passed through to the `sum` method of sub-classes of + `ndarray`, however any non-default value will be. If the + sub-class' method does not implement `keepdims` any + exceptions will be raised. + initial : scalar, optional + Starting value for the sum. See `~numpy.ufunc.reduce` for details. + + .. versionadded:: 1.15.0 + + where : array_like of bool, optional + Elements to include in the sum. See `~numpy.ufunc.reduce` for details. + + .. versionadded:: 1.17.0 + + Returns + ------- + sum_along_axis : ndarray + An array with the same shape as `a`, with the specified + axis removed. If `a` is a 0-d array, or if `axis` is None, a scalar + is returned. If an output array is specified, a reference to + `out` is returned. + + See Also + -------- + ndarray.sum : Equivalent method. + + add.reduce : Equivalent functionality of `add`. + + cumsum : Cumulative sum of array elements. + + trapz : Integration of array values using the composite trapezoidal rule. + + mean, average + + Notes + ----- + Arithmetic is modular when using integer types, and no error is + raised on overflow. + + The sum of an empty array is the neutral element 0: + + >>> np.sum([]) + 0.0 + + For floating point numbers the numerical precision of sum (and + ``np.add.reduce``) is in general limited by directly adding each number + individually to the result causing rounding errors in every step. + However, often numpy will use a numerically better approach (partial + pairwise summation) leading to improved precision in many use-cases. + This improved precision is always provided when no ``axis`` is given. + When ``axis`` is given, it will depend on which axis is summed. + Technically, to provide the best speed possible, the improved precision + is only used when the summation is along the fast axis in memory. + Note that the exact precision may vary depending on other parameters. + In contrast to NumPy, Python's ``math.fsum`` function uses a slower but + more precise approach to summation. + Especially when summing a large number of lower precision floating point + numbers, such as ``float32``, numerical errors can become significant. + In such cases it can be advisable to use `dtype="float64"` to use a higher + precision for the output. + + Examples + -------- + >>> np.sum([0.5, 1.5]) + 2.0 + >>> np.sum([0.5, 0.7, 0.2, 1.5], dtype=np.int32) + 1 + >>> np.sum([[0, 1], [0, 5]]) + 6 + >>> np.sum([[0, 1], [0, 5]], axis=0) + array([0, 6]) + >>> np.sum([[0, 1], [0, 5]], axis=1) + array([1, 5]) + >>> np.sum([[0, 1], [np.nan, 5]], where=[False, True], axis=1) + array([1., 5.]) + + If the accumulator is too small, overflow occurs: + + >>> np.ones(128, dtype=np.int8).sum(dtype=np.int8) + -128 + + You can also start the sum with a value other than zero: + + >>> np.sum([10], initial=5) + 15 + """ + if isinstance(a, _gentype): + # 2018-02-25, 1.15.0 + warnings.warn( + "Calling np.sum(generator) is deprecated, and in the future will give a different result. " + "Use np.sum(np.fromiter(generator)) or the python sum builtin instead.", + DeprecationWarning, stacklevel=3) + + res = _sum_(a) + if out is not None: + out[...] = res + return out + return res + + return _wrapreduction(a, np.add, 'sum', axis, dtype, out, keepdims=keepdims, + initial=initial, where=where) + + +def _any_dispatcher(a, axis=None, out=None, keepdims=None, *, + where=np._NoValue): + return (a, where, out) + + +@array_function_dispatch(_any_dispatcher) +def any(a, axis=None, out=None, keepdims=np._NoValue, *, where=np._NoValue): + """ + Test whether any array element along a given axis evaluates to True. + + Returns single boolean unless `axis` is not ``None`` + + Parameters + ---------- + a : array_like + Input array or object that can be converted to an array. + axis : None or int or tuple of ints, optional + Axis or axes along which a logical OR reduction is performed. + The default (``axis=None``) is to perform a logical OR over all + the dimensions of the input array. `axis` may be negative, in + which case it counts from the last to the first axis. + + .. versionadded:: 1.7.0 + + If this is a tuple of ints, a reduction is performed on multiple + axes, instead of a single axis or all the axes as before. + out : ndarray, optional + Alternate output array in which to place the result. It must have + the same shape as the expected output and its type is preserved + (e.g., if it is of type float, then it will remain so, returning + 1.0 for True and 0.0 for False, regardless of the type of `a`). + See :ref:`ufuncs-output-type` for more details. + + keepdims : bool, optional + If this is set to True, the axes which are reduced are left + in the result as dimensions with size one. With this option, + the result will broadcast correctly against the input array. + + If the default value is passed, then `keepdims` will not be + passed through to the `any` method of sub-classes of + `ndarray`, however any non-default value will be. If the + sub-class' method does not implement `keepdims` any + exceptions will be raised. + + where : array_like of bool, optional + Elements to include in checking for any `True` values. + See `~numpy.ufunc.reduce` for details. + + .. versionadded:: 1.20.0 + + Returns + ------- + any : bool or ndarray + A new boolean or `ndarray` is returned unless `out` is specified, + in which case a reference to `out` is returned. + + See Also + -------- + ndarray.any : equivalent method + + all : Test whether all elements along a given axis evaluate to True. + + Notes + ----- + Not a Number (NaN), positive infinity and negative infinity evaluate + to `True` because these are not equal to zero. + + Examples + -------- + >>> np.any([[True, False], [True, True]]) + True + + >>> np.any([[True, False], [False, False]], axis=0) + array([ True, False]) + + >>> np.any([-1, 0, 5]) + True + + >>> np.any(np.nan) + True + + >>> np.any([[True, False], [False, False]], where=[[False], [True]]) + False + + >>> o=np.array(False) + >>> z=np.any([-1, 4, 5], out=o) + >>> z, o + (array(True), array(True)) + >>> # Check now that z is a reference to o + >>> z is o + True + >>> id(z), id(o) # identity of z and o # doctest: +SKIP + (191614240, 191614240) + + """ + return _wrapreduction(a, np.logical_or, 'any', axis, None, out, + keepdims=keepdims, where=where) + + +def _all_dispatcher(a, axis=None, out=None, keepdims=None, *, + where=None): + return (a, where, out) + + +@array_function_dispatch(_all_dispatcher) +def all(a, axis=None, out=None, keepdims=np._NoValue, *, where=np._NoValue): + """ + Test whether all array elements along a given axis evaluate to True. + + Parameters + ---------- + a : array_like + Input array or object that can be converted to an array. + axis : None or int or tuple of ints, optional + Axis or axes along which a logical AND reduction is performed. + The default (``axis=None``) is to perform a logical AND over all + the dimensions of the input array. `axis` may be negative, in + which case it counts from the last to the first axis. + + .. versionadded:: 1.7.0 + + If this is a tuple of ints, a reduction is performed on multiple + axes, instead of a single axis or all the axes as before. + out : ndarray, optional + Alternate output array in which to place the result. + It must have the same shape as the expected output and its + type is preserved (e.g., if ``dtype(out)`` is float, the result + will consist of 0.0's and 1.0's). See :ref:`ufuncs-output-type` for more + details. + + keepdims : bool, optional + If this is set to True, the axes which are reduced are left + in the result as dimensions with size one. With this option, + the result will broadcast correctly against the input array. + + If the default value is passed, then `keepdims` will not be + passed through to the `all` method of sub-classes of + `ndarray`, however any non-default value will be. If the + sub-class' method does not implement `keepdims` any + exceptions will be raised. + + where : array_like of bool, optional + Elements to include in checking for all `True` values. + See `~numpy.ufunc.reduce` for details. + + .. versionadded:: 1.20.0 + + Returns + ------- + all : ndarray, bool + A new boolean or array is returned unless `out` is specified, + in which case a reference to `out` is returned. + + See Also + -------- + ndarray.all : equivalent method + + any : Test whether any element along a given axis evaluates to True. + + Notes + ----- + Not a Number (NaN), positive infinity and negative infinity + evaluate to `True` because these are not equal to zero. + + Examples + -------- + >>> np.all([[True,False],[True,True]]) + False + + >>> np.all([[True,False],[True,True]], axis=0) + array([ True, False]) + + >>> np.all([-1, 4, 5]) + True + + >>> np.all([1.0, np.nan]) + True + + >>> np.all([[True, True], [False, True]], where=[[True], [False]]) + True + + >>> o=np.array(False) + >>> z=np.all([-1, 4, 5], out=o) + >>> id(z), id(o), z + (28293632, 28293632, array(True)) # may vary + + """ + return _wrapreduction(a, np.logical_and, 'all', axis, None, out, + keepdims=keepdims, where=where) + + +def _cumsum_dispatcher(a, axis=None, dtype=None, out=None): + return (a, out) + + +@array_function_dispatch(_cumsum_dispatcher) +def cumsum(a, axis=None, dtype=None, out=None): + """ + Return the cumulative sum of the elements along a given axis. + + Parameters + ---------- + a : array_like + Input array. + axis : int, optional + Axis along which the cumulative sum is computed. The default + (None) is to compute the cumsum over the flattened array. + dtype : dtype, optional + Type of the returned array and of the accumulator in which the + elements are summed. If `dtype` is not specified, it defaults + to the dtype of `a`, unless `a` has an integer dtype with a + precision less than that of the default platform integer. In + that case, the default platform integer is used. + out : ndarray, optional + Alternative output array in which to place the result. It must + have the same shape and buffer length as the expected output + but the type will be cast if necessary. See :ref:`ufuncs-output-type` for + more details. + + Returns + ------- + cumsum_along_axis : ndarray. + A new array holding the result is returned unless `out` is + specified, in which case a reference to `out` is returned. The + result has the same size as `a`, and the same shape as `a` if + `axis` is not None or `a` is a 1-d array. + + + See Also + -------- + sum : Sum array elements. + + trapz : Integration of array values using the composite trapezoidal rule. + + diff : Calculate the n-th discrete difference along given axis. + + Notes + ----- + Arithmetic is modular when using integer types, and no error is + raised on overflow. + + Examples + -------- + >>> a = np.array([[1,2,3], [4,5,6]]) + >>> a + array([[1, 2, 3], + [4, 5, 6]]) + >>> np.cumsum(a) + array([ 1, 3, 6, 10, 15, 21]) + >>> np.cumsum(a, dtype=float) # specifies type of output value(s) + array([ 1., 3., 6., 10., 15., 21.]) + + >>> np.cumsum(a,axis=0) # sum over rows for each of the 3 columns + array([[1, 2, 3], + [5, 7, 9]]) + >>> np.cumsum(a,axis=1) # sum over columns for each of the 2 rows + array([[ 1, 3, 6], + [ 4, 9, 15]]) + + """ + return _wrapfunc(a, 'cumsum', axis=axis, dtype=dtype, out=out) + + +def _ptp_dispatcher(a, axis=None, out=None, keepdims=None): + return (a, out) + + +@array_function_dispatch(_ptp_dispatcher) +def ptp(a, axis=None, out=None, keepdims=np._NoValue): + """ + Range of values (maximum - minimum) along an axis. + + The name of the function comes from the acronym for 'peak to peak'. + + .. warning:: + `ptp` preserves the data type of the array. This means the + return value for an input of signed integers with n bits + (e.g. `np.int8`, `np.int16`, etc) is also a signed integer + with n bits. In that case, peak-to-peak values greater than + ``2**(n-1)-1`` will be returned as negative values. An example + with a work-around is shown below. + + Parameters + ---------- + a : array_like + Input values. + axis : None or int or tuple of ints, optional + Axis along which to find the peaks. By default, flatten the + array. `axis` may be negative, in + which case it counts from the last to the first axis. + + .. versionadded:: 1.15.0 + + If this is a tuple of ints, a reduction is performed on multiple + axes, instead of a single axis or all the axes as before. + out : array_like + Alternative output array in which to place the result. It must + have the same shape and buffer length as the expected output, + but the type of the output values will be cast if necessary. + + keepdims : bool, optional + If this is set to True, the axes which are reduced are left + in the result as dimensions with size one. With this option, + the result will broadcast correctly against the input array. + + If the default value is passed, then `keepdims` will not be + passed through to the `ptp` method of sub-classes of + `ndarray`, however any non-default value will be. If the + sub-class' method does not implement `keepdims` any + exceptions will be raised. + + Returns + ------- + ptp : ndarray + A new array holding the result, unless `out` was + specified, in which case a reference to `out` is returned. + + Examples + -------- + >>> x = np.array([[4, 9, 2, 10], + ... [6, 9, 7, 12]]) + + >>> np.ptp(x, axis=1) + array([8, 6]) + + >>> np.ptp(x, axis=0) + array([2, 0, 5, 2]) + + >>> np.ptp(x) + 10 + + This example shows that a negative value can be returned when + the input is an array of signed integers. + + >>> y = np.array([[1, 127], + ... [0, 127], + ... [-1, 127], + ... [-2, 127]], dtype=np.int8) + >>> np.ptp(y, axis=1) + array([ 126, 127, -128, -127], dtype=int8) + + A work-around is to use the `view()` method to view the result as + unsigned integers with the same bit width: + + >>> np.ptp(y, axis=1).view(np.uint8) + array([126, 127, 128, 129], dtype=uint8) + + """ + kwargs = {} + if keepdims is not np._NoValue: + kwargs['keepdims'] = keepdims + if type(a) is not mu.ndarray: + try: + ptp = a.ptp + except AttributeError: + pass + else: + return ptp(axis=axis, out=out, **kwargs) + return _methods._ptp(a, axis=axis, out=out, **kwargs) + + +def _amax_dispatcher(a, axis=None, out=None, keepdims=None, initial=None, + where=None): + return (a, out) + + +@array_function_dispatch(_amax_dispatcher) +def amax(a, axis=None, out=None, keepdims=np._NoValue, initial=np._NoValue, + where=np._NoValue): + """ + Return the maximum of an array or maximum along an axis. + + Parameters + ---------- + a : array_like + Input data. + axis : None or int or tuple of ints, optional + Axis or axes along which to operate. By default, flattened input is + used. + + .. versionadded:: 1.7.0 + + If this is a tuple of ints, the maximum is selected over multiple axes, + instead of a single axis or all the axes as before. + out : ndarray, optional + Alternative output array in which to place the result. Must + be of the same shape and buffer length as the expected output. + See :ref:`ufuncs-output-type` for more details. + + keepdims : bool, optional + If this is set to True, the axes which are reduced are left + in the result as dimensions with size one. With this option, + the result will broadcast correctly against the input array. + + If the default value is passed, then `keepdims` will not be + passed through to the `amax` method of sub-classes of + `ndarray`, however any non-default value will be. If the + sub-class' method does not implement `keepdims` any + exceptions will be raised. + + initial : scalar, optional + The minimum value of an output element. Must be present to allow + computation on empty slice. See `~numpy.ufunc.reduce` for details. + + .. versionadded:: 1.15.0 + + where : array_like of bool, optional + Elements to compare for the maximum. See `~numpy.ufunc.reduce` + for details. + + .. versionadded:: 1.17.0 + + Returns + ------- + amax : ndarray or scalar + Maximum of `a`. If `axis` is None, the result is a scalar value. + If `axis` is given, the result is an array of dimension + ``a.ndim - 1``. + + See Also + -------- + amin : + The minimum value of an array along a given axis, propagating any NaNs. + nanmax : + The maximum value of an array along a given axis, ignoring any NaNs. + maximum : + Element-wise maximum of two arrays, propagating any NaNs. + fmax : + Element-wise maximum of two arrays, ignoring any NaNs. + argmax : + Return the indices of the maximum values. + + nanmin, minimum, fmin + + Notes + ----- + NaN values are propagated, that is if at least one item is NaN, the + corresponding max value will be NaN as well. To ignore NaN values + (MATLAB behavior), please use nanmax. + + Don't use `amax` for element-wise comparison of 2 arrays; when + ``a.shape[0]`` is 2, ``maximum(a[0], a[1])`` is faster than + ``amax(a, axis=0)``. + + Examples + -------- + >>> a = np.arange(4).reshape((2,2)) + >>> a + array([[0, 1], + [2, 3]]) + >>> np.amax(a) # Maximum of the flattened array + 3 + >>> np.amax(a, axis=0) # Maxima along the first axis + array([2, 3]) + >>> np.amax(a, axis=1) # Maxima along the second axis + array([1, 3]) + >>> np.amax(a, where=[False, True], initial=-1, axis=0) + array([-1, 3]) + >>> b = np.arange(5, dtype=float) + >>> b[2] = np.NaN + >>> np.amax(b) + nan + >>> np.amax(b, where=~np.isnan(b), initial=-1) + 4.0 + >>> np.nanmax(b) + 4.0 + + You can use an initial value to compute the maximum of an empty slice, or + to initialize it to a different value: + + >>> np.max([[-50], [10]], axis=-1, initial=0) + array([ 0, 10]) + + Notice that the initial value is used as one of the elements for which the + maximum is determined, unlike for the default argument Python's max + function, which is only used for empty iterables. + + >>> np.max([5], initial=6) + 6 + >>> max([5], default=6) + 5 + """ + return _wrapreduction(a, np.maximum, 'max', axis, None, out, + keepdims=keepdims, initial=initial, where=where) + + +def _amin_dispatcher(a, axis=None, out=None, keepdims=None, initial=None, + where=None): + return (a, out) + + +@array_function_dispatch(_amin_dispatcher) +def amin(a, axis=None, out=None, keepdims=np._NoValue, initial=np._NoValue, + where=np._NoValue): + """ + Return the minimum of an array or minimum along an axis. + + Parameters + ---------- + a : array_like + Input data. + axis : None or int or tuple of ints, optional + Axis or axes along which to operate. By default, flattened input is + used. + + .. versionadded:: 1.7.0 + + If this is a tuple of ints, the minimum is selected over multiple axes, + instead of a single axis or all the axes as before. + out : ndarray, optional + Alternative output array in which to place the result. Must + be of the same shape and buffer length as the expected output. + See :ref:`ufuncs-output-type` for more details. + + keepdims : bool, optional + If this is set to True, the axes which are reduced are left + in the result as dimensions with size one. With this option, + the result will broadcast correctly against the input array. + + If the default value is passed, then `keepdims` will not be + passed through to the `amin` method of sub-classes of + `ndarray`, however any non-default value will be. If the + sub-class' method does not implement `keepdims` any + exceptions will be raised. + + initial : scalar, optional + The maximum value of an output element. Must be present to allow + computation on empty slice. See `~numpy.ufunc.reduce` for details. + + .. versionadded:: 1.15.0 + + where : array_like of bool, optional + Elements to compare for the minimum. See `~numpy.ufunc.reduce` + for details. + + .. versionadded:: 1.17.0 + + Returns + ------- + amin : ndarray or scalar + Minimum of `a`. If `axis` is None, the result is a scalar value. + If `axis` is given, the result is an array of dimension + ``a.ndim - 1``. + + See Also + -------- + amax : + The maximum value of an array along a given axis, propagating any NaNs. + nanmin : + The minimum value of an array along a given axis, ignoring any NaNs. + minimum : + Element-wise minimum of two arrays, propagating any NaNs. + fmin : + Element-wise minimum of two arrays, ignoring any NaNs. + argmin : + Return the indices of the minimum values. + + nanmax, maximum, fmax + + Notes + ----- + NaN values are propagated, that is if at least one item is NaN, the + corresponding min value will be NaN as well. To ignore NaN values + (MATLAB behavior), please use nanmin. + + Don't use `amin` for element-wise comparison of 2 arrays; when + ``a.shape[0]`` is 2, ``minimum(a[0], a[1])`` is faster than + ``amin(a, axis=0)``. + + Examples + -------- + >>> a = np.arange(4).reshape((2,2)) + >>> a + array([[0, 1], + [2, 3]]) + >>> np.amin(a) # Minimum of the flattened array + 0 + >>> np.amin(a, axis=0) # Minima along the first axis + array([0, 1]) + >>> np.amin(a, axis=1) # Minima along the second axis + array([0, 2]) + >>> np.amin(a, where=[False, True], initial=10, axis=0) + array([10, 1]) + + >>> b = np.arange(5, dtype=float) + >>> b[2] = np.NaN + >>> np.amin(b) + nan + >>> np.amin(b, where=~np.isnan(b), initial=10) + 0.0 + >>> np.nanmin(b) + 0.0 + + >>> np.min([[-50], [10]], axis=-1, initial=0) + array([-50, 0]) + + Notice that the initial value is used as one of the elements for which the + minimum is determined, unlike for the default argument Python's max + function, which is only used for empty iterables. + + Notice that this isn't the same as Python's ``default`` argument. + + >>> np.min([6], initial=5) + 5 + >>> min([6], default=5) + 6 + """ + return _wrapreduction(a, np.minimum, 'min', axis, None, out, + keepdims=keepdims, initial=initial, where=where) + + +def _alen_dispathcer(a): + return (a,) + + +@array_function_dispatch(_alen_dispathcer) +def alen(a): + """ + Return the length of the first dimension of the input array. + + .. deprecated:: 1.18 + `numpy.alen` is deprecated, use `len` instead. + + Parameters + ---------- + a : array_like + Input array. + + Returns + ------- + alen : int + Length of the first dimension of `a`. + + See Also + -------- + shape, size + + Examples + -------- + >>> a = np.zeros((7,4,5)) + >>> a.shape[0] + 7 + >>> np.alen(a) + 7 + + """ + # NumPy 1.18.0, 2019-08-02 + warnings.warn( + "`np.alen` is deprecated, use `len` instead", + DeprecationWarning, stacklevel=2) + try: + return len(a) + except TypeError: + return len(array(a, ndmin=1)) + + +def _prod_dispatcher(a, axis=None, dtype=None, out=None, keepdims=None, + initial=None, where=None): + return (a, out) + + +@array_function_dispatch(_prod_dispatcher) +def prod(a, axis=None, dtype=None, out=None, keepdims=np._NoValue, + initial=np._NoValue, where=np._NoValue): + """ + Return the product of array elements over a given axis. + + Parameters + ---------- + a : array_like + Input data. + axis : None or int or tuple of ints, optional + Axis or axes along which a product is performed. The default, + axis=None, will calculate the product of all the elements in the + input array. If axis is negative it counts from the last to the + first axis. + + .. versionadded:: 1.7.0 + + If axis is a tuple of ints, a product is performed on all of the + axes specified in the tuple instead of a single axis or all the + axes as before. + dtype : dtype, optional + The type of the returned array, as well as of the accumulator in + which the elements are multiplied. The dtype of `a` is used by + default unless `a` has an integer dtype of less precision than the + default platform integer. In that case, if `a` is signed then the + platform integer is used while if `a` is unsigned then an unsigned + integer of the same precision as the platform integer is used. + out : ndarray, optional + Alternative output array in which to place the result. It must have + the same shape as the expected output, but the type of the output + values will be cast if necessary. + keepdims : bool, optional + If this is set to True, the axes which are reduced are left in the + result as dimensions with size one. With this option, the result + will broadcast correctly against the input array. + + If the default value is passed, then `keepdims` will not be + passed through to the `prod` method of sub-classes of + `ndarray`, however any non-default value will be. If the + sub-class' method does not implement `keepdims` any + exceptions will be raised. + initial : scalar, optional + The starting value for this product. See `~numpy.ufunc.reduce` for details. + + .. versionadded:: 1.15.0 + + where : array_like of bool, optional + Elements to include in the product. See `~numpy.ufunc.reduce` for details. + + .. versionadded:: 1.17.0 + + Returns + ------- + product_along_axis : ndarray, see `dtype` parameter above. + An array shaped as `a` but with the specified axis removed. + Returns a reference to `out` if specified. + + See Also + -------- + ndarray.prod : equivalent method + :ref:`ufuncs-output-type` + + Notes + ----- + Arithmetic is modular when using integer types, and no error is + raised on overflow. That means that, on a 32-bit platform: + + >>> x = np.array([536870910, 536870910, 536870910, 536870910]) + >>> np.prod(x) + 16 # may vary + + The product of an empty array is the neutral element 1: + + >>> np.prod([]) + 1.0 + + Examples + -------- + By default, calculate the product of all elements: + + >>> np.prod([1.,2.]) + 2.0 + + Even when the input array is two-dimensional: + + >>> np.prod([[1.,2.],[3.,4.]]) + 24.0 + + But we can also specify the axis over which to multiply: + + >>> np.prod([[1.,2.],[3.,4.]], axis=1) + array([ 2., 12.]) + + Or select specific elements to include: + + >>> np.prod([1., np.nan, 3.], where=[True, False, True]) + 3.0 + + If the type of `x` is unsigned, then the output type is + the unsigned platform integer: + + >>> x = np.array([1, 2, 3], dtype=np.uint8) + >>> np.prod(x).dtype == np.uint + True + + If `x` is of a signed integer type, then the output type + is the default platform integer: + + >>> x = np.array([1, 2, 3], dtype=np.int8) + >>> np.prod(x).dtype == int + True + + You can also start the product with a value other than one: + + >>> np.prod([1, 2], initial=5) + 10 + """ + return _wrapreduction(a, np.multiply, 'prod', axis, dtype, out, + keepdims=keepdims, initial=initial, where=where) + + +def _cumprod_dispatcher(a, axis=None, dtype=None, out=None): + return (a, out) + + +@array_function_dispatch(_cumprod_dispatcher) +def cumprod(a, axis=None, dtype=None, out=None): + """ + Return the cumulative product of elements along a given axis. + + Parameters + ---------- + a : array_like + Input array. + axis : int, optional + Axis along which the cumulative product is computed. By default + the input is flattened. + dtype : dtype, optional + Type of the returned array, as well as of the accumulator in which + the elements are multiplied. If *dtype* is not specified, it + defaults to the dtype of `a`, unless `a` has an integer dtype with + a precision less than that of the default platform integer. In + that case, the default platform integer is used instead. + out : ndarray, optional + Alternative output array in which to place the result. It must + have the same shape and buffer length as the expected output + but the type of the resulting values will be cast if necessary. + + Returns + ------- + cumprod : ndarray + A new array holding the result is returned unless `out` is + specified, in which case a reference to out is returned. + + See Also + -------- + :ref:`ufuncs-output-type` + + Notes + ----- + Arithmetic is modular when using integer types, and no error is + raised on overflow. + + Examples + -------- + >>> a = np.array([1,2,3]) + >>> np.cumprod(a) # intermediate results 1, 1*2 + ... # total product 1*2*3 = 6 + array([1, 2, 6]) + >>> a = np.array([[1, 2, 3], [4, 5, 6]]) + >>> np.cumprod(a, dtype=float) # specify type of output + array([ 1., 2., 6., 24., 120., 720.]) + + The cumulative product for each column (i.e., over the rows) of `a`: + + >>> np.cumprod(a, axis=0) + array([[ 1, 2, 3], + [ 4, 10, 18]]) + + The cumulative product for each row (i.e. over the columns) of `a`: + + >>> np.cumprod(a,axis=1) + array([[ 1, 2, 6], + [ 4, 20, 120]]) + + """ + return _wrapfunc(a, 'cumprod', axis=axis, dtype=dtype, out=out) + + +def _ndim_dispatcher(a): + return (a,) + + +@array_function_dispatch(_ndim_dispatcher) +def ndim(a): + """ + Return the number of dimensions of an array. + + Parameters + ---------- + a : array_like + Input array. If it is not already an ndarray, a conversion is + attempted. + + Returns + ------- + number_of_dimensions : int + The number of dimensions in `a`. Scalars are zero-dimensional. + + See Also + -------- + ndarray.ndim : equivalent method + shape : dimensions of array + ndarray.shape : dimensions of array + + Examples + -------- + >>> np.ndim([[1,2,3],[4,5,6]]) + 2 + >>> np.ndim(np.array([[1,2,3],[4,5,6]])) + 2 + >>> np.ndim(1) + 0 + + """ + try: + return a.ndim + except AttributeError: + return asarray(a).ndim + + +def _size_dispatcher(a, axis=None): + return (a,) + + +@array_function_dispatch(_size_dispatcher) +def size(a, axis=None): + """ + Return the number of elements along a given axis. + + Parameters + ---------- + a : array_like + Input data. + axis : int, optional + Axis along which the elements are counted. By default, give + the total number of elements. + + Returns + ------- + element_count : int + Number of elements along the specified axis. + + See Also + -------- + shape : dimensions of array + ndarray.shape : dimensions of array + ndarray.size : number of elements in array + + Examples + -------- + >>> a = np.array([[1,2,3],[4,5,6]]) + >>> np.size(a) + 6 + >>> np.size(a,1) + 3 + >>> np.size(a,0) + 2 + + """ + if axis is None: + try: + return a.size + except AttributeError: + return asarray(a).size + else: + try: + return a.shape[axis] + except AttributeError: + return asarray(a).shape[axis] + + +def _around_dispatcher(a, decimals=None, out=None): + return (a, out) + + +@array_function_dispatch(_around_dispatcher) +def around(a, decimals=0, out=None): + """ + Evenly round to the given number of decimals. + + Parameters + ---------- + a : array_like + Input data. + decimals : int, optional + Number of decimal places to round to (default: 0). If + decimals is negative, it specifies the number of positions to + the left of the decimal point. + out : ndarray, optional + Alternative output array in which to place the result. It must have + the same shape as the expected output, but the type of the output + values will be cast if necessary. See :ref:`ufuncs-output-type` for more + details. + + Returns + ------- + rounded_array : ndarray + An array of the same type as `a`, containing the rounded values. + Unless `out` was specified, a new array is created. A reference to + the result is returned. + + The real and imaginary parts of complex numbers are rounded + separately. The result of rounding a float is a float. + + See Also + -------- + ndarray.round : equivalent method + + ceil, fix, floor, rint, trunc + + + Notes + ----- + For values exactly halfway between rounded decimal values, NumPy + rounds to the nearest even value. Thus 1.5 and 2.5 round to 2.0, + -0.5 and 0.5 round to 0.0, etc. + + ``np.around`` uses a fast but sometimes inexact algorithm to round + floating-point datatypes. For positive `decimals` it is equivalent to + ``np.true_divide(np.rint(a * 10**decimals), 10**decimals)``, which has + error due to the inexact representation of decimal fractions in the IEEE + floating point standard [1]_ and errors introduced when scaling by powers + of ten. For instance, note the extra "1" in the following: + + >>> np.round(56294995342131.5, 3) + 56294995342131.51 + + If your goal is to print such values with a fixed number of decimals, it is + preferable to use numpy's float printing routines to limit the number of + printed decimals: + + >>> np.format_float_positional(56294995342131.5, precision=3) + '56294995342131.5' + + The float printing routines use an accurate but much more computationally + demanding algorithm to compute the number of digits after the decimal + point. + + Alternatively, Python's builtin `round` function uses a more accurate + but slower algorithm for 64-bit floating point values: + + >>> round(56294995342131.5, 3) + 56294995342131.5 + >>> np.round(16.055, 2), round(16.055, 2) # equals 16.0549999999999997 + (16.06, 16.05) + + + References + ---------- + .. [1] "Lecture Notes on the Status of IEEE 754", William Kahan, + https://people.eecs.berkeley.edu/~wkahan/ieee754status/IEEE754.PDF + .. [2] "How Futile are Mindless Assessments of + Roundoff in Floating-Point Computation?", William Kahan, + https://people.eecs.berkeley.edu/~wkahan/Mindless.pdf + + Examples + -------- + >>> np.around([0.37, 1.64]) + array([0., 2.]) + >>> np.around([0.37, 1.64], decimals=1) + array([0.4, 1.6]) + >>> np.around([.5, 1.5, 2.5, 3.5, 4.5]) # rounds to nearest even value + array([0., 2., 2., 4., 4.]) + >>> np.around([1,2,3,11], decimals=1) # ndarray of ints is returned + array([ 1, 2, 3, 11]) + >>> np.around([1,2,3,11], decimals=-1) + array([ 0, 0, 0, 10]) + + """ + return _wrapfunc(a, 'round', decimals=decimals, out=out) + + +def _mean_dispatcher(a, axis=None, dtype=None, out=None, keepdims=None, *, + where=None): + return (a, where, out) + + +@array_function_dispatch(_mean_dispatcher) +def mean(a, axis=None, dtype=None, out=None, keepdims=np._NoValue, *, + where=np._NoValue): + """ + Compute the arithmetic mean along the specified axis. + + Returns the average of the array elements. The average is taken over + the flattened array by default, otherwise over the specified axis. + `float64` intermediate and return values are used for integer inputs. + + Parameters + ---------- + a : array_like + Array containing numbers whose mean is desired. If `a` is not an + array, a conversion is attempted. + axis : None or int or tuple of ints, optional + Axis or axes along which the means are computed. The default is to + compute the mean of the flattened array. + + .. versionadded:: 1.7.0 + + If this is a tuple of ints, a mean is performed over multiple axes, + instead of a single axis or all the axes as before. + dtype : data-type, optional + Type to use in computing the mean. For integer inputs, the default + is `float64`; for floating point inputs, it is the same as the + input dtype. + out : ndarray, optional + Alternate output array in which to place the result. The default + is ``None``; if provided, it must have the same shape as the + expected output, but the type will be cast if necessary. + See :ref:`ufuncs-output-type` for more details. + + keepdims : bool, optional + If this is set to True, the axes which are reduced are left + in the result as dimensions with size one. With this option, + the result will broadcast correctly against the input array. + + If the default value is passed, then `keepdims` will not be + passed through to the `mean` method of sub-classes of + `ndarray`, however any non-default value will be. If the + sub-class' method does not implement `keepdims` any + exceptions will be raised. + + where : array_like of bool, optional + Elements to include in the mean. See `~numpy.ufunc.reduce` for details. + + .. versionadded:: 1.20.0 + + Returns + ------- + m : ndarray, see dtype parameter above + If `out=None`, returns a new array containing the mean values, + otherwise a reference to the output array is returned. + + See Also + -------- + average : Weighted average + std, var, nanmean, nanstd, nanvar + + Notes + ----- + The arithmetic mean is the sum of the elements along the axis divided + by the number of elements. + + Note that for floating-point input, the mean is computed using the + same precision the input has. Depending on the input data, this can + cause the results to be inaccurate, especially for `float32` (see + example below). Specifying a higher-precision accumulator using the + `dtype` keyword can alleviate this issue. + + By default, `float16` results are computed using `float32` intermediates + for extra precision. + + Examples + -------- + >>> a = np.array([[1, 2], [3, 4]]) + >>> np.mean(a) + 2.5 + >>> np.mean(a, axis=0) + array([2., 3.]) + >>> np.mean(a, axis=1) + array([1.5, 3.5]) + + In single precision, `mean` can be inaccurate: + + >>> a = np.zeros((2, 512*512), dtype=np.float32) + >>> a[0, :] = 1.0 + >>> a[1, :] = 0.1 + >>> np.mean(a) + 0.54999924 + + Computing the mean in float64 is more accurate: + + >>> np.mean(a, dtype=np.float64) + 0.55000000074505806 # may vary + + Specifying a where argument: + >>> a = np.array([[5, 9, 13], [14, 10, 12], [11, 15, 19]]) + >>> np.mean(a) + 12.0 + >>> np.mean(a, where=[[True], [False], [False]]) + 9.0 + + """ + kwargs = {} + if keepdims is not np._NoValue: + kwargs['keepdims'] = keepdims + if where is not np._NoValue: + kwargs['where'] = where + if type(a) is not mu.ndarray: + try: + mean = a.mean + except AttributeError: + pass + else: + return mean(axis=axis, dtype=dtype, out=out, **kwargs) + + return _methods._mean(a, axis=axis, dtype=dtype, + out=out, **kwargs) + + +def _std_dispatcher(a, axis=None, dtype=None, out=None, ddof=None, + keepdims=None, *, where=None): + return (a, where, out) + + +@array_function_dispatch(_std_dispatcher) +def std(a, axis=None, dtype=None, out=None, ddof=0, keepdims=np._NoValue, *, + where=np._NoValue): + """ + Compute the standard deviation along the specified axis. + + Returns the standard deviation, a measure of the spread of a distribution, + of the array elements. The standard deviation is computed for the + flattened array by default, otherwise over the specified axis. + + Parameters + ---------- + a : array_like + Calculate the standard deviation of these values. + axis : None or int or tuple of ints, optional + Axis or axes along which the standard deviation is computed. The + default is to compute the standard deviation of the flattened array. + + .. versionadded:: 1.7.0 + + If this is a tuple of ints, a standard deviation is performed over + multiple axes, instead of a single axis or all the axes as before. + dtype : dtype, optional + Type to use in computing the standard deviation. For arrays of + integer type the default is float64, for arrays of float types it is + the same as the array type. + out : ndarray, optional + Alternative output array in which to place the result. It must have + the same shape as the expected output but the type (of the calculated + values) will be cast if necessary. + ddof : int, optional + Means Delta Degrees of Freedom. The divisor used in calculations + is ``N - ddof``, where ``N`` represents the number of elements. + By default `ddof` is zero. + keepdims : bool, optional + If this is set to True, the axes which are reduced are left + in the result as dimensions with size one. With this option, + the result will broadcast correctly against the input array. + + If the default value is passed, then `keepdims` will not be + passed through to the `std` method of sub-classes of + `ndarray`, however any non-default value will be. If the + sub-class' method does not implement `keepdims` any + exceptions will be raised. + + where : array_like of bool, optional + Elements to include in the standard deviation. + See `~numpy.ufunc.reduce` for details. + + .. versionadded:: 1.20.0 + + Returns + ------- + standard_deviation : ndarray, see dtype parameter above. + If `out` is None, return a new array containing the standard deviation, + otherwise return a reference to the output array. + + See Also + -------- + var, mean, nanmean, nanstd, nanvar + :ref:`ufuncs-output-type` + + Notes + ----- + The standard deviation is the square root of the average of the squared + deviations from the mean, i.e., ``std = sqrt(mean(x))``, where + ``x = abs(a - a.mean())**2``. + + The average squared deviation is typically calculated as ``x.sum() / N``, + where ``N = len(x)``. If, however, `ddof` is specified, the divisor + ``N - ddof`` is used instead. In standard statistical practice, ``ddof=1`` + provides an unbiased estimator of the variance of the infinite population. + ``ddof=0`` provides a maximum likelihood estimate of the variance for + normally distributed variables. The standard deviation computed in this + function is the square root of the estimated variance, so even with + ``ddof=1``, it will not be an unbiased estimate of the standard deviation + per se. + + Note that, for complex numbers, `std` takes the absolute + value before squaring, so that the result is always real and nonnegative. + + For floating-point input, the *std* is computed using the same + precision the input has. Depending on the input data, this can cause + the results to be inaccurate, especially for float32 (see example below). + Specifying a higher-accuracy accumulator using the `dtype` keyword can + alleviate this issue. + + Examples + -------- + >>> a = np.array([[1, 2], [3, 4]]) + >>> np.std(a) + 1.1180339887498949 # may vary + >>> np.std(a, axis=0) + array([1., 1.]) + >>> np.std(a, axis=1) + array([0.5, 0.5]) + + In single precision, std() can be inaccurate: + + >>> a = np.zeros((2, 512*512), dtype=np.float32) + >>> a[0, :] = 1.0 + >>> a[1, :] = 0.1 + >>> np.std(a) + 0.45000005 + + Computing the standard deviation in float64 is more accurate: + + >>> np.std(a, dtype=np.float64) + 0.44999999925494177 # may vary + + Specifying a where argument: + + >>> a = np.array([[14, 8, 11, 10], [7, 9, 10, 11], [10, 15, 5, 10]]) + >>> np.std(a) + 2.614064523559687 # may vary + >>> np.std(a, where=[[True], [True], [False]]) + 2.0 + + """ + kwargs = {} + if keepdims is not np._NoValue: + kwargs['keepdims'] = keepdims + if where is not np._NoValue: + kwargs['where'] = where + if type(a) is not mu.ndarray: + try: + std = a.std + except AttributeError: + pass + else: + return std(axis=axis, dtype=dtype, out=out, ddof=ddof, **kwargs) + + return _methods._std(a, axis=axis, dtype=dtype, out=out, ddof=ddof, + **kwargs) + + +def _var_dispatcher(a, axis=None, dtype=None, out=None, ddof=None, + keepdims=None, *, where=None): + return (a, where, out) + + +@array_function_dispatch(_var_dispatcher) +def var(a, axis=None, dtype=None, out=None, ddof=0, keepdims=np._NoValue, *, + where=np._NoValue): + """ + Compute the variance along the specified axis. + + Returns the variance of the array elements, a measure of the spread of a + distribution. The variance is computed for the flattened array by + default, otherwise over the specified axis. + + Parameters + ---------- + a : array_like + Array containing numbers whose variance is desired. If `a` is not an + array, a conversion is attempted. + axis : None or int or tuple of ints, optional + Axis or axes along which the variance is computed. The default is to + compute the variance of the flattened array. + + .. versionadded:: 1.7.0 + + If this is a tuple of ints, a variance is performed over multiple axes, + instead of a single axis or all the axes as before. + dtype : data-type, optional + Type to use in computing the variance. For arrays of integer type + the default is `float64`; for arrays of float types it is the same as + the array type. + out : ndarray, optional + Alternate output array in which to place the result. It must have + the same shape as the expected output, but the type is cast if + necessary. + ddof : int, optional + "Delta Degrees of Freedom": the divisor used in the calculation is + ``N - ddof``, where ``N`` represents the number of elements. By + default `ddof` is zero. + keepdims : bool, optional + If this is set to True, the axes which are reduced are left + in the result as dimensions with size one. With this option, + the result will broadcast correctly against the input array. + + If the default value is passed, then `keepdims` will not be + passed through to the `var` method of sub-classes of + `ndarray`, however any non-default value will be. If the + sub-class' method does not implement `keepdims` any + exceptions will be raised. + + where : array_like of bool, optional + Elements to include in the variance. See `~numpy.ufunc.reduce` for + details. + + .. versionadded:: 1.20.0 + + Returns + ------- + variance : ndarray, see dtype parameter above + If ``out=None``, returns a new array containing the variance; + otherwise, a reference to the output array is returned. + + See Also + -------- + std, mean, nanmean, nanstd, nanvar + :ref:`ufuncs-output-type` + + Notes + ----- + The variance is the average of the squared deviations from the mean, + i.e., ``var = mean(x)``, where ``x = abs(a - a.mean())**2``. + + The mean is typically calculated as ``x.sum() / N``, where ``N = len(x)``. + If, however, `ddof` is specified, the divisor ``N - ddof`` is used + instead. In standard statistical practice, ``ddof=1`` provides an + unbiased estimator of the variance of a hypothetical infinite population. + ``ddof=0`` provides a maximum likelihood estimate of the variance for + normally distributed variables. + + Note that for complex numbers, the absolute value is taken before + squaring, so that the result is always real and nonnegative. + + For floating-point input, the variance is computed using the same + precision the input has. Depending on the input data, this can cause + the results to be inaccurate, especially for `float32` (see example + below). Specifying a higher-accuracy accumulator using the ``dtype`` + keyword can alleviate this issue. + + Examples + -------- + >>> a = np.array([[1, 2], [3, 4]]) + >>> np.var(a) + 1.25 + >>> np.var(a, axis=0) + array([1., 1.]) + >>> np.var(a, axis=1) + array([0.25, 0.25]) + + In single precision, var() can be inaccurate: + + >>> a = np.zeros((2, 512*512), dtype=np.float32) + >>> a[0, :] = 1.0 + >>> a[1, :] = 0.1 + >>> np.var(a) + 0.20250003 + + Computing the variance in float64 is more accurate: + + >>> np.var(a, dtype=np.float64) + 0.20249999932944759 # may vary + >>> ((1-0.55)**2 + (0.1-0.55)**2)/2 + 0.2025 + + Specifying a where argument: + + >>> a = np.array([[14, 8, 11, 10], [7, 9, 10, 11], [10, 15, 5, 10]]) + >>> np.var(a) + 6.833333333333333 # may vary + >>> np.var(a, where=[[True], [True], [False]]) + 4.0 + + """ + kwargs = {} + if keepdims is not np._NoValue: + kwargs['keepdims'] = keepdims + if where is not np._NoValue: + kwargs['where'] = where + + if type(a) is not mu.ndarray: + try: + var = a.var + + except AttributeError: + pass + else: + return var(axis=axis, dtype=dtype, out=out, ddof=ddof, **kwargs) + + return _methods._var(a, axis=axis, dtype=dtype, out=out, ddof=ddof, + **kwargs) + + +# Aliases of other functions. These have their own definitions only so that +# they can have unique docstrings. + +@array_function_dispatch(_around_dispatcher) +def round_(a, decimals=0, out=None): + """ + Round an array to the given number of decimals. + + See Also + -------- + around : equivalent function; see for details. + """ + return around(a, decimals=decimals, out=out) + + +@array_function_dispatch(_prod_dispatcher, verify=False) +def product(*args, **kwargs): + """ + Return the product of array elements over a given axis. + + See Also + -------- + prod : equivalent function; see for details. + """ + return prod(*args, **kwargs) + + +@array_function_dispatch(_cumprod_dispatcher, verify=False) +def cumproduct(*args, **kwargs): + """ + Return the cumulative product over the given axis. + + See Also + -------- + cumprod : equivalent function; see for details. + """ + return cumprod(*args, **kwargs) + + +@array_function_dispatch(_any_dispatcher, verify=False) +def sometrue(*args, **kwargs): + """ + Check whether some values are true. + + Refer to `any` for full documentation. + + See Also + -------- + any : equivalent function; see for details. + """ + return any(*args, **kwargs) + + +@array_function_dispatch(_all_dispatcher, verify=False) +def alltrue(*args, **kwargs): + """ + Check if all elements of input array are true. + + See Also + -------- + numpy.all : Equivalent function; see for details. + """ + return all(*args, **kwargs) diff --git a/venv/Lib/site-packages/numpy/core/fromnumeric.pyi b/venv/Lib/site-packages/numpy/core/fromnumeric.pyi new file mode 100644 index 0000000..66eb3bf --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/fromnumeric.pyi @@ -0,0 +1,483 @@ +import sys +import datetime as dt +from typing import Optional, Union, Sequence, Tuple, Any, overload, TypeVar + +from numpy import ( + ndarray, + number, + integer, + bool_, + generic, + _OrderKACF, + _OrderACF, + _ArrayLikeBool, + _ArrayLikeIntOrBool, + _ModeKind, + _PartitionKind, + _SortKind, + _SortSide, +) +from numpy.typing import ( + DTypeLike, + ArrayLike, + _ShapeLike, + _Shape, + _IntLike, + _BoolLike, + _NumberLike, +) + +if sys.version_info >= (3, 8): + from typing import Literal +else: + from typing_extensions import Literal + +# Various annotations for scalars + +# While dt.datetime and dt.timedelta are not technically part of NumPy, +# they are one of the rare few builtin scalars which serve as valid return types. +# See https://github.com/numpy/numpy-stubs/pull/67#discussion_r412604113. +_ScalarNumpy = Union[generic, dt.datetime, dt.timedelta] +_ScalarBuiltin = Union[str, bytes, dt.date, dt.timedelta, bool, int, float, complex] +_Scalar = Union[_ScalarBuiltin, _ScalarNumpy] + +# Integers and booleans can generally be used interchangeably +_ScalarIntOrBool = TypeVar("_ScalarIntOrBool", bound=Union[integer, bool_]) +_ScalarGeneric = TypeVar("_ScalarGeneric", bound=generic) +_ScalarGenericDT = TypeVar( + "_ScalarGenericDT", bound=Union[dt.datetime, dt.timedelta, generic] +) + +_Number = TypeVar("_Number", bound=number) + +# The signature of take() follows a common theme with its overloads: +# 1. A generic comes in; the same generic comes out +# 2. A scalar comes in; a generic comes out +# 3. An array-like object comes in; some keyword ensures that a generic comes out +# 4. An array-like object comes in; an ndarray or generic comes out +@overload +def take( + a: _ScalarGenericDT, + indices: int, + axis: Optional[int] = ..., + out: Optional[ndarray] = ..., + mode: _ModeKind = ..., +) -> _ScalarGenericDT: ... +@overload +def take( + a: _Scalar, + indices: int, + axis: Optional[int] = ..., + out: Optional[ndarray] = ..., + mode: _ModeKind = ..., +) -> _ScalarNumpy: ... +@overload +def take( + a: ArrayLike, + indices: int, + axis: Optional[int] = ..., + out: Optional[ndarray] = ..., + mode: _ModeKind = ..., +) -> _ScalarNumpy: ... +@overload +def take( + a: ArrayLike, + indices: _ArrayLikeIntOrBool, + axis: Optional[int] = ..., + out: Optional[ndarray] = ..., + mode: _ModeKind = ..., +) -> Union[_ScalarNumpy, ndarray]: ... +def reshape(a: ArrayLike, newshape: _ShapeLike, order: _OrderACF = ...) -> ndarray: ... +@overload +def choose( + a: _ScalarIntOrBool, + choices: ArrayLike, + out: Optional[ndarray] = ..., + mode: _ModeKind = ..., +) -> _ScalarIntOrBool: ... +@overload +def choose( + a: Union[_IntLike, _BoolLike], choices: ArrayLike, out: Optional[ndarray] = ..., mode: _ModeKind = ... +) -> Union[integer, bool_]: ... +@overload +def choose( + a: _ArrayLikeIntOrBool, + choices: ArrayLike, + out: Optional[ndarray] = ..., + mode: _ModeKind = ..., +) -> ndarray: ... +def repeat( + a: ArrayLike, repeats: _ArrayLikeIntOrBool, axis: Optional[int] = ... +) -> ndarray: ... +def put( + a: ndarray, ind: _ArrayLikeIntOrBool, v: ArrayLike, mode: _ModeKind = ... +) -> None: ... +def swapaxes(a: ArrayLike, axis1: int, axis2: int) -> ndarray: ... +def transpose( + a: ArrayLike, axes: Union[None, Sequence[int], ndarray] = ... +) -> ndarray: ... +def partition( + a: ArrayLike, + kth: _ArrayLikeIntOrBool, + axis: Optional[int] = ..., + kind: _PartitionKind = ..., + order: Union[None, str, Sequence[str]] = ..., +) -> ndarray: ... +@overload +def argpartition( + a: generic, + kth: _ArrayLikeIntOrBool, + axis: Optional[int] = ..., + kind: _PartitionKind = ..., + order: Union[None, str, Sequence[str]] = ..., +) -> integer: ... +@overload +def argpartition( + a: _ScalarBuiltin, + kth: _ArrayLikeIntOrBool, + axis: Optional[int] = ..., + kind: _PartitionKind = ..., + order: Union[None, str, Sequence[str]] = ..., +) -> ndarray: ... +@overload +def argpartition( + a: ArrayLike, + kth: _ArrayLikeIntOrBool, + axis: Optional[int] = ..., + kind: _PartitionKind = ..., + order: Union[None, str, Sequence[str]] = ..., +) -> ndarray: ... +def sort( + a: ArrayLike, + axis: Optional[int] = ..., + kind: Optional[_SortKind] = ..., + order: Union[None, str, Sequence[str]] = ..., +) -> ndarray: ... +def argsort( + a: ArrayLike, + axis: Optional[int] = ..., + kind: Optional[_SortKind] = ..., + order: Union[None, str, Sequence[str]] = ..., +) -> ndarray: ... +@overload +def argmax(a: ArrayLike, axis: None = ..., out: Optional[ndarray] = ...) -> integer: ... +@overload +def argmax( + a: ArrayLike, axis: int = ..., out: Optional[ndarray] = ... +) -> Union[integer, ndarray]: ... +@overload +def argmin(a: ArrayLike, axis: None = ..., out: Optional[ndarray] = ...) -> integer: ... +@overload +def argmin( + a: ArrayLike, axis: int = ..., out: Optional[ndarray] = ... +) -> Union[integer, ndarray]: ... +@overload +def searchsorted( + a: ArrayLike, + v: _Scalar, + side: _SortSide = ..., + sorter: Optional[_ArrayLikeIntOrBool] = ..., # 1D int array +) -> integer: ... +@overload +def searchsorted( + a: ArrayLike, + v: ArrayLike, + side: _SortSide = ..., + sorter: Optional[_ArrayLikeIntOrBool] = ..., # 1D int array +) -> ndarray: ... +def resize(a: ArrayLike, new_shape: _ShapeLike) -> ndarray: ... +@overload +def squeeze(a: _ScalarGeneric, axis: Optional[_ShapeLike] = ...) -> _ScalarGeneric: ... +@overload +def squeeze(a: ArrayLike, axis: Optional[_ShapeLike] = ...) -> ndarray: ... +def diagonal( + a: ArrayLike, offset: int = ..., axis1: int = ..., axis2: int = ... # >= 2D array +) -> ndarray: ... +def trace( + a: ArrayLike, # >= 2D array + offset: int = ..., + axis1: int = ..., + axis2: int = ..., + dtype: DTypeLike = ..., + out: Optional[ndarray] = ..., +) -> Union[number, ndarray]: ... +def ravel(a: ArrayLike, order: _OrderKACF = ...) -> ndarray: ... +def nonzero(a: ArrayLike) -> Tuple[ndarray, ...]: ... +def shape(a: ArrayLike) -> _Shape: ... +def compress( + condition: ArrayLike, # 1D bool array + a: ArrayLike, + axis: Optional[int] = ..., + out: Optional[ndarray] = ..., +) -> ndarray: ... +@overload +def clip( + a: _Number, + a_min: ArrayLike, + a_max: Optional[ArrayLike], + out: Optional[ndarray] = ..., + **kwargs: Any, +) -> _Number: ... +@overload +def clip( + a: _Number, + a_min: None, + a_max: ArrayLike, + out: Optional[ndarray] = ..., + **kwargs: Any, +) -> _Number: ... +@overload +def clip( + a: ArrayLike, + a_min: ArrayLike, + a_max: Optional[ArrayLike], + out: Optional[ndarray] = ..., + **kwargs: Any, +) -> Union[number, ndarray]: ... +@overload +def clip( + a: ArrayLike, + a_min: None, + a_max: ArrayLike, + out: Optional[ndarray] = ..., + **kwargs: Any, +) -> Union[number, ndarray]: ... +@overload +def sum( + a: _Number, + axis: Optional[_ShapeLike] = ..., + dtype: DTypeLike = ..., + out: Optional[ndarray] = ..., + keepdims: bool = ..., + initial: _NumberLike = ..., + where: _ArrayLikeBool = ..., +) -> _Number: ... +@overload +def sum( + a: ArrayLike, + axis: _ShapeLike = ..., + dtype: DTypeLike = ..., + out: Optional[ndarray] = ..., + keepdims: bool = ..., + initial: _NumberLike = ..., + where: _ArrayLikeBool = ..., +) -> Union[number, ndarray]: ... +@overload +def all( + a: ArrayLike, + axis: None = ..., + out: Optional[ndarray] = ..., + keepdims: Literal[False] = ..., +) -> bool_: ... +@overload +def all( + a: ArrayLike, + axis: Optional[_ShapeLike] = ..., + out: Optional[ndarray] = ..., + keepdims: bool = ..., +) -> Union[bool_, ndarray]: ... +@overload +def any( + a: ArrayLike, + axis: None = ..., + out: Optional[ndarray] = ..., + keepdims: Literal[False] = ..., +) -> bool_: ... +@overload +def any( + a: ArrayLike, + axis: Optional[_ShapeLike] = ..., + out: Optional[ndarray] = ..., + keepdims: bool = ..., +) -> Union[bool_, ndarray]: ... +def cumsum( + a: ArrayLike, + axis: Optional[int] = ..., + dtype: DTypeLike = ..., + out: Optional[ndarray] = ..., +) -> ndarray: ... +@overload +def ptp( + a: _Number, + axis: Optional[_ShapeLike] = ..., + out: Optional[ndarray] = ..., + keepdims: bool = ..., +) -> _Number: ... +@overload +def ptp( + a: ArrayLike, + axis: None = ..., + out: Optional[ndarray] = ..., + keepdims: Literal[False] = ..., +) -> number: ... +@overload +def ptp( + a: ArrayLike, + axis: Optional[_ShapeLike] = ..., + out: Optional[ndarray] = ..., + keepdims: bool = ..., +) -> Union[number, ndarray]: ... +@overload +def amax( + a: _Number, + axis: Optional[_ShapeLike] = ..., + out: Optional[ndarray] = ..., + keepdims: bool = ..., + initial: _NumberLike = ..., + where: _ArrayLikeBool = ..., +) -> _Number: ... +@overload +def amax( + a: ArrayLike, + axis: None = ..., + out: Optional[ndarray] = ..., + keepdims: Literal[False] = ..., + initial: _NumberLike = ..., + where: _ArrayLikeBool = ..., +) -> number: ... +@overload +def amax( + a: ArrayLike, + axis: Optional[_ShapeLike] = ..., + out: Optional[ndarray] = ..., + keepdims: bool = ..., + initial: _NumberLike = ..., + where: _ArrayLikeBool = ..., +) -> Union[number, ndarray]: ... +@overload +def amin( + a: _Number, + axis: Optional[_ShapeLike] = ..., + out: Optional[ndarray] = ..., + keepdims: bool = ..., + initial: _NumberLike = ..., + where: _ArrayLikeBool = ..., +) -> _Number: ... +@overload +def amin( + a: ArrayLike, + axis: None = ..., + out: Optional[ndarray] = ..., + keepdims: Literal[False] = ..., + initial: _NumberLike = ..., + where: _ArrayLikeBool = ..., +) -> number: ... +@overload +def amin( + a: ArrayLike, + axis: Optional[_ShapeLike] = ..., + out: Optional[ndarray] = ..., + keepdims: bool = ..., + initial: _NumberLike = ..., + where: _ArrayLikeBool = ..., +) -> Union[number, ndarray]: ... + +# TODO: `np.prod()``: For object arrays `initial` does not necessarily +# have to be a numerical scalar. +# The only requirement is that it is compatible +# with the `.__mul__()` method(s) of the passed array's elements. + +# Note that the same situation holds for all wrappers around +# `np.ufunc.reduce`, e.g. `np.sum()` (`.__add__()`). +@overload +def prod( + a: _Number, + axis: Optional[_ShapeLike] = ..., + dtype: DTypeLike = ..., + out: None = ..., + keepdims: bool = ..., + initial: _NumberLike = ..., + where: _ArrayLikeBool = ..., +) -> _Number: ... +@overload +def prod( + a: ArrayLike, + axis: None = ..., + dtype: DTypeLike = ..., + out: None = ..., + keepdims: Literal[False] = ..., + initial: _NumberLike = ..., + where: _ArrayLikeBool = ..., +) -> number: ... +@overload +def prod( + a: ArrayLike, + axis: Optional[_ShapeLike] = ..., + dtype: DTypeLike = ..., + out: Optional[ndarray] = ..., + keepdims: bool = ..., + initial: _NumberLike = ..., + where: _ArrayLikeBool = ..., +) -> Union[number, ndarray]: ... +def cumprod( + a: ArrayLike, + axis: Optional[int] = ..., + dtype: DTypeLike = ..., + out: Optional[ndarray] = ..., +) -> ndarray: ... +def ndim(a: ArrayLike) -> int: ... +def size(a: ArrayLike, axis: Optional[int] = ...) -> int: ... +@overload +def around( + a: _Number, decimals: int = ..., out: Optional[ndarray] = ... +) -> _Number: ... +@overload +def around( + a: _NumberLike, decimals: int = ..., out: Optional[ndarray] = ... +) -> number: ... +@overload +def around( + a: ArrayLike, decimals: int = ..., out: Optional[ndarray] = ... +) -> ndarray: ... +@overload +def mean( + a: ArrayLike, + axis: None = ..., + dtype: DTypeLike = ..., + out: None = ..., + keepdims: Literal[False] = ..., +) -> number: ... +@overload +def mean( + a: ArrayLike, + axis: Optional[_ShapeLike] = ..., + dtype: DTypeLike = ..., + out: Optional[ndarray] = ..., + keepdims: bool = ..., +) -> Union[number, ndarray]: ... +@overload +def std( + a: ArrayLike, + axis: None = ..., + dtype: DTypeLike = ..., + out: None = ..., + ddof: int = ..., + keepdims: Literal[False] = ..., +) -> number: ... +@overload +def std( + a: ArrayLike, + axis: Optional[_ShapeLike] = ..., + dtype: DTypeLike = ..., + out: Optional[ndarray] = ..., + ddof: int = ..., + keepdims: bool = ..., +) -> Union[number, ndarray]: ... +@overload +def var( + a: ArrayLike, + axis: None = ..., + dtype: DTypeLike = ..., + out: None = ..., + ddof: int = ..., + keepdims: Literal[False] = ..., +) -> number: ... +@overload +def var( + a: ArrayLike, + axis: Optional[_ShapeLike] = ..., + dtype: DTypeLike = ..., + out: Optional[ndarray] = ..., + ddof: int = ..., + keepdims: bool = ..., +) -> Union[number, ndarray]: ... diff --git a/venv/Lib/site-packages/numpy/core/function_base.py b/venv/Lib/site-packages/numpy/core/function_base.py new file mode 100644 index 0000000..8a1fee9 --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/function_base.py @@ -0,0 +1,529 @@ +import functools +import warnings +import operator +import types + +from . import numeric as _nx +from .numeric import result_type, NaN, asanyarray, ndim +from numpy.core.multiarray import add_docstring +from numpy.core import overrides + +__all__ = ['logspace', 'linspace', 'geomspace'] + + +array_function_dispatch = functools.partial( + overrides.array_function_dispatch, module='numpy') + + +def _linspace_dispatcher(start, stop, num=None, endpoint=None, retstep=None, + dtype=None, axis=None): + return (start, stop) + + +@array_function_dispatch(_linspace_dispatcher) +def linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None, + axis=0): + """ + Return evenly spaced numbers over a specified interval. + + Returns `num` evenly spaced samples, calculated over the + interval [`start`, `stop`]. + + The endpoint of the interval can optionally be excluded. + + .. versionchanged:: 1.16.0 + Non-scalar `start` and `stop` are now supported. + + .. versionchanged:: 1.20.0 + Values are rounded towards ``-inf`` instead of ``0`` when an + integer ``dtype`` is specified. The old behavior can + still be obtained with ``np.linspace(start, stop, num).astype(int)`` + + Parameters + ---------- + start : array_like + The starting value of the sequence. + stop : array_like + The end value of the sequence, unless `endpoint` is set to False. + In that case, the sequence consists of all but the last of ``num + 1`` + evenly spaced samples, so that `stop` is excluded. Note that the step + size changes when `endpoint` is False. + num : int, optional + Number of samples to generate. Default is 50. Must be non-negative. + endpoint : bool, optional + If True, `stop` is the last sample. Otherwise, it is not included. + Default is True. + retstep : bool, optional + If True, return (`samples`, `step`), where `step` is the spacing + between samples. + dtype : dtype, optional + The type of the output array. If `dtype` is not given, the data type + is inferred from `start` and `stop`. The inferred dtype will never be + an integer; `float` is chosen even if the arguments would produce an + array of integers. + + .. versionadded:: 1.9.0 + + axis : int, optional + The axis in the result to store the samples. Relevant only if start + or stop are array-like. By default (0), the samples will be along a + new axis inserted at the beginning. Use -1 to get an axis at the end. + + .. versionadded:: 1.16.0 + + Returns + ------- + samples : ndarray + There are `num` equally spaced samples in the closed interval + ``[start, stop]`` or the half-open interval ``[start, stop)`` + (depending on whether `endpoint` is True or False). + step : float, optional + Only returned if `retstep` is True + + Size of spacing between samples. + + + See Also + -------- + arange : Similar to `linspace`, but uses a step size (instead of the + number of samples). + geomspace : Similar to `linspace`, but with numbers spaced evenly on a log + scale (a geometric progression). + logspace : Similar to `geomspace`, but with the end points specified as + logarithms. + + Examples + -------- + >>> np.linspace(2.0, 3.0, num=5) + array([2. , 2.25, 2.5 , 2.75, 3. ]) + >>> np.linspace(2.0, 3.0, num=5, endpoint=False) + array([2. , 2.2, 2.4, 2.6, 2.8]) + >>> np.linspace(2.0, 3.0, num=5, retstep=True) + (array([2. , 2.25, 2.5 , 2.75, 3. ]), 0.25) + + Graphical illustration: + + >>> import matplotlib.pyplot as plt + >>> N = 8 + >>> y = np.zeros(N) + >>> x1 = np.linspace(0, 10, N, endpoint=True) + >>> x2 = np.linspace(0, 10, N, endpoint=False) + >>> plt.plot(x1, y, 'o') + [] + >>> plt.plot(x2, y + 0.5, 'o') + [] + >>> plt.ylim([-0.5, 1]) + (-0.5, 1) + >>> plt.show() + + """ + num = operator.index(num) + if num < 0: + raise ValueError("Number of samples, %s, must be non-negative." % num) + div = (num - 1) if endpoint else num + + # Convert float/complex array scalars to float, gh-3504 + # and make sure one can use variables that have an __array_interface__, gh-6634 + start = asanyarray(start) * 1.0 + stop = asanyarray(stop) * 1.0 + + dt = result_type(start, stop, float(num)) + if dtype is None: + dtype = dt + + delta = stop - start + y = _nx.arange(0, num, dtype=dt).reshape((-1,) + (1,) * ndim(delta)) + # In-place multiplication y *= delta/div is faster, but prevents the multiplicant + # from overriding what class is produced, and thus prevents, e.g. use of Quantities, + # see gh-7142. Hence, we multiply in place only for standard scalar types. + _mult_inplace = _nx.isscalar(delta) + if div > 0: + step = delta / div + if _nx.any(step == 0): + # Special handling for denormal numbers, gh-5437 + y /= div + if _mult_inplace: + y *= delta + else: + y = y * delta + else: + if _mult_inplace: + y *= step + else: + y = y * step + else: + # sequences with 0 items or 1 item with endpoint=True (i.e. div <= 0) + # have an undefined step + step = NaN + # Multiply with delta to allow possible override of output class. + y = y * delta + + y += start + + if endpoint and num > 1: + y[-1] = stop + + if axis != 0: + y = _nx.moveaxis(y, 0, axis) + + if _nx.issubdtype(dtype, _nx.integer): + _nx.floor(y, out=y) + + if retstep: + return y.astype(dtype, copy=False), step + else: + return y.astype(dtype, copy=False) + + +def _logspace_dispatcher(start, stop, num=None, endpoint=None, base=None, + dtype=None, axis=None): + return (start, stop) + + +@array_function_dispatch(_logspace_dispatcher) +def logspace(start, stop, num=50, endpoint=True, base=10.0, dtype=None, + axis=0): + """ + Return numbers spaced evenly on a log scale. + + In linear space, the sequence starts at ``base ** start`` + (`base` to the power of `start`) and ends with ``base ** stop`` + (see `endpoint` below). + + .. versionchanged:: 1.16.0 + Non-scalar `start` and `stop` are now supported. + + Parameters + ---------- + start : array_like + ``base ** start`` is the starting value of the sequence. + stop : array_like + ``base ** stop`` is the final value of the sequence, unless `endpoint` + is False. In that case, ``num + 1`` values are spaced over the + interval in log-space, of which all but the last (a sequence of + length `num`) are returned. + num : integer, optional + Number of samples to generate. Default is 50. + endpoint : boolean, optional + If true, `stop` is the last sample. Otherwise, it is not included. + Default is True. + base : array_like, optional + The base of the log space. The step size between the elements in + ``ln(samples) / ln(base)`` (or ``log_base(samples)``) is uniform. + Default is 10.0. + dtype : dtype + The type of the output array. If `dtype` is not given, the data type + is inferred from `start` and `stop`. The inferred type will never be + an integer; `float` is chosen even if the arguments would produce an + array of integers. + axis : int, optional + The axis in the result to store the samples. Relevant only if start + or stop are array-like. By default (0), the samples will be along a + new axis inserted at the beginning. Use -1 to get an axis at the end. + + .. versionadded:: 1.16.0 + + + Returns + ------- + samples : ndarray + `num` samples, equally spaced on a log scale. + + See Also + -------- + arange : Similar to linspace, with the step size specified instead of the + number of samples. Note that, when used with a float endpoint, the + endpoint may or may not be included. + linspace : Similar to logspace, but with the samples uniformly distributed + in linear space, instead of log space. + geomspace : Similar to logspace, but with endpoints specified directly. + + Notes + ----- + Logspace is equivalent to the code + + >>> y = np.linspace(start, stop, num=num, endpoint=endpoint) + ... # doctest: +SKIP + >>> power(base, y).astype(dtype) + ... # doctest: +SKIP + + Examples + -------- + >>> np.logspace(2.0, 3.0, num=4) + array([ 100. , 215.443469 , 464.15888336, 1000. ]) + >>> np.logspace(2.0, 3.0, num=4, endpoint=False) + array([100. , 177.827941 , 316.22776602, 562.34132519]) + >>> np.logspace(2.0, 3.0, num=4, base=2.0) + array([4. , 5.0396842 , 6.34960421, 8. ]) + + Graphical illustration: + + >>> import matplotlib.pyplot as plt + >>> N = 10 + >>> x1 = np.logspace(0.1, 1, N, endpoint=True) + >>> x2 = np.logspace(0.1, 1, N, endpoint=False) + >>> y = np.zeros(N) + >>> plt.plot(x1, y, 'o') + [] + >>> plt.plot(x2, y + 0.5, 'o') + [] + >>> plt.ylim([-0.5, 1]) + (-0.5, 1) + >>> plt.show() + + """ + y = linspace(start, stop, num=num, endpoint=endpoint, axis=axis) + if dtype is None: + return _nx.power(base, y) + return _nx.power(base, y).astype(dtype, copy=False) + + +def _geomspace_dispatcher(start, stop, num=None, endpoint=None, dtype=None, + axis=None): + return (start, stop) + + +@array_function_dispatch(_geomspace_dispatcher) +def geomspace(start, stop, num=50, endpoint=True, dtype=None, axis=0): + """ + Return numbers spaced evenly on a log scale (a geometric progression). + + This is similar to `logspace`, but with endpoints specified directly. + Each output sample is a constant multiple of the previous. + + .. versionchanged:: 1.16.0 + Non-scalar `start` and `stop` are now supported. + + Parameters + ---------- + start : array_like + The starting value of the sequence. + stop : array_like + The final value of the sequence, unless `endpoint` is False. + In that case, ``num + 1`` values are spaced over the + interval in log-space, of which all but the last (a sequence of + length `num`) are returned. + num : integer, optional + Number of samples to generate. Default is 50. + endpoint : boolean, optional + If true, `stop` is the last sample. Otherwise, it is not included. + Default is True. + dtype : dtype + The type of the output array. If `dtype` is not given, the data type + is inferred from `start` and `stop`. The inferred dtype will never be + an integer; `float` is chosen even if the arguments would produce an + array of integers. + axis : int, optional + The axis in the result to store the samples. Relevant only if start + or stop are array-like. By default (0), the samples will be along a + new axis inserted at the beginning. Use -1 to get an axis at the end. + + .. versionadded:: 1.16.0 + + Returns + ------- + samples : ndarray + `num` samples, equally spaced on a log scale. + + See Also + -------- + logspace : Similar to geomspace, but with endpoints specified using log + and base. + linspace : Similar to geomspace, but with arithmetic instead of geometric + progression. + arange : Similar to linspace, with the step size specified instead of the + number of samples. + + Notes + ----- + If the inputs or dtype are complex, the output will follow a logarithmic + spiral in the complex plane. (There are an infinite number of spirals + passing through two points; the output will follow the shortest such path.) + + Examples + -------- + >>> np.geomspace(1, 1000, num=4) + array([ 1., 10., 100., 1000.]) + >>> np.geomspace(1, 1000, num=3, endpoint=False) + array([ 1., 10., 100.]) + >>> np.geomspace(1, 1000, num=4, endpoint=False) + array([ 1. , 5.62341325, 31.6227766 , 177.827941 ]) + >>> np.geomspace(1, 256, num=9) + array([ 1., 2., 4., 8., 16., 32., 64., 128., 256.]) + + Note that the above may not produce exact integers: + + >>> np.geomspace(1, 256, num=9, dtype=int) + array([ 1, 2, 4, 7, 16, 32, 63, 127, 256]) + >>> np.around(np.geomspace(1, 256, num=9)).astype(int) + array([ 1, 2, 4, 8, 16, 32, 64, 128, 256]) + + Negative, decreasing, and complex inputs are allowed: + + >>> np.geomspace(1000, 1, num=4) + array([1000., 100., 10., 1.]) + >>> np.geomspace(-1000, -1, num=4) + array([-1000., -100., -10., -1.]) + >>> np.geomspace(1j, 1000j, num=4) # Straight line + array([0. +1.j, 0. +10.j, 0. +100.j, 0.+1000.j]) + >>> np.geomspace(-1+0j, 1+0j, num=5) # Circle + array([-1.00000000e+00+1.22464680e-16j, -7.07106781e-01+7.07106781e-01j, + 6.12323400e-17+1.00000000e+00j, 7.07106781e-01+7.07106781e-01j, + 1.00000000e+00+0.00000000e+00j]) + + Graphical illustration of ``endpoint`` parameter: + + >>> import matplotlib.pyplot as plt + >>> N = 10 + >>> y = np.zeros(N) + >>> plt.semilogx(np.geomspace(1, 1000, N, endpoint=True), y + 1, 'o') + [] + >>> plt.semilogx(np.geomspace(1, 1000, N, endpoint=False), y + 2, 'o') + [] + >>> plt.axis([0.5, 2000, 0, 3]) + [0.5, 2000, 0, 3] + >>> plt.grid(True, color='0.7', linestyle='-', which='both', axis='both') + >>> plt.show() + + """ + start = asanyarray(start) + stop = asanyarray(stop) + if _nx.any(start == 0) or _nx.any(stop == 0): + raise ValueError('Geometric sequence cannot include zero') + + dt = result_type(start, stop, float(num), _nx.zeros((), dtype)) + if dtype is None: + dtype = dt + else: + # complex to dtype('complex128'), for instance + dtype = _nx.dtype(dtype) + + # Promote both arguments to the same dtype in case, for instance, one is + # complex and another is negative and log would produce NaN otherwise. + # Copy since we may change things in-place further down. + start = start.astype(dt, copy=True) + stop = stop.astype(dt, copy=True) + + out_sign = _nx.ones(_nx.broadcast(start, stop).shape, dt) + # Avoid negligible real or imaginary parts in output by rotating to + # positive real, calculating, then undoing rotation + if _nx.issubdtype(dt, _nx.complexfloating): + all_imag = (start.real == 0.) & (stop.real == 0.) + if _nx.any(all_imag): + start[all_imag] = start[all_imag].imag + stop[all_imag] = stop[all_imag].imag + out_sign[all_imag] = 1j + + both_negative = (_nx.sign(start) == -1) & (_nx.sign(stop) == -1) + if _nx.any(both_negative): + _nx.negative(start, out=start, where=both_negative) + _nx.negative(stop, out=stop, where=both_negative) + _nx.negative(out_sign, out=out_sign, where=both_negative) + + log_start = _nx.log10(start) + log_stop = _nx.log10(stop) + result = logspace(log_start, log_stop, num=num, + endpoint=endpoint, base=10.0, dtype=dtype) + + # Make sure the endpoints match the start and stop arguments. This is + # necessary because np.exp(np.log(x)) is not necessarily equal to x. + if num > 0: + result[0] = start + if num > 1 and endpoint: + result[-1] = stop + + result = out_sign * result + + if axis != 0: + result = _nx.moveaxis(result, 0, axis) + + return result.astype(dtype, copy=False) + + +def _needs_add_docstring(obj): + """ + Returns true if the only way to set the docstring of `obj` from python is + via add_docstring. + + This function errs on the side of being overly conservative. + """ + Py_TPFLAGS_HEAPTYPE = 1 << 9 + + if isinstance(obj, (types.FunctionType, types.MethodType, property)): + return False + + if isinstance(obj, type) and obj.__flags__ & Py_TPFLAGS_HEAPTYPE: + return False + + return True + + +def _add_docstring(obj, doc, warn_on_python): + if warn_on_python and not _needs_add_docstring(obj): + warnings.warn( + "add_newdoc was used on a pure-python object {}. " + "Prefer to attach it directly to the source." + .format(obj), + UserWarning, + stacklevel=3) + try: + add_docstring(obj, doc) + except Exception: + pass + + +def add_newdoc(place, obj, doc, warn_on_python=True): + """ + Add documentation to an existing object, typically one defined in C + + The purpose is to allow easier editing of the docstrings without requiring + a re-compile. This exists primarily for internal use within numpy itself. + + Parameters + ---------- + place : str + The absolute name of the module to import from + obj : str + The name of the object to add documentation to, typically a class or + function name + doc : {str, Tuple[str, str], List[Tuple[str, str]]} + If a string, the documentation to apply to `obj` + + If a tuple, then the first element is interpreted as an attribute of + `obj` and the second as the docstring to apply - ``(method, docstring)`` + + If a list, then each element of the list should be a tuple of length + two - ``[(method1, docstring1), (method2, docstring2), ...]`` + warn_on_python : bool + If True, the default, emit `UserWarning` if this is used to attach + documentation to a pure-python object. + + Notes + ----- + This routine never raises an error if the docstring can't be written, but + will raise an error if the object being documented does not exist. + + This routine cannot modify read-only docstrings, as appear + in new-style classes or built-in functions. Because this + routine never raises an error the caller must check manually + that the docstrings were changed. + + Since this function grabs the ``char *`` from a c-level str object and puts + it into the ``tp_doc`` slot of the type of `obj`, it violates a number of + C-API best-practices, by: + + - modifying a `PyTypeObject` after calling `PyType_Ready` + - calling `Py_INCREF` on the str and losing the reference, so the str + will never be released + + If possible it should be avoided. + """ + new = getattr(__import__(place, globals(), {}, [obj]), obj) + if isinstance(doc, str): + _add_docstring(new, doc.strip(), warn_on_python) + elif isinstance(doc, tuple): + attr, docstring = doc + _add_docstring(getattr(new, attr), docstring.strip(), warn_on_python) + elif isinstance(doc, list): + for attr, docstring in doc: + _add_docstring(getattr(new, attr), docstring.strip(), warn_on_python) diff --git a/venv/Lib/site-packages/numpy/core/function_base.pyi b/venv/Lib/site-packages/numpy/core/function_base.pyi new file mode 100644 index 0000000..1490bed --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/function_base.pyi @@ -0,0 +1,56 @@ +import sys +from typing import overload, Tuple, Union, Sequence, Any + +from numpy import ndarray, inexact +from numpy.typing import ArrayLike, DTypeLike, _SupportsArray, _NumberLike + +if sys.version_info >= (3, 8): + from typing import SupportsIndex, Literal +else: + from typing_extensions import Literal, Protocol + + class SupportsIndex(Protocol): + def __index__(self) -> int: ... + +# TODO: wait for support for recursive types +_ArrayLikeNested = Sequence[Sequence[Any]] +_ArrayLikeNumber = Union[ + _NumberLike, Sequence[_NumberLike], ndarray, _SupportsArray, _ArrayLikeNested +] +@overload +def linspace( + start: _ArrayLikeNumber, + stop: _ArrayLikeNumber, + num: SupportsIndex = ..., + endpoint: bool = ..., + retstep: Literal[False] = ..., + dtype: DTypeLike = ..., + axis: SupportsIndex = ..., +) -> ndarray: ... +@overload +def linspace( + start: _ArrayLikeNumber, + stop: _ArrayLikeNumber, + num: SupportsIndex = ..., + endpoint: bool = ..., + retstep: Literal[True] = ..., + dtype: DTypeLike = ..., + axis: SupportsIndex = ..., +) -> Tuple[ndarray, inexact]: ... +def logspace( + start: _ArrayLikeNumber, + stop: _ArrayLikeNumber, + num: SupportsIndex = ..., + endpoint: bool = ..., + base: _ArrayLikeNumber = ..., + dtype: DTypeLike = ..., + axis: SupportsIndex = ..., +) -> ndarray: ... +def geomspace( + start: _ArrayLikeNumber, + stop: _ArrayLikeNumber, + num: SupportsIndex = ..., + endpoint: bool = ..., + dtype: DTypeLike = ..., + axis: SupportsIndex = ..., +) -> ndarray: ... diff --git a/venv/Lib/site-packages/numpy/core/generate_numpy_api.py b/venv/Lib/site-packages/numpy/core/generate_numpy_api.py new file mode 100644 index 0000000..7997135 --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/generate_numpy_api.py @@ -0,0 +1,239 @@ +import os +import genapi + +from genapi import \ + TypeApi, GlobalVarApi, FunctionApi, BoolValuesApi + +import numpy_api + +# use annotated api when running under cpychecker +h_template = r""" +#if defined(_MULTIARRAYMODULE) || defined(WITH_CPYCHECKER_STEALS_REFERENCE_TO_ARG_ATTRIBUTE) + +typedef struct { + PyObject_HEAD + npy_bool obval; +} PyBoolScalarObject; + +extern NPY_NO_EXPORT PyTypeObject PyArrayMapIter_Type; +extern NPY_NO_EXPORT PyTypeObject PyArrayNeighborhoodIter_Type; +extern NPY_NO_EXPORT PyBoolScalarObject _PyArrayScalar_BoolValues[2]; + +%s + +#else + +#if defined(PY_ARRAY_UNIQUE_SYMBOL) +#define PyArray_API PY_ARRAY_UNIQUE_SYMBOL +#endif + +#if defined(NO_IMPORT) || defined(NO_IMPORT_ARRAY) +extern void **PyArray_API; +#else +#if defined(PY_ARRAY_UNIQUE_SYMBOL) +void **PyArray_API; +#else +static void **PyArray_API=NULL; +#endif +#endif + +%s + +#if !defined(NO_IMPORT_ARRAY) && !defined(NO_IMPORT) +static int +_import_array(void) +{ + int st; + PyObject *numpy = PyImport_ImportModule("numpy.core._multiarray_umath"); + PyObject *c_api = NULL; + + if (numpy == NULL) { + return -1; + } + c_api = PyObject_GetAttrString(numpy, "_ARRAY_API"); + Py_DECREF(numpy); + if (c_api == NULL) { + PyErr_SetString(PyExc_AttributeError, "_ARRAY_API not found"); + return -1; + } + + if (!PyCapsule_CheckExact(c_api)) { + PyErr_SetString(PyExc_RuntimeError, "_ARRAY_API is not PyCapsule object"); + Py_DECREF(c_api); + return -1; + } + PyArray_API = (void **)PyCapsule_GetPointer(c_api, NULL); + Py_DECREF(c_api); + if (PyArray_API == NULL) { + PyErr_SetString(PyExc_RuntimeError, "_ARRAY_API is NULL pointer"); + return -1; + } + + /* Perform runtime check of C API version */ + if (NPY_VERSION != PyArray_GetNDArrayCVersion()) { + PyErr_Format(PyExc_RuntimeError, "module compiled against "\ + "ABI version 0x%%x but this version of numpy is 0x%%x", \ + (int) NPY_VERSION, (int) PyArray_GetNDArrayCVersion()); + return -1; + } + if (NPY_FEATURE_VERSION > PyArray_GetNDArrayCFeatureVersion()) { + PyErr_Format(PyExc_RuntimeError, "module compiled against "\ + "API version 0x%%x but this version of numpy is 0x%%x", \ + (int) NPY_FEATURE_VERSION, (int) PyArray_GetNDArrayCFeatureVersion()); + return -1; + } + + /* + * Perform runtime check of endianness and check it matches the one set by + * the headers (npy_endian.h) as a safeguard + */ + st = PyArray_GetEndianness(); + if (st == NPY_CPU_UNKNOWN_ENDIAN) { + PyErr_Format(PyExc_RuntimeError, "FATAL: module compiled as unknown endian"); + return -1; + } +#if NPY_BYTE_ORDER == NPY_BIG_ENDIAN + if (st != NPY_CPU_BIG) { + PyErr_Format(PyExc_RuntimeError, "FATAL: module compiled as "\ + "big endian, but detected different endianness at runtime"); + return -1; + } +#elif NPY_BYTE_ORDER == NPY_LITTLE_ENDIAN + if (st != NPY_CPU_LITTLE) { + PyErr_Format(PyExc_RuntimeError, "FATAL: module compiled as "\ + "little endian, but detected different endianness at runtime"); + return -1; + } +#endif + + return 0; +} + +#define import_array() {if (_import_array() < 0) {PyErr_Print(); PyErr_SetString(PyExc_ImportError, "numpy.core.multiarray failed to import"); return NULL; } } + +#define import_array1(ret) {if (_import_array() < 0) {PyErr_Print(); PyErr_SetString(PyExc_ImportError, "numpy.core.multiarray failed to import"); return ret; } } + +#define import_array2(msg, ret) {if (_import_array() < 0) {PyErr_Print(); PyErr_SetString(PyExc_ImportError, msg); return ret; } } + +#endif + +#endif +""" + + +c_template = r""" +/* These pointers will be stored in the C-object for use in other + extension modules +*/ + +void *PyArray_API[] = { +%s +}; +""" + +c_api_header = """ +=========== +NumPy C-API +=========== +""" + +def generate_api(output_dir, force=False): + basename = 'multiarray_api' + + h_file = os.path.join(output_dir, '__%s.h' % basename) + c_file = os.path.join(output_dir, '__%s.c' % basename) + d_file = os.path.join(output_dir, '%s.txt' % basename) + targets = (h_file, c_file, d_file) + + sources = numpy_api.multiarray_api + + if (not force and not genapi.should_rebuild(targets, [numpy_api.__file__, __file__])): + return targets + else: + do_generate_api(targets, sources) + + return targets + +def do_generate_api(targets, sources): + header_file = targets[0] + c_file = targets[1] + doc_file = targets[2] + + global_vars = sources[0] + scalar_bool_values = sources[1] + types_api = sources[2] + multiarray_funcs = sources[3] + + multiarray_api = sources[:] + + module_list = [] + extension_list = [] + init_list = [] + + # Check multiarray api indexes + multiarray_api_index = genapi.merge_api_dicts(multiarray_api) + genapi.check_api_dict(multiarray_api_index) + + numpyapi_list = genapi.get_api_functions('NUMPY_API', + multiarray_funcs) + + # FIXME: ordered_funcs_api is unused + ordered_funcs_api = genapi.order_dict(multiarray_funcs) + + # Create dict name -> *Api instance + api_name = 'PyArray_API' + multiarray_api_dict = {} + for f in numpyapi_list: + name = f.name + index = multiarray_funcs[name][0] + annotations = multiarray_funcs[name][1:] + multiarray_api_dict[f.name] = FunctionApi(f.name, index, annotations, + f.return_type, + f.args, api_name) + + for name, val in global_vars.items(): + index, type = val + multiarray_api_dict[name] = GlobalVarApi(name, index, type, api_name) + + for name, val in scalar_bool_values.items(): + index = val[0] + multiarray_api_dict[name] = BoolValuesApi(name, index, api_name) + + for name, val in types_api.items(): + index = val[0] + internal_type = None if len(val) == 1 else val[1] + multiarray_api_dict[name] = TypeApi( + name, index, 'PyTypeObject', api_name, internal_type) + + if len(multiarray_api_dict) != len(multiarray_api_index): + keys_dict = set(multiarray_api_dict.keys()) + keys_index = set(multiarray_api_index.keys()) + raise AssertionError( + "Multiarray API size mismatch - " + "index has extra keys {}, dict has extra keys {}" + .format(keys_index - keys_dict, keys_dict - keys_index) + ) + + extension_list = [] + for name, index in genapi.order_dict(multiarray_api_index): + api_item = multiarray_api_dict[name] + extension_list.append(api_item.define_from_array_api_string()) + init_list.append(api_item.array_api_define()) + module_list.append(api_item.internal_define()) + + # Write to header + s = h_template % ('\n'.join(module_list), '\n'.join(extension_list)) + genapi.write_file(header_file, s) + + # Write to c-code + s = c_template % ',\n'.join(init_list) + genapi.write_file(c_file, s) + + # write to documentation + s = c_api_header + for func in numpyapi_list: + s += func.to_ReST() + s += '\n\n' + genapi.write_file(doc_file, s) + + return targets diff --git a/venv/Lib/site-packages/numpy/core/getlimits.py b/venv/Lib/site-packages/numpy/core/getlimits.py new file mode 100644 index 0000000..fcb73e8 --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/getlimits.py @@ -0,0 +1,564 @@ +"""Machine limits for Float32 and Float64 and (long double) if available... + +""" +__all__ = ['finfo', 'iinfo'] + +import warnings + +from .machar import MachAr +from .overrides import set_module +from . import numeric +from . import numerictypes as ntypes +from .numeric import array, inf +from .umath import log10, exp2 +from . import umath + + +def _fr0(a): + """fix rank-0 --> rank-1""" + if a.ndim == 0: + a = a.copy() + a.shape = (1,) + return a + + +def _fr1(a): + """fix rank > 0 --> rank-0""" + if a.size == 1: + a = a.copy() + a.shape = () + return a + +class MachArLike: + """ Object to simulate MachAr instance """ + + def __init__(self, + ftype, + *, eps, epsneg, huge, tiny, ibeta, **kwargs): + params = _MACHAR_PARAMS[ftype] + float_conv = lambda v: array([v], ftype) + float_to_float = lambda v : _fr1(float_conv(v)) + float_to_str = lambda v: (params['fmt'] % array(_fr0(v)[0], ftype)) + + self.title = params['title'] + # Parameter types same as for discovered MachAr object. + self.epsilon = self.eps = float_to_float(eps) + self.epsneg = float_to_float(epsneg) + self.xmax = self.huge = float_to_float(huge) + self.xmin = self.tiny = float_to_float(tiny) + self.ibeta = params['itype'](ibeta) + self.__dict__.update(kwargs) + self.precision = int(-log10(self.eps)) + self.resolution = float_to_float(float_conv(10) ** (-self.precision)) + self._str_eps = float_to_str(self.eps) + self._str_epsneg = float_to_str(self.epsneg) + self._str_xmin = float_to_str(self.xmin) + self._str_xmax = float_to_str(self.xmax) + self._str_resolution = float_to_str(self.resolution) + +_convert_to_float = { + ntypes.csingle: ntypes.single, + ntypes.complex_: ntypes.float_, + ntypes.clongfloat: ntypes.longfloat + } + +# Parameters for creating MachAr / MachAr-like objects +_title_fmt = 'numpy {} precision floating point number' +_MACHAR_PARAMS = { + ntypes.double: dict( + itype = ntypes.int64, + fmt = '%24.16e', + title = _title_fmt.format('double')), + ntypes.single: dict( + itype = ntypes.int32, + fmt = '%15.7e', + title = _title_fmt.format('single')), + ntypes.longdouble: dict( + itype = ntypes.longlong, + fmt = '%s', + title = _title_fmt.format('long double')), + ntypes.half: dict( + itype = ntypes.int16, + fmt = '%12.5e', + title = _title_fmt.format('half'))} + +# Key to identify the floating point type. Key is result of +# ftype('-0.1').newbyteorder('<').tobytes() +# See: +# https://perl5.git.perl.org/perl.git/blob/3118d7d684b56cbeb702af874f4326683c45f045:/Configure +_KNOWN_TYPES = {} +def _register_type(machar, bytepat): + _KNOWN_TYPES[bytepat] = machar +_float_ma = {} + +def _register_known_types(): + # Known parameters for float16 + # See docstring of MachAr class for description of parameters. + f16 = ntypes.float16 + float16_ma = MachArLike(f16, + machep=-10, + negep=-11, + minexp=-14, + maxexp=16, + it=10, + iexp=5, + ibeta=2, + irnd=5, + ngrd=0, + eps=exp2(f16(-10)), + epsneg=exp2(f16(-11)), + huge=f16(65504), + tiny=f16(2 ** -14)) + _register_type(float16_ma, b'f\xae') + _float_ma[16] = float16_ma + + # Known parameters for float32 + f32 = ntypes.float32 + float32_ma = MachArLike(f32, + machep=-23, + negep=-24, + minexp=-126, + maxexp=128, + it=23, + iexp=8, + ibeta=2, + irnd=5, + ngrd=0, + eps=exp2(f32(-23)), + epsneg=exp2(f32(-24)), + huge=f32((1 - 2 ** -24) * 2**128), + tiny=exp2(f32(-126))) + _register_type(float32_ma, b'\xcd\xcc\xcc\xbd') + _float_ma[32] = float32_ma + + # Known parameters for float64 + f64 = ntypes.float64 + epsneg_f64 = 2.0 ** -53.0 + tiny_f64 = 2.0 ** -1022.0 + float64_ma = MachArLike(f64, + machep=-52, + negep=-53, + minexp=-1022, + maxexp=1024, + it=52, + iexp=11, + ibeta=2, + irnd=5, + ngrd=0, + eps=2.0 ** -52.0, + epsneg=epsneg_f64, + huge=(1.0 - epsneg_f64) / tiny_f64 * f64(4), + tiny=tiny_f64) + _register_type(float64_ma, b'\x9a\x99\x99\x99\x99\x99\xb9\xbf') + _float_ma[64] = float64_ma + + # Known parameters for IEEE 754 128-bit binary float + ld = ntypes.longdouble + epsneg_f128 = exp2(ld(-113)) + tiny_f128 = exp2(ld(-16382)) + # Ignore runtime error when this is not f128 + with numeric.errstate(all='ignore'): + huge_f128 = (ld(1) - epsneg_f128) / tiny_f128 * ld(4) + float128_ma = MachArLike(ld, + machep=-112, + negep=-113, + minexp=-16382, + maxexp=16384, + it=112, + iexp=15, + ibeta=2, + irnd=5, + ngrd=0, + eps=exp2(ld(-112)), + epsneg=epsneg_f128, + huge=huge_f128, + tiny=tiny_f128) + # IEEE 754 128-bit binary float + _register_type(float128_ma, + b'\x9a\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\xfb\xbf') + _register_type(float128_ma, + b'\x9a\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\xfb\xbf') + _float_ma[128] = float128_ma + + # Known parameters for float80 (Intel 80-bit extended precision) + epsneg_f80 = exp2(ld(-64)) + tiny_f80 = exp2(ld(-16382)) + # Ignore runtime error when this is not f80 + with numeric.errstate(all='ignore'): + huge_f80 = (ld(1) - epsneg_f80) / tiny_f80 * ld(4) + float80_ma = MachArLike(ld, + machep=-63, + negep=-64, + minexp=-16382, + maxexp=16384, + it=63, + iexp=15, + ibeta=2, + irnd=5, + ngrd=0, + eps=exp2(ld(-63)), + epsneg=epsneg_f80, + huge=huge_f80, + tiny=tiny_f80) + # float80, first 10 bytes containing actual storage + _register_type(float80_ma, b'\xcd\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xfb\xbf') + _float_ma[80] = float80_ma + + # Guessed / known parameters for double double; see: + # https://en.wikipedia.org/wiki/Quadruple-precision_floating-point_format#Double-double_arithmetic + # These numbers have the same exponent range as float64, but extended number of + # digits in the significand. + huge_dd = (umath.nextafter(ld(inf), ld(0)) + if hasattr(umath, 'nextafter') # Missing on some platforms? + else float64_ma.huge) + float_dd_ma = MachArLike(ld, + machep=-105, + negep=-106, + minexp=-1022, + maxexp=1024, + it=105, + iexp=11, + ibeta=2, + irnd=5, + ngrd=0, + eps=exp2(ld(-105)), + epsneg= exp2(ld(-106)), + huge=huge_dd, + tiny=exp2(ld(-1022))) + # double double; low, high order (e.g. PPC 64) + _register_type(float_dd_ma, + b'\x9a\x99\x99\x99\x99\x99Y<\x9a\x99\x99\x99\x99\x99\xb9\xbf') + # double double; high, low order (e.g. PPC 64 le) + _register_type(float_dd_ma, + b'\x9a\x99\x99\x99\x99\x99\xb9\xbf\x9a\x99\x99\x99\x99\x99Y<') + _float_ma['dd'] = float_dd_ma + + +def _get_machar(ftype): + """ Get MachAr instance or MachAr-like instance + + Get parameters for floating point type, by first trying signatures of + various known floating point types, then, if none match, attempting to + identify parameters by analysis. + + Parameters + ---------- + ftype : class + Numpy floating point type class (e.g. ``np.float64``) + + Returns + ------- + ma_like : instance of :class:`MachAr` or :class:`MachArLike` + Object giving floating point parameters for `ftype`. + + Warns + ----- + UserWarning + If the binary signature of the float type is not in the dictionary of + known float types. + """ + params = _MACHAR_PARAMS.get(ftype) + if params is None: + raise ValueError(repr(ftype)) + # Detect known / suspected types + key = ftype('-0.1').newbyteorder('<').tobytes() + ma_like = None + if ftype == ntypes.longdouble: + # Could be 80 bit == 10 byte extended precision, where last bytes can + # be random garbage. + # Comparing first 10 bytes to pattern first to avoid branching on the + # random garbage. + ma_like = _KNOWN_TYPES.get(key[:10]) + if ma_like is None: + ma_like = _KNOWN_TYPES.get(key) + if ma_like is not None: + return ma_like + # Fall back to parameter discovery + warnings.warn( + 'Signature {} for {} does not match any known type: ' + 'falling back to type probe function'.format(key, ftype), + UserWarning, stacklevel=2) + return _discovered_machar(ftype) + + +def _discovered_machar(ftype): + """ Create MachAr instance with found information on float types + """ + params = _MACHAR_PARAMS[ftype] + return MachAr(lambda v: array([v], ftype), + lambda v:_fr0(v.astype(params['itype']))[0], + lambda v:array(_fr0(v)[0], ftype), + lambda v: params['fmt'] % array(_fr0(v)[0], ftype), + params['title']) + + +@set_module('numpy') +class finfo: + """ + finfo(dtype) + + Machine limits for floating point types. + + Attributes + ---------- + bits : int + The number of bits occupied by the type. + eps : float + The difference between 1.0 and the next smallest representable float + larger than 1.0. For example, for 64-bit binary floats in the IEEE-754 + standard, ``eps = 2**-52``, approximately 2.22e-16. + epsneg : float + The difference between 1.0 and the next smallest representable float + less than 1.0. For example, for 64-bit binary floats in the IEEE-754 + standard, ``epsneg = 2**-53``, approximately 1.11e-16. + iexp : int + The number of bits in the exponent portion of the floating point + representation. + machar : MachAr + The object which calculated these parameters and holds more + detailed information. + machep : int + The exponent that yields `eps`. + max : floating point number of the appropriate type + The largest representable number. + maxexp : int + The smallest positive power of the base (2) that causes overflow. + min : floating point number of the appropriate type + The smallest representable number, typically ``-max``. + minexp : int + The most negative power of the base (2) consistent with there + being no leading 0's in the mantissa. + negep : int + The exponent that yields `epsneg`. + nexp : int + The number of bits in the exponent including its sign and bias. + nmant : int + The number of bits in the mantissa. + precision : int + The approximate number of decimal digits to which this kind of + float is precise. + resolution : floating point number of the appropriate type + The approximate decimal resolution of this type, i.e., + ``10**-precision``. + tiny : float + The smallest positive floating point number with full precision + (see Notes). + + Parameters + ---------- + dtype : float, dtype, or instance + Kind of floating point data-type about which to get information. + + See Also + -------- + MachAr : The implementation of the tests that produce this information. + iinfo : The equivalent for integer data types. + spacing : The distance between a value and the nearest adjacent number + nextafter : The next floating point value after x1 towards x2 + + Notes + ----- + For developers of NumPy: do not instantiate this at the module level. + The initial calculation of these parameters is expensive and negatively + impacts import times. These objects are cached, so calling ``finfo()`` + repeatedly inside your functions is not a problem. + + Note that ``tiny`` is not actually the smallest positive representable + value in a NumPy floating point type. As in the IEEE-754 standard [1]_, + NumPy floating point types make use of subnormal numbers to fill the + gap between 0 and ``tiny``. However, subnormal numbers may have + significantly reduced precision [2]_. + + References + ---------- + .. [1] IEEE Standard for Floating-Point Arithmetic, IEEE Std 754-2008, + pp.1-70, 2008, http://www.doi.org/10.1109/IEEESTD.2008.4610935 + .. [2] Wikipedia, "Denormal Numbers", + https://en.wikipedia.org/wiki/Denormal_number + """ + + _finfo_cache = {} + + def __new__(cls, dtype): + try: + dtype = numeric.dtype(dtype) + except TypeError: + # In case a float instance was given + dtype = numeric.dtype(type(dtype)) + + obj = cls._finfo_cache.get(dtype, None) + if obj is not None: + return obj + dtypes = [dtype] + newdtype = numeric.obj2sctype(dtype) + if newdtype is not dtype: + dtypes.append(newdtype) + dtype = newdtype + if not issubclass(dtype, numeric.inexact): + raise ValueError("data type %r not inexact" % (dtype)) + obj = cls._finfo_cache.get(dtype, None) + if obj is not None: + return obj + if not issubclass(dtype, numeric.floating): + newdtype = _convert_to_float[dtype] + if newdtype is not dtype: + dtypes.append(newdtype) + dtype = newdtype + obj = cls._finfo_cache.get(dtype, None) + if obj is not None: + return obj + obj = object.__new__(cls)._init(dtype) + for dt in dtypes: + cls._finfo_cache[dt] = obj + return obj + + def _init(self, dtype): + self.dtype = numeric.dtype(dtype) + machar = _get_machar(dtype) + + for word in ['precision', 'iexp', + 'maxexp', 'minexp', 'negep', + 'machep']: + setattr(self, word, getattr(machar, word)) + for word in ['tiny', 'resolution', 'epsneg']: + setattr(self, word, getattr(machar, word).flat[0]) + self.bits = self.dtype.itemsize * 8 + self.max = machar.huge.flat[0] + self.min = -self.max + self.eps = machar.eps.flat[0] + self.nexp = machar.iexp + self.nmant = machar.it + self.machar = machar + self._str_tiny = machar._str_xmin.strip() + self._str_max = machar._str_xmax.strip() + self._str_epsneg = machar._str_epsneg.strip() + self._str_eps = machar._str_eps.strip() + self._str_resolution = machar._str_resolution.strip() + return self + + def __str__(self): + fmt = ( + 'Machine parameters for %(dtype)s\n' + '---------------------------------------------------------------\n' + 'precision = %(precision)3s resolution = %(_str_resolution)s\n' + 'machep = %(machep)6s eps = %(_str_eps)s\n' + 'negep = %(negep)6s epsneg = %(_str_epsneg)s\n' + 'minexp = %(minexp)6s tiny = %(_str_tiny)s\n' + 'maxexp = %(maxexp)6s max = %(_str_max)s\n' + 'nexp = %(nexp)6s min = -max\n' + '---------------------------------------------------------------\n' + ) + return fmt % self.__dict__ + + def __repr__(self): + c = self.__class__.__name__ + d = self.__dict__.copy() + d['klass'] = c + return (("%(klass)s(resolution=%(resolution)s, min=-%(_str_max)s," + " max=%(_str_max)s, dtype=%(dtype)s)") % d) + + +@set_module('numpy') +class iinfo: + """ + iinfo(type) + + Machine limits for integer types. + + Attributes + ---------- + bits : int + The number of bits occupied by the type. + min : int + The smallest integer expressible by the type. + max : int + The largest integer expressible by the type. + + Parameters + ---------- + int_type : integer type, dtype, or instance + The kind of integer data type to get information about. + + See Also + -------- + finfo : The equivalent for floating point data types. + + Examples + -------- + With types: + + >>> ii16 = np.iinfo(np.int16) + >>> ii16.min + -32768 + >>> ii16.max + 32767 + >>> ii32 = np.iinfo(np.int32) + >>> ii32.min + -2147483648 + >>> ii32.max + 2147483647 + + With instances: + + >>> ii32 = np.iinfo(np.int32(10)) + >>> ii32.min + -2147483648 + >>> ii32.max + 2147483647 + + """ + + _min_vals = {} + _max_vals = {} + + def __init__(self, int_type): + try: + self.dtype = numeric.dtype(int_type) + except TypeError: + self.dtype = numeric.dtype(type(int_type)) + self.kind = self.dtype.kind + self.bits = self.dtype.itemsize * 8 + self.key = "%s%d" % (self.kind, self.bits) + if self.kind not in 'iu': + raise ValueError("Invalid integer data type %r." % (self.kind,)) + + @property + def min(self): + """Minimum value of given dtype.""" + if self.kind == 'u': + return 0 + else: + try: + val = iinfo._min_vals[self.key] + except KeyError: + val = int(-(1 << (self.bits-1))) + iinfo._min_vals[self.key] = val + return val + + @property + def max(self): + """Maximum value of given dtype.""" + try: + val = iinfo._max_vals[self.key] + except KeyError: + if self.kind == 'u': + val = int((1 << self.bits) - 1) + else: + val = int((1 << (self.bits-1)) - 1) + iinfo._max_vals[self.key] = val + return val + + def __str__(self): + """String representation.""" + fmt = ( + 'Machine parameters for %(dtype)s\n' + '---------------------------------------------------------------\n' + 'min = %(min)s\n' + 'max = %(max)s\n' + '---------------------------------------------------------------\n' + ) + return fmt % {'dtype': self.dtype, 'min': self.min, 'max': self.max} + + def __repr__(self): + return "%s(min=%s, max=%s, dtype=%s)" % (self.__class__.__name__, + self.min, self.max, self.dtype) diff --git a/venv/Lib/site-packages/numpy/core/include/numpy/__multiarray_api.h b/venv/Lib/site-packages/numpy/core/include/numpy/__multiarray_api.h new file mode 100644 index 0000000..0d06c9a --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/include/numpy/__multiarray_api.h @@ -0,0 +1,1540 @@ + +#if defined(_MULTIARRAYMODULE) || defined(WITH_CPYCHECKER_STEALS_REFERENCE_TO_ARG_ATTRIBUTE) + +typedef struct { + PyObject_HEAD + npy_bool obval; +} PyBoolScalarObject; + +extern NPY_NO_EXPORT PyTypeObject PyArrayMapIter_Type; +extern NPY_NO_EXPORT PyTypeObject PyArrayNeighborhoodIter_Type; +extern NPY_NO_EXPORT PyBoolScalarObject _PyArrayScalar_BoolValues[2]; + +NPY_NO_EXPORT unsigned int PyArray_GetNDArrayCVersion \ + (void); +extern NPY_NO_EXPORT PyTypeObject PyBigArray_Type; + +extern NPY_NO_EXPORT PyTypeObject PyArray_Type; + +extern NPY_NO_EXPORT PyArray_DTypeMeta PyArrayDescr_TypeFull; +#define PyArrayDescr_Type (*(PyTypeObject *)(&PyArrayDescr_TypeFull)) + +extern NPY_NO_EXPORT PyTypeObject PyArrayFlags_Type; + +extern NPY_NO_EXPORT PyTypeObject PyArrayIter_Type; + +extern NPY_NO_EXPORT PyTypeObject PyArrayMultiIter_Type; + +extern NPY_NO_EXPORT int NPY_NUMUSERTYPES; + +extern NPY_NO_EXPORT PyTypeObject PyBoolArrType_Type; + +extern NPY_NO_EXPORT PyBoolScalarObject _PyArrayScalar_BoolValues[2]; + +extern NPY_NO_EXPORT PyTypeObject PyGenericArrType_Type; + +extern NPY_NO_EXPORT PyTypeObject PyNumberArrType_Type; + +extern NPY_NO_EXPORT PyTypeObject PyIntegerArrType_Type; + +extern NPY_NO_EXPORT PyTypeObject PySignedIntegerArrType_Type; + +extern NPY_NO_EXPORT PyTypeObject PyUnsignedIntegerArrType_Type; + +extern NPY_NO_EXPORT PyTypeObject PyInexactArrType_Type; + +extern NPY_NO_EXPORT PyTypeObject PyFloatingArrType_Type; + +extern NPY_NO_EXPORT PyTypeObject PyComplexFloatingArrType_Type; + +extern NPY_NO_EXPORT PyTypeObject PyFlexibleArrType_Type; + +extern NPY_NO_EXPORT PyTypeObject PyCharacterArrType_Type; + +extern NPY_NO_EXPORT PyTypeObject PyByteArrType_Type; + +extern NPY_NO_EXPORT PyTypeObject PyShortArrType_Type; + +extern NPY_NO_EXPORT PyTypeObject PyIntArrType_Type; + +extern NPY_NO_EXPORT PyTypeObject PyLongArrType_Type; + +extern NPY_NO_EXPORT PyTypeObject PyLongLongArrType_Type; + +extern NPY_NO_EXPORT PyTypeObject PyUByteArrType_Type; + +extern NPY_NO_EXPORT PyTypeObject PyUShortArrType_Type; + +extern NPY_NO_EXPORT PyTypeObject PyUIntArrType_Type; + +extern NPY_NO_EXPORT PyTypeObject PyULongArrType_Type; + +extern NPY_NO_EXPORT PyTypeObject PyULongLongArrType_Type; + +extern NPY_NO_EXPORT PyTypeObject PyFloatArrType_Type; + +extern NPY_NO_EXPORT PyTypeObject PyDoubleArrType_Type; + +extern NPY_NO_EXPORT PyTypeObject PyLongDoubleArrType_Type; + +extern NPY_NO_EXPORT PyTypeObject PyCFloatArrType_Type; + +extern NPY_NO_EXPORT PyTypeObject PyCDoubleArrType_Type; + +extern NPY_NO_EXPORT PyTypeObject PyCLongDoubleArrType_Type; + +extern NPY_NO_EXPORT PyTypeObject PyObjectArrType_Type; + +extern NPY_NO_EXPORT PyTypeObject PyStringArrType_Type; + +extern NPY_NO_EXPORT PyTypeObject PyUnicodeArrType_Type; + +extern NPY_NO_EXPORT PyTypeObject PyVoidArrType_Type; + +NPY_NO_EXPORT int PyArray_SetNumericOps \ + (PyObject *); +NPY_NO_EXPORT PyObject * PyArray_GetNumericOps \ + (void); +NPY_NO_EXPORT int PyArray_INCREF \ + (PyArrayObject *); +NPY_NO_EXPORT int PyArray_XDECREF \ + (PyArrayObject *); +NPY_NO_EXPORT void PyArray_SetStringFunction \ + (PyObject *, int); +NPY_NO_EXPORT PyArray_Descr * PyArray_DescrFromType \ + (int); +NPY_NO_EXPORT PyObject * PyArray_TypeObjectFromType \ + (int); +NPY_NO_EXPORT char * PyArray_Zero \ + (PyArrayObject *); +NPY_NO_EXPORT char * PyArray_One \ + (PyArrayObject *); +NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(2) NPY_GCC_NONNULL(2) PyObject * PyArray_CastToType \ + (PyArrayObject *, PyArray_Descr *, int); +NPY_NO_EXPORT int PyArray_CastTo \ + (PyArrayObject *, PyArrayObject *); +NPY_NO_EXPORT int PyArray_CastAnyTo \ + (PyArrayObject *, PyArrayObject *); +NPY_NO_EXPORT int PyArray_CanCastSafely \ + (int, int); +NPY_NO_EXPORT npy_bool PyArray_CanCastTo \ + (PyArray_Descr *, PyArray_Descr *); +NPY_NO_EXPORT int PyArray_ObjectType \ + (PyObject *, int); +NPY_NO_EXPORT PyArray_Descr * PyArray_DescrFromObject \ + (PyObject *, PyArray_Descr *); +NPY_NO_EXPORT PyArrayObject ** PyArray_ConvertToCommonType \ + (PyObject *, int *); +NPY_NO_EXPORT PyArray_Descr * PyArray_DescrFromScalar \ + (PyObject *); +NPY_NO_EXPORT PyArray_Descr * PyArray_DescrFromTypeObject \ + (PyObject *); +NPY_NO_EXPORT npy_intp PyArray_Size \ + (PyObject *); +NPY_NO_EXPORT PyObject * PyArray_Scalar \ + (void *, PyArray_Descr *, PyObject *); +NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(2) PyObject * PyArray_FromScalar \ + (PyObject *, PyArray_Descr *); +NPY_NO_EXPORT void PyArray_ScalarAsCtype \ + (PyObject *, void *); +NPY_NO_EXPORT int PyArray_CastScalarToCtype \ + (PyObject *, void *, PyArray_Descr *); +NPY_NO_EXPORT int PyArray_CastScalarDirect \ + (PyObject *, PyArray_Descr *, void *, int); +NPY_NO_EXPORT PyObject * PyArray_ScalarFromObject \ + (PyObject *); +NPY_NO_EXPORT PyArray_VectorUnaryFunc * PyArray_GetCastFunc \ + (PyArray_Descr *, int); +NPY_NO_EXPORT PyObject * PyArray_FromDims \ + (int NPY_UNUSED(nd), int *NPY_UNUSED(d), int NPY_UNUSED(type)); +NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(3) PyObject * PyArray_FromDimsAndDataAndDescr \ + (int NPY_UNUSED(nd), int *NPY_UNUSED(d), PyArray_Descr *, char *NPY_UNUSED(data)); +NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(2) PyObject * PyArray_FromAny \ + (PyObject *, PyArray_Descr *, int, int, int, PyObject *); +NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(1) PyObject * PyArray_EnsureArray \ + (PyObject *); +NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(1) PyObject * PyArray_EnsureAnyArray \ + (PyObject *); +NPY_NO_EXPORT PyObject * PyArray_FromFile \ + (FILE *, PyArray_Descr *, npy_intp, char *); +NPY_NO_EXPORT PyObject * PyArray_FromString \ + (char *, npy_intp, PyArray_Descr *, npy_intp, char *); +NPY_NO_EXPORT PyObject * PyArray_FromBuffer \ + (PyObject *, PyArray_Descr *, npy_intp, npy_intp); +NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(2) PyObject * PyArray_FromIter \ + (PyObject *, PyArray_Descr *, npy_intp); +NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(1) PyObject * PyArray_Return \ + (PyArrayObject *); +NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(2) NPY_GCC_NONNULL(2) PyObject * PyArray_GetField \ + (PyArrayObject *, PyArray_Descr *, int); +NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(2) NPY_GCC_NONNULL(2) int PyArray_SetField \ + (PyArrayObject *, PyArray_Descr *, int, PyObject *); +NPY_NO_EXPORT PyObject * PyArray_Byteswap \ + (PyArrayObject *, npy_bool); +NPY_NO_EXPORT PyObject * PyArray_Resize \ + (PyArrayObject *, PyArray_Dims *, int, NPY_ORDER NPY_UNUSED(order)); +NPY_NO_EXPORT int PyArray_MoveInto \ + (PyArrayObject *, PyArrayObject *); +NPY_NO_EXPORT int PyArray_CopyInto \ + (PyArrayObject *, PyArrayObject *); +NPY_NO_EXPORT int PyArray_CopyAnyInto \ + (PyArrayObject *, PyArrayObject *); +NPY_NO_EXPORT int PyArray_CopyObject \ + (PyArrayObject *, PyObject *); +NPY_NO_EXPORT NPY_GCC_NONNULL(1) PyObject * PyArray_NewCopy \ + (PyArrayObject *, NPY_ORDER); +NPY_NO_EXPORT PyObject * PyArray_ToList \ + (PyArrayObject *); +NPY_NO_EXPORT PyObject * PyArray_ToString \ + (PyArrayObject *, NPY_ORDER); +NPY_NO_EXPORT int PyArray_ToFile \ + (PyArrayObject *, FILE *, char *, char *); +NPY_NO_EXPORT int PyArray_Dump \ + (PyObject *, PyObject *, int); +NPY_NO_EXPORT PyObject * PyArray_Dumps \ + (PyObject *, int); +NPY_NO_EXPORT int PyArray_ValidType \ + (int); +NPY_NO_EXPORT void PyArray_UpdateFlags \ + (PyArrayObject *, int); +NPY_NO_EXPORT NPY_GCC_NONNULL(1) PyObject * PyArray_New \ + (PyTypeObject *, int, npy_intp const *, int, npy_intp const *, void *, int, int, PyObject *); +NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(2) NPY_GCC_NONNULL(1) NPY_GCC_NONNULL(2) PyObject * PyArray_NewFromDescr \ + (PyTypeObject *, PyArray_Descr *, int, npy_intp const *, npy_intp const *, void *, int, PyObject *); +NPY_NO_EXPORT PyArray_Descr * PyArray_DescrNew \ + (PyArray_Descr *); +NPY_NO_EXPORT PyArray_Descr * PyArray_DescrNewFromType \ + (int); +NPY_NO_EXPORT double PyArray_GetPriority \ + (PyObject *, double); +NPY_NO_EXPORT PyObject * PyArray_IterNew \ + (PyObject *); +NPY_NO_EXPORT PyObject* PyArray_MultiIterNew \ + (int, ...); +NPY_NO_EXPORT int PyArray_PyIntAsInt \ + (PyObject *); +NPY_NO_EXPORT npy_intp PyArray_PyIntAsIntp \ + (PyObject *); +NPY_NO_EXPORT int PyArray_Broadcast \ + (PyArrayMultiIterObject *); +NPY_NO_EXPORT void PyArray_FillObjectArray \ + (PyArrayObject *, PyObject *); +NPY_NO_EXPORT int PyArray_FillWithScalar \ + (PyArrayObject *, PyObject *); +NPY_NO_EXPORT npy_bool PyArray_CheckStrides \ + (int, int, npy_intp, npy_intp, npy_intp const *, npy_intp const *); +NPY_NO_EXPORT PyArray_Descr * PyArray_DescrNewByteorder \ + (PyArray_Descr *, char); +NPY_NO_EXPORT PyObject * PyArray_IterAllButAxis \ + (PyObject *, int *); +NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(2) PyObject * PyArray_CheckFromAny \ + (PyObject *, PyArray_Descr *, int, int, int, PyObject *); +NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(2) PyObject * PyArray_FromArray \ + (PyArrayObject *, PyArray_Descr *, int); +NPY_NO_EXPORT PyObject * PyArray_FromInterface \ + (PyObject *); +NPY_NO_EXPORT PyObject * PyArray_FromStructInterface \ + (PyObject *); +NPY_NO_EXPORT PyObject * PyArray_FromArrayAttr \ + (PyObject *, PyArray_Descr *, PyObject *); +NPY_NO_EXPORT NPY_SCALARKIND PyArray_ScalarKind \ + (int, PyArrayObject **); +NPY_NO_EXPORT int PyArray_CanCoerceScalar \ + (int, int, NPY_SCALARKIND); +NPY_NO_EXPORT PyObject * PyArray_NewFlagsObject \ + (PyObject *); +NPY_NO_EXPORT npy_bool PyArray_CanCastScalar \ + (PyTypeObject *, PyTypeObject *); +NPY_NO_EXPORT int PyArray_CompareUCS4 \ + (npy_ucs4 const *, npy_ucs4 const *, size_t); +NPY_NO_EXPORT int PyArray_RemoveSmallest \ + (PyArrayMultiIterObject *); +NPY_NO_EXPORT int PyArray_ElementStrides \ + (PyObject *); +NPY_NO_EXPORT void PyArray_Item_INCREF \ + (char *, PyArray_Descr *); +NPY_NO_EXPORT void PyArray_Item_XDECREF \ + (char *, PyArray_Descr *); +NPY_NO_EXPORT PyObject * PyArray_FieldNames \ + (PyObject *); +NPY_NO_EXPORT PyObject * PyArray_Transpose \ + (PyArrayObject *, PyArray_Dims *); +NPY_NO_EXPORT PyObject * PyArray_TakeFrom \ + (PyArrayObject *, PyObject *, int, PyArrayObject *, NPY_CLIPMODE); +NPY_NO_EXPORT PyObject * PyArray_PutTo \ + (PyArrayObject *, PyObject*, PyObject *, NPY_CLIPMODE); +NPY_NO_EXPORT PyObject * PyArray_PutMask \ + (PyArrayObject *, PyObject*, PyObject*); +NPY_NO_EXPORT PyObject * PyArray_Repeat \ + (PyArrayObject *, PyObject *, int); +NPY_NO_EXPORT PyObject * PyArray_Choose \ + (PyArrayObject *, PyObject *, PyArrayObject *, NPY_CLIPMODE); +NPY_NO_EXPORT int PyArray_Sort \ + (PyArrayObject *, int, NPY_SORTKIND); +NPY_NO_EXPORT PyObject * PyArray_ArgSort \ + (PyArrayObject *, int, NPY_SORTKIND); +NPY_NO_EXPORT PyObject * PyArray_SearchSorted \ + (PyArrayObject *, PyObject *, NPY_SEARCHSIDE, PyObject *); +NPY_NO_EXPORT PyObject * PyArray_ArgMax \ + (PyArrayObject *, int, PyArrayObject *); +NPY_NO_EXPORT PyObject * PyArray_ArgMin \ + (PyArrayObject *, int, PyArrayObject *); +NPY_NO_EXPORT PyObject * PyArray_Reshape \ + (PyArrayObject *, PyObject *); +NPY_NO_EXPORT PyObject * PyArray_Newshape \ + (PyArrayObject *, PyArray_Dims *, NPY_ORDER); +NPY_NO_EXPORT PyObject * PyArray_Squeeze \ + (PyArrayObject *); +NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(2) PyObject * PyArray_View \ + (PyArrayObject *, PyArray_Descr *, PyTypeObject *); +NPY_NO_EXPORT PyObject * PyArray_SwapAxes \ + (PyArrayObject *, int, int); +NPY_NO_EXPORT PyObject * PyArray_Max \ + (PyArrayObject *, int, PyArrayObject *); +NPY_NO_EXPORT PyObject * PyArray_Min \ + (PyArrayObject *, int, PyArrayObject *); +NPY_NO_EXPORT PyObject * PyArray_Ptp \ + (PyArrayObject *, int, PyArrayObject *); +NPY_NO_EXPORT PyObject * PyArray_Mean \ + (PyArrayObject *, int, int, PyArrayObject *); +NPY_NO_EXPORT PyObject * PyArray_Trace \ + (PyArrayObject *, int, int, int, int, PyArrayObject *); +NPY_NO_EXPORT PyObject * PyArray_Diagonal \ + (PyArrayObject *, int, int, int); +NPY_NO_EXPORT PyObject * PyArray_Clip \ + (PyArrayObject *, PyObject *, PyObject *, PyArrayObject *); +NPY_NO_EXPORT PyObject * PyArray_Conjugate \ + (PyArrayObject *, PyArrayObject *); +NPY_NO_EXPORT PyObject * PyArray_Nonzero \ + (PyArrayObject *); +NPY_NO_EXPORT PyObject * PyArray_Std \ + (PyArrayObject *, int, int, PyArrayObject *, int); +NPY_NO_EXPORT PyObject * PyArray_Sum \ + (PyArrayObject *, int, int, PyArrayObject *); +NPY_NO_EXPORT PyObject * PyArray_CumSum \ + (PyArrayObject *, int, int, PyArrayObject *); +NPY_NO_EXPORT PyObject * PyArray_Prod \ + (PyArrayObject *, int, int, PyArrayObject *); +NPY_NO_EXPORT PyObject * PyArray_CumProd \ + (PyArrayObject *, int, int, PyArrayObject *); +NPY_NO_EXPORT PyObject * PyArray_All \ + (PyArrayObject *, int, PyArrayObject *); +NPY_NO_EXPORT PyObject * PyArray_Any \ + (PyArrayObject *, int, PyArrayObject *); +NPY_NO_EXPORT PyObject * PyArray_Compress \ + (PyArrayObject *, PyObject *, int, PyArrayObject *); +NPY_NO_EXPORT PyObject * PyArray_Flatten \ + (PyArrayObject *, NPY_ORDER); +NPY_NO_EXPORT PyObject * PyArray_Ravel \ + (PyArrayObject *, NPY_ORDER); +NPY_NO_EXPORT npy_intp PyArray_MultiplyList \ + (npy_intp const *, int); +NPY_NO_EXPORT int PyArray_MultiplyIntList \ + (int const *, int); +NPY_NO_EXPORT void * PyArray_GetPtr \ + (PyArrayObject *, npy_intp const*); +NPY_NO_EXPORT int PyArray_CompareLists \ + (npy_intp const *, npy_intp const *, int); +NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(5) int PyArray_AsCArray \ + (PyObject **, void *, npy_intp *, int, PyArray_Descr*); +NPY_NO_EXPORT int PyArray_As1D \ + (PyObject **NPY_UNUSED(op), char **NPY_UNUSED(ptr), int *NPY_UNUSED(d1), int NPY_UNUSED(typecode)); +NPY_NO_EXPORT int PyArray_As2D \ + (PyObject **NPY_UNUSED(op), char ***NPY_UNUSED(ptr), int *NPY_UNUSED(d1), int *NPY_UNUSED(d2), int NPY_UNUSED(typecode)); +NPY_NO_EXPORT int PyArray_Free \ + (PyObject *, void *); +NPY_NO_EXPORT int PyArray_Converter \ + (PyObject *, PyObject **); +NPY_NO_EXPORT int PyArray_IntpFromSequence \ + (PyObject *, npy_intp *, int); +NPY_NO_EXPORT PyObject * PyArray_Concatenate \ + (PyObject *, int); +NPY_NO_EXPORT PyObject * PyArray_InnerProduct \ + (PyObject *, PyObject *); +NPY_NO_EXPORT PyObject * PyArray_MatrixProduct \ + (PyObject *, PyObject *); +NPY_NO_EXPORT PyObject * PyArray_CopyAndTranspose \ + (PyObject *); +NPY_NO_EXPORT PyObject * PyArray_Correlate \ + (PyObject *, PyObject *, int); +NPY_NO_EXPORT int PyArray_TypestrConvert \ + (int, int); +NPY_NO_EXPORT int PyArray_DescrConverter \ + (PyObject *, PyArray_Descr **); +NPY_NO_EXPORT int PyArray_DescrConverter2 \ + (PyObject *, PyArray_Descr **); +NPY_NO_EXPORT int PyArray_IntpConverter \ + (PyObject *, PyArray_Dims *); +NPY_NO_EXPORT int PyArray_BufferConverter \ + (PyObject *, PyArray_Chunk *); +NPY_NO_EXPORT int PyArray_AxisConverter \ + (PyObject *, int *); +NPY_NO_EXPORT int PyArray_BoolConverter \ + (PyObject *, npy_bool *); +NPY_NO_EXPORT int PyArray_ByteorderConverter \ + (PyObject *, char *); +NPY_NO_EXPORT int PyArray_OrderConverter \ + (PyObject *, NPY_ORDER *); +NPY_NO_EXPORT unsigned char PyArray_EquivTypes \ + (PyArray_Descr *, PyArray_Descr *); +NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(3) PyObject * PyArray_Zeros \ + (int, npy_intp const *, PyArray_Descr *, int); +NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(3) PyObject * PyArray_Empty \ + (int, npy_intp const *, PyArray_Descr *, int); +NPY_NO_EXPORT PyObject * PyArray_Where \ + (PyObject *, PyObject *, PyObject *); +NPY_NO_EXPORT PyObject * PyArray_Arange \ + (double, double, double, int); +NPY_NO_EXPORT PyObject * PyArray_ArangeObj \ + (PyObject *, PyObject *, PyObject *, PyArray_Descr *); +NPY_NO_EXPORT int PyArray_SortkindConverter \ + (PyObject *, NPY_SORTKIND *); +NPY_NO_EXPORT PyObject * PyArray_LexSort \ + (PyObject *, int); +NPY_NO_EXPORT PyObject * PyArray_Round \ + (PyArrayObject *, int, PyArrayObject *); +NPY_NO_EXPORT unsigned char PyArray_EquivTypenums \ + (int, int); +NPY_NO_EXPORT int PyArray_RegisterDataType \ + (PyArray_Descr *); +NPY_NO_EXPORT int PyArray_RegisterCastFunc \ + (PyArray_Descr *, int, PyArray_VectorUnaryFunc *); +NPY_NO_EXPORT int PyArray_RegisterCanCast \ + (PyArray_Descr *, int, NPY_SCALARKIND); +NPY_NO_EXPORT void PyArray_InitArrFuncs \ + (PyArray_ArrFuncs *); +NPY_NO_EXPORT PyObject * PyArray_IntTupleFromIntp \ + (int, npy_intp const *); +NPY_NO_EXPORT int PyArray_TypeNumFromName \ + (char const *); +NPY_NO_EXPORT int PyArray_ClipmodeConverter \ + (PyObject *, NPY_CLIPMODE *); +NPY_NO_EXPORT int PyArray_OutputConverter \ + (PyObject *, PyArrayObject **); +NPY_NO_EXPORT PyObject * PyArray_BroadcastToShape \ + (PyObject *, npy_intp *, int); +NPY_NO_EXPORT void _PyArray_SigintHandler \ + (int); +NPY_NO_EXPORT void* _PyArray_GetSigintBuf \ + (void); +NPY_NO_EXPORT int PyArray_DescrAlignConverter \ + (PyObject *, PyArray_Descr **); +NPY_NO_EXPORT int PyArray_DescrAlignConverter2 \ + (PyObject *, PyArray_Descr **); +NPY_NO_EXPORT int PyArray_SearchsideConverter \ + (PyObject *, void *); +NPY_NO_EXPORT PyObject * PyArray_CheckAxis \ + (PyArrayObject *, int *, int); +NPY_NO_EXPORT npy_intp PyArray_OverflowMultiplyList \ + (npy_intp const *, int); +NPY_NO_EXPORT int PyArray_CompareString \ + (const char *, const char *, size_t); +NPY_NO_EXPORT PyObject* PyArray_MultiIterFromObjects \ + (PyObject **, int, int, ...); +NPY_NO_EXPORT int PyArray_GetEndianness \ + (void); +NPY_NO_EXPORT unsigned int PyArray_GetNDArrayCFeatureVersion \ + (void); +NPY_NO_EXPORT PyObject * PyArray_Correlate2 \ + (PyObject *, PyObject *, int); +NPY_NO_EXPORT PyObject* PyArray_NeighborhoodIterNew \ + (PyArrayIterObject *, const npy_intp *, int, PyArrayObject*); +extern NPY_NO_EXPORT PyTypeObject PyTimeIntegerArrType_Type; + +extern NPY_NO_EXPORT PyTypeObject PyDatetimeArrType_Type; + +extern NPY_NO_EXPORT PyTypeObject PyTimedeltaArrType_Type; + +extern NPY_NO_EXPORT PyTypeObject PyHalfArrType_Type; + +extern NPY_NO_EXPORT PyTypeObject NpyIter_Type; + +NPY_NO_EXPORT void PyArray_SetDatetimeParseFunction \ + (PyObject *NPY_UNUSED(op)); +NPY_NO_EXPORT void PyArray_DatetimeToDatetimeStruct \ + (npy_datetime NPY_UNUSED(val), NPY_DATETIMEUNIT NPY_UNUSED(fr), npy_datetimestruct *); +NPY_NO_EXPORT void PyArray_TimedeltaToTimedeltaStruct \ + (npy_timedelta NPY_UNUSED(val), NPY_DATETIMEUNIT NPY_UNUSED(fr), npy_timedeltastruct *); +NPY_NO_EXPORT npy_datetime PyArray_DatetimeStructToDatetime \ + (NPY_DATETIMEUNIT NPY_UNUSED(fr), npy_datetimestruct *NPY_UNUSED(d)); +NPY_NO_EXPORT npy_datetime PyArray_TimedeltaStructToTimedelta \ + (NPY_DATETIMEUNIT NPY_UNUSED(fr), npy_timedeltastruct *NPY_UNUSED(d)); +NPY_NO_EXPORT NpyIter * NpyIter_New \ + (PyArrayObject *, npy_uint32, NPY_ORDER, NPY_CASTING, PyArray_Descr*); +NPY_NO_EXPORT NpyIter * NpyIter_MultiNew \ + (int, PyArrayObject **, npy_uint32, NPY_ORDER, NPY_CASTING, npy_uint32 *, PyArray_Descr **); +NPY_NO_EXPORT NpyIter * NpyIter_AdvancedNew \ + (int, PyArrayObject **, npy_uint32, NPY_ORDER, NPY_CASTING, npy_uint32 *, PyArray_Descr **, int, int **, npy_intp *, npy_intp); +NPY_NO_EXPORT NpyIter * NpyIter_Copy \ + (NpyIter *); +NPY_NO_EXPORT int NpyIter_Deallocate \ + (NpyIter *); +NPY_NO_EXPORT npy_bool NpyIter_HasDelayedBufAlloc \ + (NpyIter *); +NPY_NO_EXPORT npy_bool NpyIter_HasExternalLoop \ + (NpyIter *); +NPY_NO_EXPORT int NpyIter_EnableExternalLoop \ + (NpyIter *); +NPY_NO_EXPORT npy_intp * NpyIter_GetInnerStrideArray \ + (NpyIter *); +NPY_NO_EXPORT npy_intp * NpyIter_GetInnerLoopSizePtr \ + (NpyIter *); +NPY_NO_EXPORT int NpyIter_Reset \ + (NpyIter *, char **); +NPY_NO_EXPORT int NpyIter_ResetBasePointers \ + (NpyIter *, char **, char **); +NPY_NO_EXPORT int NpyIter_ResetToIterIndexRange \ + (NpyIter *, npy_intp, npy_intp, char **); +NPY_NO_EXPORT int NpyIter_GetNDim \ + (NpyIter *); +NPY_NO_EXPORT int NpyIter_GetNOp \ + (NpyIter *); +NPY_NO_EXPORT NpyIter_IterNextFunc * NpyIter_GetIterNext \ + (NpyIter *, char **); +NPY_NO_EXPORT npy_intp NpyIter_GetIterSize \ + (NpyIter *); +NPY_NO_EXPORT void NpyIter_GetIterIndexRange \ + (NpyIter *, npy_intp *, npy_intp *); +NPY_NO_EXPORT npy_intp NpyIter_GetIterIndex \ + (NpyIter *); +NPY_NO_EXPORT int NpyIter_GotoIterIndex \ + (NpyIter *, npy_intp); +NPY_NO_EXPORT npy_bool NpyIter_HasMultiIndex \ + (NpyIter *); +NPY_NO_EXPORT int NpyIter_GetShape \ + (NpyIter *, npy_intp *); +NPY_NO_EXPORT NpyIter_GetMultiIndexFunc * NpyIter_GetGetMultiIndex \ + (NpyIter *, char **); +NPY_NO_EXPORT int NpyIter_GotoMultiIndex \ + (NpyIter *, npy_intp const *); +NPY_NO_EXPORT int NpyIter_RemoveMultiIndex \ + (NpyIter *); +NPY_NO_EXPORT npy_bool NpyIter_HasIndex \ + (NpyIter *); +NPY_NO_EXPORT npy_bool NpyIter_IsBuffered \ + (NpyIter *); +NPY_NO_EXPORT npy_bool NpyIter_IsGrowInner \ + (NpyIter *); +NPY_NO_EXPORT npy_intp NpyIter_GetBufferSize \ + (NpyIter *); +NPY_NO_EXPORT npy_intp * NpyIter_GetIndexPtr \ + (NpyIter *); +NPY_NO_EXPORT int NpyIter_GotoIndex \ + (NpyIter *, npy_intp); +NPY_NO_EXPORT char ** NpyIter_GetDataPtrArray \ + (NpyIter *); +NPY_NO_EXPORT PyArray_Descr ** NpyIter_GetDescrArray \ + (NpyIter *); +NPY_NO_EXPORT PyArrayObject ** NpyIter_GetOperandArray \ + (NpyIter *); +NPY_NO_EXPORT PyArrayObject * NpyIter_GetIterView \ + (NpyIter *, npy_intp); +NPY_NO_EXPORT void NpyIter_GetReadFlags \ + (NpyIter *, char *); +NPY_NO_EXPORT void NpyIter_GetWriteFlags \ + (NpyIter *, char *); +NPY_NO_EXPORT void NpyIter_DebugPrint \ + (NpyIter *); +NPY_NO_EXPORT npy_bool NpyIter_IterationNeedsAPI \ + (NpyIter *); +NPY_NO_EXPORT void NpyIter_GetInnerFixedStrideArray \ + (NpyIter *, npy_intp *); +NPY_NO_EXPORT int NpyIter_RemoveAxis \ + (NpyIter *, int); +NPY_NO_EXPORT npy_intp * NpyIter_GetAxisStrideArray \ + (NpyIter *, int); +NPY_NO_EXPORT npy_bool NpyIter_RequiresBuffering \ + (NpyIter *); +NPY_NO_EXPORT char ** NpyIter_GetInitialDataPtrArray \ + (NpyIter *); +NPY_NO_EXPORT int NpyIter_CreateCompatibleStrides \ + (NpyIter *, npy_intp, npy_intp *); +NPY_NO_EXPORT int PyArray_CastingConverter \ + (PyObject *, NPY_CASTING *); +NPY_NO_EXPORT npy_intp PyArray_CountNonzero \ + (PyArrayObject *); +NPY_NO_EXPORT PyArray_Descr * PyArray_PromoteTypes \ + (PyArray_Descr *, PyArray_Descr *); +NPY_NO_EXPORT PyArray_Descr * PyArray_MinScalarType \ + (PyArrayObject *); +NPY_NO_EXPORT PyArray_Descr * PyArray_ResultType \ + (npy_intp, PyArrayObject **, npy_intp, PyArray_Descr **); +NPY_NO_EXPORT npy_bool PyArray_CanCastArrayTo \ + (PyArrayObject *, PyArray_Descr *, NPY_CASTING); +NPY_NO_EXPORT npy_bool PyArray_CanCastTypeTo \ + (PyArray_Descr *, PyArray_Descr *, NPY_CASTING); +NPY_NO_EXPORT PyArrayObject * PyArray_EinsteinSum \ + (char *, npy_intp, PyArrayObject **, PyArray_Descr *, NPY_ORDER, NPY_CASTING, PyArrayObject *); +NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(3) NPY_GCC_NONNULL(1) PyObject * PyArray_NewLikeArray \ + (PyArrayObject *, NPY_ORDER, PyArray_Descr *, int); +NPY_NO_EXPORT int PyArray_GetArrayParamsFromObject \ + (PyObject *NPY_UNUSED(op), PyArray_Descr *NPY_UNUSED(requested_dtype), npy_bool NPY_UNUSED(writeable), PyArray_Descr **NPY_UNUSED(out_dtype), int *NPY_UNUSED(out_ndim), npy_intp *NPY_UNUSED(out_dims), PyArrayObject **NPY_UNUSED(out_arr), PyObject *NPY_UNUSED(context)); +NPY_NO_EXPORT int PyArray_ConvertClipmodeSequence \ + (PyObject *, NPY_CLIPMODE *, int); +NPY_NO_EXPORT PyObject * PyArray_MatrixProduct2 \ + (PyObject *, PyObject *, PyArrayObject*); +NPY_NO_EXPORT npy_bool NpyIter_IsFirstVisit \ + (NpyIter *, int); +NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(2) int PyArray_SetBaseObject \ + (PyArrayObject *, PyObject *); +NPY_NO_EXPORT void PyArray_CreateSortedStridePerm \ + (int, npy_intp const *, npy_stride_sort_item *); +NPY_NO_EXPORT void PyArray_RemoveAxesInPlace \ + (PyArrayObject *, const npy_bool *); +NPY_NO_EXPORT void PyArray_DebugPrint \ + (PyArrayObject *); +NPY_NO_EXPORT int PyArray_FailUnlessWriteable \ + (PyArrayObject *, const char *); +NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(2) int PyArray_SetUpdateIfCopyBase \ + (PyArrayObject *, PyArrayObject *); +NPY_NO_EXPORT void * PyDataMem_NEW \ + (size_t); +NPY_NO_EXPORT void PyDataMem_FREE \ + (void *); +NPY_NO_EXPORT void * PyDataMem_RENEW \ + (void *, size_t); +NPY_NO_EXPORT PyDataMem_EventHookFunc * PyDataMem_SetEventHook \ + (PyDataMem_EventHookFunc *, void *, void **); +extern NPY_NO_EXPORT NPY_CASTING NPY_DEFAULT_ASSIGN_CASTING; + +NPY_NO_EXPORT void PyArray_MapIterSwapAxes \ + (PyArrayMapIterObject *, PyArrayObject **, int); +NPY_NO_EXPORT PyObject * PyArray_MapIterArray \ + (PyArrayObject *, PyObject *); +NPY_NO_EXPORT void PyArray_MapIterNext \ + (PyArrayMapIterObject *); +NPY_NO_EXPORT int PyArray_Partition \ + (PyArrayObject *, PyArrayObject *, int, NPY_SELECTKIND); +NPY_NO_EXPORT PyObject * PyArray_ArgPartition \ + (PyArrayObject *, PyArrayObject *, int, NPY_SELECTKIND); +NPY_NO_EXPORT int PyArray_SelectkindConverter \ + (PyObject *, NPY_SELECTKIND *); +NPY_NO_EXPORT void * PyDataMem_NEW_ZEROED \ + (size_t, size_t); +NPY_NO_EXPORT NPY_GCC_NONNULL(1) int PyArray_CheckAnyScalarExact \ + (PyObject *); +NPY_NO_EXPORT PyObject * PyArray_MapIterArrayCopyIfOverlap \ + (PyArrayObject *, PyObject *, int, PyArrayObject *); +NPY_NO_EXPORT int PyArray_ResolveWritebackIfCopy \ + (PyArrayObject *); +NPY_NO_EXPORT int PyArray_SetWritebackIfCopyBase \ + (PyArrayObject *, PyArrayObject *); + +#else + +#if defined(PY_ARRAY_UNIQUE_SYMBOL) +#define PyArray_API PY_ARRAY_UNIQUE_SYMBOL +#endif + +#if defined(NO_IMPORT) || defined(NO_IMPORT_ARRAY) +extern void **PyArray_API; +#else +#if defined(PY_ARRAY_UNIQUE_SYMBOL) +void **PyArray_API; +#else +static void **PyArray_API=NULL; +#endif +#endif + +#define PyArray_GetNDArrayCVersion \ + (*(unsigned int (*)(void)) \ + PyArray_API[0]) +#define PyBigArray_Type (*(PyTypeObject *)PyArray_API[1]) +#define PyArray_Type (*(PyTypeObject *)PyArray_API[2]) +#define PyArrayDescr_Type (*(PyTypeObject *)PyArray_API[3]) +#define PyArrayFlags_Type (*(PyTypeObject *)PyArray_API[4]) +#define PyArrayIter_Type (*(PyTypeObject *)PyArray_API[5]) +#define PyArrayMultiIter_Type (*(PyTypeObject *)PyArray_API[6]) +#define NPY_NUMUSERTYPES (*(int *)PyArray_API[7]) +#define PyBoolArrType_Type (*(PyTypeObject *)PyArray_API[8]) +#define _PyArrayScalar_BoolValues ((PyBoolScalarObject *)PyArray_API[9]) +#define PyGenericArrType_Type (*(PyTypeObject *)PyArray_API[10]) +#define PyNumberArrType_Type (*(PyTypeObject *)PyArray_API[11]) +#define PyIntegerArrType_Type (*(PyTypeObject *)PyArray_API[12]) +#define PySignedIntegerArrType_Type (*(PyTypeObject *)PyArray_API[13]) +#define PyUnsignedIntegerArrType_Type (*(PyTypeObject *)PyArray_API[14]) +#define PyInexactArrType_Type (*(PyTypeObject *)PyArray_API[15]) +#define PyFloatingArrType_Type (*(PyTypeObject *)PyArray_API[16]) +#define PyComplexFloatingArrType_Type (*(PyTypeObject *)PyArray_API[17]) +#define PyFlexibleArrType_Type (*(PyTypeObject *)PyArray_API[18]) +#define PyCharacterArrType_Type (*(PyTypeObject *)PyArray_API[19]) +#define PyByteArrType_Type (*(PyTypeObject *)PyArray_API[20]) +#define PyShortArrType_Type (*(PyTypeObject *)PyArray_API[21]) +#define PyIntArrType_Type (*(PyTypeObject *)PyArray_API[22]) +#define PyLongArrType_Type (*(PyTypeObject *)PyArray_API[23]) +#define PyLongLongArrType_Type (*(PyTypeObject *)PyArray_API[24]) +#define PyUByteArrType_Type (*(PyTypeObject *)PyArray_API[25]) +#define PyUShortArrType_Type (*(PyTypeObject *)PyArray_API[26]) +#define PyUIntArrType_Type (*(PyTypeObject *)PyArray_API[27]) +#define PyULongArrType_Type (*(PyTypeObject *)PyArray_API[28]) +#define PyULongLongArrType_Type (*(PyTypeObject *)PyArray_API[29]) +#define PyFloatArrType_Type (*(PyTypeObject *)PyArray_API[30]) +#define PyDoubleArrType_Type (*(PyTypeObject *)PyArray_API[31]) +#define PyLongDoubleArrType_Type (*(PyTypeObject *)PyArray_API[32]) +#define PyCFloatArrType_Type (*(PyTypeObject *)PyArray_API[33]) +#define PyCDoubleArrType_Type (*(PyTypeObject *)PyArray_API[34]) +#define PyCLongDoubleArrType_Type (*(PyTypeObject *)PyArray_API[35]) +#define PyObjectArrType_Type (*(PyTypeObject *)PyArray_API[36]) +#define PyStringArrType_Type (*(PyTypeObject *)PyArray_API[37]) +#define PyUnicodeArrType_Type (*(PyTypeObject *)PyArray_API[38]) +#define PyVoidArrType_Type (*(PyTypeObject *)PyArray_API[39]) +#define PyArray_SetNumericOps \ + (*(int (*)(PyObject *)) \ + PyArray_API[40]) +#define PyArray_GetNumericOps \ + (*(PyObject * (*)(void)) \ + PyArray_API[41]) +#define PyArray_INCREF \ + (*(int (*)(PyArrayObject *)) \ + PyArray_API[42]) +#define PyArray_XDECREF \ + (*(int (*)(PyArrayObject *)) \ + PyArray_API[43]) +#define PyArray_SetStringFunction \ + (*(void (*)(PyObject *, int)) \ + PyArray_API[44]) +#define PyArray_DescrFromType \ + (*(PyArray_Descr * (*)(int)) \ + PyArray_API[45]) +#define PyArray_TypeObjectFromType \ + (*(PyObject * (*)(int)) \ + PyArray_API[46]) +#define PyArray_Zero \ + (*(char * (*)(PyArrayObject *)) \ + PyArray_API[47]) +#define PyArray_One \ + (*(char * (*)(PyArrayObject *)) \ + PyArray_API[48]) +#define PyArray_CastToType \ + (*(PyObject * (*)(PyArrayObject *, PyArray_Descr *, int)) \ + PyArray_API[49]) +#define PyArray_CastTo \ + (*(int (*)(PyArrayObject *, PyArrayObject *)) \ + PyArray_API[50]) +#define PyArray_CastAnyTo \ + (*(int (*)(PyArrayObject *, PyArrayObject *)) \ + PyArray_API[51]) +#define PyArray_CanCastSafely \ + (*(int (*)(int, int)) \ + PyArray_API[52]) +#define PyArray_CanCastTo \ + (*(npy_bool (*)(PyArray_Descr *, PyArray_Descr *)) \ + PyArray_API[53]) +#define PyArray_ObjectType \ + (*(int (*)(PyObject *, int)) \ + PyArray_API[54]) +#define PyArray_DescrFromObject \ + (*(PyArray_Descr * (*)(PyObject *, PyArray_Descr *)) \ + PyArray_API[55]) +#define PyArray_ConvertToCommonType \ + (*(PyArrayObject ** (*)(PyObject *, int *)) \ + PyArray_API[56]) +#define PyArray_DescrFromScalar \ + (*(PyArray_Descr * (*)(PyObject *)) \ + PyArray_API[57]) +#define PyArray_DescrFromTypeObject \ + (*(PyArray_Descr * (*)(PyObject *)) \ + PyArray_API[58]) +#define PyArray_Size \ + (*(npy_intp (*)(PyObject *)) \ + PyArray_API[59]) +#define PyArray_Scalar \ + (*(PyObject * (*)(void *, PyArray_Descr *, PyObject *)) \ + PyArray_API[60]) +#define PyArray_FromScalar \ + (*(PyObject * (*)(PyObject *, PyArray_Descr *)) \ + PyArray_API[61]) +#define PyArray_ScalarAsCtype \ + (*(void (*)(PyObject *, void *)) \ + PyArray_API[62]) +#define PyArray_CastScalarToCtype \ + (*(int (*)(PyObject *, void *, PyArray_Descr *)) \ + PyArray_API[63]) +#define PyArray_CastScalarDirect \ + (*(int (*)(PyObject *, PyArray_Descr *, void *, int)) \ + PyArray_API[64]) +#define PyArray_ScalarFromObject \ + (*(PyObject * (*)(PyObject *)) \ + PyArray_API[65]) +#define PyArray_GetCastFunc \ + (*(PyArray_VectorUnaryFunc * (*)(PyArray_Descr *, int)) \ + PyArray_API[66]) +#define PyArray_FromDims \ + (*(PyObject * (*)(int NPY_UNUSED(nd), int *NPY_UNUSED(d), int NPY_UNUSED(type))) \ + PyArray_API[67]) +#define PyArray_FromDimsAndDataAndDescr \ + (*(PyObject * (*)(int NPY_UNUSED(nd), int *NPY_UNUSED(d), PyArray_Descr *, char *NPY_UNUSED(data))) \ + PyArray_API[68]) +#define PyArray_FromAny \ + (*(PyObject * (*)(PyObject *, PyArray_Descr *, int, int, int, PyObject *)) \ + PyArray_API[69]) +#define PyArray_EnsureArray \ + (*(PyObject * (*)(PyObject *)) \ + PyArray_API[70]) +#define PyArray_EnsureAnyArray \ + (*(PyObject * (*)(PyObject *)) \ + PyArray_API[71]) +#define PyArray_FromFile \ + (*(PyObject * (*)(FILE *, PyArray_Descr *, npy_intp, char *)) \ + PyArray_API[72]) +#define PyArray_FromString \ + (*(PyObject * (*)(char *, npy_intp, PyArray_Descr *, npy_intp, char *)) \ + PyArray_API[73]) +#define PyArray_FromBuffer \ + (*(PyObject * (*)(PyObject *, PyArray_Descr *, npy_intp, npy_intp)) \ + PyArray_API[74]) +#define PyArray_FromIter \ + (*(PyObject * (*)(PyObject *, PyArray_Descr *, npy_intp)) \ + PyArray_API[75]) +#define PyArray_Return \ + (*(PyObject * (*)(PyArrayObject *)) \ + PyArray_API[76]) +#define PyArray_GetField \ + (*(PyObject * (*)(PyArrayObject *, PyArray_Descr *, int)) \ + PyArray_API[77]) +#define PyArray_SetField \ + (*(int (*)(PyArrayObject *, PyArray_Descr *, int, PyObject *)) \ + PyArray_API[78]) +#define PyArray_Byteswap \ + (*(PyObject * (*)(PyArrayObject *, npy_bool)) \ + PyArray_API[79]) +#define PyArray_Resize \ + (*(PyObject * (*)(PyArrayObject *, PyArray_Dims *, int, NPY_ORDER NPY_UNUSED(order))) \ + PyArray_API[80]) +#define PyArray_MoveInto \ + (*(int (*)(PyArrayObject *, PyArrayObject *)) \ + PyArray_API[81]) +#define PyArray_CopyInto \ + (*(int (*)(PyArrayObject *, PyArrayObject *)) \ + PyArray_API[82]) +#define PyArray_CopyAnyInto \ + (*(int (*)(PyArrayObject *, PyArrayObject *)) \ + PyArray_API[83]) +#define PyArray_CopyObject \ + (*(int (*)(PyArrayObject *, PyObject *)) \ + PyArray_API[84]) +#define PyArray_NewCopy \ + (*(PyObject * (*)(PyArrayObject *, NPY_ORDER)) \ + PyArray_API[85]) +#define PyArray_ToList \ + (*(PyObject * (*)(PyArrayObject *)) \ + PyArray_API[86]) +#define PyArray_ToString \ + (*(PyObject * (*)(PyArrayObject *, NPY_ORDER)) \ + PyArray_API[87]) +#define PyArray_ToFile \ + (*(int (*)(PyArrayObject *, FILE *, char *, char *)) \ + PyArray_API[88]) +#define PyArray_Dump \ + (*(int (*)(PyObject *, PyObject *, int)) \ + PyArray_API[89]) +#define PyArray_Dumps \ + (*(PyObject * (*)(PyObject *, int)) \ + PyArray_API[90]) +#define PyArray_ValidType \ + (*(int (*)(int)) \ + PyArray_API[91]) +#define PyArray_UpdateFlags \ + (*(void (*)(PyArrayObject *, int)) \ + PyArray_API[92]) +#define PyArray_New \ + (*(PyObject * (*)(PyTypeObject *, int, npy_intp const *, int, npy_intp const *, void *, int, int, PyObject *)) \ + PyArray_API[93]) +#define PyArray_NewFromDescr \ + (*(PyObject * (*)(PyTypeObject *, PyArray_Descr *, int, npy_intp const *, npy_intp const *, void *, int, PyObject *)) \ + PyArray_API[94]) +#define PyArray_DescrNew \ + (*(PyArray_Descr * (*)(PyArray_Descr *)) \ + PyArray_API[95]) +#define PyArray_DescrNewFromType \ + (*(PyArray_Descr * (*)(int)) \ + PyArray_API[96]) +#define PyArray_GetPriority \ + (*(double (*)(PyObject *, double)) \ + PyArray_API[97]) +#define PyArray_IterNew \ + (*(PyObject * (*)(PyObject *)) \ + PyArray_API[98]) +#define PyArray_MultiIterNew \ + (*(PyObject* (*)(int, ...)) \ + PyArray_API[99]) +#define PyArray_PyIntAsInt \ + (*(int (*)(PyObject *)) \ + PyArray_API[100]) +#define PyArray_PyIntAsIntp \ + (*(npy_intp (*)(PyObject *)) \ + PyArray_API[101]) +#define PyArray_Broadcast \ + (*(int (*)(PyArrayMultiIterObject *)) \ + PyArray_API[102]) +#define PyArray_FillObjectArray \ + (*(void (*)(PyArrayObject *, PyObject *)) \ + PyArray_API[103]) +#define PyArray_FillWithScalar \ + (*(int (*)(PyArrayObject *, PyObject *)) \ + PyArray_API[104]) +#define PyArray_CheckStrides \ + (*(npy_bool (*)(int, int, npy_intp, npy_intp, npy_intp const *, npy_intp const *)) \ + PyArray_API[105]) +#define PyArray_DescrNewByteorder \ + (*(PyArray_Descr * (*)(PyArray_Descr *, char)) \ + PyArray_API[106]) +#define PyArray_IterAllButAxis \ + (*(PyObject * (*)(PyObject *, int *)) \ + PyArray_API[107]) +#define PyArray_CheckFromAny \ + (*(PyObject * (*)(PyObject *, PyArray_Descr *, int, int, int, PyObject *)) \ + PyArray_API[108]) +#define PyArray_FromArray \ + (*(PyObject * (*)(PyArrayObject *, PyArray_Descr *, int)) \ + PyArray_API[109]) +#define PyArray_FromInterface \ + (*(PyObject * (*)(PyObject *)) \ + PyArray_API[110]) +#define PyArray_FromStructInterface \ + (*(PyObject * (*)(PyObject *)) \ + PyArray_API[111]) +#define PyArray_FromArrayAttr \ + (*(PyObject * (*)(PyObject *, PyArray_Descr *, PyObject *)) \ + PyArray_API[112]) +#define PyArray_ScalarKind \ + (*(NPY_SCALARKIND (*)(int, PyArrayObject **)) \ + PyArray_API[113]) +#define PyArray_CanCoerceScalar \ + (*(int (*)(int, int, NPY_SCALARKIND)) \ + PyArray_API[114]) +#define PyArray_NewFlagsObject \ + (*(PyObject * (*)(PyObject *)) \ + PyArray_API[115]) +#define PyArray_CanCastScalar \ + (*(npy_bool (*)(PyTypeObject *, PyTypeObject *)) \ + PyArray_API[116]) +#define PyArray_CompareUCS4 \ + (*(int (*)(npy_ucs4 const *, npy_ucs4 const *, size_t)) \ + PyArray_API[117]) +#define PyArray_RemoveSmallest \ + (*(int (*)(PyArrayMultiIterObject *)) \ + PyArray_API[118]) +#define PyArray_ElementStrides \ + (*(int (*)(PyObject *)) \ + PyArray_API[119]) +#define PyArray_Item_INCREF \ + (*(void (*)(char *, PyArray_Descr *)) \ + PyArray_API[120]) +#define PyArray_Item_XDECREF \ + (*(void (*)(char *, PyArray_Descr *)) \ + PyArray_API[121]) +#define PyArray_FieldNames \ + (*(PyObject * (*)(PyObject *)) \ + PyArray_API[122]) +#define PyArray_Transpose \ + (*(PyObject * (*)(PyArrayObject *, PyArray_Dims *)) \ + PyArray_API[123]) +#define PyArray_TakeFrom \ + (*(PyObject * (*)(PyArrayObject *, PyObject *, int, PyArrayObject *, NPY_CLIPMODE)) \ + PyArray_API[124]) +#define PyArray_PutTo \ + (*(PyObject * (*)(PyArrayObject *, PyObject*, PyObject *, NPY_CLIPMODE)) \ + PyArray_API[125]) +#define PyArray_PutMask \ + (*(PyObject * (*)(PyArrayObject *, PyObject*, PyObject*)) \ + PyArray_API[126]) +#define PyArray_Repeat \ + (*(PyObject * (*)(PyArrayObject *, PyObject *, int)) \ + PyArray_API[127]) +#define PyArray_Choose \ + (*(PyObject * (*)(PyArrayObject *, PyObject *, PyArrayObject *, NPY_CLIPMODE)) \ + PyArray_API[128]) +#define PyArray_Sort \ + (*(int (*)(PyArrayObject *, int, NPY_SORTKIND)) \ + PyArray_API[129]) +#define PyArray_ArgSort \ + (*(PyObject * (*)(PyArrayObject *, int, NPY_SORTKIND)) \ + PyArray_API[130]) +#define PyArray_SearchSorted \ + (*(PyObject * (*)(PyArrayObject *, PyObject *, NPY_SEARCHSIDE, PyObject *)) \ + PyArray_API[131]) +#define PyArray_ArgMax \ + (*(PyObject * (*)(PyArrayObject *, int, PyArrayObject *)) \ + PyArray_API[132]) +#define PyArray_ArgMin \ + (*(PyObject * (*)(PyArrayObject *, int, PyArrayObject *)) \ + PyArray_API[133]) +#define PyArray_Reshape \ + (*(PyObject * (*)(PyArrayObject *, PyObject *)) \ + PyArray_API[134]) +#define PyArray_Newshape \ + (*(PyObject * (*)(PyArrayObject *, PyArray_Dims *, NPY_ORDER)) \ + PyArray_API[135]) +#define PyArray_Squeeze \ + (*(PyObject * (*)(PyArrayObject *)) \ + PyArray_API[136]) +#define PyArray_View \ + (*(PyObject * (*)(PyArrayObject *, PyArray_Descr *, PyTypeObject *)) \ + PyArray_API[137]) +#define PyArray_SwapAxes \ + (*(PyObject * (*)(PyArrayObject *, int, int)) \ + PyArray_API[138]) +#define PyArray_Max \ + (*(PyObject * (*)(PyArrayObject *, int, PyArrayObject *)) \ + PyArray_API[139]) +#define PyArray_Min \ + (*(PyObject * (*)(PyArrayObject *, int, PyArrayObject *)) \ + PyArray_API[140]) +#define PyArray_Ptp \ + (*(PyObject * (*)(PyArrayObject *, int, PyArrayObject *)) \ + PyArray_API[141]) +#define PyArray_Mean \ + (*(PyObject * (*)(PyArrayObject *, int, int, PyArrayObject *)) \ + PyArray_API[142]) +#define PyArray_Trace \ + (*(PyObject * (*)(PyArrayObject *, int, int, int, int, PyArrayObject *)) \ + PyArray_API[143]) +#define PyArray_Diagonal \ + (*(PyObject * (*)(PyArrayObject *, int, int, int)) \ + PyArray_API[144]) +#define PyArray_Clip \ + (*(PyObject * (*)(PyArrayObject *, PyObject *, PyObject *, PyArrayObject *)) \ + PyArray_API[145]) +#define PyArray_Conjugate \ + (*(PyObject * (*)(PyArrayObject *, PyArrayObject *)) \ + PyArray_API[146]) +#define PyArray_Nonzero \ + (*(PyObject * (*)(PyArrayObject *)) \ + PyArray_API[147]) +#define PyArray_Std \ + (*(PyObject * (*)(PyArrayObject *, int, int, PyArrayObject *, int)) \ + PyArray_API[148]) +#define PyArray_Sum \ + (*(PyObject * (*)(PyArrayObject *, int, int, PyArrayObject *)) \ + PyArray_API[149]) +#define PyArray_CumSum \ + (*(PyObject * (*)(PyArrayObject *, int, int, PyArrayObject *)) \ + PyArray_API[150]) +#define PyArray_Prod \ + (*(PyObject * (*)(PyArrayObject *, int, int, PyArrayObject *)) \ + PyArray_API[151]) +#define PyArray_CumProd \ + (*(PyObject * (*)(PyArrayObject *, int, int, PyArrayObject *)) \ + PyArray_API[152]) +#define PyArray_All \ + (*(PyObject * (*)(PyArrayObject *, int, PyArrayObject *)) \ + PyArray_API[153]) +#define PyArray_Any \ + (*(PyObject * (*)(PyArrayObject *, int, PyArrayObject *)) \ + PyArray_API[154]) +#define PyArray_Compress \ + (*(PyObject * (*)(PyArrayObject *, PyObject *, int, PyArrayObject *)) \ + PyArray_API[155]) +#define PyArray_Flatten \ + (*(PyObject * (*)(PyArrayObject *, NPY_ORDER)) \ + PyArray_API[156]) +#define PyArray_Ravel \ + (*(PyObject * (*)(PyArrayObject *, NPY_ORDER)) \ + PyArray_API[157]) +#define PyArray_MultiplyList \ + (*(npy_intp (*)(npy_intp const *, int)) \ + PyArray_API[158]) +#define PyArray_MultiplyIntList \ + (*(int (*)(int const *, int)) \ + PyArray_API[159]) +#define PyArray_GetPtr \ + (*(void * (*)(PyArrayObject *, npy_intp const*)) \ + PyArray_API[160]) +#define PyArray_CompareLists \ + (*(int (*)(npy_intp const *, npy_intp const *, int)) \ + PyArray_API[161]) +#define PyArray_AsCArray \ + (*(int (*)(PyObject **, void *, npy_intp *, int, PyArray_Descr*)) \ + PyArray_API[162]) +#define PyArray_As1D \ + (*(int (*)(PyObject **NPY_UNUSED(op), char **NPY_UNUSED(ptr), int *NPY_UNUSED(d1), int NPY_UNUSED(typecode))) \ + PyArray_API[163]) +#define PyArray_As2D \ + (*(int (*)(PyObject **NPY_UNUSED(op), char ***NPY_UNUSED(ptr), int *NPY_UNUSED(d1), int *NPY_UNUSED(d2), int NPY_UNUSED(typecode))) \ + PyArray_API[164]) +#define PyArray_Free \ + (*(int (*)(PyObject *, void *)) \ + PyArray_API[165]) +#define PyArray_Converter \ + (*(int (*)(PyObject *, PyObject **)) \ + PyArray_API[166]) +#define PyArray_IntpFromSequence \ + (*(int (*)(PyObject *, npy_intp *, int)) \ + PyArray_API[167]) +#define PyArray_Concatenate \ + (*(PyObject * (*)(PyObject *, int)) \ + PyArray_API[168]) +#define PyArray_InnerProduct \ + (*(PyObject * (*)(PyObject *, PyObject *)) \ + PyArray_API[169]) +#define PyArray_MatrixProduct \ + (*(PyObject * (*)(PyObject *, PyObject *)) \ + PyArray_API[170]) +#define PyArray_CopyAndTranspose \ + (*(PyObject * (*)(PyObject *)) \ + PyArray_API[171]) +#define PyArray_Correlate \ + (*(PyObject * (*)(PyObject *, PyObject *, int)) \ + PyArray_API[172]) +#define PyArray_TypestrConvert \ + (*(int (*)(int, int)) \ + PyArray_API[173]) +#define PyArray_DescrConverter \ + (*(int (*)(PyObject *, PyArray_Descr **)) \ + PyArray_API[174]) +#define PyArray_DescrConverter2 \ + (*(int (*)(PyObject *, PyArray_Descr **)) \ + PyArray_API[175]) +#define PyArray_IntpConverter \ + (*(int (*)(PyObject *, PyArray_Dims *)) \ + PyArray_API[176]) +#define PyArray_BufferConverter \ + (*(int (*)(PyObject *, PyArray_Chunk *)) \ + PyArray_API[177]) +#define PyArray_AxisConverter \ + (*(int (*)(PyObject *, int *)) \ + PyArray_API[178]) +#define PyArray_BoolConverter \ + (*(int (*)(PyObject *, npy_bool *)) \ + PyArray_API[179]) +#define PyArray_ByteorderConverter \ + (*(int (*)(PyObject *, char *)) \ + PyArray_API[180]) +#define PyArray_OrderConverter \ + (*(int (*)(PyObject *, NPY_ORDER *)) \ + PyArray_API[181]) +#define PyArray_EquivTypes \ + (*(unsigned char (*)(PyArray_Descr *, PyArray_Descr *)) \ + PyArray_API[182]) +#define PyArray_Zeros \ + (*(PyObject * (*)(int, npy_intp const *, PyArray_Descr *, int)) \ + PyArray_API[183]) +#define PyArray_Empty \ + (*(PyObject * (*)(int, npy_intp const *, PyArray_Descr *, int)) \ + PyArray_API[184]) +#define PyArray_Where \ + (*(PyObject * (*)(PyObject *, PyObject *, PyObject *)) \ + PyArray_API[185]) +#define PyArray_Arange \ + (*(PyObject * (*)(double, double, double, int)) \ + PyArray_API[186]) +#define PyArray_ArangeObj \ + (*(PyObject * (*)(PyObject *, PyObject *, PyObject *, PyArray_Descr *)) \ + PyArray_API[187]) +#define PyArray_SortkindConverter \ + (*(int (*)(PyObject *, NPY_SORTKIND *)) \ + PyArray_API[188]) +#define PyArray_LexSort \ + (*(PyObject * (*)(PyObject *, int)) \ + PyArray_API[189]) +#define PyArray_Round \ + (*(PyObject * (*)(PyArrayObject *, int, PyArrayObject *)) \ + PyArray_API[190]) +#define PyArray_EquivTypenums \ + (*(unsigned char (*)(int, int)) \ + PyArray_API[191]) +#define PyArray_RegisterDataType \ + (*(int (*)(PyArray_Descr *)) \ + PyArray_API[192]) +#define PyArray_RegisterCastFunc \ + (*(int (*)(PyArray_Descr *, int, PyArray_VectorUnaryFunc *)) \ + PyArray_API[193]) +#define PyArray_RegisterCanCast \ + (*(int (*)(PyArray_Descr *, int, NPY_SCALARKIND)) \ + PyArray_API[194]) +#define PyArray_InitArrFuncs \ + (*(void (*)(PyArray_ArrFuncs *)) \ + PyArray_API[195]) +#define PyArray_IntTupleFromIntp \ + (*(PyObject * (*)(int, npy_intp const *)) \ + PyArray_API[196]) +#define PyArray_TypeNumFromName \ + (*(int (*)(char const *)) \ + PyArray_API[197]) +#define PyArray_ClipmodeConverter \ + (*(int (*)(PyObject *, NPY_CLIPMODE *)) \ + PyArray_API[198]) +#define PyArray_OutputConverter \ + (*(int (*)(PyObject *, PyArrayObject **)) \ + PyArray_API[199]) +#define PyArray_BroadcastToShape \ + (*(PyObject * (*)(PyObject *, npy_intp *, int)) \ + PyArray_API[200]) +#define _PyArray_SigintHandler \ + (*(void (*)(int)) \ + PyArray_API[201]) +#define _PyArray_GetSigintBuf \ + (*(void* (*)(void)) \ + PyArray_API[202]) +#define PyArray_DescrAlignConverter \ + (*(int (*)(PyObject *, PyArray_Descr **)) \ + PyArray_API[203]) +#define PyArray_DescrAlignConverter2 \ + (*(int (*)(PyObject *, PyArray_Descr **)) \ + PyArray_API[204]) +#define PyArray_SearchsideConverter \ + (*(int (*)(PyObject *, void *)) \ + PyArray_API[205]) +#define PyArray_CheckAxis \ + (*(PyObject * (*)(PyArrayObject *, int *, int)) \ + PyArray_API[206]) +#define PyArray_OverflowMultiplyList \ + (*(npy_intp (*)(npy_intp const *, int)) \ + PyArray_API[207]) +#define PyArray_CompareString \ + (*(int (*)(const char *, const char *, size_t)) \ + PyArray_API[208]) +#define PyArray_MultiIterFromObjects \ + (*(PyObject* (*)(PyObject **, int, int, ...)) \ + PyArray_API[209]) +#define PyArray_GetEndianness \ + (*(int (*)(void)) \ + PyArray_API[210]) +#define PyArray_GetNDArrayCFeatureVersion \ + (*(unsigned int (*)(void)) \ + PyArray_API[211]) +#define PyArray_Correlate2 \ + (*(PyObject * (*)(PyObject *, PyObject *, int)) \ + PyArray_API[212]) +#define PyArray_NeighborhoodIterNew \ + (*(PyObject* (*)(PyArrayIterObject *, const npy_intp *, int, PyArrayObject*)) \ + PyArray_API[213]) +#define PyTimeIntegerArrType_Type (*(PyTypeObject *)PyArray_API[214]) +#define PyDatetimeArrType_Type (*(PyTypeObject *)PyArray_API[215]) +#define PyTimedeltaArrType_Type (*(PyTypeObject *)PyArray_API[216]) +#define PyHalfArrType_Type (*(PyTypeObject *)PyArray_API[217]) +#define NpyIter_Type (*(PyTypeObject *)PyArray_API[218]) +#define PyArray_SetDatetimeParseFunction \ + (*(void (*)(PyObject *NPY_UNUSED(op))) \ + PyArray_API[219]) +#define PyArray_DatetimeToDatetimeStruct \ + (*(void (*)(npy_datetime NPY_UNUSED(val), NPY_DATETIMEUNIT NPY_UNUSED(fr), npy_datetimestruct *)) \ + PyArray_API[220]) +#define PyArray_TimedeltaToTimedeltaStruct \ + (*(void (*)(npy_timedelta NPY_UNUSED(val), NPY_DATETIMEUNIT NPY_UNUSED(fr), npy_timedeltastruct *)) \ + PyArray_API[221]) +#define PyArray_DatetimeStructToDatetime \ + (*(npy_datetime (*)(NPY_DATETIMEUNIT NPY_UNUSED(fr), npy_datetimestruct *NPY_UNUSED(d))) \ + PyArray_API[222]) +#define PyArray_TimedeltaStructToTimedelta \ + (*(npy_datetime (*)(NPY_DATETIMEUNIT NPY_UNUSED(fr), npy_timedeltastruct *NPY_UNUSED(d))) \ + PyArray_API[223]) +#define NpyIter_New \ + (*(NpyIter * (*)(PyArrayObject *, npy_uint32, NPY_ORDER, NPY_CASTING, PyArray_Descr*)) \ + PyArray_API[224]) +#define NpyIter_MultiNew \ + (*(NpyIter * (*)(int, PyArrayObject **, npy_uint32, NPY_ORDER, NPY_CASTING, npy_uint32 *, PyArray_Descr **)) \ + PyArray_API[225]) +#define NpyIter_AdvancedNew \ + (*(NpyIter * (*)(int, PyArrayObject **, npy_uint32, NPY_ORDER, NPY_CASTING, npy_uint32 *, PyArray_Descr **, int, int **, npy_intp *, npy_intp)) \ + PyArray_API[226]) +#define NpyIter_Copy \ + (*(NpyIter * (*)(NpyIter *)) \ + PyArray_API[227]) +#define NpyIter_Deallocate \ + (*(int (*)(NpyIter *)) \ + PyArray_API[228]) +#define NpyIter_HasDelayedBufAlloc \ + (*(npy_bool (*)(NpyIter *)) \ + PyArray_API[229]) +#define NpyIter_HasExternalLoop \ + (*(npy_bool (*)(NpyIter *)) \ + PyArray_API[230]) +#define NpyIter_EnableExternalLoop \ + (*(int (*)(NpyIter *)) \ + PyArray_API[231]) +#define NpyIter_GetInnerStrideArray \ + (*(npy_intp * (*)(NpyIter *)) \ + PyArray_API[232]) +#define NpyIter_GetInnerLoopSizePtr \ + (*(npy_intp * (*)(NpyIter *)) \ + PyArray_API[233]) +#define NpyIter_Reset \ + (*(int (*)(NpyIter *, char **)) \ + PyArray_API[234]) +#define NpyIter_ResetBasePointers \ + (*(int (*)(NpyIter *, char **, char **)) \ + PyArray_API[235]) +#define NpyIter_ResetToIterIndexRange \ + (*(int (*)(NpyIter *, npy_intp, npy_intp, char **)) \ + PyArray_API[236]) +#define NpyIter_GetNDim \ + (*(int (*)(NpyIter *)) \ + PyArray_API[237]) +#define NpyIter_GetNOp \ + (*(int (*)(NpyIter *)) \ + PyArray_API[238]) +#define NpyIter_GetIterNext \ + (*(NpyIter_IterNextFunc * (*)(NpyIter *, char **)) \ + PyArray_API[239]) +#define NpyIter_GetIterSize \ + (*(npy_intp (*)(NpyIter *)) \ + PyArray_API[240]) +#define NpyIter_GetIterIndexRange \ + (*(void (*)(NpyIter *, npy_intp *, npy_intp *)) \ + PyArray_API[241]) +#define NpyIter_GetIterIndex \ + (*(npy_intp (*)(NpyIter *)) \ + PyArray_API[242]) +#define NpyIter_GotoIterIndex \ + (*(int (*)(NpyIter *, npy_intp)) \ + PyArray_API[243]) +#define NpyIter_HasMultiIndex \ + (*(npy_bool (*)(NpyIter *)) \ + PyArray_API[244]) +#define NpyIter_GetShape \ + (*(int (*)(NpyIter *, npy_intp *)) \ + PyArray_API[245]) +#define NpyIter_GetGetMultiIndex \ + (*(NpyIter_GetMultiIndexFunc * (*)(NpyIter *, char **)) \ + PyArray_API[246]) +#define NpyIter_GotoMultiIndex \ + (*(int (*)(NpyIter *, npy_intp const *)) \ + PyArray_API[247]) +#define NpyIter_RemoveMultiIndex \ + (*(int (*)(NpyIter *)) \ + PyArray_API[248]) +#define NpyIter_HasIndex \ + (*(npy_bool (*)(NpyIter *)) \ + PyArray_API[249]) +#define NpyIter_IsBuffered \ + (*(npy_bool (*)(NpyIter *)) \ + PyArray_API[250]) +#define NpyIter_IsGrowInner \ + (*(npy_bool (*)(NpyIter *)) \ + PyArray_API[251]) +#define NpyIter_GetBufferSize \ + (*(npy_intp (*)(NpyIter *)) \ + PyArray_API[252]) +#define NpyIter_GetIndexPtr \ + (*(npy_intp * (*)(NpyIter *)) \ + PyArray_API[253]) +#define NpyIter_GotoIndex \ + (*(int (*)(NpyIter *, npy_intp)) \ + PyArray_API[254]) +#define NpyIter_GetDataPtrArray \ + (*(char ** (*)(NpyIter *)) \ + PyArray_API[255]) +#define NpyIter_GetDescrArray \ + (*(PyArray_Descr ** (*)(NpyIter *)) \ + PyArray_API[256]) +#define NpyIter_GetOperandArray \ + (*(PyArrayObject ** (*)(NpyIter *)) \ + PyArray_API[257]) +#define NpyIter_GetIterView \ + (*(PyArrayObject * (*)(NpyIter *, npy_intp)) \ + PyArray_API[258]) +#define NpyIter_GetReadFlags \ + (*(void (*)(NpyIter *, char *)) \ + PyArray_API[259]) +#define NpyIter_GetWriteFlags \ + (*(void (*)(NpyIter *, char *)) \ + PyArray_API[260]) +#define NpyIter_DebugPrint \ + (*(void (*)(NpyIter *)) \ + PyArray_API[261]) +#define NpyIter_IterationNeedsAPI \ + (*(npy_bool (*)(NpyIter *)) \ + PyArray_API[262]) +#define NpyIter_GetInnerFixedStrideArray \ + (*(void (*)(NpyIter *, npy_intp *)) \ + PyArray_API[263]) +#define NpyIter_RemoveAxis \ + (*(int (*)(NpyIter *, int)) \ + PyArray_API[264]) +#define NpyIter_GetAxisStrideArray \ + (*(npy_intp * (*)(NpyIter *, int)) \ + PyArray_API[265]) +#define NpyIter_RequiresBuffering \ + (*(npy_bool (*)(NpyIter *)) \ + PyArray_API[266]) +#define NpyIter_GetInitialDataPtrArray \ + (*(char ** (*)(NpyIter *)) \ + PyArray_API[267]) +#define NpyIter_CreateCompatibleStrides \ + (*(int (*)(NpyIter *, npy_intp, npy_intp *)) \ + PyArray_API[268]) +#define PyArray_CastingConverter \ + (*(int (*)(PyObject *, NPY_CASTING *)) \ + PyArray_API[269]) +#define PyArray_CountNonzero \ + (*(npy_intp (*)(PyArrayObject *)) \ + PyArray_API[270]) +#define PyArray_PromoteTypes \ + (*(PyArray_Descr * (*)(PyArray_Descr *, PyArray_Descr *)) \ + PyArray_API[271]) +#define PyArray_MinScalarType \ + (*(PyArray_Descr * (*)(PyArrayObject *)) \ + PyArray_API[272]) +#define PyArray_ResultType \ + (*(PyArray_Descr * (*)(npy_intp, PyArrayObject **, npy_intp, PyArray_Descr **)) \ + PyArray_API[273]) +#define PyArray_CanCastArrayTo \ + (*(npy_bool (*)(PyArrayObject *, PyArray_Descr *, NPY_CASTING)) \ + PyArray_API[274]) +#define PyArray_CanCastTypeTo \ + (*(npy_bool (*)(PyArray_Descr *, PyArray_Descr *, NPY_CASTING)) \ + PyArray_API[275]) +#define PyArray_EinsteinSum \ + (*(PyArrayObject * (*)(char *, npy_intp, PyArrayObject **, PyArray_Descr *, NPY_ORDER, NPY_CASTING, PyArrayObject *)) \ + PyArray_API[276]) +#define PyArray_NewLikeArray \ + (*(PyObject * (*)(PyArrayObject *, NPY_ORDER, PyArray_Descr *, int)) \ + PyArray_API[277]) +#define PyArray_GetArrayParamsFromObject \ + (*(int (*)(PyObject *NPY_UNUSED(op), PyArray_Descr *NPY_UNUSED(requested_dtype), npy_bool NPY_UNUSED(writeable), PyArray_Descr **NPY_UNUSED(out_dtype), int *NPY_UNUSED(out_ndim), npy_intp *NPY_UNUSED(out_dims), PyArrayObject **NPY_UNUSED(out_arr), PyObject *NPY_UNUSED(context))) \ + PyArray_API[278]) +#define PyArray_ConvertClipmodeSequence \ + (*(int (*)(PyObject *, NPY_CLIPMODE *, int)) \ + PyArray_API[279]) +#define PyArray_MatrixProduct2 \ + (*(PyObject * (*)(PyObject *, PyObject *, PyArrayObject*)) \ + PyArray_API[280]) +#define NpyIter_IsFirstVisit \ + (*(npy_bool (*)(NpyIter *, int)) \ + PyArray_API[281]) +#define PyArray_SetBaseObject \ + (*(int (*)(PyArrayObject *, PyObject *)) \ + PyArray_API[282]) +#define PyArray_CreateSortedStridePerm \ + (*(void (*)(int, npy_intp const *, npy_stride_sort_item *)) \ + PyArray_API[283]) +#define PyArray_RemoveAxesInPlace \ + (*(void (*)(PyArrayObject *, const npy_bool *)) \ + PyArray_API[284]) +#define PyArray_DebugPrint \ + (*(void (*)(PyArrayObject *)) \ + PyArray_API[285]) +#define PyArray_FailUnlessWriteable \ + (*(int (*)(PyArrayObject *, const char *)) \ + PyArray_API[286]) +#define PyArray_SetUpdateIfCopyBase \ + (*(int (*)(PyArrayObject *, PyArrayObject *)) \ + PyArray_API[287]) +#define PyDataMem_NEW \ + (*(void * (*)(size_t)) \ + PyArray_API[288]) +#define PyDataMem_FREE \ + (*(void (*)(void *)) \ + PyArray_API[289]) +#define PyDataMem_RENEW \ + (*(void * (*)(void *, size_t)) \ + PyArray_API[290]) +#define PyDataMem_SetEventHook \ + (*(PyDataMem_EventHookFunc * (*)(PyDataMem_EventHookFunc *, void *, void **)) \ + PyArray_API[291]) +#define NPY_DEFAULT_ASSIGN_CASTING (*(NPY_CASTING *)PyArray_API[292]) +#define PyArray_MapIterSwapAxes \ + (*(void (*)(PyArrayMapIterObject *, PyArrayObject **, int)) \ + PyArray_API[293]) +#define PyArray_MapIterArray \ + (*(PyObject * (*)(PyArrayObject *, PyObject *)) \ + PyArray_API[294]) +#define PyArray_MapIterNext \ + (*(void (*)(PyArrayMapIterObject *)) \ + PyArray_API[295]) +#define PyArray_Partition \ + (*(int (*)(PyArrayObject *, PyArrayObject *, int, NPY_SELECTKIND)) \ + PyArray_API[296]) +#define PyArray_ArgPartition \ + (*(PyObject * (*)(PyArrayObject *, PyArrayObject *, int, NPY_SELECTKIND)) \ + PyArray_API[297]) +#define PyArray_SelectkindConverter \ + (*(int (*)(PyObject *, NPY_SELECTKIND *)) \ + PyArray_API[298]) +#define PyDataMem_NEW_ZEROED \ + (*(void * (*)(size_t, size_t)) \ + PyArray_API[299]) +#define PyArray_CheckAnyScalarExact \ + (*(int (*)(PyObject *)) \ + PyArray_API[300]) +#define PyArray_MapIterArrayCopyIfOverlap \ + (*(PyObject * (*)(PyArrayObject *, PyObject *, int, PyArrayObject *)) \ + PyArray_API[301]) +#define PyArray_ResolveWritebackIfCopy \ + (*(int (*)(PyArrayObject *)) \ + PyArray_API[302]) +#define PyArray_SetWritebackIfCopyBase \ + (*(int (*)(PyArrayObject *, PyArrayObject *)) \ + PyArray_API[303]) + +#if !defined(NO_IMPORT_ARRAY) && !defined(NO_IMPORT) +static int +_import_array(void) +{ + int st; + PyObject *numpy = PyImport_ImportModule("numpy.core._multiarray_umath"); + PyObject *c_api = NULL; + + if (numpy == NULL) { + return -1; + } + c_api = PyObject_GetAttrString(numpy, "_ARRAY_API"); + Py_DECREF(numpy); + if (c_api == NULL) { + PyErr_SetString(PyExc_AttributeError, "_ARRAY_API not found"); + return -1; + } + + if (!PyCapsule_CheckExact(c_api)) { + PyErr_SetString(PyExc_RuntimeError, "_ARRAY_API is not PyCapsule object"); + Py_DECREF(c_api); + return -1; + } + PyArray_API = (void **)PyCapsule_GetPointer(c_api, NULL); + Py_DECREF(c_api); + if (PyArray_API == NULL) { + PyErr_SetString(PyExc_RuntimeError, "_ARRAY_API is NULL pointer"); + return -1; + } + + /* Perform runtime check of C API version */ + if (NPY_VERSION != PyArray_GetNDArrayCVersion()) { + PyErr_Format(PyExc_RuntimeError, "module compiled against "\ + "ABI version 0x%x but this version of numpy is 0x%x", \ + (int) NPY_VERSION, (int) PyArray_GetNDArrayCVersion()); + return -1; + } + if (NPY_FEATURE_VERSION > PyArray_GetNDArrayCFeatureVersion()) { + PyErr_Format(PyExc_RuntimeError, "module compiled against "\ + "API version 0x%x but this version of numpy is 0x%x", \ + (int) NPY_FEATURE_VERSION, (int) PyArray_GetNDArrayCFeatureVersion()); + return -1; + } + + /* + * Perform runtime check of endianness and check it matches the one set by + * the headers (npy_endian.h) as a safeguard + */ + st = PyArray_GetEndianness(); + if (st == NPY_CPU_UNKNOWN_ENDIAN) { + PyErr_Format(PyExc_RuntimeError, "FATAL: module compiled as unknown endian"); + return -1; + } +#if NPY_BYTE_ORDER == NPY_BIG_ENDIAN + if (st != NPY_CPU_BIG) { + PyErr_Format(PyExc_RuntimeError, "FATAL: module compiled as "\ + "big endian, but detected different endianness at runtime"); + return -1; + } +#elif NPY_BYTE_ORDER == NPY_LITTLE_ENDIAN + if (st != NPY_CPU_LITTLE) { + PyErr_Format(PyExc_RuntimeError, "FATAL: module compiled as "\ + "little endian, but detected different endianness at runtime"); + return -1; + } +#endif + + return 0; +} + +#define import_array() {if (_import_array() < 0) {PyErr_Print(); PyErr_SetString(PyExc_ImportError, "numpy.core.multiarray failed to import"); return NULL; } } + +#define import_array1(ret) {if (_import_array() < 0) {PyErr_Print(); PyErr_SetString(PyExc_ImportError, "numpy.core.multiarray failed to import"); return ret; } } + +#define import_array2(msg, ret) {if (_import_array() < 0) {PyErr_Print(); PyErr_SetString(PyExc_ImportError, msg); return ret; } } + +#endif + +#endif diff --git a/venv/Lib/site-packages/numpy/core/include/numpy/__ufunc_api.h b/venv/Lib/site-packages/numpy/core/include/numpy/__ufunc_api.h new file mode 100644 index 0000000..c14bbc8 --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/include/numpy/__ufunc_api.h @@ -0,0 +1,311 @@ + +#ifdef _UMATHMODULE + +extern NPY_NO_EXPORT PyTypeObject PyUFunc_Type; + +extern NPY_NO_EXPORT PyTypeObject PyUFunc_Type; + +NPY_NO_EXPORT PyObject * PyUFunc_FromFuncAndData \ + (PyUFuncGenericFunction *, void **, char *, int, int, int, int, const char *, const char *, int); +NPY_NO_EXPORT int PyUFunc_RegisterLoopForType \ + (PyUFuncObject *, int, PyUFuncGenericFunction, const int *, void *); +NPY_NO_EXPORT int PyUFunc_GenericFunction \ + (PyUFuncObject *, PyObject *, PyObject *, PyArrayObject **); +NPY_NO_EXPORT void PyUFunc_f_f_As_d_d \ + (char **, npy_intp const *, npy_intp const *, void *); +NPY_NO_EXPORT void PyUFunc_d_d \ + (char **, npy_intp const *, npy_intp const *, void *); +NPY_NO_EXPORT void PyUFunc_f_f \ + (char **, npy_intp const *, npy_intp const *, void *); +NPY_NO_EXPORT void PyUFunc_g_g \ + (char **, npy_intp const *, npy_intp const *, void *); +NPY_NO_EXPORT void PyUFunc_F_F_As_D_D \ + (char **, npy_intp const *, npy_intp const *, void *); +NPY_NO_EXPORT void PyUFunc_F_F \ + (char **, npy_intp const *, npy_intp const *, void *); +NPY_NO_EXPORT void PyUFunc_D_D \ + (char **, npy_intp const *, npy_intp const *, void *); +NPY_NO_EXPORT void PyUFunc_G_G \ + (char **, npy_intp const *, npy_intp const *, void *); +NPY_NO_EXPORT void PyUFunc_O_O \ + (char **, npy_intp const *, npy_intp const *, void *); +NPY_NO_EXPORT void PyUFunc_ff_f_As_dd_d \ + (char **, npy_intp const *, npy_intp const *, void *); +NPY_NO_EXPORT void PyUFunc_ff_f \ + (char **, npy_intp const *, npy_intp const *, void *); +NPY_NO_EXPORT void PyUFunc_dd_d \ + (char **, npy_intp const *, npy_intp const *, void *); +NPY_NO_EXPORT void PyUFunc_gg_g \ + (char **, npy_intp const *, npy_intp const *, void *); +NPY_NO_EXPORT void PyUFunc_FF_F_As_DD_D \ + (char **, npy_intp const *, npy_intp const *, void *); +NPY_NO_EXPORT void PyUFunc_DD_D \ + (char **, npy_intp const *, npy_intp const *, void *); +NPY_NO_EXPORT void PyUFunc_FF_F \ + (char **, npy_intp const *, npy_intp const *, void *); +NPY_NO_EXPORT void PyUFunc_GG_G \ + (char **, npy_intp const *, npy_intp const *, void *); +NPY_NO_EXPORT void PyUFunc_OO_O \ + (char **, npy_intp const *, npy_intp const *, void *); +NPY_NO_EXPORT void PyUFunc_O_O_method \ + (char **, npy_intp const *, npy_intp const *, void *); +NPY_NO_EXPORT void PyUFunc_OO_O_method \ + (char **, npy_intp const *, npy_intp const *, void *); +NPY_NO_EXPORT void PyUFunc_On_Om \ + (char **, npy_intp const *, npy_intp const *, void *); +NPY_NO_EXPORT int PyUFunc_GetPyValues \ + (char *, int *, int *, PyObject **); +NPY_NO_EXPORT int PyUFunc_checkfperr \ + (int, PyObject *, int *); +NPY_NO_EXPORT void PyUFunc_clearfperr \ + (void); +NPY_NO_EXPORT int PyUFunc_getfperr \ + (void); +NPY_NO_EXPORT int PyUFunc_handlefperr \ + (int, PyObject *, int, int *); +NPY_NO_EXPORT int PyUFunc_ReplaceLoopBySignature \ + (PyUFuncObject *, PyUFuncGenericFunction, const int *, PyUFuncGenericFunction *); +NPY_NO_EXPORT PyObject * PyUFunc_FromFuncAndDataAndSignature \ + (PyUFuncGenericFunction *, void **, char *, int, int, int, int, const char *, const char *, int, const char *); +NPY_NO_EXPORT int PyUFunc_SetUsesArraysAsData \ + (void **, size_t); +NPY_NO_EXPORT void PyUFunc_e_e \ + (char **, npy_intp const *, npy_intp const *, void *); +NPY_NO_EXPORT void PyUFunc_e_e_As_f_f \ + (char **, npy_intp const *, npy_intp const *, void *); +NPY_NO_EXPORT void PyUFunc_e_e_As_d_d \ + (char **, npy_intp const *, npy_intp const *, void *); +NPY_NO_EXPORT void PyUFunc_ee_e \ + (char **, npy_intp const *, npy_intp const *, void *); +NPY_NO_EXPORT void PyUFunc_ee_e_As_ff_f \ + (char **, npy_intp const *, npy_intp const *, void *); +NPY_NO_EXPORT void PyUFunc_ee_e_As_dd_d \ + (char **, npy_intp const *, npy_intp const *, void *); +NPY_NO_EXPORT int PyUFunc_DefaultTypeResolver \ + (PyUFuncObject *, NPY_CASTING, PyArrayObject **, PyObject *, PyArray_Descr **); +NPY_NO_EXPORT int PyUFunc_ValidateCasting \ + (PyUFuncObject *, NPY_CASTING, PyArrayObject **, PyArray_Descr **); +NPY_NO_EXPORT int PyUFunc_RegisterLoopForDescr \ + (PyUFuncObject *, PyArray_Descr *, PyUFuncGenericFunction, PyArray_Descr **, void *); +NPY_NO_EXPORT PyObject * PyUFunc_FromFuncAndDataAndSignatureAndIdentity \ + (PyUFuncGenericFunction *, void **, char *, int, int, int, int, const char *, const char *, const int, const char *, PyObject *); + +#else + +#if defined(PY_UFUNC_UNIQUE_SYMBOL) +#define PyUFunc_API PY_UFUNC_UNIQUE_SYMBOL +#endif + +#if defined(NO_IMPORT) || defined(NO_IMPORT_UFUNC) +extern void **PyUFunc_API; +#else +#if defined(PY_UFUNC_UNIQUE_SYMBOL) +void **PyUFunc_API; +#else +static void **PyUFunc_API=NULL; +#endif +#endif + +#define PyUFunc_Type (*(PyTypeObject *)PyUFunc_API[0]) +#define PyUFunc_FromFuncAndData \ + (*(PyObject * (*)(PyUFuncGenericFunction *, void **, char *, int, int, int, int, const char *, const char *, int)) \ + PyUFunc_API[1]) +#define PyUFunc_RegisterLoopForType \ + (*(int (*)(PyUFuncObject *, int, PyUFuncGenericFunction, const int *, void *)) \ + PyUFunc_API[2]) +#define PyUFunc_GenericFunction \ + (*(int (*)(PyUFuncObject *, PyObject *, PyObject *, PyArrayObject **)) \ + PyUFunc_API[3]) +#define PyUFunc_f_f_As_d_d \ + (*(void (*)(char **, npy_intp const *, npy_intp const *, void *)) \ + PyUFunc_API[4]) +#define PyUFunc_d_d \ + (*(void (*)(char **, npy_intp const *, npy_intp const *, void *)) \ + PyUFunc_API[5]) +#define PyUFunc_f_f \ + (*(void (*)(char **, npy_intp const *, npy_intp const *, void *)) \ + PyUFunc_API[6]) +#define PyUFunc_g_g \ + (*(void (*)(char **, npy_intp const *, npy_intp const *, void *)) \ + PyUFunc_API[7]) +#define PyUFunc_F_F_As_D_D \ + (*(void (*)(char **, npy_intp const *, npy_intp const *, void *)) \ + PyUFunc_API[8]) +#define PyUFunc_F_F \ + (*(void (*)(char **, npy_intp const *, npy_intp const *, void *)) \ + PyUFunc_API[9]) +#define PyUFunc_D_D \ + (*(void (*)(char **, npy_intp const *, npy_intp const *, void *)) \ + PyUFunc_API[10]) +#define PyUFunc_G_G \ + (*(void (*)(char **, npy_intp const *, npy_intp const *, void *)) \ + PyUFunc_API[11]) +#define PyUFunc_O_O \ + (*(void (*)(char **, npy_intp const *, npy_intp const *, void *)) \ + PyUFunc_API[12]) +#define PyUFunc_ff_f_As_dd_d \ + (*(void (*)(char **, npy_intp const *, npy_intp const *, void *)) \ + PyUFunc_API[13]) +#define PyUFunc_ff_f \ + (*(void (*)(char **, npy_intp const *, npy_intp const *, void *)) \ + PyUFunc_API[14]) +#define PyUFunc_dd_d \ + (*(void (*)(char **, npy_intp const *, npy_intp const *, void *)) \ + PyUFunc_API[15]) +#define PyUFunc_gg_g \ + (*(void (*)(char **, npy_intp const *, npy_intp const *, void *)) \ + PyUFunc_API[16]) +#define PyUFunc_FF_F_As_DD_D \ + (*(void (*)(char **, npy_intp const *, npy_intp const *, void *)) \ + PyUFunc_API[17]) +#define PyUFunc_DD_D \ + (*(void (*)(char **, npy_intp const *, npy_intp const *, void *)) \ + PyUFunc_API[18]) +#define PyUFunc_FF_F \ + (*(void (*)(char **, npy_intp const *, npy_intp const *, void *)) \ + PyUFunc_API[19]) +#define PyUFunc_GG_G \ + (*(void (*)(char **, npy_intp const *, npy_intp const *, void *)) \ + PyUFunc_API[20]) +#define PyUFunc_OO_O \ + (*(void (*)(char **, npy_intp const *, npy_intp const *, void *)) \ + PyUFunc_API[21]) +#define PyUFunc_O_O_method \ + (*(void (*)(char **, npy_intp const *, npy_intp const *, void *)) \ + PyUFunc_API[22]) +#define PyUFunc_OO_O_method \ + (*(void (*)(char **, npy_intp const *, npy_intp const *, void *)) \ + PyUFunc_API[23]) +#define PyUFunc_On_Om \ + (*(void (*)(char **, npy_intp const *, npy_intp const *, void *)) \ + PyUFunc_API[24]) +#define PyUFunc_GetPyValues \ + (*(int (*)(char *, int *, int *, PyObject **)) \ + PyUFunc_API[25]) +#define PyUFunc_checkfperr \ + (*(int (*)(int, PyObject *, int *)) \ + PyUFunc_API[26]) +#define PyUFunc_clearfperr \ + (*(void (*)(void)) \ + PyUFunc_API[27]) +#define PyUFunc_getfperr \ + (*(int (*)(void)) \ + PyUFunc_API[28]) +#define PyUFunc_handlefperr \ + (*(int (*)(int, PyObject *, int, int *)) \ + PyUFunc_API[29]) +#define PyUFunc_ReplaceLoopBySignature \ + (*(int (*)(PyUFuncObject *, PyUFuncGenericFunction, const int *, PyUFuncGenericFunction *)) \ + PyUFunc_API[30]) +#define PyUFunc_FromFuncAndDataAndSignature \ + (*(PyObject * (*)(PyUFuncGenericFunction *, void **, char *, int, int, int, int, const char *, const char *, int, const char *)) \ + PyUFunc_API[31]) +#define PyUFunc_SetUsesArraysAsData \ + (*(int (*)(void **, size_t)) \ + PyUFunc_API[32]) +#define PyUFunc_e_e \ + (*(void (*)(char **, npy_intp const *, npy_intp const *, void *)) \ + PyUFunc_API[33]) +#define PyUFunc_e_e_As_f_f \ + (*(void (*)(char **, npy_intp const *, npy_intp const *, void *)) \ + PyUFunc_API[34]) +#define PyUFunc_e_e_As_d_d \ + (*(void (*)(char **, npy_intp const *, npy_intp const *, void *)) \ + PyUFunc_API[35]) +#define PyUFunc_ee_e \ + (*(void (*)(char **, npy_intp const *, npy_intp const *, void *)) \ + PyUFunc_API[36]) +#define PyUFunc_ee_e_As_ff_f \ + (*(void (*)(char **, npy_intp const *, npy_intp const *, void *)) \ + PyUFunc_API[37]) +#define PyUFunc_ee_e_As_dd_d \ + (*(void (*)(char **, npy_intp const *, npy_intp const *, void *)) \ + PyUFunc_API[38]) +#define PyUFunc_DefaultTypeResolver \ + (*(int (*)(PyUFuncObject *, NPY_CASTING, PyArrayObject **, PyObject *, PyArray_Descr **)) \ + PyUFunc_API[39]) +#define PyUFunc_ValidateCasting \ + (*(int (*)(PyUFuncObject *, NPY_CASTING, PyArrayObject **, PyArray_Descr **)) \ + PyUFunc_API[40]) +#define PyUFunc_RegisterLoopForDescr \ + (*(int (*)(PyUFuncObject *, PyArray_Descr *, PyUFuncGenericFunction, PyArray_Descr **, void *)) \ + PyUFunc_API[41]) +#define PyUFunc_FromFuncAndDataAndSignatureAndIdentity \ + (*(PyObject * (*)(PyUFuncGenericFunction *, void **, char *, int, int, int, int, const char *, const char *, const int, const char *, PyObject *)) \ + PyUFunc_API[42]) + +static NPY_INLINE int +_import_umath(void) +{ + PyObject *numpy = PyImport_ImportModule("numpy.core._multiarray_umath"); + PyObject *c_api = NULL; + + if (numpy == NULL) { + PyErr_SetString(PyExc_ImportError, + "numpy.core._multiarray_umath failed to import"); + return -1; + } + c_api = PyObject_GetAttrString(numpy, "_UFUNC_API"); + Py_DECREF(numpy); + if (c_api == NULL) { + PyErr_SetString(PyExc_AttributeError, "_UFUNC_API not found"); + return -1; + } + + if (!PyCapsule_CheckExact(c_api)) { + PyErr_SetString(PyExc_RuntimeError, "_UFUNC_API is not PyCapsule object"); + Py_DECREF(c_api); + return -1; + } + PyUFunc_API = (void **)PyCapsule_GetPointer(c_api, NULL); + Py_DECREF(c_api); + if (PyUFunc_API == NULL) { + PyErr_SetString(PyExc_RuntimeError, "_UFUNC_API is NULL pointer"); + return -1; + } + return 0; +} + +#define import_umath() \ + do {\ + UFUNC_NOFPE\ + if (_import_umath() < 0) {\ + PyErr_Print();\ + PyErr_SetString(PyExc_ImportError,\ + "numpy.core.umath failed to import");\ + return NULL;\ + }\ + } while(0) + +#define import_umath1(ret) \ + do {\ + UFUNC_NOFPE\ + if (_import_umath() < 0) {\ + PyErr_Print();\ + PyErr_SetString(PyExc_ImportError,\ + "numpy.core.umath failed to import");\ + return ret;\ + }\ + } while(0) + +#define import_umath2(ret, msg) \ + do {\ + UFUNC_NOFPE\ + if (_import_umath() < 0) {\ + PyErr_Print();\ + PyErr_SetString(PyExc_ImportError, msg);\ + return ret;\ + }\ + } while(0) + +#define import_ufunc() \ + do {\ + UFUNC_NOFPE\ + if (_import_umath() < 0) {\ + PyErr_Print();\ + PyErr_SetString(PyExc_ImportError,\ + "numpy.core.umath failed to import");\ + }\ + } while(0) + +#endif diff --git a/venv/Lib/site-packages/numpy/core/include/numpy/_neighborhood_iterator_imp.h b/venv/Lib/site-packages/numpy/core/include/numpy/_neighborhood_iterator_imp.h new file mode 100644 index 0000000..e8860cb --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/include/numpy/_neighborhood_iterator_imp.h @@ -0,0 +1,90 @@ +#ifndef _NPY_INCLUDE_NEIGHBORHOOD_IMP +#error You should not include this header directly +#endif +/* + * Private API (here for inline) + */ +static NPY_INLINE int +_PyArrayNeighborhoodIter_IncrCoord(PyArrayNeighborhoodIterObject* iter); + +/* + * Update to next item of the iterator + * + * Note: this simply increment the coordinates vector, last dimension + * incremented first , i.e, for dimension 3 + * ... + * -1, -1, -1 + * -1, -1, 0 + * -1, -1, 1 + * .... + * -1, 0, -1 + * -1, 0, 0 + * .... + * 0, -1, -1 + * 0, -1, 0 + * .... + */ +#define _UPDATE_COORD_ITER(c) \ + wb = iter->coordinates[c] < iter->bounds[c][1]; \ + if (wb) { \ + iter->coordinates[c] += 1; \ + return 0; \ + } \ + else { \ + iter->coordinates[c] = iter->bounds[c][0]; \ + } + +static NPY_INLINE int +_PyArrayNeighborhoodIter_IncrCoord(PyArrayNeighborhoodIterObject* iter) +{ + npy_intp i, wb; + + for (i = iter->nd - 1; i >= 0; --i) { + _UPDATE_COORD_ITER(i) + } + + return 0; +} + +/* + * Version optimized for 2d arrays, manual loop unrolling + */ +static NPY_INLINE int +_PyArrayNeighborhoodIter_IncrCoord2D(PyArrayNeighborhoodIterObject* iter) +{ + npy_intp wb; + + _UPDATE_COORD_ITER(1) + _UPDATE_COORD_ITER(0) + + return 0; +} +#undef _UPDATE_COORD_ITER + +/* + * Advance to the next neighbour + */ +static NPY_INLINE int +PyArrayNeighborhoodIter_Next(PyArrayNeighborhoodIterObject* iter) +{ + _PyArrayNeighborhoodIter_IncrCoord (iter); + iter->dataptr = iter->translate((PyArrayIterObject*)iter, iter->coordinates); + + return 0; +} + +/* + * Reset functions + */ +static NPY_INLINE int +PyArrayNeighborhoodIter_Reset(PyArrayNeighborhoodIterObject* iter) +{ + npy_intp i; + + for (i = 0; i < iter->nd; ++i) { + iter->coordinates[i] = iter->bounds[i][0]; + } + iter->dataptr = iter->translate((PyArrayIterObject*)iter, iter->coordinates); + + return 0; +} diff --git a/venv/Lib/site-packages/numpy/core/include/numpy/_numpyconfig.h b/venv/Lib/site-packages/numpy/core/include/numpy/_numpyconfig.h new file mode 100644 index 0000000..3ddc405 --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/include/numpy/_numpyconfig.h @@ -0,0 +1,29 @@ +#define NPY_SIZEOF_SHORT SIZEOF_SHORT +#define NPY_SIZEOF_INT SIZEOF_INT +#define NPY_SIZEOF_LONG SIZEOF_LONG +#define NPY_SIZEOF_FLOAT 4 +#define NPY_SIZEOF_COMPLEX_FLOAT 8 +#define NPY_SIZEOF_DOUBLE 8 +#define NPY_SIZEOF_COMPLEX_DOUBLE 16 +#define NPY_SIZEOF_LONGDOUBLE 8 +#define NPY_SIZEOF_COMPLEX_LONGDOUBLE 16 +#define NPY_SIZEOF_PY_INTPTR_T 8 +#define NPY_SIZEOF_OFF_T 4 +#define NPY_SIZEOF_PY_LONG_LONG 8 +#define NPY_SIZEOF_LONGLONG 8 +#define NPY_NO_SIGNAL 1 +#define NPY_NO_SMP 0 +#define NPY_HAVE_DECL_ISNAN +#define NPY_HAVE_DECL_ISINF +#define NPY_HAVE_DECL_SIGNBIT +#define NPY_HAVE_DECL_ISFINITE +#define NPY_USE_C99_COMPLEX 1 +#define NPY_RELAXED_STRIDES_CHECKING 1 +#define NPY_USE_C99_FORMATS 1 +#define NPY_VISIBILITY_HIDDEN +#define NPY_ABI_VERSION 0x01000009 +#define NPY_API_VERSION 0x0000000E + +#ifndef __STDC_FORMAT_MACROS +#define __STDC_FORMAT_MACROS 1 +#endif diff --git a/venv/Lib/site-packages/numpy/core/include/numpy/arrayobject.h b/venv/Lib/site-packages/numpy/core/include/numpy/arrayobject.h new file mode 100644 index 0000000..4f46d6b --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/include/numpy/arrayobject.h @@ -0,0 +1,11 @@ +#ifndef Py_ARRAYOBJECT_H +#define Py_ARRAYOBJECT_H + +#include "ndarrayobject.h" +#include "npy_interrupt.h" + +#ifdef NPY_NO_PREFIX +#include "noprefix.h" +#endif + +#endif diff --git a/venv/Lib/site-packages/numpy/core/include/numpy/arrayscalars.h b/venv/Lib/site-packages/numpy/core/include/numpy/arrayscalars.h new file mode 100644 index 0000000..14a3198 --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/include/numpy/arrayscalars.h @@ -0,0 +1,182 @@ +#ifndef _NPY_ARRAYSCALARS_H_ +#define _NPY_ARRAYSCALARS_H_ + +#ifndef _MULTIARRAYMODULE +typedef struct { + PyObject_HEAD + npy_bool obval; +} PyBoolScalarObject; +#endif + + +typedef struct { + PyObject_HEAD + signed char obval; +} PyByteScalarObject; + + +typedef struct { + PyObject_HEAD + short obval; +} PyShortScalarObject; + + +typedef struct { + PyObject_HEAD + int obval; +} PyIntScalarObject; + + +typedef struct { + PyObject_HEAD + long obval; +} PyLongScalarObject; + + +typedef struct { + PyObject_HEAD + npy_longlong obval; +} PyLongLongScalarObject; + + +typedef struct { + PyObject_HEAD + unsigned char obval; +} PyUByteScalarObject; + + +typedef struct { + PyObject_HEAD + unsigned short obval; +} PyUShortScalarObject; + + +typedef struct { + PyObject_HEAD + unsigned int obval; +} PyUIntScalarObject; + + +typedef struct { + PyObject_HEAD + unsigned long obval; +} PyULongScalarObject; + + +typedef struct { + PyObject_HEAD + npy_ulonglong obval; +} PyULongLongScalarObject; + + +typedef struct { + PyObject_HEAD + npy_half obval; +} PyHalfScalarObject; + + +typedef struct { + PyObject_HEAD + float obval; +} PyFloatScalarObject; + + +typedef struct { + PyObject_HEAD + double obval; +} PyDoubleScalarObject; + + +typedef struct { + PyObject_HEAD + npy_longdouble obval; +} PyLongDoubleScalarObject; + + +typedef struct { + PyObject_HEAD + npy_cfloat obval; +} PyCFloatScalarObject; + + +typedef struct { + PyObject_HEAD + npy_cdouble obval; +} PyCDoubleScalarObject; + + +typedef struct { + PyObject_HEAD + npy_clongdouble obval; +} PyCLongDoubleScalarObject; + + +typedef struct { + PyObject_HEAD + PyObject * obval; +} PyObjectScalarObject; + +typedef struct { + PyObject_HEAD + npy_datetime obval; + PyArray_DatetimeMetaData obmeta; +} PyDatetimeScalarObject; + +typedef struct { + PyObject_HEAD + npy_timedelta obval; + PyArray_DatetimeMetaData obmeta; +} PyTimedeltaScalarObject; + + +typedef struct { + PyObject_HEAD + char obval; +} PyScalarObject; + +#define PyStringScalarObject PyBytesObject +typedef struct { + /* note that the PyObject_HEAD macro lives right here */ + PyUnicodeObject base; + Py_UCS4 *obval; + char *buffer_fmt; +} PyUnicodeScalarObject; + + +typedef struct { + PyObject_VAR_HEAD + char *obval; + PyArray_Descr *descr; + int flags; + PyObject *base; + void *_buffer_info; /* private buffer info, tagged to allow warning */ +} PyVoidScalarObject; + +/* Macros + PyScalarObject + PyArrType_Type + are defined in ndarrayobject.h +*/ + +#define PyArrayScalar_False ((PyObject *)(&(_PyArrayScalar_BoolValues[0]))) +#define PyArrayScalar_True ((PyObject *)(&(_PyArrayScalar_BoolValues[1]))) +#define PyArrayScalar_FromLong(i) \ + ((PyObject *)(&(_PyArrayScalar_BoolValues[((i)!=0)]))) +#define PyArrayScalar_RETURN_BOOL_FROM_LONG(i) \ + return Py_INCREF(PyArrayScalar_FromLong(i)), \ + PyArrayScalar_FromLong(i) +#define PyArrayScalar_RETURN_FALSE \ + return Py_INCREF(PyArrayScalar_False), \ + PyArrayScalar_False +#define PyArrayScalar_RETURN_TRUE \ + return Py_INCREF(PyArrayScalar_True), \ + PyArrayScalar_True + +#define PyArrayScalar_New(cls) \ + Py##cls##ArrType_Type.tp_alloc(&Py##cls##ArrType_Type, 0) +#define PyArrayScalar_VAL(obj, cls) \ + ((Py##cls##ScalarObject *)obj)->obval +#define PyArrayScalar_ASSIGN(obj, cls, val) \ + PyArrayScalar_VAL(obj, cls) = val + +#endif diff --git a/venv/Lib/site-packages/numpy/core/include/numpy/halffloat.h b/venv/Lib/site-packages/numpy/core/include/numpy/halffloat.h new file mode 100644 index 0000000..ab0d221 --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/include/numpy/halffloat.h @@ -0,0 +1,70 @@ +#ifndef __NPY_HALFFLOAT_H__ +#define __NPY_HALFFLOAT_H__ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Half-precision routines + */ + +/* Conversions */ +float npy_half_to_float(npy_half h); +double npy_half_to_double(npy_half h); +npy_half npy_float_to_half(float f); +npy_half npy_double_to_half(double d); +/* Comparisons */ +int npy_half_eq(npy_half h1, npy_half h2); +int npy_half_ne(npy_half h1, npy_half h2); +int npy_half_le(npy_half h1, npy_half h2); +int npy_half_lt(npy_half h1, npy_half h2); +int npy_half_ge(npy_half h1, npy_half h2); +int npy_half_gt(npy_half h1, npy_half h2); +/* faster *_nonan variants for when you know h1 and h2 are not NaN */ +int npy_half_eq_nonan(npy_half h1, npy_half h2); +int npy_half_lt_nonan(npy_half h1, npy_half h2); +int npy_half_le_nonan(npy_half h1, npy_half h2); +/* Miscellaneous functions */ +int npy_half_iszero(npy_half h); +int npy_half_isnan(npy_half h); +int npy_half_isinf(npy_half h); +int npy_half_isfinite(npy_half h); +int npy_half_signbit(npy_half h); +npy_half npy_half_copysign(npy_half x, npy_half y); +npy_half npy_half_spacing(npy_half h); +npy_half npy_half_nextafter(npy_half x, npy_half y); +npy_half npy_half_divmod(npy_half x, npy_half y, npy_half *modulus); + +/* + * Half-precision constants + */ + +#define NPY_HALF_ZERO (0x0000u) +#define NPY_HALF_PZERO (0x0000u) +#define NPY_HALF_NZERO (0x8000u) +#define NPY_HALF_ONE (0x3c00u) +#define NPY_HALF_NEGONE (0xbc00u) +#define NPY_HALF_PINF (0x7c00u) +#define NPY_HALF_NINF (0xfc00u) +#define NPY_HALF_NAN (0x7e00u) + +#define NPY_MAX_HALF (0x7bffu) + +/* + * Bit-level conversions + */ + +npy_uint16 npy_floatbits_to_halfbits(npy_uint32 f); +npy_uint16 npy_doublebits_to_halfbits(npy_uint64 d); +npy_uint32 npy_halfbits_to_floatbits(npy_uint16 h); +npy_uint64 npy_halfbits_to_doublebits(npy_uint16 h); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/venv/Lib/site-packages/numpy/core/include/numpy/multiarray_api.txt b/venv/Lib/site-packages/numpy/core/include/numpy/multiarray_api.txt new file mode 100644 index 0000000..6740556 --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/include/numpy/multiarray_api.txt @@ -0,0 +1,2474 @@ + +=========== +NumPy C-API +=========== +:: + + unsigned int + PyArray_GetNDArrayCVersion(void ) + + +Included at the very first so not auto-grabbed and thus not labeled. + +:: + + int + PyArray_SetNumericOps(PyObject *dict) + +Set internal structure with number functions that all arrays will use + +:: + + PyObject * + PyArray_GetNumericOps(void ) + +Get dictionary showing number functions that all arrays will use + +:: + + int + PyArray_INCREF(PyArrayObject *mp) + +For object arrays, increment all internal references. + +:: + + int + PyArray_XDECREF(PyArrayObject *mp) + +Decrement all internal references for object arrays. +(or arrays with object fields) + +:: + + void + PyArray_SetStringFunction(PyObject *op, int repr) + +Set the array print function to be a Python function. + +:: + + PyArray_Descr * + PyArray_DescrFromType(int type) + +Get the PyArray_Descr structure for a type. + +:: + + PyObject * + PyArray_TypeObjectFromType(int type) + +Get a typeobject from a type-number -- can return NULL. + +New reference + +:: + + char * + PyArray_Zero(PyArrayObject *arr) + +Get pointer to zero of correct type for array. + +:: + + char * + PyArray_One(PyArrayObject *arr) + +Get pointer to one of correct type for array + +:: + + PyObject * + PyArray_CastToType(PyArrayObject *arr, PyArray_Descr *dtype, int + is_f_order) + +For backward compatibility + +Cast an array using typecode structure. +steals reference to dtype --- cannot be NULL + +This function always makes a copy of arr, even if the dtype +doesn't change. + +:: + + int + PyArray_CastTo(PyArrayObject *out, PyArrayObject *mp) + +Cast to an already created array. + +:: + + int + PyArray_CastAnyTo(PyArrayObject *out, PyArrayObject *mp) + +Cast to an already created array. Arrays don't have to be "broadcastable" +Only requirement is they have the same number of elements. + +:: + + int + PyArray_CanCastSafely(int fromtype, int totype) + +Check the type coercion rules. + +:: + + npy_bool + PyArray_CanCastTo(PyArray_Descr *from, PyArray_Descr *to) + +leaves reference count alone --- cannot be NULL + +PyArray_CanCastTypeTo is equivalent to this, but adds a 'casting' +parameter. + +:: + + int + PyArray_ObjectType(PyObject *op, int minimum_type) + +Return the typecode of the array a Python object would be converted to + +Returns the type number the result should have, or NPY_NOTYPE on error. + +:: + + PyArray_Descr * + PyArray_DescrFromObject(PyObject *op, PyArray_Descr *mintype) + +new reference -- accepts NULL for mintype + +:: + + PyArrayObject ** + PyArray_ConvertToCommonType(PyObject *op, int *retn) + + +This function is only used in one place within NumPy and should +generally be avoided. It is provided mainly for backward compatibility. + +The user of the function has to free the returned array. + +:: + + PyArray_Descr * + PyArray_DescrFromScalar(PyObject *sc) + +Return descr object from array scalar. + +New reference + +:: + + PyArray_Descr * + PyArray_DescrFromTypeObject(PyObject *type) + + +:: + + npy_intp + PyArray_Size(PyObject *op) + +Compute the size of an array (in number of items) + +:: + + PyObject * + PyArray_Scalar(void *data, PyArray_Descr *descr, PyObject *base) + +Get scalar-equivalent to a region of memory described by a descriptor. + +:: + + PyObject * + PyArray_FromScalar(PyObject *scalar, PyArray_Descr *outcode) + +Get 0-dim array from scalar + +0-dim array from array-scalar object +always contains a copy of the data +unless outcode is NULL, it is of void type and the referrer does +not own it either. + +steals reference to outcode + +:: + + void + PyArray_ScalarAsCtype(PyObject *scalar, void *ctypeptr) + +Convert to c-type + +no error checking is performed -- ctypeptr must be same type as scalar +in case of flexible type, the data is not copied +into ctypeptr which is expected to be a pointer to pointer + +:: + + int + PyArray_CastScalarToCtype(PyObject *scalar, void + *ctypeptr, PyArray_Descr *outcode) + +Cast Scalar to c-type + +The output buffer must be large-enough to receive the value +Even for flexible types which is different from ScalarAsCtype +where only a reference for flexible types is returned + +This may not work right on narrow builds for NumPy unicode scalars. + +:: + + int + PyArray_CastScalarDirect(PyObject *scalar, PyArray_Descr + *indescr, void *ctypeptr, int outtype) + +Cast Scalar to c-type + +:: + + PyObject * + PyArray_ScalarFromObject(PyObject *object) + +Get an Array Scalar From a Python Object + +Returns NULL if unsuccessful but error is only set if another error occurred. +Currently only Numeric-like object supported. + +:: + + PyArray_VectorUnaryFunc * + PyArray_GetCastFunc(PyArray_Descr *descr, int type_num) + +Get a cast function to cast from the input descriptor to the +output type_number (must be a registered data-type). +Returns NULL if un-successful. + +:: + + PyObject * + PyArray_FromDims(int NPY_UNUSED(nd) , int *NPY_UNUSED(d) , int + NPY_UNUSED(type) ) + +Deprecated, use PyArray_SimpleNew instead. + +:: + + PyObject * + PyArray_FromDimsAndDataAndDescr(int NPY_UNUSED(nd) , int + *NPY_UNUSED(d) , PyArray_Descr + *descr, char *NPY_UNUSED(data) ) + +Deprecated, use PyArray_NewFromDescr instead. + +:: + + PyObject * + PyArray_FromAny(PyObject *op, PyArray_Descr *newtype, int + min_depth, int max_depth, int flags, PyObject + *context) + +Does not check for NPY_ARRAY_ENSURECOPY and NPY_ARRAY_NOTSWAPPED in flags +Steals a reference to newtype --- which can be NULL + +:: + + PyObject * + PyArray_EnsureArray(PyObject *op) + +This is a quick wrapper around +PyArray_FromAny(op, NULL, 0, 0, NPY_ARRAY_ENSUREARRAY, NULL) +that special cases Arrays and PyArray_Scalars up front +It *steals a reference* to the object +It also guarantees that the result is PyArray_Type +Because it decrefs op if any conversion needs to take place +so it can be used like PyArray_EnsureArray(some_function(...)) + +:: + + PyObject * + PyArray_EnsureAnyArray(PyObject *op) + + +:: + + PyObject * + PyArray_FromFile(FILE *fp, PyArray_Descr *dtype, npy_intp num, char + *sep) + + +Given a ``FILE *`` pointer ``fp``, and a ``PyArray_Descr``, return an +array corresponding to the data encoded in that file. + +The reference to `dtype` is stolen (it is possible that the passed in +dtype is not held on to). + +The number of elements to read is given as ``num``; if it is < 0, then +then as many as possible are read. + +If ``sep`` is NULL or empty, then binary data is assumed, else +text data, with ``sep`` as the separator between elements. Whitespace in +the separator matches any length of whitespace in the text, and a match +for whitespace around the separator is added. + +For memory-mapped files, use the buffer interface. No more data than +necessary is read by this routine. + +:: + + PyObject * + PyArray_FromString(char *data, npy_intp slen, PyArray_Descr + *dtype, npy_intp num, char *sep) + + +Given a pointer to a string ``data``, a string length ``slen``, and +a ``PyArray_Descr``, return an array corresponding to the data +encoded in that string. + +If the dtype is NULL, the default array type is used (double). +If non-null, the reference is stolen. + +If ``slen`` is < 0, then the end of string is used for text data. +It is an error for ``slen`` to be < 0 for binary data (since embedded NULLs +would be the norm). + +The number of elements to read is given as ``num``; if it is < 0, then +then as many as possible are read. + +If ``sep`` is NULL or empty, then binary data is assumed, else +text data, with ``sep`` as the separator between elements. Whitespace in +the separator matches any length of whitespace in the text, and a match +for whitespace around the separator is added. + +:: + + PyObject * + PyArray_FromBuffer(PyObject *buf, PyArray_Descr *type, npy_intp + count, npy_intp offset) + + +:: + + PyObject * + PyArray_FromIter(PyObject *obj, PyArray_Descr *dtype, npy_intp count) + + +steals a reference to dtype (which cannot be NULL) + +:: + + PyObject * + PyArray_Return(PyArrayObject *mp) + + +Return either an array or the appropriate Python object if the array +is 0d and matches a Python type. +steals reference to mp + +:: + + PyObject * + PyArray_GetField(PyArrayObject *self, PyArray_Descr *typed, int + offset) + +Get a subset of bytes from each element of the array +steals reference to typed, must not be NULL + +:: + + int + PyArray_SetField(PyArrayObject *self, PyArray_Descr *dtype, int + offset, PyObject *val) + +Set a subset of bytes from each element of the array +steals reference to dtype, must not be NULL + +:: + + PyObject * + PyArray_Byteswap(PyArrayObject *self, npy_bool inplace) + + +:: + + PyObject * + PyArray_Resize(PyArrayObject *self, PyArray_Dims *newshape, int + refcheck, NPY_ORDER NPY_UNUSED(order) ) + +Resize (reallocate data). Only works if nothing else is referencing this +array and it is contiguous. If refcheck is 0, then the reference count is +not checked and assumed to be 1. You still must own this data and have no +weak-references and no base object. + +:: + + int + PyArray_MoveInto(PyArrayObject *dst, PyArrayObject *src) + +Move the memory of one array into another, allowing for overlapping data. + +Returns 0 on success, negative on failure. + +:: + + int + PyArray_CopyInto(PyArrayObject *dst, PyArrayObject *src) + +Copy an Array into another array. +Broadcast to the destination shape if necessary. + +Returns 0 on success, -1 on failure. + +:: + + int + PyArray_CopyAnyInto(PyArrayObject *dst, PyArrayObject *src) + +Copy an Array into another array -- memory must not overlap +Does not require src and dest to have "broadcastable" shapes +(only the same number of elements). + +TODO: For NumPy 2.0, this could accept an order parameter which +only allows NPY_CORDER and NPY_FORDER. Could also rename +this to CopyAsFlat to make the name more intuitive. + +Returns 0 on success, -1 on error. + +:: + + int + PyArray_CopyObject(PyArrayObject *dest, PyObject *src_object) + + +:: + + PyObject * + PyArray_NewCopy(PyArrayObject *obj, NPY_ORDER order) + +Copy an array. + +:: + + PyObject * + PyArray_ToList(PyArrayObject *self) + +To List + +:: + + PyObject * + PyArray_ToString(PyArrayObject *self, NPY_ORDER order) + + +:: + + int + PyArray_ToFile(PyArrayObject *self, FILE *fp, char *sep, char *format) + +To File + +:: + + int + PyArray_Dump(PyObject *self, PyObject *file, int protocol) + + +:: + + PyObject * + PyArray_Dumps(PyObject *self, int protocol) + + +:: + + int + PyArray_ValidType(int type) + +Is the typenum valid? + +:: + + void + PyArray_UpdateFlags(PyArrayObject *ret, int flagmask) + +Update Several Flags at once. + +:: + + PyObject * + PyArray_New(PyTypeObject *subtype, int nd, npy_intp const *dims, int + type_num, npy_intp const *strides, void *data, int + itemsize, int flags, PyObject *obj) + +Generic new array creation routine. + +:: + + PyObject * + PyArray_NewFromDescr(PyTypeObject *subtype, PyArray_Descr *descr, int + nd, npy_intp const *dims, npy_intp const + *strides, void *data, int flags, PyObject *obj) + +Generic new array creation routine. + +steals a reference to descr. On failure or when dtype->subarray is +true, dtype will be decrefed. + +:: + + PyArray_Descr * + PyArray_DescrNew(PyArray_Descr *base) + +base cannot be NULL + +:: + + PyArray_Descr * + PyArray_DescrNewFromType(int type_num) + + +:: + + double + PyArray_GetPriority(PyObject *obj, double default_) + +Get Priority from object + +:: + + PyObject * + PyArray_IterNew(PyObject *obj) + +Get Iterator. + +:: + + PyObject* + PyArray_MultiIterNew(int n, ... ) + +Get MultiIterator, + +:: + + int + PyArray_PyIntAsInt(PyObject *o) + + +:: + + npy_intp + PyArray_PyIntAsIntp(PyObject *o) + + +:: + + int + PyArray_Broadcast(PyArrayMultiIterObject *mit) + + +:: + + void + PyArray_FillObjectArray(PyArrayObject *arr, PyObject *obj) + +Assumes contiguous + +:: + + int + PyArray_FillWithScalar(PyArrayObject *arr, PyObject *obj) + + +:: + + npy_bool + PyArray_CheckStrides(int elsize, int nd, npy_intp numbytes, npy_intp + offset, npy_intp const *dims, npy_intp const + *newstrides) + + +:: + + PyArray_Descr * + PyArray_DescrNewByteorder(PyArray_Descr *self, char newendian) + + +returns a copy of the PyArray_Descr structure with the byteorder +altered: +no arguments: The byteorder is swapped (in all subfields as well) +single argument: The byteorder is forced to the given state +(in all subfields as well) + +Valid states: ('big', '>') or ('little' or '<') +('native', or '=') + +If a descr structure with | is encountered it's own +byte-order is not changed but any fields are: + + +Deep bytorder change of a data-type descriptor +Leaves reference count of self unchanged --- does not DECREF self *** + +:: + + PyObject * + PyArray_IterAllButAxis(PyObject *obj, int *inaxis) + +Get Iterator that iterates over all but one axis (don't use this with +PyArray_ITER_GOTO1D). The axis will be over-written if negative +with the axis having the smallest stride. + +:: + + PyObject * + PyArray_CheckFromAny(PyObject *op, PyArray_Descr *descr, int + min_depth, int max_depth, int requires, PyObject + *context) + +steals a reference to descr -- accepts NULL + +:: + + PyObject * + PyArray_FromArray(PyArrayObject *arr, PyArray_Descr *newtype, int + flags) + +steals reference to newtype --- acc. NULL + +:: + + PyObject * + PyArray_FromInterface(PyObject *origin) + + +:: + + PyObject * + PyArray_FromStructInterface(PyObject *input) + + +:: + + PyObject * + PyArray_FromArrayAttr(PyObject *op, PyArray_Descr *typecode, PyObject + *context) + + +:: + + NPY_SCALARKIND + PyArray_ScalarKind(int typenum, PyArrayObject **arr) + +ScalarKind + +Returns the scalar kind of a type number, with an +optional tweak based on the scalar value itself. +If no scalar is provided, it returns INTPOS_SCALAR +for both signed and unsigned integers, otherwise +it checks the sign of any signed integer to choose +INTNEG_SCALAR when appropriate. + +:: + + int + PyArray_CanCoerceScalar(int thistype, int neededtype, NPY_SCALARKIND + scalar) + + +Determines whether the data type 'thistype', with +scalar kind 'scalar', can be coerced into 'neededtype'. + +:: + + PyObject * + PyArray_NewFlagsObject(PyObject *obj) + + +Get New ArrayFlagsObject + +:: + + npy_bool + PyArray_CanCastScalar(PyTypeObject *from, PyTypeObject *to) + +See if array scalars can be cast. + +TODO: For NumPy 2.0, add a NPY_CASTING parameter. + +:: + + int + PyArray_CompareUCS4(npy_ucs4 const *s1, npy_ucs4 const *s2, size_t + len) + + +:: + + int + PyArray_RemoveSmallest(PyArrayMultiIterObject *multi) + +Adjusts previously broadcasted iterators so that the axis with +the smallest sum of iterator strides is not iterated over. +Returns dimension which is smallest in the range [0,multi->nd). +A -1 is returned if multi->nd == 0. + +don't use with PyArray_ITER_GOTO1D because factors are not adjusted + +:: + + int + PyArray_ElementStrides(PyObject *obj) + + +:: + + void + PyArray_Item_INCREF(char *data, PyArray_Descr *descr) + +XINCREF all objects in a single array item. This is complicated for +structured datatypes where the position of objects needs to be extracted. +The function is execute recursively for each nested field or subarrays dtype +such as as `np.dtype([("field1", "O"), ("field2", "f,O", (3,2))])` + +:: + + void + PyArray_Item_XDECREF(char *data, PyArray_Descr *descr) + + +XDECREF all objects in a single array item. This is complicated for +structured datatypes where the position of objects needs to be extracted. +The function is execute recursively for each nested field or subarrays dtype +such as as `np.dtype([("field1", "O"), ("field2", "f,O", (3,2))])` + +:: + + PyObject * + PyArray_FieldNames(PyObject *fields) + +Return the tuple of ordered field names from a dictionary. + +:: + + PyObject * + PyArray_Transpose(PyArrayObject *ap, PyArray_Dims *permute) + +Return Transpose. + +:: + + PyObject * + PyArray_TakeFrom(PyArrayObject *self0, PyObject *indices0, int + axis, PyArrayObject *out, NPY_CLIPMODE clipmode) + +Take + +:: + + PyObject * + PyArray_PutTo(PyArrayObject *self, PyObject*values0, PyObject + *indices0, NPY_CLIPMODE clipmode) + +Put values into an array + +:: + + PyObject * + PyArray_PutMask(PyArrayObject *self, PyObject*values0, PyObject*mask0) + +Put values into an array according to a mask. + +:: + + PyObject * + PyArray_Repeat(PyArrayObject *aop, PyObject *op, int axis) + +Repeat the array. + +:: + + PyObject * + PyArray_Choose(PyArrayObject *ip, PyObject *op, PyArrayObject + *out, NPY_CLIPMODE clipmode) + + +:: + + int + PyArray_Sort(PyArrayObject *op, int axis, NPY_SORTKIND which) + +Sort an array in-place + +:: + + PyObject * + PyArray_ArgSort(PyArrayObject *op, int axis, NPY_SORTKIND which) + +ArgSort an array + +:: + + PyObject * + PyArray_SearchSorted(PyArrayObject *op1, PyObject *op2, NPY_SEARCHSIDE + side, PyObject *perm) + + +Search the sorted array op1 for the location of the items in op2. The +result is an array of indexes, one for each element in op2, such that if +the item were to be inserted in op1 just before that index the array +would still be in sorted order. + +Parameters +---------- +op1 : PyArrayObject * +Array to be searched, must be 1-D. +op2 : PyObject * +Array of items whose insertion indexes in op1 are wanted +side : {NPY_SEARCHLEFT, NPY_SEARCHRIGHT} +If NPY_SEARCHLEFT, return first valid insertion indexes +If NPY_SEARCHRIGHT, return last valid insertion indexes +perm : PyObject * +Permutation array that sorts op1 (optional) + +Returns +------- +ret : PyObject * +New reference to npy_intp array containing indexes where items in op2 +could be validly inserted into op1. NULL on error. + +Notes +----- +Binary search is used to find the indexes. + +:: + + PyObject * + PyArray_ArgMax(PyArrayObject *op, int axis, PyArrayObject *out) + +ArgMax + +:: + + PyObject * + PyArray_ArgMin(PyArrayObject *op, int axis, PyArrayObject *out) + +ArgMin + +:: + + PyObject * + PyArray_Reshape(PyArrayObject *self, PyObject *shape) + +Reshape + +:: + + PyObject * + PyArray_Newshape(PyArrayObject *self, PyArray_Dims *newdims, NPY_ORDER + order) + +New shape for an array + +:: + + PyObject * + PyArray_Squeeze(PyArrayObject *self) + + +return a new view of the array object with all of its unit-length +dimensions squeezed out if needed, otherwise +return the same array. + +:: + + PyObject * + PyArray_View(PyArrayObject *self, PyArray_Descr *type, PyTypeObject + *pytype) + +View +steals a reference to type -- accepts NULL + +:: + + PyObject * + PyArray_SwapAxes(PyArrayObject *ap, int a1, int a2) + +SwapAxes + +:: + + PyObject * + PyArray_Max(PyArrayObject *ap, int axis, PyArrayObject *out) + +Max + +:: + + PyObject * + PyArray_Min(PyArrayObject *ap, int axis, PyArrayObject *out) + +Min + +:: + + PyObject * + PyArray_Ptp(PyArrayObject *ap, int axis, PyArrayObject *out) + +Ptp + +:: + + PyObject * + PyArray_Mean(PyArrayObject *self, int axis, int rtype, PyArrayObject + *out) + +Mean + +:: + + PyObject * + PyArray_Trace(PyArrayObject *self, int offset, int axis1, int + axis2, int rtype, PyArrayObject *out) + +Trace + +:: + + PyObject * + PyArray_Diagonal(PyArrayObject *self, int offset, int axis1, int + axis2) + +Diagonal + +In NumPy versions prior to 1.7, this function always returned a copy of +the diagonal array. In 1.7, the code has been updated to compute a view +onto 'self', but it still copies this array before returning, as well as +setting the internal WARN_ON_WRITE flag. In a future version, it will +simply return a view onto self. + +:: + + PyObject * + PyArray_Clip(PyArrayObject *self, PyObject *min, PyObject + *max, PyArrayObject *out) + +Clip + +:: + + PyObject * + PyArray_Conjugate(PyArrayObject *self, PyArrayObject *out) + +Conjugate + +:: + + PyObject * + PyArray_Nonzero(PyArrayObject *self) + +Nonzero + +TODO: In NumPy 2.0, should make the iteration order a parameter. + +:: + + PyObject * + PyArray_Std(PyArrayObject *self, int axis, int rtype, PyArrayObject + *out, int variance) + +Set variance to 1 to by-pass square-root calculation and return variance +Std + +:: + + PyObject * + PyArray_Sum(PyArrayObject *self, int axis, int rtype, PyArrayObject + *out) + +Sum + +:: + + PyObject * + PyArray_CumSum(PyArrayObject *self, int axis, int rtype, PyArrayObject + *out) + +CumSum + +:: + + PyObject * + PyArray_Prod(PyArrayObject *self, int axis, int rtype, PyArrayObject + *out) + +Prod + +:: + + PyObject * + PyArray_CumProd(PyArrayObject *self, int axis, int + rtype, PyArrayObject *out) + +CumProd + +:: + + PyObject * + PyArray_All(PyArrayObject *self, int axis, PyArrayObject *out) + +All + +:: + + PyObject * + PyArray_Any(PyArrayObject *self, int axis, PyArrayObject *out) + +Any + +:: + + PyObject * + PyArray_Compress(PyArrayObject *self, PyObject *condition, int + axis, PyArrayObject *out) + +Compress + +:: + + PyObject * + PyArray_Flatten(PyArrayObject *a, NPY_ORDER order) + +Flatten + +:: + + PyObject * + PyArray_Ravel(PyArrayObject *arr, NPY_ORDER order) + +Ravel +Returns a contiguous array + +:: + + npy_intp + PyArray_MultiplyList(npy_intp const *l1, int n) + +Multiply a List + +:: + + int + PyArray_MultiplyIntList(int const *l1, int n) + +Multiply a List of ints + +:: + + void * + PyArray_GetPtr(PyArrayObject *obj, npy_intp const*ind) + +Produce a pointer into array + +:: + + int + PyArray_CompareLists(npy_intp const *l1, npy_intp const *l2, int n) + +Compare Lists + +:: + + int + PyArray_AsCArray(PyObject **op, void *ptr, npy_intp *dims, int + nd, PyArray_Descr*typedescr) + +Simulate a C-array +steals a reference to typedescr -- can be NULL + +:: + + int + PyArray_As1D(PyObject **NPY_UNUSED(op) , char **NPY_UNUSED(ptr) , int + *NPY_UNUSED(d1) , int NPY_UNUSED(typecode) ) + +Convert to a 1D C-array + +:: + + int + PyArray_As2D(PyObject **NPY_UNUSED(op) , char ***NPY_UNUSED(ptr) , int + *NPY_UNUSED(d1) , int *NPY_UNUSED(d2) , int + NPY_UNUSED(typecode) ) + +Convert to a 2D C-array + +:: + + int + PyArray_Free(PyObject *op, void *ptr) + +Free pointers created if As2D is called + +:: + + int + PyArray_Converter(PyObject *object, PyObject **address) + + +Useful to pass as converter function for O& processing in PyArgs_ParseTuple. + +This conversion function can be used with the "O&" argument for +PyArg_ParseTuple. It will immediately return an object of array type +or will convert to a NPY_ARRAY_CARRAY any other object. + +If you use PyArray_Converter, you must DECREF the array when finished +as you get a new reference to it. + +:: + + int + PyArray_IntpFromSequence(PyObject *seq, npy_intp *vals, int maxvals) + +PyArray_IntpFromSequence +Returns the number of integers converted or -1 if an error occurred. +vals must be large enough to hold maxvals + +:: + + PyObject * + PyArray_Concatenate(PyObject *op, int axis) + +Concatenate + +Concatenate an arbitrary Python sequence into an array. +op is a python object supporting the sequence interface. +Its elements will be concatenated together to form a single +multidimensional array. If axis is NPY_MAXDIMS or bigger, then +each sequence object will be flattened before concatenation + +:: + + PyObject * + PyArray_InnerProduct(PyObject *op1, PyObject *op2) + +Numeric.innerproduct(a,v) + +:: + + PyObject * + PyArray_MatrixProduct(PyObject *op1, PyObject *op2) + +Numeric.matrixproduct(a,v) +just like inner product but does the swapaxes stuff on the fly + +:: + + PyObject * + PyArray_CopyAndTranspose(PyObject *op) + +Copy and Transpose + +Could deprecate this function, as there isn't a speed benefit over +calling Transpose and then Copy. + +:: + + PyObject * + PyArray_Correlate(PyObject *op1, PyObject *op2, int mode) + +Numeric.correlate(a1,a2,mode) + +:: + + int + PyArray_TypestrConvert(int itemsize, int gentype) + +Typestr converter + +:: + + int + PyArray_DescrConverter(PyObject *obj, PyArray_Descr **at) + +Get typenum from an object -- None goes to NPY_DEFAULT_TYPE +This function takes a Python object representing a type and converts it +to a the correct PyArray_Descr * structure to describe the type. + +Many objects can be used to represent a data-type which in NumPy is +quite a flexible concept. + +This is the central code that converts Python objects to +Type-descriptor objects that are used throughout numpy. + +Returns a new reference in *at, but the returned should not be +modified as it may be one of the canonical immutable objects or +a reference to the input obj. + +:: + + int + PyArray_DescrConverter2(PyObject *obj, PyArray_Descr **at) + +Get typenum from an object -- None goes to NULL + +:: + + int + PyArray_IntpConverter(PyObject *obj, PyArray_Dims *seq) + +Get intp chunk from sequence + +This function takes a Python sequence object and allocates and +fills in an intp array with the converted values. + +Remember to free the pointer seq.ptr when done using +PyDimMem_FREE(seq.ptr)** + +:: + + int + PyArray_BufferConverter(PyObject *obj, PyArray_Chunk *buf) + +Get buffer chunk from object + +this function takes a Python object which exposes the (single-segment) +buffer interface and returns a pointer to the data segment + +You should increment the reference count by one of buf->base +if you will hang on to a reference + +You only get a borrowed reference to the object. Do not free the +memory... + +:: + + int + PyArray_AxisConverter(PyObject *obj, int *axis) + +Get axis from an object (possibly None) -- a converter function, + +See also PyArray_ConvertMultiAxis, which also handles a tuple of axes. + +:: + + int + PyArray_BoolConverter(PyObject *object, npy_bool *val) + +Convert an object to true / false + +:: + + int + PyArray_ByteorderConverter(PyObject *obj, char *endian) + +Convert object to endian + +:: + + int + PyArray_OrderConverter(PyObject *object, NPY_ORDER *val) + +Convert an object to FORTRAN / C / ANY / KEEP + +:: + + unsigned char + PyArray_EquivTypes(PyArray_Descr *type1, PyArray_Descr *type2) + + +This function returns true if the two typecodes are +equivalent (same basic kind and same itemsize). + +:: + + PyObject * + PyArray_Zeros(int nd, npy_intp const *dims, PyArray_Descr *type, int + is_f_order) + +Zeros + +steals a reference to type. On failure or when dtype->subarray is +true, dtype will be decrefed. +accepts NULL type + +:: + + PyObject * + PyArray_Empty(int nd, npy_intp const *dims, PyArray_Descr *type, int + is_f_order) + +Empty + +accepts NULL type +steals a reference to type + +:: + + PyObject * + PyArray_Where(PyObject *condition, PyObject *x, PyObject *y) + +Where + +:: + + PyObject * + PyArray_Arange(double start, double stop, double step, int type_num) + +Arange, + +:: + + PyObject * + PyArray_ArangeObj(PyObject *start, PyObject *stop, PyObject + *step, PyArray_Descr *dtype) + + +ArangeObj, + +this doesn't change the references + +:: + + int + PyArray_SortkindConverter(PyObject *obj, NPY_SORTKIND *sortkind) + +Convert object to sort kind + +:: + + PyObject * + PyArray_LexSort(PyObject *sort_keys, int axis) + +LexSort an array providing indices that will sort a collection of arrays +lexicographically. The first key is sorted on first, followed by the second key +-- requires that arg"merge"sort is available for each sort_key + +Returns an index array that shows the indexes for the lexicographic sort along +the given axis. + +:: + + PyObject * + PyArray_Round(PyArrayObject *a, int decimals, PyArrayObject *out) + +Round + +:: + + unsigned char + PyArray_EquivTypenums(int typenum1, int typenum2) + + +:: + + int + PyArray_RegisterDataType(PyArray_Descr *descr) + +Register Data type +Does not change the reference count of descr + +:: + + int + PyArray_RegisterCastFunc(PyArray_Descr *descr, int + totype, PyArray_VectorUnaryFunc *castfunc) + +Register Casting Function +Replaces any function currently stored. + +:: + + int + PyArray_RegisterCanCast(PyArray_Descr *descr, int + totype, NPY_SCALARKIND scalar) + +Register a type number indicating that a descriptor can be cast +to it safely + +:: + + void + PyArray_InitArrFuncs(PyArray_ArrFuncs *f) + +Initialize arrfuncs to NULL + +:: + + PyObject * + PyArray_IntTupleFromIntp(int len, npy_intp const *vals) + +PyArray_IntTupleFromIntp + +:: + + int + PyArray_TypeNumFromName(char const *str) + + +:: + + int + PyArray_ClipmodeConverter(PyObject *object, NPY_CLIPMODE *val) + +Convert an object to NPY_RAISE / NPY_CLIP / NPY_WRAP + +:: + + int + PyArray_OutputConverter(PyObject *object, PyArrayObject **address) + +Useful to pass as converter function for O& processing in +PyArgs_ParseTuple for output arrays + +:: + + PyObject * + PyArray_BroadcastToShape(PyObject *obj, npy_intp *dims, int nd) + +Get Iterator broadcast to a particular shape + +:: + + void + _PyArray_SigintHandler(int signum) + + +:: + + void* + _PyArray_GetSigintBuf(void ) + + +:: + + int + PyArray_DescrAlignConverter(PyObject *obj, PyArray_Descr **at) + + +Get type-descriptor from an object forcing alignment if possible +None goes to DEFAULT type. + +any object with the .fields attribute and/or .itemsize attribute (if the +.fields attribute does not give the total size -- i.e. a partial record +naming). If itemsize is given it must be >= size computed from fields + +The .fields attribute must return a convertible dictionary if present. +Result inherits from NPY_VOID. + +:: + + int + PyArray_DescrAlignConverter2(PyObject *obj, PyArray_Descr **at) + + +Get type-descriptor from an object forcing alignment if possible +None goes to NULL. + +:: + + int + PyArray_SearchsideConverter(PyObject *obj, void *addr) + +Convert object to searchsorted side + +:: + + PyObject * + PyArray_CheckAxis(PyArrayObject *arr, int *axis, int flags) + +PyArray_CheckAxis + +check that axis is valid +convert 0-d arrays to 1-d arrays + +:: + + npy_intp + PyArray_OverflowMultiplyList(npy_intp const *l1, int n) + +Multiply a List of Non-negative numbers with over-flow detection. + +:: + + int + PyArray_CompareString(const char *s1, const char *s2, size_t len) + + +:: + + PyObject* + PyArray_MultiIterFromObjects(PyObject **mps, int n, int nadd, ... ) + +Get MultiIterator from array of Python objects and any additional + +PyObject **mps - array of PyObjects +int n - number of PyObjects in the array +int nadd - number of additional arrays to include in the iterator. + +Returns a multi-iterator object. + +:: + + int + PyArray_GetEndianness(void ) + + +:: + + unsigned int + PyArray_GetNDArrayCFeatureVersion(void ) + +Returns the built-in (at compilation time) C API version + +:: + + PyObject * + PyArray_Correlate2(PyObject *op1, PyObject *op2, int mode) + +correlate(a1,a2,mode) + +This function computes the usual correlation (correlate(a1, a2) != +correlate(a2, a1), and conjugate the second argument for complex inputs + +:: + + PyObject* + PyArray_NeighborhoodIterNew(PyArrayIterObject *x, const npy_intp + *bounds, int mode, PyArrayObject*fill) + +A Neighborhood Iterator object. + +:: + + void + PyArray_SetDatetimeParseFunction(PyObject *NPY_UNUSED(op) ) + +This function is scheduled to be removed + +TO BE REMOVED - NOT USED INTERNALLY. + +:: + + void + PyArray_DatetimeToDatetimeStruct(npy_datetime NPY_UNUSED(val) + , NPY_DATETIMEUNIT NPY_UNUSED(fr) + , npy_datetimestruct *result) + +Fill the datetime struct from the value and resolution unit. + +TO BE REMOVED - NOT USED INTERNALLY. + +:: + + void + PyArray_TimedeltaToTimedeltaStruct(npy_timedelta NPY_UNUSED(val) + , NPY_DATETIMEUNIT NPY_UNUSED(fr) + , npy_timedeltastruct *result) + +Fill the timedelta struct from the timedelta value and resolution unit. + +TO BE REMOVED - NOT USED INTERNALLY. + +:: + + npy_datetime + PyArray_DatetimeStructToDatetime(NPY_DATETIMEUNIT NPY_UNUSED(fr) + , npy_datetimestruct *NPY_UNUSED(d) ) + +Create a datetime value from a filled datetime struct and resolution unit. + +TO BE REMOVED - NOT USED INTERNALLY. + +:: + + npy_datetime + PyArray_TimedeltaStructToTimedelta(NPY_DATETIMEUNIT NPY_UNUSED(fr) + , npy_timedeltastruct + *NPY_UNUSED(d) ) + +Create a timdelta value from a filled timedelta struct and resolution unit. + +TO BE REMOVED - NOT USED INTERNALLY. + +:: + + NpyIter * + NpyIter_New(PyArrayObject *op, npy_uint32 flags, NPY_ORDER + order, NPY_CASTING casting, PyArray_Descr*dtype) + +Allocate a new iterator for one array object. + +:: + + NpyIter * + NpyIter_MultiNew(int nop, PyArrayObject **op_in, npy_uint32 + flags, NPY_ORDER order, NPY_CASTING + casting, npy_uint32 *op_flags, PyArray_Descr + **op_request_dtypes) + +Allocate a new iterator for more than one array object, using +standard NumPy broadcasting rules and the default buffer size. + +:: + + NpyIter * + NpyIter_AdvancedNew(int nop, PyArrayObject **op_in, npy_uint32 + flags, NPY_ORDER order, NPY_CASTING + casting, npy_uint32 *op_flags, PyArray_Descr + **op_request_dtypes, int oa_ndim, int + **op_axes, npy_intp *itershape, npy_intp + buffersize) + +Allocate a new iterator for multiple array objects, and advanced +options for controlling the broadcasting, shape, and buffer size. + +:: + + NpyIter * + NpyIter_Copy(NpyIter *iter) + +Makes a copy of the iterator + +:: + + int + NpyIter_Deallocate(NpyIter *iter) + +Deallocate an iterator. + +To correctly work when an error is in progress, we have to check +`PyErr_Occurred()`. This is necessary when buffers are not finalized +or WritebackIfCopy is used. We could avoid that check by exposing a new +function which is passed in whether or not a Python error is already set. + +:: + + npy_bool + NpyIter_HasDelayedBufAlloc(NpyIter *iter) + +Whether the buffer allocation is being delayed + +:: + + npy_bool + NpyIter_HasExternalLoop(NpyIter *iter) + +Whether the iterator handles the inner loop + +:: + + int + NpyIter_EnableExternalLoop(NpyIter *iter) + +Removes the inner loop handling (so HasExternalLoop returns true) + +:: + + npy_intp * + NpyIter_GetInnerStrideArray(NpyIter *iter) + +Get the array of strides for the inner loop (when HasExternalLoop is true) + +This function may be safely called without holding the Python GIL. + +:: + + npy_intp * + NpyIter_GetInnerLoopSizePtr(NpyIter *iter) + +Get a pointer to the size of the inner loop (when HasExternalLoop is true) + +This function may be safely called without holding the Python GIL. + +:: + + int + NpyIter_Reset(NpyIter *iter, char **errmsg) + +Resets the iterator to its initial state + +The use of errmsg is discouraged, it cannot be guaranteed that the GIL +will not be grabbed on casting errors even when this is passed. + +If errmsg is non-NULL, it should point to a variable which will +receive the error message, and no Python exception will be set. +This is so that the function can be called from code not holding +the GIL. Note that cast errors may still lead to the GIL being +grabbed temporarily. + +:: + + int + NpyIter_ResetBasePointers(NpyIter *iter, char **baseptrs, char + **errmsg) + +Resets the iterator to its initial state, with new base data pointers. +This function requires great caution. + +If errmsg is non-NULL, it should point to a variable which will +receive the error message, and no Python exception will be set. +This is so that the function can be called from code not holding +the GIL. Note that cast errors may still lead to the GIL being +grabbed temporarily. + +:: + + int + NpyIter_ResetToIterIndexRange(NpyIter *iter, npy_intp istart, npy_intp + iend, char **errmsg) + +Resets the iterator to a new iterator index range + +If errmsg is non-NULL, it should point to a variable which will +receive the error message, and no Python exception will be set. +This is so that the function can be called from code not holding +the GIL. Note that cast errors may still lead to the GIL being +grabbed temporarily. + +:: + + int + NpyIter_GetNDim(NpyIter *iter) + +Gets the number of dimensions being iterated + +:: + + int + NpyIter_GetNOp(NpyIter *iter) + +Gets the number of operands being iterated + +:: + + NpyIter_IterNextFunc * + NpyIter_GetIterNext(NpyIter *iter, char **errmsg) + +Compute the specialized iteration function for an iterator + +If errmsg is non-NULL, it should point to a variable which will +receive the error message, and no Python exception will be set. +This is so that the function can be called from code not holding +the GIL. + +:: + + npy_intp + NpyIter_GetIterSize(NpyIter *iter) + +Gets the number of elements being iterated + +:: + + void + NpyIter_GetIterIndexRange(NpyIter *iter, npy_intp *istart, npy_intp + *iend) + +Gets the range of iteration indices being iterated + +:: + + npy_intp + NpyIter_GetIterIndex(NpyIter *iter) + +Gets the current iteration index + +:: + + int + NpyIter_GotoIterIndex(NpyIter *iter, npy_intp iterindex) + +Sets the iterator position to the specified iterindex, +which matches the iteration order of the iterator. + +Returns NPY_SUCCEED on success, NPY_FAIL on failure. + +:: + + npy_bool + NpyIter_HasMultiIndex(NpyIter *iter) + +Whether the iterator is tracking a multi-index + +:: + + int + NpyIter_GetShape(NpyIter *iter, npy_intp *outshape) + +Gets the broadcast shape if a multi-index is being tracked by the iterator, +otherwise gets the shape of the iteration as Fortran-order +(fastest-changing index first). + +The reason Fortran-order is returned when a multi-index +is not enabled is that this is providing a direct view into how +the iterator traverses the n-dimensional space. The iterator organizes +its memory from fastest index to slowest index, and when +a multi-index is enabled, it uses a permutation to recover the original +order. + +Returns NPY_SUCCEED or NPY_FAIL. + +:: + + NpyIter_GetMultiIndexFunc * + NpyIter_GetGetMultiIndex(NpyIter *iter, char **errmsg) + +Compute a specialized get_multi_index function for the iterator + +If errmsg is non-NULL, it should point to a variable which will +receive the error message, and no Python exception will be set. +This is so that the function can be called from code not holding +the GIL. + +:: + + int + NpyIter_GotoMultiIndex(NpyIter *iter, npy_intp const *multi_index) + +Sets the iterator to the specified multi-index, which must have the +correct number of entries for 'ndim'. It is only valid +when NPY_ITER_MULTI_INDEX was passed to the constructor. This operation +fails if the multi-index is out of bounds. + +Returns NPY_SUCCEED on success, NPY_FAIL on failure. + +:: + + int + NpyIter_RemoveMultiIndex(NpyIter *iter) + +Removes multi-index support from an iterator. + +Returns NPY_SUCCEED or NPY_FAIL. + +:: + + npy_bool + NpyIter_HasIndex(NpyIter *iter) + +Whether the iterator is tracking an index + +:: + + npy_bool + NpyIter_IsBuffered(NpyIter *iter) + +Whether the iterator is buffered + +:: + + npy_bool + NpyIter_IsGrowInner(NpyIter *iter) + +Whether the inner loop can grow if buffering is unneeded + +:: + + npy_intp + NpyIter_GetBufferSize(NpyIter *iter) + +Gets the size of the buffer, or 0 if buffering is not enabled + +:: + + npy_intp * + NpyIter_GetIndexPtr(NpyIter *iter) + +Get a pointer to the index, if it is being tracked + +:: + + int + NpyIter_GotoIndex(NpyIter *iter, npy_intp flat_index) + +If the iterator is tracking an index, sets the iterator +to the specified index. + +Returns NPY_SUCCEED on success, NPY_FAIL on failure. + +:: + + char ** + NpyIter_GetDataPtrArray(NpyIter *iter) + +Get the array of data pointers (1 per object being iterated) + +This function may be safely called without holding the Python GIL. + +:: + + PyArray_Descr ** + NpyIter_GetDescrArray(NpyIter *iter) + +Get the array of data type pointers (1 per object being iterated) + +:: + + PyArrayObject ** + NpyIter_GetOperandArray(NpyIter *iter) + +Get the array of objects being iterated + +:: + + PyArrayObject * + NpyIter_GetIterView(NpyIter *iter, npy_intp i) + +Returns a view to the i-th object with the iterator's internal axes + +:: + + void + NpyIter_GetReadFlags(NpyIter *iter, char *outreadflags) + +Gets an array of read flags (1 per object being iterated) + +:: + + void + NpyIter_GetWriteFlags(NpyIter *iter, char *outwriteflags) + +Gets an array of write flags (1 per object being iterated) + +:: + + void + NpyIter_DebugPrint(NpyIter *iter) + +For debugging + +:: + + npy_bool + NpyIter_IterationNeedsAPI(NpyIter *iter) + +Whether the iteration loop, and in particular the iternext() +function, needs API access. If this is true, the GIL must +be retained while iterating. + +:: + + void + NpyIter_GetInnerFixedStrideArray(NpyIter *iter, npy_intp *out_strides) + +Get an array of strides which are fixed. Any strides which may +change during iteration receive the value NPY_MAX_INTP. Once +the iterator is ready to iterate, call this to get the strides +which will always be fixed in the inner loop, then choose optimized +inner loop functions which take advantage of those fixed strides. + +This function may be safely called without holding the Python GIL. + +:: + + int + NpyIter_RemoveAxis(NpyIter *iter, int axis) + +Removes an axis from iteration. This requires that NPY_ITER_MULTI_INDEX +was set for iterator creation, and does not work if buffering is +enabled. This function also resets the iterator to its initial state. + +Returns NPY_SUCCEED or NPY_FAIL. + +:: + + npy_intp * + NpyIter_GetAxisStrideArray(NpyIter *iter, int axis) + +Gets the array of strides for the specified axis. +If the iterator is tracking a multi-index, gets the strides +for the axis specified, otherwise gets the strides for +the iteration axis as Fortran order (fastest-changing axis first). + +Returns NULL if an error occurs. + +:: + + npy_bool + NpyIter_RequiresBuffering(NpyIter *iter) + +Whether the iteration could be done with no buffering. + +:: + + char ** + NpyIter_GetInitialDataPtrArray(NpyIter *iter) + +Get the array of data pointers (1 per object being iterated), +directly into the arrays (never pointing to a buffer), for starting +unbuffered iteration. This always returns the addresses for the +iterator position as reset to iterator index 0. + +These pointers are different from the pointers accepted by +NpyIter_ResetBasePointers, because the direction along some +axes may have been reversed, requiring base offsets. + +This function may be safely called without holding the Python GIL. + +:: + + int + NpyIter_CreateCompatibleStrides(NpyIter *iter, npy_intp + itemsize, npy_intp *outstrides) + +Builds a set of strides which are the same as the strides of an +output array created using the NPY_ITER_ALLOCATE flag, where NULL +was passed for op_axes. This is for data packed contiguously, +but not necessarily in C or Fortran order. This should be used +together with NpyIter_GetShape and NpyIter_GetNDim. + +A use case for this function is to match the shape and layout of +the iterator and tack on one or more dimensions. For example, +in order to generate a vector per input value for a numerical gradient, +you pass in ndim*itemsize for itemsize, then add another dimension to +the end with size ndim and stride itemsize. To do the Hessian matrix, +you do the same thing but add two dimensions, or take advantage of +the symmetry and pack it into 1 dimension with a particular encoding. + +This function may only be called if the iterator is tracking a multi-index +and if NPY_ITER_DONT_NEGATE_STRIDES was used to prevent an axis from +being iterated in reverse order. + +If an array is created with this method, simply adding 'itemsize' +for each iteration will traverse the new array matching the +iterator. + +Returns NPY_SUCCEED or NPY_FAIL. + +:: + + int + PyArray_CastingConverter(PyObject *obj, NPY_CASTING *casting) + +Convert any Python object, *obj*, to an NPY_CASTING enum. + +:: + + npy_intp + PyArray_CountNonzero(PyArrayObject *self) + +Counts the number of non-zero elements in the array. + +Returns -1 on error. + +:: + + PyArray_Descr * + PyArray_PromoteTypes(PyArray_Descr *type1, PyArray_Descr *type2) + +Produces the smallest size and lowest kind type to which both +input types can be cast. + +:: + + PyArray_Descr * + PyArray_MinScalarType(PyArrayObject *arr) + +If arr is a scalar (has 0 dimensions) with a built-in number data type, +finds the smallest type size/kind which can still represent its data. +Otherwise, returns the array's data type. + + +:: + + PyArray_Descr * + PyArray_ResultType(npy_intp narrs, PyArrayObject **arr, npy_intp + ndtypes, PyArray_Descr **dtypes) + +Produces the result type of a bunch of inputs, using the UFunc +type promotion rules. Use this function when you have a set of +input arrays, and need to determine an output array dtype. + +If all the inputs are scalars (have 0 dimensions) or the maximum "kind" +of the scalars is greater than the maximum "kind" of the arrays, does +a regular type promotion. + +Otherwise, does a type promotion on the MinScalarType +of all the inputs. Data types passed directly are treated as array +types. + + +:: + + npy_bool + PyArray_CanCastArrayTo(PyArrayObject *arr, PyArray_Descr + *to, NPY_CASTING casting) + +Returns 1 if the array object may be cast to the given data type using +the casting rule, 0 otherwise. This differs from PyArray_CanCastTo in +that it handles scalar arrays (0 dimensions) specially, by checking +their value. + +:: + + npy_bool + PyArray_CanCastTypeTo(PyArray_Descr *from, PyArray_Descr + *to, NPY_CASTING casting) + +Returns true if data of type 'from' may be cast to data of type +'to' according to the rule 'casting'. + +:: + + PyArrayObject * + PyArray_EinsteinSum(char *subscripts, npy_intp nop, PyArrayObject + **op_in, PyArray_Descr *dtype, NPY_ORDER + order, NPY_CASTING casting, PyArrayObject *out) + +This function provides summation of array elements according to +the Einstein summation convention. For example: +- trace(a) -> einsum("ii", a) +- transpose(a) -> einsum("ji", a) +- multiply(a,b) -> einsum(",", a, b) +- inner(a,b) -> einsum("i,i", a, b) +- outer(a,b) -> einsum("i,j", a, b) +- matvec(a,b) -> einsum("ij,j", a, b) +- matmat(a,b) -> einsum("ij,jk", a, b) + +subscripts: The string of subscripts for einstein summation. +nop: The number of operands +op_in: The array of operands +dtype: Either NULL, or the data type to force the calculation as. +order: The order for the calculation/the output axes. +casting: What kind of casts should be permitted. +out: Either NULL, or an array into which the output should be placed. + +By default, the labels get placed in alphabetical order +at the end of the output. So, if c = einsum("i,j", a, b) +then c[i,j] == a[i]*b[j], but if c = einsum("j,i", a, b) +then c[i,j] = a[j]*b[i]. + +Alternatively, you can control the output order or prevent +an axis from being summed/force an axis to be summed by providing +indices for the output. This allows us to turn 'trace' into +'diag', for example. +- diag(a) -> einsum("ii->i", a) +- sum(a, axis=0) -> einsum("i...->", a) + +Subscripts at the beginning and end may be specified by +putting an ellipsis "..." in the middle. For example, +the function einsum("i...i", a) takes the diagonal of +the first and last dimensions of the operand, and +einsum("ij...,jk...->ik...") takes the matrix product using +the first two indices of each operand instead of the last two. + +When there is only one operand, no axes being summed, and +no output parameter, this function returns a view +into the operand instead of making a copy. + +:: + + PyObject * + PyArray_NewLikeArray(PyArrayObject *prototype, NPY_ORDER + order, PyArray_Descr *dtype, int subok) + +Creates a new array with the same shape as the provided one, +with possible memory layout order and data type changes. + +prototype - The array the new one should be like. +order - NPY_CORDER - C-contiguous result. +NPY_FORTRANORDER - Fortran-contiguous result. +NPY_ANYORDER - Fortran if prototype is Fortran, C otherwise. +NPY_KEEPORDER - Keeps the axis ordering of prototype. +dtype - If not NULL, overrides the data type of the result. +subok - If 1, use the prototype's array subtype, otherwise +always create a base-class array. + +NOTE: If dtype is not NULL, steals the dtype reference. On failure or when +dtype->subarray is true, dtype will be decrefed. + +:: + + int + PyArray_GetArrayParamsFromObject(PyObject *NPY_UNUSED(op) + , PyArray_Descr + *NPY_UNUSED(requested_dtype) + , npy_bool NPY_UNUSED(writeable) + , PyArray_Descr + **NPY_UNUSED(out_dtype) , int + *NPY_UNUSED(out_ndim) , npy_intp + *NPY_UNUSED(out_dims) , PyArrayObject + **NPY_UNUSED(out_arr) , PyObject + *NPY_UNUSED(context) ) + + +:: + + int + PyArray_ConvertClipmodeSequence(PyObject *object, NPY_CLIPMODE + *modes, int n) + +Convert an object to an array of n NPY_CLIPMODE values. +This is intended to be used in functions where a different mode +could be applied to each axis, like in ravel_multi_index. + +:: + + PyObject * + PyArray_MatrixProduct2(PyObject *op1, PyObject + *op2, PyArrayObject*out) + +Numeric.matrixproduct2(a,v,out) +just like inner product but does the swapaxes stuff on the fly + +:: + + npy_bool + NpyIter_IsFirstVisit(NpyIter *iter, int iop) + +Checks to see whether this is the first time the elements +of the specified reduction operand which the iterator points at are +being seen for the first time. The function returns +a reasonable answer for reduction operands and when buffering is +disabled. The answer may be incorrect for buffered non-reduction +operands. + +This function is intended to be used in EXTERNAL_LOOP mode only, +and will produce some wrong answers when that mode is not enabled. + +If this function returns true, the caller should also +check the inner loop stride of the operand, because if +that stride is 0, then only the first element of the innermost +external loop is being visited for the first time. + +WARNING: For performance reasons, 'iop' is not bounds-checked, +it is not confirmed that 'iop' is actually a reduction +operand, and it is not confirmed that EXTERNAL_LOOP +mode is enabled. These checks are the responsibility of +the caller, and should be done outside of any inner loops. + +:: + + int + PyArray_SetBaseObject(PyArrayObject *arr, PyObject *obj) + +Sets the 'base' attribute of the array. This steals a reference +to 'obj'. + +Returns 0 on success, -1 on failure. + +:: + + void + PyArray_CreateSortedStridePerm(int ndim, npy_intp const + *strides, npy_stride_sort_item + *out_strideperm) + + +This function populates the first ndim elements +of strideperm with sorted descending by their absolute values. +For example, the stride array (4, -2, 12) becomes +[(2, 12), (0, 4), (1, -2)]. + +:: + + void + PyArray_RemoveAxesInPlace(PyArrayObject *arr, const npy_bool *flags) + + +Removes the axes flagged as True from the array, +modifying it in place. If an axis flagged for removal +has a shape entry bigger than one, this effectively selects +index zero for that axis. + +WARNING: If an axis flagged for removal has a shape equal to zero, +the array will point to invalid memory. The caller must +validate this! +If an axis flagged for removal has a shape larger than one, +the aligned flag (and in the future the contiguous flags), +may need explicit update. +(check also NPY_RELAXED_STRIDES_CHECKING) + +For example, this can be used to remove the reduction axes +from a reduction result once its computation is complete. + +:: + + void + PyArray_DebugPrint(PyArrayObject *obj) + +Prints the raw data of the ndarray in a form useful for debugging +low-level C issues. + +:: + + int + PyArray_FailUnlessWriteable(PyArrayObject *obj, const char *name) + + +This function does nothing if obj is writeable, and raises an exception +(and returns -1) if obj is not writeable. It may also do other +house-keeping, such as issuing warnings on arrays which are transitioning +to become views. Always call this function at some point before writing to +an array. + +'name' is a name for the array, used to give better error +messages. Something like "assignment destination", "output array", or even +just "array". + +:: + + int + PyArray_SetUpdateIfCopyBase(PyArrayObject *arr, PyArrayObject *base) + + +Precondition: 'arr' is a copy of 'base' (though possibly with different +strides, ordering, etc.). This function sets the UPDATEIFCOPY flag and the +->base pointer on 'arr', so that when 'arr' is destructed, it will copy any +changes back to 'base'. DEPRECATED, use PyArray_SetWritebackIfCopyBase + +Steals a reference to 'base'. + +Returns 0 on success, -1 on failure. + +:: + + void * + PyDataMem_NEW(size_t size) + +Allocates memory for array data. + +:: + + void + PyDataMem_FREE(void *ptr) + +Free memory for array data. + +:: + + void * + PyDataMem_RENEW(void *ptr, size_t size) + +Reallocate/resize memory for array data. + +:: + + PyDataMem_EventHookFunc * + PyDataMem_SetEventHook(PyDataMem_EventHookFunc *newhook, void + *user_data, void **old_data) + +Sets the allocation event hook for numpy array data. +Takes a PyDataMem_EventHookFunc *, which has the signature: +void hook(void *old, void *new, size_t size, void *user_data). +Also takes a void *user_data, and void **old_data. + +Returns a pointer to the previous hook or NULL. If old_data is +non-NULL, the previous user_data pointer will be copied to it. + +If not NULL, hook will be called at the end of each PyDataMem_NEW/FREE/RENEW: +result = PyDataMem_NEW(size) -> (*hook)(NULL, result, size, user_data) +PyDataMem_FREE(ptr) -> (*hook)(ptr, NULL, 0, user_data) +result = PyDataMem_RENEW(ptr, size) -> (*hook)(ptr, result, size, user_data) + +When the hook is called, the GIL will be held by the calling +thread. The hook should be written to be reentrant, if it performs +operations that might cause new allocation events (such as the +creation/destruction numpy objects, or creating/destroying Python +objects which might cause a gc) + +:: + + void + PyArray_MapIterSwapAxes(PyArrayMapIterObject *mit, PyArrayObject + **ret, int getmap) + + +:: + + PyObject * + PyArray_MapIterArray(PyArrayObject *a, PyObject *index) + + +Use advanced indexing to iterate an array. + +:: + + void + PyArray_MapIterNext(PyArrayMapIterObject *mit) + +This function needs to update the state of the map iterator +and point mit->dataptr to the memory-location of the next object + +Note that this function never handles an extra operand but provides +compatibility for an old (exposed) API. + +:: + + int + PyArray_Partition(PyArrayObject *op, PyArrayObject *ktharray, int + axis, NPY_SELECTKIND which) + +Partition an array in-place + +:: + + PyObject * + PyArray_ArgPartition(PyArrayObject *op, PyArrayObject *ktharray, int + axis, NPY_SELECTKIND which) + +ArgPartition an array + +:: + + int + PyArray_SelectkindConverter(PyObject *obj, NPY_SELECTKIND *selectkind) + +Convert object to select kind + +:: + + void * + PyDataMem_NEW_ZEROED(size_t size, size_t elsize) + +Allocates zeroed memory for array data. + +:: + + int + PyArray_CheckAnyScalarExact(PyObject *obj) + +return true an object is exactly a numpy scalar + +:: + + PyObject * + PyArray_MapIterArrayCopyIfOverlap(PyArrayObject *a, PyObject + *index, int + copy_if_overlap, PyArrayObject + *extra_op) + + +Same as PyArray_MapIterArray, but: + +If copy_if_overlap != 0, check if `a` has memory overlap with any of the +arrays in `index` and with `extra_op`. If yes, make copies as appropriate +to avoid problems if `a` is modified during the iteration. +`iter->array` may contain a copied array (UPDATEIFCOPY/WRITEBACKIFCOPY set). + +:: + + int + PyArray_ResolveWritebackIfCopy(PyArrayObject *self) + + +If WRITEBACKIFCOPY and self has data, reset the base WRITEABLE flag, +copy the local data to base, release the local data, and set flags +appropriately. Return 0 if not relevant, 1 if success, < 0 on failure + +:: + + int + PyArray_SetWritebackIfCopyBase(PyArrayObject *arr, PyArrayObject + *base) + + +Precondition: 'arr' is a copy of 'base' (though possibly with different +strides, ordering, etc.). This function sets the WRITEBACKIFCOPY flag and the +->base pointer on 'arr', call PyArray_ResolveWritebackIfCopy to copy any +changes back to 'base' before deallocating the array. + +Steals a reference to 'base'. + +Returns 0 on success, -1 on failure. + diff --git a/venv/Lib/site-packages/numpy/core/include/numpy/ndarrayobject.h b/venv/Lib/site-packages/numpy/core/include/numpy/ndarrayobject.h new file mode 100644 index 0000000..5ef1f10 --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/include/numpy/ndarrayobject.h @@ -0,0 +1,268 @@ +/* + * DON'T INCLUDE THIS DIRECTLY. + */ + +#ifndef NPY_NDARRAYOBJECT_H +#define NPY_NDARRAYOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "ndarraytypes.h" + +/* Includes the "function" C-API -- these are all stored in a + list of pointers --- one for each file + The two lists are concatenated into one in multiarray. + + They are available as import_array() +*/ + +#include "__multiarray_api.h" + + +/* C-API that requires previous API to be defined */ + +#define PyArray_DescrCheck(op) PyObject_TypeCheck(op, &PyArrayDescr_Type) + +#define PyArray_Check(op) PyObject_TypeCheck(op, &PyArray_Type) +#define PyArray_CheckExact(op) (((PyObject*)(op))->ob_type == &PyArray_Type) + +#define PyArray_HasArrayInterfaceType(op, type, context, out) \ + ((((out)=PyArray_FromStructInterface(op)) != Py_NotImplemented) || \ + (((out)=PyArray_FromInterface(op)) != Py_NotImplemented) || \ + (((out)=PyArray_FromArrayAttr(op, type, context)) != \ + Py_NotImplemented)) + +#define PyArray_HasArrayInterface(op, out) \ + PyArray_HasArrayInterfaceType(op, NULL, NULL, out) + +#define PyArray_IsZeroDim(op) (PyArray_Check(op) && \ + (PyArray_NDIM((PyArrayObject *)op) == 0)) + +#define PyArray_IsScalar(obj, cls) \ + (PyObject_TypeCheck(obj, &Py##cls##ArrType_Type)) + +#define PyArray_CheckScalar(m) (PyArray_IsScalar(m, Generic) || \ + PyArray_IsZeroDim(m)) +#define PyArray_IsPythonNumber(obj) \ + (PyFloat_Check(obj) || PyComplex_Check(obj) || \ + PyLong_Check(obj) || PyBool_Check(obj)) +#define PyArray_IsIntegerScalar(obj) (PyLong_Check(obj) \ + || PyArray_IsScalar((obj), Integer)) +#define PyArray_IsPythonScalar(obj) \ + (PyArray_IsPythonNumber(obj) || PyBytes_Check(obj) || \ + PyUnicode_Check(obj)) + +#define PyArray_IsAnyScalar(obj) \ + (PyArray_IsScalar(obj, Generic) || PyArray_IsPythonScalar(obj)) + +#define PyArray_CheckAnyScalar(obj) (PyArray_IsPythonScalar(obj) || \ + PyArray_CheckScalar(obj)) + + +#define PyArray_GETCONTIGUOUS(m) (PyArray_ISCONTIGUOUS(m) ? \ + Py_INCREF(m), (m) : \ + (PyArrayObject *)(PyArray_Copy(m))) + +#define PyArray_SAMESHAPE(a1,a2) ((PyArray_NDIM(a1) == PyArray_NDIM(a2)) && \ + PyArray_CompareLists(PyArray_DIMS(a1), \ + PyArray_DIMS(a2), \ + PyArray_NDIM(a1))) + +#define PyArray_SIZE(m) PyArray_MultiplyList(PyArray_DIMS(m), PyArray_NDIM(m)) +#define PyArray_NBYTES(m) (PyArray_ITEMSIZE(m) * PyArray_SIZE(m)) +#define PyArray_FROM_O(m) PyArray_FromAny(m, NULL, 0, 0, 0, NULL) + +#define PyArray_FROM_OF(m,flags) PyArray_CheckFromAny(m, NULL, 0, 0, flags, \ + NULL) + +#define PyArray_FROM_OT(m,type) PyArray_FromAny(m, \ + PyArray_DescrFromType(type), 0, 0, 0, NULL) + +#define PyArray_FROM_OTF(m, type, flags) \ + PyArray_FromAny(m, PyArray_DescrFromType(type), 0, 0, \ + (((flags) & NPY_ARRAY_ENSURECOPY) ? \ + ((flags) | NPY_ARRAY_DEFAULT) : (flags)), NULL) + +#define PyArray_FROMANY(m, type, min, max, flags) \ + PyArray_FromAny(m, PyArray_DescrFromType(type), min, max, \ + (((flags) & NPY_ARRAY_ENSURECOPY) ? \ + (flags) | NPY_ARRAY_DEFAULT : (flags)), NULL) + +#define PyArray_ZEROS(m, dims, type, is_f_order) \ + PyArray_Zeros(m, dims, PyArray_DescrFromType(type), is_f_order) + +#define PyArray_EMPTY(m, dims, type, is_f_order) \ + PyArray_Empty(m, dims, PyArray_DescrFromType(type), is_f_order) + +#define PyArray_FILLWBYTE(obj, val) memset(PyArray_DATA(obj), val, \ + PyArray_NBYTES(obj)) +#ifndef PYPY_VERSION +#define PyArray_REFCOUNT(obj) (((PyObject *)(obj))->ob_refcnt) +#define NPY_REFCOUNT PyArray_REFCOUNT +#endif +#define NPY_MAX_ELSIZE (2 * NPY_SIZEOF_LONGDOUBLE) + +#define PyArray_ContiguousFromAny(op, type, min_depth, max_depth) \ + PyArray_FromAny(op, PyArray_DescrFromType(type), min_depth, \ + max_depth, NPY_ARRAY_DEFAULT, NULL) + +#define PyArray_EquivArrTypes(a1, a2) \ + PyArray_EquivTypes(PyArray_DESCR(a1), PyArray_DESCR(a2)) + +#define PyArray_EquivByteorders(b1, b2) \ + (((b1) == (b2)) || (PyArray_ISNBO(b1) == PyArray_ISNBO(b2))) + +#define PyArray_SimpleNew(nd, dims, typenum) \ + PyArray_New(&PyArray_Type, nd, dims, typenum, NULL, NULL, 0, 0, NULL) + +#define PyArray_SimpleNewFromData(nd, dims, typenum, data) \ + PyArray_New(&PyArray_Type, nd, dims, typenum, NULL, \ + data, 0, NPY_ARRAY_CARRAY, NULL) + +#define PyArray_SimpleNewFromDescr(nd, dims, descr) \ + PyArray_NewFromDescr(&PyArray_Type, descr, nd, dims, \ + NULL, NULL, 0, NULL) + +#define PyArray_ToScalar(data, arr) \ + PyArray_Scalar(data, PyArray_DESCR(arr), (PyObject *)arr) + + +/* These might be faster without the dereferencing of obj + going on inside -- of course an optimizing compiler should + inline the constants inside a for loop making it a moot point +*/ + +#define PyArray_GETPTR1(obj, i) ((void *)(PyArray_BYTES(obj) + \ + (i)*PyArray_STRIDES(obj)[0])) + +#define PyArray_GETPTR2(obj, i, j) ((void *)(PyArray_BYTES(obj) + \ + (i)*PyArray_STRIDES(obj)[0] + \ + (j)*PyArray_STRIDES(obj)[1])) + +#define PyArray_GETPTR3(obj, i, j, k) ((void *)(PyArray_BYTES(obj) + \ + (i)*PyArray_STRIDES(obj)[0] + \ + (j)*PyArray_STRIDES(obj)[1] + \ + (k)*PyArray_STRIDES(obj)[2])) + +#define PyArray_GETPTR4(obj, i, j, k, l) ((void *)(PyArray_BYTES(obj) + \ + (i)*PyArray_STRIDES(obj)[0] + \ + (j)*PyArray_STRIDES(obj)[1] + \ + (k)*PyArray_STRIDES(obj)[2] + \ + (l)*PyArray_STRIDES(obj)[3])) + +/* Move to arrayobject.c once PyArray_XDECREF_ERR is removed */ +static NPY_INLINE void +PyArray_DiscardWritebackIfCopy(PyArrayObject *arr) +{ + PyArrayObject_fields *fa = (PyArrayObject_fields *)arr; + if (fa && fa->base) { + if ((fa->flags & NPY_ARRAY_UPDATEIFCOPY) || + (fa->flags & NPY_ARRAY_WRITEBACKIFCOPY)) { + PyArray_ENABLEFLAGS((PyArrayObject*)fa->base, NPY_ARRAY_WRITEABLE); + Py_DECREF(fa->base); + fa->base = NULL; + PyArray_CLEARFLAGS(arr, NPY_ARRAY_WRITEBACKIFCOPY); + PyArray_CLEARFLAGS(arr, NPY_ARRAY_UPDATEIFCOPY); + } + } +} + +#define PyArray_DESCR_REPLACE(descr) do { \ + PyArray_Descr *_new_; \ + _new_ = PyArray_DescrNew(descr); \ + Py_XDECREF(descr); \ + descr = _new_; \ + } while(0) + +/* Copy should always return contiguous array */ +#define PyArray_Copy(obj) PyArray_NewCopy(obj, NPY_CORDER) + +#define PyArray_FromObject(op, type, min_depth, max_depth) \ + PyArray_FromAny(op, PyArray_DescrFromType(type), min_depth, \ + max_depth, NPY_ARRAY_BEHAVED | \ + NPY_ARRAY_ENSUREARRAY, NULL) + +#define PyArray_ContiguousFromObject(op, type, min_depth, max_depth) \ + PyArray_FromAny(op, PyArray_DescrFromType(type), min_depth, \ + max_depth, NPY_ARRAY_DEFAULT | \ + NPY_ARRAY_ENSUREARRAY, NULL) + +#define PyArray_CopyFromObject(op, type, min_depth, max_depth) \ + PyArray_FromAny(op, PyArray_DescrFromType(type), min_depth, \ + max_depth, NPY_ARRAY_ENSURECOPY | \ + NPY_ARRAY_DEFAULT | \ + NPY_ARRAY_ENSUREARRAY, NULL) + +#define PyArray_Cast(mp, type_num) \ + PyArray_CastToType(mp, PyArray_DescrFromType(type_num), 0) + +#define PyArray_Take(ap, items, axis) \ + PyArray_TakeFrom(ap, items, axis, NULL, NPY_RAISE) + +#define PyArray_Put(ap, items, values) \ + PyArray_PutTo(ap, items, values, NPY_RAISE) + +/* Compatibility with old Numeric stuff -- don't use in new code */ + +#define PyArray_FromDimsAndData(nd, d, type, data) \ + PyArray_FromDimsAndDataAndDescr(nd, d, PyArray_DescrFromType(type), \ + data) + + +/* + Check to see if this key in the dictionary is the "title" + entry of the tuple (i.e. a duplicate dictionary entry in the fields + dict). +*/ + +static NPY_INLINE int +NPY_TITLE_KEY_check(PyObject *key, PyObject *value) +{ + PyObject *title; + if (PyTuple_Size(value) != 3) { + return 0; + } + title = PyTuple_GetItem(value, 2); + if (key == title) { + return 1; + } +#ifdef PYPY_VERSION + /* + * On PyPy, dictionary keys do not always preserve object identity. + * Fall back to comparison by value. + */ + if (PyUnicode_Check(title) && PyUnicode_Check(key)) { + return PyUnicode_Compare(title, key) == 0 ? 1 : 0; + } +#endif + return 0; +} + +/* Macro, for backward compat with "if NPY_TITLE_KEY(key, value) { ..." */ +#define NPY_TITLE_KEY(key, value) (NPY_TITLE_KEY_check((key), (value))) + +#define DEPRECATE(msg) PyErr_WarnEx(PyExc_DeprecationWarning,msg,1) +#define DEPRECATE_FUTUREWARNING(msg) PyErr_WarnEx(PyExc_FutureWarning,msg,1) + +#if !defined(NPY_NO_DEPRECATED_API) || \ + (NPY_NO_DEPRECATED_API < NPY_1_14_API_VERSION) +static NPY_INLINE void +PyArray_XDECREF_ERR(PyArrayObject *arr) +{ + /* 2017-Nov-10 1.14 */ + DEPRECATE("PyArray_XDECREF_ERR is deprecated, call " + "PyArray_DiscardWritebackIfCopy then Py_XDECREF instead"); + PyArray_DiscardWritebackIfCopy(arr); + Py_XDECREF(arr); +} +#endif + + +#ifdef __cplusplus +} +#endif + + +#endif /* NPY_NDARRAYOBJECT_H */ diff --git a/venv/Lib/site-packages/numpy/core/include/numpy/ndarraytypes.h b/venv/Lib/site-packages/numpy/core/include/numpy/ndarraytypes.h new file mode 100644 index 0000000..63e8bf9 --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/include/numpy/ndarraytypes.h @@ -0,0 +1,1960 @@ +#ifndef NDARRAYTYPES_H +#define NDARRAYTYPES_H + +#include "npy_common.h" +#include "npy_endian.h" +#include "npy_cpu.h" +#include "utils.h" + +#define NPY_NO_EXPORT NPY_VISIBILITY_HIDDEN + +/* Only use thread if configured in config and python supports it */ +#if defined WITH_THREAD && !NPY_NO_SMP + #define NPY_ALLOW_THREADS 1 +#else + #define NPY_ALLOW_THREADS 0 +#endif + +#ifndef __has_extension +#define __has_extension(x) 0 +#endif + +#if !defined(_NPY_NO_DEPRECATIONS) && \ + ((defined(__GNUC__)&& __GNUC__ >= 6) || \ + __has_extension(attribute_deprecated_with_message)) +#define NPY_ATTR_DEPRECATE(text) __attribute__ ((deprecated (text))) +#else +#define NPY_ATTR_DEPRECATE(text) +#endif + +/* + * There are several places in the code where an array of dimensions + * is allocated statically. This is the size of that static + * allocation. + * + * The array creation itself could have arbitrary dimensions but all + * the places where static allocation is used would need to be changed + * to dynamic (including inside of several structures) + */ + +#define NPY_MAXDIMS 32 +#define NPY_MAXARGS 32 + +/* Used for Converter Functions "O&" code in ParseTuple */ +#define NPY_FAIL 0 +#define NPY_SUCCEED 1 + +/* + * Binary compatibility version number. This number is increased + * whenever the C-API is changed such that binary compatibility is + * broken, i.e. whenever a recompile of extension modules is needed. + */ +#define NPY_VERSION NPY_ABI_VERSION + +/* + * Minor API version. This number is increased whenever a change is + * made to the C-API -- whether it breaks binary compatibility or not. + * Some changes, such as adding a function pointer to the end of the + * function table, can be made without breaking binary compatibility. + * In this case, only the NPY_FEATURE_VERSION (*not* NPY_VERSION) + * would be increased. Whenever binary compatibility is broken, both + * NPY_VERSION and NPY_FEATURE_VERSION should be increased. + */ +#define NPY_FEATURE_VERSION NPY_API_VERSION + +enum NPY_TYPES { NPY_BOOL=0, + NPY_BYTE, NPY_UBYTE, + NPY_SHORT, NPY_USHORT, + NPY_INT, NPY_UINT, + NPY_LONG, NPY_ULONG, + NPY_LONGLONG, NPY_ULONGLONG, + NPY_FLOAT, NPY_DOUBLE, NPY_LONGDOUBLE, + NPY_CFLOAT, NPY_CDOUBLE, NPY_CLONGDOUBLE, + NPY_OBJECT=17, + NPY_STRING, NPY_UNICODE, + NPY_VOID, + /* + * New 1.6 types appended, may be integrated + * into the above in 2.0. + */ + NPY_DATETIME, NPY_TIMEDELTA, NPY_HALF, + + NPY_NTYPES, + NPY_NOTYPE, + NPY_CHAR NPY_ATTR_DEPRECATE("Use NPY_STRING"), + NPY_USERDEF=256, /* leave room for characters */ + + /* The number of types not including the new 1.6 types */ + NPY_NTYPES_ABI_COMPATIBLE=21 +}; +#ifdef _MSC_VER +#pragma deprecated(NPY_CHAR) +#endif + +/* basetype array priority */ +#define NPY_PRIORITY 0.0 + +/* default subtype priority */ +#define NPY_SUBTYPE_PRIORITY 1.0 + +/* default scalar priority */ +#define NPY_SCALAR_PRIORITY -1000000.0 + +/* How many floating point types are there (excluding half) */ +#define NPY_NUM_FLOATTYPE 3 + +/* + * These characters correspond to the array type and the struct + * module + */ + +enum NPY_TYPECHAR { + NPY_BOOLLTR = '?', + NPY_BYTELTR = 'b', + NPY_UBYTELTR = 'B', + NPY_SHORTLTR = 'h', + NPY_USHORTLTR = 'H', + NPY_INTLTR = 'i', + NPY_UINTLTR = 'I', + NPY_LONGLTR = 'l', + NPY_ULONGLTR = 'L', + NPY_LONGLONGLTR = 'q', + NPY_ULONGLONGLTR = 'Q', + NPY_HALFLTR = 'e', + NPY_FLOATLTR = 'f', + NPY_DOUBLELTR = 'd', + NPY_LONGDOUBLELTR = 'g', + NPY_CFLOATLTR = 'F', + NPY_CDOUBLELTR = 'D', + NPY_CLONGDOUBLELTR = 'G', + NPY_OBJECTLTR = 'O', + NPY_STRINGLTR = 'S', + NPY_STRINGLTR2 = 'a', + NPY_UNICODELTR = 'U', + NPY_VOIDLTR = 'V', + NPY_DATETIMELTR = 'M', + NPY_TIMEDELTALTR = 'm', + NPY_CHARLTR = 'c', + + /* + * No Descriptor, just a define -- this let's + * Python users specify an array of integers + * large enough to hold a pointer on the + * platform + */ + NPY_INTPLTR = 'p', + NPY_UINTPLTR = 'P', + + /* + * These are for dtype 'kinds', not dtype 'typecodes' + * as the above are for. + */ + NPY_GENBOOLLTR ='b', + NPY_SIGNEDLTR = 'i', + NPY_UNSIGNEDLTR = 'u', + NPY_FLOATINGLTR = 'f', + NPY_COMPLEXLTR = 'c' +}; + +/* + * Changing this may break Numpy API compatibility + * due to changing offsets in PyArray_ArrFuncs, so be + * careful. Here we have reused the mergesort slot for + * any kind of stable sort, the actual implementation will + * depend on the data type. + */ +typedef enum { + NPY_QUICKSORT=0, + NPY_HEAPSORT=1, + NPY_MERGESORT=2, + NPY_STABLESORT=2, +} NPY_SORTKIND; +#define NPY_NSORTS (NPY_STABLESORT + 1) + + +typedef enum { + NPY_INTROSELECT=0 +} NPY_SELECTKIND; +#define NPY_NSELECTS (NPY_INTROSELECT + 1) + + +typedef enum { + NPY_SEARCHLEFT=0, + NPY_SEARCHRIGHT=1 +} NPY_SEARCHSIDE; +#define NPY_NSEARCHSIDES (NPY_SEARCHRIGHT + 1) + + +typedef enum { + NPY_NOSCALAR=-1, + NPY_BOOL_SCALAR, + NPY_INTPOS_SCALAR, + NPY_INTNEG_SCALAR, + NPY_FLOAT_SCALAR, + NPY_COMPLEX_SCALAR, + NPY_OBJECT_SCALAR +} NPY_SCALARKIND; +#define NPY_NSCALARKINDS (NPY_OBJECT_SCALAR + 1) + +/* For specifying array memory layout or iteration order */ +typedef enum { + /* Fortran order if inputs are all Fortran, C otherwise */ + NPY_ANYORDER=-1, + /* C order */ + NPY_CORDER=0, + /* Fortran order */ + NPY_FORTRANORDER=1, + /* An order as close to the inputs as possible */ + NPY_KEEPORDER=2 +} NPY_ORDER; + +/* For specifying allowed casting in operations which support it */ +typedef enum { + _NPY_ERROR_OCCURRED_IN_CAST = -1, + /* Only allow identical types */ + NPY_NO_CASTING=0, + /* Allow identical and byte swapped types */ + NPY_EQUIV_CASTING=1, + /* Only allow safe casts */ + NPY_SAFE_CASTING=2, + /* Allow safe casts or casts within the same kind */ + NPY_SAME_KIND_CASTING=3, + /* Allow any casts */ + NPY_UNSAFE_CASTING=4, + /* + * Flag to allow signalling that a cast is a view, this flag is not + * valid when requesting a cast of specific safety. + * _NPY_CAST_IS_VIEW|NPY_EQUIV_CASTING means the same as NPY_NO_CASTING. + */ + // TODO-DTYPES: Needs to be documented. + _NPY_CAST_IS_VIEW = 1 << 16, +} NPY_CASTING; + +typedef enum { + NPY_CLIP=0, + NPY_WRAP=1, + NPY_RAISE=2 +} NPY_CLIPMODE; + +/* The special not-a-time (NaT) value */ +#define NPY_DATETIME_NAT NPY_MIN_INT64 + +/* + * Upper bound on the length of a DATETIME ISO 8601 string + * YEAR: 21 (64-bit year) + * MONTH: 3 + * DAY: 3 + * HOURS: 3 + * MINUTES: 3 + * SECONDS: 3 + * ATTOSECONDS: 1 + 3*6 + * TIMEZONE: 5 + * NULL TERMINATOR: 1 + */ +#define NPY_DATETIME_MAX_ISO8601_STRLEN (21 + 3*5 + 1 + 3*6 + 6 + 1) + +/* The FR in the unit names stands for frequency */ +typedef enum { + /* Force signed enum type, must be -1 for code compatibility */ + NPY_FR_ERROR = -1, /* error or undetermined */ + + /* Start of valid units */ + NPY_FR_Y = 0, /* Years */ + NPY_FR_M = 1, /* Months */ + NPY_FR_W = 2, /* Weeks */ + /* Gap where 1.6 NPY_FR_B (value 3) was */ + NPY_FR_D = 4, /* Days */ + NPY_FR_h = 5, /* hours */ + NPY_FR_m = 6, /* minutes */ + NPY_FR_s = 7, /* seconds */ + NPY_FR_ms = 8, /* milliseconds */ + NPY_FR_us = 9, /* microseconds */ + NPY_FR_ns = 10, /* nanoseconds */ + NPY_FR_ps = 11, /* picoseconds */ + NPY_FR_fs = 12, /* femtoseconds */ + NPY_FR_as = 13, /* attoseconds */ + NPY_FR_GENERIC = 14 /* unbound units, can convert to anything */ +} NPY_DATETIMEUNIT; + +/* + * NOTE: With the NPY_FR_B gap for 1.6 ABI compatibility, NPY_DATETIME_NUMUNITS + * is technically one more than the actual number of units. + */ +#define NPY_DATETIME_NUMUNITS (NPY_FR_GENERIC + 1) +#define NPY_DATETIME_DEFAULTUNIT NPY_FR_GENERIC + +/* + * Business day conventions for mapping invalid business + * days to valid business days. + */ +typedef enum { + /* Go forward in time to the following business day. */ + NPY_BUSDAY_FORWARD, + NPY_BUSDAY_FOLLOWING = NPY_BUSDAY_FORWARD, + /* Go backward in time to the preceding business day. */ + NPY_BUSDAY_BACKWARD, + NPY_BUSDAY_PRECEDING = NPY_BUSDAY_BACKWARD, + /* + * Go forward in time to the following business day, unless it + * crosses a month boundary, in which case go backward + */ + NPY_BUSDAY_MODIFIEDFOLLOWING, + /* + * Go backward in time to the preceding business day, unless it + * crosses a month boundary, in which case go forward. + */ + NPY_BUSDAY_MODIFIEDPRECEDING, + /* Produce a NaT for non-business days. */ + NPY_BUSDAY_NAT, + /* Raise an exception for non-business days. */ + NPY_BUSDAY_RAISE +} NPY_BUSDAY_ROLL; + +/************************************************************ + * NumPy Auxiliary Data for inner loops, sort functions, etc. + ************************************************************/ + +/* + * When creating an auxiliary data struct, this should always appear + * as the first member, like this: + * + * typedef struct { + * NpyAuxData base; + * double constant; + * } constant_multiplier_aux_data; + */ +typedef struct NpyAuxData_tag NpyAuxData; + +/* Function pointers for freeing or cloning auxiliary data */ +typedef void (NpyAuxData_FreeFunc) (NpyAuxData *); +typedef NpyAuxData *(NpyAuxData_CloneFunc) (NpyAuxData *); + +struct NpyAuxData_tag { + NpyAuxData_FreeFunc *free; + NpyAuxData_CloneFunc *clone; + /* To allow for a bit of expansion without breaking the ABI */ + void *reserved[2]; +}; + +/* Macros to use for freeing and cloning auxiliary data */ +#define NPY_AUXDATA_FREE(auxdata) \ + do { \ + if ((auxdata) != NULL) { \ + (auxdata)->free(auxdata); \ + } \ + } while(0) +#define NPY_AUXDATA_CLONE(auxdata) \ + ((auxdata)->clone(auxdata)) + +#define NPY_ERR(str) fprintf(stderr, #str); fflush(stderr); +#define NPY_ERR2(str) fprintf(stderr, str); fflush(stderr); + + /* + * Macros to define how array, and dimension/strides data is + * allocated. + */ + + /* Data buffer - PyDataMem_NEW/FREE/RENEW are in multiarraymodule.c */ + +#define NPY_USE_PYMEM 1 + + +#if NPY_USE_PYMEM == 1 +/* use the Raw versions which are safe to call with the GIL released */ +#define PyArray_malloc PyMem_RawMalloc +#define PyArray_free PyMem_RawFree +#define PyArray_realloc PyMem_RawRealloc +#else +#define PyArray_malloc malloc +#define PyArray_free free +#define PyArray_realloc realloc +#endif + +/* Dimensions and strides */ +#define PyDimMem_NEW(size) \ + ((npy_intp *)PyArray_malloc(size*sizeof(npy_intp))) + +#define PyDimMem_FREE(ptr) PyArray_free(ptr) + +#define PyDimMem_RENEW(ptr,size) \ + ((npy_intp *)PyArray_realloc(ptr,size*sizeof(npy_intp))) + +/* forward declaration */ +struct _PyArray_Descr; + +/* These must deal with unaligned and swapped data if necessary */ +typedef PyObject * (PyArray_GetItemFunc) (void *, void *); +typedef int (PyArray_SetItemFunc)(PyObject *, void *, void *); + +typedef void (PyArray_CopySwapNFunc)(void *, npy_intp, void *, npy_intp, + npy_intp, int, void *); + +typedef void (PyArray_CopySwapFunc)(void *, void *, int, void *); +typedef npy_bool (PyArray_NonzeroFunc)(void *, void *); + + +/* + * These assume aligned and notswapped data -- a buffer will be used + * before or contiguous data will be obtained + */ + +typedef int (PyArray_CompareFunc)(const void *, const void *, void *); +typedef int (PyArray_ArgFunc)(void*, npy_intp, npy_intp*, void *); + +typedef void (PyArray_DotFunc)(void *, npy_intp, void *, npy_intp, void *, + npy_intp, void *); + +typedef void (PyArray_VectorUnaryFunc)(void *, void *, npy_intp, void *, + void *); + +/* + * XXX the ignore argument should be removed next time the API version + * is bumped. It used to be the separator. + */ +typedef int (PyArray_ScanFunc)(FILE *fp, void *dptr, + char *ignore, struct _PyArray_Descr *); +typedef int (PyArray_FromStrFunc)(char *s, void *dptr, char **endptr, + struct _PyArray_Descr *); + +typedef int (PyArray_FillFunc)(void *, npy_intp, void *); + +typedef int (PyArray_SortFunc)(void *, npy_intp, void *); +typedef int (PyArray_ArgSortFunc)(void *, npy_intp *, npy_intp, void *); +typedef int (PyArray_PartitionFunc)(void *, npy_intp, npy_intp, + npy_intp *, npy_intp *, + void *); +typedef int (PyArray_ArgPartitionFunc)(void *, npy_intp *, npy_intp, npy_intp, + npy_intp *, npy_intp *, + void *); + +typedef int (PyArray_FillWithScalarFunc)(void *, npy_intp, void *, void *); + +typedef int (PyArray_ScalarKindFunc)(void *); + +typedef void (PyArray_FastClipFunc)(void *in, npy_intp n_in, void *min, + void *max, void *out); +typedef void (PyArray_FastPutmaskFunc)(void *in, void *mask, npy_intp n_in, + void *values, npy_intp nv); +typedef int (PyArray_FastTakeFunc)(void *dest, void *src, npy_intp *indarray, + npy_intp nindarray, npy_intp n_outer, + npy_intp m_middle, npy_intp nelem, + NPY_CLIPMODE clipmode); + +typedef struct { + npy_intp *ptr; + int len; +} PyArray_Dims; + +typedef struct { + /* + * Functions to cast to most other standard types + * Can have some NULL entries. The types + * DATETIME, TIMEDELTA, and HALF go into the castdict + * even though they are built-in. + */ + PyArray_VectorUnaryFunc *cast[NPY_NTYPES_ABI_COMPATIBLE]; + + /* The next four functions *cannot* be NULL */ + + /* + * Functions to get and set items with standard Python types + * -- not array scalars + */ + PyArray_GetItemFunc *getitem; + PyArray_SetItemFunc *setitem; + + /* + * Copy and/or swap data. Memory areas may not overlap + * Use memmove first if they might + */ + PyArray_CopySwapNFunc *copyswapn; + PyArray_CopySwapFunc *copyswap; + + /* + * Function to compare items + * Can be NULL + */ + PyArray_CompareFunc *compare; + + /* + * Function to select largest + * Can be NULL + */ + PyArray_ArgFunc *argmax; + + /* + * Function to compute dot product + * Can be NULL + */ + PyArray_DotFunc *dotfunc; + + /* + * Function to scan an ASCII file and + * place a single value plus possible separator + * Can be NULL + */ + PyArray_ScanFunc *scanfunc; + + /* + * Function to read a single value from a string + * and adjust the pointer; Can be NULL + */ + PyArray_FromStrFunc *fromstr; + + /* + * Function to determine if data is zero or not + * If NULL a default version is + * used at Registration time. + */ + PyArray_NonzeroFunc *nonzero; + + /* + * Used for arange. Should return 0 on success + * and -1 on failure. + * Can be NULL. + */ + PyArray_FillFunc *fill; + + /* + * Function to fill arrays with scalar values + * Can be NULL + */ + PyArray_FillWithScalarFunc *fillwithscalar; + + /* + * Sorting functions + * Can be NULL + */ + PyArray_SortFunc *sort[NPY_NSORTS]; + PyArray_ArgSortFunc *argsort[NPY_NSORTS]; + + /* + * Dictionary of additional casting functions + * PyArray_VectorUnaryFuncs + * which can be populated to support casting + * to other registered types. Can be NULL + */ + PyObject *castdict; + + /* + * Functions useful for generalizing + * the casting rules. + * Can be NULL; + */ + PyArray_ScalarKindFunc *scalarkind; + int **cancastscalarkindto; + int *cancastto; + + PyArray_FastClipFunc *fastclip; + PyArray_FastPutmaskFunc *fastputmask; + PyArray_FastTakeFunc *fasttake; + + /* + * Function to select smallest + * Can be NULL + */ + PyArray_ArgFunc *argmin; + +} PyArray_ArrFuncs; + +/* The item must be reference counted when it is inserted or extracted. */ +#define NPY_ITEM_REFCOUNT 0x01 +/* Same as needing REFCOUNT */ +#define NPY_ITEM_HASOBJECT 0x01 +/* Convert to list for pickling */ +#define NPY_LIST_PICKLE 0x02 +/* The item is a POINTER */ +#define NPY_ITEM_IS_POINTER 0x04 +/* memory needs to be initialized for this data-type */ +#define NPY_NEEDS_INIT 0x08 +/* operations need Python C-API so don't give-up thread. */ +#define NPY_NEEDS_PYAPI 0x10 +/* Use f.getitem when extracting elements of this data-type */ +#define NPY_USE_GETITEM 0x20 +/* Use f.setitem when setting creating 0-d array from this data-type.*/ +#define NPY_USE_SETITEM 0x40 +/* A sticky flag specifically for structured arrays */ +#define NPY_ALIGNED_STRUCT 0x80 + +/* + *These are inherited for global data-type if any data-types in the + * field have them + */ +#define NPY_FROM_FIELDS (NPY_NEEDS_INIT | NPY_LIST_PICKLE | \ + NPY_ITEM_REFCOUNT | NPY_NEEDS_PYAPI) + +#define NPY_OBJECT_DTYPE_FLAGS (NPY_LIST_PICKLE | NPY_USE_GETITEM | \ + NPY_ITEM_IS_POINTER | NPY_ITEM_REFCOUNT | \ + NPY_NEEDS_INIT | NPY_NEEDS_PYAPI) + +#define PyDataType_FLAGCHK(dtype, flag) \ + (((dtype)->flags & (flag)) == (flag)) + +#define PyDataType_REFCHK(dtype) \ + PyDataType_FLAGCHK(dtype, NPY_ITEM_REFCOUNT) + +typedef struct _PyArray_Descr { + PyObject_HEAD + /* + * the type object representing an + * instance of this type -- should not + * be two type_numbers with the same type + * object. + */ + PyTypeObject *typeobj; + /* kind for this type */ + char kind; + /* unique-character representing this type */ + char type; + /* + * '>' (big), '<' (little), '|' + * (not-applicable), or '=' (native). + */ + char byteorder; + /* flags describing data type */ + char flags; + /* number representing this type */ + int type_num; + /* element size (itemsize) for this type */ + int elsize; + /* alignment needed for this type */ + int alignment; + /* + * Non-NULL if this type is + * is an array (C-contiguous) + * of some other type + */ + struct _arr_descr *subarray; + /* + * The fields dictionary for this type + * For statically defined descr this + * is always Py_None + */ + PyObject *fields; + /* + * An ordered tuple of field names or NULL + * if no fields are defined + */ + PyObject *names; + /* + * a table of functions specific for each + * basic data descriptor + */ + PyArray_ArrFuncs *f; + /* Metadata about this dtype */ + PyObject *metadata; + /* + * Metadata specific to the C implementation + * of the particular dtype. This was added + * for NumPy 1.7.0. + */ + NpyAuxData *c_metadata; + /* Cached hash value (-1 if not yet computed). + * This was added for NumPy 2.0.0. + */ + npy_hash_t hash; +} PyArray_Descr; + +typedef struct _arr_descr { + PyArray_Descr *base; + PyObject *shape; /* a tuple */ +} PyArray_ArrayDescr; + +/* + * The main array object structure. + * + * It has been recommended to use the inline functions defined below + * (PyArray_DATA and friends) to access fields here for a number of + * releases. Direct access to the members themselves is deprecated. + * To ensure that your code does not use deprecated access, + * #define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION + * (or NPY_1_8_API_VERSION or higher as required). + */ +/* This struct will be moved to a private header in a future release */ +typedef struct tagPyArrayObject_fields { + PyObject_HEAD + /* Pointer to the raw data buffer */ + char *data; + /* The number of dimensions, also called 'ndim' */ + int nd; + /* The size in each dimension, also called 'shape' */ + npy_intp *dimensions; + /* + * Number of bytes to jump to get to the + * next element in each dimension + */ + npy_intp *strides; + /* + * This object is decref'd upon + * deletion of array. Except in the + * case of WRITEBACKIFCOPY which has + * special handling. + * + * For views it points to the original + * array, collapsed so no chains of + * views occur. + * + * For creation from buffer object it + * points to an object that should be + * decref'd on deletion + * + * For WRITEBACKIFCOPY flag this is an + * array to-be-updated upon calling + * PyArray_ResolveWritebackIfCopy + */ + PyObject *base; + /* Pointer to type structure */ + PyArray_Descr *descr; + /* Flags describing array -- see below */ + int flags; + /* For weak references */ + PyObject *weakreflist; + void *_buffer_info; /* private buffer info, tagged to allow warning */ +} PyArrayObject_fields; + +/* + * To hide the implementation details, we only expose + * the Python struct HEAD. + */ +#if !defined(NPY_NO_DEPRECATED_API) || \ + (NPY_NO_DEPRECATED_API < NPY_1_7_API_VERSION) +/* + * Can't put this in npy_deprecated_api.h like the others. + * PyArrayObject field access is deprecated as of NumPy 1.7. + */ +typedef PyArrayObject_fields PyArrayObject; +#else +typedef struct tagPyArrayObject { + PyObject_HEAD +} PyArrayObject; +#endif + +/* + * Removed 2020-Nov-25, NumPy 1.20 + * #define NPY_SIZEOF_PYARRAYOBJECT (sizeof(PyArrayObject_fields)) + * + * The above macro was removed as it gave a false sense of a stable ABI + * with respect to the structures size. If you require a runtime constant, + * you can use `PyArray_Type.tp_basicsize` instead. Otherwise, please + * see the PyArrayObject documentation or ask the NumPy developers for + * information on how to correctly replace the macro in a way that is + * compatible with multiple NumPy versions. + */ + + +/* Array Flags Object */ +typedef struct PyArrayFlagsObject { + PyObject_HEAD + PyObject *arr; + int flags; +} PyArrayFlagsObject; + +/* Mirrors buffer object to ptr */ + +typedef struct { + PyObject_HEAD + PyObject *base; + void *ptr; + npy_intp len; + int flags; +} PyArray_Chunk; + +typedef struct { + NPY_DATETIMEUNIT base; + int num; +} PyArray_DatetimeMetaData; + +typedef struct { + NpyAuxData base; + PyArray_DatetimeMetaData meta; +} PyArray_DatetimeDTypeMetaData; + +/* + * This structure contains an exploded view of a date-time value. + * NaT is represented by year == NPY_DATETIME_NAT. + */ +typedef struct { + npy_int64 year; + npy_int32 month, day, hour, min, sec, us, ps, as; +} npy_datetimestruct; + +/* This is not used internally. */ +typedef struct { + npy_int64 day; + npy_int32 sec, us, ps, as; +} npy_timedeltastruct; + +typedef int (PyArray_FinalizeFunc)(PyArrayObject *, PyObject *); + +/* + * Means c-style contiguous (last index varies the fastest). The data + * elements right after each other. + * + * This flag may be requested in constructor functions. + * This flag may be tested for in PyArray_FLAGS(arr). + */ +#define NPY_ARRAY_C_CONTIGUOUS 0x0001 + +/* + * Set if array is a contiguous Fortran array: the first index varies + * the fastest in memory (strides array is reverse of C-contiguous + * array) + * + * This flag may be requested in constructor functions. + * This flag may be tested for in PyArray_FLAGS(arr). + */ +#define NPY_ARRAY_F_CONTIGUOUS 0x0002 + +/* + * Note: all 0-d arrays are C_CONTIGUOUS and F_CONTIGUOUS. If a + * 1-d array is C_CONTIGUOUS it is also F_CONTIGUOUS. Arrays with + * more then one dimension can be C_CONTIGUOUS and F_CONTIGUOUS + * at the same time if they have either zero or one element. + * If NPY_RELAXED_STRIDES_CHECKING is set, a higher dimensional + * array is always C_CONTIGUOUS and F_CONTIGUOUS if it has zero elements + * and the array is contiguous if ndarray.squeeze() is contiguous. + * I.e. dimensions for which `ndarray.shape[dimension] == 1` are + * ignored. + */ + +/* + * If set, the array owns the data: it will be free'd when the array + * is deleted. + * + * This flag may be tested for in PyArray_FLAGS(arr). + */ +#define NPY_ARRAY_OWNDATA 0x0004 + +/* + * An array never has the next four set; they're only used as parameter + * flags to the various FromAny functions + * + * This flag may be requested in constructor functions. + */ + +/* Cause a cast to occur regardless of whether or not it is safe. */ +#define NPY_ARRAY_FORCECAST 0x0010 + +/* + * Always copy the array. Returned arrays are always CONTIGUOUS, + * ALIGNED, and WRITEABLE. + * + * This flag may be requested in constructor functions. + */ +#define NPY_ARRAY_ENSURECOPY 0x0020 + +/* + * Make sure the returned array is a base-class ndarray + * + * This flag may be requested in constructor functions. + */ +#define NPY_ARRAY_ENSUREARRAY 0x0040 + +/* + * Make sure that the strides are in units of the element size Needed + * for some operations with record-arrays. + * + * This flag may be requested in constructor functions. + */ +#define NPY_ARRAY_ELEMENTSTRIDES 0x0080 + +/* + * Array data is aligned on the appropriate memory address for the type + * stored according to how the compiler would align things (e.g., an + * array of integers (4 bytes each) starts on a memory address that's + * a multiple of 4) + * + * This flag may be requested in constructor functions. + * This flag may be tested for in PyArray_FLAGS(arr). + */ +#define NPY_ARRAY_ALIGNED 0x0100 + +/* + * Array data has the native endianness + * + * This flag may be requested in constructor functions. + */ +#define NPY_ARRAY_NOTSWAPPED 0x0200 + +/* + * Array data is writeable + * + * This flag may be requested in constructor functions. + * This flag may be tested for in PyArray_FLAGS(arr). + */ +#define NPY_ARRAY_WRITEABLE 0x0400 + +/* + * If this flag is set, then base contains a pointer to an array of + * the same size that should be updated with the current contents of + * this array when PyArray_ResolveWritebackIfCopy is called. + * + * This flag may be requested in constructor functions. + * This flag may be tested for in PyArray_FLAGS(arr). + */ +#define NPY_ARRAY_UPDATEIFCOPY 0x1000 /* Deprecated in 1.14 */ +#define NPY_ARRAY_WRITEBACKIFCOPY 0x2000 + +/* + * NOTE: there are also internal flags defined in multiarray/arrayobject.h, + * which start at bit 31 and work down. + */ + +#define NPY_ARRAY_BEHAVED (NPY_ARRAY_ALIGNED | \ + NPY_ARRAY_WRITEABLE) +#define NPY_ARRAY_BEHAVED_NS (NPY_ARRAY_ALIGNED | \ + NPY_ARRAY_WRITEABLE | \ + NPY_ARRAY_NOTSWAPPED) +#define NPY_ARRAY_CARRAY (NPY_ARRAY_C_CONTIGUOUS | \ + NPY_ARRAY_BEHAVED) +#define NPY_ARRAY_CARRAY_RO (NPY_ARRAY_C_CONTIGUOUS | \ + NPY_ARRAY_ALIGNED) +#define NPY_ARRAY_FARRAY (NPY_ARRAY_F_CONTIGUOUS | \ + NPY_ARRAY_BEHAVED) +#define NPY_ARRAY_FARRAY_RO (NPY_ARRAY_F_CONTIGUOUS | \ + NPY_ARRAY_ALIGNED) +#define NPY_ARRAY_DEFAULT (NPY_ARRAY_CARRAY) +#define NPY_ARRAY_IN_ARRAY (NPY_ARRAY_CARRAY_RO) +#define NPY_ARRAY_OUT_ARRAY (NPY_ARRAY_CARRAY) +#define NPY_ARRAY_INOUT_ARRAY (NPY_ARRAY_CARRAY | \ + NPY_ARRAY_UPDATEIFCOPY) +#define NPY_ARRAY_INOUT_ARRAY2 (NPY_ARRAY_CARRAY | \ + NPY_ARRAY_WRITEBACKIFCOPY) +#define NPY_ARRAY_IN_FARRAY (NPY_ARRAY_FARRAY_RO) +#define NPY_ARRAY_OUT_FARRAY (NPY_ARRAY_FARRAY) +#define NPY_ARRAY_INOUT_FARRAY (NPY_ARRAY_FARRAY | \ + NPY_ARRAY_UPDATEIFCOPY) +#define NPY_ARRAY_INOUT_FARRAY2 (NPY_ARRAY_FARRAY | \ + NPY_ARRAY_WRITEBACKIFCOPY) + +#define NPY_ARRAY_UPDATE_ALL (NPY_ARRAY_C_CONTIGUOUS | \ + NPY_ARRAY_F_CONTIGUOUS | \ + NPY_ARRAY_ALIGNED) + +/* This flag is for the array interface, not PyArrayObject */ +#define NPY_ARR_HAS_DESCR 0x0800 + + + + +/* + * Size of internal buffers used for alignment Make BUFSIZE a multiple + * of sizeof(npy_cdouble) -- usually 16 so that ufunc buffers are aligned + */ +#define NPY_MIN_BUFSIZE ((int)sizeof(npy_cdouble)) +#define NPY_MAX_BUFSIZE (((int)sizeof(npy_cdouble))*1000000) +#define NPY_BUFSIZE 8192 +/* buffer stress test size: */ +/*#define NPY_BUFSIZE 17*/ + +#define PyArray_MAX(a,b) (((a)>(b))?(a):(b)) +#define PyArray_MIN(a,b) (((a)<(b))?(a):(b)) +#define PyArray_CLT(p,q) ((((p).real==(q).real) ? ((p).imag < (q).imag) : \ + ((p).real < (q).real))) +#define PyArray_CGT(p,q) ((((p).real==(q).real) ? ((p).imag > (q).imag) : \ + ((p).real > (q).real))) +#define PyArray_CLE(p,q) ((((p).real==(q).real) ? ((p).imag <= (q).imag) : \ + ((p).real <= (q).real))) +#define PyArray_CGE(p,q) ((((p).real==(q).real) ? ((p).imag >= (q).imag) : \ + ((p).real >= (q).real))) +#define PyArray_CEQ(p,q) (((p).real==(q).real) && ((p).imag == (q).imag)) +#define PyArray_CNE(p,q) (((p).real!=(q).real) || ((p).imag != (q).imag)) + +/* + * C API: consists of Macros and functions. The MACROS are defined + * here. + */ + + +#define PyArray_ISCONTIGUOUS(m) PyArray_CHKFLAGS((m), NPY_ARRAY_C_CONTIGUOUS) +#define PyArray_ISWRITEABLE(m) PyArray_CHKFLAGS((m), NPY_ARRAY_WRITEABLE) +#define PyArray_ISALIGNED(m) PyArray_CHKFLAGS((m), NPY_ARRAY_ALIGNED) + +#define PyArray_IS_C_CONTIGUOUS(m) PyArray_CHKFLAGS((m), NPY_ARRAY_C_CONTIGUOUS) +#define PyArray_IS_F_CONTIGUOUS(m) PyArray_CHKFLAGS((m), NPY_ARRAY_F_CONTIGUOUS) + +/* the variable is used in some places, so always define it */ +#define NPY_BEGIN_THREADS_DEF PyThreadState *_save=NULL; +#if NPY_ALLOW_THREADS +#define NPY_BEGIN_ALLOW_THREADS Py_BEGIN_ALLOW_THREADS +#define NPY_END_ALLOW_THREADS Py_END_ALLOW_THREADS +#define NPY_BEGIN_THREADS do {_save = PyEval_SaveThread();} while (0); +#define NPY_END_THREADS do { if (_save) \ + { PyEval_RestoreThread(_save); _save = NULL;} } while (0); +#define NPY_BEGIN_THREADS_THRESHOLDED(loop_size) do { if ((loop_size) > 500) \ + { _save = PyEval_SaveThread();} } while (0); + +#define NPY_BEGIN_THREADS_DESCR(dtype) \ + do {if (!(PyDataType_FLAGCHK((dtype), NPY_NEEDS_PYAPI))) \ + NPY_BEGIN_THREADS;} while (0); + +#define NPY_END_THREADS_DESCR(dtype) \ + do {if (!(PyDataType_FLAGCHK((dtype), NPY_NEEDS_PYAPI))) \ + NPY_END_THREADS; } while (0); + +#define NPY_ALLOW_C_API_DEF PyGILState_STATE __save__; +#define NPY_ALLOW_C_API do {__save__ = PyGILState_Ensure();} while (0); +#define NPY_DISABLE_C_API do {PyGILState_Release(__save__);} while (0); +#else +#define NPY_BEGIN_ALLOW_THREADS +#define NPY_END_ALLOW_THREADS +#define NPY_BEGIN_THREADS +#define NPY_END_THREADS +#define NPY_BEGIN_THREADS_THRESHOLDED(loop_size) +#define NPY_BEGIN_THREADS_DESCR(dtype) +#define NPY_END_THREADS_DESCR(dtype) +#define NPY_ALLOW_C_API_DEF +#define NPY_ALLOW_C_API +#define NPY_DISABLE_C_API +#endif + +/********************************** + * The nditer object, added in 1.6 + **********************************/ + +/* The actual structure of the iterator is an internal detail */ +typedef struct NpyIter_InternalOnly NpyIter; + +/* Iterator function pointers that may be specialized */ +typedef int (NpyIter_IterNextFunc)(NpyIter *iter); +typedef void (NpyIter_GetMultiIndexFunc)(NpyIter *iter, + npy_intp *outcoords); + +/*** Global flags that may be passed to the iterator constructors ***/ + +/* Track an index representing C order */ +#define NPY_ITER_C_INDEX 0x00000001 +/* Track an index representing Fortran order */ +#define NPY_ITER_F_INDEX 0x00000002 +/* Track a multi-index */ +#define NPY_ITER_MULTI_INDEX 0x00000004 +/* User code external to the iterator does the 1-dimensional innermost loop */ +#define NPY_ITER_EXTERNAL_LOOP 0x00000008 +/* Convert all the operands to a common data type */ +#define NPY_ITER_COMMON_DTYPE 0x00000010 +/* Operands may hold references, requiring API access during iteration */ +#define NPY_ITER_REFS_OK 0x00000020 +/* Zero-sized operands should be permitted, iteration checks IterSize for 0 */ +#define NPY_ITER_ZEROSIZE_OK 0x00000040 +/* Permits reductions (size-0 stride with dimension size > 1) */ +#define NPY_ITER_REDUCE_OK 0x00000080 +/* Enables sub-range iteration */ +#define NPY_ITER_RANGED 0x00000100 +/* Enables buffering */ +#define NPY_ITER_BUFFERED 0x00000200 +/* When buffering is enabled, grows the inner loop if possible */ +#define NPY_ITER_GROWINNER 0x00000400 +/* Delay allocation of buffers until first Reset* call */ +#define NPY_ITER_DELAY_BUFALLOC 0x00000800 +/* When NPY_KEEPORDER is specified, disable reversing negative-stride axes */ +#define NPY_ITER_DONT_NEGATE_STRIDES 0x00001000 +/* + * If output operands overlap with other operands (based on heuristics that + * has false positives but no false negatives), make temporary copies to + * eliminate overlap. + */ +#define NPY_ITER_COPY_IF_OVERLAP 0x00002000 + +/*** Per-operand flags that may be passed to the iterator constructors ***/ + +/* The operand will be read from and written to */ +#define NPY_ITER_READWRITE 0x00010000 +/* The operand will only be read from */ +#define NPY_ITER_READONLY 0x00020000 +/* The operand will only be written to */ +#define NPY_ITER_WRITEONLY 0x00040000 +/* The operand's data must be in native byte order */ +#define NPY_ITER_NBO 0x00080000 +/* The operand's data must be aligned */ +#define NPY_ITER_ALIGNED 0x00100000 +/* The operand's data must be contiguous (within the inner loop) */ +#define NPY_ITER_CONTIG 0x00200000 +/* The operand may be copied to satisfy requirements */ +#define NPY_ITER_COPY 0x00400000 +/* The operand may be copied with WRITEBACKIFCOPY to satisfy requirements */ +#define NPY_ITER_UPDATEIFCOPY 0x00800000 +/* Allocate the operand if it is NULL */ +#define NPY_ITER_ALLOCATE 0x01000000 +/* If an operand is allocated, don't use any subtype */ +#define NPY_ITER_NO_SUBTYPE 0x02000000 +/* This is a virtual array slot, operand is NULL but temporary data is there */ +#define NPY_ITER_VIRTUAL 0x04000000 +/* Require that the dimension match the iterator dimensions exactly */ +#define NPY_ITER_NO_BROADCAST 0x08000000 +/* A mask is being used on this array, affects buffer -> array copy */ +#define NPY_ITER_WRITEMASKED 0x10000000 +/* This array is the mask for all WRITEMASKED operands */ +#define NPY_ITER_ARRAYMASK 0x20000000 +/* Assume iterator order data access for COPY_IF_OVERLAP */ +#define NPY_ITER_OVERLAP_ASSUME_ELEMENTWISE 0x40000000 + +#define NPY_ITER_GLOBAL_FLAGS 0x0000ffff +#define NPY_ITER_PER_OP_FLAGS 0xffff0000 + + +/***************************** + * Basic iterator object + *****************************/ + +/* FWD declaration */ +typedef struct PyArrayIterObject_tag PyArrayIterObject; + +/* + * type of the function which translates a set of coordinates to a + * pointer to the data + */ +typedef char* (*npy_iter_get_dataptr_t)( + PyArrayIterObject* iter, const npy_intp*); + +struct PyArrayIterObject_tag { + PyObject_HEAD + int nd_m1; /* number of dimensions - 1 */ + npy_intp index, size; + npy_intp coordinates[NPY_MAXDIMS];/* N-dimensional loop */ + npy_intp dims_m1[NPY_MAXDIMS]; /* ao->dimensions - 1 */ + npy_intp strides[NPY_MAXDIMS]; /* ao->strides or fake */ + npy_intp backstrides[NPY_MAXDIMS];/* how far to jump back */ + npy_intp factors[NPY_MAXDIMS]; /* shape factors */ + PyArrayObject *ao; + char *dataptr; /* pointer to current item*/ + npy_bool contiguous; + + npy_intp bounds[NPY_MAXDIMS][2]; + npy_intp limits[NPY_MAXDIMS][2]; + npy_intp limits_sizes[NPY_MAXDIMS]; + npy_iter_get_dataptr_t translate; +} ; + + +/* Iterator API */ +#define PyArrayIter_Check(op) PyObject_TypeCheck((op), &PyArrayIter_Type) + +#define _PyAIT(it) ((PyArrayIterObject *)(it)) +#define PyArray_ITER_RESET(it) do { \ + _PyAIT(it)->index = 0; \ + _PyAIT(it)->dataptr = PyArray_BYTES(_PyAIT(it)->ao); \ + memset(_PyAIT(it)->coordinates, 0, \ + (_PyAIT(it)->nd_m1+1)*sizeof(npy_intp)); \ +} while (0) + +#define _PyArray_ITER_NEXT1(it) do { \ + (it)->dataptr += _PyAIT(it)->strides[0]; \ + (it)->coordinates[0]++; \ +} while (0) + +#define _PyArray_ITER_NEXT2(it) do { \ + if ((it)->coordinates[1] < (it)->dims_m1[1]) { \ + (it)->coordinates[1]++; \ + (it)->dataptr += (it)->strides[1]; \ + } \ + else { \ + (it)->coordinates[1] = 0; \ + (it)->coordinates[0]++; \ + (it)->dataptr += (it)->strides[0] - \ + (it)->backstrides[1]; \ + } \ +} while (0) + +#define PyArray_ITER_NEXT(it) do { \ + _PyAIT(it)->index++; \ + if (_PyAIT(it)->nd_m1 == 0) { \ + _PyArray_ITER_NEXT1(_PyAIT(it)); \ + } \ + else if (_PyAIT(it)->contiguous) \ + _PyAIT(it)->dataptr += PyArray_DESCR(_PyAIT(it)->ao)->elsize; \ + else if (_PyAIT(it)->nd_m1 == 1) { \ + _PyArray_ITER_NEXT2(_PyAIT(it)); \ + } \ + else { \ + int __npy_i; \ + for (__npy_i=_PyAIT(it)->nd_m1; __npy_i >= 0; __npy_i--) { \ + if (_PyAIT(it)->coordinates[__npy_i] < \ + _PyAIT(it)->dims_m1[__npy_i]) { \ + _PyAIT(it)->coordinates[__npy_i]++; \ + _PyAIT(it)->dataptr += \ + _PyAIT(it)->strides[__npy_i]; \ + break; \ + } \ + else { \ + _PyAIT(it)->coordinates[__npy_i] = 0; \ + _PyAIT(it)->dataptr -= \ + _PyAIT(it)->backstrides[__npy_i]; \ + } \ + } \ + } \ +} while (0) + +#define PyArray_ITER_GOTO(it, destination) do { \ + int __npy_i; \ + _PyAIT(it)->index = 0; \ + _PyAIT(it)->dataptr = PyArray_BYTES(_PyAIT(it)->ao); \ + for (__npy_i = _PyAIT(it)->nd_m1; __npy_i>=0; __npy_i--) { \ + if (destination[__npy_i] < 0) { \ + destination[__npy_i] += \ + _PyAIT(it)->dims_m1[__npy_i]+1; \ + } \ + _PyAIT(it)->dataptr += destination[__npy_i] * \ + _PyAIT(it)->strides[__npy_i]; \ + _PyAIT(it)->coordinates[__npy_i] = \ + destination[__npy_i]; \ + _PyAIT(it)->index += destination[__npy_i] * \ + ( __npy_i==_PyAIT(it)->nd_m1 ? 1 : \ + _PyAIT(it)->dims_m1[__npy_i+1]+1) ; \ + } \ +} while (0) + +#define PyArray_ITER_GOTO1D(it, ind) do { \ + int __npy_i; \ + npy_intp __npy_ind = (npy_intp)(ind); \ + if (__npy_ind < 0) __npy_ind += _PyAIT(it)->size; \ + _PyAIT(it)->index = __npy_ind; \ + if (_PyAIT(it)->nd_m1 == 0) { \ + _PyAIT(it)->dataptr = PyArray_BYTES(_PyAIT(it)->ao) + \ + __npy_ind * _PyAIT(it)->strides[0]; \ + } \ + else if (_PyAIT(it)->contiguous) \ + _PyAIT(it)->dataptr = PyArray_BYTES(_PyAIT(it)->ao) + \ + __npy_ind * PyArray_DESCR(_PyAIT(it)->ao)->elsize; \ + else { \ + _PyAIT(it)->dataptr = PyArray_BYTES(_PyAIT(it)->ao); \ + for (__npy_i = 0; __npy_i<=_PyAIT(it)->nd_m1; \ + __npy_i++) { \ + _PyAIT(it)->dataptr += \ + (__npy_ind / _PyAIT(it)->factors[__npy_i]) \ + * _PyAIT(it)->strides[__npy_i]; \ + __npy_ind %= _PyAIT(it)->factors[__npy_i]; \ + } \ + } \ +} while (0) + +#define PyArray_ITER_DATA(it) ((void *)(_PyAIT(it)->dataptr)) + +#define PyArray_ITER_NOTDONE(it) (_PyAIT(it)->index < _PyAIT(it)->size) + + +/* + * Any object passed to PyArray_Broadcast must be binary compatible + * with this structure. + */ + +typedef struct { + PyObject_HEAD + int numiter; /* number of iters */ + npy_intp size; /* broadcasted size */ + npy_intp index; /* current index */ + int nd; /* number of dims */ + npy_intp dimensions[NPY_MAXDIMS]; /* dimensions */ + PyArrayIterObject *iters[NPY_MAXARGS]; /* iterators */ +} PyArrayMultiIterObject; + +#define _PyMIT(m) ((PyArrayMultiIterObject *)(m)) +#define PyArray_MultiIter_RESET(multi) do { \ + int __npy_mi; \ + _PyMIT(multi)->index = 0; \ + for (__npy_mi=0; __npy_mi < _PyMIT(multi)->numiter; __npy_mi++) { \ + PyArray_ITER_RESET(_PyMIT(multi)->iters[__npy_mi]); \ + } \ +} while (0) + +#define PyArray_MultiIter_NEXT(multi) do { \ + int __npy_mi; \ + _PyMIT(multi)->index++; \ + for (__npy_mi=0; __npy_mi < _PyMIT(multi)->numiter; __npy_mi++) { \ + PyArray_ITER_NEXT(_PyMIT(multi)->iters[__npy_mi]); \ + } \ +} while (0) + +#define PyArray_MultiIter_GOTO(multi, dest) do { \ + int __npy_mi; \ + for (__npy_mi=0; __npy_mi < _PyMIT(multi)->numiter; __npy_mi++) { \ + PyArray_ITER_GOTO(_PyMIT(multi)->iters[__npy_mi], dest); \ + } \ + _PyMIT(multi)->index = _PyMIT(multi)->iters[0]->index; \ +} while (0) + +#define PyArray_MultiIter_GOTO1D(multi, ind) do { \ + int __npy_mi; \ + for (__npy_mi=0; __npy_mi < _PyMIT(multi)->numiter; __npy_mi++) { \ + PyArray_ITER_GOTO1D(_PyMIT(multi)->iters[__npy_mi], ind); \ + } \ + _PyMIT(multi)->index = _PyMIT(multi)->iters[0]->index; \ +} while (0) + +#define PyArray_MultiIter_DATA(multi, i) \ + ((void *)(_PyMIT(multi)->iters[i]->dataptr)) + +#define PyArray_MultiIter_NEXTi(multi, i) \ + PyArray_ITER_NEXT(_PyMIT(multi)->iters[i]) + +#define PyArray_MultiIter_NOTDONE(multi) \ + (_PyMIT(multi)->index < _PyMIT(multi)->size) + + +/* + * Store the information needed for fancy-indexing over an array. The + * fields are slightly unordered to keep consec, dataptr and subspace + * where they were originally. + */ +typedef struct { + PyObject_HEAD + /* + * Multi-iterator portion --- needs to be present in this + * order to work with PyArray_Broadcast + */ + + int numiter; /* number of index-array + iterators */ + npy_intp size; /* size of broadcasted + result */ + npy_intp index; /* current index */ + int nd; /* number of dims */ + npy_intp dimensions[NPY_MAXDIMS]; /* dimensions */ + NpyIter *outer; /* index objects + iterator */ + void *unused[NPY_MAXDIMS - 2]; + PyArrayObject *array; + /* Flat iterator for the indexed array. For compatibility solely. */ + PyArrayIterObject *ait; + + /* + * Subspace array. For binary compatibility (was an iterator, + * but only the check for NULL should be used). + */ + PyArrayObject *subspace; + + /* + * if subspace iteration, then this is the array of axes in + * the underlying array represented by the index objects + */ + int iteraxes[NPY_MAXDIMS]; + npy_intp fancy_strides[NPY_MAXDIMS]; + + /* pointer when all fancy indices are 0 */ + char *baseoffset; + + /* + * after binding consec denotes at which axis the fancy axes + * are inserted. + */ + int consec; + char *dataptr; + + int nd_fancy; + npy_intp fancy_dims[NPY_MAXDIMS]; + + /* Whether the iterator (any of the iterators) requires API */ + int needs_api; + + /* + * Extra op information. + */ + PyArrayObject *extra_op; + PyArray_Descr *extra_op_dtype; /* desired dtype */ + npy_uint32 *extra_op_flags; /* Iterator flags */ + + NpyIter *extra_op_iter; + NpyIter_IterNextFunc *extra_op_next; + char **extra_op_ptrs; + + /* + * Information about the iteration state. + */ + NpyIter_IterNextFunc *outer_next; + char **outer_ptrs; + npy_intp *outer_strides; + + /* + * Information about the subspace iterator. + */ + NpyIter *subspace_iter; + NpyIter_IterNextFunc *subspace_next; + char **subspace_ptrs; + npy_intp *subspace_strides; + + /* Count for the external loop (which ever it is) for API iteration */ + npy_intp iter_count; + +} PyArrayMapIterObject; + +enum { + NPY_NEIGHBORHOOD_ITER_ZERO_PADDING, + NPY_NEIGHBORHOOD_ITER_ONE_PADDING, + NPY_NEIGHBORHOOD_ITER_CONSTANT_PADDING, + NPY_NEIGHBORHOOD_ITER_CIRCULAR_PADDING, + NPY_NEIGHBORHOOD_ITER_MIRROR_PADDING +}; + +typedef struct { + PyObject_HEAD + + /* + * PyArrayIterObject part: keep this in this exact order + */ + int nd_m1; /* number of dimensions - 1 */ + npy_intp index, size; + npy_intp coordinates[NPY_MAXDIMS];/* N-dimensional loop */ + npy_intp dims_m1[NPY_MAXDIMS]; /* ao->dimensions - 1 */ + npy_intp strides[NPY_MAXDIMS]; /* ao->strides or fake */ + npy_intp backstrides[NPY_MAXDIMS];/* how far to jump back */ + npy_intp factors[NPY_MAXDIMS]; /* shape factors */ + PyArrayObject *ao; + char *dataptr; /* pointer to current item*/ + npy_bool contiguous; + + npy_intp bounds[NPY_MAXDIMS][2]; + npy_intp limits[NPY_MAXDIMS][2]; + npy_intp limits_sizes[NPY_MAXDIMS]; + npy_iter_get_dataptr_t translate; + + /* + * New members + */ + npy_intp nd; + + /* Dimensions is the dimension of the array */ + npy_intp dimensions[NPY_MAXDIMS]; + + /* + * Neighborhood points coordinates are computed relatively to the + * point pointed by _internal_iter + */ + PyArrayIterObject* _internal_iter; + /* + * To keep a reference to the representation of the constant value + * for constant padding + */ + char* constant; + + int mode; +} PyArrayNeighborhoodIterObject; + +/* + * Neighborhood iterator API + */ + +/* General: those work for any mode */ +static NPY_INLINE int +PyArrayNeighborhoodIter_Reset(PyArrayNeighborhoodIterObject* iter); +static NPY_INLINE int +PyArrayNeighborhoodIter_Next(PyArrayNeighborhoodIterObject* iter); +#if 0 +static NPY_INLINE int +PyArrayNeighborhoodIter_Next2D(PyArrayNeighborhoodIterObject* iter); +#endif + +/* + * Include inline implementations - functions defined there are not + * considered public API + */ +#define _NPY_INCLUDE_NEIGHBORHOOD_IMP +#include "_neighborhood_iterator_imp.h" +#undef _NPY_INCLUDE_NEIGHBORHOOD_IMP + +/* The default array type */ +#define NPY_DEFAULT_TYPE NPY_DOUBLE + +/* + * All sorts of useful ways to look into a PyArrayObject. It is recommended + * to use PyArrayObject * objects instead of always casting from PyObject *, + * for improved type checking. + * + * In many cases here the macro versions of the accessors are deprecated, + * but can't be immediately changed to inline functions because the + * preexisting macros accept PyObject * and do automatic casts. Inline + * functions accepting PyArrayObject * provides for some compile-time + * checking of correctness when working with these objects in C. + */ + +#define PyArray_ISONESEGMENT(m) (PyArray_CHKFLAGS(m, NPY_ARRAY_C_CONTIGUOUS) || \ + PyArray_CHKFLAGS(m, NPY_ARRAY_F_CONTIGUOUS)) + +#define PyArray_ISFORTRAN(m) (PyArray_CHKFLAGS(m, NPY_ARRAY_F_CONTIGUOUS) && \ + (!PyArray_CHKFLAGS(m, NPY_ARRAY_C_CONTIGUOUS))) + +#define PyArray_FORTRAN_IF(m) ((PyArray_CHKFLAGS(m, NPY_ARRAY_F_CONTIGUOUS) ? \ + NPY_ARRAY_F_CONTIGUOUS : 0)) + +#if (defined(NPY_NO_DEPRECATED_API) && (NPY_1_7_API_VERSION <= NPY_NO_DEPRECATED_API)) +/* + * Changing access macros into functions, to allow for future hiding + * of the internal memory layout. This later hiding will allow the 2.x series + * to change the internal representation of arrays without affecting + * ABI compatibility. + */ + +static NPY_INLINE int +PyArray_NDIM(const PyArrayObject *arr) +{ + return ((PyArrayObject_fields *)arr)->nd; +} + +static NPY_INLINE void * +PyArray_DATA(PyArrayObject *arr) +{ + return ((PyArrayObject_fields *)arr)->data; +} + +static NPY_INLINE char * +PyArray_BYTES(PyArrayObject *arr) +{ + return ((PyArrayObject_fields *)arr)->data; +} + +static NPY_INLINE npy_intp * +PyArray_DIMS(PyArrayObject *arr) +{ + return ((PyArrayObject_fields *)arr)->dimensions; +} + +static NPY_INLINE npy_intp * +PyArray_STRIDES(PyArrayObject *arr) +{ + return ((PyArrayObject_fields *)arr)->strides; +} + +static NPY_INLINE npy_intp +PyArray_DIM(const PyArrayObject *arr, int idim) +{ + return ((PyArrayObject_fields *)arr)->dimensions[idim]; +} + +static NPY_INLINE npy_intp +PyArray_STRIDE(const PyArrayObject *arr, int istride) +{ + return ((PyArrayObject_fields *)arr)->strides[istride]; +} + +static NPY_INLINE NPY_RETURNS_BORROWED_REF PyObject * +PyArray_BASE(PyArrayObject *arr) +{ + return ((PyArrayObject_fields *)arr)->base; +} + +static NPY_INLINE NPY_RETURNS_BORROWED_REF PyArray_Descr * +PyArray_DESCR(PyArrayObject *arr) +{ + return ((PyArrayObject_fields *)arr)->descr; +} + +static NPY_INLINE int +PyArray_FLAGS(const PyArrayObject *arr) +{ + return ((PyArrayObject_fields *)arr)->flags; +} + +static NPY_INLINE npy_intp +PyArray_ITEMSIZE(const PyArrayObject *arr) +{ + return ((PyArrayObject_fields *)arr)->descr->elsize; +} + +static NPY_INLINE int +PyArray_TYPE(const PyArrayObject *arr) +{ + return ((PyArrayObject_fields *)arr)->descr->type_num; +} + +static NPY_INLINE int +PyArray_CHKFLAGS(const PyArrayObject *arr, int flags) +{ + return (PyArray_FLAGS(arr) & flags) == flags; +} + +static NPY_INLINE PyObject * +PyArray_GETITEM(const PyArrayObject *arr, const char *itemptr) +{ + return ((PyArrayObject_fields *)arr)->descr->f->getitem( + (void *)itemptr, (PyArrayObject *)arr); +} + +/* + * SETITEM should only be used if it is known that the value is a scalar + * and of a type understood by the arrays dtype. + * Use `PyArray_Pack` if the value may be of a different dtype. + */ +static NPY_INLINE int +PyArray_SETITEM(PyArrayObject *arr, char *itemptr, PyObject *v) +{ + return ((PyArrayObject_fields *)arr)->descr->f->setitem(v, itemptr, arr); +} + +#else + +/* These macros are deprecated as of NumPy 1.7. */ +#define PyArray_NDIM(obj) (((PyArrayObject_fields *)(obj))->nd) +#define PyArray_BYTES(obj) (((PyArrayObject_fields *)(obj))->data) +#define PyArray_DATA(obj) ((void *)((PyArrayObject_fields *)(obj))->data) +#define PyArray_DIMS(obj) (((PyArrayObject_fields *)(obj))->dimensions) +#define PyArray_STRIDES(obj) (((PyArrayObject_fields *)(obj))->strides) +#define PyArray_DIM(obj,n) (PyArray_DIMS(obj)[n]) +#define PyArray_STRIDE(obj,n) (PyArray_STRIDES(obj)[n]) +#define PyArray_BASE(obj) (((PyArrayObject_fields *)(obj))->base) +#define PyArray_DESCR(obj) (((PyArrayObject_fields *)(obj))->descr) +#define PyArray_FLAGS(obj) (((PyArrayObject_fields *)(obj))->flags) +#define PyArray_CHKFLAGS(m, FLAGS) \ + ((((PyArrayObject_fields *)(m))->flags & (FLAGS)) == (FLAGS)) +#define PyArray_ITEMSIZE(obj) \ + (((PyArrayObject_fields *)(obj))->descr->elsize) +#define PyArray_TYPE(obj) \ + (((PyArrayObject_fields *)(obj))->descr->type_num) +#define PyArray_GETITEM(obj,itemptr) \ + PyArray_DESCR(obj)->f->getitem((char *)(itemptr), \ + (PyArrayObject *)(obj)) + +#define PyArray_SETITEM(obj,itemptr,v) \ + PyArray_DESCR(obj)->f->setitem((PyObject *)(v), \ + (char *)(itemptr), \ + (PyArrayObject *)(obj)) +#endif + +static NPY_INLINE PyArray_Descr * +PyArray_DTYPE(PyArrayObject *arr) +{ + return ((PyArrayObject_fields *)arr)->descr; +} + +static NPY_INLINE npy_intp * +PyArray_SHAPE(PyArrayObject *arr) +{ + return ((PyArrayObject_fields *)arr)->dimensions; +} + +/* + * Enables the specified array flags. Does no checking, + * assumes you know what you're doing. + */ +static NPY_INLINE void +PyArray_ENABLEFLAGS(PyArrayObject *arr, int flags) +{ + ((PyArrayObject_fields *)arr)->flags |= flags; +} + +/* + * Clears the specified array flags. Does no checking, + * assumes you know what you're doing. + */ +static NPY_INLINE void +PyArray_CLEARFLAGS(PyArrayObject *arr, int flags) +{ + ((PyArrayObject_fields *)arr)->flags &= ~flags; +} + +#define PyTypeNum_ISBOOL(type) ((type) == NPY_BOOL) + +#define PyTypeNum_ISUNSIGNED(type) (((type) == NPY_UBYTE) || \ + ((type) == NPY_USHORT) || \ + ((type) == NPY_UINT) || \ + ((type) == NPY_ULONG) || \ + ((type) == NPY_ULONGLONG)) + +#define PyTypeNum_ISSIGNED(type) (((type) == NPY_BYTE) || \ + ((type) == NPY_SHORT) || \ + ((type) == NPY_INT) || \ + ((type) == NPY_LONG) || \ + ((type) == NPY_LONGLONG)) + +#define PyTypeNum_ISINTEGER(type) (((type) >= NPY_BYTE) && \ + ((type) <= NPY_ULONGLONG)) + +#define PyTypeNum_ISFLOAT(type) ((((type) >= NPY_FLOAT) && \ + ((type) <= NPY_LONGDOUBLE)) || \ + ((type) == NPY_HALF)) + +#define PyTypeNum_ISNUMBER(type) (((type) <= NPY_CLONGDOUBLE) || \ + ((type) == NPY_HALF)) + +#define PyTypeNum_ISSTRING(type) (((type) == NPY_STRING) || \ + ((type) == NPY_UNICODE)) + +#define PyTypeNum_ISCOMPLEX(type) (((type) >= NPY_CFLOAT) && \ + ((type) <= NPY_CLONGDOUBLE)) + +#define PyTypeNum_ISPYTHON(type) (((type) == NPY_LONG) || \ + ((type) == NPY_DOUBLE) || \ + ((type) == NPY_CDOUBLE) || \ + ((type) == NPY_BOOL) || \ + ((type) == NPY_OBJECT )) + +#define PyTypeNum_ISFLEXIBLE(type) (((type) >=NPY_STRING) && \ + ((type) <=NPY_VOID)) + +#define PyTypeNum_ISDATETIME(type) (((type) >=NPY_DATETIME) && \ + ((type) <=NPY_TIMEDELTA)) + +#define PyTypeNum_ISUSERDEF(type) (((type) >= NPY_USERDEF) && \ + ((type) < NPY_USERDEF+ \ + NPY_NUMUSERTYPES)) + +#define PyTypeNum_ISEXTENDED(type) (PyTypeNum_ISFLEXIBLE(type) || \ + PyTypeNum_ISUSERDEF(type)) + +#define PyTypeNum_ISOBJECT(type) ((type) == NPY_OBJECT) + + +#define PyDataType_ISBOOL(obj) PyTypeNum_ISBOOL(((PyArray_Descr*)(obj))->type_num) +#define PyDataType_ISUNSIGNED(obj) PyTypeNum_ISUNSIGNED(((PyArray_Descr*)(obj))->type_num) +#define PyDataType_ISSIGNED(obj) PyTypeNum_ISSIGNED(((PyArray_Descr*)(obj))->type_num) +#define PyDataType_ISINTEGER(obj) PyTypeNum_ISINTEGER(((PyArray_Descr*)(obj))->type_num ) +#define PyDataType_ISFLOAT(obj) PyTypeNum_ISFLOAT(((PyArray_Descr*)(obj))->type_num) +#define PyDataType_ISNUMBER(obj) PyTypeNum_ISNUMBER(((PyArray_Descr*)(obj))->type_num) +#define PyDataType_ISSTRING(obj) PyTypeNum_ISSTRING(((PyArray_Descr*)(obj))->type_num) +#define PyDataType_ISCOMPLEX(obj) PyTypeNum_ISCOMPLEX(((PyArray_Descr*)(obj))->type_num) +#define PyDataType_ISPYTHON(obj) PyTypeNum_ISPYTHON(((PyArray_Descr*)(obj))->type_num) +#define PyDataType_ISFLEXIBLE(obj) PyTypeNum_ISFLEXIBLE(((PyArray_Descr*)(obj))->type_num) +#define PyDataType_ISDATETIME(obj) PyTypeNum_ISDATETIME(((PyArray_Descr*)(obj))->type_num) +#define PyDataType_ISUSERDEF(obj) PyTypeNum_ISUSERDEF(((PyArray_Descr*)(obj))->type_num) +#define PyDataType_ISEXTENDED(obj) PyTypeNum_ISEXTENDED(((PyArray_Descr*)(obj))->type_num) +#define PyDataType_ISOBJECT(obj) PyTypeNum_ISOBJECT(((PyArray_Descr*)(obj))->type_num) +#define PyDataType_HASFIELDS(obj) (((PyArray_Descr *)(obj))->names != NULL) +#define PyDataType_HASSUBARRAY(dtype) ((dtype)->subarray != NULL) +#define PyDataType_ISUNSIZED(dtype) ((dtype)->elsize == 0 && \ + !PyDataType_HASFIELDS(dtype)) +#define PyDataType_MAKEUNSIZED(dtype) ((dtype)->elsize = 0) + +#define PyArray_ISBOOL(obj) PyTypeNum_ISBOOL(PyArray_TYPE(obj)) +#define PyArray_ISUNSIGNED(obj) PyTypeNum_ISUNSIGNED(PyArray_TYPE(obj)) +#define PyArray_ISSIGNED(obj) PyTypeNum_ISSIGNED(PyArray_TYPE(obj)) +#define PyArray_ISINTEGER(obj) PyTypeNum_ISINTEGER(PyArray_TYPE(obj)) +#define PyArray_ISFLOAT(obj) PyTypeNum_ISFLOAT(PyArray_TYPE(obj)) +#define PyArray_ISNUMBER(obj) PyTypeNum_ISNUMBER(PyArray_TYPE(obj)) +#define PyArray_ISSTRING(obj) PyTypeNum_ISSTRING(PyArray_TYPE(obj)) +#define PyArray_ISCOMPLEX(obj) PyTypeNum_ISCOMPLEX(PyArray_TYPE(obj)) +#define PyArray_ISPYTHON(obj) PyTypeNum_ISPYTHON(PyArray_TYPE(obj)) +#define PyArray_ISFLEXIBLE(obj) PyTypeNum_ISFLEXIBLE(PyArray_TYPE(obj)) +#define PyArray_ISDATETIME(obj) PyTypeNum_ISDATETIME(PyArray_TYPE(obj)) +#define PyArray_ISUSERDEF(obj) PyTypeNum_ISUSERDEF(PyArray_TYPE(obj)) +#define PyArray_ISEXTENDED(obj) PyTypeNum_ISEXTENDED(PyArray_TYPE(obj)) +#define PyArray_ISOBJECT(obj) PyTypeNum_ISOBJECT(PyArray_TYPE(obj)) +#define PyArray_HASFIELDS(obj) PyDataType_HASFIELDS(PyArray_DESCR(obj)) + + /* + * FIXME: This should check for a flag on the data-type that + * states whether or not it is variable length. Because the + * ISFLEXIBLE check is hard-coded to the built-in data-types. + */ +#define PyArray_ISVARIABLE(obj) PyTypeNum_ISFLEXIBLE(PyArray_TYPE(obj)) + +#define PyArray_SAFEALIGNEDCOPY(obj) (PyArray_ISALIGNED(obj) && !PyArray_ISVARIABLE(obj)) + + +#define NPY_LITTLE '<' +#define NPY_BIG '>' +#define NPY_NATIVE '=' +#define NPY_SWAP 's' +#define NPY_IGNORE '|' + +#if NPY_BYTE_ORDER == NPY_BIG_ENDIAN +#define NPY_NATBYTE NPY_BIG +#define NPY_OPPBYTE NPY_LITTLE +#else +#define NPY_NATBYTE NPY_LITTLE +#define NPY_OPPBYTE NPY_BIG +#endif + +#define PyArray_ISNBO(arg) ((arg) != NPY_OPPBYTE) +#define PyArray_IsNativeByteOrder PyArray_ISNBO +#define PyArray_ISNOTSWAPPED(m) PyArray_ISNBO(PyArray_DESCR(m)->byteorder) +#define PyArray_ISBYTESWAPPED(m) (!PyArray_ISNOTSWAPPED(m)) + +#define PyArray_FLAGSWAP(m, flags) (PyArray_CHKFLAGS(m, flags) && \ + PyArray_ISNOTSWAPPED(m)) + +#define PyArray_ISCARRAY(m) PyArray_FLAGSWAP(m, NPY_ARRAY_CARRAY) +#define PyArray_ISCARRAY_RO(m) PyArray_FLAGSWAP(m, NPY_ARRAY_CARRAY_RO) +#define PyArray_ISFARRAY(m) PyArray_FLAGSWAP(m, NPY_ARRAY_FARRAY) +#define PyArray_ISFARRAY_RO(m) PyArray_FLAGSWAP(m, NPY_ARRAY_FARRAY_RO) +#define PyArray_ISBEHAVED(m) PyArray_FLAGSWAP(m, NPY_ARRAY_BEHAVED) +#define PyArray_ISBEHAVED_RO(m) PyArray_FLAGSWAP(m, NPY_ARRAY_ALIGNED) + + +#define PyDataType_ISNOTSWAPPED(d) PyArray_ISNBO(((PyArray_Descr *)(d))->byteorder) +#define PyDataType_ISBYTESWAPPED(d) (!PyDataType_ISNOTSWAPPED(d)) + +/************************************************************ + * A struct used by PyArray_CreateSortedStridePerm, new in 1.7. + ************************************************************/ + +typedef struct { + npy_intp perm, stride; +} npy_stride_sort_item; + +/************************************************************ + * This is the form of the struct that's stored in the + * PyCapsule returned by an array's __array_struct__ attribute. See + * https://docs.scipy.org/doc/numpy/reference/arrays.interface.html for the full + * documentation. + ************************************************************/ +typedef struct { + int two; /* + * contains the integer 2 as a sanity + * check + */ + + int nd; /* number of dimensions */ + + char typekind; /* + * kind in array --- character code of + * typestr + */ + + int itemsize; /* size of each element */ + + int flags; /* + * how should be data interpreted. Valid + * flags are CONTIGUOUS (1), F_CONTIGUOUS (2), + * ALIGNED (0x100), NOTSWAPPED (0x200), and + * WRITEABLE (0x400). ARR_HAS_DESCR (0x800) + * states that arrdescr field is present in + * structure + */ + + npy_intp *shape; /* + * A length-nd array of shape + * information + */ + + npy_intp *strides; /* A length-nd array of stride information */ + + void *data; /* A pointer to the first element of the array */ + + PyObject *descr; /* + * A list of fields or NULL (ignored if flags + * does not have ARR_HAS_DESCR flag set) + */ +} PyArrayInterface; + +/* + * This is a function for hooking into the PyDataMem_NEW/FREE/RENEW functions. + * See the documentation for PyDataMem_SetEventHook. + */ +typedef void (PyDataMem_EventHookFunc)(void *inp, void *outp, size_t size, + void *user_data); + + +/* + * PyArray_DTypeMeta related definitions. + * + * As of now, this API is preliminary and will be extended as necessary. + */ +#if defined(NPY_INTERNAL_BUILD) && NPY_INTERNAL_BUILD + /* + * The Structures defined in this block are considered private API and + * may change without warning! + */ + /* TODO: Make this definition public in the API, as soon as its settled */ + NPY_NO_EXPORT extern PyTypeObject PyArrayDTypeMeta_Type; + + typedef struct PyArray_DTypeMeta_tag PyArray_DTypeMeta; + + typedef PyArray_Descr *(discover_descr_from_pyobject_function)( + PyArray_DTypeMeta *cls, PyObject *obj); + + /* + * Before making this public, we should decide whether it should pass + * the type, or allow looking at the object. A possible use-case: + * `np.array(np.array([0]), dtype=np.ndarray)` + * Could consider arrays that are not `dtype=ndarray` "scalars". + */ + typedef int (is_known_scalar_type_function)( + PyArray_DTypeMeta *cls, PyTypeObject *obj); + + typedef PyArray_Descr *(default_descr_function)(PyArray_DTypeMeta *cls); + typedef PyArray_DTypeMeta *(common_dtype_function)( + PyArray_DTypeMeta *dtype1, PyArray_DTypeMeta *dtyep2); + typedef PyArray_Descr *(common_instance_function)( + PyArray_Descr *dtype1, PyArray_Descr *dtyep2); + + /* + * While NumPy DTypes would not need to be heap types the plan is to + * make DTypes available in Python at which point they will be heap types. + * Since we also wish to add fields to the DType class, this looks like + * a typical instance definition, but with PyHeapTypeObject instead of + * only the PyObject_HEAD. + * This must only be exposed very extremely careful consideration, since + * it is a fairly complex construct which may be better to allow + * refactoring of. + */ + struct PyArray_DTypeMeta_tag { + PyHeapTypeObject super; + + /* + * Most DTypes will have a singleton default instance, for the + * parametric legacy DTypes (bytes, string, void, datetime) this + * may be a pointer to the *prototype* instance? + */ + PyArray_Descr *singleton; + /* + * Is this DType created using the old API? This exists mainly to + * allow for assertions in paths specific to wrapping legacy types. + */ + npy_bool legacy; + /* The values stored by a parametric datatype depend on its instance */ + npy_bool parametric; + /* whether the DType can be instantiated (i.e. np.dtype cannot) */ + npy_bool abstract; + + /* + * The following fields replicate the most important dtype information. + * In the legacy implementation most of these are stored in the + * PyArray_Descr struct. + */ + /* The type object of the scalar instances (may be NULL?) */ + PyTypeObject *scalar_type; + /* kind for this type */ + char kind; + /* unique-character representing this type */ + char type; + /* flags describing data type */ + char flags; + /* number representing this type */ + int type_num; + /* + * Point to the original ArrFuncs. + * NOTE: We could make a copy to detect changes to `f`. + */ + PyArray_ArrFuncs *f; + + /* DType methods, these could be moved into its own struct */ + discover_descr_from_pyobject_function *discover_descr_from_pyobject; + is_known_scalar_type_function *is_known_scalar_type; + default_descr_function *default_descr; + common_dtype_function *common_dtype; + common_instance_function *common_instance; + /* + * Dictionary of ArrayMethods representing most possible casts + * (structured and object are exceptions). + * This should potentially become a weak mapping in the future. + */ + PyObject *castingimpls; + }; + +#endif /* NPY_INTERNAL_BUILD */ + + +/* + * Use the keyword NPY_DEPRECATED_INCLUDES to ensure that the header files + * npy_*_*_deprecated_api.h are only included from here and nowhere else. + */ +#ifdef NPY_DEPRECATED_INCLUDES +#error "Do not use the reserved keyword NPY_DEPRECATED_INCLUDES." +#endif +#define NPY_DEPRECATED_INCLUDES +#if !defined(NPY_NO_DEPRECATED_API) || \ + (NPY_NO_DEPRECATED_API < NPY_1_7_API_VERSION) +#include "npy_1_7_deprecated_api.h" +#endif +/* + * There is no file npy_1_8_deprecated_api.h since there are no additional + * deprecated API features in NumPy 1.8. + * + * Note to maintainers: insert code like the following in future NumPy + * versions. + * + * #if !defined(NPY_NO_DEPRECATED_API) || \ + * (NPY_NO_DEPRECATED_API < NPY_1_9_API_VERSION) + * #include "npy_1_9_deprecated_api.h" + * #endif + */ +#undef NPY_DEPRECATED_INCLUDES + +#endif /* NPY_ARRAYTYPES_H */ diff --git a/venv/Lib/site-packages/numpy/core/include/numpy/noprefix.h b/venv/Lib/site-packages/numpy/core/include/numpy/noprefix.h new file mode 100644 index 0000000..041f301 --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/include/numpy/noprefix.h @@ -0,0 +1,212 @@ +#ifndef NPY_NOPREFIX_H +#define NPY_NOPREFIX_H + +/* + * You can directly include noprefix.h as a backward + * compatibility measure + */ +#ifndef NPY_NO_PREFIX +#include "ndarrayobject.h" +#include "npy_interrupt.h" +#endif + +#define SIGSETJMP NPY_SIGSETJMP +#define SIGLONGJMP NPY_SIGLONGJMP +#define SIGJMP_BUF NPY_SIGJMP_BUF + +#define MAX_DIMS NPY_MAXDIMS + +#define longlong npy_longlong +#define ulonglong npy_ulonglong +#define Bool npy_bool +#define longdouble npy_longdouble +#define byte npy_byte + +#ifndef _BSD_SOURCE +#define ushort npy_ushort +#define uint npy_uint +#define ulong npy_ulong +#endif + +#define ubyte npy_ubyte +#define ushort npy_ushort +#define uint npy_uint +#define ulong npy_ulong +#define cfloat npy_cfloat +#define cdouble npy_cdouble +#define clongdouble npy_clongdouble +#define Int8 npy_int8 +#define UInt8 npy_uint8 +#define Int16 npy_int16 +#define UInt16 npy_uint16 +#define Int32 npy_int32 +#define UInt32 npy_uint32 +#define Int64 npy_int64 +#define UInt64 npy_uint64 +#define Int128 npy_int128 +#define UInt128 npy_uint128 +#define Int256 npy_int256 +#define UInt256 npy_uint256 +#define Float16 npy_float16 +#define Complex32 npy_complex32 +#define Float32 npy_float32 +#define Complex64 npy_complex64 +#define Float64 npy_float64 +#define Complex128 npy_complex128 +#define Float80 npy_float80 +#define Complex160 npy_complex160 +#define Float96 npy_float96 +#define Complex192 npy_complex192 +#define Float128 npy_float128 +#define Complex256 npy_complex256 +#define intp npy_intp +#define uintp npy_uintp +#define datetime npy_datetime +#define timedelta npy_timedelta + +#define SIZEOF_LONGLONG NPY_SIZEOF_LONGLONG +#define SIZEOF_INTP NPY_SIZEOF_INTP +#define SIZEOF_UINTP NPY_SIZEOF_UINTP +#define SIZEOF_HALF NPY_SIZEOF_HALF +#define SIZEOF_LONGDOUBLE NPY_SIZEOF_LONGDOUBLE +#define SIZEOF_DATETIME NPY_SIZEOF_DATETIME +#define SIZEOF_TIMEDELTA NPY_SIZEOF_TIMEDELTA + +#define LONGLONG_FMT NPY_LONGLONG_FMT +#define ULONGLONG_FMT NPY_ULONGLONG_FMT +#define LONGLONG_SUFFIX NPY_LONGLONG_SUFFIX +#define ULONGLONG_SUFFIX NPY_ULONGLONG_SUFFIX + +#define MAX_INT8 127 +#define MIN_INT8 -128 +#define MAX_UINT8 255 +#define MAX_INT16 32767 +#define MIN_INT16 -32768 +#define MAX_UINT16 65535 +#define MAX_INT32 2147483647 +#define MIN_INT32 (-MAX_INT32 - 1) +#define MAX_UINT32 4294967295U +#define MAX_INT64 LONGLONG_SUFFIX(9223372036854775807) +#define MIN_INT64 (-MAX_INT64 - LONGLONG_SUFFIX(1)) +#define MAX_UINT64 ULONGLONG_SUFFIX(18446744073709551615) +#define MAX_INT128 LONGLONG_SUFFIX(85070591730234615865843651857942052864) +#define MIN_INT128 (-MAX_INT128 - LONGLONG_SUFFIX(1)) +#define MAX_UINT128 ULONGLONG_SUFFIX(170141183460469231731687303715884105728) +#define MAX_INT256 LONGLONG_SUFFIX(57896044618658097711785492504343953926634992332820282019728792003956564819967) +#define MIN_INT256 (-MAX_INT256 - LONGLONG_SUFFIX(1)) +#define MAX_UINT256 ULONGLONG_SUFFIX(115792089237316195423570985008687907853269984665640564039457584007913129639935) + +#define MAX_BYTE NPY_MAX_BYTE +#define MIN_BYTE NPY_MIN_BYTE +#define MAX_UBYTE NPY_MAX_UBYTE +#define MAX_SHORT NPY_MAX_SHORT +#define MIN_SHORT NPY_MIN_SHORT +#define MAX_USHORT NPY_MAX_USHORT +#define MAX_INT NPY_MAX_INT +#define MIN_INT NPY_MIN_INT +#define MAX_UINT NPY_MAX_UINT +#define MAX_LONG NPY_MAX_LONG +#define MIN_LONG NPY_MIN_LONG +#define MAX_ULONG NPY_MAX_ULONG +#define MAX_LONGLONG NPY_MAX_LONGLONG +#define MIN_LONGLONG NPY_MIN_LONGLONG +#define MAX_ULONGLONG NPY_MAX_ULONGLONG +#define MIN_DATETIME NPY_MIN_DATETIME +#define MAX_DATETIME NPY_MAX_DATETIME +#define MIN_TIMEDELTA NPY_MIN_TIMEDELTA +#define MAX_TIMEDELTA NPY_MAX_TIMEDELTA + +#define BITSOF_BOOL NPY_BITSOF_BOOL +#define BITSOF_CHAR NPY_BITSOF_CHAR +#define BITSOF_SHORT NPY_BITSOF_SHORT +#define BITSOF_INT NPY_BITSOF_INT +#define BITSOF_LONG NPY_BITSOF_LONG +#define BITSOF_LONGLONG NPY_BITSOF_LONGLONG +#define BITSOF_HALF NPY_BITSOF_HALF +#define BITSOF_FLOAT NPY_BITSOF_FLOAT +#define BITSOF_DOUBLE NPY_BITSOF_DOUBLE +#define BITSOF_LONGDOUBLE NPY_BITSOF_LONGDOUBLE +#define BITSOF_DATETIME NPY_BITSOF_DATETIME +#define BITSOF_TIMEDELTA NPY_BITSOF_TIMEDELTA + +#define _pya_malloc PyArray_malloc +#define _pya_free PyArray_free +#define _pya_realloc PyArray_realloc + +#define BEGIN_THREADS_DEF NPY_BEGIN_THREADS_DEF +#define BEGIN_THREADS NPY_BEGIN_THREADS +#define END_THREADS NPY_END_THREADS +#define ALLOW_C_API_DEF NPY_ALLOW_C_API_DEF +#define ALLOW_C_API NPY_ALLOW_C_API +#define DISABLE_C_API NPY_DISABLE_C_API + +#define PY_FAIL NPY_FAIL +#define PY_SUCCEED NPY_SUCCEED + +#ifndef TRUE +#define TRUE NPY_TRUE +#endif + +#ifndef FALSE +#define FALSE NPY_FALSE +#endif + +#define LONGDOUBLE_FMT NPY_LONGDOUBLE_FMT + +#define CONTIGUOUS NPY_CONTIGUOUS +#define C_CONTIGUOUS NPY_C_CONTIGUOUS +#define FORTRAN NPY_FORTRAN +#define F_CONTIGUOUS NPY_F_CONTIGUOUS +#define OWNDATA NPY_OWNDATA +#define FORCECAST NPY_FORCECAST +#define ENSURECOPY NPY_ENSURECOPY +#define ENSUREARRAY NPY_ENSUREARRAY +#define ELEMENTSTRIDES NPY_ELEMENTSTRIDES +#define ALIGNED NPY_ALIGNED +#define NOTSWAPPED NPY_NOTSWAPPED +#define WRITEABLE NPY_WRITEABLE +#define UPDATEIFCOPY NPY_UPDATEIFCOPY +#define WRITEBACKIFCOPY NPY_ARRAY_WRITEBACKIFCOPY +#define ARR_HAS_DESCR NPY_ARR_HAS_DESCR +#define BEHAVED NPY_BEHAVED +#define BEHAVED_NS NPY_BEHAVED_NS +#define CARRAY NPY_CARRAY +#define CARRAY_RO NPY_CARRAY_RO +#define FARRAY NPY_FARRAY +#define FARRAY_RO NPY_FARRAY_RO +#define DEFAULT NPY_DEFAULT +#define IN_ARRAY NPY_IN_ARRAY +#define OUT_ARRAY NPY_OUT_ARRAY +#define INOUT_ARRAY NPY_INOUT_ARRAY +#define IN_FARRAY NPY_IN_FARRAY +#define OUT_FARRAY NPY_OUT_FARRAY +#define INOUT_FARRAY NPY_INOUT_FARRAY +#define UPDATE_ALL NPY_UPDATE_ALL + +#define OWN_DATA NPY_OWNDATA +#define BEHAVED_FLAGS NPY_BEHAVED +#define BEHAVED_FLAGS_NS NPY_BEHAVED_NS +#define CARRAY_FLAGS_RO NPY_CARRAY_RO +#define CARRAY_FLAGS NPY_CARRAY +#define FARRAY_FLAGS NPY_FARRAY +#define FARRAY_FLAGS_RO NPY_FARRAY_RO +#define DEFAULT_FLAGS NPY_DEFAULT +#define UPDATE_ALL_FLAGS NPY_UPDATE_ALL_FLAGS + +#ifndef MIN +#define MIN PyArray_MIN +#endif +#ifndef MAX +#define MAX PyArray_MAX +#endif +#define MAX_INTP NPY_MAX_INTP +#define MIN_INTP NPY_MIN_INTP +#define MAX_UINTP NPY_MAX_UINTP +#define INTP_FMT NPY_INTP_FMT + +#ifndef PYPY_VERSION +#define REFCOUNT PyArray_REFCOUNT +#define MAX_ELSIZE NPY_MAX_ELSIZE +#endif + +#endif diff --git a/venv/Lib/site-packages/numpy/core/include/numpy/npy_1_7_deprecated_api.h b/venv/Lib/site-packages/numpy/core/include/numpy/npy_1_7_deprecated_api.h new file mode 100644 index 0000000..a4f90e0 --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/include/numpy/npy_1_7_deprecated_api.h @@ -0,0 +1,125 @@ +#ifndef _NPY_1_7_DEPRECATED_API_H +#define _NPY_1_7_DEPRECATED_API_H + +#ifndef NPY_DEPRECATED_INCLUDES +#error "Should never include npy_*_*_deprecated_api directly." +#endif + +/* Emit a warning if the user did not specifically request the old API */ +#ifndef NPY_NO_DEPRECATED_API +#if defined(_WIN32) +#define _WARN___STR2__(x) #x +#define _WARN___STR1__(x) _WARN___STR2__(x) +#define _WARN___LOC__ __FILE__ "(" _WARN___STR1__(__LINE__) ") : Warning Msg: " +#pragma message(_WARN___LOC__"Using deprecated NumPy API, disable it with " \ + "#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION") +#else +#warning "Using deprecated NumPy API, disable it with " \ + "#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION" +#endif +#endif + +/* + * This header exists to collect all dangerous/deprecated NumPy API + * as of NumPy 1.7. + * + * This is an attempt to remove bad API, the proliferation of macros, + * and namespace pollution currently produced by the NumPy headers. + */ + +/* These array flags are deprecated as of NumPy 1.7 */ +#define NPY_CONTIGUOUS NPY_ARRAY_C_CONTIGUOUS +#define NPY_FORTRAN NPY_ARRAY_F_CONTIGUOUS + +/* + * The consistent NPY_ARRAY_* names which don't pollute the NPY_* + * namespace were added in NumPy 1.7. + * + * These versions of the carray flags are deprecated, but + * probably should only be removed after two releases instead of one. + */ +#define NPY_C_CONTIGUOUS NPY_ARRAY_C_CONTIGUOUS +#define NPY_F_CONTIGUOUS NPY_ARRAY_F_CONTIGUOUS +#define NPY_OWNDATA NPY_ARRAY_OWNDATA +#define NPY_FORCECAST NPY_ARRAY_FORCECAST +#define NPY_ENSURECOPY NPY_ARRAY_ENSURECOPY +#define NPY_ENSUREARRAY NPY_ARRAY_ENSUREARRAY +#define NPY_ELEMENTSTRIDES NPY_ARRAY_ELEMENTSTRIDES +#define NPY_ALIGNED NPY_ARRAY_ALIGNED +#define NPY_NOTSWAPPED NPY_ARRAY_NOTSWAPPED +#define NPY_WRITEABLE NPY_ARRAY_WRITEABLE +#define NPY_UPDATEIFCOPY NPY_ARRAY_UPDATEIFCOPY +#define NPY_BEHAVED NPY_ARRAY_BEHAVED +#define NPY_BEHAVED_NS NPY_ARRAY_BEHAVED_NS +#define NPY_CARRAY NPY_ARRAY_CARRAY +#define NPY_CARRAY_RO NPY_ARRAY_CARRAY_RO +#define NPY_FARRAY NPY_ARRAY_FARRAY +#define NPY_FARRAY_RO NPY_ARRAY_FARRAY_RO +#define NPY_DEFAULT NPY_ARRAY_DEFAULT +#define NPY_IN_ARRAY NPY_ARRAY_IN_ARRAY +#define NPY_OUT_ARRAY NPY_ARRAY_OUT_ARRAY +#define NPY_INOUT_ARRAY NPY_ARRAY_INOUT_ARRAY +#define NPY_IN_FARRAY NPY_ARRAY_IN_FARRAY +#define NPY_OUT_FARRAY NPY_ARRAY_OUT_FARRAY +#define NPY_INOUT_FARRAY NPY_ARRAY_INOUT_FARRAY +#define NPY_UPDATE_ALL NPY_ARRAY_UPDATE_ALL + +/* This way of accessing the default type is deprecated as of NumPy 1.7 */ +#define PyArray_DEFAULT NPY_DEFAULT_TYPE + +/* These DATETIME bits aren't used internally */ +#define PyDataType_GetDatetimeMetaData(descr) \ + ((descr->metadata == NULL) ? NULL : \ + ((PyArray_DatetimeMetaData *)(PyCapsule_GetPointer( \ + PyDict_GetItemString( \ + descr->metadata, NPY_METADATA_DTSTR), NULL)))) + +/* + * Deprecated as of NumPy 1.7, this kind of shortcut doesn't + * belong in the public API. + */ +#define NPY_AO PyArrayObject + +/* + * Deprecated as of NumPy 1.7, an all-lowercase macro doesn't + * belong in the public API. + */ +#define fortran fortran_ + +/* + * Deprecated as of NumPy 1.7, as it is a namespace-polluting + * macro. + */ +#define FORTRAN_IF PyArray_FORTRAN_IF + +/* Deprecated as of NumPy 1.7, datetime64 uses c_metadata instead */ +#define NPY_METADATA_DTSTR "__timeunit__" + +/* + * Deprecated as of NumPy 1.7. + * The reasoning: + * - These are for datetime, but there's no datetime "namespace". + * - They just turn NPY_STR_ into "", which is just + * making something simple be indirected. + */ +#define NPY_STR_Y "Y" +#define NPY_STR_M "M" +#define NPY_STR_W "W" +#define NPY_STR_D "D" +#define NPY_STR_h "h" +#define NPY_STR_m "m" +#define NPY_STR_s "s" +#define NPY_STR_ms "ms" +#define NPY_STR_us "us" +#define NPY_STR_ns "ns" +#define NPY_STR_ps "ps" +#define NPY_STR_fs "fs" +#define NPY_STR_as "as" + +/* + * The macros in old_defines.h are Deprecated as of NumPy 1.7 and will be + * removed in the next major release. + */ +#include "old_defines.h" + +#endif diff --git a/venv/Lib/site-packages/numpy/core/include/numpy/npy_3kcompat.h b/venv/Lib/site-packages/numpy/core/include/numpy/npy_3kcompat.h new file mode 100644 index 0000000..191cd24 --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/include/numpy/npy_3kcompat.h @@ -0,0 +1,585 @@ +/* + * This is a convenience header file providing compatibility utilities + * for supporting Python 2 and Python 3 in the same code base. + * + * If you want to use this for your own projects, it's recommended to make a + * copy of it. Although the stuff below is unlikely to change, we don't provide + * strong backwards compatibility guarantees at the moment. + */ + +#ifndef _NPY_3KCOMPAT_H_ +#define _NPY_3KCOMPAT_H_ + +#include +#include + +#ifndef NPY_PY3K +#define NPY_PY3K 1 +#endif + +#include "numpy/npy_common.h" +#include "numpy/ndarrayobject.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * PyInt -> PyLong + */ + + +/* + * This is a renamed copy of the Python non-limited API function _PyLong_AsInt. It is + * included here because it is missing from the PyPy API. It completes the PyLong_As* + * group of functions and can be useful in replacing PyInt_Check. + */ +static NPY_INLINE int +Npy__PyLong_AsInt(PyObject *obj) +{ + int overflow; + long result = PyLong_AsLongAndOverflow(obj, &overflow); + + /* INT_MAX and INT_MIN are defined in Python.h */ + if (overflow || result > INT_MAX || result < INT_MIN) { + /* XXX: could be cute and give a different + message for overflow == -1 */ + PyErr_SetString(PyExc_OverflowError, + "Python int too large to convert to C int"); + return -1; + } + return (int)result; +} + + +#if defined(NPY_PY3K) +/* Return True only if the long fits in a C long */ +static NPY_INLINE int PyInt_Check(PyObject *op) { + int overflow = 0; + if (!PyLong_Check(op)) { + return 0; + } + PyLong_AsLongAndOverflow(op, &overflow); + return (overflow == 0); +} + + +#define PyInt_FromLong PyLong_FromLong +#define PyInt_AsLong PyLong_AsLong +#define PyInt_AS_LONG PyLong_AsLong +#define PyInt_AsSsize_t PyLong_AsSsize_t +#define PyNumber_Int PyNumber_Long + +/* NOTE: + * + * Since the PyLong type is very different from the fixed-range PyInt, + * we don't define PyInt_Type -> PyLong_Type. + */ +#endif /* NPY_PY3K */ + +/* Py3 changes PySlice_GetIndicesEx' first argument's type to PyObject* */ +#ifdef NPY_PY3K +# define NpySlice_GetIndicesEx PySlice_GetIndicesEx +#else +# define NpySlice_GetIndicesEx(op, nop, start, end, step, slicelength) \ + PySlice_GetIndicesEx((PySliceObject *)op, nop, start, end, step, slicelength) +#endif + +#if PY_VERSION_HEX < 0x030900a4 + /* Introduced in https://github.com/python/cpython/commit/d2ec81a8c99796b51fb8c49b77a7fe369863226f */ + #define Py_SET_TYPE(obj, type) ((Py_TYPE(obj) = (type)), (void)0) + /* Introduced in https://github.com/python/cpython/commit/b10dc3e7a11fcdb97e285882eba6da92594f90f9 */ + #define Py_SET_SIZE(obj, size) ((Py_SIZE(obj) = (size)), (void)0) + /* Introduced in https://github.com/python/cpython/commit/c86a11221df7e37da389f9c6ce6e47ea22dc44ff */ + #define Py_SET_REFCNT(obj, refcnt) ((Py_REFCNT(obj) = (refcnt)), (void)0) +#endif + + +#define Npy_EnterRecursiveCall(x) Py_EnterRecursiveCall(x) + +/* Py_SETREF was added in 3.5.2, and only if Py_LIMITED_API is absent */ +#if PY_VERSION_HEX < 0x03050200 + #define Py_SETREF(op, op2) \ + do { \ + PyObject *_py_tmp = (PyObject *)(op); \ + (op) = (op2); \ + Py_DECREF(_py_tmp); \ + } while (0) +#endif + +/* introduced in https://github.com/python/cpython/commit/a24107b04c1277e3c1105f98aff5bfa3a98b33a0 */ +#if PY_VERSION_HEX < 0x030800A3 + static NPY_INLINE PyObject * + _PyDict_GetItemStringWithError(PyObject *v, const char *key) + { + PyObject *kv, *rv; + kv = PyUnicode_FromString(key); + if (kv == NULL) { + return NULL; + } + rv = PyDict_GetItemWithError(v, kv); + Py_DECREF(kv); + return rv; + } +#endif + +/* + * PyString -> PyBytes + */ + +#if defined(NPY_PY3K) + +#define PyString_Type PyBytes_Type +#define PyString_Check PyBytes_Check +#define PyStringObject PyBytesObject +#define PyString_FromString PyBytes_FromString +#define PyString_FromStringAndSize PyBytes_FromStringAndSize +#define PyString_AS_STRING PyBytes_AS_STRING +#define PyString_AsStringAndSize PyBytes_AsStringAndSize +#define PyString_FromFormat PyBytes_FromFormat +#define PyString_Concat PyBytes_Concat +#define PyString_ConcatAndDel PyBytes_ConcatAndDel +#define PyString_AsString PyBytes_AsString +#define PyString_GET_SIZE PyBytes_GET_SIZE +#define PyString_Size PyBytes_Size + +#define PyUString_Type PyUnicode_Type +#define PyUString_Check PyUnicode_Check +#define PyUStringObject PyUnicodeObject +#define PyUString_FromString PyUnicode_FromString +#define PyUString_FromStringAndSize PyUnicode_FromStringAndSize +#define PyUString_FromFormat PyUnicode_FromFormat +#define PyUString_Concat PyUnicode_Concat2 +#define PyUString_ConcatAndDel PyUnicode_ConcatAndDel +#define PyUString_GET_SIZE PyUnicode_GET_SIZE +#define PyUString_Size PyUnicode_Size +#define PyUString_InternFromString PyUnicode_InternFromString +#define PyUString_Format PyUnicode_Format + +#define PyBaseString_Check(obj) (PyUnicode_Check(obj)) + +#else + +#define PyBytes_Type PyString_Type +#define PyBytes_Check PyString_Check +#define PyBytesObject PyStringObject +#define PyBytes_FromString PyString_FromString +#define PyBytes_FromStringAndSize PyString_FromStringAndSize +#define PyBytes_AS_STRING PyString_AS_STRING +#define PyBytes_AsStringAndSize PyString_AsStringAndSize +#define PyBytes_FromFormat PyString_FromFormat +#define PyBytes_Concat PyString_Concat +#define PyBytes_ConcatAndDel PyString_ConcatAndDel +#define PyBytes_AsString PyString_AsString +#define PyBytes_GET_SIZE PyString_GET_SIZE +#define PyBytes_Size PyString_Size + +#define PyUString_Type PyString_Type +#define PyUString_Check PyString_Check +#define PyUStringObject PyStringObject +#define PyUString_FromString PyString_FromString +#define PyUString_FromStringAndSize PyString_FromStringAndSize +#define PyUString_FromFormat PyString_FromFormat +#define PyUString_Concat PyString_Concat +#define PyUString_ConcatAndDel PyString_ConcatAndDel +#define PyUString_GET_SIZE PyString_GET_SIZE +#define PyUString_Size PyString_Size +#define PyUString_InternFromString PyString_InternFromString +#define PyUString_Format PyString_Format + +#define PyBaseString_Check(obj) (PyBytes_Check(obj) || PyUnicode_Check(obj)) + +#endif /* NPY_PY3K */ + + +static NPY_INLINE void +PyUnicode_ConcatAndDel(PyObject **left, PyObject *right) +{ + Py_SETREF(*left, PyUnicode_Concat(*left, right)); + Py_DECREF(right); +} + +static NPY_INLINE void +PyUnicode_Concat2(PyObject **left, PyObject *right) +{ + Py_SETREF(*left, PyUnicode_Concat(*left, right)); +} + +/* + * PyFile_* compatibility + */ + +/* + * Get a FILE* handle to the file represented by the Python object + */ +static NPY_INLINE FILE* +npy_PyFile_Dup2(PyObject *file, char *mode, npy_off_t *orig_pos) +{ + int fd, fd2, unbuf; + PyObject *ret, *os, *io, *io_raw; + npy_off_t pos; + FILE *handle; + + /* For Python 2 PyFileObject, use PyFile_AsFile */ +#if !defined(NPY_PY3K) + if (PyFile_Check(file)) { + return PyFile_AsFile(file); + } +#endif + + /* Flush first to ensure things end up in the file in the correct order */ + ret = PyObject_CallMethod(file, "flush", ""); + if (ret == NULL) { + return NULL; + } + Py_DECREF(ret); + fd = PyObject_AsFileDescriptor(file); + if (fd == -1) { + return NULL; + } + + /* + * The handle needs to be dup'd because we have to call fclose + * at the end + */ + os = PyImport_ImportModule("os"); + if (os == NULL) { + return NULL; + } + ret = PyObject_CallMethod(os, "dup", "i", fd); + Py_DECREF(os); + if (ret == NULL) { + return NULL; + } + fd2 = PyNumber_AsSsize_t(ret, NULL); + Py_DECREF(ret); + + /* Convert to FILE* handle */ +#ifdef _WIN32 + handle = _fdopen(fd2, mode); +#else + handle = fdopen(fd2, mode); +#endif + if (handle == NULL) { + PyErr_SetString(PyExc_IOError, + "Getting a FILE* from a Python file object failed"); + return NULL; + } + + /* Record the original raw file handle position */ + *orig_pos = npy_ftell(handle); + if (*orig_pos == -1) { + /* The io module is needed to determine if buffering is used */ + io = PyImport_ImportModule("io"); + if (io == NULL) { + fclose(handle); + return NULL; + } + /* File object instances of RawIOBase are unbuffered */ + io_raw = PyObject_GetAttrString(io, "RawIOBase"); + Py_DECREF(io); + if (io_raw == NULL) { + fclose(handle); + return NULL; + } + unbuf = PyObject_IsInstance(file, io_raw); + Py_DECREF(io_raw); + if (unbuf == 1) { + /* Succeed if the IO is unbuffered */ + return handle; + } + else { + PyErr_SetString(PyExc_IOError, "obtaining file position failed"); + fclose(handle); + return NULL; + } + } + + /* Seek raw handle to the Python-side position */ + ret = PyObject_CallMethod(file, "tell", ""); + if (ret == NULL) { + fclose(handle); + return NULL; + } + pos = PyLong_AsLongLong(ret); + Py_DECREF(ret); + if (PyErr_Occurred()) { + fclose(handle); + return NULL; + } + if (npy_fseek(handle, pos, SEEK_SET) == -1) { + PyErr_SetString(PyExc_IOError, "seeking file failed"); + fclose(handle); + return NULL; + } + return handle; +} + +/* + * Close the dup-ed file handle, and seek the Python one to the current position + */ +static NPY_INLINE int +npy_PyFile_DupClose2(PyObject *file, FILE* handle, npy_off_t orig_pos) +{ + int fd, unbuf; + PyObject *ret, *io, *io_raw; + npy_off_t position; + + /* For Python 2 PyFileObject, do nothing */ +#if !defined(NPY_PY3K) + if (PyFile_Check(file)) { + return 0; + } +#endif + + position = npy_ftell(handle); + + /* Close the FILE* handle */ + fclose(handle); + + /* + * Restore original file handle position, in order to not confuse + * Python-side data structures + */ + fd = PyObject_AsFileDescriptor(file); + if (fd == -1) { + return -1; + } + + if (npy_lseek(fd, orig_pos, SEEK_SET) == -1) { + + /* The io module is needed to determine if buffering is used */ + io = PyImport_ImportModule("io"); + if (io == NULL) { + return -1; + } + /* File object instances of RawIOBase are unbuffered */ + io_raw = PyObject_GetAttrString(io, "RawIOBase"); + Py_DECREF(io); + if (io_raw == NULL) { + return -1; + } + unbuf = PyObject_IsInstance(file, io_raw); + Py_DECREF(io_raw); + if (unbuf == 1) { + /* Succeed if the IO is unbuffered */ + return 0; + } + else { + PyErr_SetString(PyExc_IOError, "seeking file failed"); + return -1; + } + } + + if (position == -1) { + PyErr_SetString(PyExc_IOError, "obtaining file position failed"); + return -1; + } + + /* Seek Python-side handle to the FILE* handle position */ + ret = PyObject_CallMethod(file, "seek", NPY_OFF_T_PYFMT "i", position, 0); + if (ret == NULL) { + return -1; + } + Py_DECREF(ret); + return 0; +} + +static NPY_INLINE int +npy_PyFile_Check(PyObject *file) +{ + int fd; + /* For Python 2, check if it is a PyFileObject */ +#if !defined(NPY_PY3K) + if (PyFile_Check(file)) { + return 1; + } +#endif + fd = PyObject_AsFileDescriptor(file); + if (fd == -1) { + PyErr_Clear(); + return 0; + } + return 1; +} + +static NPY_INLINE PyObject* +npy_PyFile_OpenFile(PyObject *filename, const char *mode) +{ + PyObject *open; + open = PyDict_GetItemString(PyEval_GetBuiltins(), "open"); + if (open == NULL) { + return NULL; + } + return PyObject_CallFunction(open, "Os", filename, mode); +} + +static NPY_INLINE int +npy_PyFile_CloseFile(PyObject *file) +{ + PyObject *ret; + + ret = PyObject_CallMethod(file, "close", NULL); + if (ret == NULL) { + return -1; + } + Py_DECREF(ret); + return 0; +} + + +/* This is a copy of _PyErr_ChainExceptions + */ +static NPY_INLINE void +npy_PyErr_ChainExceptions(PyObject *exc, PyObject *val, PyObject *tb) +{ + if (exc == NULL) + return; + + if (PyErr_Occurred()) { + /* only py3 supports this anyway */ + #ifdef NPY_PY3K + PyObject *exc2, *val2, *tb2; + PyErr_Fetch(&exc2, &val2, &tb2); + PyErr_NormalizeException(&exc, &val, &tb); + if (tb != NULL) { + PyException_SetTraceback(val, tb); + Py_DECREF(tb); + } + Py_DECREF(exc); + PyErr_NormalizeException(&exc2, &val2, &tb2); + PyException_SetContext(val2, val); + PyErr_Restore(exc2, val2, tb2); + #endif + } + else { + PyErr_Restore(exc, val, tb); + } +} + + +/* This is a copy of _PyErr_ChainExceptions, with: + * - a minimal implementation for python 2 + * - __cause__ used instead of __context__ + */ +static NPY_INLINE void +npy_PyErr_ChainExceptionsCause(PyObject *exc, PyObject *val, PyObject *tb) +{ + if (exc == NULL) + return; + + if (PyErr_Occurred()) { + /* only py3 supports this anyway */ + #ifdef NPY_PY3K + PyObject *exc2, *val2, *tb2; + PyErr_Fetch(&exc2, &val2, &tb2); + PyErr_NormalizeException(&exc, &val, &tb); + if (tb != NULL) { + PyException_SetTraceback(val, tb); + Py_DECREF(tb); + } + Py_DECREF(exc); + PyErr_NormalizeException(&exc2, &val2, &tb2); + PyException_SetCause(val2, val); + PyErr_Restore(exc2, val2, tb2); + #endif + } + else { + PyErr_Restore(exc, val, tb); + } +} + +/* + * PyObject_Cmp + */ +#if defined(NPY_PY3K) +static NPY_INLINE int +PyObject_Cmp(PyObject *i1, PyObject *i2, int *cmp) +{ + int v; + v = PyObject_RichCompareBool(i1, i2, Py_LT); + if (v == 1) { + *cmp = -1; + return 1; + } + else if (v == -1) { + return -1; + } + + v = PyObject_RichCompareBool(i1, i2, Py_GT); + if (v == 1) { + *cmp = 1; + return 1; + } + else if (v == -1) { + return -1; + } + + v = PyObject_RichCompareBool(i1, i2, Py_EQ); + if (v == 1) { + *cmp = 0; + return 1; + } + else { + *cmp = 0; + return -1; + } +} +#endif + +/* + * PyCObject functions adapted to PyCapsules. + * + * The main job here is to get rid of the improved error handling + * of PyCapsules. It's a shame... + */ +static NPY_INLINE PyObject * +NpyCapsule_FromVoidPtr(void *ptr, void (*dtor)(PyObject *)) +{ + PyObject *ret = PyCapsule_New(ptr, NULL, dtor); + if (ret == NULL) { + PyErr_Clear(); + } + return ret; +} + +static NPY_INLINE PyObject * +NpyCapsule_FromVoidPtrAndDesc(void *ptr, void* context, void (*dtor)(PyObject *)) +{ + PyObject *ret = NpyCapsule_FromVoidPtr(ptr, dtor); + if (ret != NULL && PyCapsule_SetContext(ret, context) != 0) { + PyErr_Clear(); + Py_DECREF(ret); + ret = NULL; + } + return ret; +} + +static NPY_INLINE void * +NpyCapsule_AsVoidPtr(PyObject *obj) +{ + void *ret = PyCapsule_GetPointer(obj, NULL); + if (ret == NULL) { + PyErr_Clear(); + } + return ret; +} + +static NPY_INLINE void * +NpyCapsule_GetDesc(PyObject *obj) +{ + return PyCapsule_GetContext(obj); +} + +static NPY_INLINE int +NpyCapsule_Check(PyObject *ptr) +{ + return PyCapsule_CheckExact(ptr); +} + +#ifdef __cplusplus +} +#endif + + +#endif /* _NPY_3KCOMPAT_H_ */ diff --git a/venv/Lib/site-packages/numpy/core/include/numpy/npy_common.h b/venv/Lib/site-packages/numpy/core/include/numpy/npy_common.h new file mode 100644 index 0000000..78d6d31 --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/include/numpy/npy_common.h @@ -0,0 +1,1108 @@ +#ifndef _NPY_COMMON_H_ +#define _NPY_COMMON_H_ + +/* need Python.h for npy_intp, npy_uintp */ +#include + +/* numpconfig.h is auto-generated */ +#include "numpyconfig.h" +#ifdef HAVE_NPY_CONFIG_H +#include +#endif + +/* + * using static inline modifiers when defining npy_math functions + * allows the compiler to make optimizations when possible + */ +#if defined(NPY_INTERNAL_BUILD) && NPY_INTERNAL_BUILD +#ifndef NPY_INLINE_MATH +#define NPY_INLINE_MATH 1 +#endif +#endif + +/* + * gcc does not unroll even with -O3 + * use with care, unrolling on modern cpus rarely speeds things up + */ +#ifdef HAVE_ATTRIBUTE_OPTIMIZE_UNROLL_LOOPS +#define NPY_GCC_UNROLL_LOOPS \ + __attribute__((optimize("unroll-loops"))) +#else +#define NPY_GCC_UNROLL_LOOPS +#endif + +/* highest gcc optimization level, enabled autovectorizer */ +#ifdef HAVE_ATTRIBUTE_OPTIMIZE_OPT_3 +#define NPY_GCC_OPT_3 __attribute__((optimize("O3"))) +#else +#define NPY_GCC_OPT_3 +#endif + +/* compile target attributes */ +#if defined HAVE_ATTRIBUTE_TARGET_AVX && defined HAVE_LINK_AVX +#define NPY_GCC_TARGET_AVX __attribute__((target("avx"))) +#else +#define NPY_GCC_TARGET_AVX +#endif + +#if defined HAVE_ATTRIBUTE_TARGET_AVX2_WITH_INTRINSICS +#define HAVE_ATTRIBUTE_TARGET_FMA +#define NPY_GCC_TARGET_FMA __attribute__((target("avx2,fma"))) +#endif + +#if defined HAVE_ATTRIBUTE_TARGET_AVX2 && defined HAVE_LINK_AVX2 +#define NPY_GCC_TARGET_AVX2 __attribute__((target("avx2"))) +#else +#define NPY_GCC_TARGET_AVX2 +#endif + +#if defined HAVE_ATTRIBUTE_TARGET_AVX512F && defined HAVE_LINK_AVX512F +#define NPY_GCC_TARGET_AVX512F __attribute__((target("avx512f"))) +#elif defined HAVE_ATTRIBUTE_TARGET_AVX512F_WITH_INTRINSICS +#define NPY_GCC_TARGET_AVX512F __attribute__((target("avx512f"))) +#else +#define NPY_GCC_TARGET_AVX512F +#endif + +#if defined HAVE_ATTRIBUTE_TARGET_AVX512_SKX && defined HAVE_LINK_AVX512_SKX +#define NPY_GCC_TARGET_AVX512_SKX __attribute__((target("avx512f,avx512dq,avx512vl,avx512bw,avx512cd"))) +#elif defined HAVE_ATTRIBUTE_TARGET_AVX512_SKX_WITH_INTRINSICS +#define NPY_GCC_TARGET_AVX512_SKX __attribute__((target("avx512f,avx512dq,avx512vl,avx512bw,avx512cd"))) +#else +#define NPY_GCC_TARGET_AVX512_SKX +#endif +/* + * mark an argument (starting from 1) that must not be NULL and is not checked + * DO NOT USE IF FUNCTION CHECKS FOR NULL!! the compiler will remove the check + */ +#ifdef HAVE_ATTRIBUTE_NONNULL +#define NPY_GCC_NONNULL(n) __attribute__((nonnull(n))) +#else +#define NPY_GCC_NONNULL(n) +#endif + +#if defined HAVE_XMMINTRIN_H && defined HAVE__MM_LOAD_PS +#define NPY_HAVE_SSE_INTRINSICS +#endif + +#if defined HAVE_EMMINTRIN_H && defined HAVE__MM_LOAD_PD +#define NPY_HAVE_SSE2_INTRINSICS +#endif + +#if defined HAVE_IMMINTRIN_H && defined HAVE_LINK_AVX2 +#define NPY_HAVE_AVX2_INTRINSICS +#endif + +#if defined HAVE_IMMINTRIN_H && defined HAVE_LINK_AVX512F +#define NPY_HAVE_AVX512F_INTRINSICS +#endif +/* + * give a hint to the compiler which branch is more likely or unlikely + * to occur, e.g. rare error cases: + * + * if (NPY_UNLIKELY(failure == 0)) + * return NULL; + * + * the double !! is to cast the expression (e.g. NULL) to a boolean required by + * the intrinsic + */ +#ifdef HAVE___BUILTIN_EXPECT +#define NPY_LIKELY(x) __builtin_expect(!!(x), 1) +#define NPY_UNLIKELY(x) __builtin_expect(!!(x), 0) +#else +#define NPY_LIKELY(x) (x) +#define NPY_UNLIKELY(x) (x) +#endif + +#ifdef HAVE___BUILTIN_PREFETCH +/* unlike _mm_prefetch also works on non-x86 */ +#define NPY_PREFETCH(x, rw, loc) __builtin_prefetch((x), (rw), (loc)) +#else +#ifdef HAVE__MM_PREFETCH +/* _MM_HINT_ET[01] (rw = 1) unsupported, only available in gcc >= 4.9 */ +#define NPY_PREFETCH(x, rw, loc) _mm_prefetch((x), loc == 0 ? _MM_HINT_NTA : \ + (loc == 1 ? _MM_HINT_T2 : \ + (loc == 2 ? _MM_HINT_T1 : \ + (loc == 3 ? _MM_HINT_T0 : -1)))) +#else +#define NPY_PREFETCH(x, rw,loc) +#endif +#endif + +#if defined(_MSC_VER) + #define NPY_INLINE __inline +#elif defined(__GNUC__) + #if defined(__STRICT_ANSI__) + #define NPY_INLINE __inline__ + #else + #define NPY_INLINE inline + #endif +#else + #define NPY_INLINE +#endif + +#ifdef _MSC_VER + #define NPY_FINLINE static __forceinline +#elif defined(__GNUC__) + #define NPY_FINLINE static NPY_INLINE __attribute__((always_inline)) +#else + #define NPY_FINLINE static +#endif + +#ifdef HAVE___THREAD + #define NPY_TLS __thread +#else + #ifdef HAVE___DECLSPEC_THREAD_ + #define NPY_TLS __declspec(thread) + #else + #define NPY_TLS + #endif +#endif + +#ifdef WITH_CPYCHECKER_RETURNS_BORROWED_REF_ATTRIBUTE + #define NPY_RETURNS_BORROWED_REF \ + __attribute__((cpychecker_returns_borrowed_ref)) +#else + #define NPY_RETURNS_BORROWED_REF +#endif + +#ifdef WITH_CPYCHECKER_STEALS_REFERENCE_TO_ARG_ATTRIBUTE + #define NPY_STEALS_REF_TO_ARG(n) \ + __attribute__((cpychecker_steals_reference_to_arg(n))) +#else + #define NPY_STEALS_REF_TO_ARG(n) +#endif + +/* 64 bit file position support, also on win-amd64. Ticket #1660 */ +#if defined(_MSC_VER) && defined(_WIN64) && (_MSC_VER > 1400) || \ + defined(__MINGW32__) || defined(__MINGW64__) + #include + +/* mingw based on 3.4.5 has lseek but not ftell/fseek */ +#if defined(__MINGW32__) || defined(__MINGW64__) +extern int __cdecl _fseeki64(FILE *, long long, int); +extern long long __cdecl _ftelli64(FILE *); +#endif + + #define npy_fseek _fseeki64 + #define npy_ftell _ftelli64 + #define npy_lseek _lseeki64 + #define npy_off_t npy_int64 + + #if NPY_SIZEOF_INT == 8 + #define NPY_OFF_T_PYFMT "i" + #elif NPY_SIZEOF_LONG == 8 + #define NPY_OFF_T_PYFMT "l" + #elif NPY_SIZEOF_LONGLONG == 8 + #define NPY_OFF_T_PYFMT "L" + #else + #error Unsupported size for type off_t + #endif +#else +#ifdef HAVE_FSEEKO + #define npy_fseek fseeko +#else + #define npy_fseek fseek +#endif +#ifdef HAVE_FTELLO + #define npy_ftell ftello +#else + #define npy_ftell ftell +#endif + #include + #define npy_lseek lseek + #define npy_off_t off_t + + #if NPY_SIZEOF_OFF_T == NPY_SIZEOF_SHORT + #define NPY_OFF_T_PYFMT "h" + #elif NPY_SIZEOF_OFF_T == NPY_SIZEOF_INT + #define NPY_OFF_T_PYFMT "i" + #elif NPY_SIZEOF_OFF_T == NPY_SIZEOF_LONG + #define NPY_OFF_T_PYFMT "l" + #elif NPY_SIZEOF_OFF_T == NPY_SIZEOF_LONGLONG + #define NPY_OFF_T_PYFMT "L" + #else + #error Unsupported size for type off_t + #endif +#endif + +/* enums for detected endianness */ +enum { + NPY_CPU_UNKNOWN_ENDIAN, + NPY_CPU_LITTLE, + NPY_CPU_BIG +}; + +/* + * This is to typedef npy_intp to the appropriate pointer size for this + * platform. Py_intptr_t, Py_uintptr_t are defined in pyport.h. + */ +typedef Py_intptr_t npy_intp; +typedef Py_uintptr_t npy_uintp; + +/* + * Define sizes that were not defined in numpyconfig.h. + */ +#define NPY_SIZEOF_CHAR 1 +#define NPY_SIZEOF_BYTE 1 +#define NPY_SIZEOF_DATETIME 8 +#define NPY_SIZEOF_TIMEDELTA 8 +#define NPY_SIZEOF_INTP NPY_SIZEOF_PY_INTPTR_T +#define NPY_SIZEOF_UINTP NPY_SIZEOF_PY_INTPTR_T +#define NPY_SIZEOF_HALF 2 +#define NPY_SIZEOF_CFLOAT NPY_SIZEOF_COMPLEX_FLOAT +#define NPY_SIZEOF_CDOUBLE NPY_SIZEOF_COMPLEX_DOUBLE +#define NPY_SIZEOF_CLONGDOUBLE NPY_SIZEOF_COMPLEX_LONGDOUBLE + +#ifdef constchar +#undef constchar +#endif + +#define NPY_SSIZE_T_PYFMT "n" +#define constchar char + +/* NPY_INTP_FMT Note: + * Unlike the other NPY_*_FMT macros, which are used with PyOS_snprintf, + * NPY_INTP_FMT is used with PyErr_Format and PyUnicode_FromFormat. Those + * functions use different formatting codes that are portably specified + * according to the Python documentation. See issue gh-2388. + */ +#if NPY_SIZEOF_PY_INTPTR_T == NPY_SIZEOF_INT + #define NPY_INTP NPY_INT + #define NPY_UINTP NPY_UINT + #define PyIntpArrType_Type PyIntArrType_Type + #define PyUIntpArrType_Type PyUIntArrType_Type + #define NPY_MAX_INTP NPY_MAX_INT + #define NPY_MIN_INTP NPY_MIN_INT + #define NPY_MAX_UINTP NPY_MAX_UINT + #define NPY_INTP_FMT "d" +#elif NPY_SIZEOF_PY_INTPTR_T == NPY_SIZEOF_LONG + #define NPY_INTP NPY_LONG + #define NPY_UINTP NPY_ULONG + #define PyIntpArrType_Type PyLongArrType_Type + #define PyUIntpArrType_Type PyULongArrType_Type + #define NPY_MAX_INTP NPY_MAX_LONG + #define NPY_MIN_INTP NPY_MIN_LONG + #define NPY_MAX_UINTP NPY_MAX_ULONG + #define NPY_INTP_FMT "ld" +#elif defined(PY_LONG_LONG) && (NPY_SIZEOF_PY_INTPTR_T == NPY_SIZEOF_LONGLONG) + #define NPY_INTP NPY_LONGLONG + #define NPY_UINTP NPY_ULONGLONG + #define PyIntpArrType_Type PyLongLongArrType_Type + #define PyUIntpArrType_Type PyULongLongArrType_Type + #define NPY_MAX_INTP NPY_MAX_LONGLONG + #define NPY_MIN_INTP NPY_MIN_LONGLONG + #define NPY_MAX_UINTP NPY_MAX_ULONGLONG + #define NPY_INTP_FMT "lld" +#endif + +/* + * We can only use C99 formats for npy_int_p if it is the same as + * intp_t, hence the condition on HAVE_UNITPTR_T + */ +#if (NPY_USE_C99_FORMATS) == 1 \ + && (defined HAVE_UINTPTR_T) \ + && (defined HAVE_INTTYPES_H) + #include + #undef NPY_INTP_FMT + #define NPY_INTP_FMT PRIdPTR +#endif + + +/* + * Some platforms don't define bool, long long, or long double. + * Handle that here. + */ +#define NPY_BYTE_FMT "hhd" +#define NPY_UBYTE_FMT "hhu" +#define NPY_SHORT_FMT "hd" +#define NPY_USHORT_FMT "hu" +#define NPY_INT_FMT "d" +#define NPY_UINT_FMT "u" +#define NPY_LONG_FMT "ld" +#define NPY_ULONG_FMT "lu" +#define NPY_HALF_FMT "g" +#define NPY_FLOAT_FMT "g" +#define NPY_DOUBLE_FMT "g" + + +#ifdef PY_LONG_LONG +typedef PY_LONG_LONG npy_longlong; +typedef unsigned PY_LONG_LONG npy_ulonglong; +# ifdef _MSC_VER +# define NPY_LONGLONG_FMT "I64d" +# define NPY_ULONGLONG_FMT "I64u" +# else +# define NPY_LONGLONG_FMT "lld" +# define NPY_ULONGLONG_FMT "llu" +# endif +# ifdef _MSC_VER +# define NPY_LONGLONG_SUFFIX(x) (x##i64) +# define NPY_ULONGLONG_SUFFIX(x) (x##Ui64) +# else +# define NPY_LONGLONG_SUFFIX(x) (x##LL) +# define NPY_ULONGLONG_SUFFIX(x) (x##ULL) +# endif +#else +typedef long npy_longlong; +typedef unsigned long npy_ulonglong; +# define NPY_LONGLONG_SUFFIX(x) (x##L) +# define NPY_ULONGLONG_SUFFIX(x) (x##UL) +#endif + + +typedef unsigned char npy_bool; +#define NPY_FALSE 0 +#define NPY_TRUE 1 + + +#if NPY_SIZEOF_LONGDOUBLE == NPY_SIZEOF_DOUBLE + typedef double npy_longdouble; + #define NPY_LONGDOUBLE_FMT "g" +#else + typedef long double npy_longdouble; + #define NPY_LONGDOUBLE_FMT "Lg" +#endif + +#ifndef Py_USING_UNICODE +#error Must use Python with unicode enabled. +#endif + + +typedef signed char npy_byte; +typedef unsigned char npy_ubyte; +typedef unsigned short npy_ushort; +typedef unsigned int npy_uint; +typedef unsigned long npy_ulong; + +/* These are for completeness */ +typedef char npy_char; +typedef short npy_short; +typedef int npy_int; +typedef long npy_long; +typedef float npy_float; +typedef double npy_double; + +typedef Py_hash_t npy_hash_t; +#define NPY_SIZEOF_HASH_T NPY_SIZEOF_INTP + +/* + * Disabling C99 complex usage: a lot of C code in numpy/scipy rely on being + * able to do .real/.imag. Will have to convert code first. + */ +#if 0 +#if defined(NPY_USE_C99_COMPLEX) && defined(NPY_HAVE_COMPLEX_DOUBLE) +typedef complex npy_cdouble; +#else +typedef struct { double real, imag; } npy_cdouble; +#endif + +#if defined(NPY_USE_C99_COMPLEX) && defined(NPY_HAVE_COMPLEX_FLOAT) +typedef complex float npy_cfloat; +#else +typedef struct { float real, imag; } npy_cfloat; +#endif + +#if defined(NPY_USE_C99_COMPLEX) && defined(NPY_HAVE_COMPLEX_LONG_DOUBLE) +typedef complex long double npy_clongdouble; +#else +typedef struct {npy_longdouble real, imag;} npy_clongdouble; +#endif +#endif +#if NPY_SIZEOF_COMPLEX_DOUBLE != 2 * NPY_SIZEOF_DOUBLE +#error npy_cdouble definition is not compatible with C99 complex definition ! \ + Please contact NumPy maintainers and give detailed information about your \ + compiler and platform +#endif +typedef struct { double real, imag; } npy_cdouble; + +#if NPY_SIZEOF_COMPLEX_FLOAT != 2 * NPY_SIZEOF_FLOAT +#error npy_cfloat definition is not compatible with C99 complex definition ! \ + Please contact NumPy maintainers and give detailed information about your \ + compiler and platform +#endif +typedef struct { float real, imag; } npy_cfloat; + +#if NPY_SIZEOF_COMPLEX_LONGDOUBLE != 2 * NPY_SIZEOF_LONGDOUBLE +#error npy_clongdouble definition is not compatible with C99 complex definition ! \ + Please contact NumPy maintainers and give detailed information about your \ + compiler and platform +#endif +typedef struct { npy_longdouble real, imag; } npy_clongdouble; + +/* + * numarray-style bit-width typedefs + */ +#define NPY_MAX_INT8 127 +#define NPY_MIN_INT8 -128 +#define NPY_MAX_UINT8 255 +#define NPY_MAX_INT16 32767 +#define NPY_MIN_INT16 -32768 +#define NPY_MAX_UINT16 65535 +#define NPY_MAX_INT32 2147483647 +#define NPY_MIN_INT32 (-NPY_MAX_INT32 - 1) +#define NPY_MAX_UINT32 4294967295U +#define NPY_MAX_INT64 NPY_LONGLONG_SUFFIX(9223372036854775807) +#define NPY_MIN_INT64 (-NPY_MAX_INT64 - NPY_LONGLONG_SUFFIX(1)) +#define NPY_MAX_UINT64 NPY_ULONGLONG_SUFFIX(18446744073709551615) +#define NPY_MAX_INT128 NPY_LONGLONG_SUFFIX(85070591730234615865843651857942052864) +#define NPY_MIN_INT128 (-NPY_MAX_INT128 - NPY_LONGLONG_SUFFIX(1)) +#define NPY_MAX_UINT128 NPY_ULONGLONG_SUFFIX(170141183460469231731687303715884105728) +#define NPY_MAX_INT256 NPY_LONGLONG_SUFFIX(57896044618658097711785492504343953926634992332820282019728792003956564819967) +#define NPY_MIN_INT256 (-NPY_MAX_INT256 - NPY_LONGLONG_SUFFIX(1)) +#define NPY_MAX_UINT256 NPY_ULONGLONG_SUFFIX(115792089237316195423570985008687907853269984665640564039457584007913129639935) +#define NPY_MIN_DATETIME NPY_MIN_INT64 +#define NPY_MAX_DATETIME NPY_MAX_INT64 +#define NPY_MIN_TIMEDELTA NPY_MIN_INT64 +#define NPY_MAX_TIMEDELTA NPY_MAX_INT64 + + /* Need to find the number of bits for each type and + make definitions accordingly. + + C states that sizeof(char) == 1 by definition + + So, just using the sizeof keyword won't help. + + It also looks like Python itself uses sizeof(char) quite a + bit, which by definition should be 1 all the time. + + Idea: Make Use of CHAR_BIT which should tell us how many + BITS per CHARACTER + */ + + /* Include platform definitions -- These are in the C89/90 standard */ +#include +#define NPY_MAX_BYTE SCHAR_MAX +#define NPY_MIN_BYTE SCHAR_MIN +#define NPY_MAX_UBYTE UCHAR_MAX +#define NPY_MAX_SHORT SHRT_MAX +#define NPY_MIN_SHORT SHRT_MIN +#define NPY_MAX_USHORT USHRT_MAX +#define NPY_MAX_INT INT_MAX +#ifndef INT_MIN +#define INT_MIN (-INT_MAX - 1) +#endif +#define NPY_MIN_INT INT_MIN +#define NPY_MAX_UINT UINT_MAX +#define NPY_MAX_LONG LONG_MAX +#define NPY_MIN_LONG LONG_MIN +#define NPY_MAX_ULONG ULONG_MAX + +#define NPY_BITSOF_BOOL (sizeof(npy_bool) * CHAR_BIT) +#define NPY_BITSOF_CHAR CHAR_BIT +#define NPY_BITSOF_BYTE (NPY_SIZEOF_BYTE * CHAR_BIT) +#define NPY_BITSOF_SHORT (NPY_SIZEOF_SHORT * CHAR_BIT) +#define NPY_BITSOF_INT (NPY_SIZEOF_INT * CHAR_BIT) +#define NPY_BITSOF_LONG (NPY_SIZEOF_LONG * CHAR_BIT) +#define NPY_BITSOF_LONGLONG (NPY_SIZEOF_LONGLONG * CHAR_BIT) +#define NPY_BITSOF_INTP (NPY_SIZEOF_INTP * CHAR_BIT) +#define NPY_BITSOF_HALF (NPY_SIZEOF_HALF * CHAR_BIT) +#define NPY_BITSOF_FLOAT (NPY_SIZEOF_FLOAT * CHAR_BIT) +#define NPY_BITSOF_DOUBLE (NPY_SIZEOF_DOUBLE * CHAR_BIT) +#define NPY_BITSOF_LONGDOUBLE (NPY_SIZEOF_LONGDOUBLE * CHAR_BIT) +#define NPY_BITSOF_CFLOAT (NPY_SIZEOF_CFLOAT * CHAR_BIT) +#define NPY_BITSOF_CDOUBLE (NPY_SIZEOF_CDOUBLE * CHAR_BIT) +#define NPY_BITSOF_CLONGDOUBLE (NPY_SIZEOF_CLONGDOUBLE * CHAR_BIT) +#define NPY_BITSOF_DATETIME (NPY_SIZEOF_DATETIME * CHAR_BIT) +#define NPY_BITSOF_TIMEDELTA (NPY_SIZEOF_TIMEDELTA * CHAR_BIT) + +#if NPY_BITSOF_LONG == 8 +#define NPY_INT8 NPY_LONG +#define NPY_UINT8 NPY_ULONG + typedef long npy_int8; + typedef unsigned long npy_uint8; +#define PyInt8ScalarObject PyLongScalarObject +#define PyInt8ArrType_Type PyLongArrType_Type +#define PyUInt8ScalarObject PyULongScalarObject +#define PyUInt8ArrType_Type PyULongArrType_Type +#define NPY_INT8_FMT NPY_LONG_FMT +#define NPY_UINT8_FMT NPY_ULONG_FMT +#elif NPY_BITSOF_LONG == 16 +#define NPY_INT16 NPY_LONG +#define NPY_UINT16 NPY_ULONG + typedef long npy_int16; + typedef unsigned long npy_uint16; +#define PyInt16ScalarObject PyLongScalarObject +#define PyInt16ArrType_Type PyLongArrType_Type +#define PyUInt16ScalarObject PyULongScalarObject +#define PyUInt16ArrType_Type PyULongArrType_Type +#define NPY_INT16_FMT NPY_LONG_FMT +#define NPY_UINT16_FMT NPY_ULONG_FMT +#elif NPY_BITSOF_LONG == 32 +#define NPY_INT32 NPY_LONG +#define NPY_UINT32 NPY_ULONG + typedef long npy_int32; + typedef unsigned long npy_uint32; + typedef unsigned long npy_ucs4; +#define PyInt32ScalarObject PyLongScalarObject +#define PyInt32ArrType_Type PyLongArrType_Type +#define PyUInt32ScalarObject PyULongScalarObject +#define PyUInt32ArrType_Type PyULongArrType_Type +#define NPY_INT32_FMT NPY_LONG_FMT +#define NPY_UINT32_FMT NPY_ULONG_FMT +#elif NPY_BITSOF_LONG == 64 +#define NPY_INT64 NPY_LONG +#define NPY_UINT64 NPY_ULONG + typedef long npy_int64; + typedef unsigned long npy_uint64; +#define PyInt64ScalarObject PyLongScalarObject +#define PyInt64ArrType_Type PyLongArrType_Type +#define PyUInt64ScalarObject PyULongScalarObject +#define PyUInt64ArrType_Type PyULongArrType_Type +#define NPY_INT64_FMT NPY_LONG_FMT +#define NPY_UINT64_FMT NPY_ULONG_FMT +#define MyPyLong_FromInt64 PyLong_FromLong +#define MyPyLong_AsInt64 PyLong_AsLong +#elif NPY_BITSOF_LONG == 128 +#define NPY_INT128 NPY_LONG +#define NPY_UINT128 NPY_ULONG + typedef long npy_int128; + typedef unsigned long npy_uint128; +#define PyInt128ScalarObject PyLongScalarObject +#define PyInt128ArrType_Type PyLongArrType_Type +#define PyUInt128ScalarObject PyULongScalarObject +#define PyUInt128ArrType_Type PyULongArrType_Type +#define NPY_INT128_FMT NPY_LONG_FMT +#define NPY_UINT128_FMT NPY_ULONG_FMT +#endif + +#if NPY_BITSOF_LONGLONG == 8 +# ifndef NPY_INT8 +# define NPY_INT8 NPY_LONGLONG +# define NPY_UINT8 NPY_ULONGLONG + typedef npy_longlong npy_int8; + typedef npy_ulonglong npy_uint8; +# define PyInt8ScalarObject PyLongLongScalarObject +# define PyInt8ArrType_Type PyLongLongArrType_Type +# define PyUInt8ScalarObject PyULongLongScalarObject +# define PyUInt8ArrType_Type PyULongLongArrType_Type +#define NPY_INT8_FMT NPY_LONGLONG_FMT +#define NPY_UINT8_FMT NPY_ULONGLONG_FMT +# endif +# define NPY_MAX_LONGLONG NPY_MAX_INT8 +# define NPY_MIN_LONGLONG NPY_MIN_INT8 +# define NPY_MAX_ULONGLONG NPY_MAX_UINT8 +#elif NPY_BITSOF_LONGLONG == 16 +# ifndef NPY_INT16 +# define NPY_INT16 NPY_LONGLONG +# define NPY_UINT16 NPY_ULONGLONG + typedef npy_longlong npy_int16; + typedef npy_ulonglong npy_uint16; +# define PyInt16ScalarObject PyLongLongScalarObject +# define PyInt16ArrType_Type PyLongLongArrType_Type +# define PyUInt16ScalarObject PyULongLongScalarObject +# define PyUInt16ArrType_Type PyULongLongArrType_Type +#define NPY_INT16_FMT NPY_LONGLONG_FMT +#define NPY_UINT16_FMT NPY_ULONGLONG_FMT +# endif +# define NPY_MAX_LONGLONG NPY_MAX_INT16 +# define NPY_MIN_LONGLONG NPY_MIN_INT16 +# define NPY_MAX_ULONGLONG NPY_MAX_UINT16 +#elif NPY_BITSOF_LONGLONG == 32 +# ifndef NPY_INT32 +# define NPY_INT32 NPY_LONGLONG +# define NPY_UINT32 NPY_ULONGLONG + typedef npy_longlong npy_int32; + typedef npy_ulonglong npy_uint32; + typedef npy_ulonglong npy_ucs4; +# define PyInt32ScalarObject PyLongLongScalarObject +# define PyInt32ArrType_Type PyLongLongArrType_Type +# define PyUInt32ScalarObject PyULongLongScalarObject +# define PyUInt32ArrType_Type PyULongLongArrType_Type +#define NPY_INT32_FMT NPY_LONGLONG_FMT +#define NPY_UINT32_FMT NPY_ULONGLONG_FMT +# endif +# define NPY_MAX_LONGLONG NPY_MAX_INT32 +# define NPY_MIN_LONGLONG NPY_MIN_INT32 +# define NPY_MAX_ULONGLONG NPY_MAX_UINT32 +#elif NPY_BITSOF_LONGLONG == 64 +# ifndef NPY_INT64 +# define NPY_INT64 NPY_LONGLONG +# define NPY_UINT64 NPY_ULONGLONG + typedef npy_longlong npy_int64; + typedef npy_ulonglong npy_uint64; +# define PyInt64ScalarObject PyLongLongScalarObject +# define PyInt64ArrType_Type PyLongLongArrType_Type +# define PyUInt64ScalarObject PyULongLongScalarObject +# define PyUInt64ArrType_Type PyULongLongArrType_Type +#define NPY_INT64_FMT NPY_LONGLONG_FMT +#define NPY_UINT64_FMT NPY_ULONGLONG_FMT +# define MyPyLong_FromInt64 PyLong_FromLongLong +# define MyPyLong_AsInt64 PyLong_AsLongLong +# endif +# define NPY_MAX_LONGLONG NPY_MAX_INT64 +# define NPY_MIN_LONGLONG NPY_MIN_INT64 +# define NPY_MAX_ULONGLONG NPY_MAX_UINT64 +#elif NPY_BITSOF_LONGLONG == 128 +# ifndef NPY_INT128 +# define NPY_INT128 NPY_LONGLONG +# define NPY_UINT128 NPY_ULONGLONG + typedef npy_longlong npy_int128; + typedef npy_ulonglong npy_uint128; +# define PyInt128ScalarObject PyLongLongScalarObject +# define PyInt128ArrType_Type PyLongLongArrType_Type +# define PyUInt128ScalarObject PyULongLongScalarObject +# define PyUInt128ArrType_Type PyULongLongArrType_Type +#define NPY_INT128_FMT NPY_LONGLONG_FMT +#define NPY_UINT128_FMT NPY_ULONGLONG_FMT +# endif +# define NPY_MAX_LONGLONG NPY_MAX_INT128 +# define NPY_MIN_LONGLONG NPY_MIN_INT128 +# define NPY_MAX_ULONGLONG NPY_MAX_UINT128 +#elif NPY_BITSOF_LONGLONG == 256 +# define NPY_INT256 NPY_LONGLONG +# define NPY_UINT256 NPY_ULONGLONG + typedef npy_longlong npy_int256; + typedef npy_ulonglong npy_uint256; +# define PyInt256ScalarObject PyLongLongScalarObject +# define PyInt256ArrType_Type PyLongLongArrType_Type +# define PyUInt256ScalarObject PyULongLongScalarObject +# define PyUInt256ArrType_Type PyULongLongArrType_Type +#define NPY_INT256_FMT NPY_LONGLONG_FMT +#define NPY_UINT256_FMT NPY_ULONGLONG_FMT +# define NPY_MAX_LONGLONG NPY_MAX_INT256 +# define NPY_MIN_LONGLONG NPY_MIN_INT256 +# define NPY_MAX_ULONGLONG NPY_MAX_UINT256 +#endif + +#if NPY_BITSOF_INT == 8 +#ifndef NPY_INT8 +#define NPY_INT8 NPY_INT +#define NPY_UINT8 NPY_UINT + typedef int npy_int8; + typedef unsigned int npy_uint8; +# define PyInt8ScalarObject PyIntScalarObject +# define PyInt8ArrType_Type PyIntArrType_Type +# define PyUInt8ScalarObject PyUIntScalarObject +# define PyUInt8ArrType_Type PyUIntArrType_Type +#define NPY_INT8_FMT NPY_INT_FMT +#define NPY_UINT8_FMT NPY_UINT_FMT +#endif +#elif NPY_BITSOF_INT == 16 +#ifndef NPY_INT16 +#define NPY_INT16 NPY_INT +#define NPY_UINT16 NPY_UINT + typedef int npy_int16; + typedef unsigned int npy_uint16; +# define PyInt16ScalarObject PyIntScalarObject +# define PyInt16ArrType_Type PyIntArrType_Type +# define PyUInt16ScalarObject PyIntUScalarObject +# define PyUInt16ArrType_Type PyIntUArrType_Type +#define NPY_INT16_FMT NPY_INT_FMT +#define NPY_UINT16_FMT NPY_UINT_FMT +#endif +#elif NPY_BITSOF_INT == 32 +#ifndef NPY_INT32 +#define NPY_INT32 NPY_INT +#define NPY_UINT32 NPY_UINT + typedef int npy_int32; + typedef unsigned int npy_uint32; + typedef unsigned int npy_ucs4; +# define PyInt32ScalarObject PyIntScalarObject +# define PyInt32ArrType_Type PyIntArrType_Type +# define PyUInt32ScalarObject PyUIntScalarObject +# define PyUInt32ArrType_Type PyUIntArrType_Type +#define NPY_INT32_FMT NPY_INT_FMT +#define NPY_UINT32_FMT NPY_UINT_FMT +#endif +#elif NPY_BITSOF_INT == 64 +#ifndef NPY_INT64 +#define NPY_INT64 NPY_INT +#define NPY_UINT64 NPY_UINT + typedef int npy_int64; + typedef unsigned int npy_uint64; +# define PyInt64ScalarObject PyIntScalarObject +# define PyInt64ArrType_Type PyIntArrType_Type +# define PyUInt64ScalarObject PyUIntScalarObject +# define PyUInt64ArrType_Type PyUIntArrType_Type +#define NPY_INT64_FMT NPY_INT_FMT +#define NPY_UINT64_FMT NPY_UINT_FMT +# define MyPyLong_FromInt64 PyLong_FromLong +# define MyPyLong_AsInt64 PyLong_AsLong +#endif +#elif NPY_BITSOF_INT == 128 +#ifndef NPY_INT128 +#define NPY_INT128 NPY_INT +#define NPY_UINT128 NPY_UINT + typedef int npy_int128; + typedef unsigned int npy_uint128; +# define PyInt128ScalarObject PyIntScalarObject +# define PyInt128ArrType_Type PyIntArrType_Type +# define PyUInt128ScalarObject PyUIntScalarObject +# define PyUInt128ArrType_Type PyUIntArrType_Type +#define NPY_INT128_FMT NPY_INT_FMT +#define NPY_UINT128_FMT NPY_UINT_FMT +#endif +#endif + +#if NPY_BITSOF_SHORT == 8 +#ifndef NPY_INT8 +#define NPY_INT8 NPY_SHORT +#define NPY_UINT8 NPY_USHORT + typedef short npy_int8; + typedef unsigned short npy_uint8; +# define PyInt8ScalarObject PyShortScalarObject +# define PyInt8ArrType_Type PyShortArrType_Type +# define PyUInt8ScalarObject PyUShortScalarObject +# define PyUInt8ArrType_Type PyUShortArrType_Type +#define NPY_INT8_FMT NPY_SHORT_FMT +#define NPY_UINT8_FMT NPY_USHORT_FMT +#endif +#elif NPY_BITSOF_SHORT == 16 +#ifndef NPY_INT16 +#define NPY_INT16 NPY_SHORT +#define NPY_UINT16 NPY_USHORT + typedef short npy_int16; + typedef unsigned short npy_uint16; +# define PyInt16ScalarObject PyShortScalarObject +# define PyInt16ArrType_Type PyShortArrType_Type +# define PyUInt16ScalarObject PyUShortScalarObject +# define PyUInt16ArrType_Type PyUShortArrType_Type +#define NPY_INT16_FMT NPY_SHORT_FMT +#define NPY_UINT16_FMT NPY_USHORT_FMT +#endif +#elif NPY_BITSOF_SHORT == 32 +#ifndef NPY_INT32 +#define NPY_INT32 NPY_SHORT +#define NPY_UINT32 NPY_USHORT + typedef short npy_int32; + typedef unsigned short npy_uint32; + typedef unsigned short npy_ucs4; +# define PyInt32ScalarObject PyShortScalarObject +# define PyInt32ArrType_Type PyShortArrType_Type +# define PyUInt32ScalarObject PyUShortScalarObject +# define PyUInt32ArrType_Type PyUShortArrType_Type +#define NPY_INT32_FMT NPY_SHORT_FMT +#define NPY_UINT32_FMT NPY_USHORT_FMT +#endif +#elif NPY_BITSOF_SHORT == 64 +#ifndef NPY_INT64 +#define NPY_INT64 NPY_SHORT +#define NPY_UINT64 NPY_USHORT + typedef short npy_int64; + typedef unsigned short npy_uint64; +# define PyInt64ScalarObject PyShortScalarObject +# define PyInt64ArrType_Type PyShortArrType_Type +# define PyUInt64ScalarObject PyUShortScalarObject +# define PyUInt64ArrType_Type PyUShortArrType_Type +#define NPY_INT64_FMT NPY_SHORT_FMT +#define NPY_UINT64_FMT NPY_USHORT_FMT +# define MyPyLong_FromInt64 PyLong_FromLong +# define MyPyLong_AsInt64 PyLong_AsLong +#endif +#elif NPY_BITSOF_SHORT == 128 +#ifndef NPY_INT128 +#define NPY_INT128 NPY_SHORT +#define NPY_UINT128 NPY_USHORT + typedef short npy_int128; + typedef unsigned short npy_uint128; +# define PyInt128ScalarObject PyShortScalarObject +# define PyInt128ArrType_Type PyShortArrType_Type +# define PyUInt128ScalarObject PyUShortScalarObject +# define PyUInt128ArrType_Type PyUShortArrType_Type +#define NPY_INT128_FMT NPY_SHORT_FMT +#define NPY_UINT128_FMT NPY_USHORT_FMT +#endif +#endif + + +#if NPY_BITSOF_CHAR == 8 +#ifndef NPY_INT8 +#define NPY_INT8 NPY_BYTE +#define NPY_UINT8 NPY_UBYTE + typedef signed char npy_int8; + typedef unsigned char npy_uint8; +# define PyInt8ScalarObject PyByteScalarObject +# define PyInt8ArrType_Type PyByteArrType_Type +# define PyUInt8ScalarObject PyUByteScalarObject +# define PyUInt8ArrType_Type PyUByteArrType_Type +#define NPY_INT8_FMT NPY_BYTE_FMT +#define NPY_UINT8_FMT NPY_UBYTE_FMT +#endif +#elif NPY_BITSOF_CHAR == 16 +#ifndef NPY_INT16 +#define NPY_INT16 NPY_BYTE +#define NPY_UINT16 NPY_UBYTE + typedef signed char npy_int16; + typedef unsigned char npy_uint16; +# define PyInt16ScalarObject PyByteScalarObject +# define PyInt16ArrType_Type PyByteArrType_Type +# define PyUInt16ScalarObject PyUByteScalarObject +# define PyUInt16ArrType_Type PyUByteArrType_Type +#define NPY_INT16_FMT NPY_BYTE_FMT +#define NPY_UINT16_FMT NPY_UBYTE_FMT +#endif +#elif NPY_BITSOF_CHAR == 32 +#ifndef NPY_INT32 +#define NPY_INT32 NPY_BYTE +#define NPY_UINT32 NPY_UBYTE + typedef signed char npy_int32; + typedef unsigned char npy_uint32; + typedef unsigned char npy_ucs4; +# define PyInt32ScalarObject PyByteScalarObject +# define PyInt32ArrType_Type PyByteArrType_Type +# define PyUInt32ScalarObject PyUByteScalarObject +# define PyUInt32ArrType_Type PyUByteArrType_Type +#define NPY_INT32_FMT NPY_BYTE_FMT +#define NPY_UINT32_FMT NPY_UBYTE_FMT +#endif +#elif NPY_BITSOF_CHAR == 64 +#ifndef NPY_INT64 +#define NPY_INT64 NPY_BYTE +#define NPY_UINT64 NPY_UBYTE + typedef signed char npy_int64; + typedef unsigned char npy_uint64; +# define PyInt64ScalarObject PyByteScalarObject +# define PyInt64ArrType_Type PyByteArrType_Type +# define PyUInt64ScalarObject PyUByteScalarObject +# define PyUInt64ArrType_Type PyUByteArrType_Type +#define NPY_INT64_FMT NPY_BYTE_FMT +#define NPY_UINT64_FMT NPY_UBYTE_FMT +# define MyPyLong_FromInt64 PyLong_FromLong +# define MyPyLong_AsInt64 PyLong_AsLong +#endif +#elif NPY_BITSOF_CHAR == 128 +#ifndef NPY_INT128 +#define NPY_INT128 NPY_BYTE +#define NPY_UINT128 NPY_UBYTE + typedef signed char npy_int128; + typedef unsigned char npy_uint128; +# define PyInt128ScalarObject PyByteScalarObject +# define PyInt128ArrType_Type PyByteArrType_Type +# define PyUInt128ScalarObject PyUByteScalarObject +# define PyUInt128ArrType_Type PyUByteArrType_Type +#define NPY_INT128_FMT NPY_BYTE_FMT +#define NPY_UINT128_FMT NPY_UBYTE_FMT +#endif +#endif + + + +#if NPY_BITSOF_DOUBLE == 32 +#ifndef NPY_FLOAT32 +#define NPY_FLOAT32 NPY_DOUBLE +#define NPY_COMPLEX64 NPY_CDOUBLE + typedef double npy_float32; + typedef npy_cdouble npy_complex64; +# define PyFloat32ScalarObject PyDoubleScalarObject +# define PyComplex64ScalarObject PyCDoubleScalarObject +# define PyFloat32ArrType_Type PyDoubleArrType_Type +# define PyComplex64ArrType_Type PyCDoubleArrType_Type +#define NPY_FLOAT32_FMT NPY_DOUBLE_FMT +#define NPY_COMPLEX64_FMT NPY_CDOUBLE_FMT +#endif +#elif NPY_BITSOF_DOUBLE == 64 +#ifndef NPY_FLOAT64 +#define NPY_FLOAT64 NPY_DOUBLE +#define NPY_COMPLEX128 NPY_CDOUBLE + typedef double npy_float64; + typedef npy_cdouble npy_complex128; +# define PyFloat64ScalarObject PyDoubleScalarObject +# define PyComplex128ScalarObject PyCDoubleScalarObject +# define PyFloat64ArrType_Type PyDoubleArrType_Type +# define PyComplex128ArrType_Type PyCDoubleArrType_Type +#define NPY_FLOAT64_FMT NPY_DOUBLE_FMT +#define NPY_COMPLEX128_FMT NPY_CDOUBLE_FMT +#endif +#elif NPY_BITSOF_DOUBLE == 80 +#ifndef NPY_FLOAT80 +#define NPY_FLOAT80 NPY_DOUBLE +#define NPY_COMPLEX160 NPY_CDOUBLE + typedef double npy_float80; + typedef npy_cdouble npy_complex160; +# define PyFloat80ScalarObject PyDoubleScalarObject +# define PyComplex160ScalarObject PyCDoubleScalarObject +# define PyFloat80ArrType_Type PyDoubleArrType_Type +# define PyComplex160ArrType_Type PyCDoubleArrType_Type +#define NPY_FLOAT80_FMT NPY_DOUBLE_FMT +#define NPY_COMPLEX160_FMT NPY_CDOUBLE_FMT +#endif +#elif NPY_BITSOF_DOUBLE == 96 +#ifndef NPY_FLOAT96 +#define NPY_FLOAT96 NPY_DOUBLE +#define NPY_COMPLEX192 NPY_CDOUBLE + typedef double npy_float96; + typedef npy_cdouble npy_complex192; +# define PyFloat96ScalarObject PyDoubleScalarObject +# define PyComplex192ScalarObject PyCDoubleScalarObject +# define PyFloat96ArrType_Type PyDoubleArrType_Type +# define PyComplex192ArrType_Type PyCDoubleArrType_Type +#define NPY_FLOAT96_FMT NPY_DOUBLE_FMT +#define NPY_COMPLEX192_FMT NPY_CDOUBLE_FMT +#endif +#elif NPY_BITSOF_DOUBLE == 128 +#ifndef NPY_FLOAT128 +#define NPY_FLOAT128 NPY_DOUBLE +#define NPY_COMPLEX256 NPY_CDOUBLE + typedef double npy_float128; + typedef npy_cdouble npy_complex256; +# define PyFloat128ScalarObject PyDoubleScalarObject +# define PyComplex256ScalarObject PyCDoubleScalarObject +# define PyFloat128ArrType_Type PyDoubleArrType_Type +# define PyComplex256ArrType_Type PyCDoubleArrType_Type +#define NPY_FLOAT128_FMT NPY_DOUBLE_FMT +#define NPY_COMPLEX256_FMT NPY_CDOUBLE_FMT +#endif +#endif + + + +#if NPY_BITSOF_FLOAT == 32 +#ifndef NPY_FLOAT32 +#define NPY_FLOAT32 NPY_FLOAT +#define NPY_COMPLEX64 NPY_CFLOAT + typedef float npy_float32; + typedef npy_cfloat npy_complex64; +# define PyFloat32ScalarObject PyFloatScalarObject +# define PyComplex64ScalarObject PyCFloatScalarObject +# define PyFloat32ArrType_Type PyFloatArrType_Type +# define PyComplex64ArrType_Type PyCFloatArrType_Type +#define NPY_FLOAT32_FMT NPY_FLOAT_FMT +#define NPY_COMPLEX64_FMT NPY_CFLOAT_FMT +#endif +#elif NPY_BITSOF_FLOAT == 64 +#ifndef NPY_FLOAT64 +#define NPY_FLOAT64 NPY_FLOAT +#define NPY_COMPLEX128 NPY_CFLOAT + typedef float npy_float64; + typedef npy_cfloat npy_complex128; +# define PyFloat64ScalarObject PyFloatScalarObject +# define PyComplex128ScalarObject PyCFloatScalarObject +# define PyFloat64ArrType_Type PyFloatArrType_Type +# define PyComplex128ArrType_Type PyCFloatArrType_Type +#define NPY_FLOAT64_FMT NPY_FLOAT_FMT +#define NPY_COMPLEX128_FMT NPY_CFLOAT_FMT +#endif +#elif NPY_BITSOF_FLOAT == 80 +#ifndef NPY_FLOAT80 +#define NPY_FLOAT80 NPY_FLOAT +#define NPY_COMPLEX160 NPY_CFLOAT + typedef float npy_float80; + typedef npy_cfloat npy_complex160; +# define PyFloat80ScalarObject PyFloatScalarObject +# define PyComplex160ScalarObject PyCFloatScalarObject +# define PyFloat80ArrType_Type PyFloatArrType_Type +# define PyComplex160ArrType_Type PyCFloatArrType_Type +#define NPY_FLOAT80_FMT NPY_FLOAT_FMT +#define NPY_COMPLEX160_FMT NPY_CFLOAT_FMT +#endif +#elif NPY_BITSOF_FLOAT == 96 +#ifndef NPY_FLOAT96 +#define NPY_FLOAT96 NPY_FLOAT +#define NPY_COMPLEX192 NPY_CFLOAT + typedef float npy_float96; + typedef npy_cfloat npy_complex192; +# define PyFloat96ScalarObject PyFloatScalarObject +# define PyComplex192ScalarObject PyCFloatScalarObject +# define PyFloat96ArrType_Type PyFloatArrType_Type +# define PyComplex192ArrType_Type PyCFloatArrType_Type +#define NPY_FLOAT96_FMT NPY_FLOAT_FMT +#define NPY_COMPLEX192_FMT NPY_CFLOAT_FMT +#endif +#elif NPY_BITSOF_FLOAT == 128 +#ifndef NPY_FLOAT128 +#define NPY_FLOAT128 NPY_FLOAT +#define NPY_COMPLEX256 NPY_CFLOAT + typedef float npy_float128; + typedef npy_cfloat npy_complex256; +# define PyFloat128ScalarObject PyFloatScalarObject +# define PyComplex256ScalarObject PyCFloatScalarObject +# define PyFloat128ArrType_Type PyFloatArrType_Type +# define PyComplex256ArrType_Type PyCFloatArrType_Type +#define NPY_FLOAT128_FMT NPY_FLOAT_FMT +#define NPY_COMPLEX256_FMT NPY_CFLOAT_FMT +#endif +#endif + +/* half/float16 isn't a floating-point type in C */ +#define NPY_FLOAT16 NPY_HALF +typedef npy_uint16 npy_half; +typedef npy_half npy_float16; + +#if NPY_BITSOF_LONGDOUBLE == 32 +#ifndef NPY_FLOAT32 +#define NPY_FLOAT32 NPY_LONGDOUBLE +#define NPY_COMPLEX64 NPY_CLONGDOUBLE + typedef npy_longdouble npy_float32; + typedef npy_clongdouble npy_complex64; +# define PyFloat32ScalarObject PyLongDoubleScalarObject +# define PyComplex64ScalarObject PyCLongDoubleScalarObject +# define PyFloat32ArrType_Type PyLongDoubleArrType_Type +# define PyComplex64ArrType_Type PyCLongDoubleArrType_Type +#define NPY_FLOAT32_FMT NPY_LONGDOUBLE_FMT +#define NPY_COMPLEX64_FMT NPY_CLONGDOUBLE_FMT +#endif +#elif NPY_BITSOF_LONGDOUBLE == 64 +#ifndef NPY_FLOAT64 +#define NPY_FLOAT64 NPY_LONGDOUBLE +#define NPY_COMPLEX128 NPY_CLONGDOUBLE + typedef npy_longdouble npy_float64; + typedef npy_clongdouble npy_complex128; +# define PyFloat64ScalarObject PyLongDoubleScalarObject +# define PyComplex128ScalarObject PyCLongDoubleScalarObject +# define PyFloat64ArrType_Type PyLongDoubleArrType_Type +# define PyComplex128ArrType_Type PyCLongDoubleArrType_Type +#define NPY_FLOAT64_FMT NPY_LONGDOUBLE_FMT +#define NPY_COMPLEX128_FMT NPY_CLONGDOUBLE_FMT +#endif +#elif NPY_BITSOF_LONGDOUBLE == 80 +#ifndef NPY_FLOAT80 +#define NPY_FLOAT80 NPY_LONGDOUBLE +#define NPY_COMPLEX160 NPY_CLONGDOUBLE + typedef npy_longdouble npy_float80; + typedef npy_clongdouble npy_complex160; +# define PyFloat80ScalarObject PyLongDoubleScalarObject +# define PyComplex160ScalarObject PyCLongDoubleScalarObject +# define PyFloat80ArrType_Type PyLongDoubleArrType_Type +# define PyComplex160ArrType_Type PyCLongDoubleArrType_Type +#define NPY_FLOAT80_FMT NPY_LONGDOUBLE_FMT +#define NPY_COMPLEX160_FMT NPY_CLONGDOUBLE_FMT +#endif +#elif NPY_BITSOF_LONGDOUBLE == 96 +#ifndef NPY_FLOAT96 +#define NPY_FLOAT96 NPY_LONGDOUBLE +#define NPY_COMPLEX192 NPY_CLONGDOUBLE + typedef npy_longdouble npy_float96; + typedef npy_clongdouble npy_complex192; +# define PyFloat96ScalarObject PyLongDoubleScalarObject +# define PyComplex192ScalarObject PyCLongDoubleScalarObject +# define PyFloat96ArrType_Type PyLongDoubleArrType_Type +# define PyComplex192ArrType_Type PyCLongDoubleArrType_Type +#define NPY_FLOAT96_FMT NPY_LONGDOUBLE_FMT +#define NPY_COMPLEX192_FMT NPY_CLONGDOUBLE_FMT +#endif +#elif NPY_BITSOF_LONGDOUBLE == 128 +#ifndef NPY_FLOAT128 +#define NPY_FLOAT128 NPY_LONGDOUBLE +#define NPY_COMPLEX256 NPY_CLONGDOUBLE + typedef npy_longdouble npy_float128; + typedef npy_clongdouble npy_complex256; +# define PyFloat128ScalarObject PyLongDoubleScalarObject +# define PyComplex256ScalarObject PyCLongDoubleScalarObject +# define PyFloat128ArrType_Type PyLongDoubleArrType_Type +# define PyComplex256ArrType_Type PyCLongDoubleArrType_Type +#define NPY_FLOAT128_FMT NPY_LONGDOUBLE_FMT +#define NPY_COMPLEX256_FMT NPY_CLONGDOUBLE_FMT +#endif +#elif NPY_BITSOF_LONGDOUBLE == 256 +#define NPY_FLOAT256 NPY_LONGDOUBLE +#define NPY_COMPLEX512 NPY_CLONGDOUBLE + typedef npy_longdouble npy_float256; + typedef npy_clongdouble npy_complex512; +# define PyFloat256ScalarObject PyLongDoubleScalarObject +# define PyComplex512ScalarObject PyCLongDoubleScalarObject +# define PyFloat256ArrType_Type PyLongDoubleArrType_Type +# define PyComplex512ArrType_Type PyCLongDoubleArrType_Type +#define NPY_FLOAT256_FMT NPY_LONGDOUBLE_FMT +#define NPY_COMPLEX512_FMT NPY_CLONGDOUBLE_FMT +#endif + +/* datetime typedefs */ +typedef npy_int64 npy_timedelta; +typedef npy_int64 npy_datetime; +#define NPY_DATETIME_FMT NPY_INT64_FMT +#define NPY_TIMEDELTA_FMT NPY_INT64_FMT + +/* End of typedefs for numarray style bit-width names */ + +#endif diff --git a/venv/Lib/site-packages/numpy/core/include/numpy/npy_cpu.h b/venv/Lib/site-packages/numpy/core/include/numpy/npy_cpu.h new file mode 100644 index 0000000..4dbf9d8 --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/include/numpy/npy_cpu.h @@ -0,0 +1,119 @@ +/* + * This set (target) cpu specific macros: + * - Possible values: + * NPY_CPU_X86 + * NPY_CPU_AMD64 + * NPY_CPU_PPC + * NPY_CPU_PPC64 + * NPY_CPU_PPC64LE + * NPY_CPU_SPARC + * NPY_CPU_S390 + * NPY_CPU_IA64 + * NPY_CPU_HPPA + * NPY_CPU_ALPHA + * NPY_CPU_ARMEL + * NPY_CPU_ARMEB + * NPY_CPU_SH_LE + * NPY_CPU_SH_BE + * NPY_CPU_ARCEL + * NPY_CPU_ARCEB + * NPY_CPU_RISCV64 + * NPY_CPU_WASM + */ +#ifndef _NPY_CPUARCH_H_ +#define _NPY_CPUARCH_H_ + +#include "numpyconfig.h" + +#if defined( __i386__ ) || defined(i386) || defined(_M_IX86) + /* + * __i386__ is defined by gcc and Intel compiler on Linux, + * _M_IX86 by VS compiler, + * i386 by Sun compilers on opensolaris at least + */ + #define NPY_CPU_X86 +#elif defined(__x86_64__) || defined(__amd64__) || defined(__x86_64) || defined(_M_AMD64) + /* + * both __x86_64__ and __amd64__ are defined by gcc + * __x86_64 defined by sun compiler on opensolaris at least + * _M_AMD64 defined by MS compiler + */ + #define NPY_CPU_AMD64 +#elif defined(__powerpc64__) && defined(__LITTLE_ENDIAN__) + #define NPY_CPU_PPC64LE +#elif defined(__powerpc64__) && defined(__BIG_ENDIAN__) + #define NPY_CPU_PPC64 +#elif defined(__ppc__) || defined(__powerpc__) || defined(_ARCH_PPC) + /* + * __ppc__ is defined by gcc, I remember having seen __powerpc__ once, + * but can't find it ATM + * _ARCH_PPC is used by at least gcc on AIX + * As __powerpc__ and _ARCH_PPC are also defined by PPC64 check + * for those specifically first before defaulting to ppc + */ + #define NPY_CPU_PPC +#elif defined(__sparc__) || defined(__sparc) + /* __sparc__ is defined by gcc and Forte (e.g. Sun) compilers */ + #define NPY_CPU_SPARC +#elif defined(__s390__) + #define NPY_CPU_S390 +#elif defined(__ia64) + #define NPY_CPU_IA64 +#elif defined(__hppa) + #define NPY_CPU_HPPA +#elif defined(__alpha__) + #define NPY_CPU_ALPHA +#elif defined(__arm__) || defined(__aarch64__) + #if defined(__ARMEB__) || defined(__AARCH64EB__) + #if defined(__ARM_32BIT_STATE) + #define NPY_CPU_ARMEB_AARCH32 + #elif defined(__ARM_64BIT_STATE) + #define NPY_CPU_ARMEB_AARCH64 + #else + #define NPY_CPU_ARMEB + #endif + #elif defined(__ARMEL__) || defined(__AARCH64EL__) + #if defined(__ARM_32BIT_STATE) + #define NPY_CPU_ARMEL_AARCH32 + #elif defined(__ARM_64BIT_STATE) + #define NPY_CPU_ARMEL_AARCH64 + #else + #define NPY_CPU_ARMEL + #endif + #else + # error Unknown ARM CPU, please report this to numpy maintainers with \ + information about your platform (OS, CPU and compiler) + #endif +#elif defined(__sh__) && defined(__LITTLE_ENDIAN__) + #define NPY_CPU_SH_LE +#elif defined(__sh__) && defined(__BIG_ENDIAN__) + #define NPY_CPU_SH_BE +#elif defined(__MIPSEL__) + #define NPY_CPU_MIPSEL +#elif defined(__MIPSEB__) + #define NPY_CPU_MIPSEB +#elif defined(__or1k__) + #define NPY_CPU_OR1K +#elif defined(__mc68000__) + #define NPY_CPU_M68K +#elif defined(__arc__) && defined(__LITTLE_ENDIAN__) + #define NPY_CPU_ARCEL +#elif defined(__arc__) && defined(__BIG_ENDIAN__) + #define NPY_CPU_ARCEB +#elif defined(__riscv) && defined(__riscv_xlen) && __riscv_xlen == 64 + #define NPY_CPU_RISCV64 +#elif defined(__EMSCRIPTEN__) + /* __EMSCRIPTEN__ is defined by emscripten: an LLVM-to-Web compiler */ + #define NPY_CPU_WASM +#else + #error Unknown CPU, please report this to numpy maintainers with \ + information about your platform (OS, CPU and compiler) +#endif + +#if (defined(NPY_CPU_X86) || defined(NPY_CPU_AMD64)) +#define NPY_CPU_HAVE_UNALIGNED_ACCESS 1 +#else +#define NPY_CPU_HAVE_UNALIGNED_ACCESS 0 +#endif + +#endif diff --git a/venv/Lib/site-packages/numpy/core/include/numpy/npy_endian.h b/venv/Lib/site-packages/numpy/core/include/numpy/npy_endian.h new file mode 100644 index 0000000..aa367a0 --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/include/numpy/npy_endian.h @@ -0,0 +1,73 @@ +#ifndef _NPY_ENDIAN_H_ +#define _NPY_ENDIAN_H_ + +/* + * NPY_BYTE_ORDER is set to the same value as BYTE_ORDER set by glibc in + * endian.h + */ + +#if defined(NPY_HAVE_ENDIAN_H) || defined(NPY_HAVE_SYS_ENDIAN_H) + /* Use endian.h if available */ + + #if defined(NPY_HAVE_ENDIAN_H) + #include + #elif defined(NPY_HAVE_SYS_ENDIAN_H) + #include + #endif + + #if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && defined(LITTLE_ENDIAN) + #define NPY_BYTE_ORDER BYTE_ORDER + #define NPY_LITTLE_ENDIAN LITTLE_ENDIAN + #define NPY_BIG_ENDIAN BIG_ENDIAN + #elif defined(_BYTE_ORDER) && defined(_BIG_ENDIAN) && defined(_LITTLE_ENDIAN) + #define NPY_BYTE_ORDER _BYTE_ORDER + #define NPY_LITTLE_ENDIAN _LITTLE_ENDIAN + #define NPY_BIG_ENDIAN _BIG_ENDIAN + #elif defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && defined(__LITTLE_ENDIAN) + #define NPY_BYTE_ORDER __BYTE_ORDER + #define NPY_LITTLE_ENDIAN __LITTLE_ENDIAN + #define NPY_BIG_ENDIAN __BIG_ENDIAN + #endif +#endif + +#ifndef NPY_BYTE_ORDER + /* Set endianness info using target CPU */ + #include "npy_cpu.h" + + #define NPY_LITTLE_ENDIAN 1234 + #define NPY_BIG_ENDIAN 4321 + + #if defined(NPY_CPU_X86) \ + || defined(NPY_CPU_AMD64) \ + || defined(NPY_CPU_IA64) \ + || defined(NPY_CPU_ALPHA) \ + || defined(NPY_CPU_ARMEL) \ + || defined(NPY_CPU_ARMEL_AARCH32) \ + || defined(NPY_CPU_ARMEL_AARCH64) \ + || defined(NPY_CPU_SH_LE) \ + || defined(NPY_CPU_MIPSEL) \ + || defined(NPY_CPU_PPC64LE) \ + || defined(NPY_CPU_ARCEL) \ + || defined(NPY_CPU_RISCV64) \ + || defined(NPY_CPU_WASM) + #define NPY_BYTE_ORDER NPY_LITTLE_ENDIAN + #elif defined(NPY_CPU_PPC) \ + || defined(NPY_CPU_SPARC) \ + || defined(NPY_CPU_S390) \ + || defined(NPY_CPU_HPPA) \ + || defined(NPY_CPU_PPC64) \ + || defined(NPY_CPU_ARMEB) \ + || defined(NPY_CPU_ARMEB_AARCH32) \ + || defined(NPY_CPU_ARMEB_AARCH64) \ + || defined(NPY_CPU_SH_BE) \ + || defined(NPY_CPU_MIPSEB) \ + || defined(NPY_CPU_OR1K) \ + || defined(NPY_CPU_M68K) \ + || defined(NPY_CPU_ARCEB) + #define NPY_BYTE_ORDER NPY_BIG_ENDIAN + #else + #error Unknown CPU: can not set endianness + #endif +#endif + +#endif diff --git a/venv/Lib/site-packages/numpy/core/include/numpy/npy_interrupt.h b/venv/Lib/site-packages/numpy/core/include/numpy/npy_interrupt.h new file mode 100644 index 0000000..bcb5393 --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/include/numpy/npy_interrupt.h @@ -0,0 +1,56 @@ +/* + * This API is only provided because it is part of publicly exported + * headers. Its use is considered DEPRECATED, and it will be removed + * eventually. + * (This includes the _PyArray_SigintHandler and _PyArray_GetSigintBuf + * functions which are however, public API, and not headers.) + * + * Instead of using these non-threadsafe macros consider periodically + * querying `PyErr_CheckSignals()` or `PyOS_InterruptOccurred()` will work. + * Both of these require holding the GIL, although cpython could add a + * version of `PyOS_InterruptOccurred()` which does not. Such a version + * actually exists as private API in Python 3.10, and backported to 3.9 and 3.8, + * see also https://bugs.python.org/issue41037 and + * https://github.com/python/cpython/pull/20599). + */ + +#ifndef NPY_INTERRUPT_H +#define NPY_INTERRUPT_H + +#ifndef NPY_NO_SIGNAL + +#include +#include + +#ifndef sigsetjmp + +#define NPY_SIGSETJMP(arg1, arg2) setjmp(arg1) +#define NPY_SIGLONGJMP(arg1, arg2) longjmp(arg1, arg2) +#define NPY_SIGJMP_BUF jmp_buf + +#else + +#define NPY_SIGSETJMP(arg1, arg2) sigsetjmp(arg1, arg2) +#define NPY_SIGLONGJMP(arg1, arg2) siglongjmp(arg1, arg2) +#define NPY_SIGJMP_BUF sigjmp_buf + +#endif + +# define NPY_SIGINT_ON { \ + PyOS_sighandler_t _npy_sig_save; \ + _npy_sig_save = PyOS_setsig(SIGINT, _PyArray_SigintHandler); \ + if (NPY_SIGSETJMP(*((NPY_SIGJMP_BUF *)_PyArray_GetSigintBuf()), \ + 1) == 0) { \ + +# define NPY_SIGINT_OFF } \ + PyOS_setsig(SIGINT, _npy_sig_save); \ + } + +#else /* NPY_NO_SIGNAL */ + +#define NPY_SIGINT_ON +#define NPY_SIGINT_OFF + +#endif /* HAVE_SIGSETJMP */ + +#endif /* NPY_INTERRUPT_H */ diff --git a/venv/Lib/site-packages/numpy/core/include/numpy/npy_math.h b/venv/Lib/site-packages/numpy/core/include/numpy/npy_math.h new file mode 100644 index 0000000..dbade05 --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/include/numpy/npy_math.h @@ -0,0 +1,597 @@ +#ifndef __NPY_MATH_C99_H_ +#define __NPY_MATH_C99_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#include +#ifdef __SUNPRO_CC +#include +#endif + +/* By adding static inline specifiers to npy_math function definitions when + appropriate, compiler is given the opportunity to optimize */ +#if NPY_INLINE_MATH +#define NPY_INPLACE NPY_INLINE static +#else +#define NPY_INPLACE +#endif + + +/* + * NAN and INFINITY like macros (same behavior as glibc for NAN, same as C99 + * for INFINITY) + * + * XXX: I should test whether INFINITY and NAN are available on the platform + */ +NPY_INLINE static float __npy_inff(void) +{ + const union { npy_uint32 __i; float __f;} __bint = {0x7f800000UL}; + return __bint.__f; +} + +NPY_INLINE static float __npy_nanf(void) +{ + const union { npy_uint32 __i; float __f;} __bint = {0x7fc00000UL}; + return __bint.__f; +} + +NPY_INLINE static float __npy_pzerof(void) +{ + const union { npy_uint32 __i; float __f;} __bint = {0x00000000UL}; + return __bint.__f; +} + +NPY_INLINE static float __npy_nzerof(void) +{ + const union { npy_uint32 __i; float __f;} __bint = {0x80000000UL}; + return __bint.__f; +} + +#define NPY_INFINITYF __npy_inff() +#define NPY_NANF __npy_nanf() +#define NPY_PZEROF __npy_pzerof() +#define NPY_NZEROF __npy_nzerof() + +#define NPY_INFINITY ((npy_double)NPY_INFINITYF) +#define NPY_NAN ((npy_double)NPY_NANF) +#define NPY_PZERO ((npy_double)NPY_PZEROF) +#define NPY_NZERO ((npy_double)NPY_NZEROF) + +#define NPY_INFINITYL ((npy_longdouble)NPY_INFINITYF) +#define NPY_NANL ((npy_longdouble)NPY_NANF) +#define NPY_PZEROL ((npy_longdouble)NPY_PZEROF) +#define NPY_NZEROL ((npy_longdouble)NPY_NZEROF) + +/* + * Useful constants + */ +#define NPY_E 2.718281828459045235360287471352662498 /* e */ +#define NPY_LOG2E 1.442695040888963407359924681001892137 /* log_2 e */ +#define NPY_LOG10E 0.434294481903251827651128918916605082 /* log_10 e */ +#define NPY_LOGE2 0.693147180559945309417232121458176568 /* log_e 2 */ +#define NPY_LOGE10 2.302585092994045684017991454684364208 /* log_e 10 */ +#define NPY_PI 3.141592653589793238462643383279502884 /* pi */ +#define NPY_PI_2 1.570796326794896619231321691639751442 /* pi/2 */ +#define NPY_PI_4 0.785398163397448309615660845819875721 /* pi/4 */ +#define NPY_1_PI 0.318309886183790671537767526745028724 /* 1/pi */ +#define NPY_2_PI 0.636619772367581343075535053490057448 /* 2/pi */ +#define NPY_EULER 0.577215664901532860606512090082402431 /* Euler constant */ +#define NPY_SQRT2 1.414213562373095048801688724209698079 /* sqrt(2) */ +#define NPY_SQRT1_2 0.707106781186547524400844362104849039 /* 1/sqrt(2) */ + +#define NPY_Ef 2.718281828459045235360287471352662498F /* e */ +#define NPY_LOG2Ef 1.442695040888963407359924681001892137F /* log_2 e */ +#define NPY_LOG10Ef 0.434294481903251827651128918916605082F /* log_10 e */ +#define NPY_LOGE2f 0.693147180559945309417232121458176568F /* log_e 2 */ +#define NPY_LOGE10f 2.302585092994045684017991454684364208F /* log_e 10 */ +#define NPY_PIf 3.141592653589793238462643383279502884F /* pi */ +#define NPY_PI_2f 1.570796326794896619231321691639751442F /* pi/2 */ +#define NPY_PI_4f 0.785398163397448309615660845819875721F /* pi/4 */ +#define NPY_1_PIf 0.318309886183790671537767526745028724F /* 1/pi */ +#define NPY_2_PIf 0.636619772367581343075535053490057448F /* 2/pi */ +#define NPY_EULERf 0.577215664901532860606512090082402431F /* Euler constant */ +#define NPY_SQRT2f 1.414213562373095048801688724209698079F /* sqrt(2) */ +#define NPY_SQRT1_2f 0.707106781186547524400844362104849039F /* 1/sqrt(2) */ + +#define NPY_El 2.718281828459045235360287471352662498L /* e */ +#define NPY_LOG2El 1.442695040888963407359924681001892137L /* log_2 e */ +#define NPY_LOG10El 0.434294481903251827651128918916605082L /* log_10 e */ +#define NPY_LOGE2l 0.693147180559945309417232121458176568L /* log_e 2 */ +#define NPY_LOGE10l 2.302585092994045684017991454684364208L /* log_e 10 */ +#define NPY_PIl 3.141592653589793238462643383279502884L /* pi */ +#define NPY_PI_2l 1.570796326794896619231321691639751442L /* pi/2 */ +#define NPY_PI_4l 0.785398163397448309615660845819875721L /* pi/4 */ +#define NPY_1_PIl 0.318309886183790671537767526745028724L /* 1/pi */ +#define NPY_2_PIl 0.636619772367581343075535053490057448L /* 2/pi */ +#define NPY_EULERl 0.577215664901532860606512090082402431L /* Euler constant */ +#define NPY_SQRT2l 1.414213562373095048801688724209698079L /* sqrt(2) */ +#define NPY_SQRT1_2l 0.707106781186547524400844362104849039L /* 1/sqrt(2) */ + +/* + * Integer functions. + */ +NPY_INPLACE npy_uint npy_gcdu(npy_uint a, npy_uint b); +NPY_INPLACE npy_uint npy_lcmu(npy_uint a, npy_uint b); +NPY_INPLACE npy_ulong npy_gcdul(npy_ulong a, npy_ulong b); +NPY_INPLACE npy_ulong npy_lcmul(npy_ulong a, npy_ulong b); +NPY_INPLACE npy_ulonglong npy_gcdull(npy_ulonglong a, npy_ulonglong b); +NPY_INPLACE npy_ulonglong npy_lcmull(npy_ulonglong a, npy_ulonglong b); + +NPY_INPLACE npy_int npy_gcd(npy_int a, npy_int b); +NPY_INPLACE npy_int npy_lcm(npy_int a, npy_int b); +NPY_INPLACE npy_long npy_gcdl(npy_long a, npy_long b); +NPY_INPLACE npy_long npy_lcml(npy_long a, npy_long b); +NPY_INPLACE npy_longlong npy_gcdll(npy_longlong a, npy_longlong b); +NPY_INPLACE npy_longlong npy_lcmll(npy_longlong a, npy_longlong b); + +NPY_INPLACE npy_ubyte npy_rshiftuhh(npy_ubyte a, npy_ubyte b); +NPY_INPLACE npy_ubyte npy_lshiftuhh(npy_ubyte a, npy_ubyte b); +NPY_INPLACE npy_ushort npy_rshiftuh(npy_ushort a, npy_ushort b); +NPY_INPLACE npy_ushort npy_lshiftuh(npy_ushort a, npy_ushort b); +NPY_INPLACE npy_uint npy_rshiftu(npy_uint a, npy_uint b); +NPY_INPLACE npy_uint npy_lshiftu(npy_uint a, npy_uint b); +NPY_INPLACE npy_ulong npy_rshiftul(npy_ulong a, npy_ulong b); +NPY_INPLACE npy_ulong npy_lshiftul(npy_ulong a, npy_ulong b); +NPY_INPLACE npy_ulonglong npy_rshiftull(npy_ulonglong a, npy_ulonglong b); +NPY_INPLACE npy_ulonglong npy_lshiftull(npy_ulonglong a, npy_ulonglong b); + +NPY_INPLACE npy_byte npy_rshifthh(npy_byte a, npy_byte b); +NPY_INPLACE npy_byte npy_lshifthh(npy_byte a, npy_byte b); +NPY_INPLACE npy_short npy_rshifth(npy_short a, npy_short b); +NPY_INPLACE npy_short npy_lshifth(npy_short a, npy_short b); +NPY_INPLACE npy_int npy_rshift(npy_int a, npy_int b); +NPY_INPLACE npy_int npy_lshift(npy_int a, npy_int b); +NPY_INPLACE npy_long npy_rshiftl(npy_long a, npy_long b); +NPY_INPLACE npy_long npy_lshiftl(npy_long a, npy_long b); +NPY_INPLACE npy_longlong npy_rshiftll(npy_longlong a, npy_longlong b); +NPY_INPLACE npy_longlong npy_lshiftll(npy_longlong a, npy_longlong b); + +/* + * avx function has a common API for both sin & cos. This enum is used to + * distinguish between the two + */ +typedef enum { + npy_compute_sin, + npy_compute_cos +} NPY_TRIG_OP; + +/* + * C99 double math funcs + */ +NPY_INPLACE double npy_sin(double x); +NPY_INPLACE double npy_cos(double x); +NPY_INPLACE double npy_tan(double x); +NPY_INPLACE double npy_sinh(double x); +NPY_INPLACE double npy_cosh(double x); +NPY_INPLACE double npy_tanh(double x); + +NPY_INPLACE double npy_asin(double x); +NPY_INPLACE double npy_acos(double x); +NPY_INPLACE double npy_atan(double x); + +NPY_INPLACE double npy_log(double x); +NPY_INPLACE double npy_log10(double x); +NPY_INPLACE double npy_exp(double x); +NPY_INPLACE double npy_sqrt(double x); +NPY_INPLACE double npy_cbrt(double x); + +NPY_INPLACE double npy_fabs(double x); +NPY_INPLACE double npy_ceil(double x); +NPY_INPLACE double npy_fmod(double x, double y); +NPY_INPLACE double npy_floor(double x); + +NPY_INPLACE double npy_expm1(double x); +NPY_INPLACE double npy_log1p(double x); +NPY_INPLACE double npy_hypot(double x, double y); +NPY_INPLACE double npy_acosh(double x); +NPY_INPLACE double npy_asinh(double xx); +NPY_INPLACE double npy_atanh(double x); +NPY_INPLACE double npy_rint(double x); +NPY_INPLACE double npy_trunc(double x); +NPY_INPLACE double npy_exp2(double x); +NPY_INPLACE double npy_log2(double x); + +NPY_INPLACE double npy_atan2(double x, double y); +NPY_INPLACE double npy_pow(double x, double y); +NPY_INPLACE double npy_modf(double x, double* y); +NPY_INPLACE double npy_frexp(double x, int* y); +NPY_INPLACE double npy_ldexp(double n, int y); + +NPY_INPLACE double npy_copysign(double x, double y); +double npy_nextafter(double x, double y); +double npy_spacing(double x); + +/* + * IEEE 754 fpu handling. Those are guaranteed to be macros + */ + +/* use builtins to avoid function calls in tight loops + * only available if npy_config.h is available (= numpys own build) */ +#if HAVE___BUILTIN_ISNAN + #define npy_isnan(x) __builtin_isnan(x) +#else + #ifndef NPY_HAVE_DECL_ISNAN + #define npy_isnan(x) ((x) != (x)) + #else + #if defined(_MSC_VER) && (_MSC_VER < 1900) + #define npy_isnan(x) _isnan((x)) + #else + #define npy_isnan(x) isnan(x) + #endif + #endif +#endif + + +/* only available if npy_config.h is available (= numpys own build) */ +#if HAVE___BUILTIN_ISFINITE + #define npy_isfinite(x) __builtin_isfinite(x) +#else + #ifndef NPY_HAVE_DECL_ISFINITE + #ifdef _MSC_VER + #define npy_isfinite(x) _finite((x)) + #else + #define npy_isfinite(x) !npy_isnan((x) + (-x)) + #endif + #else + #define npy_isfinite(x) isfinite((x)) + #endif +#endif + +/* only available if npy_config.h is available (= numpys own build) */ +#if HAVE___BUILTIN_ISINF + #define npy_isinf(x) __builtin_isinf(x) +#else + #ifndef NPY_HAVE_DECL_ISINF + #define npy_isinf(x) (!npy_isfinite(x) && !npy_isnan(x)) + #else + #if defined(_MSC_VER) && (_MSC_VER < 1900) + #define npy_isinf(x) (!_finite((x)) && !_isnan((x))) + #else + #define npy_isinf(x) isinf((x)) + #endif + #endif +#endif + +#ifndef NPY_HAVE_DECL_SIGNBIT + int _npy_signbit_f(float x); + int _npy_signbit_d(double x); + int _npy_signbit_ld(long double x); + #define npy_signbit(x) \ + (sizeof (x) == sizeof (long double) ? _npy_signbit_ld (x) \ + : sizeof (x) == sizeof (double) ? _npy_signbit_d (x) \ + : _npy_signbit_f (x)) +#else + #define npy_signbit(x) signbit((x)) +#endif + +/* + * float C99 math functions + */ +NPY_INPLACE float npy_sinf(float x); +NPY_INPLACE float npy_cosf(float x); +NPY_INPLACE float npy_tanf(float x); +NPY_INPLACE float npy_sinhf(float x); +NPY_INPLACE float npy_coshf(float x); +NPY_INPLACE float npy_tanhf(float x); +NPY_INPLACE float npy_fabsf(float x); +NPY_INPLACE float npy_floorf(float x); +NPY_INPLACE float npy_ceilf(float x); +NPY_INPLACE float npy_rintf(float x); +NPY_INPLACE float npy_truncf(float x); +NPY_INPLACE float npy_sqrtf(float x); +NPY_INPLACE float npy_cbrtf(float x); +NPY_INPLACE float npy_log10f(float x); +NPY_INPLACE float npy_logf(float x); +NPY_INPLACE float npy_expf(float x); +NPY_INPLACE float npy_expm1f(float x); +NPY_INPLACE float npy_asinf(float x); +NPY_INPLACE float npy_acosf(float x); +NPY_INPLACE float npy_atanf(float x); +NPY_INPLACE float npy_asinhf(float x); +NPY_INPLACE float npy_acoshf(float x); +NPY_INPLACE float npy_atanhf(float x); +NPY_INPLACE float npy_log1pf(float x); +NPY_INPLACE float npy_exp2f(float x); +NPY_INPLACE float npy_log2f(float x); + +NPY_INPLACE float npy_atan2f(float x, float y); +NPY_INPLACE float npy_hypotf(float x, float y); +NPY_INPLACE float npy_powf(float x, float y); +NPY_INPLACE float npy_fmodf(float x, float y); + +NPY_INPLACE float npy_modff(float x, float* y); +NPY_INPLACE float npy_frexpf(float x, int* y); +NPY_INPLACE float npy_ldexpf(float x, int y); + +NPY_INPLACE float npy_copysignf(float x, float y); +float npy_nextafterf(float x, float y); +float npy_spacingf(float x); + +/* + * long double C99 math functions + */ +NPY_INPLACE npy_longdouble npy_sinl(npy_longdouble x); +NPY_INPLACE npy_longdouble npy_cosl(npy_longdouble x); +NPY_INPLACE npy_longdouble npy_tanl(npy_longdouble x); +NPY_INPLACE npy_longdouble npy_sinhl(npy_longdouble x); +NPY_INPLACE npy_longdouble npy_coshl(npy_longdouble x); +NPY_INPLACE npy_longdouble npy_tanhl(npy_longdouble x); +NPY_INPLACE npy_longdouble npy_fabsl(npy_longdouble x); +NPY_INPLACE npy_longdouble npy_floorl(npy_longdouble x); +NPY_INPLACE npy_longdouble npy_ceill(npy_longdouble x); +NPY_INPLACE npy_longdouble npy_rintl(npy_longdouble x); +NPY_INPLACE npy_longdouble npy_truncl(npy_longdouble x); +NPY_INPLACE npy_longdouble npy_sqrtl(npy_longdouble x); +NPY_INPLACE npy_longdouble npy_cbrtl(npy_longdouble x); +NPY_INPLACE npy_longdouble npy_log10l(npy_longdouble x); +NPY_INPLACE npy_longdouble npy_logl(npy_longdouble x); +NPY_INPLACE npy_longdouble npy_expl(npy_longdouble x); +NPY_INPLACE npy_longdouble npy_expm1l(npy_longdouble x); +NPY_INPLACE npy_longdouble npy_asinl(npy_longdouble x); +NPY_INPLACE npy_longdouble npy_acosl(npy_longdouble x); +NPY_INPLACE npy_longdouble npy_atanl(npy_longdouble x); +NPY_INPLACE npy_longdouble npy_asinhl(npy_longdouble x); +NPY_INPLACE npy_longdouble npy_acoshl(npy_longdouble x); +NPY_INPLACE npy_longdouble npy_atanhl(npy_longdouble x); +NPY_INPLACE npy_longdouble npy_log1pl(npy_longdouble x); +NPY_INPLACE npy_longdouble npy_exp2l(npy_longdouble x); +NPY_INPLACE npy_longdouble npy_log2l(npy_longdouble x); + +NPY_INPLACE npy_longdouble npy_atan2l(npy_longdouble x, npy_longdouble y); +NPY_INPLACE npy_longdouble npy_hypotl(npy_longdouble x, npy_longdouble y); +NPY_INPLACE npy_longdouble npy_powl(npy_longdouble x, npy_longdouble y); +NPY_INPLACE npy_longdouble npy_fmodl(npy_longdouble x, npy_longdouble y); + +NPY_INPLACE npy_longdouble npy_modfl(npy_longdouble x, npy_longdouble* y); +NPY_INPLACE npy_longdouble npy_frexpl(npy_longdouble x, int* y); +NPY_INPLACE npy_longdouble npy_ldexpl(npy_longdouble x, int y); + +NPY_INPLACE npy_longdouble npy_copysignl(npy_longdouble x, npy_longdouble y); +npy_longdouble npy_nextafterl(npy_longdouble x, npy_longdouble y); +npy_longdouble npy_spacingl(npy_longdouble x); + +/* + * Non standard functions + */ +NPY_INPLACE double npy_deg2rad(double x); +NPY_INPLACE double npy_rad2deg(double x); +NPY_INPLACE double npy_logaddexp(double x, double y); +NPY_INPLACE double npy_logaddexp2(double x, double y); +NPY_INPLACE double npy_divmod(double x, double y, double *modulus); +NPY_INPLACE double npy_heaviside(double x, double h0); + +NPY_INPLACE float npy_deg2radf(float x); +NPY_INPLACE float npy_rad2degf(float x); +NPY_INPLACE float npy_logaddexpf(float x, float y); +NPY_INPLACE float npy_logaddexp2f(float x, float y); +NPY_INPLACE float npy_divmodf(float x, float y, float *modulus); +NPY_INPLACE float npy_heavisidef(float x, float h0); + +NPY_INPLACE npy_longdouble npy_deg2radl(npy_longdouble x); +NPY_INPLACE npy_longdouble npy_rad2degl(npy_longdouble x); +NPY_INPLACE npy_longdouble npy_logaddexpl(npy_longdouble x, npy_longdouble y); +NPY_INPLACE npy_longdouble npy_logaddexp2l(npy_longdouble x, npy_longdouble y); +NPY_INPLACE npy_longdouble npy_divmodl(npy_longdouble x, npy_longdouble y, + npy_longdouble *modulus); +NPY_INPLACE npy_longdouble npy_heavisidel(npy_longdouble x, npy_longdouble h0); + +#define npy_degrees npy_rad2deg +#define npy_degreesf npy_rad2degf +#define npy_degreesl npy_rad2degl + +#define npy_radians npy_deg2rad +#define npy_radiansf npy_deg2radf +#define npy_radiansl npy_deg2radl + +/* + * Complex declarations + */ + +/* + * C99 specifies that complex numbers have the same representation as + * an array of two elements, where the first element is the real part + * and the second element is the imaginary part. + */ +#define __NPY_CPACK_IMP(x, y, type, ctype) \ + union { \ + ctype z; \ + type a[2]; \ + } z1;; \ + \ + z1.a[0] = (x); \ + z1.a[1] = (y); \ + \ + return z1.z; + +static NPY_INLINE npy_cdouble npy_cpack(double x, double y) +{ + __NPY_CPACK_IMP(x, y, double, npy_cdouble); +} + +static NPY_INLINE npy_cfloat npy_cpackf(float x, float y) +{ + __NPY_CPACK_IMP(x, y, float, npy_cfloat); +} + +static NPY_INLINE npy_clongdouble npy_cpackl(npy_longdouble x, npy_longdouble y) +{ + __NPY_CPACK_IMP(x, y, npy_longdouble, npy_clongdouble); +} +#undef __NPY_CPACK_IMP + +/* + * Same remark as above, but in the other direction: extract first/second + * member of complex number, assuming a C99-compatible representation + * + * Those are defineds as static inline, and such as a reasonable compiler would + * most likely compile this to one or two instructions (on CISC at least) + */ +#define __NPY_CEXTRACT_IMP(z, index, type, ctype) \ + union { \ + ctype z; \ + type a[2]; \ + } __z_repr; \ + __z_repr.z = z; \ + \ + return __z_repr.a[index]; + +static NPY_INLINE double npy_creal(npy_cdouble z) +{ + __NPY_CEXTRACT_IMP(z, 0, double, npy_cdouble); +} + +static NPY_INLINE double npy_cimag(npy_cdouble z) +{ + __NPY_CEXTRACT_IMP(z, 1, double, npy_cdouble); +} + +static NPY_INLINE float npy_crealf(npy_cfloat z) +{ + __NPY_CEXTRACT_IMP(z, 0, float, npy_cfloat); +} + +static NPY_INLINE float npy_cimagf(npy_cfloat z) +{ + __NPY_CEXTRACT_IMP(z, 1, float, npy_cfloat); +} + +static NPY_INLINE npy_longdouble npy_creall(npy_clongdouble z) +{ + __NPY_CEXTRACT_IMP(z, 0, npy_longdouble, npy_clongdouble); +} + +static NPY_INLINE npy_longdouble npy_cimagl(npy_clongdouble z) +{ + __NPY_CEXTRACT_IMP(z, 1, npy_longdouble, npy_clongdouble); +} +#undef __NPY_CEXTRACT_IMP + +/* + * Double precision complex functions + */ +double npy_cabs(npy_cdouble z); +double npy_carg(npy_cdouble z); + +npy_cdouble npy_cexp(npy_cdouble z); +npy_cdouble npy_clog(npy_cdouble z); +npy_cdouble npy_cpow(npy_cdouble x, npy_cdouble y); + +npy_cdouble npy_csqrt(npy_cdouble z); + +npy_cdouble npy_ccos(npy_cdouble z); +npy_cdouble npy_csin(npy_cdouble z); +npy_cdouble npy_ctan(npy_cdouble z); + +npy_cdouble npy_ccosh(npy_cdouble z); +npy_cdouble npy_csinh(npy_cdouble z); +npy_cdouble npy_ctanh(npy_cdouble z); + +npy_cdouble npy_cacos(npy_cdouble z); +npy_cdouble npy_casin(npy_cdouble z); +npy_cdouble npy_catan(npy_cdouble z); + +npy_cdouble npy_cacosh(npy_cdouble z); +npy_cdouble npy_casinh(npy_cdouble z); +npy_cdouble npy_catanh(npy_cdouble z); + +/* + * Single precision complex functions + */ +float npy_cabsf(npy_cfloat z); +float npy_cargf(npy_cfloat z); + +npy_cfloat npy_cexpf(npy_cfloat z); +npy_cfloat npy_clogf(npy_cfloat z); +npy_cfloat npy_cpowf(npy_cfloat x, npy_cfloat y); + +npy_cfloat npy_csqrtf(npy_cfloat z); + +npy_cfloat npy_ccosf(npy_cfloat z); +npy_cfloat npy_csinf(npy_cfloat z); +npy_cfloat npy_ctanf(npy_cfloat z); + +npy_cfloat npy_ccoshf(npy_cfloat z); +npy_cfloat npy_csinhf(npy_cfloat z); +npy_cfloat npy_ctanhf(npy_cfloat z); + +npy_cfloat npy_cacosf(npy_cfloat z); +npy_cfloat npy_casinf(npy_cfloat z); +npy_cfloat npy_catanf(npy_cfloat z); + +npy_cfloat npy_cacoshf(npy_cfloat z); +npy_cfloat npy_casinhf(npy_cfloat z); +npy_cfloat npy_catanhf(npy_cfloat z); + + +/* + * Extended precision complex functions + */ +npy_longdouble npy_cabsl(npy_clongdouble z); +npy_longdouble npy_cargl(npy_clongdouble z); + +npy_clongdouble npy_cexpl(npy_clongdouble z); +npy_clongdouble npy_clogl(npy_clongdouble z); +npy_clongdouble npy_cpowl(npy_clongdouble x, npy_clongdouble y); + +npy_clongdouble npy_csqrtl(npy_clongdouble z); + +npy_clongdouble npy_ccosl(npy_clongdouble z); +npy_clongdouble npy_csinl(npy_clongdouble z); +npy_clongdouble npy_ctanl(npy_clongdouble z); + +npy_clongdouble npy_ccoshl(npy_clongdouble z); +npy_clongdouble npy_csinhl(npy_clongdouble z); +npy_clongdouble npy_ctanhl(npy_clongdouble z); + +npy_clongdouble npy_cacosl(npy_clongdouble z); +npy_clongdouble npy_casinl(npy_clongdouble z); +npy_clongdouble npy_catanl(npy_clongdouble z); + +npy_clongdouble npy_cacoshl(npy_clongdouble z); +npy_clongdouble npy_casinhl(npy_clongdouble z); +npy_clongdouble npy_catanhl(npy_clongdouble z); + + +/* + * Functions that set the floating point error + * status word. + */ + +/* + * platform-dependent code translates floating point + * status to an integer sum of these values + */ +#define NPY_FPE_DIVIDEBYZERO 1 +#define NPY_FPE_OVERFLOW 2 +#define NPY_FPE_UNDERFLOW 4 +#define NPY_FPE_INVALID 8 + +int npy_clear_floatstatus_barrier(char*); +int npy_get_floatstatus_barrier(char*); +/* + * use caution with these - clang and gcc8.1 are known to reorder calls + * to this form of the function which can defeat the check. The _barrier + * form of the call is preferable, where the argument is + * (char*)&local_variable + */ +int npy_clear_floatstatus(void); +int npy_get_floatstatus(void); + +void npy_set_floatstatus_divbyzero(void); +void npy_set_floatstatus_overflow(void); +void npy_set_floatstatus_underflow(void); +void npy_set_floatstatus_invalid(void); + +#ifdef __cplusplus +} +#endif + +#if NPY_INLINE_MATH +#include "npy_math_internal.h" +#endif + +#endif diff --git a/venv/Lib/site-packages/numpy/core/include/numpy/npy_no_deprecated_api.h b/venv/Lib/site-packages/numpy/core/include/numpy/npy_no_deprecated_api.h new file mode 100644 index 0000000..6183dc2 --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/include/numpy/npy_no_deprecated_api.h @@ -0,0 +1,19 @@ +/* + * This include file is provided for inclusion in Cython *.pyd files where + * one would like to define the NPY_NO_DEPRECATED_API macro. It can be + * included by + * + * cdef extern from "npy_no_deprecated_api.h": pass + * + */ +#ifndef NPY_NO_DEPRECATED_API + +/* put this check here since there may be multiple includes in C extensions. */ +#if defined(NDARRAYTYPES_H) || defined(_NPY_DEPRECATED_API_H) || \ + defined(OLD_DEFINES_H) +#error "npy_no_deprecated_api.h" must be first among numpy includes. +#else +#define NPY_NO_DEPRECATED_API NPY_API_VERSION +#endif + +#endif diff --git a/venv/Lib/site-packages/numpy/core/include/numpy/npy_os.h b/venv/Lib/site-packages/numpy/core/include/numpy/npy_os.h new file mode 100644 index 0000000..9228c39 --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/include/numpy/npy_os.h @@ -0,0 +1,30 @@ +#ifndef _NPY_OS_H_ +#define _NPY_OS_H_ + +#if defined(linux) || defined(__linux) || defined(__linux__) + #define NPY_OS_LINUX +#elif defined(__FreeBSD__) || defined(__NetBSD__) || \ + defined(__OpenBSD__) || defined(__DragonFly__) + #define NPY_OS_BSD + #ifdef __FreeBSD__ + #define NPY_OS_FREEBSD + #elif defined(__NetBSD__) + #define NPY_OS_NETBSD + #elif defined(__OpenBSD__) + #define NPY_OS_OPENBSD + #elif defined(__DragonFly__) + #define NPY_OS_DRAGONFLY + #endif +#elif defined(sun) || defined(__sun) + #define NPY_OS_SOLARIS +#elif defined(__CYGWIN__) + #define NPY_OS_CYGWIN +#elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32) + #define NPY_OS_WIN32 +#elif defined(__APPLE__) + #define NPY_OS_DARWIN +#else + #define NPY_OS_UNKNOWN +#endif + +#endif diff --git a/venv/Lib/site-packages/numpy/core/include/numpy/numpyconfig.h b/venv/Lib/site-packages/numpy/core/include/numpy/numpyconfig.h new file mode 100644 index 0000000..e393031 --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/include/numpy/numpyconfig.h @@ -0,0 +1,46 @@ +#ifndef _NPY_NUMPYCONFIG_H_ +#define _NPY_NUMPYCONFIG_H_ + +#include "_numpyconfig.h" + +/* + * On Mac OS X, because there is only one configuration stage for all the archs + * in universal builds, any macro which depends on the arch needs to be + * hardcoded + */ +#ifdef __APPLE__ + #undef NPY_SIZEOF_LONG + #undef NPY_SIZEOF_PY_INTPTR_T + + #ifdef __LP64__ + #define NPY_SIZEOF_LONG 8 + #define NPY_SIZEOF_PY_INTPTR_T 8 + #else + #define NPY_SIZEOF_LONG 4 + #define NPY_SIZEOF_PY_INTPTR_T 4 + #endif +#endif + +/** + * To help with the NPY_NO_DEPRECATED_API macro, we include API version + * numbers for specific versions of NumPy. To exclude all API that was + * deprecated as of 1.7, add the following before #including any NumPy + * headers: + * #define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION + */ +#define NPY_1_7_API_VERSION 0x00000007 +#define NPY_1_8_API_VERSION 0x00000008 +#define NPY_1_9_API_VERSION 0x00000008 +#define NPY_1_10_API_VERSION 0x00000008 +#define NPY_1_11_API_VERSION 0x00000008 +#define NPY_1_12_API_VERSION 0x00000008 +#define NPY_1_13_API_VERSION 0x00000008 +#define NPY_1_14_API_VERSION 0x00000008 +#define NPY_1_15_API_VERSION 0x00000008 +#define NPY_1_16_API_VERSION 0x00000008 +#define NPY_1_17_API_VERSION 0x00000008 +#define NPY_1_18_API_VERSION 0x00000008 +#define NPY_1_19_API_VERSION 0x00000008 +#define NPY_1_20_API_VERSION 0x0000000e + +#endif diff --git a/venv/Lib/site-packages/numpy/core/include/numpy/old_defines.h b/venv/Lib/site-packages/numpy/core/include/numpy/old_defines.h new file mode 100644 index 0000000..abf8159 --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/include/numpy/old_defines.h @@ -0,0 +1,187 @@ +/* This header is deprecated as of NumPy 1.7 */ +#ifndef OLD_DEFINES_H +#define OLD_DEFINES_H + +#if defined(NPY_NO_DEPRECATED_API) && NPY_NO_DEPRECATED_API >= NPY_1_7_API_VERSION +#error The header "old_defines.h" is deprecated as of NumPy 1.7. +#endif + +#define NDARRAY_VERSION NPY_VERSION + +#define PyArray_MIN_BUFSIZE NPY_MIN_BUFSIZE +#define PyArray_MAX_BUFSIZE NPY_MAX_BUFSIZE +#define PyArray_BUFSIZE NPY_BUFSIZE + +#define PyArray_PRIORITY NPY_PRIORITY +#define PyArray_SUBTYPE_PRIORITY NPY_PRIORITY +#define PyArray_NUM_FLOATTYPE NPY_NUM_FLOATTYPE + +#define NPY_MAX PyArray_MAX +#define NPY_MIN PyArray_MIN + +#define PyArray_TYPES NPY_TYPES +#define PyArray_BOOL NPY_BOOL +#define PyArray_BYTE NPY_BYTE +#define PyArray_UBYTE NPY_UBYTE +#define PyArray_SHORT NPY_SHORT +#define PyArray_USHORT NPY_USHORT +#define PyArray_INT NPY_INT +#define PyArray_UINT NPY_UINT +#define PyArray_LONG NPY_LONG +#define PyArray_ULONG NPY_ULONG +#define PyArray_LONGLONG NPY_LONGLONG +#define PyArray_ULONGLONG NPY_ULONGLONG +#define PyArray_HALF NPY_HALF +#define PyArray_FLOAT NPY_FLOAT +#define PyArray_DOUBLE NPY_DOUBLE +#define PyArray_LONGDOUBLE NPY_LONGDOUBLE +#define PyArray_CFLOAT NPY_CFLOAT +#define PyArray_CDOUBLE NPY_CDOUBLE +#define PyArray_CLONGDOUBLE NPY_CLONGDOUBLE +#define PyArray_OBJECT NPY_OBJECT +#define PyArray_STRING NPY_STRING +#define PyArray_UNICODE NPY_UNICODE +#define PyArray_VOID NPY_VOID +#define PyArray_DATETIME NPY_DATETIME +#define PyArray_TIMEDELTA NPY_TIMEDELTA +#define PyArray_NTYPES NPY_NTYPES +#define PyArray_NOTYPE NPY_NOTYPE +#define PyArray_CHAR NPY_CHAR +#define PyArray_USERDEF NPY_USERDEF +#define PyArray_NUMUSERTYPES NPY_NUMUSERTYPES + +#define PyArray_INTP NPY_INTP +#define PyArray_UINTP NPY_UINTP + +#define PyArray_INT8 NPY_INT8 +#define PyArray_UINT8 NPY_UINT8 +#define PyArray_INT16 NPY_INT16 +#define PyArray_UINT16 NPY_UINT16 +#define PyArray_INT32 NPY_INT32 +#define PyArray_UINT32 NPY_UINT32 + +#ifdef NPY_INT64 +#define PyArray_INT64 NPY_INT64 +#define PyArray_UINT64 NPY_UINT64 +#endif + +#ifdef NPY_INT128 +#define PyArray_INT128 NPY_INT128 +#define PyArray_UINT128 NPY_UINT128 +#endif + +#ifdef NPY_FLOAT16 +#define PyArray_FLOAT16 NPY_FLOAT16 +#define PyArray_COMPLEX32 NPY_COMPLEX32 +#endif + +#ifdef NPY_FLOAT80 +#define PyArray_FLOAT80 NPY_FLOAT80 +#define PyArray_COMPLEX160 NPY_COMPLEX160 +#endif + +#ifdef NPY_FLOAT96 +#define PyArray_FLOAT96 NPY_FLOAT96 +#define PyArray_COMPLEX192 NPY_COMPLEX192 +#endif + +#ifdef NPY_FLOAT128 +#define PyArray_FLOAT128 NPY_FLOAT128 +#define PyArray_COMPLEX256 NPY_COMPLEX256 +#endif + +#define PyArray_FLOAT32 NPY_FLOAT32 +#define PyArray_COMPLEX64 NPY_COMPLEX64 +#define PyArray_FLOAT64 NPY_FLOAT64 +#define PyArray_COMPLEX128 NPY_COMPLEX128 + + +#define PyArray_TYPECHAR NPY_TYPECHAR +#define PyArray_BOOLLTR NPY_BOOLLTR +#define PyArray_BYTELTR NPY_BYTELTR +#define PyArray_UBYTELTR NPY_UBYTELTR +#define PyArray_SHORTLTR NPY_SHORTLTR +#define PyArray_USHORTLTR NPY_USHORTLTR +#define PyArray_INTLTR NPY_INTLTR +#define PyArray_UINTLTR NPY_UINTLTR +#define PyArray_LONGLTR NPY_LONGLTR +#define PyArray_ULONGLTR NPY_ULONGLTR +#define PyArray_LONGLONGLTR NPY_LONGLONGLTR +#define PyArray_ULONGLONGLTR NPY_ULONGLONGLTR +#define PyArray_HALFLTR NPY_HALFLTR +#define PyArray_FLOATLTR NPY_FLOATLTR +#define PyArray_DOUBLELTR NPY_DOUBLELTR +#define PyArray_LONGDOUBLELTR NPY_LONGDOUBLELTR +#define PyArray_CFLOATLTR NPY_CFLOATLTR +#define PyArray_CDOUBLELTR NPY_CDOUBLELTR +#define PyArray_CLONGDOUBLELTR NPY_CLONGDOUBLELTR +#define PyArray_OBJECTLTR NPY_OBJECTLTR +#define PyArray_STRINGLTR NPY_STRINGLTR +#define PyArray_STRINGLTR2 NPY_STRINGLTR2 +#define PyArray_UNICODELTR NPY_UNICODELTR +#define PyArray_VOIDLTR NPY_VOIDLTR +#define PyArray_DATETIMELTR NPY_DATETIMELTR +#define PyArray_TIMEDELTALTR NPY_TIMEDELTALTR +#define PyArray_CHARLTR NPY_CHARLTR +#define PyArray_INTPLTR NPY_INTPLTR +#define PyArray_UINTPLTR NPY_UINTPLTR +#define PyArray_GENBOOLLTR NPY_GENBOOLLTR +#define PyArray_SIGNEDLTR NPY_SIGNEDLTR +#define PyArray_UNSIGNEDLTR NPY_UNSIGNEDLTR +#define PyArray_FLOATINGLTR NPY_FLOATINGLTR +#define PyArray_COMPLEXLTR NPY_COMPLEXLTR + +#define PyArray_QUICKSORT NPY_QUICKSORT +#define PyArray_HEAPSORT NPY_HEAPSORT +#define PyArray_MERGESORT NPY_MERGESORT +#define PyArray_SORTKIND NPY_SORTKIND +#define PyArray_NSORTS NPY_NSORTS + +#define PyArray_NOSCALAR NPY_NOSCALAR +#define PyArray_BOOL_SCALAR NPY_BOOL_SCALAR +#define PyArray_INTPOS_SCALAR NPY_INTPOS_SCALAR +#define PyArray_INTNEG_SCALAR NPY_INTNEG_SCALAR +#define PyArray_FLOAT_SCALAR NPY_FLOAT_SCALAR +#define PyArray_COMPLEX_SCALAR NPY_COMPLEX_SCALAR +#define PyArray_OBJECT_SCALAR NPY_OBJECT_SCALAR +#define PyArray_SCALARKIND NPY_SCALARKIND +#define PyArray_NSCALARKINDS NPY_NSCALARKINDS + +#define PyArray_ANYORDER NPY_ANYORDER +#define PyArray_CORDER NPY_CORDER +#define PyArray_FORTRANORDER NPY_FORTRANORDER +#define PyArray_ORDER NPY_ORDER + +#define PyDescr_ISBOOL PyDataType_ISBOOL +#define PyDescr_ISUNSIGNED PyDataType_ISUNSIGNED +#define PyDescr_ISSIGNED PyDataType_ISSIGNED +#define PyDescr_ISINTEGER PyDataType_ISINTEGER +#define PyDescr_ISFLOAT PyDataType_ISFLOAT +#define PyDescr_ISNUMBER PyDataType_ISNUMBER +#define PyDescr_ISSTRING PyDataType_ISSTRING +#define PyDescr_ISCOMPLEX PyDataType_ISCOMPLEX +#define PyDescr_ISPYTHON PyDataType_ISPYTHON +#define PyDescr_ISFLEXIBLE PyDataType_ISFLEXIBLE +#define PyDescr_ISUSERDEF PyDataType_ISUSERDEF +#define PyDescr_ISEXTENDED PyDataType_ISEXTENDED +#define PyDescr_ISOBJECT PyDataType_ISOBJECT +#define PyDescr_HASFIELDS PyDataType_HASFIELDS + +#define PyArray_LITTLE NPY_LITTLE +#define PyArray_BIG NPY_BIG +#define PyArray_NATIVE NPY_NATIVE +#define PyArray_SWAP NPY_SWAP +#define PyArray_IGNORE NPY_IGNORE + +#define PyArray_NATBYTE NPY_NATBYTE +#define PyArray_OPPBYTE NPY_OPPBYTE + +#define PyArray_MAX_ELSIZE NPY_MAX_ELSIZE + +#define PyArray_USE_PYMEM NPY_USE_PYMEM + +#define PyArray_RemoveLargest PyArray_RemoveSmallest + +#define PyArray_UCS4 npy_ucs4 + +#endif diff --git a/venv/Lib/site-packages/numpy/core/include/numpy/oldnumeric.h b/venv/Lib/site-packages/numpy/core/include/numpy/oldnumeric.h new file mode 100644 index 0000000..38530fa --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/include/numpy/oldnumeric.h @@ -0,0 +1,25 @@ +#include "arrayobject.h" + +#ifndef PYPY_VERSION +#ifndef REFCOUNT +# define REFCOUNT NPY_REFCOUNT +# define MAX_ELSIZE 16 +#endif +#endif + +#define PyArray_UNSIGNED_TYPES +#define PyArray_SBYTE NPY_BYTE +#define PyArray_CopyArray PyArray_CopyInto +#define _PyArray_multiply_list PyArray_MultiplyIntList +#define PyArray_ISSPACESAVER(m) NPY_FALSE +#define PyScalarArray_Check PyArray_CheckScalar + +#define CONTIGUOUS NPY_CONTIGUOUS +#define OWN_DIMENSIONS 0 +#define OWN_STRIDES 0 +#define OWN_DATA NPY_OWNDATA +#define SAVESPACE 0 +#define SAVESPACEBIT 0 + +#undef import_array +#define import_array() { if (_import_array() < 0) {PyErr_Print(); PyErr_SetString(PyExc_ImportError, "numpy.core.multiarray failed to import"); } } diff --git a/venv/Lib/site-packages/numpy/core/include/numpy/random/bitgen.h b/venv/Lib/site-packages/numpy/core/include/numpy/random/bitgen.h new file mode 100644 index 0000000..83c2858 --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/include/numpy/random/bitgen.h @@ -0,0 +1,20 @@ +#ifndef _RANDOM_BITGEN_H +#define _RANDOM_BITGEN_H + +#pragma once +#include +#include +#include + +/* Must match the declaration in numpy/random/.pxd */ + +typedef struct bitgen { + void *state; + uint64_t (*next_uint64)(void *st); + uint32_t (*next_uint32)(void *st); + double (*next_double)(void *st); + uint64_t (*next_raw)(void *st); +} bitgen_t; + + +#endif diff --git a/venv/Lib/site-packages/numpy/core/include/numpy/random/distributions.h b/venv/Lib/site-packages/numpy/core/include/numpy/random/distributions.h new file mode 100644 index 0000000..3ffacc8 --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/include/numpy/random/distributions.h @@ -0,0 +1,208 @@ +#ifndef _RANDOMDGEN__DISTRIBUTIONS_H_ +#define _RANDOMDGEN__DISTRIBUTIONS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "Python.h" +#include "numpy/npy_common.h" +#include +#include +#include + +#include "numpy/npy_math.h" +#include "numpy/random/bitgen.h" + +/* + * RAND_INT_TYPE is used to share integer generators with RandomState which + * used long in place of int64_t. If changing a distribution that uses + * RAND_INT_TYPE, then the original unmodified copy must be retained for + * use in RandomState by copying to the legacy distributions source file. + */ +#ifdef NP_RANDOM_LEGACY +#define RAND_INT_TYPE long +#define RAND_INT_MAX LONG_MAX +#else +#define RAND_INT_TYPE int64_t +#define RAND_INT_MAX INT64_MAX +#endif + +#ifdef _MSC_VER +#define DECLDIR __declspec(dllexport) +#else +#define DECLDIR extern +#endif + +#ifndef MIN +#define MIN(x, y) (((x) < (y)) ? x : y) +#define MAX(x, y) (((x) > (y)) ? x : y) +#endif + +#ifndef M_PI +#define M_PI 3.14159265358979323846264338328 +#endif + +typedef struct s_binomial_t { + int has_binomial; /* !=0: following parameters initialized for binomial */ + double psave; + RAND_INT_TYPE nsave; + double r; + double q; + double fm; + RAND_INT_TYPE m; + double p1; + double xm; + double xl; + double xr; + double c; + double laml; + double lamr; + double p2; + double p3; + double p4; +} binomial_t; + +DECLDIR float random_standard_uniform_f(bitgen_t *bitgen_state); +DECLDIR double random_standard_uniform(bitgen_t *bitgen_state); +DECLDIR void random_standard_uniform_fill(bitgen_t *, npy_intp, double *); +DECLDIR void random_standard_uniform_fill_f(bitgen_t *, npy_intp, float *); + +DECLDIR int64_t random_positive_int64(bitgen_t *bitgen_state); +DECLDIR int32_t random_positive_int32(bitgen_t *bitgen_state); +DECLDIR int64_t random_positive_int(bitgen_t *bitgen_state); +DECLDIR uint64_t random_uint(bitgen_t *bitgen_state); + +DECLDIR double random_standard_exponential(bitgen_t *bitgen_state); +DECLDIR float random_standard_exponential_f(bitgen_t *bitgen_state); +DECLDIR void random_standard_exponential_fill(bitgen_t *, npy_intp, double *); +DECLDIR void random_standard_exponential_fill_f(bitgen_t *, npy_intp, float *); +DECLDIR void random_standard_exponential_inv_fill(bitgen_t *, npy_intp, double *); +DECLDIR void random_standard_exponential_inv_fill_f(bitgen_t *, npy_intp, float *); + +DECLDIR double random_standard_normal(bitgen_t *bitgen_state); +DECLDIR float random_standard_normal_f(bitgen_t *bitgen_state); +DECLDIR void random_standard_normal_fill(bitgen_t *, npy_intp, double *); +DECLDIR void random_standard_normal_fill_f(bitgen_t *, npy_intp, float *); +DECLDIR double random_standard_gamma(bitgen_t *bitgen_state, double shape); +DECLDIR float random_standard_gamma_f(bitgen_t *bitgen_state, float shape); + +DECLDIR double random_normal(bitgen_t *bitgen_state, double loc, double scale); + +DECLDIR double random_gamma(bitgen_t *bitgen_state, double shape, double scale); +DECLDIR float random_gamma_f(bitgen_t *bitgen_state, float shape, float scale); + +DECLDIR double random_exponential(bitgen_t *bitgen_state, double scale); +DECLDIR double random_uniform(bitgen_t *bitgen_state, double lower, double range); +DECLDIR double random_beta(bitgen_t *bitgen_state, double a, double b); +DECLDIR double random_chisquare(bitgen_t *bitgen_state, double df); +DECLDIR double random_f(bitgen_t *bitgen_state, double dfnum, double dfden); +DECLDIR double random_standard_cauchy(bitgen_t *bitgen_state); +DECLDIR double random_pareto(bitgen_t *bitgen_state, double a); +DECLDIR double random_weibull(bitgen_t *bitgen_state, double a); +DECLDIR double random_power(bitgen_t *bitgen_state, double a); +DECLDIR double random_laplace(bitgen_t *bitgen_state, double loc, double scale); +DECLDIR double random_gumbel(bitgen_t *bitgen_state, double loc, double scale); +DECLDIR double random_logistic(bitgen_t *bitgen_state, double loc, double scale); +DECLDIR double random_lognormal(bitgen_t *bitgen_state, double mean, double sigma); +DECLDIR double random_rayleigh(bitgen_t *bitgen_state, double mode); +DECLDIR double random_standard_t(bitgen_t *bitgen_state, double df); +DECLDIR double random_noncentral_chisquare(bitgen_t *bitgen_state, double df, + double nonc); +DECLDIR double random_noncentral_f(bitgen_t *bitgen_state, double dfnum, + double dfden, double nonc); +DECLDIR double random_wald(bitgen_t *bitgen_state, double mean, double scale); +DECLDIR double random_vonmises(bitgen_t *bitgen_state, double mu, double kappa); +DECLDIR double random_triangular(bitgen_t *bitgen_state, double left, double mode, + double right); + +DECLDIR RAND_INT_TYPE random_poisson(bitgen_t *bitgen_state, double lam); +DECLDIR RAND_INT_TYPE random_negative_binomial(bitgen_t *bitgen_state, double n, + double p); + +DECLDIR int64_t random_binomial(bitgen_t *bitgen_state, double p, + int64_t n, binomial_t *binomial); + +DECLDIR RAND_INT_TYPE random_logseries(bitgen_t *bitgen_state, double p); +DECLDIR RAND_INT_TYPE random_geometric(bitgen_t *bitgen_state, double p); +DECLDIR RAND_INT_TYPE random_zipf(bitgen_t *bitgen_state, double a); +DECLDIR int64_t random_hypergeometric(bitgen_t *bitgen_state, + int64_t good, int64_t bad, int64_t sample); +DECLDIR uint64_t random_interval(bitgen_t *bitgen_state, uint64_t max); + +/* Generate random uint64 numbers in closed interval [off, off + rng]. */ +DECLDIR uint64_t random_bounded_uint64(bitgen_t *bitgen_state, uint64_t off, + uint64_t rng, uint64_t mask, + bool use_masked); + +/* Generate random uint32 numbers in closed interval [off, off + rng]. */ +DECLDIR uint32_t random_buffered_bounded_uint32(bitgen_t *bitgen_state, + uint32_t off, uint32_t rng, + uint32_t mask, bool use_masked, + int *bcnt, uint32_t *buf); +DECLDIR uint16_t random_buffered_bounded_uint16(bitgen_t *bitgen_state, + uint16_t off, uint16_t rng, + uint16_t mask, bool use_masked, + int *bcnt, uint32_t *buf); +DECLDIR uint8_t random_buffered_bounded_uint8(bitgen_t *bitgen_state, uint8_t off, + uint8_t rng, uint8_t mask, + bool use_masked, int *bcnt, + uint32_t *buf); +DECLDIR npy_bool random_buffered_bounded_bool(bitgen_t *bitgen_state, npy_bool off, + npy_bool rng, npy_bool mask, + bool use_masked, int *bcnt, + uint32_t *buf); + +DECLDIR void random_bounded_uint64_fill(bitgen_t *bitgen_state, uint64_t off, + uint64_t rng, npy_intp cnt, + bool use_masked, uint64_t *out); +DECLDIR void random_bounded_uint32_fill(bitgen_t *bitgen_state, uint32_t off, + uint32_t rng, npy_intp cnt, + bool use_masked, uint32_t *out); +DECLDIR void random_bounded_uint16_fill(bitgen_t *bitgen_state, uint16_t off, + uint16_t rng, npy_intp cnt, + bool use_masked, uint16_t *out); +DECLDIR void random_bounded_uint8_fill(bitgen_t *bitgen_state, uint8_t off, + uint8_t rng, npy_intp cnt, + bool use_masked, uint8_t *out); +DECLDIR void random_bounded_bool_fill(bitgen_t *bitgen_state, npy_bool off, + npy_bool rng, npy_intp cnt, + bool use_masked, npy_bool *out); + +DECLDIR void random_multinomial(bitgen_t *bitgen_state, RAND_INT_TYPE n, RAND_INT_TYPE *mnix, + double *pix, npy_intp d, binomial_t *binomial); + +/* multivariate hypergeometric, "count" method */ +DECLDIR int random_multivariate_hypergeometric_count(bitgen_t *bitgen_state, + int64_t total, + size_t num_colors, int64_t *colors, + int64_t nsample, + size_t num_variates, int64_t *variates); + +/* multivariate hypergeometric, "marginals" method */ +DECLDIR void random_multivariate_hypergeometric_marginals(bitgen_t *bitgen_state, + int64_t total, + size_t num_colors, int64_t *colors, + int64_t nsample, + size_t num_variates, int64_t *variates); + +/* Common to legacy-distributions.c and distributions.c but not exported */ + +RAND_INT_TYPE random_binomial_btpe(bitgen_t *bitgen_state, + RAND_INT_TYPE n, + double p, + binomial_t *binomial); +RAND_INT_TYPE random_binomial_inversion(bitgen_t *bitgen_state, + RAND_INT_TYPE n, + double p, + binomial_t *binomial); +double random_loggam(double x); +static NPY_INLINE double next_double(bitgen_t *bitgen_state) { + return bitgen_state->next_double(bitgen_state->state); +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/venv/Lib/site-packages/numpy/core/include/numpy/ufunc_api.txt b/venv/Lib/site-packages/numpy/core/include/numpy/ufunc_api.txt new file mode 100644 index 0000000..386848c --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/include/numpy/ufunc_api.txt @@ -0,0 +1,333 @@ + +================= +NumPy Ufunc C-API +================= +:: + + PyObject * + PyUFunc_FromFuncAndData(PyUFuncGenericFunction *func, void + **data, char *types, int ntypes, int nin, int + nout, int identity, const char *name, const + char *doc, int unused) + + +:: + + int + PyUFunc_RegisterLoopForType(PyUFuncObject *ufunc, int + usertype, PyUFuncGenericFunction + function, const int *arg_types, void + *data) + + +:: + + int + PyUFunc_GenericFunction(PyUFuncObject *ufunc, PyObject *args, PyObject + *kwds, PyArrayObject **op) + + +:: + + void + PyUFunc_f_f_As_d_d(char **args, npy_intp const *dimensions, npy_intp + const *steps, void *func) + + +:: + + void + PyUFunc_d_d(char **args, npy_intp const *dimensions, npy_intp const + *steps, void *func) + + +:: + + void + PyUFunc_f_f(char **args, npy_intp const *dimensions, npy_intp const + *steps, void *func) + + +:: + + void + PyUFunc_g_g(char **args, npy_intp const *dimensions, npy_intp const + *steps, void *func) + + +:: + + void + PyUFunc_F_F_As_D_D(char **args, npy_intp const *dimensions, npy_intp + const *steps, void *func) + + +:: + + void + PyUFunc_F_F(char **args, npy_intp const *dimensions, npy_intp const + *steps, void *func) + + +:: + + void + PyUFunc_D_D(char **args, npy_intp const *dimensions, npy_intp const + *steps, void *func) + + +:: + + void + PyUFunc_G_G(char **args, npy_intp const *dimensions, npy_intp const + *steps, void *func) + + +:: + + void + PyUFunc_O_O(char **args, npy_intp const *dimensions, npy_intp const + *steps, void *func) + + +:: + + void + PyUFunc_ff_f_As_dd_d(char **args, npy_intp const *dimensions, npy_intp + const *steps, void *func) + + +:: + + void + PyUFunc_ff_f(char **args, npy_intp const *dimensions, npy_intp const + *steps, void *func) + + +:: + + void + PyUFunc_dd_d(char **args, npy_intp const *dimensions, npy_intp const + *steps, void *func) + + +:: + + void + PyUFunc_gg_g(char **args, npy_intp const *dimensions, npy_intp const + *steps, void *func) + + +:: + + void + PyUFunc_FF_F_As_DD_D(char **args, npy_intp const *dimensions, npy_intp + const *steps, void *func) + + +:: + + void + PyUFunc_DD_D(char **args, npy_intp const *dimensions, npy_intp const + *steps, void *func) + + +:: + + void + PyUFunc_FF_F(char **args, npy_intp const *dimensions, npy_intp const + *steps, void *func) + + +:: + + void + PyUFunc_GG_G(char **args, npy_intp const *dimensions, npy_intp const + *steps, void *func) + + +:: + + void + PyUFunc_OO_O(char **args, npy_intp const *dimensions, npy_intp const + *steps, void *func) + + +:: + + void + PyUFunc_O_O_method(char **args, npy_intp const *dimensions, npy_intp + const *steps, void *func) + + +:: + + void + PyUFunc_OO_O_method(char **args, npy_intp const *dimensions, npy_intp + const *steps, void *func) + + +:: + + void + PyUFunc_On_Om(char **args, npy_intp const *dimensions, npy_intp const + *steps, void *func) + + +:: + + int + PyUFunc_GetPyValues(char *name, int *bufsize, int *errmask, PyObject + **errobj) + + +On return, if errobj is populated with a non-NULL value, the caller +owns a new reference to errobj. + +:: + + int + PyUFunc_checkfperr(int errmask, PyObject *errobj, int *first) + + +:: + + void + PyUFunc_clearfperr() + + +:: + + int + PyUFunc_getfperr(void ) + + +:: + + int + PyUFunc_handlefperr(int errmask, PyObject *errobj, int retstatus, int + *first) + + +:: + + int + PyUFunc_ReplaceLoopBySignature(PyUFuncObject + *func, PyUFuncGenericFunction + newfunc, const int + *signature, PyUFuncGenericFunction + *oldfunc) + + +:: + + PyObject * + PyUFunc_FromFuncAndDataAndSignature(PyUFuncGenericFunction *func, void + **data, char *types, int + ntypes, int nin, int nout, int + identity, const char *name, const + char *doc, int unused, const char + *signature) + + +:: + + int + PyUFunc_SetUsesArraysAsData(void **data, size_t i) + + +:: + + void + PyUFunc_e_e(char **args, npy_intp const *dimensions, npy_intp const + *steps, void *func) + + +:: + + void + PyUFunc_e_e_As_f_f(char **args, npy_intp const *dimensions, npy_intp + const *steps, void *func) + + +:: + + void + PyUFunc_e_e_As_d_d(char **args, npy_intp const *dimensions, npy_intp + const *steps, void *func) + + +:: + + void + PyUFunc_ee_e(char **args, npy_intp const *dimensions, npy_intp const + *steps, void *func) + + +:: + + void + PyUFunc_ee_e_As_ff_f(char **args, npy_intp const *dimensions, npy_intp + const *steps, void *func) + + +:: + + void + PyUFunc_ee_e_As_dd_d(char **args, npy_intp const *dimensions, npy_intp + const *steps, void *func) + + +:: + + int + PyUFunc_DefaultTypeResolver(PyUFuncObject *ufunc, NPY_CASTING + casting, PyArrayObject + **operands, PyObject + *type_tup, PyArray_Descr **out_dtypes) + + +This function applies the default type resolution rules +for the provided ufunc. + +Returns 0 on success, -1 on error. + +:: + + int + PyUFunc_ValidateCasting(PyUFuncObject *ufunc, NPY_CASTING + casting, PyArrayObject + **operands, PyArray_Descr **dtypes) + + +Validates that the input operands can be cast to +the input types, and the output types can be cast to +the output operands where provided. + +Returns 0 on success, -1 (with exception raised) on validation failure. + +:: + + int + PyUFunc_RegisterLoopForDescr(PyUFuncObject *ufunc, PyArray_Descr + *user_dtype, PyUFuncGenericFunction + function, PyArray_Descr + **arg_dtypes, void *data) + + +:: + + PyObject * + PyUFunc_FromFuncAndDataAndSignatureAndIdentity(PyUFuncGenericFunction + *func, void + **data, char + *types, int ntypes, int + nin, int nout, int + identity, const char + *name, const char + *doc, const int + unused, const char + *signature, PyObject + *identity_value) + + diff --git a/venv/Lib/site-packages/numpy/core/include/numpy/ufuncobject.h b/venv/Lib/site-packages/numpy/core/include/numpy/ufuncobject.h new file mode 100644 index 0000000..e5d8458 --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/include/numpy/ufuncobject.h @@ -0,0 +1,369 @@ +#ifndef Py_UFUNCOBJECT_H +#define Py_UFUNCOBJECT_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * The legacy generic inner loop for a standard element-wise or + * generalized ufunc. + */ +typedef void (*PyUFuncGenericFunction) + (char **args, + npy_intp const *dimensions, + npy_intp const *strides, + void *innerloopdata); + +/* + * The most generic one-dimensional inner loop for + * a masked standard element-wise ufunc. "Masked" here means that it skips + * doing calculations on any items for which the maskptr array has a true + * value. + */ +typedef void (PyUFunc_MaskedStridedInnerLoopFunc)( + char **dataptrs, npy_intp *strides, + char *maskptr, npy_intp mask_stride, + npy_intp count, + NpyAuxData *innerloopdata); + +/* Forward declaration for the type resolver and loop selector typedefs */ +struct _tagPyUFuncObject; + +/* + * Given the operands for calling a ufunc, should determine the + * calculation input and output data types and return an inner loop function. + * This function should validate that the casting rule is being followed, + * and fail if it is not. + * + * For backwards compatibility, the regular type resolution function does not + * support auxiliary data with object semantics. The type resolution call + * which returns a masked generic function returns a standard NpyAuxData + * object, for which the NPY_AUXDATA_FREE and NPY_AUXDATA_CLONE macros + * work. + * + * ufunc: The ufunc object. + * casting: The 'casting' parameter provided to the ufunc. + * operands: An array of length (ufunc->nin + ufunc->nout), + * with the output parameters possibly NULL. + * type_tup: Either NULL, or the type_tup passed to the ufunc. + * out_dtypes: An array which should be populated with new + * references to (ufunc->nin + ufunc->nout) new + * dtypes, one for each input and output. These + * dtypes should all be in native-endian format. + * + * Should return 0 on success, -1 on failure (with exception set), + * or -2 if Py_NotImplemented should be returned. + */ +typedef int (PyUFunc_TypeResolutionFunc)( + struct _tagPyUFuncObject *ufunc, + NPY_CASTING casting, + PyArrayObject **operands, + PyObject *type_tup, + PyArray_Descr **out_dtypes); + +/* + * Given an array of DTypes as returned by the PyUFunc_TypeResolutionFunc, + * and an array of fixed strides (the array will contain NPY_MAX_INTP for + * strides which are not necessarily fixed), returns an inner loop + * with associated auxiliary data. + * + * For backwards compatibility, there is a variant of the inner loop + * selection which returns an inner loop irrespective of the strides, + * and with a void* static auxiliary data instead of an NpyAuxData * + * dynamically allocatable auxiliary data. + * + * ufunc: The ufunc object. + * dtypes: An array which has been populated with dtypes, + * in most cases by the type resolution function + * for the same ufunc. + * fixed_strides: For each input/output, either the stride that + * will be used every time the function is called + * or NPY_MAX_INTP if the stride might change or + * is not known ahead of time. The loop selection + * function may use this stride to pick inner loops + * which are optimized for contiguous or 0-stride + * cases. + * out_innerloop: Should be populated with the correct ufunc inner + * loop for the given type. + * out_innerloopdata: Should be populated with the void* data to + * be passed into the out_innerloop function. + * out_needs_api: If the inner loop needs to use the Python API, + * should set the to 1, otherwise should leave + * this untouched. + */ +typedef int (PyUFunc_LegacyInnerLoopSelectionFunc)( + struct _tagPyUFuncObject *ufunc, + PyArray_Descr **dtypes, + PyUFuncGenericFunction *out_innerloop, + void **out_innerloopdata, + int *out_needs_api); +typedef int (PyUFunc_MaskedInnerLoopSelectionFunc)( + struct _tagPyUFuncObject *ufunc, + PyArray_Descr **dtypes, + PyArray_Descr *mask_dtype, + npy_intp *fixed_strides, + npy_intp fixed_mask_stride, + PyUFunc_MaskedStridedInnerLoopFunc **out_innerloop, + NpyAuxData **out_innerloopdata, + int *out_needs_api); + +typedef struct _tagPyUFuncObject { + PyObject_HEAD + /* + * nin: Number of inputs + * nout: Number of outputs + * nargs: Always nin + nout (Why is it stored?) + */ + int nin, nout, nargs; + + /* + * Identity for reduction, any of PyUFunc_One, PyUFunc_Zero + * PyUFunc_MinusOne, PyUFunc_None, PyUFunc_ReorderableNone, + * PyUFunc_IdentityValue. + */ + int identity; + + /* Array of one-dimensional core loops */ + PyUFuncGenericFunction *functions; + /* Array of funcdata that gets passed into the functions */ + void **data; + /* The number of elements in 'functions' and 'data' */ + int ntypes; + + /* Used to be unused field 'check_return' */ + int reserved1; + + /* The name of the ufunc */ + const char *name; + + /* Array of type numbers, of size ('nargs' * 'ntypes') */ + char *types; + + /* Documentation string */ + const char *doc; + + void *ptr; + PyObject *obj; + PyObject *userloops; + + /* generalized ufunc parameters */ + + /* 0 for scalar ufunc; 1 for generalized ufunc */ + int core_enabled; + /* number of distinct dimension names in signature */ + int core_num_dim_ix; + + /* + * dimension indices of input/output argument k are stored in + * core_dim_ixs[core_offsets[k]..core_offsets[k]+core_num_dims[k]-1] + */ + + /* numbers of core dimensions of each argument */ + int *core_num_dims; + /* + * dimension indices in a flatted form; indices + * are in the range of [0,core_num_dim_ix) + */ + int *core_dim_ixs; + /* + * positions of 1st core dimensions of each + * argument in core_dim_ixs, equivalent to cumsum(core_num_dims) + */ + int *core_offsets; + /* signature string for printing purpose */ + char *core_signature; + + /* + * A function which resolves the types and fills an array + * with the dtypes for the inputs and outputs. + */ + PyUFunc_TypeResolutionFunc *type_resolver; + /* + * A function which returns an inner loop written for + * NumPy 1.6 and earlier ufuncs. This is for backwards + * compatibility, and may be NULL if inner_loop_selector + * is specified. + */ + PyUFunc_LegacyInnerLoopSelectionFunc *legacy_inner_loop_selector; + /* + * This was blocked off to be the "new" inner loop selector in 1.7, + * but this was never implemented. (This is also why the above + * selector is called the "legacy" selector.) + */ + void *reserved2; + /* + * A function which returns a masked inner loop for the ufunc. + */ + PyUFunc_MaskedInnerLoopSelectionFunc *masked_inner_loop_selector; + + /* + * List of flags for each operand when ufunc is called by nditer object. + * These flags will be used in addition to the default flags for each + * operand set by nditer object. + */ + npy_uint32 *op_flags; + + /* + * List of global flags used when ufunc is called by nditer object. + * These flags will be used in addition to the default global flags + * set by nditer object. + */ + npy_uint32 iter_flags; + + /* New in NPY_API_VERSION 0x0000000D and above */ + + /* + * for each core_num_dim_ix distinct dimension names, + * the possible "frozen" size (-1 if not frozen). + */ + npy_intp *core_dim_sizes; + + /* + * for each distinct core dimension, a set of UFUNC_CORE_DIM* flags + */ + npy_uint32 *core_dim_flags; + + /* Identity for reduction, when identity == PyUFunc_IdentityValue */ + PyObject *identity_value; + +} PyUFuncObject; + +#include "arrayobject.h" +/* Generalized ufunc; 0x0001 reserved for possible use as CORE_ENABLED */ +/* the core dimension's size will be determined by the operands. */ +#define UFUNC_CORE_DIM_SIZE_INFERRED 0x0002 +/* the core dimension may be absent */ +#define UFUNC_CORE_DIM_CAN_IGNORE 0x0004 +/* flags inferred during execution */ +#define UFUNC_CORE_DIM_MISSING 0x00040000 + +#define UFUNC_ERR_IGNORE 0 +#define UFUNC_ERR_WARN 1 +#define UFUNC_ERR_RAISE 2 +#define UFUNC_ERR_CALL 3 +#define UFUNC_ERR_PRINT 4 +#define UFUNC_ERR_LOG 5 + + /* Python side integer mask */ + +#define UFUNC_MASK_DIVIDEBYZERO 0x07 +#define UFUNC_MASK_OVERFLOW 0x3f +#define UFUNC_MASK_UNDERFLOW 0x1ff +#define UFUNC_MASK_INVALID 0xfff + +#define UFUNC_SHIFT_DIVIDEBYZERO 0 +#define UFUNC_SHIFT_OVERFLOW 3 +#define UFUNC_SHIFT_UNDERFLOW 6 +#define UFUNC_SHIFT_INVALID 9 + + +#define UFUNC_OBJ_ISOBJECT 1 +#define UFUNC_OBJ_NEEDS_API 2 + + /* Default user error mode */ +#define UFUNC_ERR_DEFAULT \ + (UFUNC_ERR_WARN << UFUNC_SHIFT_DIVIDEBYZERO) + \ + (UFUNC_ERR_WARN << UFUNC_SHIFT_OVERFLOW) + \ + (UFUNC_ERR_WARN << UFUNC_SHIFT_INVALID) + +#if NPY_ALLOW_THREADS +#define NPY_LOOP_BEGIN_THREADS do {if (!(loop->obj & UFUNC_OBJ_NEEDS_API)) _save = PyEval_SaveThread();} while (0); +#define NPY_LOOP_END_THREADS do {if (!(loop->obj & UFUNC_OBJ_NEEDS_API)) PyEval_RestoreThread(_save);} while (0); +#else +#define NPY_LOOP_BEGIN_THREADS +#define NPY_LOOP_END_THREADS +#endif + +/* + * UFunc has unit of 0, and the order of operations can be reordered + * This case allows reduction with multiple axes at once. + */ +#define PyUFunc_Zero 0 +/* + * UFunc has unit of 1, and the order of operations can be reordered + * This case allows reduction with multiple axes at once. + */ +#define PyUFunc_One 1 +/* + * UFunc has unit of -1, and the order of operations can be reordered + * This case allows reduction with multiple axes at once. Intended for + * bitwise_and reduction. + */ +#define PyUFunc_MinusOne 2 +/* + * UFunc has no unit, and the order of operations cannot be reordered. + * This case does not allow reduction with multiple axes at once. + */ +#define PyUFunc_None -1 +/* + * UFunc has no unit, and the order of operations can be reordered + * This case allows reduction with multiple axes at once. + */ +#define PyUFunc_ReorderableNone -2 +/* + * UFunc unit is an identity_value, and the order of operations can be reordered + * This case allows reduction with multiple axes at once. + */ +#define PyUFunc_IdentityValue -3 + + +#define UFUNC_REDUCE 0 +#define UFUNC_ACCUMULATE 1 +#define UFUNC_REDUCEAT 2 +#define UFUNC_OUTER 3 + + +typedef struct { + int nin; + int nout; + PyObject *callable; +} PyUFunc_PyFuncData; + +/* A linked-list of function information for + user-defined 1-d loops. + */ +typedef struct _loop1d_info { + PyUFuncGenericFunction func; + void *data; + int *arg_types; + struct _loop1d_info *next; + int nargs; + PyArray_Descr **arg_dtypes; +} PyUFunc_Loop1d; + + +#include "__ufunc_api.h" + +#define UFUNC_PYVALS_NAME "UFUNC_PYVALS" + +/* + * THESE MACROS ARE DEPRECATED. + * Use npy_set_floatstatus_* in the npymath library. + */ +#define UFUNC_FPE_DIVIDEBYZERO NPY_FPE_DIVIDEBYZERO +#define UFUNC_FPE_OVERFLOW NPY_FPE_OVERFLOW +#define UFUNC_FPE_UNDERFLOW NPY_FPE_UNDERFLOW +#define UFUNC_FPE_INVALID NPY_FPE_INVALID + +#define generate_divbyzero_error() npy_set_floatstatus_divbyzero() +#define generate_overflow_error() npy_set_floatstatus_overflow() + + /* Make sure it gets defined if it isn't already */ +#ifndef UFUNC_NOFPE +/* Clear the floating point exception default of Borland C++ */ +#if defined(__BORLANDC__) +#define UFUNC_NOFPE _control87(MCW_EM, MCW_EM); +#else +#define UFUNC_NOFPE +#endif +#endif + + +#ifdef __cplusplus +} +#endif +#endif /* !Py_UFUNCOBJECT_H */ diff --git a/venv/Lib/site-packages/numpy/core/include/numpy/utils.h b/venv/Lib/site-packages/numpy/core/include/numpy/utils.h new file mode 100644 index 0000000..e251a52 --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/include/numpy/utils.h @@ -0,0 +1,37 @@ +#ifndef __NUMPY_UTILS_HEADER__ +#define __NUMPY_UTILS_HEADER__ + +#ifndef __COMP_NPY_UNUSED + #if defined(__GNUC__) + #define __COMP_NPY_UNUSED __attribute__ ((__unused__)) + #elif defined(__ICC) + #define __COMP_NPY_UNUSED __attribute__ ((__unused__)) + #elif defined(__clang__) + #define __COMP_NPY_UNUSED __attribute__ ((unused)) + #else + #define __COMP_NPY_UNUSED + #endif +#endif + +#if defined(__GNUC__) || defined(__ICC) || defined(__clang__) + #define NPY_DECL_ALIGNED(x) __attribute__ ((aligned (x))) +#elif defined(_MSC_VER) + #define NPY_DECL_ALIGNED(x) __declspec(align(x)) +#else + #define NPY_DECL_ALIGNED(x) +#endif + +/* Use this to tag a variable as not used. It will remove unused variable + * warning on support platforms (see __COM_NPY_UNUSED) and mangle the variable + * to avoid accidental use */ +#define NPY_UNUSED(x) (__NPY_UNUSED_TAGGED ## x) __COMP_NPY_UNUSED +#define NPY_EXPAND(x) x + +#define NPY_STRINGIFY(x) #x +#define NPY_TOSTRING(x) NPY_STRINGIFY(x) + +#define NPY_CAT__(a, b) a ## b +#define NPY_CAT_(a, b) NPY_CAT__(a, b) +#define NPY_CAT(a, b) NPY_CAT_(a, b) + +#endif diff --git a/venv/Lib/site-packages/numpy/core/lib/npy-pkg-config/mlib.ini b/venv/Lib/site-packages/numpy/core/lib/npy-pkg-config/mlib.ini new file mode 100644 index 0000000..1e70ccb --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/lib/npy-pkg-config/mlib.ini @@ -0,0 +1,12 @@ +[meta] +Name = mlib +Description = Math library used with this version of numpy +Version = 1.0 + +[default] +Libs= +Cflags= + +[msvc] +Libs= +Cflags= diff --git a/venv/Lib/site-packages/numpy/core/lib/npy-pkg-config/npymath.ini b/venv/Lib/site-packages/numpy/core/lib/npy-pkg-config/npymath.ini new file mode 100644 index 0000000..ec63fa8 --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/lib/npy-pkg-config/npymath.ini @@ -0,0 +1,20 @@ +[meta] +Name=npymath +Description=Portable, core math library implementing C99 standard +Version=0.1 + +[variables] +pkgname=numpy.core +prefix=${pkgdir} +libdir=${prefix}\lib +includedir=${prefix}\include + +[default] +Libs=-L${libdir} -lnpymath +Cflags=-I${includedir} +Requires=mlib + +[msvc] +Libs=/LIBPATH:${libdir} npymath.lib +Cflags=/INCLUDE:${includedir} +Requires=mlib diff --git a/venv/Lib/site-packages/numpy/core/lib/npymath.lib b/venv/Lib/site-packages/numpy/core/lib/npymath.lib new file mode 100644 index 0000000000000000000000000000000000000000..b6e32eb18969611e14405df033f004df43fa50b1 GIT binary patch literal 106590 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 literal 0 HcmV?d00001 diff --git a/venv/Lib/site-packages/numpy/core/machar.py b/venv/Lib/site-packages/numpy/core/machar.py new file mode 100644 index 0000000..55285fe --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/machar.py @@ -0,0 +1,342 @@ +""" +Machine arithmetics - determine the parameters of the +floating-point arithmetic system + +Author: Pearu Peterson, September 2003 + +""" +__all__ = ['MachAr'] + +from numpy.core.fromnumeric import any +from numpy.core._ufunc_config import errstate +from numpy.core.overrides import set_module + +# Need to speed this up...especially for longfloat + +@set_module('numpy') +class MachAr: + """ + Diagnosing machine parameters. + + Attributes + ---------- + ibeta : int + Radix in which numbers are represented. + it : int + Number of base-`ibeta` digits in the floating point mantissa M. + machep : int + Exponent of the smallest (most negative) power of `ibeta` that, + added to 1.0, gives something different from 1.0 + eps : float + Floating-point number ``beta**machep`` (floating point precision) + negep : int + Exponent of the smallest power of `ibeta` that, subtracted + from 1.0, gives something different from 1.0. + epsneg : float + Floating-point number ``beta**negep``. + iexp : int + Number of bits in the exponent (including its sign and bias). + minexp : int + Smallest (most negative) power of `ibeta` consistent with there + being no leading zeros in the mantissa. + xmin : float + Floating-point number ``beta**minexp`` (the smallest [in + magnitude] positive floating point number with full precision). + maxexp : int + Smallest (positive) power of `ibeta` that causes overflow. + xmax : float + ``(1-epsneg) * beta**maxexp`` (the largest [in magnitude] + usable floating value). + irnd : int + In ``range(6)``, information on what kind of rounding is done + in addition, and on how underflow is handled. + ngrd : int + Number of 'guard digits' used when truncating the product + of two mantissas to fit the representation. + epsilon : float + Same as `eps`. + tiny : float + Same as `xmin`. + huge : float + Same as `xmax`. + precision : float + ``- int(-log10(eps))`` + resolution : float + ``- 10**(-precision)`` + + Parameters + ---------- + float_conv : function, optional + Function that converts an integer or integer array to a float + or float array. Default is `float`. + int_conv : function, optional + Function that converts a float or float array to an integer or + integer array. Default is `int`. + float_to_float : function, optional + Function that converts a float array to float. Default is `float`. + Note that this does not seem to do anything useful in the current + implementation. + float_to_str : function, optional + Function that converts a single float to a string. Default is + ``lambda v:'%24.16e' %v``. + title : str, optional + Title that is printed in the string representation of `MachAr`. + + See Also + -------- + finfo : Machine limits for floating point types. + iinfo : Machine limits for integer types. + + References + ---------- + .. [1] Press, Teukolsky, Vetterling and Flannery, + "Numerical Recipes in C++," 2nd ed, + Cambridge University Press, 2002, p. 31. + + """ + + def __init__(self, float_conv=float,int_conv=int, + float_to_float=float, + float_to_str=lambda v:'%24.16e' % v, + title='Python floating point number'): + """ + + float_conv - convert integer to float (array) + int_conv - convert float (array) to integer + float_to_float - convert float array to float + float_to_str - convert array float to str + title - description of used floating point numbers + + """ + # We ignore all errors here because we are purposely triggering + # underflow to detect the properties of the runninng arch. + with errstate(under='ignore'): + self._do_init(float_conv, int_conv, float_to_float, float_to_str, title) + + def _do_init(self, float_conv, int_conv, float_to_float, float_to_str, title): + max_iterN = 10000 + msg = "Did not converge after %d tries with %s" + one = float_conv(1) + two = one + one + zero = one - one + + # Do we really need to do this? Aren't they 2 and 2.0? + # Determine ibeta and beta + a = one + for _ in range(max_iterN): + a = a + a + temp = a + one + temp1 = temp - a + if any(temp1 - one != zero): + break + else: + raise RuntimeError(msg % (_, one.dtype)) + b = one + for _ in range(max_iterN): + b = b + b + temp = a + b + itemp = int_conv(temp-a) + if any(itemp != 0): + break + else: + raise RuntimeError(msg % (_, one.dtype)) + ibeta = itemp + beta = float_conv(ibeta) + + # Determine it and irnd + it = -1 + b = one + for _ in range(max_iterN): + it = it + 1 + b = b * beta + temp = b + one + temp1 = temp - b + if any(temp1 - one != zero): + break + else: + raise RuntimeError(msg % (_, one.dtype)) + + betah = beta / two + a = one + for _ in range(max_iterN): + a = a + a + temp = a + one + temp1 = temp - a + if any(temp1 - one != zero): + break + else: + raise RuntimeError(msg % (_, one.dtype)) + temp = a + betah + irnd = 0 + if any(temp-a != zero): + irnd = 1 + tempa = a + beta + temp = tempa + betah + if irnd == 0 and any(temp-tempa != zero): + irnd = 2 + + # Determine negep and epsneg + negep = it + 3 + betain = one / beta + a = one + for i in range(negep): + a = a * betain + b = a + for _ in range(max_iterN): + temp = one - a + if any(temp-one != zero): + break + a = a * beta + negep = negep - 1 + # Prevent infinite loop on PPC with gcc 4.0: + if negep < 0: + raise RuntimeError("could not determine machine tolerance " + "for 'negep', locals() -> %s" % (locals())) + else: + raise RuntimeError(msg % (_, one.dtype)) + negep = -negep + epsneg = a + + # Determine machep and eps + machep = - it - 3 + a = b + + for _ in range(max_iterN): + temp = one + a + if any(temp-one != zero): + break + a = a * beta + machep = machep + 1 + else: + raise RuntimeError(msg % (_, one.dtype)) + eps = a + + # Determine ngrd + ngrd = 0 + temp = one + eps + if irnd == 0 and any(temp*one - one != zero): + ngrd = 1 + + # Determine iexp + i = 0 + k = 1 + z = betain + t = one + eps + nxres = 0 + for _ in range(max_iterN): + y = z + z = y*y + a = z*one # Check here for underflow + temp = z*t + if any(a+a == zero) or any(abs(z) >= y): + break + temp1 = temp * betain + if any(temp1*beta == z): + break + i = i + 1 + k = k + k + else: + raise RuntimeError(msg % (_, one.dtype)) + if ibeta != 10: + iexp = i + 1 + mx = k + k + else: + iexp = 2 + iz = ibeta + while k >= iz: + iz = iz * ibeta + iexp = iexp + 1 + mx = iz + iz - 1 + + # Determine minexp and xmin + for _ in range(max_iterN): + xmin = y + y = y * betain + a = y * one + temp = y * t + if any((a + a) != zero) and any(abs(y) < xmin): + k = k + 1 + temp1 = temp * betain + if any(temp1*beta == y) and any(temp != y): + nxres = 3 + xmin = y + break + else: + break + else: + raise RuntimeError(msg % (_, one.dtype)) + minexp = -k + + # Determine maxexp, xmax + if mx <= k + k - 3 and ibeta != 10: + mx = mx + mx + iexp = iexp + 1 + maxexp = mx + minexp + irnd = irnd + nxres + if irnd >= 2: + maxexp = maxexp - 2 + i = maxexp + minexp + if ibeta == 2 and not i: + maxexp = maxexp - 1 + if i > 20: + maxexp = maxexp - 1 + if any(a != y): + maxexp = maxexp - 2 + xmax = one - epsneg + if any(xmax*one != xmax): + xmax = one - beta*epsneg + xmax = xmax / (xmin*beta*beta*beta) + i = maxexp + minexp + 3 + for j in range(i): + if ibeta == 2: + xmax = xmax + xmax + else: + xmax = xmax * beta + + self.ibeta = ibeta + self.it = it + self.negep = negep + self.epsneg = float_to_float(epsneg) + self._str_epsneg = float_to_str(epsneg) + self.machep = machep + self.eps = float_to_float(eps) + self._str_eps = float_to_str(eps) + self.ngrd = ngrd + self.iexp = iexp + self.minexp = minexp + self.xmin = float_to_float(xmin) + self._str_xmin = float_to_str(xmin) + self.maxexp = maxexp + self.xmax = float_to_float(xmax) + self._str_xmax = float_to_str(xmax) + self.irnd = irnd + + self.title = title + # Commonly used parameters + self.epsilon = self.eps + self.tiny = self.xmin + self.huge = self.xmax + + import math + self.precision = int(-math.log10(float_to_float(self.eps))) + ten = two + two + two + two + two + resolution = ten ** (-self.precision) + self.resolution = float_to_float(resolution) + self._str_resolution = float_to_str(resolution) + + def __str__(self): + fmt = ( + 'Machine parameters for %(title)s\n' + '---------------------------------------------------------------------\n' + 'ibeta=%(ibeta)s it=%(it)s iexp=%(iexp)s ngrd=%(ngrd)s irnd=%(irnd)s\n' + 'machep=%(machep)s eps=%(_str_eps)s (beta**machep == epsilon)\n' + 'negep =%(negep)s epsneg=%(_str_epsneg)s (beta**epsneg)\n' + 'minexp=%(minexp)s xmin=%(_str_xmin)s (beta**minexp == tiny)\n' + 'maxexp=%(maxexp)s xmax=%(_str_xmax)s ((1-epsneg)*beta**maxexp == huge)\n' + '---------------------------------------------------------------------\n' + ) + return fmt % self.__dict__ + + +if __name__ == '__main__': + print(MachAr()) diff --git a/venv/Lib/site-packages/numpy/core/memmap.py b/venv/Lib/site-packages/numpy/core/memmap.py new file mode 100644 index 0000000..66653c0 --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/memmap.py @@ -0,0 +1,337 @@ +import numpy as np +from .numeric import uint8, ndarray, dtype +from numpy.compat import ( + os_fspath, contextlib_nullcontext, is_pathlib_path +) +from numpy.core.overrides import set_module + +__all__ = ['memmap'] + +dtypedescr = dtype +valid_filemodes = ["r", "c", "r+", "w+"] +writeable_filemodes = ["r+", "w+"] + +mode_equivalents = { + "readonly":"r", + "copyonwrite":"c", + "readwrite":"r+", + "write":"w+" + } + + +@set_module('numpy') +class memmap(ndarray): + """Create a memory-map to an array stored in a *binary* file on disk. + + Memory-mapped files are used for accessing small segments of large files + on disk, without reading the entire file into memory. NumPy's + memmap's are array-like objects. This differs from Python's ``mmap`` + module, which uses file-like objects. + + This subclass of ndarray has some unpleasant interactions with + some operations, because it doesn't quite fit properly as a subclass. + An alternative to using this subclass is to create the ``mmap`` + object yourself, then create an ndarray with ndarray.__new__ directly, + passing the object created in its 'buffer=' parameter. + + This class may at some point be turned into a factory function + which returns a view into an mmap buffer. + + Flush the memmap instance to write the changes to the file. Currently there + is no API to close the underlying ``mmap``. It is tricky to ensure the + resource is actually closed, since it may be shared between different + memmap instances. + + + Parameters + ---------- + filename : str, file-like object, or pathlib.Path instance + The file name or file object to be used as the array data buffer. + dtype : data-type, optional + The data-type used to interpret the file contents. + Default is `uint8`. + mode : {'r+', 'r', 'w+', 'c'}, optional + The file is opened in this mode: + + +------+-------------------------------------------------------------+ + | 'r' | Open existing file for reading only. | + +------+-------------------------------------------------------------+ + | 'r+' | Open existing file for reading and writing. | + +------+-------------------------------------------------------------+ + | 'w+' | Create or overwrite existing file for reading and writing. | + +------+-------------------------------------------------------------+ + | 'c' | Copy-on-write: assignments affect data in memory, but | + | | changes are not saved to disk. The file on disk is | + | | read-only. | + +------+-------------------------------------------------------------+ + + Default is 'r+'. + offset : int, optional + In the file, array data starts at this offset. Since `offset` is + measured in bytes, it should normally be a multiple of the byte-size + of `dtype`. When ``mode != 'r'``, even positive offsets beyond end of + file are valid; The file will be extended to accommodate the + additional data. By default, ``memmap`` will start at the beginning of + the file, even if ``filename`` is a file pointer ``fp`` and + ``fp.tell() != 0``. + shape : tuple, optional + The desired shape of the array. If ``mode == 'r'`` and the number + of remaining bytes after `offset` is not a multiple of the byte-size + of `dtype`, you must specify `shape`. By default, the returned array + will be 1-D with the number of elements determined by file size + and data-type. + order : {'C', 'F'}, optional + Specify the order of the ndarray memory layout: + :term:`row-major`, C-style or :term:`column-major`, + Fortran-style. This only has an effect if the shape is + greater than 1-D. The default order is 'C'. + + Attributes + ---------- + filename : str or pathlib.Path instance + Path to the mapped file. + offset : int + Offset position in the file. + mode : str + File mode. + + Methods + ------- + flush + Flush any changes in memory to file on disk. + When you delete a memmap object, flush is called first to write + changes to disk. + + + See also + -------- + lib.format.open_memmap : Create or load a memory-mapped ``.npy`` file. + + Notes + ----- + The memmap object can be used anywhere an ndarray is accepted. + Given a memmap ``fp``, ``isinstance(fp, numpy.ndarray)`` returns + ``True``. + + Memory-mapped files cannot be larger than 2GB on 32-bit systems. + + When a memmap causes a file to be created or extended beyond its + current size in the filesystem, the contents of the new part are + unspecified. On systems with POSIX filesystem semantics, the extended + part will be filled with zero bytes. + + Examples + -------- + >>> data = np.arange(12, dtype='float32') + >>> data.resize((3,4)) + + This example uses a temporary file so that doctest doesn't write + files to your directory. You would use a 'normal' filename. + + >>> from tempfile import mkdtemp + >>> import os.path as path + >>> filename = path.join(mkdtemp(), 'newfile.dat') + + Create a memmap with dtype and shape that matches our data: + + >>> fp = np.memmap(filename, dtype='float32', mode='w+', shape=(3,4)) + >>> fp + memmap([[0., 0., 0., 0.], + [0., 0., 0., 0.], + [0., 0., 0., 0.]], dtype=float32) + + Write data to memmap array: + + >>> fp[:] = data[:] + >>> fp + memmap([[ 0., 1., 2., 3.], + [ 4., 5., 6., 7.], + [ 8., 9., 10., 11.]], dtype=float32) + + >>> fp.filename == path.abspath(filename) + True + + Flushes memory changes to disk in order to read them back + + >>> fp.flush() + + Load the memmap and verify data was stored: + + >>> newfp = np.memmap(filename, dtype='float32', mode='r', shape=(3,4)) + >>> newfp + memmap([[ 0., 1., 2., 3.], + [ 4., 5., 6., 7.], + [ 8., 9., 10., 11.]], dtype=float32) + + Read-only memmap: + + >>> fpr = np.memmap(filename, dtype='float32', mode='r', shape=(3,4)) + >>> fpr.flags.writeable + False + + Copy-on-write memmap: + + >>> fpc = np.memmap(filename, dtype='float32', mode='c', shape=(3,4)) + >>> fpc.flags.writeable + True + + It's possible to assign to copy-on-write array, but values are only + written into the memory copy of the array, and not written to disk: + + >>> fpc + memmap([[ 0., 1., 2., 3.], + [ 4., 5., 6., 7.], + [ 8., 9., 10., 11.]], dtype=float32) + >>> fpc[0,:] = 0 + >>> fpc + memmap([[ 0., 0., 0., 0.], + [ 4., 5., 6., 7.], + [ 8., 9., 10., 11.]], dtype=float32) + + File on disk is unchanged: + + >>> fpr + memmap([[ 0., 1., 2., 3.], + [ 4., 5., 6., 7.], + [ 8., 9., 10., 11.]], dtype=float32) + + Offset into a memmap: + + >>> fpo = np.memmap(filename, dtype='float32', mode='r', offset=16) + >>> fpo + memmap([ 4., 5., 6., 7., 8., 9., 10., 11.], dtype=float32) + + """ + + __array_priority__ = -100.0 + + def __new__(subtype, filename, dtype=uint8, mode='r+', offset=0, + shape=None, order='C'): + # Import here to minimize 'import numpy' overhead + import mmap + import os.path + try: + mode = mode_equivalents[mode] + except KeyError as e: + if mode not in valid_filemodes: + raise ValueError( + "mode must be one of {!r} (got {!r})" + .format(valid_filemodes + list(mode_equivalents.keys()), mode) + ) from None + + if mode == 'w+' and shape is None: + raise ValueError("shape must be given") + + if hasattr(filename, 'read'): + f_ctx = contextlib_nullcontext(filename) + else: + f_ctx = open(os_fspath(filename), ('r' if mode == 'c' else mode)+'b') + + with f_ctx as fid: + fid.seek(0, 2) + flen = fid.tell() + descr = dtypedescr(dtype) + _dbytes = descr.itemsize + + if shape is None: + bytes = flen - offset + if bytes % _dbytes: + raise ValueError("Size of available data is not a " + "multiple of the data-type size.") + size = bytes // _dbytes + shape = (size,) + else: + if not isinstance(shape, tuple): + shape = (shape,) + size = np.intp(1) # avoid default choice of np.int_, which might overflow + for k in shape: + size *= k + + bytes = int(offset + size*_dbytes) + + if mode in ('w+', 'r+') and flen < bytes: + fid.seek(bytes - 1, 0) + fid.write(b'\0') + fid.flush() + + if mode == 'c': + acc = mmap.ACCESS_COPY + elif mode == 'r': + acc = mmap.ACCESS_READ + else: + acc = mmap.ACCESS_WRITE + + start = offset - offset % mmap.ALLOCATIONGRANULARITY + bytes -= start + array_offset = offset - start + mm = mmap.mmap(fid.fileno(), bytes, access=acc, offset=start) + + self = ndarray.__new__(subtype, shape, dtype=descr, buffer=mm, + offset=array_offset, order=order) + self._mmap = mm + self.offset = offset + self.mode = mode + + if is_pathlib_path(filename): + # special case - if we were constructed with a pathlib.path, + # then filename is a path object, not a string + self.filename = filename.resolve() + elif hasattr(fid, "name") and isinstance(fid.name, str): + # py3 returns int for TemporaryFile().name + self.filename = os.path.abspath(fid.name) + # same as memmap copies (e.g. memmap + 1) + else: + self.filename = None + + return self + + def __array_finalize__(self, obj): + if hasattr(obj, '_mmap') and np.may_share_memory(self, obj): + self._mmap = obj._mmap + self.filename = obj.filename + self.offset = obj.offset + self.mode = obj.mode + else: + self._mmap = None + self.filename = None + self.offset = None + self.mode = None + + def flush(self): + """ + Write any changes in the array to the file on disk. + + For further information, see `memmap`. + + Parameters + ---------- + None + + See Also + -------- + memmap + + """ + if self.base is not None and hasattr(self.base, 'flush'): + self.base.flush() + + def __array_wrap__(self, arr, context=None): + arr = super(memmap, self).__array_wrap__(arr, context) + + # Return a memmap if a memmap was given as the output of the + # ufunc. Leave the arr class unchanged if self is not a memmap + # to keep original memmap subclasses behavior + if self is arr or type(self) is not memmap: + return arr + # Return scalar instead of 0d memmap, e.g. for np.sum with + # axis=None + if arr.shape == (): + return arr[()] + # Return ndarray otherwise + return arr.view(np.ndarray) + + def __getitem__(self, index): + res = super(memmap, self).__getitem__(index) + if type(res) is memmap and res._mmap is None: + return res.view(type=ndarray) + return res diff --git a/venv/Lib/site-packages/numpy/core/multiarray.py b/venv/Lib/site-packages/numpy/core/multiarray.py new file mode 100644 index 0000000..f311fad --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/multiarray.py @@ -0,0 +1,1673 @@ +""" +Create the numpy.core.multiarray namespace for backward compatibility. In v1.16 +the multiarray and umath c-extension modules were merged into a single +_multiarray_umath extension module. So we replicate the old namespace +by importing from the extension module. + +""" + +import functools +import warnings + +from . import overrides +from . import _multiarray_umath +from ._multiarray_umath import * # noqa: F403 +# These imports are needed for backward compatibility, +# do not change them. issue gh-15518 +# _get_ndarray_c_version is semi-public, on purpose not added to __all__ +from ._multiarray_umath import ( + _fastCopyAndTranspose, _flagdict, _insert, _reconstruct, _vec_string, + _ARRAY_API, _monotonicity, _get_ndarray_c_version, _set_madvise_hugepage, + ) + +__all__ = [ + '_ARRAY_API', 'ALLOW_THREADS', 'BUFSIZE', 'CLIP', 'DATETIMEUNITS', + 'ITEM_HASOBJECT', 'ITEM_IS_POINTER', 'LIST_PICKLE', 'MAXDIMS', + 'MAY_SHARE_BOUNDS', 'MAY_SHARE_EXACT', 'NEEDS_INIT', 'NEEDS_PYAPI', + 'RAISE', 'USE_GETITEM', 'USE_SETITEM', 'WRAP', '_fastCopyAndTranspose', + '_flagdict', '_insert', '_reconstruct', '_vec_string', '_monotonicity', + 'add_docstring', 'arange', 'array', 'bincount', 'broadcast', + 'busday_count', 'busday_offset', 'busdaycalendar', 'can_cast', + 'compare_chararrays', 'concatenate', 'copyto', 'correlate', 'correlate2', + 'count_nonzero', 'c_einsum', 'datetime_as_string', 'datetime_data', + 'digitize', 'dot', 'dragon4_positional', 'dragon4_scientific', 'dtype', + 'empty', 'empty_like', 'error', 'flagsobj', 'flatiter', 'format_longfloat', + 'frombuffer', 'fromfile', 'fromiter', 'fromstring', 'inner', + 'interp', 'interp_complex', 'is_busday', 'lexsort', + 'matmul', 'may_share_memory', 'min_scalar_type', 'ndarray', 'nditer', + 'nested_iters', 'normalize_axis_index', 'packbits', + 'promote_types', 'putmask', 'ravel_multi_index', 'result_type', 'scalar', + 'set_datetimeparse_function', 'set_legacy_print_mode', 'set_numeric_ops', + 'set_string_function', 'set_typeDict', 'shares_memory', + 'tracemalloc_domain', 'typeinfo', 'unpackbits', 'unravel_index', 'vdot', + 'where', 'zeros'] + +# For backward compatibility, make sure pickle imports these functions from here +_reconstruct.__module__ = 'numpy.core.multiarray' +scalar.__module__ = 'numpy.core.multiarray' + + +arange.__module__ = 'numpy' +array.__module__ = 'numpy' +datetime_data.__module__ = 'numpy' +empty.__module__ = 'numpy' +frombuffer.__module__ = 'numpy' +fromfile.__module__ = 'numpy' +fromiter.__module__ = 'numpy' +frompyfunc.__module__ = 'numpy' +fromstring.__module__ = 'numpy' +geterrobj.__module__ = 'numpy' +may_share_memory.__module__ = 'numpy' +nested_iters.__module__ = 'numpy' +promote_types.__module__ = 'numpy' +set_numeric_ops.__module__ = 'numpy' +seterrobj.__module__ = 'numpy' +zeros.__module__ = 'numpy' + + +# We can't verify dispatcher signatures because NumPy's C functions don't +# support introspection. +array_function_from_c_func_and_dispatcher = functools.partial( + overrides.array_function_from_dispatcher, + module='numpy', docs_from_dispatcher=True, verify=False) + + +@array_function_from_c_func_and_dispatcher(_multiarray_umath.empty_like) +def empty_like(prototype, dtype=None, order=None, subok=None, shape=None): + """ + empty_like(prototype, dtype=None, order='K', subok=True, shape=None) + + Return a new array with the same shape and type as a given array. + + Parameters + ---------- + prototype : array_like + The shape and data-type of `prototype` define these same attributes + of the returned array. + dtype : data-type, optional + Overrides the data type of the result. + + .. versionadded:: 1.6.0 + order : {'C', 'F', 'A', or 'K'}, optional + Overrides the memory layout of the result. 'C' means C-order, + 'F' means F-order, 'A' means 'F' if `prototype` is Fortran + contiguous, 'C' otherwise. 'K' means match the layout of `prototype` + as closely as possible. + + .. versionadded:: 1.6.0 + subok : bool, optional. + If True, then the newly created array will use the sub-class + type of `prototype`, otherwise it will be a base-class array. Defaults + to True. + shape : int or sequence of ints, optional. + Overrides the shape of the result. If order='K' and the number of + dimensions is unchanged, will try to keep order, otherwise, + order='C' is implied. + + .. versionadded:: 1.17.0 + + Returns + ------- + out : ndarray + Array of uninitialized (arbitrary) data with the same + shape and type as `prototype`. + + See Also + -------- + ones_like : Return an array of ones with shape and type of input. + zeros_like : Return an array of zeros with shape and type of input. + full_like : Return a new array with shape of input filled with value. + empty : Return a new uninitialized array. + + Notes + ----- + This function does *not* initialize the returned array; to do that use + `zeros_like` or `ones_like` instead. It may be marginally faster than + the functions that do set the array values. + + Examples + -------- + >>> a = ([1,2,3], [4,5,6]) # a is array-like + >>> np.empty_like(a) + array([[-1073741821, -1073741821, 3], # uninitialized + [ 0, 0, -1073741821]]) + >>> a = np.array([[1., 2., 3.],[4.,5.,6.]]) + >>> np.empty_like(a) + array([[ -2.00000715e+000, 1.48219694e-323, -2.00000572e+000], # uninitialized + [ 4.38791518e-305, -2.00000715e+000, 4.17269252e-309]]) + + """ + return (prototype,) + + +@array_function_from_c_func_and_dispatcher(_multiarray_umath.concatenate) +def concatenate(arrays, axis=None, out=None, *, dtype=None, casting=None): + """ + concatenate((a1, a2, ...), axis=0, out=None, dtype=None, casting="same_kind") + + Join a sequence of arrays along an existing axis. + + Parameters + ---------- + a1, a2, ... : sequence of array_like + The arrays must have the same shape, except in the dimension + corresponding to `axis` (the first, by default). + axis : int, optional + The axis along which the arrays will be joined. If axis is None, + arrays are flattened before use. Default is 0. + out : ndarray, optional + If provided, the destination to place the result. The shape must be + correct, matching that of what concatenate would have returned if no + out argument were specified. + dtype : str or dtype + If provided, the destination array will have this dtype. Cannot be + provided together with `out`. + + .. versionadded:: 1.20.0 + + casting : {'no', 'equiv', 'safe', 'same_kind', 'unsafe'}, optional + Controls what kind of data casting may occur. Defaults to 'same_kind'. + + .. versionadded:: 1.20.0 + + Returns + ------- + res : ndarray + The concatenated array. + + See Also + -------- + ma.concatenate : Concatenate function that preserves input masks. + array_split : Split an array into multiple sub-arrays of equal or + near-equal size. + split : Split array into a list of multiple sub-arrays of equal size. + hsplit : Split array into multiple sub-arrays horizontally (column wise). + vsplit : Split array into multiple sub-arrays vertically (row wise). + dsplit : Split array into multiple sub-arrays along the 3rd axis (depth). + stack : Stack a sequence of arrays along a new axis. + block : Assemble arrays from blocks. + hstack : Stack arrays in sequence horizontally (column wise). + vstack : Stack arrays in sequence vertically (row wise). + dstack : Stack arrays in sequence depth wise (along third dimension). + column_stack : Stack 1-D arrays as columns into a 2-D array. + + Notes + ----- + When one or more of the arrays to be concatenated is a MaskedArray, + this function will return a MaskedArray object instead of an ndarray, + but the input masks are *not* preserved. In cases where a MaskedArray + is expected as input, use the ma.concatenate function from the masked + array module instead. + + Examples + -------- + >>> a = np.array([[1, 2], [3, 4]]) + >>> b = np.array([[5, 6]]) + >>> np.concatenate((a, b), axis=0) + array([[1, 2], + [3, 4], + [5, 6]]) + >>> np.concatenate((a, b.T), axis=1) + array([[1, 2, 5], + [3, 4, 6]]) + >>> np.concatenate((a, b), axis=None) + array([1, 2, 3, 4, 5, 6]) + + This function will not preserve masking of MaskedArray inputs. + + >>> a = np.ma.arange(3) + >>> a[1] = np.ma.masked + >>> b = np.arange(2, 5) + >>> a + masked_array(data=[0, --, 2], + mask=[False, True, False], + fill_value=999999) + >>> b + array([2, 3, 4]) + >>> np.concatenate([a, b]) + masked_array(data=[0, 1, 2, 2, 3, 4], + mask=False, + fill_value=999999) + >>> np.ma.concatenate([a, b]) + masked_array(data=[0, --, 2, 2, 3, 4], + mask=[False, True, False, False, False, False], + fill_value=999999) + + """ + if out is not None: + # optimize for the typical case where only arrays is provided + arrays = list(arrays) + arrays.append(out) + return arrays + + +@array_function_from_c_func_and_dispatcher(_multiarray_umath.inner) +def inner(a, b): + """ + inner(a, b) + + Inner product of two arrays. + + Ordinary inner product of vectors for 1-D arrays (without complex + conjugation), in higher dimensions a sum product over the last axes. + + Parameters + ---------- + a, b : array_like + If `a` and `b` are nonscalar, their last dimensions must match. + + Returns + ------- + out : ndarray + `out.shape = a.shape[:-1] + b.shape[:-1]` + + Raises + ------ + ValueError + If the last dimension of `a` and `b` has different size. + + See Also + -------- + tensordot : Sum products over arbitrary axes. + dot : Generalised matrix product, using second last dimension of `b`. + einsum : Einstein summation convention. + + Notes + ----- + For vectors (1-D arrays) it computes the ordinary inner-product:: + + np.inner(a, b) = sum(a[:]*b[:]) + + More generally, if `ndim(a) = r > 0` and `ndim(b) = s > 0`:: + + np.inner(a, b) = np.tensordot(a, b, axes=(-1,-1)) + + or explicitly:: + + np.inner(a, b)[i0,...,ir-1,j0,...,js-1] + = sum(a[i0,...,ir-1,:]*b[j0,...,js-1,:]) + + In addition `a` or `b` may be scalars, in which case:: + + np.inner(a,b) = a*b + + Examples + -------- + Ordinary inner product for vectors: + + >>> a = np.array([1,2,3]) + >>> b = np.array([0,1,0]) + >>> np.inner(a, b) + 2 + + A multidimensional example: + + >>> a = np.arange(24).reshape((2,3,4)) + >>> b = np.arange(4) + >>> np.inner(a, b) + array([[ 14, 38, 62], + [ 86, 110, 134]]) + + An example where `b` is a scalar: + + >>> np.inner(np.eye(2), 7) + array([[7., 0.], + [0., 7.]]) + + """ + return (a, b) + + +@array_function_from_c_func_and_dispatcher(_multiarray_umath.where) +def where(condition, x=None, y=None): + """ + where(condition, [x, y]) + + Return elements chosen from `x` or `y` depending on `condition`. + + .. note:: + When only `condition` is provided, this function is a shorthand for + ``np.asarray(condition).nonzero()``. Using `nonzero` directly should be + preferred, as it behaves correctly for subclasses. The rest of this + documentation covers only the case where all three arguments are + provided. + + Parameters + ---------- + condition : array_like, bool + Where True, yield `x`, otherwise yield `y`. + x, y : array_like + Values from which to choose. `x`, `y` and `condition` need to be + broadcastable to some shape. + + Returns + ------- + out : ndarray + An array with elements from `x` where `condition` is True, and elements + from `y` elsewhere. + + See Also + -------- + choose + nonzero : The function that is called when x and y are omitted + + Notes + ----- + If all the arrays are 1-D, `where` is equivalent to:: + + [xv if c else yv + for c, xv, yv in zip(condition, x, y)] + + Examples + -------- + >>> a = np.arange(10) + >>> a + array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) + >>> np.where(a < 5, a, 10*a) + array([ 0, 1, 2, 3, 4, 50, 60, 70, 80, 90]) + + This can be used on multidimensional arrays too: + + >>> np.where([[True, False], [True, True]], + ... [[1, 2], [3, 4]], + ... [[9, 8], [7, 6]]) + array([[1, 8], + [3, 4]]) + + The shapes of x, y, and the condition are broadcast together: + + >>> x, y = np.ogrid[:3, :4] + >>> np.where(x < y, x, 10 + y) # both x and 10+y are broadcast + array([[10, 0, 0, 0], + [10, 11, 1, 1], + [10, 11, 12, 2]]) + + >>> a = np.array([[0, 1, 2], + ... [0, 2, 4], + ... [0, 3, 6]]) + >>> np.where(a < 4, a, -1) # -1 is broadcast + array([[ 0, 1, 2], + [ 0, 2, -1], + [ 0, 3, -1]]) + """ + return (condition, x, y) + + +@array_function_from_c_func_and_dispatcher(_multiarray_umath.lexsort) +def lexsort(keys, axis=None): + """ + lexsort(keys, axis=-1) + + Perform an indirect stable sort using a sequence of keys. + + Given multiple sorting keys, which can be interpreted as columns in a + spreadsheet, lexsort returns an array of integer indices that describes + the sort order by multiple columns. The last key in the sequence is used + for the primary sort order, the second-to-last key for the secondary sort + order, and so on. The keys argument must be a sequence of objects that + can be converted to arrays of the same shape. If a 2D array is provided + for the keys argument, its rows are interpreted as the sorting keys and + sorting is according to the last row, second last row etc. + + Parameters + ---------- + keys : (k, N) array or tuple containing k (N,)-shaped sequences + The `k` different "columns" to be sorted. The last column (or row if + `keys` is a 2D array) is the primary sort key. + axis : int, optional + Axis to be indirectly sorted. By default, sort over the last axis. + + Returns + ------- + indices : (N,) ndarray of ints + Array of indices that sort the keys along the specified axis. + + See Also + -------- + argsort : Indirect sort. + ndarray.sort : In-place sort. + sort : Return a sorted copy of an array. + + Examples + -------- + Sort names: first by surname, then by name. + + >>> surnames = ('Hertz', 'Galilei', 'Hertz') + >>> first_names = ('Heinrich', 'Galileo', 'Gustav') + >>> ind = np.lexsort((first_names, surnames)) + >>> ind + array([1, 2, 0]) + + >>> [surnames[i] + ", " + first_names[i] for i in ind] + ['Galilei, Galileo', 'Hertz, Gustav', 'Hertz, Heinrich'] + + Sort two columns of numbers: + + >>> a = [1,5,1,4,3,4,4] # First column + >>> b = [9,4,0,4,0,2,1] # Second column + >>> ind = np.lexsort((b,a)) # Sort by a, then by b + >>> ind + array([2, 0, 4, 6, 5, 3, 1]) + + >>> [(a[i],b[i]) for i in ind] + [(1, 0), (1, 9), (3, 0), (4, 1), (4, 2), (4, 4), (5, 4)] + + Note that sorting is first according to the elements of ``a``. + Secondary sorting is according to the elements of ``b``. + + A normal ``argsort`` would have yielded: + + >>> [(a[i],b[i]) for i in np.argsort(a)] + [(1, 9), (1, 0), (3, 0), (4, 4), (4, 2), (4, 1), (5, 4)] + + Structured arrays are sorted lexically by ``argsort``: + + >>> x = np.array([(1,9), (5,4), (1,0), (4,4), (3,0), (4,2), (4,1)], + ... dtype=np.dtype([('x', int), ('y', int)])) + + >>> np.argsort(x) # or np.argsort(x, order=('x', 'y')) + array([2, 0, 4, 6, 5, 3, 1]) + + """ + if isinstance(keys, tuple): + return keys + else: + return (keys,) + + +@array_function_from_c_func_and_dispatcher(_multiarray_umath.can_cast) +def can_cast(from_, to, casting=None): + """ + can_cast(from_, to, casting='safe') + + Returns True if cast between data types can occur according to the + casting rule. If from is a scalar or array scalar, also returns + True if the scalar value can be cast without overflow or truncation + to an integer. + + Parameters + ---------- + from_ : dtype, dtype specifier, scalar, or array + Data type, scalar, or array to cast from. + to : dtype or dtype specifier + Data type to cast to. + casting : {'no', 'equiv', 'safe', 'same_kind', 'unsafe'}, optional + Controls what kind of data casting may occur. + + * 'no' means the data types should not be cast at all. + * 'equiv' means only byte-order changes are allowed. + * 'safe' means only casts which can preserve values are allowed. + * 'same_kind' means only safe casts or casts within a kind, + like float64 to float32, are allowed. + * 'unsafe' means any data conversions may be done. + + Returns + ------- + out : bool + True if cast can occur according to the casting rule. + + Notes + ----- + .. versionchanged:: 1.17.0 + Casting between a simple data type and a structured one is possible only + for "unsafe" casting. Casting to multiple fields is allowed, but + casting from multiple fields is not. + + .. versionchanged:: 1.9.0 + Casting from numeric to string types in 'safe' casting mode requires + that the string dtype length is long enough to store the maximum + integer/float value converted. + + See also + -------- + dtype, result_type + + Examples + -------- + Basic examples + + >>> np.can_cast(np.int32, np.int64) + True + >>> np.can_cast(np.float64, complex) + True + >>> np.can_cast(complex, float) + False + + >>> np.can_cast('i8', 'f8') + True + >>> np.can_cast('i8', 'f4') + False + >>> np.can_cast('i4', 'S4') + False + + Casting scalars + + >>> np.can_cast(100, 'i1') + True + >>> np.can_cast(150, 'i1') + False + >>> np.can_cast(150, 'u1') + True + + >>> np.can_cast(3.5e100, np.float32) + False + >>> np.can_cast(1000.0, np.float32) + True + + Array scalar checks the value, array does not + + >>> np.can_cast(np.array(1000.0), np.float32) + True + >>> np.can_cast(np.array([1000.0]), np.float32) + False + + Using the casting rules + + >>> np.can_cast('i8', 'i8', 'no') + True + >>> np.can_cast('i8', 'no') + False + + >>> np.can_cast('i8', 'equiv') + True + >>> np.can_cast('i8', 'equiv') + False + + >>> np.can_cast('i8', 'safe') + True + >>> np.can_cast('i4', 'safe') + False + + >>> np.can_cast('i4', 'same_kind') + True + >>> np.can_cast('u4', 'same_kind') + False + + >>> np.can_cast('u4', 'unsafe') + True + + """ + return (from_,) + + +@array_function_from_c_func_and_dispatcher(_multiarray_umath.min_scalar_type) +def min_scalar_type(a): + """ + min_scalar_type(a) + + For scalar ``a``, returns the data type with the smallest size + and smallest scalar kind which can hold its value. For non-scalar + array ``a``, returns the vector's dtype unmodified. + + Floating point values are not demoted to integers, + and complex values are not demoted to floats. + + Parameters + ---------- + a : scalar or array_like + The value whose minimal data type is to be found. + + Returns + ------- + out : dtype + The minimal data type. + + Notes + ----- + .. versionadded:: 1.6.0 + + See Also + -------- + result_type, promote_types, dtype, can_cast + + Examples + -------- + >>> np.min_scalar_type(10) + dtype('uint8') + + >>> np.min_scalar_type(-260) + dtype('int16') + + >>> np.min_scalar_type(3.1) + dtype('float16') + + >>> np.min_scalar_type(1e50) + dtype('float64') + + >>> np.min_scalar_type(np.arange(4,dtype='f8')) + dtype('float64') + + """ + return (a,) + + +@array_function_from_c_func_and_dispatcher(_multiarray_umath.result_type) +def result_type(*arrays_and_dtypes): + """ + result_type(*arrays_and_dtypes) + + Returns the type that results from applying the NumPy + type promotion rules to the arguments. + + Type promotion in NumPy works similarly to the rules in languages + like C++, with some slight differences. When both scalars and + arrays are used, the array's type takes precedence and the actual value + of the scalar is taken into account. + + For example, calculating 3*a, where a is an array of 32-bit floats, + intuitively should result in a 32-bit float output. If the 3 is a + 32-bit integer, the NumPy rules indicate it can't convert losslessly + into a 32-bit float, so a 64-bit float should be the result type. + By examining the value of the constant, '3', we see that it fits in + an 8-bit integer, which can be cast losslessly into the 32-bit float. + + Parameters + ---------- + arrays_and_dtypes : list of arrays and dtypes + The operands of some operation whose result type is needed. + + Returns + ------- + out : dtype + The result type. + + See also + -------- + dtype, promote_types, min_scalar_type, can_cast + + Notes + ----- + .. versionadded:: 1.6.0 + + The specific algorithm used is as follows. + + Categories are determined by first checking which of boolean, + integer (int/uint), or floating point (float/complex) the maximum + kind of all the arrays and the scalars are. + + If there are only scalars or the maximum category of the scalars + is higher than the maximum category of the arrays, + the data types are combined with :func:`promote_types` + to produce the return value. + + Otherwise, `min_scalar_type` is called on each array, and + the resulting data types are all combined with :func:`promote_types` + to produce the return value. + + The set of int values is not a subset of the uint values for types + with the same number of bits, something not reflected in + :func:`min_scalar_type`, but handled as a special case in `result_type`. + + Examples + -------- + >>> np.result_type(3, np.arange(7, dtype='i1')) + dtype('int8') + + >>> np.result_type('i4', 'c8') + dtype('complex128') + + >>> np.result_type(3.0, -2) + dtype('float64') + + """ + return arrays_and_dtypes + + +@array_function_from_c_func_and_dispatcher(_multiarray_umath.dot) +def dot(a, b, out=None): + """ + dot(a, b, out=None) + + Dot product of two arrays. Specifically, + + - If both `a` and `b` are 1-D arrays, it is inner product of vectors + (without complex conjugation). + + - If both `a` and `b` are 2-D arrays, it is matrix multiplication, + but using :func:`matmul` or ``a @ b`` is preferred. + + - If either `a` or `b` is 0-D (scalar), it is equivalent to :func:`multiply` + and using ``numpy.multiply(a, b)`` or ``a * b`` is preferred. + + - If `a` is an N-D array and `b` is a 1-D array, it is a sum product over + the last axis of `a` and `b`. + + - If `a` is an N-D array and `b` is an M-D array (where ``M>=2``), it is a + sum product over the last axis of `a` and the second-to-last axis of `b`:: + + dot(a, b)[i,j,k,m] = sum(a[i,j,:] * b[k,:,m]) + + Parameters + ---------- + a : array_like + First argument. + b : array_like + Second argument. + out : ndarray, optional + Output argument. This must have the exact kind that would be returned + if it was not used. In particular, it must have the right type, must be + C-contiguous, and its dtype must be the dtype that would be returned + for `dot(a,b)`. This is a performance feature. Therefore, if these + conditions are not met, an exception is raised, instead of attempting + to be flexible. + + Returns + ------- + output : ndarray + Returns the dot product of `a` and `b`. If `a` and `b` are both + scalars or both 1-D arrays then a scalar is returned; otherwise + an array is returned. + If `out` is given, then it is returned. + + Raises + ------ + ValueError + If the last dimension of `a` is not the same size as + the second-to-last dimension of `b`. + + See Also + -------- + vdot : Complex-conjugating dot product. + tensordot : Sum products over arbitrary axes. + einsum : Einstein summation convention. + matmul : '@' operator as method with out parameter. + linalg.multi_dot : Chained dot product. + + Examples + -------- + >>> np.dot(3, 4) + 12 + + Neither argument is complex-conjugated: + + >>> np.dot([2j, 3j], [2j, 3j]) + (-13+0j) + + For 2-D arrays it is the matrix product: + + >>> a = [[1, 0], [0, 1]] + >>> b = [[4, 1], [2, 2]] + >>> np.dot(a, b) + array([[4, 1], + [2, 2]]) + + >>> a = np.arange(3*4*5*6).reshape((3,4,5,6)) + >>> b = np.arange(3*4*5*6)[::-1].reshape((5,4,6,3)) + >>> np.dot(a, b)[2,3,2,1,2,2] + 499128 + >>> sum(a[2,3,2,:] * b[1,2,:,2]) + 499128 + + """ + return (a, b, out) + + +@array_function_from_c_func_and_dispatcher(_multiarray_umath.vdot) +def vdot(a, b): + """ + vdot(a, b) + + Return the dot product of two vectors. + + The vdot(`a`, `b`) function handles complex numbers differently than + dot(`a`, `b`). If the first argument is complex the complex conjugate + of the first argument is used for the calculation of the dot product. + + Note that `vdot` handles multidimensional arrays differently than `dot`: + it does *not* perform a matrix product, but flattens input arguments + to 1-D vectors first. Consequently, it should only be used for vectors. + + Parameters + ---------- + a : array_like + If `a` is complex the complex conjugate is taken before calculation + of the dot product. + b : array_like + Second argument to the dot product. + + Returns + ------- + output : ndarray + Dot product of `a` and `b`. Can be an int, float, or + complex depending on the types of `a` and `b`. + + See Also + -------- + dot : Return the dot product without using the complex conjugate of the + first argument. + + Examples + -------- + >>> a = np.array([1+2j,3+4j]) + >>> b = np.array([5+6j,7+8j]) + >>> np.vdot(a, b) + (70-8j) + >>> np.vdot(b, a) + (70+8j) + + Note that higher-dimensional arrays are flattened! + + >>> a = np.array([[1, 4], [5, 6]]) + >>> b = np.array([[4, 1], [2, 2]]) + >>> np.vdot(a, b) + 30 + >>> np.vdot(b, a) + 30 + >>> 1*4 + 4*1 + 5*2 + 6*2 + 30 + + """ + return (a, b) + + +@array_function_from_c_func_and_dispatcher(_multiarray_umath.bincount) +def bincount(x, weights=None, minlength=None): + """ + bincount(x, weights=None, minlength=0) + + Count number of occurrences of each value in array of non-negative ints. + + The number of bins (of size 1) is one larger than the largest value in + `x`. If `minlength` is specified, there will be at least this number + of bins in the output array (though it will be longer if necessary, + depending on the contents of `x`). + Each bin gives the number of occurrences of its index value in `x`. + If `weights` is specified the input array is weighted by it, i.e. if a + value ``n`` is found at position ``i``, ``out[n] += weight[i]`` instead + of ``out[n] += 1``. + + Parameters + ---------- + x : array_like, 1 dimension, nonnegative ints + Input array. + weights : array_like, optional + Weights, array of the same shape as `x`. + minlength : int, optional + A minimum number of bins for the output array. + + .. versionadded:: 1.6.0 + + Returns + ------- + out : ndarray of ints + The result of binning the input array. + The length of `out` is equal to ``np.amax(x)+1``. + + Raises + ------ + ValueError + If the input is not 1-dimensional, or contains elements with negative + values, or if `minlength` is negative. + TypeError + If the type of the input is float or complex. + + See Also + -------- + histogram, digitize, unique + + Examples + -------- + >>> np.bincount(np.arange(5)) + array([1, 1, 1, 1, 1]) + >>> np.bincount(np.array([0, 1, 1, 3, 2, 1, 7])) + array([1, 3, 1, 1, 0, 0, 0, 1]) + + >>> x = np.array([0, 1, 1, 3, 2, 1, 7, 23]) + >>> np.bincount(x).size == np.amax(x)+1 + True + + The input array needs to be of integer dtype, otherwise a + TypeError is raised: + + >>> np.bincount(np.arange(5, dtype=float)) + Traceback (most recent call last): + ... + TypeError: Cannot cast array data from dtype('float64') to dtype('int64') + according to the rule 'safe' + + A possible use of ``bincount`` is to perform sums over + variable-size chunks of an array, using the ``weights`` keyword. + + >>> w = np.array([0.3, 0.5, 0.2, 0.7, 1., -0.6]) # weights + >>> x = np.array([0, 1, 1, 2, 2, 2]) + >>> np.bincount(x, weights=w) + array([ 0.3, 0.7, 1.1]) + + """ + return (x, weights) + + +@array_function_from_c_func_and_dispatcher(_multiarray_umath.ravel_multi_index) +def ravel_multi_index(multi_index, dims, mode=None, order=None): + """ + ravel_multi_index(multi_index, dims, mode='raise', order='C') + + Converts a tuple of index arrays into an array of flat + indices, applying boundary modes to the multi-index. + + Parameters + ---------- + multi_index : tuple of array_like + A tuple of integer arrays, one array for each dimension. + dims : tuple of ints + The shape of array into which the indices from ``multi_index`` apply. + mode : {'raise', 'wrap', 'clip'}, optional + Specifies how out-of-bounds indices are handled. Can specify + either one mode or a tuple of modes, one mode per index. + + * 'raise' -- raise an error (default) + * 'wrap' -- wrap around + * 'clip' -- clip to the range + + In 'clip' mode, a negative index which would normally + wrap will clip to 0 instead. + order : {'C', 'F'}, optional + Determines whether the multi-index should be viewed as + indexing in row-major (C-style) or column-major + (Fortran-style) order. + + Returns + ------- + raveled_indices : ndarray + An array of indices into the flattened version of an array + of dimensions ``dims``. + + See Also + -------- + unravel_index + + Notes + ----- + .. versionadded:: 1.6.0 + + Examples + -------- + >>> arr = np.array([[3,6,6],[4,5,1]]) + >>> np.ravel_multi_index(arr, (7,6)) + array([22, 41, 37]) + >>> np.ravel_multi_index(arr, (7,6), order='F') + array([31, 41, 13]) + >>> np.ravel_multi_index(arr, (4,6), mode='clip') + array([22, 23, 19]) + >>> np.ravel_multi_index(arr, (4,4), mode=('clip','wrap')) + array([12, 13, 13]) + + >>> np.ravel_multi_index((3,1,4,1), (6,7,8,9)) + 1621 + """ + return multi_index + + +@array_function_from_c_func_and_dispatcher(_multiarray_umath.unravel_index) +def unravel_index(indices, shape=None, order=None, dims=None): + """ + unravel_index(indices, shape, order='C') + + Converts a flat index or array of flat indices into a tuple + of coordinate arrays. + + Parameters + ---------- + indices : array_like + An integer array whose elements are indices into the flattened + version of an array of dimensions ``shape``. Before version 1.6.0, + this function accepted just one index value. + shape : tuple of ints + The shape of the array to use for unraveling ``indices``. + + .. versionchanged:: 1.16.0 + Renamed from ``dims`` to ``shape``. + + order : {'C', 'F'}, optional + Determines whether the indices should be viewed as indexing in + row-major (C-style) or column-major (Fortran-style) order. + + .. versionadded:: 1.6.0 + + Returns + ------- + unraveled_coords : tuple of ndarray + Each array in the tuple has the same shape as the ``indices`` + array. + + See Also + -------- + ravel_multi_index + + Examples + -------- + >>> np.unravel_index([22, 41, 37], (7,6)) + (array([3, 6, 6]), array([4, 5, 1])) + >>> np.unravel_index([31, 41, 13], (7,6), order='F') + (array([3, 6, 6]), array([4, 5, 1])) + + >>> np.unravel_index(1621, (6,7,8,9)) + (3, 1, 4, 1) + + """ + if dims is not None: + warnings.warn("'shape' argument should be used instead of 'dims'", + DeprecationWarning, stacklevel=3) + return (indices,) + + +@array_function_from_c_func_and_dispatcher(_multiarray_umath.copyto) +def copyto(dst, src, casting=None, where=None): + """ + copyto(dst, src, casting='same_kind', where=True) + + Copies values from one array to another, broadcasting as necessary. + + Raises a TypeError if the `casting` rule is violated, and if + `where` is provided, it selects which elements to copy. + + .. versionadded:: 1.7.0 + + Parameters + ---------- + dst : ndarray + The array into which values are copied. + src : array_like + The array from which values are copied. + casting : {'no', 'equiv', 'safe', 'same_kind', 'unsafe'}, optional + Controls what kind of data casting may occur when copying. + + * 'no' means the data types should not be cast at all. + * 'equiv' means only byte-order changes are allowed. + * 'safe' means only casts which can preserve values are allowed. + * 'same_kind' means only safe casts or casts within a kind, + like float64 to float32, are allowed. + * 'unsafe' means any data conversions may be done. + where : array_like of bool, optional + A boolean array which is broadcasted to match the dimensions + of `dst`, and selects elements to copy from `src` to `dst` + wherever it contains the value True. + """ + return (dst, src, where) + + +@array_function_from_c_func_and_dispatcher(_multiarray_umath.putmask) +def putmask(a, mask, values): + """ + putmask(a, mask, values) + + Changes elements of an array based on conditional and input values. + + Sets ``a.flat[n] = values[n]`` for each n where ``mask.flat[n]==True``. + + If `values` is not the same size as `a` and `mask` then it will repeat. + This gives behavior different from ``a[mask] = values``. + + Parameters + ---------- + a : ndarray + Target array. + mask : array_like + Boolean mask array. It has to be the same shape as `a`. + values : array_like + Values to put into `a` where `mask` is True. If `values` is smaller + than `a` it will be repeated. + + See Also + -------- + place, put, take, copyto + + Examples + -------- + >>> x = np.arange(6).reshape(2, 3) + >>> np.putmask(x, x>2, x**2) + >>> x + array([[ 0, 1, 2], + [ 9, 16, 25]]) + + If `values` is smaller than `a` it is repeated: + + >>> x = np.arange(5) + >>> np.putmask(x, x>1, [-33, -44]) + >>> x + array([ 0, 1, -33, -44, -33]) + + """ + return (a, mask, values) + + +@array_function_from_c_func_and_dispatcher(_multiarray_umath.packbits) +def packbits(a, axis=None, bitorder='big'): + """ + packbits(a, axis=None, bitorder='big') + + Packs the elements of a binary-valued array into bits in a uint8 array. + + The result is padded to full bytes by inserting zero bits at the end. + + Parameters + ---------- + a : array_like + An array of integers or booleans whose elements should be packed to + bits. + axis : int, optional + The dimension over which bit-packing is done. + ``None`` implies packing the flattened array. + bitorder : {'big', 'little'}, optional + The order of the input bits. 'big' will mimic bin(val), + ``[0, 0, 0, 0, 0, 0, 1, 1] => 3 = 0b00000011``, 'little' will + reverse the order so ``[1, 1, 0, 0, 0, 0, 0, 0] => 3``. + Defaults to 'big'. + + .. versionadded:: 1.17.0 + + Returns + ------- + packed : ndarray + Array of type uint8 whose elements represent bits corresponding to the + logical (0 or nonzero) value of the input elements. The shape of + `packed` has the same number of dimensions as the input (unless `axis` + is None, in which case the output is 1-D). + + See Also + -------- + unpackbits: Unpacks elements of a uint8 array into a binary-valued output + array. + + Examples + -------- + >>> a = np.array([[[1,0,1], + ... [0,1,0]], + ... [[1,1,0], + ... [0,0,1]]]) + >>> b = np.packbits(a, axis=-1) + >>> b + array([[[160], + [ 64]], + [[192], + [ 32]]], dtype=uint8) + + Note that in binary 160 = 1010 0000, 64 = 0100 0000, 192 = 1100 0000, + and 32 = 0010 0000. + + """ + return (a,) + + +@array_function_from_c_func_and_dispatcher(_multiarray_umath.unpackbits) +def unpackbits(a, axis=None, count=None, bitorder='big'): + """ + unpackbits(a, axis=None, count=None, bitorder='big') + + Unpacks elements of a uint8 array into a binary-valued output array. + + Each element of `a` represents a bit-field that should be unpacked + into a binary-valued output array. The shape of the output array is + either 1-D (if `axis` is ``None``) or the same shape as the input + array with unpacking done along the axis specified. + + Parameters + ---------- + a : ndarray, uint8 type + Input array. + axis : int, optional + The dimension over which bit-unpacking is done. + ``None`` implies unpacking the flattened array. + count : int or None, optional + The number of elements to unpack along `axis`, provided as a way + of undoing the effect of packing a size that is not a multiple + of eight. A non-negative number means to only unpack `count` + bits. A negative number means to trim off that many bits from + the end. ``None`` means to unpack the entire array (the + default). Counts larger than the available number of bits will + add zero padding to the output. Negative counts must not + exceed the available number of bits. + + .. versionadded:: 1.17.0 + + bitorder : {'big', 'little'}, optional + The order of the returned bits. 'big' will mimic bin(val), + ``3 = 0b00000011 => [0, 0, 0, 0, 0, 0, 1, 1]``, 'little' will reverse + the order to ``[1, 1, 0, 0, 0, 0, 0, 0]``. + Defaults to 'big'. + + .. versionadded:: 1.17.0 + + Returns + ------- + unpacked : ndarray, uint8 type + The elements are binary-valued (0 or 1). + + See Also + -------- + packbits : Packs the elements of a binary-valued array into bits in + a uint8 array. + + Examples + -------- + >>> a = np.array([[2], [7], [23]], dtype=np.uint8) + >>> a + array([[ 2], + [ 7], + [23]], dtype=uint8) + >>> b = np.unpackbits(a, axis=1) + >>> b + array([[0, 0, 0, 0, 0, 0, 1, 0], + [0, 0, 0, 0, 0, 1, 1, 1], + [0, 0, 0, 1, 0, 1, 1, 1]], dtype=uint8) + >>> c = np.unpackbits(a, axis=1, count=-3) + >>> c + array([[0, 0, 0, 0, 0], + [0, 0, 0, 0, 0], + [0, 0, 0, 1, 0]], dtype=uint8) + + >>> p = np.packbits(b, axis=0) + >>> np.unpackbits(p, axis=0) + array([[0, 0, 0, 0, 0, 0, 1, 0], + [0, 0, 0, 0, 0, 1, 1, 1], + [0, 0, 0, 1, 0, 1, 1, 1], + [0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0]], dtype=uint8) + >>> np.array_equal(b, np.unpackbits(p, axis=0, count=b.shape[0])) + True + + """ + return (a,) + + +@array_function_from_c_func_and_dispatcher(_multiarray_umath.shares_memory) +def shares_memory(a, b, max_work=None): + """ + shares_memory(a, b, max_work=None) + + Determine if two arrays share memory. + + .. warning:: + + This function can be exponentially slow for some inputs, unless + `max_work` is set to a finite number or ``MAY_SHARE_BOUNDS``. + If in doubt, use `numpy.may_share_memory` instead. + + Parameters + ---------- + a, b : ndarray + Input arrays + max_work : int, optional + Effort to spend on solving the overlap problem (maximum number + of candidate solutions to consider). The following special + values are recognized: + + max_work=MAY_SHARE_EXACT (default) + The problem is solved exactly. In this case, the function returns + True only if there is an element shared between the arrays. Finding + the exact solution may take extremely long in some cases. + max_work=MAY_SHARE_BOUNDS + Only the memory bounds of a and b are checked. + + Raises + ------ + numpy.TooHardError + Exceeded max_work. + + Returns + ------- + out : bool + + See Also + -------- + may_share_memory + + Examples + -------- + >>> x = np.array([1, 2, 3, 4]) + >>> np.shares_memory(x, np.array([5, 6, 7])) + False + >>> np.shares_memory(x[::2], x) + True + >>> np.shares_memory(x[::2], x[1::2]) + False + + Checking whether two arrays share memory is NP-complete, and + runtime may increase exponentially in the number of + dimensions. Hence, `max_work` should generally be set to a finite + number, as it is possible to construct examples that take + extremely long to run: + + >>> from numpy.lib.stride_tricks import as_strided + >>> x = np.zeros([192163377], dtype=np.int8) + >>> x1 = as_strided(x, strides=(36674, 61119, 85569), shape=(1049, 1049, 1049)) + >>> x2 = as_strided(x[64023025:], strides=(12223, 12224, 1), shape=(1049, 1049, 1)) + >>> np.shares_memory(x1, x2, max_work=1000) + Traceback (most recent call last): + ... + numpy.TooHardError: Exceeded max_work + + Running ``np.shares_memory(x1, x2)`` without `max_work` set takes + around 1 minute for this case. It is possible to find problems + that take still significantly longer. + + """ + return (a, b) + + +@array_function_from_c_func_and_dispatcher(_multiarray_umath.may_share_memory) +def may_share_memory(a, b, max_work=None): + """ + may_share_memory(a, b, max_work=None) + + Determine if two arrays might share memory + + A return of True does not necessarily mean that the two arrays + share any element. It just means that they *might*. + + Only the memory bounds of a and b are checked by default. + + Parameters + ---------- + a, b : ndarray + Input arrays + max_work : int, optional + Effort to spend on solving the overlap problem. See + `shares_memory` for details. Default for ``may_share_memory`` + is to do a bounds check. + + Returns + ------- + out : bool + + See Also + -------- + shares_memory + + Examples + -------- + >>> np.may_share_memory(np.array([1,2]), np.array([5,8,9])) + False + >>> x = np.zeros([3, 4]) + >>> np.may_share_memory(x[:,0], x[:,1]) + True + + """ + return (a, b) + + +@array_function_from_c_func_and_dispatcher(_multiarray_umath.is_busday) +def is_busday(dates, weekmask=None, holidays=None, busdaycal=None, out=None): + """ + is_busday(dates, weekmask='1111100', holidays=None, busdaycal=None, out=None) + + Calculates which of the given dates are valid days, and which are not. + + .. versionadded:: 1.7.0 + + Parameters + ---------- + dates : array_like of datetime64[D] + The array of dates to process. + weekmask : str or array_like of bool, optional + A seven-element array indicating which of Monday through Sunday are + valid days. May be specified as a length-seven list or array, like + [1,1,1,1,1,0,0]; a length-seven string, like '1111100'; or a string + like "Mon Tue Wed Thu Fri", made up of 3-character abbreviations for + weekdays, optionally separated by white space. Valid abbreviations + are: Mon Tue Wed Thu Fri Sat Sun + holidays : array_like of datetime64[D], optional + An array of dates to consider as invalid dates. They may be + specified in any order, and NaT (not-a-time) dates are ignored. + This list is saved in a normalized form that is suited for + fast calculations of valid days. + busdaycal : busdaycalendar, optional + A `busdaycalendar` object which specifies the valid days. If this + parameter is provided, neither weekmask nor holidays may be + provided. + out : array of bool, optional + If provided, this array is filled with the result. + + Returns + ------- + out : array of bool + An array with the same shape as ``dates``, containing True for + each valid day, and False for each invalid day. + + See Also + -------- + busdaycalendar: An object that specifies a custom set of valid days. + busday_offset : Applies an offset counted in valid days. + busday_count : Counts how many valid days are in a half-open date range. + + Examples + -------- + >>> # The weekdays are Friday, Saturday, and Monday + ... np.is_busday(['2011-07-01', '2011-07-02', '2011-07-18'], + ... holidays=['2011-07-01', '2011-07-04', '2011-07-17']) + array([False, False, True]) + """ + return (dates, weekmask, holidays, out) + + +@array_function_from_c_func_and_dispatcher(_multiarray_umath.busday_offset) +def busday_offset(dates, offsets, roll=None, weekmask=None, holidays=None, + busdaycal=None, out=None): + """ + busday_offset(dates, offsets, roll='raise', weekmask='1111100', holidays=None, busdaycal=None, out=None) + + First adjusts the date to fall on a valid day according to + the ``roll`` rule, then applies offsets to the given dates + counted in valid days. + + .. versionadded:: 1.7.0 + + Parameters + ---------- + dates : array_like of datetime64[D] + The array of dates to process. + offsets : array_like of int + The array of offsets, which is broadcast with ``dates``. + roll : {'raise', 'nat', 'forward', 'following', 'backward', 'preceding', 'modifiedfollowing', 'modifiedpreceding'}, optional + How to treat dates that do not fall on a valid day. The default + is 'raise'. + + * 'raise' means to raise an exception for an invalid day. + * 'nat' means to return a NaT (not-a-time) for an invalid day. + * 'forward' and 'following' mean to take the first valid day + later in time. + * 'backward' and 'preceding' mean to take the first valid day + earlier in time. + * 'modifiedfollowing' means to take the first valid day + later in time unless it is across a Month boundary, in which + case to take the first valid day earlier in time. + * 'modifiedpreceding' means to take the first valid day + earlier in time unless it is across a Month boundary, in which + case to take the first valid day later in time. + weekmask : str or array_like of bool, optional + A seven-element array indicating which of Monday through Sunday are + valid days. May be specified as a length-seven list or array, like + [1,1,1,1,1,0,0]; a length-seven string, like '1111100'; or a string + like "Mon Tue Wed Thu Fri", made up of 3-character abbreviations for + weekdays, optionally separated by white space. Valid abbreviations + are: Mon Tue Wed Thu Fri Sat Sun + holidays : array_like of datetime64[D], optional + An array of dates to consider as invalid dates. They may be + specified in any order, and NaT (not-a-time) dates are ignored. + This list is saved in a normalized form that is suited for + fast calculations of valid days. + busdaycal : busdaycalendar, optional + A `busdaycalendar` object which specifies the valid days. If this + parameter is provided, neither weekmask nor holidays may be + provided. + out : array of datetime64[D], optional + If provided, this array is filled with the result. + + Returns + ------- + out : array of datetime64[D] + An array with a shape from broadcasting ``dates`` and ``offsets`` + together, containing the dates with offsets applied. + + See Also + -------- + busdaycalendar: An object that specifies a custom set of valid days. + is_busday : Returns a boolean array indicating valid days. + busday_count : Counts how many valid days are in a half-open date range. + + Examples + -------- + >>> # First business day in October 2011 (not accounting for holidays) + ... np.busday_offset('2011-10', 0, roll='forward') + numpy.datetime64('2011-10-03') + >>> # Last business day in February 2012 (not accounting for holidays) + ... np.busday_offset('2012-03', -1, roll='forward') + numpy.datetime64('2012-02-29') + >>> # Third Wednesday in January 2011 + ... np.busday_offset('2011-01', 2, roll='forward', weekmask='Wed') + numpy.datetime64('2011-01-19') + >>> # 2012 Mother's Day in Canada and the U.S. + ... np.busday_offset('2012-05', 1, roll='forward', weekmask='Sun') + numpy.datetime64('2012-05-13') + + >>> # First business day on or after a date + ... np.busday_offset('2011-03-20', 0, roll='forward') + numpy.datetime64('2011-03-21') + >>> np.busday_offset('2011-03-22', 0, roll='forward') + numpy.datetime64('2011-03-22') + >>> # First business day after a date + ... np.busday_offset('2011-03-20', 1, roll='backward') + numpy.datetime64('2011-03-21') + >>> np.busday_offset('2011-03-22', 1, roll='backward') + numpy.datetime64('2011-03-23') + """ + return (dates, offsets, weekmask, holidays, out) + + +@array_function_from_c_func_and_dispatcher(_multiarray_umath.busday_count) +def busday_count(begindates, enddates, weekmask=None, holidays=None, + busdaycal=None, out=None): + """ + busday_count(begindates, enddates, weekmask='1111100', holidays=[], busdaycal=None, out=None) + + Counts the number of valid days between `begindates` and + `enddates`, not including the day of `enddates`. + + If ``enddates`` specifies a date value that is earlier than the + corresponding ``begindates`` date value, the count will be negative. + + .. versionadded:: 1.7.0 + + Parameters + ---------- + begindates : array_like of datetime64[D] + The array of the first dates for counting. + enddates : array_like of datetime64[D] + The array of the end dates for counting, which are excluded + from the count themselves. + weekmask : str or array_like of bool, optional + A seven-element array indicating which of Monday through Sunday are + valid days. May be specified as a length-seven list or array, like + [1,1,1,1,1,0,0]; a length-seven string, like '1111100'; or a string + like "Mon Tue Wed Thu Fri", made up of 3-character abbreviations for + weekdays, optionally separated by white space. Valid abbreviations + are: Mon Tue Wed Thu Fri Sat Sun + holidays : array_like of datetime64[D], optional + An array of dates to consider as invalid dates. They may be + specified in any order, and NaT (not-a-time) dates are ignored. + This list is saved in a normalized form that is suited for + fast calculations of valid days. + busdaycal : busdaycalendar, optional + A `busdaycalendar` object which specifies the valid days. If this + parameter is provided, neither weekmask nor holidays may be + provided. + out : array of int, optional + If provided, this array is filled with the result. + + Returns + ------- + out : array of int + An array with a shape from broadcasting ``begindates`` and ``enddates`` + together, containing the number of valid days between + the begin and end dates. + + See Also + -------- + busdaycalendar: An object that specifies a custom set of valid days. + is_busday : Returns a boolean array indicating valid days. + busday_offset : Applies an offset counted in valid days. + + Examples + -------- + >>> # Number of weekdays in January 2011 + ... np.busday_count('2011-01', '2011-02') + 21 + >>> # Number of weekdays in 2011 + >>> np.busday_count('2011', '2012') + 260 + >>> # Number of Saturdays in 2011 + ... np.busday_count('2011', '2012', weekmask='Sat') + 53 + """ + return (begindates, enddates, weekmask, holidays, out) + + +@array_function_from_c_func_and_dispatcher( + _multiarray_umath.datetime_as_string) +def datetime_as_string(arr, unit=None, timezone=None, casting=None): + """ + datetime_as_string(arr, unit=None, timezone='naive', casting='same_kind') + + Convert an array of datetimes into an array of strings. + + Parameters + ---------- + arr : array_like of datetime64 + The array of UTC timestamps to format. + unit : str + One of None, 'auto', or a :ref:`datetime unit `. + timezone : {'naive', 'UTC', 'local'} or tzinfo + Timezone information to use when displaying the datetime. If 'UTC', end + with a Z to indicate UTC time. If 'local', convert to the local timezone + first, and suffix with a +-#### timezone offset. If a tzinfo object, + then do as with 'local', but use the specified timezone. + casting : {'no', 'equiv', 'safe', 'same_kind', 'unsafe'} + Casting to allow when changing between datetime units. + + Returns + ------- + str_arr : ndarray + An array of strings the same shape as `arr`. + + Examples + -------- + >>> import pytz + >>> d = np.arange('2002-10-27T04:30', 4*60, 60, dtype='M8[m]') + >>> d + array(['2002-10-27T04:30', '2002-10-27T05:30', '2002-10-27T06:30', + '2002-10-27T07:30'], dtype='datetime64[m]') + + Setting the timezone to UTC shows the same information, but with a Z suffix + + >>> np.datetime_as_string(d, timezone='UTC') + array(['2002-10-27T04:30Z', '2002-10-27T05:30Z', '2002-10-27T06:30Z', + '2002-10-27T07:30Z'], dtype='>> np.datetime_as_string(d, timezone=pytz.timezone('US/Eastern')) + array(['2002-10-27T00:30-0400', '2002-10-27T01:30-0400', + '2002-10-27T01:30-0500', '2002-10-27T02:30-0500'], dtype='>> np.datetime_as_string(d, unit='h') + array(['2002-10-27T04', '2002-10-27T05', '2002-10-27T06', '2002-10-27T07'], + dtype='>> np.datetime_as_string(d, unit='s') + array(['2002-10-27T04:30:00', '2002-10-27T05:30:00', '2002-10-27T06:30:00', + '2002-10-27T07:30:00'], dtype='>> np.datetime_as_string(d, unit='h', casting='safe') + Traceback (most recent call last): + ... + TypeError: Cannot create a datetime string as units 'h' from a NumPy + datetime with units 'm' according to the rule 'safe' + """ + return (arr,) diff --git a/venv/Lib/site-packages/numpy/core/numeric.py b/venv/Lib/site-packages/numpy/core/numeric.py new file mode 100644 index 0000000..a726af5 --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/numeric.py @@ -0,0 +1,2544 @@ +import functools +import itertools +import operator +import sys +import warnings +import numbers + +import numpy as np +from . import multiarray +from .multiarray import ( + _fastCopyAndTranspose as fastCopyAndTranspose, ALLOW_THREADS, + BUFSIZE, CLIP, MAXDIMS, MAY_SHARE_BOUNDS, MAY_SHARE_EXACT, RAISE, + WRAP, arange, array, broadcast, can_cast, compare_chararrays, + concatenate, copyto, dot, dtype, empty, + empty_like, flatiter, frombuffer, fromfile, fromiter, fromstring, + inner, lexsort, matmul, may_share_memory, + min_scalar_type, ndarray, nditer, nested_iters, promote_types, + putmask, result_type, set_numeric_ops, shares_memory, vdot, where, + zeros, normalize_axis_index) + +from . import overrides +from . import umath +from . import shape_base +from .overrides import set_array_function_like_doc, set_module +from .umath import (multiply, invert, sin, PINF, NAN) +from . import numerictypes +from .numerictypes import longlong, intc, int_, float_, complex_, bool_ +from ._exceptions import TooHardError, AxisError +from ._asarray import asarray, asanyarray +from ._ufunc_config import errstate + +bitwise_not = invert +ufunc = type(sin) +newaxis = None + +array_function_dispatch = functools.partial( + overrides.array_function_dispatch, module='numpy') + + +__all__ = [ + 'newaxis', 'ndarray', 'flatiter', 'nditer', 'nested_iters', 'ufunc', + 'arange', 'array', 'zeros', 'count_nonzero', 'empty', 'broadcast', 'dtype', + 'fromstring', 'fromfile', 'frombuffer', 'where', + 'argwhere', 'copyto', 'concatenate', 'fastCopyAndTranspose', 'lexsort', + 'set_numeric_ops', 'can_cast', 'promote_types', 'min_scalar_type', + 'result_type', 'isfortran', 'empty_like', 'zeros_like', 'ones_like', + 'correlate', 'convolve', 'inner', 'dot', 'outer', 'vdot', 'roll', + 'rollaxis', 'moveaxis', 'cross', 'tensordot', 'little_endian', + 'fromiter', 'array_equal', 'array_equiv', 'indices', 'fromfunction', + 'isclose', 'isscalar', 'binary_repr', 'base_repr', 'ones', + 'identity', 'allclose', 'compare_chararrays', 'putmask', + 'flatnonzero', 'Inf', 'inf', 'infty', 'Infinity', 'nan', 'NaN', + 'False_', 'True_', 'bitwise_not', 'CLIP', 'RAISE', 'WRAP', 'MAXDIMS', + 'BUFSIZE', 'ALLOW_THREADS', 'ComplexWarning', 'full', 'full_like', + 'matmul', 'shares_memory', 'may_share_memory', 'MAY_SHARE_BOUNDS', + 'MAY_SHARE_EXACT', 'TooHardError', 'AxisError'] + + +@set_module('numpy') +class ComplexWarning(RuntimeWarning): + """ + The warning raised when casting a complex dtype to a real dtype. + + As implemented, casting a complex number to a real discards its imaginary + part, but this behavior may not be what the user actually wants. + + """ + pass + + +def _zeros_like_dispatcher(a, dtype=None, order=None, subok=None, shape=None): + return (a,) + + +@array_function_dispatch(_zeros_like_dispatcher) +def zeros_like(a, dtype=None, order='K', subok=True, shape=None): + """ + Return an array of zeros with the same shape and type as a given array. + + Parameters + ---------- + a : array_like + The shape and data-type of `a` define these same attributes of + the returned array. + dtype : data-type, optional + Overrides the data type of the result. + + .. versionadded:: 1.6.0 + order : {'C', 'F', 'A', or 'K'}, optional + Overrides the memory layout of the result. 'C' means C-order, + 'F' means F-order, 'A' means 'F' if `a` is Fortran contiguous, + 'C' otherwise. 'K' means match the layout of `a` as closely + as possible. + + .. versionadded:: 1.6.0 + subok : bool, optional. + If True, then the newly created array will use the sub-class + type of `a`, otherwise it will be a base-class array. Defaults + to True. + shape : int or sequence of ints, optional. + Overrides the shape of the result. If order='K' and the number of + dimensions is unchanged, will try to keep order, otherwise, + order='C' is implied. + + .. versionadded:: 1.17.0 + + Returns + ------- + out : ndarray + Array of zeros with the same shape and type as `a`. + + See Also + -------- + empty_like : Return an empty array with shape and type of input. + ones_like : Return an array of ones with shape and type of input. + full_like : Return a new array with shape of input filled with value. + zeros : Return a new array setting values to zero. + + Examples + -------- + >>> x = np.arange(6) + >>> x = x.reshape((2, 3)) + >>> x + array([[0, 1, 2], + [3, 4, 5]]) + >>> np.zeros_like(x) + array([[0, 0, 0], + [0, 0, 0]]) + + >>> y = np.arange(3, dtype=float) + >>> y + array([0., 1., 2.]) + >>> np.zeros_like(y) + array([0., 0., 0.]) + + """ + res = empty_like(a, dtype=dtype, order=order, subok=subok, shape=shape) + # needed instead of a 0 to get same result as zeros for for string dtypes + z = zeros(1, dtype=res.dtype) + multiarray.copyto(res, z, casting='unsafe') + return res + + +def _ones_dispatcher(shape, dtype=None, order=None, *, like=None): + return(like,) + + +@set_array_function_like_doc +@set_module('numpy') +def ones(shape, dtype=None, order='C', *, like=None): + """ + Return a new array of given shape and type, filled with ones. + + Parameters + ---------- + shape : int or sequence of ints + Shape of the new array, e.g., ``(2, 3)`` or ``2``. + dtype : data-type, optional + The desired data-type for the array, e.g., `numpy.int8`. Default is + `numpy.float64`. + order : {'C', 'F'}, optional, default: C + Whether to store multi-dimensional data in row-major + (C-style) or column-major (Fortran-style) order in + memory. + ${ARRAY_FUNCTION_LIKE} + + .. versionadded:: 1.20.0 + + Returns + ------- + out : ndarray + Array of ones with the given shape, dtype, and order. + + See Also + -------- + ones_like : Return an array of ones with shape and type of input. + empty : Return a new uninitialized array. + zeros : Return a new array setting values to zero. + full : Return a new array of given shape filled with value. + + + Examples + -------- + >>> np.ones(5) + array([1., 1., 1., 1., 1.]) + + >>> np.ones((5,), dtype=int) + array([1, 1, 1, 1, 1]) + + >>> np.ones((2, 1)) + array([[1.], + [1.]]) + + >>> s = (2,2) + >>> np.ones(s) + array([[1., 1.], + [1., 1.]]) + + """ + if like is not None: + return _ones_with_like(shape, dtype=dtype, order=order, like=like) + + a = empty(shape, dtype, order) + multiarray.copyto(a, 1, casting='unsafe') + return a + + +_ones_with_like = array_function_dispatch( + _ones_dispatcher +)(ones) + + +def _ones_like_dispatcher(a, dtype=None, order=None, subok=None, shape=None): + return (a,) + + +@array_function_dispatch(_ones_like_dispatcher) +def ones_like(a, dtype=None, order='K', subok=True, shape=None): + """ + Return an array of ones with the same shape and type as a given array. + + Parameters + ---------- + a : array_like + The shape and data-type of `a` define these same attributes of + the returned array. + dtype : data-type, optional + Overrides the data type of the result. + + .. versionadded:: 1.6.0 + order : {'C', 'F', 'A', or 'K'}, optional + Overrides the memory layout of the result. 'C' means C-order, + 'F' means F-order, 'A' means 'F' if `a` is Fortran contiguous, + 'C' otherwise. 'K' means match the layout of `a` as closely + as possible. + + .. versionadded:: 1.6.0 + subok : bool, optional. + If True, then the newly created array will use the sub-class + type of `a`, otherwise it will be a base-class array. Defaults + to True. + shape : int or sequence of ints, optional. + Overrides the shape of the result. If order='K' and the number of + dimensions is unchanged, will try to keep order, otherwise, + order='C' is implied. + + .. versionadded:: 1.17.0 + + Returns + ------- + out : ndarray + Array of ones with the same shape and type as `a`. + + See Also + -------- + empty_like : Return an empty array with shape and type of input. + zeros_like : Return an array of zeros with shape and type of input. + full_like : Return a new array with shape of input filled with value. + ones : Return a new array setting values to one. + + Examples + -------- + >>> x = np.arange(6) + >>> x = x.reshape((2, 3)) + >>> x + array([[0, 1, 2], + [3, 4, 5]]) + >>> np.ones_like(x) + array([[1, 1, 1], + [1, 1, 1]]) + + >>> y = np.arange(3, dtype=float) + >>> y + array([0., 1., 2.]) + >>> np.ones_like(y) + array([1., 1., 1.]) + + """ + res = empty_like(a, dtype=dtype, order=order, subok=subok, shape=shape) + multiarray.copyto(res, 1, casting='unsafe') + return res + + +def _full_dispatcher(shape, fill_value, dtype=None, order=None, *, like=None): + return(like,) + + +@set_array_function_like_doc +@set_module('numpy') +def full(shape, fill_value, dtype=None, order='C', *, like=None): + """ + Return a new array of given shape and type, filled with `fill_value`. + + Parameters + ---------- + shape : int or sequence of ints + Shape of the new array, e.g., ``(2, 3)`` or ``2``. + fill_value : scalar or array_like + Fill value. + dtype : data-type, optional + The desired data-type for the array The default, None, means + `np.array(fill_value).dtype`. + order : {'C', 'F'}, optional + Whether to store multidimensional data in C- or Fortran-contiguous + (row- or column-wise) order in memory. + ${ARRAY_FUNCTION_LIKE} + + .. versionadded:: 1.20.0 + + Returns + ------- + out : ndarray + Array of `fill_value` with the given shape, dtype, and order. + + See Also + -------- + full_like : Return a new array with shape of input filled with value. + empty : Return a new uninitialized array. + ones : Return a new array setting values to one. + zeros : Return a new array setting values to zero. + + Examples + -------- + >>> np.full((2, 2), np.inf) + array([[inf, inf], + [inf, inf]]) + >>> np.full((2, 2), 10) + array([[10, 10], + [10, 10]]) + + >>> np.full((2, 2), [1, 2]) + array([[1, 2], + [1, 2]]) + + """ + if like is not None: + return _full_with_like(shape, fill_value, dtype=dtype, order=order, like=like) + + if dtype is None: + fill_value = asarray(fill_value) + dtype = fill_value.dtype + a = empty(shape, dtype, order) + multiarray.copyto(a, fill_value, casting='unsafe') + return a + + +_full_with_like = array_function_dispatch( + _full_dispatcher +)(full) + + +def _full_like_dispatcher(a, fill_value, dtype=None, order=None, subok=None, shape=None): + return (a,) + + +@array_function_dispatch(_full_like_dispatcher) +def full_like(a, fill_value, dtype=None, order='K', subok=True, shape=None): + """ + Return a full array with the same shape and type as a given array. + + Parameters + ---------- + a : array_like + The shape and data-type of `a` define these same attributes of + the returned array. + fill_value : scalar + Fill value. + dtype : data-type, optional + Overrides the data type of the result. + order : {'C', 'F', 'A', or 'K'}, optional + Overrides the memory layout of the result. 'C' means C-order, + 'F' means F-order, 'A' means 'F' if `a` is Fortran contiguous, + 'C' otherwise. 'K' means match the layout of `a` as closely + as possible. + subok : bool, optional. + If True, then the newly created array will use the sub-class + type of `a`, otherwise it will be a base-class array. Defaults + to True. + shape : int or sequence of ints, optional. + Overrides the shape of the result. If order='K' and the number of + dimensions is unchanged, will try to keep order, otherwise, + order='C' is implied. + + .. versionadded:: 1.17.0 + + Returns + ------- + out : ndarray + Array of `fill_value` with the same shape and type as `a`. + + See Also + -------- + empty_like : Return an empty array with shape and type of input. + ones_like : Return an array of ones with shape and type of input. + zeros_like : Return an array of zeros with shape and type of input. + full : Return a new array of given shape filled with value. + + Examples + -------- + >>> x = np.arange(6, dtype=int) + >>> np.full_like(x, 1) + array([1, 1, 1, 1, 1, 1]) + >>> np.full_like(x, 0.1) + array([0, 0, 0, 0, 0, 0]) + >>> np.full_like(x, 0.1, dtype=np.double) + array([0.1, 0.1, 0.1, 0.1, 0.1, 0.1]) + >>> np.full_like(x, np.nan, dtype=np.double) + array([nan, nan, nan, nan, nan, nan]) + + >>> y = np.arange(6, dtype=np.double) + >>> np.full_like(y, 0.1) + array([0.1, 0.1, 0.1, 0.1, 0.1, 0.1]) + + """ + res = empty_like(a, dtype=dtype, order=order, subok=subok, shape=shape) + multiarray.copyto(res, fill_value, casting='unsafe') + return res + + +def _count_nonzero_dispatcher(a, axis=None, *, keepdims=None): + return (a,) + + +@array_function_dispatch(_count_nonzero_dispatcher) +def count_nonzero(a, axis=None, *, keepdims=False): + """ + Counts the number of non-zero values in the array ``a``. + + The word "non-zero" is in reference to the Python 2.x + built-in method ``__nonzero__()`` (renamed ``__bool__()`` + in Python 3.x) of Python objects that tests an object's + "truthfulness". For example, any number is considered + truthful if it is nonzero, whereas any string is considered + truthful if it is not the empty string. Thus, this function + (recursively) counts how many elements in ``a`` (and in + sub-arrays thereof) have their ``__nonzero__()`` or ``__bool__()`` + method evaluated to ``True``. + + Parameters + ---------- + a : array_like + The array for which to count non-zeros. + axis : int or tuple, optional + Axis or tuple of axes along which to count non-zeros. + Default is None, meaning that non-zeros will be counted + along a flattened version of ``a``. + + .. versionadded:: 1.12.0 + + keepdims : bool, optional + If this is set to True, the axes that are counted are left + in the result as dimensions with size one. With this option, + the result will broadcast correctly against the input array. + + .. versionadded:: 1.19.0 + + Returns + ------- + count : int or array of int + Number of non-zero values in the array along a given axis. + Otherwise, the total number of non-zero values in the array + is returned. + + See Also + -------- + nonzero : Return the coordinates of all the non-zero values. + + Examples + -------- + >>> np.count_nonzero(np.eye(4)) + 4 + >>> a = np.array([[0, 1, 7, 0], + ... [3, 0, 2, 19]]) + >>> np.count_nonzero(a) + 5 + >>> np.count_nonzero(a, axis=0) + array([1, 1, 2, 1]) + >>> np.count_nonzero(a, axis=1) + array([2, 3]) + >>> np.count_nonzero(a, axis=1, keepdims=True) + array([[2], + [3]]) + """ + if axis is None and not keepdims: + return multiarray.count_nonzero(a) + + a = asanyarray(a) + + # TODO: this works around .astype(bool) not working properly (gh-9847) + if np.issubdtype(a.dtype, np.character): + a_bool = a != a.dtype.type() + else: + a_bool = a.astype(np.bool_, copy=False) + + return a_bool.sum(axis=axis, dtype=np.intp, keepdims=keepdims) + + +@set_module('numpy') +def isfortran(a): + """ + Check if the array is Fortran contiguous but *not* C contiguous. + + This function is obsolete and, because of changes due to relaxed stride + checking, its return value for the same array may differ for versions + of NumPy >= 1.10.0 and previous versions. If you only want to check if an + array is Fortran contiguous use ``a.flags.f_contiguous`` instead. + + Parameters + ---------- + a : ndarray + Input array. + + Returns + ------- + isfortran : bool + Returns True if the array is Fortran contiguous but *not* C contiguous. + + + Examples + -------- + + np.array allows to specify whether the array is written in C-contiguous + order (last index varies the fastest), or FORTRAN-contiguous order in + memory (first index varies the fastest). + + >>> a = np.array([[1, 2, 3], [4, 5, 6]], order='C') + >>> a + array([[1, 2, 3], + [4, 5, 6]]) + >>> np.isfortran(a) + False + + >>> b = np.array([[1, 2, 3], [4, 5, 6]], order='F') + >>> b + array([[1, 2, 3], + [4, 5, 6]]) + >>> np.isfortran(b) + True + + + The transpose of a C-ordered array is a FORTRAN-ordered array. + + >>> a = np.array([[1, 2, 3], [4, 5, 6]], order='C') + >>> a + array([[1, 2, 3], + [4, 5, 6]]) + >>> np.isfortran(a) + False + >>> b = a.T + >>> b + array([[1, 4], + [2, 5], + [3, 6]]) + >>> np.isfortran(b) + True + + C-ordered arrays evaluate as False even if they are also FORTRAN-ordered. + + >>> np.isfortran(np.array([1, 2], order='F')) + False + + """ + return a.flags.fnc + + +def _argwhere_dispatcher(a): + return (a,) + + +@array_function_dispatch(_argwhere_dispatcher) +def argwhere(a): + """ + Find the indices of array elements that are non-zero, grouped by element. + + Parameters + ---------- + a : array_like + Input data. + + Returns + ------- + index_array : (N, a.ndim) ndarray + Indices of elements that are non-zero. Indices are grouped by element. + This array will have shape ``(N, a.ndim)`` where ``N`` is the number of + non-zero items. + + See Also + -------- + where, nonzero + + Notes + ----- + ``np.argwhere(a)`` is almost the same as ``np.transpose(np.nonzero(a))``, + but produces a result of the correct shape for a 0D array. + + The output of ``argwhere`` is not suitable for indexing arrays. + For this purpose use ``nonzero(a)`` instead. + + Examples + -------- + >>> x = np.arange(6).reshape(2,3) + >>> x + array([[0, 1, 2], + [3, 4, 5]]) + >>> np.argwhere(x>1) + array([[0, 2], + [1, 0], + [1, 1], + [1, 2]]) + + """ + # nonzero does not behave well on 0d, so promote to 1d + if np.ndim(a) == 0: + a = shape_base.atleast_1d(a) + # then remove the added dimension + return argwhere(a)[:,:0] + return transpose(nonzero(a)) + + +def _flatnonzero_dispatcher(a): + return (a,) + + +@array_function_dispatch(_flatnonzero_dispatcher) +def flatnonzero(a): + """ + Return indices that are non-zero in the flattened version of a. + + This is equivalent to np.nonzero(np.ravel(a))[0]. + + Parameters + ---------- + a : array_like + Input data. + + Returns + ------- + res : ndarray + Output array, containing the indices of the elements of `a.ravel()` + that are non-zero. + + See Also + -------- + nonzero : Return the indices of the non-zero elements of the input array. + ravel : Return a 1-D array containing the elements of the input array. + + Examples + -------- + >>> x = np.arange(-2, 3) + >>> x + array([-2, -1, 0, 1, 2]) + >>> np.flatnonzero(x) + array([0, 1, 3, 4]) + + Use the indices of the non-zero elements as an index array to extract + these elements: + + >>> x.ravel()[np.flatnonzero(x)] + array([-2, -1, 1, 2]) + + """ + return np.nonzero(np.ravel(a))[0] + + +_mode_from_name_dict = {'v': 0, + 's': 1, + 'f': 2} + + +def _mode_from_name(mode): + if isinstance(mode, str): + return _mode_from_name_dict[mode.lower()[0]] + return mode + + +def _correlate_dispatcher(a, v, mode=None): + return (a, v) + + +@array_function_dispatch(_correlate_dispatcher) +def correlate(a, v, mode='valid'): + """ + Cross-correlation of two 1-dimensional sequences. + + This function computes the correlation as generally defined in signal + processing texts:: + + c_{av}[k] = sum_n a[n+k] * conj(v[n]) + + with a and v sequences being zero-padded where necessary and conj being + the conjugate. + + Parameters + ---------- + a, v : array_like + Input sequences. + mode : {'valid', 'same', 'full'}, optional + Refer to the `convolve` docstring. Note that the default + is 'valid', unlike `convolve`, which uses 'full'. + old_behavior : bool + `old_behavior` was removed in NumPy 1.10. If you need the old + behavior, use `multiarray.correlate`. + + Returns + ------- + out : ndarray + Discrete cross-correlation of `a` and `v`. + + See Also + -------- + convolve : Discrete, linear convolution of two one-dimensional sequences. + multiarray.correlate : Old, no conjugate, version of correlate. + + Notes + ----- + The definition of correlation above is not unique and sometimes correlation + may be defined differently. Another common definition is:: + + c'_{av}[k] = sum_n a[n] conj(v[n+k]) + + which is related to ``c_{av}[k]`` by ``c'_{av}[k] = c_{av}[-k]``. + + Examples + -------- + >>> np.correlate([1, 2, 3], [0, 1, 0.5]) + array([3.5]) + >>> np.correlate([1, 2, 3], [0, 1, 0.5], "same") + array([2. , 3.5, 3. ]) + >>> np.correlate([1, 2, 3], [0, 1, 0.5], "full") + array([0.5, 2. , 3.5, 3. , 0. ]) + + Using complex sequences: + + >>> np.correlate([1+1j, 2, 3-1j], [0, 1, 0.5j], 'full') + array([ 0.5-0.5j, 1.0+0.j , 1.5-1.5j, 3.0-1.j , 0.0+0.j ]) + + Note that you get the time reversed, complex conjugated result + when the two input sequences change places, i.e., + ``c_{va}[k] = c^{*}_{av}[-k]``: + + >>> np.correlate([0, 1, 0.5j], [1+1j, 2, 3-1j], 'full') + array([ 0.0+0.j , 3.0+1.j , 1.5+1.5j, 1.0+0.j , 0.5+0.5j]) + + """ + mode = _mode_from_name(mode) + return multiarray.correlate2(a, v, mode) + + +def _convolve_dispatcher(a, v, mode=None): + return (a, v) + + +@array_function_dispatch(_convolve_dispatcher) +def convolve(a, v, mode='full'): + """ + Returns the discrete, linear convolution of two one-dimensional sequences. + + The convolution operator is often seen in signal processing, where it + models the effect of a linear time-invariant system on a signal [1]_. In + probability theory, the sum of two independent random variables is + distributed according to the convolution of their individual + distributions. + + If `v` is longer than `a`, the arrays are swapped before computation. + + Parameters + ---------- + a : (N,) array_like + First one-dimensional input array. + v : (M,) array_like + Second one-dimensional input array. + mode : {'full', 'valid', 'same'}, optional + 'full': + By default, mode is 'full'. This returns the convolution + at each point of overlap, with an output shape of (N+M-1,). At + the end-points of the convolution, the signals do not overlap + completely, and boundary effects may be seen. + + 'same': + Mode 'same' returns output of length ``max(M, N)``. Boundary + effects are still visible. + + 'valid': + Mode 'valid' returns output of length + ``max(M, N) - min(M, N) + 1``. The convolution product is only given + for points where the signals overlap completely. Values outside + the signal boundary have no effect. + + Returns + ------- + out : ndarray + Discrete, linear convolution of `a` and `v`. + + See Also + -------- + scipy.signal.fftconvolve : Convolve two arrays using the Fast Fourier + Transform. + scipy.linalg.toeplitz : Used to construct the convolution operator. + polymul : Polynomial multiplication. Same output as convolve, but also + accepts poly1d objects as input. + + Notes + ----- + The discrete convolution operation is defined as + + .. math:: (a * v)[n] = \\sum_{m = -\\infty}^{\\infty} a[m] v[n - m] + + It can be shown that a convolution :math:`x(t) * y(t)` in time/space + is equivalent to the multiplication :math:`X(f) Y(f)` in the Fourier + domain, after appropriate padding (padding is necessary to prevent + circular convolution). Since multiplication is more efficient (faster) + than convolution, the function `scipy.signal.fftconvolve` exploits the + FFT to calculate the convolution of large data-sets. + + References + ---------- + .. [1] Wikipedia, "Convolution", + https://en.wikipedia.org/wiki/Convolution + + Examples + -------- + Note how the convolution operator flips the second array + before "sliding" the two across one another: + + >>> np.convolve([1, 2, 3], [0, 1, 0.5]) + array([0. , 1. , 2.5, 4. , 1.5]) + + Only return the middle values of the convolution. + Contains boundary effects, where zeros are taken + into account: + + >>> np.convolve([1,2,3],[0,1,0.5], 'same') + array([1. , 2.5, 4. ]) + + The two arrays are of the same length, so there + is only one position where they completely overlap: + + >>> np.convolve([1,2,3],[0,1,0.5], 'valid') + array([2.5]) + + """ + a, v = array(a, copy=False, ndmin=1), array(v, copy=False, ndmin=1) + if (len(v) > len(a)): + a, v = v, a + if len(a) == 0: + raise ValueError('a cannot be empty') + if len(v) == 0: + raise ValueError('v cannot be empty') + mode = _mode_from_name(mode) + return multiarray.correlate(a, v[::-1], mode) + + +def _outer_dispatcher(a, b, out=None): + return (a, b, out) + + +@array_function_dispatch(_outer_dispatcher) +def outer(a, b, out=None): + """ + Compute the outer product of two vectors. + + Given two vectors, ``a = [a0, a1, ..., aM]`` and + ``b = [b0, b1, ..., bN]``, + the outer product [1]_ is:: + + [[a0*b0 a0*b1 ... a0*bN ] + [a1*b0 . + [ ... . + [aM*b0 aM*bN ]] + + Parameters + ---------- + a : (M,) array_like + First input vector. Input is flattened if + not already 1-dimensional. + b : (N,) array_like + Second input vector. Input is flattened if + not already 1-dimensional. + out : (M, N) ndarray, optional + A location where the result is stored + + .. versionadded:: 1.9.0 + + Returns + ------- + out : (M, N) ndarray + ``out[i, j] = a[i] * b[j]`` + + See also + -------- + inner + einsum : ``einsum('i,j->ij', a.ravel(), b.ravel())`` is the equivalent. + ufunc.outer : A generalization to dimensions other than 1D and other + operations. ``np.multiply.outer(a.ravel(), b.ravel())`` + is the equivalent. + tensordot : ``np.tensordot(a.ravel(), b.ravel(), axes=((), ()))`` + is the equivalent. + + References + ---------- + .. [1] : G. H. Golub and C. F. Van Loan, *Matrix Computations*, 3rd + ed., Baltimore, MD, Johns Hopkins University Press, 1996, + pg. 8. + + Examples + -------- + Make a (*very* coarse) grid for computing a Mandelbrot set: + + >>> rl = np.outer(np.ones((5,)), np.linspace(-2, 2, 5)) + >>> rl + array([[-2., -1., 0., 1., 2.], + [-2., -1., 0., 1., 2.], + [-2., -1., 0., 1., 2.], + [-2., -1., 0., 1., 2.], + [-2., -1., 0., 1., 2.]]) + >>> im = np.outer(1j*np.linspace(2, -2, 5), np.ones((5,))) + >>> im + array([[0.+2.j, 0.+2.j, 0.+2.j, 0.+2.j, 0.+2.j], + [0.+1.j, 0.+1.j, 0.+1.j, 0.+1.j, 0.+1.j], + [0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j], + [0.-1.j, 0.-1.j, 0.-1.j, 0.-1.j, 0.-1.j], + [0.-2.j, 0.-2.j, 0.-2.j, 0.-2.j, 0.-2.j]]) + >>> grid = rl + im + >>> grid + array([[-2.+2.j, -1.+2.j, 0.+2.j, 1.+2.j, 2.+2.j], + [-2.+1.j, -1.+1.j, 0.+1.j, 1.+1.j, 2.+1.j], + [-2.+0.j, -1.+0.j, 0.+0.j, 1.+0.j, 2.+0.j], + [-2.-1.j, -1.-1.j, 0.-1.j, 1.-1.j, 2.-1.j], + [-2.-2.j, -1.-2.j, 0.-2.j, 1.-2.j, 2.-2.j]]) + + An example using a "vector" of letters: + + >>> x = np.array(['a', 'b', 'c'], dtype=object) + >>> np.outer(x, [1, 2, 3]) + array([['a', 'aa', 'aaa'], + ['b', 'bb', 'bbb'], + ['c', 'cc', 'ccc']], dtype=object) + + """ + a = asarray(a) + b = asarray(b) + return multiply(a.ravel()[:, newaxis], b.ravel()[newaxis, :], out) + + +def _tensordot_dispatcher(a, b, axes=None): + return (a, b) + + +@array_function_dispatch(_tensordot_dispatcher) +def tensordot(a, b, axes=2): + """ + Compute tensor dot product along specified axes. + + Given two tensors, `a` and `b`, and an array_like object containing + two array_like objects, ``(a_axes, b_axes)``, sum the products of + `a`'s and `b`'s elements (components) over the axes specified by + ``a_axes`` and ``b_axes``. The third argument can be a single non-negative + integer_like scalar, ``N``; if it is such, then the last ``N`` dimensions + of `a` and the first ``N`` dimensions of `b` are summed over. + + Parameters + ---------- + a, b : array_like + Tensors to "dot". + + axes : int or (2,) array_like + * integer_like + If an int N, sum over the last N axes of `a` and the first N axes + of `b` in order. The sizes of the corresponding axes must match. + * (2,) array_like + Or, a list of axes to be summed over, first sequence applying to `a`, + second to `b`. Both elements array_like must be of the same length. + + Returns + ------- + output : ndarray + The tensor dot product of the input. + + See Also + -------- + dot, einsum + + Notes + ----- + Three common use cases are: + * ``axes = 0`` : tensor product :math:`a\\otimes b` + * ``axes = 1`` : tensor dot product :math:`a\\cdot b` + * ``axes = 2`` : (default) tensor double contraction :math:`a:b` + + When `axes` is integer_like, the sequence for evaluation will be: first + the -Nth axis in `a` and 0th axis in `b`, and the -1th axis in `a` and + Nth axis in `b` last. + + When there is more than one axis to sum over - and they are not the last + (first) axes of `a` (`b`) - the argument `axes` should consist of + two sequences of the same length, with the first axis to sum over given + first in both sequences, the second axis second, and so forth. + + The shape of the result consists of the non-contracted axes of the + first tensor, followed by the non-contracted axes of the second. + + Examples + -------- + A "traditional" example: + + >>> a = np.arange(60.).reshape(3,4,5) + >>> b = np.arange(24.).reshape(4,3,2) + >>> c = np.tensordot(a,b, axes=([1,0],[0,1])) + >>> c.shape + (5, 2) + >>> c + array([[4400., 4730.], + [4532., 4874.], + [4664., 5018.], + [4796., 5162.], + [4928., 5306.]]) + >>> # A slower but equivalent way of computing the same... + >>> d = np.zeros((5,2)) + >>> for i in range(5): + ... for j in range(2): + ... for k in range(3): + ... for n in range(4): + ... d[i,j] += a[k,n,i] * b[n,k,j] + >>> c == d + array([[ True, True], + [ True, True], + [ True, True], + [ True, True], + [ True, True]]) + + An extended example taking advantage of the overloading of + and \\*: + + >>> a = np.array(range(1, 9)) + >>> a.shape = (2, 2, 2) + >>> A = np.array(('a', 'b', 'c', 'd'), dtype=object) + >>> A.shape = (2, 2) + >>> a; A + array([[[1, 2], + [3, 4]], + [[5, 6], + [7, 8]]]) + array([['a', 'b'], + ['c', 'd']], dtype=object) + + >>> np.tensordot(a, A) # third argument default is 2 for double-contraction + array(['abbcccdddd', 'aaaaabbbbbbcccccccdddddddd'], dtype=object) + + >>> np.tensordot(a, A, 1) + array([[['acc', 'bdd'], + ['aaacccc', 'bbbdddd']], + [['aaaaacccccc', 'bbbbbdddddd'], + ['aaaaaaacccccccc', 'bbbbbbbdddddddd']]], dtype=object) + + >>> np.tensordot(a, A, 0) # tensor product (result too long to incl.) + array([[[[['a', 'b'], + ['c', 'd']], + ... + + >>> np.tensordot(a, A, (0, 1)) + array([[['abbbbb', 'cddddd'], + ['aabbbbbb', 'ccdddddd']], + [['aaabbbbbbb', 'cccddddddd'], + ['aaaabbbbbbbb', 'ccccdddddddd']]], dtype=object) + + >>> np.tensordot(a, A, (2, 1)) + array([[['abb', 'cdd'], + ['aaabbbb', 'cccdddd']], + [['aaaaabbbbbb', 'cccccdddddd'], + ['aaaaaaabbbbbbbb', 'cccccccdddddddd']]], dtype=object) + + >>> np.tensordot(a, A, ((0, 1), (0, 1))) + array(['abbbcccccddddddd', 'aabbbbccccccdddddddd'], dtype=object) + + >>> np.tensordot(a, A, ((2, 1), (1, 0))) + array(['acccbbdddd', 'aaaaacccccccbbbbbbdddddddd'], dtype=object) + + """ + try: + iter(axes) + except Exception: + axes_a = list(range(-axes, 0)) + axes_b = list(range(0, axes)) + else: + axes_a, axes_b = axes + try: + na = len(axes_a) + axes_a = list(axes_a) + except TypeError: + axes_a = [axes_a] + na = 1 + try: + nb = len(axes_b) + axes_b = list(axes_b) + except TypeError: + axes_b = [axes_b] + nb = 1 + + a, b = asarray(a), asarray(b) + as_ = a.shape + nda = a.ndim + bs = b.shape + ndb = b.ndim + equal = True + if na != nb: + equal = False + else: + for k in range(na): + if as_[axes_a[k]] != bs[axes_b[k]]: + equal = False + break + if axes_a[k] < 0: + axes_a[k] += nda + if axes_b[k] < 0: + axes_b[k] += ndb + if not equal: + raise ValueError("shape-mismatch for sum") + + # Move the axes to sum over to the end of "a" + # and to the front of "b" + notin = [k for k in range(nda) if k not in axes_a] + newaxes_a = notin + axes_a + N2 = 1 + for axis in axes_a: + N2 *= as_[axis] + newshape_a = (int(multiply.reduce([as_[ax] for ax in notin])), N2) + olda = [as_[axis] for axis in notin] + + notin = [k for k in range(ndb) if k not in axes_b] + newaxes_b = axes_b + notin + N2 = 1 + for axis in axes_b: + N2 *= bs[axis] + newshape_b = (N2, int(multiply.reduce([bs[ax] for ax in notin]))) + oldb = [bs[axis] for axis in notin] + + at = a.transpose(newaxes_a).reshape(newshape_a) + bt = b.transpose(newaxes_b).reshape(newshape_b) + res = dot(at, bt) + return res.reshape(olda + oldb) + + +def _roll_dispatcher(a, shift, axis=None): + return (a,) + + +@array_function_dispatch(_roll_dispatcher) +def roll(a, shift, axis=None): + """ + Roll array elements along a given axis. + + Elements that roll beyond the last position are re-introduced at + the first. + + Parameters + ---------- + a : array_like + Input array. + shift : int or tuple of ints + The number of places by which elements are shifted. If a tuple, + then `axis` must be a tuple of the same size, and each of the + given axes is shifted by the corresponding number. If an int + while `axis` is a tuple of ints, then the same value is used for + all given axes. + axis : int or tuple of ints, optional + Axis or axes along which elements are shifted. By default, the + array is flattened before shifting, after which the original + shape is restored. + + Returns + ------- + res : ndarray + Output array, with the same shape as `a`. + + See Also + -------- + rollaxis : Roll the specified axis backwards, until it lies in a + given position. + + Notes + ----- + .. versionadded:: 1.12.0 + + Supports rolling over multiple dimensions simultaneously. + + Examples + -------- + >>> x = np.arange(10) + >>> np.roll(x, 2) + array([8, 9, 0, 1, 2, 3, 4, 5, 6, 7]) + >>> np.roll(x, -2) + array([2, 3, 4, 5, 6, 7, 8, 9, 0, 1]) + + >>> x2 = np.reshape(x, (2,5)) + >>> x2 + array([[0, 1, 2, 3, 4], + [5, 6, 7, 8, 9]]) + >>> np.roll(x2, 1) + array([[9, 0, 1, 2, 3], + [4, 5, 6, 7, 8]]) + >>> np.roll(x2, -1) + array([[1, 2, 3, 4, 5], + [6, 7, 8, 9, 0]]) + >>> np.roll(x2, 1, axis=0) + array([[5, 6, 7, 8, 9], + [0, 1, 2, 3, 4]]) + >>> np.roll(x2, -1, axis=0) + array([[5, 6, 7, 8, 9], + [0, 1, 2, 3, 4]]) + >>> np.roll(x2, 1, axis=1) + array([[4, 0, 1, 2, 3], + [9, 5, 6, 7, 8]]) + >>> np.roll(x2, -1, axis=1) + array([[1, 2, 3, 4, 0], + [6, 7, 8, 9, 5]]) + + """ + a = asanyarray(a) + if axis is None: + return roll(a.ravel(), shift, 0).reshape(a.shape) + + else: + axis = normalize_axis_tuple(axis, a.ndim, allow_duplicate=True) + broadcasted = broadcast(shift, axis) + if broadcasted.ndim > 1: + raise ValueError( + "'shift' and 'axis' should be scalars or 1D sequences") + shifts = {ax: 0 for ax in range(a.ndim)} + for sh, ax in broadcasted: + shifts[ax] += sh + + rolls = [((slice(None), slice(None)),)] * a.ndim + for ax, offset in shifts.items(): + offset %= a.shape[ax] or 1 # If `a` is empty, nothing matters. + if offset: + # (original, result), (original, result) + rolls[ax] = ((slice(None, -offset), slice(offset, None)), + (slice(-offset, None), slice(None, offset))) + + result = empty_like(a) + for indices in itertools.product(*rolls): + arr_index, res_index = zip(*indices) + result[res_index] = a[arr_index] + + return result + + +def _rollaxis_dispatcher(a, axis, start=None): + return (a,) + + +@array_function_dispatch(_rollaxis_dispatcher) +def rollaxis(a, axis, start=0): + """ + Roll the specified axis backwards, until it lies in a given position. + + This function continues to be supported for backward compatibility, but you + should prefer `moveaxis`. The `moveaxis` function was added in NumPy + 1.11. + + Parameters + ---------- + a : ndarray + Input array. + axis : int + The axis to be rolled. The positions of the other axes do not + change relative to one another. + start : int, optional + When ``start <= axis``, the axis is rolled back until it lies in + this position. When ``start > axis``, the axis is rolled until it + lies before this position. The default, 0, results in a "complete" + roll. The following table describes how negative values of ``start`` + are interpreted: + + .. table:: + :align: left + + +-------------------+----------------------+ + | ``start`` | Normalized ``start`` | + +===================+======================+ + | ``-(arr.ndim+1)`` | raise ``AxisError`` | + +-------------------+----------------------+ + | ``-arr.ndim`` | 0 | + +-------------------+----------------------+ + | |vdots| | |vdots| | + +-------------------+----------------------+ + | ``-1`` | ``arr.ndim-1`` | + +-------------------+----------------------+ + | ``0`` | ``0`` | + +-------------------+----------------------+ + | |vdots| | |vdots| | + +-------------------+----------------------+ + | ``arr.ndim`` | ``arr.ndim`` | + +-------------------+----------------------+ + | ``arr.ndim + 1`` | raise ``AxisError`` | + +-------------------+----------------------+ + + .. |vdots| unicode:: U+22EE .. Vertical Ellipsis + + Returns + ------- + res : ndarray + For NumPy >= 1.10.0 a view of `a` is always returned. For earlier + NumPy versions a view of `a` is returned only if the order of the + axes is changed, otherwise the input array is returned. + + See Also + -------- + moveaxis : Move array axes to new positions. + roll : Roll the elements of an array by a number of positions along a + given axis. + + Examples + -------- + >>> a = np.ones((3,4,5,6)) + >>> np.rollaxis(a, 3, 1).shape + (3, 6, 4, 5) + >>> np.rollaxis(a, 2).shape + (5, 3, 4, 6) + >>> np.rollaxis(a, 1, 4).shape + (3, 5, 6, 4) + + """ + n = a.ndim + axis = normalize_axis_index(axis, n) + if start < 0: + start += n + msg = "'%s' arg requires %d <= %s < %d, but %d was passed in" + if not (0 <= start < n + 1): + raise AxisError(msg % ('start', -n, 'start', n + 1, start)) + if axis < start: + # it's been removed + start -= 1 + if axis == start: + return a[...] + axes = list(range(0, n)) + axes.remove(axis) + axes.insert(start, axis) + return a.transpose(axes) + + +def normalize_axis_tuple(axis, ndim, argname=None, allow_duplicate=False): + """ + Normalizes an axis argument into a tuple of non-negative integer axes. + + This handles shorthands such as ``1`` and converts them to ``(1,)``, + as well as performing the handling of negative indices covered by + `normalize_axis_index`. + + By default, this forbids axes from being specified multiple times. + + Used internally by multi-axis-checking logic. + + .. versionadded:: 1.13.0 + + Parameters + ---------- + axis : int, iterable of int + The un-normalized index or indices of the axis. + ndim : int + The number of dimensions of the array that `axis` should be normalized + against. + argname : str, optional + A prefix to put before the error message, typically the name of the + argument. + allow_duplicate : bool, optional + If False, the default, disallow an axis from being specified twice. + + Returns + ------- + normalized_axes : tuple of int + The normalized axis index, such that `0 <= normalized_axis < ndim` + + Raises + ------ + AxisError + If any axis provided is out of range + ValueError + If an axis is repeated + + See also + -------- + normalize_axis_index : normalizing a single scalar axis + """ + # Optimization to speed-up the most common cases. + if type(axis) not in (tuple, list): + try: + axis = [operator.index(axis)] + except TypeError: + pass + # Going via an iterator directly is slower than via list comprehension. + axis = tuple([normalize_axis_index(ax, ndim, argname) for ax in axis]) + if not allow_duplicate and len(set(axis)) != len(axis): + if argname: + raise ValueError('repeated axis in `{}` argument'.format(argname)) + else: + raise ValueError('repeated axis') + return axis + + +def _moveaxis_dispatcher(a, source, destination): + return (a,) + + +@array_function_dispatch(_moveaxis_dispatcher) +def moveaxis(a, source, destination): + """ + Move axes of an array to new positions. + + Other axes remain in their original order. + + .. versionadded:: 1.11.0 + + Parameters + ---------- + a : np.ndarray + The array whose axes should be reordered. + source : int or sequence of int + Original positions of the axes to move. These must be unique. + destination : int or sequence of int + Destination positions for each of the original axes. These must also be + unique. + + Returns + ------- + result : np.ndarray + Array with moved axes. This array is a view of the input array. + + See Also + -------- + transpose: Permute the dimensions of an array. + swapaxes: Interchange two axes of an array. + + Examples + -------- + + >>> x = np.zeros((3, 4, 5)) + >>> np.moveaxis(x, 0, -1).shape + (4, 5, 3) + >>> np.moveaxis(x, -1, 0).shape + (5, 3, 4) + + These all achieve the same result: + + >>> np.transpose(x).shape + (5, 4, 3) + >>> np.swapaxes(x, 0, -1).shape + (5, 4, 3) + >>> np.moveaxis(x, [0, 1], [-1, -2]).shape + (5, 4, 3) + >>> np.moveaxis(x, [0, 1, 2], [-1, -2, -3]).shape + (5, 4, 3) + + """ + try: + # allow duck-array types if they define transpose + transpose = a.transpose + except AttributeError: + a = asarray(a) + transpose = a.transpose + + source = normalize_axis_tuple(source, a.ndim, 'source') + destination = normalize_axis_tuple(destination, a.ndim, 'destination') + if len(source) != len(destination): + raise ValueError('`source` and `destination` arguments must have ' + 'the same number of elements') + + order = [n for n in range(a.ndim) if n not in source] + + for dest, src in sorted(zip(destination, source)): + order.insert(dest, src) + + result = transpose(order) + return result + + +# fix hack in scipy which imports this function +def _move_axis_to_0(a, axis): + return moveaxis(a, axis, 0) + + +def _cross_dispatcher(a, b, axisa=None, axisb=None, axisc=None, axis=None): + return (a, b) + + +@array_function_dispatch(_cross_dispatcher) +def cross(a, b, axisa=-1, axisb=-1, axisc=-1, axis=None): + """ + Return the cross product of two (arrays of) vectors. + + The cross product of `a` and `b` in :math:`R^3` is a vector perpendicular + to both `a` and `b`. If `a` and `b` are arrays of vectors, the vectors + are defined by the last axis of `a` and `b` by default, and these axes + can have dimensions 2 or 3. Where the dimension of either `a` or `b` is + 2, the third component of the input vector is assumed to be zero and the + cross product calculated accordingly. In cases where both input vectors + have dimension 2, the z-component of the cross product is returned. + + Parameters + ---------- + a : array_like + Components of the first vector(s). + b : array_like + Components of the second vector(s). + axisa : int, optional + Axis of `a` that defines the vector(s). By default, the last axis. + axisb : int, optional + Axis of `b` that defines the vector(s). By default, the last axis. + axisc : int, optional + Axis of `c` containing the cross product vector(s). Ignored if + both input vectors have dimension 2, as the return is scalar. + By default, the last axis. + axis : int, optional + If defined, the axis of `a`, `b` and `c` that defines the vector(s) + and cross product(s). Overrides `axisa`, `axisb` and `axisc`. + + Returns + ------- + c : ndarray + Vector cross product(s). + + Raises + ------ + ValueError + When the dimension of the vector(s) in `a` and/or `b` does not + equal 2 or 3. + + See Also + -------- + inner : Inner product + outer : Outer product. + ix_ : Construct index arrays. + + Notes + ----- + .. versionadded:: 1.9.0 + + Supports full broadcasting of the inputs. + + Examples + -------- + Vector cross-product. + + >>> x = [1, 2, 3] + >>> y = [4, 5, 6] + >>> np.cross(x, y) + array([-3, 6, -3]) + + One vector with dimension 2. + + >>> x = [1, 2] + >>> y = [4, 5, 6] + >>> np.cross(x, y) + array([12, -6, -3]) + + Equivalently: + + >>> x = [1, 2, 0] + >>> y = [4, 5, 6] + >>> np.cross(x, y) + array([12, -6, -3]) + + Both vectors with dimension 2. + + >>> x = [1,2] + >>> y = [4,5] + >>> np.cross(x, y) + array(-3) + + Multiple vector cross-products. Note that the direction of the cross + product vector is defined by the `right-hand rule`. + + >>> x = np.array([[1,2,3], [4,5,6]]) + >>> y = np.array([[4,5,6], [1,2,3]]) + >>> np.cross(x, y) + array([[-3, 6, -3], + [ 3, -6, 3]]) + + The orientation of `c` can be changed using the `axisc` keyword. + + >>> np.cross(x, y, axisc=0) + array([[-3, 3], + [ 6, -6], + [-3, 3]]) + + Change the vector definition of `x` and `y` using `axisa` and `axisb`. + + >>> x = np.array([[1,2,3], [4,5,6], [7, 8, 9]]) + >>> y = np.array([[7, 8, 9], [4,5,6], [1,2,3]]) + >>> np.cross(x, y) + array([[ -6, 12, -6], + [ 0, 0, 0], + [ 6, -12, 6]]) + >>> np.cross(x, y, axisa=0, axisb=0) + array([[-24, 48, -24], + [-30, 60, -30], + [-36, 72, -36]]) + + """ + if axis is not None: + axisa, axisb, axisc = (axis,) * 3 + a = asarray(a) + b = asarray(b) + # Check axisa and axisb are within bounds + axisa = normalize_axis_index(axisa, a.ndim, msg_prefix='axisa') + axisb = normalize_axis_index(axisb, b.ndim, msg_prefix='axisb') + + # Move working axis to the end of the shape + a = moveaxis(a, axisa, -1) + b = moveaxis(b, axisb, -1) + msg = ("incompatible dimensions for cross product\n" + "(dimension must be 2 or 3)") + if a.shape[-1] not in (2, 3) or b.shape[-1] not in (2, 3): + raise ValueError(msg) + + # Create the output array + shape = broadcast(a[..., 0], b[..., 0]).shape + if a.shape[-1] == 3 or b.shape[-1] == 3: + shape += (3,) + # Check axisc is within bounds + axisc = normalize_axis_index(axisc, len(shape), msg_prefix='axisc') + dtype = promote_types(a.dtype, b.dtype) + cp = empty(shape, dtype) + + # create local aliases for readability + a0 = a[..., 0] + a1 = a[..., 1] + if a.shape[-1] == 3: + a2 = a[..., 2] + b0 = b[..., 0] + b1 = b[..., 1] + if b.shape[-1] == 3: + b2 = b[..., 2] + if cp.ndim != 0 and cp.shape[-1] == 3: + cp0 = cp[..., 0] + cp1 = cp[..., 1] + cp2 = cp[..., 2] + + if a.shape[-1] == 2: + if b.shape[-1] == 2: + # a0 * b1 - a1 * b0 + multiply(a0, b1, out=cp) + cp -= a1 * b0 + return cp + else: + assert b.shape[-1] == 3 + # cp0 = a1 * b2 - 0 (a2 = 0) + # cp1 = 0 - a0 * b2 (a2 = 0) + # cp2 = a0 * b1 - a1 * b0 + multiply(a1, b2, out=cp0) + multiply(a0, b2, out=cp1) + negative(cp1, out=cp1) + multiply(a0, b1, out=cp2) + cp2 -= a1 * b0 + else: + assert a.shape[-1] == 3 + if b.shape[-1] == 3: + # cp0 = a1 * b2 - a2 * b1 + # cp1 = a2 * b0 - a0 * b2 + # cp2 = a0 * b1 - a1 * b0 + multiply(a1, b2, out=cp0) + tmp = array(a2 * b1) + cp0 -= tmp + multiply(a2, b0, out=cp1) + multiply(a0, b2, out=tmp) + cp1 -= tmp + multiply(a0, b1, out=cp2) + multiply(a1, b0, out=tmp) + cp2 -= tmp + else: + assert b.shape[-1] == 2 + # cp0 = 0 - a2 * b1 (b2 = 0) + # cp1 = a2 * b0 - 0 (b2 = 0) + # cp2 = a0 * b1 - a1 * b0 + multiply(a2, b1, out=cp0) + negative(cp0, out=cp0) + multiply(a2, b0, out=cp1) + multiply(a0, b1, out=cp2) + cp2 -= a1 * b0 + + return moveaxis(cp, -1, axisc) + + +little_endian = (sys.byteorder == 'little') + + +@set_module('numpy') +def indices(dimensions, dtype=int, sparse=False): + """ + Return an array representing the indices of a grid. + + Compute an array where the subarrays contain index values 0, 1, ... + varying only along the corresponding axis. + + Parameters + ---------- + dimensions : sequence of ints + The shape of the grid. + dtype : dtype, optional + Data type of the result. + sparse : boolean, optional + Return a sparse representation of the grid instead of a dense + representation. Default is False. + + .. versionadded:: 1.17 + + Returns + ------- + grid : one ndarray or tuple of ndarrays + If sparse is False: + Returns one array of grid indices, + ``grid.shape = (len(dimensions),) + tuple(dimensions)``. + If sparse is True: + Returns a tuple of arrays, with + ``grid[i].shape = (1, ..., 1, dimensions[i], 1, ..., 1)`` with + dimensions[i] in the ith place + + See Also + -------- + mgrid, ogrid, meshgrid + + Notes + ----- + The output shape in the dense case is obtained by prepending the number + of dimensions in front of the tuple of dimensions, i.e. if `dimensions` + is a tuple ``(r0, ..., rN-1)`` of length ``N``, the output shape is + ``(N, r0, ..., rN-1)``. + + The subarrays ``grid[k]`` contains the N-D array of indices along the + ``k-th`` axis. Explicitly:: + + grid[k, i0, i1, ..., iN-1] = ik + + Examples + -------- + >>> grid = np.indices((2, 3)) + >>> grid.shape + (2, 2, 3) + >>> grid[0] # row indices + array([[0, 0, 0], + [1, 1, 1]]) + >>> grid[1] # column indices + array([[0, 1, 2], + [0, 1, 2]]) + + The indices can be used as an index into an array. + + >>> x = np.arange(20).reshape(5, 4) + >>> row, col = np.indices((2, 3)) + >>> x[row, col] + array([[0, 1, 2], + [4, 5, 6]]) + + Note that it would be more straightforward in the above example to + extract the required elements directly with ``x[:2, :3]``. + + If sparse is set to true, the grid will be returned in a sparse + representation. + + >>> i, j = np.indices((2, 3), sparse=True) + >>> i.shape + (2, 1) + >>> j.shape + (1, 3) + >>> i # row indices + array([[0], + [1]]) + >>> j # column indices + array([[0, 1, 2]]) + + """ + dimensions = tuple(dimensions) + N = len(dimensions) + shape = (1,)*N + if sparse: + res = tuple() + else: + res = empty((N,)+dimensions, dtype=dtype) + for i, dim in enumerate(dimensions): + idx = arange(dim, dtype=dtype).reshape( + shape[:i] + (dim,) + shape[i+1:] + ) + if sparse: + res = res + (idx,) + else: + res[i] = idx + return res + + +def _fromfunction_dispatcher(function, shape, *, dtype=None, like=None, **kwargs): + return (like,) + + +@set_array_function_like_doc +@set_module('numpy') +def fromfunction(function, shape, *, dtype=float, like=None, **kwargs): + """ + Construct an array by executing a function over each coordinate. + + The resulting array therefore has a value ``fn(x, y, z)`` at + coordinate ``(x, y, z)``. + + Parameters + ---------- + function : callable + The function is called with N parameters, where N is the rank of + `shape`. Each parameter represents the coordinates of the array + varying along a specific axis. For example, if `shape` + were ``(2, 2)``, then the parameters would be + ``array([[0, 0], [1, 1]])`` and ``array([[0, 1], [0, 1]])`` + shape : (N,) tuple of ints + Shape of the output array, which also determines the shape of + the coordinate arrays passed to `function`. + dtype : data-type, optional + Data-type of the coordinate arrays passed to `function`. + By default, `dtype` is float. + ${ARRAY_FUNCTION_LIKE} + + .. versionadded:: 1.20.0 + + Returns + ------- + fromfunction : any + The result of the call to `function` is passed back directly. + Therefore the shape of `fromfunction` is completely determined by + `function`. If `function` returns a scalar value, the shape of + `fromfunction` would not match the `shape` parameter. + + See Also + -------- + indices, meshgrid + + Notes + ----- + Keywords other than `dtype` are passed to `function`. + + Examples + -------- + >>> np.fromfunction(lambda i, j: i == j, (3, 3), dtype=int) + array([[ True, False, False], + [False, True, False], + [False, False, True]]) + + >>> np.fromfunction(lambda i, j: i + j, (3, 3), dtype=int) + array([[0, 1, 2], + [1, 2, 3], + [2, 3, 4]]) + + """ + if like is not None: + return _fromfunction_with_like(function, shape, dtype=dtype, like=like, **kwargs) + + args = indices(shape, dtype=dtype) + return function(*args, **kwargs) + + +_fromfunction_with_like = array_function_dispatch( + _fromfunction_dispatcher +)(fromfunction) + + +def _frombuffer(buf, dtype, shape, order): + return frombuffer(buf, dtype=dtype).reshape(shape, order=order) + + +@set_module('numpy') +def isscalar(element): + """ + Returns True if the type of `element` is a scalar type. + + Parameters + ---------- + element : any + Input argument, can be of any type and shape. + + Returns + ------- + val : bool + True if `element` is a scalar type, False if it is not. + + See Also + -------- + ndim : Get the number of dimensions of an array + + Notes + ----- + If you need a stricter way to identify a *numerical* scalar, use + ``isinstance(x, numbers.Number)``, as that returns ``False`` for most + non-numerical elements such as strings. + + In most cases ``np.ndim(x) == 0`` should be used instead of this function, + as that will also return true for 0d arrays. This is how numpy overloads + functions in the style of the ``dx`` arguments to `gradient` and the ``bins`` + argument to `histogram`. Some key differences: + + +--------------------------------------+---------------+-------------------+ + | x |``isscalar(x)``|``np.ndim(x) == 0``| + +======================================+===============+===================+ + | PEP 3141 numeric objects (including | ``True`` | ``True`` | + | builtins) | | | + +--------------------------------------+---------------+-------------------+ + | builtin string and buffer objects | ``True`` | ``True`` | + +--------------------------------------+---------------+-------------------+ + | other builtin objects, like | ``False`` | ``True`` | + | `pathlib.Path`, `Exception`, | | | + | the result of `re.compile` | | | + +--------------------------------------+---------------+-------------------+ + | third-party objects like | ``False`` | ``True`` | + | `matplotlib.figure.Figure` | | | + +--------------------------------------+---------------+-------------------+ + | zero-dimensional numpy arrays | ``False`` | ``True`` | + +--------------------------------------+---------------+-------------------+ + | other numpy arrays | ``False`` | ``False`` | + +--------------------------------------+---------------+-------------------+ + | `list`, `tuple`, and other sequence | ``False`` | ``False`` | + | objects | | | + +--------------------------------------+---------------+-------------------+ + + Examples + -------- + >>> np.isscalar(3.1) + True + >>> np.isscalar(np.array(3.1)) + False + >>> np.isscalar([3.1]) + False + >>> np.isscalar(False) + True + >>> np.isscalar('numpy') + True + + NumPy supports PEP 3141 numbers: + + >>> from fractions import Fraction + >>> np.isscalar(Fraction(5, 17)) + True + >>> from numbers import Number + >>> np.isscalar(Number()) + True + + """ + return (isinstance(element, generic) + or type(element) in ScalarType + or isinstance(element, numbers.Number)) + + +@set_module('numpy') +def binary_repr(num, width=None): + """ + Return the binary representation of the input number as a string. + + For negative numbers, if width is not given, a minus sign is added to the + front. If width is given, the two's complement of the number is + returned, with respect to that width. + + In a two's-complement system negative numbers are represented by the two's + complement of the absolute value. This is the most common method of + representing signed integers on computers [1]_. A N-bit two's-complement + system can represent every integer in the range + :math:`-2^{N-1}` to :math:`+2^{N-1}-1`. + + Parameters + ---------- + num : int + Only an integer decimal number can be used. + width : int, optional + The length of the returned string if `num` is positive, or the length + of the two's complement if `num` is negative, provided that `width` is + at least a sufficient number of bits for `num` to be represented in the + designated form. + + If the `width` value is insufficient, it will be ignored, and `num` will + be returned in binary (`num` > 0) or two's complement (`num` < 0) form + with its width equal to the minimum number of bits needed to represent + the number in the designated form. This behavior is deprecated and will + later raise an error. + + .. deprecated:: 1.12.0 + + Returns + ------- + bin : str + Binary representation of `num` or two's complement of `num`. + + See Also + -------- + base_repr: Return a string representation of a number in the given base + system. + bin: Python's built-in binary representation generator of an integer. + + Notes + ----- + `binary_repr` is equivalent to using `base_repr` with base 2, but about 25x + faster. + + References + ---------- + .. [1] Wikipedia, "Two's complement", + https://en.wikipedia.org/wiki/Two's_complement + + Examples + -------- + >>> np.binary_repr(3) + '11' + >>> np.binary_repr(-3) + '-11' + >>> np.binary_repr(3, width=4) + '0011' + + The two's complement is returned when the input number is negative and + width is specified: + + >>> np.binary_repr(-3, width=3) + '101' + >>> np.binary_repr(-3, width=5) + '11101' + + """ + def warn_if_insufficient(width, binwidth): + if width is not None and width < binwidth: + warnings.warn( + "Insufficient bit width provided. This behavior " + "will raise an error in the future.", DeprecationWarning, + stacklevel=3) + + # Ensure that num is a Python integer to avoid overflow or unwanted + # casts to floating point. + num = operator.index(num) + + if num == 0: + return '0' * (width or 1) + + elif num > 0: + binary = bin(num)[2:] + binwidth = len(binary) + outwidth = (binwidth if width is None + else max(binwidth, width)) + warn_if_insufficient(width, binwidth) + return binary.zfill(outwidth) + + else: + if width is None: + return '-' + bin(-num)[2:] + + else: + poswidth = len(bin(-num)[2:]) + + # See gh-8679: remove extra digit + # for numbers at boundaries. + if 2**(poswidth - 1) == -num: + poswidth -= 1 + + twocomp = 2**(poswidth + 1) + num + binary = bin(twocomp)[2:] + binwidth = len(binary) + + outwidth = max(binwidth, width) + warn_if_insufficient(width, binwidth) + return '1' * (outwidth - binwidth) + binary + + +@set_module('numpy') +def base_repr(number, base=2, padding=0): + """ + Return a string representation of a number in the given base system. + + Parameters + ---------- + number : int + The value to convert. Positive and negative values are handled. + base : int, optional + Convert `number` to the `base` number system. The valid range is 2-36, + the default value is 2. + padding : int, optional + Number of zeros padded on the left. Default is 0 (no padding). + + Returns + ------- + out : str + String representation of `number` in `base` system. + + See Also + -------- + binary_repr : Faster version of `base_repr` for base 2. + + Examples + -------- + >>> np.base_repr(5) + '101' + >>> np.base_repr(6, 5) + '11' + >>> np.base_repr(7, base=5, padding=3) + '00012' + + >>> np.base_repr(10, base=16) + 'A' + >>> np.base_repr(32, base=16) + '20' + + """ + digits = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ' + if base > len(digits): + raise ValueError("Bases greater than 36 not handled in base_repr.") + elif base < 2: + raise ValueError("Bases less than 2 not handled in base_repr.") + + num = abs(number) + res = [] + while num: + res.append(digits[num % base]) + num //= base + if padding: + res.append('0' * padding) + if number < 0: + res.append('-') + return ''.join(reversed(res or '0')) + + +# These are all essentially abbreviations +# These might wind up in a special abbreviations module + + +def _maketup(descr, val): + dt = dtype(descr) + # Place val in all scalar tuples: + fields = dt.fields + if fields is None: + return val + else: + res = [_maketup(fields[name][0], val) for name in dt.names] + return tuple(res) + + +def _identity_dispatcher(n, dtype=None, *, like=None): + return (like,) + + +@set_array_function_like_doc +@set_module('numpy') +def identity(n, dtype=None, *, like=None): + """ + Return the identity array. + + The identity array is a square array with ones on + the main diagonal. + + Parameters + ---------- + n : int + Number of rows (and columns) in `n` x `n` output. + dtype : data-type, optional + Data-type of the output. Defaults to ``float``. + ${ARRAY_FUNCTION_LIKE} + + .. versionadded:: 1.20.0 + + Returns + ------- + out : ndarray + `n` x `n` array with its main diagonal set to one, + and all other elements 0. + + Examples + -------- + >>> np.identity(3) + array([[1., 0., 0.], + [0., 1., 0.], + [0., 0., 1.]]) + + """ + if like is not None: + return _identity_with_like(n, dtype=dtype, like=like) + + from numpy import eye + return eye(n, dtype=dtype, like=like) + + +_identity_with_like = array_function_dispatch( + _identity_dispatcher +)(identity) + + +def _allclose_dispatcher(a, b, rtol=None, atol=None, equal_nan=None): + return (a, b) + + +@array_function_dispatch(_allclose_dispatcher) +def allclose(a, b, rtol=1.e-5, atol=1.e-8, equal_nan=False): + """ + Returns True if two arrays are element-wise equal within a tolerance. + + The tolerance values are positive, typically very small numbers. The + relative difference (`rtol` * abs(`b`)) and the absolute difference + `atol` are added together to compare against the absolute difference + between `a` and `b`. + + NaNs are treated as equal if they are in the same place and if + ``equal_nan=True``. Infs are treated as equal if they are in the same + place and of the same sign in both arrays. + + Parameters + ---------- + a, b : array_like + Input arrays to compare. + rtol : float + The relative tolerance parameter (see Notes). + atol : float + The absolute tolerance parameter (see Notes). + equal_nan : bool + Whether to compare NaN's as equal. If True, NaN's in `a` will be + considered equal to NaN's in `b` in the output array. + + .. versionadded:: 1.10.0 + + Returns + ------- + allclose : bool + Returns True if the two arrays are equal within the given + tolerance; False otherwise. + + See Also + -------- + isclose, all, any, equal + + Notes + ----- + If the following equation is element-wise True, then allclose returns + True. + + absolute(`a` - `b`) <= (`atol` + `rtol` * absolute(`b`)) + + The above equation is not symmetric in `a` and `b`, so that + ``allclose(a, b)`` might be different from ``allclose(b, a)`` in + some rare cases. + + The comparison of `a` and `b` uses standard broadcasting, which + means that `a` and `b` need not have the same shape in order for + ``allclose(a, b)`` to evaluate to True. The same is true for + `equal` but not `array_equal`. + + `allclose` is not defined for non-numeric data types. + + Examples + -------- + >>> np.allclose([1e10,1e-7], [1.00001e10,1e-8]) + False + >>> np.allclose([1e10,1e-8], [1.00001e10,1e-9]) + True + >>> np.allclose([1e10,1e-8], [1.0001e10,1e-9]) + False + >>> np.allclose([1.0, np.nan], [1.0, np.nan]) + False + >>> np.allclose([1.0, np.nan], [1.0, np.nan], equal_nan=True) + True + + """ + res = all(isclose(a, b, rtol=rtol, atol=atol, equal_nan=equal_nan)) + return bool(res) + + +def _isclose_dispatcher(a, b, rtol=None, atol=None, equal_nan=None): + return (a, b) + + +@array_function_dispatch(_isclose_dispatcher) +def isclose(a, b, rtol=1.e-5, atol=1.e-8, equal_nan=False): + """ + Returns a boolean array where two arrays are element-wise equal within a + tolerance. + + The tolerance values are positive, typically very small numbers. The + relative difference (`rtol` * abs(`b`)) and the absolute difference + `atol` are added together to compare against the absolute difference + between `a` and `b`. + + .. warning:: The default `atol` is not appropriate for comparing numbers + that are much smaller than one (see Notes). + + Parameters + ---------- + a, b : array_like + Input arrays to compare. + rtol : float + The relative tolerance parameter (see Notes). + atol : float + The absolute tolerance parameter (see Notes). + equal_nan : bool + Whether to compare NaN's as equal. If True, NaN's in `a` will be + considered equal to NaN's in `b` in the output array. + + Returns + ------- + y : array_like + Returns a boolean array of where `a` and `b` are equal within the + given tolerance. If both `a` and `b` are scalars, returns a single + boolean value. + + See Also + -------- + allclose + math.isclose + + Notes + ----- + .. versionadded:: 1.7.0 + + For finite values, isclose uses the following equation to test whether + two floating point values are equivalent. + + absolute(`a` - `b`) <= (`atol` + `rtol` * absolute(`b`)) + + Unlike the built-in `math.isclose`, the above equation is not symmetric + in `a` and `b` -- it assumes `b` is the reference value -- so that + `isclose(a, b)` might be different from `isclose(b, a)`. Furthermore, + the default value of atol is not zero, and is used to determine what + small values should be considered close to zero. The default value is + appropriate for expected values of order unity: if the expected values + are significantly smaller than one, it can result in false positives. + `atol` should be carefully selected for the use case at hand. A zero value + for `atol` will result in `False` if either `a` or `b` is zero. + + `isclose` is not defined for non-numeric data types. + + Examples + -------- + >>> np.isclose([1e10,1e-7], [1.00001e10,1e-8]) + array([ True, False]) + >>> np.isclose([1e10,1e-8], [1.00001e10,1e-9]) + array([ True, True]) + >>> np.isclose([1e10,1e-8], [1.0001e10,1e-9]) + array([False, True]) + >>> np.isclose([1.0, np.nan], [1.0, np.nan]) + array([ True, False]) + >>> np.isclose([1.0, np.nan], [1.0, np.nan], equal_nan=True) + array([ True, True]) + >>> np.isclose([1e-8, 1e-7], [0.0, 0.0]) + array([ True, False]) + >>> np.isclose([1e-100, 1e-7], [0.0, 0.0], atol=0.0) + array([False, False]) + >>> np.isclose([1e-10, 1e-10], [1e-20, 0.0]) + array([ True, True]) + >>> np.isclose([1e-10, 1e-10], [1e-20, 0.999999e-10], atol=0.0) + array([False, True]) + """ + def within_tol(x, y, atol, rtol): + with errstate(invalid='ignore'): + return less_equal(abs(x-y), atol + rtol * abs(y)) + + x = asanyarray(a) + y = asanyarray(b) + + # Make sure y is an inexact type to avoid bad behavior on abs(MIN_INT). + # This will cause casting of x later. Also, make sure to allow subclasses + # (e.g., for numpy.ma). + # NOTE: We explicitly allow timedelta, which used to work. This could + # possibly be deprecated. See also gh-18286. + # timedelta works if `atol` is an integer or also a timedelta. + # Although, the default tolerances are unlikely to be useful + if y.dtype.kind != "m": + dt = multiarray.result_type(y, 1.) + y = array(y, dtype=dt, copy=False, subok=True) + + xfin = isfinite(x) + yfin = isfinite(y) + if all(xfin) and all(yfin): + return within_tol(x, y, atol, rtol) + else: + finite = xfin & yfin + cond = zeros_like(finite, subok=True) + # Because we're using boolean indexing, x & y must be the same shape. + # Ideally, we'd just do x, y = broadcast_arrays(x, y). It's in + # lib.stride_tricks, though, so we can't import it here. + x = x * ones_like(cond) + y = y * ones_like(cond) + # Avoid subtraction with infinite/nan values... + cond[finite] = within_tol(x[finite], y[finite], atol, rtol) + # Check for equality of infinite values... + cond[~finite] = (x[~finite] == y[~finite]) + if equal_nan: + # Make NaN == NaN + both_nan = isnan(x) & isnan(y) + + # Needed to treat masked arrays correctly. = True would not work. + cond[both_nan] = both_nan[both_nan] + + return cond[()] # Flatten 0d arrays to scalars + + +def _array_equal_dispatcher(a1, a2, equal_nan=None): + return (a1, a2) + + +@array_function_dispatch(_array_equal_dispatcher) +def array_equal(a1, a2, equal_nan=False): + """ + True if two arrays have the same shape and elements, False otherwise. + + Parameters + ---------- + a1, a2 : array_like + Input arrays. + equal_nan : bool + Whether to compare NaN's as equal. If the dtype of a1 and a2 is + complex, values will be considered equal if either the real or the + imaginary component of a given value is ``nan``. + + .. versionadded:: 1.19.0 + + Returns + ------- + b : bool + Returns True if the arrays are equal. + + See Also + -------- + allclose: Returns True if two arrays are element-wise equal within a + tolerance. + array_equiv: Returns True if input arrays are shape consistent and all + elements equal. + + Examples + -------- + >>> np.array_equal([1, 2], [1, 2]) + True + >>> np.array_equal(np.array([1, 2]), np.array([1, 2])) + True + >>> np.array_equal([1, 2], [1, 2, 3]) + False + >>> np.array_equal([1, 2], [1, 4]) + False + >>> a = np.array([1, np.nan]) + >>> np.array_equal(a, a) + False + >>> np.array_equal(a, a, equal_nan=True) + True + + When ``equal_nan`` is True, complex values with nan components are + considered equal if either the real *or* the imaginary components are nan. + + >>> a = np.array([1 + 1j]) + >>> b = a.copy() + >>> a.real = np.nan + >>> b.imag = np.nan + >>> np.array_equal(a, b, equal_nan=True) + True + """ + try: + a1, a2 = asarray(a1), asarray(a2) + except Exception: + return False + if a1.shape != a2.shape: + return False + if not equal_nan: + return bool(asarray(a1 == a2).all()) + # Handling NaN values if equal_nan is True + a1nan, a2nan = isnan(a1), isnan(a2) + # NaN's occur at different locations + if not (a1nan == a2nan).all(): + return False + # Shapes of a1, a2 and masks are guaranteed to be consistent by this point + return bool(asarray(a1[~a1nan] == a2[~a1nan]).all()) + + +def _array_equiv_dispatcher(a1, a2): + return (a1, a2) + + +@array_function_dispatch(_array_equiv_dispatcher) +def array_equiv(a1, a2): + """ + Returns True if input arrays are shape consistent and all elements equal. + + Shape consistent means they are either the same shape, or one input array + can be broadcasted to create the same shape as the other one. + + Parameters + ---------- + a1, a2 : array_like + Input arrays. + + Returns + ------- + out : bool + True if equivalent, False otherwise. + + Examples + -------- + >>> np.array_equiv([1, 2], [1, 2]) + True + >>> np.array_equiv([1, 2], [1, 3]) + False + + Showing the shape equivalence: + + >>> np.array_equiv([1, 2], [[1, 2], [1, 2]]) + True + >>> np.array_equiv([1, 2], [[1, 2, 1, 2], [1, 2, 1, 2]]) + False + + >>> np.array_equiv([1, 2], [[1, 2], [1, 3]]) + False + + """ + try: + a1, a2 = asarray(a1), asarray(a2) + except Exception: + return False + try: + multiarray.broadcast(a1, a2) + except Exception: + return False + + return bool(asarray(a1 == a2).all()) + + +Inf = inf = infty = Infinity = PINF +nan = NaN = NAN +False_ = bool_(False) +True_ = bool_(True) + + +def extend_all(module): + existing = set(__all__) + mall = getattr(module, '__all__') + for a in mall: + if a not in existing: + __all__.append(a) + + +from .umath import * +from .numerictypes import * +from . import fromnumeric +from .fromnumeric import * +from . import arrayprint +from .arrayprint import * +from . import _asarray +from ._asarray import * +from . import _ufunc_config +from ._ufunc_config import * +extend_all(fromnumeric) +extend_all(umath) +extend_all(numerictypes) +extend_all(arrayprint) +extend_all(_asarray) +extend_all(_ufunc_config) diff --git a/venv/Lib/site-packages/numpy/core/numeric.pyi b/venv/Lib/site-packages/numpy/core/numeric.pyi new file mode 100644 index 0000000..d91cb31 --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/numeric.pyi @@ -0,0 +1,189 @@ +import sys +from typing import ( + Any, + Optional, + Union, + Sequence, + Tuple, + Callable, + List, + overload, + TypeVar, + Iterable, +) + +from numpy import ndarray, generic, dtype, bool_, signedinteger, _OrderKACF, _OrderCF +from numpy.typing import ArrayLike, DTypeLike, _ShapeLike + +if sys.version_info >= (3, 8): + from typing import Literal +else: + from typing_extensions import Literal + +_T = TypeVar("_T") +_ArrayType = TypeVar("_ArrayType", bound=ndarray) + +_CorrelateMode = Literal["valid", "same", "full"] + +@overload +def zeros_like( + a: _ArrayType, + dtype: None = ..., + order: _OrderKACF = ..., + subok: Literal[True] = ..., + shape: None = ..., +) -> _ArrayType: ... +@overload +def zeros_like( + a: ArrayLike, + dtype: DTypeLike = ..., + order: _OrderKACF = ..., + subok: bool = ..., + shape: Optional[_ShapeLike] = ..., +) -> ndarray: ... +def ones( + shape: _ShapeLike, + dtype: DTypeLike = ..., + order: _OrderCF = ..., + *, + like: ArrayLike = ..., +) -> ndarray: ... +@overload +def ones_like( + a: _ArrayType, + dtype: None = ..., + order: _OrderKACF = ..., + subok: Literal[True] = ..., + shape: None = ..., +) -> _ArrayType: ... +@overload +def ones_like( + a: ArrayLike, + dtype: DTypeLike = ..., + order: _OrderKACF = ..., + subok: bool = ..., + shape: Optional[_ShapeLike] = ..., +) -> ndarray: ... +@overload +def empty_like( + a: _ArrayType, + dtype: None = ..., + order: _OrderKACF = ..., + subok: Literal[True] = ..., + shape: None = ..., +) -> _ArrayType: ... +@overload +def empty_like( + a: ArrayLike, + dtype: DTypeLike = ..., + order: _OrderKACF = ..., + subok: bool = ..., + shape: Optional[_ShapeLike] = ..., +) -> ndarray: ... +def full( + shape: _ShapeLike, + fill_value: Any, + dtype: DTypeLike = ..., + order: _OrderCF = ..., + *, + like: ArrayLike = ..., +) -> ndarray: ... +@overload +def full_like( + a: _ArrayType, + fill_value: Any, + dtype: None = ..., + order: _OrderKACF = ..., + subok: Literal[True] = ..., + shape: None = ..., +) -> _ArrayType: ... +@overload +def full_like( + a: ArrayLike, + fill_value: Any, + dtype: DTypeLike = ..., + order: _OrderKACF = ..., + subok: bool = ..., + shape: Optional[_ShapeLike] = ..., +) -> ndarray: ... +@overload +def count_nonzero( + a: ArrayLike, axis: None = ..., *, keepdims: Literal[False] = ... +) -> int: ... +@overload +def count_nonzero( + a: ArrayLike, axis: _ShapeLike = ..., *, keepdims: bool = ... +) -> Union[signedinteger[Any], ndarray]: ... # TODO: np.intp +def isfortran(a: Union[ndarray, generic]) -> bool: ... +def argwhere(a: ArrayLike) -> ndarray: ... +def flatnonzero(a: ArrayLike) -> ndarray: ... +def correlate(a: ArrayLike, v: ArrayLike, mode: _CorrelateMode = ...) -> ndarray: ... +def convolve(a: ArrayLike, v: ArrayLike, mode: _CorrelateMode = ...) -> ndarray: ... +@overload +def outer(a: ArrayLike, b: ArrayLike, out: None = ...) -> ndarray: ... +@overload +def outer(a: ArrayLike, b: ArrayLike, out: _ArrayType = ...) -> _ArrayType: ... +def tensordot( + a: ArrayLike, + b: ArrayLike, + axes: Union[int, Tuple[_ShapeLike, _ShapeLike]] = ..., +) -> ndarray: ... +def roll( + a: ArrayLike, + shift: _ShapeLike, + axis: Optional[_ShapeLike] = ..., +) -> ndarray: ... +def rollaxis(a: ndarray, axis: int, start: int = ...) -> ndarray: ... +def moveaxis( + a: ndarray, + source: _ShapeLike, + destination: _ShapeLike, +) -> ndarray: ... +def cross( + a: ArrayLike, + b: ArrayLike, + axisa: int = ..., + axisb: int = ..., + axisc: int = ..., + axis: Optional[int] = ..., +) -> ndarray: ... +@overload +def indices( + dimensions: Sequence[int], + dtype: DTypeLike = ..., + sparse: Literal[False] = ..., +) -> ndarray: ... +@overload +def indices( + dimensions: Sequence[int], + dtype: DTypeLike = ..., + sparse: Literal[True] = ..., +) -> Tuple[ndarray, ...]: ... +def fromfunction( + function: Callable[..., _T], + shape: Sequence[int], + *, + dtype: DTypeLike = ..., + like: ArrayLike = ..., + **kwargs: Any, +) -> _T: ... +def isscalar(element: Any) -> bool: ... +def binary_repr(num: int, width: Optional[int] = ...) -> str: ... +def base_repr(number: int, base: int = ..., padding: int = ...) -> str: ... +def identity(n: int, dtype: DTypeLike = ..., *, like: ArrayLike = ...) -> ndarray: ... +def allclose( + a: ArrayLike, + b: ArrayLike, + rtol: float = ..., + atol: float = ..., + equal_nan: bool = ..., +) -> bool: ... +def isclose( + a: ArrayLike, + b: ArrayLike, + rtol: float = ..., + atol: float = ..., + equal_nan: bool = ..., +) -> Union[bool_, ndarray]: ... +def array_equal(a1: ArrayLike, a2: ArrayLike) -> bool: ... +def array_equiv(a1: ArrayLike, a2: ArrayLike) -> bool: ... diff --git a/venv/Lib/site-packages/numpy/core/numerictypes.py b/venv/Lib/site-packages/numpy/core/numerictypes.py new file mode 100644 index 0000000..e705dd3 --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/numerictypes.py @@ -0,0 +1,672 @@ +""" +numerictypes: Define the numeric type objects + +This module is designed so "from numerictypes import \\*" is safe. +Exported symbols include: + + Dictionary with all registered number types (including aliases): + typeDict + + Type objects (not all will be available, depends on platform): + see variable sctypes for which ones you have + + Bit-width names + + int8 int16 int32 int64 int128 + uint8 uint16 uint32 uint64 uint128 + float16 float32 float64 float96 float128 float256 + complex32 complex64 complex128 complex192 complex256 complex512 + datetime64 timedelta64 + + c-based names + + bool_ + + object_ + + void, str_, unicode_ + + byte, ubyte, + short, ushort + intc, uintc, + intp, uintp, + int_, uint, + longlong, ulonglong, + + single, csingle, + float_, complex_, + longfloat, clongfloat, + + As part of the type-hierarchy: xx -- is bit-width + + generic + +-> bool_ (kind=b) + +-> number + | +-> integer + | | +-> signedinteger (intxx) (kind=i) + | | | byte + | | | short + | | | intc + | | | intp int0 + | | | int_ + | | | longlong + | | \\-> unsignedinteger (uintxx) (kind=u) + | | ubyte + | | ushort + | | uintc + | | uintp uint0 + | | uint_ + | | ulonglong + | +-> inexact + | +-> floating (floatxx) (kind=f) + | | half + | | single + | | float_ (double) + | | longfloat + | \\-> complexfloating (complexxx) (kind=c) + | csingle (singlecomplex) + | complex_ (cfloat, cdouble) + | clongfloat (longcomplex) + +-> flexible + | +-> character + | | str_ (string_, bytes_) (kind=S) [Python 2] + | | unicode_ (kind=U) [Python 2] + | | + | | bytes_ (string_) (kind=S) [Python 3] + | | str_ (unicode_) (kind=U) [Python 3] + | | + | \\-> void (kind=V) + \\-> object_ (not used much) (kind=O) + +""" +import types as _types +import numbers +import warnings + +from numpy.core.multiarray import ( + typeinfo, ndarray, array, empty, dtype, datetime_data, + datetime_as_string, busday_offset, busday_count, is_busday, + busdaycalendar + ) +from numpy.core.overrides import set_module + +# we add more at the bottom +__all__ = ['sctypeDict', 'typeDict', 'sctypes', + 'ScalarType', 'obj2sctype', 'cast', 'nbytes', 'sctype2char', + 'maximum_sctype', 'issctype', 'typecodes', 'find_common_type', + 'issubdtype', 'datetime_data', 'datetime_as_string', + 'busday_offset', 'busday_count', 'is_busday', 'busdaycalendar', + ] + +# we don't need all these imports, but we need to keep them for compatibility +# for users using np.core.numerictypes.UPPER_TABLE +from ._string_helpers import ( + english_lower, english_upper, english_capitalize, LOWER_TABLE, UPPER_TABLE +) + +from ._type_aliases import ( + sctypeDict, + allTypes, + bitname, + sctypes, + _concrete_types, + _concrete_typeinfo, + _bits_of, +) +from ._dtype import _kind_name + +# we don't export these for import *, but we do want them accessible +# as numerictypes.bool, etc. +from builtins import bool, int, float, complex, object, str, bytes +from numpy.compat import long, unicode + + +# We use this later +generic = allTypes['generic'] + +genericTypeRank = ['bool', 'int8', 'uint8', 'int16', 'uint16', + 'int32', 'uint32', 'int64', 'uint64', 'int128', + 'uint128', 'float16', + 'float32', 'float64', 'float80', 'float96', 'float128', + 'float256', + 'complex32', 'complex64', 'complex128', 'complex160', + 'complex192', 'complex256', 'complex512', 'object'] + +@set_module('numpy') +def maximum_sctype(t): + """ + Return the scalar type of highest precision of the same kind as the input. + + Parameters + ---------- + t : dtype or dtype specifier + The input data type. This can be a `dtype` object or an object that + is convertible to a `dtype`. + + Returns + ------- + out : dtype + The highest precision data type of the same kind (`dtype.kind`) as `t`. + + See Also + -------- + obj2sctype, mintypecode, sctype2char + dtype + + Examples + -------- + >>> np.maximum_sctype(int) + + >>> np.maximum_sctype(np.uint8) + + >>> np.maximum_sctype(complex) + # may vary + + >>> np.maximum_sctype(str) + + + >>> np.maximum_sctype('i2') + + >>> np.maximum_sctype('f4') + # may vary + + """ + g = obj2sctype(t) + if g is None: + return t + t = g + base = _kind_name(dtype(t)) + if base in sctypes: + return sctypes[base][-1] + else: + return t + + +@set_module('numpy') +def issctype(rep): + """ + Determines whether the given object represents a scalar data-type. + + Parameters + ---------- + rep : any + If `rep` is an instance of a scalar dtype, True is returned. If not, + False is returned. + + Returns + ------- + out : bool + Boolean result of check whether `rep` is a scalar dtype. + + See Also + -------- + issubsctype, issubdtype, obj2sctype, sctype2char + + Examples + -------- + >>> np.issctype(np.int32) + True + >>> np.issctype(list) + False + >>> np.issctype(1.1) + False + + Strings are also a scalar type: + + >>> np.issctype(np.dtype('str')) + True + + """ + if not isinstance(rep, (type, dtype)): + return False + try: + res = obj2sctype(rep) + if res and res != object_: + return True + return False + except Exception: + return False + + +@set_module('numpy') +def obj2sctype(rep, default=None): + """ + Return the scalar dtype or NumPy equivalent of Python type of an object. + + Parameters + ---------- + rep : any + The object of which the type is returned. + default : any, optional + If given, this is returned for objects whose types can not be + determined. If not given, None is returned for those objects. + + Returns + ------- + dtype : dtype or Python type + The data type of `rep`. + + See Also + -------- + sctype2char, issctype, issubsctype, issubdtype, maximum_sctype + + Examples + -------- + >>> np.obj2sctype(np.int32) + + >>> np.obj2sctype(np.array([1., 2.])) + + >>> np.obj2sctype(np.array([1.j])) + + + >>> np.obj2sctype(dict) + + >>> np.obj2sctype('string') + + >>> np.obj2sctype(1, default=list) + + + """ + # prevent abstract classes being upcast + if isinstance(rep, type) and issubclass(rep, generic): + return rep + # extract dtype from arrays + if isinstance(rep, ndarray): + return rep.dtype.type + # fall back on dtype to convert + try: + res = dtype(rep) + except Exception: + return default + else: + return res.type + + +@set_module('numpy') +def issubclass_(arg1, arg2): + """ + Determine if a class is a subclass of a second class. + + `issubclass_` is equivalent to the Python built-in ``issubclass``, + except that it returns False instead of raising a TypeError if one + of the arguments is not a class. + + Parameters + ---------- + arg1 : class + Input class. True is returned if `arg1` is a subclass of `arg2`. + arg2 : class or tuple of classes. + Input class. If a tuple of classes, True is returned if `arg1` is a + subclass of any of the tuple elements. + + Returns + ------- + out : bool + Whether `arg1` is a subclass of `arg2` or not. + + See Also + -------- + issubsctype, issubdtype, issctype + + Examples + -------- + >>> np.issubclass_(np.int32, int) + False + >>> np.issubclass_(np.int32, float) + False + >>> np.issubclass_(np.float64, float) + True + + """ + try: + return issubclass(arg1, arg2) + except TypeError: + return False + + +@set_module('numpy') +def issubsctype(arg1, arg2): + """ + Determine if the first argument is a subclass of the second argument. + + Parameters + ---------- + arg1, arg2 : dtype or dtype specifier + Data-types. + + Returns + ------- + out : bool + The result. + + See Also + -------- + issctype, issubdtype, obj2sctype + + Examples + -------- + >>> np.issubsctype('S8', str) + False + >>> np.issubsctype(np.array([1]), int) + True + >>> np.issubsctype(np.array([1]), float) + False + + """ + return issubclass(obj2sctype(arg1), obj2sctype(arg2)) + + +@set_module('numpy') +def issubdtype(arg1, arg2): + r""" + Returns True if first argument is a typecode lower/equal in type hierarchy. + + This is like the builtin :func:`issubclass`, but for `dtype`\ s. + + Parameters + ---------- + arg1, arg2 : dtype_like + `dtype` or object coercible to one + + Returns + ------- + out : bool + + See Also + -------- + :ref:`arrays.scalars` : Overview of the numpy type hierarchy. + issubsctype, issubclass_ + + Examples + -------- + `issubdtype` can be used to check the type of arrays: + + >>> ints = np.array([1, 2, 3], dtype=np.int32) + >>> np.issubdtype(ints.dtype, np.integer) + True + >>> np.issubdtype(ints.dtype, np.floating) + False + + >>> floats = np.array([1, 2, 3], dtype=np.float32) + >>> np.issubdtype(floats.dtype, np.integer) + False + >>> np.issubdtype(floats.dtype, np.floating) + True + + Similar types of different sizes are not subdtypes of each other: + + >>> np.issubdtype(np.float64, np.float32) + False + >>> np.issubdtype(np.float32, np.float64) + False + + but both are subtypes of `floating`: + + >>> np.issubdtype(np.float64, np.floating) + True + >>> np.issubdtype(np.float32, np.floating) + True + + For convenience, dtype-like objects are allowed too: + + >>> np.issubdtype('S1', np.string_) + True + >>> np.issubdtype('i4', np.signedinteger) + True + + """ + if not issubclass_(arg1, generic): + arg1 = dtype(arg1).type + if not issubclass_(arg2, generic): + arg2 = dtype(arg2).type + + return issubclass(arg1, arg2) + + +# This dictionary allows look up based on any alias for an array data-type +class _typedict(dict): + """ + Base object for a dictionary for look-up with any alias for an array dtype. + + Instances of `_typedict` can not be used as dictionaries directly, + first they have to be populated. + + """ + + def __getitem__(self, obj): + return dict.__getitem__(self, obj2sctype(obj)) + +nbytes = _typedict() +_alignment = _typedict() +_maxvals = _typedict() +_minvals = _typedict() +def _construct_lookups(): + for name, info in _concrete_typeinfo.items(): + obj = info.type + nbytes[obj] = info.bits // 8 + _alignment[obj] = info.alignment + if len(info) > 5: + _maxvals[obj] = info.max + _minvals[obj] = info.min + else: + _maxvals[obj] = None + _minvals[obj] = None + +_construct_lookups() + + +@set_module('numpy') +def sctype2char(sctype): + """ + Return the string representation of a scalar dtype. + + Parameters + ---------- + sctype : scalar dtype or object + If a scalar dtype, the corresponding string character is + returned. If an object, `sctype2char` tries to infer its scalar type + and then return the corresponding string character. + + Returns + ------- + typechar : str + The string character corresponding to the scalar type. + + Raises + ------ + ValueError + If `sctype` is an object for which the type can not be inferred. + + See Also + -------- + obj2sctype, issctype, issubsctype, mintypecode + + Examples + -------- + >>> for sctype in [np.int32, np.double, np.complex_, np.string_, np.ndarray]: + ... print(np.sctype2char(sctype)) + l # may vary + d + D + S + O + + >>> x = np.array([1., 2-1.j]) + >>> np.sctype2char(x) + 'D' + >>> np.sctype2char(list) + 'O' + + """ + sctype = obj2sctype(sctype) + if sctype is None: + raise ValueError("unrecognized type") + if sctype not in _concrete_types: + # for compatibility + raise KeyError(sctype) + return dtype(sctype).char + +# Create dictionary of casting functions that wrap sequences +# indexed by type or type character +cast = _typedict() +for key in _concrete_types: + cast[key] = lambda x, k=key: array(x, copy=False).astype(k) + +try: + ScalarType = [_types.IntType, _types.FloatType, _types.ComplexType, + _types.LongType, _types.BooleanType, + _types.StringType, _types.UnicodeType, _types.BufferType] +except AttributeError: + # Py3K + ScalarType = [int, float, complex, int, bool, bytes, str, memoryview] + +ScalarType.extend(_concrete_types) +ScalarType = tuple(ScalarType) + + +# Now add the types we've determined to this module +for key in allTypes: + globals()[key] = allTypes[key] + __all__.append(key) + +del key + +typecodes = {'Character':'c', + 'Integer':'bhilqp', + 'UnsignedInteger':'BHILQP', + 'Float':'efdg', + 'Complex':'FDG', + 'AllInteger':'bBhHiIlLqQpP', + 'AllFloat':'efdgFDG', + 'Datetime': 'Mm', + 'All':'?bhilqpBHILQPefdgFDGSUVOMm'} + +# backwards compatibility --- deprecated name +typeDict = sctypeDict + +# b -> boolean +# u -> unsigned integer +# i -> signed integer +# f -> floating point +# c -> complex +# M -> datetime +# m -> timedelta +# S -> string +# U -> Unicode string +# V -> record +# O -> Python object +_kind_list = ['b', 'u', 'i', 'f', 'c', 'S', 'U', 'V', 'O', 'M', 'm'] + +__test_types = '?'+typecodes['AllInteger'][:-2]+typecodes['AllFloat']+'O' +__len_test_types = len(__test_types) + +# Keep incrementing until a common type both can be coerced to +# is found. Otherwise, return None +def _find_common_coerce(a, b): + if a > b: + return a + try: + thisind = __test_types.index(a.char) + except ValueError: + return None + return _can_coerce_all([a, b], start=thisind) + +# Find a data-type that all data-types in a list can be coerced to +def _can_coerce_all(dtypelist, start=0): + N = len(dtypelist) + if N == 0: + return None + if N == 1: + return dtypelist[0] + thisind = start + while thisind < __len_test_types: + newdtype = dtype(__test_types[thisind]) + numcoerce = len([x for x in dtypelist if newdtype >= x]) + if numcoerce == N: + return newdtype + thisind += 1 + return None + +def _register_types(): + numbers.Integral.register(integer) + numbers.Complex.register(inexact) + numbers.Real.register(floating) + numbers.Number.register(number) + +_register_types() + + +@set_module('numpy') +def find_common_type(array_types, scalar_types): + """ + Determine common type following standard coercion rules. + + Parameters + ---------- + array_types : sequence + A list of dtypes or dtype convertible objects representing arrays. + scalar_types : sequence + A list of dtypes or dtype convertible objects representing scalars. + + Returns + ------- + datatype : dtype + The common data type, which is the maximum of `array_types` ignoring + `scalar_types`, unless the maximum of `scalar_types` is of a + different kind (`dtype.kind`). If the kind is not understood, then + None is returned. + + See Also + -------- + dtype, common_type, can_cast, mintypecode + + Examples + -------- + >>> np.find_common_type([], [np.int64, np.float32, complex]) + dtype('complex128') + >>> np.find_common_type([np.int64, np.float32], []) + dtype('float64') + + The standard casting rules ensure that a scalar cannot up-cast an + array unless the scalar is of a fundamentally different kind of data + (i.e. under a different hierarchy in the data type hierarchy) then + the array: + + >>> np.find_common_type([np.float32], [np.int64, np.float64]) + dtype('float32') + + Complex is of a different type, so it up-casts the float in the + `array_types` argument: + + >>> np.find_common_type([np.float32], [complex]) + dtype('complex128') + + Type specifier strings are convertible to dtypes and can therefore + be used instead of dtypes: + + >>> np.find_common_type(['f4', 'f4', 'i4'], ['c8']) + dtype('complex128') + + """ + array_types = [dtype(x) for x in array_types] + scalar_types = [dtype(x) for x in scalar_types] + + maxa = _can_coerce_all(array_types) + maxsc = _can_coerce_all(scalar_types) + + if maxa is None: + return maxsc + + if maxsc is None: + return maxa + + try: + index_a = _kind_list.index(maxa.kind) + index_sc = _kind_list.index(maxsc.kind) + except ValueError: + return None + + if index_sc > index_a: + return _find_common_coerce(maxsc, maxa) + else: + return maxa diff --git a/venv/Lib/site-packages/numpy/core/numerictypes.pyi b/venv/Lib/site-packages/numpy/core/numerictypes.pyi new file mode 100644 index 0000000..192015f --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/numerictypes.pyi @@ -0,0 +1,29 @@ +from typing import TypeVar, Optional, Type, Union, Tuple, Sequence, overload, Any + +from numpy import generic, ndarray, dtype +from numpy.typing import DTypeLike + +_DefaultType = TypeVar("_DefaultType") + +def maximum_sctype(t: DTypeLike) -> dtype: ... +def issctype(rep: object) -> bool: ... +@overload +def obj2sctype(rep: object) -> Optional[generic]: ... +@overload +def obj2sctype(rep: object, default: None) -> Optional[generic]: ... +@overload +def obj2sctype( + rep: object, default: Type[_DefaultType] +) -> Union[generic, Type[_DefaultType]]: ... +def issubclass_(arg1: object, arg2: Union[object, Tuple[object, ...]]) -> bool: ... +def issubsctype( + arg1: Union[ndarray, DTypeLike], arg2: Union[ndarray, DTypeLike] +) -> bool: ... +def issubdtype(arg1: DTypeLike, arg2: DTypeLike) -> bool: ... +def sctype2char(sctype: object) -> str: ... +def find_common_type( + array_types: Sequence[DTypeLike], scalar_types: Sequence[DTypeLike] +) -> dtype: ... + +# TODO: Add annotations for the following objects: +# typeDict, nbytes, cast, ScalarType & typecodes diff --git a/venv/Lib/site-packages/numpy/core/overrides.py b/venv/Lib/site-packages/numpy/core/overrides.py new file mode 100644 index 0000000..c2b5fb7 --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/overrides.py @@ -0,0 +1,231 @@ +"""Implementation of __array_function__ overrides from NEP-18.""" +import collections +import functools +import os +import textwrap + +from numpy.core._multiarray_umath import ( + add_docstring, implement_array_function, _get_implementing_args) +from numpy.compat._inspect import getargspec + + +ARRAY_FUNCTION_ENABLED = bool( + int(os.environ.get('NUMPY_EXPERIMENTAL_ARRAY_FUNCTION', 1))) + +array_function_like_doc = ( + """like : array_like + Reference object to allow the creation of arrays which are not + NumPy arrays. If an array-like passed in as ``like`` supports + the ``__array_function__`` protocol, the result will be defined + by it. In this case, it ensures the creation of an array object + compatible with that passed in via this argument. + + .. note:: + The ``like`` keyword is an experimental feature pending on + acceptance of :ref:`NEP 35 `.""" +) + +def set_array_function_like_doc(public_api): + if public_api.__doc__ is not None: + public_api.__doc__ = public_api.__doc__.replace( + "${ARRAY_FUNCTION_LIKE}", + array_function_like_doc, + ) + return public_api + + +add_docstring( + implement_array_function, + """ + Implement a function with checks for __array_function__ overrides. + + All arguments are required, and can only be passed by position. + + Parameters + ---------- + implementation : function + Function that implements the operation on NumPy array without + overrides when called like ``implementation(*args, **kwargs)``. + public_api : function + Function exposed by NumPy's public API originally called like + ``public_api(*args, **kwargs)`` on which arguments are now being + checked. + relevant_args : iterable + Iterable of arguments to check for __array_function__ methods. + args : tuple + Arbitrary positional arguments originally passed into ``public_api``. + kwargs : dict + Arbitrary keyword arguments originally passed into ``public_api``. + + Returns + ------- + Result from calling ``implementation()`` or an ``__array_function__`` + method, as appropriate. + + Raises + ------ + TypeError : if no implementation is found. + """) + + +# exposed for testing purposes; used internally by implement_array_function +add_docstring( + _get_implementing_args, + """ + Collect arguments on which to call __array_function__. + + Parameters + ---------- + relevant_args : iterable of array-like + Iterable of possibly array-like arguments to check for + __array_function__ methods. + + Returns + ------- + Sequence of arguments with __array_function__ methods, in the order in + which they should be called. + """) + + +ArgSpec = collections.namedtuple('ArgSpec', 'args varargs keywords defaults') + + +def verify_matching_signatures(implementation, dispatcher): + """Verify that a dispatcher function has the right signature.""" + implementation_spec = ArgSpec(*getargspec(implementation)) + dispatcher_spec = ArgSpec(*getargspec(dispatcher)) + + if (implementation_spec.args != dispatcher_spec.args or + implementation_spec.varargs != dispatcher_spec.varargs or + implementation_spec.keywords != dispatcher_spec.keywords or + (bool(implementation_spec.defaults) != + bool(dispatcher_spec.defaults)) or + (implementation_spec.defaults is not None and + len(implementation_spec.defaults) != + len(dispatcher_spec.defaults))): + raise RuntimeError('implementation and dispatcher for %s have ' + 'different function signatures' % implementation) + + if implementation_spec.defaults is not None: + if dispatcher_spec.defaults != (None,) * len(dispatcher_spec.defaults): + raise RuntimeError('dispatcher functions can only use None for ' + 'default argument values') + + +def set_module(module): + """Decorator for overriding __module__ on a function or class. + + Example usage:: + + @set_module('numpy') + def example(): + pass + + assert example.__module__ == 'numpy' + """ + def decorator(func): + if module is not None: + func.__module__ = module + return func + return decorator + + + +# Call textwrap.dedent here instead of in the function so as to avoid +# calling dedent multiple times on the same text +_wrapped_func_source = textwrap.dedent(""" + @functools.wraps(implementation) + def {name}(*args, **kwargs): + relevant_args = dispatcher(*args, **kwargs) + return implement_array_function( + implementation, {name}, relevant_args, args, kwargs) + """) + + +def array_function_dispatch(dispatcher, module=None, verify=True, + docs_from_dispatcher=False): + """Decorator for adding dispatch with the __array_function__ protocol. + + See NEP-18 for example usage. + + Parameters + ---------- + dispatcher : callable + Function that when called like ``dispatcher(*args, **kwargs)`` with + arguments from the NumPy function call returns an iterable of + array-like arguments to check for ``__array_function__``. + module : str, optional + __module__ attribute to set on new function, e.g., ``module='numpy'``. + By default, module is copied from the decorated function. + verify : bool, optional + If True, verify the that the signature of the dispatcher and decorated + function signatures match exactly: all required and optional arguments + should appear in order with the same names, but the default values for + all optional arguments should be ``None``. Only disable verification + if the dispatcher's signature needs to deviate for some particular + reason, e.g., because the function has a signature like + ``func(*args, **kwargs)``. + docs_from_dispatcher : bool, optional + If True, copy docs from the dispatcher function onto the dispatched + function, rather than from the implementation. This is useful for + functions defined in C, which otherwise don't have docstrings. + + Returns + ------- + Function suitable for decorating the implementation of a NumPy function. + """ + + if not ARRAY_FUNCTION_ENABLED: + def decorator(implementation): + if docs_from_dispatcher: + add_docstring(implementation, dispatcher.__doc__) + if module is not None: + implementation.__module__ = module + return implementation + return decorator + + def decorator(implementation): + if verify: + verify_matching_signatures(implementation, dispatcher) + + if docs_from_dispatcher: + add_docstring(implementation, dispatcher.__doc__) + + # Equivalently, we could define this function directly instead of using + # exec. This version has the advantage of giving the helper function a + # more interpettable name. Otherwise, the original function does not + # show up at all in many cases, e.g., if it's written in C or if the + # dispatcher gets an invalid keyword argument. + source = _wrapped_func_source.format(name=implementation.__name__) + + source_object = compile( + source, filename='<__array_function__ internals>', mode='exec') + scope = { + 'implementation': implementation, + 'dispatcher': dispatcher, + 'functools': functools, + 'implement_array_function': implement_array_function, + } + exec(source_object, scope) + + public_api = scope[implementation.__name__] + + if module is not None: + public_api.__module__ = module + + public_api._implementation = implementation + + return public_api + + return decorator + + +def array_function_from_dispatcher( + implementation, module=None, verify=True, docs_from_dispatcher=True): + """Like array_function_dispatcher, but with function arguments flipped.""" + + def decorator(dispatcher): + return array_function_dispatch( + dispatcher, module, verify=verify, + docs_from_dispatcher=docs_from_dispatcher)(implementation) + return decorator diff --git a/venv/Lib/site-packages/numpy/core/records.py b/venv/Lib/site-packages/numpy/core/records.py new file mode 100644 index 0000000..c2f6c69 --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/records.py @@ -0,0 +1,1101 @@ +""" +Record Arrays +============= +Record arrays expose the fields of structured arrays as properties. + +Most commonly, ndarrays contain elements of a single type, e.g. floats, +integers, bools etc. However, it is possible for elements to be combinations +of these using structured types, such as:: + + >>> a = np.array([(1, 2.0), (1, 2.0)], dtype=[('x', np.int64), ('y', np.float64)]) + >>> a + array([(1, 2.), (1, 2.)], dtype=[('x', '>> a['x'] + array([1, 1]) + + >>> a['y'] + array([2., 2.]) + +Record arrays allow us to access fields as properties:: + + >>> ar = np.rec.array(a) + + >>> ar.x + array([1, 1]) + + >>> ar.y + array([2., 2.]) + +""" +import os +import warnings +from collections import Counter, OrderedDict + +from . import numeric as sb +from . import numerictypes as nt +from numpy.compat import ( + os_fspath, contextlib_nullcontext +) +from numpy.core.overrides import set_module +from .arrayprint import get_printoptions + +# All of the functions allow formats to be a dtype +__all__ = ['record', 'recarray', 'format_parser'] + + +ndarray = sb.ndarray + +_byteorderconv = {'b':'>', + 'l':'<', + 'n':'=', + 'B':'>', + 'L':'<', + 'N':'=', + 'S':'s', + 's':'s', + '>':'>', + '<':'<', + '=':'=', + '|':'|', + 'I':'|', + 'i':'|'} + +# formats regular expression +# allows multidimension spec with a tuple syntax in front +# of the letter code '(2,3)f4' and ' ( 2 , 3 ) f4 ' +# are equally allowed + +numfmt = nt.typeDict + +# taken from OrderedDict recipes in the Python documentation +# https://docs.python.org/3.3/library/collections.html#ordereddict-examples-and-recipes +class _OrderedCounter(Counter, OrderedDict): + """Counter that remembers the order elements are first encountered""" + + def __repr__(self): + return '%s(%r)' % (self.__class__.__name__, OrderedDict(self)) + + def __reduce__(self): + return self.__class__, (OrderedDict(self),) + + +def find_duplicate(list): + """Find duplication in a list, return a list of duplicated elements""" + return [ + item + for item, counts in _OrderedCounter(list).items() + if counts > 1 + ] + + +@set_module('numpy') +class format_parser: + """ + Class to convert formats, names, titles description to a dtype. + + After constructing the format_parser object, the dtype attribute is + the converted data-type: + ``dtype = format_parser(formats, names, titles).dtype`` + + Attributes + ---------- + dtype : dtype + The converted data-type. + + Parameters + ---------- + formats : str or list of str + The format description, either specified as a string with + comma-separated format descriptions in the form ``'f8, i4, a5'``, or + a list of format description strings in the form + ``['f8', 'i4', 'a5']``. + names : str or list/tuple of str + The field names, either specified as a comma-separated string in the + form ``'col1, col2, col3'``, or as a list or tuple of strings in the + form ``['col1', 'col2', 'col3']``. + An empty list can be used, in that case default field names + ('f0', 'f1', ...) are used. + titles : sequence + Sequence of title strings. An empty list can be used to leave titles + out. + aligned : bool, optional + If True, align the fields by padding as the C-compiler would. + Default is False. + byteorder : str, optional + If specified, all the fields will be changed to the + provided byte-order. Otherwise, the default byte-order is + used. For all available string specifiers, see `dtype.newbyteorder`. + + See Also + -------- + dtype, typename, sctype2char + + Examples + -------- + >>> np.format_parser(['>> np.format_parser(['f8', 'i4', 'a5'], ['col1', 'col2', 'col3'], + ... []).dtype + dtype([('col1', '>> np.format_parser([' len(titles): + self._titles += [None] * (self._nfields - len(titles)) + + def _createdtype(self, byteorder): + dtype = sb.dtype({ + 'names': self._names, + 'formats': self._f_formats, + 'offsets': self._offsets, + 'titles': self._titles, + }) + if byteorder is not None: + byteorder = _byteorderconv[byteorder[0]] + dtype = dtype.newbyteorder(byteorder) + + self.dtype = dtype + + +class record(nt.void): + """A data-type scalar that allows field access as attribute lookup. + """ + + # manually set name and module so that this class's type shows up + # as numpy.record when printed + __name__ = 'record' + __module__ = 'numpy' + + def __repr__(self): + if get_printoptions()['legacy'] == '1.13': + return self.__str__() + return super(record, self).__repr__() + + def __str__(self): + if get_printoptions()['legacy'] == '1.13': + return str(self.item()) + return super(record, self).__str__() + + def __getattribute__(self, attr): + if attr in ('setfield', 'getfield', 'dtype'): + return nt.void.__getattribute__(self, attr) + try: + return nt.void.__getattribute__(self, attr) + except AttributeError: + pass + fielddict = nt.void.__getattribute__(self, 'dtype').fields + res = fielddict.get(attr, None) + if res: + obj = self.getfield(*res[:2]) + # if it has fields return a record, + # otherwise return the object + try: + dt = obj.dtype + except AttributeError: + #happens if field is Object type + return obj + if dt.names is not None: + return obj.view((self.__class__, obj.dtype)) + return obj + else: + raise AttributeError("'record' object has no " + "attribute '%s'" % attr) + + def __setattr__(self, attr, val): + if attr in ('setfield', 'getfield', 'dtype'): + raise AttributeError("Cannot set '%s' attribute" % attr) + fielddict = nt.void.__getattribute__(self, 'dtype').fields + res = fielddict.get(attr, None) + if res: + return self.setfield(val, *res[:2]) + else: + if getattr(self, attr, None): + return nt.void.__setattr__(self, attr, val) + else: + raise AttributeError("'record' object has no " + "attribute '%s'" % attr) + + def __getitem__(self, indx): + obj = nt.void.__getitem__(self, indx) + + # copy behavior of record.__getattribute__, + if isinstance(obj, nt.void) and obj.dtype.names is not None: + return obj.view((self.__class__, obj.dtype)) + else: + # return a single element + return obj + + def pprint(self): + """Pretty-print all fields.""" + # pretty-print all fields + names = self.dtype.names + maxlen = max(len(name) for name in names) + fmt = '%% %ds: %%s' % maxlen + rows = [fmt % (name, getattr(self, name)) for name in names] + return "\n".join(rows) + +# The recarray is almost identical to a standard array (which supports +# named fields already) The biggest difference is that it can use +# attribute-lookup to find the fields and it is constructed using +# a record. + +# If byteorder is given it forces a particular byteorder on all +# the fields (and any subfields) + +class recarray(ndarray): + """Construct an ndarray that allows field access using attributes. + + Arrays may have a data-types containing fields, analogous + to columns in a spread sheet. An example is ``[(x, int), (y, float)]``, + where each entry in the array is a pair of ``(int, float)``. Normally, + these attributes are accessed using dictionary lookups such as ``arr['x']`` + and ``arr['y']``. Record arrays allow the fields to be accessed as members + of the array, using ``arr.x`` and ``arr.y``. + + Parameters + ---------- + shape : tuple + Shape of output array. + dtype : data-type, optional + The desired data-type. By default, the data-type is determined + from `formats`, `names`, `titles`, `aligned` and `byteorder`. + formats : list of data-types, optional + A list containing the data-types for the different columns, e.g. + ``['i4', 'f8', 'i4']``. `formats` does *not* support the new + convention of using types directly, i.e. ``(int, float, int)``. + Note that `formats` must be a list, not a tuple. + Given that `formats` is somewhat limited, we recommend specifying + `dtype` instead. + names : tuple of str, optional + The name of each column, e.g. ``('x', 'y', 'z')``. + buf : buffer, optional + By default, a new array is created of the given shape and data-type. + If `buf` is specified and is an object exposing the buffer interface, + the array will use the memory from the existing buffer. In this case, + the `offset` and `strides` keywords are available. + + Other Parameters + ---------------- + titles : tuple of str, optional + Aliases for column names. For example, if `names` were + ``('x', 'y', 'z')`` and `titles` is + ``('x_coordinate', 'y_coordinate', 'z_coordinate')``, then + ``arr['x']`` is equivalent to both ``arr.x`` and ``arr.x_coordinate``. + byteorder : {'<', '>', '='}, optional + Byte-order for all fields. + aligned : bool, optional + Align the fields in memory as the C-compiler would. + strides : tuple of ints, optional + Buffer (`buf`) is interpreted according to these strides (strides + define how many bytes each array element, row, column, etc. + occupy in memory). + offset : int, optional + Start reading buffer (`buf`) from this offset onwards. + order : {'C', 'F'}, optional + Row-major (C-style) or column-major (Fortran-style) order. + + Returns + ------- + rec : recarray + Empty array of the given shape and type. + + See Also + -------- + core.records.fromrecords : Construct a record array from data. + record : fundamental data-type for `recarray`. + format_parser : determine a data-type from formats, names, titles. + + Notes + ----- + This constructor can be compared to ``empty``: it creates a new record + array but does not fill it with data. To create a record array from data, + use one of the following methods: + + 1. Create a standard ndarray and convert it to a record array, + using ``arr.view(np.recarray)`` + 2. Use the `buf` keyword. + 3. Use `np.rec.fromrecords`. + + Examples + -------- + Create an array with two fields, ``x`` and ``y``: + + >>> x = np.array([(1.0, 2), (3.0, 4)], dtype=[('x', '>> x + array([(1., 2), (3., 4)], dtype=[('x', '>> x['x'] + array([1., 3.]) + + View the array as a record array: + + >>> x = x.view(np.recarray) + + >>> x.x + array([1., 3.]) + + >>> x.y + array([2, 4]) + + Create a new, empty record array: + + >>> np.recarray((2,), + ... dtype=[('x', int), ('y', float), ('z', int)]) #doctest: +SKIP + rec.array([(-1073741821, 1.2249118382103472e-301, 24547520), + (3471280, 1.2134086255804012e-316, 0)], + dtype=[('x', ' 0 or self.shape == (0,): + lst = sb.array2string( + self, separator=', ', prefix=prefix, suffix=',') + else: + # show zero-length shape unless it is (0,) + lst = "[], shape=%s" % (repr(self.shape),) + + lf = '\n'+' '*len(prefix) + if get_printoptions()['legacy'] == '1.13': + lf = ' ' + lf # trailing space + return fmt % (lst, lf, repr_dtype) + + def field(self, attr, val=None): + if isinstance(attr, int): + names = ndarray.__getattribute__(self, 'dtype').names + attr = names[attr] + + fielddict = ndarray.__getattribute__(self, 'dtype').fields + + res = fielddict[attr][:2] + + if val is None: + obj = self.getfield(*res) + if obj.dtype.names is not None: + return obj + return obj.view(ndarray) + else: + return self.setfield(val, *res) + + +def _deprecate_shape_0_as_None(shape): + if shape == 0: + warnings.warn( + "Passing `shape=0` to have the shape be inferred is deprecated, " + "and in future will be equivalent to `shape=(0,)`. To infer " + "the shape and suppress this warning, pass `shape=None` instead.", + FutureWarning, stacklevel=3) + return None + else: + return shape + + +def fromarrays(arrayList, dtype=None, shape=None, formats=None, + names=None, titles=None, aligned=False, byteorder=None): + """Create a record array from a (flat) list of arrays + + Parameters + ---------- + arrayList : list or tuple + List of array-like objects (such as lists, tuples, + and ndarrays). + dtype : data-type, optional + valid dtype for all arrays + shape : int or tuple of ints, optional + Shape of the resulting array. If not provided, inferred from + ``arrayList[0]``. + formats, names, titles, aligned, byteorder : + If `dtype` is ``None``, these arguments are passed to + `numpy.format_parser` to construct a dtype. See that function for + detailed documentation. + + Returns + ------- + np.recarray + Record array consisting of given arrayList columns. + + Examples + -------- + >>> x1=np.array([1,2,3,4]) + >>> x2=np.array(['a','dd','xyz','12']) + >>> x3=np.array([1.1,2,3,4]) + >>> r = np.core.records.fromarrays([x1,x2,x3],names='a,b,c') + >>> print(r[1]) + (2, 'dd', 2.0) # may vary + >>> x1[1]=34 + >>> r.a + array([1, 2, 3, 4]) + + >>> x1 = np.array([1, 2, 3, 4]) + >>> x2 = np.array(['a', 'dd', 'xyz', '12']) + >>> x3 = np.array([1.1, 2, 3,4]) + >>> r = np.core.records.fromarrays( + ... [x1, x2, x3], + ... dtype=np.dtype([('a', np.int32), ('b', 'S3'), ('c', np.float32)])) + >>> r + rec.array([(1, b'a', 1.1), (2, b'dd', 2. ), (3, b'xyz', 3. ), + (4, b'12', 4. )], + dtype=[('a', ' 0: + shape = shape[:-nn] + + for k, obj in enumerate(arrayList): + nn = descr[k].ndim + testshape = obj.shape[:obj.ndim - nn] + if testshape != shape: + raise ValueError("array-shape mismatch in array %d" % k) + + _array = recarray(shape, descr) + + # populate the record array (makes a copy) + for i in range(len(arrayList)): + _array[_names[i]] = arrayList[i] + + return _array + +def fromrecords(recList, dtype=None, shape=None, formats=None, names=None, + titles=None, aligned=False, byteorder=None): + """Create a recarray from a list of records in text form. + + Parameters + ---------- + recList : sequence + data in the same field may be heterogeneous - they will be promoted + to the highest data type. + dtype : data-type, optional + valid dtype for all arrays + shape : int or tuple of ints, optional + shape of each array. + formats, names, titles, aligned, byteorder : + If `dtype` is ``None``, these arguments are passed to + `numpy.format_parser` to construct a dtype. See that function for + detailed documentation. + + If both `formats` and `dtype` are None, then this will auto-detect + formats. Use list of tuples rather than list of lists for faster + processing. + + Returns + ------- + np.recarray + record array consisting of given recList rows. + + Examples + -------- + >>> r=np.core.records.fromrecords([(456,'dbe',1.2),(2,'de',1.3)], + ... names='col1,col2,col3') + >>> print(r[0]) + (456, 'dbe', 1.2) + >>> r.col1 + array([456, 2]) + >>> r.col2 + array(['dbe', 'de'], dtype='>> import pickle + >>> pickle.loads(pickle.dumps(r)) + rec.array([(456, 'dbe', 1.2), ( 2, 'de', 1.3)], + dtype=[('col1', ' 1: + raise ValueError("Can only deal with 1-d array.") + _array = recarray(shape, descr) + for k in range(_array.size): + _array[k] = tuple(recList[k]) + # list of lists instead of list of tuples ? + # 2018-02-07, 1.14.1 + warnings.warn( + "fromrecords expected a list of tuples, may have received a list " + "of lists instead. In the future that will raise an error", + FutureWarning, stacklevel=2) + return _array + else: + if shape is not None and retval.shape != shape: + retval.shape = shape + + res = retval.view(recarray) + + return res + + +def fromstring(datastring, dtype=None, shape=None, offset=0, formats=None, + names=None, titles=None, aligned=False, byteorder=None): + r"""Create a record array from binary data + + Note that despite the name of this function it does not accept `str` + instances. + + Parameters + ---------- + datastring : bytes-like + Buffer of binary data + dtype : data-type, optional + Valid dtype for all arrays + shape : int or tuple of ints, optional + Shape of each array. + offset : int, optional + Position in the buffer to start reading from. + formats, names, titles, aligned, byteorder : + If `dtype` is ``None``, these arguments are passed to + `numpy.format_parser` to construct a dtype. See that function for + detailed documentation. + + + Returns + ------- + np.recarray + Record array view into the data in datastring. This will be readonly + if `datastring` is readonly. + + See Also + -------- + numpy.frombuffer + + Examples + -------- + >>> a = b'\x01\x02\x03abc' + >>> np.core.records.fromstring(a, dtype='u1,u1,u1,S3') + rec.array([(1, 2, 3, b'abc')], + dtype=[('f0', 'u1'), ('f1', 'u1'), ('f2', 'u1'), ('f3', 'S3')]) + + >>> grades_dtype = [('Name', (np.str_, 10)), ('Marks', np.float64), + ... ('GradeLevel', np.int32)] + >>> grades_array = np.array([('Sam', 33.3, 3), ('Mike', 44.4, 5), + ... ('Aadi', 66.6, 6)], dtype=grades_dtype) + >>> np.core.records.fromstring(grades_array.tobytes(), dtype=grades_dtype) + rec.array([('Sam', 33.3, 3), ('Mike', 44.4, 5), ('Aadi', 66.6, 6)], + dtype=[('Name', '>> s = '\x01\x02\x03abc' + >>> np.core.records.fromstring(s, dtype='u1,u1,u1,S3') + Traceback (most recent call last) + ... + TypeError: a bytes-like object is required, not 'str' + """ + + if dtype is None and formats is None: + raise TypeError("fromstring() needs a 'dtype' or 'formats' argument") + + if dtype is not None: + descr = sb.dtype(dtype) + else: + descr = format_parser(formats, names, titles, aligned, byteorder).dtype + + itemsize = descr.itemsize + + # NumPy 1.19.0, 2020-01-01 + shape = _deprecate_shape_0_as_None(shape) + + if shape in (None, -1): + shape = (len(datastring) - offset) // itemsize + + _array = recarray(shape, descr, buf=datastring, offset=offset) + return _array + +def get_remaining_size(fd): + pos = fd.tell() + try: + fd.seek(0, 2) + return fd.tell() - pos + finally: + fd.seek(pos, 0) + +def fromfile(fd, dtype=None, shape=None, offset=0, formats=None, + names=None, titles=None, aligned=False, byteorder=None): + """Create an array from binary file data + + Parameters + ---------- + fd : str or file type + If file is a string or a path-like object then that file is opened, + else it is assumed to be a file object. The file object must + support random access (i.e. it must have tell and seek methods). + dtype : data-type, optional + valid dtype for all arrays + shape : int or tuple of ints, optional + shape of each array. + offset : int, optional + Position in the file to start reading from. + formats, names, titles, aligned, byteorder : + If `dtype` is ``None``, these arguments are passed to + `numpy.format_parser` to construct a dtype. See that function for + detailed documentation + + Returns + ------- + np.recarray + record array consisting of data enclosed in file. + + Examples + -------- + >>> from tempfile import TemporaryFile + >>> a = np.empty(10,dtype='f8,i4,a5') + >>> a[5] = (0.5,10,'abcde') + >>> + >>> fd=TemporaryFile() + >>> a = a.newbyteorder('<') + >>> a.tofile(fd) + >>> + >>> _ = fd.seek(0) + >>> r=np.core.records.fromfile(fd, formats='f8,i4,a5', shape=10, + ... byteorder='<') + >>> print(r[5]) + (0.5, 10, 'abcde') + >>> r.shape + (10,) + """ + + if dtype is None and formats is None: + raise TypeError("fromfile() needs a 'dtype' or 'formats' argument") + + # NumPy 1.19.0, 2020-01-01 + shape = _deprecate_shape_0_as_None(shape) + + if shape is None: + shape = (-1,) + elif isinstance(shape, int): + shape = (shape,) + + if hasattr(fd, 'readinto'): + # GH issue 2504. fd supports io.RawIOBase or io.BufferedIOBase interface. + # Example of fd: gzip, BytesIO, BufferedReader + # file already opened + ctx = contextlib_nullcontext(fd) + else: + # open file + ctx = open(os_fspath(fd), 'rb') + + with ctx as fd: + if offset > 0: + fd.seek(offset, 1) + size = get_remaining_size(fd) + + if dtype is not None: + descr = sb.dtype(dtype) + else: + descr = format_parser(formats, names, titles, aligned, byteorder).dtype + + itemsize = descr.itemsize + + shapeprod = sb.array(shape).prod(dtype=nt.intp) + shapesize = shapeprod * itemsize + if shapesize < 0: + shape = list(shape) + shape[shape.index(-1)] = size // -shapesize + shape = tuple(shape) + shapeprod = sb.array(shape).prod(dtype=nt.intp) + + nbytes = shapeprod * itemsize + + if nbytes > size: + raise ValueError( + "Not enough bytes left in file for specified shape and type") + + # create the array + _array = recarray(shape, descr) + nbytesread = fd.readinto(_array.data) + if nbytesread != nbytes: + raise IOError("Didn't read as many bytes as expected") + + return _array + +def array(obj, dtype=None, shape=None, offset=0, strides=None, formats=None, + names=None, titles=None, aligned=False, byteorder=None, copy=True): + """ + Construct a record array from a wide-variety of objects. + + A general-purpose record array constructor that dispatches to the + appropriate `recarray` creation function based on the inputs (see Notes). + + Parameters + ---------- + obj: any + Input object. See Notes for details on how various input types are + treated. + dtype: data-type, optional + Valid dtype for array. + shape: int or tuple of ints, optional + Shape of each array. + offset: int, optional + Position in the file or buffer to start reading from. + strides: tuple of ints, optional + Buffer (`buf`) is interpreted according to these strides (strides + define how many bytes each array element, row, column, etc. + occupy in memory). + formats, names, titles, aligned, byteorder : + If `dtype` is ``None``, these arguments are passed to + `numpy.format_parser` to construct a dtype. See that function for + detailed documentation. + copy: bool, optional + Whether to copy the input object (True), or to use a reference instead. + This option only applies when the input is an ndarray or recarray. + Defaults to True. + + Returns + ------- + np.recarray + Record array created from the specified object. + + Notes + ----- + If `obj` is ``None``, then call the `~numpy.recarray` constructor. If + `obj` is a string, then call the `fromstring` constructor. If `obj` is a + list or a tuple, then if the first object is an `~numpy.ndarray`, call + `fromarrays`, otherwise call `fromrecords`. If `obj` is a + `~numpy.recarray`, then make a copy of the data in the recarray + (if ``copy=True``) and use the new formats, names, and titles. If `obj` + is a file, then call `fromfile`. Finally, if obj is an `ndarray`, then + return ``obj.view(recarray)``, making a copy of the data if ``copy=True``. + + Examples + -------- + >>> a = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) + array([[1, 2, 3], + [4, 5, 6], + [7, 8, 9]]) + + >>> np.core.records.array(a) + rec.array([[1, 2, 3], + [4, 5, 6], + [7, 8, 9]], + dtype=int32) + + >>> b = [(1, 1), (2, 4), (3, 9)] + >>> c = np.core.records.array(b, formats = ['i2', 'f2'], names = ('x', 'y')) + >>> c + rec.array([(1, 1.0), (2, 4.0), (3, 9.0)], + dtype=[('x', '>> c.x + rec.array([1, 2, 3], dtype=int16) + + >>> c.y + rec.array([ 1.0, 4.0, 9.0], dtype=float16) + + >>> r = np.rec.array(['abc','def'], names=['col1','col2']) + >>> print(r.col1) + abc + + >>> r.col1 + array('abc', dtype='>> r.col2 + array('def', dtype=' sizeof(double) + if a == "Intel" or a == "AMD64": + deflist.append('FORCE_NO_LONG_DOUBLE_FORMATTING') + +def check_math_capabilities(config, ext, moredefs, mathlibs): + def check_func(func_name): + return config.check_func(func_name, libraries=mathlibs, + decl=True, call=True) + + def check_funcs_once(funcs_name): + decl = dict([(f, True) for f in funcs_name]) + st = config.check_funcs_once(funcs_name, libraries=mathlibs, + decl=decl, call=decl) + if st: + moredefs.extend([(fname2def(f), 1) for f in funcs_name]) + return st + + def check_funcs(funcs_name): + # Use check_funcs_once first, and if it does not work, test func per + # func. Return success only if all the functions are available + if not check_funcs_once(funcs_name): + # Global check failed, check func per func + for f in funcs_name: + if check_func(f): + moredefs.append((fname2def(f), 1)) + return 0 + else: + return 1 + + #use_msvc = config.check_decl("_MSC_VER") + + if not check_funcs_once(MANDATORY_FUNCS): + raise SystemError("One of the required function to build numpy is not" + " available (the list is %s)." % str(MANDATORY_FUNCS)) + + # Standard functions which may not be available and for which we have a + # replacement implementation. Note that some of these are C99 functions. + + # XXX: hack to circumvent cpp pollution from python: python put its + # config.h in the public namespace, so we have a clash for the common + # functions we test. We remove every function tested by python's + # autoconf, hoping their own test are correct + for f in OPTIONAL_STDFUNCS_MAYBE: + if config.check_decl(fname2def(f), + headers=["Python.h", "math.h"]): + OPTIONAL_STDFUNCS.remove(f) + + check_funcs(OPTIONAL_STDFUNCS) + + for h in OPTIONAL_HEADERS: + if config.check_func("", decl=False, call=False, headers=[h]): + h = h.replace(".", "_").replace(os.path.sep, "_") + moredefs.append((fname2def(h), 1)) + + for tup in OPTIONAL_INTRINSICS: + headers = None + if len(tup) == 2: + f, args, m = tup[0], tup[1], fname2def(tup[0]) + elif len(tup) == 3: + f, args, headers, m = tup[0], tup[1], [tup[2]], fname2def(tup[0]) + else: + f, args, headers, m = tup[0], tup[1], [tup[2]], fname2def(tup[3]) + if config.check_func(f, decl=False, call=True, call_args=args, + headers=headers): + moredefs.append((m, 1)) + + for dec, fn in OPTIONAL_FUNCTION_ATTRIBUTES: + if config.check_gcc_function_attribute(dec, fn): + moredefs.append((fname2def(fn), 1)) + if fn == 'attribute_target_avx512f': + # GH-14787: Work around GCC<8.4 bug when compiling with AVX512 + # support on Windows-based platforms + if (sys.platform in ('win32', 'cygwin') and + config.check_compiler_gcc() and + not config.check_gcc_version_at_least(8, 4)): + ext.extra_compile_args.extend( + ['-ffixed-xmm%s' % n for n in range(16, 32)]) + + for dec, fn, code, header in OPTIONAL_FUNCTION_ATTRIBUTES_WITH_INTRINSICS: + if config.check_gcc_function_attribute_with_intrinsics(dec, fn, code, + header): + moredefs.append((fname2def(fn), 1)) + + for fn in OPTIONAL_VARIABLE_ATTRIBUTES: + if config.check_gcc_variable_attribute(fn): + m = fn.replace("(", "_").replace(")", "_") + moredefs.append((fname2def(m), 1)) + + # C99 functions: float and long double versions + check_funcs(C99_FUNCS_SINGLE) + check_funcs(C99_FUNCS_EXTENDED) + +def check_complex(config, mathlibs): + priv = [] + pub = [] + + try: + if os.uname()[0] == "Interix": + warnings.warn("Disabling broken complex support. See #1365", stacklevel=2) + return priv, pub + except Exception: + # os.uname not available on all platforms. blanket except ugly but safe + pass + + # Check for complex support + st = config.check_header('complex.h') + if st: + priv.append(('HAVE_COMPLEX_H', 1)) + pub.append(('NPY_USE_C99_COMPLEX', 1)) + + for t in C99_COMPLEX_TYPES: + st = config.check_type(t, headers=["complex.h"]) + if st: + pub.append(('NPY_HAVE_%s' % type2def(t), 1)) + + def check_prec(prec): + flist = [f + prec for f in C99_COMPLEX_FUNCS] + decl = dict([(f, True) for f in flist]) + if not config.check_funcs_once(flist, call=decl, decl=decl, + libraries=mathlibs): + for f in flist: + if config.check_func(f, call=True, decl=True, + libraries=mathlibs): + priv.append((fname2def(f), 1)) + else: + priv.extend([(fname2def(f), 1) for f in flist]) + + check_prec('') + check_prec('f') + check_prec('l') + + return priv, pub + +def check_ieee_macros(config): + priv = [] + pub = [] + + macros = [] + + def _add_decl(f): + priv.append(fname2def("decl_%s" % f)) + pub.append('NPY_%s' % fname2def("decl_%s" % f)) + + # XXX: hack to circumvent cpp pollution from python: python put its + # config.h in the public namespace, so we have a clash for the common + # functions we test. We remove every function tested by python's + # autoconf, hoping their own test are correct + _macros = ["isnan", "isinf", "signbit", "isfinite"] + for f in _macros: + py_symbol = fname2def("decl_%s" % f) + already_declared = config.check_decl(py_symbol, + headers=["Python.h", "math.h"]) + if already_declared: + if config.check_macro_true(py_symbol, + headers=["Python.h", "math.h"]): + pub.append('NPY_%s' % fname2def("decl_%s" % f)) + else: + macros.append(f) + # Normally, isnan and isinf are macro (C99), but some platforms only have + # func, or both func and macro version. Check for macro only, and define + # replacement ones if not found. + # Note: including Python.h is necessary because it modifies some math.h + # definitions + for f in macros: + st = config.check_decl(f, headers=["Python.h", "math.h"]) + if st: + _add_decl(f) + + return priv, pub + +def check_types(config_cmd, ext, build_dir): + private_defines = [] + public_defines = [] + + # Expected size (in number of bytes) for each type. This is an + # optimization: those are only hints, and an exhaustive search for the size + # is done if the hints are wrong. + expected = {'short': [2], 'int': [4], 'long': [8, 4], + 'float': [4], 'double': [8], 'long double': [16, 12, 8], + 'Py_intptr_t': [8, 4], 'PY_LONG_LONG': [8], 'long long': [8], + 'off_t': [8, 4]} + + # Check we have the python header (-dev* packages on Linux) + result = config_cmd.check_header('Python.h') + if not result: + python = 'python' + if '__pypy__' in sys.builtin_module_names: + python = 'pypy' + raise SystemError( + "Cannot compile 'Python.h'. Perhaps you need to " + "install {0}-dev|{0}-devel.".format(python)) + res = config_cmd.check_header("endian.h") + if res: + private_defines.append(('HAVE_ENDIAN_H', 1)) + public_defines.append(('NPY_HAVE_ENDIAN_H', 1)) + res = config_cmd.check_header("sys/endian.h") + if res: + private_defines.append(('HAVE_SYS_ENDIAN_H', 1)) + public_defines.append(('NPY_HAVE_SYS_ENDIAN_H', 1)) + + # Check basic types sizes + for type in ('short', 'int', 'long'): + res = config_cmd.check_decl("SIZEOF_%s" % sym2def(type), headers=["Python.h"]) + if res: + public_defines.append(('NPY_SIZEOF_%s' % sym2def(type), "SIZEOF_%s" % sym2def(type))) + else: + res = config_cmd.check_type_size(type, expected=expected[type]) + if res >= 0: + public_defines.append(('NPY_SIZEOF_%s' % sym2def(type), '%d' % res)) + else: + raise SystemError("Checking sizeof (%s) failed !" % type) + + for type in ('float', 'double', 'long double'): + already_declared = config_cmd.check_decl("SIZEOF_%s" % sym2def(type), + headers=["Python.h"]) + res = config_cmd.check_type_size(type, expected=expected[type]) + if res >= 0: + public_defines.append(('NPY_SIZEOF_%s' % sym2def(type), '%d' % res)) + if not already_declared and not type == 'long double': + private_defines.append(('SIZEOF_%s' % sym2def(type), '%d' % res)) + else: + raise SystemError("Checking sizeof (%s) failed !" % type) + + # Compute size of corresponding complex type: used to check that our + # definition is binary compatible with C99 complex type (check done at + # build time in npy_common.h) + complex_def = "struct {%s __x; %s __y;}" % (type, type) + res = config_cmd.check_type_size(complex_def, + expected=[2 * x for x in expected[type]]) + if res >= 0: + public_defines.append(('NPY_SIZEOF_COMPLEX_%s' % sym2def(type), '%d' % res)) + else: + raise SystemError("Checking sizeof (%s) failed !" % complex_def) + + for type in ('Py_intptr_t', 'off_t'): + res = config_cmd.check_type_size(type, headers=["Python.h"], + library_dirs=[pythonlib_dir()], + expected=expected[type]) + + if res >= 0: + private_defines.append(('SIZEOF_%s' % sym2def(type), '%d' % res)) + public_defines.append(('NPY_SIZEOF_%s' % sym2def(type), '%d' % res)) + else: + raise SystemError("Checking sizeof (%s) failed !" % type) + + # We check declaration AND type because that's how distutils does it. + if config_cmd.check_decl('PY_LONG_LONG', headers=['Python.h']): + res = config_cmd.check_type_size('PY_LONG_LONG', headers=['Python.h'], + library_dirs=[pythonlib_dir()], + expected=expected['PY_LONG_LONG']) + if res >= 0: + private_defines.append(('SIZEOF_%s' % sym2def('PY_LONG_LONG'), '%d' % res)) + public_defines.append(('NPY_SIZEOF_%s' % sym2def('PY_LONG_LONG'), '%d' % res)) + else: + raise SystemError("Checking sizeof (%s) failed !" % 'PY_LONG_LONG') + + res = config_cmd.check_type_size('long long', + expected=expected['long long']) + if res >= 0: + #private_defines.append(('SIZEOF_%s' % sym2def('long long'), '%d' % res)) + public_defines.append(('NPY_SIZEOF_%s' % sym2def('long long'), '%d' % res)) + else: + raise SystemError("Checking sizeof (%s) failed !" % 'long long') + + if not config_cmd.check_decl('CHAR_BIT', headers=['Python.h']): + raise RuntimeError( + "Config wo CHAR_BIT is not supported" + ", please contact the maintainers") + + return private_defines, public_defines + +def check_mathlib(config_cmd): + # Testing the C math library + mathlibs = [] + mathlibs_choices = [[], ['m'], ['cpml']] + mathlib = os.environ.get('MATHLIB') + if mathlib: + mathlibs_choices.insert(0, mathlib.split(',')) + for libs in mathlibs_choices: + if config_cmd.check_func("exp", libraries=libs, decl=True, call=True): + mathlibs = libs + break + else: + raise EnvironmentError("math library missing; rerun " + "setup.py after setting the " + "MATHLIB env variable") + return mathlibs + +def visibility_define(config): + """Return the define value to use for NPY_VISIBILITY_HIDDEN (may be empty + string).""" + hide = '__attribute__((visibility("hidden")))' + if config.check_gcc_function_attribute(hide, 'hideme'): + return hide + else: + return '' + +def configuration(parent_package='',top_path=None): + from numpy.distutils.misc_util import Configuration, dot_join + from numpy.distutils.system_info import (get_info, blas_opt_info, + lapack_opt_info) + + # Accelerate is buggy, disallow it. See also numpy/linalg/setup.py + for opt_order in (blas_opt_info.blas_order, lapack_opt_info.lapack_order): + if 'accelerate' in opt_order: + opt_order.remove('accelerate') + + config = Configuration('core', parent_package, top_path) + local_dir = config.local_path + codegen_dir = join(local_dir, 'code_generators') + + if is_released(config): + warnings.simplefilter('error', MismatchCAPIWarning) + + # Check whether we have a mismatch between the set C API VERSION and the + # actual C API VERSION + check_api_version(C_API_VERSION, codegen_dir) + + generate_umath_py = join(codegen_dir, 'generate_umath.py') + n = dot_join(config.name, 'generate_umath') + generate_umath = npy_load_module('_'.join(n.split('.')), + generate_umath_py, ('.py', 'U', 1)) + + header_dir = 'include/numpy' # this is relative to config.path_in_package + + cocache = CallOnceOnly() + + def generate_config_h(ext, build_dir): + target = join(build_dir, header_dir, 'config.h') + d = os.path.dirname(target) + if not os.path.exists(d): + os.makedirs(d) + + if newer(__file__, target): + config_cmd = config.get_config_cmd() + log.info('Generating %s', target) + + # Check sizeof + moredefs, ignored = cocache.check_types(config_cmd, ext, build_dir) + + # Check math library and C99 math funcs availability + mathlibs = check_mathlib(config_cmd) + moredefs.append(('MATHLIB', ','.join(mathlibs))) + + check_math_capabilities(config_cmd, ext, moredefs, mathlibs) + moredefs.extend(cocache.check_ieee_macros(config_cmd)[0]) + moredefs.extend(cocache.check_complex(config_cmd, mathlibs)[0]) + + # Signal check + if is_npy_no_signal(): + moredefs.append('__NPY_PRIVATE_NO_SIGNAL') + + # Windows checks + if sys.platform == 'win32' or os.name == 'nt': + win32_checks(moredefs) + + # C99 restrict keyword + moredefs.append(('NPY_RESTRICT', config_cmd.check_restrict())) + + # Inline check + inline = config_cmd.check_inline() + + # Use relaxed stride checking + if NPY_RELAXED_STRIDES_CHECKING: + moredefs.append(('NPY_RELAXED_STRIDES_CHECKING', 1)) + + # Use bogus stride debug aid when relaxed strides are enabled + if NPY_RELAXED_STRIDES_DEBUG: + moredefs.append(('NPY_RELAXED_STRIDES_DEBUG', 1)) + + # Use the new experimental casting implementation in NumPy 1.20: + if NPY_USE_NEW_CASTINGIMPL: + moredefs.append(('NPY_USE_NEW_CASTINGIMPL', 1)) + + # Get long double representation + rep = check_long_double_representation(config_cmd) + moredefs.append(('HAVE_LDOUBLE_%s' % rep, 1)) + + if check_for_right_shift_internal_compiler_error(config_cmd): + moredefs.append('NPY_DO_NOT_OPTIMIZE_LONG_right_shift') + moredefs.append('NPY_DO_NOT_OPTIMIZE_ULONG_right_shift') + moredefs.append('NPY_DO_NOT_OPTIMIZE_LONGLONG_right_shift') + moredefs.append('NPY_DO_NOT_OPTIMIZE_ULONGLONG_right_shift') + + # Generate the config.h file from moredefs + with open(target, 'w') as target_f: + for d in moredefs: + if isinstance(d, str): + target_f.write('#define %s\n' % (d)) + else: + target_f.write('#define %s %s\n' % (d[0], d[1])) + + # define inline to our keyword, or nothing + target_f.write('#ifndef __cplusplus\n') + if inline == 'inline': + target_f.write('/* #undef inline */\n') + else: + target_f.write('#define inline %s\n' % inline) + target_f.write('#endif\n') + + # add the guard to make sure config.h is never included directly, + # but always through npy_config.h + target_f.write(textwrap.dedent(""" + #ifndef _NPY_NPY_CONFIG_H_ + #error config.h should never be included directly, include npy_config.h instead + #endif + """)) + + log.info('File: %s' % target) + with open(target) as target_f: + log.info(target_f.read()) + log.info('EOF') + else: + mathlibs = [] + with open(target) as target_f: + for line in target_f: + s = '#define MATHLIB' + if line.startswith(s): + value = line[len(s):].strip() + if value: + mathlibs.extend(value.split(',')) + + # Ugly: this can be called within a library and not an extension, + # in which case there is no libraries attributes (and none is + # needed). + if hasattr(ext, 'libraries'): + ext.libraries.extend(mathlibs) + + incl_dir = os.path.dirname(target) + if incl_dir not in config.numpy_include_dirs: + config.numpy_include_dirs.append(incl_dir) + + return target + + def generate_numpyconfig_h(ext, build_dir): + """Depends on config.h: generate_config_h has to be called before !""" + # put common include directory in build_dir on search path + # allows using code generation in headers + config.add_include_dirs(join(build_dir, "src", "common")) + config.add_include_dirs(join(build_dir, "src", "npymath")) + + target = join(build_dir, header_dir, '_numpyconfig.h') + d = os.path.dirname(target) + if not os.path.exists(d): + os.makedirs(d) + if newer(__file__, target): + config_cmd = config.get_config_cmd() + log.info('Generating %s', target) + + # Check sizeof + ignored, moredefs = cocache.check_types(config_cmd, ext, build_dir) + + if is_npy_no_signal(): + moredefs.append(('NPY_NO_SIGNAL', 1)) + + if is_npy_no_smp(): + moredefs.append(('NPY_NO_SMP', 1)) + else: + moredefs.append(('NPY_NO_SMP', 0)) + + mathlibs = check_mathlib(config_cmd) + moredefs.extend(cocache.check_ieee_macros(config_cmd)[1]) + moredefs.extend(cocache.check_complex(config_cmd, mathlibs)[1]) + + if NPY_RELAXED_STRIDES_CHECKING: + moredefs.append(('NPY_RELAXED_STRIDES_CHECKING', 1)) + + if NPY_RELAXED_STRIDES_DEBUG: + moredefs.append(('NPY_RELAXED_STRIDES_DEBUG', 1)) + + # Check whether we can use inttypes (C99) formats + if config_cmd.check_decl('PRIdPTR', headers=['inttypes.h']): + moredefs.append(('NPY_USE_C99_FORMATS', 1)) + + # visibility check + hidden_visibility = visibility_define(config_cmd) + moredefs.append(('NPY_VISIBILITY_HIDDEN', hidden_visibility)) + + # Add the C API/ABI versions + moredefs.append(('NPY_ABI_VERSION', '0x%.8X' % C_ABI_VERSION)) + moredefs.append(('NPY_API_VERSION', '0x%.8X' % C_API_VERSION)) + + # Add moredefs to header + with open(target, 'w') as target_f: + for d in moredefs: + if isinstance(d, str): + target_f.write('#define %s\n' % (d)) + else: + target_f.write('#define %s %s\n' % (d[0], d[1])) + + # Define __STDC_FORMAT_MACROS + target_f.write(textwrap.dedent(""" + #ifndef __STDC_FORMAT_MACROS + #define __STDC_FORMAT_MACROS 1 + #endif + """)) + + # Dump the numpyconfig.h header to stdout + log.info('File: %s' % target) + with open(target) as target_f: + log.info(target_f.read()) + log.info('EOF') + config.add_data_files((header_dir, target)) + return target + + def generate_api_func(module_name): + def generate_api(ext, build_dir): + script = join(codegen_dir, module_name + '.py') + sys.path.insert(0, codegen_dir) + try: + m = __import__(module_name) + log.info('executing %s', script) + h_file, c_file, doc_file = m.generate_api(os.path.join(build_dir, header_dir)) + finally: + del sys.path[0] + config.add_data_files((header_dir, h_file), + (header_dir, doc_file)) + return (h_file,) + return generate_api + + generate_numpy_api = generate_api_func('generate_numpy_api') + generate_ufunc_api = generate_api_func('generate_ufunc_api') + + config.add_include_dirs(join(local_dir, "src", "common")) + config.add_include_dirs(join(local_dir, "src")) + config.add_include_dirs(join(local_dir)) + + config.add_data_dir('include/numpy') + config.add_include_dirs(join('src', 'npymath')) + config.add_include_dirs(join('src', 'multiarray')) + config.add_include_dirs(join('src', 'umath')) + config.add_include_dirs(join('src', 'npysort')) + config.add_include_dirs(join('src', '_simd')) + + config.add_define_macros([("NPY_INTERNAL_BUILD", "1")]) # this macro indicates that Numpy build is in process + config.add_define_macros([("HAVE_NPY_CONFIG_H", "1")]) + if sys.platform[:3] == "aix": + config.add_define_macros([("_LARGE_FILES", None)]) + else: + config.add_define_macros([("_FILE_OFFSET_BITS", "64")]) + config.add_define_macros([('_LARGEFILE_SOURCE', '1')]) + config.add_define_macros([('_LARGEFILE64_SOURCE', '1')]) + + config.numpy_include_dirs.extend(config.paths('include')) + + deps = [join('src', 'npymath', '_signbit.c'), + join('include', 'numpy', '*object.h'), + join(codegen_dir, 'genapi.py'), + ] + + ####################################################################### + # npymath library # + ####################################################################### + + subst_dict = dict([("sep", os.path.sep), ("pkgname", "numpy.core")]) + + def get_mathlib_info(*args): + # Another ugly hack: the mathlib info is known once build_src is run, + # but we cannot use add_installed_pkg_config here either, so we only + # update the substitution dictionary during npymath build + config_cmd = config.get_config_cmd() + + # Check that the toolchain works, to fail early if it doesn't + # (avoid late errors with MATHLIB which are confusing if the + # compiler does not work). + st = config_cmd.try_link('int main(void) { return 0;}') + if not st: + # rerun the failing command in verbose mode + config_cmd.compiler.verbose = True + config_cmd.try_link('int main(void) { return 0;}') + raise RuntimeError("Broken toolchain: cannot link a simple C program") + mlibs = check_mathlib(config_cmd) + + posix_mlib = ' '.join(['-l%s' % l for l in mlibs]) + msvc_mlib = ' '.join(['%s.lib' % l for l in mlibs]) + subst_dict["posix_mathlib"] = posix_mlib + subst_dict["msvc_mathlib"] = msvc_mlib + + npymath_sources = [join('src', 'npymath', 'npy_math_internal.h.src'), + join('src', 'npymath', 'npy_math.c'), + join('src', 'npymath', 'ieee754.c.src'), + join('src', 'npymath', 'npy_math_complex.c.src'), + join('src', 'npymath', 'halffloat.c') + ] + + # Must be true for CRT compilers but not MinGW/cygwin. See gh-9977. + # Intel and Clang also don't seem happy with /GL + is_msvc = (platform.platform().startswith('Windows') and + platform.python_compiler().startswith('MS')) + config.add_installed_library('npymath', + sources=npymath_sources + [get_mathlib_info], + install_dir='lib', + build_info={ + 'include_dirs' : [], # empty list required for creating npy_math_internal.h + 'extra_compiler_args' : (['/GL-'] if is_msvc else []), + }) + config.add_npy_pkg_config("npymath.ini.in", "lib/npy-pkg-config", + subst_dict) + config.add_npy_pkg_config("mlib.ini.in", "lib/npy-pkg-config", + subst_dict) + + ####################################################################### + # multiarray_tests module # + ####################################################################### + + config.add_extension('_multiarray_tests', + sources=[join('src', 'multiarray', '_multiarray_tests.c.src'), + join('src', 'common', 'mem_overlap.c')], + depends=[join('src', 'common', 'mem_overlap.h'), + join('src', 'common', 'npy_extint128.h')], + libraries=['npymath']) + + ####################################################################### + # _multiarray_umath module - common part # + ####################################################################### + + common_deps = [ + join('src', 'common', 'array_assign.h'), + join('src', 'common', 'binop_override.h'), + join('src', 'common', 'cblasfuncs.h'), + join('src', 'common', 'lowlevel_strided_loops.h'), + join('src', 'common', 'mem_overlap.h'), + join('src', 'common', 'npy_cblas.h'), + join('src', 'common', 'npy_config.h'), + join('src', 'common', 'npy_ctypes.h'), + join('src', 'common', 'npy_extint128.h'), + join('src', 'common', 'npy_import.h'), + join('src', 'common', 'npy_longdouble.h'), + join('src', 'common', 'templ_common.h.src'), + join('src', 'common', 'ucsnarrow.h'), + join('src', 'common', 'ufunc_override.h'), + join('src', 'common', 'umathmodule.h'), + join('src', 'common', 'numpyos.h'), + join('src', 'common', 'npy_cpu_dispatch.h'), + join('src', 'common', 'simd', 'simd.h'), + ] + + common_src = [ + join('src', 'common', 'array_assign.c'), + join('src', 'common', 'mem_overlap.c'), + join('src', 'common', 'npy_longdouble.c'), + join('src', 'common', 'templ_common.h.src'), + join('src', 'common', 'ucsnarrow.c'), + join('src', 'common', 'ufunc_override.c'), + join('src', 'common', 'numpyos.c'), + join('src', 'common', 'npy_cpu_features.c.src'), + ] + + if os.environ.get('NPY_USE_BLAS_ILP64', "0") != "0": + blas_info = get_info('blas_ilp64_opt', 2) + else: + blas_info = get_info('blas_opt', 0) + + have_blas = blas_info and ('HAVE_CBLAS', None) in blas_info.get('define_macros', []) + + if have_blas: + extra_info = blas_info + # These files are also in MANIFEST.in so that they are always in + # the source distribution independently of HAVE_CBLAS. + common_src.extend([join('src', 'common', 'cblasfuncs.c'), + join('src', 'common', 'python_xerbla.c'), + ]) + else: + extra_info = {} + + ####################################################################### + # _multiarray_umath module - multiarray part # + ####################################################################### + + multiarray_deps = [ + join('src', 'multiarray', 'abstractdtypes.h'), + join('src', 'multiarray', 'arrayobject.h'), + join('src', 'multiarray', 'arraytypes.h'), + join('src', 'multiarray', 'arrayfunction_override.h'), + join('src', 'multiarray', 'array_coercion.h'), + join('src', 'multiarray', 'array_method.h'), + join('src', 'multiarray', 'npy_buffer.h'), + join('src', 'multiarray', 'calculation.h'), + join('src', 'multiarray', 'common.h'), + join('src', 'multiarray', 'convert_datatype.h'), + join('src', 'multiarray', 'convert.h'), + join('src', 'multiarray', 'conversion_utils.h'), + join('src', 'multiarray', 'ctors.h'), + join('src', 'multiarray', 'descriptor.h'), + join('src', 'multiarray', 'dtypemeta.h'), + join('src', 'multiarray', 'dragon4.h'), + join('src', 'multiarray', 'einsum_debug.h'), + join('src', 'multiarray', 'einsum_sumprod.h'), + join('src', 'multiarray', 'getset.h'), + join('src', 'multiarray', 'hashdescr.h'), + join('src', 'multiarray', 'iterators.h'), + join('src', 'multiarray', 'legacy_dtype_implementation.h'), + join('src', 'multiarray', 'mapping.h'), + join('src', 'multiarray', 'methods.h'), + join('src', 'multiarray', 'multiarraymodule.h'), + join('src', 'multiarray', 'nditer_impl.h'), + join('src', 'multiarray', 'number.h'), + join('src', 'multiarray', 'refcount.h'), + join('src', 'multiarray', 'scalartypes.h'), + join('src', 'multiarray', 'sequence.h'), + join('src', 'multiarray', 'shape.h'), + join('src', 'multiarray', 'strfuncs.h'), + join('src', 'multiarray', 'typeinfo.h'), + join('src', 'multiarray', 'usertypes.h'), + join('src', 'multiarray', 'vdot.h'), + join('include', 'numpy', 'arrayobject.h'), + join('include', 'numpy', '_neighborhood_iterator_imp.h'), + join('include', 'numpy', 'npy_endian.h'), + join('include', 'numpy', 'arrayscalars.h'), + join('include', 'numpy', 'noprefix.h'), + join('include', 'numpy', 'npy_interrupt.h'), + join('include', 'numpy', 'npy_3kcompat.h'), + join('include', 'numpy', 'npy_math.h'), + join('include', 'numpy', 'halffloat.h'), + join('include', 'numpy', 'npy_common.h'), + join('include', 'numpy', 'npy_os.h'), + join('include', 'numpy', 'utils.h'), + join('include', 'numpy', 'ndarrayobject.h'), + join('include', 'numpy', 'npy_cpu.h'), + join('include', 'numpy', 'numpyconfig.h'), + join('include', 'numpy', 'ndarraytypes.h'), + join('include', 'numpy', 'npy_1_7_deprecated_api.h'), + # add library sources as distuils does not consider libraries + # dependencies + ] + npymath_sources + + multiarray_src = [ + join('src', 'multiarray', 'abstractdtypes.c'), + join('src', 'multiarray', 'alloc.c'), + join('src', 'multiarray', 'arrayobject.c'), + join('src', 'multiarray', 'arraytypes.c.src'), + join('src', 'multiarray', 'array_coercion.c'), + join('src', 'multiarray', 'array_method.c'), + join('src', 'multiarray', 'array_assign_scalar.c'), + join('src', 'multiarray', 'array_assign_array.c'), + join('src', 'multiarray', 'arrayfunction_override.c'), + join('src', 'multiarray', 'buffer.c'), + join('src', 'multiarray', 'calculation.c'), + join('src', 'multiarray', 'compiled_base.c'), + join('src', 'multiarray', 'common.c'), + join('src', 'multiarray', 'convert.c'), + join('src', 'multiarray', 'convert_datatype.c'), + join('src', 'multiarray', 'conversion_utils.c'), + join('src', 'multiarray', 'ctors.c'), + join('src', 'multiarray', 'datetime.c'), + join('src', 'multiarray', 'datetime_strings.c'), + join('src', 'multiarray', 'datetime_busday.c'), + join('src', 'multiarray', 'datetime_busdaycal.c'), + join('src', 'multiarray', 'descriptor.c'), + join('src', 'multiarray', 'dtypemeta.c'), + join('src', 'multiarray', 'dragon4.c'), + join('src', 'multiarray', 'dtype_transfer.c'), + join('src', 'multiarray', 'einsum.c.src'), + join('src', 'multiarray', 'einsum_sumprod.c.src'), + join('src', 'multiarray', 'flagsobject.c'), + join('src', 'multiarray', 'getset.c'), + join('src', 'multiarray', 'hashdescr.c'), + join('src', 'multiarray', 'item_selection.c'), + join('src', 'multiarray', 'iterators.c'), + join('src', 'multiarray', 'legacy_dtype_implementation.c'), + join('src', 'multiarray', 'lowlevel_strided_loops.c.src'), + join('src', 'multiarray', 'mapping.c'), + join('src', 'multiarray', 'methods.c'), + join('src', 'multiarray', 'multiarraymodule.c'), + join('src', 'multiarray', 'nditer_templ.c.src'), + join('src', 'multiarray', 'nditer_api.c'), + join('src', 'multiarray', 'nditer_constr.c'), + join('src', 'multiarray', 'nditer_pywrap.c'), + join('src', 'multiarray', 'number.c'), + join('src', 'multiarray', 'refcount.c'), + join('src', 'multiarray', 'sequence.c'), + join('src', 'multiarray', 'shape.c'), + join('src', 'multiarray', 'scalarapi.c'), + join('src', 'multiarray', 'scalartypes.c.src'), + join('src', 'multiarray', 'strfuncs.c'), + join('src', 'multiarray', 'temp_elide.c'), + join('src', 'multiarray', 'typeinfo.c'), + join('src', 'multiarray', 'usertypes.c'), + join('src', 'multiarray', 'vdot.c'), + join('src', 'common', 'npy_sort.h.src'), + join('src', 'npysort', 'quicksort.c.src'), + join('src', 'npysort', 'mergesort.c.src'), + join('src', 'npysort', 'timsort.c.src'), + join('src', 'npysort', 'heapsort.c.src'), + join('src', 'npysort', 'radixsort.c.src'), + join('src', 'common', 'npy_partition.h.src'), + join('src', 'npysort', 'selection.c.src'), + join('src', 'common', 'npy_binsearch.h.src'), + join('src', 'npysort', 'binsearch.c.src'), + ] + + ####################################################################### + # _multiarray_umath module - umath part # + ####################################################################### + + def generate_umath_c(ext, build_dir): + target = join(build_dir, header_dir, '__umath_generated.c') + dir = os.path.dirname(target) + if not os.path.exists(dir): + os.makedirs(dir) + script = generate_umath_py + if newer(script, target): + with open(target, 'w') as f: + f.write(generate_umath.make_code(generate_umath.defdict, + generate_umath.__file__)) + return [] + + umath_src = [ + join('src', 'umath', 'umathmodule.c'), + join('src', 'umath', 'reduction.c'), + join('src', 'umath', 'funcs.inc.src'), + join('src', 'umath', 'simd.inc.src'), + join('src', 'umath', 'loops.h.src'), + join('src', 'umath', 'loops.c.src'), + join('src', 'umath', 'loops_unary_fp.dispatch.c.src'), + join('src', 'umath', 'matmul.h.src'), + join('src', 'umath', 'matmul.c.src'), + join('src', 'umath', 'clip.h.src'), + join('src', 'umath', 'clip.c.src'), + join('src', 'umath', 'ufunc_object.c'), + join('src', 'umath', 'extobj.c'), + join('src', 'umath', 'scalarmath.c.src'), + join('src', 'umath', 'ufunc_type_resolution.c'), + join('src', 'umath', 'override.c'), + ] + + umath_deps = [ + generate_umath_py, + join('include', 'numpy', 'npy_math.h'), + join('include', 'numpy', 'halffloat.h'), + join('src', 'multiarray', 'common.h'), + join('src', 'multiarray', 'number.h'), + join('src', 'common', 'templ_common.h.src'), + join('src', 'umath', 'simd.inc.src'), + join('src', 'umath', 'override.h'), + join(codegen_dir, 'generate_ufunc_api.py'), + ] + + config.add_extension('_multiarray_umath', + sources=multiarray_src + umath_src + + common_src + + [generate_config_h, + generate_numpyconfig_h, + generate_numpy_api, + join(codegen_dir, 'generate_numpy_api.py'), + join('*.py'), + generate_umath_c, + generate_ufunc_api, + ], + depends=deps + multiarray_deps + umath_deps + + common_deps, + libraries=['npymath'], + extra_info=extra_info) + + ####################################################################### + # umath_tests module # + ####################################################################### + + config.add_extension('_umath_tests', sources=[ + join('src', 'umath', '_umath_tests.c.src'), + join('src', 'umath', '_umath_tests.dispatch.c'), + join('src', 'common', 'npy_cpu_features.c.src'), + ]) + + ####################################################################### + # custom rational dtype module # + ####################################################################### + + config.add_extension('_rational_tests', + sources=[join('src', 'umath', '_rational_tests.c.src')]) + + ####################################################################### + # struct_ufunc_test module # + ####################################################################### + + config.add_extension('_struct_ufunc_tests', + sources=[join('src', 'umath', '_struct_ufunc_tests.c.src')]) + + + ####################################################################### + # operand_flag_tests module # + ####################################################################### + + config.add_extension('_operand_flag_tests', + sources=[join('src', 'umath', '_operand_flag_tests.c.src')]) + + ####################################################################### + # SIMD module # + ####################################################################### + + config.add_extension('_simd', sources=[ + join('src', 'common', 'npy_cpu_features.c.src'), + join('src', '_simd', '_simd.c'), + join('src', '_simd', '_simd_inc.h.src'), + join('src', '_simd', '_simd_data.inc.src'), + join('src', '_simd', '_simd.dispatch.c.src'), + ], depends=[ + join('src', 'common', 'npy_cpu_dispatch.h'), + join('src', 'common', 'simd', 'simd.h'), + join('src', '_simd', '_simd.h'), + join('src', '_simd', '_simd_inc.h.src'), + join('src', '_simd', '_simd_data.inc.src'), + join('src', '_simd', '_simd_arg.inc'), + join('src', '_simd', '_simd_convert.inc'), + join('src', '_simd', '_simd_easyintrin.inc'), + join('src', '_simd', '_simd_vector.inc'), + ]) + + config.add_subpackage('tests') + config.add_data_dir('tests/data') + config.add_data_dir('tests/examples') + config.add_data_files('*.pyi') + + config.make_svn_version_py() + + return config + +if __name__ == '__main__': + from numpy.distutils.core import setup + setup(configuration=configuration) diff --git a/venv/Lib/site-packages/numpy/core/setup_common.py b/venv/Lib/site-packages/numpy/core/setup_common.py new file mode 100644 index 0000000..ba3e215 --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/setup_common.py @@ -0,0 +1,449 @@ +# Code common to build tools +import sys +import warnings +import copy +import textwrap + +from numpy.distutils.misc_util import mingw32 + + +#------------------- +# Versioning support +#------------------- +# How to change C_API_VERSION ? +# - increase C_API_VERSION value +# - record the hash for the new C API with the cversions.py script +# and add the hash to cversions.txt +# The hash values are used to remind developers when the C API number was not +# updated - generates a MismatchCAPIWarning warning which is turned into an +# exception for released version. + +# Binary compatibility version number. This number is increased whenever the +# C-API is changed such that binary compatibility is broken, i.e. whenever a +# recompile of extension modules is needed. +C_ABI_VERSION = 0x01000009 + +# Minor API version. This number is increased whenever a change is made to the +# C-API -- whether it breaks binary compatibility or not. Some changes, such +# as adding a function pointer to the end of the function table, can be made +# without breaking binary compatibility. In this case, only the C_API_VERSION +# (*not* C_ABI_VERSION) would be increased. Whenever binary compatibility is +# broken, both C_API_VERSION and C_ABI_VERSION should be increased. +# +# 0x00000008 - 1.7.x +# 0x00000009 - 1.8.x +# 0x00000009 - 1.9.x +# 0x0000000a - 1.10.x +# 0x0000000a - 1.11.x +# 0x0000000a - 1.12.x +# 0x0000000b - 1.13.x +# 0x0000000c - 1.14.x +# 0x0000000c - 1.15.x +# 0x0000000d - 1.16.x +# 0x0000000d - 1.19.x +# 0x0000000e - 1.20.x +C_API_VERSION = 0x0000000e + +class MismatchCAPIWarning(Warning): + pass + +def is_released(config): + """Return True if a released version of numpy is detected.""" + from distutils.version import LooseVersion + + v = config.get_version('../version.py') + if v is None: + raise ValueError("Could not get version") + pv = LooseVersion(vstring=v).version + if len(pv) > 3: + return False + return True + +def get_api_versions(apiversion, codegen_dir): + """ + Return current C API checksum and the recorded checksum. + + Return current C API checksum and the recorded checksum for the given + version of the C API version. + + """ + # Compute the hash of the current API as defined in the .txt files in + # code_generators + sys.path.insert(0, codegen_dir) + try: + m = __import__('genapi') + numpy_api = __import__('numpy_api') + curapi_hash = m.fullapi_hash(numpy_api.full_api) + apis_hash = m.get_versions_hash() + finally: + del sys.path[0] + + return curapi_hash, apis_hash[apiversion] + +def check_api_version(apiversion, codegen_dir): + """Emits a MismatchCAPIWarning if the C API version needs updating.""" + curapi_hash, api_hash = get_api_versions(apiversion, codegen_dir) + + # If different hash, it means that the api .txt files in + # codegen_dir have been updated without the API version being + # updated. Any modification in those .txt files should be reflected + # in the api and eventually abi versions. + # To compute the checksum of the current API, use numpy/core/cversions.py + if not curapi_hash == api_hash: + msg = ("API mismatch detected, the C API version " + "numbers have to be updated. Current C api version is %d, " + "with checksum %s, but recorded checksum for C API version %d " + "in core/codegen_dir/cversions.txt is %s. If functions were " + "added in the C API, you have to update C_API_VERSION in %s." + ) + warnings.warn(msg % (apiversion, curapi_hash, apiversion, api_hash, + __file__), + MismatchCAPIWarning, stacklevel=2) +# Mandatory functions: if not found, fail the build +MANDATORY_FUNCS = ["sin", "cos", "tan", "sinh", "cosh", "tanh", "fabs", + "floor", "ceil", "sqrt", "log10", "log", "exp", "asin", + "acos", "atan", "fmod", 'modf', 'frexp', 'ldexp'] + +# Standard functions which may not be available and for which we have a +# replacement implementation. Note that some of these are C99 functions. +OPTIONAL_STDFUNCS = ["expm1", "log1p", "acosh", "asinh", "atanh", + "rint", "trunc", "exp2", "log2", "hypot", "atan2", "pow", + "copysign", "nextafter", "ftello", "fseeko", + "strtoll", "strtoull", "cbrt", "strtold_l", "fallocate", + "backtrace", "madvise"] + + +OPTIONAL_HEADERS = [ +# sse headers only enabled automatically on amd64/x32 builds + "xmmintrin.h", # SSE + "emmintrin.h", # SSE2 + "immintrin.h", # AVX + "features.h", # for glibc version linux + "xlocale.h", # see GH#8367 + "dlfcn.h", # dladdr + "sys/mman.h", #madvise +] + +# optional gcc compiler builtins and their call arguments and optional a +# required header and definition name (HAVE_ prepended) +# call arguments are required as the compiler will do strict signature checking +OPTIONAL_INTRINSICS = [("__builtin_isnan", '5.'), + ("__builtin_isinf", '5.'), + ("__builtin_isfinite", '5.'), + ("__builtin_bswap32", '5u'), + ("__builtin_bswap64", '5u'), + ("__builtin_expect", '5, 0'), + ("__builtin_mul_overflow", '5, 5, (int*)5'), + # MMX only needed for icc, but some clangs don't have it + ("_m_from_int64", '0', "emmintrin.h"), + ("_mm_load_ps", '(float*)0', "xmmintrin.h"), # SSE + ("_mm_prefetch", '(float*)0, _MM_HINT_NTA', + "xmmintrin.h"), # SSE + ("_mm_load_pd", '(double*)0', "emmintrin.h"), # SSE2 + ("__builtin_prefetch", "(float*)0, 0, 3"), + # check that the linker can handle avx + ("__asm__ volatile", '"vpand %xmm1, %xmm2, %xmm3"', + "stdio.h", "LINK_AVX"), + ("__asm__ volatile", '"vpand %ymm1, %ymm2, %ymm3"', + "stdio.h", "LINK_AVX2"), + ("__asm__ volatile", '"vpaddd %zmm1, %zmm2, %zmm3"', + "stdio.h", "LINK_AVX512F"), + ("__asm__ volatile", '"vfpclasspd $0x40, %zmm15, %k6\\n"\ + "vmovdqu8 %xmm0, %xmm1\\n"\ + "vpbroadcastmb2q %k0, %xmm0\\n"', + "stdio.h", "LINK_AVX512_SKX"), + ("__asm__ volatile", '"xgetbv"', "stdio.h", "XGETBV"), + ] + +# function attributes +# tested via "int %s %s(void *);" % (attribute, name) +# function name will be converted to HAVE_ preprocessor macro +OPTIONAL_FUNCTION_ATTRIBUTES = [('__attribute__((optimize("unroll-loops")))', + 'attribute_optimize_unroll_loops'), + ('__attribute__((optimize("O3")))', + 'attribute_optimize_opt_3'), + ('__attribute__((nonnull (1)))', + 'attribute_nonnull'), + ('__attribute__((target ("avx")))', + 'attribute_target_avx'), + ('__attribute__((target ("avx2")))', + 'attribute_target_avx2'), + ('__attribute__((target ("avx512f")))', + 'attribute_target_avx512f'), + ('__attribute__((target ("avx512f,avx512dq,avx512bw,avx512vl,avx512cd")))', + 'attribute_target_avx512_skx'), + ] + +# function attributes with intrinsics +# To ensure your compiler can compile avx intrinsics with just the attributes +# gcc 4.8.4 support attributes but not with intrisics +# tested via "#include<%s> int %s %s(void *){code; return 0;};" % (header, attribute, name, code) +# function name will be converted to HAVE_ preprocessor macro +# The _mm512_castps_si512 instruction is specific check for AVX-512F support +# in gcc-4.9 which is missing a subset of intrinsics. See +# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61878 +OPTIONAL_FUNCTION_ATTRIBUTES_WITH_INTRINSICS = [('__attribute__((target("avx2,fma")))', + 'attribute_target_avx2_with_intrinsics', + '__m256 temp = _mm256_set1_ps(1.0); temp = \ + _mm256_fmadd_ps(temp, temp, temp)', + 'immintrin.h'), + ('__attribute__((target("avx512f")))', + 'attribute_target_avx512f_with_intrinsics', + '__m512i temp = _mm512_castps_si512(_mm512_set1_ps(1.0))', + 'immintrin.h'), + ('__attribute__((target ("avx512f,avx512dq,avx512bw,avx512vl,avx512cd")))', + 'attribute_target_avx512_skx_with_intrinsics', + '__mmask8 temp = _mm512_fpclass_pd_mask(_mm512_set1_pd(1.0), 0x01);\ + __m512i temp = _mm512_castps_si512(_mm512_set1_ps(1.0));\ + _mm_mask_storeu_epi8(NULL, 0xFF, _mm_broadcastmb_epi64(temp))', + 'immintrin.h'), + ] + +# variable attributes tested via "int %s a" % attribute +OPTIONAL_VARIABLE_ATTRIBUTES = ["__thread", "__declspec(thread)"] + +# Subset of OPTIONAL_STDFUNCS which may already have HAVE_* defined by Python.h +OPTIONAL_STDFUNCS_MAYBE = [ + "expm1", "log1p", "acosh", "atanh", "asinh", "hypot", "copysign", + "ftello", "fseeko" + ] + +# C99 functions: float and long double versions +C99_FUNCS = [ + "sin", "cos", "tan", "sinh", "cosh", "tanh", "fabs", "floor", "ceil", + "rint", "trunc", "sqrt", "log10", "log", "log1p", "exp", "expm1", + "asin", "acos", "atan", "asinh", "acosh", "atanh", "hypot", "atan2", + "pow", "fmod", "modf", 'frexp', 'ldexp', "exp2", "log2", "copysign", + "nextafter", "cbrt" + ] +C99_FUNCS_SINGLE = [f + 'f' for f in C99_FUNCS] +C99_FUNCS_EXTENDED = [f + 'l' for f in C99_FUNCS] +C99_COMPLEX_TYPES = [ + 'complex double', 'complex float', 'complex long double' + ] +C99_COMPLEX_FUNCS = [ + "cabs", "cacos", "cacosh", "carg", "casin", "casinh", "catan", + "catanh", "ccos", "ccosh", "cexp", "cimag", "clog", "conj", "cpow", + "cproj", "creal", "csin", "csinh", "csqrt", "ctan", "ctanh" + ] + +def fname2def(name): + return "HAVE_%s" % name.upper() + +def sym2def(symbol): + define = symbol.replace(' ', '') + return define.upper() + +def type2def(symbol): + define = symbol.replace(' ', '_') + return define.upper() + +# Code to detect long double representation taken from MPFR m4 macro +def check_long_double_representation(cmd): + cmd._check_compiler() + body = LONG_DOUBLE_REPRESENTATION_SRC % {'type': 'long double'} + + # Disable whole program optimization (the default on vs2015, with python 3.5+) + # which generates intermediary object files and prevents checking the + # float representation. + if sys.platform == "win32" and not mingw32(): + try: + cmd.compiler.compile_options.remove("/GL") + except (AttributeError, ValueError): + pass + + # Disable multi-file interprocedural optimization in the Intel compiler on Linux + # which generates intermediary object files and prevents checking the + # float representation. + elif (sys.platform != "win32" + and cmd.compiler.compiler_type.startswith('intel') + and '-ipo' in cmd.compiler.cc_exe): + newcompiler = cmd.compiler.cc_exe.replace(' -ipo', '') + cmd.compiler.set_executables( + compiler=newcompiler, + compiler_so=newcompiler, + compiler_cxx=newcompiler, + linker_exe=newcompiler, + linker_so=newcompiler + ' -shared' + ) + + # We need to use _compile because we need the object filename + src, obj = cmd._compile(body, None, None, 'c') + try: + ltype = long_double_representation(pyod(obj)) + return ltype + except ValueError: + # try linking to support CC="gcc -flto" or icc -ipo + # struct needs to be volatile so it isn't optimized away + # additionally "clang -flto" requires the foo struct to be used + body = body.replace('struct', 'volatile struct') + body += "int main(void) { return foo.before[0]; }\n" + src, obj = cmd._compile(body, None, None, 'c') + cmd.temp_files.append("_configtest") + cmd.compiler.link_executable([obj], "_configtest") + ltype = long_double_representation(pyod("_configtest")) + return ltype + finally: + cmd._clean() + +LONG_DOUBLE_REPRESENTATION_SRC = r""" +/* "before" is 16 bytes to ensure there's no padding between it and "x". + * We're not expecting any "long double" bigger than 16 bytes or with + * alignment requirements stricter than 16 bytes. */ +typedef %(type)s test_type; + +struct { + char before[16]; + test_type x; + char after[8]; +} foo = { + { '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', + '\001', '\043', '\105', '\147', '\211', '\253', '\315', '\357' }, + -123456789.0, + { '\376', '\334', '\272', '\230', '\166', '\124', '\062', '\020' } +}; +""" + +def pyod(filename): + """Python implementation of the od UNIX utility (od -b, more exactly). + + Parameters + ---------- + filename : str + name of the file to get the dump from. + + Returns + ------- + out : seq + list of lines of od output + + Note + ---- + We only implement enough to get the necessary information for long double + representation, this is not intended as a compatible replacement for od. + """ + out = [] + with open(filename, 'rb') as fid: + yo2 = [oct(o)[2:] for o in fid.read()] + for i in range(0, len(yo2), 16): + line = ['%07d' % int(oct(i)[2:])] + line.extend(['%03d' % int(c) for c in yo2[i:i+16]]) + out.append(" ".join(line)) + return out + + +_BEFORE_SEQ = ['000', '000', '000', '000', '000', '000', '000', '000', + '001', '043', '105', '147', '211', '253', '315', '357'] +_AFTER_SEQ = ['376', '334', '272', '230', '166', '124', '062', '020'] + +_IEEE_DOUBLE_BE = ['301', '235', '157', '064', '124', '000', '000', '000'] +_IEEE_DOUBLE_LE = _IEEE_DOUBLE_BE[::-1] +_INTEL_EXTENDED_12B = ['000', '000', '000', '000', '240', '242', '171', '353', + '031', '300', '000', '000'] +_INTEL_EXTENDED_16B = ['000', '000', '000', '000', '240', '242', '171', '353', + '031', '300', '000', '000', '000', '000', '000', '000'] +_MOTOROLA_EXTENDED_12B = ['300', '031', '000', '000', '353', '171', + '242', '240', '000', '000', '000', '000'] +_IEEE_QUAD_PREC_BE = ['300', '031', '326', '363', '105', '100', '000', '000', + '000', '000', '000', '000', '000', '000', '000', '000'] +_IEEE_QUAD_PREC_LE = _IEEE_QUAD_PREC_BE[::-1] +_IBM_DOUBLE_DOUBLE_BE = (['301', '235', '157', '064', '124', '000', '000', '000'] + + ['000'] * 8) +_IBM_DOUBLE_DOUBLE_LE = (['000', '000', '000', '124', '064', '157', '235', '301'] + + ['000'] * 8) + +def long_double_representation(lines): + """Given a binary dump as given by GNU od -b, look for long double + representation.""" + + # Read contains a list of 32 items, each item is a byte (in octal + # representation, as a string). We 'slide' over the output until read is of + # the form before_seq + content + after_sequence, where content is the long double + # representation: + # - content is 12 bytes: 80 bits Intel representation + # - content is 16 bytes: 80 bits Intel representation (64 bits) or quad precision + # - content is 8 bytes: same as double (not implemented yet) + read = [''] * 32 + saw = None + for line in lines: + # we skip the first word, as od -b output an index at the beginning of + # each line + for w in line.split()[1:]: + read.pop(0) + read.append(w) + + # If the end of read is equal to the after_sequence, read contains + # the long double + if read[-8:] == _AFTER_SEQ: + saw = copy.copy(read) + # if the content was 12 bytes, we only have 32 - 8 - 12 = 12 + # "before" bytes. In other words the first 4 "before" bytes went + # past the sliding window. + if read[:12] == _BEFORE_SEQ[4:]: + if read[12:-8] == _INTEL_EXTENDED_12B: + return 'INTEL_EXTENDED_12_BYTES_LE' + if read[12:-8] == _MOTOROLA_EXTENDED_12B: + return 'MOTOROLA_EXTENDED_12_BYTES_BE' + # if the content was 16 bytes, we are left with 32-8-16 = 16 + # "before" bytes, so 8 went past the sliding window. + elif read[:8] == _BEFORE_SEQ[8:]: + if read[8:-8] == _INTEL_EXTENDED_16B: + return 'INTEL_EXTENDED_16_BYTES_LE' + elif read[8:-8] == _IEEE_QUAD_PREC_BE: + return 'IEEE_QUAD_BE' + elif read[8:-8] == _IEEE_QUAD_PREC_LE: + return 'IEEE_QUAD_LE' + elif read[8:-8] == _IBM_DOUBLE_DOUBLE_LE: + return 'IBM_DOUBLE_DOUBLE_LE' + elif read[8:-8] == _IBM_DOUBLE_DOUBLE_BE: + return 'IBM_DOUBLE_DOUBLE_BE' + # if the content was 8 bytes, left with 32-8-8 = 16 bytes + elif read[:16] == _BEFORE_SEQ: + if read[16:-8] == _IEEE_DOUBLE_LE: + return 'IEEE_DOUBLE_LE' + elif read[16:-8] == _IEEE_DOUBLE_BE: + return 'IEEE_DOUBLE_BE' + + if saw is not None: + raise ValueError("Unrecognized format (%s)" % saw) + else: + # We never detected the after_sequence + raise ValueError("Could not lock sequences (%s)" % saw) + + +def check_for_right_shift_internal_compiler_error(cmd): + """ + On our arm CI, this fails with an internal compilation error + + The failure looks like the following, and can be reproduced on ARM64 GCC 5.4: + + : In function 'right_shift': + :4:20: internal compiler error: in expand_shift_1, at expmed.c:2349 + ip1[i] = ip1[i] >> in2; + ^ + Please submit a full bug report, + with preprocessed source if appropriate. + See for instructions. + Compiler returned: 1 + + This function returns True if this compiler bug is present, and we need to + turn off optimization for the function + """ + cmd._check_compiler() + has_optimize = cmd.try_compile(textwrap.dedent("""\ + __attribute__((optimize("O3"))) void right_shift() {} + """), None, None) + if not has_optimize: + return False + + no_err = cmd.try_compile(textwrap.dedent("""\ + typedef long the_type; /* fails also for unsigned and long long */ + __attribute__((optimize("O3"))) void right_shift(the_type in2, the_type *ip1, int n) { + for (int i = 0; i < n; i++) { + if (in2 < (the_type)sizeof(the_type) * 8) { + ip1[i] = ip1[i] >> in2; + } + } + } + """), None, None) + return not no_err diff --git a/venv/Lib/site-packages/numpy/core/shape_base.py b/venv/Lib/site-packages/numpy/core/shape_base.py new file mode 100644 index 0000000..e4dc30d --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/shape_base.py @@ -0,0 +1,901 @@ +__all__ = ['atleast_1d', 'atleast_2d', 'atleast_3d', 'block', 'hstack', + 'stack', 'vstack'] + +import functools +import itertools +import operator +import warnings + +from . import numeric as _nx +from . import overrides +from ._asarray import array, asanyarray +from .multiarray import normalize_axis_index +from . import fromnumeric as _from_nx + + +array_function_dispatch = functools.partial( + overrides.array_function_dispatch, module='numpy') + + +def _atleast_1d_dispatcher(*arys): + return arys + + +@array_function_dispatch(_atleast_1d_dispatcher) +def atleast_1d(*arys): + """ + Convert inputs to arrays with at least one dimension. + + Scalar inputs are converted to 1-dimensional arrays, whilst + higher-dimensional inputs are preserved. + + Parameters + ---------- + arys1, arys2, ... : array_like + One or more input arrays. + + Returns + ------- + ret : ndarray + An array, or list of arrays, each with ``a.ndim >= 1``. + Copies are made only if necessary. + + See Also + -------- + atleast_2d, atleast_3d + + Examples + -------- + >>> np.atleast_1d(1.0) + array([1.]) + + >>> x = np.arange(9.0).reshape(3,3) + >>> np.atleast_1d(x) + array([[0., 1., 2.], + [3., 4., 5.], + [6., 7., 8.]]) + >>> np.atleast_1d(x) is x + True + + >>> np.atleast_1d(1, [3, 4]) + [array([1]), array([3, 4])] + + """ + res = [] + for ary in arys: + ary = asanyarray(ary) + if ary.ndim == 0: + result = ary.reshape(1) + else: + result = ary + res.append(result) + if len(res) == 1: + return res[0] + else: + return res + + +def _atleast_2d_dispatcher(*arys): + return arys + + +@array_function_dispatch(_atleast_2d_dispatcher) +def atleast_2d(*arys): + """ + View inputs as arrays with at least two dimensions. + + Parameters + ---------- + arys1, arys2, ... : array_like + One or more array-like sequences. Non-array inputs are converted + to arrays. Arrays that already have two or more dimensions are + preserved. + + Returns + ------- + res, res2, ... : ndarray + An array, or list of arrays, each with ``a.ndim >= 2``. + Copies are avoided where possible, and views with two or more + dimensions are returned. + + See Also + -------- + atleast_1d, atleast_3d + + Examples + -------- + >>> np.atleast_2d(3.0) + array([[3.]]) + + >>> x = np.arange(3.0) + >>> np.atleast_2d(x) + array([[0., 1., 2.]]) + >>> np.atleast_2d(x).base is x + True + + >>> np.atleast_2d(1, [1, 2], [[1, 2]]) + [array([[1]]), array([[1, 2]]), array([[1, 2]])] + + """ + res = [] + for ary in arys: + ary = asanyarray(ary) + if ary.ndim == 0: + result = ary.reshape(1, 1) + elif ary.ndim == 1: + result = ary[_nx.newaxis, :] + else: + result = ary + res.append(result) + if len(res) == 1: + return res[0] + else: + return res + + +def _atleast_3d_dispatcher(*arys): + return arys + + +@array_function_dispatch(_atleast_3d_dispatcher) +def atleast_3d(*arys): + """ + View inputs as arrays with at least three dimensions. + + Parameters + ---------- + arys1, arys2, ... : array_like + One or more array-like sequences. Non-array inputs are converted to + arrays. Arrays that already have three or more dimensions are + preserved. + + Returns + ------- + res1, res2, ... : ndarray + An array, or list of arrays, each with ``a.ndim >= 3``. Copies are + avoided where possible, and views with three or more dimensions are + returned. For example, a 1-D array of shape ``(N,)`` becomes a view + of shape ``(1, N, 1)``, and a 2-D array of shape ``(M, N)`` becomes a + view of shape ``(M, N, 1)``. + + See Also + -------- + atleast_1d, atleast_2d + + Examples + -------- + >>> np.atleast_3d(3.0) + array([[[3.]]]) + + >>> x = np.arange(3.0) + >>> np.atleast_3d(x).shape + (1, 3, 1) + + >>> x = np.arange(12.0).reshape(4,3) + >>> np.atleast_3d(x).shape + (4, 3, 1) + >>> np.atleast_3d(x).base is x.base # x is a reshape, so not base itself + True + + >>> for arr in np.atleast_3d([1, 2], [[1, 2]], [[[1, 2]]]): + ... print(arr, arr.shape) # doctest: +SKIP + ... + [[[1] + [2]]] (1, 2, 1) + [[[1] + [2]]] (1, 2, 1) + [[[1 2]]] (1, 1, 2) + + """ + res = [] + for ary in arys: + ary = asanyarray(ary) + if ary.ndim == 0: + result = ary.reshape(1, 1, 1) + elif ary.ndim == 1: + result = ary[_nx.newaxis, :, _nx.newaxis] + elif ary.ndim == 2: + result = ary[:, :, _nx.newaxis] + else: + result = ary + res.append(result) + if len(res) == 1: + return res[0] + else: + return res + + +def _arrays_for_stack_dispatcher(arrays, stacklevel=4): + if not hasattr(arrays, '__getitem__') and hasattr(arrays, '__iter__'): + warnings.warn('arrays to stack must be passed as a "sequence" type ' + 'such as list or tuple. Support for non-sequence ' + 'iterables such as generators is deprecated as of ' + 'NumPy 1.16 and will raise an error in the future.', + FutureWarning, stacklevel=stacklevel) + return () + return arrays + + +def _vhstack_dispatcher(tup): + return _arrays_for_stack_dispatcher(tup) + + +@array_function_dispatch(_vhstack_dispatcher) +def vstack(tup): + """ + Stack arrays in sequence vertically (row wise). + + This is equivalent to concatenation along the first axis after 1-D arrays + of shape `(N,)` have been reshaped to `(1,N)`. Rebuilds arrays divided by + `vsplit`. + + This function makes most sense for arrays with up to 3 dimensions. For + instance, for pixel-data with a height (first axis), width (second axis), + and r/g/b channels (third axis). The functions `concatenate`, `stack` and + `block` provide more general stacking and concatenation operations. + + Parameters + ---------- + tup : sequence of ndarrays + The arrays must have the same shape along all but the first axis. + 1-D arrays must have the same length. + + Returns + ------- + stacked : ndarray + The array formed by stacking the given arrays, will be at least 2-D. + + See Also + -------- + concatenate : Join a sequence of arrays along an existing axis. + stack : Join a sequence of arrays along a new axis. + block : Assemble an nd-array from nested lists of blocks. + hstack : Stack arrays in sequence horizontally (column wise). + dstack : Stack arrays in sequence depth wise (along third axis). + column_stack : Stack 1-D arrays as columns into a 2-D array. + vsplit : Split an array into multiple sub-arrays vertically (row-wise). + + Examples + -------- + >>> a = np.array([1, 2, 3]) + >>> b = np.array([2, 3, 4]) + >>> np.vstack((a,b)) + array([[1, 2, 3], + [2, 3, 4]]) + + >>> a = np.array([[1], [2], [3]]) + >>> b = np.array([[2], [3], [4]]) + >>> np.vstack((a,b)) + array([[1], + [2], + [3], + [2], + [3], + [4]]) + + """ + if not overrides.ARRAY_FUNCTION_ENABLED: + # raise warning if necessary + _arrays_for_stack_dispatcher(tup, stacklevel=2) + arrs = atleast_2d(*tup) + if not isinstance(arrs, list): + arrs = [arrs] + return _nx.concatenate(arrs, 0) + + +@array_function_dispatch(_vhstack_dispatcher) +def hstack(tup): + """ + Stack arrays in sequence horizontally (column wise). + + This is equivalent to concatenation along the second axis, except for 1-D + arrays where it concatenates along the first axis. Rebuilds arrays divided + by `hsplit`. + + This function makes most sense for arrays with up to 3 dimensions. For + instance, for pixel-data with a height (first axis), width (second axis), + and r/g/b channels (third axis). The functions `concatenate`, `stack` and + `block` provide more general stacking and concatenation operations. + + Parameters + ---------- + tup : sequence of ndarrays + The arrays must have the same shape along all but the second axis, + except 1-D arrays which can be any length. + + Returns + ------- + stacked : ndarray + The array formed by stacking the given arrays. + + See Also + -------- + concatenate : Join a sequence of arrays along an existing axis. + stack : Join a sequence of arrays along a new axis. + block : Assemble an nd-array from nested lists of blocks. + vstack : Stack arrays in sequence vertically (row wise). + dstack : Stack arrays in sequence depth wise (along third axis). + column_stack : Stack 1-D arrays as columns into a 2-D array. + hsplit : Split an array into multiple sub-arrays horizontally (column-wise). + + Examples + -------- + >>> a = np.array((1,2,3)) + >>> b = np.array((2,3,4)) + >>> np.hstack((a,b)) + array([1, 2, 3, 2, 3, 4]) + >>> a = np.array([[1],[2],[3]]) + >>> b = np.array([[2],[3],[4]]) + >>> np.hstack((a,b)) + array([[1, 2], + [2, 3], + [3, 4]]) + + """ + if not overrides.ARRAY_FUNCTION_ENABLED: + # raise warning if necessary + _arrays_for_stack_dispatcher(tup, stacklevel=2) + + arrs = atleast_1d(*tup) + if not isinstance(arrs, list): + arrs = [arrs] + # As a special case, dimension 0 of 1-dimensional arrays is "horizontal" + if arrs and arrs[0].ndim == 1: + return _nx.concatenate(arrs, 0) + else: + return _nx.concatenate(arrs, 1) + + +def _stack_dispatcher(arrays, axis=None, out=None): + arrays = _arrays_for_stack_dispatcher(arrays, stacklevel=6) + if out is not None: + # optimize for the typical case where only arrays is provided + arrays = list(arrays) + arrays.append(out) + return arrays + + +@array_function_dispatch(_stack_dispatcher) +def stack(arrays, axis=0, out=None): + """ + Join a sequence of arrays along a new axis. + + The ``axis`` parameter specifies the index of the new axis in the + dimensions of the result. For example, if ``axis=0`` it will be the first + dimension and if ``axis=-1`` it will be the last dimension. + + .. versionadded:: 1.10.0 + + Parameters + ---------- + arrays : sequence of array_like + Each array must have the same shape. + + axis : int, optional + The axis in the result array along which the input arrays are stacked. + + out : ndarray, optional + If provided, the destination to place the result. The shape must be + correct, matching that of what stack would have returned if no + out argument were specified. + + Returns + ------- + stacked : ndarray + The stacked array has one more dimension than the input arrays. + + See Also + -------- + concatenate : Join a sequence of arrays along an existing axis. + block : Assemble an nd-array from nested lists of blocks. + split : Split array into a list of multiple sub-arrays of equal size. + + Examples + -------- + >>> arrays = [np.random.randn(3, 4) for _ in range(10)] + >>> np.stack(arrays, axis=0).shape + (10, 3, 4) + + >>> np.stack(arrays, axis=1).shape + (3, 10, 4) + + >>> np.stack(arrays, axis=2).shape + (3, 4, 10) + + >>> a = np.array([1, 2, 3]) + >>> b = np.array([2, 3, 4]) + >>> np.stack((a, b)) + array([[1, 2, 3], + [2, 3, 4]]) + + >>> np.stack((a, b), axis=-1) + array([[1, 2], + [2, 3], + [3, 4]]) + + """ + if not overrides.ARRAY_FUNCTION_ENABLED: + # raise warning if necessary + _arrays_for_stack_dispatcher(arrays, stacklevel=2) + + arrays = [asanyarray(arr) for arr in arrays] + if not arrays: + raise ValueError('need at least one array to stack') + + shapes = {arr.shape for arr in arrays} + if len(shapes) != 1: + raise ValueError('all input arrays must have the same shape') + + result_ndim = arrays[0].ndim + 1 + axis = normalize_axis_index(axis, result_ndim) + + sl = (slice(None),) * axis + (_nx.newaxis,) + expanded_arrays = [arr[sl] for arr in arrays] + return _nx.concatenate(expanded_arrays, axis=axis, out=out) + + +# Internal functions to eliminate the overhead of repeated dispatch in one of +# the two possible paths inside np.block. +# Use getattr to protect against __array_function__ being disabled. +_size = getattr(_from_nx.size, '__wrapped__', _from_nx.size) +_ndim = getattr(_from_nx.ndim, '__wrapped__', _from_nx.ndim) +_concatenate = getattr(_from_nx.concatenate, '__wrapped__', _from_nx.concatenate) + + +def _block_format_index(index): + """ + Convert a list of indices ``[0, 1, 2]`` into ``"arrays[0][1][2]"``. + """ + idx_str = ''.join('[{}]'.format(i) for i in index if i is not None) + return 'arrays' + idx_str + + +def _block_check_depths_match(arrays, parent_index=[]): + """ + Recursive function checking that the depths of nested lists in `arrays` + all match. Mismatch raises a ValueError as described in the block + docstring below. + + The entire index (rather than just the depth) needs to be calculated + for each innermost list, in case an error needs to be raised, so that + the index of the offending list can be printed as part of the error. + + Parameters + ---------- + arrays : nested list of arrays + The arrays to check + parent_index : list of int + The full index of `arrays` within the nested lists passed to + `_block_check_depths_match` at the top of the recursion. + + Returns + ------- + first_index : list of int + The full index of an element from the bottom of the nesting in + `arrays`. If any element at the bottom is an empty list, this will + refer to it, and the last index along the empty axis will be None. + max_arr_ndim : int + The maximum of the ndims of the arrays nested in `arrays`. + final_size: int + The number of elements in the final array. This is used the motivate + the choice of algorithm used using benchmarking wisdom. + + """ + if type(arrays) is tuple: + # not strictly necessary, but saves us from: + # - more than one way to do things - no point treating tuples like + # lists + # - horribly confusing behaviour that results when tuples are + # treated like ndarray + raise TypeError( + '{} is a tuple. ' + 'Only lists can be used to arrange blocks, and np.block does ' + 'not allow implicit conversion from tuple to ndarray.'.format( + _block_format_index(parent_index) + ) + ) + elif type(arrays) is list and len(arrays) > 0: + idxs_ndims = (_block_check_depths_match(arr, parent_index + [i]) + for i, arr in enumerate(arrays)) + + first_index, max_arr_ndim, final_size = next(idxs_ndims) + for index, ndim, size in idxs_ndims: + final_size += size + if ndim > max_arr_ndim: + max_arr_ndim = ndim + if len(index) != len(first_index): + raise ValueError( + "List depths are mismatched. First element was at depth " + "{}, but there is an element at depth {} ({})".format( + len(first_index), + len(index), + _block_format_index(index) + ) + ) + # propagate our flag that indicates an empty list at the bottom + if index[-1] is None: + first_index = index + + return first_index, max_arr_ndim, final_size + elif type(arrays) is list and len(arrays) == 0: + # We've 'bottomed out' on an empty list + return parent_index + [None], 0, 0 + else: + # We've 'bottomed out' - arrays is either a scalar or an array + size = _size(arrays) + return parent_index, _ndim(arrays), size + + +def _atleast_nd(a, ndim): + # Ensures `a` has at least `ndim` dimensions by prepending + # ones to `a.shape` as necessary + return array(a, ndmin=ndim, copy=False, subok=True) + + +def _accumulate(values): + return list(itertools.accumulate(values)) + + +def _concatenate_shapes(shapes, axis): + """Given array shapes, return the resulting shape and slices prefixes. + + These help in nested concatenation. + + Returns + ------- + shape: tuple of int + This tuple satisfies: + ``` + shape, _ = _concatenate_shapes([arr.shape for shape in arrs], axis) + shape == concatenate(arrs, axis).shape + ``` + + slice_prefixes: tuple of (slice(start, end), ) + For a list of arrays being concatenated, this returns the slice + in the larger array at axis that needs to be sliced into. + + For example, the following holds: + ``` + ret = concatenate([a, b, c], axis) + _, (sl_a, sl_b, sl_c) = concatenate_slices([a, b, c], axis) + + ret[(slice(None),) * axis + sl_a] == a + ret[(slice(None),) * axis + sl_b] == b + ret[(slice(None),) * axis + sl_c] == c + ``` + + These are called slice prefixes since they are used in the recursive + blocking algorithm to compute the left-most slices during the + recursion. Therefore, they must be prepended to rest of the slice + that was computed deeper in the recursion. + + These are returned as tuples to ensure that they can quickly be added + to existing slice tuple without creating a new tuple every time. + + """ + # Cache a result that will be reused. + shape_at_axis = [shape[axis] for shape in shapes] + + # Take a shape, any shape + first_shape = shapes[0] + first_shape_pre = first_shape[:axis] + first_shape_post = first_shape[axis+1:] + + if any(shape[:axis] != first_shape_pre or + shape[axis+1:] != first_shape_post for shape in shapes): + raise ValueError( + 'Mismatched array shapes in block along axis {}.'.format(axis)) + + shape = (first_shape_pre + (sum(shape_at_axis),) + first_shape[axis+1:]) + + offsets_at_axis = _accumulate(shape_at_axis) + slice_prefixes = [(slice(start, end),) + for start, end in zip([0] + offsets_at_axis, + offsets_at_axis)] + return shape, slice_prefixes + + +def _block_info_recursion(arrays, max_depth, result_ndim, depth=0): + """ + Returns the shape of the final array, along with a list + of slices and a list of arrays that can be used for assignment inside the + new array + + Parameters + ---------- + arrays : nested list of arrays + The arrays to check + max_depth : list of int + The number of nested lists + result_ndim: int + The number of dimensions in thefinal array. + + Returns + ------- + shape : tuple of int + The shape that the final array will take on. + slices: list of tuple of slices + The slices into the full array required for assignment. These are + required to be prepended with ``(Ellipsis, )`` to obtain to correct + final index. + arrays: list of ndarray + The data to assign to each slice of the full array + + """ + if depth < max_depth: + shapes, slices, arrays = zip( + *[_block_info_recursion(arr, max_depth, result_ndim, depth+1) + for arr in arrays]) + + axis = result_ndim - max_depth + depth + shape, slice_prefixes = _concatenate_shapes(shapes, axis) + + # Prepend the slice prefix and flatten the slices + slices = [slice_prefix + the_slice + for slice_prefix, inner_slices in zip(slice_prefixes, slices) + for the_slice in inner_slices] + + # Flatten the array list + arrays = functools.reduce(operator.add, arrays) + + return shape, slices, arrays + else: + # We've 'bottomed out' - arrays is either a scalar or an array + # type(arrays) is not list + # Return the slice and the array inside a list to be consistent with + # the recursive case. + arr = _atleast_nd(arrays, result_ndim) + return arr.shape, [()], [arr] + + +def _block(arrays, max_depth, result_ndim, depth=0): + """ + Internal implementation of block based on repeated concatenation. + `arrays` is the argument passed to + block. `max_depth` is the depth of nested lists within `arrays` and + `result_ndim` is the greatest of the dimensions of the arrays in + `arrays` and the depth of the lists in `arrays` (see block docstring + for details). + """ + if depth < max_depth: + arrs = [_block(arr, max_depth, result_ndim, depth+1) + for arr in arrays] + return _concatenate(arrs, axis=-(max_depth-depth)) + else: + # We've 'bottomed out' - arrays is either a scalar or an array + # type(arrays) is not list + return _atleast_nd(arrays, result_ndim) + + +def _block_dispatcher(arrays): + # Use type(...) is list to match the behavior of np.block(), which special + # cases list specifically rather than allowing for generic iterables or + # tuple. Also, we know that list.__array_function__ will never exist. + if type(arrays) is list: + for subarrays in arrays: + yield from _block_dispatcher(subarrays) + else: + yield arrays + + +@array_function_dispatch(_block_dispatcher) +def block(arrays): + """ + Assemble an nd-array from nested lists of blocks. + + Blocks in the innermost lists are concatenated (see `concatenate`) along + the last dimension (-1), then these are concatenated along the + second-last dimension (-2), and so on until the outermost list is reached. + + Blocks can be of any dimension, but will not be broadcasted using the normal + rules. Instead, leading axes of size 1 are inserted, to make ``block.ndim`` + the same for all blocks. This is primarily useful for working with scalars, + and means that code like ``np.block([v, 1])`` is valid, where + ``v.ndim == 1``. + + When the nested list is two levels deep, this allows block matrices to be + constructed from their components. + + .. versionadded:: 1.13.0 + + Parameters + ---------- + arrays : nested list of array_like or scalars (but not tuples) + If passed a single ndarray or scalar (a nested list of depth 0), this + is returned unmodified (and not copied). + + Elements shapes must match along the appropriate axes (without + broadcasting), but leading 1s will be prepended to the shape as + necessary to make the dimensions match. + + Returns + ------- + block_array : ndarray + The array assembled from the given blocks. + + The dimensionality of the output is equal to the greatest of: + * the dimensionality of all the inputs + * the depth to which the input list is nested + + Raises + ------ + ValueError + * If list depths are mismatched - for instance, ``[[a, b], c]`` is + illegal, and should be spelt ``[[a, b], [c]]`` + * If lists are empty - for instance, ``[[a, b], []]`` + + See Also + -------- + concatenate : Join a sequence of arrays along an existing axis. + stack : Join a sequence of arrays along a new axis. + vstack : Stack arrays in sequence vertically (row wise). + hstack : Stack arrays in sequence horizontally (column wise). + dstack : Stack arrays in sequence depth wise (along third axis). + column_stack : Stack 1-D arrays as columns into a 2-D array. + vsplit : Split an array into multiple sub-arrays vertically (row-wise). + + Notes + ----- + + When called with only scalars, ``np.block`` is equivalent to an ndarray + call. So ``np.block([[1, 2], [3, 4]])`` is equivalent to + ``np.array([[1, 2], [3, 4]])``. + + This function does not enforce that the blocks lie on a fixed grid. + ``np.block([[a, b], [c, d]])`` is not restricted to arrays of the form:: + + AAAbb + AAAbb + cccDD + + But is also allowed to produce, for some ``a, b, c, d``:: + + AAAbb + AAAbb + cDDDD + + Since concatenation happens along the last axis first, `block` is _not_ + capable of producing the following directly:: + + AAAbb + cccbb + cccDD + + Matlab's "square bracket stacking", ``[A, B, ...; p, q, ...]``, is + equivalent to ``np.block([[A, B, ...], [p, q, ...]])``. + + Examples + -------- + The most common use of this function is to build a block matrix + + >>> A = np.eye(2) * 2 + >>> B = np.eye(3) * 3 + >>> np.block([ + ... [A, np.zeros((2, 3))], + ... [np.ones((3, 2)), B ] + ... ]) + array([[2., 0., 0., 0., 0.], + [0., 2., 0., 0., 0.], + [1., 1., 3., 0., 0.], + [1., 1., 0., 3., 0.], + [1., 1., 0., 0., 3.]]) + + With a list of depth 1, `block` can be used as `hstack` + + >>> np.block([1, 2, 3]) # hstack([1, 2, 3]) + array([1, 2, 3]) + + >>> a = np.array([1, 2, 3]) + >>> b = np.array([2, 3, 4]) + >>> np.block([a, b, 10]) # hstack([a, b, 10]) + array([ 1, 2, 3, 2, 3, 4, 10]) + + >>> A = np.ones((2, 2), int) + >>> B = 2 * A + >>> np.block([A, B]) # hstack([A, B]) + array([[1, 1, 2, 2], + [1, 1, 2, 2]]) + + With a list of depth 2, `block` can be used in place of `vstack`: + + >>> a = np.array([1, 2, 3]) + >>> b = np.array([2, 3, 4]) + >>> np.block([[a], [b]]) # vstack([a, b]) + array([[1, 2, 3], + [2, 3, 4]]) + + >>> A = np.ones((2, 2), int) + >>> B = 2 * A + >>> np.block([[A], [B]]) # vstack([A, B]) + array([[1, 1], + [1, 1], + [2, 2], + [2, 2]]) + + It can also be used in places of `atleast_1d` and `atleast_2d` + + >>> a = np.array(0) + >>> b = np.array([1]) + >>> np.block([a]) # atleast_1d(a) + array([0]) + >>> np.block([b]) # atleast_1d(b) + array([1]) + + >>> np.block([[a]]) # atleast_2d(a) + array([[0]]) + >>> np.block([[b]]) # atleast_2d(b) + array([[1]]) + + + """ + arrays, list_ndim, result_ndim, final_size = _block_setup(arrays) + + # It was found through benchmarking that making an array of final size + # around 256x256 was faster by straight concatenation on a + # i7-7700HQ processor and dual channel ram 2400MHz. + # It didn't seem to matter heavily on the dtype used. + # + # A 2D array using repeated concatenation requires 2 copies of the array. + # + # The fastest algorithm will depend on the ratio of CPU power to memory + # speed. + # One can monitor the results of the benchmark + # https://pv.github.io/numpy-bench/#bench_shape_base.Block2D.time_block2d + # to tune this parameter until a C version of the `_block_info_recursion` + # algorithm is implemented which would likely be faster than the python + # version. + if list_ndim * final_size > (2 * 512 * 512): + return _block_slicing(arrays, list_ndim, result_ndim) + else: + return _block_concatenate(arrays, list_ndim, result_ndim) + + +# These helper functions are mostly used for testing. +# They allow us to write tests that directly call `_block_slicing` +# or `_block_concatenate` without blocking large arrays to force the wisdom +# to trigger the desired path. +def _block_setup(arrays): + """ + Returns + (`arrays`, list_ndim, result_ndim, final_size) + """ + bottom_index, arr_ndim, final_size = _block_check_depths_match(arrays) + list_ndim = len(bottom_index) + if bottom_index and bottom_index[-1] is None: + raise ValueError( + 'List at {} cannot be empty'.format( + _block_format_index(bottom_index) + ) + ) + result_ndim = max(arr_ndim, list_ndim) + return arrays, list_ndim, result_ndim, final_size + + +def _block_slicing(arrays, list_ndim, result_ndim): + shape, slices, arrays = _block_info_recursion( + arrays, list_ndim, result_ndim) + dtype = _nx.result_type(*[arr.dtype for arr in arrays]) + + # Test preferring F only in the case that all input arrays are F + F_order = all(arr.flags['F_CONTIGUOUS'] for arr in arrays) + C_order = all(arr.flags['C_CONTIGUOUS'] for arr in arrays) + order = 'F' if F_order and not C_order else 'C' + result = _nx.empty(shape=shape, dtype=dtype, order=order) + # Note: In a c implementation, the function + # PyArray_CreateMultiSortedStridePerm could be used for more advanced + # guessing of the desired order. + + for the_slice, arr in zip(slices, arrays): + result[(Ellipsis,) + the_slice] = arr + return result + + +def _block_concatenate(arrays, list_ndim, result_ndim): + result = _block(arrays, list_ndim, result_ndim) + if list_ndim == 0: + # Catch an edge case where _block returns a view because + # `arrays` is a single numpy array and not a list of numpy arrays. + # This might copy scalars or lists twice, but this isn't a likely + # usecase for those interested in performance + result = result.copy() + return result diff --git a/venv/Lib/site-packages/numpy/core/shape_base.pyi b/venv/Lib/site-packages/numpy/core/shape_base.pyi new file mode 100644 index 0000000..b20598b --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/shape_base.pyi @@ -0,0 +1,41 @@ +import sys +from typing import TypeVar, overload, List, Sequence + +from numpy import ndarray +from numpy.typing import ArrayLike + +if sys.version_info >= (3, 8): + from typing import SupportsIndex +else: + from typing_extensions import Protocol + class SupportsIndex(Protocol): + def __index__(self) -> int: ... + +_ArrayType = TypeVar("_ArrayType", bound=ndarray) + +@overload +def atleast_1d(__arys: ArrayLike) -> ndarray: ... +@overload +def atleast_1d(*arys: ArrayLike) -> List[ndarray]: ... + +@overload +def atleast_2d(__arys: ArrayLike) -> ndarray: ... +@overload +def atleast_2d(*arys: ArrayLike) -> List[ndarray]: ... + +@overload +def atleast_3d(__arys: ArrayLike) -> ndarray: ... +@overload +def atleast_3d(*arys: ArrayLike) -> List[ndarray]: ... + +def vstack(tup: Sequence[ArrayLike]) -> ndarray: ... +def hstack(tup: Sequence[ArrayLike]) -> ndarray: ... +@overload +def stack( + arrays: Sequence[ArrayLike], axis: SupportsIndex = ..., out: None = ... +) -> ndarray: ... +@overload +def stack( + arrays: Sequence[ArrayLike], axis: SupportsIndex = ..., out: _ArrayType = ... +) -> _ArrayType: ... +def block(arrays: ArrayLike) -> ndarray: ... diff --git a/venv/Lib/site-packages/numpy/core/tests/__init__.py b/venv/Lib/site-packages/numpy/core/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/venv/Lib/site-packages/numpy/core/tests/_locales.py b/venv/Lib/site-packages/numpy/core/tests/_locales.py new file mode 100644 index 0000000..ce7b81f --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/tests/_locales.py @@ -0,0 +1,74 @@ +"""Provide class for testing in French locale + +""" +import sys +import locale + +import pytest + +__ALL__ = ['CommaDecimalPointLocale'] + + +def find_comma_decimal_point_locale(): + """See if platform has a decimal point as comma locale. + + Find a locale that uses a comma instead of a period as the + decimal point. + + Returns + ------- + old_locale: str + Locale when the function was called. + new_locale: {str, None) + First French locale found, None if none found. + + """ + if sys.platform == 'win32': + locales = ['FRENCH'] + else: + locales = ['fr_FR', 'fr_FR.UTF-8', 'fi_FI', 'fi_FI.UTF-8'] + + old_locale = locale.getlocale(locale.LC_NUMERIC) + new_locale = None + try: + for loc in locales: + try: + locale.setlocale(locale.LC_NUMERIC, loc) + new_locale = loc + break + except locale.Error: + pass + finally: + locale.setlocale(locale.LC_NUMERIC, locale=old_locale) + return old_locale, new_locale + + +class CommaDecimalPointLocale: + """Sets LC_NUMERIC to a locale with comma as decimal point. + + Classes derived from this class have setup and teardown methods that run + tests with locale.LC_NUMERIC set to a locale where commas (',') are used as + the decimal point instead of periods ('.'). On exit the locale is restored + to the initial locale. It also serves as context manager with the same + effect. If no such locale is available, the test is skipped. + + .. versionadded:: 1.15.0 + + """ + (cur_locale, tst_locale) = find_comma_decimal_point_locale() + + def setup(self): + if self.tst_locale is None: + pytest.skip("No French locale available") + locale.setlocale(locale.LC_NUMERIC, locale=self.tst_locale) + + def teardown(self): + locale.setlocale(locale.LC_NUMERIC, locale=self.cur_locale) + + def __enter__(self): + if self.tst_locale is None: + pytest.skip("No French locale available") + locale.setlocale(locale.LC_NUMERIC, locale=self.tst_locale) + + def __exit__(self, type, value, traceback): + locale.setlocale(locale.LC_NUMERIC, locale=self.cur_locale) diff --git a/venv/Lib/site-packages/numpy/core/tests/data/astype_copy.pkl b/venv/Lib/site-packages/numpy/core/tests/data/astype_copy.pkl new file mode 100644 index 0000000000000000000000000000000000000000..7397c978297b3f64c7e6540b23f448f280e30bcc GIT binary patch literal 716 zcmXYteJs>*9LMj0wELrGX0g*+#^yGUX+D(rtPp;lqH|WB?v6qnckVXSb|}U4T*BDc ztgt&*R!!n4);z_!hDA=U2TLO{Ow;HiegF8r_Wgc7-|zeV{uFYgGF4VizN<7_k?NYI z%2cL{6$)`aFG-Oq&6edV6)LHcCui?;@nk7GRXK-Yl?d6AYteG96T@agO8z&bDD!ht zd2%x$=bSggV%XGR?!<6~Y~P58h|n!s|2BrDl$4zg=CD`+(VqNc9e~^+UBN~>V67&n zEsSU_2&g_w9CexS?S286d?)vaZ7ZOSCN{jM9>#oZnP9{-<74-r(()ADGyiQ_X*#oFw)|WgXCbaQIUc?Vex~Y?|0qZuS+&o_ay3Y^G(z*e| zU5Z-|b^#im58G6B0ye}i_Xp`H&tlY39r^v$RA_W82MiqR@mE&?2Jin|;oS)MHc%*j zNAG>wGa}EEPm!Hn*@IEQibJv)dt#i5AIjc77i!hX#D@){8p~1s&o|_0=^xg1F!FOk`#9_}3c|bNMTiwYXD@MeGhs``i;pyb#^J) zWJ3vQ`c!lWhB#Vs&(53~3TNz)<$7TOyoDBX;Q~S)F$hvtfS)E|n#Ukgm=o85LeM0j zdC=H+OWZYiY{xUkh?kVH$8tzR@VF=-LqDK`LdKt1)PPc7Z1a&g=(WbzYv3su`h=05 zFzeB^?AZ}KnXgJsLKRFvOm{MEL3sk~NwB2gY0|)-u9i#7cJV~D@%21nPuxSwNK7{j z+?*ywmgWMST_ITf1|)@4K)^ztumBL)EJU6rX}kmE^94^WXWL!D{Q{ga%OV!D1c6x2 zF~?8C;YBtW4}RHu69c`;0M|xW2X8z&f5Dr|JbVFS%fL1r6C9tj#AmPyLyi}$h_kO~ zAtM2o`P(Fo(#=i=t@Z)D;Hi9PG7T<}73>keQ~~~M^m+;)#iR0y7p_`|$_LLI)mhz> zJ7UXvbR5_5Nf$q7rgPz%w+qYZU_o4pbYi|Nm*j(Sb#>M4;oqczbNDhR3(Gc_7UBu- zJd`cgIo!i5_8*N^uBxwVcaFIBzF}JX&uH{ttwFG=NAOki9XU%cYX&p}ngPv#WNr$X#)El?NR;s0`H$0xudb?)JSllr-j zc>Qj`QMO5KMI+SYwP+6*^{c`&+V!(BLA=jA5L+oGtBg?zos3oC_1p1aP(S(m{PlG8 zAmwFWoRgcaggJ%Cl)Wf+-3iyz-NDgcG^l@|NtNUezXW*D5 zt%;{{-48KXWd(XIyAnGRW~&F3?bWvGQ^lw1+wu16O}ua8!>5m%im$>m-c^q^@!I1X zR`KB*YTa4)HFy;t@{aGXzh7?ReH-7&DyjG?ypj3+@tMw)5SVUhjw2clP0!}eh_kNh zan~Q6;|TrtdhjBPa7^8o8c#Iqk33x)T5V7G4!C&SCZcqo4l z%H%NWexgyyR44jrRL05khPtETtN1fV)s24@-|xh6SNHE>if_2Uw{o6yFvi#Y(KQZ` z{eJgdnRNTT-pO~O9-p4y>TGCVGoTsJ4E#6)H?Klzo3pdCx770kcJu0sw6D1EYq;6+ oKW=^+NE_n9Zy)4;h|$re8PE)91~dbj0nLDBKr^5j_', where ufuncname is name of + the function in NumPy you want to validate +2) The file should contain 4 columns: dtype,input,expected output,ulperror + a. dtype: one of np.float16, np.float32, np.float64 + b. input: floating point input to ufunc in hex. Example: 0x414570a4 + represents 12.340000152587890625 + c. expected output: floating point output for the corresponding input in hex. + This should be computed using a high(er) precision library and then rounded to + same format as the input. + d. ulperror: expected maximum ulp error of the function. This + should be same across all rows of the same dtype. Otherwise, the function is + tested for the maximum ulp error among all entries of that dtype. +3) Add file umath-validation-set- to the test file test_umath_accuracy.py + which will then validate your ufunc. diff --git a/venv/Lib/site-packages/numpy/core/tests/data/umath-validation-set-cos b/venv/Lib/site-packages/numpy/core/tests/data/umath-validation-set-cos new file mode 100644 index 0000000..2e75f04 --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/tests/data/umath-validation-set-cos @@ -0,0 +1,665 @@ +dtype,input,output,ulperrortol +## +ve denormals ## +np.float32,0x004b4716,0x3f800000,2 +np.float32,0x007b2490,0x3f800000,2 +np.float32,0x007c99fa,0x3f800000,2 +np.float32,0x00734a0c,0x3f800000,2 +np.float32,0x0070de24,0x3f800000,2 +np.float32,0x007fffff,0x3f800000,2 +np.float32,0x00000001,0x3f800000,2 +## -ve denormals ## +np.float32,0x80495d65,0x3f800000,2 +np.float32,0x806894f6,0x3f800000,2 +np.float32,0x80555a76,0x3f800000,2 +np.float32,0x804e1fb8,0x3f800000,2 +np.float32,0x80687de9,0x3f800000,2 +np.float32,0x807fffff,0x3f800000,2 +np.float32,0x80000001,0x3f800000,2 +## +/-0.0f, +/-FLT_MIN +/-FLT_MAX ## +np.float32,0x00000000,0x3f800000,2 +np.float32,0x80000000,0x3f800000,2 +np.float32,0x00800000,0x3f800000,2 +np.float32,0x80800000,0x3f800000,2 +## 1.00f + 0x00000001 ## +np.float32,0x3f800000,0x3f0a5140,2 +np.float32,0x3f800001,0x3f0a513f,2 +np.float32,0x3f800002,0x3f0a513d,2 +np.float32,0xc090a8b0,0xbe4332ce,2 +np.float32,0x41ce3184,0x3f4d1de1,2 +np.float32,0xc1d85848,0xbeaa8980,2 +np.float32,0x402b8820,0xbf653aa3,2 +np.float32,0x42b4e454,0xbf4a338b,2 +np.float32,0x42a67a60,0x3c58202e,2 +np.float32,0x41d92388,0xbed987c7,2 +np.float32,0x422dd66c,0x3f5dcab3,2 +np.float32,0xc28f5be6,0xbf5688d8,2 +np.float32,0x41ab2674,0xbf53aa3b,2 +np.float32,0x3f490fdb,0x3f3504f3,2 +np.float32,0xbf490fdb,0x3f3504f3,2 +np.float32,0x3fc90fdb,0xb33bbd2e,2 +np.float32,0xbfc90fdb,0xb33bbd2e,2 +np.float32,0x40490fdb,0xbf800000,2 +np.float32,0xc0490fdb,0xbf800000,2 +np.float32,0x3fc90fdb,0xb33bbd2e,2 +np.float32,0xbfc90fdb,0xb33bbd2e,2 +np.float32,0x40490fdb,0xbf800000,2 +np.float32,0xc0490fdb,0xbf800000,2 +np.float32,0x40c90fdb,0x3f800000,2 +np.float32,0xc0c90fdb,0x3f800000,2 +np.float32,0x4016cbe4,0xbf3504f3,2 +np.float32,0xc016cbe4,0xbf3504f3,2 +np.float32,0x4096cbe4,0x324cde2e,2 +np.float32,0xc096cbe4,0x324cde2e,2 +np.float32,0x4116cbe4,0xbf800000,2 +np.float32,0xc116cbe4,0xbf800000,2 +np.float32,0x40490fdb,0xbf800000,2 +np.float32,0xc0490fdb,0xbf800000,2 +np.float32,0x40c90fdb,0x3f800000,2 +np.float32,0xc0c90fdb,0x3f800000,2 +np.float32,0x41490fdb,0x3f800000,2 +np.float32,0xc1490fdb,0x3f800000,2 +np.float32,0x407b53d2,0xbf3504f1,2 +np.float32,0xc07b53d2,0xbf3504f1,2 +np.float32,0x40fb53d2,0xb4b5563d,2 +np.float32,0xc0fb53d2,0xb4b5563d,2 +np.float32,0x417b53d2,0xbf800000,2 +np.float32,0xc17b53d2,0xbf800000,2 +np.float32,0x4096cbe4,0x324cde2e,2 +np.float32,0xc096cbe4,0x324cde2e,2 +np.float32,0x4116cbe4,0xbf800000,2 +np.float32,0xc116cbe4,0xbf800000,2 +np.float32,0x4196cbe4,0x3f800000,2 +np.float32,0xc196cbe4,0x3f800000,2 +np.float32,0x40afede0,0x3f3504f7,2 +np.float32,0xc0afede0,0x3f3504f7,2 +np.float32,0x412fede0,0x353222c4,2 +np.float32,0xc12fede0,0x353222c4,2 +np.float32,0x41afede0,0xbf800000,2 +np.float32,0xc1afede0,0xbf800000,2 +np.float32,0x40c90fdb,0x3f800000,2 +np.float32,0xc0c90fdb,0x3f800000,2 +np.float32,0x41490fdb,0x3f800000,2 +np.float32,0xc1490fdb,0x3f800000,2 +np.float32,0x41c90fdb,0x3f800000,2 +np.float32,0xc1c90fdb,0x3f800000,2 +np.float32,0x40e231d6,0x3f3504f3,2 +np.float32,0xc0e231d6,0x3f3504f3,2 +np.float32,0x416231d6,0xb319a6a2,2 +np.float32,0xc16231d6,0xb319a6a2,2 +np.float32,0x41e231d6,0xbf800000,2 +np.float32,0xc1e231d6,0xbf800000,2 +np.float32,0x40fb53d2,0xb4b5563d,2 +np.float32,0xc0fb53d2,0xb4b5563d,2 +np.float32,0x417b53d2,0xbf800000,2 +np.float32,0xc17b53d2,0xbf800000,2 +np.float32,0x41fb53d2,0x3f800000,2 +np.float32,0xc1fb53d2,0x3f800000,2 +np.float32,0x410a3ae7,0xbf3504fb,2 +np.float32,0xc10a3ae7,0xbf3504fb,2 +np.float32,0x418a3ae7,0x35b08908,2 +np.float32,0xc18a3ae7,0x35b08908,2 +np.float32,0x420a3ae7,0xbf800000,2 +np.float32,0xc20a3ae7,0xbf800000,2 +np.float32,0x4116cbe4,0xbf800000,2 +np.float32,0xc116cbe4,0xbf800000,2 +np.float32,0x4196cbe4,0x3f800000,2 +np.float32,0xc196cbe4,0x3f800000,2 +np.float32,0x4216cbe4,0x3f800000,2 +np.float32,0xc216cbe4,0x3f800000,2 +np.float32,0x41235ce2,0xbf3504ef,2 +np.float32,0xc1235ce2,0xbf3504ef,2 +np.float32,0x41a35ce2,0xb53889b6,2 +np.float32,0xc1a35ce2,0xb53889b6,2 +np.float32,0x42235ce2,0xbf800000,2 +np.float32,0xc2235ce2,0xbf800000,2 +np.float32,0x412fede0,0x353222c4,2 +np.float32,0xc12fede0,0x353222c4,2 +np.float32,0x41afede0,0xbf800000,2 +np.float32,0xc1afede0,0xbf800000,2 +np.float32,0x422fede0,0x3f800000,2 +np.float32,0xc22fede0,0x3f800000,2 +np.float32,0x413c7edd,0x3f3504f4,2 +np.float32,0xc13c7edd,0x3f3504f4,2 +np.float32,0x41bc7edd,0x33800add,2 +np.float32,0xc1bc7edd,0x33800add,2 +np.float32,0x423c7edd,0xbf800000,2 +np.float32,0xc23c7edd,0xbf800000,2 +np.float32,0x41490fdb,0x3f800000,2 +np.float32,0xc1490fdb,0x3f800000,2 +np.float32,0x41c90fdb,0x3f800000,2 +np.float32,0xc1c90fdb,0x3f800000,2 +np.float32,0x42490fdb,0x3f800000,2 +np.float32,0xc2490fdb,0x3f800000,2 +np.float32,0x4155a0d9,0x3f3504eb,2 +np.float32,0xc155a0d9,0x3f3504eb,2 +np.float32,0x41d5a0d9,0xb5b3bc81,2 +np.float32,0xc1d5a0d9,0xb5b3bc81,2 +np.float32,0x4255a0d9,0xbf800000,2 +np.float32,0xc255a0d9,0xbf800000,2 +np.float32,0x416231d6,0xb319a6a2,2 +np.float32,0xc16231d6,0xb319a6a2,2 +np.float32,0x41e231d6,0xbf800000,2 +np.float32,0xc1e231d6,0xbf800000,2 +np.float32,0x426231d6,0x3f800000,2 +np.float32,0xc26231d6,0x3f800000,2 +np.float32,0x416ec2d4,0xbf3504f7,2 +np.float32,0xc16ec2d4,0xbf3504f7,2 +np.float32,0x41eec2d4,0x353ef0a7,2 +np.float32,0xc1eec2d4,0x353ef0a7,2 +np.float32,0x426ec2d4,0xbf800000,2 +np.float32,0xc26ec2d4,0xbf800000,2 +np.float32,0x417b53d2,0xbf800000,2 +np.float32,0xc17b53d2,0xbf800000,2 +np.float32,0x41fb53d2,0x3f800000,2 +np.float32,0xc1fb53d2,0x3f800000,2 +np.float32,0x427b53d2,0x3f800000,2 +np.float32,0xc27b53d2,0x3f800000,2 +np.float32,0x4183f268,0xbf3504e7,2 +np.float32,0xc183f268,0xbf3504e7,2 +np.float32,0x4203f268,0xb6059a13,2 +np.float32,0xc203f268,0xb6059a13,2 +np.float32,0x4283f268,0xbf800000,2 +np.float32,0xc283f268,0xbf800000,2 +np.float32,0x418a3ae7,0x35b08908,2 +np.float32,0xc18a3ae7,0x35b08908,2 +np.float32,0x420a3ae7,0xbf800000,2 +np.float32,0xc20a3ae7,0xbf800000,2 +np.float32,0x428a3ae7,0x3f800000,2 +np.float32,0xc28a3ae7,0x3f800000,2 +np.float32,0x41908365,0x3f3504f0,2 +np.float32,0xc1908365,0x3f3504f0,2 +np.float32,0x42108365,0xb512200d,2 +np.float32,0xc2108365,0xb512200d,2 +np.float32,0x42908365,0xbf800000,2 +np.float32,0xc2908365,0xbf800000,2 +np.float32,0x4196cbe4,0x3f800000,2 +np.float32,0xc196cbe4,0x3f800000,2 +np.float32,0x4216cbe4,0x3f800000,2 +np.float32,0xc216cbe4,0x3f800000,2 +np.float32,0x4296cbe4,0x3f800000,2 +np.float32,0xc296cbe4,0x3f800000,2 +np.float32,0x419d1463,0x3f3504ef,2 +np.float32,0xc19d1463,0x3f3504ef,2 +np.float32,0x421d1463,0xb5455799,2 +np.float32,0xc21d1463,0xb5455799,2 +np.float32,0x429d1463,0xbf800000,2 +np.float32,0xc29d1463,0xbf800000,2 +np.float32,0x41a35ce2,0xb53889b6,2 +np.float32,0xc1a35ce2,0xb53889b6,2 +np.float32,0x42235ce2,0xbf800000,2 +np.float32,0xc2235ce2,0xbf800000,2 +np.float32,0x42a35ce2,0x3f800000,2 +np.float32,0xc2a35ce2,0x3f800000,2 +np.float32,0x41a9a561,0xbf3504ff,2 +np.float32,0xc1a9a561,0xbf3504ff,2 +np.float32,0x4229a561,0x360733d0,2 +np.float32,0xc229a561,0x360733d0,2 +np.float32,0x42a9a561,0xbf800000,2 +np.float32,0xc2a9a561,0xbf800000,2 +np.float32,0x41afede0,0xbf800000,2 +np.float32,0xc1afede0,0xbf800000,2 +np.float32,0x422fede0,0x3f800000,2 +np.float32,0xc22fede0,0x3f800000,2 +np.float32,0x42afede0,0x3f800000,2 +np.float32,0xc2afede0,0x3f800000,2 +np.float32,0x41b6365e,0xbf3504f6,2 +np.float32,0xc1b6365e,0xbf3504f6,2 +np.float32,0x4236365e,0x350bb91c,2 +np.float32,0xc236365e,0x350bb91c,2 +np.float32,0x42b6365e,0xbf800000,2 +np.float32,0xc2b6365e,0xbf800000,2 +np.float32,0x41bc7edd,0x33800add,2 +np.float32,0xc1bc7edd,0x33800add,2 +np.float32,0x423c7edd,0xbf800000,2 +np.float32,0xc23c7edd,0xbf800000,2 +np.float32,0x42bc7edd,0x3f800000,2 +np.float32,0xc2bc7edd,0x3f800000,2 +np.float32,0x41c2c75c,0x3f3504f8,2 +np.float32,0xc1c2c75c,0x3f3504f8,2 +np.float32,0x4242c75c,0x354bbe8a,2 +np.float32,0xc242c75c,0x354bbe8a,2 +np.float32,0x42c2c75c,0xbf800000,2 +np.float32,0xc2c2c75c,0xbf800000,2 +np.float32,0x41c90fdb,0x3f800000,2 +np.float32,0xc1c90fdb,0x3f800000,2 +np.float32,0x42490fdb,0x3f800000,2 +np.float32,0xc2490fdb,0x3f800000,2 +np.float32,0x42c90fdb,0x3f800000,2 +np.float32,0xc2c90fdb,0x3f800000,2 +np.float32,0x41cf585a,0x3f3504e7,2 +np.float32,0xc1cf585a,0x3f3504e7,2 +np.float32,0x424f585a,0xb608cd8c,2 +np.float32,0xc24f585a,0xb608cd8c,2 +np.float32,0x42cf585a,0xbf800000,2 +np.float32,0xc2cf585a,0xbf800000,2 +np.float32,0x41d5a0d9,0xb5b3bc81,2 +np.float32,0xc1d5a0d9,0xb5b3bc81,2 +np.float32,0x4255a0d9,0xbf800000,2 +np.float32,0xc255a0d9,0xbf800000,2 +np.float32,0x42d5a0d9,0x3f800000,2 +np.float32,0xc2d5a0d9,0x3f800000,2 +np.float32,0x41dbe958,0xbf350507,2 +np.float32,0xc1dbe958,0xbf350507,2 +np.float32,0x425be958,0x365eab75,2 +np.float32,0xc25be958,0x365eab75,2 +np.float32,0x42dbe958,0xbf800000,2 +np.float32,0xc2dbe958,0xbf800000,2 +np.float32,0x41e231d6,0xbf800000,2 +np.float32,0xc1e231d6,0xbf800000,2 +np.float32,0x426231d6,0x3f800000,2 +np.float32,0xc26231d6,0x3f800000,2 +np.float32,0x42e231d6,0x3f800000,2 +np.float32,0xc2e231d6,0x3f800000,2 +np.float32,0x41e87a55,0xbf3504ef,2 +np.float32,0xc1e87a55,0xbf3504ef,2 +np.float32,0x42687a55,0xb552257b,2 +np.float32,0xc2687a55,0xb552257b,2 +np.float32,0x42e87a55,0xbf800000,2 +np.float32,0xc2e87a55,0xbf800000,2 +np.float32,0x41eec2d4,0x353ef0a7,2 +np.float32,0xc1eec2d4,0x353ef0a7,2 +np.float32,0x426ec2d4,0xbf800000,2 +np.float32,0xc26ec2d4,0xbf800000,2 +np.float32,0x42eec2d4,0x3f800000,2 +np.float32,0xc2eec2d4,0x3f800000,2 +np.float32,0x41f50b53,0x3f3504ff,2 +np.float32,0xc1f50b53,0x3f3504ff,2 +np.float32,0x42750b53,0x360a6748,2 +np.float32,0xc2750b53,0x360a6748,2 +np.float32,0x42f50b53,0xbf800000,2 +np.float32,0xc2f50b53,0xbf800000,2 +np.float32,0x41fb53d2,0x3f800000,2 +np.float32,0xc1fb53d2,0x3f800000,2 +np.float32,0x427b53d2,0x3f800000,2 +np.float32,0xc27b53d2,0x3f800000,2 +np.float32,0x42fb53d2,0x3f800000,2 +np.float32,0xc2fb53d2,0x3f800000,2 +np.float32,0x4200ce28,0x3f3504f6,2 +np.float32,0xc200ce28,0x3f3504f6,2 +np.float32,0x4280ce28,0x34fdd672,2 +np.float32,0xc280ce28,0x34fdd672,2 +np.float32,0x4300ce28,0xbf800000,2 +np.float32,0xc300ce28,0xbf800000,2 +np.float32,0x4203f268,0xb6059a13,2 +np.float32,0xc203f268,0xb6059a13,2 +np.float32,0x4283f268,0xbf800000,2 +np.float32,0xc283f268,0xbf800000,2 +np.float32,0x4303f268,0x3f800000,2 +np.float32,0xc303f268,0x3f800000,2 +np.float32,0x420716a7,0xbf3504f8,2 +np.float32,0xc20716a7,0xbf3504f8,2 +np.float32,0x428716a7,0x35588c6d,2 +np.float32,0xc28716a7,0x35588c6d,2 +np.float32,0x430716a7,0xbf800000,2 +np.float32,0xc30716a7,0xbf800000,2 +np.float32,0x420a3ae7,0xbf800000,2 +np.float32,0xc20a3ae7,0xbf800000,2 +np.float32,0x428a3ae7,0x3f800000,2 +np.float32,0xc28a3ae7,0x3f800000,2 +np.float32,0x430a3ae7,0x3f800000,2 +np.float32,0xc30a3ae7,0x3f800000,2 +np.float32,0x420d5f26,0xbf3504e7,2 +np.float32,0xc20d5f26,0xbf3504e7,2 +np.float32,0x428d5f26,0xb60c0105,2 +np.float32,0xc28d5f26,0xb60c0105,2 +np.float32,0x430d5f26,0xbf800000,2 +np.float32,0xc30d5f26,0xbf800000,2 +np.float32,0x42108365,0xb512200d,2 +np.float32,0xc2108365,0xb512200d,2 +np.float32,0x42908365,0xbf800000,2 +np.float32,0xc2908365,0xbf800000,2 +np.float32,0x43108365,0x3f800000,2 +np.float32,0xc3108365,0x3f800000,2 +np.float32,0x4213a7a5,0x3f350507,2 +np.float32,0xc213a7a5,0x3f350507,2 +np.float32,0x4293a7a5,0x3661deee,2 +np.float32,0xc293a7a5,0x3661deee,2 +np.float32,0x4313a7a5,0xbf800000,2 +np.float32,0xc313a7a5,0xbf800000,2 +np.float32,0x4216cbe4,0x3f800000,2 +np.float32,0xc216cbe4,0x3f800000,2 +np.float32,0x4296cbe4,0x3f800000,2 +np.float32,0xc296cbe4,0x3f800000,2 +np.float32,0x4316cbe4,0x3f800000,2 +np.float32,0xc316cbe4,0x3f800000,2 +np.float32,0x4219f024,0x3f3504d8,2 +np.float32,0xc219f024,0x3f3504d8,2 +np.float32,0x4299f024,0xb69bde6c,2 +np.float32,0xc299f024,0xb69bde6c,2 +np.float32,0x4319f024,0xbf800000,2 +np.float32,0xc319f024,0xbf800000,2 +np.float32,0x421d1463,0xb5455799,2 +np.float32,0xc21d1463,0xb5455799,2 +np.float32,0x429d1463,0xbf800000,2 +np.float32,0xc29d1463,0xbf800000,2 +np.float32,0x431d1463,0x3f800000,2 +np.float32,0xc31d1463,0x3f800000,2 +np.float32,0x422038a3,0xbf350516,2 +np.float32,0xc22038a3,0xbf350516,2 +np.float32,0x42a038a3,0x36c6cd61,2 +np.float32,0xc2a038a3,0x36c6cd61,2 +np.float32,0x432038a3,0xbf800000,2 +np.float32,0xc32038a3,0xbf800000,2 +np.float32,0x42235ce2,0xbf800000,2 +np.float32,0xc2235ce2,0xbf800000,2 +np.float32,0x42a35ce2,0x3f800000,2 +np.float32,0xc2a35ce2,0x3f800000,2 +np.float32,0x43235ce2,0x3f800000,2 +np.float32,0xc3235ce2,0x3f800000,2 +np.float32,0x42268121,0xbf3504f6,2 +np.float32,0xc2268121,0xbf3504f6,2 +np.float32,0x42a68121,0x34e43aac,2 +np.float32,0xc2a68121,0x34e43aac,2 +np.float32,0x43268121,0xbf800000,2 +np.float32,0xc3268121,0xbf800000,2 +np.float32,0x4229a561,0x360733d0,2 +np.float32,0xc229a561,0x360733d0,2 +np.float32,0x42a9a561,0xbf800000,2 +np.float32,0xc2a9a561,0xbf800000,2 +np.float32,0x4329a561,0x3f800000,2 +np.float32,0xc329a561,0x3f800000,2 +np.float32,0x422cc9a0,0x3f3504f8,2 +np.float32,0xc22cc9a0,0x3f3504f8,2 +np.float32,0x42acc9a0,0x35655a50,2 +np.float32,0xc2acc9a0,0x35655a50,2 +np.float32,0x432cc9a0,0xbf800000,2 +np.float32,0xc32cc9a0,0xbf800000,2 +np.float32,0x422fede0,0x3f800000,2 +np.float32,0xc22fede0,0x3f800000,2 +np.float32,0x42afede0,0x3f800000,2 +np.float32,0xc2afede0,0x3f800000,2 +np.float32,0x432fede0,0x3f800000,2 +np.float32,0xc32fede0,0x3f800000,2 +np.float32,0x4233121f,0x3f3504e7,2 +np.float32,0xc233121f,0x3f3504e7,2 +np.float32,0x42b3121f,0xb60f347d,2 +np.float32,0xc2b3121f,0xb60f347d,2 +np.float32,0x4333121f,0xbf800000,2 +np.float32,0xc333121f,0xbf800000,2 +np.float32,0x4236365e,0x350bb91c,2 +np.float32,0xc236365e,0x350bb91c,2 +np.float32,0x42b6365e,0xbf800000,2 +np.float32,0xc2b6365e,0xbf800000,2 +np.float32,0x4336365e,0x3f800000,2 +np.float32,0xc336365e,0x3f800000,2 +np.float32,0x42395a9e,0xbf350507,2 +np.float32,0xc2395a9e,0xbf350507,2 +np.float32,0x42b95a9e,0x36651267,2 +np.float32,0xc2b95a9e,0x36651267,2 +np.float32,0x43395a9e,0xbf800000,2 +np.float32,0xc3395a9e,0xbf800000,2 +np.float32,0x423c7edd,0xbf800000,2 +np.float32,0xc23c7edd,0xbf800000,2 +np.float32,0x42bc7edd,0x3f800000,2 +np.float32,0xc2bc7edd,0x3f800000,2 +np.float32,0x433c7edd,0x3f800000,2 +np.float32,0xc33c7edd,0x3f800000,2 +np.float32,0x423fa31d,0xbf3504d7,2 +np.float32,0xc23fa31d,0xbf3504d7,2 +np.float32,0x42bfa31d,0xb69d7828,2 +np.float32,0xc2bfa31d,0xb69d7828,2 +np.float32,0x433fa31d,0xbf800000,2 +np.float32,0xc33fa31d,0xbf800000,2 +np.float32,0x4242c75c,0x354bbe8a,2 +np.float32,0xc242c75c,0x354bbe8a,2 +np.float32,0x42c2c75c,0xbf800000,2 +np.float32,0xc2c2c75c,0xbf800000,2 +np.float32,0x4342c75c,0x3f800000,2 +np.float32,0xc342c75c,0x3f800000,2 +np.float32,0x4245eb9c,0x3f350517,2 +np.float32,0xc245eb9c,0x3f350517,2 +np.float32,0x42c5eb9c,0x36c8671d,2 +np.float32,0xc2c5eb9c,0x36c8671d,2 +np.float32,0x4345eb9c,0xbf800000,2 +np.float32,0xc345eb9c,0xbf800000,2 +np.float32,0x42490fdb,0x3f800000,2 +np.float32,0xc2490fdb,0x3f800000,2 +np.float32,0x42c90fdb,0x3f800000,2 +np.float32,0xc2c90fdb,0x3f800000,2 +np.float32,0x43490fdb,0x3f800000,2 +np.float32,0xc3490fdb,0x3f800000,2 +np.float32,0x424c341a,0x3f3504f5,2 +np.float32,0xc24c341a,0x3f3504f5,2 +np.float32,0x42cc341a,0x34ca9ee6,2 +np.float32,0xc2cc341a,0x34ca9ee6,2 +np.float32,0x434c341a,0xbf800000,2 +np.float32,0xc34c341a,0xbf800000,2 +np.float32,0x424f585a,0xb608cd8c,2 +np.float32,0xc24f585a,0xb608cd8c,2 +np.float32,0x42cf585a,0xbf800000,2 +np.float32,0xc2cf585a,0xbf800000,2 +np.float32,0x434f585a,0x3f800000,2 +np.float32,0xc34f585a,0x3f800000,2 +np.float32,0x42527c99,0xbf3504f9,2 +np.float32,0xc2527c99,0xbf3504f9,2 +np.float32,0x42d27c99,0x35722833,2 +np.float32,0xc2d27c99,0x35722833,2 +np.float32,0x43527c99,0xbf800000,2 +np.float32,0xc3527c99,0xbf800000,2 +np.float32,0x4255a0d9,0xbf800000,2 +np.float32,0xc255a0d9,0xbf800000,2 +np.float32,0x42d5a0d9,0x3f800000,2 +np.float32,0xc2d5a0d9,0x3f800000,2 +np.float32,0x4355a0d9,0x3f800000,2 +np.float32,0xc355a0d9,0x3f800000,2 +np.float32,0x4258c518,0xbf3504e6,2 +np.float32,0xc258c518,0xbf3504e6,2 +np.float32,0x42d8c518,0xb61267f6,2 +np.float32,0xc2d8c518,0xb61267f6,2 +np.float32,0x4358c518,0xbf800000,2 +np.float32,0xc358c518,0xbf800000,2 +np.float32,0x425be958,0x365eab75,2 +np.float32,0xc25be958,0x365eab75,2 +np.float32,0x42dbe958,0xbf800000,2 +np.float32,0xc2dbe958,0xbf800000,2 +np.float32,0x435be958,0x3f800000,2 +np.float32,0xc35be958,0x3f800000,2 +np.float32,0x425f0d97,0x3f350508,2 +np.float32,0xc25f0d97,0x3f350508,2 +np.float32,0x42df0d97,0x366845e0,2 +np.float32,0xc2df0d97,0x366845e0,2 +np.float32,0x435f0d97,0xbf800000,2 +np.float32,0xc35f0d97,0xbf800000,2 +np.float32,0x426231d6,0x3f800000,2 +np.float32,0xc26231d6,0x3f800000,2 +np.float32,0x42e231d6,0x3f800000,2 +np.float32,0xc2e231d6,0x3f800000,2 +np.float32,0x436231d6,0x3f800000,2 +np.float32,0xc36231d6,0x3f800000,2 +np.float32,0x42655616,0x3f3504d7,2 +np.float32,0xc2655616,0x3f3504d7,2 +np.float32,0x42e55616,0xb69f11e5,2 +np.float32,0xc2e55616,0xb69f11e5,2 +np.float32,0x43655616,0xbf800000,2 +np.float32,0xc3655616,0xbf800000,2 +np.float32,0x42687a55,0xb552257b,2 +np.float32,0xc2687a55,0xb552257b,2 +np.float32,0x42e87a55,0xbf800000,2 +np.float32,0xc2e87a55,0xbf800000,2 +np.float32,0x43687a55,0x3f800000,2 +np.float32,0xc3687a55,0x3f800000,2 +np.float32,0x426b9e95,0xbf350517,2 +np.float32,0xc26b9e95,0xbf350517,2 +np.float32,0x42eb9e95,0x36ca00d9,2 +np.float32,0xc2eb9e95,0x36ca00d9,2 +np.float32,0x436b9e95,0xbf800000,2 +np.float32,0xc36b9e95,0xbf800000,2 +np.float32,0x426ec2d4,0xbf800000,2 +np.float32,0xc26ec2d4,0xbf800000,2 +np.float32,0x42eec2d4,0x3f800000,2 +np.float32,0xc2eec2d4,0x3f800000,2 +np.float32,0x436ec2d4,0x3f800000,2 +np.float32,0xc36ec2d4,0x3f800000,2 +np.float32,0x4271e713,0xbf3504f5,2 +np.float32,0xc271e713,0xbf3504f5,2 +np.float32,0x42f1e713,0x34b10321,2 +np.float32,0xc2f1e713,0x34b10321,2 +np.float32,0x4371e713,0xbf800000,2 +np.float32,0xc371e713,0xbf800000,2 +np.float32,0x42750b53,0x360a6748,2 +np.float32,0xc2750b53,0x360a6748,2 +np.float32,0x42f50b53,0xbf800000,2 +np.float32,0xc2f50b53,0xbf800000,2 +np.float32,0x43750b53,0x3f800000,2 +np.float32,0xc3750b53,0x3f800000,2 +np.float32,0x42782f92,0x3f3504f9,2 +np.float32,0xc2782f92,0x3f3504f9,2 +np.float32,0x42f82f92,0x357ef616,2 +np.float32,0xc2f82f92,0x357ef616,2 +np.float32,0x43782f92,0xbf800000,2 +np.float32,0xc3782f92,0xbf800000,2 +np.float32,0x427b53d2,0x3f800000,2 +np.float32,0xc27b53d2,0x3f800000,2 +np.float32,0x42fb53d2,0x3f800000,2 +np.float32,0xc2fb53d2,0x3f800000,2 +np.float32,0x437b53d2,0x3f800000,2 +np.float32,0xc37b53d2,0x3f800000,2 +np.float32,0x427e7811,0x3f3504e6,2 +np.float32,0xc27e7811,0x3f3504e6,2 +np.float32,0x42fe7811,0xb6159b6f,2 +np.float32,0xc2fe7811,0xb6159b6f,2 +np.float32,0x437e7811,0xbf800000,2 +np.float32,0xc37e7811,0xbf800000,2 +np.float32,0x4280ce28,0x34fdd672,2 +np.float32,0xc280ce28,0x34fdd672,2 +np.float32,0x4300ce28,0xbf800000,2 +np.float32,0xc300ce28,0xbf800000,2 +np.float32,0x4380ce28,0x3f800000,2 +np.float32,0xc380ce28,0x3f800000,2 +np.float32,0x42826048,0xbf350508,2 +np.float32,0xc2826048,0xbf350508,2 +np.float32,0x43026048,0x366b7958,2 +np.float32,0xc3026048,0x366b7958,2 +np.float32,0x43826048,0xbf800000,2 +np.float32,0xc3826048,0xbf800000,2 +np.float32,0x4283f268,0xbf800000,2 +np.float32,0xc283f268,0xbf800000,2 +np.float32,0x4303f268,0x3f800000,2 +np.float32,0xc303f268,0x3f800000,2 +np.float32,0x4383f268,0x3f800000,2 +np.float32,0xc383f268,0x3f800000,2 +np.float32,0x42858487,0xbf350504,2 +np.float32,0xc2858487,0xbf350504,2 +np.float32,0x43058487,0x363ea8be,2 +np.float32,0xc3058487,0x363ea8be,2 +np.float32,0x43858487,0xbf800000,2 +np.float32,0xc3858487,0xbf800000,2 +np.float32,0x428716a7,0x35588c6d,2 +np.float32,0xc28716a7,0x35588c6d,2 +np.float32,0x430716a7,0xbf800000,2 +np.float32,0xc30716a7,0xbf800000,2 +np.float32,0x438716a7,0x3f800000,2 +np.float32,0xc38716a7,0x3f800000,2 +np.float32,0x4288a8c7,0x3f350517,2 +np.float32,0xc288a8c7,0x3f350517,2 +np.float32,0x4308a8c7,0x36cb9a96,2 +np.float32,0xc308a8c7,0x36cb9a96,2 +np.float32,0x4388a8c7,0xbf800000,2 +np.float32,0xc388a8c7,0xbf800000,2 +np.float32,0x428a3ae7,0x3f800000,2 +np.float32,0xc28a3ae7,0x3f800000,2 +np.float32,0x430a3ae7,0x3f800000,2 +np.float32,0xc30a3ae7,0x3f800000,2 +np.float32,0x438a3ae7,0x3f800000,2 +np.float32,0xc38a3ae7,0x3f800000,2 +np.float32,0x428bcd06,0x3f3504f5,2 +np.float32,0xc28bcd06,0x3f3504f5,2 +np.float32,0x430bcd06,0x3497675b,2 +np.float32,0xc30bcd06,0x3497675b,2 +np.float32,0x438bcd06,0xbf800000,2 +np.float32,0xc38bcd06,0xbf800000,2 +np.float32,0x428d5f26,0xb60c0105,2 +np.float32,0xc28d5f26,0xb60c0105,2 +np.float32,0x430d5f26,0xbf800000,2 +np.float32,0xc30d5f26,0xbf800000,2 +np.float32,0x438d5f26,0x3f800000,2 +np.float32,0xc38d5f26,0x3f800000,2 +np.float32,0x428ef146,0xbf350526,2 +np.float32,0xc28ef146,0xbf350526,2 +np.float32,0x430ef146,0x3710bc40,2 +np.float32,0xc30ef146,0x3710bc40,2 +np.float32,0x438ef146,0xbf800000,2 +np.float32,0xc38ef146,0xbf800000,2 +np.float32,0x42908365,0xbf800000,2 +np.float32,0xc2908365,0xbf800000,2 +np.float32,0x43108365,0x3f800000,2 +np.float32,0xc3108365,0x3f800000,2 +np.float32,0x43908365,0x3f800000,2 +np.float32,0xc3908365,0x3f800000,2 +np.float32,0x42921585,0xbf3504e6,2 +np.float32,0xc2921585,0xbf3504e6,2 +np.float32,0x43121585,0xb618cee8,2 +np.float32,0xc3121585,0xb618cee8,2 +np.float32,0x43921585,0xbf800000,2 +np.float32,0xc3921585,0xbf800000,2 +np.float32,0x4293a7a5,0x3661deee,2 +np.float32,0xc293a7a5,0x3661deee,2 +np.float32,0x4313a7a5,0xbf800000,2 +np.float32,0xc313a7a5,0xbf800000,2 +np.float32,0x4393a7a5,0x3f800000,2 +np.float32,0xc393a7a5,0x3f800000,2 +np.float32,0x429539c5,0x3f350536,2 +np.float32,0xc29539c5,0x3f350536,2 +np.float32,0x431539c5,0x373bab34,2 +np.float32,0xc31539c5,0x373bab34,2 +np.float32,0x439539c5,0xbf800000,2 +np.float32,0xc39539c5,0xbf800000,2 +np.float32,0x4296cbe4,0x3f800000,2 +np.float32,0xc296cbe4,0x3f800000,2 +np.float32,0x4316cbe4,0x3f800000,2 +np.float32,0xc316cbe4,0x3f800000,2 +np.float32,0x4396cbe4,0x3f800000,2 +np.float32,0xc396cbe4,0x3f800000,2 +np.float32,0x42985e04,0x3f3504d7,2 +np.float32,0xc2985e04,0x3f3504d7,2 +np.float32,0x43185e04,0xb6a2455d,2 +np.float32,0xc3185e04,0xb6a2455d,2 +np.float32,0x43985e04,0xbf800000,2 +np.float32,0xc3985e04,0xbf800000,2 +np.float32,0x4299f024,0xb69bde6c,2 +np.float32,0xc299f024,0xb69bde6c,2 +np.float32,0x4319f024,0xbf800000,2 +np.float32,0xc319f024,0xbf800000,2 +np.float32,0x4399f024,0x3f800000,2 +np.float32,0xc399f024,0x3f800000,2 +np.float32,0x429b8243,0xbf3504ea,2 +np.float32,0xc29b8243,0xbf3504ea,2 +np.float32,0x431b8243,0xb5cb2eb8,2 +np.float32,0xc31b8243,0xb5cb2eb8,2 +np.float32,0x439b8243,0xbf800000,2 +np.float32,0xc39b8243,0xbf800000,2 +np.float32,0x435b2047,0x3f3504c1,2 +np.float32,0x42a038a2,0xb5e4ca7e,2 +np.float32,0x432038a2,0xbf800000,2 +np.float32,0x4345eb9b,0xbf800000,2 +np.float32,0x42c5eb9b,0xb5de638c,2 +np.float32,0x42eb9e94,0xb5d7fc9b,2 +np.float32,0x4350ea79,0x3631dadb,2 +np.float32,0x42dbe957,0xbf800000,2 +np.float32,0x425be957,0xb505522a,2 +np.float32,0x435be957,0x3f800000,2 +np.float32,0x46027eb2,0x3e7d94c9,2 +np.float32,0x4477baed,0xbe7f1824,2 +np.float32,0x454b8024,0x3e7f5268,2 +np.float32,0x455d2c09,0x3e7f40cb,2 +np.float32,0x4768d3de,0xba14b4af,2 +np.float32,0x46c1e7cd,0x3e7fb102,2 +np.float32,0x44a52949,0xbe7dc9d5,2 +np.float32,0x4454633a,0x3e7dbc7d,2 +np.float32,0x4689810b,0x3e7eb02b,2 +np.float32,0x473473cd,0xbe7eef6f,2 +np.float32,0x44a5193f,0x3e7e1b1f,2 +np.float32,0x46004b36,0x3e7dac59,2 +np.float32,0x467f604b,0x3d7ffd3a,2 +np.float32,0x45ea1805,0x3dffd2e0,2 +np.float32,0x457b6af3,0x3dff7831,2 +np.float32,0x44996159,0xbe7d85f4,2 +np.float32,0x47883553,0xbb80584e,2 +np.float32,0x44e19f0c,0xbdffcfe6,2 +np.float32,0x472b3bf6,0xbe7f7a82,2 +np.float32,0x4600bb4e,0x3a135e33,2 +np.float32,0x449f4556,0x3e7e42e5,2 +np.float32,0x474e9420,0x3dff77b2,2 +np.float32,0x45cbdb23,0x3dff7240,2 +np.float32,0x44222747,0x3dffb039,2 +np.float32,0x4772e419,0xbdff74b8,2 diff --git a/venv/Lib/site-packages/numpy/core/tests/data/umath-validation-set-exp b/venv/Lib/site-packages/numpy/core/tests/data/umath-validation-set-exp new file mode 100644 index 0000000..7c5ef3b --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/tests/data/umath-validation-set-exp @@ -0,0 +1,412 @@ +dtype,input,output,ulperrortol +## +ve denormals ## +np.float32,0x004b4716,0x3f800000,3 +np.float32,0x007b2490,0x3f800000,3 +np.float32,0x007c99fa,0x3f800000,3 +np.float32,0x00734a0c,0x3f800000,3 +np.float32,0x0070de24,0x3f800000,3 +np.float32,0x00495d65,0x3f800000,3 +np.float32,0x006894f6,0x3f800000,3 +np.float32,0x00555a76,0x3f800000,3 +np.float32,0x004e1fb8,0x3f800000,3 +np.float32,0x00687de9,0x3f800000,3 +## -ve denormals ## +np.float32,0x805b59af,0x3f800000,3 +np.float32,0x807ed8ed,0x3f800000,3 +np.float32,0x807142ad,0x3f800000,3 +np.float32,0x80772002,0x3f800000,3 +np.float32,0x8062abcb,0x3f800000,3 +np.float32,0x8045e31c,0x3f800000,3 +np.float32,0x805f01c2,0x3f800000,3 +np.float32,0x80506432,0x3f800000,3 +np.float32,0x8060089d,0x3f800000,3 +np.float32,0x8071292f,0x3f800000,3 +## floats that output a denormal ## +np.float32,0xc2cf3fc1,0x00000001,3 +np.float32,0xc2c79726,0x00000021,3 +np.float32,0xc2cb295d,0x00000005,3 +np.float32,0xc2b49e6b,0x00068c4c,3 +np.float32,0xc2ca8116,0x00000008,3 +np.float32,0xc2c23f82,0x000001d7,3 +np.float32,0xc2cb69c0,0x00000005,3 +np.float32,0xc2cc1f4d,0x00000003,3 +np.float32,0xc2ae094e,0x00affc4c,3 +np.float32,0xc2c86c44,0x00000015,3 +## random floats between -87.0f and 88.0f ## +np.float32,0x4030d7e0,0x417d9a05,3 +np.float32,0x426f60e8,0x6aa1be2c,3 +np.float32,0x41a1b220,0x4e0efc11,3 +np.float32,0xc20cc722,0x26159da7,3 +np.float32,0x41c492bc,0x512ec79d,3 +np.float32,0x40980210,0x42e73a0e,3 +np.float32,0xbf1f7b80,0x3f094de3,3 +np.float32,0x42a678a4,0x7b87a383,3 +np.float32,0xc20f3cfd,0x25a1c304,3 +np.float32,0x423ff34c,0x6216467f,3 +np.float32,0x00000000,0x3f800000,3 +## floats that cause an overflow ## +np.float32,0x7f06d8c1,0x7f800000,3 +np.float32,0x7f451912,0x7f800000,3 +np.float32,0x7ecceac3,0x7f800000,3 +np.float32,0x7f643b45,0x7f800000,3 +np.float32,0x7e910ea0,0x7f800000,3 +np.float32,0x7eb4756b,0x7f800000,3 +np.float32,0x7f4ec708,0x7f800000,3 +np.float32,0x7f6b4551,0x7f800000,3 +np.float32,0x7d8edbda,0x7f800000,3 +np.float32,0x7f730718,0x7f800000,3 +np.float32,0x42b17217,0x7f7fff84,3 +np.float32,0x42b17218,0x7f800000,3 +np.float32,0x42b17219,0x7f800000,3 +np.float32,0xfef2b0bc,0x00000000,3 +np.float32,0xff69f83e,0x00000000,3 +np.float32,0xff4ecb12,0x00000000,3 +np.float32,0xfeac6d86,0x00000000,3 +np.float32,0xfde0cdb8,0x00000000,3 +np.float32,0xff26aef4,0x00000000,3 +np.float32,0xff6f9277,0x00000000,3 +np.float32,0xff7adfc4,0x00000000,3 +np.float32,0xff0ad40e,0x00000000,3 +np.float32,0xff6fd8f3,0x00000000,3 +np.float32,0xc2cff1b4,0x00000001,3 +np.float32,0xc2cff1b5,0x00000000,3 +np.float32,0xc2cff1b6,0x00000000,3 +np.float32,0x7f800000,0x7f800000,3 +np.float32,0xff800000,0x00000000,3 +np.float32,0x4292f27c,0x7480000a,3 +np.float32,0x42a920be,0x7c7fff94,3 +np.float32,0x41c214c9,0x50ffffd9,3 +np.float32,0x41abe686,0x4effffd9,3 +np.float32,0x4287db5a,0x707fffd3,3 +np.float32,0x41902cbb,0x4c800078,3 +np.float32,0x42609466,0x67ffffeb,3 +np.float32,0x41a65af5,0x4e7fffd1,3 +np.float32,0x417f13ff,0x4affffc9,3 +np.float32,0x426d0e6c,0x6a3504f2,3 +np.float32,0x41bc8934,0x507fff51,3 +np.float32,0x42a7bdde,0x7c0000d6,3 +np.float32,0x4120cf66,0x46b504f6,3 +np.float32,0x4244da8f,0x62ffff1a,3 +np.float32,0x41a0cf69,0x4e000034,3 +np.float32,0x41cd2bec,0x52000005,3 +np.float32,0x42893e41,0x7100009e,3 +np.float32,0x41b437e1,0x4fb50502,3 +np.float32,0x41d8430f,0x5300001d,3 +np.float32,0x4244da92,0x62ffffda,3 +np.float32,0x41a0cf63,0x4dffffa9,3 +np.float32,0x3eb17218,0x3fb504f3,3 +np.float32,0x428729e8,0x703504dc,3 +np.float32,0x41a0cf67,0x4e000014,3 +np.float32,0x4252b77d,0x65800011,3 +np.float32,0x41902cb9,0x4c800058,3 +np.float32,0x42a0cf67,0x79800052,3 +np.float32,0x4152b77b,0x48ffffe9,3 +np.float32,0x41265af3,0x46ffffc8,3 +np.float32,0x42187e0b,0x5affff9a,3 +np.float32,0xc0d2b77c,0x3ab504f6,3 +np.float32,0xc283b2ac,0x10000072,3 +np.float32,0xc1cff1b4,0x2cb504f5,3 +np.float32,0xc05dce9e,0x3d000000,3 +np.float32,0xc28ec9d2,0x0bfffea5,3 +np.float32,0xc23c893a,0x1d7fffde,3 +np.float32,0xc2a920c0,0x027fff6c,3 +np.float32,0xc1f9886f,0x2900002b,3 +np.float32,0xc2c42920,0x000000b5,3 +np.float32,0xc2893e41,0x0dfffec5,3 +np.float32,0xc2c4da93,0x00000080,3 +np.float32,0xc17f1401,0x3400000c,3 +np.float32,0xc1902cb6,0x327fffaf,3 +np.float32,0xc27c4e3b,0x11ffffc5,3 +np.float32,0xc268e5c5,0x157ffe9d,3 +np.float32,0xc2b4e953,0x0005a826,3 +np.float32,0xc287db5a,0x0e800016,3 +np.float32,0xc207db5a,0x2700000b,3 +np.float32,0xc2b2d4fe,0x000ffff1,3 +np.float32,0xc268e5c0,0x157fffdd,3 +np.float32,0xc22920bd,0x2100003b,3 +np.float32,0xc2902caf,0x0b80011e,3 +np.float32,0xc1902cba,0x327fff2f,3 +np.float32,0xc2ca6625,0x00000008,3 +np.float32,0xc280ece8,0x10fffeb5,3 +np.float32,0xc2918f94,0x0b0000ea,3 +np.float32,0xc29b43d5,0x077ffffc,3 +np.float32,0xc1e61ff7,0x2ab504f5,3 +np.float32,0xc2867878,0x0effff15,3 +np.float32,0xc2a2324a,0x04fffff4,3 +#float64 +## near zero ## +np.float64,0x8000000000000000,0x3ff0000000000000,1 +np.float64,0x8010000000000000,0x3ff0000000000000,1 +np.float64,0x8000000000000001,0x3ff0000000000000,1 +np.float64,0x8360000000000000,0x3ff0000000000000,1 +np.float64,0x9a70000000000000,0x3ff0000000000000,1 +np.float64,0xb9b0000000000000,0x3ff0000000000000,1 +np.float64,0xb810000000000000,0x3ff0000000000000,1 +np.float64,0xbc30000000000000,0x3ff0000000000000,1 +np.float64,0xb6a0000000000000,0x3ff0000000000000,1 +np.float64,0x0000000000000000,0x3ff0000000000000,1 +np.float64,0x0010000000000000,0x3ff0000000000000,1 +np.float64,0x0000000000000001,0x3ff0000000000000,1 +np.float64,0x0360000000000000,0x3ff0000000000000,1 +np.float64,0x1a70000000000000,0x3ff0000000000000,1 +np.float64,0x3c30000000000000,0x3ff0000000000000,1 +np.float64,0x36a0000000000000,0x3ff0000000000000,1 +np.float64,0x39b0000000000000,0x3ff0000000000000,1 +np.float64,0x3810000000000000,0x3ff0000000000000,1 +## underflow ## +np.float64,0xc0c6276800000000,0x0000000000000000,1 +np.float64,0xc0c62d918ce2421d,0x0000000000000000,1 +np.float64,0xc0c62d918ce2421e,0x0000000000000000,1 +np.float64,0xc0c62d91a0000000,0x0000000000000000,1 +np.float64,0xc0c62d9180000000,0x0000000000000000,1 +np.float64,0xc0c62dea45ee3e06,0x0000000000000000,1 +np.float64,0xc0c62dea45ee3e07,0x0000000000000000,1 +np.float64,0xc0c62dea40000000,0x0000000000000000,1 +np.float64,0xc0c62dea60000000,0x0000000000000000,1 +np.float64,0xc0875f1120000000,0x0000000000000000,1 +np.float64,0xc0875f113c30b1c8,0x0000000000000000,1 +np.float64,0xc0875f1140000000,0x0000000000000000,1 +np.float64,0xc093480000000000,0x0000000000000000,1 +np.float64,0xffefffffffffffff,0x0000000000000000,1 +np.float64,0xc7efffffe0000000,0x0000000000000000,1 +## overflow ## +np.float64,0x40862e52fefa39ef,0x7ff0000000000000,1 +np.float64,0x40872e42fefa39ef,0x7ff0000000000000,1 +## +/- INF, +/- NAN ## +np.float64,0x7ff0000000000000,0x7ff0000000000000,1 +np.float64,0xfff0000000000000,0x0000000000000000,1 +np.float64,0x7ff8000000000000,0x7ff8000000000000,1 +np.float64,0xfff8000000000000,0xfff8000000000000,1 +## output denormal ## +np.float64,0xc087438520000000,0x0000000000000001,1 +np.float64,0xc08743853f2f4461,0x0000000000000001,1 +np.float64,0xc08743853f2f4460,0x0000000000000001,1 +np.float64,0xc087438540000000,0x0000000000000001,1 +## between -745.13321910 and 709.78271289 ## +np.float64,0xbff760cd14774bd9,0x3fcdb14ced00ceb6,1 +np.float64,0xbff760cd20000000,0x3fcdb14cd7993879,1 +np.float64,0xbff760cd00000000,0x3fcdb14d12fbd264,1 +np.float64,0xc07f1cf360000000,0x130c1b369af14fda,1 +np.float64,0xbeb0000000000000,0x3feffffe00001000,1 +np.float64,0xbd70000000000000,0x3fefffffffffe000,1 +np.float64,0xc084fd46e5c84952,0x0360000000000139,1 +np.float64,0xc084fd46e5c84953,0x035ffffffffffe71,1 +np.float64,0xc084fd46e0000000,0x0360000b9096d32c,1 +np.float64,0xc084fd4700000000,0x035fff9721d12104,1 +np.float64,0xc086232bc0000000,0x0010003af5e64635,1 +np.float64,0xc086232bdd7abcd2,0x001000000000007c,1 +np.float64,0xc086232bdd7abcd3,0x000ffffffffffe7c,1 +np.float64,0xc086232be0000000,0x000ffffaf57a6fc9,1 +np.float64,0xc086233920000000,0x000fe590e3b45eb0,1 +np.float64,0xc086233938000000,0x000fe56133493c57,1 +np.float64,0xc086233940000000,0x000fe5514deffbbc,1 +np.float64,0xc086234c98000000,0x000fbf1024c32ccb,1 +np.float64,0xc086234ca0000000,0x000fbf0065bae78d,1 +np.float64,0xc086234c80000000,0x000fbf3f623a7724,1 +np.float64,0xc086234ec0000000,0x000fbad237c846f9,1 +np.float64,0xc086234ec8000000,0x000fbac27cfdec97,1 +np.float64,0xc086234ee0000000,0x000fba934cfd3dc2,1 +np.float64,0xc086234ef0000000,0x000fba73d7f618d9,1 +np.float64,0xc086234f00000000,0x000fba54632dddc0,1 +np.float64,0xc0862356e0000000,0x000faae0945b761a,1 +np.float64,0xc0862356f0000000,0x000faac13eb9a310,1 +np.float64,0xc086235700000000,0x000faaa1e9567b0a,1 +np.float64,0xc086236020000000,0x000f98cd75c11ed7,1 +np.float64,0xc086236ca0000000,0x000f8081b4d93f89,1 +np.float64,0xc086236cb0000000,0x000f8062b3f4d6c5,1 +np.float64,0xc086236cc0000000,0x000f8043b34e6f8c,1 +np.float64,0xc086238d98000000,0x000f41220d9b0d2c,1 +np.float64,0xc086238da0000000,0x000f4112cc80a01f,1 +np.float64,0xc086238d80000000,0x000f414fd145db5b,1 +np.float64,0xc08624fd00000000,0x000cbfce8ea1e6c4,1 +np.float64,0xc086256080000000,0x000c250747fcd46e,1 +np.float64,0xc08626c480000000,0x000a34f4bd975193,1 +np.float64,0xbf50000000000000,0x3feff800ffeaac00,1 +np.float64,0xbe10000000000000,0x3fefffffff800000,1 +np.float64,0xbcd0000000000000,0x3feffffffffffff8,1 +np.float64,0xc055d589e0000000,0x38100004bf94f63e,1 +np.float64,0xc055d58a00000000,0x380ffff97f292ce8,1 +np.float64,0xbfd962d900000000,0x3fe585a4b00110e1,1 +np.float64,0x3ff4bed280000000,0x400d411e7a58a303,1 +np.float64,0x3fff0b3620000000,0x401bd7737ffffcf3,1 +np.float64,0x3ff0000000000000,0x4005bf0a8b145769,1 +np.float64,0x3eb0000000000000,0x3ff0000100000800,1 +np.float64,0x3d70000000000000,0x3ff0000000001000,1 +np.float64,0x40862e42e0000000,0x7fefff841808287f,1 +np.float64,0x40862e42fefa39ef,0x7fefffffffffff2a,1 +np.float64,0x40862e0000000000,0x7feef85a11e73f2d,1 +np.float64,0x4000000000000000,0x401d8e64b8d4ddae,1 +np.float64,0x4009242920000000,0x40372a52c383a488,1 +np.float64,0x4049000000000000,0x44719103e4080b45,1 +np.float64,0x4008000000000000,0x403415e5bf6fb106,1 +np.float64,0x3f50000000000000,0x3ff00400800aab55,1 +np.float64,0x3e10000000000000,0x3ff0000000400000,1 +np.float64,0x3cd0000000000000,0x3ff0000000000004,1 +np.float64,0x40562e40a0000000,0x47effed088821c3f,1 +np.float64,0x40562e42e0000000,0x47effff082e6c7ff,1 +np.float64,0x40562e4300000000,0x47f00000417184b8,1 +np.float64,0x3fe8000000000000,0x4000ef9db467dcf8,1 +np.float64,0x402b12e8d4f33589,0x412718f68c71a6fe,1 +np.float64,0x402b12e8d4f3358a,0x412718f68c71a70a,1 +np.float64,0x402b12e8c0000000,0x412718f59a7f472e,1 +np.float64,0x402b12e8e0000000,0x412718f70c0eac62,1 +##use 1th entry +np.float64,0x40631659AE147CB4,0x4db3a95025a4890f,1 +np.float64,0xC061B87D2E85A4E2,0x332640c8e2de2c51,1 +np.float64,0x405A4A50BE243AF4,0x496a45e4b7f0339a,1 +np.float64,0xC0839898B98EC5C6,0x0764027828830df4,1 +#use 2th entry +np.float64,0xC072428C44B6537C,0x2596ade838b96f3e,1 +np.float64,0xC053057C5E1AE9BF,0x3912c8fad18fdadf,1 +np.float64,0x407E89C78328BAA3,0x6bfe35d5b9a1a194,1 +np.float64,0x4083501B6DD87112,0x77a855503a38924e,1 +#use 3th entry +np.float64,0x40832C6195F24540,0x7741e73c80e5eb2f,1 +np.float64,0xC083D4CD557C2EC9,0x06b61727c2d2508e,1 +np.float64,0x400C48F5F67C99BD,0x404128820f02b92e,1 +np.float64,0x4056E36D9B2DF26A,0x4830f52ff34a8242,1 +#use 4th entry +np.float64,0x4080FF700D8CBD06,0x70fa70df9bc30f20,1 +np.float64,0x406C276D39E53328,0x543eb8e20a8f4741,1 +np.float64,0xC070D6159BBD8716,0x27a4a0548c904a75,1 +np.float64,0xC052EBCF8ED61F83,0x391c0e92368d15e4,1 +#use 5th entry +np.float64,0xC061F892A8AC5FBE,0x32f807a89efd3869,1 +np.float64,0x4021D885D2DBA085,0x40bd4dc86d3e3270,1 +np.float64,0x40767AEEEE7D4FCF,0x605e22851ee2afb7,1 +np.float64,0xC0757C5D75D08C80,0x20f0751599b992a2,1 +#use 6th entry +np.float64,0x405ACF7A284C4CE3,0x499a4e0b7a27027c,1 +np.float64,0xC085A6C9E80D7AF5,0x0175914009d62ec2,1 +np.float64,0xC07E4C02F86F1DAE,0x1439269b29a9231e,1 +np.float64,0x4080D80F9691CC87,0x7088a6cdafb041de,1 +#use 7th entry +np.float64,0x407FDFD84FBA0AC1,0x6deb1ae6f9bc4767,1 +np.float64,0x40630C06A1A2213D,0x4dac7a9d51a838b7,1 +np.float64,0x40685FDB30BB8B4F,0x5183f5cc2cac9e79,1 +np.float64,0x408045A2208F77F4,0x6ee299e08e2aa2f0,1 +#use 8th entry +np.float64,0xC08104E391F5078B,0x0ed397b7cbfbd230,1 +np.float64,0xC031501CAEFAE395,0x3e6040fd1ea35085,1 +np.float64,0xC079229124F6247C,0x1babf4f923306b1e,1 +np.float64,0x407FB65F44600435,0x6db03beaf2512b8a,1 +#use 9th entry +np.float64,0xC07EDEE8E8E8A5AC,0x136536cec9cbef48,1 +np.float64,0x4072BB4086099A14,0x5af4d3c3008b56cc,1 +np.float64,0x4050442A2EC42CB4,0x45cd393bd8fad357,1 +np.float64,0xC06AC28FB3D419B4,0x2ca1b9d3437df85f,1 +#use 10th entry +np.float64,0x40567FC6F0A68076,0x480c977fd5f3122e,1 +np.float64,0x40620A2F7EDA59BB,0x4cf278e96f4ce4d7,1 +np.float64,0xC085044707CD557C,0x034aad6c968a045a,1 +np.float64,0xC07374EA5AC516AA,0x23dd6afdc03e83d5,1 +#use 11th entry +np.float64,0x4073CC95332619C1,0x5c804b1498bbaa54,1 +np.float64,0xC0799FEBBE257F31,0x1af6a954c43b87d2,1 +np.float64,0x408159F19EA424F6,0x7200858efcbfc84d,1 +np.float64,0x404A81F6F24C0792,0x44b664a07ce5bbfa,1 +#use 12th entry +np.float64,0x40295FF1EFB9A741,0x4113c0e74c52d7b0,1 +np.float64,0x4073975F4CC411DA,0x5c32be40b4fec2c1,1 +np.float64,0x406E9DE52E82A77E,0x56049c9a3f1ae089,1 +np.float64,0x40748C2F52560ED9,0x5d93bc14fd4cd23b,1 +#use 13th entry +np.float64,0x4062A553CDC4D04C,0x4d6266bfde301318,1 +np.float64,0xC079EC1D63598AB7,0x1a88cb184dab224c,1 +np.float64,0xC0725C1CB3167427,0x25725b46f8a081f6,1 +np.float64,0x407888771D9B45F9,0x6353b1ec6bd7ce80,1 +#use 14th entry +np.float64,0xC082CBA03AA89807,0x09b383723831ce56,1 +np.float64,0xC083A8961BB67DD7,0x0735b118d5275552,1 +np.float64,0xC076BC6ECA12E7E3,0x1f2222679eaef615,1 +np.float64,0xC072752503AA1A5B,0x254eb832242c77e1,1 +#use 15th entry +np.float64,0xC058800792125DEC,0x371882372a0b48d4,1 +np.float64,0x4082909FD863E81C,0x7580d5f386920142,1 +np.float64,0xC071616F8FB534F9,0x26dbe20ef64a412b,1 +np.float64,0x406D1AB571CAA747,0x54ee0d55cb38ac20,1 +#use 16th entry +np.float64,0x406956428B7DAD09,0x52358682c271237f,1 +np.float64,0xC07EFC2D9D17B621,0x133b3e77c27a4d45,1 +np.float64,0xC08469BAC5BA3CCA,0x050863e5f42cc52f,1 +np.float64,0x407189D9626386A5,0x593cb1c0b3b5c1d3,1 +#use 17th entry +np.float64,0x4077E652E3DEB8C6,0x6269a10dcbd3c752,1 +np.float64,0x407674C97DB06878,0x605485dcc2426ec2,1 +np.float64,0xC07CE9969CF4268D,0x16386cf8996669f2,1 +np.float64,0x40780EE32D5847C4,0x62a436bd1abe108d,1 +#use 18th entry +np.float64,0x4076C3AA5E1E8DA1,0x60c62f56a5e72e24,1 +np.float64,0xC0730AFC7239B9BE,0x24758ead095cec1e,1 +np.float64,0xC085CC2B9C420DDB,0x0109cdaa2e5694c1,1 +np.float64,0x406D0765CB6D7AA4,0x54e06f8dd91bd945,1 +#use 19th entry +np.float64,0xC082D011F3B495E7,0x09a6647661d279c2,1 +np.float64,0xC072826AF8F6AFBC,0x253acd3cd224507e,1 +np.float64,0x404EB9C4810CEA09,0x457933dbf07e8133,1 +np.float64,0x408284FBC97C58CE,0x755f6eb234aa4b98,1 +#use 20th entry +np.float64,0x40856008CF6EDC63,0x7d9c0b3c03f4f73c,1 +np.float64,0xC077CB2E9F013B17,0x1d9b3d3a166a55db,1 +np.float64,0xC0479CA3C20AD057,0x3bad40e081555b99,1 +np.float64,0x40844CD31107332A,0x7a821d70aea478e2,1 +#use 21th entry +np.float64,0xC07C8FCC0BFCC844,0x16ba1cc8c539d19b,1 +np.float64,0xC085C4E9A3ABA488,0x011ff675ba1a2217,1 +np.float64,0x4074D538B32966E5,0x5dfd9d78043c6ad9,1 +np.float64,0xC0630CA16902AD46,0x3231a446074cede6,1 +#use 22th entry +np.float64,0xC06C826733D7D0B7,0x2b5f1078314d41e1,1 +np.float64,0xC0520DF55B2B907F,0x396c13a6ce8e833e,1 +np.float64,0xC080712072B0F437,0x107eae02d11d98ea,1 +np.float64,0x40528A6150E19EFB,0x469fdabda02228c5,1 +#use 23th entry +np.float64,0xC07B1D74B6586451,0x18d1253883ae3b48,1 +np.float64,0x4045AFD7867DAEC0,0x43d7d634fc4c5d98,1 +np.float64,0xC07A08B91F9ED3E2,0x1a60973e6397fc37,1 +np.float64,0x407B3ECF0AE21C8C,0x673e03e9d98d7235,1 +#use 24th entry +np.float64,0xC078AEB6F30CEABF,0x1c530b93ab54a1b3,1 +np.float64,0x4084495006A41672,0x7a775b6dc7e63064,1 +np.float64,0x40830B1C0EBF95DD,0x76e1e6eed77cfb89,1 +np.float64,0x407D93E8F33D8470,0x6a9adbc9e1e4f1e5,1 +#use 25th entry +np.float64,0x4066B11A09EFD9E8,0x504dd528065c28a7,1 +np.float64,0x408545823723AEEB,0x7d504a9b1844f594,1 +np.float64,0xC068C711F2CA3362,0x2e104f3496ea118e,1 +np.float64,0x407F317FCC3CA873,0x6cf0732c9948ebf4,1 +#use 26th entry +np.float64,0x407AFB3EBA2ED50F,0x66dc28a129c868d5,1 +np.float64,0xC075377037708ADE,0x21531a329f3d793e,1 +np.float64,0xC07C30066A1F3246,0x174448baa16ded2b,1 +np.float64,0xC06689A75DE2ABD3,0x2fad70662fae230b,1 +#use 27th entry +np.float64,0x4081514E9FCCF1E0,0x71e673b9efd15f44,1 +np.float64,0xC0762C710AF68460,0x1ff1ed7d8947fe43,1 +np.float64,0xC0468102FF70D9C4,0x3be0c3a8ff3419a3,1 +np.float64,0xC07EA4CEEF02A83E,0x13b908f085102c61,1 +#use 28th entry +np.float64,0xC06290B04AE823C4,0x328a83da3c2e3351,1 +np.float64,0xC0770EB1D1C395FB,0x1eab281c1f1db5fe,1 +np.float64,0xC06F5D4D838A5BAE,0x29500ea32fb474ea,1 +np.float64,0x40723B3133B54C5D,0x5a3c82c7c3a2b848,1 +#use 29th entry +np.float64,0x4085E6454CE3B4AA,0x7f20319b9638d06a,1 +np.float64,0x408389F2A0585D4B,0x7850667c58aab3d0,1 +np.float64,0xC0382798F9C8AE69,0x3dc1c79fe8739d6d,1 +np.float64,0xC08299D827608418,0x0a4335f76cdbaeb5,1 +#use 30th entry +np.float64,0xC06F3DED43301BF1,0x2965670ae46750a8,1 +np.float64,0xC070CAF6BDD577D9,0x27b4aa4ffdd29981,1 +np.float64,0x4078529AD4B2D9F2,0x6305c12755d5e0a6,1 +np.float64,0xC055B14E75A31B96,0x381c2eda6d111e5d,1 +#use 31th entry +np.float64,0x407B13EE414FA931,0x6700772c7544564d,1 +np.float64,0x407EAFDE9DE3EC54,0x6c346a0e49724a3c,1 +np.float64,0xC08362F398B9530D,0x07ffeddbadf980cb,1 +np.float64,0x407E865CDD9EEB86,0x6bf866cac5e0d126,1 +#use 32th entry +np.float64,0x407FB62DBC794C86,0x6db009f708ac62cb,1 +np.float64,0xC063D0BAA68CDDDE,0x31a3b2a51ce50430,1 +np.float64,0xC05E7706A2231394,0x34f24bead6fab5c9,1 +np.float64,0x4083E3A06FDE444E,0x79527b7a386d1937,1 diff --git a/venv/Lib/site-packages/numpy/core/tests/data/umath-validation-set-log b/venv/Lib/site-packages/numpy/core/tests/data/umath-validation-set-log new file mode 100644 index 0000000..b8f6b08 --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/tests/data/umath-validation-set-log @@ -0,0 +1,271 @@ +dtype,input,output,ulperrortol +## +ve denormals ## +np.float32,0x004b4716,0xc2afbc1b,4 +np.float32,0x007b2490,0xc2aec01e,4 +np.float32,0x007c99fa,0xc2aeba17,4 +np.float32,0x00734a0c,0xc2aee1dc,4 +np.float32,0x0070de24,0xc2aeecba,4 +np.float32,0x007fffff,0xc2aeac50,4 +np.float32,0x00000001,0xc2ce8ed0,4 +## -ve denormals ## +np.float32,0x80495d65,0xffc00000,4 +np.float32,0x806894f6,0xffc00000,4 +np.float32,0x80555a76,0xffc00000,4 +np.float32,0x804e1fb8,0xffc00000,4 +np.float32,0x80687de9,0xffc00000,4 +np.float32,0x807fffff,0xffc00000,4 +np.float32,0x80000001,0xffc00000,4 +## +/-0.0f, +/-FLT_MIN +/-FLT_MAX ## +np.float32,0x00000000,0xff800000,4 +np.float32,0x80000000,0xff800000,4 +np.float32,0x7f7fffff,0x42b17218,4 +np.float32,0x80800000,0xffc00000,4 +np.float32,0xff7fffff,0xffc00000,4 +## 1.00f + 0x00000001 ## +np.float32,0x3f800000,0x00000000,4 +np.float32,0x3f800001,0x33ffffff,4 +np.float32,0x3f800002,0x347ffffe,4 +np.float32,0x3f7fffff,0xb3800000,4 +np.float32,0x3f7ffffe,0xb4000000,4 +np.float32,0x3f7ffffd,0xb4400001,4 +np.float32,0x402df853,0x3f7ffffe,4 +np.float32,0x402df854,0x3f7fffff,4 +np.float32,0x402df855,0x3f800000,4 +np.float32,0x402df856,0x3f800001,4 +np.float32,0x3ebc5ab0,0xbf800001,4 +np.float32,0x3ebc5ab1,0xbf800000,4 +np.float32,0x3ebc5ab2,0xbf800000,4 +np.float32,0x3ebc5ab3,0xbf7ffffe,4 +np.float32,0x423ef575,0x407768ab,4 +np.float32,0x427b8c61,0x408485dd,4 +np.float32,0x4211e9ee,0x406630b0,4 +np.float32,0x424d5c41,0x407c0fed,4 +np.float32,0x42be722a,0x4091cc91,4 +np.float32,0x42b73d30,0x4090908b,4 +np.float32,0x427e48e2,0x4084de7f,4 +np.float32,0x428f759b,0x4088bba3,4 +np.float32,0x41629069,0x4029a0cc,4 +np.float32,0x4272c99d,0x40836379,4 +np.float32,0x4d1b7458,0x4197463d,4 +np.float32,0x4f10c594,0x41ace2b2,4 +np.float32,0x4ea397c2,0x41a85171,4 +np.float32,0x4fefa9d1,0x41b6769c,4 +np.float32,0x4ebac6ab,0x41a960dc,4 +np.float32,0x4f6efb42,0x41b0e535,4 +np.float32,0x4e9ab8e7,0x41a7df44,4 +np.float32,0x4e81b5d1,0x41a67625,4 +np.float32,0x5014d9f2,0x41b832bd,4 +np.float32,0x4f02175c,0x41ac07b8,4 +np.float32,0x7f034f89,0x42b01c47,4 +np.float32,0x7f56d00e,0x42b11849,4 +np.float32,0x7f1cd5f6,0x42b0773a,4 +np.float32,0x7e979174,0x42af02d7,4 +np.float32,0x7f23369f,0x42b08ba2,4 +np.float32,0x7f0637ae,0x42b0277d,4 +np.float32,0x7efcb6e8,0x42b00897,4 +np.float32,0x7f7907c8,0x42b163f6,4 +np.float32,0x7e95c4c2,0x42aefcba,4 +np.float32,0x7f4577b2,0x42b0ed2d,4 +np.float32,0x3f49c92e,0xbe73ae84,4 +np.float32,0x3f4a23d1,0xbe71e2f8,4 +np.float32,0x3f4abb67,0xbe6ee430,4 +np.float32,0x3f48169a,0xbe7c5532,4 +np.float32,0x3f47f5fa,0xbe7cfc37,4 +np.float32,0x3f488309,0xbe7a2ad8,4 +np.float32,0x3f479df4,0xbe7ebf5f,4 +np.float32,0x3f47cfff,0xbe7dbec9,4 +np.float32,0x3f496704,0xbe75a125,4 +np.float32,0x3f478ee8,0xbe7f0c92,4 +np.float32,0x3f4a763b,0xbe7041ce,4 +np.float32,0x3f47a108,0xbe7eaf94,4 +np.float32,0x3f48136c,0xbe7c6578,4 +np.float32,0x3f481c17,0xbe7c391c,4 +np.float32,0x3f47cd28,0xbe7dcd56,4 +np.float32,0x3f478be8,0xbe7f1bf7,4 +np.float32,0x3f4c1f8e,0xbe67e367,4 +np.float32,0x3f489b0c,0xbe79b03f,4 +np.float32,0x3f4934cf,0xbe76a08a,4 +np.float32,0x3f4954df,0xbe75fd6a,4 +np.float32,0x3f47a3f5,0xbe7ea093,4 +np.float32,0x3f4ba4fc,0xbe6a4b02,4 +np.float32,0x3f47a0e1,0xbe7eb05c,4 +np.float32,0x3f48c30a,0xbe78e42f,4 +np.float32,0x3f48cab8,0xbe78bd05,4 +np.float32,0x3f4b0569,0xbe6d6ea4,4 +np.float32,0x3f47de32,0xbe7d7607,4 +np.float32,0x3f477328,0xbe7f9b00,4 +np.float32,0x3f496dab,0xbe757f52,4 +np.float32,0x3f47662c,0xbe7fddac,4 +np.float32,0x3f48ddd8,0xbe785b80,4 +np.float32,0x3f481866,0xbe7c4bff,4 +np.float32,0x3f48b119,0xbe793fb6,4 +np.float32,0x3f48c7e8,0xbe78cb5c,4 +np.float32,0x3f4985f6,0xbe7503da,4 +np.float32,0x3f483fdf,0xbe7b8212,4 +np.float32,0x3f4b1c76,0xbe6cfa67,4 +np.float32,0x3f480b2e,0xbe7c8fa8,4 +np.float32,0x3f48745f,0xbe7a75bf,4 +np.float32,0x3f485bda,0xbe7af308,4 +np.float32,0x3f47a660,0xbe7e942c,4 +np.float32,0x3f47d4d5,0xbe7da600,4 +np.float32,0x3f4b0a26,0xbe6d56be,4 +np.float32,0x3f4a4883,0xbe712924,4 +np.float32,0x3f4769e7,0xbe7fca84,4 +np.float32,0x3f499702,0xbe74ad3f,4 +np.float32,0x3f494ab1,0xbe763131,4 +np.float32,0x3f476b69,0xbe7fc2c6,4 +np.float32,0x3f4884e8,0xbe7a214a,4 +np.float32,0x3f486945,0xbe7aae76,4 +#float64 +## +ve denormal ## +np.float64,0x0000000000000001,0xc0874385446d71c3,1 +np.float64,0x0001000000000000,0xc086395a2079b70c,1 +np.float64,0x000fffffffffffff,0xc086232bdd7abcd2,1 +np.float64,0x0007ad63e2168cb6,0xc086290bc0b2980f,1 +## -ve denormal ## +np.float64,0x8000000000000001,0xfff8000000000001,1 +np.float64,0x8001000000000000,0xfff8000000000001,1 +np.float64,0x800fffffffffffff,0xfff8000000000001,1 +np.float64,0x8007ad63e2168cb6,0xfff8000000000001,1 +## +/-0.0f, MAX, MIN## +np.float64,0x0000000000000000,0xfff0000000000000,1 +np.float64,0x8000000000000000,0xfff0000000000000,1 +np.float64,0x7fefffffffffffff,0x40862e42fefa39ef,1 +np.float64,0xffefffffffffffff,0xfff8000000000001,1 +## near 1.0f ## +np.float64,0x3ff0000000000000,0x0000000000000000,1 +np.float64,0x3fe8000000000000,0xbfd269621134db92,1 +np.float64,0x3ff0000000000001,0x3cafffffffffffff,1 +np.float64,0x3ff0000020000000,0x3e7fffffe000002b,1 +np.float64,0x3ff0000000000001,0x3cafffffffffffff,1 +np.float64,0x3fefffffe0000000,0xbe70000008000005,1 +np.float64,0x3fefffffffffffff,0xbca0000000000000,1 +## random numbers ## +np.float64,0x02500186f3d9da56,0xc0855b8abf135773,1 +np.float64,0x09200815a3951173,0xc082ff1ad7131bdc,1 +np.float64,0x0da029623b0243d4,0xc0816fc994695bb5,1 +np.float64,0x48703b8ac483a382,0x40579213a313490b,1 +np.float64,0x09207b74c87c9860,0xc082fee20ff349ef,1 +np.float64,0x62c077698e8df947,0x407821c996d110f0,1 +np.float64,0x2350b45e87c3cfb0,0xc073d6b16b51d072,1 +np.float64,0x3990a23f9ff2b623,0xc051aa60eadd8c61,1 +np.float64,0x0d011386a116c348,0xc081a6cc7ea3b8fb,1 +np.float64,0x1fe0f0303ebe273a,0xc0763870b78a81ca,1 +np.float64,0x0cd1260121d387da,0xc081b7668d61a9d1,1 +np.float64,0x1e6135a8f581d422,0xc077425ac10f08c2,1 +np.float64,0x622168db5fe52d30,0x4077b3c669b9fadb,1 +np.float64,0x69f188e1ec6d1718,0x407d1e2f18c63889,1 +np.float64,0x3aa1bf1d9c4dd1a3,0xc04d682e24bde479,1 +np.float64,0x6c81c4011ce4f683,0x407ee5190e8a8e6a,1 +np.float64,0x2191fa55aa5a5095,0xc0750c0c318b5e2d,1 +np.float64,0x32a1f602a32bf360,0xc06270caa493fc17,1 +np.float64,0x16023c90ba93249b,0xc07d0f88e0801638,1 +np.float64,0x1c525fe6d71fa9ff,0xc078af49c66a5d63,1 +np.float64,0x1a927675815d65b7,0xc079e5bdd7fe376e,1 +np.float64,0x41227b8fe70da028,0x402aa0c9f9a84c71,1 +np.float64,0x4962bb6e853fe87d,0x405a34aa04c83747,1 +np.float64,0x23d2cda00b26b5a4,0xc0737c13a06d00ea,1 +np.float64,0x2d13083fd62987fa,0xc06a25055aeb474e,1 +np.float64,0x10e31e4c9b4579a1,0xc0804e181929418e,1 +np.float64,0x26d3247d556a86a9,0xc0716774171da7e8,1 +np.float64,0x6603379398d0d4ac,0x407a64f51f8a887b,1 +np.float64,0x02d38af17d9442ba,0xc0852d955ac9dd68,1 +np.float64,0x6a2382b4818dd967,0x407d4129d688e5d4,1 +np.float64,0x2ee3c403c79b3934,0xc067a091fefaf8b6,1 +np.float64,0x6493a699acdbf1a4,0x4079663c8602bfc5,1 +np.float64,0x1c8413c4f0de3100,0xc0788c99697059b6,1 +np.float64,0x4573f1ed350d9622,0x404e9bd1e4c08920,1 +np.float64,0x2f34265c9200b69c,0xc067310cfea4e986,1 +np.float64,0x19b43e65fa22029b,0xc07a7f8877de22d6,1 +np.float64,0x0af48ab7925ed6bc,0xc0825c4fbc0e5ade,1 +np.float64,0x4fa49699cad82542,0x4065c76d2a318235,1 +np.float64,0x7204a15e56ade492,0x40815bb87484dffb,1 +np.float64,0x4734aa08a230982d,0x40542a4bf7a361a9,1 +np.float64,0x1ae4ed296c2fd749,0xc079ac4921f20abb,1 +np.float64,0x472514ea4370289c,0x4053ff372bd8f18f,1 +np.float64,0x53a54b3f73820430,0x406b5411fc5f2e33,1 +np.float64,0x64754de5a15684fa,0x407951592e99a5ab,1 +np.float64,0x69358e279868a7c3,0x407c9c671a882c31,1 +np.float64,0x284579ec61215945,0xc0706688e55f0927,1 +np.float64,0x68b5c58806447adc,0x407c43d6f4eff760,1 +np.float64,0x1945a83f98b0e65d,0xc07acc15eeb032cc,1 +np.float64,0x0fc5eb98a16578bf,0xc080b0d02eddca0e,1 +np.float64,0x6a75e208f5784250,0x407d7a7383bf8f05,1 +np.float64,0x0fe63a029c47645d,0xc080a59ca1e98866,1 +np.float64,0x37963ac53f065510,0xc057236281f7bdb6,1 +np.float64,0x135661bb07067ff7,0xc07ee924930c21e4,1 +np.float64,0x4b4699469d458422,0x405f73843756e887,1 +np.float64,0x1a66d73e4bf4881b,0xc07a039ba1c63adf,1 +np.float64,0x12a6b9b119a7da59,0xc07f62e49c6431f3,1 +np.float64,0x24c719aa8fd1bdb5,0xc072d26da4bf84d3,1 +np.float64,0x0fa6ff524ffef314,0xc080bb8514662e77,1 +np.float64,0x1db751d66fdd4a9a,0xc077b77cb50d7c92,1 +np.float64,0x4947374c516da82c,0x4059e9acfc7105bf,1 +np.float64,0x1b1771ab98f3afc8,0xc07989326b8e1f66,1 +np.float64,0x25e78805baac8070,0xc0720a818e6ef080,1 +np.float64,0x4bd7a148225d3687,0x406082d004ea3ee7,1 +np.float64,0x53d7d6b2bbbda00a,0x406b9a398967cbd5,1 +np.float64,0x6997fb9f4e1c685f,0x407ce0a703413eba,1 +np.float64,0x069802c2ff71b951,0xc083df39bf7acddc,1 +np.float64,0x4d683ac9890f66d8,0x4062ae21d8c2acf0,1 +np.float64,0x5a2825863ec14f4c,0x40722d718d549552,1 +np.float64,0x0398799a88f4db80,0xc084e93dab8e2158,1 +np.float64,0x5ed87a8b77e135a5,0x40756d7051777b33,1 +np.float64,0x5828cd6d79b9bede,0x4070cafb22fc6ca1,1 +np.float64,0x7b18ba2a5ec6f068,0x408481386b3ed6fe,1 +np.float64,0x4938fd60922198fe,0x4059c206b762ea7e,1 +np.float64,0x31b8f44fcdd1a46e,0xc063b2faa8b6434e,1 +np.float64,0x5729341c0d918464,0x407019cac0c4a7d7,1 +np.float64,0x13595e9228ee878e,0xc07ee7235a7d8088,1 +np.float64,0x17698b0dc9dd4135,0xc07c1627e3a5ad5f,1 +np.float64,0x63b977c283abb0cc,0x4078cf1ec6ed65be,1 +np.float64,0x7349cc0d4dc16943,0x4081cc697ce4cb53,1 +np.float64,0x4e49a80b732fb28d,0x4063e67e3c5cbe90,1 +np.float64,0x07ba14b848a8ae02,0xc0837ac032a094e0,1 +np.float64,0x3da9f17b691bfddc,0xc03929c25366acda,1 +np.float64,0x02ea39aa6c3ac007,0xc08525af6f21e1c4,1 +np.float64,0x3a6a42f04ed9563d,0xc04e98e825dca46b,1 +np.float64,0x1afa877cd7900be7,0xc0799d6648cb34a9,1 +np.float64,0x58ea986649e052c6,0x4071512e939ad790,1 +np.float64,0x691abbc04647f536,0x407c89aaae0fcb83,1 +np.float64,0x43aabc5063e6f284,0x4044b45d18106fd2,1 +np.float64,0x488b003c893e0bea,0x4057df012a2dafbe,1 +np.float64,0x77eb076ed67caee5,0x40836720de94769e,1 +np.float64,0x5c1b46974aba46f4,0x40738731ba256007,1 +np.float64,0x1a5b29ecb5d3c261,0xc07a0becc77040d6,1 +np.float64,0x5d8b6ccf868c6032,0x4074865c1865e2db,1 +np.float64,0x4cfb6690b4aaf5af,0x406216cd8c7e8ddb,1 +np.float64,0x76cbd8eb5c5fc39e,0x4083038dc66d682b,1 +np.float64,0x28bbd1fec5012814,0xc07014c2dd1b9711,1 +np.float64,0x33dc1b3a4fd6bf7a,0xc060bd0756e07d8a,1 +np.float64,0x52bbe89b37de99f3,0x406a10041aa7d343,1 +np.float64,0x07bc479d15eb2dd3,0xc0837a1a6e3a3b61,1 +np.float64,0x18fc5275711a901d,0xc07aff3e9d62bc93,1 +np.float64,0x114c9758e247dc71,0xc080299a7cf15b05,1 +np.float64,0x25ac8f6d60755148,0xc07233c4c0c511d4,1 +np.float64,0x260cae2bb9e9fd7e,0xc071f128c7e82eac,1 +np.float64,0x572ccdfe0241de82,0x40701bedc84bb504,1 +np.float64,0x0ddcef6c8d41f5ee,0xc0815a7e16d07084,1 +np.float64,0x6dad1d59c988af68,0x407fb4a0bc0142b1,1 +np.float64,0x025d200580d8b6d1,0xc08556c0bc32b1b2,1 +np.float64,0x7aad344b6aa74c18,0x40845bbc453f22be,1 +np.float64,0x5b5d9d6ad9d14429,0x4073036d2d21f382,1 +np.float64,0x49cd8d8dcdf19954,0x405b5c034f5c7353,1 +np.float64,0x63edb9483335c1e6,0x4078f2dd21378786,1 +np.float64,0x7b1dd64c9d2c26bd,0x408482b922017bc9,1 +np.float64,0x782e13e0b574be5f,0x40837e2a0090a5ad,1 +np.float64,0x592dfe18b9d6db2f,0x40717f777fbcb1ec,1 +np.float64,0x654e3232ac60d72c,0x4079e71a95a70446,1 +np.float64,0x7b8e42ad22091456,0x4084a9a6f1e61722,1 +np.float64,0x570e88dfd5860ae6,0x407006ae6c0d137a,1 +np.float64,0x294e98346cb98ef1,0xc06f5edaac12bd44,1 +np.float64,0x1adeaa4ab792e642,0xc079b1431d5e2633,1 +np.float64,0x7b6ead3377529ac8,0x40849eabc8c7683c,1 +np.float64,0x2b8eedae8a9b2928,0xc06c400054deef11,1 +np.float64,0x65defb45b2dcf660,0x407a4b53f181c05a,1 +np.float64,0x1baf582d475e7701,0xc07920bcad4a502c,1 +np.float64,0x461f39cf05a0f15a,0x405126368f984fa1,1 +np.float64,0x7e5f6f5dcfff005b,0x4085a37d610439b4,1 +np.float64,0x136f66e4d09bd662,0xc07ed8a2719f2511,1 +np.float64,0x65afd8983fb6ca1f,0x407a2a7f48bf7fc1,1 +np.float64,0x572fa7f95ed22319,0x40701d706cf82e6f,1 diff --git a/venv/Lib/site-packages/numpy/core/tests/data/umath-validation-set-sin b/venv/Lib/site-packages/numpy/core/tests/data/umath-validation-set-sin new file mode 100644 index 0000000..64e78ae --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/tests/data/umath-validation-set-sin @@ -0,0 +1,660 @@ +dtype,input,output,ulperrortol +## +ve denormals ## +np.float32,0x004b4716,0x004b4716,2 +np.float32,0x007b2490,0x007b2490,2 +np.float32,0x007c99fa,0x007c99fa,2 +np.float32,0x00734a0c,0x00734a0c,2 +np.float32,0x0070de24,0x0070de24,2 +np.float32,0x007fffff,0x007fffff,2 +np.float32,0x00000001,0x00000001,2 +## -ve denormals ## +np.float32,0x80495d65,0x80495d65,2 +np.float32,0x806894f6,0x806894f6,2 +np.float32,0x80555a76,0x80555a76,2 +np.float32,0x804e1fb8,0x804e1fb8,2 +np.float32,0x80687de9,0x80687de9,2 +np.float32,0x807fffff,0x807fffff,2 +np.float32,0x80000001,0x80000001,2 +## +/-0.0f, +/-FLT_MIN +/-FLT_MAX ## +np.float32,0x00000000,0x00000000,2 +np.float32,0x80000000,0x80000000,2 +np.float32,0x00800000,0x00800000,2 +np.float32,0x80800000,0x80800000,2 +## 1.00f ## +np.float32,0x3f800000,0x3f576aa4,2 +np.float32,0x3f800001,0x3f576aa6,2 +np.float32,0x3f800002,0x3f576aa7,2 +np.float32,0xc090a8b0,0x3f7b4e48,2 +np.float32,0x41ce3184,0x3f192d43,2 +np.float32,0xc1d85848,0xbf7161cb,2 +np.float32,0x402b8820,0x3ee3f29f,2 +np.float32,0x42b4e454,0x3f1d0151,2 +np.float32,0x42a67a60,0x3f7ffa4c,2 +np.float32,0x41d92388,0x3f67beef,2 +np.float32,0x422dd66c,0xbeffb0c1,2 +np.float32,0xc28f5be6,0xbf0bae79,2 +np.float32,0x41ab2674,0x3f0ffe2b,2 +np.float32,0x3f490fdb,0x3f3504f3,2 +np.float32,0xbf490fdb,0xbf3504f3,2 +np.float32,0x3fc90fdb,0x3f800000,2 +np.float32,0xbfc90fdb,0xbf800000,2 +np.float32,0x40490fdb,0xb3bbbd2e,2 +np.float32,0xc0490fdb,0x33bbbd2e,2 +np.float32,0x3fc90fdb,0x3f800000,2 +np.float32,0xbfc90fdb,0xbf800000,2 +np.float32,0x40490fdb,0xb3bbbd2e,2 +np.float32,0xc0490fdb,0x33bbbd2e,2 +np.float32,0x40c90fdb,0x343bbd2e,2 +np.float32,0xc0c90fdb,0xb43bbd2e,2 +np.float32,0x4016cbe4,0x3f3504f3,2 +np.float32,0xc016cbe4,0xbf3504f3,2 +np.float32,0x4096cbe4,0xbf800000,2 +np.float32,0xc096cbe4,0x3f800000,2 +np.float32,0x4116cbe4,0xb2ccde2e,2 +np.float32,0xc116cbe4,0x32ccde2e,2 +np.float32,0x40490fdb,0xb3bbbd2e,2 +np.float32,0xc0490fdb,0x33bbbd2e,2 +np.float32,0x40c90fdb,0x343bbd2e,2 +np.float32,0xc0c90fdb,0xb43bbd2e,2 +np.float32,0x41490fdb,0x34bbbd2e,2 +np.float32,0xc1490fdb,0xb4bbbd2e,2 +np.float32,0x407b53d2,0xbf3504f5,2 +np.float32,0xc07b53d2,0x3f3504f5,2 +np.float32,0x40fb53d2,0x3f800000,2 +np.float32,0xc0fb53d2,0xbf800000,2 +np.float32,0x417b53d2,0xb535563d,2 +np.float32,0xc17b53d2,0x3535563d,2 +np.float32,0x4096cbe4,0xbf800000,2 +np.float32,0xc096cbe4,0x3f800000,2 +np.float32,0x4116cbe4,0xb2ccde2e,2 +np.float32,0xc116cbe4,0x32ccde2e,2 +np.float32,0x4196cbe4,0x334cde2e,2 +np.float32,0xc196cbe4,0xb34cde2e,2 +np.float32,0x40afede0,0xbf3504ef,2 +np.float32,0xc0afede0,0x3f3504ef,2 +np.float32,0x412fede0,0xbf800000,2 +np.float32,0xc12fede0,0x3f800000,2 +np.float32,0x41afede0,0xb5b222c4,2 +np.float32,0xc1afede0,0x35b222c4,2 +np.float32,0x40c90fdb,0x343bbd2e,2 +np.float32,0xc0c90fdb,0xb43bbd2e,2 +np.float32,0x41490fdb,0x34bbbd2e,2 +np.float32,0xc1490fdb,0xb4bbbd2e,2 +np.float32,0x41c90fdb,0x353bbd2e,2 +np.float32,0xc1c90fdb,0xb53bbd2e,2 +np.float32,0x40e231d6,0x3f3504f3,2 +np.float32,0xc0e231d6,0xbf3504f3,2 +np.float32,0x416231d6,0x3f800000,2 +np.float32,0xc16231d6,0xbf800000,2 +np.float32,0x41e231d6,0xb399a6a2,2 +np.float32,0xc1e231d6,0x3399a6a2,2 +np.float32,0x40fb53d2,0x3f800000,2 +np.float32,0xc0fb53d2,0xbf800000,2 +np.float32,0x417b53d2,0xb535563d,2 +np.float32,0xc17b53d2,0x3535563d,2 +np.float32,0x41fb53d2,0x35b5563d,2 +np.float32,0xc1fb53d2,0xb5b5563d,2 +np.float32,0x410a3ae7,0x3f3504eb,2 +np.float32,0xc10a3ae7,0xbf3504eb,2 +np.float32,0x418a3ae7,0xbf800000,2 +np.float32,0xc18a3ae7,0x3f800000,2 +np.float32,0x420a3ae7,0xb6308908,2 +np.float32,0xc20a3ae7,0x36308908,2 +np.float32,0x4116cbe4,0xb2ccde2e,2 +np.float32,0xc116cbe4,0x32ccde2e,2 +np.float32,0x4196cbe4,0x334cde2e,2 +np.float32,0xc196cbe4,0xb34cde2e,2 +np.float32,0x4216cbe4,0x33ccde2e,2 +np.float32,0xc216cbe4,0xb3ccde2e,2 +np.float32,0x41235ce2,0xbf3504f7,2 +np.float32,0xc1235ce2,0x3f3504f7,2 +np.float32,0x41a35ce2,0x3f800000,2 +np.float32,0xc1a35ce2,0xbf800000,2 +np.float32,0x42235ce2,0xb5b889b6,2 +np.float32,0xc2235ce2,0x35b889b6,2 +np.float32,0x412fede0,0xbf800000,2 +np.float32,0xc12fede0,0x3f800000,2 +np.float32,0x41afede0,0xb5b222c4,2 +np.float32,0xc1afede0,0x35b222c4,2 +np.float32,0x422fede0,0x363222c4,2 +np.float32,0xc22fede0,0xb63222c4,2 +np.float32,0x413c7edd,0xbf3504f3,2 +np.float32,0xc13c7edd,0x3f3504f3,2 +np.float32,0x41bc7edd,0xbf800000,2 +np.float32,0xc1bc7edd,0x3f800000,2 +np.float32,0x423c7edd,0xb4000add,2 +np.float32,0xc23c7edd,0x34000add,2 +np.float32,0x41490fdb,0x34bbbd2e,2 +np.float32,0xc1490fdb,0xb4bbbd2e,2 +np.float32,0x41c90fdb,0x353bbd2e,2 +np.float32,0xc1c90fdb,0xb53bbd2e,2 +np.float32,0x42490fdb,0x35bbbd2e,2 +np.float32,0xc2490fdb,0xb5bbbd2e,2 +np.float32,0x4155a0d9,0x3f3504fb,2 +np.float32,0xc155a0d9,0xbf3504fb,2 +np.float32,0x41d5a0d9,0x3f800000,2 +np.float32,0xc1d5a0d9,0xbf800000,2 +np.float32,0x4255a0d9,0xb633bc81,2 +np.float32,0xc255a0d9,0x3633bc81,2 +np.float32,0x416231d6,0x3f800000,2 +np.float32,0xc16231d6,0xbf800000,2 +np.float32,0x41e231d6,0xb399a6a2,2 +np.float32,0xc1e231d6,0x3399a6a2,2 +np.float32,0x426231d6,0x3419a6a2,2 +np.float32,0xc26231d6,0xb419a6a2,2 +np.float32,0x416ec2d4,0x3f3504ef,2 +np.float32,0xc16ec2d4,0xbf3504ef,2 +np.float32,0x41eec2d4,0xbf800000,2 +np.float32,0xc1eec2d4,0x3f800000,2 +np.float32,0x426ec2d4,0xb5bef0a7,2 +np.float32,0xc26ec2d4,0x35bef0a7,2 +np.float32,0x417b53d2,0xb535563d,2 +np.float32,0xc17b53d2,0x3535563d,2 +np.float32,0x41fb53d2,0x35b5563d,2 +np.float32,0xc1fb53d2,0xb5b5563d,2 +np.float32,0x427b53d2,0x3635563d,2 +np.float32,0xc27b53d2,0xb635563d,2 +np.float32,0x4183f268,0xbf3504ff,2 +np.float32,0xc183f268,0x3f3504ff,2 +np.float32,0x4203f268,0x3f800000,2 +np.float32,0xc203f268,0xbf800000,2 +np.float32,0x4283f268,0xb6859a13,2 +np.float32,0xc283f268,0x36859a13,2 +np.float32,0x418a3ae7,0xbf800000,2 +np.float32,0xc18a3ae7,0x3f800000,2 +np.float32,0x420a3ae7,0xb6308908,2 +np.float32,0xc20a3ae7,0x36308908,2 +np.float32,0x428a3ae7,0x36b08908,2 +np.float32,0xc28a3ae7,0xb6b08908,2 +np.float32,0x41908365,0xbf3504f6,2 +np.float32,0xc1908365,0x3f3504f6,2 +np.float32,0x42108365,0xbf800000,2 +np.float32,0xc2108365,0x3f800000,2 +np.float32,0x42908365,0x3592200d,2 +np.float32,0xc2908365,0xb592200d,2 +np.float32,0x4196cbe4,0x334cde2e,2 +np.float32,0xc196cbe4,0xb34cde2e,2 +np.float32,0x4216cbe4,0x33ccde2e,2 +np.float32,0xc216cbe4,0xb3ccde2e,2 +np.float32,0x4296cbe4,0x344cde2e,2 +np.float32,0xc296cbe4,0xb44cde2e,2 +np.float32,0x419d1463,0x3f3504f8,2 +np.float32,0xc19d1463,0xbf3504f8,2 +np.float32,0x421d1463,0x3f800000,2 +np.float32,0xc21d1463,0xbf800000,2 +np.float32,0x429d1463,0xb5c55799,2 +np.float32,0xc29d1463,0x35c55799,2 +np.float32,0x41a35ce2,0x3f800000,2 +np.float32,0xc1a35ce2,0xbf800000,2 +np.float32,0x42235ce2,0xb5b889b6,2 +np.float32,0xc2235ce2,0x35b889b6,2 +np.float32,0x42a35ce2,0x363889b6,2 +np.float32,0xc2a35ce2,0xb63889b6,2 +np.float32,0x41a9a561,0x3f3504e7,2 +np.float32,0xc1a9a561,0xbf3504e7,2 +np.float32,0x4229a561,0xbf800000,2 +np.float32,0xc229a561,0x3f800000,2 +np.float32,0x42a9a561,0xb68733d0,2 +np.float32,0xc2a9a561,0x368733d0,2 +np.float32,0x41afede0,0xb5b222c4,2 +np.float32,0xc1afede0,0x35b222c4,2 +np.float32,0x422fede0,0x363222c4,2 +np.float32,0xc22fede0,0xb63222c4,2 +np.float32,0x42afede0,0x36b222c4,2 +np.float32,0xc2afede0,0xb6b222c4,2 +np.float32,0x41b6365e,0xbf3504f0,2 +np.float32,0xc1b6365e,0x3f3504f0,2 +np.float32,0x4236365e,0x3f800000,2 +np.float32,0xc236365e,0xbf800000,2 +np.float32,0x42b6365e,0x358bb91c,2 +np.float32,0xc2b6365e,0xb58bb91c,2 +np.float32,0x41bc7edd,0xbf800000,2 +np.float32,0xc1bc7edd,0x3f800000,2 +np.float32,0x423c7edd,0xb4000add,2 +np.float32,0xc23c7edd,0x34000add,2 +np.float32,0x42bc7edd,0x34800add,2 +np.float32,0xc2bc7edd,0xb4800add,2 +np.float32,0x41c2c75c,0xbf3504ef,2 +np.float32,0xc1c2c75c,0x3f3504ef,2 +np.float32,0x4242c75c,0xbf800000,2 +np.float32,0xc242c75c,0x3f800000,2 +np.float32,0x42c2c75c,0xb5cbbe8a,2 +np.float32,0xc2c2c75c,0x35cbbe8a,2 +np.float32,0x41c90fdb,0x353bbd2e,2 +np.float32,0xc1c90fdb,0xb53bbd2e,2 +np.float32,0x42490fdb,0x35bbbd2e,2 +np.float32,0xc2490fdb,0xb5bbbd2e,2 +np.float32,0x42c90fdb,0x363bbd2e,2 +np.float32,0xc2c90fdb,0xb63bbd2e,2 +np.float32,0x41cf585a,0x3f3504ff,2 +np.float32,0xc1cf585a,0xbf3504ff,2 +np.float32,0x424f585a,0x3f800000,2 +np.float32,0xc24f585a,0xbf800000,2 +np.float32,0x42cf585a,0xb688cd8c,2 +np.float32,0xc2cf585a,0x3688cd8c,2 +np.float32,0x41d5a0d9,0x3f800000,2 +np.float32,0xc1d5a0d9,0xbf800000,2 +np.float32,0x4255a0d9,0xb633bc81,2 +np.float32,0xc255a0d9,0x3633bc81,2 +np.float32,0x42d5a0d9,0x36b3bc81,2 +np.float32,0xc2d5a0d9,0xb6b3bc81,2 +np.float32,0x41dbe958,0x3f3504e0,2 +np.float32,0xc1dbe958,0xbf3504e0,2 +np.float32,0x425be958,0xbf800000,2 +np.float32,0xc25be958,0x3f800000,2 +np.float32,0x42dbe958,0xb6deab75,2 +np.float32,0xc2dbe958,0x36deab75,2 +np.float32,0x41e231d6,0xb399a6a2,2 +np.float32,0xc1e231d6,0x3399a6a2,2 +np.float32,0x426231d6,0x3419a6a2,2 +np.float32,0xc26231d6,0xb419a6a2,2 +np.float32,0x42e231d6,0x3499a6a2,2 +np.float32,0xc2e231d6,0xb499a6a2,2 +np.float32,0x41e87a55,0xbf3504f8,2 +np.float32,0xc1e87a55,0x3f3504f8,2 +np.float32,0x42687a55,0x3f800000,2 +np.float32,0xc2687a55,0xbf800000,2 +np.float32,0x42e87a55,0xb5d2257b,2 +np.float32,0xc2e87a55,0x35d2257b,2 +np.float32,0x41eec2d4,0xbf800000,2 +np.float32,0xc1eec2d4,0x3f800000,2 +np.float32,0x426ec2d4,0xb5bef0a7,2 +np.float32,0xc26ec2d4,0x35bef0a7,2 +np.float32,0x42eec2d4,0x363ef0a7,2 +np.float32,0xc2eec2d4,0xb63ef0a7,2 +np.float32,0x41f50b53,0xbf3504e7,2 +np.float32,0xc1f50b53,0x3f3504e7,2 +np.float32,0x42750b53,0xbf800000,2 +np.float32,0xc2750b53,0x3f800000,2 +np.float32,0x42f50b53,0xb68a6748,2 +np.float32,0xc2f50b53,0x368a6748,2 +np.float32,0x41fb53d2,0x35b5563d,2 +np.float32,0xc1fb53d2,0xb5b5563d,2 +np.float32,0x427b53d2,0x3635563d,2 +np.float32,0xc27b53d2,0xb635563d,2 +np.float32,0x42fb53d2,0x36b5563d,2 +np.float32,0xc2fb53d2,0xb6b5563d,2 +np.float32,0x4200ce28,0x3f3504f0,2 +np.float32,0xc200ce28,0xbf3504f0,2 +np.float32,0x4280ce28,0x3f800000,2 +np.float32,0xc280ce28,0xbf800000,2 +np.float32,0x4300ce28,0x357dd672,2 +np.float32,0xc300ce28,0xb57dd672,2 +np.float32,0x4203f268,0x3f800000,2 +np.float32,0xc203f268,0xbf800000,2 +np.float32,0x4283f268,0xb6859a13,2 +np.float32,0xc283f268,0x36859a13,2 +np.float32,0x4303f268,0x37059a13,2 +np.float32,0xc303f268,0xb7059a13,2 +np.float32,0x420716a7,0x3f3504ee,2 +np.float32,0xc20716a7,0xbf3504ee,2 +np.float32,0x428716a7,0xbf800000,2 +np.float32,0xc28716a7,0x3f800000,2 +np.float32,0x430716a7,0xb5d88c6d,2 +np.float32,0xc30716a7,0x35d88c6d,2 +np.float32,0x420a3ae7,0xb6308908,2 +np.float32,0xc20a3ae7,0x36308908,2 +np.float32,0x428a3ae7,0x36b08908,2 +np.float32,0xc28a3ae7,0xb6b08908,2 +np.float32,0x430a3ae7,0x37308908,2 +np.float32,0xc30a3ae7,0xb7308908,2 +np.float32,0x420d5f26,0xbf350500,2 +np.float32,0xc20d5f26,0x3f350500,2 +np.float32,0x428d5f26,0x3f800000,2 +np.float32,0xc28d5f26,0xbf800000,2 +np.float32,0x430d5f26,0xb68c0105,2 +np.float32,0xc30d5f26,0x368c0105,2 +np.float32,0x42108365,0xbf800000,2 +np.float32,0xc2108365,0x3f800000,2 +np.float32,0x42908365,0x3592200d,2 +np.float32,0xc2908365,0xb592200d,2 +np.float32,0x43108365,0xb612200d,2 +np.float32,0xc3108365,0x3612200d,2 +np.float32,0x4213a7a5,0xbf3504df,2 +np.float32,0xc213a7a5,0x3f3504df,2 +np.float32,0x4293a7a5,0xbf800000,2 +np.float32,0xc293a7a5,0x3f800000,2 +np.float32,0x4313a7a5,0xb6e1deee,2 +np.float32,0xc313a7a5,0x36e1deee,2 +np.float32,0x4216cbe4,0x33ccde2e,2 +np.float32,0xc216cbe4,0xb3ccde2e,2 +np.float32,0x4296cbe4,0x344cde2e,2 +np.float32,0xc296cbe4,0xb44cde2e,2 +np.float32,0x4316cbe4,0x34ccde2e,2 +np.float32,0xc316cbe4,0xb4ccde2e,2 +np.float32,0x4219f024,0x3f35050f,2 +np.float32,0xc219f024,0xbf35050f,2 +np.float32,0x4299f024,0x3f800000,2 +np.float32,0xc299f024,0xbf800000,2 +np.float32,0x4319f024,0xb71bde6c,2 +np.float32,0xc319f024,0x371bde6c,2 +np.float32,0x421d1463,0x3f800000,2 +np.float32,0xc21d1463,0xbf800000,2 +np.float32,0x429d1463,0xb5c55799,2 +np.float32,0xc29d1463,0x35c55799,2 +np.float32,0x431d1463,0x36455799,2 +np.float32,0xc31d1463,0xb6455799,2 +np.float32,0x422038a3,0x3f3504d0,2 +np.float32,0xc22038a3,0xbf3504d0,2 +np.float32,0x42a038a3,0xbf800000,2 +np.float32,0xc2a038a3,0x3f800000,2 +np.float32,0x432038a3,0xb746cd61,2 +np.float32,0xc32038a3,0x3746cd61,2 +np.float32,0x42235ce2,0xb5b889b6,2 +np.float32,0xc2235ce2,0x35b889b6,2 +np.float32,0x42a35ce2,0x363889b6,2 +np.float32,0xc2a35ce2,0xb63889b6,2 +np.float32,0x43235ce2,0x36b889b6,2 +np.float32,0xc3235ce2,0xb6b889b6,2 +np.float32,0x42268121,0xbf3504f1,2 +np.float32,0xc2268121,0x3f3504f1,2 +np.float32,0x42a68121,0x3f800000,2 +np.float32,0xc2a68121,0xbf800000,2 +np.float32,0x43268121,0x35643aac,2 +np.float32,0xc3268121,0xb5643aac,2 +np.float32,0x4229a561,0xbf800000,2 +np.float32,0xc229a561,0x3f800000,2 +np.float32,0x42a9a561,0xb68733d0,2 +np.float32,0xc2a9a561,0x368733d0,2 +np.float32,0x4329a561,0x370733d0,2 +np.float32,0xc329a561,0xb70733d0,2 +np.float32,0x422cc9a0,0xbf3504ee,2 +np.float32,0xc22cc9a0,0x3f3504ee,2 +np.float32,0x42acc9a0,0xbf800000,2 +np.float32,0xc2acc9a0,0x3f800000,2 +np.float32,0x432cc9a0,0xb5e55a50,2 +np.float32,0xc32cc9a0,0x35e55a50,2 +np.float32,0x422fede0,0x363222c4,2 +np.float32,0xc22fede0,0xb63222c4,2 +np.float32,0x42afede0,0x36b222c4,2 +np.float32,0xc2afede0,0xb6b222c4,2 +np.float32,0x432fede0,0x373222c4,2 +np.float32,0xc32fede0,0xb73222c4,2 +np.float32,0x4233121f,0x3f350500,2 +np.float32,0xc233121f,0xbf350500,2 +np.float32,0x42b3121f,0x3f800000,2 +np.float32,0xc2b3121f,0xbf800000,2 +np.float32,0x4333121f,0xb68f347d,2 +np.float32,0xc333121f,0x368f347d,2 +np.float32,0x4236365e,0x3f800000,2 +np.float32,0xc236365e,0xbf800000,2 +np.float32,0x42b6365e,0x358bb91c,2 +np.float32,0xc2b6365e,0xb58bb91c,2 +np.float32,0x4336365e,0xb60bb91c,2 +np.float32,0xc336365e,0x360bb91c,2 +np.float32,0x42395a9e,0x3f3504df,2 +np.float32,0xc2395a9e,0xbf3504df,2 +np.float32,0x42b95a9e,0xbf800000,2 +np.float32,0xc2b95a9e,0x3f800000,2 +np.float32,0x43395a9e,0xb6e51267,2 +np.float32,0xc3395a9e,0x36e51267,2 +np.float32,0x423c7edd,0xb4000add,2 +np.float32,0xc23c7edd,0x34000add,2 +np.float32,0x42bc7edd,0x34800add,2 +np.float32,0xc2bc7edd,0xb4800add,2 +np.float32,0x433c7edd,0x35000add,2 +np.float32,0xc33c7edd,0xb5000add,2 +np.float32,0x423fa31d,0xbf35050f,2 +np.float32,0xc23fa31d,0x3f35050f,2 +np.float32,0x42bfa31d,0x3f800000,2 +np.float32,0xc2bfa31d,0xbf800000,2 +np.float32,0x433fa31d,0xb71d7828,2 +np.float32,0xc33fa31d,0x371d7828,2 +np.float32,0x4242c75c,0xbf800000,2 +np.float32,0xc242c75c,0x3f800000,2 +np.float32,0x42c2c75c,0xb5cbbe8a,2 +np.float32,0xc2c2c75c,0x35cbbe8a,2 +np.float32,0x4342c75c,0x364bbe8a,2 +np.float32,0xc342c75c,0xb64bbe8a,2 +np.float32,0x4245eb9c,0xbf3504d0,2 +np.float32,0xc245eb9c,0x3f3504d0,2 +np.float32,0x42c5eb9c,0xbf800000,2 +np.float32,0xc2c5eb9c,0x3f800000,2 +np.float32,0x4345eb9c,0xb748671d,2 +np.float32,0xc345eb9c,0x3748671d,2 +np.float32,0x42490fdb,0x35bbbd2e,2 +np.float32,0xc2490fdb,0xb5bbbd2e,2 +np.float32,0x42c90fdb,0x363bbd2e,2 +np.float32,0xc2c90fdb,0xb63bbd2e,2 +np.float32,0x43490fdb,0x36bbbd2e,2 +np.float32,0xc3490fdb,0xb6bbbd2e,2 +np.float32,0x424c341a,0x3f3504f1,2 +np.float32,0xc24c341a,0xbf3504f1,2 +np.float32,0x42cc341a,0x3f800000,2 +np.float32,0xc2cc341a,0xbf800000,2 +np.float32,0x434c341a,0x354a9ee6,2 +np.float32,0xc34c341a,0xb54a9ee6,2 +np.float32,0x424f585a,0x3f800000,2 +np.float32,0xc24f585a,0xbf800000,2 +np.float32,0x42cf585a,0xb688cd8c,2 +np.float32,0xc2cf585a,0x3688cd8c,2 +np.float32,0x434f585a,0x3708cd8c,2 +np.float32,0xc34f585a,0xb708cd8c,2 +np.float32,0x42527c99,0x3f3504ee,2 +np.float32,0xc2527c99,0xbf3504ee,2 +np.float32,0x42d27c99,0xbf800000,2 +np.float32,0xc2d27c99,0x3f800000,2 +np.float32,0x43527c99,0xb5f22833,2 +np.float32,0xc3527c99,0x35f22833,2 +np.float32,0x4255a0d9,0xb633bc81,2 +np.float32,0xc255a0d9,0x3633bc81,2 +np.float32,0x42d5a0d9,0x36b3bc81,2 +np.float32,0xc2d5a0d9,0xb6b3bc81,2 +np.float32,0x4355a0d9,0x3733bc81,2 +np.float32,0xc355a0d9,0xb733bc81,2 +np.float32,0x4258c518,0xbf350500,2 +np.float32,0xc258c518,0x3f350500,2 +np.float32,0x42d8c518,0x3f800000,2 +np.float32,0xc2d8c518,0xbf800000,2 +np.float32,0x4358c518,0xb69267f6,2 +np.float32,0xc358c518,0x369267f6,2 +np.float32,0x425be958,0xbf800000,2 +np.float32,0xc25be958,0x3f800000,2 +np.float32,0x42dbe958,0xb6deab75,2 +np.float32,0xc2dbe958,0x36deab75,2 +np.float32,0x435be958,0x375eab75,2 +np.float32,0xc35be958,0xb75eab75,2 +np.float32,0x425f0d97,0xbf3504df,2 +np.float32,0xc25f0d97,0x3f3504df,2 +np.float32,0x42df0d97,0xbf800000,2 +np.float32,0xc2df0d97,0x3f800000,2 +np.float32,0x435f0d97,0xb6e845e0,2 +np.float32,0xc35f0d97,0x36e845e0,2 +np.float32,0x426231d6,0x3419a6a2,2 +np.float32,0xc26231d6,0xb419a6a2,2 +np.float32,0x42e231d6,0x3499a6a2,2 +np.float32,0xc2e231d6,0xb499a6a2,2 +np.float32,0x436231d6,0x3519a6a2,2 +np.float32,0xc36231d6,0xb519a6a2,2 +np.float32,0x42655616,0x3f35050f,2 +np.float32,0xc2655616,0xbf35050f,2 +np.float32,0x42e55616,0x3f800000,2 +np.float32,0xc2e55616,0xbf800000,2 +np.float32,0x43655616,0xb71f11e5,2 +np.float32,0xc3655616,0x371f11e5,2 +np.float32,0x42687a55,0x3f800000,2 +np.float32,0xc2687a55,0xbf800000,2 +np.float32,0x42e87a55,0xb5d2257b,2 +np.float32,0xc2e87a55,0x35d2257b,2 +np.float32,0x43687a55,0x3652257b,2 +np.float32,0xc3687a55,0xb652257b,2 +np.float32,0x426b9e95,0x3f3504cf,2 +np.float32,0xc26b9e95,0xbf3504cf,2 +np.float32,0x42eb9e95,0xbf800000,2 +np.float32,0xc2eb9e95,0x3f800000,2 +np.float32,0x436b9e95,0xb74a00d9,2 +np.float32,0xc36b9e95,0x374a00d9,2 +np.float32,0x426ec2d4,0xb5bef0a7,2 +np.float32,0xc26ec2d4,0x35bef0a7,2 +np.float32,0x42eec2d4,0x363ef0a7,2 +np.float32,0xc2eec2d4,0xb63ef0a7,2 +np.float32,0x436ec2d4,0x36bef0a7,2 +np.float32,0xc36ec2d4,0xb6bef0a7,2 +np.float32,0x4271e713,0xbf3504f1,2 +np.float32,0xc271e713,0x3f3504f1,2 +np.float32,0x42f1e713,0x3f800000,2 +np.float32,0xc2f1e713,0xbf800000,2 +np.float32,0x4371e713,0x35310321,2 +np.float32,0xc371e713,0xb5310321,2 +np.float32,0x42750b53,0xbf800000,2 +np.float32,0xc2750b53,0x3f800000,2 +np.float32,0x42f50b53,0xb68a6748,2 +np.float32,0xc2f50b53,0x368a6748,2 +np.float32,0x43750b53,0x370a6748,2 +np.float32,0xc3750b53,0xb70a6748,2 +np.float32,0x42782f92,0xbf3504ee,2 +np.float32,0xc2782f92,0x3f3504ee,2 +np.float32,0x42f82f92,0xbf800000,2 +np.float32,0xc2f82f92,0x3f800000,2 +np.float32,0x43782f92,0xb5fef616,2 +np.float32,0xc3782f92,0x35fef616,2 +np.float32,0x427b53d2,0x3635563d,2 +np.float32,0xc27b53d2,0xb635563d,2 +np.float32,0x42fb53d2,0x36b5563d,2 +np.float32,0xc2fb53d2,0xb6b5563d,2 +np.float32,0x437b53d2,0x3735563d,2 +np.float32,0xc37b53d2,0xb735563d,2 +np.float32,0x427e7811,0x3f350500,2 +np.float32,0xc27e7811,0xbf350500,2 +np.float32,0x42fe7811,0x3f800000,2 +np.float32,0xc2fe7811,0xbf800000,2 +np.float32,0x437e7811,0xb6959b6f,2 +np.float32,0xc37e7811,0x36959b6f,2 +np.float32,0x4280ce28,0x3f800000,2 +np.float32,0xc280ce28,0xbf800000,2 +np.float32,0x4300ce28,0x357dd672,2 +np.float32,0xc300ce28,0xb57dd672,2 +np.float32,0x4380ce28,0xb5fdd672,2 +np.float32,0xc380ce28,0x35fdd672,2 +np.float32,0x42826048,0x3f3504de,2 +np.float32,0xc2826048,0xbf3504de,2 +np.float32,0x43026048,0xbf800000,2 +np.float32,0xc3026048,0x3f800000,2 +np.float32,0x43826048,0xb6eb7958,2 +np.float32,0xc3826048,0x36eb7958,2 +np.float32,0x4283f268,0xb6859a13,2 +np.float32,0xc283f268,0x36859a13,2 +np.float32,0x4303f268,0x37059a13,2 +np.float32,0xc303f268,0xb7059a13,2 +np.float32,0x4383f268,0x37859a13,2 +np.float32,0xc383f268,0xb7859a13,2 +np.float32,0x42858487,0xbf3504e2,2 +np.float32,0xc2858487,0x3f3504e2,2 +np.float32,0x43058487,0x3f800000,2 +np.float32,0xc3058487,0xbf800000,2 +np.float32,0x43858487,0x36bea8be,2 +np.float32,0xc3858487,0xb6bea8be,2 +np.float32,0x428716a7,0xbf800000,2 +np.float32,0xc28716a7,0x3f800000,2 +np.float32,0x430716a7,0xb5d88c6d,2 +np.float32,0xc30716a7,0x35d88c6d,2 +np.float32,0x438716a7,0x36588c6d,2 +np.float32,0xc38716a7,0xb6588c6d,2 +np.float32,0x4288a8c7,0xbf3504cf,2 +np.float32,0xc288a8c7,0x3f3504cf,2 +np.float32,0x4308a8c7,0xbf800000,2 +np.float32,0xc308a8c7,0x3f800000,2 +np.float32,0x4388a8c7,0xb74b9a96,2 +np.float32,0xc388a8c7,0x374b9a96,2 +np.float32,0x428a3ae7,0x36b08908,2 +np.float32,0xc28a3ae7,0xb6b08908,2 +np.float32,0x430a3ae7,0x37308908,2 +np.float32,0xc30a3ae7,0xb7308908,2 +np.float32,0x438a3ae7,0x37b08908,2 +np.float32,0xc38a3ae7,0xb7b08908,2 +np.float32,0x428bcd06,0x3f3504f2,2 +np.float32,0xc28bcd06,0xbf3504f2,2 +np.float32,0x430bcd06,0x3f800000,2 +np.float32,0xc30bcd06,0xbf800000,2 +np.float32,0x438bcd06,0x3517675b,2 +np.float32,0xc38bcd06,0xb517675b,2 +np.float32,0x428d5f26,0x3f800000,2 +np.float32,0xc28d5f26,0xbf800000,2 +np.float32,0x430d5f26,0xb68c0105,2 +np.float32,0xc30d5f26,0x368c0105,2 +np.float32,0x438d5f26,0x370c0105,2 +np.float32,0xc38d5f26,0xb70c0105,2 +np.float32,0x428ef146,0x3f3504c0,2 +np.float32,0xc28ef146,0xbf3504c0,2 +np.float32,0x430ef146,0xbf800000,2 +np.float32,0xc30ef146,0x3f800000,2 +np.float32,0x438ef146,0xb790bc40,2 +np.float32,0xc38ef146,0x3790bc40,2 +np.float32,0x42908365,0x3592200d,2 +np.float32,0xc2908365,0xb592200d,2 +np.float32,0x43108365,0xb612200d,2 +np.float32,0xc3108365,0x3612200d,2 +np.float32,0x43908365,0xb692200d,2 +np.float32,0xc3908365,0x3692200d,2 +np.float32,0x42921585,0xbf350501,2 +np.float32,0xc2921585,0x3f350501,2 +np.float32,0x43121585,0x3f800000,2 +np.float32,0xc3121585,0xbf800000,2 +np.float32,0x43921585,0xb698cee8,2 +np.float32,0xc3921585,0x3698cee8,2 +np.float32,0x4293a7a5,0xbf800000,2 +np.float32,0xc293a7a5,0x3f800000,2 +np.float32,0x4313a7a5,0xb6e1deee,2 +np.float32,0xc313a7a5,0x36e1deee,2 +np.float32,0x4393a7a5,0x3761deee,2 +np.float32,0xc393a7a5,0xb761deee,2 +np.float32,0x429539c5,0xbf3504b1,2 +np.float32,0xc29539c5,0x3f3504b1,2 +np.float32,0x431539c5,0xbf800000,2 +np.float32,0xc31539c5,0x3f800000,2 +np.float32,0x439539c5,0xb7bbab34,2 +np.float32,0xc39539c5,0x37bbab34,2 +np.float32,0x4296cbe4,0x344cde2e,2 +np.float32,0xc296cbe4,0xb44cde2e,2 +np.float32,0x4316cbe4,0x34ccde2e,2 +np.float32,0xc316cbe4,0xb4ccde2e,2 +np.float32,0x4396cbe4,0x354cde2e,2 +np.float32,0xc396cbe4,0xb54cde2e,2 +np.float32,0x42985e04,0x3f350510,2 +np.float32,0xc2985e04,0xbf350510,2 +np.float32,0x43185e04,0x3f800000,2 +np.float32,0xc3185e04,0xbf800000,2 +np.float32,0x43985e04,0xb722455d,2 +np.float32,0xc3985e04,0x3722455d,2 +np.float32,0x4299f024,0x3f800000,2 +np.float32,0xc299f024,0xbf800000,2 +np.float32,0x4319f024,0xb71bde6c,2 +np.float32,0xc319f024,0x371bde6c,2 +np.float32,0x4399f024,0x379bde6c,2 +np.float32,0xc399f024,0xb79bde6c,2 +np.float32,0x429b8243,0x3f3504fc,2 +np.float32,0xc29b8243,0xbf3504fc,2 +np.float32,0x431b8243,0xbf800000,2 +np.float32,0xc31b8243,0x3f800000,2 +np.float32,0x439b8243,0x364b2eb8,2 +np.float32,0xc39b8243,0xb64b2eb8,2 +np.float32,0x435b2047,0xbf350525,2 +np.float32,0x42a038a2,0xbf800000,2 +np.float32,0x432038a2,0x3664ca7e,2 +np.float32,0x4345eb9b,0x365e638c,2 +np.float32,0x42c5eb9b,0xbf800000,2 +np.float32,0x42eb9e94,0xbf800000,2 +np.float32,0x4350ea79,0x3f800000,2 +np.float32,0x42dbe957,0x3585522a,2 +np.float32,0x425be957,0xbf800000,2 +np.float32,0x435be957,0xb605522a,2 +np.float32,0x476362a2,0xbd7ff911,2 +np.float32,0x464c99a4,0x3e7f4d41,2 +np.float32,0x4471f73d,0x3e7fe1b0,2 +np.float32,0x445a6752,0x3e7ef367,2 +np.float32,0x474fa400,0x3e7f9fcd,2 +np.float32,0x45c1e72f,0xbe7fc7af,2 +np.float32,0x4558c91d,0x3e7e9f31,2 +np.float32,0x43784f94,0xbdff6654,2 +np.float32,0x466e8500,0xbe7ea0a3,2 +np.float32,0x468e1c25,0x3e7e22fb,2 +np.float32,0x44ea6cfc,0x3dff70c3,2 +np.float32,0x4605126c,0x3e7f89ef,2 +np.float32,0x4788b3c6,0xbb87d853,2 +np.float32,0x4531b042,0x3dffd163,2 +np.float32,0x43f1f71d,0x3dfff387,2 +np.float32,0x462c3fa5,0xbd7fe13d,2 +np.float32,0x441c5354,0xbdff76b4,2 +np.float32,0x44908b69,0x3e7dcf0d,2 +np.float32,0x478813ad,0xbe7e9d80,2 +np.float32,0x441c4351,0x3dff937b,2 diff --git a/venv/Lib/site-packages/numpy/core/tests/examples/checks.pyx b/venv/Lib/site-packages/numpy/core/tests/examples/checks.pyx new file mode 100644 index 0000000..151979d --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/tests/examples/checks.pyx @@ -0,0 +1,30 @@ +""" +Functions in this module give python-space wrappers for cython functions +exposed in numpy/__init__.pxd, so they can be tested in test_cython.py +""" +cimport numpy as cnp +cnp.import_array() + + +def is_td64(obj): + return cnp.is_timedelta64_object(obj) + + +def is_dt64(obj): + return cnp.is_datetime64_object(obj) + + +def get_dt64_value(obj): + return cnp.get_datetime64_value(obj) + + +def get_td64_value(obj): + return cnp.get_timedelta64_value(obj) + + +def get_dt64_unit(obj): + return cnp.get_datetime64_unit(obj) + + +def is_integer(obj): + return isinstance(obj, (cnp.integer, int)) diff --git a/venv/Lib/site-packages/numpy/core/tests/examples/setup.py b/venv/Lib/site-packages/numpy/core/tests/examples/setup.py new file mode 100644 index 0000000..6e34aa7 --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/tests/examples/setup.py @@ -0,0 +1,25 @@ +""" +Provide python-space access to the functions exposed in numpy/__init__.pxd +for testing. +""" + +import numpy as np +from distutils.core import setup +from Cython.Build import cythonize +from setuptools.extension import Extension +import os + +macros = [("NPY_NO_DEPRECATED_API", 0)] + +checks = Extension( + "checks", + sources=[os.path.join('.', "checks.pyx")], + include_dirs=[np.get_include()], + define_macros=macros, +) + +extensions = [checks] + +setup( + ext_modules=cythonize(extensions) +) diff --git a/venv/Lib/site-packages/numpy/core/tests/test__exceptions.py b/venv/Lib/site-packages/numpy/core/tests/test__exceptions.py new file mode 100644 index 0000000..51c0569 --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/tests/test__exceptions.py @@ -0,0 +1,58 @@ +""" +Tests of the ._exceptions module. Primarily for exercising the __str__ methods. +""" + +import pickle + +import numpy as np + +_ArrayMemoryError = np.core._exceptions._ArrayMemoryError +_UFuncNoLoopError = np.core._exceptions._UFuncNoLoopError + +class TestArrayMemoryError: + def test_pickling(self): + """ Test that _ArrayMemoryError can be pickled """ + error = _ArrayMemoryError((1023,), np.dtype(np.uint8)) + res = pickle.loads(pickle.dumps(error)) + assert res._total_size == error._total_size + + def test_str(self): + e = _ArrayMemoryError((1023,), np.dtype(np.uint8)) + str(e) # not crashing is enough + + # testing these properties is easier than testing the full string repr + def test__size_to_string(self): + """ Test e._size_to_string """ + f = _ArrayMemoryError._size_to_string + Ki = 1024 + assert f(0) == '0 bytes' + assert f(1) == '1 bytes' + assert f(1023) == '1023 bytes' + assert f(Ki) == '1.00 KiB' + assert f(Ki+1) == '1.00 KiB' + assert f(10*Ki) == '10.0 KiB' + assert f(int(999.4*Ki)) == '999. KiB' + assert f(int(1023.4*Ki)) == '1023. KiB' + assert f(int(1023.5*Ki)) == '1.00 MiB' + assert f(Ki*Ki) == '1.00 MiB' + + # 1023.9999 Mib should round to 1 GiB + assert f(int(Ki*Ki*Ki*0.9999)) == '1.00 GiB' + assert f(Ki*Ki*Ki*Ki*Ki*Ki) == '1.00 EiB' + # larger than sys.maxsize, adding larger prefices isn't going to help + # anyway. + assert f(Ki*Ki*Ki*Ki*Ki*Ki*123456) == '123456. EiB' + + def test__total_size(self): + """ Test e._total_size """ + e = _ArrayMemoryError((1,), np.dtype(np.uint8)) + assert e._total_size == 1 + + e = _ArrayMemoryError((2, 4), np.dtype((np.uint64, 16))) + assert e._total_size == 1024 + + +class TestUFuncNoLoopError: + def test_pickling(self): + """ Test that _UFuncNoLoopError can be pickled """ + assert isinstance(pickle.dumps(_UFuncNoLoopError), bytes) diff --git a/venv/Lib/site-packages/numpy/core/tests/test_abc.py b/venv/Lib/site-packages/numpy/core/tests/test_abc.py new file mode 100644 index 0000000..30e5748 --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/tests/test_abc.py @@ -0,0 +1,54 @@ +from numpy.testing import assert_ + +import numbers + +import numpy as np +from numpy.core.numerictypes import sctypes + +class TestABC: + def test_abstract(self): + assert_(issubclass(np.number, numbers.Number)) + + assert_(issubclass(np.inexact, numbers.Complex)) + assert_(issubclass(np.complexfloating, numbers.Complex)) + assert_(issubclass(np.floating, numbers.Real)) + + assert_(issubclass(np.integer, numbers.Integral)) + assert_(issubclass(np.signedinteger, numbers.Integral)) + assert_(issubclass(np.unsignedinteger, numbers.Integral)) + + def test_floats(self): + for t in sctypes['float']: + assert_(isinstance(t(), numbers.Real), + "{0} is not instance of Real".format(t.__name__)) + assert_(issubclass(t, numbers.Real), + "{0} is not subclass of Real".format(t.__name__)) + assert_(not isinstance(t(), numbers.Rational), + "{0} is instance of Rational".format(t.__name__)) + assert_(not issubclass(t, numbers.Rational), + "{0} is subclass of Rational".format(t.__name__)) + + def test_complex(self): + for t in sctypes['complex']: + assert_(isinstance(t(), numbers.Complex), + "{0} is not instance of Complex".format(t.__name__)) + assert_(issubclass(t, numbers.Complex), + "{0} is not subclass of Complex".format(t.__name__)) + assert_(not isinstance(t(), numbers.Real), + "{0} is instance of Real".format(t.__name__)) + assert_(not issubclass(t, numbers.Real), + "{0} is subclass of Real".format(t.__name__)) + + def test_int(self): + for t in sctypes['int']: + assert_(isinstance(t(), numbers.Integral), + "{0} is not instance of Integral".format(t.__name__)) + assert_(issubclass(t, numbers.Integral), + "{0} is not subclass of Integral".format(t.__name__)) + + def test_uint(self): + for t in sctypes['uint']: + assert_(isinstance(t(), numbers.Integral), + "{0} is not instance of Integral".format(t.__name__)) + assert_(issubclass(t, numbers.Integral), + "{0} is not subclass of Integral".format(t.__name__)) diff --git a/venv/Lib/site-packages/numpy/core/tests/test_api.py b/venv/Lib/site-packages/numpy/core/tests/test_api.py new file mode 100644 index 0000000..0f42f70 --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/tests/test_api.py @@ -0,0 +1,587 @@ +import sys + +import numpy as np +from numpy.core._rational_tests import rational +import pytest +from numpy.testing import ( + assert_, assert_equal, assert_array_equal, assert_raises, assert_warns, + HAS_REFCOUNT + ) + +# Switch between new behaviour when NPY_RELAXED_STRIDES_CHECKING is set. +NPY_RELAXED_STRIDES_CHECKING = np.ones((10, 1), order='C').flags.f_contiguous + + +def test_array_array(): + tobj = type(object) + ones11 = np.ones((1, 1), np.float64) + tndarray = type(ones11) + # Test is_ndarray + assert_equal(np.array(ones11, dtype=np.float64), ones11) + if HAS_REFCOUNT: + old_refcount = sys.getrefcount(tndarray) + np.array(ones11) + assert_equal(old_refcount, sys.getrefcount(tndarray)) + + # test None + assert_equal(np.array(None, dtype=np.float64), + np.array(np.nan, dtype=np.float64)) + if HAS_REFCOUNT: + old_refcount = sys.getrefcount(tobj) + np.array(None, dtype=np.float64) + assert_equal(old_refcount, sys.getrefcount(tobj)) + + # test scalar + assert_equal(np.array(1.0, dtype=np.float64), + np.ones((), dtype=np.float64)) + if HAS_REFCOUNT: + old_refcount = sys.getrefcount(np.float64) + np.array(np.array(1.0, dtype=np.float64), dtype=np.float64) + assert_equal(old_refcount, sys.getrefcount(np.float64)) + + # test string + S2 = np.dtype((bytes, 2)) + S3 = np.dtype((bytes, 3)) + S5 = np.dtype((bytes, 5)) + assert_equal(np.array(b"1.0", dtype=np.float64), + np.ones((), dtype=np.float64)) + assert_equal(np.array(b"1.0").dtype, S3) + assert_equal(np.array(b"1.0", dtype=bytes).dtype, S3) + assert_equal(np.array(b"1.0", dtype=S2), np.array(b"1.")) + assert_equal(np.array(b"1", dtype=S5), np.ones((), dtype=S5)) + + # test string + U2 = np.dtype((str, 2)) + U3 = np.dtype((str, 3)) + U5 = np.dtype((str, 5)) + assert_equal(np.array("1.0", dtype=np.float64), + np.ones((), dtype=np.float64)) + assert_equal(np.array("1.0").dtype, U3) + assert_equal(np.array("1.0", dtype=str).dtype, U3) + assert_equal(np.array("1.0", dtype=U2), np.array(str("1."))) + assert_equal(np.array("1", dtype=U5), np.ones((), dtype=U5)) + + builtins = getattr(__builtins__, '__dict__', __builtins__) + assert_(hasattr(builtins, 'get')) + + # test memoryview + dat = np.array(memoryview(b'1.0'), dtype=np.float64) + assert_equal(dat, [49.0, 46.0, 48.0]) + assert_(dat.dtype.type is np.float64) + + dat = np.array(memoryview(b'1.0')) + assert_equal(dat, [49, 46, 48]) + assert_(dat.dtype.type is np.uint8) + + # test array interface + a = np.array(100.0, dtype=np.float64) + o = type("o", (object,), + dict(__array_interface__=a.__array_interface__)) + assert_equal(np.array(o, dtype=np.float64), a) + + # test array_struct interface + a = np.array([(1, 4.0, 'Hello'), (2, 6.0, 'World')], + dtype=[('f0', int), ('f1', float), ('f2', str)]) + o = type("o", (object,), + dict(__array_struct__=a.__array_struct__)) + ## wasn't what I expected... is np.array(o) supposed to equal a ? + ## instead we get a array([...], dtype=">V18") + assert_equal(bytes(np.array(o).data), bytes(a.data)) + + # test array + o = type("o", (object,), + dict(__array__=lambda *x: np.array(100.0, dtype=np.float64)))() + assert_equal(np.array(o, dtype=np.float64), np.array(100.0, np.float64)) + + # test recursion + nested = 1.5 + for i in range(np.MAXDIMS): + nested = [nested] + + # no error + np.array(nested) + + # Exceeds recursion limit + assert_raises(ValueError, np.array, [nested], dtype=np.float64) + + # Try with lists... + assert_equal(np.array([None] * 10, dtype=np.float64), + np.full((10,), np.nan, dtype=np.float64)) + assert_equal(np.array([[None]] * 10, dtype=np.float64), + np.full((10, 1), np.nan, dtype=np.float64)) + assert_equal(np.array([[None] * 10], dtype=np.float64), + np.full((1, 10), np.nan, dtype=np.float64)) + assert_equal(np.array([[None] * 10] * 10, dtype=np.float64), + np.full((10, 10), np.nan, dtype=np.float64)) + + assert_equal(np.array([1.0] * 10, dtype=np.float64), + np.ones((10,), dtype=np.float64)) + assert_equal(np.array([[1.0]] * 10, dtype=np.float64), + np.ones((10, 1), dtype=np.float64)) + assert_equal(np.array([[1.0] * 10], dtype=np.float64), + np.ones((1, 10), dtype=np.float64)) + assert_equal(np.array([[1.0] * 10] * 10, dtype=np.float64), + np.ones((10, 10), dtype=np.float64)) + + # Try with tuples + assert_equal(np.array((None,) * 10, dtype=np.float64), + np.full((10,), np.nan, dtype=np.float64)) + assert_equal(np.array([(None,)] * 10, dtype=np.float64), + np.full((10, 1), np.nan, dtype=np.float64)) + assert_equal(np.array([(None,) * 10], dtype=np.float64), + np.full((1, 10), np.nan, dtype=np.float64)) + assert_equal(np.array([(None,) * 10] * 10, dtype=np.float64), + np.full((10, 10), np.nan, dtype=np.float64)) + + assert_equal(np.array((1.0,) * 10, dtype=np.float64), + np.ones((10,), dtype=np.float64)) + assert_equal(np.array([(1.0,)] * 10, dtype=np.float64), + np.ones((10, 1), dtype=np.float64)) + assert_equal(np.array([(1.0,) * 10], dtype=np.float64), + np.ones((1, 10), dtype=np.float64)) + assert_equal(np.array([(1.0,) * 10] * 10, dtype=np.float64), + np.ones((10, 10), dtype=np.float64)) + +@pytest.mark.parametrize("array", [True, False]) +def test_array_impossible_casts(array): + # All builtin types can forst cast as least theoretically + # but user dtypes cannot necessarily. + rt = rational(1, 2) + if array: + rt = np.array(rt) + with assert_raises(ValueError): + np.array(rt, dtype="M8") + + +def test_fastCopyAndTranspose(): + # 0D array + a = np.array(2) + b = np.fastCopyAndTranspose(a) + assert_equal(b, a.T) + assert_(b.flags.owndata) + + # 1D array + a = np.array([3, 2, 7, 0]) + b = np.fastCopyAndTranspose(a) + assert_equal(b, a.T) + assert_(b.flags.owndata) + + # 2D array + a = np.arange(6).reshape(2, 3) + b = np.fastCopyAndTranspose(a) + assert_equal(b, a.T) + assert_(b.flags.owndata) + +def test_array_astype(): + a = np.arange(6, dtype='f4').reshape(2, 3) + # Default behavior: allows unsafe casts, keeps memory layout, + # always copies. + b = a.astype('i4') + assert_equal(a, b) + assert_equal(b.dtype, np.dtype('i4')) + assert_equal(a.strides, b.strides) + b = a.T.astype('i4') + assert_equal(a.T, b) + assert_equal(b.dtype, np.dtype('i4')) + assert_equal(a.T.strides, b.strides) + b = a.astype('f4') + assert_equal(a, b) + assert_(not (a is b)) + + # copy=False parameter can sometimes skip a copy + b = a.astype('f4', copy=False) + assert_(a is b) + + # order parameter allows overriding of the memory layout, + # forcing a copy if the layout is wrong + b = a.astype('f4', order='F', copy=False) + assert_equal(a, b) + assert_(not (a is b)) + assert_(b.flags.f_contiguous) + + b = a.astype('f4', order='C', copy=False) + assert_equal(a, b) + assert_(a is b) + assert_(b.flags.c_contiguous) + + # casting parameter allows catching bad casts + b = a.astype('c8', casting='safe') + assert_equal(a, b) + assert_equal(b.dtype, np.dtype('c8')) + + assert_raises(TypeError, a.astype, 'i4', casting='safe') + + # subok=False passes through a non-subclassed array + b = a.astype('f4', subok=0, copy=False) + assert_(a is b) + + class MyNDArray(np.ndarray): + pass + + a = np.array([[0, 1, 2], [3, 4, 5]], dtype='f4').view(MyNDArray) + + # subok=True passes through a subclass + b = a.astype('f4', subok=True, copy=False) + assert_(a is b) + + # subok=True is default, and creates a subtype on a cast + b = a.astype('i4', copy=False) + assert_equal(a, b) + assert_equal(type(b), MyNDArray) + + # subok=False never returns a subclass + b = a.astype('f4', subok=False, copy=False) + assert_equal(a, b) + assert_(not (a is b)) + assert_(type(b) is not MyNDArray) + + # Make sure converting from string object to fixed length string + # does not truncate. + a = np.array([b'a'*100], dtype='O') + b = a.astype('S') + assert_equal(a, b) + assert_equal(b.dtype, np.dtype('S100')) + a = np.array([u'a'*100], dtype='O') + b = a.astype('U') + assert_equal(a, b) + assert_equal(b.dtype, np.dtype('U100')) + + # Same test as above but for strings shorter than 64 characters + a = np.array([b'a'*10], dtype='O') + b = a.astype('S') + assert_equal(a, b) + assert_equal(b.dtype, np.dtype('S10')) + a = np.array([u'a'*10], dtype='O') + b = a.astype('U') + assert_equal(a, b) + assert_equal(b.dtype, np.dtype('U10')) + + a = np.array(123456789012345678901234567890, dtype='O').astype('S') + assert_array_equal(a, np.array(b'1234567890' * 3, dtype='S30')) + a = np.array(123456789012345678901234567890, dtype='O').astype('U') + assert_array_equal(a, np.array(u'1234567890' * 3, dtype='U30')) + + a = np.array([123456789012345678901234567890], dtype='O').astype('S') + assert_array_equal(a, np.array(b'1234567890' * 3, dtype='S30')) + a = np.array([123456789012345678901234567890], dtype='O').astype('U') + assert_array_equal(a, np.array(u'1234567890' * 3, dtype='U30')) + + a = np.array(123456789012345678901234567890, dtype='S') + assert_array_equal(a, np.array(b'1234567890' * 3, dtype='S30')) + a = np.array(123456789012345678901234567890, dtype='U') + assert_array_equal(a, np.array(u'1234567890' * 3, dtype='U30')) + + a = np.array(u'a\u0140', dtype='U') + b = np.ndarray(buffer=a, dtype='uint32', shape=2) + assert_(b.size == 2) + + a = np.array([1000], dtype='i4') + assert_raises(TypeError, a.astype, 'S1', casting='safe') + + a = np.array(1000, dtype='i4') + assert_raises(TypeError, a.astype, 'U1', casting='safe') + + +@pytest.mark.parametrize("dt", ["d", "f", "S13", "U32"]) +def test_array_astype_to_void(dt): + dt = np.dtype(dt) + arr = np.array([], dtype=dt) + assert arr.astype("V").dtype.itemsize == dt.itemsize + +def test_object_array_astype_to_void(): + # This is different to `test_array_astype_to_void` as object arrays + # are inspected. The default void is "V8" (8 is the length of double) + arr = np.array([], dtype="O").astype("V") + assert arr.dtype == "V8" + +@pytest.mark.parametrize("t", + np.sctypes['uint'] + np.sctypes['int'] + np.sctypes['float'] +) +def test_array_astype_warning(t): + # test ComplexWarning when casting from complex to float or int + a = np.array(10, dtype=np.complex_) + assert_warns(np.ComplexWarning, a.astype, t) + +@pytest.mark.parametrize(["dtype", "out_dtype"], + [(np.bytes_, np.bool_), + (np.unicode_, np.bool_), + (np.dtype("S10,S9"), np.dtype("?,?"))]) +def test_string_to_boolean_cast(dtype, out_dtype): + """ + Currently, for `astype` strings are cast to booleans effectively by + calling `bool(int(string)`. This is not consistent (see gh-9875) and + will eventually be deprecated. + """ + arr = np.array(["10", "10\0\0\0", "0\0\0", "0"], dtype=dtype) + expected = np.array([True, True, False, False], dtype=out_dtype) + assert_array_equal(arr.astype(out_dtype), expected) + +@pytest.mark.parametrize(["dtype", "out_dtype"], + [(np.bytes_, np.bool_), + (np.unicode_, np.bool_), + (np.dtype("S10,S9"), np.dtype("?,?"))]) +def test_string_to_boolean_cast_errors(dtype, out_dtype): + """ + These currently error out, since cast to integers fails, but should not + error out in the future. + """ + for invalid in ["False", "True", "", "\0", "non-empty"]: + arr = np.array([invalid], dtype=dtype) + with assert_raises(ValueError): + arr.astype(out_dtype) + +@pytest.mark.parametrize("str_type", [str, bytes, np.str_, np.unicode_]) +@pytest.mark.parametrize("scalar_type", + [np.complex64, np.complex128, np.clongdouble]) +def test_string_to_complex_cast(str_type, scalar_type): + value = scalar_type(b"1+3j") + assert scalar_type(value) == 1+3j + assert np.array([value], dtype=object).astype(scalar_type)[()] == 1+3j + assert np.array(value).astype(scalar_type)[()] == 1+3j + arr = np.zeros(1, dtype=scalar_type) + arr[0] = value + assert arr[0] == 1+3j + +@pytest.mark.parametrize("dtype", np.typecodes["AllFloat"]) +def test_none_to_nan_cast(dtype): + # Note that at the time of writing this test, the scalar constructors + # reject None + arr = np.zeros(1, dtype=dtype) + arr[0] = None + assert np.isnan(arr)[0] + assert np.isnan(np.array(None, dtype=dtype))[()] + assert np.isnan(np.array([None], dtype=dtype))[0] + assert np.isnan(np.array(None).astype(dtype))[()] + +def test_copyto_fromscalar(): + a = np.arange(6, dtype='f4').reshape(2, 3) + + # Simple copy + np.copyto(a, 1.5) + assert_equal(a, 1.5) + np.copyto(a.T, 2.5) + assert_equal(a, 2.5) + + # Where-masked copy + mask = np.array([[0, 1, 0], [0, 0, 1]], dtype='?') + np.copyto(a, 3.5, where=mask) + assert_equal(a, [[2.5, 3.5, 2.5], [2.5, 2.5, 3.5]]) + mask = np.array([[0, 1], [1, 1], [1, 0]], dtype='?') + np.copyto(a.T, 4.5, where=mask) + assert_equal(a, [[2.5, 4.5, 4.5], [4.5, 4.5, 3.5]]) + +def test_copyto(): + a = np.arange(6, dtype='i4').reshape(2, 3) + + # Simple copy + np.copyto(a, [[3, 1, 5], [6, 2, 1]]) + assert_equal(a, [[3, 1, 5], [6, 2, 1]]) + + # Overlapping copy should work + np.copyto(a[:, :2], a[::-1, 1::-1]) + assert_equal(a, [[2, 6, 5], [1, 3, 1]]) + + # Defaults to 'same_kind' casting + assert_raises(TypeError, np.copyto, a, 1.5) + + # Force a copy with 'unsafe' casting, truncating 1.5 to 1 + np.copyto(a, 1.5, casting='unsafe') + assert_equal(a, 1) + + # Copying with a mask + np.copyto(a, 3, where=[True, False, True]) + assert_equal(a, [[3, 1, 3], [3, 1, 3]]) + + # Casting rule still applies with a mask + assert_raises(TypeError, np.copyto, a, 3.5, where=[True, False, True]) + + # Lists of integer 0's and 1's is ok too + np.copyto(a, 4.0, casting='unsafe', where=[[0, 1, 1], [1, 0, 0]]) + assert_equal(a, [[3, 4, 4], [4, 1, 3]]) + + # Overlapping copy with mask should work + np.copyto(a[:, :2], a[::-1, 1::-1], where=[[0, 1], [1, 1]]) + assert_equal(a, [[3, 4, 4], [4, 3, 3]]) + + # 'dst' must be an array + assert_raises(TypeError, np.copyto, [1, 2, 3], [2, 3, 4]) + +def test_copyto_permut(): + # test explicit overflow case + pad = 500 + l = [True] * pad + [True, True, True, True] + r = np.zeros(len(l)-pad) + d = np.ones(len(l)-pad) + mask = np.array(l)[pad:] + np.copyto(r, d, where=mask[::-1]) + + # test all permutation of possible masks, 9 should be sufficient for + # current 4 byte unrolled code + power = 9 + d = np.ones(power) + for i in range(2**power): + r = np.zeros(power) + l = [(i & x) != 0 for x in range(power)] + mask = np.array(l) + np.copyto(r, d, where=mask) + assert_array_equal(r == 1, l) + assert_equal(r.sum(), sum(l)) + + r = np.zeros(power) + np.copyto(r, d, where=mask[::-1]) + assert_array_equal(r == 1, l[::-1]) + assert_equal(r.sum(), sum(l)) + + r = np.zeros(power) + np.copyto(r[::2], d[::2], where=mask[::2]) + assert_array_equal(r[::2] == 1, l[::2]) + assert_equal(r[::2].sum(), sum(l[::2])) + + r = np.zeros(power) + np.copyto(r[::2], d[::2], where=mask[::-2]) + assert_array_equal(r[::2] == 1, l[::-2]) + assert_equal(r[::2].sum(), sum(l[::-2])) + + for c in [0xFF, 0x7F, 0x02, 0x10]: + r = np.zeros(power) + mask = np.array(l) + imask = np.array(l).view(np.uint8) + imask[mask != 0] = c + np.copyto(r, d, where=mask) + assert_array_equal(r == 1, l) + assert_equal(r.sum(), sum(l)) + + r = np.zeros(power) + np.copyto(r, d, where=True) + assert_equal(r.sum(), r.size) + r = np.ones(power) + d = np.zeros(power) + np.copyto(r, d, where=False) + assert_equal(r.sum(), r.size) + +def test_copy_order(): + a = np.arange(24).reshape(2, 1, 3, 4) + b = a.copy(order='F') + c = np.arange(24).reshape(2, 1, 4, 3).swapaxes(2, 3) + + def check_copy_result(x, y, ccontig, fcontig, strides=False): + assert_(not (x is y)) + assert_equal(x, y) + assert_equal(res.flags.c_contiguous, ccontig) + assert_equal(res.flags.f_contiguous, fcontig) + # This check is impossible only because + # NPY_RELAXED_STRIDES_CHECKING changes the strides actively + if not NPY_RELAXED_STRIDES_CHECKING: + if strides: + assert_equal(x.strides, y.strides) + else: + assert_(x.strides != y.strides) + + # Validate the initial state of a, b, and c + assert_(a.flags.c_contiguous) + assert_(not a.flags.f_contiguous) + assert_(not b.flags.c_contiguous) + assert_(b.flags.f_contiguous) + assert_(not c.flags.c_contiguous) + assert_(not c.flags.f_contiguous) + + # Copy with order='C' + res = a.copy(order='C') + check_copy_result(res, a, ccontig=True, fcontig=False, strides=True) + res = b.copy(order='C') + check_copy_result(res, b, ccontig=True, fcontig=False, strides=False) + res = c.copy(order='C') + check_copy_result(res, c, ccontig=True, fcontig=False, strides=False) + res = np.copy(a, order='C') + check_copy_result(res, a, ccontig=True, fcontig=False, strides=True) + res = np.copy(b, order='C') + check_copy_result(res, b, ccontig=True, fcontig=False, strides=False) + res = np.copy(c, order='C') + check_copy_result(res, c, ccontig=True, fcontig=False, strides=False) + + # Copy with order='F' + res = a.copy(order='F') + check_copy_result(res, a, ccontig=False, fcontig=True, strides=False) + res = b.copy(order='F') + check_copy_result(res, b, ccontig=False, fcontig=True, strides=True) + res = c.copy(order='F') + check_copy_result(res, c, ccontig=False, fcontig=True, strides=False) + res = np.copy(a, order='F') + check_copy_result(res, a, ccontig=False, fcontig=True, strides=False) + res = np.copy(b, order='F') + check_copy_result(res, b, ccontig=False, fcontig=True, strides=True) + res = np.copy(c, order='F') + check_copy_result(res, c, ccontig=False, fcontig=True, strides=False) + + # Copy with order='K' + res = a.copy(order='K') + check_copy_result(res, a, ccontig=True, fcontig=False, strides=True) + res = b.copy(order='K') + check_copy_result(res, b, ccontig=False, fcontig=True, strides=True) + res = c.copy(order='K') + check_copy_result(res, c, ccontig=False, fcontig=False, strides=True) + res = np.copy(a, order='K') + check_copy_result(res, a, ccontig=True, fcontig=False, strides=True) + res = np.copy(b, order='K') + check_copy_result(res, b, ccontig=False, fcontig=True, strides=True) + res = np.copy(c, order='K') + check_copy_result(res, c, ccontig=False, fcontig=False, strides=True) + +def test_contiguous_flags(): + a = np.ones((4, 4, 1))[::2,:,:] + if NPY_RELAXED_STRIDES_CHECKING: + a.strides = a.strides[:2] + (-123,) + b = np.ones((2, 2, 1, 2, 2)).swapaxes(3, 4) + + def check_contig(a, ccontig, fcontig): + assert_(a.flags.c_contiguous == ccontig) + assert_(a.flags.f_contiguous == fcontig) + + # Check if new arrays are correct: + check_contig(a, False, False) + check_contig(b, False, False) + if NPY_RELAXED_STRIDES_CHECKING: + check_contig(np.empty((2, 2, 0, 2, 2)), True, True) + check_contig(np.array([[[1], [2]]], order='F'), True, True) + else: + check_contig(np.empty((2, 2, 0, 2, 2)), True, False) + check_contig(np.array([[[1], [2]]], order='F'), False, True) + check_contig(np.empty((2, 2)), True, False) + check_contig(np.empty((2, 2), order='F'), False, True) + + # Check that np.array creates correct contiguous flags: + check_contig(np.array(a, copy=False), False, False) + check_contig(np.array(a, copy=False, order='C'), True, False) + check_contig(np.array(a, ndmin=4, copy=False, order='F'), False, True) + + if NPY_RELAXED_STRIDES_CHECKING: + # Check slicing update of flags and : + check_contig(a[0], True, True) + check_contig(a[None, ::4, ..., None], True, True) + check_contig(b[0, 0, ...], False, True) + check_contig(b[:,:, 0:0,:,:], True, True) + else: + # Check slicing update of flags: + check_contig(a[0], True, False) + # Would be nice if this was C-Contiguous: + check_contig(a[None, 0, ..., None], False, False) + check_contig(b[0, 0, 0, ...], False, True) + + # Test ravel and squeeze. + check_contig(a.ravel(), True, True) + check_contig(np.ones((1, 3, 1)).squeeze(), True, True) + +def test_broadcast_arrays(): + # Test user defined dtypes + a = np.array([(1, 2, 3)], dtype='u4,u4,u4') + b = np.array([(1, 2, 3), (4, 5, 6), (7, 8, 9)], dtype='u4,u4,u4') + result = np.broadcast_arrays(a, b) + assert_equal(result[0], np.array([(1, 2, 3), (1, 2, 3), (1, 2, 3)], dtype='u4,u4,u4')) + assert_equal(result[1], np.array([(1, 2, 3), (4, 5, 6), (7, 8, 9)], dtype='u4,u4,u4')) + +@pytest.mark.parametrize(["shape", "fill_value", "expected_output"], + [((2, 2), [5.0, 6.0], np.array([[5.0, 6.0], [5.0, 6.0]])), + ((3, 2), [1.0, 2.0], np.array([[1.0, 2.0], [1.0, 2.0], [1.0, 2.0]]))]) +def test_full_from_list(shape, fill_value, expected_output): + output = np.full(shape, fill_value) + assert_equal(output, expected_output) diff --git a/venv/Lib/site-packages/numpy/core/tests/test_array_coercion.py b/venv/Lib/site-packages/numpy/core/tests/test_array_coercion.py new file mode 100644 index 0000000..8f709db --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/tests/test_array_coercion.py @@ -0,0 +1,733 @@ +""" +Tests for array coercion, mainly through testing `np.array` results directly. +Note that other such tests exist e.g. in `test_api.py` and many corner-cases +are tested (sometimes indirectly) elsewhere. +""" + +import pytest +from pytest import param + +from itertools import product + +import numpy as np +from numpy.core._rational_tests import rational +from numpy.core._multiarray_umath import _discover_array_parameters + +from numpy.testing import ( + assert_array_equal, assert_warns, IS_PYPY) + + +def arraylikes(): + """ + Generator for functions converting an array into various array-likes. + If full is True (default) includes array-likes not capable of handling + all dtypes + """ + # base array: + def ndarray(a): + return a + + yield param(ndarray, id="ndarray") + + # subclass: + class MyArr(np.ndarray): + pass + + def subclass(a): + return a.view(MyArr) + + yield subclass + + class _SequenceLike(): + # We are giving a warning that array-like's were also expected to be + # sequence-like in `np.array([array_like])`, this can be removed + # when the deprecation exired (started NumPy 1.20) + def __len__(self): + raise TypeError + + def __getitem__(self): + raise TypeError + + # Array-interface + class ArrayDunder(_SequenceLike): + def __init__(self, a): + self.a = a + + def __array__(self, dtype=None): + return self.a + + yield param(ArrayDunder, id="__array__") + + # memory-view + yield param(memoryview, id="memoryview") + + # Array-interface + class ArrayInterface(_SequenceLike): + def __init__(self, a): + self.a = a # need to hold on to keep interface valid + self.__array_interface__ = a.__array_interface__ + + yield param(ArrayInterface, id="__array_interface__") + + # Array-Struct + class ArrayStruct(_SequenceLike): + def __init__(self, a): + self.a = a # need to hold on to keep struct valid + self.__array_struct__ = a.__array_struct__ + + yield param(ArrayStruct, id="__array_struct__") + + +def scalar_instances(times=True, extended_precision=True, user_dtype=True): + # Hard-coded list of scalar instances. + # Floats: + yield param(np.sqrt(np.float16(5)), id="float16") + yield param(np.sqrt(np.float32(5)), id="float32") + yield param(np.sqrt(np.float64(5)), id="float64") + if extended_precision: + yield param(np.sqrt(np.longdouble(5)), id="longdouble") + + # Complex: + yield param(np.sqrt(np.complex64(2+3j)), id="complex64") + yield param(np.sqrt(np.complex128(2+3j)), id="complex128") + if extended_precision: + yield param(np.sqrt(np.longcomplex(2+3j)), id="clongdouble") + + # Bool: + # XFAIL: Bool should be added, but has some bad properties when it + # comes to strings, see also gh-9875 + # yield param(np.bool_(0), id="bool") + + # Integers: + yield param(np.int8(2), id="int8") + yield param(np.int16(2), id="int16") + yield param(np.int32(2), id="int32") + yield param(np.int64(2), id="int64") + + yield param(np.uint8(2), id="uint8") + yield param(np.uint16(2), id="uint16") + yield param(np.uint32(2), id="uint32") + yield param(np.uint64(2), id="uint64") + + # Rational: + if user_dtype: + yield param(rational(1, 2), id="rational") + + # Cannot create a structured void scalar directly: + structured = np.array([(1, 3)], "i,i")[0] + assert isinstance(structured, np.void) + assert structured.dtype == np.dtype("i,i") + yield param(structured, id="structured") + + if times: + # Datetimes and timedelta + yield param(np.timedelta64(2), id="timedelta64[generic]") + yield param(np.timedelta64(23, "s"), id="timedelta64[s]") + yield param(np.timedelta64("NaT", "s"), id="timedelta64[s](NaT)") + + yield param(np.datetime64("NaT"), id="datetime64[generic](NaT)") + yield param(np.datetime64("2020-06-07 12:43", "ms"), id="datetime64[ms]") + + # Strings and unstructured void: + yield param(np.bytes_(b"1234"), id="bytes") + yield param(np.unicode_("2345"), id="unicode") + yield param(np.void(b"4321"), id="unstructured_void") + + +def is_parametric_dtype(dtype): + """Returns True if the the dtype is a parametric legacy dtype (itemsize + is 0, or a datetime without units) + """ + if dtype.itemsize == 0: + return True + if issubclass(dtype.type, (np.datetime64, np.timedelta64)): + if dtype.name.endswith("64"): + # Generic time units + return True + return False + + +class TestStringDiscovery: + @pytest.mark.parametrize("obj", + [object(), 1.2, 10**43, None, "string"], + ids=["object", "1.2", "10**43", "None", "string"]) + def test_basic_stringlength(self, obj): + length = len(str(obj)) + expected = np.dtype(f"S{length}") + + assert np.array(obj, dtype="S").dtype == expected + assert np.array([obj], dtype="S").dtype == expected + + # A nested array is also discovered correctly + arr = np.array(obj, dtype="O") + assert np.array(arr, dtype="S").dtype == expected + # Check that .astype() behaves identical + assert arr.astype("S").dtype == expected + + @pytest.mark.parametrize("obj", + [object(), 1.2, 10**43, None, "string"], + ids=["object", "1.2", "10**43", "None", "string"]) + def test_nested_arrays_stringlength(self, obj): + length = len(str(obj)) + expected = np.dtype(f"S{length}") + arr = np.array(obj, dtype="O") + assert np.array([arr, arr], dtype="S").dtype == expected + + @pytest.mark.parametrize("arraylike", arraylikes()) + def test_unpack_first_level(self, arraylike): + # We unpack exactly one level of array likes + obj = np.array([None]) + obj[0] = np.array(1.2) + # the length of the included item, not of the float dtype + length = len(str(obj[0])) + expected = np.dtype(f"S{length}") + + obj = arraylike(obj) + # casting to string usually calls str(obj) + arr = np.array([obj], dtype="S") + assert arr.shape == (1, 1) + assert arr.dtype == expected + + +class TestScalarDiscovery: + def test_void_special_case(self): + # Void dtypes with structures discover tuples as elements + arr = np.array((1, 2, 3), dtype="i,i,i") + assert arr.shape == () + arr = np.array([(1, 2, 3)], dtype="i,i,i") + assert arr.shape == (1,) + + def test_char_special_case(self): + arr = np.array("string", dtype="c") + assert arr.shape == (6,) + assert arr.dtype.char == "c" + arr = np.array(["string"], dtype="c") + assert arr.shape == (1, 6) + assert arr.dtype.char == "c" + + def test_char_special_case_deep(self): + # Check that the character special case errors correctly if the + # array is too deep: + nested = ["string"] # 2 dimensions (due to string being sequence) + for i in range(np.MAXDIMS - 2): + nested = [nested] + + arr = np.array(nested, dtype='c') + assert arr.shape == (1,) * (np.MAXDIMS - 1) + (6,) + with pytest.raises(ValueError): + np.array([nested], dtype="c") + + def test_unknown_object(self): + arr = np.array(object()) + assert arr.shape == () + assert arr.dtype == np.dtype("O") + + @pytest.mark.parametrize("scalar", scalar_instances()) + def test_scalar(self, scalar): + arr = np.array(scalar) + assert arr.shape == () + assert arr.dtype == scalar.dtype + + arr = np.array([[scalar, scalar]]) + assert arr.shape == (1, 2) + assert arr.dtype == scalar.dtype + + # Additionally to string this test also runs into a corner case + # with datetime promotion (the difference is the promotion order). + def test_scalar_promotion(self): + for sc1, sc2 in product(scalar_instances(), scalar_instances()): + sc1, sc2 = sc1.values[0], sc2.values[0] + # test all combinations: + try: + arr = np.array([sc1, sc2]) + except (TypeError, ValueError): + # The promotion between two times can fail + # XFAIL (ValueError): Some object casts are currently undefined + continue + assert arr.shape == (2,) + try: + dt1, dt2 = sc1.dtype, sc2.dtype + expected_dtype = np.promote_types(dt1, dt2) + assert arr.dtype == expected_dtype + except TypeError as e: + # Will currently always go to object dtype + assert arr.dtype == np.dtype("O") + + @pytest.mark.parametrize("scalar", scalar_instances()) + def test_scalar_coercion(self, scalar): + # This tests various scalar coercion paths, mainly for the numerical + # types. It includes some paths not directly related to `np.array` + if isinstance(scalar, np.inexact): + # Ensure we have a full-precision number if available + scalar = type(scalar)((scalar * 2)**0.5) + + if type(scalar) is rational: + # Rational generally fails due to a missing cast. In the future + # object casts should automatically be defined based on `setitem`. + pytest.xfail("Rational to object cast is undefined currently.") + + # Use casting from object: + arr = np.array(scalar, dtype=object).astype(scalar.dtype) + + # Test various ways to create an array containing this scalar: + arr1 = np.array(scalar).reshape(1) + arr2 = np.array([scalar]) + arr3 = np.empty(1, dtype=scalar.dtype) + arr3[0] = scalar + arr4 = np.empty(1, dtype=scalar.dtype) + arr4[:] = [scalar] + # All of these methods should yield the same results + assert_array_equal(arr, arr1) + assert_array_equal(arr, arr2) + assert_array_equal(arr, arr3) + assert_array_equal(arr, arr4) + + @pytest.mark.xfail(IS_PYPY, reason="`int(np.complex128(3))` fails on PyPy") + @pytest.mark.filterwarnings("ignore::numpy.ComplexWarning") + @pytest.mark.parametrize("cast_to", scalar_instances()) + def test_scalar_coercion_same_as_cast_and_assignment(self, cast_to): + """ + Test that in most cases: + * `np.array(scalar, dtype=dtype)` + * `np.empty((), dtype=dtype)[()] = scalar` + * `np.array(scalar).astype(dtype)` + should behave the same. The only exceptions are paramteric dtypes + (mainly datetime/timedelta without unit) and void without fields. + """ + dtype = cast_to.dtype # use to parametrize only the target dtype + + for scalar in scalar_instances(times=False): + scalar = scalar.values[0] + + if dtype.type == np.void: + if scalar.dtype.fields is not None and dtype.fields is None: + # Here, coercion to "V6" works, but the cast fails. + # Since the types are identical, SETITEM takes care of + # this, but has different rules than the cast. + with pytest.raises(TypeError): + np.array(scalar).astype(dtype) + np.array(scalar, dtype=dtype) + np.array([scalar], dtype=dtype) + continue + + # The main test, we first try to use casting and if it succeeds + # continue below testing that things are the same, otherwise + # test that the alternative paths at least also fail. + try: + cast = np.array(scalar).astype(dtype) + except (TypeError, ValueError, RuntimeError): + # coercion should also raise (error type may change) + with pytest.raises(Exception): + np.array(scalar, dtype=dtype) + + if (isinstance(scalar, rational) and + np.issubdtype(dtype, np.signedinteger)): + return + + with pytest.raises(Exception): + np.array([scalar], dtype=dtype) + # assignment should also raise + res = np.zeros((), dtype=dtype) + with pytest.raises(Exception): + res[()] = scalar + + return + + # Non error path: + arr = np.array(scalar, dtype=dtype) + assert_array_equal(arr, cast) + # assignment behaves the same + ass = np.zeros((), dtype=dtype) + ass[()] = scalar + assert_array_equal(ass, cast) + + @pytest.mark.parametrize("dtype_char", np.typecodes["All"]) + def test_default_dtype_instance(self, dtype_char): + if dtype_char in "SU": + dtype = np.dtype(dtype_char + "1") + elif dtype_char == "V": + # Legacy behaviour was to use V8. The reason was float64 being the + # default dtype and that having 8 bytes. + dtype = np.dtype("V8") + else: + dtype = np.dtype(dtype_char) + + discovered_dtype, _ = _discover_array_parameters([], type(dtype)) + + assert discovered_dtype == dtype + assert discovered_dtype.itemsize == dtype.itemsize + + @pytest.mark.parametrize("dtype", np.typecodes["Integer"]) + def test_scalar_to_int_coerce_does_not_cast(self, dtype): + """ + Signed integers are currently different in that they do not cast other + NumPy scalar, but instead use scalar.__int__(). The harcoded + exception to this rule is `np.array(scalar, dtype=integer)`. + """ + dtype = np.dtype(dtype) + invalid_int = np.ulonglong(-1) + + float_nan = np.float64(np.nan) + + for scalar in [float_nan, invalid_int]: + # This is a special case using casting logic and thus not failing: + coerced = np.array(scalar, dtype=dtype) + cast = np.array(scalar).astype(dtype) + assert_array_equal(coerced, cast) + + # However these fail: + with pytest.raises((ValueError, OverflowError)): + np.array([scalar], dtype=dtype) + with pytest.raises((ValueError, OverflowError)): + cast[()] = scalar + + +class TestTimeScalars: + @pytest.mark.parametrize("dtype", [np.int64, np.float32]) + @pytest.mark.parametrize("scalar", + [param(np.timedelta64("NaT", "s"), id="timedelta64[s](NaT)"), + param(np.timedelta64(123, "s"), id="timedelta64[s]"), + param(np.datetime64("NaT", "generic"), id="datetime64[generic](NaT)"), + param(np.datetime64(1, "D"), id="datetime64[D]")],) + def test_coercion_basic(self, dtype, scalar): + # Note the `[scalar]` is there because np.array(scalar) uses stricter + # `scalar.__int__()` rules for backward compatibility right now. + arr = np.array(scalar, dtype=dtype) + cast = np.array(scalar).astype(dtype) + assert_array_equal(arr, cast) + + ass = np.ones((), dtype=dtype) + if issubclass(dtype, np.integer): + with pytest.raises(TypeError): + # raises, as would np.array([scalar], dtype=dtype), this is + # conversion from times, but behaviour of integers. + ass[()] = scalar + else: + ass[()] = scalar + assert_array_equal(ass, cast) + + @pytest.mark.parametrize("dtype", [np.int64, np.float32]) + @pytest.mark.parametrize("scalar", + [param(np.timedelta64(123, "ns"), id="timedelta64[ns]"), + param(np.timedelta64(12, "generic"), id="timedelta64[generic]")]) + def test_coercion_timedelta_convert_to_number(self, dtype, scalar): + # Only "ns" and "generic" timedeltas can be converted to numbers + # so these are slightly special. + arr = np.array(scalar, dtype=dtype) + cast = np.array(scalar).astype(dtype) + ass = np.ones((), dtype=dtype) + ass[()] = scalar # raises, as would np.array([scalar], dtype=dtype) + + assert_array_equal(arr, cast) + assert_array_equal(cast, cast) + + @pytest.mark.parametrize("dtype", ["S6", "U6"]) + @pytest.mark.parametrize(["val", "unit"], + [param(123, "s", id="[s]"), param(123, "D", id="[D]")]) + def test_coercion_assignment_datetime(self, val, unit, dtype): + # String from datetime64 assignment is currently special cased to + # never use casting. This is because casting will error in this + # case, and traditionally in most cases the behaviour is maintained + # like this. (`np.array(scalar, dtype="U6")` would have failed before) + # TODO: This discrepency _should_ be resolved, either by relaxing the + # cast, or by deprecating the first part. + scalar = np.datetime64(val, unit) + dtype = np.dtype(dtype) + cut_string = dtype.type(str(scalar)[:6]) + + arr = np.array(scalar, dtype=dtype) + assert arr[()] == cut_string + ass = np.ones((), dtype=dtype) + ass[()] = scalar + assert ass[()] == cut_string + + with pytest.raises(RuntimeError): + # However, unlike the above assignment using `str(scalar)[:6]` + # due to being handled by the string DType and not be casting + # the explicit cast fails: + np.array(scalar).astype(dtype) + + + @pytest.mark.parametrize(["val", "unit"], + [param(123, "s", id="[s]"), param(123, "D", id="[D]")]) + def test_coercion_assignment_timedelta(self, val, unit): + scalar = np.timedelta64(val, unit) + + # Unlike datetime64, timedelta allows the unsafe cast: + np.array(scalar, dtype="S6") + cast = np.array(scalar).astype("S6") + ass = np.ones((), dtype="S6") + ass[()] = scalar + expected = scalar.astype("S")[:6] + assert cast[()] == expected + assert ass[()] == expected + +class TestNested: + def test_nested_simple(self): + initial = [1.2] + nested = initial + for i in range(np.MAXDIMS - 1): + nested = [nested] + + arr = np.array(nested, dtype="float64") + assert arr.shape == (1,) * np.MAXDIMS + with pytest.raises(ValueError): + np.array([nested], dtype="float64") + + # We discover object automatically at this time: + with assert_warns(np.VisibleDeprecationWarning): + arr = np.array([nested]) + assert arr.dtype == np.dtype("O") + assert arr.shape == (1,) * np.MAXDIMS + assert arr.item() is initial + + def test_pathological_self_containing(self): + # Test that this also works for two nested sequences + l = [] + l.append(l) + arr = np.array([l, l, l], dtype=object) + assert arr.shape == (3,) + (1,) * (np.MAXDIMS - 1) + + # Also check a ragged case: + arr = np.array([l, [None], l], dtype=object) + assert arr.shape == (3, 1) + + @pytest.mark.parametrize("arraylike", arraylikes()) + def test_nested_arraylikes(self, arraylike): + # We try storing an array like into an array, but the array-like + # will have too many dimensions. This means the shape discovery + # decides that the array-like must be treated as an object (a special + # case of ragged discovery). The result will be an array with one + # dimension less than the maximum dimensions, and the array being + # assigned to it (which does work for object or if `float(arraylike)` + # works). + initial = arraylike(np.ones((1, 1))) + + nested = initial + for i in range(np.MAXDIMS - 1): + nested = [nested] + + with pytest.warns(DeprecationWarning): + # It will refuse to assign the array into + np.array(nested, dtype="float64") + + # If this is object, we end up assigning a (1, 1) array into (1,) + # (due to running out of dimensions), this is currently supported but + # a special case which is not ideal. + arr = np.array(nested, dtype=object) + assert arr.shape == (1,) * np.MAXDIMS + assert arr.item() == np.array(initial).item() + + @pytest.mark.parametrize("arraylike", arraylikes()) + def test_uneven_depth_ragged(self, arraylike): + arr = np.arange(4).reshape((2, 2)) + arr = arraylike(arr) + + # Array is ragged in the second dimension already: + out = np.array([arr, [arr]], dtype=object) + assert out.shape == (2,) + assert out[0] is arr + assert type(out[1]) is list + + # Array is ragged in the third dimension: + with pytest.raises(ValueError): + # This is a broadcast error during assignment, because + # the array shape would be (2, 2, 2) but `arr[0, 0] = arr` fails. + np.array([arr, [arr, arr]], dtype=object) + + def test_empty_sequence(self): + arr = np.array([[], [1], [[1]]], dtype=object) + assert arr.shape == (3,) + + # The empty sequence stops further dimension discovery, so the + # result shape will be (0,) which leads to an error during: + with pytest.raises(ValueError): + np.array([[], np.empty((0, 1))], dtype=object) + + def test_array_of_different_depths(self): + # When multiple arrays (or array-likes) are included in a + # sequences and have different depth, we currently discover + # as many dimensions as they share. (see also gh-17224) + arr = np.zeros((3, 2)) + mismatch_first_dim = np.zeros((1, 2)) + mismatch_second_dim = np.zeros((3, 3)) + + dtype, shape = _discover_array_parameters( + [arr, mismatch_second_dim], dtype=np.dtype("O")) + assert shape == (2, 3) + + dtype, shape = _discover_array_parameters( + [arr, mismatch_first_dim], dtype=np.dtype("O")) + assert shape == (2,) + # The second case is currently supported because the arrays + # can be stored as objects: + res = np.asarray([arr, mismatch_first_dim], dtype=np.dtype("O")) + assert res[0] is arr + assert res[1] is mismatch_first_dim + + +class TestBadSequences: + # These are tests for bad objects passed into `np.array`, in general + # these have undefined behaviour. In the old code they partially worked + # when now they will fail. We could (and maybe should) create a copy + # of all sequences to be safe against bad-actors. + + def test_growing_list(self): + # List to coerce, `mylist` will append to it during coercion + obj = [] + class mylist(list): + def __len__(self): + obj.append([1, 2]) + return super().__len__() + + obj.append(mylist([1, 2])) + + with pytest.raises(RuntimeError): + np.array(obj) + + # Note: We do not test a shrinking list. These do very evil things + # and the only way to fix them would be to copy all sequences. + # (which may be a real option in the future). + + def test_mutated_list(self): + # List to coerce, `mylist` will mutate the first element + obj = [] + class mylist(list): + def __len__(self): + obj[0] = [2, 3] # replace with a different list. + return super().__len__() + + obj.append([2, 3]) + obj.append(mylist([1, 2])) + with pytest.raises(RuntimeError): + np.array(obj) + + def test_replace_0d_array(self): + # List to coerce, `mylist` will mutate the first element + obj = [] + class baditem: + def __len__(self): + obj[0][0] = 2 # replace with a different list. + raise ValueError("not actually a sequence!") + + def __getitem__(self): + pass + + # Runs into a corner case in the new code, the `array(2)` is cached + # so replacing it invalidates the cache. + obj.append([np.array(2), baditem()]) + with pytest.raises(RuntimeError): + np.array(obj) + + +class TestArrayLikes: + @pytest.mark.parametrize("arraylike", arraylikes()) + def test_0d_object_special_case(self, arraylike): + arr = np.array(0.) + obj = arraylike(arr) + # A single array-like is always converted: + res = np.array(obj, dtype=object) + assert_array_equal(arr, res) + + # But a single 0-D nested array-like never: + res = np.array([obj], dtype=object) + assert res[0] is obj + + def test_0d_generic_special_case(self): + class ArraySubclass(np.ndarray): + def __float__(self): + raise TypeError("e.g. quantities raise on this") + + arr = np.array(0.) + obj = arr.view(ArraySubclass) + res = np.array(obj) + # The subclass is simply cast: + assert_array_equal(arr, res) + + # If the 0-D array-like is included, __float__ is currently + # guaranteed to be used. We may want to change that, quantities + # and masked arrays half make use of this. + with pytest.raises(TypeError): + np.array([obj]) + + # The same holds for memoryview: + obj = memoryview(arr) + res = np.array(obj) + assert_array_equal(arr, res) + with pytest.raises(ValueError): + # The error type does not matter much here. + np.array([obj]) + + def test_arraylike_classes(self): + # The classes of array-likes should generally be acceptable to be + # stored inside a numpy (object) array. This tests all of the + # special attributes (since all are checked during coercion). + arr = np.array(np.int64) + assert arr[()] is np.int64 + arr = np.array([np.int64]) + assert arr[0] is np.int64 + + # This also works for properties/unbound methods: + class ArrayLike: + @property + def __array_interface__(self): + pass + + @property + def __array_struct__(self): + pass + + def __array__(self): + pass + + arr = np.array(ArrayLike) + assert arr[()] is ArrayLike + arr = np.array([ArrayLike]) + assert arr[0] is ArrayLike + + @pytest.mark.skipif( + np.dtype(np.intp).itemsize < 8, reason="Needs 64bit platform") + def test_too_large_array_error_paths(self): + """Test the error paths, including for memory leaks""" + arr = np.array(0, dtype="uint8") + # Guarantees that a contiguous copy won't work: + arr = np.broadcast_to(arr, 2**62) + + for i in range(5): + # repeat, to ensure caching cannot have an effect: + with pytest.raises(MemoryError): + np.array(arr) + with pytest.raises(MemoryError): + np.array([arr]) + + @pytest.mark.parametrize("attribute", + ["__array_interface__", "__array__", "__array_struct__"]) + @pytest.mark.parametrize("error", [RecursionError, MemoryError]) + def test_bad_array_like_attributes(self, attribute, error): + # RecursionError and MemoryError are considered fatal. All errors + # (except AttributeError) should probably be raised in the future, + # but shapely made use of it, so it will require a deprecation. + + class BadInterface: + def __getattr__(self, attr): + if attr == attribute: + raise error + super().__getattr__(attr) + + with pytest.raises(error): + np.array(BadInterface()) + + @pytest.mark.parametrize("error", [RecursionError, MemoryError]) + def test_bad_array_like_bad_length(self, error): + # RecursionError and MemoryError are considered "critical" in + # sequences. We could expand this more generally though. (NumPy 1.20) + class BadSequence: + def __len__(self): + raise error + def __getitem__(self): + # must have getitem to be a Sequence + return 1 + + with pytest.raises(error): + np.array(BadSequence()) + diff --git a/venv/Lib/site-packages/numpy/core/tests/test_arrayprint.py b/venv/Lib/site-packages/numpy/core/tests/test_arrayprint.py new file mode 100644 index 0000000..a2703d8 --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/tests/test_arrayprint.py @@ -0,0 +1,961 @@ +# -*- coding: utf-8 -*- +import sys +import gc +from hypothesis import given +from hypothesis.extra import numpy as hynp +import pytest + +import numpy as np +from numpy.testing import ( + assert_, assert_equal, assert_raises, assert_warns, HAS_REFCOUNT, + assert_raises_regex, + ) +import textwrap + +class TestArrayRepr: + def test_nan_inf(self): + x = np.array([np.nan, np.inf]) + assert_equal(repr(x), 'array([nan, inf])') + + def test_subclass(self): + class sub(np.ndarray): pass + + # one dimensional + x1d = np.array([1, 2]).view(sub) + assert_equal(repr(x1d), 'sub([1, 2])') + + # two dimensional + x2d = np.array([[1, 2], [3, 4]]).view(sub) + assert_equal(repr(x2d), + 'sub([[1, 2],\n' + ' [3, 4]])') + + # two dimensional with flexible dtype + xstruct = np.ones((2,2), dtype=[('a', ' 1) + y = sub(None) + x[()] = y + y[()] = x + assert_equal(repr(x), + 'sub(sub(sub(..., dtype=object), dtype=object), dtype=object)') + assert_equal(str(x), '...') + x[()] = 0 # resolve circular references for garbage collector + + # nested 0d-subclass-object + x = sub(None) + x[()] = sub(None) + assert_equal(repr(x), 'sub(sub(None, dtype=object), dtype=object)') + assert_equal(str(x), 'None') + + # gh-10663 + class DuckCounter(np.ndarray): + def __getitem__(self, item): + result = super(DuckCounter, self).__getitem__(item) + if not isinstance(result, DuckCounter): + result = result[...].view(DuckCounter) + return result + + def to_string(self): + return {0: 'zero', 1: 'one', 2: 'two'}.get(self.item(), 'many') + + def __str__(self): + if self.shape == (): + return self.to_string() + else: + fmt = {'all': lambda x: x.to_string()} + return np.array2string(self, formatter=fmt) + + dc = np.arange(5).view(DuckCounter) + assert_equal(str(dc), "[zero one two many many]") + assert_equal(str(dc[0]), "zero") + + def test_self_containing(self): + arr0d = np.array(None) + arr0d[()] = arr0d + assert_equal(repr(arr0d), + 'array(array(..., dtype=object), dtype=object)') + arr0d[()] = 0 # resolve recursion for garbage collector + + arr1d = np.array([None, None]) + arr1d[1] = arr1d + assert_equal(repr(arr1d), + 'array([None, array(..., dtype=object)], dtype=object)') + arr1d[1] = 0 # resolve recursion for garbage collector + + first = np.array(None) + second = np.array(None) + first[()] = second + second[()] = first + assert_equal(repr(first), + 'array(array(array(..., dtype=object), dtype=object), dtype=object)') + first[()] = 0 # resolve circular references for garbage collector + + def test_containing_list(self): + # printing square brackets directly would be ambiguuous + arr1d = np.array([None, None]) + arr1d[0] = [1, 2] + arr1d[1] = [3] + assert_equal(repr(arr1d), + 'array([list([1, 2]), list([3])], dtype=object)') + + def test_void_scalar_recursion(self): + # gh-9345 + repr(np.void(b'test')) # RecursionError ? + + def test_fieldless_structured(self): + # gh-10366 + no_fields = np.dtype([]) + arr_no_fields = np.empty(4, dtype=no_fields) + assert_equal(repr(arr_no_fields), 'array([(), (), (), ()], dtype=[])') + + +class TestComplexArray: + def test_str(self): + rvals = [0, 1, -1, np.inf, -np.inf, np.nan] + cvals = [complex(rp, ip) for rp in rvals for ip in rvals] + dtypes = [np.complex64, np.cdouble, np.clongdouble] + actual = [str(np.array([c], dt)) for c in cvals for dt in dtypes] + wanted = [ + '[0.+0.j]', '[0.+0.j]', '[0.+0.j]', + '[0.+1.j]', '[0.+1.j]', '[0.+1.j]', + '[0.-1.j]', '[0.-1.j]', '[0.-1.j]', + '[0.+infj]', '[0.+infj]', '[0.+infj]', + '[0.-infj]', '[0.-infj]', '[0.-infj]', + '[0.+nanj]', '[0.+nanj]', '[0.+nanj]', + '[1.+0.j]', '[1.+0.j]', '[1.+0.j]', + '[1.+1.j]', '[1.+1.j]', '[1.+1.j]', + '[1.-1.j]', '[1.-1.j]', '[1.-1.j]', + '[1.+infj]', '[1.+infj]', '[1.+infj]', + '[1.-infj]', '[1.-infj]', '[1.-infj]', + '[1.+nanj]', '[1.+nanj]', '[1.+nanj]', + '[-1.+0.j]', '[-1.+0.j]', '[-1.+0.j]', + '[-1.+1.j]', '[-1.+1.j]', '[-1.+1.j]', + '[-1.-1.j]', '[-1.-1.j]', '[-1.-1.j]', + '[-1.+infj]', '[-1.+infj]', '[-1.+infj]', + '[-1.-infj]', '[-1.-infj]', '[-1.-infj]', + '[-1.+nanj]', '[-1.+nanj]', '[-1.+nanj]', + '[inf+0.j]', '[inf+0.j]', '[inf+0.j]', + '[inf+1.j]', '[inf+1.j]', '[inf+1.j]', + '[inf-1.j]', '[inf-1.j]', '[inf-1.j]', + '[inf+infj]', '[inf+infj]', '[inf+infj]', + '[inf-infj]', '[inf-infj]', '[inf-infj]', + '[inf+nanj]', '[inf+nanj]', '[inf+nanj]', + '[-inf+0.j]', '[-inf+0.j]', '[-inf+0.j]', + '[-inf+1.j]', '[-inf+1.j]', '[-inf+1.j]', + '[-inf-1.j]', '[-inf-1.j]', '[-inf-1.j]', + '[-inf+infj]', '[-inf+infj]', '[-inf+infj]', + '[-inf-infj]', '[-inf-infj]', '[-inf-infj]', + '[-inf+nanj]', '[-inf+nanj]', '[-inf+nanj]', + '[nan+0.j]', '[nan+0.j]', '[nan+0.j]', + '[nan+1.j]', '[nan+1.j]', '[nan+1.j]', + '[nan-1.j]', '[nan-1.j]', '[nan-1.j]', + '[nan+infj]', '[nan+infj]', '[nan+infj]', + '[nan-infj]', '[nan-infj]', '[nan-infj]', + '[nan+nanj]', '[nan+nanj]', '[nan+nanj]'] + + for res, val in zip(actual, wanted): + assert_equal(res, val) + +class TestArray2String: + def test_basic(self): + """Basic test of array2string.""" + a = np.arange(3) + assert_(np.array2string(a) == '[0 1 2]') + assert_(np.array2string(a, max_line_width=4, legacy='1.13') == '[0 1\n 2]') + assert_(np.array2string(a, max_line_width=4) == '[0\n 1\n 2]') + + def test_unexpected_kwarg(self): + # ensure than an appropriate TypeError + # is raised when array2string receives + # an unexpected kwarg + + with assert_raises_regex(TypeError, 'nonsense'): + np.array2string(np.array([1, 2, 3]), + nonsense=None) + + def test_format_function(self): + """Test custom format function for each element in array.""" + def _format_function(x): + if np.abs(x) < 1: + return '.' + elif np.abs(x) < 2: + return 'o' + else: + return 'O' + + x = np.arange(3) + x_hex = "[0x0 0x1 0x2]" + x_oct = "[0o0 0o1 0o2]" + assert_(np.array2string(x, formatter={'all':_format_function}) == + "[. o O]") + assert_(np.array2string(x, formatter={'int_kind':_format_function}) == + "[. o O]") + assert_(np.array2string(x, formatter={'all':lambda x: "%.4f" % x}) == + "[0.0000 1.0000 2.0000]") + assert_equal(np.array2string(x, formatter={'int':lambda x: hex(x)}), + x_hex) + assert_equal(np.array2string(x, formatter={'int':lambda x: oct(x)}), + x_oct) + + x = np.arange(3.) + assert_(np.array2string(x, formatter={'float_kind':lambda x: "%.2f" % x}) == + "[0.00 1.00 2.00]") + assert_(np.array2string(x, formatter={'float':lambda x: "%.2f" % x}) == + "[0.00 1.00 2.00]") + + s = np.array(['abc', 'def']) + assert_(np.array2string(s, formatter={'numpystr':lambda s: s*2}) == + '[abcabc defdef]') + + + def test_structure_format(self): + dt = np.dtype([('name', np.str_, 16), ('grades', np.float64, (2,))]) + x = np.array([('Sarah', (8.0, 7.0)), ('John', (6.0, 7.0))], dtype=dt) + assert_equal(np.array2string(x), + "[('Sarah', [8., 7.]) ('John', [6., 7.])]") + + np.set_printoptions(legacy='1.13') + try: + # for issue #5692 + A = np.zeros(shape=10, dtype=[("A", "M8[s]")]) + A[5:].fill(np.datetime64('NaT')) + assert_equal( + np.array2string(A), + textwrap.dedent("""\ + [('1970-01-01T00:00:00',) ('1970-01-01T00:00:00',) ('1970-01-01T00:00:00',) + ('1970-01-01T00:00:00',) ('1970-01-01T00:00:00',) ('NaT',) ('NaT',) + ('NaT',) ('NaT',) ('NaT',)]""") + ) + finally: + np.set_printoptions(legacy=False) + + # same again, but with non-legacy behavior + assert_equal( + np.array2string(A), + textwrap.dedent("""\ + [('1970-01-01T00:00:00',) ('1970-01-01T00:00:00',) + ('1970-01-01T00:00:00',) ('1970-01-01T00:00:00',) + ('1970-01-01T00:00:00',) ( 'NaT',) + ( 'NaT',) ( 'NaT',) + ( 'NaT',) ( 'NaT',)]""") + ) + + # and again, with timedeltas + A = np.full(10, 123456, dtype=[("A", "m8[s]")]) + A[5:].fill(np.datetime64('NaT')) + assert_equal( + np.array2string(A), + textwrap.dedent("""\ + [(123456,) (123456,) (123456,) (123456,) (123456,) ( 'NaT',) ( 'NaT',) + ( 'NaT',) ( 'NaT',) ( 'NaT',)]""") + ) + + # See #8160 + struct_int = np.array([([1, -1],), ([123, 1],)], dtype=[('B', 'i4', 2)]) + assert_equal(np.array2string(struct_int), + "[([ 1, -1],) ([123, 1],)]") + struct_2dint = np.array([([[0, 1], [2, 3]],), ([[12, 0], [0, 0]],)], + dtype=[('B', 'i4', (2, 2))]) + assert_equal(np.array2string(struct_2dint), + "[([[ 0, 1], [ 2, 3]],) ([[12, 0], [ 0, 0]],)]") + + # See #8172 + array_scalar = np.array( + (1., 2.1234567890123456789, 3.), dtype=('f8,f8,f8')) + assert_equal(np.array2string(array_scalar), "(1., 2.12345679, 3.)") + + def test_unstructured_void_repr(self): + a = np.array([27, 91, 50, 75, 7, 65, 10, 8, + 27, 91, 51, 49,109, 82,101,100], dtype='u1').view('V8') + assert_equal(repr(a[0]), r"void(b'\x1B\x5B\x32\x4B\x07\x41\x0A\x08')") + assert_equal(str(a[0]), r"b'\x1B\x5B\x32\x4B\x07\x41\x0A\x08'") + assert_equal(repr(a), + r"array([b'\x1B\x5B\x32\x4B\x07\x41\x0A\x08'," "\n" + r" b'\x1B\x5B\x33\x31\x6D\x52\x65\x64'], dtype='|V8')") + + assert_equal(eval(repr(a), vars(np)), a) + assert_equal(eval(repr(a[0]), vars(np)), a[0]) + + def test_edgeitems_kwarg(self): + # previously the global print options would be taken over the kwarg + arr = np.zeros(3, int) + assert_equal( + np.array2string(arr, edgeitems=1, threshold=0), + "[0 ... 0]" + ) + + def test_summarize_1d(self): + A = np.arange(1001) + strA = '[ 0 1 2 ... 998 999 1000]' + assert_equal(str(A), strA) + + reprA = 'array([ 0, 1, 2, ..., 998, 999, 1000])' + assert_equal(repr(A), reprA) + + def test_summarize_2d(self): + A = np.arange(1002).reshape(2, 501) + strA = '[[ 0 1 2 ... 498 499 500]\n' \ + ' [ 501 502 503 ... 999 1000 1001]]' + assert_equal(str(A), strA) + + reprA = 'array([[ 0, 1, 2, ..., 498, 499, 500],\n' \ + ' [ 501, 502, 503, ..., 999, 1000, 1001]])' + assert_equal(repr(A), reprA) + + def test_linewidth(self): + a = np.full(6, 1) + + def make_str(a, width, **kw): + return np.array2string(a, separator="", max_line_width=width, **kw) + + assert_equal(make_str(a, 8, legacy='1.13'), '[111111]') + assert_equal(make_str(a, 7, legacy='1.13'), '[111111]') + assert_equal(make_str(a, 5, legacy='1.13'), '[1111\n' + ' 11]') + + assert_equal(make_str(a, 8), '[111111]') + assert_equal(make_str(a, 7), '[11111\n' + ' 1]') + assert_equal(make_str(a, 5), '[111\n' + ' 111]') + + b = a[None,None,:] + + assert_equal(make_str(b, 12, legacy='1.13'), '[[[111111]]]') + assert_equal(make_str(b, 9, legacy='1.13'), '[[[111111]]]') + assert_equal(make_str(b, 8, legacy='1.13'), '[[[11111\n' + ' 1]]]') + + assert_equal(make_str(b, 12), '[[[111111]]]') + assert_equal(make_str(b, 9), '[[[111\n' + ' 111]]]') + assert_equal(make_str(b, 8), '[[[11\n' + ' 11\n' + ' 11]]]') + + def test_wide_element(self): + a = np.array(['xxxxx']) + assert_equal( + np.array2string(a, max_line_width=5), + "['xxxxx']" + ) + assert_equal( + np.array2string(a, max_line_width=5, legacy='1.13'), + "[ 'xxxxx']" + ) + + def test_multiline_repr(self): + class MultiLine: + def __repr__(self): + return "Line 1\nLine 2" + + a = np.array([[None, MultiLine()], [MultiLine(), None]]) + + assert_equal( + np.array2string(a), + '[[None Line 1\n' + ' Line 2]\n' + ' [Line 1\n' + ' Line 2 None]]' + ) + assert_equal( + np.array2string(a, max_line_width=5), + '[[None\n' + ' Line 1\n' + ' Line 2]\n' + ' [Line 1\n' + ' Line 2\n' + ' None]]' + ) + assert_equal( + repr(a), + 'array([[None, Line 1\n' + ' Line 2],\n' + ' [Line 1\n' + ' Line 2, None]], dtype=object)' + ) + + class MultiLineLong: + def __repr__(self): + return "Line 1\nLooooooooooongestLine2\nLongerLine 3" + + a = np.array([[None, MultiLineLong()], [MultiLineLong(), None]]) + assert_equal( + repr(a), + 'array([[None, Line 1\n' + ' LooooooooooongestLine2\n' + ' LongerLine 3 ],\n' + ' [Line 1\n' + ' LooooooooooongestLine2\n' + ' LongerLine 3 , None]], dtype=object)' + ) + assert_equal( + np.array_repr(a, 20), + 'array([[None,\n' + ' Line 1\n' + ' LooooooooooongestLine2\n' + ' LongerLine 3 ],\n' + ' [Line 1\n' + ' LooooooooooongestLine2\n' + ' LongerLine 3 ,\n' + ' None]],\n' + ' dtype=object)' + ) + + def test_nested_array_repr(self): + a = np.empty((2, 2), dtype=object) + a[0, 0] = np.eye(2) + a[0, 1] = np.eye(3) + a[1, 0] = None + a[1, 1] = np.ones((3, 1)) + assert_equal( + repr(a), + 'array([[array([[1., 0.],\n' + ' [0., 1.]]), array([[1., 0., 0.],\n' + ' [0., 1., 0.],\n' + ' [0., 0., 1.]])],\n' + ' [None, array([[1.],\n' + ' [1.],\n' + ' [1.]])]], dtype=object)' + ) + + @given(hynp.from_dtype(np.dtype("U"))) + def test_any_text(self, text): + # This test checks that, given any value that can be represented in an + # array of dtype("U") (i.e. unicode string), ... + a = np.array([text, text, text]) + # casting a list of them to an array does not e.g. truncate the value + assert_equal(a[0], text) + # and that np.array2string puts a newline in the expected location + expected_repr = "[{0!r} {0!r}\n {0!r}]".format(text) + result = np.array2string(a, max_line_width=len(repr(text)) * 2 + 3) + assert_equal(result, expected_repr) + + @pytest.mark.skipif(not HAS_REFCOUNT, reason="Python lacks refcounts") + def test_refcount(self): + # make sure we do not hold references to the array due to a recursive + # closure (gh-10620) + gc.disable() + a = np.arange(2) + r1 = sys.getrefcount(a) + np.array2string(a) + np.array2string(a) + r2 = sys.getrefcount(a) + gc.collect() + gc.enable() + assert_(r1 == r2) + +class TestPrintOptions: + """Test getting and setting global print options.""" + + def setup(self): + self.oldopts = np.get_printoptions() + + def teardown(self): + np.set_printoptions(**self.oldopts) + + def test_basic(self): + x = np.array([1.5, 0, 1.234567890]) + assert_equal(repr(x), "array([1.5 , 0. , 1.23456789])") + np.set_printoptions(precision=4) + assert_equal(repr(x), "array([1.5 , 0. , 1.2346])") + + def test_precision_zero(self): + np.set_printoptions(precision=0) + for values, string in ( + ([0.], "0."), ([.3], "0."), ([-.3], "-0."), ([.7], "1."), + ([1.5], "2."), ([-1.5], "-2."), ([-15.34], "-15."), + ([100.], "100."), ([.2, -1, 122.51], " 0., -1., 123."), + ([0], "0"), ([-12], "-12"), ([complex(.3, -.7)], "0.-1.j")): + x = np.array(values) + assert_equal(repr(x), "array([%s])" % string) + + def test_formatter(self): + x = np.arange(3) + np.set_printoptions(formatter={'all':lambda x: str(x-1)}) + assert_equal(repr(x), "array([-1, 0, 1])") + + def test_formatter_reset(self): + x = np.arange(3) + np.set_printoptions(formatter={'all':lambda x: str(x-1)}) + assert_equal(repr(x), "array([-1, 0, 1])") + np.set_printoptions(formatter={'int':None}) + assert_equal(repr(x), "array([0, 1, 2])") + + np.set_printoptions(formatter={'all':lambda x: str(x-1)}) + assert_equal(repr(x), "array([-1, 0, 1])") + np.set_printoptions(formatter={'all':None}) + assert_equal(repr(x), "array([0, 1, 2])") + + np.set_printoptions(formatter={'int':lambda x: str(x-1)}) + assert_equal(repr(x), "array([-1, 0, 1])") + np.set_printoptions(formatter={'int_kind':None}) + assert_equal(repr(x), "array([0, 1, 2])") + + x = np.arange(3.) + np.set_printoptions(formatter={'float':lambda x: str(x-1)}) + assert_equal(repr(x), "array([-1.0, 0.0, 1.0])") + np.set_printoptions(formatter={'float_kind':None}) + assert_equal(repr(x), "array([0., 1., 2.])") + + def test_0d_arrays(self): + assert_equal(str(np.array(u'café', '= 0: + expected_safety = Casting.safe + else: + expected_safety = Casting.same_kind + + to_dt = self.string_with_modified_length(string_dt, change_length) + safety, (_, res_dt) = cast._resolve_descriptors((other_dt, to_dt)) + assert res_dt is to_dt + assert safety == expected_safety + + # The opposite direction is always considered unsafe: + cast = get_castingimpl(string_DT, other_DT) + + safety, _ = cast._resolve_descriptors((string_dt, other_dt)) + assert safety == Casting.unsafe + + cast = get_castingimpl(string_DT, other_DT) + safety, (_, res_dt) = cast._resolve_descriptors((string_dt, None)) + assert safety == Casting.unsafe + assert other_dt is res_dt # returns the singleton for simple dtypes + + @pytest.mark.parametrize("other_dt", ["S8", "U8"]) + @pytest.mark.parametrize("string_char", ["S", "U"]) + def test_string_to_string_cancast(self, other_dt, string_char): + other_dt = np.dtype(other_dt) + + fact = 1 if string_char == "S" else 4 + div = 1 if other_dt.char == "S" else 4 + + string_DT = type(np.dtype(string_char)) + cast = get_castingimpl(type(other_dt), string_DT) + + expected_length = other_dt.itemsize // div + string_dt = np.dtype(f"{string_char}{expected_length}") + + safety, (res_other_dt, res_dt) = cast._resolve_descriptors((other_dt, None)) + assert res_dt.itemsize == expected_length * fact + assert isinstance(res_dt, string_DT) + + if other_dt.char == string_char: + if other_dt.isnative: + expected_safety = Casting.no | Casting.cast_is_view + else: + expected_safety = Casting.equiv + elif string_char == "U": + expected_safety = Casting.safe + else: + expected_safety = Casting.unsafe + + assert expected_safety == safety + + for change_length in [-1, 0, 1]: + to_dt = self.string_with_modified_length(string_dt, change_length) + safety, (_, res_dt) = cast._resolve_descriptors((other_dt, to_dt)) + + assert res_dt is to_dt + if expected_safety == Casting.unsafe: + assert safety == expected_safety + elif change_length < 0: + assert safety == Casting.same_kind + elif change_length == 0: + assert safety == expected_safety + elif change_length > 0: + assert safety == Casting.safe + + def test_void_to_string_special_case(self): + # Cover a small special case in void to string casting that could + # probably just as well be turned into an error (compare + # `test_object_to_parametric_internal_error` below). + assert np.array([], dtype="V5").astype("S").dtype.itemsize == 5 + assert np.array([], dtype="V5").astype("U").dtype.itemsize == 4 * 5 + + def test_object_to_parametric_internal_error(self): + # We reject casting from object to a parametric type, without + # figuring out the correct instance first. + object_dtype = type(np.dtype(object)) + other_dtype = type(np.dtype(str)) + cast = get_castingimpl(object_dtype, other_dtype) + with pytest.raises(TypeError, + match="casting from object to the parametric DType"): + cast._resolve_descriptors((np.dtype("O"), None)) diff --git a/venv/Lib/site-packages/numpy/core/tests/test_conversion_utils.py b/venv/Lib/site-packages/numpy/core/tests/test_conversion_utils.py new file mode 100644 index 0000000..d8849ee --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/tests/test_conversion_utils.py @@ -0,0 +1,205 @@ +""" +Tests for numpy/core/src/multiarray/conversion_utils.c +""" +import re + +import pytest + +import numpy as np +import numpy.core._multiarray_tests as mt +from numpy.testing import assert_warns + + +class StringConverterTestCase: + allow_bytes = True + case_insensitive = True + exact_match = False + warn = True + + def _check_value_error(self, val): + pattern = r'\(got {}\)'.format(re.escape(repr(val))) + with pytest.raises(ValueError, match=pattern) as exc: + self.conv(val) + + def _check_conv_assert_warn(self, val, expected): + if self.warn: + with assert_warns(DeprecationWarning) as exc: + assert self.conv(val) == expected + else: + assert self.conv(val) == expected + + def _check(self, val, expected): + """Takes valid non-deprecated inputs for converters, + runs converters on inputs, checks correctness of outputs, + warnings and errors""" + assert self.conv(val) == expected + + if self.allow_bytes: + assert self.conv(val.encode('ascii')) == expected + else: + with pytest.raises(TypeError): + self.conv(val.encode('ascii')) + + if len(val) != 1: + if self.exact_match: + self._check_value_error(val[:1]) + self._check_value_error(val + '\0') + else: + self._check_conv_assert_warn(val[:1], expected) + + if self.case_insensitive: + if val != val.lower(): + self._check_conv_assert_warn(val.lower(), expected) + if val != val.upper(): + self._check_conv_assert_warn(val.upper(), expected) + else: + if val != val.lower(): + self._check_value_error(val.lower()) + if val != val.upper(): + self._check_value_error(val.upper()) + + def test_wrong_type(self): + # common cases which apply to all the below + with pytest.raises(TypeError): + self.conv({}) + with pytest.raises(TypeError): + self.conv([]) + + def test_wrong_value(self): + # nonsense strings + self._check_value_error('') + self._check_value_error('\N{greek small letter pi}') + + if self.allow_bytes: + self._check_value_error(b'') + # bytes which can't be converted to strings via utf8 + self._check_value_error(b"\xFF") + if self.exact_match: + self._check_value_error("there's no way this is supported") + + +class TestByteorderConverter(StringConverterTestCase): + """ Tests of PyArray_ByteorderConverter """ + conv = mt.run_byteorder_converter + warn = False + + def test_valid(self): + for s in ['big', '>']: + self._check(s, 'NPY_BIG') + for s in ['little', '<']: + self._check(s, 'NPY_LITTLE') + for s in ['native', '=']: + self._check(s, 'NPY_NATIVE') + for s in ['ignore', '|']: + self._check(s, 'NPY_IGNORE') + for s in ['swap']: + self._check(s, 'NPY_SWAP') + + +class TestSortkindConverter(StringConverterTestCase): + """ Tests of PyArray_SortkindConverter """ + conv = mt.run_sortkind_converter + warn = False + + def test_valid(self): + self._check('quicksort', 'NPY_QUICKSORT') + self._check('heapsort', 'NPY_HEAPSORT') + self._check('mergesort', 'NPY_STABLESORT') # alias + self._check('stable', 'NPY_STABLESORT') + + +class TestSelectkindConverter(StringConverterTestCase): + """ Tests of PyArray_SelectkindConverter """ + conv = mt.run_selectkind_converter + case_insensitive = False + exact_match = True + + def test_valid(self): + self._check('introselect', 'NPY_INTROSELECT') + + +class TestSearchsideConverter(StringConverterTestCase): + """ Tests of PyArray_SearchsideConverter """ + conv = mt.run_searchside_converter + def test_valid(self): + self._check('left', 'NPY_SEARCHLEFT') + self._check('right', 'NPY_SEARCHRIGHT') + + +class TestOrderConverter(StringConverterTestCase): + """ Tests of PyArray_OrderConverter """ + conv = mt.run_order_converter + warn = False + + def test_valid(self): + self._check('c', 'NPY_CORDER') + self._check('f', 'NPY_FORTRANORDER') + self._check('a', 'NPY_ANYORDER') + self._check('k', 'NPY_KEEPORDER') + + def test_flatten_invalid_order(self): + # invalid after gh-14596 + with pytest.raises(ValueError): + self.conv('Z') + for order in [False, True, 0, 8]: + with pytest.raises(TypeError): + self.conv(order) + + +class TestClipmodeConverter(StringConverterTestCase): + """ Tests of PyArray_ClipmodeConverter """ + conv = mt.run_clipmode_converter + def test_valid(self): + self._check('clip', 'NPY_CLIP') + self._check('wrap', 'NPY_WRAP') + self._check('raise', 'NPY_RAISE') + + # integer values allowed here + assert self.conv(np.CLIP) == 'NPY_CLIP' + assert self.conv(np.WRAP) == 'NPY_WRAP' + assert self.conv(np.RAISE) == 'NPY_RAISE' + + +class TestCastingConverter(StringConverterTestCase): + """ Tests of PyArray_CastingConverter """ + conv = mt.run_casting_converter + case_insensitive = False + exact_match = True + + def test_valid(self): + self._check("no", "NPY_NO_CASTING") + self._check("equiv", "NPY_EQUIV_CASTING") + self._check("safe", "NPY_SAFE_CASTING") + self._check("same_kind", "NPY_SAME_KIND_CASTING") + self._check("unsafe", "NPY_UNSAFE_CASTING") + + +class TestIntpConverter: + """ Tests of PyArray_IntpConverter """ + conv = mt.run_intp_converter + + def test_basic(self): + assert self.conv(1) == (1,) + assert self.conv((1, 2)) == (1, 2) + assert self.conv([1, 2]) == (1, 2) + assert self.conv(()) == () + + def test_none(self): + # once the warning expires, this will raise TypeError + with pytest.warns(DeprecationWarning): + assert self.conv(None) == () + + def test_float(self): + with pytest.raises(TypeError): + self.conv(1.0) + with pytest.raises(TypeError): + self.conv([1, 1.0]) + + def test_too_large(self): + with pytest.raises(ValueError): + self.conv(2**64) + + def test_too_many_dims(self): + assert self.conv([1]*32) == (1,)*32 + with pytest.raises(ValueError): + self.conv([1]*33) diff --git a/venv/Lib/site-packages/numpy/core/tests/test_cpu_dispatcher.py b/venv/Lib/site-packages/numpy/core/tests/test_cpu_dispatcher.py new file mode 100644 index 0000000..8712dee --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/tests/test_cpu_dispatcher.py @@ -0,0 +1,42 @@ +from numpy.core._multiarray_umath import __cpu_features__, __cpu_baseline__, __cpu_dispatch__ +from numpy.core import _umath_tests +from numpy.testing import assert_equal + +def test_dispatcher(): + """ + Testing the utilites of the CPU dispatcher + """ + targets = ( + "SSE2", "SSE41", "AVX2", + "VSX", "VSX2", "VSX3", + "NEON", "ASIMD", "ASIMDHP" + ) + highest_sfx = "" # no suffix for the baseline + all_sfx = [] + for feature in reversed(targets): + # skip baseline features, by the default `CCompilerOpt` do not generate separated objects + # for the baseline, just one object combined all of them via 'baseline' option + # within the configuration statments. + if feature in __cpu_baseline__: + continue + # check compiler and running machine support + if feature not in __cpu_dispatch__ or not __cpu_features__[feature]: + continue + + if not highest_sfx: + highest_sfx = "_" + feature + all_sfx.append("func" + "_" + feature) + + test = _umath_tests.test_dispatch() + assert_equal(test["func"], "func" + highest_sfx) + assert_equal(test["var"], "var" + highest_sfx) + + if highest_sfx: + assert_equal(test["func_xb"], "func" + highest_sfx) + assert_equal(test["var_xb"], "var" + highest_sfx) + else: + assert_equal(test["func_xb"], "nobase") + assert_equal(test["var_xb"], "nobase") + + all_sfx.append("func") # add the baseline + assert_equal(test["all"], all_sfx) diff --git a/venv/Lib/site-packages/numpy/core/tests/test_cpu_features.py b/venv/Lib/site-packages/numpy/core/tests/test_cpu_features.py new file mode 100644 index 0000000..bafa5a0 --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/tests/test_cpu_features.py @@ -0,0 +1,171 @@ +import sys, platform, re, pytest +from numpy.core._multiarray_umath import __cpu_features__ + +def assert_features_equal(actual, desired, fname): + __tracebackhide__ = True # Hide traceback for py.test + actual, desired = str(actual), str(desired) + if actual == desired: + return + detected = str(__cpu_features__).replace("'", "") + try: + with open("/proc/cpuinfo", "r") as fd: + cpuinfo = fd.read(2048) + except Exception as err: + cpuinfo = str(err) + + try: + import subprocess + auxv = subprocess.check_output(['/bin/true'], env=dict(LD_SHOW_AUXV="1")) + auxv = auxv.decode() + except Exception as err: + auxv = str(err) + + import textwrap + error_report = textwrap.indent( +""" +########################################### +### Extra debugging information +########################################### +------------------------------------------- +--- NumPy Detections +------------------------------------------- +%s +------------------------------------------- +--- SYS / CPUINFO +------------------------------------------- +%s.... +------------------------------------------- +--- SYS / AUXV +------------------------------------------- +%s +""" % (detected, cpuinfo, auxv), prefix='\r') + + raise AssertionError(( + "Failure Detection\n" + " NAME: '%s'\n" + " ACTUAL: %s\n" + " DESIRED: %s\n" + "%s" + ) % (fname, actual, desired, error_report)) + +class AbstractTest(object): + features = [] + features_groups = {} + features_map = {} + features_flags = set() + + def load_flags(self): + # a hook + pass + def test_features(self): + self.load_flags() + for gname, features in self.features_groups.items(): + test_features = [self.cpu_have(f) for f in features] + assert_features_equal(__cpu_features__.get(gname), all(test_features), gname) + + for feature_name in self.features: + cpu_have = self.cpu_have(feature_name) + npy_have = __cpu_features__.get(feature_name) + assert_features_equal(npy_have, cpu_have, feature_name) + + def cpu_have(self, feature_name): + map_names = self.features_map.get(feature_name, feature_name) + if isinstance(map_names, str): + return map_names in self.features_flags + for f in map_names: + if f in self.features_flags: + return True + return False + + def load_flags_cpuinfo(self, magic_key): + self.features_flags = self.get_cpuinfo_item(magic_key) + + def get_cpuinfo_item(self, magic_key): + values = set() + with open('/proc/cpuinfo') as fd: + for line in fd: + if not line.startswith(magic_key): + continue + flags_value = [s.strip() for s in line.split(':', 1)] + if len(flags_value) == 2: + values = values.union(flags_value[1].upper().split()) + return values + + def load_flags_auxv(self): + import subprocess + auxv = subprocess.check_output(['/bin/true'], env=dict(LD_SHOW_AUXV="1")) + for at in auxv.split(b'\n'): + if not at.startswith(b"AT_HWCAP"): + continue + hwcap_value = [s.strip() for s in at.split(b':', 1)] + if len(hwcap_value) == 2: + self.features_flags = self.features_flags.union( + hwcap_value[1].upper().decode().split() + ) + +is_linux = sys.platform.startswith('linux') +machine = platform.machine() +is_x86 = re.match("^(amd64|x86|i386|i686)", machine, re.IGNORECASE) +@pytest.mark.skipif(not is_linux or not is_x86, reason="Only for Linux and x86") +class Test_X86_Features(AbstractTest): + features = [ + "MMX", "SSE", "SSE2", "SSE3", "SSSE3", "SSE41", "POPCNT", "SSE42", + "AVX", "F16C", "XOP", "FMA4", "FMA3", "AVX2", "AVX512F", "AVX512CD", + "AVX512ER", "AVX512PF", "AVX5124FMAPS", "AVX5124VNNIW", "AVX512VPOPCNTDQ", + "AVX512VL", "AVX512BW", "AVX512DQ", "AVX512VNNI", "AVX512IFMA", + "AVX512VBMI", "AVX512VBMI2", "AVX512BITALG", + ] + features_groups = dict( + AVX512_KNL = ["AVX512F", "AVX512CD", "AVX512ER", "AVX512PF"], + AVX512_KNM = ["AVX512F", "AVX512CD", "AVX512ER", "AVX512PF", "AVX5124FMAPS", + "AVX5124VNNIW", "AVX512VPOPCNTDQ"], + AVX512_SKX = ["AVX512F", "AVX512CD", "AVX512BW", "AVX512DQ", "AVX512VL"], + AVX512_CLX = ["AVX512F", "AVX512CD", "AVX512BW", "AVX512DQ", "AVX512VL", "AVX512VNNI"], + AVX512_CNL = ["AVX512F", "AVX512CD", "AVX512BW", "AVX512DQ", "AVX512VL", "AVX512IFMA", + "AVX512VBMI"], + AVX512_ICL = ["AVX512F", "AVX512CD", "AVX512BW", "AVX512DQ", "AVX512VL", "AVX512IFMA", + "AVX512VBMI", "AVX512VNNI", "AVX512VBMI2", "AVX512BITALG", "AVX512VPOPCNTDQ"], + ) + features_map = dict( + SSE3="PNI", SSE41="SSE4_1", SSE42="SSE4_2", FMA3="FMA", + AVX512VNNI="AVX512_VNNI", AVX512BITALG="AVX512_BITALG", AVX512VBMI2="AVX512_VBMI2", + AVX5124FMAPS="AVX512_4FMAPS", AVX5124VNNIW="AVX512_4VNNIW", AVX512VPOPCNTDQ="AVX512_VPOPCNTDQ", + ) + def load_flags(self): + self.load_flags_cpuinfo("flags") + +is_power = re.match("^(powerpc|ppc)64", machine, re.IGNORECASE) +@pytest.mark.skipif(not is_linux or not is_power, reason="Only for Linux and Power") +class Test_POWER_Features(AbstractTest): + features = ["VSX", "VSX2", "VSX3"] + features_map = dict(VSX2="ARCH_2_07", VSX3="ARCH_3_00") + + def load_flags(self): + self.load_flags_auxv() + +is_arm = re.match("^(arm|aarch64)", machine, re.IGNORECASE) +@pytest.mark.skipif(not is_linux or not is_arm, reason="Only for Linux and ARM") +class Test_ARM_Features(AbstractTest): + features = [ + "NEON", "ASIMD", "FPHP", "ASIMDHP", "ASIMDDP", "ASIMDFHM" + ] + features_groups = dict( + NEON_FP16 = ["NEON", "HALF"], + NEON_VFPV4 = ["NEON", "VFPV4"], + ) + def load_flags(self): + self.load_flags_cpuinfo("Features") + arch = self.get_cpuinfo_item("CPU architecture") + # in case of mounting virtual filesystem of aarch64 kernel + is_rootfs_v8 = int('0'+next(iter(arch))) > 7 if arch else 0 + if re.match("^(aarch64|AARCH64)", machine) or is_rootfs_v8: + self.features_map = dict( + NEON="ASIMD", HALF="ASIMD", VFPV4="ASIMD" + ) + else: + self.features_map = dict( + # ELF auxiliary vector and /proc/cpuinfo on Linux kernel(armv8 aarch32) + # doesn't provide information about ASIMD, so we assume that ASIMD is supported + # if the kernel reports any one of the following ARM8 features. + ASIMD=("AES", "SHA1", "SHA2", "PMULL", "CRC32") + ) diff --git a/venv/Lib/site-packages/numpy/core/tests/test_cython.py b/venv/Lib/site-packages/numpy/core/tests/test_cython.py new file mode 100644 index 0000000..a1f09d0 --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/tests/test_cython.py @@ -0,0 +1,134 @@ +import os +import shutil +import subprocess +import sys +import pytest + +import numpy as np + +# This import is copied from random.tests.test_extending +try: + import cython + from Cython.Compiler.Version import version as cython_version +except ImportError: + cython = None +else: + from distutils.version import LooseVersion + + # Cython 0.29.21 is required for Python 3.9 and there are + # other fixes in the 0.29 series that are needed even for earlier + # Python versions. + # Note: keep in sync with the one in pyproject.toml + required_version = LooseVersion("0.29.21") + if LooseVersion(cython_version) < required_version: + # too old or wrong cython, skip the test + cython = None + +pytestmark = pytest.mark.skipif(cython is None, reason="requires cython") + + +@pytest.fixture +def install_temp(request, tmp_path): + # Based in part on test_cython from random.tests.test_extending + + here = os.path.dirname(__file__) + ext_dir = os.path.join(here, "examples") + + cytest = str(tmp_path / "cytest") + + shutil.copytree(ext_dir, cytest) + # build the examples and "install" them into a temporary directory + + install_log = str(tmp_path / "tmp_install_log.txt") + subprocess.check_call( + [ + sys.executable, + "setup.py", + "build", + "install", + "--prefix", str(tmp_path / "installdir"), + "--single-version-externally-managed", + "--record", + install_log, + ], + cwd=cytest, + ) + + # In order to import the built module, we need its path to sys.path + # so parse that out of the record + with open(install_log) as fid: + for line in fid: + if "checks" in line: + sys.path.append(os.path.dirname(line)) + break + else: + raise RuntimeError(f'could not parse "{install_log}"') + + +def test_is_timedelta64_object(install_temp): + import checks + + assert checks.is_td64(np.timedelta64(1234)) + assert checks.is_td64(np.timedelta64(1234, "ns")) + assert checks.is_td64(np.timedelta64("NaT", "ns")) + + assert not checks.is_td64(1) + assert not checks.is_td64(None) + assert not checks.is_td64("foo") + assert not checks.is_td64(np.datetime64("now", "s")) + + +def test_is_datetime64_object(install_temp): + import checks + + assert checks.is_dt64(np.datetime64(1234, "ns")) + assert checks.is_dt64(np.datetime64("NaT", "ns")) + + assert not checks.is_dt64(1) + assert not checks.is_dt64(None) + assert not checks.is_dt64("foo") + assert not checks.is_dt64(np.timedelta64(1234)) + + +def test_get_datetime64_value(install_temp): + import checks + + dt64 = np.datetime64("2016-01-01", "ns") + + result = checks.get_dt64_value(dt64) + expected = dt64.view("i8") + + assert result == expected + + +def test_get_timedelta64_value(install_temp): + import checks + + td64 = np.timedelta64(12345, "h") + + result = checks.get_td64_value(td64) + expected = td64.view("i8") + + assert result == expected + + +def test_get_datetime64_unit(install_temp): + import checks + + dt64 = np.datetime64("2016-01-01", "ns") + result = checks.get_dt64_unit(dt64) + expected = 10 + assert result == expected + + td64 = np.timedelta64(12345, "h") + result = checks.get_dt64_unit(td64) + expected = 5 + assert result == expected + + +def test_abstract_scalars(install_temp): + import checks + + assert checks.is_integer(1) + assert checks.is_integer(np.int8(1)) + assert checks.is_integer(np.uint64(1)) diff --git a/venv/Lib/site-packages/numpy/core/tests/test_datetime.py b/venv/Lib/site-packages/numpy/core/tests/test_datetime.py new file mode 100644 index 0000000..62f6381 --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/tests/test_datetime.py @@ -0,0 +1,2413 @@ + +import numpy +import numpy as np +import datetime +import pytest +from numpy.testing import ( + assert_, assert_equal, assert_raises, assert_warns, suppress_warnings, + assert_raises_regex, + ) +from numpy.compat import pickle + +# Use pytz to test out various time zones if available +try: + from pytz import timezone as tz + _has_pytz = True +except ImportError: + _has_pytz = False + +try: + RecursionError +except NameError: + RecursionError = RuntimeError # python < 3.5 + + +class TestDateTime: + def test_datetime_dtype_creation(self): + for unit in ['Y', 'M', 'W', 'D', + 'h', 'm', 's', 'ms', 'us', + 'μs', # alias for us + 'ns', 'ps', 'fs', 'as']: + dt1 = np.dtype('M8[750%s]' % unit) + assert_(dt1 == np.dtype('datetime64[750%s]' % unit)) + dt2 = np.dtype('m8[%s]' % unit) + assert_(dt2 == np.dtype('timedelta64[%s]' % unit)) + + # Generic units shouldn't add [] to the end + assert_equal(str(np.dtype("M8")), "datetime64") + + # Should be possible to specify the endianness + assert_equal(np.dtype("=M8"), np.dtype("M8")) + assert_equal(np.dtype("=M8[s]"), np.dtype("M8[s]")) + assert_(np.dtype(">M8") == np.dtype("M8") or + np.dtype("M8[D]") == np.dtype("M8[D]") or + np.dtype("M8") != np.dtype("m8") == np.dtype("m8") or + np.dtype("m8[D]") == np.dtype("m8[D]") or + np.dtype("m8") != np.dtype(" Scalars + assert_equal(np.datetime64(b, '[s]'), np.datetime64('NaT', '[s]')) + assert_equal(np.datetime64(b, '[ms]'), np.datetime64('NaT', '[ms]')) + assert_equal(np.datetime64(b, '[M]'), np.datetime64('NaT', '[M]')) + assert_equal(np.datetime64(b, '[Y]'), np.datetime64('NaT', '[Y]')) + assert_equal(np.datetime64(b, '[W]'), np.datetime64('NaT', '[W]')) + + # Arrays -> Scalars + assert_equal(np.datetime64(a, '[s]'), np.datetime64('NaT', '[s]')) + assert_equal(np.datetime64(a, '[ms]'), np.datetime64('NaT', '[ms]')) + assert_equal(np.datetime64(a, '[M]'), np.datetime64('NaT', '[M]')) + assert_equal(np.datetime64(a, '[Y]'), np.datetime64('NaT', '[Y]')) + assert_equal(np.datetime64(a, '[W]'), np.datetime64('NaT', '[W]')) + + # NaN -> NaT + nan = np.array([np.nan] * 8) + fnan = nan.astype('f') + lnan = nan.astype('g') + cnan = nan.astype('D') + cfnan = nan.astype('F') + clnan = nan.astype('G') + + nat = np.array([np.datetime64('NaT')] * 8) + assert_equal(nan.astype('M8[ns]'), nat) + assert_equal(fnan.astype('M8[ns]'), nat) + assert_equal(lnan.astype('M8[ns]'), nat) + assert_equal(cnan.astype('M8[ns]'), nat) + assert_equal(cfnan.astype('M8[ns]'), nat) + assert_equal(clnan.astype('M8[ns]'), nat) + + nat = np.array([np.timedelta64('NaT')] * 8) + assert_equal(nan.astype('timedelta64[ns]'), nat) + assert_equal(fnan.astype('timedelta64[ns]'), nat) + assert_equal(lnan.astype('timedelta64[ns]'), nat) + assert_equal(cnan.astype('timedelta64[ns]'), nat) + assert_equal(cfnan.astype('timedelta64[ns]'), nat) + assert_equal(clnan.astype('timedelta64[ns]'), nat) + + def test_days_creation(self): + assert_equal(np.array('1599', dtype='M8[D]').astype('i8'), + (1600-1970)*365 - (1972-1600)/4 + 3 - 365) + assert_equal(np.array('1600', dtype='M8[D]').astype('i8'), + (1600-1970)*365 - (1972-1600)/4 + 3) + assert_equal(np.array('1601', dtype='M8[D]').astype('i8'), + (1600-1970)*365 - (1972-1600)/4 + 3 + 366) + assert_equal(np.array('1900', dtype='M8[D]').astype('i8'), + (1900-1970)*365 - (1970-1900)//4) + assert_equal(np.array('1901', dtype='M8[D]').astype('i8'), + (1900-1970)*365 - (1970-1900)//4 + 365) + assert_equal(np.array('1967', dtype='M8[D]').astype('i8'), -3*365 - 1) + assert_equal(np.array('1968', dtype='M8[D]').astype('i8'), -2*365 - 1) + assert_equal(np.array('1969', dtype='M8[D]').astype('i8'), -1*365) + assert_equal(np.array('1970', dtype='M8[D]').astype('i8'), 0*365) + assert_equal(np.array('1971', dtype='M8[D]').astype('i8'), 1*365) + assert_equal(np.array('1972', dtype='M8[D]').astype('i8'), 2*365) + assert_equal(np.array('1973', dtype='M8[D]').astype('i8'), 3*365 + 1) + assert_equal(np.array('1974', dtype='M8[D]').astype('i8'), 4*365 + 1) + assert_equal(np.array('2000', dtype='M8[D]').astype('i8'), + (2000 - 1970)*365 + (2000 - 1972)//4) + assert_equal(np.array('2001', dtype='M8[D]').astype('i8'), + (2000 - 1970)*365 + (2000 - 1972)//4 + 366) + assert_equal(np.array('2400', dtype='M8[D]').astype('i8'), + (2400 - 1970)*365 + (2400 - 1972)//4 - 3) + assert_equal(np.array('2401', dtype='M8[D]').astype('i8'), + (2400 - 1970)*365 + (2400 - 1972)//4 - 3 + 366) + + assert_equal(np.array('1600-02-29', dtype='M8[D]').astype('i8'), + (1600-1970)*365 - (1972-1600)//4 + 3 + 31 + 28) + assert_equal(np.array('1600-03-01', dtype='M8[D]').astype('i8'), + (1600-1970)*365 - (1972-1600)//4 + 3 + 31 + 29) + assert_equal(np.array('2000-02-29', dtype='M8[D]').astype('i8'), + (2000 - 1970)*365 + (2000 - 1972)//4 + 31 + 28) + assert_equal(np.array('2000-03-01', dtype='M8[D]').astype('i8'), + (2000 - 1970)*365 + (2000 - 1972)//4 + 31 + 29) + assert_equal(np.array('2001-03-22', dtype='M8[D]').astype('i8'), + (2000 - 1970)*365 + (2000 - 1972)//4 + 366 + 31 + 28 + 21) + + def test_days_to_pydate(self): + assert_equal(np.array('1599', dtype='M8[D]').astype('O'), + datetime.date(1599, 1, 1)) + assert_equal(np.array('1600', dtype='M8[D]').astype('O'), + datetime.date(1600, 1, 1)) + assert_equal(np.array('1601', dtype='M8[D]').astype('O'), + datetime.date(1601, 1, 1)) + assert_equal(np.array('1900', dtype='M8[D]').astype('O'), + datetime.date(1900, 1, 1)) + assert_equal(np.array('1901', dtype='M8[D]').astype('O'), + datetime.date(1901, 1, 1)) + assert_equal(np.array('2000', dtype='M8[D]').astype('O'), + datetime.date(2000, 1, 1)) + assert_equal(np.array('2001', dtype='M8[D]').astype('O'), + datetime.date(2001, 1, 1)) + assert_equal(np.array('1600-02-29', dtype='M8[D]').astype('O'), + datetime.date(1600, 2, 29)) + assert_equal(np.array('1600-03-01', dtype='M8[D]').astype('O'), + datetime.date(1600, 3, 1)) + assert_equal(np.array('2001-03-22', dtype='M8[D]').astype('O'), + datetime.date(2001, 3, 22)) + + def test_dtype_comparison(self): + assert_(not (np.dtype('M8[us]') == np.dtype('M8[ms]'))) + assert_(np.dtype('M8[us]') != np.dtype('M8[ms]')) + assert_(np.dtype('M8[2D]') != np.dtype('M8[D]')) + assert_(np.dtype('M8[D]') != np.dtype('M8[2D]')) + + def test_pydatetime_creation(self): + a = np.array(['1960-03-12', datetime.date(1960, 3, 12)], dtype='M8[D]') + assert_equal(a[0], a[1]) + a = np.array(['1999-12-31', datetime.date(1999, 12, 31)], dtype='M8[D]') + assert_equal(a[0], a[1]) + a = np.array(['2000-01-01', datetime.date(2000, 1, 1)], dtype='M8[D]') + assert_equal(a[0], a[1]) + # Will fail if the date changes during the exact right moment + a = np.array(['today', datetime.date.today()], dtype='M8[D]') + assert_equal(a[0], a[1]) + # datetime.datetime.now() returns local time, not UTC + #a = np.array(['now', datetime.datetime.now()], dtype='M8[s]') + #assert_equal(a[0], a[1]) + + # we can give a datetime.date time units + assert_equal(np.array(datetime.date(1960, 3, 12), dtype='M8[s]'), + np.array(np.datetime64('1960-03-12T00:00:00'))) + + def test_datetime_string_conversion(self): + a = ['2011-03-16', '1920-01-01', '2013-05-19'] + str_a = np.array(a, dtype='S') + uni_a = np.array(a, dtype='U') + dt_a = np.array(a, dtype='M') + + # String to datetime + assert_equal(dt_a, str_a.astype('M')) + assert_equal(dt_a.dtype, str_a.astype('M').dtype) + dt_b = np.empty_like(dt_a) + dt_b[...] = str_a + assert_equal(dt_a, dt_b) + + # Datetime to string + assert_equal(str_a, dt_a.astype('S0')) + str_b = np.empty_like(str_a) + str_b[...] = dt_a + assert_equal(str_a, str_b) + + # Unicode to datetime + assert_equal(dt_a, uni_a.astype('M')) + assert_equal(dt_a.dtype, uni_a.astype('M').dtype) + dt_b = np.empty_like(dt_a) + dt_b[...] = uni_a + assert_equal(dt_a, dt_b) + + # Datetime to unicode + assert_equal(uni_a, dt_a.astype('U')) + uni_b = np.empty_like(uni_a) + uni_b[...] = dt_a + assert_equal(uni_a, uni_b) + + # Datetime to long string - gh-9712 + assert_equal(str_a, dt_a.astype((np.string_, 128))) + str_b = np.empty(str_a.shape, dtype=(np.string_, 128)) + str_b[...] = dt_a + assert_equal(str_a, str_b) + + def test_datetime_array_str(self): + a = np.array(['2011-03-16', '1920-01-01', '2013-05-19'], dtype='M') + assert_equal(str(a), "['2011-03-16' '1920-01-01' '2013-05-19']") + + a = np.array(['2011-03-16T13:55', '1920-01-01T03:12'], dtype='M') + assert_equal(np.array2string(a, separator=', ', + formatter={'datetime': lambda x: + "'%s'" % np.datetime_as_string(x, timezone='UTC')}), + "['2011-03-16T13:55Z', '1920-01-01T03:12Z']") + + # Check that one NaT doesn't corrupt subsequent entries + a = np.array(['2010', 'NaT', '2030']).astype('M') + assert_equal(str(a), "['2010' 'NaT' '2030']") + + def test_timedelta_array_str(self): + a = np.array([-1, 0, 100], dtype='m') + assert_equal(str(a), "[ -1 0 100]") + a = np.array(['NaT', 'NaT'], dtype='m') + assert_equal(str(a), "['NaT' 'NaT']") + # Check right-alignment with NaTs + a = np.array([-1, 'NaT', 0], dtype='m') + assert_equal(str(a), "[ -1 'NaT' 0]") + a = np.array([-1, 'NaT', 1234567], dtype='m') + assert_equal(str(a), "[ -1 'NaT' 1234567]") + + # Test with other byteorder: + a = np.array([-1, 'NaT', 1234567], dtype='>m') + assert_equal(str(a), "[ -1 'NaT' 1234567]") + a = np.array([-1, 'NaT', 1234567], dtype=''\np4\nNNNI-1\nI-1\nI0\n((dp5\n(S'us'\np6\n" + \ + b"I1\nI1\nI1\ntp7\ntp8\ntp9\nb." + assert_equal(pickle.loads(pkl), np.dtype('>M8[us]')) + + def test_setstate(self): + "Verify that datetime dtype __setstate__ can handle bad arguments" + dt = np.dtype('>M8[us]') + assert_raises(ValueError, dt.__setstate__, (4, '>', None, None, None, -1, -1, 0, 1)) + assert_(dt.__reduce__()[2] == np.dtype('>M8[us]').__reduce__()[2]) + assert_raises(TypeError, dt.__setstate__, (4, '>', None, None, None, -1, -1, 0, ({}, 'xxx'))) + assert_(dt.__reduce__()[2] == np.dtype('>M8[us]').__reduce__()[2]) + + def test_dtype_promotion(self): + # datetime datetime computes the metadata gcd + # timedelta timedelta computes the metadata gcd + for mM in ['m', 'M']: + assert_equal( + np.promote_types(np.dtype(mM+'8[2Y]'), np.dtype(mM+'8[2Y]')), + np.dtype(mM+'8[2Y]')) + assert_equal( + np.promote_types(np.dtype(mM+'8[12Y]'), np.dtype(mM+'8[15Y]')), + np.dtype(mM+'8[3Y]')) + assert_equal( + np.promote_types(np.dtype(mM+'8[62M]'), np.dtype(mM+'8[24M]')), + np.dtype(mM+'8[2M]')) + assert_equal( + np.promote_types(np.dtype(mM+'8[1W]'), np.dtype(mM+'8[2D]')), + np.dtype(mM+'8[1D]')) + assert_equal( + np.promote_types(np.dtype(mM+'8[W]'), np.dtype(mM+'8[13s]')), + np.dtype(mM+'8[s]')) + assert_equal( + np.promote_types(np.dtype(mM+'8[13W]'), np.dtype(mM+'8[49s]')), + np.dtype(mM+'8[7s]')) + # timedelta timedelta raises when there is no reasonable gcd + assert_raises(TypeError, np.promote_types, + np.dtype('m8[Y]'), np.dtype('m8[D]')) + assert_raises(TypeError, np.promote_types, + np.dtype('m8[M]'), np.dtype('m8[W]')) + # timedelta and float cannot be safely cast with each other + assert_raises(TypeError, np.promote_types, "float32", "m8") + assert_raises(TypeError, np.promote_types, "m8", "float32") + assert_raises(TypeError, np.promote_types, "uint64", "m8") + assert_raises(TypeError, np.promote_types, "m8", "uint64") + + # timedelta timedelta may overflow with big unit ranges + assert_raises(OverflowError, np.promote_types, + np.dtype('m8[W]'), np.dtype('m8[fs]')) + assert_raises(OverflowError, np.promote_types, + np.dtype('m8[s]'), np.dtype('m8[as]')) + + def test_cast_overflow(self): + # gh-4486 + def cast(): + numpy.datetime64("1971-01-01 00:00:00.000000000000000").astype("datetime64[%s]', + 'timedelta64[%s]']) + def test_isfinite_isinf_isnan_units(self, unit, dstr): + '''check isfinite, isinf, isnan for all units of M, m dtypes + ''' + arr_val = [123, -321, "NaT"] + arr = np.array(arr_val, dtype= dstr % unit) + pos = np.array([True, True, False]) + neg = np.array([False, False, True]) + false = np.array([False, False, False]) + assert_equal(np.isfinite(arr), pos) + assert_equal(np.isinf(arr), false) + assert_equal(np.isnan(arr), neg) + + def test_assert_equal(self): + assert_raises(AssertionError, assert_equal, + np.datetime64('nat'), np.timedelta64('nat')) + + def test_corecursive_input(self): + # construct a co-recursive list + a, b = [], [] + a.append(b) + b.append(a) + obj_arr = np.array([None]) + obj_arr[0] = a + + # At some point this caused a stack overflow (gh-11154). Now raises + # ValueError since the nested list cannot be converted to a datetime. + assert_raises(ValueError, obj_arr.astype, 'M8') + assert_raises(ValueError, obj_arr.astype, 'm8') + + @pytest.mark.parametrize("shape", [(), (1,)]) + def test_discovery_from_object_array(self, shape): + arr = np.array("2020-10-10", dtype=object).reshape(shape) + res = np.array("2020-10-10", dtype="M8").reshape(shape) + assert res.dtype == np.dtype("M8[D]") + assert_equal(arr.astype("M8"), res) + arr[...] = np.bytes_("2020-10-10") # try a numpy string type + assert_equal(arr.astype("M8"), res) + arr = arr.astype("S") + assert_equal(arr.astype("S").astype("M8"), res) + + @pytest.mark.parametrize("time_unit", [ + "Y", "M", "W", "D", "h", "m", "s", "ms", "us", "ns", "ps", "fs", "as", + # compound units + "10D", "2M", + ]) + def test_limit_symmetry(self, time_unit): + """ + Dates should have symmetric limits around the unix epoch at +/-np.int64 + """ + epoch = np.datetime64(0, time_unit) + latest = np.datetime64(np.iinfo(np.int64).max, time_unit) + earliest = np.datetime64(-np.iinfo(np.int64).max, time_unit) + + # above should not have overflowed + assert earliest < epoch < latest + + @pytest.mark.parametrize("time_unit", [ + "Y", "M", + pytest.param("W", marks=pytest.mark.xfail(reason="gh-13197")), + "D", "h", "m", + "s", "ms", "us", "ns", "ps", "fs", "as", + pytest.param("10D", marks=pytest.mark.xfail(reason="similar to gh-13197")), + ]) + @pytest.mark.parametrize("sign", [-1, 1]) + def test_limit_str_roundtrip(self, time_unit, sign): + """ + Limits should roundtrip when converted to strings. + + This tests the conversion to and from npy_datetimestruct. + """ + # TODO: add absolute (gold standard) time span limit strings + limit = np.datetime64(np.iinfo(np.int64).max * sign, time_unit) + + # Convert to string and back. Explicit unit needed since the day and + # week reprs are not distinguishable. + limit_via_str = np.datetime64(str(limit), time_unit) + assert limit_via_str == limit + + +class TestDateTimeData: + + def test_basic(self): + a = np.array(['1980-03-23'], dtype=np.datetime64) + assert_equal(np.datetime_data(a.dtype), ('D', 1)) + + def test_bytes(self): + # byte units are converted to unicode + dt = np.datetime64('2000', (b'ms', 5)) + assert np.datetime_data(dt.dtype) == ('ms', 5) + + dt = np.datetime64('2000', b'5ms') + assert np.datetime_data(dt.dtype) == ('ms', 5) + + def test_non_ascii(self): + # μs is normalized to μ + dt = np.datetime64('2000', ('μs', 5)) + assert np.datetime_data(dt.dtype) == ('us', 5) + + dt = np.datetime64('2000', '5μs') + assert np.datetime_data(dt.dtype) == ('us', 5) diff --git a/venv/Lib/site-packages/numpy/core/tests/test_defchararray.py b/venv/Lib/site-packages/numpy/core/tests/test_defchararray.py new file mode 100644 index 0000000..59fc547 --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/tests/test_defchararray.py @@ -0,0 +1,673 @@ + +import numpy as np +from numpy.core.multiarray import _vec_string +from numpy.testing import ( + assert_, assert_equal, assert_array_equal, assert_raises, + assert_raises_regex + ) + +kw_unicode_true = {'unicode': True} # make 2to3 work properly +kw_unicode_false = {'unicode': False} + +class TestBasic: + def test_from_object_array(self): + A = np.array([['abc', 2], + ['long ', '0123456789']], dtype='O') + B = np.char.array(A) + assert_equal(B.dtype.itemsize, 10) + assert_array_equal(B, [[b'abc', b'2'], + [b'long', b'0123456789']]) + + def test_from_object_array_unicode(self): + A = np.array([['abc', u'Sigma \u03a3'], + ['long ', '0123456789']], dtype='O') + assert_raises(ValueError, np.char.array, (A,)) + B = np.char.array(A, **kw_unicode_true) + assert_equal(B.dtype.itemsize, 10 * np.array('a', 'U').dtype.itemsize) + assert_array_equal(B, [['abc', u'Sigma \u03a3'], + ['long', '0123456789']]) + + def test_from_string_array(self): + A = np.array([[b'abc', b'foo'], + [b'long ', b'0123456789']]) + assert_equal(A.dtype.type, np.string_) + B = np.char.array(A) + assert_array_equal(B, A) + assert_equal(B.dtype, A.dtype) + assert_equal(B.shape, A.shape) + B[0, 0] = 'changed' + assert_(B[0, 0] != A[0, 0]) + C = np.char.asarray(A) + assert_array_equal(C, A) + assert_equal(C.dtype, A.dtype) + C[0, 0] = 'changed again' + assert_(C[0, 0] != B[0, 0]) + assert_(C[0, 0] == A[0, 0]) + + def test_from_unicode_array(self): + A = np.array([['abc', u'Sigma \u03a3'], + ['long ', '0123456789']]) + assert_equal(A.dtype.type, np.unicode_) + B = np.char.array(A) + assert_array_equal(B, A) + assert_equal(B.dtype, A.dtype) + assert_equal(B.shape, A.shape) + B = np.char.array(A, **kw_unicode_true) + assert_array_equal(B, A) + assert_equal(B.dtype, A.dtype) + assert_equal(B.shape, A.shape) + + def fail(): + np.char.array(A, **kw_unicode_false) + + assert_raises(UnicodeEncodeError, fail) + + def test_unicode_upconvert(self): + A = np.char.array(['abc']) + B = np.char.array([u'\u03a3']) + assert_(issubclass((A + B).dtype.type, np.unicode_)) + + def test_from_string(self): + A = np.char.array(b'abc') + assert_equal(len(A), 1) + assert_equal(len(A[0]), 3) + assert_(issubclass(A.dtype.type, np.string_)) + + def test_from_unicode(self): + A = np.char.array(u'\u03a3') + assert_equal(len(A), 1) + assert_equal(len(A[0]), 1) + assert_equal(A.itemsize, 4) + assert_(issubclass(A.dtype.type, np.unicode_)) + +class TestVecString: + def test_non_existent_method(self): + + def fail(): + _vec_string('a', np.string_, 'bogus') + + assert_raises(AttributeError, fail) + + def test_non_string_array(self): + + def fail(): + _vec_string(1, np.string_, 'strip') + + assert_raises(TypeError, fail) + + def test_invalid_args_tuple(self): + + def fail(): + _vec_string(['a'], np.string_, 'strip', 1) + + assert_raises(TypeError, fail) + + def test_invalid_type_descr(self): + + def fail(): + _vec_string(['a'], 'BOGUS', 'strip') + + assert_raises(TypeError, fail) + + def test_invalid_function_args(self): + + def fail(): + _vec_string(['a'], np.string_, 'strip', (1,)) + + assert_raises(TypeError, fail) + + def test_invalid_result_type(self): + + def fail(): + _vec_string(['a'], np.int_, 'strip') + + assert_raises(TypeError, fail) + + def test_broadcast_error(self): + + def fail(): + _vec_string([['abc', 'def']], np.int_, 'find', (['a', 'd', 'j'],)) + + assert_raises(ValueError, fail) + + +class TestWhitespace: + def setup(self): + self.A = np.array([['abc ', '123 '], + ['789 ', 'xyz ']]).view(np.chararray) + self.B = np.array([['abc', '123'], + ['789', 'xyz']]).view(np.chararray) + + def test1(self): + assert_(np.all(self.A == self.B)) + assert_(np.all(self.A >= self.B)) + assert_(np.all(self.A <= self.B)) + assert_(not np.any(self.A > self.B)) + assert_(not np.any(self.A < self.B)) + assert_(not np.any(self.A != self.B)) + +class TestChar: + def setup(self): + self.A = np.array('abc1', dtype='c').view(np.chararray) + + def test_it(self): + assert_equal(self.A.shape, (4,)) + assert_equal(self.A.upper()[:2].tobytes(), b'AB') + +class TestComparisons: + def setup(self): + self.A = np.array([['abc', '123'], + ['789', 'xyz']]).view(np.chararray) + self.B = np.array([['efg', '123 '], + ['051', 'tuv']]).view(np.chararray) + + def test_not_equal(self): + assert_array_equal((self.A != self.B), [[True, False], [True, True]]) + + def test_equal(self): + assert_array_equal((self.A == self.B), [[False, True], [False, False]]) + + def test_greater_equal(self): + assert_array_equal((self.A >= self.B), [[False, True], [True, True]]) + + def test_less_equal(self): + assert_array_equal((self.A <= self.B), [[True, True], [False, False]]) + + def test_greater(self): + assert_array_equal((self.A > self.B), [[False, False], [True, True]]) + + def test_less(self): + assert_array_equal((self.A < self.B), [[True, False], [False, False]]) + + def test_type(self): + out1 = np.char.equal(self.A, self.B) + out2 = np.char.equal('a', 'a') + assert_(isinstance(out1, np.ndarray)) + assert_(isinstance(out2, np.ndarray)) + +class TestComparisonsMixed1(TestComparisons): + """Ticket #1276""" + + def setup(self): + TestComparisons.setup(self) + self.B = np.array([['efg', '123 '], + ['051', 'tuv']], np.unicode_).view(np.chararray) + +class TestComparisonsMixed2(TestComparisons): + """Ticket #1276""" + + def setup(self): + TestComparisons.setup(self) + self.A = np.array([['abc', '123'], + ['789', 'xyz']], np.unicode_).view(np.chararray) + +class TestInformation: + def setup(self): + self.A = np.array([[' abc ', ''], + ['12345', 'MixedCase'], + ['123 \t 345 \0 ', 'UPPER']]).view(np.chararray) + self.B = np.array([[u' \u03a3 ', u''], + [u'12345', u'MixedCase'], + [u'123 \t 345 \0 ', u'UPPER']]).view(np.chararray) + + def test_len(self): + assert_(issubclass(np.char.str_len(self.A).dtype.type, np.integer)) + assert_array_equal(np.char.str_len(self.A), [[5, 0], [5, 9], [12, 5]]) + assert_array_equal(np.char.str_len(self.B), [[3, 0], [5, 9], [12, 5]]) + + def test_count(self): + assert_(issubclass(self.A.count('').dtype.type, np.integer)) + assert_array_equal(self.A.count('a'), [[1, 0], [0, 1], [0, 0]]) + assert_array_equal(self.A.count('123'), [[0, 0], [1, 0], [1, 0]]) + # Python doesn't seem to like counting NULL characters + # assert_array_equal(self.A.count('\0'), [[0, 0], [0, 0], [1, 0]]) + assert_array_equal(self.A.count('a', 0, 2), [[1, 0], [0, 0], [0, 0]]) + assert_array_equal(self.B.count('a'), [[0, 0], [0, 1], [0, 0]]) + assert_array_equal(self.B.count('123'), [[0, 0], [1, 0], [1, 0]]) + # assert_array_equal(self.B.count('\0'), [[0, 0], [0, 0], [1, 0]]) + + def test_endswith(self): + assert_(issubclass(self.A.endswith('').dtype.type, np.bool_)) + assert_array_equal(self.A.endswith(' '), [[1, 0], [0, 0], [1, 0]]) + assert_array_equal(self.A.endswith('3', 0, 3), [[0, 0], [1, 0], [1, 0]]) + + def fail(): + self.A.endswith('3', 'fdjk') + + assert_raises(TypeError, fail) + + def test_find(self): + assert_(issubclass(self.A.find('a').dtype.type, np.integer)) + assert_array_equal(self.A.find('a'), [[1, -1], [-1, 6], [-1, -1]]) + assert_array_equal(self.A.find('3'), [[-1, -1], [2, -1], [2, -1]]) + assert_array_equal(self.A.find('a', 0, 2), [[1, -1], [-1, -1], [-1, -1]]) + assert_array_equal(self.A.find(['1', 'P']), [[-1, -1], [0, -1], [0, 1]]) + + def test_index(self): + + def fail(): + self.A.index('a') + + assert_raises(ValueError, fail) + assert_(np.char.index('abcba', 'b') == 1) + assert_(issubclass(np.char.index('abcba', 'b').dtype.type, np.integer)) + + def test_isalnum(self): + assert_(issubclass(self.A.isalnum().dtype.type, np.bool_)) + assert_array_equal(self.A.isalnum(), [[False, False], [True, True], [False, True]]) + + def test_isalpha(self): + assert_(issubclass(self.A.isalpha().dtype.type, np.bool_)) + assert_array_equal(self.A.isalpha(), [[False, False], [False, True], [False, True]]) + + def test_isdigit(self): + assert_(issubclass(self.A.isdigit().dtype.type, np.bool_)) + assert_array_equal(self.A.isdigit(), [[False, False], [True, False], [False, False]]) + + def test_islower(self): + assert_(issubclass(self.A.islower().dtype.type, np.bool_)) + assert_array_equal(self.A.islower(), [[True, False], [False, False], [False, False]]) + + def test_isspace(self): + assert_(issubclass(self.A.isspace().dtype.type, np.bool_)) + assert_array_equal(self.A.isspace(), [[False, False], [False, False], [False, False]]) + + def test_istitle(self): + assert_(issubclass(self.A.istitle().dtype.type, np.bool_)) + assert_array_equal(self.A.istitle(), [[False, False], [False, False], [False, False]]) + + def test_isupper(self): + assert_(issubclass(self.A.isupper().dtype.type, np.bool_)) + assert_array_equal(self.A.isupper(), [[False, False], [False, False], [False, True]]) + + def test_rfind(self): + assert_(issubclass(self.A.rfind('a').dtype.type, np.integer)) + assert_array_equal(self.A.rfind('a'), [[1, -1], [-1, 6], [-1, -1]]) + assert_array_equal(self.A.rfind('3'), [[-1, -1], [2, -1], [6, -1]]) + assert_array_equal(self.A.rfind('a', 0, 2), [[1, -1], [-1, -1], [-1, -1]]) + assert_array_equal(self.A.rfind(['1', 'P']), [[-1, -1], [0, -1], [0, 2]]) + + def test_rindex(self): + + def fail(): + self.A.rindex('a') + + assert_raises(ValueError, fail) + assert_(np.char.rindex('abcba', 'b') == 3) + assert_(issubclass(np.char.rindex('abcba', 'b').dtype.type, np.integer)) + + def test_startswith(self): + assert_(issubclass(self.A.startswith('').dtype.type, np.bool_)) + assert_array_equal(self.A.startswith(' '), [[1, 0], [0, 0], [0, 0]]) + assert_array_equal(self.A.startswith('1', 0, 3), [[0, 0], [1, 0], [1, 0]]) + + def fail(): + self.A.startswith('3', 'fdjk') + + assert_raises(TypeError, fail) + + +class TestMethods: + def setup(self): + self.A = np.array([[' abc ', ''], + ['12345', 'MixedCase'], + ['123 \t 345 \0 ', 'UPPER']], + dtype='S').view(np.chararray) + self.B = np.array([[u' \u03a3 ', u''], + [u'12345', u'MixedCase'], + [u'123 \t 345 \0 ', u'UPPER']]).view(np.chararray) + + def test_capitalize(self): + tgt = [[b' abc ', b''], + [b'12345', b'Mixedcase'], + [b'123 \t 345 \0 ', b'Upper']] + assert_(issubclass(self.A.capitalize().dtype.type, np.string_)) + assert_array_equal(self.A.capitalize(), tgt) + + tgt = [[u' \u03c3 ', ''], + ['12345', 'Mixedcase'], + ['123 \t 345 \0 ', 'Upper']] + assert_(issubclass(self.B.capitalize().dtype.type, np.unicode_)) + assert_array_equal(self.B.capitalize(), tgt) + + def test_center(self): + assert_(issubclass(self.A.center(10).dtype.type, np.string_)) + C = self.A.center([10, 20]) + assert_array_equal(np.char.str_len(C), [[10, 20], [10, 20], [12, 20]]) + + C = self.A.center(20, b'#') + assert_(np.all(C.startswith(b'#'))) + assert_(np.all(C.endswith(b'#'))) + + C = np.char.center(b'FOO', [[10, 20], [15, 8]]) + tgt = [[b' FOO ', b' FOO '], + [b' FOO ', b' FOO ']] + assert_(issubclass(C.dtype.type, np.string_)) + assert_array_equal(C, tgt) + + def test_decode(self): + A = np.char.array([b'\\u03a3']) + assert_(A.decode('unicode-escape')[0] == '\u03a3') + + def test_encode(self): + B = self.B.encode('unicode_escape') + assert_(B[0][0] == str(' \\u03a3 ').encode('latin1')) + + def test_expandtabs(self): + T = self.A.expandtabs() + assert_(T[2, 0] == b'123 345 \0') + + def test_join(self): + # NOTE: list(b'123') == [49, 50, 51] + # so that b','.join(b'123') results to an error on Py3 + A0 = self.A.decode('ascii') + + A = np.char.join([',', '#'], A0) + assert_(issubclass(A.dtype.type, np.unicode_)) + tgt = np.array([[' ,a,b,c, ', ''], + ['1,2,3,4,5', 'M#i#x#e#d#C#a#s#e'], + ['1,2,3, ,\t, ,3,4,5, ,\x00, ', 'U#P#P#E#R']]) + assert_array_equal(np.char.join([',', '#'], A0), tgt) + + def test_ljust(self): + assert_(issubclass(self.A.ljust(10).dtype.type, np.string_)) + + C = self.A.ljust([10, 20]) + assert_array_equal(np.char.str_len(C), [[10, 20], [10, 20], [12, 20]]) + + C = self.A.ljust(20, b'#') + assert_array_equal(C.startswith(b'#'), [ + [False, True], [False, False], [False, False]]) + assert_(np.all(C.endswith(b'#'))) + + C = np.char.ljust(b'FOO', [[10, 20], [15, 8]]) + tgt = [[b'FOO ', b'FOO '], + [b'FOO ', b'FOO ']] + assert_(issubclass(C.dtype.type, np.string_)) + assert_array_equal(C, tgt) + + def test_lower(self): + tgt = [[b' abc ', b''], + [b'12345', b'mixedcase'], + [b'123 \t 345 \0 ', b'upper']] + assert_(issubclass(self.A.lower().dtype.type, np.string_)) + assert_array_equal(self.A.lower(), tgt) + + tgt = [[u' \u03c3 ', u''], + [u'12345', u'mixedcase'], + [u'123 \t 345 \0 ', u'upper']] + assert_(issubclass(self.B.lower().dtype.type, np.unicode_)) + assert_array_equal(self.B.lower(), tgt) + + def test_lstrip(self): + tgt = [[b'abc ', b''], + [b'12345', b'MixedCase'], + [b'123 \t 345 \0 ', b'UPPER']] + assert_(issubclass(self.A.lstrip().dtype.type, np.string_)) + assert_array_equal(self.A.lstrip(), tgt) + + tgt = [[b' abc', b''], + [b'2345', b'ixedCase'], + [b'23 \t 345 \x00', b'UPPER']] + assert_array_equal(self.A.lstrip([b'1', b'M']), tgt) + + tgt = [[u'\u03a3 ', ''], + ['12345', 'MixedCase'], + ['123 \t 345 \0 ', 'UPPER']] + assert_(issubclass(self.B.lstrip().dtype.type, np.unicode_)) + assert_array_equal(self.B.lstrip(), tgt) + + def test_partition(self): + P = self.A.partition([b'3', b'M']) + tgt = [[(b' abc ', b'', b''), (b'', b'', b'')], + [(b'12', b'3', b'45'), (b'', b'M', b'ixedCase')], + [(b'12', b'3', b' \t 345 \0 '), (b'UPPER', b'', b'')]] + assert_(issubclass(P.dtype.type, np.string_)) + assert_array_equal(P, tgt) + + def test_replace(self): + R = self.A.replace([b'3', b'a'], + [b'##########', b'@']) + tgt = [[b' abc ', b''], + [b'12##########45', b'MixedC@se'], + [b'12########## \t ##########45 \x00', b'UPPER']] + assert_(issubclass(R.dtype.type, np.string_)) + assert_array_equal(R, tgt) + + def test_rjust(self): + assert_(issubclass(self.A.rjust(10).dtype.type, np.string_)) + + C = self.A.rjust([10, 20]) + assert_array_equal(np.char.str_len(C), [[10, 20], [10, 20], [12, 20]]) + + C = self.A.rjust(20, b'#') + assert_(np.all(C.startswith(b'#'))) + assert_array_equal(C.endswith(b'#'), + [[False, True], [False, False], [False, False]]) + + C = np.char.rjust(b'FOO', [[10, 20], [15, 8]]) + tgt = [[b' FOO', b' FOO'], + [b' FOO', b' FOO']] + assert_(issubclass(C.dtype.type, np.string_)) + assert_array_equal(C, tgt) + + def test_rpartition(self): + P = self.A.rpartition([b'3', b'M']) + tgt = [[(b'', b'', b' abc '), (b'', b'', b'')], + [(b'12', b'3', b'45'), (b'', b'M', b'ixedCase')], + [(b'123 \t ', b'3', b'45 \0 '), (b'', b'', b'UPPER')]] + assert_(issubclass(P.dtype.type, np.string_)) + assert_array_equal(P, tgt) + + def test_rsplit(self): + A = self.A.rsplit(b'3') + tgt = [[[b' abc '], [b'']], + [[b'12', b'45'], [b'MixedCase']], + [[b'12', b' \t ', b'45 \x00 '], [b'UPPER']]] + assert_(issubclass(A.dtype.type, np.object_)) + assert_equal(A.tolist(), tgt) + + def test_rstrip(self): + assert_(issubclass(self.A.rstrip().dtype.type, np.string_)) + + tgt = [[b' abc', b''], + [b'12345', b'MixedCase'], + [b'123 \t 345', b'UPPER']] + assert_array_equal(self.A.rstrip(), tgt) + + tgt = [[b' abc ', b''], + [b'1234', b'MixedCase'], + [b'123 \t 345 \x00', b'UPP'] + ] + assert_array_equal(self.A.rstrip([b'5', b'ER']), tgt) + + tgt = [[u' \u03a3', ''], + ['12345', 'MixedCase'], + ['123 \t 345', 'UPPER']] + assert_(issubclass(self.B.rstrip().dtype.type, np.unicode_)) + assert_array_equal(self.B.rstrip(), tgt) + + def test_strip(self): + tgt = [[b'abc', b''], + [b'12345', b'MixedCase'], + [b'123 \t 345', b'UPPER']] + assert_(issubclass(self.A.strip().dtype.type, np.string_)) + assert_array_equal(self.A.strip(), tgt) + + tgt = [[b' abc ', b''], + [b'234', b'ixedCas'], + [b'23 \t 345 \x00', b'UPP']] + assert_array_equal(self.A.strip([b'15', b'EReM']), tgt) + + tgt = [[u'\u03a3', ''], + ['12345', 'MixedCase'], + ['123 \t 345', 'UPPER']] + assert_(issubclass(self.B.strip().dtype.type, np.unicode_)) + assert_array_equal(self.B.strip(), tgt) + + def test_split(self): + A = self.A.split(b'3') + tgt = [ + [[b' abc '], [b'']], + [[b'12', b'45'], [b'MixedCase']], + [[b'12', b' \t ', b'45 \x00 '], [b'UPPER']]] + assert_(issubclass(A.dtype.type, np.object_)) + assert_equal(A.tolist(), tgt) + + def test_splitlines(self): + A = np.char.array(['abc\nfds\nwer']).splitlines() + assert_(issubclass(A.dtype.type, np.object_)) + assert_(A.shape == (1,)) + assert_(len(A[0]) == 3) + + def test_swapcase(self): + tgt = [[b' ABC ', b''], + [b'12345', b'mIXEDcASE'], + [b'123 \t 345 \0 ', b'upper']] + assert_(issubclass(self.A.swapcase().dtype.type, np.string_)) + assert_array_equal(self.A.swapcase(), tgt) + + tgt = [[u' \u03c3 ', u''], + [u'12345', u'mIXEDcASE'], + [u'123 \t 345 \0 ', u'upper']] + assert_(issubclass(self.B.swapcase().dtype.type, np.unicode_)) + assert_array_equal(self.B.swapcase(), tgt) + + def test_title(self): + tgt = [[b' Abc ', b''], + [b'12345', b'Mixedcase'], + [b'123 \t 345 \0 ', b'Upper']] + assert_(issubclass(self.A.title().dtype.type, np.string_)) + assert_array_equal(self.A.title(), tgt) + + tgt = [[u' \u03a3 ', u''], + [u'12345', u'Mixedcase'], + [u'123 \t 345 \0 ', u'Upper']] + assert_(issubclass(self.B.title().dtype.type, np.unicode_)) + assert_array_equal(self.B.title(), tgt) + + def test_upper(self): + tgt = [[b' ABC ', b''], + [b'12345', b'MIXEDCASE'], + [b'123 \t 345 \0 ', b'UPPER']] + assert_(issubclass(self.A.upper().dtype.type, np.string_)) + assert_array_equal(self.A.upper(), tgt) + + tgt = [[u' \u03a3 ', u''], + [u'12345', u'MIXEDCASE'], + [u'123 \t 345 \0 ', u'UPPER']] + assert_(issubclass(self.B.upper().dtype.type, np.unicode_)) + assert_array_equal(self.B.upper(), tgt) + + def test_isnumeric(self): + + def fail(): + self.A.isnumeric() + + assert_raises(TypeError, fail) + assert_(issubclass(self.B.isnumeric().dtype.type, np.bool_)) + assert_array_equal(self.B.isnumeric(), [ + [False, False], [True, False], [False, False]]) + + def test_isdecimal(self): + + def fail(): + self.A.isdecimal() + + assert_raises(TypeError, fail) + assert_(issubclass(self.B.isdecimal().dtype.type, np.bool_)) + assert_array_equal(self.B.isdecimal(), [ + [False, False], [True, False], [False, False]]) + + +class TestOperations: + def setup(self): + self.A = np.array([['abc', '123'], + ['789', 'xyz']]).view(np.chararray) + self.B = np.array([['efg', '456'], + ['051', 'tuv']]).view(np.chararray) + + def test_add(self): + AB = np.array([['abcefg', '123456'], + ['789051', 'xyztuv']]).view(np.chararray) + assert_array_equal(AB, (self.A + self.B)) + assert_(len((self.A + self.B)[0][0]) == 6) + + def test_radd(self): + QA = np.array([['qabc', 'q123'], + ['q789', 'qxyz']]).view(np.chararray) + assert_array_equal(QA, ('q' + self.A)) + + def test_mul(self): + A = self.A + for r in (2, 3, 5, 7, 197): + Ar = np.array([[A[0, 0]*r, A[0, 1]*r], + [A[1, 0]*r, A[1, 1]*r]]).view(np.chararray) + + assert_array_equal(Ar, (self.A * r)) + + for ob in [object(), 'qrs']: + with assert_raises_regex(ValueError, + 'Can only multiply by integers'): + A*ob + + def test_rmul(self): + A = self.A + for r in (2, 3, 5, 7, 197): + Ar = np.array([[A[0, 0]*r, A[0, 1]*r], + [A[1, 0]*r, A[1, 1]*r]]).view(np.chararray) + assert_array_equal(Ar, (r * self.A)) + + for ob in [object(), 'qrs']: + with assert_raises_regex(ValueError, + 'Can only multiply by integers'): + ob * A + + def test_mod(self): + """Ticket #856""" + F = np.array([['%d', '%f'], ['%s', '%r']]).view(np.chararray) + C = np.array([[3, 7], [19, 1]]) + FC = np.array([['3', '7.000000'], + ['19', '1']]).view(np.chararray) + assert_array_equal(FC, F % C) + + A = np.array([['%.3f', '%d'], ['%s', '%r']]).view(np.chararray) + A1 = np.array([['1.000', '1'], ['1', '1']]).view(np.chararray) + assert_array_equal(A1, (A % 1)) + + A2 = np.array([['1.000', '2'], ['3', '4']]).view(np.chararray) + assert_array_equal(A2, (A % [[1, 2], [3, 4]])) + + def test_rmod(self): + assert_(("%s" % self.A) == str(self.A)) + assert_(("%r" % self.A) == repr(self.A)) + + for ob in [42, object()]: + with assert_raises_regex( + TypeError, "unsupported operand type.* and 'chararray'"): + ob % self.A + + def test_slice(self): + """Regression test for https://github.com/numpy/numpy/issues/5982""" + + arr = np.array([['abc ', 'def '], ['geh ', 'ijk ']], + dtype='S4').view(np.chararray) + sl1 = arr[:] + assert_array_equal(sl1, arr) + assert_(sl1.base is arr) + assert_(sl1.base.base is arr.base) + + sl2 = arr[:, :] + assert_array_equal(sl2, arr) + assert_(sl2.base is arr) + assert_(sl2.base.base is arr.base) + + assert_(arr[0, 0] == b'abc') + + +def test_empty_indexing(): + """Regression test for ticket 1948.""" + # Check that indexing a chararray with an empty list/array returns an + # empty chararray instead of a chararray with a single empty string in it. + s = np.chararray((4,)) + assert_(s[[]].size == 0) diff --git a/venv/Lib/site-packages/numpy/core/tests/test_deprecations.py b/venv/Lib/site-packages/numpy/core/tests/test_deprecations.py new file mode 100644 index 0000000..a079406 --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/tests/test_deprecations.py @@ -0,0 +1,873 @@ +""" +Tests related to deprecation warnings. Also a convenient place +to document how deprecations should eventually be turned into errors. + +""" +import datetime +import operator +import warnings +import pytest +import tempfile +import re +import sys + +import numpy as np +from numpy.testing import ( + assert_raises, assert_warns, assert_, assert_array_equal + ) + +from numpy.core._multiarray_tests import fromstring_null_term_c_api + +try: + import pytz + _has_pytz = True +except ImportError: + _has_pytz = False + + +class _DeprecationTestCase: + # Just as warning: warnings uses re.match, so the start of this message + # must match. + message = '' + warning_cls = DeprecationWarning + + def setup(self): + self.warn_ctx = warnings.catch_warnings(record=True) + self.log = self.warn_ctx.__enter__() + + # Do *not* ignore other DeprecationWarnings. Ignoring warnings + # can give very confusing results because of + # https://bugs.python.org/issue4180 and it is probably simplest to + # try to keep the tests cleanly giving only the right warning type. + # (While checking them set to "error" those are ignored anyway) + # We still have them show up, because otherwise they would be raised + warnings.filterwarnings("always", category=self.warning_cls) + warnings.filterwarnings("always", message=self.message, + category=self.warning_cls) + + def teardown(self): + self.warn_ctx.__exit__() + + def assert_deprecated(self, function, num=1, ignore_others=False, + function_fails=False, + exceptions=np._NoValue, + args=(), kwargs={}): + """Test if DeprecationWarnings are given and raised. + + This first checks if the function when called gives `num` + DeprecationWarnings, after that it tries to raise these + DeprecationWarnings and compares them with `exceptions`. + The exceptions can be different for cases where this code path + is simply not anticipated and the exception is replaced. + + Parameters + ---------- + function : callable + The function to test + num : int + Number of DeprecationWarnings to expect. This should normally be 1. + ignore_others : bool + Whether warnings of the wrong type should be ignored (note that + the message is not checked) + function_fails : bool + If the function would normally fail, setting this will check for + warnings inside a try/except block. + exceptions : Exception or tuple of Exceptions + Exception to expect when turning the warnings into an error. + The default checks for DeprecationWarnings. If exceptions is + empty the function is expected to run successfully. + args : tuple + Arguments for `function` + kwargs : dict + Keyword arguments for `function` + """ + __tracebackhide__ = True # Hide traceback for py.test + + # reset the log + self.log[:] = [] + + if exceptions is np._NoValue: + exceptions = (self.warning_cls,) + + try: + function(*args, **kwargs) + except (Exception if function_fails else tuple()): + pass + + # just in case, clear the registry + num_found = 0 + for warning in self.log: + if warning.category is self.warning_cls: + num_found += 1 + elif not ignore_others: + raise AssertionError( + "expected %s but got: %s" % + (self.warning_cls.__name__, warning.category)) + if num is not None and num_found != num: + msg = "%i warnings found but %i expected." % (len(self.log), num) + lst = [str(w) for w in self.log] + raise AssertionError("\n".join([msg] + lst)) + + with warnings.catch_warnings(): + warnings.filterwarnings("error", message=self.message, + category=self.warning_cls) + try: + function(*args, **kwargs) + if exceptions != tuple(): + raise AssertionError( + "No error raised during function call") + except exceptions: + if exceptions == tuple(): + raise AssertionError( + "Error raised during function call") + + def assert_not_deprecated(self, function, args=(), kwargs={}): + """Test that warnings are not raised. + + This is just a shorthand for: + + self.assert_deprecated(function, num=0, ignore_others=True, + exceptions=tuple(), args=args, kwargs=kwargs) + """ + self.assert_deprecated(function, num=0, ignore_others=True, + exceptions=tuple(), args=args, kwargs=kwargs) + + +class _VisibleDeprecationTestCase(_DeprecationTestCase): + warning_cls = np.VisibleDeprecationWarning + + +class TestNonTupleNDIndexDeprecation: + def test_basic(self): + a = np.zeros((5, 5)) + with warnings.catch_warnings(): + warnings.filterwarnings('always') + assert_warns(FutureWarning, a.__getitem__, [[0, 1], [0, 1]]) + assert_warns(FutureWarning, a.__getitem__, [slice(None)]) + + warnings.filterwarnings('error') + assert_raises(FutureWarning, a.__getitem__, [[0, 1], [0, 1]]) + assert_raises(FutureWarning, a.__getitem__, [slice(None)]) + + # a a[[0, 1]] always was advanced indexing, so no error/warning + a[[0, 1]] + + +class TestComparisonDeprecations(_DeprecationTestCase): + """This tests the deprecation, for non-element-wise comparison logic. + This used to mean that when an error occurred during element-wise comparison + (i.e. broadcasting) NotImplemented was returned, but also in the comparison + itself, False was given instead of the error. + + Also test FutureWarning for the None comparison. + """ + + message = "elementwise.* comparison failed; .*" + + def test_normal_types(self): + for op in (operator.eq, operator.ne): + # Broadcasting errors: + self.assert_deprecated(op, args=(np.zeros(3), [])) + a = np.zeros(3, dtype='i,i') + # (warning is issued a couple of times here) + self.assert_deprecated(op, args=(a, a[:-1]), num=None) + + # ragged array comparison returns True/False + a = np.array([1, np.array([1,2,3])], dtype=object) + b = np.array([1, np.array([1,2,3])], dtype=object) + self.assert_deprecated(op, args=(a, b), num=None) + + def test_string(self): + # For two string arrays, strings always raised the broadcasting error: + a = np.array(['a', 'b']) + b = np.array(['a', 'b', 'c']) + assert_raises(ValueError, lambda x, y: x == y, a, b) + + # The empty list is not cast to string, and this used to pass due + # to dtype mismatch; now (2018-06-21) it correctly leads to a + # FutureWarning. + assert_warns(FutureWarning, lambda: a == []) + + def test_void_dtype_equality_failures(self): + class NotArray: + def __array__(self): + raise TypeError + + # Needed so Python 3 does not raise DeprecationWarning twice. + def __ne__(self, other): + return NotImplemented + + self.assert_deprecated(lambda: np.arange(2) == NotArray()) + self.assert_deprecated(lambda: np.arange(2) != NotArray()) + + struct1 = np.zeros(2, dtype="i4,i4") + struct2 = np.zeros(2, dtype="i4,i4,i4") + + assert_warns(FutureWarning, lambda: struct1 == 1) + assert_warns(FutureWarning, lambda: struct1 == struct2) + assert_warns(FutureWarning, lambda: struct1 != 1) + assert_warns(FutureWarning, lambda: struct1 != struct2) + + def test_array_richcompare_legacy_weirdness(self): + # It doesn't really work to use assert_deprecated here, b/c part of + # the point of assert_deprecated is to check that when warnings are + # set to "error" mode then the error is propagated -- which is good! + # But here we are testing a bunch of code that is deprecated *because* + # it has the habit of swallowing up errors and converting them into + # different warnings. So assert_warns will have to be sufficient. + assert_warns(FutureWarning, lambda: np.arange(2) == "a") + assert_warns(FutureWarning, lambda: np.arange(2) != "a") + # No warning for scalar comparisons + with warnings.catch_warnings(): + warnings.filterwarnings("error") + assert_(not (np.array(0) == "a")) + assert_(np.array(0) != "a") + assert_(not (np.int16(0) == "a")) + assert_(np.int16(0) != "a") + + for arg1 in [np.asarray(0), np.int16(0)]: + struct = np.zeros(2, dtype="i4,i4") + for arg2 in [struct, "a"]: + for f in [operator.lt, operator.le, operator.gt, operator.ge]: + with warnings.catch_warnings() as l: + warnings.filterwarnings("always") + assert_raises(TypeError, f, arg1, arg2) + assert_(not l) + + +class TestDatetime64Timezone(_DeprecationTestCase): + """Parsing of datetime64 with timezones deprecated in 1.11.0, because + datetime64 is now timezone naive rather than UTC only. + + It will be quite a while before we can remove this, because, at the very + least, a lot of existing code uses the 'Z' modifier to avoid conversion + from local time to UTC, even if otherwise it handles time in a timezone + naive fashion. + """ + def test_string(self): + self.assert_deprecated(np.datetime64, args=('2000-01-01T00+01',)) + self.assert_deprecated(np.datetime64, args=('2000-01-01T00Z',)) + + @pytest.mark.skipif(not _has_pytz, + reason="The pytz module is not available.") + def test_datetime(self): + tz = pytz.timezone('US/Eastern') + dt = datetime.datetime(2000, 1, 1, 0, 0, tzinfo=tz) + self.assert_deprecated(np.datetime64, args=(dt,)) + + +class TestNonCContiguousViewDeprecation(_DeprecationTestCase): + """View of non-C-contiguous arrays deprecated in 1.11.0. + + The deprecation will not be raised for arrays that are both C and F + contiguous, as C contiguous is dominant. There are more such arrays + with relaxed stride checking than without so the deprecation is not + as visible with relaxed stride checking in force. + """ + + def test_fortran_contiguous(self): + self.assert_deprecated(np.ones((2,2)).T.view, args=(complex,)) + self.assert_deprecated(np.ones((2,2)).T.view, args=(np.int8,)) + + +class TestArrayDataAttributeAssignmentDeprecation(_DeprecationTestCase): + """Assigning the 'data' attribute of an ndarray is unsafe as pointed + out in gh-7093. Eventually, such assignment should NOT be allowed, but + in the interests of maintaining backwards compatibility, only a Deprecation- + Warning will be raised instead for the time being to give developers time to + refactor relevant code. + """ + + def test_data_attr_assignment(self): + a = np.arange(10) + b = np.linspace(0, 1, 10) + + self.message = ("Assigning the 'data' attribute is an " + "inherently unsafe operation and will " + "be removed in the future.") + self.assert_deprecated(a.__setattr__, args=('data', b.data)) + + +class TestBinaryReprInsufficientWidthParameterForRepresentation(_DeprecationTestCase): + """ + If a 'width' parameter is passed into ``binary_repr`` that is insufficient to + represent the number in base 2 (positive) or 2's complement (negative) form, + the function used to silently ignore the parameter and return a representation + using the minimal number of bits needed for the form in question. Such behavior + is now considered unsafe from a user perspective and will raise an error in the future. + """ + + def test_insufficient_width_positive(self): + args = (10,) + kwargs = {'width': 2} + + self.message = ("Insufficient bit width provided. This behavior " + "will raise an error in the future.") + self.assert_deprecated(np.binary_repr, args=args, kwargs=kwargs) + + def test_insufficient_width_negative(self): + args = (-5,) + kwargs = {'width': 2} + + self.message = ("Insufficient bit width provided. This behavior " + "will raise an error in the future.") + self.assert_deprecated(np.binary_repr, args=args, kwargs=kwargs) + + +class TestNumericStyleTypecodes(_DeprecationTestCase): + """ + Most numeric style typecodes were previously deprecated (and removed) + in 1.20. This also deprecates the remaining ones. + """ + # 2020-06-09, NumPy 1.20 + def test_all_dtypes(self): + deprecated_types = ['Bytes0', 'Datetime64', 'Str0'] + # Depending on intp size, either Uint32 or Uint64 is defined: + deprecated_types.append(f"U{np.dtype(np.intp).name}") + for dt in deprecated_types: + self.assert_deprecated(np.dtype, exceptions=(TypeError,), + args=(dt,)) + + +class TestTestDeprecated: + def test_assert_deprecated(self): + test_case_instance = _DeprecationTestCase() + test_case_instance.setup() + assert_raises(AssertionError, + test_case_instance.assert_deprecated, + lambda: None) + + def foo(): + warnings.warn("foo", category=DeprecationWarning, stacklevel=2) + + test_case_instance.assert_deprecated(foo) + test_case_instance.teardown() + + +class TestNonNumericConjugate(_DeprecationTestCase): + """ + Deprecate no-op behavior of ndarray.conjugate on non-numeric dtypes, + which conflicts with the error behavior of np.conjugate. + """ + def test_conjugate(self): + for a in np.array(5), np.array(5j): + self.assert_not_deprecated(a.conjugate) + for a in (np.array('s'), np.array('2016', 'M'), + np.array((1, 2), [('a', int), ('b', int)])): + self.assert_deprecated(a.conjugate) + + +class TestNPY_CHAR(_DeprecationTestCase): + # 2017-05-03, 1.13.0 + def test_npy_char_deprecation(self): + from numpy.core._multiarray_tests import npy_char_deprecation + self.assert_deprecated(npy_char_deprecation) + assert_(npy_char_deprecation() == 'S1') + + +class TestPyArray_AS1D(_DeprecationTestCase): + def test_npy_pyarrayas1d_deprecation(self): + from numpy.core._multiarray_tests import npy_pyarrayas1d_deprecation + assert_raises(NotImplementedError, npy_pyarrayas1d_deprecation) + + +class TestPyArray_AS2D(_DeprecationTestCase): + def test_npy_pyarrayas2d_deprecation(self): + from numpy.core._multiarray_tests import npy_pyarrayas2d_deprecation + assert_raises(NotImplementedError, npy_pyarrayas2d_deprecation) + + +class Test_UPDATEIFCOPY(_DeprecationTestCase): + """ + v1.14 deprecates creating an array with the UPDATEIFCOPY flag, use + WRITEBACKIFCOPY instead + """ + def test_npy_updateifcopy_deprecation(self): + from numpy.core._multiarray_tests import npy_updateifcopy_deprecation + arr = np.arange(9).reshape(3, 3) + v = arr.T + self.assert_deprecated(npy_updateifcopy_deprecation, args=(v,)) + + +class TestDatetimeEvent(_DeprecationTestCase): + # 2017-08-11, 1.14.0 + def test_3_tuple(self): + for cls in (np.datetime64, np.timedelta64): + # two valid uses - (unit, num) and (unit, num, den, None) + self.assert_not_deprecated(cls, args=(1, ('ms', 2))) + self.assert_not_deprecated(cls, args=(1, ('ms', 2, 1, None))) + + # trying to use the event argument, removed in 1.7.0, is deprecated + # it used to be a uint8 + self.assert_deprecated(cls, args=(1, ('ms', 2, 'event'))) + self.assert_deprecated(cls, args=(1, ('ms', 2, 63))) + self.assert_deprecated(cls, args=(1, ('ms', 2, 1, 'event'))) + self.assert_deprecated(cls, args=(1, ('ms', 2, 1, 63))) + + +class TestTruthTestingEmptyArrays(_DeprecationTestCase): + # 2017-09-25, 1.14.0 + message = '.*truth value of an empty array is ambiguous.*' + + def test_1d(self): + self.assert_deprecated(bool, args=(np.array([]),)) + + def test_2d(self): + self.assert_deprecated(bool, args=(np.zeros((1, 0)),)) + self.assert_deprecated(bool, args=(np.zeros((0, 1)),)) + self.assert_deprecated(bool, args=(np.zeros((0, 0)),)) + + +class TestBincount(_DeprecationTestCase): + # 2017-06-01, 1.14.0 + def test_bincount_minlength(self): + self.assert_deprecated(lambda: np.bincount([1, 2, 3], minlength=None)) + + +class TestAlen(_DeprecationTestCase): + # 2019-08-02, 1.18.0 + def test_alen(self): + self.assert_deprecated(lambda: np.alen(np.array([1, 2, 3]))) + + +class TestGeneratorSum(_DeprecationTestCase): + # 2018-02-25, 1.15.0 + def test_generator_sum(self): + self.assert_deprecated(np.sum, args=((i for i in range(5)),)) + + +class TestPositiveOnNonNumerical(_DeprecationTestCase): + # 2018-06-28, 1.16.0 + def test_positive_on_non_number(self): + self.assert_deprecated(operator.pos, args=(np.array('foo'),)) + + +class TestFromstring(_DeprecationTestCase): + # 2017-10-19, 1.14 + def test_fromstring(self): + self.assert_deprecated(np.fromstring, args=('\x00'*80,)) + + +class TestFromStringAndFileInvalidData(_DeprecationTestCase): + # 2019-06-08, 1.17.0 + # Tests should be moved to real tests when deprecation is done. + message = "string or file could not be read to its end" + + @pytest.mark.parametrize("invalid_str", [",invalid_data", "invalid_sep"]) + def test_deprecate_unparsable_data_file(self, invalid_str): + x = np.array([1.51, 2, 3.51, 4], dtype=float) + + with tempfile.TemporaryFile(mode="w") as f: + x.tofile(f, sep=',', format='%.2f') + f.write(invalid_str) + + f.seek(0) + self.assert_deprecated(lambda: np.fromfile(f, sep=",")) + f.seek(0) + self.assert_deprecated(lambda: np.fromfile(f, sep=",", count=5)) + # Should not raise: + with warnings.catch_warnings(): + warnings.simplefilter("error", DeprecationWarning) + f.seek(0) + res = np.fromfile(f, sep=",", count=4) + assert_array_equal(res, x) + + @pytest.mark.parametrize("invalid_str", [",invalid_data", "invalid_sep"]) + def test_deprecate_unparsable_string(self, invalid_str): + x = np.array([1.51, 2, 3.51, 4], dtype=float) + x_str = "1.51,2,3.51,4{}".format(invalid_str) + + self.assert_deprecated(lambda: np.fromstring(x_str, sep=",")) + self.assert_deprecated(lambda: np.fromstring(x_str, sep=",", count=5)) + + # The C-level API can use not fixed size, but 0 terminated strings, + # so test that as well: + bytestr = x_str.encode("ascii") + self.assert_deprecated(lambda: fromstring_null_term_c_api(bytestr)) + + with assert_warns(DeprecationWarning): + # this is slightly strange, in that fromstring leaves data + # potentially uninitialized (would be good to error when all is + # read, but count is larger then actual data maybe). + res = np.fromstring(x_str, sep=",", count=5) + assert_array_equal(res[:-1], x) + + with warnings.catch_warnings(): + warnings.simplefilter("error", DeprecationWarning) + + # Should not raise: + res = np.fromstring(x_str, sep=",", count=4) + assert_array_equal(res, x) + + +class Test_GetSet_NumericOps(_DeprecationTestCase): + # 2018-09-20, 1.16.0 + def test_get_numeric_ops(self): + from numpy.core._multiarray_tests import getset_numericops + self.assert_deprecated(getset_numericops, num=2) + + # empty kwargs prevents any state actually changing which would break + # other tests. + self.assert_deprecated(np.set_numeric_ops, kwargs={}) + assert_raises(ValueError, np.set_numeric_ops, add='abc') + + +class TestShape1Fields(_DeprecationTestCase): + warning_cls = FutureWarning + + # 2019-05-20, 1.17.0 + def test_shape_1_fields(self): + self.assert_deprecated(np.dtype, args=([('a', int, 1)],)) + + +class TestNonZero(_DeprecationTestCase): + # 2019-05-26, 1.17.0 + def test_zerod(self): + self.assert_deprecated(lambda: np.nonzero(np.array(0))) + self.assert_deprecated(lambda: np.nonzero(np.array(1))) + + +def test_deprecate_ragged_arrays(): + # 2019-11-29 1.19.0 + # + # NEP 34 deprecated automatic object dtype when creating ragged + # arrays. Also see the "ragged" tests in `test_multiarray` + # + # emits a VisibleDeprecationWarning + arg = [1, [2, 3]] + with assert_warns(np.VisibleDeprecationWarning): + np.array(arg) + + +class TestTooDeepDeprecation(_VisibleDeprecationTestCase): + # NumPy 1.20, 2020-05-08 + # This is a bit similar to the above ragged array deprecation case. + message = re.escape("Creating an ndarray from nested sequences exceeding") + + def test_deprecation(self): + nested = [1] + for i in range(np.MAXDIMS - 1): + nested = [nested] + self.assert_not_deprecated(np.array, args=(nested,)) + self.assert_not_deprecated(np.array, + args=(nested,), kwargs=dict(dtype=object)) + + self.assert_deprecated(np.array, args=([nested],)) + + +class TestToString(_DeprecationTestCase): + # 2020-03-06 1.19.0 + message = re.escape("tostring() is deprecated. Use tobytes() instead.") + + def test_tostring(self): + arr = np.array(list(b"test\xFF"), dtype=np.uint8) + self.assert_deprecated(arr.tostring) + + def test_tostring_matches_tobytes(self): + arr = np.array(list(b"test\xFF"), dtype=np.uint8) + b = arr.tobytes() + with assert_warns(DeprecationWarning): + s = arr.tostring() + assert s == b + + +class TestDTypeCoercion(_DeprecationTestCase): + # 2020-02-06 1.19.0 + message = "Converting .* to a dtype .*is deprecated" + deprecated_types = [ + # The builtin scalar super types: + np.generic, np.flexible, np.number, + np.inexact, np.floating, np.complexfloating, + np.integer, np.unsignedinteger, np.signedinteger, + # character is a deprecated S1 special case: + np.character, + ] + + def test_dtype_coercion(self): + for scalar_type in self.deprecated_types: + self.assert_deprecated(np.dtype, args=(scalar_type,)) + + def test_array_construction(self): + for scalar_type in self.deprecated_types: + self.assert_deprecated(np.array, args=([], scalar_type,)) + + def test_not_deprecated(self): + # All specific types are not deprecated: + for group in np.sctypes.values(): + for scalar_type in group: + self.assert_not_deprecated(np.dtype, args=(scalar_type,)) + + for scalar_type in [type, dict, list, tuple]: + # Typical python types are coerced to object currently: + self.assert_not_deprecated(np.dtype, args=(scalar_type,)) + + +class BuiltInRoundComplexDType(_DeprecationTestCase): + # 2020-03-31 1.19.0 + deprecated_types = [np.csingle, np.cdouble, np.clongdouble] + not_deprecated_types = [ + np.int8, np.int16, np.int32, np.int64, + np.uint8, np.uint16, np.uint32, np.uint64, + np.float16, np.float32, np.float64, + ] + + def test_deprecated(self): + for scalar_type in self.deprecated_types: + scalar = scalar_type(0) + self.assert_deprecated(round, args=(scalar,)) + self.assert_deprecated(round, args=(scalar, 0)) + self.assert_deprecated(round, args=(scalar,), kwargs={'ndigits': 0}) + + def test_not_deprecated(self): + for scalar_type in self.not_deprecated_types: + scalar = scalar_type(0) + self.assert_not_deprecated(round, args=(scalar,)) + self.assert_not_deprecated(round, args=(scalar, 0)) + self.assert_not_deprecated(round, args=(scalar,), kwargs={'ndigits': 0}) + + +class TestIncorrectAdvancedIndexWithEmptyResult(_DeprecationTestCase): + # 2020-05-27, NumPy 1.20.0 + message = "Out of bound index found. This was previously ignored.*" + + @pytest.mark.parametrize("index", [([3, 0],), ([0, 0], [3, 0])]) + def test_empty_subspace(self, index): + # Test for both a single and two/multiple advanced indices. These + # This will raise an IndexError in the future. + arr = np.ones((2, 2, 0)) + self.assert_deprecated(arr.__getitem__, args=(index,)) + self.assert_deprecated(arr.__setitem__, args=(index, 0.)) + + # for this array, the subspace is only empty after applying the slice + arr2 = np.ones((2, 2, 1)) + index2 = (slice(0, 0),) + index + self.assert_deprecated(arr2.__getitem__, args=(index2,)) + self.assert_deprecated(arr2.__setitem__, args=(index2, 0.)) + + def test_empty_index_broadcast_not_deprecated(self): + arr = np.ones((2, 2, 2)) + + index = ([[3], [2]], []) # broadcast to an empty result. + self.assert_not_deprecated(arr.__getitem__, args=(index,)) + self.assert_not_deprecated(arr.__setitem__, + args=(index, np.empty((2, 0, 2)))) + + +class TestNonExactMatchDeprecation(_DeprecationTestCase): + # 2020-04-22 + def test_non_exact_match(self): + arr = np.array([[3, 6, 6], [4, 5, 1]]) + # misspelt mode check + self.assert_deprecated(lambda: np.ravel_multi_index(arr, (7, 6), mode='Cilp')) + # using completely different word with first character as R + self.assert_deprecated(lambda: np.searchsorted(arr[0], 4, side='Random')) + + +class TestDeprecatedGlobals(_DeprecationTestCase): + # 2020-06-06 + @pytest.mark.skipif( + sys.version_info < (3, 7), + reason='module-level __getattr__ not supported') + def test_type_aliases(self): + # from builtins + self.assert_deprecated(lambda: np.bool(True)) + self.assert_deprecated(lambda: np.int(1)) + self.assert_deprecated(lambda: np.float(1)) + self.assert_deprecated(lambda: np.complex(1)) + self.assert_deprecated(lambda: np.object()) + self.assert_deprecated(lambda: np.str('abc')) + + # from np.compat + self.assert_deprecated(lambda: np.long(1)) + self.assert_deprecated(lambda: np.unicode('abc')) + + +class TestMatrixInOuter(_DeprecationTestCase): + # 2020-05-13 NumPy 1.20.0 + message = (r"add.outer\(\) was passed a numpy matrix as " + r"(first|second) argument.") + + def test_deprecated(self): + arr = np.array([1, 2, 3]) + m = np.array([1, 2, 3]).view(np.matrix) + self.assert_deprecated(np.add.outer, args=(m, m), num=2) + self.assert_deprecated(np.add.outer, args=(arr, m)) + self.assert_deprecated(np.add.outer, args=(m, arr)) + self.assert_not_deprecated(np.add.outer, args=(arr, arr)) + + +class TestRaggedArray(_DeprecationTestCase): + # 2020-07-24, NumPy 1.20.0 + message = "setting an array element with a sequence" + + def test_deprecated(self): + arr = np.ones((1, 1)) + # Deprecated if the array is a leave node: + self.assert_deprecated(lambda: np.array([arr, 0], dtype=np.float64)) + self.assert_deprecated(lambda: np.array([0, arr], dtype=np.float64)) + # And when it is an assignment into a lower dimensional subarray: + self.assert_deprecated(lambda: np.array([arr, [0]], dtype=np.float64)) + self.assert_deprecated(lambda: np.array([[0], arr], dtype=np.float64)) + + +class FlatteningConcatenateUnsafeCast(_DeprecationTestCase): + # NumPy 1.20, 2020-09-03 + message = "concatenate with `axis=None` will use same-kind casting" + + def test_deprecated(self): + self.assert_deprecated(np.concatenate, + args=(([0.], [1.]),), + kwargs=dict(axis=None, out=np.empty(2, dtype=np.int64))) + + def test_not_deprecated(self): + self.assert_not_deprecated(np.concatenate, + args=(([0.], [1.]),), + kwargs={'axis': None, 'out': np.empty(2, dtype=np.int64), + 'casting': "unsafe"}) + + with assert_raises(TypeError): + # Tests should notice if the deprecation warning is given first... + np.concatenate(([0.], [1.]), out=np.empty(2, dtype=np.int64), + casting="same_kind") + + +class TestDeprecateSubarrayDTypeDuringArrayCoercion(_DeprecationTestCase): + warning_cls = FutureWarning + message = "(creating|casting) an array (with|to) a subarray dtype" + + def test_deprecated_array(self): + # Arrays are more complex, since they "broadcast" on success: + arr = np.array([1, 2]) + + self.assert_deprecated(lambda: arr.astype("(2)i,")) + with pytest.warns(FutureWarning): + res = arr.astype("(2)i,") + + assert_array_equal(res, [[1, 2], [1, 2]]) + + self.assert_deprecated(lambda: np.array(arr, dtype="(2)i,")) + with pytest.warns(FutureWarning): + res = np.array(arr, dtype="(2)i,") + + assert_array_equal(res, [[1, 2], [1, 2]]) + + with pytest.warns(FutureWarning): + res = np.array([[(1,), (2,)], arr], dtype="(2)i,") + + assert_array_equal(res, [[[1, 1], [2, 2]], [[1, 2], [1, 2]]]) + + def test_deprecated_and_error(self): + # These error paths do not give a warning, but will succeed in the + # future. + arr = np.arange(5 * 2).reshape(5, 2) + def check(): + with pytest.raises(ValueError): + arr.astype("(2,2)f") + + self.assert_deprecated(check) + + def check(): + with pytest.raises(ValueError): + np.array(arr, dtype="(2,2)f") + + self.assert_deprecated(check) + + +class TestFutureWarningArrayLikeNotIterable(_DeprecationTestCase): + # Deprecated 2020-12-09, NumPy 1.20 + warning_cls = FutureWarning + message = "The input object of type.*but not a sequence" + + @pytest.mark.parametrize("protocol", + ["__array__", "__array_interface__", "__array_struct__"]) + def test_deprecated(self, protocol): + """Test that these objects give a warning since they are not 0-D, + not coerced at the top level `np.array(obj)`, but nested, and do + *not* define the sequence protocol. + + NOTE: Tests for the versions including __len__ and __getitem__ exist + in `test_array_coercion.py` and they can be modified or ammended + when this deprecation expired. + """ + blueprint = np.arange(10) + MyArr = type("MyArr", (), {protocol: getattr(blueprint, protocol)}) + self.assert_deprecated(lambda: np.array([MyArr()], dtype=object)) + + @pytest.mark.parametrize("protocol", + ["__array__", "__array_interface__", "__array_struct__"]) + def test_0d_not_deprecated(self, protocol): + # 0-D always worked (albeit it would use __float__ or similar for the + # conversion, which may not happen anymore) + blueprint = np.array(1.) + MyArr = type("MyArr", (), {protocol: getattr(blueprint, protocol)}) + myarr = MyArr() + + self.assert_not_deprecated(lambda: np.array([myarr], dtype=object)) + res = np.array([myarr], dtype=object) + expected = np.empty(1, dtype=object) + expected[0] = myarr + assert_array_equal(res, expected) + + @pytest.mark.parametrize("protocol", + ["__array__", "__array_interface__", "__array_struct__"]) + def test_unnested_not_deprecated(self, protocol): + blueprint = np.arange(10) + MyArr = type("MyArr", (), {protocol: getattr(blueprint, protocol)}) + myarr = MyArr() + + self.assert_not_deprecated(lambda: np.array(myarr)) + res = np.array(myarr) + assert_array_equal(res, blueprint) + + @pytest.mark.parametrize("protocol", + ["__array__", "__array_interface__", "__array_struct__"]) + def test_strange_dtype_handling(self, protocol): + """The old code would actually use the dtype from the array, but + then end up not using the array (for dimension discovery) + """ + blueprint = np.arange(10).astype("f4") + MyArr = type("MyArr", (), {protocol: getattr(blueprint, protocol), + "__float__": lambda _: 0.5}) + myarr = MyArr() + + # Make sure we warn (and capture the FutureWarning) + with pytest.warns(FutureWarning, match=self.message): + res = np.array([[myarr]]) + + assert res.shape == (1, 1) + assert res.dtype == "f4" + assert res[0, 0] == 0.5 + + @pytest.mark.parametrize("protocol", + ["__array__", "__array_interface__", "__array_struct__"]) + def test_assignment_not_deprecated(self, protocol): + # If the result is dtype=object we do not unpack a nested array or + # array-like, if it is nested at exactly the right depth. + # NOTE: We actually do still call __array__, etc. but ignore the result + # in the end. For `dtype=object` we could optimize that away. + blueprint = np.arange(10).astype("f4") + MyArr = type("MyArr", (), {protocol: getattr(blueprint, protocol), + "__float__": lambda _: 0.5}) + myarr = MyArr() + + res = np.empty(3, dtype=object) + def set(): + res[:] = [myarr, myarr, myarr] + self.assert_not_deprecated(set) + assert res[0] is myarr + assert res[1] is myarr + assert res[2] is myarr + + +class TestDeprecatedUnpickleObjectScalar(_DeprecationTestCase): + # Deprecated 2020-11-24, NumPy 1.20 + """ + Technically, it should be impossible to create numpy object scalars, + but there was an unpickle path that would in theory allow it. That + path is invalid and must lead to the warning. + """ + message = "Unpickling a scalar with object dtype is deprecated." + + def test_deprecated(self): + ctor = np.core.multiarray.scalar + self.assert_deprecated(lambda: ctor(np.dtype("O"), 1)) diff --git a/venv/Lib/site-packages/numpy/core/tests/test_dtype.py b/venv/Lib/site-packages/numpy/core/tests/test_dtype.py new file mode 100644 index 0000000..c4f0267 --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/tests/test_dtype.py @@ -0,0 +1,1428 @@ +import sys +import operator +import pytest +import ctypes +import gc + +import numpy as np +from numpy.core._rational_tests import rational +from numpy.core._multiarray_tests import create_custom_field_dtype +from numpy.testing import ( + assert_, assert_equal, assert_array_equal, assert_raises, HAS_REFCOUNT) +from numpy.compat import pickle +from itertools import permutations + +def assert_dtype_equal(a, b): + assert_equal(a, b) + assert_equal(hash(a), hash(b), + "two equivalent types do not hash to the same value !") + +def assert_dtype_not_equal(a, b): + assert_(a != b) + assert_(hash(a) != hash(b), + "two different types hash to the same value !") + +class TestBuiltin: + @pytest.mark.parametrize('t', [int, float, complex, np.int32, str, object, + np.compat.unicode]) + def test_run(self, t): + """Only test hash runs at all.""" + dt = np.dtype(t) + hash(dt) + + @pytest.mark.parametrize('t', [int, float]) + def test_dtype(self, t): + # Make sure equivalent byte order char hash the same (e.g. < and = on + # little endian) + dt = np.dtype(t) + dt2 = dt.newbyteorder("<") + dt3 = dt.newbyteorder(">") + if dt == dt2: + assert_(dt.byteorder != dt2.byteorder, "bogus test") + assert_dtype_equal(dt, dt2) + else: + assert_(dt.byteorder != dt3.byteorder, "bogus test") + assert_dtype_equal(dt, dt3) + + def test_equivalent_dtype_hashing(self): + # Make sure equivalent dtypes with different type num hash equal + uintp = np.dtype(np.uintp) + if uintp.itemsize == 4: + left = uintp + right = np.dtype(np.uint32) + else: + left = uintp + right = np.dtype(np.ulonglong) + assert_(left == right) + assert_(hash(left) == hash(right)) + + def test_invalid_types(self): + # Make sure invalid type strings raise an error + + assert_raises(TypeError, np.dtype, 'O3') + assert_raises(TypeError, np.dtype, 'O5') + assert_raises(TypeError, np.dtype, 'O7') + assert_raises(TypeError, np.dtype, 'b3') + assert_raises(TypeError, np.dtype, 'h4') + assert_raises(TypeError, np.dtype, 'I5') + assert_raises(TypeError, np.dtype, 'e3') + assert_raises(TypeError, np.dtype, 'f5') + + if np.dtype('g').itemsize == 8 or np.dtype('g').itemsize == 16: + assert_raises(TypeError, np.dtype, 'g12') + elif np.dtype('g').itemsize == 12: + assert_raises(TypeError, np.dtype, 'g16') + + if np.dtype('l').itemsize == 8: + assert_raises(TypeError, np.dtype, 'l4') + assert_raises(TypeError, np.dtype, 'L4') + else: + assert_raises(TypeError, np.dtype, 'l8') + assert_raises(TypeError, np.dtype, 'L8') + + if np.dtype('q').itemsize == 8: + assert_raises(TypeError, np.dtype, 'q4') + assert_raises(TypeError, np.dtype, 'Q4') + else: + assert_raises(TypeError, np.dtype, 'q8') + assert_raises(TypeError, np.dtype, 'Q8') + + @pytest.mark.parametrize("dtype", + ['Bool', 'Complex32', 'Complex64', 'Float16', 'Float32', 'Float64', + 'Int8', 'Int16', 'Int32', 'Int64', 'Object0', 'Timedelta64', + 'UInt8', 'UInt16', 'UInt32', 'UInt64', 'Void0', + "Float128", "Complex128"]) + def test_numeric_style_types_are_invalid(self, dtype): + with assert_raises(TypeError): + np.dtype(dtype) + + @pytest.mark.parametrize( + 'value', + ['m8', 'M8', 'datetime64', 'timedelta64', + 'i4, (2,3)f8, f4', 'a3, 3u8, (3,4)a10', + '>f', 'f4', (64, 64)), (1,)), + ('rtile', '>f4', (64, 36))], (3,)), + ('bottom', [('bleft', ('>f4', (8, 64)), (1,)), + ('bright', '>f4', (8, 36))])]) + assert_equal(str(dt), + "[('top', [('tiles', ('>f4', (64, 64)), (1,)), " + "('rtile', '>f4', (64, 36))], (3,)), " + "('bottom', [('bleft', ('>f4', (8, 64)), (1,)), " + "('bright', '>f4', (8, 36))])]") + + # If the sticky aligned flag is set to True, it makes the + # str() function use a dict representation with an 'aligned' flag + dt = np.dtype([('top', [('tiles', ('>f4', (64, 64)), (1,)), + ('rtile', '>f4', (64, 36))], + (3,)), + ('bottom', [('bleft', ('>f4', (8, 64)), (1,)), + ('bright', '>f4', (8, 36))])], + align=True) + assert_equal(str(dt), + "{'names':['top','bottom'], " + "'formats':[([('tiles', ('>f4', (64, 64)), (1,)), " + "('rtile', '>f4', (64, 36))], (3,))," + "[('bleft', ('>f4', (8, 64)), (1,)), " + "('bright', '>f4', (8, 36))]], " + "'offsets':[0,76800], " + "'itemsize':80000, " + "'aligned':True}") + assert_equal(np.dtype(eval(str(dt))), dt) + + dt = np.dtype({'names': ['r', 'g', 'b'], 'formats': ['u1', 'u1', 'u1'], + 'offsets': [0, 1, 2], + 'titles': ['Red pixel', 'Green pixel', 'Blue pixel']}) + assert_equal(str(dt), + "[(('Red pixel', 'r'), 'u1'), " + "(('Green pixel', 'g'), 'u1'), " + "(('Blue pixel', 'b'), 'u1')]") + + dt = np.dtype({'names': ['rgba', 'r', 'g', 'b'], + 'formats': ['f4', (64, 64)), (1,)), + ('rtile', '>f4', (64, 36))], (3,)), + ('bottom', [('bleft', ('>f4', (8, 64)), (1,)), + ('bright', '>f4', (8, 36))])]) + assert_equal(repr(dt), + "dtype([('top', [('tiles', ('>f4', (64, 64)), (1,)), " + "('rtile', '>f4', (64, 36))], (3,)), " + "('bottom', [('bleft', ('>f4', (8, 64)), (1,)), " + "('bright', '>f4', (8, 36))])])") + + dt = np.dtype({'names': ['r', 'g', 'b'], 'formats': ['u1', 'u1', 'u1'], + 'offsets': [0, 1, 2], + 'titles': ['Red pixel', 'Green pixel', 'Blue pixel']}, + align=True) + assert_equal(repr(dt), + "dtype([(('Red pixel', 'r'), 'u1'), " + "(('Green pixel', 'g'), 'u1'), " + "(('Blue pixel', 'b'), 'u1')], align=True)") + + def test_repr_structured_not_packed(self): + dt = np.dtype({'names': ['rgba', 'r', 'g', 'b'], + 'formats': ['f4', (2, 1)), ('b', 'u4')]) + self.check(BigEndStruct, expected) + + def test_little_endian_structure_packed(self): + class LittleEndStruct(ctypes.LittleEndianStructure): + _fields_ = [ + ('one', ctypes.c_uint8), + ('two', ctypes.c_uint32) + ] + _pack_ = 1 + expected = np.dtype([('one', 'u1'), ('two', 'B'), + ('b', '>H') + ], align=True) + self.check(PaddedStruct, expected) + + def test_simple_endian_types(self): + self.check(ctypes.c_uint16.__ctype_le__, np.dtype('u2')) + self.check(ctypes.c_uint8.__ctype_le__, np.dtype('u1')) + self.check(ctypes.c_uint8.__ctype_be__, np.dtype('u1')) + + all_types = set(np.typecodes['All']) + all_pairs = permutations(all_types, 2) + + @pytest.mark.parametrize("pair", all_pairs) + def test_pairs(self, pair): + """ + Check that np.dtype('x,y') matches [np.dtype('x'), np.dtype('y')] + Example: np.dtype('d,I') -> dtype([('f0', '..j", [0, 0], optimize=do_opt) + assert_raises(ValueError, np.einsum, "j->.j...", [0, 0], optimize=do_opt) + + # invalid subscript character + assert_raises(ValueError, np.einsum, "i%...", [0, 0], optimize=do_opt) + assert_raises(ValueError, np.einsum, "...j$", [0, 0], optimize=do_opt) + assert_raises(ValueError, np.einsum, "i->&", [0, 0], optimize=do_opt) + + # output subscripts must appear in input + assert_raises(ValueError, np.einsum, "i->ij", [0, 0], optimize=do_opt) + + # output subscripts may only be specified once + assert_raises(ValueError, np.einsum, "ij->jij", [[0, 0], [0, 0]], + optimize=do_opt) + + # dimensions much match when being collapsed + assert_raises(ValueError, np.einsum, "ii", + np.arange(6).reshape(2, 3), optimize=do_opt) + assert_raises(ValueError, np.einsum, "ii->i", + np.arange(6).reshape(2, 3), optimize=do_opt) + + # broadcasting to new dimensions must be enabled explicitly + assert_raises(ValueError, np.einsum, "i", np.arange(6).reshape(2, 3), + optimize=do_opt) + assert_raises(ValueError, np.einsum, "i->i", [[0, 1], [0, 1]], + out=np.arange(4).reshape(2, 2), optimize=do_opt) + with assert_raises_regex(ValueError, "'b'"): + # gh-11221 - 'c' erroneously appeared in the error message + a = np.ones((3, 3, 4, 5, 6)) + b = np.ones((3, 4, 5)) + np.einsum('aabcb,abc', a, b) + + # Check order kwarg, asanyarray allows 1d to pass through + assert_raises(ValueError, np.einsum, "i->i", np.arange(6).reshape(-1, 1), + optimize=do_opt, order='d') + + def test_einsum_views(self): + # pass-through + for do_opt in [True, False]: + a = np.arange(6) + a.shape = (2, 3) + + b = np.einsum("...", a, optimize=do_opt) + assert_(b.base is a) + + b = np.einsum(a, [Ellipsis], optimize=do_opt) + assert_(b.base is a) + + b = np.einsum("ij", a, optimize=do_opt) + assert_(b.base is a) + assert_equal(b, a) + + b = np.einsum(a, [0, 1], optimize=do_opt) + assert_(b.base is a) + assert_equal(b, a) + + # output is writeable whenever input is writeable + b = np.einsum("...", a, optimize=do_opt) + assert_(b.flags['WRITEABLE']) + a.flags['WRITEABLE'] = False + b = np.einsum("...", a, optimize=do_opt) + assert_(not b.flags['WRITEABLE']) + + # transpose + a = np.arange(6) + a.shape = (2, 3) + + b = np.einsum("ji", a, optimize=do_opt) + assert_(b.base is a) + assert_equal(b, a.T) + + b = np.einsum(a, [1, 0], optimize=do_opt) + assert_(b.base is a) + assert_equal(b, a.T) + + # diagonal + a = np.arange(9) + a.shape = (3, 3) + + b = np.einsum("ii->i", a, optimize=do_opt) + assert_(b.base is a) + assert_equal(b, [a[i, i] for i in range(3)]) + + b = np.einsum(a, [0, 0], [0], optimize=do_opt) + assert_(b.base is a) + assert_equal(b, [a[i, i] for i in range(3)]) + + # diagonal with various ways of broadcasting an additional dimension + a = np.arange(27) + a.shape = (3, 3, 3) + + b = np.einsum("...ii->...i", a, optimize=do_opt) + assert_(b.base is a) + assert_equal(b, [[x[i, i] for i in range(3)] for x in a]) + + b = np.einsum(a, [Ellipsis, 0, 0], [Ellipsis, 0], optimize=do_opt) + assert_(b.base is a) + assert_equal(b, [[x[i, i] for i in range(3)] for x in a]) + + b = np.einsum("ii...->...i", a, optimize=do_opt) + assert_(b.base is a) + assert_equal(b, [[x[i, i] for i in range(3)] + for x in a.transpose(2, 0, 1)]) + + b = np.einsum(a, [0, 0, Ellipsis], [Ellipsis, 0], optimize=do_opt) + assert_(b.base is a) + assert_equal(b, [[x[i, i] for i in range(3)] + for x in a.transpose(2, 0, 1)]) + + b = np.einsum("...ii->i...", a, optimize=do_opt) + assert_(b.base is a) + assert_equal(b, [a[:, i, i] for i in range(3)]) + + b = np.einsum(a, [Ellipsis, 0, 0], [0, Ellipsis], optimize=do_opt) + assert_(b.base is a) + assert_equal(b, [a[:, i, i] for i in range(3)]) + + b = np.einsum("jii->ij", a, optimize=do_opt) + assert_(b.base is a) + assert_equal(b, [a[:, i, i] for i in range(3)]) + + b = np.einsum(a, [1, 0, 0], [0, 1], optimize=do_opt) + assert_(b.base is a) + assert_equal(b, [a[:, i, i] for i in range(3)]) + + b = np.einsum("ii...->i...", a, optimize=do_opt) + assert_(b.base is a) + assert_equal(b, [a.transpose(2, 0, 1)[:, i, i] for i in range(3)]) + + b = np.einsum(a, [0, 0, Ellipsis], [0, Ellipsis], optimize=do_opt) + assert_(b.base is a) + assert_equal(b, [a.transpose(2, 0, 1)[:, i, i] for i in range(3)]) + + b = np.einsum("i...i->i...", a, optimize=do_opt) + assert_(b.base is a) + assert_equal(b, [a.transpose(1, 0, 2)[:, i, i] for i in range(3)]) + + b = np.einsum(a, [0, Ellipsis, 0], [0, Ellipsis], optimize=do_opt) + assert_(b.base is a) + assert_equal(b, [a.transpose(1, 0, 2)[:, i, i] for i in range(3)]) + + b = np.einsum("i...i->...i", a, optimize=do_opt) + assert_(b.base is a) + assert_equal(b, [[x[i, i] for i in range(3)] + for x in a.transpose(1, 0, 2)]) + + b = np.einsum(a, [0, Ellipsis, 0], [Ellipsis, 0], optimize=do_opt) + assert_(b.base is a) + assert_equal(b, [[x[i, i] for i in range(3)] + for x in a.transpose(1, 0, 2)]) + + # triple diagonal + a = np.arange(27) + a.shape = (3, 3, 3) + + b = np.einsum("iii->i", a, optimize=do_opt) + assert_(b.base is a) + assert_equal(b, [a[i, i, i] for i in range(3)]) + + b = np.einsum(a, [0, 0, 0], [0], optimize=do_opt) + assert_(b.base is a) + assert_equal(b, [a[i, i, i] for i in range(3)]) + + # swap axes + a = np.arange(24) + a.shape = (2, 3, 4) + + b = np.einsum("ijk->jik", a, optimize=do_opt) + assert_(b.base is a) + assert_equal(b, a.swapaxes(0, 1)) + + b = np.einsum(a, [0, 1, 2], [1, 0, 2], optimize=do_opt) + assert_(b.base is a) + assert_equal(b, a.swapaxes(0, 1)) + + def check_einsum_sums(self, dtype, do_opt=False): + # Check various sums. Does many sizes to exercise unrolled loops. + + # sum(a, axis=-1) + for n in range(1, 17): + a = np.arange(n, dtype=dtype) + assert_equal(np.einsum("i->", a, optimize=do_opt), + np.sum(a, axis=-1).astype(dtype)) + assert_equal(np.einsum(a, [0], [], optimize=do_opt), + np.sum(a, axis=-1).astype(dtype)) + + for n in range(1, 17): + a = np.arange(2*3*n, dtype=dtype).reshape(2, 3, n) + assert_equal(np.einsum("...i->...", a, optimize=do_opt), + np.sum(a, axis=-1).astype(dtype)) + assert_equal(np.einsum(a, [Ellipsis, 0], [Ellipsis], optimize=do_opt), + np.sum(a, axis=-1).astype(dtype)) + + # sum(a, axis=0) + for n in range(1, 17): + a = np.arange(2*n, dtype=dtype).reshape(2, n) + assert_equal(np.einsum("i...->...", a, optimize=do_opt), + np.sum(a, axis=0).astype(dtype)) + assert_equal(np.einsum(a, [0, Ellipsis], [Ellipsis], optimize=do_opt), + np.sum(a, axis=0).astype(dtype)) + + for n in range(1, 17): + a = np.arange(2*3*n, dtype=dtype).reshape(2, 3, n) + assert_equal(np.einsum("i...->...", a, optimize=do_opt), + np.sum(a, axis=0).astype(dtype)) + assert_equal(np.einsum(a, [0, Ellipsis], [Ellipsis], optimize=do_opt), + np.sum(a, axis=0).astype(dtype)) + + # trace(a) + for n in range(1, 17): + a = np.arange(n*n, dtype=dtype).reshape(n, n) + assert_equal(np.einsum("ii", a, optimize=do_opt), + np.trace(a).astype(dtype)) + assert_equal(np.einsum(a, [0, 0], optimize=do_opt), + np.trace(a).astype(dtype)) + + # gh-15961: should accept numpy int64 type in subscript list + np_array = np.asarray([0, 0]) + assert_equal(np.einsum(a, np_array, optimize=do_opt), + np.trace(a).astype(dtype)) + assert_equal(np.einsum(a, list(np_array), optimize=do_opt), + np.trace(a).astype(dtype)) + + # multiply(a, b) + assert_equal(np.einsum("..., ...", 3, 4), 12) # scalar case + for n in range(1, 17): + a = np.arange(3 * n, dtype=dtype).reshape(3, n) + b = np.arange(2 * 3 * n, dtype=dtype).reshape(2, 3, n) + assert_equal(np.einsum("..., ...", a, b, optimize=do_opt), + np.multiply(a, b)) + assert_equal(np.einsum(a, [Ellipsis], b, [Ellipsis], optimize=do_opt), + np.multiply(a, b)) + + # inner(a,b) + for n in range(1, 17): + a = np.arange(2 * 3 * n, dtype=dtype).reshape(2, 3, n) + b = np.arange(n, dtype=dtype) + assert_equal(np.einsum("...i, ...i", a, b, optimize=do_opt), np.inner(a, b)) + assert_equal(np.einsum(a, [Ellipsis, 0], b, [Ellipsis, 0], optimize=do_opt), + np.inner(a, b)) + + for n in range(1, 11): + a = np.arange(n * 3 * 2, dtype=dtype).reshape(n, 3, 2) + b = np.arange(n, dtype=dtype) + assert_equal(np.einsum("i..., i...", a, b, optimize=do_opt), + np.inner(a.T, b.T).T) + assert_equal(np.einsum(a, [0, Ellipsis], b, [0, Ellipsis], optimize=do_opt), + np.inner(a.T, b.T).T) + + # outer(a,b) + for n in range(1, 17): + a = np.arange(3, dtype=dtype)+1 + b = np.arange(n, dtype=dtype)+1 + assert_equal(np.einsum("i,j", a, b, optimize=do_opt), + np.outer(a, b)) + assert_equal(np.einsum(a, [0], b, [1], optimize=do_opt), + np.outer(a, b)) + + # Suppress the complex warnings for the 'as f8' tests + with suppress_warnings() as sup: + sup.filter(np.ComplexWarning) + + # matvec(a,b) / a.dot(b) where a is matrix, b is vector + for n in range(1, 17): + a = np.arange(4*n, dtype=dtype).reshape(4, n) + b = np.arange(n, dtype=dtype) + assert_equal(np.einsum("ij, j", a, b, optimize=do_opt), + np.dot(a, b)) + assert_equal(np.einsum(a, [0, 1], b, [1], optimize=do_opt), + np.dot(a, b)) + + c = np.arange(4, dtype=dtype) + np.einsum("ij,j", a, b, out=c, + dtype='f8', casting='unsafe', optimize=do_opt) + assert_equal(c, + np.dot(a.astype('f8'), + b.astype('f8')).astype(dtype)) + c[...] = 0 + np.einsum(a, [0, 1], b, [1], out=c, + dtype='f8', casting='unsafe', optimize=do_opt) + assert_equal(c, + np.dot(a.astype('f8'), + b.astype('f8')).astype(dtype)) + + for n in range(1, 17): + a = np.arange(4*n, dtype=dtype).reshape(4, n) + b = np.arange(n, dtype=dtype) + assert_equal(np.einsum("ji,j", a.T, b.T, optimize=do_opt), + np.dot(b.T, a.T)) + assert_equal(np.einsum(a.T, [1, 0], b.T, [1], optimize=do_opt), + np.dot(b.T, a.T)) + + c = np.arange(4, dtype=dtype) + np.einsum("ji,j", a.T, b.T, out=c, + dtype='f8', casting='unsafe', optimize=do_opt) + assert_equal(c, + np.dot(b.T.astype('f8'), + a.T.astype('f8')).astype(dtype)) + c[...] = 0 + np.einsum(a.T, [1, 0], b.T, [1], out=c, + dtype='f8', casting='unsafe', optimize=do_opt) + assert_equal(c, + np.dot(b.T.astype('f8'), + a.T.astype('f8')).astype(dtype)) + + # matmat(a,b) / a.dot(b) where a is matrix, b is matrix + for n in range(1, 17): + if n < 8 or dtype != 'f2': + a = np.arange(4*n, dtype=dtype).reshape(4, n) + b = np.arange(n*6, dtype=dtype).reshape(n, 6) + assert_equal(np.einsum("ij,jk", a, b, optimize=do_opt), + np.dot(a, b)) + assert_equal(np.einsum(a, [0, 1], b, [1, 2], optimize=do_opt), + np.dot(a, b)) + + for n in range(1, 17): + a = np.arange(4*n, dtype=dtype).reshape(4, n) + b = np.arange(n*6, dtype=dtype).reshape(n, 6) + c = np.arange(24, dtype=dtype).reshape(4, 6) + np.einsum("ij,jk", a, b, out=c, dtype='f8', casting='unsafe', + optimize=do_opt) + assert_equal(c, + np.dot(a.astype('f8'), + b.astype('f8')).astype(dtype)) + c[...] = 0 + np.einsum(a, [0, 1], b, [1, 2], out=c, + dtype='f8', casting='unsafe', optimize=do_opt) + assert_equal(c, + np.dot(a.astype('f8'), + b.astype('f8')).astype(dtype)) + + # matrix triple product (note this is not currently an efficient + # way to multiply 3 matrices) + a = np.arange(12, dtype=dtype).reshape(3, 4) + b = np.arange(20, dtype=dtype).reshape(4, 5) + c = np.arange(30, dtype=dtype).reshape(5, 6) + if dtype != 'f2': + assert_equal(np.einsum("ij,jk,kl", a, b, c, optimize=do_opt), + a.dot(b).dot(c)) + assert_equal(np.einsum(a, [0, 1], b, [1, 2], c, [2, 3], + optimize=do_opt), a.dot(b).dot(c)) + + d = np.arange(18, dtype=dtype).reshape(3, 6) + np.einsum("ij,jk,kl", a, b, c, out=d, + dtype='f8', casting='unsafe', optimize=do_opt) + tgt = a.astype('f8').dot(b.astype('f8')) + tgt = tgt.dot(c.astype('f8')).astype(dtype) + assert_equal(d, tgt) + + d[...] = 0 + np.einsum(a, [0, 1], b, [1, 2], c, [2, 3], out=d, + dtype='f8', casting='unsafe', optimize=do_opt) + tgt = a.astype('f8').dot(b.astype('f8')) + tgt = tgt.dot(c.astype('f8')).astype(dtype) + assert_equal(d, tgt) + + # tensordot(a, b) + if np.dtype(dtype) != np.dtype('f2'): + a = np.arange(60, dtype=dtype).reshape(3, 4, 5) + b = np.arange(24, dtype=dtype).reshape(4, 3, 2) + assert_equal(np.einsum("ijk, jil -> kl", a, b), + np.tensordot(a, b, axes=([1, 0], [0, 1]))) + assert_equal(np.einsum(a, [0, 1, 2], b, [1, 0, 3], [2, 3]), + np.tensordot(a, b, axes=([1, 0], [0, 1]))) + + c = np.arange(10, dtype=dtype).reshape(5, 2) + np.einsum("ijk,jil->kl", a, b, out=c, + dtype='f8', casting='unsafe', optimize=do_opt) + assert_equal(c, np.tensordot(a.astype('f8'), b.astype('f8'), + axes=([1, 0], [0, 1])).astype(dtype)) + c[...] = 0 + np.einsum(a, [0, 1, 2], b, [1, 0, 3], [2, 3], out=c, + dtype='f8', casting='unsafe', optimize=do_opt) + assert_equal(c, np.tensordot(a.astype('f8'), b.astype('f8'), + axes=([1, 0], [0, 1])).astype(dtype)) + + # logical_and(logical_and(a!=0, b!=0), c!=0) + a = np.array([1, 3, -2, 0, 12, 13, 0, 1], dtype=dtype) + b = np.array([0, 3.5, 0., -2, 0, 1, 3, 12], dtype=dtype) + c = np.array([True, True, False, True, True, False, True, True]) + assert_equal(np.einsum("i,i,i->i", a, b, c, + dtype='?', casting='unsafe', optimize=do_opt), + np.logical_and(np.logical_and(a != 0, b != 0), c != 0)) + assert_equal(np.einsum(a, [0], b, [0], c, [0], [0], + dtype='?', casting='unsafe'), + np.logical_and(np.logical_and(a != 0, b != 0), c != 0)) + + a = np.arange(9, dtype=dtype) + assert_equal(np.einsum(",i->", 3, a), 3*np.sum(a)) + assert_equal(np.einsum(3, [], a, [0], []), 3*np.sum(a)) + assert_equal(np.einsum("i,->", a, 3), 3*np.sum(a)) + assert_equal(np.einsum(a, [0], 3, [], []), 3*np.sum(a)) + + # Various stride0, contiguous, and SSE aligned variants + for n in range(1, 25): + a = np.arange(n, dtype=dtype) + if np.dtype(dtype).itemsize > 1: + assert_equal(np.einsum("...,...", a, a, optimize=do_opt), + np.multiply(a, a)) + assert_equal(np.einsum("i,i", a, a, optimize=do_opt), np.dot(a, a)) + assert_equal(np.einsum("i,->i", a, 2, optimize=do_opt), 2*a) + assert_equal(np.einsum(",i->i", 2, a, optimize=do_opt), 2*a) + assert_equal(np.einsum("i,->", a, 2, optimize=do_opt), 2*np.sum(a)) + assert_equal(np.einsum(",i->", 2, a, optimize=do_opt), 2*np.sum(a)) + + assert_equal(np.einsum("...,...", a[1:], a[:-1], optimize=do_opt), + np.multiply(a[1:], a[:-1])) + assert_equal(np.einsum("i,i", a[1:], a[:-1], optimize=do_opt), + np.dot(a[1:], a[:-1])) + assert_equal(np.einsum("i,->i", a[1:], 2, optimize=do_opt), 2*a[1:]) + assert_equal(np.einsum(",i->i", 2, a[1:], optimize=do_opt), 2*a[1:]) + assert_equal(np.einsum("i,->", a[1:], 2, optimize=do_opt), + 2*np.sum(a[1:])) + assert_equal(np.einsum(",i->", 2, a[1:], optimize=do_opt), + 2*np.sum(a[1:])) + + # An object array, summed as the data type + a = np.arange(9, dtype=object) + + b = np.einsum("i->", a, dtype=dtype, casting='unsafe') + assert_equal(b, np.sum(a)) + assert_equal(b.dtype, np.dtype(dtype)) + + b = np.einsum(a, [0], [], dtype=dtype, casting='unsafe') + assert_equal(b, np.sum(a)) + assert_equal(b.dtype, np.dtype(dtype)) + + # A case which was failing (ticket #1885) + p = np.arange(2) + 1 + q = np.arange(4).reshape(2, 2) + 3 + r = np.arange(4).reshape(2, 2) + 7 + assert_equal(np.einsum('z,mz,zm->', p, q, r), 253) + + # singleton dimensions broadcast (gh-10343) + p = np.ones((10,2)) + q = np.ones((1,2)) + assert_array_equal(np.einsum('ij,ij->j', p, q, optimize=True), + np.einsum('ij,ij->j', p, q, optimize=False)) + assert_array_equal(np.einsum('ij,ij->j', p, q, optimize=True), + [10.] * 2) + + # a blas-compatible contraction broadcasting case which was failing + # for optimize=True (ticket #10930) + x = np.array([2., 3.]) + y = np.array([4.]) + assert_array_equal(np.einsum("i, i", x, y, optimize=False), 20.) + assert_array_equal(np.einsum("i, i", x, y, optimize=True), 20.) + + # all-ones array was bypassing bug (ticket #10930) + p = np.ones((1, 5)) / 2 + q = np.ones((5, 5)) / 2 + for optimize in (True, False): + assert_array_equal(np.einsum("...ij,...jk->...ik", p, p, + optimize=optimize), + np.einsum("...ij,...jk->...ik", p, q, + optimize=optimize)) + assert_array_equal(np.einsum("...ij,...jk->...ik", p, q, + optimize=optimize), + np.full((1, 5), 1.25)) + + # Cases which were failing (gh-10899) + x = np.eye(2, dtype=dtype) + y = np.ones(2, dtype=dtype) + assert_array_equal(np.einsum("ji,i->", x, y, optimize=optimize), + [2.]) # contig_contig_outstride0_two + assert_array_equal(np.einsum("i,ij->", y, x, optimize=optimize), + [2.]) # stride0_contig_outstride0_two + assert_array_equal(np.einsum("ij,i->", x, y, optimize=optimize), + [2.]) # contig_stride0_outstride0_two + + def test_einsum_sums_int8(self): + self.check_einsum_sums('i1') + + def test_einsum_sums_uint8(self): + self.check_einsum_sums('u1') + + def test_einsum_sums_int16(self): + self.check_einsum_sums('i2') + + def test_einsum_sums_uint16(self): + self.check_einsum_sums('u2') + + def test_einsum_sums_int32(self): + self.check_einsum_sums('i4') + self.check_einsum_sums('i4', True) + + def test_einsum_sums_uint32(self): + self.check_einsum_sums('u4') + self.check_einsum_sums('u4', True) + + def test_einsum_sums_int64(self): + self.check_einsum_sums('i8') + + def test_einsum_sums_uint64(self): + self.check_einsum_sums('u8') + + def test_einsum_sums_float16(self): + self.check_einsum_sums('f2') + + def test_einsum_sums_float32(self): + self.check_einsum_sums('f4') + + def test_einsum_sums_float64(self): + self.check_einsum_sums('f8') + self.check_einsum_sums('f8', True) + + def test_einsum_sums_longdouble(self): + self.check_einsum_sums(np.longdouble) + + def test_einsum_sums_cfloat64(self): + self.check_einsum_sums('c8') + self.check_einsum_sums('c8', True) + + def test_einsum_sums_cfloat128(self): + self.check_einsum_sums('c16') + + def test_einsum_sums_clongdouble(self): + self.check_einsum_sums(np.clongdouble) + + def test_einsum_misc(self): + # This call used to crash because of a bug in + # PyArray_AssignZero + a = np.ones((1, 2)) + b = np.ones((2, 2, 1)) + assert_equal(np.einsum('ij...,j...->i...', a, b), [[[2], [2]]]) + assert_equal(np.einsum('ij...,j...->i...', a, b, optimize=True), [[[2], [2]]]) + + # Regression test for issue #10369 (test unicode inputs with Python 2) + assert_equal(np.einsum(u'ij...,j...->i...', a, b), [[[2], [2]]]) + assert_equal(np.einsum('...i,...i', [1, 2, 3], [2, 3, 4]), 20) + assert_equal(np.einsum(u'...i,...i', [1, 2, 3], [2, 3, 4]), 20) + assert_equal(np.einsum('...i,...i', [1, 2, 3], [2, 3, 4], + optimize=u'greedy'), 20) + + # The iterator had an issue with buffering this reduction + a = np.ones((5, 12, 4, 2, 3), np.int64) + b = np.ones((5, 12, 11), np.int64) + assert_equal(np.einsum('ijklm,ijn,ijn->', a, b, b), + np.einsum('ijklm,ijn->', a, b)) + assert_equal(np.einsum('ijklm,ijn,ijn->', a, b, b, optimize=True), + np.einsum('ijklm,ijn->', a, b, optimize=True)) + + # Issue #2027, was a problem in the contiguous 3-argument + # inner loop implementation + a = np.arange(1, 3) + b = np.arange(1, 5).reshape(2, 2) + c = np.arange(1, 9).reshape(4, 2) + assert_equal(np.einsum('x,yx,zx->xzy', a, b, c), + [[[1, 3], [3, 9], [5, 15], [7, 21]], + [[8, 16], [16, 32], [24, 48], [32, 64]]]) + assert_equal(np.einsum('x,yx,zx->xzy', a, b, c, optimize=True), + [[[1, 3], [3, 9], [5, 15], [7, 21]], + [[8, 16], [16, 32], [24, 48], [32, 64]]]) + + # Ensure explicitly setting out=None does not cause an error + # see issue gh-15776 and issue gh-15256 + assert_equal(np.einsum('i,j', [1], [2], out=None), [[2]]) + + def test_subscript_range(self): + # Issue #7741, make sure that all letters of Latin alphabet (both uppercase & lowercase) can be used + # when creating a subscript from arrays + a = np.ones((2, 3)) + b = np.ones((3, 4)) + np.einsum(a, [0, 20], b, [20, 2], [0, 2], optimize=False) + np.einsum(a, [0, 27], b, [27, 2], [0, 2], optimize=False) + np.einsum(a, [0, 51], b, [51, 2], [0, 2], optimize=False) + assert_raises(ValueError, lambda: np.einsum(a, [0, 52], b, [52, 2], [0, 2], optimize=False)) + assert_raises(ValueError, lambda: np.einsum(a, [-1, 5], b, [5, 2], [-1, 2], optimize=False)) + + def test_einsum_broadcast(self): + # Issue #2455 change in handling ellipsis + # remove the 'middle broadcast' error + # only use the 'RIGHT' iteration in prepare_op_axes + # adds auto broadcast on left where it belongs + # broadcast on right has to be explicit + # We need to test the optimized parsing as well + + A = np.arange(2 * 3 * 4).reshape(2, 3, 4) + B = np.arange(3) + ref = np.einsum('ijk,j->ijk', A, B, optimize=False) + for opt in [True, False]: + assert_equal(np.einsum('ij...,j...->ij...', A, B, optimize=opt), ref) + assert_equal(np.einsum('ij...,...j->ij...', A, B, optimize=opt), ref) + assert_equal(np.einsum('ij...,j->ij...', A, B, optimize=opt), ref) # used to raise error + + A = np.arange(12).reshape((4, 3)) + B = np.arange(6).reshape((3, 2)) + ref = np.einsum('ik,kj->ij', A, B, optimize=False) + for opt in [True, False]: + assert_equal(np.einsum('ik...,k...->i...', A, B, optimize=opt), ref) + assert_equal(np.einsum('ik...,...kj->i...j', A, B, optimize=opt), ref) + assert_equal(np.einsum('...k,kj', A, B, optimize=opt), ref) # used to raise error + assert_equal(np.einsum('ik,k...->i...', A, B, optimize=opt), ref) # used to raise error + + dims = [2, 3, 4, 5] + a = np.arange(np.prod(dims)).reshape(dims) + v = np.arange(dims[2]) + ref = np.einsum('ijkl,k->ijl', a, v, optimize=False) + for opt in [True, False]: + assert_equal(np.einsum('ijkl,k', a, v, optimize=opt), ref) + assert_equal(np.einsum('...kl,k', a, v, optimize=opt), ref) # used to raise error + assert_equal(np.einsum('...kl,k...', a, v, optimize=opt), ref) + + J, K, M = 160, 160, 120 + A = np.arange(J * K * M).reshape(1, 1, 1, J, K, M) + B = np.arange(J * K * M * 3).reshape(J, K, M, 3) + ref = np.einsum('...lmn,...lmno->...o', A, B, optimize=False) + for opt in [True, False]: + assert_equal(np.einsum('...lmn,lmno->...o', A, B, + optimize=opt), ref) # used to raise error + + def test_einsum_fixedstridebug(self): + # Issue #4485 obscure einsum bug + # This case revealed a bug in nditer where it reported a stride + # as 'fixed' (0) when it was in fact not fixed during processing + # (0 or 4). The reason for the bug was that the check for a fixed + # stride was using the information from the 2D inner loop reuse + # to restrict the iteration dimensions it had to validate to be + # the same, but that 2D inner loop reuse logic is only triggered + # during the buffer copying step, and hence it was invalid to + # rely on those values. The fix is to check all the dimensions + # of the stride in question, which in the test case reveals that + # the stride is not fixed. + # + # NOTE: This test is triggered by the fact that the default buffersize, + # used by einsum, is 8192, and 3*2731 = 8193, is larger than that + # and results in a mismatch between the buffering and the + # striding for operand A. + A = np.arange(2 * 3).reshape(2, 3).astype(np.float32) + B = np.arange(2 * 3 * 2731).reshape(2, 3, 2731).astype(np.int16) + es = np.einsum('cl, cpx->lpx', A, B) + tp = np.tensordot(A, B, axes=(0, 0)) + assert_equal(es, tp) + # The following is the original test case from the bug report, + # made repeatable by changing random arrays to aranges. + A = np.arange(3 * 3).reshape(3, 3).astype(np.float64) + B = np.arange(3 * 3 * 64 * 64).reshape(3, 3, 64, 64).astype(np.float32) + es = np.einsum('cl, cpxy->lpxy', A, B) + tp = np.tensordot(A, B, axes=(0, 0)) + assert_equal(es, tp) + + def test_einsum_fixed_collapsingbug(self): + # Issue #5147. + # The bug only occurred when output argument of einssum was used. + x = np.random.normal(0, 1, (5, 5, 5, 5)) + y1 = np.zeros((5, 5)) + np.einsum('aabb->ab', x, out=y1) + idx = np.arange(5) + y2 = x[idx[:, None], idx[:, None], idx, idx] + assert_equal(y1, y2) + + def test_einsum_failed_on_p9_and_s390x(self): + # Issues gh-14692 and gh-12689 + # Bug with signed vs unsigned char errored on power9 and s390x Linux + tensor = np.random.random_sample((10, 10, 10, 10)) + x = np.einsum('ijij->', tensor) + y = tensor.trace(axis1=0, axis2=2).trace() + assert_allclose(x, y) + + def test_einsum_all_contig_non_contig_output(self): + # Issue gh-5907, tests that the all contiguous special case + # actually checks the contiguity of the output + x = np.ones((5, 5)) + out = np.ones(10)[::2] + correct_base = np.ones(10) + correct_base[::2] = 5 + # Always worked (inner iteration is done with 0-stride): + np.einsum('mi,mi,mi->m', x, x, x, out=out) + assert_array_equal(out.base, correct_base) + # Example 1: + out = np.ones(10)[::2] + np.einsum('im,im,im->m', x, x, x, out=out) + assert_array_equal(out.base, correct_base) + # Example 2, buffering causes x to be contiguous but + # special cases do not catch the operation before: + out = np.ones((2, 2, 2))[..., 0] + correct_base = np.ones((2, 2, 2)) + correct_base[..., 0] = 2 + x = np.ones((2, 2), np.float32) + np.einsum('ij,jk->ik', x, x, out=out) + assert_array_equal(out.base, correct_base) + + def test_small_boolean_arrays(self): + # See gh-5946. + # Use array of True embedded in False. + a = np.zeros((16, 1, 1), dtype=np.bool_)[:2] + a[...] = True + out = np.zeros((16, 1, 1), dtype=np.bool_)[:2] + tgt = np.ones((2, 1, 1), dtype=np.bool_) + res = np.einsum('...ij,...jk->...ik', a, a, out=out) + assert_equal(res, tgt) + + def test_out_is_res(self): + a = np.arange(9).reshape(3, 3) + res = np.einsum('...ij,...jk->...ik', a, a, out=a) + assert res is a + + def optimize_compare(self, subscripts, operands=None): + # Tests all paths of the optimization function against + # conventional einsum + if operands is None: + args = [subscripts] + terms = subscripts.split('->')[0].split(',') + for term in terms: + dims = [global_size_dict[x] for x in term] + args.append(np.random.rand(*dims)) + else: + args = [subscripts] + operands + + noopt = np.einsum(*args, optimize=False) + opt = np.einsum(*args, optimize='greedy') + assert_almost_equal(opt, noopt) + opt = np.einsum(*args, optimize='optimal') + assert_almost_equal(opt, noopt) + + def test_hadamard_like_products(self): + # Hadamard outer products + self.optimize_compare('a,ab,abc->abc') + self.optimize_compare('a,b,ab->ab') + + def test_index_transformations(self): + # Simple index transformation cases + self.optimize_compare('ea,fb,gc,hd,abcd->efgh') + self.optimize_compare('ea,fb,abcd,gc,hd->efgh') + self.optimize_compare('abcd,ea,fb,gc,hd->efgh') + + def test_complex(self): + # Long test cases + self.optimize_compare('acdf,jbje,gihb,hfac,gfac,gifabc,hfac') + self.optimize_compare('acdf,jbje,gihb,hfac,gfac,gifabc,hfac') + self.optimize_compare('cd,bdhe,aidb,hgca,gc,hgibcd,hgac') + self.optimize_compare('abhe,hidj,jgba,hiab,gab') + self.optimize_compare('bde,cdh,agdb,hica,ibd,hgicd,hiac') + self.optimize_compare('chd,bde,agbc,hiad,hgc,hgi,hiad') + self.optimize_compare('chd,bde,agbc,hiad,bdi,cgh,agdb') + self.optimize_compare('bdhe,acad,hiab,agac,hibd') + + def test_collapse(self): + # Inner products + self.optimize_compare('ab,ab,c->') + self.optimize_compare('ab,ab,c->c') + self.optimize_compare('ab,ab,cd,cd->') + self.optimize_compare('ab,ab,cd,cd->ac') + self.optimize_compare('ab,ab,cd,cd->cd') + self.optimize_compare('ab,ab,cd,cd,ef,ef->') + + def test_expand(self): + # Outer products + self.optimize_compare('ab,cd,ef->abcdef') + self.optimize_compare('ab,cd,ef->acdf') + self.optimize_compare('ab,cd,de->abcde') + self.optimize_compare('ab,cd,de->be') + self.optimize_compare('ab,bcd,cd->abcd') + self.optimize_compare('ab,bcd,cd->abd') + + def test_edge_cases(self): + # Difficult edge cases for optimization + self.optimize_compare('eb,cb,fb->cef') + self.optimize_compare('dd,fb,be,cdb->cef') + self.optimize_compare('bca,cdb,dbf,afc->') + self.optimize_compare('dcc,fce,ea,dbf->ab') + self.optimize_compare('fdf,cdd,ccd,afe->ae') + self.optimize_compare('abcd,ad') + self.optimize_compare('ed,fcd,ff,bcf->be') + self.optimize_compare('baa,dcf,af,cde->be') + self.optimize_compare('bd,db,eac->ace') + self.optimize_compare('fff,fae,bef,def->abd') + self.optimize_compare('efc,dbc,acf,fd->abe') + self.optimize_compare('ba,ac,da->bcd') + + def test_inner_product(self): + # Inner products + self.optimize_compare('ab,ab') + self.optimize_compare('ab,ba') + self.optimize_compare('abc,abc') + self.optimize_compare('abc,bac') + self.optimize_compare('abc,cba') + + def test_random_cases(self): + # Randomly built test cases + self.optimize_compare('aab,fa,df,ecc->bde') + self.optimize_compare('ecb,fef,bad,ed->ac') + self.optimize_compare('bcf,bbb,fbf,fc->') + self.optimize_compare('bb,ff,be->e') + self.optimize_compare('bcb,bb,fc,fff->') + self.optimize_compare('fbb,dfd,fc,fc->') + self.optimize_compare('afd,ba,cc,dc->bf') + self.optimize_compare('adb,bc,fa,cfc->d') + self.optimize_compare('bbd,bda,fc,db->acf') + self.optimize_compare('dba,ead,cad->bce') + self.optimize_compare('aef,fbc,dca->bde') + + def test_combined_views_mapping(self): + # gh-10792 + a = np.arange(9).reshape(1, 1, 3, 1, 3) + b = np.einsum('bbcdc->d', a) + assert_equal(b, [12]) + + def test_broadcasting_dot_cases(self): + # Ensures broadcasting cases are not mistaken for GEMM + + a = np.random.rand(1, 5, 4) + b = np.random.rand(4, 6) + c = np.random.rand(5, 6) + d = np.random.rand(10) + + self.optimize_compare('ijk,kl,jl', operands=[a, b, c]) + self.optimize_compare('ijk,kl,jl,i->i', operands=[a, b, c, d]) + + e = np.random.rand(1, 1, 5, 4) + f = np.random.rand(7, 7) + self.optimize_compare('abjk,kl,jl', operands=[e, b, c]) + self.optimize_compare('abjk,kl,jl,ab->ab', operands=[e, b, c, f]) + + # Edge case found in gh-11308 + g = np.arange(64).reshape(2, 4, 8) + self.optimize_compare('obk,ijk->ioj', operands=[g, g]) + + def test_output_order(self): + # Ensure output order is respected for optimize cases, the below + # conraction should yield a reshaped tensor view + # gh-16415 + + a = np.ones((2, 3, 5), order='F') + b = np.ones((4, 3), order='F') + + for opt in [True, False]: + tmp = np.einsum('...ft,mf->...mt', a, b, order='a', optimize=opt) + assert_(tmp.flags.f_contiguous) + + tmp = np.einsum('...ft,mf->...mt', a, b, order='f', optimize=opt) + assert_(tmp.flags.f_contiguous) + + tmp = np.einsum('...ft,mf->...mt', a, b, order='c', optimize=opt) + assert_(tmp.flags.c_contiguous) + + tmp = np.einsum('...ft,mf->...mt', a, b, order='k', optimize=opt) + assert_(tmp.flags.c_contiguous is False) + assert_(tmp.flags.f_contiguous is False) + + tmp = np.einsum('...ft,mf->...mt', a, b, optimize=opt) + assert_(tmp.flags.c_contiguous is False) + assert_(tmp.flags.f_contiguous is False) + + c = np.ones((4, 3), order='C') + for opt in [True, False]: + tmp = np.einsum('...ft,mf->...mt', a, c, order='a', optimize=opt) + assert_(tmp.flags.c_contiguous) + + d = np.ones((2, 3, 5), order='C') + for opt in [True, False]: + tmp = np.einsum('...ft,mf->...mt', d, c, order='a', optimize=opt) + assert_(tmp.flags.c_contiguous) + +class TestEinsumPath: + def build_operands(self, string, size_dict=global_size_dict): + + # Builds views based off initial operands + operands = [string] + terms = string.split('->')[0].split(',') + for term in terms: + dims = [size_dict[x] for x in term] + operands.append(np.random.rand(*dims)) + + return operands + + def assert_path_equal(self, comp, benchmark): + # Checks if list of tuples are equivalent + ret = (len(comp) == len(benchmark)) + assert_(ret) + for pos in range(len(comp) - 1): + ret &= isinstance(comp[pos + 1], tuple) + ret &= (comp[pos + 1] == benchmark[pos + 1]) + assert_(ret) + + def test_memory_contraints(self): + # Ensure memory constraints are satisfied + + outer_test = self.build_operands('a,b,c->abc') + + path, path_str = np.einsum_path(*outer_test, optimize=('greedy', 0)) + self.assert_path_equal(path, ['einsum_path', (0, 1, 2)]) + + path, path_str = np.einsum_path(*outer_test, optimize=('optimal', 0)) + self.assert_path_equal(path, ['einsum_path', (0, 1, 2)]) + + long_test = self.build_operands('acdf,jbje,gihb,hfac') + path, path_str = np.einsum_path(*long_test, optimize=('greedy', 0)) + self.assert_path_equal(path, ['einsum_path', (0, 1, 2, 3)]) + + path, path_str = np.einsum_path(*long_test, optimize=('optimal', 0)) + self.assert_path_equal(path, ['einsum_path', (0, 1, 2, 3)]) + + def test_long_paths(self): + # Long complex cases + + # Long test 1 + long_test1 = self.build_operands('acdf,jbje,gihb,hfac,gfac,gifabc,hfac') + path, path_str = np.einsum_path(*long_test1, optimize='greedy') + self.assert_path_equal(path, ['einsum_path', + (3, 6), (3, 4), (2, 4), (2, 3), (0, 2), (0, 1)]) + + path, path_str = np.einsum_path(*long_test1, optimize='optimal') + self.assert_path_equal(path, ['einsum_path', + (3, 6), (3, 4), (2, 4), (2, 3), (0, 2), (0, 1)]) + + # Long test 2 + long_test2 = self.build_operands('chd,bde,agbc,hiad,bdi,cgh,agdb') + path, path_str = np.einsum_path(*long_test2, optimize='greedy') + print(path) + self.assert_path_equal(path, ['einsum_path', + (3, 4), (0, 3), (3, 4), (1, 3), (1, 2), (0, 1)]) + + path, path_str = np.einsum_path(*long_test2, optimize='optimal') + print(path) + self.assert_path_equal(path, ['einsum_path', + (0, 5), (1, 4), (3, 4), (1, 3), (1, 2), (0, 1)]) + + def test_edge_paths(self): + # Difficult edge cases + + # Edge test1 + edge_test1 = self.build_operands('eb,cb,fb->cef') + path, path_str = np.einsum_path(*edge_test1, optimize='greedy') + self.assert_path_equal(path, ['einsum_path', (0, 2), (0, 1)]) + + path, path_str = np.einsum_path(*edge_test1, optimize='optimal') + self.assert_path_equal(path, ['einsum_path', (0, 2), (0, 1)]) + + # Edge test2 + edge_test2 = self.build_operands('dd,fb,be,cdb->cef') + path, path_str = np.einsum_path(*edge_test2, optimize='greedy') + self.assert_path_equal(path, ['einsum_path', (0, 3), (0, 1), (0, 1)]) + + path, path_str = np.einsum_path(*edge_test2, optimize='optimal') + self.assert_path_equal(path, ['einsum_path', (0, 3), (0, 1), (0, 1)]) + + # Edge test3 + edge_test3 = self.build_operands('bca,cdb,dbf,afc->') + path, path_str = np.einsum_path(*edge_test3, optimize='greedy') + self.assert_path_equal(path, ['einsum_path', (1, 2), (0, 2), (0, 1)]) + + path, path_str = np.einsum_path(*edge_test3, optimize='optimal') + self.assert_path_equal(path, ['einsum_path', (1, 2), (0, 2), (0, 1)]) + + # Edge test4 + edge_test4 = self.build_operands('dcc,fce,ea,dbf->ab') + path, path_str = np.einsum_path(*edge_test4, optimize='greedy') + self.assert_path_equal(path, ['einsum_path', (1, 2), (0, 1), (0, 1)]) + + path, path_str = np.einsum_path(*edge_test4, optimize='optimal') + self.assert_path_equal(path, ['einsum_path', (1, 2), (0, 2), (0, 1)]) + + # Edge test5 + edge_test4 = self.build_operands('a,ac,ab,ad,cd,bd,bc->', + size_dict={"a": 20, "b": 20, "c": 20, "d": 20}) + path, path_str = np.einsum_path(*edge_test4, optimize='greedy') + self.assert_path_equal(path, ['einsum_path', (0, 1), (0, 1, 2, 3, 4, 5)]) + + path, path_str = np.einsum_path(*edge_test4, optimize='optimal') + self.assert_path_equal(path, ['einsum_path', (0, 1), (0, 1, 2, 3, 4, 5)]) + + def test_path_type_input(self): + # Test explicit path handeling + path_test = self.build_operands('dcc,fce,ea,dbf->ab') + + path, path_str = np.einsum_path(*path_test, optimize=False) + self.assert_path_equal(path, ['einsum_path', (0, 1, 2, 3)]) + + path, path_str = np.einsum_path(*path_test, optimize=True) + self.assert_path_equal(path, ['einsum_path', (1, 2), (0, 1), (0, 1)]) + + exp_path = ['einsum_path', (0, 2), (0, 2), (0, 1)] + path, path_str = np.einsum_path(*path_test, optimize=exp_path) + self.assert_path_equal(path, exp_path) + + # Double check einsum works on the input path + noopt = np.einsum(*path_test, optimize=False) + opt = np.einsum(*path_test, optimize=exp_path) + assert_almost_equal(noopt, opt) + + def test_spaces(self): + #gh-10794 + arr = np.array([[1]]) + for sp in itertools.product(['', ' '], repeat=4): + # no error for any spacing + np.einsum('{}...a{}->{}...a{}'.format(*sp), arr) + +def test_overlap(): + a = np.arange(9, dtype=int).reshape(3, 3) + b = np.arange(9, dtype=int).reshape(3, 3) + d = np.dot(a, b) + # sanity check + c = np.einsum('ij,jk->ik', a, b) + assert_equal(c, d) + #gh-10080, out overlaps one of the operands + c = np.einsum('ij,jk->ik', a, b, out=b) + assert_equal(c, d) diff --git a/venv/Lib/site-packages/numpy/core/tests/test_errstate.py b/venv/Lib/site-packages/numpy/core/tests/test_errstate.py new file mode 100644 index 0000000..184a373 --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/tests/test_errstate.py @@ -0,0 +1,59 @@ +import pytest +import sysconfig + +import numpy as np +from numpy.testing import assert_, assert_raises + +# The floating point emulation on ARM EABI systems lacking a hardware FPU is +# known to be buggy. This is an attempt to identify these hosts. It may not +# catch all possible cases, but it catches the known cases of gh-413 and +# gh-15562. +hosttype = sysconfig.get_config_var('HOST_GNU_TYPE') +arm_softfloat = False if hosttype is None else hosttype.endswith('gnueabi') + +class TestErrstate: + @pytest.mark.skipif(arm_softfloat, + reason='platform/cpu issue with FPU (gh-413,-15562)') + def test_invalid(self): + with np.errstate(all='raise', under='ignore'): + a = -np.arange(3) + # This should work + with np.errstate(invalid='ignore'): + np.sqrt(a) + # While this should fail! + with assert_raises(FloatingPointError): + np.sqrt(a) + + @pytest.mark.skipif(arm_softfloat, + reason='platform/cpu issue with FPU (gh-15562)') + def test_divide(self): + with np.errstate(all='raise', under='ignore'): + a = -np.arange(3) + # This should work + with np.errstate(divide='ignore'): + a // 0 + # While this should fail! + with assert_raises(FloatingPointError): + a // 0 + # As should this, see gh-15562 + with assert_raises(FloatingPointError): + a // a + + def test_errcall(self): + def foo(*args): + print(args) + + olderrcall = np.geterrcall() + with np.errstate(call=foo): + assert_(np.geterrcall() is foo, 'call is not foo') + with np.errstate(call=None): + assert_(np.geterrcall() is None, 'call is not None') + assert_(np.geterrcall() is olderrcall, 'call is not olderrcall') + + def test_errstate_decorator(self): + @np.errstate(all='ignore') + def foo(): + a = -np.arange(3) + a // 0 + + foo() diff --git a/venv/Lib/site-packages/numpy/core/tests/test_extint128.py b/venv/Lib/site-packages/numpy/core/tests/test_extint128.py new file mode 100644 index 0000000..3b64915 --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/tests/test_extint128.py @@ -0,0 +1,219 @@ +import itertools +import contextlib +import operator +import pytest + +import numpy as np +import numpy.core._multiarray_tests as mt + +from numpy.testing import assert_raises, assert_equal + + +INT64_MAX = np.iinfo(np.int64).max +INT64_MIN = np.iinfo(np.int64).min +INT64_MID = 2**32 + +# int128 is not two's complement, the sign bit is separate +INT128_MAX = 2**128 - 1 +INT128_MIN = -INT128_MAX +INT128_MID = 2**64 + +INT64_VALUES = ( + [INT64_MIN + j for j in range(20)] + + [INT64_MAX - j for j in range(20)] + + [INT64_MID + j for j in range(-20, 20)] + + [2*INT64_MID + j for j in range(-20, 20)] + + [INT64_MID//2 + j for j in range(-20, 20)] + + list(range(-70, 70)) +) + +INT128_VALUES = ( + [INT128_MIN + j for j in range(20)] + + [INT128_MAX - j for j in range(20)] + + [INT128_MID + j for j in range(-20, 20)] + + [2*INT128_MID + j for j in range(-20, 20)] + + [INT128_MID//2 + j for j in range(-20, 20)] + + list(range(-70, 70)) + + [False] # negative zero +) + +INT64_POS_VALUES = [x for x in INT64_VALUES if x > 0] + + +@contextlib.contextmanager +def exc_iter(*args): + """ + Iterate over Cartesian product of *args, and if an exception is raised, + add information of the current iterate. + """ + + value = [None] + + def iterate(): + for v in itertools.product(*args): + value[0] = v + yield v + + try: + yield iterate() + except Exception: + import traceback + msg = "At: %r\n%s" % (repr(value[0]), + traceback.format_exc()) + raise AssertionError(msg) + + +def test_safe_binop(): + # Test checked arithmetic routines + + ops = [ + (operator.add, 1), + (operator.sub, 2), + (operator.mul, 3) + ] + + with exc_iter(ops, INT64_VALUES, INT64_VALUES) as it: + for xop, a, b in it: + pyop, op = xop + c = pyop(a, b) + + if not (INT64_MIN <= c <= INT64_MAX): + assert_raises(OverflowError, mt.extint_safe_binop, a, b, op) + else: + d = mt.extint_safe_binop(a, b, op) + if c != d: + # assert_equal is slow + assert_equal(d, c) + + +def test_to_128(): + with exc_iter(INT64_VALUES) as it: + for a, in it: + b = mt.extint_to_128(a) + if a != b: + assert_equal(b, a) + + +def test_to_64(): + with exc_iter(INT128_VALUES) as it: + for a, in it: + if not (INT64_MIN <= a <= INT64_MAX): + assert_raises(OverflowError, mt.extint_to_64, a) + else: + b = mt.extint_to_64(a) + if a != b: + assert_equal(b, a) + + +def test_mul_64_64(): + with exc_iter(INT64_VALUES, INT64_VALUES) as it: + for a, b in it: + c = a * b + d = mt.extint_mul_64_64(a, b) + if c != d: + assert_equal(d, c) + + +def test_add_128(): + with exc_iter(INT128_VALUES, INT128_VALUES) as it: + for a, b in it: + c = a + b + if not (INT128_MIN <= c <= INT128_MAX): + assert_raises(OverflowError, mt.extint_add_128, a, b) + else: + d = mt.extint_add_128(a, b) + if c != d: + assert_equal(d, c) + + +def test_sub_128(): + with exc_iter(INT128_VALUES, INT128_VALUES) as it: + for a, b in it: + c = a - b + if not (INT128_MIN <= c <= INT128_MAX): + assert_raises(OverflowError, mt.extint_sub_128, a, b) + else: + d = mt.extint_sub_128(a, b) + if c != d: + assert_equal(d, c) + + +def test_neg_128(): + with exc_iter(INT128_VALUES) as it: + for a, in it: + b = -a + c = mt.extint_neg_128(a) + if b != c: + assert_equal(c, b) + + +def test_shl_128(): + with exc_iter(INT128_VALUES) as it: + for a, in it: + if a < 0: + b = -(((-a) << 1) & (2**128-1)) + else: + b = (a << 1) & (2**128-1) + c = mt.extint_shl_128(a) + if b != c: + assert_equal(c, b) + + +def test_shr_128(): + with exc_iter(INT128_VALUES) as it: + for a, in it: + if a < 0: + b = -((-a) >> 1) + else: + b = a >> 1 + c = mt.extint_shr_128(a) + if b != c: + assert_equal(c, b) + + +def test_gt_128(): + with exc_iter(INT128_VALUES, INT128_VALUES) as it: + for a, b in it: + c = a > b + d = mt.extint_gt_128(a, b) + if c != d: + assert_equal(d, c) + + +@pytest.mark.slow +def test_divmod_128_64(): + with exc_iter(INT128_VALUES, INT64_POS_VALUES) as it: + for a, b in it: + if a >= 0: + c, cr = divmod(a, b) + else: + c, cr = divmod(-a, b) + c = -c + cr = -cr + + d, dr = mt.extint_divmod_128_64(a, b) + + if c != d or d != dr or b*d + dr != a: + assert_equal(d, c) + assert_equal(dr, cr) + assert_equal(b*d + dr, a) + + +def test_floordiv_128_64(): + with exc_iter(INT128_VALUES, INT64_POS_VALUES) as it: + for a, b in it: + c = a // b + d = mt.extint_floordiv_128_64(a, b) + + if c != d: + assert_equal(d, c) + + +def test_ceildiv_128_64(): + with exc_iter(INT128_VALUES, INT64_POS_VALUES) as it: + for a, b in it: + c = (a + b - 1) // b + d = mt.extint_ceildiv_128_64(a, b) + + if c != d: + assert_equal(d, c) diff --git a/venv/Lib/site-packages/numpy/core/tests/test_function_base.py b/venv/Lib/site-packages/numpy/core/tests/test_function_base.py new file mode 100644 index 0000000..dad7a58 --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/tests/test_function_base.py @@ -0,0 +1,409 @@ +from numpy import ( + logspace, linspace, geomspace, dtype, array, sctypes, arange, isnan, + ndarray, sqrt, nextafter, stack, errstate + ) +from numpy.testing import ( + assert_, assert_equal, assert_raises, assert_array_equal, assert_allclose, + ) + + +class PhysicalQuantity(float): + def __new__(cls, value): + return float.__new__(cls, value) + + def __add__(self, x): + assert_(isinstance(x, PhysicalQuantity)) + return PhysicalQuantity(float(x) + float(self)) + __radd__ = __add__ + + def __sub__(self, x): + assert_(isinstance(x, PhysicalQuantity)) + return PhysicalQuantity(float(self) - float(x)) + + def __rsub__(self, x): + assert_(isinstance(x, PhysicalQuantity)) + return PhysicalQuantity(float(x) - float(self)) + + def __mul__(self, x): + return PhysicalQuantity(float(x) * float(self)) + __rmul__ = __mul__ + + def __div__(self, x): + return PhysicalQuantity(float(self) / float(x)) + + def __rdiv__(self, x): + return PhysicalQuantity(float(x) / float(self)) + + +class PhysicalQuantity2(ndarray): + __array_priority__ = 10 + + +class TestLogspace: + + def test_basic(self): + y = logspace(0, 6) + assert_(len(y) == 50) + y = logspace(0, 6, num=100) + assert_(y[-1] == 10 ** 6) + y = logspace(0, 6, endpoint=False) + assert_(y[-1] < 10 ** 6) + y = logspace(0, 6, num=7) + assert_array_equal(y, [1, 10, 100, 1e3, 1e4, 1e5, 1e6]) + + def test_start_stop_array(self): + start = array([0., 1.]) + stop = array([6., 7.]) + t1 = logspace(start, stop, 6) + t2 = stack([logspace(_start, _stop, 6) + for _start, _stop in zip(start, stop)], axis=1) + assert_equal(t1, t2) + t3 = logspace(start, stop[0], 6) + t4 = stack([logspace(_start, stop[0], 6) + for _start in start], axis=1) + assert_equal(t3, t4) + t5 = logspace(start, stop, 6, axis=-1) + assert_equal(t5, t2.T) + + def test_dtype(self): + y = logspace(0, 6, dtype='float32') + assert_equal(y.dtype, dtype('float32')) + y = logspace(0, 6, dtype='float64') + assert_equal(y.dtype, dtype('float64')) + y = logspace(0, 6, dtype='int32') + assert_equal(y.dtype, dtype('int32')) + + def test_physical_quantities(self): + a = PhysicalQuantity(1.0) + b = PhysicalQuantity(5.0) + assert_equal(logspace(a, b), logspace(1.0, 5.0)) + + def test_subclass(self): + a = array(1).view(PhysicalQuantity2) + b = array(7).view(PhysicalQuantity2) + ls = logspace(a, b) + assert type(ls) is PhysicalQuantity2 + assert_equal(ls, logspace(1.0, 7.0)) + ls = logspace(a, b, 1) + assert type(ls) is PhysicalQuantity2 + assert_equal(ls, logspace(1.0, 7.0, 1)) + + +class TestGeomspace: + + def test_basic(self): + y = geomspace(1, 1e6) + assert_(len(y) == 50) + y = geomspace(1, 1e6, num=100) + assert_(y[-1] == 10 ** 6) + y = geomspace(1, 1e6, endpoint=False) + assert_(y[-1] < 10 ** 6) + y = geomspace(1, 1e6, num=7) + assert_array_equal(y, [1, 10, 100, 1e3, 1e4, 1e5, 1e6]) + + y = geomspace(8, 2, num=3) + assert_allclose(y, [8, 4, 2]) + assert_array_equal(y.imag, 0) + + y = geomspace(-1, -100, num=3) + assert_array_equal(y, [-1, -10, -100]) + assert_array_equal(y.imag, 0) + + y = geomspace(-100, -1, num=3) + assert_array_equal(y, [-100, -10, -1]) + assert_array_equal(y.imag, 0) + + def test_boundaries_match_start_and_stop_exactly(self): + # make sure that the boundaries of the returned array exactly + # equal 'start' and 'stop' - this isn't obvious because + # np.exp(np.log(x)) isn't necessarily exactly equal to x + start = 0.3 + stop = 20.3 + + y = geomspace(start, stop, num=1) + assert_equal(y[0], start) + + y = geomspace(start, stop, num=1, endpoint=False) + assert_equal(y[0], start) + + y = geomspace(start, stop, num=3) + assert_equal(y[0], start) + assert_equal(y[-1], stop) + + y = geomspace(start, stop, num=3, endpoint=False) + assert_equal(y[0], start) + + def test_nan_interior(self): + with errstate(invalid='ignore'): + y = geomspace(-3, 3, num=4) + + assert_equal(y[0], -3.0) + assert_(isnan(y[1:-1]).all()) + assert_equal(y[3], 3.0) + + with errstate(invalid='ignore'): + y = geomspace(-3, 3, num=4, endpoint=False) + + assert_equal(y[0], -3.0) + assert_(isnan(y[1:]).all()) + + def test_complex(self): + # Purely imaginary + y = geomspace(1j, 16j, num=5) + assert_allclose(y, [1j, 2j, 4j, 8j, 16j]) + assert_array_equal(y.real, 0) + + y = geomspace(-4j, -324j, num=5) + assert_allclose(y, [-4j, -12j, -36j, -108j, -324j]) + assert_array_equal(y.real, 0) + + y = geomspace(1+1j, 1000+1000j, num=4) + assert_allclose(y, [1+1j, 10+10j, 100+100j, 1000+1000j]) + + y = geomspace(-1+1j, -1000+1000j, num=4) + assert_allclose(y, [-1+1j, -10+10j, -100+100j, -1000+1000j]) + + # Logarithmic spirals + y = geomspace(-1, 1, num=3, dtype=complex) + assert_allclose(y, [-1, 1j, +1]) + + y = geomspace(0+3j, -3+0j, 3) + assert_allclose(y, [0+3j, -3/sqrt(2)+3j/sqrt(2), -3+0j]) + y = geomspace(0+3j, 3+0j, 3) + assert_allclose(y, [0+3j, 3/sqrt(2)+3j/sqrt(2), 3+0j]) + y = geomspace(-3+0j, 0-3j, 3) + assert_allclose(y, [-3+0j, -3/sqrt(2)-3j/sqrt(2), 0-3j]) + y = geomspace(0+3j, -3+0j, 3) + assert_allclose(y, [0+3j, -3/sqrt(2)+3j/sqrt(2), -3+0j]) + y = geomspace(-2-3j, 5+7j, 7) + assert_allclose(y, [-2-3j, -0.29058977-4.15771027j, + 2.08885354-4.34146838j, 4.58345529-3.16355218j, + 6.41401745-0.55233457j, 6.75707386+3.11795092j, + 5+7j]) + + # Type promotion should prevent the -5 from becoming a NaN + y = geomspace(3j, -5, 2) + assert_allclose(y, [3j, -5]) + y = geomspace(-5, 3j, 2) + assert_allclose(y, [-5, 3j]) + + def test_dtype(self): + y = geomspace(1, 1e6, dtype='float32') + assert_equal(y.dtype, dtype('float32')) + y = geomspace(1, 1e6, dtype='float64') + assert_equal(y.dtype, dtype('float64')) + y = geomspace(1, 1e6, dtype='int32') + assert_equal(y.dtype, dtype('int32')) + + # Native types + y = geomspace(1, 1e6, dtype=float) + assert_equal(y.dtype, dtype('float_')) + y = geomspace(1, 1e6, dtype=complex) + assert_equal(y.dtype, dtype('complex')) + + def test_start_stop_array_scalar(self): + lim1 = array([120, 100], dtype="int8") + lim2 = array([-120, -100], dtype="int8") + lim3 = array([1200, 1000], dtype="uint16") + t1 = geomspace(lim1[0], lim1[1], 5) + t2 = geomspace(lim2[0], lim2[1], 5) + t3 = geomspace(lim3[0], lim3[1], 5) + t4 = geomspace(120.0, 100.0, 5) + t5 = geomspace(-120.0, -100.0, 5) + t6 = geomspace(1200.0, 1000.0, 5) + + # t3 uses float32, t6 uses float64 + assert_allclose(t1, t4, rtol=1e-2) + assert_allclose(t2, t5, rtol=1e-2) + assert_allclose(t3, t6, rtol=1e-5) + + def test_start_stop_array(self): + # Try to use all special cases. + start = array([1.e0, 32., 1j, -4j, 1+1j, -1]) + stop = array([1.e4, 2., 16j, -324j, 10000+10000j, 1]) + t1 = geomspace(start, stop, 5) + t2 = stack([geomspace(_start, _stop, 5) + for _start, _stop in zip(start, stop)], axis=1) + assert_equal(t1, t2) + t3 = geomspace(start, stop[0], 5) + t4 = stack([geomspace(_start, stop[0], 5) + for _start in start], axis=1) + assert_equal(t3, t4) + t5 = geomspace(start, stop, 5, axis=-1) + assert_equal(t5, t2.T) + + def test_physical_quantities(self): + a = PhysicalQuantity(1.0) + b = PhysicalQuantity(5.0) + assert_equal(geomspace(a, b), geomspace(1.0, 5.0)) + + def test_subclass(self): + a = array(1).view(PhysicalQuantity2) + b = array(7).view(PhysicalQuantity2) + gs = geomspace(a, b) + assert type(gs) is PhysicalQuantity2 + assert_equal(gs, geomspace(1.0, 7.0)) + gs = geomspace(a, b, 1) + assert type(gs) is PhysicalQuantity2 + assert_equal(gs, geomspace(1.0, 7.0, 1)) + + def test_bounds(self): + assert_raises(ValueError, geomspace, 0, 10) + assert_raises(ValueError, geomspace, 10, 0) + assert_raises(ValueError, geomspace, 0, 0) + + +class TestLinspace: + + def test_basic(self): + y = linspace(0, 10) + assert_(len(y) == 50) + y = linspace(2, 10, num=100) + assert_(y[-1] == 10) + y = linspace(2, 10, endpoint=False) + assert_(y[-1] < 10) + assert_raises(ValueError, linspace, 0, 10, num=-1) + + def test_corner(self): + y = list(linspace(0, 1, 1)) + assert_(y == [0.0], y) + assert_raises(TypeError, linspace, 0, 1, num=2.5) + + def test_type(self): + t1 = linspace(0, 1, 0).dtype + t2 = linspace(0, 1, 1).dtype + t3 = linspace(0, 1, 2).dtype + assert_equal(t1, t2) + assert_equal(t2, t3) + + def test_dtype(self): + y = linspace(0, 6, dtype='float32') + assert_equal(y.dtype, dtype('float32')) + y = linspace(0, 6, dtype='float64') + assert_equal(y.dtype, dtype('float64')) + y = linspace(0, 6, dtype='int32') + assert_equal(y.dtype, dtype('int32')) + + def test_start_stop_array_scalar(self): + lim1 = array([-120, 100], dtype="int8") + lim2 = array([120, -100], dtype="int8") + lim3 = array([1200, 1000], dtype="uint16") + t1 = linspace(lim1[0], lim1[1], 5) + t2 = linspace(lim2[0], lim2[1], 5) + t3 = linspace(lim3[0], lim3[1], 5) + t4 = linspace(-120.0, 100.0, 5) + t5 = linspace(120.0, -100.0, 5) + t6 = linspace(1200.0, 1000.0, 5) + assert_equal(t1, t4) + assert_equal(t2, t5) + assert_equal(t3, t6) + + def test_start_stop_array(self): + start = array([-120, 120], dtype="int8") + stop = array([100, -100], dtype="int8") + t1 = linspace(start, stop, 5) + t2 = stack([linspace(_start, _stop, 5) + for _start, _stop in zip(start, stop)], axis=1) + assert_equal(t1, t2) + t3 = linspace(start, stop[0], 5) + t4 = stack([linspace(_start, stop[0], 5) + for _start in start], axis=1) + assert_equal(t3, t4) + t5 = linspace(start, stop, 5, axis=-1) + assert_equal(t5, t2.T) + + def test_complex(self): + lim1 = linspace(1 + 2j, 3 + 4j, 5) + t1 = array([1.0+2.j, 1.5+2.5j, 2.0+3j, 2.5+3.5j, 3.0+4j]) + lim2 = linspace(1j, 10, 5) + t2 = array([0.0+1.j, 2.5+0.75j, 5.0+0.5j, 7.5+0.25j, 10.0+0j]) + assert_equal(lim1, t1) + assert_equal(lim2, t2) + + def test_physical_quantities(self): + a = PhysicalQuantity(0.0) + b = PhysicalQuantity(1.0) + assert_equal(linspace(a, b), linspace(0.0, 1.0)) + + def test_subclass(self): + a = array(0).view(PhysicalQuantity2) + b = array(1).view(PhysicalQuantity2) + ls = linspace(a, b) + assert type(ls) is PhysicalQuantity2 + assert_equal(ls, linspace(0.0, 1.0)) + ls = linspace(a, b, 1) + assert type(ls) is PhysicalQuantity2 + assert_equal(ls, linspace(0.0, 1.0, 1)) + + def test_array_interface(self): + # Regression test for https://github.com/numpy/numpy/pull/6659 + # Ensure that start/stop can be objects that implement + # __array_interface__ and are convertible to numeric scalars + + class Arrayish: + """ + A generic object that supports the __array_interface__ and hence + can in principle be converted to a numeric scalar, but is not + otherwise recognized as numeric, but also happens to support + multiplication by floats. + + Data should be an object that implements the buffer interface, + and contains at least 4 bytes. + """ + + def __init__(self, data): + self._data = data + + @property + def __array_interface__(self): + return {'shape': (), 'typestr': ' 1) + assert_(info.minexp < -1) + assert_(info.maxexp > 1) diff --git a/venv/Lib/site-packages/numpy/core/tests/test_half.py b/venv/Lib/site-packages/numpy/core/tests/test_half.py new file mode 100644 index 0000000..1b6fd21 --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/tests/test_half.py @@ -0,0 +1,554 @@ +import platform +import pytest + +import numpy as np +from numpy import uint16, float16, float32, float64 +from numpy.testing import assert_, assert_equal + + +def assert_raises_fpe(strmatch, callable, *args, **kwargs): + try: + callable(*args, **kwargs) + except FloatingPointError as exc: + assert_(str(exc).find(strmatch) >= 0, + "Did not raise floating point %s error" % strmatch) + else: + assert_(False, + "Did not raise floating point %s error" % strmatch) + +class TestHalf: + def setup(self): + # An array of all possible float16 values + self.all_f16 = np.arange(0x10000, dtype=uint16) + self.all_f16.dtype = float16 + self.all_f32 = np.array(self.all_f16, dtype=float32) + self.all_f64 = np.array(self.all_f16, dtype=float64) + + # An array of all non-NaN float16 values, in sorted order + self.nonan_f16 = np.concatenate( + (np.arange(0xfc00, 0x7fff, -1, dtype=uint16), + np.arange(0x0000, 0x7c01, 1, dtype=uint16))) + self.nonan_f16.dtype = float16 + self.nonan_f32 = np.array(self.nonan_f16, dtype=float32) + self.nonan_f64 = np.array(self.nonan_f16, dtype=float64) + + # An array of all finite float16 values, in sorted order + self.finite_f16 = self.nonan_f16[1:-1] + self.finite_f32 = self.nonan_f32[1:-1] + self.finite_f64 = self.nonan_f64[1:-1] + + def test_half_conversions(self): + """Checks that all 16-bit values survive conversion + to/from 32-bit and 64-bit float""" + # Because the underlying routines preserve the NaN bits, every + # value is preserved when converting to/from other floats. + + # Convert from float32 back to float16 + b = np.array(self.all_f32, dtype=float16) + assert_equal(self.all_f16.view(dtype=uint16), + b.view(dtype=uint16)) + + # Convert from float64 back to float16 + b = np.array(self.all_f64, dtype=float16) + assert_equal(self.all_f16.view(dtype=uint16), + b.view(dtype=uint16)) + + # Convert float16 to longdouble and back + # This doesn't necessarily preserve the extra NaN bits, + # so exclude NaNs. + a_ld = np.array(self.nonan_f16, dtype=np.longdouble) + b = np.array(a_ld, dtype=float16) + assert_equal(self.nonan_f16.view(dtype=uint16), + b.view(dtype=uint16)) + + # Check the range for which all integers can be represented + i_int = np.arange(-2048, 2049) + i_f16 = np.array(i_int, dtype=float16) + j = np.array(i_f16, dtype=int) + assert_equal(i_int, j) + + @pytest.mark.parametrize("string_dt", ["S", "U"]) + def test_half_conversion_to_string(self, string_dt): + # Currently uses S/U32 (which is sufficient for float32) + expected_dt = np.dtype(f"{string_dt}32") + assert np.promote_types(np.float16, string_dt) == expected_dt + assert np.promote_types(string_dt, np.float16) == expected_dt + + arr = np.ones(3, dtype=np.float16).astype(string_dt) + assert arr.dtype == expected_dt + + @pytest.mark.parametrize("string_dt", ["S", "U"]) + def test_half_conversion_from_string(self, string_dt): + string = np.array("3.1416", dtype=string_dt) + assert string.astype(np.float16) == np.array(3.1416, dtype=np.float16) + + @pytest.mark.parametrize("offset", [None, "up", "down"]) + @pytest.mark.parametrize("shift", [None, "up", "down"]) + @pytest.mark.parametrize("float_t", [np.float32, np.float64]) + def test_half_conversion_rounding(self, float_t, shift, offset): + # Assumes that round to even is used during casting. + max_pattern = np.float16(np.finfo(np.float16).max).view(np.uint16) + + # Test all (positive) finite numbers, denormals are most interesting + # however: + f16s_patterns = np.arange(0, max_pattern+1, dtype=np.uint16) + f16s_float = f16s_patterns.view(np.float16).astype(float_t) + + # Shift the values by half a bit up or a down (or do not shift), + if shift == "up": + f16s_float = 0.5 * (f16s_float[:-1] + f16s_float[1:])[1:] + elif shift == "down": + f16s_float = 0.5 * (f16s_float[:-1] + f16s_float[1:])[:-1] + else: + f16s_float = f16s_float[1:-1] + + # Increase the float by a minimal value: + if offset == "up": + f16s_float = np.nextafter(f16s_float, float_t(1e50)) + elif offset == "down": + f16s_float = np.nextafter(f16s_float, float_t(-1e50)) + + # Convert back to float16 and its bit pattern: + res_patterns = f16s_float.astype(np.float16).view(np.uint16) + + # The above calculations tries the original values, or the exact + # mid points between the float16 values. It then further offsets them + # by as little as possible. If no offset occurs, "round to even" + # logic will be necessary, an arbitrarily small offset should cause + # normal up/down rounding always. + + # Calculate the expected pattern: + cmp_patterns = f16s_patterns[1:-1].copy() + + if shift == "down" and offset != "up": + shift_pattern = -1 + elif shift == "up" and offset != "down": + shift_pattern = 1 + else: + # There cannot be a shift, either shift is None, so all rounding + # will go back to original, or shift is reduced by offset too much. + shift_pattern = 0 + + # If rounding occurs, is it normal rounding or round to even? + if offset is None: + # Round to even occurs, modify only non-even, cast to allow + (-1) + cmp_patterns[0::2].view(np.int16)[...] += shift_pattern + else: + cmp_patterns.view(np.int16)[...] += shift_pattern + + assert_equal(res_patterns, cmp_patterns) + + @pytest.mark.parametrize(["float_t", "uint_t", "bits"], + [(np.float32, np.uint32, 23), + (np.float64, np.uint64, 52)]) + def test_half_conversion_denormal_round_even(self, float_t, uint_t, bits): + # Test specifically that all bits are considered when deciding + # whether round to even should occur (i.e. no bits are lost at the + # end. Compare also gh-12721. The most bits can get lost for the + # smallest denormal: + smallest_value = np.uint16(1).view(np.float16).astype(float_t) + assert smallest_value == 2**-24 + + # Will be rounded to zero based on round to even rule: + rounded_to_zero = smallest_value / float_t(2) + assert rounded_to_zero.astype(np.float16) == 0 + + # The significand will be all 0 for the float_t, test that we do not + # lose the lower ones of these: + for i in range(bits): + # slightly increasing the value should make it round up: + larger_pattern = rounded_to_zero.view(uint_t) | uint_t(1 << i) + larger_value = larger_pattern.view(float_t) + assert larger_value.astype(np.float16) == smallest_value + + def test_nans_infs(self): + with np.errstate(all='ignore'): + # Check some of the ufuncs + assert_equal(np.isnan(self.all_f16), np.isnan(self.all_f32)) + assert_equal(np.isinf(self.all_f16), np.isinf(self.all_f32)) + assert_equal(np.isfinite(self.all_f16), np.isfinite(self.all_f32)) + assert_equal(np.signbit(self.all_f16), np.signbit(self.all_f32)) + assert_equal(np.spacing(float16(65504)), np.inf) + + # Check comparisons of all values with NaN + nan = float16(np.nan) + + assert_(not (self.all_f16 == nan).any()) + assert_(not (nan == self.all_f16).any()) + + assert_((self.all_f16 != nan).all()) + assert_((nan != self.all_f16).all()) + + assert_(not (self.all_f16 < nan).any()) + assert_(not (nan < self.all_f16).any()) + + assert_(not (self.all_f16 <= nan).any()) + assert_(not (nan <= self.all_f16).any()) + + assert_(not (self.all_f16 > nan).any()) + assert_(not (nan > self.all_f16).any()) + + assert_(not (self.all_f16 >= nan).any()) + assert_(not (nan >= self.all_f16).any()) + + def test_half_values(self): + """Confirms a small number of known half values""" + a = np.array([1.0, -1.0, + 2.0, -2.0, + 0.0999755859375, 0.333251953125, # 1/10, 1/3 + 65504, -65504, # Maximum magnitude + 2.0**(-14), -2.0**(-14), # Minimum normal + 2.0**(-24), -2.0**(-24), # Minimum subnormal + 0, -1/1e1000, # Signed zeros + np.inf, -np.inf]) + b = np.array([0x3c00, 0xbc00, + 0x4000, 0xc000, + 0x2e66, 0x3555, + 0x7bff, 0xfbff, + 0x0400, 0x8400, + 0x0001, 0x8001, + 0x0000, 0x8000, + 0x7c00, 0xfc00], dtype=uint16) + b.dtype = float16 + assert_equal(a, b) + + def test_half_rounding(self): + """Checks that rounding when converting to half is correct""" + a = np.array([2.0**-25 + 2.0**-35, # Rounds to minimum subnormal + 2.0**-25, # Underflows to zero (nearest even mode) + 2.0**-26, # Underflows to zero + 1.0+2.0**-11 + 2.0**-16, # rounds to 1.0+2**(-10) + 1.0+2.0**-11, # rounds to 1.0 (nearest even mode) + 1.0+2.0**-12, # rounds to 1.0 + 65519, # rounds to 65504 + 65520], # rounds to inf + dtype=float64) + rounded = [2.0**-24, + 0.0, + 0.0, + 1.0+2.0**(-10), + 1.0, + 1.0, + 65504, + np.inf] + + # Check float64->float16 rounding + b = np.array(a, dtype=float16) + assert_equal(b, rounded) + + # Check float32->float16 rounding + a = np.array(a, dtype=float32) + b = np.array(a, dtype=float16) + assert_equal(b, rounded) + + def test_half_correctness(self): + """Take every finite float16, and check the casting functions with + a manual conversion.""" + + # Create an array of all finite float16s + a_bits = self.finite_f16.view(dtype=uint16) + + # Convert to 64-bit float manually + a_sgn = (-1.0)**((a_bits & 0x8000) >> 15) + a_exp = np.array((a_bits & 0x7c00) >> 10, dtype=np.int32) - 15 + a_man = (a_bits & 0x03ff) * 2.0**(-10) + # Implicit bit of normalized floats + a_man[a_exp != -15] += 1 + # Denormalized exponent is -14 + a_exp[a_exp == -15] = -14 + + a_manual = a_sgn * a_man * 2.0**a_exp + + a32_fail = np.nonzero(self.finite_f32 != a_manual)[0] + if len(a32_fail) != 0: + bad_index = a32_fail[0] + assert_equal(self.finite_f32, a_manual, + "First non-equal is half value %x -> %g != %g" % + (self.finite_f16[bad_index], + self.finite_f32[bad_index], + a_manual[bad_index])) + + a64_fail = np.nonzero(self.finite_f64 != a_manual)[0] + if len(a64_fail) != 0: + bad_index = a64_fail[0] + assert_equal(self.finite_f64, a_manual, + "First non-equal is half value %x -> %g != %g" % + (self.finite_f16[bad_index], + self.finite_f64[bad_index], + a_manual[bad_index])) + + def test_half_ordering(self): + """Make sure comparisons are working right""" + + # All non-NaN float16 values in reverse order + a = self.nonan_f16[::-1].copy() + + # 32-bit float copy + b = np.array(a, dtype=float32) + + # Should sort the same + a.sort() + b.sort() + assert_equal(a, b) + + # Comparisons should work + assert_((a[:-1] <= a[1:]).all()) + assert_(not (a[:-1] > a[1:]).any()) + assert_((a[1:] >= a[:-1]).all()) + assert_(not (a[1:] < a[:-1]).any()) + # All != except for +/-0 + assert_equal(np.nonzero(a[:-1] < a[1:])[0].size, a.size-2) + assert_equal(np.nonzero(a[1:] > a[:-1])[0].size, a.size-2) + + def test_half_funcs(self): + """Test the various ArrFuncs""" + + # fill + assert_equal(np.arange(10, dtype=float16), + np.arange(10, dtype=float32)) + + # fillwithscalar + a = np.zeros((5,), dtype=float16) + a.fill(1) + assert_equal(a, np.ones((5,), dtype=float16)) + + # nonzero and copyswap + a = np.array([0, 0, -1, -1/1e20, 0, 2.0**-24, 7.629e-6], dtype=float16) + assert_equal(a.nonzero()[0], + [2, 5, 6]) + a = a.byteswap().newbyteorder() + assert_equal(a.nonzero()[0], + [2, 5, 6]) + + # dot + a = np.arange(0, 10, 0.5, dtype=float16) + b = np.ones((20,), dtype=float16) + assert_equal(np.dot(a, b), + 95) + + # argmax + a = np.array([0, -np.inf, -2, 0.5, 12.55, 7.3, 2.1, 12.4], dtype=float16) + assert_equal(a.argmax(), + 4) + a = np.array([0, -np.inf, -2, np.inf, 12.55, np.nan, 2.1, 12.4], dtype=float16) + assert_equal(a.argmax(), + 5) + + # getitem + a = np.arange(10, dtype=float16) + for i in range(10): + assert_equal(a.item(i), i) + + def test_spacing_nextafter(self): + """Test np.spacing and np.nextafter""" + # All non-negative finite #'s + a = np.arange(0x7c00, dtype=uint16) + hinf = np.array((np.inf,), dtype=float16) + hnan = np.array((np.nan,), dtype=float16) + a_f16 = a.view(dtype=float16) + + assert_equal(np.spacing(a_f16[:-1]), a_f16[1:]-a_f16[:-1]) + + assert_equal(np.nextafter(a_f16[:-1], hinf), a_f16[1:]) + assert_equal(np.nextafter(a_f16[0], -hinf), -a_f16[1]) + assert_equal(np.nextafter(a_f16[1:], -hinf), a_f16[:-1]) + + assert_equal(np.nextafter(hinf, a_f16), a_f16[-1]) + assert_equal(np.nextafter(-hinf, a_f16), -a_f16[-1]) + + assert_equal(np.nextafter(hinf, hinf), hinf) + assert_equal(np.nextafter(hinf, -hinf), a_f16[-1]) + assert_equal(np.nextafter(-hinf, hinf), -a_f16[-1]) + assert_equal(np.nextafter(-hinf, -hinf), -hinf) + + assert_equal(np.nextafter(a_f16, hnan), hnan[0]) + assert_equal(np.nextafter(hnan, a_f16), hnan[0]) + + assert_equal(np.nextafter(hnan, hnan), hnan) + assert_equal(np.nextafter(hinf, hnan), hnan) + assert_equal(np.nextafter(hnan, hinf), hnan) + + # switch to negatives + a |= 0x8000 + + assert_equal(np.spacing(a_f16[0]), np.spacing(a_f16[1])) + assert_equal(np.spacing(a_f16[1:]), a_f16[:-1]-a_f16[1:]) + + assert_equal(np.nextafter(a_f16[0], hinf), -a_f16[1]) + assert_equal(np.nextafter(a_f16[1:], hinf), a_f16[:-1]) + assert_equal(np.nextafter(a_f16[:-1], -hinf), a_f16[1:]) + + assert_equal(np.nextafter(hinf, a_f16), -a_f16[-1]) + assert_equal(np.nextafter(-hinf, a_f16), a_f16[-1]) + + assert_equal(np.nextafter(a_f16, hnan), hnan[0]) + assert_equal(np.nextafter(hnan, a_f16), hnan[0]) + + def test_half_ufuncs(self): + """Test the various ufuncs""" + + a = np.array([0, 1, 2, 4, 2], dtype=float16) + b = np.array([-2, 5, 1, 4, 3], dtype=float16) + c = np.array([0, -1, -np.inf, np.nan, 6], dtype=float16) + + assert_equal(np.add(a, b), [-2, 6, 3, 8, 5]) + assert_equal(np.subtract(a, b), [2, -4, 1, 0, -1]) + assert_equal(np.multiply(a, b), [0, 5, 2, 16, 6]) + assert_equal(np.divide(a, b), [0, 0.199951171875, 2, 1, 0.66650390625]) + + assert_equal(np.equal(a, b), [False, False, False, True, False]) + assert_equal(np.not_equal(a, b), [True, True, True, False, True]) + assert_equal(np.less(a, b), [False, True, False, False, True]) + assert_equal(np.less_equal(a, b), [False, True, False, True, True]) + assert_equal(np.greater(a, b), [True, False, True, False, False]) + assert_equal(np.greater_equal(a, b), [True, False, True, True, False]) + assert_equal(np.logical_and(a, b), [False, True, True, True, True]) + assert_equal(np.logical_or(a, b), [True, True, True, True, True]) + assert_equal(np.logical_xor(a, b), [True, False, False, False, False]) + assert_equal(np.logical_not(a), [True, False, False, False, False]) + + assert_equal(np.isnan(c), [False, False, False, True, False]) + assert_equal(np.isinf(c), [False, False, True, False, False]) + assert_equal(np.isfinite(c), [True, True, False, False, True]) + assert_equal(np.signbit(b), [True, False, False, False, False]) + + assert_equal(np.copysign(b, a), [2, 5, 1, 4, 3]) + + assert_equal(np.maximum(a, b), [0, 5, 2, 4, 3]) + + x = np.maximum(b, c) + assert_(np.isnan(x[3])) + x[3] = 0 + assert_equal(x, [0, 5, 1, 0, 6]) + + assert_equal(np.minimum(a, b), [-2, 1, 1, 4, 2]) + + x = np.minimum(b, c) + assert_(np.isnan(x[3])) + x[3] = 0 + assert_equal(x, [-2, -1, -np.inf, 0, 3]) + + assert_equal(np.fmax(a, b), [0, 5, 2, 4, 3]) + assert_equal(np.fmax(b, c), [0, 5, 1, 4, 6]) + assert_equal(np.fmin(a, b), [-2, 1, 1, 4, 2]) + assert_equal(np.fmin(b, c), [-2, -1, -np.inf, 4, 3]) + + assert_equal(np.floor_divide(a, b), [0, 0, 2, 1, 0]) + assert_equal(np.remainder(a, b), [0, 1, 0, 0, 2]) + assert_equal(np.divmod(a, b), ([0, 0, 2, 1, 0], [0, 1, 0, 0, 2])) + assert_equal(np.square(b), [4, 25, 1, 16, 9]) + assert_equal(np.reciprocal(b), [-0.5, 0.199951171875, 1, 0.25, 0.333251953125]) + assert_equal(np.ones_like(b), [1, 1, 1, 1, 1]) + assert_equal(np.conjugate(b), b) + assert_equal(np.absolute(b), [2, 5, 1, 4, 3]) + assert_equal(np.negative(b), [2, -5, -1, -4, -3]) + assert_equal(np.positive(b), b) + assert_equal(np.sign(b), [-1, 1, 1, 1, 1]) + assert_equal(np.modf(b), ([0, 0, 0, 0, 0], b)) + assert_equal(np.frexp(b), ([-0.5, 0.625, 0.5, 0.5, 0.75], [2, 3, 1, 3, 2])) + assert_equal(np.ldexp(b, [0, 1, 2, 4, 2]), [-2, 10, 4, 64, 12]) + + def test_half_coercion(self): + """Test that half gets coerced properly with the other types""" + a16 = np.array((1,), dtype=float16) + a32 = np.array((1,), dtype=float32) + b16 = float16(1) + b32 = float32(1) + + assert_equal(np.power(a16, 2).dtype, float16) + assert_equal(np.power(a16, 2.0).dtype, float16) + assert_equal(np.power(a16, b16).dtype, float16) + assert_equal(np.power(a16, b32).dtype, float16) + assert_equal(np.power(a16, a16).dtype, float16) + assert_equal(np.power(a16, a32).dtype, float32) + + assert_equal(np.power(b16, 2).dtype, float64) + assert_equal(np.power(b16, 2.0).dtype, float64) + assert_equal(np.power(b16, b16).dtype, float16) + assert_equal(np.power(b16, b32).dtype, float32) + assert_equal(np.power(b16, a16).dtype, float16) + assert_equal(np.power(b16, a32).dtype, float32) + + assert_equal(np.power(a32, a16).dtype, float32) + assert_equal(np.power(a32, b16).dtype, float32) + assert_equal(np.power(b32, a16).dtype, float16) + assert_equal(np.power(b32, b16).dtype, float32) + + @pytest.mark.skipif(platform.machine() == "armv5tel", + reason="See gh-413.") + def test_half_fpe(self): + with np.errstate(all='raise'): + sx16 = np.array((1e-4,), dtype=float16) + bx16 = np.array((1e4,), dtype=float16) + sy16 = float16(1e-4) + by16 = float16(1e4) + + # Underflow errors + assert_raises_fpe('underflow', lambda a, b:a*b, sx16, sx16) + assert_raises_fpe('underflow', lambda a, b:a*b, sx16, sy16) + assert_raises_fpe('underflow', lambda a, b:a*b, sy16, sx16) + assert_raises_fpe('underflow', lambda a, b:a*b, sy16, sy16) + assert_raises_fpe('underflow', lambda a, b:a/b, sx16, bx16) + assert_raises_fpe('underflow', lambda a, b:a/b, sx16, by16) + assert_raises_fpe('underflow', lambda a, b:a/b, sy16, bx16) + assert_raises_fpe('underflow', lambda a, b:a/b, sy16, by16) + assert_raises_fpe('underflow', lambda a, b:a/b, + float16(2.**-14), float16(2**11)) + assert_raises_fpe('underflow', lambda a, b:a/b, + float16(-2.**-14), float16(2**11)) + assert_raises_fpe('underflow', lambda a, b:a/b, + float16(2.**-14+2**-24), float16(2)) + assert_raises_fpe('underflow', lambda a, b:a/b, + float16(-2.**-14-2**-24), float16(2)) + assert_raises_fpe('underflow', lambda a, b:a/b, + float16(2.**-14+2**-23), float16(4)) + + # Overflow errors + assert_raises_fpe('overflow', lambda a, b:a*b, bx16, bx16) + assert_raises_fpe('overflow', lambda a, b:a*b, bx16, by16) + assert_raises_fpe('overflow', lambda a, b:a*b, by16, bx16) + assert_raises_fpe('overflow', lambda a, b:a*b, by16, by16) + assert_raises_fpe('overflow', lambda a, b:a/b, bx16, sx16) + assert_raises_fpe('overflow', lambda a, b:a/b, bx16, sy16) + assert_raises_fpe('overflow', lambda a, b:a/b, by16, sx16) + assert_raises_fpe('overflow', lambda a, b:a/b, by16, sy16) + assert_raises_fpe('overflow', lambda a, b:a+b, + float16(65504), float16(17)) + assert_raises_fpe('overflow', lambda a, b:a-b, + float16(-65504), float16(17)) + assert_raises_fpe('overflow', np.nextafter, float16(65504), float16(np.inf)) + assert_raises_fpe('overflow', np.nextafter, float16(-65504), float16(-np.inf)) + assert_raises_fpe('overflow', np.spacing, float16(65504)) + + # Invalid value errors + assert_raises_fpe('invalid', np.divide, float16(np.inf), float16(np.inf)) + assert_raises_fpe('invalid', np.spacing, float16(np.inf)) + assert_raises_fpe('invalid', np.spacing, float16(np.nan)) + + # These should not raise + float16(65472)+float16(32) + float16(2**-13)/float16(2) + float16(2**-14)/float16(2**10) + np.spacing(float16(-65504)) + np.nextafter(float16(65504), float16(-np.inf)) + np.nextafter(float16(-65504), float16(np.inf)) + np.nextafter(float16(np.inf), float16(0)) + np.nextafter(float16(-np.inf), float16(0)) + np.nextafter(float16(0), float16(np.nan)) + np.nextafter(float16(np.nan), float16(0)) + float16(2**-14)/float16(2**10) + float16(-2**-14)/float16(2**10) + float16(2**-14+2**-23)/float16(2) + float16(-2**-14-2**-23)/float16(2) + + def test_half_array_interface(self): + """Test that half is compatible with __array_interface__""" + class Dummy: + pass + + a = np.ones((1,), dtype=float16) + b = Dummy() + b.__array_interface__ = a.__array_interface__ + c = np.array(b) + assert_(c.dtype == float16) + assert_equal(a, c) diff --git a/venv/Lib/site-packages/numpy/core/tests/test_indexerrors.py b/venv/Lib/site-packages/numpy/core/tests/test_indexerrors.py new file mode 100644 index 0000000..a0e9a8c --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/tests/test_indexerrors.py @@ -0,0 +1,133 @@ +import numpy as np +from numpy.testing import ( + assert_raises, assert_raises_regex, + ) + + +class TestIndexErrors: + '''Tests to exercise indexerrors not covered by other tests.''' + + def test_arraytypes_fasttake(self): + 'take from a 0-length dimension' + x = np.empty((2, 3, 0, 4)) + assert_raises(IndexError, x.take, [0], axis=2) + assert_raises(IndexError, x.take, [1], axis=2) + assert_raises(IndexError, x.take, [0], axis=2, mode='wrap') + assert_raises(IndexError, x.take, [0], axis=2, mode='clip') + + def test_take_from_object(self): + # Check exception taking from object array + d = np.zeros(5, dtype=object) + assert_raises(IndexError, d.take, [6]) + + # Check exception taking from 0-d array + d = np.zeros((5, 0), dtype=object) + assert_raises(IndexError, d.take, [1], axis=1) + assert_raises(IndexError, d.take, [0], axis=1) + assert_raises(IndexError, d.take, [0]) + assert_raises(IndexError, d.take, [0], mode='wrap') + assert_raises(IndexError, d.take, [0], mode='clip') + + def test_multiindex_exceptions(self): + a = np.empty(5, dtype=object) + assert_raises(IndexError, a.item, 20) + a = np.empty((5, 0), dtype=object) + assert_raises(IndexError, a.item, (0, 0)) + + a = np.empty(5, dtype=object) + assert_raises(IndexError, a.itemset, 20, 0) + a = np.empty((5, 0), dtype=object) + assert_raises(IndexError, a.itemset, (0, 0), 0) + + def test_put_exceptions(self): + a = np.zeros((5, 5)) + assert_raises(IndexError, a.put, 100, 0) + a = np.zeros((5, 5), dtype=object) + assert_raises(IndexError, a.put, 100, 0) + a = np.zeros((5, 5, 0)) + assert_raises(IndexError, a.put, 100, 0) + a = np.zeros((5, 5, 0), dtype=object) + assert_raises(IndexError, a.put, 100, 0) + + def test_iterators_exceptions(self): + "cases in iterators.c" + def assign(obj, ind, val): + obj[ind] = val + + a = np.zeros([1, 2, 3]) + assert_raises(IndexError, lambda: a[0, 5, None, 2]) + assert_raises(IndexError, lambda: a[0, 5, 0, 2]) + assert_raises(IndexError, lambda: assign(a, (0, 5, None, 2), 1)) + assert_raises(IndexError, lambda: assign(a, (0, 5, 0, 2), 1)) + + a = np.zeros([1, 0, 3]) + assert_raises(IndexError, lambda: a[0, 0, None, 2]) + assert_raises(IndexError, lambda: assign(a, (0, 0, None, 2), 1)) + + a = np.zeros([1, 2, 3]) + assert_raises(IndexError, lambda: a.flat[10]) + assert_raises(IndexError, lambda: assign(a.flat, 10, 5)) + a = np.zeros([1, 0, 3]) + assert_raises(IndexError, lambda: a.flat[10]) + assert_raises(IndexError, lambda: assign(a.flat, 10, 5)) + + a = np.zeros([1, 2, 3]) + assert_raises(IndexError, lambda: a.flat[np.array(10)]) + assert_raises(IndexError, lambda: assign(a.flat, np.array(10), 5)) + a = np.zeros([1, 0, 3]) + assert_raises(IndexError, lambda: a.flat[np.array(10)]) + assert_raises(IndexError, lambda: assign(a.flat, np.array(10), 5)) + + a = np.zeros([1, 2, 3]) + assert_raises(IndexError, lambda: a.flat[np.array([10])]) + assert_raises(IndexError, lambda: assign(a.flat, np.array([10]), 5)) + a = np.zeros([1, 0, 3]) + assert_raises(IndexError, lambda: a.flat[np.array([10])]) + assert_raises(IndexError, lambda: assign(a.flat, np.array([10]), 5)) + + def test_mapping(self): + "cases from mapping.c" + + def assign(obj, ind, val): + obj[ind] = val + + a = np.zeros((0, 10)) + assert_raises(IndexError, lambda: a[12]) + + a = np.zeros((3, 5)) + assert_raises(IndexError, lambda: a[(10, 20)]) + assert_raises(IndexError, lambda: assign(a, (10, 20), 1)) + a = np.zeros((3, 0)) + assert_raises(IndexError, lambda: a[(1, 0)]) + assert_raises(IndexError, lambda: assign(a, (1, 0), 1)) + + a = np.zeros((10,)) + assert_raises(IndexError, lambda: assign(a, 10, 1)) + a = np.zeros((0,)) + assert_raises(IndexError, lambda: assign(a, 10, 1)) + + a = np.zeros((3, 5)) + assert_raises(IndexError, lambda: a[(1, [1, 20])]) + assert_raises(IndexError, lambda: assign(a, (1, [1, 20]), 1)) + a = np.zeros((3, 0)) + assert_raises(IndexError, lambda: a[(1, [0, 1])]) + assert_raises(IndexError, lambda: assign(a, (1, [0, 1]), 1)) + + def test_mapping_error_message(self): + a = np.zeros((3, 5)) + index = (1, 2, 3, 4, 5) + assert_raises_regex( + IndexError, + "too many indices for array: " + "array is 2-dimensional, but 5 were indexed", + lambda: a[index]) + + def test_methods(self): + "cases from methods.c" + + a = np.zeros((3, 3)) + assert_raises(IndexError, lambda: a.item(100)) + assert_raises(IndexError, lambda: a.itemset(100, 1)) + a = np.zeros((0, 3)) + assert_raises(IndexError, lambda: a.item(100)) + assert_raises(IndexError, lambda: a.itemset(100, 1)) diff --git a/venv/Lib/site-packages/numpy/core/tests/test_indexing.py b/venv/Lib/site-packages/numpy/core/tests/test_indexing.py new file mode 100644 index 0000000..57b1f38 --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/tests/test_indexing.py @@ -0,0 +1,1395 @@ +import sys +import warnings +import functools +import operator + +import pytest + +import numpy as np +from numpy.core._multiarray_tests import array_indexing +from itertools import product +from numpy.testing import ( + assert_, assert_equal, assert_raises, assert_raises_regex, + assert_array_equal, assert_warns, HAS_REFCOUNT, + ) + + +class TestIndexing: + def test_index_no_floats(self): + a = np.array([[[5]]]) + + assert_raises(IndexError, lambda: a[0.0]) + assert_raises(IndexError, lambda: a[0, 0.0]) + assert_raises(IndexError, lambda: a[0.0, 0]) + assert_raises(IndexError, lambda: a[0.0,:]) + assert_raises(IndexError, lambda: a[:, 0.0]) + assert_raises(IndexError, lambda: a[:, 0.0,:]) + assert_raises(IndexError, lambda: a[0.0,:,:]) + assert_raises(IndexError, lambda: a[0, 0, 0.0]) + assert_raises(IndexError, lambda: a[0.0, 0, 0]) + assert_raises(IndexError, lambda: a[0, 0.0, 0]) + assert_raises(IndexError, lambda: a[-1.4]) + assert_raises(IndexError, lambda: a[0, -1.4]) + assert_raises(IndexError, lambda: a[-1.4, 0]) + assert_raises(IndexError, lambda: a[-1.4,:]) + assert_raises(IndexError, lambda: a[:, -1.4]) + assert_raises(IndexError, lambda: a[:, -1.4,:]) + assert_raises(IndexError, lambda: a[-1.4,:,:]) + assert_raises(IndexError, lambda: a[0, 0, -1.4]) + assert_raises(IndexError, lambda: a[-1.4, 0, 0]) + assert_raises(IndexError, lambda: a[0, -1.4, 0]) + assert_raises(IndexError, lambda: a[0.0:, 0.0]) + assert_raises(IndexError, lambda: a[0.0:, 0.0,:]) + + def test_slicing_no_floats(self): + a = np.array([[5]]) + + # start as float. + assert_raises(TypeError, lambda: a[0.0:]) + assert_raises(TypeError, lambda: a[0:, 0.0:2]) + assert_raises(TypeError, lambda: a[0.0::2, :0]) + assert_raises(TypeError, lambda: a[0.0:1:2,:]) + assert_raises(TypeError, lambda: a[:, 0.0:]) + # stop as float. + assert_raises(TypeError, lambda: a[:0.0]) + assert_raises(TypeError, lambda: a[:0, 1:2.0]) + assert_raises(TypeError, lambda: a[:0.0:2, :0]) + assert_raises(TypeError, lambda: a[:0.0,:]) + assert_raises(TypeError, lambda: a[:, 0:4.0:2]) + # step as float. + assert_raises(TypeError, lambda: a[::1.0]) + assert_raises(TypeError, lambda: a[0:, :2:2.0]) + assert_raises(TypeError, lambda: a[1::4.0, :0]) + assert_raises(TypeError, lambda: a[::5.0,:]) + assert_raises(TypeError, lambda: a[:, 0:4:2.0]) + # mixed. + assert_raises(TypeError, lambda: a[1.0:2:2.0]) + assert_raises(TypeError, lambda: a[1.0::2.0]) + assert_raises(TypeError, lambda: a[0:, :2.0:2.0]) + assert_raises(TypeError, lambda: a[1.0:1:4.0, :0]) + assert_raises(TypeError, lambda: a[1.0:5.0:5.0,:]) + assert_raises(TypeError, lambda: a[:, 0.4:4.0:2.0]) + # should still get the DeprecationWarning if step = 0. + assert_raises(TypeError, lambda: a[::0.0]) + + def test_index_no_array_to_index(self): + # No non-scalar arrays. + a = np.array([[[1]]]) + + assert_raises(TypeError, lambda: a[a:a:a]) + + def test_none_index(self): + # `None` index adds newaxis + a = np.array([1, 2, 3]) + assert_equal(a[None], a[np.newaxis]) + assert_equal(a[None].ndim, a.ndim + 1) + + def test_empty_tuple_index(self): + # Empty tuple index creates a view + a = np.array([1, 2, 3]) + assert_equal(a[()], a) + assert_(a[()].base is a) + a = np.array(0) + assert_(isinstance(a[()], np.int_)) + + def test_void_scalar_empty_tuple(self): + s = np.zeros((), dtype='V4') + assert_equal(s[()].dtype, s.dtype) + assert_equal(s[()], s) + assert_equal(type(s[...]), np.ndarray) + + def test_same_kind_index_casting(self): + # Indexes should be cast with same-kind and not safe, even if that + # is somewhat unsafe. So test various different code paths. + index = np.arange(5) + u_index = index.astype(np.uintp) + arr = np.arange(10) + + assert_array_equal(arr[index], arr[u_index]) + arr[u_index] = np.arange(5) + assert_array_equal(arr, np.arange(10)) + + arr = np.arange(10).reshape(5, 2) + assert_array_equal(arr[index], arr[u_index]) + + arr[u_index] = np.arange(5)[:,None] + assert_array_equal(arr, np.arange(5)[:,None].repeat(2, axis=1)) + + arr = np.arange(25).reshape(5, 5) + assert_array_equal(arr[u_index, u_index], arr[index, index]) + + def test_empty_fancy_index(self): + # Empty list index creates an empty array + # with the same dtype (but with weird shape) + a = np.array([1, 2, 3]) + assert_equal(a[[]], []) + assert_equal(a[[]].dtype, a.dtype) + + b = np.array([], dtype=np.intp) + assert_equal(a[[]], []) + assert_equal(a[[]].dtype, a.dtype) + + b = np.array([]) + assert_raises(IndexError, a.__getitem__, b) + + def test_ellipsis_index(self): + a = np.array([[1, 2, 3], + [4, 5, 6], + [7, 8, 9]]) + assert_(a[...] is not a) + assert_equal(a[...], a) + # `a[...]` was `a` in numpy <1.9. + assert_(a[...].base is a) + + # Slicing with ellipsis can skip an + # arbitrary number of dimensions + assert_equal(a[0, ...], a[0]) + assert_equal(a[0, ...], a[0,:]) + assert_equal(a[..., 0], a[:, 0]) + + # Slicing with ellipsis always results + # in an array, not a scalar + assert_equal(a[0, ..., 1], np.array(2)) + + # Assignment with `(Ellipsis,)` on 0-d arrays + b = np.array(1) + b[(Ellipsis,)] = 2 + assert_equal(b, 2) + + def test_single_int_index(self): + # Single integer index selects one row + a = np.array([[1, 2, 3], + [4, 5, 6], + [7, 8, 9]]) + + assert_equal(a[0], [1, 2, 3]) + assert_equal(a[-1], [7, 8, 9]) + + # Index out of bounds produces IndexError + assert_raises(IndexError, a.__getitem__, 1 << 30) + # Index overflow produces IndexError + assert_raises(IndexError, a.__getitem__, 1 << 64) + + def test_single_bool_index(self): + # Single boolean index + a = np.array([[1, 2, 3], + [4, 5, 6], + [7, 8, 9]]) + + assert_equal(a[np.array(True)], a[None]) + assert_equal(a[np.array(False)], a[None][0:0]) + + def test_boolean_shape_mismatch(self): + arr = np.ones((5, 4, 3)) + + index = np.array([True]) + assert_raises(IndexError, arr.__getitem__, index) + + index = np.array([False] * 6) + assert_raises(IndexError, arr.__getitem__, index) + + index = np.zeros((4, 4), dtype=bool) + assert_raises(IndexError, arr.__getitem__, index) + + assert_raises(IndexError, arr.__getitem__, (slice(None), index)) + + def test_boolean_indexing_onedim(self): + # Indexing a 2-dimensional array with + # boolean array of length one + a = np.array([[ 0., 0., 0.]]) + b = np.array([ True], dtype=bool) + assert_equal(a[b], a) + # boolean assignment + a[b] = 1. + assert_equal(a, [[1., 1., 1.]]) + + def test_boolean_assignment_value_mismatch(self): + # A boolean assignment should fail when the shape of the values + # cannot be broadcast to the subscription. (see also gh-3458) + a = np.arange(4) + + def f(a, v): + a[a > -1] = v + + assert_raises(ValueError, f, a, []) + assert_raises(ValueError, f, a, [1, 2, 3]) + assert_raises(ValueError, f, a[:1], [1, 2, 3]) + + def test_boolean_assignment_needs_api(self): + # See also gh-7666 + # This caused a segfault on Python 2 due to the GIL not being + # held when the iterator does not need it, but the transfer function + # does + arr = np.zeros(1000) + indx = np.zeros(1000, dtype=bool) + indx[:100] = True + arr[indx] = np.ones(100, dtype=object) + + expected = np.zeros(1000) + expected[:100] = 1 + assert_array_equal(arr, expected) + + def test_boolean_indexing_twodim(self): + # Indexing a 2-dimensional array with + # 2-dimensional boolean array + a = np.array([[1, 2, 3], + [4, 5, 6], + [7, 8, 9]]) + b = np.array([[ True, False, True], + [False, True, False], + [ True, False, True]]) + assert_equal(a[b], [1, 3, 5, 7, 9]) + assert_equal(a[b[1]], [[4, 5, 6]]) + assert_equal(a[b[0]], a[b[2]]) + + # boolean assignment + a[b] = 0 + assert_equal(a, [[0, 2, 0], + [4, 0, 6], + [0, 8, 0]]) + + def test_boolean_indexing_list(self): + # Regression test for #13715. It's a use-after-free bug which the + # test won't directly catch, but it will show up in valgrind. + a = np.array([1, 2, 3]) + b = [True, False, True] + # Two variants of the test because the first takes a fast path + assert_equal(a[b], [1, 3]) + assert_equal(a[None, b], [[1, 3]]) + + def test_reverse_strides_and_subspace_bufferinit(self): + # This tests that the strides are not reversed for simple and + # subspace fancy indexing. + a = np.ones(5) + b = np.zeros(5, dtype=np.intp)[::-1] + c = np.arange(5)[::-1] + + a[b] = c + # If the strides are not reversed, the 0 in the arange comes last. + assert_equal(a[0], 0) + + # This also tests that the subspace buffer is initialized: + a = np.ones((5, 2)) + c = np.arange(10).reshape(5, 2)[::-1] + a[b, :] = c + assert_equal(a[0], [0, 1]) + + def test_reversed_strides_result_allocation(self): + # Test a bug when calculating the output strides for a result array + # when the subspace size was 1 (and test other cases as well) + a = np.arange(10)[:, None] + i = np.arange(10)[::-1] + assert_array_equal(a[i], a[i.copy('C')]) + + a = np.arange(20).reshape(-1, 2) + + def test_uncontiguous_subspace_assignment(self): + # During development there was a bug activating a skip logic + # based on ndim instead of size. + a = np.full((3, 4, 2), -1) + b = np.full((3, 4, 2), -1) + + a[[0, 1]] = np.arange(2 * 4 * 2).reshape(2, 4, 2).T + b[[0, 1]] = np.arange(2 * 4 * 2).reshape(2, 4, 2).T.copy() + + assert_equal(a, b) + + def test_too_many_fancy_indices_special_case(self): + # Just documents behaviour, this is a small limitation. + a = np.ones((1,) * 32) # 32 is NPY_MAXDIMS + assert_raises(IndexError, a.__getitem__, (np.array([0]),) * 32) + + def test_scalar_array_bool(self): + # NumPy bools can be used as boolean index (python ones as of yet not) + a = np.array(1) + assert_equal(a[np.bool_(True)], a[np.array(True)]) + assert_equal(a[np.bool_(False)], a[np.array(False)]) + + # After deprecating bools as integers: + #a = np.array([0,1,2]) + #assert_equal(a[True, :], a[None, :]) + #assert_equal(a[:, True], a[:, None]) + # + #assert_(not np.may_share_memory(a, a[True, :])) + + def test_everything_returns_views(self): + # Before `...` would return a itself. + a = np.arange(5) + + assert_(a is not a[()]) + assert_(a is not a[...]) + assert_(a is not a[:]) + + def test_broaderrors_indexing(self): + a = np.zeros((5, 5)) + assert_raises(IndexError, a.__getitem__, ([0, 1], [0, 1, 2])) + assert_raises(IndexError, a.__setitem__, ([0, 1], [0, 1, 2]), 0) + + def test_trivial_fancy_out_of_bounds(self): + a = np.zeros(5) + ind = np.ones(20, dtype=np.intp) + ind[-1] = 10 + assert_raises(IndexError, a.__getitem__, ind) + assert_raises(IndexError, a.__setitem__, ind, 0) + ind = np.ones(20, dtype=np.intp) + ind[0] = 11 + assert_raises(IndexError, a.__getitem__, ind) + assert_raises(IndexError, a.__setitem__, ind, 0) + + def test_trivial_fancy_not_possible(self): + # Test that the fast path for trivial assignment is not incorrectly + # used when the index is not contiguous or 1D, see also gh-11467. + a = np.arange(6) + idx = np.arange(6, dtype=np.intp).reshape(2, 1, 3)[:, :, 0] + assert_array_equal(a[idx], idx) + + # this case must not go into the fast path, note that idx is + # a non-contiuguous none 1D array here. + a[idx] = -1 + res = np.arange(6) + res[0] = -1 + res[3] = -1 + assert_array_equal(a, res) + + def test_nonbaseclass_values(self): + class SubClass(np.ndarray): + def __array_finalize__(self, old): + # Have array finalize do funny things + self.fill(99) + + a = np.zeros((5, 5)) + s = a.copy().view(type=SubClass) + s.fill(1) + + a[[0, 1, 2, 3, 4], :] = s + assert_((a == 1).all()) + + # Subspace is last, so transposing might want to finalize + a[:, [0, 1, 2, 3, 4]] = s + assert_((a == 1).all()) + + a.fill(0) + a[...] = s + assert_((a == 1).all()) + + def test_array_like_values(self): + # Similar to the above test, but use a memoryview instead + a = np.zeros((5, 5)) + s = np.arange(25, dtype=np.float64).reshape(5, 5) + + a[[0, 1, 2, 3, 4], :] = memoryview(s) + assert_array_equal(a, s) + + a[:, [0, 1, 2, 3, 4]] = memoryview(s) + assert_array_equal(a, s) + + a[...] = memoryview(s) + assert_array_equal(a, s) + + def test_subclass_writeable(self): + d = np.rec.array([('NGC1001', 11), ('NGC1002', 1.), ('NGC1003', 1.)], + dtype=[('target', 'S20'), ('V_mag', '>f4')]) + ind = np.array([False, True, True], dtype=bool) + assert_(d[ind].flags.writeable) + ind = np.array([0, 1]) + assert_(d[ind].flags.writeable) + assert_(d[...].flags.writeable) + assert_(d[0].flags.writeable) + + def test_memory_order(self): + # This is not necessary to preserve. Memory layouts for + # more complex indices are not as simple. + a = np.arange(10) + b = np.arange(10).reshape(5,2).T + assert_(a[b].flags.f_contiguous) + + # Takes a different implementation branch: + a = a.reshape(-1, 1) + assert_(a[b, 0].flags.f_contiguous) + + def test_scalar_return_type(self): + # Full scalar indices should return scalars and object + # arrays should not call PyArray_Return on their items + class Zero: + # The most basic valid indexing + def __index__(self): + return 0 + + z = Zero() + + class ArrayLike: + # Simple array, should behave like the array + def __array__(self): + return np.array(0) + + a = np.zeros(()) + assert_(isinstance(a[()], np.float_)) + a = np.zeros(1) + assert_(isinstance(a[z], np.float_)) + a = np.zeros((1, 1)) + assert_(isinstance(a[z, np.array(0)], np.float_)) + assert_(isinstance(a[z, ArrayLike()], np.float_)) + + # And object arrays do not call it too often: + b = np.array(0) + a = np.array(0, dtype=object) + a[()] = b + assert_(isinstance(a[()], np.ndarray)) + a = np.array([b, None]) + assert_(isinstance(a[z], np.ndarray)) + a = np.array([[b, None]]) + assert_(isinstance(a[z, np.array(0)], np.ndarray)) + assert_(isinstance(a[z, ArrayLike()], np.ndarray)) + + def test_small_regressions(self): + # Reference count of intp for index checks + a = np.array([0]) + if HAS_REFCOUNT: + refcount = sys.getrefcount(np.dtype(np.intp)) + # item setting always checks indices in separate function: + a[np.array([0], dtype=np.intp)] = 1 + a[np.array([0], dtype=np.uint8)] = 1 + assert_raises(IndexError, a.__setitem__, + np.array([1], dtype=np.intp), 1) + assert_raises(IndexError, a.__setitem__, + np.array([1], dtype=np.uint8), 1) + + if HAS_REFCOUNT: + assert_equal(sys.getrefcount(np.dtype(np.intp)), refcount) + + def test_unaligned(self): + v = (np.zeros(64, dtype=np.int8) + ord('a'))[1:-7] + d = v.view(np.dtype("S8")) + # unaligned source + x = (np.zeros(16, dtype=np.int8) + ord('a'))[1:-7] + x = x.view(np.dtype("S8")) + x[...] = np.array("b" * 8, dtype="S") + b = np.arange(d.size) + #trivial + assert_equal(d[b], d) + d[b] = x + # nontrivial + # unaligned index array + b = np.zeros(d.size + 1).view(np.int8)[1:-(np.intp(0).itemsize - 1)] + b = b.view(np.intp)[:d.size] + b[...] = np.arange(d.size) + assert_equal(d[b.astype(np.int16)], d) + d[b.astype(np.int16)] = x + # boolean + d[b % 2 == 0] + d[b % 2 == 0] = x[::2] + + def test_tuple_subclass(self): + arr = np.ones((5, 5)) + + # A tuple subclass should also be an nd-index + class TupleSubclass(tuple): + pass + index = ([1], [1]) + index = TupleSubclass(index) + assert_(arr[index].shape == (1,)) + # Unlike the non nd-index: + assert_(arr[index,].shape != (1,)) + + def test_broken_sequence_not_nd_index(self): + # See gh-5063: + # If we have an object which claims to be a sequence, but fails + # on item getting, this should not be converted to an nd-index (tuple) + # If this object happens to be a valid index otherwise, it should work + # This object here is very dubious and probably bad though: + class SequenceLike: + def __index__(self): + return 0 + + def __len__(self): + return 1 + + def __getitem__(self, item): + raise IndexError('Not possible') + + arr = np.arange(10) + assert_array_equal(arr[SequenceLike()], arr[SequenceLike(),]) + + # also test that field indexing does not segfault + # for a similar reason, by indexing a structured array + arr = np.zeros((1,), dtype=[('f1', 'i8'), ('f2', 'i8')]) + assert_array_equal(arr[SequenceLike()], arr[SequenceLike(),]) + + def test_indexing_array_weird_strides(self): + # See also gh-6221 + # the shapes used here come from the issue and create the correct + # size for the iterator buffering size. + x = np.ones(10) + x2 = np.ones((10, 2)) + ind = np.arange(10)[:, None, None, None] + ind = np.broadcast_to(ind, (10, 55, 4, 4)) + + # single advanced index case + assert_array_equal(x[ind], x[ind.copy()]) + # higher dimensional advanced index + zind = np.zeros(4, dtype=np.intp) + assert_array_equal(x2[ind, zind], x2[ind.copy(), zind]) + + def test_indexing_array_negative_strides(self): + # From gh-8264, + # core dumps if negative strides are used in iteration + arro = np.zeros((4, 4)) + arr = arro[::-1, ::-1] + + slices = (slice(None), [0, 1, 2, 3]) + arr[slices] = 10 + assert_array_equal(arr, 10.) + + def test_character_assignment(self): + # This is an example a function going through CopyObject which + # used to have an untested special path for scalars + # (the character special dtype case, should be deprecated probably) + arr = np.zeros((1, 5), dtype="c") + arr[0] = np.str_("asdfg") # must assign as a sequence + assert_array_equal(arr[0], np.array("asdfg", dtype="c")) + assert arr[0, 1] == b"s" # make sure not all were set to "a" for both + + @pytest.mark.parametrize("index", + [True, False, np.array([0])]) + @pytest.mark.parametrize("num", [32, 40]) + @pytest.mark.parametrize("original_ndim", [1, 32]) + def test_too_many_advanced_indices(self, index, num, original_ndim): + # These are limitations based on the number of arguments we can process. + # For `num=32` (and all boolean cases), the result is actually define; + # but the use of NpyIter (NPY_MAXARGS) limits it for technical reasons. + arr = np.ones((1,) * original_ndim) + with pytest.raises(IndexError): + arr[(index,) * num] + with pytest.raises(IndexError): + arr[(index,) * num] = 1. + + def test_structured_advanced_indexing(self): + # Test that copyswap(n) used by integer array indexing is threadsafe + # for structured datatypes, see gh-15387. This test can behave randomly. + from concurrent.futures import ThreadPoolExecutor + + # Create a deeply nested dtype to make a failure more likely: + dt = np.dtype([("", "f8")]) + dt = np.dtype([("", dt)] * 2) + dt = np.dtype([("", dt)] * 2) + # The array should be large enough to likely run into threading issues + arr = np.random.uniform(size=(6000, 8)).view(dt)[:, 0] + + rng = np.random.default_rng() + def func(arr): + indx = rng.integers(0, len(arr), size=6000, dtype=np.intp) + arr[indx] + + tpe = ThreadPoolExecutor(max_workers=8) + futures = [tpe.submit(func, arr) for _ in range(10)] + for f in futures: + f.result() + + assert arr.dtype is dt + + +class TestFieldIndexing: + def test_scalar_return_type(self): + # Field access on an array should return an array, even if it + # is 0-d. + a = np.zeros((), [('a','f8')]) + assert_(isinstance(a['a'], np.ndarray)) + assert_(isinstance(a[['a']], np.ndarray)) + + +class TestBroadcastedAssignments: + def assign(self, a, ind, val): + a[ind] = val + return a + + def test_prepending_ones(self): + a = np.zeros((3, 2)) + + a[...] = np.ones((1, 3, 2)) + # Fancy with subspace with and without transpose + a[[0, 1, 2], :] = np.ones((1, 3, 2)) + a[:, [0, 1]] = np.ones((1, 3, 2)) + # Fancy without subspace (with broadcasting) + a[[[0], [1], [2]], [0, 1]] = np.ones((1, 3, 2)) + + def test_prepend_not_one(self): + assign = self.assign + s_ = np.s_ + a = np.zeros(5) + + # Too large and not only ones. + assert_raises(ValueError, assign, a, s_[...], np.ones((2, 1))) + assert_raises(ValueError, assign, a, s_[[1, 2, 3],], np.ones((2, 1))) + assert_raises(ValueError, assign, a, s_[[[1], [2]],], np.ones((2,2,1))) + + def test_simple_broadcasting_errors(self): + assign = self.assign + s_ = np.s_ + a = np.zeros((5, 1)) + + assert_raises(ValueError, assign, a, s_[...], np.zeros((5, 2))) + assert_raises(ValueError, assign, a, s_[...], np.zeros((5, 0))) + assert_raises(ValueError, assign, a, s_[:, [0]], np.zeros((5, 2))) + assert_raises(ValueError, assign, a, s_[:, [0]], np.zeros((5, 0))) + assert_raises(ValueError, assign, a, s_[[0], :], np.zeros((2, 1))) + + def test_index_is_larger(self): + # Simple case of fancy index broadcasting of the index. + a = np.zeros((5, 5)) + a[[[0], [1], [2]], [0, 1, 2]] = [2, 3, 4] + + assert_((a[:3, :3] == [2, 3, 4]).all()) + + def test_broadcast_subspace(self): + a = np.zeros((100, 100)) + v = np.arange(100)[:,None] + b = np.arange(100)[::-1] + a[b] = v + assert_((a[::-1] == v).all()) + + +class TestSubclasses: + def test_basic(self): + # Test that indexing in various ways produces SubClass instances, + # and that the base is set up correctly: the original subclass + # instance for views, and a new ndarray for advanced/boolean indexing + # where a copy was made (latter a regression test for gh-11983). + class SubClass(np.ndarray): + pass + + a = np.arange(5) + s = a.view(SubClass) + s_slice = s[:3] + assert_(type(s_slice) is SubClass) + assert_(s_slice.base is s) + assert_array_equal(s_slice, a[:3]) + + s_fancy = s[[0, 1, 2]] + assert_(type(s_fancy) is SubClass) + assert_(s_fancy.base is not s) + assert_(type(s_fancy.base) is np.ndarray) + assert_array_equal(s_fancy, a[[0, 1, 2]]) + assert_array_equal(s_fancy.base, a[[0, 1, 2]]) + + s_bool = s[s > 0] + assert_(type(s_bool) is SubClass) + assert_(s_bool.base is not s) + assert_(type(s_bool.base) is np.ndarray) + assert_array_equal(s_bool, a[a > 0]) + assert_array_equal(s_bool.base, a[a > 0]) + + def test_fancy_on_read_only(self): + # Test that fancy indexing on read-only SubClass does not make a + # read-only copy (gh-14132) + class SubClass(np.ndarray): + pass + + a = np.arange(5) + s = a.view(SubClass) + s.flags.writeable = False + s_fancy = s[[0, 1, 2]] + assert_(s_fancy.flags.writeable) + + + def test_finalize_gets_full_info(self): + # Array finalize should be called on the filled array. + class SubClass(np.ndarray): + def __array_finalize__(self, old): + self.finalize_status = np.array(self) + self.old = old + + s = np.arange(10).view(SubClass) + new_s = s[:3] + assert_array_equal(new_s.finalize_status, new_s) + assert_array_equal(new_s.old, s) + + new_s = s[[0,1,2,3]] + assert_array_equal(new_s.finalize_status, new_s) + assert_array_equal(new_s.old, s) + + new_s = s[s > 0] + assert_array_equal(new_s.finalize_status, new_s) + assert_array_equal(new_s.old, s) + + +class TestFancyIndexingCast: + def test_boolean_index_cast_assign(self): + # Setup the boolean index and float arrays. + shape = (8, 63) + bool_index = np.zeros(shape).astype(bool) + bool_index[0, 1] = True + zero_array = np.zeros(shape) + + # Assigning float is fine. + zero_array[bool_index] = np.array([1]) + assert_equal(zero_array[0, 1], 1) + + # Fancy indexing works, although we get a cast warning. + assert_warns(np.ComplexWarning, + zero_array.__setitem__, ([0], [1]), np.array([2 + 1j])) + assert_equal(zero_array[0, 1], 2) # No complex part + + # Cast complex to float, throwing away the imaginary portion. + assert_warns(np.ComplexWarning, + zero_array.__setitem__, bool_index, np.array([1j])) + assert_equal(zero_array[0, 1], 0) + +class TestFancyIndexingEquivalence: + def test_object_assign(self): + # Check that the field and object special case using copyto is active. + # The right hand side cannot be converted to an array here. + a = np.arange(5, dtype=object) + b = a.copy() + a[:3] = [1, (1,2), 3] + b[[0, 1, 2]] = [1, (1,2), 3] + assert_array_equal(a, b) + + # test same for subspace fancy indexing + b = np.arange(5, dtype=object)[None, :] + b[[0], :3] = [[1, (1,2), 3]] + assert_array_equal(a, b[0]) + + # Check that swapping of axes works. + # There was a bug that made the later assignment throw a ValueError + # do to an incorrectly transposed temporary right hand side (gh-5714) + b = b.T + b[:3, [0]] = [[1], [(1,2)], [3]] + assert_array_equal(a, b[:, 0]) + + # Another test for the memory order of the subspace + arr = np.ones((3, 4, 5), dtype=object) + # Equivalent slicing assignment for comparison + cmp_arr = arr.copy() + cmp_arr[:1, ...] = [[[1], [2], [3], [4]]] + arr[[0], ...] = [[[1], [2], [3], [4]]] + assert_array_equal(arr, cmp_arr) + arr = arr.copy('F') + arr[[0], ...] = [[[1], [2], [3], [4]]] + assert_array_equal(arr, cmp_arr) + + def test_cast_equivalence(self): + # Yes, normal slicing uses unsafe casting. + a = np.arange(5) + b = a.copy() + + a[:3] = np.array(['2', '-3', '-1']) + b[[0, 2, 1]] = np.array(['2', '-1', '-3']) + assert_array_equal(a, b) + + # test the same for subspace fancy indexing + b = np.arange(5)[None, :] + b[[0], :3] = np.array([['2', '-3', '-1']]) + assert_array_equal(a, b[0]) + + +class TestMultiIndexingAutomated: + """ + These tests use code to mimic the C-Code indexing for selection. + + NOTE: + + * This still lacks tests for complex item setting. + * If you change behavior of indexing, you might want to modify + these tests to try more combinations. + * Behavior was written to match numpy version 1.8. (though a + first version matched 1.7.) + * Only tuple indices are supported by the mimicking code. + (and tested as of writing this) + * Error types should match most of the time as long as there + is only one error. For multiple errors, what gets raised + will usually not be the same one. They are *not* tested. + + Update 2016-11-30: It is probably not worth maintaining this test + indefinitely and it can be dropped if maintenance becomes a burden. + + """ + + def setup(self): + self.a = np.arange(np.prod([3, 1, 5, 6])).reshape(3, 1, 5, 6) + self.b = np.empty((3, 0, 5, 6)) + self.complex_indices = ['skip', Ellipsis, + 0, + # Boolean indices, up to 3-d for some special cases of eating up + # dimensions, also need to test all False + np.array([True, False, False]), + np.array([[True, False], [False, True]]), + np.array([[[False, False], [False, False]]]), + # Some slices: + slice(-5, 5, 2), + slice(1, 1, 100), + slice(4, -1, -2), + slice(None, None, -3), + # Some Fancy indexes: + np.empty((0, 1, 1), dtype=np.intp), # empty and can be broadcast + np.array([0, 1, -2]), + np.array([[2], [0], [1]]), + np.array([[0, -1], [0, 1]], dtype=np.dtype('intp').newbyteorder()), + np.array([2, -1], dtype=np.int8), + np.zeros([1]*31, dtype=int), # trigger too large array. + np.array([0., 1.])] # invalid datatype + # Some simpler indices that still cover a bit more + self.simple_indices = [Ellipsis, None, -1, [1], np.array([True]), + 'skip'] + # Very simple ones to fill the rest: + self.fill_indices = [slice(None, None), 0] + + def _get_multi_index(self, arr, indices): + """Mimic multi dimensional indexing. + + Parameters + ---------- + arr : ndarray + Array to be indexed. + indices : tuple of index objects + + Returns + ------- + out : ndarray + An array equivalent to the indexing operation (but always a copy). + `arr[indices]` should be identical. + no_copy : bool + Whether the indexing operation requires a copy. If this is `True`, + `np.may_share_memory(arr, arr[indices])` should be `True` (with + some exceptions for scalars and possibly 0-d arrays). + + Notes + ----- + While the function may mostly match the errors of normal indexing this + is generally not the case. + """ + in_indices = list(indices) + indices = [] + # if False, this is a fancy or boolean index + no_copy = True + # number of fancy/scalar indexes that are not consecutive + num_fancy = 0 + # number of dimensions indexed by a "fancy" index + fancy_dim = 0 + # NOTE: This is a funny twist (and probably OK to change). + # The boolean array has illegal indexes, but this is + # allowed if the broadcast fancy-indices are 0-sized. + # This variable is to catch that case. + error_unless_broadcast_to_empty = False + + # We need to handle Ellipsis and make arrays from indices, also + # check if this is fancy indexing (set no_copy). + ndim = 0 + ellipsis_pos = None # define here mostly to replace all but first. + for i, indx in enumerate(in_indices): + if indx is None: + continue + if isinstance(indx, np.ndarray) and indx.dtype == bool: + no_copy = False + if indx.ndim == 0: + raise IndexError + # boolean indices can have higher dimensions + ndim += indx.ndim + fancy_dim += indx.ndim + continue + if indx is Ellipsis: + if ellipsis_pos is None: + ellipsis_pos = i + continue # do not increment ndim counter + raise IndexError + if isinstance(indx, slice): + ndim += 1 + continue + if not isinstance(indx, np.ndarray): + # This could be open for changes in numpy. + # numpy should maybe raise an error if casting to intp + # is not safe. It rejects np.array([1., 2.]) but not + # [1., 2.] as index (same for ie. np.take). + # (Note the importance of empty lists if changing this here) + try: + indx = np.array(indx, dtype=np.intp) + except ValueError: + raise IndexError + in_indices[i] = indx + elif indx.dtype.kind != 'b' and indx.dtype.kind != 'i': + raise IndexError('arrays used as indices must be of ' + 'integer (or boolean) type') + if indx.ndim != 0: + no_copy = False + ndim += 1 + fancy_dim += 1 + + if arr.ndim - ndim < 0: + # we can't take more dimensions then we have, not even for 0-d + # arrays. since a[()] makes sense, but not a[(),]. We will + # raise an error later on, unless a broadcasting error occurs + # first. + raise IndexError + + if ndim == 0 and None not in in_indices: + # Well we have no indexes or one Ellipsis. This is legal. + return arr.copy(), no_copy + + if ellipsis_pos is not None: + in_indices[ellipsis_pos:ellipsis_pos+1] = ([slice(None, None)] * + (arr.ndim - ndim)) + + for ax, indx in enumerate(in_indices): + if isinstance(indx, slice): + # convert to an index array + indx = np.arange(*indx.indices(arr.shape[ax])) + indices.append(['s', indx]) + continue + elif indx is None: + # this is like taking a slice with one element from a new axis: + indices.append(['n', np.array([0], dtype=np.intp)]) + arr = arr.reshape((arr.shape[:ax] + (1,) + arr.shape[ax:])) + continue + if isinstance(indx, np.ndarray) and indx.dtype == bool: + if indx.shape != arr.shape[ax:ax+indx.ndim]: + raise IndexError + + try: + flat_indx = np.ravel_multi_index(np.nonzero(indx), + arr.shape[ax:ax+indx.ndim], mode='raise') + except Exception: + error_unless_broadcast_to_empty = True + # fill with 0s instead, and raise error later + flat_indx = np.array([0]*indx.sum(), dtype=np.intp) + # concatenate axis into a single one: + if indx.ndim != 0: + arr = arr.reshape((arr.shape[:ax] + + (np.prod(arr.shape[ax:ax+indx.ndim]),) + + arr.shape[ax+indx.ndim:])) + indx = flat_indx + else: + # This could be changed, a 0-d boolean index can + # make sense (even outside the 0-d indexed array case) + # Note that originally this is could be interpreted as + # integer in the full integer special case. + raise IndexError + else: + # If the index is a singleton, the bounds check is done + # before the broadcasting. This used to be different in <1.9 + if indx.ndim == 0: + if indx >= arr.shape[ax] or indx < -arr.shape[ax]: + raise IndexError + if indx.ndim == 0: + # The index is a scalar. This used to be two fold, but if + # fancy indexing was active, the check was done later, + # possibly after broadcasting it away (1.7. or earlier). + # Now it is always done. + if indx >= arr.shape[ax] or indx < - arr.shape[ax]: + raise IndexError + if (len(indices) > 0 and + indices[-1][0] == 'f' and + ax != ellipsis_pos): + # NOTE: There could still have been a 0-sized Ellipsis + # between them. Checked that with ellipsis_pos. + indices[-1].append(indx) + else: + # We have a fancy index that is not after an existing one. + # NOTE: A 0-d array triggers this as well, while one may + # expect it to not trigger it, since a scalar would not be + # considered fancy indexing. + num_fancy += 1 + indices.append(['f', indx]) + + if num_fancy > 1 and not no_copy: + # We have to flush the fancy indexes left + new_indices = indices[:] + axes = list(range(arr.ndim)) + fancy_axes = [] + new_indices.insert(0, ['f']) + ni = 0 + ai = 0 + for indx in indices: + ni += 1 + if indx[0] == 'f': + new_indices[0].extend(indx[1:]) + del new_indices[ni] + ni -= 1 + for ax in range(ai, ai + len(indx[1:])): + fancy_axes.append(ax) + axes.remove(ax) + ai += len(indx) - 1 # axis we are at + indices = new_indices + # and now we need to transpose arr: + arr = arr.transpose(*(fancy_axes + axes)) + + # We only have one 'f' index now and arr is transposed accordingly. + # Now handle newaxis by reshaping... + ax = 0 + for indx in indices: + if indx[0] == 'f': + if len(indx) == 1: + continue + # First of all, reshape arr to combine fancy axes into one: + orig_shape = arr.shape + orig_slice = orig_shape[ax:ax + len(indx[1:])] + arr = arr.reshape((arr.shape[:ax] + + (np.prod(orig_slice).astype(int),) + + arr.shape[ax + len(indx[1:]):])) + + # Check if broadcasting works + res = np.broadcast(*indx[1:]) + # unfortunately the indices might be out of bounds. So check + # that first, and use mode='wrap' then. However only if + # there are any indices... + if res.size != 0: + if error_unless_broadcast_to_empty: + raise IndexError + for _indx, _size in zip(indx[1:], orig_slice): + if _indx.size == 0: + continue + if np.any(_indx >= _size) or np.any(_indx < -_size): + raise IndexError + if len(indx[1:]) == len(orig_slice): + if np.product(orig_slice) == 0: + # Work around for a crash or IndexError with 'wrap' + # in some 0-sized cases. + try: + mi = np.ravel_multi_index(indx[1:], orig_slice, + mode='raise') + except Exception: + # This happens with 0-sized orig_slice (sometimes?) + # here it is a ValueError, but indexing gives a: + raise IndexError('invalid index into 0-sized') + else: + mi = np.ravel_multi_index(indx[1:], orig_slice, + mode='wrap') + else: + # Maybe never happens... + raise ValueError + arr = arr.take(mi.ravel(), axis=ax) + try: + arr = arr.reshape((arr.shape[:ax] + + mi.shape + + arr.shape[ax+1:])) + except ValueError: + # too many dimensions, probably + raise IndexError + ax += mi.ndim + continue + + # If we are here, we have a 1D array for take: + arr = arr.take(indx[1], axis=ax) + ax += 1 + + return arr, no_copy + + def _check_multi_index(self, arr, index): + """Check a multi index item getting and simple setting. + + Parameters + ---------- + arr : ndarray + Array to be indexed, must be a reshaped arange. + index : tuple of indexing objects + Index being tested. + """ + # Test item getting + try: + mimic_get, no_copy = self._get_multi_index(arr, index) + except Exception as e: + if HAS_REFCOUNT: + prev_refcount = sys.getrefcount(arr) + assert_raises(type(e), arr.__getitem__, index) + assert_raises(type(e), arr.__setitem__, index, 0) + if HAS_REFCOUNT: + assert_equal(prev_refcount, sys.getrefcount(arr)) + return + + self._compare_index_result(arr, index, mimic_get, no_copy) + + def _check_single_index(self, arr, index): + """Check a single index item getting and simple setting. + + Parameters + ---------- + arr : ndarray + Array to be indexed, must be an arange. + index : indexing object + Index being tested. Must be a single index and not a tuple + of indexing objects (see also `_check_multi_index`). + """ + try: + mimic_get, no_copy = self._get_multi_index(arr, (index,)) + except Exception as e: + if HAS_REFCOUNT: + prev_refcount = sys.getrefcount(arr) + assert_raises(type(e), arr.__getitem__, index) + assert_raises(type(e), arr.__setitem__, index, 0) + if HAS_REFCOUNT: + assert_equal(prev_refcount, sys.getrefcount(arr)) + return + + self._compare_index_result(arr, index, mimic_get, no_copy) + + def _compare_index_result(self, arr, index, mimic_get, no_copy): + """Compare mimicked result to indexing result. + """ + arr = arr.copy() + indexed_arr = arr[index] + assert_array_equal(indexed_arr, mimic_get) + # Check if we got a view, unless its a 0-sized or 0-d array. + # (then its not a view, and that does not matter) + if indexed_arr.size != 0 and indexed_arr.ndim != 0: + assert_(np.may_share_memory(indexed_arr, arr) == no_copy) + # Check reference count of the original array + if HAS_REFCOUNT: + if no_copy: + # refcount increases by one: + assert_equal(sys.getrefcount(arr), 3) + else: + assert_equal(sys.getrefcount(arr), 2) + + # Test non-broadcast setitem: + b = arr.copy() + b[index] = mimic_get + 1000 + if b.size == 0: + return # nothing to compare here... + if no_copy and indexed_arr.ndim != 0: + # change indexed_arr in-place to manipulate original: + indexed_arr += 1000 + assert_array_equal(arr, b) + return + # Use the fact that the array is originally an arange: + arr.flat[indexed_arr.ravel()] += 1000 + assert_array_equal(arr, b) + + def test_boolean(self): + a = np.array(5) + assert_equal(a[np.array(True)], 5) + a[np.array(True)] = 1 + assert_equal(a, 1) + # NOTE: This is different from normal broadcasting, as + # arr[boolean_array] works like in a multi index. Which means + # it is aligned to the left. This is probably correct for + # consistency with arr[boolean_array,] also no broadcasting + # is done at all + self._check_multi_index( + self.a, (np.zeros_like(self.a, dtype=bool),)) + self._check_multi_index( + self.a, (np.zeros_like(self.a, dtype=bool)[..., 0],)) + self._check_multi_index( + self.a, (np.zeros_like(self.a, dtype=bool)[None, ...],)) + + def test_multidim(self): + # Automatically test combinations with complex indexes on 2nd (or 1st) + # spot and the simple ones in one other spot. + with warnings.catch_warnings(): + # This is so that np.array(True) is not accepted in a full integer + # index, when running the file separately. + warnings.filterwarnings('error', '', DeprecationWarning) + warnings.filterwarnings('error', '', np.VisibleDeprecationWarning) + + def isskip(idx): + return isinstance(idx, str) and idx == "skip" + + for simple_pos in [0, 2, 3]: + tocheck = [self.fill_indices, self.complex_indices, + self.fill_indices, self.fill_indices] + tocheck[simple_pos] = self.simple_indices + for index in product(*tocheck): + index = tuple(i for i in index if not isskip(i)) + self._check_multi_index(self.a, index) + self._check_multi_index(self.b, index) + + # Check very simple item getting: + self._check_multi_index(self.a, (0, 0, 0, 0)) + self._check_multi_index(self.b, (0, 0, 0, 0)) + # Also check (simple cases of) too many indices: + assert_raises(IndexError, self.a.__getitem__, (0, 0, 0, 0, 0)) + assert_raises(IndexError, self.a.__setitem__, (0, 0, 0, 0, 0), 0) + assert_raises(IndexError, self.a.__getitem__, (0, 0, [1], 0, 0)) + assert_raises(IndexError, self.a.__setitem__, (0, 0, [1], 0, 0), 0) + + def test_1d(self): + a = np.arange(10) + for index in self.complex_indices: + self._check_single_index(a, index) + +class TestFloatNonIntegerArgument: + """ + These test that ``TypeError`` is raised when you try to use + non-integers as arguments to for indexing and slicing e.g. ``a[0.0:5]`` + and ``a[0.5]``, or other functions like ``array.reshape(1., -1)``. + + """ + def test_valid_indexing(self): + # These should raise no errors. + a = np.array([[[5]]]) + + a[np.array([0])] + a[[0, 0]] + a[:, [0, 0]] + a[:, 0,:] + a[:,:,:] + + def test_valid_slicing(self): + # These should raise no errors. + a = np.array([[[5]]]) + + a[::] + a[0:] + a[:2] + a[0:2] + a[::2] + a[1::2] + a[:2:2] + a[1:2:2] + + def test_non_integer_argument_errors(self): + a = np.array([[5]]) + + assert_raises(TypeError, np.reshape, a, (1., 1., -1)) + assert_raises(TypeError, np.reshape, a, (np.array(1.), -1)) + assert_raises(TypeError, np.take, a, [0], 1.) + assert_raises(TypeError, np.take, a, [0], np.float64(1.)) + + def test_non_integer_sequence_multiplication(self): + # NumPy scalar sequence multiply should not work with non-integers + def mult(a, b): + return a * b + + assert_raises(TypeError, mult, [1], np.float_(3)) + # following should be OK + mult([1], np.int_(3)) + + def test_reduce_axis_float_index(self): + d = np.zeros((3,3,3)) + assert_raises(TypeError, np.min, d, 0.5) + assert_raises(TypeError, np.min, d, (0.5, 1)) + assert_raises(TypeError, np.min, d, (1, 2.2)) + assert_raises(TypeError, np.min, d, (.2, 1.2)) + + +class TestBooleanIndexing: + # Using a boolean as integer argument/indexing is an error. + def test_bool_as_int_argument_errors(self): + a = np.array([[[1]]]) + + assert_raises(TypeError, np.reshape, a, (True, -1)) + assert_raises(TypeError, np.reshape, a, (np.bool_(True), -1)) + # Note that operator.index(np.array(True)) does not work, a boolean + # array is thus also deprecated, but not with the same message: + assert_raises(TypeError, operator.index, np.array(True)) + assert_warns(DeprecationWarning, operator.index, np.True_) + assert_raises(TypeError, np.take, args=(a, [0], False)) + + def test_boolean_indexing_weirdness(self): + # Weird boolean indexing things + a = np.ones((2, 3, 4)) + a[False, True, ...].shape == (0, 2, 3, 4) + a[True, [0, 1], True, True, [1], [[2]]] == (1, 2) + assert_raises(IndexError, lambda: a[False, [0, 1], ...]) + + + def test_boolean_indexing_fast_path(self): + # These used to either give the wrong error, or incorrectly give no + # error. + a = np.ones((3, 3)) + + # This used to incorrectly work (and give an array of shape (0,)) + idx1 = np.array([[False]*9]) + assert_raises_regex(IndexError, + "boolean index did not match indexed array along dimension 0; " + "dimension is 3 but corresponding boolean dimension is 1", + lambda: a[idx1]) + + # This used to incorrectly give a ValueError: operands could not be broadcast together + idx2 = np.array([[False]*8 + [True]]) + assert_raises_regex(IndexError, + "boolean index did not match indexed array along dimension 0; " + "dimension is 3 but corresponding boolean dimension is 1", + lambda: a[idx2]) + + # This is the same as it used to be. The above two should work like this. + idx3 = np.array([[False]*10]) + assert_raises_regex(IndexError, + "boolean index did not match indexed array along dimension 0; " + "dimension is 3 but corresponding boolean dimension is 1", + lambda: a[idx3]) + + # This used to give ValueError: non-broadcastable operand + a = np.ones((1, 1, 2)) + idx = np.array([[[True], [False]]]) + assert_raises_regex(IndexError, + "boolean index did not match indexed array along dimension 1; " + "dimension is 1 but corresponding boolean dimension is 2", + lambda: a[idx]) + + +class TestArrayToIndexDeprecation: + """Creating an an index from array not 0-D is an error. + + """ + def test_array_to_index_error(self): + # so no exception is expected. The raising is effectively tested above. + a = np.array([[[1]]]) + + assert_raises(TypeError, operator.index, np.array([1])) + assert_raises(TypeError, np.reshape, a, (a, -1)) + assert_raises(TypeError, np.take, a, [0], a) + + +class TestNonIntegerArrayLike: + """Tests that array_likes only valid if can safely cast to integer. + + For instance, lists give IndexError when they cannot be safely cast to + an integer. + + """ + def test_basic(self): + a = np.arange(10) + + assert_raises(IndexError, a.__getitem__, [0.5, 1.5]) + assert_raises(IndexError, a.__getitem__, (['1', '2'],)) + + # The following is valid + a.__getitem__([]) + + +class TestMultipleEllipsisError: + """An index can only have a single ellipsis. + + """ + def test_basic(self): + a = np.arange(10) + assert_raises(IndexError, lambda: a[..., ...]) + assert_raises(IndexError, a.__getitem__, ((Ellipsis,) * 2,)) + assert_raises(IndexError, a.__getitem__, ((Ellipsis,) * 3,)) + + +class TestCApiAccess: + def test_getitem(self): + subscript = functools.partial(array_indexing, 0) + + # 0-d arrays don't work: + assert_raises(IndexError, subscript, np.ones(()), 0) + # Out of bound values: + assert_raises(IndexError, subscript, np.ones(10), 11) + assert_raises(IndexError, subscript, np.ones(10), -11) + assert_raises(IndexError, subscript, np.ones((10, 10)), 11) + assert_raises(IndexError, subscript, np.ones((10, 10)), -11) + + a = np.arange(10) + assert_array_equal(a[4], subscript(a, 4)) + a = a.reshape(5, 2) + assert_array_equal(a[-4], subscript(a, -4)) + + def test_setitem(self): + assign = functools.partial(array_indexing, 1) + + # Deletion is impossible: + assert_raises(ValueError, assign, np.ones(10), 0) + # 0-d arrays don't work: + assert_raises(IndexError, assign, np.ones(()), 0, 0) + # Out of bound values: + assert_raises(IndexError, assign, np.ones(10), 11, 0) + assert_raises(IndexError, assign, np.ones(10), -11, 0) + assert_raises(IndexError, assign, np.ones((10, 10)), 11, 0) + assert_raises(IndexError, assign, np.ones((10, 10)), -11, 0) + + a = np.arange(10) + assign(a, 4, 10) + assert_(a[4] == 10) + + a = a.reshape(5, 2) + assign(a, 4, 10) + assert_array_equal(a[-1], [10, 10]) diff --git a/venv/Lib/site-packages/numpy/core/tests/test_item_selection.py b/venv/Lib/site-packages/numpy/core/tests/test_item_selection.py new file mode 100644 index 0000000..3c35245 --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/tests/test_item_selection.py @@ -0,0 +1,86 @@ +import sys + +import numpy as np +from numpy.testing import ( + assert_, assert_raises, assert_array_equal, HAS_REFCOUNT + ) + + +class TestTake: + def test_simple(self): + a = [[1, 2], [3, 4]] + a_str = [[b'1', b'2'], [b'3', b'4']] + modes = ['raise', 'wrap', 'clip'] + indices = [-1, 4] + index_arrays = [np.empty(0, dtype=np.intp), + np.empty(tuple(), dtype=np.intp), + np.empty((1, 1), dtype=np.intp)] + real_indices = {'raise': {-1: 1, 4: IndexError}, + 'wrap': {-1: 1, 4: 0}, + 'clip': {-1: 0, 4: 1}} + # Currently all types but object, use the same function generation. + # So it should not be necessary to test all. However test also a non + # refcounted struct on top of object, which has a size that hits the + # default (non-specialized) path. + types = int, object, np.dtype([('', 'i2', 3)]) + for t in types: + # ta works, even if the array may be odd if buffer interface is used + ta = np.array(a if np.issubdtype(t, np.number) else a_str, dtype=t) + tresult = list(ta.T.copy()) + for index_array in index_arrays: + if index_array.size != 0: + tresult[0].shape = (2,) + index_array.shape + tresult[1].shape = (2,) + index_array.shape + for mode in modes: + for index in indices: + real_index = real_indices[mode][index] + if real_index is IndexError and index_array.size != 0: + index_array.put(0, index) + assert_raises(IndexError, ta.take, index_array, + mode=mode, axis=1) + elif index_array.size != 0: + index_array.put(0, index) + res = ta.take(index_array, mode=mode, axis=1) + assert_array_equal(res, tresult[real_index]) + else: + res = ta.take(index_array, mode=mode, axis=1) + assert_(res.shape == (2,) + index_array.shape) + + def test_refcounting(self): + objects = [object() for i in range(10)] + for mode in ('raise', 'clip', 'wrap'): + a = np.array(objects) + b = np.array([2, 2, 4, 5, 3, 5]) + a.take(b, out=a[:6], mode=mode) + del a + if HAS_REFCOUNT: + assert_(all(sys.getrefcount(o) == 3 for o in objects)) + # not contiguous, example: + a = np.array(objects * 2)[::2] + a.take(b, out=a[:6], mode=mode) + del a + if HAS_REFCOUNT: + assert_(all(sys.getrefcount(o) == 3 for o in objects)) + + def test_unicode_mode(self): + d = np.arange(10) + k = b'\xc3\xa4'.decode("UTF8") + assert_raises(ValueError, d.take, 5, mode=k) + + def test_empty_partition(self): + # In reference to github issue #6530 + a_original = np.array([0, 2, 4, 6, 8, 10]) + a = a_original.copy() + + # An empty partition should be a successful no-op + a.partition(np.array([], dtype=np.int16)) + + assert_array_equal(a, a_original) + + def test_empty_argpartition(self): + # In reference to github issue #6530 + a = np.array([0, 2, 4, 6, 8, 10]) + a = a.argpartition(np.array([], dtype=np.int16)) + + b = np.array([0, 1, 2, 3, 4, 5]) + assert_array_equal(a, b) diff --git a/venv/Lib/site-packages/numpy/core/tests/test_longdouble.py b/venv/Lib/site-packages/numpy/core/tests/test_longdouble.py new file mode 100644 index 0000000..acef995 --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/tests/test_longdouble.py @@ -0,0 +1,369 @@ +import warnings +import pytest + +import numpy as np +from numpy.testing import ( + assert_, assert_equal, assert_raises, assert_warns, assert_array_equal, + temppath, + ) +from numpy.core.tests._locales import CommaDecimalPointLocale + +LD_INFO = np.finfo(np.longdouble) +longdouble_longer_than_double = (LD_INFO.eps < np.finfo(np.double).eps) + + +_o = 1 + LD_INFO.eps +string_to_longdouble_inaccurate = (_o != np.longdouble(repr(_o))) +del _o + + +def test_scalar_extraction(): + """Confirm that extracting a value doesn't convert to python float""" + o = 1 + LD_INFO.eps + a = np.array([o, o, o]) + assert_equal(a[1], o) + + +# Conversions string -> long double + +# 0.1 not exactly representable in base 2 floating point. +repr_precision = len(repr(np.longdouble(0.1))) +# +2 from macro block starting around line 842 in scalartypes.c.src. +@pytest.mark.skipif(LD_INFO.precision + 2 >= repr_precision, + reason="repr precision not enough to show eps") +def test_repr_roundtrip(): + # We will only see eps in repr if within printing precision. + o = 1 + LD_INFO.eps + assert_equal(np.longdouble(repr(o)), o, "repr was %s" % repr(o)) + + +@pytest.mark.skipif(string_to_longdouble_inaccurate, reason="Need strtold_l") +def test_repr_roundtrip_bytes(): + o = 1 + LD_INFO.eps + assert_equal(np.longdouble(repr(o).encode("ascii")), o) + + +@pytest.mark.skipif(string_to_longdouble_inaccurate, reason="Need strtold_l") +@pytest.mark.parametrize("strtype", (np.str_, np.bytes_, str, bytes)) +def test_array_and_stringlike_roundtrip(strtype): + """ + Test that string representations of long-double roundtrip both + for array casting and scalar coercion, see also gh-15608. + """ + o = 1 + LD_INFO.eps + + if strtype in (np.bytes_, bytes): + o_str = strtype(repr(o).encode("ascii")) + else: + o_str = strtype(repr(o)) + + # Test that `o` is correctly coerced from the string-like + assert o == np.longdouble(o_str) + + # Test that arrays also roundtrip correctly: + o_strarr = np.asarray([o] * 3, dtype=strtype) + assert (o == o_strarr.astype(np.longdouble)).all() + + # And array coercion and casting to string give the same as scalar repr: + assert (o_strarr == o_str).all() + assert (np.asarray([o] * 3).astype(strtype) == o_str).all() + + +def test_bogus_string(): + assert_raises(ValueError, np.longdouble, "spam") + assert_raises(ValueError, np.longdouble, "1.0 flub") + + +@pytest.mark.skipif(string_to_longdouble_inaccurate, reason="Need strtold_l") +def test_fromstring(): + o = 1 + LD_INFO.eps + s = (" " + repr(o))*5 + a = np.array([o]*5) + assert_equal(np.fromstring(s, sep=" ", dtype=np.longdouble), a, + err_msg="reading '%s'" % s) + + +def test_fromstring_complex(): + for ctype in ["complex", "cdouble", "cfloat"]: + # Check spacing between separator + assert_equal(np.fromstring("1, 2 , 3 ,4", sep=",", dtype=ctype), + np.array([1., 2., 3., 4.])) + # Real component not specified + assert_equal(np.fromstring("1j, -2j, 3j, 4e1j", sep=",", dtype=ctype), + np.array([1.j, -2.j, 3.j, 40.j])) + # Both components specified + assert_equal(np.fromstring("1+1j,2-2j, -3+3j, -4e1+4j", sep=",", dtype=ctype), + np.array([1. + 1.j, 2. - 2.j, - 3. + 3.j, - 40. + 4j])) + # Spaces at wrong places + with assert_warns(DeprecationWarning): + assert_equal(np.fromstring("1+2 j,3", dtype=ctype, sep=","), + np.array([1.])) + with assert_warns(DeprecationWarning): + assert_equal(np.fromstring("1+ 2j,3", dtype=ctype, sep=","), + np.array([1.])) + with assert_warns(DeprecationWarning): + assert_equal(np.fromstring("1 +2j,3", dtype=ctype, sep=","), + np.array([1.])) + with assert_warns(DeprecationWarning): + assert_equal(np.fromstring("1+j", dtype=ctype, sep=","), + np.array([1.])) + with assert_warns(DeprecationWarning): + assert_equal(np.fromstring("1+", dtype=ctype, sep=","), + np.array([1.])) + with assert_warns(DeprecationWarning): + assert_equal(np.fromstring("1j+1", dtype=ctype, sep=","), + np.array([1j])) + + +def test_fromstring_bogus(): + with assert_warns(DeprecationWarning): + assert_equal(np.fromstring("1. 2. 3. flop 4.", dtype=float, sep=" "), + np.array([1., 2., 3.])) + + +def test_fromstring_empty(): + with assert_warns(DeprecationWarning): + assert_equal(np.fromstring("xxxxx", sep="x"), + np.array([])) + + +def test_fromstring_missing(): + with assert_warns(DeprecationWarning): + assert_equal(np.fromstring("1xx3x4x5x6", sep="x"), + np.array([1])) + + +class TestFileBased: + + ldbl = 1 + LD_INFO.eps + tgt = np.array([ldbl]*5) + out = ''.join([repr(t) + '\n' for t in tgt]) + + def test_fromfile_bogus(self): + with temppath() as path: + with open(path, 'wt') as f: + f.write("1. 2. 3. flop 4.\n") + + with assert_warns(DeprecationWarning): + res = np.fromfile(path, dtype=float, sep=" ") + assert_equal(res, np.array([1., 2., 3.])) + + def test_fromfile_complex(self): + for ctype in ["complex", "cdouble", "cfloat"]: + # Check spacing between separator and only real component specified + with temppath() as path: + with open(path, 'wt') as f: + f.write("1, 2 , 3 ,4\n") + + res = np.fromfile(path, dtype=ctype, sep=",") + assert_equal(res, np.array([1., 2., 3., 4.])) + + # Real component not specified + with temppath() as path: + with open(path, 'wt') as f: + f.write("1j, -2j, 3j, 4e1j\n") + + res = np.fromfile(path, dtype=ctype, sep=",") + assert_equal(res, np.array([1.j, -2.j, 3.j, 40.j])) + + # Both components specified + with temppath() as path: + with open(path, 'wt') as f: + f.write("1+1j,2-2j, -3+3j, -4e1+4j\n") + + res = np.fromfile(path, dtype=ctype, sep=",") + assert_equal(res, np.array([1. + 1.j, 2. - 2.j, - 3. + 3.j, - 40. + 4j])) + + # Spaces at wrong places + with temppath() as path: + with open(path, 'wt') as f: + f.write("1+2 j,3\n") + + with assert_warns(DeprecationWarning): + res = np.fromfile(path, dtype=ctype, sep=",") + assert_equal(res, np.array([1.])) + + # Spaces at wrong places + with temppath() as path: + with open(path, 'wt') as f: + f.write("1+ 2j,3\n") + + with assert_warns(DeprecationWarning): + res = np.fromfile(path, dtype=ctype, sep=",") + assert_equal(res, np.array([1.])) + + # Spaces at wrong places + with temppath() as path: + with open(path, 'wt') as f: + f.write("1 +2j,3\n") + + with assert_warns(DeprecationWarning): + res = np.fromfile(path, dtype=ctype, sep=",") + assert_equal(res, np.array([1.])) + + # Spaces at wrong places + with temppath() as path: + with open(path, 'wt') as f: + f.write("1+j\n") + + with assert_warns(DeprecationWarning): + res = np.fromfile(path, dtype=ctype, sep=",") + assert_equal(res, np.array([1.])) + + # Spaces at wrong places + with temppath() as path: + with open(path, 'wt') as f: + f.write("1+\n") + + with assert_warns(DeprecationWarning): + res = np.fromfile(path, dtype=ctype, sep=",") + assert_equal(res, np.array([1.])) + + # Spaces at wrong places + with temppath() as path: + with open(path, 'wt') as f: + f.write("1j+1\n") + + with assert_warns(DeprecationWarning): + res = np.fromfile(path, dtype=ctype, sep=",") + assert_equal(res, np.array([1.j])) + + + + @pytest.mark.skipif(string_to_longdouble_inaccurate, + reason="Need strtold_l") + def test_fromfile(self): + with temppath() as path: + with open(path, 'wt') as f: + f.write(self.out) + res = np.fromfile(path, dtype=np.longdouble, sep="\n") + assert_equal(res, self.tgt) + + @pytest.mark.skipif(string_to_longdouble_inaccurate, + reason="Need strtold_l") + def test_genfromtxt(self): + with temppath() as path: + with open(path, 'wt') as f: + f.write(self.out) + res = np.genfromtxt(path, dtype=np.longdouble) + assert_equal(res, self.tgt) + + @pytest.mark.skipif(string_to_longdouble_inaccurate, + reason="Need strtold_l") + def test_loadtxt(self): + with temppath() as path: + with open(path, 'wt') as f: + f.write(self.out) + res = np.loadtxt(path, dtype=np.longdouble) + assert_equal(res, self.tgt) + + @pytest.mark.skipif(string_to_longdouble_inaccurate, + reason="Need strtold_l") + def test_tofile_roundtrip(self): + with temppath() as path: + self.tgt.tofile(path, sep=" ") + res = np.fromfile(path, dtype=np.longdouble, sep=" ") + assert_equal(res, self.tgt) + + +# Conversions long double -> string + + +def test_repr_exact(): + o = 1 + LD_INFO.eps + assert_(repr(o) != '1') + + +@pytest.mark.skipif(longdouble_longer_than_double, reason="BUG #2376") +@pytest.mark.skipif(string_to_longdouble_inaccurate, + reason="Need strtold_l") +def test_format(): + o = 1 + LD_INFO.eps + assert_("{0:.40g}".format(o) != '1') + + +@pytest.mark.skipif(longdouble_longer_than_double, reason="BUG #2376") +@pytest.mark.skipif(string_to_longdouble_inaccurate, + reason="Need strtold_l") +def test_percent(): + o = 1 + LD_INFO.eps + assert_("%.40g" % o != '1') + + +@pytest.mark.skipif(longdouble_longer_than_double, + reason="array repr problem") +@pytest.mark.skipif(string_to_longdouble_inaccurate, + reason="Need strtold_l") +def test_array_repr(): + o = 1 + LD_INFO.eps + a = np.array([o]) + b = np.array([1], dtype=np.longdouble) + if not np.all(a != b): + raise ValueError("precision loss creating arrays") + assert_(repr(a) != repr(b)) + +# +# Locale tests: scalar types formatting should be independent of the locale +# + +class TestCommaDecimalPointLocale(CommaDecimalPointLocale): + + def test_repr_roundtrip_foreign(self): + o = 1.5 + assert_equal(o, np.longdouble(repr(o))) + + def test_fromstring_foreign_repr(self): + f = 1.234 + a = np.fromstring(repr(f), dtype=float, sep=" ") + assert_equal(a[0], f) + + def test_fromstring_best_effort_float(self): + with assert_warns(DeprecationWarning): + assert_equal(np.fromstring("1,234", dtype=float, sep=" "), + np.array([1.])) + + def test_fromstring_best_effort(self): + with assert_warns(DeprecationWarning): + assert_equal(np.fromstring("1,234", dtype=np.longdouble, sep=" "), + np.array([1.])) + + def test_fromstring_foreign(self): + s = "1.234" + a = np.fromstring(s, dtype=np.longdouble, sep=" ") + assert_equal(a[0], np.longdouble(s)) + + def test_fromstring_foreign_sep(self): + a = np.array([1, 2, 3, 4]) + b = np.fromstring("1,2,3,4,", dtype=np.longdouble, sep=",") + assert_array_equal(a, b) + + def test_fromstring_foreign_value(self): + with assert_warns(DeprecationWarning): + b = np.fromstring("1,234", dtype=np.longdouble, sep=" ") + assert_array_equal(b[0], 1) + + +@pytest.mark.parametrize("int_val", [ + # cases discussed in gh-10723 + # and gh-9968 + 2 ** 1024, 0]) +def test_longdouble_from_int(int_val): + # for issue gh-9968 + str_val = str(int_val) + # we'll expect a RuntimeWarning on platforms + # with np.longdouble equivalent to np.double + # for large integer input + with warnings.catch_warnings(record=True) as w: + warnings.filterwarnings('always', '', RuntimeWarning) + # can be inf==inf on some platforms + assert np.longdouble(int_val) == np.longdouble(str_val) + # we can't directly compare the int and + # max longdouble value on all platforms + if np.allclose(np.finfo(np.longdouble).max, + np.finfo(np.double).max) and w: + assert w[0].category is RuntimeWarning + +@pytest.mark.parametrize("bool_val", [ + True, False]) +def test_longdouble_from_bool(bool_val): + assert np.longdouble(bool_val) == np.longdouble(int(bool_val)) diff --git a/venv/Lib/site-packages/numpy/core/tests/test_machar.py b/venv/Lib/site-packages/numpy/core/tests/test_machar.py new file mode 100644 index 0000000..673f309 --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/tests/test_machar.py @@ -0,0 +1,30 @@ +""" +Test machar. Given recent changes to hardcode type data, we might want to get +rid of both MachAr and this test at some point. + +""" +from numpy.core.machar import MachAr +import numpy.core.numerictypes as ntypes +from numpy import errstate, array + + +class TestMachAr: + def _run_machar_highprec(self): + # Instantiate MachAr instance with high enough precision to cause + # underflow + try: + hiprec = ntypes.float96 + MachAr(lambda v: array(v, hiprec)) + except AttributeError: + # Fixme, this needs to raise a 'skip' exception. + "Skipping test: no ntypes.float96 available on this platform." + + def test_underlow(self): + # Regression test for #759: + # instantiating MachAr for dtype = np.float96 raises spurious warning. + with errstate(all='raise'): + try: + self._run_machar_highprec() + except FloatingPointError as e: + msg = "Caught %s exception, should not have been raised." % e + raise AssertionError(msg) diff --git a/venv/Lib/site-packages/numpy/core/tests/test_mem_overlap.py b/venv/Lib/site-packages/numpy/core/tests/test_mem_overlap.py new file mode 100644 index 0000000..675613d --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/tests/test_mem_overlap.py @@ -0,0 +1,926 @@ +import itertools +import pytest + +import numpy as np +from numpy.core._multiarray_tests import solve_diophantine, internal_overlap +from numpy.core import _umath_tests +from numpy.lib.stride_tricks import as_strided +from numpy.testing import ( + assert_, assert_raises, assert_equal, assert_array_equal + ) + + +ndims = 2 +size = 10 +shape = tuple([size] * ndims) + +MAY_SHARE_BOUNDS = 0 +MAY_SHARE_EXACT = -1 + + +def _indices_for_nelems(nelems): + """Returns slices of length nelems, from start onwards, in direction sign.""" + + if nelems == 0: + return [size // 2] # int index + + res = [] + for step in (1, 2): + for sign in (-1, 1): + start = size // 2 - nelems * step * sign // 2 + stop = start + nelems * step * sign + res.append(slice(start, stop, step * sign)) + + return res + + +def _indices_for_axis(): + """Returns (src, dst) pairs of indices.""" + + res = [] + for nelems in (0, 2, 3): + ind = _indices_for_nelems(nelems) + res.extend(itertools.product(ind, ind)) # all assignments of size "nelems" + + return res + + +def _indices(ndims): + """Returns ((axis0_src, axis0_dst), (axis1_src, axis1_dst), ... ) index pairs.""" + + ind = _indices_for_axis() + return itertools.product(ind, repeat=ndims) + + +def _check_assignment(srcidx, dstidx): + """Check assignment arr[dstidx] = arr[srcidx] works.""" + + arr = np.arange(np.product(shape)).reshape(shape) + + cpy = arr.copy() + + cpy[dstidx] = arr[srcidx] + arr[dstidx] = arr[srcidx] + + assert_(np.all(arr == cpy), + 'assigning arr[%s] = arr[%s]' % (dstidx, srcidx)) + + +def test_overlapping_assignments(): + # Test automatically generated assignments which overlap in memory. + + inds = _indices(ndims) + + for ind in inds: + srcidx = tuple([a[0] for a in ind]) + dstidx = tuple([a[1] for a in ind]) + + _check_assignment(srcidx, dstidx) + + +@pytest.mark.slow +def test_diophantine_fuzz(): + # Fuzz test the diophantine solver + rng = np.random.RandomState(1234) + + max_int = np.iinfo(np.intp).max + + for ndim in range(10): + feasible_count = 0 + infeasible_count = 0 + + min_count = 500//(ndim + 1) + + while min(feasible_count, infeasible_count) < min_count: + # Ensure big and small integer problems + A_max = 1 + rng.randint(0, 11, dtype=np.intp)**6 + U_max = rng.randint(0, 11, dtype=np.intp)**6 + + A_max = min(max_int, A_max) + U_max = min(max_int-1, U_max) + + A = tuple(int(rng.randint(1, A_max+1, dtype=np.intp)) + for j in range(ndim)) + U = tuple(int(rng.randint(0, U_max+2, dtype=np.intp)) + for j in range(ndim)) + + b_ub = min(max_int-2, sum(a*ub for a, ub in zip(A, U))) + b = rng.randint(-1, b_ub+2, dtype=np.intp) + + if ndim == 0 and feasible_count < min_count: + b = 0 + + X = solve_diophantine(A, U, b) + + if X is None: + # Check the simplified decision problem agrees + X_simplified = solve_diophantine(A, U, b, simplify=1) + assert_(X_simplified is None, (A, U, b, X_simplified)) + + # Check no solution exists (provided the problem is + # small enough so that brute force checking doesn't + # take too long) + ranges = tuple(range(0, a*ub+1, a) for a, ub in zip(A, U)) + + size = 1 + for r in ranges: + size *= len(r) + if size < 100000: + assert_(not any(sum(w) == b for w in itertools.product(*ranges))) + infeasible_count += 1 + else: + # Check the simplified decision problem agrees + X_simplified = solve_diophantine(A, U, b, simplify=1) + assert_(X_simplified is not None, (A, U, b, X_simplified)) + + # Check validity + assert_(sum(a*x for a, x in zip(A, X)) == b) + assert_(all(0 <= x <= ub for x, ub in zip(X, U))) + feasible_count += 1 + + +def test_diophantine_overflow(): + # Smoke test integer overflow detection + max_intp = np.iinfo(np.intp).max + max_int64 = np.iinfo(np.int64).max + + if max_int64 <= max_intp: + # Check that the algorithm works internally in 128-bit; + # solving this problem requires large intermediate numbers + A = (max_int64//2, max_int64//2 - 10) + U = (max_int64//2, max_int64//2 - 10) + b = 2*(max_int64//2) - 10 + + assert_equal(solve_diophantine(A, U, b), (1, 1)) + + +def check_may_share_memory_exact(a, b): + got = np.may_share_memory(a, b, max_work=MAY_SHARE_EXACT) + + assert_equal(np.may_share_memory(a, b), + np.may_share_memory(a, b, max_work=MAY_SHARE_BOUNDS)) + + a.fill(0) + b.fill(0) + a.fill(1) + exact = b.any() + + err_msg = "" + if got != exact: + err_msg = " " + "\n ".join([ + "base_a - base_b = %r" % (a.__array_interface__['data'][0] - b.__array_interface__['data'][0],), + "shape_a = %r" % (a.shape,), + "shape_b = %r" % (b.shape,), + "strides_a = %r" % (a.strides,), + "strides_b = %r" % (b.strides,), + "size_a = %r" % (a.size,), + "size_b = %r" % (b.size,) + ]) + + assert_equal(got, exact, err_msg=err_msg) + + +def test_may_share_memory_manual(): + # Manual test cases for may_share_memory + + # Base arrays + xs0 = [ + np.zeros([13, 21, 23, 22], dtype=np.int8), + np.zeros([13, 21, 23*2, 22], dtype=np.int8)[:,:,::2,:] + ] + + # Generate all negative stride combinations + xs = [] + for x in xs0: + for ss in itertools.product(*(([slice(None), slice(None, None, -1)],)*4)): + xp = x[ss] + xs.append(xp) + + for x in xs: + # The default is a simple extent check + assert_(np.may_share_memory(x[:,0,:], x[:,1,:])) + assert_(np.may_share_memory(x[:,0,:], x[:,1,:], max_work=None)) + + # Exact checks + check_may_share_memory_exact(x[:,0,:], x[:,1,:]) + check_may_share_memory_exact(x[:,::7], x[:,3::3]) + + try: + xp = x.ravel() + if xp.flags.owndata: + continue + xp = xp.view(np.int16) + except ValueError: + continue + + # 0-size arrays cannot overlap + check_may_share_memory_exact(x.ravel()[6:6], + xp.reshape(13, 21, 23, 11)[:,::7]) + + # Test itemsize is dealt with + check_may_share_memory_exact(x[:,::7], + xp.reshape(13, 21, 23, 11)) + check_may_share_memory_exact(x[:,::7], + xp.reshape(13, 21, 23, 11)[:,3::3]) + check_may_share_memory_exact(x.ravel()[6:7], + xp.reshape(13, 21, 23, 11)[:,::7]) + + # Check unit size + x = np.zeros([1], dtype=np.int8) + check_may_share_memory_exact(x, x) + check_may_share_memory_exact(x, x.copy()) + + +def iter_random_view_pairs(x, same_steps=True, equal_size=False): + rng = np.random.RandomState(1234) + + if equal_size and same_steps: + raise ValueError() + + def random_slice(n, step): + start = rng.randint(0, n+1, dtype=np.intp) + stop = rng.randint(start, n+1, dtype=np.intp) + if rng.randint(0, 2, dtype=np.intp) == 0: + stop, start = start, stop + step *= -1 + return slice(start, stop, step) + + def random_slice_fixed_size(n, step, size): + start = rng.randint(0, n+1 - size*step) + stop = start + (size-1)*step + 1 + if rng.randint(0, 2) == 0: + stop, start = start-1, stop-1 + if stop < 0: + stop = None + step *= -1 + return slice(start, stop, step) + + # First a few regular views + yield x, x + for j in range(1, 7, 3): + yield x[j:], x[:-j] + yield x[...,j:], x[...,:-j] + + # An array with zero stride internal overlap + strides = list(x.strides) + strides[0] = 0 + xp = as_strided(x, shape=x.shape, strides=strides) + yield x, xp + yield xp, xp + + # An array with non-zero stride internal overlap + strides = list(x.strides) + if strides[0] > 1: + strides[0] = 1 + xp = as_strided(x, shape=x.shape, strides=strides) + yield x, xp + yield xp, xp + + # Then discontiguous views + while True: + steps = tuple(rng.randint(1, 11, dtype=np.intp) + if rng.randint(0, 5, dtype=np.intp) == 0 else 1 + for j in range(x.ndim)) + s1 = tuple(random_slice(p, s) for p, s in zip(x.shape, steps)) + + t1 = np.arange(x.ndim) + rng.shuffle(t1) + + if equal_size: + t2 = t1 + else: + t2 = np.arange(x.ndim) + rng.shuffle(t2) + + a = x[s1] + + if equal_size: + if a.size == 0: + continue + + steps2 = tuple(rng.randint(1, max(2, p//(1+pa))) + if rng.randint(0, 5) == 0 else 1 + for p, s, pa in zip(x.shape, s1, a.shape)) + s2 = tuple(random_slice_fixed_size(p, s, pa) + for p, s, pa in zip(x.shape, steps2, a.shape)) + elif same_steps: + steps2 = steps + else: + steps2 = tuple(rng.randint(1, 11, dtype=np.intp) + if rng.randint(0, 5, dtype=np.intp) == 0 else 1 + for j in range(x.ndim)) + + if not equal_size: + s2 = tuple(random_slice(p, s) for p, s in zip(x.shape, steps2)) + + a = a.transpose(t1) + b = x[s2].transpose(t2) + + yield a, b + + +def check_may_share_memory_easy_fuzz(get_max_work, same_steps, min_count): + # Check that overlap problems with common strides are solved with + # little work. + x = np.zeros([17,34,71,97], dtype=np.int16) + + feasible = 0 + infeasible = 0 + + pair_iter = iter_random_view_pairs(x, same_steps) + + while min(feasible, infeasible) < min_count: + a, b = next(pair_iter) + + bounds_overlap = np.may_share_memory(a, b) + may_share_answer = np.may_share_memory(a, b) + easy_answer = np.may_share_memory(a, b, max_work=get_max_work(a, b)) + exact_answer = np.may_share_memory(a, b, max_work=MAY_SHARE_EXACT) + + if easy_answer != exact_answer: + # assert_equal is slow... + assert_equal(easy_answer, exact_answer) + + if may_share_answer != bounds_overlap: + assert_equal(may_share_answer, bounds_overlap) + + if bounds_overlap: + if exact_answer: + feasible += 1 + else: + infeasible += 1 + + +@pytest.mark.slow +def test_may_share_memory_easy_fuzz(): + # Check that overlap problems with common strides are always + # solved with little work. + + check_may_share_memory_easy_fuzz(get_max_work=lambda a, b: 1, + same_steps=True, + min_count=2000) + + +@pytest.mark.slow +def test_may_share_memory_harder_fuzz(): + # Overlap problems with not necessarily common strides take more + # work. + # + # The work bound below can't be reduced much. Harder problems can + # also exist but not be detected here, as the set of problems + # comes from RNG. + + check_may_share_memory_easy_fuzz(get_max_work=lambda a, b: max(a.size, b.size)//2, + same_steps=False, + min_count=2000) + + +def test_shares_memory_api(): + x = np.zeros([4, 5, 6], dtype=np.int8) + + assert_equal(np.shares_memory(x, x), True) + assert_equal(np.shares_memory(x, x.copy()), False) + + a = x[:,::2,::3] + b = x[:,::3,::2] + assert_equal(np.shares_memory(a, b), True) + assert_equal(np.shares_memory(a, b, max_work=None), True) + assert_raises(np.TooHardError, np.shares_memory, a, b, max_work=1) + + +def test_may_share_memory_bad_max_work(): + x = np.zeros([1]) + assert_raises(OverflowError, np.may_share_memory, x, x, max_work=10**100) + assert_raises(OverflowError, np.shares_memory, x, x, max_work=10**100) + + +def test_internal_overlap_diophantine(): + def check(A, U, exists=None): + X = solve_diophantine(A, U, 0, require_ub_nontrivial=1) + + if exists is None: + exists = (X is not None) + + if X is not None: + assert_(sum(a*x for a, x in zip(A, X)) == sum(a*u//2 for a, u in zip(A, U))) + assert_(all(0 <= x <= u for x, u in zip(X, U))) + assert_(any(x != u//2 for x, u in zip(X, U))) + + if exists: + assert_(X is not None, repr(X)) + else: + assert_(X is None, repr(X)) + + # Smoke tests + check((3, 2), (2*2, 3*2), exists=True) + check((3*2, 2), (15*2, (3-1)*2), exists=False) + + +def test_internal_overlap_slices(): + # Slicing an array never generates internal overlap + + x = np.zeros([17,34,71,97], dtype=np.int16) + + rng = np.random.RandomState(1234) + + def random_slice(n, step): + start = rng.randint(0, n+1, dtype=np.intp) + stop = rng.randint(start, n+1, dtype=np.intp) + if rng.randint(0, 2, dtype=np.intp) == 0: + stop, start = start, stop + step *= -1 + return slice(start, stop, step) + + cases = 0 + min_count = 5000 + + while cases < min_count: + steps = tuple(rng.randint(1, 11, dtype=np.intp) + if rng.randint(0, 5, dtype=np.intp) == 0 else 1 + for j in range(x.ndim)) + t1 = np.arange(x.ndim) + rng.shuffle(t1) + s1 = tuple(random_slice(p, s) for p, s in zip(x.shape, steps)) + a = x[s1].transpose(t1) + + assert_(not internal_overlap(a)) + cases += 1 + + +def check_internal_overlap(a, manual_expected=None): + got = internal_overlap(a) + + # Brute-force check + m = set() + ranges = tuple(range(n) for n in a.shape) + for v in itertools.product(*ranges): + offset = sum(s*w for s, w in zip(a.strides, v)) + if offset in m: + expected = True + break + else: + m.add(offset) + else: + expected = False + + # Compare + if got != expected: + assert_equal(got, expected, err_msg=repr((a.strides, a.shape))) + if manual_expected is not None and expected != manual_expected: + assert_equal(expected, manual_expected) + return got + + +def test_internal_overlap_manual(): + # Stride tricks can construct arrays with internal overlap + + # We don't care about memory bounds, the array is not + # read/write accessed + x = np.arange(1).astype(np.int8) + + # Check low-dimensional special cases + + check_internal_overlap(x, False) # 1-dim + check_internal_overlap(x.reshape([]), False) # 0-dim + + a = as_strided(x, strides=(3, 4), shape=(4, 4)) + check_internal_overlap(a, False) + + a = as_strided(x, strides=(3, 4), shape=(5, 4)) + check_internal_overlap(a, True) + + a = as_strided(x, strides=(0,), shape=(0,)) + check_internal_overlap(a, False) + + a = as_strided(x, strides=(0,), shape=(1,)) + check_internal_overlap(a, False) + + a = as_strided(x, strides=(0,), shape=(2,)) + check_internal_overlap(a, True) + + a = as_strided(x, strides=(0, -9993), shape=(87, 22)) + check_internal_overlap(a, True) + + a = as_strided(x, strides=(0, -9993), shape=(1, 22)) + check_internal_overlap(a, False) + + a = as_strided(x, strides=(0, -9993), shape=(0, 22)) + check_internal_overlap(a, False) + + +def test_internal_overlap_fuzz(): + # Fuzz check; the brute-force check is fairly slow + + x = np.arange(1).astype(np.int8) + + overlap = 0 + no_overlap = 0 + min_count = 100 + + rng = np.random.RandomState(1234) + + while min(overlap, no_overlap) < min_count: + ndim = rng.randint(1, 4, dtype=np.intp) + + strides = tuple(rng.randint(-1000, 1000, dtype=np.intp) + for j in range(ndim)) + shape = tuple(rng.randint(1, 30, dtype=np.intp) + for j in range(ndim)) + + a = as_strided(x, strides=strides, shape=shape) + result = check_internal_overlap(a) + + if result: + overlap += 1 + else: + no_overlap += 1 + + +def test_non_ndarray_inputs(): + # Regression check for gh-5604 + + class MyArray: + def __init__(self, data): + self.data = data + + @property + def __array_interface__(self): + return self.data.__array_interface__ + + class MyArray2: + def __init__(self, data): + self.data = data + + def __array__(self): + return self.data + + for cls in [MyArray, MyArray2]: + x = np.arange(5) + + assert_(np.may_share_memory(cls(x[::2]), x[1::2])) + assert_(not np.shares_memory(cls(x[::2]), x[1::2])) + + assert_(np.shares_memory(cls(x[1::3]), x[::2])) + assert_(np.may_share_memory(cls(x[1::3]), x[::2])) + + +def view_element_first_byte(x): + """Construct an array viewing the first byte of each element of `x`""" + from numpy.lib.stride_tricks import DummyArray + interface = dict(x.__array_interface__) + interface['typestr'] = '|b1' + interface['descr'] = [('', '|b1')] + return np.asarray(DummyArray(interface, x)) + + +def assert_copy_equivalent(operation, args, out, **kwargs): + """ + Check that operation(*args, out=out) produces results + equivalent to out[...] = operation(*args, out=out.copy()) + """ + + kwargs['out'] = out + kwargs2 = dict(kwargs) + kwargs2['out'] = out.copy() + + out_orig = out.copy() + out[...] = operation(*args, **kwargs2) + expected = out.copy() + out[...] = out_orig + + got = operation(*args, **kwargs).copy() + + if (got != expected).any(): + assert_equal(got, expected) + + +class TestUFunc: + """ + Test ufunc call memory overlap handling + """ + + def check_unary_fuzz(self, operation, get_out_axis_size, dtype=np.int16, + count=5000): + shapes = [7, 13, 8, 21, 29, 32] + + rng = np.random.RandomState(1234) + + for ndim in range(1, 6): + x = rng.randint(0, 2**16, size=shapes[:ndim]).astype(dtype) + + it = iter_random_view_pairs(x, same_steps=False, equal_size=True) + + min_count = count // (ndim + 1)**2 + + overlapping = 0 + while overlapping < min_count: + a, b = next(it) + + a_orig = a.copy() + b_orig = b.copy() + + if get_out_axis_size is None: + assert_copy_equivalent(operation, [a], out=b) + + if np.shares_memory(a, b): + overlapping += 1 + else: + for axis in itertools.chain(range(ndim), [None]): + a[...] = a_orig + b[...] = b_orig + + # Determine size for reduction axis (None if scalar) + outsize, scalarize = get_out_axis_size(a, b, axis) + if outsize == 'skip': + continue + + # Slice b to get an output array of the correct size + sl = [slice(None)] * ndim + if axis is None: + if outsize is None: + sl = [slice(0, 1)] + [0]*(ndim - 1) + else: + sl = [slice(0, outsize)] + [0]*(ndim - 1) + else: + if outsize is None: + k = b.shape[axis]//2 + if ndim == 1: + sl[axis] = slice(k, k + 1) + else: + sl[axis] = k + else: + assert b.shape[axis] >= outsize + sl[axis] = slice(0, outsize) + b_out = b[tuple(sl)] + + if scalarize: + b_out = b_out.reshape([]) + + if np.shares_memory(a, b_out): + overlapping += 1 + + # Check result + assert_copy_equivalent(operation, [a], out=b_out, axis=axis) + + @pytest.mark.slow + def test_unary_ufunc_call_fuzz(self): + self.check_unary_fuzz(np.invert, None, np.int16) + + def test_binary_ufunc_accumulate_fuzz(self): + def get_out_axis_size(a, b, axis): + if axis is None: + if a.ndim == 1: + return a.size, False + else: + return 'skip', False # accumulate doesn't support this + else: + return a.shape[axis], False + + self.check_unary_fuzz(np.add.accumulate, get_out_axis_size, + dtype=np.int16, count=500) + + def test_binary_ufunc_reduce_fuzz(self): + def get_out_axis_size(a, b, axis): + return None, (axis is None or a.ndim == 1) + + self.check_unary_fuzz(np.add.reduce, get_out_axis_size, + dtype=np.int16, count=500) + + def test_binary_ufunc_reduceat_fuzz(self): + def get_out_axis_size(a, b, axis): + if axis is None: + if a.ndim == 1: + return a.size, False + else: + return 'skip', False # reduceat doesn't support this + else: + return a.shape[axis], False + + def do_reduceat(a, out, axis): + if axis is None: + size = len(a) + step = size//len(out) + else: + size = a.shape[axis] + step = a.shape[axis] // out.shape[axis] + idx = np.arange(0, size, step) + return np.add.reduceat(a, idx, out=out, axis=axis) + + self.check_unary_fuzz(do_reduceat, get_out_axis_size, + dtype=np.int16, count=500) + + def test_binary_ufunc_reduceat_manual(self): + def check(ufunc, a, ind, out): + c1 = ufunc.reduceat(a.copy(), ind.copy(), out=out.copy()) + c2 = ufunc.reduceat(a, ind, out=out) + assert_array_equal(c1, c2) + + # Exactly same input/output arrays + a = np.arange(10000, dtype=np.int16) + check(np.add, a, a[::-1].copy(), a) + + # Overlap with index + a = np.arange(10000, dtype=np.int16) + check(np.add, a, a[::-1], a) + + @pytest.mark.slow + def test_unary_gufunc_fuzz(self): + shapes = [7, 13, 8, 21, 29, 32] + gufunc = _umath_tests.euclidean_pdist + + rng = np.random.RandomState(1234) + + for ndim in range(2, 6): + x = rng.rand(*shapes[:ndim]) + + it = iter_random_view_pairs(x, same_steps=False, equal_size=True) + + min_count = 500 // (ndim + 1)**2 + + overlapping = 0 + while overlapping < min_count: + a, b = next(it) + + if min(a.shape[-2:]) < 2 or min(b.shape[-2:]) < 2 or a.shape[-1] < 2: + continue + + # Ensure the shapes are so that euclidean_pdist is happy + if b.shape[-1] > b.shape[-2]: + b = b[...,0,:] + else: + b = b[...,:,0] + + n = a.shape[-2] + p = n * (n - 1) // 2 + if p <= b.shape[-1] and p > 0: + b = b[...,:p] + else: + n = max(2, int(np.sqrt(b.shape[-1]))//2) + p = n * (n - 1) // 2 + a = a[...,:n,:] + b = b[...,:p] + + # Call + if np.shares_memory(a, b): + overlapping += 1 + + with np.errstate(over='ignore', invalid='ignore'): + assert_copy_equivalent(gufunc, [a], out=b) + + def test_ufunc_at_manual(self): + def check(ufunc, a, ind, b=None): + a0 = a.copy() + if b is None: + ufunc.at(a0, ind.copy()) + c1 = a0.copy() + ufunc.at(a, ind) + c2 = a.copy() + else: + ufunc.at(a0, ind.copy(), b.copy()) + c1 = a0.copy() + ufunc.at(a, ind, b) + c2 = a.copy() + assert_array_equal(c1, c2) + + # Overlap with index + a = np.arange(10000, dtype=np.int16) + check(np.invert, a[::-1], a) + + # Overlap with second data array + a = np.arange(100, dtype=np.int16) + ind = np.arange(0, 100, 2, dtype=np.int16) + check(np.add, a, ind, a[25:75]) + + def test_unary_ufunc_1d_manual(self): + # Exercise branches in PyArray_EQUIVALENTLY_ITERABLE + + def check(a, b): + a_orig = a.copy() + b_orig = b.copy() + + b0 = b.copy() + c1 = ufunc(a, out=b0) + c2 = ufunc(a, out=b) + assert_array_equal(c1, c2) + + # Trigger "fancy ufunc loop" code path + mask = view_element_first_byte(b).view(np.bool_) + + a[...] = a_orig + b[...] = b_orig + c1 = ufunc(a, out=b.copy(), where=mask.copy()).copy() + + a[...] = a_orig + b[...] = b_orig + c2 = ufunc(a, out=b, where=mask.copy()).copy() + + # Also, mask overlapping with output + a[...] = a_orig + b[...] = b_orig + c3 = ufunc(a, out=b, where=mask).copy() + + assert_array_equal(c1, c2) + assert_array_equal(c1, c3) + + dtypes = [np.int8, np.int16, np.int32, np.int64, np.float32, + np.float64, np.complex64, np.complex128] + dtypes = [np.dtype(x) for x in dtypes] + + for dtype in dtypes: + if np.issubdtype(dtype, np.integer): + ufunc = np.invert + else: + ufunc = np.reciprocal + + n = 1000 + k = 10 + indices = [ + np.index_exp[:n], + np.index_exp[k:k+n], + np.index_exp[n-1::-1], + np.index_exp[k+n-1:k-1:-1], + np.index_exp[:2*n:2], + np.index_exp[k:k+2*n:2], + np.index_exp[2*n-1::-2], + np.index_exp[k+2*n-1:k-1:-2], + ] + + for xi, yi in itertools.product(indices, indices): + v = np.arange(1, 1 + n*2 + k, dtype=dtype) + x = v[xi] + y = v[yi] + + with np.errstate(all='ignore'): + check(x, y) + + # Scalar cases + check(x[:1], y) + check(x[-1:], y) + check(x[:1].reshape([]), y) + check(x[-1:].reshape([]), y) + + def test_unary_ufunc_where_same(self): + # Check behavior at wheremask overlap + ufunc = np.invert + + def check(a, out, mask): + c1 = ufunc(a, out=out.copy(), where=mask.copy()) + c2 = ufunc(a, out=out, where=mask) + assert_array_equal(c1, c2) + + # Check behavior with same input and output arrays + x = np.arange(100).astype(np.bool_) + check(x, x, x) + check(x, x.copy(), x) + check(x, x, x.copy()) + + @pytest.mark.slow + def test_binary_ufunc_1d_manual(self): + ufunc = np.add + + def check(a, b, c): + c0 = c.copy() + c1 = ufunc(a, b, out=c0) + c2 = ufunc(a, b, out=c) + assert_array_equal(c1, c2) + + for dtype in [np.int8, np.int16, np.int32, np.int64, + np.float32, np.float64, np.complex64, np.complex128]: + # Check different data dependency orders + + n = 1000 + k = 10 + + indices = [] + for p in [1, 2]: + indices.extend([ + np.index_exp[:p*n:p], + np.index_exp[k:k+p*n:p], + np.index_exp[p*n-1::-p], + np.index_exp[k+p*n-1:k-1:-p], + ]) + + for x, y, z in itertools.product(indices, indices, indices): + v = np.arange(6*n).astype(dtype) + x = v[x] + y = v[y] + z = v[z] + + check(x, y, z) + + # Scalar cases + check(x[:1], y, z) + check(x[-1:], y, z) + check(x[:1].reshape([]), y, z) + check(x[-1:].reshape([]), y, z) + check(x, y[:1], z) + check(x, y[-1:], z) + check(x, y[:1].reshape([]), z) + check(x, y[-1:].reshape([]), z) + + def test_inplace_op_simple_manual(self): + rng = np.random.RandomState(1234) + x = rng.rand(200, 200) # bigger than bufsize + + x += x.T + assert_array_equal(x - x.T, 0) diff --git a/venv/Lib/site-packages/numpy/core/tests/test_memmap.py b/venv/Lib/site-packages/numpy/core/tests/test_memmap.py new file mode 100644 index 0000000..a1e0c8f --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/tests/test_memmap.py @@ -0,0 +1,218 @@ +import sys +import os +import shutil +import mmap +import pytest +from pathlib import Path +from tempfile import NamedTemporaryFile, TemporaryFile, mktemp, mkdtemp + +from numpy import ( + memmap, sum, average, product, ndarray, isscalar, add, subtract, multiply) + +from numpy import arange, allclose, asarray +from numpy.testing import ( + assert_, assert_equal, assert_array_equal, suppress_warnings, IS_PYPY, + break_cycles + ) + +class TestMemmap: + def setup(self): + self.tmpfp = NamedTemporaryFile(prefix='mmap') + self.tempdir = mkdtemp() + self.shape = (3, 4) + self.dtype = 'float32' + self.data = arange(12, dtype=self.dtype) + self.data.resize(self.shape) + + def teardown(self): + self.tmpfp.close() + self.data = None + if IS_PYPY: + break_cycles() + break_cycles() + shutil.rmtree(self.tempdir) + + def test_roundtrip(self): + # Write data to file + fp = memmap(self.tmpfp, dtype=self.dtype, mode='w+', + shape=self.shape) + fp[:] = self.data[:] + del fp # Test __del__ machinery, which handles cleanup + + # Read data back from file + newfp = memmap(self.tmpfp, dtype=self.dtype, mode='r', + shape=self.shape) + assert_(allclose(self.data, newfp)) + assert_array_equal(self.data, newfp) + assert_equal(newfp.flags.writeable, False) + + def test_open_with_filename(self): + tmpname = mktemp('', 'mmap', dir=self.tempdir) + fp = memmap(tmpname, dtype=self.dtype, mode='w+', + shape=self.shape) + fp[:] = self.data[:] + del fp + + def test_unnamed_file(self): + with TemporaryFile() as f: + fp = memmap(f, dtype=self.dtype, shape=self.shape) + del fp + + def test_attributes(self): + offset = 1 + mode = "w+" + fp = memmap(self.tmpfp, dtype=self.dtype, mode=mode, + shape=self.shape, offset=offset) + assert_equal(offset, fp.offset) + assert_equal(mode, fp.mode) + del fp + + def test_filename(self): + tmpname = mktemp('', 'mmap', dir=self.tempdir) + fp = memmap(tmpname, dtype=self.dtype, mode='w+', + shape=self.shape) + abspath = os.path.abspath(tmpname) + fp[:] = self.data[:] + assert_equal(abspath, fp.filename) + b = fp[:1] + assert_equal(abspath, b.filename) + del b + del fp + + def test_path(self): + tmpname = mktemp('', 'mmap', dir=self.tempdir) + fp = memmap(Path(tmpname), dtype=self.dtype, mode='w+', + shape=self.shape) + # os.path.realpath does not resolve symlinks on Windows + # see: https://bugs.python.org/issue9949 + # use Path.resolve, just as memmap class does internally + abspath = str(Path(tmpname).resolve()) + fp[:] = self.data[:] + assert_equal(abspath, str(fp.filename.resolve())) + b = fp[:1] + assert_equal(abspath, str(b.filename.resolve())) + del b + del fp + + def test_filename_fileobj(self): + fp = memmap(self.tmpfp, dtype=self.dtype, mode="w+", + shape=self.shape) + assert_equal(fp.filename, self.tmpfp.name) + + @pytest.mark.skipif(sys.platform == 'gnu0', + reason="Known to fail on hurd") + def test_flush(self): + fp = memmap(self.tmpfp, dtype=self.dtype, mode='w+', + shape=self.shape) + fp[:] = self.data[:] + assert_equal(fp[0], self.data[0]) + fp.flush() + + def test_del(self): + # Make sure a view does not delete the underlying mmap + fp_base = memmap(self.tmpfp, dtype=self.dtype, mode='w+', + shape=self.shape) + fp_base[0] = 5 + fp_view = fp_base[0:1] + assert_equal(fp_view[0], 5) + del fp_view + # Should still be able to access and assign values after + # deleting the view + assert_equal(fp_base[0], 5) + fp_base[0] = 6 + assert_equal(fp_base[0], 6) + + def test_arithmetic_drops_references(self): + fp = memmap(self.tmpfp, dtype=self.dtype, mode='w+', + shape=self.shape) + tmp = (fp + 10) + if isinstance(tmp, memmap): + assert_(tmp._mmap is not fp._mmap) + + def test_indexing_drops_references(self): + fp = memmap(self.tmpfp, dtype=self.dtype, mode='w+', + shape=self.shape) + tmp = fp[(1, 2), (2, 3)] + if isinstance(tmp, memmap): + assert_(tmp._mmap is not fp._mmap) + + def test_slicing_keeps_references(self): + fp = memmap(self.tmpfp, dtype=self.dtype, mode='w+', + shape=self.shape) + assert_(fp[:2, :2]._mmap is fp._mmap) + + def test_view(self): + fp = memmap(self.tmpfp, dtype=self.dtype, shape=self.shape) + new1 = fp.view() + new2 = new1.view() + assert_(new1.base is fp) + assert_(new2.base is fp) + new_array = asarray(fp) + assert_(new_array.base is fp) + + def test_ufunc_return_ndarray(self): + fp = memmap(self.tmpfp, dtype=self.dtype, shape=self.shape) + fp[:] = self.data + + with suppress_warnings() as sup: + sup.filter(FutureWarning, "np.average currently does not preserve") + for unary_op in [sum, average, product]: + result = unary_op(fp) + assert_(isscalar(result)) + assert_(result.__class__ is self.data[0, 0].__class__) + + assert_(unary_op(fp, axis=0).__class__ is ndarray) + assert_(unary_op(fp, axis=1).__class__ is ndarray) + + for binary_op in [add, subtract, multiply]: + assert_(binary_op(fp, self.data).__class__ is ndarray) + assert_(binary_op(self.data, fp).__class__ is ndarray) + assert_(binary_op(fp, fp).__class__ is ndarray) + + fp += 1 + assert(fp.__class__ is memmap) + add(fp, 1, out=fp) + assert(fp.__class__ is memmap) + + def test_getitem(self): + fp = memmap(self.tmpfp, dtype=self.dtype, shape=self.shape) + fp[:] = self.data + + assert_(fp[1:, :-1].__class__ is memmap) + # Fancy indexing returns a copy that is not memmapped + assert_(fp[[0, 1]].__class__ is ndarray) + + def test_memmap_subclass(self): + class MemmapSubClass(memmap): + pass + + fp = MemmapSubClass(self.tmpfp, dtype=self.dtype, shape=self.shape) + fp[:] = self.data + + # We keep previous behavior for subclasses of memmap, i.e. the + # ufunc and __getitem__ output is never turned into a ndarray + assert_(sum(fp, axis=0).__class__ is MemmapSubClass) + assert_(sum(fp).__class__ is MemmapSubClass) + assert_(fp[1:, :-1].__class__ is MemmapSubClass) + assert(fp[[0, 1]].__class__ is MemmapSubClass) + + def test_mmap_offset_greater_than_allocation_granularity(self): + size = 5 * mmap.ALLOCATIONGRANULARITY + offset = mmap.ALLOCATIONGRANULARITY + 1 + fp = memmap(self.tmpfp, shape=size, mode='w+', offset=offset) + assert_(fp.offset == offset) + + def test_no_shape(self): + self.tmpfp.write(b'a'*16) + mm = memmap(self.tmpfp, dtype='float64') + assert_equal(mm.shape, (2,)) + + def test_empty_array(self): + # gh-12653 + with pytest.raises(ValueError, match='empty file'): + memmap(self.tmpfp, shape=(0,4), mode='w+') + + self.tmpfp.write(b'\0') + + # ok now the file is not empty + memmap(self.tmpfp, shape=(0,4), mode='w+') diff --git a/venv/Lib/site-packages/numpy/core/tests/test_multiarray.py b/venv/Lib/site-packages/numpy/core/tests/test_multiarray.py new file mode 100644 index 0000000..6335a47 --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/tests/test_multiarray.py @@ -0,0 +1,8743 @@ +import collections.abc +import tempfile +import sys +import shutil +import warnings +import operator +import io +import itertools +import functools +import ctypes +import os +import gc +import weakref +import pytest +from contextlib import contextmanager + +from numpy.compat import pickle + +import pathlib +import builtins +from decimal import Decimal + +import numpy as np +import numpy.core._multiarray_tests as _multiarray_tests +from numpy.core._rational_tests import rational +from numpy.testing import ( + assert_, assert_raises, assert_warns, assert_equal, assert_almost_equal, + assert_array_equal, assert_raises_regex, assert_array_almost_equal, + assert_allclose, IS_PYPY, HAS_REFCOUNT, assert_array_less, runstring, + temppath, suppress_warnings, break_cycles, + ) +from numpy.testing._private.utils import _no_tracing +from numpy.core.tests._locales import CommaDecimalPointLocale + +# Need to test an object that does not fully implement math interface +from datetime import timedelta, datetime + + +def _aligned_zeros(shape, dtype=float, order="C", align=None): + """ + Allocate a new ndarray with aligned memory. + + The ndarray is guaranteed *not* aligned to twice the requested alignment. + Eg, if align=4, guarantees it is not aligned to 8. If align=None uses + dtype.alignment.""" + dtype = np.dtype(dtype) + if dtype == np.dtype(object): + # Can't do this, fall back to standard allocation (which + # should always be sufficiently aligned) + if align is not None: + raise ValueError("object array alignment not supported") + return np.zeros(shape, dtype=dtype, order=order) + if align is None: + align = dtype.alignment + if not hasattr(shape, '__len__'): + shape = (shape,) + size = functools.reduce(operator.mul, shape) * dtype.itemsize + buf = np.empty(size + 2*align + 1, np.uint8) + + ptr = buf.__array_interface__['data'][0] + offset = ptr % align + if offset != 0: + offset = align - offset + if (ptr % (2*align)) == 0: + offset += align + + # Note: slices producing 0-size arrays do not necessarily change + # data pointer --- so we use and allocate size+1 + buf = buf[offset:offset+size+1][:-1] + data = np.ndarray(shape, dtype, buf, order=order) + data.fill(0) + return data + + +class TestFlags: + def setup(self): + self.a = np.arange(10) + + def test_writeable(self): + mydict = locals() + self.a.flags.writeable = False + assert_raises(ValueError, runstring, 'self.a[0] = 3', mydict) + assert_raises(ValueError, runstring, 'self.a[0:1].itemset(3)', mydict) + self.a.flags.writeable = True + self.a[0] = 5 + self.a[0] = 0 + + def test_writeable_any_base(self): + # Ensure that any base being writeable is sufficient to change flag; + # this is especially interesting for arrays from an array interface. + arr = np.arange(10) + + class subclass(np.ndarray): + pass + + # Create subclass so base will not be collapsed, this is OK to change + view1 = arr.view(subclass) + view2 = view1[...] + arr.flags.writeable = False + view2.flags.writeable = False + view2.flags.writeable = True # Can be set to True again. + + arr = np.arange(10) + + class frominterface: + def __init__(self, arr): + self.arr = arr + self.__array_interface__ = arr.__array_interface__ + + view1 = np.asarray(frominterface) + view2 = view1[...] + view2.flags.writeable = False + view2.flags.writeable = True + + view1.flags.writeable = False + view2.flags.writeable = False + with assert_raises(ValueError): + # Must assume not writeable, since only base is not: + view2.flags.writeable = True + + def test_writeable_from_readonly(self): + # gh-9440 - make sure fromstring, from buffer on readonly buffers + # set writeable False + data = b'\x00' * 100 + vals = np.frombuffer(data, 'B') + assert_raises(ValueError, vals.setflags, write=True) + types = np.dtype( [('vals', 'u1'), ('res3', 'S4')] ) + values = np.core.records.fromstring(data, types) + vals = values['vals'] + assert_raises(ValueError, vals.setflags, write=True) + + def test_writeable_from_buffer(self): + data = bytearray(b'\x00' * 100) + vals = np.frombuffer(data, 'B') + assert_(vals.flags.writeable) + vals.setflags(write=False) + assert_(vals.flags.writeable is False) + vals.setflags(write=True) + assert_(vals.flags.writeable) + types = np.dtype( [('vals', 'u1'), ('res3', 'S4')] ) + values = np.core.records.fromstring(data, types) + vals = values['vals'] + assert_(vals.flags.writeable) + vals.setflags(write=False) + assert_(vals.flags.writeable is False) + vals.setflags(write=True) + assert_(vals.flags.writeable) + + @pytest.mark.skipif(IS_PYPY, reason="PyPy always copies") + def test_writeable_pickle(self): + import pickle + # Small arrays will be copied without setting base. + # See condition for using PyArray_SetBaseObject in + # array_setstate. + a = np.arange(1000) + for v in range(pickle.HIGHEST_PROTOCOL): + vals = pickle.loads(pickle.dumps(a, v)) + assert_(vals.flags.writeable) + assert_(isinstance(vals.base, bytes)) + + def test_writeable_from_c_data(self): + # Test that the writeable flag can be changed for an array wrapping + # low level C-data, but not owning its data. + # Also see that this is deprecated to change from python. + from numpy.core._multiarray_tests import get_c_wrapping_array + + arr_writeable = get_c_wrapping_array(True) + assert not arr_writeable.flags.owndata + assert arr_writeable.flags.writeable + view = arr_writeable[...] + + # Toggling the writeable flag works on the view: + view.flags.writeable = False + assert not view.flags.writeable + view.flags.writeable = True + assert view.flags.writeable + # Flag can be unset on the arr_writeable: + arr_writeable.flags.writeable = False + + arr_readonly = get_c_wrapping_array(False) + assert not arr_readonly.flags.owndata + assert not arr_readonly.flags.writeable + + for arr in [arr_writeable, arr_readonly]: + view = arr[...] + view.flags.writeable = False # make sure it is readonly + arr.flags.writeable = False + assert not arr.flags.writeable + + with assert_raises(ValueError): + view.flags.writeable = True + + with warnings.catch_warnings(): + warnings.simplefilter("error", DeprecationWarning) + with assert_raises(DeprecationWarning): + arr.flags.writeable = True + + with assert_warns(DeprecationWarning): + arr.flags.writeable = True + + def test_warnonwrite(self): + a = np.arange(10) + a.flags._warn_on_write = True + with warnings.catch_warnings(record=True) as w: + warnings.filterwarnings('always') + a[1] = 10 + a[2] = 10 + # only warn once + assert_(len(w) == 1) + + @pytest.mark.parametrize(["flag", "flag_value", "writeable"], + [("writeable", True, True), + # Delete _warn_on_write after deprecation and simplify + # the parameterization: + ("_warn_on_write", True, False), + ("writeable", False, False)]) + def test_readonly_flag_protocols(self, flag, flag_value, writeable): + a = np.arange(10) + setattr(a.flags, flag, flag_value) + + class MyArr(): + __array_struct__ = a.__array_struct__ + + assert memoryview(a).readonly is not writeable + assert a.__array_interface__['data'][1] is not writeable + assert np.asarray(MyArr()).flags.writeable is writeable + + def test_otherflags(self): + assert_equal(self.a.flags.carray, True) + assert_equal(self.a.flags['C'], True) + assert_equal(self.a.flags.farray, False) + assert_equal(self.a.flags.behaved, True) + assert_equal(self.a.flags.fnc, False) + assert_equal(self.a.flags.forc, True) + assert_equal(self.a.flags.owndata, True) + assert_equal(self.a.flags.writeable, True) + assert_equal(self.a.flags.aligned, True) + with assert_warns(DeprecationWarning): + assert_equal(self.a.flags.updateifcopy, False) + with assert_warns(DeprecationWarning): + assert_equal(self.a.flags['U'], False) + assert_equal(self.a.flags['UPDATEIFCOPY'], False) + assert_equal(self.a.flags.writebackifcopy, False) + assert_equal(self.a.flags['X'], False) + assert_equal(self.a.flags['WRITEBACKIFCOPY'], False) + + def test_string_align(self): + a = np.zeros(4, dtype=np.dtype('|S4')) + assert_(a.flags.aligned) + # not power of two are accessed byte-wise and thus considered aligned + a = np.zeros(5, dtype=np.dtype('|S4')) + assert_(a.flags.aligned) + + def test_void_align(self): + a = np.zeros(4, dtype=np.dtype([("a", "i4"), ("b", "i4")])) + assert_(a.flags.aligned) + + +class TestHash: + # see #3793 + def test_int(self): + for st, ut, s in [(np.int8, np.uint8, 8), + (np.int16, np.uint16, 16), + (np.int32, np.uint32, 32), + (np.int64, np.uint64, 64)]: + for i in range(1, s): + assert_equal(hash(st(-2**i)), hash(-2**i), + err_msg="%r: -2**%d" % (st, i)) + assert_equal(hash(st(2**(i - 1))), hash(2**(i - 1)), + err_msg="%r: 2**%d" % (st, i - 1)) + assert_equal(hash(st(2**i - 1)), hash(2**i - 1), + err_msg="%r: 2**%d - 1" % (st, i)) + + i = max(i - 1, 1) + assert_equal(hash(ut(2**(i - 1))), hash(2**(i - 1)), + err_msg="%r: 2**%d" % (ut, i - 1)) + assert_equal(hash(ut(2**i - 1)), hash(2**i - 1), + err_msg="%r: 2**%d - 1" % (ut, i)) + + +class TestAttributes: + def setup(self): + self.one = np.arange(10) + self.two = np.arange(20).reshape(4, 5) + self.three = np.arange(60, dtype=np.float64).reshape(2, 5, 6) + + def test_attributes(self): + assert_equal(self.one.shape, (10,)) + assert_equal(self.two.shape, (4, 5)) + assert_equal(self.three.shape, (2, 5, 6)) + self.three.shape = (10, 3, 2) + assert_equal(self.three.shape, (10, 3, 2)) + self.three.shape = (2, 5, 6) + assert_equal(self.one.strides, (self.one.itemsize,)) + num = self.two.itemsize + assert_equal(self.two.strides, (5*num, num)) + num = self.three.itemsize + assert_equal(self.three.strides, (30*num, 6*num, num)) + assert_equal(self.one.ndim, 1) + assert_equal(self.two.ndim, 2) + assert_equal(self.three.ndim, 3) + num = self.two.itemsize + assert_equal(self.two.size, 20) + assert_equal(self.two.nbytes, 20*num) + assert_equal(self.two.itemsize, self.two.dtype.itemsize) + assert_equal(self.two.base, np.arange(20)) + + def test_dtypeattr(self): + assert_equal(self.one.dtype, np.dtype(np.int_)) + assert_equal(self.three.dtype, np.dtype(np.float_)) + assert_equal(self.one.dtype.char, 'l') + assert_equal(self.three.dtype.char, 'd') + assert_(self.three.dtype.str[0] in '<>') + assert_equal(self.one.dtype.str[1], 'i') + assert_equal(self.three.dtype.str[1], 'f') + + def test_int_subclassing(self): + # Regression test for https://github.com/numpy/numpy/pull/3526 + + numpy_int = np.int_(0) + + # int_ doesn't inherit from Python int, because it's not fixed-width + assert_(not isinstance(numpy_int, int)) + + def test_stridesattr(self): + x = self.one + + def make_array(size, offset, strides): + return np.ndarray(size, buffer=x, dtype=int, + offset=offset*x.itemsize, + strides=strides*x.itemsize) + + assert_equal(make_array(4, 4, -1), np.array([4, 3, 2, 1])) + assert_raises(ValueError, make_array, 4, 4, -2) + assert_raises(ValueError, make_array, 4, 2, -1) + assert_raises(ValueError, make_array, 8, 3, 1) + assert_equal(make_array(8, 3, 0), np.array([3]*8)) + # Check behavior reported in gh-2503: + assert_raises(ValueError, make_array, (2, 3), 5, np.array([-2, -3])) + make_array(0, 0, 10) + + def test_set_stridesattr(self): + x = self.one + + def make_array(size, offset, strides): + try: + r = np.ndarray([size], dtype=int, buffer=x, + offset=offset*x.itemsize) + except Exception as e: + raise RuntimeError(e) + r.strides = strides = strides*x.itemsize + return r + + assert_equal(make_array(4, 4, -1), np.array([4, 3, 2, 1])) + assert_equal(make_array(7, 3, 1), np.array([3, 4, 5, 6, 7, 8, 9])) + assert_raises(ValueError, make_array, 4, 4, -2) + assert_raises(ValueError, make_array, 4, 2, -1) + assert_raises(RuntimeError, make_array, 8, 3, 1) + # Check that the true extent of the array is used. + # Test relies on as_strided base not exposing a buffer. + x = np.lib.stride_tricks.as_strided(np.arange(1), (10, 10), (0, 0)) + + def set_strides(arr, strides): + arr.strides = strides + + assert_raises(ValueError, set_strides, x, (10*x.itemsize, x.itemsize)) + + # Test for offset calculations: + x = np.lib.stride_tricks.as_strided(np.arange(10, dtype=np.int8)[-1], + shape=(10,), strides=(-1,)) + assert_raises(ValueError, set_strides, x[::-1], -1) + a = x[::-1] + a.strides = 1 + a[::2].strides = 2 + + # test 0d + arr_0d = np.array(0) + arr_0d.strides = () + assert_raises(TypeError, set_strides, arr_0d, None) + + def test_fill(self): + for t in "?bhilqpBHILQPfdgFDGO": + x = np.empty((3, 2, 1), t) + y = np.empty((3, 2, 1), t) + x.fill(1) + y[...] = 1 + assert_equal(x, y) + + def test_fill_max_uint64(self): + x = np.empty((3, 2, 1), dtype=np.uint64) + y = np.empty((3, 2, 1), dtype=np.uint64) + value = 2**64 - 1 + y[...] = value + x.fill(value) + assert_array_equal(x, y) + + def test_fill_struct_array(self): + # Filling from a scalar + x = np.array([(0, 0.0), (1, 1.0)], dtype='i4,f8') + x.fill(x[0]) + assert_equal(x['f1'][1], x['f1'][0]) + # Filling from a tuple that can be converted + # to a scalar + x = np.zeros(2, dtype=[('a', 'f8'), ('b', 'i4')]) + x.fill((3.5, -2)) + assert_array_equal(x['a'], [3.5, 3.5]) + assert_array_equal(x['b'], [-2, -2]) + + +class TestArrayConstruction: + def test_array(self): + d = np.ones(6) + r = np.array([d, d]) + assert_equal(r, np.ones((2, 6))) + + d = np.ones(6) + tgt = np.ones((2, 6)) + r = np.array([d, d]) + assert_equal(r, tgt) + tgt[1] = 2 + r = np.array([d, d + 1]) + assert_equal(r, tgt) + + d = np.ones(6) + r = np.array([[d, d]]) + assert_equal(r, np.ones((1, 2, 6))) + + d = np.ones(6) + r = np.array([[d, d], [d, d]]) + assert_equal(r, np.ones((2, 2, 6))) + + d = np.ones((6, 6)) + r = np.array([d, d]) + assert_equal(r, np.ones((2, 6, 6))) + + d = np.ones((6, )) + r = np.array([[d, d + 1], d + 2], dtype=object) + assert_equal(len(r), 2) + assert_equal(r[0], [d, d + 1]) + assert_equal(r[1], d + 2) + + tgt = np.ones((2, 3), dtype=bool) + tgt[0, 2] = False + tgt[1, 0:2] = False + r = np.array([[True, True, False], [False, False, True]]) + assert_equal(r, tgt) + r = np.array([[True, False], [True, False], [False, True]]) + assert_equal(r, tgt.T) + + def test_array_empty(self): + assert_raises(TypeError, np.array) + + def test_array_copy_false(self): + d = np.array([1, 2, 3]) + e = np.array(d, copy=False) + d[1] = 3 + assert_array_equal(e, [1, 3, 3]) + e = np.array(d, copy=False, order='F') + d[1] = 4 + assert_array_equal(e, [1, 4, 3]) + e[2] = 7 + assert_array_equal(d, [1, 4, 7]) + + def test_array_copy_true(self): + d = np.array([[1,2,3], [1, 2, 3]]) + e = np.array(d, copy=True) + d[0, 1] = 3 + e[0, 2] = -7 + assert_array_equal(e, [[1, 2, -7], [1, 2, 3]]) + assert_array_equal(d, [[1, 3, 3], [1, 2, 3]]) + e = np.array(d, copy=True, order='F') + d[0, 1] = 5 + e[0, 2] = 7 + assert_array_equal(e, [[1, 3, 7], [1, 2, 3]]) + assert_array_equal(d, [[1, 5, 3], [1,2,3]]) + + def test_array_cont(self): + d = np.ones(10)[::2] + assert_(np.ascontiguousarray(d).flags.c_contiguous) + assert_(np.ascontiguousarray(d).flags.f_contiguous) + assert_(np.asfortranarray(d).flags.c_contiguous) + assert_(np.asfortranarray(d).flags.f_contiguous) + d = np.ones((10, 10))[::2,::2] + assert_(np.ascontiguousarray(d).flags.c_contiguous) + assert_(np.asfortranarray(d).flags.f_contiguous) + + +class TestAssignment: + def test_assignment_broadcasting(self): + a = np.arange(6).reshape(2, 3) + + # Broadcasting the input to the output + a[...] = np.arange(3) + assert_equal(a, [[0, 1, 2], [0, 1, 2]]) + a[...] = np.arange(2).reshape(2, 1) + assert_equal(a, [[0, 0, 0], [1, 1, 1]]) + + # For compatibility with <= 1.5, a limited version of broadcasting + # the output to the input. + # + # This behavior is inconsistent with NumPy broadcasting + # in general, because it only uses one of the two broadcasting + # rules (adding a new "1" dimension to the left of the shape), + # applied to the output instead of an input. In NumPy 2.0, this kind + # of broadcasting assignment will likely be disallowed. + a[...] = np.arange(6)[::-1].reshape(1, 2, 3) + assert_equal(a, [[5, 4, 3], [2, 1, 0]]) + # The other type of broadcasting would require a reduction operation. + + def assign(a, b): + a[...] = b + + assert_raises(ValueError, assign, a, np.arange(12).reshape(2, 2, 3)) + + def test_assignment_errors(self): + # Address issue #2276 + class C: + pass + a = np.zeros(1) + + def assign(v): + a[0] = v + + assert_raises((AttributeError, TypeError), assign, C()) + assert_raises(ValueError, assign, [1]) + + def test_unicode_assignment(self): + # gh-5049 + from numpy.core.numeric import set_string_function + + @contextmanager + def inject_str(s): + """ replace ndarray.__str__ temporarily """ + set_string_function(lambda x: s, repr=False) + try: + yield + finally: + set_string_function(None, repr=False) + + a1d = np.array([u'test']) + a0d = np.array(u'done') + with inject_str(u'bad'): + a1d[0] = a0d # previously this would invoke __str__ + assert_equal(a1d[0], u'done') + + # this would crash for the same reason + np.array([np.array(u'\xe5\xe4\xf6')]) + + def test_stringlike_empty_list(self): + # gh-8902 + u = np.array([u'done']) + b = np.array([b'done']) + + class bad_sequence: + def __getitem__(self): pass + def __len__(self): raise RuntimeError + + assert_raises(ValueError, operator.setitem, u, 0, []) + assert_raises(ValueError, operator.setitem, b, 0, []) + + assert_raises(ValueError, operator.setitem, u, 0, bad_sequence()) + assert_raises(ValueError, operator.setitem, b, 0, bad_sequence()) + + def test_longdouble_assignment(self): + # only relevant if longdouble is larger than float + # we're looking for loss of precision + + for dtype in (np.longdouble, np.longcomplex): + # gh-8902 + tinyb = np.nextafter(np.longdouble(0), 1).astype(dtype) + tinya = np.nextafter(np.longdouble(0), -1).astype(dtype) + + # construction + tiny1d = np.array([tinya]) + assert_equal(tiny1d[0], tinya) + + # scalar = scalar + tiny1d[0] = tinyb + assert_equal(tiny1d[0], tinyb) + + # 0d = scalar + tiny1d[0, ...] = tinya + assert_equal(tiny1d[0], tinya) + + # 0d = 0d + tiny1d[0, ...] = tinyb[...] + assert_equal(tiny1d[0], tinyb) + + # scalar = 0d + tiny1d[0] = tinyb[...] + assert_equal(tiny1d[0], tinyb) + + arr = np.array([np.array(tinya)]) + assert_equal(arr[0], tinya) + + def test_cast_to_string(self): + # cast to str should do "str(scalar)", not "str(scalar.item())" + # Example: In python2, str(float) is truncated, so we want to avoid + # str(np.float64(...).item()) as this would incorrectly truncate. + a = np.zeros(1, dtype='S20') + a[:] = np.array(['1.12345678901234567890'], dtype='f8') + assert_equal(a[0], b"1.1234567890123457") + + +class TestDtypedescr: + def test_construction(self): + d1 = np.dtype('i4') + assert_equal(d1, np.dtype(np.int32)) + d2 = np.dtype('f8') + assert_equal(d2, np.dtype(np.float64)) + + def test_byteorders(self): + assert_(np.dtype('i4')) + assert_(np.dtype([('a', 'i4')])) + + def test_structured_non_void(self): + fields = [('a', 'i8'), ('b', 'f8')]) + assert_equal(a == b, [False, True]) + + def test_casting(self): + # Check that casting a structured array to change its byte order + # works + a = np.array([(1,)], dtype=[('a', 'i4')], casting='unsafe')) + b = a.astype([('a', '>i4')]) + assert_equal(b, a.byteswap().newbyteorder()) + assert_equal(a['a'][0], b['a'][0]) + + # Check that equality comparison works on structured arrays if + # they are 'equiv'-castable + a = np.array([(5, 42), (10, 1)], dtype=[('a', '>i4'), ('b', 'f8')]) + assert_(np.can_cast(a.dtype, b.dtype, casting='equiv')) + assert_equal(a == b, [True, True]) + + # Check that 'equiv' casting can change byte order + assert_(np.can_cast(a.dtype, b.dtype, casting='equiv')) + c = a.astype(b.dtype, casting='equiv') + assert_equal(a == c, [True, True]) + + # Check that 'safe' casting can change byte order and up-cast + # fields + t = [('a', 'f8')] + assert_(np.can_cast(a.dtype, t, casting='safe')) + c = a.astype(t, casting='safe') + assert_equal((c == np.array([(5, 42), (10, 1)], dtype=t)), + [True, True]) + + # Check that 'same_kind' casting can change byte order and + # change field widths within a "kind" + t = [('a', 'f4')] + assert_(np.can_cast(a.dtype, t, casting='same_kind')) + c = a.astype(t, casting='same_kind') + assert_equal((c == np.array([(5, 42), (10, 1)], dtype=t)), + [True, True]) + + # Check that casting fails if the casting rule should fail on + # any of the fields + t = [('a', '>i8'), ('b', 'i2'), ('b', 'i8'), ('b', 'i4')] + assert_(not np.can_cast(a.dtype, t, casting=casting)) + t = [('a', '>i4'), ('b', ' false + for n in range(3): + v = np.array(b'', (dtype, n)) + assert_equal(bool(v), False) + assert_equal(bool(v[()]), False) + assert_equal(v.astype(bool), False) + assert_(isinstance(v.astype(bool), np.ndarray)) + assert_(v[()].astype(bool) is np.False_) + + # anything else -> true + for n in range(1, 4): + for val in [b'a', b'0', b' ']: + v = np.array(val, (dtype, n)) + assert_equal(bool(v), True) + assert_equal(bool(v[()]), True) + assert_equal(v.astype(bool), True) + assert_(isinstance(v.astype(bool), np.ndarray)) + assert_(v[()].astype(bool) is np.True_) + + def test_cast_from_void(self): + self._test_cast_from_flexible(np.void) + + @pytest.mark.xfail(reason="See gh-9847") + def test_cast_from_unicode(self): + self._test_cast_from_flexible(np.unicode_) + + @pytest.mark.xfail(reason="See gh-9847") + def test_cast_from_bytes(self): + self._test_cast_from_flexible(np.bytes_) + + +class TestZeroSizeFlexible: + @staticmethod + def _zeros(shape, dtype=str): + dtype = np.dtype(dtype) + if dtype == np.void: + return np.zeros(shape, dtype=(dtype, 0)) + + # not constructable directly + dtype = np.dtype([('x', dtype, 0)]) + return np.zeros(shape, dtype=dtype)['x'] + + def test_create(self): + zs = self._zeros(10, bytes) + assert_equal(zs.itemsize, 0) + zs = self._zeros(10, np.void) + assert_equal(zs.itemsize, 0) + zs = self._zeros(10, str) + assert_equal(zs.itemsize, 0) + + def _test_sort_partition(self, name, kinds, **kwargs): + # Previously, these would all hang + for dt in [bytes, np.void, str]: + zs = self._zeros(10, dt) + sort_method = getattr(zs, name) + sort_func = getattr(np, name) + for kind in kinds: + sort_method(kind=kind, **kwargs) + sort_func(zs, kind=kind, **kwargs) + + def test_sort(self): + self._test_sort_partition('sort', kinds='qhs') + + def test_argsort(self): + self._test_sort_partition('argsort', kinds='qhs') + + def test_partition(self): + self._test_sort_partition('partition', kinds=['introselect'], kth=2) + + def test_argpartition(self): + self._test_sort_partition('argpartition', kinds=['introselect'], kth=2) + + def test_resize(self): + # previously an error + for dt in [bytes, np.void, str]: + zs = self._zeros(10, dt) + zs.resize(25) + zs.resize((10, 10)) + + def test_view(self): + for dt in [bytes, np.void, str]: + zs = self._zeros(10, dt) + + # viewing as itself should be allowed + assert_equal(zs.view(dt).dtype, np.dtype(dt)) + + # viewing as any non-empty type gives an empty result + assert_equal(zs.view((dt, 1)).shape, (0,)) + + def test_dumps(self): + zs = self._zeros(10, int) + assert_equal(zs, pickle.loads(zs.dumps())) + + def test_pickle(self): + for proto in range(2, pickle.HIGHEST_PROTOCOL + 1): + for dt in [bytes, np.void, str]: + zs = self._zeros(10, dt) + p = pickle.dumps(zs, protocol=proto) + zs2 = pickle.loads(p) + + assert_equal(zs.dtype, zs2.dtype) + + @pytest.mark.skipif(pickle.HIGHEST_PROTOCOL < 5, + reason="requires pickle protocol 5") + def test_pickle_with_buffercallback(self): + array = np.arange(10) + buffers = [] + bytes_string = pickle.dumps(array, buffer_callback=buffers.append, + protocol=5) + array_from_buffer = pickle.loads(bytes_string, buffers=buffers) + # when using pickle protocol 5 with buffer callbacks, + # array_from_buffer is reconstructed from a buffer holding a view + # to the initial array's data, so modifying an element in array + # should modify it in array_from_buffer too. + array[0] = -1 + assert array_from_buffer[0] == -1, array_from_buffer[0] + + +class TestMethods: + + sort_kinds = ['quicksort', 'heapsort', 'stable'] + + def test_all_where(self): + a = np.array([[True, False, True], + [False, False, False], + [True, True, True]]) + wh_full = np.array([[True, False, True], + [False, False, False], + [True, False, True]]) + wh_lower = np.array([[False], + [False], + [True]]) + for _ax in [0, None]: + assert_equal(a.all(axis=_ax, where=wh_lower), + np.all(a[wh_lower[:,0],:], axis=_ax)) + assert_equal(np.all(a, axis=_ax, where=wh_lower), + a[wh_lower[:,0],:].all(axis=_ax)) + + assert_equal(a.all(where=wh_full), True) + assert_equal(np.all(a, where=wh_full), True) + assert_equal(a.all(where=False), True) + assert_equal(np.all(a, where=False), True) + + def test_any_where(self): + a = np.array([[True, False, True], + [False, False, False], + [True, True, True]]) + wh_full = np.array([[False, True, False], + [True, True, True], + [False, False, False]]) + wh_middle = np.array([[False], + [True], + [False]]) + for _ax in [0, None]: + assert_equal(a.any(axis=_ax, where=wh_middle), + np.any(a[wh_middle[:,0],:], axis=_ax)) + assert_equal(np.any(a, axis=_ax, where=wh_middle), + a[wh_middle[:,0],:].any(axis=_ax)) + assert_equal(a.any(where=wh_full), False) + assert_equal(np.any(a, where=wh_full), False) + assert_equal(a.any(where=False), False) + assert_equal(np.any(a, where=False), False) + + def test_compress(self): + tgt = [[5, 6, 7, 8, 9]] + arr = np.arange(10).reshape(2, 5) + out = arr.compress([0, 1], axis=0) + assert_equal(out, tgt) + + tgt = [[1, 3], [6, 8]] + out = arr.compress([0, 1, 0, 1, 0], axis=1) + assert_equal(out, tgt) + + tgt = [[1], [6]] + arr = np.arange(10).reshape(2, 5) + out = arr.compress([0, 1], axis=1) + assert_equal(out, tgt) + + arr = np.arange(10).reshape(2, 5) + out = arr.compress([0, 1]) + assert_equal(out, 1) + + def test_choose(self): + x = 2*np.ones((3,), dtype=int) + y = 3*np.ones((3,), dtype=int) + x2 = 2*np.ones((2, 3), dtype=int) + y2 = 3*np.ones((2, 3), dtype=int) + ind = np.array([0, 0, 1]) + + A = ind.choose((x, y)) + assert_equal(A, [2, 2, 3]) + + A = ind.choose((x2, y2)) + assert_equal(A, [[2, 2, 3], [2, 2, 3]]) + + A = ind.choose((x, y2)) + assert_equal(A, [[2, 2, 3], [2, 2, 3]]) + + oned = np.ones(1) + # gh-12031, caused SEGFAULT + assert_raises(TypeError, oned.choose,np.void(0), [oned]) + + out = np.array(0) + ret = np.choose(np.array(1), [10, 20, 30], out=out) + assert out is ret + assert_equal(out[()], 20) + + # gh-6272 check overlap on out + x = np.arange(5) + y = np.choose([0,0,0], [x[:3], x[:3], x[:3]], out=x[1:4], mode='wrap') + assert_equal(y, np.array([0, 1, 2])) + + def test_prod(self): + ba = [1, 2, 10, 11, 6, 5, 4] + ba2 = [[1, 2, 3, 4], [5, 6, 7, 9], [10, 3, 4, 5]] + + for ctype in [np.int16, np.uint16, np.int32, np.uint32, + np.float32, np.float64, np.complex64, np.complex128]: + a = np.array(ba, ctype) + a2 = np.array(ba2, ctype) + if ctype in ['1', 'b']: + assert_raises(ArithmeticError, a.prod) + assert_raises(ArithmeticError, a2.prod, axis=1) + else: + assert_equal(a.prod(axis=0), 26400) + assert_array_equal(a2.prod(axis=0), + np.array([50, 36, 84, 180], ctype)) + assert_array_equal(a2.prod(axis=-1), + np.array([24, 1890, 600], ctype)) + + def test_repeat(self): + m = np.array([1, 2, 3, 4, 5, 6]) + m_rect = m.reshape((2, 3)) + + A = m.repeat([1, 3, 2, 1, 1, 2]) + assert_equal(A, [1, 2, 2, 2, 3, + 3, 4, 5, 6, 6]) + + A = m.repeat(2) + assert_equal(A, [1, 1, 2, 2, 3, 3, + 4, 4, 5, 5, 6, 6]) + + A = m_rect.repeat([2, 1], axis=0) + assert_equal(A, [[1, 2, 3], + [1, 2, 3], + [4, 5, 6]]) + + A = m_rect.repeat([1, 3, 2], axis=1) + assert_equal(A, [[1, 2, 2, 2, 3, 3], + [4, 5, 5, 5, 6, 6]]) + + A = m_rect.repeat(2, axis=0) + assert_equal(A, [[1, 2, 3], + [1, 2, 3], + [4, 5, 6], + [4, 5, 6]]) + + A = m_rect.repeat(2, axis=1) + assert_equal(A, [[1, 1, 2, 2, 3, 3], + [4, 4, 5, 5, 6, 6]]) + + def test_reshape(self): + arr = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]]) + + tgt = [[1, 2, 3, 4, 5, 6], [7, 8, 9, 10, 11, 12]] + assert_equal(arr.reshape(2, 6), tgt) + + tgt = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]] + assert_equal(arr.reshape(3, 4), tgt) + + tgt = [[1, 10, 8, 6], [4, 2, 11, 9], [7, 5, 3, 12]] + assert_equal(arr.reshape((3, 4), order='F'), tgt) + + tgt = [[1, 4, 7, 10], [2, 5, 8, 11], [3, 6, 9, 12]] + assert_equal(arr.T.reshape((3, 4), order='C'), tgt) + + def test_round(self): + def check_round(arr, expected, *round_args): + assert_equal(arr.round(*round_args), expected) + # With output array + out = np.zeros_like(arr) + res = arr.round(*round_args, out=out) + assert_equal(out, expected) + assert out is res + + check_round(np.array([1.2, 1.5]), [1, 2]) + check_round(np.array(1.5), 2) + check_round(np.array([12.2, 15.5]), [10, 20], -1) + check_round(np.array([12.15, 15.51]), [12.2, 15.5], 1) + # Complex rounding + check_round(np.array([4.5 + 1.5j]), [4 + 2j]) + check_round(np.array([12.5 + 15.5j]), [10 + 20j], -1) + + def test_squeeze(self): + a = np.array([[[1], [2], [3]]]) + assert_equal(a.squeeze(), [1, 2, 3]) + assert_equal(a.squeeze(axis=(0,)), [[1], [2], [3]]) + assert_raises(ValueError, a.squeeze, axis=(1,)) + assert_equal(a.squeeze(axis=(2,)), [[1, 2, 3]]) + + def test_transpose(self): + a = np.array([[1, 2], [3, 4]]) + assert_equal(a.transpose(), [[1, 3], [2, 4]]) + assert_raises(ValueError, lambda: a.transpose(0)) + assert_raises(ValueError, lambda: a.transpose(0, 0)) + assert_raises(ValueError, lambda: a.transpose(0, 1, 2)) + + def test_sort(self): + # test ordering for floats and complex containing nans. It is only + # necessary to check the less-than comparison, so sorts that + # only follow the insertion sort path are sufficient. We only + # test doubles and complex doubles as the logic is the same. + + # check doubles + msg = "Test real sort order with nans" + a = np.array([np.nan, 1, 0]) + b = np.sort(a) + assert_equal(b, a[::-1], msg) + # check complex + msg = "Test complex sort order with nans" + a = np.zeros(9, dtype=np.complex128) + a.real += [np.nan, np.nan, np.nan, 1, 0, 1, 1, 0, 0] + a.imag += [np.nan, 1, 0, np.nan, np.nan, 1, 0, 1, 0] + b = np.sort(a) + assert_equal(b, a[::-1], msg) + + # all c scalar sorts use the same code with different types + # so it suffices to run a quick check with one type. The number + # of sorted items must be greater than ~50 to check the actual + # algorithm because quick and merge sort fall over to insertion + # sort for small arrays. + + @pytest.mark.parametrize('dtype', [np.uint8, np.uint16, np.uint32, np.uint64, + np.float16, np.float32, np.float64, + np.longdouble]) + def test_sort_unsigned(self, dtype): + a = np.arange(101, dtype=dtype) + b = a[::-1].copy() + for kind in self.sort_kinds: + msg = "scalar sort, kind=%s" % kind + c = a.copy() + c.sort(kind=kind) + assert_equal(c, a, msg) + c = b.copy() + c.sort(kind=kind) + assert_equal(c, a, msg) + + @pytest.mark.parametrize('dtype', + [np.int8, np.int16, np.int32, np.int64, np.float16, + np.float32, np.float64, np.longdouble]) + def test_sort_signed(self, dtype): + a = np.arange(-50, 51, dtype=dtype) + b = a[::-1].copy() + for kind in self.sort_kinds: + msg = "scalar sort, kind=%s" % (kind) + c = a.copy() + c.sort(kind=kind) + assert_equal(c, a, msg) + c = b.copy() + c.sort(kind=kind) + assert_equal(c, a, msg) + + @pytest.mark.parametrize('dtype', [np.float32, np.float64, np.longdouble]) + @pytest.mark.parametrize('part', ['real', 'imag']) + def test_sort_complex(self, part, dtype): + # test complex sorts. These use the same code as the scalars + # but the compare function differs. + cdtype = { + np.single: np.csingle, + np.double: np.cdouble, + np.longdouble: np.clongdouble, + }[dtype] + a = np.arange(-50, 51, dtype=dtype) + b = a[::-1].copy() + ai = (a * (1+1j)).astype(cdtype) + bi = (b * (1+1j)).astype(cdtype) + setattr(ai, part, 1) + setattr(bi, part, 1) + for kind in self.sort_kinds: + msg = "complex sort, %s part == 1, kind=%s" % (part, kind) + c = ai.copy() + c.sort(kind=kind) + assert_equal(c, ai, msg) + c = bi.copy() + c.sort(kind=kind) + assert_equal(c, ai, msg) + + def test_sort_complex_byte_swapping(self): + # test sorting of complex arrays requiring byte-swapping, gh-5441 + for endianness in '<>': + for dt in np.typecodes['Complex']: + arr = np.array([1+3.j, 2+2.j, 3+1.j], dtype=endianness + dt) + c = arr.copy() + c.sort() + msg = 'byte-swapped complex sort, dtype={0}'.format(dt) + assert_equal(c, arr, msg) + + @pytest.mark.parametrize('dtype', [np.bytes_, np.unicode_]) + def test_sort_string(self, dtype): + # np.array will perform the encoding to bytes for us in the bytes test + a = np.array(['aaaaaaaa' + chr(i) for i in range(101)], dtype=dtype) + b = a[::-1].copy() + for kind in self.sort_kinds: + msg = "kind=%s" % kind + c = a.copy() + c.sort(kind=kind) + assert_equal(c, a, msg) + c = b.copy() + c.sort(kind=kind) + assert_equal(c, a, msg) + + def test_sort_object(self): + # test object array sorts. + a = np.empty((101,), dtype=object) + a[:] = list(range(101)) + b = a[::-1] + for kind in ['q', 'h', 'm']: + msg = "kind=%s" % kind + c = a.copy() + c.sort(kind=kind) + assert_equal(c, a, msg) + c = b.copy() + c.sort(kind=kind) + assert_equal(c, a, msg) + + def test_sort_structured(self): + # test record array sorts. + dt = np.dtype([('f', float), ('i', int)]) + a = np.array([(i, i) for i in range(101)], dtype=dt) + b = a[::-1] + for kind in ['q', 'h', 'm']: + msg = "kind=%s" % kind + c = a.copy() + c.sort(kind=kind) + assert_equal(c, a, msg) + c = b.copy() + c.sort(kind=kind) + assert_equal(c, a, msg) + + @pytest.mark.parametrize('dtype', ['datetime64[D]', 'timedelta64[D]']) + def test_sort_time(self, dtype): + # test datetime64 and timedelta64 sorts. + a = np.arange(0, 101, dtype=dtype) + b = a[::-1] + for kind in ['q', 'h', 'm']: + msg = "kind=%s" % kind + c = a.copy() + c.sort(kind=kind) + assert_equal(c, a, msg) + c = b.copy() + c.sort(kind=kind) + assert_equal(c, a, msg) + + def test_sort_axis(self): + # check axis handling. This should be the same for all type + # specific sorts, so we only check it for one type and one kind + a = np.array([[3, 2], [1, 0]]) + b = np.array([[1, 0], [3, 2]]) + c = np.array([[2, 3], [0, 1]]) + d = a.copy() + d.sort(axis=0) + assert_equal(d, b, "test sort with axis=0") + d = a.copy() + d.sort(axis=1) + assert_equal(d, c, "test sort with axis=1") + d = a.copy() + d.sort() + assert_equal(d, c, "test sort with default axis") + + def test_sort_size_0(self): + # check axis handling for multidimensional empty arrays + a = np.array([]) + a.shape = (3, 2, 1, 0) + for axis in range(-a.ndim, a.ndim): + msg = 'test empty array sort with axis={0}'.format(axis) + assert_equal(np.sort(a, axis=axis), a, msg) + msg = 'test empty array sort with axis=None' + assert_equal(np.sort(a, axis=None), a.ravel(), msg) + + def test_sort_bad_ordering(self): + # test generic class with bogus ordering, + # should not segfault. + class Boom: + def __lt__(self, other): + return True + + a = np.array([Boom()] * 100, dtype=object) + for kind in self.sort_kinds: + msg = "kind=%s" % kind + c = a.copy() + c.sort(kind=kind) + assert_equal(c, a, msg) + + def test_void_sort(self): + # gh-8210 - previously segfaulted + for i in range(4): + rand = np.random.randint(256, size=4000, dtype=np.uint8) + arr = rand.view('V4') + arr[::-1].sort() + + dt = np.dtype([('val', 'i4', (1,))]) + for i in range(4): + rand = np.random.randint(256, size=4000, dtype=np.uint8) + arr = rand.view(dt) + arr[::-1].sort() + + def test_sort_raises(self): + #gh-9404 + arr = np.array([0, datetime.now(), 1], dtype=object) + for kind in self.sort_kinds: + assert_raises(TypeError, arr.sort, kind=kind) + #gh-3879 + class Raiser: + def raises_anything(*args, **kwargs): + raise TypeError("SOMETHING ERRORED") + __eq__ = __ne__ = __lt__ = __gt__ = __ge__ = __le__ = raises_anything + arr = np.array([[Raiser(), n] for n in range(10)]).reshape(-1) + np.random.shuffle(arr) + for kind in self.sort_kinds: + assert_raises(TypeError, arr.sort, kind=kind) + + def test_sort_degraded(self): + # test degraded dataset would take minutes to run with normal qsort + d = np.arange(1000000) + do = d.copy() + x = d + # create a median of 3 killer where each median is the sorted second + # last element of the quicksort partition + while x.size > 3: + mid = x.size // 2 + x[mid], x[-2] = x[-2], x[mid] + x = x[:-2] + + assert_equal(np.sort(d), do) + assert_equal(d[np.argsort(d)], do) + + def test_copy(self): + def assert_fortran(arr): + assert_(arr.flags.fortran) + assert_(arr.flags.f_contiguous) + assert_(not arr.flags.c_contiguous) + + def assert_c(arr): + assert_(not arr.flags.fortran) + assert_(not arr.flags.f_contiguous) + assert_(arr.flags.c_contiguous) + + a = np.empty((2, 2), order='F') + # Test copying a Fortran array + assert_c(a.copy()) + assert_c(a.copy('C')) + assert_fortran(a.copy('F')) + assert_fortran(a.copy('A')) + + # Now test starting with a C array. + a = np.empty((2, 2), order='C') + assert_c(a.copy()) + assert_c(a.copy('C')) + assert_fortran(a.copy('F')) + assert_c(a.copy('A')) + + def test_sort_order(self): + # Test sorting an array with fields + x1 = np.array([21, 32, 14]) + x2 = np.array(['my', 'first', 'name']) + x3 = np.array([3.1, 4.5, 6.2]) + r = np.rec.fromarrays([x1, x2, x3], names='id,word,number') + + r.sort(order=['id']) + assert_equal(r.id, np.array([14, 21, 32])) + assert_equal(r.word, np.array(['name', 'my', 'first'])) + assert_equal(r.number, np.array([6.2, 3.1, 4.5])) + + r.sort(order=['word']) + assert_equal(r.id, np.array([32, 21, 14])) + assert_equal(r.word, np.array(['first', 'my', 'name'])) + assert_equal(r.number, np.array([4.5, 3.1, 6.2])) + + r.sort(order=['number']) + assert_equal(r.id, np.array([21, 32, 14])) + assert_equal(r.word, np.array(['my', 'first', 'name'])) + assert_equal(r.number, np.array([3.1, 4.5, 6.2])) + + assert_raises_regex(ValueError, 'duplicate', + lambda: r.sort(order=['id', 'id'])) + + if sys.byteorder == 'little': + strtype = '>i2' + else: + strtype = '': + for dt in np.typecodes['Complex']: + arr = np.array([1+3.j, 2+2.j, 3+1.j], dtype=endianness + dt) + msg = 'byte-swapped complex argsort, dtype={0}'.format(dt) + assert_equal(arr.argsort(), + np.arange(len(arr), dtype=np.intp), msg) + + # test string argsorts. + s = 'aaaaaaaa' + a = np.array([s + chr(i) for i in range(101)]) + b = a[::-1].copy() + r = np.arange(101) + rr = r[::-1] + for kind in self.sort_kinds: + msg = "string argsort, kind=%s" % kind + assert_equal(a.copy().argsort(kind=kind), r, msg) + assert_equal(b.copy().argsort(kind=kind), rr, msg) + + # test unicode argsorts. + s = 'aaaaaaaa' + a = np.array([s + chr(i) for i in range(101)], dtype=np.unicode_) + b = a[::-1] + r = np.arange(101) + rr = r[::-1] + for kind in self.sort_kinds: + msg = "unicode argsort, kind=%s" % kind + assert_equal(a.copy().argsort(kind=kind), r, msg) + assert_equal(b.copy().argsort(kind=kind), rr, msg) + + # test object array argsorts. + a = np.empty((101,), dtype=object) + a[:] = list(range(101)) + b = a[::-1] + r = np.arange(101) + rr = r[::-1] + for kind in self.sort_kinds: + msg = "object argsort, kind=%s" % kind + assert_equal(a.copy().argsort(kind=kind), r, msg) + assert_equal(b.copy().argsort(kind=kind), rr, msg) + + # test structured array argsorts. + dt = np.dtype([('f', float), ('i', int)]) + a = np.array([(i, i) for i in range(101)], dtype=dt) + b = a[::-1] + r = np.arange(101) + rr = r[::-1] + for kind in self.sort_kinds: + msg = "structured array argsort, kind=%s" % kind + assert_equal(a.copy().argsort(kind=kind), r, msg) + assert_equal(b.copy().argsort(kind=kind), rr, msg) + + # test datetime64 argsorts. + a = np.arange(0, 101, dtype='datetime64[D]') + b = a[::-1] + r = np.arange(101) + rr = r[::-1] + for kind in ['q', 'h', 'm']: + msg = "datetime64 argsort, kind=%s" % kind + assert_equal(a.copy().argsort(kind=kind), r, msg) + assert_equal(b.copy().argsort(kind=kind), rr, msg) + + # test timedelta64 argsorts. + a = np.arange(0, 101, dtype='timedelta64[D]') + b = a[::-1] + r = np.arange(101) + rr = r[::-1] + for kind in ['q', 'h', 'm']: + msg = "timedelta64 argsort, kind=%s" % kind + assert_equal(a.copy().argsort(kind=kind), r, msg) + assert_equal(b.copy().argsort(kind=kind), rr, msg) + + # check axis handling. This should be the same for all type + # specific argsorts, so we only check it for one type and one kind + a = np.array([[3, 2], [1, 0]]) + b = np.array([[1, 1], [0, 0]]) + c = np.array([[1, 0], [1, 0]]) + assert_equal(a.copy().argsort(axis=0), b) + assert_equal(a.copy().argsort(axis=1), c) + assert_equal(a.copy().argsort(), c) + + # check axis handling for multidimensional empty arrays + a = np.array([]) + a.shape = (3, 2, 1, 0) + for axis in range(-a.ndim, a.ndim): + msg = 'test empty array argsort with axis={0}'.format(axis) + assert_equal(np.argsort(a, axis=axis), + np.zeros_like(a, dtype=np.intp), msg) + msg = 'test empty array argsort with axis=None' + assert_equal(np.argsort(a, axis=None), + np.zeros_like(a.ravel(), dtype=np.intp), msg) + + # check that stable argsorts are stable + r = np.arange(100) + # scalars + a = np.zeros(100) + assert_equal(a.argsort(kind='m'), r) + # complex + a = np.zeros(100, dtype=complex) + assert_equal(a.argsort(kind='m'), r) + # string + a = np.array(['aaaaaaaaa' for i in range(100)]) + assert_equal(a.argsort(kind='m'), r) + # unicode + a = np.array(['aaaaaaaaa' for i in range(100)], dtype=np.unicode_) + assert_equal(a.argsort(kind='m'), r) + + def test_sort_unicode_kind(self): + d = np.arange(10) + k = b'\xc3\xa4'.decode("UTF8") + assert_raises(ValueError, d.sort, kind=k) + assert_raises(ValueError, d.argsort, kind=k) + + def test_searchsorted(self): + # test for floats and complex containing nans. The logic is the + # same for all float types so only test double types for now. + # The search sorted routines use the compare functions for the + # array type, so this checks if that is consistent with the sort + # order. + + # check double + a = np.array([0, 1, np.nan]) + msg = "Test real searchsorted with nans, side='l'" + b = a.searchsorted(a, side='left') + assert_equal(b, np.arange(3), msg) + msg = "Test real searchsorted with nans, side='r'" + b = a.searchsorted(a, side='right') + assert_equal(b, np.arange(1, 4), msg) + # check keyword arguments + a.searchsorted(v=1) + # check double complex + a = np.zeros(9, dtype=np.complex128) + a.real += [0, 0, 1, 1, 0, 1, np.nan, np.nan, np.nan] + a.imag += [0, 1, 0, 1, np.nan, np.nan, 0, 1, np.nan] + msg = "Test complex searchsorted with nans, side='l'" + b = a.searchsorted(a, side='left') + assert_equal(b, np.arange(9), msg) + msg = "Test complex searchsorted with nans, side='r'" + b = a.searchsorted(a, side='right') + assert_equal(b, np.arange(1, 10), msg) + msg = "Test searchsorted with little endian, side='l'" + a = np.array([0, 128], dtype=' p[:, i]).all(), + msg="%d: %r < %r" % (i, p[:, i], p[:, i + 1:].T)) + aae(p, d1[np.arange(d1.shape[0])[:, None], + np.argpartition(d1, i, axis=1, kind=k)]) + + p = np.partition(d0, i, axis=0, kind=k) + aae(p[i, :], np.array([i] * d1.shape[0], dtype=dt)) + # array_less does not seem to work right + at((p[:i, :] <= p[i, :]).all(), + msg="%d: %r <= %r" % (i, p[i, :], p[:i, :])) + at((p[i + 1:, :] > p[i, :]).all(), + msg="%d: %r < %r" % (i, p[i, :], p[:, i + 1:])) + aae(p, d0[np.argpartition(d0, i, axis=0, kind=k), + np.arange(d0.shape[1])[None, :]]) + + # check inplace + dc = d.copy() + dc.partition(i, kind=k) + assert_equal(dc, np.partition(d, i, kind=k)) + dc = d0.copy() + dc.partition(i, axis=0, kind=k) + assert_equal(dc, np.partition(d0, i, axis=0, kind=k)) + dc = d1.copy() + dc.partition(i, axis=1, kind=k) + assert_equal(dc, np.partition(d1, i, axis=1, kind=k)) + + def assert_partitioned(self, d, kth): + prev = 0 + for k in np.sort(kth): + assert_array_less(d[prev:k], d[k], err_msg='kth %d' % k) + assert_((d[k:] >= d[k]).all(), + msg="kth %d, %r not greater equal %d" % (k, d[k:], d[k])) + prev = k + 1 + + def test_partition_iterative(self): + d = np.arange(17) + kth = (0, 1, 2, 429, 231) + assert_raises(ValueError, d.partition, kth) + assert_raises(ValueError, d.argpartition, kth) + d = np.arange(10).reshape((2, 5)) + assert_raises(ValueError, d.partition, kth, axis=0) + assert_raises(ValueError, d.partition, kth, axis=1) + assert_raises(ValueError, np.partition, d, kth, axis=1) + assert_raises(ValueError, np.partition, d, kth, axis=None) + + d = np.array([3, 4, 2, 1]) + p = np.partition(d, (0, 3)) + self.assert_partitioned(p, (0, 3)) + self.assert_partitioned(d[np.argpartition(d, (0, 3))], (0, 3)) + + assert_array_equal(p, np.partition(d, (-3, -1))) + assert_array_equal(p, d[np.argpartition(d, (-3, -1))]) + + d = np.arange(17) + np.random.shuffle(d) + d.partition(range(d.size)) + assert_array_equal(np.arange(17), d) + np.random.shuffle(d) + assert_array_equal(np.arange(17), d[d.argpartition(range(d.size))]) + + # test unsorted kth + d = np.arange(17) + np.random.shuffle(d) + keys = np.array([1, 3, 8, -2]) + np.random.shuffle(d) + p = np.partition(d, keys) + self.assert_partitioned(p, keys) + p = d[np.argpartition(d, keys)] + self.assert_partitioned(p, keys) + np.random.shuffle(keys) + assert_array_equal(np.partition(d, keys), p) + assert_array_equal(d[np.argpartition(d, keys)], p) + + # equal kth + d = np.arange(20)[::-1] + self.assert_partitioned(np.partition(d, [5]*4), [5]) + self.assert_partitioned(np.partition(d, [5]*4 + [6, 13]), + [5]*4 + [6, 13]) + self.assert_partitioned(d[np.argpartition(d, [5]*4)], [5]) + self.assert_partitioned(d[np.argpartition(d, [5]*4 + [6, 13])], + [5]*4 + [6, 13]) + + d = np.arange(12) + np.random.shuffle(d) + d1 = np.tile(np.arange(12), (4, 1)) + map(np.random.shuffle, d1) + d0 = np.transpose(d1) + + kth = (1, 6, 7, -1) + p = np.partition(d1, kth, axis=1) + pa = d1[np.arange(d1.shape[0])[:, None], + d1.argpartition(kth, axis=1)] + assert_array_equal(p, pa) + for i in range(d1.shape[0]): + self.assert_partitioned(p[i,:], kth) + p = np.partition(d0, kth, axis=0) + pa = d0[np.argpartition(d0, kth, axis=0), + np.arange(d0.shape[1])[None,:]] + assert_array_equal(p, pa) + for i in range(d0.shape[1]): + self.assert_partitioned(p[:, i], kth) + + def test_partition_cdtype(self): + d = np.array([('Galahad', 1.7, 38), ('Arthur', 1.8, 41), + ('Lancelot', 1.9, 38)], + dtype=[('name', '|S10'), ('height', ' (numpy ufunc, has_in_place_version, preferred_dtype) + ops = { + 'add': (np.add, True, float), + 'sub': (np.subtract, True, float), + 'mul': (np.multiply, True, float), + 'truediv': (np.true_divide, True, float), + 'floordiv': (np.floor_divide, True, float), + 'mod': (np.remainder, True, float), + 'divmod': (np.divmod, False, float), + 'pow': (np.power, True, int), + 'lshift': (np.left_shift, True, int), + 'rshift': (np.right_shift, True, int), + 'and': (np.bitwise_and, True, int), + 'xor': (np.bitwise_xor, True, int), + 'or': (np.bitwise_or, True, int), + 'matmul': (np.matmul, False, float), + # 'ge': (np.less_equal, False), + # 'gt': (np.less, False), + # 'le': (np.greater_equal, False), + # 'lt': (np.greater, False), + # 'eq': (np.equal, False), + # 'ne': (np.not_equal, False), + } + + class Coerced(Exception): + pass + + def array_impl(self): + raise Coerced + + def op_impl(self, other): + return "forward" + + def rop_impl(self, other): + return "reverse" + + def iop_impl(self, other): + return "in-place" + + def array_ufunc_impl(self, ufunc, method, *args, **kwargs): + return ("__array_ufunc__", ufunc, method, args, kwargs) + + # Create an object with the given base, in the given module, with a + # bunch of placeholder __op__ methods, and optionally a + # __array_ufunc__ and __array_priority__. + def make_obj(base, array_priority=False, array_ufunc=False, + alleged_module="__main__"): + class_namespace = {"__array__": array_impl} + if array_priority is not False: + class_namespace["__array_priority__"] = array_priority + for op in ops: + class_namespace["__{0}__".format(op)] = op_impl + class_namespace["__r{0}__".format(op)] = rop_impl + class_namespace["__i{0}__".format(op)] = iop_impl + if array_ufunc is not False: + class_namespace["__array_ufunc__"] = array_ufunc + eval_namespace = {"base": base, + "class_namespace": class_namespace, + "__name__": alleged_module, + } + MyType = eval("type('MyType', (base,), class_namespace)", + eval_namespace) + if issubclass(MyType, np.ndarray): + # Use this range to avoid special case weirdnesses around + # divide-by-0, pow(x, 2), overflow due to pow(big, big), etc. + return np.arange(3, 7).reshape(2, 2).view(MyType) + else: + return MyType() + + def check(obj, binop_override_expected, ufunc_override_expected, + inplace_override_expected, check_scalar=True): + for op, (ufunc, has_inplace, dtype) in ops.items(): + err_msg = ('op: %s, ufunc: %s, has_inplace: %s, dtype: %s' + % (op, ufunc, has_inplace, dtype)) + check_objs = [np.arange(3, 7, dtype=dtype).reshape(2, 2)] + if check_scalar: + check_objs.append(check_objs[0][0]) + for arr in check_objs: + arr_method = getattr(arr, "__{0}__".format(op)) + + def first_out_arg(result): + if op == "divmod": + assert_(isinstance(result, tuple)) + return result[0] + else: + return result + + # arr __op__ obj + if binop_override_expected: + assert_equal(arr_method(obj), NotImplemented, err_msg) + elif ufunc_override_expected: + assert_equal(arr_method(obj)[0], "__array_ufunc__", + err_msg) + else: + if (isinstance(obj, np.ndarray) and + (type(obj).__array_ufunc__ is + np.ndarray.__array_ufunc__)): + # __array__ gets ignored + res = first_out_arg(arr_method(obj)) + assert_(res.__class__ is obj.__class__, err_msg) + else: + assert_raises((TypeError, Coerced), + arr_method, obj, err_msg=err_msg) + # obj __op__ arr + arr_rmethod = getattr(arr, "__r{0}__".format(op)) + if ufunc_override_expected: + res = arr_rmethod(obj) + assert_equal(res[0], "__array_ufunc__", + err_msg=err_msg) + assert_equal(res[1], ufunc, err_msg=err_msg) + else: + if (isinstance(obj, np.ndarray) and + (type(obj).__array_ufunc__ is + np.ndarray.__array_ufunc__)): + # __array__ gets ignored + res = first_out_arg(arr_rmethod(obj)) + assert_(res.__class__ is obj.__class__, err_msg) + else: + # __array_ufunc__ = "asdf" creates a TypeError + assert_raises((TypeError, Coerced), + arr_rmethod, obj, err_msg=err_msg) + + # arr __iop__ obj + # array scalars don't have in-place operators + if has_inplace and isinstance(arr, np.ndarray): + arr_imethod = getattr(arr, "__i{0}__".format(op)) + if inplace_override_expected: + assert_equal(arr_method(obj), NotImplemented, + err_msg=err_msg) + elif ufunc_override_expected: + res = arr_imethod(obj) + assert_equal(res[0], "__array_ufunc__", err_msg) + assert_equal(res[1], ufunc, err_msg) + assert_(type(res[-1]["out"]) is tuple, err_msg) + assert_(res[-1]["out"][0] is arr, err_msg) + else: + if (isinstance(obj, np.ndarray) and + (type(obj).__array_ufunc__ is + np.ndarray.__array_ufunc__)): + # __array__ gets ignored + assert_(arr_imethod(obj) is arr, err_msg) + else: + assert_raises((TypeError, Coerced), + arr_imethod, obj, + err_msg=err_msg) + + op_fn = getattr(operator, op, None) + if op_fn is None: + op_fn = getattr(operator, op + "_", None) + if op_fn is None: + op_fn = getattr(builtins, op) + assert_equal(op_fn(obj, arr), "forward", err_msg) + if not isinstance(obj, np.ndarray): + if binop_override_expected: + assert_equal(op_fn(arr, obj), "reverse", err_msg) + elif ufunc_override_expected: + assert_equal(op_fn(arr, obj)[0], "__array_ufunc__", + err_msg) + if ufunc_override_expected: + assert_equal(ufunc(obj, arr)[0], "__array_ufunc__", + err_msg) + + # No array priority, no array_ufunc -> nothing called + check(make_obj(object), False, False, False) + # Negative array priority, no array_ufunc -> nothing called + # (has to be very negative, because scalar priority is -1000000.0) + check(make_obj(object, array_priority=-2**30), False, False, False) + # Positive array priority, no array_ufunc -> binops and iops only + check(make_obj(object, array_priority=1), True, False, True) + # ndarray ignores array_priority for ndarray subclasses + check(make_obj(np.ndarray, array_priority=1), False, False, False, + check_scalar=False) + # Positive array_priority and array_ufunc -> array_ufunc only + check(make_obj(object, array_priority=1, + array_ufunc=array_ufunc_impl), False, True, False) + check(make_obj(np.ndarray, array_priority=1, + array_ufunc=array_ufunc_impl), False, True, False) + # array_ufunc set to None -> defer binops only + check(make_obj(object, array_ufunc=None), True, False, False) + check(make_obj(np.ndarray, array_ufunc=None), True, False, False, + check_scalar=False) + + def test_ufunc_override_normalize_signature(self): + # gh-5674 + class SomeClass: + def __array_ufunc__(self, ufunc, method, *inputs, **kw): + return kw + + a = SomeClass() + kw = np.add(a, [1]) + assert_('sig' not in kw and 'signature' not in kw) + kw = np.add(a, [1], sig='ii->i') + assert_('sig' not in kw and 'signature' in kw) + assert_equal(kw['signature'], 'ii->i') + kw = np.add(a, [1], signature='ii->i') + assert_('sig' not in kw and 'signature' in kw) + assert_equal(kw['signature'], 'ii->i') + + def test_array_ufunc_index(self): + # Check that index is set appropriately, also if only an output + # is passed on (latter is another regression tests for github bug 4753) + # This also checks implicitly that 'out' is always a tuple. + class CheckIndex: + def __array_ufunc__(self, ufunc, method, *inputs, **kw): + for i, a in enumerate(inputs): + if a is self: + return i + # calls below mean we must be in an output. + for j, a in enumerate(kw['out']): + if a is self: + return (j,) + + a = CheckIndex() + dummy = np.arange(2.) + # 1 input, 1 output + assert_equal(np.sin(a), 0) + assert_equal(np.sin(dummy, a), (0,)) + assert_equal(np.sin(dummy, out=a), (0,)) + assert_equal(np.sin(dummy, out=(a,)), (0,)) + assert_equal(np.sin(a, a), 0) + assert_equal(np.sin(a, out=a), 0) + assert_equal(np.sin(a, out=(a,)), 0) + # 1 input, 2 outputs + assert_equal(np.modf(dummy, a), (0,)) + assert_equal(np.modf(dummy, None, a), (1,)) + assert_equal(np.modf(dummy, dummy, a), (1,)) + assert_equal(np.modf(dummy, out=(a, None)), (0,)) + assert_equal(np.modf(dummy, out=(a, dummy)), (0,)) + assert_equal(np.modf(dummy, out=(None, a)), (1,)) + assert_equal(np.modf(dummy, out=(dummy, a)), (1,)) + assert_equal(np.modf(a, out=(dummy, a)), 0) + with assert_raises(TypeError): + # Out argument must be tuple, since there are multiple outputs + np.modf(dummy, out=a) + + assert_raises(ValueError, np.modf, dummy, out=(a,)) + + # 2 inputs, 1 output + assert_equal(np.add(a, dummy), 0) + assert_equal(np.add(dummy, a), 1) + assert_equal(np.add(dummy, dummy, a), (0,)) + assert_equal(np.add(dummy, a, a), 1) + assert_equal(np.add(dummy, dummy, out=a), (0,)) + assert_equal(np.add(dummy, dummy, out=(a,)), (0,)) + assert_equal(np.add(a, dummy, out=a), 0) + + def test_out_override(self): + # regression test for github bug 4753 + class OutClass(np.ndarray): + def __array_ufunc__(self, ufunc, method, *inputs, **kw): + if 'out' in kw: + tmp_kw = kw.copy() + tmp_kw.pop('out') + func = getattr(ufunc, method) + kw['out'][0][...] = func(*inputs, **tmp_kw) + + A = np.array([0]).view(OutClass) + B = np.array([5]) + C = np.array([6]) + np.multiply(C, B, A) + assert_equal(A[0], 30) + assert_(isinstance(A, OutClass)) + A[0] = 0 + np.multiply(C, B, out=A) + assert_equal(A[0], 30) + assert_(isinstance(A, OutClass)) + + def test_pow_override_with_errors(self): + # regression test for gh-9112 + class PowerOnly(np.ndarray): + def __array_ufunc__(self, ufunc, method, *inputs, **kw): + if ufunc is not np.power: + raise NotImplementedError + return "POWER!" + # explicit cast to float, to ensure the fast power path is taken. + a = np.array(5., dtype=np.float64).view(PowerOnly) + assert_equal(a ** 2.5, "POWER!") + with assert_raises(NotImplementedError): + a ** 0.5 + with assert_raises(NotImplementedError): + a ** 0 + with assert_raises(NotImplementedError): + a ** 1 + with assert_raises(NotImplementedError): + a ** -1 + with assert_raises(NotImplementedError): + a ** 2 + + def test_pow_array_object_dtype(self): + # test pow on arrays of object dtype + class SomeClass: + def __init__(self, num=None): + self.num = num + + # want to ensure a fast pow path is not taken + def __mul__(self, other): + raise AssertionError('__mul__ should not be called') + + def __div__(self, other): + raise AssertionError('__div__ should not be called') + + def __pow__(self, exp): + return SomeClass(num=self.num ** exp) + + def __eq__(self, other): + if isinstance(other, SomeClass): + return self.num == other.num + + __rpow__ = __pow__ + + def pow_for(exp, arr): + return np.array([x ** exp for x in arr]) + + obj_arr = np.array([SomeClass(1), SomeClass(2), SomeClass(3)]) + + assert_equal(obj_arr ** 0.5, pow_for(0.5, obj_arr)) + assert_equal(obj_arr ** 0, pow_for(0, obj_arr)) + assert_equal(obj_arr ** 1, pow_for(1, obj_arr)) + assert_equal(obj_arr ** -1, pow_for(-1, obj_arr)) + assert_equal(obj_arr ** 2, pow_for(2, obj_arr)) + + def test_pos_array_ufunc_override(self): + class A(np.ndarray): + def __array_ufunc__(self, ufunc, method, *inputs, **kwargs): + return getattr(ufunc, method)(*[i.view(np.ndarray) for + i in inputs], **kwargs) + tst = np.array('foo').view(A) + with assert_raises(TypeError): + +tst + + +class TestTemporaryElide: + # elision is only triggered on relatively large arrays + + def test_extension_incref_elide(self): + # test extension (e.g. cython) calling PyNumber_* slots without + # increasing the reference counts + # + # def incref_elide(a): + # d = input.copy() # refcount 1 + # return d, d + d # PyNumber_Add without increasing refcount + from numpy.core._multiarray_tests import incref_elide + d = np.ones(100000) + orig, res = incref_elide(d) + d + d + # the return original should not be changed to an inplace operation + assert_array_equal(orig, d) + assert_array_equal(res, d + d) + + def test_extension_incref_elide_stack(self): + # scanning if the refcount == 1 object is on the python stack to check + # that we are called directly from python is flawed as object may still + # be above the stack pointer and we have no access to the top of it + # + # def incref_elide_l(d): + # return l[4] + l[4] # PyNumber_Add without increasing refcount + from numpy.core._multiarray_tests import incref_elide_l + # padding with 1 makes sure the object on the stack is not overwritten + l = [1, 1, 1, 1, np.ones(100000)] + res = incref_elide_l(l) + # the return original should not be changed to an inplace operation + assert_array_equal(l[4], np.ones(100000)) + assert_array_equal(res, l[4] + l[4]) + + def test_temporary_with_cast(self): + # check that we don't elide into a temporary which would need casting + d = np.ones(200000, dtype=np.int64) + assert_equal(((d + d) + 2**222).dtype, np.dtype('O')) + + r = ((d + d) / 2) + assert_equal(r.dtype, np.dtype('f8')) + + r = np.true_divide((d + d), 2) + assert_equal(r.dtype, np.dtype('f8')) + + r = ((d + d) / 2.) + assert_equal(r.dtype, np.dtype('f8')) + + r = ((d + d) // 2) + assert_equal(r.dtype, np.dtype(np.int64)) + + # commutative elision into the astype result + f = np.ones(100000, dtype=np.float32) + assert_equal(((f + f) + f.astype(np.float64)).dtype, np.dtype('f8')) + + # no elision into lower type + d = f.astype(np.float64) + assert_equal(((f + f) + d).dtype, d.dtype) + l = np.ones(100000, dtype=np.longdouble) + assert_equal(((d + d) + l).dtype, l.dtype) + + # test unary abs with different output dtype + for dt in (np.complex64, np.complex128, np.clongdouble): + c = np.ones(100000, dtype=dt) + r = abs(c * 2.0) + assert_equal(r.dtype, np.dtype('f%d' % (c.itemsize // 2))) + + def test_elide_broadcast(self): + # test no elision on broadcast to higher dimension + # only triggers elision code path in debug mode as triggering it in + # normal mode needs 256kb large matching dimension, so a lot of memory + d = np.ones((2000, 1), dtype=int) + b = np.ones((2000), dtype=bool) + r = (1 - d) + b + assert_equal(r, 1) + assert_equal(r.shape, (2000, 2000)) + + def test_elide_scalar(self): + # check inplace op does not create ndarray from scalars + a = np.bool_() + assert_(type(~(a & a)) is np.bool_) + + def test_elide_scalar_readonly(self): + # The imaginary part of a real array is readonly. This needs to go + # through fast_scalar_power which is only called for powers of + # +1, -1, 0, 0.5, and 2, so use 2. Also need valid refcount for + # elision which can be gotten for the imaginary part of a real + # array. Should not error. + a = np.empty(100000, dtype=np.float64) + a.imag ** 2 + + def test_elide_readonly(self): + # don't try to elide readonly temporaries + r = np.asarray(np.broadcast_to(np.zeros(1), 100000).flat) * 0.0 + assert_equal(r, 0) + + def test_elide_updateifcopy(self): + a = np.ones(2**20)[::2] + b = a.flat.__array__() + 1 + del b + assert_equal(a, 1) + + +class TestCAPI: + def test_IsPythonScalar(self): + from numpy.core._multiarray_tests import IsPythonScalar + assert_(IsPythonScalar(b'foobar')) + assert_(IsPythonScalar(1)) + assert_(IsPythonScalar(2**80)) + assert_(IsPythonScalar(2.)) + assert_(IsPythonScalar("a")) + + +class TestSubscripting: + def test_test_zero_rank(self): + x = np.array([1, 2, 3]) + assert_(isinstance(x[0], np.int_)) + assert_(type(x[0, ...]) is np.ndarray) + + +class TestPickling: + @pytest.mark.skipif(pickle.HIGHEST_PROTOCOL >= 5, + reason=('this tests the error messages when trying to' + 'protocol 5 although it is not available')) + def test_correct_protocol5_error_message(self): + array = np.arange(10) + + if sys.version_info[:2] in ((3, 6), (3, 7)): + # For the specific case of python3.6 and 3.7, raise a clear import + # error about the pickle5 backport when trying to use protocol=5 + # without the pickle5 package + with pytest.raises(ImportError): + array.__reduce_ex__(5) + + def test_record_array_with_object_dtype(self): + my_object = object() + + arr_with_object = np.array( + [(my_object, 1, 2.0)], + dtype=[('a', object), ('b', int), ('c', float)]) + arr_without_object = np.array( + [('xxx', 1, 2.0)], + dtype=[('a', str), ('b', int), ('c', float)]) + + for proto in range(2, pickle.HIGHEST_PROTOCOL + 1): + depickled_arr_with_object = pickle.loads( + pickle.dumps(arr_with_object, protocol=proto)) + depickled_arr_without_object = pickle.loads( + pickle.dumps(arr_without_object, protocol=proto)) + + assert_equal(arr_with_object.dtype, + depickled_arr_with_object.dtype) + assert_equal(arr_without_object.dtype, + depickled_arr_without_object.dtype) + + @pytest.mark.skipif(pickle.HIGHEST_PROTOCOL < 5, + reason="requires pickle protocol 5") + def test_f_contiguous_array(self): + f_contiguous_array = np.array([[1, 2, 3], [4, 5, 6]], order='F') + buffers = [] + + # When using pickle protocol 5, Fortran-contiguous arrays can be + # serialized using out-of-band buffers + bytes_string = pickle.dumps(f_contiguous_array, protocol=5, + buffer_callback=buffers.append) + + assert len(buffers) > 0 + + depickled_f_contiguous_array = pickle.loads(bytes_string, + buffers=buffers) + + assert_equal(f_contiguous_array, depickled_f_contiguous_array) + + def test_non_contiguous_array(self): + non_contiguous_array = np.arange(12).reshape(3, 4)[:, :2] + assert not non_contiguous_array.flags.c_contiguous + assert not non_contiguous_array.flags.f_contiguous + + # make sure non-contiguous arrays can be pickled-depickled + # using any protocol + for proto in range(2, pickle.HIGHEST_PROTOCOL + 1): + depickled_non_contiguous_array = pickle.loads( + pickle.dumps(non_contiguous_array, protocol=proto)) + + assert_equal(non_contiguous_array, depickled_non_contiguous_array) + + def test_roundtrip(self): + for proto in range(2, pickle.HIGHEST_PROTOCOL + 1): + carray = np.array([[2, 9], [7, 0], [3, 8]]) + DATA = [ + carray, + np.transpose(carray), + np.array([('xxx', 1, 2.0)], dtype=[('a', (str, 3)), ('b', int), + ('c', float)]) + ] + + refs = [weakref.ref(a) for a in DATA] + for a in DATA: + assert_equal( + a, pickle.loads(pickle.dumps(a, protocol=proto)), + err_msg="%r" % a) + del a, DATA, carray + break_cycles() + # check for reference leaks (gh-12793) + for ref in refs: + assert ref() is None + + def _loads(self, obj): + return pickle.loads(obj, encoding='latin1') + + # version 0 pickles, using protocol=2 to pickle + # version 0 doesn't have a version field + def test_version0_int8(self): + s = b'\x80\x02cnumpy.core._internal\n_reconstruct\nq\x01cnumpy\nndarray\nq\x02K\x00\x85U\x01b\x87Rq\x03(K\x04\x85cnumpy\ndtype\nq\x04U\x02i1K\x00K\x01\x87Rq\x05(U\x01|NNJ\xff\xff\xff\xffJ\xff\xff\xff\xfftb\x89U\x04\x01\x02\x03\x04tb.' + a = np.array([1, 2, 3, 4], dtype=np.int8) + p = self._loads(s) + assert_equal(a, p) + + def test_version0_float32(self): + s = b'\x80\x02cnumpy.core._internal\n_reconstruct\nq\x01cnumpy\nndarray\nq\x02K\x00\x85U\x01b\x87Rq\x03(K\x04\x85cnumpy\ndtype\nq\x04U\x02f4K\x00K\x01\x87Rq\x05(U\x01= g2, [g1[i] >= g2[i] for i in [0, 1, 2]]) + assert_array_equal(g1 < g2, [g1[i] < g2[i] for i in [0, 1, 2]]) + assert_array_equal(g1 > g2, [g1[i] > g2[i] for i in [0, 1, 2]]) + + def test_mixed(self): + g1 = np.array(["spam", "spa", "spammer", "and eggs"]) + g2 = "spam" + assert_array_equal(g1 == g2, [x == g2 for x in g1]) + assert_array_equal(g1 != g2, [x != g2 for x in g1]) + assert_array_equal(g1 < g2, [x < g2 for x in g1]) + assert_array_equal(g1 > g2, [x > g2 for x in g1]) + assert_array_equal(g1 <= g2, [x <= g2 for x in g1]) + assert_array_equal(g1 >= g2, [x >= g2 for x in g1]) + + def test_unicode(self): + g1 = np.array([u"This", u"is", u"example"]) + g2 = np.array([u"This", u"was", u"example"]) + assert_array_equal(g1 == g2, [g1[i] == g2[i] for i in [0, 1, 2]]) + assert_array_equal(g1 != g2, [g1[i] != g2[i] for i in [0, 1, 2]]) + assert_array_equal(g1 <= g2, [g1[i] <= g2[i] for i in [0, 1, 2]]) + assert_array_equal(g1 >= g2, [g1[i] >= g2[i] for i in [0, 1, 2]]) + assert_array_equal(g1 < g2, [g1[i] < g2[i] for i in [0, 1, 2]]) + assert_array_equal(g1 > g2, [g1[i] > g2[i] for i in [0, 1, 2]]) + + +class TestArgmax: + + nan_arr = [ + ([0, 1, 2, 3, np.nan], 4), + ([0, 1, 2, np.nan, 3], 3), + ([np.nan, 0, 1, 2, 3], 0), + ([np.nan, 0, np.nan, 2, 3], 0), + ([0, 1, 2, 3, complex(0, np.nan)], 4), + ([0, 1, 2, 3, complex(np.nan, 0)], 4), + ([0, 1, 2, complex(np.nan, 0), 3], 3), + ([0, 1, 2, complex(0, np.nan), 3], 3), + ([complex(0, np.nan), 0, 1, 2, 3], 0), + ([complex(np.nan, np.nan), 0, 1, 2, 3], 0), + ([complex(np.nan, 0), complex(np.nan, 2), complex(np.nan, 1)], 0), + ([complex(np.nan, np.nan), complex(np.nan, 2), complex(np.nan, 1)], 0), + ([complex(np.nan, 0), complex(np.nan, 2), complex(np.nan, np.nan)], 0), + + ([complex(0, 0), complex(0, 2), complex(0, 1)], 1), + ([complex(1, 0), complex(0, 2), complex(0, 1)], 0), + ([complex(1, 0), complex(0, 2), complex(1, 1)], 2), + + ([np.datetime64('1923-04-14T12:43:12'), + np.datetime64('1994-06-21T14:43:15'), + np.datetime64('2001-10-15T04:10:32'), + np.datetime64('1995-11-25T16:02:16'), + np.datetime64('2005-01-04T03:14:12'), + np.datetime64('2041-12-03T14:05:03')], 5), + ([np.datetime64('1935-09-14T04:40:11'), + np.datetime64('1949-10-12T12:32:11'), + np.datetime64('2010-01-03T05:14:12'), + np.datetime64('2015-11-20T12:20:59'), + np.datetime64('1932-09-23T10:10:13'), + np.datetime64('2014-10-10T03:50:30')], 3), + # Assorted tests with NaTs + ([np.datetime64('NaT'), + np.datetime64('NaT'), + np.datetime64('2010-01-03T05:14:12'), + np.datetime64('NaT'), + np.datetime64('2015-09-23T10:10:13'), + np.datetime64('1932-10-10T03:50:30')], 0), + ([np.datetime64('2059-03-14T12:43:12'), + np.datetime64('1996-09-21T14:43:15'), + np.datetime64('NaT'), + np.datetime64('2022-12-25T16:02:16'), + np.datetime64('1963-10-04T03:14:12'), + np.datetime64('2013-05-08T18:15:23')], 2), + ([np.timedelta64(2, 's'), + np.timedelta64(1, 's'), + np.timedelta64('NaT', 's'), + np.timedelta64(3, 's')], 2), + ([np.timedelta64('NaT', 's')] * 3, 0), + + ([timedelta(days=5, seconds=14), timedelta(days=2, seconds=35), + timedelta(days=-1, seconds=23)], 0), + ([timedelta(days=1, seconds=43), timedelta(days=10, seconds=5), + timedelta(days=5, seconds=14)], 1), + ([timedelta(days=10, seconds=24), timedelta(days=10, seconds=5), + timedelta(days=10, seconds=43)], 2), + + ([False, False, False, False, True], 4), + ([False, False, False, True, False], 3), + ([True, False, False, False, False], 0), + ([True, False, True, False, False], 0), + ] + + def test_all(self): + a = np.random.normal(0, 1, (4, 5, 6, 7, 8)) + for i in range(a.ndim): + amax = a.max(i) + aargmax = a.argmax(i) + axes = list(range(a.ndim)) + axes.remove(i) + assert_(np.all(amax == aargmax.choose(*a.transpose(i,*axes)))) + + def test_combinations(self): + for arr, pos in self.nan_arr: + with suppress_warnings() as sup: + sup.filter(RuntimeWarning, + "invalid value encountered in reduce") + max_val = np.max(arr) + + assert_equal(np.argmax(arr), pos, err_msg="%r" % arr) + assert_equal(arr[np.argmax(arr)], max_val, err_msg="%r" % arr) + + def test_output_shape(self): + # see also gh-616 + a = np.ones((10, 5)) + # Check some simple shape mismatches + out = np.ones(11, dtype=np.int_) + assert_raises(ValueError, a.argmax, -1, out) + + out = np.ones((2, 5), dtype=np.int_) + assert_raises(ValueError, a.argmax, -1, out) + + # these could be relaxed possibly (used to allow even the previous) + out = np.ones((1, 10), dtype=np.int_) + assert_raises(ValueError, a.argmax, -1, out) + + out = np.ones(10, dtype=np.int_) + a.argmax(-1, out=out) + assert_equal(out, a.argmax(-1)) + + @pytest.mark.parametrize('ndim', [0, 1]) + def test_ret_is_out(self, ndim): + a = np.ones((4,) + (3,)*ndim) + out = np.empty((3,)*ndim, dtype=np.intp) + ret = a.argmax(axis=0, out=out) + assert ret is out + + def test_argmax_unicode(self): + d = np.zeros(6031, dtype='= cmin)) + assert_(np.all(x <= cmax)) + + def _clip_type(self, type_group, array_max, + clip_min, clip_max, inplace=False, + expected_min=None, expected_max=None): + if expected_min is None: + expected_min = clip_min + if expected_max is None: + expected_max = clip_max + + for T in np.sctypes[type_group]: + if sys.byteorder == 'little': + byte_orders = ['=', '>'] + else: + byte_orders = ['<', '='] + + for byteorder in byte_orders: + dtype = np.dtype(T).newbyteorder(byteorder) + + x = (np.random.random(1000) * array_max).astype(dtype) + if inplace: + # The tests that call us pass clip_min and clip_max that + # might not fit in the destination dtype. They were written + # assuming the previous unsafe casting, which now must be + # passed explicitly to avoid a warning. + x.clip(clip_min, clip_max, x, casting='unsafe') + else: + x = x.clip(clip_min, clip_max) + byteorder = '=' + + if x.dtype.byteorder == '|': + byteorder = '|' + assert_equal(x.dtype.byteorder, byteorder) + self._check_range(x, expected_min, expected_max) + return x + + def test_basic(self): + for inplace in [False, True]: + self._clip_type( + 'float', 1024, -12.8, 100.2, inplace=inplace) + self._clip_type( + 'float', 1024, 0, 0, inplace=inplace) + + self._clip_type( + 'int', 1024, -120, 100, inplace=inplace) + self._clip_type( + 'int', 1024, 0, 0, inplace=inplace) + + self._clip_type( + 'uint', 1024, 0, 0, inplace=inplace) + self._clip_type( + 'uint', 1024, -120, 100, inplace=inplace, expected_min=0) + + def test_record_array(self): + rec = np.array([(-5, 2.0, 3.0), (5.0, 4.0, 3.0)], + dtype=[('x', '= 3)) + x = val.clip(min=3) + assert_(np.all(x >= 3)) + x = val.clip(max=4) + assert_(np.all(x <= 4)) + + def test_nan(self): + input_arr = np.array([-2., np.nan, 0.5, 3., 0.25, np.nan]) + result = input_arr.clip(-1, 1) + expected = np.array([-1., np.nan, 0.5, 1., 0.25, np.nan]) + assert_array_equal(result, expected) + + +class TestCompress: + def test_axis(self): + tgt = [[5, 6, 7, 8, 9]] + arr = np.arange(10).reshape(2, 5) + out = np.compress([0, 1], arr, axis=0) + assert_equal(out, tgt) + + tgt = [[1, 3], [6, 8]] + out = np.compress([0, 1, 0, 1, 0], arr, axis=1) + assert_equal(out, tgt) + + def test_truncate(self): + tgt = [[1], [6]] + arr = np.arange(10).reshape(2, 5) + out = np.compress([0, 1], arr, axis=1) + assert_equal(out, tgt) + + def test_flatten(self): + arr = np.arange(10).reshape(2, 5) + out = np.compress([0, 1], arr) + assert_equal(out, 1) + + +class TestPutmask: + def tst_basic(self, x, T, mask, val): + np.putmask(x, mask, val) + assert_equal(x[mask], np.array(val, T)) + + def test_ip_types(self): + unchecked_types = [bytes, str, np.void] + + x = np.random.random(1000)*100 + mask = x < 40 + + for val in [-100, 0, 15]: + for types in np.sctypes.values(): + for T in types: + if T not in unchecked_types: + self.tst_basic(x.copy().astype(T), T, mask, val) + + # Also test string of a length which uses an untypical length + dt = np.dtype("S3") + self.tst_basic(x.astype(dt), dt.type, mask, dt.type(val)[:3]) + + def test_mask_size(self): + assert_raises(ValueError, np.putmask, np.array([1, 2, 3]), [True], 5) + + @pytest.mark.parametrize('dtype', ('>i4', 'f8'), ('z', 'i4', 'f8'), ('z', ' 16MB + d = np.zeros(4 * 1024 ** 2) + d.tofile(self.filename) + assert_equal(os.path.getsize(self.filename), d.nbytes) + assert_array_equal(d, np.fromfile(self.filename)) + # check offset + with open(self.filename, "r+b") as f: + f.seek(d.nbytes) + d.tofile(f) + assert_equal(os.path.getsize(self.filename), d.nbytes * 2) + # check append mode (gh-8329) + open(self.filename, "w").close() # delete file contents + with open(self.filename, "ab") as f: + d.tofile(f) + assert_array_equal(d, np.fromfile(self.filename)) + with open(self.filename, "ab") as f: + d.tofile(f) + assert_equal(os.path.getsize(self.filename), d.nbytes * 2) + + def test_io_open_buffered_fromfile(self): + # gh-6632 + self.x.tofile(self.filename) + with io.open(self.filename, 'rb', buffering=-1) as f: + y = np.fromfile(f, dtype=self.dtype) + assert_array_equal(y, self.x.flat) + + def test_file_position_after_fromfile(self): + # gh-4118 + sizes = [io.DEFAULT_BUFFER_SIZE//8, + io.DEFAULT_BUFFER_SIZE, + io.DEFAULT_BUFFER_SIZE*8] + + for size in sizes: + with open(self.filename, 'wb') as f: + f.seek(size-1) + f.write(b'\0') + + for mode in ['rb', 'r+b']: + err_msg = "%d %s" % (size, mode) + + with open(self.filename, mode) as f: + f.read(2) + np.fromfile(f, dtype=np.float64, count=1) + pos = f.tell() + assert_equal(pos, 10, err_msg=err_msg) + + def test_file_position_after_tofile(self): + # gh-4118 + sizes = [io.DEFAULT_BUFFER_SIZE//8, + io.DEFAULT_BUFFER_SIZE, + io.DEFAULT_BUFFER_SIZE*8] + + for size in sizes: + err_msg = "%d" % (size,) + + with open(self.filename, 'wb') as f: + f.seek(size-1) + f.write(b'\0') + f.seek(10) + f.write(b'12') + np.array([0], dtype=np.float64).tofile(f) + pos = f.tell() + assert_equal(pos, 10 + 2 + 8, err_msg=err_msg) + + with open(self.filename, 'r+b') as f: + f.read(2) + f.seek(0, 1) # seek between read&write required by ANSI C + np.array([0], dtype=np.float64).tofile(f) + pos = f.tell() + assert_equal(pos, 10, err_msg=err_msg) + + def test_load_object_array_fromfile(self): + # gh-12300 + with open(self.filename, 'w') as f: + # Ensure we have a file with consistent contents + pass + + with open(self.filename, 'rb') as f: + assert_raises_regex(ValueError, "Cannot read into object array", + np.fromfile, f, dtype=object) + + assert_raises_regex(ValueError, "Cannot read into object array", + np.fromfile, self.filename, dtype=object) + + def test_fromfile_offset(self): + with open(self.filename, 'wb') as f: + self.x.tofile(f) + + with open(self.filename, 'rb') as f: + y = np.fromfile(f, dtype=self.dtype, offset=0) + assert_array_equal(y, self.x.flat) + + with open(self.filename, 'rb') as f: + count_items = len(self.x.flat) // 8 + offset_items = len(self.x.flat) // 4 + offset_bytes = self.dtype.itemsize * offset_items + y = np.fromfile(f, dtype=self.dtype, count=count_items, offset=offset_bytes) + assert_array_equal(y, self.x.flat[offset_items:offset_items+count_items]) + + # subsequent seeks should stack + offset_bytes = self.dtype.itemsize + z = np.fromfile(f, dtype=self.dtype, offset=offset_bytes) + assert_array_equal(z, self.x.flat[offset_items+count_items+1:]) + + with open(self.filename, 'wb') as f: + self.x.tofile(f, sep=",") + + with open(self.filename, 'rb') as f: + assert_raises_regex( + TypeError, + "'offset' argument only permitted for binary files", + np.fromfile, self.filename, dtype=self.dtype, + sep=",", offset=1) + + def _check_from(self, s, value, **kw): + if 'sep' not in kw: + y = np.frombuffer(s, **kw) + else: + y = np.fromstring(s, **kw) + assert_array_equal(y, value) + + with open(self.filename, 'wb') as f: + f.write(s) + y = np.fromfile(self.filename, **kw) + assert_array_equal(y, value) + + def test_nan(self): + self._check_from( + b"nan +nan -nan NaN nan(foo) +NaN(BAR) -NAN(q_u_u_x_)", + [np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan], + sep=' ') + + def test_inf(self): + self._check_from( + b"inf +inf -inf infinity -Infinity iNfInItY -inF", + [np.inf, np.inf, -np.inf, np.inf, -np.inf, np.inf, -np.inf], + sep=' ') + + def test_numbers(self): + self._check_from(b"1.234 -1.234 .3 .3e55 -123133.1231e+133", + [1.234, -1.234, .3, .3e55, -123133.1231e+133], sep=' ') + + def test_binary(self): + self._check_from(b'\x00\x00\x80?\x00\x00\x00@\x00\x00@@\x00\x00\x80@', + np.array([1, 2, 3, 4]), + dtype=' 1 minute on mechanical hard drive + def test_big_binary(self): + """Test workarounds for 32-bit limited fwrite, fseek, and ftell + calls in windows. These normally would hang doing something like this. + See http://projects.scipy.org/numpy/ticket/1660""" + if sys.platform != 'win32': + return + try: + # before workarounds, only up to 2**32-1 worked + fourgbplus = 2**32 + 2**16 + testbytes = np.arange(8, dtype=np.int8) + n = len(testbytes) + flike = tempfile.NamedTemporaryFile() + f = flike.file + np.tile(testbytes, fourgbplus // testbytes.nbytes).tofile(f) + flike.seek(0) + a = np.fromfile(f, dtype=np.int8) + flike.close() + assert_(len(a) == fourgbplus) + # check only start and end for speed: + assert_((a[:n] == testbytes).all()) + assert_((a[-n:] == testbytes).all()) + except (MemoryError, ValueError): + pass + + def test_string(self): + self._check_from(b'1,2,3,4', [1., 2., 3., 4.], sep=',') + + def test_counted_string(self): + self._check_from(b'1,2,3,4', [1., 2., 3., 4.], count=4, sep=',') + self._check_from(b'1,2,3,4', [1., 2., 3.], count=3, sep=',') + self._check_from(b'1,2,3,4', [1., 2., 3., 4.], count=-1, sep=',') + + def test_string_with_ws(self): + self._check_from(b'1 2 3 4 ', [1, 2, 3, 4], dtype=int, sep=' ') + + def test_counted_string_with_ws(self): + self._check_from(b'1 2 3 4 ', [1, 2, 3], count=3, dtype=int, + sep=' ') + + def test_ascii(self): + self._check_from(b'1 , 2 , 3 , 4', [1., 2., 3., 4.], sep=',') + self._check_from(b'1,2,3,4', [1., 2., 3., 4.], dtype=float, sep=',') + + def test_malformed(self): + with assert_warns(DeprecationWarning): + self._check_from(b'1.234 1,234', [1.234, 1.], sep=' ') + + def test_long_sep(self): + self._check_from(b'1_x_3_x_4_x_5', [1, 3, 4, 5], sep='_x_') + + def test_dtype(self): + v = np.array([1, 2, 3, 4], dtype=np.int_) + self._check_from(b'1,2,3,4', v, sep=',', dtype=np.int_) + + def test_dtype_bool(self): + # can't use _check_from because fromstring can't handle True/False + v = np.array([True, False, True, False], dtype=np.bool_) + s = b'1,0,-2.3,0' + with open(self.filename, 'wb') as f: + f.write(s) + y = np.fromfile(self.filename, sep=',', dtype=np.bool_) + assert_(y.dtype == '?') + assert_array_equal(y, v) + + def test_tofile_sep(self): + x = np.array([1.51, 2, 3.51, 4], dtype=float) + with open(self.filename, 'w') as f: + x.tofile(f, sep=',') + with open(self.filename, 'r') as f: + s = f.read() + #assert_equal(s, '1.51,2.0,3.51,4.0') + y = np.array([float(p) for p in s.split(',')]) + assert_array_equal(x,y) + + def test_tofile_format(self): + x = np.array([1.51, 2, 3.51, 4], dtype=float) + with open(self.filename, 'w') as f: + x.tofile(f, sep=',', format='%.2f') + with open(self.filename, 'r') as f: + s = f.read() + assert_equal(s, '1.51,2.00,3.51,4.00') + + def test_tofile_cleanup(self): + x = np.zeros((10), dtype=object) + with open(self.filename, 'wb') as f: + assert_raises(IOError, lambda: x.tofile(f, sep='')) + # Dup-ed file handle should be closed or remove will fail on Windows OS + os.remove(self.filename) + + # Also make sure that we close the Python handle + assert_raises(IOError, lambda: x.tofile(self.filename)) + os.remove(self.filename) + + def test_locale(self): + with CommaDecimalPointLocale(): + self.test_numbers() + self.test_nan() + self.test_inf() + self.test_counted_string() + self.test_ascii() + self.test_malformed() + self.test_tofile_sep() + self.test_tofile_format() + + def test_fromfile_subarray_binary(self): + # Test subarray dtypes which are absorbed into the shape + x = np.arange(24, dtype="i4").reshape(2, 3, 4) + x.tofile(self.filename) + res = np.fromfile(self.filename, dtype="(3,4)i4") + assert_array_equal(x, res) + + x_str = x.tobytes() + with assert_warns(DeprecationWarning): + # binary fromstring is deprecated + res = np.fromstring(x_str, dtype="(3,4)i4") + assert_array_equal(x, res) + + def test_parsing_subarray_unsupported(self): + # We currently do not support parsing subarray dtypes + data = "12,42,13," * 50 + with pytest.raises(ValueError): + expected = np.fromstring(data, dtype="(3,)i", sep=",") + + with open(self.filename, "w") as f: + f.write(data) + + with pytest.raises(ValueError): + np.fromfile(self.filename, dtype="(3,)i", sep=",") + + def test_read_shorter_than_count_subarray(self): + # Test that requesting more values does not cause any problems + # in conjuction with subarray dimensions being absored into the + # array dimension. + expected = np.arange(511 * 10, dtype="i").reshape(-1, 10) + + binary = expected.tobytes() + with pytest.raises(ValueError): + with pytest.warns(DeprecationWarning): + np.fromstring(binary, dtype="(10,)i", count=10000) + + expected.tofile(self.filename) + res = np.fromfile(self.filename, dtype="(10,)i", count=10000) + assert_array_equal(res, expected) + + +class TestFromBuffer: + @pytest.mark.parametrize('byteorder', ['<', '>']) + @pytest.mark.parametrize('dtype', [float, int, complex]) + def test_basic(self, byteorder, dtype): + dt = np.dtype(dtype).newbyteorder(byteorder) + x = (np.random.random((4, 7)) * 5).astype(dt) + buf = x.tobytes() + assert_array_equal(np.frombuffer(buf, dtype=dt), x.flat) + + def test_empty(self): + assert_array_equal(np.frombuffer(b''), np.array([])) + + +class TestFlat: + def setup(self): + a0 = np.arange(20.0) + a = a0.reshape(4, 5) + a0.shape = (4, 5) + a.flags.writeable = False + self.a = a + self.b = a[::2, ::2] + self.a0 = a0 + self.b0 = a0[::2, ::2] + + def test_contiguous(self): + testpassed = False + try: + self.a.flat[12] = 100.0 + except ValueError: + testpassed = True + assert_(testpassed) + assert_(self.a.flat[12] == 12.0) + + def test_discontiguous(self): + testpassed = False + try: + self.b.flat[4] = 100.0 + except ValueError: + testpassed = True + assert_(testpassed) + assert_(self.b.flat[4] == 12.0) + + def test___array__(self): + c = self.a.flat.__array__() + d = self.b.flat.__array__() + e = self.a0.flat.__array__() + f = self.b0.flat.__array__() + + assert_(c.flags.writeable is False) + assert_(d.flags.writeable is False) + # for 1.14 all are set to non-writeable on the way to replacing the + # UPDATEIFCOPY array returned for non-contiguous arrays. + assert_(e.flags.writeable is True) + assert_(f.flags.writeable is False) + with assert_warns(DeprecationWarning): + assert_(c.flags.updateifcopy is False) + with assert_warns(DeprecationWarning): + assert_(d.flags.updateifcopy is False) + with assert_warns(DeprecationWarning): + assert_(e.flags.updateifcopy is False) + with assert_warns(DeprecationWarning): + # UPDATEIFCOPY is removed. + assert_(f.flags.updateifcopy is False) + assert_(c.flags.writebackifcopy is False) + assert_(d.flags.writebackifcopy is False) + assert_(e.flags.writebackifcopy is False) + assert_(f.flags.writebackifcopy is False) + + @pytest.mark.skipif(not HAS_REFCOUNT, reason="Python lacks refcounts") + def test_refcount(self): + # includes regression test for reference count error gh-13165 + inds = [np.intp(0), np.array([True]*self.a.size), np.array([0]), None] + indtype = np.dtype(np.intp) + rc_indtype = sys.getrefcount(indtype) + for ind in inds: + rc_ind = sys.getrefcount(ind) + for _ in range(100): + try: + self.a.flat[ind] + except IndexError: + pass + assert_(abs(sys.getrefcount(ind) - rc_ind) < 50) + assert_(abs(sys.getrefcount(indtype) - rc_indtype) < 50) + + +class TestResize: + + @_no_tracing + def test_basic(self): + x = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]]) + if IS_PYPY: + x.resize((5, 5), refcheck=False) + else: + x.resize((5, 5)) + assert_array_equal(x.flat[:9], + np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]]).flat) + assert_array_equal(x[9:].flat, 0) + + def test_check_reference(self): + x = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]]) + y = x + assert_raises(ValueError, x.resize, (5, 1)) + del y # avoid pyflakes unused variable warning. + + @_no_tracing + def test_int_shape(self): + x = np.eye(3) + if IS_PYPY: + x.resize(3, refcheck=False) + else: + x.resize(3) + assert_array_equal(x, np.eye(3)[0,:]) + + def test_none_shape(self): + x = np.eye(3) + x.resize(None) + assert_array_equal(x, np.eye(3)) + x.resize() + assert_array_equal(x, np.eye(3)) + + def test_0d_shape(self): + # to it multiple times to test it does not break alloc cache gh-9216 + for i in range(10): + x = np.empty((1,)) + x.resize(()) + assert_equal(x.shape, ()) + assert_equal(x.size, 1) + x = np.empty(()) + x.resize((1,)) + assert_equal(x.shape, (1,)) + assert_equal(x.size, 1) + + def test_invalid_arguments(self): + assert_raises(TypeError, np.eye(3).resize, 'hi') + assert_raises(ValueError, np.eye(3).resize, -1) + assert_raises(TypeError, np.eye(3).resize, order=1) + assert_raises(TypeError, np.eye(3).resize, refcheck='hi') + + @_no_tracing + def test_freeform_shape(self): + x = np.eye(3) + if IS_PYPY: + x.resize(3, 2, 1, refcheck=False) + else: + x.resize(3, 2, 1) + assert_(x.shape == (3, 2, 1)) + + @_no_tracing + def test_zeros_appended(self): + x = np.eye(3) + if IS_PYPY: + x.resize(2, 3, 3, refcheck=False) + else: + x.resize(2, 3, 3) + assert_array_equal(x[0], np.eye(3)) + assert_array_equal(x[1], np.zeros((3, 3))) + + @_no_tracing + def test_obj_obj(self): + # check memory is initialized on resize, gh-4857 + a = np.ones(10, dtype=[('k', object, 2)]) + if IS_PYPY: + a.resize(15, refcheck=False) + else: + a.resize(15,) + assert_equal(a.shape, (15,)) + assert_array_equal(a['k'][-5:], 0) + assert_array_equal(a['k'][:-5], 1) + + def test_empty_view(self): + # check that sizes containing a zero don't trigger a reallocate for + # already empty arrays + x = np.zeros((10, 0), int) + x_view = x[...] + x_view.resize((0, 10)) + x_view.resize((0, 100)) + + def test_check_weakref(self): + x = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]]) + xref = weakref.ref(x) + assert_raises(ValueError, x.resize, (5, 1)) + del xref # avoid pyflakes unused variable warning. + + +class TestRecord: + def test_field_rename(self): + dt = np.dtype([('f', float), ('i', int)]) + dt.names = ['p', 'q'] + assert_equal(dt.names, ['p', 'q']) + + def test_multiple_field_name_occurrence(self): + def test_dtype_init(): + np.dtype([("A", "f8"), ("B", "f8"), ("A", "f8")]) + + # Error raised when multiple fields have the same name + assert_raises(ValueError, test_dtype_init) + + def test_bytes_fields(self): + # Bytes are not allowed in field names and not recognized in titles + # on Py3 + assert_raises(TypeError, np.dtype, [(b'a', int)]) + assert_raises(TypeError, np.dtype, [(('b', b'a'), int)]) + + dt = np.dtype([((b'a', 'b'), int)]) + assert_raises(TypeError, dt.__getitem__, b'a') + + x = np.array([(1,), (2,), (3,)], dtype=dt) + assert_raises(IndexError, x.__getitem__, b'a') + + y = x[0] + assert_raises(IndexError, y.__getitem__, b'a') + + def test_multiple_field_name_unicode(self): + def test_dtype_unicode(): + np.dtype([("\u20B9", "f8"), ("B", "f8"), ("\u20B9", "f8")]) + + # Error raised when multiple fields have the same name(unicode included) + assert_raises(ValueError, test_dtype_unicode) + + def test_fromarrays_unicode(self): + # A single name string provided to fromarrays() is allowed to be unicode + # on both Python 2 and 3: + x = np.core.records.fromarrays([[0], [1]], names=u'a,b', formats=u'i4,i4') + assert_equal(x['a'][0], 0) + assert_equal(x['b'][0], 1) + + def test_unicode_order(self): + # Test that we can sort with order as a unicode field name in both Python 2 and + # 3: + name = u'b' + x = np.array([1, 3, 2], dtype=[(name, int)]) + x.sort(order=name) + assert_equal(x[u'b'], np.array([1, 2, 3])) + + def test_field_names(self): + # Test unicode and 8-bit / byte strings can be used + a = np.zeros((1,), dtype=[('f1', 'i4'), + ('f2', 'i4'), + ('f3', [('sf1', 'i4')])]) + # byte string indexing fails gracefully + assert_raises(IndexError, a.__setitem__, b'f1', 1) + assert_raises(IndexError, a.__getitem__, b'f1') + assert_raises(IndexError, a['f1'].__setitem__, b'sf1', 1) + assert_raises(IndexError, a['f1'].__getitem__, b'sf1') + b = a.copy() + fn1 = str('f1') + b[fn1] = 1 + assert_equal(b[fn1], 1) + fnn = str('not at all') + assert_raises(ValueError, b.__setitem__, fnn, 1) + assert_raises(ValueError, b.__getitem__, fnn) + b[0][fn1] = 2 + assert_equal(b[fn1], 2) + # Subfield + assert_raises(ValueError, b[0].__setitem__, fnn, 1) + assert_raises(ValueError, b[0].__getitem__, fnn) + # Subfield + fn3 = str('f3') + sfn1 = str('sf1') + b[fn3][sfn1] = 1 + assert_equal(b[fn3][sfn1], 1) + assert_raises(ValueError, b[fn3].__setitem__, fnn, 1) + assert_raises(ValueError, b[fn3].__getitem__, fnn) + # multiple subfields + fn2 = str('f2') + b[fn2] = 3 + + assert_equal(b[['f1', 'f2']][0].tolist(), (2, 3)) + assert_equal(b[['f2', 'f1']][0].tolist(), (3, 2)) + assert_equal(b[['f1', 'f3']][0].tolist(), (2, (1,))) + + # non-ascii unicode field indexing is well behaved + assert_raises(ValueError, a.__setitem__, u'\u03e0', 1) + assert_raises(ValueError, a.__getitem__, u'\u03e0') + + def test_record_hash(self): + a = np.array([(1, 2), (1, 2)], dtype='i1,i2') + a.flags.writeable = False + b = np.array([(1, 2), (3, 4)], dtype=[('num1', 'i1'), ('num2', 'i2')]) + b.flags.writeable = False + c = np.array([(1, 2), (3, 4)], dtype='i1,i2') + c.flags.writeable = False + assert_(hash(a[0]) == hash(a[1])) + assert_(hash(a[0]) == hash(b[0])) + assert_(hash(a[0]) != hash(b[1])) + assert_(hash(c[0]) == hash(a[0]) and c[0] == a[0]) + + def test_record_no_hash(self): + a = np.array([(1, 2), (1, 2)], dtype='i1,i2') + assert_raises(TypeError, hash, a[0]) + + def test_empty_structure_creation(self): + # make sure these do not raise errors (gh-5631) + np.array([()], dtype={'names': [], 'formats': [], + 'offsets': [], 'itemsize': 12}) + np.array([(), (), (), (), ()], dtype={'names': [], 'formats': [], + 'offsets': [], 'itemsize': 12}) + + def test_multifield_indexing_view(self): + a = np.ones(3, dtype=[('a', 'i4'), ('b', 'f4'), ('c', 'u4')]) + v = a[['a', 'c']] + assert_(v.base is a) + assert_(v.dtype == np.dtype({'names': ['a', 'c'], + 'formats': ['i4', 'u4'], + 'offsets': [0, 8]})) + v[:] = (4,5) + assert_equal(a[0].item(), (4, 1, 5)) + +class TestView: + def test_basic(self): + x = np.array([(1, 2, 3, 4), (5, 6, 7, 8)], + dtype=[('r', np.int8), ('g', np.int8), + ('b', np.int8), ('a', np.int8)]) + # We must be specific about the endianness here: + y = x.view(dtype=' 0) + assert_(issubclass(w[0].category, RuntimeWarning)) + + def test_empty(self): + A = np.zeros((0, 3)) + for f in self.funcs: + for axis in [0, None]: + with warnings.catch_warnings(record=True) as w: + warnings.simplefilter('always') + assert_(np.isnan(f(A, axis=axis)).all()) + assert_(len(w) > 0) + assert_(issubclass(w[0].category, RuntimeWarning)) + for axis in [1]: + with warnings.catch_warnings(record=True) as w: + warnings.simplefilter('always') + assert_equal(f(A, axis=axis), np.zeros([])) + + def test_mean_values(self): + for mat in [self.rmat, self.cmat, self.omat]: + for axis in [0, 1]: + tgt = mat.sum(axis=axis) + res = _mean(mat, axis=axis) * mat.shape[axis] + assert_almost_equal(res, tgt) + for axis in [None]: + tgt = mat.sum(axis=axis) + res = _mean(mat, axis=axis) * np.prod(mat.shape) + assert_almost_equal(res, tgt) + + def test_mean_float16(self): + # This fail if the sum inside mean is done in float16 instead + # of float32. + assert_(_mean(np.ones(100000, dtype='float16')) == 1) + + def test_mean_axis_error(self): + # Ensure that AxisError is raised instead of IndexError when axis is + # out of bounds, see gh-15817. + with assert_raises(np.core._exceptions.AxisError): + np.arange(10).mean(axis=2) + + def test_mean_where(self): + a = np.arange(16).reshape((4, 4)) + wh_full = np.array([[False, True, False, True], + [True, False, True, False], + [True, True, False, False], + [False, False, True, True]]) + wh_partial = np.array([[False], + [True], + [True], + [False]]) + _cases = [(1, True, [1.5, 5.5, 9.5, 13.5]), + (0, wh_full, [6., 5., 10., 9.]), + (1, wh_full, [2., 5., 8.5, 14.5]), + (0, wh_partial, [6., 7., 8., 9.])] + for _ax, _wh, _res in _cases: + assert_allclose(a.mean(axis=_ax, where=_wh), + np.array(_res)) + assert_allclose(np.mean(a, axis=_ax, where=_wh), + np.array(_res)) + + a3d = np.arange(16).reshape((2, 2, 4)) + _wh_partial = np.array([False, True, True, False]) + _res = [[1.5, 5.5], [9.5, 13.5]] + assert_allclose(a3d.mean(axis=2, where=_wh_partial), + np.array(_res)) + assert_allclose(np.mean(a3d, axis=2, where=_wh_partial), + np.array(_res)) + + with pytest.warns(RuntimeWarning) as w: + assert_allclose(a.mean(axis=1, where=wh_partial), + np.array([np.nan, 5.5, 9.5, np.nan])) + with pytest.warns(RuntimeWarning) as w: + assert_equal(a.mean(where=False), np.nan) + with pytest.warns(RuntimeWarning) as w: + assert_equal(np.mean(a, where=False), np.nan) + + def test_var_values(self): + for mat in [self.rmat, self.cmat, self.omat]: + for axis in [0, 1, None]: + msqr = _mean(mat * mat.conj(), axis=axis) + mean = _mean(mat, axis=axis) + tgt = msqr - mean * mean.conjugate() + res = _var(mat, axis=axis) + assert_almost_equal(res, tgt) + + @pytest.mark.parametrize(('complex_dtype', 'ndec'), ( + ('complex64', 6), + ('complex128', 7), + ('clongdouble', 7), + )) + def test_var_complex_values(self, complex_dtype, ndec): + # Test fast-paths for every builtin complex type + for axis in [0, 1, None]: + mat = self.cmat.copy().astype(complex_dtype) + msqr = _mean(mat * mat.conj(), axis=axis) + mean = _mean(mat, axis=axis) + tgt = msqr - mean * mean.conjugate() + res = _var(mat, axis=axis) + assert_almost_equal(res, tgt, decimal=ndec) + + def test_var_dimensions(self): + # _var paths for complex number introduce additions on views that + # increase dimensions. Ensure this generalizes to higher dims + mat = np.stack([self.cmat]*3) + for axis in [0, 1, 2, -1, None]: + msqr = _mean(mat * mat.conj(), axis=axis) + mean = _mean(mat, axis=axis) + tgt = msqr - mean * mean.conjugate() + res = _var(mat, axis=axis) + assert_almost_equal(res, tgt) + + def test_var_complex_byteorder(self): + # Test that var fast-path does not cause failures for complex arrays + # with non-native byteorder + cmat = self.cmat.copy().astype('complex128') + cmat_swapped = cmat.astype(cmat.dtype.newbyteorder()) + assert_almost_equal(cmat.var(), cmat_swapped.var()) + + def test_var_axis_error(self): + # Ensure that AxisError is raised instead of IndexError when axis is + # out of bounds, see gh-15817. + with assert_raises(np.core._exceptions.AxisError): + np.arange(10).var(axis=2) + + def test_var_where(self): + a = np.arange(25).reshape((5, 5)) + wh_full = np.array([[False, True, False, True, True], + [True, False, True, True, False], + [True, True, False, False, True], + [False, True, True, False, True], + [True, False, True, True, False]]) + wh_partial = np.array([[False], + [True], + [True], + [False], + [True]]) + _cases = [(0, True, [50., 50., 50., 50., 50.]), + (1, True, [2., 2., 2., 2., 2.])] + for _ax, _wh, _res in _cases: + assert_allclose(a.var(axis=_ax, where=_wh), + np.array(_res)) + assert_allclose(np.var(a, axis=_ax, where=_wh), + np.array(_res)) + + a3d = np.arange(16).reshape((2, 2, 4)) + _wh_partial = np.array([False, True, True, False]) + _res = [[0.25, 0.25], [0.25, 0.25]] + assert_allclose(a3d.var(axis=2, where=_wh_partial), + np.array(_res)) + assert_allclose(np.var(a3d, axis=2, where=_wh_partial), + np.array(_res)) + + assert_allclose(np.var(a, axis=1, where=wh_full), + np.var(a[wh_full].reshape((5, 3)), axis=1)) + assert_allclose(np.var(a, axis=0, where=wh_partial), + np.var(a[wh_partial[:,0]], axis=0)) + with pytest.warns(RuntimeWarning) as w: + assert_equal(a.var(where=False), np.nan) + with pytest.warns(RuntimeWarning) as w: + assert_equal(np.var(a, where=False), np.nan) + + def test_std_values(self): + for mat in [self.rmat, self.cmat, self.omat]: + for axis in [0, 1, None]: + tgt = np.sqrt(_var(mat, axis=axis)) + res = _std(mat, axis=axis) + assert_almost_equal(res, tgt) + + def test_std_where(self): + a = np.arange(25).reshape((5,5))[::-1] + whf = np.array([[False, True, False, True, True], + [True, False, True, False, True], + [True, True, False, True, False], + [True, False, True, True, False], + [False, True, False, True, True]]) + whp = np.array([[False], + [False], + [True], + [True], + [False]]) + _cases = [ + (0, True, 7.07106781*np.ones((5))), + (1, True, 1.41421356*np.ones((5))), + (0, whf, + np.array([4.0824829 , 8.16496581, 5., 7.39509973, 8.49836586])), + (0, whp, 2.5*np.ones((5))) + ] + for _ax, _wh, _res in _cases: + assert_allclose(a.std(axis=_ax, where=_wh), _res) + assert_allclose(np.std(a, axis=_ax, where=_wh), _res) + + a3d = np.arange(16).reshape((2, 2, 4)) + _wh_partial = np.array([False, True, True, False]) + _res = [[0.5, 0.5], [0.5, 0.5]] + assert_allclose(a3d.std(axis=2, where=_wh_partial), + np.array(_res)) + assert_allclose(np.std(a3d, axis=2, where=_wh_partial), + np.array(_res)) + + assert_allclose(a.std(axis=1, where=whf), + np.std(a[whf].reshape((5,3)), axis=1)) + assert_allclose(np.std(a, axis=1, where=whf), + (a[whf].reshape((5,3))).std(axis=1)) + assert_allclose(a.std(axis=0, where=whp), + np.std(a[whp[:,0]], axis=0)) + assert_allclose(np.std(a, axis=0, where=whp), + (a[whp[:,0]]).std(axis=0)) + with pytest.warns(RuntimeWarning) as w: + assert_equal(a.std(where=False), np.nan) + with pytest.warns(RuntimeWarning) as w: + assert_equal(np.std(a, where=False), np.nan) + + def test_subclass(self): + class TestArray(np.ndarray): + def __new__(cls, data, info): + result = np.array(data) + result = result.view(cls) + result.info = info + return result + + def __array_finalize__(self, obj): + self.info = getattr(obj, "info", '') + + dat = TestArray([[1, 2, 3, 4], [5, 6, 7, 8]], 'jubba') + res = dat.mean(1) + assert_(res.info == dat.info) + res = dat.std(1) + assert_(res.info == dat.info) + res = dat.var(1) + assert_(res.info == dat.info) + +class TestVdot: + def test_basic(self): + dt_numeric = np.typecodes['AllFloat'] + np.typecodes['AllInteger'] + dt_complex = np.typecodes['Complex'] + + # test real + a = np.eye(3) + for dt in dt_numeric + 'O': + b = a.astype(dt) + res = np.vdot(b, b) + assert_(np.isscalar(res)) + assert_equal(np.vdot(b, b), 3) + + # test complex + a = np.eye(3) * 1j + for dt in dt_complex + 'O': + b = a.astype(dt) + res = np.vdot(b, b) + assert_(np.isscalar(res)) + assert_equal(np.vdot(b, b), 3) + + # test boolean + b = np.eye(3, dtype=bool) + res = np.vdot(b, b) + assert_(np.isscalar(res)) + assert_equal(np.vdot(b, b), True) + + def test_vdot_array_order(self): + a = np.array([[1, 2], [3, 4]], order='C') + b = np.array([[1, 2], [3, 4]], order='F') + res = np.vdot(a, a) + + # integer arrays are exact + assert_equal(np.vdot(a, b), res) + assert_equal(np.vdot(b, a), res) + assert_equal(np.vdot(b, b), res) + + def test_vdot_uncontiguous(self): + for size in [2, 1000]: + # Different sizes match different branches in vdot. + a = np.zeros((size, 2, 2)) + b = np.zeros((size, 2, 2)) + a[:, 0, 0] = np.arange(size) + b[:, 0, 0] = np.arange(size) + 1 + # Make a and b uncontiguous: + a = a[..., 0] + b = b[..., 0] + + assert_equal(np.vdot(a, b), + np.vdot(a.flatten(), b.flatten())) + assert_equal(np.vdot(a, b.copy()), + np.vdot(a.flatten(), b.flatten())) + assert_equal(np.vdot(a.copy(), b), + np.vdot(a.flatten(), b.flatten())) + assert_equal(np.vdot(a.copy('F'), b), + np.vdot(a.flatten(), b.flatten())) + assert_equal(np.vdot(a, b.copy('F')), + np.vdot(a.flatten(), b.flatten())) + + +class TestDot: + def setup(self): + np.random.seed(128) + self.A = np.random.rand(4, 2) + self.b1 = np.random.rand(2, 1) + self.b2 = np.random.rand(2) + self.b3 = np.random.rand(1, 2) + self.b4 = np.random.rand(4) + self.N = 7 + + def test_dotmatmat(self): + A = self.A + res = np.dot(A.transpose(), A) + tgt = np.array([[1.45046013, 0.86323640], + [0.86323640, 0.84934569]]) + assert_almost_equal(res, tgt, decimal=self.N) + + def test_dotmatvec(self): + A, b1 = self.A, self.b1 + res = np.dot(A, b1) + tgt = np.array([[0.32114320], [0.04889721], + [0.15696029], [0.33612621]]) + assert_almost_equal(res, tgt, decimal=self.N) + + def test_dotmatvec2(self): + A, b2 = self.A, self.b2 + res = np.dot(A, b2) + tgt = np.array([0.29677940, 0.04518649, 0.14468333, 0.31039293]) + assert_almost_equal(res, tgt, decimal=self.N) + + def test_dotvecmat(self): + A, b4 = self.A, self.b4 + res = np.dot(b4, A) + tgt = np.array([1.23495091, 1.12222648]) + assert_almost_equal(res, tgt, decimal=self.N) + + def test_dotvecmat2(self): + b3, A = self.b3, self.A + res = np.dot(b3, A.transpose()) + tgt = np.array([[0.58793804, 0.08957460, 0.30605758, 0.62716383]]) + assert_almost_equal(res, tgt, decimal=self.N) + + def test_dotvecmat3(self): + A, b4 = self.A, self.b4 + res = np.dot(A.transpose(), b4) + tgt = np.array([1.23495091, 1.12222648]) + assert_almost_equal(res, tgt, decimal=self.N) + + def test_dotvecvecouter(self): + b1, b3 = self.b1, self.b3 + res = np.dot(b1, b3) + tgt = np.array([[0.20128610, 0.08400440], [0.07190947, 0.03001058]]) + assert_almost_equal(res, tgt, decimal=self.N) + + def test_dotvecvecinner(self): + b1, b3 = self.b1, self.b3 + res = np.dot(b3, b1) + tgt = np.array([[ 0.23129668]]) + assert_almost_equal(res, tgt, decimal=self.N) + + def test_dotcolumnvect1(self): + b1 = np.ones((3, 1)) + b2 = [5.3] + res = np.dot(b1, b2) + tgt = np.array([5.3, 5.3, 5.3]) + assert_almost_equal(res, tgt, decimal=self.N) + + def test_dotcolumnvect2(self): + b1 = np.ones((3, 1)).transpose() + b2 = [6.2] + res = np.dot(b2, b1) + tgt = np.array([6.2, 6.2, 6.2]) + assert_almost_equal(res, tgt, decimal=self.N) + + def test_dotvecscalar(self): + np.random.seed(100) + b1 = np.random.rand(1, 1) + b2 = np.random.rand(1, 4) + res = np.dot(b1, b2) + tgt = np.array([[0.15126730, 0.23068496, 0.45905553, 0.00256425]]) + assert_almost_equal(res, tgt, decimal=self.N) + + def test_dotvecscalar2(self): + np.random.seed(100) + b1 = np.random.rand(4, 1) + b2 = np.random.rand(1, 1) + res = np.dot(b1, b2) + tgt = np.array([[0.00256425],[0.00131359],[0.00200324],[ 0.00398638]]) + assert_almost_equal(res, tgt, decimal=self.N) + + def test_all(self): + dims = [(), (1,), (1, 1)] + dout = [(), (1,), (1, 1), (1,), (), (1,), (1, 1), (1,), (1, 1)] + for dim, (dim1, dim2) in zip(dout, itertools.product(dims, dims)): + b1 = np.zeros(dim1) + b2 = np.zeros(dim2) + res = np.dot(b1, b2) + tgt = np.zeros(dim) + assert_(res.shape == tgt.shape) + assert_almost_equal(res, tgt, decimal=self.N) + + def test_vecobject(self): + class Vec: + def __init__(self, sequence=None): + if sequence is None: + sequence = [] + self.array = np.array(sequence) + + def __add__(self, other): + out = Vec() + out.array = self.array + other.array + return out + + def __sub__(self, other): + out = Vec() + out.array = self.array - other.array + return out + + def __mul__(self, other): # with scalar + out = Vec(self.array.copy()) + out.array *= other + return out + + def __rmul__(self, other): + return self*other + + U_non_cont = np.transpose([[1., 1.], [1., 2.]]) + U_cont = np.ascontiguousarray(U_non_cont) + x = np.array([Vec([1., 0.]), Vec([0., 1.])]) + zeros = np.array([Vec([0., 0.]), Vec([0., 0.])]) + zeros_test = np.dot(U_cont, x) - np.dot(U_non_cont, x) + assert_equal(zeros[0].array, zeros_test[0].array) + assert_equal(zeros[1].array, zeros_test[1].array) + + def test_dot_2args(self): + from numpy.core.multiarray import dot + + a = np.array([[1, 2], [3, 4]], dtype=float) + b = np.array([[1, 0], [1, 1]], dtype=float) + c = np.array([[3, 2], [7, 4]], dtype=float) + + d = dot(a, b) + assert_allclose(c, d) + + def test_dot_3args(self): + from numpy.core.multiarray import dot + + np.random.seed(22) + f = np.random.random_sample((1024, 16)) + v = np.random.random_sample((16, 32)) + + r = np.empty((1024, 32)) + for i in range(12): + dot(f, v, r) + if HAS_REFCOUNT: + assert_equal(sys.getrefcount(r), 2) + r2 = dot(f, v, out=None) + assert_array_equal(r2, r) + assert_(r is dot(f, v, out=r)) + + v = v[:, 0].copy() # v.shape == (16,) + r = r[:, 0].copy() # r.shape == (1024,) + r2 = dot(f, v) + assert_(r is dot(f, v, r)) + assert_array_equal(r2, r) + + def test_dot_3args_errors(self): + from numpy.core.multiarray import dot + + np.random.seed(22) + f = np.random.random_sample((1024, 16)) + v = np.random.random_sample((16, 32)) + + r = np.empty((1024, 31)) + assert_raises(ValueError, dot, f, v, r) + + r = np.empty((1024,)) + assert_raises(ValueError, dot, f, v, r) + + r = np.empty((32,)) + assert_raises(ValueError, dot, f, v, r) + + r = np.empty((32, 1024)) + assert_raises(ValueError, dot, f, v, r) + assert_raises(ValueError, dot, f, v, r.T) + + r = np.empty((1024, 64)) + assert_raises(ValueError, dot, f, v, r[:, ::2]) + assert_raises(ValueError, dot, f, v, r[:, :32]) + + r = np.empty((1024, 32), dtype=np.float32) + assert_raises(ValueError, dot, f, v, r) + + r = np.empty((1024, 32), dtype=int) + assert_raises(ValueError, dot, f, v, r) + + def test_dot_array_order(self): + a = np.array([[1, 2], [3, 4]], order='C') + b = np.array([[1, 2], [3, 4]], order='F') + res = np.dot(a, a) + + # integer arrays are exact + assert_equal(np.dot(a, b), res) + assert_equal(np.dot(b, a), res) + assert_equal(np.dot(b, b), res) + + +class MatmulCommon: + """Common tests for '@' operator and numpy.matmul. + + """ + # Should work with these types. Will want to add + # "O" at some point + types = "?bhilqBHILQefdgFDGO" + + def test_exceptions(self): + dims = [ + ((1,), (2,)), # mismatched vector vector + ((2, 1,), (2,)), # mismatched matrix vector + ((2,), (1, 2)), # mismatched vector matrix + ((1, 2), (3, 1)), # mismatched matrix matrix + ((1,), ()), # vector scalar + ((), (1)), # scalar vector + ((1, 1), ()), # matrix scalar + ((), (1, 1)), # scalar matrix + ((2, 2, 1), (3, 1, 2)), # cannot broadcast + ] + + for dt, (dm1, dm2) in itertools.product(self.types, dims): + a = np.ones(dm1, dtype=dt) + b = np.ones(dm2, dtype=dt) + assert_raises(ValueError, self.matmul, a, b) + + def test_shapes(self): + dims = [ + ((1, 1), (2, 1, 1)), # broadcast first argument + ((2, 1, 1), (1, 1)), # broadcast second argument + ((2, 1, 1), (2, 1, 1)), # matrix stack sizes match + ] + + for dt, (dm1, dm2) in itertools.product(self.types, dims): + a = np.ones(dm1, dtype=dt) + b = np.ones(dm2, dtype=dt) + res = self.matmul(a, b) + assert_(res.shape == (2, 1, 1)) + + # vector vector returns scalars. + for dt in self.types: + a = np.ones((2,), dtype=dt) + b = np.ones((2,), dtype=dt) + c = self.matmul(a, b) + assert_(np.array(c).shape == ()) + + def test_result_types(self): + mat = np.ones((1,1)) + vec = np.ones((1,)) + for dt in self.types: + m = mat.astype(dt) + v = vec.astype(dt) + for arg in [(m, v), (v, m), (m, m)]: + res = self.matmul(*arg) + assert_(res.dtype == dt) + + # vector vector returns scalars + if dt != "O": + res = self.matmul(v, v) + assert_(type(res) is np.dtype(dt).type) + + def test_scalar_output(self): + vec1 = np.array([2]) + vec2 = np.array([3, 4]).reshape(1, -1) + tgt = np.array([6, 8]) + for dt in self.types[1:]: + v1 = vec1.astype(dt) + v2 = vec2.astype(dt) + res = self.matmul(v1, v2) + assert_equal(res, tgt) + res = self.matmul(v2.T, v1) + assert_equal(res, tgt) + + # boolean type + vec = np.array([True, True], dtype='?').reshape(1, -1) + res = self.matmul(vec[:, 0], vec) + assert_equal(res, True) + + def test_vector_vector_values(self): + vec1 = np.array([1, 2]) + vec2 = np.array([3, 4]).reshape(-1, 1) + tgt1 = np.array([11]) + tgt2 = np.array([[3, 6], [4, 8]]) + for dt in self.types[1:]: + v1 = vec1.astype(dt) + v2 = vec2.astype(dt) + res = self.matmul(v1, v2) + assert_equal(res, tgt1) + # no broadcast, we must make v1 into a 2d ndarray + res = self.matmul(v2, v1.reshape(1, -1)) + assert_equal(res, tgt2) + + # boolean type + vec = np.array([True, True], dtype='?') + res = self.matmul(vec, vec) + assert_equal(res, True) + + def test_vector_matrix_values(self): + vec = np.array([1, 2]) + mat1 = np.array([[1, 2], [3, 4]]) + mat2 = np.stack([mat1]*2, axis=0) + tgt1 = np.array([7, 10]) + tgt2 = np.stack([tgt1]*2, axis=0) + for dt in self.types[1:]: + v = vec.astype(dt) + m1 = mat1.astype(dt) + m2 = mat2.astype(dt) + res = self.matmul(v, m1) + assert_equal(res, tgt1) + res = self.matmul(v, m2) + assert_equal(res, tgt2) + + # boolean type + vec = np.array([True, False]) + mat1 = np.array([[True, False], [False, True]]) + mat2 = np.stack([mat1]*2, axis=0) + tgt1 = np.array([True, False]) + tgt2 = np.stack([tgt1]*2, axis=0) + + res = self.matmul(vec, mat1) + assert_equal(res, tgt1) + res = self.matmul(vec, mat2) + assert_equal(res, tgt2) + + def test_matrix_vector_values(self): + vec = np.array([1, 2]) + mat1 = np.array([[1, 2], [3, 4]]) + mat2 = np.stack([mat1]*2, axis=0) + tgt1 = np.array([5, 11]) + tgt2 = np.stack([tgt1]*2, axis=0) + for dt in self.types[1:]: + v = vec.astype(dt) + m1 = mat1.astype(dt) + m2 = mat2.astype(dt) + res = self.matmul(m1, v) + assert_equal(res, tgt1) + res = self.matmul(m2, v) + assert_equal(res, tgt2) + + # boolean type + vec = np.array([True, False]) + mat1 = np.array([[True, False], [False, True]]) + mat2 = np.stack([mat1]*2, axis=0) + tgt1 = np.array([True, False]) + tgt2 = np.stack([tgt1]*2, axis=0) + + res = self.matmul(vec, mat1) + assert_equal(res, tgt1) + res = self.matmul(vec, mat2) + assert_equal(res, tgt2) + + def test_matrix_matrix_values(self): + mat1 = np.array([[1, 2], [3, 4]]) + mat2 = np.array([[1, 0], [1, 1]]) + mat12 = np.stack([mat1, mat2], axis=0) + mat21 = np.stack([mat2, mat1], axis=0) + tgt11 = np.array([[7, 10], [15, 22]]) + tgt12 = np.array([[3, 2], [7, 4]]) + tgt21 = np.array([[1, 2], [4, 6]]) + tgt12_21 = np.stack([tgt12, tgt21], axis=0) + tgt11_12 = np.stack((tgt11, tgt12), axis=0) + tgt11_21 = np.stack((tgt11, tgt21), axis=0) + for dt in self.types[1:]: + m1 = mat1.astype(dt) + m2 = mat2.astype(dt) + m12 = mat12.astype(dt) + m21 = mat21.astype(dt) + + # matrix @ matrix + res = self.matmul(m1, m2) + assert_equal(res, tgt12) + res = self.matmul(m2, m1) + assert_equal(res, tgt21) + + # stacked @ matrix + res = self.matmul(m12, m1) + assert_equal(res, tgt11_21) + + # matrix @ stacked + res = self.matmul(m1, m12) + assert_equal(res, tgt11_12) + + # stacked @ stacked + res = self.matmul(m12, m21) + assert_equal(res, tgt12_21) + + # boolean type + m1 = np.array([[1, 1], [0, 0]], dtype=np.bool_) + m2 = np.array([[1, 0], [1, 1]], dtype=np.bool_) + m12 = np.stack([m1, m2], axis=0) + m21 = np.stack([m2, m1], axis=0) + tgt11 = m1 + tgt12 = m1 + tgt21 = np.array([[1, 1], [1, 1]], dtype=np.bool_) + tgt12_21 = np.stack([tgt12, tgt21], axis=0) + tgt11_12 = np.stack((tgt11, tgt12), axis=0) + tgt11_21 = np.stack((tgt11, tgt21), axis=0) + + # matrix @ matrix + res = self.matmul(m1, m2) + assert_equal(res, tgt12) + res = self.matmul(m2, m1) + assert_equal(res, tgt21) + + # stacked @ matrix + res = self.matmul(m12, m1) + assert_equal(res, tgt11_21) + + # matrix @ stacked + res = self.matmul(m1, m12) + assert_equal(res, tgt11_12) + + # stacked @ stacked + res = self.matmul(m12, m21) + assert_equal(res, tgt12_21) + + +class TestMatmul(MatmulCommon): + matmul = np.matmul + + def test_out_arg(self): + a = np.ones((5, 2), dtype=float) + b = np.array([[1, 3], [5, 7]], dtype=float) + tgt = np.dot(a, b) + + # test as positional argument + msg = "out positional argument" + out = np.zeros((5, 2), dtype=float) + self.matmul(a, b, out) + assert_array_equal(out, tgt, err_msg=msg) + + # test as keyword argument + msg = "out keyword argument" + out = np.zeros((5, 2), dtype=float) + self.matmul(a, b, out=out) + assert_array_equal(out, tgt, err_msg=msg) + + # test out with not allowed type cast (safe casting) + msg = "Cannot cast ufunc .* output" + out = np.zeros((5, 2), dtype=np.int32) + assert_raises_regex(TypeError, msg, self.matmul, a, b, out=out) + + # test out with type upcast to complex + out = np.zeros((5, 2), dtype=np.complex128) + c = self.matmul(a, b, out=out) + assert_(c is out) + with suppress_warnings() as sup: + sup.filter(np.ComplexWarning, '') + c = c.astype(tgt.dtype) + assert_array_equal(c, tgt) + + def test_out_contiguous(self): + a = np.ones((5, 2), dtype=float) + b = np.array([[1, 3], [5, 7]], dtype=float) + v = np.array([1, 3], dtype=float) + tgt = np.dot(a, b) + tgt_mv = np.dot(a, v) + + # test out non-contiguous + out = np.ones((5, 2, 2), dtype=float) + c = self.matmul(a, b, out=out[..., 0]) + assert c.base is out + assert_array_equal(c, tgt) + c = self.matmul(a, v, out=out[:, 0, 0]) + assert_array_equal(c, tgt_mv) + c = self.matmul(v, a.T, out=out[:, 0, 0]) + assert_array_equal(c, tgt_mv) + + # test out contiguous in only last dim + out = np.ones((10, 2), dtype=float) + c = self.matmul(a, b, out=out[::2, :]) + assert_array_equal(c, tgt) + + # test transposes of out, args + out = np.ones((5, 2), dtype=float) + c = self.matmul(b.T, a.T, out=out.T) + assert_array_equal(out, tgt) + + m1 = np.arange(15.).reshape(5, 3) + m2 = np.arange(21.).reshape(3, 7) + m3 = np.arange(30.).reshape(5, 6)[:, ::2] # non-contiguous + vc = np.arange(10.) + vr = np.arange(6.) + m0 = np.zeros((3, 0)) + @pytest.mark.parametrize('args', ( + # matrix-matrix + (m1, m2), (m2.T, m1.T), (m2.T.copy(), m1.T), (m2.T, m1.T.copy()), + # matrix-matrix-transpose, contiguous and non + (m1, m1.T), (m1.T, m1), (m1, m3.T), (m3, m1.T), + (m3, m3.T), (m3.T, m3), + # matrix-matrix non-contiguous + (m3, m2), (m2.T, m3.T), (m2.T.copy(), m3.T), + # vector-matrix, matrix-vector, contiguous + (m1, vr[:3]), (vc[:5], m1), (m1.T, vc[:5]), (vr[:3], m1.T), + # vector-matrix, matrix-vector, vector non-contiguous + (m1, vr[::2]), (vc[::2], m1), (m1.T, vc[::2]), (vr[::2], m1.T), + # vector-matrix, matrix-vector, matrix non-contiguous + (m3, vr[:3]), (vc[:5], m3), (m3.T, vc[:5]), (vr[:3], m3.T), + # vector-matrix, matrix-vector, both non-contiguous + (m3, vr[::2]), (vc[::2], m3), (m3.T, vc[::2]), (vr[::2], m3.T), + # size == 0 + (m0, m0.T), (m0.T, m0), (m1, m0), (m0.T, m1.T), + )) + def test_dot_equivalent(self, args): + r1 = np.matmul(*args) + r2 = np.dot(*args) + assert_equal(r1, r2) + + r3 = np.matmul(args[0].copy(), args[1].copy()) + assert_equal(r1, r3) + + def test_matmul_object(self): + import fractions + + f = np.vectorize(fractions.Fraction) + def random_ints(): + return np.random.randint(1, 1000, size=(10, 3, 3)) + M1 = f(random_ints(), random_ints()) + M2 = f(random_ints(), random_ints()) + + M3 = self.matmul(M1, M2) + + [N1, N2, N3] = [a.astype(float) for a in [M1, M2, M3]] + + assert_allclose(N3, self.matmul(N1, N2)) + + def test_matmul_object_type_scalar(self): + from fractions import Fraction as F + v = np.array([F(2,3), F(5,7)]) + res = self.matmul(v, v) + assert_(type(res) is F) + + def test_matmul_empty(self): + a = np.empty((3, 0), dtype=object) + b = np.empty((0, 3), dtype=object) + c = np.zeros((3, 3)) + assert_array_equal(np.matmul(a, b), c) + + def test_matmul_exception_multiply(self): + # test that matmul fails if `__mul__` is missing + class add_not_multiply(): + def __add__(self, other): + return self + a = np.full((3,3), add_not_multiply()) + with assert_raises(TypeError): + b = np.matmul(a, a) + + def test_matmul_exception_add(self): + # test that matmul fails if `__add__` is missing + class multiply_not_add(): + def __mul__(self, other): + return self + a = np.full((3,3), multiply_not_add()) + with assert_raises(TypeError): + b = np.matmul(a, a) + + def test_matmul_bool(self): + # gh-14439 + a = np.array([[1, 0],[1, 1]], dtype=bool) + assert np.max(a.view(np.uint8)) == 1 + b = np.matmul(a, a) + # matmul with boolean output should always be 0, 1 + assert np.max(b.view(np.uint8)) == 1 + + rg = np.random.default_rng(np.random.PCG64(43)) + d = rg.integers(2, size=4*5, dtype=np.int8) + d = d.reshape(4, 5) > 0 + out1 = np.matmul(d, d.reshape(5, 4)) + out2 = np.dot(d, d.reshape(5, 4)) + assert_equal(out1, out2) + + c = np.matmul(np.zeros((2, 0), dtype=bool), np.zeros(0, dtype=bool)) + assert not np.any(c) + + +class TestMatmulOperator(MatmulCommon): + import operator + matmul = operator.matmul + + def test_array_priority_override(self): + + class A: + __array_priority__ = 1000 + + def __matmul__(self, other): + return "A" + + def __rmatmul__(self, other): + return "A" + + a = A() + b = np.ones(2) + assert_equal(self.matmul(a, b), "A") + assert_equal(self.matmul(b, a), "A") + + def test_matmul_raises(self): + assert_raises(TypeError, self.matmul, np.int8(5), np.int8(5)) + assert_raises(TypeError, self.matmul, np.void(b'abc'), np.void(b'abc')) + assert_raises(ValueError, self.matmul, np.arange(10), np.void(b'abc')) + +def test_matmul_inplace(): + # It would be nice to support in-place matmul eventually, but for now + # we don't have a working implementation, so better just to error out + # and nudge people to writing "a = a @ b". + a = np.eye(3) + b = np.eye(3) + assert_raises(TypeError, a.__imatmul__, b) + import operator + assert_raises(TypeError, operator.imatmul, a, b) + assert_raises(TypeError, exec, "a @= b", globals(), locals()) + +def test_matmul_axes(): + a = np.arange(3*4*5).reshape(3, 4, 5) + c = np.matmul(a, a, axes=[(-2, -1), (-1, -2), (1, 2)]) + assert c.shape == (3, 4, 4) + d = np.matmul(a, a, axes=[(-2, -1), (-1, -2), (0, 1)]) + assert d.shape == (4, 4, 3) + e = np.swapaxes(d, 0, 2) + assert_array_equal(e, c) + f = np.matmul(a, np.arange(3), axes=[(1, 0), (0), (0)]) + assert f.shape == (4, 5) + + +class TestInner: + + def test_inner_type_mismatch(self): + c = 1. + A = np.array((1,1), dtype='i,i') + + assert_raises(TypeError, np.inner, c, A) + assert_raises(TypeError, np.inner, A, c) + + def test_inner_scalar_and_vector(self): + for dt in np.typecodes['AllInteger'] + np.typecodes['AllFloat'] + '?': + sca = np.array(3, dtype=dt)[()] + vec = np.array([1, 2], dtype=dt) + desired = np.array([3, 6], dtype=dt) + assert_equal(np.inner(vec, sca), desired) + assert_equal(np.inner(sca, vec), desired) + + def test_vecself(self): + # Ticket 844. + # Inner product of a vector with itself segfaults or give + # meaningless result + a = np.zeros(shape=(1, 80), dtype=np.float64) + p = np.inner(a, a) + assert_almost_equal(p, 0, decimal=14) + + def test_inner_product_with_various_contiguities(self): + # github issue 6532 + for dt in np.typecodes['AllInteger'] + np.typecodes['AllFloat'] + '?': + # check an inner product involving a matrix transpose + A = np.array([[1, 2], [3, 4]], dtype=dt) + B = np.array([[1, 3], [2, 4]], dtype=dt) + C = np.array([1, 1], dtype=dt) + desired = np.array([4, 6], dtype=dt) + assert_equal(np.inner(A.T, C), desired) + assert_equal(np.inner(C, A.T), desired) + assert_equal(np.inner(B, C), desired) + assert_equal(np.inner(C, B), desired) + # check a matrix product + desired = np.array([[7, 10], [15, 22]], dtype=dt) + assert_equal(np.inner(A, B), desired) + # check the syrk vs. gemm paths + desired = np.array([[5, 11], [11, 25]], dtype=dt) + assert_equal(np.inner(A, A), desired) + assert_equal(np.inner(A, A.copy()), desired) + # check an inner product involving an aliased and reversed view + a = np.arange(5).astype(dt) + b = a[::-1] + desired = np.array(10, dtype=dt).item() + assert_equal(np.inner(b, a), desired) + + def test_3d_tensor(self): + for dt in np.typecodes['AllInteger'] + np.typecodes['AllFloat'] + '?': + a = np.arange(24).reshape(2,3,4).astype(dt) + b = np.arange(24, 48).reshape(2,3,4).astype(dt) + desired = np.array( + [[[[ 158, 182, 206], + [ 230, 254, 278]], + + [[ 566, 654, 742], + [ 830, 918, 1006]], + + [[ 974, 1126, 1278], + [1430, 1582, 1734]]], + + [[[1382, 1598, 1814], + [2030, 2246, 2462]], + + [[1790, 2070, 2350], + [2630, 2910, 3190]], + + [[2198, 2542, 2886], + [3230, 3574, 3918]]]], + dtype=dt + ) + assert_equal(np.inner(a, b), desired) + assert_equal(np.inner(b, a).transpose(2,3,0,1), desired) + + +class TestAlen: + def test_basic(self): + with pytest.warns(DeprecationWarning): + m = np.array([1, 2, 3]) + assert_equal(np.alen(m), 3) + + m = np.array([[1, 2, 3], [4, 5, 7]]) + assert_equal(np.alen(m), 2) + + m = [1, 2, 3] + assert_equal(np.alen(m), 3) + + m = [[1, 2, 3], [4, 5, 7]] + assert_equal(np.alen(m), 2) + + def test_singleton(self): + with pytest.warns(DeprecationWarning): + assert_equal(np.alen(5), 1) + + +class TestChoose: + def setup(self): + self.x = 2*np.ones((3,), dtype=int) + self.y = 3*np.ones((3,), dtype=int) + self.x2 = 2*np.ones((2, 3), dtype=int) + self.y2 = 3*np.ones((2, 3), dtype=int) + self.ind = [0, 0, 1] + + def test_basic(self): + A = np.choose(self.ind, (self.x, self.y)) + assert_equal(A, [2, 2, 3]) + + def test_broadcast1(self): + A = np.choose(self.ind, (self.x2, self.y2)) + assert_equal(A, [[2, 2, 3], [2, 2, 3]]) + + def test_broadcast2(self): + A = np.choose(self.ind, (self.x, self.y2)) + assert_equal(A, [[2, 2, 3], [2, 2, 3]]) + + @pytest.mark.parametrize("ops", + [(1000, np.array([1], dtype=np.uint8)), + (-1, np.array([1], dtype=np.uint8)), + (1., np.float32(3)), + (1., np.array([3], dtype=np.float32))],) + def test_output_dtype(self, ops): + expected_dt = np.result_type(*ops) + assert(np.choose([0], ops).dtype == expected_dt) + + +class TestRepeat: + def setup(self): + self.m = np.array([1, 2, 3, 4, 5, 6]) + self.m_rect = self.m.reshape((2, 3)) + + def test_basic(self): + A = np.repeat(self.m, [1, 3, 2, 1, 1, 2]) + assert_equal(A, [1, 2, 2, 2, 3, + 3, 4, 5, 6, 6]) + + def test_broadcast1(self): + A = np.repeat(self.m, 2) + assert_equal(A, [1, 1, 2, 2, 3, 3, + 4, 4, 5, 5, 6, 6]) + + def test_axis_spec(self): + A = np.repeat(self.m_rect, [2, 1], axis=0) + assert_equal(A, [[1, 2, 3], + [1, 2, 3], + [4, 5, 6]]) + + A = np.repeat(self.m_rect, [1, 3, 2], axis=1) + assert_equal(A, [[1, 2, 2, 2, 3, 3], + [4, 5, 5, 5, 6, 6]]) + + def test_broadcast2(self): + A = np.repeat(self.m_rect, 2, axis=0) + assert_equal(A, [[1, 2, 3], + [1, 2, 3], + [4, 5, 6], + [4, 5, 6]]) + + A = np.repeat(self.m_rect, 2, axis=1) + assert_equal(A, [[1, 1, 2, 2, 3, 3], + [4, 4, 5, 5, 6, 6]]) + + +# TODO: test for multidimensional +NEIGH_MODE = {'zero': 0, 'one': 1, 'constant': 2, 'circular': 3, 'mirror': 4} + + +@pytest.mark.parametrize('dt', [float, Decimal], ids=['float', 'object']) +class TestNeighborhoodIter: + # Simple, 2d tests + def test_simple2d(self, dt): + # Test zero and one padding for simple data type + x = np.array([[0, 1], [2, 3]], dtype=dt) + r = [np.array([[0, 0, 0], [0, 0, 1]], dtype=dt), + np.array([[0, 0, 0], [0, 1, 0]], dtype=dt), + np.array([[0, 0, 1], [0, 2, 3]], dtype=dt), + np.array([[0, 1, 0], [2, 3, 0]], dtype=dt)] + l = _multiarray_tests.test_neighborhood_iterator( + x, [-1, 0, -1, 1], x[0], NEIGH_MODE['zero']) + assert_array_equal(l, r) + + r = [np.array([[1, 1, 1], [1, 0, 1]], dtype=dt), + np.array([[1, 1, 1], [0, 1, 1]], dtype=dt), + np.array([[1, 0, 1], [1, 2, 3]], dtype=dt), + np.array([[0, 1, 1], [2, 3, 1]], dtype=dt)] + l = _multiarray_tests.test_neighborhood_iterator( + x, [-1, 0, -1, 1], x[0], NEIGH_MODE['one']) + assert_array_equal(l, r) + + r = [np.array([[4, 4, 4], [4, 0, 1]], dtype=dt), + np.array([[4, 4, 4], [0, 1, 4]], dtype=dt), + np.array([[4, 0, 1], [4, 2, 3]], dtype=dt), + np.array([[0, 1, 4], [2, 3, 4]], dtype=dt)] + l = _multiarray_tests.test_neighborhood_iterator( + x, [-1, 0, -1, 1], 4, NEIGH_MODE['constant']) + assert_array_equal(l, r) + + def test_mirror2d(self, dt): + x = np.array([[0, 1], [2, 3]], dtype=dt) + r = [np.array([[0, 0, 1], [0, 0, 1]], dtype=dt), + np.array([[0, 1, 1], [0, 1, 1]], dtype=dt), + np.array([[0, 0, 1], [2, 2, 3]], dtype=dt), + np.array([[0, 1, 1], [2, 3, 3]], dtype=dt)] + l = _multiarray_tests.test_neighborhood_iterator( + x, [-1, 0, -1, 1], x[0], NEIGH_MODE['mirror']) + assert_array_equal(l, r) + + # Simple, 1d tests + def test_simple(self, dt): + # Test padding with constant values + x = np.linspace(1, 5, 5).astype(dt) + r = [[0, 1, 2], [1, 2, 3], [2, 3, 4], [3, 4, 5], [4, 5, 0]] + l = _multiarray_tests.test_neighborhood_iterator( + x, [-1, 1], x[0], NEIGH_MODE['zero']) + assert_array_equal(l, r) + + r = [[1, 1, 2], [1, 2, 3], [2, 3, 4], [3, 4, 5], [4, 5, 1]] + l = _multiarray_tests.test_neighborhood_iterator( + x, [-1, 1], x[0], NEIGH_MODE['one']) + assert_array_equal(l, r) + + r = [[x[4], 1, 2], [1, 2, 3], [2, 3, 4], [3, 4, 5], [4, 5, x[4]]] + l = _multiarray_tests.test_neighborhood_iterator( + x, [-1, 1], x[4], NEIGH_MODE['constant']) + assert_array_equal(l, r) + + # Test mirror modes + def test_mirror(self, dt): + x = np.linspace(1, 5, 5).astype(dt) + r = np.array([[2, 1, 1, 2, 3], [1, 1, 2, 3, 4], [1, 2, 3, 4, 5], + [2, 3, 4, 5, 5], [3, 4, 5, 5, 4]], dtype=dt) + l = _multiarray_tests.test_neighborhood_iterator( + x, [-2, 2], x[1], NEIGH_MODE['mirror']) + assert_([i.dtype == dt for i in l]) + assert_array_equal(l, r) + + # Circular mode + def test_circular(self, dt): + x = np.linspace(1, 5, 5).astype(dt) + r = np.array([[4, 5, 1, 2, 3], [5, 1, 2, 3, 4], [1, 2, 3, 4, 5], + [2, 3, 4, 5, 1], [3, 4, 5, 1, 2]], dtype=dt) + l = _multiarray_tests.test_neighborhood_iterator( + x, [-2, 2], x[0], NEIGH_MODE['circular']) + assert_array_equal(l, r) + + +# Test stacking neighborhood iterators +class TestStackedNeighborhoodIter: + # Simple, 1d test: stacking 2 constant-padded neigh iterators + def test_simple_const(self): + dt = np.float64 + # Test zero and one padding for simple data type + x = np.array([1, 2, 3], dtype=dt) + r = [np.array([0], dtype=dt), + np.array([0], dtype=dt), + np.array([1], dtype=dt), + np.array([2], dtype=dt), + np.array([3], dtype=dt), + np.array([0], dtype=dt), + np.array([0], dtype=dt)] + l = _multiarray_tests.test_neighborhood_iterator_oob( + x, [-2, 4], NEIGH_MODE['zero'], [0, 0], NEIGH_MODE['zero']) + assert_array_equal(l, r) + + r = [np.array([1, 0, 1], dtype=dt), + np.array([0, 1, 2], dtype=dt), + np.array([1, 2, 3], dtype=dt), + np.array([2, 3, 0], dtype=dt), + np.array([3, 0, 1], dtype=dt)] + l = _multiarray_tests.test_neighborhood_iterator_oob( + x, [-1, 3], NEIGH_MODE['zero'], [-1, 1], NEIGH_MODE['one']) + assert_array_equal(l, r) + + # 2nd simple, 1d test: stacking 2 neigh iterators, mixing const padding and + # mirror padding + def test_simple_mirror(self): + dt = np.float64 + # Stacking zero on top of mirror + x = np.array([1, 2, 3], dtype=dt) + r = [np.array([0, 1, 1], dtype=dt), + np.array([1, 1, 2], dtype=dt), + np.array([1, 2, 3], dtype=dt), + np.array([2, 3, 3], dtype=dt), + np.array([3, 3, 0], dtype=dt)] + l = _multiarray_tests.test_neighborhood_iterator_oob( + x, [-1, 3], NEIGH_MODE['mirror'], [-1, 1], NEIGH_MODE['zero']) + assert_array_equal(l, r) + + # Stacking mirror on top of zero + x = np.array([1, 2, 3], dtype=dt) + r = [np.array([1, 0, 0], dtype=dt), + np.array([0, 0, 1], dtype=dt), + np.array([0, 1, 2], dtype=dt), + np.array([1, 2, 3], dtype=dt), + np.array([2, 3, 0], dtype=dt)] + l = _multiarray_tests.test_neighborhood_iterator_oob( + x, [-1, 3], NEIGH_MODE['zero'], [-2, 0], NEIGH_MODE['mirror']) + assert_array_equal(l, r) + + # Stacking mirror on top of zero: 2nd + x = np.array([1, 2, 3], dtype=dt) + r = [np.array([0, 1, 2], dtype=dt), + np.array([1, 2, 3], dtype=dt), + np.array([2, 3, 0], dtype=dt), + np.array([3, 0, 0], dtype=dt), + np.array([0, 0, 3], dtype=dt)] + l = _multiarray_tests.test_neighborhood_iterator_oob( + x, [-1, 3], NEIGH_MODE['zero'], [0, 2], NEIGH_MODE['mirror']) + assert_array_equal(l, r) + + # Stacking mirror on top of zero: 3rd + x = np.array([1, 2, 3], dtype=dt) + r = [np.array([1, 0, 0, 1, 2], dtype=dt), + np.array([0, 0, 1, 2, 3], dtype=dt), + np.array([0, 1, 2, 3, 0], dtype=dt), + np.array([1, 2, 3, 0, 0], dtype=dt), + np.array([2, 3, 0, 0, 3], dtype=dt)] + l = _multiarray_tests.test_neighborhood_iterator_oob( + x, [-1, 3], NEIGH_MODE['zero'], [-2, 2], NEIGH_MODE['mirror']) + assert_array_equal(l, r) + + # 3rd simple, 1d test: stacking 2 neigh iterators, mixing const padding and + # circular padding + def test_simple_circular(self): + dt = np.float64 + # Stacking zero on top of mirror + x = np.array([1, 2, 3], dtype=dt) + r = [np.array([0, 3, 1], dtype=dt), + np.array([3, 1, 2], dtype=dt), + np.array([1, 2, 3], dtype=dt), + np.array([2, 3, 1], dtype=dt), + np.array([3, 1, 0], dtype=dt)] + l = _multiarray_tests.test_neighborhood_iterator_oob( + x, [-1, 3], NEIGH_MODE['circular'], [-1, 1], NEIGH_MODE['zero']) + assert_array_equal(l, r) + + # Stacking mirror on top of zero + x = np.array([1, 2, 3], dtype=dt) + r = [np.array([3, 0, 0], dtype=dt), + np.array([0, 0, 1], dtype=dt), + np.array([0, 1, 2], dtype=dt), + np.array([1, 2, 3], dtype=dt), + np.array([2, 3, 0], dtype=dt)] + l = _multiarray_tests.test_neighborhood_iterator_oob( + x, [-1, 3], NEIGH_MODE['zero'], [-2, 0], NEIGH_MODE['circular']) + assert_array_equal(l, r) + + # Stacking mirror on top of zero: 2nd + x = np.array([1, 2, 3], dtype=dt) + r = [np.array([0, 1, 2], dtype=dt), + np.array([1, 2, 3], dtype=dt), + np.array([2, 3, 0], dtype=dt), + np.array([3, 0, 0], dtype=dt), + np.array([0, 0, 1], dtype=dt)] + l = _multiarray_tests.test_neighborhood_iterator_oob( + x, [-1, 3], NEIGH_MODE['zero'], [0, 2], NEIGH_MODE['circular']) + assert_array_equal(l, r) + + # Stacking mirror on top of zero: 3rd + x = np.array([1, 2, 3], dtype=dt) + r = [np.array([3, 0, 0, 1, 2], dtype=dt), + np.array([0, 0, 1, 2, 3], dtype=dt), + np.array([0, 1, 2, 3, 0], dtype=dt), + np.array([1, 2, 3, 0, 0], dtype=dt), + np.array([2, 3, 0, 0, 1], dtype=dt)] + l = _multiarray_tests.test_neighborhood_iterator_oob( + x, [-1, 3], NEIGH_MODE['zero'], [-2, 2], NEIGH_MODE['circular']) + assert_array_equal(l, r) + + # 4th simple, 1d test: stacking 2 neigh iterators, but with lower iterator + # being strictly within the array + def test_simple_strict_within(self): + dt = np.float64 + # Stacking zero on top of zero, first neighborhood strictly inside the + # array + x = np.array([1, 2, 3], dtype=dt) + r = [np.array([1, 2, 3, 0], dtype=dt)] + l = _multiarray_tests.test_neighborhood_iterator_oob( + x, [1, 1], NEIGH_MODE['zero'], [-1, 2], NEIGH_MODE['zero']) + assert_array_equal(l, r) + + # Stacking mirror on top of zero, first neighborhood strictly inside the + # array + x = np.array([1, 2, 3], dtype=dt) + r = [np.array([1, 2, 3, 3], dtype=dt)] + l = _multiarray_tests.test_neighborhood_iterator_oob( + x, [1, 1], NEIGH_MODE['zero'], [-1, 2], NEIGH_MODE['mirror']) + assert_array_equal(l, r) + + # Stacking mirror on top of zero, first neighborhood strictly inside the + # array + x = np.array([1, 2, 3], dtype=dt) + r = [np.array([1, 2, 3, 1], dtype=dt)] + l = _multiarray_tests.test_neighborhood_iterator_oob( + x, [1, 1], NEIGH_MODE['zero'], [-1, 2], NEIGH_MODE['circular']) + assert_array_equal(l, r) + +class TestWarnings: + + def test_complex_warning(self): + x = np.array([1, 2]) + y = np.array([1-2j, 1+2j]) + + with warnings.catch_warnings(): + warnings.simplefilter("error", np.ComplexWarning) + assert_raises(np.ComplexWarning, x.__setitem__, slice(None), y) + assert_equal(x, [1, 2]) + + +class TestMinScalarType: + + def test_usigned_shortshort(self): + dt = np.min_scalar_type(2**8-1) + wanted = np.dtype('uint8') + assert_equal(wanted, dt) + + def test_usigned_short(self): + dt = np.min_scalar_type(2**16-1) + wanted = np.dtype('uint16') + assert_equal(wanted, dt) + + def test_usigned_int(self): + dt = np.min_scalar_type(2**32-1) + wanted = np.dtype('uint32') + assert_equal(wanted, dt) + + def test_usigned_longlong(self): + dt = np.min_scalar_type(2**63-1) + wanted = np.dtype('uint64') + assert_equal(wanted, dt) + + def test_object(self): + dt = np.min_scalar_type(2**64) + wanted = np.dtype('O') + assert_equal(wanted, dt) + + +from numpy.core._internal import _dtype_from_pep3118 + + +class TestPEP3118Dtype: + def _check(self, spec, wanted): + dt = np.dtype(wanted) + actual = _dtype_from_pep3118(spec) + assert_equal(actual, dt, + err_msg="spec %r != dtype %r" % (spec, wanted)) + + def test_native_padding(self): + align = np.dtype('i').alignment + for j in range(8): + if j == 0: + s = 'bi' + else: + s = 'b%dxi' % j + self._check('@'+s, {'f0': ('i1', 0), + 'f1': ('i', align*(1 + j//align))}) + self._check('='+s, {'f0': ('i1', 0), + 'f1': ('i', 1+j)}) + + def test_native_padding_2(self): + # Native padding should work also for structs and sub-arrays + self._check('x3T{xi}', {'f0': (({'f0': ('i', 4)}, (3,)), 4)}) + self._check('^x3T{xi}', {'f0': (({'f0': ('i', 1)}, (3,)), 1)}) + + def test_trailing_padding(self): + # Trailing padding should be included, *and*, the item size + # should match the alignment if in aligned mode + align = np.dtype('i').alignment + size = np.dtype('i').itemsize + + def aligned(n): + return align*(1 + (n-1)//align) + + base = dict(formats=['i'], names=['f0']) + + self._check('ix', dict(itemsize=aligned(size + 1), **base)) + self._check('ixx', dict(itemsize=aligned(size + 2), **base)) + self._check('ixxx', dict(itemsize=aligned(size + 3), **base)) + self._check('ixxxx', dict(itemsize=aligned(size + 4), **base)) + self._check('i7x', dict(itemsize=aligned(size + 7), **base)) + + self._check('^ix', dict(itemsize=size + 1, **base)) + self._check('^ixx', dict(itemsize=size + 2, **base)) + self._check('^ixxx', dict(itemsize=size + 3, **base)) + self._check('^ixxxx', dict(itemsize=size + 4, **base)) + self._check('^i7x', dict(itemsize=size + 7, **base)) + + def test_native_padding_3(self): + dt = np.dtype( + [('a', 'b'), ('b', 'i'), + ('sub', np.dtype('b,i')), ('c', 'i')], + align=True) + self._check("T{b:a:xxxi:b:T{b:f0:=i:f1:}:sub:xxxi:c:}", dt) + + dt = np.dtype( + [('a', 'b'), ('b', 'i'), ('c', 'b'), ('d', 'b'), + ('e', 'b'), ('sub', np.dtype('b,i', align=True))]) + self._check("T{b:a:=i:b:b:c:b:d:b:e:T{b:f0:xxxi:f1:}:sub:}", dt) + + def test_padding_with_array_inside_struct(self): + dt = np.dtype( + [('a', 'b'), ('b', 'i'), ('c', 'b', (3,)), + ('d', 'i')], + align=True) + self._check("T{b:a:xxxi:b:3b:c:xi:d:}", dt) + + def test_byteorder_inside_struct(self): + # The byte order after @T{=i} should be '=', not '@'. + # Check this by noting the absence of native alignment. + self._check('@T{^i}xi', {'f0': ({'f0': ('i', 0)}, 0), + 'f1': ('i', 5)}) + + def test_intra_padding(self): + # Natively aligned sub-arrays may require some internal padding + align = np.dtype('i').alignment + size = np.dtype('i').itemsize + + def aligned(n): + return (align*(1 + (n-1)//align)) + + self._check('(3)T{ix}', (dict( + names=['f0'], + formats=['i'], + offsets=[0], + itemsize=aligned(size + 1) + ), (3,))) + + def test_char_vs_string(self): + dt = np.dtype('c') + self._check('c', dt) + + dt = np.dtype([('f0', 'S1', (4,)), ('f1', 'S4')]) + self._check('4c4s', dt) + + def test_field_order(self): + # gh-9053 - previously, we relied on dictionary key order + self._check("(0)I:a:f:b:", [('a', 'I', (0,)), ('b', 'f')]) + self._check("(0)I:b:f:a:", [('b', 'I', (0,)), ('a', 'f')]) + + def test_unnamed_fields(self): + self._check('ii', [('f0', 'i'), ('f1', 'i')]) + self._check('ii:f0:', [('f1', 'i'), ('f0', 'i')]) + + self._check('i', 'i') + self._check('i:f0:', [('f0', 'i')]) + + +class TestNewBufferProtocol: + """ Test PEP3118 buffers """ + + def _check_roundtrip(self, obj): + obj = np.asarray(obj) + x = memoryview(obj) + y = np.asarray(x) + y2 = np.array(x) + assert_(not y.flags.owndata) + assert_(y2.flags.owndata) + + assert_equal(y.dtype, obj.dtype) + assert_equal(y.shape, obj.shape) + assert_array_equal(obj, y) + + assert_equal(y2.dtype, obj.dtype) + assert_equal(y2.shape, obj.shape) + assert_array_equal(obj, y2) + + def test_roundtrip(self): + x = np.array([1, 2, 3, 4, 5], dtype='i4') + self._check_roundtrip(x) + + x = np.array([[1, 2], [3, 4]], dtype=np.float64) + self._check_roundtrip(x) + + x = np.zeros((3, 3, 3), dtype=np.float32)[:, 0,:] + self._check_roundtrip(x) + + dt = [('a', 'b'), + ('b', 'h'), + ('c', 'i'), + ('d', 'l'), + ('dx', 'q'), + ('e', 'B'), + ('f', 'H'), + ('g', 'I'), + ('h', 'L'), + ('hx', 'Q'), + ('i', np.single), + ('j', np.double), + ('k', np.longdouble), + ('ix', np.csingle), + ('jx', np.cdouble), + ('kx', np.clongdouble), + ('l', 'S4'), + ('m', 'U4'), + ('n', 'V3'), + ('o', '?'), + ('p', np.half), + ] + x = np.array( + [(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + b'aaaa', 'bbbb', b'xxx', True, 1.0)], + dtype=dt) + self._check_roundtrip(x) + + x = np.array(([[1, 2], [3, 4]],), dtype=[('a', (int, (2, 2)))]) + self._check_roundtrip(x) + + x = np.array([1, 2, 3], dtype='>i2') + self._check_roundtrip(x) + + x = np.array([1, 2, 3], dtype='') + x = np.zeros(4, dtype=dt) + self._check_roundtrip(x) + + def test_roundtrip_scalar(self): + # Issue #4015. + self._check_roundtrip(0) + + def test_invalid_buffer_format(self): + # datetime64 cannot be used fully in a buffer yet + # Should be fixed in the next Numpy major release + dt = np.dtype([('a', 'uint16'), ('b', 'M8[s]')]) + a = np.empty(3, dt) + assert_raises((ValueError, BufferError), memoryview, a) + assert_raises((ValueError, BufferError), memoryview, np.array((3), 'M8[D]')) + + def test_export_simple_1d(self): + x = np.array([1, 2, 3, 4, 5], dtype='i') + y = memoryview(x) + assert_equal(y.format, 'i') + assert_equal(y.shape, (5,)) + assert_equal(y.ndim, 1) + assert_equal(y.strides, (4,)) + assert_equal(y.suboffsets, ()) + assert_equal(y.itemsize, 4) + + def test_export_simple_nd(self): + x = np.array([[1, 2], [3, 4]], dtype=np.float64) + y = memoryview(x) + assert_equal(y.format, 'd') + assert_equal(y.shape, (2, 2)) + assert_equal(y.ndim, 2) + assert_equal(y.strides, (16, 8)) + assert_equal(y.suboffsets, ()) + assert_equal(y.itemsize, 8) + + def test_export_discontiguous(self): + x = np.zeros((3, 3, 3), dtype=np.float32)[:, 0,:] + y = memoryview(x) + assert_equal(y.format, 'f') + assert_equal(y.shape, (3, 3)) + assert_equal(y.ndim, 2) + assert_equal(y.strides, (36, 4)) + assert_equal(y.suboffsets, ()) + assert_equal(y.itemsize, 4) + + def test_export_record(self): + dt = [('a', 'b'), + ('b', 'h'), + ('c', 'i'), + ('d', 'l'), + ('dx', 'q'), + ('e', 'B'), + ('f', 'H'), + ('g', 'I'), + ('h', 'L'), + ('hx', 'Q'), + ('i', np.single), + ('j', np.double), + ('k', np.longdouble), + ('ix', np.csingle), + ('jx', np.cdouble), + ('kx', np.clongdouble), + ('l', 'S4'), + ('m', 'U4'), + ('n', 'V3'), + ('o', '?'), + ('p', np.half), + ] + x = np.array( + [(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + b'aaaa', 'bbbb', b' ', True, 1.0)], + dtype=dt) + y = memoryview(x) + assert_equal(y.shape, (1,)) + assert_equal(y.ndim, 1) + assert_equal(y.suboffsets, ()) + + sz = sum([np.dtype(b).itemsize for a, b in dt]) + if np.dtype('l').itemsize == 4: + assert_equal(y.format, 'T{b:a:=h:b:i:c:l:d:q:dx:B:e:@H:f:=I:g:L:h:Q:hx:f:i:d:j:^g:k:=Zf:ix:Zd:jx:^Zg:kx:4s:l:=4w:m:3x:n:?:o:@e:p:}') + else: + assert_equal(y.format, 'T{b:a:=h:b:i:c:q:d:q:dx:B:e:@H:f:=I:g:Q:h:Q:hx:f:i:d:j:^g:k:=Zf:ix:Zd:jx:^Zg:kx:4s:l:=4w:m:3x:n:?:o:@e:p:}') + # Cannot test if NPY_RELAXED_STRIDES_CHECKING changes the strides + if not (np.ones(1).strides[0] == np.iinfo(np.intp).max): + assert_equal(y.strides, (sz,)) + assert_equal(y.itemsize, sz) + + def test_export_subarray(self): + x = np.array(([[1, 2], [3, 4]],), dtype=[('a', ('i', (2, 2)))]) + y = memoryview(x) + assert_equal(y.format, 'T{(2,2)i:a:}') + assert_equal(y.shape, ()) + assert_equal(y.ndim, 0) + assert_equal(y.strides, ()) + assert_equal(y.suboffsets, ()) + assert_equal(y.itemsize, 16) + + def test_export_endian(self): + x = np.array([1, 2, 3], dtype='>i') + y = memoryview(x) + if sys.byteorder == 'little': + assert_equal(y.format, '>i') + else: + assert_equal(y.format, 'i') + + x = np.array([1, 2, 3], dtype=' np.array(0, dtype=dt1), "type %s failed" % (dt1,)) + assert_(not 1 < np.array(0, dtype=dt1), "type %s failed" % (dt1,)) + + for dt2 in np.typecodes['AllInteger']: + assert_(np.array(1, dtype=dt1) > np.array(0, dtype=dt2), + "type %s and %s failed" % (dt1, dt2)) + assert_(not np.array(1, dtype=dt1) < np.array(0, dtype=dt2), + "type %s and %s failed" % (dt1, dt2)) + + # Unsigned integers + for dt1 in 'BHILQP': + assert_(-1 < np.array(1, dtype=dt1), "type %s failed" % (dt1,)) + assert_(not -1 > np.array(1, dtype=dt1), "type %s failed" % (dt1,)) + assert_(-1 != np.array(1, dtype=dt1), "type %s failed" % (dt1,)) + + # Unsigned vs signed + for dt2 in 'bhilqp': + assert_(np.array(1, dtype=dt1) > np.array(-1, dtype=dt2), + "type %s and %s failed" % (dt1, dt2)) + assert_(not np.array(1, dtype=dt1) < np.array(-1, dtype=dt2), + "type %s and %s failed" % (dt1, dt2)) + assert_(np.array(1, dtype=dt1) != np.array(-1, dtype=dt2), + "type %s and %s failed" % (dt1, dt2)) + + # Signed integers and floats + for dt1 in 'bhlqp' + np.typecodes['Float']: + assert_(1 > np.array(-1, dtype=dt1), "type %s failed" % (dt1,)) + assert_(not 1 < np.array(-1, dtype=dt1), "type %s failed" % (dt1,)) + assert_(-1 == np.array(-1, dtype=dt1), "type %s failed" % (dt1,)) + + for dt2 in 'bhlqp' + np.typecodes['Float']: + assert_(np.array(1, dtype=dt1) > np.array(-1, dtype=dt2), + "type %s and %s failed" % (dt1, dt2)) + assert_(not np.array(1, dtype=dt1) < np.array(-1, dtype=dt2), + "type %s and %s failed" % (dt1, dt2)) + assert_(np.array(-1, dtype=dt1) == np.array(-1, dtype=dt2), + "type %s and %s failed" % (dt1, dt2)) + + def test_to_bool_scalar(self): + assert_equal(bool(np.array([False])), False) + assert_equal(bool(np.array([True])), True) + assert_equal(bool(np.array([[42]])), True) + assert_raises(ValueError, bool, np.array([1, 2])) + + class NotConvertible: + def __bool__(self): + raise NotImplementedError + + assert_raises(NotImplementedError, bool, np.array(NotConvertible())) + assert_raises(NotImplementedError, bool, np.array([NotConvertible()])) + + self_containing = np.array([None]) + self_containing[0] = self_containing + try: + Error = RecursionError + except NameError: + Error = RuntimeError # python < 3.5 + assert_raises(Error, bool, self_containing) # previously stack overflow + self_containing[0] = None # resolve circular reference + + def test_to_int_scalar(self): + # gh-9972 means that these aren't always the same + int_funcs = (int, lambda x: x.__int__()) + for int_func in int_funcs: + assert_equal(int_func(np.array(0)), 0) + assert_equal(int_func(np.array([1])), 1) + assert_equal(int_func(np.array([[42]])), 42) + assert_raises(TypeError, int_func, np.array([1, 2])) + + # gh-9972 + assert_equal(4, int_func(np.array('4'))) + assert_equal(5, int_func(np.bytes_(b'5'))) + assert_equal(6, int_func(np.unicode_(u'6'))) + + class HasTrunc: + def __trunc__(self): + return 3 + assert_equal(3, int_func(np.array(HasTrunc()))) + assert_equal(3, int_func(np.array([HasTrunc()]))) + + class NotConvertible: + def __int__(self): + raise NotImplementedError + assert_raises(NotImplementedError, + int_func, np.array(NotConvertible())) + assert_raises(NotImplementedError, + int_func, np.array([NotConvertible()])) + + +class TestWhere: + def test_basic(self): + dts = [bool, np.int16, np.int32, np.int64, np.double, np.complex128, + np.longdouble, np.clongdouble] + for dt in dts: + c = np.ones(53, dtype=bool) + assert_equal(np.where( c, dt(0), dt(1)), dt(0)) + assert_equal(np.where(~c, dt(0), dt(1)), dt(1)) + assert_equal(np.where(True, dt(0), dt(1)), dt(0)) + assert_equal(np.where(False, dt(0), dt(1)), dt(1)) + d = np.ones_like(c).astype(dt) + e = np.zeros_like(d) + r = d.astype(dt) + c[7] = False + r[7] = e[7] + assert_equal(np.where(c, e, e), e) + assert_equal(np.where(c, d, e), r) + assert_equal(np.where(c, d, e[0]), r) + assert_equal(np.where(c, d[0], e), r) + assert_equal(np.where(c[::2], d[::2], e[::2]), r[::2]) + assert_equal(np.where(c[1::2], d[1::2], e[1::2]), r[1::2]) + assert_equal(np.where(c[::3], d[::3], e[::3]), r[::3]) + assert_equal(np.where(c[1::3], d[1::3], e[1::3]), r[1::3]) + assert_equal(np.where(c[::-2], d[::-2], e[::-2]), r[::-2]) + assert_equal(np.where(c[::-3], d[::-3], e[::-3]), r[::-3]) + assert_equal(np.where(c[1::-3], d[1::-3], e[1::-3]), r[1::-3]) + + def test_exotic(self): + # object + assert_array_equal(np.where(True, None, None), np.array(None)) + # zero sized + m = np.array([], dtype=bool).reshape(0, 3) + b = np.array([], dtype=np.float64).reshape(0, 3) + assert_array_equal(np.where(m, 0, b), np.array([]).reshape(0, 3)) + + # object cast + d = np.array([-1.34, -0.16, -0.54, -0.31, -0.08, -0.95, 0.000, 0.313, + 0.547, -0.18, 0.876, 0.236, 1.969, 0.310, 0.699, 1.013, + 1.267, 0.229, -1.39, 0.487]) + nan = float('NaN') + e = np.array(['5z', '0l', nan, 'Wz', nan, nan, 'Xq', 'cs', nan, nan, + 'QN', nan, nan, 'Fd', nan, nan, 'kp', nan, '36', 'i1'], + dtype=object) + m = np.array([0, 0, 1, 0, 1, 1, 0, 0, 1, 1, + 0, 1, 1, 0, 1, 1, 0, 1, 0, 0], dtype=bool) + + r = e[:] + r[np.where(m)] = d[np.where(m)] + assert_array_equal(np.where(m, d, e), r) + + r = e[:] + r[np.where(~m)] = d[np.where(~m)] + assert_array_equal(np.where(m, e, d), r) + + assert_array_equal(np.where(m, e, e), e) + + # minimal dtype result with NaN scalar (e.g required by pandas) + d = np.array([1., 2.], dtype=np.float32) + e = float('NaN') + assert_equal(np.where(True, d, e).dtype, np.float32) + e = float('Infinity') + assert_equal(np.where(True, d, e).dtype, np.float32) + e = float('-Infinity') + assert_equal(np.where(True, d, e).dtype, np.float32) + # also check upcast + e = float(1e150) + assert_equal(np.where(True, d, e).dtype, np.float64) + + def test_ndim(self): + c = [True, False] + a = np.zeros((2, 25)) + b = np.ones((2, 25)) + r = np.where(np.array(c)[:,np.newaxis], a, b) + assert_array_equal(r[0], a[0]) + assert_array_equal(r[1], b[0]) + + a = a.T + b = b.T + r = np.where(c, a, b) + assert_array_equal(r[:,0], a[:,0]) + assert_array_equal(r[:,1], b[:,0]) + + def test_dtype_mix(self): + c = np.array([False, True, False, False, False, False, True, False, + False, False, True, False]) + a = np.uint32(1) + b = np.array([5., 0., 3., 2., -1., -4., 0., -10., 10., 1., 0., 3.], + dtype=np.float64) + r = np.array([5., 1., 3., 2., -1., -4., 1., -10., 10., 1., 1., 3.], + dtype=np.float64) + assert_equal(np.where(c, a, b), r) + + a = a.astype(np.float32) + b = b.astype(np.int64) + assert_equal(np.where(c, a, b), r) + + # non bool mask + c = c.astype(int) + c[c != 0] = 34242324 + assert_equal(np.where(c, a, b), r) + # invert + tmpmask = c != 0 + c[c == 0] = 41247212 + c[tmpmask] = 0 + assert_equal(np.where(c, b, a), r) + + def test_foreign(self): + c = np.array([False, True, False, False, False, False, True, False, + False, False, True, False]) + r = np.array([5., 1., 3., 2., -1., -4., 1., -10., 10., 1., 1., 3.], + dtype=np.float64) + a = np.ones(1, dtype='>i4') + b = np.array([5., 0., 3., 2., -1., -4., 0., -10., 10., 1., 0., 3.], + dtype=np.float64) + assert_equal(np.where(c, a, b), r) + + b = b.astype('>f8') + assert_equal(np.where(c, a, b), r) + + a = a.astype('i4') + assert_equal(np.where(c, a, b), r) + + def test_error(self): + c = [True, True] + a = np.ones((4, 5)) + b = np.ones((5, 5)) + assert_raises(ValueError, np.where, c, a, a) + assert_raises(ValueError, np.where, c[0], a, b) + + def test_string(self): + # gh-4778 check strings are properly filled with nulls + a = np.array("abc") + b = np.array("x" * 753) + assert_equal(np.where(True, a, b), "abc") + assert_equal(np.where(False, b, a), "abc") + + # check native datatype sized strings + a = np.array("abcd") + b = np.array("x" * 8) + assert_equal(np.where(True, a, b), "abcd") + assert_equal(np.where(False, b, a), "abcd") + + def test_empty_result(self): + # pass empty where result through an assignment which reads the data of + # empty arrays, error detectable with valgrind, see gh-8922 + x = np.zeros((1, 1)) + ibad = np.vstack(np.where(x == 99.)) + assert_array_equal(ibad, + np.atleast_2d(np.array([[],[]], dtype=np.intp))) + + def test_largedim(self): + # invalid read regression gh-9304 + shape = [10, 2, 3, 4, 5, 6] + np.random.seed(2) + array = np.random.rand(*shape) + + for i in range(10): + benchmark = array.nonzero() + result = array.nonzero() + assert_array_equal(benchmark, result) + + +if not IS_PYPY: + # sys.getsizeof() is not valid on PyPy + class TestSizeOf: + + def test_empty_array(self): + x = np.array([]) + assert_(sys.getsizeof(x) > 0) + + def check_array(self, dtype): + elem_size = dtype(0).itemsize + + for length in [10, 50, 100, 500]: + x = np.arange(length, dtype=dtype) + assert_(sys.getsizeof(x) > length * elem_size) + + def test_array_int32(self): + self.check_array(np.int32) + + def test_array_int64(self): + self.check_array(np.int64) + + def test_array_float32(self): + self.check_array(np.float32) + + def test_array_float64(self): + self.check_array(np.float64) + + def test_view(self): + d = np.ones(100) + assert_(sys.getsizeof(d[...]) < sys.getsizeof(d)) + + def test_reshape(self): + d = np.ones(100) + assert_(sys.getsizeof(d) < sys.getsizeof(d.reshape(100, 1, 1).copy())) + + @_no_tracing + def test_resize(self): + d = np.ones(100) + old = sys.getsizeof(d) + d.resize(50) + assert_(old > sys.getsizeof(d)) + d.resize(150) + assert_(old < sys.getsizeof(d)) + + def test_error(self): + d = np.ones(100) + assert_raises(TypeError, d.__sizeof__, "a") + + +class TestHashing: + + def test_arrays_not_hashable(self): + x = np.ones(3) + assert_raises(TypeError, hash, x) + + def test_collections_hashable(self): + x = np.array([]) + assert_(not isinstance(x, collections.abc.Hashable)) + + +class TestArrayPriority: + # This will go away when __array_priority__ is settled, meanwhile + # it serves to check unintended changes. + op = operator + binary_ops = [ + op.pow, op.add, op.sub, op.mul, op.floordiv, op.truediv, op.mod, + op.and_, op.or_, op.xor, op.lshift, op.rshift, op.mod, op.gt, + op.ge, op.lt, op.le, op.ne, op.eq + ] + + class Foo(np.ndarray): + __array_priority__ = 100. + + def __new__(cls, *args, **kwargs): + return np.array(*args, **kwargs).view(cls) + + class Bar(np.ndarray): + __array_priority__ = 101. + + def __new__(cls, *args, **kwargs): + return np.array(*args, **kwargs).view(cls) + + class Other: + __array_priority__ = 1000. + + def _all(self, other): + return self.__class__() + + __add__ = __radd__ = _all + __sub__ = __rsub__ = _all + __mul__ = __rmul__ = _all + __pow__ = __rpow__ = _all + __div__ = __rdiv__ = _all + __mod__ = __rmod__ = _all + __truediv__ = __rtruediv__ = _all + __floordiv__ = __rfloordiv__ = _all + __and__ = __rand__ = _all + __xor__ = __rxor__ = _all + __or__ = __ror__ = _all + __lshift__ = __rlshift__ = _all + __rshift__ = __rrshift__ = _all + __eq__ = _all + __ne__ = _all + __gt__ = _all + __ge__ = _all + __lt__ = _all + __le__ = _all + + def test_ndarray_subclass(self): + a = np.array([1, 2]) + b = self.Bar([1, 2]) + for f in self.binary_ops: + msg = repr(f) + assert_(isinstance(f(a, b), self.Bar), msg) + assert_(isinstance(f(b, a), self.Bar), msg) + + def test_ndarray_other(self): + a = np.array([1, 2]) + b = self.Other() + for f in self.binary_ops: + msg = repr(f) + assert_(isinstance(f(a, b), self.Other), msg) + assert_(isinstance(f(b, a), self.Other), msg) + + def test_subclass_subclass(self): + a = self.Foo([1, 2]) + b = self.Bar([1, 2]) + for f in self.binary_ops: + msg = repr(f) + assert_(isinstance(f(a, b), self.Bar), msg) + assert_(isinstance(f(b, a), self.Bar), msg) + + def test_subclass_other(self): + a = self.Foo([1, 2]) + b = self.Other() + for f in self.binary_ops: + msg = repr(f) + assert_(isinstance(f(a, b), self.Other), msg) + assert_(isinstance(f(b, a), self.Other), msg) + + +class TestBytestringArrayNonzero: + + def test_empty_bstring_array_is_falsey(self): + assert_(not np.array([''], dtype=str)) + + def test_whitespace_bstring_array_is_falsey(self): + a = np.array(['spam'], dtype=str) + a[0] = ' \0\0' + assert_(not a) + + def test_all_null_bstring_array_is_falsey(self): + a = np.array(['spam'], dtype=str) + a[0] = '\0\0\0\0' + assert_(not a) + + def test_null_inside_bstring_array_is_truthy(self): + a = np.array(['spam'], dtype=str) + a[0] = ' \0 \0' + assert_(a) + + +class TestUnicodeEncoding: + """ + Tests for encoding related bugs, such as UCS2 vs UCS4, round-tripping + issues, etc + """ + def test_round_trip(self): + """ Tests that GETITEM, SETITEM, and PyArray_Scalar roundtrip """ + # gh-15363 + arr = np.zeros(shape=(), dtype="U1") + for i in range(1, sys.maxunicode + 1): + expected = chr(i) + arr[()] = expected + assert arr[()] == expected + assert arr.item() == expected + + def test_assign_scalar(self): + # gh-3258 + l = np.array(['aa', 'bb']) + l[:] = np.unicode_('cc') + assert_equal(l, ['cc', 'cc']) + + def test_fill_scalar(self): + # gh-7227 + l = np.array(['aa', 'bb']) + l.fill(np.unicode_('cc')) + assert_equal(l, ['cc', 'cc']) + + +class TestUnicodeArrayNonzero: + + def test_empty_ustring_array_is_falsey(self): + assert_(not np.array([''], dtype=np.unicode_)) + + def test_whitespace_ustring_array_is_falsey(self): + a = np.array(['eggs'], dtype=np.unicode_) + a[0] = ' \0\0' + assert_(not a) + + def test_all_null_ustring_array_is_falsey(self): + a = np.array(['eggs'], dtype=np.unicode_) + a[0] = '\0\0\0\0' + assert_(not a) + + def test_null_inside_ustring_array_is_truthy(self): + a = np.array(['eggs'], dtype=np.unicode_) + a[0] = ' \0 \0' + assert_(a) + + +class TestFormat: + + def test_0d(self): + a = np.array(np.pi) + assert_equal('{:0.3g}'.format(a), '3.14') + assert_equal('{:0.3g}'.format(a[()]), '3.14') + + def test_1d_no_format(self): + a = np.array([np.pi]) + assert_equal('{}'.format(a), str(a)) + + def test_1d_format(self): + # until gh-5543, ensure that the behaviour matches what it used to be + a = np.array([np.pi]) + assert_raises(TypeError, '{:30}'.format, a) + +from numpy.testing import IS_PYPY + +class TestCTypes: + + def test_ctypes_is_available(self): + test_arr = np.array([[1, 2, 3], [4, 5, 6]]) + + assert_equal(ctypes, test_arr.ctypes._ctypes) + assert_equal(tuple(test_arr.ctypes.shape), (2, 3)) + + def test_ctypes_is_not_available(self): + from numpy.core import _internal + _internal.ctypes = None + try: + test_arr = np.array([[1, 2, 3], [4, 5, 6]]) + + assert_(isinstance(test_arr.ctypes._ctypes, + _internal._missing_ctypes)) + assert_equal(tuple(test_arr.ctypes.shape), (2, 3)) + finally: + _internal.ctypes = ctypes + + def _make_readonly(x): + x.flags.writeable = False + return x + + @pytest.mark.parametrize('arr', [ + np.array([1, 2, 3]), + np.array([['one', 'two'], ['three', 'four']]), + np.array((1, 2), dtype='i4,i4'), + np.zeros((2,), dtype= + np.dtype(dict( + formats=['2, [44, 55]) + assert_equal(a, np.array([[0, 44], [1, 55], [2, 44]])) + # hit one of the failing paths + assert_raises(ValueError, np.place, a, a>20, []) + + def test_put_noncontiguous(self): + a = np.arange(6).reshape(2,3).T # force non-c-contiguous + np.put(a, [0, 2], [44, 55]) + assert_equal(a, np.array([[44, 3], [55, 4], [2, 5]])) + + def test_putmask_noncontiguous(self): + a = np.arange(6).reshape(2,3).T # force non-c-contiguous + # uses arr_putmask + np.putmask(a, a>2, a**2) + assert_equal(a, np.array([[0, 9], [1, 16], [2, 25]])) + + def test_take_mode_raise(self): + a = np.arange(6, dtype='int') + out = np.empty(2, dtype='int') + np.take(a, [0, 2], out=out, mode='raise') + assert_equal(out, np.array([0, 2])) + + def test_choose_mod_raise(self): + a = np.array([[1, 0, 1], [0, 1, 0], [1, 0, 1]]) + out = np.empty((3,3), dtype='int') + choices = [-10, 10] + np.choose(a, choices, out=out, mode='raise') + assert_equal(out, np.array([[ 10, -10, 10], + [-10, 10, -10], + [ 10, -10, 10]])) + + def test_flatiter__array__(self): + a = np.arange(9).reshape(3,3) + b = a.T.flat + c = b.__array__() + # triggers the WRITEBACKIFCOPY resolution, assuming refcount semantics + del c + + def test_dot_out(self): + # if HAVE_CBLAS, will use WRITEBACKIFCOPY + a = np.arange(9, dtype=float).reshape(3,3) + b = np.dot(a, a, out=a) + assert_equal(b, np.array([[15, 18, 21], [42, 54, 66], [69, 90, 111]])) + + def test_view_assign(self): + from numpy.core._multiarray_tests import npy_create_writebackifcopy, npy_resolve + + arr = np.arange(9).reshape(3, 3).T + arr_wb = npy_create_writebackifcopy(arr) + assert_(arr_wb.flags.writebackifcopy) + assert_(arr_wb.base is arr) + arr_wb[...] = -100 + npy_resolve(arr_wb) + # arr changes after resolve, even though we assigned to arr_wb + assert_equal(arr, -100) + # after resolve, the two arrays no longer reference each other + assert_(arr_wb.ctypes.data != 0) + assert_equal(arr_wb.base, None) + # assigning to arr_wb does not get transferred to arr + arr_wb[...] = 100 + assert_equal(arr, -100) + + @pytest.mark.leaks_references( + reason="increments self in dealloc; ignore since deprecated path.") + def test_dealloc_warning(self): + with suppress_warnings() as sup: + sup.record(RuntimeWarning) + arr = np.arange(9).reshape(3, 3) + v = arr.T + _multiarray_tests.npy_abuse_writebackifcopy(v) + assert len(sup.log) == 1 + + def test_view_discard_refcount(self): + from numpy.core._multiarray_tests import npy_create_writebackifcopy, npy_discard + + arr = np.arange(9).reshape(3, 3).T + orig = arr.copy() + if HAS_REFCOUNT: + arr_cnt = sys.getrefcount(arr) + arr_wb = npy_create_writebackifcopy(arr) + assert_(arr_wb.flags.writebackifcopy) + assert_(arr_wb.base is arr) + arr_wb[...] = -100 + npy_discard(arr_wb) + # arr remains unchanged after discard + assert_equal(arr, orig) + # after discard, the two arrays no longer reference each other + assert_(arr_wb.ctypes.data != 0) + assert_equal(arr_wb.base, None) + if HAS_REFCOUNT: + assert_equal(arr_cnt, sys.getrefcount(arr)) + # assigning to arr_wb does not get transferred to arr + arr_wb[...] = 100 + assert_equal(arr, orig) + + +class TestArange: + def test_infinite(self): + assert_raises_regex( + ValueError, "size exceeded", + np.arange, 0, np.inf + ) + + def test_nan_step(self): + assert_raises_regex( + ValueError, "cannot compute length", + np.arange, 0, 1, np.nan + ) + + def test_zero_step(self): + assert_raises(ZeroDivisionError, np.arange, 0, 10, 0) + assert_raises(ZeroDivisionError, np.arange, 0.0, 10.0, 0.0) + + # empty range + assert_raises(ZeroDivisionError, np.arange, 0, 0, 0) + assert_raises(ZeroDivisionError, np.arange, 0.0, 0.0, 0.0) + + +class TestArrayFinalize: + """ Tests __array_finalize__ """ + + def test_receives_base(self): + # gh-11237 + class SavesBase(np.ndarray): + def __array_finalize__(self, obj): + self.saved_base = self.base + + a = np.array(1).view(SavesBase) + assert_(a.saved_base is a.base) + + def test_lifetime_on_error(self): + # gh-11237 + class RaisesInFinalize(np.ndarray): + def __array_finalize__(self, obj): + # crash, but keep this object alive + raise Exception(self) + + # a plain object can't be weakref'd + class Dummy: pass + + # get a weak reference to an object within an array + obj_arr = np.array(Dummy()) + obj_ref = weakref.ref(obj_arr[()]) + + # get an array that crashed in __array_finalize__ + with assert_raises(Exception) as e: + obj_arr.view(RaisesInFinalize) + + obj_subarray = e.exception.args[0] + del e + assert_(isinstance(obj_subarray, RaisesInFinalize)) + + # reference should still be held by obj_arr + break_cycles() + assert_(obj_ref() is not None, "object should not already be dead") + + del obj_arr + break_cycles() + assert_(obj_ref() is not None, "obj_arr should not hold the last reference") + + del obj_subarray + break_cycles() + assert_(obj_ref() is None, "no references should remain") + + +def test_orderconverter_with_nonASCII_unicode_ordering(): + # gh-7475 + a = np.arange(5) + assert_raises(ValueError, a.flatten, order=u'\xe2') + + +def test_equal_override(): + # gh-9153: ndarray.__eq__ uses special logic for structured arrays, which + # did not respect overrides with __array_priority__ or __array_ufunc__. + # The PR fixed this for __array_priority__ and __array_ufunc__ = None. + class MyAlwaysEqual: + def __eq__(self, other): + return "eq" + + def __ne__(self, other): + return "ne" + + class MyAlwaysEqualOld(MyAlwaysEqual): + __array_priority__ = 10000 + + class MyAlwaysEqualNew(MyAlwaysEqual): + __array_ufunc__ = None + + array = np.array([(0, 1), (2, 3)], dtype='i4,i4') + for my_always_equal_cls in MyAlwaysEqualOld, MyAlwaysEqualNew: + my_always_equal = my_always_equal_cls() + assert_equal(my_always_equal == array, 'eq') + assert_equal(array == my_always_equal, 'eq') + assert_equal(my_always_equal != array, 'ne') + assert_equal(array != my_always_equal, 'ne') + + +def test_npymath_complex(): + # Smoketest npymath functions + from numpy.core._multiarray_tests import ( + npy_cabs, npy_carg) + + funcs = {npy_cabs: np.absolute, + npy_carg: np.angle} + vals = (1, np.inf, -np.inf, np.nan) + types = (np.complex64, np.complex128, np.clongdouble) + + for fun, npfun in funcs.items(): + for x, y in itertools.product(vals, vals): + for t in types: + z = t(complex(x, y)) + got = fun(z) + expected = npfun(z) + assert_allclose(got, expected) + + +def test_npymath_real(): + # Smoketest npymath functions + from numpy.core._multiarray_tests import ( + npy_log10, npy_cosh, npy_sinh, npy_tan, npy_tanh) + + funcs = {npy_log10: np.log10, + npy_cosh: np.cosh, + npy_sinh: np.sinh, + npy_tan: np.tan, + npy_tanh: np.tanh} + vals = (1, np.inf, -np.inf, np.nan) + types = (np.float32, np.float64, np.longdouble) + + with np.errstate(all='ignore'): + for fun, npfun in funcs.items(): + for x, t in itertools.product(vals, types): + z = t(x) + got = fun(z) + expected = npfun(z) + assert_allclose(got, expected) + +def test_uintalignment_and_alignment(): + # alignment code needs to satisfy these requirements: + # 1. numpy structs match C struct layout + # 2. ufuncs/casting is safe wrt to aligned access + # 3. copy code is safe wrt to "uint alidned" access + # + # Complex types are the main problem, whose alignment may not be the same + # as their "uint alignment". + # + # This test might only fail on certain platforms, where uint64 alignment is + # not equal to complex64 alignment. The second 2 tests will only fail + # for DEBUG=1. + + d1 = np.dtype('u1,c8', align=True) + d2 = np.dtype('u4,c8', align=True) + d3 = np.dtype({'names': ['a', 'b'], 'formats': ['u1', d1]}, align=True) + + assert_equal(np.zeros(1, dtype=d1)['f1'].flags['ALIGNED'], True) + assert_equal(np.zeros(1, dtype=d2)['f1'].flags['ALIGNED'], True) + assert_equal(np.zeros(1, dtype='u1,c8')['f1'].flags['ALIGNED'], False) + + # check that C struct matches numpy struct size + s = _multiarray_tests.get_struct_alignments() + for d, (alignment, size) in zip([d1,d2,d3], s): + assert_equal(d.alignment, alignment) + assert_equal(d.itemsize, size) + + # check that ufuncs don't complain in debug mode + # (this is probably OK if the aligned flag is true above) + src = np.zeros((2,2), dtype=d1)['f1'] # 4-byte aligned, often + np.exp(src) # assert fails? + + # check that copy code doesn't complain in debug mode + dst = np.zeros((2,2), dtype='c8') + dst[:,1] = src[:,1] # assert in lowlevel_strided_loops fails? + +class TestAlignment: + # adapted from scipy._lib.tests.test__util.test__aligned_zeros + # Checks that unusual memory alignments don't trip up numpy. + # In particular, check RELAXED_STRIDES don't trip alignment assertions in + # NDEBUG mode for size-0 arrays (gh-12503) + + def check(self, shape, dtype, order, align): + err_msg = repr((shape, dtype, order, align)) + x = _aligned_zeros(shape, dtype, order, align=align) + if align is None: + align = np.dtype(dtype).alignment + assert_equal(x.__array_interface__['data'][0] % align, 0) + if hasattr(shape, '__len__'): + assert_equal(x.shape, shape, err_msg) + else: + assert_equal(x.shape, (shape,), err_msg) + assert_equal(x.dtype, dtype) + if order == "C": + assert_(x.flags.c_contiguous, err_msg) + elif order == "F": + if x.size > 0: + assert_(x.flags.f_contiguous, err_msg) + elif order is None: + assert_(x.flags.c_contiguous, err_msg) + else: + raise ValueError() + + def test_various_alignments(self): + for align in [1, 2, 3, 4, 8, 12, 16, 32, 64, None]: + for n in [0, 1, 3, 11]: + for order in ["C", "F", None]: + for dtype in list(np.typecodes["All"]) + ['i4,i4,i4']: + if dtype == 'O': + # object dtype can't be misaligned + continue + for shape in [n, (1, 2, 3, n)]: + self.check(shape, np.dtype(dtype), order, align) + + def test_strided_loop_alignments(self): + # particularly test that complex64 and float128 use right alignment + # code-paths, since these are particularly problematic. It is useful to + # turn on USE_DEBUG for this test, so lowlevel-loop asserts are run. + for align in [1, 2, 4, 8, 12, 16, None]: + xf64 = _aligned_zeros(3, np.float64) + + xc64 = _aligned_zeros(3, np.complex64, align=align) + xf128 = _aligned_zeros(3, np.longdouble, align=align) + + # test casting, both to and from misaligned + with suppress_warnings() as sup: + sup.filter(np.ComplexWarning, "Casting complex values") + xc64.astype('f8') + xf64.astype(np.complex64) + test = xc64 + xf64 + + xf128.astype('f8') + xf64.astype(np.longdouble) + test = xf128 + xf64 + + test = xf128 + xc64 + + # test copy, both to and from misaligned + # contig copy + xf64[:] = xf64.copy() + xc64[:] = xc64.copy() + xf128[:] = xf128.copy() + # strided copy + xf64[::2] = xf64[::2].copy() + xc64[::2] = xc64[::2].copy() + xf128[::2] = xf128[::2].copy() + +def test_getfield(): + a = np.arange(32, dtype='uint16') + if sys.byteorder == 'little': + i = 0 + j = 1 + else: + i = 1 + j = 0 + b = a.getfield('int8', i) + assert_equal(b, a) + b = a.getfield('int8', j) + assert_equal(b, 0) + pytest.raises(ValueError, a.getfield, 'uint8', -1) + pytest.raises(ValueError, a.getfield, 'uint8', 16) + pytest.raises(ValueError, a.getfield, 'uint64', 0) diff --git a/venv/Lib/site-packages/numpy/core/tests/test_nditer.py b/venv/Lib/site-packages/numpy/core/tests/test_nditer.py new file mode 100644 index 0000000..cb6d77b --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/tests/test_nditer.py @@ -0,0 +1,2968 @@ +import sys +import pytest + +import numpy as np +import numpy.core._multiarray_tests as _multiarray_tests +from numpy import array, arange, nditer, all +from numpy.testing import ( + assert_, assert_equal, assert_array_equal, assert_raises, + HAS_REFCOUNT, suppress_warnings + ) + + +def iter_multi_index(i): + ret = [] + while not i.finished: + ret.append(i.multi_index) + i.iternext() + return ret + +def iter_indices(i): + ret = [] + while not i.finished: + ret.append(i.index) + i.iternext() + return ret + +def iter_iterindices(i): + ret = [] + while not i.finished: + ret.append(i.iterindex) + i.iternext() + return ret + +@pytest.mark.skipif(not HAS_REFCOUNT, reason="Python lacks refcounts") +def test_iter_refcount(): + # Make sure the iterator doesn't leak + + # Basic + a = arange(6) + dt = np.dtype('f4').newbyteorder() + rc_a = sys.getrefcount(a) + rc_dt = sys.getrefcount(dt) + with nditer(a, [], + [['readwrite', 'updateifcopy']], + casting='unsafe', + op_dtypes=[dt]) as it: + assert_(not it.iterationneedsapi) + assert_(sys.getrefcount(a) > rc_a) + assert_(sys.getrefcount(dt) > rc_dt) + # del 'it' + it = None + assert_equal(sys.getrefcount(a), rc_a) + assert_equal(sys.getrefcount(dt), rc_dt) + + # With a copy + a = arange(6, dtype='f4') + dt = np.dtype('f4') + rc_a = sys.getrefcount(a) + rc_dt = sys.getrefcount(dt) + it = nditer(a, [], + [['readwrite']], + op_dtypes=[dt]) + rc2_a = sys.getrefcount(a) + rc2_dt = sys.getrefcount(dt) + it2 = it.copy() + assert_(sys.getrefcount(a) > rc2_a) + assert_(sys.getrefcount(dt) > rc2_dt) + it = None + assert_equal(sys.getrefcount(a), rc2_a) + assert_equal(sys.getrefcount(dt), rc2_dt) + it2 = None + assert_equal(sys.getrefcount(a), rc_a) + assert_equal(sys.getrefcount(dt), rc_dt) + + del it2 # avoid pyflakes unused variable warning + +def test_iter_best_order(): + # The iterator should always find the iteration order + # with increasing memory addresses + + # Test the ordering for 1-D to 5-D shapes + for shape in [(5,), (3, 4), (2, 3, 4), (2, 3, 4, 3), (2, 3, 2, 2, 3)]: + a = arange(np.prod(shape)) + # Test each combination of positive and negative strides + for dirs in range(2**len(shape)): + dirs_index = [slice(None)]*len(shape) + for bit in range(len(shape)): + if ((2**bit) & dirs): + dirs_index[bit] = slice(None, None, -1) + dirs_index = tuple(dirs_index) + + aview = a.reshape(shape)[dirs_index] + # C-order + i = nditer(aview, [], [['readonly']]) + assert_equal([x for x in i], a) + # Fortran-order + i = nditer(aview.T, [], [['readonly']]) + assert_equal([x for x in i], a) + # Other order + if len(shape) > 2: + i = nditer(aview.swapaxes(0, 1), [], [['readonly']]) + assert_equal([x for x in i], a) + +def test_iter_c_order(): + # Test forcing C order + + # Test the ordering for 1-D to 5-D shapes + for shape in [(5,), (3, 4), (2, 3, 4), (2, 3, 4, 3), (2, 3, 2, 2, 3)]: + a = arange(np.prod(shape)) + # Test each combination of positive and negative strides + for dirs in range(2**len(shape)): + dirs_index = [slice(None)]*len(shape) + for bit in range(len(shape)): + if ((2**bit) & dirs): + dirs_index[bit] = slice(None, None, -1) + dirs_index = tuple(dirs_index) + + aview = a.reshape(shape)[dirs_index] + # C-order + i = nditer(aview, order='C') + assert_equal([x for x in i], aview.ravel(order='C')) + # Fortran-order + i = nditer(aview.T, order='C') + assert_equal([x for x in i], aview.T.ravel(order='C')) + # Other order + if len(shape) > 2: + i = nditer(aview.swapaxes(0, 1), order='C') + assert_equal([x for x in i], + aview.swapaxes(0, 1).ravel(order='C')) + +def test_iter_f_order(): + # Test forcing F order + + # Test the ordering for 1-D to 5-D shapes + for shape in [(5,), (3, 4), (2, 3, 4), (2, 3, 4, 3), (2, 3, 2, 2, 3)]: + a = arange(np.prod(shape)) + # Test each combination of positive and negative strides + for dirs in range(2**len(shape)): + dirs_index = [slice(None)]*len(shape) + for bit in range(len(shape)): + if ((2**bit) & dirs): + dirs_index[bit] = slice(None, None, -1) + dirs_index = tuple(dirs_index) + + aview = a.reshape(shape)[dirs_index] + # C-order + i = nditer(aview, order='F') + assert_equal([x for x in i], aview.ravel(order='F')) + # Fortran-order + i = nditer(aview.T, order='F') + assert_equal([x for x in i], aview.T.ravel(order='F')) + # Other order + if len(shape) > 2: + i = nditer(aview.swapaxes(0, 1), order='F') + assert_equal([x for x in i], + aview.swapaxes(0, 1).ravel(order='F')) + +def test_iter_c_or_f_order(): + # Test forcing any contiguous (C or F) order + + # Test the ordering for 1-D to 5-D shapes + for shape in [(5,), (3, 4), (2, 3, 4), (2, 3, 4, 3), (2, 3, 2, 2, 3)]: + a = arange(np.prod(shape)) + # Test each combination of positive and negative strides + for dirs in range(2**len(shape)): + dirs_index = [slice(None)]*len(shape) + for bit in range(len(shape)): + if ((2**bit) & dirs): + dirs_index[bit] = slice(None, None, -1) + dirs_index = tuple(dirs_index) + + aview = a.reshape(shape)[dirs_index] + # C-order + i = nditer(aview, order='A') + assert_equal([x for x in i], aview.ravel(order='A')) + # Fortran-order + i = nditer(aview.T, order='A') + assert_equal([x for x in i], aview.T.ravel(order='A')) + # Other order + if len(shape) > 2: + i = nditer(aview.swapaxes(0, 1), order='A') + assert_equal([x for x in i], + aview.swapaxes(0, 1).ravel(order='A')) + +def test_iter_best_order_multi_index_1d(): + # The multi-indices should be correct with any reordering + + a = arange(4) + # 1D order + i = nditer(a, ['multi_index'], [['readonly']]) + assert_equal(iter_multi_index(i), [(0,), (1,), (2,), (3,)]) + # 1D reversed order + i = nditer(a[::-1], ['multi_index'], [['readonly']]) + assert_equal(iter_multi_index(i), [(3,), (2,), (1,), (0,)]) + +def test_iter_best_order_multi_index_2d(): + # The multi-indices should be correct with any reordering + + a = arange(6) + # 2D C-order + i = nditer(a.reshape(2, 3), ['multi_index'], [['readonly']]) + assert_equal(iter_multi_index(i), [(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2)]) + # 2D Fortran-order + i = nditer(a.reshape(2, 3).copy(order='F'), ['multi_index'], [['readonly']]) + assert_equal(iter_multi_index(i), [(0, 0), (1, 0), (0, 1), (1, 1), (0, 2), (1, 2)]) + # 2D reversed C-order + i = nditer(a.reshape(2, 3)[::-1], ['multi_index'], [['readonly']]) + assert_equal(iter_multi_index(i), [(1, 0), (1, 1), (1, 2), (0, 0), (0, 1), (0, 2)]) + i = nditer(a.reshape(2, 3)[:, ::-1], ['multi_index'], [['readonly']]) + assert_equal(iter_multi_index(i), [(0, 2), (0, 1), (0, 0), (1, 2), (1, 1), (1, 0)]) + i = nditer(a.reshape(2, 3)[::-1, ::-1], ['multi_index'], [['readonly']]) + assert_equal(iter_multi_index(i), [(1, 2), (1, 1), (1, 0), (0, 2), (0, 1), (0, 0)]) + # 2D reversed Fortran-order + i = nditer(a.reshape(2, 3).copy(order='F')[::-1], ['multi_index'], [['readonly']]) + assert_equal(iter_multi_index(i), [(1, 0), (0, 0), (1, 1), (0, 1), (1, 2), (0, 2)]) + i = nditer(a.reshape(2, 3).copy(order='F')[:, ::-1], + ['multi_index'], [['readonly']]) + assert_equal(iter_multi_index(i), [(0, 2), (1, 2), (0, 1), (1, 1), (0, 0), (1, 0)]) + i = nditer(a.reshape(2, 3).copy(order='F')[::-1, ::-1], + ['multi_index'], [['readonly']]) + assert_equal(iter_multi_index(i), [(1, 2), (0, 2), (1, 1), (0, 1), (1, 0), (0, 0)]) + +def test_iter_best_order_multi_index_3d(): + # The multi-indices should be correct with any reordering + + a = arange(12) + # 3D C-order + i = nditer(a.reshape(2, 3, 2), ['multi_index'], [['readonly']]) + assert_equal(iter_multi_index(i), + [(0, 0, 0), (0, 0, 1), (0, 1, 0), (0, 1, 1), (0, 2, 0), (0, 2, 1), + (1, 0, 0), (1, 0, 1), (1, 1, 0), (1, 1, 1), (1, 2, 0), (1, 2, 1)]) + # 3D Fortran-order + i = nditer(a.reshape(2, 3, 2).copy(order='F'), ['multi_index'], [['readonly']]) + assert_equal(iter_multi_index(i), + [(0, 0, 0), (1, 0, 0), (0, 1, 0), (1, 1, 0), (0, 2, 0), (1, 2, 0), + (0, 0, 1), (1, 0, 1), (0, 1, 1), (1, 1, 1), (0, 2, 1), (1, 2, 1)]) + # 3D reversed C-order + i = nditer(a.reshape(2, 3, 2)[::-1], ['multi_index'], [['readonly']]) + assert_equal(iter_multi_index(i), + [(1, 0, 0), (1, 0, 1), (1, 1, 0), (1, 1, 1), (1, 2, 0), (1, 2, 1), + (0, 0, 0), (0, 0, 1), (0, 1, 0), (0, 1, 1), (0, 2, 0), (0, 2, 1)]) + i = nditer(a.reshape(2, 3, 2)[:, ::-1], ['multi_index'], [['readonly']]) + assert_equal(iter_multi_index(i), + [(0, 2, 0), (0, 2, 1), (0, 1, 0), (0, 1, 1), (0, 0, 0), (0, 0, 1), + (1, 2, 0), (1, 2, 1), (1, 1, 0), (1, 1, 1), (1, 0, 0), (1, 0, 1)]) + i = nditer(a.reshape(2, 3, 2)[:,:, ::-1], ['multi_index'], [['readonly']]) + assert_equal(iter_multi_index(i), + [(0, 0, 1), (0, 0, 0), (0, 1, 1), (0, 1, 0), (0, 2, 1), (0, 2, 0), + (1, 0, 1), (1, 0, 0), (1, 1, 1), (1, 1, 0), (1, 2, 1), (1, 2, 0)]) + # 3D reversed Fortran-order + i = nditer(a.reshape(2, 3, 2).copy(order='F')[::-1], + ['multi_index'], [['readonly']]) + assert_equal(iter_multi_index(i), + [(1, 0, 0), (0, 0, 0), (1, 1, 0), (0, 1, 0), (1, 2, 0), (0, 2, 0), + (1, 0, 1), (0, 0, 1), (1, 1, 1), (0, 1, 1), (1, 2, 1), (0, 2, 1)]) + i = nditer(a.reshape(2, 3, 2).copy(order='F')[:, ::-1], + ['multi_index'], [['readonly']]) + assert_equal(iter_multi_index(i), + [(0, 2, 0), (1, 2, 0), (0, 1, 0), (1, 1, 0), (0, 0, 0), (1, 0, 0), + (0, 2, 1), (1, 2, 1), (0, 1, 1), (1, 1, 1), (0, 0, 1), (1, 0, 1)]) + i = nditer(a.reshape(2, 3, 2).copy(order='F')[:,:, ::-1], + ['multi_index'], [['readonly']]) + assert_equal(iter_multi_index(i), + [(0, 0, 1), (1, 0, 1), (0, 1, 1), (1, 1, 1), (0, 2, 1), (1, 2, 1), + (0, 0, 0), (1, 0, 0), (0, 1, 0), (1, 1, 0), (0, 2, 0), (1, 2, 0)]) + +def test_iter_best_order_c_index_1d(): + # The C index should be correct with any reordering + + a = arange(4) + # 1D order + i = nditer(a, ['c_index'], [['readonly']]) + assert_equal(iter_indices(i), [0, 1, 2, 3]) + # 1D reversed order + i = nditer(a[::-1], ['c_index'], [['readonly']]) + assert_equal(iter_indices(i), [3, 2, 1, 0]) + +def test_iter_best_order_c_index_2d(): + # The C index should be correct with any reordering + + a = arange(6) + # 2D C-order + i = nditer(a.reshape(2, 3), ['c_index'], [['readonly']]) + assert_equal(iter_indices(i), [0, 1, 2, 3, 4, 5]) + # 2D Fortran-order + i = nditer(a.reshape(2, 3).copy(order='F'), + ['c_index'], [['readonly']]) + assert_equal(iter_indices(i), [0, 3, 1, 4, 2, 5]) + # 2D reversed C-order + i = nditer(a.reshape(2, 3)[::-1], ['c_index'], [['readonly']]) + assert_equal(iter_indices(i), [3, 4, 5, 0, 1, 2]) + i = nditer(a.reshape(2, 3)[:, ::-1], ['c_index'], [['readonly']]) + assert_equal(iter_indices(i), [2, 1, 0, 5, 4, 3]) + i = nditer(a.reshape(2, 3)[::-1, ::-1], ['c_index'], [['readonly']]) + assert_equal(iter_indices(i), [5, 4, 3, 2, 1, 0]) + # 2D reversed Fortran-order + i = nditer(a.reshape(2, 3).copy(order='F')[::-1], + ['c_index'], [['readonly']]) + assert_equal(iter_indices(i), [3, 0, 4, 1, 5, 2]) + i = nditer(a.reshape(2, 3).copy(order='F')[:, ::-1], + ['c_index'], [['readonly']]) + assert_equal(iter_indices(i), [2, 5, 1, 4, 0, 3]) + i = nditer(a.reshape(2, 3).copy(order='F')[::-1, ::-1], + ['c_index'], [['readonly']]) + assert_equal(iter_indices(i), [5, 2, 4, 1, 3, 0]) + +def test_iter_best_order_c_index_3d(): + # The C index should be correct with any reordering + + a = arange(12) + # 3D C-order + i = nditer(a.reshape(2, 3, 2), ['c_index'], [['readonly']]) + assert_equal(iter_indices(i), + [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]) + # 3D Fortran-order + i = nditer(a.reshape(2, 3, 2).copy(order='F'), + ['c_index'], [['readonly']]) + assert_equal(iter_indices(i), + [0, 6, 2, 8, 4, 10, 1, 7, 3, 9, 5, 11]) + # 3D reversed C-order + i = nditer(a.reshape(2, 3, 2)[::-1], ['c_index'], [['readonly']]) + assert_equal(iter_indices(i), + [6, 7, 8, 9, 10, 11, 0, 1, 2, 3, 4, 5]) + i = nditer(a.reshape(2, 3, 2)[:, ::-1], ['c_index'], [['readonly']]) + assert_equal(iter_indices(i), + [4, 5, 2, 3, 0, 1, 10, 11, 8, 9, 6, 7]) + i = nditer(a.reshape(2, 3, 2)[:,:, ::-1], ['c_index'], [['readonly']]) + assert_equal(iter_indices(i), + [1, 0, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10]) + # 3D reversed Fortran-order + i = nditer(a.reshape(2, 3, 2).copy(order='F')[::-1], + ['c_index'], [['readonly']]) + assert_equal(iter_indices(i), + [6, 0, 8, 2, 10, 4, 7, 1, 9, 3, 11, 5]) + i = nditer(a.reshape(2, 3, 2).copy(order='F')[:, ::-1], + ['c_index'], [['readonly']]) + assert_equal(iter_indices(i), + [4, 10, 2, 8, 0, 6, 5, 11, 3, 9, 1, 7]) + i = nditer(a.reshape(2, 3, 2).copy(order='F')[:,:, ::-1], + ['c_index'], [['readonly']]) + assert_equal(iter_indices(i), + [1, 7, 3, 9, 5, 11, 0, 6, 2, 8, 4, 10]) + +def test_iter_best_order_f_index_1d(): + # The Fortran index should be correct with any reordering + + a = arange(4) + # 1D order + i = nditer(a, ['f_index'], [['readonly']]) + assert_equal(iter_indices(i), [0, 1, 2, 3]) + # 1D reversed order + i = nditer(a[::-1], ['f_index'], [['readonly']]) + assert_equal(iter_indices(i), [3, 2, 1, 0]) + +def test_iter_best_order_f_index_2d(): + # The Fortran index should be correct with any reordering + + a = arange(6) + # 2D C-order + i = nditer(a.reshape(2, 3), ['f_index'], [['readonly']]) + assert_equal(iter_indices(i), [0, 2, 4, 1, 3, 5]) + # 2D Fortran-order + i = nditer(a.reshape(2, 3).copy(order='F'), + ['f_index'], [['readonly']]) + assert_equal(iter_indices(i), [0, 1, 2, 3, 4, 5]) + # 2D reversed C-order + i = nditer(a.reshape(2, 3)[::-1], ['f_index'], [['readonly']]) + assert_equal(iter_indices(i), [1, 3, 5, 0, 2, 4]) + i = nditer(a.reshape(2, 3)[:, ::-1], ['f_index'], [['readonly']]) + assert_equal(iter_indices(i), [4, 2, 0, 5, 3, 1]) + i = nditer(a.reshape(2, 3)[::-1, ::-1], ['f_index'], [['readonly']]) + assert_equal(iter_indices(i), [5, 3, 1, 4, 2, 0]) + # 2D reversed Fortran-order + i = nditer(a.reshape(2, 3).copy(order='F')[::-1], + ['f_index'], [['readonly']]) + assert_equal(iter_indices(i), [1, 0, 3, 2, 5, 4]) + i = nditer(a.reshape(2, 3).copy(order='F')[:, ::-1], + ['f_index'], [['readonly']]) + assert_equal(iter_indices(i), [4, 5, 2, 3, 0, 1]) + i = nditer(a.reshape(2, 3).copy(order='F')[::-1, ::-1], + ['f_index'], [['readonly']]) + assert_equal(iter_indices(i), [5, 4, 3, 2, 1, 0]) + +def test_iter_best_order_f_index_3d(): + # The Fortran index should be correct with any reordering + + a = arange(12) + # 3D C-order + i = nditer(a.reshape(2, 3, 2), ['f_index'], [['readonly']]) + assert_equal(iter_indices(i), + [0, 6, 2, 8, 4, 10, 1, 7, 3, 9, 5, 11]) + # 3D Fortran-order + i = nditer(a.reshape(2, 3, 2).copy(order='F'), + ['f_index'], [['readonly']]) + assert_equal(iter_indices(i), + [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]) + # 3D reversed C-order + i = nditer(a.reshape(2, 3, 2)[::-1], ['f_index'], [['readonly']]) + assert_equal(iter_indices(i), + [1, 7, 3, 9, 5, 11, 0, 6, 2, 8, 4, 10]) + i = nditer(a.reshape(2, 3, 2)[:, ::-1], ['f_index'], [['readonly']]) + assert_equal(iter_indices(i), + [4, 10, 2, 8, 0, 6, 5, 11, 3, 9, 1, 7]) + i = nditer(a.reshape(2, 3, 2)[:,:, ::-1], ['f_index'], [['readonly']]) + assert_equal(iter_indices(i), + [6, 0, 8, 2, 10, 4, 7, 1, 9, 3, 11, 5]) + # 3D reversed Fortran-order + i = nditer(a.reshape(2, 3, 2).copy(order='F')[::-1], + ['f_index'], [['readonly']]) + assert_equal(iter_indices(i), + [1, 0, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10]) + i = nditer(a.reshape(2, 3, 2).copy(order='F')[:, ::-1], + ['f_index'], [['readonly']]) + assert_equal(iter_indices(i), + [4, 5, 2, 3, 0, 1, 10, 11, 8, 9, 6, 7]) + i = nditer(a.reshape(2, 3, 2).copy(order='F')[:,:, ::-1], + ['f_index'], [['readonly']]) + assert_equal(iter_indices(i), + [6, 7, 8, 9, 10, 11, 0, 1, 2, 3, 4, 5]) + +def test_iter_no_inner_full_coalesce(): + # Check no_inner iterators which coalesce into a single inner loop + + for shape in [(5,), (3, 4), (2, 3, 4), (2, 3, 4, 3), (2, 3, 2, 2, 3)]: + size = np.prod(shape) + a = arange(size) + # Test each combination of forward and backwards indexing + for dirs in range(2**len(shape)): + dirs_index = [slice(None)]*len(shape) + for bit in range(len(shape)): + if ((2**bit) & dirs): + dirs_index[bit] = slice(None, None, -1) + dirs_index = tuple(dirs_index) + + aview = a.reshape(shape)[dirs_index] + # C-order + i = nditer(aview, ['external_loop'], [['readonly']]) + assert_equal(i.ndim, 1) + assert_equal(i[0].shape, (size,)) + # Fortran-order + i = nditer(aview.T, ['external_loop'], [['readonly']]) + assert_equal(i.ndim, 1) + assert_equal(i[0].shape, (size,)) + # Other order + if len(shape) > 2: + i = nditer(aview.swapaxes(0, 1), + ['external_loop'], [['readonly']]) + assert_equal(i.ndim, 1) + assert_equal(i[0].shape, (size,)) + +def test_iter_no_inner_dim_coalescing(): + # Check no_inner iterators whose dimensions may not coalesce completely + + # Skipping the last element in a dimension prevents coalescing + # with the next-bigger dimension + a = arange(24).reshape(2, 3, 4)[:,:, :-1] + i = nditer(a, ['external_loop'], [['readonly']]) + assert_equal(i.ndim, 2) + assert_equal(i[0].shape, (3,)) + a = arange(24).reshape(2, 3, 4)[:, :-1,:] + i = nditer(a, ['external_loop'], [['readonly']]) + assert_equal(i.ndim, 2) + assert_equal(i[0].shape, (8,)) + a = arange(24).reshape(2, 3, 4)[:-1,:,:] + i = nditer(a, ['external_loop'], [['readonly']]) + assert_equal(i.ndim, 1) + assert_equal(i[0].shape, (12,)) + + # Even with lots of 1-sized dimensions, should still coalesce + a = arange(24).reshape(1, 1, 2, 1, 1, 3, 1, 1, 4, 1, 1) + i = nditer(a, ['external_loop'], [['readonly']]) + assert_equal(i.ndim, 1) + assert_equal(i[0].shape, (24,)) + +def test_iter_dim_coalescing(): + # Check that the correct number of dimensions are coalesced + + # Tracking a multi-index disables coalescing + a = arange(24).reshape(2, 3, 4) + i = nditer(a, ['multi_index'], [['readonly']]) + assert_equal(i.ndim, 3) + + # A tracked index can allow coalescing if it's compatible with the array + a3d = arange(24).reshape(2, 3, 4) + i = nditer(a3d, ['c_index'], [['readonly']]) + assert_equal(i.ndim, 1) + i = nditer(a3d.swapaxes(0, 1), ['c_index'], [['readonly']]) + assert_equal(i.ndim, 3) + i = nditer(a3d.T, ['c_index'], [['readonly']]) + assert_equal(i.ndim, 3) + i = nditer(a3d.T, ['f_index'], [['readonly']]) + assert_equal(i.ndim, 1) + i = nditer(a3d.T.swapaxes(0, 1), ['f_index'], [['readonly']]) + assert_equal(i.ndim, 3) + + # When C or F order is forced, coalescing may still occur + a3d = arange(24).reshape(2, 3, 4) + i = nditer(a3d, order='C') + assert_equal(i.ndim, 1) + i = nditer(a3d.T, order='C') + assert_equal(i.ndim, 3) + i = nditer(a3d, order='F') + assert_equal(i.ndim, 3) + i = nditer(a3d.T, order='F') + assert_equal(i.ndim, 1) + i = nditer(a3d, order='A') + assert_equal(i.ndim, 1) + i = nditer(a3d.T, order='A') + assert_equal(i.ndim, 1) + +def test_iter_broadcasting(): + # Standard NumPy broadcasting rules + + # 1D with scalar + i = nditer([arange(6), np.int32(2)], ['multi_index'], [['readonly']]*2) + assert_equal(i.itersize, 6) + assert_equal(i.shape, (6,)) + + # 2D with scalar + i = nditer([arange(6).reshape(2, 3), np.int32(2)], + ['multi_index'], [['readonly']]*2) + assert_equal(i.itersize, 6) + assert_equal(i.shape, (2, 3)) + # 2D with 1D + i = nditer([arange(6).reshape(2, 3), arange(3)], + ['multi_index'], [['readonly']]*2) + assert_equal(i.itersize, 6) + assert_equal(i.shape, (2, 3)) + i = nditer([arange(2).reshape(2, 1), arange(3)], + ['multi_index'], [['readonly']]*2) + assert_equal(i.itersize, 6) + assert_equal(i.shape, (2, 3)) + # 2D with 2D + i = nditer([arange(2).reshape(2, 1), arange(3).reshape(1, 3)], + ['multi_index'], [['readonly']]*2) + assert_equal(i.itersize, 6) + assert_equal(i.shape, (2, 3)) + + # 3D with scalar + i = nditer([np.int32(2), arange(24).reshape(4, 2, 3)], + ['multi_index'], [['readonly']]*2) + assert_equal(i.itersize, 24) + assert_equal(i.shape, (4, 2, 3)) + # 3D with 1D + i = nditer([arange(3), arange(24).reshape(4, 2, 3)], + ['multi_index'], [['readonly']]*2) + assert_equal(i.itersize, 24) + assert_equal(i.shape, (4, 2, 3)) + i = nditer([arange(3), arange(8).reshape(4, 2, 1)], + ['multi_index'], [['readonly']]*2) + assert_equal(i.itersize, 24) + assert_equal(i.shape, (4, 2, 3)) + # 3D with 2D + i = nditer([arange(6).reshape(2, 3), arange(24).reshape(4, 2, 3)], + ['multi_index'], [['readonly']]*2) + assert_equal(i.itersize, 24) + assert_equal(i.shape, (4, 2, 3)) + i = nditer([arange(2).reshape(2, 1), arange(24).reshape(4, 2, 3)], + ['multi_index'], [['readonly']]*2) + assert_equal(i.itersize, 24) + assert_equal(i.shape, (4, 2, 3)) + i = nditer([arange(3).reshape(1, 3), arange(8).reshape(4, 2, 1)], + ['multi_index'], [['readonly']]*2) + assert_equal(i.itersize, 24) + assert_equal(i.shape, (4, 2, 3)) + # 3D with 3D + i = nditer([arange(2).reshape(1, 2, 1), arange(3).reshape(1, 1, 3), + arange(4).reshape(4, 1, 1)], + ['multi_index'], [['readonly']]*3) + assert_equal(i.itersize, 24) + assert_equal(i.shape, (4, 2, 3)) + i = nditer([arange(6).reshape(1, 2, 3), arange(4).reshape(4, 1, 1)], + ['multi_index'], [['readonly']]*2) + assert_equal(i.itersize, 24) + assert_equal(i.shape, (4, 2, 3)) + i = nditer([arange(24).reshape(4, 2, 3), arange(12).reshape(4, 1, 3)], + ['multi_index'], [['readonly']]*2) + assert_equal(i.itersize, 24) + assert_equal(i.shape, (4, 2, 3)) + +def test_iter_itershape(): + # Check that allocated outputs work with a specified shape + a = np.arange(6, dtype='i2').reshape(2, 3) + i = nditer([a, None], [], [['readonly'], ['writeonly', 'allocate']], + op_axes=[[0, 1, None], None], + itershape=(-1, -1, 4)) + assert_equal(i.operands[1].shape, (2, 3, 4)) + assert_equal(i.operands[1].strides, (24, 8, 2)) + + i = nditer([a.T, None], [], [['readonly'], ['writeonly', 'allocate']], + op_axes=[[0, 1, None], None], + itershape=(-1, -1, 4)) + assert_equal(i.operands[1].shape, (3, 2, 4)) + assert_equal(i.operands[1].strides, (8, 24, 2)) + + i = nditer([a.T, None], [], [['readonly'], ['writeonly', 'allocate']], + order='F', + op_axes=[[0, 1, None], None], + itershape=(-1, -1, 4)) + assert_equal(i.operands[1].shape, (3, 2, 4)) + assert_equal(i.operands[1].strides, (2, 6, 12)) + + # If we specify 1 in the itershape, it shouldn't allow broadcasting + # of that dimension to a bigger value + assert_raises(ValueError, nditer, [a, None], [], + [['readonly'], ['writeonly', 'allocate']], + op_axes=[[0, 1, None], None], + itershape=(-1, 1, 4)) + # Test bug that for no op_axes but itershape, they are NULLed correctly + i = np.nditer([np.ones(2), None, None], itershape=(2,)) + +def test_iter_broadcasting_errors(): + # Check that errors are thrown for bad broadcasting shapes + + # 1D with 1D + assert_raises(ValueError, nditer, [arange(2), arange(3)], + [], [['readonly']]*2) + # 2D with 1D + assert_raises(ValueError, nditer, + [arange(6).reshape(2, 3), arange(2)], + [], [['readonly']]*2) + # 2D with 2D + assert_raises(ValueError, nditer, + [arange(6).reshape(2, 3), arange(9).reshape(3, 3)], + [], [['readonly']]*2) + assert_raises(ValueError, nditer, + [arange(6).reshape(2, 3), arange(4).reshape(2, 2)], + [], [['readonly']]*2) + # 3D with 3D + assert_raises(ValueError, nditer, + [arange(36).reshape(3, 3, 4), arange(24).reshape(2, 3, 4)], + [], [['readonly']]*2) + assert_raises(ValueError, nditer, + [arange(8).reshape(2, 4, 1), arange(24).reshape(2, 3, 4)], + [], [['readonly']]*2) + + # Verify that the error message mentions the right shapes + try: + nditer([arange(2).reshape(1, 2, 1), + arange(3).reshape(1, 3), + arange(6).reshape(2, 3)], + [], + [['readonly'], ['readonly'], ['writeonly', 'no_broadcast']]) + raise AssertionError('Should have raised a broadcast error') + except ValueError as e: + msg = str(e) + # The message should contain the shape of the 3rd operand + assert_(msg.find('(2,3)') >= 0, + 'Message "%s" doesn\'t contain operand shape (2,3)' % msg) + # The message should contain the broadcast shape + assert_(msg.find('(1,2,3)') >= 0, + 'Message "%s" doesn\'t contain broadcast shape (1,2,3)' % msg) + + try: + nditer([arange(6).reshape(2, 3), arange(2)], + [], + [['readonly'], ['readonly']], + op_axes=[[0, 1], [0, np.newaxis]], + itershape=(4, 3)) + raise AssertionError('Should have raised a broadcast error') + except ValueError as e: + msg = str(e) + # The message should contain "shape->remappedshape" for each operand + assert_(msg.find('(2,3)->(2,3)') >= 0, + 'Message "%s" doesn\'t contain operand shape (2,3)->(2,3)' % msg) + assert_(msg.find('(2,)->(2,newaxis)') >= 0, + ('Message "%s" doesn\'t contain remapped operand shape' + + '(2,)->(2,newaxis)') % msg) + # The message should contain the itershape parameter + assert_(msg.find('(4,3)') >= 0, + 'Message "%s" doesn\'t contain itershape parameter (4,3)' % msg) + + try: + nditer([np.zeros((2, 1, 1)), np.zeros((2,))], + [], + [['writeonly', 'no_broadcast'], ['readonly']]) + raise AssertionError('Should have raised a broadcast error') + except ValueError as e: + msg = str(e) + # The message should contain the shape of the bad operand + assert_(msg.find('(2,1,1)') >= 0, + 'Message "%s" doesn\'t contain operand shape (2,1,1)' % msg) + # The message should contain the broadcast shape + assert_(msg.find('(2,1,2)') >= 0, + 'Message "%s" doesn\'t contain the broadcast shape (2,1,2)' % msg) + +def test_iter_flags_errors(): + # Check that bad combinations of flags produce errors + + a = arange(6) + + # Not enough operands + assert_raises(ValueError, nditer, [], [], []) + # Too many operands + assert_raises(ValueError, nditer, [a]*100, [], [['readonly']]*100) + # Bad global flag + assert_raises(ValueError, nditer, [a], ['bad flag'], [['readonly']]) + # Bad op flag + assert_raises(ValueError, nditer, [a], [], [['readonly', 'bad flag']]) + # Bad order parameter + assert_raises(ValueError, nditer, [a], [], [['readonly']], order='G') + # Bad casting parameter + assert_raises(ValueError, nditer, [a], [], [['readonly']], casting='noon') + # op_flags must match ops + assert_raises(ValueError, nditer, [a]*3, [], [['readonly']]*2) + # Cannot track both a C and an F index + assert_raises(ValueError, nditer, a, + ['c_index', 'f_index'], [['readonly']]) + # Inner iteration and multi-indices/indices are incompatible + assert_raises(ValueError, nditer, a, + ['external_loop', 'multi_index'], [['readonly']]) + assert_raises(ValueError, nditer, a, + ['external_loop', 'c_index'], [['readonly']]) + assert_raises(ValueError, nditer, a, + ['external_loop', 'f_index'], [['readonly']]) + # Must specify exactly one of readwrite/readonly/writeonly per operand + assert_raises(ValueError, nditer, a, [], [[]]) + assert_raises(ValueError, nditer, a, [], [['readonly', 'writeonly']]) + assert_raises(ValueError, nditer, a, [], [['readonly', 'readwrite']]) + assert_raises(ValueError, nditer, a, [], [['writeonly', 'readwrite']]) + assert_raises(ValueError, nditer, a, + [], [['readonly', 'writeonly', 'readwrite']]) + # Python scalars are always readonly + assert_raises(TypeError, nditer, 1.5, [], [['writeonly']]) + assert_raises(TypeError, nditer, 1.5, [], [['readwrite']]) + # Array scalars are always readonly + assert_raises(TypeError, nditer, np.int32(1), [], [['writeonly']]) + assert_raises(TypeError, nditer, np.int32(1), [], [['readwrite']]) + # Check readonly array + a.flags.writeable = False + assert_raises(ValueError, nditer, a, [], [['writeonly']]) + assert_raises(ValueError, nditer, a, [], [['readwrite']]) + a.flags.writeable = True + # Multi-indices available only with the multi_index flag + i = nditer(arange(6), [], [['readonly']]) + assert_raises(ValueError, lambda i:i.multi_index, i) + # Index available only with an index flag + assert_raises(ValueError, lambda i:i.index, i) + # GotoCoords and GotoIndex incompatible with buffering or no_inner + + def assign_multi_index(i): + i.multi_index = (0,) + + def assign_index(i): + i.index = 0 + + def assign_iterindex(i): + i.iterindex = 0 + + def assign_iterrange(i): + i.iterrange = (0, 1) + i = nditer(arange(6), ['external_loop']) + assert_raises(ValueError, assign_multi_index, i) + assert_raises(ValueError, assign_index, i) + assert_raises(ValueError, assign_iterindex, i) + assert_raises(ValueError, assign_iterrange, i) + i = nditer(arange(6), ['buffered']) + assert_raises(ValueError, assign_multi_index, i) + assert_raises(ValueError, assign_index, i) + assert_raises(ValueError, assign_iterrange, i) + # Can't iterate if size is zero + assert_raises(ValueError, nditer, np.array([])) + +def test_iter_slice(): + a, b, c = np.arange(3), np.arange(3), np.arange(3.) + i = nditer([a, b, c], [], ['readwrite']) + with i: + i[0:2] = (3, 3) + assert_equal(a, [3, 1, 2]) + assert_equal(b, [3, 1, 2]) + assert_equal(c, [0, 1, 2]) + i[1] = 12 + assert_equal(i[0:2], [3, 12]) + +def test_iter_assign_mapping(): + a = np.arange(24, dtype='f8').reshape(2, 3, 4).T + it = np.nditer(a, [], [['readwrite', 'updateifcopy']], + casting='same_kind', op_dtypes=[np.dtype('f4')]) + with it: + it.operands[0][...] = 3 + it.operands[0][...] = 14 + assert_equal(a, 14) + it = np.nditer(a, [], [['readwrite', 'updateifcopy']], + casting='same_kind', op_dtypes=[np.dtype('f4')]) + with it: + x = it.operands[0][-1:1] + x[...] = 14 + it.operands[0][...] = -1234 + assert_equal(a, -1234) + # check for no warnings on dealloc + x = None + it = None + +def test_iter_nbo_align_contig(): + # Check that byte order, alignment, and contig changes work + + # Byte order change by requesting a specific dtype + a = np.arange(6, dtype='f4') + au = a.byteswap().newbyteorder() + assert_(a.dtype.byteorder != au.dtype.byteorder) + i = nditer(au, [], [['readwrite', 'updateifcopy']], + casting='equiv', + op_dtypes=[np.dtype('f4')]) + with i: + # context manager triggers UPDATEIFCOPY on i at exit + assert_equal(i.dtypes[0].byteorder, a.dtype.byteorder) + assert_equal(i.operands[0].dtype.byteorder, a.dtype.byteorder) + assert_equal(i.operands[0], a) + i.operands[0][:] = 2 + assert_equal(au, [2]*6) + del i # should not raise a warning + # Byte order change by requesting NBO + a = np.arange(6, dtype='f4') + au = a.byteswap().newbyteorder() + assert_(a.dtype.byteorder != au.dtype.byteorder) + with nditer(au, [], [['readwrite', 'updateifcopy', 'nbo']], + casting='equiv') as i: + # context manager triggers UPDATEIFCOPY on i at exit + assert_equal(i.dtypes[0].byteorder, a.dtype.byteorder) + assert_equal(i.operands[0].dtype.byteorder, a.dtype.byteorder) + assert_equal(i.operands[0], a) + i.operands[0][:] = 12345 + i.operands[0][:] = 2 + assert_equal(au, [2]*6) + + # Unaligned input + a = np.zeros((6*4+1,), dtype='i1')[1:] + a.dtype = 'f4' + a[:] = np.arange(6, dtype='f4') + assert_(not a.flags.aligned) + # Without 'aligned', shouldn't copy + i = nditer(a, [], [['readonly']]) + assert_(not i.operands[0].flags.aligned) + assert_equal(i.operands[0], a) + # With 'aligned', should make a copy + with nditer(a, [], [['readwrite', 'updateifcopy', 'aligned']]) as i: + assert_(i.operands[0].flags.aligned) + # context manager triggers UPDATEIFCOPY on i at exit + assert_equal(i.operands[0], a) + i.operands[0][:] = 3 + assert_equal(a, [3]*6) + + # Discontiguous input + a = arange(12) + # If it is contiguous, shouldn't copy + i = nditer(a[:6], [], [['readonly']]) + assert_(i.operands[0].flags.contiguous) + assert_equal(i.operands[0], a[:6]) + # If it isn't contiguous, should buffer + i = nditer(a[::2], ['buffered', 'external_loop'], + [['readonly', 'contig']], + buffersize=10) + assert_(i[0].flags.contiguous) + assert_equal(i[0], a[::2]) + +def test_iter_array_cast(): + # Check that arrays are cast as requested + + # No cast 'f4' -> 'f4' + a = np.arange(6, dtype='f4').reshape(2, 3) + i = nditer(a, [], [['readwrite']], op_dtypes=[np.dtype('f4')]) + with i: + assert_equal(i.operands[0], a) + assert_equal(i.operands[0].dtype, np.dtype('f4')) + + # Byte-order cast ' '>f4' + a = np.arange(6, dtype='f4')]) as i: + assert_equal(i.operands[0], a) + assert_equal(i.operands[0].dtype, np.dtype('>f4')) + + # Safe case 'f4' -> 'f8' + a = np.arange(24, dtype='f4').reshape(2, 3, 4).swapaxes(1, 2) + i = nditer(a, [], [['readonly', 'copy']], + casting='safe', + op_dtypes=[np.dtype('f8')]) + assert_equal(i.operands[0], a) + assert_equal(i.operands[0].dtype, np.dtype('f8')) + # The memory layout of the temporary should match a (a is (48,4,16)) + # except negative strides get flipped to positive strides. + assert_equal(i.operands[0].strides, (96, 8, 32)) + a = a[::-1,:, ::-1] + i = nditer(a, [], [['readonly', 'copy']], + casting='safe', + op_dtypes=[np.dtype('f8')]) + assert_equal(i.operands[0], a) + assert_equal(i.operands[0].dtype, np.dtype('f8')) + assert_equal(i.operands[0].strides, (96, 8, 32)) + + # Same-kind cast 'f8' -> 'f4' -> 'f8' + a = np.arange(24, dtype='f8').reshape(2, 3, 4).T + with nditer(a, [], + [['readwrite', 'updateifcopy']], + casting='same_kind', + op_dtypes=[np.dtype('f4')]) as i: + assert_equal(i.operands[0], a) + assert_equal(i.operands[0].dtype, np.dtype('f4')) + assert_equal(i.operands[0].strides, (4, 16, 48)) + # Check that WRITEBACKIFCOPY is activated at exit + i.operands[0][2, 1, 1] = -12.5 + assert_(a[2, 1, 1] != -12.5) + assert_equal(a[2, 1, 1], -12.5) + + a = np.arange(6, dtype='i4')[::-2] + with nditer(a, [], + [['writeonly', 'updateifcopy']], + casting='unsafe', + op_dtypes=[np.dtype('f4')]) as i: + assert_equal(i.operands[0].dtype, np.dtype('f4')) + # Even though the stride was negative in 'a', it + # becomes positive in the temporary + assert_equal(i.operands[0].strides, (4,)) + i.operands[0][:] = [1, 2, 3] + assert_equal(a, [1, 2, 3]) + +def test_iter_array_cast_errors(): + # Check that invalid casts are caught + + # Need to enable copying for casts to occur + assert_raises(TypeError, nditer, arange(2, dtype='f4'), [], + [['readonly']], op_dtypes=[np.dtype('f8')]) + # Also need to allow casting for casts to occur + assert_raises(TypeError, nditer, arange(2, dtype='f4'), [], + [['readonly', 'copy']], casting='no', + op_dtypes=[np.dtype('f8')]) + assert_raises(TypeError, nditer, arange(2, dtype='f4'), [], + [['readonly', 'copy']], casting='equiv', + op_dtypes=[np.dtype('f8')]) + assert_raises(TypeError, nditer, arange(2, dtype='f8'), [], + [['writeonly', 'updateifcopy']], + casting='no', + op_dtypes=[np.dtype('f4')]) + assert_raises(TypeError, nditer, arange(2, dtype='f8'), [], + [['writeonly', 'updateifcopy']], + casting='equiv', + op_dtypes=[np.dtype('f4')]) + # ' '>f4' should not work with casting='no' + assert_raises(TypeError, nditer, arange(2, dtype='f4')]) + # 'f4' -> 'f8' is a safe cast, but 'f8' -> 'f4' isn't + assert_raises(TypeError, nditer, arange(2, dtype='f4'), [], + [['readwrite', 'updateifcopy']], + casting='safe', + op_dtypes=[np.dtype('f8')]) + assert_raises(TypeError, nditer, arange(2, dtype='f8'), [], + [['readwrite', 'updateifcopy']], + casting='safe', + op_dtypes=[np.dtype('f4')]) + # 'f4' -> 'i4' is neither a safe nor a same-kind cast + assert_raises(TypeError, nditer, arange(2, dtype='f4'), [], + [['readonly', 'copy']], + casting='same_kind', + op_dtypes=[np.dtype('i4')]) + assert_raises(TypeError, nditer, arange(2, dtype='i4'), [], + [['writeonly', 'updateifcopy']], + casting='same_kind', + op_dtypes=[np.dtype('f4')]) + +def test_iter_scalar_cast(): + # Check that scalars are cast as requested + + # No cast 'f4' -> 'f4' + i = nditer(np.float32(2.5), [], [['readonly']], + op_dtypes=[np.dtype('f4')]) + assert_equal(i.dtypes[0], np.dtype('f4')) + assert_equal(i.value.dtype, np.dtype('f4')) + assert_equal(i.value, 2.5) + # Safe cast 'f4' -> 'f8' + i = nditer(np.float32(2.5), [], + [['readonly', 'copy']], + casting='safe', + op_dtypes=[np.dtype('f8')]) + assert_equal(i.dtypes[0], np.dtype('f8')) + assert_equal(i.value.dtype, np.dtype('f8')) + assert_equal(i.value, 2.5) + # Same-kind cast 'f8' -> 'f4' + i = nditer(np.float64(2.5), [], + [['readonly', 'copy']], + casting='same_kind', + op_dtypes=[np.dtype('f4')]) + assert_equal(i.dtypes[0], np.dtype('f4')) + assert_equal(i.value.dtype, np.dtype('f4')) + assert_equal(i.value, 2.5) + # Unsafe cast 'f8' -> 'i4' + i = nditer(np.float64(3.0), [], + [['readonly', 'copy']], + casting='unsafe', + op_dtypes=[np.dtype('i4')]) + assert_equal(i.dtypes[0], np.dtype('i4')) + assert_equal(i.value.dtype, np.dtype('i4')) + assert_equal(i.value, 3) + # Readonly scalars may be cast even without setting COPY or BUFFERED + i = nditer(3, [], [['readonly']], op_dtypes=[np.dtype('f8')]) + assert_equal(i[0].dtype, np.dtype('f8')) + assert_equal(i[0], 3.) + +def test_iter_scalar_cast_errors(): + # Check that invalid casts are caught + + # Need to allow copying/buffering for write casts of scalars to occur + assert_raises(TypeError, nditer, np.float32(2), [], + [['readwrite']], op_dtypes=[np.dtype('f8')]) + assert_raises(TypeError, nditer, 2.5, [], + [['readwrite']], op_dtypes=[np.dtype('f4')]) + # 'f8' -> 'f4' isn't a safe cast if the value would overflow + assert_raises(TypeError, nditer, np.float64(1e60), [], + [['readonly']], + casting='safe', + op_dtypes=[np.dtype('f4')]) + # 'f4' -> 'i4' is neither a safe nor a same-kind cast + assert_raises(TypeError, nditer, np.float32(2), [], + [['readonly']], + casting='same_kind', + op_dtypes=[np.dtype('i4')]) + +def test_iter_object_arrays_basic(): + # Check that object arrays work + + obj = {'a':3,'b':'d'} + a = np.array([[1, 2, 3], None, obj, None], dtype='O') + if HAS_REFCOUNT: + rc = sys.getrefcount(obj) + + # Need to allow references for object arrays + assert_raises(TypeError, nditer, a) + if HAS_REFCOUNT: + assert_equal(sys.getrefcount(obj), rc) + + i = nditer(a, ['refs_ok'], ['readonly']) + vals = [x_[()] for x_ in i] + assert_equal(np.array(vals, dtype='O'), a) + vals, i, x = [None]*3 + if HAS_REFCOUNT: + assert_equal(sys.getrefcount(obj), rc) + + i = nditer(a.reshape(2, 2).T, ['refs_ok', 'buffered'], + ['readonly'], order='C') + assert_(i.iterationneedsapi) + vals = [x_[()] for x_ in i] + assert_equal(np.array(vals, dtype='O'), a.reshape(2, 2).ravel(order='F')) + vals, i, x = [None]*3 + if HAS_REFCOUNT: + assert_equal(sys.getrefcount(obj), rc) + + i = nditer(a.reshape(2, 2).T, ['refs_ok', 'buffered'], + ['readwrite'], order='C') + with i: + for x in i: + x[...] = None + vals, i, x = [None]*3 + if HAS_REFCOUNT: + assert_(sys.getrefcount(obj) == rc-1) + assert_equal(a, np.array([None]*4, dtype='O')) + +def test_iter_object_arrays_conversions(): + # Conversions to/from objects + a = np.arange(6, dtype='O') + i = nditer(a, ['refs_ok', 'buffered'], ['readwrite'], + casting='unsafe', op_dtypes='i4') + with i: + for x in i: + x[...] += 1 + assert_equal(a, np.arange(6)+1) + + a = np.arange(6, dtype='i4') + i = nditer(a, ['refs_ok', 'buffered'], ['readwrite'], + casting='unsafe', op_dtypes='O') + with i: + for x in i: + x[...] += 1 + assert_equal(a, np.arange(6)+1) + + # Non-contiguous object array + a = np.zeros((6,), dtype=[('p', 'i1'), ('a', 'O')]) + a = a['a'] + a[:] = np.arange(6) + i = nditer(a, ['refs_ok', 'buffered'], ['readwrite'], + casting='unsafe', op_dtypes='i4') + with i: + for x in i: + x[...] += 1 + assert_equal(a, np.arange(6)+1) + + #Non-contiguous value array + a = np.zeros((6,), dtype=[('p', 'i1'), ('a', 'i4')]) + a = a['a'] + a[:] = np.arange(6) + 98172488 + i = nditer(a, ['refs_ok', 'buffered'], ['readwrite'], + casting='unsafe', op_dtypes='O') + with i: + ob = i[0][()] + if HAS_REFCOUNT: + rc = sys.getrefcount(ob) + for x in i: + x[...] += 1 + if HAS_REFCOUNT: + assert_(sys.getrefcount(ob) == rc-1) + assert_equal(a, np.arange(6)+98172489) + +def test_iter_common_dtype(): + # Check that the iterator finds a common data type correctly + + i = nditer([array([3], dtype='f4'), array([0], dtype='f8')], + ['common_dtype'], + [['readonly', 'copy']]*2, + casting='safe') + assert_equal(i.dtypes[0], np.dtype('f8')) + assert_equal(i.dtypes[1], np.dtype('f8')) + i = nditer([array([3], dtype='i4'), array([0], dtype='f4')], + ['common_dtype'], + [['readonly', 'copy']]*2, + casting='safe') + assert_equal(i.dtypes[0], np.dtype('f8')) + assert_equal(i.dtypes[1], np.dtype('f8')) + i = nditer([array([3], dtype='f4'), array(0, dtype='f8')], + ['common_dtype'], + [['readonly', 'copy']]*2, + casting='same_kind') + assert_equal(i.dtypes[0], np.dtype('f4')) + assert_equal(i.dtypes[1], np.dtype('f4')) + i = nditer([array([3], dtype='u4'), array(0, dtype='i4')], + ['common_dtype'], + [['readonly', 'copy']]*2, + casting='safe') + assert_equal(i.dtypes[0], np.dtype('u4')) + assert_equal(i.dtypes[1], np.dtype('u4')) + i = nditer([array([3], dtype='u4'), array(-12, dtype='i4')], + ['common_dtype'], + [['readonly', 'copy']]*2, + casting='safe') + assert_equal(i.dtypes[0], np.dtype('i8')) + assert_equal(i.dtypes[1], np.dtype('i8')) + i = nditer([array([3], dtype='u4'), array(-12, dtype='i4'), + array([2j], dtype='c8'), array([9], dtype='f8')], + ['common_dtype'], + [['readonly', 'copy']]*4, + casting='safe') + assert_equal(i.dtypes[0], np.dtype('c16')) + assert_equal(i.dtypes[1], np.dtype('c16')) + assert_equal(i.dtypes[2], np.dtype('c16')) + assert_equal(i.dtypes[3], np.dtype('c16')) + assert_equal(i.value, (3, -12, 2j, 9)) + + # When allocating outputs, other outputs aren't factored in + i = nditer([array([3], dtype='i4'), None, array([2j], dtype='c16')], [], + [['readonly', 'copy'], + ['writeonly', 'allocate'], + ['writeonly']], + casting='safe') + assert_equal(i.dtypes[0], np.dtype('i4')) + assert_equal(i.dtypes[1], np.dtype('i4')) + assert_equal(i.dtypes[2], np.dtype('c16')) + # But, if common data types are requested, they are + i = nditer([array([3], dtype='i4'), None, array([2j], dtype='c16')], + ['common_dtype'], + [['readonly', 'copy'], + ['writeonly', 'allocate'], + ['writeonly']], + casting='safe') + assert_equal(i.dtypes[0], np.dtype('c16')) + assert_equal(i.dtypes[1], np.dtype('c16')) + assert_equal(i.dtypes[2], np.dtype('c16')) + +def test_iter_copy_if_overlap(): + # Ensure the iterator makes copies on read/write overlap, if requested + + # Copy not needed, 1 op + for flag in ['readonly', 'writeonly', 'readwrite']: + a = arange(10) + i = nditer([a], ['copy_if_overlap'], [[flag]]) + with i: + assert_(i.operands[0] is a) + + # Copy needed, 2 ops, read-write overlap + x = arange(10) + a = x[1:] + b = x[:-1] + with nditer([a, b], ['copy_if_overlap'], [['readonly'], ['readwrite']]) as i: + assert_(not np.shares_memory(*i.operands)) + + # Copy not needed with elementwise, 2 ops, exactly same arrays + x = arange(10) + a = x + b = x + i = nditer([a, b], ['copy_if_overlap'], [['readonly', 'overlap_assume_elementwise'], + ['readwrite', 'overlap_assume_elementwise']]) + with i: + assert_(i.operands[0] is a and i.operands[1] is b) + with nditer([a, b], ['copy_if_overlap'], [['readonly'], ['readwrite']]) as i: + assert_(i.operands[0] is a and not np.shares_memory(i.operands[1], b)) + + # Copy not needed, 2 ops, no overlap + x = arange(10) + a = x[::2] + b = x[1::2] + i = nditer([a, b], ['copy_if_overlap'], [['readonly'], ['writeonly']]) + assert_(i.operands[0] is a and i.operands[1] is b) + + # Copy needed, 2 ops, read-write overlap + x = arange(4, dtype=np.int8) + a = x[3:] + b = x.view(np.int32)[:1] + with nditer([a, b], ['copy_if_overlap'], [['readonly'], ['writeonly']]) as i: + assert_(not np.shares_memory(*i.operands)) + + # Copy needed, 3 ops, read-write overlap + for flag in ['writeonly', 'readwrite']: + x = np.ones([10, 10]) + a = x + b = x.T + c = x + with nditer([a, b, c], ['copy_if_overlap'], + [['readonly'], ['readonly'], [flag]]) as i: + a2, b2, c2 = i.operands + assert_(not np.shares_memory(a2, c2)) + assert_(not np.shares_memory(b2, c2)) + + # Copy not needed, 3 ops, read-only overlap + x = np.ones([10, 10]) + a = x + b = x.T + c = x + i = nditer([a, b, c], ['copy_if_overlap'], + [['readonly'], ['readonly'], ['readonly']]) + a2, b2, c2 = i.operands + assert_(a is a2) + assert_(b is b2) + assert_(c is c2) + + # Copy not needed, 3 ops, read-only overlap + x = np.ones([10, 10]) + a = x + b = np.ones([10, 10]) + c = x.T + i = nditer([a, b, c], ['copy_if_overlap'], + [['readonly'], ['writeonly'], ['readonly']]) + a2, b2, c2 = i.operands + assert_(a is a2) + assert_(b is b2) + assert_(c is c2) + + # Copy not needed, 3 ops, write-only overlap + x = np.arange(7) + a = x[:3] + b = x[3:6] + c = x[4:7] + i = nditer([a, b, c], ['copy_if_overlap'], + [['readonly'], ['writeonly'], ['writeonly']]) + a2, b2, c2 = i.operands + assert_(a is a2) + assert_(b is b2) + assert_(c is c2) + +def test_iter_op_axes(): + # Check that custom axes work + + # Reverse the axes + a = arange(6).reshape(2, 3) + i = nditer([a, a.T], [], [['readonly']]*2, op_axes=[[0, 1], [1, 0]]) + assert_(all([x == y for (x, y) in i])) + a = arange(24).reshape(2, 3, 4) + i = nditer([a.T, a], [], [['readonly']]*2, op_axes=[[2, 1, 0], None]) + assert_(all([x == y for (x, y) in i])) + + # Broadcast 1D to any dimension + a = arange(1, 31).reshape(2, 3, 5) + b = arange(1, 3) + i = nditer([a, b], [], [['readonly']]*2, op_axes=[None, [0, -1, -1]]) + assert_equal([x*y for (x, y) in i], (a*b.reshape(2, 1, 1)).ravel()) + b = arange(1, 4) + i = nditer([a, b], [], [['readonly']]*2, op_axes=[None, [-1, 0, -1]]) + assert_equal([x*y for (x, y) in i], (a*b.reshape(1, 3, 1)).ravel()) + b = arange(1, 6) + i = nditer([a, b], [], [['readonly']]*2, + op_axes=[None, [np.newaxis, np.newaxis, 0]]) + assert_equal([x*y for (x, y) in i], (a*b.reshape(1, 1, 5)).ravel()) + + # Inner product-style broadcasting + a = arange(24).reshape(2, 3, 4) + b = arange(40).reshape(5, 2, 4) + i = nditer([a, b], ['multi_index'], [['readonly']]*2, + op_axes=[[0, 1, -1, -1], [-1, -1, 0, 1]]) + assert_equal(i.shape, (2, 3, 5, 2)) + + # Matrix product-style broadcasting + a = arange(12).reshape(3, 4) + b = arange(20).reshape(4, 5) + i = nditer([a, b], ['multi_index'], [['readonly']]*2, + op_axes=[[0, -1], [-1, 1]]) + assert_equal(i.shape, (3, 5)) + +def test_iter_op_axes_errors(): + # Check that custom axes throws errors for bad inputs + + # Wrong number of items in op_axes + a = arange(6).reshape(2, 3) + assert_raises(ValueError, nditer, [a, a], [], [['readonly']]*2, + op_axes=[[0], [1], [0]]) + # Out of bounds items in op_axes + assert_raises(ValueError, nditer, [a, a], [], [['readonly']]*2, + op_axes=[[2, 1], [0, 1]]) + assert_raises(ValueError, nditer, [a, a], [], [['readonly']]*2, + op_axes=[[0, 1], [2, -1]]) + # Duplicate items in op_axes + assert_raises(ValueError, nditer, [a, a], [], [['readonly']]*2, + op_axes=[[0, 0], [0, 1]]) + assert_raises(ValueError, nditer, [a, a], [], [['readonly']]*2, + op_axes=[[0, 1], [1, 1]]) + + # Different sized arrays in op_axes + assert_raises(ValueError, nditer, [a, a], [], [['readonly']]*2, + op_axes=[[0, 1], [0, 1, 0]]) + + # Non-broadcastable dimensions in the result + assert_raises(ValueError, nditer, [a, a], [], [['readonly']]*2, + op_axes=[[0, 1], [1, 0]]) + +def test_iter_copy(): + # Check that copying the iterator works correctly + a = arange(24).reshape(2, 3, 4) + + # Simple iterator + i = nditer(a) + j = i.copy() + assert_equal([x[()] for x in i], [x[()] for x in j]) + + i.iterindex = 3 + j = i.copy() + assert_equal([x[()] for x in i], [x[()] for x in j]) + + # Buffered iterator + i = nditer(a, ['buffered', 'ranged'], order='F', buffersize=3) + j = i.copy() + assert_equal([x[()] for x in i], [x[()] for x in j]) + + i.iterindex = 3 + j = i.copy() + assert_equal([x[()] for x in i], [x[()] for x in j]) + + i.iterrange = (3, 9) + j = i.copy() + assert_equal([x[()] for x in i], [x[()] for x in j]) + + i.iterrange = (2, 18) + next(i) + next(i) + j = i.copy() + assert_equal([x[()] for x in i], [x[()] for x in j]) + + # Casting iterator + with nditer(a, ['buffered'], order='F', casting='unsafe', + op_dtypes='f8', buffersize=5) as i: + j = i.copy() + assert_equal([x[()] for x in j], a.ravel(order='F')) + + a = arange(24, dtype='cast->swap + + a = np.arange(10, dtype='f4').newbyteorder().byteswap() + i = nditer(a, ['buffered', 'external_loop'], + [['readwrite', 'nbo', 'aligned']], + casting='same_kind', + op_dtypes=[np.dtype('f8').newbyteorder()], + buffersize=3) + with i: + for v in i: + v[...] *= 2 + + assert_equal(a, 2*np.arange(10, dtype='f4')) + + with suppress_warnings() as sup: + sup.filter(np.ComplexWarning) + + a = np.arange(10, dtype='f8').newbyteorder().byteswap() + i = nditer(a, ['buffered', 'external_loop'], + [['readwrite', 'nbo', 'aligned']], + casting='unsafe', + op_dtypes=[np.dtype('c8').newbyteorder()], + buffersize=3) + with i: + for v in i: + v[...] *= 2 + + assert_equal(a, 2*np.arange(10, dtype='f8')) + +def test_iter_buffered_cast_byteswapped_complex(): + # Test that buffering can handle a cast which requires swap->cast->copy + + a = np.arange(10, dtype='c8').newbyteorder().byteswap() + a += 2j + i = nditer(a, ['buffered', 'external_loop'], + [['readwrite', 'nbo', 'aligned']], + casting='same_kind', + op_dtypes=[np.dtype('c16')], + buffersize=3) + with i: + for v in i: + v[...] *= 2 + assert_equal(a, 2*np.arange(10, dtype='c8') + 4j) + + a = np.arange(10, dtype='c8') + a += 2j + i = nditer(a, ['buffered', 'external_loop'], + [['readwrite', 'nbo', 'aligned']], + casting='same_kind', + op_dtypes=[np.dtype('c16').newbyteorder()], + buffersize=3) + with i: + for v in i: + v[...] *= 2 + assert_equal(a, 2*np.arange(10, dtype='c8') + 4j) + + a = np.arange(10, dtype=np.clongdouble).newbyteorder().byteswap() + a += 2j + i = nditer(a, ['buffered', 'external_loop'], + [['readwrite', 'nbo', 'aligned']], + casting='same_kind', + op_dtypes=[np.dtype('c16')], + buffersize=3) + with i: + for v in i: + v[...] *= 2 + assert_equal(a, 2*np.arange(10, dtype=np.clongdouble) + 4j) + + a = np.arange(10, dtype=np.longdouble).newbyteorder().byteswap() + i = nditer(a, ['buffered', 'external_loop'], + [['readwrite', 'nbo', 'aligned']], + casting='same_kind', + op_dtypes=[np.dtype('f4')], + buffersize=7) + with i: + for v in i: + v[...] *= 2 + assert_equal(a, 2*np.arange(10, dtype=np.longdouble)) + +def test_iter_buffered_cast_structured_type(): + # Tests buffering of structured types + + # simple -> struct type (duplicates the value) + sdt = [('a', 'f4'), ('b', 'i8'), ('c', 'c8', (2, 3)), ('d', 'O')] + a = np.arange(3, dtype='f4') + 0.5 + i = nditer(a, ['buffered', 'refs_ok'], ['readonly'], + casting='unsafe', + op_dtypes=sdt) + vals = [np.array(x) for x in i] + assert_equal(vals[0]['a'], 0.5) + assert_equal(vals[0]['b'], 0) + assert_equal(vals[0]['c'], [[(0.5)]*3]*2) + assert_equal(vals[0]['d'], 0.5) + assert_equal(vals[1]['a'], 1.5) + assert_equal(vals[1]['b'], 1) + assert_equal(vals[1]['c'], [[(1.5)]*3]*2) + assert_equal(vals[1]['d'], 1.5) + assert_equal(vals[0].dtype, np.dtype(sdt)) + + # object -> struct type + sdt = [('a', 'f4'), ('b', 'i8'), ('c', 'c8', (2, 3)), ('d', 'O')] + a = np.zeros((3,), dtype='O') + a[0] = (0.5, 0.5, [[0.5, 0.5, 0.5], [0.5, 0.5, 0.5]], 0.5) + a[1] = (1.5, 1.5, [[1.5, 1.5, 1.5], [1.5, 1.5, 1.5]], 1.5) + a[2] = (2.5, 2.5, [[2.5, 2.5, 2.5], [2.5, 2.5, 2.5]], 2.5) + if HAS_REFCOUNT: + rc = sys.getrefcount(a[0]) + i = nditer(a, ['buffered', 'refs_ok'], ['readonly'], + casting='unsafe', + op_dtypes=sdt) + vals = [x.copy() for x in i] + assert_equal(vals[0]['a'], 0.5) + assert_equal(vals[0]['b'], 0) + assert_equal(vals[0]['c'], [[(0.5)]*3]*2) + assert_equal(vals[0]['d'], 0.5) + assert_equal(vals[1]['a'], 1.5) + assert_equal(vals[1]['b'], 1) + assert_equal(vals[1]['c'], [[(1.5)]*3]*2) + assert_equal(vals[1]['d'], 1.5) + assert_equal(vals[0].dtype, np.dtype(sdt)) + vals, i, x = [None]*3 + if HAS_REFCOUNT: + assert_equal(sys.getrefcount(a[0]), rc) + + # single-field struct type -> simple + sdt = [('a', 'f4')] + a = np.array([(5.5,), (8,)], dtype=sdt) + i = nditer(a, ['buffered', 'refs_ok'], ['readonly'], + casting='unsafe', + op_dtypes='i4') + assert_equal([x_[()] for x_ in i], [5, 8]) + + # make sure multi-field struct type -> simple doesn't work + sdt = [('a', 'f4'), ('b', 'i8'), ('d', 'O')] + a = np.array([(5.5, 7, 'test'), (8, 10, 11)], dtype=sdt) + assert_raises(TypeError, lambda: ( + nditer(a, ['buffered', 'refs_ok'], ['readonly'], + casting='unsafe', + op_dtypes='i4'))) + + # struct type -> struct type (field-wise copy) + sdt1 = [('a', 'f4'), ('b', 'i8'), ('d', 'O')] + sdt2 = [('d', 'u2'), ('a', 'O'), ('b', 'f8')] + a = np.array([(1, 2, 3), (4, 5, 6)], dtype=sdt1) + i = nditer(a, ['buffered', 'refs_ok'], ['readonly'], + casting='unsafe', + op_dtypes=sdt2) + assert_equal(i[0].dtype, np.dtype(sdt2)) + assert_equal([np.array(x_) for x_ in i], + [np.array((1, 2, 3), dtype=sdt2), + np.array((4, 5, 6), dtype=sdt2)]) + + # make sure struct type -> struct type with different + # number of fields fails + sdt1 = [('a', 'f4'), ('b', 'i8'), ('d', 'O')] + sdt2 = [('b', 'O'), ('a', 'f8')] + a = np.array([(1, 2, 3), (4, 5, 6)], dtype=sdt1) + + assert_raises(ValueError, lambda : ( + nditer(a, ['buffered', 'refs_ok'], ['readwrite'], + casting='unsafe', + op_dtypes=sdt2))) + + +def test_iter_buffered_cast_subarray(): + # Tests buffering of subarrays + + # one element -> many (copies it to all) + sdt1 = [('a', 'f4')] + sdt2 = [('a', 'f8', (3, 2, 2))] + a = np.zeros((6,), dtype=sdt1) + a['a'] = np.arange(6) + i = nditer(a, ['buffered', 'refs_ok'], ['readonly'], + casting='unsafe', + op_dtypes=sdt2) + assert_equal(i[0].dtype, np.dtype(sdt2)) + for x, count in zip(i, list(range(6))): + assert_(np.all(x['a'] == count)) + + # one element -> many -> back (copies it to all) + sdt1 = [('a', 'O', (1, 1))] + sdt2 = [('a', 'O', (3, 2, 2))] + a = np.zeros((6,), dtype=sdt1) + a['a'][:, 0, 0] = np.arange(6) + i = nditer(a, ['buffered', 'refs_ok'], ['readwrite'], + casting='unsafe', + op_dtypes=sdt2) + with i: + assert_equal(i[0].dtype, np.dtype(sdt2)) + count = 0 + for x in i: + assert_(np.all(x['a'] == count)) + x['a'][0] += 2 + count += 1 + assert_equal(a['a'], np.arange(6).reshape(6, 1, 1)+2) + + # many -> one element -> back (copies just element 0) + sdt1 = [('a', 'O', (3, 2, 2))] + sdt2 = [('a', 'O', (1,))] + a = np.zeros((6,), dtype=sdt1) + a['a'][:, 0, 0, 0] = np.arange(6) + i = nditer(a, ['buffered', 'refs_ok'], ['readwrite'], + casting='unsafe', + op_dtypes=sdt2) + with i: + assert_equal(i[0].dtype, np.dtype(sdt2)) + count = 0 + for x in i: + assert_equal(x['a'], count) + x['a'] += 2 + count += 1 + assert_equal(a['a'], np.arange(6).reshape(6, 1, 1, 1)*np.ones((1, 3, 2, 2))+2) + + # many -> one element -> back (copies just element 0) + sdt1 = [('a', 'f8', (3, 2, 2))] + sdt2 = [('a', 'O', (1,))] + a = np.zeros((6,), dtype=sdt1) + a['a'][:, 0, 0, 0] = np.arange(6) + i = nditer(a, ['buffered', 'refs_ok'], ['readonly'], + casting='unsafe', + op_dtypes=sdt2) + assert_equal(i[0].dtype, np.dtype(sdt2)) + count = 0 + for x in i: + assert_equal(x['a'], count) + count += 1 + + # many -> one element (copies just element 0) + sdt1 = [('a', 'O', (3, 2, 2))] + sdt2 = [('a', 'f4', (1,))] + a = np.zeros((6,), dtype=sdt1) + a['a'][:, 0, 0, 0] = np.arange(6) + i = nditer(a, ['buffered', 'refs_ok'], ['readonly'], + casting='unsafe', + op_dtypes=sdt2) + assert_equal(i[0].dtype, np.dtype(sdt2)) + count = 0 + for x in i: + assert_equal(x['a'], count) + count += 1 + + # many -> matching shape (straightforward copy) + sdt1 = [('a', 'O', (3, 2, 2))] + sdt2 = [('a', 'f4', (3, 2, 2))] + a = np.zeros((6,), dtype=sdt1) + a['a'] = np.arange(6*3*2*2).reshape(6, 3, 2, 2) + i = nditer(a, ['buffered', 'refs_ok'], ['readonly'], + casting='unsafe', + op_dtypes=sdt2) + assert_equal(i[0].dtype, np.dtype(sdt2)) + count = 0 + for x in i: + assert_equal(x['a'], a[count]['a']) + count += 1 + + # vector -> smaller vector (truncates) + sdt1 = [('a', 'f8', (6,))] + sdt2 = [('a', 'f4', (2,))] + a = np.zeros((6,), dtype=sdt1) + a['a'] = np.arange(6*6).reshape(6, 6) + i = nditer(a, ['buffered', 'refs_ok'], ['readonly'], + casting='unsafe', + op_dtypes=sdt2) + assert_equal(i[0].dtype, np.dtype(sdt2)) + count = 0 + for x in i: + assert_equal(x['a'], a[count]['a'][:2]) + count += 1 + + # vector -> bigger vector (pads with zeros) + sdt1 = [('a', 'f8', (2,))] + sdt2 = [('a', 'f4', (6,))] + a = np.zeros((6,), dtype=sdt1) + a['a'] = np.arange(6*2).reshape(6, 2) + i = nditer(a, ['buffered', 'refs_ok'], ['readonly'], + casting='unsafe', + op_dtypes=sdt2) + assert_equal(i[0].dtype, np.dtype(sdt2)) + count = 0 + for x in i: + assert_equal(x['a'][:2], a[count]['a']) + assert_equal(x['a'][2:], [0, 0, 0, 0]) + count += 1 + + # vector -> matrix (broadcasts) + sdt1 = [('a', 'f8', (2,))] + sdt2 = [('a', 'f4', (2, 2))] + a = np.zeros((6,), dtype=sdt1) + a['a'] = np.arange(6*2).reshape(6, 2) + i = nditer(a, ['buffered', 'refs_ok'], ['readonly'], + casting='unsafe', + op_dtypes=sdt2) + assert_equal(i[0].dtype, np.dtype(sdt2)) + count = 0 + for x in i: + assert_equal(x['a'][0], a[count]['a']) + assert_equal(x['a'][1], a[count]['a']) + count += 1 + + # vector -> matrix (broadcasts and zero-pads) + sdt1 = [('a', 'f8', (2, 1))] + sdt2 = [('a', 'f4', (3, 2))] + a = np.zeros((6,), dtype=sdt1) + a['a'] = np.arange(6*2).reshape(6, 2, 1) + i = nditer(a, ['buffered', 'refs_ok'], ['readonly'], + casting='unsafe', + op_dtypes=sdt2) + assert_equal(i[0].dtype, np.dtype(sdt2)) + count = 0 + for x in i: + assert_equal(x['a'][:2, 0], a[count]['a'][:, 0]) + assert_equal(x['a'][:2, 1], a[count]['a'][:, 0]) + assert_equal(x['a'][2,:], [0, 0]) + count += 1 + + # matrix -> matrix (truncates and zero-pads) + sdt1 = [('a', 'f8', (2, 3))] + sdt2 = [('a', 'f4', (3, 2))] + a = np.zeros((6,), dtype=sdt1) + a['a'] = np.arange(6*2*3).reshape(6, 2, 3) + i = nditer(a, ['buffered', 'refs_ok'], ['readonly'], + casting='unsafe', + op_dtypes=sdt2) + assert_equal(i[0].dtype, np.dtype(sdt2)) + count = 0 + for x in i: + assert_equal(x['a'][:2, 0], a[count]['a'][:, 0]) + assert_equal(x['a'][:2, 1], a[count]['a'][:, 1]) + assert_equal(x['a'][2,:], [0, 0]) + count += 1 + +def test_iter_buffering_badwriteback(): + # Writing back from a buffer cannot combine elements + + # a needs write buffering, but had a broadcast dimension + a = np.arange(6).reshape(2, 3, 1) + b = np.arange(12).reshape(2, 3, 2) + assert_raises(ValueError, nditer, [a, b], + ['buffered', 'external_loop'], + [['readwrite'], ['writeonly']], + order='C') + + # But if a is readonly, it's fine + nditer([a, b], ['buffered', 'external_loop'], + [['readonly'], ['writeonly']], + order='C') + + # If a has just one element, it's fine too (constant 0 stride, a reduction) + a = np.arange(1).reshape(1, 1, 1) + nditer([a, b], ['buffered', 'external_loop', 'reduce_ok'], + [['readwrite'], ['writeonly']], + order='C') + + # check that it fails on other dimensions too + a = np.arange(6).reshape(1, 3, 2) + assert_raises(ValueError, nditer, [a, b], + ['buffered', 'external_loop'], + [['readwrite'], ['writeonly']], + order='C') + a = np.arange(4).reshape(2, 1, 2) + assert_raises(ValueError, nditer, [a, b], + ['buffered', 'external_loop'], + [['readwrite'], ['writeonly']], + order='C') + +def test_iter_buffering_string(): + # Safe casting disallows shrinking strings + a = np.array(['abc', 'a', 'abcd'], dtype=np.bytes_) + assert_equal(a.dtype, np.dtype('S4')) + assert_raises(TypeError, nditer, a, ['buffered'], ['readonly'], + op_dtypes='S2') + i = nditer(a, ['buffered'], ['readonly'], op_dtypes='S6') + assert_equal(i[0], b'abc') + assert_equal(i[0].dtype, np.dtype('S6')) + + a = np.array(['abc', 'a', 'abcd'], dtype=np.unicode_) + assert_equal(a.dtype, np.dtype('U4')) + assert_raises(TypeError, nditer, a, ['buffered'], ['readonly'], + op_dtypes='U2') + i = nditer(a, ['buffered'], ['readonly'], op_dtypes='U6') + assert_equal(i[0], u'abc') + assert_equal(i[0].dtype, np.dtype('U6')) + +def test_iter_buffering_growinner(): + # Test that the inner loop grows when no buffering is needed + a = np.arange(30) + i = nditer(a, ['buffered', 'growinner', 'external_loop'], + buffersize=5) + # Should end up with just one inner loop here + assert_equal(i[0].size, a.size) + + +@pytest.mark.slow +def test_iter_buffered_reduce_reuse(): + # large enough array for all views, including negative strides. + a = np.arange(2*3**5)[3**5:3**5+1] + flags = ['buffered', 'delay_bufalloc', 'multi_index', 'reduce_ok', 'refs_ok'] + op_flags = [('readonly',), ('readwrite', 'allocate')] + op_axes_list = [[(0, 1, 2), (0, 1, -1)], [(0, 1, 2), (0, -1, -1)]] + # wrong dtype to force buffering + op_dtypes = [float, a.dtype] + + def get_params(): + for xs in range(-3**2, 3**2 + 1): + for ys in range(xs, 3**2 + 1): + for op_axes in op_axes_list: + # last stride is reduced and because of that not + # important for this test, as it is the inner stride. + strides = (xs * a.itemsize, ys * a.itemsize, a.itemsize) + arr = np.lib.stride_tricks.as_strided(a, (3, 3, 3), strides) + + for skip in [0, 1]: + yield arr, op_axes, skip + + for arr, op_axes, skip in get_params(): + nditer2 = np.nditer([arr.copy(), None], + op_axes=op_axes, flags=flags, op_flags=op_flags, + op_dtypes=op_dtypes) + with nditer2: + nditer2.operands[-1][...] = 0 + nditer2.reset() + nditer2.iterindex = skip + + for (a2_in, b2_in) in nditer2: + b2_in += a2_in.astype(np.int_) + + comp_res = nditer2.operands[-1] + + for bufsize in range(0, 3**3): + nditer1 = np.nditer([arr, None], + op_axes=op_axes, flags=flags, op_flags=op_flags, + buffersize=bufsize, op_dtypes=op_dtypes) + with nditer1: + nditer1.operands[-1][...] = 0 + nditer1.reset() + nditer1.iterindex = skip + + for (a1_in, b1_in) in nditer1: + b1_in += a1_in.astype(np.int_) + + res = nditer1.operands[-1] + assert_array_equal(res, comp_res) + + +def test_iter_no_broadcast(): + # Test that the no_broadcast flag works + a = np.arange(24).reshape(2, 3, 4) + b = np.arange(6).reshape(2, 3, 1) + c = np.arange(12).reshape(3, 4) + + nditer([a, b, c], [], + [['readonly', 'no_broadcast'], + ['readonly'], ['readonly']]) + assert_raises(ValueError, nditer, [a, b, c], [], + [['readonly'], ['readonly', 'no_broadcast'], ['readonly']]) + assert_raises(ValueError, nditer, [a, b, c], [], + [['readonly'], ['readonly'], ['readonly', 'no_broadcast']]) + + +class TestIterNested: + + def test_basic(self): + # Test nested iteration basic usage + a = arange(12).reshape(2, 3, 2) + + i, j = np.nested_iters(a, [[0], [1, 2]]) + vals = [list(j) for _ in i] + assert_equal(vals, [[0, 1, 2, 3, 4, 5], [6, 7, 8, 9, 10, 11]]) + + i, j = np.nested_iters(a, [[0, 1], [2]]) + vals = [list(j) for _ in i] + assert_equal(vals, [[0, 1], [2, 3], [4, 5], [6, 7], [8, 9], [10, 11]]) + + i, j = np.nested_iters(a, [[0, 2], [1]]) + vals = [list(j) for _ in i] + assert_equal(vals, [[0, 2, 4], [1, 3, 5], [6, 8, 10], [7, 9, 11]]) + + def test_reorder(self): + # Test nested iteration basic usage + a = arange(12).reshape(2, 3, 2) + + # In 'K' order (default), it gets reordered + i, j = np.nested_iters(a, [[0], [2, 1]]) + vals = [list(j) for _ in i] + assert_equal(vals, [[0, 1, 2, 3, 4, 5], [6, 7, 8, 9, 10, 11]]) + + i, j = np.nested_iters(a, [[1, 0], [2]]) + vals = [list(j) for _ in i] + assert_equal(vals, [[0, 1], [2, 3], [4, 5], [6, 7], [8, 9], [10, 11]]) + + i, j = np.nested_iters(a, [[2, 0], [1]]) + vals = [list(j) for _ in i] + assert_equal(vals, [[0, 2, 4], [1, 3, 5], [6, 8, 10], [7, 9, 11]]) + + # In 'C' order, it doesn't + i, j = np.nested_iters(a, [[0], [2, 1]], order='C') + vals = [list(j) for _ in i] + assert_equal(vals, [[0, 2, 4, 1, 3, 5], [6, 8, 10, 7, 9, 11]]) + + i, j = np.nested_iters(a, [[1, 0], [2]], order='C') + vals = [list(j) for _ in i] + assert_equal(vals, [[0, 1], [6, 7], [2, 3], [8, 9], [4, 5], [10, 11]]) + + i, j = np.nested_iters(a, [[2, 0], [1]], order='C') + vals = [list(j) for _ in i] + assert_equal(vals, [[0, 2, 4], [6, 8, 10], [1, 3, 5], [7, 9, 11]]) + + def test_flip_axes(self): + # Test nested iteration with negative axes + a = arange(12).reshape(2, 3, 2)[::-1, ::-1, ::-1] + + # In 'K' order (default), the axes all get flipped + i, j = np.nested_iters(a, [[0], [1, 2]]) + vals = [list(j) for _ in i] + assert_equal(vals, [[0, 1, 2, 3, 4, 5], [6, 7, 8, 9, 10, 11]]) + + i, j = np.nested_iters(a, [[0, 1], [2]]) + vals = [list(j) for _ in i] + assert_equal(vals, [[0, 1], [2, 3], [4, 5], [6, 7], [8, 9], [10, 11]]) + + i, j = np.nested_iters(a, [[0, 2], [1]]) + vals = [list(j) for _ in i] + assert_equal(vals, [[0, 2, 4], [1, 3, 5], [6, 8, 10], [7, 9, 11]]) + + # In 'C' order, flipping axes is disabled + i, j = np.nested_iters(a, [[0], [1, 2]], order='C') + vals = [list(j) for _ in i] + assert_equal(vals, [[11, 10, 9, 8, 7, 6], [5, 4, 3, 2, 1, 0]]) + + i, j = np.nested_iters(a, [[0, 1], [2]], order='C') + vals = [list(j) for _ in i] + assert_equal(vals, [[11, 10], [9, 8], [7, 6], [5, 4], [3, 2], [1, 0]]) + + i, j = np.nested_iters(a, [[0, 2], [1]], order='C') + vals = [list(j) for _ in i] + assert_equal(vals, [[11, 9, 7], [10, 8, 6], [5, 3, 1], [4, 2, 0]]) + + def test_broadcast(self): + # Test nested iteration with broadcasting + a = arange(2).reshape(2, 1) + b = arange(3).reshape(1, 3) + + i, j = np.nested_iters([a, b], [[0], [1]]) + vals = [list(j) for _ in i] + assert_equal(vals, [[[0, 0], [0, 1], [0, 2]], [[1, 0], [1, 1], [1, 2]]]) + + i, j = np.nested_iters([a, b], [[1], [0]]) + vals = [list(j) for _ in i] + assert_equal(vals, [[[0, 0], [1, 0]], [[0, 1], [1, 1]], [[0, 2], [1, 2]]]) + + def test_dtype_copy(self): + # Test nested iteration with a copy to change dtype + + # copy + a = arange(6, dtype='i4').reshape(2, 3) + i, j = np.nested_iters(a, [[0], [1]], + op_flags=['readonly', 'copy'], + op_dtypes='f8') + assert_equal(j[0].dtype, np.dtype('f8')) + vals = [list(j) for _ in i] + assert_equal(vals, [[0, 1, 2], [3, 4, 5]]) + vals = None + + # writebackifcopy - using context manager + a = arange(6, dtype='f4').reshape(2, 3) + i, j = np.nested_iters(a, [[0], [1]], + op_flags=['readwrite', 'updateifcopy'], + casting='same_kind', + op_dtypes='f8') + with i, j: + assert_equal(j[0].dtype, np.dtype('f8')) + for x in i: + for y in j: + y[...] += 1 + assert_equal(a, [[0, 1, 2], [3, 4, 5]]) + assert_equal(a, [[1, 2, 3], [4, 5, 6]]) + + # writebackifcopy - using close() + a = arange(6, dtype='f4').reshape(2, 3) + i, j = np.nested_iters(a, [[0], [1]], + op_flags=['readwrite', 'updateifcopy'], + casting='same_kind', + op_dtypes='f8') + assert_equal(j[0].dtype, np.dtype('f8')) + for x in i: + for y in j: + y[...] += 1 + assert_equal(a, [[0, 1, 2], [3, 4, 5]]) + i.close() + j.close() + assert_equal(a, [[1, 2, 3], [4, 5, 6]]) + + def test_dtype_buffered(self): + # Test nested iteration with buffering to change dtype + + a = arange(6, dtype='f4').reshape(2, 3) + i, j = np.nested_iters(a, [[0], [1]], + flags=['buffered'], + op_flags=['readwrite'], + casting='same_kind', + op_dtypes='f8') + assert_equal(j[0].dtype, np.dtype('f8')) + for x in i: + for y in j: + y[...] += 1 + assert_equal(a, [[1, 2, 3], [4, 5, 6]]) + + def test_0d(self): + a = np.arange(12).reshape(2, 3, 2) + i, j = np.nested_iters(a, [[], [1, 0, 2]]) + vals = [list(j) for _ in i] + assert_equal(vals, [[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]]) + + i, j = np.nested_iters(a, [[1, 0, 2], []]) + vals = [list(j) for _ in i] + assert_equal(vals, [[0], [1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11]]) + + i, j, k = np.nested_iters(a, [[2, 0], [], [1]]) + vals = [] + for x in i: + for y in j: + vals.append([z for z in k]) + assert_equal(vals, [[0, 2, 4], [1, 3, 5], [6, 8, 10], [7, 9, 11]]) + + def test_iter_nested_iters_dtype_buffered(self): + # Test nested iteration with buffering to change dtype + + a = arange(6, dtype='f4').reshape(2, 3) + i, j = np.nested_iters(a, [[0], [1]], + flags=['buffered'], + op_flags=['readwrite'], + casting='same_kind', + op_dtypes='f8') + with i, j: + assert_equal(j[0].dtype, np.dtype('f8')) + for x in i: + for y in j: + y[...] += 1 + assert_equal(a, [[1, 2, 3], [4, 5, 6]]) + +def test_iter_reduction_error(): + + a = np.arange(6) + assert_raises(ValueError, nditer, [a, None], [], + [['readonly'], ['readwrite', 'allocate']], + op_axes=[[0], [-1]]) + + a = np.arange(6).reshape(2, 3) + assert_raises(ValueError, nditer, [a, None], ['external_loop'], + [['readonly'], ['readwrite', 'allocate']], + op_axes=[[0, 1], [-1, -1]]) + +def test_iter_reduction(): + # Test doing reductions with the iterator + + a = np.arange(6) + i = nditer([a, None], ['reduce_ok'], + [['readonly'], ['readwrite', 'allocate']], + op_axes=[[0], [-1]]) + # Need to initialize the output operand to the addition unit + with i: + i.operands[1][...] = 0 + # Do the reduction + for x, y in i: + y[...] += x + # Since no axes were specified, should have allocated a scalar + assert_equal(i.operands[1].ndim, 0) + assert_equal(i.operands[1], np.sum(a)) + + a = np.arange(6).reshape(2, 3) + i = nditer([a, None], ['reduce_ok', 'external_loop'], + [['readonly'], ['readwrite', 'allocate']], + op_axes=[[0, 1], [-1, -1]]) + # Need to initialize the output operand to the addition unit + with i: + i.operands[1][...] = 0 + # Reduction shape/strides for the output + assert_equal(i[1].shape, (6,)) + assert_equal(i[1].strides, (0,)) + # Do the reduction + for x, y in i: + # Use a for loop instead of ``y[...] += x`` + # (equivalent to ``y[...] = y[...].copy() + x``), + # because y has zero strides we use for the reduction + for j in range(len(y)): + y[j] += x[j] + # Since no axes were specified, should have allocated a scalar + assert_equal(i.operands[1].ndim, 0) + assert_equal(i.operands[1], np.sum(a)) + + # This is a tricky reduction case for the buffering double loop + # to handle + a = np.ones((2, 3, 5)) + it1 = nditer([a, None], ['reduce_ok', 'external_loop'], + [['readonly'], ['readwrite', 'allocate']], + op_axes=[None, [0, -1, 1]]) + it2 = nditer([a, None], ['reduce_ok', 'external_loop', + 'buffered', 'delay_bufalloc'], + [['readonly'], ['readwrite', 'allocate']], + op_axes=[None, [0, -1, 1]], buffersize=10) + with it1, it2: + it1.operands[1].fill(0) + it2.operands[1].fill(0) + it2.reset() + for x in it1: + x[1][...] += x[0] + for x in it2: + x[1][...] += x[0] + assert_equal(it1.operands[1], it2.operands[1]) + assert_equal(it2.operands[1].sum(), a.size) + +def test_iter_buffering_reduction(): + # Test doing buffered reductions with the iterator + + a = np.arange(6) + b = np.array(0., dtype='f8').byteswap().newbyteorder() + i = nditer([a, b], ['reduce_ok', 'buffered'], + [['readonly'], ['readwrite', 'nbo']], + op_axes=[[0], [-1]]) + with i: + assert_equal(i[1].dtype, np.dtype('f8')) + assert_(i[1].dtype != b.dtype) + # Do the reduction + for x, y in i: + y[...] += x + # Since no axes were specified, should have allocated a scalar + assert_equal(b, np.sum(a)) + + a = np.arange(6).reshape(2, 3) + b = np.array([0, 0], dtype='f8').byteswap().newbyteorder() + i = nditer([a, b], ['reduce_ok', 'external_loop', 'buffered'], + [['readonly'], ['readwrite', 'nbo']], + op_axes=[[0, 1], [0, -1]]) + # Reduction shape/strides for the output + with i: + assert_equal(i[1].shape, (3,)) + assert_equal(i[1].strides, (0,)) + # Do the reduction + for x, y in i: + # Use a for loop instead of ``y[...] += x`` + # (equivalent to ``y[...] = y[...].copy() + x``), + # because y has zero strides we use for the reduction + for j in range(len(y)): + y[j] += x[j] + assert_equal(b, np.sum(a, axis=1)) + + # Iterator inner double loop was wrong on this one + p = np.arange(2) + 1 + it = np.nditer([p, None], + ['delay_bufalloc', 'reduce_ok', 'buffered', 'external_loop'], + [['readonly'], ['readwrite', 'allocate']], + op_axes=[[-1, 0], [-1, -1]], + itershape=(2, 2)) + with it: + it.operands[1].fill(0) + it.reset() + assert_equal(it[0], [1, 2, 1, 2]) + + # Iterator inner loop should take argument contiguity into account + x = np.ones((7, 13, 8), np.int8)[4:6,1:11:6,1:5].transpose(1, 2, 0) + x[...] = np.arange(x.size).reshape(x.shape) + y_base = np.arange(4*4, dtype=np.int8).reshape(4, 4) + y_base_copy = y_base.copy() + y = y_base[::2,:,None] + + it = np.nditer([y, x], + ['buffered', 'external_loop', 'reduce_ok'], + [['readwrite'], ['readonly']]) + with it: + for a, b in it: + a.fill(2) + + assert_equal(y_base[1::2], y_base_copy[1::2]) + assert_equal(y_base[::2], 2) + +def test_iter_buffering_reduction_reuse_reduce_loops(): + # There was a bug triggering reuse of the reduce loop inappropriately, + # which caused processing to happen in unnecessarily small chunks + # and overran the buffer. + + a = np.zeros((2, 7)) + b = np.zeros((1, 7)) + it = np.nditer([a, b], flags=['reduce_ok', 'external_loop', 'buffered'], + op_flags=[['readonly'], ['readwrite']], + buffersize=5) + + with it: + bufsizes = [x.shape[0] for x, y in it] + assert_equal(bufsizes, [5, 2, 5, 2]) + assert_equal(sum(bufsizes), a.size) + +def test_iter_writemasked_badinput(): + a = np.zeros((2, 3)) + b = np.zeros((3,)) + m = np.array([[True, True, False], [False, True, False]]) + m2 = np.array([True, True, False]) + m3 = np.array([0, 1, 1], dtype='u1') + mbad1 = np.array([0, 1, 1], dtype='i1') + mbad2 = np.array([0, 1, 1], dtype='f4') + + # Need an 'arraymask' if any operand is 'writemasked' + assert_raises(ValueError, nditer, [a, m], [], + [['readwrite', 'writemasked'], ['readonly']]) + + # A 'writemasked' operand must not be readonly + assert_raises(ValueError, nditer, [a, m], [], + [['readonly', 'writemasked'], ['readonly', 'arraymask']]) + + # 'writemasked' and 'arraymask' may not be used together + assert_raises(ValueError, nditer, [a, m], [], + [['readonly'], ['readwrite', 'arraymask', 'writemasked']]) + + # 'arraymask' may only be specified once + assert_raises(ValueError, nditer, [a, m, m2], [], + [['readwrite', 'writemasked'], + ['readonly', 'arraymask'], + ['readonly', 'arraymask']]) + + # An 'arraymask' with nothing 'writemasked' also doesn't make sense + assert_raises(ValueError, nditer, [a, m], [], + [['readwrite'], ['readonly', 'arraymask']]) + + # A writemasked reduction requires a similarly smaller mask + assert_raises(ValueError, nditer, [a, b, m], ['reduce_ok'], + [['readonly'], + ['readwrite', 'writemasked'], + ['readonly', 'arraymask']]) + # But this should work with a smaller/equal mask to the reduction operand + np.nditer([a, b, m2], ['reduce_ok'], + [['readonly'], + ['readwrite', 'writemasked'], + ['readonly', 'arraymask']]) + # The arraymask itself cannot be a reduction + assert_raises(ValueError, nditer, [a, b, m2], ['reduce_ok'], + [['readonly'], + ['readwrite', 'writemasked'], + ['readwrite', 'arraymask']]) + + # A uint8 mask is ok too + np.nditer([a, m3], ['buffered'], + [['readwrite', 'writemasked'], + ['readonly', 'arraymask']], + op_dtypes=['f4', None], + casting='same_kind') + # An int8 mask isn't ok + assert_raises(TypeError, np.nditer, [a, mbad1], ['buffered'], + [['readwrite', 'writemasked'], + ['readonly', 'arraymask']], + op_dtypes=['f4', None], + casting='same_kind') + # A float32 mask isn't ok + assert_raises(TypeError, np.nditer, [a, mbad2], ['buffered'], + [['readwrite', 'writemasked'], + ['readonly', 'arraymask']], + op_dtypes=['f4', None], + casting='same_kind') + +def test_iter_writemasked(): + a = np.zeros((3,), dtype='f8') + msk = np.array([True, True, False]) + + # When buffering is unused, 'writemasked' effectively does nothing. + # It's up to the user of the iterator to obey the requested semantics. + it = np.nditer([a, msk], [], + [['readwrite', 'writemasked'], + ['readonly', 'arraymask']]) + with it: + for x, m in it: + x[...] = 1 + # Because we violated the semantics, all the values became 1 + assert_equal(a, [1, 1, 1]) + + # Even if buffering is enabled, we still may be accessing the array + # directly. + it = np.nditer([a, msk], ['buffered'], + [['readwrite', 'writemasked'], + ['readonly', 'arraymask']]) + with it: + for x, m in it: + x[...] = 2.5 + # Because we violated the semantics, all the values became 2.5 + assert_equal(a, [2.5, 2.5, 2.5]) + + # If buffering will definitely happening, for instance because of + # a cast, only the items selected by the mask will be copied back from + # the buffer. + it = np.nditer([a, msk], ['buffered'], + [['readwrite', 'writemasked'], + ['readonly', 'arraymask']], + op_dtypes=['i8', None], + casting='unsafe') + with it: + for x, m in it: + x[...] = 3 + # Even though we violated the semantics, only the selected values + # were copied back + assert_equal(a, [3, 3, 2.5]) + +def test_iter_non_writable_attribute_deletion(): + it = np.nditer(np.ones(2)) + attr = ["value", "shape", "operands", "itviews", "has_delayed_bufalloc", + "iterationneedsapi", "has_multi_index", "has_index", "dtypes", + "ndim", "nop", "itersize", "finished"] + + for s in attr: + assert_raises(AttributeError, delattr, it, s) + + +def test_iter_writable_attribute_deletion(): + it = np.nditer(np.ones(2)) + attr = [ "multi_index", "index", "iterrange", "iterindex"] + for s in attr: + assert_raises(AttributeError, delattr, it, s) + + +def test_iter_element_deletion(): + it = np.nditer(np.ones(3)) + try: + del it[1] + del it[1:2] + except TypeError: + pass + except Exception: + raise AssertionError + +def test_iter_allocated_array_dtypes(): + # If the dtype of an allocated output has a shape, the shape gets + # tacked onto the end of the result. + it = np.nditer(([1, 3, 20], None), op_dtypes=[None, ('i4', (2,))]) + for a, b in it: + b[0] = a - 1 + b[1] = a + 1 + assert_equal(it.operands[1], [[0, 2], [2, 4], [19, 21]]) + + # Check the same (less sensitive) thing when `op_axes` with -1 is given. + it = np.nditer(([[1, 3, 20]], None), op_dtypes=[None, ('i4', (2,))], + flags=["reduce_ok"], op_axes=[None, (-1, 0)]) + for a, b in it: + b[0] = a - 1 + b[1] = a + 1 + assert_equal(it.operands[1], [[0, 2], [2, 4], [19, 21]]) + + # Make sure this works for scalars too + it = np.nditer((10, 2, None), op_dtypes=[None, None, ('i4', (2, 2))]) + for a, b, c in it: + c[0, 0] = a - b + c[0, 1] = a + b + c[1, 0] = a * b + c[1, 1] = a / b + assert_equal(it.operands[2], [[8, 12], [20, 5]]) + + +def test_0d_iter(): + # Basic test for iteration of 0-d arrays: + i = nditer([2, 3], ['multi_index'], [['readonly']]*2) + assert_equal(i.ndim, 0) + assert_equal(next(i), (2, 3)) + assert_equal(i.multi_index, ()) + assert_equal(i.iterindex, 0) + assert_raises(StopIteration, next, i) + # test reset: + i.reset() + assert_equal(next(i), (2, 3)) + assert_raises(StopIteration, next, i) + + # test forcing to 0-d + i = nditer(np.arange(5), ['multi_index'], [['readonly']], op_axes=[()]) + assert_equal(i.ndim, 0) + assert_equal(len(i), 1) + + i = nditer(np.arange(5), ['multi_index'], [['readonly']], + op_axes=[()], itershape=()) + assert_equal(i.ndim, 0) + assert_equal(len(i), 1) + + # passing an itershape alone is not enough, the op_axes are also needed + with assert_raises(ValueError): + nditer(np.arange(5), ['multi_index'], [['readonly']], itershape=()) + + # Test a more complex buffered casting case (same as another test above) + sdt = [('a', 'f4'), ('b', 'i8'), ('c', 'c8', (2, 3)), ('d', 'O')] + a = np.array(0.5, dtype='f4') + i = nditer(a, ['buffered', 'refs_ok'], ['readonly'], + casting='unsafe', op_dtypes=sdt) + vals = next(i) + assert_equal(vals['a'], 0.5) + assert_equal(vals['b'], 0) + assert_equal(vals['c'], [[(0.5)]*3]*2) + assert_equal(vals['d'], 0.5) + +def test_object_iter_cleanup(): + # see gh-18450 + # object arrays can raise a python exception in ufunc inner loops using + # nditer, which should cause iteration to stop & cleanup. There were bugs + # in the nditer cleanup when decref'ing object arrays. + # This test would trigger valgrind "uninitialized read" before the bugfix. + assert_raises(TypeError, lambda: np.zeros((17000, 2), dtype='f4') * None) + + # this more explicit code also triggers the invalid access + arr = np.arange(np.BUFSIZE * 10).reshape(10, -1).astype(str) + oarr = arr.astype(object) + oarr[:, -1] = None + assert_raises(TypeError, lambda: np.add(oarr[:, ::-1], arr[:, ::-1])) + + # followup: this tests for a bug introduced in the first pass of gh-18450, + # caused by an incorrect fallthrough of the TypeError + class T: + def __bool__(self): + raise TypeError("Ambiguous") + assert_raises(TypeError, np.logical_or.reduce, + np.array([T(), T()], dtype='O')) + +def test_iter_too_large(): + # The total size of the iterator must not exceed the maximum intp due + # to broadcasting. Dividing by 1024 will keep it small enough to + # give a legal array. + size = np.iinfo(np.intp).max // 1024 + arr = np.lib.stride_tricks.as_strided(np.zeros(1), (size,), (0,)) + assert_raises(ValueError, nditer, (arr, arr[:, None])) + # test the same for multiindex. That may get more interesting when + # removing 0 dimensional axis is allowed (since an iterator can grow then) + assert_raises(ValueError, nditer, + (arr, arr[:, None]), flags=['multi_index']) + + +def test_iter_too_large_with_multiindex(): + # When a multi index is being tracked, the error is delayed this + # checks the delayed error messages and getting below that by + # removing an axis. + base_size = 2**10 + num = 1 + while base_size**num < np.iinfo(np.intp).max: + num += 1 + + shape_template = [1, 1] * num + arrays = [] + for i in range(num): + shape = shape_template[:] + shape[i * 2] = 2**10 + arrays.append(np.empty(shape)) + arrays = tuple(arrays) + + # arrays are now too large to be broadcast. The different modes test + # different nditer functionality with or without GIL. + for mode in range(6): + with assert_raises(ValueError): + _multiarray_tests.test_nditer_too_large(arrays, -1, mode) + # but if we do nothing with the nditer, it can be constructed: + _multiarray_tests.test_nditer_too_large(arrays, -1, 7) + + # When an axis is removed, things should work again (half the time): + for i in range(num): + for mode in range(6): + # an axis with size 1024 is removed: + _multiarray_tests.test_nditer_too_large(arrays, i*2, mode) + # an axis with size 1 is removed: + with assert_raises(ValueError): + _multiarray_tests.test_nditer_too_large(arrays, i*2 + 1, mode) + +def test_writebacks(): + a = np.arange(6, dtype='f4') + au = a.byteswap().newbyteorder() + assert_(a.dtype.byteorder != au.dtype.byteorder) + it = nditer(au, [], [['readwrite', 'updateifcopy']], + casting='equiv', op_dtypes=[np.dtype('f4')]) + with it: + it.operands[0][:] = 100 + assert_equal(au, 100) + # do it again, this time raise an error, + it = nditer(au, [], [['readwrite', 'updateifcopy']], + casting='equiv', op_dtypes=[np.dtype('f4')]) + try: + with it: + assert_equal(au.flags.writeable, False) + it.operands[0][:] = 0 + raise ValueError('exit context manager on exception') + except: + pass + assert_equal(au, 0) + assert_equal(au.flags.writeable, True) + # cannot reuse i outside context manager + assert_raises(ValueError, getattr, it, 'operands') + + it = nditer(au, [], [['readwrite', 'updateifcopy']], + casting='equiv', op_dtypes=[np.dtype('f4')]) + with it: + x = it.operands[0] + x[:] = 6 + assert_(x.flags.writebackifcopy) + assert_equal(au, 6) + assert_(not x.flags.writebackifcopy) + x[:] = 123 # x.data still valid + assert_equal(au, 6) # but not connected to au + + it = nditer(au, [], + [['readwrite', 'updateifcopy']], + casting='equiv', op_dtypes=[np.dtype('f4')]) + # reentering works + with it: + with it: + for x in it: + x[...] = 123 + + it = nditer(au, [], + [['readwrite', 'updateifcopy']], + casting='equiv', op_dtypes=[np.dtype('f4')]) + # make sure exiting the inner context manager closes the iterator + with it: + with it: + for x in it: + x[...] = 123 + assert_raises(ValueError, getattr, it, 'operands') + # do not crash if original data array is decrefed + it = nditer(au, [], + [['readwrite', 'updateifcopy']], + casting='equiv', op_dtypes=[np.dtype('f4')]) + del au + with it: + for x in it: + x[...] = 123 + # make sure we cannot reenter the closed iterator + enter = it.__enter__ + assert_raises(RuntimeError, enter) + +def test_close_equivalent(): + ''' using a context amanger and using nditer.close are equivalent + ''' + def add_close(x, y, out=None): + addop = np.add + it = np.nditer([x, y, out], [], + [['readonly'], ['readonly'], ['writeonly','allocate']]) + for (a, b, c) in it: + addop(a, b, out=c) + ret = it.operands[2] + it.close() + return ret + + def add_context(x, y, out=None): + addop = np.add + it = np.nditer([x, y, out], [], + [['readonly'], ['readonly'], ['writeonly','allocate']]) + with it: + for (a, b, c) in it: + addop(a, b, out=c) + return it.operands[2] + z = add_close(range(5), range(5)) + assert_equal(z, range(0, 10, 2)) + z = add_context(range(5), range(5)) + assert_equal(z, range(0, 10, 2)) + +def test_close_raises(): + it = np.nditer(np.arange(3)) + assert_equal (next(it), 0) + it.close() + assert_raises(StopIteration, next, it) + assert_raises(ValueError, getattr, it, 'operands') + +@pytest.mark.skipif(not HAS_REFCOUNT, reason="Python lacks refcounts") +def test_warn_noclose(): + a = np.arange(6, dtype='f4') + au = a.byteswap().newbyteorder() + with suppress_warnings() as sup: + sup.record(RuntimeWarning) + it = np.nditer(au, [], [['readwrite', 'updateifcopy']], + casting='equiv', op_dtypes=[np.dtype('f4')]) + del it + assert len(sup.log) == 1 + + +@pytest.mark.skipif(not HAS_REFCOUNT, reason="Python lacks refcounts") +@pytest.mark.parametrize(["in_dtype", "buf_dtype"], + [("i", "O"), ("O", "i"), # most simple cases + ("i,O", "O,O"), # structured partially only copying O + ("O,i", "i,O"), # structured casting to and from O + ]) +@pytest.mark.parametrize("steps", [1, 2, 3]) +def test_partial_iteration_cleanup(in_dtype, buf_dtype, steps): + value = 123 # relies on python cache (leak-check will still find it) + arr = np.full(int(np.BUFSIZE * 2.5), value).astype(in_dtype) + count = sys.getrefcount(value) + + it = np.nditer(arr, op_dtypes=[np.dtype(buf_dtype)], + flags=["buffered", "external_loop", "refs_ok"], casting="unsafe") + for step in range(steps): + # The iteration finishes in 3 steps, the first two are partial + next(it) + + # Note that resetting does not free references + del it + assert count == sys.getrefcount(value) + + # Repeat the test with `iternext` + it = np.nditer(arr, op_dtypes=[np.dtype(buf_dtype)], + flags=["buffered", "external_loop", "refs_ok"], casting="unsafe") + for step in range(steps): + it.iternext() + + del it # should ensure cleanup + assert count == sys.getrefcount(value) + + +@pytest.mark.skipif(not HAS_REFCOUNT, reason="Python lacks refcounts") +@pytest.mark.parametrize(["in_dtype", "buf_dtype"], + [("O", "i"), # most simple cases + ("O,i", "i,O"), # structured casting to and from O + ]) +def test_partial_iteration_error(in_dtype, buf_dtype): + value = 123 # relies on python cache (leak-check will still find it) + arr = np.full(int(np.BUFSIZE * 2.5), value).astype(in_dtype) + if in_dtype == "O": + arr[int(np.BUFSIZE * 1.5)] = None + else: + arr[int(np.BUFSIZE * 1.5)]["f0"] = None + + count = sys.getrefcount(value) + + it = np.nditer(arr, op_dtypes=[np.dtype(buf_dtype)], + flags=["buffered", "external_loop", "refs_ok"], casting="unsafe") + with pytest.raises(TypeError): + # pytest.raises seems to have issues with the error originating + # in the for loop, so manually unravel: + next(it) + next(it) # raises TypeError + + # Repeat the test with `iternext` after resetting, the buffers should + # already be cleared from any references, so resetting is sufficient. + it.reset() + with pytest.raises(TypeError): + it.iternext() + it.iternext() + + assert count == sys.getrefcount(value) diff --git a/venv/Lib/site-packages/numpy/core/tests/test_numeric.py b/venv/Lib/site-packages/numpy/core/tests/test_numeric.py new file mode 100644 index 0000000..91aafe4 --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/tests/test_numeric.py @@ -0,0 +1,3472 @@ +import sys +import warnings +import itertools +import platform +import pytest +import math +from decimal import Decimal + +import numpy as np +from numpy.core import umath +from numpy.random import rand, randint, randn +from numpy.testing import ( + assert_, assert_equal, assert_raises, assert_raises_regex, + assert_array_equal, assert_almost_equal, assert_array_almost_equal, + assert_warns, assert_array_max_ulp, HAS_REFCOUNT + ) +from numpy.core._rational_tests import rational + +from hypothesis import assume, given, strategies as st +from hypothesis.extra import numpy as hynp + + +class TestResize: + def test_copies(self): + A = np.array([[1, 2], [3, 4]]) + Ar1 = np.array([[1, 2, 3, 4], [1, 2, 3, 4]]) + assert_equal(np.resize(A, (2, 4)), Ar1) + + Ar2 = np.array([[1, 2], [3, 4], [1, 2], [3, 4]]) + assert_equal(np.resize(A, (4, 2)), Ar2) + + Ar3 = np.array([[1, 2, 3], [4, 1, 2], [3, 4, 1], [2, 3, 4]]) + assert_equal(np.resize(A, (4, 3)), Ar3) + + def test_repeats(self): + A = np.array([1, 2, 3]) + Ar1 = np.array([[1, 2, 3, 1], [2, 3, 1, 2]]) + assert_equal(np.resize(A, (2, 4)), Ar1) + + Ar2 = np.array([[1, 2], [3, 1], [2, 3], [1, 2]]) + assert_equal(np.resize(A, (4, 2)), Ar2) + + Ar3 = np.array([[1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3]]) + assert_equal(np.resize(A, (4, 3)), Ar3) + + def test_zeroresize(self): + A = np.array([[1, 2], [3, 4]]) + Ar = np.resize(A, (0,)) + assert_array_equal(Ar, np.array([])) + assert_equal(A.dtype, Ar.dtype) + + Ar = np.resize(A, (0, 2)) + assert_equal(Ar.shape, (0, 2)) + + Ar = np.resize(A, (2, 0)) + assert_equal(Ar.shape, (2, 0)) + + def test_reshape_from_zero(self): + # See also gh-6740 + A = np.zeros(0, dtype=[('a', np.float32)]) + Ar = np.resize(A, (2, 1)) + assert_array_equal(Ar, np.zeros((2, 1), Ar.dtype)) + assert_equal(A.dtype, Ar.dtype) + + def test_negative_resize(self): + A = np.arange(0, 10, dtype=np.float32) + new_shape = (-10, -1) + with pytest.raises(ValueError, match=r"negative"): + np.resize(A, new_shape=new_shape) + + def test_subclass(self): + class MyArray(np.ndarray): + __array_priority__ = 1. + + my_arr = np.array([1]).view(MyArray) + assert type(np.resize(my_arr, 5)) is MyArray + assert type(np.resize(my_arr, 0)) is MyArray + + my_arr = np.array([]).view(MyArray) + assert type(np.resize(my_arr, 5)) is MyArray + + +class TestNonarrayArgs: + # check that non-array arguments to functions wrap them in arrays + def test_choose(self): + choices = [[0, 1, 2], + [3, 4, 5], + [5, 6, 7]] + tgt = [5, 1, 5] + a = [2, 0, 1] + + out = np.choose(a, choices) + assert_equal(out, tgt) + + def test_clip(self): + arr = [-1, 5, 2, 3, 10, -4, -9] + out = np.clip(arr, 2, 7) + tgt = [2, 5, 2, 3, 7, 2, 2] + assert_equal(out, tgt) + + def test_compress(self): + arr = [[0, 1, 2, 3, 4], + [5, 6, 7, 8, 9]] + tgt = [[5, 6, 7, 8, 9]] + out = np.compress([0, 1], arr, axis=0) + assert_equal(out, tgt) + + def test_count_nonzero(self): + arr = [[0, 1, 7, 0, 0], + [3, 0, 0, 2, 19]] + tgt = np.array([2, 3]) + out = np.count_nonzero(arr, axis=1) + assert_equal(out, tgt) + + def test_cumproduct(self): + A = [[1, 2, 3], [4, 5, 6]] + assert_(np.all(np.cumproduct(A) == np.array([1, 2, 6, 24, 120, 720]))) + + def test_diagonal(self): + a = [[0, 1, 2, 3], + [4, 5, 6, 7], + [8, 9, 10, 11]] + out = np.diagonal(a) + tgt = [0, 5, 10] + + assert_equal(out, tgt) + + def test_mean(self): + A = [[1, 2, 3], [4, 5, 6]] + assert_(np.mean(A) == 3.5) + assert_(np.all(np.mean(A, 0) == np.array([2.5, 3.5, 4.5]))) + assert_(np.all(np.mean(A, 1) == np.array([2., 5.]))) + + with warnings.catch_warnings(record=True) as w: + warnings.filterwarnings('always', '', RuntimeWarning) + assert_(np.isnan(np.mean([]))) + assert_(w[0].category is RuntimeWarning) + + def test_ptp(self): + a = [3, 4, 5, 10, -3, -5, 6.0] + assert_equal(np.ptp(a, axis=0), 15.0) + + def test_prod(self): + arr = [[1, 2, 3, 4], + [5, 6, 7, 9], + [10, 3, 4, 5]] + tgt = [24, 1890, 600] + + assert_equal(np.prod(arr, axis=-1), tgt) + + def test_ravel(self): + a = [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]] + tgt = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] + assert_equal(np.ravel(a), tgt) + + def test_repeat(self): + a = [1, 2, 3] + tgt = [1, 1, 2, 2, 3, 3] + + out = np.repeat(a, 2) + assert_equal(out, tgt) + + def test_reshape(self): + arr = [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]] + tgt = [[1, 2, 3, 4, 5, 6], [7, 8, 9, 10, 11, 12]] + assert_equal(np.reshape(arr, (2, 6)), tgt) + + def test_round(self): + arr = [1.56, 72.54, 6.35, 3.25] + tgt = [1.6, 72.5, 6.4, 3.2] + assert_equal(np.around(arr, decimals=1), tgt) + s = np.float64(1.) + assert_(isinstance(s.round(), np.float64)) + assert_equal(s.round(), 1.) + + @pytest.mark.parametrize('dtype', [ + np.int8, np.int16, np.int32, np.int64, + np.uint8, np.uint16, np.uint32, np.uint64, + np.float16, np.float32, np.float64, + ]) + def test_dunder_round(self, dtype): + s = dtype(1) + assert_(isinstance(round(s), int)) + assert_(isinstance(round(s, None), int)) + assert_(isinstance(round(s, ndigits=None), int)) + assert_equal(round(s), 1) + assert_equal(round(s, None), 1) + assert_equal(round(s, ndigits=None), 1) + + @pytest.mark.parametrize('val, ndigits', [ + pytest.param(2**31 - 1, -1, + marks=pytest.mark.xfail(reason="Out of range of int32") + ), + (2**31 - 1, 1-math.ceil(math.log10(2**31 - 1))), + (2**31 - 1, -math.ceil(math.log10(2**31 - 1))) + ]) + def test_dunder_round_edgecases(self, val, ndigits): + assert_equal(round(val, ndigits), round(np.int32(val), ndigits)) + + def test_dunder_round_accuracy(self): + f = np.float64(5.1 * 10**73) + assert_(isinstance(round(f, -73), np.float64)) + assert_array_max_ulp(round(f, -73), 5.0 * 10**73) + assert_(isinstance(round(f, ndigits=-73), np.float64)) + assert_array_max_ulp(round(f, ndigits=-73), 5.0 * 10**73) + + i = np.int64(501) + assert_(isinstance(round(i, -2), np.int64)) + assert_array_max_ulp(round(i, -2), 500) + assert_(isinstance(round(i, ndigits=-2), np.int64)) + assert_array_max_ulp(round(i, ndigits=-2), 500) + + @pytest.mark.xfail(raises=AssertionError, reason="gh-15896") + def test_round_py_consistency(self): + f = 5.1 * 10**73 + assert_equal(round(np.float64(f), -73), round(f, -73)) + + def test_searchsorted(self): + arr = [-8, -5, -1, 3, 6, 10] + out = np.searchsorted(arr, 0) + assert_equal(out, 3) + + def test_size(self): + A = [[1, 2, 3], [4, 5, 6]] + assert_(np.size(A) == 6) + assert_(np.size(A, 0) == 2) + assert_(np.size(A, 1) == 3) + + def test_squeeze(self): + A = [[[1, 1, 1], [2, 2, 2], [3, 3, 3]]] + assert_equal(np.squeeze(A).shape, (3, 3)) + assert_equal(np.squeeze(np.zeros((1, 3, 1))).shape, (3,)) + assert_equal(np.squeeze(np.zeros((1, 3, 1)), axis=0).shape, (3, 1)) + assert_equal(np.squeeze(np.zeros((1, 3, 1)), axis=-1).shape, (1, 3)) + assert_equal(np.squeeze(np.zeros((1, 3, 1)), axis=2).shape, (1, 3)) + assert_equal(np.squeeze([np.zeros((3, 1))]).shape, (3,)) + assert_equal(np.squeeze([np.zeros((3, 1))], axis=0).shape, (3, 1)) + assert_equal(np.squeeze([np.zeros((3, 1))], axis=2).shape, (1, 3)) + assert_equal(np.squeeze([np.zeros((3, 1))], axis=-1).shape, (1, 3)) + + def test_std(self): + A = [[1, 2, 3], [4, 5, 6]] + assert_almost_equal(np.std(A), 1.707825127659933) + assert_almost_equal(np.std(A, 0), np.array([1.5, 1.5, 1.5])) + assert_almost_equal(np.std(A, 1), np.array([0.81649658, 0.81649658])) + + with warnings.catch_warnings(record=True) as w: + warnings.filterwarnings('always', '', RuntimeWarning) + assert_(np.isnan(np.std([]))) + assert_(w[0].category is RuntimeWarning) + + def test_swapaxes(self): + tgt = [[[0, 4], [2, 6]], [[1, 5], [3, 7]]] + a = [[[0, 1], [2, 3]], [[4, 5], [6, 7]]] + out = np.swapaxes(a, 0, 2) + assert_equal(out, tgt) + + def test_sum(self): + m = [[1, 2, 3], + [4, 5, 6], + [7, 8, 9]] + tgt = [[6], [15], [24]] + out = np.sum(m, axis=1, keepdims=True) + + assert_equal(tgt, out) + + def test_take(self): + tgt = [2, 3, 5] + indices = [1, 2, 4] + a = [1, 2, 3, 4, 5] + + out = np.take(a, indices) + assert_equal(out, tgt) + + def test_trace(self): + c = [[1, 2], [3, 4], [5, 6]] + assert_equal(np.trace(c), 5) + + def test_transpose(self): + arr = [[1, 2], [3, 4], [5, 6]] + tgt = [[1, 3, 5], [2, 4, 6]] + assert_equal(np.transpose(arr, (1, 0)), tgt) + + def test_var(self): + A = [[1, 2, 3], [4, 5, 6]] + assert_almost_equal(np.var(A), 2.9166666666666665) + assert_almost_equal(np.var(A, 0), np.array([2.25, 2.25, 2.25])) + assert_almost_equal(np.var(A, 1), np.array([0.66666667, 0.66666667])) + + with warnings.catch_warnings(record=True) as w: + warnings.filterwarnings('always', '', RuntimeWarning) + assert_(np.isnan(np.var([]))) + assert_(w[0].category is RuntimeWarning) + + B = np.array([None, 0]) + B[0] = 1j + assert_almost_equal(np.var(B), 0.25) + +class TestIsscalar: + def test_isscalar(self): + assert_(np.isscalar(3.1)) + assert_(np.isscalar(np.int16(12345))) + assert_(np.isscalar(False)) + assert_(np.isscalar('numpy')) + assert_(not np.isscalar([3.1])) + assert_(not np.isscalar(None)) + + # PEP 3141 + from fractions import Fraction + assert_(np.isscalar(Fraction(5, 17))) + from numbers import Number + assert_(np.isscalar(Number())) + + +class TestBoolScalar: + def test_logical(self): + f = np.False_ + t = np.True_ + s = "xyz" + assert_((t and s) is s) + assert_((f and s) is f) + + def test_bitwise_or(self): + f = np.False_ + t = np.True_ + assert_((t | t) is t) + assert_((f | t) is t) + assert_((t | f) is t) + assert_((f | f) is f) + + def test_bitwise_and(self): + f = np.False_ + t = np.True_ + assert_((t & t) is t) + assert_((f & t) is f) + assert_((t & f) is f) + assert_((f & f) is f) + + def test_bitwise_xor(self): + f = np.False_ + t = np.True_ + assert_((t ^ t) is f) + assert_((f ^ t) is t) + assert_((t ^ f) is t) + assert_((f ^ f) is f) + + +class TestBoolArray: + def setup(self): + # offset for simd tests + self.t = np.array([True] * 41, dtype=bool)[1::] + self.f = np.array([False] * 41, dtype=bool)[1::] + self.o = np.array([False] * 42, dtype=bool)[2::] + self.nm = self.f.copy() + self.im = self.t.copy() + self.nm[3] = True + self.nm[-2] = True + self.im[3] = False + self.im[-2] = False + + def test_all_any(self): + assert_(self.t.all()) + assert_(self.t.any()) + assert_(not self.f.all()) + assert_(not self.f.any()) + assert_(self.nm.any()) + assert_(self.im.any()) + assert_(not self.nm.all()) + assert_(not self.im.all()) + # check bad element in all positions + for i in range(256 - 7): + d = np.array([False] * 256, dtype=bool)[7::] + d[i] = True + assert_(np.any(d)) + e = np.array([True] * 256, dtype=bool)[7::] + e[i] = False + assert_(not np.all(e)) + assert_array_equal(e, ~d) + # big array test for blocked libc loops + for i in list(range(9, 6000, 507)) + [7764, 90021, -10]: + d = np.array([False] * 100043, dtype=bool) + d[i] = True + assert_(np.any(d), msg="%r" % i) + e = np.array([True] * 100043, dtype=bool) + e[i] = False + assert_(not np.all(e), msg="%r" % i) + + def test_logical_not_abs(self): + assert_array_equal(~self.t, self.f) + assert_array_equal(np.abs(~self.t), self.f) + assert_array_equal(np.abs(~self.f), self.t) + assert_array_equal(np.abs(self.f), self.f) + assert_array_equal(~np.abs(self.f), self.t) + assert_array_equal(~np.abs(self.t), self.f) + assert_array_equal(np.abs(~self.nm), self.im) + np.logical_not(self.t, out=self.o) + assert_array_equal(self.o, self.f) + np.abs(self.t, out=self.o) + assert_array_equal(self.o, self.t) + + def test_logical_and_or_xor(self): + assert_array_equal(self.t | self.t, self.t) + assert_array_equal(self.f | self.f, self.f) + assert_array_equal(self.t | self.f, self.t) + assert_array_equal(self.f | self.t, self.t) + np.logical_or(self.t, self.t, out=self.o) + assert_array_equal(self.o, self.t) + assert_array_equal(self.t & self.t, self.t) + assert_array_equal(self.f & self.f, self.f) + assert_array_equal(self.t & self.f, self.f) + assert_array_equal(self.f & self.t, self.f) + np.logical_and(self.t, self.t, out=self.o) + assert_array_equal(self.o, self.t) + assert_array_equal(self.t ^ self.t, self.f) + assert_array_equal(self.f ^ self.f, self.f) + assert_array_equal(self.t ^ self.f, self.t) + assert_array_equal(self.f ^ self.t, self.t) + np.logical_xor(self.t, self.t, out=self.o) + assert_array_equal(self.o, self.f) + + assert_array_equal(self.nm & self.t, self.nm) + assert_array_equal(self.im & self.f, False) + assert_array_equal(self.nm & True, self.nm) + assert_array_equal(self.im & False, self.f) + assert_array_equal(self.nm | self.t, self.t) + assert_array_equal(self.im | self.f, self.im) + assert_array_equal(self.nm | True, self.t) + assert_array_equal(self.im | False, self.im) + assert_array_equal(self.nm ^ self.t, self.im) + assert_array_equal(self.im ^ self.f, self.im) + assert_array_equal(self.nm ^ True, self.im) + assert_array_equal(self.im ^ False, self.im) + + +class TestBoolCmp: + def setup(self): + self.f = np.ones(256, dtype=np.float32) + self.ef = np.ones(self.f.size, dtype=bool) + self.d = np.ones(128, dtype=np.float64) + self.ed = np.ones(self.d.size, dtype=bool) + # generate values for all permutation of 256bit simd vectors + s = 0 + for i in range(32): + self.f[s:s+8] = [i & 2**x for x in range(8)] + self.ef[s:s+8] = [(i & 2**x) != 0 for x in range(8)] + s += 8 + s = 0 + for i in range(16): + self.d[s:s+4] = [i & 2**x for x in range(4)] + self.ed[s:s+4] = [(i & 2**x) != 0 for x in range(4)] + s += 4 + + self.nf = self.f.copy() + self.nd = self.d.copy() + self.nf[self.ef] = np.nan + self.nd[self.ed] = np.nan + + self.inff = self.f.copy() + self.infd = self.d.copy() + self.inff[::3][self.ef[::3]] = np.inf + self.infd[::3][self.ed[::3]] = np.inf + self.inff[1::3][self.ef[1::3]] = -np.inf + self.infd[1::3][self.ed[1::3]] = -np.inf + self.inff[2::3][self.ef[2::3]] = np.nan + self.infd[2::3][self.ed[2::3]] = np.nan + self.efnonan = self.ef.copy() + self.efnonan[2::3] = False + self.ednonan = self.ed.copy() + self.ednonan[2::3] = False + + self.signf = self.f.copy() + self.signd = self.d.copy() + self.signf[self.ef] *= -1. + self.signd[self.ed] *= -1. + self.signf[1::6][self.ef[1::6]] = -np.inf + self.signd[1::6][self.ed[1::6]] = -np.inf + self.signf[3::6][self.ef[3::6]] = -np.nan + self.signd[3::6][self.ed[3::6]] = -np.nan + self.signf[4::6][self.ef[4::6]] = -0. + self.signd[4::6][self.ed[4::6]] = -0. + + def test_float(self): + # offset for alignment test + for i in range(4): + assert_array_equal(self.f[i:] > 0, self.ef[i:]) + assert_array_equal(self.f[i:] - 1 >= 0, self.ef[i:]) + assert_array_equal(self.f[i:] == 0, ~self.ef[i:]) + assert_array_equal(-self.f[i:] < 0, self.ef[i:]) + assert_array_equal(-self.f[i:] + 1 <= 0, self.ef[i:]) + r = self.f[i:] != 0 + assert_array_equal(r, self.ef[i:]) + r2 = self.f[i:] != np.zeros_like(self.f[i:]) + r3 = 0 != self.f[i:] + assert_array_equal(r, r2) + assert_array_equal(r, r3) + # check bool == 0x1 + assert_array_equal(r.view(np.int8), r.astype(np.int8)) + assert_array_equal(r2.view(np.int8), r2.astype(np.int8)) + assert_array_equal(r3.view(np.int8), r3.astype(np.int8)) + + # isnan on amd64 takes the same code path + assert_array_equal(np.isnan(self.nf[i:]), self.ef[i:]) + assert_array_equal(np.isfinite(self.nf[i:]), ~self.ef[i:]) + assert_array_equal(np.isfinite(self.inff[i:]), ~self.ef[i:]) + assert_array_equal(np.isinf(self.inff[i:]), self.efnonan[i:]) + assert_array_equal(np.signbit(self.signf[i:]), self.ef[i:]) + + def test_double(self): + # offset for alignment test + for i in range(2): + assert_array_equal(self.d[i:] > 0, self.ed[i:]) + assert_array_equal(self.d[i:] - 1 >= 0, self.ed[i:]) + assert_array_equal(self.d[i:] == 0, ~self.ed[i:]) + assert_array_equal(-self.d[i:] < 0, self.ed[i:]) + assert_array_equal(-self.d[i:] + 1 <= 0, self.ed[i:]) + r = self.d[i:] != 0 + assert_array_equal(r, self.ed[i:]) + r2 = self.d[i:] != np.zeros_like(self.d[i:]) + r3 = 0 != self.d[i:] + assert_array_equal(r, r2) + assert_array_equal(r, r3) + # check bool == 0x1 + assert_array_equal(r.view(np.int8), r.astype(np.int8)) + assert_array_equal(r2.view(np.int8), r2.astype(np.int8)) + assert_array_equal(r3.view(np.int8), r3.astype(np.int8)) + + # isnan on amd64 takes the same code path + assert_array_equal(np.isnan(self.nd[i:]), self.ed[i:]) + assert_array_equal(np.isfinite(self.nd[i:]), ~self.ed[i:]) + assert_array_equal(np.isfinite(self.infd[i:]), ~self.ed[i:]) + assert_array_equal(np.isinf(self.infd[i:]), self.ednonan[i:]) + assert_array_equal(np.signbit(self.signd[i:]), self.ed[i:]) + + +class TestSeterr: + def test_default(self): + err = np.geterr() + assert_equal(err, + dict(divide='warn', + invalid='warn', + over='warn', + under='ignore') + ) + + def test_set(self): + with np.errstate(): + err = np.seterr() + old = np.seterr(divide='print') + assert_(err == old) + new = np.seterr() + assert_(new['divide'] == 'print') + np.seterr(over='raise') + assert_(np.geterr()['over'] == 'raise') + assert_(new['divide'] == 'print') + np.seterr(**old) + assert_(np.geterr() == old) + + @pytest.mark.skipif(platform.machine() == "armv5tel", reason="See gh-413.") + def test_divide_err(self): + with np.errstate(divide='raise'): + with assert_raises(FloatingPointError): + np.array([1.]) / np.array([0.]) + + np.seterr(divide='ignore') + np.array([1.]) / np.array([0.]) + + def test_errobj(self): + olderrobj = np.geterrobj() + self.called = 0 + try: + with warnings.catch_warnings(record=True) as w: + warnings.simplefilter("always") + with np.errstate(divide='warn'): + np.seterrobj([20000, 1, None]) + np.array([1.]) / np.array([0.]) + assert_equal(len(w), 1) + + def log_err(*args): + self.called += 1 + extobj_err = args + assert_(len(extobj_err) == 2) + assert_("divide" in extobj_err[0]) + + with np.errstate(divide='ignore'): + np.seterrobj([20000, 3, log_err]) + np.array([1.]) / np.array([0.]) + assert_equal(self.called, 1) + + np.seterrobj(olderrobj) + with np.errstate(divide='ignore'): + np.divide(1., 0., extobj=[20000, 3, log_err]) + assert_equal(self.called, 2) + finally: + np.seterrobj(olderrobj) + del self.called + + def test_errobj_noerrmask(self): + # errmask = 0 has a special code path for the default + olderrobj = np.geterrobj() + try: + # set errobj to something non default + np.seterrobj([umath.UFUNC_BUFSIZE_DEFAULT, + umath.ERR_DEFAULT + 1, None]) + # call a ufunc + np.isnan(np.array([6])) + # same with the default, lots of times to get rid of possible + # pre-existing stack in the code + for i in range(10000): + np.seterrobj([umath.UFUNC_BUFSIZE_DEFAULT, umath.ERR_DEFAULT, + None]) + np.isnan(np.array([6])) + finally: + np.seterrobj(olderrobj) + + +class TestFloatExceptions: + def assert_raises_fpe(self, fpeerr, flop, x, y): + ftype = type(x) + try: + flop(x, y) + assert_(False, + "Type %s did not raise fpe error '%s'." % (ftype, fpeerr)) + except FloatingPointError as exc: + assert_(str(exc).find(fpeerr) >= 0, + "Type %s raised wrong fpe error '%s'." % (ftype, exc)) + + def assert_op_raises_fpe(self, fpeerr, flop, sc1, sc2): + # Check that fpe exception is raised. + # + # Given a floating operation `flop` and two scalar values, check that + # the operation raises the floating point exception specified by + # `fpeerr`. Tests all variants with 0-d array scalars as well. + + self.assert_raises_fpe(fpeerr, flop, sc1, sc2) + self.assert_raises_fpe(fpeerr, flop, sc1[()], sc2) + self.assert_raises_fpe(fpeerr, flop, sc1, sc2[()]) + self.assert_raises_fpe(fpeerr, flop, sc1[()], sc2[()]) + + def test_floating_exceptions(self): + # Test basic arithmetic function errors + with np.errstate(all='raise'): + # Test for all real and complex float types + for typecode in np.typecodes['AllFloat']: + ftype = np.obj2sctype(typecode) + if np.dtype(ftype).kind == 'f': + # Get some extreme values for the type + fi = np.finfo(ftype) + ft_tiny = fi.tiny + ft_max = fi.max + ft_eps = fi.eps + underflow = 'underflow' + divbyzero = 'divide by zero' + else: + # 'c', complex, corresponding real dtype + rtype = type(ftype(0).real) + fi = np.finfo(rtype) + ft_tiny = ftype(fi.tiny) + ft_max = ftype(fi.max) + ft_eps = ftype(fi.eps) + # The complex types raise different exceptions + underflow = '' + divbyzero = '' + overflow = 'overflow' + invalid = 'invalid' + + self.assert_raises_fpe(underflow, + lambda a, b: a/b, ft_tiny, ft_max) + self.assert_raises_fpe(underflow, + lambda a, b: a*b, ft_tiny, ft_tiny) + self.assert_raises_fpe(overflow, + lambda a, b: a*b, ft_max, ftype(2)) + self.assert_raises_fpe(overflow, + lambda a, b: a/b, ft_max, ftype(0.5)) + self.assert_raises_fpe(overflow, + lambda a, b: a+b, ft_max, ft_max*ft_eps) + self.assert_raises_fpe(overflow, + lambda a, b: a-b, -ft_max, ft_max*ft_eps) + self.assert_raises_fpe(overflow, + np.power, ftype(2), ftype(2**fi.nexp)) + self.assert_raises_fpe(divbyzero, + lambda a, b: a/b, ftype(1), ftype(0)) + self.assert_raises_fpe(invalid, + lambda a, b: a/b, ftype(np.inf), ftype(np.inf)) + self.assert_raises_fpe(invalid, + lambda a, b: a/b, ftype(0), ftype(0)) + self.assert_raises_fpe(invalid, + lambda a, b: a-b, ftype(np.inf), ftype(np.inf)) + self.assert_raises_fpe(invalid, + lambda a, b: a+b, ftype(np.inf), ftype(-np.inf)) + self.assert_raises_fpe(invalid, + lambda a, b: a*b, ftype(0), ftype(np.inf)) + + def test_warnings(self): + # test warning code path + with warnings.catch_warnings(record=True) as w: + warnings.simplefilter("always") + with np.errstate(all="warn"): + np.divide(1, 0.) + assert_equal(len(w), 1) + assert_("divide by zero" in str(w[0].message)) + np.array(1e300) * np.array(1e300) + assert_equal(len(w), 2) + assert_("overflow" in str(w[-1].message)) + np.array(np.inf) - np.array(np.inf) + assert_equal(len(w), 3) + assert_("invalid value" in str(w[-1].message)) + np.array(1e-300) * np.array(1e-300) + assert_equal(len(w), 4) + assert_("underflow" in str(w[-1].message)) + + +class TestTypes: + def check_promotion_cases(self, promote_func): + # tests that the scalars get coerced correctly. + b = np.bool_(0) + i8, i16, i32, i64 = np.int8(0), np.int16(0), np.int32(0), np.int64(0) + u8, u16, u32, u64 = np.uint8(0), np.uint16(0), np.uint32(0), np.uint64(0) + f32, f64, fld = np.float32(0), np.float64(0), np.longdouble(0) + c64, c128, cld = np.complex64(0), np.complex128(0), np.clongdouble(0) + + # coercion within the same kind + assert_equal(promote_func(i8, i16), np.dtype(np.int16)) + assert_equal(promote_func(i32, i8), np.dtype(np.int32)) + assert_equal(promote_func(i16, i64), np.dtype(np.int64)) + assert_equal(promote_func(u8, u32), np.dtype(np.uint32)) + assert_equal(promote_func(f32, f64), np.dtype(np.float64)) + assert_equal(promote_func(fld, f32), np.dtype(np.longdouble)) + assert_equal(promote_func(f64, fld), np.dtype(np.longdouble)) + assert_equal(promote_func(c128, c64), np.dtype(np.complex128)) + assert_equal(promote_func(cld, c128), np.dtype(np.clongdouble)) + assert_equal(promote_func(c64, fld), np.dtype(np.clongdouble)) + + # coercion between kinds + assert_equal(promote_func(b, i32), np.dtype(np.int32)) + assert_equal(promote_func(b, u8), np.dtype(np.uint8)) + assert_equal(promote_func(i8, u8), np.dtype(np.int16)) + assert_equal(promote_func(u8, i32), np.dtype(np.int32)) + assert_equal(promote_func(i64, u32), np.dtype(np.int64)) + assert_equal(promote_func(u64, i32), np.dtype(np.float64)) + assert_equal(promote_func(i32, f32), np.dtype(np.float64)) + assert_equal(promote_func(i64, f32), np.dtype(np.float64)) + assert_equal(promote_func(f32, i16), np.dtype(np.float32)) + assert_equal(promote_func(f32, u32), np.dtype(np.float64)) + assert_equal(promote_func(f32, c64), np.dtype(np.complex64)) + assert_equal(promote_func(c128, f32), np.dtype(np.complex128)) + assert_equal(promote_func(cld, f64), np.dtype(np.clongdouble)) + + # coercion between scalars and 1-D arrays + assert_equal(promote_func(np.array([b]), i8), np.dtype(np.int8)) + assert_equal(promote_func(np.array([b]), u8), np.dtype(np.uint8)) + assert_equal(promote_func(np.array([b]), i32), np.dtype(np.int32)) + assert_equal(promote_func(np.array([b]), u32), np.dtype(np.uint32)) + assert_equal(promote_func(np.array([i8]), i64), np.dtype(np.int8)) + assert_equal(promote_func(u64, np.array([i32])), np.dtype(np.int32)) + assert_equal(promote_func(i64, np.array([u32])), np.dtype(np.uint32)) + assert_equal(promote_func(np.int32(-1), np.array([u64])), + np.dtype(np.float64)) + assert_equal(promote_func(f64, np.array([f32])), np.dtype(np.float32)) + assert_equal(promote_func(fld, np.array([f32])), np.dtype(np.float32)) + assert_equal(promote_func(np.array([f64]), fld), np.dtype(np.float64)) + assert_equal(promote_func(fld, np.array([c64])), + np.dtype(np.complex64)) + assert_equal(promote_func(c64, np.array([f64])), + np.dtype(np.complex128)) + assert_equal(promote_func(np.complex64(3j), np.array([f64])), + np.dtype(np.complex128)) + + # coercion between scalars and 1-D arrays, where + # the scalar has greater kind than the array + assert_equal(promote_func(np.array([b]), f64), np.dtype(np.float64)) + assert_equal(promote_func(np.array([b]), i64), np.dtype(np.int64)) + assert_equal(promote_func(np.array([b]), u64), np.dtype(np.uint64)) + assert_equal(promote_func(np.array([i8]), f64), np.dtype(np.float64)) + assert_equal(promote_func(np.array([u16]), f64), np.dtype(np.float64)) + + # uint and int are treated as the same "kind" for + # the purposes of array-scalar promotion. + assert_equal(promote_func(np.array([u16]), i32), np.dtype(np.uint16)) + + # float and complex are treated as the same "kind" for + # the purposes of array-scalar promotion, so that you can do + # (0j + float32array) to get a complex64 array instead of + # a complex128 array. + assert_equal(promote_func(np.array([f32]), c128), + np.dtype(np.complex64)) + + def test_coercion(self): + def res_type(a, b): + return np.add(a, b).dtype + + self.check_promotion_cases(res_type) + + # Use-case: float/complex scalar * bool/int8 array + # shouldn't narrow the float/complex type + for a in [np.array([True, False]), np.array([-3, 12], dtype=np.int8)]: + b = 1.234 * a + assert_equal(b.dtype, np.dtype('f8'), "array type %s" % a.dtype) + b = np.longdouble(1.234) * a + assert_equal(b.dtype, np.dtype(np.longdouble), + "array type %s" % a.dtype) + b = np.float64(1.234) * a + assert_equal(b.dtype, np.dtype('f8'), "array type %s" % a.dtype) + b = np.float32(1.234) * a + assert_equal(b.dtype, np.dtype('f4'), "array type %s" % a.dtype) + b = np.float16(1.234) * a + assert_equal(b.dtype, np.dtype('f2'), "array type %s" % a.dtype) + + b = 1.234j * a + assert_equal(b.dtype, np.dtype('c16'), "array type %s" % a.dtype) + b = np.clongdouble(1.234j) * a + assert_equal(b.dtype, np.dtype(np.clongdouble), + "array type %s" % a.dtype) + b = np.complex128(1.234j) * a + assert_equal(b.dtype, np.dtype('c16'), "array type %s" % a.dtype) + b = np.complex64(1.234j) * a + assert_equal(b.dtype, np.dtype('c8'), "array type %s" % a.dtype) + + # The following use-case is problematic, and to resolve its + # tricky side-effects requires more changes. + # + # Use-case: (1-t)*a, where 't' is a boolean array and 'a' is + # a float32, shouldn't promote to float64 + # + # a = np.array([1.0, 1.5], dtype=np.float32) + # t = np.array([True, False]) + # b = t*a + # assert_equal(b, [1.0, 0.0]) + # assert_equal(b.dtype, np.dtype('f4')) + # b = (1-t)*a + # assert_equal(b, [0.0, 1.5]) + # assert_equal(b.dtype, np.dtype('f4')) + # + # Probably ~t (bitwise negation) is more proper to use here, + # but this is arguably less intuitive to understand at a glance, and + # would fail if 't' is actually an integer array instead of boolean: + # + # b = (~t)*a + # assert_equal(b, [0.0, 1.5]) + # assert_equal(b.dtype, np.dtype('f4')) + + def test_result_type(self): + self.check_promotion_cases(np.result_type) + assert_(np.result_type(None) == np.dtype(None)) + + def test_promote_types_endian(self): + # promote_types should always return native-endian types + assert_equal(np.promote_types('i8', '>i8'), np.dtype('i8')) + + assert_equal(np.promote_types('>i8', '>U16'), np.dtype('U21')) + assert_equal(np.promote_types('U16', '>i8'), np.dtype('U21')) + assert_equal(np.promote_types('S5', '>U8'), np.dtype('U8')) + assert_equal(np.promote_types('U8', '>S5'), np.dtype('U8')) + assert_equal(np.promote_types('U8', '>U5'), np.dtype('U8')) + + assert_equal(np.promote_types('M8', '>M8'), np.dtype('M8')) + assert_equal(np.promote_types('m8', '>m8'), np.dtype('m8')) + + def test_can_cast_and_promote_usertypes(self): + # The rational type defines safe casting for signed integers, + # boolean. Rational itself *does* cast safely to double. + # (rational does not actually cast to all signed integers, e.g. + # int64 can be both long and longlong and it registers only the first) + valid_types = ["int8", "int16", "int32", "int64", "bool"] + invalid_types = "BHILQP" + "FDG" + "mM" + "f" + "V" + + rational_dt = np.dtype(rational) + for numpy_dtype in valid_types: + numpy_dtype = np.dtype(numpy_dtype) + assert np.can_cast(numpy_dtype, rational_dt) + assert np.promote_types(numpy_dtype, rational_dt) is rational_dt + + for numpy_dtype in invalid_types: + numpy_dtype = np.dtype(numpy_dtype) + assert not np.can_cast(numpy_dtype, rational_dt) + with pytest.raises(TypeError): + np.promote_types(numpy_dtype, rational_dt) + + double_dt = np.dtype("double") + assert np.can_cast(rational_dt, double_dt) + assert np.promote_types(double_dt, rational_dt) is double_dt + + @pytest.mark.parametrize("swap", ["", "swap"]) + @pytest.mark.parametrize("string_dtype", ["U", "S"]) + def test_promote_types_strings(self, swap, string_dtype): + if swap == "swap": + promote_types = lambda a, b: np.promote_types(b, a) + else: + promote_types = np.promote_types + + S = string_dtype + # Promote numeric with unsized string: + assert_equal(promote_types('bool', S), np.dtype(S+'5')) + assert_equal(promote_types('b', S), np.dtype(S+'4')) + assert_equal(promote_types('u1', S), np.dtype(S+'3')) + assert_equal(promote_types('u2', S), np.dtype(S+'5')) + assert_equal(promote_types('u4', S), np.dtype(S+'10')) + assert_equal(promote_types('u8', S), np.dtype(S+'20')) + assert_equal(promote_types('i1', S), np.dtype(S+'4')) + assert_equal(promote_types('i2', S), np.dtype(S+'6')) + assert_equal(promote_types('i4', S), np.dtype(S+'11')) + assert_equal(promote_types('i8', S), np.dtype(S+'21')) + # Promote numeric with sized string: + assert_equal(promote_types('bool', S+'1'), np.dtype(S+'5')) + assert_equal(promote_types('bool', S+'30'), np.dtype(S+'30')) + assert_equal(promote_types('b', S+'1'), np.dtype(S+'4')) + assert_equal(promote_types('b', S+'30'), np.dtype(S+'30')) + assert_equal(promote_types('u1', S+'1'), np.dtype(S+'3')) + assert_equal(promote_types('u1', S+'30'), np.dtype(S+'30')) + assert_equal(promote_types('u2', S+'1'), np.dtype(S+'5')) + assert_equal(promote_types('u2', S+'30'), np.dtype(S+'30')) + assert_equal(promote_types('u4', S+'1'), np.dtype(S+'10')) + assert_equal(promote_types('u4', S+'30'), np.dtype(S+'30')) + assert_equal(promote_types('u8', S+'1'), np.dtype(S+'20')) + assert_equal(promote_types('u8', S+'30'), np.dtype(S+'30')) + # Promote with object: + assert_equal(promote_types('O', S+'30'), np.dtype('O')) + + @pytest.mark.parametrize(["dtype1", "dtype2"], + [[np.dtype("V6"), np.dtype("V10")], + [np.dtype([("name1", "i8")]), np.dtype([("name2", "i8")])], + [np.dtype("i8,i8"), np.dtype("i4,i4")], + ]) + def test_invalid_void_promotion(self, dtype1, dtype2): + # Mainly test structured void promotion, which currently allows + # byte-swapping, but nothing else: + with pytest.raises(TypeError): + np.promote_types(dtype1, dtype2) + + @pytest.mark.parametrize(["dtype1", "dtype2"], + [[np.dtype("V10"), np.dtype("V10")], + [np.dtype([("name1", "i8")])], + [np.dtype("i8,i8"), np.dtype("i8,>i8")], + ]) + def test_valid_void_promotion(self, dtype1, dtype2): + assert np.promote_types(dtype1, dtype2) is dtype1 + + @pytest.mark.parametrize("dtype", + list(np.typecodes["All"]) + + ["i,i", "S3", "S100", "U3", "U100", rational]) + def test_promote_identical_types_metadata(self, dtype): + # The same type passed in twice to promote types always + # preserves metadata + metadata = {1: 1} + dtype = np.dtype(dtype, metadata=metadata) + + res = np.promote_types(dtype, dtype) + assert res.metadata == dtype.metadata + + # byte-swapping preserves and makes the dtype native: + dtype = dtype.newbyteorder() + if dtype.isnative: + # The type does not have byte swapping + return + + res = np.promote_types(dtype, dtype) + if res.char in "?bhilqpBHILQPefdgFDGOmM" or dtype.type is rational: + # Metadata is lost for simple promotions (they create a new dtype) + assert res.metadata is None + else: + assert res.metadata == metadata + if dtype.kind != "V": + # the result is native (except for structured void) + assert res.isnative + + @pytest.mark.slow + @pytest.mark.parametrize(["dtype1", "dtype2"], + itertools.product( + list(np.typecodes["All"]) + + ["i,i", "S3", "S100", "U3", "U100", rational], + repeat=2)) + def test_promote_types_metadata(self, dtype1, dtype2): + """Metadata handling in promotion does not appear formalized + right now in NumPy. This test should thus be considered to + document behaviour, rather than test the correct definition of it. + + This test is very ugly, it was useful for rewriting part of the + promotion, but probably should eventually be replaced/deleted + (i.e. when metadata handling in promotion is better defined). + """ + metadata1 = {1: 1} + metadata2 = {2: 2} + dtype1 = np.dtype(dtype1, metadata=metadata1) + dtype2 = np.dtype(dtype2, metadata=metadata2) + + try: + res = np.promote_types(dtype1, dtype2) + except TypeError: + # Promotion failed, this test only checks metadata + return + + if res.char in "?bhilqpBHILQPefdgFDGOmM" or res.type is rational: + # All simple types lose metadata (due to using promotion table): + assert res.metadata is None + elif res == dtype1: + # If one result is the result, it is usually returned unchanged: + assert res is dtype1 + elif res == dtype2: + # dtype1 may have been cast to the same type/kind as dtype2. + # If the resulting dtype is identical we currently pick the cast + # version of dtype1, which lost the metadata: + if np.promote_types(dtype1, dtype2.kind) == dtype2: + res.metadata is None + else: + res.metadata == metadata2 + else: + assert res.metadata is None + + # Try again for byteswapped version + dtype1 = dtype1.newbyteorder() + assert dtype1.metadata == metadata1 + res_bs = np.promote_types(dtype1, dtype2) + if res_bs.names is not None: + # Structured promotion doesn't remove byteswap: + assert res_bs.newbyteorder() == res + else: + assert res_bs == res + assert res_bs.metadata == res.metadata + + @pytest.mark.parametrize(["dtype1", "dtype2"], + [[np.dtype("V6"), np.dtype("V10")], + [np.dtype([("name1", "i8")]), np.dtype([("name2", "i8")])], + [np.dtype("i8,i8"), np.dtype("i4,i4")], + ]) + def test_invalid_void_promotion(self, dtype1, dtype2): + # Mainly test structured void promotion, which currently allows + # byte-swapping, but nothing else: + with pytest.raises(TypeError): + np.promote_types(dtype1, dtype2) + + @pytest.mark.parametrize(["dtype1", "dtype2"], + [[np.dtype("V10"), np.dtype("V10")], + [np.dtype([("name1", "i8")])], + [np.dtype("i8,i8"), np.dtype("i8,>i8")], + ]) + def test_valid_void_promotion(self, dtype1, dtype2): + assert np.promote_types(dtype1, dtype2) is dtype1 + + def test_can_cast(self): + assert_(np.can_cast(np.int32, np.int64)) + assert_(np.can_cast(np.float64, complex)) + assert_(not np.can_cast(complex, float)) + + assert_(np.can_cast('i8', 'f8')) + assert_(not np.can_cast('i8', 'f4')) + assert_(np.can_cast('i4', 'S11')) + + assert_(np.can_cast('i8', 'i8', 'no')) + assert_(not np.can_cast('i8', 'no')) + + assert_(np.can_cast('i8', 'equiv')) + assert_(not np.can_cast('i8', 'equiv')) + + assert_(np.can_cast('i8', 'safe')) + assert_(not np.can_cast('i4', 'safe')) + + assert_(np.can_cast('i4', 'same_kind')) + assert_(not np.can_cast('u4', 'same_kind')) + + assert_(np.can_cast('u4', 'unsafe')) + + assert_(np.can_cast('bool', 'S5')) + assert_(not np.can_cast('bool', 'S4')) + + assert_(np.can_cast('b', 'S4')) + assert_(not np.can_cast('b', 'S3')) + + assert_(np.can_cast('u1', 'S3')) + assert_(not np.can_cast('u1', 'S2')) + assert_(np.can_cast('u2', 'S5')) + assert_(not np.can_cast('u2', 'S4')) + assert_(np.can_cast('u4', 'S10')) + assert_(not np.can_cast('u4', 'S9')) + assert_(np.can_cast('u8', 'S20')) + assert_(not np.can_cast('u8', 'S19')) + + assert_(np.can_cast('i1', 'S4')) + assert_(not np.can_cast('i1', 'S3')) + assert_(np.can_cast('i2', 'S6')) + assert_(not np.can_cast('i2', 'S5')) + assert_(np.can_cast('i4', 'S11')) + assert_(not np.can_cast('i4', 'S10')) + assert_(np.can_cast('i8', 'S21')) + assert_(not np.can_cast('i8', 'S20')) + + assert_(np.can_cast('bool', 'S5')) + assert_(not np.can_cast('bool', 'S4')) + + assert_(np.can_cast('b', 'U4')) + assert_(not np.can_cast('b', 'U3')) + + assert_(np.can_cast('u1', 'U3')) + assert_(not np.can_cast('u1', 'U2')) + assert_(np.can_cast('u2', 'U5')) + assert_(not np.can_cast('u2', 'U4')) + assert_(np.can_cast('u4', 'U10')) + assert_(not np.can_cast('u4', 'U9')) + assert_(np.can_cast('u8', 'U20')) + assert_(not np.can_cast('u8', 'U19')) + + assert_(np.can_cast('i1', 'U4')) + assert_(not np.can_cast('i1', 'U3')) + assert_(np.can_cast('i2', 'U6')) + assert_(not np.can_cast('i2', 'U5')) + assert_(np.can_cast('i4', 'U11')) + assert_(not np.can_cast('i4', 'U10')) + assert_(np.can_cast('i8', 'U21')) + assert_(not np.can_cast('i8', 'U20')) + + assert_raises(TypeError, np.can_cast, 'i4', None) + assert_raises(TypeError, np.can_cast, None, 'i4') + + # Also test keyword arguments + assert_(np.can_cast(from_=np.int32, to=np.int64)) + + def test_can_cast_simple_to_structured(self): + # Non-structured can only be cast to structured in 'unsafe' mode. + assert_(not np.can_cast('i4', 'i4,i4')) + assert_(not np.can_cast('i4', 'i4,i2')) + assert_(np.can_cast('i4', 'i4,i4', casting='unsafe')) + assert_(np.can_cast('i4', 'i4,i2', casting='unsafe')) + # Even if there is just a single field which is OK. + assert_(not np.can_cast('i2', [('f1', 'i4')])) + assert_(not np.can_cast('i2', [('f1', 'i4')], casting='same_kind')) + assert_(np.can_cast('i2', [('f1', 'i4')], casting='unsafe')) + # It should be the same for recursive structured or subarrays. + assert_(not np.can_cast('i2', [('f1', 'i4,i4')])) + assert_(np.can_cast('i2', [('f1', 'i4,i4')], casting='unsafe')) + assert_(not np.can_cast('i2', [('f1', '(2,3)i4')])) + assert_(np.can_cast('i2', [('f1', '(2,3)i4')], casting='unsafe')) + + def test_can_cast_structured_to_simple(self): + # Need unsafe casting for structured to simple. + assert_(not np.can_cast([('f1', 'i4')], 'i4')) + assert_(np.can_cast([('f1', 'i4')], 'i4', casting='unsafe')) + assert_(np.can_cast([('f1', 'i4')], 'i2', casting='unsafe')) + # Since it is unclear what is being cast, multiple fields to + # single should not work even for unsafe casting. + assert_(not np.can_cast('i4,i4', 'i4', casting='unsafe')) + # But a single field inside a single field is OK. + assert_(not np.can_cast([('f1', [('x', 'i4')])], 'i4')) + assert_(np.can_cast([('f1', [('x', 'i4')])], 'i4', casting='unsafe')) + # And a subarray is fine too - it will just take the first element + # (arguably not very consistently; might also take the first field). + assert_(not np.can_cast([('f0', '(3,)i4')], 'i4')) + assert_(np.can_cast([('f0', '(3,)i4')], 'i4', casting='unsafe')) + # But a structured subarray with multiple fields should fail. + assert_(not np.can_cast([('f0', ('i4,i4'), (2,))], 'i4', + casting='unsafe')) + + def test_can_cast_values(self): + # gh-5917 + for dt in np.sctypes['int'] + np.sctypes['uint']: + ii = np.iinfo(dt) + assert_(np.can_cast(ii.min, dt)) + assert_(np.can_cast(ii.max, dt)) + assert_(not np.can_cast(ii.min - 1, dt)) + assert_(not np.can_cast(ii.max + 1, dt)) + + for dt in np.sctypes['float']: + fi = np.finfo(dt) + assert_(np.can_cast(fi.min, dt)) + assert_(np.can_cast(fi.max, dt)) + + +# Custom exception class to test exception propagation in fromiter +class NIterError(Exception): + pass + + +class TestFromiter: + def makegen(self): + return (x**2 for x in range(24)) + + def test_types(self): + ai32 = np.fromiter(self.makegen(), np.int32) + ai64 = np.fromiter(self.makegen(), np.int64) + af = np.fromiter(self.makegen(), float) + assert_(ai32.dtype == np.dtype(np.int32)) + assert_(ai64.dtype == np.dtype(np.int64)) + assert_(af.dtype == np.dtype(float)) + + def test_lengths(self): + expected = np.array(list(self.makegen())) + a = np.fromiter(self.makegen(), int) + a20 = np.fromiter(self.makegen(), int, 20) + assert_(len(a) == len(expected)) + assert_(len(a20) == 20) + assert_raises(ValueError, np.fromiter, + self.makegen(), int, len(expected) + 10) + + def test_values(self): + expected = np.array(list(self.makegen())) + a = np.fromiter(self.makegen(), int) + a20 = np.fromiter(self.makegen(), int, 20) + assert_(np.alltrue(a == expected, axis=0)) + assert_(np.alltrue(a20 == expected[:20], axis=0)) + + def load_data(self, n, eindex): + # Utility method for the issue 2592 tests. + # Raise an exception at the desired index in the iterator. + for e in range(n): + if e == eindex: + raise NIterError('error at index %s' % eindex) + yield e + + def test_2592(self): + # Test iteration exceptions are correctly raised. + count, eindex = 10, 5 + assert_raises(NIterError, np.fromiter, + self.load_data(count, eindex), dtype=int, count=count) + + def test_2592_edge(self): + # Test iter. exceptions, edge case (exception at end of iterator). + count = 10 + eindex = count-1 + assert_raises(NIterError, np.fromiter, + self.load_data(count, eindex), dtype=int, count=count) + + +class TestNonzero: + def test_nonzero_trivial(self): + assert_equal(np.count_nonzero(np.array([])), 0) + assert_equal(np.count_nonzero(np.array([], dtype='?')), 0) + assert_equal(np.nonzero(np.array([])), ([],)) + + assert_equal(np.count_nonzero(np.array([0])), 0) + assert_equal(np.count_nonzero(np.array([0], dtype='?')), 0) + assert_equal(np.nonzero(np.array([0])), ([],)) + + assert_equal(np.count_nonzero(np.array([1])), 1) + assert_equal(np.count_nonzero(np.array([1], dtype='?')), 1) + assert_equal(np.nonzero(np.array([1])), ([0],)) + + def test_nonzero_zerod(self): + assert_equal(np.count_nonzero(np.array(0)), 0) + assert_equal(np.count_nonzero(np.array(0, dtype='?')), 0) + with assert_warns(DeprecationWarning): + assert_equal(np.nonzero(np.array(0)), ([],)) + + assert_equal(np.count_nonzero(np.array(1)), 1) + assert_equal(np.count_nonzero(np.array(1, dtype='?')), 1) + with assert_warns(DeprecationWarning): + assert_equal(np.nonzero(np.array(1)), ([0],)) + + def test_nonzero_onedim(self): + x = np.array([1, 0, 2, -1, 0, 0, 8]) + assert_equal(np.count_nonzero(x), 4) + assert_equal(np.count_nonzero(x), 4) + assert_equal(np.nonzero(x), ([0, 2, 3, 6],)) + + x = np.array([(1, 2), (0, 0), (1, 1), (-1, 3), (0, 7)], + dtype=[('a', 'i4'), ('b', 'i2')]) + assert_equal(np.count_nonzero(x['a']), 3) + assert_equal(np.count_nonzero(x['b']), 4) + assert_equal(np.nonzero(x['a']), ([0, 2, 3],)) + assert_equal(np.nonzero(x['b']), ([0, 2, 3, 4],)) + + def test_nonzero_twodim(self): + x = np.array([[0, 1, 0], [2, 0, 3]]) + assert_equal(np.count_nonzero(x), 3) + assert_equal(np.nonzero(x), ([0, 1, 1], [1, 0, 2])) + + x = np.eye(3) + assert_equal(np.count_nonzero(x), 3) + assert_equal(np.nonzero(x), ([0, 1, 2], [0, 1, 2])) + + x = np.array([[(0, 1), (0, 0), (1, 11)], + [(1, 1), (1, 0), (0, 0)], + [(0, 0), (1, 5), (0, 1)]], dtype=[('a', 'f4'), ('b', 'u1')]) + assert_equal(np.count_nonzero(x['a']), 4) + assert_equal(np.count_nonzero(x['b']), 5) + assert_equal(np.nonzero(x['a']), ([0, 1, 1, 2], [2, 0, 1, 1])) + assert_equal(np.nonzero(x['b']), ([0, 0, 1, 2, 2], [0, 2, 0, 1, 2])) + + assert_(not x['a'].T.flags.aligned) + assert_equal(np.count_nonzero(x['a'].T), 4) + assert_equal(np.count_nonzero(x['b'].T), 5) + assert_equal(np.nonzero(x['a'].T), ([0, 1, 1, 2], [1, 1, 2, 0])) + assert_equal(np.nonzero(x['b'].T), ([0, 0, 1, 2, 2], [0, 1, 2, 0, 2])) + + def test_sparse(self): + # test special sparse condition boolean code path + for i in range(20): + c = np.zeros(200, dtype=bool) + c[i::20] = True + assert_equal(np.nonzero(c)[0], np.arange(i, 200 + i, 20)) + + c = np.zeros(400, dtype=bool) + c[10 + i:20 + i] = True + c[20 + i*2] = True + assert_equal(np.nonzero(c)[0], + np.concatenate((np.arange(10 + i, 20 + i), [20 + i*2]))) + + def test_return_type(self): + class C(np.ndarray): + pass + + for view in (C, np.ndarray): + for nd in range(1, 4): + shape = tuple(range(2, 2+nd)) + x = np.arange(np.prod(shape)).reshape(shape).view(view) + for nzx in (np.nonzero(x), x.nonzero()): + for nzx_i in nzx: + assert_(type(nzx_i) is np.ndarray) + assert_(nzx_i.flags.writeable) + + def test_count_nonzero_axis(self): + # Basic check of functionality + m = np.array([[0, 1, 7, 0, 0], [3, 0, 0, 2, 19]]) + + expected = np.array([1, 1, 1, 1, 1]) + assert_equal(np.count_nonzero(m, axis=0), expected) + + expected = np.array([2, 3]) + assert_equal(np.count_nonzero(m, axis=1), expected) + + assert_raises(ValueError, np.count_nonzero, m, axis=(1, 1)) + assert_raises(TypeError, np.count_nonzero, m, axis='foo') + assert_raises(np.AxisError, np.count_nonzero, m, axis=3) + assert_raises(TypeError, np.count_nonzero, + m, axis=np.array([[1], [2]])) + + def test_count_nonzero_axis_all_dtypes(self): + # More thorough test that the axis argument is respected + # for all dtypes and responds correctly when presented with + # either integer or tuple arguments for axis + msg = "Mismatch for dtype: %s" + + def assert_equal_w_dt(a, b, err_msg): + assert_equal(a.dtype, b.dtype, err_msg=err_msg) + assert_equal(a, b, err_msg=err_msg) + + for dt in np.typecodes['All']: + err_msg = msg % (np.dtype(dt).name,) + + if dt != 'V': + if dt != 'M': + m = np.zeros((3, 3), dtype=dt) + n = np.ones(1, dtype=dt) + + m[0, 0] = n[0] + m[1, 0] = n[0] + + else: # np.zeros doesn't work for np.datetime64 + m = np.array(['1970-01-01'] * 9) + m = m.reshape((3, 3)) + + m[0, 0] = '1970-01-12' + m[1, 0] = '1970-01-12' + m = m.astype(dt) + + expected = np.array([2, 0, 0], dtype=np.intp) + assert_equal_w_dt(np.count_nonzero(m, axis=0), + expected, err_msg=err_msg) + + expected = np.array([1, 1, 0], dtype=np.intp) + assert_equal_w_dt(np.count_nonzero(m, axis=1), + expected, err_msg=err_msg) + + expected = np.array(2) + assert_equal(np.count_nonzero(m, axis=(0, 1)), + expected, err_msg=err_msg) + assert_equal(np.count_nonzero(m, axis=None), + expected, err_msg=err_msg) + assert_equal(np.count_nonzero(m), + expected, err_msg=err_msg) + + if dt == 'V': + # There are no 'nonzero' objects for np.void, so the testing + # setup is slightly different for this dtype + m = np.array([np.void(1)] * 6).reshape((2, 3)) + + expected = np.array([0, 0, 0], dtype=np.intp) + assert_equal_w_dt(np.count_nonzero(m, axis=0), + expected, err_msg=err_msg) + + expected = np.array([0, 0], dtype=np.intp) + assert_equal_w_dt(np.count_nonzero(m, axis=1), + expected, err_msg=err_msg) + + expected = np.array(0) + assert_equal(np.count_nonzero(m, axis=(0, 1)), + expected, err_msg=err_msg) + assert_equal(np.count_nonzero(m, axis=None), + expected, err_msg=err_msg) + assert_equal(np.count_nonzero(m), + expected, err_msg=err_msg) + + def test_count_nonzero_axis_consistent(self): + # Check that the axis behaviour for valid axes in + # non-special cases is consistent (and therefore + # correct) by checking it against an integer array + # that is then casted to the generic object dtype + from itertools import combinations, permutations + + axis = (0, 1, 2, 3) + size = (5, 5, 5, 5) + msg = "Mismatch for axis: %s" + + rng = np.random.RandomState(1234) + m = rng.randint(-100, 100, size=size) + n = m.astype(object) + + for length in range(len(axis)): + for combo in combinations(axis, length): + for perm in permutations(combo): + assert_equal( + np.count_nonzero(m, axis=perm), + np.count_nonzero(n, axis=perm), + err_msg=msg % (perm,)) + + def test_countnonzero_axis_empty(self): + a = np.array([[0, 0, 1], [1, 0, 1]]) + assert_equal(np.count_nonzero(a, axis=()), a.astype(bool)) + + def test_countnonzero_keepdims(self): + a = np.array([[0, 0, 1, 0], + [0, 3, 5, 0], + [7, 9, 2, 0]]) + assert_equal(np.count_nonzero(a, axis=0, keepdims=True), + [[1, 2, 3, 0]]) + assert_equal(np.count_nonzero(a, axis=1, keepdims=True), + [[1], [2], [3]]) + assert_equal(np.count_nonzero(a, keepdims=True), + [[6]]) + + def test_array_method(self): + # Tests that the array method + # call to nonzero works + m = np.array([[1, 0, 0], [4, 0, 6]]) + tgt = [[0, 1, 1], [0, 0, 2]] + + assert_equal(m.nonzero(), tgt) + + def test_nonzero_invalid_object(self): + # gh-9295 + a = np.array([np.array([1, 2]), 3], dtype=object) + assert_raises(ValueError, np.nonzero, a) + + class BoolErrors: + def __bool__(self): + raise ValueError("Not allowed") + + assert_raises(ValueError, np.nonzero, np.array([BoolErrors()])) + + def test_nonzero_sideeffect_safety(self): + # gh-13631 + class FalseThenTrue: + _val = False + def __bool__(self): + try: + return self._val + finally: + self._val = True + + class TrueThenFalse: + _val = True + def __bool__(self): + try: + return self._val + finally: + self._val = False + + # result grows on the second pass + a = np.array([True, FalseThenTrue()]) + assert_raises(RuntimeError, np.nonzero, a) + + a = np.array([[True], [FalseThenTrue()]]) + assert_raises(RuntimeError, np.nonzero, a) + + # result shrinks on the second pass + a = np.array([False, TrueThenFalse()]) + assert_raises(RuntimeError, np.nonzero, a) + + a = np.array([[False], [TrueThenFalse()]]) + assert_raises(RuntimeError, np.nonzero, a) + + def test_nonzero_exception_safe(self): + # gh-13930 + + class ThrowsAfter: + def __init__(self, iters): + self.iters_left = iters + + def __bool__(self): + if self.iters_left == 0: + raise ValueError("called `iters` times") + + self.iters_left -= 1 + return True + + """ + Test that a ValueError is raised instead of a SystemError + + If the __bool__ function is called after the error state is set, + Python (cpython) will raise a SystemError. + """ + + # assert that an exception in first pass is handled correctly + a = np.array([ThrowsAfter(5)]*10) + assert_raises(ValueError, np.nonzero, a) + + # raise exception in second pass for 1-dimensional loop + a = np.array([ThrowsAfter(15)]*10) + assert_raises(ValueError, np.nonzero, a) + + # raise exception in second pass for n-dimensional loop + a = np.array([[ThrowsAfter(15)]]*10) + assert_raises(ValueError, np.nonzero, a) + + def test_structured_threadsafety(self): + # Nonzero (and some other functions) should be threadsafe for + # structured datatypes, see gh-15387. This test can behave randomly. + from concurrent.futures import ThreadPoolExecutor + + # Create a deeply nested dtype to make a failure more likely: + dt = np.dtype([("", "f8")]) + dt = np.dtype([("", dt)]) + dt = np.dtype([("", dt)] * 2) + # The array should be large enough to likely run into threading issues + arr = np.random.uniform(size=(5000, 4)).view(dt)[:, 0] + def func(arr): + arr.nonzero() + + tpe = ThreadPoolExecutor(max_workers=8) + futures = [tpe.submit(func, arr) for _ in range(10)] + for f in futures: + f.result() + + assert arr.dtype is dt + + +class TestIndex: + def test_boolean(self): + a = rand(3, 5, 8) + V = rand(5, 8) + g1 = randint(0, 5, size=15) + g2 = randint(0, 8, size=15) + V[g1, g2] = -V[g1, g2] + assert_((np.array([a[0][V > 0], a[1][V > 0], a[2][V > 0]]) == a[:, V > 0]).all()) + + def test_boolean_edgecase(self): + a = np.array([], dtype='int32') + b = np.array([], dtype='bool') + c = a[b] + assert_equal(c, []) + assert_equal(c.dtype, np.dtype('int32')) + + +class TestBinaryRepr: + def test_zero(self): + assert_equal(np.binary_repr(0), '0') + + def test_positive(self): + assert_equal(np.binary_repr(10), '1010') + assert_equal(np.binary_repr(12522), + '11000011101010') + assert_equal(np.binary_repr(10736848), + '101000111101010011010000') + + def test_negative(self): + assert_equal(np.binary_repr(-1), '-1') + assert_equal(np.binary_repr(-10), '-1010') + assert_equal(np.binary_repr(-12522), + '-11000011101010') + assert_equal(np.binary_repr(-10736848), + '-101000111101010011010000') + + def test_sufficient_width(self): + assert_equal(np.binary_repr(0, width=5), '00000') + assert_equal(np.binary_repr(10, width=7), '0001010') + assert_equal(np.binary_repr(-5, width=7), '1111011') + + def test_neg_width_boundaries(self): + # see gh-8670 + + # Ensure that the example in the issue does not + # break before proceeding to a more thorough test. + assert_equal(np.binary_repr(-128, width=8), '10000000') + + for width in range(1, 11): + num = -2**(width - 1) + exp = '1' + (width - 1) * '0' + assert_equal(np.binary_repr(num, width=width), exp) + + def test_large_neg_int64(self): + # See gh-14289. + assert_equal(np.binary_repr(np.int64(-2**62), width=64), + '11' + '0'*62) + + +class TestBaseRepr: + def test_base3(self): + assert_equal(np.base_repr(3**5, 3), '100000') + + def test_positive(self): + assert_equal(np.base_repr(12, 10), '12') + assert_equal(np.base_repr(12, 10, 4), '000012') + assert_equal(np.base_repr(12, 4), '30') + assert_equal(np.base_repr(3731624803700888, 36), '10QR0ROFCEW') + + def test_negative(self): + assert_equal(np.base_repr(-12, 10), '-12') + assert_equal(np.base_repr(-12, 10, 4), '-000012') + assert_equal(np.base_repr(-12, 4), '-30') + + def test_base_range(self): + with assert_raises(ValueError): + np.base_repr(1, 1) + with assert_raises(ValueError): + np.base_repr(1, 37) + + +class TestArrayComparisons: + def test_array_equal(self): + res = np.array_equal(np.array([1, 2]), np.array([1, 2])) + assert_(res) + assert_(type(res) is bool) + res = np.array_equal(np.array([1, 2]), np.array([1, 2, 3])) + assert_(not res) + assert_(type(res) is bool) + res = np.array_equal(np.array([1, 2]), np.array([3, 4])) + assert_(not res) + assert_(type(res) is bool) + res = np.array_equal(np.array([1, 2]), np.array([1, 3])) + assert_(not res) + assert_(type(res) is bool) + res = np.array_equal(np.array(['a'], dtype='S1'), np.array(['a'], dtype='S1')) + assert_(res) + assert_(type(res) is bool) + res = np.array_equal(np.array([('a', 1)], dtype='S1,u4'), + np.array([('a', 1)], dtype='S1,u4')) + assert_(res) + assert_(type(res) is bool) + + def test_array_equal_equal_nan(self): + # Test array_equal with equal_nan kwarg + a1 = np.array([1, 2, np.nan]) + a2 = np.array([1, np.nan, 2]) + a3 = np.array([1, 2, np.inf]) + + # equal_nan=False by default + assert_(not np.array_equal(a1, a1)) + assert_(np.array_equal(a1, a1, equal_nan=True)) + assert_(not np.array_equal(a1, a2, equal_nan=True)) + # nan's not conflated with inf's + assert_(not np.array_equal(a1, a3, equal_nan=True)) + # 0-D arrays + a = np.array(np.nan) + assert_(not np.array_equal(a, a)) + assert_(np.array_equal(a, a, equal_nan=True)) + # Non-float dtype - equal_nan should have no effect + a = np.array([1, 2, 3], dtype=int) + assert_(np.array_equal(a, a)) + assert_(np.array_equal(a, a, equal_nan=True)) + # Multi-dimensional array + a = np.array([[0, 1], [np.nan, 1]]) + assert_(not np.array_equal(a, a)) + assert_(np.array_equal(a, a, equal_nan=True)) + # Complex values + a, b = [np.array([1 + 1j])]*2 + a.real, b.imag = np.nan, np.nan + assert_(not np.array_equal(a, b, equal_nan=False)) + assert_(np.array_equal(a, b, equal_nan=True)) + + def test_none_compares_elementwise(self): + a = np.array([None, 1, None], dtype=object) + assert_equal(a == None, [True, False, True]) + assert_equal(a != None, [False, True, False]) + + a = np.ones(3) + assert_equal(a == None, [False, False, False]) + assert_equal(a != None, [True, True, True]) + + def test_array_equiv(self): + res = np.array_equiv(np.array([1, 2]), np.array([1, 2])) + assert_(res) + assert_(type(res) is bool) + res = np.array_equiv(np.array([1, 2]), np.array([1, 2, 3])) + assert_(not res) + assert_(type(res) is bool) + res = np.array_equiv(np.array([1, 2]), np.array([3, 4])) + assert_(not res) + assert_(type(res) is bool) + res = np.array_equiv(np.array([1, 2]), np.array([1, 3])) + assert_(not res) + assert_(type(res) is bool) + + res = np.array_equiv(np.array([1, 1]), np.array([1])) + assert_(res) + assert_(type(res) is bool) + res = np.array_equiv(np.array([1, 1]), np.array([[1], [1]])) + assert_(res) + assert_(type(res) is bool) + res = np.array_equiv(np.array([1, 2]), np.array([2])) + assert_(not res) + assert_(type(res) is bool) + res = np.array_equiv(np.array([1, 2]), np.array([[1], [2]])) + assert_(not res) + assert_(type(res) is bool) + res = np.array_equiv(np.array([1, 2]), np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])) + assert_(not res) + assert_(type(res) is bool) + + +def assert_array_strict_equal(x, y): + assert_array_equal(x, y) + # Check flags, 32 bit arches typically don't provide 16 byte alignment + if ((x.dtype.alignment <= 8 or + np.intp().dtype.itemsize != 4) and + sys.platform != 'win32'): + assert_(x.flags == y.flags) + else: + assert_(x.flags.owndata == y.flags.owndata) + assert_(x.flags.writeable == y.flags.writeable) + assert_(x.flags.c_contiguous == y.flags.c_contiguous) + assert_(x.flags.f_contiguous == y.flags.f_contiguous) + assert_(x.flags.writebackifcopy == y.flags.writebackifcopy) + # check endianness + assert_(x.dtype.isnative == y.dtype.isnative) + + +class TestClip: + def setup(self): + self.nr = 5 + self.nc = 3 + + def fastclip(self, a, m, M, out=None, casting=None): + if out is None: + if casting is None: + return a.clip(m, M) + else: + return a.clip(m, M, casting=casting) + else: + if casting is None: + return a.clip(m, M, out) + else: + return a.clip(m, M, out, casting=casting) + + def clip(self, a, m, M, out=None): + # use slow-clip + selector = np.less(a, m) + 2*np.greater(a, M) + return selector.choose((a, m, M), out=out) + + # Handy functions + def _generate_data(self, n, m): + return randn(n, m) + + def _generate_data_complex(self, n, m): + return randn(n, m) + 1.j * rand(n, m) + + def _generate_flt_data(self, n, m): + return (randn(n, m)).astype(np.float32) + + def _neg_byteorder(self, a): + a = np.asarray(a) + if sys.byteorder == 'little': + a = a.astype(a.dtype.newbyteorder('>')) + else: + a = a.astype(a.dtype.newbyteorder('<')) + return a + + def _generate_non_native_data(self, n, m): + data = randn(n, m) + data = self._neg_byteorder(data) + assert_(not data.dtype.isnative) + return data + + def _generate_int_data(self, n, m): + return (10 * rand(n, m)).astype(np.int64) + + def _generate_int32_data(self, n, m): + return (10 * rand(n, m)).astype(np.int32) + + # Now the real test cases + + @pytest.mark.parametrize("dtype", '?bhilqpBHILQPefdgFDGO') + def test_ones_pathological(self, dtype): + # for preservation of behavior described in + # gh-12519; amin > amax behavior may still change + # in the future + arr = np.ones(10, dtype=dtype) + expected = np.zeros(10, dtype=dtype) + actual = np.clip(arr, 1, 0) + if dtype == 'O': + assert actual.tolist() == expected.tolist() + else: + assert_equal(actual, expected) + + def test_simple_double(self): + # Test native double input with scalar min/max. + a = self._generate_data(self.nr, self.nc) + m = 0.1 + M = 0.6 + ac = self.fastclip(a, m, M) + act = self.clip(a, m, M) + assert_array_strict_equal(ac, act) + + def test_simple_int(self): + # Test native int input with scalar min/max. + a = self._generate_int_data(self.nr, self.nc) + a = a.astype(int) + m = -2 + M = 4 + ac = self.fastclip(a, m, M) + act = self.clip(a, m, M) + assert_array_strict_equal(ac, act) + + def test_array_double(self): + # Test native double input with array min/max. + a = self._generate_data(self.nr, self.nc) + m = np.zeros(a.shape) + M = m + 0.5 + ac = self.fastclip(a, m, M) + act = self.clip(a, m, M) + assert_array_strict_equal(ac, act) + + def test_simple_nonnative(self): + # Test non native double input with scalar min/max. + # Test native double input with non native double scalar min/max. + a = self._generate_non_native_data(self.nr, self.nc) + m = -0.5 + M = 0.6 + ac = self.fastclip(a, m, M) + act = self.clip(a, m, M) + assert_array_equal(ac, act) + + # Test native double input with non native double scalar min/max. + a = self._generate_data(self.nr, self.nc) + m = -0.5 + M = self._neg_byteorder(0.6) + assert_(not M.dtype.isnative) + ac = self.fastclip(a, m, M) + act = self.clip(a, m, M) + assert_array_equal(ac, act) + + def test_simple_complex(self): + # Test native complex input with native double scalar min/max. + # Test native input with complex double scalar min/max. + a = 3 * self._generate_data_complex(self.nr, self.nc) + m = -0.5 + M = 1. + ac = self.fastclip(a, m, M) + act = self.clip(a, m, M) + assert_array_strict_equal(ac, act) + + # Test native input with complex double scalar min/max. + a = 3 * self._generate_data(self.nr, self.nc) + m = -0.5 + 1.j + M = 1. + 2.j + ac = self.fastclip(a, m, M) + act = self.clip(a, m, M) + assert_array_strict_equal(ac, act) + + def test_clip_complex(self): + # Address Issue gh-5354 for clipping complex arrays + # Test native complex input without explicit min/max + # ie, either min=None or max=None + a = np.ones(10, dtype=complex) + m = a.min() + M = a.max() + am = self.fastclip(a, m, None) + aM = self.fastclip(a, None, M) + assert_array_strict_equal(am, a) + assert_array_strict_equal(aM, a) + + def test_clip_non_contig(self): + # Test clip for non contiguous native input and native scalar min/max. + a = self._generate_data(self.nr * 2, self.nc * 3) + a = a[::2, ::3] + assert_(not a.flags['F_CONTIGUOUS']) + assert_(not a.flags['C_CONTIGUOUS']) + ac = self.fastclip(a, -1.6, 1.7) + act = self.clip(a, -1.6, 1.7) + assert_array_strict_equal(ac, act) + + def test_simple_out(self): + # Test native double input with scalar min/max. + a = self._generate_data(self.nr, self.nc) + m = -0.5 + M = 0.6 + ac = np.zeros(a.shape) + act = np.zeros(a.shape) + self.fastclip(a, m, M, ac) + self.clip(a, m, M, act) + assert_array_strict_equal(ac, act) + + @pytest.mark.parametrize("casting", [None, "unsafe"]) + def test_simple_int32_inout(self, casting): + # Test native int32 input with double min/max and int32 out. + a = self._generate_int32_data(self.nr, self.nc) + m = np.float64(0) + M = np.float64(2) + ac = np.zeros(a.shape, dtype=np.int32) + act = ac.copy() + if casting is None: + with assert_warns(DeprecationWarning): + # NumPy 1.17.0, 2018-02-24 - casting is unsafe + self.fastclip(a, m, M, ac, casting=casting) + else: + # explicitly passing "unsafe" will silence warning + self.fastclip(a, m, M, ac, casting=casting) + self.clip(a, m, M, act) + assert_array_strict_equal(ac, act) + + def test_simple_int64_out(self): + # Test native int32 input with int32 scalar min/max and int64 out. + a = self._generate_int32_data(self.nr, self.nc) + m = np.int32(-1) + M = np.int32(1) + ac = np.zeros(a.shape, dtype=np.int64) + act = ac.copy() + self.fastclip(a, m, M, ac) + self.clip(a, m, M, act) + assert_array_strict_equal(ac, act) + + def test_simple_int64_inout(self): + # Test native int32 input with double array min/max and int32 out. + a = self._generate_int32_data(self.nr, self.nc) + m = np.zeros(a.shape, np.float64) + M = np.float64(1) + ac = np.zeros(a.shape, dtype=np.int32) + act = ac.copy() + with assert_warns(DeprecationWarning): + # NumPy 1.17.0, 2018-02-24 - casting is unsafe + self.fastclip(a, m, M, ac) + self.clip(a, m, M, act) + assert_array_strict_equal(ac, act) + + def test_simple_int32_out(self): + # Test native double input with scalar min/max and int out. + a = self._generate_data(self.nr, self.nc) + m = -1.0 + M = 2.0 + ac = np.zeros(a.shape, dtype=np.int32) + act = ac.copy() + with assert_warns(DeprecationWarning): + # NumPy 1.17.0, 2018-02-24 - casting is unsafe + self.fastclip(a, m, M, ac) + self.clip(a, m, M, act) + assert_array_strict_equal(ac, act) + + def test_simple_inplace_01(self): + # Test native double input with array min/max in-place. + a = self._generate_data(self.nr, self.nc) + ac = a.copy() + m = np.zeros(a.shape) + M = 1.0 + self.fastclip(a, m, M, a) + self.clip(a, m, M, ac) + assert_array_strict_equal(a, ac) + + def test_simple_inplace_02(self): + # Test native double input with scalar min/max in-place. + a = self._generate_data(self.nr, self.nc) + ac = a.copy() + m = -0.5 + M = 0.6 + self.fastclip(a, m, M, a) + self.clip(ac, m, M, ac) + assert_array_strict_equal(a, ac) + + def test_noncontig_inplace(self): + # Test non contiguous double input with double scalar min/max in-place. + a = self._generate_data(self.nr * 2, self.nc * 3) + a = a[::2, ::3] + assert_(not a.flags['F_CONTIGUOUS']) + assert_(not a.flags['C_CONTIGUOUS']) + ac = a.copy() + m = -0.5 + M = 0.6 + self.fastclip(a, m, M, a) + self.clip(ac, m, M, ac) + assert_array_equal(a, ac) + + def test_type_cast_01(self): + # Test native double input with scalar min/max. + a = self._generate_data(self.nr, self.nc) + m = -0.5 + M = 0.6 + ac = self.fastclip(a, m, M) + act = self.clip(a, m, M) + assert_array_strict_equal(ac, act) + + def test_type_cast_02(self): + # Test native int32 input with int32 scalar min/max. + a = self._generate_int_data(self.nr, self.nc) + a = a.astype(np.int32) + m = -2 + M = 4 + ac = self.fastclip(a, m, M) + act = self.clip(a, m, M) + assert_array_strict_equal(ac, act) + + def test_type_cast_03(self): + # Test native int32 input with float64 scalar min/max. + a = self._generate_int32_data(self.nr, self.nc) + m = -2 + M = 4 + ac = self.fastclip(a, np.float64(m), np.float64(M)) + act = self.clip(a, np.float64(m), np.float64(M)) + assert_array_strict_equal(ac, act) + + def test_type_cast_04(self): + # Test native int32 input with float32 scalar min/max. + a = self._generate_int32_data(self.nr, self.nc) + m = np.float32(-2) + M = np.float32(4) + act = self.fastclip(a, m, M) + ac = self.clip(a, m, M) + assert_array_strict_equal(ac, act) + + def test_type_cast_05(self): + # Test native int32 with double arrays min/max. + a = self._generate_int_data(self.nr, self.nc) + m = -0.5 + M = 1. + ac = self.fastclip(a, m * np.zeros(a.shape), M) + act = self.clip(a, m * np.zeros(a.shape), M) + assert_array_strict_equal(ac, act) + + def test_type_cast_06(self): + # Test native with NON native scalar min/max. + a = self._generate_data(self.nr, self.nc) + m = 0.5 + m_s = self._neg_byteorder(m) + M = 1. + act = self.clip(a, m_s, M) + ac = self.fastclip(a, m_s, M) + assert_array_strict_equal(ac, act) + + def test_type_cast_07(self): + # Test NON native with native array min/max. + a = self._generate_data(self.nr, self.nc) + m = -0.5 * np.ones(a.shape) + M = 1. + a_s = self._neg_byteorder(a) + assert_(not a_s.dtype.isnative) + act = a_s.clip(m, M) + ac = self.fastclip(a_s, m, M) + assert_array_strict_equal(ac, act) + + def test_type_cast_08(self): + # Test NON native with native scalar min/max. + a = self._generate_data(self.nr, self.nc) + m = -0.5 + M = 1. + a_s = self._neg_byteorder(a) + assert_(not a_s.dtype.isnative) + ac = self.fastclip(a_s, m, M) + act = a_s.clip(m, M) + assert_array_strict_equal(ac, act) + + def test_type_cast_09(self): + # Test native with NON native array min/max. + a = self._generate_data(self.nr, self.nc) + m = -0.5 * np.ones(a.shape) + M = 1. + m_s = self._neg_byteorder(m) + assert_(not m_s.dtype.isnative) + ac = self.fastclip(a, m_s, M) + act = self.clip(a, m_s, M) + assert_array_strict_equal(ac, act) + + def test_type_cast_10(self): + # Test native int32 with float min/max and float out for output argument. + a = self._generate_int_data(self.nr, self.nc) + b = np.zeros(a.shape, dtype=np.float32) + m = np.float32(-0.5) + M = np.float32(1) + act = self.clip(a, m, M, out=b) + ac = self.fastclip(a, m, M, out=b) + assert_array_strict_equal(ac, act) + + def test_type_cast_11(self): + # Test non native with native scalar, min/max, out non native + a = self._generate_non_native_data(self.nr, self.nc) + b = a.copy() + b = b.astype(b.dtype.newbyteorder('>')) + bt = b.copy() + m = -0.5 + M = 1. + self.fastclip(a, m, M, out=b) + self.clip(a, m, M, out=bt) + assert_array_strict_equal(b, bt) + + def test_type_cast_12(self): + # Test native int32 input and min/max and float out + a = self._generate_int_data(self.nr, self.nc) + b = np.zeros(a.shape, dtype=np.float32) + m = np.int32(0) + M = np.int32(1) + act = self.clip(a, m, M, out=b) + ac = self.fastclip(a, m, M, out=b) + assert_array_strict_equal(ac, act) + + def test_clip_with_out_simple(self): + # Test native double input with scalar min/max + a = self._generate_data(self.nr, self.nc) + m = -0.5 + M = 0.6 + ac = np.zeros(a.shape) + act = np.zeros(a.shape) + self.fastclip(a, m, M, ac) + self.clip(a, m, M, act) + assert_array_strict_equal(ac, act) + + def test_clip_with_out_simple2(self): + # Test native int32 input with double min/max and int32 out + a = self._generate_int32_data(self.nr, self.nc) + m = np.float64(0) + M = np.float64(2) + ac = np.zeros(a.shape, dtype=np.int32) + act = ac.copy() + with assert_warns(DeprecationWarning): + # NumPy 1.17.0, 2018-02-24 - casting is unsafe + self.fastclip(a, m, M, ac) + self.clip(a, m, M, act) + assert_array_strict_equal(ac, act) + + def test_clip_with_out_simple_int32(self): + # Test native int32 input with int32 scalar min/max and int64 out + a = self._generate_int32_data(self.nr, self.nc) + m = np.int32(-1) + M = np.int32(1) + ac = np.zeros(a.shape, dtype=np.int64) + act = ac.copy() + self.fastclip(a, m, M, ac) + self.clip(a, m, M, act) + assert_array_strict_equal(ac, act) + + def test_clip_with_out_array_int32(self): + # Test native int32 input with double array min/max and int32 out + a = self._generate_int32_data(self.nr, self.nc) + m = np.zeros(a.shape, np.float64) + M = np.float64(1) + ac = np.zeros(a.shape, dtype=np.int32) + act = ac.copy() + with assert_warns(DeprecationWarning): + # NumPy 1.17.0, 2018-02-24 - casting is unsafe + self.fastclip(a, m, M, ac) + self.clip(a, m, M, act) + assert_array_strict_equal(ac, act) + + def test_clip_with_out_array_outint32(self): + # Test native double input with scalar min/max and int out + a = self._generate_data(self.nr, self.nc) + m = -1.0 + M = 2.0 + ac = np.zeros(a.shape, dtype=np.int32) + act = ac.copy() + with assert_warns(DeprecationWarning): + # NumPy 1.17.0, 2018-02-24 - casting is unsafe + self.fastclip(a, m, M, ac) + self.clip(a, m, M, act) + assert_array_strict_equal(ac, act) + + def test_clip_with_out_transposed(self): + # Test that the out argument works when transposed + a = np.arange(16).reshape(4, 4) + out = np.empty_like(a).T + a.clip(4, 10, out=out) + expected = self.clip(a, 4, 10) + assert_array_equal(out, expected) + + def test_clip_with_out_memory_overlap(self): + # Test that the out argument works when it has memory overlap + a = np.arange(16).reshape(4, 4) + ac = a.copy() + a[:-1].clip(4, 10, out=a[1:]) + expected = self.clip(ac[:-1], 4, 10) + assert_array_equal(a[1:], expected) + + def test_clip_inplace_array(self): + # Test native double input with array min/max + a = self._generate_data(self.nr, self.nc) + ac = a.copy() + m = np.zeros(a.shape) + M = 1.0 + self.fastclip(a, m, M, a) + self.clip(a, m, M, ac) + assert_array_strict_equal(a, ac) + + def test_clip_inplace_simple(self): + # Test native double input with scalar min/max + a = self._generate_data(self.nr, self.nc) + ac = a.copy() + m = -0.5 + M = 0.6 + self.fastclip(a, m, M, a) + self.clip(a, m, M, ac) + assert_array_strict_equal(a, ac) + + def test_clip_func_takes_out(self): + # Ensure that the clip() function takes an out=argument. + a = self._generate_data(self.nr, self.nc) + ac = a.copy() + m = -0.5 + M = 0.6 + a2 = np.clip(a, m, M, out=a) + self.clip(a, m, M, ac) + assert_array_strict_equal(a2, ac) + assert_(a2 is a) + + def test_clip_nan(self): + d = np.arange(7.) + with assert_warns(DeprecationWarning): + assert_equal(d.clip(min=np.nan), d) + with assert_warns(DeprecationWarning): + assert_equal(d.clip(max=np.nan), d) + with assert_warns(DeprecationWarning): + assert_equal(d.clip(min=np.nan, max=np.nan), d) + with assert_warns(DeprecationWarning): + assert_equal(d.clip(min=-2, max=np.nan), d) + with assert_warns(DeprecationWarning): + assert_equal(d.clip(min=np.nan, max=10), d) + + def test_object_clip(self): + a = np.arange(10, dtype=object) + actual = np.clip(a, 1, 5) + expected = np.array([1, 1, 2, 3, 4, 5, 5, 5, 5, 5]) + assert actual.tolist() == expected.tolist() + + def test_clip_all_none(self): + a = np.arange(10, dtype=object) + with assert_raises_regex(ValueError, 'max or min'): + np.clip(a, None, None) + + def test_clip_invalid_casting(self): + a = np.arange(10, dtype=object) + with assert_raises_regex(ValueError, + 'casting must be one of'): + self.fastclip(a, 1, 8, casting="garbage") + + @pytest.mark.parametrize("amin, amax", [ + # two scalars + (1, 0), + # mix scalar and array + (1, np.zeros(10)), + # two arrays + (np.ones(10), np.zeros(10)), + ]) + def test_clip_value_min_max_flip(self, amin, amax): + a = np.arange(10, dtype=np.int64) + # requirement from ufunc_docstrings.py + expected = np.minimum(np.maximum(a, amin), amax) + actual = np.clip(a, amin, amax) + assert_equal(actual, expected) + + @pytest.mark.parametrize("arr, amin, amax, exp", [ + # for a bug in npy_ObjectClip, based on a + # case produced by hypothesis + (np.zeros(10, dtype=np.int64), + 0, + -2**64+1, + np.full(10, -2**64+1, dtype=object)), + # for bugs in NPY_TIMEDELTA_MAX, based on a case + # produced by hypothesis + (np.zeros(10, dtype='m8') - 1, + 0, + 0, + np.zeros(10, dtype='m8')), + ]) + def test_clip_problem_cases(self, arr, amin, amax, exp): + actual = np.clip(arr, amin, amax) + assert_equal(actual, exp) + + @pytest.mark.xfail(reason="no scalar nan propagation yet", + raises=AssertionError, + strict=True) + @pytest.mark.parametrize("arr, amin, amax", [ + # problematic scalar nan case from hypothesis + (np.zeros(10, dtype=np.int64), + np.array(np.nan), + np.zeros(10, dtype=np.int32)), + ]) + @pytest.mark.filterwarnings("ignore::DeprecationWarning") + def test_clip_scalar_nan_propagation(self, arr, amin, amax): + # enforcement of scalar nan propagation for comparisons + # called through clip() + expected = np.minimum(np.maximum(arr, amin), amax) + actual = np.clip(arr, amin, amax) + assert_equal(actual, expected) + + @pytest.mark.xfail(reason="propagation doesn't match spec") + @pytest.mark.parametrize("arr, amin, amax", [ + (np.array([1] * 10, dtype='m8'), + np.timedelta64('NaT'), + np.zeros(10, dtype=np.int32)), + ]) + @pytest.mark.filterwarnings("ignore::DeprecationWarning") + def test_NaT_propagation(self, arr, amin, amax): + # NOTE: the expected function spec doesn't + # propagate NaT, but clip() now does + expected = np.minimum(np.maximum(arr, amin), amax) + actual = np.clip(arr, amin, amax) + assert_equal(actual, expected) + + @given(data=st.data(), shape=hynp.array_shapes()) + def test_clip_property(self, data, shape): + """A property-based test using Hypothesis. + + This aims for maximum generality: it could in principle generate *any* + valid inputs to np.clip, and in practice generates much more varied + inputs than human testers come up with. + + Because many of the inputs have tricky dependencies - compatible dtypes + and mutually-broadcastable shapes - we use `st.data()` strategy draw + values *inside* the test function, from strategies we construct based + on previous values. An alternative would be to define a custom strategy + with `@st.composite`, but until we have duplicated code inline is fine. + + That accounts for most of the function; the actual test is just three + lines to calculate and compare actual vs expected results! + """ + # Our base array and bounds should not need to be of the same type as + # long as they are all compatible - so we allow any int or float type. + dtype_strategy = hynp.integer_dtypes() | hynp.floating_dtypes() + + # The following line is a total hack to disable the varied-dtypes + # component of this test, because result != expected if dtypes can vary. + dtype_strategy = st.just(data.draw(dtype_strategy)) + + # Generate an arbitrary array of the chosen shape and dtype + # This is the value that we clip. + arr = data.draw(hynp.arrays(dtype=dtype_strategy, shape=shape)) + + # Generate shapes for the bounds which can be broadcast with each other + # and with the base shape. Below, we might decide to use scalar bounds, + # but it's clearer to generate these shapes unconditionally in advance. + in_shapes, result_shape = data.draw( + hynp.mutually_broadcastable_shapes( + num_shapes=2, + base_shape=shape, + # Commenting out the min_dims line allows zero-dimensional arrays, + # and zero-dimensional arrays containing NaN make the test fail. + min_dims=1 + + ) + ) + amin = data.draw( + dtype_strategy.flatmap(hynp.from_dtype) + | hynp.arrays(dtype=dtype_strategy, shape=in_shapes[0]) + ) + amax = data.draw( + dtype_strategy.flatmap(hynp.from_dtype) + | hynp.arrays(dtype=dtype_strategy, shape=in_shapes[1]) + ) + # If we allow either bound to be a scalar `nan`, the test will fail - + # so we just "assume" that away (if it is, this raises a special + # exception and Hypothesis will try again with different inputs) + assume(not np.isscalar(amin) or not np.isnan(amin)) + assume(not np.isscalar(amax) or not np.isnan(amax)) + + # Then calculate our result and expected result and check that they're + # equal! See gh-12519 for discussion deciding on this property. + result = np.clip(arr, amin, amax) + expected = np.minimum(amax, np.maximum(arr, amin)) + assert_array_equal(result, expected) + + +class TestAllclose: + rtol = 1e-5 + atol = 1e-8 + + def setup(self): + self.olderr = np.seterr(invalid='ignore') + + def teardown(self): + np.seterr(**self.olderr) + + def tst_allclose(self, x, y): + assert_(np.allclose(x, y), "%s and %s not close" % (x, y)) + + def tst_not_allclose(self, x, y): + assert_(not np.allclose(x, y), "%s and %s shouldn't be close" % (x, y)) + + def test_ip_allclose(self): + # Parametric test factory. + arr = np.array([100, 1000]) + aran = np.arange(125).reshape((5, 5, 5)) + + atol = self.atol + rtol = self.rtol + + data = [([1, 0], [1, 0]), + ([atol], [0]), + ([1], [1+rtol+atol]), + (arr, arr + arr*rtol), + (arr, arr + arr*rtol + atol*2), + (aran, aran + aran*rtol), + (np.inf, np.inf), + (np.inf, [np.inf])] + + for (x, y) in data: + self.tst_allclose(x, y) + + def test_ip_not_allclose(self): + # Parametric test factory. + aran = np.arange(125).reshape((5, 5, 5)) + + atol = self.atol + rtol = self.rtol + + data = [([np.inf, 0], [1, np.inf]), + ([np.inf, 0], [1, 0]), + ([np.inf, np.inf], [1, np.inf]), + ([np.inf, np.inf], [1, 0]), + ([-np.inf, 0], [np.inf, 0]), + ([np.nan, 0], [np.nan, 0]), + ([atol*2], [0]), + ([1], [1+rtol+atol*2]), + (aran, aran + aran*atol + atol*2), + (np.array([np.inf, 1]), np.array([0, np.inf]))] + + for (x, y) in data: + self.tst_not_allclose(x, y) + + def test_no_parameter_modification(self): + x = np.array([np.inf, 1]) + y = np.array([0, np.inf]) + np.allclose(x, y) + assert_array_equal(x, np.array([np.inf, 1])) + assert_array_equal(y, np.array([0, np.inf])) + + def test_min_int(self): + # Could make problems because of abs(min_int) == min_int + min_int = np.iinfo(np.int_).min + a = np.array([min_int], dtype=np.int_) + assert_(np.allclose(a, a)) + + def test_equalnan(self): + x = np.array([1.0, np.nan]) + assert_(np.allclose(x, x, equal_nan=True)) + + def test_return_class_is_ndarray(self): + # Issue gh-6475 + # Check that allclose does not preserve subtypes + class Foo(np.ndarray): + def __new__(cls, *args, **kwargs): + return np.array(*args, **kwargs).view(cls) + + a = Foo([1]) + assert_(type(np.allclose(a, a)) is bool) + + +class TestIsclose: + rtol = 1e-5 + atol = 1e-8 + + def setup(self): + atol = self.atol + rtol = self.rtol + arr = np.array([100, 1000]) + aran = np.arange(125).reshape((5, 5, 5)) + + self.all_close_tests = [ + ([1, 0], [1, 0]), + ([atol], [0]), + ([1], [1 + rtol + atol]), + (arr, arr + arr*rtol), + (arr, arr + arr*rtol + atol), + (aran, aran + aran*rtol), + (np.inf, np.inf), + (np.inf, [np.inf]), + ([np.inf, -np.inf], [np.inf, -np.inf]), + ] + self.none_close_tests = [ + ([np.inf, 0], [1, np.inf]), + ([np.inf, -np.inf], [1, 0]), + ([np.inf, np.inf], [1, -np.inf]), + ([np.inf, np.inf], [1, 0]), + ([np.nan, 0], [np.nan, -np.inf]), + ([atol*2], [0]), + ([1], [1 + rtol + atol*2]), + (aran, aran + rtol*1.1*aran + atol*1.1), + (np.array([np.inf, 1]), np.array([0, np.inf])), + ] + self.some_close_tests = [ + ([np.inf, 0], [np.inf, atol*2]), + ([atol, 1, 1e6*(1 + 2*rtol) + atol], [0, np.nan, 1e6]), + (np.arange(3), [0, 1, 2.1]), + (np.nan, [np.nan, np.nan, np.nan]), + ([0], [atol, np.inf, -np.inf, np.nan]), + (0, [atol, np.inf, -np.inf, np.nan]), + ] + self.some_close_results = [ + [True, False], + [True, False, False], + [True, True, False], + [False, False, False], + [True, False, False, False], + [True, False, False, False], + ] + + def test_ip_isclose(self): + self.setup() + tests = self.some_close_tests + results = self.some_close_results + for (x, y), result in zip(tests, results): + assert_array_equal(np.isclose(x, y), result) + + def tst_all_isclose(self, x, y): + assert_(np.all(np.isclose(x, y)), "%s and %s not close" % (x, y)) + + def tst_none_isclose(self, x, y): + msg = "%s and %s shouldn't be close" + assert_(not np.any(np.isclose(x, y)), msg % (x, y)) + + def tst_isclose_allclose(self, x, y): + msg = "isclose.all() and allclose aren't same for %s and %s" + msg2 = "isclose and allclose aren't same for %s and %s" + if np.isscalar(x) and np.isscalar(y): + assert_(np.isclose(x, y) == np.allclose(x, y), msg=msg2 % (x, y)) + else: + assert_array_equal(np.isclose(x, y).all(), np.allclose(x, y), msg % (x, y)) + + def test_ip_all_isclose(self): + self.setup() + for (x, y) in self.all_close_tests: + self.tst_all_isclose(x, y) + + def test_ip_none_isclose(self): + self.setup() + for (x, y) in self.none_close_tests: + self.tst_none_isclose(x, y) + + def test_ip_isclose_allclose(self): + self.setup() + tests = (self.all_close_tests + self.none_close_tests + + self.some_close_tests) + for (x, y) in tests: + self.tst_isclose_allclose(x, y) + + def test_equal_nan(self): + assert_array_equal(np.isclose(np.nan, np.nan, equal_nan=True), [True]) + arr = np.array([1.0, np.nan]) + assert_array_equal(np.isclose(arr, arr, equal_nan=True), [True, True]) + + def test_masked_arrays(self): + # Make sure to test the output type when arguments are interchanged. + + x = np.ma.masked_where([True, True, False], np.arange(3)) + assert_(type(x) is type(np.isclose(2, x))) + assert_(type(x) is type(np.isclose(x, 2))) + + x = np.ma.masked_where([True, True, False], [np.nan, np.inf, np.nan]) + assert_(type(x) is type(np.isclose(np.inf, x))) + assert_(type(x) is type(np.isclose(x, np.inf))) + + x = np.ma.masked_where([True, True, False], [np.nan, np.nan, np.nan]) + y = np.isclose(np.nan, x, equal_nan=True) + assert_(type(x) is type(y)) + # Ensure that the mask isn't modified... + assert_array_equal([True, True, False], y.mask) + y = np.isclose(x, np.nan, equal_nan=True) + assert_(type(x) is type(y)) + # Ensure that the mask isn't modified... + assert_array_equal([True, True, False], y.mask) + + x = np.ma.masked_where([True, True, False], [np.nan, np.nan, np.nan]) + y = np.isclose(x, x, equal_nan=True) + assert_(type(x) is type(y)) + # Ensure that the mask isn't modified... + assert_array_equal([True, True, False], y.mask) + + def test_scalar_return(self): + assert_(np.isscalar(np.isclose(1, 1))) + + def test_no_parameter_modification(self): + x = np.array([np.inf, 1]) + y = np.array([0, np.inf]) + np.isclose(x, y) + assert_array_equal(x, np.array([np.inf, 1])) + assert_array_equal(y, np.array([0, np.inf])) + + def test_non_finite_scalar(self): + # GH7014, when two scalars are compared the output should also be a + # scalar + assert_(np.isclose(np.inf, -np.inf) is np.False_) + assert_(np.isclose(0, np.inf) is np.False_) + assert_(type(np.isclose(0, np.inf)) is np.bool_) + + def test_timedelta(self): + # Allclose currently works for timedelta64 as long as `atol` is + # an integer or also a timedelta64 + a = np.array([[1, 2, 3, "NaT"]], dtype="m8[ns]") + assert np.isclose(a, a, atol=0, equal_nan=True).all() + assert np.isclose(a, a, atol=np.timedelta64(1, "ns"), equal_nan=True).all() + assert np.allclose(a, a, atol=0, equal_nan=True) + assert np.allclose(a, a, atol=np.timedelta64(1, "ns"), equal_nan=True) + + +class TestStdVar: + def setup(self): + self.A = np.array([1, -1, 1, -1]) + self.real_var = 1 + + def test_basic(self): + assert_almost_equal(np.var(self.A), self.real_var) + assert_almost_equal(np.std(self.A)**2, self.real_var) + + def test_scalars(self): + assert_equal(np.var(1), 0) + assert_equal(np.std(1), 0) + + def test_ddof1(self): + assert_almost_equal(np.var(self.A, ddof=1), + self.real_var*len(self.A)/float(len(self.A)-1)) + assert_almost_equal(np.std(self.A, ddof=1)**2, + self.real_var*len(self.A)/float(len(self.A)-1)) + + def test_ddof2(self): + assert_almost_equal(np.var(self.A, ddof=2), + self.real_var*len(self.A)/float(len(self.A)-2)) + assert_almost_equal(np.std(self.A, ddof=2)**2, + self.real_var*len(self.A)/float(len(self.A)-2)) + + def test_out_scalar(self): + d = np.arange(10) + out = np.array(0.) + r = np.std(d, out=out) + assert_(r is out) + assert_array_equal(r, out) + r = np.var(d, out=out) + assert_(r is out) + assert_array_equal(r, out) + r = np.mean(d, out=out) + assert_(r is out) + assert_array_equal(r, out) + + +class TestStdVarComplex: + def test_basic(self): + A = np.array([1, 1.j, -1, -1.j]) + real_var = 1 + assert_almost_equal(np.var(A), real_var) + assert_almost_equal(np.std(A)**2, real_var) + + def test_scalars(self): + assert_equal(np.var(1j), 0) + assert_equal(np.std(1j), 0) + + +class TestCreationFuncs: + # Test ones, zeros, empty and full. + + def setup(self): + dtypes = {np.dtype(tp) for tp in itertools.chain(*np.sctypes.values())} + # void, bytes, str + variable_sized = {tp for tp in dtypes if tp.str.endswith('0')} + self.dtypes = sorted(dtypes - variable_sized | + {np.dtype(tp.str.replace("0", str(i))) + for tp in variable_sized for i in range(1, 10)}, + key=lambda dtype: dtype.str) + self.orders = {'C': 'c_contiguous', 'F': 'f_contiguous'} + self.ndims = 10 + + def check_function(self, func, fill_value=None): + par = ((0, 1, 2), + range(self.ndims), + self.orders, + self.dtypes) + fill_kwarg = {} + if fill_value is not None: + fill_kwarg = {'fill_value': fill_value} + + for size, ndims, order, dtype in itertools.product(*par): + shape = ndims * [size] + + # do not fill void type + if fill_kwarg and dtype.str.startswith('|V'): + continue + + arr = func(shape, order=order, dtype=dtype, + **fill_kwarg) + + assert_equal(arr.dtype, dtype) + assert_(getattr(arr.flags, self.orders[order])) + + if fill_value is not None: + if dtype.str.startswith('|S'): + val = str(fill_value) + else: + val = fill_value + assert_equal(arr, dtype.type(val)) + + def test_zeros(self): + self.check_function(np.zeros) + + def test_ones(self): + self.check_function(np.ones) + + def test_empty(self): + self.check_function(np.empty) + + def test_full(self): + self.check_function(np.full, 0) + self.check_function(np.full, 1) + + @pytest.mark.skipif(not HAS_REFCOUNT, reason="Python lacks refcounts") + def test_for_reference_leak(self): + # Make sure we have an object for reference + dim = 1 + beg = sys.getrefcount(dim) + np.zeros([dim]*10) + assert_(sys.getrefcount(dim) == beg) + np.ones([dim]*10) + assert_(sys.getrefcount(dim) == beg) + np.empty([dim]*10) + assert_(sys.getrefcount(dim) == beg) + np.full([dim]*10, 0) + assert_(sys.getrefcount(dim) == beg) + + +class TestLikeFuncs: + '''Test ones_like, zeros_like, empty_like and full_like''' + + def setup(self): + self.data = [ + # Array scalars + (np.array(3.), None), + (np.array(3), 'f8'), + # 1D arrays + (np.arange(6, dtype='f4'), None), + (np.arange(6), 'c16'), + # 2D C-layout arrays + (np.arange(6).reshape(2, 3), None), + (np.arange(6).reshape(3, 2), 'i1'), + # 2D F-layout arrays + (np.arange(6).reshape((2, 3), order='F'), None), + (np.arange(6).reshape((3, 2), order='F'), 'i1'), + # 3D C-layout arrays + (np.arange(24).reshape(2, 3, 4), None), + (np.arange(24).reshape(4, 3, 2), 'f4'), + # 3D F-layout arrays + (np.arange(24).reshape((2, 3, 4), order='F'), None), + (np.arange(24).reshape((4, 3, 2), order='F'), 'f4'), + # 3D non-C/F-layout arrays + (np.arange(24).reshape(2, 3, 4).swapaxes(0, 1), None), + (np.arange(24).reshape(4, 3, 2).swapaxes(0, 1), '?'), + ] + self.shapes = [(), (5,), (5,6,), (5,6,7,)] + + def compare_array_value(self, dz, value, fill_value): + if value is not None: + if fill_value: + try: + z = dz.dtype.type(value) + except OverflowError: + pass + else: + assert_(np.all(dz == z)) + else: + assert_(np.all(dz == value)) + + def check_like_function(self, like_function, value, fill_value=False): + if fill_value: + fill_kwarg = {'fill_value': value} + else: + fill_kwarg = {} + for d, dtype in self.data: + # default (K) order, dtype + dz = like_function(d, dtype=dtype, **fill_kwarg) + assert_equal(dz.shape, d.shape) + assert_equal(np.array(dz.strides)*d.dtype.itemsize, + np.array(d.strides)*dz.dtype.itemsize) + assert_equal(d.flags.c_contiguous, dz.flags.c_contiguous) + assert_equal(d.flags.f_contiguous, dz.flags.f_contiguous) + if dtype is None: + assert_equal(dz.dtype, d.dtype) + else: + assert_equal(dz.dtype, np.dtype(dtype)) + self.compare_array_value(dz, value, fill_value) + + # C order, default dtype + dz = like_function(d, order='C', dtype=dtype, **fill_kwarg) + assert_equal(dz.shape, d.shape) + assert_(dz.flags.c_contiguous) + if dtype is None: + assert_equal(dz.dtype, d.dtype) + else: + assert_equal(dz.dtype, np.dtype(dtype)) + self.compare_array_value(dz, value, fill_value) + + # F order, default dtype + dz = like_function(d, order='F', dtype=dtype, **fill_kwarg) + assert_equal(dz.shape, d.shape) + assert_(dz.flags.f_contiguous) + if dtype is None: + assert_equal(dz.dtype, d.dtype) + else: + assert_equal(dz.dtype, np.dtype(dtype)) + self.compare_array_value(dz, value, fill_value) + + # A order + dz = like_function(d, order='A', dtype=dtype, **fill_kwarg) + assert_equal(dz.shape, d.shape) + if d.flags.f_contiguous: + assert_(dz.flags.f_contiguous) + else: + assert_(dz.flags.c_contiguous) + if dtype is None: + assert_equal(dz.dtype, d.dtype) + else: + assert_equal(dz.dtype, np.dtype(dtype)) + self.compare_array_value(dz, value, fill_value) + + # Test the 'shape' parameter + for s in self.shapes: + for o in 'CFA': + sz = like_function(d, dtype=dtype, shape=s, order=o, + **fill_kwarg) + assert_equal(sz.shape, s) + if dtype is None: + assert_equal(sz.dtype, d.dtype) + else: + assert_equal(sz.dtype, np.dtype(dtype)) + if o == 'C' or (o == 'A' and d.flags.c_contiguous): + assert_(sz.flags.c_contiguous) + elif o == 'F' or (o == 'A' and d.flags.f_contiguous): + assert_(sz.flags.f_contiguous) + self.compare_array_value(sz, value, fill_value) + + if (d.ndim != len(s)): + assert_equal(np.argsort(like_function(d, dtype=dtype, + shape=s, order='K', + **fill_kwarg).strides), + np.argsort(np.empty(s, dtype=dtype, + order='C').strides)) + else: + assert_equal(np.argsort(like_function(d, dtype=dtype, + shape=s, order='K', + **fill_kwarg).strides), + np.argsort(d.strides)) + + # Test the 'subok' parameter + class MyNDArray(np.ndarray): + pass + + a = np.array([[1, 2], [3, 4]]).view(MyNDArray) + + b = like_function(a, **fill_kwarg) + assert_(type(b) is MyNDArray) + + b = like_function(a, subok=False, **fill_kwarg) + assert_(type(b) is not MyNDArray) + + def test_ones_like(self): + self.check_like_function(np.ones_like, 1) + + def test_zeros_like(self): + self.check_like_function(np.zeros_like, 0) + + def test_empty_like(self): + self.check_like_function(np.empty_like, None) + + def test_filled_like(self): + self.check_like_function(np.full_like, 0, True) + self.check_like_function(np.full_like, 1, True) + self.check_like_function(np.full_like, 1000, True) + self.check_like_function(np.full_like, 123.456, True) + self.check_like_function(np.full_like, np.inf, True) + + +class TestCorrelate: + def _setup(self, dt): + self.x = np.array([1, 2, 3, 4, 5], dtype=dt) + self.xs = np.arange(1, 20)[::3] + self.y = np.array([-1, -2, -3], dtype=dt) + self.z1 = np.array([ -3., -8., -14., -20., -26., -14., -5.], dtype=dt) + self.z1_4 = np.array([-2., -5., -8., -11., -14., -5.], dtype=dt) + self.z1r = np.array([-15., -22., -22., -16., -10., -4., -1.], dtype=dt) + self.z2 = np.array([-5., -14., -26., -20., -14., -8., -3.], dtype=dt) + self.z2r = np.array([-1., -4., -10., -16., -22., -22., -15.], dtype=dt) + self.zs = np.array([-3., -14., -30., -48., -66., -84., + -102., -54., -19.], dtype=dt) + + def test_float(self): + self._setup(float) + z = np.correlate(self.x, self.y, 'full') + assert_array_almost_equal(z, self.z1) + z = np.correlate(self.x, self.y[:-1], 'full') + assert_array_almost_equal(z, self.z1_4) + z = np.correlate(self.y, self.x, 'full') + assert_array_almost_equal(z, self.z2) + z = np.correlate(self.x[::-1], self.y, 'full') + assert_array_almost_equal(z, self.z1r) + z = np.correlate(self.y, self.x[::-1], 'full') + assert_array_almost_equal(z, self.z2r) + z = np.correlate(self.xs, self.y, 'full') + assert_array_almost_equal(z, self.zs) + + def test_object(self): + self._setup(Decimal) + z = np.correlate(self.x, self.y, 'full') + assert_array_almost_equal(z, self.z1) + z = np.correlate(self.y, self.x, 'full') + assert_array_almost_equal(z, self.z2) + + def test_no_overwrite(self): + d = np.ones(100) + k = np.ones(3) + np.correlate(d, k) + assert_array_equal(d, np.ones(100)) + assert_array_equal(k, np.ones(3)) + + def test_complex(self): + x = np.array([1, 2, 3, 4+1j], dtype=complex) + y = np.array([-1, -2j, 3+1j], dtype=complex) + r_z = np.array([3-1j, 6, 8+1j, 11+5j, -5+8j, -4-1j], dtype=complex) + r_z = r_z[::-1].conjugate() + z = np.correlate(y, x, mode='full') + assert_array_almost_equal(z, r_z) + + def test_zero_size(self): + with pytest.raises(ValueError): + np.correlate(np.array([]), np.ones(1000), mode='full') + with pytest.raises(ValueError): + np.correlate(np.ones(1000), np.array([]), mode='full') + +class TestConvolve: + def test_object(self): + d = [1.] * 100 + k = [1.] * 3 + assert_array_almost_equal(np.convolve(d, k)[2:-2], np.full(98, 3)) + + def test_no_overwrite(self): + d = np.ones(100) + k = np.ones(3) + np.convolve(d, k) + assert_array_equal(d, np.ones(100)) + assert_array_equal(k, np.ones(3)) + + +class TestArgwhere: + + @pytest.mark.parametrize('nd', [0, 1, 2]) + def test_nd(self, nd): + # get an nd array with multiple elements in every dimension + x = np.empty((2,)*nd, bool) + + # none + x[...] = False + assert_equal(np.argwhere(x).shape, (0, nd)) + + # only one + x[...] = False + x.flat[0] = True + assert_equal(np.argwhere(x).shape, (1, nd)) + + # all but one + x[...] = True + x.flat[0] = False + assert_equal(np.argwhere(x).shape, (x.size - 1, nd)) + + # all + x[...] = True + assert_equal(np.argwhere(x).shape, (x.size, nd)) + + def test_2D(self): + x = np.arange(6).reshape((2, 3)) + assert_array_equal(np.argwhere(x > 1), + [[0, 2], + [1, 0], + [1, 1], + [1, 2]]) + + def test_list(self): + assert_equal(np.argwhere([4, 0, 2, 1, 3]), [[0], [2], [3], [4]]) + + +class TestStringFunction: + + def test_set_string_function(self): + a = np.array([1]) + np.set_string_function(lambda x: "FOO", repr=True) + assert_equal(repr(a), "FOO") + np.set_string_function(None, repr=True) + assert_equal(repr(a), "array([1])") + + np.set_string_function(lambda x: "FOO", repr=False) + assert_equal(str(a), "FOO") + np.set_string_function(None, repr=False) + assert_equal(str(a), "[1]") + + +class TestRoll: + def test_roll1d(self): + x = np.arange(10) + xr = np.roll(x, 2) + assert_equal(xr, np.array([8, 9, 0, 1, 2, 3, 4, 5, 6, 7])) + + def test_roll2d(self): + x2 = np.reshape(np.arange(10), (2, 5)) + x2r = np.roll(x2, 1) + assert_equal(x2r, np.array([[9, 0, 1, 2, 3], [4, 5, 6, 7, 8]])) + + x2r = np.roll(x2, 1, axis=0) + assert_equal(x2r, np.array([[5, 6, 7, 8, 9], [0, 1, 2, 3, 4]])) + + x2r = np.roll(x2, 1, axis=1) + assert_equal(x2r, np.array([[4, 0, 1, 2, 3], [9, 5, 6, 7, 8]])) + + # Roll multiple axes at once. + x2r = np.roll(x2, 1, axis=(0, 1)) + assert_equal(x2r, np.array([[9, 5, 6, 7, 8], [4, 0, 1, 2, 3]])) + + x2r = np.roll(x2, (1, 0), axis=(0, 1)) + assert_equal(x2r, np.array([[5, 6, 7, 8, 9], [0, 1, 2, 3, 4]])) + + x2r = np.roll(x2, (-1, 0), axis=(0, 1)) + assert_equal(x2r, np.array([[5, 6, 7, 8, 9], [0, 1, 2, 3, 4]])) + + x2r = np.roll(x2, (0, 1), axis=(0, 1)) + assert_equal(x2r, np.array([[4, 0, 1, 2, 3], [9, 5, 6, 7, 8]])) + + x2r = np.roll(x2, (0, -1), axis=(0, 1)) + assert_equal(x2r, np.array([[1, 2, 3, 4, 0], [6, 7, 8, 9, 5]])) + + x2r = np.roll(x2, (1, 1), axis=(0, 1)) + assert_equal(x2r, np.array([[9, 5, 6, 7, 8], [4, 0, 1, 2, 3]])) + + x2r = np.roll(x2, (-1, -1), axis=(0, 1)) + assert_equal(x2r, np.array([[6, 7, 8, 9, 5], [1, 2, 3, 4, 0]])) + + # Roll the same axis multiple times. + x2r = np.roll(x2, 1, axis=(0, 0)) + assert_equal(x2r, np.array([[0, 1, 2, 3, 4], [5, 6, 7, 8, 9]])) + + x2r = np.roll(x2, 1, axis=(1, 1)) + assert_equal(x2r, np.array([[3, 4, 0, 1, 2], [8, 9, 5, 6, 7]])) + + # Roll more than one turn in either direction. + x2r = np.roll(x2, 6, axis=1) + assert_equal(x2r, np.array([[4, 0, 1, 2, 3], [9, 5, 6, 7, 8]])) + + x2r = np.roll(x2, -4, axis=1) + assert_equal(x2r, np.array([[4, 0, 1, 2, 3], [9, 5, 6, 7, 8]])) + + def test_roll_empty(self): + x = np.array([]) + assert_equal(np.roll(x, 1), np.array([])) + + +class TestRollaxis: + + # expected shape indexed by (axis, start) for array of + # shape (1, 2, 3, 4) + tgtshape = {(0, 0): (1, 2, 3, 4), (0, 1): (1, 2, 3, 4), + (0, 2): (2, 1, 3, 4), (0, 3): (2, 3, 1, 4), + (0, 4): (2, 3, 4, 1), + (1, 0): (2, 1, 3, 4), (1, 1): (1, 2, 3, 4), + (1, 2): (1, 2, 3, 4), (1, 3): (1, 3, 2, 4), + (1, 4): (1, 3, 4, 2), + (2, 0): (3, 1, 2, 4), (2, 1): (1, 3, 2, 4), + (2, 2): (1, 2, 3, 4), (2, 3): (1, 2, 3, 4), + (2, 4): (1, 2, 4, 3), + (3, 0): (4, 1, 2, 3), (3, 1): (1, 4, 2, 3), + (3, 2): (1, 2, 4, 3), (3, 3): (1, 2, 3, 4), + (3, 4): (1, 2, 3, 4)} + + def test_exceptions(self): + a = np.arange(1*2*3*4).reshape(1, 2, 3, 4) + assert_raises(np.AxisError, np.rollaxis, a, -5, 0) + assert_raises(np.AxisError, np.rollaxis, a, 0, -5) + assert_raises(np.AxisError, np.rollaxis, a, 4, 0) + assert_raises(np.AxisError, np.rollaxis, a, 0, 5) + + def test_results(self): + a = np.arange(1*2*3*4).reshape(1, 2, 3, 4).copy() + aind = np.indices(a.shape) + assert_(a.flags['OWNDATA']) + for (i, j) in self.tgtshape: + # positive axis, positive start + res = np.rollaxis(a, axis=i, start=j) + i0, i1, i2, i3 = aind[np.array(res.shape) - 1] + assert_(np.all(res[i0, i1, i2, i3] == a)) + assert_(res.shape == self.tgtshape[(i, j)], str((i,j))) + assert_(not res.flags['OWNDATA']) + + # negative axis, positive start + ip = i + 1 + res = np.rollaxis(a, axis=-ip, start=j) + i0, i1, i2, i3 = aind[np.array(res.shape) - 1] + assert_(np.all(res[i0, i1, i2, i3] == a)) + assert_(res.shape == self.tgtshape[(4 - ip, j)]) + assert_(not res.flags['OWNDATA']) + + # positive axis, negative start + jp = j + 1 if j < 4 else j + res = np.rollaxis(a, axis=i, start=-jp) + i0, i1, i2, i3 = aind[np.array(res.shape) - 1] + assert_(np.all(res[i0, i1, i2, i3] == a)) + assert_(res.shape == self.tgtshape[(i, 4 - jp)]) + assert_(not res.flags['OWNDATA']) + + # negative axis, negative start + ip = i + 1 + jp = j + 1 if j < 4 else j + res = np.rollaxis(a, axis=-ip, start=-jp) + i0, i1, i2, i3 = aind[np.array(res.shape) - 1] + assert_(np.all(res[i0, i1, i2, i3] == a)) + assert_(res.shape == self.tgtshape[(4 - ip, 4 - jp)]) + assert_(not res.flags['OWNDATA']) + + +class TestMoveaxis: + def test_move_to_end(self): + x = np.random.randn(5, 6, 7) + for source, expected in [(0, (6, 7, 5)), + (1, (5, 7, 6)), + (2, (5, 6, 7)), + (-1, (5, 6, 7))]: + actual = np.moveaxis(x, source, -1).shape + assert_(actual, expected) + + def test_move_new_position(self): + x = np.random.randn(1, 2, 3, 4) + for source, destination, expected in [ + (0, 1, (2, 1, 3, 4)), + (1, 2, (1, 3, 2, 4)), + (1, -1, (1, 3, 4, 2)), + ]: + actual = np.moveaxis(x, source, destination).shape + assert_(actual, expected) + + def test_preserve_order(self): + x = np.zeros((1, 2, 3, 4)) + for source, destination in [ + (0, 0), + (3, -1), + (-1, 3), + ([0, -1], [0, -1]), + ([2, 0], [2, 0]), + (range(4), range(4)), + ]: + actual = np.moveaxis(x, source, destination).shape + assert_(actual, (1, 2, 3, 4)) + + def test_move_multiples(self): + x = np.zeros((0, 1, 2, 3)) + for source, destination, expected in [ + ([0, 1], [2, 3], (2, 3, 0, 1)), + ([2, 3], [0, 1], (2, 3, 0, 1)), + ([0, 1, 2], [2, 3, 0], (2, 3, 0, 1)), + ([3, 0], [1, 0], (0, 3, 1, 2)), + ([0, 3], [0, 1], (0, 3, 1, 2)), + ]: + actual = np.moveaxis(x, source, destination).shape + assert_(actual, expected) + + def test_errors(self): + x = np.random.randn(1, 2, 3) + assert_raises_regex(np.AxisError, 'source.*out of bounds', + np.moveaxis, x, 3, 0) + assert_raises_regex(np.AxisError, 'source.*out of bounds', + np.moveaxis, x, -4, 0) + assert_raises_regex(np.AxisError, 'destination.*out of bounds', + np.moveaxis, x, 0, 5) + assert_raises_regex(ValueError, 'repeated axis in `source`', + np.moveaxis, x, [0, 0], [0, 1]) + assert_raises_regex(ValueError, 'repeated axis in `destination`', + np.moveaxis, x, [0, 1], [1, 1]) + assert_raises_regex(ValueError, 'must have the same number', + np.moveaxis, x, 0, [0, 1]) + assert_raises_regex(ValueError, 'must have the same number', + np.moveaxis, x, [0, 1], [0]) + + def test_array_likes(self): + x = np.ma.zeros((1, 2, 3)) + result = np.moveaxis(x, 0, 0) + assert_(x.shape, result.shape) + assert_(isinstance(result, np.ma.MaskedArray)) + + x = [1, 2, 3] + result = np.moveaxis(x, 0, 0) + assert_(x, list(result)) + assert_(isinstance(result, np.ndarray)) + + +class TestCross: + def test_2x2(self): + u = [1, 2] + v = [3, 4] + z = -2 + cp = np.cross(u, v) + assert_equal(cp, z) + cp = np.cross(v, u) + assert_equal(cp, -z) + + def test_2x3(self): + u = [1, 2] + v = [3, 4, 5] + z = np.array([10, -5, -2]) + cp = np.cross(u, v) + assert_equal(cp, z) + cp = np.cross(v, u) + assert_equal(cp, -z) + + def test_3x3(self): + u = [1, 2, 3] + v = [4, 5, 6] + z = np.array([-3, 6, -3]) + cp = np.cross(u, v) + assert_equal(cp, z) + cp = np.cross(v, u) + assert_equal(cp, -z) + + def test_broadcasting(self): + # Ticket #2624 (Trac #2032) + u = np.tile([1, 2], (11, 1)) + v = np.tile([3, 4], (11, 1)) + z = -2 + assert_equal(np.cross(u, v), z) + assert_equal(np.cross(v, u), -z) + assert_equal(np.cross(u, u), 0) + + u = np.tile([1, 2], (11, 1)).T + v = np.tile([3, 4, 5], (11, 1)) + z = np.tile([10, -5, -2], (11, 1)) + assert_equal(np.cross(u, v, axisa=0), z) + assert_equal(np.cross(v, u.T), -z) + assert_equal(np.cross(v, v), 0) + + u = np.tile([1, 2, 3], (11, 1)).T + v = np.tile([3, 4], (11, 1)).T + z = np.tile([-12, 9, -2], (11, 1)) + assert_equal(np.cross(u, v, axisa=0, axisb=0), z) + assert_equal(np.cross(v.T, u.T), -z) + assert_equal(np.cross(u.T, u.T), 0) + + u = np.tile([1, 2, 3], (5, 1)) + v = np.tile([4, 5, 6], (5, 1)).T + z = np.tile([-3, 6, -3], (5, 1)) + assert_equal(np.cross(u, v, axisb=0), z) + assert_equal(np.cross(v.T, u), -z) + assert_equal(np.cross(u, u), 0) + + def test_broadcasting_shapes(self): + u = np.ones((2, 1, 3)) + v = np.ones((5, 3)) + assert_equal(np.cross(u, v).shape, (2, 5, 3)) + u = np.ones((10, 3, 5)) + v = np.ones((2, 5)) + assert_equal(np.cross(u, v, axisa=1, axisb=0).shape, (10, 5, 3)) + assert_raises(np.AxisError, np.cross, u, v, axisa=1, axisb=2) + assert_raises(np.AxisError, np.cross, u, v, axisa=3, axisb=0) + u = np.ones((10, 3, 5, 7)) + v = np.ones((5, 7, 2)) + assert_equal(np.cross(u, v, axisa=1, axisc=2).shape, (10, 5, 3, 7)) + assert_raises(np.AxisError, np.cross, u, v, axisa=-5, axisb=2) + assert_raises(np.AxisError, np.cross, u, v, axisa=1, axisb=-4) + # gh-5885 + u = np.ones((3, 4, 2)) + for axisc in range(-2, 2): + assert_equal(np.cross(u, u, axisc=axisc).shape, (3, 4)) + + +def test_outer_out_param(): + arr1 = np.ones((5,)) + arr2 = np.ones((2,)) + arr3 = np.linspace(-2, 2, 5) + out1 = np.ndarray(shape=(5,5)) + out2 = np.ndarray(shape=(2, 5)) + res1 = np.outer(arr1, arr3, out1) + assert_equal(res1, out1) + assert_equal(np.outer(arr2, arr3, out2), out2) + + +class TestIndices: + + def test_simple(self): + [x, y] = np.indices((4, 3)) + assert_array_equal(x, np.array([[0, 0, 0], + [1, 1, 1], + [2, 2, 2], + [3, 3, 3]])) + assert_array_equal(y, np.array([[0, 1, 2], + [0, 1, 2], + [0, 1, 2], + [0, 1, 2]])) + + def test_single_input(self): + [x] = np.indices((4,)) + assert_array_equal(x, np.array([0, 1, 2, 3])) + + [x] = np.indices((4,), sparse=True) + assert_array_equal(x, np.array([0, 1, 2, 3])) + + def test_scalar_input(self): + assert_array_equal([], np.indices(())) + assert_array_equal([], np.indices((), sparse=True)) + assert_array_equal([[]], np.indices((0,))) + assert_array_equal([[]], np.indices((0,), sparse=True)) + + def test_sparse(self): + [x, y] = np.indices((4,3), sparse=True) + assert_array_equal(x, np.array([[0], [1], [2], [3]])) + assert_array_equal(y, np.array([[0, 1, 2]])) + + @pytest.mark.parametrize("dtype", [np.int32, np.int64, np.float32, np.float64]) + @pytest.mark.parametrize("dims", [(), (0,), (4, 3)]) + def test_return_type(self, dtype, dims): + inds = np.indices(dims, dtype=dtype) + assert_(inds.dtype == dtype) + + for arr in np.indices(dims, dtype=dtype, sparse=True): + assert_(arr.dtype == dtype) + + +class TestRequire: + flag_names = ['C', 'C_CONTIGUOUS', 'CONTIGUOUS', + 'F', 'F_CONTIGUOUS', 'FORTRAN', + 'A', 'ALIGNED', + 'W', 'WRITEABLE', + 'O', 'OWNDATA'] + + def generate_all_false(self, dtype): + arr = np.zeros((2, 2), [('junk', 'i1'), ('a', dtype)]) + arr.setflags(write=False) + a = arr['a'] + assert_(not a.flags['C']) + assert_(not a.flags['F']) + assert_(not a.flags['O']) + assert_(not a.flags['W']) + assert_(not a.flags['A']) + return a + + def set_and_check_flag(self, flag, dtype, arr): + if dtype is None: + dtype = arr.dtype + b = np.require(arr, dtype, [flag]) + assert_(b.flags[flag]) + assert_(b.dtype == dtype) + + # a further call to np.require ought to return the same array + # unless OWNDATA is specified. + c = np.require(b, None, [flag]) + if flag[0] != 'O': + assert_(c is b) + else: + assert_(c.flags[flag]) + + def test_require_each(self): + + id = ['f8', 'i4'] + fd = [None, 'f8', 'c16'] + for idtype, fdtype, flag in itertools.product(id, fd, self.flag_names): + a = self.generate_all_false(idtype) + self.set_and_check_flag(flag, fdtype, a) + + def test_unknown_requirement(self): + a = self.generate_all_false('f8') + assert_raises(KeyError, np.require, a, None, 'Q') + + def test_non_array_input(self): + a = np.require([1, 2, 3, 4], 'i4', ['C', 'A', 'O']) + assert_(a.flags['O']) + assert_(a.flags['C']) + assert_(a.flags['A']) + assert_(a.dtype == 'i4') + assert_equal(a, [1, 2, 3, 4]) + + def test_C_and_F_simul(self): + a = self.generate_all_false('f8') + assert_raises(ValueError, np.require, a, None, ['C', 'F']) + + def test_ensure_array(self): + class ArraySubclass(np.ndarray): + pass + + a = ArraySubclass((2, 2)) + b = np.require(a, None, ['E']) + assert_(type(b) is np.ndarray) + + def test_preserve_subtype(self): + class ArraySubclass(np.ndarray): + pass + + for flag in self.flag_names: + a = ArraySubclass((2, 2)) + self.set_and_check_flag(flag, None, a) + + +class TestBroadcast: + def test_broadcast_in_args(self): + # gh-5881 + arrs = [np.empty((6, 7)), np.empty((5, 6, 1)), np.empty((7,)), + np.empty((5, 1, 7))] + mits = [np.broadcast(*arrs), + np.broadcast(np.broadcast(*arrs[:0]), np.broadcast(*arrs[0:])), + np.broadcast(np.broadcast(*arrs[:1]), np.broadcast(*arrs[1:])), + np.broadcast(np.broadcast(*arrs[:2]), np.broadcast(*arrs[2:])), + np.broadcast(arrs[0], np.broadcast(*arrs[1:-1]), arrs[-1])] + for mit in mits: + assert_equal(mit.shape, (5, 6, 7)) + assert_equal(mit.ndim, 3) + assert_equal(mit.nd, 3) + assert_equal(mit.numiter, 4) + for a, ia in zip(arrs, mit.iters): + assert_(a is ia.base) + + def test_broadcast_single_arg(self): + # gh-6899 + arrs = [np.empty((5, 6, 7))] + mit = np.broadcast(*arrs) + assert_equal(mit.shape, (5, 6, 7)) + assert_equal(mit.ndim, 3) + assert_equal(mit.nd, 3) + assert_equal(mit.numiter, 1) + assert_(arrs[0] is mit.iters[0].base) + + def test_number_of_arguments(self): + arr = np.empty((5,)) + for j in range(35): + arrs = [arr] * j + if j > 32: + assert_raises(ValueError, np.broadcast, *arrs) + else: + mit = np.broadcast(*arrs) + assert_equal(mit.numiter, j) + + def test_broadcast_error_kwargs(self): + #gh-13455 + arrs = [np.empty((5, 6, 7))] + mit = np.broadcast(*arrs) + mit2 = np.broadcast(*arrs, **{}) + assert_equal(mit.shape, mit2.shape) + assert_equal(mit.ndim, mit2.ndim) + assert_equal(mit.nd, mit2.nd) + assert_equal(mit.numiter, mit2.numiter) + assert_(mit.iters[0].base is mit2.iters[0].base) + + assert_raises(ValueError, np.broadcast, 1, **{'x': 1}) + +class TestKeepdims: + + class sub_array(np.ndarray): + def sum(self, axis=None, dtype=None, out=None): + return np.ndarray.sum(self, axis, dtype, out, keepdims=True) + + def test_raise(self): + sub_class = self.sub_array + x = np.arange(30).view(sub_class) + assert_raises(TypeError, np.sum, x, keepdims=True) + + +class TestTensordot: + + def test_zero_dimension(self): + # Test resolution to issue #5663 + a = np.ndarray((3,0)) + b = np.ndarray((0,4)) + td = np.tensordot(a, b, (1, 0)) + assert_array_equal(td, np.dot(a, b)) + assert_array_equal(td, np.einsum('ij,jk', a, b)) + + def test_zero_dimensional(self): + # gh-12130 + arr_0d = np.array(1) + ret = np.tensordot(arr_0d, arr_0d, ([], [])) # contracting no axes is well defined + assert_array_equal(ret, arr_0d) diff --git a/venv/Lib/site-packages/numpy/core/tests/test_numerictypes.py b/venv/Lib/site-packages/numpy/core/tests/test_numerictypes.py new file mode 100644 index 0000000..9cb0034 --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/tests/test_numerictypes.py @@ -0,0 +1,554 @@ +import sys +import itertools + +import pytest +import numpy as np +from numpy.testing import assert_, assert_equal, assert_raises, IS_PYPY + +# This is the structure of the table used for plain objects: +# +# +-+-+-+ +# |x|y|z| +# +-+-+-+ + +# Structure of a plain array description: +Pdescr = [ + ('x', 'i4', (2,)), + ('y', 'f8', (2, 2)), + ('z', 'u1')] + +# A plain list of tuples with values for testing: +PbufferT = [ + # x y z + ([3, 2], [[6., 4.], [6., 4.]], 8), + ([4, 3], [[7., 5.], [7., 5.]], 9), + ] + + +# This is the structure of the table used for nested objects (DON'T PANIC!): +# +# +-+---------------------------------+-----+----------+-+-+ +# |x|Info |color|info |y|z| +# | +-----+--+----------------+----+--+ +----+-----+ | | +# | |value|y2|Info2 |name|z2| |Name|Value| | | +# | | | +----+-----+--+--+ | | | | | | | +# | | | |name|value|y3|z3| | | | | | | | +# +-+-----+--+----+-----+--+--+----+--+-----+----+-----+-+-+ +# + +# The corresponding nested array description: +Ndescr = [ + ('x', 'i4', (2,)), + ('Info', [ + ('value', 'c16'), + ('y2', 'f8'), + ('Info2', [ + ('name', 'S2'), + ('value', 'c16', (2,)), + ('y3', 'f8', (2,)), + ('z3', 'u4', (2,))]), + ('name', 'S2'), + ('z2', 'b1')]), + ('color', 'S2'), + ('info', [ + ('Name', 'U8'), + ('Value', 'c16')]), + ('y', 'f8', (2, 2)), + ('z', 'u1')] + +NbufferT = [ + # x Info color info y z + # value y2 Info2 name z2 Name Value + # name value y3 z3 + ([3, 2], (6j, 6., (b'nn', [6j, 4j], [6., 4.], [1, 2]), b'NN', True), b'cc', (u'NN', 6j), [[6., 4.], [6., 4.]], 8), + ([4, 3], (7j, 7., (b'oo', [7j, 5j], [7., 5.], [2, 1]), b'OO', False), b'dd', (u'OO', 7j), [[7., 5.], [7., 5.]], 9), + ] + + +byteorder = {'little':'<', 'big':'>'}[sys.byteorder] + +def normalize_descr(descr): + "Normalize a description adding the platform byteorder." + + out = [] + for item in descr: + dtype = item[1] + if isinstance(dtype, str): + if dtype[0] not in ['|', '<', '>']: + onebyte = dtype[1:] == "1" + if onebyte or dtype[0] in ['S', 'V', 'b']: + dtype = "|" + dtype + else: + dtype = byteorder + dtype + if len(item) > 2 and np.prod(item[2]) > 1: + nitem = (item[0], dtype, item[2]) + else: + nitem = (item[0], dtype) + out.append(nitem) + elif isinstance(dtype, list): + l = normalize_descr(dtype) + out.append((item[0], l)) + else: + raise ValueError("Expected a str or list and got %s" % + (type(item))) + return out + + +############################################################ +# Creation tests +############################################################ + +class CreateZeros: + """Check the creation of heterogeneous arrays zero-valued""" + + def test_zeros0D(self): + """Check creation of 0-dimensional objects""" + h = np.zeros((), dtype=self._descr) + assert_(normalize_descr(self._descr) == h.dtype.descr) + assert_(h.dtype.fields['x'][0].name[:4] == 'void') + assert_(h.dtype.fields['x'][0].char == 'V') + assert_(h.dtype.fields['x'][0].type == np.void) + # A small check that data is ok + assert_equal(h['z'], np.zeros((), dtype='u1')) + + def test_zerosSD(self): + """Check creation of single-dimensional objects""" + h = np.zeros((2,), dtype=self._descr) + assert_(normalize_descr(self._descr) == h.dtype.descr) + assert_(h.dtype['y'].name[:4] == 'void') + assert_(h.dtype['y'].char == 'V') + assert_(h.dtype['y'].type == np.void) + # A small check that data is ok + assert_equal(h['z'], np.zeros((2,), dtype='u1')) + + def test_zerosMD(self): + """Check creation of multi-dimensional objects""" + h = np.zeros((2, 3), dtype=self._descr) + assert_(normalize_descr(self._descr) == h.dtype.descr) + assert_(h.dtype['z'].name == 'uint8') + assert_(h.dtype['z'].char == 'B') + assert_(h.dtype['z'].type == np.uint8) + # A small check that data is ok + assert_equal(h['z'], np.zeros((2, 3), dtype='u1')) + + +class TestCreateZerosPlain(CreateZeros): + """Check the creation of heterogeneous arrays zero-valued (plain)""" + _descr = Pdescr + +class TestCreateZerosNested(CreateZeros): + """Check the creation of heterogeneous arrays zero-valued (nested)""" + _descr = Ndescr + + +class CreateValues: + """Check the creation of heterogeneous arrays with values""" + + def test_tuple(self): + """Check creation from tuples""" + h = np.array(self._buffer, dtype=self._descr) + assert_(normalize_descr(self._descr) == h.dtype.descr) + if self.multiple_rows: + assert_(h.shape == (2,)) + else: + assert_(h.shape == ()) + + def test_list_of_tuple(self): + """Check creation from list of tuples""" + h = np.array([self._buffer], dtype=self._descr) + assert_(normalize_descr(self._descr) == h.dtype.descr) + if self.multiple_rows: + assert_(h.shape == (1, 2)) + else: + assert_(h.shape == (1,)) + + def test_list_of_list_of_tuple(self): + """Check creation from list of list of tuples""" + h = np.array([[self._buffer]], dtype=self._descr) + assert_(normalize_descr(self._descr) == h.dtype.descr) + if self.multiple_rows: + assert_(h.shape == (1, 1, 2)) + else: + assert_(h.shape == (1, 1)) + + +class TestCreateValuesPlainSingle(CreateValues): + """Check the creation of heterogeneous arrays (plain, single row)""" + _descr = Pdescr + multiple_rows = 0 + _buffer = PbufferT[0] + +class TestCreateValuesPlainMultiple(CreateValues): + """Check the creation of heterogeneous arrays (plain, multiple rows)""" + _descr = Pdescr + multiple_rows = 1 + _buffer = PbufferT + +class TestCreateValuesNestedSingle(CreateValues): + """Check the creation of heterogeneous arrays (nested, single row)""" + _descr = Ndescr + multiple_rows = 0 + _buffer = NbufferT[0] + +class TestCreateValuesNestedMultiple(CreateValues): + """Check the creation of heterogeneous arrays (nested, multiple rows)""" + _descr = Ndescr + multiple_rows = 1 + _buffer = NbufferT + + +############################################################ +# Reading tests +############################################################ + +class ReadValuesPlain: + """Check the reading of values in heterogeneous arrays (plain)""" + + def test_access_fields(self): + h = np.array(self._buffer, dtype=self._descr) + if not self.multiple_rows: + assert_(h.shape == ()) + assert_equal(h['x'], np.array(self._buffer[0], dtype='i4')) + assert_equal(h['y'], np.array(self._buffer[1], dtype='f8')) + assert_equal(h['z'], np.array(self._buffer[2], dtype='u1')) + else: + assert_(len(h) == 2) + assert_equal(h['x'], np.array([self._buffer[0][0], + self._buffer[1][0]], dtype='i4')) + assert_equal(h['y'], np.array([self._buffer[0][1], + self._buffer[1][1]], dtype='f8')) + assert_equal(h['z'], np.array([self._buffer[0][2], + self._buffer[1][2]], dtype='u1')) + + +class TestReadValuesPlainSingle(ReadValuesPlain): + """Check the creation of heterogeneous arrays (plain, single row)""" + _descr = Pdescr + multiple_rows = 0 + _buffer = PbufferT[0] + +class TestReadValuesPlainMultiple(ReadValuesPlain): + """Check the values of heterogeneous arrays (plain, multiple rows)""" + _descr = Pdescr + multiple_rows = 1 + _buffer = PbufferT + +class ReadValuesNested: + """Check the reading of values in heterogeneous arrays (nested)""" + + def test_access_top_fields(self): + """Check reading the top fields of a nested array""" + h = np.array(self._buffer, dtype=self._descr) + if not self.multiple_rows: + assert_(h.shape == ()) + assert_equal(h['x'], np.array(self._buffer[0], dtype='i4')) + assert_equal(h['y'], np.array(self._buffer[4], dtype='f8')) + assert_equal(h['z'], np.array(self._buffer[5], dtype='u1')) + else: + assert_(len(h) == 2) + assert_equal(h['x'], np.array([self._buffer[0][0], + self._buffer[1][0]], dtype='i4')) + assert_equal(h['y'], np.array([self._buffer[0][4], + self._buffer[1][4]], dtype='f8')) + assert_equal(h['z'], np.array([self._buffer[0][5], + self._buffer[1][5]], dtype='u1')) + + def test_nested1_acessors(self): + """Check reading the nested fields of a nested array (1st level)""" + h = np.array(self._buffer, dtype=self._descr) + if not self.multiple_rows: + assert_equal(h['Info']['value'], + np.array(self._buffer[1][0], dtype='c16')) + assert_equal(h['Info']['y2'], + np.array(self._buffer[1][1], dtype='f8')) + assert_equal(h['info']['Name'], + np.array(self._buffer[3][0], dtype='U2')) + assert_equal(h['info']['Value'], + np.array(self._buffer[3][1], dtype='c16')) + else: + assert_equal(h['Info']['value'], + np.array([self._buffer[0][1][0], + self._buffer[1][1][0]], + dtype='c16')) + assert_equal(h['Info']['y2'], + np.array([self._buffer[0][1][1], + self._buffer[1][1][1]], + dtype='f8')) + assert_equal(h['info']['Name'], + np.array([self._buffer[0][3][0], + self._buffer[1][3][0]], + dtype='U2')) + assert_equal(h['info']['Value'], + np.array([self._buffer[0][3][1], + self._buffer[1][3][1]], + dtype='c16')) + + def test_nested2_acessors(self): + """Check reading the nested fields of a nested array (2nd level)""" + h = np.array(self._buffer, dtype=self._descr) + if not self.multiple_rows: + assert_equal(h['Info']['Info2']['value'], + np.array(self._buffer[1][2][1], dtype='c16')) + assert_equal(h['Info']['Info2']['z3'], + np.array(self._buffer[1][2][3], dtype='u4')) + else: + assert_equal(h['Info']['Info2']['value'], + np.array([self._buffer[0][1][2][1], + self._buffer[1][1][2][1]], + dtype='c16')) + assert_equal(h['Info']['Info2']['z3'], + np.array([self._buffer[0][1][2][3], + self._buffer[1][1][2][3]], + dtype='u4')) + + def test_nested1_descriptor(self): + """Check access nested descriptors of a nested array (1st level)""" + h = np.array(self._buffer, dtype=self._descr) + assert_(h.dtype['Info']['value'].name == 'complex128') + assert_(h.dtype['Info']['y2'].name == 'float64') + assert_(h.dtype['info']['Name'].name == 'str256') + assert_(h.dtype['info']['Value'].name == 'complex128') + + def test_nested2_descriptor(self): + """Check access nested descriptors of a nested array (2nd level)""" + h = np.array(self._buffer, dtype=self._descr) + assert_(h.dtype['Info']['Info2']['value'].name == 'void256') + assert_(h.dtype['Info']['Info2']['z3'].name == 'void64') + + +class TestReadValuesNestedSingle(ReadValuesNested): + """Check the values of heterogeneous arrays (nested, single row)""" + _descr = Ndescr + multiple_rows = False + _buffer = NbufferT[0] + +class TestReadValuesNestedMultiple(ReadValuesNested): + """Check the values of heterogeneous arrays (nested, multiple rows)""" + _descr = Ndescr + multiple_rows = True + _buffer = NbufferT + +class TestEmptyField: + def test_assign(self): + a = np.arange(10, dtype=np.float32) + a.dtype = [("int", "<0i4"), ("float", "<2f4")] + assert_(a['int'].shape == (5, 0)) + assert_(a['float'].shape == (5, 2)) + +class TestCommonType: + def test_scalar_loses1(self): + res = np.find_common_type(['f4', 'f4', 'i2'], ['f8']) + assert_(res == 'f4') + + def test_scalar_loses2(self): + res = np.find_common_type(['f4', 'f4'], ['i8']) + assert_(res == 'f4') + + def test_scalar_wins(self): + res = np.find_common_type(['f4', 'f4', 'i2'], ['c8']) + assert_(res == 'c8') + + def test_scalar_wins2(self): + res = np.find_common_type(['u4', 'i4', 'i4'], ['f4']) + assert_(res == 'f8') + + def test_scalar_wins3(self): # doesn't go up to 'f16' on purpose + res = np.find_common_type(['u8', 'i8', 'i8'], ['f8']) + assert_(res == 'f8') + +class TestMultipleFields: + def setup(self): + self.ary = np.array([(1, 2, 3, 4), (5, 6, 7, 8)], dtype='i4,f4,i2,c8') + + def _bad_call(self): + return self.ary['f0', 'f1'] + + def test_no_tuple(self): + assert_raises(IndexError, self._bad_call) + + def test_return(self): + res = self.ary[['f0', 'f2']].tolist() + assert_(res == [(1, 3), (5, 7)]) + + +class TestIsSubDType: + # scalar types can be promoted into dtypes + wrappers = [np.dtype, lambda x: x] + + def test_both_abstract(self): + assert_(np.issubdtype(np.floating, np.inexact)) + assert_(not np.issubdtype(np.inexact, np.floating)) + + def test_same(self): + for cls in (np.float32, np.int32): + for w1, w2 in itertools.product(self.wrappers, repeat=2): + assert_(np.issubdtype(w1(cls), w2(cls))) + + def test_subclass(self): + # note we cannot promote floating to a dtype, as it would turn into a + # concrete type + for w in self.wrappers: + assert_(np.issubdtype(w(np.float32), np.floating)) + assert_(np.issubdtype(w(np.float64), np.floating)) + + def test_subclass_backwards(self): + for w in self.wrappers: + assert_(not np.issubdtype(np.floating, w(np.float32))) + assert_(not np.issubdtype(np.floating, w(np.float64))) + + def test_sibling_class(self): + for w1, w2 in itertools.product(self.wrappers, repeat=2): + assert_(not np.issubdtype(w1(np.float32), w2(np.float64))) + assert_(not np.issubdtype(w1(np.float64), w2(np.float32))) + + def test_nondtype_nonscalartype(self): + # See gh-14619 and gh-9505 which introduced the deprecation to fix + # this. These tests are directly taken from gh-9505 + assert not np.issubdtype(np.float32, 'float64') + assert not np.issubdtype(np.float32, 'f8') + assert not np.issubdtype(np.int32, str) + assert not np.issubdtype(np.int32, 'int64') + assert not np.issubdtype(np.str_, 'void') + # for the following the correct spellings are + # np.integer, np.floating, or np.complexfloating respectively: + assert not np.issubdtype(np.int8, int) # np.int8 is never np.int_ + assert not np.issubdtype(np.float32, float) + assert not np.issubdtype(np.complex64, complex) + assert not np.issubdtype(np.float32, "float") + assert not np.issubdtype(np.float64, "f") + + # Test the same for the correct first datatype and abstract one + # in the case of int, float, complex: + assert np.issubdtype(np.float64, 'float64') + assert np.issubdtype(np.float64, 'f8') + assert np.issubdtype(np.str_, str) + assert np.issubdtype(np.int64, 'int64') + assert np.issubdtype(np.void, 'void') + assert np.issubdtype(np.int8, np.integer) + assert np.issubdtype(np.float32, np.floating) + assert np.issubdtype(np.complex64, np.complexfloating) + assert np.issubdtype(np.float64, "float") + assert np.issubdtype(np.float32, "f") + + +class TestSctypeDict: + def test_longdouble(self): + assert_(np.sctypeDict['f8'] is not np.longdouble) + assert_(np.sctypeDict['c16'] is not np.clongdouble) + + +class TestBitName: + def test_abstract(self): + assert_raises(ValueError, np.core.numerictypes.bitname, np.floating) + + +class TestMaximumSctype: + + # note that parametrizing with sctype['int'] and similar would skip types + # with the same size (gh-11923) + + @pytest.mark.parametrize('t', [np.byte, np.short, np.intc, np.int_, np.longlong]) + def test_int(self, t): + assert_equal(np.maximum_sctype(t), np.sctypes['int'][-1]) + + @pytest.mark.parametrize('t', [np.ubyte, np.ushort, np.uintc, np.uint, np.ulonglong]) + def test_uint(self, t): + assert_equal(np.maximum_sctype(t), np.sctypes['uint'][-1]) + + @pytest.mark.parametrize('t', [np.half, np.single, np.double, np.longdouble]) + def test_float(self, t): + assert_equal(np.maximum_sctype(t), np.sctypes['float'][-1]) + + @pytest.mark.parametrize('t', [np.csingle, np.cdouble, np.clongdouble]) + def test_complex(self, t): + assert_equal(np.maximum_sctype(t), np.sctypes['complex'][-1]) + + @pytest.mark.parametrize('t', [np.bool_, np.object_, np.unicode_, np.bytes_, np.void]) + def test_other(self, t): + assert_equal(np.maximum_sctype(t), t) + + +class Test_sctype2char: + # This function is old enough that we're really just documenting the quirks + # at this point. + + def test_scalar_type(self): + assert_equal(np.sctype2char(np.double), 'd') + assert_equal(np.sctype2char(np.int_), 'l') + assert_equal(np.sctype2char(np.unicode_), 'U') + assert_equal(np.sctype2char(np.bytes_), 'S') + + def test_other_type(self): + assert_equal(np.sctype2char(float), 'd') + assert_equal(np.sctype2char(list), 'O') + assert_equal(np.sctype2char(np.ndarray), 'O') + + def test_third_party_scalar_type(self): + from numpy.core._rational_tests import rational + assert_raises(KeyError, np.sctype2char, rational) + assert_raises(KeyError, np.sctype2char, rational(1)) + + def test_array_instance(self): + assert_equal(np.sctype2char(np.array([1.0, 2.0])), 'd') + + def test_abstract_type(self): + assert_raises(KeyError, np.sctype2char, np.floating) + + def test_non_type(self): + assert_raises(ValueError, np.sctype2char, 1) + +@pytest.mark.parametrize("rep, expected", [ + (np.int32, True), + (list, False), + (1.1, False), + (str, True), + (np.dtype(np.float64), True), + (np.dtype((np.int16, (3, 4))), True), + (np.dtype([('a', np.int8)]), True), + ]) +def test_issctype(rep, expected): + # ensure proper identification of scalar + # data-types by issctype() + actual = np.issctype(rep) + assert_equal(actual, expected) + + +@pytest.mark.skipif(sys.flags.optimize > 1, + reason="no docstrings present to inspect when PYTHONOPTIMIZE/Py_OptimizeFlag > 1") +@pytest.mark.xfail(IS_PYPY, + reason="PyPy cannot modify tp_doc after PyType_Ready") +class TestDocStrings: + def test_platform_dependent_aliases(self): + if np.int64 is np.int_: + assert_('int64' in np.int_.__doc__) + elif np.int64 is np.longlong: + assert_('int64' in np.longlong.__doc__) + + +class TestScalarTypeNames: + # gh-9799 + + numeric_types = [ + np.byte, np.short, np.intc, np.int_, np.longlong, + np.ubyte, np.ushort, np.uintc, np.uint, np.ulonglong, + np.half, np.single, np.double, np.longdouble, + np.csingle, np.cdouble, np.clongdouble, + ] + + def test_names_are_unique(self): + # none of the above may be aliases for each other + assert len(set(self.numeric_types)) == len(self.numeric_types) + + # names must be unique + names = [t.__name__ for t in self.numeric_types] + assert len(set(names)) == len(names) + + @pytest.mark.parametrize('t', numeric_types) + def test_names_reflect_attributes(self, t): + """ Test that names correspond to where the type is under ``np.`` """ + assert getattr(np, t.__name__) is t + + @pytest.mark.parametrize('t', numeric_types) + def test_names_are_undersood_by_dtype(self, t): + """ Test the dtype constructor maps names back to the type """ + assert np.dtype(t.__name__).type is t diff --git a/venv/Lib/site-packages/numpy/core/tests/test_overrides.py b/venv/Lib/site-packages/numpy/core/tests/test_overrides.py new file mode 100644 index 0000000..94e39f9 --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/tests/test_overrides.py @@ -0,0 +1,583 @@ +import inspect +import sys +import os +import tempfile +from io import StringIO +from unittest import mock + +import numpy as np +from numpy.testing import ( + assert_, assert_equal, assert_raises, assert_raises_regex) +from numpy.core.overrides import ( + _get_implementing_args, array_function_dispatch, + verify_matching_signatures, ARRAY_FUNCTION_ENABLED) +from numpy.compat import pickle +import pytest + + +requires_array_function = pytest.mark.skipif( + not ARRAY_FUNCTION_ENABLED, + reason="__array_function__ dispatch not enabled.") + + +def _return_not_implemented(self, *args, **kwargs): + return NotImplemented + + +# need to define this at the top level to test pickling +@array_function_dispatch(lambda array: (array,)) +def dispatched_one_arg(array): + """Docstring.""" + return 'original' + + +@array_function_dispatch(lambda array1, array2: (array1, array2)) +def dispatched_two_arg(array1, array2): + """Docstring.""" + return 'original' + + +class TestGetImplementingArgs: + + def test_ndarray(self): + array = np.array(1) + + args = _get_implementing_args([array]) + assert_equal(list(args), [array]) + + args = _get_implementing_args([array, array]) + assert_equal(list(args), [array]) + + args = _get_implementing_args([array, 1]) + assert_equal(list(args), [array]) + + args = _get_implementing_args([1, array]) + assert_equal(list(args), [array]) + + def test_ndarray_subclasses(self): + + class OverrideSub(np.ndarray): + __array_function__ = _return_not_implemented + + class NoOverrideSub(np.ndarray): + pass + + array = np.array(1).view(np.ndarray) + override_sub = np.array(1).view(OverrideSub) + no_override_sub = np.array(1).view(NoOverrideSub) + + args = _get_implementing_args([array, override_sub]) + assert_equal(list(args), [override_sub, array]) + + args = _get_implementing_args([array, no_override_sub]) + assert_equal(list(args), [no_override_sub, array]) + + args = _get_implementing_args( + [override_sub, no_override_sub]) + assert_equal(list(args), [override_sub, no_override_sub]) + + def test_ndarray_and_duck_array(self): + + class Other: + __array_function__ = _return_not_implemented + + array = np.array(1) + other = Other() + + args = _get_implementing_args([other, array]) + assert_equal(list(args), [other, array]) + + args = _get_implementing_args([array, other]) + assert_equal(list(args), [array, other]) + + def test_ndarray_subclass_and_duck_array(self): + + class OverrideSub(np.ndarray): + __array_function__ = _return_not_implemented + + class Other: + __array_function__ = _return_not_implemented + + array = np.array(1) + subarray = np.array(1).view(OverrideSub) + other = Other() + + assert_equal(_get_implementing_args([array, subarray, other]), + [subarray, array, other]) + assert_equal(_get_implementing_args([array, other, subarray]), + [subarray, array, other]) + + def test_many_duck_arrays(self): + + class A: + __array_function__ = _return_not_implemented + + class B(A): + __array_function__ = _return_not_implemented + + class C(A): + __array_function__ = _return_not_implemented + + class D: + __array_function__ = _return_not_implemented + + a = A() + b = B() + c = C() + d = D() + + assert_equal(_get_implementing_args([1]), []) + assert_equal(_get_implementing_args([a]), [a]) + assert_equal(_get_implementing_args([a, 1]), [a]) + assert_equal(_get_implementing_args([a, a, a]), [a]) + assert_equal(_get_implementing_args([a, d, a]), [a, d]) + assert_equal(_get_implementing_args([a, b]), [b, a]) + assert_equal(_get_implementing_args([b, a]), [b, a]) + assert_equal(_get_implementing_args([a, b, c]), [b, c, a]) + assert_equal(_get_implementing_args([a, c, b]), [c, b, a]) + + def test_too_many_duck_arrays(self): + namespace = dict(__array_function__=_return_not_implemented) + types = [type('A' + str(i), (object,), namespace) for i in range(33)] + relevant_args = [t() for t in types] + + actual = _get_implementing_args(relevant_args[:32]) + assert_equal(actual, relevant_args[:32]) + + with assert_raises_regex(TypeError, 'distinct argument types'): + _get_implementing_args(relevant_args) + + +class TestNDArrayArrayFunction: + + @requires_array_function + def test_method(self): + + class Other: + __array_function__ = _return_not_implemented + + class NoOverrideSub(np.ndarray): + pass + + class OverrideSub(np.ndarray): + __array_function__ = _return_not_implemented + + array = np.array([1]) + other = Other() + no_override_sub = array.view(NoOverrideSub) + override_sub = array.view(OverrideSub) + + result = array.__array_function__(func=dispatched_two_arg, + types=(np.ndarray,), + args=(array, 1.), kwargs={}) + assert_equal(result, 'original') + + result = array.__array_function__(func=dispatched_two_arg, + types=(np.ndarray, Other), + args=(array, other), kwargs={}) + assert_(result is NotImplemented) + + result = array.__array_function__(func=dispatched_two_arg, + types=(np.ndarray, NoOverrideSub), + args=(array, no_override_sub), + kwargs={}) + assert_equal(result, 'original') + + result = array.__array_function__(func=dispatched_two_arg, + types=(np.ndarray, OverrideSub), + args=(array, override_sub), + kwargs={}) + assert_equal(result, 'original') + + with assert_raises_regex(TypeError, 'no implementation found'): + np.concatenate((array, other)) + + expected = np.concatenate((array, array)) + result = np.concatenate((array, no_override_sub)) + assert_equal(result, expected.view(NoOverrideSub)) + result = np.concatenate((array, override_sub)) + assert_equal(result, expected.view(OverrideSub)) + + def test_no_wrapper(self): + # This shouldn't happen unless a user intentionally calls + # __array_function__ with invalid arguments, but check that we raise + # an appropriate error all the same. + array = np.array(1) + func = lambda x: x + with assert_raises_regex(AttributeError, '_implementation'): + array.__array_function__(func=func, types=(np.ndarray,), + args=(array,), kwargs={}) + + +@requires_array_function +class TestArrayFunctionDispatch: + + def test_pickle(self): + for proto in range(2, pickle.HIGHEST_PROTOCOL + 1): + roundtripped = pickle.loads( + pickle.dumps(dispatched_one_arg, protocol=proto)) + assert_(roundtripped is dispatched_one_arg) + + def test_name_and_docstring(self): + assert_equal(dispatched_one_arg.__name__, 'dispatched_one_arg') + if sys.flags.optimize < 2: + assert_equal(dispatched_one_arg.__doc__, 'Docstring.') + + def test_interface(self): + + class MyArray: + def __array_function__(self, func, types, args, kwargs): + return (self, func, types, args, kwargs) + + original = MyArray() + (obj, func, types, args, kwargs) = dispatched_one_arg(original) + assert_(obj is original) + assert_(func is dispatched_one_arg) + assert_equal(set(types), {MyArray}) + # assert_equal uses the overloaded np.iscomplexobj() internally + assert_(args == (original,)) + assert_equal(kwargs, {}) + + def test_not_implemented(self): + + class MyArray: + def __array_function__(self, func, types, args, kwargs): + return NotImplemented + + array = MyArray() + with assert_raises_regex(TypeError, 'no implementation found'): + dispatched_one_arg(array) + + +@requires_array_function +class TestVerifyMatchingSignatures: + + def test_verify_matching_signatures(self): + + verify_matching_signatures(lambda x: 0, lambda x: 0) + verify_matching_signatures(lambda x=None: 0, lambda x=None: 0) + verify_matching_signatures(lambda x=1: 0, lambda x=None: 0) + + with assert_raises(RuntimeError): + verify_matching_signatures(lambda a: 0, lambda b: 0) + with assert_raises(RuntimeError): + verify_matching_signatures(lambda x: 0, lambda x=None: 0) + with assert_raises(RuntimeError): + verify_matching_signatures(lambda x=None: 0, lambda y=None: 0) + with assert_raises(RuntimeError): + verify_matching_signatures(lambda x=1: 0, lambda y=1: 0) + + def test_array_function_dispatch(self): + + with assert_raises(RuntimeError): + @array_function_dispatch(lambda x: (x,)) + def f(y): + pass + + # should not raise + @array_function_dispatch(lambda x: (x,), verify=False) + def f(y): + pass + + +def _new_duck_type_and_implements(): + """Create a duck array type and implements functions.""" + HANDLED_FUNCTIONS = {} + + class MyArray: + def __array_function__(self, func, types, args, kwargs): + if func not in HANDLED_FUNCTIONS: + return NotImplemented + if not all(issubclass(t, MyArray) for t in types): + return NotImplemented + return HANDLED_FUNCTIONS[func](*args, **kwargs) + + def implements(numpy_function): + """Register an __array_function__ implementations.""" + def decorator(func): + HANDLED_FUNCTIONS[numpy_function] = func + return func + return decorator + + return (MyArray, implements) + + +@requires_array_function +class TestArrayFunctionImplementation: + + def test_one_arg(self): + MyArray, implements = _new_duck_type_and_implements() + + @implements(dispatched_one_arg) + def _(array): + return 'myarray' + + assert_equal(dispatched_one_arg(1), 'original') + assert_equal(dispatched_one_arg(MyArray()), 'myarray') + + def test_optional_args(self): + MyArray, implements = _new_duck_type_and_implements() + + @array_function_dispatch(lambda array, option=None: (array,)) + def func_with_option(array, option='default'): + return option + + @implements(func_with_option) + def my_array_func_with_option(array, new_option='myarray'): + return new_option + + # we don't need to implement every option on __array_function__ + # implementations + assert_equal(func_with_option(1), 'default') + assert_equal(func_with_option(1, option='extra'), 'extra') + assert_equal(func_with_option(MyArray()), 'myarray') + with assert_raises(TypeError): + func_with_option(MyArray(), option='extra') + + # but new options on implementations can't be used + result = my_array_func_with_option(MyArray(), new_option='yes') + assert_equal(result, 'yes') + with assert_raises(TypeError): + func_with_option(MyArray(), new_option='no') + + def test_not_implemented(self): + MyArray, implements = _new_duck_type_and_implements() + + @array_function_dispatch(lambda array: (array,), module='my') + def func(array): + return array + + array = np.array(1) + assert_(func(array) is array) + assert_equal(func.__module__, 'my') + + with assert_raises_regex( + TypeError, "no implementation found for 'my.func'"): + func(MyArray()) + + +class TestNDArrayMethods: + + def test_repr(self): + # gh-12162: should still be defined even if __array_function__ doesn't + # implement np.array_repr() + + class MyArray(np.ndarray): + def __array_function__(*args, **kwargs): + return NotImplemented + + array = np.array(1).view(MyArray) + assert_equal(repr(array), 'MyArray(1)') + assert_equal(str(array), '1') + + +class TestNumPyFunctions: + + def test_set_module(self): + assert_equal(np.sum.__module__, 'numpy') + assert_equal(np.char.equal.__module__, 'numpy.char') + assert_equal(np.fft.fft.__module__, 'numpy.fft') + assert_equal(np.linalg.solve.__module__, 'numpy.linalg') + + def test_inspect_sum(self): + signature = inspect.signature(np.sum) + assert_('axis' in signature.parameters) + + @requires_array_function + def test_override_sum(self): + MyArray, implements = _new_duck_type_and_implements() + + @implements(np.sum) + def _(array): + return 'yes' + + assert_equal(np.sum(MyArray()), 'yes') + + @requires_array_function + def test_sum_on_mock_array(self): + + # We need a proxy for mocks because __array_function__ is only looked + # up in the class dict + class ArrayProxy: + def __init__(self, value): + self.value = value + def __array_function__(self, *args, **kwargs): + return self.value.__array_function__(*args, **kwargs) + def __array__(self, *args, **kwargs): + return self.value.__array__(*args, **kwargs) + + proxy = ArrayProxy(mock.Mock(spec=ArrayProxy)) + proxy.value.__array_function__.return_value = 1 + result = np.sum(proxy) + assert_equal(result, 1) + proxy.value.__array_function__.assert_called_once_with( + np.sum, (ArrayProxy,), (proxy,), {}) + proxy.value.__array__.assert_not_called() + + @requires_array_function + def test_sum_forwarding_implementation(self): + + class MyArray(np.ndarray): + + def sum(self, axis, out): + return 'summed' + + def __array_function__(self, func, types, args, kwargs): + return super().__array_function__(func, types, args, kwargs) + + # note: the internal implementation of np.sum() calls the .sum() method + array = np.array(1).view(MyArray) + assert_equal(np.sum(array), 'summed') + + +class TestArrayLike: + def setup(self): + class MyArray(): + def __init__(self, function=None): + self.function = function + + def __array_function__(self, func, types, args, kwargs): + try: + my_func = getattr(self, func.__name__) + except AttributeError: + return NotImplemented + return my_func(*args, **kwargs) + + self.MyArray = MyArray + + class MyNoArrayFunctionArray(): + def __init__(self, function=None): + self.function = function + + self.MyNoArrayFunctionArray = MyNoArrayFunctionArray + + def add_method(self, name, arr_class, enable_value_error=False): + def _definition(*args, **kwargs): + # Check that `like=` isn't propagated downstream + assert 'like' not in kwargs + + if enable_value_error and 'value_error' in kwargs: + raise ValueError + + return arr_class(getattr(arr_class, name)) + setattr(arr_class, name, _definition) + + def func_args(*args, **kwargs): + return args, kwargs + + @requires_array_function + def test_array_like_not_implemented(self): + self.add_method('array', self.MyArray) + + ref = self.MyArray.array() + + with assert_raises_regex(TypeError, 'no implementation found'): + array_like = np.asarray(1, like=ref) + + _array_tests = [ + ('array', *func_args((1,))), + ('asarray', *func_args((1,))), + ('asanyarray', *func_args((1,))), + ('ascontiguousarray', *func_args((2, 3))), + ('asfortranarray', *func_args((2, 3))), + ('require', *func_args((np.arange(6).reshape(2, 3),), + requirements=['A', 'F'])), + ('empty', *func_args((1,))), + ('full', *func_args((1,), 2)), + ('ones', *func_args((1,))), + ('zeros', *func_args((1,))), + ('arange', *func_args(3)), + ('frombuffer', *func_args(b'\x00' * 8, dtype=int)), + ('fromiter', *func_args(range(3), dtype=int)), + ('fromstring', *func_args('1,2', dtype=int, sep=',')), + ('loadtxt', *func_args(lambda: StringIO('0 1\n2 3'))), + ('genfromtxt', *func_args(lambda: StringIO(u'1,2.1'), + dtype=[('int', 'i8'), ('float', 'f8')], + delimiter=',')), + ] + + @pytest.mark.parametrize('function, args, kwargs', _array_tests) + @pytest.mark.parametrize('numpy_ref', [True, False]) + @requires_array_function + def test_array_like(self, function, args, kwargs, numpy_ref): + self.add_method('array', self.MyArray) + self.add_method(function, self.MyArray) + np_func = getattr(np, function) + my_func = getattr(self.MyArray, function) + + if numpy_ref is True: + ref = np.array(1) + else: + ref = self.MyArray.array() + + like_args = tuple(a() if callable(a) else a for a in args) + array_like = np_func(*like_args, **kwargs, like=ref) + + if numpy_ref is True: + assert type(array_like) is np.ndarray + + np_args = tuple(a() if callable(a) else a for a in args) + np_arr = np_func(*np_args, **kwargs) + + # Special-case np.empty to ensure values match + if function == "empty": + np_arr.fill(1) + array_like.fill(1) + + assert_equal(array_like, np_arr) + else: + assert type(array_like) is self.MyArray + assert array_like.function is my_func + + @pytest.mark.parametrize('function, args, kwargs', _array_tests) + @pytest.mark.parametrize('ref', [1, [1], "MyNoArrayFunctionArray"]) + @requires_array_function + def test_no_array_function_like(self, function, args, kwargs, ref): + self.add_method('array', self.MyNoArrayFunctionArray) + self.add_method(function, self.MyNoArrayFunctionArray) + np_func = getattr(np, function) + + # Instantiate ref if it's the MyNoArrayFunctionArray class + if ref == "MyNoArrayFunctionArray": + ref = self.MyNoArrayFunctionArray.array() + + like_args = tuple(a() if callable(a) else a for a in args) + + with assert_raises_regex(TypeError, + 'The `like` argument must be an array-like that implements'): + np_func(*like_args, **kwargs, like=ref) + + @pytest.mark.parametrize('numpy_ref', [True, False]) + def test_array_like_fromfile(self, numpy_ref): + self.add_method('array', self.MyArray) + self.add_method("fromfile", self.MyArray) + + if numpy_ref is True: + ref = np.array(1) + else: + ref = self.MyArray.array() + + data = np.random.random(5) + + with tempfile.TemporaryDirectory() as tmpdir: + fname = os.path.join(tmpdir, "testfile") + data.tofile(fname) + + array_like = np.fromfile(fname, like=ref) + if numpy_ref is True: + assert type(array_like) is np.ndarray + np_res = np.fromfile(fname, like=ref) + assert_equal(np_res, data) + assert_equal(array_like, np_res) + else: + assert type(array_like) is self.MyArray + assert array_like.function is self.MyArray.fromfile + + @requires_array_function + def test_exception_handling(self): + self.add_method('array', self.MyArray, enable_value_error=True) + + ref = self.MyArray.array() + + with assert_raises(ValueError): + np.array(1, value_error=True, like=ref) diff --git a/venv/Lib/site-packages/numpy/core/tests/test_print.py b/venv/Lib/site-packages/numpy/core/tests/test_print.py new file mode 100644 index 0000000..89a8b48 --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/tests/test_print.py @@ -0,0 +1,200 @@ +import sys + +import pytest + +import numpy as np +from numpy.testing import assert_, assert_equal +from numpy.core.tests._locales import CommaDecimalPointLocale + + +from io import StringIO + +_REF = {np.inf: 'inf', -np.inf: '-inf', np.nan: 'nan'} + + +@pytest.mark.parametrize('tp', [np.float32, np.double, np.longdouble]) +def test_float_types(tp): + """ Check formatting. + + This is only for the str function, and only for simple types. + The precision of np.float32 and np.longdouble aren't the same as the + python float precision. + + """ + for x in [0, 1, -1, 1e20]: + assert_equal(str(tp(x)), str(float(x)), + err_msg='Failed str formatting for type %s' % tp) + + if tp(1e16).itemsize > 4: + assert_equal(str(tp(1e16)), str(float('1e16')), + err_msg='Failed str formatting for type %s' % tp) + else: + ref = '1e+16' + assert_equal(str(tp(1e16)), ref, + err_msg='Failed str formatting for type %s' % tp) + + +@pytest.mark.parametrize('tp', [np.float32, np.double, np.longdouble]) +def test_nan_inf_float(tp): + """ Check formatting of nan & inf. + + This is only for the str function, and only for simple types. + The precision of np.float32 and np.longdouble aren't the same as the + python float precision. + + """ + for x in [np.inf, -np.inf, np.nan]: + assert_equal(str(tp(x)), _REF[x], + err_msg='Failed str formatting for type %s' % tp) + + +@pytest.mark.parametrize('tp', [np.complex64, np.cdouble, np.clongdouble]) +def test_complex_types(tp): + """Check formatting of complex types. + + This is only for the str function, and only for simple types. + The precision of np.float32 and np.longdouble aren't the same as the + python float precision. + + """ + for x in [0, 1, -1, 1e20]: + assert_equal(str(tp(x)), str(complex(x)), + err_msg='Failed str formatting for type %s' % tp) + assert_equal(str(tp(x*1j)), str(complex(x*1j)), + err_msg='Failed str formatting for type %s' % tp) + assert_equal(str(tp(x + x*1j)), str(complex(x + x*1j)), + err_msg='Failed str formatting for type %s' % tp) + + if tp(1e16).itemsize > 8: + assert_equal(str(tp(1e16)), str(complex(1e16)), + err_msg='Failed str formatting for type %s' % tp) + else: + ref = '(1e+16+0j)' + assert_equal(str(tp(1e16)), ref, + err_msg='Failed str formatting for type %s' % tp) + + +@pytest.mark.parametrize('dtype', [np.complex64, np.cdouble, np.clongdouble]) +def test_complex_inf_nan(dtype): + """Check inf/nan formatting of complex types.""" + TESTS = { + complex(np.inf, 0): "(inf+0j)", + complex(0, np.inf): "infj", + complex(-np.inf, 0): "(-inf+0j)", + complex(0, -np.inf): "-infj", + complex(np.inf, 1): "(inf+1j)", + complex(1, np.inf): "(1+infj)", + complex(-np.inf, 1): "(-inf+1j)", + complex(1, -np.inf): "(1-infj)", + complex(np.nan, 0): "(nan+0j)", + complex(0, np.nan): "nanj", + complex(-np.nan, 0): "(nan+0j)", + complex(0, -np.nan): "nanj", + complex(np.nan, 1): "(nan+1j)", + complex(1, np.nan): "(1+nanj)", + complex(-np.nan, 1): "(nan+1j)", + complex(1, -np.nan): "(1+nanj)", + } + for c, s in TESTS.items(): + assert_equal(str(dtype(c)), s) + + +# print tests +def _test_redirected_print(x, tp, ref=None): + file = StringIO() + file_tp = StringIO() + stdout = sys.stdout + try: + sys.stdout = file_tp + print(tp(x)) + sys.stdout = file + if ref: + print(ref) + else: + print(x) + finally: + sys.stdout = stdout + + assert_equal(file.getvalue(), file_tp.getvalue(), + err_msg='print failed for type%s' % tp) + + +@pytest.mark.parametrize('tp', [np.float32, np.double, np.longdouble]) +def test_float_type_print(tp): + """Check formatting when using print """ + for x in [0, 1, -1, 1e20]: + _test_redirected_print(float(x), tp) + + for x in [np.inf, -np.inf, np.nan]: + _test_redirected_print(float(x), tp, _REF[x]) + + if tp(1e16).itemsize > 4: + _test_redirected_print(float(1e16), tp) + else: + ref = '1e+16' + _test_redirected_print(float(1e16), tp, ref) + + +@pytest.mark.parametrize('tp', [np.complex64, np.cdouble, np.clongdouble]) +def test_complex_type_print(tp): + """Check formatting when using print """ + # We do not create complex with inf/nan directly because the feature is + # missing in python < 2.6 + for x in [0, 1, -1, 1e20]: + _test_redirected_print(complex(x), tp) + + if tp(1e16).itemsize > 8: + _test_redirected_print(complex(1e16), tp) + else: + ref = '(1e+16+0j)' + _test_redirected_print(complex(1e16), tp, ref) + + _test_redirected_print(complex(np.inf, 1), tp, '(inf+1j)') + _test_redirected_print(complex(-np.inf, 1), tp, '(-inf+1j)') + _test_redirected_print(complex(-np.nan, 1), tp, '(nan+1j)') + + +def test_scalar_format(): + """Test the str.format method with NumPy scalar types""" + tests = [('{0}', True, np.bool_), + ('{0}', False, np.bool_), + ('{0:d}', 130, np.uint8), + ('{0:d}', 50000, np.uint16), + ('{0:d}', 3000000000, np.uint32), + ('{0:d}', 15000000000000000000, np.uint64), + ('{0:d}', -120, np.int8), + ('{0:d}', -30000, np.int16), + ('{0:d}', -2000000000, np.int32), + ('{0:d}', -7000000000000000000, np.int64), + ('{0:g}', 1.5, np.float16), + ('{0:g}', 1.5, np.float32), + ('{0:g}', 1.5, np.float64), + ('{0:g}', 1.5, np.longdouble), + ('{0:g}', 1.5+0.5j, np.complex64), + ('{0:g}', 1.5+0.5j, np.complex128), + ('{0:g}', 1.5+0.5j, np.clongdouble)] + + for (fmat, val, valtype) in tests: + try: + assert_equal(fmat.format(val), fmat.format(valtype(val)), + "failed with val %s, type %s" % (val, valtype)) + except ValueError as e: + assert_(False, + "format raised exception (fmt='%s', val=%s, type=%s, exc='%s')" % + (fmat, repr(val), repr(valtype), str(e))) + + +# +# Locale tests: scalar types formatting should be independent of the locale +# + +class TestCommaDecimalPointLocale(CommaDecimalPointLocale): + + def test_locale_single(self): + assert_equal(str(np.float32(1.2)), str(float(1.2))) + + def test_locale_double(self): + assert_equal(str(np.double(1.2)), str(float(1.2))) + + def test_locale_longdouble(self): + assert_equal(str(np.longdouble('1.2')), str(float(1.2))) diff --git a/venv/Lib/site-packages/numpy/core/tests/test_protocols.py b/venv/Lib/site-packages/numpy/core/tests/test_protocols.py new file mode 100644 index 0000000..55a2bcf --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/tests/test_protocols.py @@ -0,0 +1,44 @@ +import pytest +import warnings +import numpy as np + + +@pytest.mark.filterwarnings("error") +def test_getattr_warning(): + # issue gh-14735: make sure we clear only getattr errors, and let warnings + # through + class Wrapper: + def __init__(self, array): + self.array = array + + def __len__(self): + return len(self.array) + + def __getitem__(self, item): + return type(self)(self.array[item]) + + def __getattr__(self, name): + if name.startswith("__array_"): + warnings.warn("object got converted", UserWarning, stacklevel=1) + + return getattr(self.array, name) + + def __repr__(self): + return "".format(self=self) + + array = Wrapper(np.arange(10)) + with pytest.raises(UserWarning, match="object got converted"): + np.asarray(array) + + +def test_array_called(): + class Wrapper: + val = '0' * 100 + def __array__(self, result=None): + return np.array([self.val], dtype=object) + + + wrapped = Wrapper() + arr = np.array(wrapped, dtype=str) + assert arr.dtype == 'U100' + assert arr[0] == Wrapper.val diff --git a/venv/Lib/site-packages/numpy/core/tests/test_records.py b/venv/Lib/site-packages/numpy/core/tests/test_records.py new file mode 100644 index 0000000..4d4b4b5 --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/tests/test_records.py @@ -0,0 +1,520 @@ +import collections.abc +import textwrap +from io import BytesIO +from os import path +from pathlib import Path +import pytest + +import numpy as np +from numpy.testing import ( + assert_, assert_equal, assert_array_equal, assert_array_almost_equal, + assert_raises, temppath, + ) +from numpy.compat import pickle + + +class TestFromrecords: + def test_fromrecords(self): + r = np.rec.fromrecords([[456, 'dbe', 1.2], [2, 'de', 1.3]], + names='col1,col2,col3') + assert_equal(r[0].item(), (456, 'dbe', 1.2)) + assert_equal(r['col1'].dtype.kind, 'i') + assert_equal(r['col2'].dtype.kind, 'U') + assert_equal(r['col2'].dtype.itemsize, 12) + assert_equal(r['col3'].dtype.kind, 'f') + + def test_fromrecords_0len(self): + """ Verify fromrecords works with a 0-length input """ + dtype = [('a', float), ('b', float)] + r = np.rec.fromrecords([], dtype=dtype) + assert_equal(r.shape, (0,)) + + def test_fromrecords_2d(self): + data = [ + [(1, 2), (3, 4), (5, 6)], + [(6, 5), (4, 3), (2, 1)] + ] + expected_a = [[1, 3, 5], [6, 4, 2]] + expected_b = [[2, 4, 6], [5, 3, 1]] + + # try with dtype + r1 = np.rec.fromrecords(data, dtype=[('a', int), ('b', int)]) + assert_equal(r1['a'], expected_a) + assert_equal(r1['b'], expected_b) + + # try with names + r2 = np.rec.fromrecords(data, names=['a', 'b']) + assert_equal(r2['a'], expected_a) + assert_equal(r2['b'], expected_b) + + assert_equal(r1, r2) + + def test_method_array(self): + r = np.rec.array(b'abcdefg' * 100, formats='i2,a3,i4', shape=3, byteorder='big') + assert_equal(r[1].item(), (25444, b'efg', 1633837924)) + + def test_method_array2(self): + r = np.rec.array([(1, 11, 'a'), (2, 22, 'b'), (3, 33, 'c'), (4, 44, 'd'), (5, 55, 'ex'), + (6, 66, 'f'), (7, 77, 'g')], formats='u1,f4,a1') + assert_equal(r[1].item(), (2, 22.0, b'b')) + + def test_recarray_slices(self): + r = np.rec.array([(1, 11, 'a'), (2, 22, 'b'), (3, 33, 'c'), (4, 44, 'd'), (5, 55, 'ex'), + (6, 66, 'f'), (7, 77, 'g')], formats='u1,f4,a1') + assert_equal(r[1::2][1].item(), (4, 44.0, b'd')) + + def test_recarray_fromarrays(self): + x1 = np.array([1, 2, 3, 4]) + x2 = np.array(['a', 'dd', 'xyz', '12']) + x3 = np.array([1.1, 2, 3, 4]) + r = np.rec.fromarrays([x1, x2, x3], names='a,b,c') + assert_equal(r[1].item(), (2, 'dd', 2.0)) + x1[1] = 34 + assert_equal(r.a, np.array([1, 2, 3, 4])) + + def test_recarray_fromfile(self): + data_dir = path.join(path.dirname(__file__), 'data') + filename = path.join(data_dir, 'recarray_from_file.fits') + fd = open(filename, 'rb') + fd.seek(2880 * 2) + r1 = np.rec.fromfile(fd, formats='f8,i4,a5', shape=3, byteorder='big') + fd.seek(2880 * 2) + r2 = np.rec.array(fd, formats='f8,i4,a5', shape=3, byteorder='big') + fd.seek(2880 * 2) + bytes_array = BytesIO() + bytes_array.write(fd.read()) + bytes_array.seek(0) + r3 = np.rec.fromfile(bytes_array, formats='f8,i4,a5', shape=3, byteorder='big') + fd.close() + assert_equal(r1, r2) + assert_equal(r2, r3) + + def test_recarray_from_obj(self): + count = 10 + a = np.zeros(count, dtype='O') + b = np.zeros(count, dtype='f8') + c = np.zeros(count, dtype='f8') + for i in range(len(a)): + a[i] = list(range(1, 10)) + + mine = np.rec.fromarrays([a, b, c], names='date,data1,data2') + for i in range(len(a)): + assert_((mine.date[i] == list(range(1, 10)))) + assert_((mine.data1[i] == 0.0)) + assert_((mine.data2[i] == 0.0)) + + def test_recarray_repr(self): + a = np.array([(1, 0.1), (2, 0.2)], + dtype=[('foo', ' 2) & (a < 6)) + xb = np.where((b > 2) & (b < 6)) + ya = ((a > 2) & (a < 6)) + yb = ((b > 2) & (b < 6)) + assert_array_almost_equal(xa, ya.nonzero()) + assert_array_almost_equal(xb, yb.nonzero()) + assert_(np.all(a[ya] > 0.5)) + assert_(np.all(b[yb] > 0.5)) + + def test_endian_where(self): + # GitHub issue #369 + net = np.zeros(3, dtype='>f4') + net[1] = 0.00458849 + net[2] = 0.605202 + max_net = net.max() + test = np.where(net <= 0., max_net, net) + correct = np.array([ 0.60520202, 0.00458849, 0.60520202]) + assert_array_almost_equal(test, correct) + + def test_endian_recarray(self): + # Ticket #2185 + dt = np.dtype([ + ('head', '>u4'), + ('data', '>u4', 2), + ]) + buf = np.recarray(1, dtype=dt) + buf[0]['head'] = 1 + buf[0]['data'][:] = [1, 1] + + h = buf[0]['head'] + d = buf[0]['data'][0] + buf[0]['head'] = h + buf[0]['data'][0] = d + assert_(buf[0]['head'] == 1) + + def test_mem_dot(self): + # Ticket #106 + x = np.random.randn(0, 1) + y = np.random.randn(10, 1) + # Dummy array to detect bad memory access: + _z = np.ones(10) + _dummy = np.empty((0, 10)) + z = np.lib.stride_tricks.as_strided(_z, _dummy.shape, _dummy.strides) + np.dot(x, np.transpose(y), out=z) + assert_equal(_z, np.ones(10)) + # Do the same for the built-in dot: + np.core.multiarray.dot(x, np.transpose(y), out=z) + assert_equal(_z, np.ones(10)) + + def test_arange_endian(self): + # Ticket #111 + ref = np.arange(10) + x = np.arange(10, dtype=' 1 and x['two'] > 2) + + def test_method_args(self): + # Make sure methods and functions have same default axis + # keyword and arguments + funcs1 = ['argmax', 'argmin', 'sum', ('product', 'prod'), + ('sometrue', 'any'), + ('alltrue', 'all'), 'cumsum', ('cumproduct', 'cumprod'), + 'ptp', 'cumprod', 'prod', 'std', 'var', 'mean', + 'round', 'min', 'max', 'argsort', 'sort'] + funcs2 = ['compress', 'take', 'repeat'] + + for func in funcs1: + arr = np.random.rand(8, 7) + arr2 = arr.copy() + if isinstance(func, tuple): + func_meth = func[1] + func = func[0] + else: + func_meth = func + res1 = getattr(arr, func_meth)() + res2 = getattr(np, func)(arr2) + if res1 is None: + res1 = arr + + if res1.dtype.kind in 'uib': + assert_((res1 == res2).all(), func) + else: + assert_(abs(res1-res2).max() < 1e-8, func) + + for func in funcs2: + arr1 = np.random.rand(8, 7) + arr2 = np.random.rand(8, 7) + res1 = None + if func == 'compress': + arr1 = arr1.ravel() + res1 = getattr(arr2, func)(arr1) + else: + arr2 = (15*arr2).astype(int).ravel() + if res1 is None: + res1 = getattr(arr1, func)(arr2) + res2 = getattr(np, func)(arr1, arr2) + assert_(abs(res1-res2).max() < 1e-8, func) + + def test_mem_lexsort_strings(self): + # Ticket #298 + lst = ['abc', 'cde', 'fgh'] + np.lexsort((lst,)) + + def test_fancy_index(self): + # Ticket #302 + x = np.array([1, 2])[np.array([0])] + assert_equal(x.shape, (1,)) + + def test_recarray_copy(self): + # Ticket #312 + dt = [('x', np.int16), ('y', np.float64)] + ra = np.array([(1, 2.3)], dtype=dt) + rb = np.rec.array(ra, dtype=dt) + rb['x'] = 2. + assert_(ra['x'] != rb['x']) + + def test_rec_fromarray(self): + # Ticket #322 + x1 = np.array([[1, 2], [3, 4], [5, 6]]) + x2 = np.array(['a', 'dd', 'xyz']) + x3 = np.array([1.1, 2, 3]) + np.rec.fromarrays([x1, x2, x3], formats="(2,)i4,a3,f8") + + def test_object_array_assign(self): + x = np.empty((2, 2), object) + x.flat[2] = (1, 2, 3) + assert_equal(x.flat[2], (1, 2, 3)) + + def test_ndmin_float64(self): + # Ticket #324 + x = np.array([1, 2, 3], dtype=np.float64) + assert_equal(np.array(x, dtype=np.float32, ndmin=2).ndim, 2) + assert_equal(np.array(x, dtype=np.float64, ndmin=2).ndim, 2) + + def test_ndmin_order(self): + # Issue #465 and related checks + assert_(np.array([1, 2], order='C', ndmin=3).flags.c_contiguous) + assert_(np.array([1, 2], order='F', ndmin=3).flags.f_contiguous) + assert_(np.array(np.ones((2, 2), order='F'), ndmin=3).flags.f_contiguous) + assert_(np.array(np.ones((2, 2), order='C'), ndmin=3).flags.c_contiguous) + + def test_mem_axis_minimization(self): + # Ticket #327 + data = np.arange(5) + data = np.add.outer(data, data) + + def test_mem_float_imag(self): + # Ticket #330 + np.float64(1.0).imag + + def test_dtype_tuple(self): + # Ticket #334 + assert_(np.dtype('i4') == np.dtype(('i4', ()))) + + def test_dtype_posttuple(self): + # Ticket #335 + np.dtype([('col1', '()i4')]) + + def test_numeric_carray_compare(self): + # Ticket #341 + assert_equal(np.array(['X'], 'c'), b'X') + + def test_string_array_size(self): + # Ticket #342 + assert_raises(ValueError, + np.array, [['X'], ['X', 'X', 'X']], '|S1') + + def test_dtype_repr(self): + # Ticket #344 + dt1 = np.dtype(('uint32', 2)) + dt2 = np.dtype(('uint32', (2,))) + assert_equal(dt1.__repr__(), dt2.__repr__()) + + def test_reshape_order(self): + # Make sure reshape order works. + a = np.arange(6).reshape(2, 3, order='F') + assert_equal(a, [[0, 2, 4], [1, 3, 5]]) + a = np.array([[1, 2], [3, 4], [5, 6], [7, 8]]) + b = a[:, 1] + assert_equal(b.reshape(2, 2, order='F'), [[2, 6], [4, 8]]) + + def test_reshape_zero_strides(self): + # Issue #380, test reshaping of zero strided arrays + a = np.ones(1) + a = np.lib.stride_tricks.as_strided(a, shape=(5,), strides=(0,)) + assert_(a.reshape(5, 1).strides[0] == 0) + + def test_reshape_zero_size(self): + # GitHub Issue #2700, setting shape failed for 0-sized arrays + a = np.ones((0, 2)) + a.shape = (-1, 2) + + # Cannot test if NPY_RELAXED_STRIDES_CHECKING changes the strides. + # With NPY_RELAXED_STRIDES_CHECKING the test becomes superfluous. + @pytest.mark.skipif(np.ones(1).strides[0] == np.iinfo(np.intp).max, + reason="Using relaxed stride checking") + def test_reshape_trailing_ones_strides(self): + # GitHub issue gh-2949, bad strides for trailing ones of new shape + a = np.zeros(12, dtype=np.int32)[::2] # not contiguous + strides_c = (16, 8, 8, 8) + strides_f = (8, 24, 48, 48) + assert_equal(a.reshape(3, 2, 1, 1).strides, strides_c) + assert_equal(a.reshape(3, 2, 1, 1, order='F').strides, strides_f) + assert_equal(np.array(0, dtype=np.int32).reshape(1, 1).strides, (4, 4)) + + def test_repeat_discont(self): + # Ticket #352 + a = np.arange(12).reshape(4, 3)[:, 2] + assert_equal(a.repeat(3), [2, 2, 2, 5, 5, 5, 8, 8, 8, 11, 11, 11]) + + def test_array_index(self): + # Make sure optimization is not called in this case. + a = np.array([1, 2, 3]) + a2 = np.array([[1, 2, 3]]) + assert_equal(a[np.where(a == 3)], a2[np.where(a2 == 3)]) + + def test_object_argmax(self): + a = np.array([1, 2, 3], dtype=object) + assert_(a.argmax() == 2) + + def test_recarray_fields(self): + # Ticket #372 + dt0 = np.dtype([('f0', 'i4'), ('f1', 'i4')]) + dt1 = np.dtype([('f0', 'i8'), ('f1', 'i8')]) + for a in [np.array([(1, 2), (3, 4)], "i4,i4"), + np.rec.array([(1, 2), (3, 4)], "i4,i4"), + np.rec.array([(1, 2), (3, 4)]), + np.rec.fromarrays([(1, 2), (3, 4)], "i4,i4"), + np.rec.fromarrays([(1, 2), (3, 4)])]: + assert_(a.dtype in [dt0, dt1]) + + def test_random_shuffle(self): + # Ticket #374 + a = np.arange(5).reshape((5, 1)) + b = a.copy() + np.random.shuffle(b) + assert_equal(np.sort(b, axis=0), a) + + def test_refcount_vdot(self): + # Changeset #3443 + _assert_valid_refcount(np.vdot) + + def test_startswith(self): + ca = np.char.array(['Hi', 'There']) + assert_equal(ca.startswith('H'), [True, False]) + + def test_noncommutative_reduce_accumulate(self): + # Ticket #413 + tosubtract = np.arange(5) + todivide = np.array([2.0, 0.5, 0.25]) + assert_equal(np.subtract.reduce(tosubtract), -10) + assert_equal(np.divide.reduce(todivide), 16.0) + assert_array_equal(np.subtract.accumulate(tosubtract), + np.array([0, -1, -3, -6, -10])) + assert_array_equal(np.divide.accumulate(todivide), + np.array([2., 4., 16.])) + + def test_convolve_empty(self): + # Convolve should raise an error for empty input array. + assert_raises(ValueError, np.convolve, [], [1]) + assert_raises(ValueError, np.convolve, [1], []) + + def test_multidim_byteswap(self): + # Ticket #449 + r = np.array([(1, (0, 1, 2))], dtype="i2,3i2") + assert_array_equal(r.byteswap(), + np.array([(256, (0, 256, 512))], r.dtype)) + + def test_string_NULL(self): + # Changeset 3557 + assert_equal(np.array("a\x00\x0b\x0c\x00").item(), + 'a\x00\x0b\x0c') + + def test_junk_in_string_fields_of_recarray(self): + # Ticket #483 + r = np.array([[b'abc']], dtype=[('var1', '|S20')]) + assert_(asbytes(r['var1'][0][0]) == b'abc') + + def test_take_output(self): + # Ensure that 'take' honours output parameter. + x = np.arange(12).reshape((3, 4)) + a = np.take(x, [0, 2], axis=1) + b = np.zeros_like(a) + np.take(x, [0, 2], axis=1, out=b) + assert_array_equal(a, b) + + def test_take_object_fail(self): + # Issue gh-3001 + d = 123. + a = np.array([d, 1], dtype=object) + if HAS_REFCOUNT: + ref_d = sys.getrefcount(d) + try: + a.take([0, 100]) + except IndexError: + pass + if HAS_REFCOUNT: + assert_(ref_d == sys.getrefcount(d)) + + def test_array_str_64bit(self): + # Ticket #501 + s = np.array([1, np.nan], dtype=np.float64) + with np.errstate(all='raise'): + np.array_str(s) # Should succeed + + def test_frompyfunc_endian(self): + # Ticket #503 + from math import radians + uradians = np.frompyfunc(radians, 1, 1) + big_endian = np.array([83.4, 83.5], dtype='>f8') + little_endian = np.array([83.4, 83.5], dtype=' object + # casting succeeds + def rs(): + x = np.ones([484, 286]) + y = np.zeros([484, 286]) + x |= y + + assert_raises(TypeError, rs) + + def test_unicode_scalar(self): + # Ticket #600 + x = np.array(["DROND", "DROND1"], dtype="U6") + el = x[1] + for proto in range(2, pickle.HIGHEST_PROTOCOL + 1): + new = pickle.loads(pickle.dumps(el, protocol=proto)) + assert_equal(new, el) + + def test_arange_non_native_dtype(self): + # Ticket #616 + for T in ('>f4', ' 0)] = v + + assert_raises(IndexError, ia, x, s, np.zeros(9, dtype=float)) + assert_raises(IndexError, ia, x, s, np.zeros(11, dtype=float)) + + # Old special case (different code path): + assert_raises(ValueError, ia, x.flat, s, np.zeros(9, dtype=float)) + assert_raises(ValueError, ia, x.flat, s, np.zeros(11, dtype=float)) + + def test_mem_scalar_indexing(self): + # Ticket #603 + x = np.array([0], dtype=float) + index = np.array(0, dtype=np.int32) + x[index] + + def test_binary_repr_0_width(self): + assert_equal(np.binary_repr(0, width=3), '000') + + def test_fromstring(self): + assert_equal(np.fromstring("12:09:09", dtype=int, sep=":"), + [12, 9, 9]) + + def test_searchsorted_variable_length(self): + x = np.array(['a', 'aa', 'b']) + y = np.array(['d', 'e']) + assert_equal(x.searchsorted(y), [3, 3]) + + def test_string_argsort_with_zeros(self): + # Check argsort for strings containing zeros. + x = np.frombuffer(b"\x00\x02\x00\x01", dtype="|S2") + assert_array_equal(x.argsort(kind='m'), np.array([1, 0])) + assert_array_equal(x.argsort(kind='q'), np.array([1, 0])) + + def test_string_sort_with_zeros(self): + # Check sort for strings containing zeros. + x = np.frombuffer(b"\x00\x02\x00\x01", dtype="|S2") + y = np.frombuffer(b"\x00\x01\x00\x02", dtype="|S2") + assert_array_equal(np.sort(x, kind="q"), y) + + def test_copy_detection_zero_dim(self): + # Ticket #658 + np.indices((0, 3, 4)).T.reshape(-1, 3) + + def test_flat_byteorder(self): + # Ticket #657 + x = np.arange(10) + assert_array_equal(x.astype('>i4'), x.astype('i4').flat[:], x.astype('i4')): + x = np.array([-1, 0, 1], dtype=dt) + assert_equal(x.flat[0].dtype, x[0].dtype) + + def test_copy_detection_corner_case(self): + # Ticket #658 + np.indices((0, 3, 4)).T.reshape(-1, 3) + + # Cannot test if NPY_RELAXED_STRIDES_CHECKING changes the strides. + # With NPY_RELAXED_STRIDES_CHECKING the test becomes superfluous, + # 0-sized reshape itself is tested elsewhere. + @pytest.mark.skipif(np.ones(1).strides[0] == np.iinfo(np.intp).max, + reason="Using relaxed stride checking") + def test_copy_detection_corner_case2(self): + # Ticket #771: strides are not set correctly when reshaping 0-sized + # arrays + b = np.indices((0, 3, 4)).T.reshape(-1, 3) + assert_equal(b.strides, (3 * b.itemsize, b.itemsize)) + + def test_object_array_refcounting(self): + # Ticket #633 + if not hasattr(sys, 'getrefcount'): + return + + # NB. this is probably CPython-specific + + cnt = sys.getrefcount + + a = object() + b = object() + c = object() + + cnt0_a = cnt(a) + cnt0_b = cnt(b) + cnt0_c = cnt(c) + + # -- 0d -> 1-d broadcast slice assignment + + arr = np.zeros(5, dtype=np.object_) + + arr[:] = a + assert_equal(cnt(a), cnt0_a + 5) + + arr[:] = b + assert_equal(cnt(a), cnt0_a) + assert_equal(cnt(b), cnt0_b + 5) + + arr[:2] = c + assert_equal(cnt(b), cnt0_b + 3) + assert_equal(cnt(c), cnt0_c + 2) + + del arr + + # -- 1-d -> 2-d broadcast slice assignment + + arr = np.zeros((5, 2), dtype=np.object_) + arr0 = np.zeros(2, dtype=np.object_) + + arr0[0] = a + assert_(cnt(a) == cnt0_a + 1) + arr0[1] = b + assert_(cnt(b) == cnt0_b + 1) + + arr[:, :] = arr0 + assert_(cnt(a) == cnt0_a + 6) + assert_(cnt(b) == cnt0_b + 6) + + arr[:, 0] = None + assert_(cnt(a) == cnt0_a + 1) + + del arr, arr0 + + # -- 2-d copying + flattening + + arr = np.zeros((5, 2), dtype=np.object_) + + arr[:, 0] = a + arr[:, 1] = b + assert_(cnt(a) == cnt0_a + 5) + assert_(cnt(b) == cnt0_b + 5) + + arr2 = arr.copy() + assert_(cnt(a) == cnt0_a + 10) + assert_(cnt(b) == cnt0_b + 10) + + arr2 = arr[:, 0].copy() + assert_(cnt(a) == cnt0_a + 10) + assert_(cnt(b) == cnt0_b + 5) + + arr2 = arr.flatten() + assert_(cnt(a) == cnt0_a + 10) + assert_(cnt(b) == cnt0_b + 10) + + del arr, arr2 + + # -- concatenate, repeat, take, choose + + arr1 = np.zeros((5, 1), dtype=np.object_) + arr2 = np.zeros((5, 1), dtype=np.object_) + + arr1[...] = a + arr2[...] = b + assert_(cnt(a) == cnt0_a + 5) + assert_(cnt(b) == cnt0_b + 5) + + tmp = np.concatenate((arr1, arr2)) + assert_(cnt(a) == cnt0_a + 5 + 5) + assert_(cnt(b) == cnt0_b + 5 + 5) + + tmp = arr1.repeat(3, axis=0) + assert_(cnt(a) == cnt0_a + 5 + 3*5) + + tmp = arr1.take([1, 2, 3], axis=0) + assert_(cnt(a) == cnt0_a + 5 + 3) + + x = np.array([[0], [1], [0], [1], [1]], int) + tmp = x.choose(arr1, arr2) + assert_(cnt(a) == cnt0_a + 5 + 2) + assert_(cnt(b) == cnt0_b + 5 + 3) + + del tmp # Avoid pyflakes unused variable warning + + def test_mem_custom_float_to_array(self): + # Ticket 702 + class MyFloat: + def __float__(self): + return 1.0 + + tmp = np.atleast_1d([MyFloat()]) + tmp.astype(float) # Should succeed + + def test_object_array_refcount_self_assign(self): + # Ticket #711 + class VictimObject: + deleted = False + + def __del__(self): + self.deleted = True + + d = VictimObject() + arr = np.zeros(5, dtype=np.object_) + arr[:] = d + del d + arr[:] = arr # refcount of 'd' might hit zero here + assert_(not arr[0].deleted) + arr[:] = arr # trying to induce a segfault by doing it again... + assert_(not arr[0].deleted) + + def test_mem_fromiter_invalid_dtype_string(self): + x = [1, 2, 3] + assert_raises(ValueError, + np.fromiter, [xi for xi in x], dtype='S') + + def test_reduce_big_object_array(self): + # Ticket #713 + oldsize = np.setbufsize(10*16) + a = np.array([None]*161, object) + assert_(not np.any(a)) + np.setbufsize(oldsize) + + def test_mem_0d_array_index(self): + # Ticket #714 + np.zeros(10)[np.array(0)] + + def test_nonnative_endian_fill(self): + # Non-native endian arrays were incorrectly filled with scalars + # before r5034. + if sys.byteorder == 'little': + dtype = np.dtype('>i4') + else: + dtype = np.dtype('data contains non-zero floats + x = np.array([123456789e199], dtype=np.float64) + if IS_PYPY: + x.resize((m, 0), refcheck=False) + else: + x.resize((m, 0)) + y = np.array([123456789e199], dtype=np.float64) + if IS_PYPY: + y.resize((0, n), refcheck=False) + else: + y.resize((0, n)) + + # `dot` should just return zero (m, n) matrix + z = np.dot(x, y) + assert_(np.all(z == 0)) + assert_(z.shape == (m, n)) + + def test_zeros(self): + # Regression test for #1061. + # Set a size which cannot fit into a 64 bits signed integer + sz = 2 ** 64 + with assert_raises_regex(ValueError, + 'Maximum allowed dimension exceeded'): + np.empty(sz) + + def test_huge_arange(self): + # Regression test for #1062. + # Set a size which cannot fit into a 64 bits signed integer + sz = 2 ** 64 + with assert_raises_regex(ValueError, + 'Maximum allowed size exceeded'): + np.arange(sz) + assert_(np.size == sz) + + def test_fromiter_bytes(self): + # Ticket #1058 + a = np.fromiter(list(range(10)), dtype='b') + b = np.fromiter(list(range(10)), dtype='B') + assert_(np.alltrue(a == np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]))) + assert_(np.alltrue(b == np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]))) + + def test_array_from_sequence_scalar_array(self): + # Ticket #1078: segfaults when creating an array with a sequence of + # 0d arrays. + a = np.array((np.ones(2), np.array(2)), dtype=object) + assert_equal(a.shape, (2,)) + assert_equal(a.dtype, np.dtype(object)) + assert_equal(a[0], np.ones(2)) + assert_equal(a[1], np.array(2)) + + a = np.array(((1,), np.array(1)), dtype=object) + assert_equal(a.shape, (2,)) + assert_equal(a.dtype, np.dtype(object)) + assert_equal(a[0], (1,)) + assert_equal(a[1], np.array(1)) + + def test_array_from_sequence_scalar_array2(self): + # Ticket #1081: weird array with strange input... + t = np.array([np.array([]), np.array(0, object)], dtype=object) + assert_equal(t.shape, (2,)) + assert_equal(t.dtype, np.dtype(object)) + + def test_array_too_big(self): + # Ticket #1080. + assert_raises(ValueError, np.zeros, [975]*7, np.int8) + assert_raises(ValueError, np.zeros, [26244]*5, np.int8) + + def test_dtype_keyerrors_(self): + # Ticket #1106. + dt = np.dtype([('f1', np.uint)]) + assert_raises(KeyError, dt.__getitem__, "f2") + assert_raises(IndexError, dt.__getitem__, 1) + assert_raises(TypeError, dt.__getitem__, 0.0) + + def test_lexsort_buffer_length(self): + # Ticket #1217, don't segfault. + a = np.ones(100, dtype=np.int8) + b = np.ones(100, dtype=np.int32) + i = np.lexsort((a[::-1], b)) + assert_equal(i, np.arange(100, dtype=int)) + + def test_object_array_to_fixed_string(self): + # Ticket #1235. + a = np.array(['abcdefgh', 'ijklmnop'], dtype=np.object_) + b = np.array(a, dtype=(np.str_, 8)) + assert_equal(a, b) + c = np.array(a, dtype=(np.str_, 5)) + assert_equal(c, np.array(['abcde', 'ijklm'])) + d = np.array(a, dtype=(np.str_, 12)) + assert_equal(a, d) + e = np.empty((2, ), dtype=(np.str_, 8)) + e[:] = a[:] + assert_equal(a, e) + + def test_unicode_to_string_cast(self): + # Ticket #1240. + a = np.array([[u'abc', u'\u03a3'], + [u'asdf', u'erw']], + dtype='U') + assert_raises(UnicodeEncodeError, np.array, a, 'S4') + + def test_unicode_to_string_cast_error(self): + # gh-15790 + a = np.array([u'\x80'] * 129, dtype='U3') + assert_raises(UnicodeEncodeError, np.array, a, 'S') + b = a.reshape(3, 43)[:-1, :-1] + assert_raises(UnicodeEncodeError, np.array, b, 'S') + + def test_mixed_string_unicode_array_creation(self): + a = np.array(['1234', u'123']) + assert_(a.itemsize == 16) + a = np.array([u'123', '1234']) + assert_(a.itemsize == 16) + a = np.array(['1234', u'123', '12345']) + assert_(a.itemsize == 20) + a = np.array([u'123', '1234', u'12345']) + assert_(a.itemsize == 20) + a = np.array([u'123', '1234', u'1234']) + assert_(a.itemsize == 16) + + def test_misaligned_objects_segfault(self): + # Ticket #1198 and #1267 + a1 = np.zeros((10,), dtype='O,c') + a2 = np.array(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'], 'S10') + a1['f0'] = a2 + repr(a1) + np.argmax(a1['f0']) + a1['f0'][1] = "FOO" + a1['f0'] = "FOO" + np.array(a1['f0'], dtype='S') + np.nonzero(a1['f0']) + a1.sort() + copy.deepcopy(a1) + + def test_misaligned_scalars_segfault(self): + # Ticket #1267 + s1 = np.array(('a', 'Foo'), dtype='c,O') + s2 = np.array(('b', 'Bar'), dtype='c,O') + s1['f1'] = s2['f1'] + s1['f1'] = 'Baz' + + def test_misaligned_dot_product_objects(self): + # Ticket #1267 + # This didn't require a fix, but it's worth testing anyway, because + # it may fail if .dot stops enforcing the arrays to be BEHAVED + a = np.array([[(1, 'a'), (0, 'a')], [(0, 'a'), (1, 'a')]], dtype='O,c') + b = np.array([[(4, 'a'), (1, 'a')], [(2, 'a'), (2, 'a')]], dtype='O,c') + np.dot(a['f0'], b['f0']) + + def test_byteswap_complex_scalar(self): + # Ticket #1259 and gh-441 + for dtype in [np.dtype('<'+t) for t in np.typecodes['Complex']]: + z = np.array([2.2-1.1j], dtype) + x = z[0] # always native-endian + y = x.byteswap() + if x.dtype.byteorder == z.dtype.byteorder: + # little-endian machine + assert_equal(x, np.frombuffer(y.tobytes(), dtype=dtype.newbyteorder())) + else: + # big-endian machine + assert_equal(x, np.frombuffer(y.tobytes(), dtype=dtype)) + # double check real and imaginary parts: + assert_equal(x.real, y.real.byteswap()) + assert_equal(x.imag, y.imag.byteswap()) + + def test_structured_arrays_with_objects1(self): + # Ticket #1299 + stra = 'aaaa' + strb = 'bbbb' + x = np.array([[(0, stra), (1, strb)]], 'i8,O') + x[x.nonzero()] = x.ravel()[:1] + assert_(x[0, 1] == x[0, 0]) + + @pytest.mark.skipif(not HAS_REFCOUNT, reason="Python lacks refcounts") + def test_structured_arrays_with_objects2(self): + # Ticket #1299 second test + stra = 'aaaa' + strb = 'bbbb' + numb = sys.getrefcount(strb) + numa = sys.getrefcount(stra) + x = np.array([[(0, stra), (1, strb)]], 'i8,O') + x[x.nonzero()] = x.ravel()[:1] + assert_(sys.getrefcount(strb) == numb) + assert_(sys.getrefcount(stra) == numa + 2) + + def test_duplicate_title_and_name(self): + # Ticket #1254 + dtspec = [(('a', 'a'), 'i'), ('b', 'i')] + assert_raises(ValueError, np.dtype, dtspec) + + def test_signed_integer_division_overflow(self): + # Ticket #1317. + def test_type(t): + min = np.array([np.iinfo(t).min]) + min //= -1 + + with np.errstate(divide="ignore"): + for t in (np.int8, np.int16, np.int32, np.int64, int): + test_type(t) + + def test_buffer_hashlib(self): + from hashlib import sha256 + + x = np.array([1, 2, 3], dtype=np.dtype('c') + + def test_log1p_compiler_shenanigans(self): + # Check if log1p is behaving on 32 bit intel systems. + assert_(np.isfinite(np.log1p(np.exp2(-53)))) + + def test_fromiter_comparison(self): + a = np.fromiter(list(range(10)), dtype='b') + b = np.fromiter(list(range(10)), dtype='B') + assert_(np.alltrue(a == np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]))) + assert_(np.alltrue(b == np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]))) + + def test_fromstring_crash(self): + # Ticket #1345: the following should not cause a crash + with assert_warns(DeprecationWarning): + np.fromstring(b'aa, aa, 1.0', sep=',') + + def test_ticket_1539(self): + dtypes = [x for x in np.typeDict.values() + if (issubclass(x, np.number) + and not issubclass(x, np.timedelta64))] + a = np.array([], np.bool_) # not x[0] because it is unordered + failures = [] + + for x in dtypes: + b = a.astype(x) + for y in dtypes: + c = a.astype(y) + try: + np.dot(b, c) + except TypeError: + failures.append((x, y)) + if failures: + raise AssertionError("Failures: %r" % failures) + + def test_ticket_1538(self): + x = np.finfo(np.float32) + for name in 'eps epsneg max min resolution tiny'.split(): + assert_equal(type(getattr(x, name)), np.float32, + err_msg=name) + + def test_ticket_1434(self): + # Check that the out= argument in var and std has an effect + data = np.array(((1, 2, 3), (4, 5, 6), (7, 8, 9))) + out = np.zeros((3,)) + + ret = data.var(axis=1, out=out) + assert_(ret is out) + assert_array_equal(ret, data.var(axis=1)) + + ret = data.std(axis=1, out=out) + assert_(ret is out) + assert_array_equal(ret, data.std(axis=1)) + + def test_complex_nan_maximum(self): + cnan = complex(0, np.nan) + assert_equal(np.maximum(1, cnan), cnan) + + def test_subclass_int_tuple_assignment(self): + # ticket #1563 + class Subclass(np.ndarray): + def __new__(cls, i): + return np.ones((i,)).view(cls) + + x = Subclass(5) + x[(0,)] = 2 # shouldn't raise an exception + assert_equal(x[0], 2) + + def test_ufunc_no_unnecessary_views(self): + # ticket #1548 + class Subclass(np.ndarray): + pass + x = np.array([1, 2, 3]).view(Subclass) + y = np.add(x, x, x) + assert_equal(id(x), id(y)) + + @pytest.mark.skipif(not HAS_REFCOUNT, reason="Python lacks refcounts") + def test_take_refcount(self): + # ticket #939 + a = np.arange(16, dtype=float) + a.shape = (4, 4) + lut = np.ones((5 + 3, 4), float) + rgba = np.empty(shape=a.shape + (4,), dtype=lut.dtype) + c1 = sys.getrefcount(rgba) + try: + lut.take(a, axis=0, mode='clip', out=rgba) + except TypeError: + pass + c2 = sys.getrefcount(rgba) + assert_equal(c1, c2) + + def test_fromfile_tofile_seeks(self): + # On Python 3, tofile/fromfile used to get (#1610) the Python + # file handle out of sync + f0 = tempfile.NamedTemporaryFile() + f = f0.file + f.write(np.arange(255, dtype='u1').tobytes()) + + f.seek(20) + ret = np.fromfile(f, count=4, dtype='u1') + assert_equal(ret, np.array([20, 21, 22, 23], dtype='u1')) + assert_equal(f.tell(), 24) + + f.seek(40) + np.array([1, 2, 3], dtype='u1').tofile(f) + assert_equal(f.tell(), 43) + + f.seek(40) + data = f.read(3) + assert_equal(data, b"\x01\x02\x03") + + f.seek(80) + f.read(4) + data = np.fromfile(f, dtype='u1', count=4) + assert_equal(data, np.array([84, 85, 86, 87], dtype='u1')) + + f.close() + + def test_complex_scalar_warning(self): + for tp in [np.csingle, np.cdouble, np.clongdouble]: + x = tp(1+2j) + assert_warns(np.ComplexWarning, float, x) + with suppress_warnings() as sup: + sup.filter(np.ComplexWarning) + assert_equal(float(x), float(x.real)) + + def test_complex_scalar_complex_cast(self): + for tp in [np.csingle, np.cdouble, np.clongdouble]: + x = tp(1+2j) + assert_equal(complex(x), 1+2j) + + def test_complex_boolean_cast(self): + # Ticket #2218 + for tp in [np.csingle, np.cdouble, np.clongdouble]: + x = np.array([0, 0+0.5j, 0.5+0j], dtype=tp) + assert_equal(x.astype(bool), np.array([0, 1, 1], dtype=bool)) + assert_(np.any(x)) + assert_(np.all(x[1:])) + + def test_uint_int_conversion(self): + x = 2**64 - 1 + assert_equal(int(np.uint64(x)), x) + + def test_duplicate_field_names_assign(self): + ra = np.fromiter(((i*3, i*2) for i in range(10)), dtype='i8,f8') + ra.dtype.names = ('f1', 'f2') + repr(ra) # should not cause a segmentation fault + assert_raises(ValueError, setattr, ra.dtype, 'names', ('f1', 'f1')) + + def test_eq_string_and_object_array(self): + # From e-mail thread "__eq__ with str and object" (Keith Goodman) + a1 = np.array(['a', 'b'], dtype=object) + a2 = np.array(['a', 'c']) + assert_array_equal(a1 == a2, [True, False]) + assert_array_equal(a2 == a1, [True, False]) + + def test_nonzero_byteswap(self): + a = np.array([0x80000000, 0x00000080, 0], dtype=np.uint32) + a.dtype = np.float32 + assert_equal(a.nonzero()[0], [1]) + a = a.byteswap().newbyteorder() + assert_equal(a.nonzero()[0], [1]) # [0] if nonzero() ignores swap + + def test_find_common_type_boolean(self): + # Ticket #1695 + assert_(np.find_common_type([], ['?', '?']) == '?') + + def test_empty_mul(self): + a = np.array([1.]) + a[1:1] *= 2 + assert_equal(a, [1.]) + + def test_array_side_effect(self): + # The second use of itemsize was throwing an exception because in + # ctors.c, discover_itemsize was calling PyObject_Length without + # checking the return code. This failed to get the length of the + # number 2, and the exception hung around until something checked + # PyErr_Occurred() and returned an error. + assert_equal(np.dtype('S10').itemsize, 10) + np.array([['abc', 2], ['long ', '0123456789']], dtype=np.string_) + assert_equal(np.dtype('S10').itemsize, 10) + + def test_any_float(self): + # all and any for floats + a = np.array([0.1, 0.9]) + assert_(np.any(a)) + assert_(np.all(a)) + + def test_large_float_sum(self): + a = np.arange(10000, dtype='f') + assert_equal(a.sum(dtype='d'), a.astype('d').sum()) + + def test_ufunc_casting_out(self): + a = np.array(1.0, dtype=np.float32) + b = np.array(1.0, dtype=np.float64) + c = np.array(1.0, dtype=np.float32) + np.add(a, b, out=c) + assert_equal(c, 2.0) + + def test_array_scalar_contiguous(self): + # Array scalars are both C and Fortran contiguous + assert_(np.array(1.0).flags.c_contiguous) + assert_(np.array(1.0).flags.f_contiguous) + assert_(np.array(np.float32(1.0)).flags.c_contiguous) + assert_(np.array(np.float32(1.0)).flags.f_contiguous) + + def test_squeeze_contiguous(self): + # Similar to GitHub issue #387 + a = np.zeros((1, 2)).squeeze() + b = np.zeros((2, 2, 2), order='F')[:, :, ::2].squeeze() + assert_(a.flags.c_contiguous) + assert_(a.flags.f_contiguous) + assert_(b.flags.f_contiguous) + + def test_squeeze_axis_handling(self): + # Issue #10779 + # Ensure proper handling of objects + # that don't support axis specification + # when squeezing + + class OldSqueeze(np.ndarray): + + def __new__(cls, + input_array): + obj = np.asarray(input_array).view(cls) + return obj + + # it is perfectly reasonable that prior + # to numpy version 1.7.0 a subclass of ndarray + # might have been created that did not expect + # squeeze to have an axis argument + # NOTE: this example is somewhat artificial; + # it is designed to simulate an old API + # expectation to guard against regression + def squeeze(self): + return super(OldSqueeze, self).squeeze() + + oldsqueeze = OldSqueeze(np.array([[1],[2],[3]])) + + # if no axis argument is specified the old API + # expectation should give the correct result + assert_equal(np.squeeze(oldsqueeze), + np.array([1,2,3])) + + # likewise, axis=None should work perfectly well + # with the old API expectation + assert_equal(np.squeeze(oldsqueeze, axis=None), + np.array([1,2,3])) + + # however, specification of any particular axis + # should raise a TypeError in the context of the + # old API specification, even when using a valid + # axis specification like 1 for this array + with assert_raises(TypeError): + # this would silently succeed for array + # subclasses / objects that did not support + # squeeze axis argument handling before fixing + # Issue #10779 + np.squeeze(oldsqueeze, axis=1) + + # check for the same behavior when using an invalid + # axis specification -- in this case axis=0 does not + # have size 1, but the priority should be to raise + # a TypeError for the axis argument and NOT a + # ValueError for squeezing a non-empty dimension + with assert_raises(TypeError): + np.squeeze(oldsqueeze, axis=0) + + # the new API knows how to handle the axis + # argument and will return a ValueError if + # attempting to squeeze an axis that is not + # of length 1 + with assert_raises(ValueError): + np.squeeze(np.array([[1],[2],[3]]), axis=0) + + def test_reduce_contiguous(self): + # GitHub issue #387 + a = np.add.reduce(np.zeros((2, 1, 2)), (0, 1)) + b = np.add.reduce(np.zeros((2, 1, 2)), 1) + assert_(a.flags.c_contiguous) + assert_(a.flags.f_contiguous) + assert_(b.flags.c_contiguous) + + def test_object_array_self_reference(self): + # Object arrays with references to themselves can cause problems + a = np.array(0, dtype=object) + a[()] = a + assert_raises(RecursionError, int, a) + assert_raises(RecursionError, float, a) + a[()] = None + + def test_object_array_circular_reference(self): + # Test the same for a circular reference. + a = np.array(0, dtype=object) + b = np.array(0, dtype=object) + a[()] = b + b[()] = a + assert_raises(RecursionError, int, a) + # NumPy has no tp_traverse currently, so circular references + # cannot be detected. So resolve it: + a[()] = None + + # This was causing a to become like the above + a = np.array(0, dtype=object) + a[...] += 1 + assert_equal(a, 1) + + def test_object_array_nested(self): + # but is fine with a reference to a different array + a = np.array(0, dtype=object) + b = np.array(0, dtype=object) + a[()] = b + assert_equal(int(a), int(0)) + assert_equal(float(a), float(0)) + + def test_object_array_self_copy(self): + # An object array being copied into itself DECREF'ed before INCREF'ing + # causing segmentation faults (gh-3787) + a = np.array(object(), dtype=object) + np.copyto(a, a) + if HAS_REFCOUNT: + assert_(sys.getrefcount(a[()]) == 2) + a[()].__class__ # will segfault if object was deleted + + def test_zerosize_accumulate(self): + "Ticket #1733" + x = np.array([[42, 0]], dtype=np.uint32) + assert_equal(np.add.accumulate(x[:-1, 0]), []) + + def test_objectarray_setfield(self): + # Setfield should not overwrite Object fields with non-Object data + x = np.array([1, 2, 3], dtype=object) + assert_raises(TypeError, x.setfield, 4, np.int32, 0) + + def test_setting_rank0_string(self): + "Ticket #1736" + s1 = b"hello1" + s2 = b"hello2" + a = np.zeros((), dtype="S10") + a[()] = s1 + assert_equal(a, np.array(s1)) + a[()] = np.array(s2) + assert_equal(a, np.array(s2)) + + a = np.zeros((), dtype='f4') + a[()] = 3 + assert_equal(a, np.array(3)) + a[()] = np.array(4) + assert_equal(a, np.array(4)) + + def test_string_astype(self): + "Ticket #1748" + s1 = b'black' + s2 = b'white' + s3 = b'other' + a = np.array([[s1], [s2], [s3]]) + assert_equal(a.dtype, np.dtype('S5')) + b = a.astype(np.dtype('S0')) + assert_equal(b.dtype, np.dtype('S5')) + + def test_ticket_1756(self): + # Ticket #1756 + s = b'0123456789abcdef' + a = np.array([s]*5) + for i in range(1, 17): + a1 = np.array(a, "|S%d" % i) + a2 = np.array([s[:i]]*5) + assert_equal(a1, a2) + + def test_fields_strides(self): + "gh-2355" + r = np.frombuffer(b'abcdefghijklmnop'*4*3, dtype='i4,(2,3)u2') + assert_equal(r[0:3:2]['f1'], r['f1'][0:3:2]) + assert_equal(r[0:3:2]['f1'][0], r[0:3:2][0]['f1']) + assert_equal(r[0:3:2]['f1'][0][()], r[0:3:2][0]['f1'][()]) + assert_equal(r[0:3:2]['f1'][0].strides, r[0:3:2][0]['f1'].strides) + + def test_alignment_update(self): + # Check that alignment flag is updated on stride setting + a = np.arange(10) + assert_(a.flags.aligned) + a.strides = 3 + assert_(not a.flags.aligned) + + def test_ticket_1770(self): + "Should not segfault on python 3k" + import numpy as np + try: + a = np.zeros((1,), dtype=[('f1', 'f')]) + a['f1'] = 1 + a['f2'] = 1 + except ValueError: + pass + except Exception: + raise AssertionError + + def test_ticket_1608(self): + "x.flat shouldn't modify data" + x = np.array([[1, 2], [3, 4]]).T + np.array(x.flat) + assert_equal(x, [[1, 3], [2, 4]]) + + def test_pickle_string_overwrite(self): + import re + + data = np.array([1], dtype='b') + blob = pickle.dumps(data, protocol=1) + data = pickle.loads(blob) + + # Check that loads does not clobber interned strings + s = re.sub("a(.)", "\x01\\1", "a_") + assert_equal(s[0], "\x01") + data[0] = 0xbb + s = re.sub("a(.)", "\x01\\1", "a_") + assert_equal(s[0], "\x01") + + def test_pickle_bytes_overwrite(self): + for proto in range(2, pickle.HIGHEST_PROTOCOL + 1): + data = np.array([1], dtype='b') + data = pickle.loads(pickle.dumps(data, protocol=proto)) + data[0] = 0xdd + bytestring = "\x01 ".encode('ascii') + assert_equal(bytestring[0:1], '\x01'.encode('ascii')) + + def test_pickle_py2_array_latin1_hack(self): + # Check that unpickling hacks in Py3 that support + # encoding='latin1' work correctly. + + # Python2 output for pickle.dumps(numpy.array([129], dtype='b')) + data = (b"cnumpy.core.multiarray\n_reconstruct\np0\n(cnumpy\nndarray\np1\n(I0\n" + b"tp2\nS'b'\np3\ntp4\nRp5\n(I1\n(I1\ntp6\ncnumpy\ndtype\np7\n(S'i1'\np8\n" + b"I0\nI1\ntp9\nRp10\n(I3\nS'|'\np11\nNNNI-1\nI-1\nI0\ntp12\nbI00\nS'\\x81'\n" + b"p13\ntp14\nb.") + # This should work: + result = pickle.loads(data, encoding='latin1') + assert_array_equal(result, np.array([129], dtype='b')) + # Should not segfault: + assert_raises(Exception, pickle.loads, data, encoding='koi8-r') + + def test_pickle_py2_scalar_latin1_hack(self): + # Check that scalar unpickling hack in Py3 that supports + # encoding='latin1' work correctly. + + # Python2 output for pickle.dumps(...) + datas = [ + # (original, python2_pickle, koi8r_validity) + (np.unicode_('\u6bd2'), + (b"cnumpy.core.multiarray\nscalar\np0\n(cnumpy\ndtype\np1\n" + b"(S'U1'\np2\nI0\nI1\ntp3\nRp4\n(I3\nS'<'\np5\nNNNI4\nI4\nI0\n" + b"tp6\nbS'\\xd2k\\x00\\x00'\np7\ntp8\nRp9\n."), + 'invalid'), + + (np.float64(9e123), + (b"cnumpy.core.multiarray\nscalar\np0\n(cnumpy\ndtype\np1\n(S'f8'\n" + b"p2\nI0\nI1\ntp3\nRp4\n(I3\nS'<'\np5\nNNNI-1\nI-1\nI0\ntp6\n" + b"bS'O\\x81\\xb7Z\\xaa:\\xabY'\np7\ntp8\nRp9\n."), + 'invalid'), + + (np.bytes_(b'\x9c'), # different 8-bit code point in KOI8-R vs latin1 + (b"cnumpy.core.multiarray\nscalar\np0\n(cnumpy\ndtype\np1\n(S'S1'\np2\n" + b"I0\nI1\ntp3\nRp4\n(I3\nS'|'\np5\nNNNI1\nI1\nI0\ntp6\nbS'\\x9c'\np7\n" + b"tp8\nRp9\n."), + 'different'), + ] + for original, data, koi8r_validity in datas: + result = pickle.loads(data, encoding='latin1') + assert_equal(result, original) + + # Decoding under non-latin1 encoding (e.g.) KOI8-R can + # produce bad results, but should not segfault. + if koi8r_validity == 'different': + # Unicode code points happen to lie within latin1, + # but are different in koi8-r, resulting to silent + # bogus results + result = pickle.loads(data, encoding='koi8-r') + assert_(result != original) + elif koi8r_validity == 'invalid': + # Unicode code points outside latin1, so results + # to an encoding exception + assert_raises(ValueError, pickle.loads, data, encoding='koi8-r') + else: + raise ValueError(koi8r_validity) + + def test_structured_type_to_object(self): + a_rec = np.array([(0, 1), (3, 2)], dtype='i4,i8') + a_obj = np.empty((2,), dtype=object) + a_obj[0] = (0, 1) + a_obj[1] = (3, 2) + # astype records -> object + assert_equal(a_rec.astype(object), a_obj) + # '=' records -> object + b = np.empty_like(a_obj) + b[...] = a_rec + assert_equal(b, a_obj) + # '=' object -> records + b = np.empty_like(a_rec) + b[...] = a_obj + assert_equal(b, a_rec) + + def test_assign_obj_listoflists(self): + # Ticket # 1870 + # The inner list should get assigned to the object elements + a = np.zeros(4, dtype=object) + b = a.copy() + a[0] = [1] + a[1] = [2] + a[2] = [3] + a[3] = [4] + b[...] = [[1], [2], [3], [4]] + assert_equal(a, b) + # The first dimension should get broadcast + a = np.zeros((2, 2), dtype=object) + a[...] = [[1, 2]] + assert_equal(a, [[1, 2], [1, 2]]) + + @pytest.mark.slow_pypy + def test_memoryleak(self): + # Ticket #1917 - ensure that array data doesn't leak + for i in range(1000): + # 100MB times 1000 would give 100GB of memory usage if it leaks + a = np.empty((100000000,), dtype='i1') + del a + + @pytest.mark.skipif(not HAS_REFCOUNT, reason="Python lacks refcounts") + def test_ufunc_reduce_memoryleak(self): + a = np.arange(6) + acnt = sys.getrefcount(a) + np.add.reduce(a) + assert_equal(sys.getrefcount(a), acnt) + + def test_search_sorted_invalid_arguments(self): + # Ticket #2021, should not segfault. + x = np.arange(0, 4, dtype='datetime64[D]') + assert_raises(TypeError, x.searchsorted, 1) + + def test_string_truncation(self): + # Ticket #1990 - Data can be truncated in creation of an array from a + # mixed sequence of numeric values and strings + for val in [True, 1234, 123.4, complex(1, 234)]: + for tostr in [asunicode, asbytes]: + b = np.array([val, tostr('xx')]) + assert_equal(tostr(b[0]), tostr(val)) + b = np.array([tostr('xx'), val]) + assert_equal(tostr(b[1]), tostr(val)) + + # test also with longer strings + b = np.array([val, tostr('xxxxxxxxxx')]) + assert_equal(tostr(b[0]), tostr(val)) + b = np.array([tostr('xxxxxxxxxx'), val]) + assert_equal(tostr(b[1]), tostr(val)) + + def test_string_truncation_ucs2(self): + # Ticket #2081. Python compiled with two byte unicode + # can lead to truncation if itemsize is not properly + # adjusted for NumPy's four byte unicode. + a = np.array(['abcd']) + assert_equal(a.dtype.itemsize, 16) + + def test_unique_stable(self): + # Ticket #2063 must always choose stable sort for argsort to + # get consistent results + v = np.array(([0]*5 + [1]*6 + [2]*6)*4) + res = np.unique(v, return_index=True) + tgt = (np.array([0, 1, 2]), np.array([ 0, 5, 11])) + assert_equal(res, tgt) + + def test_unicode_alloc_dealloc_match(self): + # Ticket #1578, the mismatch only showed up when running + # python-debug for python versions >= 2.7, and then as + # a core dump and error message. + a = np.array(['abc'], dtype=np.unicode_)[0] + del a + + def test_refcount_error_in_clip(self): + # Ticket #1588 + a = np.zeros((2,), dtype='>i2').clip(min=0) + x = a + a + # This used to segfault: + y = str(x) + # Check the final string: + assert_(y == "[0 0]") + + def test_searchsorted_wrong_dtype(self): + # Ticket #2189, it used to segfault, so we check that it raises the + # proper exception. + a = np.array([('a', 1)], dtype='S1, int') + assert_raises(TypeError, np.searchsorted, a, 1.2) + # Ticket #2066, similar problem: + dtype = np.format_parser(['i4', 'i4'], [], []) + a = np.recarray((2, ), dtype) + assert_raises(TypeError, np.searchsorted, a, 1) + + def test_complex64_alignment(self): + # Issue gh-2668 (trac 2076), segfault on sparc due to misalignment + dtt = np.complex64 + arr = np.arange(10, dtype=dtt) + # 2D array + arr2 = np.reshape(arr, (2, 5)) + # Fortran write followed by (C or F) read caused bus error + data_str = arr2.tobytes('F') + data_back = np.ndarray(arr2.shape, + arr2.dtype, + buffer=data_str, + order='F') + assert_array_equal(arr2, data_back) + + def test_structured_count_nonzero(self): + arr = np.array([0, 1]).astype('i4, (2)i4')[:1] + count = np.count_nonzero(arr) + assert_equal(count, 0) + + def test_copymodule_preserves_f_contiguity(self): + a = np.empty((2, 2), order='F') + b = copy.copy(a) + c = copy.deepcopy(a) + assert_(b.flags.fortran) + assert_(b.flags.f_contiguous) + assert_(c.flags.fortran) + assert_(c.flags.f_contiguous) + + def test_fortran_order_buffer(self): + import numpy as np + a = np.array([['Hello', 'Foob']], dtype='U5', order='F') + arr = np.ndarray(shape=[1, 2, 5], dtype='U1', buffer=a) + arr2 = np.array([[[u'H', u'e', u'l', u'l', u'o'], + [u'F', u'o', u'o', u'b', u'']]]) + assert_array_equal(arr, arr2) + + def test_assign_from_sequence_error(self): + # Ticket #4024. + arr = np.array([1, 2, 3]) + assert_raises(ValueError, arr.__setitem__, slice(None), [9, 9]) + arr.__setitem__(slice(None), [9]) + assert_equal(arr, [9, 9, 9]) + + def test_format_on_flex_array_element(self): + # Ticket #4369. + dt = np.dtype([('date', ' 0: + # unpickling ndarray goes through _frombuffer for protocol 5 + assert b'numpy.core.numeric' in s + else: + assert b'numpy.core.multiarray' in s + + def test_object_casting_errors(self): + # gh-11993 update to ValueError (see gh-16909), since strings can in + # principle be converted to complex, but this string cannot. + arr = np.array(['AAAAA', 18465886.0, 18465886.0], dtype=object) + assert_raises(ValueError, arr.astype, 'c8') + + def test_eff1d_casting(self): + # gh-12711 + x = np.array([1, 2, 4, 7, 0], dtype=np.int16) + res = np.ediff1d(x, to_begin=-99, to_end=np.array([88, 99])) + assert_equal(res, [-99, 1, 2, 3, -7, 88, 99]) + + # The use of safe casting means, that 1<<20 is cast unsafely, an + # error may be better, but currently there is no mechanism for it. + res = np.ediff1d(x, to_begin=(1<<20), to_end=(1<<20)) + assert_equal(res, [0, 1, 2, 3, -7, 0]) + + def test_pickle_datetime64_array(self): + # gh-12745 (would fail with pickle5 installed) + d = np.datetime64('2015-07-04 12:59:59.50', 'ns') + arr = np.array([d]) + for proto in range(2, pickle.HIGHEST_PROTOCOL + 1): + dumped = pickle.dumps(arr, protocol=proto) + assert_equal(pickle.loads(dumped), arr) + + def test_bad_array_interface(self): + class T: + __array_interface__ = {} + + with assert_raises(ValueError): + np.array([T()]) + + def test_2d__array__shape(self): + class T(object): + def __array__(self): + return np.ndarray(shape=(0,0)) + + # Make sure __array__ is used instead of Sequence methods. + def __iter__(self): + return iter([]) + + def __getitem__(self, idx): + raise AssertionError("__getitem__ was called") + + def __len__(self): + return 0 + + + t = T() + # gh-13659, would raise in broadcasting [x=t for x in result] + arr = np.array([t]) + assert arr.shape == (1, 0, 0) + + @pytest.mark.skipif(sys.maxsize < 2 ** 31 + 1, reason='overflows 32-bit python') + @pytest.mark.skipif(sys.platform == 'win32' and sys.version_info[:2] < (3, 8), + reason='overflows on windows, fixed in bpo-16865') + def test_to_ctypes(self): + #gh-14214 + arr = np.zeros((2 ** 31 + 1,), 'b') + assert arr.size * arr.itemsize > 2 ** 31 + c_arr = np.ctypeslib.as_ctypes(arr) + assert_equal(c_arr._length_, arr.size) + + def test_complex_conversion_error(self): + # gh-17068 + with pytest.raises(TypeError, match=r"Unable to convert dtype.*"): + complex(np.array("now", np.datetime64)) + + def test__array_interface__descr(self): + # gh-17068 + dt = np.dtype(dict(names=['a', 'b'], + offsets=[0, 0], + formats=[np.int64, np.int64])) + descr = np.array((1, 1), dtype=dt).__array_interface__['descr'] + assert descr == [('', '|V8')] # instead of [(b'', '|V8')] + + @pytest.mark.skipif(sys.maxsize < 2 ** 31 + 1, reason='overflows 32-bit python') + @requires_memory(free_bytes=9e9) + def test_dot_big_stride(self): + # gh-17111 + # blas stride = stride//itemsize > int32 max + int32_max = np.iinfo(np.int32).max + n = int32_max + 3 + a = np.empty([n], dtype=np.float32) + b = a[::n-1] + b[...] = 1 + assert b.strides[0] > int32_max * b.dtype.itemsize + assert np.dot(b, b) == 2.0 + + def test_frompyfunc_name(self): + # name conversion was failing for python 3 strings + # resulting in the default '?' name. Also test utf-8 + # encoding using non-ascii name. + def cassé(x): + return x + + f = np.frompyfunc(cassé, 1, 1) + assert str(f) == "" diff --git a/venv/Lib/site-packages/numpy/core/tests/test_scalar_ctors.py b/venv/Lib/site-packages/numpy/core/tests/test_scalar_ctors.py new file mode 100644 index 0000000..7e93353 --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/tests/test_scalar_ctors.py @@ -0,0 +1,115 @@ +""" +Test the scalar constructors, which also do type-coercion +""" +import pytest + +import numpy as np +from numpy.testing import ( + assert_equal, assert_almost_equal, assert_warns, + ) + +class TestFromString: + def test_floating(self): + # Ticket #640, floats from string + fsingle = np.single('1.234') + fdouble = np.double('1.234') + flongdouble = np.longdouble('1.234') + assert_almost_equal(fsingle, 1.234) + assert_almost_equal(fdouble, 1.234) + assert_almost_equal(flongdouble, 1.234) + + def test_floating_overflow(self): + """ Strings containing an unrepresentable float overflow """ + fhalf = np.half('1e10000') + assert_equal(fhalf, np.inf) + fsingle = np.single('1e10000') + assert_equal(fsingle, np.inf) + fdouble = np.double('1e10000') + assert_equal(fdouble, np.inf) + flongdouble = assert_warns(RuntimeWarning, np.longdouble, '1e10000') + assert_equal(flongdouble, np.inf) + + fhalf = np.half('-1e10000') + assert_equal(fhalf, -np.inf) + fsingle = np.single('-1e10000') + assert_equal(fsingle, -np.inf) + fdouble = np.double('-1e10000') + assert_equal(fdouble, -np.inf) + flongdouble = assert_warns(RuntimeWarning, np.longdouble, '-1e10000') + assert_equal(flongdouble, -np.inf) + + +class TestExtraArgs: + def test_superclass(self): + # try both positional and keyword arguments + s = np.str_(b'\\x61', encoding='unicode-escape') + assert s == 'a' + s = np.str_(b'\\x61', 'unicode-escape') + assert s == 'a' + + # previously this would return '\\xx' + with pytest.raises(UnicodeDecodeError): + np.str_(b'\\xx', encoding='unicode-escape') + with pytest.raises(UnicodeDecodeError): + np.str_(b'\\xx', 'unicode-escape') + + # superclass fails, but numpy succeeds + assert np.bytes_(-2) == b'-2' + + def test_datetime(self): + dt = np.datetime64('2000-01', ('M', 2)) + assert np.datetime_data(dt) == ('M', 2) + + with pytest.raises(TypeError): + np.datetime64('2000', garbage=True) + + def test_bool(self): + with pytest.raises(TypeError): + np.bool_(False, garbage=True) + + def test_void(self): + with pytest.raises(TypeError): + np.void(b'test', garbage=True) + + +class TestFromInt: + def test_intp(self): + # Ticket #99 + assert_equal(1024, np.intp(1024)) + + def test_uint64_from_negative(self): + assert_equal(np.uint64(-2), np.uint64(18446744073709551614)) + + +int_types = [np.byte, np.short, np.intc, np.int_, np.longlong] +uint_types = [np.ubyte, np.ushort, np.uintc, np.uint, np.ulonglong] +float_types = [np.half, np.single, np.double, np.longdouble] +cfloat_types = [np.csingle, np.cdouble, np.clongdouble] + + +class TestArrayFromScalar: + """ gh-15467 """ + + def _do_test(self, t1, t2): + x = t1(2) + arr = np.array(x, dtype=t2) + # type should be preserved exactly + if t2 is None: + assert arr.dtype.type is t1 + else: + assert arr.dtype.type is t2 + + @pytest.mark.parametrize('t1', int_types + uint_types) + @pytest.mark.parametrize('t2', int_types + uint_types + [None]) + def test_integers(self, t1, t2): + return self._do_test(t1, t2) + + @pytest.mark.parametrize('t1', float_types) + @pytest.mark.parametrize('t2', float_types + [None]) + def test_reals(self, t1, t2): + return self._do_test(t1, t2) + + @pytest.mark.parametrize('t1', cfloat_types) + @pytest.mark.parametrize('t2', cfloat_types + [None]) + def test_complex(self, t1, t2): + return self._do_test(t1, t2) diff --git a/venv/Lib/site-packages/numpy/core/tests/test_scalar_methods.py b/venv/Lib/site-packages/numpy/core/tests/test_scalar_methods.py new file mode 100644 index 0000000..4f5fd29 --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/tests/test_scalar_methods.py @@ -0,0 +1,103 @@ +""" +Test the scalar constructors, which also do type-coercion +""" +import fractions +import platform + +import pytest +import numpy as np + +from numpy.testing import assert_equal, assert_raises + + +class TestAsIntegerRatio: + # derived in part from the cpython test "test_floatasratio" + + @pytest.mark.parametrize("ftype", [ + np.half, np.single, np.double, np.longdouble]) + @pytest.mark.parametrize("f, ratio", [ + (0.875, (7, 8)), + (-0.875, (-7, 8)), + (0.0, (0, 1)), + (11.5, (23, 2)), + ]) + def test_small(self, ftype, f, ratio): + assert_equal(ftype(f).as_integer_ratio(), ratio) + + @pytest.mark.parametrize("ftype", [ + np.half, np.single, np.double, np.longdouble]) + def test_simple_fractions(self, ftype): + R = fractions.Fraction + assert_equal(R(0, 1), + R(*ftype(0.0).as_integer_ratio())) + assert_equal(R(5, 2), + R(*ftype(2.5).as_integer_ratio())) + assert_equal(R(1, 2), + R(*ftype(0.5).as_integer_ratio())) + assert_equal(R(-2100, 1), + R(*ftype(-2100.0).as_integer_ratio())) + + @pytest.mark.parametrize("ftype", [ + np.half, np.single, np.double, np.longdouble]) + def test_errors(self, ftype): + assert_raises(OverflowError, ftype('inf').as_integer_ratio) + assert_raises(OverflowError, ftype('-inf').as_integer_ratio) + assert_raises(ValueError, ftype('nan').as_integer_ratio) + + def test_against_known_values(self): + R = fractions.Fraction + assert_equal(R(1075, 512), + R(*np.half(2.1).as_integer_ratio())) + assert_equal(R(-1075, 512), + R(*np.half(-2.1).as_integer_ratio())) + assert_equal(R(4404019, 2097152), + R(*np.single(2.1).as_integer_ratio())) + assert_equal(R(-4404019, 2097152), + R(*np.single(-2.1).as_integer_ratio())) + assert_equal(R(4728779608739021, 2251799813685248), + R(*np.double(2.1).as_integer_ratio())) + assert_equal(R(-4728779608739021, 2251799813685248), + R(*np.double(-2.1).as_integer_ratio())) + # longdouble is platform dependent + + @pytest.mark.parametrize("ftype, frac_vals, exp_vals", [ + # dtype test cases generated using hypothesis + # first five generated cases per dtype + (np.half, [0.0, 0.01154830649280303, 0.31082276347447274, + 0.527350517124794, 0.8308562335072596], + [0, 1, 0, -8, 12]), + (np.single, [0.0, 0.09248576989263226, 0.8160498218131407, + 0.17389442853722373, 0.7956044195067877], + [0, 12, 10, 17, -26]), + (np.double, [0.0, 0.031066908499895136, 0.5214135908877832, + 0.45780736035689296, 0.5906586745934036], + [0, -801, 51, 194, -653]), + pytest.param( + np.longdouble, + [0.0, 0.20492557202724854, 0.4277180662199366, 0.9888085019891495, + 0.9620175814461964], + [0, -7400, 14266, -7822, -8721], + marks=[ + pytest.mark.skipif( + np.finfo(np.double) == np.finfo(np.longdouble), + reason="long double is same as double"), + pytest.mark.skipif( + platform.machine().startswith("ppc"), + reason="IBM double double"), + ] + ) + ]) + def test_roundtrip(self, ftype, frac_vals, exp_vals): + for frac, exp in zip(frac_vals, exp_vals): + f = np.ldexp(frac, exp, dtype=ftype) + n, d = f.as_integer_ratio() + + try: + # workaround for gh-9968 + nf = np.longdouble(str(n)) + df = np.longdouble(str(d)) + except (OverflowError, RuntimeWarning): + # the values may not fit in any float type + pytest.skip("longdouble too small on this platform") + + assert_equal(nf / df, f, "{}/{}".format(n, d)) diff --git a/venv/Lib/site-packages/numpy/core/tests/test_scalarbuffer.py b/venv/Lib/site-packages/numpy/core/tests/test_scalarbuffer.py new file mode 100644 index 0000000..851cd30 --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/tests/test_scalarbuffer.py @@ -0,0 +1,154 @@ +""" +Test scalar buffer interface adheres to PEP 3118 +""" +import numpy as np +from numpy.core._rational_tests import rational +from numpy.core._multiarray_tests import get_buffer_info +import pytest + +from numpy.testing import assert_, assert_equal, assert_raises + +# PEP3118 format strings for native (standard alignment and byteorder) types +scalars_and_codes = [ + (np.bool_, '?'), + (np.byte, 'b'), + (np.short, 'h'), + (np.intc, 'i'), + (np.int_, 'l'), + (np.longlong, 'q'), + (np.ubyte, 'B'), + (np.ushort, 'H'), + (np.uintc, 'I'), + (np.uint, 'L'), + (np.ulonglong, 'Q'), + (np.half, 'e'), + (np.single, 'f'), + (np.double, 'd'), + (np.longdouble, 'g'), + (np.csingle, 'Zf'), + (np.cdouble, 'Zd'), + (np.clongdouble, 'Zg'), +] +scalars_only, codes_only = zip(*scalars_and_codes) + + +class TestScalarPEP3118: + + @pytest.mark.parametrize('scalar', scalars_only, ids=codes_only) + def test_scalar_match_array(self, scalar): + x = scalar() + a = np.array([], dtype=np.dtype(scalar)) + mv_x = memoryview(x) + mv_a = memoryview(a) + assert_equal(mv_x.format, mv_a.format) + + @pytest.mark.parametrize('scalar', scalars_only, ids=codes_only) + def test_scalar_dim(self, scalar): + x = scalar() + mv_x = memoryview(x) + assert_equal(mv_x.itemsize, np.dtype(scalar).itemsize) + assert_equal(mv_x.ndim, 0) + assert_equal(mv_x.shape, ()) + assert_equal(mv_x.strides, ()) + assert_equal(mv_x.suboffsets, ()) + + @pytest.mark.parametrize('scalar, code', scalars_and_codes, ids=codes_only) + def test_scalar_code_and_properties(self, scalar, code): + x = scalar() + expected = dict(strides=(), itemsize=x.dtype.itemsize, ndim=0, + shape=(), format=code, readonly=True) + + mv_x = memoryview(x) + print(mv_x.readonly, self._as_dict(mv_x)) + assert self._as_dict(mv_x) == expected + + @pytest.mark.parametrize('scalar', scalars_only, ids=codes_only) + def test_scalar_buffers_readonly(self, scalar): + x = scalar() + with pytest.raises(BufferError, match="scalar buffer is readonly"): + get_buffer_info(x, ["WRITABLE"]) + + def test_void_scalar_structured_data(self): + dt = np.dtype([('name', np.unicode_, 16), ('grades', np.float64, (2,))]) + x = np.array(('ndarray_scalar', (1.2, 3.0)), dtype=dt)[()] + assert_(isinstance(x, np.void)) + mv_x = memoryview(x) + expected_size = 16 * np.dtype((np.unicode_, 1)).itemsize + expected_size += 2 * np.dtype(np.float64).itemsize + assert_equal(mv_x.itemsize, expected_size) + assert_equal(mv_x.ndim, 0) + assert_equal(mv_x.shape, ()) + assert_equal(mv_x.strides, ()) + assert_equal(mv_x.suboffsets, ()) + + # check scalar format string against ndarray format string + a = np.array([('Sarah', (8.0, 7.0)), ('John', (6.0, 7.0))], dtype=dt) + assert_(isinstance(a, np.ndarray)) + mv_a = memoryview(a) + assert_equal(mv_x.itemsize, mv_a.itemsize) + assert_equal(mv_x.format, mv_a.format) + + # Check that we do not allow writeable buffer export (technically + # we could allow it sometimes here...) + with pytest.raises(BufferError, match="scalar buffer is readonly"): + get_buffer_info(x, ["WRITABLE"]) + + def _as_dict(self, m): + return dict(strides=m.strides, shape=m.shape, itemsize=m.itemsize, + ndim=m.ndim, format=m.format, readonly=m.readonly) + + def test_datetime_memoryview(self): + # gh-11656 + # Values verified with v1.13.3, shape is not () as in test_scalar_dim + + dt1 = np.datetime64('2016-01-01') + dt2 = np.datetime64('2017-01-01') + expected = dict(strides=(1,), itemsize=1, ndim=1, shape=(8,), + format='B', readonly=True) + v = memoryview(dt1) + assert self._as_dict(v) == expected + + v = memoryview(dt2 - dt1) + assert self._as_dict(v) == expected + + dt = np.dtype([('a', 'uint16'), ('b', 'M8[s]')]) + a = np.empty(1, dt) + # Fails to create a PEP 3118 valid buffer + assert_raises((ValueError, BufferError), memoryview, a[0]) + + # Check that we do not allow writeable buffer export + with pytest.raises(BufferError, match="scalar buffer is readonly"): + get_buffer_info(dt1, ["WRITABLE"]) + + @pytest.mark.parametrize('s', [ + pytest.param("\x32\x32", id="ascii"), + pytest.param("\uFE0F\uFE0F", id="basic multilingual"), + pytest.param("\U0001f4bb\U0001f4bb", id="non-BMP"), + ]) + def test_str_ucs4(self, s): + s = np.str_(s) # only our subclass implements the buffer protocol + + # all the same, characters always encode as ucs4 + expected = dict(strides=(), itemsize=8, ndim=0, shape=(), format='2w', + readonly=True) + + v = memoryview(s) + assert self._as_dict(v) == expected + + # integers of the paltform-appropriate endianness + code_points = np.frombuffer(v, dtype='i4') + + assert_equal(code_points, [ord(c) for c in s]) + + # Check that we do not allow writeable buffer export + with pytest.raises(BufferError, match="scalar buffer is readonly"): + get_buffer_info(s, ["WRITABLE"]) + + def test_user_scalar_fails_buffer(self): + r = rational(1) + with assert_raises(TypeError): + memoryview(r) + + # Check that we do not allow writeable buffer export + with pytest.raises(BufferError, match="scalar buffer is readonly"): + get_buffer_info(r, ["WRITABLE"]) \ No newline at end of file diff --git a/venv/Lib/site-packages/numpy/core/tests/test_scalarinherit.py b/venv/Lib/site-packages/numpy/core/tests/test_scalarinherit.py new file mode 100644 index 0000000..cc53eb2 --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/tests/test_scalarinherit.py @@ -0,0 +1,99 @@ +# -*- coding: utf-8 -*- +""" Test printing of scalar types. + +""" +import pytest + +import numpy as np +from numpy.testing import assert_, assert_raises + + +class A: + pass +class B(A, np.float64): + pass + +class C(B): + pass +class D(C, B): + pass + +class B0(np.float64, A): + pass +class C0(B0): + pass + +class HasNew: + def __new__(cls, *args, **kwargs): + return cls, args, kwargs + +class B1(np.float64, HasNew): + pass + + +class TestInherit: + def test_init(self): + x = B(1.0) + assert_(str(x) == '1.0') + y = C(2.0) + assert_(str(y) == '2.0') + z = D(3.0) + assert_(str(z) == '3.0') + + def test_init2(self): + x = B0(1.0) + assert_(str(x) == '1.0') + y = C0(2.0) + assert_(str(y) == '2.0') + + def test_gh_15395(self): + # HasNew is the second base, so `np.float64` should have priority + x = B1(1.0) + assert_(str(x) == '1.0') + + # previously caused RecursionError!? + with pytest.raises(TypeError): + B1(1.0, 2.0) + + +class TestCharacter: + def test_char_radd(self): + # GH issue 9620, reached gentype_add and raise TypeError + np_s = np.string_('abc') + np_u = np.unicode_('abc') + s = b'def' + u = u'def' + assert_(np_s.__radd__(np_s) is NotImplemented) + assert_(np_s.__radd__(np_u) is NotImplemented) + assert_(np_s.__radd__(s) is NotImplemented) + assert_(np_s.__radd__(u) is NotImplemented) + assert_(np_u.__radd__(np_s) is NotImplemented) + assert_(np_u.__radd__(np_u) is NotImplemented) + assert_(np_u.__radd__(s) is NotImplemented) + assert_(np_u.__radd__(u) is NotImplemented) + assert_(s + np_s == b'defabc') + assert_(u + np_u == u'defabc') + + class MyStr(str, np.generic): + # would segfault + pass + + with assert_raises(TypeError): + # Previously worked, but gave completely wrong result + ret = s + MyStr('abc') + + class MyBytes(bytes, np.generic): + # would segfault + pass + + ret = s + MyBytes(b'abc') + assert(type(ret) is type(s)) + assert ret == b"defabc" + + def test_char_repeat(self): + np_s = np.string_('abc') + np_u = np.unicode_('abc') + res_s = b'abc' * 5 + res_u = u'abc' * 5 + assert_(np_s * 5 == res_s) + assert_(np_u * 5 == res_u) diff --git a/venv/Lib/site-packages/numpy/core/tests/test_scalarmath.py b/venv/Lib/site-packages/numpy/core/tests/test_scalarmath.py new file mode 100644 index 0000000..d852941 --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/tests/test_scalarmath.py @@ -0,0 +1,709 @@ +import sys +import warnings +import itertools +import operator +import platform +import pytest + +import numpy as np +from numpy.testing import ( + assert_, assert_equal, assert_raises, assert_almost_equal, + assert_array_equal, IS_PYPY, suppress_warnings, _gen_alignment_data, + assert_warns, assert_raises_regex, + ) + +types = [np.bool_, np.byte, np.ubyte, np.short, np.ushort, np.intc, np.uintc, + np.int_, np.uint, np.longlong, np.ulonglong, + np.single, np.double, np.longdouble, np.csingle, + np.cdouble, np.clongdouble] + +floating_types = np.floating.__subclasses__() +complex_floating_types = np.complexfloating.__subclasses__() + + +# This compares scalarmath against ufuncs. + +class TestTypes: + def test_types(self): + for atype in types: + a = atype(1) + assert_(a == 1, "error with %r: got %r" % (atype, a)) + + def test_type_add(self): + # list of types + for k, atype in enumerate(types): + a_scalar = atype(3) + a_array = np.array([3], dtype=atype) + for l, btype in enumerate(types): + b_scalar = btype(1) + b_array = np.array([1], dtype=btype) + c_scalar = a_scalar + b_scalar + c_array = a_array + b_array + # It was comparing the type numbers, but the new ufunc + # function-finding mechanism finds the lowest function + # to which both inputs can be cast - which produces 'l' + # when you do 'q' + 'b'. The old function finding mechanism + # skipped ahead based on the first argument, but that + # does not produce properly symmetric results... + assert_equal(c_scalar.dtype, c_array.dtype, + "error with types (%d/'%c' + %d/'%c')" % + (k, np.dtype(atype).char, l, np.dtype(btype).char)) + + def test_type_create(self): + for k, atype in enumerate(types): + a = np.array([1, 2, 3], atype) + b = atype([1, 2, 3]) + assert_equal(a, b) + + def test_leak(self): + # test leak of scalar objects + # a leak would show up in valgrind as still-reachable of ~2.6MB + for i in range(200000): + np.add(1, 1) + + +class TestBaseMath: + def test_blocked(self): + # test alignments offsets for simd instructions + # alignments for vz + 2 * (vs - 1) + 1 + for dt, sz in [(np.float32, 11), (np.float64, 7), (np.int32, 11)]: + for out, inp1, inp2, msg in _gen_alignment_data(dtype=dt, + type='binary', + max_size=sz): + exp1 = np.ones_like(inp1) + inp1[...] = np.ones_like(inp1) + inp2[...] = np.zeros_like(inp2) + assert_almost_equal(np.add(inp1, inp2), exp1, err_msg=msg) + assert_almost_equal(np.add(inp1, 2), exp1 + 2, err_msg=msg) + assert_almost_equal(np.add(1, inp2), exp1, err_msg=msg) + + np.add(inp1, inp2, out=out) + assert_almost_equal(out, exp1, err_msg=msg) + + inp2[...] += np.arange(inp2.size, dtype=dt) + 1 + assert_almost_equal(np.square(inp2), + np.multiply(inp2, inp2), err_msg=msg) + # skip true divide for ints + if dt != np.int32: + assert_almost_equal(np.reciprocal(inp2), + np.divide(1, inp2), err_msg=msg) + + inp1[...] = np.ones_like(inp1) + np.add(inp1, 2, out=out) + assert_almost_equal(out, exp1 + 2, err_msg=msg) + inp2[...] = np.ones_like(inp2) + np.add(2, inp2, out=out) + assert_almost_equal(out, exp1 + 2, err_msg=msg) + + def test_lower_align(self): + # check data that is not aligned to element size + # i.e doubles are aligned to 4 bytes on i386 + d = np.zeros(23 * 8, dtype=np.int8)[4:-4].view(np.float64) + o = np.zeros(23 * 8, dtype=np.int8)[4:-4].view(np.float64) + assert_almost_equal(d + d, d * 2) + np.add(d, d, out=o) + np.add(np.ones_like(d), d, out=o) + np.add(d, np.ones_like(d), out=o) + np.add(np.ones_like(d), d) + np.add(d, np.ones_like(d)) + + +class TestPower: + def test_small_types(self): + for t in [np.int8, np.int16, np.float16]: + a = t(3) + b = a ** 4 + assert_(b == 81, "error with %r: got %r" % (t, b)) + + def test_large_types(self): + for t in [np.int32, np.int64, np.float32, np.float64, np.longdouble]: + a = t(51) + b = a ** 4 + msg = "error with %r: got %r" % (t, b) + if np.issubdtype(t, np.integer): + assert_(b == 6765201, msg) + else: + assert_almost_equal(b, 6765201, err_msg=msg) + + def test_integers_to_negative_integer_power(self): + # Note that the combination of uint64 with a signed integer + # has common type np.float64. The other combinations should all + # raise a ValueError for integer ** negative integer. + exp = [np.array(-1, dt)[()] for dt in 'bhilq'] + + # 1 ** -1 possible special case + base = [np.array(1, dt)[()] for dt in 'bhilqBHILQ'] + for i1, i2 in itertools.product(base, exp): + if i1.dtype != np.uint64: + assert_raises(ValueError, operator.pow, i1, i2) + else: + res = operator.pow(i1, i2) + assert_(res.dtype.type is np.float64) + assert_almost_equal(res, 1.) + + # -1 ** -1 possible special case + base = [np.array(-1, dt)[()] for dt in 'bhilq'] + for i1, i2 in itertools.product(base, exp): + if i1.dtype != np.uint64: + assert_raises(ValueError, operator.pow, i1, i2) + else: + res = operator.pow(i1, i2) + assert_(res.dtype.type is np.float64) + assert_almost_equal(res, -1.) + + # 2 ** -1 perhaps generic + base = [np.array(2, dt)[()] for dt in 'bhilqBHILQ'] + for i1, i2 in itertools.product(base, exp): + if i1.dtype != np.uint64: + assert_raises(ValueError, operator.pow, i1, i2) + else: + res = operator.pow(i1, i2) + assert_(res.dtype.type is np.float64) + assert_almost_equal(res, .5) + + def test_mixed_types(self): + typelist = [np.int8, np.int16, np.float16, + np.float32, np.float64, np.int8, + np.int16, np.int32, np.int64] + for t1 in typelist: + for t2 in typelist: + a = t1(3) + b = t2(2) + result = a**b + msg = ("error with %r and %r:" + "got %r, expected %r") % (t1, t2, result, 9) + if np.issubdtype(np.dtype(result), np.integer): + assert_(result == 9, msg) + else: + assert_almost_equal(result, 9, err_msg=msg) + + def test_modular_power(self): + # modular power is not implemented, so ensure it errors + a = 5 + b = 4 + c = 10 + expected = pow(a, b, c) # noqa: F841 + for t in (np.int32, np.float32, np.complex64): + # note that 3-operand power only dispatches on the first argument + assert_raises(TypeError, operator.pow, t(a), b, c) + assert_raises(TypeError, operator.pow, np.array(t(a)), b, c) + + +def floordiv_and_mod(x, y): + return (x // y, x % y) + + +def _signs(dt): + if dt in np.typecodes['UnsignedInteger']: + return (+1,) + else: + return (+1, -1) + + +class TestModulus: + + def test_modulus_basic(self): + dt = np.typecodes['AllInteger'] + np.typecodes['Float'] + for op in [floordiv_and_mod, divmod]: + for dt1, dt2 in itertools.product(dt, dt): + for sg1, sg2 in itertools.product(_signs(dt1), _signs(dt2)): + fmt = 'op: %s, dt1: %s, dt2: %s, sg1: %s, sg2: %s' + msg = fmt % (op.__name__, dt1, dt2, sg1, sg2) + a = np.array(sg1*71, dtype=dt1)[()] + b = np.array(sg2*19, dtype=dt2)[()] + div, rem = op(a, b) + assert_equal(div*b + rem, a, err_msg=msg) + if sg2 == -1: + assert_(b < rem <= 0, msg) + else: + assert_(b > rem >= 0, msg) + + def test_float_modulus_exact(self): + # test that float results are exact for small integers. This also + # holds for the same integers scaled by powers of two. + nlst = list(range(-127, 0)) + plst = list(range(1, 128)) + dividend = nlst + [0] + plst + divisor = nlst + plst + arg = list(itertools.product(dividend, divisor)) + tgt = list(divmod(*t) for t in arg) + + a, b = np.array(arg, dtype=int).T + # convert exact integer results from Python to float so that + # signed zero can be used, it is checked. + tgtdiv, tgtrem = np.array(tgt, dtype=float).T + tgtdiv = np.where((tgtdiv == 0.0) & ((b < 0) ^ (a < 0)), -0.0, tgtdiv) + tgtrem = np.where((tgtrem == 0.0) & (b < 0), -0.0, tgtrem) + + for op in [floordiv_and_mod, divmod]: + for dt in np.typecodes['Float']: + msg = 'op: %s, dtype: %s' % (op.__name__, dt) + fa = a.astype(dt) + fb = b.astype(dt) + # use list comprehension so a_ and b_ are scalars + div, rem = zip(*[op(a_, b_) for a_, b_ in zip(fa, fb)]) + assert_equal(div, tgtdiv, err_msg=msg) + assert_equal(rem, tgtrem, err_msg=msg) + + def test_float_modulus_roundoff(self): + # gh-6127 + dt = np.typecodes['Float'] + for op in [floordiv_and_mod, divmod]: + for dt1, dt2 in itertools.product(dt, dt): + for sg1, sg2 in itertools.product((+1, -1), (+1, -1)): + fmt = 'op: %s, dt1: %s, dt2: %s, sg1: %s, sg2: %s' + msg = fmt % (op.__name__, dt1, dt2, sg1, sg2) + a = np.array(sg1*78*6e-8, dtype=dt1)[()] + b = np.array(sg2*6e-8, dtype=dt2)[()] + div, rem = op(a, b) + # Equal assertion should hold when fmod is used + assert_equal(div*b + rem, a, err_msg=msg) + if sg2 == -1: + assert_(b < rem <= 0, msg) + else: + assert_(b > rem >= 0, msg) + + def test_float_modulus_corner_cases(self): + # Check remainder magnitude. + for dt in np.typecodes['Float']: + b = np.array(1.0, dtype=dt) + a = np.nextafter(np.array(0.0, dtype=dt), -b) + rem = operator.mod(a, b) + assert_(rem <= b, 'dt: %s' % dt) + rem = operator.mod(-a, -b) + assert_(rem >= -b, 'dt: %s' % dt) + + # Check nans, inf + with suppress_warnings() as sup: + sup.filter(RuntimeWarning, "invalid value encountered in remainder") + sup.filter(RuntimeWarning, "divide by zero encountered in remainder") + sup.filter(RuntimeWarning, "divide by zero encountered in floor_divide") + sup.filter(RuntimeWarning, "divide by zero encountered in divmod") + sup.filter(RuntimeWarning, "invalid value encountered in divmod") + for dt in np.typecodes['Float']: + fone = np.array(1.0, dtype=dt) + fzer = np.array(0.0, dtype=dt) + finf = np.array(np.inf, dtype=dt) + fnan = np.array(np.nan, dtype=dt) + rem = operator.mod(fone, fzer) + assert_(np.isnan(rem), 'dt: %s' % dt) + # MSVC 2008 returns NaN here, so disable the check. + #rem = operator.mod(fone, finf) + #assert_(rem == fone, 'dt: %s' % dt) + rem = operator.mod(fone, fnan) + assert_(np.isnan(rem), 'dt: %s' % dt) + rem = operator.mod(finf, fone) + assert_(np.isnan(rem), 'dt: %s' % dt) + for op in [floordiv_and_mod, divmod]: + div, mod = op(fone, fzer) + assert_(np.isinf(div)) and assert_(np.isnan(mod)) + + def test_inplace_floordiv_handling(self): + # issue gh-12927 + # this only applies to in-place floordiv //=, because the output type + # promotes to float which does not fit + a = np.array([1, 2], np.int64) + b = np.array([1, 2], np.uint64) + pattern = 'could not be coerced to provided output parameter' + with assert_raises_regex(TypeError, pattern): + a //= b + + +class TestComplexDivision: + def test_zero_division(self): + with np.errstate(all="ignore"): + for t in [np.complex64, np.complex128]: + a = t(0.0) + b = t(1.0) + assert_(np.isinf(b/a)) + b = t(complex(np.inf, np.inf)) + assert_(np.isinf(b/a)) + b = t(complex(np.inf, np.nan)) + assert_(np.isinf(b/a)) + b = t(complex(np.nan, np.inf)) + assert_(np.isinf(b/a)) + b = t(complex(np.nan, np.nan)) + assert_(np.isnan(b/a)) + b = t(0.) + assert_(np.isnan(b/a)) + + def test_signed_zeros(self): + with np.errstate(all="ignore"): + for t in [np.complex64, np.complex128]: + # tupled (numerator, denominator, expected) + # for testing as expected == numerator/denominator + data = ( + (( 0.0,-1.0), ( 0.0, 1.0), (-1.0,-0.0)), + (( 0.0,-1.0), ( 0.0,-1.0), ( 1.0,-0.0)), + (( 0.0,-1.0), (-0.0,-1.0), ( 1.0, 0.0)), + (( 0.0,-1.0), (-0.0, 1.0), (-1.0, 0.0)), + (( 0.0, 1.0), ( 0.0,-1.0), (-1.0, 0.0)), + (( 0.0,-1.0), ( 0.0,-1.0), ( 1.0,-0.0)), + ((-0.0,-1.0), ( 0.0,-1.0), ( 1.0,-0.0)), + ((-0.0, 1.0), ( 0.0,-1.0), (-1.0,-0.0)) + ) + for cases in data: + n = cases[0] + d = cases[1] + ex = cases[2] + result = t(complex(n[0], n[1])) / t(complex(d[0], d[1])) + # check real and imag parts separately to avoid comparison + # in array context, which does not account for signed zeros + assert_equal(result.real, ex[0]) + assert_equal(result.imag, ex[1]) + + def test_branches(self): + with np.errstate(all="ignore"): + for t in [np.complex64, np.complex128]: + # tupled (numerator, denominator, expected) + # for testing as expected == numerator/denominator + data = list() + + # trigger branch: real(fabs(denom)) > imag(fabs(denom)) + # followed by else condition as neither are == 0 + data.append((( 2.0, 1.0), ( 2.0, 1.0), (1.0, 0.0))) + + # trigger branch: real(fabs(denom)) > imag(fabs(denom)) + # followed by if condition as both are == 0 + # is performed in test_zero_division(), so this is skipped + + # trigger else if branch: real(fabs(denom)) < imag(fabs(denom)) + data.append((( 1.0, 2.0), ( 1.0, 2.0), (1.0, 0.0))) + + for cases in data: + n = cases[0] + d = cases[1] + ex = cases[2] + result = t(complex(n[0], n[1])) / t(complex(d[0], d[1])) + # check real and imag parts separately to avoid comparison + # in array context, which does not account for signed zeros + assert_equal(result.real, ex[0]) + assert_equal(result.imag, ex[1]) + + +class TestConversion: + def test_int_from_long(self): + l = [1e6, 1e12, 1e18, -1e6, -1e12, -1e18] + li = [10**6, 10**12, 10**18, -10**6, -10**12, -10**18] + for T in [None, np.float64, np.int64]: + a = np.array(l, dtype=T) + assert_equal([int(_m) for _m in a], li) + + a = np.array(l[:3], dtype=np.uint64) + assert_equal([int(_m) for _m in a], li[:3]) + + def test_iinfo_long_values(self): + for code in 'bBhH': + res = np.array(np.iinfo(code).max + 1, dtype=code) + tgt = np.iinfo(code).min + assert_(res == tgt) + + for code in np.typecodes['AllInteger']: + res = np.array(np.iinfo(code).max, dtype=code) + tgt = np.iinfo(code).max + assert_(res == tgt) + + for code in np.typecodes['AllInteger']: + res = np.typeDict[code](np.iinfo(code).max) + tgt = np.iinfo(code).max + assert_(res == tgt) + + def test_int_raise_behaviour(self): + def overflow_error_func(dtype): + np.typeDict[dtype](np.iinfo(dtype).max + 1) + + for code in 'lLqQ': + assert_raises(OverflowError, overflow_error_func, code) + + def test_int_from_infinite_longdouble(self): + # gh-627 + x = np.longdouble(np.inf) + assert_raises(OverflowError, int, x) + with suppress_warnings() as sup: + sup.record(np.ComplexWarning) + x = np.clongdouble(np.inf) + assert_raises(OverflowError, int, x) + assert_equal(len(sup.log), 1) + + @pytest.mark.skipif(not IS_PYPY, reason="Test is PyPy only (gh-9972)") + def test_int_from_infinite_longdouble___int__(self): + x = np.longdouble(np.inf) + assert_raises(OverflowError, x.__int__) + with suppress_warnings() as sup: + sup.record(np.ComplexWarning) + x = np.clongdouble(np.inf) + assert_raises(OverflowError, x.__int__) + assert_equal(len(sup.log), 1) + + @pytest.mark.skipif(np.finfo(np.double) == np.finfo(np.longdouble), + reason="long double is same as double") + @pytest.mark.skipif(platform.machine().startswith("ppc"), + reason="IBM double double") + def test_int_from_huge_longdouble(self): + # Produce a longdouble that would overflow a double, + # use exponent that avoids bug in Darwin pow function. + exp = np.finfo(np.double).maxexp - 1 + huge_ld = 2 * 1234 * np.longdouble(2) ** exp + huge_i = 2 * 1234 * 2 ** exp + assert_(huge_ld != np.inf) + assert_equal(int(huge_ld), huge_i) + + def test_int_from_longdouble(self): + x = np.longdouble(1.5) + assert_equal(int(x), 1) + x = np.longdouble(-10.5) + assert_equal(int(x), -10) + + def test_numpy_scalar_relational_operators(self): + # All integer + for dt1 in np.typecodes['AllInteger']: + assert_(1 > np.array(0, dtype=dt1)[()], "type %s failed" % (dt1,)) + assert_(not 1 < np.array(0, dtype=dt1)[()], "type %s failed" % (dt1,)) + + for dt2 in np.typecodes['AllInteger']: + assert_(np.array(1, dtype=dt1)[()] > np.array(0, dtype=dt2)[()], + "type %s and %s failed" % (dt1, dt2)) + assert_(not np.array(1, dtype=dt1)[()] < np.array(0, dtype=dt2)[()], + "type %s and %s failed" % (dt1, dt2)) + + #Unsigned integers + for dt1 in 'BHILQP': + assert_(-1 < np.array(1, dtype=dt1)[()], "type %s failed" % (dt1,)) + assert_(not -1 > np.array(1, dtype=dt1)[()], "type %s failed" % (dt1,)) + assert_(-1 != np.array(1, dtype=dt1)[()], "type %s failed" % (dt1,)) + + #unsigned vs signed + for dt2 in 'bhilqp': + assert_(np.array(1, dtype=dt1)[()] > np.array(-1, dtype=dt2)[()], + "type %s and %s failed" % (dt1, dt2)) + assert_(not np.array(1, dtype=dt1)[()] < np.array(-1, dtype=dt2)[()], + "type %s and %s failed" % (dt1, dt2)) + assert_(np.array(1, dtype=dt1)[()] != np.array(-1, dtype=dt2)[()], + "type %s and %s failed" % (dt1, dt2)) + + #Signed integers and floats + for dt1 in 'bhlqp' + np.typecodes['Float']: + assert_(1 > np.array(-1, dtype=dt1)[()], "type %s failed" % (dt1,)) + assert_(not 1 < np.array(-1, dtype=dt1)[()], "type %s failed" % (dt1,)) + assert_(-1 == np.array(-1, dtype=dt1)[()], "type %s failed" % (dt1,)) + + for dt2 in 'bhlqp' + np.typecodes['Float']: + assert_(np.array(1, dtype=dt1)[()] > np.array(-1, dtype=dt2)[()], + "type %s and %s failed" % (dt1, dt2)) + assert_(not np.array(1, dtype=dt1)[()] < np.array(-1, dtype=dt2)[()], + "type %s and %s failed" % (dt1, dt2)) + assert_(np.array(-1, dtype=dt1)[()] == np.array(-1, dtype=dt2)[()], + "type %s and %s failed" % (dt1, dt2)) + + def test_scalar_comparison_to_none(self): + # Scalars should just return False and not give a warnings. + # The comparisons are flagged by pep8, ignore that. + with warnings.catch_warnings(record=True) as w: + warnings.filterwarnings('always', '', FutureWarning) + assert_(not np.float32(1) == None) + assert_(not np.str_('test') == None) + # This is dubious (see below): + assert_(not np.datetime64('NaT') == None) + + assert_(np.float32(1) != None) + assert_(np.str_('test') != None) + # This is dubious (see below): + assert_(np.datetime64('NaT') != None) + assert_(len(w) == 0) + + # For documentation purposes, this is why the datetime is dubious. + # At the time of deprecation this was no behaviour change, but + # it has to be considered when the deprecations are done. + assert_(np.equal(np.datetime64('NaT'), None)) + + +#class TestRepr: +# def test_repr(self): +# for t in types: +# val = t(1197346475.0137341) +# val_repr = repr(val) +# val2 = eval(val_repr) +# assert_equal( val, val2 ) + + +class TestRepr: + def _test_type_repr(self, t): + finfo = np.finfo(t) + last_fraction_bit_idx = finfo.nexp + finfo.nmant + last_exponent_bit_idx = finfo.nexp + storage_bytes = np.dtype(t).itemsize*8 + # could add some more types to the list below + for which in ['small denorm', 'small norm']: + # Values from https://en.wikipedia.org/wiki/IEEE_754 + constr = np.array([0x00]*storage_bytes, dtype=np.uint8) + if which == 'small denorm': + byte = last_fraction_bit_idx // 8 + bytebit = 7-(last_fraction_bit_idx % 8) + constr[byte] = 1 << bytebit + elif which == 'small norm': + byte = last_exponent_bit_idx // 8 + bytebit = 7-(last_exponent_bit_idx % 8) + constr[byte] = 1 << bytebit + else: + raise ValueError('hmm') + val = constr.view(t)[0] + val_repr = repr(val) + val2 = t(eval(val_repr)) + if not (val2 == 0 and val < 1e-100): + assert_equal(val, val2) + + def test_float_repr(self): + # long double test cannot work, because eval goes through a python + # float + for t in [np.float32, np.float64]: + self._test_type_repr(t) + + +if not IS_PYPY: + # sys.getsizeof() is not valid on PyPy + class TestSizeOf: + + def test_equal_nbytes(self): + for type in types: + x = type(0) + assert_(sys.getsizeof(x) > x.nbytes) + + def test_error(self): + d = np.float32() + assert_raises(TypeError, d.__sizeof__, "a") + + +class TestMultiply: + def test_seq_repeat(self): + # Test that basic sequences get repeated when multiplied with + # numpy integers. And errors are raised when multiplied with others. + # Some of this behaviour may be controversial and could be open for + # change. + accepted_types = set(np.typecodes["AllInteger"]) + deprecated_types = {'?'} + forbidden_types = ( + set(np.typecodes["All"]) - accepted_types - deprecated_types) + forbidden_types -= {'V'} # can't default-construct void scalars + + for seq_type in (list, tuple): + seq = seq_type([1, 2, 3]) + for numpy_type in accepted_types: + i = np.dtype(numpy_type).type(2) + assert_equal(seq * i, seq * int(i)) + assert_equal(i * seq, int(i) * seq) + + for numpy_type in deprecated_types: + i = np.dtype(numpy_type).type() + assert_equal( + assert_warns(DeprecationWarning, operator.mul, seq, i), + seq * int(i)) + assert_equal( + assert_warns(DeprecationWarning, operator.mul, i, seq), + int(i) * seq) + + for numpy_type in forbidden_types: + i = np.dtype(numpy_type).type() + assert_raises(TypeError, operator.mul, seq, i) + assert_raises(TypeError, operator.mul, i, seq) + + def test_no_seq_repeat_basic_array_like(self): + # Test that an array-like which does not know how to be multiplied + # does not attempt sequence repeat (raise TypeError). + # See also gh-7428. + class ArrayLike: + def __init__(self, arr): + self.arr = arr + def __array__(self): + return self.arr + + # Test for simple ArrayLike above and memoryviews (original report) + for arr_like in (ArrayLike(np.ones(3)), memoryview(np.ones(3))): + assert_array_equal(arr_like * np.float32(3.), np.full(3, 3.)) + assert_array_equal(np.float32(3.) * arr_like, np.full(3, 3.)) + assert_array_equal(arr_like * np.int_(3), np.full(3, 3)) + assert_array_equal(np.int_(3) * arr_like, np.full(3, 3)) + + +class TestNegative: + def test_exceptions(self): + a = np.ones((), dtype=np.bool_)[()] + assert_raises(TypeError, operator.neg, a) + + def test_result(self): + types = np.typecodes['AllInteger'] + np.typecodes['AllFloat'] + with suppress_warnings() as sup: + sup.filter(RuntimeWarning) + for dt in types: + a = np.ones((), dtype=dt)[()] + assert_equal(operator.neg(a) + a, 0) + + +class TestSubtract: + def test_exceptions(self): + a = np.ones((), dtype=np.bool_)[()] + assert_raises(TypeError, operator.sub, a, a) + + def test_result(self): + types = np.typecodes['AllInteger'] + np.typecodes['AllFloat'] + with suppress_warnings() as sup: + sup.filter(RuntimeWarning) + for dt in types: + a = np.ones((), dtype=dt)[()] + assert_equal(operator.sub(a, a), 0) + + +class TestAbs: + def _test_abs_func(self, absfunc): + for tp in floating_types + complex_floating_types: + x = tp(-1.5) + assert_equal(absfunc(x), 1.5) + x = tp(0.0) + res = absfunc(x) + # assert_equal() checks zero signedness + assert_equal(res, 0.0) + x = tp(-0.0) + res = absfunc(x) + assert_equal(res, 0.0) + + x = tp(np.finfo(tp).max) + assert_equal(absfunc(x), x.real) + + x = tp(np.finfo(tp).tiny) + assert_equal(absfunc(x), x.real) + + x = tp(np.finfo(tp).min) + assert_equal(absfunc(x), -x.real) + + def test_builtin_abs(self): + self._test_abs_func(abs) + + def test_numpy_abs(self): + self._test_abs_func(np.abs) + + +class TestBitShifts: + + @pytest.mark.parametrize('type_code', np.typecodes['AllInteger']) + @pytest.mark.parametrize('op', + [operator.rshift, operator.lshift], ids=['>>', '<<']) + def test_shift_all_bits(self, type_code, op): + """ Shifts where the shift amount is the width of the type or wider """ + # gh-2449 + dt = np.dtype(type_code) + nbits = dt.itemsize * 8 + for val in [5, -5]: + for shift in [nbits, nbits + 4]: + val_scl = dt.type(val) + shift_scl = dt.type(shift) + res_scl = op(val_scl, shift_scl) + if val_scl < 0 and op is operator.rshift: + # sign bit is preserved + assert_equal(res_scl, -1) + else: + assert_equal(res_scl, 0) + + # Result on scalars should be the same as on arrays + val_arr = np.array([val]*32, dtype=dt) + shift_arr = np.array([shift]*32, dtype=dt) + res_arr = op(val_arr, shift_arr) + assert_equal(res_arr, res_scl) diff --git a/venv/Lib/site-packages/numpy/core/tests/test_scalarprint.py b/venv/Lib/site-packages/numpy/core/tests/test_scalarprint.py new file mode 100644 index 0000000..6502ec4 --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/tests/test_scalarprint.py @@ -0,0 +1,322 @@ +# -*- coding: utf-8 -*- +""" Test printing of scalar types. + +""" +import code +import platform +import pytest +import sys + +from tempfile import TemporaryFile +import numpy as np +from numpy.testing import assert_, assert_equal + +class TestRealScalars: + def test_str(self): + svals = [0.0, -0.0, 1, -1, np.inf, -np.inf, np.nan] + styps = [np.float16, np.float32, np.float64, np.longdouble] + wanted = [ + ['0.0', '0.0', '0.0', '0.0' ], + ['-0.0', '-0.0', '-0.0', '-0.0'], + ['1.0', '1.0', '1.0', '1.0' ], + ['-1.0', '-1.0', '-1.0', '-1.0'], + ['inf', 'inf', 'inf', 'inf' ], + ['-inf', '-inf', '-inf', '-inf'], + ['nan', 'nan', 'nan', 'nan']] + + for wants, val in zip(wanted, svals): + for want, styp in zip(wants, styps): + msg = 'for str({}({}))'.format(np.dtype(styp).name, repr(val)) + assert_equal(str(styp(val)), want, err_msg=msg) + + def test_scalar_cutoffs(self): + # test that both the str and repr of np.float64 behaves + # like python floats in python3. + def check(v): + assert_equal(str(np.float64(v)), str(v)) + assert_equal(str(np.float64(v)), repr(v)) + assert_equal(repr(np.float64(v)), repr(v)) + assert_equal(repr(np.float64(v)), str(v)) + + # check we use the same number of significant digits + check(1.12345678901234567890) + check(0.0112345678901234567890) + + # check switch from scientific output to positional and back + check(1e-5) + check(1e-4) + check(1e15) + check(1e16) + + def test_py2_float_print(self): + # gh-10753 + # In python2, the python float type implements an obsolete method + # tp_print, which overrides tp_repr and tp_str when using "print" to + # output to a "real file" (ie, not a StringIO). Make sure we don't + # inherit it. + x = np.double(0.1999999999999) + with TemporaryFile('r+t') as f: + print(x, file=f) + f.seek(0) + output = f.read() + assert_equal(output, str(x) + '\n') + # In python2 the value float('0.1999999999999') prints with reduced + # precision as '0.2', but we want numpy's np.double('0.1999999999999') + # to print the unique value, '0.1999999999999'. + + # gh-11031 + # Only in the python2 interactive shell and when stdout is a "real" + # file, the output of the last command is printed to stdout without + # Py_PRINT_RAW (unlike the print statement) so `>>> x` and `>>> print + # x` are potentially different. Make sure they are the same. The only + # way I found to get prompt-like output is using an actual prompt from + # the 'code' module. Again, must use tempfile to get a "real" file. + + # dummy user-input which enters one line and then ctrl-Ds. + def userinput(): + yield 'np.sqrt(2)' + raise EOFError + gen = userinput() + input_func = lambda prompt="": next(gen) + + with TemporaryFile('r+t') as fo, TemporaryFile('r+t') as fe: + orig_stdout, orig_stderr = sys.stdout, sys.stderr + sys.stdout, sys.stderr = fo, fe + + code.interact(local={'np': np}, readfunc=input_func, banner='') + + sys.stdout, sys.stderr = orig_stdout, orig_stderr + + fo.seek(0) + capture = fo.read().strip() + + assert_equal(capture, repr(np.sqrt(2))) + + def test_dragon4(self): + # these tests are adapted from Ryan Juckett's dragon4 implementation, + # see dragon4.c for details. + + fpos32 = lambda x, **k: np.format_float_positional(np.float32(x), **k) + fsci32 = lambda x, **k: np.format_float_scientific(np.float32(x), **k) + fpos64 = lambda x, **k: np.format_float_positional(np.float64(x), **k) + fsci64 = lambda x, **k: np.format_float_scientific(np.float64(x), **k) + + preckwd = lambda prec: {'unique': False, 'precision': prec} + + assert_equal(fpos32('1.0'), "1.") + assert_equal(fsci32('1.0'), "1.e+00") + assert_equal(fpos32('10.234'), "10.234") + assert_equal(fpos32('-10.234'), "-10.234") + assert_equal(fsci32('10.234'), "1.0234e+01") + assert_equal(fsci32('-10.234'), "-1.0234e+01") + assert_equal(fpos32('1000.0'), "1000.") + assert_equal(fpos32('1.0', precision=0), "1.") + assert_equal(fsci32('1.0', precision=0), "1.e+00") + assert_equal(fpos32('10.234', precision=0), "10.") + assert_equal(fpos32('-10.234', precision=0), "-10.") + assert_equal(fsci32('10.234', precision=0), "1.e+01") + assert_equal(fsci32('-10.234', precision=0), "-1.e+01") + assert_equal(fpos32('10.234', precision=2), "10.23") + assert_equal(fsci32('-10.234', precision=2), "-1.02e+01") + assert_equal(fsci64('9.9999999999999995e-08', **preckwd(16)), + '9.9999999999999995e-08') + assert_equal(fsci64('9.8813129168249309e-324', **preckwd(16)), + '9.8813129168249309e-324') + assert_equal(fsci64('9.9999999999999694e-311', **preckwd(16)), + '9.9999999999999694e-311') + + + # test rounding + # 3.1415927410 is closest float32 to np.pi + assert_equal(fpos32('3.14159265358979323846', **preckwd(10)), + "3.1415927410") + assert_equal(fsci32('3.14159265358979323846', **preckwd(10)), + "3.1415927410e+00") + assert_equal(fpos64('3.14159265358979323846', **preckwd(10)), + "3.1415926536") + assert_equal(fsci64('3.14159265358979323846', **preckwd(10)), + "3.1415926536e+00") + # 299792448 is closest float32 to 299792458 + assert_equal(fpos32('299792458.0', **preckwd(5)), "299792448.00000") + assert_equal(fsci32('299792458.0', **preckwd(5)), "2.99792e+08") + assert_equal(fpos64('299792458.0', **preckwd(5)), "299792458.00000") + assert_equal(fsci64('299792458.0', **preckwd(5)), "2.99792e+08") + + assert_equal(fpos32('3.14159265358979323846', **preckwd(25)), + "3.1415927410125732421875000") + assert_equal(fpos64('3.14159265358979323846', **preckwd(50)), + "3.14159265358979311599796346854418516159057617187500") + assert_equal(fpos64('3.14159265358979323846'), "3.141592653589793") + + + # smallest numbers + assert_equal(fpos32(0.5**(126 + 23), unique=False, precision=149), + "0.00000000000000000000000000000000000000000000140129846432" + "4817070923729583289916131280261941876515771757068283889791" + "08268586060148663818836212158203125") + assert_equal(fpos64(0.5**(1022 + 52), unique=False, precision=1074), + "0.00000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000049406564584124654417656" + "8792868221372365059802614324764425585682500675507270208751" + "8652998363616359923797965646954457177309266567103559397963" + "9877479601078187812630071319031140452784581716784898210368" + "8718636056998730723050006387409153564984387312473397273169" + "6151400317153853980741262385655911710266585566867681870395" + "6031062493194527159149245532930545654440112748012970999954" + "1931989409080416563324524757147869014726780159355238611550" + "1348035264934720193790268107107491703332226844753335720832" + "4319360923828934583680601060115061698097530783422773183292" + "4790498252473077637592724787465608477820373446969953364701" + "7972677717585125660551199131504891101451037862738167250955" + "8373897335989936648099411642057026370902792427675445652290" + "87538682506419718265533447265625") + + # largest numbers + assert_equal(fpos32(np.finfo(np.float32).max, **preckwd(0)), + "340282346638528859811704183484516925440.") + assert_equal(fpos64(np.finfo(np.float64).max, **preckwd(0)), + "1797693134862315708145274237317043567980705675258449965989" + "1747680315726078002853876058955863276687817154045895351438" + "2464234321326889464182768467546703537516986049910576551282" + "0762454900903893289440758685084551339423045832369032229481" + "6580855933212334827479782620414472316873817718091929988125" + "0404026184124858368.") + # Warning: In unique mode only the integer digits necessary for + # uniqueness are computed, the rest are 0. Should we change this? + assert_equal(fpos32(np.finfo(np.float32).max, precision=0), + "340282350000000000000000000000000000000.") + + # test trailing zeros + assert_equal(fpos32('1.0', unique=False, precision=3), "1.000") + assert_equal(fpos64('1.0', unique=False, precision=3), "1.000") + assert_equal(fsci32('1.0', unique=False, precision=3), "1.000e+00") + assert_equal(fsci64('1.0', unique=False, precision=3), "1.000e+00") + assert_equal(fpos32('1.5', unique=False, precision=3), "1.500") + assert_equal(fpos64('1.5', unique=False, precision=3), "1.500") + assert_equal(fsci32('1.5', unique=False, precision=3), "1.500e+00") + assert_equal(fsci64('1.5', unique=False, precision=3), "1.500e+00") + # gh-10713 + assert_equal(fpos64('324', unique=False, precision=5, fractional=False), "324.00") + + def test_dragon4_interface(self): + tps = [np.float16, np.float32, np.float64] + if hasattr(np, 'float128'): + tps.append(np.float128) + + fpos = np.format_float_positional + fsci = np.format_float_scientific + + for tp in tps: + # test padding + assert_equal(fpos(tp('1.0'), pad_left=4, pad_right=4), " 1. ") + assert_equal(fpos(tp('-1.0'), pad_left=4, pad_right=4), " -1. ") + assert_equal(fpos(tp('-10.2'), + pad_left=4, pad_right=4), " -10.2 ") + + # test exp_digits + assert_equal(fsci(tp('1.23e1'), exp_digits=5), "1.23e+00001") + + # test fixed (non-unique) mode + assert_equal(fpos(tp('1.0'), unique=False, precision=4), "1.0000") + assert_equal(fsci(tp('1.0'), unique=False, precision=4), + "1.0000e+00") + + # test trimming + # trim of 'k' or '.' only affects non-unique mode, since unique + # mode will not output trailing 0s. + assert_equal(fpos(tp('1.'), unique=False, precision=4, trim='k'), + "1.0000") + + assert_equal(fpos(tp('1.'), unique=False, precision=4, trim='.'), + "1.") + assert_equal(fpos(tp('1.2'), unique=False, precision=4, trim='.'), + "1.2" if tp != np.float16 else "1.2002") + + assert_equal(fpos(tp('1.'), unique=False, precision=4, trim='0'), + "1.0") + assert_equal(fpos(tp('1.2'), unique=False, precision=4, trim='0'), + "1.2" if tp != np.float16 else "1.2002") + assert_equal(fpos(tp('1.'), trim='0'), "1.0") + + assert_equal(fpos(tp('1.'), unique=False, precision=4, trim='-'), + "1") + assert_equal(fpos(tp('1.2'), unique=False, precision=4, trim='-'), + "1.2" if tp != np.float16 else "1.2002") + assert_equal(fpos(tp('1.'), trim='-'), "1") + + @pytest.mark.skipif(not platform.machine().startswith("ppc64"), + reason="only applies to ppc float128 values") + def test_ppc64_ibm_double_double128(self): + # check that the precision decreases once we get into the subnormal + # range. Unlike float64, this starts around 1e-292 instead of 1e-308, + # which happens when the first double is normal and the second is + # subnormal. + x = np.float128('2.123123123123123123123123123123123e-286') + got = [str(x/np.float128('2e' + str(i))) for i in range(0,40)] + expected = [ + "1.06156156156156156156156156156157e-286", + "1.06156156156156156156156156156158e-287", + "1.06156156156156156156156156156159e-288", + "1.0615615615615615615615615615616e-289", + "1.06156156156156156156156156156157e-290", + "1.06156156156156156156156156156156e-291", + "1.0615615615615615615615615615616e-292", + "1.0615615615615615615615615615615e-293", + "1.061561561561561561561561561562e-294", + "1.06156156156156156156156156155e-295", + "1.0615615615615615615615615616e-296", + "1.06156156156156156156156156e-297", + "1.06156156156156156156156157e-298", + "1.0615615615615615615615616e-299", + "1.06156156156156156156156e-300", + "1.06156156156156156156155e-301", + "1.0615615615615615615616e-302", + "1.061561561561561561562e-303", + "1.06156156156156156156e-304", + "1.0615615615615615618e-305", + "1.06156156156156156e-306", + "1.06156156156156157e-307", + "1.0615615615615616e-308", + "1.06156156156156e-309", + "1.06156156156157e-310", + "1.0615615615616e-311", + "1.06156156156e-312", + "1.06156156154e-313", + "1.0615615616e-314", + "1.06156156e-315", + "1.06156155e-316", + "1.061562e-317", + "1.06156e-318", + "1.06155e-319", + "1.0617e-320", + "1.06e-321", + "1.04e-322", + "1e-323", + "0.0", + "0.0"] + assert_equal(got, expected) + + # Note: we follow glibc behavior, but it (or gcc) might not be right. + # In particular we can get two values that print the same but are not + # equal: + a = np.float128('2')/np.float128('3') + b = np.float128(str(a)) + assert_equal(str(a), str(b)) + assert_(a != b) + + def float32_roundtrip(self): + # gh-9360 + x = np.float32(1024 - 2**-14) + y = np.float32(1024 - 2**-13) + assert_(repr(x) != repr(y)) + assert_equal(np.float32(repr(x)), x) + assert_equal(np.float32(repr(y)), y) + + def float64_vs_python(self): + # gh-2643, gh-6136, gh-6908 + assert_equal(repr(np.float64(0.1)), repr(0.1)) + assert_(repr(np.float64(0.20000000000000004)) != repr(0.2)) diff --git a/venv/Lib/site-packages/numpy/core/tests/test_shape_base.py b/venv/Lib/site-packages/numpy/core/tests/test_shape_base.py new file mode 100644 index 0000000..9922c91 --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/tests/test_shape_base.py @@ -0,0 +1,765 @@ +import pytest +import numpy as np +from numpy.core import ( + array, arange, atleast_1d, atleast_2d, atleast_3d, block, vstack, hstack, + newaxis, concatenate, stack + ) +from numpy.core.shape_base import (_block_dispatcher, _block_setup, + _block_concatenate, _block_slicing) +from numpy.testing import ( + assert_, assert_raises, assert_array_equal, assert_equal, + assert_raises_regex, assert_warns, IS_PYPY + ) + + +class TestAtleast1d: + def test_0D_array(self): + a = array(1) + b = array(2) + res = [atleast_1d(a), atleast_1d(b)] + desired = [array([1]), array([2])] + assert_array_equal(res, desired) + + def test_1D_array(self): + a = array([1, 2]) + b = array([2, 3]) + res = [atleast_1d(a), atleast_1d(b)] + desired = [array([1, 2]), array([2, 3])] + assert_array_equal(res, desired) + + def test_2D_array(self): + a = array([[1, 2], [1, 2]]) + b = array([[2, 3], [2, 3]]) + res = [atleast_1d(a), atleast_1d(b)] + desired = [a, b] + assert_array_equal(res, desired) + + def test_3D_array(self): + a = array([[1, 2], [1, 2]]) + b = array([[2, 3], [2, 3]]) + a = array([a, a]) + b = array([b, b]) + res = [atleast_1d(a), atleast_1d(b)] + desired = [a, b] + assert_array_equal(res, desired) + + def test_r1array(self): + """ Test to make sure equivalent Travis O's r1array function + """ + assert_(atleast_1d(3).shape == (1,)) + assert_(atleast_1d(3j).shape == (1,)) + assert_(atleast_1d(3.0).shape == (1,)) + assert_(atleast_1d([[2, 3], [4, 5]]).shape == (2, 2)) + + +class TestAtleast2d: + def test_0D_array(self): + a = array(1) + b = array(2) + res = [atleast_2d(a), atleast_2d(b)] + desired = [array([[1]]), array([[2]])] + assert_array_equal(res, desired) + + def test_1D_array(self): + a = array([1, 2]) + b = array([2, 3]) + res = [atleast_2d(a), atleast_2d(b)] + desired = [array([[1, 2]]), array([[2, 3]])] + assert_array_equal(res, desired) + + def test_2D_array(self): + a = array([[1, 2], [1, 2]]) + b = array([[2, 3], [2, 3]]) + res = [atleast_2d(a), atleast_2d(b)] + desired = [a, b] + assert_array_equal(res, desired) + + def test_3D_array(self): + a = array([[1, 2], [1, 2]]) + b = array([[2, 3], [2, 3]]) + a = array([a, a]) + b = array([b, b]) + res = [atleast_2d(a), atleast_2d(b)] + desired = [a, b] + assert_array_equal(res, desired) + + def test_r2array(self): + """ Test to make sure equivalent Travis O's r2array function + """ + assert_(atleast_2d(3).shape == (1, 1)) + assert_(atleast_2d([3j, 1]).shape == (1, 2)) + assert_(atleast_2d([[[3, 1], [4, 5]], [[3, 5], [1, 2]]]).shape == (2, 2, 2)) + + +class TestAtleast3d: + def test_0D_array(self): + a = array(1) + b = array(2) + res = [atleast_3d(a), atleast_3d(b)] + desired = [array([[[1]]]), array([[[2]]])] + assert_array_equal(res, desired) + + def test_1D_array(self): + a = array([1, 2]) + b = array([2, 3]) + res = [atleast_3d(a), atleast_3d(b)] + desired = [array([[[1], [2]]]), array([[[2], [3]]])] + assert_array_equal(res, desired) + + def test_2D_array(self): + a = array([[1, 2], [1, 2]]) + b = array([[2, 3], [2, 3]]) + res = [atleast_3d(a), atleast_3d(b)] + desired = [a[:,:, newaxis], b[:,:, newaxis]] + assert_array_equal(res, desired) + + def test_3D_array(self): + a = array([[1, 2], [1, 2]]) + b = array([[2, 3], [2, 3]]) + a = array([a, a]) + b = array([b, b]) + res = [atleast_3d(a), atleast_3d(b)] + desired = [a, b] + assert_array_equal(res, desired) + + +class TestHstack: + def test_non_iterable(self): + assert_raises(TypeError, hstack, 1) + + def test_empty_input(self): + assert_raises(ValueError, hstack, ()) + + def test_0D_array(self): + a = array(1) + b = array(2) + res = hstack([a, b]) + desired = array([1, 2]) + assert_array_equal(res, desired) + + def test_1D_array(self): + a = array([1]) + b = array([2]) + res = hstack([a, b]) + desired = array([1, 2]) + assert_array_equal(res, desired) + + def test_2D_array(self): + a = array([[1], [2]]) + b = array([[1], [2]]) + res = hstack([a, b]) + desired = array([[1, 1], [2, 2]]) + assert_array_equal(res, desired) + + def test_generator(self): + with assert_warns(FutureWarning): + hstack((np.arange(3) for _ in range(2))) + with assert_warns(FutureWarning): + hstack(map(lambda x: x, np.ones((3, 2)))) + + +class TestVstack: + def test_non_iterable(self): + assert_raises(TypeError, vstack, 1) + + def test_empty_input(self): + assert_raises(ValueError, vstack, ()) + + def test_0D_array(self): + a = array(1) + b = array(2) + res = vstack([a, b]) + desired = array([[1], [2]]) + assert_array_equal(res, desired) + + def test_1D_array(self): + a = array([1]) + b = array([2]) + res = vstack([a, b]) + desired = array([[1], [2]]) + assert_array_equal(res, desired) + + def test_2D_array(self): + a = array([[1], [2]]) + b = array([[1], [2]]) + res = vstack([a, b]) + desired = array([[1], [2], [1], [2]]) + assert_array_equal(res, desired) + + def test_2D_array2(self): + a = array([1, 2]) + b = array([1, 2]) + res = vstack([a, b]) + desired = array([[1, 2], [1, 2]]) + assert_array_equal(res, desired) + + def test_generator(self): + with assert_warns(FutureWarning): + vstack((np.arange(3) for _ in range(2))) + + +class TestConcatenate: + def test_returns_copy(self): + a = np.eye(3) + b = np.concatenate([a]) + b[0, 0] = 2 + assert b[0, 0] != a[0, 0] + + def test_exceptions(self): + # test axis must be in bounds + for ndim in [1, 2, 3]: + a = np.ones((1,)*ndim) + np.concatenate((a, a), axis=0) # OK + assert_raises(np.AxisError, np.concatenate, (a, a), axis=ndim) + assert_raises(np.AxisError, np.concatenate, (a, a), axis=-(ndim + 1)) + + # Scalars cannot be concatenated + assert_raises(ValueError, concatenate, (0,)) + assert_raises(ValueError, concatenate, (np.array(0),)) + + # dimensionality must match + assert_raises_regex( + ValueError, + r"all the input arrays must have same number of dimensions, but " + r"the array at index 0 has 1 dimension\(s\) and the array at " + r"index 1 has 2 dimension\(s\)", + np.concatenate, (np.zeros(1), np.zeros((1, 1)))) + + # test shapes must match except for concatenation axis + a = np.ones((1, 2, 3)) + b = np.ones((2, 2, 3)) + axis = list(range(3)) + for i in range(3): + np.concatenate((a, b), axis=axis[0]) # OK + assert_raises_regex( + ValueError, + "all the input array dimensions for the concatenation axis " + "must match exactly, but along dimension {}, the array at " + "index 0 has size 1 and the array at index 1 has size 2" + .format(i), + np.concatenate, (a, b), axis=axis[1]) + assert_raises(ValueError, np.concatenate, (a, b), axis=axis[2]) + a = np.moveaxis(a, -1, 0) + b = np.moveaxis(b, -1, 0) + axis.append(axis.pop(0)) + + # No arrays to concatenate raises ValueError + assert_raises(ValueError, concatenate, ()) + + def test_concatenate_axis_None(self): + a = np.arange(4, dtype=np.float64).reshape((2, 2)) + b = list(range(3)) + c = ['x'] + r = np.concatenate((a, a), axis=None) + assert_equal(r.dtype, a.dtype) + assert_equal(r.ndim, 1) + r = np.concatenate((a, b), axis=None) + assert_equal(r.size, a.size + len(b)) + assert_equal(r.dtype, a.dtype) + r = np.concatenate((a, b, c), axis=None) + d = array(['0.0', '1.0', '2.0', '3.0', + '0', '1', '2', 'x']) + assert_array_equal(r, d) + + out = np.zeros(a.size + len(b)) + r = np.concatenate((a, b), axis=None) + rout = np.concatenate((a, b), axis=None, out=out) + assert_(out is rout) + assert_equal(r, rout) + + def test_large_concatenate_axis_None(self): + # When no axis is given, concatenate uses flattened versions. + # This also had a bug with many arrays (see gh-5979). + x = np.arange(1, 100) + r = np.concatenate(x, None) + assert_array_equal(x, r) + + # This should probably be deprecated: + r = np.concatenate(x, 100) # axis is >= MAXDIMS + assert_array_equal(x, r) + + def test_concatenate(self): + # Test concatenate function + # One sequence returns unmodified (but as array) + r4 = list(range(4)) + assert_array_equal(concatenate((r4,)), r4) + # Any sequence + assert_array_equal(concatenate((tuple(r4),)), r4) + assert_array_equal(concatenate((array(r4),)), r4) + # 1D default concatenation + r3 = list(range(3)) + assert_array_equal(concatenate((r4, r3)), r4 + r3) + # Mixed sequence types + assert_array_equal(concatenate((tuple(r4), r3)), r4 + r3) + assert_array_equal(concatenate((array(r4), r3)), r4 + r3) + # Explicit axis specification + assert_array_equal(concatenate((r4, r3), 0), r4 + r3) + # Including negative + assert_array_equal(concatenate((r4, r3), -1), r4 + r3) + # 2D + a23 = array([[10, 11, 12], [13, 14, 15]]) + a13 = array([[0, 1, 2]]) + res = array([[10, 11, 12], [13, 14, 15], [0, 1, 2]]) + assert_array_equal(concatenate((a23, a13)), res) + assert_array_equal(concatenate((a23, a13), 0), res) + assert_array_equal(concatenate((a23.T, a13.T), 1), res.T) + assert_array_equal(concatenate((a23.T, a13.T), -1), res.T) + # Arrays much match shape + assert_raises(ValueError, concatenate, (a23.T, a13.T), 0) + # 3D + res = arange(2 * 3 * 7).reshape((2, 3, 7)) + a0 = res[..., :4] + a1 = res[..., 4:6] + a2 = res[..., 6:] + assert_array_equal(concatenate((a0, a1, a2), 2), res) + assert_array_equal(concatenate((a0, a1, a2), -1), res) + assert_array_equal(concatenate((a0.T, a1.T, a2.T), 0), res.T) + + out = res.copy() + rout = concatenate((a0, a1, a2), 2, out=out) + assert_(out is rout) + assert_equal(res, rout) + + @pytest.mark.skipif(IS_PYPY, reason="PYPY handles sq_concat, nb_add differently than cpython") + def test_operator_concat(self): + import operator + a = array([1, 2]) + b = array([3, 4]) + n = [1,2] + res = array([1, 2, 3, 4]) + assert_raises(TypeError, operator.concat, a, b) + assert_raises(TypeError, operator.concat, a, n) + assert_raises(TypeError, operator.concat, n, a) + assert_raises(TypeError, operator.concat, a, 1) + assert_raises(TypeError, operator.concat, 1, a) + + def test_bad_out_shape(self): + a = array([1, 2]) + b = array([3, 4]) + + assert_raises(ValueError, concatenate, (a, b), out=np.empty(5)) + assert_raises(ValueError, concatenate, (a, b), out=np.empty((4,1))) + assert_raises(ValueError, concatenate, (a, b), out=np.empty((1,4))) + concatenate((a, b), out=np.empty(4)) + + @pytest.mark.parametrize("axis", [None, 0]) + @pytest.mark.parametrize("out_dtype", ["c8", "f4", "f8", ">f8", "i8", "S4"]) + @pytest.mark.parametrize("casting", + ['no', 'equiv', 'safe', 'same_kind', 'unsafe']) + def test_out_and_dtype(self, axis, out_dtype, casting): + # Compare usage of `out=out` with `dtype=out.dtype` + out = np.empty(4, dtype=out_dtype) + to_concat = (array([1.1, 2.2]), array([3.3, 4.4])) + + if not np.can_cast(to_concat[0], out_dtype, casting=casting): + with assert_raises(TypeError): + concatenate(to_concat, out=out, axis=axis, casting=casting) + with assert_raises(TypeError): + concatenate(to_concat, dtype=out.dtype, + axis=axis, casting=casting) + else: + res_out = concatenate(to_concat, out=out, + axis=axis, casting=casting) + res_dtype = concatenate(to_concat, dtype=out.dtype, + axis=axis, casting=casting) + assert res_out is out + assert_array_equal(out, res_dtype) + assert res_dtype.dtype == out_dtype + + with assert_raises(TypeError): + concatenate(to_concat, out=out, dtype=out_dtype, axis=axis) + + @pytest.mark.parametrize("axis", [None, 0]) + @pytest.mark.parametrize("string_dt", ["S", "U", "S0", "U0"]) + @pytest.mark.parametrize("arrs", + [([0.],), ([0.], [1]), ([0], ["string"], [1.])]) + def test_dtype_with_promotion(self, arrs, string_dt, axis): + # Note that U0 and S0 should be deprecated eventually and changed to + # actually give the empty string result (together with `np.array`) + res = np.concatenate(arrs, axis=axis, dtype=string_dt, casting="unsafe") + assert res.dtype == np.promote_types("d", string_dt) + + @pytest.mark.parametrize("axis", [None, 0]) + def test_string_dtype_does_not_inspect(self, axis): + # The error here currently depends on NPY_USE_NEW_CASTINGIMPL as + # the new version rejects using the "default string length" of 64. + # The new behaviour is better, `np.array()` and `arr.astype()` would + # have to be used instead. (currently only raises due to unsafe cast) + with pytest.raises((ValueError, TypeError)): + np.concatenate(([None], [1]), dtype="S", axis=axis) + with pytest.raises((ValueError, TypeError)): + np.concatenate(([None], [1]), dtype="U", axis=axis) + + @pytest.mark.parametrize("axis", [None, 0]) + def test_subarray_error(self, axis): + with pytest.raises(TypeError, match=".*subarray dtype"): + np.concatenate(([1], [1]), dtype="(2,)i", axis=axis) + + +def test_stack(): + # non-iterable input + assert_raises(TypeError, stack, 1) + + # 0d input + for input_ in [(1, 2, 3), + [np.int32(1), np.int32(2), np.int32(3)], + [np.array(1), np.array(2), np.array(3)]]: + assert_array_equal(stack(input_), [1, 2, 3]) + # 1d input examples + a = np.array([1, 2, 3]) + b = np.array([4, 5, 6]) + r1 = array([[1, 2, 3], [4, 5, 6]]) + assert_array_equal(np.stack((a, b)), r1) + assert_array_equal(np.stack((a, b), axis=1), r1.T) + # all input types + assert_array_equal(np.stack(list([a, b])), r1) + assert_array_equal(np.stack(array([a, b])), r1) + # all shapes for 1d input + arrays = [np.random.randn(3) for _ in range(10)] + axes = [0, 1, -1, -2] + expected_shapes = [(10, 3), (3, 10), (3, 10), (10, 3)] + for axis, expected_shape in zip(axes, expected_shapes): + assert_equal(np.stack(arrays, axis).shape, expected_shape) + assert_raises_regex(np.AxisError, 'out of bounds', stack, arrays, axis=2) + assert_raises_regex(np.AxisError, 'out of bounds', stack, arrays, axis=-3) + # all shapes for 2d input + arrays = [np.random.randn(3, 4) for _ in range(10)] + axes = [0, 1, 2, -1, -2, -3] + expected_shapes = [(10, 3, 4), (3, 10, 4), (3, 4, 10), + (3, 4, 10), (3, 10, 4), (10, 3, 4)] + for axis, expected_shape in zip(axes, expected_shapes): + assert_equal(np.stack(arrays, axis).shape, expected_shape) + # empty arrays + assert_(stack([[], [], []]).shape == (3, 0)) + assert_(stack([[], [], []], axis=1).shape == (0, 3)) + # out + out = np.zeros_like(r1) + np.stack((a, b), out=out) + assert_array_equal(out, r1) + # edge cases + assert_raises_regex(ValueError, 'need at least one array', stack, []) + assert_raises_regex(ValueError, 'must have the same shape', + stack, [1, np.arange(3)]) + assert_raises_regex(ValueError, 'must have the same shape', + stack, [np.arange(3), 1]) + assert_raises_regex(ValueError, 'must have the same shape', + stack, [np.arange(3), 1], axis=1) + assert_raises_regex(ValueError, 'must have the same shape', + stack, [np.zeros((3, 3)), np.zeros(3)], axis=1) + assert_raises_regex(ValueError, 'must have the same shape', + stack, [np.arange(2), np.arange(3)]) + # generator is deprecated + with assert_warns(FutureWarning): + result = stack((x for x in range(3))) + assert_array_equal(result, np.array([0, 1, 2])) + + +class TestBlock: + @pytest.fixture(params=['block', 'force_concatenate', 'force_slicing']) + def block(self, request): + # blocking small arrays and large arrays go through different paths. + # the algorithm is triggered depending on the number of element + # copies required. + # We define a test fixture that forces most tests to go through + # both code paths. + # Ultimately, this should be removed if a single algorithm is found + # to be faster for both small and large arrays. + def _block_force_concatenate(arrays): + arrays, list_ndim, result_ndim, _ = _block_setup(arrays) + return _block_concatenate(arrays, list_ndim, result_ndim) + + def _block_force_slicing(arrays): + arrays, list_ndim, result_ndim, _ = _block_setup(arrays) + return _block_slicing(arrays, list_ndim, result_ndim) + + if request.param == 'force_concatenate': + return _block_force_concatenate + elif request.param == 'force_slicing': + return _block_force_slicing + elif request.param == 'block': + return block + else: + raise ValueError('Unknown blocking request. There is a typo in the tests.') + + def test_returns_copy(self, block): + a = np.eye(3) + b = block(a) + b[0, 0] = 2 + assert b[0, 0] != a[0, 0] + + def test_block_total_size_estimate(self, block): + _, _, _, total_size = _block_setup([1]) + assert total_size == 1 + + _, _, _, total_size = _block_setup([[1]]) + assert total_size == 1 + + _, _, _, total_size = _block_setup([[1, 1]]) + assert total_size == 2 + + _, _, _, total_size = _block_setup([[1], [1]]) + assert total_size == 2 + + _, _, _, total_size = _block_setup([[1, 2], [3, 4]]) + assert total_size == 4 + + def test_block_simple_row_wise(self, block): + a_2d = np.ones((2, 2)) + b_2d = 2 * a_2d + desired = np.array([[1, 1, 2, 2], + [1, 1, 2, 2]]) + result = block([a_2d, b_2d]) + assert_equal(desired, result) + + def test_block_simple_column_wise(self, block): + a_2d = np.ones((2, 2)) + b_2d = 2 * a_2d + expected = np.array([[1, 1], + [1, 1], + [2, 2], + [2, 2]]) + result = block([[a_2d], [b_2d]]) + assert_equal(expected, result) + + def test_block_with_1d_arrays_row_wise(self, block): + # # # 1-D vectors are treated as row arrays + a = np.array([1, 2, 3]) + b = np.array([2, 3, 4]) + expected = np.array([1, 2, 3, 2, 3, 4]) + result = block([a, b]) + assert_equal(expected, result) + + def test_block_with_1d_arrays_multiple_rows(self, block): + a = np.array([1, 2, 3]) + b = np.array([2, 3, 4]) + expected = np.array([[1, 2, 3, 2, 3, 4], + [1, 2, 3, 2, 3, 4]]) + result = block([[a, b], [a, b]]) + assert_equal(expected, result) + + def test_block_with_1d_arrays_column_wise(self, block): + # # # 1-D vectors are treated as row arrays + a_1d = np.array([1, 2, 3]) + b_1d = np.array([2, 3, 4]) + expected = np.array([[1, 2, 3], + [2, 3, 4]]) + result = block([[a_1d], [b_1d]]) + assert_equal(expected, result) + + def test_block_mixed_1d_and_2d(self, block): + a_2d = np.ones((2, 2)) + b_1d = np.array([2, 2]) + result = block([[a_2d], [b_1d]]) + expected = np.array([[1, 1], + [1, 1], + [2, 2]]) + assert_equal(expected, result) + + def test_block_complicated(self, block): + # a bit more complicated + one_2d = np.array([[1, 1, 1]]) + two_2d = np.array([[2, 2, 2]]) + three_2d = np.array([[3, 3, 3, 3, 3, 3]]) + four_1d = np.array([4, 4, 4, 4, 4, 4]) + five_0d = np.array(5) + six_1d = np.array([6, 6, 6, 6, 6]) + zero_2d = np.zeros((2, 6)) + + expected = np.array([[1, 1, 1, 2, 2, 2], + [3, 3, 3, 3, 3, 3], + [4, 4, 4, 4, 4, 4], + [5, 6, 6, 6, 6, 6], + [0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0]]) + + result = block([[one_2d, two_2d], + [three_2d], + [four_1d], + [five_0d, six_1d], + [zero_2d]]) + assert_equal(result, expected) + + def test_nested(self, block): + one = np.array([1, 1, 1]) + two = np.array([[2, 2, 2], [2, 2, 2], [2, 2, 2]]) + three = np.array([3, 3, 3]) + four = np.array([4, 4, 4]) + five = np.array(5) + six = np.array([6, 6, 6, 6, 6]) + zero = np.zeros((2, 6)) + + result = block([ + [ + block([ + [one], + [three], + [four] + ]), + two + ], + [five, six], + [zero] + ]) + expected = np.array([[1, 1, 1, 2, 2, 2], + [3, 3, 3, 2, 2, 2], + [4, 4, 4, 2, 2, 2], + [5, 6, 6, 6, 6, 6], + [0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0]]) + + assert_equal(result, expected) + + def test_3d(self, block): + a000 = np.ones((2, 2, 2), int) * 1 + + a100 = np.ones((3, 2, 2), int) * 2 + a010 = np.ones((2, 3, 2), int) * 3 + a001 = np.ones((2, 2, 3), int) * 4 + + a011 = np.ones((2, 3, 3), int) * 5 + a101 = np.ones((3, 2, 3), int) * 6 + a110 = np.ones((3, 3, 2), int) * 7 + + a111 = np.ones((3, 3, 3), int) * 8 + + result = block([ + [ + [a000, a001], + [a010, a011], + ], + [ + [a100, a101], + [a110, a111], + ] + ]) + expected = array([[[1, 1, 4, 4, 4], + [1, 1, 4, 4, 4], + [3, 3, 5, 5, 5], + [3, 3, 5, 5, 5], + [3, 3, 5, 5, 5]], + + [[1, 1, 4, 4, 4], + [1, 1, 4, 4, 4], + [3, 3, 5, 5, 5], + [3, 3, 5, 5, 5], + [3, 3, 5, 5, 5]], + + [[2, 2, 6, 6, 6], + [2, 2, 6, 6, 6], + [7, 7, 8, 8, 8], + [7, 7, 8, 8, 8], + [7, 7, 8, 8, 8]], + + [[2, 2, 6, 6, 6], + [2, 2, 6, 6, 6], + [7, 7, 8, 8, 8], + [7, 7, 8, 8, 8], + [7, 7, 8, 8, 8]], + + [[2, 2, 6, 6, 6], + [2, 2, 6, 6, 6], + [7, 7, 8, 8, 8], + [7, 7, 8, 8, 8], + [7, 7, 8, 8, 8]]]) + + assert_array_equal(result, expected) + + def test_block_with_mismatched_shape(self, block): + a = np.array([0, 0]) + b = np.eye(2) + assert_raises(ValueError, block, [a, b]) + assert_raises(ValueError, block, [b, a]) + + to_block = [[np.ones((2,3)), np.ones((2,2))], + [np.ones((2,2)), np.ones((2,2))]] + assert_raises(ValueError, block, to_block) + def test_no_lists(self, block): + assert_equal(block(1), np.array(1)) + assert_equal(block(np.eye(3)), np.eye(3)) + + def test_invalid_nesting(self, block): + msg = 'depths are mismatched' + assert_raises_regex(ValueError, msg, block, [1, [2]]) + assert_raises_regex(ValueError, msg, block, [1, []]) + assert_raises_regex(ValueError, msg, block, [[1], 2]) + assert_raises_regex(ValueError, msg, block, [[], 2]) + assert_raises_regex(ValueError, msg, block, [ + [[1], [2]], + [[3, 4]], + [5] # missing brackets + ]) + + def test_empty_lists(self, block): + assert_raises_regex(ValueError, 'empty', block, []) + assert_raises_regex(ValueError, 'empty', block, [[]]) + assert_raises_regex(ValueError, 'empty', block, [[1], []]) + + def test_tuple(self, block): + assert_raises_regex(TypeError, 'tuple', block, ([1, 2], [3, 4])) + assert_raises_regex(TypeError, 'tuple', block, [(1, 2), (3, 4)]) + + def test_different_ndims(self, block): + a = 1. + b = 2 * np.ones((1, 2)) + c = 3 * np.ones((1, 1, 3)) + + result = block([a, b, c]) + expected = np.array([[[1., 2., 2., 3., 3., 3.]]]) + + assert_equal(result, expected) + + def test_different_ndims_depths(self, block): + a = 1. + b = 2 * np.ones((1, 2)) + c = 3 * np.ones((1, 2, 3)) + + result = block([[a, b], [c]]) + expected = np.array([[[1., 2., 2.], + [3., 3., 3.], + [3., 3., 3.]]]) + + assert_equal(result, expected) + + def test_block_memory_order(self, block): + # 3D + arr_c = np.zeros((3,)*3, order='C') + arr_f = np.zeros((3,)*3, order='F') + + b_c = [[[arr_c, arr_c], + [arr_c, arr_c]], + [[arr_c, arr_c], + [arr_c, arr_c]]] + + b_f = [[[arr_f, arr_f], + [arr_f, arr_f]], + [[arr_f, arr_f], + [arr_f, arr_f]]] + + assert block(b_c).flags['C_CONTIGUOUS'] + assert block(b_f).flags['F_CONTIGUOUS'] + + arr_c = np.zeros((3, 3), order='C') + arr_f = np.zeros((3, 3), order='F') + # 2D + b_c = [[arr_c, arr_c], + [arr_c, arr_c]] + + b_f = [[arr_f, arr_f], + [arr_f, arr_f]] + + assert block(b_c).flags['C_CONTIGUOUS'] + assert block(b_f).flags['F_CONTIGUOUS'] + + +def test_block_dispatcher(): + class ArrayLike: + pass + a = ArrayLike() + b = ArrayLike() + c = ArrayLike() + assert_equal(list(_block_dispatcher(a)), [a]) + assert_equal(list(_block_dispatcher([a])), [a]) + assert_equal(list(_block_dispatcher([a, b])), [a, b]) + assert_equal(list(_block_dispatcher([[a], [b, [c]]])), [a, b, c]) + # don't recurse into non-lists + assert_equal(list(_block_dispatcher((a, b))), [(a, b)]) diff --git a/venv/Lib/site-packages/numpy/core/tests/test_simd.py b/venv/Lib/site-packages/numpy/core/tests/test_simd.py new file mode 100644 index 0000000..897ad14 --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/tests/test_simd.py @@ -0,0 +1,638 @@ +# NOTE: Please avoid the use of numpy.testing since NPYV intrinsics +# may be involved in their functionality. +import pytest, math +from numpy.core._simd import targets + +class _Test_Utility: + # submodule of the desired SIMD extention, e.g. targets["AVX512F"] + npyv = None + # the current data type suffix e.g. 's8' + sfx = None + + def __getattr__(self, attr): + """ + To call NPV intrinsics without the attribute 'npyv' and + auto suffixing intrinsics according to class attribute 'sfx' + """ + return getattr(self.npyv, attr + "_" + self.sfx) + + def _data(self, start=None, count=None, reverse=False): + """ + Create list of consecutive numbers according to number of vector's lanes. + """ + if start is None: + start = 1 + if count is None: + count = self.nlanes + rng = range(start, start + count) + if reverse: + rng = reversed(rng) + if self._is_fp(): + return [x / 1.0 for x in rng] + return list(rng) + + def _is_unsigned(self): + return self.sfx[0] == 'u' + + def _is_signed(self): + return self.sfx[0] == 's' + + def _is_fp(self): + return self.sfx[0] == 'f' + + def _scalar_size(self): + return int(self.sfx[1:]) + + def _int_clip(self, seq): + if self._is_fp(): + return seq + max_int = self._int_max() + min_int = self._int_min() + return [min(max(v, min_int), max_int) for v in seq] + + def _int_max(self): + if self._is_fp(): + return None + max_u = self._to_unsigned(self.setall(-1))[0] + if self._is_signed(): + return max_u // 2 + return max_u + + def _int_min(self): + if self._is_fp(): + return None + if self._is_unsigned(): + return 0 + return -(self._int_max() + 1) + + def _true_mask(self): + max_unsig = getattr(self.npyv, "setall_u" + self.sfx[1:])(-1) + return max_unsig[0] + + def _to_unsigned(self, vector): + if isinstance(vector, (list, tuple)): + return getattr(self.npyv, "load_u" + self.sfx[1:])(vector) + else: + sfx = vector.__name__.replace("npyv_", "") + if sfx[0] == "b": + cvt_intrin = "cvt_u{0}_b{0}" + else: + cvt_intrin = "reinterpret_u{0}_{1}" + return getattr(self.npyv, cvt_intrin.format(sfx[1:], sfx))(vector) + + def _pinfinity(self): + v = self.npyv.setall_u32(0x7f800000) + return self.npyv.reinterpret_f32_u32(v)[0] + + def _ninfinity(self): + v = self.npyv.setall_u32(0xff800000) + return self.npyv.reinterpret_f32_u32(v)[0] + + def _nan(self): + v = self.npyv.setall_u32(0x7fc00000) + return self.npyv.reinterpret_f32_u32(v)[0] + +class _SIMD_INT(_Test_Utility): + """ + To test all integer vector types at once + """ + def test_operators_shift(self): + if self.sfx in ("u8", "s8"): + return + + data_a = self._data(self._int_max() - self.nlanes) + data_b = self._data(self._int_min(), reverse=True) + vdata_a, vdata_b = self.load(data_a), self.load(data_b) + + for count in range(self._scalar_size()): + # load to cast + data_shl_a = self.load([a << count for a in data_a]) + # left shift + shl = self.shl(vdata_a, count) + assert shl == data_shl_a + # load to cast + data_shr_a = self.load([a >> count for a in data_a]) + # right shift + shr = self.shr(vdata_a, count) + assert shr == data_shr_a + + # shift by zero or max or out-range immediate constant is not applicable and illogical + for count in range(1, self._scalar_size()): + # load to cast + data_shl_a = self.load([a << count for a in data_a]) + # left shift by an immediate constant + shli = self.shli(vdata_a, count) + assert shli == data_shl_a + # load to cast + data_shr_a = self.load([a >> count for a in data_a]) + # right shift by an immediate constant + shri = self.shri(vdata_a, count) + assert shri == data_shr_a + + def test_arithmetic_subadd_saturated(self): + if self.sfx in ("u32", "s32", "u64", "s64"): + return + + data_a = self._data(self._int_max() - self.nlanes) + data_b = self._data(self._int_min(), reverse=True) + vdata_a, vdata_b = self.load(data_a), self.load(data_b) + + data_adds = self._int_clip([a + b for a, b in zip(data_a, data_b)]) + adds = self.adds(vdata_a, vdata_b) + assert adds == data_adds + + data_subs = self._int_clip([a - b for a, b in zip(data_a, data_b)]) + subs = self.subs(vdata_a, vdata_b) + assert subs == data_subs + +class _SIMD_FP(_Test_Utility): + """ + To test all float vector types at once + """ + def test_arithmetic_fused(self): + vdata_a, vdata_b, vdata_c = [self.load(self._data())]*3 + vdata_cx2 = self.add(vdata_c, vdata_c) + # multiply and add, a*b + c + data_fma = self.load([a * b + c for a, b, c in zip(vdata_a, vdata_b, vdata_c)]) + fma = self.muladd(vdata_a, vdata_b, vdata_c) + assert fma == data_fma + # multiply and subtract, a*b - c + fms = self.mulsub(vdata_a, vdata_b, vdata_c) + data_fms = self.sub(data_fma, vdata_cx2) + assert fms == data_fms + # negate multiply and add, -(a*b) + c + nfma = self.nmuladd(vdata_a, vdata_b, vdata_c) + data_nfma = self.sub(vdata_cx2, data_fma) + assert nfma == data_nfma + # negate multiply and subtract, -(a*b) - c + nfms = self.nmulsub(vdata_a, vdata_b, vdata_c) + data_nfms = self.mul(data_fma, self.setall(-1)) + assert nfms == data_nfms + + def test_abs(self): + pinf, ninf, nan = self._pinfinity(), self._ninfinity(), self._nan() + data = self._data() + vdata = self.load(self._data()) + + abs_cases = ((-0, 0), (ninf, pinf), (pinf, pinf), (nan, nan)) + for case, desired in abs_cases: + data_abs = [desired]*self.nlanes + vabs = self.abs(self.setall(case)) + assert vabs == pytest.approx(data_abs, nan_ok=True) + + vabs = self.abs(self.mul(vdata, self.setall(-1))) + assert vabs == data + + def test_sqrt(self): + pinf, ninf, nan = self._pinfinity(), self._ninfinity(), self._nan() + data = self._data() + vdata = self.load(self._data()) + + sqrt_cases = ((-0.0, -0.0), (0.0, 0.0), (-1.0, nan), (ninf, nan), (pinf, pinf)) + for case, desired in sqrt_cases: + data_sqrt = [desired]*self.nlanes + sqrt = self.sqrt(self.setall(case)) + assert sqrt == pytest.approx(data_sqrt, nan_ok=True) + + data_sqrt = self.load([math.sqrt(x) for x in data]) # load to truncate precision + sqrt = self.sqrt(vdata) + assert sqrt == data_sqrt + + def test_square(self): + pinf, ninf, nan = self._pinfinity(), self._ninfinity(), self._nan() + data = self._data() + vdata = self.load(self._data()) + # square + square_cases = ((nan, nan), (pinf, pinf), (ninf, pinf)) + for case, desired in square_cases: + data_square = [desired]*self.nlanes + square = self.square(self.setall(case)) + assert square == pytest.approx(data_square, nan_ok=True) + + data_square = [x*x for x in data] + square = self.square(vdata) + assert square == data_square + + def test_reciprocal(self): + pinf, ninf, nan = self._pinfinity(), self._ninfinity(), self._nan() + data = self._data() + vdata = self.load(self._data()) + + recip_cases = ((nan, nan), (pinf, 0.0), (ninf, -0.0), (0.0, pinf), (-0.0, ninf)) + for case, desired in recip_cases: + data_recip = [desired]*self.nlanes + recip = self.recip(self.setall(case)) + assert recip == pytest.approx(data_recip, nan_ok=True) + + data_recip = self.load([1/x for x in data]) # load to truncate precision + recip = self.recip(vdata) + assert recip == data_recip + +class _SIMD_ALL(_Test_Utility): + """ + To test all vector types at once + """ + def test_memory_load(self): + data = self._data() + # unaligned load + load_data = self.load(data) + assert load_data == data + # aligned load + loada_data = self.loada(data) + assert loada_data == data + # stream load + loads_data = self.loads(data) + assert loads_data == data + # load lower part + loadl = self.loadl(data) + loadl_half = list(loadl)[:self.nlanes//2] + data_half = data[:self.nlanes//2] + assert loadl_half == data_half + assert loadl != data # detect overflow + + def test_memory_store(self): + data = self._data() + vdata = self.load(data) + # unaligned store + store = [0] * self.nlanes + self.store(store, vdata) + assert store == data + # aligned store + store_a = [0] * self.nlanes + self.storea(store_a, vdata) + assert store_a == data + # stream store + store_s = [0] * self.nlanes + self.stores(store_s, vdata) + assert store_s == data + # store lower part + store_l = [0] * self.nlanes + self.storel(store_l, vdata) + assert store_l[:self.nlanes//2] == data[:self.nlanes//2] + assert store_l != vdata # detect overflow + # store higher part + store_h = [0] * self.nlanes + self.storeh(store_h, vdata) + assert store_h[:self.nlanes//2] == data[self.nlanes//2:] + assert store_h != vdata # detect overflow + + def test_memory_partial_load(self): + if self.sfx in ("u8", "s8", "u16", "s16"): + return + + data = self._data() + lanes = list(range(1, self.nlanes + 1)) + lanes += [self.nlanes**2, self.nlanes**4] # test out of range + for n in lanes: + load_till = self.load_till(data, n, 15) + data_till = data[:n] + [15] * (self.nlanes-n) + assert load_till == data_till + load_tillz = self.load_tillz(data, n) + data_tillz = data[:n] + [0] * (self.nlanes-n) + assert load_tillz == data_tillz + + def test_memory_partial_store(self): + if self.sfx in ("u8", "s8", "u16", "s16"): + return + + data = self._data() + data_rev = self._data(reverse=True) + vdata = self.load(data) + lanes = list(range(1, self.nlanes + 1)) + lanes += [self.nlanes**2, self.nlanes**4] + for n in lanes: + data_till = data_rev.copy() + data_till[:n] = data[:n] + store_till = self._data(reverse=True) + self.store_till(store_till, n, vdata) + assert store_till == data_till + + def test_memory_noncont_load(self): + if self.sfx in ("u8", "s8", "u16", "s16"): + return + + for stride in range(1, 64): + data = self._data(count=stride*self.nlanes) + data_stride = data[::stride] + loadn = self.loadn(data, stride) + assert loadn == data_stride + + for stride in range(-64, 0): + data = self._data(stride, -stride*self.nlanes) + data_stride = self.load(data[::stride]) # cast unsigned + loadn = self.loadn(data, stride) + assert loadn == data_stride + + def test_memory_noncont_partial_load(self): + if self.sfx in ("u8", "s8", "u16", "s16"): + return + + lanes = list(range(1, self.nlanes + 1)) + lanes += [self.nlanes**2, self.nlanes**4] + for stride in range(1, 64): + data = self._data(count=stride*self.nlanes) + data_stride = data[::stride] + for n in lanes: + data_stride_till = data_stride[:n] + [15] * (self.nlanes-n) + loadn_till = self.loadn_till(data, stride, n, 15) + assert loadn_till == data_stride_till + data_stride_tillz = data_stride[:n] + [0] * (self.nlanes-n) + loadn_tillz = self.loadn_tillz(data, stride, n) + assert loadn_tillz == data_stride_tillz + + for stride in range(-64, 0): + data = self._data(stride, -stride*self.nlanes) + data_stride = list(self.load(data[::stride])) # cast unsigned + for n in lanes: + data_stride_till = data_stride[:n] + [15] * (self.nlanes-n) + loadn_till = self.loadn_till(data, stride, n, 15) + assert loadn_till == data_stride_till + data_stride_tillz = data_stride[:n] + [0] * (self.nlanes-n) + loadn_tillz = self.loadn_tillz(data, stride, n) + assert loadn_tillz == data_stride_tillz + + def test_memory_noncont_store(self): + if self.sfx in ("u8", "s8", "u16", "s16"): + return + + vdata = self.load(self._data()) + for stride in range(1, 64): + data = [15] * stride * self.nlanes + data[::stride] = vdata + storen = [15] * stride * self.nlanes + storen += [127]*64 + self.storen(storen, stride, vdata) + assert storen[:-64] == data + assert storen[-64:] == [127]*64 # detect overflow + + for stride in range(-64, 0): + data = [15] * -stride * self.nlanes + data[::stride] = vdata + storen = [127]*64 + storen += [15] * -stride * self.nlanes + self.storen(storen, stride, vdata) + assert storen[64:] == data + assert storen[:64] == [127]*64 # detect overflow + + def test_memory_noncont_partial_store(self): + if self.sfx in ("u8", "s8", "u16", "s16"): + return + + data = self._data() + vdata = self.load(data) + lanes = list(range(1, self.nlanes + 1)) + lanes += [self.nlanes**2, self.nlanes**4] + for stride in range(1, 64): + for n in lanes: + data_till = [15] * stride * self.nlanes + data_till[::stride] = data[:n] + [15] * (self.nlanes-n) + storen_till = [15] * stride * self.nlanes + storen_till += [127]*64 + self.storen_till(storen_till, stride, n, vdata) + assert storen_till[:-64] == data_till + assert storen_till[-64:] == [127]*64 # detect overflow + + for stride in range(-64, 0): + for n in lanes: + data_till = [15] * -stride * self.nlanes + data_till[::stride] = data[:n] + [15] * (self.nlanes-n) + storen_till = [127]*64 + storen_till += [15] * -stride * self.nlanes + self.storen_till(storen_till, stride, n, vdata) + assert storen_till[64:] == data_till + assert storen_till[:64] == [127]*64 # detect overflow + + def test_misc(self): + broadcast_zero = self.zero() + assert broadcast_zero == [0] * self.nlanes + for i in range(1, 10): + broadcasti = self.setall(i) + assert broadcasti == [i] * self.nlanes + + data_a, data_b = self._data(), self._data(reverse=True) + vdata_a, vdata_b = self.load(data_a), self.load(data_b) + + # py level of npyv_set_* don't support ignoring the extra specified lanes or + # fill non-specified lanes with zero. + vset = self.set(*data_a) + assert vset == data_a + # py level of npyv_setf_* don't support ignoring the extra specified lanes or + # fill non-specified lanes with the specified scalar. + vsetf = self.setf(10, *data_a) + assert vsetf == data_a + + # We're testing the sainty of _simd's type-vector, + # reinterpret* intrinsics itself are tested via compiler + # during the build of _simd module + sfxes = ["u8", "s8", "u16", "s16", "u32", "s32", "u64", "s64", "f32"] + if self.npyv.simd_f64: + sfxes.append("f64") + for sfx in sfxes: + vec_name = getattr(self, "reinterpret_" + sfx)(vdata_a).__name__ + assert vec_name == "npyv_" + sfx + + # select & mask operations + select_a = self.select(self.cmpeq(self.zero(), self.zero()), vdata_a, vdata_b) + assert select_a == data_a + select_b = self.select(self.cmpneq(self.zero(), self.zero()), vdata_a, vdata_b) + assert select_b == data_b + + # cleanup intrinsic is only used with AVX for + # zeroing registers to avoid the AVX-SSE transition penalty, + # so nothing to test here + self.npyv.cleanup() + + def test_reorder(self): + data_a, data_b = self._data(), self._data(reverse=True) + vdata_a, vdata_b = self.load(data_a), self.load(data_b) + # lower half part + data_a_lo = data_a[:self.nlanes//2] + data_b_lo = data_b[:self.nlanes//2] + # higher half part + data_a_hi = data_a[self.nlanes//2:] + data_b_hi = data_b[self.nlanes//2:] + # combine two lower parts + combinel = self.combinel(vdata_a, vdata_b) + assert combinel == data_a_lo + data_b_lo + # combine two higher parts + combineh = self.combineh(vdata_a, vdata_b) + assert combineh == data_a_hi + data_b_hi + # combine x2 + combine = self.combine(vdata_a, vdata_b) + assert combine == (data_a_lo + data_b_lo, data_a_hi + data_b_hi) + # zip(interleave) + data_zipl = [v for p in zip(data_a_lo, data_b_lo) for v in p] + data_ziph = [v for p in zip(data_a_hi, data_b_hi) for v in p] + vzip = self.zip(vdata_a, vdata_b) + assert vzip == (data_zipl, data_ziph) + + def test_operators_comparison(self): + if self._is_fp(): + data_a = self._data() + else: + data_a = self._data(self._int_max() - self.nlanes) + data_b = self._data(self._int_min(), reverse=True) + vdata_a, vdata_b = self.load(data_a), self.load(data_b) + + mask_true = self._true_mask() + def to_bool(vector): + return [lane == mask_true for lane in vector] + # equal + data_eq = [a == b for a, b in zip(data_a, data_b)] + cmpeq = to_bool(self.cmpeq(vdata_a, vdata_b)) + assert cmpeq == data_eq + # not equal + data_neq = [a != b for a, b in zip(data_a, data_b)] + cmpneq = to_bool(self.cmpneq(vdata_a, vdata_b)) + assert cmpneq == data_neq + # greater than + data_gt = [a > b for a, b in zip(data_a, data_b)] + cmpgt = to_bool(self.cmpgt(vdata_a, vdata_b)) + assert cmpgt == data_gt + # greater than and equal + data_ge = [a >= b for a, b in zip(data_a, data_b)] + cmpge = to_bool(self.cmpge(vdata_a, vdata_b)) + assert cmpge == data_ge + # less than + data_lt = [a < b for a, b in zip(data_a, data_b)] + cmplt = to_bool(self.cmplt(vdata_a, vdata_b)) + assert cmplt == data_lt + # less than and equal + data_le = [a <= b for a, b in zip(data_a, data_b)] + cmple = to_bool(self.cmple(vdata_a, vdata_b)) + assert cmple == data_le + + def test_operators_logical(self): + if self._is_fp(): + data_a = self._data() + else: + data_a = self._data(self._int_max() - self.nlanes) + data_b = self._data(self._int_min(), reverse=True) + vdata_a, vdata_b = self.load(data_a), self.load(data_b) + + if self._is_fp(): + data_cast_a = self._to_unsigned(vdata_a) + data_cast_b = self._to_unsigned(vdata_b) + cast, cast_data = self._to_unsigned, self._to_unsigned + else: + data_cast_a, data_cast_b = data_a, data_b + cast, cast_data = lambda a: a, self.load + + data_xor = cast_data([a ^ b for a, b in zip(data_cast_a, data_cast_b)]) + vxor = cast(self.xor(vdata_a, vdata_b)) + assert vxor == data_xor + + data_or = cast_data([a | b for a, b in zip(data_cast_a, data_cast_b)]) + vor = cast(getattr(self, "or")(vdata_a, vdata_b)) + assert vor == data_or + + data_and = cast_data([a & b for a, b in zip(data_cast_a, data_cast_b)]) + vand = cast(getattr(self, "and")(vdata_a, vdata_b)) + assert vand == data_and + + data_not = cast_data([~a for a in data_cast_a]) + vnot = cast(getattr(self, "not")(vdata_a)) + assert vnot == data_not + + def test_conversion_boolean(self): + bsfx = "b" + self.sfx[1:] + to_boolean = getattr(self.npyv, "cvt_%s_%s" % (bsfx, self.sfx)) + from_boolean = getattr(self.npyv, "cvt_%s_%s" % (self.sfx, bsfx)) + + false_vb = to_boolean(self.setall(0)) + true_vb = self.cmpeq(self.setall(0), self.setall(0)) + assert false_vb != true_vb + + false_vsfx = from_boolean(false_vb) + true_vsfx = from_boolean(true_vb) + assert false_vsfx != true_vsfx + + def test_arithmetic_subadd(self): + if self._is_fp(): + data_a = self._data() + else: + data_a = self._data(self._int_max() - self.nlanes) + data_b = self._data(self._int_min(), reverse=True) + vdata_a, vdata_b = self.load(data_a), self.load(data_b) + + # non-saturated + data_add = self.load([a + b for a, b in zip(data_a, data_b)]) # load to cast + add = self.add(vdata_a, vdata_b) + assert add == data_add + data_sub = self.load([a - b for a, b in zip(data_a, data_b)]) + sub = self.sub(vdata_a, vdata_b) + assert sub == data_sub + + def test_arithmetic_mul(self): + if self.sfx in ("u64", "s64"): + return + + if self._is_fp(): + data_a = self._data() + else: + data_a = self._data(self._int_max() - self.nlanes) + data_b = self._data(self._int_min(), reverse=True) + vdata_a, vdata_b = self.load(data_a), self.load(data_b) + + data_mul = self.load([a * b for a, b in zip(data_a, data_b)]) + mul = self.mul(vdata_a, vdata_b) + assert mul == data_mul + + def test_arithmetic_div(self): + if not self._is_fp(): + return + + data_a, data_b = self._data(), self._data(reverse=True) + vdata_a, vdata_b = self.load(data_a), self.load(data_b) + + # load to truncate f64 to precision of f32 + data_div = self.load([a / b for a, b in zip(data_a, data_b)]) + div = self.div(vdata_a, vdata_b) + assert div == data_div + + def test_arithmetic_reduce_sum(self): + if not self._is_fp(): + return + # reduce sum + data = self._data() + vdata = self.load(data) + + data_sum = sum(data) + vsum = self.sum(vdata) + assert vsum == data_sum + +int_sfx = ("u8", "s8", "u16", "s16", "u32", "s32", "u64", "s64") +fp_sfx = ("f32", "f64") +all_sfx = int_sfx + fp_sfx +tests_registry = { + int_sfx : _SIMD_INT, + fp_sfx : _SIMD_FP, + all_sfx : _SIMD_ALL +} +for target_name, npyv in targets.items(): + simd_width = npyv.simd if npyv else '' + pretty_name = target_name.split('__') # multi-target separator + if len(pretty_name) > 1: + # multi-target + pretty_name = f"({' '.join(pretty_name)})" + else: + pretty_name = pretty_name[0] + + skip = "" + skip_sfx = dict() + if not npyv: + skip = f"target '{pretty_name}' isn't supported by current machine" + elif not npyv.simd: + skip = f"target '{pretty_name}' isn't supported by NPYV" + elif not npyv.simd_f64: + skip_sfx["f64"] = f"target '{pretty_name}' doesn't support double-precision" + + for sfxes, cls in tests_registry.items(): + for sfx in sfxes: + skip_m = skip_sfx.get(sfx, skip) + inhr = (cls,) + attr = dict(npyv=targets[target_name], sfx=sfx) + tcls = type(f"Test{cls.__name__}_{simd_width}_{target_name}_{sfx}", inhr, attr) + if skip_m: + pytest.mark.skip(reason=skip_m)(tcls) + globals()[tcls.__name__] = tcls diff --git a/venv/Lib/site-packages/numpy/core/tests/test_simd_module.py b/venv/Lib/site-packages/numpy/core/tests/test_simd_module.py new file mode 100644 index 0000000..3d71088 --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/tests/test_simd_module.py @@ -0,0 +1,97 @@ +import pytest +from numpy.core._simd import targets +""" +This testing unit only for checking the sanity of common functionality, +therefore all we need is just to take one submodule that represents any +of enabled SIMD extensions to run the test on it and the second submodule +required to run only one check related to the possibility of mixing +the data types among each submodule. +""" +npyvs = [npyv_mod for npyv_mod in targets.values() if npyv_mod and npyv_mod.simd] +npyv, npyv2 = (npyvs + [None, None])[:2] + +unsigned_sfx = ["u8", "u16", "u32", "u64"] +signed_sfx = ["s8", "s16", "s32", "s64"] +fp_sfx = ["f32"] +if npyv and npyv.simd_f64: + fp_sfx.append("f64") + +int_sfx = unsigned_sfx + signed_sfx +all_sfx = unsigned_sfx + int_sfx + +@pytest.mark.skipif(not npyv, reason="could not find any SIMD extension with NPYV support") +class Test_SIMD_MODULE: + + @pytest.mark.parametrize('sfx', all_sfx) + def test_num_lanes(self, sfx): + nlanes = getattr(npyv, "nlanes_" + sfx) + vector = getattr(npyv, "setall_" + sfx)(1) + assert len(vector) == nlanes + + @pytest.mark.parametrize('sfx', all_sfx) + def test_type_name(self, sfx): + vector = getattr(npyv, "setall_" + sfx)(1) + assert vector.__name__ == "npyv_" + sfx + + def test_raises(self): + a, b = [npyv.setall_u32(1)]*2 + for sfx in all_sfx: + vcb = lambda intrin: getattr(npyv, f"{intrin}_{sfx}") + pytest.raises(TypeError, vcb("add"), a) + pytest.raises(TypeError, vcb("add"), a, b, a) + pytest.raises(TypeError, vcb("setall")) + pytest.raises(TypeError, vcb("setall"), [1]) + pytest.raises(TypeError, vcb("load"), 1) + pytest.raises(ValueError, vcb("load"), [1]) + pytest.raises(ValueError, vcb("store"), [1], getattr(npyv, f"reinterpret_{sfx}_u32")(a)) + + @pytest.mark.skipif(not npyv2, reason=( + "could not find a second SIMD extension with NPYV support" + )) + def test_nomix(self): + # mix among submodules isn't allowed + a = npyv.setall_u32(1) + a2 = npyv2.setall_u32(1) + pytest.raises(TypeError, npyv.add_u32, a2, a2) + pytest.raises(TypeError, npyv2.add_u32, a, a) + + @pytest.mark.parametrize('sfx', unsigned_sfx) + def test_unsigned_overflow(self, sfx): + nlanes = getattr(npyv, "nlanes_" + sfx) + maxu = (1 << int(sfx[1:])) - 1 + maxu_72 = (1 << 72) - 1 + lane = getattr(npyv, "setall_" + sfx)(maxu_72)[0] + assert lane == maxu + lanes = getattr(npyv, "load_" + sfx)([maxu_72] * nlanes) + assert lanes == [maxu] * nlanes + lane = getattr(npyv, "setall_" + sfx)(-1)[0] + assert lane == maxu + lanes = getattr(npyv, "load_" + sfx)([-1] * nlanes) + assert lanes == [maxu] * nlanes + + @pytest.mark.parametrize('sfx', signed_sfx) + def test_signed_overflow(self, sfx): + nlanes = getattr(npyv, "nlanes_" + sfx) + maxs_72 = (1 << 71) - 1 + lane = getattr(npyv, "setall_" + sfx)(maxs_72)[0] + assert lane == -1 + lanes = getattr(npyv, "load_" + sfx)([maxs_72] * nlanes) + assert lanes == [-1] * nlanes + mins_72 = -1 << 71 + lane = getattr(npyv, "setall_" + sfx)(mins_72)[0] + assert lane == 0 + lanes = getattr(npyv, "load_" + sfx)([mins_72] * nlanes) + assert lanes == [0] * nlanes + + def test_truncate_f32(self): + f32 = npyv.setall_f32(0.1)[0] + assert f32 != 0.1 + assert round(f32, 1) == 0.1 + + def test_compare(self): + data_range = range(0, npyv.nlanes_u32) + vdata = npyv.load_u32(data_range) + assert vdata == list(data_range) + assert vdata == tuple(data_range) + for i in data_range: + assert vdata[i] == data_range[i] diff --git a/venv/Lib/site-packages/numpy/core/tests/test_ufunc.py b/venv/Lib/site-packages/numpy/core/tests/test_ufunc.py new file mode 100644 index 0000000..aa17d6b --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/tests/test_ufunc.py @@ -0,0 +1,2159 @@ +import warnings +import itertools +import sys + +import pytest + +import numpy as np +import numpy.core._umath_tests as umt +import numpy.linalg._umath_linalg as uml +import numpy.core._operand_flag_tests as opflag_tests +import numpy.core._rational_tests as _rational_tests +from numpy.testing import ( + assert_, assert_equal, assert_raises, assert_array_equal, + assert_almost_equal, assert_array_almost_equal, assert_no_warnings, + assert_allclose, HAS_REFCOUNT, + ) +from numpy.compat import pickle + + +UNARY_UFUNCS = [obj for obj in np.core.umath.__dict__.values() + if isinstance(obj, np.ufunc)] +UNARY_OBJECT_UFUNCS = [uf for uf in UNARY_UFUNCS if "O->O" in uf.types] + + +class TestUfuncKwargs: + def test_kwarg_exact(self): + assert_raises(TypeError, np.add, 1, 2, castingx='safe') + assert_raises(TypeError, np.add, 1, 2, dtypex=int) + assert_raises(TypeError, np.add, 1, 2, extobjx=[4096]) + assert_raises(TypeError, np.add, 1, 2, outx=None) + assert_raises(TypeError, np.add, 1, 2, sigx='ii->i') + assert_raises(TypeError, np.add, 1, 2, signaturex='ii->i') + assert_raises(TypeError, np.add, 1, 2, subokx=False) + assert_raises(TypeError, np.add, 1, 2, wherex=[True]) + + def test_sig_signature(self): + assert_raises(ValueError, np.add, 1, 2, sig='ii->i', + signature='ii->i') + + def test_sig_dtype(self): + assert_raises(RuntimeError, np.add, 1, 2, sig='ii->i', + dtype=int) + assert_raises(RuntimeError, np.add, 1, 2, signature='ii->i', + dtype=int) + + def test_extobj_refcount(self): + # Should not segfault with USE_DEBUG. + assert_raises(TypeError, np.add, 1, 2, extobj=[4096], parrot=True) + + +class TestUfuncGenericLoops: + """Test generic loops. + + The loops to be tested are: + + PyUFunc_ff_f_As_dd_d + PyUFunc_ff_f + PyUFunc_dd_d + PyUFunc_gg_g + PyUFunc_FF_F_As_DD_D + PyUFunc_DD_D + PyUFunc_FF_F + PyUFunc_GG_G + PyUFunc_OO_O + PyUFunc_OO_O_method + PyUFunc_f_f_As_d_d + PyUFunc_d_d + PyUFunc_f_f + PyUFunc_g_g + PyUFunc_F_F_As_D_D + PyUFunc_F_F + PyUFunc_D_D + PyUFunc_G_G + PyUFunc_O_O + PyUFunc_O_O_method + PyUFunc_On_Om + + Where: + + f -- float + d -- double + g -- long double + F -- complex float + D -- complex double + G -- complex long double + O -- python object + + It is difficult to assure that each of these loops is entered from the + Python level as the special cased loops are a moving target and the + corresponding types are architecture dependent. We probably need to + define C level testing ufuncs to get at them. For the time being, I've + just looked at the signatures registered in the build directory to find + relevant functions. + + """ + np_dtypes = [ + (np.single, np.single), (np.single, np.double), + (np.csingle, np.csingle), (np.csingle, np.cdouble), + (np.double, np.double), (np.longdouble, np.longdouble), + (np.cdouble, np.cdouble), (np.clongdouble, np.clongdouble)] + + @pytest.mark.parametrize('input_dtype,output_dtype', np_dtypes) + def test_unary_PyUFunc(self, input_dtype, output_dtype, f=np.exp, x=0, y=1): + xs = np.full(10, input_dtype(x), dtype=output_dtype) + ys = f(xs)[::2] + assert_allclose(ys, y) + assert_equal(ys.dtype, output_dtype) + + def f2(x, y): + return x**y + + @pytest.mark.parametrize('input_dtype,output_dtype', np_dtypes) + def test_binary_PyUFunc(self, input_dtype, output_dtype, f=f2, x=0, y=1): + xs = np.full(10, input_dtype(x), dtype=output_dtype) + ys = f(xs, xs)[::2] + assert_allclose(ys, y) + assert_equal(ys.dtype, output_dtype) + + # class to use in testing object method loops + class foo: + def conjugate(self): + return np.bool_(1) + + def logical_xor(self, obj): + return np.bool_(1) + + def test_unary_PyUFunc_O_O(self): + x = np.ones(10, dtype=object) + assert_(np.all(np.abs(x) == 1)) + + def test_unary_PyUFunc_O_O_method_simple(self, foo=foo): + x = np.full(10, foo(), dtype=object) + assert_(np.all(np.conjugate(x) == True)) + + def test_binary_PyUFunc_OO_O(self): + x = np.ones(10, dtype=object) + assert_(np.all(np.add(x, x) == 2)) + + def test_binary_PyUFunc_OO_O_method(self, foo=foo): + x = np.full(10, foo(), dtype=object) + assert_(np.all(np.logical_xor(x, x))) + + def test_binary_PyUFunc_On_Om_method(self, foo=foo): + x = np.full((10, 2, 3), foo(), dtype=object) + assert_(np.all(np.logical_xor(x, x))) + + def test_python_complex_conjugate(self): + # The conjugate ufunc should fall back to calling the method: + arr = np.array([1+2j, 3-4j], dtype="O") + assert isinstance(arr[0], complex) + res = np.conjugate(arr) + assert res.dtype == np.dtype("O") + assert_array_equal(res, np.array([1-2j, 3+4j], dtype="O")) + + @pytest.mark.parametrize("ufunc", UNARY_OBJECT_UFUNCS) + def test_unary_PyUFunc_O_O_method_full(self, ufunc): + """Compare the result of the object loop with non-object one""" + val = np.float64(np.pi/4) + + class MyFloat(np.float64): + def __getattr__(self, attr): + try: + return super().__getattr__(attr) + except AttributeError: + return lambda: getattr(np.core.umath, attr)(val) + + num_arr = np.array([val], dtype=np.float64) + obj_arr = np.array([MyFloat(val)], dtype="O") + + with np.errstate(all="raise"): + try: + res_num = ufunc(num_arr) + except Exception as exc: + with assert_raises(type(exc)): + ufunc(obj_arr) + else: + res_obj = ufunc(obj_arr) + assert_array_equal(res_num.astype("O"), res_obj) + + +def _pickleable_module_global(): + pass + + +class TestUfunc: + def test_pickle(self): + for proto in range(2, pickle.HIGHEST_PROTOCOL + 1): + assert_(pickle.loads(pickle.dumps(np.sin, + protocol=proto)) is np.sin) + + # Check that ufunc not defined in the top level numpy namespace + # such as numpy.core._rational_tests.test_add can also be pickled + res = pickle.loads(pickle.dumps(_rational_tests.test_add, + protocol=proto)) + assert_(res is _rational_tests.test_add) + + def test_pickle_withstring(self): + astring = (b"cnumpy.core\n_ufunc_reconstruct\np0\n" + b"(S'numpy.core.umath'\np1\nS'cos'\np2\ntp3\nRp4\n.") + assert_(pickle.loads(astring) is np.cos) + + def test_pickle_name_is_qualname(self): + # This tests that a simplification of our ufunc pickle code will + # lead to allowing qualnames as names. Future ufuncs should + # possible add a specific qualname, or a hook into pickling instead + # (dask+numba may benefit). + _pickleable_module_global.ufunc = umt._pickleable_module_global_ufunc + obj = pickle.loads(pickle.dumps(_pickleable_module_global.ufunc)) + assert obj is umt._pickleable_module_global_ufunc + + def test_reduceat_shifting_sum(self): + L = 6 + x = np.arange(L) + idx = np.array(list(zip(np.arange(L - 2), np.arange(L - 2) + 2))).ravel() + assert_array_equal(np.add.reduceat(x, idx)[::2], [1, 3, 5, 7]) + + def test_all_ufunc(self): + """Try to check presence and results of all ufuncs. + + The list of ufuncs comes from generate_umath.py and is as follows: + + ===== ==== ============= =============== ======================== + done args function types notes + ===== ==== ============= =============== ======================== + n 1 conjugate nums + O + n 1 absolute nums + O complex -> real + n 1 negative nums + O + n 1 sign nums + O -> int + n 1 invert bool + ints + O flts raise an error + n 1 degrees real + M cmplx raise an error + n 1 radians real + M cmplx raise an error + n 1 arccos flts + M + n 1 arccosh flts + M + n 1 arcsin flts + M + n 1 arcsinh flts + M + n 1 arctan flts + M + n 1 arctanh flts + M + n 1 cos flts + M + n 1 sin flts + M + n 1 tan flts + M + n 1 cosh flts + M + n 1 sinh flts + M + n 1 tanh flts + M + n 1 exp flts + M + n 1 expm1 flts + M + n 1 log flts + M + n 1 log10 flts + M + n 1 log1p flts + M + n 1 sqrt flts + M real x < 0 raises error + n 1 ceil real + M + n 1 trunc real + M + n 1 floor real + M + n 1 fabs real + M + n 1 rint flts + M + n 1 isnan flts -> bool + n 1 isinf flts -> bool + n 1 isfinite flts -> bool + n 1 signbit real -> bool + n 1 modf real -> (frac, int) + n 1 logical_not bool + nums + M -> bool + n 2 left_shift ints + O flts raise an error + n 2 right_shift ints + O flts raise an error + n 2 add bool + nums + O boolean + is || + n 2 subtract bool + nums + O boolean - is ^ + n 2 multiply bool + nums + O boolean * is & + n 2 divide nums + O + n 2 floor_divide nums + O + n 2 true_divide nums + O bBhH -> f, iIlLqQ -> d + n 2 fmod nums + M + n 2 power nums + O + n 2 greater bool + nums + O -> bool + n 2 greater_equal bool + nums + O -> bool + n 2 less bool + nums + O -> bool + n 2 less_equal bool + nums + O -> bool + n 2 equal bool + nums + O -> bool + n 2 not_equal bool + nums + O -> bool + n 2 logical_and bool + nums + M -> bool + n 2 logical_or bool + nums + M -> bool + n 2 logical_xor bool + nums + M -> bool + n 2 maximum bool + nums + O + n 2 minimum bool + nums + O + n 2 bitwise_and bool + ints + O flts raise an error + n 2 bitwise_or bool + ints + O flts raise an error + n 2 bitwise_xor bool + ints + O flts raise an error + n 2 arctan2 real + M + n 2 remainder ints + real + O + n 2 hypot real + M + ===== ==== ============= =============== ======================== + + Types other than those listed will be accepted, but they are cast to + the smallest compatible type for which the function is defined. The + casting rules are: + + bool -> int8 -> float32 + ints -> double + + """ + pass + + # from include/numpy/ufuncobject.h + size_inferred = 2 + can_ignore = 4 + def test_signature0(self): + # the arguments to test_signature are: nin, nout, core_signature + enabled, num_dims, ixs, flags, sizes = umt.test_signature( + 2, 1, "(i),(i)->()") + assert_equal(enabled, 1) + assert_equal(num_dims, (1, 1, 0)) + assert_equal(ixs, (0, 0)) + assert_equal(flags, (self.size_inferred,)) + assert_equal(sizes, (-1,)) + + def test_signature1(self): + # empty core signature; treat as plain ufunc (with trivial core) + enabled, num_dims, ixs, flags, sizes = umt.test_signature( + 2, 1, "(),()->()") + assert_equal(enabled, 0) + assert_equal(num_dims, (0, 0, 0)) + assert_equal(ixs, ()) + assert_equal(flags, ()) + assert_equal(sizes, ()) + + def test_signature2(self): + # more complicated names for variables + enabled, num_dims, ixs, flags, sizes = umt.test_signature( + 2, 1, "(i1,i2),(J_1)->(_kAB)") + assert_equal(enabled, 1) + assert_equal(num_dims, (2, 1, 1)) + assert_equal(ixs, (0, 1, 2, 3)) + assert_equal(flags, (self.size_inferred,)*4) + assert_equal(sizes, (-1, -1, -1, -1)) + + def test_signature3(self): + enabled, num_dims, ixs, flags, sizes = umt.test_signature( + 2, 1, u"(i1, i12), (J_1)->(i12, i2)") + assert_equal(enabled, 1) + assert_equal(num_dims, (2, 1, 2)) + assert_equal(ixs, (0, 1, 2, 1, 3)) + assert_equal(flags, (self.size_inferred,)*4) + assert_equal(sizes, (-1, -1, -1, -1)) + + def test_signature4(self): + # matrix_multiply signature from _umath_tests + enabled, num_dims, ixs, flags, sizes = umt.test_signature( + 2, 1, "(n,k),(k,m)->(n,m)") + assert_equal(enabled, 1) + assert_equal(num_dims, (2, 2, 2)) + assert_equal(ixs, (0, 1, 1, 2, 0, 2)) + assert_equal(flags, (self.size_inferred,)*3) + assert_equal(sizes, (-1, -1, -1)) + + def test_signature5(self): + # matmul signature from _umath_tests + enabled, num_dims, ixs, flags, sizes = umt.test_signature( + 2, 1, "(n?,k),(k,m?)->(n?,m?)") + assert_equal(enabled, 1) + assert_equal(num_dims, (2, 2, 2)) + assert_equal(ixs, (0, 1, 1, 2, 0, 2)) + assert_equal(flags, (self.size_inferred | self.can_ignore, + self.size_inferred, + self.size_inferred | self.can_ignore)) + assert_equal(sizes, (-1, -1, -1)) + + def test_signature6(self): + enabled, num_dims, ixs, flags, sizes = umt.test_signature( + 1, 1, "(3)->()") + assert_equal(enabled, 1) + assert_equal(num_dims, (1, 0)) + assert_equal(ixs, (0,)) + assert_equal(flags, (0,)) + assert_equal(sizes, (3,)) + + def test_signature7(self): + enabled, num_dims, ixs, flags, sizes = umt.test_signature( + 3, 1, "(3),(03,3),(n)->(9)") + assert_equal(enabled, 1) + assert_equal(num_dims, (1, 2, 1, 1)) + assert_equal(ixs, (0, 0, 0, 1, 2)) + assert_equal(flags, (0, self.size_inferred, 0)) + assert_equal(sizes, (3, -1, 9)) + + def test_signature8(self): + enabled, num_dims, ixs, flags, sizes = umt.test_signature( + 3, 1, "(3?),(3?,3?),(n)->(9)") + assert_equal(enabled, 1) + assert_equal(num_dims, (1, 2, 1, 1)) + assert_equal(ixs, (0, 0, 0, 1, 2)) + assert_equal(flags, (self.can_ignore, self.size_inferred, 0)) + assert_equal(sizes, (3, -1, 9)) + + def test_signature_failure_extra_parenthesis(self): + with assert_raises(ValueError): + umt.test_signature(2, 1, "((i)),(i)->()") + + def test_signature_failure_mismatching_parenthesis(self): + with assert_raises(ValueError): + umt.test_signature(2, 1, "(i),)i(->()") + + def test_signature_failure_signature_missing_input_arg(self): + with assert_raises(ValueError): + umt.test_signature(2, 1, "(i),->()") + + def test_signature_failure_signature_missing_output_arg(self): + with assert_raises(ValueError): + umt.test_signature(2, 2, "(i),(i)->()") + + def test_get_signature(self): + assert_equal(umt.inner1d.signature, "(i),(i)->()") + + def test_forced_sig(self): + a = 0.5*np.arange(3, dtype='f8') + assert_equal(np.add(a, 0.5), [0.5, 1, 1.5]) + assert_equal(np.add(a, 0.5, sig='i', casting='unsafe'), [0, 0, 1]) + assert_equal(np.add(a, 0.5, sig='ii->i', casting='unsafe'), [0, 0, 1]) + assert_equal(np.add(a, 0.5, sig=('i4',), casting='unsafe'), [0, 0, 1]) + assert_equal(np.add(a, 0.5, sig=('i4', 'i4', 'i4'), + casting='unsafe'), [0, 0, 1]) + + b = np.zeros((3,), dtype='f8') + np.add(a, 0.5, out=b) + assert_equal(b, [0.5, 1, 1.5]) + b[:] = 0 + np.add(a, 0.5, sig='i', out=b, casting='unsafe') + assert_equal(b, [0, 0, 1]) + b[:] = 0 + np.add(a, 0.5, sig='ii->i', out=b, casting='unsafe') + assert_equal(b, [0, 0, 1]) + b[:] = 0 + np.add(a, 0.5, sig=('i4',), out=b, casting='unsafe') + assert_equal(b, [0, 0, 1]) + b[:] = 0 + np.add(a, 0.5, sig=('i4', 'i4', 'i4'), out=b, casting='unsafe') + assert_equal(b, [0, 0, 1]) + + def test_true_divide(self): + a = np.array(10) + b = np.array(20) + tgt = np.array(0.5) + + for tc in 'bhilqBHILQefdgFDG': + dt = np.dtype(tc) + aa = a.astype(dt) + bb = b.astype(dt) + + # Check result value and dtype. + for x, y in itertools.product([aa, -aa], [bb, -bb]): + + # Check with no output type specified + if tc in 'FDG': + tgt = complex(x)/complex(y) + else: + tgt = float(x)/float(y) + + res = np.true_divide(x, y) + rtol = max(np.finfo(res).resolution, 1e-15) + assert_allclose(res, tgt, rtol=rtol) + + if tc in 'bhilqBHILQ': + assert_(res.dtype.name == 'float64') + else: + assert_(res.dtype.name == dt.name ) + + # Check with output type specified. This also checks for the + # incorrect casts in issue gh-3484 because the unary '-' does + # not change types, even for unsigned types, Hence casts in the + # ufunc from signed to unsigned and vice versa will lead to + # errors in the values. + for tcout in 'bhilqBHILQ': + dtout = np.dtype(tcout) + assert_raises(TypeError, np.true_divide, x, y, dtype=dtout) + + for tcout in 'efdg': + dtout = np.dtype(tcout) + if tc in 'FDG': + # Casting complex to float is not allowed + assert_raises(TypeError, np.true_divide, x, y, dtype=dtout) + else: + tgt = float(x)/float(y) + rtol = max(np.finfo(dtout).resolution, 1e-15) + atol = max(np.finfo(dtout).tiny, 3e-308) + # Some test values result in invalid for float16. + with np.errstate(invalid='ignore'): + res = np.true_divide(x, y, dtype=dtout) + if not np.isfinite(res) and tcout == 'e': + continue + assert_allclose(res, tgt, rtol=rtol, atol=atol) + assert_(res.dtype.name == dtout.name) + + for tcout in 'FDG': + dtout = np.dtype(tcout) + tgt = complex(x)/complex(y) + rtol = max(np.finfo(dtout).resolution, 1e-15) + atol = max(np.finfo(dtout).tiny, 3e-308) + res = np.true_divide(x, y, dtype=dtout) + if not np.isfinite(res): + continue + assert_allclose(res, tgt, rtol=rtol, atol=atol) + assert_(res.dtype.name == dtout.name) + + # Check booleans + a = np.ones((), dtype=np.bool_) + res = np.true_divide(a, a) + assert_(res == 1.0) + assert_(res.dtype.name == 'float64') + res = np.true_divide(~a, a) + assert_(res == 0.0) + assert_(res.dtype.name == 'float64') + + def test_sum_stability(self): + a = np.ones(500, dtype=np.float32) + assert_almost_equal((a / 10.).sum() - a.size / 10., 0, 4) + + a = np.ones(500, dtype=np.float64) + assert_almost_equal((a / 10.).sum() - a.size / 10., 0, 13) + + def test_sum(self): + for dt in (int, np.float16, np.float32, np.float64, np.longdouble): + for v in (0, 1, 2, 7, 8, 9, 15, 16, 19, 127, + 128, 1024, 1235): + tgt = dt(v * (v + 1) / 2) + d = np.arange(1, v + 1, dtype=dt) + + # warning if sum overflows, which it does in float16 + overflow = not np.isfinite(tgt) + + with warnings.catch_warnings(record=True) as w: + warnings.simplefilter("always") + assert_almost_equal(np.sum(d), tgt) + assert_equal(len(w), 1 * overflow) + + assert_almost_equal(np.sum(d[::-1]), tgt) + assert_equal(len(w), 2 * overflow) + + d = np.ones(500, dtype=dt) + assert_almost_equal(np.sum(d[::2]), 250.) + assert_almost_equal(np.sum(d[1::2]), 250.) + assert_almost_equal(np.sum(d[::3]), 167.) + assert_almost_equal(np.sum(d[1::3]), 167.) + assert_almost_equal(np.sum(d[::-2]), 250.) + assert_almost_equal(np.sum(d[-1::-2]), 250.) + assert_almost_equal(np.sum(d[::-3]), 167.) + assert_almost_equal(np.sum(d[-1::-3]), 167.) + # sum with first reduction entry != 0 + d = np.ones((1,), dtype=dt) + d += d + assert_almost_equal(d, 2.) + + def test_sum_complex(self): + for dt in (np.complex64, np.complex128, np.clongdouble): + for v in (0, 1, 2, 7, 8, 9, 15, 16, 19, 127, + 128, 1024, 1235): + tgt = dt(v * (v + 1) / 2) - dt((v * (v + 1) / 2) * 1j) + d = np.empty(v, dtype=dt) + d.real = np.arange(1, v + 1) + d.imag = -np.arange(1, v + 1) + assert_almost_equal(np.sum(d), tgt) + assert_almost_equal(np.sum(d[::-1]), tgt) + + d = np.ones(500, dtype=dt) + 1j + assert_almost_equal(np.sum(d[::2]), 250. + 250j) + assert_almost_equal(np.sum(d[1::2]), 250. + 250j) + assert_almost_equal(np.sum(d[::3]), 167. + 167j) + assert_almost_equal(np.sum(d[1::3]), 167. + 167j) + assert_almost_equal(np.sum(d[::-2]), 250. + 250j) + assert_almost_equal(np.sum(d[-1::-2]), 250. + 250j) + assert_almost_equal(np.sum(d[::-3]), 167. + 167j) + assert_almost_equal(np.sum(d[-1::-3]), 167. + 167j) + # sum with first reduction entry != 0 + d = np.ones((1,), dtype=dt) + 1j + d += d + assert_almost_equal(d, 2. + 2j) + + def test_sum_initial(self): + # Integer, single axis + assert_equal(np.sum([3], initial=2), 5) + + # Floating point + assert_almost_equal(np.sum([0.2], initial=0.1), 0.3) + + # Multiple non-adjacent axes + assert_equal(np.sum(np.ones((2, 3, 5), dtype=np.int64), axis=(0, 2), initial=2), + [12, 12, 12]) + + def test_sum_where(self): + # More extensive tests done in test_reduction_with_where. + assert_equal(np.sum([[1., 2.], [3., 4.]], where=[True, False]), 4.) + assert_equal(np.sum([[1., 2.], [3., 4.]], axis=0, initial=5., + where=[True, False]), [9., 5.]) + + def test_inner1d(self): + a = np.arange(6).reshape((2, 3)) + assert_array_equal(umt.inner1d(a, a), np.sum(a*a, axis=-1)) + a = np.arange(6) + assert_array_equal(umt.inner1d(a, a), np.sum(a*a)) + + def test_broadcast(self): + msg = "broadcast" + a = np.arange(4).reshape((2, 1, 2)) + b = np.arange(4).reshape((1, 2, 2)) + assert_array_equal(umt.inner1d(a, b), np.sum(a*b, axis=-1), err_msg=msg) + msg = "extend & broadcast loop dimensions" + b = np.arange(4).reshape((2, 2)) + assert_array_equal(umt.inner1d(a, b), np.sum(a*b, axis=-1), err_msg=msg) + # Broadcast in core dimensions should fail + a = np.arange(8).reshape((4, 2)) + b = np.arange(4).reshape((4, 1)) + assert_raises(ValueError, umt.inner1d, a, b) + # Extend core dimensions should fail + a = np.arange(8).reshape((4, 2)) + b = np.array(7) + assert_raises(ValueError, umt.inner1d, a, b) + # Broadcast should fail + a = np.arange(2).reshape((2, 1, 1)) + b = np.arange(3).reshape((3, 1, 1)) + assert_raises(ValueError, umt.inner1d, a, b) + + # Writing to a broadcasted array with overlap should warn, gh-2705 + a = np.arange(2) + b = np.arange(4).reshape((2, 2)) + u, v = np.broadcast_arrays(a, b) + assert_equal(u.strides[0], 0) + x = u + v + with warnings.catch_warnings(record=True) as w: + warnings.simplefilter("always") + u += v + assert_equal(len(w), 1) + assert_(x[0, 0] != u[0, 0]) + + # Output reduction should not be allowed. + # See gh-15139 + a = np.arange(6).reshape(3, 2) + b = np.ones(2) + out = np.empty(()) + assert_raises(ValueError, umt.inner1d, a, b, out) + out2 = np.empty(3) + c = umt.inner1d(a, b, out2) + assert_(c is out2) + + def test_out_broadcasts(self): + # For ufuncs and gufuncs (not for reductions), we currently allow + # the output to cause broadcasting of the input arrays. + # both along dimensions with shape 1 and dimensions which do not + # exist at all in the inputs. + arr = np.arange(3).reshape(1, 3) + out = np.empty((5, 4, 3)) + np.add(arr, arr, out=out) + assert (out == np.arange(3) * 2).all() + + # The same holds for gufuncs (gh-16484) + umt.inner1d(arr, arr, out=out) + # the result would be just a scalar `5`, but is broadcast fully: + assert (out == 5).all() + + def test_type_cast(self): + msg = "type cast" + a = np.arange(6, dtype='short').reshape((2, 3)) + assert_array_equal(umt.inner1d(a, a), np.sum(a*a, axis=-1), + err_msg=msg) + msg = "type cast on one argument" + a = np.arange(6).reshape((2, 3)) + b = a + 0.1 + assert_array_almost_equal(umt.inner1d(a, b), np.sum(a*b, axis=-1), + err_msg=msg) + + def test_endian(self): + msg = "big endian" + a = np.arange(6, dtype='>i4').reshape((2, 3)) + assert_array_equal(umt.inner1d(a, a), np.sum(a*a, axis=-1), + err_msg=msg) + msg = "little endian" + a = np.arange(6, dtype='()' + inner1d = umt.inner1d + a = np.arange(27.).reshape((3, 3, 3)) + b = np.arange(10., 19.).reshape((3, 1, 3)) + # basic tests on inputs (outputs tested below with matrix_multiply). + c = inner1d(a, b) + assert_array_equal(c, (a * b).sum(-1)) + # default + c = inner1d(a, b, axes=[(-1,), (-1,), ()]) + assert_array_equal(c, (a * b).sum(-1)) + # integers ok for single axis. + c = inner1d(a, b, axes=[-1, -1, ()]) + assert_array_equal(c, (a * b).sum(-1)) + # mix fine + c = inner1d(a, b, axes=[(-1,), -1, ()]) + assert_array_equal(c, (a * b).sum(-1)) + # can omit last axis. + c = inner1d(a, b, axes=[-1, -1]) + assert_array_equal(c, (a * b).sum(-1)) + # can pass in other types of integer (with __index__ protocol) + c = inner1d(a, b, axes=[np.int8(-1), np.array(-1, dtype=np.int32)]) + assert_array_equal(c, (a * b).sum(-1)) + # swap some axes + c = inner1d(a, b, axes=[0, 0]) + assert_array_equal(c, (a * b).sum(0)) + c = inner1d(a, b, axes=[0, 2]) + assert_array_equal(c, (a.transpose(1, 2, 0) * b).sum(-1)) + # Check errors for improperly constructed axes arguments. + # should have list. + assert_raises(TypeError, inner1d, a, b, axes=-1) + # needs enough elements + assert_raises(ValueError, inner1d, a, b, axes=[-1]) + # should pass in indices. + assert_raises(TypeError, inner1d, a, b, axes=[-1.0, -1.0]) + assert_raises(TypeError, inner1d, a, b, axes=[(-1.0,), -1]) + assert_raises(TypeError, inner1d, a, b, axes=[None, 1]) + # cannot pass an index unless there is only one dimension + # (output is wrong in this case) + assert_raises(TypeError, inner1d, a, b, axes=[-1, -1, -1]) + # or pass in generally the wrong number of axes + assert_raises(ValueError, inner1d, a, b, axes=[-1, -1, (-1,)]) + assert_raises(ValueError, inner1d, a, b, axes=[-1, (-2, -1), ()]) + # axes need to have same length. + assert_raises(ValueError, inner1d, a, b, axes=[0, 1]) + + # matrix_multiply signature: '(m,n),(n,p)->(m,p)' + mm = umt.matrix_multiply + a = np.arange(12).reshape((2, 3, 2)) + b = np.arange(8).reshape((2, 2, 2, 1)) + 1 + # Sanity check. + c = mm(a, b) + assert_array_equal(c, np.matmul(a, b)) + # Default axes. + c = mm(a, b, axes=[(-2, -1), (-2, -1), (-2, -1)]) + assert_array_equal(c, np.matmul(a, b)) + # Default with explicit axes. + c = mm(a, b, axes=[(1, 2), (2, 3), (2, 3)]) + assert_array_equal(c, np.matmul(a, b)) + # swap some axes. + c = mm(a, b, axes=[(0, -1), (1, 2), (-2, -1)]) + assert_array_equal(c, np.matmul(a.transpose(1, 0, 2), + b.transpose(0, 3, 1, 2))) + # Default with output array. + c = np.empty((2, 2, 3, 1)) + d = mm(a, b, out=c, axes=[(1, 2), (2, 3), (2, 3)]) + assert_(c is d) + assert_array_equal(c, np.matmul(a, b)) + # Transposed output array + c = np.empty((1, 2, 2, 3)) + d = mm(a, b, out=c, axes=[(-2, -1), (-2, -1), (3, 0)]) + assert_(c is d) + assert_array_equal(c, np.matmul(a, b).transpose(3, 0, 1, 2)) + # Check errors for improperly constructed axes arguments. + # wrong argument + assert_raises(TypeError, mm, a, b, axis=1) + # axes should be list + assert_raises(TypeError, mm, a, b, axes=1) + assert_raises(TypeError, mm, a, b, axes=((-2, -1), (-2, -1), (-2, -1))) + # list needs to have right length + assert_raises(ValueError, mm, a, b, axes=[]) + assert_raises(ValueError, mm, a, b, axes=[(-2, -1)]) + # list should contain tuples for multiple axes + assert_raises(TypeError, mm, a, b, axes=[-1, -1, -1]) + assert_raises(TypeError, mm, a, b, axes=[(-2, -1), (-2, -1), -1]) + assert_raises(TypeError, + mm, a, b, axes=[[-2, -1], [-2, -1], [-2, -1]]) + assert_raises(TypeError, + mm, a, b, axes=[(-2, -1), (-2, -1), [-2, -1]]) + assert_raises(TypeError, mm, a, b, axes=[(-2, -1), (-2, -1), None]) + # tuples should not have duplicated values + assert_raises(ValueError, mm, a, b, axes=[(-2, -1), (-2, -1), (-2, -2)]) + # arrays should have enough axes. + z = np.zeros((2, 2)) + assert_raises(ValueError, mm, z, z[0]) + assert_raises(ValueError, mm, z, z, out=z[:, 0]) + assert_raises(ValueError, mm, z[1], z, axes=[0, 1]) + assert_raises(ValueError, mm, z, z, out=z[0], axes=[0, 1]) + # Regular ufuncs should not accept axes. + assert_raises(TypeError, np.add, 1., 1., axes=[0]) + # should be able to deal with bad unrelated kwargs. + assert_raises(TypeError, mm, z, z, axes=[0, 1], parrot=True) + + def test_axis_argument(self): + # inner1d signature: '(i),(i)->()' + inner1d = umt.inner1d + a = np.arange(27.).reshape((3, 3, 3)) + b = np.arange(10., 19.).reshape((3, 1, 3)) + c = inner1d(a, b) + assert_array_equal(c, (a * b).sum(-1)) + c = inner1d(a, b, axis=-1) + assert_array_equal(c, (a * b).sum(-1)) + out = np.zeros_like(c) + d = inner1d(a, b, axis=-1, out=out) + assert_(d is out) + assert_array_equal(d, c) + c = inner1d(a, b, axis=0) + assert_array_equal(c, (a * b).sum(0)) + # Sanity checks on innerwt and cumsum. + a = np.arange(6).reshape((2, 3)) + b = np.arange(10, 16).reshape((2, 3)) + w = np.arange(20, 26).reshape((2, 3)) + assert_array_equal(umt.innerwt(a, b, w, axis=0), + np.sum(a * b * w, axis=0)) + assert_array_equal(umt.cumsum(a, axis=0), np.cumsum(a, axis=0)) + assert_array_equal(umt.cumsum(a, axis=-1), np.cumsum(a, axis=-1)) + out = np.empty_like(a) + b = umt.cumsum(a, out=out, axis=0) + assert_(out is b) + assert_array_equal(b, np.cumsum(a, axis=0)) + b = umt.cumsum(a, out=out, axis=1) + assert_(out is b) + assert_array_equal(b, np.cumsum(a, axis=-1)) + # Check errors. + # Cannot pass in both axis and axes. + assert_raises(TypeError, inner1d, a, b, axis=0, axes=[0, 0]) + # Not an integer. + assert_raises(TypeError, inner1d, a, b, axis=[0]) + # more than 1 core dimensions. + mm = umt.matrix_multiply + assert_raises(TypeError, mm, a, b, axis=1) + # Output wrong size in axis. + out = np.empty((1, 2, 3), dtype=a.dtype) + assert_raises(ValueError, umt.cumsum, a, out=out, axis=0) + # Regular ufuncs should not accept axis. + assert_raises(TypeError, np.add, 1., 1., axis=0) + + def test_keepdims_argument(self): + # inner1d signature: '(i),(i)->()' + inner1d = umt.inner1d + a = np.arange(27.).reshape((3, 3, 3)) + b = np.arange(10., 19.).reshape((3, 1, 3)) + c = inner1d(a, b) + assert_array_equal(c, (a * b).sum(-1)) + c = inner1d(a, b, keepdims=False) + assert_array_equal(c, (a * b).sum(-1)) + c = inner1d(a, b, keepdims=True) + assert_array_equal(c, (a * b).sum(-1, keepdims=True)) + out = np.zeros_like(c) + d = inner1d(a, b, keepdims=True, out=out) + assert_(d is out) + assert_array_equal(d, c) + # Now combined with axis and axes. + c = inner1d(a, b, axis=-1, keepdims=False) + assert_array_equal(c, (a * b).sum(-1, keepdims=False)) + c = inner1d(a, b, axis=-1, keepdims=True) + assert_array_equal(c, (a * b).sum(-1, keepdims=True)) + c = inner1d(a, b, axis=0, keepdims=False) + assert_array_equal(c, (a * b).sum(0, keepdims=False)) + c = inner1d(a, b, axis=0, keepdims=True) + assert_array_equal(c, (a * b).sum(0, keepdims=True)) + c = inner1d(a, b, axes=[(-1,), (-1,), ()], keepdims=False) + assert_array_equal(c, (a * b).sum(-1)) + c = inner1d(a, b, axes=[(-1,), (-1,), (-1,)], keepdims=True) + assert_array_equal(c, (a * b).sum(-1, keepdims=True)) + c = inner1d(a, b, axes=[0, 0], keepdims=False) + assert_array_equal(c, (a * b).sum(0)) + c = inner1d(a, b, axes=[0, 0, 0], keepdims=True) + assert_array_equal(c, (a * b).sum(0, keepdims=True)) + c = inner1d(a, b, axes=[0, 2], keepdims=False) + assert_array_equal(c, (a.transpose(1, 2, 0) * b).sum(-1)) + c = inner1d(a, b, axes=[0, 2], keepdims=True) + assert_array_equal(c, (a.transpose(1, 2, 0) * b).sum(-1, + keepdims=True)) + c = inner1d(a, b, axes=[0, 2, 2], keepdims=True) + assert_array_equal(c, (a.transpose(1, 2, 0) * b).sum(-1, + keepdims=True)) + c = inner1d(a, b, axes=[0, 2, 0], keepdims=True) + assert_array_equal(c, (a * b.transpose(2, 0, 1)).sum(0, keepdims=True)) + # Hardly useful, but should work. + c = inner1d(a, b, axes=[0, 2, 1], keepdims=True) + assert_array_equal(c, (a.transpose(1, 0, 2) * b.transpose(0, 2, 1)) + .sum(1, keepdims=True)) + # Check with two core dimensions. + a = np.eye(3) * np.arange(4.)[:, np.newaxis, np.newaxis] + expected = uml.det(a) + c = uml.det(a, keepdims=False) + assert_array_equal(c, expected) + c = uml.det(a, keepdims=True) + assert_array_equal(c, expected[:, np.newaxis, np.newaxis]) + a = np.eye(3) * np.arange(4.)[:, np.newaxis, np.newaxis] + expected_s, expected_l = uml.slogdet(a) + cs, cl = uml.slogdet(a, keepdims=False) + assert_array_equal(cs, expected_s) + assert_array_equal(cl, expected_l) + cs, cl = uml.slogdet(a, keepdims=True) + assert_array_equal(cs, expected_s[:, np.newaxis, np.newaxis]) + assert_array_equal(cl, expected_l[:, np.newaxis, np.newaxis]) + # Sanity check on innerwt. + a = np.arange(6).reshape((2, 3)) + b = np.arange(10, 16).reshape((2, 3)) + w = np.arange(20, 26).reshape((2, 3)) + assert_array_equal(umt.innerwt(a, b, w, keepdims=True), + np.sum(a * b * w, axis=-1, keepdims=True)) + assert_array_equal(umt.innerwt(a, b, w, axis=0, keepdims=True), + np.sum(a * b * w, axis=0, keepdims=True)) + # Check errors. + # Not a boolean + assert_raises(TypeError, inner1d, a, b, keepdims='true') + # More than 1 core dimension, and core output dimensions. + mm = umt.matrix_multiply + assert_raises(TypeError, mm, a, b, keepdims=True) + assert_raises(TypeError, mm, a, b, keepdims=False) + # Regular ufuncs should not accept keepdims. + assert_raises(TypeError, np.add, 1., 1., keepdims=False) + + def test_innerwt(self): + a = np.arange(6).reshape((2, 3)) + b = np.arange(10, 16).reshape((2, 3)) + w = np.arange(20, 26).reshape((2, 3)) + assert_array_equal(umt.innerwt(a, b, w), np.sum(a*b*w, axis=-1)) + a = np.arange(100, 124).reshape((2, 3, 4)) + b = np.arange(200, 224).reshape((2, 3, 4)) + w = np.arange(300, 324).reshape((2, 3, 4)) + assert_array_equal(umt.innerwt(a, b, w), np.sum(a*b*w, axis=-1)) + + def test_innerwt_empty(self): + """Test generalized ufunc with zero-sized operands""" + a = np.array([], dtype='f8') + b = np.array([], dtype='f8') + w = np.array([], dtype='f8') + assert_array_equal(umt.innerwt(a, b, w), np.sum(a*b*w, axis=-1)) + + def test_cross1d(self): + """Test with fixed-sized signature.""" + a = np.eye(3) + assert_array_equal(umt.cross1d(a, a), np.zeros((3, 3))) + out = np.zeros((3, 3)) + result = umt.cross1d(a[0], a, out) + assert_(result is out) + assert_array_equal(result, np.vstack((np.zeros(3), a[2], -a[1]))) + assert_raises(ValueError, umt.cross1d, np.eye(4), np.eye(4)) + assert_raises(ValueError, umt.cross1d, a, np.arange(4.)) + # Wrong output core dimension. + assert_raises(ValueError, umt.cross1d, a, np.arange(3.), np.zeros((3, 4))) + # Wrong output broadcast dimension (see gh-15139). + assert_raises(ValueError, umt.cross1d, a, np.arange(3.), np.zeros(3)) + + def test_can_ignore_signature(self): + # Comparing the effects of ? in signature: + # matrix_multiply: (m,n),(n,p)->(m,p) # all must be there. + # matmul: (m?,n),(n,p?)->(m?,p?) # allow missing m, p. + mat = np.arange(12).reshape((2, 3, 2)) + single_vec = np.arange(2) + col_vec = single_vec[:, np.newaxis] + col_vec_array = np.arange(8).reshape((2, 2, 2, 1)) + 1 + # matrix @ single column vector with proper dimension + mm_col_vec = umt.matrix_multiply(mat, col_vec) + # matmul does the same thing + matmul_col_vec = umt.matmul(mat, col_vec) + assert_array_equal(matmul_col_vec, mm_col_vec) + # matrix @ vector without dimension making it a column vector. + # matrix multiply fails -> missing core dim. + assert_raises(ValueError, umt.matrix_multiply, mat, single_vec) + # matmul mimicker passes, and returns a vector. + matmul_col = umt.matmul(mat, single_vec) + assert_array_equal(matmul_col, mm_col_vec.squeeze()) + # Now with a column array: same as for column vector, + # broadcasting sensibly. + mm_col_vec = umt.matrix_multiply(mat, col_vec_array) + matmul_col_vec = umt.matmul(mat, col_vec_array) + assert_array_equal(matmul_col_vec, mm_col_vec) + # As above, but for row vector + single_vec = np.arange(3) + row_vec = single_vec[np.newaxis, :] + row_vec_array = np.arange(24).reshape((4, 2, 1, 1, 3)) + 1 + # row vector @ matrix + mm_row_vec = umt.matrix_multiply(row_vec, mat) + matmul_row_vec = umt.matmul(row_vec, mat) + assert_array_equal(matmul_row_vec, mm_row_vec) + # single row vector @ matrix + assert_raises(ValueError, umt.matrix_multiply, single_vec, mat) + matmul_row = umt.matmul(single_vec, mat) + assert_array_equal(matmul_row, mm_row_vec.squeeze()) + # row vector array @ matrix + mm_row_vec = umt.matrix_multiply(row_vec_array, mat) + matmul_row_vec = umt.matmul(row_vec_array, mat) + assert_array_equal(matmul_row_vec, mm_row_vec) + # Now for vector combinations + # row vector @ column vector + col_vec = row_vec.T + col_vec_array = row_vec_array.swapaxes(-2, -1) + mm_row_col_vec = umt.matrix_multiply(row_vec, col_vec) + matmul_row_col_vec = umt.matmul(row_vec, col_vec) + assert_array_equal(matmul_row_col_vec, mm_row_col_vec) + # single row vector @ single col vector + assert_raises(ValueError, umt.matrix_multiply, single_vec, single_vec) + matmul_row_col = umt.matmul(single_vec, single_vec) + assert_array_equal(matmul_row_col, mm_row_col_vec.squeeze()) + # row vector array @ matrix + mm_row_col_array = umt.matrix_multiply(row_vec_array, col_vec_array) + matmul_row_col_array = umt.matmul(row_vec_array, col_vec_array) + assert_array_equal(matmul_row_col_array, mm_row_col_array) + # Finally, check that things are *not* squeezed if one gives an + # output. + out = np.zeros_like(mm_row_col_array) + out = umt.matrix_multiply(row_vec_array, col_vec_array, out=out) + assert_array_equal(out, mm_row_col_array) + out[:] = 0 + out = umt.matmul(row_vec_array, col_vec_array, out=out) + assert_array_equal(out, mm_row_col_array) + # And check one cannot put missing dimensions back. + out = np.zeros_like(mm_row_col_vec) + assert_raises(ValueError, umt.matrix_multiply, single_vec, single_vec, + out) + # But fine for matmul, since it is just a broadcast. + out = umt.matmul(single_vec, single_vec, out) + assert_array_equal(out, mm_row_col_vec.squeeze()) + + def test_matrix_multiply(self): + self.compare_matrix_multiply_results(np.int64) + self.compare_matrix_multiply_results(np.double) + + def test_matrix_multiply_umath_empty(self): + res = umt.matrix_multiply(np.ones((0, 10)), np.ones((10, 0))) + assert_array_equal(res, np.zeros((0, 0))) + res = umt.matrix_multiply(np.ones((10, 0)), np.ones((0, 10))) + assert_array_equal(res, np.zeros((10, 10))) + + def compare_matrix_multiply_results(self, tp): + d1 = np.array(np.random.rand(2, 3, 4), dtype=tp) + d2 = np.array(np.random.rand(2, 3, 4), dtype=tp) + msg = "matrix multiply on type %s" % d1.dtype.name + + def permute_n(n): + if n == 1: + return ([0],) + ret = () + base = permute_n(n-1) + for perm in base: + for i in range(n): + new = perm + [n-1] + new[n-1] = new[i] + new[i] = n-1 + ret += (new,) + return ret + + def slice_n(n): + if n == 0: + return ((),) + ret = () + base = slice_n(n-1) + for sl in base: + ret += (sl+(slice(None),),) + ret += (sl+(slice(0, 1),),) + return ret + + def broadcastable(s1, s2): + return s1 == s2 or s1 == 1 or s2 == 1 + + permute_3 = permute_n(3) + slice_3 = slice_n(3) + ((slice(None, None, -1),)*3,) + + ref = True + for p1 in permute_3: + for p2 in permute_3: + for s1 in slice_3: + for s2 in slice_3: + a1 = d1.transpose(p1)[s1] + a2 = d2.transpose(p2)[s2] + ref = ref and a1.base is not None + ref = ref and a2.base is not None + if (a1.shape[-1] == a2.shape[-2] and + broadcastable(a1.shape[0], a2.shape[0])): + assert_array_almost_equal( + umt.matrix_multiply(a1, a2), + np.sum(a2[..., np.newaxis].swapaxes(-3, -1) * + a1[..., np.newaxis,:], axis=-1), + err_msg=msg + ' %s %s' % (str(a1.shape), + str(a2.shape))) + + assert_equal(ref, True, err_msg="reference check") + + def test_euclidean_pdist(self): + a = np.arange(12, dtype=float).reshape(4, 3) + out = np.empty((a.shape[0] * (a.shape[0] - 1) // 2,), dtype=a.dtype) + umt.euclidean_pdist(a, out) + b = np.sqrt(np.sum((a[:, None] - a)**2, axis=-1)) + b = b[~np.tri(a.shape[0], dtype=bool)] + assert_almost_equal(out, b) + # An output array is required to determine p with signature (n,d)->(p) + assert_raises(ValueError, umt.euclidean_pdist, a) + + def test_cumsum(self): + a = np.arange(10) + result = umt.cumsum(a) + assert_array_equal(result, a.cumsum()) + + def test_object_logical(self): + a = np.array([3, None, True, False, "test", ""], dtype=object) + assert_equal(np.logical_or(a, None), + np.array([x or None for x in a], dtype=object)) + assert_equal(np.logical_or(a, True), + np.array([x or True for x in a], dtype=object)) + assert_equal(np.logical_or(a, 12), + np.array([x or 12 for x in a], dtype=object)) + assert_equal(np.logical_or(a, "blah"), + np.array([x or "blah" for x in a], dtype=object)) + + assert_equal(np.logical_and(a, None), + np.array([x and None for x in a], dtype=object)) + assert_equal(np.logical_and(a, True), + np.array([x and True for x in a], dtype=object)) + assert_equal(np.logical_and(a, 12), + np.array([x and 12 for x in a], dtype=object)) + assert_equal(np.logical_and(a, "blah"), + np.array([x and "blah" for x in a], dtype=object)) + + assert_equal(np.logical_not(a), + np.array([not x for x in a], dtype=object)) + + assert_equal(np.logical_or.reduce(a), 3) + assert_equal(np.logical_and.reduce(a), None) + + def test_object_comparison(self): + class HasComparisons: + def __eq__(self, other): + return '==' + + arr0d = np.array(HasComparisons()) + assert_equal(arr0d == arr0d, True) + assert_equal(np.equal(arr0d, arr0d), True) # normal behavior is a cast + + arr1d = np.array([HasComparisons()]) + assert_equal(arr1d == arr1d, np.array([True])) + assert_equal(np.equal(arr1d, arr1d), np.array([True])) # normal behavior is a cast + assert_equal(np.equal(arr1d, arr1d, dtype=object), np.array(['=='])) + + def test_object_array_reduction(self): + # Reductions on object arrays + a = np.array(['a', 'b', 'c'], dtype=object) + assert_equal(np.sum(a), 'abc') + assert_equal(np.max(a), 'c') + assert_equal(np.min(a), 'a') + a = np.array([True, False, True], dtype=object) + assert_equal(np.sum(a), 2) + assert_equal(np.prod(a), 0) + assert_equal(np.any(a), True) + assert_equal(np.all(a), False) + assert_equal(np.max(a), True) + assert_equal(np.min(a), False) + assert_equal(np.array([[1]], dtype=object).sum(), 1) + assert_equal(np.array([[[1, 2]]], dtype=object).sum((0, 1)), [1, 2]) + assert_equal(np.array([1], dtype=object).sum(initial=1), 2) + assert_equal(np.array([[1], [2, 3]], dtype=object) + .sum(initial=[0], where=[False, True]), [0, 2, 3]) + + def test_object_array_accumulate_inplace(self): + # Checks that in-place accumulates work, see also gh-7402 + arr = np.ones(4, dtype=object) + arr[:] = [[1] for i in range(4)] + # Twice reproduced also for tuples: + np.add.accumulate(arr, out=arr) + np.add.accumulate(arr, out=arr) + assert_array_equal(arr, + np.array([[1]*i for i in [1, 3, 6, 10]], dtype=object), + ) + + # And the same if the axis argument is used + arr = np.ones((2, 4), dtype=object) + arr[0, :] = [[2] for i in range(4)] + np.add.accumulate(arr, out=arr, axis=-1) + np.add.accumulate(arr, out=arr, axis=-1) + assert_array_equal(arr[0, :], + np.array([[2]*i for i in [1, 3, 6, 10]], dtype=object), + ) + + def test_object_array_reduceat_inplace(self): + # Checks that in-place reduceats work, see also gh-7465 + arr = np.empty(4, dtype=object) + arr[:] = [[1] for i in range(4)] + out = np.empty(4, dtype=object) + out[:] = [[1] for i in range(4)] + np.add.reduceat(arr, np.arange(4), out=arr) + np.add.reduceat(arr, np.arange(4), out=arr) + assert_array_equal(arr, out) + + # And the same if the axis argument is used + arr = np.ones((2, 4), dtype=object) + arr[0, :] = [[2] for i in range(4)] + out = np.ones((2, 4), dtype=object) + out[0, :] = [[2] for i in range(4)] + np.add.reduceat(arr, np.arange(4), out=arr, axis=-1) + np.add.reduceat(arr, np.arange(4), out=arr, axis=-1) + assert_array_equal(arr, out) + + def test_zerosize_reduction(self): + # Test with default dtype and object dtype + for a in [[], np.array([], dtype=object)]: + assert_equal(np.sum(a), 0) + assert_equal(np.prod(a), 1) + assert_equal(np.any(a), False) + assert_equal(np.all(a), True) + assert_raises(ValueError, np.max, a) + assert_raises(ValueError, np.min, a) + + def test_axis_out_of_bounds(self): + a = np.array([False, False]) + assert_raises(np.AxisError, a.all, axis=1) + a = np.array([False, False]) + assert_raises(np.AxisError, a.all, axis=-2) + + a = np.array([False, False]) + assert_raises(np.AxisError, a.any, axis=1) + a = np.array([False, False]) + assert_raises(np.AxisError, a.any, axis=-2) + + def test_scalar_reduction(self): + # The functions 'sum', 'prod', etc allow specifying axis=0 + # even for scalars + assert_equal(np.sum(3, axis=0), 3) + assert_equal(np.prod(3.5, axis=0), 3.5) + assert_equal(np.any(True, axis=0), True) + assert_equal(np.all(False, axis=0), False) + assert_equal(np.max(3, axis=0), 3) + assert_equal(np.min(2.5, axis=0), 2.5) + + # Check scalar behaviour for ufuncs without an identity + assert_equal(np.power.reduce(3), 3) + + # Make sure that scalars are coming out from this operation + assert_(type(np.prod(np.float32(2.5), axis=0)) is np.float32) + assert_(type(np.sum(np.float32(2.5), axis=0)) is np.float32) + assert_(type(np.max(np.float32(2.5), axis=0)) is np.float32) + assert_(type(np.min(np.float32(2.5), axis=0)) is np.float32) + + # check if scalars/0-d arrays get cast + assert_(type(np.any(0, axis=0)) is np.bool_) + + # assert that 0-d arrays get wrapped + class MyArray(np.ndarray): + pass + a = np.array(1).view(MyArray) + assert_(type(np.any(a)) is MyArray) + + def test_casting_out_param(self): + # Test that it's possible to do casts on output + a = np.ones((200, 100), np.int64) + b = np.ones((200, 100), np.int64) + c = np.ones((200, 100), np.float64) + np.add(a, b, out=c) + assert_equal(c, 2) + + a = np.zeros(65536) + b = np.zeros(65536, dtype=np.float32) + np.subtract(a, 0, out=b) + assert_equal(b, 0) + + def test_where_param(self): + # Test that the where= ufunc parameter works with regular arrays + a = np.arange(7) + b = np.ones(7) + c = np.zeros(7) + np.add(a, b, out=c, where=(a % 2 == 1)) + assert_equal(c, [0, 2, 0, 4, 0, 6, 0]) + + a = np.arange(4).reshape(2, 2) + 2 + np.power(a, [2, 3], out=a, where=[[0, 1], [1, 0]]) + assert_equal(a, [[2, 27], [16, 5]]) + # Broadcasting the where= parameter + np.subtract(a, 2, out=a, where=[True, False]) + assert_equal(a, [[0, 27], [14, 5]]) + + def test_where_param_buffer_output(self): + # This test is temporarily skipped because it requires + # adding masking features to the nditer to work properly + + # With casting on output + a = np.ones(10, np.int64) + b = np.ones(10, np.int64) + c = 1.5 * np.ones(10, np.float64) + np.add(a, b, out=c, where=[1, 0, 0, 1, 0, 0, 1, 1, 1, 0]) + assert_equal(c, [2, 1.5, 1.5, 2, 1.5, 1.5, 2, 2, 2, 1.5]) + + def test_where_param_alloc(self): + # With casting and allocated output + a = np.array([1], dtype=np.int64) + m = np.array([True], dtype=bool) + assert_equal(np.sqrt(a, where=m), [1]) + + # No casting and allocated output + a = np.array([1], dtype=np.float64) + m = np.array([True], dtype=bool) + assert_equal(np.sqrt(a, where=m), [1]) + + def test_where_with_broadcasting(self): + # See gh-17198 + a = np.random.random((5000, 4)) + b = np.random.random((5000, 1)) + + where = a > 0.3 + out = np.full_like(a, 0) + np.less(a, b, where=where, out=out) + b_where = np.broadcast_to(b, a.shape)[where] + assert_array_equal((a[where] < b_where), out[where].astype(bool)) + assert not out[~where].any() # outside mask, out remains all 0 + + def check_identityless_reduction(self, a): + # np.minimum.reduce is an identityless reduction + + # Verify that it sees the zero at various positions + a[...] = 1 + a[1, 0, 0] = 0 + assert_equal(np.minimum.reduce(a, axis=None), 0) + assert_equal(np.minimum.reduce(a, axis=(0, 1)), [0, 1, 1, 1]) + assert_equal(np.minimum.reduce(a, axis=(0, 2)), [0, 1, 1]) + assert_equal(np.minimum.reduce(a, axis=(1, 2)), [1, 0]) + assert_equal(np.minimum.reduce(a, axis=0), + [[0, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1]]) + assert_equal(np.minimum.reduce(a, axis=1), + [[1, 1, 1, 1], [0, 1, 1, 1]]) + assert_equal(np.minimum.reduce(a, axis=2), + [[1, 1, 1], [0, 1, 1]]) + assert_equal(np.minimum.reduce(a, axis=()), a) + + a[...] = 1 + a[0, 1, 0] = 0 + assert_equal(np.minimum.reduce(a, axis=None), 0) + assert_equal(np.minimum.reduce(a, axis=(0, 1)), [0, 1, 1, 1]) + assert_equal(np.minimum.reduce(a, axis=(0, 2)), [1, 0, 1]) + assert_equal(np.minimum.reduce(a, axis=(1, 2)), [0, 1]) + assert_equal(np.minimum.reduce(a, axis=0), + [[1, 1, 1, 1], [0, 1, 1, 1], [1, 1, 1, 1]]) + assert_equal(np.minimum.reduce(a, axis=1), + [[0, 1, 1, 1], [1, 1, 1, 1]]) + assert_equal(np.minimum.reduce(a, axis=2), + [[1, 0, 1], [1, 1, 1]]) + assert_equal(np.minimum.reduce(a, axis=()), a) + + a[...] = 1 + a[0, 0, 1] = 0 + assert_equal(np.minimum.reduce(a, axis=None), 0) + assert_equal(np.minimum.reduce(a, axis=(0, 1)), [1, 0, 1, 1]) + assert_equal(np.minimum.reduce(a, axis=(0, 2)), [0, 1, 1]) + assert_equal(np.minimum.reduce(a, axis=(1, 2)), [0, 1]) + assert_equal(np.minimum.reduce(a, axis=0), + [[1, 0, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1]]) + assert_equal(np.minimum.reduce(a, axis=1), + [[1, 0, 1, 1], [1, 1, 1, 1]]) + assert_equal(np.minimum.reduce(a, axis=2), + [[0, 1, 1], [1, 1, 1]]) + assert_equal(np.minimum.reduce(a, axis=()), a) + + def test_identityless_reduction_corder(self): + a = np.empty((2, 3, 4), order='C') + self.check_identityless_reduction(a) + + def test_identityless_reduction_forder(self): + a = np.empty((2, 3, 4), order='F') + self.check_identityless_reduction(a) + + def test_identityless_reduction_otherorder(self): + a = np.empty((2, 4, 3), order='C').swapaxes(1, 2) + self.check_identityless_reduction(a) + + def test_identityless_reduction_noncontig(self): + a = np.empty((3, 5, 4), order='C').swapaxes(1, 2) + a = a[1:, 1:, 1:] + self.check_identityless_reduction(a) + + def test_identityless_reduction_noncontig_unaligned(self): + a = np.empty((3*4*5*8 + 1,), dtype='i1') + a = a[1:].view(dtype='f8') + a.shape = (3, 4, 5) + a = a[1:, 1:, 1:] + self.check_identityless_reduction(a) + + def test_initial_reduction(self): + # np.minimum.reduce is an identityless reduction + + # For cases like np.maximum(np.abs(...), initial=0) + # More generally, a supremum over non-negative numbers. + assert_equal(np.maximum.reduce([], initial=0), 0) + + # For cases like reduction of an empty array over the reals. + assert_equal(np.minimum.reduce([], initial=np.inf), np.inf) + assert_equal(np.maximum.reduce([], initial=-np.inf), -np.inf) + + # Random tests + assert_equal(np.minimum.reduce([5], initial=4), 4) + assert_equal(np.maximum.reduce([4], initial=5), 5) + assert_equal(np.maximum.reduce([5], initial=4), 5) + assert_equal(np.minimum.reduce([4], initial=5), 4) + + # Check initial=None raises ValueError for both types of ufunc reductions + assert_raises(ValueError, np.minimum.reduce, [], initial=None) + assert_raises(ValueError, np.add.reduce, [], initial=None) + + # Check that np._NoValue gives default behavior. + assert_equal(np.add.reduce([], initial=np._NoValue), 0) + + # Check that initial kwarg behaves as intended for dtype=object + a = np.array([10], dtype=object) + res = np.add.reduce(a, initial=5) + assert_equal(res, 15) + + @pytest.mark.parametrize('axis', (0, 1, None)) + @pytest.mark.parametrize('where', (np.array([False, True, True]), + np.array([[True], [False], [True]]), + np.array([[True, False, False], + [False, True, False], + [False, True, True]]))) + def test_reduction_with_where(self, axis, where): + a = np.arange(9.).reshape(3, 3) + a_copy = a.copy() + a_check = np.zeros_like(a) + np.positive(a, out=a_check, where=where) + + res = np.add.reduce(a, axis=axis, where=where) + check = a_check.sum(axis) + assert_equal(res, check) + # Check we do not overwrite elements of a internally. + assert_array_equal(a, a_copy) + + @pytest.mark.parametrize(('axis', 'where'), + ((0, np.array([True, False, True])), + (1, [True, True, False]), + (None, True))) + @pytest.mark.parametrize('initial', (-np.inf, 5.)) + def test_reduction_with_where_and_initial(self, axis, where, initial): + a = np.arange(9.).reshape(3, 3) + a_copy = a.copy() + a_check = np.full(a.shape, -np.inf) + np.positive(a, out=a_check, where=where) + + res = np.maximum.reduce(a, axis=axis, where=where, initial=initial) + check = a_check.max(axis, initial=initial) + assert_equal(res, check) + + def test_reduction_where_initial_needed(self): + a = np.arange(9.).reshape(3, 3) + m = [False, True, False] + assert_raises(ValueError, np.maximum.reduce, a, where=m) + + def test_identityless_reduction_nonreorderable(self): + a = np.array([[8.0, 2.0, 2.0], [1.0, 0.5, 0.25]]) + + res = np.divide.reduce(a, axis=0) + assert_equal(res, [8.0, 4.0, 8.0]) + + res = np.divide.reduce(a, axis=1) + assert_equal(res, [2.0, 8.0]) + + res = np.divide.reduce(a, axis=()) + assert_equal(res, a) + + assert_raises(ValueError, np.divide.reduce, a, axis=(0, 1)) + + def test_reduce_zero_axis(self): + # If we have a n x m array and do a reduction with axis=1, then we are + # doing n reductions, and each reduction takes an m-element array. For + # a reduction operation without an identity, then: + # n > 0, m > 0: fine + # n = 0, m > 0: fine, doing 0 reductions of m-element arrays + # n > 0, m = 0: can't reduce a 0-element array, ValueError + # n = 0, m = 0: can't reduce a 0-element array, ValueError (for + # consistency with the above case) + # This test doesn't actually look at return values, it just checks to + # make sure that error we get an error in exactly those cases where we + # expect one, and assumes the calculations themselves are done + # correctly. + + def ok(f, *args, **kwargs): + f(*args, **kwargs) + + def err(f, *args, **kwargs): + assert_raises(ValueError, f, *args, **kwargs) + + def t(expect, func, n, m): + expect(func, np.zeros((n, m)), axis=1) + expect(func, np.zeros((m, n)), axis=0) + expect(func, np.zeros((n // 2, n // 2, m)), axis=2) + expect(func, np.zeros((n // 2, m, n // 2)), axis=1) + expect(func, np.zeros((n, m // 2, m // 2)), axis=(1, 2)) + expect(func, np.zeros((m // 2, n, m // 2)), axis=(0, 2)) + expect(func, np.zeros((m // 3, m // 3, m // 3, + n // 2, n // 2)), + axis=(0, 1, 2)) + # Check what happens if the inner (resp. outer) dimensions are a + # mix of zero and non-zero: + expect(func, np.zeros((10, m, n)), axis=(0, 1)) + expect(func, np.zeros((10, n, m)), axis=(0, 2)) + expect(func, np.zeros((m, 10, n)), axis=0) + expect(func, np.zeros((10, m, n)), axis=1) + expect(func, np.zeros((10, n, m)), axis=2) + + # np.maximum is just an arbitrary ufunc with no reduction identity + assert_equal(np.maximum.identity, None) + t(ok, np.maximum.reduce, 30, 30) + t(ok, np.maximum.reduce, 0, 30) + t(err, np.maximum.reduce, 30, 0) + t(err, np.maximum.reduce, 0, 0) + err(np.maximum.reduce, []) + np.maximum.reduce(np.zeros((0, 0)), axis=()) + + # all of the combinations are fine for a reduction that has an + # identity + t(ok, np.add.reduce, 30, 30) + t(ok, np.add.reduce, 0, 30) + t(ok, np.add.reduce, 30, 0) + t(ok, np.add.reduce, 0, 0) + np.add.reduce([]) + np.add.reduce(np.zeros((0, 0)), axis=()) + + # OTOH, accumulate always makes sense for any combination of n and m, + # because it maps an m-element array to an m-element array. These + # tests are simpler because accumulate doesn't accept multiple axes. + for uf in (np.maximum, np.add): + uf.accumulate(np.zeros((30, 0)), axis=0) + uf.accumulate(np.zeros((0, 30)), axis=0) + uf.accumulate(np.zeros((30, 30)), axis=0) + uf.accumulate(np.zeros((0, 0)), axis=0) + + def test_safe_casting(self): + # In old versions of numpy, in-place operations used the 'unsafe' + # casting rules. In versions >= 1.10, 'same_kind' is the + # default and an exception is raised instead of a warning. + # when 'same_kind' is not satisfied. + a = np.array([1, 2, 3], dtype=int) + # Non-in-place addition is fine + assert_array_equal(assert_no_warnings(np.add, a, 1.1), + [2.1, 3.1, 4.1]) + assert_raises(TypeError, np.add, a, 1.1, out=a) + + def add_inplace(a, b): + a += b + + assert_raises(TypeError, add_inplace, a, 1.1) + # Make sure that explicitly overriding the exception is allowed: + assert_no_warnings(np.add, a, 1.1, out=a, casting="unsafe") + assert_array_equal(a, [2, 3, 4]) + + def test_ufunc_custom_out(self): + # Test ufunc with built in input types and custom output type + + a = np.array([0, 1, 2], dtype='i8') + b = np.array([0, 1, 2], dtype='i8') + c = np.empty(3, dtype=_rational_tests.rational) + + # Output must be specified so numpy knows what + # ufunc signature to look for + result = _rational_tests.test_add(a, b, c) + target = np.array([0, 2, 4], dtype=_rational_tests.rational) + assert_equal(result, target) + + # no output type should raise TypeError + with assert_raises(TypeError): + _rational_tests.test_add(a, b) + + def test_operand_flags(self): + a = np.arange(16, dtype='l').reshape(4, 4) + b = np.arange(9, dtype='l').reshape(3, 3) + opflag_tests.inplace_add(a[:-1, :-1], b) + assert_equal(a, np.array([[0, 2, 4, 3], [7, 9, 11, 7], + [14, 16, 18, 11], [12, 13, 14, 15]], dtype='l')) + + a = np.array(0) + opflag_tests.inplace_add(a, 3) + assert_equal(a, 3) + opflag_tests.inplace_add(a, [3, 4]) + assert_equal(a, 10) + + def test_struct_ufunc(self): + import numpy.core._struct_ufunc_tests as struct_ufunc + + a = np.array([(1, 2, 3)], dtype='u8,u8,u8') + b = np.array([(1, 2, 3)], dtype='u8,u8,u8') + + result = struct_ufunc.add_triplet(a, b) + assert_equal(result, np.array([(2, 4, 6)], dtype='u8,u8,u8')) + assert_raises(RuntimeError, struct_ufunc.register_fail) + + def test_custom_ufunc(self): + a = np.array( + [_rational_tests.rational(1, 2), + _rational_tests.rational(1, 3), + _rational_tests.rational(1, 4)], + dtype=_rational_tests.rational) + b = np.array( + [_rational_tests.rational(1, 2), + _rational_tests.rational(1, 3), + _rational_tests.rational(1, 4)], + dtype=_rational_tests.rational) + + result = _rational_tests.test_add_rationals(a, b) + expected = np.array( + [_rational_tests.rational(1), + _rational_tests.rational(2, 3), + _rational_tests.rational(1, 2)], + dtype=_rational_tests.rational) + assert_equal(result, expected) + + def test_custom_ufunc_forced_sig(self): + # gh-9351 - looking for a non-first userloop would previously hang + with assert_raises(TypeError): + np.multiply(_rational_tests.rational(1), 1, + signature=(_rational_tests.rational, int, None)) + + def test_custom_array_like(self): + + class MyThing: + __array_priority__ = 1000 + + rmul_count = 0 + getitem_count = 0 + + def __init__(self, shape): + self.shape = shape + + def __len__(self): + return self.shape[0] + + def __getitem__(self, i): + MyThing.getitem_count += 1 + if not isinstance(i, tuple): + i = (i,) + if len(i) > self.ndim: + raise IndexError("boo") + + return MyThing(self.shape[len(i):]) + + def __rmul__(self, other): + MyThing.rmul_count += 1 + return self + + np.float64(5)*MyThing((3, 3)) + assert_(MyThing.rmul_count == 1, MyThing.rmul_count) + assert_(MyThing.getitem_count <= 2, MyThing.getitem_count) + + def test_inplace_fancy_indexing(self): + + a = np.arange(10) + np.add.at(a, [2, 5, 2], 1) + assert_equal(a, [0, 1, 4, 3, 4, 6, 6, 7, 8, 9]) + + a = np.arange(10) + b = np.array([100, 100, 100]) + np.add.at(a, [2, 5, 2], b) + assert_equal(a, [0, 1, 202, 3, 4, 105, 6, 7, 8, 9]) + + a = np.arange(9).reshape(3, 3) + b = np.array([[100, 100, 100], [200, 200, 200], [300, 300, 300]]) + np.add.at(a, (slice(None), [1, 2, 1]), b) + assert_equal(a, [[0, 201, 102], [3, 404, 205], [6, 607, 308]]) + + a = np.arange(27).reshape(3, 3, 3) + b = np.array([100, 200, 300]) + np.add.at(a, (slice(None), slice(None), [1, 2, 1]), b) + assert_equal(a, + [[[0, 401, 202], + [3, 404, 205], + [6, 407, 208]], + + [[9, 410, 211], + [12, 413, 214], + [15, 416, 217]], + + [[18, 419, 220], + [21, 422, 223], + [24, 425, 226]]]) + + a = np.arange(9).reshape(3, 3) + b = np.array([[100, 100, 100], [200, 200, 200], [300, 300, 300]]) + np.add.at(a, ([1, 2, 1], slice(None)), b) + assert_equal(a, [[0, 1, 2], [403, 404, 405], [206, 207, 208]]) + + a = np.arange(27).reshape(3, 3, 3) + b = np.array([100, 200, 300]) + np.add.at(a, (slice(None), [1, 2, 1], slice(None)), b) + assert_equal(a, + [[[0, 1, 2], + [203, 404, 605], + [106, 207, 308]], + + [[9, 10, 11], + [212, 413, 614], + [115, 216, 317]], + + [[18, 19, 20], + [221, 422, 623], + [124, 225, 326]]]) + + a = np.arange(9).reshape(3, 3) + b = np.array([100, 200, 300]) + np.add.at(a, (0, [1, 2, 1]), b) + assert_equal(a, [[0, 401, 202], [3, 4, 5], [6, 7, 8]]) + + a = np.arange(27).reshape(3, 3, 3) + b = np.array([100, 200, 300]) + np.add.at(a, ([1, 2, 1], 0, slice(None)), b) + assert_equal(a, + [[[0, 1, 2], + [3, 4, 5], + [6, 7, 8]], + + [[209, 410, 611], + [12, 13, 14], + [15, 16, 17]], + + [[118, 219, 320], + [21, 22, 23], + [24, 25, 26]]]) + + a = np.arange(27).reshape(3, 3, 3) + b = np.array([100, 200, 300]) + np.add.at(a, (slice(None), slice(None), slice(None)), b) + assert_equal(a, + [[[100, 201, 302], + [103, 204, 305], + [106, 207, 308]], + + [[109, 210, 311], + [112, 213, 314], + [115, 216, 317]], + + [[118, 219, 320], + [121, 222, 323], + [124, 225, 326]]]) + + a = np.arange(10) + np.negative.at(a, [2, 5, 2]) + assert_equal(a, [0, 1, 2, 3, 4, -5, 6, 7, 8, 9]) + + # Test 0-dim array + a = np.array(0) + np.add.at(a, (), 1) + assert_equal(a, 1) + + assert_raises(IndexError, np.add.at, a, 0, 1) + assert_raises(IndexError, np.add.at, a, [], 1) + + # Test mixed dtypes + a = np.arange(10) + np.power.at(a, [1, 2, 3, 2], 3.5) + assert_equal(a, np.array([0, 1, 4414, 46, 4, 5, 6, 7, 8, 9])) + + # Test boolean indexing and boolean ufuncs + a = np.arange(10) + index = a % 2 == 0 + np.equal.at(a, index, [0, 2, 4, 6, 8]) + assert_equal(a, [1, 1, 1, 3, 1, 5, 1, 7, 1, 9]) + + # Test unary operator + a = np.arange(10, dtype='u4') + np.invert.at(a, [2, 5, 2]) + assert_equal(a, [0, 1, 2, 3, 4, 5 ^ 0xffffffff, 6, 7, 8, 9]) + + # Test empty subspace + orig = np.arange(4) + a = orig[:, None][:, 0:0] + np.add.at(a, [0, 1], 3) + assert_array_equal(orig, np.arange(4)) + + # Test with swapped byte order + index = np.array([1, 2, 1], np.dtype('i').newbyteorder()) + values = np.array([1, 2, 3, 4], np.dtype('f').newbyteorder()) + np.add.at(values, index, 3) + assert_array_equal(values, [1, 8, 6, 4]) + + # Test exception thrown + values = np.array(['a', 1], dtype=object) + assert_raises(TypeError, np.add.at, values, [0, 1], 1) + assert_array_equal(values, np.array(['a', 1], dtype=object)) + + # Test multiple output ufuncs raise error, gh-5665 + assert_raises(ValueError, np.modf.at, np.arange(10), [1]) + + def test_reduce_arguments(self): + f = np.add.reduce + d = np.ones((5,2), dtype=int) + o = np.ones((2,), dtype=d.dtype) + r = o * 5 + assert_equal(f(d), r) + # a, axis=0, dtype=None, out=None, keepdims=False + assert_equal(f(d, axis=0), r) + assert_equal(f(d, 0), r) + assert_equal(f(d, 0, dtype=None), r) + assert_equal(f(d, 0, dtype='i'), r) + assert_equal(f(d, 0, 'i'), r) + assert_equal(f(d, 0, None), r) + assert_equal(f(d, 0, None, out=None), r) + assert_equal(f(d, 0, None, out=o), r) + assert_equal(f(d, 0, None, o), r) + assert_equal(f(d, 0, None, None), r) + assert_equal(f(d, 0, None, None, keepdims=False), r) + assert_equal(f(d, 0, None, None, True), r.reshape((1,) + r.shape)) + assert_equal(f(d, 0, None, None, False, 0), r) + assert_equal(f(d, 0, None, None, False, initial=0), r) + assert_equal(f(d, 0, None, None, False, 0, True), r) + assert_equal(f(d, 0, None, None, False, 0, where=True), r) + # multiple keywords + assert_equal(f(d, axis=0, dtype=None, out=None, keepdims=False), r) + assert_equal(f(d, 0, dtype=None, out=None, keepdims=False), r) + assert_equal(f(d, 0, None, out=None, keepdims=False), r) + assert_equal(f(d, 0, None, out=None, keepdims=False, initial=0, + where=True), r) + + # too little + assert_raises(TypeError, f) + # too much + assert_raises(TypeError, f, d, 0, None, None, False, 0, True, 1) + # invalid axis + assert_raises(TypeError, f, d, "invalid") + assert_raises(TypeError, f, d, axis="invalid") + assert_raises(TypeError, f, d, axis="invalid", dtype=None, + keepdims=True) + # invalid dtype + assert_raises(TypeError, f, d, 0, "invalid") + assert_raises(TypeError, f, d, dtype="invalid") + assert_raises(TypeError, f, d, dtype="invalid", out=None) + # invalid out + assert_raises(TypeError, f, d, 0, None, "invalid") + assert_raises(TypeError, f, d, out="invalid") + assert_raises(TypeError, f, d, out="invalid", dtype=None) + # keepdims boolean, no invalid value + # assert_raises(TypeError, f, d, 0, None, None, "invalid") + # assert_raises(TypeError, f, d, keepdims="invalid", axis=0, dtype=None) + # invalid mix + assert_raises(TypeError, f, d, 0, keepdims="invalid", dtype="invalid", + out=None) + + # invalid keyword + assert_raises(TypeError, f, d, axis=0, dtype=None, invalid=0) + assert_raises(TypeError, f, d, invalid=0) + assert_raises(TypeError, f, d, 0, keepdims=True, invalid="invalid", + out=None) + assert_raises(TypeError, f, d, axis=0, dtype=None, keepdims=True, + out=None, invalid=0) + assert_raises(TypeError, f, d, axis=0, dtype=None, + out=None, invalid=0) + + def test_structured_equal(self): + # https://github.com/numpy/numpy/issues/4855 + + class MyA(np.ndarray): + def __array_ufunc__(self, ufunc, method, *inputs, **kwargs): + return getattr(ufunc, method)(*(input.view(np.ndarray) + for input in inputs), **kwargs) + a = np.arange(12.).reshape(4,3) + ra = a.view(dtype=('f8,f8,f8')).squeeze() + mra = ra.view(MyA) + + target = np.array([ True, False, False, False], dtype=bool) + assert_equal(np.all(target == (mra == ra[0])), True) + + def test_scalar_equal(self): + # Scalar comparisons should always work, without deprecation warnings. + # even when the ufunc fails. + a = np.array(0.) + b = np.array('a') + assert_(a != b) + assert_(b != a) + assert_(not (a == b)) + assert_(not (b == a)) + + def test_NotImplemented_not_returned(self): + # See gh-5964 and gh-2091. Some of these functions are not operator + # related and were fixed for other reasons in the past. + binary_funcs = [ + np.power, np.add, np.subtract, np.multiply, np.divide, + np.true_divide, np.floor_divide, np.bitwise_and, np.bitwise_or, + np.bitwise_xor, np.left_shift, np.right_shift, np.fmax, + np.fmin, np.fmod, np.hypot, np.logaddexp, np.logaddexp2, + np.logical_and, np.logical_or, np.logical_xor, np.maximum, + np.minimum, np.mod, + np.greater, np.greater_equal, np.less, np.less_equal, + np.equal, np.not_equal] + + a = np.array('1') + b = 1 + c = np.array([1., 2.]) + for f in binary_funcs: + assert_raises(TypeError, f, a, b) + assert_raises(TypeError, f, c, a) + + def test_reduce_noncontig_output(self): + # Check that reduction deals with non-contiguous output arrays + # appropriately. + # + # gh-8036 + + x = np.arange(7*13*8, dtype=np.int16).reshape(7, 13, 8) + x = x[4:6,1:11:6,1:5].transpose(1, 2, 0) + y_base = np.arange(4*4, dtype=np.int16).reshape(4, 4) + y = y_base[::2,:] + + y_base_copy = y_base.copy() + + r0 = np.add.reduce(x, out=y.copy(), axis=2) + r1 = np.add.reduce(x, out=y, axis=2) + + # The results should match, and y_base shouldn't get clobbered + assert_equal(r0, r1) + assert_equal(y_base[1,:], y_base_copy[1,:]) + assert_equal(y_base[3,:], y_base_copy[3,:]) + + @pytest.mark.parametrize('out_shape', + [(), (1,), (3,), (1, 1), (1, 3), (4, 3)]) + @pytest.mark.parametrize('keepdims', [True, False]) + @pytest.mark.parametrize('f_reduce', [np.add.reduce, np.minimum.reduce]) + def test_reduce_wrong_dimension_output(self, f_reduce, keepdims, out_shape): + # Test that we're not incorrectly broadcasting dimensions. + # See gh-15144 (failed for np.add.reduce previously). + a = np.arange(12.).reshape(4, 3) + out = np.empty(out_shape, a.dtype) + + correct_out = f_reduce(a, axis=0, keepdims=keepdims) + if out_shape != correct_out.shape: + with assert_raises(ValueError): + f_reduce(a, axis=0, out=out, keepdims=keepdims) + else: + check = f_reduce(a, axis=0, out=out, keepdims=keepdims) + assert_(check is out) + assert_array_equal(check, correct_out) + + def test_reduce_output_does_not_broadcast_input(self): + # Test that the output shape cannot broadcast an input dimension + # (it never can add dimensions, but it might expand an existing one) + a = np.ones((1, 10)) + out_correct = (np.empty((1, 1))) + out_incorrect = np.empty((3, 1)) + np.add.reduce(a, axis=-1, out=out_correct, keepdims=True) + np.add.reduce(a, axis=-1, out=out_correct[:, 0], keepdims=False) + with assert_raises(ValueError): + np.add.reduce(a, axis=-1, out=out_incorrect, keepdims=True) + with assert_raises(ValueError): + np.add.reduce(a, axis=-1, out=out_incorrect[:, 0], keepdims=False) + + def test_reduce_output_subclass_ok(self): + class MyArr(np.ndarray): + pass + + out = np.empty(()) + np.add.reduce(np.ones(5), out=out) # no subclass, all fine + out = out.view(MyArr) + assert np.add.reduce(np.ones(5), out=out) is out + assert type(np.add.reduce(out)) is MyArr + + def test_no_doc_string(self): + # gh-9337 + assert_('\n' not in umt.inner1d_no_doc.__doc__) + + def test_invalid_args(self): + # gh-7961 + exc = pytest.raises(TypeError, np.sqrt, None) + # minimally check the exception text + assert exc.match('loop of ufunc does not support') + + @pytest.mark.parametrize('nat', [np.datetime64('nat'), np.timedelta64('nat')]) + def test_nat_is_not_finite(self, nat): + try: + assert not np.isfinite(nat) + except TypeError: + pass # ok, just not implemented + + @pytest.mark.parametrize('nat', [np.datetime64('nat'), np.timedelta64('nat')]) + def test_nat_is_nan(self, nat): + try: + assert np.isnan(nat) + except TypeError: + pass # ok, just not implemented + + @pytest.mark.parametrize('nat', [np.datetime64('nat'), np.timedelta64('nat')]) + def test_nat_is_not_inf(self, nat): + try: + assert not np.isinf(nat) + except TypeError: + pass # ok, just not implemented + + +@pytest.mark.parametrize('ufunc', [getattr(np, x) for x in dir(np) + if isinstance(getattr(np, x), np.ufunc)]) +def test_ufunc_types(ufunc): + ''' + Check all ufuncs that the correct type is returned. Avoid + object and boolean types since many operations are not defined for + for them. + + Choose the shape so even dot and matmul will succeed + ''' + for typ in ufunc.types: + # types is a list of strings like ii->i + if 'O' in typ or '?' in typ: + continue + inp, out = typ.split('->') + args = [np.ones((3, 3), t) for t in inp] + with warnings.catch_warnings(record=True): + warnings.filterwarnings("always") + res = ufunc(*args) + if isinstance(res, tuple): + outs = tuple(out) + assert len(res) == len(outs) + for r, t in zip(res, outs): + assert r.dtype == np.dtype(t) + else: + assert res.dtype == np.dtype(out) + +@pytest.mark.parametrize('ufunc', [getattr(np, x) for x in dir(np) + if isinstance(getattr(np, x), np.ufunc)]) +def test_ufunc_noncontiguous(ufunc): + ''' + Check that contiguous and non-contiguous calls to ufuncs + have the same results for values in range(9) + ''' + for typ in ufunc.types: + # types is a list of strings like ii->i + if any(set('O?mM') & set(typ)): + # bool, object, datetime are too irregular for this simple test + continue + inp, out = typ.split('->') + args_c = [np.empty(6, t) for t in inp] + args_n = [np.empty(18, t)[::3] for t in inp] + for a in args_c: + a.flat = range(1,7) + for a in args_n: + a.flat = range(1,7) + with warnings.catch_warnings(record=True): + warnings.filterwarnings("always") + res_c = ufunc(*args_c) + res_n = ufunc(*args_n) + if len(out) == 1: + res_c = (res_c,) + res_n = (res_n,) + for c_ar, n_ar in zip(res_c, res_n): + dt = c_ar.dtype + if np.issubdtype(dt, np.floating): + # for floating point results allow a small fuss in comparisons + # since different algorithms (libm vs. intrinsics) can be used + # for different input strides + res_eps = np.finfo(dt).eps + tol = 2*res_eps + assert_allclose(res_c, res_n, atol=tol, rtol=tol) + else: + assert_equal(c_ar, n_ar) + + +@pytest.mark.parametrize('ufunc', [np.sign, np.equal]) +def test_ufunc_warn_with_nan(ufunc): + # issue gh-15127 + # test that calling certain ufuncs with a non-standard `nan` value does not + # emit a warning + # `b` holds a 64 bit signaling nan: the most significant bit of the + # significand is zero. + b = np.array([0x7ff0000000000001], 'i8').view('f8') + assert np.isnan(b) + if ufunc.nin == 1: + ufunc(b) + elif ufunc.nin == 2: + ufunc(b, b.copy()) + else: + raise ValueError('ufunc with more than 2 inputs') + + +@pytest.mark.skipif(not HAS_REFCOUNT, reason="Python lacks refcounts") +def test_ufunc_casterrors(): + # Tests that casting errors are correctly reported and buffers are + # cleared. + # The following array can be added to itself as an object array, but + # the result cannot be cast to an integer output: + value = 123 # relies on python cache (leak-check will still find it) + arr = np.array([value] * int(np.BUFSIZE * 1.5) + + ["string"] + + [value] * int(1.5 * np.BUFSIZE), dtype=object) + out = np.ones(len(arr), dtype=np.intp) + + count = sys.getrefcount(value) + with pytest.raises(ValueError): + # Output casting failure: + np.add(arr, arr, out=out, casting="unsafe") + + assert count == sys.getrefcount(value) + # output is unchanged after the error, this shows that the iteration + # was aborted (this is not necessarily defined behaviour) + assert out[-1] == 1 + + with pytest.raises(ValueError): + # Input casting failure: + np.add(arr, arr, out=out, dtype=np.intp, casting="unsafe") + + assert count == sys.getrefcount(value) + # output is unchanged after the error, this shows that the iteration + # was aborted (this is not necessarily defined behaviour) + assert out[-1] == 1 + + +@pytest.mark.skipif(not HAS_REFCOUNT, reason="Python lacks refcounts") +@pytest.mark.parametrize("offset", + [0, np.BUFSIZE//2, int(1.5*np.BUFSIZE)]) +def test_reduce_casterrors(offset): + # Test reporting of casting errors in reductions, we test various + # offsets to where the casting error will occur, since these may occur + # at different places during the reduction procedure. For example + # the first item may be special. + value = 123 # relies on python cache (leak-check will still find it) + arr = np.array([value] * offset + + ["string"] + + [value] * int(1.5 * np.BUFSIZE), dtype=object) + out = np.array(-1, dtype=np.intp) + + count = sys.getrefcount(value) + with pytest.raises(ValueError): + # This is an unsafe cast, but we currently always allow that: + np.add.reduce(arr, dtype=np.intp, out=out) + assert count == sys.getrefcount(value) + # If an error occurred during casting, the operation is done at most until + # the error occurs (the result of which would be `value * offset`) and -1 + # if the error happened immediately. + # This does not define behaviour, the output is invalid and thus undefined + assert out[()] < value * offset diff --git a/venv/Lib/site-packages/numpy/core/tests/test_umath.py b/venv/Lib/site-packages/numpy/core/tests/test_umath.py new file mode 100644 index 0000000..858dac4 --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/tests/test_umath.py @@ -0,0 +1,3473 @@ +import platform +import warnings +import fnmatch +import itertools +import pytest +import sys +from fractions import Fraction + +import numpy.core.umath as ncu +from numpy.core import _umath_tests as ncu_tests +import numpy as np +from numpy.testing import ( + assert_, assert_equal, assert_raises, assert_raises_regex, + assert_array_equal, assert_almost_equal, assert_array_almost_equal, + assert_array_max_ulp, assert_allclose, assert_no_warnings, suppress_warnings, + _gen_alignment_data, assert_array_almost_equal_nulp, assert_warns + ) + +def on_powerpc(): + """ True if we are running on a Power PC platform.""" + return platform.processor() == 'powerpc' or \ + platform.machine().startswith('ppc') + + +def bad_arcsinh(): + """The blocklisted trig functions are not accurate on aarch64 for + complex256. Rather than dig through the actual problem skip the + test. This should be fixed when we can move past glibc2.17 + which is the version in manylinux2014 + """ + x = 1.78e-10 + v1 = np.arcsinh(np.float128(x)) + v2 = np.arcsinh(np.complex256(x)).real + # The eps for float128 is 1-e33, so this is way bigger + return abs((v1 / v2) - 1.0) > 1e-23 + +if platform.machine() == 'aarch64' and bad_arcsinh(): + skip_longcomplex_msg = ('Trig functions of np.longcomplex values known to be ' + 'inaccurate on aarch64 for some compilation ' + 'configurations, should be fixed by building on a ' + 'platform using glibc>2.17') +else: + skip_longcomplex_msg = '' + + +class _FilterInvalids: + def setup(self): + self.olderr = np.seterr(invalid='ignore') + + def teardown(self): + np.seterr(**self.olderr) + + +class TestConstants: + def test_pi(self): + assert_allclose(ncu.pi, 3.141592653589793, 1e-15) + + def test_e(self): + assert_allclose(ncu.e, 2.718281828459045, 1e-15) + + def test_euler_gamma(self): + assert_allclose(ncu.euler_gamma, 0.5772156649015329, 1e-15) + + +class TestOut: + def test_out_subok(self): + for subok in (True, False): + a = np.array(0.5) + o = np.empty(()) + + r = np.add(a, 2, o, subok=subok) + assert_(r is o) + r = np.add(a, 2, out=o, subok=subok) + assert_(r is o) + r = np.add(a, 2, out=(o,), subok=subok) + assert_(r is o) + + d = np.array(5.7) + o1 = np.empty(()) + o2 = np.empty((), dtype=np.int32) + + r1, r2 = np.frexp(d, o1, None, subok=subok) + assert_(r1 is o1) + r1, r2 = np.frexp(d, None, o2, subok=subok) + assert_(r2 is o2) + r1, r2 = np.frexp(d, o1, o2, subok=subok) + assert_(r1 is o1) + assert_(r2 is o2) + + r1, r2 = np.frexp(d, out=(o1, None), subok=subok) + assert_(r1 is o1) + r1, r2 = np.frexp(d, out=(None, o2), subok=subok) + assert_(r2 is o2) + r1, r2 = np.frexp(d, out=(o1, o2), subok=subok) + assert_(r1 is o1) + assert_(r2 is o2) + + with assert_raises(TypeError): + # Out argument must be tuple, since there are multiple outputs. + r1, r2 = np.frexp(d, out=o1, subok=subok) + + assert_raises(ValueError, np.add, a, 2, o, o, subok=subok) + assert_raises(ValueError, np.add, a, 2, o, out=o, subok=subok) + assert_raises(ValueError, np.add, a, 2, None, out=o, subok=subok) + assert_raises(ValueError, np.add, a, 2, out=(o, o), subok=subok) + assert_raises(ValueError, np.add, a, 2, out=(), subok=subok) + assert_raises(TypeError, np.add, a, 2, [], subok=subok) + assert_raises(TypeError, np.add, a, 2, out=[], subok=subok) + assert_raises(TypeError, np.add, a, 2, out=([],), subok=subok) + o.flags.writeable = False + assert_raises(ValueError, np.add, a, 2, o, subok=subok) + assert_raises(ValueError, np.add, a, 2, out=o, subok=subok) + assert_raises(ValueError, np.add, a, 2, out=(o,), subok=subok) + + def test_out_wrap_subok(self): + class ArrayWrap(np.ndarray): + __array_priority__ = 10 + + def __new__(cls, arr): + return np.asarray(arr).view(cls).copy() + + def __array_wrap__(self, arr, context): + return arr.view(type(self)) + + for subok in (True, False): + a = ArrayWrap([0.5]) + + r = np.add(a, 2, subok=subok) + if subok: + assert_(isinstance(r, ArrayWrap)) + else: + assert_(type(r) == np.ndarray) + + r = np.add(a, 2, None, subok=subok) + if subok: + assert_(isinstance(r, ArrayWrap)) + else: + assert_(type(r) == np.ndarray) + + r = np.add(a, 2, out=None, subok=subok) + if subok: + assert_(isinstance(r, ArrayWrap)) + else: + assert_(type(r) == np.ndarray) + + r = np.add(a, 2, out=(None,), subok=subok) + if subok: + assert_(isinstance(r, ArrayWrap)) + else: + assert_(type(r) == np.ndarray) + + d = ArrayWrap([5.7]) + o1 = np.empty((1,)) + o2 = np.empty((1,), dtype=np.int32) + + r1, r2 = np.frexp(d, o1, subok=subok) + if subok: + assert_(isinstance(r2, ArrayWrap)) + else: + assert_(type(r2) == np.ndarray) + + r1, r2 = np.frexp(d, o1, None, subok=subok) + if subok: + assert_(isinstance(r2, ArrayWrap)) + else: + assert_(type(r2) == np.ndarray) + + r1, r2 = np.frexp(d, None, o2, subok=subok) + if subok: + assert_(isinstance(r1, ArrayWrap)) + else: + assert_(type(r1) == np.ndarray) + + r1, r2 = np.frexp(d, out=(o1, None), subok=subok) + if subok: + assert_(isinstance(r2, ArrayWrap)) + else: + assert_(type(r2) == np.ndarray) + + r1, r2 = np.frexp(d, out=(None, o2), subok=subok) + if subok: + assert_(isinstance(r1, ArrayWrap)) + else: + assert_(type(r1) == np.ndarray) + + with assert_raises(TypeError): + # Out argument must be tuple, since there are multiple outputs. + r1, r2 = np.frexp(d, out=o1, subok=subok) + + +class TestComparisons: + def test_ignore_object_identity_in_equal(self): + # Check comparing identical objects whose comparison + # is not a simple boolean, e.g., arrays that are compared elementwise. + a = np.array([np.array([1, 2, 3]), None], dtype=object) + assert_raises(ValueError, np.equal, a, a) + + # Check error raised when comparing identical non-comparable objects. + class FunkyType: + def __eq__(self, other): + raise TypeError("I won't compare") + + a = np.array([FunkyType()]) + assert_raises(TypeError, np.equal, a, a) + + # Check identity doesn't override comparison mismatch. + a = np.array([np.nan], dtype=object) + assert_equal(np.equal(a, a), [False]) + + def test_ignore_object_identity_in_not_equal(self): + # Check comparing identical objects whose comparison + # is not a simple boolean, e.g., arrays that are compared elementwise. + a = np.array([np.array([1, 2, 3]), None], dtype=object) + assert_raises(ValueError, np.not_equal, a, a) + + # Check error raised when comparing identical non-comparable objects. + class FunkyType: + def __ne__(self, other): + raise TypeError("I won't compare") + + a = np.array([FunkyType()]) + assert_raises(TypeError, np.not_equal, a, a) + + # Check identity doesn't override comparison mismatch. + a = np.array([np.nan], dtype=object) + assert_equal(np.not_equal(a, a), [True]) + + +class TestAdd: + def test_reduce_alignment(self): + # gh-9876 + # make sure arrays with weird strides work with the optimizations in + # pairwise_sum_@TYPE@. On x86, the 'b' field will count as aligned at a + # 4 byte offset, even though its itemsize is 8. + a = np.zeros(2, dtype=[('a', np.int32), ('b', np.float64)]) + a['a'] = -1 + assert_equal(a['b'].sum(), 0) + + +class TestDivision: + def test_division_int(self): + # int division should follow Python + x = np.array([5, 10, 90, 100, -5, -10, -90, -100, -120]) + if 5 / 10 == 0.5: + assert_equal(x / 100, [0.05, 0.1, 0.9, 1, + -0.05, -0.1, -0.9, -1, -1.2]) + else: + assert_equal(x / 100, [0, 0, 0, 1, -1, -1, -1, -1, -2]) + assert_equal(x // 100, [0, 0, 0, 1, -1, -1, -1, -1, -2]) + assert_equal(x % 100, [5, 10, 90, 0, 95, 90, 10, 0, 80]) + + def test_division_complex(self): + # check that implementation is correct + msg = "Complex division implementation check" + x = np.array([1. + 1.*1j, 1. + .5*1j, 1. + 2.*1j], dtype=np.complex128) + assert_almost_equal(x**2/x, x, err_msg=msg) + # check overflow, underflow + msg = "Complex division overflow/underflow check" + x = np.array([1.e+110, 1.e-110], dtype=np.complex128) + y = x**2/x + assert_almost_equal(y/x, [1, 1], err_msg=msg) + + def test_zero_division_complex(self): + with np.errstate(invalid="ignore", divide="ignore"): + x = np.array([0.0], dtype=np.complex128) + y = 1.0/x + assert_(np.isinf(y)[0]) + y = complex(np.inf, np.nan)/x + assert_(np.isinf(y)[0]) + y = complex(np.nan, np.inf)/x + assert_(np.isinf(y)[0]) + y = complex(np.inf, np.inf)/x + assert_(np.isinf(y)[0]) + y = 0.0/x + assert_(np.isnan(y)[0]) + + def test_floor_division_complex(self): + # check that implementation is correct + msg = "Complex floor division implementation check" + x = np.array([.9 + 1j, -.1 + 1j, .9 + .5*1j, .9 + 2.*1j], dtype=np.complex128) + y = np.array([0., -1., 0., 0.], dtype=np.complex128) + assert_equal(np.floor_divide(x**2, x), y, err_msg=msg) + # check overflow, underflow + msg = "Complex floor division overflow/underflow check" + x = np.array([1.e+110, 1.e-110], dtype=np.complex128) + y = np.floor_divide(x**2, x) + assert_equal(y, [1.e+110, 0], err_msg=msg) + + def test_floor_division_signed_zero(self): + # Check that the sign bit is correctly set when dividing positive and + # negative zero by one. + x = np.zeros(10) + assert_equal(np.signbit(x//1), 0) + assert_equal(np.signbit((-x)//1), 1) + + @pytest.mark.parametrize('dtype', np.typecodes['Float']) + def test_floor_division_errors(self, dtype): + fnan = np.array(np.nan, dtype=dtype) + fone = np.array(1.0, dtype=dtype) + fzer = np.array(0.0, dtype=dtype) + finf = np.array(np.inf, dtype=dtype) + # divide by zero error check + with np.errstate(divide='raise', invalid='ignore'): + assert_raises(FloatingPointError, np.floor_divide, fone, fzer) + with np.errstate(invalid='raise'): + assert_raises(FloatingPointError, np.floor_divide, fnan, fone) + assert_raises(FloatingPointError, np.floor_divide, fone, fnan) + assert_raises(FloatingPointError, np.floor_divide, fnan, fzer) + + @pytest.mark.parametrize('dtype', np.typecodes['Float']) + def test_floor_division_corner_cases(self, dtype): + # test corner cases like 1.0//0.0 for errors and return vals + x = np.zeros(10, dtype=dtype) + y = np.ones(10, dtype=dtype) + fnan = np.array(np.nan, dtype=dtype) + fone = np.array(1.0, dtype=dtype) + fzer = np.array(0.0, dtype=dtype) + finf = np.array(np.inf, dtype=dtype) + with suppress_warnings() as sup: + sup.filter(RuntimeWarning, "invalid value encountered in floor_divide") + div = np.floor_divide(fnan, fone) + assert(np.isnan(div)), "dt: %s, div: %s" % (dt, div) + div = np.floor_divide(fone, fnan) + assert(np.isnan(div)), "dt: %s, div: %s" % (dt, div) + div = np.floor_divide(fnan, fzer) + assert(np.isnan(div)), "dt: %s, div: %s" % (dt, div) + # verify 1.0//0.0 computations return inf + with np.errstate(divide='ignore'): + z = np.floor_divide(y, x) + assert_(np.isinf(z).all()) + +def floor_divide_and_remainder(x, y): + return (np.floor_divide(x, y), np.remainder(x, y)) + + +def _signs(dt): + if dt in np.typecodes['UnsignedInteger']: + return (+1,) + else: + return (+1, -1) + + +class TestRemainder: + + def test_remainder_basic(self): + dt = np.typecodes['AllInteger'] + np.typecodes['Float'] + for op in [floor_divide_and_remainder, np.divmod]: + for dt1, dt2 in itertools.product(dt, dt): + for sg1, sg2 in itertools.product(_signs(dt1), _signs(dt2)): + fmt = 'op: %s, dt1: %s, dt2: %s, sg1: %s, sg2: %s' + msg = fmt % (op.__name__, dt1, dt2, sg1, sg2) + a = np.array(sg1*71, dtype=dt1) + b = np.array(sg2*19, dtype=dt2) + div, rem = op(a, b) + assert_equal(div*b + rem, a, err_msg=msg) + if sg2 == -1: + assert_(b < rem <= 0, msg) + else: + assert_(b > rem >= 0, msg) + + def test_float_remainder_exact(self): + # test that float results are exact for small integers. This also + # holds for the same integers scaled by powers of two. + nlst = list(range(-127, 0)) + plst = list(range(1, 128)) + dividend = nlst + [0] + plst + divisor = nlst + plst + arg = list(itertools.product(dividend, divisor)) + tgt = list(divmod(*t) for t in arg) + + a, b = np.array(arg, dtype=int).T + # convert exact integer results from Python to float so that + # signed zero can be used, it is checked. + tgtdiv, tgtrem = np.array(tgt, dtype=float).T + tgtdiv = np.where((tgtdiv == 0.0) & ((b < 0) ^ (a < 0)), -0.0, tgtdiv) + tgtrem = np.where((tgtrem == 0.0) & (b < 0), -0.0, tgtrem) + + for op in [floor_divide_and_remainder, np.divmod]: + for dt in np.typecodes['Float']: + msg = 'op: %s, dtype: %s' % (op.__name__, dt) + fa = a.astype(dt) + fb = b.astype(dt) + div, rem = op(fa, fb) + assert_equal(div, tgtdiv, err_msg=msg) + assert_equal(rem, tgtrem, err_msg=msg) + + def test_float_remainder_roundoff(self): + # gh-6127 + dt = np.typecodes['Float'] + for op in [floor_divide_and_remainder, np.divmod]: + for dt1, dt2 in itertools.product(dt, dt): + for sg1, sg2 in itertools.product((+1, -1), (+1, -1)): + fmt = 'op: %s, dt1: %s, dt2: %s, sg1: %s, sg2: %s' + msg = fmt % (op.__name__, dt1, dt2, sg1, sg2) + a = np.array(sg1*78*6e-8, dtype=dt1) + b = np.array(sg2*6e-8, dtype=dt2) + div, rem = op(a, b) + # Equal assertion should hold when fmod is used + assert_equal(div*b + rem, a, err_msg=msg) + if sg2 == -1: + assert_(b < rem <= 0, msg) + else: + assert_(b > rem >= 0, msg) + + @pytest.mark.parametrize('dtype', np.typecodes['Float']) + def test_float_divmod_errors(self, dtype): + # Check valid errors raised for divmod and remainder + fzero = np.array(0.0, dtype=dtype) + fone = np.array(1.0, dtype=dtype) + finf = np.array(np.inf, dtype=dtype) + fnan = np.array(np.nan, dtype=dtype) + # since divmod is combination of both remainder and divide + # ops it will set both dividebyzero and invalid flags + with np.errstate(divide='raise', invalid='ignore'): + assert_raises(FloatingPointError, np.divmod, fone, fzero) + with np.errstate(divide='ignore', invalid='raise'): + assert_raises(FloatingPointError, np.divmod, fone, fzero) + with np.errstate(invalid='raise'): + assert_raises(FloatingPointError, np.divmod, fzero, fzero) + with np.errstate(invalid='raise'): + assert_raises(FloatingPointError, np.divmod, finf, finf) + with np.errstate(divide='ignore', invalid='raise'): + assert_raises(FloatingPointError, np.divmod, finf, fzero) + with np.errstate(divide='raise', invalid='ignore'): + assert_raises(FloatingPointError, np.divmod, finf, fzero) + + @pytest.mark.parametrize('dtype', np.typecodes['Float']) + @pytest.mark.parametrize('fn', [np.fmod, np.remainder]) + def test_float_remainder_errors(self, dtype, fn): + fzero = np.array(0.0, dtype=dtype) + fone = np.array(1.0, dtype=dtype) + finf = np.array(np.inf, dtype=dtype) + fnan = np.array(np.nan, dtype=dtype) + with np.errstate(invalid='raise'): + assert_raises(FloatingPointError, fn, fone, fzero) + assert_raises(FloatingPointError, fn, fnan, fzero) + assert_raises(FloatingPointError, fn, fone, fnan) + assert_raises(FloatingPointError, fn, fnan, fone) + + def test_float_remainder_overflow(self): + a = np.finfo(np.float64).tiny + with np.errstate(over='ignore', invalid='ignore'): + div, mod = np.divmod(4, a) + np.isinf(div) + assert_(mod == 0) + with np.errstate(over='raise', invalid='ignore'): + assert_raises(FloatingPointError, np.divmod, 4, a) + with np.errstate(invalid='raise', over='ignore'): + assert_raises(FloatingPointError, np.divmod, 4, a) + + def test_float_divmod_corner_cases(self): + # check nan cases + for dt in np.typecodes['Float']: + fnan = np.array(np.nan, dtype=dt) + fone = np.array(1.0, dtype=dt) + fzer = np.array(0.0, dtype=dt) + finf = np.array(np.inf, dtype=dt) + with suppress_warnings() as sup: + sup.filter(RuntimeWarning, "invalid value encountered in divmod") + sup.filter(RuntimeWarning, "divide by zero encountered in divmod") + div, rem = np.divmod(fone, fzer) + assert(np.isinf(div)), 'dt: %s, div: %s' % (dt, rem) + assert(np.isnan(rem)), 'dt: %s, rem: %s' % (dt, rem) + div, rem = np.divmod(fzer, fzer) + assert(np.isnan(rem)), 'dt: %s, rem: %s' % (dt, rem) + assert_(np.isnan(div)), 'dt: %s, rem: %s' % (dt, rem) + div, rem = np.divmod(finf, finf) + assert(np.isnan(div)), 'dt: %s, rem: %s' % (dt, rem) + assert(np.isnan(rem)), 'dt: %s, rem: %s' % (dt, rem) + div, rem = np.divmod(finf, fzer) + assert(np.isinf(div)), 'dt: %s, rem: %s' % (dt, rem) + assert(np.isnan(rem)), 'dt: %s, rem: %s' % (dt, rem) + div, rem = np.divmod(fnan, fone) + assert(np.isnan(rem)), "dt: %s, rem: %s" % (dt, rem) + assert(np.isnan(div)), "dt: %s, rem: %s" % (dt, rem) + div, rem = np.divmod(fone, fnan) + assert(np.isnan(rem)), "dt: %s, rem: %s" % (dt, rem) + assert(np.isnan(div)), "dt: %s, rem: %s" % (dt, rem) + div, rem = np.divmod(fnan, fzer) + assert(np.isnan(rem)), "dt: %s, rem: %s" % (dt, rem) + assert(np.isnan(div)), "dt: %s, rem: %s" % (dt, rem) + + def test_float_remainder_corner_cases(self): + # Check remainder magnitude. + for dt in np.typecodes['Float']: + fone = np.array(1.0, dtype=dt) + fzer = np.array(0.0, dtype=dt) + fnan = np.array(np.nan, dtype=dt) + b = np.array(1.0, dtype=dt) + a = np.nextafter(np.array(0.0, dtype=dt), -b) + rem = np.remainder(a, b) + assert_(rem <= b, 'dt: %s' % dt) + rem = np.remainder(-a, -b) + assert_(rem >= -b, 'dt: %s' % dt) + + # Check nans, inf + with suppress_warnings() as sup: + sup.filter(RuntimeWarning, "invalid value encountered in remainder") + sup.filter(RuntimeWarning, "invalid value encountered in fmod") + for dt in np.typecodes['Float']: + fone = np.array(1.0, dtype=dt) + fzer = np.array(0.0, dtype=dt) + finf = np.array(np.inf, dtype=dt) + fnan = np.array(np.nan, dtype=dt) + rem = np.remainder(fone, fzer) + assert_(np.isnan(rem), 'dt: %s, rem: %s' % (dt, rem)) + # MSVC 2008 returns NaN here, so disable the check. + #rem = np.remainder(fone, finf) + #assert_(rem == fone, 'dt: %s, rem: %s' % (dt, rem)) + rem = np.remainder(finf, fone) + fmod = np.fmod(finf, fone) + assert_(np.isnan(fmod), 'dt: %s, fmod: %s' % (dt, fmod)) + assert_(np.isnan(rem), 'dt: %s, rem: %s' % (dt, rem)) + rem = np.remainder(finf, finf) + fmod = np.fmod(finf, fone) + assert_(np.isnan(rem), 'dt: %s, rem: %s' % (dt, rem)) + assert_(np.isnan(fmod), 'dt: %s, fmod: %s' % (dt, fmod)) + rem = np.remainder(finf, fzer) + fmod = np.fmod(finf, fzer) + assert_(np.isnan(rem), 'dt: %s, rem: %s' % (dt, rem)) + assert_(np.isnan(fmod), 'dt: %s, fmod: %s' % (dt, fmod)) + rem = np.remainder(fone, fnan) + fmod = np.fmod(fone, fnan) + assert_(np.isnan(rem), 'dt: %s, rem: %s' % (dt, rem)) + assert_(np.isnan(fmod), 'dt: %s, fmod: %s' % (dt, fmod)) + rem = np.remainder(fnan, fzer) + fmod = np.fmod(fnan, fzer) + assert_(np.isnan(rem), 'dt: %s, rem: %s' % (dt, rem)) + assert_(np.isnan(fmod), 'dt: %s, fmod: %s' % (dt, rem)) + rem = np.remainder(fnan, fone) + fmod = np.fmod(fnan, fone) + assert_(np.isnan(rem), 'dt: %s, rem: %s' % (dt, rem)) + assert_(np.isnan(fmod), 'dt: %s, fmod: %s' % (dt, rem)) + + +class TestCbrt: + def test_cbrt_scalar(self): + assert_almost_equal((np.cbrt(np.float32(-2.5)**3)), -2.5) + + def test_cbrt(self): + x = np.array([1., 2., -3., np.inf, -np.inf]) + assert_almost_equal(np.cbrt(x**3), x) + + assert_(np.isnan(np.cbrt(np.nan))) + assert_equal(np.cbrt(np.inf), np.inf) + assert_equal(np.cbrt(-np.inf), -np.inf) + + +class TestPower: + def test_power_float(self): + x = np.array([1., 2., 3.]) + assert_equal(x**0, [1., 1., 1.]) + assert_equal(x**1, x) + assert_equal(x**2, [1., 4., 9.]) + y = x.copy() + y **= 2 + assert_equal(y, [1., 4., 9.]) + assert_almost_equal(x**(-1), [1., 0.5, 1./3]) + assert_almost_equal(x**(0.5), [1., ncu.sqrt(2), ncu.sqrt(3)]) + + for out, inp, msg in _gen_alignment_data(dtype=np.float32, + type='unary', + max_size=11): + exp = [ncu.sqrt(i) for i in inp] + assert_almost_equal(inp**(0.5), exp, err_msg=msg) + np.sqrt(inp, out=out) + assert_equal(out, exp, err_msg=msg) + + for out, inp, msg in _gen_alignment_data(dtype=np.float64, + type='unary', + max_size=7): + exp = [ncu.sqrt(i) for i in inp] + assert_almost_equal(inp**(0.5), exp, err_msg=msg) + np.sqrt(inp, out=out) + assert_equal(out, exp, err_msg=msg) + + def test_power_complex(self): + x = np.array([1+2j, 2+3j, 3+4j]) + assert_equal(x**0, [1., 1., 1.]) + assert_equal(x**1, x) + assert_almost_equal(x**2, [-3+4j, -5+12j, -7+24j]) + assert_almost_equal(x**3, [(1+2j)**3, (2+3j)**3, (3+4j)**3]) + assert_almost_equal(x**4, [(1+2j)**4, (2+3j)**4, (3+4j)**4]) + assert_almost_equal(x**(-1), [1/(1+2j), 1/(2+3j), 1/(3+4j)]) + assert_almost_equal(x**(-2), [1/(1+2j)**2, 1/(2+3j)**2, 1/(3+4j)**2]) + assert_almost_equal(x**(-3), [(-11+2j)/125, (-46-9j)/2197, + (-117-44j)/15625]) + assert_almost_equal(x**(0.5), [ncu.sqrt(1+2j), ncu.sqrt(2+3j), + ncu.sqrt(3+4j)]) + norm = 1./((x**14)[0]) + assert_almost_equal(x**14 * norm, + [i * norm for i in [-76443+16124j, 23161315+58317492j, + 5583548873 + 2465133864j]]) + + # Ticket #836 + def assert_complex_equal(x, y): + assert_array_equal(x.real, y.real) + assert_array_equal(x.imag, y.imag) + + for z in [complex(0, np.inf), complex(1, np.inf)]: + z = np.array([z], dtype=np.complex_) + with np.errstate(invalid="ignore"): + assert_complex_equal(z**1, z) + assert_complex_equal(z**2, z*z) + assert_complex_equal(z**3, z*z*z) + + def test_power_zero(self): + # ticket #1271 + zero = np.array([0j]) + one = np.array([1+0j]) + cnan = np.array([complex(np.nan, np.nan)]) + # FIXME cinf not tested. + #cinf = np.array([complex(np.inf, 0)]) + + def assert_complex_equal(x, y): + x, y = np.asarray(x), np.asarray(y) + assert_array_equal(x.real, y.real) + assert_array_equal(x.imag, y.imag) + + # positive powers + for p in [0.33, 0.5, 1, 1.5, 2, 3, 4, 5, 6.6]: + assert_complex_equal(np.power(zero, p), zero) + + # zero power + assert_complex_equal(np.power(zero, 0), one) + with np.errstate(invalid="ignore"): + assert_complex_equal(np.power(zero, 0+1j), cnan) + + # negative power + for p in [0.33, 0.5, 1, 1.5, 2, 3, 4, 5, 6.6]: + assert_complex_equal(np.power(zero, -p), cnan) + assert_complex_equal(np.power(zero, -1+0.2j), cnan) + + def test_fast_power(self): + x = np.array([1, 2, 3], np.int16) + res = x**2.0 + assert_((x**2.00001).dtype is res.dtype) + assert_array_equal(res, [1, 4, 9]) + # check the inplace operation on the casted copy doesn't mess with x + assert_(not np.may_share_memory(res, x)) + assert_array_equal(x, [1, 2, 3]) + + # Check that the fast path ignores 1-element not 0-d arrays + res = x ** np.array([[[2]]]) + assert_equal(res.shape, (1, 1, 3)) + + def test_integer_power(self): + a = np.array([15, 15], 'i8') + b = np.power(a, a) + assert_equal(b, [437893890380859375, 437893890380859375]) + + def test_integer_power_with_integer_zero_exponent(self): + dtypes = np.typecodes['Integer'] + for dt in dtypes: + arr = np.arange(-10, 10, dtype=dt) + assert_equal(np.power(arr, 0), np.ones_like(arr)) + + dtypes = np.typecodes['UnsignedInteger'] + for dt in dtypes: + arr = np.arange(10, dtype=dt) + assert_equal(np.power(arr, 0), np.ones_like(arr)) + + def test_integer_power_of_1(self): + dtypes = np.typecodes['AllInteger'] + for dt in dtypes: + arr = np.arange(10, dtype=dt) + assert_equal(np.power(1, arr), np.ones_like(arr)) + + def test_integer_power_of_zero(self): + dtypes = np.typecodes['AllInteger'] + for dt in dtypes: + arr = np.arange(1, 10, dtype=dt) + assert_equal(np.power(0, arr), np.zeros_like(arr)) + + def test_integer_to_negative_power(self): + dtypes = np.typecodes['Integer'] + for dt in dtypes: + a = np.array([0, 1, 2, 3], dtype=dt) + b = np.array([0, 1, 2, -3], dtype=dt) + one = np.array(1, dtype=dt) + minusone = np.array(-1, dtype=dt) + assert_raises(ValueError, np.power, a, b) + assert_raises(ValueError, np.power, a, minusone) + assert_raises(ValueError, np.power, one, b) + assert_raises(ValueError, np.power, one, minusone) + + +class TestFloat_power: + def test_type_conversion(self): + arg_type = '?bhilBHILefdgFDG' + res_type = 'ddddddddddddgDDG' + for dtin, dtout in zip(arg_type, res_type): + msg = "dtin: %s, dtout: %s" % (dtin, dtout) + arg = np.ones(1, dtype=dtin) + res = np.float_power(arg, arg) + assert_(res.dtype.name == np.dtype(dtout).name, msg) + + +class TestLog2: + def test_log2_values(self): + x = [1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024] + y = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] + for dt in ['f', 'd', 'g']: + xf = np.array(x, dtype=dt) + yf = np.array(y, dtype=dt) + assert_almost_equal(np.log2(xf), yf) + + def test_log2_ints(self): + # a good log2 implementation should provide this, + # might fail on OS with bad libm + for i in range(1, 65): + v = np.log2(2.**i) + assert_equal(v, float(i), err_msg='at exponent %d' % i) + + def test_log2_special(self): + assert_equal(np.log2(1.), 0.) + assert_equal(np.log2(np.inf), np.inf) + assert_(np.isnan(np.log2(np.nan))) + + with warnings.catch_warnings(record=True) as w: + warnings.filterwarnings('always', '', RuntimeWarning) + assert_(np.isnan(np.log2(-1.))) + assert_(np.isnan(np.log2(-np.inf))) + assert_equal(np.log2(0.), -np.inf) + assert_(w[0].category is RuntimeWarning) + assert_(w[1].category is RuntimeWarning) + assert_(w[2].category is RuntimeWarning) + + +class TestExp2: + def test_exp2_values(self): + x = [1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024] + y = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] + for dt in ['f', 'd', 'g']: + xf = np.array(x, dtype=dt) + yf = np.array(y, dtype=dt) + assert_almost_equal(np.exp2(yf), xf) + + +class TestLogAddExp2(_FilterInvalids): + # Need test for intermediate precisions + def test_logaddexp2_values(self): + x = [1, 2, 3, 4, 5] + y = [5, 4, 3, 2, 1] + z = [6, 6, 6, 6, 6] + for dt, dec_ in zip(['f', 'd', 'g'], [6, 15, 15]): + xf = np.log2(np.array(x, dtype=dt)) + yf = np.log2(np.array(y, dtype=dt)) + zf = np.log2(np.array(z, dtype=dt)) + assert_almost_equal(np.logaddexp2(xf, yf), zf, decimal=dec_) + + def test_logaddexp2_range(self): + x = [1000000, -1000000, 1000200, -1000200] + y = [1000200, -1000200, 1000000, -1000000] + z = [1000200, -1000000, 1000200, -1000000] + for dt in ['f', 'd', 'g']: + logxf = np.array(x, dtype=dt) + logyf = np.array(y, dtype=dt) + logzf = np.array(z, dtype=dt) + assert_almost_equal(np.logaddexp2(logxf, logyf), logzf) + + def test_inf(self): + inf = np.inf + x = [inf, -inf, inf, -inf, inf, 1, -inf, 1] + y = [inf, inf, -inf, -inf, 1, inf, 1, -inf] + z = [inf, inf, inf, -inf, inf, inf, 1, 1] + with np.errstate(invalid='raise'): + for dt in ['f', 'd', 'g']: + logxf = np.array(x, dtype=dt) + logyf = np.array(y, dtype=dt) + logzf = np.array(z, dtype=dt) + assert_equal(np.logaddexp2(logxf, logyf), logzf) + + def test_nan(self): + assert_(np.isnan(np.logaddexp2(np.nan, np.inf))) + assert_(np.isnan(np.logaddexp2(np.inf, np.nan))) + assert_(np.isnan(np.logaddexp2(np.nan, 0))) + assert_(np.isnan(np.logaddexp2(0, np.nan))) + assert_(np.isnan(np.logaddexp2(np.nan, np.nan))) + + def test_reduce(self): + assert_equal(np.logaddexp2.identity, -np.inf) + assert_equal(np.logaddexp2.reduce([]), -np.inf) + assert_equal(np.logaddexp2.reduce([-np.inf]), -np.inf) + assert_equal(np.logaddexp2.reduce([-np.inf, 0]), 0) + + +class TestLog: + def test_log_values(self): + x = [1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024] + y = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] + for dt in ['f', 'd', 'g']: + log2_ = 0.69314718055994530943 + xf = np.array(x, dtype=dt) + yf = np.array(y, dtype=dt)*log2_ + assert_almost_equal(np.log(xf), yf) + + # test aliasing(issue #17761) + x = np.array([2, 0.937500, 3, 0.947500, 1.054697]) + xf = np.log(x) + assert_almost_equal(np.log(x, out=x), xf) + + def test_log_strides(self): + np.random.seed(42) + strides = np.array([-4,-3,-2,-1,1,2,3,4]) + sizes = np.arange(2,100) + for ii in sizes: + x_f64 = np.float64(np.random.uniform(low=0.01, high=100.0,size=ii)) + x_special = x_f64.copy() + x_special[3:-1:4] = 1.0 + y_true = np.log(x_f64) + y_special = np.log(x_special) + for jj in strides: + assert_array_almost_equal_nulp(np.log(x_f64[::jj]), y_true[::jj], nulp=2) + assert_array_almost_equal_nulp(np.log(x_special[::jj]), y_special[::jj], nulp=2) + +class TestExp: + def test_exp_values(self): + x = [1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024] + y = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] + for dt in ['f', 'd', 'g']: + log2_ = 0.69314718055994530943 + xf = np.array(x, dtype=dt) + yf = np.array(y, dtype=dt)*log2_ + assert_almost_equal(np.exp(yf), xf) + + def test_exp_strides(self): + np.random.seed(42) + strides = np.array([-4,-3,-2,-1,1,2,3,4]) + sizes = np.arange(2,100) + for ii in sizes: + x_f64 = np.float64(np.random.uniform(low=0.01, high=709.1,size=ii)) + y_true = np.exp(x_f64) + for jj in strides: + assert_array_almost_equal_nulp(np.exp(x_f64[::jj]), y_true[::jj], nulp=2) + +class TestSpecialFloats: + def test_exp_values(self): + x = [np.nan, np.nan, np.inf, 0.] + y = [np.nan, -np.nan, np.inf, -np.inf] + for dt in ['f', 'd', 'g']: + xf = np.array(x, dtype=dt) + yf = np.array(y, dtype=dt) + assert_equal(np.exp(yf), xf) + + with np.errstate(over='raise'): + assert_raises(FloatingPointError, np.exp, np.float32(100.)) + assert_raises(FloatingPointError, np.exp, np.float32(1E19)) + assert_raises(FloatingPointError, np.exp, np.float64(800.)) + assert_raises(FloatingPointError, np.exp, np.float64(1E19)) + + def test_log_values(self): + with np.errstate(all='ignore'): + x = [np.nan, np.nan, np.inf, np.nan, -np.inf, np.nan] + y = [np.nan, -np.nan, np.inf, -np.inf, 0., -1.0] + for dt in ['f', 'd', 'g']: + xf = np.array(x, dtype=dt) + yf = np.array(y, dtype=dt) + assert_equal(np.log(yf), xf) + + with np.errstate(divide='raise'): + assert_raises(FloatingPointError, np.log, np.float32(0.)) + + with np.errstate(invalid='raise'): + assert_raises(FloatingPointError, np.log, np.float32(-np.inf)) + assert_raises(FloatingPointError, np.log, np.float32(-1.0)) + + # See https://github.com/numpy/numpy/issues/18005 + with assert_no_warnings(): + a = np.array(1e9, dtype='float32') + np.log(a) + + def test_sincos_values(self): + with np.errstate(all='ignore'): + x = [np.nan, np.nan, np.nan, np.nan] + y = [np.nan, -np.nan, np.inf, -np.inf] + for dt in ['f', 'd', 'g']: + xf = np.array(x, dtype=dt) + yf = np.array(y, dtype=dt) + assert_equal(np.sin(yf), xf) + assert_equal(np.cos(yf), xf) + + with np.errstate(invalid='raise'): + assert_raises(FloatingPointError, np.sin, np.float32(-np.inf)) + assert_raises(FloatingPointError, np.sin, np.float32(np.inf)) + assert_raises(FloatingPointError, np.cos, np.float32(-np.inf)) + assert_raises(FloatingPointError, np.cos, np.float32(np.inf)) + + def test_sqrt_values(self): + with np.errstate(all='ignore'): + x = [np.nan, np.nan, np.inf, np.nan, 0.] + y = [np.nan, -np.nan, np.inf, -np.inf, 0.] + for dt in ['f', 'd', 'g']: + xf = np.array(x, dtype=dt) + yf = np.array(y, dtype=dt) + assert_equal(np.sqrt(yf), xf) + + #with np.errstate(invalid='raise'): + # for dt in ['f', 'd', 'g']: + # assert_raises(FloatingPointError, np.sqrt, np.array(-100., dtype=dt)) + + def test_abs_values(self): + x = [np.nan, np.nan, np.inf, np.inf, 0., 0., 1.0, 1.0] + y = [np.nan, -np.nan, np.inf, -np.inf, 0., -0., -1.0, 1.0] + for dt in ['f', 'd', 'g']: + xf = np.array(x, dtype=dt) + yf = np.array(y, dtype=dt) + assert_equal(np.abs(yf), xf) + + def test_square_values(self): + x = [np.nan, np.nan, np.inf, np.inf] + y = [np.nan, -np.nan, np.inf, -np.inf] + with np.errstate(all='ignore'): + for dt in ['f', 'd', 'g']: + xf = np.array(x, dtype=dt) + yf = np.array(y, dtype=dt) + assert_equal(np.square(yf), xf) + + with np.errstate(over='raise'): + assert_raises(FloatingPointError, np.square, np.array(1E32, dtype='f')) + assert_raises(FloatingPointError, np.square, np.array(1E200, dtype='d')) + + def test_reciprocal_values(self): + with np.errstate(all='ignore'): + x = [np.nan, np.nan, 0.0, -0.0, np.inf, -np.inf] + y = [np.nan, -np.nan, np.inf, -np.inf, 0., -0.] + for dt in ['f', 'd', 'g']: + xf = np.array(x, dtype=dt) + yf = np.array(y, dtype=dt) + assert_equal(np.reciprocal(yf), xf) + + with np.errstate(divide='raise'): + for dt in ['f', 'd', 'g']: + assert_raises(FloatingPointError, np.reciprocal, np.array(-0.0, dtype=dt)) + +class TestFPClass: + @pytest.mark.parametrize("stride", [-4,-2,-1,1,2,4]) + def test_fpclass(self, stride): + arr_f64 = np.array([np.nan, -np.nan, np.inf, -np.inf, -1.0, 1.0, -0.0, 0.0, 2.2251e-308, -2.2251e-308], dtype='d') + arr_f32 = np.array([np.nan, -np.nan, np.inf, -np.inf, -1.0, 1.0, -0.0, 0.0, 1.4013e-045, -1.4013e-045], dtype='f') + nan = np.array([True, True, False, False, False, False, False, False, False, False]) + inf = np.array([False, False, True, True, False, False, False, False, False, False]) + sign = np.array([False, True, False, True, True, False, True, False, False, True]) + finite = np.array([False, False, False, False, True, True, True, True, True, True]) + assert_equal(np.isnan(arr_f32[::stride]), nan[::stride]) + assert_equal(np.isnan(arr_f64[::stride]), nan[::stride]) + assert_equal(np.isinf(arr_f32[::stride]), inf[::stride]) + assert_equal(np.isinf(arr_f64[::stride]), inf[::stride]) + assert_equal(np.signbit(arr_f32[::stride]), sign[::stride]) + assert_equal(np.signbit(arr_f64[::stride]), sign[::stride]) + assert_equal(np.isfinite(arr_f32[::stride]), finite[::stride]) + assert_equal(np.isfinite(arr_f64[::stride]), finite[::stride]) + +class TestLDExp: + @pytest.mark.parametrize("stride", [-4,-2,-1,1,2,4]) + @pytest.mark.parametrize("dtype", ['f', 'd']) + def test_ldexp(self, dtype, stride): + mant = np.array([0.125, 0.25, 0.5, 1., 1., 2., 4., 8.], dtype=dtype) + exp = np.array([3, 2, 1, 0, 0, -1, -2, -3], dtype='i') + out = np.zeros(8, dtype=dtype) + assert_equal(np.ldexp(mant[::stride], exp[::stride], out=out[::stride]), np.ones(8, dtype=dtype)[::stride]) + assert_equal(out[::stride], np.ones(8, dtype=dtype)[::stride]) + +class TestFRExp: + @pytest.mark.parametrize("stride", [-4,-2,-1,1,2,4]) + @pytest.mark.parametrize("dtype", ['f', 'd']) + @pytest.mark.skipif(not sys.platform.startswith('linux'), + reason="np.frexp gives different answers for NAN/INF on windows and linux") + def test_frexp(self, dtype, stride): + arr = np.array([np.nan, np.nan, np.inf, -np.inf, 0.0, -0.0, 1.0, -1.0], dtype=dtype) + mant_true = np.array([np.nan, np.nan, np.inf, -np.inf, 0.0, -0.0, 0.5, -0.5], dtype=dtype) + exp_true = np.array([0, 0, 0, 0, 0, 0, 1, 1], dtype='i') + out_mant = np.ones(8, dtype=dtype) + out_exp = 2*np.ones(8, dtype='i') + mant, exp = np.frexp(arr[::stride], out=(out_mant[::stride], out_exp[::stride])) + assert_equal(mant_true[::stride], mant) + assert_equal(exp_true[::stride], exp) + assert_equal(out_mant[::stride], mant_true[::stride]) + assert_equal(out_exp[::stride], exp_true[::stride]) + +# func : [maxulperror, low, high] +avx_ufuncs = {'sqrt' :[1, 0., 100.], + 'absolute' :[0, -100., 100.], + 'reciprocal' :[1, 1., 100.], + 'square' :[1, -100., 100.], + 'rint' :[0, -100., 100.], + 'floor' :[0, -100., 100.], + 'ceil' :[0, -100., 100.], + 'trunc' :[0, -100., 100.]} + +class TestAVXUfuncs: + def test_avx_based_ufunc(self): + strides = np.array([-4,-3,-2,-1,1,2,3,4]) + np.random.seed(42) + for func, prop in avx_ufuncs.items(): + maxulperr = prop[0] + minval = prop[1] + maxval = prop[2] + # various array sizes to ensure masking in AVX is tested + for size in range(1,32): + myfunc = getattr(np, func) + x_f32 = np.float32(np.random.uniform(low=minval, high=maxval, + size=size)) + x_f64 = np.float64(x_f32) + x_f128 = np.longdouble(x_f32) + y_true128 = myfunc(x_f128) + if maxulperr == 0: + assert_equal(myfunc(x_f32), np.float32(y_true128)) + assert_equal(myfunc(x_f64), np.float64(y_true128)) + else: + assert_array_max_ulp(myfunc(x_f32), np.float32(y_true128), + maxulp=maxulperr) + assert_array_max_ulp(myfunc(x_f64), np.float64(y_true128), + maxulp=maxulperr) + # various strides to test gather instruction + if size > 1: + y_true32 = myfunc(x_f32) + y_true64 = myfunc(x_f64) + for jj in strides: + assert_equal(myfunc(x_f64[::jj]), y_true64[::jj]) + assert_equal(myfunc(x_f32[::jj]), y_true32[::jj]) + +class TestAVXFloat32Transcendental: + def test_exp_float32(self): + np.random.seed(42) + x_f32 = np.float32(np.random.uniform(low=0.0,high=88.1,size=1000000)) + x_f64 = np.float64(x_f32) + assert_array_max_ulp(np.exp(x_f32), np.float32(np.exp(x_f64)), maxulp=3) + + def test_log_float32(self): + np.random.seed(42) + x_f32 = np.float32(np.random.uniform(low=0.0,high=1000,size=1000000)) + x_f64 = np.float64(x_f32) + assert_array_max_ulp(np.log(x_f32), np.float32(np.log(x_f64)), maxulp=4) + + def test_sincos_float32(self): + np.random.seed(42) + N = 1000000 + M = np.int_(N/20) + index = np.random.randint(low=0, high=N, size=M) + x_f32 = np.float32(np.random.uniform(low=-100.,high=100.,size=N)) + # test coverage for elements > 117435.992f for which glibc is used + x_f32[index] = np.float32(10E+10*np.random.rand(M)) + x_f64 = np.float64(x_f32) + assert_array_max_ulp(np.sin(x_f32), np.float32(np.sin(x_f64)), maxulp=2) + assert_array_max_ulp(np.cos(x_f32), np.float32(np.cos(x_f64)), maxulp=2) + # test aliasing(issue #17761) + tx_f32 = x_f32.copy() + assert_array_max_ulp(np.sin(x_f32, out=x_f32), np.float32(np.sin(x_f64)), maxulp=2) + assert_array_max_ulp(np.cos(tx_f32, out=tx_f32), np.float32(np.cos(x_f64)), maxulp=2) + + def test_strided_float32(self): + np.random.seed(42) + strides = np.array([-4,-3,-2,-1,1,2,3,4]) + sizes = np.arange(2,100) + for ii in sizes: + x_f32 = np.float32(np.random.uniform(low=0.01,high=88.1,size=ii)) + x_f32_large = x_f32.copy() + x_f32_large[3:-1:4] = 120000.0 + exp_true = np.exp(x_f32) + log_true = np.log(x_f32) + sin_true = np.sin(x_f32_large) + cos_true = np.cos(x_f32_large) + for jj in strides: + assert_array_almost_equal_nulp(np.exp(x_f32[::jj]), exp_true[::jj], nulp=2) + assert_array_almost_equal_nulp(np.log(x_f32[::jj]), log_true[::jj], nulp=2) + assert_array_almost_equal_nulp(np.sin(x_f32_large[::jj]), sin_true[::jj], nulp=2) + assert_array_almost_equal_nulp(np.cos(x_f32_large[::jj]), cos_true[::jj], nulp=2) + +class TestLogAddExp(_FilterInvalids): + def test_logaddexp_values(self): + x = [1, 2, 3, 4, 5] + y = [5, 4, 3, 2, 1] + z = [6, 6, 6, 6, 6] + for dt, dec_ in zip(['f', 'd', 'g'], [6, 15, 15]): + xf = np.log(np.array(x, dtype=dt)) + yf = np.log(np.array(y, dtype=dt)) + zf = np.log(np.array(z, dtype=dt)) + assert_almost_equal(np.logaddexp(xf, yf), zf, decimal=dec_) + + def test_logaddexp_range(self): + x = [1000000, -1000000, 1000200, -1000200] + y = [1000200, -1000200, 1000000, -1000000] + z = [1000200, -1000000, 1000200, -1000000] + for dt in ['f', 'd', 'g']: + logxf = np.array(x, dtype=dt) + logyf = np.array(y, dtype=dt) + logzf = np.array(z, dtype=dt) + assert_almost_equal(np.logaddexp(logxf, logyf), logzf) + + def test_inf(self): + inf = np.inf + x = [inf, -inf, inf, -inf, inf, 1, -inf, 1] + y = [inf, inf, -inf, -inf, 1, inf, 1, -inf] + z = [inf, inf, inf, -inf, inf, inf, 1, 1] + with np.errstate(invalid='raise'): + for dt in ['f', 'd', 'g']: + logxf = np.array(x, dtype=dt) + logyf = np.array(y, dtype=dt) + logzf = np.array(z, dtype=dt) + assert_equal(np.logaddexp(logxf, logyf), logzf) + + def test_nan(self): + assert_(np.isnan(np.logaddexp(np.nan, np.inf))) + assert_(np.isnan(np.logaddexp(np.inf, np.nan))) + assert_(np.isnan(np.logaddexp(np.nan, 0))) + assert_(np.isnan(np.logaddexp(0, np.nan))) + assert_(np.isnan(np.logaddexp(np.nan, np.nan))) + + def test_reduce(self): + assert_equal(np.logaddexp.identity, -np.inf) + assert_equal(np.logaddexp.reduce([]), -np.inf) + + +class TestLog1p: + def test_log1p(self): + assert_almost_equal(ncu.log1p(0.2), ncu.log(1.2)) + assert_almost_equal(ncu.log1p(1e-6), ncu.log(1+1e-6)) + + def test_special(self): + with np.errstate(invalid="ignore", divide="ignore"): + assert_equal(ncu.log1p(np.nan), np.nan) + assert_equal(ncu.log1p(np.inf), np.inf) + assert_equal(ncu.log1p(-1.), -np.inf) + assert_equal(ncu.log1p(-2.), np.nan) + assert_equal(ncu.log1p(-np.inf), np.nan) + + +class TestExpm1: + def test_expm1(self): + assert_almost_equal(ncu.expm1(0.2), ncu.exp(0.2)-1) + assert_almost_equal(ncu.expm1(1e-6), ncu.exp(1e-6)-1) + + def test_special(self): + assert_equal(ncu.expm1(np.inf), np.inf) + assert_equal(ncu.expm1(0.), 0.) + assert_equal(ncu.expm1(-0.), -0.) + assert_equal(ncu.expm1(np.inf), np.inf) + assert_equal(ncu.expm1(-np.inf), -1.) + + def test_complex(self): + x = np.asarray(1e-12) + assert_allclose(x, ncu.expm1(x)) + x = x.astype(np.complex128) + assert_allclose(x, ncu.expm1(x)) + + +class TestHypot: + def test_simple(self): + assert_almost_equal(ncu.hypot(1, 1), ncu.sqrt(2)) + assert_almost_equal(ncu.hypot(0, 0), 0) + + def test_reduce(self): + assert_almost_equal(ncu.hypot.reduce([3.0, 4.0]), 5.0) + assert_almost_equal(ncu.hypot.reduce([3.0, 4.0, 0]), 5.0) + assert_almost_equal(ncu.hypot.reduce([9.0, 12.0, 20.0]), 25.0) + assert_equal(ncu.hypot.reduce([]), 0.0) + + +def assert_hypot_isnan(x, y): + with np.errstate(invalid='ignore'): + assert_(np.isnan(ncu.hypot(x, y)), + "hypot(%s, %s) is %s, not nan" % (x, y, ncu.hypot(x, y))) + + +def assert_hypot_isinf(x, y): + with np.errstate(invalid='ignore'): + assert_(np.isinf(ncu.hypot(x, y)), + "hypot(%s, %s) is %s, not inf" % (x, y, ncu.hypot(x, y))) + + +class TestHypotSpecialValues: + def test_nan_outputs(self): + assert_hypot_isnan(np.nan, np.nan) + assert_hypot_isnan(np.nan, 1) + + def test_nan_outputs2(self): + assert_hypot_isinf(np.nan, np.inf) + assert_hypot_isinf(np.inf, np.nan) + assert_hypot_isinf(np.inf, 0) + assert_hypot_isinf(0, np.inf) + assert_hypot_isinf(np.inf, np.inf) + assert_hypot_isinf(np.inf, 23.0) + + def test_no_fpe(self): + assert_no_warnings(ncu.hypot, np.inf, 0) + + +def assert_arctan2_isnan(x, y): + assert_(np.isnan(ncu.arctan2(x, y)), "arctan(%s, %s) is %s, not nan" % (x, y, ncu.arctan2(x, y))) + + +def assert_arctan2_ispinf(x, y): + assert_((np.isinf(ncu.arctan2(x, y)) and ncu.arctan2(x, y) > 0), "arctan(%s, %s) is %s, not +inf" % (x, y, ncu.arctan2(x, y))) + + +def assert_arctan2_isninf(x, y): + assert_((np.isinf(ncu.arctan2(x, y)) and ncu.arctan2(x, y) < 0), "arctan(%s, %s) is %s, not -inf" % (x, y, ncu.arctan2(x, y))) + + +def assert_arctan2_ispzero(x, y): + assert_((ncu.arctan2(x, y) == 0 and not np.signbit(ncu.arctan2(x, y))), "arctan(%s, %s) is %s, not +0" % (x, y, ncu.arctan2(x, y))) + + +def assert_arctan2_isnzero(x, y): + assert_((ncu.arctan2(x, y) == 0 and np.signbit(ncu.arctan2(x, y))), "arctan(%s, %s) is %s, not -0" % (x, y, ncu.arctan2(x, y))) + + +class TestArctan2SpecialValues: + def test_one_one(self): + # atan2(1, 1) returns pi/4. + assert_almost_equal(ncu.arctan2(1, 1), 0.25 * np.pi) + assert_almost_equal(ncu.arctan2(-1, 1), -0.25 * np.pi) + assert_almost_equal(ncu.arctan2(1, -1), 0.75 * np.pi) + + def test_zero_nzero(self): + # atan2(+-0, -0) returns +-pi. + assert_almost_equal(ncu.arctan2(np.PZERO, np.NZERO), np.pi) + assert_almost_equal(ncu.arctan2(np.NZERO, np.NZERO), -np.pi) + + def test_zero_pzero(self): + # atan2(+-0, +0) returns +-0. + assert_arctan2_ispzero(np.PZERO, np.PZERO) + assert_arctan2_isnzero(np.NZERO, np.PZERO) + + def test_zero_negative(self): + # atan2(+-0, x) returns +-pi for x < 0. + assert_almost_equal(ncu.arctan2(np.PZERO, -1), np.pi) + assert_almost_equal(ncu.arctan2(np.NZERO, -1), -np.pi) + + def test_zero_positive(self): + # atan2(+-0, x) returns +-0 for x > 0. + assert_arctan2_ispzero(np.PZERO, 1) + assert_arctan2_isnzero(np.NZERO, 1) + + def test_positive_zero(self): + # atan2(y, +-0) returns +pi/2 for y > 0. + assert_almost_equal(ncu.arctan2(1, np.PZERO), 0.5 * np.pi) + assert_almost_equal(ncu.arctan2(1, np.NZERO), 0.5 * np.pi) + + def test_negative_zero(self): + # atan2(y, +-0) returns -pi/2 for y < 0. + assert_almost_equal(ncu.arctan2(-1, np.PZERO), -0.5 * np.pi) + assert_almost_equal(ncu.arctan2(-1, np.NZERO), -0.5 * np.pi) + + def test_any_ninf(self): + # atan2(+-y, -infinity) returns +-pi for finite y > 0. + assert_almost_equal(ncu.arctan2(1, np.NINF), np.pi) + assert_almost_equal(ncu.arctan2(-1, np.NINF), -np.pi) + + def test_any_pinf(self): + # atan2(+-y, +infinity) returns +-0 for finite y > 0. + assert_arctan2_ispzero(1, np.inf) + assert_arctan2_isnzero(-1, np.inf) + + def test_inf_any(self): + # atan2(+-infinity, x) returns +-pi/2 for finite x. + assert_almost_equal(ncu.arctan2( np.inf, 1), 0.5 * np.pi) + assert_almost_equal(ncu.arctan2(-np.inf, 1), -0.5 * np.pi) + + def test_inf_ninf(self): + # atan2(+-infinity, -infinity) returns +-3*pi/4. + assert_almost_equal(ncu.arctan2( np.inf, -np.inf), 0.75 * np.pi) + assert_almost_equal(ncu.arctan2(-np.inf, -np.inf), -0.75 * np.pi) + + def test_inf_pinf(self): + # atan2(+-infinity, +infinity) returns +-pi/4. + assert_almost_equal(ncu.arctan2( np.inf, np.inf), 0.25 * np.pi) + assert_almost_equal(ncu.arctan2(-np.inf, np.inf), -0.25 * np.pi) + + def test_nan_any(self): + # atan2(nan, x) returns nan for any x, including inf + assert_arctan2_isnan(np.nan, np.inf) + assert_arctan2_isnan(np.inf, np.nan) + assert_arctan2_isnan(np.nan, np.nan) + + +class TestLdexp: + def _check_ldexp(self, tp): + assert_almost_equal(ncu.ldexp(np.array(2., np.float32), + np.array(3, tp)), 16.) + assert_almost_equal(ncu.ldexp(np.array(2., np.float64), + np.array(3, tp)), 16.) + assert_almost_equal(ncu.ldexp(np.array(2., np.longdouble), + np.array(3, tp)), 16.) + + def test_ldexp(self): + # The default Python int type should work + assert_almost_equal(ncu.ldexp(2., 3), 16.) + # The following int types should all be accepted + self._check_ldexp(np.int8) + self._check_ldexp(np.int16) + self._check_ldexp(np.int32) + self._check_ldexp('i') + self._check_ldexp('l') + + def test_ldexp_overflow(self): + # silence warning emitted on overflow + with np.errstate(over="ignore"): + imax = np.iinfo(np.dtype('l')).max + imin = np.iinfo(np.dtype('l')).min + assert_equal(ncu.ldexp(2., imax), np.inf) + assert_equal(ncu.ldexp(2., imin), 0) + + +class TestMaximum(_FilterInvalids): + def test_reduce(self): + dflt = np.typecodes['AllFloat'] + dint = np.typecodes['AllInteger'] + seq1 = np.arange(11) + seq2 = seq1[::-1] + func = np.maximum.reduce + for dt in dint: + tmp1 = seq1.astype(dt) + tmp2 = seq2.astype(dt) + assert_equal(func(tmp1), 10) + assert_equal(func(tmp2), 10) + for dt in dflt: + tmp1 = seq1.astype(dt) + tmp2 = seq2.astype(dt) + assert_equal(func(tmp1), 10) + assert_equal(func(tmp2), 10) + tmp1[::2] = np.nan + tmp2[::2] = np.nan + assert_equal(func(tmp1), np.nan) + assert_equal(func(tmp2), np.nan) + + def test_reduce_complex(self): + assert_equal(np.maximum.reduce([1, 2j]), 1) + assert_equal(np.maximum.reduce([1+3j, 2j]), 1+3j) + + def test_float_nans(self): + nan = np.nan + arg1 = np.array([0, nan, nan]) + arg2 = np.array([nan, 0, nan]) + out = np.array([nan, nan, nan]) + assert_equal(np.maximum(arg1, arg2), out) + + def test_object_nans(self): + # Multiple checks to give this a chance to + # fail if cmp is used instead of rich compare. + # Failure cannot be guaranteed. + for i in range(1): + x = np.array(float('nan'), object) + y = 1.0 + z = np.array(float('nan'), object) + assert_(np.maximum(x, y) == 1.0) + assert_(np.maximum(z, y) == 1.0) + + def test_complex_nans(self): + nan = np.nan + for cnan in [complex(nan, 0), complex(0, nan), complex(nan, nan)]: + arg1 = np.array([0, cnan, cnan], dtype=complex) + arg2 = np.array([cnan, 0, cnan], dtype=complex) + out = np.array([nan, nan, nan], dtype=complex) + assert_equal(np.maximum(arg1, arg2), out) + + def test_object_array(self): + arg1 = np.arange(5, dtype=object) + arg2 = arg1 + 1 + assert_equal(np.maximum(arg1, arg2), arg2) + + def test_strided_array(self): + arr1 = np.array([-4.0, 1.0, 10.0, 0.0, np.nan, -np.nan, np.inf, -np.inf]) + arr2 = np.array([-2.0,-1.0, np.nan, 1.0, 0.0, np.nan, 1.0, -3.0]) + maxtrue = np.array([-2.0, 1.0, np.nan, 1.0, np.nan, np.nan, np.inf, -3.0]) + out = np.ones(8) + out_maxtrue = np.array([-2.0, 1.0, 1.0, 10.0, 1.0, 1.0, np.nan, 1.0]) + assert_equal(np.maximum(arr1,arr2), maxtrue) + assert_equal(np.maximum(arr1[::2],arr2[::2]), maxtrue[::2]) + assert_equal(np.maximum(arr1[:4:], arr2[::2]), np.array([-2.0, np.nan, 10.0, 1.0])) + assert_equal(np.maximum(arr1[::3], arr2[:3:]), np.array([-2.0, 0.0, np.nan])) + assert_equal(np.maximum(arr1[:6:2], arr2[::3], out=out[::3]), np.array([-2.0, 10., np.nan])) + assert_equal(out, out_maxtrue) + + +class TestMinimum(_FilterInvalids): + def test_reduce(self): + dflt = np.typecodes['AllFloat'] + dint = np.typecodes['AllInteger'] + seq1 = np.arange(11) + seq2 = seq1[::-1] + func = np.minimum.reduce + for dt in dint: + tmp1 = seq1.astype(dt) + tmp2 = seq2.astype(dt) + assert_equal(func(tmp1), 0) + assert_equal(func(tmp2), 0) + for dt in dflt: + tmp1 = seq1.astype(dt) + tmp2 = seq2.astype(dt) + assert_equal(func(tmp1), 0) + assert_equal(func(tmp2), 0) + tmp1[::2] = np.nan + tmp2[::2] = np.nan + assert_equal(func(tmp1), np.nan) + assert_equal(func(tmp2), np.nan) + + def test_reduce_complex(self): + assert_equal(np.minimum.reduce([1, 2j]), 2j) + assert_equal(np.minimum.reduce([1+3j, 2j]), 2j) + + def test_float_nans(self): + nan = np.nan + arg1 = np.array([0, nan, nan]) + arg2 = np.array([nan, 0, nan]) + out = np.array([nan, nan, nan]) + assert_equal(np.minimum(arg1, arg2), out) + + def test_object_nans(self): + # Multiple checks to give this a chance to + # fail if cmp is used instead of rich compare. + # Failure cannot be guaranteed. + for i in range(1): + x = np.array(float('nan'), object) + y = 1.0 + z = np.array(float('nan'), object) + assert_(np.minimum(x, y) == 1.0) + assert_(np.minimum(z, y) == 1.0) + + def test_complex_nans(self): + nan = np.nan + for cnan in [complex(nan, 0), complex(0, nan), complex(nan, nan)]: + arg1 = np.array([0, cnan, cnan], dtype=complex) + arg2 = np.array([cnan, 0, cnan], dtype=complex) + out = np.array([nan, nan, nan], dtype=complex) + assert_equal(np.minimum(arg1, arg2), out) + + def test_object_array(self): + arg1 = np.arange(5, dtype=object) + arg2 = arg1 + 1 + assert_equal(np.minimum(arg1, arg2), arg1) + + def test_strided_array(self): + arr1 = np.array([-4.0, 1.0, 10.0, 0.0, np.nan, -np.nan, np.inf, -np.inf]) + arr2 = np.array([-2.0,-1.0, np.nan, 1.0, 0.0, np.nan, 1.0, -3.0]) + mintrue = np.array([-4.0, -1.0, np.nan, 0.0, np.nan, np.nan, 1.0, -np.inf]) + out = np.ones(8) + out_mintrue = np.array([-4.0, 1.0, 1.0, 1.0, 1.0, 1.0, np.nan, 1.0]) + assert_equal(np.minimum(arr1,arr2), mintrue) + assert_equal(np.minimum(arr1[::2],arr2[::2]), mintrue[::2]) + assert_equal(np.minimum(arr1[:4:], arr2[::2]), np.array([-4.0, np.nan, 0.0, 0.0])) + assert_equal(np.minimum(arr1[::3], arr2[:3:]), np.array([-4.0, -1.0, np.nan])) + assert_equal(np.minimum(arr1[:6:2], arr2[::3], out=out[::3]), np.array([-4.0, 1.0, np.nan])) + assert_equal(out, out_mintrue) + +class TestFmax(_FilterInvalids): + def test_reduce(self): + dflt = np.typecodes['AllFloat'] + dint = np.typecodes['AllInteger'] + seq1 = np.arange(11) + seq2 = seq1[::-1] + func = np.fmax.reduce + for dt in dint: + tmp1 = seq1.astype(dt) + tmp2 = seq2.astype(dt) + assert_equal(func(tmp1), 10) + assert_equal(func(tmp2), 10) + for dt in dflt: + tmp1 = seq1.astype(dt) + tmp2 = seq2.astype(dt) + assert_equal(func(tmp1), 10) + assert_equal(func(tmp2), 10) + tmp1[::2] = np.nan + tmp2[::2] = np.nan + assert_equal(func(tmp1), 9) + assert_equal(func(tmp2), 9) + + def test_reduce_complex(self): + assert_equal(np.fmax.reduce([1, 2j]), 1) + assert_equal(np.fmax.reduce([1+3j, 2j]), 1+3j) + + def test_float_nans(self): + nan = np.nan + arg1 = np.array([0, nan, nan]) + arg2 = np.array([nan, 0, nan]) + out = np.array([0, 0, nan]) + assert_equal(np.fmax(arg1, arg2), out) + + def test_complex_nans(self): + nan = np.nan + for cnan in [complex(nan, 0), complex(0, nan), complex(nan, nan)]: + arg1 = np.array([0, cnan, cnan], dtype=complex) + arg2 = np.array([cnan, 0, cnan], dtype=complex) + out = np.array([0, 0, nan], dtype=complex) + assert_equal(np.fmax(arg1, arg2), out) + + +class TestFmin(_FilterInvalids): + def test_reduce(self): + dflt = np.typecodes['AllFloat'] + dint = np.typecodes['AllInteger'] + seq1 = np.arange(11) + seq2 = seq1[::-1] + func = np.fmin.reduce + for dt in dint: + tmp1 = seq1.astype(dt) + tmp2 = seq2.astype(dt) + assert_equal(func(tmp1), 0) + assert_equal(func(tmp2), 0) + for dt in dflt: + tmp1 = seq1.astype(dt) + tmp2 = seq2.astype(dt) + assert_equal(func(tmp1), 0) + assert_equal(func(tmp2), 0) + tmp1[::2] = np.nan + tmp2[::2] = np.nan + assert_equal(func(tmp1), 1) + assert_equal(func(tmp2), 1) + + def test_reduce_complex(self): + assert_equal(np.fmin.reduce([1, 2j]), 2j) + assert_equal(np.fmin.reduce([1+3j, 2j]), 2j) + + def test_float_nans(self): + nan = np.nan + arg1 = np.array([0, nan, nan]) + arg2 = np.array([nan, 0, nan]) + out = np.array([0, 0, nan]) + assert_equal(np.fmin(arg1, arg2), out) + + def test_complex_nans(self): + nan = np.nan + for cnan in [complex(nan, 0), complex(0, nan), complex(nan, nan)]: + arg1 = np.array([0, cnan, cnan], dtype=complex) + arg2 = np.array([cnan, 0, cnan], dtype=complex) + out = np.array([0, 0, nan], dtype=complex) + assert_equal(np.fmin(arg1, arg2), out) + + +class TestBool: + def test_exceptions(self): + a = np.ones(1, dtype=np.bool_) + assert_raises(TypeError, np.negative, a) + assert_raises(TypeError, np.positive, a) + assert_raises(TypeError, np.subtract, a, a) + + def test_truth_table_logical(self): + # 2, 3 and 4 serves as true values + input1 = [0, 0, 3, 2] + input2 = [0, 4, 0, 2] + + typecodes = (np.typecodes['AllFloat'] + + np.typecodes['AllInteger'] + + '?') # boolean + for dtype in map(np.dtype, typecodes): + arg1 = np.asarray(input1, dtype=dtype) + arg2 = np.asarray(input2, dtype=dtype) + + # OR + out = [False, True, True, True] + for func in (np.logical_or, np.maximum): + assert_equal(func(arg1, arg2).astype(bool), out) + # AND + out = [False, False, False, True] + for func in (np.logical_and, np.minimum): + assert_equal(func(arg1, arg2).astype(bool), out) + # XOR + out = [False, True, True, False] + for func in (np.logical_xor, np.not_equal): + assert_equal(func(arg1, arg2).astype(bool), out) + + def test_truth_table_bitwise(self): + arg1 = [False, False, True, True] + arg2 = [False, True, False, True] + + out = [False, True, True, True] + assert_equal(np.bitwise_or(arg1, arg2), out) + + out = [False, False, False, True] + assert_equal(np.bitwise_and(arg1, arg2), out) + + out = [False, True, True, False] + assert_equal(np.bitwise_xor(arg1, arg2), out) + + def test_reduce(self): + none = np.array([0, 0, 0, 0], bool) + some = np.array([1, 0, 1, 1], bool) + every = np.array([1, 1, 1, 1], bool) + empty = np.array([], bool) + + arrs = [none, some, every, empty] + + for arr in arrs: + assert_equal(np.logical_and.reduce(arr), all(arr)) + + for arr in arrs: + assert_equal(np.logical_or.reduce(arr), any(arr)) + + for arr in arrs: + assert_equal(np.logical_xor.reduce(arr), arr.sum() % 2 == 1) + + +class TestBitwiseUFuncs: + + bitwise_types = [np.dtype(c) for c in '?' + 'bBhHiIlLqQ' + 'O'] + + def test_values(self): + for dt in self.bitwise_types: + zeros = np.array([0], dtype=dt) + ones = np.array([-1], dtype=dt) + msg = "dt = '%s'" % dt.char + + assert_equal(np.bitwise_not(zeros), ones, err_msg=msg) + assert_equal(np.bitwise_not(ones), zeros, err_msg=msg) + + assert_equal(np.bitwise_or(zeros, zeros), zeros, err_msg=msg) + assert_equal(np.bitwise_or(zeros, ones), ones, err_msg=msg) + assert_equal(np.bitwise_or(ones, zeros), ones, err_msg=msg) + assert_equal(np.bitwise_or(ones, ones), ones, err_msg=msg) + + assert_equal(np.bitwise_xor(zeros, zeros), zeros, err_msg=msg) + assert_equal(np.bitwise_xor(zeros, ones), ones, err_msg=msg) + assert_equal(np.bitwise_xor(ones, zeros), ones, err_msg=msg) + assert_equal(np.bitwise_xor(ones, ones), zeros, err_msg=msg) + + assert_equal(np.bitwise_and(zeros, zeros), zeros, err_msg=msg) + assert_equal(np.bitwise_and(zeros, ones), zeros, err_msg=msg) + assert_equal(np.bitwise_and(ones, zeros), zeros, err_msg=msg) + assert_equal(np.bitwise_and(ones, ones), ones, err_msg=msg) + + def test_types(self): + for dt in self.bitwise_types: + zeros = np.array([0], dtype=dt) + ones = np.array([-1], dtype=dt) + msg = "dt = '%s'" % dt.char + + assert_(np.bitwise_not(zeros).dtype == dt, msg) + assert_(np.bitwise_or(zeros, zeros).dtype == dt, msg) + assert_(np.bitwise_xor(zeros, zeros).dtype == dt, msg) + assert_(np.bitwise_and(zeros, zeros).dtype == dt, msg) + + def test_identity(self): + assert_(np.bitwise_or.identity == 0, 'bitwise_or') + assert_(np.bitwise_xor.identity == 0, 'bitwise_xor') + assert_(np.bitwise_and.identity == -1, 'bitwise_and') + + def test_reduction(self): + binary_funcs = (np.bitwise_or, np.bitwise_xor, np.bitwise_and) + + for dt in self.bitwise_types: + zeros = np.array([0], dtype=dt) + ones = np.array([-1], dtype=dt) + for f in binary_funcs: + msg = "dt: '%s', f: '%s'" % (dt, f) + assert_equal(f.reduce(zeros), zeros, err_msg=msg) + assert_equal(f.reduce(ones), ones, err_msg=msg) + + # Test empty reduction, no object dtype + for dt in self.bitwise_types[:-1]: + # No object array types + empty = np.array([], dtype=dt) + for f in binary_funcs: + msg = "dt: '%s', f: '%s'" % (dt, f) + tgt = np.array(f.identity, dtype=dt) + res = f.reduce(empty) + assert_equal(res, tgt, err_msg=msg) + assert_(res.dtype == tgt.dtype, msg) + + # Empty object arrays use the identity. Note that the types may + # differ, the actual type used is determined by the assign_identity + # function and is not the same as the type returned by the identity + # method. + for f in binary_funcs: + msg = "dt: '%s'" % (f,) + empty = np.array([], dtype=object) + tgt = f.identity + res = f.reduce(empty) + assert_equal(res, tgt, err_msg=msg) + + # Non-empty object arrays do not use the identity + for f in binary_funcs: + msg = "dt: '%s'" % (f,) + btype = np.array([True], dtype=object) + assert_(type(f.reduce(btype)) is bool, msg) + + +class TestInt: + def test_logical_not(self): + x = np.ones(10, dtype=np.int16) + o = np.ones(10 * 2, dtype=bool) + tgt = o.copy() + tgt[::2] = False + os = o[::2] + assert_array_equal(np.logical_not(x, out=os), False) + assert_array_equal(o, tgt) + + +class TestFloatingPoint: + def test_floating_point(self): + assert_equal(ncu.FLOATING_POINT_SUPPORT, 1) + + +class TestDegrees: + def test_degrees(self): + assert_almost_equal(ncu.degrees(np.pi), 180.0) + assert_almost_equal(ncu.degrees(-0.5*np.pi), -90.0) + + +class TestRadians: + def test_radians(self): + assert_almost_equal(ncu.radians(180.0), np.pi) + assert_almost_equal(ncu.radians(-90.0), -0.5*np.pi) + + +class TestHeavside: + def test_heaviside(self): + x = np.array([[-30.0, -0.1, 0.0, 0.2], [7.5, np.nan, np.inf, -np.inf]]) + expectedhalf = np.array([[0.0, 0.0, 0.5, 1.0], [1.0, np.nan, 1.0, 0.0]]) + expected1 = expectedhalf.copy() + expected1[0, 2] = 1 + + h = ncu.heaviside(x, 0.5) + assert_equal(h, expectedhalf) + + h = ncu.heaviside(x, 1.0) + assert_equal(h, expected1) + + x = x.astype(np.float32) + + h = ncu.heaviside(x, np.float32(0.5)) + assert_equal(h, expectedhalf.astype(np.float32)) + + h = ncu.heaviside(x, np.float32(1.0)) + assert_equal(h, expected1.astype(np.float32)) + + +class TestSign: + def test_sign(self): + a = np.array([np.inf, -np.inf, np.nan, 0.0, 3.0, -3.0]) + out = np.zeros(a.shape) + tgt = np.array([1., -1., np.nan, 0.0, 1.0, -1.0]) + + with np.errstate(invalid='ignore'): + res = ncu.sign(a) + assert_equal(res, tgt) + res = ncu.sign(a, out) + assert_equal(res, tgt) + assert_equal(out, tgt) + + def test_sign_dtype_object(self): + # In reference to github issue #6229 + + foo = np.array([-.1, 0, .1]) + a = np.sign(foo.astype(object)) + b = np.sign(foo) + + assert_array_equal(a, b) + + def test_sign_dtype_nan_object(self): + # In reference to github issue #6229 + def test_nan(): + foo = np.array([np.nan]) + # FIXME: a not used + a = np.sign(foo.astype(object)) + + assert_raises(TypeError, test_nan) + +class TestMinMax: + def test_minmax_blocked(self): + # simd tests on max/min, test all alignments, slow but important + # for 2 * vz + 2 * (vs - 1) + 1 (unrolled once) + for dt, sz in [(np.float32, 15), (np.float64, 7)]: + for out, inp, msg in _gen_alignment_data(dtype=dt, type='unary', + max_size=sz): + for i in range(inp.size): + inp[:] = np.arange(inp.size, dtype=dt) + inp[i] = np.nan + emsg = lambda: '%r\n%s' % (inp, msg) + with suppress_warnings() as sup: + sup.filter(RuntimeWarning, + "invalid value encountered in reduce") + assert_(np.isnan(inp.max()), msg=emsg) + assert_(np.isnan(inp.min()), msg=emsg) + + inp[i] = 1e10 + assert_equal(inp.max(), 1e10, err_msg=msg) + inp[i] = -1e10 + assert_equal(inp.min(), -1e10, err_msg=msg) + + def test_lower_align(self): + # check data that is not aligned to element size + # i.e doubles are aligned to 4 bytes on i386 + d = np.zeros(23 * 8, dtype=np.int8)[4:-4].view(np.float64) + assert_equal(d.max(), d[0]) + assert_equal(d.min(), d[0]) + + def test_reduce_reorder(self): + # gh 10370, 11029 Some compilers reorder the call to npy_getfloatstatus + # and put it before the call to an intrisic function that causes + # invalid status to be set. Also make sure warnings are not emitted + for n in (2, 4, 8, 16, 32): + for dt in (np.float32, np.float16, np.complex64): + for r in np.diagflat(np.array([np.nan] * n, dtype=dt)): + assert_equal(np.min(r), np.nan) + + def test_minimize_no_warns(self): + a = np.minimum(np.nan, 1) + assert_equal(a, np.nan) + + +class TestAbsoluteNegative: + def test_abs_neg_blocked(self): + # simd tests on abs, test all alignments for vz + 2 * (vs - 1) + 1 + for dt, sz in [(np.float32, 11), (np.float64, 5)]: + for out, inp, msg in _gen_alignment_data(dtype=dt, type='unary', + max_size=sz): + tgt = [ncu.absolute(i) for i in inp] + np.absolute(inp, out=out) + assert_equal(out, tgt, err_msg=msg) + assert_((out >= 0).all()) + + tgt = [-1*(i) for i in inp] + np.negative(inp, out=out) + assert_equal(out, tgt, err_msg=msg) + + for v in [np.nan, -np.inf, np.inf]: + for i in range(inp.size): + d = np.arange(inp.size, dtype=dt) + inp[:] = -d + inp[i] = v + d[i] = -v if v == -np.inf else v + assert_array_equal(np.abs(inp), d, err_msg=msg) + np.abs(inp, out=out) + assert_array_equal(out, d, err_msg=msg) + + assert_array_equal(-inp, -1*inp, err_msg=msg) + d = -1 * inp + np.negative(inp, out=out) + assert_array_equal(out, d, err_msg=msg) + + def test_lower_align(self): + # check data that is not aligned to element size + # i.e doubles are aligned to 4 bytes on i386 + d = np.zeros(23 * 8, dtype=np.int8)[4:-4].view(np.float64) + assert_equal(np.abs(d), d) + assert_equal(np.negative(d), -d) + np.negative(d, out=d) + np.negative(np.ones_like(d), out=d) + np.abs(d, out=d) + np.abs(np.ones_like(d), out=d) + + +class TestPositive: + def test_valid(self): + valid_dtypes = [int, float, complex, object] + for dtype in valid_dtypes: + x = np.arange(5, dtype=dtype) + result = np.positive(x) + assert_equal(x, result, err_msg=str(dtype)) + + def test_invalid(self): + with assert_raises(TypeError): + np.positive(True) + with assert_raises(TypeError): + np.positive(np.datetime64('2000-01-01')) + with assert_raises(TypeError): + np.positive(np.array(['foo'], dtype=str)) + with assert_raises(TypeError): + np.positive(np.array(['bar'], dtype=object)) + + +class TestSpecialMethods: + def test_wrap(self): + + class with_wrap: + def __array__(self): + return np.zeros(1) + + def __array_wrap__(self, arr, context): + r = with_wrap() + r.arr = arr + r.context = context + return r + + a = with_wrap() + x = ncu.minimum(a, a) + assert_equal(x.arr, np.zeros(1)) + func, args, i = x.context + assert_(func is ncu.minimum) + assert_equal(len(args), 2) + assert_equal(args[0], a) + assert_equal(args[1], a) + assert_equal(i, 0) + + def test_wrap_and_prepare_out(self): + # Calling convention for out should not affect how special methods are + # called + + class StoreArrayPrepareWrap(np.ndarray): + _wrap_args = None + _prepare_args = None + def __new__(cls): + return np.empty(()).view(cls) + def __array_wrap__(self, obj, context): + self._wrap_args = context[1] + return obj + def __array_prepare__(self, obj, context): + self._prepare_args = context[1] + return obj + @property + def args(self): + # We need to ensure these are fetched at the same time, before + # any other ufuncs are called by the assertions + return (self._prepare_args, self._wrap_args) + def __repr__(self): + return "a" # for short test output + + def do_test(f_call, f_expected): + a = StoreArrayPrepareWrap() + f_call(a) + p, w = a.args + expected = f_expected(a) + try: + assert_equal(p, expected) + assert_equal(w, expected) + except AssertionError as e: + # assert_equal produces truly useless error messages + raise AssertionError("\n".join([ + "Bad arguments passed in ufunc call", + " expected: {}".format(expected), + " __array_prepare__ got: {}".format(p), + " __array_wrap__ got: {}".format(w) + ])) + + # method not on the out argument + do_test(lambda a: np.add(a, 0), lambda a: (a, 0)) + do_test(lambda a: np.add(a, 0, None), lambda a: (a, 0)) + do_test(lambda a: np.add(a, 0, out=None), lambda a: (a, 0)) + do_test(lambda a: np.add(a, 0, out=(None,)), lambda a: (a, 0)) + + # method on the out argument + do_test(lambda a: np.add(0, 0, a), lambda a: (0, 0, a)) + do_test(lambda a: np.add(0, 0, out=a), lambda a: (0, 0, a)) + do_test(lambda a: np.add(0, 0, out=(a,)), lambda a: (0, 0, a)) + + def test_wrap_with_iterable(self): + # test fix for bug #1026: + + class with_wrap(np.ndarray): + __array_priority__ = 10 + + def __new__(cls): + return np.asarray(1).view(cls).copy() + + def __array_wrap__(self, arr, context): + return arr.view(type(self)) + + a = with_wrap() + x = ncu.multiply(a, (1, 2, 3)) + assert_(isinstance(x, with_wrap)) + assert_array_equal(x, np.array((1, 2, 3))) + + def test_priority_with_scalar(self): + # test fix for bug #826: + + class A(np.ndarray): + __array_priority__ = 10 + + def __new__(cls): + return np.asarray(1.0, 'float64').view(cls).copy() + + a = A() + x = np.float64(1)*a + assert_(isinstance(x, A)) + assert_array_equal(x, np.array(1)) + + def test_old_wrap(self): + + class with_wrap: + def __array__(self): + return np.zeros(1) + + def __array_wrap__(self, arr): + r = with_wrap() + r.arr = arr + return r + + a = with_wrap() + x = ncu.minimum(a, a) + assert_equal(x.arr, np.zeros(1)) + + def test_priority(self): + + class A: + def __array__(self): + return np.zeros(1) + + def __array_wrap__(self, arr, context): + r = type(self)() + r.arr = arr + r.context = context + return r + + class B(A): + __array_priority__ = 20. + + class C(A): + __array_priority__ = 40. + + x = np.zeros(1) + a = A() + b = B() + c = C() + f = ncu.minimum + assert_(type(f(x, x)) is np.ndarray) + assert_(type(f(x, a)) is A) + assert_(type(f(x, b)) is B) + assert_(type(f(x, c)) is C) + assert_(type(f(a, x)) is A) + assert_(type(f(b, x)) is B) + assert_(type(f(c, x)) is C) + + assert_(type(f(a, a)) is A) + assert_(type(f(a, b)) is B) + assert_(type(f(b, a)) is B) + assert_(type(f(b, b)) is B) + assert_(type(f(b, c)) is C) + assert_(type(f(c, b)) is C) + assert_(type(f(c, c)) is C) + + assert_(type(ncu.exp(a) is A)) + assert_(type(ncu.exp(b) is B)) + assert_(type(ncu.exp(c) is C)) + + def test_failing_wrap(self): + + class A: + def __array__(self): + return np.zeros(2) + + def __array_wrap__(self, arr, context): + raise RuntimeError + + a = A() + assert_raises(RuntimeError, ncu.maximum, a, a) + assert_raises(RuntimeError, ncu.maximum.reduce, a) + + def test_failing_out_wrap(self): + + singleton = np.array([1.0]) + + class Ok(np.ndarray): + def __array_wrap__(self, obj): + return singleton + + class Bad(np.ndarray): + def __array_wrap__(self, obj): + raise RuntimeError + + ok = np.empty(1).view(Ok) + bad = np.empty(1).view(Bad) + # double-free (segfault) of "ok" if "bad" raises an exception + for i in range(10): + assert_raises(RuntimeError, ncu.frexp, 1, ok, bad) + + def test_none_wrap(self): + # Tests that issue #8507 is resolved. Previously, this would segfault + + class A: + def __array__(self): + return np.zeros(1) + + def __array_wrap__(self, arr, context=None): + return None + + a = A() + assert_equal(ncu.maximum(a, a), None) + + def test_default_prepare(self): + + class with_wrap: + __array_priority__ = 10 + + def __array__(self): + return np.zeros(1) + + def __array_wrap__(self, arr, context): + return arr + + a = with_wrap() + x = ncu.minimum(a, a) + assert_equal(x, np.zeros(1)) + assert_equal(type(x), np.ndarray) + + def test_prepare(self): + + class with_prepare(np.ndarray): + __array_priority__ = 10 + + def __array_prepare__(self, arr, context): + # make sure we can return a new + return np.array(arr).view(type=with_prepare) + + a = np.array(1).view(type=with_prepare) + x = np.add(a, a) + assert_equal(x, np.array(2)) + assert_equal(type(x), with_prepare) + + def test_prepare_out(self): + + class with_prepare(np.ndarray): + __array_priority__ = 10 + + def __array_prepare__(self, arr, context): + return np.array(arr).view(type=with_prepare) + + a = np.array([1]).view(type=with_prepare) + x = np.add(a, a, a) + # Returned array is new, because of the strange + # __array_prepare__ above + assert_(not np.shares_memory(x, a)) + assert_equal(x, np.array([2])) + assert_equal(type(x), with_prepare) + + def test_failing_prepare(self): + + class A: + def __array__(self): + return np.zeros(1) + + def __array_prepare__(self, arr, context=None): + raise RuntimeError + + a = A() + assert_raises(RuntimeError, ncu.maximum, a, a) + + def test_array_too_many_args(self): + + class A(object): + def __array__(self, dtype, context): + return np.zeros(1) + + a = A() + assert_raises_regex(TypeError, '2 required positional', np.sum, a) + + def test_ufunc_override(self): + # check override works even with instance with high priority. + class A: + def __array_ufunc__(self, func, method, *inputs, **kwargs): + return self, func, method, inputs, kwargs + + class MyNDArray(np.ndarray): + __array_priority__ = 100 + + a = A() + b = np.array([1]).view(MyNDArray) + res0 = np.multiply(a, b) + res1 = np.multiply(b, b, out=a) + + # self + assert_equal(res0[0], a) + assert_equal(res1[0], a) + assert_equal(res0[1], np.multiply) + assert_equal(res1[1], np.multiply) + assert_equal(res0[2], '__call__') + assert_equal(res1[2], '__call__') + assert_equal(res0[3], (a, b)) + assert_equal(res1[3], (b, b)) + assert_equal(res0[4], {}) + assert_equal(res1[4], {'out': (a,)}) + + def test_ufunc_override_mro(self): + + # Some multi arg functions for testing. + def tres_mul(a, b, c): + return a * b * c + + def quatro_mul(a, b, c, d): + return a * b * c * d + + # Make these into ufuncs. + three_mul_ufunc = np.frompyfunc(tres_mul, 3, 1) + four_mul_ufunc = np.frompyfunc(quatro_mul, 4, 1) + + class A: + def __array_ufunc__(self, func, method, *inputs, **kwargs): + return "A" + + class ASub(A): + def __array_ufunc__(self, func, method, *inputs, **kwargs): + return "ASub" + + class B: + def __array_ufunc__(self, func, method, *inputs, **kwargs): + return "B" + + class C: + def __init__(self): + self.count = 0 + + def __array_ufunc__(self, func, method, *inputs, **kwargs): + self.count += 1 + return NotImplemented + + class CSub(C): + def __array_ufunc__(self, func, method, *inputs, **kwargs): + self.count += 1 + return NotImplemented + + a = A() + a_sub = ASub() + b = B() + c = C() + + # Standard + res = np.multiply(a, a_sub) + assert_equal(res, "ASub") + res = np.multiply(a_sub, b) + assert_equal(res, "ASub") + + # With 1 NotImplemented + res = np.multiply(c, a) + assert_equal(res, "A") + assert_equal(c.count, 1) + # Check our counter works, so we can trust tests below. + res = np.multiply(c, a) + assert_equal(c.count, 2) + + # Both NotImplemented. + c = C() + c_sub = CSub() + assert_raises(TypeError, np.multiply, c, c_sub) + assert_equal(c.count, 1) + assert_equal(c_sub.count, 1) + c.count = c_sub.count = 0 + assert_raises(TypeError, np.multiply, c_sub, c) + assert_equal(c.count, 1) + assert_equal(c_sub.count, 1) + c.count = 0 + assert_raises(TypeError, np.multiply, c, c) + assert_equal(c.count, 1) + c.count = 0 + assert_raises(TypeError, np.multiply, 2, c) + assert_equal(c.count, 1) + + # Ternary testing. + assert_equal(three_mul_ufunc(a, 1, 2), "A") + assert_equal(three_mul_ufunc(1, a, 2), "A") + assert_equal(three_mul_ufunc(1, 2, a), "A") + + assert_equal(three_mul_ufunc(a, a, 6), "A") + assert_equal(three_mul_ufunc(a, 2, a), "A") + assert_equal(three_mul_ufunc(a, 2, b), "A") + assert_equal(three_mul_ufunc(a, 2, a_sub), "ASub") + assert_equal(three_mul_ufunc(a, a_sub, 3), "ASub") + c.count = 0 + assert_equal(three_mul_ufunc(c, a_sub, 3), "ASub") + assert_equal(c.count, 1) + c.count = 0 + assert_equal(three_mul_ufunc(1, a_sub, c), "ASub") + assert_equal(c.count, 0) + + c.count = 0 + assert_equal(three_mul_ufunc(a, b, c), "A") + assert_equal(c.count, 0) + c_sub.count = 0 + assert_equal(three_mul_ufunc(a, b, c_sub), "A") + assert_equal(c_sub.count, 0) + assert_equal(three_mul_ufunc(1, 2, b), "B") + + assert_raises(TypeError, three_mul_ufunc, 1, 2, c) + assert_raises(TypeError, three_mul_ufunc, c_sub, 2, c) + assert_raises(TypeError, three_mul_ufunc, c_sub, 2, 3) + + # Quaternary testing. + assert_equal(four_mul_ufunc(a, 1, 2, 3), "A") + assert_equal(four_mul_ufunc(1, a, 2, 3), "A") + assert_equal(four_mul_ufunc(1, 1, a, 3), "A") + assert_equal(four_mul_ufunc(1, 1, 2, a), "A") + + assert_equal(four_mul_ufunc(a, b, 2, 3), "A") + assert_equal(four_mul_ufunc(1, a, 2, b), "A") + assert_equal(four_mul_ufunc(b, 1, a, 3), "B") + assert_equal(four_mul_ufunc(a_sub, 1, 2, a), "ASub") + assert_equal(four_mul_ufunc(a, 1, 2, a_sub), "ASub") + + c = C() + c_sub = CSub() + assert_raises(TypeError, four_mul_ufunc, 1, 2, 3, c) + assert_equal(c.count, 1) + c.count = 0 + assert_raises(TypeError, four_mul_ufunc, 1, 2, c_sub, c) + assert_equal(c_sub.count, 1) + assert_equal(c.count, 1) + c2 = C() + c.count = c_sub.count = 0 + assert_raises(TypeError, four_mul_ufunc, 1, c, c_sub, c2) + assert_equal(c_sub.count, 1) + assert_equal(c.count, 1) + assert_equal(c2.count, 0) + c.count = c2.count = c_sub.count = 0 + assert_raises(TypeError, four_mul_ufunc, c2, c, c_sub, c) + assert_equal(c_sub.count, 1) + assert_equal(c.count, 0) + assert_equal(c2.count, 1) + + def test_ufunc_override_methods(self): + + class A: + def __array_ufunc__(self, ufunc, method, *inputs, **kwargs): + return self, ufunc, method, inputs, kwargs + + # __call__ + a = A() + res = np.multiply.__call__(1, a, foo='bar', answer=42) + assert_equal(res[0], a) + assert_equal(res[1], np.multiply) + assert_equal(res[2], '__call__') + assert_equal(res[3], (1, a)) + assert_equal(res[4], {'foo': 'bar', 'answer': 42}) + + # __call__, wrong args + assert_raises(TypeError, np.multiply, a) + assert_raises(TypeError, np.multiply, a, a, a, a) + assert_raises(TypeError, np.multiply, a, a, sig='a', signature='a') + assert_raises(TypeError, ncu_tests.inner1d, a, a, axis=0, axes=[0, 0]) + + # reduce, positional args + res = np.multiply.reduce(a, 'axis0', 'dtype0', 'out0', 'keep0') + assert_equal(res[0], a) + assert_equal(res[1], np.multiply) + assert_equal(res[2], 'reduce') + assert_equal(res[3], (a,)) + assert_equal(res[4], {'dtype':'dtype0', + 'out': ('out0',), + 'keepdims': 'keep0', + 'axis': 'axis0'}) + + # reduce, kwargs + res = np.multiply.reduce(a, axis='axis0', dtype='dtype0', out='out0', + keepdims='keep0', initial='init0', + where='where0') + assert_equal(res[0], a) + assert_equal(res[1], np.multiply) + assert_equal(res[2], 'reduce') + assert_equal(res[3], (a,)) + assert_equal(res[4], {'dtype':'dtype0', + 'out': ('out0',), + 'keepdims': 'keep0', + 'axis': 'axis0', + 'initial': 'init0', + 'where': 'where0'}) + + # reduce, output equal to None removed, but not other explicit ones, + # even if they are at their default value. + res = np.multiply.reduce(a, 0, None, None, False) + assert_equal(res[4], {'axis': 0, 'dtype': None, 'keepdims': False}) + res = np.multiply.reduce(a, out=None, axis=0, keepdims=True) + assert_equal(res[4], {'axis': 0, 'keepdims': True}) + res = np.multiply.reduce(a, None, out=(None,), dtype=None) + assert_equal(res[4], {'axis': None, 'dtype': None}) + res = np.multiply.reduce(a, 0, None, None, False, 2, True) + assert_equal(res[4], {'axis': 0, 'dtype': None, 'keepdims': False, + 'initial': 2, 'where': True}) + # np._NoValue ignored for initial + res = np.multiply.reduce(a, 0, None, None, False, + np._NoValue, True) + assert_equal(res[4], {'axis': 0, 'dtype': None, 'keepdims': False, + 'where': True}) + # None kept for initial, True for where. + res = np.multiply.reduce(a, 0, None, None, False, None, True) + assert_equal(res[4], {'axis': 0, 'dtype': None, 'keepdims': False, + 'initial': None, 'where': True}) + + # reduce, wrong args + assert_raises(ValueError, np.multiply.reduce, a, out=()) + assert_raises(ValueError, np.multiply.reduce, a, out=('out0', 'out1')) + assert_raises(TypeError, np.multiply.reduce, a, 'axis0', axis='axis0') + + # accumulate, pos args + res = np.multiply.accumulate(a, 'axis0', 'dtype0', 'out0') + assert_equal(res[0], a) + assert_equal(res[1], np.multiply) + assert_equal(res[2], 'accumulate') + assert_equal(res[3], (a,)) + assert_equal(res[4], {'dtype':'dtype0', + 'out': ('out0',), + 'axis': 'axis0'}) + + # accumulate, kwargs + res = np.multiply.accumulate(a, axis='axis0', dtype='dtype0', + out='out0') + assert_equal(res[0], a) + assert_equal(res[1], np.multiply) + assert_equal(res[2], 'accumulate') + assert_equal(res[3], (a,)) + assert_equal(res[4], {'dtype':'dtype0', + 'out': ('out0',), + 'axis': 'axis0'}) + + # accumulate, output equal to None removed. + res = np.multiply.accumulate(a, 0, None, None) + assert_equal(res[4], {'axis': 0, 'dtype': None}) + res = np.multiply.accumulate(a, out=None, axis=0, dtype='dtype1') + assert_equal(res[4], {'axis': 0, 'dtype': 'dtype1'}) + res = np.multiply.accumulate(a, None, out=(None,), dtype=None) + assert_equal(res[4], {'axis': None, 'dtype': None}) + + # accumulate, wrong args + assert_raises(ValueError, np.multiply.accumulate, a, out=()) + assert_raises(ValueError, np.multiply.accumulate, a, + out=('out0', 'out1')) + assert_raises(TypeError, np.multiply.accumulate, a, + 'axis0', axis='axis0') + + # reduceat, pos args + res = np.multiply.reduceat(a, [4, 2], 'axis0', 'dtype0', 'out0') + assert_equal(res[0], a) + assert_equal(res[1], np.multiply) + assert_equal(res[2], 'reduceat') + assert_equal(res[3], (a, [4, 2])) + assert_equal(res[4], {'dtype':'dtype0', + 'out': ('out0',), + 'axis': 'axis0'}) + + # reduceat, kwargs + res = np.multiply.reduceat(a, [4, 2], axis='axis0', dtype='dtype0', + out='out0') + assert_equal(res[0], a) + assert_equal(res[1], np.multiply) + assert_equal(res[2], 'reduceat') + assert_equal(res[3], (a, [4, 2])) + assert_equal(res[4], {'dtype':'dtype0', + 'out': ('out0',), + 'axis': 'axis0'}) + + # reduceat, output equal to None removed. + res = np.multiply.reduceat(a, [4, 2], 0, None, None) + assert_equal(res[4], {'axis': 0, 'dtype': None}) + res = np.multiply.reduceat(a, [4, 2], axis=None, out=None, dtype='dt') + assert_equal(res[4], {'axis': None, 'dtype': 'dt'}) + res = np.multiply.reduceat(a, [4, 2], None, None, out=(None,)) + assert_equal(res[4], {'axis': None, 'dtype': None}) + + # reduceat, wrong args + assert_raises(ValueError, np.multiply.reduce, a, [4, 2], out=()) + assert_raises(ValueError, np.multiply.reduce, a, [4, 2], + out=('out0', 'out1')) + assert_raises(TypeError, np.multiply.reduce, a, [4, 2], + 'axis0', axis='axis0') + + # outer + res = np.multiply.outer(a, 42) + assert_equal(res[0], a) + assert_equal(res[1], np.multiply) + assert_equal(res[2], 'outer') + assert_equal(res[3], (a, 42)) + assert_equal(res[4], {}) + + # outer, wrong args + assert_raises(TypeError, np.multiply.outer, a) + assert_raises(TypeError, np.multiply.outer, a, a, a, a) + assert_raises(TypeError, np.multiply.outer, a, a, sig='a', signature='a') + + # at + res = np.multiply.at(a, [4, 2], 'b0') + assert_equal(res[0], a) + assert_equal(res[1], np.multiply) + assert_equal(res[2], 'at') + assert_equal(res[3], (a, [4, 2], 'b0')) + + # at, wrong args + assert_raises(TypeError, np.multiply.at, a) + assert_raises(TypeError, np.multiply.at, a, a, a, a) + + def test_ufunc_override_out(self): + + class A: + def __array_ufunc__(self, ufunc, method, *inputs, **kwargs): + return kwargs + + class B: + def __array_ufunc__(self, ufunc, method, *inputs, **kwargs): + return kwargs + + a = A() + b = B() + res0 = np.multiply(a, b, 'out_arg') + res1 = np.multiply(a, b, out='out_arg') + res2 = np.multiply(2, b, 'out_arg') + res3 = np.multiply(3, b, out='out_arg') + res4 = np.multiply(a, 4, 'out_arg') + res5 = np.multiply(a, 5, out='out_arg') + + assert_equal(res0['out'][0], 'out_arg') + assert_equal(res1['out'][0], 'out_arg') + assert_equal(res2['out'][0], 'out_arg') + assert_equal(res3['out'][0], 'out_arg') + assert_equal(res4['out'][0], 'out_arg') + assert_equal(res5['out'][0], 'out_arg') + + # ufuncs with multiple output modf and frexp. + res6 = np.modf(a, 'out0', 'out1') + res7 = np.frexp(a, 'out0', 'out1') + assert_equal(res6['out'][0], 'out0') + assert_equal(res6['out'][1], 'out1') + assert_equal(res7['out'][0], 'out0') + assert_equal(res7['out'][1], 'out1') + + # While we're at it, check that default output is never passed on. + assert_(np.sin(a, None) == {}) + assert_(np.sin(a, out=None) == {}) + assert_(np.sin(a, out=(None,)) == {}) + assert_(np.modf(a, None) == {}) + assert_(np.modf(a, None, None) == {}) + assert_(np.modf(a, out=(None, None)) == {}) + with assert_raises(TypeError): + # Out argument must be tuple, since there are multiple outputs. + np.modf(a, out=None) + + # don't give positional and output argument, or too many arguments. + # wrong number of arguments in the tuple is an error too. + assert_raises(TypeError, np.multiply, a, b, 'one', out='two') + assert_raises(TypeError, np.multiply, a, b, 'one', 'two') + assert_raises(ValueError, np.multiply, a, b, out=('one', 'two')) + assert_raises(ValueError, np.multiply, a, out=()) + assert_raises(TypeError, np.modf, a, 'one', out=('two', 'three')) + assert_raises(TypeError, np.modf, a, 'one', 'two', 'three') + assert_raises(ValueError, np.modf, a, out=('one', 'two', 'three')) + assert_raises(ValueError, np.modf, a, out=('one',)) + + def test_ufunc_override_exception(self): + + class A: + def __array_ufunc__(self, *a, **kwargs): + raise ValueError("oops") + + a = A() + assert_raises(ValueError, np.negative, 1, out=a) + assert_raises(ValueError, np.negative, a) + assert_raises(ValueError, np.divide, 1., a) + + def test_ufunc_override_not_implemented(self): + + class A: + def __array_ufunc__(self, *args, **kwargs): + return NotImplemented + + msg = ("operand type(s) all returned NotImplemented from " + "__array_ufunc__(, '__call__', <*>): 'A'") + with assert_raises_regex(TypeError, fnmatch.translate(msg)): + np.negative(A()) + + msg = ("operand type(s) all returned NotImplemented from " + "__array_ufunc__(, '__call__', <*>, , " + "out=(1,)): 'A', 'object', 'int'") + with assert_raises_regex(TypeError, fnmatch.translate(msg)): + np.add(A(), object(), out=1) + + def test_ufunc_override_disabled(self): + + class OptOut: + __array_ufunc__ = None + + opt_out = OptOut() + + # ufuncs always raise + msg = "operand 'OptOut' does not support ufuncs" + with assert_raises_regex(TypeError, msg): + np.add(opt_out, 1) + with assert_raises_regex(TypeError, msg): + np.add(1, opt_out) + with assert_raises_regex(TypeError, msg): + np.negative(opt_out) + + # opt-outs still hold even when other arguments have pathological + # __array_ufunc__ implementations + + class GreedyArray: + def __array_ufunc__(self, *args, **kwargs): + return self + + greedy = GreedyArray() + assert_(np.negative(greedy) is greedy) + with assert_raises_regex(TypeError, msg): + np.add(greedy, opt_out) + with assert_raises_regex(TypeError, msg): + np.add(greedy, 1, out=opt_out) + + def test_gufunc_override(self): + # gufunc are just ufunc instances, but follow a different path, + # so check __array_ufunc__ overrides them properly. + class A: + def __array_ufunc__(self, ufunc, method, *inputs, **kwargs): + return self, ufunc, method, inputs, kwargs + + inner1d = ncu_tests.inner1d + a = A() + res = inner1d(a, a) + assert_equal(res[0], a) + assert_equal(res[1], inner1d) + assert_equal(res[2], '__call__') + assert_equal(res[3], (a, a)) + assert_equal(res[4], {}) + + res = inner1d(1, 1, out=a) + assert_equal(res[0], a) + assert_equal(res[1], inner1d) + assert_equal(res[2], '__call__') + assert_equal(res[3], (1, 1)) + assert_equal(res[4], {'out': (a,)}) + + # wrong number of arguments in the tuple is an error too. + assert_raises(TypeError, inner1d, a, out='two') + assert_raises(TypeError, inner1d, a, a, 'one', out='two') + assert_raises(TypeError, inner1d, a, a, 'one', 'two') + assert_raises(ValueError, inner1d, a, a, out=('one', 'two')) + assert_raises(ValueError, inner1d, a, a, out=()) + + def test_ufunc_override_with_super(self): + # NOTE: this class is used in doc/source/user/basics.subclassing.rst + # if you make any changes here, do update it there too. + class A(np.ndarray): + def __array_ufunc__(self, ufunc, method, *inputs, out=None, **kwargs): + args = [] + in_no = [] + for i, input_ in enumerate(inputs): + if isinstance(input_, A): + in_no.append(i) + args.append(input_.view(np.ndarray)) + else: + args.append(input_) + + outputs = out + out_no = [] + if outputs: + out_args = [] + for j, output in enumerate(outputs): + if isinstance(output, A): + out_no.append(j) + out_args.append(output.view(np.ndarray)) + else: + out_args.append(output) + kwargs['out'] = tuple(out_args) + else: + outputs = (None,) * ufunc.nout + + info = {} + if in_no: + info['inputs'] = in_no + if out_no: + info['outputs'] = out_no + + results = super(A, self).__array_ufunc__(ufunc, method, + *args, **kwargs) + if results is NotImplemented: + return NotImplemented + + if method == 'at': + if isinstance(inputs[0], A): + inputs[0].info = info + return + + if ufunc.nout == 1: + results = (results,) + + results = tuple((np.asarray(result).view(A) + if output is None else output) + for result, output in zip(results, outputs)) + if results and isinstance(results[0], A): + results[0].info = info + + return results[0] if len(results) == 1 else results + + class B: + def __array_ufunc__(self, ufunc, method, *inputs, **kwargs): + if any(isinstance(input_, A) for input_ in inputs): + return "A!" + else: + return NotImplemented + + d = np.arange(5.) + # 1 input, 1 output + a = np.arange(5.).view(A) + b = np.sin(a) + check = np.sin(d) + assert_(np.all(check == b)) + assert_equal(b.info, {'inputs': [0]}) + b = np.sin(d, out=(a,)) + assert_(np.all(check == b)) + assert_equal(b.info, {'outputs': [0]}) + assert_(b is a) + a = np.arange(5.).view(A) + b = np.sin(a, out=a) + assert_(np.all(check == b)) + assert_equal(b.info, {'inputs': [0], 'outputs': [0]}) + + # 1 input, 2 outputs + a = np.arange(5.).view(A) + b1, b2 = np.modf(a) + assert_equal(b1.info, {'inputs': [0]}) + b1, b2 = np.modf(d, out=(None, a)) + assert_(b2 is a) + assert_equal(b1.info, {'outputs': [1]}) + a = np.arange(5.).view(A) + b = np.arange(5.).view(A) + c1, c2 = np.modf(a, out=(a, b)) + assert_(c1 is a) + assert_(c2 is b) + assert_equal(c1.info, {'inputs': [0], 'outputs': [0, 1]}) + + # 2 input, 1 output + a = np.arange(5.).view(A) + b = np.arange(5.).view(A) + c = np.add(a, b, out=a) + assert_(c is a) + assert_equal(c.info, {'inputs': [0, 1], 'outputs': [0]}) + # some tests with a non-ndarray subclass + a = np.arange(5.) + b = B() + assert_(a.__array_ufunc__(np.add, '__call__', a, b) is NotImplemented) + assert_(b.__array_ufunc__(np.add, '__call__', a, b) is NotImplemented) + assert_raises(TypeError, np.add, a, b) + a = a.view(A) + assert_(a.__array_ufunc__(np.add, '__call__', a, b) is NotImplemented) + assert_(b.__array_ufunc__(np.add, '__call__', a, b) == "A!") + assert_(np.add(a, b) == "A!") + # regression check for gh-9102 -- tests ufunc.reduce implicitly. + d = np.array([[1, 2, 3], [1, 2, 3]]) + a = d.view(A) + c = a.any() + check = d.any() + assert_equal(c, check) + assert_(c.info, {'inputs': [0]}) + c = a.max() + check = d.max() + assert_equal(c, check) + assert_(c.info, {'inputs': [0]}) + b = np.array(0).view(A) + c = a.max(out=b) + assert_equal(c, check) + assert_(c is b) + assert_(c.info, {'inputs': [0], 'outputs': [0]}) + check = a.max(axis=0) + b = np.zeros_like(check).view(A) + c = a.max(axis=0, out=b) + assert_equal(c, check) + assert_(c is b) + assert_(c.info, {'inputs': [0], 'outputs': [0]}) + # simple explicit tests of reduce, accumulate, reduceat + check = np.add.reduce(d, axis=1) + c = np.add.reduce(a, axis=1) + assert_equal(c, check) + assert_(c.info, {'inputs': [0]}) + b = np.zeros_like(c) + c = np.add.reduce(a, 1, None, b) + assert_equal(c, check) + assert_(c is b) + assert_(c.info, {'inputs': [0], 'outputs': [0]}) + check = np.add.accumulate(d, axis=0) + c = np.add.accumulate(a, axis=0) + assert_equal(c, check) + assert_(c.info, {'inputs': [0]}) + b = np.zeros_like(c) + c = np.add.accumulate(a, 0, None, b) + assert_equal(c, check) + assert_(c is b) + assert_(c.info, {'inputs': [0], 'outputs': [0]}) + indices = [0, 2, 1] + check = np.add.reduceat(d, indices, axis=1) + c = np.add.reduceat(a, indices, axis=1) + assert_equal(c, check) + assert_(c.info, {'inputs': [0]}) + b = np.zeros_like(c) + c = np.add.reduceat(a, indices, 1, None, b) + assert_equal(c, check) + assert_(c is b) + assert_(c.info, {'inputs': [0], 'outputs': [0]}) + # and a few tests for at + d = np.array([[1, 2, 3], [1, 2, 3]]) + check = d.copy() + a = d.copy().view(A) + np.add.at(check, ([0, 1], [0, 2]), 1.) + np.add.at(a, ([0, 1], [0, 2]), 1.) + assert_equal(a, check) + assert_(a.info, {'inputs': [0]}) + b = np.array(1.).view(A) + a = d.copy().view(A) + np.add.at(a, ([0, 1], [0, 2]), b) + assert_equal(a, check) + assert_(a.info, {'inputs': [0, 2]}) + + +class TestChoose: + def test_mixed(self): + c = np.array([True, True]) + a = np.array([True, True]) + assert_equal(np.choose(c, (a, 1)), np.array([1, 1])) + + +class TestRationalFunctions: + def test_lcm(self): + self._test_lcm_inner(np.int16) + self._test_lcm_inner(np.uint16) + + def test_lcm_object(self): + self._test_lcm_inner(np.object_) + + def test_gcd(self): + self._test_gcd_inner(np.int16) + self._test_lcm_inner(np.uint16) + + def test_gcd_object(self): + self._test_gcd_inner(np.object_) + + def _test_lcm_inner(self, dtype): + # basic use + a = np.array([12, 120], dtype=dtype) + b = np.array([20, 200], dtype=dtype) + assert_equal(np.lcm(a, b), [60, 600]) + + if not issubclass(dtype, np.unsignedinteger): + # negatives are ignored + a = np.array([12, -12, 12, -12], dtype=dtype) + b = np.array([20, 20, -20, -20], dtype=dtype) + assert_equal(np.lcm(a, b), [60]*4) + + # reduce + a = np.array([3, 12, 20], dtype=dtype) + assert_equal(np.lcm.reduce([3, 12, 20]), 60) + + # broadcasting, and a test including 0 + a = np.arange(6).astype(dtype) + b = 20 + assert_equal(np.lcm(a, b), [0, 20, 20, 60, 20, 20]) + + def _test_gcd_inner(self, dtype): + # basic use + a = np.array([12, 120], dtype=dtype) + b = np.array([20, 200], dtype=dtype) + assert_equal(np.gcd(a, b), [4, 40]) + + if not issubclass(dtype, np.unsignedinteger): + # negatives are ignored + a = np.array([12, -12, 12, -12], dtype=dtype) + b = np.array([20, 20, -20, -20], dtype=dtype) + assert_equal(np.gcd(a, b), [4]*4) + + # reduce + a = np.array([15, 25, 35], dtype=dtype) + assert_equal(np.gcd.reduce(a), 5) + + # broadcasting, and a test including 0 + a = np.arange(6).astype(dtype) + b = 20 + assert_equal(np.gcd(a, b), [20, 1, 2, 1, 4, 5]) + + def test_lcm_overflow(self): + # verify that we don't overflow when a*b does overflow + big = np.int32(np.iinfo(np.int32).max // 11) + a = 2*big + b = 5*big + assert_equal(np.lcm(a, b), 10*big) + + def test_gcd_overflow(self): + for dtype in (np.int32, np.int64): + # verify that we don't overflow when taking abs(x) + # not relevant for lcm, where the result is unrepresentable anyway + a = dtype(np.iinfo(dtype).min) # negative power of two + q = -(a // 4) + assert_equal(np.gcd(a, q*3), q) + assert_equal(np.gcd(a, -q*3), q) + + def test_decimal(self): + from decimal import Decimal + a = np.array([1, 1, -1, -1]) * Decimal('0.20') + b = np.array([1, -1, 1, -1]) * Decimal('0.12') + + assert_equal(np.gcd(a, b), 4*[Decimal('0.04')]) + assert_equal(np.lcm(a, b), 4*[Decimal('0.60')]) + + def test_float(self): + # not well-defined on float due to rounding errors + assert_raises(TypeError, np.gcd, 0.3, 0.4) + assert_raises(TypeError, np.lcm, 0.3, 0.4) + + def test_builtin_long(self): + # sanity check that array coercion is alright for builtin longs + assert_equal(np.array(2**200).item(), 2**200) + + # expressed as prime factors + a = np.array(2**100 * 3**5) + b = np.array([2**100 * 5**7, 2**50 * 3**10]) + assert_equal(np.gcd(a, b), [2**100, 2**50 * 3**5]) + assert_equal(np.lcm(a, b), [2**100 * 3**5 * 5**7, 2**100 * 3**10]) + + assert_equal(np.gcd(2**100, 3**100), 1) + + +class TestRoundingFunctions: + + def test_object_direct(self): + """ test direct implementation of these magic methods """ + class C: + def __floor__(self): + return 1 + def __ceil__(self): + return 2 + def __trunc__(self): + return 3 + + arr = np.array([C(), C()]) + assert_equal(np.floor(arr), [1, 1]) + assert_equal(np.ceil(arr), [2, 2]) + assert_equal(np.trunc(arr), [3, 3]) + + def test_object_indirect(self): + """ test implementations via __float__ """ + class C: + def __float__(self): + return -2.5 + + arr = np.array([C(), C()]) + assert_equal(np.floor(arr), [-3, -3]) + assert_equal(np.ceil(arr), [-2, -2]) + with pytest.raises(TypeError): + np.trunc(arr) # consistent with math.trunc + + def test_fraction(self): + f = Fraction(-4, 3) + assert_equal(np.floor(f), -2) + assert_equal(np.ceil(f), -1) + assert_equal(np.trunc(f), -1) + + +class TestComplexFunctions: + funcs = [np.arcsin, np.arccos, np.arctan, np.arcsinh, np.arccosh, + np.arctanh, np.sin, np.cos, np.tan, np.exp, + np.exp2, np.log, np.sqrt, np.log10, np.log2, + np.log1p] + + def test_it(self): + for f in self.funcs: + if f is np.arccosh: + x = 1.5 + else: + x = .5 + fr = f(x) + fz = f(complex(x)) + assert_almost_equal(fz.real, fr, err_msg='real part %s' % f) + assert_almost_equal(fz.imag, 0., err_msg='imag part %s' % f) + + def test_precisions_consistent(self): + z = 1 + 1j + for f in self.funcs: + fcf = f(np.csingle(z)) + fcd = f(np.cdouble(z)) + fcl = f(np.clongdouble(z)) + assert_almost_equal(fcf, fcd, decimal=6, err_msg='fch-fcd %s' % f) + assert_almost_equal(fcl, fcd, decimal=15, err_msg='fch-fcl %s' % f) + + def test_branch_cuts(self): + # check branch cuts and continuity on them + _check_branch_cut(np.log, -0.5, 1j, 1, -1, True) + _check_branch_cut(np.log2, -0.5, 1j, 1, -1, True) + _check_branch_cut(np.log10, -0.5, 1j, 1, -1, True) + _check_branch_cut(np.log1p, -1.5, 1j, 1, -1, True) + _check_branch_cut(np.sqrt, -0.5, 1j, 1, -1, True) + + _check_branch_cut(np.arcsin, [ -2, 2], [1j, 1j], 1, -1, True) + _check_branch_cut(np.arccos, [ -2, 2], [1j, 1j], 1, -1, True) + _check_branch_cut(np.arctan, [0-2j, 2j], [1, 1], -1, 1, True) + + _check_branch_cut(np.arcsinh, [0-2j, 2j], [1, 1], -1, 1, True) + _check_branch_cut(np.arccosh, [ -1, 0.5], [1j, 1j], 1, -1, True) + _check_branch_cut(np.arctanh, [ -2, 2], [1j, 1j], 1, -1, True) + + # check against bogus branch cuts: assert continuity between quadrants + _check_branch_cut(np.arcsin, [0-2j, 2j], [ 1, 1], 1, 1) + _check_branch_cut(np.arccos, [0-2j, 2j], [ 1, 1], 1, 1) + _check_branch_cut(np.arctan, [ -2, 2], [1j, 1j], 1, 1) + + _check_branch_cut(np.arcsinh, [ -2, 2, 0], [1j, 1j, 1], 1, 1) + _check_branch_cut(np.arccosh, [0-2j, 2j, 2], [1, 1, 1j], 1, 1) + _check_branch_cut(np.arctanh, [0-2j, 2j, 0], [1, 1, 1j], 1, 1) + + def test_branch_cuts_complex64(self): + # check branch cuts and continuity on them + _check_branch_cut(np.log, -0.5, 1j, 1, -1, True, np.complex64) + _check_branch_cut(np.log2, -0.5, 1j, 1, -1, True, np.complex64) + _check_branch_cut(np.log10, -0.5, 1j, 1, -1, True, np.complex64) + _check_branch_cut(np.log1p, -1.5, 1j, 1, -1, True, np.complex64) + _check_branch_cut(np.sqrt, -0.5, 1j, 1, -1, True, np.complex64) + + _check_branch_cut(np.arcsin, [ -2, 2], [1j, 1j], 1, -1, True, np.complex64) + _check_branch_cut(np.arccos, [ -2, 2], [1j, 1j], 1, -1, True, np.complex64) + _check_branch_cut(np.arctan, [0-2j, 2j], [1, 1], -1, 1, True, np.complex64) + + _check_branch_cut(np.arcsinh, [0-2j, 2j], [1, 1], -1, 1, True, np.complex64) + _check_branch_cut(np.arccosh, [ -1, 0.5], [1j, 1j], 1, -1, True, np.complex64) + _check_branch_cut(np.arctanh, [ -2, 2], [1j, 1j], 1, -1, True, np.complex64) + + # check against bogus branch cuts: assert continuity between quadrants + _check_branch_cut(np.arcsin, [0-2j, 2j], [ 1, 1], 1, 1, False, np.complex64) + _check_branch_cut(np.arccos, [0-2j, 2j], [ 1, 1], 1, 1, False, np.complex64) + _check_branch_cut(np.arctan, [ -2, 2], [1j, 1j], 1, 1, False, np.complex64) + + _check_branch_cut(np.arcsinh, [ -2, 2, 0], [1j, 1j, 1], 1, 1, False, np.complex64) + _check_branch_cut(np.arccosh, [0-2j, 2j, 2], [1, 1, 1j], 1, 1, False, np.complex64) + _check_branch_cut(np.arctanh, [0-2j, 2j, 0], [1, 1, 1j], 1, 1, False, np.complex64) + + def test_against_cmath(self): + import cmath + + points = [-1-1j, -1+1j, +1-1j, +1+1j] + name_map = {'arcsin': 'asin', 'arccos': 'acos', 'arctan': 'atan', + 'arcsinh': 'asinh', 'arccosh': 'acosh', 'arctanh': 'atanh'} + atol = 4*np.finfo(complex).eps + for func in self.funcs: + fname = func.__name__.split('.')[-1] + cname = name_map.get(fname, fname) + try: + cfunc = getattr(cmath, cname) + except AttributeError: + continue + for p in points: + a = complex(func(np.complex_(p))) + b = cfunc(p) + assert_(abs(a - b) < atol, "%s %s: %s; cmath: %s" % (fname, p, a, b)) + + @pytest.mark.parametrize('dtype', [np.complex64, np.complex_, np.longcomplex]) + def test_loss_of_precision(self, dtype): + """Check loss of precision in complex arc* functions""" + + # Check against known-good functions + + info = np.finfo(dtype) + real_dtype = dtype(0.).real.dtype + eps = info.eps + + def check(x, rtol): + x = x.astype(real_dtype) + + z = x.astype(dtype) + d = np.absolute(np.arcsinh(x)/np.arcsinh(z).real - 1) + assert_(np.all(d < rtol), (np.argmax(d), x[np.argmax(d)], d.max(), + 'arcsinh')) + + z = (1j*x).astype(dtype) + d = np.absolute(np.arcsinh(x)/np.arcsin(z).imag - 1) + assert_(np.all(d < rtol), (np.argmax(d), x[np.argmax(d)], d.max(), + 'arcsin')) + + z = x.astype(dtype) + d = np.absolute(np.arctanh(x)/np.arctanh(z).real - 1) + assert_(np.all(d < rtol), (np.argmax(d), x[np.argmax(d)], d.max(), + 'arctanh')) + + z = (1j*x).astype(dtype) + d = np.absolute(np.arctanh(x)/np.arctan(z).imag - 1) + assert_(np.all(d < rtol), (np.argmax(d), x[np.argmax(d)], d.max(), + 'arctan')) + + # The switchover was chosen as 1e-3; hence there can be up to + # ~eps/1e-3 of relative cancellation error before it + + x_series = np.logspace(-20, -3.001, 200) + x_basic = np.logspace(-2.999, 0, 10, endpoint=False) + + if dtype is np.longcomplex: + # It's not guaranteed that the system-provided arc functions + # are accurate down to a few epsilons. (Eg. on Linux 64-bit) + # So, give more leeway for long complex tests here: + # Can use 2.1 for > Ubuntu LTS Trusty (2014), glibc = 2.19. + if skip_longcomplex_msg: + pytest.skip(skip_longcomplex_msg) + check(x_series, 50.0*eps) + else: + check(x_series, 2.1*eps) + check(x_basic, 2.0*eps/1e-3) + + # Check a few points + + z = np.array([1e-5*(1+1j)], dtype=dtype) + p = 9.999999999333333333e-6 + 1.000000000066666666e-5j + d = np.absolute(1-np.arctanh(z)/p) + assert_(np.all(d < 1e-15)) + + p = 1.0000000000333333333e-5 + 9.999999999666666667e-6j + d = np.absolute(1-np.arcsinh(z)/p) + assert_(np.all(d < 1e-15)) + + p = 9.999999999333333333e-6j + 1.000000000066666666e-5 + d = np.absolute(1-np.arctan(z)/p) + assert_(np.all(d < 1e-15)) + + p = 1.0000000000333333333e-5j + 9.999999999666666667e-6 + d = np.absolute(1-np.arcsin(z)/p) + assert_(np.all(d < 1e-15)) + + # Check continuity across switchover points + + def check(func, z0, d=1): + z0 = np.asarray(z0, dtype=dtype) + zp = z0 + abs(z0) * d * eps * 2 + zm = z0 - abs(z0) * d * eps * 2 + assert_(np.all(zp != zm), (zp, zm)) + + # NB: the cancellation error at the switchover is at least eps + good = (abs(func(zp) - func(zm)) < 2*eps) + assert_(np.all(good), (func, z0[~good])) + + for func in (np.arcsinh, np.arcsinh, np.arcsin, np.arctanh, np.arctan): + pts = [rp+1j*ip for rp in (-1e-3, 0, 1e-3) for ip in(-1e-3, 0, 1e-3) + if rp != 0 or ip != 0] + check(func, pts, 1) + check(func, pts, 1j) + check(func, pts, 1+1j) + + +class TestAttributes: + def test_attributes(self): + add = ncu.add + assert_equal(add.__name__, 'add') + assert_(add.ntypes >= 18) # don't fail if types added + assert_('ii->i' in add.types) + assert_equal(add.nin, 2) + assert_equal(add.nout, 1) + assert_equal(add.identity, 0) + + def test_doc(self): + # don't bother checking the long list of kwargs, which are likely to + # change + assert_(ncu.add.__doc__.startswith( + "add(x1, x2, /, out=None, *, where=True")) + assert_(ncu.frexp.__doc__.startswith( + "frexp(x[, out1, out2], / [, out=(None, None)], *, where=True")) + + +class TestSubclass: + + def test_subclass_op(self): + + class simple(np.ndarray): + def __new__(subtype, shape): + self = np.ndarray.__new__(subtype, shape, dtype=object) + self.fill(0) + return self + + a = simple((3, 4)) + assert_equal(a+a, a) + + +class TestFrompyfunc(object): + + def test_identity(self): + def mul(a, b): + return a * b + + # with identity=value + mul_ufunc = np.frompyfunc(mul, nin=2, nout=1, identity=1) + assert_equal(mul_ufunc.reduce([2, 3, 4]), 24) + assert_equal(mul_ufunc.reduce(np.ones((2, 2)), axis=(0, 1)), 1) + assert_equal(mul_ufunc.reduce([]), 1) + + # with identity=None (reorderable) + mul_ufunc = np.frompyfunc(mul, nin=2, nout=1, identity=None) + assert_equal(mul_ufunc.reduce([2, 3, 4]), 24) + assert_equal(mul_ufunc.reduce(np.ones((2, 2)), axis=(0, 1)), 1) + assert_raises(ValueError, lambda: mul_ufunc.reduce([])) + + # with no identity (not reorderable) + mul_ufunc = np.frompyfunc(mul, nin=2, nout=1) + assert_equal(mul_ufunc.reduce([2, 3, 4]), 24) + assert_raises(ValueError, lambda: mul_ufunc.reduce(np.ones((2, 2)), axis=(0, 1))) + assert_raises(ValueError, lambda: mul_ufunc.reduce([])) + + +def _check_branch_cut(f, x0, dx, re_sign=1, im_sign=-1, sig_zero_ok=False, + dtype=complex): + """ + Check for a branch cut in a function. + + Assert that `x0` lies on a branch cut of function `f` and `f` is + continuous from the direction `dx`. + + Parameters + ---------- + f : func + Function to check + x0 : array-like + Point on branch cut + dx : array-like + Direction to check continuity in + re_sign, im_sign : {1, -1} + Change of sign of the real or imaginary part expected + sig_zero_ok : bool + Whether to check if the branch cut respects signed zero (if applicable) + dtype : dtype + Dtype to check (should be complex) + + """ + x0 = np.atleast_1d(x0).astype(dtype) + dx = np.atleast_1d(dx).astype(dtype) + + if np.dtype(dtype).char == 'F': + scale = np.finfo(dtype).eps * 1e2 + atol = np.float32(1e-2) + else: + scale = np.finfo(dtype).eps * 1e3 + atol = 1e-4 + + y0 = f(x0) + yp = f(x0 + dx*scale*np.absolute(x0)/np.absolute(dx)) + ym = f(x0 - dx*scale*np.absolute(x0)/np.absolute(dx)) + + assert_(np.all(np.absolute(y0.real - yp.real) < atol), (y0, yp)) + assert_(np.all(np.absolute(y0.imag - yp.imag) < atol), (y0, yp)) + assert_(np.all(np.absolute(y0.real - ym.real*re_sign) < atol), (y0, ym)) + assert_(np.all(np.absolute(y0.imag - ym.imag*im_sign) < atol), (y0, ym)) + + if sig_zero_ok: + # check that signed zeros also work as a displacement + jr = (x0.real == 0) & (dx.real != 0) + ji = (x0.imag == 0) & (dx.imag != 0) + if np.any(jr): + x = x0[jr] + x.real = np.NZERO + ym = f(x) + assert_(np.all(np.absolute(y0[jr].real - ym.real*re_sign) < atol), (y0[jr], ym)) + assert_(np.all(np.absolute(y0[jr].imag - ym.imag*im_sign) < atol), (y0[jr], ym)) + + if np.any(ji): + x = x0[ji] + x.imag = np.NZERO + ym = f(x) + assert_(np.all(np.absolute(y0[ji].real - ym.real*re_sign) < atol), (y0[ji], ym)) + assert_(np.all(np.absolute(y0[ji].imag - ym.imag*im_sign) < atol), (y0[ji], ym)) + +def test_copysign(): + assert_(np.copysign(1, -1) == -1) + with np.errstate(divide="ignore"): + assert_(1 / np.copysign(0, -1) < 0) + assert_(1 / np.copysign(0, 1) > 0) + assert_(np.signbit(np.copysign(np.nan, -1))) + assert_(not np.signbit(np.copysign(np.nan, 1))) + +def _test_nextafter(t): + one = t(1) + two = t(2) + zero = t(0) + eps = np.finfo(t).eps + assert_(np.nextafter(one, two) - one == eps) + assert_(np.nextafter(one, zero) - one < 0) + assert_(np.isnan(np.nextafter(np.nan, one))) + assert_(np.isnan(np.nextafter(one, np.nan))) + assert_(np.nextafter(one, one) == one) + +def test_nextafter(): + return _test_nextafter(np.float64) + + +def test_nextafterf(): + return _test_nextafter(np.float32) + + +@pytest.mark.skipif(np.finfo(np.double) == np.finfo(np.longdouble), + reason="long double is same as double") +@pytest.mark.xfail(condition=platform.machine().startswith("ppc64"), + reason="IBM double double") +def test_nextafterl(): + return _test_nextafter(np.longdouble) + + +def test_nextafter_0(): + for t, direction in itertools.product(np.sctypes['float'], (1, -1)): + tiny = np.finfo(t).tiny + assert_(0. < direction * np.nextafter(t(0), t(direction)) < tiny) + assert_equal(np.nextafter(t(0), t(direction)) / t(2.1), direction * 0.0) + +def _test_spacing(t): + one = t(1) + eps = np.finfo(t).eps + nan = t(np.nan) + inf = t(np.inf) + with np.errstate(invalid='ignore'): + assert_(np.spacing(one) == eps) + assert_(np.isnan(np.spacing(nan))) + assert_(np.isnan(np.spacing(inf))) + assert_(np.isnan(np.spacing(-inf))) + assert_(np.spacing(t(1e30)) != 0) + +def test_spacing(): + return _test_spacing(np.float64) + +def test_spacingf(): + return _test_spacing(np.float32) + + +@pytest.mark.skipif(np.finfo(np.double) == np.finfo(np.longdouble), + reason="long double is same as double") +@pytest.mark.xfail(condition=platform.machine().startswith("ppc64"), + reason="IBM double double") +def test_spacingl(): + return _test_spacing(np.longdouble) + +def test_spacing_gfortran(): + # Reference from this fortran file, built with gfortran 4.3.3 on linux + # 32bits: + # PROGRAM test_spacing + # INTEGER, PARAMETER :: SGL = SELECTED_REAL_KIND(p=6, r=37) + # INTEGER, PARAMETER :: DBL = SELECTED_REAL_KIND(p=13, r=200) + # + # WRITE(*,*) spacing(0.00001_DBL) + # WRITE(*,*) spacing(1.0_DBL) + # WRITE(*,*) spacing(1000._DBL) + # WRITE(*,*) spacing(10500._DBL) + # + # WRITE(*,*) spacing(0.00001_SGL) + # WRITE(*,*) spacing(1.0_SGL) + # WRITE(*,*) spacing(1000._SGL) + # WRITE(*,*) spacing(10500._SGL) + # END PROGRAM + ref = {np.float64: [1.69406589450860068E-021, + 2.22044604925031308E-016, + 1.13686837721616030E-013, + 1.81898940354585648E-012], + np.float32: [9.09494702E-13, + 1.19209290E-07, + 6.10351563E-05, + 9.76562500E-04]} + + for dt, dec_ in zip([np.float32, np.float64], (10, 20)): + x = np.array([1e-5, 1, 1000, 10500], dtype=dt) + assert_array_almost_equal(np.spacing(x), ref[dt], decimal=dec_) + +def test_nextafter_vs_spacing(): + # XXX: spacing does not handle long double yet + for t in [np.float32, np.float64]: + for _f in [1, 1e-5, 1000]: + f = t(_f) + f1 = t(_f + 1) + assert_(np.nextafter(f, f1) - f == np.spacing(f)) + +def test_pos_nan(): + """Check np.nan is a positive nan.""" + assert_(np.signbit(np.nan) == 0) + +def test_reduceat(): + """Test bug in reduceat when structured arrays are not copied.""" + db = np.dtype([('name', 'S11'), ('time', np.int64), ('value', np.float32)]) + a = np.empty([100], dtype=db) + a['name'] = 'Simple' + a['time'] = 10 + a['value'] = 100 + indx = [0, 7, 15, 25] + + h2 = [] + val1 = indx[0] + for val2 in indx[1:]: + h2.append(np.add.reduce(a['value'][val1:val2])) + val1 = val2 + h2.append(np.add.reduce(a['value'][val1:])) + h2 = np.array(h2) + + # test buffered -- this should work + h1 = np.add.reduceat(a['value'], indx) + assert_array_almost_equal(h1, h2) + + # This is when the error occurs. + # test no buffer + np.setbufsize(32) + h1 = np.add.reduceat(a['value'], indx) + np.setbufsize(np.UFUNC_BUFSIZE_DEFAULT) + assert_array_almost_equal(h1, h2) + +def test_reduceat_empty(): + """Reduceat should work with empty arrays""" + indices = np.array([], 'i4') + x = np.array([], 'f8') + result = np.add.reduceat(x, indices) + assert_equal(result.dtype, x.dtype) + assert_equal(result.shape, (0,)) + # Another case with a slightly different zero-sized shape + x = np.ones((5, 2)) + result = np.add.reduceat(x, [], axis=0) + assert_equal(result.dtype, x.dtype) + assert_equal(result.shape, (0, 2)) + result = np.add.reduceat(x, [], axis=1) + assert_equal(result.dtype, x.dtype) + assert_equal(result.shape, (5, 0)) + +def test_complex_nan_comparisons(): + nans = [complex(np.nan, 0), complex(0, np.nan), complex(np.nan, np.nan)] + fins = [complex(1, 0), complex(-1, 0), complex(0, 1), complex(0, -1), + complex(1, 1), complex(-1, -1), complex(0, 0)] + + with np.errstate(invalid='ignore'): + for x in nans + fins: + x = np.array([x]) + for y in nans + fins: + y = np.array([y]) + + if np.isfinite(x) and np.isfinite(y): + continue + + assert_equal(x < y, False, err_msg="%r < %r" % (x, y)) + assert_equal(x > y, False, err_msg="%r > %r" % (x, y)) + assert_equal(x <= y, False, err_msg="%r <= %r" % (x, y)) + assert_equal(x >= y, False, err_msg="%r >= %r" % (x, y)) + assert_equal(x == y, False, err_msg="%r == %r" % (x, y)) + + +def test_rint_big_int(): + # np.rint bug for large integer values on Windows 32-bit and MKL + # https://github.com/numpy/numpy/issues/6685 + val = 4607998452777363968 + # This is exactly representable in floating point + assert_equal(val, int(float(val))) + # Rint should not change the value + assert_equal(val, np.rint(val)) + +@pytest.mark.parametrize('ftype', [np.float32, np.float64]) +def test_memoverlap_accumulate(ftype): + # Reproduces bug https://github.com/numpy/numpy/issues/15597 + arr = np.array([0.61, 0.60, 0.77, 0.41, 0.19], dtype=ftype) + out_max = np.array([0.61, 0.61, 0.77, 0.77, 0.77], dtype=ftype) + out_min = np.array([0.61, 0.60, 0.60, 0.41, 0.19], dtype=ftype) + assert_equal(np.maximum.accumulate(arr), out_max) + assert_equal(np.minimum.accumulate(arr), out_min) + +def test_signaling_nan_exceptions(): + with assert_no_warnings(): + a = np.ndarray(shape=(), dtype='float32', buffer=b'\x00\xe0\xbf\xff') + np.isnan(a) + +@pytest.mark.parametrize("arr", [ + np.arange(2), + np.matrix([0, 1]), + np.matrix([[0, 1], [2, 5]]), + ]) +def test_outer_subclass_preserve(arr): + # for gh-8661 + class foo(np.ndarray): pass + actual = np.multiply.outer(arr.view(foo), arr.view(foo)) + assert actual.__class__.__name__ == 'foo' + +def test_outer_bad_subclass(): + class BadArr1(np.ndarray): + def __array_finalize__(self, obj): + # The outer call reshapes to 3 dims, try to do a bad reshape. + if self.ndim == 3: + self.shape = self.shape + (1,) + + def __array_prepare__(self, obj, context=None): + return obj + + class BadArr2(np.ndarray): + def __array_finalize__(self, obj): + if isinstance(obj, BadArr2): + # outer inserts 1-sized dims. In that case disturb them. + if self.shape[-1] == 1: + self.shape = self.shape[::-1] + + def __array_prepare__(self, obj, context=None): + return obj + + for cls in [BadArr1, BadArr2]: + arr = np.ones((2, 3)).view(cls) + with assert_raises(TypeError) as a: + # The first array gets reshaped (not the second one) + np.add.outer(arr, [1, 2]) + + # This actually works, since we only see the reshaping error: + arr = np.ones((2, 3)).view(cls) + assert type(np.add.outer([1, 2], arr)) is cls + +def test_outer_exceeds_maxdims(): + deep = np.ones((1,) * 17) + with assert_raises(ValueError): + np.add.outer(deep, deep) + diff --git a/venv/Lib/site-packages/numpy/core/tests/test_umath_accuracy.py b/venv/Lib/site-packages/numpy/core/tests/test_umath_accuracy.py new file mode 100644 index 0000000..33080ed --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/tests/test_umath_accuracy.py @@ -0,0 +1,59 @@ +import numpy as np +import platform +from os import path +import sys +import pytest +from ctypes import c_longlong, c_double, c_float, c_int, cast, pointer, POINTER +from numpy.testing import assert_array_max_ulp +from numpy.core._multiarray_umath import __cpu_features__ + +IS_AVX = __cpu_features__.get('AVX512F', False) or \ + (__cpu_features__.get('FMA3', False) and __cpu_features__.get('AVX2', False)) +runtest = sys.platform.startswith('linux') and IS_AVX +platform_skip = pytest.mark.skipif(not runtest, + reason="avoid testing inconsistent platform " + "library implementations") + +# convert string to hex function taken from: +# https://stackoverflow.com/questions/1592158/convert-hex-to-float # +def convert(s, datatype="np.float32"): + i = int(s, 16) # convert from hex to a Python int + if (datatype == "np.float64"): + cp = pointer(c_longlong(i)) # make this into a c long long integer + fp = cast(cp, POINTER(c_double)) # cast the int pointer to a double pointer + else: + cp = pointer(c_int(i)) # make this into a c integer + fp = cast(cp, POINTER(c_float)) # cast the int pointer to a float pointer + + return fp.contents.value # dereference the pointer, get the float + +str_to_float = np.vectorize(convert) +files = ['umath-validation-set-exp', + 'umath-validation-set-log', + 'umath-validation-set-sin', + 'umath-validation-set-cos'] + +class TestAccuracy: + @platform_skip + def test_validate_transcendentals(self): + with np.errstate(all='ignore'): + for filename in files: + data_dir = path.join(path.dirname(__file__), 'data') + filepath = path.join(data_dir, filename) + with open(filepath) as fid: + file_without_comments = (r for r in fid if not r[0] in ('$', '#')) + data = np.genfromtxt(file_without_comments, + dtype=('|S39','|S39','|S39',int), + names=('type','input','output','ulperr'), + delimiter=',', + skip_header=1) + npfunc = getattr(np, filename.split('-')[3]) + for datatype in np.unique(data['type']): + data_subset = data[data['type'] == datatype] + inval = np.array(str_to_float(data_subset['input'].astype(str), data_subset['type'].astype(str)), dtype=eval(datatype)) + outval = np.array(str_to_float(data_subset['output'].astype(str), data_subset['type'].astype(str)), dtype=eval(datatype)) + perm = np.random.permutation(len(inval)) + inval = inval[perm] + outval = outval[perm] + maxulperr = data_subset['ulperr'].max() + assert_array_max_ulp(npfunc(inval), outval, maxulperr) diff --git a/venv/Lib/site-packages/numpy/core/tests/test_umath_complex.py b/venv/Lib/site-packages/numpy/core/tests/test_umath_complex.py new file mode 100644 index 0000000..90a349d --- /dev/null +++ b/venv/Lib/site-packages/numpy/core/tests/test_umath_complex.py @@ -0,0 +1,610 @@ +import sys +import platform +import pytest + +import numpy as np +# import the c-extension module directly since _arg is not exported via umath +import numpy.core._multiarray_umath as ncu +from numpy.testing import ( + assert_raises, assert_equal, assert_array_equal, assert_almost_equal, assert_array_max_ulp + ) + +# TODO: branch cuts (use Pauli code) +# TODO: conj 'symmetry' +# TODO: FPU exceptions + +# At least on Windows the results of many complex functions are not conforming +# to the C99 standard. See ticket 1574. +# Ditto for Solaris (ticket 1642) and OS X on PowerPC. +#FIXME: this will probably change when we require full C99 campatibility +with np.errstate(all='ignore'): + functions_seem_flaky = ((np.exp(complex(np.inf, 0)).imag != 0) + or (np.log(complex(np.NZERO, 0)).imag != np.pi)) +# TODO: replace with a check on whether platform-provided C99 funcs are used +xfail_complex_tests = (not sys.platform.startswith('linux') or functions_seem_flaky) + +# TODO This can be xfail when the generator functions are got rid of. +platform_skip = pytest.mark.skipif(xfail_complex_tests, + reason="Inadequate C99 complex support") + + + +class TestCexp: + def test_simple(self): + check = check_complex_value + f = np.exp + + check(f, 1, 0, np.exp(1), 0, False) + check(f, 0, 1, np.cos(1), np.sin(1), False) + + ref = np.exp(1) * complex(np.cos(1), np.sin(1)) + check(f, 1, 1, ref.real, ref.imag, False) + + @platform_skip + def test_special_values(self): + # C99: Section G 6.3.1 + + check = check_complex_value + f = np.exp + + # cexp(+-0 + 0i) is 1 + 0i + check(f, np.PZERO, 0, 1, 0, False) + check(f, np.NZERO, 0, 1, 0, False) + + # cexp(x + infi) is nan + nani for finite x and raises 'invalid' FPU + # exception + check(f, 1, np.inf, np.nan, np.nan) + check(f, -1, np.inf, np.nan, np.nan) + check(f, 0, np.inf, np.nan, np.nan) + + # cexp(inf + 0i) is inf + 0i + check(f, np.inf, 0, np.inf, 0) + + # cexp(-inf + yi) is +0 * (cos(y) + i sin(y)) for finite y + check(f, -np.inf, 1, np.PZERO, np.PZERO) + check(f, -np.inf, 0.75 * np.pi, np.NZERO, np.PZERO) + + # cexp(inf + yi) is +inf * (cos(y) + i sin(y)) for finite y + check(f, np.inf, 1, np.inf, np.inf) + check(f, np.inf, 0.75 * np.pi, -np.inf, np.inf) + + # cexp(-inf + inf i) is +-0 +- 0i (signs unspecified) + def _check_ninf_inf(dummy): + msgform = "cexp(-inf, inf) is (%f, %f), expected (+-0, +-0)" + with np.errstate(invalid='ignore'): + z = f(np.array(complex(-np.inf, np.inf))) + if z.real != 0 or z.imag != 0: + raise AssertionError(msgform % (z.real, z.imag)) + + _check_ninf_inf(None) + + # cexp(inf + inf i) is +-inf + NaNi and raised invalid FPU ex. + def _check_inf_inf(dummy): + msgform = "cexp(inf, inf) is (%f, %f), expected (+-inf, nan)" + with np.errstate(invalid='ignore'): + z = f(np.array(complex(np.inf, np.inf))) + if not np.isinf(z.real) or not np.isnan(z.imag): + raise AssertionError(msgform % (z.real, z.imag)) + + _check_inf_inf(None) + + # cexp(-inf + nan i) is +-0 +- 0i + def _check_ninf_nan(dummy): + msgform = "cexp(-inf, nan) is (%f, %f), expected (+-0, +-0)" + with np.errstate(invalid='ignore'): + z = f(np.array(complex(-np.inf, np.nan))) + if z.real != 0 or z.imag != 0: + raise AssertionError(msgform % (z.real, z.imag)) + + _check_ninf_nan(None) + + # cexp(inf + nan i) is +-inf + nan + def _check_inf_nan(dummy): + msgform = "cexp(-inf, nan) is (%f, %f), expected (+-inf, nan)" + with np.errstate(invalid='ignore'): + z = f(np.array(complex(np.inf, np.nan))) + if not np.isinf(z.real) or not np.isnan(z.imag): + raise AssertionError(msgform % (z.real, z.imag)) + + _check_inf_nan(None) + + # cexp(nan + yi) is nan + nani for y != 0 (optional: raises invalid FPU + # ex) + check(f, np.nan, 1, np.nan, np.nan) + check(f, np.nan, -1, np.nan, np.nan) + + check(f, np.nan, np.inf, np.nan, np.nan) + check(f, np.nan, -np.inf, np.nan, np.nan) + + # cexp(nan + nani) is nan + nani + check(f, np.nan, np.nan, np.nan, np.nan) + + # TODO This can be xfail when the generator functions are got rid of. + @pytest.mark.skip(reason="cexp(nan + 0I) is wrong on most platforms") + def test_special_values2(self): + # XXX: most implementations get it wrong here (including glibc <= 2.10) + # cexp(nan + 0i) is nan + 0i + check = check_complex_value + f = np.exp + + check(f, np.nan, 0, np.nan, 0) + +class TestClog: + def test_simple(self): + x = np.array([1+0j, 1+2j]) + y_r = np.log(np.abs(x)) + 1j * np.angle(x) + y = np.log(x) + for i in range(len(x)): + assert_almost_equal(y[i], y_r[i]) + + @platform_skip + @pytest.mark.skipif(platform.machine() == "armv5tel", reason="See gh-413.") + def test_special_values(self): + xl = [] + yl = [] + + # From C99 std (Sec 6.3.2) + # XXX: check exceptions raised + # --- raise for invalid fails. + + # clog(-0 + i0) returns -inf + i pi and raises the 'divide-by-zero' + # floating-point exception. + with np.errstate(divide='raise'): + x = np.array([np.NZERO], dtype=complex) + y = complex(-np.inf, np.pi) + assert_raises(FloatingPointError, np.log, x) + with np.errstate(divide='ignore'): + assert_almost_equal(np.log(x), y) + + xl.append(x) + yl.append(y) + + # clog(+0 + i0) returns -inf + i0 and raises the 'divide-by-zero' + # floating-point exception. + with np.errstate(divide='raise'): + x = np.array([0], dtype=complex) + y = complex(-np.inf, 0) + assert_raises(FloatingPointError, np.log, x) + with np.errstate(divide='ignore'): + assert_almost_equal(np.log(x), y) + + xl.append(x) + yl.append(y) + + # clog(x + i inf returns +inf + i pi /2, for finite x. + x = np.array([complex(1, np.inf)], dtype=complex) + y = complex(np.inf, 0.5 * np.pi) + assert_almost_equal(np.log(x), y) + xl.append(x) + yl.append(y) + + x = np.array([complex(-1, np.inf)], dtype=complex) + assert_almost_equal(np.log(x), y) + xl.append(x) + yl.append(y) + + # clog(x + iNaN) returns NaN + iNaN and optionally raises the + # 'invalid' floating- point exception, for finite x. + with np.errstate(invalid='raise'): + x = np.array([complex(1., np.nan)], dtype=complex) + y = complex(np.nan, np.nan) + #assert_raises(FloatingPointError, np.log, x) + with np.errstate(invalid='ignore'): + assert_almost_equal(np.log(x), y) + + xl.append(x) + yl.append(y) + + with np.errstate(invalid='raise'): + x = np.array([np.inf + 1j * np.nan], dtype=complex) + #assert_raises(FloatingPointError, np.log, x) + with np.errstate(invalid='ignore'): + assert_almost_equal(np.log(x), y) + + xl.append(x) + yl.append(y) + + # clog(- inf + iy) returns +inf + ipi , for finite positive-signed y. + x = np.array([-np.inf + 1j], dtype=complex) + y = complex(np.inf, np.pi) + assert_almost_equal(np.log(x), y) + xl.append(x) + yl.append(y) + + # clog(+ inf + iy) returns +inf + i0, for finite positive-signed y. + x = np.array([np.inf + 1j], dtype=complex) + y = complex(np.inf, 0) + assert_almost_equal(np.log(x), y) + xl.append(x) + yl.append(y) + + # clog(- inf + i inf) returns +inf + i3pi /4. + x = np.array([complex(-np.inf, np.inf)], dtype=complex) + y = complex(np.inf, 0.75 * np.pi) + assert_almost_equal(np.log(x), y) + xl.append(x) + yl.append(y) + + # clog(+ inf + i inf) returns +inf + ipi /4. + x = np.array([complex(np.inf, np.inf)], dtype=complex) + y = complex(np.inf, 0.25 * np.pi) + assert_almost_equal(np.log(x), y) + xl.append(x) + yl.append(y) + + # clog(+/- inf + iNaN) returns +inf + iNaN. + x = np.array([complex(np.inf, np.nan)], dtype=complex) + y = complex(np.inf, np.nan) + assert_almost_equal(np.log(x), y) + xl.append(x) + yl.append(y) + + x = np.array([complex(-np.inf, np.nan)], dtype=complex) + assert_almost_equal(np.log(x), y) + xl.append(x) + yl.append(y) + + # clog(NaN + iy) returns NaN + iNaN and optionally raises the + # 'invalid' floating-point exception, for finite y. + x = np.array([complex(np.nan, 1)], dtype=complex) + y = complex(np.nan, np.nan) + assert_almost_equal(np.log(x), y) + xl.append(x) + yl.append(y) + + # clog(NaN + i inf) returns +inf + iNaN. + x = np.array([complex(np.nan, np.inf)], dtype=complex) + y = complex(np.inf, np.nan) + assert_almost_equal(np.log(x), y) + xl.append(x) + yl.append(y) + + # clog(NaN + iNaN) returns NaN + iNaN. + x = np.array([complex(np.nan, np.nan)], dtype=complex) + y = complex(np.nan, np.nan) + assert_almost_equal(np.log(x), y) + xl.append(x) + yl.append(y) + + # clog(conj(z)) = conj(clog(z)). + xa = np.array(xl, dtype=complex) + ya = np.array(yl, dtype=complex) + with np.errstate(divide='ignore'): + for i in range(len(xa)): + assert_almost_equal(np.log(xa[i].conj()), ya[i].conj()) + + +class TestCsqrt: + + def test_simple(self): + # sqrt(1) + check_complex_value(np.sqrt, 1, 0, 1, 0) + + # sqrt(1i) + rres = 0.5*np.sqrt(2) + ires = rres + check_complex_value(np.sqrt, 0, 1, rres, ires, False) + + # sqrt(-1) + check_complex_value(np.sqrt, -1, 0, 0, 1) + + def test_simple_conjugate(self): + ref = np.conj(np.sqrt(complex(1, 1))) + + def f(z): + return np.sqrt(np.conj(z)) + + check_complex_value(f, 1, 1, ref.real, ref.imag, False) + + #def test_branch_cut(self): + # _check_branch_cut(f, -1, 0, 1, -1) + + @platform_skip + def test_special_values(self): + # C99: Sec G 6.4.2 + + check = check_complex_value + f = np.sqrt + + # csqrt(+-0 + 0i) is 0 + 0i + check(f, np.PZERO, 0, 0, 0) + check(f, np.NZERO, 0, 0, 0) + + # csqrt(x + infi) is inf + infi for any x (including NaN) + check(f, 1, np.inf, np.inf, np.inf) + check(f, -1, np.inf, np.inf, np.inf) + + check(f, np.PZERO, np.inf, np.inf, np.inf) + check(f, np.NZERO, np.inf, np.inf, np.inf) + check(f, np.inf, np.inf, np.inf, np.inf) + check(f, -np.inf, np.inf, np.inf, np.inf) + check(f, -np.nan, np.inf, np.inf, np.inf) + + # csqrt(x + nani) is nan + nani for any finite x + check(f, 1, np.nan, np.nan, np.nan) + check(f, -1, np.nan, np.nan, np.nan) + check(f, 0, np.nan, np.nan, np.nan) + + # csqrt(-inf + yi) is +0 + infi for any finite y > 0 + check(f, -np.inf, 1, np.PZERO, np.inf) + + # csqrt(inf + yi) is +inf + 0i for any finite y > 0 + check(f, np.inf, 1, np.inf, np.PZERO) + + # csqrt(-inf + nani) is nan +- infi (both +i infi are valid) + def _check_ninf_nan(dummy): + msgform = "csqrt(-inf, nan) is (%f, %f), expected (nan, +-inf)" + z = np.sqrt(np.array(complex(-np.inf, np.nan))) + #Fixme: ugly workaround for isinf bug. + with np.errstate(invalid='ignore'): + if not (np.isnan(z.real) and np.isinf(z.imag)): + raise AssertionError(msgform % (z.real, z.imag)) + + _check_ninf_nan(None) + + # csqrt(+inf + nani) is inf + nani + check(f, np.inf, np.nan, np.inf, np.nan) + + # csqrt(nan + yi) is nan + nani for any finite y (infinite handled in x + # + nani) + check(f, np.nan, 0, np.nan, np.nan) + check(f, np.nan, 1, np.nan, np.nan) + check(f, np.nan, np.nan, np.nan, np.nan) + + # XXX: check for conj(csqrt(z)) == csqrt(conj(z)) (need to fix branch + # cuts first) + +class TestCpow: + def setup(self): + self.olderr = np.seterr(invalid='ignore') + + def teardown(self): + np.seterr(**self.olderr) + + def test_simple(self): + x = np.array([1+1j, 0+2j, 1+2j, np.inf, np.nan]) + y_r = x ** 2 + y = np.power(x, 2) + for i in range(len(x)): + assert_almost_equal(y[i], y_r[i]) + + def test_scalar(self): + x = np.array([1, 1j, 2, 2.5+.37j, np.inf, np.nan]) + y = np.array([1, 1j, -0.5+1.5j, -0.5+1.5j, 2, 3]) + lx = list(range(len(x))) + # Compute the values for complex type in python + p_r = [complex(x[i]) ** complex(y[i]) for i in lx] + # Substitute a result allowed by C99 standard + p_r[4] = complex(np.inf, np.nan) + # Do the same with numpy complex scalars + n_r = [x[i] ** y[i] for i in lx] + for i in lx: + assert_almost_equal(n_r[i], p_r[i], err_msg='Loop %d\n' % i) + + def test_array(self): + x = np.array([1, 1j, 2, 2.5+.37j, np.inf, np.nan]) + y = np.array([1, 1j, -0.5+1.5j, -0.5+1.5j, 2, 3]) + lx = list(range(len(x))) + # Compute the values for complex type in python + p_r = [complex(x[i]) ** complex(y[i]) for i in lx] + # Substitute a result allowed by C99 standard + p_r[4] = complex(np.inf, np.nan) + # Do the same with numpy arrays + n_r = x ** y + for i in lx: + assert_almost_equal(n_r[i], p_r[i], err_msg='Loop %d\n' % i) + +class TestCabs: + def setup(self): + self.olderr = np.seterr(invalid='ignore') + + def teardown(self): + np.seterr(**self.olderr) + + def test_simple(self): + x = np.array([1+1j, 0+2j, 1+2j, np.inf, np.nan]) + y_r = np.array([np.sqrt(2.), 2, np.sqrt(5), np.inf, np.nan]) + y = np.abs(x) + for i in range(len(x)): + assert_almost_equal(y[i], y_r[i]) + + def test_fabs(self): + # Test that np.abs(x +- 0j) == np.abs(x) (as mandated by C99 for cabs) + x = np.array([1+0j], dtype=complex) + assert_array_equal(np.abs(x), np.real(x)) + + x = np.array([complex(1, np.NZERO)], dtype=complex) + assert_array_equal(np.abs(x), np.real(x)) + + x = np.array([complex(np.inf, np.NZERO)], dtype=complex) + assert_array_equal(np.abs(x), np.real(x)) + + x = np.array([complex(np.nan, np.NZERO)], dtype=complex) + assert_array_equal(np.abs(x), np.real(x)) + + def test_cabs_inf_nan(self): + x, y = [], [] + + # cabs(+-nan + nani) returns nan + x.append(np.nan) + y.append(np.nan) + check_real_value(np.abs, np.nan, np.nan, np.nan) + + x.append(np.nan) + y.append(-np.nan) + check_real_value(np.abs, -np.nan, np.nan, np.nan) + + # According to C99 standard, if exactly one of the real/part is inf and + # the other nan, then cabs should return inf + x.append(np.inf) + y.append(np.nan) + check_real_value(np.abs, np.inf, np.nan, np.inf) + + x.append(-np.inf) + y.append(np.nan) + check_real_value(np.abs, -np.inf, np.nan, np.inf) + + # cabs(conj(z)) == conj(cabs(z)) (= cabs(z)) + def f(a): + return np.abs(np.conj(a)) + + def g(a, b): + return np.abs(complex(a, b)) + + xa = np.array(x, dtype=complex) + for i in range(len(xa)): + ref = g(x[i], y[i]) + check_real_value(f, x[i], y[i], ref) + +class TestCarg: + def test_simple(self): + check_real_value(ncu._arg, 1, 0, 0, False) + check_real_value(ncu._arg, 0, 1, 0.5*np.pi, False) + + check_real_value(ncu._arg, 1, 1, 0.25*np.pi, False) + check_real_value(ncu._arg, np.PZERO, np.PZERO, np.PZERO) + + # TODO This can be xfail when the generator functions are got rid of. + @pytest.mark.skip( + reason="Complex arithmetic with signed zero fails on most platforms") + def test_zero(self): + # carg(-0 +- 0i) returns +- pi + check_real_value(ncu._arg, np.NZERO, np.PZERO, np.pi, False) + check_real_value(ncu._arg, np.NZERO, np.NZERO, -np.pi, False) + + # carg(+0 +- 0i) returns +- 0 + check_real_value(ncu._arg, np.PZERO, np.PZERO, np.PZERO) + check_real_value(ncu._arg, np.PZERO, np.NZERO, np.NZERO) + + # carg(x +- 0i) returns +- 0 for x > 0 + check_real_value(ncu._arg, 1, np.PZERO, np.PZERO, False) + check_real_value(ncu._arg, 1, np.NZERO, np.NZERO, False) + + # carg(x +- 0i) returns +- pi for x < 0 + check_real_value(ncu._arg, -1, np.PZERO, np.pi, False) + check_real_value(ncu._arg, -1, np.NZERO, -np.pi, False) + + # carg(+- 0 + yi) returns pi/2 for y > 0 + check_real_value(ncu._arg, np.PZERO, 1, 0.5 * np.pi, False) + check_real_value(ncu._arg, np.NZERO, 1, 0.5 * np.pi, False) + + # carg(+- 0 + yi) returns -pi/2 for y < 0 + check_real_value(ncu._arg, np.PZERO, -1, 0.5 * np.pi, False) + check_real_value(ncu._arg, np.NZERO, -1, -0.5 * np.pi, False) + + #def test_branch_cuts(self): + # _check_branch_cut(ncu._arg, -1, 1j, -1, 1) + + def test_special_values(self): + # carg(-np.inf +- yi) returns +-pi for finite y > 0 + check_real_value(ncu._arg, -np.inf, 1, np.pi, False) + check_real_value(ncu._arg, -np.inf, -1, -np.pi, False) + + # carg(np.inf +- yi) returns +-0 for finite y > 0 + check_real_value(ncu._arg, np.inf, 1, np.PZERO, False) + check_real_value(ncu._arg, np.inf, -1, np.NZERO, False) + + # carg(x +- np.infi) returns +-pi/2 for finite x + check_real_value(ncu._arg, 1, np.inf, 0.5 * np.pi, False) + check_real_value(ncu._arg, 1, -np.inf, -0.5 * np.pi, False) + + # carg(-np.inf +- np.infi) returns +-3pi/4 + check_real_value(ncu._arg, -np.inf, np.inf, 0.75 * np.pi, False) + check_real_value(ncu._arg, -np.inf, -np.inf, -0.75 * np.pi, False) + + # carg(np.inf +- np.infi) returns +-pi/4 + check_real_value(ncu._arg, np.inf, np.inf, 0.25 * np.pi, False) + check_real_value(ncu._arg, np.inf, -np.inf, -0.25 * np.pi, False) + + # carg(x + yi) returns np.nan if x or y is nan + check_real_value(ncu._arg, np.nan, 0, np.nan, False) + check_real_value(ncu._arg, 0, np.nan, np.nan, False) + + check_real_value(ncu._arg, np.nan, np.inf, np.nan, False) + check_real_value(ncu._arg, np.inf, np.nan, np.nan, False) + + +def check_real_value(f, x1, y1, x, exact=True): + z1 = np.array([complex(x1, y1)]) + if exact: + assert_equal(f(z1), x) + else: + assert_almost_equal(f(z1), x) + + +def check_complex_value(f, x1, y1, x2, y2, exact=True): + z1 = np.array([complex(x1, y1)]) + z2 = complex(x2, y2) + with np.errstate(invalid='ignore'): + if exact: + assert_equal(f(z1), z2) + else: + assert_almost_equal(f(z1), z2) + +class TestSpecialComplexAVX(object): + @pytest.mark.parametrize("stride", [-4,-2,-1,1,2,4]) + @pytest.mark.parametrize("astype", [np.complex64, np.complex128]) + def test_array(self, stride, astype): + arr = np.array([complex(np.nan , np.nan), + complex(np.nan , np.inf), + complex(np.inf , np.nan), + complex(np.inf , np.inf), + complex(0. , np.inf), + complex(np.inf , 0.), + complex(0. , 0.), + complex(0. , np.nan), + complex(np.nan , 0.)], dtype=astype) + abs_true = np.array([np.nan, np.inf, np.inf, np.inf, np.inf, np.inf, 0., np.nan, np.nan], dtype=arr.real.dtype) + sq_true = np.array([complex(np.nan, np.nan), + complex(np.nan, np.nan), + complex(np.nan, np.nan), + complex(np.nan, np.inf), + complex(-np.inf, np.nan), + complex(np.inf, np.nan), + complex(0., 0.), + complex(np.nan, np.nan), + complex(np.nan, np.nan)], dtype=astype) + assert_equal(np.abs(arr[::stride]), abs_true[::stride]) + with np.errstate(invalid='ignore'): + assert_equal(np.square(arr[::stride]), sq_true[::stride]) + +class TestComplexAbsoluteAVX(object): + @pytest.mark.parametrize("arraysize", [1,2,3,4,5,6,7,8,9,10,11,13,15,17,18,19]) + @pytest.mark.parametrize("stride", [-4,-3,-2,-1,1,2,3,4]) + @pytest.mark.parametrize("astype", [np.complex64, np.complex128]) + # test to ensure masking and strides work as intended in the AVX implementation + def test_array(self, arraysize, stride, astype): + arr = np.ones(arraysize, dtype=astype) + abs_true = np.ones(arraysize, dtype=arr.real.dtype) + assert_equal(np.abs(arr[::stride]), abs_true[::stride]) + +# Testcase taken as is from https://github.com/numpy/numpy/issues/16660 +class TestComplexAbsoluteMixedDTypes(object): + @pytest.mark.parametrize("stride", [-4,-3,-2,-1,1,2,3,4]) + @pytest.mark.parametrize("astype", [np.complex64, np.complex128]) + @pytest.mark.parametrize("func", ['abs', 'square', 'conjugate']) + + def test_array(self, stride, astype, func): + dtype = [('template_id', 'U') + uni_arr2 = str_arr.astype('>> _lib = np.ctypeslib.load_library('libmystuff', '.') #doctest: +SKIP + +Our result type, an ndarray that must be of type double, be 1-dimensional +and is C-contiguous in memory: + +>>> array_1d_double = np.ctypeslib.ndpointer( +... dtype=np.double, +... ndim=1, flags='CONTIGUOUS') #doctest: +SKIP + +Our C-function typically takes an array and updates its values +in-place. For example:: + + void foo_func(double* x, int length) + { + int i; + for (i = 0; i < length; i++) { + x[i] = i*i; + } + } + +We wrap it using: + +>>> _lib.foo_func.restype = None #doctest: +SKIP +>>> _lib.foo_func.argtypes = [array_1d_double, c_int] #doctest: +SKIP + +Then, we're ready to call ``foo_func``: + +>>> out = np.empty(15, dtype=np.double) +>>> _lib.foo_func(out, len(out)) #doctest: +SKIP + +""" +__all__ = ['load_library', 'ndpointer', 'c_intp', 'as_ctypes', 'as_array'] + +import os +from numpy import ( + integer, ndarray, dtype as _dtype, array, frombuffer +) +from numpy.core.multiarray import _flagdict, flagsobj + +try: + import ctypes +except ImportError: + ctypes = None + +if ctypes is None: + def _dummy(*args, **kwds): + """ + Dummy object that raises an ImportError if ctypes is not available. + + Raises + ------ + ImportError + If ctypes is not available. + + """ + raise ImportError("ctypes is not available.") + load_library = _dummy + as_ctypes = _dummy + as_array = _dummy + from numpy import intp as c_intp + _ndptr_base = object +else: + import numpy.core._internal as nic + c_intp = nic._getintp_ctype() + del nic + _ndptr_base = ctypes.c_void_p + + # Adapted from Albert Strasheim + def load_library(libname, loader_path): + """ + It is possible to load a library using + >>> lib = ctypes.cdll[] # doctest: +SKIP + + But there are cross-platform considerations, such as library file extensions, + plus the fact Windows will just load the first library it finds with that name. + NumPy supplies the load_library function as a convenience. + + Parameters + ---------- + libname : str + Name of the library, which can have 'lib' as a prefix, + but without an extension. + loader_path : str + Where the library can be found. + + Returns + ------- + ctypes.cdll[libpath] : library object + A ctypes library object + + Raises + ------ + OSError + If there is no library with the expected extension, or the + library is defective and cannot be loaded. + """ + if ctypes.__version__ < '1.0.1': + import warnings + warnings.warn("All features of ctypes interface may not work " + "with ctypes < 1.0.1", stacklevel=2) + + ext = os.path.splitext(libname)[1] + if not ext: + # Try to load library with platform-specific name, otherwise + # default to libname.[so|pyd]. Sometimes, these files are built + # erroneously on non-linux platforms. + from numpy.distutils.misc_util import get_shared_lib_extension + so_ext = get_shared_lib_extension() + libname_ext = [libname + so_ext] + # mac, windows and linux >= py3.2 shared library and loadable + # module have different extensions so try both + so_ext2 = get_shared_lib_extension(is_python_ext=True) + if not so_ext2 == so_ext: + libname_ext.insert(0, libname + so_ext2) + else: + libname_ext = [libname] + + loader_path = os.path.abspath(loader_path) + if not os.path.isdir(loader_path): + libdir = os.path.dirname(loader_path) + else: + libdir = loader_path + + for ln in libname_ext: + libpath = os.path.join(libdir, ln) + if os.path.exists(libpath): + try: + return ctypes.cdll[libpath] + except OSError: + ## defective lib file + raise + ## if no successful return in the libname_ext loop: + raise OSError("no file with expected extension") + + +def _num_fromflags(flaglist): + num = 0 + for val in flaglist: + num += _flagdict[val] + return num + +_flagnames = ['C_CONTIGUOUS', 'F_CONTIGUOUS', 'ALIGNED', 'WRITEABLE', + 'OWNDATA', 'UPDATEIFCOPY', 'WRITEBACKIFCOPY'] +def _flags_fromnum(num): + res = [] + for key in _flagnames: + value = _flagdict[key] + if (num & value): + res.append(key) + return res + + +class _ndptr(_ndptr_base): + @classmethod + def from_param(cls, obj): + if not isinstance(obj, ndarray): + raise TypeError("argument must be an ndarray") + if cls._dtype_ is not None \ + and obj.dtype != cls._dtype_: + raise TypeError("array must have data type %s" % cls._dtype_) + if cls._ndim_ is not None \ + and obj.ndim != cls._ndim_: + raise TypeError("array must have %d dimension(s)" % cls._ndim_) + if cls._shape_ is not None \ + and obj.shape != cls._shape_: + raise TypeError("array must have shape %s" % str(cls._shape_)) + if cls._flags_ is not None \ + and ((obj.flags.num & cls._flags_) != cls._flags_): + raise TypeError("array must have flags %s" % + _flags_fromnum(cls._flags_)) + return obj.ctypes + + +class _concrete_ndptr(_ndptr): + """ + Like _ndptr, but with `_shape_` and `_dtype_` specified. + + Notably, this means the pointer has enough information to reconstruct + the array, which is not generally true. + """ + def _check_retval_(self): + """ + This method is called when this class is used as the .restype + attribute for a shared-library function, to automatically wrap the + pointer into an array. + """ + return self.contents + + @property + def contents(self): + """ + Get an ndarray viewing the data pointed to by this pointer. + + This mirrors the `contents` attribute of a normal ctypes pointer + """ + full_dtype = _dtype((self._dtype_, self._shape_)) + full_ctype = ctypes.c_char * full_dtype.itemsize + buffer = ctypes.cast(self, ctypes.POINTER(full_ctype)).contents + return frombuffer(buffer, dtype=full_dtype).squeeze(axis=0) + + +# Factory for an array-checking class with from_param defined for +# use with ctypes argtypes mechanism +_pointer_type_cache = {} +def ndpointer(dtype=None, ndim=None, shape=None, flags=None): + """ + Array-checking restype/argtypes. + + An ndpointer instance is used to describe an ndarray in restypes + and argtypes specifications. This approach is more flexible than + using, for example, ``POINTER(c_double)``, since several restrictions + can be specified, which are verified upon calling the ctypes function. + These include data type, number of dimensions, shape and flags. If a + given array does not satisfy the specified restrictions, + a ``TypeError`` is raised. + + Parameters + ---------- + dtype : data-type, optional + Array data-type. + ndim : int, optional + Number of array dimensions. + shape : tuple of ints, optional + Array shape. + flags : str or tuple of str + Array flags; may be one or more of: + + - C_CONTIGUOUS / C / CONTIGUOUS + - F_CONTIGUOUS / F / FORTRAN + - OWNDATA / O + - WRITEABLE / W + - ALIGNED / A + - WRITEBACKIFCOPY / X + - UPDATEIFCOPY / U + + Returns + ------- + klass : ndpointer type object + A type object, which is an ``_ndtpr`` instance containing + dtype, ndim, shape and flags information. + + Raises + ------ + TypeError + If a given array does not satisfy the specified restrictions. + + Examples + -------- + >>> clib.somefunc.argtypes = [np.ctypeslib.ndpointer(dtype=np.float64, + ... ndim=1, + ... flags='C_CONTIGUOUS')] + ... #doctest: +SKIP + >>> clib.somefunc(np.array([1, 2, 3], dtype=np.float64)) + ... #doctest: +SKIP + + """ + + # normalize dtype to an Optional[dtype] + if dtype is not None: + dtype = _dtype(dtype) + + # normalize flags to an Optional[int] + num = None + if flags is not None: + if isinstance(flags, str): + flags = flags.split(',') + elif isinstance(flags, (int, integer)): + num = flags + flags = _flags_fromnum(num) + elif isinstance(flags, flagsobj): + num = flags.num + flags = _flags_fromnum(num) + if num is None: + try: + flags = [x.strip().upper() for x in flags] + except Exception as e: + raise TypeError("invalid flags specification") from e + num = _num_fromflags(flags) + + # normalize shape to an Optional[tuple] + if shape is not None: + try: + shape = tuple(shape) + except TypeError: + # single integer -> 1-tuple + shape = (shape,) + + cache_key = (dtype, ndim, shape, num) + + try: + return _pointer_type_cache[cache_key] + except KeyError: + pass + + # produce a name for the new type + if dtype is None: + name = 'any' + elif dtype.names is not None: + name = str(id(dtype)) + else: + name = dtype.str + if ndim is not None: + name += "_%dd" % ndim + if shape is not None: + name += "_"+"x".join(str(x) for x in shape) + if flags is not None: + name += "_"+"_".join(flags) + + if dtype is not None and shape is not None: + base = _concrete_ndptr + else: + base = _ndptr + + klass = type("ndpointer_%s"%name, (base,), + {"_dtype_": dtype, + "_shape_" : shape, + "_ndim_" : ndim, + "_flags_" : num}) + _pointer_type_cache[cache_key] = klass + return klass + + +if ctypes is not None: + def _ctype_ndarray(element_type, shape): + """ Create an ndarray of the given element type and shape """ + for dim in shape[::-1]: + element_type = dim * element_type + # prevent the type name include np.ctypeslib + element_type.__module__ = None + return element_type + + + def _get_scalar_type_map(): + """ + Return a dictionary mapping native endian scalar dtype to ctypes types + """ + ct = ctypes + simple_types = [ + ct.c_byte, ct.c_short, ct.c_int, ct.c_long, ct.c_longlong, + ct.c_ubyte, ct.c_ushort, ct.c_uint, ct.c_ulong, ct.c_ulonglong, + ct.c_float, ct.c_double, + ct.c_bool, + ] + return {_dtype(ctype): ctype for ctype in simple_types} + + + _scalar_type_map = _get_scalar_type_map() + + + def _ctype_from_dtype_scalar(dtype): + # swapping twice ensure that `=` is promoted to <, >, or | + dtype_with_endian = dtype.newbyteorder('S').newbyteorder('S') + dtype_native = dtype.newbyteorder('=') + try: + ctype = _scalar_type_map[dtype_native] + except KeyError as e: + raise NotImplementedError( + "Converting {!r} to a ctypes type".format(dtype) + ) from None + + if dtype_with_endian.byteorder == '>': + ctype = ctype.__ctype_be__ + elif dtype_with_endian.byteorder == '<': + ctype = ctype.__ctype_le__ + + return ctype + + + def _ctype_from_dtype_subarray(dtype): + element_dtype, shape = dtype.subdtype + ctype = _ctype_from_dtype(element_dtype) + return _ctype_ndarray(ctype, shape) + + + def _ctype_from_dtype_structured(dtype): + # extract offsets of each field + field_data = [] + for name in dtype.names: + field_dtype, offset = dtype.fields[name][:2] + field_data.append((offset, name, _ctype_from_dtype(field_dtype))) + + # ctypes doesn't care about field order + field_data = sorted(field_data, key=lambda f: f[0]) + + if len(field_data) > 1 and all(offset == 0 for offset, name, ctype in field_data): + # union, if multiple fields all at address 0 + size = 0 + _fields_ = [] + for offset, name, ctype in field_data: + _fields_.append((name, ctype)) + size = max(size, ctypes.sizeof(ctype)) + + # pad to the right size + if dtype.itemsize != size: + _fields_.append(('', ctypes.c_char * dtype.itemsize)) + + # we inserted manual padding, so always `_pack_` + return type('union', (ctypes.Union,), dict( + _fields_=_fields_, + _pack_=1, + __module__=None, + )) + else: + last_offset = 0 + _fields_ = [] + for offset, name, ctype in field_data: + padding = offset - last_offset + if padding < 0: + raise NotImplementedError("Overlapping fields") + if padding > 0: + _fields_.append(('', ctypes.c_char * padding)) + + _fields_.append((name, ctype)) + last_offset = offset + ctypes.sizeof(ctype) + + + padding = dtype.itemsize - last_offset + if padding > 0: + _fields_.append(('', ctypes.c_char * padding)) + + # we inserted manual padding, so always `_pack_` + return type('struct', (ctypes.Structure,), dict( + _fields_=_fields_, + _pack_=1, + __module__=None, + )) + + + def _ctype_from_dtype(dtype): + if dtype.fields is not None: + return _ctype_from_dtype_structured(dtype) + elif dtype.subdtype is not None: + return _ctype_from_dtype_subarray(dtype) + else: + return _ctype_from_dtype_scalar(dtype) + + + def as_ctypes_type(dtype): + r""" + Convert a dtype into a ctypes type. + + Parameters + ---------- + dtype : dtype + The dtype to convert + + Returns + ------- + ctype + A ctype scalar, union, array, or struct + + Raises + ------ + NotImplementedError + If the conversion is not possible + + Notes + ----- + This function does not losslessly round-trip in either direction. + + ``np.dtype(as_ctypes_type(dt))`` will: + + - insert padding fields + - reorder fields to be sorted by offset + - discard field titles + + ``as_ctypes_type(np.dtype(ctype))`` will: + + - discard the class names of `ctypes.Structure`\ s and + `ctypes.Union`\ s + - convert single-element `ctypes.Union`\ s into single-element + `ctypes.Structure`\ s + - insert padding fields + + """ + return _ctype_from_dtype(_dtype(dtype)) + + + def as_array(obj, shape=None): + """ + Create a numpy array from a ctypes array or POINTER. + + The numpy array shares the memory with the ctypes object. + + The shape parameter must be given if converting from a ctypes POINTER. + The shape parameter is ignored if converting from a ctypes array + """ + if isinstance(obj, ctypes._Pointer): + # convert pointers to an array of the desired shape + if shape is None: + raise TypeError( + 'as_array() requires a shape argument when called on a ' + 'pointer') + p_arr_type = ctypes.POINTER(_ctype_ndarray(obj._type_, shape)) + obj = ctypes.cast(obj, p_arr_type).contents + + return array(obj, copy=False) + + + def as_ctypes(obj): + """Create and return a ctypes object from a numpy array. Actually + anything that exposes the __array_interface__ is accepted.""" + ai = obj.__array_interface__ + if ai["strides"]: + raise TypeError("strided arrays not supported") + if ai["version"] != 3: + raise TypeError("only __array_interface__ version 3 supported") + addr, readonly = ai["data"] + if readonly: + raise TypeError("readonly arrays unsupported") + + # can't use `_dtype((ai["typestr"], ai["shape"]))` here, as it overflows + # dtype.itemsize (gh-14214) + ctype_scalar = as_ctypes_type(ai["typestr"]) + result_type = _ctype_ndarray(ctype_scalar, ai["shape"]) + result = result_type.from_address(addr) + result.__keep = obj + return result diff --git a/venv/Lib/site-packages/numpy/ctypeslib.pyi b/venv/Lib/site-packages/numpy/ctypeslib.pyi new file mode 100644 index 0000000..125c20f --- /dev/null +++ b/venv/Lib/site-packages/numpy/ctypeslib.pyi @@ -0,0 +1,10 @@ +from typing import Any, List + +__all__: List[str] + +load_library: Any +ndpointer: Any +c_intp: Any +as_ctypes: Any +as_array: Any +as_ctypes_type: Any diff --git a/venv/Lib/site-packages/numpy/distutils/__config__.py b/venv/Lib/site-packages/numpy/distutils/__config__.py new file mode 100644 index 0000000..2b2ee70 --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/__config__.py @@ -0,0 +1,78 @@ +# This file is generated by numpy's setup.py +# It contains system_info results at the time of building this package. +__all__ = ["get_info","show"] + + +import os +import sys + +extra_dll_dir = os.path.join(os.path.dirname(__file__), '.libs') + +if sys.platform == 'win32' and os.path.isdir(extra_dll_dir): + if sys.version_info >= (3, 8): + os.add_dll_directory(extra_dll_dir) + else: + os.environ.setdefault('PATH', '') + os.environ['PATH'] += os.pathsep + extra_dll_dir + +blas_mkl_info={} +blis_info={} +openblas_info={'library_dirs': ['D:\\a\\1\\s\\numpy\\build\\openblas_info'], 'libraries': ['openblas_info'], 'language': 'f77', 'define_macros': [('HAVE_CBLAS', None)]} +blas_opt_info={'library_dirs': ['D:\\a\\1\\s\\numpy\\build\\openblas_info'], 'libraries': ['openblas_info'], 'language': 'f77', 'define_macros': [('HAVE_CBLAS', None)]} +lapack_mkl_info={} +openblas_lapack_info={'library_dirs': ['D:\\a\\1\\s\\numpy\\build\\openblas_lapack_info'], 'libraries': ['openblas_lapack_info'], 'language': 'f77', 'define_macros': [('HAVE_CBLAS', None)]} +lapack_opt_info={'library_dirs': ['D:\\a\\1\\s\\numpy\\build\\openblas_lapack_info'], 'libraries': ['openblas_lapack_info'], 'language': 'f77', 'define_macros': [('HAVE_CBLAS', None)]} + +def get_info(name): + g = globals() + return g.get(name, g.get(name + "_info", {})) + +def show(): + """ + Show libraries in the system on which NumPy was built. + + Print information about various resources (libraries, library + directories, include directories, etc.) in the system on which + NumPy was built. + + See Also + -------- + get_include : Returns the directory containing NumPy C + header files. + + Notes + ----- + Classes specifying the information to be printed are defined + in the `numpy.distutils.system_info` module. + + Information may include: + + * ``language``: language used to write the libraries (mostly + C or f77) + * ``libraries``: names of libraries found in the system + * ``library_dirs``: directories containing the libraries + * ``include_dirs``: directories containing library header files + * ``src_dirs``: directories containing library source files + * ``define_macros``: preprocessor macros used by + ``distutils.setup`` + + Examples + -------- + >>> import numpy as np + >>> np.show_config() + blas_opt_info: + language = c + define_macros = [('HAVE_CBLAS', None)] + libraries = ['openblas', 'openblas'] + library_dirs = ['/usr/local/lib'] + """ + for name,info_dict in globals().items(): + if name[0] == "_" or type(info_dict) is not type({}): continue + print(name + ":") + if not info_dict: + print(" NOT AVAILABLE") + for k,v in info_dict.items(): + v = str(v) + if k == "sources" and len(v) > 200: + v = v[:60] + " ...\n... " + v[-60:] + print(" %s = %s" % (k,v)) diff --git a/venv/Lib/site-packages/numpy/distutils/__init__.py b/venv/Lib/site-packages/numpy/distutils/__init__.py new file mode 100644 index 0000000..79974d1 --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/__init__.py @@ -0,0 +1,51 @@ +""" +An enhanced distutils, providing support for Fortran compilers, for BLAS, +LAPACK and other common libraries for numerical computing, and more. + +Public submodules are:: + + misc_util + system_info + cpu_info + log + exec_command + +For details, please see the *Packaging* and *NumPy Distutils User Guide* +sections of the NumPy Reference Guide. + +For configuring the preference for and location of libraries like BLAS and +LAPACK, and for setting include paths and similar build options, please see +``site.cfg.example`` in the root of the NumPy repository or sdist. + +""" + +# Must import local ccompiler ASAP in order to get +# customized CCompiler.spawn effective. +from . import ccompiler +from . import unixccompiler + +from .npy_pkg_config import * + +# If numpy is installed, add distutils.test() +try: + from . import __config__ + # Normally numpy is installed if the above import works, but an interrupted + # in-place build could also have left a __config__.py. In that case the + # next import may still fail, so keep it inside the try block. + from numpy._pytesttester import PytestTester + test = PytestTester(__name__) + del PytestTester +except ImportError: + pass + + +def customized_fcompiler(plat=None, compiler=None): + from numpy.distutils.fcompiler import new_fcompiler + c = new_fcompiler(plat=plat, compiler=compiler) + c.customize() + return c + +def customized_ccompiler(plat=None, compiler=None, verbose=1): + c = ccompiler.new_compiler(plat=plat, compiler=compiler, verbose=verbose) + c.customize('') + return c diff --git a/venv/Lib/site-packages/numpy/distutils/__init__.pyi b/venv/Lib/site-packages/numpy/distutils/__init__.pyi new file mode 100644 index 0000000..3938d68 --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/__init__.pyi @@ -0,0 +1,4 @@ +from typing import Any + +# TODO: remove when the full numpy namespace is defined +def __getattr__(name: str) -> Any: ... diff --git a/venv/Lib/site-packages/numpy/distutils/_shell_utils.py b/venv/Lib/site-packages/numpy/distutils/_shell_utils.py new file mode 100644 index 0000000..82abd5f --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/_shell_utils.py @@ -0,0 +1,91 @@ +""" +Helper functions for interacting with the shell, and consuming shell-style +parameters provided in config files. +""" +import os +import shlex +import subprocess +try: + from shlex import quote +except ImportError: + from pipes import quote + +__all__ = ['WindowsParser', 'PosixParser', 'NativeParser'] + + +class CommandLineParser: + """ + An object that knows how to split and join command-line arguments. + + It must be true that ``argv == split(join(argv))`` for all ``argv``. + The reverse neednt be true - `join(split(cmd))` may result in the addition + or removal of unnecessary escaping. + """ + @staticmethod + def join(argv): + """ Join a list of arguments into a command line string """ + raise NotImplementedError + + @staticmethod + def split(cmd): + """ Split a command line string into a list of arguments """ + raise NotImplementedError + + +class WindowsParser: + """ + The parsing behavior used by `subprocess.call("string")` on Windows, which + matches the Microsoft C/C++ runtime. + + Note that this is _not_ the behavior of cmd. + """ + @staticmethod + def join(argv): + # note that list2cmdline is specific to the windows syntax + return subprocess.list2cmdline(argv) + + @staticmethod + def split(cmd): + import ctypes # guarded import for systems without ctypes + try: + ctypes.windll + except AttributeError: + raise NotImplementedError + + # Windows has special parsing rules for the executable (no quotes), + # that we do not care about - insert a dummy element + if not cmd: + return [] + cmd = 'dummy ' + cmd + + CommandLineToArgvW = ctypes.windll.shell32.CommandLineToArgvW + CommandLineToArgvW.restype = ctypes.POINTER(ctypes.c_wchar_p) + CommandLineToArgvW.argtypes = (ctypes.c_wchar_p, ctypes.POINTER(ctypes.c_int)) + + nargs = ctypes.c_int() + lpargs = CommandLineToArgvW(cmd, ctypes.byref(nargs)) + args = [lpargs[i] for i in range(nargs.value)] + assert not ctypes.windll.kernel32.LocalFree(lpargs) + + # strip the element we inserted + assert args[0] == "dummy" + return args[1:] + + +class PosixParser: + """ + The parsing behavior used by `subprocess.call("string", shell=True)` on Posix. + """ + @staticmethod + def join(argv): + return ' '.join(quote(arg) for arg in argv) + + @staticmethod + def split(cmd): + return shlex.split(cmd, posix=True) + + +if os.name == 'nt': + NativeParser = WindowsParser +elif os.name == 'posix': + NativeParser = PosixParser diff --git a/venv/Lib/site-packages/numpy/distutils/ccompiler.py b/venv/Lib/site-packages/numpy/distutils/ccompiler.py new file mode 100644 index 0000000..106436e --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/ccompiler.py @@ -0,0 +1,791 @@ +import os +import re +import sys +import shlex +import time +import subprocess +from copy import copy +from distutils import ccompiler +from distutils.ccompiler import ( + compiler_class, gen_lib_options, get_default_compiler, new_compiler, + CCompiler +) +from distutils.errors import ( + DistutilsExecError, DistutilsModuleError, DistutilsPlatformError, + CompileError, UnknownFileError +) +from distutils.sysconfig import customize_compiler +from distutils.version import LooseVersion + +from numpy.distutils import log +from numpy.distutils.exec_command import ( + filepath_from_subprocess_output, forward_bytes_to_stdout +) +from numpy.distutils.misc_util import cyg2win32, is_sequence, mingw32, \ + get_num_build_jobs, \ + _commandline_dep_string + +# globals for parallel build management +try: + import threading +except ImportError: + import dummy_threading as threading +_job_semaphore = None +_global_lock = threading.Lock() +_processing_files = set() + + +def _needs_build(obj, cc_args, extra_postargs, pp_opts): + """ + Check if an objects needs to be rebuild based on its dependencies + + Parameters + ---------- + obj : str + object file + + Returns + ------- + bool + """ + # defined in unixcompiler.py + dep_file = obj + '.d' + if not os.path.exists(dep_file): + return True + + # dep_file is a makefile containing 'object: dependencies' + # formatted like posix shell (spaces escaped, \ line continuations) + # the last line contains the compiler commandline arguments as some + # projects may compile an extension multiple times with different + # arguments + with open(dep_file, "r") as f: + lines = f.readlines() + + cmdline =_commandline_dep_string(cc_args, extra_postargs, pp_opts) + last_cmdline = lines[-1] + if last_cmdline != cmdline: + return True + + contents = ''.join(lines[:-1]) + deps = [x for x in shlex.split(contents, posix=True) + if x != "\n" and not x.endswith(":")] + + try: + t_obj = os.stat(obj).st_mtime + + # check if any of the dependencies is newer than the object + # the dependencies includes the source used to create the object + for f in deps: + if os.stat(f).st_mtime > t_obj: + return True + except OSError: + # no object counts as newer (shouldn't happen if dep_file exists) + return True + + return False + + +def replace_method(klass, method_name, func): + # Py3k does not have unbound method anymore, MethodType does not work + m = lambda self, *args, **kw: func(self, *args, **kw) + setattr(klass, method_name, m) + + +###################################################################### +## Method that subclasses may redefine. But don't call this method, +## it i private to CCompiler class and may return unexpected +## results if used elsewhere. So, you have been warned.. + +def CCompiler_find_executables(self): + """ + Does nothing here, but is called by the get_version method and can be + overridden by subclasses. In particular it is redefined in the `FCompiler` + class where more documentation can be found. + + """ + pass + + +replace_method(CCompiler, 'find_executables', CCompiler_find_executables) + + +# Using customized CCompiler.spawn. +def CCompiler_spawn(self, cmd, display=None): + """ + Execute a command in a sub-process. + + Parameters + ---------- + cmd : str + The command to execute. + display : str or sequence of str, optional + The text to add to the log file kept by `numpy.distutils`. + If not given, `display` is equal to `cmd`. + + Returns + ------- + None + + Raises + ------ + DistutilsExecError + If the command failed, i.e. the exit status was not 0. + + """ + if display is None: + display = cmd + if is_sequence(display): + display = ' '.join(list(display)) + log.info(display) + try: + if self.verbose: + subprocess.check_output(cmd) + else: + subprocess.check_output(cmd, stderr=subprocess.STDOUT) + except subprocess.CalledProcessError as exc: + o = exc.output + s = exc.returncode + except OSError: + # OSError doesn't have the same hooks for the exception + # output, but exec_command() historically would use an + # empty string for EnvironmentError (base class for + # OSError) + o = b'' + # status previously used by exec_command() for parent + # of OSError + s = 127 + else: + # use a convenience return here so that any kind of + # caught exception will execute the default code after the + # try / except block, which handles various exceptions + return None + + if is_sequence(cmd): + cmd = ' '.join(list(cmd)) + + if self.verbose: + forward_bytes_to_stdout(o) + + if re.search(b'Too many open files', o): + msg = '\nTry rerunning setup command until build succeeds.' + else: + msg = '' + raise DistutilsExecError('Command "%s" failed with exit status %d%s' % + (cmd, s, msg)) + +replace_method(CCompiler, 'spawn', CCompiler_spawn) + +def CCompiler_object_filenames(self, source_filenames, strip_dir=0, output_dir=''): + """ + Return the name of the object files for the given source files. + + Parameters + ---------- + source_filenames : list of str + The list of paths to source files. Paths can be either relative or + absolute, this is handled transparently. + strip_dir : bool, optional + Whether to strip the directory from the returned paths. If True, + the file name prepended by `output_dir` is returned. Default is False. + output_dir : str, optional + If given, this path is prepended to the returned paths to the + object files. + + Returns + ------- + obj_names : list of str + The list of paths to the object files corresponding to the source + files in `source_filenames`. + + """ + if output_dir is None: + output_dir = '' + obj_names = [] + for src_name in source_filenames: + base, ext = os.path.splitext(os.path.normpath(src_name)) + base = os.path.splitdrive(base)[1] # Chop off the drive + base = base[os.path.isabs(base):] # If abs, chop off leading / + if base.startswith('..'): + # Resolve starting relative path components, middle ones + # (if any) have been handled by os.path.normpath above. + i = base.rfind('..')+2 + d = base[:i] + d = os.path.basename(os.path.abspath(d)) + base = d + base[i:] + if ext not in self.src_extensions: + raise UnknownFileError("unknown file type '%s' (from '%s')" % (ext, src_name)) + if strip_dir: + base = os.path.basename(base) + obj_name = os.path.join(output_dir, base + self.obj_extension) + obj_names.append(obj_name) + return obj_names + +replace_method(CCompiler, 'object_filenames', CCompiler_object_filenames) + +def CCompiler_compile(self, sources, output_dir=None, macros=None, + include_dirs=None, debug=0, extra_preargs=None, + extra_postargs=None, depends=None): + """ + Compile one or more source files. + + Please refer to the Python distutils API reference for more details. + + Parameters + ---------- + sources : list of str + A list of filenames + output_dir : str, optional + Path to the output directory. + macros : list of tuples + A list of macro definitions. + include_dirs : list of str, optional + The directories to add to the default include file search path for + this compilation only. + debug : bool, optional + Whether or not to output debug symbols in or alongside the object + file(s). + extra_preargs, extra_postargs : ? + Extra pre- and post-arguments. + depends : list of str, optional + A list of file names that all targets depend on. + + Returns + ------- + objects : list of str + A list of object file names, one per source file `sources`. + + Raises + ------ + CompileError + If compilation fails. + + """ + # This method is effective only with Python >=2.3 distutils. + # Any changes here should be applied also to fcompiler.compile + # method to support pre Python 2.3 distutils. + global _job_semaphore + + jobs = get_num_build_jobs() + + # setup semaphore to not exceed number of compile jobs when parallelized at + # extension level (python >= 3.5) + with _global_lock: + if _job_semaphore is None: + _job_semaphore = threading.Semaphore(jobs) + + if not sources: + return [] + from numpy.distutils.fcompiler import (FCompiler, is_f_file, + has_f90_header) + if isinstance(self, FCompiler): + display = [] + for fc in ['f77', 'f90', 'fix']: + fcomp = getattr(self, 'compiler_'+fc) + if fcomp is None: + continue + display.append("Fortran %s compiler: %s" % (fc, ' '.join(fcomp))) + display = '\n'.join(display) + else: + ccomp = self.compiler_so + display = "C compiler: %s\n" % (' '.join(ccomp),) + log.info(display) + macros, objects, extra_postargs, pp_opts, build = \ + self._setup_compile(output_dir, macros, include_dirs, sources, + depends, extra_postargs) + cc_args = self._get_cc_args(pp_opts, debug, extra_preargs) + display = "compile options: '%s'" % (' '.join(cc_args)) + if extra_postargs: + display += "\nextra options: '%s'" % (' '.join(extra_postargs)) + log.info(display) + + def single_compile(args): + obj, (src, ext) = args + if not _needs_build(obj, cc_args, extra_postargs, pp_opts): + return + + # check if we are currently already processing the same object + # happens when using the same source in multiple extensions + while True: + # need explicit lock as there is no atomic check and add with GIL + with _global_lock: + # file not being worked on, start working + if obj not in _processing_files: + _processing_files.add(obj) + break + # wait for the processing to end + time.sleep(0.1) + + try: + # retrieve slot from our #job semaphore and build + with _job_semaphore: + self._compile(obj, src, ext, cc_args, extra_postargs, pp_opts) + finally: + # register being done processing + with _global_lock: + _processing_files.remove(obj) + + + if isinstance(self, FCompiler): + objects_to_build = list(build.keys()) + f77_objects, other_objects = [], [] + for obj in objects: + if obj in objects_to_build: + src, ext = build[obj] + if self.compiler_type=='absoft': + obj = cyg2win32(obj) + src = cyg2win32(src) + if is_f_file(src) and not has_f90_header(src): + f77_objects.append((obj, (src, ext))) + else: + other_objects.append((obj, (src, ext))) + + # f77 objects can be built in parallel + build_items = f77_objects + # build f90 modules serial, module files are generated during + # compilation and may be used by files later in the list so the + # ordering is important + for o in other_objects: + single_compile(o) + else: + build_items = build.items() + + if len(build) > 1 and jobs > 1: + # build parallel + import multiprocessing.pool + pool = multiprocessing.pool.ThreadPool(jobs) + pool.map(single_compile, build_items) + pool.close() + else: + # build serial + for o in build_items: + single_compile(o) + + # Return *all* object filenames, not just the ones we just built. + return objects + +replace_method(CCompiler, 'compile', CCompiler_compile) + +def CCompiler_customize_cmd(self, cmd, ignore=()): + """ + Customize compiler using distutils command. + + Parameters + ---------- + cmd : class instance + An instance inheriting from `distutils.cmd.Command`. + ignore : sequence of str, optional + List of `CCompiler` commands (without ``'set_'``) that should not be + altered. Strings that are checked for are: + ``('include_dirs', 'define', 'undef', 'libraries', 'library_dirs', + 'rpath', 'link_objects')``. + + Returns + ------- + None + + """ + log.info('customize %s using %s' % (self.__class__.__name__, + cmd.__class__.__name__)) + def allow(attr): + return getattr(cmd, attr, None) is not None and attr not in ignore + + if allow('include_dirs'): + self.set_include_dirs(cmd.include_dirs) + if allow('define'): + for (name, value) in cmd.define: + self.define_macro(name, value) + if allow('undef'): + for macro in cmd.undef: + self.undefine_macro(macro) + if allow('libraries'): + self.set_libraries(self.libraries + cmd.libraries) + if allow('library_dirs'): + self.set_library_dirs(self.library_dirs + cmd.library_dirs) + if allow('rpath'): + self.set_runtime_library_dirs(cmd.rpath) + if allow('link_objects'): + self.set_link_objects(cmd.link_objects) + +replace_method(CCompiler, 'customize_cmd', CCompiler_customize_cmd) + +def _compiler_to_string(compiler): + props = [] + mx = 0 + keys = list(compiler.executables.keys()) + for key in ['version', 'libraries', 'library_dirs', + 'object_switch', 'compile_switch', + 'include_dirs', 'define', 'undef', 'rpath', 'link_objects']: + if key not in keys: + keys.append(key) + for key in keys: + if hasattr(compiler, key): + v = getattr(compiler, key) + mx = max(mx, len(key)) + props.append((key, repr(v))) + fmt = '%-' + repr(mx+1) + 's = %s' + lines = [fmt % prop for prop in props] + return '\n'.join(lines) + +def CCompiler_show_customization(self): + """ + Print the compiler customizations to stdout. + + Parameters + ---------- + None + + Returns + ------- + None + + Notes + ----- + Printing is only done if the distutils log threshold is < 2. + + """ + try: + self.get_version() + except Exception: + pass + if log._global_log.threshold<2: + print('*'*80) + print(self.__class__) + print(_compiler_to_string(self)) + print('*'*80) + +replace_method(CCompiler, 'show_customization', CCompiler_show_customization) + +def CCompiler_customize(self, dist, need_cxx=0): + """ + Do any platform-specific customization of a compiler instance. + + This method calls `distutils.sysconfig.customize_compiler` for + platform-specific customization, as well as optionally remove a flag + to suppress spurious warnings in case C++ code is being compiled. + + Parameters + ---------- + dist : object + This parameter is not used for anything. + need_cxx : bool, optional + Whether or not C++ has to be compiled. If so (True), the + ``"-Wstrict-prototypes"`` option is removed to prevent spurious + warnings. Default is False. + + Returns + ------- + None + + Notes + ----- + All the default options used by distutils can be extracted with:: + + from distutils import sysconfig + sysconfig.get_config_vars('CC', 'CXX', 'OPT', 'BASECFLAGS', + 'CCSHARED', 'LDSHARED', 'SO') + + """ + # See FCompiler.customize for suggested usage. + log.info('customize %s' % (self.__class__.__name__)) + customize_compiler(self) + if need_cxx: + # In general, distutils uses -Wstrict-prototypes, but this option is + # not valid for C++ code, only for C. Remove it if it's there to + # avoid a spurious warning on every compilation. + try: + self.compiler_so.remove('-Wstrict-prototypes') + except (AttributeError, ValueError): + pass + + if hasattr(self, 'compiler') and 'cc' in self.compiler[0]: + if not self.compiler_cxx: + if self.compiler[0].startswith('gcc'): + a, b = 'gcc', 'g++' + else: + a, b = 'cc', 'c++' + self.compiler_cxx = [self.compiler[0].replace(a, b)]\ + + self.compiler[1:] + else: + if hasattr(self, 'compiler'): + log.warn("#### %s #######" % (self.compiler,)) + if not hasattr(self, 'compiler_cxx'): + log.warn('Missing compiler_cxx fix for ' + self.__class__.__name__) + + + # check if compiler supports gcc style automatic dependencies + # run on every extension so skip for known good compilers + if hasattr(self, 'compiler') and ('gcc' in self.compiler[0] or + 'g++' in self.compiler[0] or + 'clang' in self.compiler[0]): + self._auto_depends = True + elif os.name == 'posix': + import tempfile + import shutil + tmpdir = tempfile.mkdtemp() + try: + fn = os.path.join(tmpdir, "file.c") + with open(fn, "w") as f: + f.write("int a;\n") + self.compile([fn], output_dir=tmpdir, + extra_preargs=['-MMD', '-MF', fn + '.d']) + self._auto_depends = True + except CompileError: + self._auto_depends = False + finally: + shutil.rmtree(tmpdir) + + return + +replace_method(CCompiler, 'customize', CCompiler_customize) + +def simple_version_match(pat=r'[-.\d]+', ignore='', start=''): + """ + Simple matching of version numbers, for use in CCompiler and FCompiler. + + Parameters + ---------- + pat : str, optional + A regular expression matching version numbers. + Default is ``r'[-.\\d]+'``. + ignore : str, optional + A regular expression matching patterns to skip. + Default is ``''``, in which case nothing is skipped. + start : str, optional + A regular expression matching the start of where to start looking + for version numbers. + Default is ``''``, in which case searching is started at the + beginning of the version string given to `matcher`. + + Returns + ------- + matcher : callable + A function that is appropriate to use as the ``.version_match`` + attribute of a `CCompiler` class. `matcher` takes a single parameter, + a version string. + + """ + def matcher(self, version_string): + # version string may appear in the second line, so getting rid + # of new lines: + version_string = version_string.replace('\n', ' ') + pos = 0 + if start: + m = re.match(start, version_string) + if not m: + return None + pos = m.end() + while True: + m = re.search(pat, version_string[pos:]) + if not m: + return None + if ignore and re.match(ignore, m.group(0)): + pos = m.end() + continue + break + return m.group(0) + return matcher + +def CCompiler_get_version(self, force=False, ok_status=[0]): + """ + Return compiler version, or None if compiler is not available. + + Parameters + ---------- + force : bool, optional + If True, force a new determination of the version, even if the + compiler already has a version attribute. Default is False. + ok_status : list of int, optional + The list of status values returned by the version look-up process + for which a version string is returned. If the status value is not + in `ok_status`, None is returned. Default is ``[0]``. + + Returns + ------- + version : str or None + Version string, in the format of `distutils.version.LooseVersion`. + + """ + if not force and hasattr(self, 'version'): + return self.version + self.find_executables() + try: + version_cmd = self.version_cmd + except AttributeError: + return None + if not version_cmd or not version_cmd[0]: + return None + try: + matcher = self.version_match + except AttributeError: + try: + pat = self.version_pattern + except AttributeError: + return None + def matcher(version_string): + m = re.match(pat, version_string) + if not m: + return None + version = m.group('version') + return version + + try: + output = subprocess.check_output(version_cmd, stderr=subprocess.STDOUT) + except subprocess.CalledProcessError as exc: + output = exc.output + status = exc.returncode + except OSError: + # match the historical returns for a parent + # exception class caught by exec_command() + status = 127 + output = b'' + else: + # output isn't actually a filepath but we do this + # for now to match previous distutils behavior + output = filepath_from_subprocess_output(output) + status = 0 + + version = None + if status in ok_status: + version = matcher(output) + if version: + version = LooseVersion(version) + self.version = version + return version + +replace_method(CCompiler, 'get_version', CCompiler_get_version) + +def CCompiler_cxx_compiler(self): + """ + Return the C++ compiler. + + Parameters + ---------- + None + + Returns + ------- + cxx : class instance + The C++ compiler, as a `CCompiler` instance. + + """ + if self.compiler_type in ('msvc', 'intelw', 'intelemw'): + return self + + cxx = copy(self) + cxx.compiler_so = [cxx.compiler_cxx[0]] + cxx.compiler_so[1:] + if sys.platform.startswith('aix') and 'ld_so_aix' in cxx.linker_so[0]: + # AIX needs the ld_so_aix script included with Python + cxx.linker_so = [cxx.linker_so[0], cxx.compiler_cxx[0]] \ + + cxx.linker_so[2:] + else: + cxx.linker_so = [cxx.compiler_cxx[0]] + cxx.linker_so[1:] + return cxx + +replace_method(CCompiler, 'cxx_compiler', CCompiler_cxx_compiler) + +compiler_class['intel'] = ('intelccompiler', 'IntelCCompiler', + "Intel C Compiler for 32-bit applications") +compiler_class['intele'] = ('intelccompiler', 'IntelItaniumCCompiler', + "Intel C Itanium Compiler for Itanium-based applications") +compiler_class['intelem'] = ('intelccompiler', 'IntelEM64TCCompiler', + "Intel C Compiler for 64-bit applications") +compiler_class['intelw'] = ('intelccompiler', 'IntelCCompilerW', + "Intel C Compiler for 32-bit applications on Windows") +compiler_class['intelemw'] = ('intelccompiler', 'IntelEM64TCCompilerW', + "Intel C Compiler for 64-bit applications on Windows") +compiler_class['pathcc'] = ('pathccompiler', 'PathScaleCCompiler', + "PathScale Compiler for SiCortex-based applications") +ccompiler._default_compilers += (('linux.*', 'intel'), + ('linux.*', 'intele'), + ('linux.*', 'intelem'), + ('linux.*', 'pathcc'), + ('nt', 'intelw'), + ('nt', 'intelemw')) + +if sys.platform == 'win32': + compiler_class['mingw32'] = ('mingw32ccompiler', 'Mingw32CCompiler', + "Mingw32 port of GNU C Compiler for Win32"\ + "(for MSC built Python)") + if mingw32(): + # On windows platforms, we want to default to mingw32 (gcc) + # because msvc can't build blitz stuff. + log.info('Setting mingw32 as default compiler for nt.') + ccompiler._default_compilers = (('nt', 'mingw32'),) \ + + ccompiler._default_compilers + + +_distutils_new_compiler = new_compiler +def new_compiler (plat=None, + compiler=None, + verbose=None, + dry_run=0, + force=0): + # Try first C compilers from numpy.distutils. + if verbose is None: + verbose = log.get_threshold() <= log.INFO + if plat is None: + plat = os.name + try: + if compiler is None: + compiler = get_default_compiler(plat) + (module_name, class_name, long_description) = compiler_class[compiler] + except KeyError: + msg = "don't know how to compile C/C++ code on platform '%s'" % plat + if compiler is not None: + msg = msg + " with '%s' compiler" % compiler + raise DistutilsPlatformError(msg) + module_name = "numpy.distutils." + module_name + try: + __import__ (module_name) + except ImportError as e: + msg = str(e) + log.info('%s in numpy.distutils; trying from distutils', + str(msg)) + module_name = module_name[6:] + try: + __import__(module_name) + except ImportError as e: + msg = str(e) + raise DistutilsModuleError("can't compile C/C++ code: unable to load module '%s'" % \ + module_name) + try: + module = sys.modules[module_name] + klass = vars(module)[class_name] + except KeyError: + raise DistutilsModuleError(("can't compile C/C++ code: unable to find class '%s' " + + "in module '%s'") % (class_name, module_name)) + compiler = klass(None, dry_run, force) + compiler.verbose = verbose + log.debug('new_compiler returns %s' % (klass)) + return compiler + +ccompiler.new_compiler = new_compiler + +_distutils_gen_lib_options = gen_lib_options +def gen_lib_options(compiler, library_dirs, runtime_library_dirs, libraries): + # the version of this function provided by CPython allows the following + # to return lists, which are unpacked automatically: + # - compiler.runtime_library_dir_option + # our version extends the behavior to: + # - compiler.library_dir_option + # - compiler.library_option + # - compiler.find_library_file + r = _distutils_gen_lib_options(compiler, library_dirs, + runtime_library_dirs, libraries) + lib_opts = [] + for i in r: + if is_sequence(i): + lib_opts.extend(list(i)) + else: + lib_opts.append(i) + return lib_opts +ccompiler.gen_lib_options = gen_lib_options + +# Also fix up the various compiler modules, which do +# from distutils.ccompiler import gen_lib_options +# Don't bother with mwerks, as we don't support Classic Mac. +for _cc in ['msvc9', 'msvc', '_msvc', 'bcpp', 'cygwinc', 'emxc', 'unixc']: + _m = sys.modules.get('distutils.' + _cc + 'compiler') + if _m is not None: + setattr(_m, 'gen_lib_options', gen_lib_options) + diff --git a/venv/Lib/site-packages/numpy/distutils/ccompiler_opt.py b/venv/Lib/site-packages/numpy/distutils/ccompiler_opt.py new file mode 100644 index 0000000..ea944bd --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/ccompiler_opt.py @@ -0,0 +1,2535 @@ +"""Provides the `CCompilerOpt` class, used for handling the CPU/hardware +optimization, starting from parsing the command arguments, to managing the +relation between the CPU baseline and dispatch-able features, +also generating the required C headers and ending with compiling +the sources with proper compiler's flags. + +`CCompilerOpt` doesn't provide runtime detection for the CPU features, +instead only focuses on the compiler side, but it creates abstract C headers +that can be used later for the final runtime dispatching process.""" + +import sys, io, os, re, textwrap, pprint, inspect, atexit, subprocess + +class _Config: + """An abstract class holds all configurable attributes of `CCompilerOpt`, + these class attributes can be used to change the default behavior + of `CCompilerOpt` in order to fit other requirements. + + Attributes + ---------- + conf_nocache : bool + Set True to disable memory and file cache. + Default is False. + + conf_noopt : bool + Set True to forces the optimization to be disabled, + in this case `CCompilerOpt` tends to generate all + expected headers in order to 'not' break the build. + Default is False. + + conf_cache_factors : list + Add extra factors to the primary caching factors. The caching factors + are utilized to determine if there are changes had happened that + requires to discard the cache and re-updating it. The primary factors + are the arguments of `CCompilerOpt` and `CCompiler`'s properties(type, flags, etc). + Default is list of two items, containing the time of last modification + of `ccompiler_opt` and value of attribute "conf_noopt" + + conf_tmp_path : str, + The path of temporary directory. Default is auto-created + temporary directory via ``tempfile.mkdtemp()``. + + conf_check_path : str + The path of testing files. Each added CPU feature must have a + **C** source file contains at least one intrinsic or instruction that + related to this feature, so it can be tested against the compiler. + Default is ``./distutils/checks``. + + conf_target_groups : dict + Extra tokens that can be reached from dispatch-able sources through + the special mark ``@targets``. Default is an empty dictionary. + + **Notes**: + - case-insensitive for tokens and group names + - sign '#' must stick in the begin of group name and only within ``@targets`` + + **Example**: + .. code-block:: console + + $ "@targets #avx_group other_tokens" > group_inside.c + + >>> CCompilerOpt.conf_target_groups["avx_group"] = \\ + "$werror $maxopt avx2 avx512f avx512_skx" + >>> cco = CCompilerOpt(cc_instance) + >>> cco.try_dispatch(["group_inside.c"]) + + conf_c_prefix : str + The prefix of public C definitions. Default is ``"NPY_"``. + + conf_c_prefix_ : str + The prefix of internal C definitions. Default is ``"NPY__"``. + + conf_cc_flags : dict + Nested dictionaries defining several compiler flags + that linked to some major functions, the main key + represent the compiler name and sub-keys represent + flags names. Default is already covers all supported + **C** compilers. + + Sub-keys explained as follows: + + "native": str or None + used by argument option `native`, to detect the current + machine support via the compiler. + "werror": str or None + utilized to treat warning as errors during testing CPU features + against the compiler and also for target's policy `$werror` + via dispatch-able sources. + "maxopt": str or None + utilized for target's policy '$maxopt' and the value should + contains the maximum acceptable optimization by the compiler. + e.g. in gcc `'-O3'` + + **Notes**: + * case-sensitive for compiler names and flags + * use space to separate multiple flags + * any flag will tested against the compiler and it will skipped + if it's not applicable. + + conf_min_features : dict + A dictionary defines the used CPU features for + argument option `'min'`, the key represent the CPU architecture + name e.g. `'x86'`. Default values provide the best effort + on wide range of users platforms. + + **Note**: case-sensitive for architecture names. + + conf_features : dict + Nested dictionaries used for identifying the CPU features. + the primary key is represented as a feature name or group name + that gathers several features. Default values covers all + supported features but without the major options like "flags", + these undefined options handle it by method `conf_features_partial()`. + Default value is covers almost all CPU features for *X86*, *IBM/Power64* + and *ARM 7/8*. + + Sub-keys explained as follows: + + "implies" : str or list, optional, + List of CPU feature names to be implied by it, + the feature name must be defined within `conf_features`. + Default is None. + + "flags": str or list, optional + List of compiler flags. Default is None. + + "detect": str or list, optional + List of CPU feature names that required to be detected + in runtime. By default, its the feature name or features + in "group" if its specified. + + "implies_detect": bool, optional + If True, all "detect" of implied features will be combined. + Default is True. see `feature_detect()`. + + "group": str or list, optional + Same as "implies" but doesn't require the feature name to be + defined within `conf_features`. + + "interest": int, required + a key for sorting CPU features + + "headers": str or list, optional + intrinsics C header file + + "disable": str, optional + force disable feature, the string value should contains the + reason of disabling. + + "autovec": bool or None, optional + True or False to declare that CPU feature can be auto-vectorized + by the compiler. + By default(None), treated as True if the feature contains at + least one applicable flag. see `feature_can_autovec()` + + "extra_checks": str or list, optional + Extra test case names for the CPU feature that need to be tested + against the compiler. + + Each test case must have a C file named ``extra_xxxx.c``, where + ``xxxx`` is the case name in lower case, under 'conf_check_path'. + It should contain at least one intrinsic or function related to the test case. + + If the compiler able to successfully compile the C file then `CCompilerOpt` + will add a C ``#define`` for it into the main dispatch header, e.g. + ```#define {conf_c_prefix}_XXXX`` where ``XXXX`` is the case name in upper case. + + **NOTES**: + * space can be used as separator with options that supports "str or list" + * case-sensitive for all values and feature name must be in upper-case. + * if flags aren't applicable, its will skipped rather than disable the + CPU feature + * the CPU feature will disabled if the compiler fail to compile + the test file + """ + conf_nocache = False + conf_noopt = False + conf_cache_factors = None + conf_tmp_path = None + conf_check_path = os.path.join( + os.path.dirname(os.path.realpath(__file__)), "checks" + ) + conf_target_groups = {} + conf_c_prefix = 'NPY_' + conf_c_prefix_ = 'NPY__' + conf_cc_flags = dict( + gcc = dict( + # native should always fail on arm and ppc64, + # native usually works only with x86 + native = '-march=native', + opt = '-O3', + werror = '-Werror' + ), + clang = dict( + native = '-march=native', + opt = "-O3", + werror = '-Werror' + ), + icc = dict( + native = '-xHost', + opt = '-O3', + werror = '-Werror' + ), + iccw = dict( + native = '/QxHost', + opt = '/O3', + werror = '/Werror' + ), + msvc = dict( + native = None, + opt = '/O2', + werror = '/WX' + ) + ) + conf_min_features = dict( + x86 = "SSE SSE2", + x64 = "SSE SSE2 SSE3", + ppc64 = '', # play it safe + ppc64le = "VSX VSX2", + armhf = '', # play it safe + aarch64 = "NEON NEON_FP16 NEON_VFPV4 ASIMD" + ) + conf_features = dict( + # X86 + SSE = dict( + interest=1, headers="xmmintrin.h", + # enabling SSE without SSE2 is useless also + # it's non-optional for x86_64 + implies="SSE2" + ), + SSE2 = dict(interest=2, implies="SSE", headers="emmintrin.h"), + SSE3 = dict(interest=3, implies="SSE2", headers="pmmintrin.h"), + SSSE3 = dict(interest=4, implies="SSE3", headers="tmmintrin.h"), + SSE41 = dict(interest=5, implies="SSSE3", headers="smmintrin.h"), + POPCNT = dict(interest=6, implies="SSE41", headers="popcntintrin.h"), + SSE42 = dict(interest=7, implies="POPCNT"), + AVX = dict( + interest=8, implies="SSE42", headers="immintrin.h", + implies_detect=False + ), + XOP = dict(interest=9, implies="AVX", headers="x86intrin.h"), + FMA4 = dict(interest=10, implies="AVX", headers="x86intrin.h"), + F16C = dict(interest=11, implies="AVX"), + FMA3 = dict(interest=12, implies="F16C"), + AVX2 = dict(interest=13, implies="F16C"), + AVX512F = dict( + interest=20, implies="FMA3 AVX2", implies_detect=False, + extra_checks="AVX512F_REDUCE" + ), + AVX512CD = dict(interest=21, implies="AVX512F"), + AVX512_KNL = dict( + interest=40, implies="AVX512CD", group="AVX512ER AVX512PF", + detect="AVX512_KNL", implies_detect=False + ), + AVX512_KNM = dict( + interest=41, implies="AVX512_KNL", + group="AVX5124FMAPS AVX5124VNNIW AVX512VPOPCNTDQ", + detect="AVX512_KNM", implies_detect=False + ), + AVX512_SKX = dict( + interest=42, implies="AVX512CD", group="AVX512VL AVX512BW AVX512DQ", + detect="AVX512_SKX", implies_detect=False, + extra_checks="AVX512BW_MASK AVX512DQ_MASK" + ), + AVX512_CLX = dict( + interest=43, implies="AVX512_SKX", group="AVX512VNNI", + detect="AVX512_CLX" + ), + AVX512_CNL = dict( + interest=44, implies="AVX512_SKX", group="AVX512IFMA AVX512VBMI", + detect="AVX512_CNL", implies_detect=False + ), + AVX512_ICL = dict( + interest=45, implies="AVX512_CLX AVX512_CNL", + group="AVX512VBMI2 AVX512BITALG AVX512VPOPCNTDQ", + detect="AVX512_ICL", implies_detect=False + ), + # IBM/Power + ## Power7/ISA 2.06 + VSX = dict(interest=1, headers="altivec.h"), + ## Power8/ISA 2.07 + VSX2 = dict(interest=2, implies="VSX", implies_detect=False), + ## Power9/ISA 3.00 + VSX3 = dict(interest=3, implies="VSX2", implies_detect=False), + # ARM + NEON = dict(interest=1, headers="arm_neon.h"), + NEON_FP16 = dict(interest=2, implies="NEON"), + ## FMA + NEON_VFPV4 = dict(interest=3, implies="NEON_FP16"), + ## Advanced SIMD + ASIMD = dict(interest=4, implies="NEON_FP16 NEON_VFPV4", implies_detect=False), + ## ARMv8.2 half-precision & vector arithm + ASIMDHP = dict(interest=5, implies="ASIMD"), + ## ARMv8.2 dot product + ASIMDDP = dict(interest=6, implies="ASIMD"), + ## ARMv8.2 Single & half-precision Multiply + ASIMDFHM = dict(interest=7, implies="ASIMDHP"), + ) + def conf_features_partial(self): + """Return a dictionary of supported CPU features by the platform, + and accumulate the rest of undefined options in `conf_features`, + the returned dict has same rules and notes in + class attribute `conf_features`, also its override + any options that been set in 'conf_features'. + """ + if self.cc_noopt: + # optimization is disabled + return {} + + on_x86 = self.cc_on_x86 or self.cc_on_x64 + is_unix = self.cc_is_gcc or self.cc_is_clang + + if on_x86 and is_unix: return dict( + SSE = dict(flags="-msse"), + SSE2 = dict(flags="-msse2"), + SSE3 = dict(flags="-msse3"), + SSSE3 = dict(flags="-mssse3"), + SSE41 = dict(flags="-msse4.1"), + POPCNT = dict(flags="-mpopcnt"), + SSE42 = dict(flags="-msse4.2"), + AVX = dict(flags="-mavx"), + F16C = dict(flags="-mf16c"), + XOP = dict(flags="-mxop"), + FMA4 = dict(flags="-mfma4"), + FMA3 = dict(flags="-mfma"), + AVX2 = dict(flags="-mavx2"), + AVX512F = dict(flags="-mavx512f"), + AVX512CD = dict(flags="-mavx512cd"), + AVX512_KNL = dict(flags="-mavx512er -mavx512pf"), + AVX512_KNM = dict( + flags="-mavx5124fmaps -mavx5124vnniw -mavx512vpopcntdq" + ), + AVX512_SKX = dict(flags="-mavx512vl -mavx512bw -mavx512dq"), + AVX512_CLX = dict(flags="-mavx512vnni"), + AVX512_CNL = dict(flags="-mavx512ifma -mavx512vbmi"), + AVX512_ICL = dict( + flags="-mavx512vbmi2 -mavx512bitalg -mavx512vpopcntdq" + ) + ) + if on_x86 and self.cc_is_icc: return dict( + SSE = dict(flags="-msse"), + SSE2 = dict(flags="-msse2"), + SSE3 = dict(flags="-msse3"), + SSSE3 = dict(flags="-mssse3"), + SSE41 = dict(flags="-msse4.1"), + POPCNT = {}, + SSE42 = dict(flags="-msse4.2"), + AVX = dict(flags="-mavx"), + F16C = {}, + XOP = dict(disable="Intel Compiler doesn't support it"), + FMA4 = dict(disable="Intel Compiler doesn't support it"), + # Intel Compiler doesn't support AVX2 or FMA3 independently + FMA3 = dict( + implies="F16C AVX2", flags="-march=core-avx2" + ), + AVX2 = dict(implies="FMA3", flags="-march=core-avx2"), + # Intel Compiler doesn't support AVX512F or AVX512CD independently + AVX512F = dict( + implies="AVX2 AVX512CD", flags="-march=common-avx512" + ), + AVX512CD = dict( + implies="AVX2 AVX512F", flags="-march=common-avx512" + ), + AVX512_KNL = dict(flags="-xKNL"), + AVX512_KNM = dict(flags="-xKNM"), + AVX512_SKX = dict(flags="-xSKYLAKE-AVX512"), + AVX512_CLX = dict(flags="-xCASCADELAKE"), + AVX512_CNL = dict(flags="-xCANNONLAKE"), + AVX512_ICL = dict(flags="-xICELAKE-CLIENT"), + ) + if on_x86 and self.cc_is_iccw: return dict( + SSE = dict(flags="/arch:SSE"), + SSE2 = dict(flags="/arch:SSE2"), + SSE3 = dict(flags="/arch:SSE3"), + SSSE3 = dict(flags="/arch:SSSE3"), + SSE41 = dict(flags="/arch:SSE4.1"), + POPCNT = {}, + SSE42 = dict(flags="/arch:SSE4.2"), + AVX = dict(flags="/arch:AVX"), + F16C = {}, + XOP = dict(disable="Intel Compiler doesn't support it"), + FMA4 = dict(disable="Intel Compiler doesn't support it"), + # Intel Compiler doesn't support FMA3 or AVX2 independently + FMA3 = dict( + implies="F16C AVX2", flags="/arch:CORE-AVX2" + ), + AVX2 = dict( + implies="FMA3", flags="/arch:CORE-AVX2" + ), + # Intel Compiler doesn't support AVX512F or AVX512CD independently + AVX512F = dict( + implies="AVX2 AVX512CD", flags="/Qx:COMMON-AVX512" + ), + AVX512CD = dict( + implies="AVX2 AVX512F", flags="/Qx:COMMON-AVX512" + ), + AVX512_KNL = dict(flags="/Qx:KNL"), + AVX512_KNM = dict(flags="/Qx:KNM"), + AVX512_SKX = dict(flags="/Qx:SKYLAKE-AVX512"), + AVX512_CLX = dict(flags="/Qx:CASCADELAKE"), + AVX512_CNL = dict(flags="/Qx:CANNONLAKE"), + AVX512_ICL = dict(flags="/Qx:ICELAKE-CLIENT") + ) + if on_x86 and self.cc_is_msvc: return dict( + SSE = dict(flags="/arch:SSE"), + SSE2 = dict(flags="/arch:SSE2"), + SSE3 = {}, + SSSE3 = {}, + SSE41 = {}, + POPCNT = dict(headers="nmmintrin.h"), + SSE42 = {}, + AVX = dict(flags="/arch:AVX"), + F16C = {}, + XOP = dict(headers="ammintrin.h"), + FMA4 = dict(headers="ammintrin.h"), + # MSVC doesn't support FMA3 or AVX2 independently + FMA3 = dict( + implies="F16C AVX2", flags="/arch:AVX2" + ), + AVX2 = dict( + implies="F16C FMA3", flags="/arch:AVX2" + ), + # MSVC doesn't support AVX512F or AVX512CD independently, + # always generate instructions belong to (VL/VW/DQ) + AVX512F = dict( + implies="AVX2 AVX512CD AVX512_SKX", flags="/arch:AVX512" + ), + AVX512CD = dict( + implies="AVX512F AVX512_SKX", flags="/arch:AVX512" + ), + AVX512_KNL = dict( + disable="MSVC compiler doesn't support it" + ), + AVX512_KNM = dict( + disable="MSVC compiler doesn't support it" + ), + AVX512_SKX = dict(flags="/arch:AVX512"), + AVX512_CLX = {}, + AVX512_CNL = {}, + AVX512_ICL = {} + ) + + on_power = self.cc_on_ppc64le or self.cc_on_ppc64 + if on_power: + partial = dict( + VSX = dict( + implies=("VSX2" if self.cc_on_ppc64le else ""), + flags="-mvsx" + ), + VSX2 = dict( + flags="-mcpu=power8", implies_detect=False + ), + VSX3 = dict( + flags="-mcpu=power9 -mtune=power9", implies_detect=False + ) + ) + if self.cc_is_clang: + partial["VSX"]["flags"] = "-maltivec -mvsx" + partial["VSX2"]["flags"] = "-mpower8-vector" + partial["VSX3"]["flags"] = "-mpower9-vector" + + return partial + + if self.cc_on_aarch64 and is_unix: return dict( + NEON = dict( + implies="NEON_FP16 NEON_VFPV4 ASIMD", autovec=True + ), + NEON_FP16 = dict( + implies="NEON NEON_VFPV4 ASIMD", autovec=True + ), + NEON_VFPV4 = dict( + implies="NEON NEON_FP16 ASIMD", autovec=True + ), + ASIMD = dict( + implies="NEON NEON_FP16 NEON_VFPV4", autovec=True + ), + ASIMDHP = dict( + flags="-march=armv8.2-a+fp16" + ), + ASIMDDP = dict( + flags="-march=armv8.2-a+dotprod" + ), + ASIMDFHM = dict( + flags="-march=armv8.2-a+fp16fml" + ), + ) + if self.cc_on_armhf and is_unix: return dict( + NEON = dict( + flags="-mfpu=neon" + ), + NEON_FP16 = dict( + flags="-mfpu=neon-fp16 -mfp16-format=ieee" + ), + NEON_VFPV4 = dict( + flags="-mfpu=neon-vfpv4", + ), + ASIMD = dict( + flags="-mfpu=neon-fp-armv8 -march=armv8-a+simd", + ), + ASIMDHP = dict( + flags="-march=armv8.2-a+fp16" + ), + ASIMDDP = dict( + flags="-march=armv8.2-a+dotprod", + ), + ASIMDFHM = dict( + flags="-march=armv8.2-a+fp16fml" + ) + ) + # TODO: ARM MSVC + return {} + + def __init__(self): + if self.conf_tmp_path is None: + import tempfile, shutil + tmp = tempfile.mkdtemp() + def rm_temp(): + try: + shutil.rmtree(tmp) + except IOError: + pass + atexit.register(rm_temp) + self.conf_tmp_path = tmp + + if self.conf_cache_factors is None: + self.conf_cache_factors = [ + os.path.getmtime(__file__), + self.conf_nocache + ] + +class _Distutils: + """A helper class that provides a collection of fundamental methods + implemented in a top of Python and NumPy Distutils. + + The idea behind this class is to gather all methods that it may + need to override in case of reuse 'CCompilerOpt' in environment + different than of what NumPy has. + + Parameters + ---------- + ccompiler : `CCompiler` + The generate instance that returned from `distutils.ccompiler.new_compiler()`. + """ + def __init__(self, ccompiler): + self._ccompiler = ccompiler + + def dist_compile(self, sources, flags, **kwargs): + """Wrap CCompiler.compile()""" + assert(isinstance(sources, list)) + assert(isinstance(flags, list)) + flags = kwargs.pop("extra_postargs", []) + flags + return self._ccompiler.compile( + sources, extra_postargs=flags, **kwargs + ) + + def dist_test(self, source, flags): + """Return True if 'CCompiler.compile()' able to compile + a source file with certain flags. + """ + assert(isinstance(source, str)) + from distutils.errors import CompileError + cc = self._ccompiler; + bk_spawn = getattr(cc, 'spawn', None) + if bk_spawn: + cc_type = getattr(self._ccompiler, "compiler_type", "") + if cc_type in ("msvc",): + setattr(cc, 'spawn', self._dist_test_spawn_paths) + else: + setattr(cc, 'spawn', self._dist_test_spawn) + test = False + try: + self.dist_compile( + [source], flags, output_dir=self.conf_tmp_path + ) + test = True + except CompileError as e: + self.dist_log(str(e), stderr=True) + if bk_spawn: + setattr(cc, 'spawn', bk_spawn) + return test + + def dist_info(self): + """ + Return a tuple containing info about (platform, compiler, extra_args), + required by the abstract class '_CCompiler' for discovering the + platform environment. This is also used as a cache factor in order + to detect any changes happening from outside. + """ + if hasattr(self, "_dist_info"): + return self._dist_info + + cc_type = getattr(self._ccompiler, "compiler_type", '') + if cc_type in ("intelem", "intelemw"): + platform = "x86_64" + elif cc_type in ("intel", "intelw", "intele"): + platform = "x86" + else: + from distutils.util import get_platform + platform = get_platform() + + cc_info = getattr(self._ccompiler, "compiler", getattr(self._ccompiler, "compiler_so", '')) + if not cc_type or cc_type == "unix": + if hasattr(cc_info, "__iter__"): + compiler = cc_info[0] + else: + compiler = str(cc_info) + else: + compiler = cc_type + + if hasattr(cc_info, "__iter__") and len(cc_info) > 1: + extra_args = ' '.join(cc_info[1:]) + else: + extra_args = os.environ.get("CFLAGS", "") + extra_args += os.environ.get("CPPFLAGS", "") + + self._dist_info = (platform, compiler, extra_args) + return self._dist_info + + @staticmethod + def dist_error(*args): + """Raise a compiler error""" + from distutils.errors import CompileError + raise CompileError(_Distutils._dist_str(*args)) + + @staticmethod + def dist_fatal(*args): + """Raise a distutils error""" + from distutils.errors import DistutilsError + raise DistutilsError(_Distutils._dist_str(*args)) + + @staticmethod + def dist_log(*args, stderr=False): + """Print a console message""" + from numpy.distutils import log + out = _Distutils._dist_str(*args) + if stderr: + log.warn(out) + else: + log.info(out) + + @staticmethod + def dist_load_module(name, path): + """Load a module from file, required by the abstract class '_Cache'.""" + from numpy.compat import npy_load_module + try: + return npy_load_module(name, path) + except Exception as e: + _Distutils.dist_log(e, stderr=True) + return None + + @staticmethod + def _dist_str(*args): + """Return a string to print by log and errors.""" + def to_str(arg): + if not isinstance(arg, str) and hasattr(arg, '__iter__'): + ret = [] + for a in arg: + ret.append(to_str(a)) + return '('+ ' '.join(ret) + ')' + return str(arg) + + stack = inspect.stack()[2] + start = "CCompilerOpt.%s[%d] : " % (stack.function, stack.lineno) + out = ' '.join([ + to_str(a) + for a in (*args,) + ]) + return start + out + + def _dist_test_spawn_paths(self, cmd, display=None): + """ + Fix msvc SDK ENV path same as distutils do + without it we get c1: fatal error C1356: unable to find mspdbcore.dll + """ + if not hasattr(self._ccompiler, "_paths"): + self._dist_test_spawn(cmd) + return + old_path = os.getenv("path") + try: + os.environ["path"] = self._ccompiler._paths + self._dist_test_spawn(cmd) + finally: + os.environ["path"] = old_path + + _dist_warn_regex = re.compile( + # intel and msvc compilers don't raise + # fatal errors when flags are wrong or unsupported + ".*(" + "warning D9002|" # msvc, it should be work with any language. + "invalid argument for option" # intel + ").*" + ) + @staticmethod + def _dist_test_spawn(cmd, display=None): + from distutils.errors import CompileError + try: + o = subprocess.check_output(cmd, stderr=subprocess.STDOUT, + universal_newlines=True) + if o and re.match(_Distutils._dist_warn_regex, o): + _Distutils.dist_error( + "Flags in command", cmd ,"aren't supported by the compiler" + ", output -> \n%s" % o + ) + except subprocess.CalledProcessError as exc: + o = exc.output + s = exc.returncode + except OSError: + o = b'' + s = 127 + else: + return None + _Distutils.dist_error( + "Command", cmd, "failed with exit status %d output -> \n%s" % ( + s, o + )) + +_share_cache = {} +class _Cache: + """An abstract class handles caching functionality, provides two + levels of caching, in-memory by share instances attributes among + each other and by store attributes into files. + + **Note**: + any attributes that start with ``_`` or ``conf_`` will be ignored. + + Parameters + ---------- + cache_path: str or None + The path of cache file, if None then cache in file will disabled. + + *factors: + The caching factors that need to utilize next to `conf_cache_factors`. + + Attributes + ---------- + cache_private: set + Hold the attributes that need be skipped from "in-memory cache". + + cache_infile: bool + Utilized during initializing this class, to determine if the cache was able + to loaded from the specified cache path in 'cache_path'. + """ + + # skip attributes from cache + _cache_ignore = re.compile("^(_|conf_)") + + def __init__(self, cache_path=None, *factors): + self.cache_me = {} + self.cache_private = set() + self.cache_infile = False + + if self.conf_nocache: + self.dist_log("cache is disabled by `Config`") + return + + chash = self.cache_hash(*factors, *self.conf_cache_factors) + if cache_path: + if os.path.exists(cache_path): + self.dist_log("load cache from file ->", cache_path) + cache_mod = self.dist_load_module("cache", cache_path) + if not cache_mod: + self.dist_log( + "unable to load the cache file as a module", + stderr=True + ) + elif not hasattr(cache_mod, "hash") or \ + not hasattr(cache_mod, "data"): + self.dist_log("invalid cache file", stderr=True) + elif chash == cache_mod.hash: + self.dist_log("hit the file cache") + for attr, val in cache_mod.data.items(): + setattr(self, attr, val) + self.cache_infile = True + else: + self.dist_log("miss the file cache") + + atexit.register(self._cache_write, cache_path, chash) + + if not self.cache_infile: + other_cache = _share_cache.get(chash) + if other_cache: + self.dist_log("hit the memory cache") + for attr, val in other_cache.__dict__.items(): + if attr in other_cache.cache_private or \ + re.match(self._cache_ignore, attr): + continue + setattr(self, attr, val) + + _share_cache[chash] = self + + def __del__(self): + # TODO: remove the cache form share on del + pass + + def _cache_write(self, cache_path, cache_hash): + # TODO: don't write if the cache doesn't change + self.dist_log("write cache to path ->", cache_path) + for attr in list(self.__dict__.keys()): + if re.match(self._cache_ignore, attr): + self.__dict__.pop(attr) + + d = os.path.dirname(cache_path) + if not os.path.exists(d): + os.makedirs(d) + + repr_dict = pprint.pformat(self.__dict__, compact=True) + with open(cache_path, "w") as f: + f.write(textwrap.dedent("""\ + # AUTOGENERATED DON'T EDIT + # Please make changes to the code generator \ + (distutils/ccompiler_opt.py) + hash = {} + data = \\ + """).format(cache_hash)) + f.write(repr_dict) + + def cache_hash(self, *factors): + # is there a built-in non-crypto hash? + # sdbm + chash = 0 + for f in factors: + for char in str(f): + chash = ord(char) + (chash << 6) + (chash << 16) - chash + chash &= 0xFFFFFFFF + return chash + + @staticmethod + def me(cb): + """ + A static method that can be treated as a decorator to + dynamically cache certain methods. + """ + def cache_wrap_me(self, *args, **kwargs): + # good for normal args + cache_key = str(( + cb.__name__, *args, *kwargs.keys(), *kwargs.values() + )) + if cache_key in self.cache_me: + return self.cache_me[cache_key] + ccb = cb(self, *args, **kwargs) + self.cache_me[cache_key] = ccb + return ccb + return cache_wrap_me + +class _CCompiler(object): + """A helper class for `CCompilerOpt` containing all utilities that + related to the fundamental compiler's functions. + + Attributes + ---------- + cc_on_x86 : bool + True when the target architecture is 32-bit x86 + cc_on_x64 : bool + True when the target architecture is 64-bit x86 + cc_on_ppc64 : bool + True when the target architecture is 64-bit big-endian PowerPC + cc_on_armhf : bool + True when the target architecture is 32-bit ARMv7+ + cc_on_aarch64 : bool + True when the target architecture is 64-bit Armv8-a+ + cc_on_noarch : bool + True when the target architecture is unknown or not supported + cc_is_gcc : bool + True if the compiler is GNU or + if the compiler is unknown + cc_is_clang : bool + True if the compiler is Clang + cc_is_icc : bool + True if the compiler is Intel compiler (unix like) + cc_is_iccw : bool + True if the compiler is Intel compiler (msvc like) + cc_is_nocc : bool + True if the compiler isn't supported directly, + Note: that cause a fail-back to gcc + cc_has_debug : bool + True if the compiler has debug flags + cc_has_native : bool + True if the compiler has native flags + cc_noopt : bool + True if the compiler has definition 'DISABLE_OPT*', + or 'cc_on_noarch' is True + cc_march : str + The target architecture name, or "unknown" if + the architecture isn't supported + cc_name : str + The compiler name, or "unknown" if the compiler isn't supported + cc_flags : dict + Dictionary containing the initialized flags of `_Config.conf_cc_flags` + """ + def __init__(self): + if hasattr(self, "cc_is_cached"): + return + # attr regex + detect_arch = ( + ("cc_on_x64", ".*(x|x86_|amd)64.*"), + ("cc_on_x86", ".*(win32|x86|i386|i686).*"), + ("cc_on_ppc64le", ".*(powerpc|ppc)64(el|le).*"), + ("cc_on_ppc64", ".*(powerpc|ppc)64.*"), + ("cc_on_aarch64", ".*(aarch64|arm64).*"), + ("cc_on_armhf", ".*arm.*"), + # undefined platform + ("cc_on_noarch", ""), + ) + detect_compiler = ( + ("cc_is_gcc", r".*(gcc|gnu\-g).*"), + ("cc_is_clang", ".*clang.*"), + ("cc_is_iccw", ".*(intelw|intelemw|iccw).*"), # intel msvc like + ("cc_is_icc", ".*(intel|icc).*"), # intel unix like + ("cc_is_msvc", ".*msvc.*"), + # undefined compiler will be treat it as gcc + ("cc_is_nocc", ""), + ) + detect_args = ( + ("cc_has_debug", ".*(O0|Od|ggdb|coverage|debug:full).*"), + ("cc_has_native", ".*(-march=native|-xHost|/QxHost).*"), + # in case if the class run with -DNPY_DISABLE_OPTIMIZATION + ("cc_noopt", ".*DISABLE_OPT.*"), + ) + + dist_info = self.dist_info() + platform, compiler_info, extra_args = dist_info + # set False to all attrs + for section in (detect_arch, detect_compiler, detect_args): + for attr, rgex in section: + setattr(self, attr, False) + + for detect, searchin in ((detect_arch, platform), (detect_compiler, compiler_info)): + for attr, rgex in detect: + if rgex and not re.match(rgex, searchin, re.IGNORECASE): + continue + setattr(self, attr, True) + break + + for attr, rgex in detect_args: + if rgex and not re.match(rgex, extra_args, re.IGNORECASE): + continue + setattr(self, attr, True) + + if self.cc_on_noarch: + self.dist_log( + "unable to detect CPU architecture which lead to disable the optimization. " + f"check dist_info:<<\n{dist_info}\n>>", + stderr=True + ) + self.cc_noopt = True + + if self.conf_noopt: + self.dist_log("Optimization is disabled by the Config", stderr=True) + self.cc_noopt = True + + if self.cc_is_nocc: + """ + mingw can be treated as a gcc, and also xlc even if it based on clang, + but still has the same gcc optimization flags. + """ + self.dist_log( + "unable to detect compiler type which leads to treating it as GCC. " + "this is a normal behavior if you're using gcc-like compiler such as MinGW or IBM/XLC." + f"check dist_info:<<\n{dist_info}\n>>", + stderr=True + ) + self.cc_is_gcc = True + + self.cc_march = "unknown" + for arch in ("x86", "x64", "ppc64", "ppc64le", "armhf", "aarch64"): + if getattr(self, "cc_on_" + arch): + self.cc_march = arch + break + + self.cc_name = "unknown" + for name in ("gcc", "clang", "iccw", "icc", "msvc"): + if getattr(self, "cc_is_" + name): + self.cc_name = name + break + + self.cc_flags = {} + compiler_flags = self.conf_cc_flags.get(self.cc_name) + if compiler_flags is None: + self.dist_fatal( + "undefined flag for compiler '%s', " + "leave an empty dict instead" % self.cc_name + ) + for name, flags in compiler_flags.items(): + self.cc_flags[name] = nflags = [] + if flags: + assert(isinstance(flags, str)) + flags = flags.split() + for f in flags: + if self.cc_test_flags([f]): + nflags.append(f) + + self.cc_is_cached = True + + @_Cache.me + def cc_test_flags(self, flags): + """ + Returns True if the compiler supports 'flags'. + """ + assert(isinstance(flags, list)) + self.dist_log("testing flags", flags) + test_path = os.path.join(self.conf_check_path, "test_flags.c") + test = self.dist_test(test_path, flags) + if not test: + self.dist_log("testing failed", stderr=True) + return test + + def cc_normalize_flags(self, flags): + """ + Remove the conflicts that caused due gathering implied features flags. + + Parameters + ---------- + 'flags' list, compiler flags + flags should be sorted from the lowest to the highest interest. + + Returns + ------- + list, filtered from any conflicts. + + Examples + -------- + >>> self.cc_normalize_flags(['-march=armv8.2-a+fp16', '-march=armv8.2-a+dotprod']) + ['armv8.2-a+fp16+dotprod'] + + >>> self.cc_normalize_flags( + ['-msse', '-msse2', '-msse3', '-mssse3', '-msse4.1', '-msse4.2', '-mavx', '-march=core-avx2'] + ) + ['-march=core-avx2'] + """ + assert(isinstance(flags, list)) + if self.cc_is_gcc or self.cc_is_clang or self.cc_is_icc: + return self._cc_normalize_unix(flags) + + if self.cc_is_msvc or self.cc_is_iccw: + return self._cc_normalize_win(flags) + return flags + + _cc_normalize_unix_mrgx = re.compile( + # 1- to check the highest of + r"^(-mcpu=|-march=|-x[A-Z0-9\-])" + ) + _cc_normalize_unix_frgx = re.compile( + # 2- to remove any flags starts with + # -march, -mcpu, -x(INTEL) and '-m' without '=' + r"^(?!(-mcpu=|-march=|-x[A-Z0-9\-]))(?!-m[a-z0-9\-\.]*.$)" + ) + _cc_normalize_unix_krgx = re.compile( + # 3- keep only the highest of + r"^(-mfpu|-mtune)" + ) + _cc_normalize_arch_ver = re.compile( + r"[0-9.]" + ) + def _cc_normalize_unix(self, flags): + def ver_flags(f): + # arch ver subflag + # -march=armv8.2-a+fp16fml + tokens = f.split('+') + ver = float('0' + ''.join( + re.findall(self._cc_normalize_arch_ver, tokens[0]) + )) + return ver, tokens[0], tokens[1:] + + if len(flags) <= 1: + return flags + # get the highest matched flag + for i, cur_flag in enumerate(reversed(flags)): + if not re.match(self._cc_normalize_unix_mrgx, cur_flag): + continue + lower_flags = flags[:-(i+1)] + upper_flags = flags[-i:] + filterd = list(filter( + self._cc_normalize_unix_frgx.search, lower_flags + )) + # gather subflags + ver, arch, subflags = ver_flags(cur_flag) + if ver > 0 and len(subflags) > 0: + for xflag in lower_flags: + xver, _, xsubflags = ver_flags(xflag) + if ver == xver: + subflags = xsubflags + subflags + cur_flag = arch + '+' + '+'.join(subflags) + + flags = filterd + [cur_flag] + if i > 0: + flags += upper_flags + break + + # to remove overridable flags + final_flags = [] + matched = set() + for f in reversed(flags): + match = re.match(self._cc_normalize_unix_krgx, f) + if not match: + pass + elif match[0] in matched: + continue + else: + matched.add(match[0]) + final_flags.insert(0, f) + return final_flags + + _cc_normalize_win_frgx = re.compile( + r"^(?!(/arch\:|/Qx\:))" + ) + _cc_normalize_win_mrgx = re.compile( + r"^(/arch|/Qx:)" + ) + def _cc_normalize_win(self, flags): + for i, f in enumerate(reversed(flags)): + if not re.match(self._cc_normalize_win_mrgx, f): + continue + i += 1 + return list(filter( + self._cc_normalize_win_frgx.search, flags[:-i] + )) + flags[-i:] + return flags + +class _Feature: + """A helper class for `CCompilerOpt` that managing CPU features. + + Attributes + ---------- + feature_supported : dict + Dictionary containing all CPU features that supported + by the platform, according to the specified values in attribute + `_Config.conf_features` and `_Config.conf_features_partial()` + + feature_min : set + The minimum support of CPU features, according to + the specified values in attribute `_Config.conf_min_features`. + """ + def __init__(self): + if hasattr(self, "feature_is_cached"): + return + self.feature_supported = pfeatures = self.conf_features_partial() + for feature_name in list(pfeatures.keys()): + feature = pfeatures[feature_name] + cfeature = self.conf_features[feature_name] + feature.update({ + k:v for k,v in cfeature.items() if k not in feature + }) + disabled = feature.get("disable") + if disabled is not None: + pfeatures.pop(feature_name) + self.dist_log( + "feature '%s' is disabled," % feature_name, + disabled, stderr=True + ) + continue + # list is used internally for these options + for option in ( + "implies", "group", "detect", "headers", "flags", "extra_checks" + ) : + oval = feature.get(option) + if isinstance(oval, str): + feature[option] = oval.split() + + self.feature_min = set() + min_f = self.conf_min_features.get(self.cc_march, "") + for F in min_f.upper().split(): + if F in self.feature_supported: + self.feature_min.add(F) + + self.feature_is_cached = True + + def feature_names(self, names=None, force_flags=None): + """ + Returns a set of CPU feature names that supported by platform and the **C** compiler. + + Parameters + ---------- + 'names': sequence or None, optional + Specify certain CPU features to test it against the **C** compiler. + if None(default), it will test all current supported features. + **Note**: feature names must be in upper-case. + + 'force_flags': list or None, optional + If None(default), default compiler flags for every CPU feature will be used + during the test. + """ + assert( + names is None or ( + not isinstance(names, str) and + hasattr(names, "__iter__") + ) + ) + assert(force_flags is None or isinstance(force_flags, list)) + if names is None: + names = self.feature_supported.keys() + supported_names = set() + for f in names: + if self.feature_is_supported(f, force_flags=force_flags): + supported_names.add(f) + return supported_names + + def feature_is_exist(self, name): + """ + Returns True if a certain feature is exist and covered within + `_Config.conf_features`. + + Parameters + ---------- + 'name': str + feature name in uppercase. + """ + assert(name.isupper()) + return name in self.conf_features + + def feature_sorted(self, names, reverse=False): + """ + Sort a list of CPU features ordered by the lowest interest. + + Parameters + ---------- + 'names': sequence + sequence of supported feature names in uppercase. + 'reverse': bool, optional + If true, the sorted features is reversed. (highest interest) + + Returns + ------- + list, sorted CPU features + """ + def sort_cb(k): + if isinstance(k, str): + return self.feature_supported[k]["interest"] + # multiple features + rank = max([self.feature_supported[f]["interest"] for f in k]) + # FIXME: that's not a safe way to increase the rank for + # multi targets + rank += len(k) -1 + return rank + return sorted(names, reverse=reverse, key=sort_cb) + + def feature_implies(self, names, keep_origins=False): + """ + Return a set of CPU features that implied by 'names' + + Parameters + ---------- + names: str or sequence of str + CPU feature name(s) in uppercase. + + keep_origins: bool + if False(default) then the returned set will not contain any + features from 'names'. This case happens only when two features + imply each other. + + Examples + -------- + >>> self.feature_implies("SSE3") + {'SSE', 'SSE2'} + >>> self.feature_implies("SSE2") + {'SSE'} + >>> self.feature_implies("SSE2", keep_origins=True) + # 'SSE2' found here since 'SSE' and 'SSE2' imply each other + {'SSE', 'SSE2'} + """ + def get_implies(name, _caller=set()): + implies = set() + d = self.feature_supported[name] + for i in d.get("implies", []): + implies.add(i) + if i in _caller: + # infinity recursive guard since + # features can imply each other + continue + _caller.add(name) + implies = implies.union(get_implies(i, _caller)) + return implies + + if isinstance(names, str): + implies = get_implies(names) + names = [names] + else: + assert(hasattr(names, "__iter__")) + implies = set() + for n in names: + implies = implies.union(get_implies(n)) + if not keep_origins: + implies.difference_update(names) + return implies + + def feature_implies_c(self, names): + """same as feature_implies() but combining 'names'""" + if isinstance(names, str): + names = set((names,)) + else: + names = set(names) + return names.union(self.feature_implies(names)) + + def feature_ahead(self, names): + """ + Return list of features in 'names' after remove any + implied features and keep the origins. + + Parameters + ---------- + 'names': sequence + sequence of CPU feature names in uppercase. + + Returns + ------- + list of CPU features sorted as-is 'names' + + Examples + -------- + >>> self.feature_ahead(["SSE2", "SSE3", "SSE41"]) + ["SSE41"] + # assume AVX2 and FMA3 implies each other and AVX2 + # is the highest interest + >>> self.feature_ahead(["SSE2", "SSE3", "SSE41", "AVX2", "FMA3"]) + ["AVX2"] + # assume AVX2 and FMA3 don't implies each other + >>> self.feature_ahead(["SSE2", "SSE3", "SSE41", "AVX2", "FMA3"]) + ["AVX2", "FMA3"] + """ + assert( + not isinstance(names, str) + and hasattr(names, '__iter__') + ) + implies = self.feature_implies(names, keep_origins=True) + ahead = [n for n in names if n not in implies] + if len(ahead) == 0: + # return the highest interested feature + # if all features imply each other + ahead = self.feature_sorted(names, reverse=True)[:1] + return ahead + + def feature_untied(self, names): + """ + same as 'feature_ahead()' but if both features implied each other + and keep the highest interest. + + Parameters + ---------- + 'names': sequence + sequence of CPU feature names in uppercase. + + Returns + ------- + list of CPU features sorted as-is 'names' + + Examples + -------- + >>> self.feature_untied(["SSE2", "SSE3", "SSE41"]) + ["SSE2", "SSE3", "SSE41"] + # assume AVX2 and FMA3 implies each other + >>> self.feature_untied(["SSE2", "SSE3", "SSE41", "FMA3", "AVX2"]) + ["SSE2", "SSE3", "SSE41", "AVX2"] + """ + assert( + not isinstance(names, str) + and hasattr(names, '__iter__') + ) + final = [] + for n in names: + implies = self.feature_implies(n) + tied = [ + nn for nn in final + if nn in implies and n in self.feature_implies(nn) + ] + if tied: + tied = self.feature_sorted(tied + [n]) + if n not in tied[1:]: + continue + final.remove(tied[:1][0]) + final.append(n) + return final + + def feature_get_til(self, names, keyisfalse): + """ + same as `feature_implies_c()` but stop collecting implied + features when feature's option that provided through + parameter 'keyisfalse' is False, also sorting the returned + features. + """ + def til(tnames): + # sort from highest to lowest interest then cut if "key" is False + tnames = self.feature_implies_c(tnames) + tnames = self.feature_sorted(tnames, reverse=True) + for i, n in enumerate(tnames): + if not self.feature_supported[n].get(keyisfalse, True): + tnames = tnames[:i+1] + break + return tnames + + if isinstance(names, str) or len(names) <= 1: + names = til(names) + # normalize the sort + names.reverse() + return names + + names = self.feature_ahead(names) + names = {t for n in names for t in til(n)} + return self.feature_sorted(names) + + def feature_detect(self, names): + """ + Return a list of CPU features that required to be detected + sorted from the lowest to highest interest. + """ + names = self.feature_get_til(names, "implies_detect") + detect = [] + for n in names: + d = self.feature_supported[n] + detect += d.get("detect", d.get("group", [n])) + return detect + + @_Cache.me + def feature_flags(self, names): + """ + Return a list of CPU features flags sorted from the lowest + to highest interest. + """ + names = self.feature_sorted(self.feature_implies_c(names)) + flags = [] + for n in names: + d = self.feature_supported[n] + f = d.get("flags", []) + if not f or not self.cc_test_flags(f): + continue + flags += f + return self.cc_normalize_flags(flags) + + @_Cache.me + def feature_test(self, name, force_flags=None): + """ + Test a certain CPU feature against the compiler through its own + check file. + + Parameters + ---------- + 'name': str + Supported CPU feature name. + + 'force_flags': list or None, optional + If None(default), the returned flags from `feature_flags()` + will be used. + """ + if force_flags is None: + force_flags = self.feature_flags(name) + + self.dist_log( + "testing feature '%s' with flags (%s)" % ( + name, ' '.join(force_flags) + )) + # Each CPU feature must have C source code contains at + # least one intrinsic or instruction related to this feature. + test_path = os.path.join( + self.conf_check_path, "cpu_%s.c" % name.lower() + ) + if not os.path.exists(test_path): + self.dist_fatal("feature test file is not exist", test_path) + + test = self.dist_test(test_path, force_flags + self.cc_flags["werror"]) + if not test: + self.dist_log("testing failed", stderr=True) + return test + + @_Cache.me + def feature_is_supported(self, name, force_flags=None): + """ + Check if a certain CPU feature is supported by the platform and compiler. + + Parameters + ---------- + 'name': str + CPU feature name in uppercase. + + 'force_flags': list or None, optional + If None(default), default compiler flags for every CPU feature will be used + during test. + """ + assert(name.isupper()) + assert(force_flags is None or isinstance(force_flags, list)) + + supported = name in self.feature_supported + if supported: + for impl in self.feature_implies(name): + if not self.feature_test(impl, force_flags): + return False + if not self.feature_test(name, force_flags): + return False + return supported + + @_Cache.me + def feature_can_autovec(self, name): + """ + check if the feature can be auto-vectorized by the compiler + """ + assert(isinstance(name, str)) + d = self.feature_supported[name] + can = d.get("autovec", None) + if can is None: + valid_flags = [ + self.cc_test_flags([f]) for f in d.get("flags", []) + ] + can = valid_flags and any(valid_flags) + return can + + @_Cache.me + def feature_extra_checks(self, name): + """ + Return a list of supported extra checks after testing them against + the compiler. + + Parameters + ---------- + names: str + CPU feature name in uppercase. + """ + assert isinstance(name, str) + d = self.feature_supported[name] + extra_checks = d.get("extra_checks", []) + if not extra_checks: + return [] + + self.dist_log("Testing extra checks for feature '%s'" % name, extra_checks) + flags = self.feature_flags(name) + available = [] + not_available = [] + for chk in extra_checks: + test_path = os.path.join( + self.conf_check_path, "extra_%s.c" % chk.lower() + ) + if not os.path.exists(test_path): + self.dist_fatal("extra check file does not exist", test_path) + + is_supported = self.dist_test(test_path, flags + self.cc_flags["werror"]) + if is_supported: + available.append(chk) + else: + not_available.append(chk) + + if not_available: + self.dist_log("testing failed for checks", not_available, stderr=True) + return available + + + def feature_c_preprocessor(self, feature_name, tabs=0): + """ + Generate C preprocessor definitions and include headers of a CPU feature. + + Parameters + ---------- + 'feature_name': str + CPU feature name in uppercase. + 'tabs': int + if > 0, align the generated strings to the right depend on number of tabs. + + Returns + ------- + str, generated C preprocessor + + Examples + -------- + >>> self.feature_c_preprocessor("SSE3") + /** SSE3 **/ + #define NPY_HAVE_SSE3 1 + #include + """ + assert(feature_name.isupper()) + feature = self.feature_supported.get(feature_name) + assert(feature is not None) + + prepr = [ + "/** %s **/" % feature_name, + "#define %sHAVE_%s 1" % (self.conf_c_prefix, feature_name) + ] + prepr += [ + "#include <%s>" % h for h in feature.get("headers", []) + ] + + extra_defs = feature.get("group", []) + extra_defs += self.feature_extra_checks(feature_name) + for edef in extra_defs: + # Guard extra definitions in case of duplicate with + # another feature + prepr += [ + "#ifndef %sHAVE_%s" % (self.conf_c_prefix, edef), + "\t#define %sHAVE_%s 1" % (self.conf_c_prefix, edef), + "#endif", + ] + + if tabs > 0: + prepr = [('\t'*tabs) + l for l in prepr] + return '\n'.join(prepr) + +class _Parse: + """A helper class that parsing main arguments of `CCompilerOpt`, + also parsing configuration statements in dispatch-able sources. + + Parameters + ---------- + cpu_baseline: str or None + minimal set of required CPU features or special options. + + cpu_dispatch: str or None + dispatched set of additional CPU features or special options. + + Special options can be: + - **MIN**: Enables the minimum CPU features that utilized via `_Config.conf_min_features` + - **MAX**: Enables all supported CPU features by the Compiler and platform. + - **NATIVE**: Enables all CPU features that supported by the current machine. + - **NONE**: Enables nothing + - **Operand +/-**: remove or add features, useful with options **MAX**, **MIN** and **NATIVE**. + NOTE: operand + is only added for nominal reason. + + NOTES: + - Case-insensitive among all CPU features and special options. + - Comma or space can be used as a separator. + - If the CPU feature is not supported by the user platform or compiler, + it will be skipped rather than raising a fatal error. + - Any specified CPU features to 'cpu_dispatch' will be skipped if its part of CPU baseline features + - 'cpu_baseline' force enables implied features. + + Attributes + ---------- + parse_baseline_names : list + Final CPU baseline's feature names(sorted from low to high) + parse_baseline_flags : list + Compiler flags of baseline features + parse_dispatch_names : list + Final CPU dispatch-able feature names(sorted from low to high) + parse_target_groups : dict + Dictionary containing initialized target groups that configured + through class attribute `conf_target_groups`. + + The key is represent the group name and value is a tuple + contains three items : + - bool, True if group has the 'baseline' option. + - list, list of CPU features. + - list, list of extra compiler flags. + + """ + def __init__(self, cpu_baseline, cpu_dispatch): + self._parse_policies = dict( + # POLICY NAME, (HAVE, NOT HAVE, [DEB]) + KEEP_BASELINE = ( + None, self._parse_policy_not_keepbase, + [] + ), + KEEP_SORT = ( + self._parse_policy_keepsort, + self._parse_policy_not_keepsort, + [] + ), + MAXOPT = ( + self._parse_policy_maxopt, None, + [] + ), + WERROR = ( + self._parse_policy_werror, None, + [] + ), + AUTOVEC = ( + self._parse_policy_autovec, None, + ["MAXOPT"] + ) + ) + if hasattr(self, "parse_is_cached"): + return + + self.parse_baseline_names = [] + self.parse_baseline_flags = [] + self.parse_dispatch_names = [] + self.parse_target_groups = {} + + if self.cc_noopt: + # skip parsing baseline and dispatch args and keep parsing target groups + cpu_baseline = cpu_dispatch = None + + self.dist_log("check requested baseline") + if cpu_baseline is not None: + cpu_baseline = self._parse_arg_features("cpu_baseline", cpu_baseline) + baseline_names = self.feature_names(cpu_baseline) + self.parse_baseline_flags = self.feature_flags(baseline_names) + self.parse_baseline_names = self.feature_sorted( + self.feature_implies_c(baseline_names) + ) + + self.dist_log("check requested dispatch-able features") + if cpu_dispatch is not None: + cpu_dispatch_ = self._parse_arg_features("cpu_dispatch", cpu_dispatch) + cpu_dispatch = { + f for f in cpu_dispatch_ + if f not in self.parse_baseline_names + } + conflict_baseline = cpu_dispatch_.difference(cpu_dispatch) + self.parse_dispatch_names = self.feature_sorted( + self.feature_names(cpu_dispatch) + ) + if len(conflict_baseline) > 0: + self.dist_log( + "skip features", conflict_baseline, "since its part of baseline" + ) + + self.dist_log("initialize targets groups") + for group_name, tokens in self.conf_target_groups.items(): + self.dist_log("parse target group", group_name) + GROUP_NAME = group_name.upper() + if not tokens or not tokens.strip(): + # allow empty groups, useful in case if there's a need + # to disable certain group since '_parse_target_tokens()' + # requires at least one valid target + self.parse_target_groups[GROUP_NAME] = ( + False, [], [] + ) + continue + has_baseline, features, extra_flags = \ + self._parse_target_tokens(tokens) + self.parse_target_groups[GROUP_NAME] = ( + has_baseline, features, extra_flags + ) + + self.parse_is_cached = True + + def parse_targets(self, source): + """ + Fetch and parse configuration statements that required for + defining the targeted CPU features, statements should be declared + in the top of source in between **C** comment and start + with a special mark **@targets**. + + Configuration statements are sort of keywords representing + CPU features names, group of statements and policies, combined + together to determine the required optimization. + + Parameters + ---------- + source: str + the path of **C** source file. + + Returns + ------- + - bool, True if group has the 'baseline' option + - list, list of CPU features + - list, list of extra compiler flags + """ + self.dist_log("looking for '@targets' inside -> ", source) + # get lines between /*@targets and */ + with open(source) as fd: + tokens = "" + max_to_reach = 1000 # good enough, isn't? + start_with = "@targets" + start_pos = -1 + end_with = "*/" + end_pos = -1 + for current_line, line in enumerate(fd): + if current_line == max_to_reach: + self.dist_fatal("reached the max of lines") + break + if start_pos == -1: + start_pos = line.find(start_with) + if start_pos == -1: + continue + start_pos += len(start_with) + tokens += line + end_pos = line.find(end_with) + if end_pos != -1: + end_pos += len(tokens) - len(line) + break + + if start_pos == -1: + self.dist_fatal("expected to find '%s' within a C comment" % start_with) + if end_pos == -1: + self.dist_fatal("expected to end with '%s'" % end_with) + + tokens = tokens[start_pos:end_pos] + return self._parse_target_tokens(tokens) + + _parse_regex_arg = re.compile(r'\s|[,]|([+-])') + def _parse_arg_features(self, arg_name, req_features): + if not isinstance(req_features, str): + self.dist_fatal("expected a string in '%s'" % arg_name) + + final_features = set() + # space and comma can be used as a separator + tokens = list(filter(None, re.split(self._parse_regex_arg, req_features))) + append = True # append is the default + for tok in tokens: + if tok[0] in ("#", "$"): + self.dist_fatal( + arg_name, "target groups and policies " + "aren't allowed from arguments, " + "only from dispatch-able sources" + ) + if tok == '+': + append = True + continue + if tok == '-': + append = False + continue + + TOK = tok.upper() # we use upper-case internally + features_to = set() + if TOK == "NONE": + pass + elif TOK == "NATIVE": + native = self.cc_flags["native"] + if not native: + self.dist_fatal(arg_name, + "native option isn't supported by the compiler" + ) + features_to = self.feature_names(force_flags=native) + elif TOK == "MAX": + features_to = self.feature_supported.keys() + elif TOK == "MIN": + features_to = self.feature_min + else: + if TOK in self.feature_supported: + features_to.add(TOK) + else: + if not self.feature_is_exist(TOK): + self.dist_fatal(arg_name, + ", '%s' isn't a known feature or option" % tok + ) + if append: + final_features = final_features.union(features_to) + else: + final_features = final_features.difference(features_to) + + append = True # back to default + + return final_features + + _parse_regex_target = re.compile(r'\s|[*,/]|([()])') + def _parse_target_tokens(self, tokens): + assert(isinstance(tokens, str)) + final_targets = [] # to keep it sorted as specified + extra_flags = [] + has_baseline = False + + skipped = set() + policies = set() + multi_target = None + + tokens = list(filter(None, re.split(self._parse_regex_target, tokens))) + if not tokens: + self.dist_fatal("expected one token at least") + + for tok in tokens: + TOK = tok.upper() + ch = tok[0] + if ch in ('+', '-'): + self.dist_fatal( + "+/- are 'not' allowed from target's groups or @targets, " + "only from cpu_baseline and cpu_dispatch parms" + ) + elif ch == '$': + if multi_target is not None: + self.dist_fatal( + "policies aren't allowed inside multi-target '()'" + ", only CPU features" + ) + policies.add(self._parse_token_policy(TOK)) + elif ch == '#': + if multi_target is not None: + self.dist_fatal( + "target groups aren't allowed inside multi-target '()'" + ", only CPU features" + ) + has_baseline, final_targets, extra_flags = \ + self._parse_token_group(TOK, has_baseline, final_targets, extra_flags) + elif ch == '(': + if multi_target is not None: + self.dist_fatal("unclosed multi-target, missing ')'") + multi_target = set() + elif ch == ')': + if multi_target is None: + self.dist_fatal("multi-target opener '(' wasn't found") + targets = self._parse_multi_target(multi_target) + if targets is None: + skipped.add(tuple(multi_target)) + else: + if len(targets) == 1: + targets = targets[0] + if targets and targets not in final_targets: + final_targets.append(targets) + multi_target = None # back to default + else: + if TOK == "BASELINE": + if multi_target is not None: + self.dist_fatal("baseline isn't allowed inside multi-target '()'") + has_baseline = True + continue + + if multi_target is not None: + multi_target.add(TOK) + continue + + if not self.feature_is_exist(TOK): + self.dist_fatal("invalid target name '%s'" % TOK) + + is_enabled = ( + TOK in self.parse_baseline_names or + TOK in self.parse_dispatch_names + ) + if is_enabled: + if TOK not in final_targets: + final_targets.append(TOK) + continue + + skipped.add(TOK) + + if multi_target is not None: + self.dist_fatal("unclosed multi-target, missing ')'") + if skipped: + self.dist_log( + "skip targets", skipped, + "not part of baseline or dispatch-able features" + ) + + final_targets = self.feature_untied(final_targets) + + # add polices dependencies + for p in list(policies): + _, _, deps = self._parse_policies[p] + for d in deps: + if d in policies: + continue + self.dist_log( + "policy '%s' force enables '%s'" % ( + p, d + )) + policies.add(d) + + # release policies filtrations + for p, (have, nhave, _) in self._parse_policies.items(): + func = None + if p in policies: + func = have + self.dist_log("policy '%s' is ON" % p) + else: + func = nhave + if not func: + continue + has_baseline, final_targets, extra_flags = func( + has_baseline, final_targets, extra_flags + ) + + return has_baseline, final_targets, extra_flags + + def _parse_token_policy(self, token): + """validate policy token""" + if len(token) <= 1 or token[-1:] == token[0]: + self.dist_fatal("'$' must stuck in the begin of policy name") + token = token[1:] + if token not in self._parse_policies: + self.dist_fatal( + "'%s' is an invalid policy name, available policies are" % token, + self._parse_policies.keys() + ) + return token + + def _parse_token_group(self, token, has_baseline, final_targets, extra_flags): + """validate group token""" + if len(token) <= 1 or token[-1:] == token[0]: + self.dist_fatal("'#' must stuck in the begin of group name") + + token = token[1:] + ghas_baseline, gtargets, gextra_flags = self.parse_target_groups.get( + token, (False, None, []) + ) + if gtargets is None: + self.dist_fatal( + "'%s' is an invalid target group name, " % token + \ + "available target groups are", + self.parse_target_groups.keys() + ) + if ghas_baseline: + has_baseline = True + # always keep sorting as specified + final_targets += [f for f in gtargets if f not in final_targets] + extra_flags += [f for f in gextra_flags if f not in extra_flags] + return has_baseline, final_targets, extra_flags + + def _parse_multi_target(self, targets): + """validate multi targets that defined between parentheses()""" + # remove any implied features and keep the origins + if not targets: + self.dist_fatal("empty multi-target '()'") + if not all([ + self.feature_is_exist(tar) for tar in targets + ]) : + self.dist_fatal("invalid target name in multi-target", targets) + if not all([ + ( + tar in self.parse_baseline_names or + tar in self.parse_dispatch_names + ) + for tar in targets + ]) : + return None + targets = self.feature_ahead(targets) + if not targets: + return None + # force sort multi targets, so it can be comparable + targets = self.feature_sorted(targets) + targets = tuple(targets) # hashable + return targets + + def _parse_policy_not_keepbase(self, has_baseline, final_targets, extra_flags): + """skip all baseline features""" + skipped = [] + for tar in final_targets[:]: + is_base = False + if isinstance(tar, str): + is_base = tar in self.parse_baseline_names + else: + # multi targets + is_base = all([ + f in self.parse_baseline_names + for f in tar + ]) + if is_base: + skipped.append(tar) + final_targets.remove(tar) + + if skipped: + self.dist_log("skip baseline features", skipped) + + return has_baseline, final_targets, extra_flags + + def _parse_policy_keepsort(self, has_baseline, final_targets, extra_flags): + """leave a notice that $keep_sort is on""" + self.dist_log( + "policy 'keep_sort' is on, dispatch-able targets", final_targets, "\n" + "are 'not' sorted depend on the highest interest but" + "as specified in the dispatch-able source or the extra group" + ) + return has_baseline, final_targets, extra_flags + + def _parse_policy_not_keepsort(self, has_baseline, final_targets, extra_flags): + """sorted depend on the highest interest""" + final_targets = self.feature_sorted(final_targets, reverse=True) + return has_baseline, final_targets, extra_flags + + def _parse_policy_maxopt(self, has_baseline, final_targets, extra_flags): + """append the compiler optimization flags""" + if self.cc_has_debug: + self.dist_log("debug mode is detected, policy 'maxopt' is skipped.") + elif self.cc_noopt: + self.dist_log("optimization is disabled, policy 'maxopt' is skipped.") + else: + flags = self.cc_flags["opt"] + if not flags: + self.dist_log( + "current compiler doesn't support optimization flags, " + "policy 'maxopt' is skipped", stderr=True + ) + else: + extra_flags += flags + return has_baseline, final_targets, extra_flags + + def _parse_policy_werror(self, has_baseline, final_targets, extra_flags): + """force warnings to treated as errors""" + flags = self.cc_flags["werror"] + if not flags: + self.dist_log( + "current compiler doesn't support werror flags, " + "warnings will 'not' treated as errors", stderr=True + ) + else: + self.dist_log("compiler warnings are treated as errors") + extra_flags += flags + return has_baseline, final_targets, extra_flags + + def _parse_policy_autovec(self, has_baseline, final_targets, extra_flags): + """skip features that has no auto-vectorized support by compiler""" + skipped = [] + for tar in final_targets[:]: + if isinstance(tar, str): + can = self.feature_can_autovec(tar) + else: # multiple target + can = all([ + self.feature_can_autovec(t) + for t in tar + ]) + if not can: + final_targets.remove(tar) + skipped.append(tar) + + if skipped: + self.dist_log("skip non auto-vectorized features", skipped) + + return has_baseline, final_targets, extra_flags + +class CCompilerOpt(_Config, _Distutils, _Cache, _CCompiler, _Feature, _Parse): + """ + A helper class for `CCompiler` aims to provide extra build options + to effectively control of compiler optimizations that are directly + related to CPU features. + """ + def __init__(self, ccompiler, cpu_baseline="min", cpu_dispatch="max", cache_path=None): + _Config.__init__(self) + _Distutils.__init__(self, ccompiler) + _Cache.__init__(self, cache_path, self.dist_info(), cpu_baseline, cpu_dispatch) + _CCompiler.__init__(self) + _Feature.__init__(self) + if not self.cc_noopt and self.cc_has_native: + self.dist_log( + "native flag is specified through environment variables. " + "force cpu-baseline='native'" + ) + cpu_baseline = "native" + _Parse.__init__(self, cpu_baseline, cpu_dispatch) + # keep the requested features untouched, need it later for report + # and trace purposes + self._requested_baseline = cpu_baseline + self._requested_dispatch = cpu_dispatch + # key is the dispatch-able source and value is a tuple + # contains two items (has_baseline[boolean], dispatched-features[list]) + self.sources_status = getattr(self, "sources_status", {}) + # every instance should has a separate one + self.cache_private.add("sources_status") + # set it at the end to make sure the cache writing was done after init + # this class + self.hit_cache = hasattr(self, "hit_cache") + + def is_cached(self): + """ + Returns True if the class loaded from the cache file + """ + return self.cache_infile and self.hit_cache + + def cpu_baseline_flags(self): + """ + Returns a list of final CPU baseline compiler flags + """ + return self.parse_baseline_flags + + def cpu_baseline_names(self): + """ + return a list of final CPU baseline feature names + """ + return self.parse_baseline_names + + def cpu_dispatch_names(self): + """ + return a list of final CPU dispatch feature names + """ + return self.parse_dispatch_names + + def try_dispatch(self, sources, src_dir=None, **kwargs): + """ + Compile one or more dispatch-able sources and generates object files, + also generates abstract C config headers and macros that + used later for the final runtime dispatching process. + + The mechanism behind it is to takes each source file that specified + in 'sources' and branching it into several files depend on + special configuration statements that must be declared in the + top of each source which contains targeted CPU features, + then it compiles every branched source with the proper compiler flags. + + Parameters + ---------- + sources : list + Must be a list of dispatch-able sources file paths, + and configuration statements must be declared inside + each file. + + src_dir : str + Path of parent directory for the generated headers and wrapped sources. + If None(default) the files will generated in-place. + + **kwargs : any + Arguments to pass on to the `CCompiler.compile()` + + Returns + ------- + list : generated object files + + Raises + ------ + CompileError + Raises by `CCompiler.compile()` on compiling failure. + DistutilsError + Some errors during checking the sanity of configuration statements. + + See Also + -------- + parse_targets : + Parsing the configuration statements of dispatch-able sources. + """ + to_compile = {} + baseline_flags = self.cpu_baseline_flags() + include_dirs = kwargs.setdefault("include_dirs", []) + + for src in sources: + output_dir = os.path.dirname(src) + if src_dir: + if not output_dir.startswith(src_dir): + output_dir = os.path.join(src_dir, output_dir) + if output_dir not in include_dirs: + # To allow including the generated config header(*.dispatch.h) + # by the dispatch-able sources + include_dirs.append(output_dir) + + has_baseline, targets, extra_flags = self.parse_targets(src) + nochange = self._generate_config(output_dir, src, targets, has_baseline) + for tar in targets: + tar_src = self._wrap_target(output_dir, src, tar, nochange=nochange) + flags = tuple(extra_flags + self.feature_flags(tar)) + to_compile.setdefault(flags, []).append(tar_src) + + if has_baseline: + flags = tuple(extra_flags + baseline_flags) + to_compile.setdefault(flags, []).append(src) + + self.sources_status[src] = (has_baseline, targets) + + # For these reasons, the sources are compiled in a separate loop: + # - Gathering all sources with the same flags to benefit from + # the parallel compiling as much as possible. + # - To generate all config headers of the dispatchable sources, + # before the compilation in case if there are dependency relationships + # among them. + objects = [] + for flags, srcs in to_compile.items(): + objects += self.dist_compile(srcs, list(flags), **kwargs) + return objects + + def generate_dispatch_header(self, header_path): + """ + Generate the dispatch header which contains the #definitions and headers + for platform-specific instruction-sets for the enabled CPU baseline and + dispatch-able features. + + Its highly recommended to take a look at the generated header + also the generated source files via `try_dispatch()` + in order to get the full picture. + """ + self.dist_log("generate CPU dispatch header: (%s)" % header_path) + + baseline_names = self.cpu_baseline_names() + dispatch_names = self.cpu_dispatch_names() + baseline_len = len(baseline_names) + dispatch_len = len(dispatch_names) + + header_dir = os.path.dirname(header_path) + if not os.path.exists(header_dir): + self.dist_log( + f"dispatch header dir {header_dir} does not exist, creating it", + stderr=True + ) + os.makedirs(header_dir) + + with open(header_path, 'w') as f: + baseline_calls = ' \\\n'.join([ + ( + "\t%sWITH_CPU_EXPAND_(MACRO_TO_CALL(%s, __VA_ARGS__))" + ) % (self.conf_c_prefix, f) + for f in baseline_names + ]) + dispatch_calls = ' \\\n'.join([ + ( + "\t%sWITH_CPU_EXPAND_(MACRO_TO_CALL(%s, __VA_ARGS__))" + ) % (self.conf_c_prefix, f) + for f in dispatch_names + ]) + f.write(textwrap.dedent("""\ + /* + * AUTOGENERATED DON'T EDIT + * Please make changes to the code generator (distutils/ccompiler_opt.py) + */ + #define {pfx}WITH_CPU_BASELINE "{baseline_str}" + #define {pfx}WITH_CPU_DISPATCH "{dispatch_str}" + #define {pfx}WITH_CPU_BASELINE_N {baseline_len} + #define {pfx}WITH_CPU_DISPATCH_N {dispatch_len} + #define {pfx}WITH_CPU_EXPAND_(X) X + #define {pfx}WITH_CPU_BASELINE_CALL(MACRO_TO_CALL, ...) \\ + {baseline_calls} + #define {pfx}WITH_CPU_DISPATCH_CALL(MACRO_TO_CALL, ...) \\ + {dispatch_calls} + """).format( + pfx=self.conf_c_prefix, baseline_str=" ".join(baseline_names), + dispatch_str=" ".join(dispatch_names), baseline_len=baseline_len, + dispatch_len=dispatch_len, baseline_calls=baseline_calls, + dispatch_calls=dispatch_calls + )) + baseline_pre = '' + for name in baseline_names: + baseline_pre += self.feature_c_preprocessor(name, tabs=1) + '\n' + + dispatch_pre = '' + for name in dispatch_names: + dispatch_pre += textwrap.dedent("""\ + #ifdef {pfx}CPU_TARGET_{name} + {pre} + #endif /*{pfx}CPU_TARGET_{name}*/ + """).format( + pfx=self.conf_c_prefix_, name=name, pre=self.feature_c_preprocessor( + name, tabs=1 + )) + + f.write(textwrap.dedent("""\ + /******* baseline features *******/ + {baseline_pre} + /******* dispatch features *******/ + {dispatch_pre} + """).format( + pfx=self.conf_c_prefix_, baseline_pre=baseline_pre, + dispatch_pre=dispatch_pre + )) + + def report(self, full=False): + report = [] + platform_rows = [] + baseline_rows = [] + dispatch_rows = [] + report.append(("Platform", platform_rows)) + report.append(("", "")) + report.append(("CPU baseline", baseline_rows)) + report.append(("", "")) + report.append(("CPU dispatch", dispatch_rows)) + + ########## platform ########## + platform_rows.append(("Architecture", ( + "unsupported" if self.cc_on_noarch else self.cc_march) + )) + platform_rows.append(("Compiler", ( + "unix-like" if self.cc_is_nocc else self.cc_name) + )) + ########## baseline ########## + if self.cc_noopt: + baseline_rows.append(("Requested", "optimization disabled")) + else: + baseline_rows.append(("Requested", repr(self._requested_baseline))) + + baseline_names = self.cpu_baseline_names() + baseline_rows.append(( + "Enabled", (' '.join(baseline_names) if baseline_names else "none") + )) + baseline_flags = self.cpu_baseline_flags() + baseline_rows.append(( + "Flags", (' '.join(baseline_flags) if baseline_flags else "none") + )) + extra_checks = [] + for name in baseline_names: + extra_checks += self.feature_extra_checks(name) + baseline_rows.append(( + "Extra checks", (' '.join(extra_checks) if extra_checks else "none") + )) + + ########## dispatch ########## + if self.cc_noopt: + baseline_rows.append(("Requested", "optimization disabled")) + else: + dispatch_rows.append(("Requested", repr(self._requested_dispatch))) + + dispatch_names = self.cpu_dispatch_names() + dispatch_rows.append(( + "Enabled", (' '.join(dispatch_names) if dispatch_names else "none") + )) + ########## Generated ########## + # TODO: + # - collect object names from 'try_dispatch()' + # then get size of each object and printed + # - give more details about the features that not + # generated due compiler support + # - find a better output's design. + # + target_sources = {} + for source, (_, targets) in self.sources_status.items(): + for tar in targets: + target_sources.setdefault(tar, []).append(source) + + if not full or not target_sources: + generated = "" + for tar in self.feature_sorted(target_sources): + sources = target_sources[tar] + name = tar if isinstance(tar, str) else '(%s)' % ' '.join(tar) + generated += name + "[%d] " % len(sources) + dispatch_rows.append(("Generated", generated[:-1] if generated else "none")) + else: + dispatch_rows.append(("Generated", '')) + for tar in self.feature_sorted(target_sources): + sources = target_sources[tar] + pretty_name = tar if isinstance(tar, str) else '(%s)' % ' '.join(tar) + flags = ' '.join(self.feature_flags(tar)) + implies = ' '.join(self.feature_sorted(self.feature_implies(tar))) + detect = ' '.join(self.feature_detect(tar)) + extra_checks = [] + for name in ((tar,) if isinstance(tar, str) else tar): + extra_checks += self.feature_extra_checks(name) + extra_checks = (' '.join(extra_checks) if extra_checks else "none") + + dispatch_rows.append(('', '')) + dispatch_rows.append((pretty_name, implies)) + dispatch_rows.append(("Flags", flags)) + dispatch_rows.append(("Extra checks", extra_checks)) + dispatch_rows.append(("Detect", detect)) + for src in sources: + dispatch_rows.append(("", src)) + + ############################### + # TODO: add support for 'markdown' format + text = [] + secs_len = [len(secs) for secs, _ in report] + cols_len = [len(col) for _, rows in report for col, _ in rows] + tab = ' ' * 2 + pad = max(max(secs_len), max(cols_len)) + for sec, rows in report: + if not sec: + text.append("") # empty line + continue + sec += ' ' * (pad - len(sec)) + text.append(sec + tab + ': ') + for col, val in rows: + col += ' ' * (pad - len(col)) + text.append(tab + col + ': ' + val) + + return '\n'.join(text) + + def _wrap_target(self, output_dir, dispatch_src, target, nochange=False): + assert(isinstance(target, (str, tuple))) + if isinstance(target, str): + ext_name = target_name = target + else: + # multi-target + ext_name = '.'.join(target) + target_name = '__'.join(target) + + wrap_path = os.path.join(output_dir, os.path.basename(dispatch_src)) + wrap_path = "{0}.{2}{1}".format(*os.path.splitext(wrap_path), ext_name.lower()) + if nochange and os.path.exists(wrap_path): + return wrap_path + + self.dist_log("wrap dispatch-able target -> ", wrap_path) + # sorting for readability + features = self.feature_sorted(self.feature_implies_c(target)) + target_join = "#define %sCPU_TARGET_" % self.conf_c_prefix_ + target_defs = [target_join + f for f in features] + target_defs = '\n'.join(target_defs) + + with open(wrap_path, "w") as fd: + fd.write(textwrap.dedent("""\ + /** + * AUTOGENERATED DON'T EDIT + * Please make changes to the code generator \ + (distutils/ccompiler_opt.py) + */ + #define {pfx}CPU_TARGET_MODE + #define {pfx}CPU_TARGET_CURRENT {target_name} + {target_defs} + #include "{path}" + """).format( + pfx=self.conf_c_prefix_, target_name=target_name, + path=os.path.abspath(dispatch_src), target_defs=target_defs + )) + return wrap_path + + def _generate_config(self, output_dir, dispatch_src, targets, has_baseline=False): + config_path = os.path.basename(dispatch_src).replace(".c", ".h") + config_path = os.path.join(output_dir, config_path) + # check if targets didn't change to avoid recompiling + cache_hash = self.cache_hash(targets, has_baseline) + try: + with open(config_path) as f: + last_hash = f.readline().split("cache_hash:") + if len(last_hash) == 2 and int(last_hash[1]) == cache_hash: + return True + except IOError: + pass + + self.dist_log("generate dispatched config -> ", config_path) + dispatch_calls = [] + for tar in targets: + if isinstance(tar, str): + target_name = tar + else: # multi target + target_name = '__'.join([t for t in tar]) + req_detect = self.feature_detect(tar) + req_detect = '&&'.join([ + "CHK(%s)" % f for f in req_detect + ]) + dispatch_calls.append( + "\t%sCPU_DISPATCH_EXPAND_(CB((%s), %s, __VA_ARGS__))" % ( + self.conf_c_prefix_, req_detect, target_name + )) + dispatch_calls = ' \\\n'.join(dispatch_calls) + + if has_baseline: + baseline_calls = ( + "\t%sCPU_DISPATCH_EXPAND_(CB(__VA_ARGS__))" + ) % self.conf_c_prefix_ + else: + baseline_calls = '' + + with open(config_path, "w") as fd: + fd.write(textwrap.dedent("""\ + // cache_hash:{cache_hash} + /** + * AUTOGENERATED DON'T EDIT + * Please make changes to the code generator (distutils/ccompiler_opt.py) + */ + #ifndef {pfx}CPU_DISPATCH_EXPAND_ + #define {pfx}CPU_DISPATCH_EXPAND_(X) X + #endif + #undef {pfx}CPU_DISPATCH_BASELINE_CALL + #undef {pfx}CPU_DISPATCH_CALL + #define {pfx}CPU_DISPATCH_BASELINE_CALL(CB, ...) \\ + {baseline_calls} + #define {pfx}CPU_DISPATCH_CALL(CHK, CB, ...) \\ + {dispatch_calls} + """).format( + pfx=self.conf_c_prefix_, baseline_calls=baseline_calls, + dispatch_calls=dispatch_calls, cache_hash=cache_hash + )) + return False + +def new_ccompiler_opt(compiler, dispatch_hpath, **kwargs): + """ + Create a new instance of 'CCompilerOpt' and generate the dispatch header + which contains the #definitions and headers of platform-specific instruction-sets for + the enabled CPU baseline and dispatch-able features. + + Parameters + ---------- + compiler : CCompiler instance + dispatch_hpath : str + path of the dispatch header + + **kwargs: passed as-is to `CCompilerOpt(...)` + Returns + ------- + new instance of CCompilerOpt + """ + opt = CCompilerOpt(compiler, **kwargs) + if not os.path.exists(dispatch_hpath) or not opt.is_cached(): + opt.generate_dispatch_header(dispatch_hpath) + return opt diff --git a/venv/Lib/site-packages/numpy/distutils/checks/cpu_asimd.c b/venv/Lib/site-packages/numpy/distutils/checks/cpu_asimd.c new file mode 100644 index 0000000..8df556b --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/checks/cpu_asimd.c @@ -0,0 +1,25 @@ +#ifdef _MSC_VER + #include +#endif +#include + +int main(void) +{ + float32x4_t v1 = vdupq_n_f32(1.0f), v2 = vdupq_n_f32(2.0f); + /* MAXMIN */ + int ret = (int)vgetq_lane_f32(vmaxnmq_f32(v1, v2), 0); + ret += (int)vgetq_lane_f32(vminnmq_f32(v1, v2), 0); + /* ROUNDING */ + ret += (int)vgetq_lane_f32(vrndq_f32(v1), 0); +#ifdef __aarch64__ + { + float64x2_t vd1 = vdupq_n_f64(1.0), vd2 = vdupq_n_f64(2.0); + /* MAXMIN */ + ret += (int)vgetq_lane_f64(vmaxnmq_f64(vd1, vd2), 0); + ret += (int)vgetq_lane_f64(vminnmq_f64(vd1, vd2), 0); + /* ROUNDING */ + ret += (int)vgetq_lane_f64(vrndq_f64(vd1), 0); + } +#endif + return ret; +} diff --git a/venv/Lib/site-packages/numpy/distutils/checks/cpu_asimddp.c b/venv/Lib/site-packages/numpy/distutils/checks/cpu_asimddp.c new file mode 100644 index 0000000..0158d13 --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/checks/cpu_asimddp.c @@ -0,0 +1,15 @@ +#ifdef _MSC_VER + #include +#endif +#include + +int main(void) +{ + uint8x16_t v1 = vdupq_n_u8((unsigned char)1), v2 = vdupq_n_u8((unsigned char)2); + uint32x4_t va = vdupq_n_u32(3); + int ret = (int)vgetq_lane_u32(vdotq_u32(va, v1, v2), 0); +#ifdef __aarch64__ + ret += (int)vgetq_lane_u32(vdotq_laneq_u32(va, v1, v2, 0), 0); +#endif + return ret; +} diff --git a/venv/Lib/site-packages/numpy/distutils/checks/cpu_asimdfhm.c b/venv/Lib/site-packages/numpy/distutils/checks/cpu_asimdfhm.c new file mode 100644 index 0000000..bb437aa --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/checks/cpu_asimdfhm.c @@ -0,0 +1,17 @@ +#ifdef _MSC_VER + #include +#endif +#include + +int main(void) +{ + float16x8_t vhp = vdupq_n_f16((float16_t)1); + float16x4_t vlhp = vdup_n_f16((float16_t)1); + float32x4_t vf = vdupq_n_f32(1.0f); + float32x2_t vlf = vdup_n_f32(1.0f); + + int ret = (int)vget_lane_f32(vfmlal_low_u32(vlf, vlhp, vlhp), 0); + ret += (int)vgetq_lane_f32(vfmlslq_high_u32(vf, vhp, vhp), 0); + + return ret; +} diff --git a/venv/Lib/site-packages/numpy/distutils/checks/cpu_asimdhp.c b/venv/Lib/site-packages/numpy/distutils/checks/cpu_asimdhp.c new file mode 100644 index 0000000..80b9400 --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/checks/cpu_asimdhp.c @@ -0,0 +1,14 @@ +#ifdef _MSC_VER + #include +#endif +#include + +int main(void) +{ + float16x8_t vhp = vdupq_n_f16((float16_t)-1); + float16x4_t vlhp = vdup_n_f16((float16_t)-1); + + int ret = (int)vgetq_lane_f16(vabdq_f16(vhp, vhp), 0); + ret += (int)vget_lane_f16(vabd_f16(vlhp, vlhp), 0); + return ret; +} diff --git a/venv/Lib/site-packages/numpy/distutils/checks/cpu_avx.c b/venv/Lib/site-packages/numpy/distutils/checks/cpu_avx.c new file mode 100644 index 0000000..737c0d2 --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/checks/cpu_avx.c @@ -0,0 +1,7 @@ +#include + +int main(void) +{ + __m256 a = _mm256_add_ps(_mm256_setzero_ps(), _mm256_setzero_ps()); + return (int)_mm_cvtss_f32(_mm256_castps256_ps128(a)); +} diff --git a/venv/Lib/site-packages/numpy/distutils/checks/cpu_avx2.c b/venv/Lib/site-packages/numpy/distutils/checks/cpu_avx2.c new file mode 100644 index 0000000..dfb11fd --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/checks/cpu_avx2.c @@ -0,0 +1,7 @@ +#include + +int main(void) +{ + __m256i a = _mm256_abs_epi16(_mm256_setzero_si256()); + return _mm_cvtsi128_si32(_mm256_castsi256_si128(a)); +} diff --git a/venv/Lib/site-packages/numpy/distutils/checks/cpu_avx512_clx.c b/venv/Lib/site-packages/numpy/distutils/checks/cpu_avx512_clx.c new file mode 100644 index 0000000..71dad83 --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/checks/cpu_avx512_clx.c @@ -0,0 +1,8 @@ +#include + +int main(void) +{ + /* VNNI */ + __m512i a = _mm512_dpbusd_epi32(_mm512_setzero_si512(), _mm512_setzero_si512(), _mm512_setzero_si512()); + return _mm_cvtsi128_si32(_mm512_castsi512_si128(a)); +} diff --git a/venv/Lib/site-packages/numpy/distutils/checks/cpu_avx512_cnl.c b/venv/Lib/site-packages/numpy/distutils/checks/cpu_avx512_cnl.c new file mode 100644 index 0000000..dfab443 --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/checks/cpu_avx512_cnl.c @@ -0,0 +1,10 @@ +#include + +int main(void) +{ + /* IFMA */ + __m512i a = _mm512_madd52hi_epu64(_mm512_setzero_si512(), _mm512_setzero_si512(), _mm512_setzero_si512()); + /* VMBI */ + a = _mm512_permutex2var_epi8(a, _mm512_setzero_si512(), _mm512_setzero_si512()); + return _mm_cvtsi128_si32(_mm512_castsi512_si128(a)); +} diff --git a/venv/Lib/site-packages/numpy/distutils/checks/cpu_avx512_icl.c b/venv/Lib/site-packages/numpy/distutils/checks/cpu_avx512_icl.c new file mode 100644 index 0000000..cf2706b --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/checks/cpu_avx512_icl.c @@ -0,0 +1,12 @@ +#include + +int main(void) +{ + /* VBMI2 */ + __m512i a = _mm512_shrdv_epi64(_mm512_setzero_si512(), _mm512_setzero_si512(), _mm512_setzero_si512()); + /* BITLAG */ + a = _mm512_popcnt_epi8(a); + /* VPOPCNTDQ */ + a = _mm512_popcnt_epi64(a); + return _mm_cvtsi128_si32(_mm512_castsi512_si128(a)); +} diff --git a/venv/Lib/site-packages/numpy/distutils/checks/cpu_avx512_knl.c b/venv/Lib/site-packages/numpy/distutils/checks/cpu_avx512_knl.c new file mode 100644 index 0000000..0699f37 --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/checks/cpu_avx512_knl.c @@ -0,0 +1,11 @@ +#include + +int main(void) +{ + int base[128]; + /* ER */ + __m512i a = _mm512_castpd_si512(_mm512_exp2a23_pd(_mm512_setzero_pd())); + /* PF */ + _mm512_mask_prefetch_i64scatter_pd(base, _mm512_cmpeq_epi64_mask(a, a), a, 1, _MM_HINT_T1); + return base[0]; +} diff --git a/venv/Lib/site-packages/numpy/distutils/checks/cpu_avx512_knm.c b/venv/Lib/site-packages/numpy/distutils/checks/cpu_avx512_knm.c new file mode 100644 index 0000000..db61b4b --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/checks/cpu_avx512_knm.c @@ -0,0 +1,17 @@ +#include + +int main(void) +{ + __m512i a = _mm512_setzero_si512(); + __m512 b = _mm512_setzero_ps(); + + /* 4FMAPS */ + b = _mm512_4fmadd_ps(b, b, b, b, b, NULL); + /* 4VNNIW */ + a = _mm512_4dpwssd_epi32(a, a, a, a, a, NULL); + /* VPOPCNTDQ */ + a = _mm512_popcnt_epi64(a); + + a = _mm512_add_epi32(a, _mm512_castps_si512(b)); + return _mm_cvtsi128_si32(_mm512_castsi512_si128(a)); +} diff --git a/venv/Lib/site-packages/numpy/distutils/checks/cpu_avx512_skx.c b/venv/Lib/site-packages/numpy/distutils/checks/cpu_avx512_skx.c new file mode 100644 index 0000000..1d5e15b --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/checks/cpu_avx512_skx.c @@ -0,0 +1,12 @@ +#include + +int main(void) +{ + /* VL */ + __m256i a = _mm256_abs_epi64(_mm256_setzero_si256()); + /* DQ */ + __m512i b = _mm512_broadcast_i32x8(a); + /* BW */ + b = _mm512_abs_epi16(b); + return _mm_cvtsi128_si32(_mm512_castsi512_si128(b)); +} diff --git a/venv/Lib/site-packages/numpy/distutils/checks/cpu_avx512cd.c b/venv/Lib/site-packages/numpy/distutils/checks/cpu_avx512cd.c new file mode 100644 index 0000000..61bef6b --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/checks/cpu_avx512cd.c @@ -0,0 +1,7 @@ +#include + +int main(void) +{ + __m512i a = _mm512_lzcnt_epi32(_mm512_setzero_si512()); + return _mm_cvtsi128_si32(_mm512_castsi512_si128(a)); +} diff --git a/venv/Lib/site-packages/numpy/distutils/checks/cpu_avx512f.c b/venv/Lib/site-packages/numpy/distutils/checks/cpu_avx512f.c new file mode 100644 index 0000000..f60cc09 --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/checks/cpu_avx512f.c @@ -0,0 +1,7 @@ +#include + +int main(void) +{ + __m512i a = _mm512_abs_epi32(_mm512_setzero_si512()); + return _mm_cvtsi128_si32(_mm512_castsi512_si128(a)); +} diff --git a/venv/Lib/site-packages/numpy/distutils/checks/cpu_f16c.c b/venv/Lib/site-packages/numpy/distutils/checks/cpu_f16c.c new file mode 100644 index 0000000..a5a343e --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/checks/cpu_f16c.c @@ -0,0 +1,9 @@ +#include +#include + +int main(void) +{ + __m128 a = _mm_cvtph_ps(_mm_setzero_si128()); + __m256 a8 = _mm256_cvtph_ps(_mm_setzero_si128()); + return (int)(_mm_cvtss_f32(a) + _mm_cvtss_f32(_mm256_castps256_ps128(a8))); +} diff --git a/venv/Lib/site-packages/numpy/distutils/checks/cpu_fma3.c b/venv/Lib/site-packages/numpy/distutils/checks/cpu_fma3.c new file mode 100644 index 0000000..cf34c6c --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/checks/cpu_fma3.c @@ -0,0 +1,8 @@ +#include +#include + +int main(void) +{ + __m256 a = _mm256_fmadd_ps(_mm256_setzero_ps(), _mm256_setzero_ps(), _mm256_setzero_ps()); + return (int)_mm_cvtss_f32(_mm256_castps256_ps128(a)); +} diff --git a/venv/Lib/site-packages/numpy/distutils/checks/cpu_fma4.c b/venv/Lib/site-packages/numpy/distutils/checks/cpu_fma4.c new file mode 100644 index 0000000..1ad7170 --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/checks/cpu_fma4.c @@ -0,0 +1,12 @@ +#include +#ifdef _MSC_VER + #include +#else + #include +#endif + +int main(void) +{ + __m256 a = _mm256_macc_ps(_mm256_setzero_ps(), _mm256_setzero_ps(), _mm256_setzero_ps()); + return (int)_mm_cvtss_f32(_mm256_castps256_ps128(a)); +} diff --git a/venv/Lib/site-packages/numpy/distutils/checks/cpu_neon.c b/venv/Lib/site-packages/numpy/distutils/checks/cpu_neon.c new file mode 100644 index 0000000..4eab1f3 --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/checks/cpu_neon.c @@ -0,0 +1,15 @@ +#ifdef _MSC_VER + #include +#endif +#include + +int main(void) +{ + float32x4_t v1 = vdupq_n_f32(1.0f), v2 = vdupq_n_f32(2.0f); + int ret = (int)vgetq_lane_f32(vmulq_f32(v1, v2), 0); +#ifdef __aarch64__ + float64x2_t vd1 = vdupq_n_f64(1.0), vd2 = vdupq_n_f64(2.0); + ret += (int)vgetq_lane_f64(vmulq_f64(vd1, vd2), 0); +#endif + return ret; +} diff --git a/venv/Lib/site-packages/numpy/distutils/checks/cpu_neon_fp16.c b/venv/Lib/site-packages/numpy/distutils/checks/cpu_neon_fp16.c new file mode 100644 index 0000000..745d2e7 --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/checks/cpu_neon_fp16.c @@ -0,0 +1,11 @@ +#ifdef _MSC_VER + #include +#endif +#include + +int main(void) +{ + short z4[] = {0, 0, 0, 0, 0, 0, 0, 0}; + float32x4_t v_z4 = vcvt_f32_f16((float16x4_t)vld1_s16((const short*)z4)); + return (int)vgetq_lane_f32(v_z4, 0); +} diff --git a/venv/Lib/site-packages/numpy/distutils/checks/cpu_neon_vfpv4.c b/venv/Lib/site-packages/numpy/distutils/checks/cpu_neon_vfpv4.c new file mode 100644 index 0000000..45f7b5d --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/checks/cpu_neon_vfpv4.c @@ -0,0 +1,19 @@ +#ifdef _MSC_VER + #include +#endif +#include + +int main(void) +{ + float32x4_t v1 = vdupq_n_f32(1.0f); + float32x4_t v2 = vdupq_n_f32(2.0f); + float32x4_t v3 = vdupq_n_f32(3.0f); + int ret = (int)vgetq_lane_f32(vfmaq_f32(v1, v2, v3), 0); +#ifdef __aarch64__ + float64x2_t vd1 = vdupq_n_f64(1.0); + float64x2_t vd2 = vdupq_n_f64(2.0); + float64x2_t vd3 = vdupq_n_f64(3.0); + ret += (int)vgetq_lane_f64(vfmaq_f64(vd1, vd2, vd3), 0); +#endif + return ret; +} diff --git a/venv/Lib/site-packages/numpy/distutils/checks/cpu_popcnt.c b/venv/Lib/site-packages/numpy/distutils/checks/cpu_popcnt.c new file mode 100644 index 0000000..e6a80fb --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/checks/cpu_popcnt.c @@ -0,0 +1,23 @@ +#ifdef _MSC_VER + #include +#else + #include +#endif + +int main(void) +{ + long long a = 0; + int b; +#ifdef _MSC_VER + #ifdef _M_X64 + a = _mm_popcnt_u64(1); + #endif + b = _mm_popcnt_u32(1); +#else + #ifdef __x86_64__ + a = __builtin_popcountll(1); + #endif + b = __builtin_popcount(1); +#endif + return (int)a + b; +} diff --git a/venv/Lib/site-packages/numpy/distutils/checks/cpu_sse.c b/venv/Lib/site-packages/numpy/distutils/checks/cpu_sse.c new file mode 100644 index 0000000..bb98bf6 --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/checks/cpu_sse.c @@ -0,0 +1,7 @@ +#include + +int main(void) +{ + __m128 a = _mm_add_ps(_mm_setzero_ps(), _mm_setzero_ps()); + return (int)_mm_cvtss_f32(a); +} diff --git a/venv/Lib/site-packages/numpy/distutils/checks/cpu_sse2.c b/venv/Lib/site-packages/numpy/distutils/checks/cpu_sse2.c new file mode 100644 index 0000000..658afc9 --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/checks/cpu_sse2.c @@ -0,0 +1,7 @@ +#include + +int main(void) +{ + __m128i a = _mm_add_epi16(_mm_setzero_si128(), _mm_setzero_si128()); + return _mm_cvtsi128_si32(a); +} diff --git a/venv/Lib/site-packages/numpy/distutils/checks/cpu_sse3.c b/venv/Lib/site-packages/numpy/distutils/checks/cpu_sse3.c new file mode 100644 index 0000000..aece1e6 --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/checks/cpu_sse3.c @@ -0,0 +1,7 @@ +#include + +int main(void) +{ + __m128 a = _mm_hadd_ps(_mm_setzero_ps(), _mm_setzero_ps()); + return (int)_mm_cvtss_f32(a); +} diff --git a/venv/Lib/site-packages/numpy/distutils/checks/cpu_sse41.c b/venv/Lib/site-packages/numpy/distutils/checks/cpu_sse41.c new file mode 100644 index 0000000..bfdb9fe --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/checks/cpu_sse41.c @@ -0,0 +1,7 @@ +#include + +int main(void) +{ + __m128 a = _mm_floor_ps(_mm_setzero_ps()); + return (int)_mm_cvtss_f32(a); +} diff --git a/venv/Lib/site-packages/numpy/distutils/checks/cpu_sse42.c b/venv/Lib/site-packages/numpy/distutils/checks/cpu_sse42.c new file mode 100644 index 0000000..24f5d93 --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/checks/cpu_sse42.c @@ -0,0 +1,7 @@ +#include + +int main(void) +{ + __m128 a = _mm_hadd_ps(_mm_setzero_ps(), _mm_setzero_ps()); + return (int)_mm_cvtss_f32(a); +} diff --git a/venv/Lib/site-packages/numpy/distutils/checks/cpu_ssse3.c b/venv/Lib/site-packages/numpy/distutils/checks/cpu_ssse3.c new file mode 100644 index 0000000..ad0abc1 --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/checks/cpu_ssse3.c @@ -0,0 +1,7 @@ +#include + +int main(void) +{ + __m128i a = _mm_hadd_epi16(_mm_setzero_si128(), _mm_setzero_si128()); + return (int)_mm_cvtsi128_si32(a); +} diff --git a/venv/Lib/site-packages/numpy/distutils/checks/cpu_vsx.c b/venv/Lib/site-packages/numpy/distutils/checks/cpu_vsx.c new file mode 100644 index 0000000..0b3f30d --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/checks/cpu_vsx.c @@ -0,0 +1,21 @@ +#ifndef __VSX__ + #error "VSX is not supported" +#endif +#include + +#if (defined(__GNUC__) && !defined(vec_xl)) || (defined(__clang__) && !defined(__IBMC__)) + #define vsx_ld vec_vsx_ld + #define vsx_st vec_vsx_st +#else + #define vsx_ld vec_xl + #define vsx_st vec_xst +#endif + +int main(void) +{ + unsigned int zout[4]; + unsigned int z4[] = {0, 0, 0, 0}; + __vector unsigned int v_z4 = vsx_ld(0, z4); + vsx_st(v_z4, 0, zout); + return zout[0]; +} diff --git a/venv/Lib/site-packages/numpy/distutils/checks/cpu_vsx2.c b/venv/Lib/site-packages/numpy/distutils/checks/cpu_vsx2.c new file mode 100644 index 0000000..410fb29 --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/checks/cpu_vsx2.c @@ -0,0 +1,13 @@ +#ifndef __VSX__ + #error "VSX is not supported" +#endif +#include + +typedef __vector unsigned long long v_uint64x2; + +int main(void) +{ + v_uint64x2 z2 = (v_uint64x2){0, 0}; + z2 = (v_uint64x2)vec_cmpeq(z2, z2); + return (int)vec_extract(z2, 0); +} diff --git a/venv/Lib/site-packages/numpy/distutils/checks/cpu_vsx3.c b/venv/Lib/site-packages/numpy/distutils/checks/cpu_vsx3.c new file mode 100644 index 0000000..8575265 --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/checks/cpu_vsx3.c @@ -0,0 +1,13 @@ +#ifndef __VSX__ + #error "VSX is not supported" +#endif +#include + +typedef __vector unsigned int v_uint32x4; + +int main(void) +{ + v_uint32x4 z4 = (v_uint32x4){0, 0, 0, 0}; + z4 = vec_absd(z4, z4); + return (int)vec_extract(z4, 0); +} diff --git a/venv/Lib/site-packages/numpy/distutils/checks/cpu_xop.c b/venv/Lib/site-packages/numpy/distutils/checks/cpu_xop.c new file mode 100644 index 0000000..51d70cf --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/checks/cpu_xop.c @@ -0,0 +1,12 @@ +#include +#ifdef _MSC_VER + #include +#else + #include +#endif + +int main(void) +{ + __m128i a = _mm_comge_epu32(_mm_setzero_si128(), _mm_setzero_si128()); + return _mm_cvtsi128_si32(a); +} diff --git a/venv/Lib/site-packages/numpy/distutils/checks/extra_avx512bw_mask.c b/venv/Lib/site-packages/numpy/distutils/checks/extra_avx512bw_mask.c new file mode 100644 index 0000000..9cfd0c2 --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/checks/extra_avx512bw_mask.c @@ -0,0 +1,18 @@ +#include +/** + * Test BW mask operations due to: + * - MSVC has supported it since vs2019 see, + * https://developercommunity.visualstudio.com/content/problem/518298/missing-avx512bw-mask-intrinsics.html + * - Clang >= v8.0 + * - GCC >= v7.1 + */ +int main(void) +{ + __mmask64 m64 = _mm512_cmpeq_epi8_mask(_mm512_set1_epi8((char)1), _mm512_set1_epi8((char)1)); + m64 = _kor_mask64(m64, m64); + m64 = _kxor_mask64(m64, m64); + m64 = _cvtu64_mask64(_cvtmask64_u64(m64)); + m64 = _mm512_kunpackd(m64, m64); + m64 = (__mmask64)_mm512_kunpackw((__mmask32)m64, (__mmask32)m64); + return (int)_cvtmask64_u64(m64); +} diff --git a/venv/Lib/site-packages/numpy/distutils/checks/extra_avx512dq_mask.c b/venv/Lib/site-packages/numpy/distutils/checks/extra_avx512dq_mask.c new file mode 100644 index 0000000..f0dc88b --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/checks/extra_avx512dq_mask.c @@ -0,0 +1,16 @@ +#include +/** + * Test DQ mask operations due to: + * - MSVC has supported it since vs2019 see, + * https://developercommunity.visualstudio.com/content/problem/518298/missing-avx512bw-mask-intrinsics.html + * - Clang >= v8.0 + * - GCC >= v7.1 + */ +int main(void) +{ + __mmask8 m8 = _mm512_cmpeq_epi64_mask(_mm512_set1_epi64(1), _mm512_set1_epi64(1)); + m8 = _kor_mask8(m8, m8); + m8 = _kxor_mask8(m8, m8); + m8 = _cvtu32_mask8(_cvtmask8_u32(m8)); + return (int)_cvtmask8_u32(m8); +} diff --git a/venv/Lib/site-packages/numpy/distutils/checks/extra_avx512f_reduce.c b/venv/Lib/site-packages/numpy/distutils/checks/extra_avx512f_reduce.c new file mode 100644 index 0000000..f979d50 --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/checks/extra_avx512f_reduce.c @@ -0,0 +1,41 @@ +#include +/** + * The following intrinsics don't have direct native support but compilers + * tend to emulate them. + * They're usually supported by gcc >= 7.1, clang >= 4 and icc >= 19 + */ +int main(void) +{ + __m512 one_ps = _mm512_set1_ps(1.0f); + __m512d one_pd = _mm512_set1_pd(1.0); + __m512i one_i64 = _mm512_set1_epi64(1.0); + // add + float sum_ps = _mm512_reduce_add_ps(one_ps); + double sum_pd = _mm512_reduce_add_pd(one_pd); + int sum_int = (int)_mm512_reduce_add_epi64(one_i64); + sum_int += (int)_mm512_reduce_add_epi32(one_i64); + // mul + sum_ps += _mm512_reduce_mul_ps(one_ps); + sum_pd += _mm512_reduce_mul_pd(one_pd); + sum_int += (int)_mm512_reduce_mul_epi64(one_i64); + sum_int += (int)_mm512_reduce_mul_epi32(one_i64); + // min + sum_ps += _mm512_reduce_min_ps(one_ps); + sum_pd += _mm512_reduce_min_pd(one_pd); + sum_int += (int)_mm512_reduce_min_epi32(one_i64); + sum_int += (int)_mm512_reduce_min_epu32(one_i64); + sum_int += (int)_mm512_reduce_min_epi64(one_i64); + // max + sum_ps += _mm512_reduce_max_ps(one_ps); + sum_pd += _mm512_reduce_max_pd(one_pd); + sum_int += (int)_mm512_reduce_max_epi32(one_i64); + sum_int += (int)_mm512_reduce_max_epu32(one_i64); + sum_int += (int)_mm512_reduce_max_epi64(one_i64); + // and + sum_int += (int)_mm512_reduce_and_epi32(one_i64); + sum_int += (int)_mm512_reduce_and_epi64(one_i64); + // or + sum_int += (int)_mm512_reduce_or_epi32(one_i64); + sum_int += (int)_mm512_reduce_or_epi64(one_i64); + return (int)sum_ps + (int)sum_pd + sum_int; +} diff --git a/venv/Lib/site-packages/numpy/distutils/checks/test_flags.c b/venv/Lib/site-packages/numpy/distutils/checks/test_flags.c new file mode 100644 index 0000000..4cd09d4 --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/checks/test_flags.c @@ -0,0 +1 @@ +int test_flags; diff --git a/venv/Lib/site-packages/numpy/distutils/command/__init__.py b/venv/Lib/site-packages/numpy/distutils/command/__init__.py new file mode 100644 index 0000000..3ba501d --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/command/__init__.py @@ -0,0 +1,41 @@ +"""distutils.command + +Package containing implementation of all the standard Distutils +commands. + +""" +def test_na_writable_attributes_deletion(): + a = np.NA(2) + attr = ['payload', 'dtype'] + for s in attr: + assert_raises(AttributeError, delattr, a, s) + + +__revision__ = "$Id: __init__.py,v 1.3 2005/05/16 11:08:49 pearu Exp $" + +distutils_all = [ #'build_py', + 'clean', + 'install_clib', + 'install_scripts', + 'bdist', + 'bdist_dumb', + 'bdist_wininst', + ] + +__import__('distutils.command', globals(), locals(), distutils_all) + +__all__ = ['build', + 'config_compiler', + 'config', + 'build_src', + 'build_py', + 'build_ext', + 'build_clib', + 'build_scripts', + 'install', + 'install_data', + 'install_headers', + 'install_lib', + 'bdist_rpm', + 'sdist', + ] + distutils_all diff --git a/venv/Lib/site-packages/numpy/distutils/command/autodist.py b/venv/Lib/site-packages/numpy/distutils/command/autodist.py new file mode 100644 index 0000000..b72d0ca --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/command/autodist.py @@ -0,0 +1,148 @@ +"""This module implements additional tests ala autoconf which can be useful. + +""" +import textwrap + +# We put them here since they could be easily reused outside numpy.distutils + +def check_inline(cmd): + """Return the inline identifier (may be empty).""" + cmd._check_compiler() + body = textwrap.dedent(""" + #ifndef __cplusplus + static %(inline)s int static_func (void) + { + return 0; + } + %(inline)s int nostatic_func (void) + { + return 0; + } + #endif""") + + for kw in ['inline', '__inline__', '__inline']: + st = cmd.try_compile(body % {'inline': kw}, None, None) + if st: + return kw + + return '' + + +def check_restrict(cmd): + """Return the restrict identifier (may be empty).""" + cmd._check_compiler() + body = textwrap.dedent(""" + static int static_func (char * %(restrict)s a) + { + return 0; + } + """) + + for kw in ['restrict', '__restrict__', '__restrict']: + st = cmd.try_compile(body % {'restrict': kw}, None, None) + if st: + return kw + + return '' + + +def check_compiler_gcc(cmd): + """Check if the compiler is GCC.""" + + cmd._check_compiler() + body = textwrap.dedent(""" + int + main() + { + #if (! defined __GNUC__) + #error gcc required + #endif + return 0; + } + """) + return cmd.try_compile(body, None, None) + + +def check_gcc_version_at_least(cmd, major, minor=0, patchlevel=0): + """ + Check that the gcc version is at least the specified version.""" + + cmd._check_compiler() + version = '.'.join([str(major), str(minor), str(patchlevel)]) + body = textwrap.dedent(""" + int + main() + { + #if (! defined __GNUC__) || (__GNUC__ < %(major)d) || \\ + (__GNUC_MINOR__ < %(minor)d) || \\ + (__GNUC_PATCHLEVEL__ < %(patchlevel)d) + #error gcc >= %(version)s required + #endif + return 0; + } + """) + kw = {'version': version, 'major': major, 'minor': minor, + 'patchlevel': patchlevel} + + return cmd.try_compile(body % kw, None, None) + + +def check_gcc_function_attribute(cmd, attribute, name): + """Return True if the given function attribute is supported.""" + cmd._check_compiler() + body = textwrap.dedent(""" + #pragma GCC diagnostic error "-Wattributes" + #pragma clang diagnostic error "-Wattributes" + + int %s %s(void* unused) + { + return 0; + } + + int + main() + { + return 0; + } + """) % (attribute, name) + return cmd.try_compile(body, None, None) != 0 + + +def check_gcc_function_attribute_with_intrinsics(cmd, attribute, name, code, + include): + """Return True if the given function attribute is supported with + intrinsics.""" + cmd._check_compiler() + body = textwrap.dedent(""" + #include<%s> + int %s %s(void) + { + %s; + return 0; + } + + int + main() + { + return 0; + } + """) % (include, attribute, name, code) + return cmd.try_compile(body, None, None) != 0 + + +def check_gcc_variable_attribute(cmd, attribute): + """Return True if the given variable attribute is supported.""" + cmd._check_compiler() + body = textwrap.dedent(""" + #pragma GCC diagnostic error "-Wattributes" + #pragma clang diagnostic error "-Wattributes" + + int %s foo; + + int + main() + { + return 0; + } + """) % (attribute, ) + return cmd.try_compile(body, None, None) != 0 diff --git a/venv/Lib/site-packages/numpy/distutils/command/bdist_rpm.py b/venv/Lib/site-packages/numpy/distutils/command/bdist_rpm.py new file mode 100644 index 0000000..682e7a8 --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/command/bdist_rpm.py @@ -0,0 +1,22 @@ +import os +import sys +if 'setuptools' in sys.modules: + from setuptools.command.bdist_rpm import bdist_rpm as old_bdist_rpm +else: + from distutils.command.bdist_rpm import bdist_rpm as old_bdist_rpm + +class bdist_rpm(old_bdist_rpm): + + def _make_spec_file(self): + spec_file = old_bdist_rpm._make_spec_file(self) + + # Replace hardcoded setup.py script name + # with the real setup script name. + setup_py = os.path.basename(sys.argv[0]) + if setup_py == 'setup.py': + return spec_file + new_spec_file = [] + for line in spec_file: + line = line.replace('setup.py', setup_py) + new_spec_file.append(line) + return new_spec_file diff --git a/venv/Lib/site-packages/numpy/distutils/command/build.py b/venv/Lib/site-packages/numpy/distutils/command/build.py new file mode 100644 index 0000000..a4fda53 --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/command/build.py @@ -0,0 +1,61 @@ +import os +import sys +from distutils.command.build import build as old_build +from distutils.util import get_platform +from numpy.distutils.command.config_compiler import show_fortran_compilers + +class build(old_build): + + sub_commands = [('config_cc', lambda *args: True), + ('config_fc', lambda *args: True), + ('build_src', old_build.has_ext_modules), + ] + old_build.sub_commands + + user_options = old_build.user_options + [ + ('fcompiler=', None, + "specify the Fortran compiler type"), + ('warn-error', None, + "turn all warnings into errors (-Werror)"), + ('cpu-baseline=', None, + "specify a list of enabled baseline CPU optimizations"), + ('cpu-dispatch=', None, + "specify a list of dispatched CPU optimizations"), + ('disable-optimization', None, + "disable CPU optimized code(dispatch,simd,fast...)"), + ('simd-test=', None, + "specify a list of CPU optimizations to be tested against NumPy SIMD interface"), + ] + + help_options = old_build.help_options + [ + ('help-fcompiler', None, "list available Fortran compilers", + show_fortran_compilers), + ] + + def initialize_options(self): + old_build.initialize_options(self) + self.fcompiler = None + self.warn_error = False + self.cpu_baseline = "min" + self.cpu_dispatch = "max -xop -fma4" # drop AMD legacy features by default + self.disable_optimization = False + """ + the '_simd' module is a very large. Adding more dispatched features + will increase binary size and compile time. By default we minimize + the targeted features to those most commonly used by the NumPy SIMD interface(NPYV), + NOTE: any specified features will be ignored if they're: + - part of the baseline(--cpu-baseline) + - not part of dispatch-able features(--cpu-dispatch) + - not supported by compiler or platform + """ + self.simd_test = "BASELINE SSE2 SSE42 XOP FMA4 (FMA3 AVX2) AVX512F AVX512_SKX VSX VSX2 VSX3 NEON ASIMD" + + def finalize_options(self): + build_scripts = self.build_scripts + old_build.finalize_options(self) + plat_specifier = ".{}-{}.{}".format(get_platform(), *sys.version_info[:2]) + if build_scripts is None: + self.build_scripts = os.path.join(self.build_base, + 'scripts' + plat_specifier) + + def run(self): + old_build.run(self) diff --git a/venv/Lib/site-packages/numpy/distutils/command/build_clib.py b/venv/Lib/site-packages/numpy/distutils/command/build_clib.py new file mode 100644 index 0000000..1b3004c --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/command/build_clib.py @@ -0,0 +1,401 @@ +""" Modified version of build_clib that handles fortran source files. +""" +import os +from glob import glob +import shutil +from distutils.command.build_clib import build_clib as old_build_clib +from distutils.errors import DistutilsSetupError, DistutilsError, \ + DistutilsFileError + +from numpy.distutils import log +from distutils.dep_util import newer_group +from numpy.distutils.misc_util import ( + filter_sources, get_lib_source_files, get_numpy_include_dirs, + has_cxx_sources, has_f_sources, is_sequence +) +from numpy.distutils.ccompiler_opt import new_ccompiler_opt + +# Fix Python distutils bug sf #1718574: +_l = old_build_clib.user_options +for _i in range(len(_l)): + if _l[_i][0] in ['build-clib', 'build-temp']: + _l[_i] = (_l[_i][0] + '=',) + _l[_i][1:] +# + + +class build_clib(old_build_clib): + + description = "build C/C++/F libraries used by Python extensions" + + user_options = old_build_clib.user_options + [ + ('fcompiler=', None, + "specify the Fortran compiler type"), + ('inplace', 'i', 'Build in-place'), + ('parallel=', 'j', + "number of parallel jobs"), + ('warn-error', None, + "turn all warnings into errors (-Werror)"), + ('cpu-baseline=', None, + "specify a list of enabled baseline CPU optimizations"), + ('cpu-dispatch=', None, + "specify a list of dispatched CPU optimizations"), + ('disable-optimization', None, + "disable CPU optimized code(dispatch,simd,fast...)"), + ] + + boolean_options = old_build_clib.boolean_options + \ + ['inplace', 'warn-error', 'disable-optimization'] + + def initialize_options(self): + old_build_clib.initialize_options(self) + self.fcompiler = None + self.inplace = 0 + self.parallel = None + self.warn_error = None + self.cpu_baseline = None + self.cpu_dispatch = None + self.disable_optimization = None + + + def finalize_options(self): + if self.parallel: + try: + self.parallel = int(self.parallel) + except ValueError as e: + raise ValueError("--parallel/-j argument must be an integer") from e + old_build_clib.finalize_options(self) + self.set_undefined_options('build', + ('parallel', 'parallel'), + ('warn_error', 'warn_error'), + ('cpu_baseline', 'cpu_baseline'), + ('cpu_dispatch', 'cpu_dispatch'), + ('disable_optimization', 'disable_optimization') + ) + + def have_f_sources(self): + for (lib_name, build_info) in self.libraries: + if has_f_sources(build_info.get('sources', [])): + return True + return False + + def have_cxx_sources(self): + for (lib_name, build_info) in self.libraries: + if has_cxx_sources(build_info.get('sources', [])): + return True + return False + + def run(self): + if not self.libraries: + return + + # Make sure that library sources are complete. + languages = [] + + # Make sure that extension sources are complete. + self.run_command('build_src') + + for (lib_name, build_info) in self.libraries: + l = build_info.get('language', None) + if l and l not in languages: + languages.append(l) + + from distutils.ccompiler import new_compiler + self.compiler = new_compiler(compiler=self.compiler, + dry_run=self.dry_run, + force=self.force) + self.compiler.customize(self.distribution, + need_cxx=self.have_cxx_sources()) + + if self.warn_error: + self.compiler.compiler.append('-Werror') + self.compiler.compiler_so.append('-Werror') + + libraries = self.libraries + self.libraries = None + self.compiler.customize_cmd(self) + self.libraries = libraries + + self.compiler.show_customization() + + if not self.disable_optimization: + dispatch_hpath = os.path.join("numpy", "distutils", "include", "npy_cpu_dispatch_config.h") + dispatch_hpath = os.path.join(self.get_finalized_command("build_src").build_src, dispatch_hpath) + opt_cache_path = os.path.abspath( + os.path.join(self.build_temp, 'ccompiler_opt_cache_clib.py') + ) + self.compiler_opt = new_ccompiler_opt( + compiler=self.compiler, dispatch_hpath=dispatch_hpath, + cpu_baseline=self.cpu_baseline, cpu_dispatch=self.cpu_dispatch, + cache_path=opt_cache_path + ) + if not self.compiler_opt.is_cached(): + log.info("Detected changes on compiler optimizations, force rebuilding") + self.force = True + + import atexit + def report(): + log.info("\n########### CLIB COMPILER OPTIMIZATION ###########") + log.info(self.compiler_opt.report(full=True)) + + atexit.register(report) + + if self.have_f_sources(): + from numpy.distutils.fcompiler import new_fcompiler + self._f_compiler = new_fcompiler(compiler=self.fcompiler, + verbose=self.verbose, + dry_run=self.dry_run, + force=self.force, + requiref90='f90' in languages, + c_compiler=self.compiler) + if self._f_compiler is not None: + self._f_compiler.customize(self.distribution) + + libraries = self.libraries + self.libraries = None + self._f_compiler.customize_cmd(self) + self.libraries = libraries + + self._f_compiler.show_customization() + else: + self._f_compiler = None + + self.build_libraries(self.libraries) + + if self.inplace: + for l in self.distribution.installed_libraries: + libname = self.compiler.library_filename(l.name) + source = os.path.join(self.build_clib, libname) + target = os.path.join(l.target_dir, libname) + self.mkpath(l.target_dir) + shutil.copy(source, target) + + def get_source_files(self): + self.check_library_list(self.libraries) + filenames = [] + for lib in self.libraries: + filenames.extend(get_lib_source_files(lib)) + return filenames + + def build_libraries(self, libraries): + for (lib_name, build_info) in libraries: + self.build_a_library(build_info, lib_name, libraries) + + def build_a_library(self, build_info, lib_name, libraries): + # default compilers + compiler = self.compiler + fcompiler = self._f_compiler + + sources = build_info.get('sources') + if sources is None or not is_sequence(sources): + raise DistutilsSetupError(("in 'libraries' option (library '%s'), " + + "'sources' must be present and must be " + + "a list of source filenames") % lib_name) + sources = list(sources) + + c_sources, cxx_sources, f_sources, fmodule_sources \ + = filter_sources(sources) + requiref90 = not not fmodule_sources or \ + build_info.get('language', 'c') == 'f90' + + # save source type information so that build_ext can use it. + source_languages = [] + if c_sources: + source_languages.append('c') + if cxx_sources: + source_languages.append('c++') + if requiref90: + source_languages.append('f90') + elif f_sources: + source_languages.append('f77') + build_info['source_languages'] = source_languages + + lib_file = compiler.library_filename(lib_name, + output_dir=self.build_clib) + depends = sources + build_info.get('depends', []) + if not (self.force or newer_group(depends, lib_file, 'newer')): + log.debug("skipping '%s' library (up-to-date)", lib_name) + return + else: + log.info("building '%s' library", lib_name) + + config_fc = build_info.get('config_fc', {}) + if fcompiler is not None and config_fc: + log.info('using additional config_fc from setup script ' + 'for fortran compiler: %s' + % (config_fc,)) + from numpy.distutils.fcompiler import new_fcompiler + fcompiler = new_fcompiler(compiler=fcompiler.compiler_type, + verbose=self.verbose, + dry_run=self.dry_run, + force=self.force, + requiref90=requiref90, + c_compiler=self.compiler) + if fcompiler is not None: + dist = self.distribution + base_config_fc = dist.get_option_dict('config_fc').copy() + base_config_fc.update(config_fc) + fcompiler.customize(base_config_fc) + + # check availability of Fortran compilers + if (f_sources or fmodule_sources) and fcompiler is None: + raise DistutilsError("library %s has Fortran sources" + " but no Fortran compiler found" % (lib_name)) + + if fcompiler is not None: + fcompiler.extra_f77_compile_args = build_info.get( + 'extra_f77_compile_args') or [] + fcompiler.extra_f90_compile_args = build_info.get( + 'extra_f90_compile_args') or [] + + macros = build_info.get('macros') + if macros is None: + macros = [] + include_dirs = build_info.get('include_dirs') + if include_dirs is None: + include_dirs = [] + extra_postargs = build_info.get('extra_compiler_args') or [] + + include_dirs.extend(get_numpy_include_dirs()) + # where compiled F90 module files are: + module_dirs = build_info.get('module_dirs') or [] + module_build_dir = os.path.dirname(lib_file) + if requiref90: + self.mkpath(module_build_dir) + + if compiler.compiler_type == 'msvc': + # this hack works around the msvc compiler attributes + # problem, msvc uses its own convention :( + c_sources += cxx_sources + cxx_sources = [] + + # filtering C dispatch-table sources when optimization is not disabled, + # otherwise treated as normal sources. + copt_c_sources = [] + copt_baseline_flags = [] + copt_macros = [] + if not self.disable_optimization: + bsrc_dir = self.get_finalized_command("build_src").build_src + dispatch_hpath = os.path.join("numpy", "distutils", "include") + dispatch_hpath = os.path.join(bsrc_dir, dispatch_hpath) + include_dirs.append(dispatch_hpath) + + copt_build_src = None if self.inplace else bsrc_dir + copt_c_sources = [ + c_sources.pop(c_sources.index(src)) + for src in c_sources[:] if src.endswith(".dispatch.c") + ] + copt_baseline_flags = self.compiler_opt.cpu_baseline_flags() + else: + copt_macros.append(("NPY_DISABLE_OPTIMIZATION", 1)) + + objects = [] + if copt_c_sources: + log.info("compiling C dispatch-able sources") + objects += self.compiler_opt.try_dispatch(copt_c_sources, + output_dir=self.build_temp, + src_dir=copt_build_src, + macros=macros + copt_macros, + include_dirs=include_dirs, + debug=self.debug, + extra_postargs=extra_postargs) + + if c_sources: + log.info("compiling C sources") + objects += compiler.compile(c_sources, + output_dir=self.build_temp, + macros=macros + copt_macros, + include_dirs=include_dirs, + debug=self.debug, + extra_postargs=extra_postargs + copt_baseline_flags) + + if cxx_sources: + log.info("compiling C++ sources") + cxx_compiler = compiler.cxx_compiler() + cxx_objects = cxx_compiler.compile(cxx_sources, + output_dir=self.build_temp, + macros=macros + copt_macros, + include_dirs=include_dirs, + debug=self.debug, + extra_postargs=extra_postargs + copt_baseline_flags) + objects.extend(cxx_objects) + + if f_sources or fmodule_sources: + extra_postargs = [] + f_objects = [] + + if requiref90: + if fcompiler.module_dir_switch is None: + existing_modules = glob('*.mod') + extra_postargs += fcompiler.module_options( + module_dirs, module_build_dir) + + if fmodule_sources: + log.info("compiling Fortran 90 module sources") + f_objects += fcompiler.compile(fmodule_sources, + output_dir=self.build_temp, + macros=macros, + include_dirs=include_dirs, + debug=self.debug, + extra_postargs=extra_postargs) + + if requiref90 and self._f_compiler.module_dir_switch is None: + # move new compiled F90 module files to module_build_dir + for f in glob('*.mod'): + if f in existing_modules: + continue + t = os.path.join(module_build_dir, f) + if os.path.abspath(f) == os.path.abspath(t): + continue + if os.path.isfile(t): + os.remove(t) + try: + self.move_file(f, module_build_dir) + except DistutilsFileError: + log.warn('failed to move %r to %r' + % (f, module_build_dir)) + + if f_sources: + log.info("compiling Fortran sources") + f_objects += fcompiler.compile(f_sources, + output_dir=self.build_temp, + macros=macros, + include_dirs=include_dirs, + debug=self.debug, + extra_postargs=extra_postargs) + else: + f_objects = [] + + if f_objects and not fcompiler.can_ccompiler_link(compiler): + # Default linker cannot link Fortran object files, and results + # need to be wrapped later. Instead of creating a real static + # library, just keep track of the object files. + listfn = os.path.join(self.build_clib, + lib_name + '.fobjects') + with open(listfn, 'w') as f: + f.write("\n".join(os.path.abspath(obj) for obj in f_objects)) + + listfn = os.path.join(self.build_clib, + lib_name + '.cobjects') + with open(listfn, 'w') as f: + f.write("\n".join(os.path.abspath(obj) for obj in objects)) + + # create empty "library" file for dependency tracking + lib_fname = os.path.join(self.build_clib, + lib_name + compiler.static_lib_extension) + with open(lib_fname, 'wb') as f: + pass + else: + # assume that default linker is suitable for + # linking Fortran object files + objects.extend(f_objects) + compiler.create_static_lib(objects, lib_name, + output_dir=self.build_clib, + debug=self.debug) + + # fix library dependencies + clib_libraries = build_info.get('libraries', []) + for lname, binfo in libraries: + if lname in clib_libraries: + clib_libraries.extend(binfo.get('libraries', [])) + if clib_libraries: + build_info['libraries'] = clib_libraries diff --git a/venv/Lib/site-packages/numpy/distutils/command/build_ext.py b/venv/Lib/site-packages/numpy/distutils/command/build_ext.py new file mode 100644 index 0000000..99c6be8 --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/command/build_ext.py @@ -0,0 +1,678 @@ +""" Modified version of build_ext that handles fortran source files. + +""" +import os +import subprocess +from glob import glob + +from distutils.dep_util import newer_group +from distutils.command.build_ext import build_ext as old_build_ext +from distutils.errors import DistutilsFileError, DistutilsSetupError,\ + DistutilsError +from distutils.file_util import copy_file + +from numpy.distutils import log +from numpy.distutils.exec_command import filepath_from_subprocess_output +from numpy.distutils.system_info import combine_paths +from numpy.distutils.misc_util import ( + filter_sources, get_ext_source_files, get_numpy_include_dirs, + has_cxx_sources, has_f_sources, is_sequence +) +from numpy.distutils.command.config_compiler import show_fortran_compilers +from numpy.distutils.ccompiler_opt import new_ccompiler_opt, CCompilerOpt + +class build_ext (old_build_ext): + + description = "build C/C++/F extensions (compile/link to build directory)" + + user_options = old_build_ext.user_options + [ + ('fcompiler=', None, + "specify the Fortran compiler type"), + ('parallel=', 'j', + "number of parallel jobs"), + ('warn-error', None, + "turn all warnings into errors (-Werror)"), + ('cpu-baseline=', None, + "specify a list of enabled baseline CPU optimizations"), + ('cpu-dispatch=', None, + "specify a list of dispatched CPU optimizations"), + ('disable-optimization', None, + "disable CPU optimized code(dispatch,simd,fast...)"), + ('simd-test=', None, + "specify a list of CPU optimizations to be tested against NumPy SIMD interface"), + ] + + help_options = old_build_ext.help_options + [ + ('help-fcompiler', None, "list available Fortran compilers", + show_fortran_compilers), + ] + + boolean_options = old_build_ext.boolean_options + ['warn-error', 'disable-optimization'] + + def initialize_options(self): + old_build_ext.initialize_options(self) + self.fcompiler = None + self.parallel = None + self.warn_error = None + self.cpu_baseline = None + self.cpu_dispatch = None + self.disable_optimization = None + self.simd_test = None + + def finalize_options(self): + if self.parallel: + try: + self.parallel = int(self.parallel) + except ValueError as e: + raise ValueError("--parallel/-j argument must be an integer") from e + + # Ensure that self.include_dirs and self.distribution.include_dirs + # refer to the same list object. finalize_options will modify + # self.include_dirs, but self.distribution.include_dirs is used + # during the actual build. + # self.include_dirs is None unless paths are specified with + # --include-dirs. + # The include paths will be passed to the compiler in the order: + # numpy paths, --include-dirs paths, Python include path. + if isinstance(self.include_dirs, str): + self.include_dirs = self.include_dirs.split(os.pathsep) + incl_dirs = self.include_dirs or [] + if self.distribution.include_dirs is None: + self.distribution.include_dirs = [] + self.include_dirs = self.distribution.include_dirs + self.include_dirs.extend(incl_dirs) + + old_build_ext.finalize_options(self) + self.set_undefined_options('build', + ('parallel', 'parallel'), + ('warn_error', 'warn_error'), + ('cpu_baseline', 'cpu_baseline'), + ('cpu_dispatch', 'cpu_dispatch'), + ('disable_optimization', 'disable_optimization'), + ('simd_test', 'simd_test') + ) + CCompilerOpt.conf_target_groups["simd_test"] = self.simd_test + + def run(self): + if not self.extensions: + return + + # Make sure that extension sources are complete. + self.run_command('build_src') + + if self.distribution.has_c_libraries(): + if self.inplace: + if self.distribution.have_run.get('build_clib'): + log.warn('build_clib already run, it is too late to ' + 'ensure in-place build of build_clib') + build_clib = self.distribution.get_command_obj( + 'build_clib') + else: + build_clib = self.distribution.get_command_obj( + 'build_clib') + build_clib.inplace = 1 + build_clib.ensure_finalized() + build_clib.run() + self.distribution.have_run['build_clib'] = 1 + + else: + self.run_command('build_clib') + build_clib = self.get_finalized_command('build_clib') + self.library_dirs.append(build_clib.build_clib) + else: + build_clib = None + + # Not including C libraries to the list of + # extension libraries automatically to prevent + # bogus linking commands. Extensions must + # explicitly specify the C libraries that they use. + + from distutils.ccompiler import new_compiler + from numpy.distutils.fcompiler import new_fcompiler + + compiler_type = self.compiler + # Initialize C compiler: + self.compiler = new_compiler(compiler=compiler_type, + verbose=self.verbose, + dry_run=self.dry_run, + force=self.force) + self.compiler.customize(self.distribution) + self.compiler.customize_cmd(self) + + if self.warn_error: + self.compiler.compiler.append('-Werror') + self.compiler.compiler_so.append('-Werror') + + self.compiler.show_customization() + + if not self.disable_optimization: + dispatch_hpath = os.path.join("numpy", "distutils", "include", "npy_cpu_dispatch_config.h") + dispatch_hpath = os.path.join(self.get_finalized_command("build_src").build_src, dispatch_hpath) + opt_cache_path = os.path.abspath( + os.path.join(self.build_temp, 'ccompiler_opt_cache_ext.py') + ) + self.compiler_opt = new_ccompiler_opt( + compiler=self.compiler, dispatch_hpath=dispatch_hpath, + cpu_baseline=self.cpu_baseline, cpu_dispatch=self.cpu_dispatch, + cache_path=opt_cache_path + ) + if not self.compiler_opt.is_cached(): + log.info("Detected changes on compiler optimizations, force rebuilding") + self.force = True + + import atexit + def report(): + log.info("\n########### EXT COMPILER OPTIMIZATION ###########") + log.info(self.compiler_opt.report(full=True)) + atexit.register(report) + + # Setup directory for storing generated extra DLL files on Windows + self.extra_dll_dir = os.path.join(self.build_temp, '.libs') + if not os.path.isdir(self.extra_dll_dir): + os.makedirs(self.extra_dll_dir) + + # Create mapping of libraries built by build_clib: + clibs = {} + if build_clib is not None: + for libname, build_info in build_clib.libraries or []: + if libname in clibs and clibs[libname] != build_info: + log.warn('library %r defined more than once,' + ' overwriting build_info\n%s... \nwith\n%s...' + % (libname, repr(clibs[libname])[:300], repr(build_info)[:300])) + clibs[libname] = build_info + # .. and distribution libraries: + for libname, build_info in self.distribution.libraries or []: + if libname in clibs: + # build_clib libraries have a precedence before distribution ones + continue + clibs[libname] = build_info + + # Determine if C++/Fortran 77/Fortran 90 compilers are needed. + # Update extension libraries, library_dirs, and macros. + all_languages = set() + for ext in self.extensions: + ext_languages = set() + c_libs = [] + c_lib_dirs = [] + macros = [] + for libname in ext.libraries: + if libname in clibs: + binfo = clibs[libname] + c_libs += binfo.get('libraries', []) + c_lib_dirs += binfo.get('library_dirs', []) + for m in binfo.get('macros', []): + if m not in macros: + macros.append(m) + + for l in clibs.get(libname, {}).get('source_languages', []): + ext_languages.add(l) + if c_libs: + new_c_libs = ext.libraries + c_libs + log.info('updating extension %r libraries from %r to %r' + % (ext.name, ext.libraries, new_c_libs)) + ext.libraries = new_c_libs + ext.library_dirs = ext.library_dirs + c_lib_dirs + if macros: + log.info('extending extension %r defined_macros with %r' + % (ext.name, macros)) + ext.define_macros = ext.define_macros + macros + + # determine extension languages + if has_f_sources(ext.sources): + ext_languages.add('f77') + if has_cxx_sources(ext.sources): + ext_languages.add('c++') + l = ext.language or self.compiler.detect_language(ext.sources) + if l: + ext_languages.add(l) + # reset language attribute for choosing proper linker + if 'c++' in ext_languages: + ext_language = 'c++' + elif 'f90' in ext_languages: + ext_language = 'f90' + elif 'f77' in ext_languages: + ext_language = 'f77' + else: + ext_language = 'c' # default + if l and l != ext_language and ext.language: + log.warn('resetting extension %r language from %r to %r.' % + (ext.name, l, ext_language)) + ext.language = ext_language + # global language + all_languages.update(ext_languages) + + need_f90_compiler = 'f90' in all_languages + need_f77_compiler = 'f77' in all_languages + need_cxx_compiler = 'c++' in all_languages + + # Initialize C++ compiler: + if need_cxx_compiler: + self._cxx_compiler = new_compiler(compiler=compiler_type, + verbose=self.verbose, + dry_run=self.dry_run, + force=self.force) + compiler = self._cxx_compiler + compiler.customize(self.distribution, need_cxx=need_cxx_compiler) + compiler.customize_cmd(self) + compiler.show_customization() + self._cxx_compiler = compiler.cxx_compiler() + else: + self._cxx_compiler = None + + # Initialize Fortran 77 compiler: + if need_f77_compiler: + ctype = self.fcompiler + self._f77_compiler = new_fcompiler(compiler=self.fcompiler, + verbose=self.verbose, + dry_run=self.dry_run, + force=self.force, + requiref90=False, + c_compiler=self.compiler) + fcompiler = self._f77_compiler + if fcompiler: + ctype = fcompiler.compiler_type + fcompiler.customize(self.distribution) + if fcompiler and fcompiler.get_version(): + fcompiler.customize_cmd(self) + fcompiler.show_customization() + else: + self.warn('f77_compiler=%s is not available.' % + (ctype)) + self._f77_compiler = None + else: + self._f77_compiler = None + + # Initialize Fortran 90 compiler: + if need_f90_compiler: + ctype = self.fcompiler + self._f90_compiler = new_fcompiler(compiler=self.fcompiler, + verbose=self.verbose, + dry_run=self.dry_run, + force=self.force, + requiref90=True, + c_compiler=self.compiler) + fcompiler = self._f90_compiler + if fcompiler: + ctype = fcompiler.compiler_type + fcompiler.customize(self.distribution) + if fcompiler and fcompiler.get_version(): + fcompiler.customize_cmd(self) + fcompiler.show_customization() + else: + self.warn('f90_compiler=%s is not available.' % + (ctype)) + self._f90_compiler = None + else: + self._f90_compiler = None + + # Build extensions + self.build_extensions() + + # Copy over any extra DLL files + # FIXME: In the case where there are more than two packages, + # we blindly assume that both packages need all of the libraries, + # resulting in a larger wheel than is required. This should be fixed, + # but it's so rare that I won't bother to handle it. + pkg_roots = { + self.get_ext_fullname(ext.name).split('.')[0] + for ext in self.extensions + } + for pkg_root in pkg_roots: + shared_lib_dir = os.path.join(pkg_root, '.libs') + if not self.inplace: + shared_lib_dir = os.path.join(self.build_lib, shared_lib_dir) + for fn in os.listdir(self.extra_dll_dir): + if not os.path.isdir(shared_lib_dir): + os.makedirs(shared_lib_dir) + if not fn.lower().endswith('.dll'): + continue + runtime_lib = os.path.join(self.extra_dll_dir, fn) + copy_file(runtime_lib, shared_lib_dir) + + def swig_sources(self, sources, extensions=None): + # Do nothing. Swig sources have been handled in build_src command. + return sources + + def build_extension(self, ext): + sources = ext.sources + if sources is None or not is_sequence(sources): + raise DistutilsSetupError( + ("in 'ext_modules' option (extension '%s'), " + + "'sources' must be present and must be " + + "a list of source filenames") % ext.name) + sources = list(sources) + + if not sources: + return + + fullname = self.get_ext_fullname(ext.name) + if self.inplace: + modpath = fullname.split('.') + package = '.'.join(modpath[0:-1]) + base = modpath[-1] + build_py = self.get_finalized_command('build_py') + package_dir = build_py.get_package_dir(package) + ext_filename = os.path.join(package_dir, + self.get_ext_filename(base)) + else: + ext_filename = os.path.join(self.build_lib, + self.get_ext_filename(fullname)) + depends = sources + ext.depends + + if not (self.force or newer_group(depends, ext_filename, 'newer')): + log.debug("skipping '%s' extension (up-to-date)", ext.name) + return + else: + log.info("building '%s' extension", ext.name) + + extra_args = ext.extra_compile_args or [] + macros = ext.define_macros[:] + for undef in ext.undef_macros: + macros.append((undef,)) + + c_sources, cxx_sources, f_sources, fmodule_sources = \ + filter_sources(ext.sources) + + if self.compiler.compiler_type == 'msvc': + if cxx_sources: + # Needed to compile kiva.agg._agg extension. + extra_args.append('/Zm1000') + # this hack works around the msvc compiler attributes + # problem, msvc uses its own convention :( + c_sources += cxx_sources + cxx_sources = [] + + # Set Fortran/C++ compilers for compilation and linking. + if ext.language == 'f90': + fcompiler = self._f90_compiler + elif ext.language == 'f77': + fcompiler = self._f77_compiler + else: # in case ext.language is c++, for instance + fcompiler = self._f90_compiler or self._f77_compiler + if fcompiler is not None: + fcompiler.extra_f77_compile_args = (ext.extra_f77_compile_args or []) if hasattr( + ext, 'extra_f77_compile_args') else [] + fcompiler.extra_f90_compile_args = (ext.extra_f90_compile_args or []) if hasattr( + ext, 'extra_f90_compile_args') else [] + cxx_compiler = self._cxx_compiler + + # check for the availability of required compilers + if cxx_sources and cxx_compiler is None: + raise DistutilsError("extension %r has C++ sources" + "but no C++ compiler found" % (ext.name)) + if (f_sources or fmodule_sources) and fcompiler is None: + raise DistutilsError("extension %r has Fortran sources " + "but no Fortran compiler found" % (ext.name)) + if ext.language in ['f77', 'f90'] and fcompiler is None: + self.warn("extension %r has Fortran libraries " + "but no Fortran linker found, using default linker" % (ext.name)) + if ext.language == 'c++' and cxx_compiler is None: + self.warn("extension %r has C++ libraries " + "but no C++ linker found, using default linker" % (ext.name)) + + kws = {'depends': ext.depends} + output_dir = self.build_temp + + include_dirs = ext.include_dirs + get_numpy_include_dirs() + + # filtering C dispatch-table sources when optimization is not disabled, + # otherwise treated as normal sources. + copt_c_sources = [] + copt_baseline_flags = [] + copt_macros = [] + if not self.disable_optimization: + bsrc_dir = self.get_finalized_command("build_src").build_src + dispatch_hpath = os.path.join("numpy", "distutils", "include") + dispatch_hpath = os.path.join(bsrc_dir, dispatch_hpath) + include_dirs.append(dispatch_hpath) + + copt_build_src = None if self.inplace else bsrc_dir + copt_c_sources = [ + c_sources.pop(c_sources.index(src)) + for src in c_sources[:] if src.endswith(".dispatch.c") + ] + copt_baseline_flags = self.compiler_opt.cpu_baseline_flags() + else: + copt_macros.append(("NPY_DISABLE_OPTIMIZATION", 1)) + + c_objects = [] + if copt_c_sources: + log.info("compiling C dispatch-able sources") + c_objects += self.compiler_opt.try_dispatch(copt_c_sources, + output_dir=output_dir, + src_dir=copt_build_src, + macros=macros + copt_macros, + include_dirs=include_dirs, + debug=self.debug, + extra_postargs=extra_args, + **kws) + if c_sources: + log.info("compiling C sources") + c_objects += self.compiler.compile(c_sources, + output_dir=output_dir, + macros=macros + copt_macros, + include_dirs=include_dirs, + debug=self.debug, + extra_postargs=extra_args + copt_baseline_flags, + **kws) + if cxx_sources: + log.info("compiling C++ sources") + c_objects += cxx_compiler.compile(cxx_sources, + output_dir=output_dir, + macros=macros + copt_macros, + include_dirs=include_dirs, + debug=self.debug, + extra_postargs=extra_args + copt_baseline_flags, + **kws) + + extra_postargs = [] + f_objects = [] + if fmodule_sources: + log.info("compiling Fortran 90 module sources") + module_dirs = ext.module_dirs[:] + module_build_dir = os.path.join( + self.build_temp, os.path.dirname( + self.get_ext_filename(fullname))) + + self.mkpath(module_build_dir) + if fcompiler.module_dir_switch is None: + existing_modules = glob('*.mod') + extra_postargs += fcompiler.module_options( + module_dirs, module_build_dir) + f_objects += fcompiler.compile(fmodule_sources, + output_dir=self.build_temp, + macros=macros, + include_dirs=include_dirs, + debug=self.debug, + extra_postargs=extra_postargs, + depends=ext.depends) + + if fcompiler.module_dir_switch is None: + for f in glob('*.mod'): + if f in existing_modules: + continue + t = os.path.join(module_build_dir, f) + if os.path.abspath(f) == os.path.abspath(t): + continue + if os.path.isfile(t): + os.remove(t) + try: + self.move_file(f, module_build_dir) + except DistutilsFileError: + log.warn('failed to move %r to %r' % + (f, module_build_dir)) + if f_sources: + log.info("compiling Fortran sources") + f_objects += fcompiler.compile(f_sources, + output_dir=self.build_temp, + macros=macros, + include_dirs=include_dirs, + debug=self.debug, + extra_postargs=extra_postargs, + depends=ext.depends) + + if f_objects and not fcompiler.can_ccompiler_link(self.compiler): + unlinkable_fobjects = f_objects + objects = c_objects + else: + unlinkable_fobjects = [] + objects = c_objects + f_objects + + if ext.extra_objects: + objects.extend(ext.extra_objects) + extra_args = ext.extra_link_args or [] + libraries = self.get_libraries(ext)[:] + library_dirs = ext.library_dirs[:] + + linker = self.compiler.link_shared_object + # Always use system linker when using MSVC compiler. + if self.compiler.compiler_type in ('msvc', 'intelw', 'intelemw'): + # expand libraries with fcompiler libraries as we are + # not using fcompiler linker + self._libs_with_msvc_and_fortran( + fcompiler, libraries, library_dirs) + + elif ext.language in ['f77', 'f90'] and fcompiler is not None: + linker = fcompiler.link_shared_object + if ext.language == 'c++' and cxx_compiler is not None: + linker = cxx_compiler.link_shared_object + + if fcompiler is not None: + objects, libraries = self._process_unlinkable_fobjects( + objects, libraries, + fcompiler, library_dirs, + unlinkable_fobjects) + + linker(objects, ext_filename, + libraries=libraries, + library_dirs=library_dirs, + runtime_library_dirs=ext.runtime_library_dirs, + extra_postargs=extra_args, + export_symbols=self.get_export_symbols(ext), + debug=self.debug, + build_temp=self.build_temp, + target_lang=ext.language) + + def _add_dummy_mingwex_sym(self, c_sources): + build_src = self.get_finalized_command("build_src").build_src + build_clib = self.get_finalized_command("build_clib").build_clib + objects = self.compiler.compile([os.path.join(build_src, + "gfortran_vs2003_hack.c")], + output_dir=self.build_temp) + self.compiler.create_static_lib( + objects, "_gfortran_workaround", output_dir=build_clib, debug=self.debug) + + def _process_unlinkable_fobjects(self, objects, libraries, + fcompiler, library_dirs, + unlinkable_fobjects): + libraries = list(libraries) + objects = list(objects) + unlinkable_fobjects = list(unlinkable_fobjects) + + # Expand possible fake static libraries to objects; + # make sure to iterate over a copy of the list as + # "fake" libraries will be removed as they are + # enountered + for lib in libraries[:]: + for libdir in library_dirs: + fake_lib = os.path.join(libdir, lib + '.fobjects') + if os.path.isfile(fake_lib): + # Replace fake static library + libraries.remove(lib) + with open(fake_lib, 'r') as f: + unlinkable_fobjects.extend(f.read().splitlines()) + + # Expand C objects + c_lib = os.path.join(libdir, lib + '.cobjects') + with open(c_lib, 'r') as f: + objects.extend(f.read().splitlines()) + + # Wrap unlinkable objects to a linkable one + if unlinkable_fobjects: + fobjects = [os.path.abspath(obj) for obj in unlinkable_fobjects] + wrapped = fcompiler.wrap_unlinkable_objects( + fobjects, output_dir=self.build_temp, + extra_dll_dir=self.extra_dll_dir) + objects.extend(wrapped) + + return objects, libraries + + def _libs_with_msvc_and_fortran(self, fcompiler, c_libraries, + c_library_dirs): + if fcompiler is None: + return + + for libname in c_libraries: + if libname.startswith('msvc'): + continue + fileexists = False + for libdir in c_library_dirs or []: + libfile = os.path.join(libdir, '%s.lib' % (libname)) + if os.path.isfile(libfile): + fileexists = True + break + if fileexists: + continue + # make g77-compiled static libs available to MSVC + fileexists = False + for libdir in c_library_dirs: + libfile = os.path.join(libdir, 'lib%s.a' % (libname)) + if os.path.isfile(libfile): + # copy libname.a file to name.lib so that MSVC linker + # can find it + libfile2 = os.path.join(self.build_temp, libname + '.lib') + copy_file(libfile, libfile2) + if self.build_temp not in c_library_dirs: + c_library_dirs.append(self.build_temp) + fileexists = True + break + if fileexists: + continue + log.warn('could not find library %r in directories %s' + % (libname, c_library_dirs)) + + # Always use system linker when using MSVC compiler. + f_lib_dirs = [] + for dir in fcompiler.library_dirs: + # correct path when compiling in Cygwin but with normal Win + # Python + if dir.startswith('/usr/lib'): + try: + dir = subprocess.check_output(['cygpath', '-w', dir]) + except (OSError, subprocess.CalledProcessError): + pass + else: + dir = filepath_from_subprocess_output(dir) + f_lib_dirs.append(dir) + c_library_dirs.extend(f_lib_dirs) + + # make g77-compiled static libs available to MSVC + for lib in fcompiler.libraries: + if not lib.startswith('msvc'): + c_libraries.append(lib) + p = combine_paths(f_lib_dirs, 'lib' + lib + '.a') + if p: + dst_name = os.path.join(self.build_temp, lib + '.lib') + if not os.path.isfile(dst_name): + copy_file(p[0], dst_name) + if self.build_temp not in c_library_dirs: + c_library_dirs.append(self.build_temp) + + def get_source_files(self): + self.check_extensions_list(self.extensions) + filenames = [] + for ext in self.extensions: + filenames.extend(get_ext_source_files(ext)) + return filenames + + def get_outputs(self): + self.check_extensions_list(self.extensions) + + outputs = [] + for ext in self.extensions: + if not ext.sources: + continue + fullname = self.get_ext_fullname(ext.name) + outputs.append(os.path.join(self.build_lib, + self.get_ext_filename(fullname))) + return outputs diff --git a/venv/Lib/site-packages/numpy/distutils/command/build_py.py b/venv/Lib/site-packages/numpy/distutils/command/build_py.py new file mode 100644 index 0000000..d30dc5b --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/command/build_py.py @@ -0,0 +1,31 @@ +from distutils.command.build_py import build_py as old_build_py +from numpy.distutils.misc_util import is_string + +class build_py(old_build_py): + + def run(self): + build_src = self.get_finalized_command('build_src') + if build_src.py_modules_dict and self.packages is None: + self.packages = list(build_src.py_modules_dict.keys ()) + old_build_py.run(self) + + def find_package_modules(self, package, package_dir): + modules = old_build_py.find_package_modules(self, package, package_dir) + + # Find build_src generated *.py files. + build_src = self.get_finalized_command('build_src') + modules += build_src.py_modules_dict.get(package, []) + + return modules + + def find_modules(self): + old_py_modules = self.py_modules[:] + new_py_modules = [_m for _m in self.py_modules if is_string(_m)] + self.py_modules[:] = new_py_modules + modules = old_build_py.find_modules(self) + self.py_modules[:] = old_py_modules + + return modules + + # XXX: Fix find_source_files for item in py_modules such that item is 3-tuple + # and item[2] is source file. diff --git a/venv/Lib/site-packages/numpy/distutils/command/build_scripts.py b/venv/Lib/site-packages/numpy/distutils/command/build_scripts.py new file mode 100644 index 0000000..d5cadb2 --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/command/build_scripts.py @@ -0,0 +1,49 @@ +""" Modified version of build_scripts that handles building scripts from functions. + +""" +from distutils.command.build_scripts import build_scripts as old_build_scripts +from numpy.distutils import log +from numpy.distutils.misc_util import is_string + +class build_scripts(old_build_scripts): + + def generate_scripts(self, scripts): + new_scripts = [] + func_scripts = [] + for script in scripts: + if is_string(script): + new_scripts.append(script) + else: + func_scripts.append(script) + if not func_scripts: + return new_scripts + + build_dir = self.build_dir + self.mkpath(build_dir) + for func in func_scripts: + script = func(build_dir) + if not script: + continue + if is_string(script): + log.info(" adding '%s' to scripts" % (script,)) + new_scripts.append(script) + else: + [log.info(" adding '%s' to scripts" % (s,)) for s in script] + new_scripts.extend(list(script)) + return new_scripts + + def run (self): + if not self.scripts: + return + + self.scripts = self.generate_scripts(self.scripts) + # Now make sure that the distribution object has this list of scripts. + # setuptools' develop command requires that this be a list of filenames, + # not functions. + self.distribution.scripts = self.scripts + + return old_build_scripts.run(self) + + def get_source_files(self): + from numpy.distutils.misc_util import get_script_files + return get_script_files(self.scripts) diff --git a/venv/Lib/site-packages/numpy/distutils/command/build_src.py b/venv/Lib/site-packages/numpy/distutils/command/build_src.py new file mode 100644 index 0000000..303d619 --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/command/build_src.py @@ -0,0 +1,773 @@ +""" Build swig and f2py sources. +""" +import os +import re +import sys +import shlex +import copy + +from distutils.command import build_ext +from distutils.dep_util import newer_group, newer +from distutils.util import get_platform +from distutils.errors import DistutilsError, DistutilsSetupError + + +# this import can't be done here, as it uses numpy stuff only available +# after it's installed +#import numpy.f2py +from numpy.distutils import log +from numpy.distutils.misc_util import ( + fortran_ext_match, appendpath, is_string, is_sequence, get_cmd + ) +from numpy.distutils.from_template import process_file as process_f_file +from numpy.distutils.conv_template import process_file as process_c_file + +def subst_vars(target, source, d): + """Substitute any occurrence of @foo@ by d['foo'] from source file into + target.""" + var = re.compile('@([a-zA-Z_]+)@') + with open(source, 'r') as fs: + with open(target, 'w') as ft: + for l in fs: + m = var.search(l) + if m: + ft.write(l.replace('@%s@' % m.group(1), d[m.group(1)])) + else: + ft.write(l) + +class build_src(build_ext.build_ext): + + description = "build sources from SWIG, F2PY files or a function" + + user_options = [ + ('build-src=', 'd', "directory to \"build\" sources to"), + ('f2py-opts=', None, "list of f2py command line options"), + ('swig=', None, "path to the SWIG executable"), + ('swig-opts=', None, "list of SWIG command line options"), + ('swig-cpp', None, "make SWIG create C++ files (default is autodetected from sources)"), + ('f2pyflags=', None, "additional flags to f2py (use --f2py-opts= instead)"), # obsolete + ('swigflags=', None, "additional flags to swig (use --swig-opts= instead)"), # obsolete + ('force', 'f', "forcibly build everything (ignore file timestamps)"), + ('inplace', 'i', + "ignore build-lib and put compiled extensions into the source " + + "directory alongside your pure Python modules"), + ('verbose-cfg', None, + "change logging level from WARN to INFO which will show all " + + "compiler output") + ] + + boolean_options = ['force', 'inplace', 'verbose-cfg'] + + help_options = [] + + def initialize_options(self): + self.extensions = None + self.package = None + self.py_modules = None + self.py_modules_dict = None + self.build_src = None + self.build_lib = None + self.build_base = None + self.force = None + self.inplace = None + self.package_dir = None + self.f2pyflags = None # obsolete + self.f2py_opts = None + self.swigflags = None # obsolete + self.swig_opts = None + self.swig_cpp = None + self.swig = None + self.verbose_cfg = None + + def finalize_options(self): + self.set_undefined_options('build', + ('build_base', 'build_base'), + ('build_lib', 'build_lib'), + ('force', 'force')) + if self.package is None: + self.package = self.distribution.ext_package + self.extensions = self.distribution.ext_modules + self.libraries = self.distribution.libraries or [] + self.py_modules = self.distribution.py_modules or [] + self.data_files = self.distribution.data_files or [] + + if self.build_src is None: + plat_specifier = ".{}-{}.{}".format(get_platform(), *sys.version_info[:2]) + self.build_src = os.path.join(self.build_base, 'src'+plat_specifier) + + # py_modules_dict is used in build_py.find_package_modules + self.py_modules_dict = {} + + if self.f2pyflags: + if self.f2py_opts: + log.warn('ignoring --f2pyflags as --f2py-opts already used') + else: + self.f2py_opts = self.f2pyflags + self.f2pyflags = None + if self.f2py_opts is None: + self.f2py_opts = [] + else: + self.f2py_opts = shlex.split(self.f2py_opts) + + if self.swigflags: + if self.swig_opts: + log.warn('ignoring --swigflags as --swig-opts already used') + else: + self.swig_opts = self.swigflags + self.swigflags = None + + if self.swig_opts is None: + self.swig_opts = [] + else: + self.swig_opts = shlex.split(self.swig_opts) + + # use options from build_ext command + build_ext = self.get_finalized_command('build_ext') + if self.inplace is None: + self.inplace = build_ext.inplace + if self.swig_cpp is None: + self.swig_cpp = build_ext.swig_cpp + for c in ['swig', 'swig_opt']: + o = '--'+c.replace('_', '-') + v = getattr(build_ext, c, None) + if v: + if getattr(self, c): + log.warn('both build_src and build_ext define %s option' % (o)) + else: + log.info('using "%s=%s" option from build_ext command' % (o, v)) + setattr(self, c, v) + + def run(self): + log.info("build_src") + if not (self.extensions or self.libraries): + return + self.build_sources() + + def build_sources(self): + + if self.inplace: + self.get_package_dir = \ + self.get_finalized_command('build_py').get_package_dir + + self.build_py_modules_sources() + + for libname_info in self.libraries: + self.build_library_sources(*libname_info) + + if self.extensions: + self.check_extensions_list(self.extensions) + + for ext in self.extensions: + self.build_extension_sources(ext) + + self.build_data_files_sources() + self.build_npy_pkg_config() + + def build_data_files_sources(self): + if not self.data_files: + return + log.info('building data_files sources') + from numpy.distutils.misc_util import get_data_files + new_data_files = [] + for data in self.data_files: + if isinstance(data, str): + new_data_files.append(data) + elif isinstance(data, tuple): + d, files = data + if self.inplace: + build_dir = self.get_package_dir('.'.join(d.split(os.sep))) + else: + build_dir = os.path.join(self.build_src, d) + funcs = [f for f in files if hasattr(f, '__call__')] + files = [f for f in files if not hasattr(f, '__call__')] + for f in funcs: + if f.__code__.co_argcount==1: + s = f(build_dir) + else: + s = f() + if s is not None: + if isinstance(s, list): + files.extend(s) + elif isinstance(s, str): + files.append(s) + else: + raise TypeError(repr(s)) + filenames = get_data_files((d, files)) + new_data_files.append((d, filenames)) + else: + raise TypeError(repr(data)) + self.data_files[:] = new_data_files + + + def _build_npy_pkg_config(self, info, gd): + template, install_dir, subst_dict = info + template_dir = os.path.dirname(template) + for k, v in gd.items(): + subst_dict[k] = v + + if self.inplace == 1: + generated_dir = os.path.join(template_dir, install_dir) + else: + generated_dir = os.path.join(self.build_src, template_dir, + install_dir) + generated = os.path.basename(os.path.splitext(template)[0]) + generated_path = os.path.join(generated_dir, generated) + if not os.path.exists(generated_dir): + os.makedirs(generated_dir) + + subst_vars(generated_path, template, subst_dict) + + # Where to install relatively to install prefix + full_install_dir = os.path.join(template_dir, install_dir) + return full_install_dir, generated_path + + def build_npy_pkg_config(self): + log.info('build_src: building npy-pkg config files') + + # XXX: another ugly workaround to circumvent distutils brain damage. We + # need the install prefix here, but finalizing the options of the + # install command when only building sources cause error. Instead, we + # copy the install command instance, and finalize the copy so that it + # does not disrupt how distutils want to do things when with the + # original install command instance. + install_cmd = copy.copy(get_cmd('install')) + if not install_cmd.finalized == 1: + install_cmd.finalize_options() + build_npkg = False + if self.inplace == 1: + top_prefix = '.' + build_npkg = True + elif hasattr(install_cmd, 'install_libbase'): + top_prefix = install_cmd.install_libbase + build_npkg = True + + if build_npkg: + for pkg, infos in self.distribution.installed_pkg_config.items(): + pkg_path = self.distribution.package_dir[pkg] + prefix = os.path.join(os.path.abspath(top_prefix), pkg_path) + d = {'prefix': prefix} + for info in infos: + install_dir, generated = self._build_npy_pkg_config(info, d) + self.distribution.data_files.append((install_dir, + [generated])) + + def build_py_modules_sources(self): + if not self.py_modules: + return + log.info('building py_modules sources') + new_py_modules = [] + for source in self.py_modules: + if is_sequence(source) and len(source)==3: + package, module_base, source = source + if self.inplace: + build_dir = self.get_package_dir(package) + else: + build_dir = os.path.join(self.build_src, + os.path.join(*package.split('.'))) + if hasattr(source, '__call__'): + target = os.path.join(build_dir, module_base + '.py') + source = source(target) + if source is None: + continue + modules = [(package, module_base, source)] + if package not in self.py_modules_dict: + self.py_modules_dict[package] = [] + self.py_modules_dict[package] += modules + else: + new_py_modules.append(source) + self.py_modules[:] = new_py_modules + + def build_library_sources(self, lib_name, build_info): + sources = list(build_info.get('sources', [])) + + if not sources: + return + + log.info('building library "%s" sources' % (lib_name)) + + sources = self.generate_sources(sources, (lib_name, build_info)) + + sources = self.template_sources(sources, (lib_name, build_info)) + + sources, h_files = self.filter_h_files(sources) + + if h_files: + log.info('%s - nothing done with h_files = %s', + self.package, h_files) + + #for f in h_files: + # self.distribution.headers.append((lib_name,f)) + + build_info['sources'] = sources + return + + def build_extension_sources(self, ext): + + sources = list(ext.sources) + + log.info('building extension "%s" sources' % (ext.name)) + + fullname = self.get_ext_fullname(ext.name) + + modpath = fullname.split('.') + package = '.'.join(modpath[0:-1]) + + if self.inplace: + self.ext_target_dir = self.get_package_dir(package) + + sources = self.generate_sources(sources, ext) + sources = self.template_sources(sources, ext) + sources = self.swig_sources(sources, ext) + sources = self.f2py_sources(sources, ext) + sources = self.pyrex_sources(sources, ext) + + sources, py_files = self.filter_py_files(sources) + + if package not in self.py_modules_dict: + self.py_modules_dict[package] = [] + modules = [] + for f in py_files: + module = os.path.splitext(os.path.basename(f))[0] + modules.append((package, module, f)) + self.py_modules_dict[package] += modules + + sources, h_files = self.filter_h_files(sources) + + if h_files: + log.info('%s - nothing done with h_files = %s', + package, h_files) + #for f in h_files: + # self.distribution.headers.append((package,f)) + + ext.sources = sources + + def generate_sources(self, sources, extension): + new_sources = [] + func_sources = [] + for source in sources: + if is_string(source): + new_sources.append(source) + else: + func_sources.append(source) + if not func_sources: + return new_sources + if self.inplace and not is_sequence(extension): + build_dir = self.ext_target_dir + else: + if is_sequence(extension): + name = extension[0] + # if 'include_dirs' not in extension[1]: + # extension[1]['include_dirs'] = [] + # incl_dirs = extension[1]['include_dirs'] + else: + name = extension.name + # incl_dirs = extension.include_dirs + #if self.build_src not in incl_dirs: + # incl_dirs.append(self.build_src) + build_dir = os.path.join(*([self.build_src] + +name.split('.')[:-1])) + self.mkpath(build_dir) + + if self.verbose_cfg: + new_level = log.INFO + else: + new_level = log.WARN + old_level = log.set_threshold(new_level) + + for func in func_sources: + source = func(extension, build_dir) + if not source: + continue + if is_sequence(source): + [log.info(" adding '%s' to sources." % (s,)) for s in source] + new_sources.extend(source) + else: + log.info(" adding '%s' to sources." % (source,)) + new_sources.append(source) + log.set_threshold(old_level) + return new_sources + + def filter_py_files(self, sources): + return self.filter_files(sources, ['.py']) + + def filter_h_files(self, sources): + return self.filter_files(sources, ['.h', '.hpp', '.inc']) + + def filter_files(self, sources, exts = []): + new_sources = [] + files = [] + for source in sources: + (base, ext) = os.path.splitext(source) + if ext in exts: + files.append(source) + else: + new_sources.append(source) + return new_sources, files + + def template_sources(self, sources, extension): + new_sources = [] + if is_sequence(extension): + depends = extension[1].get('depends') + include_dirs = extension[1].get('include_dirs') + else: + depends = extension.depends + include_dirs = extension.include_dirs + for source in sources: + (base, ext) = os.path.splitext(source) + if ext == '.src': # Template file + if self.inplace: + target_dir = os.path.dirname(base) + else: + target_dir = appendpath(self.build_src, os.path.dirname(base)) + self.mkpath(target_dir) + target_file = os.path.join(target_dir, os.path.basename(base)) + if (self.force or newer_group([source] + depends, target_file)): + if _f_pyf_ext_match(base): + log.info("from_template:> %s" % (target_file)) + outstr = process_f_file(source) + else: + log.info("conv_template:> %s" % (target_file)) + outstr = process_c_file(source) + with open(target_file, 'w') as fid: + fid.write(outstr) + if _header_ext_match(target_file): + d = os.path.dirname(target_file) + if d not in include_dirs: + log.info(" adding '%s' to include_dirs." % (d)) + include_dirs.append(d) + new_sources.append(target_file) + else: + new_sources.append(source) + return new_sources + + def pyrex_sources(self, sources, extension): + """Pyrex not supported; this remains for Cython support (see below)""" + new_sources = [] + ext_name = extension.name.split('.')[-1] + for source in sources: + (base, ext) = os.path.splitext(source) + if ext == '.pyx': + target_file = self.generate_a_pyrex_source(base, ext_name, + source, + extension) + new_sources.append(target_file) + else: + new_sources.append(source) + return new_sources + + def generate_a_pyrex_source(self, base, ext_name, source, extension): + """Pyrex is not supported, but some projects monkeypatch this method. + + That allows compiling Cython code, see gh-6955. + This method will remain here for compatibility reasons. + """ + return [] + + def f2py_sources(self, sources, extension): + new_sources = [] + f2py_sources = [] + f_sources = [] + f2py_targets = {} + target_dirs = [] + ext_name = extension.name.split('.')[-1] + skip_f2py = 0 + + for source in sources: + (base, ext) = os.path.splitext(source) + if ext == '.pyf': # F2PY interface file + if self.inplace: + target_dir = os.path.dirname(base) + else: + target_dir = appendpath(self.build_src, os.path.dirname(base)) + if os.path.isfile(source): + name = get_f2py_modulename(source) + if name != ext_name: + raise DistutilsSetupError('mismatch of extension names: %s ' + 'provides %r but expected %r' % ( + source, name, ext_name)) + target_file = os.path.join(target_dir, name+'module.c') + else: + log.debug(' source %s does not exist: skipping f2py\'ing.' \ + % (source)) + name = ext_name + skip_f2py = 1 + target_file = os.path.join(target_dir, name+'module.c') + if not os.path.isfile(target_file): + log.warn(' target %s does not exist:\n '\ + 'Assuming %smodule.c was generated with '\ + '"build_src --inplace" command.' \ + % (target_file, name)) + target_dir = os.path.dirname(base) + target_file = os.path.join(target_dir, name+'module.c') + if not os.path.isfile(target_file): + raise DistutilsSetupError("%r missing" % (target_file,)) + log.info(' Yes! Using %r as up-to-date target.' \ + % (target_file)) + target_dirs.append(target_dir) + f2py_sources.append(source) + f2py_targets[source] = target_file + new_sources.append(target_file) + elif fortran_ext_match(ext): + f_sources.append(source) + else: + new_sources.append(source) + + if not (f2py_sources or f_sources): + return new_sources + + for d in target_dirs: + self.mkpath(d) + + f2py_options = extension.f2py_options + self.f2py_opts + + if self.distribution.libraries: + for name, build_info in self.distribution.libraries: + if name in extension.libraries: + f2py_options.extend(build_info.get('f2py_options', [])) + + log.info("f2py options: %s" % (f2py_options)) + + if f2py_sources: + if len(f2py_sources) != 1: + raise DistutilsSetupError( + 'only one .pyf file is allowed per extension module but got'\ + ' more: %r' % (f2py_sources,)) + source = f2py_sources[0] + target_file = f2py_targets[source] + target_dir = os.path.dirname(target_file) or '.' + depends = [source] + extension.depends + if (self.force or newer_group(depends, target_file, 'newer')) \ + and not skip_f2py: + log.info("f2py: %s" % (source)) + import numpy.f2py + numpy.f2py.run_main(f2py_options + + ['--build-dir', target_dir, source]) + else: + log.debug(" skipping '%s' f2py interface (up-to-date)" % (source)) + else: + #XXX TODO: --inplace support for sdist command + if is_sequence(extension): + name = extension[0] + else: name = extension.name + target_dir = os.path.join(*([self.build_src] + +name.split('.')[:-1])) + target_file = os.path.join(target_dir, ext_name + 'module.c') + new_sources.append(target_file) + depends = f_sources + extension.depends + if (self.force or newer_group(depends, target_file, 'newer')) \ + and not skip_f2py: + log.info("f2py:> %s" % (target_file)) + self.mkpath(target_dir) + import numpy.f2py + numpy.f2py.run_main(f2py_options + ['--lower', + '--build-dir', target_dir]+\ + ['-m', ext_name]+f_sources) + else: + log.debug(" skipping f2py fortran files for '%s' (up-to-date)"\ + % (target_file)) + + if not os.path.isfile(target_file): + raise DistutilsError("f2py target file %r not generated" % (target_file,)) + + build_dir = os.path.join(self.build_src, target_dir) + target_c = os.path.join(build_dir, 'fortranobject.c') + target_h = os.path.join(build_dir, 'fortranobject.h') + log.info(" adding '%s' to sources." % (target_c)) + new_sources.append(target_c) + if build_dir not in extension.include_dirs: + log.info(" adding '%s' to include_dirs." % (build_dir)) + extension.include_dirs.append(build_dir) + + if not skip_f2py: + import numpy.f2py + d = os.path.dirname(numpy.f2py.__file__) + source_c = os.path.join(d, 'src', 'fortranobject.c') + source_h = os.path.join(d, 'src', 'fortranobject.h') + if newer(source_c, target_c) or newer(source_h, target_h): + self.mkpath(os.path.dirname(target_c)) + self.copy_file(source_c, target_c) + self.copy_file(source_h, target_h) + else: + if not os.path.isfile(target_c): + raise DistutilsSetupError("f2py target_c file %r not found" % (target_c,)) + if not os.path.isfile(target_h): + raise DistutilsSetupError("f2py target_h file %r not found" % (target_h,)) + + for name_ext in ['-f2pywrappers.f', '-f2pywrappers2.f90']: + filename = os.path.join(target_dir, ext_name + name_ext) + if os.path.isfile(filename): + log.info(" adding '%s' to sources." % (filename)) + f_sources.append(filename) + + return new_sources + f_sources + + def swig_sources(self, sources, extension): + # Assuming SWIG 1.3.14 or later. See compatibility note in + # http://www.swig.org/Doc1.3/Python.html#Python_nn6 + + new_sources = [] + swig_sources = [] + swig_targets = {} + target_dirs = [] + py_files = [] # swig generated .py files + target_ext = '.c' + if '-c++' in extension.swig_opts: + typ = 'c++' + is_cpp = True + extension.swig_opts.remove('-c++') + elif self.swig_cpp: + typ = 'c++' + is_cpp = True + else: + typ = None + is_cpp = False + skip_swig = 0 + ext_name = extension.name.split('.')[-1] + + for source in sources: + (base, ext) = os.path.splitext(source) + if ext == '.i': # SWIG interface file + # the code below assumes that the sources list + # contains not more than one .i SWIG interface file + if self.inplace: + target_dir = os.path.dirname(base) + py_target_dir = self.ext_target_dir + else: + target_dir = appendpath(self.build_src, os.path.dirname(base)) + py_target_dir = target_dir + if os.path.isfile(source): + name = get_swig_modulename(source) + if name != ext_name[1:]: + raise DistutilsSetupError( + 'mismatch of extension names: %s provides %r' + ' but expected %r' % (source, name, ext_name[1:])) + if typ is None: + typ = get_swig_target(source) + is_cpp = typ=='c++' + else: + typ2 = get_swig_target(source) + if typ2 is None: + log.warn('source %r does not define swig target, assuming %s swig target' \ + % (source, typ)) + elif typ!=typ2: + log.warn('expected %r but source %r defines %r swig target' \ + % (typ, source, typ2)) + if typ2=='c++': + log.warn('resetting swig target to c++ (some targets may have .c extension)') + is_cpp = True + else: + log.warn('assuming that %r has c++ swig target' % (source)) + if is_cpp: + target_ext = '.cpp' + target_file = os.path.join(target_dir, '%s_wrap%s' \ + % (name, target_ext)) + else: + log.warn(' source %s does not exist: skipping swig\'ing.' \ + % (source)) + name = ext_name[1:] + skip_swig = 1 + target_file = _find_swig_target(target_dir, name) + if not os.path.isfile(target_file): + log.warn(' target %s does not exist:\n '\ + 'Assuming %s_wrap.{c,cpp} was generated with '\ + '"build_src --inplace" command.' \ + % (target_file, name)) + target_dir = os.path.dirname(base) + target_file = _find_swig_target(target_dir, name) + if not os.path.isfile(target_file): + raise DistutilsSetupError("%r missing" % (target_file,)) + log.warn(' Yes! Using %r as up-to-date target.' \ + % (target_file)) + target_dirs.append(target_dir) + new_sources.append(target_file) + py_files.append(os.path.join(py_target_dir, name+'.py')) + swig_sources.append(source) + swig_targets[source] = new_sources[-1] + else: + new_sources.append(source) + + if not swig_sources: + return new_sources + + if skip_swig: + return new_sources + py_files + + for d in target_dirs: + self.mkpath(d) + + swig = self.swig or self.find_swig() + swig_cmd = [swig, "-python"] + extension.swig_opts + if is_cpp: + swig_cmd.append('-c++') + for d in extension.include_dirs: + swig_cmd.append('-I'+d) + for source in swig_sources: + target = swig_targets[source] + depends = [source] + extension.depends + if self.force or newer_group(depends, target, 'newer'): + log.info("%s: %s" % (os.path.basename(swig) \ + + (is_cpp and '++' or ''), source)) + self.spawn(swig_cmd + self.swig_opts \ + + ["-o", target, '-outdir', py_target_dir, source]) + else: + log.debug(" skipping '%s' swig interface (up-to-date)" \ + % (source)) + + return new_sources + py_files + +_f_pyf_ext_match = re.compile(r'.*[.](f90|f95|f77|for|ftn|f|pyf)\Z', re.I).match +_header_ext_match = re.compile(r'.*[.](inc|h|hpp)\Z', re.I).match + +#### SWIG related auxiliary functions #### +_swig_module_name_match = re.compile(r'\s*%module\s*(.*\(\s*package\s*=\s*"(?P[\w_]+)".*\)|)\s*(?P[\w_]+)', + re.I).match +_has_c_header = re.compile(r'-[*]-\s*c\s*-[*]-', re.I).search +_has_cpp_header = re.compile(r'-[*]-\s*c[+][+]\s*-[*]-', re.I).search + +def get_swig_target(source): + with open(source, 'r') as f: + result = None + line = f.readline() + if _has_cpp_header(line): + result = 'c++' + if _has_c_header(line): + result = 'c' + return result + +def get_swig_modulename(source): + with open(source, 'r') as f: + name = None + for line in f: + m = _swig_module_name_match(line) + if m: + name = m.group('name') + break + return name + +def _find_swig_target(target_dir, name): + for ext in ['.cpp', '.c']: + target = os.path.join(target_dir, '%s_wrap%s' % (name, ext)) + if os.path.isfile(target): + break + return target + +#### F2PY related auxiliary functions #### + +_f2py_module_name_match = re.compile(r'\s*python\s*module\s*(?P[\w_]+)', + re.I).match +_f2py_user_module_name_match = re.compile(r'\s*python\s*module\s*(?P[\w_]*?' + r'__user__[\w_]*)', re.I).match + +def get_f2py_modulename(source): + name = None + with open(source) as f: + for line in f: + m = _f2py_module_name_match(line) + if m: + if _f2py_user_module_name_match(line): # skip *__user__* names + continue + name = m.group('name') + break + return name + +########################################## diff --git a/venv/Lib/site-packages/numpy/distutils/command/config.py b/venv/Lib/site-packages/numpy/distutils/command/config.py new file mode 100644 index 0000000..60881f4 --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/command/config.py @@ -0,0 +1,516 @@ +# Added Fortran compiler support to config. Currently useful only for +# try_compile call. try_run works but is untested for most of Fortran +# compilers (they must define linker_exe first). +# Pearu Peterson +import os +import signal +import subprocess +import sys +import textwrap +import warnings + +from distutils.command.config import config as old_config +from distutils.command.config import LANG_EXT +from distutils import log +from distutils.file_util import copy_file +from distutils.ccompiler import CompileError, LinkError +import distutils +from numpy.distutils.exec_command import filepath_from_subprocess_output +from numpy.distutils.mingw32ccompiler import generate_manifest +from numpy.distutils.command.autodist import (check_gcc_function_attribute, + check_gcc_function_attribute_with_intrinsics, + check_gcc_variable_attribute, + check_gcc_version_at_least, + check_inline, + check_restrict, + check_compiler_gcc) + +LANG_EXT['f77'] = '.f' +LANG_EXT['f90'] = '.f90' + +class config(old_config): + old_config.user_options += [ + ('fcompiler=', None, "specify the Fortran compiler type"), + ] + + def initialize_options(self): + self.fcompiler = None + old_config.initialize_options(self) + + def _check_compiler (self): + old_config._check_compiler(self) + from numpy.distutils.fcompiler import FCompiler, new_fcompiler + + if sys.platform == 'win32' and (self.compiler.compiler_type in + ('msvc', 'intelw', 'intelemw')): + # XXX: hack to circumvent a python 2.6 bug with msvc9compiler: + # initialize call query_vcvarsall, which throws an IOError, and + # causes an error along the way without much information. We try to + # catch it here, hoping it is early enough, and print an helpful + # message instead of Error: None. + if not self.compiler.initialized: + try: + self.compiler.initialize() + except IOError as e: + msg = textwrap.dedent("""\ + Could not initialize compiler instance: do you have Visual Studio + installed? If you are trying to build with MinGW, please use "python setup.py + build -c mingw32" instead. If you have Visual Studio installed, check it is + correctly installed, and the right version (VS 2008 for python 2.6, 2.7 and 3.2, + VS 2010 for >= 3.3). + + Original exception was: %s, and the Compiler class was %s + ============================================================================""") \ + % (e, self.compiler.__class__.__name__) + print(textwrap.dedent("""\ + ============================================================================""")) + raise distutils.errors.DistutilsPlatformError(msg) + + # After MSVC is initialized, add an explicit /MANIFEST to linker + # flags. See issues gh-4245 and gh-4101 for details. Also + # relevant are issues 4431 and 16296 on the Python bug tracker. + from distutils import msvc9compiler + if msvc9compiler.get_build_version() >= 10: + for ldflags in [self.compiler.ldflags_shared, + self.compiler.ldflags_shared_debug]: + if '/MANIFEST' not in ldflags: + ldflags.append('/MANIFEST') + + if not isinstance(self.fcompiler, FCompiler): + self.fcompiler = new_fcompiler(compiler=self.fcompiler, + dry_run=self.dry_run, force=1, + c_compiler=self.compiler) + if self.fcompiler is not None: + self.fcompiler.customize(self.distribution) + if self.fcompiler.get_version(): + self.fcompiler.customize_cmd(self) + self.fcompiler.show_customization() + + def _wrap_method(self, mth, lang, args): + from distutils.ccompiler import CompileError + from distutils.errors import DistutilsExecError + save_compiler = self.compiler + if lang in ['f77', 'f90']: + self.compiler = self.fcompiler + try: + ret = mth(*((self,)+args)) + except (DistutilsExecError, CompileError) as e: + str(e) + self.compiler = save_compiler + raise CompileError + self.compiler = save_compiler + return ret + + def _compile (self, body, headers, include_dirs, lang): + src, obj = self._wrap_method(old_config._compile, lang, + (body, headers, include_dirs, lang)) + # _compile in unixcompiler.py sometimes creates .d dependency files. + # Clean them up. + self.temp_files.append(obj + '.d') + return src, obj + + def _link (self, body, + headers, include_dirs, + libraries, library_dirs, lang): + if self.compiler.compiler_type=='msvc': + libraries = (libraries or [])[:] + library_dirs = (library_dirs or [])[:] + if lang in ['f77', 'f90']: + lang = 'c' # always use system linker when using MSVC compiler + if self.fcompiler: + for d in self.fcompiler.library_dirs or []: + # correct path when compiling in Cygwin but with + # normal Win Python + if d.startswith('/usr/lib'): + try: + d = subprocess.check_output(['cygpath', + '-w', d]) + except (OSError, subprocess.CalledProcessError): + pass + else: + d = filepath_from_subprocess_output(d) + library_dirs.append(d) + for libname in self.fcompiler.libraries or []: + if libname not in libraries: + libraries.append(libname) + for libname in libraries: + if libname.startswith('msvc'): continue + fileexists = False + for libdir in library_dirs or []: + libfile = os.path.join(libdir, '%s.lib' % (libname)) + if os.path.isfile(libfile): + fileexists = True + break + if fileexists: continue + # make g77-compiled static libs available to MSVC + fileexists = False + for libdir in library_dirs: + libfile = os.path.join(libdir, 'lib%s.a' % (libname)) + if os.path.isfile(libfile): + # copy libname.a file to name.lib so that MSVC linker + # can find it + libfile2 = os.path.join(libdir, '%s.lib' % (libname)) + copy_file(libfile, libfile2) + self.temp_files.append(libfile2) + fileexists = True + break + if fileexists: continue + log.warn('could not find library %r in directories %s' \ + % (libname, library_dirs)) + elif self.compiler.compiler_type == 'mingw32': + generate_manifest(self) + return self._wrap_method(old_config._link, lang, + (body, headers, include_dirs, + libraries, library_dirs, lang)) + + def check_header(self, header, include_dirs=None, library_dirs=None, lang='c'): + self._check_compiler() + return self.try_compile( + "/* we need a dummy line to make distutils happy */", + [header], include_dirs) + + def check_decl(self, symbol, + headers=None, include_dirs=None): + self._check_compiler() + body = textwrap.dedent(""" + int main(void) + { + #ifndef %s + (void) %s; + #endif + ; + return 0; + }""") % (symbol, symbol) + + return self.try_compile(body, headers, include_dirs) + + def check_macro_true(self, symbol, + headers=None, include_dirs=None): + self._check_compiler() + body = textwrap.dedent(""" + int main(void) + { + #if %s + #else + #error false or undefined macro + #endif + ; + return 0; + }""") % (symbol,) + + return self.try_compile(body, headers, include_dirs) + + def check_type(self, type_name, headers=None, include_dirs=None, + library_dirs=None): + """Check type availability. Return True if the type can be compiled, + False otherwise""" + self._check_compiler() + + # First check the type can be compiled + body = textwrap.dedent(r""" + int main(void) { + if ((%(name)s *) 0) + return 0; + if (sizeof (%(name)s)) + return 0; + } + """) % {'name': type_name} + + st = False + try: + try: + self._compile(body % {'type': type_name}, + headers, include_dirs, 'c') + st = True + except distutils.errors.CompileError: + st = False + finally: + self._clean() + + return st + + def check_type_size(self, type_name, headers=None, include_dirs=None, library_dirs=None, expected=None): + """Check size of a given type.""" + self._check_compiler() + + # First check the type can be compiled + body = textwrap.dedent(r""" + typedef %(type)s npy_check_sizeof_type; + int main (void) + { + static int test_array [1 - 2 * !(((long) (sizeof (npy_check_sizeof_type))) >= 0)]; + test_array [0] = 0 + + ; + return 0; + } + """) + self._compile(body % {'type': type_name}, + headers, include_dirs, 'c') + self._clean() + + if expected: + body = textwrap.dedent(r""" + typedef %(type)s npy_check_sizeof_type; + int main (void) + { + static int test_array [1 - 2 * !(((long) (sizeof (npy_check_sizeof_type))) == %(size)s)]; + test_array [0] = 0 + + ; + return 0; + } + """) + for size in expected: + try: + self._compile(body % {'type': type_name, 'size': size}, + headers, include_dirs, 'c') + self._clean() + return size + except CompileError: + pass + + # this fails to *compile* if size > sizeof(type) + body = textwrap.dedent(r""" + typedef %(type)s npy_check_sizeof_type; + int main (void) + { + static int test_array [1 - 2 * !(((long) (sizeof (npy_check_sizeof_type))) <= %(size)s)]; + test_array [0] = 0 + + ; + return 0; + } + """) + + # The principle is simple: we first find low and high bounds of size + # for the type, where low/high are looked up on a log scale. Then, we + # do a binary search to find the exact size between low and high + low = 0 + mid = 0 + while True: + try: + self._compile(body % {'type': type_name, 'size': mid}, + headers, include_dirs, 'c') + self._clean() + break + except CompileError: + #log.info("failure to test for bound %d" % mid) + low = mid + 1 + mid = 2 * mid + 1 + + high = mid + # Binary search: + while low != high: + mid = (high - low) // 2 + low + try: + self._compile(body % {'type': type_name, 'size': mid}, + headers, include_dirs, 'c') + self._clean() + high = mid + except CompileError: + low = mid + 1 + return low + + def check_func(self, func, + headers=None, include_dirs=None, + libraries=None, library_dirs=None, + decl=False, call=False, call_args=None): + # clean up distutils's config a bit: add void to main(), and + # return a value. + self._check_compiler() + body = [] + if decl: + if type(decl) == str: + body.append(decl) + else: + body.append("int %s (void);" % func) + # Handle MSVC intrinsics: force MS compiler to make a function call. + # Useful to test for some functions when built with optimization on, to + # avoid build error because the intrinsic and our 'fake' test + # declaration do not match. + body.append("#ifdef _MSC_VER") + body.append("#pragma function(%s)" % func) + body.append("#endif") + body.append("int main (void) {") + if call: + if call_args is None: + call_args = '' + body.append(" %s(%s);" % (func, call_args)) + else: + body.append(" %s;" % func) + body.append(" return 0;") + body.append("}") + body = '\n'.join(body) + "\n" + + return self.try_link(body, headers, include_dirs, + libraries, library_dirs) + + def check_funcs_once(self, funcs, + headers=None, include_dirs=None, + libraries=None, library_dirs=None, + decl=False, call=False, call_args=None): + """Check a list of functions at once. + + This is useful to speed up things, since all the functions in the funcs + list will be put in one compilation unit. + + Arguments + --------- + funcs : seq + list of functions to test + include_dirs : seq + list of header paths + libraries : seq + list of libraries to link the code snippet to + library_dirs : seq + list of library paths + decl : dict + for every (key, value), the declaration in the value will be + used for function in key. If a function is not in the + dictionary, no declaration will be used. + call : dict + for every item (f, value), if the value is True, a call will be + done to the function f. + """ + self._check_compiler() + body = [] + if decl: + for f, v in decl.items(): + if v: + body.append("int %s (void);" % f) + + # Handle MS intrinsics. See check_func for more info. + body.append("#ifdef _MSC_VER") + for func in funcs: + body.append("#pragma function(%s)" % func) + body.append("#endif") + + body.append("int main (void) {") + if call: + for f in funcs: + if f in call and call[f]: + if not (call_args and f in call_args and call_args[f]): + args = '' + else: + args = call_args[f] + body.append(" %s(%s);" % (f, args)) + else: + body.append(" %s;" % f) + else: + for f in funcs: + body.append(" %s;" % f) + body.append(" return 0;") + body.append("}") + body = '\n'.join(body) + "\n" + + return self.try_link(body, headers, include_dirs, + libraries, library_dirs) + + def check_inline(self): + """Return the inline keyword recognized by the compiler, empty string + otherwise.""" + return check_inline(self) + + def check_restrict(self): + """Return the restrict keyword recognized by the compiler, empty string + otherwise.""" + return check_restrict(self) + + def check_compiler_gcc(self): + """Return True if the C compiler is gcc""" + return check_compiler_gcc(self) + + def check_gcc_function_attribute(self, attribute, name): + return check_gcc_function_attribute(self, attribute, name) + + def check_gcc_function_attribute_with_intrinsics(self, attribute, name, + code, include): + return check_gcc_function_attribute_with_intrinsics(self, attribute, + name, code, include) + + def check_gcc_variable_attribute(self, attribute): + return check_gcc_variable_attribute(self, attribute) + + def check_gcc_version_at_least(self, major, minor=0, patchlevel=0): + """Return True if the GCC version is greater than or equal to the + specified version.""" + return check_gcc_version_at_least(self, major, minor, patchlevel) + + def get_output(self, body, headers=None, include_dirs=None, + libraries=None, library_dirs=None, + lang="c", use_tee=None): + """Try to compile, link to an executable, and run a program + built from 'body' and 'headers'. Returns the exit status code + of the program and its output. + """ + # 2008-11-16, RemoveMe + warnings.warn("\n+++++++++++++++++++++++++++++++++++++++++++++++++\n" + "Usage of get_output is deprecated: please do not \n" + "use it anymore, and avoid configuration checks \n" + "involving running executable on the target machine.\n" + "+++++++++++++++++++++++++++++++++++++++++++++++++\n", + DeprecationWarning, stacklevel=2) + self._check_compiler() + exitcode, output = 255, '' + try: + grabber = GrabStdout() + try: + src, obj, exe = self._link(body, headers, include_dirs, + libraries, library_dirs, lang) + grabber.restore() + except Exception: + output = grabber.data + grabber.restore() + raise + exe = os.path.join('.', exe) + try: + # specify cwd arg for consistency with + # historic usage pattern of exec_command() + # also, note that exe appears to be a string, + # which exec_command() handled, but we now + # use a list for check_output() -- this assumes + # that exe is always a single command + output = subprocess.check_output([exe], cwd='.') + except subprocess.CalledProcessError as exc: + exitstatus = exc.returncode + output = '' + except OSError: + # preserve the EnvironmentError exit status + # used historically in exec_command() + exitstatus = 127 + output = '' + else: + output = filepath_from_subprocess_output(output) + if hasattr(os, 'WEXITSTATUS'): + exitcode = os.WEXITSTATUS(exitstatus) + if os.WIFSIGNALED(exitstatus): + sig = os.WTERMSIG(exitstatus) + log.error('subprocess exited with signal %d' % (sig,)) + if sig == signal.SIGINT: + # control-C + raise KeyboardInterrupt + else: + exitcode = exitstatus + log.info("success!") + except (CompileError, LinkError): + log.info("failure.") + self._clean() + return exitcode, output + +class GrabStdout: + + def __init__(self): + self.sys_stdout = sys.stdout + self.data = '' + sys.stdout = self + + def write (self, data): + self.sys_stdout.write(data) + self.data += data + + def flush (self): + self.sys_stdout.flush() + + def restore(self): + sys.stdout = self.sys_stdout diff --git a/venv/Lib/site-packages/numpy/distutils/command/config_compiler.py b/venv/Lib/site-packages/numpy/distutils/command/config_compiler.py new file mode 100644 index 0000000..44265bf --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/command/config_compiler.py @@ -0,0 +1,126 @@ +from distutils.core import Command +from numpy.distutils import log + +#XXX: Linker flags + +def show_fortran_compilers(_cache=None): + # Using cache to prevent infinite recursion. + if _cache: + return + elif _cache is None: + _cache = [] + _cache.append(1) + from numpy.distutils.fcompiler import show_fcompilers + import distutils.core + dist = distutils.core._setup_distribution + show_fcompilers(dist) + +class config_fc(Command): + """ Distutils command to hold user specified options + to Fortran compilers. + + config_fc command is used by the FCompiler.customize() method. + """ + + description = "specify Fortran 77/Fortran 90 compiler information" + + user_options = [ + ('fcompiler=', None, "specify Fortran compiler type"), + ('f77exec=', None, "specify F77 compiler command"), + ('f90exec=', None, "specify F90 compiler command"), + ('f77flags=', None, "specify F77 compiler flags"), + ('f90flags=', None, "specify F90 compiler flags"), + ('opt=', None, "specify optimization flags"), + ('arch=', None, "specify architecture specific optimization flags"), + ('debug', 'g', "compile with debugging information"), + ('noopt', None, "compile without optimization"), + ('noarch', None, "compile without arch-dependent optimization"), + ] + + help_options = [ + ('help-fcompiler', None, "list available Fortran compilers", + show_fortran_compilers), + ] + + boolean_options = ['debug', 'noopt', 'noarch'] + + def initialize_options(self): + self.fcompiler = None + self.f77exec = None + self.f90exec = None + self.f77flags = None + self.f90flags = None + self.opt = None + self.arch = None + self.debug = None + self.noopt = None + self.noarch = None + + def finalize_options(self): + log.info('unifing config_fc, config, build_clib, build_ext, build commands --fcompiler options') + build_clib = self.get_finalized_command('build_clib') + build_ext = self.get_finalized_command('build_ext') + config = self.get_finalized_command('config') + build = self.get_finalized_command('build') + cmd_list = [self, config, build_clib, build_ext, build] + for a in ['fcompiler']: + l = [] + for c in cmd_list: + v = getattr(c, a) + if v is not None: + if not isinstance(v, str): v = v.compiler_type + if v not in l: l.append(v) + if not l: v1 = None + else: v1 = l[0] + if len(l)>1: + log.warn(' commands have different --%s options: %s'\ + ', using first in list as default' % (a, l)) + if v1: + for c in cmd_list: + if getattr(c, a) is None: setattr(c, a, v1) + + def run(self): + # Do nothing. + return + +class config_cc(Command): + """ Distutils command to hold user specified options + to C/C++ compilers. + """ + + description = "specify C/C++ compiler information" + + user_options = [ + ('compiler=', None, "specify C/C++ compiler type"), + ] + + def initialize_options(self): + self.compiler = None + + def finalize_options(self): + log.info('unifing config_cc, config, build_clib, build_ext, build commands --compiler options') + build_clib = self.get_finalized_command('build_clib') + build_ext = self.get_finalized_command('build_ext') + config = self.get_finalized_command('config') + build = self.get_finalized_command('build') + cmd_list = [self, config, build_clib, build_ext, build] + for a in ['compiler']: + l = [] + for c in cmd_list: + v = getattr(c, a) + if v is not None: + if not isinstance(v, str): v = v.compiler_type + if v not in l: l.append(v) + if not l: v1 = None + else: v1 = l[0] + if len(l)>1: + log.warn(' commands have different --%s options: %s'\ + ', using first in list as default' % (a, l)) + if v1: + for c in cmd_list: + if getattr(c, a) is None: setattr(c, a, v1) + return + + def run(self): + # Do nothing. + return diff --git a/venv/Lib/site-packages/numpy/distutils/command/develop.py b/venv/Lib/site-packages/numpy/distutils/command/develop.py new file mode 100644 index 0000000..af24baf --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/command/develop.py @@ -0,0 +1,15 @@ +""" Override the develop command from setuptools so we can ensure that our +generated files (from build_src or build_scripts) are properly converted to real +files with filenames. + +""" +from setuptools.command.develop import develop as old_develop + +class develop(old_develop): + __doc__ = old_develop.__doc__ + def install_for_development(self): + # Build sources in-place, too. + self.reinitialize_command('build_src', inplace=1) + # Make sure scripts are built. + self.run_command('build_scripts') + old_develop.install_for_development(self) diff --git a/venv/Lib/site-packages/numpy/distutils/command/egg_info.py b/venv/Lib/site-packages/numpy/distutils/command/egg_info.py new file mode 100644 index 0000000..14c62b4 --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/command/egg_info.py @@ -0,0 +1,25 @@ +import sys + +from setuptools.command.egg_info import egg_info as _egg_info + +class egg_info(_egg_info): + def run(self): + if 'sdist' in sys.argv: + import warnings + import textwrap + msg = textwrap.dedent(""" + `build_src` is being run, this may lead to missing + files in your sdist! You want to use distutils.sdist + instead of the setuptools version: + + from distutils.command.sdist import sdist + cmdclass={'sdist': sdist}" + + See numpy's setup.py or gh-7131 for details.""") + warnings.warn(msg, UserWarning, stacklevel=2) + + # We need to ensure that build_src has been executed in order to give + # setuptools' egg_info command real filenames instead of functions which + # generate files. + self.run_command("build_src") + _egg_info.run(self) diff --git a/venv/Lib/site-packages/numpy/distutils/command/install.py b/venv/Lib/site-packages/numpy/distutils/command/install.py new file mode 100644 index 0000000..2eff2d1 --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/command/install.py @@ -0,0 +1,79 @@ +import sys +if 'setuptools' in sys.modules: + import setuptools.command.install as old_install_mod + have_setuptools = True +else: + import distutils.command.install as old_install_mod + have_setuptools = False +from distutils.file_util import write_file + +old_install = old_install_mod.install + +class install(old_install): + + # Always run install_clib - the command is cheap, so no need to bypass it; + # but it's not run by setuptools -- so it's run again in install_data + sub_commands = old_install.sub_commands + [ + ('install_clib', lambda x: True) + ] + + def finalize_options (self): + old_install.finalize_options(self) + self.install_lib = self.install_libbase + + def setuptools_run(self): + """ The setuptools version of the .run() method. + + We must pull in the entire code so we can override the level used in the + _getframe() call since we wrap this call by one more level. + """ + from distutils.command.install import install as distutils_install + + # Explicit request for old-style install? Just do it + if self.old_and_unmanageable or self.single_version_externally_managed: + return distutils_install.run(self) + + # Attempt to detect whether we were called from setup() or by another + # command. If we were called by setup(), our caller will be the + # 'run_command' method in 'distutils.dist', and *its* caller will be + # the 'run_commands' method. If we were called any other way, our + # immediate caller *might* be 'run_command', but it won't have been + # called by 'run_commands'. This is slightly kludgy, but seems to + # work. + # + caller = sys._getframe(3) + caller_module = caller.f_globals.get('__name__', '') + caller_name = caller.f_code.co_name + + if caller_module != 'distutils.dist' or caller_name!='run_commands': + # We weren't called from the command line or setup(), so we + # should run in backward-compatibility mode to support bdist_* + # commands. + distutils_install.run(self) + else: + self.do_egg_install() + + def run(self): + if not have_setuptools: + r = old_install.run(self) + else: + r = self.setuptools_run() + if self.record: + # bdist_rpm fails when INSTALLED_FILES contains + # paths with spaces. Such paths must be enclosed + # with double-quotes. + with open(self.record, 'r') as f: + lines = [] + need_rewrite = False + for l in f: + l = l.rstrip() + if ' ' in l: + need_rewrite = True + l = '"%s"' % (l) + lines.append(l) + if need_rewrite: + self.execute(write_file, + (self.record, lines), + "re-writing list of installed files to '%s'" % + self.record) + return r diff --git a/venv/Lib/site-packages/numpy/distutils/command/install_clib.py b/venv/Lib/site-packages/numpy/distutils/command/install_clib.py new file mode 100644 index 0000000..aa2e559 --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/command/install_clib.py @@ -0,0 +1,40 @@ +import os +from distutils.core import Command +from distutils.ccompiler import new_compiler +from numpy.distutils.misc_util import get_cmd + +class install_clib(Command): + description = "Command to install installable C libraries" + + user_options = [] + + def initialize_options(self): + self.install_dir = None + self.outfiles = [] + + def finalize_options(self): + self.set_undefined_options('install', ('install_lib', 'install_dir')) + + def run (self): + build_clib_cmd = get_cmd("build_clib") + if not build_clib_cmd.build_clib: + # can happen if the user specified `--skip-build` + build_clib_cmd.finalize_options() + build_dir = build_clib_cmd.build_clib + + # We need the compiler to get the library name -> filename association + if not build_clib_cmd.compiler: + compiler = new_compiler(compiler=None) + compiler.customize(self.distribution) + else: + compiler = build_clib_cmd.compiler + + for l in self.distribution.installed_libraries: + target_dir = os.path.join(self.install_dir, l.target_dir) + name = compiler.library_filename(l.name) + source = os.path.join(build_dir, name) + self.mkpath(target_dir) + self.outfiles.append(self.copy_file(source, target_dir)[0]) + + def get_outputs(self): + return self.outfiles diff --git a/venv/Lib/site-packages/numpy/distutils/command/install_data.py b/venv/Lib/site-packages/numpy/distutils/command/install_data.py new file mode 100644 index 0000000..0a2e68a --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/command/install_data.py @@ -0,0 +1,24 @@ +import sys +have_setuptools = ('setuptools' in sys.modules) + +from distutils.command.install_data import install_data as old_install_data + +#data installer with improved intelligence over distutils +#data files are copied into the project directory instead +#of willy-nilly +class install_data (old_install_data): + + def run(self): + old_install_data.run(self) + + if have_setuptools: + # Run install_clib again, since setuptools does not run sub-commands + # of install automatically + self.run_command('install_clib') + + def finalize_options (self): + self.set_undefined_options('install', + ('install_lib', 'install_dir'), + ('root', 'root'), + ('force', 'force'), + ) diff --git a/venv/Lib/site-packages/numpy/distutils/command/install_headers.py b/venv/Lib/site-packages/numpy/distutils/command/install_headers.py new file mode 100644 index 0000000..bb4ad56 --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/command/install_headers.py @@ -0,0 +1,25 @@ +import os +from distutils.command.install_headers import install_headers as old_install_headers + +class install_headers (old_install_headers): + + def run (self): + headers = self.distribution.headers + if not headers: + return + + prefix = os.path.dirname(self.install_dir) + for header in headers: + if isinstance(header, tuple): + # Kind of a hack, but I don't know where else to change this... + if header[0] == 'numpy.core': + header = ('numpy', header[1]) + if os.path.splitext(header[1])[1] == '.inc': + continue + d = os.path.join(*([prefix]+header[0].split('.'))) + header = header[1] + else: + d = self.install_dir + self.mkpath(d) + (out, _) = self.copy_file(header, d) + self.outfiles.append(out) diff --git a/venv/Lib/site-packages/numpy/distutils/command/sdist.py b/venv/Lib/site-packages/numpy/distutils/command/sdist.py new file mode 100644 index 0000000..e341938 --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/command/sdist.py @@ -0,0 +1,27 @@ +import sys +if 'setuptools' in sys.modules: + from setuptools.command.sdist import sdist as old_sdist +else: + from distutils.command.sdist import sdist as old_sdist + +from numpy.distutils.misc_util import get_data_files + +class sdist(old_sdist): + + def add_defaults (self): + old_sdist.add_defaults(self) + + dist = self.distribution + + if dist.has_data_files(): + for data in dist.data_files: + self.filelist.extend(get_data_files(data)) + + if dist.has_headers(): + headers = [] + for h in dist.headers: + if isinstance(h, str): headers.append(h) + else: headers.append(h[1]) + self.filelist.extend(headers) + + return diff --git a/venv/Lib/site-packages/numpy/distutils/conv_template.py b/venv/Lib/site-packages/numpy/distutils/conv_template.py new file mode 100644 index 0000000..d08015f --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/conv_template.py @@ -0,0 +1,330 @@ +#!/usr/bin/env python3 +""" +takes templated file .xxx.src and produces .xxx file where .xxx is +.i or .c or .h, using the following template rules + +/**begin repeat -- on a line by itself marks the start of a repeated code + segment +/**end repeat**/ -- on a line by itself marks it's end + +After the /**begin repeat and before the */, all the named templates are placed +these should all have the same number of replacements + +Repeat blocks can be nested, with each nested block labeled with its depth, +i.e. +/**begin repeat1 + *.... + */ +/**end repeat1**/ + +When using nested loops, you can optionally exclude particular +combinations of the variables using (inside the comment portion of the inner loop): + + :exclude: var1=value1, var2=value2, ... + +This will exclude the pattern where var1 is value1 and var2 is value2 when +the result is being generated. + + +In the main body each replace will use one entry from the list of named replacements + + Note that all #..# forms in a block must have the same number of + comma-separated entries. + +Example: + + An input file containing + + /**begin repeat + * #a = 1,2,3# + * #b = 1,2,3# + */ + + /**begin repeat1 + * #c = ted, jim# + */ + @a@, @b@, @c@ + /**end repeat1**/ + + /**end repeat**/ + + produces + + line 1 "template.c.src" + + /* + ********************************************************************* + ** This file was autogenerated from a template DO NOT EDIT!!** + ** Changes should be made to the original source (.src) file ** + ********************************************************************* + */ + + #line 9 + 1, 1, ted + + #line 9 + 1, 1, jim + + #line 9 + 2, 2, ted + + #line 9 + 2, 2, jim + + #line 9 + 3, 3, ted + + #line 9 + 3, 3, jim + +""" + +__all__ = ['process_str', 'process_file'] + +import os +import sys +import re + +# names for replacement that are already global. +global_names = {} + +# header placed at the front of head processed file +header =\ +""" +/* + ***************************************************************************** + ** This file was autogenerated from a template DO NOT EDIT!!!! ** + ** Changes should be made to the original source (.src) file ** + ***************************************************************************** + */ + +""" +# Parse string for repeat loops +def parse_structure(astr, level): + """ + The returned line number is from the beginning of the string, starting + at zero. Returns an empty list if no loops found. + + """ + if level == 0 : + loopbeg = "/**begin repeat" + loopend = "/**end repeat**/" + else : + loopbeg = "/**begin repeat%d" % level + loopend = "/**end repeat%d**/" % level + + ind = 0 + line = 0 + spanlist = [] + while True: + start = astr.find(loopbeg, ind) + if start == -1: + break + start2 = astr.find("*/", start) + start2 = astr.find("\n", start2) + fini1 = astr.find(loopend, start2) + fini2 = astr.find("\n", fini1) + line += astr.count("\n", ind, start2+1) + spanlist.append((start, start2+1, fini1, fini2+1, line)) + line += astr.count("\n", start2+1, fini2) + ind = fini2 + spanlist.sort() + return spanlist + + +def paren_repl(obj): + torep = obj.group(1) + numrep = obj.group(2) + return ','.join([torep]*int(numrep)) + +parenrep = re.compile(r"[(]([^)]*)[)]\*(\d+)") +plainrep = re.compile(r"([^*]+)\*(\d+)") +def parse_values(astr): + # replaces all occurrences of '(a,b,c)*4' in astr + # with 'a,b,c,a,b,c,a,b,c,a,b,c'. Empty braces generate + # empty values, i.e., ()*4 yields ',,,'. The result is + # split at ',' and a list of values returned. + astr = parenrep.sub(paren_repl, astr) + # replaces occurrences of xxx*3 with xxx, xxx, xxx + astr = ','.join([plainrep.sub(paren_repl, x.strip()) + for x in astr.split(',')]) + return astr.split(',') + + +stripast = re.compile(r"\n\s*\*?") +named_re = re.compile(r"#\s*(\w*)\s*=([^#]*)#") +exclude_vars_re = re.compile(r"(\w*)=(\w*)") +exclude_re = re.compile(":exclude:") +def parse_loop_header(loophead) : + """Find all named replacements in the header + + Returns a list of dictionaries, one for each loop iteration, + where each key is a name to be substituted and the corresponding + value is the replacement string. + + Also return a list of exclusions. The exclusions are dictionaries + of key value pairs. There can be more than one exclusion. + [{'var1':'value1', 'var2', 'value2'[,...]}, ...] + + """ + # Strip out '\n' and leading '*', if any, in continuation lines. + # This should not effect code previous to this change as + # continuation lines were not allowed. + loophead = stripast.sub("", loophead) + # parse out the names and lists of values + names = [] + reps = named_re.findall(loophead) + nsub = None + for rep in reps: + name = rep[0] + vals = parse_values(rep[1]) + size = len(vals) + if nsub is None : + nsub = size + elif nsub != size : + msg = "Mismatch in number of values, %d != %d\n%s = %s" + raise ValueError(msg % (nsub, size, name, vals)) + names.append((name, vals)) + + + # Find any exclude variables + excludes = [] + + for obj in exclude_re.finditer(loophead): + span = obj.span() + # find next newline + endline = loophead.find('\n', span[1]) + substr = loophead[span[1]:endline] + ex_names = exclude_vars_re.findall(substr) + excludes.append(dict(ex_names)) + + # generate list of dictionaries, one for each template iteration + dlist = [] + if nsub is None : + raise ValueError("No substitution variables found") + for i in range(nsub): + tmp = {name: vals[i] for name, vals in names} + dlist.append(tmp) + return dlist + +replace_re = re.compile(r"@([\w]+)@") +def parse_string(astr, env, level, line) : + lineno = "#line %d\n" % line + + # local function for string replacement, uses env + def replace(match): + name = match.group(1) + try : + val = env[name] + except KeyError: + msg = 'line %d: no definition of key "%s"'%(line, name) + raise ValueError(msg) + return val + + code = [lineno] + struct = parse_structure(astr, level) + if struct : + # recurse over inner loops + oldend = 0 + newlevel = level + 1 + for sub in struct: + pref = astr[oldend:sub[0]] + head = astr[sub[0]:sub[1]] + text = astr[sub[1]:sub[2]] + oldend = sub[3] + newline = line + sub[4] + code.append(replace_re.sub(replace, pref)) + try : + envlist = parse_loop_header(head) + except ValueError as e: + msg = "line %d: %s" % (newline, e) + raise ValueError(msg) + for newenv in envlist : + newenv.update(env) + newcode = parse_string(text, newenv, newlevel, newline) + code.extend(newcode) + suff = astr[oldend:] + code.append(replace_re.sub(replace, suff)) + else : + # replace keys + code.append(replace_re.sub(replace, astr)) + code.append('\n') + return ''.join(code) + +def process_str(astr): + code = [header] + code.extend(parse_string(astr, global_names, 0, 1)) + return ''.join(code) + + +include_src_re = re.compile(r"(\n|\A)#include\s*['\"]" + r"(?P[\w\d./\\]+[.]src)['\"]", re.I) + +def resolve_includes(source): + d = os.path.dirname(source) + with open(source) as fid: + lines = [] + for line in fid: + m = include_src_re.match(line) + if m: + fn = m.group('name') + if not os.path.isabs(fn): + fn = os.path.join(d, fn) + if os.path.isfile(fn): + print('Including file', fn) + lines.extend(resolve_includes(fn)) + else: + lines.append(line) + else: + lines.append(line) + return lines + +def process_file(source): + lines = resolve_includes(source) + sourcefile = os.path.normcase(source).replace("\\", "\\\\") + try: + code = process_str(''.join(lines)) + except ValueError as e: + raise ValueError('In "%s" loop at %s' % (sourcefile, e)) + return '#line 1 "%s"\n%s' % (sourcefile, code) + + +def unique_key(adict): + # this obtains a unique key given a dictionary + # currently it works by appending together n of the letters of the + # current keys and increasing n until a unique key is found + # -- not particularly quick + allkeys = list(adict.keys()) + done = False + n = 1 + while not done: + newkey = "".join([x[:n] for x in allkeys]) + if newkey in allkeys: + n += 1 + else: + done = True + return newkey + + +def main(): + try: + file = sys.argv[1] + except IndexError: + fid = sys.stdin + outfile = sys.stdout + else: + fid = open(file, 'r') + (base, ext) = os.path.splitext(file) + newname = base + outfile = open(newname, 'w') + + allstr = fid.read() + try: + writestr = process_str(allstr) + except ValueError as e: + raise ValueError("In %s loop at %s" % (file, e)) + + outfile.write(writestr) + +if __name__ == "__main__": + main() diff --git a/venv/Lib/site-packages/numpy/distutils/core.py b/venv/Lib/site-packages/numpy/distutils/core.py new file mode 100644 index 0000000..d5551f3 --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/core.py @@ -0,0 +1,215 @@ +import sys +from distutils.core import Distribution + +if 'setuptools' in sys.modules: + have_setuptools = True + from setuptools import setup as old_setup + # easy_install imports math, it may be picked up from cwd + from setuptools.command import easy_install + try: + # very old versions of setuptools don't have this + from setuptools.command import bdist_egg + except ImportError: + have_setuptools = False +else: + from distutils.core import setup as old_setup + have_setuptools = False + +import warnings +import distutils.core +import distutils.dist + +from numpy.distutils.extension import Extension +from numpy.distutils.numpy_distribution import NumpyDistribution +from numpy.distutils.command import config, config_compiler, \ + build, build_py, build_ext, build_clib, build_src, build_scripts, \ + sdist, install_data, install_headers, install, bdist_rpm, \ + install_clib +from numpy.distutils.misc_util import is_sequence, is_string + +numpy_cmdclass = {'build': build.build, + 'build_src': build_src.build_src, + 'build_scripts': build_scripts.build_scripts, + 'config_cc': config_compiler.config_cc, + 'config_fc': config_compiler.config_fc, + 'config': config.config, + 'build_ext': build_ext.build_ext, + 'build_py': build_py.build_py, + 'build_clib': build_clib.build_clib, + 'sdist': sdist.sdist, + 'install_data': install_data.install_data, + 'install_headers': install_headers.install_headers, + 'install_clib': install_clib.install_clib, + 'install': install.install, + 'bdist_rpm': bdist_rpm.bdist_rpm, + } +if have_setuptools: + # Use our own versions of develop and egg_info to ensure that build_src is + # handled appropriately. + from numpy.distutils.command import develop, egg_info + numpy_cmdclass['bdist_egg'] = bdist_egg.bdist_egg + numpy_cmdclass['develop'] = develop.develop + numpy_cmdclass['easy_install'] = easy_install.easy_install + numpy_cmdclass['egg_info'] = egg_info.egg_info + +def _dict_append(d, **kws): + for k, v in kws.items(): + if k not in d: + d[k] = v + continue + dv = d[k] + if isinstance(dv, tuple): + d[k] = dv + tuple(v) + elif isinstance(dv, list): + d[k] = dv + list(v) + elif isinstance(dv, dict): + _dict_append(dv, **v) + elif is_string(dv): + d[k] = dv + v + else: + raise TypeError(repr(type(dv))) + +def _command_line_ok(_cache=None): + """ Return True if command line does not contain any + help or display requests. + """ + if _cache: + return _cache[0] + elif _cache is None: + _cache = [] + ok = True + display_opts = ['--'+n for n in Distribution.display_option_names] + for o in Distribution.display_options: + if o[1]: + display_opts.append('-'+o[1]) + for arg in sys.argv: + if arg.startswith('--help') or arg=='-h' or arg in display_opts: + ok = False + break + _cache.append(ok) + return ok + +def get_distribution(always=False): + dist = distutils.core._setup_distribution + # XXX Hack to get numpy installable with easy_install. + # The problem is easy_install runs it's own setup(), which + # sets up distutils.core._setup_distribution. However, + # when our setup() runs, that gets overwritten and lost. + # We can't use isinstance, as the DistributionWithoutHelpCommands + # class is local to a function in setuptools.command.easy_install + if dist is not None and \ + 'DistributionWithoutHelpCommands' in repr(dist): + dist = None + if always and dist is None: + dist = NumpyDistribution() + return dist + +def setup(**attr): + + cmdclass = numpy_cmdclass.copy() + + new_attr = attr.copy() + if 'cmdclass' in new_attr: + cmdclass.update(new_attr['cmdclass']) + new_attr['cmdclass'] = cmdclass + + if 'configuration' in new_attr: + # To avoid calling configuration if there are any errors + # or help request in command in the line. + configuration = new_attr.pop('configuration') + + old_dist = distutils.core._setup_distribution + old_stop = distutils.core._setup_stop_after + distutils.core._setup_distribution = None + distutils.core._setup_stop_after = "commandline" + try: + dist = setup(**new_attr) + finally: + distutils.core._setup_distribution = old_dist + distutils.core._setup_stop_after = old_stop + if dist.help or not _command_line_ok(): + # probably displayed help, skip running any commands + return dist + + # create setup dictionary and append to new_attr + config = configuration() + if hasattr(config, 'todict'): + config = config.todict() + _dict_append(new_attr, **config) + + # Move extension source libraries to libraries + libraries = [] + for ext in new_attr.get('ext_modules', []): + new_libraries = [] + for item in ext.libraries: + if is_sequence(item): + lib_name, build_info = item + _check_append_ext_library(libraries, lib_name, build_info) + new_libraries.append(lib_name) + elif is_string(item): + new_libraries.append(item) + else: + raise TypeError("invalid description of extension module " + "library %r" % (item,)) + ext.libraries = new_libraries + if libraries: + if 'libraries' not in new_attr: + new_attr['libraries'] = [] + for item in libraries: + _check_append_library(new_attr['libraries'], item) + + # sources in ext_modules or libraries may contain header files + if ('ext_modules' in new_attr or 'libraries' in new_attr) \ + and 'headers' not in new_attr: + new_attr['headers'] = [] + + # Use our custom NumpyDistribution class instead of distutils' one + new_attr['distclass'] = NumpyDistribution + + return old_setup(**new_attr) + +def _check_append_library(libraries, item): + for libitem in libraries: + if is_sequence(libitem): + if is_sequence(item): + if item[0]==libitem[0]: + if item[1] is libitem[1]: + return + warnings.warn("[0] libraries list contains %r with" + " different build_info" % (item[0],), + stacklevel=2) + break + else: + if item==libitem[0]: + warnings.warn("[1] libraries list contains %r with" + " no build_info" % (item[0],), + stacklevel=2) + break + else: + if is_sequence(item): + if item[0]==libitem: + warnings.warn("[2] libraries list contains %r with" + " no build_info" % (item[0],), + stacklevel=2) + break + else: + if item==libitem: + return + libraries.append(item) + +def _check_append_ext_library(libraries, lib_name, build_info): + for item in libraries: + if is_sequence(item): + if item[0]==lib_name: + if item[1] is build_info: + return + warnings.warn("[3] libraries list contains %r with" + " different build_info" % (lib_name,), + stacklevel=2) + break + elif item==lib_name: + warnings.warn("[4] libraries list contains %r with" + " no build_info" % (lib_name,), + stacklevel=2) + break + libraries.append((lib_name, build_info)) diff --git a/venv/Lib/site-packages/numpy/distutils/cpuinfo.py b/venv/Lib/site-packages/numpy/distutils/cpuinfo.py new file mode 100644 index 0000000..51ce3c1 --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/cpuinfo.py @@ -0,0 +1,683 @@ +#!/usr/bin/env python3 +""" +cpuinfo + +Copyright 2002 Pearu Peterson all rights reserved, +Pearu Peterson +Permission to use, modify, and distribute this software is given under the +terms of the NumPy (BSD style) license. See LICENSE.txt that came with +this distribution for specifics. + +NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. +Pearu Peterson + +""" +__all__ = ['cpu'] + +import os +import platform +import re +import sys +import types +import warnings + +from subprocess import getstatusoutput + + +def getoutput(cmd, successful_status=(0,), stacklevel=1): + try: + status, output = getstatusoutput(cmd) + except EnvironmentError as e: + warnings.warn(str(e), UserWarning, stacklevel=stacklevel) + return False, "" + if os.WIFEXITED(status) and os.WEXITSTATUS(status) in successful_status: + return True, output + return False, output + +def command_info(successful_status=(0,), stacklevel=1, **kw): + info = {} + for key in kw: + ok, output = getoutput(kw[key], successful_status=successful_status, + stacklevel=stacklevel+1) + if ok: + info[key] = output.strip() + return info + +def command_by_line(cmd, successful_status=(0,), stacklevel=1): + ok, output = getoutput(cmd, successful_status=successful_status, + stacklevel=stacklevel+1) + if not ok: + return + for line in output.splitlines(): + yield line.strip() + +def key_value_from_command(cmd, sep, successful_status=(0,), + stacklevel=1): + d = {} + for line in command_by_line(cmd, successful_status=successful_status, + stacklevel=stacklevel+1): + l = [s.strip() for s in line.split(sep, 1)] + if len(l) == 2: + d[l[0]] = l[1] + return d + +class CPUInfoBase: + """Holds CPU information and provides methods for requiring + the availability of various CPU features. + """ + + def _try_call(self, func): + try: + return func() + except Exception: + pass + + def __getattr__(self, name): + if not name.startswith('_'): + if hasattr(self, '_'+name): + attr = getattr(self, '_'+name) + if isinstance(attr, types.MethodType): + return lambda func=self._try_call,attr=attr : func(attr) + else: + return lambda : None + raise AttributeError(name) + + def _getNCPUs(self): + return 1 + + def __get_nbits(self): + abits = platform.architecture()[0] + nbits = re.compile(r'(\d+)bit').search(abits).group(1) + return nbits + + def _is_32bit(self): + return self.__get_nbits() == '32' + + def _is_64bit(self): + return self.__get_nbits() == '64' + +class LinuxCPUInfo(CPUInfoBase): + + info = None + + def __init__(self): + if self.info is not None: + return + info = [ {} ] + ok, output = getoutput('uname -m') + if ok: + info[0]['uname_m'] = output.strip() + try: + fo = open('/proc/cpuinfo') + except EnvironmentError as e: + warnings.warn(str(e), UserWarning, stacklevel=2) + else: + for line in fo: + name_value = [s.strip() for s in line.split(':', 1)] + if len(name_value) != 2: + continue + name, value = name_value + if not info or name in info[-1]: # next processor + info.append({}) + info[-1][name] = value + fo.close() + self.__class__.info = info + + def _not_impl(self): pass + + # Athlon + + def _is_AMD(self): + return self.info[0]['vendor_id']=='AuthenticAMD' + + def _is_AthlonK6_2(self): + return self._is_AMD() and self.info[0]['model'] == '2' + + def _is_AthlonK6_3(self): + return self._is_AMD() and self.info[0]['model'] == '3' + + def _is_AthlonK6(self): + return re.match(r'.*?AMD-K6', self.info[0]['model name']) is not None + + def _is_AthlonK7(self): + return re.match(r'.*?AMD-K7', self.info[0]['model name']) is not None + + def _is_AthlonMP(self): + return re.match(r'.*?Athlon\(tm\) MP\b', + self.info[0]['model name']) is not None + + def _is_AMD64(self): + return self.is_AMD() and self.info[0]['family'] == '15' + + def _is_Athlon64(self): + return re.match(r'.*?Athlon\(tm\) 64\b', + self.info[0]['model name']) is not None + + def _is_AthlonHX(self): + return re.match(r'.*?Athlon HX\b', + self.info[0]['model name']) is not None + + def _is_Opteron(self): + return re.match(r'.*?Opteron\b', + self.info[0]['model name']) is not None + + def _is_Hammer(self): + return re.match(r'.*?Hammer\b', + self.info[0]['model name']) is not None + + # Alpha + + def _is_Alpha(self): + return self.info[0]['cpu']=='Alpha' + + def _is_EV4(self): + return self.is_Alpha() and self.info[0]['cpu model'] == 'EV4' + + def _is_EV5(self): + return self.is_Alpha() and self.info[0]['cpu model'] == 'EV5' + + def _is_EV56(self): + return self.is_Alpha() and self.info[0]['cpu model'] == 'EV56' + + def _is_PCA56(self): + return self.is_Alpha() and self.info[0]['cpu model'] == 'PCA56' + + # Intel + + #XXX + _is_i386 = _not_impl + + def _is_Intel(self): + return self.info[0]['vendor_id']=='GenuineIntel' + + def _is_i486(self): + return self.info[0]['cpu']=='i486' + + def _is_i586(self): + return self.is_Intel() and self.info[0]['cpu family'] == '5' + + def _is_i686(self): + return self.is_Intel() and self.info[0]['cpu family'] == '6' + + def _is_Celeron(self): + return re.match(r'.*?Celeron', + self.info[0]['model name']) is not None + + def _is_Pentium(self): + return re.match(r'.*?Pentium', + self.info[0]['model name']) is not None + + def _is_PentiumII(self): + return re.match(r'.*?Pentium.*?II\b', + self.info[0]['model name']) is not None + + def _is_PentiumPro(self): + return re.match(r'.*?PentiumPro\b', + self.info[0]['model name']) is not None + + def _is_PentiumMMX(self): + return re.match(r'.*?Pentium.*?MMX\b', + self.info[0]['model name']) is not None + + def _is_PentiumIII(self): + return re.match(r'.*?Pentium.*?III\b', + self.info[0]['model name']) is not None + + def _is_PentiumIV(self): + return re.match(r'.*?Pentium.*?(IV|4)\b', + self.info[0]['model name']) is not None + + def _is_PentiumM(self): + return re.match(r'.*?Pentium.*?M\b', + self.info[0]['model name']) is not None + + def _is_Prescott(self): + return self.is_PentiumIV() and self.has_sse3() + + def _is_Nocona(self): + return (self.is_Intel() + and (self.info[0]['cpu family'] == '6' + or self.info[0]['cpu family'] == '15') + and (self.has_sse3() and not self.has_ssse3()) + and re.match(r'.*?\blm\b', self.info[0]['flags']) is not None) + + def _is_Core2(self): + return (self.is_64bit() and self.is_Intel() and + re.match(r'.*?Core\(TM\)2\b', + self.info[0]['model name']) is not None) + + def _is_Itanium(self): + return re.match(r'.*?Itanium\b', + self.info[0]['family']) is not None + + def _is_XEON(self): + return re.match(r'.*?XEON\b', + self.info[0]['model name'], re.IGNORECASE) is not None + + _is_Xeon = _is_XEON + + # Varia + + def _is_singleCPU(self): + return len(self.info) == 1 + + def _getNCPUs(self): + return len(self.info) + + def _has_fdiv_bug(self): + return self.info[0]['fdiv_bug']=='yes' + + def _has_f00f_bug(self): + return self.info[0]['f00f_bug']=='yes' + + def _has_mmx(self): + return re.match(r'.*?\bmmx\b', self.info[0]['flags']) is not None + + def _has_sse(self): + return re.match(r'.*?\bsse\b', self.info[0]['flags']) is not None + + def _has_sse2(self): + return re.match(r'.*?\bsse2\b', self.info[0]['flags']) is not None + + def _has_sse3(self): + return re.match(r'.*?\bpni\b', self.info[0]['flags']) is not None + + def _has_ssse3(self): + return re.match(r'.*?\bssse3\b', self.info[0]['flags']) is not None + + def _has_3dnow(self): + return re.match(r'.*?\b3dnow\b', self.info[0]['flags']) is not None + + def _has_3dnowext(self): + return re.match(r'.*?\b3dnowext\b', self.info[0]['flags']) is not None + +class IRIXCPUInfo(CPUInfoBase): + info = None + + def __init__(self): + if self.info is not None: + return + info = key_value_from_command('sysconf', sep=' ', + successful_status=(0, 1)) + self.__class__.info = info + + def _not_impl(self): pass + + def _is_singleCPU(self): + return self.info.get('NUM_PROCESSORS') == '1' + + def _getNCPUs(self): + return int(self.info.get('NUM_PROCESSORS', 1)) + + def __cputype(self, n): + return self.info.get('PROCESSORS').split()[0].lower() == 'r%s' % (n) + def _is_r2000(self): return self.__cputype(2000) + def _is_r3000(self): return self.__cputype(3000) + def _is_r3900(self): return self.__cputype(3900) + def _is_r4000(self): return self.__cputype(4000) + def _is_r4100(self): return self.__cputype(4100) + def _is_r4300(self): return self.__cputype(4300) + def _is_r4400(self): return self.__cputype(4400) + def _is_r4600(self): return self.__cputype(4600) + def _is_r4650(self): return self.__cputype(4650) + def _is_r5000(self): return self.__cputype(5000) + def _is_r6000(self): return self.__cputype(6000) + def _is_r8000(self): return self.__cputype(8000) + def _is_r10000(self): return self.__cputype(10000) + def _is_r12000(self): return self.__cputype(12000) + def _is_rorion(self): return self.__cputype('orion') + + def get_ip(self): + try: return self.info.get('MACHINE') + except Exception: pass + def __machine(self, n): + return self.info.get('MACHINE').lower() == 'ip%s' % (n) + def _is_IP19(self): return self.__machine(19) + def _is_IP20(self): return self.__machine(20) + def _is_IP21(self): return self.__machine(21) + def _is_IP22(self): return self.__machine(22) + def _is_IP22_4k(self): return self.__machine(22) and self._is_r4000() + def _is_IP22_5k(self): return self.__machine(22) and self._is_r5000() + def _is_IP24(self): return self.__machine(24) + def _is_IP25(self): return self.__machine(25) + def _is_IP26(self): return self.__machine(26) + def _is_IP27(self): return self.__machine(27) + def _is_IP28(self): return self.__machine(28) + def _is_IP30(self): return self.__machine(30) + def _is_IP32(self): return self.__machine(32) + def _is_IP32_5k(self): return self.__machine(32) and self._is_r5000() + def _is_IP32_10k(self): return self.__machine(32) and self._is_r10000() + + +class DarwinCPUInfo(CPUInfoBase): + info = None + + def __init__(self): + if self.info is not None: + return + info = command_info(arch='arch', + machine='machine') + info['sysctl_hw'] = key_value_from_command('sysctl hw', sep='=') + self.__class__.info = info + + def _not_impl(self): pass + + def _getNCPUs(self): + return int(self.info['sysctl_hw'].get('hw.ncpu', 1)) + + def _is_Power_Macintosh(self): + return self.info['sysctl_hw']['hw.machine']=='Power Macintosh' + + def _is_i386(self): + return self.info['arch']=='i386' + def _is_ppc(self): + return self.info['arch']=='ppc' + + def __machine(self, n): + return self.info['machine'] == 'ppc%s'%n + def _is_ppc601(self): return self.__machine(601) + def _is_ppc602(self): return self.__machine(602) + def _is_ppc603(self): return self.__machine(603) + def _is_ppc603e(self): return self.__machine('603e') + def _is_ppc604(self): return self.__machine(604) + def _is_ppc604e(self): return self.__machine('604e') + def _is_ppc620(self): return self.__machine(620) + def _is_ppc630(self): return self.__machine(630) + def _is_ppc740(self): return self.__machine(740) + def _is_ppc7400(self): return self.__machine(7400) + def _is_ppc7450(self): return self.__machine(7450) + def _is_ppc750(self): return self.__machine(750) + def _is_ppc403(self): return self.__machine(403) + def _is_ppc505(self): return self.__machine(505) + def _is_ppc801(self): return self.__machine(801) + def _is_ppc821(self): return self.__machine(821) + def _is_ppc823(self): return self.__machine(823) + def _is_ppc860(self): return self.__machine(860) + + +class SunOSCPUInfo(CPUInfoBase): + + info = None + + def __init__(self): + if self.info is not None: + return + info = command_info(arch='arch', + mach='mach', + uname_i='uname_i', + isainfo_b='isainfo -b', + isainfo_n='isainfo -n', + ) + info['uname_X'] = key_value_from_command('uname -X', sep='=') + for line in command_by_line('psrinfo -v 0'): + m = re.match(r'\s*The (?P

    [\w\d]+) processor operates at', line) + if m: + info['processor'] = m.group('p') + break + self.__class__.info = info + + def _not_impl(self): pass + + def _is_i386(self): + return self.info['isainfo_n']=='i386' + def _is_sparc(self): + return self.info['isainfo_n']=='sparc' + def _is_sparcv9(self): + return self.info['isainfo_n']=='sparcv9' + + def _getNCPUs(self): + return int(self.info['uname_X'].get('NumCPU', 1)) + + def _is_sun4(self): + return self.info['arch']=='sun4' + + def _is_SUNW(self): + return re.match(r'SUNW', self.info['uname_i']) is not None + def _is_sparcstation5(self): + return re.match(r'.*SPARCstation-5', self.info['uname_i']) is not None + def _is_ultra1(self): + return re.match(r'.*Ultra-1', self.info['uname_i']) is not None + def _is_ultra250(self): + return re.match(r'.*Ultra-250', self.info['uname_i']) is not None + def _is_ultra2(self): + return re.match(r'.*Ultra-2', self.info['uname_i']) is not None + def _is_ultra30(self): + return re.match(r'.*Ultra-30', self.info['uname_i']) is not None + def _is_ultra4(self): + return re.match(r'.*Ultra-4', self.info['uname_i']) is not None + def _is_ultra5_10(self): + return re.match(r'.*Ultra-5_10', self.info['uname_i']) is not None + def _is_ultra5(self): + return re.match(r'.*Ultra-5', self.info['uname_i']) is not None + def _is_ultra60(self): + return re.match(r'.*Ultra-60', self.info['uname_i']) is not None + def _is_ultra80(self): + return re.match(r'.*Ultra-80', self.info['uname_i']) is not None + def _is_ultraenterprice(self): + return re.match(r'.*Ultra-Enterprise', self.info['uname_i']) is not None + def _is_ultraenterprice10k(self): + return re.match(r'.*Ultra-Enterprise-10000', self.info['uname_i']) is not None + def _is_sunfire(self): + return re.match(r'.*Sun-Fire', self.info['uname_i']) is not None + def _is_ultra(self): + return re.match(r'.*Ultra', self.info['uname_i']) is not None + + def _is_cpusparcv7(self): + return self.info['processor']=='sparcv7' + def _is_cpusparcv8(self): + return self.info['processor']=='sparcv8' + def _is_cpusparcv9(self): + return self.info['processor']=='sparcv9' + +class Win32CPUInfo(CPUInfoBase): + + info = None + pkey = r"HARDWARE\DESCRIPTION\System\CentralProcessor" + # XXX: what does the value of + # HKEY_LOCAL_MACHINE\HARDWARE\DESCRIPTION\System\CentralProcessor\0 + # mean? + + def __init__(self): + if self.info is not None: + return + info = [] + try: + #XXX: Bad style to use so long `try:...except:...`. Fix it! + import winreg + + prgx = re.compile(r"family\s+(?P\d+)\s+model\s+(?P\d+)" + r"\s+stepping\s+(?P\d+)", re.IGNORECASE) + chnd=winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, self.pkey) + pnum=0 + while True: + try: + proc=winreg.EnumKey(chnd, pnum) + except winreg.error: + break + else: + pnum+=1 + info.append({"Processor":proc}) + phnd=winreg.OpenKey(chnd, proc) + pidx=0 + while True: + try: + name, value, vtpe=winreg.EnumValue(phnd, pidx) + except winreg.error: + break + else: + pidx=pidx+1 + info[-1][name]=value + if name=="Identifier": + srch=prgx.search(value) + if srch: + info[-1]["Family"]=int(srch.group("FML")) + info[-1]["Model"]=int(srch.group("MDL")) + info[-1]["Stepping"]=int(srch.group("STP")) + except Exception as e: + print(e, '(ignoring)') + self.__class__.info = info + + def _not_impl(self): pass + + # Athlon + + def _is_AMD(self): + return self.info[0]['VendorIdentifier']=='AuthenticAMD' + + def _is_Am486(self): + return self.is_AMD() and self.info[0]['Family']==4 + + def _is_Am5x86(self): + return self.is_AMD() and self.info[0]['Family']==4 + + def _is_AMDK5(self): + return self.is_AMD() and self.info[0]['Family']==5 \ + and self.info[0]['Model'] in [0, 1, 2, 3] + + def _is_AMDK6(self): + return self.is_AMD() and self.info[0]['Family']==5 \ + and self.info[0]['Model'] in [6, 7] + + def _is_AMDK6_2(self): + return self.is_AMD() and self.info[0]['Family']==5 \ + and self.info[0]['Model']==8 + + def _is_AMDK6_3(self): + return self.is_AMD() and self.info[0]['Family']==5 \ + and self.info[0]['Model']==9 + + def _is_AMDK7(self): + return self.is_AMD() and self.info[0]['Family'] == 6 + + # To reliably distinguish between the different types of AMD64 chips + # (Athlon64, Operton, Athlon64 X2, Semperon, Turion 64, etc.) would + # require looking at the 'brand' from cpuid + + def _is_AMD64(self): + return self.is_AMD() and self.info[0]['Family'] == 15 + + # Intel + + def _is_Intel(self): + return self.info[0]['VendorIdentifier']=='GenuineIntel' + + def _is_i386(self): + return self.info[0]['Family']==3 + + def _is_i486(self): + return self.info[0]['Family']==4 + + def _is_i586(self): + return self.is_Intel() and self.info[0]['Family']==5 + + def _is_i686(self): + return self.is_Intel() and self.info[0]['Family']==6 + + def _is_Pentium(self): + return self.is_Intel() and self.info[0]['Family']==5 + + def _is_PentiumMMX(self): + return self.is_Intel() and self.info[0]['Family']==5 \ + and self.info[0]['Model']==4 + + def _is_PentiumPro(self): + return self.is_Intel() and self.info[0]['Family']==6 \ + and self.info[0]['Model']==1 + + def _is_PentiumII(self): + return self.is_Intel() and self.info[0]['Family']==6 \ + and self.info[0]['Model'] in [3, 5, 6] + + def _is_PentiumIII(self): + return self.is_Intel() and self.info[0]['Family']==6 \ + and self.info[0]['Model'] in [7, 8, 9, 10, 11] + + def _is_PentiumIV(self): + return self.is_Intel() and self.info[0]['Family']==15 + + def _is_PentiumM(self): + return self.is_Intel() and self.info[0]['Family'] == 6 \ + and self.info[0]['Model'] in [9, 13, 14] + + def _is_Core2(self): + return self.is_Intel() and self.info[0]['Family'] == 6 \ + and self.info[0]['Model'] in [15, 16, 17] + + # Varia + + def _is_singleCPU(self): + return len(self.info) == 1 + + def _getNCPUs(self): + return len(self.info) + + def _has_mmx(self): + if self.is_Intel(): + return (self.info[0]['Family']==5 and self.info[0]['Model']==4) \ + or (self.info[0]['Family'] in [6, 15]) + elif self.is_AMD(): + return self.info[0]['Family'] in [5, 6, 15] + else: + return False + + def _has_sse(self): + if self.is_Intel(): + return ((self.info[0]['Family']==6 and + self.info[0]['Model'] in [7, 8, 9, 10, 11]) + or self.info[0]['Family']==15) + elif self.is_AMD(): + return ((self.info[0]['Family']==6 and + self.info[0]['Model'] in [6, 7, 8, 10]) + or self.info[0]['Family']==15) + else: + return False + + def _has_sse2(self): + if self.is_Intel(): + return self.is_Pentium4() or self.is_PentiumM() \ + or self.is_Core2() + elif self.is_AMD(): + return self.is_AMD64() + else: + return False + + def _has_3dnow(self): + return self.is_AMD() and self.info[0]['Family'] in [5, 6, 15] + + def _has_3dnowext(self): + return self.is_AMD() and self.info[0]['Family'] in [6, 15] + +if sys.platform.startswith('linux'): # variations: linux2,linux-i386 (any others?) + cpuinfo = LinuxCPUInfo +elif sys.platform.startswith('irix'): + cpuinfo = IRIXCPUInfo +elif sys.platform == 'darwin': + cpuinfo = DarwinCPUInfo +elif sys.platform.startswith('sunos'): + cpuinfo = SunOSCPUInfo +elif sys.platform.startswith('win32'): + cpuinfo = Win32CPUInfo +elif sys.platform.startswith('cygwin'): + cpuinfo = LinuxCPUInfo +#XXX: other OS's. Eg. use _winreg on Win32. Or os.uname on unices. +else: + cpuinfo = CPUInfoBase + +cpu = cpuinfo() + +#if __name__ == "__main__": +# +# cpu.is_blaa() +# cpu.is_Intel() +# cpu.is_Alpha() +# +# print('CPU information:'), +# for name in dir(cpuinfo): +# if name[0]=='_' and name[1]!='_': +# r = getattr(cpu,name[1:])() +# if r: +# if r!=1: +# print('%s=%s' %(name[1:],r)) +# else: +# print(name[1:]), +# print() diff --git a/venv/Lib/site-packages/numpy/distutils/exec_command.py b/venv/Lib/site-packages/numpy/distutils/exec_command.py new file mode 100644 index 0000000..fb10d24 --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/exec_command.py @@ -0,0 +1,316 @@ +""" +exec_command + +Implements exec_command function that is (almost) equivalent to +commands.getstatusoutput function but on NT, DOS systems the +returned status is actually correct (though, the returned status +values may be different by a factor). In addition, exec_command +takes keyword arguments for (re-)defining environment variables. + +Provides functions: + + exec_command --- execute command in a specified directory and + in the modified environment. + find_executable --- locate a command using info from environment + variable PATH. Equivalent to posix `which` + command. + +Author: Pearu Peterson +Created: 11 January 2003 + +Requires: Python 2.x + +Successfully tested on: + +======== ============ ================================================= +os.name sys.platform comments +======== ============ ================================================= +posix linux2 Debian (sid) Linux, Python 2.1.3+, 2.2.3+, 2.3.3 + PyCrust 0.9.3, Idle 1.0.2 +posix linux2 Red Hat 9 Linux, Python 2.1.3, 2.2.2, 2.3.2 +posix sunos5 SunOS 5.9, Python 2.2, 2.3.2 +posix darwin Darwin 7.2.0, Python 2.3 +nt win32 Windows Me + Python 2.3(EE), Idle 1.0, PyCrust 0.7.2 + Python 2.1.1 Idle 0.8 +nt win32 Windows 98, Python 2.1.1. Idle 0.8 +nt win32 Cygwin 98-4.10, Python 2.1.1(MSC) - echo tests + fail i.e. redefining environment variables may + not work. FIXED: don't use cygwin echo! + Comment: also `cmd /c echo` will not work + but redefining environment variables do work. +posix cygwin Cygwin 98-4.10, Python 2.3.3(cygming special) +nt win32 Windows XP, Python 2.3.3 +======== ============ ================================================= + +Known bugs: + +* Tests, that send messages to stderr, fail when executed from MSYS prompt + because the messages are lost at some point. + +""" +__all__ = ['exec_command', 'find_executable'] + +import os +import sys +import subprocess +import locale +import warnings + +from numpy.distutils.misc_util import is_sequence, make_temp_file +from numpy.distutils import log + +def filepath_from_subprocess_output(output): + """ + Convert `bytes` in the encoding used by a subprocess into a filesystem-appropriate `str`. + + Inherited from `exec_command`, and possibly incorrect. + """ + mylocale = locale.getpreferredencoding(False) + if mylocale is None: + mylocale = 'ascii' + output = output.decode(mylocale, errors='replace') + output = output.replace('\r\n', '\n') + # Another historical oddity + if output[-1:] == '\n': + output = output[:-1] + return output + + +def forward_bytes_to_stdout(val): + """ + Forward bytes from a subprocess call to the console, without attempting to + decode them. + + The assumption is that the subprocess call already returned bytes in + a suitable encoding. + """ + if hasattr(sys.stdout, 'buffer'): + # use the underlying binary output if there is one + sys.stdout.buffer.write(val) + elif hasattr(sys.stdout, 'encoding'): + # round-trip the encoding if necessary + sys.stdout.write(val.decode(sys.stdout.encoding)) + else: + # make a best-guess at the encoding + sys.stdout.write(val.decode('utf8', errors='replace')) + + +def temp_file_name(): + # 2019-01-30, 1.17 + warnings.warn('temp_file_name is deprecated since NumPy v1.17, use ' + 'tempfile.mkstemp instead', DeprecationWarning, stacklevel=1) + fo, name = make_temp_file() + fo.close() + return name + +def get_pythonexe(): + pythonexe = sys.executable + if os.name in ['nt', 'dos']: + fdir, fn = os.path.split(pythonexe) + fn = fn.upper().replace('PYTHONW', 'PYTHON') + pythonexe = os.path.join(fdir, fn) + assert os.path.isfile(pythonexe), '%r is not a file' % (pythonexe,) + return pythonexe + +def find_executable(exe, path=None, _cache={}): + """Return full path of a executable or None. + + Symbolic links are not followed. + """ + key = exe, path + try: + return _cache[key] + except KeyError: + pass + log.debug('find_executable(%r)' % exe) + orig_exe = exe + + if path is None: + path = os.environ.get('PATH', os.defpath) + if os.name=='posix': + realpath = os.path.realpath + else: + realpath = lambda a:a + + if exe.startswith('"'): + exe = exe[1:-1] + + suffixes = [''] + if os.name in ['nt', 'dos', 'os2']: + fn, ext = os.path.splitext(exe) + extra_suffixes = ['.exe', '.com', '.bat'] + if ext.lower() not in extra_suffixes: + suffixes = extra_suffixes + + if os.path.isabs(exe): + paths = [''] + else: + paths = [ os.path.abspath(p) for p in path.split(os.pathsep) ] + + for path in paths: + fn = os.path.join(path, exe) + for s in suffixes: + f_ext = fn+s + if not os.path.islink(f_ext): + f_ext = realpath(f_ext) + if os.path.isfile(f_ext) and os.access(f_ext, os.X_OK): + log.info('Found executable %s' % f_ext) + _cache[key] = f_ext + return f_ext + + log.warn('Could not locate executable %s' % orig_exe) + return None + +############################################################ + +def _preserve_environment( names ): + log.debug('_preserve_environment(%r)' % (names)) + env = {name: os.environ.get(name) for name in names} + return env + +def _update_environment( **env ): + log.debug('_update_environment(...)') + for name, value in env.items(): + os.environ[name] = value or '' + +def exec_command(command, execute_in='', use_shell=None, use_tee=None, + _with_python = 1, **env ): + """ + Return (status,output) of executed command. + + .. deprecated:: 1.17 + Use subprocess.Popen instead + + Parameters + ---------- + command : str + A concatenated string of executable and arguments. + execute_in : str + Before running command ``cd execute_in`` and after ``cd -``. + use_shell : {bool, None}, optional + If True, execute ``sh -c command``. Default None (True) + use_tee : {bool, None}, optional + If True use tee. Default None (True) + + + Returns + ------- + res : str + Both stdout and stderr messages. + + Notes + ----- + On NT, DOS systems the returned status is correct for external commands. + Wild cards will not work for non-posix systems or when use_shell=0. + + """ + # 2019-01-30, 1.17 + warnings.warn('exec_command is deprecated since NumPy v1.17, use ' + 'subprocess.Popen instead', DeprecationWarning, stacklevel=1) + log.debug('exec_command(%r,%s)' % (command, + ','.join(['%s=%r'%kv for kv in env.items()]))) + + if use_tee is None: + use_tee = os.name=='posix' + if use_shell is None: + use_shell = os.name=='posix' + execute_in = os.path.abspath(execute_in) + oldcwd = os.path.abspath(os.getcwd()) + + if __name__[-12:] == 'exec_command': + exec_dir = os.path.dirname(os.path.abspath(__file__)) + elif os.path.isfile('exec_command.py'): + exec_dir = os.path.abspath('.') + else: + exec_dir = os.path.abspath(sys.argv[0]) + if os.path.isfile(exec_dir): + exec_dir = os.path.dirname(exec_dir) + + if oldcwd!=execute_in: + os.chdir(execute_in) + log.debug('New cwd: %s' % execute_in) + else: + log.debug('Retaining cwd: %s' % oldcwd) + + oldenv = _preserve_environment( list(env.keys()) ) + _update_environment( **env ) + + try: + st = _exec_command(command, + use_shell=use_shell, + use_tee=use_tee, + **env) + finally: + if oldcwd!=execute_in: + os.chdir(oldcwd) + log.debug('Restored cwd to %s' % oldcwd) + _update_environment(**oldenv) + + return st + + +def _exec_command(command, use_shell=None, use_tee = None, **env): + """ + Internal workhorse for exec_command(). + """ + if use_shell is None: + use_shell = os.name=='posix' + if use_tee is None: + use_tee = os.name=='posix' + + if os.name == 'posix' and use_shell: + # On POSIX, subprocess always uses /bin/sh, override + sh = os.environ.get('SHELL', '/bin/sh') + if is_sequence(command): + command = [sh, '-c', ' '.join(command)] + else: + command = [sh, '-c', command] + use_shell = False + + elif os.name == 'nt' and is_sequence(command): + # On Windows, join the string for CreateProcess() ourselves as + # subprocess does it a bit differently + command = ' '.join(_quote_arg(arg) for arg in command) + + # Inherit environment by default + env = env or None + try: + # universal_newlines is set to False so that communicate() + # will return bytes. We need to decode the output ourselves + # so that Python will not raise a UnicodeDecodeError when + # it encounters an invalid character; rather, we simply replace it + proc = subprocess.Popen(command, shell=use_shell, env=env, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + universal_newlines=False) + except EnvironmentError: + # Return 127, as os.spawn*() and /bin/sh do + return 127, '' + + text, err = proc.communicate() + mylocale = locale.getpreferredencoding(False) + if mylocale is None: + mylocale = 'ascii' + text = text.decode(mylocale, errors='replace') + text = text.replace('\r\n', '\n') + # Another historical oddity + if text[-1:] == '\n': + text = text[:-1] + + if use_tee and text: + print(text) + return proc.returncode, text + + +def _quote_arg(arg): + """ + Quote the argument for safe use in a shell command line. + """ + # If there is a quote in the string, assume relevants parts of the + # string are already quoted (e.g. '-I"C:\\Program Files\\..."') + if '"' not in arg and ' ' in arg: + return '"%s"' % arg + return arg + +############################################################ diff --git a/venv/Lib/site-packages/numpy/distutils/extension.py b/venv/Lib/site-packages/numpy/distutils/extension.py new file mode 100644 index 0000000..67114ef --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/extension.py @@ -0,0 +1,103 @@ +"""distutils.extension + +Provides the Extension class, used to describe C/C++ extension +modules in setup scripts. + +Overridden to support f2py. + +""" +import re +from distutils.extension import Extension as old_Extension + + +cxx_ext_re = re.compile(r'.*[.](cpp|cxx|cc)\Z', re.I).match +fortran_pyf_ext_re = re.compile(r'.*[.](f90|f95|f77|for|ftn|f|pyf)\Z', re.I).match + + +class Extension(old_Extension): + """ + Parameters + ---------- + name : str + Extension name. + sources : list of str + List of source file locations relative to the top directory of + the package. + extra_compile_args : list of str + Extra command line arguments to pass to the compiler. + extra_f77_compile_args : list of str + Extra command line arguments to pass to the fortran77 compiler. + extra_f90_compile_args : list of str + Extra command line arguments to pass to the fortran90 compiler. + """ + def __init__( + self, name, sources, + include_dirs=None, + define_macros=None, + undef_macros=None, + library_dirs=None, + libraries=None, + runtime_library_dirs=None, + extra_objects=None, + extra_compile_args=None, + extra_link_args=None, + export_symbols=None, + swig_opts=None, + depends=None, + language=None, + f2py_options=None, + module_dirs=None, + extra_f77_compile_args=None, + extra_f90_compile_args=None,): + + old_Extension.__init__( + self, name, [], + include_dirs=include_dirs, + define_macros=define_macros, + undef_macros=undef_macros, + library_dirs=library_dirs, + libraries=libraries, + runtime_library_dirs=runtime_library_dirs, + extra_objects=extra_objects, + extra_compile_args=extra_compile_args, + extra_link_args=extra_link_args, + export_symbols=export_symbols) + + # Avoid assert statements checking that sources contains strings: + self.sources = sources + + # Python 2.4 distutils new features + self.swig_opts = swig_opts or [] + # swig_opts is assumed to be a list. Here we handle the case where it + # is specified as a string instead. + if isinstance(self.swig_opts, str): + import warnings + msg = "swig_opts is specified as a string instead of a list" + warnings.warn(msg, SyntaxWarning, stacklevel=2) + self.swig_opts = self.swig_opts.split() + + # Python 2.3 distutils new features + self.depends = depends or [] + self.language = language + + # numpy_distutils features + self.f2py_options = f2py_options or [] + self.module_dirs = module_dirs or [] + self.extra_f77_compile_args = extra_f77_compile_args or [] + self.extra_f90_compile_args = extra_f90_compile_args or [] + + return + + def has_cxx_sources(self): + for source in self.sources: + if cxx_ext_re(str(source)): + return True + return False + + def has_f2py_sources(self): + for source in self.sources: + if fortran_pyf_ext_re(source): + return True + return False + +# class Extension diff --git a/venv/Lib/site-packages/numpy/distutils/fcompiler/__init__.py b/venv/Lib/site-packages/numpy/distutils/fcompiler/__init__.py new file mode 100644 index 0000000..b644175 --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/fcompiler/__init__.py @@ -0,0 +1,1022 @@ +"""numpy.distutils.fcompiler + +Contains FCompiler, an abstract base class that defines the interface +for the numpy.distutils Fortran compiler abstraction model. + +Terminology: + +To be consistent, where the term 'executable' is used, it means the single +file, like 'gcc', that is executed, and should be a string. In contrast, +'command' means the entire command line, like ['gcc', '-c', 'file.c'], and +should be a list. + +But note that FCompiler.executables is actually a dictionary of commands. + +""" +__all__ = ['FCompiler', 'new_fcompiler', 'show_fcompilers', + 'dummy_fortran_file'] + +import os +import sys +import re + +from distutils.sysconfig import get_python_lib +from distutils.fancy_getopt import FancyGetopt +from distutils.errors import DistutilsModuleError, \ + DistutilsExecError, CompileError, LinkError, DistutilsPlatformError +from distutils.util import split_quoted, strtobool + +from numpy.distutils.ccompiler import CCompiler, gen_lib_options +from numpy.distutils import log +from numpy.distutils.misc_util import is_string, all_strings, is_sequence, \ + make_temp_file, get_shared_lib_extension +from numpy.distutils.exec_command import find_executable +from numpy.distutils import _shell_utils + +from .environment import EnvironmentConfig + +__metaclass__ = type + +class CompilerNotFound(Exception): + pass + +def flaglist(s): + if is_string(s): + return split_quoted(s) + else: + return s + +def str2bool(s): + if is_string(s): + return strtobool(s) + return bool(s) + +def is_sequence_of_strings(seq): + return is_sequence(seq) and all_strings(seq) + +class FCompiler(CCompiler): + """Abstract base class to define the interface that must be implemented + by real Fortran compiler classes. + + Methods that subclasses may redefine: + + update_executables(), find_executables(), get_version() + get_flags(), get_flags_opt(), get_flags_arch(), get_flags_debug() + get_flags_f77(), get_flags_opt_f77(), get_flags_arch_f77(), + get_flags_debug_f77(), get_flags_f90(), get_flags_opt_f90(), + get_flags_arch_f90(), get_flags_debug_f90(), + get_flags_fix(), get_flags_linker_so() + + DON'T call these methods (except get_version) after + constructing a compiler instance or inside any other method. + All methods, except update_executables() and find_executables(), + may call the get_version() method. + + After constructing a compiler instance, always call customize(dist=None) + method that finalizes compiler construction and makes the following + attributes available: + compiler_f77 + compiler_f90 + compiler_fix + linker_so + archiver + ranlib + libraries + library_dirs + """ + + # These are the environment variables and distutils keys used. + # Each configuration description is + # (, , , , ) + # The hook names are handled by the self._environment_hook method. + # - names starting with 'self.' call methods in this class + # - names starting with 'exe.' return the key in the executables dict + # - names like 'flags.YYY' return self.get_flag_YYY() + # convert is either None or a function to convert a string to the + # appropriate type used. + + distutils_vars = EnvironmentConfig( + distutils_section='config_fc', + noopt = (None, None, 'noopt', str2bool, False), + noarch = (None, None, 'noarch', str2bool, False), + debug = (None, None, 'debug', str2bool, False), + verbose = (None, None, 'verbose', str2bool, False), + ) + + command_vars = EnvironmentConfig( + distutils_section='config_fc', + compiler_f77 = ('exe.compiler_f77', 'F77', 'f77exec', None, False), + compiler_f90 = ('exe.compiler_f90', 'F90', 'f90exec', None, False), + compiler_fix = ('exe.compiler_fix', 'F90', 'f90exec', None, False), + version_cmd = ('exe.version_cmd', None, None, None, False), + linker_so = ('exe.linker_so', 'LDSHARED', 'ldshared', None, False), + linker_exe = ('exe.linker_exe', 'LD', 'ld', None, False), + archiver = (None, 'AR', 'ar', None, False), + ranlib = (None, 'RANLIB', 'ranlib', None, False), + ) + + flag_vars = EnvironmentConfig( + distutils_section='config_fc', + f77 = ('flags.f77', 'F77FLAGS', 'f77flags', flaglist, True), + f90 = ('flags.f90', 'F90FLAGS', 'f90flags', flaglist, True), + free = ('flags.free', 'FREEFLAGS', 'freeflags', flaglist, True), + fix = ('flags.fix', None, None, flaglist, False), + opt = ('flags.opt', 'FOPT', 'opt', flaglist, True), + opt_f77 = ('flags.opt_f77', None, None, flaglist, False), + opt_f90 = ('flags.opt_f90', None, None, flaglist, False), + arch = ('flags.arch', 'FARCH', 'arch', flaglist, False), + arch_f77 = ('flags.arch_f77', None, None, flaglist, False), + arch_f90 = ('flags.arch_f90', None, None, flaglist, False), + debug = ('flags.debug', 'FDEBUG', 'fdebug', flaglist, True), + debug_f77 = ('flags.debug_f77', None, None, flaglist, False), + debug_f90 = ('flags.debug_f90', None, None, flaglist, False), + flags = ('self.get_flags', 'FFLAGS', 'fflags', flaglist, True), + linker_so = ('flags.linker_so', 'LDFLAGS', 'ldflags', flaglist, True), + linker_exe = ('flags.linker_exe', 'LDFLAGS', 'ldflags', flaglist, True), + ar = ('flags.ar', 'ARFLAGS', 'arflags', flaglist, True), + ) + + language_map = {'.f': 'f77', + '.for': 'f77', + '.F': 'f77', # XXX: needs preprocessor + '.ftn': 'f77', + '.f77': 'f77', + '.f90': 'f90', + '.F90': 'f90', # XXX: needs preprocessor + '.f95': 'f90', + } + language_order = ['f90', 'f77'] + + + # These will be set by the subclass + + compiler_type = None + compiler_aliases = () + version_pattern = None + + possible_executables = [] + executables = { + 'version_cmd': ["f77", "-v"], + 'compiler_f77': ["f77"], + 'compiler_f90': ["f90"], + 'compiler_fix': ["f90", "-fixed"], + 'linker_so': ["f90", "-shared"], + 'linker_exe': ["f90"], + 'archiver': ["ar", "-cr"], + 'ranlib': None, + } + + # If compiler does not support compiling Fortran 90 then it can + # suggest using another compiler. For example, gnu would suggest + # gnu95 compiler type when there are F90 sources. + suggested_f90_compiler = None + + compile_switch = "-c" + object_switch = "-o " # Ending space matters! It will be stripped + # but if it is missing then object_switch + # will be prefixed to object file name by + # string concatenation. + library_switch = "-o " # Ditto! + + # Switch to specify where module files are created and searched + # for USE statement. Normally it is a string and also here ending + # space matters. See above. + module_dir_switch = None + + # Switch to specify where module files are searched for USE statement. + module_include_switch = '-I' + + pic_flags = [] # Flags to create position-independent code + + src_extensions = ['.for', '.ftn', '.f77', '.f', '.f90', '.f95', '.F', '.F90', '.FOR'] + obj_extension = ".o" + + shared_lib_extension = get_shared_lib_extension() + static_lib_extension = ".a" # or .lib + static_lib_format = "lib%s%s" # or %s%s + shared_lib_format = "%s%s" + exe_extension = "" + + _exe_cache = {} + + _executable_keys = ['version_cmd', 'compiler_f77', 'compiler_f90', + 'compiler_fix', 'linker_so', 'linker_exe', 'archiver', + 'ranlib'] + + # This will be set by new_fcompiler when called in + # command/{build_ext.py, build_clib.py, config.py} files. + c_compiler = None + + # extra_{f77,f90}_compile_args are set by build_ext.build_extension method + extra_f77_compile_args = [] + extra_f90_compile_args = [] + + def __init__(self, *args, **kw): + CCompiler.__init__(self, *args, **kw) + self.distutils_vars = self.distutils_vars.clone(self._environment_hook) + self.command_vars = self.command_vars.clone(self._environment_hook) + self.flag_vars = self.flag_vars.clone(self._environment_hook) + self.executables = self.executables.copy() + for e in self._executable_keys: + if e not in self.executables: + self.executables[e] = None + + # Some methods depend on .customize() being called first, so + # this keeps track of whether that's happened yet. + self._is_customised = False + + def __copy__(self): + obj = self.__new__(self.__class__) + obj.__dict__.update(self.__dict__) + obj.distutils_vars = obj.distutils_vars.clone(obj._environment_hook) + obj.command_vars = obj.command_vars.clone(obj._environment_hook) + obj.flag_vars = obj.flag_vars.clone(obj._environment_hook) + obj.executables = obj.executables.copy() + return obj + + def copy(self): + return self.__copy__() + + # Use properties for the attributes used by CCompiler. Setting them + # as attributes from the self.executables dictionary is error-prone, + # so we get them from there each time. + def _command_property(key): + def fget(self): + assert self._is_customised + return self.executables[key] + return property(fget=fget) + version_cmd = _command_property('version_cmd') + compiler_f77 = _command_property('compiler_f77') + compiler_f90 = _command_property('compiler_f90') + compiler_fix = _command_property('compiler_fix') + linker_so = _command_property('linker_so') + linker_exe = _command_property('linker_exe') + archiver = _command_property('archiver') + ranlib = _command_property('ranlib') + + # Make our terminology consistent. + def set_executable(self, key, value): + self.set_command(key, value) + + def set_commands(self, **kw): + for k, v in kw.items(): + self.set_command(k, v) + + def set_command(self, key, value): + if not key in self._executable_keys: + raise ValueError( + "unknown executable '%s' for class %s" % + (key, self.__class__.__name__)) + if is_string(value): + value = split_quoted(value) + assert value is None or is_sequence_of_strings(value[1:]), (key, value) + self.executables[key] = value + + ###################################################################### + ## Methods that subclasses may redefine. But don't call these methods! + ## They are private to FCompiler class and may return unexpected + ## results if used elsewhere. So, you have been warned.. + + def find_executables(self): + """Go through the self.executables dictionary, and attempt to + find and assign appropriate executables. + + Executable names are looked for in the environment (environment + variables, the distutils.cfg, and command line), the 0th-element of + the command list, and the self.possible_executables list. + + Also, if the 0th element is "" or "", the Fortran 77 + or the Fortran 90 compiler executable is used, unless overridden + by an environment setting. + + Subclasses should call this if overridden. + """ + assert self._is_customised + exe_cache = self._exe_cache + def cached_find_executable(exe): + if exe in exe_cache: + return exe_cache[exe] + fc_exe = find_executable(exe) + exe_cache[exe] = exe_cache[fc_exe] = fc_exe + return fc_exe + def verify_command_form(name, value): + if value is not None and not is_sequence_of_strings(value): + raise ValueError( + "%s value %r is invalid in class %s" % + (name, value, self.__class__.__name__)) + def set_exe(exe_key, f77=None, f90=None): + cmd = self.executables.get(exe_key, None) + if not cmd: + return None + # Note that we get cmd[0] here if the environment doesn't + # have anything set + exe_from_environ = getattr(self.command_vars, exe_key) + if not exe_from_environ: + possibles = [f90, f77] + self.possible_executables + else: + possibles = [exe_from_environ] + self.possible_executables + + seen = set() + unique_possibles = [] + for e in possibles: + if e == '': + e = f77 + elif e == '': + e = f90 + if not e or e in seen: + continue + seen.add(e) + unique_possibles.append(e) + + for exe in unique_possibles: + fc_exe = cached_find_executable(exe) + if fc_exe: + cmd[0] = fc_exe + return fc_exe + self.set_command(exe_key, None) + return None + + ctype = self.compiler_type + f90 = set_exe('compiler_f90') + if not f90: + f77 = set_exe('compiler_f77') + if f77: + log.warn('%s: no Fortran 90 compiler found' % ctype) + else: + raise CompilerNotFound('%s: f90 nor f77' % ctype) + else: + f77 = set_exe('compiler_f77', f90=f90) + if not f77: + log.warn('%s: no Fortran 77 compiler found' % ctype) + set_exe('compiler_fix', f90=f90) + + set_exe('linker_so', f77=f77, f90=f90) + set_exe('linker_exe', f77=f77, f90=f90) + set_exe('version_cmd', f77=f77, f90=f90) + set_exe('archiver') + set_exe('ranlib') + + def update_executables(self): + """Called at the beginning of customisation. Subclasses should + override this if they need to set up the executables dictionary. + + Note that self.find_executables() is run afterwards, so the + self.executables dictionary values can contain or as + the command, which will be replaced by the found F77 or F90 + compiler. + """ + pass + + def get_flags(self): + """List of flags common to all compiler types.""" + return [] + self.pic_flags + + def _get_command_flags(self, key): + cmd = self.executables.get(key, None) + if cmd is None: + return [] + return cmd[1:] + + def get_flags_f77(self): + """List of Fortran 77 specific flags.""" + return self._get_command_flags('compiler_f77') + def get_flags_f90(self): + """List of Fortran 90 specific flags.""" + return self._get_command_flags('compiler_f90') + def get_flags_free(self): + """List of Fortran 90 free format specific flags.""" + return [] + def get_flags_fix(self): + """List of Fortran 90 fixed format specific flags.""" + return self._get_command_flags('compiler_fix') + def get_flags_linker_so(self): + """List of linker flags to build a shared library.""" + return self._get_command_flags('linker_so') + def get_flags_linker_exe(self): + """List of linker flags to build an executable.""" + return self._get_command_flags('linker_exe') + def get_flags_ar(self): + """List of archiver flags. """ + return self._get_command_flags('archiver') + def get_flags_opt(self): + """List of architecture independent compiler flags.""" + return [] + def get_flags_arch(self): + """List of architecture dependent compiler flags.""" + return [] + def get_flags_debug(self): + """List of compiler flags to compile with debugging information.""" + return [] + + get_flags_opt_f77 = get_flags_opt_f90 = get_flags_opt + get_flags_arch_f77 = get_flags_arch_f90 = get_flags_arch + get_flags_debug_f77 = get_flags_debug_f90 = get_flags_debug + + def get_libraries(self): + """List of compiler libraries.""" + return self.libraries[:] + def get_library_dirs(self): + """List of compiler library directories.""" + return self.library_dirs[:] + + def get_version(self, force=False, ok_status=[0]): + assert self._is_customised + version = CCompiler.get_version(self, force=force, ok_status=ok_status) + if version is None: + raise CompilerNotFound() + return version + + + ############################################################ + + ## Public methods: + + def customize(self, dist = None): + """Customize Fortran compiler. + + This method gets Fortran compiler specific information from + (i) class definition, (ii) environment, (iii) distutils config + files, and (iv) command line (later overrides earlier). + + This method should be always called after constructing a + compiler instance. But not in __init__ because Distribution + instance is needed for (iii) and (iv). + """ + log.info('customize %s' % (self.__class__.__name__)) + + self._is_customised = True + + self.distutils_vars.use_distribution(dist) + self.command_vars.use_distribution(dist) + self.flag_vars.use_distribution(dist) + + self.update_executables() + + # find_executables takes care of setting the compiler commands, + # version_cmd, linker_so, linker_exe, ar, and ranlib + self.find_executables() + + noopt = self.distutils_vars.get('noopt', False) + noarch = self.distutils_vars.get('noarch', noopt) + debug = self.distutils_vars.get('debug', False) + + f77 = self.command_vars.compiler_f77 + f90 = self.command_vars.compiler_f90 + + f77flags = [] + f90flags = [] + freeflags = [] + fixflags = [] + + if f77: + f77 = _shell_utils.NativeParser.split(f77) + f77flags = self.flag_vars.f77 + if f90: + f90 = _shell_utils.NativeParser.split(f90) + f90flags = self.flag_vars.f90 + freeflags = self.flag_vars.free + # XXX Assuming that free format is default for f90 compiler. + fix = self.command_vars.compiler_fix + # NOTE: this and similar examples are probably just + # excluding --coverage flag when F90 = gfortran --coverage + # instead of putting that flag somewhere more appropriate + # this and similar examples where a Fortran compiler + # environment variable has been customized by CI or a user + # should perhaps eventually be more thoroughly tested and more + # robustly handled + if fix: + fix = _shell_utils.NativeParser.split(fix) + fixflags = self.flag_vars.fix + f90flags + + oflags, aflags, dflags = [], [], [] + # examine get_flags__ for extra flags + # only add them if the method is different from get_flags_ + def get_flags(tag, flags): + # note that self.flag_vars. calls self.get_flags_() + flags.extend(getattr(self.flag_vars, tag)) + this_get = getattr(self, 'get_flags_' + tag) + for name, c, flagvar in [('f77', f77, f77flags), + ('f90', f90, f90flags), + ('f90', fix, fixflags)]: + t = '%s_%s' % (tag, name) + if c and this_get is not getattr(self, 'get_flags_' + t): + flagvar.extend(getattr(self.flag_vars, t)) + if not noopt: + get_flags('opt', oflags) + if not noarch: + get_flags('arch', aflags) + if debug: + get_flags('debug', dflags) + + fflags = self.flag_vars.flags + dflags + oflags + aflags + + if f77: + self.set_commands(compiler_f77=f77+f77flags+fflags) + if f90: + self.set_commands(compiler_f90=f90+freeflags+f90flags+fflags) + if fix: + self.set_commands(compiler_fix=fix+fixflags+fflags) + + + #XXX: Do we need LDSHARED->SOSHARED, LDFLAGS->SOFLAGS + linker_so = self.linker_so + if linker_so: + linker_so_flags = self.flag_vars.linker_so + if sys.platform.startswith('aix'): + python_lib = get_python_lib(standard_lib=1) + ld_so_aix = os.path.join(python_lib, 'config', 'ld_so_aix') + python_exp = os.path.join(python_lib, 'config', 'python.exp') + linker_so = [ld_so_aix] + linker_so + ['-bI:'+python_exp] + self.set_commands(linker_so=linker_so+linker_so_flags) + + linker_exe = self.linker_exe + if linker_exe: + linker_exe_flags = self.flag_vars.linker_exe + self.set_commands(linker_exe=linker_exe+linker_exe_flags) + + ar = self.command_vars.archiver + if ar: + arflags = self.flag_vars.ar + self.set_commands(archiver=[ar]+arflags) + + self.set_library_dirs(self.get_library_dirs()) + self.set_libraries(self.get_libraries()) + + def dump_properties(self): + """Print out the attributes of a compiler instance.""" + props = [] + for key in list(self.executables.keys()) + \ + ['version', 'libraries', 'library_dirs', + 'object_switch', 'compile_switch']: + if hasattr(self, key): + v = getattr(self, key) + props.append((key, None, '= '+repr(v))) + props.sort() + + pretty_printer = FancyGetopt(props) + for l in pretty_printer.generate_help("%s instance properties:" \ + % (self.__class__.__name__)): + if l[:4]==' --': + l = ' ' + l[4:] + print(l) + + ################### + + def _compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts): + """Compile 'src' to product 'obj'.""" + src_flags = {} + if is_f_file(src) and not has_f90_header(src): + flavor = ':f77' + compiler = self.compiler_f77 + src_flags = get_f77flags(src) + extra_compile_args = self.extra_f77_compile_args or [] + elif is_free_format(src): + flavor = ':f90' + compiler = self.compiler_f90 + if compiler is None: + raise DistutilsExecError('f90 not supported by %s needed for %s'\ + % (self.__class__.__name__, src)) + extra_compile_args = self.extra_f90_compile_args or [] + else: + flavor = ':fix' + compiler = self.compiler_fix + if compiler is None: + raise DistutilsExecError('f90 (fixed) not supported by %s needed for %s'\ + % (self.__class__.__name__, src)) + extra_compile_args = self.extra_f90_compile_args or [] + if self.object_switch[-1]==' ': + o_args = [self.object_switch.strip(), obj] + else: + o_args = [self.object_switch.strip()+obj] + + assert self.compile_switch.strip() + s_args = [self.compile_switch, src] + + if extra_compile_args: + log.info('extra %s options: %r' \ + % (flavor[1:], ' '.join(extra_compile_args))) + + extra_flags = src_flags.get(self.compiler_type, []) + if extra_flags: + log.info('using compile options from source: %r' \ + % ' '.join(extra_flags)) + + command = compiler + cc_args + extra_flags + s_args + o_args \ + + extra_postargs + extra_compile_args + + display = '%s: %s' % (os.path.basename(compiler[0]) + flavor, + src) + try: + self.spawn(command, display=display) + except DistutilsExecError as e: + msg = str(e) + raise CompileError(msg) + + def module_options(self, module_dirs, module_build_dir): + options = [] + if self.module_dir_switch is not None: + if self.module_dir_switch[-1]==' ': + options.extend([self.module_dir_switch.strip(), module_build_dir]) + else: + options.append(self.module_dir_switch.strip()+module_build_dir) + else: + print('XXX: module_build_dir=%r option ignored' % (module_build_dir)) + print('XXX: Fix module_dir_switch for ', self.__class__.__name__) + if self.module_include_switch is not None: + for d in [module_build_dir]+module_dirs: + options.append('%s%s' % (self.module_include_switch, d)) + else: + print('XXX: module_dirs=%r option ignored' % (module_dirs)) + print('XXX: Fix module_include_switch for ', self.__class__.__name__) + return options + + def library_option(self, lib): + return "-l" + lib + def library_dir_option(self, dir): + return "-L" + dir + + def link(self, target_desc, objects, + output_filename, output_dir=None, libraries=None, + library_dirs=None, runtime_library_dirs=None, + export_symbols=None, debug=0, extra_preargs=None, + extra_postargs=None, build_temp=None, target_lang=None): + objects, output_dir = self._fix_object_args(objects, output_dir) + libraries, library_dirs, runtime_library_dirs = \ + self._fix_lib_args(libraries, library_dirs, runtime_library_dirs) + + lib_opts = gen_lib_options(self, library_dirs, runtime_library_dirs, + libraries) + if is_string(output_dir): + output_filename = os.path.join(output_dir, output_filename) + elif output_dir is not None: + raise TypeError("'output_dir' must be a string or None") + + if self._need_link(objects, output_filename): + if self.library_switch[-1]==' ': + o_args = [self.library_switch.strip(), output_filename] + else: + o_args = [self.library_switch.strip()+output_filename] + + if is_string(self.objects): + ld_args = objects + [self.objects] + else: + ld_args = objects + self.objects + ld_args = ld_args + lib_opts + o_args + if debug: + ld_args[:0] = ['-g'] + if extra_preargs: + ld_args[:0] = extra_preargs + if extra_postargs: + ld_args.extend(extra_postargs) + self.mkpath(os.path.dirname(output_filename)) + if target_desc == CCompiler.EXECUTABLE: + linker = self.linker_exe[:] + else: + linker = self.linker_so[:] + command = linker + ld_args + try: + self.spawn(command) + except DistutilsExecError as e: + msg = str(e) + raise LinkError(msg) + else: + log.debug("skipping %s (up-to-date)", output_filename) + + def _environment_hook(self, name, hook_name): + if hook_name is None: + return None + if is_string(hook_name): + if hook_name.startswith('self.'): + hook_name = hook_name[5:] + hook = getattr(self, hook_name) + return hook() + elif hook_name.startswith('exe.'): + hook_name = hook_name[4:] + var = self.executables[hook_name] + if var: + return var[0] + else: + return None + elif hook_name.startswith('flags.'): + hook_name = hook_name[6:] + hook = getattr(self, 'get_flags_' + hook_name) + return hook() + else: + return hook_name() + + def can_ccompiler_link(self, ccompiler): + """ + Check if the given C compiler can link objects produced by + this compiler. + """ + return True + + def wrap_unlinkable_objects(self, objects, output_dir, extra_dll_dir): + """ + Convert a set of object files that are not compatible with the default + linker, to a file that is compatible. + + Parameters + ---------- + objects : list + List of object files to include. + output_dir : str + Output directory to place generated object files. + extra_dll_dir : str + Output directory to place extra DLL files that need to be + included on Windows. + + Returns + ------- + converted_objects : list of str + List of converted object files. + Note that the number of output files is not necessarily + the same as inputs. + + """ + raise NotImplementedError() + + ## class FCompiler + +_default_compilers = ( + # sys.platform mappings + ('win32', ('gnu', 'intelv', 'absoft', 'compaqv', 'intelev', 'gnu95', 'g95', + 'intelvem', 'intelem', 'flang')), + ('cygwin.*', ('gnu', 'intelv', 'absoft', 'compaqv', 'intelev', 'gnu95', 'g95')), + ('linux.*', ('gnu95', 'intel', 'lahey', 'pg', 'nv', 'absoft', 'nag', 'vast', 'compaq', + 'intele', 'intelem', 'gnu', 'g95', 'pathf95', 'nagfor', 'fujitsu')), + ('darwin.*', ('gnu95', 'nag', 'absoft', 'ibm', 'intel', 'gnu', 'g95', 'pg')), + ('sunos.*', ('sun', 'gnu', 'gnu95', 'g95')), + ('irix.*', ('mips', 'gnu', 'gnu95',)), + ('aix.*', ('ibm', 'gnu', 'gnu95',)), + # os.name mappings + ('posix', ('gnu', 'gnu95',)), + ('nt', ('gnu', 'gnu95',)), + ('mac', ('gnu95', 'gnu', 'pg')), + ) + +fcompiler_class = None +fcompiler_aliases = None + +def load_all_fcompiler_classes(): + """Cache all the FCompiler classes found in modules in the + numpy.distutils.fcompiler package. + """ + from glob import glob + global fcompiler_class, fcompiler_aliases + if fcompiler_class is not None: + return + pys = os.path.join(os.path.dirname(__file__), '*.py') + fcompiler_class = {} + fcompiler_aliases = {} + for fname in glob(pys): + module_name, ext = os.path.splitext(os.path.basename(fname)) + module_name = 'numpy.distutils.fcompiler.' + module_name + __import__ (module_name) + module = sys.modules[module_name] + if hasattr(module, 'compilers'): + for cname in module.compilers: + klass = getattr(module, cname) + desc = (klass.compiler_type, klass, klass.description) + fcompiler_class[klass.compiler_type] = desc + for alias in klass.compiler_aliases: + if alias in fcompiler_aliases: + raise ValueError("alias %r defined for both %s and %s" + % (alias, klass.__name__, + fcompiler_aliases[alias][1].__name__)) + fcompiler_aliases[alias] = desc + +def _find_existing_fcompiler(compiler_types, + osname=None, platform=None, + requiref90=False, + c_compiler=None): + from numpy.distutils.core import get_distribution + dist = get_distribution(always=True) + for compiler_type in compiler_types: + v = None + try: + c = new_fcompiler(plat=platform, compiler=compiler_type, + c_compiler=c_compiler) + c.customize(dist) + v = c.get_version() + if requiref90 and c.compiler_f90 is None: + v = None + new_compiler = c.suggested_f90_compiler + if new_compiler: + log.warn('Trying %r compiler as suggested by %r ' + 'compiler for f90 support.' % (compiler_type, + new_compiler)) + c = new_fcompiler(plat=platform, compiler=new_compiler, + c_compiler=c_compiler) + c.customize(dist) + v = c.get_version() + if v is not None: + compiler_type = new_compiler + if requiref90 and c.compiler_f90 is None: + raise ValueError('%s does not support compiling f90 codes, ' + 'skipping.' % (c.__class__.__name__)) + except DistutilsModuleError: + log.debug("_find_existing_fcompiler: compiler_type='%s' raised DistutilsModuleError", compiler_type) + except CompilerNotFound: + log.debug("_find_existing_fcompiler: compiler_type='%s' not found", compiler_type) + if v is not None: + return compiler_type + return None + +def available_fcompilers_for_platform(osname=None, platform=None): + if osname is None: + osname = os.name + if platform is None: + platform = sys.platform + matching_compiler_types = [] + for pattern, compiler_type in _default_compilers: + if re.match(pattern, platform) or re.match(pattern, osname): + for ct in compiler_type: + if ct not in matching_compiler_types: + matching_compiler_types.append(ct) + if not matching_compiler_types: + matching_compiler_types.append('gnu') + return matching_compiler_types + +def get_default_fcompiler(osname=None, platform=None, requiref90=False, + c_compiler=None): + """Determine the default Fortran compiler to use for the given + platform.""" + matching_compiler_types = available_fcompilers_for_platform(osname, + platform) + log.info("get_default_fcompiler: matching types: '%s'", + matching_compiler_types) + compiler_type = _find_existing_fcompiler(matching_compiler_types, + osname=osname, + platform=platform, + requiref90=requiref90, + c_compiler=c_compiler) + return compiler_type + +# Flag to avoid rechecking for Fortran compiler every time +failed_fcompilers = set() + +def new_fcompiler(plat=None, + compiler=None, + verbose=0, + dry_run=0, + force=0, + requiref90=False, + c_compiler = None): + """Generate an instance of some FCompiler subclass for the supplied + platform/compiler combination. + """ + global failed_fcompilers + fcompiler_key = (plat, compiler) + if fcompiler_key in failed_fcompilers: + return None + + load_all_fcompiler_classes() + if plat is None: + plat = os.name + if compiler is None: + compiler = get_default_fcompiler(plat, requiref90=requiref90, + c_compiler=c_compiler) + if compiler in fcompiler_class: + module_name, klass, long_description = fcompiler_class[compiler] + elif compiler in fcompiler_aliases: + module_name, klass, long_description = fcompiler_aliases[compiler] + else: + msg = "don't know how to compile Fortran code on platform '%s'" % plat + if compiler is not None: + msg = msg + " with '%s' compiler." % compiler + msg = msg + " Supported compilers are: %s)" \ + % (','.join(fcompiler_class.keys())) + log.warn(msg) + failed_fcompilers.add(fcompiler_key) + return None + + compiler = klass(verbose=verbose, dry_run=dry_run, force=force) + compiler.c_compiler = c_compiler + return compiler + +def show_fcompilers(dist=None): + """Print list of available compilers (used by the "--help-fcompiler" + option to "config_fc"). + """ + if dist is None: + from distutils.dist import Distribution + from numpy.distutils.command.config_compiler import config_fc + dist = Distribution() + dist.script_name = os.path.basename(sys.argv[0]) + dist.script_args = ['config_fc'] + sys.argv[1:] + try: + dist.script_args.remove('--help-fcompiler') + except ValueError: + pass + dist.cmdclass['config_fc'] = config_fc + dist.parse_config_files() + dist.parse_command_line() + compilers = [] + compilers_na = [] + compilers_ni = [] + if not fcompiler_class: + load_all_fcompiler_classes() + platform_compilers = available_fcompilers_for_platform() + for compiler in platform_compilers: + v = None + log.set_verbosity(-2) + try: + c = new_fcompiler(compiler=compiler, verbose=dist.verbose) + c.customize(dist) + v = c.get_version() + except (DistutilsModuleError, CompilerNotFound) as e: + log.debug("show_fcompilers: %s not found" % (compiler,)) + log.debug(repr(e)) + + if v is None: + compilers_na.append(("fcompiler="+compiler, None, + fcompiler_class[compiler][2])) + else: + c.dump_properties() + compilers.append(("fcompiler="+compiler, None, + fcompiler_class[compiler][2] + ' (%s)' % v)) + + compilers_ni = list(set(fcompiler_class.keys()) - set(platform_compilers)) + compilers_ni = [("fcompiler="+fc, None, fcompiler_class[fc][2]) + for fc in compilers_ni] + + compilers.sort() + compilers_na.sort() + compilers_ni.sort() + pretty_printer = FancyGetopt(compilers) + pretty_printer.print_help("Fortran compilers found:") + pretty_printer = FancyGetopt(compilers_na) + pretty_printer.print_help("Compilers available for this " + "platform, but not found:") + if compilers_ni: + pretty_printer = FancyGetopt(compilers_ni) + pretty_printer.print_help("Compilers not available on this platform:") + print("For compiler details, run 'config_fc --verbose' setup command.") + + +def dummy_fortran_file(): + fo, name = make_temp_file(suffix='.f') + fo.write(" subroutine dummy()\n end\n") + fo.close() + return name[:-2] + + +is_f_file = re.compile(r'.*[.](for|ftn|f77|f)\Z', re.I).match +_has_f_header = re.compile(r'-[*]-\s*fortran\s*-[*]-', re.I).search +_has_f90_header = re.compile(r'-[*]-\s*f90\s*-[*]-', re.I).search +_has_fix_header = re.compile(r'-[*]-\s*fix\s*-[*]-', re.I).search +_free_f90_start = re.compile(r'[^c*!]\s*[^\s\d\t]', re.I).match + +def is_free_format(file): + """Check if file is in free format Fortran.""" + # f90 allows both fixed and free format, assuming fixed unless + # signs of free format are detected. + result = 0 + with open(file, encoding='latin1') as f: + line = f.readline() + n = 10000 # the number of non-comment lines to scan for hints + if _has_f_header(line) or _has_fix_header(line): + n = 0 + elif _has_f90_header(line): + n = 0 + result = 1 + while n>0 and line: + line = line.rstrip() + if line and line[0]!='!': + n -= 1 + if (line[0]!='\t' and _free_f90_start(line[:5])) or line[-1:]=='&': + result = 1 + break + line = f.readline() + return result + +def has_f90_header(src): + with open(src, encoding='latin1') as f: + line = f.readline() + return _has_f90_header(line) or _has_fix_header(line) + +_f77flags_re = re.compile(r'(c|)f77flags\s*\(\s*(?P\w+)\s*\)\s*=\s*(?P.*)', re.I) +def get_f77flags(src): + """ + Search the first 20 lines of fortran 77 code for line pattern + `CF77FLAGS()=` + Return a dictionary {:}. + """ + flags = {} + with open(src, encoding='latin1') as f: + i = 0 + for line in f: + i += 1 + if i>20: break + m = _f77flags_re.match(line) + if not m: continue + fcname = m.group('fcname').strip() + fflags = m.group('fflags').strip() + flags[fcname] = split_quoted(fflags) + return flags + +# TODO: implement get_f90flags and use it in _compile similarly to get_f77flags + +if __name__ == '__main__': + show_fcompilers() diff --git a/venv/Lib/site-packages/numpy/distutils/fcompiler/absoft.py b/venv/Lib/site-packages/numpy/distutils/fcompiler/absoft.py new file mode 100644 index 0000000..efe3a4c --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/fcompiler/absoft.py @@ -0,0 +1,156 @@ + +# http://www.absoft.com/literature/osxuserguide.pdf +# http://www.absoft.com/documentation.html + +# Notes: +# - when using -g77 then use -DUNDERSCORE_G77 to compile f2py +# generated extension modules (works for f2py v2.45.241_1936 and up) +import os + +from numpy.distutils.cpuinfo import cpu +from numpy.distutils.fcompiler import FCompiler, dummy_fortran_file +from numpy.distutils.misc_util import cyg2win32 + +compilers = ['AbsoftFCompiler'] + +class AbsoftFCompiler(FCompiler): + + compiler_type = 'absoft' + description = 'Absoft Corp Fortran Compiler' + #version_pattern = r'FORTRAN 77 Compiler (?P[^\s*,]*).*?Absoft Corp' + version_pattern = r'(f90:.*?(Absoft Pro FORTRAN Version|FORTRAN 77 Compiler|Absoft Fortran Compiler Version|Copyright Absoft Corporation.*?Version))'+\ + r' (?P[^\s*,]*)(.*?Absoft Corp|)' + + # on windows: f90 -V -c dummy.f + # f90: Copyright Absoft Corporation 1994-1998 mV2; Cray Research, Inc. 1994-1996 CF90 (2.x.x.x f36t87) Version 2.3 Wed Apr 19, 2006 13:05:16 + + # samt5735(8)$ f90 -V -c dummy.f + # f90: Copyright Absoft Corporation 1994-2002; Absoft Pro FORTRAN Version 8.0 + # Note that fink installs g77 as f77, so need to use f90 for detection. + + executables = { + 'version_cmd' : None, # set by update_executables + 'compiler_f77' : ["f77"], + 'compiler_fix' : ["f90"], + 'compiler_f90' : ["f90"], + 'linker_so' : [""], + 'archiver' : ["ar", "-cr"], + 'ranlib' : ["ranlib"] + } + + if os.name=='nt': + library_switch = '/out:' #No space after /out:! + + module_dir_switch = None + module_include_switch = '-p' + + def update_executables(self): + f = cyg2win32(dummy_fortran_file()) + self.executables['version_cmd'] = ['', '-V', '-c', + f+'.f', '-o', f+'.o'] + + def get_flags_linker_so(self): + if os.name=='nt': + opt = ['/dll'] + # The "-K shared" switches are being left in for pre-9.0 versions + # of Absoft though I don't think versions earlier than 9 can + # actually be used to build shared libraries. In fact, version + # 8 of Absoft doesn't recognize "-K shared" and will fail. + elif self.get_version() >= '9.0': + opt = ['-shared'] + else: + opt = ["-K", "shared"] + return opt + + def library_dir_option(self, dir): + if os.name=='nt': + return ['-link', '/PATH:%s' % (dir)] + return "-L" + dir + + def library_option(self, lib): + if os.name=='nt': + return '%s.lib' % (lib) + return "-l" + lib + + def get_library_dirs(self): + opt = FCompiler.get_library_dirs(self) + d = os.environ.get('ABSOFT') + if d: + if self.get_version() >= '10.0': + # use shared libraries, the static libraries were not compiled -fPIC + prefix = 'sh' + else: + prefix = '' + if cpu.is_64bit(): + suffix = '64' + else: + suffix = '' + opt.append(os.path.join(d, '%slib%s' % (prefix, suffix))) + return opt + + def get_libraries(self): + opt = FCompiler.get_libraries(self) + if self.get_version() >= '11.0': + opt.extend(['af90math', 'afio', 'af77math', 'amisc']) + elif self.get_version() >= '10.0': + opt.extend(['af90math', 'afio', 'af77math', 'U77']) + elif self.get_version() >= '8.0': + opt.extend(['f90math', 'fio', 'f77math', 'U77']) + else: + opt.extend(['fio', 'f90math', 'fmath', 'U77']) + if os.name =='nt': + opt.append('COMDLG32') + return opt + + def get_flags(self): + opt = FCompiler.get_flags(self) + if os.name != 'nt': + opt.extend(['-s']) + if self.get_version(): + if self.get_version()>='8.2': + opt.append('-fpic') + return opt + + def get_flags_f77(self): + opt = FCompiler.get_flags_f77(self) + opt.extend(['-N22', '-N90', '-N110']) + v = self.get_version() + if os.name == 'nt': + if v and v>='8.0': + opt.extend(['-f', '-N15']) + else: + opt.append('-f') + if v: + if v<='4.6': + opt.append('-B108') + else: + # Though -N15 is undocumented, it works with + # Absoft 8.0 on Linux + opt.append('-N15') + return opt + + def get_flags_f90(self): + opt = FCompiler.get_flags_f90(self) + opt.extend(["-YCFRL=1", "-YCOM_NAMES=LCS", "-YCOM_PFX", "-YEXT_PFX", + "-YCOM_SFX=_", "-YEXT_SFX=_", "-YEXT_NAMES=LCS"]) + if self.get_version(): + if self.get_version()>'4.6': + opt.extend(["-YDEALLOC=ALL"]) + return opt + + def get_flags_fix(self): + opt = FCompiler.get_flags_fix(self) + opt.extend(["-YCFRL=1", "-YCOM_NAMES=LCS", "-YCOM_PFX", "-YEXT_PFX", + "-YCOM_SFX=_", "-YEXT_SFX=_", "-YEXT_NAMES=LCS"]) + opt.extend(["-f", "fixed"]) + return opt + + def get_flags_opt(self): + opt = ['-O'] + return opt + +if __name__ == '__main__': + from distutils import log + log.set_verbosity(2) + from numpy.distutils import customized_fcompiler + print(customized_fcompiler(compiler='absoft').get_version()) diff --git a/venv/Lib/site-packages/numpy/distutils/fcompiler/compaq.py b/venv/Lib/site-packages/numpy/distutils/fcompiler/compaq.py new file mode 100644 index 0000000..1a35686 --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/fcompiler/compaq.py @@ -0,0 +1,120 @@ + +#http://www.compaq.com/fortran/docs/ +import os +import sys + +from numpy.distutils.fcompiler import FCompiler +from distutils.errors import DistutilsPlatformError + +compilers = ['CompaqFCompiler'] +if os.name != 'posix' or sys.platform[:6] == 'cygwin' : + # Otherwise we'd get a false positive on posix systems with + # case-insensitive filesystems (like darwin), because we'll pick + # up /bin/df + compilers.append('CompaqVisualFCompiler') + +class CompaqFCompiler(FCompiler): + + compiler_type = 'compaq' + description = 'Compaq Fortran Compiler' + version_pattern = r'Compaq Fortran (?P[^\s]*).*' + + if sys.platform[:5]=='linux': + fc_exe = 'fort' + else: + fc_exe = 'f90' + + executables = { + 'version_cmd' : ['', "-version"], + 'compiler_f77' : [fc_exe, "-f77rtl", "-fixed"], + 'compiler_fix' : [fc_exe, "-fixed"], + 'compiler_f90' : [fc_exe], + 'linker_so' : [''], + 'archiver' : ["ar", "-cr"], + 'ranlib' : ["ranlib"] + } + + module_dir_switch = '-module ' # not tested + module_include_switch = '-I' + + def get_flags(self): + return ['-assume no2underscore', '-nomixed_str_len_arg'] + def get_flags_debug(self): + return ['-g', '-check bounds'] + def get_flags_opt(self): + return ['-O4', '-align dcommons', '-assume bigarrays', + '-assume nozsize', '-math_library fast'] + def get_flags_arch(self): + return ['-arch host', '-tune host'] + def get_flags_linker_so(self): + if sys.platform[:5]=='linux': + return ['-shared'] + return ['-shared', '-Wl,-expect_unresolved,*'] + +class CompaqVisualFCompiler(FCompiler): + + compiler_type = 'compaqv' + description = 'DIGITAL or Compaq Visual Fortran Compiler' + version_pattern = (r'(DIGITAL|Compaq) Visual Fortran Optimizing Compiler' + r' Version (?P[^\s]*).*') + + compile_switch = '/compile_only' + object_switch = '/object:' + library_switch = '/OUT:' #No space after /OUT:! + + static_lib_extension = ".lib" + static_lib_format = "%s%s" + module_dir_switch = '/module:' + module_include_switch = '/I' + + ar_exe = 'lib.exe' + fc_exe = 'DF' + + if sys.platform=='win32': + from numpy.distutils.msvccompiler import MSVCCompiler + + try: + m = MSVCCompiler() + m.initialize() + ar_exe = m.lib + except DistutilsPlatformError: + pass + except AttributeError as e: + if '_MSVCCompiler__root' in str(e): + print('Ignoring "%s" (I think it is msvccompiler.py bug)' % (e)) + else: + raise + except IOError as e: + if not "vcvarsall.bat" in str(e): + print("Unexpected IOError in", __file__) + raise e + except ValueError as e: + if not "'path'" in str(e): + print("Unexpected ValueError in", __file__) + raise e + + executables = { + 'version_cmd' : ['', "/what"], + 'compiler_f77' : [fc_exe, "/f77rtl", "/fixed"], + 'compiler_fix' : [fc_exe, "/fixed"], + 'compiler_f90' : [fc_exe], + 'linker_so' : [''], + 'archiver' : [ar_exe, "/OUT:"], + 'ranlib' : None + } + + def get_flags(self): + return ['/nologo', '/MD', '/WX', '/iface=(cref,nomixed_str_len_arg)', + '/names:lowercase', '/assume:underscore'] + def get_flags_opt(self): + return ['/Ox', '/fast', '/optimize:5', '/unroll:0', '/math_library:fast'] + def get_flags_arch(self): + return ['/threads'] + def get_flags_debug(self): + return ['/debug'] + +if __name__ == '__main__': + from distutils import log + log.set_verbosity(2) + from numpy.distutils import customized_fcompiler + print(customized_fcompiler(compiler='compaq').get_version()) diff --git a/venv/Lib/site-packages/numpy/distutils/fcompiler/environment.py b/venv/Lib/site-packages/numpy/distutils/fcompiler/environment.py new file mode 100644 index 0000000..ecd4d99 --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/fcompiler/environment.py @@ -0,0 +1,88 @@ +import os +from distutils.dist import Distribution + +__metaclass__ = type + +class EnvironmentConfig: + def __init__(self, distutils_section='ALL', **kw): + self._distutils_section = distutils_section + self._conf_keys = kw + self._conf = None + self._hook_handler = None + + def dump_variable(self, name): + conf_desc = self._conf_keys[name] + hook, envvar, confvar, convert, append = conf_desc + if not convert: + convert = lambda x : x + print('%s.%s:' % (self._distutils_section, name)) + v = self._hook_handler(name, hook) + print(' hook : %s' % (convert(v),)) + if envvar: + v = os.environ.get(envvar, None) + print(' environ: %s' % (convert(v),)) + if confvar and self._conf: + v = self._conf.get(confvar, (None, None))[1] + print(' config : %s' % (convert(v),)) + + def dump_variables(self): + for name in self._conf_keys: + self.dump_variable(name) + + def __getattr__(self, name): + try: + conf_desc = self._conf_keys[name] + except KeyError: + raise AttributeError( + f"'EnvironmentConfig' object has no attribute '{name}'" + ) from None + + return self._get_var(name, conf_desc) + + def get(self, name, default=None): + try: + conf_desc = self._conf_keys[name] + except KeyError: + return default + var = self._get_var(name, conf_desc) + if var is None: + var = default + return var + + def _get_var(self, name, conf_desc): + hook, envvar, confvar, convert, append = conf_desc + if convert is None: + convert = lambda x: x + var = self._hook_handler(name, hook) + if envvar is not None: + envvar_contents = os.environ.get(envvar) + if envvar_contents is not None: + envvar_contents = convert(envvar_contents) + if var and append: + if os.environ.get('NPY_DISTUTILS_APPEND_FLAGS', '1') == '1': + var.extend(envvar_contents) + else: + # NPY_DISTUTILS_APPEND_FLAGS was explicitly set to 0 + # to keep old (overwrite flags rather than append to + # them) behavior + var = envvar_contents + else: + var = envvar_contents + if confvar is not None and self._conf: + if confvar in self._conf: + source, confvar_contents = self._conf[confvar] + var = convert(confvar_contents) + return var + + + def clone(self, hook_handler): + ec = self.__class__(distutils_section=self._distutils_section, + **self._conf_keys) + ec._hook_handler = hook_handler + return ec + + def use_distribution(self, dist): + if isinstance(dist, Distribution): + self._conf = dist.get_option_dict(self._distutils_section) + else: + self._conf = dist diff --git a/venv/Lib/site-packages/numpy/distutils/fcompiler/fujitsu.py b/venv/Lib/site-packages/numpy/distutils/fcompiler/fujitsu.py new file mode 100644 index 0000000..ddce674 --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/fcompiler/fujitsu.py @@ -0,0 +1,46 @@ +""" +fujitsu + +Supports Fujitsu compiler function. +This compiler is developed by Fujitsu and is used in A64FX on Fugaku. +""" +from numpy.distutils.fcompiler import FCompiler + +compilers = ['FujitsuFCompiler'] + +class FujitsuFCompiler(FCompiler): + compiler_type = 'fujitsu' + description = 'Fujitsu Fortran Compiler' + + possible_executables = ['frt'] + version_pattern = r'frt \(FRT\) (?P[a-z\d.]+)' + # $ frt --version + # frt (FRT) x.x.x yyyymmdd + + executables = { + 'version_cmd' : ["", "--version"], + 'compiler_f77' : ["frt", "-Fixed"], + 'compiler_fix' : ["frt", "-Fixed"], + 'compiler_f90' : ["frt"], + 'linker_so' : ["frt", "-shared"], + 'archiver' : ["ar", "-cr"], + 'ranlib' : ["ranlib"] + } + pic_flags = ['-KPIC'] + module_dir_switch = '-M' + module_include_switch = '-I' + + def get_flags_opt(self): + return ['-O3'] + def get_flags_debug(self): + return ['-g'] + def runtime_library_dir_option(self, dir): + return f'-Wl,-rpath={dir}' + def get_libraries(self): + return ['fj90f', 'fj90i', 'fjsrcinfo'] + +if __name__ == '__main__': + from distutils import log + from numpy.distutils import customized_fcompiler + log.set_verbosity(2) + print(customized_fcompiler('fujitsu').get_version()) diff --git a/venv/Lib/site-packages/numpy/distutils/fcompiler/g95.py b/venv/Lib/site-packages/numpy/distutils/fcompiler/g95.py new file mode 100644 index 0000000..e109a97 --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/fcompiler/g95.py @@ -0,0 +1,42 @@ +# http://g95.sourceforge.net/ +from numpy.distutils.fcompiler import FCompiler + +compilers = ['G95FCompiler'] + +class G95FCompiler(FCompiler): + compiler_type = 'g95' + description = 'G95 Fortran Compiler' + +# version_pattern = r'G95 \((GCC (?P[\d.]+)|.*?) \(g95!\) (?P.*)\).*' + # $ g95 --version + # G95 (GCC 4.0.3 (g95!) May 22 2006) + + version_pattern = r'G95 \((GCC (?P[\d.]+)|.*?) \(g95 (?P.*)!\) (?P.*)\).*' + # $ g95 --version + # G95 (GCC 4.0.3 (g95 0.90!) Aug 22 2006) + + executables = { + 'version_cmd' : ["", "--version"], + 'compiler_f77' : ["g95", "-ffixed-form"], + 'compiler_fix' : ["g95", "-ffixed-form"], + 'compiler_f90' : ["g95"], + 'linker_so' : ["", "-shared"], + 'archiver' : ["ar", "-cr"], + 'ranlib' : ["ranlib"] + } + pic_flags = ['-fpic'] + module_dir_switch = '-fmod=' + module_include_switch = '-I' + + def get_flags(self): + return ['-fno-second-underscore'] + def get_flags_opt(self): + return ['-O'] + def get_flags_debug(self): + return ['-g'] + +if __name__ == '__main__': + from distutils import log + from numpy.distutils import customized_fcompiler + log.set_verbosity(2) + print(customized_fcompiler('g95').get_version()) diff --git a/venv/Lib/site-packages/numpy/distutils/fcompiler/gnu.py b/venv/Lib/site-packages/numpy/distutils/fcompiler/gnu.py new file mode 100644 index 0000000..68d1501 --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/fcompiler/gnu.py @@ -0,0 +1,549 @@ +import re +import os +import sys +import warnings +import platform +import tempfile +import hashlib +import base64 +import subprocess +from subprocess import Popen, PIPE, STDOUT +from numpy.distutils.exec_command import filepath_from_subprocess_output +from numpy.distutils.fcompiler import FCompiler +from distutils.version import LooseVersion + +compilers = ['GnuFCompiler', 'Gnu95FCompiler'] + +TARGET_R = re.compile(r"Target: ([a-zA-Z0-9_\-]*)") + +# XXX: handle cross compilation + + +def is_win64(): + return sys.platform == "win32" and platform.architecture()[0] == "64bit" + + +class GnuFCompiler(FCompiler): + compiler_type = 'gnu' + compiler_aliases = ('g77', ) + description = 'GNU Fortran 77 compiler' + + def gnu_version_match(self, version_string): + """Handle the different versions of GNU fortran compilers""" + # Strip warning(s) that may be emitted by gfortran + while version_string.startswith('gfortran: warning'): + version_string = version_string[version_string.find('\n') + 1:] + + # Gfortran versions from after 2010 will output a simple string + # (usually "x.y", "x.y.z" or "x.y.z-q") for ``-dumpversion``; older + # gfortrans may still return long version strings (``-dumpversion`` was + # an alias for ``--version``) + if len(version_string) <= 20: + # Try to find a valid version string + m = re.search(r'([0-9.]+)', version_string) + if m: + # g77 provides a longer version string that starts with GNU + # Fortran + if version_string.startswith('GNU Fortran'): + return ('g77', m.group(1)) + + # gfortran only outputs a version string such as #.#.#, so check + # if the match is at the start of the string + elif m.start() == 0: + return ('gfortran', m.group(1)) + else: + # Output probably from --version, try harder: + m = re.search(r'GNU Fortran\s+95.*?([0-9-.]+)', version_string) + if m: + return ('gfortran', m.group(1)) + m = re.search( + r'GNU Fortran.*?\-?([0-9-.]+\.[0-9-.]+)', version_string) + if m: + v = m.group(1) + if v.startswith('0') or v.startswith('2') or v.startswith('3'): + # the '0' is for early g77's + return ('g77', v) + else: + # at some point in the 4.x series, the ' 95' was dropped + # from the version string + return ('gfortran', v) + + # If still nothing, raise an error to make the problem easy to find. + err = 'A valid Fortran version was not found in this string:\n' + raise ValueError(err + version_string) + + def version_match(self, version_string): + v = self.gnu_version_match(version_string) + if not v or v[0] != 'g77': + return None + return v[1] + + possible_executables = ['g77', 'f77'] + executables = { + 'version_cmd' : [None, "-dumpversion"], + 'compiler_f77' : [None, "-g", "-Wall", "-fno-second-underscore"], + 'compiler_f90' : None, # Use --fcompiler=gnu95 for f90 codes + 'compiler_fix' : None, + 'linker_so' : [None, "-g", "-Wall"], + 'archiver' : ["ar", "-cr"], + 'ranlib' : ["ranlib"], + 'linker_exe' : [None, "-g", "-Wall"] + } + module_dir_switch = None + module_include_switch = None + + # Cygwin: f771: warning: -fPIC ignored for target (all code is + # position independent) + if os.name != 'nt' and sys.platform != 'cygwin': + pic_flags = ['-fPIC'] + + # use -mno-cygwin for g77 when Python is not Cygwin-Python + if sys.platform == 'win32': + for key in ['version_cmd', 'compiler_f77', 'linker_so', 'linker_exe']: + executables[key].append('-mno-cygwin') + + g2c = 'g2c' + suggested_f90_compiler = 'gnu95' + + def get_flags_linker_so(self): + opt = self.linker_so[1:] + if sys.platform == 'darwin': + target = os.environ.get('MACOSX_DEPLOYMENT_TARGET', None) + # If MACOSX_DEPLOYMENT_TARGET is set, we simply trust the value + # and leave it alone. But, distutils will complain if the + # environment's value is different from the one in the Python + # Makefile used to build Python. We let disutils handle this + # error checking. + if not target: + # If MACOSX_DEPLOYMENT_TARGET is not set in the environment, + # we try to get it first from sysconfig and then + # fall back to setting it to 10.9 This is a reasonable default + # even when using the official Python dist and those derived + # from it. + import sysconfig + target = sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET') + if not target: + target = '10.9' + s = f'Env. variable MACOSX_DEPLOYMENT_TARGET set to {target}' + warnings.warn(s, stacklevel=2) + os.environ['MACOSX_DEPLOYMENT_TARGET'] = str(target) + opt.extend(['-undefined', 'dynamic_lookup', '-bundle']) + else: + opt.append("-shared") + if sys.platform.startswith('sunos'): + # SunOS often has dynamically loaded symbols defined in the + # static library libg2c.a The linker doesn't like this. To + # ignore the problem, use the -mimpure-text flag. It isn't + # the safest thing, but seems to work. 'man gcc' says: + # ".. Instead of using -mimpure-text, you should compile all + # source code with -fpic or -fPIC." + opt.append('-mimpure-text') + return opt + + def get_libgcc_dir(self): + try: + output = subprocess.check_output(self.compiler_f77 + + ['-print-libgcc-file-name']) + except (OSError, subprocess.CalledProcessError): + pass + else: + output = filepath_from_subprocess_output(output) + return os.path.dirname(output) + return None + + def get_libgfortran_dir(self): + if sys.platform[:5] == 'linux': + libgfortran_name = 'libgfortran.so' + elif sys.platform == 'darwin': + libgfortran_name = 'libgfortran.dylib' + else: + libgfortran_name = None + + libgfortran_dir = None + if libgfortran_name: + find_lib_arg = ['-print-file-name={0}'.format(libgfortran_name)] + try: + output = subprocess.check_output( + self.compiler_f77 + find_lib_arg) + except (OSError, subprocess.CalledProcessError): + pass + else: + output = filepath_from_subprocess_output(output) + libgfortran_dir = os.path.dirname(output) + return libgfortran_dir + + def get_library_dirs(self): + opt = [] + if sys.platform[:5] != 'linux': + d = self.get_libgcc_dir() + if d: + # if windows and not cygwin, libg2c lies in a different folder + if sys.platform == 'win32' and not d.startswith('/usr/lib'): + d = os.path.normpath(d) + path = os.path.join(d, "lib%s.a" % self.g2c) + if not os.path.exists(path): + root = os.path.join(d, *((os.pardir, ) * 4)) + d2 = os.path.abspath(os.path.join(root, 'lib')) + path = os.path.join(d2, "lib%s.a" % self.g2c) + if os.path.exists(path): + opt.append(d2) + opt.append(d) + # For Macports / Linux, libgfortran and libgcc are not co-located + lib_gfortran_dir = self.get_libgfortran_dir() + if lib_gfortran_dir: + opt.append(lib_gfortran_dir) + return opt + + def get_libraries(self): + opt = [] + d = self.get_libgcc_dir() + if d is not None: + g2c = self.g2c + '-pic' + f = self.static_lib_format % (g2c, self.static_lib_extension) + if not os.path.isfile(os.path.join(d, f)): + g2c = self.g2c + else: + g2c = self.g2c + + if g2c is not None: + opt.append(g2c) + c_compiler = self.c_compiler + if sys.platform == 'win32' and c_compiler and \ + c_compiler.compiler_type == 'msvc': + opt.append('gcc') + if sys.platform == 'darwin': + opt.append('cc_dynamic') + return opt + + def get_flags_debug(self): + return ['-g'] + + def get_flags_opt(self): + v = self.get_version() + if v and v <= '3.3.3': + # With this compiler version building Fortran BLAS/LAPACK + # with -O3 caused failures in lib.lapack heevr,syevr tests. + opt = ['-O2'] + else: + opt = ['-O3'] + opt.append('-funroll-loops') + return opt + + def _c_arch_flags(self): + """ Return detected arch flags from CFLAGS """ + import sysconfig + try: + cflags = sysconfig.get_config_vars()['CFLAGS'] + except KeyError: + return [] + arch_re = re.compile(r"-arch\s+(\w+)") + arch_flags = [] + for arch in arch_re.findall(cflags): + arch_flags += ['-arch', arch] + return arch_flags + + def get_flags_arch(self): + return [] + + def runtime_library_dir_option(self, dir): + if sys.platform == 'win32': + # Linux/Solaris/Unix support RPATH, Windows does not + raise NotImplementedError + + # TODO: could use -Xlinker here, if it's supported + assert "," not in dir + + if sys.platform == 'darwin': + return f'-Wl,-rpath,{dir}' + elif sys.platform[:3] == 'aix': + # AIX RPATH is called LIBPATH + return f'-Wl,-blibpath:{dir}' + else: + return f'-Wl,-rpath={dir}' + + +class Gnu95FCompiler(GnuFCompiler): + compiler_type = 'gnu95' + compiler_aliases = ('gfortran', ) + description = 'GNU Fortran 95 compiler' + + def version_match(self, version_string): + v = self.gnu_version_match(version_string) + if not v or v[0] != 'gfortran': + return None + v = v[1] + if LooseVersion(v) >= "4": + # gcc-4 series releases do not support -mno-cygwin option + pass + else: + # use -mno-cygwin flag for gfortran when Python is not + # Cygwin-Python + if sys.platform == 'win32': + for key in [ + 'version_cmd', 'compiler_f77', 'compiler_f90', + 'compiler_fix', 'linker_so', 'linker_exe' + ]: + self.executables[key].append('-mno-cygwin') + return v + + possible_executables = ['gfortran', 'f95'] + executables = { + 'version_cmd' : ["", "-dumpversion"], + 'compiler_f77' : [None, "-Wall", "-g", "-ffixed-form", + "-fno-second-underscore"], + 'compiler_f90' : [None, "-Wall", "-g", + "-fno-second-underscore"], + 'compiler_fix' : [None, "-Wall", "-g","-ffixed-form", + "-fno-second-underscore"], + 'linker_so' : ["", "-Wall", "-g"], + 'archiver' : ["ar", "-cr"], + 'ranlib' : ["ranlib"], + 'linker_exe' : [None, "-Wall"] + } + + module_dir_switch = '-J' + module_include_switch = '-I' + + if sys.platform[:3] == 'aix': + executables['linker_so'].append('-lpthread') + if platform.architecture()[0][:2] == '64': + for key in ['compiler_f77', 'compiler_f90','compiler_fix','linker_so', 'linker_exe']: + executables[key].append('-maix64') + + g2c = 'gfortran' + + def _universal_flags(self, cmd): + """Return a list of -arch flags for every supported architecture.""" + if not sys.platform == 'darwin': + return [] + arch_flags = [] + # get arches the C compiler gets. + c_archs = self._c_arch_flags() + if "i386" in c_archs: + c_archs[c_archs.index("i386")] = "i686" + # check the arches the Fortran compiler supports, and compare with + # arch flags from C compiler + for arch in ["ppc", "i686", "x86_64", "ppc64"]: + if _can_target(cmd, arch) and arch in c_archs: + arch_flags.extend(["-arch", arch]) + return arch_flags + + def get_flags(self): + flags = GnuFCompiler.get_flags(self) + arch_flags = self._universal_flags(self.compiler_f90) + if arch_flags: + flags[:0] = arch_flags + return flags + + def get_flags_linker_so(self): + flags = GnuFCompiler.get_flags_linker_so(self) + arch_flags = self._universal_flags(self.linker_so) + if arch_flags: + flags[:0] = arch_flags + return flags + + def get_library_dirs(self): + opt = GnuFCompiler.get_library_dirs(self) + if sys.platform == 'win32': + c_compiler = self.c_compiler + if c_compiler and c_compiler.compiler_type == "msvc": + target = self.get_target() + if target: + d = os.path.normpath(self.get_libgcc_dir()) + root = os.path.join(d, *((os.pardir, ) * 4)) + path = os.path.join(root, "lib") + mingwdir = os.path.normpath(path) + if os.path.exists(os.path.join(mingwdir, "libmingwex.a")): + opt.append(mingwdir) + # For Macports / Linux, libgfortran and libgcc are not co-located + lib_gfortran_dir = self.get_libgfortran_dir() + if lib_gfortran_dir: + opt.append(lib_gfortran_dir) + return opt + + def get_libraries(self): + opt = GnuFCompiler.get_libraries(self) + if sys.platform == 'darwin': + opt.remove('cc_dynamic') + if sys.platform == 'win32': + c_compiler = self.c_compiler + if c_compiler and c_compiler.compiler_type == "msvc": + if "gcc" in opt: + i = opt.index("gcc") + opt.insert(i + 1, "mingwex") + opt.insert(i + 1, "mingw32") + c_compiler = self.c_compiler + if c_compiler and c_compiler.compiler_type == "msvc": + return [] + else: + pass + return opt + + def get_target(self): + try: + output = subprocess.check_output(self.compiler_f77 + ['-v']) + except (OSError, subprocess.CalledProcessError): + pass + else: + output = filepath_from_subprocess_output(output) + m = TARGET_R.search(output) + if m: + return m.group(1) + return "" + + def _hash_files(self, filenames): + h = hashlib.sha1() + for fn in filenames: + with open(fn, 'rb') as f: + while True: + block = f.read(131072) + if not block: + break + h.update(block) + text = base64.b32encode(h.digest()) + text = text.decode('ascii') + return text.rstrip('=') + + def _link_wrapper_lib(self, objects, output_dir, extra_dll_dir, + chained_dlls, is_archive): + """Create a wrapper shared library for the given objects + + Return an MSVC-compatible lib + """ + + c_compiler = self.c_compiler + if c_compiler.compiler_type != "msvc": + raise ValueError("This method only supports MSVC") + + object_hash = self._hash_files(list(objects) + list(chained_dlls)) + + if is_win64(): + tag = 'win_amd64' + else: + tag = 'win32' + + basename = 'lib' + os.path.splitext( + os.path.basename(objects[0]))[0][:8] + root_name = basename + '.' + object_hash + '.gfortran-' + tag + dll_name = root_name + '.dll' + def_name = root_name + '.def' + lib_name = root_name + '.lib' + dll_path = os.path.join(extra_dll_dir, dll_name) + def_path = os.path.join(output_dir, def_name) + lib_path = os.path.join(output_dir, lib_name) + + if os.path.isfile(lib_path): + # Nothing to do + return lib_path, dll_path + + if is_archive: + objects = (["-Wl,--whole-archive"] + list(objects) + + ["-Wl,--no-whole-archive"]) + self.link_shared_object( + objects, + dll_name, + output_dir=extra_dll_dir, + extra_postargs=list(chained_dlls) + [ + '-Wl,--allow-multiple-definition', + '-Wl,--output-def,' + def_path, + '-Wl,--export-all-symbols', + '-Wl,--enable-auto-import', + '-static', + '-mlong-double-64', + ]) + + # No PowerPC! + if is_win64(): + specifier = '/MACHINE:X64' + else: + specifier = '/MACHINE:X86' + + # MSVC specific code + lib_args = ['/def:' + def_path, '/OUT:' + lib_path, specifier] + if not c_compiler.initialized: + c_compiler.initialize() + c_compiler.spawn([c_compiler.lib] + lib_args) + + return lib_path, dll_path + + def can_ccompiler_link(self, compiler): + # MSVC cannot link objects compiled by GNU fortran + return compiler.compiler_type not in ("msvc", ) + + def wrap_unlinkable_objects(self, objects, output_dir, extra_dll_dir): + """ + Convert a set of object files that are not compatible with the default + linker, to a file that is compatible. + """ + if self.c_compiler.compiler_type == "msvc": + # Compile a DLL and return the lib for the DLL as + # the object. Also keep track of previous DLLs that + # we have compiled so that we can link against them. + + # If there are .a archives, assume they are self-contained + # static libraries, and build separate DLLs for each + archives = [] + plain_objects = [] + for obj in objects: + if obj.lower().endswith('.a'): + archives.append(obj) + else: + plain_objects.append(obj) + + chained_libs = [] + chained_dlls = [] + for archive in archives[::-1]: + lib, dll = self._link_wrapper_lib( + [archive], + output_dir, + extra_dll_dir, + chained_dlls=chained_dlls, + is_archive=True) + chained_libs.insert(0, lib) + chained_dlls.insert(0, dll) + + if not plain_objects: + return chained_libs + + lib, dll = self._link_wrapper_lib( + plain_objects, + output_dir, + extra_dll_dir, + chained_dlls=chained_dlls, + is_archive=False) + return [lib] + chained_libs + else: + raise ValueError("Unsupported C compiler") + + +def _can_target(cmd, arch): + """Return true if the architecture supports the -arch flag""" + newcmd = cmd[:] + fid, filename = tempfile.mkstemp(suffix=".f") + os.close(fid) + try: + d = os.path.dirname(filename) + output = os.path.splitext(filename)[0] + ".o" + try: + newcmd.extend(["-arch", arch, "-c", filename]) + p = Popen(newcmd, stderr=STDOUT, stdout=PIPE, cwd=d) + p.communicate() + return p.returncode == 0 + finally: + if os.path.exists(output): + os.remove(output) + finally: + os.remove(filename) + return False + + +if __name__ == '__main__': + from distutils import log + from numpy.distutils import customized_fcompiler + log.set_verbosity(2) + + print(customized_fcompiler('gnu').get_version()) + try: + print(customized_fcompiler('g95').get_version()) + except Exception as e: + print(e) diff --git a/venv/Lib/site-packages/numpy/distutils/fcompiler/hpux.py b/venv/Lib/site-packages/numpy/distutils/fcompiler/hpux.py new file mode 100644 index 0000000..09e6483 --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/fcompiler/hpux.py @@ -0,0 +1,41 @@ +from numpy.distutils.fcompiler import FCompiler + +compilers = ['HPUXFCompiler'] + +class HPUXFCompiler(FCompiler): + + compiler_type = 'hpux' + description = 'HP Fortran 90 Compiler' + version_pattern = r'HP F90 (?P[^\s*,]*)' + + executables = { + 'version_cmd' : ["f90", "+version"], + 'compiler_f77' : ["f90"], + 'compiler_fix' : ["f90"], + 'compiler_f90' : ["f90"], + 'linker_so' : ["ld", "-b"], + 'archiver' : ["ar", "-cr"], + 'ranlib' : ["ranlib"] + } + module_dir_switch = None #XXX: fix me + module_include_switch = None #XXX: fix me + pic_flags = ['+Z'] + def get_flags(self): + return self.pic_flags + ['+ppu', '+DD64'] + def get_flags_opt(self): + return ['-O3'] + def get_libraries(self): + return ['m'] + def get_library_dirs(self): + opt = ['/usr/lib/hpux64'] + return opt + def get_version(self, force=0, ok_status=[256, 0, 1]): + # XXX status==256 may indicate 'unrecognized option' or + # 'no input file'. So, version_cmd needs more work. + return FCompiler.get_version(self, force, ok_status) + +if __name__ == '__main__': + from distutils import log + log.set_verbosity(10) + from numpy.distutils import customized_fcompiler + print(customized_fcompiler(compiler='hpux').get_version()) diff --git a/venv/Lib/site-packages/numpy/distutils/fcompiler/ibm.py b/venv/Lib/site-packages/numpy/distutils/fcompiler/ibm.py new file mode 100644 index 0000000..4a83682 --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/fcompiler/ibm.py @@ -0,0 +1,97 @@ +import os +import re +import sys +import subprocess + +from numpy.distutils.fcompiler import FCompiler +from numpy.distutils.exec_command import find_executable +from numpy.distutils.misc_util import make_temp_file +from distutils import log + +compilers = ['IBMFCompiler'] + +class IBMFCompiler(FCompiler): + compiler_type = 'ibm' + description = 'IBM XL Fortran Compiler' + version_pattern = r'(xlf\(1\)\s*|)IBM XL Fortran ((Advanced Edition |)Version |Enterprise Edition V|for AIX, V)(?P[^\s*]*)' + #IBM XL Fortran Enterprise Edition V10.1 for AIX \nVersion: 10.01.0000.0004 + + executables = { + 'version_cmd' : ["", "-qversion"], + 'compiler_f77' : ["xlf"], + 'compiler_fix' : ["xlf90", "-qfixed"], + 'compiler_f90' : ["xlf90"], + 'linker_so' : ["xlf95"], + 'archiver' : ["ar", "-cr"], + 'ranlib' : ["ranlib"] + } + + def get_version(self,*args,**kwds): + version = FCompiler.get_version(self,*args,**kwds) + + if version is None and sys.platform.startswith('aix'): + # use lslpp to find out xlf version + lslpp = find_executable('lslpp') + xlf = find_executable('xlf') + if os.path.exists(xlf) and os.path.exists(lslpp): + try: + o = subprocess.check_output([lslpp, '-Lc', 'xlfcmp']) + except (OSError, subprocess.CalledProcessError): + pass + else: + m = re.search(r'xlfcmp:(?P\d+([.]\d+)+)', o) + if m: version = m.group('version') + + xlf_dir = '/etc/opt/ibmcmp/xlf' + if version is None and os.path.isdir(xlf_dir): + # linux: + # If the output of xlf does not contain version info + # (that's the case with xlf 8.1, for instance) then + # let's try another method: + l = sorted(os.listdir(xlf_dir)) + l.reverse() + l = [d for d in l if os.path.isfile(os.path.join(xlf_dir, d, 'xlf.cfg'))] + if l: + from distutils.version import LooseVersion + self.version = version = LooseVersion(l[0]) + return version + + def get_flags(self): + return ['-qextname'] + + def get_flags_debug(self): + return ['-g'] + + def get_flags_linker_so(self): + opt = [] + if sys.platform=='darwin': + opt.append('-Wl,-bundle,-flat_namespace,-undefined,suppress') + else: + opt.append('-bshared') + version = self.get_version(ok_status=[0, 40]) + if version is not None: + if sys.platform.startswith('aix'): + xlf_cfg = '/etc/xlf.cfg' + else: + xlf_cfg = '/etc/opt/ibmcmp/xlf/%s/xlf.cfg' % version + fo, new_cfg = make_temp_file(suffix='_xlf.cfg') + log.info('Creating '+new_cfg) + with open(xlf_cfg, 'r') as fi: + crt1_match = re.compile(r'\s*crt\s*[=]\s*(?P.*)/crt1.o').match + for line in fi: + m = crt1_match(line) + if m: + fo.write('crt = %s/bundle1.o\n' % (m.group('path'))) + else: + fo.write(line) + fo.close() + opt.append('-F'+new_cfg) + return opt + + def get_flags_opt(self): + return ['-O3'] + +if __name__ == '__main__': + from numpy.distutils import customized_fcompiler + log.set_verbosity(2) + print(customized_fcompiler(compiler='ibm').get_version()) diff --git a/venv/Lib/site-packages/numpy/distutils/fcompiler/intel.py b/venv/Lib/site-packages/numpy/distutils/fcompiler/intel.py new file mode 100644 index 0000000..c7b3c23 --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/fcompiler/intel.py @@ -0,0 +1,220 @@ +# http://developer.intel.com/software/products/compilers/flin/ +import sys + +from numpy.distutils.ccompiler import simple_version_match +from numpy.distutils.fcompiler import FCompiler, dummy_fortran_file + +compilers = ['IntelFCompiler', 'IntelVisualFCompiler', + 'IntelItaniumFCompiler', 'IntelItaniumVisualFCompiler', + 'IntelEM64VisualFCompiler', 'IntelEM64TFCompiler'] + + +def intel_version_match(type): + # Match against the important stuff in the version string + return simple_version_match(start=r'Intel.*?Fortran.*?(?:%s).*?Version' % (type,)) + + +class BaseIntelFCompiler(FCompiler): + def update_executables(self): + f = dummy_fortran_file() + self.executables['version_cmd'] = ['', '-FI', '-V', '-c', + f + '.f', '-o', f + '.o'] + + def runtime_library_dir_option(self, dir): + # TODO: could use -Xlinker here, if it's supported + assert "," not in dir + + return '-Wl,-rpath=%s' % dir + + +class IntelFCompiler(BaseIntelFCompiler): + + compiler_type = 'intel' + compiler_aliases = ('ifort',) + description = 'Intel Fortran Compiler for 32-bit apps' + version_match = intel_version_match('32-bit|IA-32') + + possible_executables = ['ifort', 'ifc'] + + executables = { + 'version_cmd' : None, # set by update_executables + 'compiler_f77' : [None, "-72", "-w90", "-w95"], + 'compiler_f90' : [None], + 'compiler_fix' : [None, "-FI"], + 'linker_so' : ["", "-shared"], + 'archiver' : ["ar", "-cr"], + 'ranlib' : ["ranlib"] + } + + pic_flags = ['-fPIC'] + module_dir_switch = '-module ' # Don't remove ending space! + module_include_switch = '-I' + + def get_flags_free(self): + return ['-FR'] + + def get_flags(self): + return ['-fPIC'] + + def get_flags_opt(self): # Scipy test failures with -O2 + v = self.get_version() + mpopt = 'openmp' if v and v < '15' else 'qopenmp' + return ['-fp-model', 'strict', '-O1', '-{}'.format(mpopt)] + + def get_flags_arch(self): + return [] + + def get_flags_linker_so(self): + opt = FCompiler.get_flags_linker_so(self) + v = self.get_version() + if v and v >= '8.0': + opt.append('-nofor_main') + if sys.platform == 'darwin': + # Here, it's -dynamiclib + try: + idx = opt.index('-shared') + opt.remove('-shared') + except ValueError: + idx = 0 + opt[idx:idx] = ['-dynamiclib', '-Wl,-undefined,dynamic_lookup'] + return opt + + +class IntelItaniumFCompiler(IntelFCompiler): + compiler_type = 'intele' + compiler_aliases = () + description = 'Intel Fortran Compiler for Itanium apps' + + version_match = intel_version_match('Itanium|IA-64') + + possible_executables = ['ifort', 'efort', 'efc'] + + executables = { + 'version_cmd' : None, + 'compiler_f77' : [None, "-FI", "-w90", "-w95"], + 'compiler_fix' : [None, "-FI"], + 'compiler_f90' : [None], + 'linker_so' : ['', "-shared"], + 'archiver' : ["ar", "-cr"], + 'ranlib' : ["ranlib"] + } + + +class IntelEM64TFCompiler(IntelFCompiler): + compiler_type = 'intelem' + compiler_aliases = () + description = 'Intel Fortran Compiler for 64-bit apps' + + version_match = intel_version_match('EM64T-based|Intel\\(R\\) 64|64|IA-64|64-bit') + + possible_executables = ['ifort', 'efort', 'efc'] + + executables = { + 'version_cmd' : None, + 'compiler_f77' : [None, "-FI"], + 'compiler_fix' : [None, "-FI"], + 'compiler_f90' : [None], + 'linker_so' : ['', "-shared"], + 'archiver' : ["ar", "-cr"], + 'ranlib' : ["ranlib"] + } + + def get_flags(self): + return ['-fPIC'] + + def get_flags_opt(self): # Scipy test failures with -O2 + v = self.get_version() + mpopt = 'openmp' if v and v < '15' else 'qopenmp' + return ['-fp-model', 'strict', '-O1', '-{}'.format(mpopt)] + + def get_flags_arch(self): + return [] + +# Is there no difference in the version string between the above compilers +# and the Visual compilers? + + +class IntelVisualFCompiler(BaseIntelFCompiler): + compiler_type = 'intelv' + description = 'Intel Visual Fortran Compiler for 32-bit apps' + version_match = intel_version_match('32-bit|IA-32') + + def update_executables(self): + f = dummy_fortran_file() + self.executables['version_cmd'] = ['', '/FI', '/c', + f + '.f', '/o', f + '.o'] + + ar_exe = 'lib.exe' + possible_executables = ['ifort', 'ifl'] + + executables = { + 'version_cmd' : None, + 'compiler_f77' : [None], + 'compiler_fix' : [None], + 'compiler_f90' : [None], + 'linker_so' : [None], + 'archiver' : [ar_exe, "/verbose", "/OUT:"], + 'ranlib' : None + } + + compile_switch = '/c ' + object_switch = '/Fo' # No space after /Fo! + library_switch = '/OUT:' # No space after /OUT:! + module_dir_switch = '/module:' # No space after /module: + module_include_switch = '/I' + + def get_flags(self): + opt = ['/nologo', '/MD', '/nbs', '/names:lowercase', '/assume:underscore'] + return opt + + def get_flags_free(self): + return [] + + def get_flags_debug(self): + return ['/4Yb', '/d2'] + + def get_flags_opt(self): + return ['/O1'] # Scipy test failures with /O2 + + def get_flags_arch(self): + return ["/arch:IA32", "/QaxSSE3"] + + def runtime_library_dir_option(self, dir): + raise NotImplementedError + + +class IntelItaniumVisualFCompiler(IntelVisualFCompiler): + compiler_type = 'intelev' + description = 'Intel Visual Fortran Compiler for Itanium apps' + + version_match = intel_version_match('Itanium') + + possible_executables = ['efl'] # XXX this is a wild guess + ar_exe = IntelVisualFCompiler.ar_exe + + executables = { + 'version_cmd' : None, + 'compiler_f77' : [None, "-FI", "-w90", "-w95"], + 'compiler_fix' : [None, "-FI", "-4L72", "-w"], + 'compiler_f90' : [None], + 'linker_so' : ['', "-shared"], + 'archiver' : [ar_exe, "/verbose", "/OUT:"], + 'ranlib' : None + } + + +class IntelEM64VisualFCompiler(IntelVisualFCompiler): + compiler_type = 'intelvem' + description = 'Intel Visual Fortran Compiler for 64-bit apps' + + version_match = simple_version_match(start=r'Intel\(R\).*?64,') + + def get_flags_arch(self): + return [] + + +if __name__ == '__main__': + from distutils import log + log.set_verbosity(2) + from numpy.distutils import customized_fcompiler + print(customized_fcompiler(compiler='intel').get_version()) diff --git a/venv/Lib/site-packages/numpy/distutils/fcompiler/lahey.py b/venv/Lib/site-packages/numpy/distutils/fcompiler/lahey.py new file mode 100644 index 0000000..e925838 --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/fcompiler/lahey.py @@ -0,0 +1,45 @@ +import os + +from numpy.distutils.fcompiler import FCompiler + +compilers = ['LaheyFCompiler'] + +class LaheyFCompiler(FCompiler): + + compiler_type = 'lahey' + description = 'Lahey/Fujitsu Fortran 95 Compiler' + version_pattern = r'Lahey/Fujitsu Fortran 95 Compiler Release (?P[^\s*]*)' + + executables = { + 'version_cmd' : ["", "--version"], + 'compiler_f77' : ["lf95", "--fix"], + 'compiler_fix' : ["lf95", "--fix"], + 'compiler_f90' : ["lf95"], + 'linker_so' : ["lf95", "-shared"], + 'archiver' : ["ar", "-cr"], + 'ranlib' : ["ranlib"] + } + + module_dir_switch = None #XXX Fix me + module_include_switch = None #XXX Fix me + + def get_flags_opt(self): + return ['-O'] + def get_flags_debug(self): + return ['-g', '--chk', '--chkglobal'] + def get_library_dirs(self): + opt = [] + d = os.environ.get('LAHEY') + if d: + opt.append(os.path.join(d, 'lib')) + return opt + def get_libraries(self): + opt = [] + opt.extend(['fj9f6', 'fj9i6', 'fj9ipp', 'fj9e6']) + return opt + +if __name__ == '__main__': + from distutils import log + log.set_verbosity(2) + from numpy.distutils import customized_fcompiler + print(customized_fcompiler(compiler='lahey').get_version()) diff --git a/venv/Lib/site-packages/numpy/distutils/fcompiler/mips.py b/venv/Lib/site-packages/numpy/distutils/fcompiler/mips.py new file mode 100644 index 0000000..a097380 --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/fcompiler/mips.py @@ -0,0 +1,54 @@ +from numpy.distutils.cpuinfo import cpu +from numpy.distutils.fcompiler import FCompiler + +compilers = ['MIPSFCompiler'] + +class MIPSFCompiler(FCompiler): + + compiler_type = 'mips' + description = 'MIPSpro Fortran Compiler' + version_pattern = r'MIPSpro Compilers: Version (?P[^\s*,]*)' + + executables = { + 'version_cmd' : ["", "-version"], + 'compiler_f77' : ["f77", "-f77"], + 'compiler_fix' : ["f90", "-fixedform"], + 'compiler_f90' : ["f90"], + 'linker_so' : ["f90", "-shared"], + 'archiver' : ["ar", "-cr"], + 'ranlib' : None + } + module_dir_switch = None #XXX: fix me + module_include_switch = None #XXX: fix me + pic_flags = ['-KPIC'] + + def get_flags(self): + return self.pic_flags + ['-n32'] + def get_flags_opt(self): + return ['-O3'] + def get_flags_arch(self): + opt = [] + for a in '19 20 21 22_4k 22_5k 24 25 26 27 28 30 32_5k 32_10k'.split(): + if getattr(cpu, 'is_IP%s'%a)(): + opt.append('-TARG:platform=IP%s' % a) + break + return opt + def get_flags_arch_f77(self): + r = None + if cpu.is_r10000(): r = 10000 + elif cpu.is_r12000(): r = 12000 + elif cpu.is_r8000(): r = 8000 + elif cpu.is_r5000(): r = 5000 + elif cpu.is_r4000(): r = 4000 + if r is not None: + return ['r%s' % (r)] + return [] + def get_flags_arch_f90(self): + r = self.get_flags_arch_f77() + if r: + r[0] = '-' + r[0] + return r + +if __name__ == '__main__': + from numpy.distutils import customized_fcompiler + print(customized_fcompiler(compiler='mips').get_version()) diff --git a/venv/Lib/site-packages/numpy/distutils/fcompiler/nag.py b/venv/Lib/site-packages/numpy/distutils/fcompiler/nag.py new file mode 100644 index 0000000..908e724 --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/fcompiler/nag.py @@ -0,0 +1,82 @@ +import sys +import re +from numpy.distutils.fcompiler import FCompiler + +compilers = ['NAGFCompiler', 'NAGFORCompiler'] + +class BaseNAGFCompiler(FCompiler): + version_pattern = r'NAG.* Release (?P[^(\s]*)' + + def version_match(self, version_string): + m = re.search(self.version_pattern, version_string) + if m: + return m.group('version') + else: + return None + + def get_flags_linker_so(self): + return ["-Wl,-shared"] + def get_flags_opt(self): + return ['-O4'] + def get_flags_arch(self): + return [''] + +class NAGFCompiler(BaseNAGFCompiler): + + compiler_type = 'nag' + description = 'NAGWare Fortran 95 Compiler' + + executables = { + 'version_cmd' : ["", "-V"], + 'compiler_f77' : ["f95", "-fixed"], + 'compiler_fix' : ["f95", "-fixed"], + 'compiler_f90' : ["f95"], + 'linker_so' : [""], + 'archiver' : ["ar", "-cr"], + 'ranlib' : ["ranlib"] + } + + def get_flags_linker_so(self): + if sys.platform == 'darwin': + return ['-unsharedf95', '-Wl,-bundle,-flat_namespace,-undefined,suppress'] + return BaseNAGFCompiler.get_flags_linker_so(self) + def get_flags_arch(self): + version = self.get_version() + if version and version < '5.1': + return ['-target=native'] + else: + return BaseNAGFCompiler.get_flags_arch(self) + def get_flags_debug(self): + return ['-g', '-gline', '-g90', '-nan', '-C'] + +class NAGFORCompiler(BaseNAGFCompiler): + + compiler_type = 'nagfor' + description = 'NAG Fortran Compiler' + + executables = { + 'version_cmd' : ["nagfor", "-V"], + 'compiler_f77' : ["nagfor", "-fixed"], + 'compiler_fix' : ["nagfor", "-fixed"], + 'compiler_f90' : ["nagfor"], + 'linker_so' : ["nagfor"], + 'archiver' : ["ar", "-cr"], + 'ranlib' : ["ranlib"] + } + + def get_flags_debug(self): + version = self.get_version() + if version and version > '6.1': + return ['-g', '-u', '-nan', '-C=all', '-thread_safe', + '-kind=unique', '-Warn=allocation', '-Warn=subnormal'] + else: + return ['-g', '-nan', '-C=all', '-u', '-thread_safe'] + + +if __name__ == '__main__': + from distutils import log + log.set_verbosity(2) + from numpy.distutils import customized_fcompiler + compiler = customized_fcompiler(compiler='nagfor') + print(compiler.get_version()) + print(compiler.get_flags_debug()) diff --git a/venv/Lib/site-packages/numpy/distutils/fcompiler/none.py b/venv/Lib/site-packages/numpy/distutils/fcompiler/none.py new file mode 100644 index 0000000..ef411ff --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/fcompiler/none.py @@ -0,0 +1,28 @@ +from numpy.distutils.fcompiler import FCompiler +from numpy.distutils import customized_fcompiler + +compilers = ['NoneFCompiler'] + +class NoneFCompiler(FCompiler): + + compiler_type = 'none' + description = 'Fake Fortran compiler' + + executables = {'compiler_f77': None, + 'compiler_f90': None, + 'compiler_fix': None, + 'linker_so': None, + 'linker_exe': None, + 'archiver': None, + 'ranlib': None, + 'version_cmd': None, + } + + def find_executables(self): + pass + + +if __name__ == '__main__': + from distutils import log + log.set_verbosity(2) + print(customized_fcompiler(compiler='none').get_version()) diff --git a/venv/Lib/site-packages/numpy/distutils/fcompiler/nv.py b/venv/Lib/site-packages/numpy/distutils/fcompiler/nv.py new file mode 100644 index 0000000..8e9f168 --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/fcompiler/nv.py @@ -0,0 +1,55 @@ +import sys + +from numpy.distutils.fcompiler import FCompiler + +compilers = ['NVHPCFCompiler'] + +class NVHPCFCompiler(FCompiler): + """ NVIDIA High Performance Computing (HPC) SDK Fortran Compiler + + https://developer.nvidia.com/hpc-sdk + + Since august 2020 the NVIDIA HPC SDK includes the compilers formerly known as The Portland Group compilers, + https://www.pgroup.com/index.htm. + See also `numpy.distutils.fcompiler.pg`. + """ + + compiler_type = 'nv' + description = 'NVIDIA HPC SDK' + version_pattern = r'\s*(nvfortran|(pg(f77|f90|fortran)) \(aka nvfortran\)) (?P[\d.-]+).*' + + executables = { + 'version_cmd': ["", "-V"], + 'compiler_f77': ["nvfortran"], + 'compiler_fix': ["nvfortran", "-Mfixed"], + 'compiler_f90': ["nvfortran"], + 'linker_so': [""], + 'archiver': ["ar", "-cr"], + 'ranlib': ["ranlib"] + } + pic_flags = ['-fpic'] + + module_dir_switch = '-module ' + module_include_switch = '-I' + + def get_flags(self): + opt = ['-Minform=inform', '-Mnosecond_underscore'] + return self.pic_flags + opt + + def get_flags_opt(self): + return ['-fast'] + + def get_flags_debug(self): + return ['-g'] + + def get_flags_linker_so(self): + return ["-shared", '-fpic'] + + def runtime_library_dir_option(self, dir): + return '-R%s' % dir + +if __name__ == '__main__': + from distutils import log + log.set_verbosity(2) + from numpy.distutils import customized_fcompiler + print(customized_fcompiler(compiler='nv').get_version()) diff --git a/venv/Lib/site-packages/numpy/distutils/fcompiler/pathf95.py b/venv/Lib/site-packages/numpy/distutils/fcompiler/pathf95.py new file mode 100644 index 0000000..0768cb1 --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/fcompiler/pathf95.py @@ -0,0 +1,33 @@ +from numpy.distutils.fcompiler import FCompiler + +compilers = ['PathScaleFCompiler'] + +class PathScaleFCompiler(FCompiler): + + compiler_type = 'pathf95' + description = 'PathScale Fortran Compiler' + version_pattern = r'PathScale\(TM\) Compiler Suite: Version (?P[\d.]+)' + + executables = { + 'version_cmd' : ["pathf95", "-version"], + 'compiler_f77' : ["pathf95", "-fixedform"], + 'compiler_fix' : ["pathf95", "-fixedform"], + 'compiler_f90' : ["pathf95"], + 'linker_so' : ["pathf95", "-shared"], + 'archiver' : ["ar", "-cr"], + 'ranlib' : ["ranlib"] + } + pic_flags = ['-fPIC'] + module_dir_switch = '-module ' # Don't remove ending space! + module_include_switch = '-I' + + def get_flags_opt(self): + return ['-O3'] + def get_flags_debug(self): + return ['-g'] + +if __name__ == '__main__': + from distutils import log + log.set_verbosity(2) + from numpy.distutils import customized_fcompiler + print(customized_fcompiler(compiler='pathf95').get_version()) diff --git a/venv/Lib/site-packages/numpy/distutils/fcompiler/pg.py b/venv/Lib/site-packages/numpy/distutils/fcompiler/pg.py new file mode 100644 index 0000000..72442c4 --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/fcompiler/pg.py @@ -0,0 +1,128 @@ +# http://www.pgroup.com +import sys + +from numpy.distutils.fcompiler import FCompiler +from sys import platform +from os.path import join, dirname, normpath + +compilers = ['PGroupFCompiler', 'PGroupFlangCompiler'] + + +class PGroupFCompiler(FCompiler): + + compiler_type = 'pg' + description = 'Portland Group Fortran Compiler' + version_pattern = r'\s*pg(f77|f90|hpf|fortran) (?P[\d.-]+).*' + + if platform == 'darwin': + executables = { + 'version_cmd': ["", "-V"], + 'compiler_f77': ["pgfortran", "-dynamiclib"], + 'compiler_fix': ["pgfortran", "-Mfixed", "-dynamiclib"], + 'compiler_f90': ["pgfortran", "-dynamiclib"], + 'linker_so': ["libtool"], + 'archiver': ["ar", "-cr"], + 'ranlib': ["ranlib"] + } + pic_flags = [''] + else: + executables = { + 'version_cmd': ["", "-V"], + 'compiler_f77': ["pgfortran"], + 'compiler_fix': ["pgfortran", "-Mfixed"], + 'compiler_f90': ["pgfortran"], + 'linker_so': [""], + 'archiver': ["ar", "-cr"], + 'ranlib': ["ranlib"] + } + pic_flags = ['-fpic'] + + module_dir_switch = '-module ' + module_include_switch = '-I' + + def get_flags(self): + opt = ['-Minform=inform', '-Mnosecond_underscore'] + return self.pic_flags + opt + + def get_flags_opt(self): + return ['-fast'] + + def get_flags_debug(self): + return ['-g'] + + if platform == 'darwin': + def get_flags_linker_so(self): + return ["-dynamic", '-undefined', 'dynamic_lookup'] + + else: + def get_flags_linker_so(self): + return ["-shared", '-fpic'] + + def runtime_library_dir_option(self, dir): + return '-R%s' % dir + + +import functools + +class PGroupFlangCompiler(FCompiler): + compiler_type = 'flang' + description = 'Portland Group Fortran LLVM Compiler' + version_pattern = r'\s*(flang|clang) version (?P[\d.-]+).*' + + ar_exe = 'lib.exe' + possible_executables = ['flang'] + + executables = { + 'version_cmd': ["", "--version"], + 'compiler_f77': ["flang"], + 'compiler_fix': ["flang"], + 'compiler_f90': ["flang"], + 'linker_so': [None], + 'archiver': [ar_exe, "/verbose", "/OUT:"], + 'ranlib': None + } + + library_switch = '/OUT:' # No space after /OUT:! + module_dir_switch = '-module ' # Don't remove ending space! + + def get_libraries(self): + opt = FCompiler.get_libraries(self) + opt.extend(['flang', 'flangrti', 'ompstub']) + return opt + + @functools.lru_cache(maxsize=128) + def get_library_dirs(self): + """List of compiler library directories.""" + opt = FCompiler.get_library_dirs(self) + flang_dir = dirname(self.executables['compiler_f77'][0]) + opt.append(normpath(join(flang_dir, '..', 'lib'))) + + return opt + + def get_flags(self): + return [] + + def get_flags_free(self): + return [] + + def get_flags_debug(self): + return ['-g'] + + def get_flags_opt(self): + return ['-O3'] + + def get_flags_arch(self): + return [] + + def runtime_library_dir_option(self, dir): + raise NotImplementedError + + +if __name__ == '__main__': + from distutils import log + log.set_verbosity(2) + from numpy.distutils import customized_fcompiler + if 'flang' in sys.argv: + print(customized_fcompiler(compiler='flang').get_version()) + else: + print(customized_fcompiler(compiler='pg').get_version()) diff --git a/venv/Lib/site-packages/numpy/distutils/fcompiler/sun.py b/venv/Lib/site-packages/numpy/distutils/fcompiler/sun.py new file mode 100644 index 0000000..d039f0b --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/fcompiler/sun.py @@ -0,0 +1,51 @@ +from numpy.distutils.ccompiler import simple_version_match +from numpy.distutils.fcompiler import FCompiler + +compilers = ['SunFCompiler'] + +class SunFCompiler(FCompiler): + + compiler_type = 'sun' + description = 'Sun or Forte Fortran 95 Compiler' + # ex: + # f90: Sun WorkShop 6 update 2 Fortran 95 6.2 Patch 111690-10 2003/08/28 + version_match = simple_version_match( + start=r'f9[05]: (Sun|Forte|WorkShop).*Fortran 95') + + executables = { + 'version_cmd' : ["", "-V"], + 'compiler_f77' : ["f90"], + 'compiler_fix' : ["f90", "-fixed"], + 'compiler_f90' : ["f90"], + 'linker_so' : ["", "-Bdynamic", "-G"], + 'archiver' : ["ar", "-cr"], + 'ranlib' : ["ranlib"] + } + module_dir_switch = '-moddir=' + module_include_switch = '-M' + pic_flags = ['-xcode=pic32'] + + def get_flags_f77(self): + ret = ["-ftrap=%none"] + if (self.get_version() or '') >= '7': + ret.append("-f77") + else: + ret.append("-fixed") + return ret + def get_opt(self): + return ['-fast', '-dalign'] + def get_arch(self): + return ['-xtarget=generic'] + def get_libraries(self): + opt = [] + opt.extend(['fsu', 'sunmath', 'mvec']) + return opt + + def runtime_library_dir_option(self, dir): + return '-R%s' % dir + +if __name__ == '__main__': + from distutils import log + log.set_verbosity(2) + from numpy.distutils import customized_fcompiler + print(customized_fcompiler(compiler='sun').get_version()) diff --git a/venv/Lib/site-packages/numpy/distutils/fcompiler/vast.py b/venv/Lib/site-packages/numpy/distutils/fcompiler/vast.py new file mode 100644 index 0000000..92a1647 --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/fcompiler/vast.py @@ -0,0 +1,52 @@ +import os + +from numpy.distutils.fcompiler.gnu import GnuFCompiler + +compilers = ['VastFCompiler'] + +class VastFCompiler(GnuFCompiler): + compiler_type = 'vast' + compiler_aliases = () + description = 'Pacific-Sierra Research Fortran 90 Compiler' + version_pattern = (r'\s*Pacific-Sierra Research vf90 ' + r'(Personal|Professional)\s+(?P[^\s]*)') + + # VAST f90 does not support -o with -c. So, object files are created + # to the current directory and then moved to build directory + object_switch = ' && function _mvfile { mv -v `basename $1` $1 ; } && _mvfile ' + + executables = { + 'version_cmd' : ["vf90", "-v"], + 'compiler_f77' : ["g77"], + 'compiler_fix' : ["f90", "-Wv,-ya"], + 'compiler_f90' : ["f90"], + 'linker_so' : [""], + 'archiver' : ["ar", "-cr"], + 'ranlib' : ["ranlib"] + } + module_dir_switch = None #XXX Fix me + module_include_switch = None #XXX Fix me + + def find_executables(self): + pass + + def get_version_cmd(self): + f90 = self.compiler_f90[0] + d, b = os.path.split(f90) + vf90 = os.path.join(d, 'v'+b) + return vf90 + + def get_flags_arch(self): + vast_version = self.get_version() + gnu = GnuFCompiler() + gnu.customize(None) + self.version = gnu.get_version() + opt = GnuFCompiler.get_flags_arch(self) + self.version = vast_version + return opt + +if __name__ == '__main__': + from distutils import log + log.set_verbosity(2) + from numpy.distutils import customized_fcompiler + print(customized_fcompiler(compiler='vast').get_version()) diff --git a/venv/Lib/site-packages/numpy/distutils/from_template.py b/venv/Lib/site-packages/numpy/distutils/from_template.py new file mode 100644 index 0000000..070b7d8 --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/from_template.py @@ -0,0 +1,262 @@ +#!/usr/bin/env python3 +""" + +process_file(filename) + + takes templated file .xxx.src and produces .xxx file where .xxx + is .pyf .f90 or .f using the following template rules: + + '<..>' denotes a template. + + All function and subroutine blocks in a source file with names that + contain '<..>' will be replicated according to the rules in '<..>'. + + The number of comma-separated words in '<..>' will determine the number of + replicates. + + '<..>' may have two different forms, named and short. For example, + + named: + where anywhere inside a block '

    ' will be replaced with + 'd', 's', 'z', and 'c' for each replicate of the block. + + <_c> is already defined: <_c=s,d,c,z> + <_t> is already defined: <_t=real,double precision,complex,double complex> + + short: + , a short form of the named, useful when no

    appears inside + a block. + + In general, '<..>' contains a comma separated list of arbitrary + expressions. If these expression must contain a comma|leftarrow|rightarrow, + then prepend the comma|leftarrow|rightarrow with a backslash. + + If an expression matches '\\' then it will be replaced + by -th expression. + + Note that all '<..>' forms in a block must have the same number of + comma-separated entries. + + Predefined named template rules: + + + + + + +""" +__all__ = ['process_str', 'process_file'] + +import os +import sys +import re + +routine_start_re = re.compile(r'(\n|\A)(( (\$|\*))|)\s*(subroutine|function)\b', re.I) +routine_end_re = re.compile(r'\n\s*end\s*(subroutine|function)\b.*(\n|\Z)', re.I) +function_start_re = re.compile(r'\n (\$|\*)\s*function\b', re.I) + +def parse_structure(astr): + """ Return a list of tuples for each function or subroutine each + tuple is the start and end of a subroutine or function to be + expanded. + """ + + spanlist = [] + ind = 0 + while True: + m = routine_start_re.search(astr, ind) + if m is None: + break + start = m.start() + if function_start_re.match(astr, start, m.end()): + while True: + i = astr.rfind('\n', ind, start) + if i==-1: + break + start = i + if astr[i:i+7]!='\n $': + break + start += 1 + m = routine_end_re.search(astr, m.end()) + ind = end = m and m.end()-1 or len(astr) + spanlist.append((start, end)) + return spanlist + +template_re = re.compile(r"<\s*(\w[\w\d]*)\s*>") +named_re = re.compile(r"<\s*(\w[\w\d]*)\s*=\s*(.*?)\s*>") +list_re = re.compile(r"<\s*((.*?))\s*>") + +def find_repl_patterns(astr): + reps = named_re.findall(astr) + names = {} + for rep in reps: + name = rep[0].strip() or unique_key(names) + repl = rep[1].replace(r'\,', '@comma@') + thelist = conv(repl) + names[name] = thelist + return names + +def find_and_remove_repl_patterns(astr): + names = find_repl_patterns(astr) + astr = re.subn(named_re, '', astr)[0] + return astr, names + +item_re = re.compile(r"\A\\(?P\d+)\Z") +def conv(astr): + b = astr.split(',') + l = [x.strip() for x in b] + for i in range(len(l)): + m = item_re.match(l[i]) + if m: + j = int(m.group('index')) + l[i] = l[j] + return ','.join(l) + +def unique_key(adict): + """ Obtain a unique key given a dictionary.""" + allkeys = list(adict.keys()) + done = False + n = 1 + while not done: + newkey = '__l%s' % (n) + if newkey in allkeys: + n += 1 + else: + done = True + return newkey + + +template_name_re = re.compile(r'\A\s*(\w[\w\d]*)\s*\Z') +def expand_sub(substr, names): + substr = substr.replace(r'\>', '@rightarrow@') + substr = substr.replace(r'\<', '@leftarrow@') + lnames = find_repl_patterns(substr) + substr = named_re.sub(r"<\1>", substr) # get rid of definition templates + + def listrepl(mobj): + thelist = conv(mobj.group(1).replace(r'\,', '@comma@')) + if template_name_re.match(thelist): + return "<%s>" % (thelist) + name = None + for key in lnames.keys(): # see if list is already in dictionary + if lnames[key] == thelist: + name = key + if name is None: # this list is not in the dictionary yet + name = unique_key(lnames) + lnames[name] = thelist + return "<%s>" % name + + substr = list_re.sub(listrepl, substr) # convert all lists to named templates + # newnames are constructed as needed + + numsubs = None + base_rule = None + rules = {} + for r in template_re.findall(substr): + if r not in rules: + thelist = lnames.get(r, names.get(r, None)) + if thelist is None: + raise ValueError('No replicates found for <%s>' % (r)) + if r not in names and not thelist.startswith('_'): + names[r] = thelist + rule = [i.replace('@comma@', ',') for i in thelist.split(',')] + num = len(rule) + + if numsubs is None: + numsubs = num + rules[r] = rule + base_rule = r + elif num == numsubs: + rules[r] = rule + else: + print("Mismatch in number of replacements (base <%s=%s>)" + " for <%s=%s>. Ignoring." % + (base_rule, ','.join(rules[base_rule]), r, thelist)) + if not rules: + return substr + + def namerepl(mobj): + name = mobj.group(1) + return rules.get(name, (k+1)*[name])[k] + + newstr = '' + for k in range(numsubs): + newstr += template_re.sub(namerepl, substr) + '\n\n' + + newstr = newstr.replace('@rightarrow@', '>') + newstr = newstr.replace('@leftarrow@', '<') + return newstr + +def process_str(allstr): + newstr = allstr + writestr = '' + + struct = parse_structure(newstr) + + oldend = 0 + names = {} + names.update(_special_names) + for sub in struct: + cleanedstr, defs = find_and_remove_repl_patterns(newstr[oldend:sub[0]]) + writestr += cleanedstr + names.update(defs) + writestr += expand_sub(newstr[sub[0]:sub[1]], names) + oldend = sub[1] + writestr += newstr[oldend:] + + return writestr + +include_src_re = re.compile(r"(\n|\A)\s*include\s*['\"](?P[\w\d./\\]+[.]src)['\"]", re.I) + +def resolve_includes(source): + d = os.path.dirname(source) + with open(source) as fid: + lines = [] + for line in fid: + m = include_src_re.match(line) + if m: + fn = m.group('name') + if not os.path.isabs(fn): + fn = os.path.join(d, fn) + if os.path.isfile(fn): + print('Including file', fn) + lines.extend(resolve_includes(fn)) + else: + lines.append(line) + else: + lines.append(line) + return lines + +def process_file(source): + lines = resolve_includes(source) + return process_str(''.join(lines)) + +_special_names = find_repl_patterns(''' +<_c=s,d,c,z> +<_t=real,double precision,complex,double complex> + + + + + +''') + +def main(): + try: + file = sys.argv[1] + except IndexError: + fid = sys.stdin + outfile = sys.stdout + else: + fid = open(file, 'r') + (base, ext) = os.path.splitext(file) + newname = base + outfile = open(newname, 'w') + + allstr = fid.read() + writestr = process_str(allstr) + outfile.write(writestr) + + +if __name__ == "__main__": + main() diff --git a/venv/Lib/site-packages/numpy/distutils/intelccompiler.py b/venv/Lib/site-packages/numpy/distutils/intelccompiler.py new file mode 100644 index 0000000..0388ad5 --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/intelccompiler.py @@ -0,0 +1,111 @@ +import platform + +from distutils.unixccompiler import UnixCCompiler +from numpy.distutils.exec_command import find_executable +from numpy.distutils.ccompiler import simple_version_match +if platform.system() == 'Windows': + from numpy.distutils.msvc9compiler import MSVCCompiler + + +class IntelCCompiler(UnixCCompiler): + """A modified Intel compiler compatible with a GCC-built Python.""" + compiler_type = 'intel' + cc_exe = 'icc' + cc_args = 'fPIC' + + def __init__(self, verbose=0, dry_run=0, force=0): + UnixCCompiler.__init__(self, verbose, dry_run, force) + + v = self.get_version() + mpopt = 'openmp' if v and v < '15' else 'qopenmp' + self.cc_exe = ('icc -fPIC -fp-model strict -O3 ' + '-fomit-frame-pointer -{}').format(mpopt) + compiler = self.cc_exe + + if platform.system() == 'Darwin': + shared_flag = '-Wl,-undefined,dynamic_lookup' + else: + shared_flag = '-shared' + self.set_executables(compiler=compiler, + compiler_so=compiler, + compiler_cxx=compiler, + archiver='xiar' + ' cru', + linker_exe=compiler + ' -shared-intel', + linker_so=compiler + ' ' + shared_flag + + ' -shared-intel') + + +class IntelItaniumCCompiler(IntelCCompiler): + compiler_type = 'intele' + + # On Itanium, the Intel Compiler used to be called ecc, let's search for + # it (now it's also icc, so ecc is last in the search). + for cc_exe in map(find_executable, ['icc', 'ecc']): + if cc_exe: + break + + +class IntelEM64TCCompiler(UnixCCompiler): + """ + A modified Intel x86_64 compiler compatible with a 64bit GCC-built Python. + """ + compiler_type = 'intelem' + cc_exe = 'icc -m64' + cc_args = '-fPIC' + + def __init__(self, verbose=0, dry_run=0, force=0): + UnixCCompiler.__init__(self, verbose, dry_run, force) + + v = self.get_version() + mpopt = 'openmp' if v and v < '15' else 'qopenmp' + self.cc_exe = ('icc -m64 -fPIC -fp-model strict -O3 ' + '-fomit-frame-pointer -{}').format(mpopt) + compiler = self.cc_exe + + if platform.system() == 'Darwin': + shared_flag = '-Wl,-undefined,dynamic_lookup' + else: + shared_flag = '-shared' + self.set_executables(compiler=compiler, + compiler_so=compiler, + compiler_cxx=compiler, + archiver='xiar' + ' cru', + linker_exe=compiler + ' -shared-intel', + linker_so=compiler + ' ' + shared_flag + + ' -shared-intel') + + +if platform.system() == 'Windows': + class IntelCCompilerW(MSVCCompiler): + """ + A modified Intel compiler compatible with an MSVC-built Python. + """ + compiler_type = 'intelw' + compiler_cxx = 'icl' + + def __init__(self, verbose=0, dry_run=0, force=0): + MSVCCompiler.__init__(self, verbose, dry_run, force) + version_match = simple_version_match(start=r'Intel\(R\).*?32,') + self.__version = version_match + + def initialize(self, plat_name=None): + MSVCCompiler.initialize(self, plat_name) + self.cc = self.find_exe('icl.exe') + self.lib = self.find_exe('xilib') + self.linker = self.find_exe('xilink') + self.compile_options = ['/nologo', '/O3', '/MD', '/W3', + '/Qstd=c99'] + self.compile_options_debug = ['/nologo', '/Od', '/MDd', '/W3', + '/Qstd=c99', '/Z7', '/D_DEBUG'] + + class IntelEM64TCCompilerW(IntelCCompilerW): + """ + A modified Intel x86_64 compiler compatible with + a 64bit MSVC-built Python. + """ + compiler_type = 'intelemw' + + def __init__(self, verbose=0, dry_run=0, force=0): + MSVCCompiler.__init__(self, verbose, dry_run, force) + version_match = simple_version_match(start=r'Intel\(R\).*?64,') + self.__version = version_match diff --git a/venv/Lib/site-packages/numpy/distutils/lib2def.py b/venv/Lib/site-packages/numpy/distutils/lib2def.py new file mode 100644 index 0000000..820ed71 --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/lib2def.py @@ -0,0 +1,116 @@ +import re +import sys +import subprocess + +__doc__ = """This module generates a DEF file from the symbols in +an MSVC-compiled DLL import library. It correctly discriminates between +data and functions. The data is collected from the output of the program +nm(1). + +Usage: + python lib2def.py [libname.lib] [output.def] +or + python lib2def.py [libname.lib] > output.def + +libname.lib defaults to python.lib and output.def defaults to stdout + +Author: Robert Kern +Last Update: April 30, 1999 +""" + +__version__ = '0.1a' + +py_ver = "%d%d" % tuple(sys.version_info[:2]) + +DEFAULT_NM = ['nm', '-Cs'] + +DEF_HEADER = """LIBRARY python%s.dll +;CODE PRELOAD MOVEABLE DISCARDABLE +;DATA PRELOAD SINGLE + +EXPORTS +""" % py_ver +# the header of the DEF file + +FUNC_RE = re.compile(r"^(.*) in python%s\.dll" % py_ver, re.MULTILINE) +DATA_RE = re.compile(r"^_imp__(.*) in python%s\.dll" % py_ver, re.MULTILINE) + +def parse_cmd(): + """Parses the command-line arguments. + +libfile, deffile = parse_cmd()""" + if len(sys.argv) == 3: + if sys.argv[1][-4:] == '.lib' and sys.argv[2][-4:] == '.def': + libfile, deffile = sys.argv[1:] + elif sys.argv[1][-4:] == '.def' and sys.argv[2][-4:] == '.lib': + deffile, libfile = sys.argv[1:] + else: + print("I'm assuming that your first argument is the library") + print("and the second is the DEF file.") + elif len(sys.argv) == 2: + if sys.argv[1][-4:] == '.def': + deffile = sys.argv[1] + libfile = 'python%s.lib' % py_ver + elif sys.argv[1][-4:] == '.lib': + deffile = None + libfile = sys.argv[1] + else: + libfile = 'python%s.lib' % py_ver + deffile = None + return libfile, deffile + +def getnm(nm_cmd=['nm', '-Cs', 'python%s.lib' % py_ver], shell=True): + """Returns the output of nm_cmd via a pipe. + +nm_output = getnm(nm_cmd = 'nm -Cs py_lib')""" + p = subprocess.Popen(nm_cmd, shell=shell, stdout=subprocess.PIPE, + stderr=subprocess.PIPE, universal_newlines=True) + nm_output, nm_err = p.communicate() + if p.returncode != 0: + raise RuntimeError('failed to run "%s": "%s"' % ( + ' '.join(nm_cmd), nm_err)) + return nm_output + +def parse_nm(nm_output): + """Returns a tuple of lists: dlist for the list of data +symbols and flist for the list of function symbols. + +dlist, flist = parse_nm(nm_output)""" + data = DATA_RE.findall(nm_output) + func = FUNC_RE.findall(nm_output) + + flist = [] + for sym in data: + if sym in func and (sym[:2] == 'Py' or sym[:3] == '_Py' or sym[:4] == 'init'): + flist.append(sym) + + dlist = [] + for sym in data: + if sym not in flist and (sym[:2] == 'Py' or sym[:3] == '_Py'): + dlist.append(sym) + + dlist.sort() + flist.sort() + return dlist, flist + +def output_def(dlist, flist, header, file = sys.stdout): + """Outputs the final DEF file to a file defaulting to stdout. + +output_def(dlist, flist, header, file = sys.stdout)""" + for data_sym in dlist: + header = header + '\t%s DATA\n' % data_sym + header = header + '\n' # blank line + for func_sym in flist: + header = header + '\t%s\n' % func_sym + file.write(header) + +if __name__ == '__main__': + libfile, deffile = parse_cmd() + if deffile is None: + deffile = sys.stdout + else: + deffile = open(deffile, 'w') + nm_cmd = DEFAULT_NM + [str(libfile)] + nm_output = getnm(nm_cmd, shell=False) + dlist, flist = parse_nm(nm_output) + output_def(dlist, flist, DEF_HEADER, deffile) diff --git a/venv/Lib/site-packages/numpy/distutils/line_endings.py b/venv/Lib/site-packages/numpy/distutils/line_endings.py new file mode 100644 index 0000000..686e5eb --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/line_endings.py @@ -0,0 +1,77 @@ +""" Functions for converting from DOS to UNIX line endings + +""" +import os +import re +import sys + + +def dos2unix(file): + "Replace CRLF with LF in argument files. Print names of changed files." + if os.path.isdir(file): + print(file, "Directory!") + return + + with open(file, "rb") as fp: + data = fp.read() + if '\0' in data: + print(file, "Binary!") + return + + newdata = re.sub("\r\n", "\n", data) + if newdata != data: + print('dos2unix:', file) + with open(file, "wb") as f: + f.write(newdata) + return file + else: + print(file, 'ok') + +def dos2unix_one_dir(modified_files, dir_name, file_names): + for file in file_names: + full_path = os.path.join(dir_name, file) + file = dos2unix(full_path) + if file is not None: + modified_files.append(file) + +def dos2unix_dir(dir_name): + modified_files = [] + os.path.walk(dir_name, dos2unix_one_dir, modified_files) + return modified_files +#---------------------------------- + +def unix2dos(file): + "Replace LF with CRLF in argument files. Print names of changed files." + if os.path.isdir(file): + print(file, "Directory!") + return + + with open(file, "rb") as fp: + data = fp.read() + if '\0' in data: + print(file, "Binary!") + return + newdata = re.sub("\r\n", "\n", data) + newdata = re.sub("\n", "\r\n", newdata) + if newdata != data: + print('unix2dos:', file) + with open(file, "wb") as f: + f.write(newdata) + return file + else: + print(file, 'ok') + +def unix2dos_one_dir(modified_files, dir_name, file_names): + for file in file_names: + full_path = os.path.join(dir_name, file) + unix2dos(full_path) + if file is not None: + modified_files.append(file) + +def unix2dos_dir(dir_name): + modified_files = [] + os.path.walk(dir_name, unix2dos_one_dir, modified_files) + return modified_files + +if __name__ == "__main__": + dos2unix_dir(sys.argv[1]) diff --git a/venv/Lib/site-packages/numpy/distutils/log.py b/venv/Lib/site-packages/numpy/distutils/log.py new file mode 100644 index 0000000..a8113b9 --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/log.py @@ -0,0 +1,89 @@ +# Colored log +import sys +from distutils.log import * # noqa: F403 +from distutils.log import Log as old_Log +from distutils.log import _global_log + +from numpy.distutils.misc_util import (red_text, default_text, cyan_text, + green_text, is_sequence, is_string) + + +def _fix_args(args,flag=1): + if is_string(args): + return args.replace('%', '%%') + if flag and is_sequence(args): + return tuple([_fix_args(a, flag=0) for a in args]) + return args + + +class Log(old_Log): + def _log(self, level, msg, args): + if level >= self.threshold: + if args: + msg = msg % _fix_args(args) + if 0: + if msg.startswith('copying ') and msg.find(' -> ') != -1: + return + if msg.startswith('byte-compiling '): + return + print(_global_color_map[level](msg)) + sys.stdout.flush() + + def good(self, msg, *args): + """ + If we log WARN messages, log this message as a 'nice' anti-warn + message. + + """ + if WARN >= self.threshold: + if args: + print(green_text(msg % _fix_args(args))) + else: + print(green_text(msg)) + sys.stdout.flush() + + +_global_log.__class__ = Log + +good = _global_log.good + +def set_threshold(level, force=False): + prev_level = _global_log.threshold + if prev_level > DEBUG or force: + # If we're running at DEBUG, don't change the threshold, as there's + # likely a good reason why we're running at this level. + _global_log.threshold = level + if level <= DEBUG: + info('set_threshold: setting threshold to DEBUG level,' + ' it can be changed only with force argument') + else: + info('set_threshold: not changing threshold from DEBUG level' + ' %s to %s' % (prev_level, level)) + return prev_level + +def get_threshold(): + return _global_log.threshold + +def set_verbosity(v, force=False): + prev_level = _global_log.threshold + if v < 0: + set_threshold(ERROR, force) + elif v == 0: + set_threshold(WARN, force) + elif v == 1: + set_threshold(INFO, force) + elif v >= 2: + set_threshold(DEBUG, force) + return {FATAL:-2,ERROR:-1,WARN:0,INFO:1,DEBUG:2}.get(prev_level, 1) + + +_global_color_map = { + DEBUG:cyan_text, + INFO:default_text, + WARN:red_text, + ERROR:red_text, + FATAL:red_text +} + +# don't use INFO,.. flags in set_verbosity, these flags are for set_threshold. +set_verbosity(0, force=True) diff --git a/venv/Lib/site-packages/numpy/distutils/mingw/gfortran_vs2003_hack.c b/venv/Lib/site-packages/numpy/distutils/mingw/gfortran_vs2003_hack.c new file mode 100644 index 0000000..485a675 --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/mingw/gfortran_vs2003_hack.c @@ -0,0 +1,6 @@ +int _get_output_format(void) +{ + return 0; +} + +int _imp____lc_codepage = 0; diff --git a/venv/Lib/site-packages/numpy/distutils/mingw32ccompiler.py b/venv/Lib/site-packages/numpy/distutils/mingw32ccompiler.py new file mode 100644 index 0000000..3358695 --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/mingw32ccompiler.py @@ -0,0 +1,657 @@ +""" +Support code for building Python extensions on Windows. + + # NT stuff + # 1. Make sure libpython.a exists for gcc. If not, build it. + # 2. Force windows to use gcc (we're struggling with MSVC and g77 support) + # 3. Force windows to use g77 + +""" +import os +import platform +import sys +import subprocess +import re +import textwrap + +# Overwrite certain distutils.ccompiler functions: +import numpy.distutils.ccompiler # noqa: F401 +from numpy.distutils import log +# NT stuff +# 1. Make sure libpython.a exists for gcc. If not, build it. +# 2. Force windows to use gcc (we're struggling with MSVC and g77 support) +# --> this is done in numpy/distutils/ccompiler.py +# 3. Force windows to use g77 + +import distutils.cygwinccompiler +from distutils.version import StrictVersion +from distutils.unixccompiler import UnixCCompiler +from distutils.msvccompiler import get_build_version as get_build_msvc_version +from distutils.errors import UnknownFileError +from numpy.distutils.misc_util import (msvc_runtime_library, + msvc_runtime_version, + msvc_runtime_major, + get_build_architecture) + +def get_msvcr_replacement(): + """Replacement for outdated version of get_msvcr from cygwinccompiler""" + msvcr = msvc_runtime_library() + return [] if msvcr is None else [msvcr] + +# monkey-patch cygwinccompiler with our updated version from misc_util +# to avoid getting an exception raised on Python 3.5 +distutils.cygwinccompiler.get_msvcr = get_msvcr_replacement + +# Useful to generate table of symbols from a dll +_START = re.compile(r'\[Ordinal/Name Pointer\] Table') +_TABLE = re.compile(r'^\s+\[([\s*[0-9]*)\] ([a-zA-Z0-9_]*)') + +# the same as cygwin plus some additional parameters +class Mingw32CCompiler(distutils.cygwinccompiler.CygwinCCompiler): + """ A modified MingW32 compiler compatible with an MSVC built Python. + + """ + + compiler_type = 'mingw32' + + def __init__ (self, + verbose=0, + dry_run=0, + force=0): + + distutils.cygwinccompiler.CygwinCCompiler.__init__ (self, verbose, + dry_run, force) + + # we need to support 3.2 which doesn't match the standard + # get_versions methods regex + if self.gcc_version is None: + try: + out_string = subprocess.check_output(['gcc', '-dumpversion']) + except (OSError, CalledProcessError): + out_string = "" # ignore failures to match old behavior + result = re.search(r'(\d+\.\d+)', out_string) + if result: + self.gcc_version = StrictVersion(result.group(1)) + + # A real mingw32 doesn't need to specify a different entry point, + # but cygwin 2.91.57 in no-cygwin-mode needs it. + if self.gcc_version <= "2.91.57": + entry_point = '--entry _DllMain@12' + else: + entry_point = '' + + if self.linker_dll == 'dllwrap': + # Commented out '--driver-name g++' part that fixes weird + # g++.exe: g++: No such file or directory + # error (mingw 1.0 in Enthon24 tree, gcc-3.4.5). + # If the --driver-name part is required for some environment + # then make the inclusion of this part specific to that + # environment. + self.linker = 'dllwrap' # --driver-name g++' + elif self.linker_dll == 'gcc': + self.linker = 'g++' + + # **changes: eric jones 4/11/01 + # 1. Check for import library on Windows. Build if it doesn't exist. + + build_import_library() + + # Check for custom msvc runtime library on Windows. Build if it doesn't exist. + msvcr_success = build_msvcr_library() + msvcr_dbg_success = build_msvcr_library(debug=True) + if msvcr_success or msvcr_dbg_success: + # add preprocessor statement for using customized msvcr lib + self.define_macro('NPY_MINGW_USE_CUSTOM_MSVCR') + + # Define the MSVC version as hint for MinGW + msvcr_version = msvc_runtime_version() + if msvcr_version: + self.define_macro('__MSVCRT_VERSION__', '0x%04i' % msvcr_version) + + # MS_WIN64 should be defined when building for amd64 on windows, + # but python headers define it only for MS compilers, which has all + # kind of bad consequences, like using Py_ModuleInit4 instead of + # Py_ModuleInit4_64, etc... So we add it here + if get_build_architecture() == 'AMD64': + if self.gcc_version < "4.0": + self.set_executables( + compiler='gcc -g -DDEBUG -DMS_WIN64 -mno-cygwin -O0 -Wall', + compiler_so='gcc -g -DDEBUG -DMS_WIN64 -mno-cygwin -O0' + ' -Wall -Wstrict-prototypes', + linker_exe='gcc -g -mno-cygwin', + linker_so='gcc -g -mno-cygwin -shared') + else: + # gcc-4 series releases do not support -mno-cygwin option + self.set_executables( + compiler='gcc -g -DDEBUG -DMS_WIN64 -O0 -Wall', + compiler_so='gcc -g -DDEBUG -DMS_WIN64 -O0 -Wall -Wstrict-prototypes', + linker_exe='gcc -g', + linker_so='gcc -g -shared') + else: + if self.gcc_version <= "3.0.0": + self.set_executables( + compiler='gcc -mno-cygwin -O2 -w', + compiler_so='gcc -mno-cygwin -mdll -O2 -w' + ' -Wstrict-prototypes', + linker_exe='g++ -mno-cygwin', + linker_so='%s -mno-cygwin -mdll -static %s' % + (self.linker, entry_point)) + elif self.gcc_version < "4.0": + self.set_executables( + compiler='gcc -mno-cygwin -O2 -Wall', + compiler_so='gcc -mno-cygwin -O2 -Wall' + ' -Wstrict-prototypes', + linker_exe='g++ -mno-cygwin', + linker_so='g++ -mno-cygwin -shared') + else: + # gcc-4 series releases do not support -mno-cygwin option + self.set_executables(compiler='gcc -O2 -Wall', + compiler_so='gcc -O2 -Wall -Wstrict-prototypes', + linker_exe='g++ ', + linker_so='g++ -shared') + # added for python2.3 support + # we can't pass it through set_executables because pre 2.2 would fail + self.compiler_cxx = ['g++'] + + # Maybe we should also append -mthreads, but then the finished dlls + # need another dll (mingwm10.dll see Mingw32 docs) (-mthreads: Support + # thread-safe exception handling on `Mingw32') + + # no additional libraries needed + #self.dll_libraries=[] + return + + # __init__ () + + def link(self, + target_desc, + objects, + output_filename, + output_dir, + libraries, + library_dirs, + runtime_library_dirs, + export_symbols = None, + debug=0, + extra_preargs=None, + extra_postargs=None, + build_temp=None, + target_lang=None): + # Include the appropriate MSVC runtime library if Python was built + # with MSVC >= 7.0 (MinGW standard is msvcrt) + runtime_library = msvc_runtime_library() + if runtime_library: + if not libraries: + libraries = [] + libraries.append(runtime_library) + args = (self, + target_desc, + objects, + output_filename, + output_dir, + libraries, + library_dirs, + runtime_library_dirs, + None, #export_symbols, we do this in our def-file + debug, + extra_preargs, + extra_postargs, + build_temp, + target_lang) + if self.gcc_version < "3.0.0": + func = distutils.cygwinccompiler.CygwinCCompiler.link + else: + func = UnixCCompiler.link + func(*args[:func.__code__.co_argcount]) + return + + def object_filenames (self, + source_filenames, + strip_dir=0, + output_dir=''): + if output_dir is None: output_dir = '' + obj_names = [] + for src_name in source_filenames: + # use normcase to make sure '.rc' is really '.rc' and not '.RC' + (base, ext) = os.path.splitext (os.path.normcase(src_name)) + + # added these lines to strip off windows drive letters + # without it, .o files are placed next to .c files + # instead of the build directory + drv, base = os.path.splitdrive(base) + if drv: + base = base[1:] + + if ext not in (self.src_extensions + ['.rc', '.res']): + raise UnknownFileError( + "unknown file type '%s' (from '%s')" % \ + (ext, src_name)) + if strip_dir: + base = os.path.basename (base) + if ext == '.res' or ext == '.rc': + # these need to be compiled to object files + obj_names.append (os.path.join (output_dir, + base + ext + self.obj_extension)) + else: + obj_names.append (os.path.join (output_dir, + base + self.obj_extension)) + return obj_names + + # object_filenames () + + +def find_python_dll(): + # We can't do much here: + # - find it in the virtualenv (sys.prefix) + # - find it in python main dir (sys.base_prefix, if in a virtualenv) + # - sys.real_prefix is main dir for virtualenvs in Python 2.7 + # - in system32, + # - ortherwise (Sxs), I don't know how to get it. + stems = [sys.prefix] + if hasattr(sys, 'base_prefix') and sys.base_prefix != sys.prefix: + stems.append(sys.base_prefix) + elif hasattr(sys, 'real_prefix') and sys.real_prefix != sys.prefix: + stems.append(sys.real_prefix) + + sub_dirs = ['', 'lib', 'bin'] + # generate possible combinations of directory trees and sub-directories + lib_dirs = [] + for stem in stems: + for folder in sub_dirs: + lib_dirs.append(os.path.join(stem, folder)) + + # add system directory as well + if 'SYSTEMROOT' in os.environ: + lib_dirs.append(os.path.join(os.environ['SYSTEMROOT'], 'System32')) + + # search in the file system for possible candidates + major_version, minor_version = tuple(sys.version_info[:2]) + implementation = platform.python_implementation() + if implementation == 'CPython': + dllname = f'python{major_version}{minor_version}.dll' + elif implementation == 'PyPy': + dllname = f'libpypy{major_version}-c.dll' + else: + dllname = 'Unknown platform {implementation}' + print("Looking for %s" % dllname) + for folder in lib_dirs: + dll = os.path.join(folder, dllname) + if os.path.exists(dll): + return dll + + raise ValueError("%s not found in %s" % (dllname, lib_dirs)) + +def dump_table(dll): + st = subprocess.check_output(["objdump.exe", "-p", dll]) + return st.split(b'\n') + +def generate_def(dll, dfile): + """Given a dll file location, get all its exported symbols and dump them + into the given def file. + + The .def file will be overwritten""" + dump = dump_table(dll) + for i in range(len(dump)): + if _START.match(dump[i].decode()): + break + else: + raise ValueError("Symbol table not found") + + syms = [] + for j in range(i+1, len(dump)): + m = _TABLE.match(dump[j].decode()) + if m: + syms.append((int(m.group(1).strip()), m.group(2))) + else: + break + + if len(syms) == 0: + log.warn('No symbols found in %s' % dll) + + with open(dfile, 'w') as d: + d.write('LIBRARY %s\n' % os.path.basename(dll)) + d.write(';CODE PRELOAD MOVEABLE DISCARDABLE\n') + d.write(';DATA PRELOAD SINGLE\n') + d.write('\nEXPORTS\n') + for s in syms: + #d.write('@%d %s\n' % (s[0], s[1])) + d.write('%s\n' % s[1]) + +def find_dll(dll_name): + + arch = {'AMD64' : 'amd64', + 'Intel' : 'x86'}[get_build_architecture()] + + def _find_dll_in_winsxs(dll_name): + # Walk through the WinSxS directory to find the dll. + winsxs_path = os.path.join(os.environ.get('WINDIR', r'C:\WINDOWS'), + 'winsxs') + if not os.path.exists(winsxs_path): + return None + for root, dirs, files in os.walk(winsxs_path): + if dll_name in files and arch in root: + return os.path.join(root, dll_name) + return None + + def _find_dll_in_path(dll_name): + # First, look in the Python directory, then scan PATH for + # the given dll name. + for path in [sys.prefix] + os.environ['PATH'].split(';'): + filepath = os.path.join(path, dll_name) + if os.path.exists(filepath): + return os.path.abspath(filepath) + + return _find_dll_in_winsxs(dll_name) or _find_dll_in_path(dll_name) + +def build_msvcr_library(debug=False): + if os.name != 'nt': + return False + + # If the version number is None, then we couldn't find the MSVC runtime at + # all, because we are running on a Python distribution which is customed + # compiled; trust that the compiler is the same as the one available to us + # now, and that it is capable of linking with the correct runtime without + # any extra options. + msvcr_ver = msvc_runtime_major() + if msvcr_ver is None: + log.debug('Skip building import library: ' + 'Runtime is not compiled with MSVC') + return False + + # Skip using a custom library for versions < MSVC 8.0 + if msvcr_ver < 80: + log.debug('Skip building msvcr library:' + ' custom functionality not present') + return False + + msvcr_name = msvc_runtime_library() + if debug: + msvcr_name += 'd' + + # Skip if custom library already exists + out_name = "lib%s.a" % msvcr_name + out_file = os.path.join(sys.prefix, 'libs', out_name) + if os.path.isfile(out_file): + log.debug('Skip building msvcr library: "%s" exists' % + (out_file,)) + return True + + # Find the msvcr dll + msvcr_dll_name = msvcr_name + '.dll' + dll_file = find_dll(msvcr_dll_name) + if not dll_file: + log.warn('Cannot build msvcr library: "%s" not found' % + msvcr_dll_name) + return False + + def_name = "lib%s.def" % msvcr_name + def_file = os.path.join(sys.prefix, 'libs', def_name) + + log.info('Building msvcr library: "%s" (from %s)' \ + % (out_file, dll_file)) + + # Generate a symbol definition file from the msvcr dll + generate_def(dll_file, def_file) + + # Create a custom mingw library for the given symbol definitions + cmd = ['dlltool', '-d', def_file, '-l', out_file] + retcode = subprocess.call(cmd) + + # Clean up symbol definitions + os.remove(def_file) + + return (not retcode) + +def build_import_library(): + if os.name != 'nt': + return + + arch = get_build_architecture() + if arch == 'AMD64': + return _build_import_library_amd64() + elif arch == 'Intel': + return _build_import_library_x86() + else: + raise ValueError("Unhandled arch %s" % arch) + +def _check_for_import_lib(): + """Check if an import library for the Python runtime already exists.""" + major_version, minor_version = tuple(sys.version_info[:2]) + + # patterns for the file name of the library itself + patterns = ['libpython%d%d.a', + 'libpython%d%d.dll.a', + 'libpython%d.%d.dll.a'] + + # directory trees that may contain the library + stems = [sys.prefix] + if hasattr(sys, 'base_prefix') and sys.base_prefix != sys.prefix: + stems.append(sys.base_prefix) + elif hasattr(sys, 'real_prefix') and sys.real_prefix != sys.prefix: + stems.append(sys.real_prefix) + + # possible subdirectories within those trees where it is placed + sub_dirs = ['libs', 'lib'] + + # generate a list of candidate locations + candidates = [] + for pat in patterns: + filename = pat % (major_version, minor_version) + for stem_dir in stems: + for folder in sub_dirs: + candidates.append(os.path.join(stem_dir, folder, filename)) + + # test the filesystem to see if we can find any of these + for fullname in candidates: + if os.path.isfile(fullname): + # already exists, in location given + return (True, fullname) + + # needs to be built, preferred location given first + return (False, candidates[0]) + +def _build_import_library_amd64(): + out_exists, out_file = _check_for_import_lib() + if out_exists: + log.debug('Skip building import library: "%s" exists', out_file) + return + + # get the runtime dll for which we are building import library + dll_file = find_python_dll() + log.info('Building import library (arch=AMD64): "%s" (from %s)' % + (out_file, dll_file)) + + # generate symbol list from this library + def_name = "python%d%d.def" % tuple(sys.version_info[:2]) + def_file = os.path.join(sys.prefix, 'libs', def_name) + generate_def(dll_file, def_file) + + # generate import library from this symbol list + cmd = ['dlltool', '-d', def_file, '-l', out_file] + subprocess.check_call(cmd) + +def _build_import_library_x86(): + """ Build the import libraries for Mingw32-gcc on Windows + """ + out_exists, out_file = _check_for_import_lib() + if out_exists: + log.debug('Skip building import library: "%s" exists', out_file) + return + + lib_name = "python%d%d.lib" % tuple(sys.version_info[:2]) + lib_file = os.path.join(sys.prefix, 'libs', lib_name) + if not os.path.isfile(lib_file): + # didn't find library file in virtualenv, try base distribution, too, + # and use that instead if found there. for Python 2.7 venvs, the base + # directory is in attribute real_prefix instead of base_prefix. + if hasattr(sys, 'base_prefix'): + base_lib = os.path.join(sys.base_prefix, 'libs', lib_name) + elif hasattr(sys, 'real_prefix'): + base_lib = os.path.join(sys.real_prefix, 'libs', lib_name) + else: + base_lib = '' # os.path.isfile('') == False + + if os.path.isfile(base_lib): + lib_file = base_lib + else: + log.warn('Cannot build import library: "%s" not found', lib_file) + return + log.info('Building import library (ARCH=x86): "%s"', out_file) + + from numpy.distutils import lib2def + + def_name = "python%d%d.def" % tuple(sys.version_info[:2]) + def_file = os.path.join(sys.prefix, 'libs', def_name) + nm_output = lib2def.getnm( + lib2def.DEFAULT_NM + [lib_file], shell=False) + dlist, flist = lib2def.parse_nm(nm_output) + with open(def_file, 'w') as fid: + lib2def.output_def(dlist, flist, lib2def.DEF_HEADER, fid) + + dll_name = find_python_dll () + + cmd = ["dlltool", + "--dllname", dll_name, + "--def", def_file, + "--output-lib", out_file] + status = subprocess.check_output(cmd) + if status: + log.warn('Failed to build import library for gcc. Linking will fail.') + return + +#===================================== +# Dealing with Visual Studio MANIFESTS +#===================================== + +# Functions to deal with visual studio manifests. Manifest are a mechanism to +# enforce strong DLL versioning on windows, and has nothing to do with +# distutils MANIFEST. manifests are XML files with version info, and used by +# the OS loader; they are necessary when linking against a DLL not in the +# system path; in particular, official python 2.6 binary is built against the +# MS runtime 9 (the one from VS 2008), which is not available on most windows +# systems; python 2.6 installer does install it in the Win SxS (Side by side) +# directory, but this requires the manifest for this to work. This is a big +# mess, thanks MS for a wonderful system. + +# XXX: ideally, we should use exactly the same version as used by python. I +# submitted a patch to get this version, but it was only included for python +# 2.6.1 and above. So for versions below, we use a "best guess". +_MSVCRVER_TO_FULLVER = {} +if sys.platform == 'win32': + try: + import msvcrt + # I took one version in my SxS directory: no idea if it is the good + # one, and we can't retrieve it from python + _MSVCRVER_TO_FULLVER['80'] = "8.0.50727.42" + _MSVCRVER_TO_FULLVER['90'] = "9.0.21022.8" + # Value from msvcrt.CRT_ASSEMBLY_VERSION under Python 3.3.0 + # on Windows XP: + _MSVCRVER_TO_FULLVER['100'] = "10.0.30319.460" + # Python 3.7 uses 1415, but get_build_version returns 140 ?? + _MSVCRVER_TO_FULLVER['140'] = "14.15.26726.0" + if hasattr(msvcrt, "CRT_ASSEMBLY_VERSION"): + major, minor, rest = msvcrt.CRT_ASSEMBLY_VERSION.split(".", 2) + _MSVCRVER_TO_FULLVER[major + minor] = msvcrt.CRT_ASSEMBLY_VERSION + del major, minor, rest + except ImportError: + # If we are here, means python was not built with MSVC. Not sure what + # to do in that case: manifest building will fail, but it should not be + # used in that case anyway + log.warn('Cannot import msvcrt: using manifest will not be possible') + +def msvc_manifest_xml(maj, min): + """Given a major and minor version of the MSVCR, returns the + corresponding XML file.""" + try: + fullver = _MSVCRVER_TO_FULLVER[str(maj * 10 + min)] + except KeyError: + raise ValueError("Version %d,%d of MSVCRT not supported yet" % + (maj, min)) + # Don't be fooled, it looks like an XML, but it is not. In particular, it + # should not have any space before starting, and its size should be + # divisible by 4, most likely for alignment constraints when the xml is + # embedded in the binary... + # This template was copied directly from the python 2.6 binary (using + # strings.exe from mingw on python.exe). + template = textwrap.dedent("""\ + + + + + + + + + + + + + + """) + + return template % {'fullver': fullver, 'maj': maj, 'min': min} + +def manifest_rc(name, type='dll'): + """Return the rc file used to generate the res file which will be embedded + as manifest for given manifest file name, of given type ('dll' or + 'exe'). + + Parameters + ---------- + name : str + name of the manifest file to embed + type : str {'dll', 'exe'} + type of the binary which will embed the manifest + + """ + if type == 'dll': + rctype = 2 + elif type == 'exe': + rctype = 1 + else: + raise ValueError("Type %s not supported" % type) + + return """\ +#include "winuser.h" +%d RT_MANIFEST %s""" % (rctype, name) + +def check_embedded_msvcr_match_linked(msver): + """msver is the ms runtime version used for the MANIFEST.""" + # check msvcr major version are the same for linking and + # embedding + maj = msvc_runtime_major() + if maj: + if not maj == int(msver): + raise ValueError( + "Discrepancy between linked msvcr " \ + "(%d) and the one about to be embedded " \ + "(%d)" % (int(msver), maj)) + +def configtest_name(config): + base = os.path.basename(config._gen_temp_sourcefile("yo", [], "c")) + return os.path.splitext(base)[0] + +def manifest_name(config): + # Get configest name (including suffix) + root = configtest_name(config) + exext = config.compiler.exe_extension + return root + exext + ".manifest" + +def rc_name(config): + # Get configtest name (including suffix) + root = configtest_name(config) + return root + ".rc" + +def generate_manifest(config): + msver = get_build_msvc_version() + if msver is not None: + if msver >= 8: + check_embedded_msvcr_match_linked(msver) + ma = int(msver) + mi = int((msver - ma) * 10) + # Write the manifest file + manxml = msvc_manifest_xml(ma, mi) + man = open(manifest_name(config), "w") + config.temp_files.append(manifest_name(config)) + man.write(manxml) + man.close() diff --git a/venv/Lib/site-packages/numpy/distutils/misc_util.py b/venv/Lib/site-packages/numpy/distutils/misc_util.py new file mode 100644 index 0000000..a8e19d5 --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/misc_util.py @@ -0,0 +1,2393 @@ +import os +import re +import sys +import copy +import glob +import atexit +import tempfile +import subprocess +import shutil +import multiprocessing +import textwrap +import importlib.util + +import distutils +from distutils.errors import DistutilsError +try: + from threading import local as tlocal +except ImportError: + from dummy_threading import local as tlocal + +# stores temporary directory of each thread to only create one per thread +_tdata = tlocal() + +# store all created temporary directories so they can be deleted on exit +_tmpdirs = [] +def clean_up_temporary_directory(): + if _tmpdirs is not None: + for d in _tmpdirs: + try: + shutil.rmtree(d) + except OSError: + pass + +atexit.register(clean_up_temporary_directory) + +from numpy.compat import npy_load_module + +__all__ = ['Configuration', 'get_numpy_include_dirs', 'default_config_dict', + 'dict_append', 'appendpath', 'generate_config_py', + 'get_cmd', 'allpath', 'get_mathlibs', + 'terminal_has_colors', 'red_text', 'green_text', 'yellow_text', + 'blue_text', 'cyan_text', 'cyg2win32', 'mingw32', 'all_strings', + 'has_f_sources', 'has_cxx_sources', 'filter_sources', + 'get_dependencies', 'is_local_src_dir', 'get_ext_source_files', + 'get_script_files', 'get_lib_source_files', 'get_data_files', + 'dot_join', 'get_frame', 'minrelpath', 'njoin', + 'is_sequence', 'is_string', 'as_list', 'gpaths', 'get_language', + 'quote_args', 'get_build_architecture', 'get_info', 'get_pkg_info', + 'get_num_build_jobs'] + +class InstallableLib: + """ + Container to hold information on an installable library. + + Parameters + ---------- + name : str + Name of the installed library. + build_info : dict + Dictionary holding build information. + target_dir : str + Absolute path specifying where to install the library. + + See Also + -------- + Configuration.add_installed_library + + Notes + ----- + The three parameters are stored as attributes with the same names. + + """ + def __init__(self, name, build_info, target_dir): + self.name = name + self.build_info = build_info + self.target_dir = target_dir + + +def get_num_build_jobs(): + """ + Get number of parallel build jobs set by the --parallel command line + argument of setup.py + If the command did not receive a setting the environment variable + NPY_NUM_BUILD_JOBS is checked. If that is unset, return the number of + processors on the system, with a maximum of 8 (to prevent + overloading the system if there a lot of CPUs). + + Returns + ------- + out : int + number of parallel jobs that can be run + + """ + from numpy.distutils.core import get_distribution + try: + cpu_count = len(os.sched_getaffinity(0)) + except AttributeError: + cpu_count = multiprocessing.cpu_count() + cpu_count = min(cpu_count, 8) + envjobs = int(os.environ.get("NPY_NUM_BUILD_JOBS", cpu_count)) + dist = get_distribution() + # may be None during configuration + if dist is None: + return envjobs + + # any of these three may have the job set, take the largest + cmdattr = (getattr(dist.get_command_obj('build'), 'parallel', None), + getattr(dist.get_command_obj('build_ext'), 'parallel', None), + getattr(dist.get_command_obj('build_clib'), 'parallel', None)) + if all(x is None for x in cmdattr): + return envjobs + else: + return max(x for x in cmdattr if x is not None) + +def quote_args(args): + # don't used _nt_quote_args as it does not check if + # args items already have quotes or not. + args = list(args) + for i in range(len(args)): + a = args[i] + if ' ' in a and a[0] not in '"\'': + args[i] = '"%s"' % (a) + return args + +def allpath(name): + "Convert a /-separated pathname to one using the OS's path separator." + splitted = name.split('/') + return os.path.join(*splitted) + +def rel_path(path, parent_path): + """Return path relative to parent_path.""" + # Use realpath to avoid issues with symlinked dirs (see gh-7707) + pd = os.path.realpath(os.path.abspath(parent_path)) + apath = os.path.realpath(os.path.abspath(path)) + if len(apath) < len(pd): + return path + if apath == pd: + return '' + if pd == apath[:len(pd)]: + assert apath[len(pd)] in [os.sep], repr((path, apath[len(pd)])) + path = apath[len(pd)+1:] + return path + +def get_path_from_frame(frame, parent_path=None): + """Return path of the module given a frame object from the call stack. + + Returned path is relative to parent_path when given, + otherwise it is absolute path. + """ + + # First, try to find if the file name is in the frame. + try: + caller_file = eval('__file__', frame.f_globals, frame.f_locals) + d = os.path.dirname(os.path.abspath(caller_file)) + except NameError: + # __file__ is not defined, so let's try __name__. We try this second + # because setuptools spoofs __name__ to be '__main__' even though + # sys.modules['__main__'] might be something else, like easy_install(1). + caller_name = eval('__name__', frame.f_globals, frame.f_locals) + __import__(caller_name) + mod = sys.modules[caller_name] + if hasattr(mod, '__file__'): + d = os.path.dirname(os.path.abspath(mod.__file__)) + else: + # we're probably running setup.py as execfile("setup.py") + # (likely we're building an egg) + d = os.path.abspath('.') + + if parent_path is not None: + d = rel_path(d, parent_path) + + return d or '.' + +def njoin(*path): + """Join two or more pathname components + + - convert a /-separated pathname to one using the OS's path separator. + - resolve `..` and `.` from path. + + Either passing n arguments as in njoin('a','b'), or a sequence + of n names as in njoin(['a','b']) is handled, or a mixture of such arguments. + """ + paths = [] + for p in path: + if is_sequence(p): + # njoin(['a', 'b'], 'c') + paths.append(njoin(*p)) + else: + assert is_string(p) + paths.append(p) + path = paths + if not path: + # njoin() + joined = '' + else: + # njoin('a', 'b') + joined = os.path.join(*path) + if os.path.sep != '/': + joined = joined.replace('/', os.path.sep) + return minrelpath(joined) + +def get_mathlibs(path=None): + """Return the MATHLIB line from numpyconfig.h + """ + if path is not None: + config_file = os.path.join(path, '_numpyconfig.h') + else: + # Look for the file in each of the numpy include directories. + dirs = get_numpy_include_dirs() + for path in dirs: + fn = os.path.join(path, '_numpyconfig.h') + if os.path.exists(fn): + config_file = fn + break + else: + raise DistutilsError('_numpyconfig.h not found in numpy include ' + 'dirs %r' % (dirs,)) + + with open(config_file) as fid: + mathlibs = [] + s = '#define MATHLIB' + for line in fid: + if line.startswith(s): + value = line[len(s):].strip() + if value: + mathlibs.extend(value.split(',')) + return mathlibs + +def minrelpath(path): + """Resolve `..` and '.' from path. + """ + if not is_string(path): + return path + if '.' not in path: + return path + l = path.split(os.sep) + while l: + try: + i = l.index('.', 1) + except ValueError: + break + del l[i] + j = 1 + while l: + try: + i = l.index('..', j) + except ValueError: + break + if l[i-1]=='..': + j += 1 + else: + del l[i], l[i-1] + j = 1 + if not l: + return '' + return os.sep.join(l) + +def sorted_glob(fileglob): + """sorts output of python glob for https://bugs.python.org/issue30461 + to allow extensions to have reproducible build results""" + return sorted(glob.glob(fileglob)) + +def _fix_paths(paths, local_path, include_non_existing): + assert is_sequence(paths), repr(type(paths)) + new_paths = [] + assert not is_string(paths), repr(paths) + for n in paths: + if is_string(n): + if '*' in n or '?' in n: + p = sorted_glob(n) + p2 = sorted_glob(njoin(local_path, n)) + if p2: + new_paths.extend(p2) + elif p: + new_paths.extend(p) + else: + if include_non_existing: + new_paths.append(n) + print('could not resolve pattern in %r: %r' % + (local_path, n)) + else: + n2 = njoin(local_path, n) + if os.path.exists(n2): + new_paths.append(n2) + else: + if os.path.exists(n): + new_paths.append(n) + elif include_non_existing: + new_paths.append(n) + if not os.path.exists(n): + print('non-existing path in %r: %r' % + (local_path, n)) + + elif is_sequence(n): + new_paths.extend(_fix_paths(n, local_path, include_non_existing)) + else: + new_paths.append(n) + return [minrelpath(p) for p in new_paths] + +def gpaths(paths, local_path='', include_non_existing=True): + """Apply glob to paths and prepend local_path if needed. + """ + if is_string(paths): + paths = (paths,) + return _fix_paths(paths, local_path, include_non_existing) + +def make_temp_file(suffix='', prefix='', text=True): + if not hasattr(_tdata, 'tempdir'): + _tdata.tempdir = tempfile.mkdtemp() + _tmpdirs.append(_tdata.tempdir) + fid, name = tempfile.mkstemp(suffix=suffix, + prefix=prefix, + dir=_tdata.tempdir, + text=text) + fo = os.fdopen(fid, 'w') + return fo, name + +# Hooks for colored terminal output. +# See also https://web.archive.org/web/20100314204946/http://www.livinglogic.de/Python/ansistyle +def terminal_has_colors(): + if sys.platform=='cygwin' and 'USE_COLOR' not in os.environ: + # Avoid importing curses that causes illegal operation + # with a message: + # PYTHON2 caused an invalid page fault in + # module CYGNURSES7.DLL as 015f:18bbfc28 + # Details: Python 2.3.3 [GCC 3.3.1 (cygming special)] + # ssh to Win32 machine from debian + # curses.version is 2.2 + # CYGWIN_98-4.10, release 1.5.7(0.109/3/2)) + return 0 + if hasattr(sys.stdout, 'isatty') and sys.stdout.isatty(): + try: + import curses + curses.setupterm() + if (curses.tigetnum("colors") >= 0 + and curses.tigetnum("pairs") >= 0 + and ((curses.tigetstr("setf") is not None + and curses.tigetstr("setb") is not None) + or (curses.tigetstr("setaf") is not None + and curses.tigetstr("setab") is not None) + or curses.tigetstr("scp") is not None)): + return 1 + except Exception: + pass + return 0 + +if terminal_has_colors(): + _colour_codes = dict(black=0, red=1, green=2, yellow=3, + blue=4, magenta=5, cyan=6, white=7, default=9) + def colour_text(s, fg=None, bg=None, bold=False): + seq = [] + if bold: + seq.append('1') + if fg: + fgcode = 30 + _colour_codes.get(fg.lower(), 0) + seq.append(str(fgcode)) + if bg: + bgcode = 40 + _colour_codes.get(fg.lower(), 7) + seq.append(str(bgcode)) + if seq: + return '\x1b[%sm%s\x1b[0m' % (';'.join(seq), s) + else: + return s +else: + def colour_text(s, fg=None, bg=None): + return s + +def default_text(s): + return colour_text(s, 'default') +def red_text(s): + return colour_text(s, 'red') +def green_text(s): + return colour_text(s, 'green') +def yellow_text(s): + return colour_text(s, 'yellow') +def cyan_text(s): + return colour_text(s, 'cyan') +def blue_text(s): + return colour_text(s, 'blue') + +######################### + +def cyg2win32(path): + if sys.platform=='cygwin' and path.startswith('/cygdrive'): + path = path[10] + ':' + os.path.normcase(path[11:]) + return path + +def mingw32(): + """Return true when using mingw32 environment. + """ + if sys.platform=='win32': + if os.environ.get('OSTYPE', '')=='msys': + return True + if os.environ.get('MSYSTEM', '')=='MINGW32': + return True + return False + +def msvc_runtime_version(): + "Return version of MSVC runtime library, as defined by __MSC_VER__ macro" + msc_pos = sys.version.find('MSC v.') + if msc_pos != -1: + msc_ver = int(sys.version[msc_pos+6:msc_pos+10]) + else: + msc_ver = None + return msc_ver + +def msvc_runtime_library(): + "Return name of MSVC runtime library if Python was built with MSVC >= 7" + ver = msvc_runtime_major () + if ver: + if ver < 140: + return "msvcr%i" % ver + else: + return "vcruntime%i" % ver + else: + return None + +def msvc_runtime_major(): + "Return major version of MSVC runtime coded like get_build_msvc_version" + major = {1300: 70, # MSVC 7.0 + 1310: 71, # MSVC 7.1 + 1400: 80, # MSVC 8 + 1500: 90, # MSVC 9 (aka 2008) + 1600: 100, # MSVC 10 (aka 2010) + 1900: 140, # MSVC 14 (aka 2015) + }.get(msvc_runtime_version(), None) + return major + +######################### + +#XXX need support for .C that is also C++ +cxx_ext_match = re.compile(r'.*[.](cpp|cxx|cc)\Z', re.I).match +fortran_ext_match = re.compile(r'.*[.](f90|f95|f77|for|ftn|f)\Z', re.I).match +f90_ext_match = re.compile(r'.*[.](f90|f95)\Z', re.I).match +f90_module_name_match = re.compile(r'\s*module\s*(?P[\w_]+)', re.I).match +def _get_f90_modules(source): + """Return a list of Fortran f90 module names that + given source file defines. + """ + if not f90_ext_match(source): + return [] + modules = [] + with open(source, 'r') as f: + for line in f: + m = f90_module_name_match(line) + if m: + name = m.group('name') + modules.append(name) + # break # XXX can we assume that there is one module per file? + return modules + +def is_string(s): + return isinstance(s, str) + +def all_strings(lst): + """Return True if all items in lst are string objects. """ + for item in lst: + if not is_string(item): + return False + return True + +def is_sequence(seq): + if is_string(seq): + return False + try: + len(seq) + except Exception: + return False + return True + +def is_glob_pattern(s): + return is_string(s) and ('*' in s or '?' in s) + +def as_list(seq): + if is_sequence(seq): + return list(seq) + else: + return [seq] + +def get_language(sources): + # not used in numpy/scipy packages, use build_ext.detect_language instead + """Determine language value (c,f77,f90) from sources """ + language = None + for source in sources: + if isinstance(source, str): + if f90_ext_match(source): + language = 'f90' + break + elif fortran_ext_match(source): + language = 'f77' + return language + +def has_f_sources(sources): + """Return True if sources contains Fortran files """ + for source in sources: + if fortran_ext_match(source): + return True + return False + +def has_cxx_sources(sources): + """Return True if sources contains C++ files """ + for source in sources: + if cxx_ext_match(source): + return True + return False + +def filter_sources(sources): + """Return four lists of filenames containing + C, C++, Fortran, and Fortran 90 module sources, + respectively. + """ + c_sources = [] + cxx_sources = [] + f_sources = [] + fmodule_sources = [] + for source in sources: + if fortran_ext_match(source): + modules = _get_f90_modules(source) + if modules: + fmodule_sources.append(source) + else: + f_sources.append(source) + elif cxx_ext_match(source): + cxx_sources.append(source) + else: + c_sources.append(source) + return c_sources, cxx_sources, f_sources, fmodule_sources + + +def _get_headers(directory_list): + # get *.h files from list of directories + headers = [] + for d in directory_list: + head = sorted_glob(os.path.join(d, "*.h")) #XXX: *.hpp files?? + headers.extend(head) + return headers + +def _get_directories(list_of_sources): + # get unique directories from list of sources. + direcs = [] + for f in list_of_sources: + d = os.path.split(f) + if d[0] != '' and not d[0] in direcs: + direcs.append(d[0]) + return direcs + +def _commandline_dep_string(cc_args, extra_postargs, pp_opts): + """ + Return commandline representation used to determine if a file needs + to be recompiled + """ + cmdline = 'commandline: ' + cmdline += ' '.join(cc_args) + cmdline += ' '.join(extra_postargs) + cmdline += ' '.join(pp_opts) + '\n' + return cmdline + + +def get_dependencies(sources): + #XXX scan sources for include statements + return _get_headers(_get_directories(sources)) + +def is_local_src_dir(directory): + """Return true if directory is local directory. + """ + if not is_string(directory): + return False + abs_dir = os.path.abspath(directory) + c = os.path.commonprefix([os.getcwd(), abs_dir]) + new_dir = abs_dir[len(c):].split(os.sep) + if new_dir and not new_dir[0]: + new_dir = new_dir[1:] + if new_dir and new_dir[0]=='build': + return False + new_dir = os.sep.join(new_dir) + return os.path.isdir(new_dir) + +def general_source_files(top_path): + pruned_directories = {'CVS':1, '.svn':1, 'build':1} + prune_file_pat = re.compile(r'(?:[~#]|\.py[co]|\.o)$') + for dirpath, dirnames, filenames in os.walk(top_path, topdown=True): + pruned = [ d for d in dirnames if d not in pruned_directories ] + dirnames[:] = pruned + for f in filenames: + if not prune_file_pat.search(f): + yield os.path.join(dirpath, f) + +def general_source_directories_files(top_path): + """Return a directory name relative to top_path and + files contained. + """ + pruned_directories = ['CVS', '.svn', 'build'] + prune_file_pat = re.compile(r'(?:[~#]|\.py[co]|\.o)$') + for dirpath, dirnames, filenames in os.walk(top_path, topdown=True): + pruned = [ d for d in dirnames if d not in pruned_directories ] + dirnames[:] = pruned + for d in dirnames: + dpath = os.path.join(dirpath, d) + rpath = rel_path(dpath, top_path) + files = [] + for f in os.listdir(dpath): + fn = os.path.join(dpath, f) + if os.path.isfile(fn) and not prune_file_pat.search(fn): + files.append(fn) + yield rpath, files + dpath = top_path + rpath = rel_path(dpath, top_path) + filenames = [os.path.join(dpath, f) for f in os.listdir(dpath) \ + if not prune_file_pat.search(f)] + files = [f for f in filenames if os.path.isfile(f)] + yield rpath, files + + +def get_ext_source_files(ext): + # Get sources and any include files in the same directory. + filenames = [] + sources = [_m for _m in ext.sources if is_string(_m)] + filenames.extend(sources) + filenames.extend(get_dependencies(sources)) + for d in ext.depends: + if is_local_src_dir(d): + filenames.extend(list(general_source_files(d))) + elif os.path.isfile(d): + filenames.append(d) + return filenames + +def get_script_files(scripts): + scripts = [_m for _m in scripts if is_string(_m)] + return scripts + +def get_lib_source_files(lib): + filenames = [] + sources = lib[1].get('sources', []) + sources = [_m for _m in sources if is_string(_m)] + filenames.extend(sources) + filenames.extend(get_dependencies(sources)) + depends = lib[1].get('depends', []) + for d in depends: + if is_local_src_dir(d): + filenames.extend(list(general_source_files(d))) + elif os.path.isfile(d): + filenames.append(d) + return filenames + +def get_shared_lib_extension(is_python_ext=False): + """Return the correct file extension for shared libraries. + + Parameters + ---------- + is_python_ext : bool, optional + Whether the shared library is a Python extension. Default is False. + + Returns + ------- + so_ext : str + The shared library extension. + + Notes + ----- + For Python shared libs, `so_ext` will typically be '.so' on Linux and OS X, + and '.pyd' on Windows. For Python >= 3.2 `so_ext` has a tag prepended on + POSIX systems according to PEP 3149. For Python 3.2 this is implemented on + Linux, but not on OS X. + + """ + confvars = distutils.sysconfig.get_config_vars() + # SO is deprecated in 3.3.1, use EXT_SUFFIX instead + so_ext = confvars.get('EXT_SUFFIX', None) + if so_ext is None: + so_ext = confvars.get('SO', '') + + if not is_python_ext: + # hardcode known values, config vars (including SHLIB_SUFFIX) are + # unreliable (see #3182) + # darwin, windows and debug linux are wrong in 3.3.1 and older + if (sys.platform.startswith('linux') or + sys.platform.startswith('gnukfreebsd')): + so_ext = '.so' + elif sys.platform.startswith('darwin'): + so_ext = '.dylib' + elif sys.platform.startswith('win'): + so_ext = '.dll' + else: + # fall back to config vars for unknown platforms + # fix long extension for Python >=3.2, see PEP 3149. + if 'SOABI' in confvars: + # Does nothing unless SOABI config var exists + so_ext = so_ext.replace('.' + confvars.get('SOABI'), '', 1) + + return so_ext + +def get_data_files(data): + if is_string(data): + return [data] + sources = data[1] + filenames = [] + for s in sources: + if hasattr(s, '__call__'): + continue + if is_local_src_dir(s): + filenames.extend(list(general_source_files(s))) + elif is_string(s): + if os.path.isfile(s): + filenames.append(s) + else: + print('Not existing data file:', s) + else: + raise TypeError(repr(s)) + return filenames + +def dot_join(*args): + return '.'.join([a for a in args if a]) + +def get_frame(level=0): + """Return frame object from call stack with given level. + """ + try: + return sys._getframe(level+1) + except AttributeError: + frame = sys.exc_info()[2].tb_frame + for _ in range(level+1): + frame = frame.f_back + return frame + + +###################### + +class Configuration: + + _list_keys = ['packages', 'ext_modules', 'data_files', 'include_dirs', + 'libraries', 'headers', 'scripts', 'py_modules', + 'installed_libraries', 'define_macros'] + _dict_keys = ['package_dir', 'installed_pkg_config'] + _extra_keys = ['name', 'version'] + + numpy_include_dirs = [] + + def __init__(self, + package_name=None, + parent_name=None, + top_path=None, + package_path=None, + caller_level=1, + setup_name='setup.py', + **attrs): + """Construct configuration instance of a package. + + package_name -- name of the package + Ex.: 'distutils' + parent_name -- name of the parent package + Ex.: 'numpy' + top_path -- directory of the toplevel package + Ex.: the directory where the numpy package source sits + package_path -- directory of package. Will be computed by magic from the + directory of the caller module if not specified + Ex.: the directory where numpy.distutils is + caller_level -- frame level to caller namespace, internal parameter. + """ + self.name = dot_join(parent_name, package_name) + self.version = None + + caller_frame = get_frame(caller_level) + self.local_path = get_path_from_frame(caller_frame, top_path) + # local_path -- directory of a file (usually setup.py) that + # defines a configuration() function. + # local_path -- directory of a file (usually setup.py) that + # defines a configuration() function. + if top_path is None: + top_path = self.local_path + self.local_path = '' + if package_path is None: + package_path = self.local_path + elif os.path.isdir(njoin(self.local_path, package_path)): + package_path = njoin(self.local_path, package_path) + if not os.path.isdir(package_path or '.'): + raise ValueError("%r is not a directory" % (package_path,)) + self.top_path = top_path + self.package_path = package_path + # this is the relative path in the installed package + self.path_in_package = os.path.join(*self.name.split('.')) + + self.list_keys = self._list_keys[:] + self.dict_keys = self._dict_keys[:] + + for n in self.list_keys: + v = copy.copy(attrs.get(n, [])) + setattr(self, n, as_list(v)) + + for n in self.dict_keys: + v = copy.copy(attrs.get(n, {})) + setattr(self, n, v) + + known_keys = self.list_keys + self.dict_keys + self.extra_keys = self._extra_keys[:] + for n in attrs.keys(): + if n in known_keys: + continue + a = attrs[n] + setattr(self, n, a) + if isinstance(a, list): + self.list_keys.append(n) + elif isinstance(a, dict): + self.dict_keys.append(n) + else: + self.extra_keys.append(n) + + if os.path.exists(njoin(package_path, '__init__.py')): + self.packages.append(self.name) + self.package_dir[self.name] = package_path + + self.options = dict( + ignore_setup_xxx_py = False, + assume_default_configuration = False, + delegate_options_to_subpackages = False, + quiet = False, + ) + + caller_instance = None + for i in range(1, 3): + try: + f = get_frame(i) + except ValueError: + break + try: + caller_instance = eval('self', f.f_globals, f.f_locals) + break + except NameError: + pass + if isinstance(caller_instance, self.__class__): + if caller_instance.options['delegate_options_to_subpackages']: + self.set_options(**caller_instance.options) + + self.setup_name = setup_name + + def todict(self): + """ + Return a dictionary compatible with the keyword arguments of distutils + setup function. + + Examples + -------- + >>> setup(**config.todict()) #doctest: +SKIP + """ + + self._optimize_data_files() + d = {} + known_keys = self.list_keys + self.dict_keys + self.extra_keys + for n in known_keys: + a = getattr(self, n) + if a: + d[n] = a + return d + + def info(self, message): + if not self.options['quiet']: + print(message) + + def warn(self, message): + sys.stderr.write('Warning: %s\n' % (message,)) + + def set_options(self, **options): + """ + Configure Configuration instance. + + The following options are available: + - ignore_setup_xxx_py + - assume_default_configuration + - delegate_options_to_subpackages + - quiet + + """ + for key, value in options.items(): + if key in self.options: + self.options[key] = value + else: + raise ValueError('Unknown option: '+key) + + def get_distribution(self): + """Return the distutils distribution object for self.""" + from numpy.distutils.core import get_distribution + return get_distribution() + + def _wildcard_get_subpackage(self, subpackage_name, + parent_name, + caller_level = 1): + l = subpackage_name.split('.') + subpackage_path = njoin([self.local_path]+l) + dirs = [_m for _m in sorted_glob(subpackage_path) if os.path.isdir(_m)] + config_list = [] + for d in dirs: + if not os.path.isfile(njoin(d, '__init__.py')): + continue + if 'build' in d.split(os.sep): + continue + n = '.'.join(d.split(os.sep)[-len(l):]) + c = self.get_subpackage(n, + parent_name = parent_name, + caller_level = caller_level+1) + config_list.extend(c) + return config_list + + def _get_configuration_from_setup_py(self, setup_py, + subpackage_name, + subpackage_path, + parent_name, + caller_level = 1): + # In case setup_py imports local modules: + sys.path.insert(0, os.path.dirname(setup_py)) + try: + setup_name = os.path.splitext(os.path.basename(setup_py))[0] + n = dot_join(self.name, subpackage_name, setup_name) + setup_module = npy_load_module('_'.join(n.split('.')), + setup_py, + ('.py', 'U', 1)) + if not hasattr(setup_module, 'configuration'): + if not self.options['assume_default_configuration']: + self.warn('Assuming default configuration '\ + '(%s does not define configuration())'\ + % (setup_module)) + config = Configuration(subpackage_name, parent_name, + self.top_path, subpackage_path, + caller_level = caller_level + 1) + else: + pn = dot_join(*([parent_name] + subpackage_name.split('.')[:-1])) + args = (pn,) + if setup_module.configuration.__code__.co_argcount > 1: + args = args + (self.top_path,) + config = setup_module.configuration(*args) + if config.name!=dot_join(parent_name, subpackage_name): + self.warn('Subpackage %r configuration returned as %r' % \ + (dot_join(parent_name, subpackage_name), config.name)) + finally: + del sys.path[0] + return config + + def get_subpackage(self,subpackage_name, + subpackage_path=None, + parent_name=None, + caller_level = 1): + """Return list of subpackage configurations. + + Parameters + ---------- + subpackage_name : str or None + Name of the subpackage to get the configuration. '*' in + subpackage_name is handled as a wildcard. + subpackage_path : str + If None, then the path is assumed to be the local path plus the + subpackage_name. If a setup.py file is not found in the + subpackage_path, then a default configuration is used. + parent_name : str + Parent name. + """ + if subpackage_name is None: + if subpackage_path is None: + raise ValueError( + "either subpackage_name or subpackage_path must be specified") + subpackage_name = os.path.basename(subpackage_path) + + # handle wildcards + l = subpackage_name.split('.') + if subpackage_path is None and '*' in subpackage_name: + return self._wildcard_get_subpackage(subpackage_name, + parent_name, + caller_level = caller_level+1) + assert '*' not in subpackage_name, repr((subpackage_name, subpackage_path, parent_name)) + if subpackage_path is None: + subpackage_path = njoin([self.local_path] + l) + else: + subpackage_path = njoin([subpackage_path] + l[:-1]) + subpackage_path = self.paths([subpackage_path])[0] + setup_py = njoin(subpackage_path, self.setup_name) + if not self.options['ignore_setup_xxx_py']: + if not os.path.isfile(setup_py): + setup_py = njoin(subpackage_path, + 'setup_%s.py' % (subpackage_name)) + if not os.path.isfile(setup_py): + if not self.options['assume_default_configuration']: + self.warn('Assuming default configuration '\ + '(%s/{setup_%s,setup}.py was not found)' \ + % (os.path.dirname(setup_py), subpackage_name)) + config = Configuration(subpackage_name, parent_name, + self.top_path, subpackage_path, + caller_level = caller_level+1) + else: + config = self._get_configuration_from_setup_py( + setup_py, + subpackage_name, + subpackage_path, + parent_name, + caller_level = caller_level + 1) + if config: + return [config] + else: + return [] + + def add_subpackage(self,subpackage_name, + subpackage_path=None, + standalone = False): + """Add a sub-package to the current Configuration instance. + + This is useful in a setup.py script for adding sub-packages to a + package. + + Parameters + ---------- + subpackage_name : str + name of the subpackage + subpackage_path : str + if given, the subpackage path such as the subpackage is in + subpackage_path / subpackage_name. If None,the subpackage is + assumed to be located in the local path / subpackage_name. + standalone : bool + """ + + if standalone: + parent_name = None + else: + parent_name = self.name + config_list = self.get_subpackage(subpackage_name, subpackage_path, + parent_name = parent_name, + caller_level = 2) + if not config_list: + self.warn('No configuration returned, assuming unavailable.') + for config in config_list: + d = config + if isinstance(config, Configuration): + d = config.todict() + assert isinstance(d, dict), repr(type(d)) + + self.info('Appending %s configuration to %s' \ + % (d.get('name'), self.name)) + self.dict_append(**d) + + dist = self.get_distribution() + if dist is not None: + self.warn('distutils distribution has been initialized,'\ + ' it may be too late to add a subpackage '+ subpackage_name) + + def add_data_dir(self, data_path): + """Recursively add files under data_path to data_files list. + + Recursively add files under data_path to the list of data_files to be + installed (and distributed). The data_path can be either a relative + path-name, or an absolute path-name, or a 2-tuple where the first + argument shows where in the install directory the data directory + should be installed to. + + Parameters + ---------- + data_path : seq or str + Argument can be either + + * 2-sequence (, ) + * path to data directory where python datadir suffix defaults + to package dir. + + Notes + ----- + Rules for installation paths:: + + foo/bar -> (foo/bar, foo/bar) -> parent/foo/bar + (gun, foo/bar) -> parent/gun + foo/* -> (foo/a, foo/a), (foo/b, foo/b) -> parent/foo/a, parent/foo/b + (gun, foo/*) -> (gun, foo/a), (gun, foo/b) -> gun + (gun/*, foo/*) -> parent/gun/a, parent/gun/b + /foo/bar -> (bar, /foo/bar) -> parent/bar + (gun, /foo/bar) -> parent/gun + (fun/*/gun/*, sun/foo/bar) -> parent/fun/foo/gun/bar + + Examples + -------- + For example suppose the source directory contains fun/foo.dat and + fun/bar/car.dat: + + >>> self.add_data_dir('fun') #doctest: +SKIP + >>> self.add_data_dir(('sun', 'fun')) #doctest: +SKIP + >>> self.add_data_dir(('gun', '/full/path/to/fun'))#doctest: +SKIP + + Will install data-files to the locations:: + + / + fun/ + foo.dat + bar/ + car.dat + sun/ + foo.dat + bar/ + car.dat + gun/ + foo.dat + car.dat + + """ + if is_sequence(data_path): + d, data_path = data_path + else: + d = None + if is_sequence(data_path): + [self.add_data_dir((d, p)) for p in data_path] + return + if not is_string(data_path): + raise TypeError("not a string: %r" % (data_path,)) + if d is None: + if os.path.isabs(data_path): + return self.add_data_dir((os.path.basename(data_path), data_path)) + return self.add_data_dir((data_path, data_path)) + paths = self.paths(data_path, include_non_existing=False) + if is_glob_pattern(data_path): + if is_glob_pattern(d): + pattern_list = allpath(d).split(os.sep) + pattern_list.reverse() + # /a/*//b/ -> /a/*/b + rl = list(range(len(pattern_list)-1)); rl.reverse() + for i in rl: + if not pattern_list[i]: + del pattern_list[i] + # + for path in paths: + if not os.path.isdir(path): + print('Not a directory, skipping', path) + continue + rpath = rel_path(path, self.local_path) + path_list = rpath.split(os.sep) + path_list.reverse() + target_list = [] + i = 0 + for s in pattern_list: + if is_glob_pattern(s): + if i>=len(path_list): + raise ValueError('cannot fill pattern %r with %r' \ + % (d, path)) + target_list.append(path_list[i]) + else: + assert s==path_list[i], repr((s, path_list[i], data_path, d, path, rpath)) + target_list.append(s) + i += 1 + if path_list[i:]: + self.warn('mismatch of pattern_list=%s and path_list=%s'\ + % (pattern_list, path_list)) + target_list.reverse() + self.add_data_dir((os.sep.join(target_list), path)) + else: + for path in paths: + self.add_data_dir((d, path)) + return + assert not is_glob_pattern(d), repr(d) + + dist = self.get_distribution() + if dist is not None and dist.data_files is not None: + data_files = dist.data_files + else: + data_files = self.data_files + + for path in paths: + for d1, f in list(general_source_directories_files(path)): + target_path = os.path.join(self.path_in_package, d, d1) + data_files.append((target_path, f)) + + def _optimize_data_files(self): + data_dict = {} + for p, files in self.data_files: + if p not in data_dict: + data_dict[p] = set() + for f in files: + data_dict[p].add(f) + self.data_files[:] = [(p, list(files)) for p, files in data_dict.items()] + + def add_data_files(self,*files): + """Add data files to configuration data_files. + + Parameters + ---------- + files : sequence + Argument(s) can be either + + * 2-sequence (,) + * paths to data files where python datadir prefix defaults + to package dir. + + Notes + ----- + The form of each element of the files sequence is very flexible + allowing many combinations of where to get the files from the package + and where they should ultimately be installed on the system. The most + basic usage is for an element of the files argument sequence to be a + simple filename. This will cause that file from the local path to be + installed to the installation path of the self.name package (package + path). The file argument can also be a relative path in which case the + entire relative path will be installed into the package directory. + Finally, the file can be an absolute path name in which case the file + will be found at the absolute path name but installed to the package + path. + + This basic behavior can be augmented by passing a 2-tuple in as the + file argument. The first element of the tuple should specify the + relative path (under the package install directory) where the + remaining sequence of files should be installed to (it has nothing to + do with the file-names in the source distribution). The second element + of the tuple is the sequence of files that should be installed. The + files in this sequence can be filenames, relative paths, or absolute + paths. For absolute paths the file will be installed in the top-level + package installation directory (regardless of the first argument). + Filenames and relative path names will be installed in the package + install directory under the path name given as the first element of + the tuple. + + Rules for installation paths: + + #. file.txt -> (., file.txt)-> parent/file.txt + #. foo/file.txt -> (foo, foo/file.txt) -> parent/foo/file.txt + #. /foo/bar/file.txt -> (., /foo/bar/file.txt) -> parent/file.txt + #. ``*``.txt -> parent/a.txt, parent/b.txt + #. foo/``*``.txt`` -> parent/foo/a.txt, parent/foo/b.txt + #. ``*/*.txt`` -> (``*``, ``*``/``*``.txt) -> parent/c/a.txt, parent/d/b.txt + #. (sun, file.txt) -> parent/sun/file.txt + #. (sun, bar/file.txt) -> parent/sun/file.txt + #. (sun, /foo/bar/file.txt) -> parent/sun/file.txt + #. (sun, ``*``.txt) -> parent/sun/a.txt, parent/sun/b.txt + #. (sun, bar/``*``.txt) -> parent/sun/a.txt, parent/sun/b.txt + #. (sun/``*``, ``*``/``*``.txt) -> parent/sun/c/a.txt, parent/d/b.txt + + An additional feature is that the path to a data-file can actually be + a function that takes no arguments and returns the actual path(s) to + the data-files. This is useful when the data files are generated while + building the package. + + Examples + -------- + Add files to the list of data_files to be included with the package. + + >>> self.add_data_files('foo.dat', + ... ('fun', ['gun.dat', 'nun/pun.dat', '/tmp/sun.dat']), + ... 'bar/cat.dat', + ... '/full/path/to/can.dat') #doctest: +SKIP + + will install these data files to:: + + / + foo.dat + fun/ + gun.dat + nun/ + pun.dat + sun.dat + bar/ + car.dat + can.dat + + where is the package (or sub-package) + directory such as '/usr/lib/python2.4/site-packages/mypackage' ('C: + \\Python2.4 \\Lib \\site-packages \\mypackage') or + '/usr/lib/python2.4/site- packages/mypackage/mysubpackage' ('C: + \\Python2.4 \\Lib \\site-packages \\mypackage \\mysubpackage'). + """ + + if len(files)>1: + for f in files: + self.add_data_files(f) + return + assert len(files)==1 + if is_sequence(files[0]): + d, files = files[0] + else: + d = None + if is_string(files): + filepat = files + elif is_sequence(files): + if len(files)==1: + filepat = files[0] + else: + for f in files: + self.add_data_files((d, f)) + return + else: + raise TypeError(repr(type(files))) + + if d is None: + if hasattr(filepat, '__call__'): + d = '' + elif os.path.isabs(filepat): + d = '' + else: + d = os.path.dirname(filepat) + self.add_data_files((d, files)) + return + + paths = self.paths(filepat, include_non_existing=False) + if is_glob_pattern(filepat): + if is_glob_pattern(d): + pattern_list = d.split(os.sep) + pattern_list.reverse() + for path in paths: + path_list = path.split(os.sep) + path_list.reverse() + path_list.pop() # filename + target_list = [] + i = 0 + for s in pattern_list: + if is_glob_pattern(s): + target_list.append(path_list[i]) + i += 1 + else: + target_list.append(s) + target_list.reverse() + self.add_data_files((os.sep.join(target_list), path)) + else: + self.add_data_files((d, paths)) + return + assert not is_glob_pattern(d), repr((d, filepat)) + + dist = self.get_distribution() + if dist is not None and dist.data_files is not None: + data_files = dist.data_files + else: + data_files = self.data_files + + data_files.append((os.path.join(self.path_in_package, d), paths)) + + ### XXX Implement add_py_modules + + def add_define_macros(self, macros): + """Add define macros to configuration + + Add the given sequence of macro name and value duples to the beginning + of the define_macros list This list will be visible to all extension + modules of the current package. + """ + dist = self.get_distribution() + if dist is not None: + if not hasattr(dist, 'define_macros'): + dist.define_macros = [] + dist.define_macros.extend(macros) + else: + self.define_macros.extend(macros) + + + def add_include_dirs(self,*paths): + """Add paths to configuration include directories. + + Add the given sequence of paths to the beginning of the include_dirs + list. This list will be visible to all extension modules of the + current package. + """ + include_dirs = self.paths(paths) + dist = self.get_distribution() + if dist is not None: + if dist.include_dirs is None: + dist.include_dirs = [] + dist.include_dirs.extend(include_dirs) + else: + self.include_dirs.extend(include_dirs) + + def add_headers(self,*files): + """Add installable headers to configuration. + + Add the given sequence of files to the beginning of the headers list. + By default, headers will be installed under // directory. If an item of files + is a tuple, then its first argument specifies the actual installation + location relative to the path. + + Parameters + ---------- + files : str or seq + Argument(s) can be either: + + * 2-sequence (,) + * path(s) to header file(s) where python includedir suffix will + default to package name. + """ + headers = [] + for path in files: + if is_string(path): + [headers.append((self.name, p)) for p in self.paths(path)] + else: + if not isinstance(path, (tuple, list)) or len(path) != 2: + raise TypeError(repr(path)) + [headers.append((path[0], p)) for p in self.paths(path[1])] + dist = self.get_distribution() + if dist is not None: + if dist.headers is None: + dist.headers = [] + dist.headers.extend(headers) + else: + self.headers.extend(headers) + + def paths(self,*paths,**kws): + """Apply glob to paths and prepend local_path if needed. + + Applies glob.glob(...) to each path in the sequence (if needed) and + pre-pends the local_path if needed. Because this is called on all + source lists, this allows wildcard characters to be specified in lists + of sources for extension modules and libraries and scripts and allows + path-names be relative to the source directory. + + """ + include_non_existing = kws.get('include_non_existing', True) + return gpaths(paths, + local_path = self.local_path, + include_non_existing=include_non_existing) + + def _fix_paths_dict(self, kw): + for k in kw.keys(): + v = kw[k] + if k in ['sources', 'depends', 'include_dirs', 'library_dirs', + 'module_dirs', 'extra_objects']: + new_v = self.paths(v) + kw[k] = new_v + + def add_extension(self,name,sources,**kw): + """Add extension to configuration. + + Create and add an Extension instance to the ext_modules list. This + method also takes the following optional keyword arguments that are + passed on to the Extension constructor. + + Parameters + ---------- + name : str + name of the extension + sources : seq + list of the sources. The list of sources may contain functions + (called source generators) which must take an extension instance + and a build directory as inputs and return a source file or list of + source files or None. If None is returned then no sources are + generated. If the Extension instance has no sources after + processing all source generators, then no extension module is + built. + include_dirs : + define_macros : + undef_macros : + library_dirs : + libraries : + runtime_library_dirs : + extra_objects : + extra_compile_args : + extra_link_args : + extra_f77_compile_args : + extra_f90_compile_args : + export_symbols : + swig_opts : + depends : + The depends list contains paths to files or directories that the + sources of the extension module depend on. If any path in the + depends list is newer than the extension module, then the module + will be rebuilt. + language : + f2py_options : + module_dirs : + extra_info : dict or list + dict or list of dict of keywords to be appended to keywords. + + Notes + ----- + The self.paths(...) method is applied to all lists that may contain + paths. + """ + ext_args = copy.copy(kw) + ext_args['name'] = dot_join(self.name, name) + ext_args['sources'] = sources + + if 'extra_info' in ext_args: + extra_info = ext_args['extra_info'] + del ext_args['extra_info'] + if isinstance(extra_info, dict): + extra_info = [extra_info] + for info in extra_info: + assert isinstance(info, dict), repr(info) + dict_append(ext_args,**info) + + self._fix_paths_dict(ext_args) + + # Resolve out-of-tree dependencies + libraries = ext_args.get('libraries', []) + libnames = [] + ext_args['libraries'] = [] + for libname in libraries: + if isinstance(libname, tuple): + self._fix_paths_dict(libname[1]) + + # Handle library names of the form libname@relative/path/to/library + if '@' in libname: + lname, lpath = libname.split('@', 1) + lpath = os.path.abspath(njoin(self.local_path, lpath)) + if os.path.isdir(lpath): + c = self.get_subpackage(None, lpath, + caller_level = 2) + if isinstance(c, Configuration): + c = c.todict() + for l in [l[0] for l in c.get('libraries', [])]: + llname = l.split('__OF__', 1)[0] + if llname == lname: + c.pop('name', None) + dict_append(ext_args,**c) + break + continue + libnames.append(libname) + + ext_args['libraries'] = libnames + ext_args['libraries'] + ext_args['define_macros'] = \ + self.define_macros + ext_args.get('define_macros', []) + + from numpy.distutils.core import Extension + ext = Extension(**ext_args) + self.ext_modules.append(ext) + + dist = self.get_distribution() + if dist is not None: + self.warn('distutils distribution has been initialized,'\ + ' it may be too late to add an extension '+name) + return ext + + def add_library(self,name,sources,**build_info): + """ + Add library to configuration. + + Parameters + ---------- + name : str + Name of the extension. + sources : sequence + List of the sources. The list of sources may contain functions + (called source generators) which must take an extension instance + and a build directory as inputs and return a source file or list of + source files or None. If None is returned then no sources are + generated. If the Extension instance has no sources after + processing all source generators, then no extension module is + built. + build_info : dict, optional + The following keys are allowed: + + * depends + * macros + * include_dirs + * extra_compiler_args + * extra_f77_compile_args + * extra_f90_compile_args + * f2py_options + * language + + """ + self._add_library(name, sources, None, build_info) + + dist = self.get_distribution() + if dist is not None: + self.warn('distutils distribution has been initialized,'\ + ' it may be too late to add a library '+ name) + + def _add_library(self, name, sources, install_dir, build_info): + """Common implementation for add_library and add_installed_library. Do + not use directly""" + build_info = copy.copy(build_info) + build_info['sources'] = sources + + # Sometimes, depends is not set up to an empty list by default, and if + # depends is not given to add_library, distutils barfs (#1134) + if not 'depends' in build_info: + build_info['depends'] = [] + + self._fix_paths_dict(build_info) + + # Add to libraries list so that it is build with build_clib + self.libraries.append((name, build_info)) + + def add_installed_library(self, name, sources, install_dir, build_info=None): + """ + Similar to add_library, but the specified library is installed. + + Most C libraries used with `distutils` are only used to build python + extensions, but libraries built through this method will be installed + so that they can be reused by third-party packages. + + Parameters + ---------- + name : str + Name of the installed library. + sources : sequence + List of the library's source files. See `add_library` for details. + install_dir : str + Path to install the library, relative to the current sub-package. + build_info : dict, optional + The following keys are allowed: + + * depends + * macros + * include_dirs + * extra_compiler_args + * extra_f77_compile_args + * extra_f90_compile_args + * f2py_options + * language + + Returns + ------- + None + + See Also + -------- + add_library, add_npy_pkg_config, get_info + + Notes + ----- + The best way to encode the options required to link against the specified + C libraries is to use a "libname.ini" file, and use `get_info` to + retrieve the required options (see `add_npy_pkg_config` for more + information). + + """ + if not build_info: + build_info = {} + + install_dir = os.path.join(self.package_path, install_dir) + self._add_library(name, sources, install_dir, build_info) + self.installed_libraries.append(InstallableLib(name, build_info, install_dir)) + + def add_npy_pkg_config(self, template, install_dir, subst_dict=None): + """ + Generate and install a npy-pkg config file from a template. + + The config file generated from `template` is installed in the + given install directory, using `subst_dict` for variable substitution. + + Parameters + ---------- + template : str + The path of the template, relatively to the current package path. + install_dir : str + Where to install the npy-pkg config file, relatively to the current + package path. + subst_dict : dict, optional + If given, any string of the form ``@key@`` will be replaced by + ``subst_dict[key]`` in the template file when installed. The install + prefix is always available through the variable ``@prefix@``, since the + install prefix is not easy to get reliably from setup.py. + + See also + -------- + add_installed_library, get_info + + Notes + ----- + This works for both standard installs and in-place builds, i.e. the + ``@prefix@`` refer to the source directory for in-place builds. + + Examples + -------- + :: + + config.add_npy_pkg_config('foo.ini.in', 'lib', {'foo': bar}) + + Assuming the foo.ini.in file has the following content:: + + [meta] + Name=@foo@ + Version=1.0 + Description=dummy description + + [default] + Cflags=-I@prefix@/include + Libs= + + The generated file will have the following content:: + + [meta] + Name=bar + Version=1.0 + Description=dummy description + + [default] + Cflags=-Iprefix_dir/include + Libs= + + and will be installed as foo.ini in the 'lib' subpath. + + When cross-compiling with numpy distutils, it might be necessary to + use modified npy-pkg-config files. Using the default/generated files + will link with the host libraries (i.e. libnpymath.a). For + cross-compilation you of-course need to link with target libraries, + while using the host Python installation. + + You can copy out the numpy/core/lib/npy-pkg-config directory, add a + pkgdir value to the .ini files and set NPY_PKG_CONFIG_PATH environment + variable to point to the directory with the modified npy-pkg-config + files. + + Example npymath.ini modified for cross-compilation:: + + [meta] + Name=npymath + Description=Portable, core math library implementing C99 standard + Version=0.1 + + [variables] + pkgname=numpy.core + pkgdir=/build/arm-linux-gnueabi/sysroot/usr/lib/python3.7/site-packages/numpy/core + prefix=${pkgdir} + libdir=${prefix}/lib + includedir=${prefix}/include + + [default] + Libs=-L${libdir} -lnpymath + Cflags=-I${includedir} + Requires=mlib + + [msvc] + Libs=/LIBPATH:${libdir} npymath.lib + Cflags=/INCLUDE:${includedir} + Requires=mlib + + """ + if subst_dict is None: + subst_dict = {} + template = os.path.join(self.package_path, template) + + if self.name in self.installed_pkg_config: + self.installed_pkg_config[self.name].append((template, install_dir, + subst_dict)) + else: + self.installed_pkg_config[self.name] = [(template, install_dir, + subst_dict)] + + + def add_scripts(self,*files): + """Add scripts to configuration. + + Add the sequence of files to the beginning of the scripts list. + Scripts will be installed under the /bin/ directory. + + """ + scripts = self.paths(files) + dist = self.get_distribution() + if dist is not None: + if dist.scripts is None: + dist.scripts = [] + dist.scripts.extend(scripts) + else: + self.scripts.extend(scripts) + + def dict_append(self,**dict): + for key in self.list_keys: + a = getattr(self, key) + a.extend(dict.get(key, [])) + for key in self.dict_keys: + a = getattr(self, key) + a.update(dict.get(key, {})) + known_keys = self.list_keys + self.dict_keys + self.extra_keys + for key in dict.keys(): + if key not in known_keys: + a = getattr(self, key, None) + if a and a==dict[key]: continue + self.warn('Inheriting attribute %r=%r from %r' \ + % (key, dict[key], dict.get('name', '?'))) + setattr(self, key, dict[key]) + self.extra_keys.append(key) + elif key in self.extra_keys: + self.info('Ignoring attempt to set %r (from %r to %r)' \ + % (key, getattr(self, key), dict[key])) + elif key in known_keys: + # key is already processed above + pass + else: + raise ValueError("Don't know about key=%r" % (key)) + + def __str__(self): + from pprint import pformat + known_keys = self.list_keys + self.dict_keys + self.extra_keys + s = '<'+5*'-' + '\n' + s += 'Configuration of '+self.name+':\n' + known_keys.sort() + for k in known_keys: + a = getattr(self, k, None) + if a: + s += '%s = %s\n' % (k, pformat(a)) + s += 5*'-' + '>' + return s + + def get_config_cmd(self): + """ + Returns the numpy.distutils config command instance. + """ + cmd = get_cmd('config') + cmd.ensure_finalized() + cmd.dump_source = 0 + cmd.noisy = 0 + old_path = os.environ.get('PATH') + if old_path: + path = os.pathsep.join(['.', old_path]) + os.environ['PATH'] = path + return cmd + + def get_build_temp_dir(self): + """ + Return a path to a temporary directory where temporary files should be + placed. + """ + cmd = get_cmd('build') + cmd.ensure_finalized() + return cmd.build_temp + + def have_f77c(self): + """Check for availability of Fortran 77 compiler. + + Use it inside source generating function to ensure that + setup distribution instance has been initialized. + + Notes + ----- + True if a Fortran 77 compiler is available (because a simple Fortran 77 + code was able to be compiled successfully). + """ + simple_fortran_subroutine = ''' + subroutine simple + end + ''' + config_cmd = self.get_config_cmd() + flag = config_cmd.try_compile(simple_fortran_subroutine, lang='f77') + return flag + + def have_f90c(self): + """Check for availability of Fortran 90 compiler. + + Use it inside source generating function to ensure that + setup distribution instance has been initialized. + + Notes + ----- + True if a Fortran 90 compiler is available (because a simple Fortran + 90 code was able to be compiled successfully) + """ + simple_fortran_subroutine = ''' + subroutine simple + end + ''' + config_cmd = self.get_config_cmd() + flag = config_cmd.try_compile(simple_fortran_subroutine, lang='f90') + return flag + + def append_to(self, extlib): + """Append libraries, include_dirs to extension or library item. + """ + if is_sequence(extlib): + lib_name, build_info = extlib + dict_append(build_info, + libraries=self.libraries, + include_dirs=self.include_dirs) + else: + from numpy.distutils.core import Extension + assert isinstance(extlib, Extension), repr(extlib) + extlib.libraries.extend(self.libraries) + extlib.include_dirs.extend(self.include_dirs) + + def _get_svn_revision(self, path): + """Return path's SVN revision number. + """ + try: + output = subprocess.check_output(['svnversion'], cwd=path) + except (subprocess.CalledProcessError, OSError): + pass + else: + m = re.match(rb'(?P\d+)', output) + if m: + return int(m.group('revision')) + + if sys.platform=='win32' and os.environ.get('SVN_ASP_DOT_NET_HACK', None): + entries = njoin(path, '_svn', 'entries') + else: + entries = njoin(path, '.svn', 'entries') + if os.path.isfile(entries): + with open(entries) as f: + fstr = f.read() + if fstr[:5] == '\d+)"', fstr) + if m: + return int(m.group('revision')) + else: # non-xml entries file --- check to be sure that + m = re.search(r'dir[\n\r]+(?P\d+)', fstr) + if m: + return int(m.group('revision')) + return None + + def _get_hg_revision(self, path): + """Return path's Mercurial revision number. + """ + try: + output = subprocess.check_output( + ['hg', 'identify', '--num'], cwd=path) + except (subprocess.CalledProcessError, OSError): + pass + else: + m = re.match(rb'(?P\d+)', output) + if m: + return int(m.group('revision')) + + branch_fn = njoin(path, '.hg', 'branch') + branch_cache_fn = njoin(path, '.hg', 'branch.cache') + + if os.path.isfile(branch_fn): + branch0 = None + with open(branch_fn) as f: + revision0 = f.read().strip() + + branch_map = {} + with open(branch_cache_fn, 'r') as f: + for line in f: + branch1, revision1 = line.split()[:2] + if revision1==revision0: + branch0 = branch1 + try: + revision1 = int(revision1) + except ValueError: + continue + branch_map[branch1] = revision1 + + return branch_map.get(branch0) + + return None + + + def get_version(self, version_file=None, version_variable=None): + """Try to get version string of a package. + + Return a version string of the current package or None if the version + information could not be detected. + + Notes + ----- + This method scans files named + __version__.py, _version.py, version.py, and + __svn_version__.py for string variables version, __version__, and + _version, until a version number is found. + """ + version = getattr(self, 'version', None) + if version is not None: + return version + + # Get version from version file. + if version_file is None: + files = ['__version__.py', + self.name.split('.')[-1]+'_version.py', + 'version.py', + '__svn_version__.py', + '__hg_version__.py'] + else: + files = [version_file] + if version_variable is None: + version_vars = ['version', + '__version__', + self.name.split('.')[-1]+'_version'] + else: + version_vars = [version_variable] + for f in files: + fn = njoin(self.local_path, f) + if os.path.isfile(fn): + info = ('.py', 'U', 1) + name = os.path.splitext(os.path.basename(fn))[0] + n = dot_join(self.name, name) + try: + version_module = npy_load_module('_'.join(n.split('.')), + fn, info) + except ImportError as e: + self.warn(str(e)) + version_module = None + if version_module is None: + continue + + for a in version_vars: + version = getattr(version_module, a, None) + if version is not None: + break + if version is not None: + break + + if version is not None: + self.version = version + return version + + # Get version as SVN or Mercurial revision number + revision = self._get_svn_revision(self.local_path) + if revision is None: + revision = self._get_hg_revision(self.local_path) + + if revision is not None: + version = str(revision) + self.version = version + + return version + + def make_svn_version_py(self, delete=True): + """Appends a data function to the data_files list that will generate + __svn_version__.py file to the current package directory. + + Generate package __svn_version__.py file from SVN revision number, + it will be removed after python exits but will be available + when sdist, etc commands are executed. + + Notes + ----- + If __svn_version__.py existed before, nothing is done. + + This is + intended for working with source directories that are in an SVN + repository. + """ + target = njoin(self.local_path, '__svn_version__.py') + revision = self._get_svn_revision(self.local_path) + if os.path.isfile(target) or revision is None: + return + else: + def generate_svn_version_py(): + if not os.path.isfile(target): + version = str(revision) + self.info('Creating %s (version=%r)' % (target, version)) + with open(target, 'w') as f: + f.write('version = %r\n' % (version)) + + def rm_file(f=target,p=self.info): + if delete: + try: os.remove(f); p('removed '+f) + except OSError: pass + try: os.remove(f+'c'); p('removed '+f+'c') + except OSError: pass + + atexit.register(rm_file) + + return target + + self.add_data_files(('', generate_svn_version_py())) + + def make_hg_version_py(self, delete=True): + """Appends a data function to the data_files list that will generate + __hg_version__.py file to the current package directory. + + Generate package __hg_version__.py file from Mercurial revision, + it will be removed after python exits but will be available + when sdist, etc commands are executed. + + Notes + ----- + If __hg_version__.py existed before, nothing is done. + + This is intended for working with source directories that are + in an Mercurial repository. + """ + target = njoin(self.local_path, '__hg_version__.py') + revision = self._get_hg_revision(self.local_path) + if os.path.isfile(target) or revision is None: + return + else: + def generate_hg_version_py(): + if not os.path.isfile(target): + version = str(revision) + self.info('Creating %s (version=%r)' % (target, version)) + with open(target, 'w') as f: + f.write('version = %r\n' % (version)) + + def rm_file(f=target,p=self.info): + if delete: + try: os.remove(f); p('removed '+f) + except OSError: pass + try: os.remove(f+'c'); p('removed '+f+'c') + except OSError: pass + + atexit.register(rm_file) + + return target + + self.add_data_files(('', generate_hg_version_py())) + + def make_config_py(self,name='__config__'): + """Generate package __config__.py file containing system_info + information used during building the package. + + This file is installed to the + package installation directory. + + """ + self.py_modules.append((self.name, name, generate_config_py)) + + def get_info(self,*names): + """Get resources information. + + Return information (from system_info.get_info) for all of the names in + the argument list in a single dictionary. + """ + from .system_info import get_info, dict_append + info_dict = {} + for a in names: + dict_append(info_dict,**get_info(a)) + return info_dict + + +def get_cmd(cmdname, _cache={}): + if cmdname not in _cache: + import distutils.core + dist = distutils.core._setup_distribution + if dist is None: + from distutils.errors import DistutilsInternalError + raise DistutilsInternalError( + 'setup distribution instance not initialized') + cmd = dist.get_command_obj(cmdname) + _cache[cmdname] = cmd + return _cache[cmdname] + +def get_numpy_include_dirs(): + # numpy_include_dirs are set by numpy/core/setup.py, otherwise [] + include_dirs = Configuration.numpy_include_dirs[:] + if not include_dirs: + import numpy + include_dirs = [ numpy.get_include() ] + # else running numpy/core/setup.py + return include_dirs + +def get_npy_pkg_dir(): + """Return the path where to find the npy-pkg-config directory. + + If the NPY_PKG_CONFIG_PATH environment variable is set, the value of that + is returned. Otherwise, a path inside the location of the numpy module is + returned. + + The NPY_PKG_CONFIG_PATH can be useful when cross-compiling, maintaining + customized npy-pkg-config .ini files for the cross-compilation + environment, and using them when cross-compiling. + + """ + d = os.environ.get('NPY_PKG_CONFIG_PATH') + if d is not None: + return d + spec = importlib.util.find_spec('numpy') + d = os.path.join(os.path.dirname(spec.origin), + 'core', 'lib', 'npy-pkg-config') + return d + +def get_pkg_info(pkgname, dirs=None): + """ + Return library info for the given package. + + Parameters + ---------- + pkgname : str + Name of the package (should match the name of the .ini file, without + the extension, e.g. foo for the file foo.ini). + dirs : sequence, optional + If given, should be a sequence of additional directories where to look + for npy-pkg-config files. Those directories are searched prior to the + NumPy directory. + + Returns + ------- + pkginfo : class instance + The `LibraryInfo` instance containing the build information. + + Raises + ------ + PkgNotFound + If the package is not found. + + See Also + -------- + Configuration.add_npy_pkg_config, Configuration.add_installed_library, + get_info + + """ + from numpy.distutils.npy_pkg_config import read_config + + if dirs: + dirs.append(get_npy_pkg_dir()) + else: + dirs = [get_npy_pkg_dir()] + return read_config(pkgname, dirs) + +def get_info(pkgname, dirs=None): + """ + Return an info dict for a given C library. + + The info dict contains the necessary options to use the C library. + + Parameters + ---------- + pkgname : str + Name of the package (should match the name of the .ini file, without + the extension, e.g. foo for the file foo.ini). + dirs : sequence, optional + If given, should be a sequence of additional directories where to look + for npy-pkg-config files. Those directories are searched prior to the + NumPy directory. + + Returns + ------- + info : dict + The dictionary with build information. + + Raises + ------ + PkgNotFound + If the package is not found. + + See Also + -------- + Configuration.add_npy_pkg_config, Configuration.add_installed_library, + get_pkg_info + + Examples + -------- + To get the necessary information for the npymath library from NumPy: + + >>> npymath_info = np.distutils.misc_util.get_info('npymath') + >>> npymath_info #doctest: +SKIP + {'define_macros': [], 'libraries': ['npymath'], 'library_dirs': + ['.../numpy/core/lib'], 'include_dirs': ['.../numpy/core/include']} + + This info dict can then be used as input to a `Configuration` instance:: + + config.add_extension('foo', sources=['foo.c'], extra_info=npymath_info) + + """ + from numpy.distutils.npy_pkg_config import parse_flags + pkg_info = get_pkg_info(pkgname, dirs) + + # Translate LibraryInfo instance into a build_info dict + info = parse_flags(pkg_info.cflags()) + for k, v in parse_flags(pkg_info.libs()).items(): + info[k].extend(v) + + # add_extension extra_info argument is ANAL + info['define_macros'] = info['macros'] + del info['macros'] + del info['ignored'] + + return info + +def is_bootstrapping(): + import builtins + + try: + builtins.__NUMPY_SETUP__ + return True + except AttributeError: + return False + + +######################### + +def default_config_dict(name = None, parent_name = None, local_path=None): + """Return a configuration dictionary for usage in + configuration() function defined in file setup_.py. + """ + import warnings + warnings.warn('Use Configuration(%r,%r,top_path=%r) instead of '\ + 'deprecated default_config_dict(%r,%r,%r)' + % (name, parent_name, local_path, + name, parent_name, local_path, + ), stacklevel=2) + c = Configuration(name, parent_name, local_path) + return c.todict() + + +def dict_append(d, **kws): + for k, v in kws.items(): + if k in d: + ov = d[k] + if isinstance(ov, str): + d[k] = v + else: + d[k].extend(v) + else: + d[k] = v + +def appendpath(prefix, path): + if os.path.sep != '/': + prefix = prefix.replace('/', os.path.sep) + path = path.replace('/', os.path.sep) + drive = '' + if os.path.isabs(path): + drive = os.path.splitdrive(prefix)[0] + absprefix = os.path.splitdrive(os.path.abspath(prefix))[1] + pathdrive, path = os.path.splitdrive(path) + d = os.path.commonprefix([absprefix, path]) + if os.path.join(absprefix[:len(d)], absprefix[len(d):]) != absprefix \ + or os.path.join(path[:len(d)], path[len(d):]) != path: + # Handle invalid paths + d = os.path.dirname(d) + subpath = path[len(d):] + if os.path.isabs(subpath): + subpath = subpath[1:] + else: + subpath = path + return os.path.normpath(njoin(drive + prefix, subpath)) + +def generate_config_py(target): + """Generate config.py file containing system_info information + used during building the package. + + Usage: + config['py_modules'].append((packagename, '__config__',generate_config_py)) + """ + from numpy.distutils.system_info import system_info + from distutils.dir_util import mkpath + mkpath(os.path.dirname(target)) + with open(target, 'w') as f: + f.write('# This file is generated by numpy\'s %s\n' % (os.path.basename(sys.argv[0]))) + f.write('# It contains system_info results at the time of building this package.\n') + f.write('__all__ = ["get_info","show"]\n\n') + + # For gfortran+msvc combination, extra shared libraries may exist + f.write(textwrap.dedent(""" + import os + import sys + + extra_dll_dir = os.path.join(os.path.dirname(__file__), '.libs') + + if sys.platform == 'win32' and os.path.isdir(extra_dll_dir): + if sys.version_info >= (3, 8): + os.add_dll_directory(extra_dll_dir) + else: + os.environ.setdefault('PATH', '') + os.environ['PATH'] += os.pathsep + extra_dll_dir + + """)) + + for k, i in system_info.saved_results.items(): + f.write('%s=%r\n' % (k, i)) + f.write(textwrap.dedent(r''' + def get_info(name): + g = globals() + return g.get(name, g.get(name + "_info", {})) + + def show(): + """ + Show libraries in the system on which NumPy was built. + + Print information about various resources (libraries, library + directories, include directories, etc.) in the system on which + NumPy was built. + + See Also + -------- + get_include : Returns the directory containing NumPy C + header files. + + Notes + ----- + Classes specifying the information to be printed are defined + in the `numpy.distutils.system_info` module. + + Information may include: + + * ``language``: language used to write the libraries (mostly + C or f77) + * ``libraries``: names of libraries found in the system + * ``library_dirs``: directories containing the libraries + * ``include_dirs``: directories containing library header files + * ``src_dirs``: directories containing library source files + * ``define_macros``: preprocessor macros used by + ``distutils.setup`` + + Examples + -------- + >>> import numpy as np + >>> np.show_config() + blas_opt_info: + language = c + define_macros = [('HAVE_CBLAS', None)] + libraries = ['openblas', 'openblas'] + library_dirs = ['/usr/local/lib'] + """ + for name,info_dict in globals().items(): + if name[0] == "_" or type(info_dict) is not type({}): continue + print(name + ":") + if not info_dict: + print(" NOT AVAILABLE") + for k,v in info_dict.items(): + v = str(v) + if k == "sources" and len(v) > 200: + v = v[:60] + " ...\n... " + v[-60:] + print(" %s = %s" % (k,v)) + ''')) + + return target + +def msvc_version(compiler): + """Return version major and minor of compiler instance if it is + MSVC, raise an exception otherwise.""" + if not compiler.compiler_type == "msvc": + raise ValueError("Compiler instance is not msvc (%s)"\ + % compiler.compiler_type) + return compiler._MSVCCompiler__version + +def get_build_architecture(): + # Importing distutils.msvccompiler triggers a warning on non-Windows + # systems, so delay the import to here. + from distutils.msvccompiler import get_build_architecture + return get_build_architecture() diff --git a/venv/Lib/site-packages/numpy/distutils/msvc9compiler.py b/venv/Lib/site-packages/numpy/distutils/msvc9compiler.py new file mode 100644 index 0000000..6823949 --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/msvc9compiler.py @@ -0,0 +1,63 @@ +import os +from distutils.msvc9compiler import MSVCCompiler as _MSVCCompiler + +from .system_info import platform_bits + + +def _merge(old, new): + """Concatenate two environment paths avoiding repeats. + + Here `old` is the environment string before the base class initialize + function is called and `new` is the string after the call. The new string + will be a fixed string if it is not obtained from the current environment, + or the same as the old string if obtained from the same environment. The aim + here is not to append the new string if it is already contained in the old + string so as to limit the growth of the environment string. + + Parameters + ---------- + old : string + Previous environment string. + new : string + New environment string. + + Returns + ------- + ret : string + Updated environment string. + + """ + if not old: + return new + if new in old: + return old + + # Neither new nor old is empty. Give old priority. + return ';'.join([old, new]) + + +class MSVCCompiler(_MSVCCompiler): + def __init__(self, verbose=0, dry_run=0, force=0): + _MSVCCompiler.__init__(self, verbose, dry_run, force) + + def initialize(self, plat_name=None): + # The 'lib' and 'include' variables may be overwritten + # by MSVCCompiler.initialize, so save them for later merge. + environ_lib = os.getenv('lib') + environ_include = os.getenv('include') + _MSVCCompiler.initialize(self, plat_name) + + # Merge current and previous values of 'lib' and 'include' + os.environ['lib'] = _merge(environ_lib, os.environ['lib']) + os.environ['include'] = _merge(environ_include, os.environ['include']) + + # msvc9 building for 32 bits requires SSE2 to work around a + # compiler bug. + if platform_bits == 32: + self.compile_options += ['/arch:SSE2'] + self.compile_options_debug += ['/arch:SSE2'] + + def manifest_setup_ldargs(self, output_filename, build_temp, ld_args): + ld_args.append('/MANIFEST') + _MSVCCompiler.manifest_setup_ldargs(self, output_filename, + build_temp, ld_args) diff --git a/venv/Lib/site-packages/numpy/distutils/msvccompiler.py b/venv/Lib/site-packages/numpy/distutils/msvccompiler.py new file mode 100644 index 0000000..681a254 --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/msvccompiler.py @@ -0,0 +1,58 @@ +import os +from distutils.msvccompiler import MSVCCompiler as _MSVCCompiler + +from .system_info import platform_bits + + +def _merge(old, new): + """Concatenate two environment paths avoiding repeats. + + Here `old` is the environment string before the base class initialize + function is called and `new` is the string after the call. The new string + will be a fixed string if it is not obtained from the current environment, + or the same as the old string if obtained from the same environment. The aim + here is not to append the new string if it is already contained in the old + string so as to limit the growth of the environment string. + + Parameters + ---------- + old : string + Previous environment string. + new : string + New environment string. + + Returns + ------- + ret : string + Updated environment string. + + """ + if new in old: + return old + if not old: + return new + + # Neither new nor old is empty. Give old priority. + return ';'.join([old, new]) + + +class MSVCCompiler(_MSVCCompiler): + def __init__(self, verbose=0, dry_run=0, force=0): + _MSVCCompiler.__init__(self, verbose, dry_run, force) + + def initialize(self): + # The 'lib' and 'include' variables may be overwritten + # by MSVCCompiler.initialize, so save them for later merge. + environ_lib = os.getenv('lib', '') + environ_include = os.getenv('include', '') + _MSVCCompiler.initialize(self) + + # Merge current and previous values of 'lib' and 'include' + os.environ['lib'] = _merge(environ_lib, os.environ['lib']) + os.environ['include'] = _merge(environ_include, os.environ['include']) + + # msvc9 building for 32 bits requires SSE2 to work around a + # compiler bug. + if platform_bits == 32: + self.compile_options += ['/arch:SSE2'] + self.compile_options_debug += ['/arch:SSE2'] diff --git a/venv/Lib/site-packages/numpy/distutils/npy_pkg_config.py b/venv/Lib/site-packages/numpy/distutils/npy_pkg_config.py new file mode 100644 index 0000000..951ce5f --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/npy_pkg_config.py @@ -0,0 +1,437 @@ +import sys +import re +import os + +from configparser import RawConfigParser + +__all__ = ['FormatError', 'PkgNotFound', 'LibraryInfo', 'VariableSet', + 'read_config', 'parse_flags'] + +_VAR = re.compile(r'\$\{([a-zA-Z0-9_-]+)\}') + +class FormatError(IOError): + """ + Exception thrown when there is a problem parsing a configuration file. + + """ + def __init__(self, msg): + self.msg = msg + + def __str__(self): + return self.msg + +class PkgNotFound(IOError): + """Exception raised when a package can not be located.""" + def __init__(self, msg): + self.msg = msg + + def __str__(self): + return self.msg + +def parse_flags(line): + """ + Parse a line from a config file containing compile flags. + + Parameters + ---------- + line : str + A single line containing one or more compile flags. + + Returns + ------- + d : dict + Dictionary of parsed flags, split into relevant categories. + These categories are the keys of `d`: + + * 'include_dirs' + * 'library_dirs' + * 'libraries' + * 'macros' + * 'ignored' + + """ + d = {'include_dirs': [], 'library_dirs': [], 'libraries': [], + 'macros': [], 'ignored': []} + + flags = (' ' + line).split(' -') + for flag in flags: + flag = '-' + flag + if len(flag) > 0: + if flag.startswith('-I'): + d['include_dirs'].append(flag[2:].strip()) + elif flag.startswith('-L'): + d['library_dirs'].append(flag[2:].strip()) + elif flag.startswith('-l'): + d['libraries'].append(flag[2:].strip()) + elif flag.startswith('-D'): + d['macros'].append(flag[2:].strip()) + else: + d['ignored'].append(flag) + + return d + +def _escape_backslash(val): + return val.replace('\\', '\\\\') + +class LibraryInfo: + """ + Object containing build information about a library. + + Parameters + ---------- + name : str + The library name. + description : str + Description of the library. + version : str + Version string. + sections : dict + The sections of the configuration file for the library. The keys are + the section headers, the values the text under each header. + vars : class instance + A `VariableSet` instance, which contains ``(name, value)`` pairs for + variables defined in the configuration file for the library. + requires : sequence, optional + The required libraries for the library to be installed. + + Notes + ----- + All input parameters (except "sections" which is a method) are available as + attributes of the same name. + + """ + def __init__(self, name, description, version, sections, vars, requires=None): + self.name = name + self.description = description + if requires: + self.requires = requires + else: + self.requires = [] + self.version = version + self._sections = sections + self.vars = vars + + def sections(self): + """ + Return the section headers of the config file. + + Parameters + ---------- + None + + Returns + ------- + keys : list of str + The list of section headers. + + """ + return list(self._sections.keys()) + + def cflags(self, section="default"): + val = self.vars.interpolate(self._sections[section]['cflags']) + return _escape_backslash(val) + + def libs(self, section="default"): + val = self.vars.interpolate(self._sections[section]['libs']) + return _escape_backslash(val) + + def __str__(self): + m = ['Name: %s' % self.name, 'Description: %s' % self.description] + if self.requires: + m.append('Requires:') + else: + m.append('Requires: %s' % ",".join(self.requires)) + m.append('Version: %s' % self.version) + + return "\n".join(m) + +class VariableSet: + """ + Container object for the variables defined in a config file. + + `VariableSet` can be used as a plain dictionary, with the variable names + as keys. + + Parameters + ---------- + d : dict + Dict of items in the "variables" section of the configuration file. + + """ + def __init__(self, d): + self._raw_data = dict([(k, v) for k, v in d.items()]) + + self._re = {} + self._re_sub = {} + + self._init_parse() + + def _init_parse(self): + for k, v in self._raw_data.items(): + self._init_parse_var(k, v) + + def _init_parse_var(self, name, value): + self._re[name] = re.compile(r'\$\{%s\}' % name) + self._re_sub[name] = value + + def interpolate(self, value): + # Brute force: we keep interpolating until there is no '${var}' anymore + # or until interpolated string is equal to input string + def _interpolate(value): + for k in self._re.keys(): + value = self._re[k].sub(self._re_sub[k], value) + return value + while _VAR.search(value): + nvalue = _interpolate(value) + if nvalue == value: + break + value = nvalue + + return value + + def variables(self): + """ + Return the list of variable names. + + Parameters + ---------- + None + + Returns + ------- + names : list of str + The names of all variables in the `VariableSet` instance. + + """ + return list(self._raw_data.keys()) + + # Emulate a dict to set/get variables values + def __getitem__(self, name): + return self._raw_data[name] + + def __setitem__(self, name, value): + self._raw_data[name] = value + self._init_parse_var(name, value) + +def parse_meta(config): + if not config.has_section('meta'): + raise FormatError("No meta section found !") + + d = dict(config.items('meta')) + + for k in ['name', 'description', 'version']: + if not k in d: + raise FormatError("Option %s (section [meta]) is mandatory, " + "but not found" % k) + + if not 'requires' in d: + d['requires'] = [] + + return d + +def parse_variables(config): + if not config.has_section('variables'): + raise FormatError("No variables section found !") + + d = {} + + for name, value in config.items("variables"): + d[name] = value + + return VariableSet(d) + +def parse_sections(config): + return meta_d, r + +def pkg_to_filename(pkg_name): + return "%s.ini" % pkg_name + +def parse_config(filename, dirs=None): + if dirs: + filenames = [os.path.join(d, filename) for d in dirs] + else: + filenames = [filename] + + config = RawConfigParser() + + n = config.read(filenames) + if not len(n) >= 1: + raise PkgNotFound("Could not find file(s) %s" % str(filenames)) + + # Parse meta and variables sections + meta = parse_meta(config) + + vars = {} + if config.has_section('variables'): + for name, value in config.items("variables"): + vars[name] = _escape_backslash(value) + + # Parse "normal" sections + secs = [s for s in config.sections() if not s in ['meta', 'variables']] + sections = {} + + requires = {} + for s in secs: + d = {} + if config.has_option(s, "requires"): + requires[s] = config.get(s, 'requires') + + for name, value in config.items(s): + d[name] = value + sections[s] = d + + return meta, vars, sections, requires + +def _read_config_imp(filenames, dirs=None): + def _read_config(f): + meta, vars, sections, reqs = parse_config(f, dirs) + # recursively add sections and variables of required libraries + for rname, rvalue in reqs.items(): + nmeta, nvars, nsections, nreqs = _read_config(pkg_to_filename(rvalue)) + + # Update var dict for variables not in 'top' config file + for k, v in nvars.items(): + if not k in vars: + vars[k] = v + + # Update sec dict + for oname, ovalue in nsections[rname].items(): + if ovalue: + sections[rname][oname] += ' %s' % ovalue + + return meta, vars, sections, reqs + + meta, vars, sections, reqs = _read_config(filenames) + + # FIXME: document this. If pkgname is defined in the variables section, and + # there is no pkgdir variable defined, pkgdir is automatically defined to + # the path of pkgname. This requires the package to be imported to work + if not 'pkgdir' in vars and "pkgname" in vars: + pkgname = vars["pkgname"] + if not pkgname in sys.modules: + raise ValueError("You should import %s to get information on %s" % + (pkgname, meta["name"])) + + mod = sys.modules[pkgname] + vars["pkgdir"] = _escape_backslash(os.path.dirname(mod.__file__)) + + return LibraryInfo(name=meta["name"], description=meta["description"], + version=meta["version"], sections=sections, vars=VariableSet(vars)) + +# Trivial cache to cache LibraryInfo instances creation. To be really +# efficient, the cache should be handled in read_config, since a same file can +# be parsed many time outside LibraryInfo creation, but I doubt this will be a +# problem in practice +_CACHE = {} +def read_config(pkgname, dirs=None): + """ + Return library info for a package from its configuration file. + + Parameters + ---------- + pkgname : str + Name of the package (should match the name of the .ini file, without + the extension, e.g. foo for the file foo.ini). + dirs : sequence, optional + If given, should be a sequence of directories - usually including + the NumPy base directory - where to look for npy-pkg-config files. + + Returns + ------- + pkginfo : class instance + The `LibraryInfo` instance containing the build information. + + Raises + ------ + PkgNotFound + If the package is not found. + + See Also + -------- + misc_util.get_info, misc_util.get_pkg_info + + Examples + -------- + >>> npymath_info = np.distutils.npy_pkg_config.read_config('npymath') + >>> type(npymath_info) + + >>> print(npymath_info) + Name: npymath + Description: Portable, core math library implementing C99 standard + Requires: + Version: 0.1 #random + + """ + try: + return _CACHE[pkgname] + except KeyError: + v = _read_config_imp(pkg_to_filename(pkgname), dirs) + _CACHE[pkgname] = v + return v + +# TODO: +# - implements version comparison (modversion + atleast) + +# pkg-config simple emulator - useful for debugging, and maybe later to query +# the system +if __name__ == '__main__': + from optparse import OptionParser + import glob + + parser = OptionParser() + parser.add_option("--cflags", dest="cflags", action="store_true", + help="output all preprocessor and compiler flags") + parser.add_option("--libs", dest="libs", action="store_true", + help="output all linker flags") + parser.add_option("--use-section", dest="section", + help="use this section instead of default for options") + parser.add_option("--version", dest="version", action="store_true", + help="output version") + parser.add_option("--atleast-version", dest="min_version", + help="Minimal version") + parser.add_option("--list-all", dest="list_all", action="store_true", + help="Minimal version") + parser.add_option("--define-variable", dest="define_variable", + help="Replace variable with the given value") + + (options, args) = parser.parse_args(sys.argv) + + if len(args) < 2: + raise ValueError("Expect package name on the command line:") + + if options.list_all: + files = glob.glob("*.ini") + for f in files: + info = read_config(f) + print("%s\t%s - %s" % (info.name, info.name, info.description)) + + pkg_name = args[1] + d = os.environ.get('NPY_PKG_CONFIG_PATH') + if d: + info = read_config(pkg_name, ['numpy/core/lib/npy-pkg-config', '.', d]) + else: + info = read_config(pkg_name, ['numpy/core/lib/npy-pkg-config', '.']) + + if options.section: + section = options.section + else: + section = "default" + + if options.define_variable: + m = re.search(r'([\S]+)=([\S]+)', options.define_variable) + if not m: + raise ValueError("--define-variable option should be of " + "the form --define-variable=foo=bar") + else: + name = m.group(1) + value = m.group(2) + info.vars[name] = value + + if options.cflags: + print(info.cflags(section)) + if options.libs: + print(info.libs(section)) + if options.version: + print(info.version) + if options.min_version: + print(info.version >= options.min_version) diff --git a/venv/Lib/site-packages/numpy/distutils/numpy_distribution.py b/venv/Lib/site-packages/numpy/distutils/numpy_distribution.py new file mode 100644 index 0000000..ea81826 --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/numpy_distribution.py @@ -0,0 +1,17 @@ +# XXX: Handle setuptools ? +from distutils.core import Distribution + +# This class is used because we add new files (sconscripts, and so on) with the +# scons command +class NumpyDistribution(Distribution): + def __init__(self, attrs = None): + # A list of (sconscripts, pre_hook, post_hook, src, parent_names) + self.scons_data = [] + # A list of installable libraries + self.installed_libraries = [] + # A dict of pkg_config files to generate/install + self.installed_pkg_config = {} + Distribution.__init__(self, attrs) + + def has_scons_scripts(self): + return bool(self.scons_data) diff --git a/venv/Lib/site-packages/numpy/distutils/pathccompiler.py b/venv/Lib/site-packages/numpy/distutils/pathccompiler.py new file mode 100644 index 0000000..4805181 --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/pathccompiler.py @@ -0,0 +1,21 @@ +from distutils.unixccompiler import UnixCCompiler + +class PathScaleCCompiler(UnixCCompiler): + + """ + PathScale compiler compatible with an gcc built Python. + """ + + compiler_type = 'pathcc' + cc_exe = 'pathcc' + cxx_exe = 'pathCC' + + def __init__ (self, verbose=0, dry_run=0, force=0): + UnixCCompiler.__init__ (self, verbose, dry_run, force) + cc_compiler = self.cc_exe + cxx_compiler = self.cxx_exe + self.set_executables(compiler=cc_compiler, + compiler_so=cc_compiler, + compiler_cxx=cxx_compiler, + linker_exe=cc_compiler, + linker_so=cc_compiler + ' -shared') diff --git a/venv/Lib/site-packages/numpy/distutils/setup.py b/venv/Lib/site-packages/numpy/distutils/setup.py new file mode 100644 index 0000000..522756f --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/setup.py @@ -0,0 +1,17 @@ +#!/usr/bin/env python3 +def configuration(parent_package='',top_path=None): + from numpy.distutils.misc_util import Configuration + config = Configuration('distutils', parent_package, top_path) + config.add_subpackage('command') + config.add_subpackage('fcompiler') + config.add_subpackage('tests') + config.add_data_files('site.cfg') + config.add_data_files('mingw/gfortran_vs2003_hack.c') + config.add_data_dir('checks') + config.add_data_files('*.pyi') + config.make_config_py() + return config + +if __name__ == '__main__': + from numpy.distutils.core import setup + setup(configuration=configuration) diff --git a/venv/Lib/site-packages/numpy/distutils/system_info.py b/venv/Lib/site-packages/numpy/distutils/system_info.py new file mode 100644 index 0000000..13f9da0 --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/system_info.py @@ -0,0 +1,3080 @@ +#!/usr/bin/env python3 +""" +This file defines a set of system_info classes for getting +information about various resources (libraries, library directories, +include directories, etc.) in the system. Usage: + info_dict = get_info() + where is a string 'atlas','x11','fftw','lapack','blas', + 'lapack_src', 'blas_src', etc. For a complete list of allowed names, + see the definition of get_info() function below. + + Returned info_dict is a dictionary which is compatible with + distutils.setup keyword arguments. If info_dict == {}, then the + asked resource is not available (system_info could not find it). + + Several *_info classes specify an environment variable to specify + the locations of software. When setting the corresponding environment + variable to 'None' then the software will be ignored, even when it + is available in system. + +Global parameters: + system_info.search_static_first - search static libraries (.a) + in precedence to shared ones (.so, .sl) if enabled. + system_info.verbosity - output the results to stdout if enabled. + +The file 'site.cfg' is looked for in + +1) Directory of main setup.py file being run. +2) Home directory of user running the setup.py file as ~/.numpy-site.cfg +3) System wide directory (location of this file...) + +The first one found is used to get system configuration options The +format is that used by ConfigParser (i.e., Windows .INI style). The +section ALL is not intended for general use. + +Appropriate defaults are used if nothing is specified. + +The order of finding the locations of resources is the following: + 1. environment variable + 2. section in site.cfg + 3. DEFAULT section in site.cfg + 4. System default search paths (see ``default_*`` variables below). +Only the first complete match is returned. + +Currently, the following classes are available, along with their section names: + + Numeric_info:Numeric + _numpy_info:Numeric + _pkg_config_info:None + accelerate_info:accelerate + agg2_info:agg2 + amd_info:amd + atlas_3_10_blas_info:atlas + atlas_3_10_blas_threads_info:atlas + atlas_3_10_info:atlas + atlas_3_10_threads_info:atlas + atlas_blas_info:atlas + atlas_blas_threads_info:atlas + atlas_info:atlas + atlas_threads_info:atlas + blas64__opt_info:ALL # usage recommended (general ILP64 BLAS, 64_ symbol suffix) + blas_ilp64_opt_info:ALL # usage recommended (general ILP64 BLAS) + blas_ilp64_plain_opt_info:ALL # usage recommended (general ILP64 BLAS, no symbol suffix) + blas_info:blas + blas_mkl_info:mkl + blas_opt_info:ALL # usage recommended + blas_src_info:blas_src + blis_info:blis + boost_python_info:boost_python + dfftw_info:fftw + dfftw_threads_info:fftw + djbfft_info:djbfft + f2py_info:ALL + fft_opt_info:ALL + fftw2_info:fftw + fftw3_info:fftw3 + fftw_info:fftw + fftw_threads_info:fftw + flame_info:flame + freetype2_info:freetype2 + gdk_2_info:gdk_2 + gdk_info:gdk + gdk_pixbuf_2_info:gdk_pixbuf_2 + gdk_pixbuf_xlib_2_info:gdk_pixbuf_xlib_2 + gdk_x11_2_info:gdk_x11_2 + gtkp_2_info:gtkp_2 + gtkp_x11_2_info:gtkp_x11_2 + lapack64__opt_info:ALL # usage recommended (general ILP64 LAPACK, 64_ symbol suffix) + lapack_atlas_3_10_info:atlas + lapack_atlas_3_10_threads_info:atlas + lapack_atlas_info:atlas + lapack_atlas_threads_info:atlas + lapack_ilp64_opt_info:ALL # usage recommended (general ILP64 LAPACK) + lapack_ilp64_plain_opt_info:ALL # usage recommended (general ILP64 LAPACK, no symbol suffix) + lapack_info:lapack + lapack_mkl_info:mkl + lapack_opt_info:ALL # usage recommended + lapack_src_info:lapack_src + mkl_info:mkl + numarray_info:numarray + numerix_info:numerix + numpy_info:numpy + openblas64__info:openblas64_ + openblas64__lapack_info:openblas64_ + openblas_clapack_info:openblas + openblas_ilp64_info:openblas_ilp64 + openblas_ilp64_lapack_info:openblas_ilp64 + openblas_info:openblas + openblas_lapack_info:openblas + sfftw_info:fftw + sfftw_threads_info:fftw + system_info:ALL + umfpack_info:umfpack + wx_info:wx + x11_info:x11 + xft_info:xft + +Example: +---------- +[DEFAULT] +# default section +library_dirs = /usr/lib:/usr/local/lib:/opt/lib +include_dirs = /usr/include:/usr/local/include:/opt/include +src_dirs = /usr/local/src:/opt/src +# search static libraries (.a) in preference to shared ones (.so) +search_static_first = 0 + +[fftw] +libraries = rfftw, fftw + +[atlas] +library_dirs = /usr/lib/3dnow:/usr/lib/3dnow/atlas +# for overriding the names of the atlas libraries +libraries = lapack, f77blas, cblas, atlas + +[x11] +library_dirs = /usr/X11R6/lib +include_dirs = /usr/X11R6/include +---------- + +Note that the ``libraries`` key is the default setting for libraries. + +Authors: + Pearu Peterson , February 2002 + David M. Cooke , April 2002 + +Copyright 2002 Pearu Peterson all rights reserved, +Pearu Peterson +Permission to use, modify, and distribute this software is given under the +terms of the NumPy (BSD style) license. See LICENSE.txt that came with +this distribution for specifics. + +NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. + +""" +import sys +import os +import re +import copy +import warnings +import subprocess +import textwrap + +from glob import glob +from functools import reduce +from configparser import NoOptionError +from configparser import RawConfigParser as ConfigParser +# It seems that some people are importing ConfigParser from here so is +# good to keep its class name. Use of RawConfigParser is needed in +# order to be able to load path names with percent in them, like +# `feature%2Fcool` which is common on git flow branch names. + +from distutils.errors import DistutilsError +from distutils.dist import Distribution +import sysconfig +from numpy.distutils import log +from distutils.util import get_platform + +from numpy.distutils.exec_command import ( + find_executable, filepath_from_subprocess_output, + ) +from numpy.distutils.misc_util import (is_sequence, is_string, + get_shared_lib_extension) +from numpy.distutils.command.config import config as cmd_config +from numpy.distutils import customized_ccompiler as _customized_ccompiler +from numpy.distutils import _shell_utils +import distutils.ccompiler +import tempfile +import shutil + +__all__ = ['system_info'] + +# Determine number of bits +import platform +_bits = {'32bit': 32, '64bit': 64} +platform_bits = _bits[platform.architecture()[0]] + + +global_compiler = None + +def customized_ccompiler(): + global global_compiler + if not global_compiler: + global_compiler = _customized_ccompiler() + return global_compiler + + +def _c_string_literal(s): + """ + Convert a python string into a literal suitable for inclusion into C code + """ + # only these three characters are forbidden in C strings + s = s.replace('\\', r'\\') + s = s.replace('"', r'\"') + s = s.replace('\n', r'\n') + return '"{}"'.format(s) + + +def libpaths(paths, bits): + """Return a list of library paths valid on 32 or 64 bit systems. + + Inputs: + paths : sequence + A sequence of strings (typically paths) + bits : int + An integer, the only valid values are 32 or 64. A ValueError exception + is raised otherwise. + + Examples: + + Consider a list of directories + >>> paths = ['/usr/X11R6/lib','/usr/X11/lib','/usr/lib'] + + For a 32-bit platform, this is already valid: + >>> np.distutils.system_info.libpaths(paths,32) + ['/usr/X11R6/lib', '/usr/X11/lib', '/usr/lib'] + + On 64 bits, we prepend the '64' postfix + >>> np.distutils.system_info.libpaths(paths,64) + ['/usr/X11R6/lib64', '/usr/X11R6/lib', '/usr/X11/lib64', '/usr/X11/lib', + '/usr/lib64', '/usr/lib'] + """ + if bits not in (32, 64): + raise ValueError("Invalid bit size in libpaths: 32 or 64 only") + + # Handle 32bit case + if bits == 32: + return paths + + # Handle 64bit case + out = [] + for p in paths: + out.extend([p + '64', p]) + + return out + + +if sys.platform == 'win32': + default_lib_dirs = ['C:\\', + os.path.join(sysconfig.get_config_var('exec_prefix'), + 'libs')] + default_runtime_dirs = [] + default_include_dirs = [] + default_src_dirs = ['.'] + default_x11_lib_dirs = [] + default_x11_include_dirs = [] + _include_dirs = [ + 'include', + 'include/suitesparse', + ] + _lib_dirs = [ + 'lib', + ] + + _include_dirs = [d.replace('/', os.sep) for d in _include_dirs] + _lib_dirs = [d.replace('/', os.sep) for d in _lib_dirs] + def add_system_root(library_root): + """Add a package manager root to the include directories""" + global default_lib_dirs + global default_include_dirs + + library_root = os.path.normpath(library_root) + + default_lib_dirs.extend( + os.path.join(library_root, d) for d in _lib_dirs) + default_include_dirs.extend( + os.path.join(library_root, d) for d in _include_dirs) + + # VCpkg is the de-facto package manager on windows for C/C++ + # libraries. If it is on the PATH, then we append its paths here. + vcpkg = shutil.which('vcpkg') + if vcpkg: + vcpkg_dir = os.path.dirname(vcpkg) + if platform.architecture()[0] == '32bit': + specifier = 'x86' + else: + specifier = 'x64' + + vcpkg_installed = os.path.join(vcpkg_dir, 'installed') + for vcpkg_root in [ + os.path.join(vcpkg_installed, specifier + '-windows'), + os.path.join(vcpkg_installed, specifier + '-windows-static'), + ]: + add_system_root(vcpkg_root) + + # Conda is another popular package manager that provides libraries + conda = shutil.which('conda') + if conda: + conda_dir = os.path.dirname(conda) + add_system_root(os.path.join(conda_dir, '..', 'Library')) + add_system_root(os.path.join(conda_dir, 'Library')) + +else: + default_lib_dirs = libpaths(['/usr/local/lib', '/opt/lib', '/usr/lib', + '/opt/local/lib', '/sw/lib'], platform_bits) + default_runtime_dirs = [] + default_include_dirs = ['/usr/local/include', + '/opt/include', '/usr/include', + # path of umfpack under macports + '/opt/local/include/ufsparse', + '/opt/local/include', '/sw/include', + '/usr/include/suitesparse'] + default_src_dirs = ['.', '/usr/local/src', '/opt/src', '/sw/src'] + + default_x11_lib_dirs = libpaths(['/usr/X11R6/lib', '/usr/X11/lib', + '/usr/lib'], platform_bits) + default_x11_include_dirs = ['/usr/X11R6/include', '/usr/X11/include', + '/usr/include'] + + if os.path.exists('/usr/lib/X11'): + globbed_x11_dir = glob('/usr/lib/*/libX11.so') + if globbed_x11_dir: + x11_so_dir = os.path.split(globbed_x11_dir[0])[0] + default_x11_lib_dirs.extend([x11_so_dir, '/usr/lib/X11']) + default_x11_include_dirs.extend(['/usr/lib/X11/include', + '/usr/include/X11']) + + with open(os.devnull, 'w') as tmp: + try: + p = subprocess.Popen(["gcc", "-print-multiarch"], stdout=subprocess.PIPE, + stderr=tmp) + except (OSError, DistutilsError): + # OSError if gcc is not installed, or SandboxViolation (DistutilsError + # subclass) if an old setuptools bug is triggered (see gh-3160). + pass + else: + triplet = str(p.communicate()[0].decode().strip()) + if p.returncode == 0: + # gcc supports the "-print-multiarch" option + default_x11_lib_dirs += [os.path.join("/usr/lib/", triplet)] + default_lib_dirs += [os.path.join("/usr/lib/", triplet)] + + +if os.path.join(sys.prefix, 'lib') not in default_lib_dirs: + default_lib_dirs.insert(0, os.path.join(sys.prefix, 'lib')) + default_include_dirs.append(os.path.join(sys.prefix, 'include')) + default_src_dirs.append(os.path.join(sys.prefix, 'src')) + +default_lib_dirs = [_m for _m in default_lib_dirs if os.path.isdir(_m)] +default_runtime_dirs = [_m for _m in default_runtime_dirs if os.path.isdir(_m)] +default_include_dirs = [_m for _m in default_include_dirs if os.path.isdir(_m)] +default_src_dirs = [_m for _m in default_src_dirs if os.path.isdir(_m)] + +so_ext = get_shared_lib_extension() + + +def is_symlink_to_accelerate(filename): + accelpath = '/System/Library/Frameworks/Accelerate.framework' + return (sys.platform == 'darwin' and os.path.islink(filename) and + os.path.realpath(filename).startswith(accelpath)) + + +_accel_msg = ( + 'Found {filename}, but that file is a symbolic link to the ' + 'MacOS Accelerate framework, which is not supported by NumPy. ' + 'You must configure the build to use a different optimized library, ' + 'or disable the use of optimized BLAS and LAPACK by setting the ' + 'environment variables NPY_BLAS_ORDER="" and NPY_LAPACK_ORDER="" ' + 'before building NumPy.' +) + + +def get_standard_file(fname): + """Returns a list of files named 'fname' from + 1) System-wide directory (directory-location of this module) + 2) Users HOME directory (os.environ['HOME']) + 3) Local directory + """ + # System-wide file + filenames = [] + try: + f = __file__ + except NameError: + f = sys.argv[0] + else: + sysfile = os.path.join(os.path.split(os.path.abspath(f))[0], + fname) + if os.path.isfile(sysfile): + filenames.append(sysfile) + + # Home directory + # And look for the user config file + try: + f = os.path.expanduser('~') + except KeyError: + pass + else: + user_file = os.path.join(f, fname) + if os.path.isfile(user_file): + filenames.append(user_file) + + # Local file + if os.path.isfile(fname): + filenames.append(os.path.abspath(fname)) + + return filenames + + +def _parse_env_order(base_order, env): + """ Parse an environment variable `env` by splitting with "," and only returning elements from `base_order` + + This method will sequence the environment variable and check for their invidual elements in `base_order`. + + The items in the environment variable may be negated via '^item' or '!itema,itemb'. + It must start with ^/! to negate all options. + + Raises + ------ + ValueError: for mixed negated and non-negated orders or multiple negated orders + + Parameters + ---------- + base_order : list of str + the base list of orders + env : str + the environment variable to be parsed, if none is found, `base_order` is returned + + Returns + ------- + allow_order : list of str + allowed orders in lower-case + unknown_order : list of str + for values not overlapping with `base_order` + """ + order_str = os.environ.get(env, None) + + # ensure all base-orders are lower-case (for easier comparison) + base_order = [order.lower() for order in base_order] + if order_str is None: + return base_order, [] + + neg = order_str.startswith('^') or order_str.startswith('!') + # Check format + order_str_l = list(order_str) + sum_neg = order_str_l.count('^') + order_str_l.count('!') + if neg: + if sum_neg > 1: + raise ValueError(f"Environment variable '{env}' may only contain a single (prefixed) negation: {order_str}") + # remove prefix + order_str = order_str[1:] + elif sum_neg > 0: + raise ValueError(f"Environment variable '{env}' may not mix negated an non-negated items: {order_str}") + + # Split and lower case + orders = order_str.lower().split(',') + + # to inform callee about non-overlapping elements + unknown_order = [] + + # if negated, we have to remove from the order + if neg: + allow_order = base_order.copy() + + for order in orders: + if not order: + continue + + if order not in base_order: + unknown_order.append(order) + continue + + if order in allow_order: + allow_order.remove(order) + + else: + allow_order = [] + + for order in orders: + if not order: + continue + + if order not in base_order: + unknown_order.append(order) + continue + + if order not in allow_order: + allow_order.append(order) + + return allow_order, unknown_order + + +def get_info(name, notfound_action=0): + """ + notfound_action: + 0 - do nothing + 1 - display warning message + 2 - raise error + """ + cl = {'atlas': atlas_info, # use lapack_opt or blas_opt instead + 'atlas_threads': atlas_threads_info, # ditto + 'atlas_blas': atlas_blas_info, + 'atlas_blas_threads': atlas_blas_threads_info, + 'lapack_atlas': lapack_atlas_info, # use lapack_opt instead + 'lapack_atlas_threads': lapack_atlas_threads_info, # ditto + 'atlas_3_10': atlas_3_10_info, # use lapack_opt or blas_opt instead + 'atlas_3_10_threads': atlas_3_10_threads_info, # ditto + 'atlas_3_10_blas': atlas_3_10_blas_info, + 'atlas_3_10_blas_threads': atlas_3_10_blas_threads_info, + 'lapack_atlas_3_10': lapack_atlas_3_10_info, # use lapack_opt instead + 'lapack_atlas_3_10_threads': lapack_atlas_3_10_threads_info, # ditto + 'flame': flame_info, # use lapack_opt instead + 'mkl': mkl_info, + # openblas which may or may not have embedded lapack + 'openblas': openblas_info, # use blas_opt instead + # openblas with embedded lapack + 'openblas_lapack': openblas_lapack_info, # use blas_opt instead + 'openblas_clapack': openblas_clapack_info, # use blas_opt instead + 'blis': blis_info, # use blas_opt instead + 'lapack_mkl': lapack_mkl_info, # use lapack_opt instead + 'blas_mkl': blas_mkl_info, # use blas_opt instead + 'openblas64_': openblas64__info, + 'openblas64__lapack': openblas64__lapack_info, + 'openblas_ilp64': openblas_ilp64_info, + 'openblas_ilp64_lapack': openblas_ilp64_lapack_info, + 'x11': x11_info, + 'fft_opt': fft_opt_info, + 'fftw': fftw_info, + 'fftw2': fftw2_info, + 'fftw3': fftw3_info, + 'dfftw': dfftw_info, + 'sfftw': sfftw_info, + 'fftw_threads': fftw_threads_info, + 'dfftw_threads': dfftw_threads_info, + 'sfftw_threads': sfftw_threads_info, + 'djbfft': djbfft_info, + 'blas': blas_info, # use blas_opt instead + 'lapack': lapack_info, # use lapack_opt instead + 'lapack_src': lapack_src_info, + 'blas_src': blas_src_info, + 'numpy': numpy_info, + 'f2py': f2py_info, + 'Numeric': Numeric_info, + 'numeric': Numeric_info, + 'numarray': numarray_info, + 'numerix': numerix_info, + 'lapack_opt': lapack_opt_info, + 'lapack_ilp64_opt': lapack_ilp64_opt_info, + 'lapack_ilp64_plain_opt': lapack_ilp64_plain_opt_info, + 'lapack64__opt': lapack64__opt_info, + 'blas_opt': blas_opt_info, + 'blas_ilp64_opt': blas_ilp64_opt_info, + 'blas_ilp64_plain_opt': blas_ilp64_plain_opt_info, + 'blas64__opt': blas64__opt_info, + 'boost_python': boost_python_info, + 'agg2': agg2_info, + 'wx': wx_info, + 'gdk_pixbuf_xlib_2': gdk_pixbuf_xlib_2_info, + 'gdk-pixbuf-xlib-2.0': gdk_pixbuf_xlib_2_info, + 'gdk_pixbuf_2': gdk_pixbuf_2_info, + 'gdk-pixbuf-2.0': gdk_pixbuf_2_info, + 'gdk': gdk_info, + 'gdk_2': gdk_2_info, + 'gdk-2.0': gdk_2_info, + 'gdk_x11_2': gdk_x11_2_info, + 'gdk-x11-2.0': gdk_x11_2_info, + 'gtkp_x11_2': gtkp_x11_2_info, + 'gtk+-x11-2.0': gtkp_x11_2_info, + 'gtkp_2': gtkp_2_info, + 'gtk+-2.0': gtkp_2_info, + 'xft': xft_info, + 'freetype2': freetype2_info, + 'umfpack': umfpack_info, + 'amd': amd_info, + }.get(name.lower(), system_info) + return cl().get_info(notfound_action) + + +class NotFoundError(DistutilsError): + """Some third-party program or library is not found.""" + + +class AliasedOptionError(DistutilsError): + """ + Aliases entries in config files should not be existing. + In section '{section}' we found multiple appearances of options {options}.""" + + +class AtlasNotFoundError(NotFoundError): + """ + Atlas (http://github.com/math-atlas/math-atlas) libraries not found. + Directories to search for the libraries can be specified in the + numpy/distutils/site.cfg file (section [atlas]) or by setting + the ATLAS environment variable.""" + + +class FlameNotFoundError(NotFoundError): + """ + FLAME (http://www.cs.utexas.edu/~flame/web/) libraries not found. + Directories to search for the libraries can be specified in the + numpy/distutils/site.cfg file (section [flame]).""" + + +class LapackNotFoundError(NotFoundError): + """ + Lapack (http://www.netlib.org/lapack/) libraries not found. + Directories to search for the libraries can be specified in the + numpy/distutils/site.cfg file (section [lapack]) or by setting + the LAPACK environment variable.""" + + +class LapackSrcNotFoundError(LapackNotFoundError): + """ + Lapack (http://www.netlib.org/lapack/) sources not found. + Directories to search for the sources can be specified in the + numpy/distutils/site.cfg file (section [lapack_src]) or by setting + the LAPACK_SRC environment variable.""" + + +class LapackILP64NotFoundError(NotFoundError): + """ + 64-bit Lapack libraries not found. + Known libraries in numpy/distutils/site.cfg file are: + openblas64_, openblas_ilp64 + """ + +class BlasOptNotFoundError(NotFoundError): + """ + Optimized (vendor) Blas libraries are not found. + Falls back to netlib Blas library which has worse performance. + A better performance should be easily gained by switching + Blas library.""" + +class BlasNotFoundError(NotFoundError): + """ + Blas (http://www.netlib.org/blas/) libraries not found. + Directories to search for the libraries can be specified in the + numpy/distutils/site.cfg file (section [blas]) or by setting + the BLAS environment variable.""" + +class BlasILP64NotFoundError(NotFoundError): + """ + 64-bit Blas libraries not found. + Known libraries in numpy/distutils/site.cfg file are: + openblas64_, openblas_ilp64 + """ + +class BlasSrcNotFoundError(BlasNotFoundError): + """ + Blas (http://www.netlib.org/blas/) sources not found. + Directories to search for the sources can be specified in the + numpy/distutils/site.cfg file (section [blas_src]) or by setting + the BLAS_SRC environment variable.""" + + +class FFTWNotFoundError(NotFoundError): + """ + FFTW (http://www.fftw.org/) libraries not found. + Directories to search for the libraries can be specified in the + numpy/distutils/site.cfg file (section [fftw]) or by setting + the FFTW environment variable.""" + + +class DJBFFTNotFoundError(NotFoundError): + """ + DJBFFT (https://cr.yp.to/djbfft.html) libraries not found. + Directories to search for the libraries can be specified in the + numpy/distutils/site.cfg file (section [djbfft]) or by setting + the DJBFFT environment variable.""" + + +class NumericNotFoundError(NotFoundError): + """ + Numeric (https://www.numpy.org/) module not found. + Get it from above location, install it, and retry setup.py.""" + + +class X11NotFoundError(NotFoundError): + """X11 libraries not found.""" + + +class UmfpackNotFoundError(NotFoundError): + """ + UMFPACK sparse solver (https://www.cise.ufl.edu/research/sparse/umfpack/) + not found. Directories to search for the libraries can be specified in the + numpy/distutils/site.cfg file (section [umfpack]) or by setting + the UMFPACK environment variable.""" + + +class system_info: + + """ get_info() is the only public method. Don't use others. + """ + dir_env_var = None + # XXX: search_static_first is disabled by default, may disappear in + # future unless it is proved to be useful. + search_static_first = 0 + # The base-class section name is a random word "ALL" and is not really + # intended for general use. It cannot be None nor can it be DEFAULT as + # these break the ConfigParser. See gh-15338 + section = 'ALL' + saved_results = {} + + notfounderror = NotFoundError + + def __init__(self, + default_lib_dirs=default_lib_dirs, + default_include_dirs=default_include_dirs, + ): + self.__class__.info = {} + self.local_prefixes = [] + defaults = {'library_dirs': os.pathsep.join(default_lib_dirs), + 'include_dirs': os.pathsep.join(default_include_dirs), + 'runtime_library_dirs': os.pathsep.join(default_runtime_dirs), + 'rpath': '', + 'src_dirs': os.pathsep.join(default_src_dirs), + 'search_static_first': str(self.search_static_first), + 'extra_compile_args': '', 'extra_link_args': ''} + self.cp = ConfigParser(defaults) + self.files = [] + self.files.extend(get_standard_file('.numpy-site.cfg')) + self.files.extend(get_standard_file('site.cfg')) + self.parse_config_files() + + if self.section is not None: + self.search_static_first = self.cp.getboolean( + self.section, 'search_static_first') + assert isinstance(self.search_static_first, int) + + def parse_config_files(self): + self.cp.read(self.files) + if not self.cp.has_section(self.section): + if self.section is not None: + self.cp.add_section(self.section) + + def calc_libraries_info(self): + libs = self.get_libraries() + dirs = self.get_lib_dirs() + # The extensions use runtime_library_dirs + r_dirs = self.get_runtime_lib_dirs() + # Intrinsic distutils use rpath, we simply append both entries + # as though they were one entry + r_dirs.extend(self.get_runtime_lib_dirs(key='rpath')) + info = {} + for lib in libs: + i = self.check_libs(dirs, [lib]) + if i is not None: + dict_append(info, **i) + else: + log.info('Library %s was not found. Ignoring' % (lib)) + + if r_dirs: + i = self.check_libs(r_dirs, [lib]) + if i is not None: + # Swap library keywords found to runtime_library_dirs + # the libraries are insisting on the user having defined + # them using the library_dirs, and not necessarily by + # runtime_library_dirs + del i['libraries'] + i['runtime_library_dirs'] = i.pop('library_dirs') + dict_append(info, **i) + else: + log.info('Runtime library %s was not found. Ignoring' % (lib)) + + return info + + def set_info(self, **info): + if info: + lib_info = self.calc_libraries_info() + dict_append(info, **lib_info) + # Update extra information + extra_info = self.calc_extra_info() + dict_append(info, **extra_info) + self.saved_results[self.__class__.__name__] = info + + def get_option_single(self, *options): + """ Ensure that only one of `options` are found in the section + + Parameters + ---------- + *options : list of str + a list of options to be found in the section (``self.section``) + + Returns + ------- + str : + the option that is uniquely found in the section + + Raises + ------ + AliasedOptionError : + in case more than one of the options are found + """ + found = [self.cp.has_option(self.section, opt) for opt in options] + if sum(found) == 1: + return options[found.index(True)] + elif sum(found) == 0: + # nothing is found anyways + return options[0] + + # Else we have more than 1 key found + if AliasedOptionError.__doc__ is None: + raise AliasedOptionError() + raise AliasedOptionError(AliasedOptionError.__doc__.format( + section=self.section, options='[{}]'.format(', '.join(options)))) + + + def has_info(self): + return self.__class__.__name__ in self.saved_results + + def calc_extra_info(self): + """ Updates the information in the current information with + respect to these flags: + extra_compile_args + extra_link_args + """ + info = {} + for key in ['extra_compile_args', 'extra_link_args']: + # Get values + opt = self.cp.get(self.section, key) + opt = _shell_utils.NativeParser.split(opt) + if opt: + tmp = {key: opt} + dict_append(info, **tmp) + return info + + def get_info(self, notfound_action=0): + """ Return a dictionary with items that are compatible + with numpy.distutils.setup keyword arguments. + """ + flag = 0 + if not self.has_info(): + flag = 1 + log.info(self.__class__.__name__ + ':') + if hasattr(self, 'calc_info'): + self.calc_info() + if notfound_action: + if not self.has_info(): + if notfound_action == 1: + warnings.warn(self.notfounderror.__doc__, stacklevel=2) + elif notfound_action == 2: + raise self.notfounderror(self.notfounderror.__doc__) + else: + raise ValueError(repr(notfound_action)) + + if not self.has_info(): + log.info(' NOT AVAILABLE') + self.set_info() + else: + log.info(' FOUND:') + + res = self.saved_results.get(self.__class__.__name__) + if log.get_threshold() <= log.INFO and flag: + for k, v in res.items(): + v = str(v) + if k in ['sources', 'libraries'] and len(v) > 270: + v = v[:120] + '...\n...\n...' + v[-120:] + log.info(' %s = %s', k, v) + log.info('') + + return copy.deepcopy(res) + + def get_paths(self, section, key): + dirs = self.cp.get(section, key).split(os.pathsep) + env_var = self.dir_env_var + if env_var: + if is_sequence(env_var): + e0 = env_var[-1] + for e in env_var: + if e in os.environ: + e0 = e + break + if not env_var[0] == e0: + log.info('Setting %s=%s' % (env_var[0], e0)) + env_var = e0 + if env_var and env_var in os.environ: + d = os.environ[env_var] + if d == 'None': + log.info('Disabled %s: %s', + self.__class__.__name__, '(%s is None)' + % (env_var,)) + return [] + if os.path.isfile(d): + dirs = [os.path.dirname(d)] + dirs + l = getattr(self, '_lib_names', []) + if len(l) == 1: + b = os.path.basename(d) + b = os.path.splitext(b)[0] + if b[:3] == 'lib': + log.info('Replacing _lib_names[0]==%r with %r' \ + % (self._lib_names[0], b[3:])) + self._lib_names[0] = b[3:] + else: + ds = d.split(os.pathsep) + ds2 = [] + for d in ds: + if os.path.isdir(d): + ds2.append(d) + for dd in ['include', 'lib']: + d1 = os.path.join(d, dd) + if os.path.isdir(d1): + ds2.append(d1) + dirs = ds2 + dirs + default_dirs = self.cp.get(self.section, key).split(os.pathsep) + dirs.extend(default_dirs) + ret = [] + for d in dirs: + if len(d) > 0 and not os.path.isdir(d): + warnings.warn('Specified path %s is invalid.' % d, stacklevel=2) + continue + + if d not in ret: + ret.append(d) + + log.debug('( %s = %s )', key, ':'.join(ret)) + return ret + + def get_lib_dirs(self, key='library_dirs'): + return self.get_paths(self.section, key) + + def get_runtime_lib_dirs(self, key='runtime_library_dirs'): + path = self.get_paths(self.section, key) + if path == ['']: + path = [] + return path + + def get_include_dirs(self, key='include_dirs'): + return self.get_paths(self.section, key) + + def get_src_dirs(self, key='src_dirs'): + return self.get_paths(self.section, key) + + def get_libs(self, key, default): + try: + libs = self.cp.get(self.section, key) + except NoOptionError: + if not default: + return [] + if is_string(default): + return [default] + return default + return [b for b in [a.strip() for a in libs.split(',')] if b] + + def get_libraries(self, key='libraries'): + if hasattr(self, '_lib_names'): + return self.get_libs(key, default=self._lib_names) + else: + return self.get_libs(key, '') + + def library_extensions(self): + c = customized_ccompiler() + static_exts = [] + if c.compiler_type != 'msvc': + # MSVC doesn't understand binutils + static_exts.append('.a') + if sys.platform == 'win32': + static_exts.append('.lib') # .lib is used by MSVC and others + if self.search_static_first: + exts = static_exts + [so_ext] + else: + exts = [so_ext] + static_exts + if sys.platform == 'cygwin': + exts.append('.dll.a') + if sys.platform == 'darwin': + exts.append('.dylib') + return exts + + def check_libs(self, lib_dirs, libs, opt_libs=[]): + """If static or shared libraries are available then return + their info dictionary. + + Checks for all libraries as shared libraries first, then + static (or vice versa if self.search_static_first is True). + """ + exts = self.library_extensions() + info = None + for ext in exts: + info = self._check_libs(lib_dirs, libs, opt_libs, [ext]) + if info is not None: + break + if not info: + log.info(' libraries %s not found in %s', ','.join(libs), + lib_dirs) + return info + + def check_libs2(self, lib_dirs, libs, opt_libs=[]): + """If static or shared libraries are available then return + their info dictionary. + + Checks each library for shared or static. + """ + exts = self.library_extensions() + info = self._check_libs(lib_dirs, libs, opt_libs, exts) + if not info: + log.info(' libraries %s not found in %s', ','.join(libs), + lib_dirs) + + return info + + def _find_lib(self, lib_dir, lib, exts): + assert is_string(lib_dir) + # under windows first try without 'lib' prefix + if sys.platform == 'win32': + lib_prefixes = ['', 'lib'] + else: + lib_prefixes = ['lib'] + # for each library name, see if we can find a file for it. + for ext in exts: + for prefix in lib_prefixes: + p = self.combine_paths(lib_dir, prefix + lib + ext) + if p: + # p[0] is the full path to the binary library file. + if is_symlink_to_accelerate(p[0]): + raise RuntimeError(_accel_msg.format(filename=p[0])) + break + if p: + assert len(p) == 1 + # ??? splitext on p[0] would do this for cygwin + # doesn't seem correct + if ext == '.dll.a': + lib += '.dll' + if ext == '.lib': + lib = prefix + lib + return lib + + return False + + def _find_libs(self, lib_dirs, libs, exts): + # make sure we preserve the order of libs, as it can be important + found_dirs, found_libs = [], [] + for lib in libs: + for lib_dir in lib_dirs: + found_lib = self._find_lib(lib_dir, lib, exts) + if found_lib: + found_libs.append(found_lib) + if lib_dir not in found_dirs: + found_dirs.append(lib_dir) + break + return found_dirs, found_libs + + def _check_libs(self, lib_dirs, libs, opt_libs, exts): + """Find mandatory and optional libs in expected paths. + + Missing optional libraries are silently forgotten. + """ + if not is_sequence(lib_dirs): + lib_dirs = [lib_dirs] + # First, try to find the mandatory libraries + found_dirs, found_libs = self._find_libs(lib_dirs, libs, exts) + if len(found_libs) > 0 and len(found_libs) == len(libs): + # Now, check for optional libraries + opt_found_dirs, opt_found_libs = self._find_libs(lib_dirs, opt_libs, exts) + found_libs.extend(opt_found_libs) + for lib_dir in opt_found_dirs: + if lib_dir not in found_dirs: + found_dirs.append(lib_dir) + info = {'libraries': found_libs, 'library_dirs': found_dirs} + return info + else: + return None + + def combine_paths(self, *args): + """Return a list of existing paths composed by all combinations + of items from the arguments. + """ + return combine_paths(*args) + + +class fft_opt_info(system_info): + + def calc_info(self): + info = {} + fftw_info = get_info('fftw3') or get_info('fftw2') or get_info('dfftw') + djbfft_info = get_info('djbfft') + if fftw_info: + dict_append(info, **fftw_info) + if djbfft_info: + dict_append(info, **djbfft_info) + self.set_info(**info) + return + + +class fftw_info(system_info): + #variables to override + section = 'fftw' + dir_env_var = 'FFTW' + notfounderror = FFTWNotFoundError + ver_info = [{'name':'fftw3', + 'libs':['fftw3'], + 'includes':['fftw3.h'], + 'macros':[('SCIPY_FFTW3_H', None)]}, + {'name':'fftw2', + 'libs':['rfftw', 'fftw'], + 'includes':['fftw.h', 'rfftw.h'], + 'macros':[('SCIPY_FFTW_H', None)]}] + + def calc_ver_info(self, ver_param): + """Returns True on successful version detection, else False""" + lib_dirs = self.get_lib_dirs() + incl_dirs = self.get_include_dirs() + + opt = self.get_option_single(self.section + '_libs', 'libraries') + libs = self.get_libs(opt, ver_param['libs']) + info = self.check_libs(lib_dirs, libs) + if info is not None: + flag = 0 + for d in incl_dirs: + if len(self.combine_paths(d, ver_param['includes'])) \ + == len(ver_param['includes']): + dict_append(info, include_dirs=[d]) + flag = 1 + break + if flag: + dict_append(info, define_macros=ver_param['macros']) + else: + info = None + if info is not None: + self.set_info(**info) + return True + else: + log.info(' %s not found' % (ver_param['name'])) + return False + + def calc_info(self): + for i in self.ver_info: + if self.calc_ver_info(i): + break + + +class fftw2_info(fftw_info): + #variables to override + section = 'fftw' + dir_env_var = 'FFTW' + notfounderror = FFTWNotFoundError + ver_info = [{'name':'fftw2', + 'libs':['rfftw', 'fftw'], + 'includes':['fftw.h', 'rfftw.h'], + 'macros':[('SCIPY_FFTW_H', None)]} + ] + + +class fftw3_info(fftw_info): + #variables to override + section = 'fftw3' + dir_env_var = 'FFTW3' + notfounderror = FFTWNotFoundError + ver_info = [{'name':'fftw3', + 'libs':['fftw3'], + 'includes':['fftw3.h'], + 'macros':[('SCIPY_FFTW3_H', None)]}, + ] + + +class dfftw_info(fftw_info): + section = 'fftw' + dir_env_var = 'FFTW' + ver_info = [{'name':'dfftw', + 'libs':['drfftw', 'dfftw'], + 'includes':['dfftw.h', 'drfftw.h'], + 'macros':[('SCIPY_DFFTW_H', None)]}] + + +class sfftw_info(fftw_info): + section = 'fftw' + dir_env_var = 'FFTW' + ver_info = [{'name':'sfftw', + 'libs':['srfftw', 'sfftw'], + 'includes':['sfftw.h', 'srfftw.h'], + 'macros':[('SCIPY_SFFTW_H', None)]}] + + +class fftw_threads_info(fftw_info): + section = 'fftw' + dir_env_var = 'FFTW' + ver_info = [{'name':'fftw threads', + 'libs':['rfftw_threads', 'fftw_threads'], + 'includes':['fftw_threads.h', 'rfftw_threads.h'], + 'macros':[('SCIPY_FFTW_THREADS_H', None)]}] + + +class dfftw_threads_info(fftw_info): + section = 'fftw' + dir_env_var = 'FFTW' + ver_info = [{'name':'dfftw threads', + 'libs':['drfftw_threads', 'dfftw_threads'], + 'includes':['dfftw_threads.h', 'drfftw_threads.h'], + 'macros':[('SCIPY_DFFTW_THREADS_H', None)]}] + + +class sfftw_threads_info(fftw_info): + section = 'fftw' + dir_env_var = 'FFTW' + ver_info = [{'name':'sfftw threads', + 'libs':['srfftw_threads', 'sfftw_threads'], + 'includes':['sfftw_threads.h', 'srfftw_threads.h'], + 'macros':[('SCIPY_SFFTW_THREADS_H', None)]}] + + +class djbfft_info(system_info): + section = 'djbfft' + dir_env_var = 'DJBFFT' + notfounderror = DJBFFTNotFoundError + + def get_paths(self, section, key): + pre_dirs = system_info.get_paths(self, section, key) + dirs = [] + for d in pre_dirs: + dirs.extend(self.combine_paths(d, ['djbfft']) + [d]) + return [d for d in dirs if os.path.isdir(d)] + + def calc_info(self): + lib_dirs = self.get_lib_dirs() + incl_dirs = self.get_include_dirs() + info = None + for d in lib_dirs: + p = self.combine_paths(d, ['djbfft.a']) + if p: + info = {'extra_objects': p} + break + p = self.combine_paths(d, ['libdjbfft.a', 'libdjbfft' + so_ext]) + if p: + info = {'libraries': ['djbfft'], 'library_dirs': [d]} + break + if info is None: + return + for d in incl_dirs: + if len(self.combine_paths(d, ['fftc8.h', 'fftfreq.h'])) == 2: + dict_append(info, include_dirs=[d], + define_macros=[('SCIPY_DJBFFT_H', None)]) + self.set_info(**info) + return + return + + +class mkl_info(system_info): + section = 'mkl' + dir_env_var = 'MKLROOT' + _lib_mkl = ['mkl_rt'] + + def get_mkl_rootdir(self): + mklroot = os.environ.get('MKLROOT', None) + if mklroot is not None: + return mklroot + paths = os.environ.get('LD_LIBRARY_PATH', '').split(os.pathsep) + ld_so_conf = '/etc/ld.so.conf' + if os.path.isfile(ld_so_conf): + with open(ld_so_conf, 'r') as f: + for d in f: + d = d.strip() + if d: + paths.append(d) + intel_mkl_dirs = [] + for path in paths: + path_atoms = path.split(os.sep) + for m in path_atoms: + if m.startswith('mkl'): + d = os.sep.join(path_atoms[:path_atoms.index(m) + 2]) + intel_mkl_dirs.append(d) + break + for d in paths: + dirs = glob(os.path.join(d, 'mkl', '*')) + dirs += glob(os.path.join(d, 'mkl*')) + for sub_dir in dirs: + if os.path.isdir(os.path.join(sub_dir, 'lib')): + return sub_dir + return None + + def __init__(self): + mklroot = self.get_mkl_rootdir() + if mklroot is None: + system_info.__init__(self) + else: + from .cpuinfo import cpu + if cpu.is_Itanium(): + plt = '64' + elif cpu.is_Intel() and cpu.is_64bit(): + plt = 'intel64' + else: + plt = '32' + system_info.__init__( + self, + default_lib_dirs=[os.path.join(mklroot, 'lib', plt)], + default_include_dirs=[os.path.join(mklroot, 'include')]) + + def calc_info(self): + lib_dirs = self.get_lib_dirs() + incl_dirs = self.get_include_dirs() + opt = self.get_option_single('mkl_libs', 'libraries') + mkl_libs = self.get_libs(opt, self._lib_mkl) + info = self.check_libs2(lib_dirs, mkl_libs) + if info is None: + return + dict_append(info, + define_macros=[('SCIPY_MKL_H', None), + ('HAVE_CBLAS', None)], + include_dirs=incl_dirs) + if sys.platform == 'win32': + pass # win32 has no pthread library + else: + dict_append(info, libraries=['pthread']) + self.set_info(**info) + + +class lapack_mkl_info(mkl_info): + pass + + +class blas_mkl_info(mkl_info): + pass + + +class atlas_info(system_info): + section = 'atlas' + dir_env_var = 'ATLAS' + _lib_names = ['f77blas', 'cblas'] + if sys.platform[:7] == 'freebsd': + _lib_atlas = ['atlas_r'] + _lib_lapack = ['alapack_r'] + else: + _lib_atlas = ['atlas'] + _lib_lapack = ['lapack'] + + notfounderror = AtlasNotFoundError + + def get_paths(self, section, key): + pre_dirs = system_info.get_paths(self, section, key) + dirs = [] + for d in pre_dirs: + dirs.extend(self.combine_paths(d, ['atlas*', 'ATLAS*', + 'sse', '3dnow', 'sse2']) + [d]) + return [d for d in dirs if os.path.isdir(d)] + + def calc_info(self): + lib_dirs = self.get_lib_dirs() + info = {} + opt = self.get_option_single('atlas_libs', 'libraries') + atlas_libs = self.get_libs(opt, self._lib_names + self._lib_atlas) + lapack_libs = self.get_libs('lapack_libs', self._lib_lapack) + atlas = None + lapack = None + atlas_1 = None + for d in lib_dirs: + # FIXME: lapack_atlas is unused + lapack_atlas = self.check_libs2(d, ['lapack_atlas'], []) + atlas = self.check_libs2(d, atlas_libs, []) + if atlas is not None: + lib_dirs2 = [d] + self.combine_paths(d, ['atlas*', 'ATLAS*']) + lapack = self.check_libs2(lib_dirs2, lapack_libs, []) + if lapack is not None: + break + if atlas: + atlas_1 = atlas + log.info(self.__class__) + if atlas is None: + atlas = atlas_1 + if atlas is None: + return + include_dirs = self.get_include_dirs() + h = (self.combine_paths(lib_dirs + include_dirs, 'cblas.h') or [None]) + h = h[0] + if h: + h = os.path.dirname(h) + dict_append(info, include_dirs=[h]) + info['language'] = 'c' + if lapack is not None: + dict_append(info, **lapack) + dict_append(info, **atlas) + elif 'lapack_atlas' in atlas['libraries']: + dict_append(info, **atlas) + dict_append(info, + define_macros=[('ATLAS_WITH_LAPACK_ATLAS', None)]) + self.set_info(**info) + return + else: + dict_append(info, **atlas) + dict_append(info, define_macros=[('ATLAS_WITHOUT_LAPACK', None)]) + message = textwrap.dedent(""" + ********************************************************************* + Could not find lapack library within the ATLAS installation. + ********************************************************************* + """) + warnings.warn(message, stacklevel=2) + self.set_info(**info) + return + + # Check if lapack library is complete, only warn if it is not. + lapack_dir = lapack['library_dirs'][0] + lapack_name = lapack['libraries'][0] + lapack_lib = None + lib_prefixes = ['lib'] + if sys.platform == 'win32': + lib_prefixes.append('') + for e in self.library_extensions(): + for prefix in lib_prefixes: + fn = os.path.join(lapack_dir, prefix + lapack_name + e) + if os.path.exists(fn): + lapack_lib = fn + break + if lapack_lib: + break + if lapack_lib is not None: + sz = os.stat(lapack_lib)[6] + if sz <= 4000 * 1024: + message = textwrap.dedent(""" + ********************************************************************* + Lapack library (from ATLAS) is probably incomplete: + size of %s is %sk (expected >4000k) + + Follow the instructions in the KNOWN PROBLEMS section of the file + numpy/INSTALL.txt. + ********************************************************************* + """) % (lapack_lib, sz / 1024) + warnings.warn(message, stacklevel=2) + else: + info['language'] = 'f77' + + atlas_version, atlas_extra_info = get_atlas_version(**atlas) + dict_append(info, **atlas_extra_info) + + self.set_info(**info) + + +class atlas_blas_info(atlas_info): + _lib_names = ['f77blas', 'cblas'] + + def calc_info(self): + lib_dirs = self.get_lib_dirs() + info = {} + opt = self.get_option_single('atlas_libs', 'libraries') + atlas_libs = self.get_libs(opt, self._lib_names + self._lib_atlas) + atlas = self.check_libs2(lib_dirs, atlas_libs, []) + if atlas is None: + return + include_dirs = self.get_include_dirs() + h = (self.combine_paths(lib_dirs + include_dirs, 'cblas.h') or [None]) + h = h[0] + if h: + h = os.path.dirname(h) + dict_append(info, include_dirs=[h]) + info['language'] = 'c' + info['define_macros'] = [('HAVE_CBLAS', None)] + + atlas_version, atlas_extra_info = get_atlas_version(**atlas) + dict_append(atlas, **atlas_extra_info) + + dict_append(info, **atlas) + + self.set_info(**info) + return + + +class atlas_threads_info(atlas_info): + dir_env_var = ['PTATLAS', 'ATLAS'] + _lib_names = ['ptf77blas', 'ptcblas'] + + +class atlas_blas_threads_info(atlas_blas_info): + dir_env_var = ['PTATLAS', 'ATLAS'] + _lib_names = ['ptf77blas', 'ptcblas'] + + +class lapack_atlas_info(atlas_info): + _lib_names = ['lapack_atlas'] + atlas_info._lib_names + + +class lapack_atlas_threads_info(atlas_threads_info): + _lib_names = ['lapack_atlas'] + atlas_threads_info._lib_names + + +class atlas_3_10_info(atlas_info): + _lib_names = ['satlas'] + _lib_atlas = _lib_names + _lib_lapack = _lib_names + + +class atlas_3_10_blas_info(atlas_3_10_info): + _lib_names = ['satlas'] + + def calc_info(self): + lib_dirs = self.get_lib_dirs() + info = {} + opt = self.get_option_single('atlas_lib', 'libraries') + atlas_libs = self.get_libs(opt, self._lib_names) + atlas = self.check_libs2(lib_dirs, atlas_libs, []) + if atlas is None: + return + include_dirs = self.get_include_dirs() + h = (self.combine_paths(lib_dirs + include_dirs, 'cblas.h') or [None]) + h = h[0] + if h: + h = os.path.dirname(h) + dict_append(info, include_dirs=[h]) + info['language'] = 'c' + info['define_macros'] = [('HAVE_CBLAS', None)] + + atlas_version, atlas_extra_info = get_atlas_version(**atlas) + dict_append(atlas, **atlas_extra_info) + + dict_append(info, **atlas) + + self.set_info(**info) + return + + +class atlas_3_10_threads_info(atlas_3_10_info): + dir_env_var = ['PTATLAS', 'ATLAS'] + _lib_names = ['tatlas'] + _lib_atlas = _lib_names + _lib_lapack = _lib_names + + +class atlas_3_10_blas_threads_info(atlas_3_10_blas_info): + dir_env_var = ['PTATLAS', 'ATLAS'] + _lib_names = ['tatlas'] + + +class lapack_atlas_3_10_info(atlas_3_10_info): + pass + + +class lapack_atlas_3_10_threads_info(atlas_3_10_threads_info): + pass + + +class lapack_info(system_info): + section = 'lapack' + dir_env_var = 'LAPACK' + _lib_names = ['lapack'] + notfounderror = LapackNotFoundError + + def calc_info(self): + lib_dirs = self.get_lib_dirs() + + opt = self.get_option_single('lapack_libs', 'libraries') + lapack_libs = self.get_libs(opt, self._lib_names) + info = self.check_libs(lib_dirs, lapack_libs, []) + if info is None: + return + info['language'] = 'f77' + self.set_info(**info) + + +class lapack_src_info(system_info): + section = 'lapack_src' + dir_env_var = 'LAPACK_SRC' + notfounderror = LapackSrcNotFoundError + + def get_paths(self, section, key): + pre_dirs = system_info.get_paths(self, section, key) + dirs = [] + for d in pre_dirs: + dirs.extend([d] + self.combine_paths(d, ['LAPACK*/SRC', 'SRC'])) + return [d for d in dirs if os.path.isdir(d)] + + def calc_info(self): + src_dirs = self.get_src_dirs() + src_dir = '' + for d in src_dirs: + if os.path.isfile(os.path.join(d, 'dgesv.f')): + src_dir = d + break + if not src_dir: + #XXX: Get sources from netlib. May be ask first. + return + # The following is extracted from LAPACK-3.0/SRC/Makefile. + # Added missing names from lapack-lite-3.1.1/SRC/Makefile + # while keeping removed names for Lapack-3.0 compatibility. + allaux = ''' + ilaenv ieeeck lsame lsamen xerbla + iparmq + ''' # *.f + laux = ''' + bdsdc bdsqr disna labad lacpy ladiv lae2 laebz laed0 laed1 + laed2 laed3 laed4 laed5 laed6 laed7 laed8 laed9 laeda laev2 + lagtf lagts lamch lamrg lanst lapy2 lapy3 larnv larrb larre + larrf lartg laruv las2 lascl lasd0 lasd1 lasd2 lasd3 lasd4 + lasd5 lasd6 lasd7 lasd8 lasd9 lasda lasdq lasdt laset lasq1 + lasq2 lasq3 lasq4 lasq5 lasq6 lasr lasrt lassq lasv2 pttrf + stebz stedc steqr sterf + + larra larrc larrd larr larrk larrj larrr laneg laisnan isnan + lazq3 lazq4 + ''' # [s|d]*.f + lasrc = ''' + gbbrd gbcon gbequ gbrfs gbsv gbsvx gbtf2 gbtrf gbtrs gebak + gebal gebd2 gebrd gecon geequ gees geesx geev geevx gegs gegv + gehd2 gehrd gelq2 gelqf gels gelsd gelss gelsx gelsy geql2 + geqlf geqp3 geqpf geqr2 geqrf gerfs gerq2 gerqf gesc2 gesdd + gesv gesvd gesvx getc2 getf2 getrf getri getrs ggbak ggbal + gges ggesx ggev ggevx ggglm gghrd gglse ggqrf ggrqf ggsvd + ggsvp gtcon gtrfs gtsv gtsvx gttrf gttrs gtts2 hgeqz hsein + hseqr labrd lacon laein lags2 lagtm lahqr lahrd laic1 lals0 + lalsa lalsd langb lange langt lanhs lansb lansp lansy lantb + lantp lantr lapll lapmt laqgb laqge laqp2 laqps laqsb laqsp + laqsy lar1v lar2v larf larfb larfg larft larfx largv larrv + lartv larz larzb larzt laswp lasyf latbs latdf latps latrd + latrs latrz latzm lauu2 lauum pbcon pbequ pbrfs pbstf pbsv + pbsvx pbtf2 pbtrf pbtrs pocon poequ porfs posv posvx potf2 + potrf potri potrs ppcon ppequ pprfs ppsv ppsvx pptrf pptri + pptrs ptcon pteqr ptrfs ptsv ptsvx pttrs ptts2 spcon sprfs + spsv spsvx sptrf sptri sptrs stegr stein sycon syrfs sysv + sysvx sytf2 sytrf sytri sytrs tbcon tbrfs tbtrs tgevc tgex2 + tgexc tgsen tgsja tgsna tgsy2 tgsyl tpcon tprfs tptri tptrs + trcon trevc trexc trrfs trsen trsna trsyl trti2 trtri trtrs + tzrqf tzrzf + + lacn2 lahr2 stemr laqr0 laqr1 laqr2 laqr3 laqr4 laqr5 + ''' # [s|c|d|z]*.f + sd_lasrc = ''' + laexc lag2 lagv2 laln2 lanv2 laqtr lasy2 opgtr opmtr org2l + org2r orgbr orghr orgl2 orglq orgql orgqr orgr2 orgrq orgtr + orm2l orm2r ormbr ormhr orml2 ormlq ormql ormqr ormr2 ormr3 + ormrq ormrz ormtr rscl sbev sbevd sbevx sbgst sbgv sbgvd sbgvx + sbtrd spev spevd spevx spgst spgv spgvd spgvx sptrd stev stevd + stevr stevx syev syevd syevr syevx sygs2 sygst sygv sygvd + sygvx sytd2 sytrd + ''' # [s|d]*.f + cz_lasrc = ''' + bdsqr hbev hbevd hbevx hbgst hbgv hbgvd hbgvx hbtrd hecon heev + heevd heevr heevx hegs2 hegst hegv hegvd hegvx herfs hesv + hesvx hetd2 hetf2 hetrd hetrf hetri hetrs hpcon hpev hpevd + hpevx hpgst hpgv hpgvd hpgvx hprfs hpsv hpsvx hptrd hptrf + hptri hptrs lacgv lacp2 lacpy lacrm lacrt ladiv laed0 laed7 + laed8 laesy laev2 lahef lanhb lanhe lanhp lanht laqhb laqhe + laqhp larcm larnv lartg lascl laset lasr lassq pttrf rot spmv + spr stedc steqr symv syr ung2l ung2r ungbr unghr ungl2 unglq + ungql ungqr ungr2 ungrq ungtr unm2l unm2r unmbr unmhr unml2 + unmlq unmql unmqr unmr2 unmr3 unmrq unmrz unmtr upgtr upmtr + ''' # [c|z]*.f + ####### + sclaux = laux + ' econd ' # s*.f + dzlaux = laux + ' secnd ' # d*.f + slasrc = lasrc + sd_lasrc # s*.f + dlasrc = lasrc + sd_lasrc # d*.f + clasrc = lasrc + cz_lasrc + ' srot srscl ' # c*.f + zlasrc = lasrc + cz_lasrc + ' drot drscl ' # z*.f + oclasrc = ' icmax1 scsum1 ' # *.f + ozlasrc = ' izmax1 dzsum1 ' # *.f + sources = ['s%s.f' % f for f in (sclaux + slasrc).split()] \ + + ['d%s.f' % f for f in (dzlaux + dlasrc).split()] \ + + ['c%s.f' % f for f in (clasrc).split()] \ + + ['z%s.f' % f for f in (zlasrc).split()] \ + + ['%s.f' % f for f in (allaux + oclasrc + ozlasrc).split()] + sources = [os.path.join(src_dir, f) for f in sources] + # Lapack 3.1: + src_dir2 = os.path.join(src_dir, '..', 'INSTALL') + sources += [os.path.join(src_dir2, p + 'lamch.f') for p in 'sdcz'] + # Lapack 3.2.1: + sources += [os.path.join(src_dir, p + 'larfp.f') for p in 'sdcz'] + sources += [os.path.join(src_dir, 'ila' + p + 'lr.f') for p in 'sdcz'] + sources += [os.path.join(src_dir, 'ila' + p + 'lc.f') for p in 'sdcz'] + # Should we check here actual existence of source files? + # Yes, the file listing is different between 3.0 and 3.1 + # versions. + sources = [f for f in sources if os.path.isfile(f)] + info = {'sources': sources, 'language': 'f77'} + self.set_info(**info) + +atlas_version_c_text = r''' +/* This file is generated from numpy/distutils/system_info.py */ +void ATL_buildinfo(void); +int main(void) { + ATL_buildinfo(); + return 0; +} +''' + +_cached_atlas_version = {} + + +def get_atlas_version(**config): + libraries = config.get('libraries', []) + library_dirs = config.get('library_dirs', []) + key = (tuple(libraries), tuple(library_dirs)) + if key in _cached_atlas_version: + return _cached_atlas_version[key] + c = cmd_config(Distribution()) + atlas_version = None + info = {} + try: + s, o = c.get_output(atlas_version_c_text, + libraries=libraries, library_dirs=library_dirs, + ) + if s and re.search(r'undefined reference to `_gfortran', o, re.M): + s, o = c.get_output(atlas_version_c_text, + libraries=libraries + ['gfortran'], + library_dirs=library_dirs, + ) + if not s: + warnings.warn(textwrap.dedent(""" + ***************************************************** + Linkage with ATLAS requires gfortran. Use + + python setup.py config_fc --fcompiler=gnu95 ... + + when building extension libraries that use ATLAS. + Make sure that -lgfortran is used for C++ extensions. + ***************************************************** + """), stacklevel=2) + dict_append(info, language='f90', + define_macros=[('ATLAS_REQUIRES_GFORTRAN', None)]) + except Exception: # failed to get version from file -- maybe on Windows + # look at directory name + for o in library_dirs: + m = re.search(r'ATLAS_(?P\d+[.]\d+[.]\d+)_', o) + if m: + atlas_version = m.group('version') + if atlas_version is not None: + break + + # final choice --- look at ATLAS_VERSION environment + # variable + if atlas_version is None: + atlas_version = os.environ.get('ATLAS_VERSION', None) + if atlas_version: + dict_append(info, define_macros=[( + 'ATLAS_INFO', _c_string_literal(atlas_version)) + ]) + else: + dict_append(info, define_macros=[('NO_ATLAS_INFO', -1)]) + return atlas_version or '?.?.?', info + + if not s: + m = re.search(r'ATLAS version (?P\d+[.]\d+[.]\d+)', o) + if m: + atlas_version = m.group('version') + if atlas_version is None: + if re.search(r'undefined symbol: ATL_buildinfo', o, re.M): + atlas_version = '3.2.1_pre3.3.6' + else: + log.info('Status: %d', s) + log.info('Output: %s', o) + + elif atlas_version == '3.2.1_pre3.3.6': + dict_append(info, define_macros=[('NO_ATLAS_INFO', -2)]) + else: + dict_append(info, define_macros=[( + 'ATLAS_INFO', _c_string_literal(atlas_version)) + ]) + result = _cached_atlas_version[key] = atlas_version, info + return result + + +class lapack_opt_info(system_info): + notfounderror = LapackNotFoundError + # List of all known LAPACK libraries, in the default order + lapack_order = ['mkl', 'openblas', 'flame', 'atlas', 'lapack'] + order_env_var_name = 'NPY_LAPACK_ORDER' + + def _calc_info_mkl(self): + info = get_info('lapack_mkl') + if info: + self.set_info(**info) + return True + return False + + def _calc_info_openblas(self): + info = get_info('openblas_lapack') + if info: + self.set_info(**info) + return True + info = get_info('openblas_clapack') + if info: + self.set_info(**info) + return True + return False + + def _calc_info_flame(self): + info = get_info('flame') + if info: + self.set_info(**info) + return True + return False + + def _calc_info_atlas(self): + info = get_info('atlas_3_10_threads') + if not info: + info = get_info('atlas_3_10') + if not info: + info = get_info('atlas_threads') + if not info: + info = get_info('atlas') + if info: + # Figure out if ATLAS has lapack... + # If not we need the lapack library, but not BLAS! + l = info.get('define_macros', []) + if ('ATLAS_WITH_LAPACK_ATLAS', None) in l \ + or ('ATLAS_WITHOUT_LAPACK', None) in l: + # Get LAPACK (with possible warnings) + # If not found we don't accept anything + # since we can't use ATLAS with LAPACK! + lapack_info = self._get_info_lapack() + if not lapack_info: + return False + dict_append(info, **lapack_info) + self.set_info(**info) + return True + return False + + def _calc_info_accelerate(self): + info = get_info('accelerate') + if info: + self.set_info(**info) + return True + return False + + def _get_info_blas(self): + # Default to get the optimized BLAS implementation + info = get_info('blas_opt') + if not info: + warnings.warn(BlasNotFoundError.__doc__ or '', stacklevel=3) + info_src = get_info('blas_src') + if not info_src: + warnings.warn(BlasSrcNotFoundError.__doc__ or '', stacklevel=3) + return {} + dict_append(info, libraries=[('fblas_src', info_src)]) + return info + + def _get_info_lapack(self): + info = get_info('lapack') + if not info: + warnings.warn(LapackNotFoundError.__doc__ or '', stacklevel=3) + info_src = get_info('lapack_src') + if not info_src: + warnings.warn(LapackSrcNotFoundError.__doc__ or '', stacklevel=3) + return {} + dict_append(info, libraries=[('flapack_src', info_src)]) + return info + + def _calc_info_lapack(self): + info = self._get_info_lapack() + if info: + info_blas = self._get_info_blas() + dict_append(info, **info_blas) + dict_append(info, define_macros=[('NO_ATLAS_INFO', 1)]) + self.set_info(**info) + return True + return False + + def _calc_info(self, name): + return getattr(self, '_calc_info_{}'.format(name))() + + def calc_info(self): + lapack_order, unknown_order = _parse_env_order(self.lapack_order, self.order_env_var_name) + if len(unknown_order) > 0: + raise ValueError("lapack_opt_info user defined " + "LAPACK order has unacceptable " + "values: {}".format(unknown_order)) + + for lapack in lapack_order: + if self._calc_info(lapack): + return + + if 'lapack' not in lapack_order: + # Since the user may request *not* to use any library, we still need + # to raise warnings to signal missing packages! + warnings.warn(LapackNotFoundError.__doc__ or '', stacklevel=2) + warnings.warn(LapackSrcNotFoundError.__doc__ or '', stacklevel=2) + + +class _ilp64_opt_info_mixin: + symbol_suffix = None + symbol_prefix = None + + def _check_info(self, info): + macros = dict(info.get('define_macros', [])) + prefix = macros.get('BLAS_SYMBOL_PREFIX', '') + suffix = macros.get('BLAS_SYMBOL_SUFFIX', '') + + if self.symbol_prefix not in (None, prefix): + return False + + if self.symbol_suffix not in (None, suffix): + return False + + return bool(info) + + +class lapack_ilp64_opt_info(lapack_opt_info, _ilp64_opt_info_mixin): + notfounderror = LapackILP64NotFoundError + lapack_order = ['openblas64_', 'openblas_ilp64'] + order_env_var_name = 'NPY_LAPACK_ILP64_ORDER' + + def _calc_info(self, name): + info = get_info(name + '_lapack') + if self._check_info(info): + self.set_info(**info) + return True + return False + + +class lapack_ilp64_plain_opt_info(lapack_ilp64_opt_info): + # Same as lapack_ilp64_opt_info, but fix symbol names + symbol_prefix = '' + symbol_suffix = '' + + +class lapack64__opt_info(lapack_ilp64_opt_info): + symbol_prefix = '' + symbol_suffix = '64_' + + +class blas_opt_info(system_info): + notfounderror = BlasNotFoundError + # List of all known BLAS libraries, in the default order + blas_order = ['mkl', 'blis', 'openblas', 'atlas', 'blas'] + order_env_var_name = 'NPY_BLAS_ORDER' + + def _calc_info_mkl(self): + info = get_info('blas_mkl') + if info: + self.set_info(**info) + return True + return False + + def _calc_info_blis(self): + info = get_info('blis') + if info: + self.set_info(**info) + return True + return False + + def _calc_info_openblas(self): + info = get_info('openblas') + if info: + self.set_info(**info) + return True + return False + + def _calc_info_atlas(self): + info = get_info('atlas_3_10_blas_threads') + if not info: + info = get_info('atlas_3_10_blas') + if not info: + info = get_info('atlas_blas_threads') + if not info: + info = get_info('atlas_blas') + if info: + self.set_info(**info) + return True + return False + + def _calc_info_accelerate(self): + info = get_info('accelerate') + if info: + self.set_info(**info) + return True + return False + + def _calc_info_blas(self): + # Warn about a non-optimized BLAS library + warnings.warn(BlasOptNotFoundError.__doc__ or '', stacklevel=3) + info = {} + dict_append(info, define_macros=[('NO_ATLAS_INFO', 1)]) + + blas = get_info('blas') + if blas: + dict_append(info, **blas) + else: + # Not even BLAS was found! + warnings.warn(BlasNotFoundError.__doc__ or '', stacklevel=3) + + blas_src = get_info('blas_src') + if not blas_src: + warnings.warn(BlasSrcNotFoundError.__doc__ or '', stacklevel=3) + return False + dict_append(info, libraries=[('fblas_src', blas_src)]) + + self.set_info(**info) + return True + + def _calc_info(self, name): + return getattr(self, '_calc_info_{}'.format(name))() + + def calc_info(self): + blas_order, unknown_order = _parse_env_order(self.blas_order, self.order_env_var_name) + if len(unknown_order) > 0: + raise ValueError("blas_opt_info user defined BLAS order has unacceptable values: {}".format(unknown_order)) + + for blas in blas_order: + if self._calc_info(blas): + return + + if 'blas' not in blas_order: + # Since the user may request *not* to use any library, we still need + # to raise warnings to signal missing packages! + warnings.warn(BlasNotFoundError.__doc__ or '', stacklevel=2) + warnings.warn(BlasSrcNotFoundError.__doc__ or '', stacklevel=2) + + +class blas_ilp64_opt_info(blas_opt_info, _ilp64_opt_info_mixin): + notfounderror = BlasILP64NotFoundError + blas_order = ['openblas64_', 'openblas_ilp64'] + order_env_var_name = 'NPY_BLAS_ILP64_ORDER' + + def _calc_info(self, name): + info = get_info(name) + if self._check_info(info): + self.set_info(**info) + return True + return False + + +class blas_ilp64_plain_opt_info(blas_ilp64_opt_info): + symbol_prefix = '' + symbol_suffix = '' + + +class blas64__opt_info(blas_ilp64_opt_info): + symbol_prefix = '' + symbol_suffix = '64_' + + +class cblas_info(system_info): + section = 'cblas' + dir_env_var = 'CBLAS' + # No default as it's used only in blas_info + _lib_names = [] + notfounderror = BlasNotFoundError + + +class blas_info(system_info): + section = 'blas' + dir_env_var = 'BLAS' + _lib_names = ['blas'] + notfounderror = BlasNotFoundError + + def calc_info(self): + lib_dirs = self.get_lib_dirs() + opt = self.get_option_single('blas_libs', 'libraries') + blas_libs = self.get_libs(opt, self._lib_names) + info = self.check_libs(lib_dirs, blas_libs, []) + if info is None: + return + else: + info['include_dirs'] = self.get_include_dirs() + if platform.system() == 'Windows': + # The check for windows is needed because get_cblas_libs uses the + # same compiler that was used to compile Python and msvc is + # often not installed when mingw is being used. This rough + # treatment is not desirable, but windows is tricky. + info['language'] = 'f77' # XXX: is it generally true? + # If cblas is given as an option, use those + cblas_info_obj = cblas_info() + cblas_opt = cblas_info_obj.get_option_single('cblas_libs', 'libraries') + cblas_libs = cblas_info_obj.get_libs(cblas_opt, None) + if cblas_libs: + info['libraries'] = cblas_libs + blas_libs + info['define_macros'] = [('HAVE_CBLAS', None)] + else: + lib = self.get_cblas_libs(info) + if lib is not None: + info['language'] = 'c' + info['libraries'] = lib + info['define_macros'] = [('HAVE_CBLAS', None)] + self.set_info(**info) + + def get_cblas_libs(self, info): + """ Check whether we can link with CBLAS interface + + This method will search through several combinations of libraries + to check whether CBLAS is present: + + 1. Libraries in ``info['libraries']``, as is + 2. As 1. but also explicitly adding ``'cblas'`` as a library + 3. As 1. but also explicitly adding ``'blas'`` as a library + 4. Check only library ``'cblas'`` + 5. Check only library ``'blas'`` + + Parameters + ---------- + info : dict + system information dictionary for compilation and linking + + Returns + ------- + libraries : list of str or None + a list of libraries that enables the use of CBLAS interface. + Returns None if not found or a compilation error occurs. + + Since 1.17 returns a list. + """ + # primitive cblas check by looking for the header and trying to link + # cblas or blas + c = customized_ccompiler() + tmpdir = tempfile.mkdtemp() + s = textwrap.dedent("""\ + #include + int main(int argc, const char *argv[]) + { + double a[4] = {1,2,3,4}; + double b[4] = {5,6,7,8}; + return cblas_ddot(4, a, 1, b, 1) > 10; + }""") + src = os.path.join(tmpdir, 'source.c') + try: + with open(src, 'wt') as f: + f.write(s) + + try: + # check we can compile (find headers) + obj = c.compile([src], output_dir=tmpdir, + include_dirs=self.get_include_dirs()) + except (distutils.ccompiler.CompileError, distutils.ccompiler.LinkError): + return None + + # check we can link (find library) + # some systems have separate cblas and blas libs. + for libs in [info['libraries'], ['cblas'] + info['libraries'], + ['blas'] + info['libraries'], ['cblas'], ['blas']]: + try: + c.link_executable(obj, os.path.join(tmpdir, "a.out"), + libraries=libs, + library_dirs=info['library_dirs'], + extra_postargs=info.get('extra_link_args', [])) + return libs + except distutils.ccompiler.LinkError: + pass + finally: + shutil.rmtree(tmpdir) + return None + + +class openblas_info(blas_info): + section = 'openblas' + dir_env_var = 'OPENBLAS' + _lib_names = ['openblas'] + _require_symbols = [] + notfounderror = BlasNotFoundError + + @property + def symbol_prefix(self): + try: + return self.cp.get(self.section, 'symbol_prefix') + except NoOptionError: + return '' + + @property + def symbol_suffix(self): + try: + return self.cp.get(self.section, 'symbol_suffix') + except NoOptionError: + return '' + + def _calc_info(self): + c = customized_ccompiler() + + lib_dirs = self.get_lib_dirs() + + # Prefer to use libraries over openblas_libs + opt = self.get_option_single('openblas_libs', 'libraries') + openblas_libs = self.get_libs(opt, self._lib_names) + + info = self.check_libs(lib_dirs, openblas_libs, []) + + if c.compiler_type == "msvc" and info is None: + from numpy.distutils.fcompiler import new_fcompiler + f = new_fcompiler(c_compiler=c) + if f and f.compiler_type == 'gnu95': + # Try gfortran-compatible library files + info = self.check_msvc_gfortran_libs(lib_dirs, openblas_libs) + # Skip lapack check, we'd need build_ext to do it + skip_symbol_check = True + elif info: + skip_symbol_check = False + info['language'] = 'c' + + if info is None: + return None + + # Add extra info for OpenBLAS + extra_info = self.calc_extra_info() + dict_append(info, **extra_info) + + if not (skip_symbol_check or self.check_symbols(info)): + return None + + info['define_macros'] = [('HAVE_CBLAS', None)] + if self.symbol_prefix: + info['define_macros'] += [('BLAS_SYMBOL_PREFIX', self.symbol_prefix)] + if self.symbol_suffix: + info['define_macros'] += [('BLAS_SYMBOL_SUFFIX', self.symbol_suffix)] + + return info + + def calc_info(self): + info = self._calc_info() + if info is not None: + self.set_info(**info) + + def check_msvc_gfortran_libs(self, library_dirs, libraries): + # First, find the full path to each library directory + library_paths = [] + for library in libraries: + for library_dir in library_dirs: + # MinGW static ext will be .a + fullpath = os.path.join(library_dir, library + '.a') + if os.path.isfile(fullpath): + library_paths.append(fullpath) + break + else: + return None + + # Generate numpy.distutils virtual static library file + basename = self.__class__.__name__ + tmpdir = os.path.join(os.getcwd(), 'build', basename) + if not os.path.isdir(tmpdir): + os.makedirs(tmpdir) + + info = {'library_dirs': [tmpdir], + 'libraries': [basename], + 'language': 'f77'} + + fake_lib_file = os.path.join(tmpdir, basename + '.fobjects') + fake_clib_file = os.path.join(tmpdir, basename + '.cobjects') + with open(fake_lib_file, 'w') as f: + f.write("\n".join(library_paths)) + with open(fake_clib_file, 'w') as f: + pass + + return info + + def check_symbols(self, info): + res = False + c = customized_ccompiler() + + tmpdir = tempfile.mkdtemp() + + prototypes = "\n".join("void %s%s%s();" % (self.symbol_prefix, + symbol_name, + self.symbol_suffix) + for symbol_name in self._require_symbols) + calls = "\n".join("%s%s%s();" % (self.symbol_prefix, + symbol_name, + self.symbol_suffix) + for symbol_name in self._require_symbols) + s = textwrap.dedent("""\ + %(prototypes)s + int main(int argc, const char *argv[]) + { + %(calls)s + return 0; + }""") % dict(prototypes=prototypes, calls=calls) + src = os.path.join(tmpdir, 'source.c') + out = os.path.join(tmpdir, 'a.out') + # Add the additional "extra" arguments + try: + extra_args = info['extra_link_args'] + except Exception: + extra_args = [] + try: + with open(src, 'wt') as f: + f.write(s) + obj = c.compile([src], output_dir=tmpdir) + try: + c.link_executable(obj, out, libraries=info['libraries'], + library_dirs=info['library_dirs'], + extra_postargs=extra_args) + res = True + except distutils.ccompiler.LinkError: + res = False + finally: + shutil.rmtree(tmpdir) + return res + +class openblas_lapack_info(openblas_info): + section = 'openblas' + dir_env_var = 'OPENBLAS' + _lib_names = ['openblas'] + _require_symbols = ['zungqr_'] + notfounderror = BlasNotFoundError + +class openblas_clapack_info(openblas_lapack_info): + _lib_names = ['openblas', 'lapack'] + +class openblas_ilp64_info(openblas_info): + section = 'openblas_ilp64' + dir_env_var = 'OPENBLAS_ILP64' + _lib_names = ['openblas64'] + _require_symbols = ['dgemm_', 'cblas_dgemm'] + notfounderror = BlasILP64NotFoundError + + def _calc_info(self): + info = super()._calc_info() + if info is not None: + info['define_macros'] += [('HAVE_BLAS_ILP64', None)] + return info + +class openblas_ilp64_lapack_info(openblas_ilp64_info): + _require_symbols = ['dgemm_', 'cblas_dgemm', 'zungqr_', 'LAPACKE_zungqr'] + + def _calc_info(self): + info = super()._calc_info() + if info: + info['define_macros'] += [('HAVE_LAPACKE', None)] + return info + +class openblas64__info(openblas_ilp64_info): + # ILP64 Openblas, with default symbol suffix + section = 'openblas64_' + dir_env_var = 'OPENBLAS64_' + _lib_names = ['openblas64_'] + symbol_suffix = '64_' + symbol_prefix = '' + +class openblas64__lapack_info(openblas_ilp64_lapack_info, openblas64__info): + pass + +class blis_info(blas_info): + section = 'blis' + dir_env_var = 'BLIS' + _lib_names = ['blis'] + notfounderror = BlasNotFoundError + + def calc_info(self): + lib_dirs = self.get_lib_dirs() + opt = self.get_option_single('blis_libs', 'libraries') + blis_libs = self.get_libs(opt, self._lib_names) + info = self.check_libs2(lib_dirs, blis_libs, []) + if info is None: + return + + # Add include dirs + incl_dirs = self.get_include_dirs() + dict_append(info, + language='c', + define_macros=[('HAVE_CBLAS', None)], + include_dirs=incl_dirs) + self.set_info(**info) + + +class flame_info(system_info): + """ Usage of libflame for LAPACK operations + + This requires libflame to be compiled with lapack wrappers: + + ./configure --enable-lapack2flame ... + + Be aware that libflame 5.1.0 has some missing names in the shared library, so + if you have problems, try the static flame library. + """ + section = 'flame' + _lib_names = ['flame'] + notfounderror = FlameNotFoundError + + def check_embedded_lapack(self, info): + """ libflame does not necessarily have a wrapper for fortran LAPACK, we need to check """ + c = customized_ccompiler() + + tmpdir = tempfile.mkdtemp() + s = textwrap.dedent("""\ + void zungqr_(); + int main(int argc, const char *argv[]) + { + zungqr_(); + return 0; + }""") + src = os.path.join(tmpdir, 'source.c') + out = os.path.join(tmpdir, 'a.out') + # Add the additional "extra" arguments + extra_args = info.get('extra_link_args', []) + try: + with open(src, 'wt') as f: + f.write(s) + obj = c.compile([src], output_dir=tmpdir) + try: + c.link_executable(obj, out, libraries=info['libraries'], + library_dirs=info['library_dirs'], + extra_postargs=extra_args) + return True + except distutils.ccompiler.LinkError: + return False + finally: + shutil.rmtree(tmpdir) + + def calc_info(self): + lib_dirs = self.get_lib_dirs() + flame_libs = self.get_libs('libraries', self._lib_names) + + info = self.check_libs2(lib_dirs, flame_libs, []) + if info is None: + return + + if self.check_embedded_lapack(info): + # check if the user has supplied all information required + self.set_info(**info) + else: + # Try and get the BLAS lib to see if we can get it to work + blas_info = get_info('blas_opt') + if not blas_info: + # since we already failed once, this ain't going to work either + return + + # Now we need to merge the two dictionaries + for key in blas_info: + if isinstance(blas_info[key], list): + info[key] = info.get(key, []) + blas_info[key] + elif isinstance(blas_info[key], tuple): + info[key] = info.get(key, ()) + blas_info[key] + else: + info[key] = info.get(key, '') + blas_info[key] + + # Now check again + if self.check_embedded_lapack(info): + self.set_info(**info) + + +class accelerate_info(system_info): + section = 'accelerate' + _lib_names = ['accelerate', 'veclib'] + notfounderror = BlasNotFoundError + + def calc_info(self): + # Make possible to enable/disable from config file/env var + libraries = os.environ.get('ACCELERATE') + if libraries: + libraries = [libraries] + else: + libraries = self.get_libs('libraries', self._lib_names) + libraries = [lib.strip().lower() for lib in libraries] + + if (sys.platform == 'darwin' and + not os.getenv('_PYTHON_HOST_PLATFORM', None)): + # Use the system BLAS from Accelerate or vecLib under OSX + args = [] + link_args = [] + if get_platform()[-4:] == 'i386' or 'intel' in get_platform() or \ + 'x86_64' in get_platform() or \ + 'i386' in platform.platform(): + intel = 1 + else: + intel = 0 + if (os.path.exists('/System/Library/Frameworks' + '/Accelerate.framework/') and + 'accelerate' in libraries): + if intel: + args.extend(['-msse3']) + else: + args.extend(['-faltivec']) + args.extend([ + '-I/System/Library/Frameworks/vecLib.framework/Headers']) + link_args.extend(['-Wl,-framework', '-Wl,Accelerate']) + elif (os.path.exists('/System/Library/Frameworks' + '/vecLib.framework/') and + 'veclib' in libraries): + if intel: + args.extend(['-msse3']) + else: + args.extend(['-faltivec']) + args.extend([ + '-I/System/Library/Frameworks/vecLib.framework/Headers']) + link_args.extend(['-Wl,-framework', '-Wl,vecLib']) + + if args: + self.set_info(extra_compile_args=args, + extra_link_args=link_args, + define_macros=[('NO_ATLAS_INFO', 3), + ('HAVE_CBLAS', None)]) + + return + +class blas_src_info(system_info): + section = 'blas_src' + dir_env_var = 'BLAS_SRC' + notfounderror = BlasSrcNotFoundError + + def get_paths(self, section, key): + pre_dirs = system_info.get_paths(self, section, key) + dirs = [] + for d in pre_dirs: + dirs.extend([d] + self.combine_paths(d, ['blas'])) + return [d for d in dirs if os.path.isdir(d)] + + def calc_info(self): + src_dirs = self.get_src_dirs() + src_dir = '' + for d in src_dirs: + if os.path.isfile(os.path.join(d, 'daxpy.f')): + src_dir = d + break + if not src_dir: + #XXX: Get sources from netlib. May be ask first. + return + blas1 = ''' + caxpy csscal dnrm2 dzasum saxpy srotg zdotc ccopy cswap drot + dznrm2 scasum srotm zdotu cdotc dasum drotg icamax scnrm2 + srotmg zdrot cdotu daxpy drotm idamax scopy sscal zdscal crotg + dcabs1 drotmg isamax sdot sswap zrotg cscal dcopy dscal izamax + snrm2 zaxpy zscal csrot ddot dswap sasum srot zcopy zswap + scabs1 + ''' + blas2 = ''' + cgbmv chpmv ctrsv dsymv dtrsv sspr2 strmv zhemv ztpmv cgemv + chpr dgbmv dsyr lsame ssymv strsv zher ztpsv cgerc chpr2 dgemv + dsyr2 sgbmv ssyr xerbla zher2 ztrmv cgeru ctbmv dger dtbmv + sgemv ssyr2 zgbmv zhpmv ztrsv chbmv ctbsv dsbmv dtbsv sger + stbmv zgemv zhpr chemv ctpmv dspmv dtpmv ssbmv stbsv zgerc + zhpr2 cher ctpsv dspr dtpsv sspmv stpmv zgeru ztbmv cher2 + ctrmv dspr2 dtrmv sspr stpsv zhbmv ztbsv + ''' + blas3 = ''' + cgemm csymm ctrsm dsyrk sgemm strmm zhemm zsyr2k chemm csyr2k + dgemm dtrmm ssymm strsm zher2k zsyrk cher2k csyrk dsymm dtrsm + ssyr2k zherk ztrmm cherk ctrmm dsyr2k ssyrk zgemm zsymm ztrsm + ''' + sources = [os.path.join(src_dir, f + '.f') \ + for f in (blas1 + blas2 + blas3).split()] + #XXX: should we check here actual existence of source files? + sources = [f for f in sources if os.path.isfile(f)] + info = {'sources': sources, 'language': 'f77'} + self.set_info(**info) + + +class x11_info(system_info): + section = 'x11' + notfounderror = X11NotFoundError + _lib_names = ['X11'] + + def __init__(self): + system_info.__init__(self, + default_lib_dirs=default_x11_lib_dirs, + default_include_dirs=default_x11_include_dirs) + + def calc_info(self): + if sys.platform in ['win32']: + return + lib_dirs = self.get_lib_dirs() + include_dirs = self.get_include_dirs() + opt = self.get_option_single('x11_libs', 'libraries') + x11_libs = self.get_libs(opt, self._lib_names) + info = self.check_libs(lib_dirs, x11_libs, []) + if info is None: + return + inc_dir = None + for d in include_dirs: + if self.combine_paths(d, 'X11/X.h'): + inc_dir = d + break + if inc_dir is not None: + dict_append(info, include_dirs=[inc_dir]) + self.set_info(**info) + + +class _numpy_info(system_info): + section = 'Numeric' + modulename = 'Numeric' + notfounderror = NumericNotFoundError + + def __init__(self): + include_dirs = [] + try: + module = __import__(self.modulename) + prefix = [] + for name in module.__file__.split(os.sep): + if name == 'lib': + break + prefix.append(name) + + # Ask numpy for its own include path before attempting + # anything else + try: + include_dirs.append(getattr(module, 'get_include')()) + except AttributeError: + pass + + include_dirs.append(sysconfig.get_path('include')) + except ImportError: + pass + py_incl_dir = sysconfig.get_path('include') + include_dirs.append(py_incl_dir) + py_pincl_dir = sysconfig.get_path('platinclude') + if py_pincl_dir not in include_dirs: + include_dirs.append(py_pincl_dir) + for d in default_include_dirs: + d = os.path.join(d, os.path.basename(py_incl_dir)) + if d not in include_dirs: + include_dirs.append(d) + system_info.__init__(self, + default_lib_dirs=[], + default_include_dirs=include_dirs) + + def calc_info(self): + try: + module = __import__(self.modulename) + except ImportError: + return + info = {} + macros = [] + for v in ['__version__', 'version']: + vrs = getattr(module, v, None) + if vrs is None: + continue + macros = [(self.modulename.upper() + '_VERSION', + _c_string_literal(vrs)), + (self.modulename.upper(), None)] + break + dict_append(info, define_macros=macros) + include_dirs = self.get_include_dirs() + inc_dir = None + for d in include_dirs: + if self.combine_paths(d, + os.path.join(self.modulename, + 'arrayobject.h')): + inc_dir = d + break + if inc_dir is not None: + dict_append(info, include_dirs=[inc_dir]) + if info: + self.set_info(**info) + return + + +class numarray_info(_numpy_info): + section = 'numarray' + modulename = 'numarray' + + +class Numeric_info(_numpy_info): + section = 'Numeric' + modulename = 'Numeric' + + +class numpy_info(_numpy_info): + section = 'numpy' + modulename = 'numpy' + + +class numerix_info(system_info): + section = 'numerix' + + def calc_info(self): + which = None, None + if os.getenv("NUMERIX"): + which = os.getenv("NUMERIX"), "environment var" + # If all the above fail, default to numpy. + if which[0] is None: + which = "numpy", "defaulted" + try: + import numpy # noqa: F401 + which = "numpy", "defaulted" + except ImportError as e: + msg1 = str(e) + try: + import Numeric # noqa: F401 + which = "numeric", "defaulted" + except ImportError as e: + msg2 = str(e) + try: + import numarray # noqa: F401 + which = "numarray", "defaulted" + except ImportError as e: + msg3 = str(e) + log.info(msg1) + log.info(msg2) + log.info(msg3) + which = which[0].strip().lower(), which[1] + if which[0] not in ["numeric", "numarray", "numpy"]: + raise ValueError("numerix selector must be either 'Numeric' " + "or 'numarray' or 'numpy' but the value obtained" + " from the %s was '%s'." % (which[1], which[0])) + os.environ['NUMERIX'] = which[0] + self.set_info(**get_info(which[0])) + + +class f2py_info(system_info): + def calc_info(self): + try: + import numpy.f2py as f2py + except ImportError: + return + f2py_dir = os.path.join(os.path.dirname(f2py.__file__), 'src') + self.set_info(sources=[os.path.join(f2py_dir, 'fortranobject.c')], + include_dirs=[f2py_dir]) + return + + +class boost_python_info(system_info): + section = 'boost_python' + dir_env_var = 'BOOST' + + def get_paths(self, section, key): + pre_dirs = system_info.get_paths(self, section, key) + dirs = [] + for d in pre_dirs: + dirs.extend([d] + self.combine_paths(d, ['boost*'])) + return [d for d in dirs if os.path.isdir(d)] + + def calc_info(self): + src_dirs = self.get_src_dirs() + src_dir = '' + for d in src_dirs: + if os.path.isfile(os.path.join(d, 'libs', 'python', 'src', + 'module.cpp')): + src_dir = d + break + if not src_dir: + return + py_incl_dirs = [sysconfig.get_path('include')] + py_pincl_dir = sysconfig.get_path('platinclude') + if py_pincl_dir not in py_incl_dirs: + py_incl_dirs.append(py_pincl_dir) + srcs_dir = os.path.join(src_dir, 'libs', 'python', 'src') + bpl_srcs = glob(os.path.join(srcs_dir, '*.cpp')) + bpl_srcs += glob(os.path.join(srcs_dir, '*', '*.cpp')) + info = {'libraries': [('boost_python_src', + {'include_dirs': [src_dir] + py_incl_dirs, + 'sources':bpl_srcs} + )], + 'include_dirs': [src_dir], + } + if info: + self.set_info(**info) + return + + +class agg2_info(system_info): + section = 'agg2' + dir_env_var = 'AGG2' + + def get_paths(self, section, key): + pre_dirs = system_info.get_paths(self, section, key) + dirs = [] + for d in pre_dirs: + dirs.extend([d] + self.combine_paths(d, ['agg2*'])) + return [d for d in dirs if os.path.isdir(d)] + + def calc_info(self): + src_dirs = self.get_src_dirs() + src_dir = '' + for d in src_dirs: + if os.path.isfile(os.path.join(d, 'src', 'agg_affine_matrix.cpp')): + src_dir = d + break + if not src_dir: + return + if sys.platform == 'win32': + agg2_srcs = glob(os.path.join(src_dir, 'src', 'platform', + 'win32', 'agg_win32_bmp.cpp')) + else: + agg2_srcs = glob(os.path.join(src_dir, 'src', '*.cpp')) + agg2_srcs += [os.path.join(src_dir, 'src', 'platform', + 'X11', + 'agg_platform_support.cpp')] + + info = {'libraries': + [('agg2_src', + {'sources': agg2_srcs, + 'include_dirs': [os.path.join(src_dir, 'include')], + } + )], + 'include_dirs': [os.path.join(src_dir, 'include')], + } + if info: + self.set_info(**info) + return + + +class _pkg_config_info(system_info): + section = None + config_env_var = 'PKG_CONFIG' + default_config_exe = 'pkg-config' + append_config_exe = '' + version_macro_name = None + release_macro_name = None + version_flag = '--modversion' + cflags_flag = '--cflags' + + def get_config_exe(self): + if self.config_env_var in os.environ: + return os.environ[self.config_env_var] + return self.default_config_exe + + def get_config_output(self, config_exe, option): + cmd = config_exe + ' ' + self.append_config_exe + ' ' + option + try: + o = subprocess.check_output(cmd) + except (OSError, subprocess.CalledProcessError): + pass + else: + o = filepath_from_subprocess_output(o) + return o + + def calc_info(self): + config_exe = find_executable(self.get_config_exe()) + if not config_exe: + log.warn('File not found: %s. Cannot determine %s info.' \ + % (config_exe, self.section)) + return + info = {} + macros = [] + libraries = [] + library_dirs = [] + include_dirs = [] + extra_link_args = [] + extra_compile_args = [] + version = self.get_config_output(config_exe, self.version_flag) + if version: + macros.append((self.__class__.__name__.split('.')[-1].upper(), + _c_string_literal(version))) + if self.version_macro_name: + macros.append((self.version_macro_name + '_%s' + % (version.replace('.', '_')), None)) + if self.release_macro_name: + release = self.get_config_output(config_exe, '--release') + if release: + macros.append((self.release_macro_name + '_%s' + % (release.replace('.', '_')), None)) + opts = self.get_config_output(config_exe, '--libs') + if opts: + for opt in opts.split(): + if opt[:2] == '-l': + libraries.append(opt[2:]) + elif opt[:2] == '-L': + library_dirs.append(opt[2:]) + else: + extra_link_args.append(opt) + opts = self.get_config_output(config_exe, self.cflags_flag) + if opts: + for opt in opts.split(): + if opt[:2] == '-I': + include_dirs.append(opt[2:]) + elif opt[:2] == '-D': + if '=' in opt: + n, v = opt[2:].split('=') + macros.append((n, v)) + else: + macros.append((opt[2:], None)) + else: + extra_compile_args.append(opt) + if macros: + dict_append(info, define_macros=macros) + if libraries: + dict_append(info, libraries=libraries) + if library_dirs: + dict_append(info, library_dirs=library_dirs) + if include_dirs: + dict_append(info, include_dirs=include_dirs) + if extra_link_args: + dict_append(info, extra_link_args=extra_link_args) + if extra_compile_args: + dict_append(info, extra_compile_args=extra_compile_args) + if info: + self.set_info(**info) + return + + +class wx_info(_pkg_config_info): + section = 'wx' + config_env_var = 'WX_CONFIG' + default_config_exe = 'wx-config' + append_config_exe = '' + version_macro_name = 'WX_VERSION' + release_macro_name = 'WX_RELEASE' + version_flag = '--version' + cflags_flag = '--cxxflags' + + +class gdk_pixbuf_xlib_2_info(_pkg_config_info): + section = 'gdk_pixbuf_xlib_2' + append_config_exe = 'gdk-pixbuf-xlib-2.0' + version_macro_name = 'GDK_PIXBUF_XLIB_VERSION' + + +class gdk_pixbuf_2_info(_pkg_config_info): + section = 'gdk_pixbuf_2' + append_config_exe = 'gdk-pixbuf-2.0' + version_macro_name = 'GDK_PIXBUF_VERSION' + + +class gdk_x11_2_info(_pkg_config_info): + section = 'gdk_x11_2' + append_config_exe = 'gdk-x11-2.0' + version_macro_name = 'GDK_X11_VERSION' + + +class gdk_2_info(_pkg_config_info): + section = 'gdk_2' + append_config_exe = 'gdk-2.0' + version_macro_name = 'GDK_VERSION' + + +class gdk_info(_pkg_config_info): + section = 'gdk' + append_config_exe = 'gdk' + version_macro_name = 'GDK_VERSION' + + +class gtkp_x11_2_info(_pkg_config_info): + section = 'gtkp_x11_2' + append_config_exe = 'gtk+-x11-2.0' + version_macro_name = 'GTK_X11_VERSION' + + +class gtkp_2_info(_pkg_config_info): + section = 'gtkp_2' + append_config_exe = 'gtk+-2.0' + version_macro_name = 'GTK_VERSION' + + +class xft_info(_pkg_config_info): + section = 'xft' + append_config_exe = 'xft' + version_macro_name = 'XFT_VERSION' + + +class freetype2_info(_pkg_config_info): + section = 'freetype2' + append_config_exe = 'freetype2' + version_macro_name = 'FREETYPE2_VERSION' + + +class amd_info(system_info): + section = 'amd' + dir_env_var = 'AMD' + _lib_names = ['amd'] + + def calc_info(self): + lib_dirs = self.get_lib_dirs() + + opt = self.get_option_single('amd_libs', 'libraries') + amd_libs = self.get_libs(opt, self._lib_names) + info = self.check_libs(lib_dirs, amd_libs, []) + if info is None: + return + + include_dirs = self.get_include_dirs() + + inc_dir = None + for d in include_dirs: + p = self.combine_paths(d, 'amd.h') + if p: + inc_dir = os.path.dirname(p[0]) + break + if inc_dir is not None: + dict_append(info, include_dirs=[inc_dir], + define_macros=[('SCIPY_AMD_H', None)], + swig_opts=['-I' + inc_dir]) + + self.set_info(**info) + return + + +class umfpack_info(system_info): + section = 'umfpack' + dir_env_var = 'UMFPACK' + notfounderror = UmfpackNotFoundError + _lib_names = ['umfpack'] + + def calc_info(self): + lib_dirs = self.get_lib_dirs() + + opt = self.get_option_single('umfpack_libs', 'libraries') + umfpack_libs = self.get_libs(opt, self._lib_names) + info = self.check_libs(lib_dirs, umfpack_libs, []) + if info is None: + return + + include_dirs = self.get_include_dirs() + + inc_dir = None + for d in include_dirs: + p = self.combine_paths(d, ['', 'umfpack'], 'umfpack.h') + if p: + inc_dir = os.path.dirname(p[0]) + break + if inc_dir is not None: + dict_append(info, include_dirs=[inc_dir], + define_macros=[('SCIPY_UMFPACK_H', None)], + swig_opts=['-I' + inc_dir]) + + dict_append(info, **get_info('amd')) + + self.set_info(**info) + return + + +def combine_paths(*args, **kws): + """ Return a list of existing paths composed by all combinations of + items from arguments. + """ + r = [] + for a in args: + if not a: + continue + if is_string(a): + a = [a] + r.append(a) + args = r + if not args: + return [] + if len(args) == 1: + result = reduce(lambda a, b: a + b, map(glob, args[0]), []) + elif len(args) == 2: + result = [] + for a0 in args[0]: + for a1 in args[1]: + result.extend(glob(os.path.join(a0, a1))) + else: + result = combine_paths(*(combine_paths(args[0], args[1]) + args[2:])) + log.debug('(paths: %s)', ','.join(result)) + return result + +language_map = {'c': 0, 'c++': 1, 'f77': 2, 'f90': 3} +inv_language_map = {0: 'c', 1: 'c++', 2: 'f77', 3: 'f90'} + + +def dict_append(d, **kws): + languages = [] + for k, v in kws.items(): + if k == 'language': + languages.append(v) + continue + if k in d: + if k in ['library_dirs', 'include_dirs', + 'extra_compile_args', 'extra_link_args', + 'runtime_library_dirs', 'define_macros']: + [d[k].append(vv) for vv in v if vv not in d[k]] + else: + d[k].extend(v) + else: + d[k] = v + if languages: + l = inv_language_map[max([language_map.get(l, 0) for l in languages])] + d['language'] = l + return + + +def parseCmdLine(argv=(None,)): + import optparse + parser = optparse.OptionParser("usage: %prog [-v] [info objs]") + parser.add_option('-v', '--verbose', action='store_true', dest='verbose', + default=False, + help='be verbose and print more messages') + + opts, args = parser.parse_args(args=argv[1:]) + return opts, args + + +def show_all(argv=None): + import inspect + if argv is None: + argv = sys.argv + opts, args = parseCmdLine(argv) + if opts.verbose: + log.set_threshold(log.DEBUG) + else: + log.set_threshold(log.INFO) + show_only = [] + for n in args: + if n[-5:] != '_info': + n = n + '_info' + show_only.append(n) + show_all = not show_only + _gdict_ = globals().copy() + for name, c in _gdict_.items(): + if not inspect.isclass(c): + continue + if not issubclass(c, system_info) or c is system_info: + continue + if not show_all: + if name not in show_only: + continue + del show_only[show_only.index(name)] + conf = c() + conf.verbosity = 2 + # FIXME: r not used + r = conf.get_info() + if show_only: + log.info('Info classes not defined: %s', ','.join(show_only)) + +if __name__ == "__main__": + show_all() diff --git a/venv/Lib/site-packages/numpy/distutils/tests/__init__.py b/venv/Lib/site-packages/numpy/distutils/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/venv/Lib/site-packages/numpy/distutils/tests/test_build_ext.py b/venv/Lib/site-packages/numpy/distutils/tests/test_build_ext.py new file mode 100644 index 0000000..c007159 --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/tests/test_build_ext.py @@ -0,0 +1,72 @@ +'''Tests for numpy.distutils.build_ext.''' + +import os +import subprocess +import sys +from textwrap import indent, dedent +import pytest + +@pytest.mark.slow +def test_multi_fortran_libs_link(tmp_path): + ''' + Ensures multiple "fake" static libraries are correctly linked. + see gh-18295 + ''' + + # We need to make sure we actually have an f77 compiler. + # This is nontrivial, so we'll borrow the utilities + # from f2py tests: + from numpy.f2py.tests.util import has_f77_compiler + if not has_f77_compiler(): + pytest.skip('No F77 compiler found') + + # make some dummy sources + with open(tmp_path / '_dummy1.f', 'w') as fid: + fid.write(indent(dedent('''\ + FUNCTION dummy_one() + RETURN + END FUNCTION'''), prefix=' '*6)) + with open(tmp_path / '_dummy2.f', 'w') as fid: + fid.write(indent(dedent('''\ + FUNCTION dummy_two() + RETURN + END FUNCTION'''), prefix=' '*6)) + with open(tmp_path / '_dummy.c', 'w') as fid: + # doesn't need to load - just needs to exist + fid.write('int PyInit_dummyext;') + + # make a setup file + with open(tmp_path / 'setup.py', 'w') as fid: + srctree = os.path.join(os.path.dirname(__file__), '..', '..', '..') + fid.write(dedent(f'''\ + def configuration(parent_package="", top_path=None): + from numpy.distutils.misc_util import Configuration + config = Configuration("", parent_package, top_path) + config.add_library("dummy1", sources=["_dummy1.f"]) + config.add_library("dummy2", sources=["_dummy2.f"]) + config.add_extension("dummyext", sources=["_dummy.c"], libraries=["dummy1", "dummy2"]) + return config + + + if __name__ == "__main__": + import sys + sys.path.insert(0, r"{srctree}") + from numpy.distutils.core import setup + setup(**configuration(top_path="").todict())''')) + + # build the test extensino and "install" into a temporary directory + build_dir = tmp_path + subprocess.check_call([sys.executable, 'setup.py', 'build', 'install', + '--prefix', str(tmp_path / 'installdir'), + '--record', str(tmp_path / 'tmp_install_log.txt'), + ], + cwd=str(build_dir), + ) + # get the path to the so + so = None + with open(tmp_path /'tmp_install_log.txt') as fid: + for line in fid: + if 'dummyext' in line: + so = line.strip() + break + assert so is not None diff --git a/venv/Lib/site-packages/numpy/distutils/tests/test_ccompiler_opt.py b/venv/Lib/site-packages/numpy/distutils/tests/test_ccompiler_opt.py new file mode 100644 index 0000000..287a683 --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/tests/test_ccompiler_opt.py @@ -0,0 +1,787 @@ +import re, textwrap, os +from os import sys, path +from distutils.errors import DistutilsError + +is_standalone = __name__ == '__main__' and __package__ is None +if is_standalone: + import unittest, contextlib, tempfile, shutil + sys.path.append(path.abspath(path.join(path.dirname(__file__), ".."))) + from ccompiler_opt import CCompilerOpt + + # from numpy/testing/_private/utils.py + @contextlib.contextmanager + def tempdir(*args, **kwargs): + tmpdir = tempfile.mkdtemp(*args, **kwargs) + try: + yield tmpdir + finally: + shutil.rmtree(tmpdir) + + def assert_(expr, msg=''): + if not expr: + raise AssertionError(msg) +else: + from numpy.distutils.ccompiler_opt import CCompilerOpt + from numpy.testing import assert_, tempdir + +# architectures and compilers to test +arch_compilers = dict( + x86 = ("gcc", "clang", "icc", "iccw", "msvc"), + x64 = ("gcc", "clang", "icc", "iccw", "msvc"), + ppc64 = ("gcc", "clang"), + ppc64le = ("gcc", "clang"), + armhf = ("gcc", "clang"), + aarch64 = ("gcc", "clang"), + noarch = ("gcc",) +) + +class FakeCCompilerOpt(CCompilerOpt): + fake_info = "" + def __init__(self, trap_files="", trap_flags="", *args, **kwargs): + self.fake_trap_files = trap_files + self.fake_trap_flags = trap_flags + CCompilerOpt.__init__(self, None, **kwargs) + + def __repr__(self): + return textwrap.dedent("""\ + <<<< + march : {} + compiler : {} + ---------------- + {} + >>>> + """).format(self.cc_march, self.cc_name, self.report()) + + def dist_compile(self, sources, flags, **kwargs): + assert(isinstance(sources, list)) + assert(isinstance(flags, list)) + if self.fake_trap_files: + for src in sources: + if re.match(self.fake_trap_files, src): + self.dist_error("source is trapped by a fake interface") + if self.fake_trap_flags: + for f in flags: + if re.match(self.fake_trap_flags, f): + self.dist_error("flag is trapped by a fake interface") + # fake objects + return zip(sources, [' '.join(flags)] * len(sources)) + + def dist_info(self): + return FakeCCompilerOpt.fake_info + + @staticmethod + def dist_log(*args, stderr=False): + pass + +class _Test_CCompilerOpt(object): + arch = None # x86_64 + cc = None # gcc + + def setup(self): + FakeCCompilerOpt.conf_nocache = True + self._opt = None + + def nopt(self, *args, **kwargs): + FakeCCompilerOpt.fake_info = (self.arch, self.cc, "") + return FakeCCompilerOpt(*args, **kwargs) + + def opt(self): + if not self._opt: + self._opt = self.nopt() + return self._opt + + def march(self): + return self.opt().cc_march + + def cc_name(self): + return self.opt().cc_name + + def get_targets(self, targets, groups, **kwargs): + FakeCCompilerOpt.conf_target_groups = groups + opt = self.nopt( + cpu_baseline=kwargs.get("baseline", "min"), + cpu_dispatch=kwargs.get("dispatch", "max"), + trap_files=kwargs.get("trap_files", ""), + trap_flags=kwargs.get("trap_flags", "") + ) + with tempdir() as tmpdir: + file = os.path.join(tmpdir, "test_targets.c") + with open(file, 'w') as f: + f.write(targets) + gtargets = [] + gflags = {} + fake_objects = opt.try_dispatch([file]) + for source, flags in fake_objects: + gtar = source.split('.')[1:-1] + glen = len(gtar) + if glen == 0: + gtar = "baseline" + elif glen == 1: + gtar = gtar[0].upper() + else: + # converting multi-target into parentheses str format to be equivalent + # to the configuration statements syntax. + gtar = ('('+' '.join(gtar)+')').upper() + gtargets.append(gtar) + gflags[gtar] = flags + + has_baseline, targets = opt.sources_status[file] + targets = targets + ["baseline"] if has_baseline else targets + # convert tuple that represent multi-target into parentheses str format + targets = [ + '('+' '.join(tar)+')' if isinstance(tar, tuple) else tar + for tar in targets + ] + if len(targets) != len(gtargets) or not all(t in gtargets for t in targets): + raise AssertionError( + "'sources_status' returns different targets than the compiled targets\n" + "%s != %s" % (targets, gtargets) + ) + # return targets from 'sources_status' since the order is matters + return targets, gflags + + def arg_regex(self, **kwargs): + map2origin = dict( + x64 = "x86", + ppc64le = "ppc64", + aarch64 = "armhf", + clang = "gcc", + ) + march = self.march(); cc_name = self.cc_name() + map_march = map2origin.get(march, march) + map_cc = map2origin.get(cc_name, cc_name) + for key in ( + march, cc_name, map_march, map_cc, + march + '_' + cc_name, + map_march + '_' + cc_name, + march + '_' + map_cc, + map_march + '_' + map_cc, + ) : + regex = kwargs.pop(key, None) + if regex is not None: + break + if regex: + if isinstance(regex, dict): + for k, v in regex.items(): + if v[-1:] not in ')}$?\\.+*': + regex[k] = v + '$' + else: + assert(isinstance(regex, str)) + if regex[-1:] not in ')}$?\\.+*': + regex += '$' + return regex + + def expect(self, dispatch, baseline="", **kwargs): + match = self.arg_regex(**kwargs) + if match is None: + return + opt = self.nopt( + cpu_baseline=baseline, cpu_dispatch=dispatch, + trap_files=kwargs.get("trap_files", ""), + trap_flags=kwargs.get("trap_flags", "") + ) + features = ' '.join(opt.cpu_dispatch_names()) + if not match: + if len(features) != 0: + raise AssertionError( + 'expected empty features, not "%s"' % features + ) + return + if not re.match(match, features, re.IGNORECASE): + raise AssertionError( + 'dispatch features "%s" not match "%s"' % (features, match) + ) + + def expect_baseline(self, baseline, dispatch="", **kwargs): + match = self.arg_regex(**kwargs) + if match is None: + return + opt = self.nopt( + cpu_baseline=baseline, cpu_dispatch=dispatch, + trap_files=kwargs.get("trap_files", ""), + trap_flags=kwargs.get("trap_flags", "") + ) + features = ' '.join(opt.cpu_baseline_names()) + if not match: + if len(features) != 0: + raise AssertionError( + 'expected empty features, not "%s"' % features + ) + return + if not re.match(match, features, re.IGNORECASE): + raise AssertionError( + 'baseline features "%s" not match "%s"' % (features, match) + ) + + def expect_flags(self, baseline, dispatch="", **kwargs): + match = self.arg_regex(**kwargs) + if match is None: + return + opt = self.nopt( + cpu_baseline=baseline, cpu_dispatch=dispatch, + trap_files=kwargs.get("trap_files", ""), + trap_flags=kwargs.get("trap_flags", "") + ) + flags = ' '.join(opt.cpu_baseline_flags()) + if not match: + if len(flags) != 0: + raise AssertionError( + 'expected empty flags not "%s"' % flags + ) + return + if not re.match(match, flags): + raise AssertionError( + 'flags "%s" not match "%s"' % (flags, match) + ) + + def expect_targets(self, targets, groups={}, **kwargs): + match = self.arg_regex(**kwargs) + if match is None: + return + targets, _ = self.get_targets(targets=targets, groups=groups, **kwargs) + targets = ' '.join(targets) + if not match: + if len(targets) != 0: + raise AssertionError( + 'expected empty targets, not "%s"' % targets + ) + return + if not re.match(match, targets, re.IGNORECASE): + raise AssertionError( + 'targets "%s" not match "%s"' % (targets, match) + ) + + def expect_target_flags(self, targets, groups={}, **kwargs): + match_dict = self.arg_regex(**kwargs) + if match_dict is None: + return + assert(isinstance(match_dict, dict)) + _, tar_flags = self.get_targets(targets=targets, groups=groups) + + for match_tar, match_flags in match_dict.items(): + if match_tar not in tar_flags: + raise AssertionError( + 'expected to find target "%s"' % match_tar + ) + flags = tar_flags[match_tar] + if not match_flags: + if len(flags) != 0: + raise AssertionError( + 'expected to find empty flags in target "%s"' % match_tar + ) + if not re.match(match_flags, flags): + raise AssertionError( + '"%s" flags "%s" not match "%s"' % (match_tar, flags, match_flags) + ) + + def test_interface(self): + wrong_arch = "ppc64" if self.arch != "ppc64" else "x86" + wrong_cc = "clang" if self.cc != "clang" else "icc" + opt = self.opt() + assert_(getattr(opt, "cc_on_" + self.arch)) + assert_(not getattr(opt, "cc_on_" + wrong_arch)) + assert_(getattr(opt, "cc_is_" + self.cc)) + assert_(not getattr(opt, "cc_is_" + wrong_cc)) + + def test_args_empty(self): + for baseline, dispatch in ( + ("", "none"), + (None, ""), + ("none +none", "none - none"), + ("none -max", "min - max"), + ("+vsx2 -VSX2", "vsx avx2 avx512f -max"), + ("max -vsx - avx + avx512f neon -MAX ", + "min -min + max -max -vsx + avx2 -avx2 +NONE") + ) : + opt = self.nopt(cpu_baseline=baseline, cpu_dispatch=dispatch) + assert(len(opt.cpu_baseline_names()) == 0) + assert(len(opt.cpu_dispatch_names()) == 0) + + def test_args_validation(self): + if self.march() == "unknown": + return + # check sanity of argument's validation + for baseline, dispatch in ( + ("unkown_feature - max +min", "unknown max min"), # unknowing features + ("#avx2", "$vsx") # groups and polices aren't acceptable + ) : + try: + self.nopt(cpu_baseline=baseline, cpu_dispatch=dispatch) + raise AssertionError("excepted an exception for invalid arguments") + except DistutilsError: + pass + + def test_skip(self): + # only takes what platform supports and skip the others + # without casing exceptions + self.expect( + "sse vsx neon", + x86="sse", ppc64="vsx", armhf="neon", unknown="" + ) + self.expect( + "sse41 avx avx2 vsx2 vsx3 neon_vfpv4 asimd", + x86 = "sse41 avx avx2", + ppc64 = "vsx2 vsx3", + armhf = "neon_vfpv4 asimd", + unknown = "" + ) + # any features in cpu_dispatch must be ignored if it's part of baseline + self.expect( + "sse neon vsx", baseline="sse neon vsx", + x86="", ppc64="", armhf="" + ) + self.expect( + "avx2 vsx3 asimdhp", baseline="avx2 vsx3 asimdhp", + x86="", ppc64="", armhf="" + ) + + def test_implies(self): + # baseline combining implied features, so we count + # on it instead of testing 'feature_implies()'' directly + self.expect_baseline( + "fma3 avx2 asimd vsx3", + # .* between two spaces can validate features in between + x86 = "sse .* sse41 .* fma3.*avx2", + ppc64 = "vsx vsx2 vsx3", + armhf = "neon neon_fp16 neon_vfpv4 asimd" + ) + """ + special cases + """ + # in icc and msvc, FMA3 and AVX2 can't be separated + # both need to implies each other, same for avx512f & cd + for f0, f1 in ( + ("fma3", "avx2"), + ("avx512f", "avx512cd"), + ): + diff = ".* sse42 .* %s .*%s$" % (f0, f1) + self.expect_baseline(f0, + x86_gcc=".* sse42 .* %s$" % f0, + x86_icc=diff, x86_iccw=diff + ) + self.expect_baseline(f1, + x86_gcc=".* avx .* %s$" % f1, + x86_icc=diff, x86_iccw=diff + ) + # in msvc, following features can't be separated too + for f in (("fma3", "avx2"), ("avx512f", "avx512cd", "avx512_skx")): + for ff in f: + self.expect_baseline(ff, + x86_msvc=".*%s" % ' '.join(f) + ) + + # in ppc64le VSX and VSX2 can't be separated + self.expect_baseline("vsx", ppc64le="vsx vsx2") + # in aarch64 following features can't be separated + for f in ("neon", "neon_fp16", "neon_vfpv4", "asimd"): + self.expect_baseline(f, aarch64="neon neon_fp16 neon_vfpv4 asimd") + + def test_args_options(self): + # max & native + for o in ("max", "native"): + if o == "native" and self.cc_name() == "msvc": + continue + self.expect(o, + trap_files=".*cpu_(sse|vsx|neon).c", + x86="", ppc64="", armhf="" + ) + self.expect(o, + trap_files=".*cpu_(sse3|vsx2|neon_vfpv4).c", + x86="sse sse2", ppc64="vsx", armhf="neon neon_fp16", + aarch64="", ppc64le="" + ) + self.expect(o, + trap_files=".*cpu_(popcnt|vsx3).c", + x86="sse .* sse41", ppc64="vsx vsx2", + armhf="neon neon_fp16 .* asimd .*" + ) + self.expect(o, + x86_gcc=".* xop fma4 .* avx512f .* avx512_knl avx512_knm avx512_skx .*", + # in icc, xop and fam4 aren't supported + x86_icc=".* avx512f .* avx512_knl avx512_knm avx512_skx .*", + x86_iccw=".* avx512f .* avx512_knl avx512_knm avx512_skx .*", + # in msvc, avx512_knl avx512_knm aren't supported + x86_msvc=".* xop fma4 .* avx512f .* avx512_skx .*", + armhf=".* asimd asimdhp asimddp .*", + ppc64="vsx vsx2 vsx3.*" + ) + # min + self.expect("min", + x86="sse sse2", x64="sse sse2 sse3", + armhf="", aarch64="neon neon_fp16 .* asimd", + ppc64="", ppc64le="vsx vsx2" + ) + self.expect( + "min", trap_files=".*cpu_(sse2|vsx2).c", + x86="", ppc64le="" + ) + # an exception must triggered if native flag isn't supported + # when option "native" is activated through the args + try: + self.expect("native", + trap_flags=".*(-march=native|-xHost|/QxHost).*", + x86=".*", ppc64=".*", armhf=".*" + ) + if self.march() != "unknown": + raise AssertionError( + "excepted an exception for %s" % self.march() + ) + except DistutilsError: + if self.march() == "unknown": + raise AssertionError("excepted no exceptions") + + def test_flags(self): + self.expect_flags( + "sse sse2 vsx vsx2 neon neon_fp16", + x86_gcc="-msse -msse2", x86_icc="-msse -msse2", + x86_iccw="/arch:SSE2", x86_msvc="/arch:SSE2", + ppc64_gcc= "-mcpu=power8", + ppc64_clang="-maltivec -mvsx -mpower8-vector", + armhf_gcc="-mfpu=neon-fp16 -mfp16-format=ieee", + aarch64="" + ) + # testing normalize -march + self.expect_flags( + "asimd", + aarch64="", + armhf_gcc=r"-mfp16-format=ieee -mfpu=neon-fp-armv8 -march=armv8-a\+simd" + ) + self.expect_flags( + "asimdhp", + aarch64_gcc=r"-march=armv8.2-a\+fp16", + armhf_gcc=r"-mfp16-format=ieee -mfpu=neon-fp-armv8 -march=armv8.2-a\+fp16" + ) + self.expect_flags( + "asimddp", aarch64_gcc=r"-march=armv8.2-a\+dotprod" + ) + self.expect_flags( + # asimdfhm implies asimdhp + "asimdfhm", aarch64_gcc=r"-march=armv8.2-a\+fp16\+fp16fml" + ) + self.expect_flags( + "asimddp asimdhp asimdfhm", + aarch64_gcc=r"-march=armv8.2-a\+dotprod\+fp16\+fp16fml" + ) + + def test_targets_exceptions(self): + for targets in ( + "bla bla", "/*@targets", + "/*@targets */", + "/*@targets unknown */", + "/*@targets $unknown_policy avx2 */", + "/*@targets #unknown_group avx2 */", + "/*@targets $ */", + "/*@targets # vsx */", + "/*@targets #$ vsx */", + "/*@targets vsx avx2 ) */", + "/*@targets vsx avx2 (avx2 */", + "/*@targets vsx avx2 () */", + "/*@targets vsx avx2 ($autovec) */", # no features + "/*@targets vsx avx2 (xxx) */", + "/*@targets vsx avx2 (baseline) */", + ) : + try: + self.expect_targets( + targets, + x86="", armhf="", ppc64="" + ) + if self.march() != "unknown": + raise AssertionError( + "excepted an exception for %s" % self.march() + ) + except DistutilsError: + if self.march() == "unknown": + raise AssertionError("excepted no exceptions") + + def test_targets_syntax(self): + for targets in ( + "/*@targets $keep_baseline sse vsx neon*/", + "/*@targets,$keep_baseline,sse,vsx,neon*/", + "/*@targets*$keep_baseline*sse*vsx*neon*/", + """ + /* + ** @targets + ** $keep_baseline, sse vsx,neon + */ + """, + """ + /* + ************@targets************* + ** $keep_baseline, sse vsx, neon + ********************************* + */ + """, + """ + /* + /////////////@targets///////////////// + //$keep_baseline//sse//vsx//neon + ///////////////////////////////////// + */ + """, + """ + /* + @targets + $keep_baseline + SSE VSX NEON*/ + """ + ) : + self.expect_targets(targets, + x86="sse", ppc64="vsx", armhf="neon", unknown="" + ) + + def test_targets(self): + # test skipping baseline features + self.expect_targets( + """ + /*@targets + sse sse2 sse41 avx avx2 avx512f + vsx vsx2 vsx3 + neon neon_fp16 asimdhp asimddp + */ + """, + baseline="avx vsx2 asimd", + x86="avx512f avx2", armhf="asimddp asimdhp", ppc64="vsx3" + ) + # test skipping non-dispatch features + self.expect_targets( + """ + /*@targets + sse41 avx avx2 avx512f + vsx2 vsx3 + asimd asimdhp asimddp + */ + """, + baseline="", dispatch="sse41 avx2 vsx2 asimd asimddp", + x86="avx2 sse41", armhf="asimddp asimd", ppc64="vsx2" + ) + # test skipping features that not supported + self.expect_targets( + """ + /*@targets + sse2 sse41 avx2 avx512f + vsx2 vsx3 + neon asimdhp asimddp + */ + """, + baseline="", + trap_files=".*(avx2|avx512f|vsx3|asimddp).c", + x86="sse41 sse2", ppc64="vsx2", armhf="asimdhp neon" + ) + # test skipping features that implies each other + self.expect_targets( + """ + /*@targets + sse sse2 avx fma3 avx2 avx512f avx512cd + vsx vsx2 vsx3 + neon neon_vfpv4 neon_fp16 neon_fp16 asimd asimdhp + asimddp asimdfhm + */ + """, + baseline="", + x86_gcc="avx512cd avx512f avx2 fma3 avx sse2", + x86_msvc="avx512cd avx2 avx sse2", + x86_icc="avx512cd avx2 avx sse2", + x86_iccw="avx512cd avx2 avx sse2", + ppc64="vsx3 vsx2 vsx", + ppc64le="vsx3 vsx2", + armhf="asimdfhm asimddp asimdhp asimd neon_vfpv4 neon_fp16 neon", + aarch64="asimdfhm asimddp asimdhp asimd" + ) + + def test_targets_policies(self): + # 'keep_baseline', generate objects for baseline features + self.expect_targets( + """ + /*@targets + $keep_baseline + sse2 sse42 avx2 avx512f + vsx2 vsx3 + neon neon_vfpv4 asimd asimddp + */ + """, + baseline="sse41 avx2 vsx2 asimd vsx3", + x86="avx512f avx2 sse42 sse2", + ppc64="vsx3 vsx2", + armhf="asimddp asimd neon_vfpv4 neon", + # neon, neon_vfpv4, asimd implies each other + aarch64="asimddp asimd" + ) + # 'keep_sort', leave the sort as-is + self.expect_targets( + """ + /*@targets + $keep_baseline $keep_sort + avx512f sse42 avx2 sse2 + vsx2 vsx3 + asimd neon neon_vfpv4 asimddp + */ + """, + x86="avx512f sse42 avx2 sse2", + ppc64="vsx2 vsx3", + armhf="asimd neon neon_vfpv4 asimddp", + # neon, neon_vfpv4, asimd implies each other + aarch64="asimd asimddp" + ) + # 'autovec', skipping features that can't be + # vectorized by the compiler + self.expect_targets( + """ + /*@targets + $keep_baseline $keep_sort $autovec + avx512f avx2 sse42 sse41 sse2 + vsx3 vsx2 + asimddp asimd neon_vfpv4 neon + */ + """, + x86_gcc="avx512f avx2 sse42 sse41 sse2", + x86_icc="avx512f avx2 sse42 sse41 sse2", + x86_iccw="avx512f avx2 sse42 sse41 sse2", + x86_msvc="avx512f avx2 sse2", + ppc64="vsx3 vsx2", + armhf="asimddp asimd neon_vfpv4 neon", + # neon, neon_vfpv4, asimd implies each other + aarch64="asimddp asimd" + ) + for policy in ("$maxopt", "$autovec"): + # 'maxopt' and autovec set the max acceptable optimization flags + self.expect_target_flags( + "/*@targets baseline %s */" % policy, + gcc={"baseline":".*-O3.*"}, icc={"baseline":".*-O3.*"}, + iccw={"baseline":".*/O3.*"}, msvc={"baseline":".*/O2.*"}, + unknown={"baseline":".*"} + ) + + # 'werror', force compilers to treat warnings as errors + self.expect_target_flags( + "/*@targets baseline $werror */", + gcc={"baseline":".*-Werror.*"}, icc={"baseline":".*-Werror.*"}, + iccw={"baseline":".*/Werror.*"}, msvc={"baseline":".*/WX.*"}, + unknown={"baseline":".*"} + ) + + def test_targets_groups(self): + self.expect_targets( + """ + /*@targets $keep_baseline baseline #test_group */ + """, + groups=dict( + test_group=(""" + $keep_baseline + asimddp sse2 vsx2 avx2 vsx3 + avx512f asimdhp + """) + ), + x86="avx512f avx2 sse2 baseline", + ppc64="vsx3 vsx2 baseline", + armhf="asimddp asimdhp baseline" + ) + # test skip duplicating and sorting + self.expect_targets( + """ + /*@targets + * sse42 avx avx512f + * #test_group_1 + * vsx2 + * #test_group_2 + * asimddp asimdfhm + */ + """, + groups=dict( + test_group_1=(""" + VSX2 vsx3 asimd avx2 SSE41 + """), + test_group_2=(""" + vsx2 vsx3 asImd aVx2 sse41 + """) + ), + x86="avx512f avx2 avx sse42 sse41", + ppc64="vsx3 vsx2", + # vsx2 part of the default baseline of ppc64le, option ("min") + ppc64le="vsx3", + armhf="asimdfhm asimddp asimd", + # asimd part of the default baseline of aarch64, option ("min") + aarch64="asimdfhm asimddp" + ) + + def test_targets_multi(self): + self.expect_targets( + """ + /*@targets + (avx512_clx avx512_cnl) (asimdhp asimddp) + */ + """, + x86=r"\(avx512_clx avx512_cnl\)", + armhf=r"\(asimdhp asimddp\)", + ) + # test skipping implied features and auto-sort + self.expect_targets( + """ + /*@targets + f16c (sse41 avx sse42) (sse3 avx2 avx512f) + vsx2 (vsx vsx3 vsx2) + (neon neon_vfpv4 asimd asimdhp asimddp) + */ + """, + x86="avx512f f16c avx", + ppc64="vsx3 vsx2", + ppc64le="vsx3", # vsx2 part of baseline + armhf=r"\(asimdhp asimddp\)", + ) + # test skipping implied features and keep sort + self.expect_targets( + """ + /*@targets $keep_sort + (sse41 avx sse42) (sse3 avx2 avx512f) + (vsx vsx3 vsx2) + (asimddp neon neon_vfpv4 asimd asimdhp) + */ + """, + x86="avx avx512f", + ppc64="vsx3", + armhf=r"\(asimdhp asimddp\)", + ) + # test compiler variety and avoiding duplicating + self.expect_targets( + """ + /*@targets $keep_sort + fma3 avx2 (fma3 avx2) (avx2 fma3) avx2 fma3 + */ + """, + x86_gcc=r"fma3 avx2 \(fma3 avx2\)", + x86_icc="avx2", x86_iccw="avx2", + x86_msvc="avx2" + ) + +def new_test(arch, cc): + if is_standalone: return textwrap.dedent("""\ + class TestCCompilerOpt_{class_name}(_Test_CCompilerOpt, unittest.TestCase): + arch = '{arch}' + cc = '{cc}' + def __init__(self, methodName="runTest"): + unittest.TestCase.__init__(self, methodName) + self.setup() + """).format( + class_name=arch + '_' + cc, arch=arch, cc=cc + ) + return textwrap.dedent("""\ + class TestCCompilerOpt_{class_name}(_Test_CCompilerOpt): + arch = '{arch}' + cc = '{cc}' + """).format( + class_name=arch + '_' + cc, arch=arch, cc=cc + ) +""" +if 1 and is_standalone: + FakeCCompilerOpt.fake_info = "x86_icc" + cco = FakeCCompilerOpt(None, cpu_baseline="avx2") + print(' '.join(cco.cpu_baseline_names())) + print(cco.cpu_baseline_flags()) + unittest.main() + sys.exit() +""" +for arch, compilers in arch_compilers.items(): + for cc in compilers: + exec(new_test(arch, cc)) + +if is_standalone: + unittest.main() diff --git a/venv/Lib/site-packages/numpy/distutils/tests/test_ccompiler_opt_conf.py b/venv/Lib/site-packages/numpy/distutils/tests/test_ccompiler_opt_conf.py new file mode 100644 index 0000000..09c1fad --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/tests/test_ccompiler_opt_conf.py @@ -0,0 +1,176 @@ +import unittest +from os import sys, path + +is_standalone = __name__ == '__main__' and __package__ is None +if is_standalone: + sys.path.append(path.abspath(path.join(path.dirname(__file__), ".."))) + from ccompiler_opt import CCompilerOpt +else: + from numpy.distutils.ccompiler_opt import CCompilerOpt + +arch_compilers = dict( + x86 = ("gcc", "clang", "icc", "iccw", "msvc"), + x64 = ("gcc", "clang", "icc", "iccw", "msvc"), + ppc64 = ("gcc", "clang"), + ppc64le = ("gcc", "clang"), + armhf = ("gcc", "clang"), + aarch64 = ("gcc", "clang"), + narch = ("gcc",) +) + +class FakeCCompilerOpt(CCompilerOpt): + fake_info = ("arch", "compiler", "extra_args") + def __init__(self, *args, **kwargs): + CCompilerOpt.__init__(self, None, **kwargs) + def dist_compile(self, sources, flags, **kwargs): + return sources + def dist_info(self): + return FakeCCompilerOpt.fake_info + @staticmethod + def dist_log(*args, stderr=False): + pass + +class _TestConfFeatures(FakeCCompilerOpt): + """A hook to check the sanity of configured features +- before it called by the abstract class '_Feature' + """ + + def conf_features_partial(self): + conf_all = self.conf_features + for feature_name, feature in conf_all.items(): + self.test_feature( + "attribute conf_features", + conf_all, feature_name, feature + ) + + conf_partial = FakeCCompilerOpt.conf_features_partial(self) + for feature_name, feature in conf_partial.items(): + self.test_feature( + "conf_features_partial()", + conf_partial, feature_name, feature + ) + return conf_partial + + def test_feature(self, log, search_in, feature_name, feature_dict): + error_msg = ( + "during validate '{}' within feature '{}', " + "march '{}' and compiler '{}'\n>> " + ).format(log, feature_name, self.cc_march, self.cc_name) + + if not feature_name.isupper(): + raise AssertionError(error_msg + "feature name must be in uppercase") + + for option, val in feature_dict.items(): + self.test_option_types(error_msg, option, val) + self.test_duplicates(error_msg, option, val) + + self.test_implies(error_msg, search_in, feature_name, feature_dict) + self.test_group(error_msg, search_in, feature_name, feature_dict) + self.test_extra_checks(error_msg, search_in, feature_name, feature_dict) + + def test_option_types(self, error_msg, option, val): + for tp, available in ( + ((str, list), ( + "implies", "headers", "flags", "group", "detect", "extra_checks" + )), + ((str,), ("disable",)), + ((int,), ("interest",)), + ((bool,), ("implies_detect",)), + ((bool, type(None)), ("autovec",)), + ) : + found_it = option in available + if not found_it: + continue + if not isinstance(val, tp): + error_tp = [t.__name__ for t in (*tp,)] + error_tp = ' or '.join(error_tp) + raise AssertionError(error_msg + + "expected '%s' type for option '%s' not '%s'" % ( + error_tp, option, type(val).__name__ + )) + break + + if not found_it: + raise AssertionError(error_msg + "invalid option name '%s'" % option) + + def test_duplicates(self, error_msg, option, val): + if option not in ( + "implies", "headers", "flags", "group", "detect", "extra_checks" + ) : return + + if isinstance(val, str): + val = val.split() + + if len(val) != len(set(val)): + raise AssertionError(error_msg + "duplicated values in option '%s'" % option) + + def test_implies(self, error_msg, search_in, feature_name, feature_dict): + if feature_dict.get("disabled") is not None: + return + implies = feature_dict.get("implies", "") + if not implies: + return + if isinstance(implies, str): + implies = implies.split() + + if feature_name in implies: + raise AssertionError(error_msg + "feature implies itself") + + for impl in implies: + impl_dict = search_in.get(impl) + if impl_dict is not None: + if "disable" in impl_dict: + raise AssertionError(error_msg + "implies disabled feature '%s'" % impl) + continue + raise AssertionError(error_msg + "implies non-exist feature '%s'" % impl) + + def test_group(self, error_msg, search_in, feature_name, feature_dict): + if feature_dict.get("disabled") is not None: + return + group = feature_dict.get("group", "") + if not group: + return + if isinstance(group, str): + group = group.split() + + for f in group: + impl_dict = search_in.get(f) + if not impl_dict or "disable" in impl_dict: + continue + raise AssertionError(error_msg + + "in option 'group', '%s' already exists as a feature name" % f + ) + + def test_extra_checks(self, error_msg, search_in, feature_name, feature_dict): + if feature_dict.get("disabled") is not None: + return + extra_checks = feature_dict.get("extra_checks", "") + if not extra_checks: + return + if isinstance(extra_checks, str): + extra_checks = extra_checks.split() + + for f in extra_checks: + impl_dict = search_in.get(f) + if not impl_dict or "disable" in impl_dict: + continue + raise AssertionError(error_msg + + "in option 'extra_checks', extra test case '%s' already exists as a feature name" % f + ) + +class TestConfFeatures(unittest.TestCase): + def __init__(self, methodName="runTest"): + unittest.TestCase.__init__(self, methodName) + self.setup() + + def setup(self): + FakeCCompilerOpt.conf_nocache = True + + def test_features(self): + for arch, compilers in arch_compilers.items(): + for cc in compilers: + FakeCCompilerOpt.fake_info = (arch, cc, "") + _TestConfFeatures() + +if is_standalone: + unittest.main() diff --git a/venv/Lib/site-packages/numpy/distutils/tests/test_exec_command.py b/venv/Lib/site-packages/numpy/distutils/tests/test_exec_command.py new file mode 100644 index 0000000..d6eb7d1 --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/tests/test_exec_command.py @@ -0,0 +1,214 @@ +import os +import sys +from tempfile import TemporaryFile + +from numpy.distutils import exec_command +from numpy.distutils.exec_command import get_pythonexe +from numpy.testing import tempdir, assert_, assert_warns + +# In python 3 stdout, stderr are text (unicode compliant) devices, so to +# emulate them import StringIO from the io module. +from io import StringIO + +class redirect_stdout: + """Context manager to redirect stdout for exec_command test.""" + def __init__(self, stdout=None): + self._stdout = stdout or sys.stdout + + def __enter__(self): + self.old_stdout = sys.stdout + sys.stdout = self._stdout + + def __exit__(self, exc_type, exc_value, traceback): + self._stdout.flush() + sys.stdout = self.old_stdout + # note: closing sys.stdout won't close it. + self._stdout.close() + +class redirect_stderr: + """Context manager to redirect stderr for exec_command test.""" + def __init__(self, stderr=None): + self._stderr = stderr or sys.stderr + + def __enter__(self): + self.old_stderr = sys.stderr + sys.stderr = self._stderr + + def __exit__(self, exc_type, exc_value, traceback): + self._stderr.flush() + sys.stderr = self.old_stderr + # note: closing sys.stderr won't close it. + self._stderr.close() + +class emulate_nonposix: + """Context manager to emulate os.name != 'posix' """ + def __init__(self, osname='non-posix'): + self._new_name = osname + + def __enter__(self): + self._old_name = os.name + os.name = self._new_name + + def __exit__(self, exc_type, exc_value, traceback): + os.name = self._old_name + + +def test_exec_command_stdout(): + # Regression test for gh-2999 and gh-2915. + # There are several packages (nose, scipy.weave.inline, Sage inline + # Fortran) that replace stdout, in which case it doesn't have a fileno + # method. This is tested here, with a do-nothing command that fails if the + # presence of fileno() is assumed in exec_command. + + # The code has a special case for posix systems, so if we are on posix test + # both that the special case works and that the generic code works. + + # Test posix version: + with redirect_stdout(StringIO()): + with redirect_stderr(TemporaryFile()): + with assert_warns(DeprecationWarning): + exec_command.exec_command("cd '.'") + + if os.name == 'posix': + # Test general (non-posix) version: + with emulate_nonposix(): + with redirect_stdout(StringIO()): + with redirect_stderr(TemporaryFile()): + with assert_warns(DeprecationWarning): + exec_command.exec_command("cd '.'") + +def test_exec_command_stderr(): + # Test posix version: + with redirect_stdout(TemporaryFile(mode='w+')): + with redirect_stderr(StringIO()): + with assert_warns(DeprecationWarning): + exec_command.exec_command("cd '.'") + + if os.name == 'posix': + # Test general (non-posix) version: + with emulate_nonposix(): + with redirect_stdout(TemporaryFile()): + with redirect_stderr(StringIO()): + with assert_warns(DeprecationWarning): + exec_command.exec_command("cd '.'") + + +class TestExecCommand: + def setup(self): + self.pyexe = get_pythonexe() + + def check_nt(self, **kws): + s, o = exec_command.exec_command('cmd /C echo path=%path%') + assert_(s == 0) + assert_(o != '') + + s, o = exec_command.exec_command( + '"%s" -c "import sys;sys.stderr.write(sys.platform)"' % self.pyexe) + assert_(s == 0) + assert_(o == 'win32') + + def check_posix(self, **kws): + s, o = exec_command.exec_command("echo Hello", **kws) + assert_(s == 0) + assert_(o == 'Hello') + + s, o = exec_command.exec_command('echo $AAA', **kws) + assert_(s == 0) + assert_(o == '') + + s, o = exec_command.exec_command('echo "$AAA"', AAA='Tere', **kws) + assert_(s == 0) + assert_(o == 'Tere') + + s, o = exec_command.exec_command('echo "$AAA"', **kws) + assert_(s == 0) + assert_(o == '') + + if 'BBB' not in os.environ: + os.environ['BBB'] = 'Hi' + s, o = exec_command.exec_command('echo "$BBB"', **kws) + assert_(s == 0) + assert_(o == 'Hi') + + s, o = exec_command.exec_command('echo "$BBB"', BBB='Hey', **kws) + assert_(s == 0) + assert_(o == 'Hey') + + s, o = exec_command.exec_command('echo "$BBB"', **kws) + assert_(s == 0) + assert_(o == 'Hi') + + del os.environ['BBB'] + + s, o = exec_command.exec_command('echo "$BBB"', **kws) + assert_(s == 0) + assert_(o == '') + + + s, o = exec_command.exec_command('this_is_not_a_command', **kws) + assert_(s != 0) + assert_(o != '') + + s, o = exec_command.exec_command('echo path=$PATH', **kws) + assert_(s == 0) + assert_(o != '') + + s, o = exec_command.exec_command( + '"%s" -c "import sys,os;sys.stderr.write(os.name)"' % + self.pyexe, **kws) + assert_(s == 0) + assert_(o == 'posix') + + def check_basic(self, *kws): + s, o = exec_command.exec_command( + '"%s" -c "raise \'Ignore me.\'"' % self.pyexe, **kws) + assert_(s != 0) + assert_(o != '') + + s, o = exec_command.exec_command( + '"%s" -c "import sys;sys.stderr.write(\'0\');' + 'sys.stderr.write(\'1\');sys.stderr.write(\'2\')"' % + self.pyexe, **kws) + assert_(s == 0) + assert_(o == '012') + + s, o = exec_command.exec_command( + '"%s" -c "import sys;sys.exit(15)"' % self.pyexe, **kws) + assert_(s == 15) + assert_(o == '') + + s, o = exec_command.exec_command( + '"%s" -c "print(\'Heipa\'")' % self.pyexe, **kws) + assert_(s == 0) + assert_(o == 'Heipa') + + def check_execute_in(self, **kws): + with tempdir() as tmpdir: + fn = "file" + tmpfile = os.path.join(tmpdir, fn) + with open(tmpfile, 'w') as f: + f.write('Hello') + + s, o = exec_command.exec_command( + '"%s" -c "f = open(\'%s\', \'r\'); f.close()"' % + (self.pyexe, fn), **kws) + assert_(s != 0) + assert_(o != '') + s, o = exec_command.exec_command( + '"%s" -c "f = open(\'%s\', \'r\'); print(f.read()); ' + 'f.close()"' % (self.pyexe, fn), execute_in=tmpdir, **kws) + assert_(s == 0) + assert_(o == 'Hello') + + def test_basic(self): + with redirect_stdout(StringIO()): + with redirect_stderr(StringIO()): + with assert_warns(DeprecationWarning): + if os.name == "posix": + self.check_posix(use_tee=0) + self.check_posix(use_tee=1) + elif os.name == "nt": + self.check_nt(use_tee=0) + self.check_nt(use_tee=1) + self.check_execute_in(use_tee=0) + self.check_execute_in(use_tee=1) diff --git a/venv/Lib/site-packages/numpy/distutils/tests/test_fcompiler.py b/venv/Lib/site-packages/numpy/distutils/tests/test_fcompiler.py new file mode 100644 index 0000000..dd97f1e --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/tests/test_fcompiler.py @@ -0,0 +1,43 @@ +from numpy.testing import assert_ +import numpy.distutils.fcompiler + +customizable_flags = [ + ('f77', 'F77FLAGS'), + ('f90', 'F90FLAGS'), + ('free', 'FREEFLAGS'), + ('arch', 'FARCH'), + ('debug', 'FDEBUG'), + ('flags', 'FFLAGS'), + ('linker_so', 'LDFLAGS'), +] + + +def test_fcompiler_flags(monkeypatch): + monkeypatch.setenv('NPY_DISTUTILS_APPEND_FLAGS', '0') + fc = numpy.distutils.fcompiler.new_fcompiler(compiler='none') + flag_vars = fc.flag_vars.clone(lambda *args, **kwargs: None) + + for opt, envvar in customizable_flags: + new_flag = '-dummy-{}-flag'.format(opt) + prev_flags = getattr(flag_vars, opt) + + monkeypatch.setenv(envvar, new_flag) + new_flags = getattr(flag_vars, opt) + + monkeypatch.delenv(envvar) + assert_(new_flags == [new_flag]) + + monkeypatch.setenv('NPY_DISTUTILS_APPEND_FLAGS', '1') + + for opt, envvar in customizable_flags: + new_flag = '-dummy-{}-flag'.format(opt) + prev_flags = getattr(flag_vars, opt) + monkeypatch.setenv(envvar, new_flag) + new_flags = getattr(flag_vars, opt) + + monkeypatch.delenv(envvar) + if prev_flags is None: + assert_(new_flags == [new_flag]) + else: + assert_(new_flags == prev_flags + [new_flag]) + diff --git a/venv/Lib/site-packages/numpy/distutils/tests/test_fcompiler_gnu.py b/venv/Lib/site-packages/numpy/distutils/tests/test_fcompiler_gnu.py new file mode 100644 index 0000000..0817ae5 --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/tests/test_fcompiler_gnu.py @@ -0,0 +1,55 @@ +from numpy.testing import assert_ + +import numpy.distutils.fcompiler + +g77_version_strings = [ + ('GNU Fortran 0.5.25 20010319 (prerelease)', '0.5.25'), + ('GNU Fortran (GCC 3.2) 3.2 20020814 (release)', '3.2'), + ('GNU Fortran (GCC) 3.3.3 20040110 (prerelease) (Debian)', '3.3.3'), + ('GNU Fortran (GCC) 3.3.3 (Debian 20040401)', '3.3.3'), + ('GNU Fortran (GCC 3.2.2 20030222 (Red Hat Linux 3.2.2-5)) 3.2.2' + ' 20030222 (Red Hat Linux 3.2.2-5)', '3.2.2'), +] + +gfortran_version_strings = [ + ('GNU Fortran 95 (GCC 4.0.3 20051023 (prerelease) (Debian 4.0.2-3))', + '4.0.3'), + ('GNU Fortran 95 (GCC) 4.1.0', '4.1.0'), + ('GNU Fortran 95 (GCC) 4.2.0 20060218 (experimental)', '4.2.0'), + ('GNU Fortran (GCC) 4.3.0 20070316 (experimental)', '4.3.0'), + ('GNU Fortran (rubenvb-4.8.0) 4.8.0', '4.8.0'), + ('4.8.0', '4.8.0'), + ('4.0.3-7', '4.0.3'), + ("gfortran: warning: couldn't understand kern.osversion '14.1.0\n4.9.1", + '4.9.1'), + ("gfortran: warning: couldn't understand kern.osversion '14.1.0\n" + "gfortran: warning: yet another warning\n4.9.1", + '4.9.1'), + ('GNU Fortran (crosstool-NG 8a21ab48) 7.2.0', '7.2.0') +] + +class TestG77Versions: + def test_g77_version(self): + fc = numpy.distutils.fcompiler.new_fcompiler(compiler='gnu') + for vs, version in g77_version_strings: + v = fc.version_match(vs) + assert_(v == version, (vs, v)) + + def test_not_g77(self): + fc = numpy.distutils.fcompiler.new_fcompiler(compiler='gnu') + for vs, _ in gfortran_version_strings: + v = fc.version_match(vs) + assert_(v is None, (vs, v)) + +class TestGFortranVersions: + def test_gfortran_version(self): + fc = numpy.distutils.fcompiler.new_fcompiler(compiler='gnu95') + for vs, version in gfortran_version_strings: + v = fc.version_match(vs) + assert_(v == version, (vs, v)) + + def test_not_gfortran(self): + fc = numpy.distutils.fcompiler.new_fcompiler(compiler='gnu95') + for vs, _ in g77_version_strings: + v = fc.version_match(vs) + assert_(v is None, (vs, v)) diff --git a/venv/Lib/site-packages/numpy/distutils/tests/test_fcompiler_intel.py b/venv/Lib/site-packages/numpy/distutils/tests/test_fcompiler_intel.py new file mode 100644 index 0000000..45c9cda --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/tests/test_fcompiler_intel.py @@ -0,0 +1,30 @@ +import numpy.distutils.fcompiler +from numpy.testing import assert_ + + +intel_32bit_version_strings = [ + ("Intel(R) Fortran Intel(R) 32-bit Compiler Professional for applications" + "running on Intel(R) 32, Version 11.1", '11.1'), +] + +intel_64bit_version_strings = [ + ("Intel(R) Fortran IA-64 Compiler Professional for applications" + "running on IA-64, Version 11.0", '11.0'), + ("Intel(R) Fortran Intel(R) 64 Compiler Professional for applications" + "running on Intel(R) 64, Version 11.1", '11.1') +] + +class TestIntelFCompilerVersions: + def test_32bit_version(self): + fc = numpy.distutils.fcompiler.new_fcompiler(compiler='intel') + for vs, version in intel_32bit_version_strings: + v = fc.version_match(vs) + assert_(v == version) + + +class TestIntelEM64TFCompilerVersions: + def test_64bit_version(self): + fc = numpy.distutils.fcompiler.new_fcompiler(compiler='intelem') + for vs, version in intel_64bit_version_strings: + v = fc.version_match(vs) + assert_(v == version) diff --git a/venv/Lib/site-packages/numpy/distutils/tests/test_fcompiler_nagfor.py b/venv/Lib/site-packages/numpy/distutils/tests/test_fcompiler_nagfor.py new file mode 100644 index 0000000..2e04f52 --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/tests/test_fcompiler_nagfor.py @@ -0,0 +1,22 @@ +from numpy.testing import assert_ +import numpy.distutils.fcompiler + +nag_version_strings = [('nagfor', 'NAG Fortran Compiler Release ' + '6.2(Chiyoda) Build 6200', '6.2'), + ('nagfor', 'NAG Fortran Compiler Release ' + '6.1(Tozai) Build 6136', '6.1'), + ('nagfor', 'NAG Fortran Compiler Release ' + '6.0(Hibiya) Build 1021', '6.0'), + ('nagfor', 'NAG Fortran Compiler Release ' + '5.3.2(971)', '5.3.2'), + ('nag', 'NAGWare Fortran 95 compiler Release 5.1' + '(347,355-367,375,380-383,389,394,399,401-402,407,' + '431,435,437,446,459-460,463,472,494,496,503,508,' + '511,517,529,555,557,565)', '5.1')] + +class TestNagFCompilerVersions: + def test_version_match(self): + for comp, vs, version in nag_version_strings: + fc = numpy.distutils.fcompiler.new_fcompiler(compiler=comp) + v = fc.version_match(vs) + assert_(v == version) diff --git a/venv/Lib/site-packages/numpy/distutils/tests/test_from_template.py b/venv/Lib/site-packages/numpy/distutils/tests/test_from_template.py new file mode 100644 index 0000000..5881754 --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/tests/test_from_template.py @@ -0,0 +1,44 @@ + +from numpy.distutils.from_template import process_str +from numpy.testing import assert_equal + + +pyf_src = """ +python module foo + <_rd=real,double precision> + interface + subroutine foosub(tol) + <_rd>, intent(in,out) :: tol + end subroutine foosub + end interface +end python module foo +""" + +expected_pyf = """ +python module foo + interface + subroutine sfoosub(tol) + real, intent(in,out) :: tol + end subroutine sfoosub + subroutine dfoosub(tol) + double precision, intent(in,out) :: tol + end subroutine dfoosub + end interface +end python module foo +""" + + +def normalize_whitespace(s): + """ + Remove leading and trailing whitespace, and convert internal + stretches of whitespace to a single space. + """ + return ' '.join(s.split()) + + +def test_from_template(): + """Regression test for gh-10712.""" + pyf = process_str(pyf_src) + normalized_pyf = normalize_whitespace(pyf) + normalized_expected_pyf = normalize_whitespace(expected_pyf) + assert_equal(normalized_pyf, normalized_expected_pyf) diff --git a/venv/Lib/site-packages/numpy/distutils/tests/test_mingw32ccompiler.py b/venv/Lib/site-packages/numpy/distutils/tests/test_mingw32ccompiler.py new file mode 100644 index 0000000..ebedacb --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/tests/test_mingw32ccompiler.py @@ -0,0 +1,42 @@ +import shutil +import subprocess +import sys +import pytest + +from numpy.distutils import mingw32ccompiler + + +@pytest.mark.skipif(sys.platform != 'win32', reason='win32 only test') +def test_build_import(): + '''Test the mingw32ccompiler.build_import_library, which builds a + `python.a` from the MSVC `python.lib` + ''' + + # make sure `nm.exe` exists and supports the current python version. This + # can get mixed up when the PATH has a 64-bit nm but the python is 32-bit + try: + out = subprocess.check_output(['nm.exe', '--help']) + except FileNotFoundError: + pytest.skip("'nm.exe' not on path, is mingw installed?") + supported = out[out.find(b'supported targets:'):] + if sys.maxsize < 2**32: + if b'pe-i386' not in supported: + raise ValueError("'nm.exe' found but it does not support 32-bit " + "dlls when using 32-bit python. Supported " + "formats: '%s'" % supported) + elif b'pe-x86-64' not in supported: + raise ValueError("'nm.exe' found but it does not support 64-bit " + "dlls when using 64-bit python. Supported " + "formats: '%s'" % supported) + # Hide the import library to force a build + has_import_lib, fullpath = mingw32ccompiler._check_for_import_lib() + if has_import_lib: + shutil.move(fullpath, fullpath + '.bak') + + try: + # Whew, now we can actually test the function + mingw32ccompiler.build_import_library() + + finally: + if has_import_lib: + shutil.move(fullpath + '.bak', fullpath) diff --git a/venv/Lib/site-packages/numpy/distutils/tests/test_misc_util.py b/venv/Lib/site-packages/numpy/distutils/tests/test_misc_util.py new file mode 100644 index 0000000..605c804 --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/tests/test_misc_util.py @@ -0,0 +1,82 @@ +from os.path import join, sep, dirname + +from numpy.distutils.misc_util import ( + appendpath, minrelpath, gpaths, get_shared_lib_extension, get_info + ) +from numpy.testing import ( + assert_, assert_equal + ) + +ajoin = lambda *paths: join(*((sep,)+paths)) + +class TestAppendpath: + + def test_1(self): + assert_equal(appendpath('prefix', 'name'), join('prefix', 'name')) + assert_equal(appendpath('/prefix', 'name'), ajoin('prefix', 'name')) + assert_equal(appendpath('/prefix', '/name'), ajoin('prefix', 'name')) + assert_equal(appendpath('prefix', '/name'), join('prefix', 'name')) + + def test_2(self): + assert_equal(appendpath('prefix/sub', 'name'), + join('prefix', 'sub', 'name')) + assert_equal(appendpath('prefix/sub', 'sup/name'), + join('prefix', 'sub', 'sup', 'name')) + assert_equal(appendpath('/prefix/sub', '/prefix/name'), + ajoin('prefix', 'sub', 'name')) + + def test_3(self): + assert_equal(appendpath('/prefix/sub', '/prefix/sup/name'), + ajoin('prefix', 'sub', 'sup', 'name')) + assert_equal(appendpath('/prefix/sub/sub2', '/prefix/sup/sup2/name'), + ajoin('prefix', 'sub', 'sub2', 'sup', 'sup2', 'name')) + assert_equal(appendpath('/prefix/sub/sub2', '/prefix/sub/sup/name'), + ajoin('prefix', 'sub', 'sub2', 'sup', 'name')) + +class TestMinrelpath: + + def test_1(self): + n = lambda path: path.replace('/', sep) + assert_equal(minrelpath(n('aa/bb')), n('aa/bb')) + assert_equal(minrelpath('..'), '..') + assert_equal(minrelpath(n('aa/..')), '') + assert_equal(minrelpath(n('aa/../bb')), 'bb') + assert_equal(minrelpath(n('aa/bb/..')), 'aa') + assert_equal(minrelpath(n('aa/bb/../..')), '') + assert_equal(minrelpath(n('aa/bb/../cc/../dd')), n('aa/dd')) + assert_equal(minrelpath(n('.././..')), n('../..')) + assert_equal(minrelpath(n('aa/bb/.././../dd')), n('dd')) + +class TestGpaths: + + def test_gpaths(self): + local_path = minrelpath(join(dirname(__file__), '..')) + ls = gpaths('command/*.py', local_path) + assert_(join(local_path, 'command', 'build_src.py') in ls, repr(ls)) + f = gpaths('system_info.py', local_path) + assert_(join(local_path, 'system_info.py') == f[0], repr(f)) + +class TestSharedExtension: + + def test_get_shared_lib_extension(self): + import sys + ext = get_shared_lib_extension(is_python_ext=False) + if sys.platform.startswith('linux'): + assert_equal(ext, '.so') + elif sys.platform.startswith('gnukfreebsd'): + assert_equal(ext, '.so') + elif sys.platform.startswith('darwin'): + assert_equal(ext, '.dylib') + elif sys.platform.startswith('win'): + assert_equal(ext, '.dll') + # just check for no crash + assert_(get_shared_lib_extension(is_python_ext=True)) + + +def test_installed_npymath_ini(): + # Regression test for gh-7707. If npymath.ini wasn't installed, then this + # will give an error. + info = get_info('npymath') + + assert isinstance(info, dict) + assert "define_macros" in info diff --git a/venv/Lib/site-packages/numpy/distutils/tests/test_npy_pkg_config.py b/venv/Lib/site-packages/numpy/distutils/tests/test_npy_pkg_config.py new file mode 100644 index 0000000..b287ebe --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/tests/test_npy_pkg_config.py @@ -0,0 +1,84 @@ +import os + +from numpy.distutils.npy_pkg_config import read_config, parse_flags +from numpy.testing import temppath, assert_ + +simple = """\ +[meta] +Name = foo +Description = foo lib +Version = 0.1 + +[default] +cflags = -I/usr/include +libs = -L/usr/lib +""" +simple_d = {'cflags': '-I/usr/include', 'libflags': '-L/usr/lib', + 'version': '0.1', 'name': 'foo'} + +simple_variable = """\ +[meta] +Name = foo +Description = foo lib +Version = 0.1 + +[variables] +prefix = /foo/bar +libdir = ${prefix}/lib +includedir = ${prefix}/include + +[default] +cflags = -I${includedir} +libs = -L${libdir} +""" +simple_variable_d = {'cflags': '-I/foo/bar/include', 'libflags': '-L/foo/bar/lib', + 'version': '0.1', 'name': 'foo'} + +class TestLibraryInfo: + def test_simple(self): + with temppath('foo.ini') as path: + with open(path, 'w') as f: + f.write(simple) + pkg = os.path.splitext(path)[0] + out = read_config(pkg) + + assert_(out.cflags() == simple_d['cflags']) + assert_(out.libs() == simple_d['libflags']) + assert_(out.name == simple_d['name']) + assert_(out.version == simple_d['version']) + + def test_simple_variable(self): + with temppath('foo.ini') as path: + with open(path, 'w') as f: + f.write(simple_variable) + pkg = os.path.splitext(path)[0] + out = read_config(pkg) + + assert_(out.cflags() == simple_variable_d['cflags']) + assert_(out.libs() == simple_variable_d['libflags']) + assert_(out.name == simple_variable_d['name']) + assert_(out.version == simple_variable_d['version']) + out.vars['prefix'] = '/Users/david' + assert_(out.cflags() == '-I/Users/david/include') + +class TestParseFlags: + def test_simple_cflags(self): + d = parse_flags("-I/usr/include") + assert_(d['include_dirs'] == ['/usr/include']) + + d = parse_flags("-I/usr/include -DFOO") + assert_(d['include_dirs'] == ['/usr/include']) + assert_(d['macros'] == ['FOO']) + + d = parse_flags("-I /usr/include -DFOO") + assert_(d['include_dirs'] == ['/usr/include']) + assert_(d['macros'] == ['FOO']) + + def test_simple_lflags(self): + d = parse_flags("-L/usr/lib -lfoo -L/usr/lib -lbar") + assert_(d['library_dirs'] == ['/usr/lib', '/usr/lib']) + assert_(d['libraries'] == ['foo', 'bar']) + + d = parse_flags("-L /usr/lib -lfoo -L/usr/lib -lbar") + assert_(d['library_dirs'] == ['/usr/lib', '/usr/lib']) + assert_(d['libraries'] == ['foo', 'bar']) diff --git a/venv/Lib/site-packages/numpy/distutils/tests/test_shell_utils.py b/venv/Lib/site-packages/numpy/distutils/tests/test_shell_utils.py new file mode 100644 index 0000000..32bd283 --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/tests/test_shell_utils.py @@ -0,0 +1,76 @@ +import pytest +import subprocess +import json +import sys + +from numpy.distutils import _shell_utils + +argv_cases = [ + [r'exe'], + [r'path/exe'], + [r'path\exe'], + [r'\\server\path\exe'], + [r'path to/exe'], + [r'path to\exe'], + + [r'exe', '--flag'], + [r'path/exe', '--flag'], + [r'path\exe', '--flag'], + [r'path to/exe', '--flag'], + [r'path to\exe', '--flag'], + + # flags containing literal quotes in their name + [r'path to/exe', '--flag-"quoted"'], + [r'path to\exe', '--flag-"quoted"'], + [r'path to/exe', '"--flag-quoted"'], + [r'path to\exe', '"--flag-quoted"'], +] + + +@pytest.fixture(params=[ + _shell_utils.WindowsParser, + _shell_utils.PosixParser +]) +def Parser(request): + return request.param + + +@pytest.fixture +def runner(Parser): + if Parser != _shell_utils.NativeParser: + pytest.skip('Unable to run with non-native parser') + + if Parser == _shell_utils.WindowsParser: + return lambda cmd: subprocess.check_output(cmd) + elif Parser == _shell_utils.PosixParser: + # posix has no non-shell string parsing + return lambda cmd: subprocess.check_output(cmd, shell=True) + else: + raise NotImplementedError + + +@pytest.mark.parametrize('argv', argv_cases) +def test_join_matches_subprocess(Parser, runner, argv): + """ + Test that join produces strings understood by subprocess + """ + # invoke python to return its arguments as json + cmd = [ + sys.executable, '-c', + 'import json, sys; print(json.dumps(sys.argv[1:]))' + ] + joined = Parser.join(cmd + argv) + json_out = runner(joined).decode() + assert json.loads(json_out) == argv + + +@pytest.mark.parametrize('argv', argv_cases) +def test_roundtrip(Parser, argv): + """ + Test that split is the inverse operation of join + """ + try: + joined = Parser.join(argv) + assert argv == Parser.split(joined) + except NotImplementedError: + pytest.skip("Not implemented") diff --git a/venv/Lib/site-packages/numpy/distutils/tests/test_system_info.py b/venv/Lib/site-packages/numpy/distutils/tests/test_system_info.py new file mode 100644 index 0000000..ec15126 --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/tests/test_system_info.py @@ -0,0 +1,320 @@ +import os +import shutil +import pytest +from tempfile import mkstemp, mkdtemp +from subprocess import Popen, PIPE +from distutils.errors import DistutilsError + +from numpy.testing import assert_, assert_equal, assert_raises +from numpy.distutils import ccompiler, customized_ccompiler +from numpy.distutils.system_info import system_info, ConfigParser, mkl_info +from numpy.distutils.system_info import AliasedOptionError +from numpy.distutils.system_info import default_lib_dirs, default_include_dirs +from numpy.distutils import _shell_utils + + +def get_class(name, notfound_action=1): + """ + notfound_action: + 0 - do nothing + 1 - display warning message + 2 - raise error + """ + cl = {'temp1': Temp1Info, + 'temp2': Temp2Info, + 'duplicate_options': DuplicateOptionInfo, + }.get(name.lower(), _system_info) + return cl() + +simple_site = """ +[ALL] +library_dirs = {dir1:s}{pathsep:s}{dir2:s} +libraries = {lib1:s},{lib2:s} +extra_compile_args = -I/fake/directory -I"/path with/spaces" -Os +runtime_library_dirs = {dir1:s} + +[temp1] +library_dirs = {dir1:s} +libraries = {lib1:s} +runtime_library_dirs = {dir1:s} + +[temp2] +library_dirs = {dir2:s} +libraries = {lib2:s} +extra_link_args = -Wl,-rpath={lib2_escaped:s} +rpath = {dir2:s} + +[duplicate_options] +mylib_libs = {lib1:s} +libraries = {lib2:s} +""" +site_cfg = simple_site + +fakelib_c_text = """ +/* This file is generated from numpy/distutils/testing/test_system_info.py */ +#include +void foo(void) { + printf("Hello foo"); +} +void bar(void) { + printf("Hello bar"); +} +""" + +def have_compiler(): + """ Return True if there appears to be an executable compiler + """ + compiler = customized_ccompiler() + try: + cmd = compiler.compiler # Unix compilers + except AttributeError: + try: + if not compiler.initialized: + compiler.initialize() # MSVC is different + except (DistutilsError, ValueError): + return False + cmd = [compiler.cc] + try: + p = Popen(cmd, stdout=PIPE, stderr=PIPE) + p.stdout.close() + p.stderr.close() + p.wait() + except OSError: + return False + return True + + +HAVE_COMPILER = have_compiler() + + +class _system_info(system_info): + + def __init__(self, + default_lib_dirs=default_lib_dirs, + default_include_dirs=default_include_dirs, + verbosity=1, + ): + self.__class__.info = {} + self.local_prefixes = [] + defaults = {'library_dirs': '', + 'include_dirs': '', + 'runtime_library_dirs': '', + 'rpath': '', + 'src_dirs': '', + 'search_static_first': "0", + 'extra_compile_args': '', + 'extra_link_args': ''} + self.cp = ConfigParser(defaults) + # We have to parse the config files afterwards + # to have a consistent temporary filepath + + def _check_libs(self, lib_dirs, libs, opt_libs, exts): + """Override _check_libs to return with all dirs """ + info = {'libraries': libs, 'library_dirs': lib_dirs} + return info + + +class Temp1Info(_system_info): + """For testing purposes""" + section = 'temp1' + + +class Temp2Info(_system_info): + """For testing purposes""" + section = 'temp2' + +class DuplicateOptionInfo(_system_info): + """For testing purposes""" + section = 'duplicate_options' + + +class TestSystemInfoReading: + + def setup(self): + """ Create the libraries """ + # Create 2 sources and 2 libraries + self._dir1 = mkdtemp() + self._src1 = os.path.join(self._dir1, 'foo.c') + self._lib1 = os.path.join(self._dir1, 'libfoo.so') + self._dir2 = mkdtemp() + self._src2 = os.path.join(self._dir2, 'bar.c') + self._lib2 = os.path.join(self._dir2, 'libbar.so') + # Update local site.cfg + global simple_site, site_cfg + site_cfg = simple_site.format(**{ + 'dir1': self._dir1, + 'lib1': self._lib1, + 'dir2': self._dir2, + 'lib2': self._lib2, + 'pathsep': os.pathsep, + 'lib2_escaped': _shell_utils.NativeParser.join([self._lib2]) + }) + # Write site.cfg + fd, self._sitecfg = mkstemp() + os.close(fd) + with open(self._sitecfg, 'w') as fd: + fd.write(site_cfg) + # Write the sources + with open(self._src1, 'w') as fd: + fd.write(fakelib_c_text) + with open(self._src2, 'w') as fd: + fd.write(fakelib_c_text) + # We create all class-instances + + def site_and_parse(c, site_cfg): + c.files = [site_cfg] + c.parse_config_files() + return c + self.c_default = site_and_parse(get_class('default'), self._sitecfg) + self.c_temp1 = site_and_parse(get_class('temp1'), self._sitecfg) + self.c_temp2 = site_and_parse(get_class('temp2'), self._sitecfg) + self.c_dup_options = site_and_parse(get_class('duplicate_options'), + self._sitecfg) + + + def teardown(self): + # Do each removal separately + try: + shutil.rmtree(self._dir1) + except Exception: + pass + try: + shutil.rmtree(self._dir2) + except Exception: + pass + try: + os.remove(self._sitecfg) + except Exception: + pass + + def test_all(self): + # Read in all information in the ALL block + tsi = self.c_default + assert_equal(tsi.get_lib_dirs(), [self._dir1, self._dir2]) + assert_equal(tsi.get_libraries(), [self._lib1, self._lib2]) + assert_equal(tsi.get_runtime_lib_dirs(), [self._dir1]) + extra = tsi.calc_extra_info() + assert_equal(extra['extra_compile_args'], ['-I/fake/directory', '-I/path with/spaces', '-Os']) + + def test_temp1(self): + # Read in all information in the temp1 block + tsi = self.c_temp1 + assert_equal(tsi.get_lib_dirs(), [self._dir1]) + assert_equal(tsi.get_libraries(), [self._lib1]) + assert_equal(tsi.get_runtime_lib_dirs(), [self._dir1]) + + def test_temp2(self): + # Read in all information in the temp2 block + tsi = self.c_temp2 + assert_equal(tsi.get_lib_dirs(), [self._dir2]) + assert_equal(tsi.get_libraries(), [self._lib2]) + # Now from rpath and not runtime_library_dirs + assert_equal(tsi.get_runtime_lib_dirs(key='rpath'), [self._dir2]) + extra = tsi.calc_extra_info() + assert_equal(extra['extra_link_args'], ['-Wl,-rpath=' + self._lib2]) + + def test_duplicate_options(self): + # Ensure that duplicates are raising an AliasedOptionError + tsi = self.c_dup_options + assert_raises(AliasedOptionError, tsi.get_option_single, "mylib_libs", "libraries") + assert_equal(tsi.get_libs("mylib_libs", [self._lib1]), [self._lib1]) + assert_equal(tsi.get_libs("libraries", [self._lib2]), [self._lib2]) + + @pytest.mark.skipif(not HAVE_COMPILER, reason="Missing compiler") + def test_compile1(self): + # Compile source and link the first source + c = customized_ccompiler() + previousDir = os.getcwd() + try: + # Change directory to not screw up directories + os.chdir(self._dir1) + c.compile([os.path.basename(self._src1)], output_dir=self._dir1) + # Ensure that the object exists + assert_(os.path.isfile(self._src1.replace('.c', '.o')) or + os.path.isfile(self._src1.replace('.c', '.obj'))) + finally: + os.chdir(previousDir) + + @pytest.mark.skipif(not HAVE_COMPILER, reason="Missing compiler") + @pytest.mark.skipif('msvc' in repr(ccompiler.new_compiler()), + reason="Fails with MSVC compiler ") + def test_compile2(self): + # Compile source and link the second source + tsi = self.c_temp2 + c = customized_ccompiler() + extra_link_args = tsi.calc_extra_info()['extra_link_args'] + previousDir = os.getcwd() + try: + # Change directory to not screw up directories + os.chdir(self._dir2) + c.compile([os.path.basename(self._src2)], output_dir=self._dir2, + extra_postargs=extra_link_args) + # Ensure that the object exists + assert_(os.path.isfile(self._src2.replace('.c', '.o'))) + finally: + os.chdir(previousDir) + + def test_overrides(self): + previousDir = os.getcwd() + cfg = os.path.join(self._dir1, 'site.cfg') + shutil.copy(self._sitecfg, cfg) + try: + os.chdir(self._dir1) + # Check that the '[ALL]' section does not override + # missing values from other sections + info = mkl_info() + lib_dirs = info.cp['ALL']['library_dirs'].split(os.pathsep) + assert info.get_lib_dirs() != lib_dirs + + # But if we copy the values to a '[mkl]' section the value + # is correct + with open(cfg, 'r') as fid: + mkl = fid.read().replace('ALL', 'mkl') + with open(cfg, 'w') as fid: + fid.write(mkl) + info = mkl_info() + assert info.get_lib_dirs() == lib_dirs + + # Also, the values will be taken from a section named '[DEFAULT]' + with open(cfg, 'r') as fid: + dflt = fid.read().replace('mkl', 'DEFAULT') + with open(cfg, 'w') as fid: + fid.write(dflt) + info = mkl_info() + assert info.get_lib_dirs() == lib_dirs + finally: + os.chdir(previousDir) + + +def test_distutils_parse_env_order(monkeypatch): + from numpy.distutils.system_info import _parse_env_order + env = 'NPY_TESTS_DISTUTILS_PARSE_ENV_ORDER' + + base_order = list('abcdef') + + monkeypatch.setenv(env, 'b,i,e,f') + order, unknown = _parse_env_order(base_order, env) + assert len(order) == 3 + assert order == list('bef') + assert len(unknown) == 1 + + # For when LAPACK/BLAS optimization is disabled + monkeypatch.setenv(env, '') + order, unknown = _parse_env_order(base_order, env) + assert len(order) == 0 + assert len(unknown) == 0 + + for prefix in '^!': + monkeypatch.setenv(env, f'{prefix}b,i,e') + order, unknown = _parse_env_order(base_order, env) + assert len(order) == 4 + assert order == list('acdf') + assert len(unknown) == 1 + + with pytest.raises(ValueError): + monkeypatch.setenv(env, 'b,^e,i') + _parse_env_order(base_order, env) + + with pytest.raises(ValueError): + monkeypatch.setenv(env, '!b,^e,i') + _parse_env_order(base_order, env) diff --git a/venv/Lib/site-packages/numpy/distutils/unixccompiler.py b/venv/Lib/site-packages/numpy/distutils/unixccompiler.py new file mode 100644 index 0000000..0cd2d24 --- /dev/null +++ b/venv/Lib/site-packages/numpy/distutils/unixccompiler.py @@ -0,0 +1,140 @@ +""" +unixccompiler - can handle very long argument lists for ar. + +""" +import os +import sys +import subprocess + +from distutils.errors import CompileError, DistutilsExecError, LibError +from distutils.unixccompiler import UnixCCompiler +from numpy.distutils.ccompiler import replace_method +from numpy.distutils.misc_util import _commandline_dep_string +from numpy.distutils import log + +# Note that UnixCCompiler._compile appeared in Python 2.3 +def UnixCCompiler__compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts): + """Compile a single source files with a Unix-style compiler.""" + # HP ad-hoc fix, see ticket 1383 + ccomp = self.compiler_so + if ccomp[0] == 'aCC': + # remove flags that will trigger ANSI-C mode for aCC + if '-Ae' in ccomp: + ccomp.remove('-Ae') + if '-Aa' in ccomp: + ccomp.remove('-Aa') + # add flags for (almost) sane C++ handling + ccomp += ['-AA'] + self.compiler_so = ccomp + # ensure OPT environment variable is read + if 'OPT' in os.environ: + # XXX who uses this? + from sysconfig import get_config_vars + opt = " ".join(os.environ['OPT'].split()) + gcv_opt = " ".join(get_config_vars('OPT')[0].split()) + ccomp_s = " ".join(self.compiler_so) + if opt not in ccomp_s: + ccomp_s = ccomp_s.replace(gcv_opt, opt) + self.compiler_so = ccomp_s.split() + llink_s = " ".join(self.linker_so) + if opt not in llink_s: + self.linker_so = llink_s.split() + opt.split() + + display = '%s: %s' % (os.path.basename(self.compiler_so[0]), src) + + # gcc style automatic dependencies, outputs a makefile (-MF) that lists + # all headers needed by a c file as a side effect of compilation (-MMD) + if getattr(self, '_auto_depends', False): + deps = ['-MMD', '-MF', obj + '.d'] + else: + deps = [] + + try: + self.spawn(self.compiler_so + cc_args + [src, '-o', obj] + deps + + extra_postargs, display = display) + except DistutilsExecError as e: + msg = str(e) + raise CompileError(msg) + + # add commandline flags to dependency file + if deps: + # After running the compiler, the file created will be in EBCDIC + # but will not be tagged as such. This tags it so the file does not + # have multiple different encodings being written to it + if sys.platform == 'zos': + subprocess.check_output(['chtag', '-tc', 'IBM1047', obj + '.d']) + with open(obj + '.d', 'a') as f: + f.write(_commandline_dep_string(cc_args, extra_postargs, pp_opts)) + +replace_method(UnixCCompiler, '_compile', UnixCCompiler__compile) + + +def UnixCCompiler_create_static_lib(self, objects, output_libname, + output_dir=None, debug=0, target_lang=None): + """ + Build a static library in a separate sub-process. + + Parameters + ---------- + objects : list or tuple of str + List of paths to object files used to build the static library. + output_libname : str + The library name as an absolute or relative (if `output_dir` is used) + path. + output_dir : str, optional + The path to the output directory. Default is None, in which case + the ``output_dir`` attribute of the UnixCCompiler instance. + debug : bool, optional + This parameter is not used. + target_lang : str, optional + This parameter is not used. + + Returns + ------- + None + + """ + objects, output_dir = self._fix_object_args(objects, output_dir) + + output_filename = \ + self.library_filename(output_libname, output_dir=output_dir) + + if self._need_link(objects, output_filename): + try: + # previous .a may be screwed up; best to remove it first + # and recreate. + # Also, ar on OS X doesn't handle updating universal archives + os.unlink(output_filename) + except (IOError, OSError): + pass + self.mkpath(os.path.dirname(output_filename)) + tmp_objects = objects + self.objects + while tmp_objects: + objects = tmp_objects[:50] + tmp_objects = tmp_objects[50:] + display = '%s: adding %d object files to %s' % ( + os.path.basename(self.archiver[0]), + len(objects), output_filename) + self.spawn(self.archiver + [output_filename] + objects, + display = display) + + # Not many Unices required ranlib anymore -- SunOS 4.x is, I + # think the only major Unix that does. Maybe we need some + # platform intelligence here to skip ranlib if it's not + # needed -- or maybe Python's configure script took care of + # it for us, hence the check for leading colon. + if self.ranlib: + display = '%s:@ %s' % (os.path.basename(self.ranlib[0]), + output_filename) + try: + self.spawn(self.ranlib + [output_filename], + display = display) + except DistutilsExecError as e: + msg = str(e) + raise LibError(msg) + else: + log.debug("skipping %s (up-to-date)", output_filename) + return + +replace_method(UnixCCompiler, 'create_static_lib', + UnixCCompiler_create_static_lib) diff --git a/venv/Lib/site-packages/numpy/doc/__init__.py b/venv/Lib/site-packages/numpy/doc/__init__.py new file mode 100644 index 0000000..8a944fe --- /dev/null +++ b/venv/Lib/site-packages/numpy/doc/__init__.py @@ -0,0 +1,26 @@ +import os + +ref_dir = os.path.join(os.path.dirname(__file__)) + +__all__ = sorted(f[:-3] for f in os.listdir(ref_dir) if f.endswith('.py') and + not f.startswith('__')) + +for f in __all__: + __import__(__name__ + '.' + f) + +del f, ref_dir + +__doc__ = """\ +Topical documentation +===================== + +The following topics are available: +%s + +You can view them by + +>>> help(np.doc.TOPIC) #doctest: +SKIP + +""" % '\n- '.join([''] + __all__) + +__all__.extend(['__doc__']) diff --git a/venv/Lib/site-packages/numpy/doc/constants.py b/venv/Lib/site-packages/numpy/doc/constants.py new file mode 100644 index 0000000..128493d --- /dev/null +++ b/venv/Lib/site-packages/numpy/doc/constants.py @@ -0,0 +1,413 @@ +# -*- coding: utf-8 -*- +""" +========= +Constants +========= + +.. currentmodule:: numpy + +NumPy includes several constants: + +%(constant_list)s +""" +# +# Note: the docstring is autogenerated. +# +import re +import textwrap + +# Maintain same format as in numpy.add_newdocs +constants = [] +def add_newdoc(module, name, doc): + constants.append((name, doc)) + +add_newdoc('numpy', 'pi', + """ + ``pi = 3.1415926535897932384626433...`` + + References + ---------- + https://en.wikipedia.org/wiki/Pi + + """) + +add_newdoc('numpy', 'e', + """ + Euler's constant, base of natural logarithms, Napier's constant. + + ``e = 2.71828182845904523536028747135266249775724709369995...`` + + See Also + -------- + exp : Exponential function + log : Natural logarithm + + References + ---------- + https://en.wikipedia.org/wiki/E_%28mathematical_constant%29 + + """) + +add_newdoc('numpy', 'euler_gamma', + """ + ``γ = 0.5772156649015328606065120900824024310421...`` + + References + ---------- + https://en.wikipedia.org/wiki/Euler-Mascheroni_constant + + """) + +add_newdoc('numpy', 'inf', + """ + IEEE 754 floating point representation of (positive) infinity. + + Returns + ------- + y : float + A floating point representation of positive infinity. + + See Also + -------- + isinf : Shows which elements are positive or negative infinity + + isposinf : Shows which elements are positive infinity + + isneginf : Shows which elements are negative infinity + + isnan : Shows which elements are Not a Number + + isfinite : Shows which elements are finite (not one of Not a Number, + positive infinity and negative infinity) + + Notes + ----- + NumPy uses the IEEE Standard for Binary Floating-Point for Arithmetic + (IEEE 754). This means that Not a Number is not equivalent to infinity. + Also that positive infinity is not equivalent to negative infinity. But + infinity is equivalent to positive infinity. + + `Inf`, `Infinity`, `PINF` and `infty` are aliases for `inf`. + + Examples + -------- + >>> np.inf + inf + >>> np.array([1]) / 0. + array([ Inf]) + + """) + +add_newdoc('numpy', 'nan', + """ + IEEE 754 floating point representation of Not a Number (NaN). + + Returns + ------- + y : A floating point representation of Not a Number. + + See Also + -------- + isnan : Shows which elements are Not a Number. + + isfinite : Shows which elements are finite (not one of + Not a Number, positive infinity and negative infinity) + + Notes + ----- + NumPy uses the IEEE Standard for Binary Floating-Point for Arithmetic + (IEEE 754). This means that Not a Number is not equivalent to infinity. + + `NaN` and `NAN` are aliases of `nan`. + + Examples + -------- + >>> np.nan + nan + >>> np.log(-1) + nan + >>> np.log([-1, 1, 2]) + array([ NaN, 0. , 0.69314718]) + + """) + +add_newdoc('numpy', 'newaxis', + """ + A convenient alias for None, useful for indexing arrays. + + Examples + -------- + >>> newaxis is None + True + >>> x = np.arange(3) + >>> x + array([0, 1, 2]) + >>> x[:, newaxis] + array([[0], + [1], + [2]]) + >>> x[:, newaxis, newaxis] + array([[[0]], + [[1]], + [[2]]]) + >>> x[:, newaxis] * x + array([[0, 0, 0], + [0, 1, 2], + [0, 2, 4]]) + + Outer product, same as ``outer(x, y)``: + + >>> y = np.arange(3, 6) + >>> x[:, newaxis] * y + array([[ 0, 0, 0], + [ 3, 4, 5], + [ 6, 8, 10]]) + + ``x[newaxis, :]`` is equivalent to ``x[newaxis]`` and ``x[None]``: + + >>> x[newaxis, :].shape + (1, 3) + >>> x[newaxis].shape + (1, 3) + >>> x[None].shape + (1, 3) + >>> x[:, newaxis].shape + (3, 1) + + """) + +add_newdoc('numpy', 'NZERO', + """ + IEEE 754 floating point representation of negative zero. + + Returns + ------- + y : float + A floating point representation of negative zero. + + See Also + -------- + PZERO : Defines positive zero. + + isinf : Shows which elements are positive or negative infinity. + + isposinf : Shows which elements are positive infinity. + + isneginf : Shows which elements are negative infinity. + + isnan : Shows which elements are Not a Number. + + isfinite : Shows which elements are finite - not one of + Not a Number, positive infinity and negative infinity. + + Notes + ----- + NumPy uses the IEEE Standard for Binary Floating-Point for Arithmetic + (IEEE 754). Negative zero is considered to be a finite number. + + Examples + -------- + >>> np.NZERO + -0.0 + >>> np.PZERO + 0.0 + + >>> np.isfinite([np.NZERO]) + array([ True]) + >>> np.isnan([np.NZERO]) + array([False]) + >>> np.isinf([np.NZERO]) + array([False]) + + """) + +add_newdoc('numpy', 'PZERO', + """ + IEEE 754 floating point representation of positive zero. + + Returns + ------- + y : float + A floating point representation of positive zero. + + See Also + -------- + NZERO : Defines negative zero. + + isinf : Shows which elements are positive or negative infinity. + + isposinf : Shows which elements are positive infinity. + + isneginf : Shows which elements are negative infinity. + + isnan : Shows which elements are Not a Number. + + isfinite : Shows which elements are finite - not one of + Not a Number, positive infinity and negative infinity. + + Notes + ----- + NumPy uses the IEEE Standard for Binary Floating-Point for Arithmetic + (IEEE 754). Positive zero is considered to be a finite number. + + Examples + -------- + >>> np.PZERO + 0.0 + >>> np.NZERO + -0.0 + + >>> np.isfinite([np.PZERO]) + array([ True]) + >>> np.isnan([np.PZERO]) + array([False]) + >>> np.isinf([np.PZERO]) + array([False]) + + """) + +add_newdoc('numpy', 'NAN', + """ + IEEE 754 floating point representation of Not a Number (NaN). + + `NaN` and `NAN` are equivalent definitions of `nan`. Please use + `nan` instead of `NAN`. + + See Also + -------- + nan + + """) + +add_newdoc('numpy', 'NaN', + """ + IEEE 754 floating point representation of Not a Number (NaN). + + `NaN` and `NAN` are equivalent definitions of `nan`. Please use + `nan` instead of `NaN`. + + See Also + -------- + nan + + """) + +add_newdoc('numpy', 'NINF', + """ + IEEE 754 floating point representation of negative infinity. + + Returns + ------- + y : float + A floating point representation of negative infinity. + + See Also + -------- + isinf : Shows which elements are positive or negative infinity + + isposinf : Shows which elements are positive infinity + + isneginf : Shows which elements are negative infinity + + isnan : Shows which elements are Not a Number + + isfinite : Shows which elements are finite (not one of Not a Number, + positive infinity and negative infinity) + + Notes + ----- + NumPy uses the IEEE Standard for Binary Floating-Point for Arithmetic + (IEEE 754). This means that Not a Number is not equivalent to infinity. + Also that positive infinity is not equivalent to negative infinity. But + infinity is equivalent to positive infinity. + + Examples + -------- + >>> np.NINF + -inf + >>> np.log(0) + -inf + + """) + +add_newdoc('numpy', 'PINF', + """ + IEEE 754 floating point representation of (positive) infinity. + + Use `inf` because `Inf`, `Infinity`, `PINF` and `infty` are aliases for + `inf`. For more details, see `inf`. + + See Also + -------- + inf + + """) + +add_newdoc('numpy', 'infty', + """ + IEEE 754 floating point representation of (positive) infinity. + + Use `inf` because `Inf`, `Infinity`, `PINF` and `infty` are aliases for + `inf`. For more details, see `inf`. + + See Also + -------- + inf + + """) + +add_newdoc('numpy', 'Inf', + """ + IEEE 754 floating point representation of (positive) infinity. + + Use `inf` because `Inf`, `Infinity`, `PINF` and `infty` are aliases for + `inf`. For more details, see `inf`. + + See Also + -------- + inf + + """) + +add_newdoc('numpy', 'Infinity', + """ + IEEE 754 floating point representation of (positive) infinity. + + Use `inf` because `Inf`, `Infinity`, `PINF` and `infty` are aliases for + `inf`. For more details, see `inf`. + + See Also + -------- + inf + + """) + + +if __doc__: + constants_str = [] + constants.sort() + for name, doc in constants: + s = textwrap.dedent(doc).replace("\n", "\n ") + + # Replace sections by rubrics + lines = s.split("\n") + new_lines = [] + for line in lines: + m = re.match(r'^(\s+)[-=]+\s*$', line) + if m and new_lines: + prev = textwrap.dedent(new_lines.pop()) + new_lines.append('%s.. rubric:: %s' % (m.group(1), prev)) + new_lines.append('') + else: + new_lines.append(line) + s = "\n".join(new_lines) + + # Done. + constants_str.append(""".. data:: %s\n %s""" % (name, s)) + constants_str = "\n".join(constants_str) + + __doc__ = __doc__ % dict(constant_list=constants_str) + del constants_str, name, doc + del line, lines, new_lines, m, s, prev + +del constants, add_newdoc diff --git a/venv/Lib/site-packages/numpy/doc/ufuncs.py b/venv/Lib/site-packages/numpy/doc/ufuncs.py new file mode 100644 index 0000000..eecc150 --- /dev/null +++ b/venv/Lib/site-packages/numpy/doc/ufuncs.py @@ -0,0 +1,137 @@ +""" +=================== +Universal Functions +=================== + +Ufuncs are, generally speaking, mathematical functions or operations that are +applied element-by-element to the contents of an array. That is, the result +in each output array element only depends on the value in the corresponding +input array (or arrays) and on no other array elements. NumPy comes with a +large suite of ufuncs, and scipy extends that suite substantially. The simplest +example is the addition operator: :: + + >>> np.array([0,2,3,4]) + np.array([1,1,-1,2]) + array([1, 3, 2, 6]) + +The ufunc module lists all the available ufuncs in numpy. Documentation on +the specific ufuncs may be found in those modules. This documentation is +intended to address the more general aspects of ufuncs common to most of +them. All of the ufuncs that make use of Python operators (e.g., +, -, etc.) +have equivalent functions defined (e.g. add() for +) + +Type coercion +============= + +What happens when a binary operator (e.g., +,-,\\*,/, etc) deals with arrays of +two different types? What is the type of the result? Typically, the result is +the higher of the two types. For example: :: + + float32 + float64 -> float64 + int8 + int32 -> int32 + int16 + float32 -> float32 + float32 + complex64 -> complex64 + +There are some less obvious cases generally involving mixes of types +(e.g. uints, ints and floats) where equal bit sizes for each are not +capable of saving all the information in a different type of equivalent +bit size. Some examples are int32 vs float32 or uint32 vs int32. +Generally, the result is the higher type of larger size than both +(if available). So: :: + + int32 + float32 -> float64 + uint32 + int32 -> int64 + +Finally, the type coercion behavior when expressions involve Python +scalars is different than that seen for arrays. Since Python has a +limited number of types, combining a Python int with a dtype=np.int8 +array does not coerce to the higher type but instead, the type of the +array prevails. So the rules for Python scalars combined with arrays is +that the result will be that of the array equivalent the Python scalar +if the Python scalar is of a higher 'kind' than the array (e.g., float +vs. int), otherwise the resultant type will be that of the array. +For example: :: + + Python int + int8 -> int8 + Python float + int8 -> float64 + +ufunc methods +============= + +Binary ufuncs support 4 methods. + +**.reduce(arr)** applies the binary operator to elements of the array in + sequence. For example: :: + + >>> np.add.reduce(np.arange(10)) # adds all elements of array + 45 + +For multidimensional arrays, the first dimension is reduced by default: :: + + >>> np.add.reduce(np.arange(10).reshape(2,5)) + array([ 5, 7, 9, 11, 13]) + +The axis keyword can be used to specify different axes to reduce: :: + + >>> np.add.reduce(np.arange(10).reshape(2,5),axis=1) + array([10, 35]) + +**.accumulate(arr)** applies the binary operator and generates an an +equivalently shaped array that includes the accumulated amount for each +element of the array. A couple examples: :: + + >>> np.add.accumulate(np.arange(10)) + array([ 0, 1, 3, 6, 10, 15, 21, 28, 36, 45]) + >>> np.multiply.accumulate(np.arange(1,9)) + array([ 1, 2, 6, 24, 120, 720, 5040, 40320]) + +The behavior for multidimensional arrays is the same as for .reduce(), +as is the use of the axis keyword). + +**.reduceat(arr,indices)** allows one to apply reduce to selected parts + of an array. It is a difficult method to understand. See the documentation + at: + +**.outer(arr1,arr2)** generates an outer operation on the two arrays arr1 and + arr2. It will work on multidimensional arrays (the shape of the result is + the concatenation of the two input shapes.: :: + + >>> np.multiply.outer(np.arange(3),np.arange(4)) + array([[0, 0, 0, 0], + [0, 1, 2, 3], + [0, 2, 4, 6]]) + +Output arguments +================ + +All ufuncs accept an optional output array. The array must be of the expected +output shape. Beware that if the type of the output array is of a different +(and lower) type than the output result, the results may be silently truncated +or otherwise corrupted in the downcast to the lower type. This usage is useful +when one wants to avoid creating large temporary arrays and instead allows one +to reuse the same array memory repeatedly (at the expense of not being able to +use more convenient operator notation in expressions). Note that when the +output argument is used, the ufunc still returns a reference to the result. + + >>> x = np.arange(2) + >>> np.add(np.arange(2),np.arange(2.),x) + array([0, 2]) + >>> x + array([0, 2]) + +and & or as ufuncs +================== + +Invariably people try to use the python 'and' and 'or' as logical operators +(and quite understandably). But these operators do not behave as normal +operators since Python treats these quite differently. They cannot be +overloaded with array equivalents. Thus using 'and' or 'or' with an array +results in an error. There are two alternatives: + + 1) use the ufunc functions logical_and() and logical_or(). + 2) use the bitwise operators & and \\|. The drawback of these is that if + the arguments to these operators are not boolean arrays, the result is + likely incorrect. On the other hand, most usages of logical_and and + logical_or are with boolean arrays. As long as one is careful, this is + a convenient way to apply these operators. + +""" diff --git a/venv/Lib/site-packages/numpy/dual.py b/venv/Lib/site-packages/numpy/dual.py new file mode 100644 index 0000000..eb7e61a --- /dev/null +++ b/venv/Lib/site-packages/numpy/dual.py @@ -0,0 +1,83 @@ +""" +.. deprecated:: 1.20 + +*This module is deprecated. Instead of importing functions from* +``numpy.dual``, *the functions should be imported directly from NumPy +or SciPy*. + +Aliases for functions which may be accelerated by SciPy. + +SciPy_ can be built to use accelerated or otherwise improved libraries +for FFTs, linear algebra, and special functions. This module allows +developers to transparently support these accelerated functions when +SciPy is available but still support users who have only installed +NumPy. + +.. _SciPy : https://www.scipy.org + +""" +import warnings + + +warnings.warn('The module numpy.dual is deprecated. Instead of using dual, ' + 'use the functions directly from numpy or scipy.', + category=DeprecationWarning, + stacklevel=2) + +# This module should be used for functions both in numpy and scipy if +# you want to use the numpy version if available but the scipy version +# otherwise. +# Usage --- from numpy.dual import fft, inv + +__all__ = ['fft', 'ifft', 'fftn', 'ifftn', 'fft2', 'ifft2', + 'norm', 'inv', 'svd', 'solve', 'det', 'eig', 'eigvals', + 'eigh', 'eigvalsh', 'lstsq', 'pinv', 'cholesky', 'i0'] + +import numpy.linalg as linpkg +import numpy.fft as fftpkg +from numpy.lib import i0 +import sys + + +fft = fftpkg.fft +ifft = fftpkg.ifft +fftn = fftpkg.fftn +ifftn = fftpkg.ifftn +fft2 = fftpkg.fft2 +ifft2 = fftpkg.ifft2 + +norm = linpkg.norm +inv = linpkg.inv +svd = linpkg.svd +solve = linpkg.solve +det = linpkg.det +eig = linpkg.eig +eigvals = linpkg.eigvals +eigh = linpkg.eigh +eigvalsh = linpkg.eigvalsh +lstsq = linpkg.lstsq +pinv = linpkg.pinv +cholesky = linpkg.cholesky + +_restore_dict = {} + +def register_func(name, func): + if name not in __all__: + raise ValueError("{} not a dual function.".format(name)) + f = sys._getframe(0).f_globals + _restore_dict[name] = f[name] + f[name] = func + +def restore_func(name): + if name not in __all__: + raise ValueError("{} not a dual function.".format(name)) + try: + val = _restore_dict[name] + except KeyError: + return + else: + sys._getframe(0).f_globals[name] = val + +def restore_all(): + for name in _restore_dict.keys(): + restore_func(name) diff --git a/venv/Lib/site-packages/numpy/emath.pyi b/venv/Lib/site-packages/numpy/emath.pyi new file mode 100644 index 0000000..5aae84b --- /dev/null +++ b/venv/Lib/site-packages/numpy/emath.pyi @@ -0,0 +1,13 @@ +from typing import Any, List + +__all__: List[str] + +sqrt: Any +log: Any +log2: Any +logn: Any +log10: Any +power: Any +arccos: Any +arcsin: Any +arctanh: Any diff --git a/venv/Lib/site-packages/numpy/f2py/__init__.py b/venv/Lib/site-packages/numpy/f2py/__init__.py new file mode 100644 index 0000000..07ab6cd --- /dev/null +++ b/venv/Lib/site-packages/numpy/f2py/__init__.py @@ -0,0 +1,153 @@ +#!/usr/bin/env python3 +"""Fortran to Python Interface Generator. + +""" +__all__ = ['run_main', 'compile', 'f2py_testing'] + +import sys +import subprocess +import os + +from . import f2py2e +from . import diagnose + +run_main = f2py2e.run_main +main = f2py2e.main + + +def compile(source, + modulename='untitled', + extra_args='', + verbose=True, + source_fn=None, + extension='.f', + full_output=False + ): + """ + Build extension module from a Fortran 77 source string with f2py. + + Parameters + ---------- + source : str or bytes + Fortran source of module / subroutine to compile + + .. versionchanged:: 1.16.0 + Accept str as well as bytes + + modulename : str, optional + The name of the compiled python module + extra_args : str or list, optional + Additional parameters passed to f2py + + .. versionchanged:: 1.16.0 + A list of args may also be provided. + + verbose : bool, optional + Print f2py output to screen + source_fn : str, optional + Name of the file where the fortran source is written. + The default is to use a temporary file with the extension + provided by the `extension` parameter + extension : {'.f', '.f90'}, optional + Filename extension if `source_fn` is not provided. + The extension tells which fortran standard is used. + The default is `.f`, which implies F77 standard. + + .. versionadded:: 1.11.0 + + full_output : bool, optional + If True, return a `subprocess.CompletedProcess` containing + the stdout and stderr of the compile process, instead of just + the status code. + + .. versionadded:: 1.20.0 + + + Returns + ------- + result : int or `subprocess.CompletedProcess` + 0 on success, or a `subprocess.CompletedProcess` if + ``full_output=True`` + + Examples + -------- + .. include:: compile_session.dat + :literal: + + """ + import tempfile + import shlex + + if source_fn is None: + f, fname = tempfile.mkstemp(suffix=extension) + # f is a file descriptor so need to close it + # carefully -- not with .close() directly + os.close(f) + else: + fname = source_fn + + if not isinstance(source, str): + source = str(source, 'utf-8') + try: + with open(fname, 'w') as f: + f.write(source) + + args = ['-c', '-m', modulename, f.name] + + if isinstance(extra_args, str): + is_posix = (os.name == 'posix') + extra_args = shlex.split(extra_args, posix=is_posix) + + args.extend(extra_args) + + c = [sys.executable, + '-c', + 'import numpy.f2py as f2py2e;f2py2e.main()'] + args + try: + cp = subprocess.run(c, stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + except OSError: + # preserve historic status code used by exec_command() + cp = subprocess.CompletedProcess(c, 127, stdout=b'', stderr=b'') + else: + if verbose: + print(cp.stdout.decode()) + finally: + if source_fn is None: + os.remove(fname) + + if full_output: + return cp + else: + return cp.returncode + + +if sys.version_info[:2] >= (3, 7): + # module level getattr is only supported in 3.7 onwards + # https://www.python.org/dev/peps/pep-0562/ + def __getattr__(attr): + + # Avoid importing things that aren't needed for building + # which might import the main numpy module + if attr == "f2py_testing": + import numpy.f2py.f2py_testing as f2py_testing + return f2py_testing + + elif attr == "test": + from numpy._pytesttester import PytestTester + test = PytestTester(__name__) + return test + + else: + raise AttributeError("module {!r} has no attribute " + "{!r}".format(__name__, attr)) + + def __dir__(): + return list(globals().keys() | {"f2py_testing", "test"}) + +else: + from . import f2py_testing + + from numpy._pytesttester import PytestTester + test = PytestTester(__name__) + del PytestTester diff --git a/venv/Lib/site-packages/numpy/f2py/__init__.pyi b/venv/Lib/site-packages/numpy/f2py/__init__.pyi new file mode 100644 index 0000000..50594c1 --- /dev/null +++ b/venv/Lib/site-packages/numpy/f2py/__init__.pyi @@ -0,0 +1,7 @@ +from typing import Any, List + +__all__: List[str] + +run_main: Any +compile: Any +f2py_testing: Any diff --git a/venv/Lib/site-packages/numpy/f2py/__main__.py b/venv/Lib/site-packages/numpy/f2py/__main__.py new file mode 100644 index 0000000..c611507 --- /dev/null +++ b/venv/Lib/site-packages/numpy/f2py/__main__.py @@ -0,0 +1,4 @@ +# See http://cens.ioc.ee/projects/f2py2e/ +from numpy.f2py.f2py2e import main + +main() diff --git a/venv/Lib/site-packages/numpy/f2py/__version__.py b/venv/Lib/site-packages/numpy/f2py/__version__.py new file mode 100644 index 0000000..e20d7c1 --- /dev/null +++ b/venv/Lib/site-packages/numpy/f2py/__version__.py @@ -0,0 +1 @@ +from numpy.version import version diff --git a/venv/Lib/site-packages/numpy/f2py/auxfuncs.py b/venv/Lib/site-packages/numpy/f2py/auxfuncs.py new file mode 100644 index 0000000..5250fea --- /dev/null +++ b/venv/Lib/site-packages/numpy/f2py/auxfuncs.py @@ -0,0 +1,857 @@ +#!/usr/bin/env python3 +""" + +Auxiliary functions for f2py2e. + +Copyright 1999,2000 Pearu Peterson all rights reserved, +Pearu Peterson +Permission to use, modify, and distribute this software is given under the +terms of the NumPy (BSD style) LICENSE. + + +NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. +$Date: 2005/07/24 19:01:55 $ +Pearu Peterson + +""" +import pprint +import sys +import types +from functools import reduce + +from . import __version__ +from . import cfuncs + +__all__ = [ + 'applyrules', 'debugcapi', 'dictappend', 'errmess', 'gentitle', + 'getargs2', 'getcallprotoargument', 'getcallstatement', + 'getfortranname', 'getpymethoddef', 'getrestdoc', 'getusercode', + 'getusercode1', 'hasbody', 'hascallstatement', 'hascommon', + 'hasexternals', 'hasinitvalue', 'hasnote', 'hasresultnote', + 'isallocatable', 'isarray', 'isarrayofstrings', 'iscomplex', + 'iscomplexarray', 'iscomplexfunction', 'iscomplexfunction_warn', + 'isdouble', 'isdummyroutine', 'isexternal', 'isfunction', + 'isfunction_wrap', 'isint1array', 'isinteger', 'isintent_aux', + 'isintent_c', 'isintent_callback', 'isintent_copy', 'isintent_dict', + 'isintent_hide', 'isintent_in', 'isintent_inout', 'isintent_inplace', + 'isintent_nothide', 'isintent_out', 'isintent_overwrite', 'islogical', + 'islogicalfunction', 'islong_complex', 'islong_double', + 'islong_doublefunction', 'islong_long', 'islong_longfunction', + 'ismodule', 'ismoduleroutine', 'isoptional', 'isprivate', 'isrequired', + 'isroutine', 'isscalar', 'issigned_long_longarray', 'isstring', + 'isstringarray', 'isstringfunction', 'issubroutine', + 'issubroutine_wrap', 'isthreadsafe', 'isunsigned', 'isunsigned_char', + 'isunsigned_chararray', 'isunsigned_long_long', + 'isunsigned_long_longarray', 'isunsigned_short', + 'isunsigned_shortarray', 'l_and', 'l_not', 'l_or', 'outmess', + 'replace', 'show', 'stripcomma', 'throw_error', +] + + +f2py_version = __version__.version + + +errmess = sys.stderr.write +show = pprint.pprint + +options = {} +debugoptions = [] +wrapfuncs = 1 + + +def outmess(t): + if options.get('verbose', 1): + sys.stdout.write(t) + + +def debugcapi(var): + return 'capi' in debugoptions + + +def _isstring(var): + return 'typespec' in var and var['typespec'] == 'character' and \ + not isexternal(var) + + +def isstring(var): + return _isstring(var) and not isarray(var) + + +def ischaracter(var): + return isstring(var) and 'charselector' not in var + + +def isstringarray(var): + return isarray(var) and _isstring(var) + + +def isarrayofstrings(var): + # leaving out '*' for now so that `character*(*) a(m)` and `character + # a(m,*)` are treated differently. Luckily `character**` is illegal. + return isstringarray(var) and var['dimension'][-1] == '(*)' + + +def isarray(var): + return 'dimension' in var and not isexternal(var) + + +def isscalar(var): + return not (isarray(var) or isstring(var) or isexternal(var)) + + +def iscomplex(var): + return isscalar(var) and \ + var.get('typespec') in ['complex', 'double complex'] + + +def islogical(var): + return isscalar(var) and var.get('typespec') == 'logical' + + +def isinteger(var): + return isscalar(var) and var.get('typespec') == 'integer' + + +def isreal(var): + return isscalar(var) and var.get('typespec') == 'real' + + +def get_kind(var): + try: + return var['kindselector']['*'] + except KeyError: + try: + return var['kindselector']['kind'] + except KeyError: + pass + + +def islong_long(var): + if not isscalar(var): + return 0 + if var.get('typespec') not in ['integer', 'logical']: + return 0 + return get_kind(var) == '8' + + +def isunsigned_char(var): + if not isscalar(var): + return 0 + if var.get('typespec') != 'integer': + return 0 + return get_kind(var) == '-1' + + +def isunsigned_short(var): + if not isscalar(var): + return 0 + if var.get('typespec') != 'integer': + return 0 + return get_kind(var) == '-2' + + +def isunsigned(var): + if not isscalar(var): + return 0 + if var.get('typespec') != 'integer': + return 0 + return get_kind(var) == '-4' + + +def isunsigned_long_long(var): + if not isscalar(var): + return 0 + if var.get('typespec') != 'integer': + return 0 + return get_kind(var) == '-8' + + +def isdouble(var): + if not isscalar(var): + return 0 + if not var.get('typespec') == 'real': + return 0 + return get_kind(var) == '8' + + +def islong_double(var): + if not isscalar(var): + return 0 + if not var.get('typespec') == 'real': + return 0 + return get_kind(var) == '16' + + +def islong_complex(var): + if not iscomplex(var): + return 0 + return get_kind(var) == '32' + + +def iscomplexarray(var): + return isarray(var) and \ + var.get('typespec') in ['complex', 'double complex'] + + +def isint1array(var): + return isarray(var) and var.get('typespec') == 'integer' \ + and get_kind(var) == '1' + + +def isunsigned_chararray(var): + return isarray(var) and var.get('typespec') in ['integer', 'logical']\ + and get_kind(var) == '-1' + + +def isunsigned_shortarray(var): + return isarray(var) and var.get('typespec') in ['integer', 'logical']\ + and get_kind(var) == '-2' + + +def isunsignedarray(var): + return isarray(var) and var.get('typespec') in ['integer', 'logical']\ + and get_kind(var) == '-4' + + +def isunsigned_long_longarray(var): + return isarray(var) and var.get('typespec') in ['integer', 'logical']\ + and get_kind(var) == '-8' + + +def issigned_chararray(var): + return isarray(var) and var.get('typespec') in ['integer', 'logical']\ + and get_kind(var) == '1' + + +def issigned_shortarray(var): + return isarray(var) and var.get('typespec') in ['integer', 'logical']\ + and get_kind(var) == '2' + + +def issigned_array(var): + return isarray(var) and var.get('typespec') in ['integer', 'logical']\ + and get_kind(var) == '4' + + +def issigned_long_longarray(var): + return isarray(var) and var.get('typespec') in ['integer', 'logical']\ + and get_kind(var) == '8' + + +def isallocatable(var): + return 'attrspec' in var and 'allocatable' in var['attrspec'] + + +def ismutable(var): + return not ('dimension' not in var or isstring(var)) + + +def ismoduleroutine(rout): + return 'modulename' in rout + + +def ismodule(rout): + return 'block' in rout and 'module' == rout['block'] + + +def isfunction(rout): + return 'block' in rout and 'function' == rout['block'] + + +def isfunction_wrap(rout): + if isintent_c(rout): + return 0 + return wrapfuncs and isfunction(rout) and (not isexternal(rout)) + + +def issubroutine(rout): + return 'block' in rout and 'subroutine' == rout['block'] + + +def issubroutine_wrap(rout): + if isintent_c(rout): + return 0 + return issubroutine(rout) and hasassumedshape(rout) + + +def hasassumedshape(rout): + if rout.get('hasassumedshape'): + return True + for a in rout['args']: + for d in rout['vars'].get(a, {}).get('dimension', []): + if d == ':': + rout['hasassumedshape'] = True + return True + return False + + +def requiresf90wrapper(rout): + return ismoduleroutine(rout) or hasassumedshape(rout) + + +def isroutine(rout): + return isfunction(rout) or issubroutine(rout) + + +def islogicalfunction(rout): + if not isfunction(rout): + return 0 + if 'result' in rout: + a = rout['result'] + else: + a = rout['name'] + if a in rout['vars']: + return islogical(rout['vars'][a]) + return 0 + + +def islong_longfunction(rout): + if not isfunction(rout): + return 0 + if 'result' in rout: + a = rout['result'] + else: + a = rout['name'] + if a in rout['vars']: + return islong_long(rout['vars'][a]) + return 0 + + +def islong_doublefunction(rout): + if not isfunction(rout): + return 0 + if 'result' in rout: + a = rout['result'] + else: + a = rout['name'] + if a in rout['vars']: + return islong_double(rout['vars'][a]) + return 0 + + +def iscomplexfunction(rout): + if not isfunction(rout): + return 0 + if 'result' in rout: + a = rout['result'] + else: + a = rout['name'] + if a in rout['vars']: + return iscomplex(rout['vars'][a]) + return 0 + + +def iscomplexfunction_warn(rout): + if iscomplexfunction(rout): + outmess("""\ + ************************************************************** + Warning: code with a function returning complex value + may not work correctly with your Fortran compiler. + Run the following test before using it in your applications: + $(f2py install dir)/test-site/{b/runme_scalar,e/runme} + When using GNU gcc/g77 compilers, codes should work correctly. + **************************************************************\n""") + return 1 + return 0 + + +def isstringfunction(rout): + if not isfunction(rout): + return 0 + if 'result' in rout: + a = rout['result'] + else: + a = rout['name'] + if a in rout['vars']: + return isstring(rout['vars'][a]) + return 0 + + +def hasexternals(rout): + return 'externals' in rout and rout['externals'] + + +def isthreadsafe(rout): + return 'f2pyenhancements' in rout and \ + 'threadsafe' in rout['f2pyenhancements'] + + +def hasvariables(rout): + return 'vars' in rout and rout['vars'] + + +def isoptional(var): + return ('attrspec' in var and 'optional' in var['attrspec'] and + 'required' not in var['attrspec']) and isintent_nothide(var) + + +def isexternal(var): + return 'attrspec' in var and 'external' in var['attrspec'] + + +def isrequired(var): + return not isoptional(var) and isintent_nothide(var) + + +def isintent_in(var): + if 'intent' not in var: + return 1 + if 'hide' in var['intent']: + return 0 + if 'inplace' in var['intent']: + return 0 + if 'in' in var['intent']: + return 1 + if 'out' in var['intent']: + return 0 + if 'inout' in var['intent']: + return 0 + if 'outin' in var['intent']: + return 0 + return 1 + + +def isintent_inout(var): + return ('intent' in var and ('inout' in var['intent'] or + 'outin' in var['intent']) and 'in' not in var['intent'] and + 'hide' not in var['intent'] and 'inplace' not in var['intent']) + + +def isintent_out(var): + return 'out' in var.get('intent', []) + + +def isintent_hide(var): + return ('intent' in var and ('hide' in var['intent'] or + ('out' in var['intent'] and 'in' not in var['intent'] and + (not l_or(isintent_inout, isintent_inplace)(var))))) + +def isintent_nothide(var): + return not isintent_hide(var) + + +def isintent_c(var): + return 'c' in var.get('intent', []) + + +def isintent_cache(var): + return 'cache' in var.get('intent', []) + + +def isintent_copy(var): + return 'copy' in var.get('intent', []) + + +def isintent_overwrite(var): + return 'overwrite' in var.get('intent', []) + + +def isintent_callback(var): + return 'callback' in var.get('intent', []) + + +def isintent_inplace(var): + return 'inplace' in var.get('intent', []) + + +def isintent_aux(var): + return 'aux' in var.get('intent', []) + + +def isintent_aligned4(var): + return 'aligned4' in var.get('intent', []) + + +def isintent_aligned8(var): + return 'aligned8' in var.get('intent', []) + + +def isintent_aligned16(var): + return 'aligned16' in var.get('intent', []) + +isintent_dict = {isintent_in: 'INTENT_IN', isintent_inout: 'INTENT_INOUT', + isintent_out: 'INTENT_OUT', isintent_hide: 'INTENT_HIDE', + isintent_cache: 'INTENT_CACHE', + isintent_c: 'INTENT_C', isoptional: 'OPTIONAL', + isintent_inplace: 'INTENT_INPLACE', + isintent_aligned4: 'INTENT_ALIGNED4', + isintent_aligned8: 'INTENT_ALIGNED8', + isintent_aligned16: 'INTENT_ALIGNED16', + } + + +def isprivate(var): + return 'attrspec' in var and 'private' in var['attrspec'] + + +def hasinitvalue(var): + return '=' in var + + +def hasinitvalueasstring(var): + if not hasinitvalue(var): + return 0 + return var['='][0] in ['"', "'"] + + +def hasnote(var): + return 'note' in var + + +def hasresultnote(rout): + if not isfunction(rout): + return 0 + if 'result' in rout: + a = rout['result'] + else: + a = rout['name'] + if a in rout['vars']: + return hasnote(rout['vars'][a]) + return 0 + + +def hascommon(rout): + return 'common' in rout + + +def containscommon(rout): + if hascommon(rout): + return 1 + if hasbody(rout): + for b in rout['body']: + if containscommon(b): + return 1 + return 0 + + +def containsmodule(block): + if ismodule(block): + return 1 + if not hasbody(block): + return 0 + for b in block['body']: + if containsmodule(b): + return 1 + return 0 + + +def hasbody(rout): + return 'body' in rout + + +def hascallstatement(rout): + return getcallstatement(rout) is not None + + +def istrue(var): + return 1 + + +def isfalse(var): + return 0 + + +class F2PYError(Exception): + pass + + +class throw_error: + + def __init__(self, mess): + self.mess = mess + + def __call__(self, var): + mess = '\n\n var = %s\n Message: %s\n' % (var, self.mess) + raise F2PYError(mess) + + +def l_and(*f): + l, l2 = 'lambda v', [] + for i in range(len(f)): + l = '%s,f%d=f[%d]' % (l, i, i) + l2.append('f%d(v)' % (i)) + return eval('%s:%s' % (l, ' and '.join(l2))) + + +def l_or(*f): + l, l2 = 'lambda v', [] + for i in range(len(f)): + l = '%s,f%d=f[%d]' % (l, i, i) + l2.append('f%d(v)' % (i)) + return eval('%s:%s' % (l, ' or '.join(l2))) + + +def l_not(f): + return eval('lambda v,f=f:not f(v)') + + +def isdummyroutine(rout): + try: + return rout['f2pyenhancements']['fortranname'] == '' + except KeyError: + return 0 + + +def getfortranname(rout): + try: + name = rout['f2pyenhancements']['fortranname'] + if name == '': + raise KeyError + if not name: + errmess('Failed to use fortranname from %s\n' % + (rout['f2pyenhancements'])) + raise KeyError + except KeyError: + name = rout['name'] + return name + + +def getmultilineblock(rout, blockname, comment=1, counter=0): + try: + r = rout['f2pyenhancements'].get(blockname) + except KeyError: + return + if not r: + return + if counter > 0 and isinstance(r, str): + return + if isinstance(r, list): + if counter >= len(r): + return + r = r[counter] + if r[:3] == "'''": + if comment: + r = '\t/* start ' + blockname + \ + ' multiline (' + repr(counter) + ') */\n' + r[3:] + else: + r = r[3:] + if r[-3:] == "'''": + if comment: + r = r[:-3] + '\n\t/* end multiline (' + repr(counter) + ')*/' + else: + r = r[:-3] + else: + errmess("%s multiline block should end with `'''`: %s\n" + % (blockname, repr(r))) + return r + + +def getcallstatement(rout): + return getmultilineblock(rout, 'callstatement') + + +def getcallprotoargument(rout, cb_map={}): + r = getmultilineblock(rout, 'callprotoargument', comment=0) + if r: + return r + if hascallstatement(rout): + outmess( + 'warning: callstatement is defined without callprotoargument\n') + return + from .capi_maps import getctype + arg_types, arg_types2 = [], [] + if l_and(isstringfunction, l_not(isfunction_wrap))(rout): + arg_types.extend(['char*', 'size_t']) + for n in rout['args']: + var = rout['vars'][n] + if isintent_callback(var): + continue + if n in cb_map: + ctype = cb_map[n] + '_typedef' + else: + ctype = getctype(var) + if l_and(isintent_c, l_or(isscalar, iscomplex))(var): + pass + elif isstring(var): + pass + else: + ctype = ctype + '*' + if isstring(var) or isarrayofstrings(var): + arg_types2.append('size_t') + arg_types.append(ctype) + + proto_args = ','.join(arg_types + arg_types2) + if not proto_args: + proto_args = 'void' + return proto_args + + +def getusercode(rout): + return getmultilineblock(rout, 'usercode') + + +def getusercode1(rout): + return getmultilineblock(rout, 'usercode', counter=1) + + +def getpymethoddef(rout): + return getmultilineblock(rout, 'pymethoddef') + + +def getargs(rout): + sortargs, args = [], [] + if 'args' in rout: + args = rout['args'] + if 'sortvars' in rout: + for a in rout['sortvars']: + if a in args: + sortargs.append(a) + for a in args: + if a not in sortargs: + sortargs.append(a) + else: + sortargs = rout['args'] + return args, sortargs + + +def getargs2(rout): + sortargs, args = [], rout.get('args', []) + auxvars = [a for a in rout['vars'].keys() if isintent_aux(rout['vars'][a]) + and a not in args] + args = auxvars + args + if 'sortvars' in rout: + for a in rout['sortvars']: + if a in args: + sortargs.append(a) + for a in args: + if a not in sortargs: + sortargs.append(a) + else: + sortargs = auxvars + rout['args'] + return args, sortargs + + +def getrestdoc(rout): + if 'f2pymultilines' not in rout: + return None + k = None + if rout['block'] == 'python module': + k = rout['block'], rout['name'] + return rout['f2pymultilines'].get(k, None) + + +def gentitle(name): + l = (80 - len(name) - 6) // 2 + return '/*%s %s %s*/' % (l * '*', name, l * '*') + + +def flatlist(l): + if isinstance(l, list): + return reduce(lambda x, y, f=flatlist: x + f(y), l, []) + return [l] + + +def stripcomma(s): + if s and s[-1] == ',': + return s[:-1] + return s + + +def replace(str, d, defaultsep=''): + if isinstance(d, list): + return [replace(str, _m, defaultsep) for _m in d] + if isinstance(str, list): + return [replace(_m, d, defaultsep) for _m in str] + for k in 2 * list(d.keys()): + if k == 'separatorsfor': + continue + if 'separatorsfor' in d and k in d['separatorsfor']: + sep = d['separatorsfor'][k] + else: + sep = defaultsep + if isinstance(d[k], list): + str = str.replace('#%s#' % (k), sep.join(flatlist(d[k]))) + else: + str = str.replace('#%s#' % (k), d[k]) + return str + + +def dictappend(rd, ar): + if isinstance(ar, list): + for a in ar: + rd = dictappend(rd, a) + return rd + for k in ar.keys(): + if k[0] == '_': + continue + if k in rd: + if isinstance(rd[k], str): + rd[k] = [rd[k]] + if isinstance(rd[k], list): + if isinstance(ar[k], list): + rd[k] = rd[k] + ar[k] + else: + rd[k].append(ar[k]) + elif isinstance(rd[k], dict): + if isinstance(ar[k], dict): + if k == 'separatorsfor': + for k1 in ar[k].keys(): + if k1 not in rd[k]: + rd[k][k1] = ar[k][k1] + else: + rd[k] = dictappend(rd[k], ar[k]) + else: + rd[k] = ar[k] + return rd + + +def applyrules(rules, d, var={}): + ret = {} + if isinstance(rules, list): + for r in rules: + rr = applyrules(r, d, var) + ret = dictappend(ret, rr) + if '_break' in rr: + break + return ret + if '_check' in rules and (not rules['_check'](var)): + return ret + if 'need' in rules: + res = applyrules({'needs': rules['need']}, d, var) + if 'needs' in res: + cfuncs.append_needs(res['needs']) + + for k in rules.keys(): + if k == 'separatorsfor': + ret[k] = rules[k] + continue + if isinstance(rules[k], str): + ret[k] = replace(rules[k], d) + elif isinstance(rules[k], list): + ret[k] = [] + for i in rules[k]: + ar = applyrules({k: i}, d, var) + if k in ar: + ret[k].append(ar[k]) + elif k[0] == '_': + continue + elif isinstance(rules[k], dict): + ret[k] = [] + for k1 in rules[k].keys(): + if isinstance(k1, types.FunctionType) and k1(var): + if isinstance(rules[k][k1], list): + for i in rules[k][k1]: + if isinstance(i, dict): + res = applyrules({'supertext': i}, d, var) + if 'supertext' in res: + i = res['supertext'] + else: + i = '' + ret[k].append(replace(i, d)) + else: + i = rules[k][k1] + if isinstance(i, dict): + res = applyrules({'supertext': i}, d) + if 'supertext' in res: + i = res['supertext'] + else: + i = '' + ret[k].append(replace(i, d)) + else: + errmess('applyrules: ignoring rule %s.\n' % repr(rules[k])) + if isinstance(ret[k], list): + if len(ret[k]) == 1: + ret[k] = ret[k][0] + if ret[k] == []: + del ret[k] + return ret diff --git a/venv/Lib/site-packages/numpy/f2py/capi_maps.py b/venv/Lib/site-packages/numpy/f2py/capi_maps.py new file mode 100644 index 0000000..fe0d4a5 --- /dev/null +++ b/venv/Lib/site-packages/numpy/f2py/capi_maps.py @@ -0,0 +1,838 @@ +#!/usr/bin/env python3 +""" + +Copyright 1999,2000 Pearu Peterson all rights reserved, +Pearu Peterson +Permission to use, modify, and distribute this software is given under the +terms of the NumPy License. + +NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. +$Date: 2005/05/06 10:57:33 $ +Pearu Peterson + +""" +from . import __version__ +f2py_version = __version__.version + +import copy +import re +import os +from .crackfortran import markoutercomma +from . import cb_rules + +# The environment provided by auxfuncs.py is needed for some calls to eval. +# As the needed functions cannot be determined by static inspection of the +# code, it is safest to use import * pending a major refactoring of f2py. +from .auxfuncs import * + +__all__ = [ + 'getctype', 'getstrlength', 'getarrdims', 'getpydocsign', + 'getarrdocsign', 'getinit', 'sign2map', 'routsign2map', 'modsign2map', + 'cb_sign2map', 'cb_routsign2map', 'common_sign2map' +] + + +# Numarray and Numeric users should set this False +using_newcore = True + +depargs = [] +lcb_map = {} +lcb2_map = {} +# forced casting: mainly caused by the fact that Python or Numeric +# C/APIs do not support the corresponding C types. +c2py_map = {'double': 'float', + 'float': 'float', # forced casting + 'long_double': 'float', # forced casting + 'char': 'int', # forced casting + 'signed_char': 'int', # forced casting + 'unsigned_char': 'int', # forced casting + 'short': 'int', # forced casting + 'unsigned_short': 'int', # forced casting + 'int': 'int', # (forced casting) + 'long': 'int', + 'long_long': 'long', + 'unsigned': 'int', # forced casting + 'complex_float': 'complex', # forced casting + 'complex_double': 'complex', + 'complex_long_double': 'complex', # forced casting + 'string': 'string', + } +c2capi_map = {'double': 'NPY_DOUBLE', + 'float': 'NPY_FLOAT', + 'long_double': 'NPY_DOUBLE', # forced casting + 'char': 'NPY_STRING', + 'unsigned_char': 'NPY_UBYTE', + 'signed_char': 'NPY_BYTE', + 'short': 'NPY_SHORT', + 'unsigned_short': 'NPY_USHORT', + 'int': 'NPY_INT', + 'unsigned': 'NPY_UINT', + 'long': 'NPY_LONG', + 'long_long': 'NPY_LONG', # forced casting + 'complex_float': 'NPY_CFLOAT', + 'complex_double': 'NPY_CDOUBLE', + 'complex_long_double': 'NPY_CDOUBLE', # forced casting + 'string': 'NPY_STRING'} + +# These new maps aren't used anywhere yet, but should be by default +# unless building numeric or numarray extensions. +if using_newcore: + c2capi_map = {'double': 'NPY_DOUBLE', + 'float': 'NPY_FLOAT', + 'long_double': 'NPY_LONGDOUBLE', + 'char': 'NPY_BYTE', + 'unsigned_char': 'NPY_UBYTE', + 'signed_char': 'NPY_BYTE', + 'short': 'NPY_SHORT', + 'unsigned_short': 'NPY_USHORT', + 'int': 'NPY_INT', + 'unsigned': 'NPY_UINT', + 'long': 'NPY_LONG', + 'unsigned_long': 'NPY_ULONG', + 'long_long': 'NPY_LONGLONG', + 'unsigned_long_long': 'NPY_ULONGLONG', + 'complex_float': 'NPY_CFLOAT', + 'complex_double': 'NPY_CDOUBLE', + 'complex_long_double': 'NPY_CDOUBLE', + 'string':'NPY_STRING' + + } +c2pycode_map = {'double': 'd', + 'float': 'f', + 'long_double': 'd', # forced casting + 'char': '1', + 'signed_char': '1', + 'unsigned_char': 'b', + 'short': 's', + 'unsigned_short': 'w', + 'int': 'i', + 'unsigned': 'u', + 'long': 'l', + 'long_long': 'L', + 'complex_float': 'F', + 'complex_double': 'D', + 'complex_long_double': 'D', # forced casting + 'string': 'c' + } +if using_newcore: + c2pycode_map = {'double': 'd', + 'float': 'f', + 'long_double': 'g', + 'char': 'b', + 'unsigned_char': 'B', + 'signed_char': 'b', + 'short': 'h', + 'unsigned_short': 'H', + 'int': 'i', + 'unsigned': 'I', + 'long': 'l', + 'unsigned_long': 'L', + 'long_long': 'q', + 'unsigned_long_long': 'Q', + 'complex_float': 'F', + 'complex_double': 'D', + 'complex_long_double': 'G', + 'string': 'S'} +c2buildvalue_map = {'double': 'd', + 'float': 'f', + 'char': 'b', + 'signed_char': 'b', + 'short': 'h', + 'int': 'i', + 'long': 'l', + 'long_long': 'L', + 'complex_float': 'N', + 'complex_double': 'N', + 'complex_long_double': 'N', + 'string': 'y'} + +if using_newcore: + # c2buildvalue_map=??? + pass + +f2cmap_all = {'real': {'': 'float', '4': 'float', '8': 'double', + '12': 'long_double', '16': 'long_double'}, + 'integer': {'': 'int', '1': 'signed_char', '2': 'short', + '4': 'int', '8': 'long_long', + '-1': 'unsigned_char', '-2': 'unsigned_short', + '-4': 'unsigned', '-8': 'unsigned_long_long'}, + 'complex': {'': 'complex_float', '8': 'complex_float', + '16': 'complex_double', '24': 'complex_long_double', + '32': 'complex_long_double'}, + 'complexkind': {'': 'complex_float', '4': 'complex_float', + '8': 'complex_double', '12': 'complex_long_double', + '16': 'complex_long_double'}, + 'logical': {'': 'int', '1': 'char', '2': 'short', '4': 'int', + '8': 'long_long'}, + 'double complex': {'': 'complex_double'}, + 'double precision': {'': 'double'}, + 'byte': {'': 'char'}, + 'character': {'': 'string'} + } + +f2cmap_default = copy.deepcopy(f2cmap_all) + + +def load_f2cmap_file(f2cmap_file): + global f2cmap_all + + f2cmap_all = copy.deepcopy(f2cmap_default) + + if f2cmap_file is None: + # Default value + f2cmap_file = '.f2py_f2cmap' + if not os.path.isfile(f2cmap_file): + return + + # User defined additions to f2cmap_all. + # f2cmap_file must contain a dictionary of dictionaries, only. For + # example, {'real':{'low':'float'}} means that Fortran 'real(low)' is + # interpreted as C 'float'. This feature is useful for F90/95 users if + # they use PARAMETERSs in type specifications. + try: + outmess('Reading f2cmap from {!r} ...\n'.format(f2cmap_file)) + with open(f2cmap_file, 'r') as f: + d = eval(f.read(), {}, {}) + for k, d1 in list(d.items()): + for k1 in list(d1.keys()): + d1[k1.lower()] = d1[k1] + d[k.lower()] = d[k] + for k in list(d.keys()): + if k not in f2cmap_all: + f2cmap_all[k] = {} + for k1 in list(d[k].keys()): + if d[k][k1] in c2py_map: + if k1 in f2cmap_all[k]: + outmess( + "\tWarning: redefinition of {'%s':{'%s':'%s'->'%s'}}\n" % (k, k1, f2cmap_all[k][k1], d[k][k1])) + f2cmap_all[k][k1] = d[k][k1] + outmess('\tMapping "%s(kind=%s)" to "%s"\n' % + (k, k1, d[k][k1])) + else: + errmess("\tIgnoring map {'%s':{'%s':'%s'}}: '%s' must be in %s\n" % ( + k, k1, d[k][k1], d[k][k1], list(c2py_map.keys()))) + outmess('Successfully applied user defined f2cmap changes\n') + except Exception as msg: + errmess( + 'Failed to apply user defined f2cmap changes: %s. Skipping.\n' % (msg)) + +cformat_map = {'double': '%g', + 'float': '%g', + 'long_double': '%Lg', + 'char': '%d', + 'signed_char': '%d', + 'unsigned_char': '%hhu', + 'short': '%hd', + 'unsigned_short': '%hu', + 'int': '%d', + 'unsigned': '%u', + 'long': '%ld', + 'unsigned_long': '%lu', + 'long_long': '%ld', + 'complex_float': '(%g,%g)', + 'complex_double': '(%g,%g)', + 'complex_long_double': '(%Lg,%Lg)', + 'string': '%s', + } + +# Auxiliary functions + + +def getctype(var): + """ + Determines C type + """ + ctype = 'void' + if isfunction(var): + if 'result' in var: + a = var['result'] + else: + a = var['name'] + if a in var['vars']: + return getctype(var['vars'][a]) + else: + errmess('getctype: function %s has no return value?!\n' % a) + elif issubroutine(var): + return ctype + elif 'typespec' in var and var['typespec'].lower() in f2cmap_all: + typespec = var['typespec'].lower() + f2cmap = f2cmap_all[typespec] + ctype = f2cmap[''] # default type + if 'kindselector' in var: + if '*' in var['kindselector']: + try: + ctype = f2cmap[var['kindselector']['*']] + except KeyError: + errmess('getctype: "%s %s %s" not supported.\n' % + (var['typespec'], '*', var['kindselector']['*'])) + elif 'kind' in var['kindselector']: + if typespec + 'kind' in f2cmap_all: + f2cmap = f2cmap_all[typespec + 'kind'] + try: + ctype = f2cmap[var['kindselector']['kind']] + except KeyError: + if typespec in f2cmap_all: + f2cmap = f2cmap_all[typespec] + try: + ctype = f2cmap[str(var['kindselector']['kind'])] + except KeyError: + errmess('getctype: "%s(kind=%s)" is mapped to C "%s" (to override define dict(%s = dict(%s="")) in %s/.f2py_f2cmap file).\n' + % (typespec, var['kindselector']['kind'], ctype, + typespec, var['kindselector']['kind'], os.getcwd())) + + else: + if not isexternal(var): + errmess( + 'getctype: No C-type found in "%s", assuming void.\n' % var) + return ctype + + +def getstrlength(var): + if isstringfunction(var): + if 'result' in var: + a = var['result'] + else: + a = var['name'] + if a in var['vars']: + return getstrlength(var['vars'][a]) + else: + errmess('getstrlength: function %s has no return value?!\n' % a) + if not isstring(var): + errmess( + 'getstrlength: expected a signature of a string but got: %s\n' % (repr(var))) + len = '1' + if 'charselector' in var: + a = var['charselector'] + if '*' in a: + len = a['*'] + elif 'len' in a: + len = a['len'] + if re.match(r'\(\s*(\*|:)\s*\)', len) or re.match(r'(\*|:)', len): + if isintent_hide(var): + errmess('getstrlength:intent(hide): expected a string with defined length but got: %s\n' % ( + repr(var))) + len = '-1' + return len + + +def getarrdims(a, var, verbose=0): + ret = {} + if isstring(var) and not isarray(var): + ret['dims'] = getstrlength(var) + ret['size'] = ret['dims'] + ret['rank'] = '1' + elif isscalar(var): + ret['size'] = '1' + ret['rank'] = '0' + ret['dims'] = '' + elif isarray(var): + dim = copy.copy(var['dimension']) + ret['size'] = '*'.join(dim) + try: + ret['size'] = repr(eval(ret['size'])) + except Exception: + pass + ret['dims'] = ','.join(dim) + ret['rank'] = repr(len(dim)) + ret['rank*[-1]'] = repr(len(dim) * [-1])[1:-1] + for i in range(len(dim)): # solve dim for dependencies + v = [] + if dim[i] in depargs: + v = [dim[i]] + else: + for va in depargs: + if re.match(r'.*?\b%s\b.*' % va, dim[i]): + v.append(va) + for va in v: + if depargs.index(va) > depargs.index(a): + dim[i] = '*' + break + ret['setdims'], i = '', -1 + for d in dim: + i = i + 1 + if d not in ['*', ':', '(*)', '(:)']: + ret['setdims'] = '%s#varname#_Dims[%d]=%s,' % ( + ret['setdims'], i, d) + if ret['setdims']: + ret['setdims'] = ret['setdims'][:-1] + ret['cbsetdims'], i = '', -1 + for d in var['dimension']: + i = i + 1 + if d not in ['*', ':', '(*)', '(:)']: + ret['cbsetdims'] = '%s#varname#_Dims[%d]=%s,' % ( + ret['cbsetdims'], i, d) + elif isintent_in(var): + outmess('getarrdims:warning: assumed shape array, using 0 instead of %r\n' + % (d)) + ret['cbsetdims'] = '%s#varname#_Dims[%d]=%s,' % ( + ret['cbsetdims'], i, 0) + elif verbose: + errmess( + 'getarrdims: If in call-back function: array argument %s must have bounded dimensions: got %s\n' % (repr(a), repr(d))) + if ret['cbsetdims']: + ret['cbsetdims'] = ret['cbsetdims'][:-1] +# if not isintent_c(var): +# var['dimension'].reverse() + return ret + + +def getpydocsign(a, var): + global lcb_map + if isfunction(var): + if 'result' in var: + af = var['result'] + else: + af = var['name'] + if af in var['vars']: + return getpydocsign(af, var['vars'][af]) + else: + errmess('getctype: function %s has no return value?!\n' % af) + return '', '' + sig, sigout = a, a + opt = '' + if isintent_in(var): + opt = 'input' + elif isintent_inout(var): + opt = 'in/output' + out_a = a + if isintent_out(var): + for k in var['intent']: + if k[:4] == 'out=': + out_a = k[4:] + break + init = '' + ctype = getctype(var) + + if hasinitvalue(var): + init, showinit = getinit(a, var) + init = ', optional\\n Default: %s' % showinit + if isscalar(var): + if isintent_inout(var): + sig = '%s : %s rank-0 array(%s,\'%s\')%s' % (a, opt, c2py_map[ctype], + c2pycode_map[ctype], init) + else: + sig = '%s : %s %s%s' % (a, opt, c2py_map[ctype], init) + sigout = '%s : %s' % (out_a, c2py_map[ctype]) + elif isstring(var): + if isintent_inout(var): + sig = '%s : %s rank-0 array(string(len=%s),\'c\')%s' % ( + a, opt, getstrlength(var), init) + else: + sig = '%s : %s string(len=%s)%s' % ( + a, opt, getstrlength(var), init) + sigout = '%s : string(len=%s)' % (out_a, getstrlength(var)) + elif isarray(var): + dim = var['dimension'] + rank = repr(len(dim)) + sig = '%s : %s rank-%s array(\'%s\') with bounds (%s)%s' % (a, opt, rank, + c2pycode_map[ + ctype], + ','.join(dim), init) + if a == out_a: + sigout = '%s : rank-%s array(\'%s\') with bounds (%s)'\ + % (a, rank, c2pycode_map[ctype], ','.join(dim)) + else: + sigout = '%s : rank-%s array(\'%s\') with bounds (%s) and %s storage'\ + % (out_a, rank, c2pycode_map[ctype], ','.join(dim), a) + elif isexternal(var): + ua = '' + if a in lcb_map and lcb_map[a] in lcb2_map and 'argname' in lcb2_map[lcb_map[a]]: + ua = lcb2_map[lcb_map[a]]['argname'] + if not ua == a: + ua = ' => %s' % ua + else: + ua = '' + sig = '%s : call-back function%s' % (a, ua) + sigout = sig + else: + errmess( + 'getpydocsign: Could not resolve docsignature for "%s".\\n' % a) + return sig, sigout + + +def getarrdocsign(a, var): + ctype = getctype(var) + if isstring(var) and (not isarray(var)): + sig = '%s : rank-0 array(string(len=%s),\'c\')' % (a, + getstrlength(var)) + elif isscalar(var): + sig = '%s : rank-0 array(%s,\'%s\')' % (a, c2py_map[ctype], + c2pycode_map[ctype],) + elif isarray(var): + dim = var['dimension'] + rank = repr(len(dim)) + sig = '%s : rank-%s array(\'%s\') with bounds (%s)' % (a, rank, + c2pycode_map[ + ctype], + ','.join(dim)) + return sig + + +def getinit(a, var): + if isstring(var): + init, showinit = '""', "''" + else: + init, showinit = '', '' + if hasinitvalue(var): + init = var['='] + showinit = init + if iscomplex(var) or iscomplexarray(var): + ret = {} + + try: + v = var["="] + if ',' in v: + ret['init.r'], ret['init.i'] = markoutercomma( + v[1:-1]).split('@,@') + else: + v = eval(v, {}, {}) + ret['init.r'], ret['init.i'] = str(v.real), str(v.imag) + except Exception: + raise ValueError( + 'getinit: expected complex number `(r,i)\' but got `%s\' as initial value of %r.' % (init, a)) + if isarray(var): + init = '(capi_c.r=%s,capi_c.i=%s,capi_c)' % ( + ret['init.r'], ret['init.i']) + elif isstring(var): + if not init: + init, showinit = '""', "''" + if init[0] == "'": + init = '"%s"' % (init[1:-1].replace('"', '\\"')) + if init[0] == '"': + showinit = "'%s'" % (init[1:-1]) + return init, showinit + + +def sign2map(a, var): + """ + varname,ctype,atype + init,init.r,init.i,pytype + vardebuginfo,vardebugshowvalue,varshowvalue + varrfromat + intent + """ + out_a = a + if isintent_out(var): + for k in var['intent']: + if k[:4] == 'out=': + out_a = k[4:] + break + ret = {'varname': a, 'outvarname': out_a, 'ctype': getctype(var)} + intent_flags = [] + for f, s in isintent_dict.items(): + if f(var): + intent_flags.append('F2PY_%s' % s) + if intent_flags: + # XXX: Evaluate intent_flags here. + ret['intent'] = '|'.join(intent_flags) + else: + ret['intent'] = 'F2PY_INTENT_IN' + if isarray(var): + ret['varrformat'] = 'N' + elif ret['ctype'] in c2buildvalue_map: + ret['varrformat'] = c2buildvalue_map[ret['ctype']] + else: + ret['varrformat'] = 'O' + ret['init'], ret['showinit'] = getinit(a, var) + if hasinitvalue(var) and iscomplex(var) and not isarray(var): + ret['init.r'], ret['init.i'] = markoutercomma( + ret['init'][1:-1]).split('@,@') + if isexternal(var): + ret['cbnamekey'] = a + if a in lcb_map: + ret['cbname'] = lcb_map[a] + ret['maxnofargs'] = lcb2_map[lcb_map[a]]['maxnofargs'] + ret['nofoptargs'] = lcb2_map[lcb_map[a]]['nofoptargs'] + ret['cbdocstr'] = lcb2_map[lcb_map[a]]['docstr'] + ret['cblatexdocstr'] = lcb2_map[lcb_map[a]]['latexdocstr'] + else: + ret['cbname'] = a + errmess('sign2map: Confused: external %s is not in lcb_map%s.\n' % ( + a, list(lcb_map.keys()))) + if isstring(var): + ret['length'] = getstrlength(var) + if isarray(var): + ret = dictappend(ret, getarrdims(a, var)) + dim = copy.copy(var['dimension']) + if ret['ctype'] in c2capi_map: + ret['atype'] = c2capi_map[ret['ctype']] + # Debug info + if debugcapi(var): + il = [isintent_in, 'input', isintent_out, 'output', + isintent_inout, 'inoutput', isrequired, 'required', + isoptional, 'optional', isintent_hide, 'hidden', + iscomplex, 'complex scalar', + l_and(isscalar, l_not(iscomplex)), 'scalar', + isstring, 'string', isarray, 'array', + iscomplexarray, 'complex array', isstringarray, 'string array', + iscomplexfunction, 'complex function', + l_and(isfunction, l_not(iscomplexfunction)), 'function', + isexternal, 'callback', + isintent_callback, 'callback', + isintent_aux, 'auxiliary', + ] + rl = [] + for i in range(0, len(il), 2): + if il[i](var): + rl.append(il[i + 1]) + if isstring(var): + rl.append('slen(%s)=%s' % (a, ret['length'])) + if isarray(var): + ddim = ','.join( + map(lambda x, y: '%s|%s' % (x, y), var['dimension'], dim)) + rl.append('dims(%s)' % ddim) + if isexternal(var): + ret['vardebuginfo'] = 'debug-capi:%s=>%s:%s' % ( + a, ret['cbname'], ','.join(rl)) + else: + ret['vardebuginfo'] = 'debug-capi:%s %s=%s:%s' % ( + ret['ctype'], a, ret['showinit'], ','.join(rl)) + if isscalar(var): + if ret['ctype'] in cformat_map: + ret['vardebugshowvalue'] = 'debug-capi:%s=%s' % ( + a, cformat_map[ret['ctype']]) + if isstring(var): + ret['vardebugshowvalue'] = 'debug-capi:slen(%s)=%%d %s=\\"%%s\\"' % ( + a, a) + if isexternal(var): + ret['vardebugshowvalue'] = 'debug-capi:%s=%%p' % (a) + if ret['ctype'] in cformat_map: + ret['varshowvalue'] = '#name#:%s=%s' % (a, cformat_map[ret['ctype']]) + ret['showvalueformat'] = '%s' % (cformat_map[ret['ctype']]) + if isstring(var): + ret['varshowvalue'] = '#name#:slen(%s)=%%d %s=\\"%%s\\"' % (a, a) + ret['pydocsign'], ret['pydocsignout'] = getpydocsign(a, var) + if hasnote(var): + ret['note'] = var['note'] + return ret + + +def routsign2map(rout): + """ + name,NAME,begintitle,endtitle + rname,ctype,rformat + routdebugshowvalue + """ + global lcb_map + name = rout['name'] + fname = getfortranname(rout) + ret = {'name': name, + 'texname': name.replace('_', '\\_'), + 'name_lower': name.lower(), + 'NAME': name.upper(), + 'begintitle': gentitle(name), + 'endtitle': gentitle('end of %s' % name), + 'fortranname': fname, + 'FORTRANNAME': fname.upper(), + 'callstatement': getcallstatement(rout) or '', + 'usercode': getusercode(rout) or '', + 'usercode1': getusercode1(rout) or '', + } + if '_' in fname: + ret['F_FUNC'] = 'F_FUNC_US' + else: + ret['F_FUNC'] = 'F_FUNC' + if '_' in name: + ret['F_WRAPPEDFUNC'] = 'F_WRAPPEDFUNC_US' + else: + ret['F_WRAPPEDFUNC'] = 'F_WRAPPEDFUNC' + lcb_map = {} + if 'use' in rout: + for u in rout['use'].keys(): + if u in cb_rules.cb_map: + for un in cb_rules.cb_map[u]: + ln = un[0] + if 'map' in rout['use'][u]: + for k in rout['use'][u]['map'].keys(): + if rout['use'][u]['map'][k] == un[0]: + ln = k + break + lcb_map[ln] = un[1] + elif 'externals' in rout and rout['externals']: + errmess('routsign2map: Confused: function %s has externals %s but no "use" statement.\n' % ( + ret['name'], repr(rout['externals']))) + ret['callprotoargument'] = getcallprotoargument(rout, lcb_map) or '' + if isfunction(rout): + if 'result' in rout: + a = rout['result'] + else: + a = rout['name'] + ret['rname'] = a + ret['pydocsign'], ret['pydocsignout'] = getpydocsign(a, rout) + ret['ctype'] = getctype(rout['vars'][a]) + if hasresultnote(rout): + ret['resultnote'] = rout['vars'][a]['note'] + rout['vars'][a]['note'] = ['See elsewhere.'] + if ret['ctype'] in c2buildvalue_map: + ret['rformat'] = c2buildvalue_map[ret['ctype']] + else: + ret['rformat'] = 'O' + errmess('routsign2map: no c2buildvalue key for type %s\n' % + (repr(ret['ctype']))) + if debugcapi(rout): + if ret['ctype'] in cformat_map: + ret['routdebugshowvalue'] = 'debug-capi:%s=%s' % ( + a, cformat_map[ret['ctype']]) + if isstringfunction(rout): + ret['routdebugshowvalue'] = 'debug-capi:slen(%s)=%%d %s=\\"%%s\\"' % ( + a, a) + if isstringfunction(rout): + ret['rlength'] = getstrlength(rout['vars'][a]) + if ret['rlength'] == '-1': + errmess('routsign2map: expected explicit specification of the length of the string returned by the fortran function %s; taking 10.\n' % ( + repr(rout['name']))) + ret['rlength'] = '10' + if hasnote(rout): + ret['note'] = rout['note'] + rout['note'] = ['See elsewhere.'] + return ret + + +def modsign2map(m): + """ + modulename + """ + if ismodule(m): + ret = {'f90modulename': m['name'], + 'F90MODULENAME': m['name'].upper(), + 'texf90modulename': m['name'].replace('_', '\\_')} + else: + ret = {'modulename': m['name'], + 'MODULENAME': m['name'].upper(), + 'texmodulename': m['name'].replace('_', '\\_')} + ret['restdoc'] = getrestdoc(m) or [] + if hasnote(m): + ret['note'] = m['note'] + ret['usercode'] = getusercode(m) or '' + ret['usercode1'] = getusercode1(m) or '' + if m['body']: + ret['interface_usercode'] = getusercode(m['body'][0]) or '' + else: + ret['interface_usercode'] = '' + ret['pymethoddef'] = getpymethoddef(m) or '' + if 'coutput' in m: + ret['coutput'] = m['coutput'] + if 'f2py_wrapper_output' in m: + ret['f2py_wrapper_output'] = m['f2py_wrapper_output'] + return ret + + +def cb_sign2map(a, var, index=None): + ret = {'varname': a} + ret['varname_i'] = ret['varname'] + ret['ctype'] = getctype(var) + if ret['ctype'] in c2capi_map: + ret['atype'] = c2capi_map[ret['ctype']] + if ret['ctype'] in cformat_map: + ret['showvalueformat'] = '%s' % (cformat_map[ret['ctype']]) + if isarray(var): + ret = dictappend(ret, getarrdims(a, var)) + ret['pydocsign'], ret['pydocsignout'] = getpydocsign(a, var) + if hasnote(var): + ret['note'] = var['note'] + var['note'] = ['See elsewhere.'] + return ret + + +def cb_routsign2map(rout, um): + """ + name,begintitle,endtitle,argname + ctype,rctype,maxnofargs,nofoptargs,returncptr + """ + ret = {'name': 'cb_%s_in_%s' % (rout['name'], um), + 'returncptr': ''} + if isintent_callback(rout): + if '_' in rout['name']: + F_FUNC = 'F_FUNC_US' + else: + F_FUNC = 'F_FUNC' + ret['callbackname'] = '%s(%s,%s)' \ + % (F_FUNC, + rout['name'].lower(), + rout['name'].upper(), + ) + ret['static'] = 'extern' + else: + ret['callbackname'] = ret['name'] + ret['static'] = 'static' + ret['argname'] = rout['name'] + ret['begintitle'] = gentitle(ret['name']) + ret['endtitle'] = gentitle('end of %s' % ret['name']) + ret['ctype'] = getctype(rout) + ret['rctype'] = 'void' + if ret['ctype'] == 'string': + ret['rctype'] = 'void' + else: + ret['rctype'] = ret['ctype'] + if ret['rctype'] != 'void': + if iscomplexfunction(rout): + ret['returncptr'] = """ +#ifdef F2PY_CB_RETURNCOMPLEX +return_value= +#endif +""" + else: + ret['returncptr'] = 'return_value=' + if ret['ctype'] in cformat_map: + ret['showvalueformat'] = '%s' % (cformat_map[ret['ctype']]) + if isstringfunction(rout): + ret['strlength'] = getstrlength(rout) + if isfunction(rout): + if 'result' in rout: + a = rout['result'] + else: + a = rout['name'] + if hasnote(rout['vars'][a]): + ret['note'] = rout['vars'][a]['note'] + rout['vars'][a]['note'] = ['See elsewhere.'] + ret['rname'] = a + ret['pydocsign'], ret['pydocsignout'] = getpydocsign(a, rout) + if iscomplexfunction(rout): + ret['rctype'] = """ +#ifdef F2PY_CB_RETURNCOMPLEX +#ctype# +#else +void +#endif +""" + else: + if hasnote(rout): + ret['note'] = rout['note'] + rout['note'] = ['See elsewhere.'] + nofargs = 0 + nofoptargs = 0 + if 'args' in rout and 'vars' in rout: + for a in rout['args']: + var = rout['vars'][a] + if l_or(isintent_in, isintent_inout)(var): + nofargs = nofargs + 1 + if isoptional(var): + nofoptargs = nofoptargs + 1 + ret['maxnofargs'] = repr(nofargs) + ret['nofoptargs'] = repr(nofoptargs) + if hasnote(rout) and isfunction(rout) and 'result' in rout: + ret['routnote'] = rout['note'] + rout['note'] = ['See elsewhere.'] + return ret + + +def common_sign2map(a, var): # obsolute + ret = {'varname': a, 'ctype': getctype(var)} + if isstringarray(var): + ret['ctype'] = 'char' + if ret['ctype'] in c2capi_map: + ret['atype'] = c2capi_map[ret['ctype']] + if ret['ctype'] in cformat_map: + ret['showvalueformat'] = '%s' % (cformat_map[ret['ctype']]) + if isarray(var): + ret = dictappend(ret, getarrdims(a, var)) + elif isstring(var): + ret['size'] = getstrlength(var) + ret['rank'] = '1' + ret['pydocsign'], ret['pydocsignout'] = getpydocsign(a, var) + if hasnote(var): + ret['note'] = var['note'] + var['note'] = ['See elsewhere.'] + # for strings this returns 0-rank but actually is 1-rank + ret['arrdocstr'] = getarrdocsign(a, var) + return ret diff --git a/venv/Lib/site-packages/numpy/f2py/cb_rules.py b/venv/Lib/site-packages/numpy/f2py/cb_rules.py new file mode 100644 index 0000000..62aa2fc --- /dev/null +++ b/venv/Lib/site-packages/numpy/f2py/cb_rules.py @@ -0,0 +1,616 @@ +#!/usr/bin/env python3 +""" + +Build call-back mechanism for f2py2e. + +Copyright 2000 Pearu Peterson all rights reserved, +Pearu Peterson +Permission to use, modify, and distribute this software is given under the +terms of the NumPy License. + +NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. +$Date: 2005/07/20 11:27:58 $ +Pearu Peterson + +""" +from . import __version__ +from .auxfuncs import ( + applyrules, debugcapi, dictappend, errmess, getargs, hasnote, isarray, + iscomplex, iscomplexarray, iscomplexfunction, isfunction, isintent_c, + isintent_hide, isintent_in, isintent_inout, isintent_nothide, + isintent_out, isoptional, isrequired, isscalar, isstring, + isstringfunction, issubroutine, l_and, l_not, l_or, outmess, replace, + stripcomma, throw_error +) +from . import cfuncs + +f2py_version = __version__.version + + +################## Rules for callback function ############## + +cb_routine_rules = { + 'cbtypedefs': 'typedef #rctype#(*#name#_typedef)(#optargs_td##args_td##strarglens_td##noargs#);', + 'body': """ +#begintitle# +typedef struct { + PyObject *capi; + PyTupleObject *args_capi; + int nofargs; + jmp_buf jmpbuf; +} #name#_t; + +#if defined(F2PY_THREAD_LOCAL_DECL) && !defined(F2PY_USE_PYTHON_TLS) + +static F2PY_THREAD_LOCAL_DECL #name#_t *_active_#name# = NULL; + +static #name#_t *swap_active_#name#(#name#_t *ptr) { + #name#_t *prev = _active_#name#; + _active_#name# = ptr; + return prev; +} + +static #name#_t *get_active_#name#(void) { + return _active_#name#; +} + +#else + +static #name#_t *swap_active_#name#(#name#_t *ptr) { + char *key = "__f2py_cb_#name#"; + return (#name#_t *)F2PySwapThreadLocalCallbackPtr(key, ptr); +} + +static #name#_t *get_active_#name#(void) { + char *key = "__f2py_cb_#name#"; + return (#name#_t *)F2PyGetThreadLocalCallbackPtr(key); +} + +#endif + +/*typedef #rctype#(*#name#_typedef)(#optargs_td##args_td##strarglens_td##noargs#);*/ +#static# #rctype# #callbackname# (#optargs##args##strarglens##noargs#) { + #name#_t cb_local = { NULL, NULL, 0 }; + #name#_t *cb = NULL; + PyTupleObject *capi_arglist = NULL; + PyObject *capi_return = NULL; + PyObject *capi_tmp = NULL; + PyObject *capi_arglist_list = NULL; + int capi_j,capi_i = 0; + int capi_longjmp_ok = 1; +#decl# +#ifdef F2PY_REPORT_ATEXIT +f2py_cb_start_clock(); +#endif + cb = get_active_#name#(); + if (cb == NULL) { + capi_longjmp_ok = 0; + cb = &cb_local; + } + capi_arglist = cb->args_capi; + CFUNCSMESS(\"cb:Call-back function #name# (maxnofargs=#maxnofargs#(-#nofoptargs#))\\n\"); + CFUNCSMESSPY(\"cb:#name#_capi=\",cb->capi); + if (cb->capi==NULL) { + capi_longjmp_ok = 0; + cb->capi = PyObject_GetAttrString(#modulename#_module,\"#argname#\"); + CFUNCSMESSPY(\"cb:#name#_capi=\",cb->capi); + } + if (cb->capi==NULL) { + PyErr_SetString(#modulename#_error,\"cb: Callback #argname# not defined (as an argument or module #modulename# attribute).\\n\"); + goto capi_fail; + } + if (F2PyCapsule_Check(cb->capi)) { + #name#_typedef #name#_cptr; + #name#_cptr = F2PyCapsule_AsVoidPtr(cb->capi); + #returncptr#(*#name#_cptr)(#optargs_nm##args_nm##strarglens_nm#); + #return# + } + if (capi_arglist==NULL) { + capi_longjmp_ok = 0; + capi_tmp = PyObject_GetAttrString(#modulename#_module,\"#argname#_extra_args\"); + if (capi_tmp) { + capi_arglist = (PyTupleObject *)PySequence_Tuple(capi_tmp); + if (capi_arglist==NULL) { + PyErr_SetString(#modulename#_error,\"Failed to convert #modulename#.#argname#_extra_args to tuple.\\n\"); + goto capi_fail; + } + } else { + PyErr_Clear(); + capi_arglist = (PyTupleObject *)Py_BuildValue(\"()\"); + } + } + if (capi_arglist == NULL) { + PyErr_SetString(#modulename#_error,\"Callback #argname# argument list is not set.\\n\"); + goto capi_fail; + } +#setdims# +#ifdef PYPY_VERSION +#define CAPI_ARGLIST_SETITEM(idx, value) PyList_SetItem((PyObject *)capi_arglist_list, idx, value) + capi_arglist_list = PySequence_List(capi_arglist); + if (capi_arglist_list == NULL) goto capi_fail; +#else +#define CAPI_ARGLIST_SETITEM(idx, value) PyTuple_SetItem((PyObject *)capi_arglist, idx, value) +#endif +#pyobjfrom# +#undef CAPI_ARGLIST_SETITEM +#ifdef PYPY_VERSION + CFUNCSMESSPY(\"cb:capi_arglist=\",capi_arglist_list); +#else + CFUNCSMESSPY(\"cb:capi_arglist=\",capi_arglist); +#endif + CFUNCSMESS(\"cb:Call-back calling Python function #argname#.\\n\"); +#ifdef F2PY_REPORT_ATEXIT +f2py_cb_start_call_clock(); +#endif +#ifdef PYPY_VERSION + capi_return = PyObject_CallObject(cb->capi,(PyObject *)capi_arglist_list); + Py_DECREF(capi_arglist_list); + capi_arglist_list = NULL; +#else + capi_return = PyObject_CallObject(cb->capi,(PyObject *)capi_arglist); +#endif +#ifdef F2PY_REPORT_ATEXIT +f2py_cb_stop_call_clock(); +#endif + CFUNCSMESSPY(\"cb:capi_return=\",capi_return); + if (capi_return == NULL) { + fprintf(stderr,\"capi_return is NULL\\n\"); + goto capi_fail; + } + if (capi_return == Py_None) { + Py_DECREF(capi_return); + capi_return = Py_BuildValue(\"()\"); + } + else if (!PyTuple_Check(capi_return)) { + capi_return = Py_BuildValue(\"(N)\",capi_return); + } + capi_j = PyTuple_Size(capi_return); + capi_i = 0; +#frompyobj# + CFUNCSMESS(\"cb:#name#:successful\\n\"); + Py_DECREF(capi_return); +#ifdef F2PY_REPORT_ATEXIT +f2py_cb_stop_clock(); +#endif + goto capi_return_pt; +capi_fail: + fprintf(stderr,\"Call-back #name# failed.\\n\"); + Py_XDECREF(capi_return); + Py_XDECREF(capi_arglist_list); + if (capi_longjmp_ok) { + longjmp(cb->jmpbuf,-1); + } +capi_return_pt: + ; +#return# +} +#endtitle# +""", + 'need': ['setjmp.h', 'CFUNCSMESS', 'F2PY_THREAD_LOCAL_DECL'], + 'maxnofargs': '#maxnofargs#', + 'nofoptargs': '#nofoptargs#', + 'docstr': """\ +\tdef #argname#(#docsignature#): return #docreturn#\\n\\ +#docstrsigns#""", + 'latexdocstr': """ +{{}\\verb@def #argname#(#latexdocsignature#): return #docreturn#@{}} +#routnote# + +#latexdocstrsigns#""", + 'docstrshort': 'def #argname#(#docsignature#): return #docreturn#' +} +cb_rout_rules = [ + { # Init + 'separatorsfor': {'decl': '\n', + 'args': ',', 'optargs': '', 'pyobjfrom': '\n', 'freemem': '\n', + 'args_td': ',', 'optargs_td': '', + 'args_nm': ',', 'optargs_nm': '', + 'frompyobj': '\n', 'setdims': '\n', + 'docstrsigns': '\\n"\n"', + 'latexdocstrsigns': '\n', + 'latexdocstrreq': '\n', 'latexdocstropt': '\n', + 'latexdocstrout': '\n', 'latexdocstrcbs': '\n', + }, + 'decl': '/*decl*/', 'pyobjfrom': '/*pyobjfrom*/', 'frompyobj': '/*frompyobj*/', + 'args': [], 'optargs': '', 'return': '', 'strarglens': '', 'freemem': '/*freemem*/', + 'args_td': [], 'optargs_td': '', 'strarglens_td': '', + 'args_nm': [], 'optargs_nm': '', 'strarglens_nm': '', + 'noargs': '', + 'setdims': '/*setdims*/', + 'docstrsigns': '', 'latexdocstrsigns': '', + 'docstrreq': '\tRequired arguments:', + 'docstropt': '\tOptional arguments:', + 'docstrout': '\tReturn objects:', + 'docstrcbs': '\tCall-back functions:', + 'docreturn': '', 'docsign': '', 'docsignopt': '', + 'latexdocstrreq': '\\noindent Required arguments:', + 'latexdocstropt': '\\noindent Optional arguments:', + 'latexdocstrout': '\\noindent Return objects:', + 'latexdocstrcbs': '\\noindent Call-back functions:', + 'routnote': {hasnote: '--- #note#', l_not(hasnote): ''}, + }, { # Function + 'decl': ' #ctype# return_value;', + 'frompyobj': [{debugcapi: ' CFUNCSMESS("cb:Getting return_value->");'}, + ' if (capi_j>capi_i)\n GETSCALARFROMPYTUPLE(capi_return,capi_i++,&return_value,#ctype#,"#ctype#_from_pyobj failed in converting return_value of call-back function #name# to C #ctype#\\n");', + {debugcapi: + ' fprintf(stderr,"#showvalueformat#.\\n",return_value);'} + ], + 'need': ['#ctype#_from_pyobj', {debugcapi: 'CFUNCSMESS'}, 'GETSCALARFROMPYTUPLE'], + 'return': ' return return_value;', + '_check': l_and(isfunction, l_not(isstringfunction), l_not(iscomplexfunction)) + }, + { # String function + 'pyobjfrom': {debugcapi: ' fprintf(stderr,"debug-capi:cb:#name#:%d:\\n",return_value_len);'}, + 'args': '#ctype# return_value,int return_value_len', + 'args_nm': 'return_value,&return_value_len', + 'args_td': '#ctype# ,int', + 'frompyobj': [{debugcapi: ' CFUNCSMESS("cb:Getting return_value->\\"");'}, + """ if (capi_j>capi_i) + GETSTRFROMPYTUPLE(capi_return,capi_i++,return_value,return_value_len);""", + {debugcapi: + ' fprintf(stderr,"#showvalueformat#\\".\\n",return_value);'} + ], + 'need': ['#ctype#_from_pyobj', {debugcapi: 'CFUNCSMESS'}, + 'string.h', 'GETSTRFROMPYTUPLE'], + 'return': 'return;', + '_check': isstringfunction + }, + { # Complex function + 'optargs': """ +#ifndef F2PY_CB_RETURNCOMPLEX +#ctype# *return_value +#endif +""", + 'optargs_nm': """ +#ifndef F2PY_CB_RETURNCOMPLEX +return_value +#endif +""", + 'optargs_td': """ +#ifndef F2PY_CB_RETURNCOMPLEX +#ctype# * +#endif +""", + 'decl': """ +#ifdef F2PY_CB_RETURNCOMPLEX + #ctype# return_value; +#endif +""", + 'frompyobj': [{debugcapi: ' CFUNCSMESS("cb:Getting return_value->");'}, + """\ + if (capi_j>capi_i) +#ifdef F2PY_CB_RETURNCOMPLEX + GETSCALARFROMPYTUPLE(capi_return,capi_i++,&return_value,#ctype#,\"#ctype#_from_pyobj failed in converting return_value of call-back function #name# to C #ctype#\\n\"); +#else + GETSCALARFROMPYTUPLE(capi_return,capi_i++,return_value,#ctype#,\"#ctype#_from_pyobj failed in converting return_value of call-back function #name# to C #ctype#\\n\"); +#endif +""", + {debugcapi: """ +#ifdef F2PY_CB_RETURNCOMPLEX + fprintf(stderr,\"#showvalueformat#.\\n\",(return_value).r,(return_value).i); +#else + fprintf(stderr,\"#showvalueformat#.\\n\",(*return_value).r,(*return_value).i); +#endif + +"""} + ], + 'return': """ +#ifdef F2PY_CB_RETURNCOMPLEX + return return_value; +#else + return; +#endif +""", + 'need': ['#ctype#_from_pyobj', {debugcapi: 'CFUNCSMESS'}, + 'string.h', 'GETSCALARFROMPYTUPLE', '#ctype#'], + '_check': iscomplexfunction + }, + {'docstrout': '\t\t#pydocsignout#', + 'latexdocstrout': ['\\item[]{{}\\verb@#pydocsignout#@{}}', + {hasnote: '--- #note#'}], + 'docreturn': '#rname#,', + '_check': isfunction}, + {'_check': issubroutine, 'return': 'return;'} +] + +cb_arg_rules = [ + { # Doc + 'docstropt': {l_and(isoptional, isintent_nothide): '\t\t#pydocsign#'}, + 'docstrreq': {l_and(isrequired, isintent_nothide): '\t\t#pydocsign#'}, + 'docstrout': {isintent_out: '\t\t#pydocsignout#'}, + 'latexdocstropt': {l_and(isoptional, isintent_nothide): ['\\item[]{{}\\verb@#pydocsign#@{}}', + {hasnote: '--- #note#'}]}, + 'latexdocstrreq': {l_and(isrequired, isintent_nothide): ['\\item[]{{}\\verb@#pydocsign#@{}}', + {hasnote: '--- #note#'}]}, + 'latexdocstrout': {isintent_out: ['\\item[]{{}\\verb@#pydocsignout#@{}}', + {l_and(hasnote, isintent_hide): '--- #note#', + l_and(hasnote, isintent_nothide): '--- See above.'}]}, + 'docsign': {l_and(isrequired, isintent_nothide): '#varname#,'}, + 'docsignopt': {l_and(isoptional, isintent_nothide): '#varname#,'}, + 'depend': '' + }, + { + 'args': { + l_and(isscalar, isintent_c): '#ctype# #varname_i#', + l_and(isscalar, l_not(isintent_c)): '#ctype# *#varname_i#_cb_capi', + isarray: '#ctype# *#varname_i#', + isstring: '#ctype# #varname_i#' + }, + 'args_nm': { + l_and(isscalar, isintent_c): '#varname_i#', + l_and(isscalar, l_not(isintent_c)): '#varname_i#_cb_capi', + isarray: '#varname_i#', + isstring: '#varname_i#' + }, + 'args_td': { + l_and(isscalar, isintent_c): '#ctype#', + l_and(isscalar, l_not(isintent_c)): '#ctype# *', + isarray: '#ctype# *', + isstring: '#ctype#' + }, + 'need': {l_or(isscalar, isarray, isstring): '#ctype#'}, + # untested with multiple args + 'strarglens': {isstring: ',int #varname_i#_cb_len'}, + 'strarglens_td': {isstring: ',int'}, # untested with multiple args + # untested with multiple args + 'strarglens_nm': {isstring: ',#varname_i#_cb_len'}, + }, + { # Scalars + 'decl': {l_not(isintent_c): ' #ctype# #varname_i#=(*#varname_i#_cb_capi);'}, + 'error': {l_and(isintent_c, isintent_out, + throw_error('intent(c,out) is forbidden for callback scalar arguments')): + ''}, + 'frompyobj': [{debugcapi: ' CFUNCSMESS("cb:Getting #varname#->");'}, + {isintent_out: + ' if (capi_j>capi_i)\n GETSCALARFROMPYTUPLE(capi_return,capi_i++,#varname_i#_cb_capi,#ctype#,"#ctype#_from_pyobj failed in converting argument #varname# of call-back function #name# to C #ctype#\\n");'}, + {l_and(debugcapi, l_and(l_not(iscomplex), isintent_c)): + ' fprintf(stderr,"#showvalueformat#.\\n",#varname_i#);'}, + {l_and(debugcapi, l_and(l_not(iscomplex), l_not( isintent_c))): + ' fprintf(stderr,"#showvalueformat#.\\n",*#varname_i#_cb_capi);'}, + {l_and(debugcapi, l_and(iscomplex, isintent_c)): + ' fprintf(stderr,"#showvalueformat#.\\n",(#varname_i#).r,(#varname_i#).i);'}, + {l_and(debugcapi, l_and(iscomplex, l_not( isintent_c))): + ' fprintf(stderr,"#showvalueformat#.\\n",(*#varname_i#_cb_capi).r,(*#varname_i#_cb_capi).i);'}, + ], + 'need': [{isintent_out: ['#ctype#_from_pyobj', 'GETSCALARFROMPYTUPLE']}, + {debugcapi: 'CFUNCSMESS'}], + '_check': isscalar + }, { + 'pyobjfrom': [{isintent_in: """\ + if (cb->nofargs>capi_i) + if (CAPI_ARGLIST_SETITEM(capi_i++,pyobj_from_#ctype#1(#varname_i#))) + goto capi_fail;"""}, + {isintent_inout: """\ + if (cb->nofargs>capi_i) + if (CAPI_ARGLIST_SETITEM(capi_i++,pyarr_from_p_#ctype#1(#varname_i#_cb_capi))) + goto capi_fail;"""}], + 'need': [{isintent_in: 'pyobj_from_#ctype#1'}, + {isintent_inout: 'pyarr_from_p_#ctype#1'}, + {iscomplex: '#ctype#'}], + '_check': l_and(isscalar, isintent_nothide), + '_optional': '' + }, { # String + 'frompyobj': [{debugcapi: ' CFUNCSMESS("cb:Getting #varname#->\\"");'}, + """ if (capi_j>capi_i) + GETSTRFROMPYTUPLE(capi_return,capi_i++,#varname_i#,#varname_i#_cb_len);""", + {debugcapi: + ' fprintf(stderr,"#showvalueformat#\\":%d:.\\n",#varname_i#,#varname_i#_cb_len);'}, + ], + 'need': ['#ctype#', 'GETSTRFROMPYTUPLE', + {debugcapi: 'CFUNCSMESS'}, 'string.h'], + '_check': l_and(isstring, isintent_out) + }, { + 'pyobjfrom': [{debugcapi: ' fprintf(stderr,"debug-capi:cb:#varname#=\\"#showvalueformat#\\":%d:\\n",#varname_i#,#varname_i#_cb_len);'}, + {isintent_in: """\ + if (cb->nofargs>capi_i) + if (CAPI_ARGLIST_SETITEM(capi_i++,pyobj_from_#ctype#1size(#varname_i#,#varname_i#_cb_len))) + goto capi_fail;"""}, + {isintent_inout: """\ + if (cb->nofargs>capi_i) { + int #varname_i#_cb_dims[] = {#varname_i#_cb_len}; + if (CAPI_ARGLIST_SETITEM(capi_i++,pyarr_from_p_#ctype#1(#varname_i#,#varname_i#_cb_dims))) + goto capi_fail; + }"""}], + 'need': [{isintent_in: 'pyobj_from_#ctype#1size'}, + {isintent_inout: 'pyarr_from_p_#ctype#1'}], + '_check': l_and(isstring, isintent_nothide), + '_optional': '' + }, + # Array ... + { + 'decl': ' npy_intp #varname_i#_Dims[#rank#] = {#rank*[-1]#};', + 'setdims': ' #cbsetdims#;', + '_check': isarray, + '_depend': '' + }, + { + 'pyobjfrom': [{debugcapi: ' fprintf(stderr,"debug-capi:cb:#varname#\\n");'}, + {isintent_c: """\ + if (cb->nofargs>capi_i) { + int itemsize_ = #atype# == NPY_STRING ? 1 : 0; + /*XXX: Hmm, what will destroy this array??? */ + PyArrayObject *tmp_arr = (PyArrayObject *)PyArray_New(&PyArray_Type,#rank#,#varname_i#_Dims,#atype#,NULL,(char*)#varname_i#,itemsize_,NPY_ARRAY_CARRAY,NULL); +""", + l_not(isintent_c): """\ + if (cb->nofargs>capi_i) { + int itemsize_ = #atype# == NPY_STRING ? 1 : 0; + /*XXX: Hmm, what will destroy this array??? */ + PyArrayObject *tmp_arr = (PyArrayObject *)PyArray_New(&PyArray_Type,#rank#,#varname_i#_Dims,#atype#,NULL,(char*)#varname_i#,itemsize_,NPY_ARRAY_FARRAY,NULL); +""", + }, + """ + if (tmp_arr==NULL) + goto capi_fail; + if (CAPI_ARGLIST_SETITEM(capi_i++,(PyObject *)tmp_arr)) + goto capi_fail; +}"""], + '_check': l_and(isarray, isintent_nothide, l_or(isintent_in, isintent_inout)), + '_optional': '', + }, { + 'frompyobj': [{debugcapi: ' CFUNCSMESS("cb:Getting #varname#->");'}, + """ if (capi_j>capi_i) { + PyArrayObject *rv_cb_arr = NULL; + if ((capi_tmp = PyTuple_GetItem(capi_return,capi_i++))==NULL) goto capi_fail; + rv_cb_arr = array_from_pyobj(#atype#,#varname_i#_Dims,#rank#,F2PY_INTENT_IN""", + {isintent_c: '|F2PY_INTENT_C'}, + """,capi_tmp); + if (rv_cb_arr == NULL) { + fprintf(stderr,\"rv_cb_arr is NULL\\n\"); + goto capi_fail; + } + MEMCOPY(#varname_i#,PyArray_DATA(rv_cb_arr),PyArray_NBYTES(rv_cb_arr)); + if (capi_tmp != (PyObject *)rv_cb_arr) { + Py_DECREF(rv_cb_arr); + } + }""", + {debugcapi: ' fprintf(stderr,"<-.\\n");'}, + ], + 'need': ['MEMCOPY', {iscomplexarray: '#ctype#'}], + '_check': l_and(isarray, isintent_out) + }, { + 'docreturn': '#varname#,', + '_check': isintent_out + } +] + +################## Build call-back module ############# +cb_map = {} + + +def buildcallbacks(m): + cb_map[m['name']] = [] + for bi in m['body']: + if bi['block'] == 'interface': + for b in bi['body']: + if b: + buildcallback(b, m['name']) + else: + errmess('warning: empty body for %s\n' % (m['name'])) + + +def buildcallback(rout, um): + from . import capi_maps + + outmess('\tConstructing call-back function "cb_%s_in_%s"\n' % + (rout['name'], um)) + args, depargs = getargs(rout) + capi_maps.depargs = depargs + var = rout['vars'] + vrd = capi_maps.cb_routsign2map(rout, um) + rd = dictappend({}, vrd) + cb_map[um].append([rout['name'], rd['name']]) + for r in cb_rout_rules: + if ('_check' in r and r['_check'](rout)) or ('_check' not in r): + ar = applyrules(r, vrd, rout) + rd = dictappend(rd, ar) + savevrd = {} + for i, a in enumerate(args): + vrd = capi_maps.cb_sign2map(a, var[a], index=i) + savevrd[a] = vrd + for r in cb_arg_rules: + if '_depend' in r: + continue + if '_optional' in r and isoptional(var[a]): + continue + if ('_check' in r and r['_check'](var[a])) or ('_check' not in r): + ar = applyrules(r, vrd, var[a]) + rd = dictappend(rd, ar) + if '_break' in r: + break + for a in args: + vrd = savevrd[a] + for r in cb_arg_rules: + if '_depend' in r: + continue + if ('_optional' not in r) or ('_optional' in r and isrequired(var[a])): + continue + if ('_check' in r and r['_check'](var[a])) or ('_check' not in r): + ar = applyrules(r, vrd, var[a]) + rd = dictappend(rd, ar) + if '_break' in r: + break + for a in depargs: + vrd = savevrd[a] + for r in cb_arg_rules: + if '_depend' not in r: + continue + if '_optional' in r: + continue + if ('_check' in r and r['_check'](var[a])) or ('_check' not in r): + ar = applyrules(r, vrd, var[a]) + rd = dictappend(rd, ar) + if '_break' in r: + break + if 'args' in rd and 'optargs' in rd: + if isinstance(rd['optargs'], list): + rd['optargs'] = rd['optargs'] + [""" +#ifndef F2PY_CB_RETURNCOMPLEX +, +#endif +"""] + rd['optargs_nm'] = rd['optargs_nm'] + [""" +#ifndef F2PY_CB_RETURNCOMPLEX +, +#endif +"""] + rd['optargs_td'] = rd['optargs_td'] + [""" +#ifndef F2PY_CB_RETURNCOMPLEX +, +#endif +"""] + if isinstance(rd['docreturn'], list): + rd['docreturn'] = stripcomma( + replace('#docreturn#', {'docreturn': rd['docreturn']})) + optargs = stripcomma(replace('#docsignopt#', + {'docsignopt': rd['docsignopt']} + )) + if optargs == '': + rd['docsignature'] = stripcomma( + replace('#docsign#', {'docsign': rd['docsign']})) + else: + rd['docsignature'] = replace('#docsign#[#docsignopt#]', + {'docsign': rd['docsign'], + 'docsignopt': optargs, + }) + rd['latexdocsignature'] = rd['docsignature'].replace('_', '\\_') + rd['latexdocsignature'] = rd['latexdocsignature'].replace(',', ', ') + rd['docstrsigns'] = [] + rd['latexdocstrsigns'] = [] + for k in ['docstrreq', 'docstropt', 'docstrout', 'docstrcbs']: + if k in rd and isinstance(rd[k], list): + rd['docstrsigns'] = rd['docstrsigns'] + rd[k] + k = 'latex' + k + if k in rd and isinstance(rd[k], list): + rd['latexdocstrsigns'] = rd['latexdocstrsigns'] + rd[k][0:1] +\ + ['\\begin{description}'] + rd[k][1:] +\ + ['\\end{description}'] + if 'args' not in rd: + rd['args'] = '' + rd['args_td'] = '' + rd['args_nm'] = '' + if not (rd.get('args') or rd.get('optargs') or rd.get('strarglens')): + rd['noargs'] = 'void' + + ar = applyrules(cb_routine_rules, rd) + cfuncs.callbacks[rd['name']] = ar['body'] + if isinstance(ar['need'], str): + ar['need'] = [ar['need']] + + if 'need' in rd: + for t in cfuncs.typedefs.keys(): + if t in rd['need']: + ar['need'].append(t) + + cfuncs.typedefs_generated[rd['name'] + '_typedef'] = ar['cbtypedefs'] + ar['need'].append(rd['name'] + '_typedef') + cfuncs.needs[rd['name']] = ar['need'] + + capi_maps.lcb2_map[rd['name']] = {'maxnofargs': ar['maxnofargs'], + 'nofoptargs': ar['nofoptargs'], + 'docstr': ar['docstr'], + 'latexdocstr': ar['latexdocstr'], + 'argname': rd['argname'] + } + outmess('\t %s\n' % (ar['docstrshort'])) + return +################## Build call-back function ############# diff --git a/venv/Lib/site-packages/numpy/f2py/cfuncs.py b/venv/Lib/site-packages/numpy/f2py/cfuncs.py new file mode 100644 index 0000000..974062f --- /dev/null +++ b/venv/Lib/site-packages/numpy/f2py/cfuncs.py @@ -0,0 +1,1362 @@ +#!/usr/bin/env python3 +""" + +C declarations, CPP macros, and C functions for f2py2e. +Only required declarations/macros/functions will be used. + +Copyright 1999,2000 Pearu Peterson all rights reserved, +Pearu Peterson +Permission to use, modify, and distribute this software is given under the +terms of the NumPy License. + +NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. +$Date: 2005/05/06 11:42:34 $ +Pearu Peterson + +""" +import sys +import copy + +from . import __version__ + +f2py_version = __version__.version +errmess = sys.stderr.write + +##################### Definitions ################## + +outneeds = {'includes0': [], 'includes': [], 'typedefs': [], 'typedefs_generated': [], + 'userincludes': [], + 'cppmacros': [], 'cfuncs': [], 'callbacks': [], 'f90modhooks': [], + 'commonhooks': []} +needs = {} +includes0 = {'includes0': '/*need_includes0*/'} +includes = {'includes': '/*need_includes*/'} +userincludes = {'userincludes': '/*need_userincludes*/'} +typedefs = {'typedefs': '/*need_typedefs*/'} +typedefs_generated = {'typedefs_generated': '/*need_typedefs_generated*/'} +cppmacros = {'cppmacros': '/*need_cppmacros*/'} +cfuncs = {'cfuncs': '/*need_cfuncs*/'} +callbacks = {'callbacks': '/*need_callbacks*/'} +f90modhooks = {'f90modhooks': '/*need_f90modhooks*/', + 'initf90modhooksstatic': '/*initf90modhooksstatic*/', + 'initf90modhooksdynamic': '/*initf90modhooksdynamic*/', + } +commonhooks = {'commonhooks': '/*need_commonhooks*/', + 'initcommonhooks': '/*need_initcommonhooks*/', + } + +############ Includes ################### + +includes0['math.h'] = '#include ' +includes0['string.h'] = '#include ' +includes0['setjmp.h'] = '#include ' + +includes['Python.h'] = '#include "Python.h"' +needs['arrayobject.h'] = ['Python.h'] +includes['arrayobject.h'] = '''#define PY_ARRAY_UNIQUE_SYMBOL PyArray_API +#include "arrayobject.h"''' + +includes['arrayobject.h'] = '#include "fortranobject.h"' +includes['stdarg.h'] = '#include ' + +############# Type definitions ############### + +typedefs['unsigned_char'] = 'typedef unsigned char unsigned_char;' +typedefs['unsigned_short'] = 'typedef unsigned short unsigned_short;' +typedefs['unsigned_long'] = 'typedef unsigned long unsigned_long;' +typedefs['signed_char'] = 'typedef signed char signed_char;' +typedefs['long_long'] = """\ +#ifdef _WIN32 +typedef __int64 long_long; +#else +typedef long long long_long; +typedef unsigned long long unsigned_long_long; +#endif +""" +typedefs['unsigned_long_long'] = """\ +#ifdef _WIN32 +typedef __uint64 long_long; +#else +typedef unsigned long long unsigned_long_long; +#endif +""" +typedefs['long_double'] = """\ +#ifndef _LONG_DOUBLE +typedef long double long_double; +#endif +""" +typedefs[ + 'complex_long_double'] = 'typedef struct {long double r,i;} complex_long_double;' +typedefs['complex_float'] = 'typedef struct {float r,i;} complex_float;' +typedefs['complex_double'] = 'typedef struct {double r,i;} complex_double;' +typedefs['string'] = """typedef char * string;""" + + +############### CPP macros #################### +cppmacros['CFUNCSMESS'] = """\ +#ifdef DEBUGCFUNCS +#define CFUNCSMESS(mess) fprintf(stderr,\"debug-capi:\"mess); +#define CFUNCSMESSPY(mess,obj) CFUNCSMESS(mess) \\ + PyObject_Print((PyObject *)obj,stderr,Py_PRINT_RAW);\\ + fprintf(stderr,\"\\n\"); +#else +#define CFUNCSMESS(mess) +#define CFUNCSMESSPY(mess,obj) +#endif +""" +cppmacros['F_FUNC'] = """\ +#if defined(PREPEND_FORTRAN) +#if defined(NO_APPEND_FORTRAN) +#if defined(UPPERCASE_FORTRAN) +#define F_FUNC(f,F) _##F +#else +#define F_FUNC(f,F) _##f +#endif +#else +#if defined(UPPERCASE_FORTRAN) +#define F_FUNC(f,F) _##F##_ +#else +#define F_FUNC(f,F) _##f##_ +#endif +#endif +#else +#if defined(NO_APPEND_FORTRAN) +#if defined(UPPERCASE_FORTRAN) +#define F_FUNC(f,F) F +#else +#define F_FUNC(f,F) f +#endif +#else +#if defined(UPPERCASE_FORTRAN) +#define F_FUNC(f,F) F##_ +#else +#define F_FUNC(f,F) f##_ +#endif +#endif +#endif +#if defined(UNDERSCORE_G77) +#define F_FUNC_US(f,F) F_FUNC(f##_,F##_) +#else +#define F_FUNC_US(f,F) F_FUNC(f,F) +#endif +""" +cppmacros['F_WRAPPEDFUNC'] = """\ +#if defined(PREPEND_FORTRAN) +#if defined(NO_APPEND_FORTRAN) +#if defined(UPPERCASE_FORTRAN) +#define F_WRAPPEDFUNC(f,F) _F2PYWRAP##F +#else +#define F_WRAPPEDFUNC(f,F) _f2pywrap##f +#endif +#else +#if defined(UPPERCASE_FORTRAN) +#define F_WRAPPEDFUNC(f,F) _F2PYWRAP##F##_ +#else +#define F_WRAPPEDFUNC(f,F) _f2pywrap##f##_ +#endif +#endif +#else +#if defined(NO_APPEND_FORTRAN) +#if defined(UPPERCASE_FORTRAN) +#define F_WRAPPEDFUNC(f,F) F2PYWRAP##F +#else +#define F_WRAPPEDFUNC(f,F) f2pywrap##f +#endif +#else +#if defined(UPPERCASE_FORTRAN) +#define F_WRAPPEDFUNC(f,F) F2PYWRAP##F##_ +#else +#define F_WRAPPEDFUNC(f,F) f2pywrap##f##_ +#endif +#endif +#endif +#if defined(UNDERSCORE_G77) +#define F_WRAPPEDFUNC_US(f,F) F_WRAPPEDFUNC(f##_,F##_) +#else +#define F_WRAPPEDFUNC_US(f,F) F_WRAPPEDFUNC(f,F) +#endif +""" +cppmacros['F_MODFUNC'] = """\ +#if defined(F90MOD2CCONV1) /*E.g. Compaq Fortran */ +#if defined(NO_APPEND_FORTRAN) +#define F_MODFUNCNAME(m,f) $ ## m ## $ ## f +#else +#define F_MODFUNCNAME(m,f) $ ## m ## $ ## f ## _ +#endif +#endif + +#if defined(F90MOD2CCONV2) /*E.g. IBM XL Fortran, not tested though */ +#if defined(NO_APPEND_FORTRAN) +#define F_MODFUNCNAME(m,f) __ ## m ## _MOD_ ## f +#else +#define F_MODFUNCNAME(m,f) __ ## m ## _MOD_ ## f ## _ +#endif +#endif + +#if defined(F90MOD2CCONV3) /*E.g. MIPSPro Compilers */ +#if defined(NO_APPEND_FORTRAN) +#define F_MODFUNCNAME(m,f) f ## .in. ## m +#else +#define F_MODFUNCNAME(m,f) f ## .in. ## m ## _ +#endif +#endif +/* +#if defined(UPPERCASE_FORTRAN) +#define F_MODFUNC(m,M,f,F) F_MODFUNCNAME(M,F) +#else +#define F_MODFUNC(m,M,f,F) F_MODFUNCNAME(m,f) +#endif +*/ + +#define F_MODFUNC(m,f) (*(f2pymodstruct##m##.##f)) +""" +cppmacros['SWAPUNSAFE'] = """\ +#define SWAP(a,b) (size_t)(a) = ((size_t)(a) ^ (size_t)(b));\\ + (size_t)(b) = ((size_t)(a) ^ (size_t)(b));\\ + (size_t)(a) = ((size_t)(a) ^ (size_t)(b)) +""" +cppmacros['SWAP'] = """\ +#define SWAP(a,b,t) {\\ + t *c;\\ + c = a;\\ + a = b;\\ + b = c;} +""" +# cppmacros['ISCONTIGUOUS']='#define ISCONTIGUOUS(m) (PyArray_FLAGS(m) & +# NPY_ARRAY_C_CONTIGUOUS)' +cppmacros['PRINTPYOBJERR'] = """\ +#define PRINTPYOBJERR(obj)\\ + fprintf(stderr,\"#modulename#.error is related to \");\\ + PyObject_Print((PyObject *)obj,stderr,Py_PRINT_RAW);\\ + fprintf(stderr,\"\\n\"); +""" +cppmacros['MINMAX'] = """\ +#ifndef max +#define max(a,b) ((a > b) ? (a) : (b)) +#endif +#ifndef min +#define min(a,b) ((a < b) ? (a) : (b)) +#endif +#ifndef MAX +#define MAX(a,b) ((a > b) ? (a) : (b)) +#endif +#ifndef MIN +#define MIN(a,b) ((a < b) ? (a) : (b)) +#endif +""" +needs['len..'] = ['f2py_size'] +cppmacros['len..'] = """\ +#define rank(var) var ## _Rank +#define shape(var,dim) var ## _Dims[dim] +#define old_rank(var) (PyArray_NDIM((PyArrayObject *)(capi_ ## var ## _tmp))) +#define old_shape(var,dim) PyArray_DIM(((PyArrayObject *)(capi_ ## var ## _tmp)),dim) +#define fshape(var,dim) shape(var,rank(var)-dim-1) +#define len(var) shape(var,0) +#define flen(var) fshape(var,0) +#define old_size(var) PyArray_SIZE((PyArrayObject *)(capi_ ## var ## _tmp)) +/* #define index(i) capi_i ## i */ +#define slen(var) capi_ ## var ## _len +#define size(var, ...) f2py_size((PyArrayObject *)(capi_ ## var ## _tmp), ## __VA_ARGS__, -1) +""" +needs['f2py_size'] = ['stdarg.h'] +cfuncs['f2py_size'] = """\ +static int f2py_size(PyArrayObject* var, ...) +{ + npy_int sz = 0; + npy_int dim; + npy_int rank; + va_list argp; + va_start(argp, var); + dim = va_arg(argp, npy_int); + if (dim==-1) + { + sz = PyArray_SIZE(var); + } + else + { + rank = PyArray_NDIM(var); + if (dim>=1 && dim<=rank) + sz = PyArray_DIM(var, dim-1); + else + fprintf(stderr, \"f2py_size: 2nd argument value=%d fails to satisfy 1<=value<=%d. Result will be 0.\\n\", dim, rank); + } + va_end(argp); + return sz; +} +""" + +cppmacros[ + 'pyobj_from_char1'] = '#define pyobj_from_char1(v) (PyLong_FromLong(v))' +cppmacros[ + 'pyobj_from_short1'] = '#define pyobj_from_short1(v) (PyLong_FromLong(v))' +needs['pyobj_from_int1'] = ['signed_char'] +cppmacros['pyobj_from_int1'] = '#define pyobj_from_int1(v) (PyLong_FromLong(v))' +cppmacros[ + 'pyobj_from_long1'] = '#define pyobj_from_long1(v) (PyLong_FromLong(v))' +needs['pyobj_from_long_long1'] = ['long_long'] +cppmacros['pyobj_from_long_long1'] = """\ +#ifdef HAVE_LONG_LONG +#define pyobj_from_long_long1(v) (PyLong_FromLongLong(v)) +#else +#warning HAVE_LONG_LONG is not available. Redefining pyobj_from_long_long. +#define pyobj_from_long_long1(v) (PyLong_FromLong(v)) +#endif +""" +needs['pyobj_from_long_double1'] = ['long_double'] +cppmacros[ + 'pyobj_from_long_double1'] = '#define pyobj_from_long_double1(v) (PyFloat_FromDouble(v))' +cppmacros[ + 'pyobj_from_double1'] = '#define pyobj_from_double1(v) (PyFloat_FromDouble(v))' +cppmacros[ + 'pyobj_from_float1'] = '#define pyobj_from_float1(v) (PyFloat_FromDouble(v))' +needs['pyobj_from_complex_long_double1'] = ['complex_long_double'] +cppmacros[ + 'pyobj_from_complex_long_double1'] = '#define pyobj_from_complex_long_double1(v) (PyComplex_FromDoubles(v.r,v.i))' +needs['pyobj_from_complex_double1'] = ['complex_double'] +cppmacros[ + 'pyobj_from_complex_double1'] = '#define pyobj_from_complex_double1(v) (PyComplex_FromDoubles(v.r,v.i))' +needs['pyobj_from_complex_float1'] = ['complex_float'] +cppmacros[ + 'pyobj_from_complex_float1'] = '#define pyobj_from_complex_float1(v) (PyComplex_FromDoubles(v.r,v.i))' +needs['pyobj_from_string1'] = ['string'] +cppmacros[ + 'pyobj_from_string1'] = '#define pyobj_from_string1(v) (PyUnicode_FromString((char *)v))' +needs['pyobj_from_string1size'] = ['string'] +cppmacros[ + 'pyobj_from_string1size'] = '#define pyobj_from_string1size(v,len) (PyUnicode_FromStringAndSize((char *)v, len))' +needs['TRYPYARRAYTEMPLATE'] = ['PRINTPYOBJERR'] +cppmacros['TRYPYARRAYTEMPLATE'] = """\ +/* New SciPy */ +#define TRYPYARRAYTEMPLATECHAR case NPY_STRING: *(char *)(PyArray_DATA(arr))=*v; break; +#define TRYPYARRAYTEMPLATELONG case NPY_LONG: *(long *)(PyArray_DATA(arr))=*v; break; +#define TRYPYARRAYTEMPLATEOBJECT case NPY_OBJECT: PyArray_SETITEM(arr,PyArray_DATA(arr),pyobj_from_ ## ctype ## 1(*v)); break; + +#define TRYPYARRAYTEMPLATE(ctype,typecode) \\ + PyArrayObject *arr = NULL;\\ + if (!obj) return -2;\\ + if (!PyArray_Check(obj)) return -1;\\ + if (!(arr=(PyArrayObject *)obj)) {fprintf(stderr,\"TRYPYARRAYTEMPLATE:\");PRINTPYOBJERR(obj);return 0;}\\ + if (PyArray_DESCR(arr)->type==typecode) {*(ctype *)(PyArray_DATA(arr))=*v; return 1;}\\ + switch (PyArray_TYPE(arr)) {\\ + case NPY_DOUBLE: *(double *)(PyArray_DATA(arr))=*v; break;\\ + case NPY_INT: *(int *)(PyArray_DATA(arr))=*v; break;\\ + case NPY_LONG: *(long *)(PyArray_DATA(arr))=*v; break;\\ + case NPY_FLOAT: *(float *)(PyArray_DATA(arr))=*v; break;\\ + case NPY_CDOUBLE: *(double *)(PyArray_DATA(arr))=*v; break;\\ + case NPY_CFLOAT: *(float *)(PyArray_DATA(arr))=*v; break;\\ + case NPY_BOOL: *(npy_bool *)(PyArray_DATA(arr))=(*v!=0); break;\\ + case NPY_UBYTE: *(unsigned char *)(PyArray_DATA(arr))=*v; break;\\ + case NPY_BYTE: *(signed char *)(PyArray_DATA(arr))=*v; break;\\ + case NPY_SHORT: *(short *)(PyArray_DATA(arr))=*v; break;\\ + case NPY_USHORT: *(npy_ushort *)(PyArray_DATA(arr))=*v; break;\\ + case NPY_UINT: *(npy_uint *)(PyArray_DATA(arr))=*v; break;\\ + case NPY_ULONG: *(npy_ulong *)(PyArray_DATA(arr))=*v; break;\\ + case NPY_LONGLONG: *(npy_longlong *)(PyArray_DATA(arr))=*v; break;\\ + case NPY_ULONGLONG: *(npy_ulonglong *)(PyArray_DATA(arr))=*v; break;\\ + case NPY_LONGDOUBLE: *(npy_longdouble *)(PyArray_DATA(arr))=*v; break;\\ + case NPY_CLONGDOUBLE: *(npy_longdouble *)(PyArray_DATA(arr))=*v; break;\\ + case NPY_OBJECT: PyArray_SETITEM(arr, PyArray_DATA(arr), pyobj_from_ ## ctype ## 1(*v)); break;\\ + default: return -2;\\ + };\\ + return 1 +""" + +needs['TRYCOMPLEXPYARRAYTEMPLATE'] = ['PRINTPYOBJERR'] +cppmacros['TRYCOMPLEXPYARRAYTEMPLATE'] = """\ +#define TRYCOMPLEXPYARRAYTEMPLATEOBJECT case NPY_OBJECT: PyArray_SETITEM(arr, PyArray_DATA(arr), pyobj_from_complex_ ## ctype ## 1((*v))); break; +#define TRYCOMPLEXPYARRAYTEMPLATE(ctype,typecode)\\ + PyArrayObject *arr = NULL;\\ + if (!obj) return -2;\\ + if (!PyArray_Check(obj)) return -1;\\ + if (!(arr=(PyArrayObject *)obj)) {fprintf(stderr,\"TRYCOMPLEXPYARRAYTEMPLATE:\");PRINTPYOBJERR(obj);return 0;}\\ + if (PyArray_DESCR(arr)->type==typecode) {\\ + *(ctype *)(PyArray_DATA(arr))=(*v).r;\\ + *(ctype *)(PyArray_DATA(arr)+sizeof(ctype))=(*v).i;\\ + return 1;\\ + }\\ + switch (PyArray_TYPE(arr)) {\\ + case NPY_CDOUBLE: *(double *)(PyArray_DATA(arr))=(*v).r;*(double *)(PyArray_DATA(arr)+sizeof(double))=(*v).i;break;\\ + case NPY_CFLOAT: *(float *)(PyArray_DATA(arr))=(*v).r;*(float *)(PyArray_DATA(arr)+sizeof(float))=(*v).i;break;\\ + case NPY_DOUBLE: *(double *)(PyArray_DATA(arr))=(*v).r; break;\\ + case NPY_LONG: *(long *)(PyArray_DATA(arr))=(*v).r; break;\\ + case NPY_FLOAT: *(float *)(PyArray_DATA(arr))=(*v).r; break;\\ + case NPY_INT: *(int *)(PyArray_DATA(arr))=(*v).r; break;\\ + case NPY_SHORT: *(short *)(PyArray_DATA(arr))=(*v).r; break;\\ + case NPY_UBYTE: *(unsigned char *)(PyArray_DATA(arr))=(*v).r; break;\\ + case NPY_BYTE: *(signed char *)(PyArray_DATA(arr))=(*v).r; break;\\ + case NPY_BOOL: *(npy_bool *)(PyArray_DATA(arr))=((*v).r!=0 && (*v).i!=0); break;\\ + case NPY_USHORT: *(npy_ushort *)(PyArray_DATA(arr))=(*v).r; break;\\ + case NPY_UINT: *(npy_uint *)(PyArray_DATA(arr))=(*v).r; break;\\ + case NPY_ULONG: *(npy_ulong *)(PyArray_DATA(arr))=(*v).r; break;\\ + case NPY_LONGLONG: *(npy_longlong *)(PyArray_DATA(arr))=(*v).r; break;\\ + case NPY_ULONGLONG: *(npy_ulonglong *)(PyArray_DATA(arr))=(*v).r; break;\\ + case NPY_LONGDOUBLE: *(npy_longdouble *)(PyArray_DATA(arr))=(*v).r; break;\\ + case NPY_CLONGDOUBLE: *(npy_longdouble *)(PyArray_DATA(arr))=(*v).r;*(npy_longdouble *)(PyArray_DATA(arr)+sizeof(npy_longdouble))=(*v).i;break;\\ + case NPY_OBJECT: PyArray_SETITEM(arr, PyArray_DATA(arr), pyobj_from_complex_ ## ctype ## 1((*v))); break;\\ + default: return -2;\\ + };\\ + return -1; +""" +# cppmacros['NUMFROMARROBJ']="""\ +# define NUMFROMARROBJ(typenum,ctype) \\ +# if (PyArray_Check(obj)) arr = (PyArrayObject *)obj;\\ +# else arr = (PyArrayObject *)PyArray_ContiguousFromObject(obj,typenum,0,0);\\ +# if (arr) {\\ +# if (PyArray_TYPE(arr)==NPY_OBJECT) {\\ +# if (!ctype ## _from_pyobj(v,(PyArray_DESCR(arr)->getitem)(PyArray_DATA(arr)),\"\"))\\ +# goto capi_fail;\\ +# } else {\\ +# (PyArray_DESCR(arr)->cast[typenum])(PyArray_DATA(arr),1,(char*)v,1,1);\\ +# }\\ +# if ((PyObject *)arr != obj) { Py_DECREF(arr); }\\ +# return 1;\\ +# } +# """ +# XXX: Note that CNUMFROMARROBJ is identical with NUMFROMARROBJ +# cppmacros['CNUMFROMARROBJ']="""\ +# define CNUMFROMARROBJ(typenum,ctype) \\ +# if (PyArray_Check(obj)) arr = (PyArrayObject *)obj;\\ +# else arr = (PyArrayObject *)PyArray_ContiguousFromObject(obj,typenum,0,0);\\ +# if (arr) {\\ +# if (PyArray_TYPE(arr)==NPY_OBJECT) {\\ +# if (!ctype ## _from_pyobj(v,(PyArray_DESCR(arr)->getitem)(PyArray_DATA(arr)),\"\"))\\ +# goto capi_fail;\\ +# } else {\\ +# (PyArray_DESCR(arr)->cast[typenum])((void *)(PyArray_DATA(arr)),1,(void *)(v),1,1);\\ +# }\\ +# if ((PyObject *)arr != obj) { Py_DECREF(arr); }\\ +# return 1;\\ +# } +# """ + + +needs['GETSTRFROMPYTUPLE'] = ['STRINGCOPYN', 'PRINTPYOBJERR'] +cppmacros['GETSTRFROMPYTUPLE'] = """\ +#define GETSTRFROMPYTUPLE(tuple,index,str,len) {\\ + PyObject *rv_cb_str = PyTuple_GetItem((tuple),(index));\\ + if (rv_cb_str == NULL)\\ + goto capi_fail;\\ + if (PyBytes_Check(rv_cb_str)) {\\ + str[len-1]='\\0';\\ + STRINGCOPYN((str),PyBytes_AS_STRING((PyBytesObject*)rv_cb_str),(len));\\ + } else {\\ + PRINTPYOBJERR(rv_cb_str);\\ + PyErr_SetString(#modulename#_error,\"string object expected\");\\ + goto capi_fail;\\ + }\\ + } +""" +cppmacros['GETSCALARFROMPYTUPLE'] = """\ +#define GETSCALARFROMPYTUPLE(tuple,index,var,ctype,mess) {\\ + if ((capi_tmp = PyTuple_GetItem((tuple),(index)))==NULL) goto capi_fail;\\ + if (!(ctype ## _from_pyobj((var),capi_tmp,mess)))\\ + goto capi_fail;\\ + } +""" + +cppmacros['FAILNULL'] = """\\ +#define FAILNULL(p) do { \\ + if ((p) == NULL) { \\ + PyErr_SetString(PyExc_MemoryError, "NULL pointer found"); \\ + goto capi_fail; \\ + } \\ +} while (0) +""" +needs['MEMCOPY'] = ['string.h', 'FAILNULL'] +cppmacros['MEMCOPY'] = """\ +#define MEMCOPY(to,from,n)\\ + do { FAILNULL(to); FAILNULL(from); (void)memcpy(to,from,n); } while (0) +""" +cppmacros['STRINGMALLOC'] = """\ +#define STRINGMALLOC(str,len)\\ + if ((str = (string)malloc(sizeof(char)*(len+1))) == NULL) {\\ + PyErr_SetString(PyExc_MemoryError, \"out of memory\");\\ + goto capi_fail;\\ + } else {\\ + (str)[len] = '\\0';\\ + } +""" +cppmacros['STRINGFREE'] = """\ +#define STRINGFREE(str) do {if (!(str == NULL)) free(str);} while (0) +""" +needs['STRINGCOPYN'] = ['string.h', 'FAILNULL'] +cppmacros['STRINGCOPYN'] = """\ +#define STRINGCOPYN(to,from,buf_size) \\ + do { \\ + int _m = (buf_size); \\ + char *_to = (to); \\ + char *_from = (from); \\ + FAILNULL(_to); FAILNULL(_from); \\ + (void)strncpy(_to, _from, sizeof(char)*_m); \\ + _to[_m-1] = '\\0'; \\ + /* Padding with spaces instead of nulls */ \\ + for (_m -= 2; _m >= 0 && _to[_m] == '\\0'; _m--) { \\ + _to[_m] = ' '; \\ + } \\ + } while (0) +""" +needs['STRINGCOPY'] = ['string.h', 'FAILNULL'] +cppmacros['STRINGCOPY'] = """\ +#define STRINGCOPY(to,from)\\ + do { FAILNULL(to); FAILNULL(from); (void)strcpy(to,from); } while (0) +""" +cppmacros['CHECKGENERIC'] = """\ +#define CHECKGENERIC(check,tcheck,name) \\ + if (!(check)) {\\ + PyErr_SetString(#modulename#_error,\"(\"tcheck\") failed for \"name);\\ + /*goto capi_fail;*/\\ + } else """ +cppmacros['CHECKARRAY'] = """\ +#define CHECKARRAY(check,tcheck,name) \\ + if (!(check)) {\\ + PyErr_SetString(#modulename#_error,\"(\"tcheck\") failed for \"name);\\ + /*goto capi_fail;*/\\ + } else """ +cppmacros['CHECKSTRING'] = """\ +#define CHECKSTRING(check,tcheck,name,show,var)\\ + if (!(check)) {\\ + char errstring[256];\\ + sprintf(errstring, \"%s: \"show, \"(\"tcheck\") failed for \"name, slen(var), var);\\ + PyErr_SetString(#modulename#_error, errstring);\\ + /*goto capi_fail;*/\\ + } else """ +cppmacros['CHECKSCALAR'] = """\ +#define CHECKSCALAR(check,tcheck,name,show,var)\\ + if (!(check)) {\\ + char errstring[256];\\ + sprintf(errstring, \"%s: \"show, \"(\"tcheck\") failed for \"name, var);\\ + PyErr_SetString(#modulename#_error,errstring);\\ + /*goto capi_fail;*/\\ + } else """ +# cppmacros['CHECKDIMS']="""\ +# define CHECKDIMS(dims,rank) \\ +# for (int i=0;i<(rank);i++)\\ +# if (dims[i]<0) {\\ +# fprintf(stderr,\"Unspecified array argument requires a complete dimension specification.\\n\");\\ +# goto capi_fail;\\ +# } +# """ +cppmacros[ + 'ARRSIZE'] = '#define ARRSIZE(dims,rank) (_PyArray_multiply_list(dims,rank))' +cppmacros['OLDPYNUM'] = """\ +#ifdef OLDPYNUM +#error You need to install NumPy version 0.13 or higher. See https://scipy.org/install.html +#endif +""" +cppmacros["F2PY_THREAD_LOCAL_DECL"] = """\ +#ifndef F2PY_THREAD_LOCAL_DECL +#if defined(_MSC_VER) +#define F2PY_THREAD_LOCAL_DECL __declspec(thread) +#elif defined(__STDC_VERSION__) \\ + && (__STDC_VERSION__ >= 201112L) \\ + && !defined(__STDC_NO_THREADS__) \\ + && (!defined(__GLIBC__) || __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 12)) +/* __STDC_NO_THREADS__ was first defined in a maintenance release of glibc 2.12, + see https://lists.gnu.org/archive/html/commit-hurd/2012-07/msg00180.html, + so `!defined(__STDC_NO_THREADS__)` may give false positive for the existence + of `threads.h` when using an older release of glibc 2.12 */ +#include +#define F2PY_THREAD_LOCAL_DECL thread_local +#elif defined(__GNUC__) \\ + && (__GNUC__ > 4 || (__GNUC__ == 4 && (__GNUC_MINOR__ >= 4))) +#define F2PY_THREAD_LOCAL_DECL __thread +#endif +#endif +""" +################# C functions ############### + +cfuncs['calcarrindex'] = """\ +static int calcarrindex(int *i,PyArrayObject *arr) { + int k,ii = i[0]; + for (k=1; k < PyArray_NDIM(arr); k++) + ii += (ii*(PyArray_DIM(arr,k) - 1)+i[k]); /* assuming contiguous arr */ + return ii; +}""" +cfuncs['calcarrindextr'] = """\ +static int calcarrindextr(int *i,PyArrayObject *arr) { + int k,ii = i[PyArray_NDIM(arr)-1]; + for (k=1; k < PyArray_NDIM(arr); k++) + ii += (ii*(PyArray_DIM(arr,PyArray_NDIM(arr)-k-1) - 1)+i[PyArray_NDIM(arr)-k-1]); /* assuming contiguous arr */ + return ii; +}""" +cfuncs['forcomb'] = """\ +static struct { int nd;npy_intp *d;int *i,*i_tr,tr; } forcombcache; +static int initforcomb(npy_intp *dims,int nd,int tr) { + int k; + if (dims==NULL) return 0; + if (nd<0) return 0; + forcombcache.nd = nd; + forcombcache.d = dims; + forcombcache.tr = tr; + if ((forcombcache.i = (int *)malloc(sizeof(int)*nd))==NULL) return 0; + if ((forcombcache.i_tr = (int *)malloc(sizeof(int)*nd))==NULL) return 0; + for (k=1;kreal; + (*v).i = ((npy_clongdouble *)PyArray_DATA(obj))->imag; + return 1; + } + } + if (complex_double_from_pyobj(&cd,obj,errmess)) { + (*v).r = (long_double)cd.r; + (*v).i = (long_double)cd.i; + return 1; + } + return 0; +} +""" + + +needs['complex_double_from_pyobj'] = ['complex_double'] +cfuncs['complex_double_from_pyobj'] = """\ +static int +complex_double_from_pyobj(complex_double* v, PyObject *obj, const char *errmess) { + Py_complex c; + if (PyComplex_Check(obj)) { + c = PyComplex_AsCComplex(obj); + (*v).r = c.real; + (*v).i = c.imag; + return 1; + } + if (PyArray_IsScalar(obj, ComplexFloating)) { + if (PyArray_IsScalar(obj, CFloat)) { + npy_cfloat new; + PyArray_ScalarAsCtype(obj, &new); + (*v).r = (double)new.real; + (*v).i = (double)new.imag; + } + else if (PyArray_IsScalar(obj, CLongDouble)) { + npy_clongdouble new; + PyArray_ScalarAsCtype(obj, &new); + (*v).r = (double)new.real; + (*v).i = (double)new.imag; + } + else { /* if (PyArray_IsScalar(obj, CDouble)) */ + PyArray_ScalarAsCtype(obj, v); + } + return 1; + } + if (PyArray_CheckScalar(obj)) { /* 0-dim array or still array scalar */ + PyObject *arr; + if (PyArray_Check(obj)) { + arr = PyArray_Cast((PyArrayObject *)obj, NPY_CDOUBLE); + } + else { + arr = PyArray_FromScalar(obj, PyArray_DescrFromType(NPY_CDOUBLE)); + } + if (arr == NULL) { + return 0; + } + (*v).r = ((npy_cdouble *)PyArray_DATA(arr))->real; + (*v).i = ((npy_cdouble *)PyArray_DATA(arr))->imag; + Py_DECREF(arr); + return 1; + } + /* Python does not provide PyNumber_Complex function :-( */ + (*v).i = 0.0; + if (PyFloat_Check(obj)) { + (*v).r = PyFloat_AsDouble(obj); + return !((*v).r == -1.0 && PyErr_Occurred()); + } + if (PyLong_Check(obj)) { + (*v).r = PyLong_AsDouble(obj); + return !((*v).r == -1.0 && PyErr_Occurred()); + } + if (PySequence_Check(obj) && !(PyBytes_Check(obj) || PyUnicode_Check(obj))) { + PyObject *tmp = PySequence_GetItem(obj,0); + if (tmp) { + if (complex_double_from_pyobj(v,tmp,errmess)) { + Py_DECREF(tmp); + return 1; + } + Py_DECREF(tmp); + } + } + { + PyObject* err = PyErr_Occurred(); + if (err==NULL) + err = PyExc_TypeError; + PyErr_SetString(err,errmess); + } + return 0; +} +""" + + +needs['complex_float_from_pyobj'] = [ + 'complex_float', 'complex_double_from_pyobj'] +cfuncs['complex_float_from_pyobj'] = """\ +static int +complex_float_from_pyobj(complex_float* v,PyObject *obj,const char *errmess) +{ + complex_double cd={0.0,0.0}; + if (complex_double_from_pyobj(&cd,obj,errmess)) { + (*v).r = (float)cd.r; + (*v).i = (float)cd.i; + return 1; + } + return 0; +} +""" + + +needs['try_pyarr_from_char'] = ['pyobj_from_char1', 'TRYPYARRAYTEMPLATE'] +cfuncs[ + 'try_pyarr_from_char'] = 'static int try_pyarr_from_char(PyObject* obj,char* v) {\n TRYPYARRAYTEMPLATE(char,\'c\');\n}\n' +needs['try_pyarr_from_signed_char'] = ['TRYPYARRAYTEMPLATE', 'unsigned_char'] +cfuncs[ + 'try_pyarr_from_unsigned_char'] = 'static int try_pyarr_from_unsigned_char(PyObject* obj,unsigned_char* v) {\n TRYPYARRAYTEMPLATE(unsigned_char,\'b\');\n}\n' +needs['try_pyarr_from_signed_char'] = ['TRYPYARRAYTEMPLATE', 'signed_char'] +cfuncs[ + 'try_pyarr_from_signed_char'] = 'static int try_pyarr_from_signed_char(PyObject* obj,signed_char* v) {\n TRYPYARRAYTEMPLATE(signed_char,\'1\');\n}\n' +needs['try_pyarr_from_short'] = ['pyobj_from_short1', 'TRYPYARRAYTEMPLATE'] +cfuncs[ + 'try_pyarr_from_short'] = 'static int try_pyarr_from_short(PyObject* obj,short* v) {\n TRYPYARRAYTEMPLATE(short,\'s\');\n}\n' +needs['try_pyarr_from_int'] = ['pyobj_from_int1', 'TRYPYARRAYTEMPLATE'] +cfuncs[ + 'try_pyarr_from_int'] = 'static int try_pyarr_from_int(PyObject* obj,int* v) {\n TRYPYARRAYTEMPLATE(int,\'i\');\n}\n' +needs['try_pyarr_from_long'] = ['pyobj_from_long1', 'TRYPYARRAYTEMPLATE'] +cfuncs[ + 'try_pyarr_from_long'] = 'static int try_pyarr_from_long(PyObject* obj,long* v) {\n TRYPYARRAYTEMPLATE(long,\'l\');\n}\n' +needs['try_pyarr_from_long_long'] = [ + 'pyobj_from_long_long1', 'TRYPYARRAYTEMPLATE', 'long_long'] +cfuncs[ + 'try_pyarr_from_long_long'] = 'static int try_pyarr_from_long_long(PyObject* obj,long_long* v) {\n TRYPYARRAYTEMPLATE(long_long,\'L\');\n}\n' +needs['try_pyarr_from_float'] = ['pyobj_from_float1', 'TRYPYARRAYTEMPLATE'] +cfuncs[ + 'try_pyarr_from_float'] = 'static int try_pyarr_from_float(PyObject* obj,float* v) {\n TRYPYARRAYTEMPLATE(float,\'f\');\n}\n' +needs['try_pyarr_from_double'] = ['pyobj_from_double1', 'TRYPYARRAYTEMPLATE'] +cfuncs[ + 'try_pyarr_from_double'] = 'static int try_pyarr_from_double(PyObject* obj,double* v) {\n TRYPYARRAYTEMPLATE(double,\'d\');\n}\n' +needs['try_pyarr_from_complex_float'] = [ + 'pyobj_from_complex_float1', 'TRYCOMPLEXPYARRAYTEMPLATE', 'complex_float'] +cfuncs[ + 'try_pyarr_from_complex_float'] = 'static int try_pyarr_from_complex_float(PyObject* obj,complex_float* v) {\n TRYCOMPLEXPYARRAYTEMPLATE(float,\'F\');\n}\n' +needs['try_pyarr_from_complex_double'] = [ + 'pyobj_from_complex_double1', 'TRYCOMPLEXPYARRAYTEMPLATE', 'complex_double'] +cfuncs[ + 'try_pyarr_from_complex_double'] = 'static int try_pyarr_from_complex_double(PyObject* obj,complex_double* v) {\n TRYCOMPLEXPYARRAYTEMPLATE(double,\'D\');\n}\n' + + +needs['create_cb_arglist'] = ['CFUNCSMESS', 'PRINTPYOBJERR', 'MINMAX'] +# create the list of arguments to be used when calling back to python +cfuncs['create_cb_arglist'] = """\ +static int +create_cb_arglist(PyObject* fun, PyTupleObject* xa , const int maxnofargs, + const int nofoptargs, int *nofargs, PyTupleObject **args, + const char *errmess) +{ + PyObject *tmp = NULL; + PyObject *tmp_fun = NULL; + Py_ssize_t tot, opt, ext, siz, i, di = 0; + CFUNCSMESS(\"create_cb_arglist\\n\"); + tot=opt=ext=siz=0; + /* Get the total number of arguments */ + if (PyFunction_Check(fun)) { + tmp_fun = fun; + Py_INCREF(tmp_fun); + } + else { + di = 1; + if (PyObject_HasAttrString(fun,\"im_func\")) { + tmp_fun = PyObject_GetAttrString(fun,\"im_func\"); + } + else if (PyObject_HasAttrString(fun,\"__call__\")) { + tmp = PyObject_GetAttrString(fun,\"__call__\"); + if (PyObject_HasAttrString(tmp,\"im_func\")) + tmp_fun = PyObject_GetAttrString(tmp,\"im_func\"); + else { + tmp_fun = fun; /* built-in function */ + Py_INCREF(tmp_fun); + tot = maxnofargs; + if (PyCFunction_Check(fun)) { + /* In case the function has a co_argcount (like on PyPy) */ + di = 0; + } + if (xa != NULL) + tot += PyTuple_Size((PyObject *)xa); + } + Py_XDECREF(tmp); + } + else if (PyFortran_Check(fun) || PyFortran_Check1(fun)) { + tot = maxnofargs; + if (xa != NULL) + tot += PyTuple_Size((PyObject *)xa); + tmp_fun = fun; + Py_INCREF(tmp_fun); + } + else if (F2PyCapsule_Check(fun)) { + tot = maxnofargs; + if (xa != NULL) + ext = PyTuple_Size((PyObject *)xa); + if(ext>0) { + fprintf(stderr,\"extra arguments tuple cannot be used with CObject call-back\\n\"); + goto capi_fail; + } + tmp_fun = fun; + Py_INCREF(tmp_fun); + } + } + + if (tmp_fun == NULL) { + fprintf(stderr, + \"Call-back argument must be function|instance|instance.__call__|f2py-function \" + \"but got %s.\\n\", + ((fun == NULL) ? \"NULL\" : Py_TYPE(fun)->tp_name)); + goto capi_fail; + } + + if (PyObject_HasAttrString(tmp_fun,\"__code__\")) { + if (PyObject_HasAttrString(tmp = PyObject_GetAttrString(tmp_fun,\"__code__\"),\"co_argcount\")) { + PyObject *tmp_argcount = PyObject_GetAttrString(tmp,\"co_argcount\"); + Py_DECREF(tmp); + if (tmp_argcount == NULL) { + goto capi_fail; + } + tot = PyLong_AsSsize_t(tmp_argcount) - di; + Py_DECREF(tmp_argcount); + } + } + /* Get the number of optional arguments */ + if (PyObject_HasAttrString(tmp_fun,\"__defaults__\")) { + if (PyTuple_Check(tmp = PyObject_GetAttrString(tmp_fun,\"__defaults__\"))) + opt = PyTuple_Size(tmp); + Py_XDECREF(tmp); + } + /* Get the number of extra arguments */ + if (xa != NULL) + ext = PyTuple_Size((PyObject *)xa); + /* Calculate the size of call-backs argument list */ + siz = MIN(maxnofargs+ext,tot); + *nofargs = MAX(0,siz-ext); + +#ifdef DEBUGCFUNCS + fprintf(stderr, + \"debug-capi:create_cb_arglist:maxnofargs(-nofoptargs),\" + \"tot,opt,ext,siz,nofargs = %d(-%d), %zd, %zd, %zd, %zd, %d\\n\", + maxnofargs, nofoptargs, tot, opt, ext, siz, *nofargs); +#endif + + if (siz < tot-opt) { + fprintf(stderr, + \"create_cb_arglist: Failed to build argument list \" + \"(siz) with enough arguments (tot-opt) required by \" + \"user-supplied function (siz,tot,opt=%zd, %zd, %zd).\\n\", + siz, tot, opt); + goto capi_fail; + } + + /* Initialize argument list */ + *args = (PyTupleObject *)PyTuple_New(siz); + for (i=0;i<*nofargs;i++) { + Py_INCREF(Py_None); + PyTuple_SET_ITEM((PyObject *)(*args),i,Py_None); + } + if (xa != NULL) + for (i=(*nofargs);i 0: + if outneeds[n][0] not in needs: + out.append(outneeds[n][0]) + del outneeds[n][0] + else: + flag = 0 + for k in outneeds[n][1:]: + if k in needs[outneeds[n][0]]: + flag = 1 + break + if flag: + outneeds[n] = outneeds[n][1:] + [outneeds[n][0]] + else: + out.append(outneeds[n][0]) + del outneeds[n][0] + if saveout and (0 not in map(lambda x, y: x == y, saveout, outneeds[n])) \ + and outneeds[n] != []: + print(n, saveout) + errmess( + 'get_needs: no progress in sorting needs, probably circular dependence, skipping.\n') + out = out + saveout + break + saveout = copy.copy(outneeds[n]) + if out == []: + out = [n] + res[n] = out + return res diff --git a/venv/Lib/site-packages/numpy/f2py/common_rules.py b/venv/Lib/site-packages/numpy/f2py/common_rules.py new file mode 100644 index 0000000..937d8bc --- /dev/null +++ b/venv/Lib/site-packages/numpy/f2py/common_rules.py @@ -0,0 +1,145 @@ +#!/usr/bin/env python3 +""" + +Build common block mechanism for f2py2e. + +Copyright 2000 Pearu Peterson all rights reserved, +Pearu Peterson +Permission to use, modify, and distribute this software is given under the +terms of the NumPy License + +NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. +$Date: 2005/05/06 10:57:33 $ +Pearu Peterson + +""" +from . import __version__ +f2py_version = __version__.version + +from .auxfuncs import ( + hasbody, hascommon, hasnote, isintent_hide, outmess +) +from . import capi_maps +from . import func2subr +from .crackfortran import rmbadname + + +def findcommonblocks(block, top=1): + ret = [] + if hascommon(block): + for key, value in block['common'].items(): + vars_ = {v: block['vars'][v] for v in value} + ret.append((key, value, vars_)) + elif hasbody(block): + for b in block['body']: + ret = ret + findcommonblocks(b, 0) + if top: + tret = [] + names = [] + for t in ret: + if t[0] not in names: + names.append(t[0]) + tret.append(t) + return tret + return ret + + +def buildhooks(m): + ret = {'commonhooks': [], 'initcommonhooks': [], + 'docs': ['"COMMON blocks:\\n"']} + fwrap = [''] + + def fadd(line, s=fwrap): + s[0] = '%s\n %s' % (s[0], line) + chooks = [''] + + def cadd(line, s=chooks): + s[0] = '%s\n%s' % (s[0], line) + ihooks = [''] + + def iadd(line, s=ihooks): + s[0] = '%s\n%s' % (s[0], line) + doc = [''] + + def dadd(line, s=doc): + s[0] = '%s\n%s' % (s[0], line) + for (name, vnames, vars) in findcommonblocks(m): + lower_name = name.lower() + hnames, inames = [], [] + for n in vnames: + if isintent_hide(vars[n]): + hnames.append(n) + else: + inames.append(n) + if hnames: + outmess('\t\tConstructing COMMON block support for "%s"...\n\t\t %s\n\t\t Hidden: %s\n' % ( + name, ','.join(inames), ','.join(hnames))) + else: + outmess('\t\tConstructing COMMON block support for "%s"...\n\t\t %s\n' % ( + name, ','.join(inames))) + fadd('subroutine f2pyinit%s(setupfunc)' % name) + fadd('external setupfunc') + for n in vnames: + fadd(func2subr.var2fixfortran(vars, n)) + if name == '_BLNK_': + fadd('common %s' % (','.join(vnames))) + else: + fadd('common /%s/ %s' % (name, ','.join(vnames))) + fadd('call setupfunc(%s)' % (','.join(inames))) + fadd('end\n') + cadd('static FortranDataDef f2py_%s_def[] = {' % (name)) + idims = [] + for n in inames: + ct = capi_maps.getctype(vars[n]) + at = capi_maps.c2capi_map[ct] + dm = capi_maps.getarrdims(n, vars[n]) + if dm['dims']: + idims.append('(%s)' % (dm['dims'])) + else: + idims.append('') + dms = dm['dims'].strip() + if not dms: + dms = '-1' + cadd('\t{\"%s\",%s,{{%s}},%s},' % (n, dm['rank'], dms, at)) + cadd('\t{NULL}\n};') + inames1 = rmbadname(inames) + inames1_tps = ','.join(['char *' + s for s in inames1]) + cadd('static void f2py_setup_%s(%s) {' % (name, inames1_tps)) + cadd('\tint i_f2py=0;') + for n in inames1: + cadd('\tf2py_%s_def[i_f2py++].data = %s;' % (name, n)) + cadd('}') + if '_' in lower_name: + F_FUNC = 'F_FUNC_US' + else: + F_FUNC = 'F_FUNC' + cadd('extern void %s(f2pyinit%s,F2PYINIT%s)(void(*)(%s));' + % (F_FUNC, lower_name, name.upper(), + ','.join(['char*'] * len(inames1)))) + cadd('static void f2py_init_%s(void) {' % name) + cadd('\t%s(f2pyinit%s,F2PYINIT%s)(f2py_setup_%s);' + % (F_FUNC, lower_name, name.upper(), name)) + cadd('}\n') + iadd('\ttmp = PyFortranObject_New(f2py_%s_def,f2py_init_%s);' % (name, name)) + iadd('\tF2PyDict_SetItemString(d, \"%s\", tmp);' % name) + iadd('\tPy_DECREF(tmp);') + tname = name.replace('_', '\\_') + dadd('\\subsection{Common block \\texttt{%s}}\n' % (tname)) + dadd('\\begin{description}') + for n in inames: + dadd('\\item[]{{}\\verb@%s@{}}' % + (capi_maps.getarrdocsign(n, vars[n]))) + if hasnote(vars[n]): + note = vars[n]['note'] + if isinstance(note, list): + note = '\n'.join(note) + dadd('--- %s' % (note)) + dadd('\\end{description}') + ret['docs'].append( + '"\t/%s/ %s\\n"' % (name, ','.join(map(lambda v, d: v + d, inames, idims)))) + ret['commonhooks'] = chooks + ret['initcommonhooks'] = ihooks + ret['latexdoc'] = doc[0] + if len(ret['docs']) <= 1: + ret['docs'] = '' + return ret, fwrap[0] diff --git a/venv/Lib/site-packages/numpy/f2py/crackfortran.py b/venv/Lib/site-packages/numpy/f2py/crackfortran.py new file mode 100644 index 0000000..1149633 --- /dev/null +++ b/venv/Lib/site-packages/numpy/f2py/crackfortran.py @@ -0,0 +1,3408 @@ +#!/usr/bin/env python3 +""" +crackfortran --- read fortran (77,90) code and extract declaration information. + +Copyright 1999-2004 Pearu Peterson all rights reserved, +Pearu Peterson +Permission to use, modify, and distribute this software is given under the +terms of the NumPy License. + +NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. +$Date: 2005/09/27 07:13:49 $ +Pearu Peterson + + +Usage of crackfortran: +====================== +Command line keys: -quiet,-verbose,-fix,-f77,-f90,-show,-h + -m ,--ignore-contains +Functions: crackfortran, crack2fortran +The following Fortran statements/constructions are supported +(or will be if needed): + block data,byte,call,character,common,complex,contains,data, + dimension,double complex,double precision,end,external,function, + implicit,integer,intent,interface,intrinsic, + logical,module,optional,parameter,private,public, + program,real,(sequence?),subroutine,type,use,virtual, + include,pythonmodule +Note: 'virtual' is mapped to 'dimension'. +Note: 'implicit integer (z) static (z)' is 'implicit static (z)' (this is minor bug). +Note: code after 'contains' will be ignored until its scope ends. +Note: 'common' statement is extended: dimensions are moved to variable definitions +Note: f2py directive: f2py is read as +Note: pythonmodule is introduced to represent Python module + +Usage: + `postlist=crackfortran(files)` + `postlist` contains declaration information read from the list of files `files`. + `crack2fortran(postlist)` returns a fortran code to be saved to pyf-file + + `postlist` has the following structure: + *** it is a list of dictionaries containing `blocks': + B = {'block','body','vars','parent_block'[,'name','prefix','args','result', + 'implicit','externals','interfaced','common','sortvars', + 'commonvars','note']} + B['block'] = 'interface' | 'function' | 'subroutine' | 'module' | + 'program' | 'block data' | 'type' | 'pythonmodule' + B['body'] --- list containing `subblocks' with the same structure as `blocks' + B['parent_block'] --- dictionary of a parent block: + C['body'][]['parent_block'] is C + B['vars'] --- dictionary of variable definitions + B['sortvars'] --- dictionary of variable definitions sorted by dependence (independent first) + B['name'] --- name of the block (not if B['block']=='interface') + B['prefix'] --- prefix string (only if B['block']=='function') + B['args'] --- list of argument names if B['block']== 'function' | 'subroutine' + B['result'] --- name of the return value (only if B['block']=='function') + B['implicit'] --- dictionary {'a':,'b':...} | None + B['externals'] --- list of variables being external + B['interfaced'] --- list of variables being external and defined + B['common'] --- dictionary of common blocks (list of objects) + B['commonvars'] --- list of variables used in common blocks (dimensions are moved to variable definitions) + B['from'] --- string showing the 'parents' of the current block + B['use'] --- dictionary of modules used in current block: + {:{['only':<0|1>],['map':{:,...}]}} + B['note'] --- list of LaTeX comments on the block + B['f2pyenhancements'] --- optional dictionary + {'threadsafe':'','fortranname':, + 'callstatement':|, + 'callprotoargument':, + 'usercode':|, + 'pymethoddef:' + } + B['entry'] --- dictionary {entryname:argslist,..} + B['varnames'] --- list of variable names given in the order of reading the + Fortran code, useful for derived types. + B['saved_interface'] --- a string of scanned routine signature, defines explicit interface + *** Variable definition is a dictionary + D = B['vars'][] = + {'typespec'[,'attrspec','kindselector','charselector','=','typename']} + D['typespec'] = 'byte' | 'character' | 'complex' | 'double complex' | + 'double precision' | 'integer' | 'logical' | 'real' | 'type' + D['attrspec'] --- list of attributes (e.g. 'dimension()', + 'external','intent(in|out|inout|hide|c|callback|cache|aligned4|aligned8|aligned16)', + 'optional','required', etc) + K = D['kindselector'] = {['*','kind']} (only if D['typespec'] = + 'complex' | 'integer' | 'logical' | 'real' ) + C = D['charselector'] = {['*','len','kind']} + (only if D['typespec']=='character') + D['='] --- initialization expression string + D['typename'] --- name of the type if D['typespec']=='type' + D['dimension'] --- list of dimension bounds + D['intent'] --- list of intent specifications + D['depend'] --- list of variable names on which current variable depends on + D['check'] --- list of C-expressions; if C-expr returns zero, exception is raised + D['note'] --- list of LaTeX comments on the variable + *** Meaning of kind/char selectors (few examples): + D['typespec>']*K['*'] + D['typespec'](kind=K['kind']) + character*C['*'] + character(len=C['len'],kind=C['kind']) + (see also fortran type declaration statement formats below) + +Fortran 90 type declaration statement format (F77 is subset of F90) +==================================================================== +(Main source: IBM XL Fortran 5.1 Language Reference Manual) +type declaration = [[]::] + = byte | + character[] | + complex[] | + double complex | + double precision | + integer[] | + logical[] | + real[] | + type() + = * | + ([len=][,[kind=]]) | + (kind=[,len=]) + = * | + ([kind=]) + = comma separated list of attributes. + Only the following attributes are used in + building up the interface: + external + (parameter --- affects '=' key) + optional + intent + Other attributes are ignored. + = in | out | inout + = comma separated list of dimension bounds. + = [[*][()] | [()]*] + [// | =] [,] + +In addition, the following attributes are used: check,depend,note + +TODO: + * Apply 'parameter' attribute (e.g. 'integer parameter :: i=2' 'real x(i)' + -> 'real x(2)') + The above may be solved by creating appropriate preprocessor program, for example. + +""" +import sys +import string +import fileinput +import re +import os +import copy +import platform + +from . import __version__ + +# The environment provided by auxfuncs.py is needed for some calls to eval. +# As the needed functions cannot be determined by static inspection of the +# code, it is safest to use import * pending a major refactoring of f2py. +from .auxfuncs import * + + +f2py_version = __version__.version + +# Global flags: +strictf77 = 1 # Ignore `!' comments unless line[0]=='!' +sourcecodeform = 'fix' # 'fix','free' +quiet = 0 # Be verbose if 0 (Obsolete: not used any more) +verbose = 1 # Be quiet if 0, extra verbose if > 1. +tabchar = 4 * ' ' +pyffilename = '' +f77modulename = '' +skipemptyends = 0 # for old F77 programs without 'program' statement +ignorecontains = 1 +dolowercase = 1 +debug = [] + +# Global variables +beginpattern = '' +currentfilename = '' +expectbegin = 1 +f90modulevars = {} +filepositiontext = '' +gotnextfile = 1 +groupcache = None +groupcounter = 0 +grouplist = {groupcounter: []} +groupname = '' +include_paths = [] +neededmodule = -1 +onlyfuncs = [] +previous_context = None +skipblocksuntil = -1 +skipfuncs = [] +skipfunctions = [] +usermodules = [] + + +def reset_global_f2py_vars(): + global groupcounter, grouplist, neededmodule, expectbegin + global skipblocksuntil, usermodules, f90modulevars, gotnextfile + global filepositiontext, currentfilename, skipfunctions, skipfuncs + global onlyfuncs, include_paths, previous_context + global strictf77, sourcecodeform, quiet, verbose, tabchar, pyffilename + global f77modulename, skipemptyends, ignorecontains, dolowercase, debug + + # flags + strictf77 = 1 + sourcecodeform = 'fix' + quiet = 0 + verbose = 1 + tabchar = 4 * ' ' + pyffilename = '' + f77modulename = '' + skipemptyends = 0 + ignorecontains = 1 + dolowercase = 1 + debug = [] + # variables + groupcounter = 0 + grouplist = {groupcounter: []} + neededmodule = -1 + expectbegin = 1 + skipblocksuntil = -1 + usermodules = [] + f90modulevars = {} + gotnextfile = 1 + filepositiontext = '' + currentfilename = '' + skipfunctions = [] + skipfuncs = [] + onlyfuncs = [] + include_paths = [] + previous_context = None + + +def outmess(line, flag=1): + global filepositiontext + + if not verbose: + return + if not quiet: + if flag: + sys.stdout.write(filepositiontext) + sys.stdout.write(line) + +re._MAXCACHE = 50 +defaultimplicitrules = {} +for c in "abcdefghopqrstuvwxyz$_": + defaultimplicitrules[c] = {'typespec': 'real'} +for c in "ijklmn": + defaultimplicitrules[c] = {'typespec': 'integer'} +del c +badnames = {} +invbadnames = {} +for n in ['int', 'double', 'float', 'char', 'short', 'long', 'void', 'case', 'while', + 'return', 'signed', 'unsigned', 'if', 'for', 'typedef', 'sizeof', 'union', + 'struct', 'static', 'register', 'new', 'break', 'do', 'goto', 'switch', + 'continue', 'else', 'inline', 'extern', 'delete', 'const', 'auto', + 'len', 'rank', 'shape', 'index', 'slen', 'size', '_i', + 'max', 'min', + 'flen', 'fshape', + 'string', 'complex_double', 'float_double', 'stdin', 'stderr', 'stdout', + 'type', 'default']: + badnames[n] = n + '_bn' + invbadnames[n + '_bn'] = n + + +def rmbadname1(name): + if name in badnames: + errmess('rmbadname1: Replacing "%s" with "%s".\n' % + (name, badnames[name])) + return badnames[name] + return name + + +def rmbadname(names): + return [rmbadname1(_m) for _m in names] + + +def undo_rmbadname1(name): + if name in invbadnames: + errmess('undo_rmbadname1: Replacing "%s" with "%s".\n' + % (name, invbadnames[name])) + return invbadnames[name] + return name + + +def undo_rmbadname(names): + return [undo_rmbadname1(_m) for _m in names] + + +def getextension(name): + i = name.rfind('.') + if i == -1: + return '' + if '\\' in name[i:]: + return '' + if '/' in name[i:]: + return '' + return name[i + 1:] + +is_f_file = re.compile(r'.*\.(for|ftn|f77|f)\Z', re.I).match +_has_f_header = re.compile(r'-\*-\s*fortran\s*-\*-', re.I).search +_has_f90_header = re.compile(r'-\*-\s*f90\s*-\*-', re.I).search +_has_fix_header = re.compile(r'-\*-\s*fix\s*-\*-', re.I).search +_free_f90_start = re.compile(r'[^c*]\s*[^\s\d\t]', re.I).match + + +def is_free_format(file): + """Check if file is in free format Fortran.""" + # f90 allows both fixed and free format, assuming fixed unless + # signs of free format are detected. + result = 0 + with open(file, 'r') as f: + line = f.readline() + n = 15 # the number of non-comment lines to scan for hints + if _has_f_header(line): + n = 0 + elif _has_f90_header(line): + n = 0 + result = 1 + while n > 0 and line: + if line[0] != '!' and line.strip(): + n -= 1 + if (line[0] != '\t' and _free_f90_start(line[:5])) or line[-2:-1] == '&': + result = 1 + break + line = f.readline() + return result + + +# Read fortran (77,90) code +def readfortrancode(ffile, dowithline=show, istop=1): + """ + Read fortran codes from files and + 1) Get rid of comments, line continuations, and empty lines; lower cases. + 2) Call dowithline(line) on every line. + 3) Recursively call itself when statement \"include ''\" is met. + """ + global gotnextfile, filepositiontext, currentfilename, sourcecodeform, strictf77 + global beginpattern, quiet, verbose, dolowercase, include_paths + + if not istop: + saveglobals = gotnextfile, filepositiontext, currentfilename, sourcecodeform, strictf77,\ + beginpattern, quiet, verbose, dolowercase + if ffile == []: + return + localdolowercase = dolowercase + cont = 0 + finalline = '' + ll = '' + includeline = re.compile( + r'\s*include\s*(\'|")(?P[^\'"]*)(\'|")', re.I) + cont1 = re.compile(r'(?P.*)&\s*\Z') + cont2 = re.compile(r'(\s*&|)(?P.*)') + mline_mark = re.compile(r".*?'''") + if istop: + dowithline('', -1) + ll, l1 = '', '' + spacedigits = [' '] + [str(_m) for _m in range(10)] + filepositiontext = '' + fin = fileinput.FileInput(ffile) + while True: + l = fin.readline() + if not l: + break + if fin.isfirstline(): + filepositiontext = '' + currentfilename = fin.filename() + gotnextfile = 1 + l1 = l + strictf77 = 0 + sourcecodeform = 'fix' + ext = os.path.splitext(currentfilename)[1] + if is_f_file(currentfilename) and \ + not (_has_f90_header(l) or _has_fix_header(l)): + strictf77 = 1 + elif is_free_format(currentfilename) and not _has_fix_header(l): + sourcecodeform = 'free' + if strictf77: + beginpattern = beginpattern77 + else: + beginpattern = beginpattern90 + outmess('\tReading file %s (format:%s%s)\n' + % (repr(currentfilename), sourcecodeform, + strictf77 and ',strict' or '')) + + l = l.expandtabs().replace('\xa0', ' ') + # Get rid of newline characters + while not l == '': + if l[-1] not in "\n\r\f": + break + l = l[:-1] + if not strictf77: + (l, rl) = split_by_unquoted(l, '!') + l += ' ' + if rl[:5].lower() == '!f2py': # f2py directive + l, _ = split_by_unquoted(l + 4 * ' ' + rl[5:], '!') + if l.strip() == '': # Skip empty line + cont = 0 + continue + if sourcecodeform == 'fix': + if l[0] in ['*', 'c', '!', 'C', '#']: + if l[1:5].lower() == 'f2py': # f2py directive + l = ' ' + l[5:] + else: # Skip comment line + cont = 0 + continue + elif strictf77: + if len(l) > 72: + l = l[:72] + if not (l[0] in spacedigits): + raise Exception('readfortrancode: Found non-(space,digit) char ' + 'in the first column.\n\tAre you sure that ' + 'this code is in fix form?\n\tline=%s' % repr(l)) + + if (not cont or strictf77) and (len(l) > 5 and not l[5] == ' '): + # Continuation of a previous line + ll = ll + l[6:] + finalline = '' + origfinalline = '' + else: + if not strictf77: + # F90 continuation + r = cont1.match(l) + if r: + l = r.group('line') # Continuation follows .. + if cont: + ll = ll + cont2.match(l).group('line') + finalline = '' + origfinalline = '' + else: + # clean up line beginning from possible digits. + l = ' ' + l[5:] + if localdolowercase: + finalline = ll.lower() + else: + finalline = ll + origfinalline = ll + ll = l + cont = (r is not None) + else: + # clean up line beginning from possible digits. + l = ' ' + l[5:] + if localdolowercase: + finalline = ll.lower() + else: + finalline = ll + origfinalline = ll + ll = l + + elif sourcecodeform == 'free': + if not cont and ext == '.pyf' and mline_mark.match(l): + l = l + '\n' + while True: + lc = fin.readline() + if not lc: + errmess( + 'Unexpected end of file when reading multiline\n') + break + l = l + lc + if mline_mark.match(lc): + break + l = l.rstrip() + r = cont1.match(l) + if r: + l = r.group('line') # Continuation follows .. + if cont: + ll = ll + cont2.match(l).group('line') + finalline = '' + origfinalline = '' + else: + if localdolowercase: + finalline = ll.lower() + else: + finalline = ll + origfinalline = ll + ll = l + cont = (r is not None) + else: + raise ValueError( + "Flag sourcecodeform must be either 'fix' or 'free': %s" % repr(sourcecodeform)) + filepositiontext = 'Line #%d in %s:"%s"\n\t' % ( + fin.filelineno() - 1, currentfilename, l1) + m = includeline.match(origfinalline) + if m: + fn = m.group('name') + if os.path.isfile(fn): + readfortrancode(fn, dowithline=dowithline, istop=0) + else: + include_dirs = [ + os.path.dirname(currentfilename)] + include_paths + foundfile = 0 + for inc_dir in include_dirs: + fn1 = os.path.join(inc_dir, fn) + if os.path.isfile(fn1): + foundfile = 1 + readfortrancode(fn1, dowithline=dowithline, istop=0) + break + if not foundfile: + outmess('readfortrancode: could not find include file %s in %s. Ignoring.\n' % ( + repr(fn), os.pathsep.join(include_dirs))) + else: + dowithline(finalline) + l1 = ll + if localdolowercase: + finalline = ll.lower() + else: + finalline = ll + origfinalline = ll + filepositiontext = 'Line #%d in %s:"%s"\n\t' % ( + fin.filelineno() - 1, currentfilename, l1) + m = includeline.match(origfinalline) + if m: + fn = m.group('name') + if os.path.isfile(fn): + readfortrancode(fn, dowithline=dowithline, istop=0) + else: + include_dirs = [os.path.dirname(currentfilename)] + include_paths + foundfile = 0 + for inc_dir in include_dirs: + fn1 = os.path.join(inc_dir, fn) + if os.path.isfile(fn1): + foundfile = 1 + readfortrancode(fn1, dowithline=dowithline, istop=0) + break + if not foundfile: + outmess('readfortrancode: could not find include file %s in %s. Ignoring.\n' % ( + repr(fn), os.pathsep.join(include_dirs))) + else: + dowithline(finalline) + filepositiontext = '' + fin.close() + if istop: + dowithline('', 1) + else: + gotnextfile, filepositiontext, currentfilename, sourcecodeform, strictf77,\ + beginpattern, quiet, verbose, dolowercase = saveglobals + +# Crack line +beforethisafter = r'\s*(?P%s(?=\s*(\b(%s)\b)))' + \ + r'\s*(?P(\b(%s)\b))' + \ + r'\s*(?P%s)\s*\Z' +## +fortrantypes = r'character|logical|integer|real|complex|double\s*(precision\s*(complex|)|complex)|type(?=\s*\([\w\s,=(*)]*\))|byte' +typespattern = re.compile( + beforethisafter % ('', fortrantypes, fortrantypes, '.*'), re.I), 'type' +typespattern4implicit = re.compile(beforethisafter % ( + '', fortrantypes + '|static|automatic|undefined', fortrantypes + '|static|automatic|undefined', '.*'), re.I) +# +functionpattern = re.compile(beforethisafter % ( + r'([a-z]+[\w\s(=*+-/)]*?|)', 'function', 'function', '.*'), re.I), 'begin' +subroutinepattern = re.compile(beforethisafter % ( + r'[a-z\s]*?', 'subroutine', 'subroutine', '.*'), re.I), 'begin' +# modulepattern=re.compile(beforethisafter%('[a-z\s]*?','module','module','.*'),re.I),'begin' +# +groupbegins77 = r'program|block\s*data' +beginpattern77 = re.compile( + beforethisafter % ('', groupbegins77, groupbegins77, '.*'), re.I), 'begin' +groupbegins90 = groupbegins77 + \ + r'|module(?!\s*procedure)|python\s*module|interface|type(?!\s*\()' +beginpattern90 = re.compile( + beforethisafter % ('', groupbegins90, groupbegins90, '.*'), re.I), 'begin' +groupends = (r'end|endprogram|endblockdata|endmodule|endpythonmodule|' + r'endinterface|endsubroutine|endfunction') +endpattern = re.compile( + beforethisafter % ('', groupends, groupends, r'[\w\s]*'), re.I), 'end' +# endifs='end\s*(if|do|where|select|while|forall)' +endifs = r'(end\s*(if|do|where|select|while|forall))|(module\s*procedure)' +endifpattern = re.compile( + beforethisafter % (r'[\w]*?', endifs, endifs, r'[\w\s]*'), re.I), 'endif' +# +implicitpattern = re.compile( + beforethisafter % ('', 'implicit', 'implicit', '.*'), re.I), 'implicit' +dimensionpattern = re.compile(beforethisafter % ( + '', 'dimension|virtual', 'dimension|virtual', '.*'), re.I), 'dimension' +externalpattern = re.compile( + beforethisafter % ('', 'external', 'external', '.*'), re.I), 'external' +optionalpattern = re.compile( + beforethisafter % ('', 'optional', 'optional', '.*'), re.I), 'optional' +requiredpattern = re.compile( + beforethisafter % ('', 'required', 'required', '.*'), re.I), 'required' +publicpattern = re.compile( + beforethisafter % ('', 'public', 'public', '.*'), re.I), 'public' +privatepattern = re.compile( + beforethisafter % ('', 'private', 'private', '.*'), re.I), 'private' +intrinsicpattern = re.compile( + beforethisafter % ('', 'intrinsic', 'intrinsic', '.*'), re.I), 'intrinsic' +intentpattern = re.compile(beforethisafter % ( + '', 'intent|depend|note|check', 'intent|depend|note|check', r'\s*\(.*?\).*'), re.I), 'intent' +parameterpattern = re.compile( + beforethisafter % ('', 'parameter', 'parameter', r'\s*\(.*'), re.I), 'parameter' +datapattern = re.compile( + beforethisafter % ('', 'data', 'data', '.*'), re.I), 'data' +callpattern = re.compile( + beforethisafter % ('', 'call', 'call', '.*'), re.I), 'call' +entrypattern = re.compile( + beforethisafter % ('', 'entry', 'entry', '.*'), re.I), 'entry' +callfunpattern = re.compile( + beforethisafter % ('', 'callfun', 'callfun', '.*'), re.I), 'callfun' +commonpattern = re.compile( + beforethisafter % ('', 'common', 'common', '.*'), re.I), 'common' +usepattern = re.compile( + beforethisafter % ('', 'use', 'use', '.*'), re.I), 'use' +containspattern = re.compile( + beforethisafter % ('', 'contains', 'contains', ''), re.I), 'contains' +formatpattern = re.compile( + beforethisafter % ('', 'format', 'format', '.*'), re.I), 'format' +# Non-fortran and f2py-specific statements +f2pyenhancementspattern = re.compile(beforethisafter % ('', 'threadsafe|fortranname|callstatement|callprotoargument|usercode|pymethoddef', + 'threadsafe|fortranname|callstatement|callprotoargument|usercode|pymethoddef', '.*'), re.I | re.S), 'f2pyenhancements' +multilinepattern = re.compile( + r"\s*(?P''')(?P.*?)(?P''')\s*\Z", re.S), 'multiline' +## + +def split_by_unquoted(line, characters): + """ + Splits the line into (line[:i], line[i:]), + where i is the index of first occurrence of one of the characters + not within quotes, or len(line) if no such index exists + """ + assert not (set('"\'') & set(characters)), "cannot split by unquoted quotes" + r = re.compile( + r"\A(?P({single_quoted}|{double_quoted}|{not_quoted})*)" + r"(?P{char}.*)\Z".format( + not_quoted="[^\"'{}]".format(re.escape(characters)), + char="[{}]".format(re.escape(characters)), + single_quoted=r"('([^'\\]|(\\.))*')", + double_quoted=r'("([^"\\]|(\\.))*")')) + m = r.match(line) + if m: + d = m.groupdict() + return (d["before"], d["after"]) + return (line, "") + +def _simplifyargs(argsline): + a = [] + for n in markoutercomma(argsline).split('@,@'): + for r in '(),': + n = n.replace(r, '_') + a.append(n) + return ','.join(a) + +crackline_re_1 = re.compile(r'\s*(?P\b[a-z]+\w*\b)\s*=.*', re.I) + + +def crackline(line, reset=0): + """ + reset=-1 --- initialize + reset=0 --- crack the line + reset=1 --- final check if mismatch of blocks occurred + + Cracked data is saved in grouplist[0]. + """ + global beginpattern, groupcounter, groupname, groupcache, grouplist + global filepositiontext, currentfilename, neededmodule, expectbegin + global skipblocksuntil, skipemptyends, previous_context, gotnextfile + + _, has_semicolon = split_by_unquoted(line, ";") + if has_semicolon and not (f2pyenhancementspattern[0].match(line) or + multilinepattern[0].match(line)): + # XXX: non-zero reset values need testing + assert reset == 0, repr(reset) + # split line on unquoted semicolons + line, semicolon_line = split_by_unquoted(line, ";") + while semicolon_line: + crackline(line, reset) + line, semicolon_line = split_by_unquoted(semicolon_line[1:], ";") + crackline(line, reset) + return + if reset < 0: + groupcounter = 0 + groupname = {groupcounter: ''} + groupcache = {groupcounter: {}} + grouplist = {groupcounter: []} + groupcache[groupcounter]['body'] = [] + groupcache[groupcounter]['vars'] = {} + groupcache[groupcounter]['block'] = '' + groupcache[groupcounter]['name'] = '' + neededmodule = -1 + skipblocksuntil = -1 + return + if reset > 0: + fl = 0 + if f77modulename and neededmodule == groupcounter: + fl = 2 + while groupcounter > fl: + outmess('crackline: groupcounter=%s groupname=%s\n' % + (repr(groupcounter), repr(groupname))) + outmess( + 'crackline: Mismatch of blocks encountered. Trying to fix it by assuming "end" statement.\n') + grouplist[groupcounter - 1].append(groupcache[groupcounter]) + grouplist[groupcounter - 1][-1]['body'] = grouplist[groupcounter] + del grouplist[groupcounter] + groupcounter = groupcounter - 1 + if f77modulename and neededmodule == groupcounter: + grouplist[groupcounter - 1].append(groupcache[groupcounter]) + grouplist[groupcounter - 1][-1]['body'] = grouplist[groupcounter] + del grouplist[groupcounter] + groupcounter = groupcounter - 1 # end interface + grouplist[groupcounter - 1].append(groupcache[groupcounter]) + grouplist[groupcounter - 1][-1]['body'] = grouplist[groupcounter] + del grouplist[groupcounter] + groupcounter = groupcounter - 1 # end module + neededmodule = -1 + return + if line == '': + return + flag = 0 + for pat in [dimensionpattern, externalpattern, intentpattern, optionalpattern, + requiredpattern, + parameterpattern, datapattern, publicpattern, privatepattern, + intrinsicpattern, + endifpattern, endpattern, + formatpattern, + beginpattern, functionpattern, subroutinepattern, + implicitpattern, typespattern, commonpattern, + callpattern, usepattern, containspattern, + entrypattern, + f2pyenhancementspattern, + multilinepattern + ]: + m = pat[0].match(line) + if m: + break + flag = flag + 1 + if not m: + re_1 = crackline_re_1 + if 0 <= skipblocksuntil <= groupcounter: + return + if 'externals' in groupcache[groupcounter]: + for name in groupcache[groupcounter]['externals']: + if name in invbadnames: + name = invbadnames[name] + if 'interfaced' in groupcache[groupcounter] and name in groupcache[groupcounter]['interfaced']: + continue + m1 = re.match( + r'(?P[^"]*)\b%s\b\s*@\(@(?P[^@]*)@\)@.*\Z' % name, markouterparen(line), re.I) + if m1: + m2 = re_1.match(m1.group('before')) + a = _simplifyargs(m1.group('args')) + if m2: + line = 'callfun %s(%s) result (%s)' % ( + name, a, m2.group('result')) + else: + line = 'callfun %s(%s)' % (name, a) + m = callfunpattern[0].match(line) + if not m: + outmess( + 'crackline: could not resolve function call for line=%s.\n' % repr(line)) + return + analyzeline(m, 'callfun', line) + return + if verbose > 1 or (verbose == 1 and currentfilename.lower().endswith('.pyf')): + previous_context = None + outmess('crackline:%d: No pattern for line\n' % (groupcounter)) + return + elif pat[1] == 'end': + if 0 <= skipblocksuntil < groupcounter: + groupcounter = groupcounter - 1 + if skipblocksuntil <= groupcounter: + return + if groupcounter <= 0: + raise Exception('crackline: groupcounter(=%s) is nonpositive. ' + 'Check the blocks.' + % (groupcounter)) + m1 = beginpattern[0].match((line)) + if (m1) and (not m1.group('this') == groupname[groupcounter]): + raise Exception('crackline: End group %s does not match with ' + 'previous Begin group %s\n\t%s' % + (repr(m1.group('this')), repr(groupname[groupcounter]), + filepositiontext) + ) + if skipblocksuntil == groupcounter: + skipblocksuntil = -1 + grouplist[groupcounter - 1].append(groupcache[groupcounter]) + grouplist[groupcounter - 1][-1]['body'] = grouplist[groupcounter] + del grouplist[groupcounter] + groupcounter = groupcounter - 1 + if not skipemptyends: + expectbegin = 1 + elif pat[1] == 'begin': + if 0 <= skipblocksuntil <= groupcounter: + groupcounter = groupcounter + 1 + return + gotnextfile = 0 + analyzeline(m, pat[1], line) + expectbegin = 0 + elif pat[1] == 'endif': + pass + elif pat[1] == 'contains': + if ignorecontains: + return + if 0 <= skipblocksuntil <= groupcounter: + return + skipblocksuntil = groupcounter + else: + if 0 <= skipblocksuntil <= groupcounter: + return + analyzeline(m, pat[1], line) + + +def markouterparen(line): + l = '' + f = 0 + for c in line: + if c == '(': + f = f + 1 + if f == 1: + l = l + '@(@' + continue + elif c == ')': + f = f - 1 + if f == 0: + l = l + '@)@' + continue + l = l + c + return l + + +def markoutercomma(line, comma=','): + l = '' + f = 0 + before, after = split_by_unquoted(line, comma + '()') + l += before + while after: + if (after[0] == comma) and (f == 0): + l += '@' + comma + '@' + else: + l += after[0] + if after[0] == '(': + f += 1 + elif after[0] == ')': + f -= 1 + before, after = split_by_unquoted(after[1:], comma + '()') + l += before + assert not f, repr((f, line, l)) + return l + +def unmarkouterparen(line): + r = line.replace('@(@', '(').replace('@)@', ')') + return r + + +def appenddecl(decl, decl2, force=1): + if not decl: + decl = {} + if not decl2: + return decl + if decl is decl2: + return decl + for k in list(decl2.keys()): + if k == 'typespec': + if force or k not in decl: + decl[k] = decl2[k] + elif k == 'attrspec': + for l in decl2[k]: + decl = setattrspec(decl, l, force) + elif k == 'kindselector': + decl = setkindselector(decl, decl2[k], force) + elif k == 'charselector': + decl = setcharselector(decl, decl2[k], force) + elif k in ['=', 'typename']: + if force or k not in decl: + decl[k] = decl2[k] + elif k == 'note': + pass + elif k in ['intent', 'check', 'dimension', 'optional', 'required']: + errmess('appenddecl: "%s" not implemented.\n' % k) + else: + raise Exception('appenddecl: Unknown variable definition key:' + + str(k)) + return decl + +selectpattern = re.compile( + r'\s*(?P(@\(@.*?@\)@|\*[\d*]+|\*\s*@\(@.*?@\)@|))(?P.*)\Z', re.I) +nameargspattern = re.compile( + r'\s*(?P\b[\w$]+\b)\s*(@\(@\s*(?P[\w\s,]*)\s*@\)@|)\s*((result(\s*@\(@\s*(?P\b[\w$]+\b)\s*@\)@|))|(bind\s*@\(@\s*(?P.*)\s*@\)@))*\s*\Z', re.I) +callnameargspattern = re.compile( + r'\s*(?P\b[\w$]+\b)\s*@\(@\s*(?P.*)\s*@\)@\s*\Z', re.I) +real16pattern = re.compile( + r'([-+]?(?:\d+(?:\.\d*)?|\d*\.\d+))[dD]((?:[-+]?\d+)?)') +real8pattern = re.compile( + r'([-+]?((?:\d+(?:\.\d*)?|\d*\.\d+))[eE]((?:[-+]?\d+)?)|(\d+\.\d*))') + +_intentcallbackpattern = re.compile(r'intent\s*\(.*?\bcallback\b', re.I) + + +def _is_intent_callback(vdecl): + for a in vdecl.get('attrspec', []): + if _intentcallbackpattern.match(a): + return 1 + return 0 + + +def _resolvenameargspattern(line): + line = markouterparen(line) + m1 = nameargspattern.match(line) + if m1: + return m1.group('name'), m1.group('args'), m1.group('result'), m1.group('bind') + m1 = callnameargspattern.match(line) + if m1: + return m1.group('name'), m1.group('args'), None, None + return None, [], None, None + + +def analyzeline(m, case, line): + global groupcounter, groupname, groupcache, grouplist, filepositiontext + global currentfilename, f77modulename, neededinterface, neededmodule + global expectbegin, gotnextfile, previous_context + + block = m.group('this') + if case != 'multiline': + previous_context = None + if expectbegin and case not in ['begin', 'call', 'callfun', 'type'] \ + and not skipemptyends and groupcounter < 1: + newname = os.path.basename(currentfilename).split('.')[0] + outmess( + 'analyzeline: no group yet. Creating program group with name "%s".\n' % newname) + gotnextfile = 0 + groupcounter = groupcounter + 1 + groupname[groupcounter] = 'program' + groupcache[groupcounter] = {} + grouplist[groupcounter] = [] + groupcache[groupcounter]['body'] = [] + groupcache[groupcounter]['vars'] = {} + groupcache[groupcounter]['block'] = 'program' + groupcache[groupcounter]['name'] = newname + groupcache[groupcounter]['from'] = 'fromsky' + expectbegin = 0 + if case in ['begin', 'call', 'callfun']: + # Crack line => block,name,args,result + block = block.lower() + if re.match(r'block\s*data', block, re.I): + block = 'block data' + if re.match(r'python\s*module', block, re.I): + block = 'python module' + name, args, result, bind = _resolvenameargspattern(m.group('after')) + if name is None: + if block == 'block data': + name = '_BLOCK_DATA_' + else: + name = '' + if block not in ['interface', 'block data']: + outmess('analyzeline: No name/args pattern found for line.\n') + + previous_context = (block, name, groupcounter) + if args: + args = rmbadname([x.strip() + for x in markoutercomma(args).split('@,@')]) + else: + args = [] + if '' in args: + while '' in args: + args.remove('') + outmess( + 'analyzeline: argument list is malformed (missing argument).\n') + + # end of crack line => block,name,args,result + needmodule = 0 + needinterface = 0 + + if case in ['call', 'callfun']: + needinterface = 1 + if 'args' not in groupcache[groupcounter]: + return + if name not in groupcache[groupcounter]['args']: + return + for it in grouplist[groupcounter]: + if it['name'] == name: + return + if name in groupcache[groupcounter]['interfaced']: + return + block = {'call': 'subroutine', 'callfun': 'function'}[case] + if f77modulename and neededmodule == -1 and groupcounter <= 1: + neededmodule = groupcounter + 2 + needmodule = 1 + if block != 'interface': + needinterface = 1 + # Create new block(s) + groupcounter = groupcounter + 1 + groupcache[groupcounter] = {} + grouplist[groupcounter] = [] + if needmodule: + if verbose > 1: + outmess('analyzeline: Creating module block %s\n' % + repr(f77modulename), 0) + groupname[groupcounter] = 'module' + groupcache[groupcounter]['block'] = 'python module' + groupcache[groupcounter]['name'] = f77modulename + groupcache[groupcounter]['from'] = '' + groupcache[groupcounter]['body'] = [] + groupcache[groupcounter]['externals'] = [] + groupcache[groupcounter]['interfaced'] = [] + groupcache[groupcounter]['vars'] = {} + groupcounter = groupcounter + 1 + groupcache[groupcounter] = {} + grouplist[groupcounter] = [] + if needinterface: + if verbose > 1: + outmess('analyzeline: Creating additional interface block (groupcounter=%s).\n' % ( + groupcounter), 0) + groupname[groupcounter] = 'interface' + groupcache[groupcounter]['block'] = 'interface' + groupcache[groupcounter]['name'] = 'unknown_interface' + groupcache[groupcounter]['from'] = '%s:%s' % ( + groupcache[groupcounter - 1]['from'], groupcache[groupcounter - 1]['name']) + groupcache[groupcounter]['body'] = [] + groupcache[groupcounter]['externals'] = [] + groupcache[groupcounter]['interfaced'] = [] + groupcache[groupcounter]['vars'] = {} + groupcounter = groupcounter + 1 + groupcache[groupcounter] = {} + grouplist[groupcounter] = [] + groupname[groupcounter] = block + groupcache[groupcounter]['block'] = block + if not name: + name = 'unknown_' + block + groupcache[groupcounter]['prefix'] = m.group('before') + groupcache[groupcounter]['name'] = rmbadname1(name) + groupcache[groupcounter]['result'] = result + if groupcounter == 1: + groupcache[groupcounter]['from'] = currentfilename + else: + if f77modulename and groupcounter == 3: + groupcache[groupcounter]['from'] = '%s:%s' % ( + groupcache[groupcounter - 1]['from'], currentfilename) + else: + groupcache[groupcounter]['from'] = '%s:%s' % ( + groupcache[groupcounter - 1]['from'], groupcache[groupcounter - 1]['name']) + for k in list(groupcache[groupcounter].keys()): + if not groupcache[groupcounter][k]: + del groupcache[groupcounter][k] + + groupcache[groupcounter]['args'] = args + groupcache[groupcounter]['body'] = [] + groupcache[groupcounter]['externals'] = [] + groupcache[groupcounter]['interfaced'] = [] + groupcache[groupcounter]['vars'] = {} + groupcache[groupcounter]['entry'] = {} + # end of creation + if block == 'type': + groupcache[groupcounter]['varnames'] = [] + + if case in ['call', 'callfun']: # set parents variables + if name not in groupcache[groupcounter - 2]['externals']: + groupcache[groupcounter - 2]['externals'].append(name) + groupcache[groupcounter]['vars'] = copy.deepcopy( + groupcache[groupcounter - 2]['vars']) + try: + del groupcache[groupcounter]['vars'][name][ + groupcache[groupcounter]['vars'][name]['attrspec'].index('external')] + except Exception: + pass + if block in ['function', 'subroutine']: # set global attributes + try: + groupcache[groupcounter]['vars'][name] = appenddecl( + groupcache[groupcounter]['vars'][name], groupcache[groupcounter - 2]['vars']['']) + except Exception: + pass + if case == 'callfun': # return type + if result and result in groupcache[groupcounter]['vars']: + if not name == result: + groupcache[groupcounter]['vars'][name] = appenddecl( + groupcache[groupcounter]['vars'][name], groupcache[groupcounter]['vars'][result]) + # if groupcounter>1: # name is interfaced + try: + groupcache[groupcounter - 2]['interfaced'].append(name) + except Exception: + pass + if block == 'function': + t = typespattern[0].match(m.group('before') + ' ' + name) + if t: + typespec, selector, attr, edecl = cracktypespec0( + t.group('this'), t.group('after')) + updatevars(typespec, selector, attr, edecl) + + if case in ['call', 'callfun']: + grouplist[groupcounter - 1].append(groupcache[groupcounter]) + grouplist[groupcounter - 1][-1]['body'] = grouplist[groupcounter] + del grouplist[groupcounter] + groupcounter = groupcounter - 1 # end routine + grouplist[groupcounter - 1].append(groupcache[groupcounter]) + grouplist[groupcounter - 1][-1]['body'] = grouplist[groupcounter] + del grouplist[groupcounter] + groupcounter = groupcounter - 1 # end interface + + elif case == 'entry': + name, args, result, bind = _resolvenameargspattern(m.group('after')) + if name is not None: + if args: + args = rmbadname([x.strip() + for x in markoutercomma(args).split('@,@')]) + else: + args = [] + assert result is None, repr(result) + groupcache[groupcounter]['entry'][name] = args + previous_context = ('entry', name, groupcounter) + elif case == 'type': + typespec, selector, attr, edecl = cracktypespec0( + block, m.group('after')) + last_name = updatevars(typespec, selector, attr, edecl) + if last_name is not None: + previous_context = ('variable', last_name, groupcounter) + elif case in ['dimension', 'intent', 'optional', 'required', 'external', 'public', 'private', 'intrinsic']: + edecl = groupcache[groupcounter]['vars'] + ll = m.group('after').strip() + i = ll.find('::') + if i < 0 and case == 'intent': + i = markouterparen(ll).find('@)@') - 2 + ll = ll[:i + 1] + '::' + ll[i + 1:] + i = ll.find('::') + if ll[i:] == '::' and 'args' in groupcache[groupcounter]: + outmess('All arguments will have attribute %s%s\n' % + (m.group('this'), ll[:i])) + ll = ll + ','.join(groupcache[groupcounter]['args']) + if i < 0: + i = 0 + pl = '' + else: + pl = ll[:i].strip() + ll = ll[i + 2:] + ch = markoutercomma(pl).split('@,@') + if len(ch) > 1: + pl = ch[0] + outmess('analyzeline: cannot handle multiple attributes without type specification. Ignoring %r.\n' % ( + ','.join(ch[1:]))) + last_name = None + + for e in [x.strip() for x in markoutercomma(ll).split('@,@')]: + m1 = namepattern.match(e) + if not m1: + if case in ['public', 'private']: + k = '' + else: + print(m.groupdict()) + outmess('analyzeline: no name pattern found in %s statement for %s. Skipping.\n' % ( + case, repr(e))) + continue + else: + k = rmbadname1(m1.group('name')) + if k not in edecl: + edecl[k] = {} + if case == 'dimension': + ap = case + m1.group('after') + if case == 'intent': + ap = m.group('this') + pl + if _intentcallbackpattern.match(ap): + if k not in groupcache[groupcounter]['args']: + if groupcounter > 1: + if '__user__' not in groupcache[groupcounter - 2]['name']: + outmess( + 'analyzeline: missing __user__ module (could be nothing)\n') + # fixes ticket 1693 + if k != groupcache[groupcounter]['name']: + outmess('analyzeline: appending intent(callback) %s' + ' to %s arguments\n' % (k, groupcache[groupcounter]['name'])) + groupcache[groupcounter]['args'].append(k) + else: + errmess( + 'analyzeline: intent(callback) %s is ignored' % (k)) + else: + errmess('analyzeline: intent(callback) %s is already' + ' in argument list' % (k)) + if case in ['optional', 'required', 'public', 'external', 'private', 'intrinsic']: + ap = case + if 'attrspec' in edecl[k]: + edecl[k]['attrspec'].append(ap) + else: + edecl[k]['attrspec'] = [ap] + if case == 'external': + if groupcache[groupcounter]['block'] == 'program': + outmess('analyzeline: ignoring program arguments\n') + continue + if k not in groupcache[groupcounter]['args']: + continue + if 'externals' not in groupcache[groupcounter]: + groupcache[groupcounter]['externals'] = [] + groupcache[groupcounter]['externals'].append(k) + last_name = k + groupcache[groupcounter]['vars'] = edecl + if last_name is not None: + previous_context = ('variable', last_name, groupcounter) + elif case == 'parameter': + edecl = groupcache[groupcounter]['vars'] + ll = m.group('after').strip()[1:-1] + last_name = None + for e in markoutercomma(ll).split('@,@'): + try: + k, initexpr = [x.strip() for x in e.split('=')] + except Exception: + outmess( + 'analyzeline: could not extract name,expr in parameter statement "%s" of "%s"\n' % (e, ll)) + continue + params = get_parameters(edecl) + k = rmbadname1(k) + if k not in edecl: + edecl[k] = {} + if '=' in edecl[k] and (not edecl[k]['='] == initexpr): + outmess('analyzeline: Overwriting the value of parameter "%s" ("%s") with "%s".\n' % ( + k, edecl[k]['='], initexpr)) + t = determineexprtype(initexpr, params) + if t: + if t.get('typespec') == 'real': + tt = list(initexpr) + for m in real16pattern.finditer(initexpr): + tt[m.start():m.end()] = list( + initexpr[m.start():m.end()].lower().replace('d', 'e')) + initexpr = ''.join(tt) + elif t.get('typespec') == 'complex': + initexpr = initexpr[1:].lower().replace('d', 'e').\ + replace(',', '+1j*(') + try: + v = eval(initexpr, {}, params) + except (SyntaxError, NameError, TypeError) as msg: + errmess('analyzeline: Failed to evaluate %r. Ignoring: %s\n' + % (initexpr, msg)) + continue + edecl[k]['='] = repr(v) + if 'attrspec' in edecl[k]: + edecl[k]['attrspec'].append('parameter') + else: + edecl[k]['attrspec'] = ['parameter'] + last_name = k + groupcache[groupcounter]['vars'] = edecl + if last_name is not None: + previous_context = ('variable', last_name, groupcounter) + elif case == 'implicit': + if m.group('after').strip().lower() == 'none': + groupcache[groupcounter]['implicit'] = None + elif m.group('after'): + if 'implicit' in groupcache[groupcounter]: + impl = groupcache[groupcounter]['implicit'] + else: + impl = {} + if impl is None: + outmess( + 'analyzeline: Overwriting earlier "implicit none" statement.\n') + impl = {} + for e in markoutercomma(m.group('after')).split('@,@'): + decl = {} + m1 = re.match( + r'\s*(?P.*?)\s*(\(\s*(?P[a-z-, ]+)\s*\)\s*|)\Z', e, re.I) + if not m1: + outmess( + 'analyzeline: could not extract info of implicit statement part "%s"\n' % (e)) + continue + m2 = typespattern4implicit.match(m1.group('this')) + if not m2: + outmess( + 'analyzeline: could not extract types pattern of implicit statement part "%s"\n' % (e)) + continue + typespec, selector, attr, edecl = cracktypespec0( + m2.group('this'), m2.group('after')) + kindselect, charselect, typename = cracktypespec( + typespec, selector) + decl['typespec'] = typespec + decl['kindselector'] = kindselect + decl['charselector'] = charselect + decl['typename'] = typename + for k in list(decl.keys()): + if not decl[k]: + del decl[k] + for r in markoutercomma(m1.group('after')).split('@,@'): + if '-' in r: + try: + begc, endc = [x.strip() for x in r.split('-')] + except Exception: + outmess( + 'analyzeline: expected "-" instead of "%s" in range list of implicit statement\n' % r) + continue + else: + begc = endc = r.strip() + if not len(begc) == len(endc) == 1: + outmess( + 'analyzeline: expected "-" instead of "%s" in range list of implicit statement (2)\n' % r) + continue + for o in range(ord(begc), ord(endc) + 1): + impl[chr(o)] = decl + groupcache[groupcounter]['implicit'] = impl + elif case == 'data': + ll = [] + dl = '' + il = '' + f = 0 + fc = 1 + inp = 0 + for c in m.group('after'): + if not inp: + if c == "'": + fc = not fc + if c == '/' and fc: + f = f + 1 + continue + if c == '(': + inp = inp + 1 + elif c == ')': + inp = inp - 1 + if f == 0: + dl = dl + c + elif f == 1: + il = il + c + elif f == 2: + dl = dl.strip() + if dl.startswith(','): + dl = dl[1:].strip() + ll.append([dl, il]) + dl = c + il = '' + f = 0 + if f == 2: + dl = dl.strip() + if dl.startswith(','): + dl = dl[1:].strip() + ll.append([dl, il]) + vars = {} + if 'vars' in groupcache[groupcounter]: + vars = groupcache[groupcounter]['vars'] + last_name = None + for l in ll: + l = [x.strip() for x in l] + if l[0][0] == ',': + l[0] = l[0][1:] + if l[0][0] == '(': + outmess( + 'analyzeline: implied-DO list "%s" is not supported. Skipping.\n' % l[0]) + continue + i = 0 + j = 0 + llen = len(l[1]) + for v in rmbadname([x.strip() for x in markoutercomma(l[0]).split('@,@')]): + if v[0] == '(': + outmess( + 'analyzeline: implied-DO list "%s" is not supported. Skipping.\n' % v) + # XXX: subsequent init expressions may get wrong values. + # Ignoring since data statements are irrelevant for + # wrapping. + continue + fc = 0 + while (i < llen) and (fc or not l[1][i] == ','): + if l[1][i] == "'": + fc = not fc + i = i + 1 + i = i + 1 + if v not in vars: + vars[v] = {} + if '=' in vars[v] and not vars[v]['='] == l[1][j:i - 1]: + outmess('analyzeline: changing init expression of "%s" ("%s") to "%s"\n' % ( + v, vars[v]['='], l[1][j:i - 1])) + vars[v]['='] = l[1][j:i - 1] + j = i + last_name = v + groupcache[groupcounter]['vars'] = vars + if last_name is not None: + previous_context = ('variable', last_name, groupcounter) + elif case == 'common': + line = m.group('after').strip() + if not line[0] == '/': + line = '//' + line + cl = [] + f = 0 + bn = '' + ol = '' + for c in line: + if c == '/': + f = f + 1 + continue + if f >= 3: + bn = bn.strip() + if not bn: + bn = '_BLNK_' + cl.append([bn, ol]) + f = f - 2 + bn = '' + ol = '' + if f % 2: + bn = bn + c + else: + ol = ol + c + bn = bn.strip() + if not bn: + bn = '_BLNK_' + cl.append([bn, ol]) + commonkey = {} + if 'common' in groupcache[groupcounter]: + commonkey = groupcache[groupcounter]['common'] + for c in cl: + if c[0] not in commonkey: + commonkey[c[0]] = [] + for i in [x.strip() for x in markoutercomma(c[1]).split('@,@')]: + if i: + commonkey[c[0]].append(i) + groupcache[groupcounter]['common'] = commonkey + previous_context = ('common', bn, groupcounter) + elif case == 'use': + m1 = re.match( + r'\A\s*(?P\b\w+\b)\s*((,(\s*\bonly\b\s*:|(?P))\s*(?P.*))|)\s*\Z', m.group('after'), re.I) + if m1: + mm = m1.groupdict() + if 'use' not in groupcache[groupcounter]: + groupcache[groupcounter]['use'] = {} + name = m1.group('name') + groupcache[groupcounter]['use'][name] = {} + isonly = 0 + if 'list' in mm and mm['list'] is not None: + if 'notonly' in mm and mm['notonly'] is None: + isonly = 1 + groupcache[groupcounter]['use'][name]['only'] = isonly + ll = [x.strip() for x in mm['list'].split(',')] + rl = {} + for l in ll: + if '=' in l: + m2 = re.match( + r'\A\s*(?P\b\w+\b)\s*=\s*>\s*(?P\b\w+\b)\s*\Z', l, re.I) + if m2: + rl[m2.group('local').strip()] = m2.group( + 'use').strip() + else: + outmess( + 'analyzeline: Not local=>use pattern found in %s\n' % repr(l)) + else: + rl[l] = l + groupcache[groupcounter]['use'][name]['map'] = rl + else: + pass + else: + print(m.groupdict()) + outmess('analyzeline: Could not crack the use statement.\n') + elif case in ['f2pyenhancements']: + if 'f2pyenhancements' not in groupcache[groupcounter]: + groupcache[groupcounter]['f2pyenhancements'] = {} + d = groupcache[groupcounter]['f2pyenhancements'] + if m.group('this') == 'usercode' and 'usercode' in d: + if isinstance(d['usercode'], str): + d['usercode'] = [d['usercode']] + d['usercode'].append(m.group('after')) + else: + d[m.group('this')] = m.group('after') + elif case == 'multiline': + if previous_context is None: + if verbose: + outmess('analyzeline: No context for multiline block.\n') + return + gc = groupcounter + appendmultiline(groupcache[gc], + previous_context[:2], + m.group('this')) + else: + if verbose > 1: + print(m.groupdict()) + outmess('analyzeline: No code implemented for line.\n') + + +def appendmultiline(group, context_name, ml): + if 'f2pymultilines' not in group: + group['f2pymultilines'] = {} + d = group['f2pymultilines'] + if context_name not in d: + d[context_name] = [] + d[context_name].append(ml) + return + + +def cracktypespec0(typespec, ll): + selector = None + attr = None + if re.match(r'double\s*complex', typespec, re.I): + typespec = 'double complex' + elif re.match(r'double\s*precision', typespec, re.I): + typespec = 'double precision' + else: + typespec = typespec.strip().lower() + m1 = selectpattern.match(markouterparen(ll)) + if not m1: + outmess( + 'cracktypespec0: no kind/char_selector pattern found for line.\n') + return + d = m1.groupdict() + for k in list(d.keys()): + d[k] = unmarkouterparen(d[k]) + if typespec in ['complex', 'integer', 'logical', 'real', 'character', 'type']: + selector = d['this'] + ll = d['after'] + i = ll.find('::') + if i >= 0: + attr = ll[:i].strip() + ll = ll[i + 2:] + return typespec, selector, attr, ll +##### +namepattern = re.compile(r'\s*(?P\b\w+\b)\s*(?P.*)\s*\Z', re.I) +kindselector = re.compile( + r'\s*(\(\s*(kind\s*=)?\s*(?P.*)\s*\)|\*\s*(?P.*?))\s*\Z', re.I) +charselector = re.compile( + r'\s*(\((?P.*)\)|\*\s*(?P.*))\s*\Z', re.I) +lenkindpattern = re.compile( + r'\s*(kind\s*=\s*(?P.*?)\s*(@,@\s*len\s*=\s*(?P.*)|)|(len\s*=\s*|)(?P.*?)\s*(@,@\s*(kind\s*=\s*|)(?P.*)|))\s*\Z', re.I) +lenarraypattern = re.compile( + r'\s*(@\(@\s*(?!/)\s*(?P.*?)\s*@\)@\s*\*\s*(?P.*?)|(\*\s*(?P.*?)|)\s*(@\(@\s*(?!/)\s*(?P.*?)\s*@\)@|))\s*(=\s*(?P.*?)|(@\(@|)/\s*(?P.*?)\s*/(@\)@|)|)\s*\Z', re.I) + + +def removespaces(expr): + expr = expr.strip() + if len(expr) <= 1: + return expr + expr2 = expr[0] + for i in range(1, len(expr) - 1): + if (expr[i] == ' ' and + ((expr[i + 1] in "()[]{}=+-/* ") or + (expr[i - 1] in "()[]{}=+-/* "))): + continue + expr2 = expr2 + expr[i] + expr2 = expr2 + expr[-1] + return expr2 + + +def markinnerspaces(line): + l = '' + f = 0 + cc = '\'' + cb = '' + for c in line: + if cb == '\\' and c in ['\\', '\'', '"']: + l = l + c + cb = c + continue + if f == 0 and c in ['\'', '"']: + cc = c + if c == cc: + f = f + 1 + elif c == cc: + f = f - 1 + elif c == ' ' and f == 1: + l = l + '@_@' + continue + l = l + c + cb = c + return l + + +def updatevars(typespec, selector, attrspec, entitydecl): + global groupcache, groupcounter + + last_name = None + kindselect, charselect, typename = cracktypespec(typespec, selector) + if attrspec: + attrspec = [x.strip() for x in markoutercomma(attrspec).split('@,@')] + l = [] + c = re.compile(r'(?P[a-zA-Z]+)') + for a in attrspec: + if not a: + continue + m = c.match(a) + if m: + s = m.group('start').lower() + a = s + a[len(s):] + l.append(a) + attrspec = l + el = [x.strip() for x in markoutercomma(entitydecl).split('@,@')] + el1 = [] + for e in el: + for e1 in [x.strip() for x in markoutercomma(removespaces(markinnerspaces(e)), comma=' ').split('@ @')]: + if e1: + el1.append(e1.replace('@_@', ' ')) + for e in el1: + m = namepattern.match(e) + if not m: + outmess( + 'updatevars: no name pattern found for entity=%s. Skipping.\n' % (repr(e))) + continue + ename = rmbadname1(m.group('name')) + edecl = {} + if ename in groupcache[groupcounter]['vars']: + edecl = groupcache[groupcounter]['vars'][ename].copy() + not_has_typespec = 'typespec' not in edecl + if not_has_typespec: + edecl['typespec'] = typespec + elif typespec and (not typespec == edecl['typespec']): + outmess('updatevars: attempt to change the type of "%s" ("%s") to "%s". Ignoring.\n' % ( + ename, edecl['typespec'], typespec)) + if 'kindselector' not in edecl: + edecl['kindselector'] = copy.copy(kindselect) + elif kindselect: + for k in list(kindselect.keys()): + if k in edecl['kindselector'] and (not kindselect[k] == edecl['kindselector'][k]): + outmess('updatevars: attempt to change the kindselector "%s" of "%s" ("%s") to "%s". Ignoring.\n' % ( + k, ename, edecl['kindselector'][k], kindselect[k])) + else: + edecl['kindselector'][k] = copy.copy(kindselect[k]) + if 'charselector' not in edecl and charselect: + if not_has_typespec: + edecl['charselector'] = charselect + else: + errmess('updatevars:%s: attempt to change empty charselector to %r. Ignoring.\n' + % (ename, charselect)) + elif charselect: + for k in list(charselect.keys()): + if k in edecl['charselector'] and (not charselect[k] == edecl['charselector'][k]): + outmess('updatevars: attempt to change the charselector "%s" of "%s" ("%s") to "%s". Ignoring.\n' % ( + k, ename, edecl['charselector'][k], charselect[k])) + else: + edecl['charselector'][k] = copy.copy(charselect[k]) + if 'typename' not in edecl: + edecl['typename'] = typename + elif typename and (not edecl['typename'] == typename): + outmess('updatevars: attempt to change the typename of "%s" ("%s") to "%s". Ignoring.\n' % ( + ename, edecl['typename'], typename)) + if 'attrspec' not in edecl: + edecl['attrspec'] = copy.copy(attrspec) + elif attrspec: + for a in attrspec: + if a not in edecl['attrspec']: + edecl['attrspec'].append(a) + else: + edecl['typespec'] = copy.copy(typespec) + edecl['kindselector'] = copy.copy(kindselect) + edecl['charselector'] = copy.copy(charselect) + edecl['typename'] = typename + edecl['attrspec'] = copy.copy(attrspec) + if 'external' in (edecl.get('attrspec') or []) and e in groupcache[groupcounter]['args']: + if 'externals' not in groupcache[groupcounter]: + groupcache[groupcounter]['externals'] = [] + groupcache[groupcounter]['externals'].append(e) + if m.group('after'): + m1 = lenarraypattern.match(markouterparen(m.group('after'))) + if m1: + d1 = m1.groupdict() + for lk in ['len', 'array', 'init']: + if d1[lk + '2'] is not None: + d1[lk] = d1[lk + '2'] + del d1[lk + '2'] + for k in list(d1.keys()): + if d1[k] is not None: + d1[k] = unmarkouterparen(d1[k]) + else: + del d1[k] + if 'len' in d1 and 'array' in d1: + if d1['len'] == '': + d1['len'] = d1['array'] + del d1['array'] + else: + d1['array'] = d1['array'] + ',' + d1['len'] + del d1['len'] + errmess('updatevars: "%s %s" is mapped to "%s %s(%s)"\n' % ( + typespec, e, typespec, ename, d1['array'])) + if 'array' in d1: + dm = 'dimension(%s)' % d1['array'] + if 'attrspec' not in edecl or (not edecl['attrspec']): + edecl['attrspec'] = [dm] + else: + edecl['attrspec'].append(dm) + for dm1 in edecl['attrspec']: + if dm1[:9] == 'dimension' and dm1 != dm: + del edecl['attrspec'][-1] + errmess('updatevars:%s: attempt to change %r to %r. Ignoring.\n' + % (ename, dm1, dm)) + break + + if 'len' in d1: + if typespec in ['complex', 'integer', 'logical', 'real']: + if ('kindselector' not in edecl) or (not edecl['kindselector']): + edecl['kindselector'] = {} + edecl['kindselector']['*'] = d1['len'] + elif typespec == 'character': + if ('charselector' not in edecl) or (not edecl['charselector']): + edecl['charselector'] = {} + if 'len' in edecl['charselector']: + del edecl['charselector']['len'] + edecl['charselector']['*'] = d1['len'] + if 'init' in d1: + if '=' in edecl and (not edecl['='] == d1['init']): + outmess('updatevars: attempt to change the init expression of "%s" ("%s") to "%s". Ignoring.\n' % ( + ename, edecl['='], d1['init'])) + else: + edecl['='] = d1['init'] + else: + outmess('updatevars: could not crack entity declaration "%s". Ignoring.\n' % ( + ename + m.group('after'))) + for k in list(edecl.keys()): + if not edecl[k]: + del edecl[k] + groupcache[groupcounter]['vars'][ename] = edecl + if 'varnames' in groupcache[groupcounter]: + groupcache[groupcounter]['varnames'].append(ename) + last_name = ename + return last_name + + +def cracktypespec(typespec, selector): + kindselect = None + charselect = None + typename = None + if selector: + if typespec in ['complex', 'integer', 'logical', 'real']: + kindselect = kindselector.match(selector) + if not kindselect: + outmess( + 'cracktypespec: no kindselector pattern found for %s\n' % (repr(selector))) + return + kindselect = kindselect.groupdict() + kindselect['*'] = kindselect['kind2'] + del kindselect['kind2'] + for k in list(kindselect.keys()): + if not kindselect[k]: + del kindselect[k] + for k, i in list(kindselect.items()): + kindselect[k] = rmbadname1(i) + elif typespec == 'character': + charselect = charselector.match(selector) + if not charselect: + outmess( + 'cracktypespec: no charselector pattern found for %s\n' % (repr(selector))) + return + charselect = charselect.groupdict() + charselect['*'] = charselect['charlen'] + del charselect['charlen'] + if charselect['lenkind']: + lenkind = lenkindpattern.match( + markoutercomma(charselect['lenkind'])) + lenkind = lenkind.groupdict() + for lk in ['len', 'kind']: + if lenkind[lk + '2']: + lenkind[lk] = lenkind[lk + '2'] + charselect[lk] = lenkind[lk] + del lenkind[lk + '2'] + del charselect['lenkind'] + for k in list(charselect.keys()): + if not charselect[k]: + del charselect[k] + for k, i in list(charselect.items()): + charselect[k] = rmbadname1(i) + elif typespec == 'type': + typename = re.match(r'\s*\(\s*(?P\w+)\s*\)', selector, re.I) + if typename: + typename = typename.group('name') + else: + outmess('cracktypespec: no typename found in %s\n' % + (repr(typespec + selector))) + else: + outmess('cracktypespec: no selector used for %s\n' % + (repr(selector))) + return kindselect, charselect, typename +###### + + +def setattrspec(decl, attr, force=0): + if not decl: + decl = {} + if not attr: + return decl + if 'attrspec' not in decl: + decl['attrspec'] = [attr] + return decl + if force: + decl['attrspec'].append(attr) + if attr in decl['attrspec']: + return decl + if attr == 'static' and 'automatic' not in decl['attrspec']: + decl['attrspec'].append(attr) + elif attr == 'automatic' and 'static' not in decl['attrspec']: + decl['attrspec'].append(attr) + elif attr == 'public': + if 'private' not in decl['attrspec']: + decl['attrspec'].append(attr) + elif attr == 'private': + if 'public' not in decl['attrspec']: + decl['attrspec'].append(attr) + else: + decl['attrspec'].append(attr) + return decl + + +def setkindselector(decl, sel, force=0): + if not decl: + decl = {} + if not sel: + return decl + if 'kindselector' not in decl: + decl['kindselector'] = sel + return decl + for k in list(sel.keys()): + if force or k not in decl['kindselector']: + decl['kindselector'][k] = sel[k] + return decl + + +def setcharselector(decl, sel, force=0): + if not decl: + decl = {} + if not sel: + return decl + if 'charselector' not in decl: + decl['charselector'] = sel + return decl + for k in list(sel.keys()): + if force or k not in decl['charselector']: + decl['charselector'][k] = sel[k] + return decl + + +def getblockname(block, unknown='unknown'): + if 'name' in block: + return block['name'] + return unknown + +# post processing + + +def setmesstext(block): + global filepositiontext + + try: + filepositiontext = 'In: %s:%s\n' % (block['from'], block['name']) + except Exception: + pass + + +def get_usedict(block): + usedict = {} + if 'parent_block' in block: + usedict = get_usedict(block['parent_block']) + if 'use' in block: + usedict.update(block['use']) + return usedict + + +def get_useparameters(block, param_map=None): + global f90modulevars + + if param_map is None: + param_map = {} + usedict = get_usedict(block) + if not usedict: + return param_map + for usename, mapping in list(usedict.items()): + usename = usename.lower() + if usename not in f90modulevars: + outmess('get_useparameters: no module %s info used by %s\n' % + (usename, block.get('name'))) + continue + mvars = f90modulevars[usename] + params = get_parameters(mvars) + if not params: + continue + # XXX: apply mapping + if mapping: + errmess('get_useparameters: mapping for %s not impl.' % (mapping)) + for k, v in list(params.items()): + if k in param_map: + outmess('get_useparameters: overriding parameter %s with' + ' value from module %s' % (repr(k), repr(usename))) + param_map[k] = v + + return param_map + + +def postcrack2(block, tab='', param_map=None): + global f90modulevars + + if not f90modulevars: + return block + if isinstance(block, list): + ret = [postcrack2(g, tab=tab + '\t', param_map=param_map) + for g in block] + return ret + setmesstext(block) + outmess('%sBlock: %s\n' % (tab, block['name']), 0) + + if param_map is None: + param_map = get_useparameters(block) + + if param_map is not None and 'vars' in block: + vars = block['vars'] + for n in list(vars.keys()): + var = vars[n] + if 'kindselector' in var: + kind = var['kindselector'] + if 'kind' in kind: + val = kind['kind'] + if val in param_map: + kind['kind'] = param_map[val] + new_body = [postcrack2(b, tab=tab + '\t', param_map=param_map) + for b in block['body']] + block['body'] = new_body + + return block + + +def postcrack(block, args=None, tab=''): + """ + TODO: + function return values + determine expression types if in argument list + """ + global usermodules, onlyfunctions + + if isinstance(block, list): + gret = [] + uret = [] + for g in block: + setmesstext(g) + g = postcrack(g, tab=tab + '\t') + # sort user routines to appear first + if 'name' in g and '__user__' in g['name']: + uret.append(g) + else: + gret.append(g) + return uret + gret + setmesstext(block) + if not isinstance(block, dict) and 'block' not in block: + raise Exception('postcrack: Expected block dictionary instead of ' + + str(block)) + if 'name' in block and not block['name'] == 'unknown_interface': + outmess('%sBlock: %s\n' % (tab, block['name']), 0) + block = analyzeargs(block) + block = analyzecommon(block) + block['vars'] = analyzevars(block) + block['sortvars'] = sortvarnames(block['vars']) + if 'args' in block and block['args']: + args = block['args'] + block['body'] = analyzebody(block, args, tab=tab) + + userisdefined = [] + if 'use' in block: + useblock = block['use'] + for k in list(useblock.keys()): + if '__user__' in k: + userisdefined.append(k) + else: + useblock = {} + name = '' + if 'name' in block: + name = block['name'] + # and not userisdefined: # Build a __user__ module + if 'externals' in block and block['externals']: + interfaced = [] + if 'interfaced' in block: + interfaced = block['interfaced'] + mvars = copy.copy(block['vars']) + if name: + mname = name + '__user__routines' + else: + mname = 'unknown__user__routines' + if mname in userisdefined: + i = 1 + while '%s_%i' % (mname, i) in userisdefined: + i = i + 1 + mname = '%s_%i' % (mname, i) + interface = {'block': 'interface', 'body': [], + 'vars': {}, 'name': name + '_user_interface'} + for e in block['externals']: + if e in interfaced: + edef = [] + j = -1 + for b in block['body']: + j = j + 1 + if b['block'] == 'interface': + i = -1 + for bb in b['body']: + i = i + 1 + if 'name' in bb and bb['name'] == e: + edef = copy.copy(bb) + del b['body'][i] + break + if edef: + if not b['body']: + del block['body'][j] + del interfaced[interfaced.index(e)] + break + interface['body'].append(edef) + else: + if e in mvars and not isexternal(mvars[e]): + interface['vars'][e] = mvars[e] + if interface['vars'] or interface['body']: + block['interfaced'] = interfaced + mblock = {'block': 'python module', 'body': [ + interface], 'vars': {}, 'name': mname, 'interfaced': block['externals']} + useblock[mname] = {} + usermodules.append(mblock) + if useblock: + block['use'] = useblock + return block + + +def sortvarnames(vars): + indep = [] + dep = [] + for v in list(vars.keys()): + if 'depend' in vars[v] and vars[v]['depend']: + dep.append(v) + else: + indep.append(v) + n = len(dep) + i = 0 + while dep: # XXX: How to catch dependence cycles correctly? + v = dep[0] + fl = 0 + for w in dep[1:]: + if w in vars[v]['depend']: + fl = 1 + break + if fl: + dep = dep[1:] + [v] + i = i + 1 + if i > n: + errmess('sortvarnames: failed to compute dependencies because' + ' of cyclic dependencies between ' + + ', '.join(dep) + '\n') + indep = indep + dep + break + else: + indep.append(v) + dep = dep[1:] + n = len(dep) + i = 0 + return indep + + +def analyzecommon(block): + if not hascommon(block): + return block + commonvars = [] + for k in list(block['common'].keys()): + comvars = [] + for e in block['common'][k]: + m = re.match( + r'\A\s*\b(?P.*?)\b\s*(\((?P.*?)\)|)\s*\Z', e, re.I) + if m: + dims = [] + if m.group('dims'): + dims = [x.strip() + for x in markoutercomma(m.group('dims')).split('@,@')] + n = rmbadname1(m.group('name').strip()) + if n in block['vars']: + if 'attrspec' in block['vars'][n]: + block['vars'][n]['attrspec'].append( + 'dimension(%s)' % (','.join(dims))) + else: + block['vars'][n]['attrspec'] = [ + 'dimension(%s)' % (','.join(dims))] + else: + if dims: + block['vars'][n] = { + 'attrspec': ['dimension(%s)' % (','.join(dims))]} + else: + block['vars'][n] = {} + if n not in commonvars: + commonvars.append(n) + else: + n = e + errmess( + 'analyzecommon: failed to extract "[()]" from "%s" in common /%s/.\n' % (e, k)) + comvars.append(n) + block['common'][k] = comvars + if 'commonvars' not in block: + block['commonvars'] = commonvars + else: + block['commonvars'] = block['commonvars'] + commonvars + return block + + +def analyzebody(block, args, tab=''): + global usermodules, skipfuncs, onlyfuncs, f90modulevars + + setmesstext(block) + body = [] + for b in block['body']: + b['parent_block'] = block + if b['block'] in ['function', 'subroutine']: + if args is not None and b['name'] not in args: + continue + else: + as_ = b['args'] + if b['name'] in skipfuncs: + continue + if onlyfuncs and b['name'] not in onlyfuncs: + continue + b['saved_interface'] = crack2fortrangen( + b, '\n' + ' ' * 6, as_interface=True) + + else: + as_ = args + b = postcrack(b, as_, tab=tab + '\t') + if b['block'] == 'interface' and not b['body']: + if 'f2pyenhancements' not in b: + continue + if b['block'].replace(' ', '') == 'pythonmodule': + usermodules.append(b) + else: + if b['block'] == 'module': + f90modulevars[b['name']] = b['vars'] + body.append(b) + return body + + +def buildimplicitrules(block): + setmesstext(block) + implicitrules = defaultimplicitrules + attrrules = {} + if 'implicit' in block: + if block['implicit'] is None: + implicitrules = None + if verbose > 1: + outmess( + 'buildimplicitrules: no implicit rules for routine %s.\n' % repr(block['name'])) + else: + for k in list(block['implicit'].keys()): + if block['implicit'][k].get('typespec') not in ['static', 'automatic']: + implicitrules[k] = block['implicit'][k] + else: + attrrules[k] = block['implicit'][k]['typespec'] + return implicitrules, attrrules + + +def myeval(e, g=None, l=None): + """ Like `eval` but returns only integers and floats """ + r = eval(e, g, l) + if type(r) in [int, float]: + return r + raise ValueError('r=%r' % (r)) + +getlincoef_re_1 = re.compile(r'\A\b\w+\b\Z', re.I) + + +def getlincoef(e, xset): # e = a*x+b ; x in xset + """ + Obtain ``a`` and ``b`` when ``e == "a*x+b"``, where ``x`` is a symbol in + xset. + + >>> getlincoef('2*x + 1', {'x'}) + (2, 1, 'x') + >>> getlincoef('3*x + x*2 + 2 + 1', {'x'}) + (5, 3, 'x') + >>> getlincoef('0', {'x'}) + (0, 0, None) + >>> getlincoef('0*x', {'x'}) + (0, 0, 'x') + >>> getlincoef('x*x', {'x'}) + (None, None, None) + + This can be tricked by sufficiently complex expressions + + >>> getlincoef('(x - 0.5)*(x - 1.5)*(x - 1)*x + 2*x + 3', {'x'}) + (2.0, 3.0, 'x') + """ + try: + c = int(myeval(e, {}, {})) + return 0, c, None + except Exception: + pass + if getlincoef_re_1.match(e): + return 1, 0, e + len_e = len(e) + for x in xset: + if len(x) > len_e: + continue + if re.search(r'\w\s*\([^)]*\b' + x + r'\b', e): + # skip function calls having x as an argument, e.g max(1, x) + continue + re_1 = re.compile(r'(?P.*?)\b' + x + r'\b(?P.*)', re.I) + m = re_1.match(e) + if m: + try: + m1 = re_1.match(e) + while m1: + ee = '%s(%s)%s' % ( + m1.group('before'), 0, m1.group('after')) + m1 = re_1.match(ee) + b = myeval(ee, {}, {}) + m1 = re_1.match(e) + while m1: + ee = '%s(%s)%s' % ( + m1.group('before'), 1, m1.group('after')) + m1 = re_1.match(ee) + a = myeval(ee, {}, {}) - b + m1 = re_1.match(e) + while m1: + ee = '%s(%s)%s' % ( + m1.group('before'), 0.5, m1.group('after')) + m1 = re_1.match(ee) + c = myeval(ee, {}, {}) + # computing another point to be sure that expression is linear + m1 = re_1.match(e) + while m1: + ee = '%s(%s)%s' % ( + m1.group('before'), 1.5, m1.group('after')) + m1 = re_1.match(ee) + c2 = myeval(ee, {}, {}) + if (a * 0.5 + b == c and a * 1.5 + b == c2): + return a, b, x + except Exception: + pass + break + return None, None, None + +_varname_match = re.compile(r'\A[a-z]\w*\Z').match + + +def getarrlen(dl, args, star='*'): + """ + Parameters + ---------- + dl : sequence of two str objects + dimensions of the array + args : Iterable[str] + symbols used in the expression + star : Any + unused + + Returns + ------- + expr : str + Some numeric expression as a string + arg : Optional[str] + If understood, the argument from `args` present in `expr` + expr2 : Optional[str] + If understood, an expression fragment that should be used as + ``"(%s%s".format(something, expr2)``. + + Examples + -------- + >>> getarrlen(['10*x + 20', '40*x'], {'x'}) + ('30 * x - 19', 'x', '+19)/(30)') + >>> getarrlen(['1', '10*x + 20'], {'x'}) + ('10 * x + 20', 'x', '-20)/(10)') + >>> getarrlen(['10*x + 20', '1'], {'x'}) + ('-10 * x - 18', 'x', '+18)/(-10)') + >>> getarrlen(['20', '1'], {'x'}) + ('-18', None, None) + """ + edl = [] + try: + edl.append(myeval(dl[0], {}, {})) + except Exception: + edl.append(dl[0]) + try: + edl.append(myeval(dl[1], {}, {})) + except Exception: + edl.append(dl[1]) + if isinstance(edl[0], int): + p1 = 1 - edl[0] + if p1 == 0: + d = str(dl[1]) + elif p1 < 0: + d = '%s-%s' % (dl[1], -p1) + else: + d = '%s+%s' % (dl[1], p1) + elif isinstance(edl[1], int): + p1 = 1 + edl[1] + if p1 == 0: + d = '-(%s)' % (dl[0]) + else: + d = '%s-(%s)' % (p1, dl[0]) + else: + d = '%s-(%s)+1' % (dl[1], dl[0]) + try: + return repr(myeval(d, {}, {})), None, None + except Exception: + pass + d1, d2 = getlincoef(dl[0], args), getlincoef(dl[1], args) + if None not in [d1[0], d2[0]]: + if (d1[0], d2[0]) == (0, 0): + return repr(d2[1] - d1[1] + 1), None, None + b = d2[1] - d1[1] + 1 + d1 = (d1[0], 0, d1[2]) + d2 = (d2[0], b, d2[2]) + if d1[0] == 0 and d2[2] in args: + if b < 0: + return '%s * %s - %s' % (d2[0], d2[2], -b), d2[2], '+%s)/(%s)' % (-b, d2[0]) + elif b: + return '%s * %s + %s' % (d2[0], d2[2], b), d2[2], '-%s)/(%s)' % (b, d2[0]) + else: + return '%s * %s' % (d2[0], d2[2]), d2[2], ')/(%s)' % (d2[0]) + if d2[0] == 0 and d1[2] in args: + + if b < 0: + return '%s * %s - %s' % (-d1[0], d1[2], -b), d1[2], '+%s)/(%s)' % (-b, -d1[0]) + elif b: + return '%s * %s + %s' % (-d1[0], d1[2], b), d1[2], '-%s)/(%s)' % (b, -d1[0]) + else: + return '%s * %s' % (-d1[0], d1[2]), d1[2], ')/(%s)' % (-d1[0]) + if d1[2] == d2[2] and d1[2] in args: + a = d2[0] - d1[0] + if not a: + return repr(b), None, None + if b < 0: + return '%s * %s - %s' % (a, d1[2], -b), d2[2], '+%s)/(%s)' % (-b, a) + elif b: + return '%s * %s + %s' % (a, d1[2], b), d2[2], '-%s)/(%s)' % (b, a) + else: + return '%s * %s' % (a, d1[2]), d2[2], ')/(%s)' % (a) + if d1[0] == d2[0] == 1: + c = str(d1[2]) + if c not in args: + if _varname_match(c): + outmess('\tgetarrlen:variable "%s" undefined\n' % (c)) + c = '(%s)' % c + if b == 0: + d = '%s-%s' % (d2[2], c) + elif b < 0: + d = '%s-%s-%s' % (d2[2], c, -b) + else: + d = '%s-%s+%s' % (d2[2], c, b) + elif d1[0] == 0: + c2 = str(d2[2]) + if c2 not in args: + if _varname_match(c2): + outmess('\tgetarrlen:variable "%s" undefined\n' % (c2)) + c2 = '(%s)' % c2 + if d2[0] == 1: + pass + elif d2[0] == -1: + c2 = '-%s' % c2 + else: + c2 = '%s*%s' % (d2[0], c2) + + if b == 0: + d = c2 + elif b < 0: + d = '%s-%s' % (c2, -b) + else: + d = '%s+%s' % (c2, b) + elif d2[0] == 0: + c1 = str(d1[2]) + if c1 not in args: + if _varname_match(c1): + outmess('\tgetarrlen:variable "%s" undefined\n' % (c1)) + c1 = '(%s)' % c1 + if d1[0] == 1: + c1 = '-%s' % c1 + elif d1[0] == -1: + c1 = '+%s' % c1 + elif d1[0] < 0: + c1 = '+%s*%s' % (-d1[0], c1) + else: + c1 = '-%s*%s' % (d1[0], c1) + + if b == 0: + d = c1 + elif b < 0: + d = '%s-%s' % (c1, -b) + else: + d = '%s+%s' % (c1, b) + else: + c1 = str(d1[2]) + if c1 not in args: + if _varname_match(c1): + outmess('\tgetarrlen:variable "%s" undefined\n' % (c1)) + c1 = '(%s)' % c1 + if d1[0] == 1: + c1 = '-%s' % c1 + elif d1[0] == -1: + c1 = '+%s' % c1 + elif d1[0] < 0: + c1 = '+%s*%s' % (-d1[0], c1) + else: + c1 = '-%s*%s' % (d1[0], c1) + + c2 = str(d2[2]) + if c2 not in args: + if _varname_match(c2): + outmess('\tgetarrlen:variable "%s" undefined\n' % (c2)) + c2 = '(%s)' % c2 + if d2[0] == 1: + pass + elif d2[0] == -1: + c2 = '-%s' % c2 + else: + c2 = '%s*%s' % (d2[0], c2) + + if b == 0: + d = '%s%s' % (c2, c1) + elif b < 0: + d = '%s%s-%s' % (c2, c1, -b) + else: + d = '%s%s+%s' % (c2, c1, b) + return d, None, None + +word_pattern = re.compile(r'\b[a-z][\w$]*\b', re.I) + + +def _get_depend_dict(name, vars, deps): + if name in vars: + words = vars[name].get('depend', []) + + if '=' in vars[name] and not isstring(vars[name]): + for word in word_pattern.findall(vars[name]['=']): + if word not in words and word in vars: + words.append(word) + for word in words[:]: + for w in deps.get(word, []) \ + or _get_depend_dict(word, vars, deps): + if w not in words: + words.append(w) + else: + outmess('_get_depend_dict: no dependence info for %s\n' % (repr(name))) + words = [] + deps[name] = words + return words + + +def _calc_depend_dict(vars): + names = list(vars.keys()) + depend_dict = {} + for n in names: + _get_depend_dict(n, vars, depend_dict) + return depend_dict + + +def get_sorted_names(vars): + """ + """ + depend_dict = _calc_depend_dict(vars) + names = [] + for name in list(depend_dict.keys()): + if not depend_dict[name]: + names.append(name) + del depend_dict[name] + while depend_dict: + for name, lst in list(depend_dict.items()): + new_lst = [n for n in lst if n in depend_dict] + if not new_lst: + names.append(name) + del depend_dict[name] + else: + depend_dict[name] = new_lst + return [name for name in names if name in vars] + + +def _kind_func(string): + # XXX: return something sensible. + if string[0] in "'\"": + string = string[1:-1] + if real16pattern.match(string): + return 8 + elif real8pattern.match(string): + return 4 + return 'kind(' + string + ')' + + +def _selected_int_kind_func(r): + # XXX: This should be processor dependent + m = 10 ** r + if m <= 2 ** 8: + return 1 + if m <= 2 ** 16: + return 2 + if m <= 2 ** 32: + return 4 + if m <= 2 ** 63: + return 8 + if m <= 2 ** 128: + return 16 + return -1 + + +def _selected_real_kind_func(p, r=0, radix=0): + # XXX: This should be processor dependent + # This is only good for 0 <= p <= 20 + if p < 7: + return 4 + if p < 16: + return 8 + machine = platform.machine().lower() + if machine.startswith(('aarch64', 'power', 'ppc', 'riscv', 's390x', 'sparc')): + if p <= 20: + return 16 + else: + if p < 19: + return 10 + elif p <= 20: + return 16 + return -1 + + +def get_parameters(vars, global_params={}): + params = copy.copy(global_params) + g_params = copy.copy(global_params) + for name, func in [('kind', _kind_func), + ('selected_int_kind', _selected_int_kind_func), + ('selected_real_kind', _selected_real_kind_func), ]: + if name not in g_params: + g_params[name] = func + param_names = [] + for n in get_sorted_names(vars): + if 'attrspec' in vars[n] and 'parameter' in vars[n]['attrspec']: + param_names.append(n) + kind_re = re.compile(r'\bkind\s*\(\s*(?P.*)\s*\)', re.I) + selected_int_kind_re = re.compile( + r'\bselected_int_kind\s*\(\s*(?P.*)\s*\)', re.I) + selected_kind_re = re.compile( + r'\bselected_(int|real)_kind\s*\(\s*(?P.*)\s*\)', re.I) + for n in param_names: + if '=' in vars[n]: + v = vars[n]['='] + if islogical(vars[n]): + v = v.lower() + for repl in [ + ('.false.', 'False'), + ('.true.', 'True'), + # TODO: test .eq., .neq., etc replacements. + ]: + v = v.replace(*repl) + v = kind_re.sub(r'kind("\1")', v) + v = selected_int_kind_re.sub(r'selected_int_kind(\1)', v) + + # We need to act according to the data. + # The easy case is if the data has a kind-specifier, + # then we may easily remove those specifiers. + # However, it may be that the user uses other specifiers...(!) + is_replaced = False + if 'kindselector' in vars[n]: + if 'kind' in vars[n]['kindselector']: + orig_v_len = len(v) + v = v.replace('_' + vars[n]['kindselector']['kind'], '') + # Again, this will be true if even a single specifier + # has been replaced, see comment above. + is_replaced = len(v) < orig_v_len + + if not is_replaced: + if not selected_kind_re.match(v): + v_ = v.split('_') + # In case there are additive parameters + if len(v_) > 1: + v = ''.join(v_[:-1]).lower().replace(v_[-1].lower(), '') + + # Currently this will not work for complex numbers. + # There is missing code for extracting a complex number, + # which may be defined in either of these: + # a) (Re, Im) + # b) cmplx(Re, Im) + # c) dcmplx(Re, Im) + # d) cmplx(Re, Im, ) + + if isdouble(vars[n]): + tt = list(v) + for m in real16pattern.finditer(v): + tt[m.start():m.end()] = list( + v[m.start():m.end()].lower().replace('d', 'e')) + v = ''.join(tt) + + elif iscomplex(vars[n]): + # FIXME complex numbers may also have exponents + if v[0] == '(' and v[-1] == ')': + # FIXME, unused l looks like potential bug + l = markoutercomma(v[1:-1]).split('@,@') + + try: + params[n] = eval(v, g_params, params) + except Exception as msg: + params[n] = v + outmess('get_parameters: got "%s" on %s\n' % (msg, repr(v))) + if isstring(vars[n]) and isinstance(params[n], int): + params[n] = chr(params[n]) + nl = n.lower() + if nl != n: + params[nl] = params[n] + else: + print(vars[n]) + outmess( + 'get_parameters:parameter %s does not have value?!\n' % (repr(n))) + return params + + +def _eval_length(length, params): + if length in ['(:)', '(*)', '*']: + return '(*)' + return _eval_scalar(length, params) + +_is_kind_number = re.compile(r'\d+_').match + + +def _eval_scalar(value, params): + if _is_kind_number(value): + value = value.split('_')[0] + try: + value = str(eval(value, {}, params)) + except (NameError, SyntaxError, TypeError): + return value + except Exception as msg: + errmess('"%s" in evaluating %r ' + '(available names: %s)\n' + % (msg, value, list(params.keys()))) + return value + + +def analyzevars(block): + global f90modulevars + + setmesstext(block) + implicitrules, attrrules = buildimplicitrules(block) + vars = copy.copy(block['vars']) + if block['block'] == 'function' and block['name'] not in vars: + vars[block['name']] = {} + if '' in block['vars']: + del vars[''] + if 'attrspec' in block['vars']['']: + gen = block['vars']['']['attrspec'] + for n in list(vars.keys()): + for k in ['public', 'private']: + if k in gen: + vars[n] = setattrspec(vars[n], k) + svars = [] + args = block['args'] + for a in args: + try: + vars[a] + svars.append(a) + except KeyError: + pass + for n in list(vars.keys()): + if n not in args: + svars.append(n) + + params = get_parameters(vars, get_useparameters(block)) + + dep_matches = {} + name_match = re.compile(r'[A-Za-z][\w$]*').match + for v in list(vars.keys()): + m = name_match(v) + if m: + n = v[m.start():m.end()] + try: + dep_matches[n] + except KeyError: + dep_matches[n] = re.compile(r'.*\b%s\b' % (v), re.I).match + for n in svars: + if n[0] in list(attrrules.keys()): + vars[n] = setattrspec(vars[n], attrrules[n[0]]) + if 'typespec' not in vars[n]: + if not('attrspec' in vars[n] and 'external' in vars[n]['attrspec']): + if implicitrules: + ln0 = n[0].lower() + for k in list(implicitrules[ln0].keys()): + if k == 'typespec' and implicitrules[ln0][k] == 'undefined': + continue + if k not in vars[n]: + vars[n][k] = implicitrules[ln0][k] + elif k == 'attrspec': + for l in implicitrules[ln0][k]: + vars[n] = setattrspec(vars[n], l) + elif n in block['args']: + outmess('analyzevars: typespec of variable %s is not defined in routine %s.\n' % ( + repr(n), block['name'])) + + if 'charselector' in vars[n]: + if 'len' in vars[n]['charselector']: + l = vars[n]['charselector']['len'] + try: + l = str(eval(l, {}, params)) + except Exception: + pass + vars[n]['charselector']['len'] = l + + if 'kindselector' in vars[n]: + if 'kind' in vars[n]['kindselector']: + l = vars[n]['kindselector']['kind'] + try: + l = str(eval(l, {}, params)) + except Exception: + pass + vars[n]['kindselector']['kind'] = l + + savelindims = {} + if 'attrspec' in vars[n]: + attr = vars[n]['attrspec'] + attr.reverse() + vars[n]['attrspec'] = [] + dim, intent, depend, check, note = None, None, None, None, None + for a in attr: + if a[:9] == 'dimension': + dim = (a[9:].strip())[1:-1] + elif a[:6] == 'intent': + intent = (a[6:].strip())[1:-1] + elif a[:6] == 'depend': + depend = (a[6:].strip())[1:-1] + elif a[:5] == 'check': + check = (a[5:].strip())[1:-1] + elif a[:4] == 'note': + note = (a[4:].strip())[1:-1] + else: + vars[n] = setattrspec(vars[n], a) + if intent: + if 'intent' not in vars[n]: + vars[n]['intent'] = [] + for c in [x.strip() for x in markoutercomma(intent).split('@,@')]: + # Remove spaces so that 'in out' becomes 'inout' + tmp = c.replace(' ', '') + if tmp not in vars[n]['intent']: + vars[n]['intent'].append(tmp) + intent = None + if note: + note = note.replace('\\n\\n', '\n\n') + note = note.replace('\\n ', '\n') + if 'note' not in vars[n]: + vars[n]['note'] = [note] + else: + vars[n]['note'].append(note) + note = None + if depend is not None: + if 'depend' not in vars[n]: + vars[n]['depend'] = [] + for c in rmbadname([x.strip() for x in markoutercomma(depend).split('@,@')]): + if c not in vars[n]['depend']: + vars[n]['depend'].append(c) + depend = None + if check is not None: + if 'check' not in vars[n]: + vars[n]['check'] = [] + for c in [x.strip() for x in markoutercomma(check).split('@,@')]: + if c not in vars[n]['check']: + vars[n]['check'].append(c) + check = None + if dim and 'dimension' not in vars[n]: + vars[n]['dimension'] = [] + for d in rmbadname([x.strip() for x in markoutercomma(dim).split('@,@')]): + star = '*' + if d == ':': + star = ':' + if d in params: + d = str(params[d]) + for p in list(params.keys()): + re_1 = re.compile(r'(?P.*?)\b' + p + r'\b(?P.*)', re.I) + m = re_1.match(d) + while m: + d = m.group('before') + \ + str(params[p]) + m.group('after') + m = re_1.match(d) + if d == star: + dl = [star] + else: + dl = markoutercomma(d, ':').split('@:@') + if len(dl) == 2 and '*' in dl: # e.g. dimension(5:*) + dl = ['*'] + d = '*' + if len(dl) == 1 and not dl[0] == star: + dl = ['1', dl[0]] + if len(dl) == 2: + d, v, di = getarrlen(dl, list(block['vars'].keys())) + if d[:4] == '1 * ': + d = d[4:] + if di and di[-4:] == '/(1)': + di = di[:-4] + if v: + savelindims[d] = v, di + vars[n]['dimension'].append(d) + if 'dimension' in vars[n]: + if isintent_c(vars[n]): + shape_macro = 'shape' + else: + shape_macro = 'shape' # 'fshape' + if isstringarray(vars[n]): + if 'charselector' in vars[n]: + d = vars[n]['charselector'] + if '*' in d: + d = d['*'] + errmess('analyzevars: character array "character*%s %s(%s)" is considered as "character %s(%s)"; "intent(c)" is forced.\n' + % (d, n, + ','.join(vars[n]['dimension']), + n, ','.join(vars[n]['dimension'] + [d]))) + vars[n]['dimension'].append(d) + del vars[n]['charselector'] + if 'intent' not in vars[n]: + vars[n]['intent'] = [] + if 'c' not in vars[n]['intent']: + vars[n]['intent'].append('c') + else: + errmess( + "analyzevars: charselector=%r unhandled." % (d)) + if 'check' not in vars[n] and 'args' in block and n in block['args']: + flag = 'depend' not in vars[n] + if flag: + vars[n]['depend'] = [] + vars[n]['check'] = [] + if 'dimension' in vars[n]: + #/----< no check + i = -1 + ni = len(vars[n]['dimension']) + for d in vars[n]['dimension']: + ddeps = [] # dependencies of 'd' + ad = '' + pd = '' + if d not in vars: + if d in savelindims: + pd, ad = '(', savelindims[d][1] + d = savelindims[d][0] + else: + for r in block['args']: + if r not in vars: + continue + if re.match(r'.*?\b' + r + r'\b', d, re.I): + ddeps.append(r) + if d in vars: + if 'attrspec' in vars[d]: + for aa in vars[d]['attrspec']: + if aa[:6] == 'depend': + ddeps += aa[6:].strip()[1:-1].split(',') + if 'depend' in vars[d]: + ddeps = ddeps + vars[d]['depend'] + i = i + 1 + if d in vars and ('depend' not in vars[d]) \ + and ('=' not in vars[d]) and (d not in vars[n]['depend']) \ + and l_or(isintent_in, isintent_inout, isintent_inplace)(vars[n]): + vars[d]['depend'] = [n] + if ni > 1: + vars[d]['='] = '%s%s(%s,%s)%s' % ( + pd, shape_macro, n, i, ad) + else: + vars[d]['='] = '%slen(%s)%s' % (pd, n, ad) + # /---< no check + if 1 and 'check' not in vars[d]: + if ni > 1: + vars[d]['check'] = ['%s%s(%s,%i)%s==%s' + % (pd, shape_macro, n, i, ad, d)] + else: + vars[d]['check'] = [ + '%slen(%s)%s>=%s' % (pd, n, ad, d)] + if 'attrspec' not in vars[d]: + vars[d]['attrspec'] = ['optional'] + if ('optional' not in vars[d]['attrspec']) and\ + ('required' not in vars[d]['attrspec']): + vars[d]['attrspec'].append('optional') + elif d not in ['*', ':']: + #/----< no check + if flag: + if d in vars: + if n not in ddeps: + vars[n]['depend'].append(d) + else: + vars[n]['depend'] = vars[n]['depend'] + ddeps + elif isstring(vars[n]): + length = '1' + if 'charselector' in vars[n]: + if '*' in vars[n]['charselector']: + length = _eval_length(vars[n]['charselector']['*'], + params) + vars[n]['charselector']['*'] = length + elif 'len' in vars[n]['charselector']: + length = _eval_length(vars[n]['charselector']['len'], + params) + del vars[n]['charselector']['len'] + vars[n]['charselector']['*'] = length + + if not vars[n]['check']: + del vars[n]['check'] + if flag and not vars[n]['depend']: + del vars[n]['depend'] + if '=' in vars[n]: + if 'attrspec' not in vars[n]: + vars[n]['attrspec'] = [] + if ('optional' not in vars[n]['attrspec']) and \ + ('required' not in vars[n]['attrspec']): + vars[n]['attrspec'].append('optional') + if 'depend' not in vars[n]: + vars[n]['depend'] = [] + for v, m in list(dep_matches.items()): + if m(vars[n]['=']): + vars[n]['depend'].append(v) + if not vars[n]['depend']: + del vars[n]['depend'] + if isscalar(vars[n]): + vars[n]['='] = _eval_scalar(vars[n]['='], params) + + for n in list(vars.keys()): + if n == block['name']: # n is block name + if 'note' in vars[n]: + block['note'] = vars[n]['note'] + if block['block'] == 'function': + if 'result' in block and block['result'] in vars: + vars[n] = appenddecl(vars[n], vars[block['result']]) + if 'prefix' in block: + pr = block['prefix'] + ispure = 0 + isrec = 1 + pr1 = pr.replace('pure', '') + ispure = (not pr == pr1) + pr = pr1.replace('recursive', '') + isrec = (not pr == pr1) + m = typespattern[0].match(pr) + if m: + typespec, selector, attr, edecl = cracktypespec0( + m.group('this'), m.group('after')) + kindselect, charselect, typename = cracktypespec( + typespec, selector) + vars[n]['typespec'] = typespec + if kindselect: + if 'kind' in kindselect: + try: + kindselect['kind'] = eval( + kindselect['kind'], {}, params) + except Exception: + pass + vars[n]['kindselector'] = kindselect + if charselect: + vars[n]['charselector'] = charselect + if typename: + vars[n]['typename'] = typename + if ispure: + vars[n] = setattrspec(vars[n], 'pure') + if isrec: + vars[n] = setattrspec(vars[n], 'recursive') + else: + outmess( + 'analyzevars: prefix (%s) were not used\n' % repr(block['prefix'])) + if not block['block'] in ['module', 'pythonmodule', 'python module', 'block data']: + if 'commonvars' in block: + neededvars = copy.copy(block['args'] + block['commonvars']) + else: + neededvars = copy.copy(block['args']) + for n in list(vars.keys()): + if l_or(isintent_callback, isintent_aux)(vars[n]): + neededvars.append(n) + if 'entry' in block: + neededvars.extend(list(block['entry'].keys())) + for k in list(block['entry'].keys()): + for n in block['entry'][k]: + if n not in neededvars: + neededvars.append(n) + if block['block'] == 'function': + if 'result' in block: + neededvars.append(block['result']) + else: + neededvars.append(block['name']) + if block['block'] in ['subroutine', 'function']: + name = block['name'] + if name in vars and 'intent' in vars[name]: + block['intent'] = vars[name]['intent'] + if block['block'] == 'type': + neededvars.extend(list(vars.keys())) + for n in list(vars.keys()): + if n not in neededvars: + del vars[n] + return vars + +analyzeargs_re_1 = re.compile(r'\A[a-z]+[\w$]*\Z', re.I) + + +def expr2name(a, block, args=[]): + orig_a = a + a_is_expr = not analyzeargs_re_1.match(a) + if a_is_expr: # `a` is an expression + implicitrules, attrrules = buildimplicitrules(block) + at = determineexprtype(a, block['vars'], implicitrules) + na = 'e_' + for c in a: + c = c.lower() + if c not in string.ascii_lowercase + string.digits: + c = '_' + na = na + c + if na[-1] == '_': + na = na + 'e' + else: + na = na + '_e' + a = na + while a in block['vars'] or a in block['args']: + a = a + 'r' + if a in args: + k = 1 + while a + str(k) in args: + k = k + 1 + a = a + str(k) + if a_is_expr: + block['vars'][a] = at + else: + if a not in block['vars']: + if orig_a in block['vars']: + block['vars'][a] = block['vars'][orig_a] + else: + block['vars'][a] = {} + if 'externals' in block and orig_a in block['externals'] + block['interfaced']: + block['vars'][a] = setattrspec(block['vars'][a], 'external') + return a + + +def analyzeargs(block): + setmesstext(block) + implicitrules, attrrules = buildimplicitrules(block) + if 'args' not in block: + block['args'] = [] + args = [] + for a in block['args']: + a = expr2name(a, block, args) + args.append(a) + block['args'] = args + if 'entry' in block: + for k, args1 in list(block['entry'].items()): + for a in args1: + if a not in block['vars']: + block['vars'][a] = {} + + for b in block['body']: + if b['name'] in args: + if 'externals' not in block: + block['externals'] = [] + if b['name'] not in block['externals']: + block['externals'].append(b['name']) + if 'result' in block and block['result'] not in block['vars']: + block['vars'][block['result']] = {} + return block + +determineexprtype_re_1 = re.compile(r'\A\(.+?,.+?\)\Z', re.I) +determineexprtype_re_2 = re.compile(r'\A[+-]?\d+(_(?P\w+)|)\Z', re.I) +determineexprtype_re_3 = re.compile( + r'\A[+-]?[\d.]+[-\d+de.]*(_(?P\w+)|)\Z', re.I) +determineexprtype_re_4 = re.compile(r'\A\(.*\)\Z', re.I) +determineexprtype_re_5 = re.compile(r'\A(?P\w+)\s*\(.*?\)\s*\Z', re.I) + + +def _ensure_exprdict(r): + if isinstance(r, int): + return {'typespec': 'integer'} + if isinstance(r, float): + return {'typespec': 'real'} + if isinstance(r, complex): + return {'typespec': 'complex'} + if isinstance(r, dict): + return r + raise AssertionError(repr(r)) + + +def determineexprtype(expr, vars, rules={}): + if expr in vars: + return _ensure_exprdict(vars[expr]) + expr = expr.strip() + if determineexprtype_re_1.match(expr): + return {'typespec': 'complex'} + m = determineexprtype_re_2.match(expr) + if m: + if 'name' in m.groupdict() and m.group('name'): + outmess( + 'determineexprtype: selected kind types not supported (%s)\n' % repr(expr)) + return {'typespec': 'integer'} + m = determineexprtype_re_3.match(expr) + if m: + if 'name' in m.groupdict() and m.group('name'): + outmess( + 'determineexprtype: selected kind types not supported (%s)\n' % repr(expr)) + return {'typespec': 'real'} + for op in ['+', '-', '*', '/']: + for e in [x.strip() for x in markoutercomma(expr, comma=op).split('@' + op + '@')]: + if e in vars: + return _ensure_exprdict(vars[e]) + t = {} + if determineexprtype_re_4.match(expr): # in parenthesis + t = determineexprtype(expr[1:-1], vars, rules) + else: + m = determineexprtype_re_5.match(expr) + if m: + rn = m.group('name') + t = determineexprtype(m.group('name'), vars, rules) + if t and 'attrspec' in t: + del t['attrspec'] + if not t: + if rn[0] in rules: + return _ensure_exprdict(rules[rn[0]]) + if expr[0] in '\'"': + return {'typespec': 'character', 'charselector': {'*': '*'}} + if not t: + outmess( + 'determineexprtype: could not determine expressions (%s) type.\n' % (repr(expr))) + return t + +###### + + +def crack2fortrangen(block, tab='\n', as_interface=False): + global skipfuncs, onlyfuncs + + setmesstext(block) + ret = '' + if isinstance(block, list): + for g in block: + if g and g['block'] in ['function', 'subroutine']: + if g['name'] in skipfuncs: + continue + if onlyfuncs and g['name'] not in onlyfuncs: + continue + ret = ret + crack2fortrangen(g, tab, as_interface=as_interface) + return ret + prefix = '' + name = '' + args = '' + blocktype = block['block'] + if blocktype == 'program': + return '' + argsl = [] + if 'name' in block: + name = block['name'] + if 'args' in block: + vars = block['vars'] + for a in block['args']: + a = expr2name(a, block, argsl) + if not isintent_callback(vars[a]): + argsl.append(a) + if block['block'] == 'function' or argsl: + args = '(%s)' % ','.join(argsl) + f2pyenhancements = '' + if 'f2pyenhancements' in block: + for k in list(block['f2pyenhancements'].keys()): + f2pyenhancements = '%s%s%s %s' % ( + f2pyenhancements, tab + tabchar, k, block['f2pyenhancements'][k]) + intent_lst = block.get('intent', [])[:] + if blocktype == 'function' and 'callback' in intent_lst: + intent_lst.remove('callback') + if intent_lst: + f2pyenhancements = '%s%sintent(%s) %s' %\ + (f2pyenhancements, tab + tabchar, + ','.join(intent_lst), name) + use = '' + if 'use' in block: + use = use2fortran(block['use'], tab + tabchar) + common = '' + if 'common' in block: + common = common2fortran(block['common'], tab + tabchar) + if name == 'unknown_interface': + name = '' + result = '' + if 'result' in block: + result = ' result (%s)' % block['result'] + if block['result'] not in argsl: + argsl.append(block['result']) + body = crack2fortrangen(block['body'], tab + tabchar, as_interface=as_interface) + vars = vars2fortran( + block, block['vars'], argsl, tab + tabchar, as_interface=as_interface) + mess = '' + if 'from' in block and not as_interface: + mess = '! in %s' % block['from'] + if 'entry' in block: + entry_stmts = '' + for k, i in list(block['entry'].items()): + entry_stmts = '%s%sentry %s(%s)' \ + % (entry_stmts, tab + tabchar, k, ','.join(i)) + body = body + entry_stmts + if blocktype == 'block data' and name == '_BLOCK_DATA_': + name = '' + ret = '%s%s%s %s%s%s %s%s%s%s%s%s%send %s %s' % ( + tab, prefix, blocktype, name, args, result, mess, f2pyenhancements, use, vars, common, body, tab, blocktype, name) + return ret + + +def common2fortran(common, tab=''): + ret = '' + for k in list(common.keys()): + if k == '_BLNK_': + ret = '%s%scommon %s' % (ret, tab, ','.join(common[k])) + else: + ret = '%s%scommon /%s/ %s' % (ret, tab, k, ','.join(common[k])) + return ret + + +def use2fortran(use, tab=''): + ret = '' + for m in list(use.keys()): + ret = '%s%suse %s,' % (ret, tab, m) + if use[m] == {}: + if ret and ret[-1] == ',': + ret = ret[:-1] + continue + if 'only' in use[m] and use[m]['only']: + ret = '%s only:' % (ret) + if 'map' in use[m] and use[m]['map']: + c = ' ' + for k in list(use[m]['map'].keys()): + if k == use[m]['map'][k]: + ret = '%s%s%s' % (ret, c, k) + c = ',' + else: + ret = '%s%s%s=>%s' % (ret, c, k, use[m]['map'][k]) + c = ',' + if ret and ret[-1] == ',': + ret = ret[:-1] + return ret + + +def true_intent_list(var): + lst = var['intent'] + ret = [] + for intent in lst: + try: + f = globals()['isintent_%s' % intent] + except KeyError: + pass + else: + if f(var): + ret.append(intent) + return ret + + +def vars2fortran(block, vars, args, tab='', as_interface=False): + """ + TODO: + public sub + ... + """ + setmesstext(block) + ret = '' + nout = [] + for a in args: + if a in block['vars']: + nout.append(a) + if 'commonvars' in block: + for a in block['commonvars']: + if a in vars: + if a not in nout: + nout.append(a) + else: + errmess( + 'vars2fortran: Confused?!: "%s" is not defined in vars.\n' % a) + if 'varnames' in block: + nout.extend(block['varnames']) + if not as_interface: + for a in list(vars.keys()): + if a not in nout: + nout.append(a) + for a in nout: + if 'depend' in vars[a]: + for d in vars[a]['depend']: + if d in vars and 'depend' in vars[d] and a in vars[d]['depend']: + errmess( + 'vars2fortran: Warning: cross-dependence between variables "%s" and "%s"\n' % (a, d)) + if 'externals' in block and a in block['externals']: + if isintent_callback(vars[a]): + ret = '%s%sintent(callback) %s' % (ret, tab, a) + ret = '%s%sexternal %s' % (ret, tab, a) + if isoptional(vars[a]): + ret = '%s%soptional %s' % (ret, tab, a) + if a in vars and 'typespec' not in vars[a]: + continue + cont = 1 + for b in block['body']: + if a == b['name'] and b['block'] == 'function': + cont = 0 + break + if cont: + continue + if a not in vars: + show(vars) + outmess('vars2fortran: No definition for argument "%s".\n' % a) + continue + if a == block['name']: + if block['block'] != 'function' or block.get('result'): + # 1) skip declaring a variable that name matches with + # subroutine name + # 2) skip declaring function when its type is + # declared via `result` construction + continue + if 'typespec' not in vars[a]: + if 'attrspec' in vars[a] and 'external' in vars[a]['attrspec']: + if a in args: + ret = '%s%sexternal %s' % (ret, tab, a) + continue + show(vars[a]) + outmess('vars2fortran: No typespec for argument "%s".\n' % a) + continue + vardef = vars[a]['typespec'] + if vardef == 'type' and 'typename' in vars[a]: + vardef = '%s(%s)' % (vardef, vars[a]['typename']) + selector = {} + if 'kindselector' in vars[a]: + selector = vars[a]['kindselector'] + elif 'charselector' in vars[a]: + selector = vars[a]['charselector'] + if '*' in selector: + if selector['*'] in ['*', ':']: + vardef = '%s*(%s)' % (vardef, selector['*']) + else: + vardef = '%s*%s' % (vardef, selector['*']) + else: + if 'len' in selector: + vardef = '%s(len=%s' % (vardef, selector['len']) + if 'kind' in selector: + vardef = '%s,kind=%s)' % (vardef, selector['kind']) + else: + vardef = '%s)' % (vardef) + elif 'kind' in selector: + vardef = '%s(kind=%s)' % (vardef, selector['kind']) + c = ' ' + if 'attrspec' in vars[a]: + attr = [l for l in vars[a]['attrspec'] + if l not in ['external']] + if attr: + vardef = '%s, %s' % (vardef, ','.join(attr)) + c = ',' + if 'dimension' in vars[a]: + vardef = '%s%sdimension(%s)' % ( + vardef, c, ','.join(vars[a]['dimension'])) + c = ',' + if 'intent' in vars[a]: + lst = true_intent_list(vars[a]) + if lst: + vardef = '%s%sintent(%s)' % (vardef, c, ','.join(lst)) + c = ',' + if 'check' in vars[a]: + vardef = '%s%scheck(%s)' % (vardef, c, ','.join(vars[a]['check'])) + c = ',' + if 'depend' in vars[a]: + vardef = '%s%sdepend(%s)' % ( + vardef, c, ','.join(vars[a]['depend'])) + c = ',' + if '=' in vars[a]: + v = vars[a]['='] + if vars[a]['typespec'] in ['complex', 'double complex']: + try: + v = eval(v) + v = '(%s,%s)' % (v.real, v.imag) + except Exception: + pass + vardef = '%s :: %s=%s' % (vardef, a, v) + else: + vardef = '%s :: %s' % (vardef, a) + ret = '%s%s%s' % (ret, tab, vardef) + return ret +###### + + +def crackfortran(files): + global usermodules + + outmess('Reading fortran codes...\n', 0) + readfortrancode(files, crackline) + outmess('Post-processing...\n', 0) + usermodules = [] + postlist = postcrack(grouplist[0]) + outmess('Post-processing (stage 2)...\n', 0) + postlist = postcrack2(postlist) + return usermodules + postlist + + +def crack2fortran(block): + global f2py_version + + pyf = crack2fortrangen(block) + '\n' + header = """! -*- f90 -*- +! Note: the context of this file is case sensitive. +""" + footer = """ +! This file was auto-generated with f2py (version:%s). +! See http://cens.ioc.ee/projects/f2py2e/ +""" % (f2py_version) + return header + pyf + footer + +if __name__ == "__main__": + files = [] + funcs = [] + f = 1 + f2 = 0 + f3 = 0 + showblocklist = 0 + for l in sys.argv[1:]: + if l == '': + pass + elif l[0] == ':': + f = 0 + elif l == '-quiet': + quiet = 1 + verbose = 0 + elif l == '-verbose': + verbose = 2 + quiet = 0 + elif l == '-fix': + if strictf77: + outmess( + 'Use option -f90 before -fix if Fortran 90 code is in fix form.\n', 0) + skipemptyends = 1 + sourcecodeform = 'fix' + elif l == '-skipemptyends': + skipemptyends = 1 + elif l == '--ignore-contains': + ignorecontains = 1 + elif l == '-f77': + strictf77 = 1 + sourcecodeform = 'fix' + elif l == '-f90': + strictf77 = 0 + sourcecodeform = 'free' + skipemptyends = 1 + elif l == '-h': + f2 = 1 + elif l == '-show': + showblocklist = 1 + elif l == '-m': + f3 = 1 + elif l[0] == '-': + errmess('Unknown option %s\n' % repr(l)) + elif f2: + f2 = 0 + pyffilename = l + elif f3: + f3 = 0 + f77modulename = l + elif f: + try: + open(l).close() + files.append(l) + except IOError as detail: + errmess('IOError: %s\n' % str(detail)) + else: + funcs.append(l) + if not strictf77 and f77modulename and not skipemptyends: + outmess("""\ + Warning: You have specified module name for non Fortran 77 code + that should not need one (expect if you are scanning F90 code + for non module blocks but then you should use flag -skipemptyends + and also be sure that the files do not contain programs without program statement). +""", 0) + + postlist = crackfortran(files) + if pyffilename: + outmess('Writing fortran code to file %s\n' % repr(pyffilename), 0) + pyf = crack2fortran(postlist) + with open(pyffilename, 'w') as f: + f.write(pyf) + if showblocklist: + show(postlist) diff --git a/venv/Lib/site-packages/numpy/f2py/diagnose.py b/venv/Lib/site-packages/numpy/f2py/diagnose.py new file mode 100644 index 0000000..21ee399 --- /dev/null +++ b/venv/Lib/site-packages/numpy/f2py/diagnose.py @@ -0,0 +1,154 @@ +#!/usr/bin/env python3 +import os +import sys +import tempfile + + +def run_command(cmd): + print('Running %r:' % (cmd)) + os.system(cmd) + print('------') + + +def run(): + _path = os.getcwd() + os.chdir(tempfile.gettempdir()) + print('------') + print('os.name=%r' % (os.name)) + print('------') + print('sys.platform=%r' % (sys.platform)) + print('------') + print('sys.version:') + print(sys.version) + print('------') + print('sys.prefix:') + print(sys.prefix) + print('------') + print('sys.path=%r' % (':'.join(sys.path))) + print('------') + + try: + import numpy + has_newnumpy = 1 + except ImportError: + print('Failed to import new numpy:', sys.exc_info()[1]) + has_newnumpy = 0 + + try: + from numpy.f2py import f2py2e + has_f2py2e = 1 + except ImportError: + print('Failed to import f2py2e:', sys.exc_info()[1]) + has_f2py2e = 0 + + try: + import numpy.distutils + has_numpy_distutils = 2 + except ImportError: + try: + import numpy_distutils + has_numpy_distutils = 1 + except ImportError: + print('Failed to import numpy_distutils:', sys.exc_info()[1]) + has_numpy_distutils = 0 + + if has_newnumpy: + try: + print('Found new numpy version %r in %s' % + (numpy.__version__, numpy.__file__)) + except Exception as msg: + print('error:', msg) + print('------') + + if has_f2py2e: + try: + print('Found f2py2e version %r in %s' % + (f2py2e.__version__.version, f2py2e.__file__)) + except Exception as msg: + print('error:', msg) + print('------') + + if has_numpy_distutils: + try: + if has_numpy_distutils == 2: + print('Found numpy.distutils version %r in %r' % ( + numpy.distutils.__version__, + numpy.distutils.__file__)) + else: + print('Found numpy_distutils version %r in %r' % ( + numpy_distutils.numpy_distutils_version.numpy_distutils_version, + numpy_distutils.__file__)) + print('------') + except Exception as msg: + print('error:', msg) + print('------') + try: + if has_numpy_distutils == 1: + print( + 'Importing numpy_distutils.command.build_flib ...', end=' ') + import numpy_distutils.command.build_flib as build_flib + print('ok') + print('------') + try: + print( + 'Checking availability of supported Fortran compilers:') + for compiler_class in build_flib.all_compilers: + compiler_class(verbose=1).is_available() + print('------') + except Exception as msg: + print('error:', msg) + print('------') + except Exception as msg: + print( + 'error:', msg, '(ignore it, build_flib is obsolute for numpy.distutils 0.2.2 and up)') + print('------') + try: + if has_numpy_distutils == 2: + print('Importing numpy.distutils.fcompiler ...', end=' ') + import numpy.distutils.fcompiler as fcompiler + else: + print('Importing numpy_distutils.fcompiler ...', end=' ') + import numpy_distutils.fcompiler as fcompiler + print('ok') + print('------') + try: + print('Checking availability of supported Fortran compilers:') + fcompiler.show_fcompilers() + print('------') + except Exception as msg: + print('error:', msg) + print('------') + except Exception as msg: + print('error:', msg) + print('------') + try: + if has_numpy_distutils == 2: + print('Importing numpy.distutils.cpuinfo ...', end=' ') + from numpy.distutils.cpuinfo import cpuinfo + print('ok') + print('------') + else: + try: + print( + 'Importing numpy_distutils.command.cpuinfo ...', end=' ') + from numpy_distutils.command.cpuinfo import cpuinfo + print('ok') + print('------') + except Exception as msg: + print('error:', msg, '(ignore it)') + print('Importing numpy_distutils.cpuinfo ...', end=' ') + from numpy_distutils.cpuinfo import cpuinfo + print('ok') + print('------') + cpu = cpuinfo() + print('CPU information:', end=' ') + for name in dir(cpuinfo): + if name[0] == '_' and name[1] != '_' and getattr(cpu, name[1:])(): + print(name[1:], end=' ') + print('------') + except Exception as msg: + print('error:', msg) + print('------') + os.chdir(_path) +if __name__ == "__main__": + run() diff --git a/venv/Lib/site-packages/numpy/f2py/f2py2e.py b/venv/Lib/site-packages/numpy/f2py/f2py2e.py new file mode 100644 index 0000000..a14f068 --- /dev/null +++ b/venv/Lib/site-packages/numpy/f2py/f2py2e.py @@ -0,0 +1,692 @@ +#!/usr/bin/env python3 +""" + +f2py2e - Fortran to Python C/API generator. 2nd Edition. + See __usage__ below. + +Copyright 1999--2011 Pearu Peterson all rights reserved, +Pearu Peterson +Permission to use, modify, and distribute this software is given under the +terms of the NumPy License. + +NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. +$Date: 2005/05/06 08:31:19 $ +Pearu Peterson + +""" +import sys +import os +import pprint +import re + +from . import crackfortran +from . import rules +from . import cb_rules +from . import auxfuncs +from . import cfuncs +from . import f90mod_rules +from . import __version__ +from . import capi_maps + +f2py_version = __version__.version +numpy_version = __version__.version +errmess = sys.stderr.write +# outmess=sys.stdout.write +show = pprint.pprint +outmess = auxfuncs.outmess + +__usage__ =\ +f"""Usage: + +1) To construct extension module sources: + + f2py [] [[[only:]||[skip:]] \\ + ] \\ + [: ...] + +2) To compile fortran files and build extension modules: + + f2py -c [, , ] + +3) To generate signature files: + + f2py -h ...< same options as in (1) > + +Description: This program generates a Python C/API file (module.c) + that contains wrappers for given fortran functions so that they + can be called from Python. With the -c option the corresponding + extension modules are built. + +Options: + + --2d-numpy Use numpy.f2py tool with NumPy support. [DEFAULT] + --2d-numeric Use f2py2e tool with Numeric support. + --2d-numarray Use f2py2e tool with Numarray support. + --g3-numpy Use 3rd generation f2py from the separate f2py package. + [NOT AVAILABLE YET] + + -h Write signatures of the fortran routines to file + and exit. You can then edit and use it instead + of . If ==stdout then the + signatures are printed to stdout. + Names of fortran routines for which Python C/API + functions will be generated. Default is all that are found + in . + Paths to fortran/signature files that will be scanned for + in order to determine their signatures. + skip: Ignore fortran functions that follow until `:'. + only: Use only fortran functions that follow until `:'. + : Get back to mode. + + -m Name of the module; f2py generates a Python/C API + file module.c or extension module . + Default is 'untitled'. + + --[no-]lower Do [not] lower the cases in . By default, + --lower is assumed with -h key, and --no-lower without -h key. + + --build-dir All f2py generated files are created in . + Default is tempfile.mkdtemp(). + + --overwrite-signature Overwrite existing signature file. + + --[no-]latex-doc Create (or not) module.tex. + Default is --no-latex-doc. + --short-latex Create 'incomplete' LaTeX document (without commands + \\documentclass, \\tableofcontents, and \\begin{{document}}, + \\end{{document}}). + + --[no-]rest-doc Create (or not) module.rst. + Default is --no-rest-doc. + + --debug-capi Create C/API code that reports the state of the wrappers + during runtime. Useful for debugging. + + --[no-]wrap-functions Create Fortran subroutine wrappers to Fortran 77 + functions. --wrap-functions is default because it ensures + maximum portability/compiler independence. + + --include-paths ::... Search include files from the given + directories. + + --help-link [..] List system resources found by system_info.py. See also + --link- switch below. [..] is optional list + of resources names. E.g. try 'f2py --help-link lapack_opt'. + + --f2cmap Load Fortran-to-Python KIND specification from the given + file. Default: .f2py_f2cmap in current directory. + + --quiet Run quietly. + --verbose Run with extra verbosity. + -v Print f2py version ID and exit. + + +numpy.distutils options (only effective with -c): + + --fcompiler= Specify Fortran compiler type by vendor + --compiler= Specify C compiler type (as defined by distutils) + + --help-fcompiler List available Fortran compilers and exit + --f77exec= Specify the path to F77 compiler + --f90exec= Specify the path to F90 compiler + --f77flags= Specify F77 compiler flags + --f90flags= Specify F90 compiler flags + --opt= Specify optimization flags + --arch= Specify architecture specific optimization flags + --noopt Compile without optimization + --noarch Compile without arch-dependent optimization + --debug Compile with debugging information + +Extra options (only effective with -c): + + --link- Link extension module with as defined + by numpy.distutils/system_info.py. E.g. to link + with optimized LAPACK libraries (vecLib on MacOSX, + ATLAS elsewhere), use --link-lapack_opt. + See also --help-link switch. + + -L/path/to/lib/ -l + -D -U + -I/path/to/include/ + .o .so .a + + Using the following macros may be required with non-gcc Fortran + compilers: + -DPREPEND_FORTRAN -DNO_APPEND_FORTRAN -DUPPERCASE_FORTRAN + -DUNDERSCORE_G77 + + When using -DF2PY_REPORT_ATEXIT, a performance report of F2PY + interface is printed out at exit (platforms: Linux). + + When using -DF2PY_REPORT_ON_ARRAY_COPY=, a message is + sent to stderr whenever F2PY interface makes a copy of an + array. Integer sets the threshold for array sizes when + a message should be shown. + +Version: {f2py_version} +numpy Version: {numpy_version} +Requires: Python 3.5 or higher. +License: NumPy license (see LICENSE.txt in the NumPy source code) +Copyright 1999 - 2011 Pearu Peterson all rights reserved. +http://cens.ioc.ee/projects/f2py2e/""" + + +def scaninputline(inputline): + files, skipfuncs, onlyfuncs, debug = [], [], [], [] + f, f2, f3, f5, f6, f7, f8, f9, f10 = 1, 0, 0, 0, 0, 0, 0, 0, 0 + verbose = 1 + dolc = -1 + dolatexdoc = 0 + dorestdoc = 0 + wrapfuncs = 1 + buildpath = '.' + include_paths = [] + signsfile, modulename = None, None + options = {'buildpath': buildpath, + 'coutput': None, + 'f2py_wrapper_output': None} + for l in inputline: + if l == '': + pass + elif l == 'only:': + f = 0 + elif l == 'skip:': + f = -1 + elif l == ':': + f = 1 + elif l[:8] == '--debug-': + debug.append(l[8:]) + elif l == '--lower': + dolc = 1 + elif l == '--build-dir': + f6 = 1 + elif l == '--no-lower': + dolc = 0 + elif l == '--quiet': + verbose = 0 + elif l == '--verbose': + verbose += 1 + elif l == '--latex-doc': + dolatexdoc = 1 + elif l == '--no-latex-doc': + dolatexdoc = 0 + elif l == '--rest-doc': + dorestdoc = 1 + elif l == '--no-rest-doc': + dorestdoc = 0 + elif l == '--wrap-functions': + wrapfuncs = 1 + elif l == '--no-wrap-functions': + wrapfuncs = 0 + elif l == '--short-latex': + options['shortlatex'] = 1 + elif l == '--coutput': + f8 = 1 + elif l == '--f2py-wrapper-output': + f9 = 1 + elif l == '--f2cmap': + f10 = 1 + elif l == '--overwrite-signature': + options['h-overwrite'] = 1 + elif l == '-h': + f2 = 1 + elif l == '-m': + f3 = 1 + elif l[:2] == '-v': + print(f2py_version) + sys.exit() + elif l == '--show-compilers': + f5 = 1 + elif l[:8] == '-include': + cfuncs.outneeds['userincludes'].append(l[9:-1]) + cfuncs.userincludes[l[9:-1]] = '#include ' + l[8:] + elif l[:15] in '--include_paths': + outmess( + 'f2py option --include_paths is deprecated, use --include-paths instead.\n') + f7 = 1 + elif l[:15] in '--include-paths': + f7 = 1 + elif l[0] == '-': + errmess('Unknown option %s\n' % repr(l)) + sys.exit() + elif f2: + f2 = 0 + signsfile = l + elif f3: + f3 = 0 + modulename = l + elif f6: + f6 = 0 + buildpath = l + elif f7: + f7 = 0 + include_paths.extend(l.split(os.pathsep)) + elif f8: + f8 = 0 + options["coutput"] = l + elif f9: + f9 = 0 + options["f2py_wrapper_output"] = l + elif f10: + f10 = 0 + options["f2cmap_file"] = l + elif f == 1: + try: + with open(l): + pass + files.append(l) + except IOError as detail: + errmess('IOError: %s. Skipping file "%s".\n' % + (str(detail), l)) + elif f == -1: + skipfuncs.append(l) + elif f == 0: + onlyfuncs.append(l) + if not f5 and not files and not modulename: + print(__usage__) + sys.exit() + if not os.path.isdir(buildpath): + if not verbose: + outmess('Creating build directory %s' % (buildpath)) + os.mkdir(buildpath) + if signsfile: + signsfile = os.path.join(buildpath, signsfile) + if signsfile and os.path.isfile(signsfile) and 'h-overwrite' not in options: + errmess( + 'Signature file "%s" exists!!! Use --overwrite-signature to overwrite.\n' % (signsfile)) + sys.exit() + + options['debug'] = debug + options['verbose'] = verbose + if dolc == -1 and not signsfile: + options['do-lower'] = 0 + else: + options['do-lower'] = dolc + if modulename: + options['module'] = modulename + if signsfile: + options['signsfile'] = signsfile + if onlyfuncs: + options['onlyfuncs'] = onlyfuncs + if skipfuncs: + options['skipfuncs'] = skipfuncs + options['dolatexdoc'] = dolatexdoc + options['dorestdoc'] = dorestdoc + options['wrapfuncs'] = wrapfuncs + options['buildpath'] = buildpath + options['include_paths'] = include_paths + options.setdefault('f2cmap_file', None) + return files, options + + +def callcrackfortran(files, options): + rules.options = options + crackfortran.debug = options['debug'] + crackfortran.verbose = options['verbose'] + if 'module' in options: + crackfortran.f77modulename = options['module'] + if 'skipfuncs' in options: + crackfortran.skipfuncs = options['skipfuncs'] + if 'onlyfuncs' in options: + crackfortran.onlyfuncs = options['onlyfuncs'] + crackfortran.include_paths[:] = options['include_paths'] + crackfortran.dolowercase = options['do-lower'] + postlist = crackfortran.crackfortran(files) + if 'signsfile' in options: + outmess('Saving signatures to file "%s"\n' % (options['signsfile'])) + pyf = crackfortran.crack2fortran(postlist) + if options['signsfile'][-6:] == 'stdout': + sys.stdout.write(pyf) + else: + with open(options['signsfile'], 'w') as f: + f.write(pyf) + if options["coutput"] is None: + for mod in postlist: + mod["coutput"] = "%smodule.c" % mod["name"] + else: + for mod in postlist: + mod["coutput"] = options["coutput"] + if options["f2py_wrapper_output"] is None: + for mod in postlist: + mod["f2py_wrapper_output"] = "%s-f2pywrappers.f" % mod["name"] + else: + for mod in postlist: + mod["f2py_wrapper_output"] = options["f2py_wrapper_output"] + return postlist + + +def buildmodules(lst): + cfuncs.buildcfuncs() + outmess('Building modules...\n') + modules, mnames, isusedby = [], [], {} + for i in range(len(lst)): + if '__user__' in lst[i]['name']: + cb_rules.buildcallbacks(lst[i]) + else: + if 'use' in lst[i]: + for u in lst[i]['use'].keys(): + if u not in isusedby: + isusedby[u] = [] + isusedby[u].append(lst[i]['name']) + modules.append(lst[i]) + mnames.append(lst[i]['name']) + ret = {} + for i in range(len(mnames)): + if mnames[i] in isusedby: + outmess('\tSkipping module "%s" which is used by %s.\n' % ( + mnames[i], ','.join(['"%s"' % s for s in isusedby[mnames[i]]]))) + else: + um = [] + if 'use' in modules[i]: + for u in modules[i]['use'].keys(): + if u in isusedby and u in mnames: + um.append(modules[mnames.index(u)]) + else: + outmess( + '\tModule "%s" uses nonexisting "%s" which will be ignored.\n' % (mnames[i], u)) + ret[mnames[i]] = {} + dict_append(ret[mnames[i]], rules.buildmodule(modules[i], um)) + return ret + + +def dict_append(d_out, d_in): + for (k, v) in d_in.items(): + if k not in d_out: + d_out[k] = [] + if isinstance(v, list): + d_out[k] = d_out[k] + v + else: + d_out[k].append(v) + + +def run_main(comline_list): + """ + Equivalent to running:: + + f2py + + where ``=string.join(,' ')``, but in Python. Unless + ``-h`` is used, this function returns a dictionary containing + information on generated modules and their dependencies on source + files. For example, the command ``f2py -m scalar scalar.f`` can be + executed from Python as follows + + You cannot build extension modules with this function, that is, + using ``-c`` is not allowed. Use ``compile`` command instead + + Examples + -------- + .. include:: run_main_session.dat + :literal: + + """ + crackfortran.reset_global_f2py_vars() + f2pydir = os.path.dirname(os.path.abspath(cfuncs.__file__)) + fobjhsrc = os.path.join(f2pydir, 'src', 'fortranobject.h') + fobjcsrc = os.path.join(f2pydir, 'src', 'fortranobject.c') + files, options = scaninputline(comline_list) + auxfuncs.options = options + capi_maps.load_f2cmap_file(options['f2cmap_file']) + postlist = callcrackfortran(files, options) + isusedby = {} + for i in range(len(postlist)): + if 'use' in postlist[i]: + for u in postlist[i]['use'].keys(): + if u not in isusedby: + isusedby[u] = [] + isusedby[u].append(postlist[i]['name']) + for i in range(len(postlist)): + if postlist[i]['block'] == 'python module' and '__user__' in postlist[i]['name']: + if postlist[i]['name'] in isusedby: + # if not quiet: + outmess('Skipping Makefile build for module "%s" which is used by %s\n' % ( + postlist[i]['name'], ','.join(['"%s"' % s for s in isusedby[postlist[i]['name']]]))) + if 'signsfile' in options: + if options['verbose'] > 1: + outmess( + 'Stopping. Edit the signature file and then run f2py on the signature file: ') + outmess('%s %s\n' % + (os.path.basename(sys.argv[0]), options['signsfile'])) + return + for i in range(len(postlist)): + if postlist[i]['block'] != 'python module': + if 'python module' not in options: + errmess( + 'Tip: If your original code is Fortran source then you must use -m option.\n') + raise TypeError('All blocks must be python module blocks but got %s' % ( + repr(postlist[i]['block']))) + auxfuncs.debugoptions = options['debug'] + f90mod_rules.options = options + auxfuncs.wrapfuncs = options['wrapfuncs'] + + ret = buildmodules(postlist) + + for mn in ret.keys(): + dict_append(ret[mn], {'csrc': fobjcsrc, 'h': fobjhsrc}) + return ret + + +def filter_files(prefix, suffix, files, remove_prefix=None): + """ + Filter files by prefix and suffix. + """ + filtered, rest = [], [] + match = re.compile(prefix + r'.*' + suffix + r'\Z').match + if remove_prefix: + ind = len(prefix) + else: + ind = 0 + for file in [x.strip() for x in files]: + if match(file): + filtered.append(file[ind:]) + else: + rest.append(file) + return filtered, rest + + +def get_prefix(module): + p = os.path.dirname(os.path.dirname(module.__file__)) + return p + + +def run_compile(): + """ + Do it all in one call! + """ + import tempfile + + i = sys.argv.index('-c') + del sys.argv[i] + + remove_build_dir = 0 + try: + i = sys.argv.index('--build-dir') + except ValueError: + i = None + if i is not None: + build_dir = sys.argv[i + 1] + del sys.argv[i + 1] + del sys.argv[i] + else: + remove_build_dir = 1 + build_dir = tempfile.mkdtemp() + + _reg1 = re.compile(r'--link-') + sysinfo_flags = [_m for _m in sys.argv[1:] if _reg1.match(_m)] + sys.argv = [_m for _m in sys.argv if _m not in sysinfo_flags] + if sysinfo_flags: + sysinfo_flags = [f[7:] for f in sysinfo_flags] + + _reg2 = re.compile( + r'--((no-|)(wrap-functions|lower)|debug-capi|quiet)|-include') + f2py_flags = [_m for _m in sys.argv[1:] if _reg2.match(_m)] + sys.argv = [_m for _m in sys.argv if _m not in f2py_flags] + f2py_flags2 = [] + fl = 0 + for a in sys.argv[1:]: + if a in ['only:', 'skip:']: + fl = 1 + elif a == ':': + fl = 0 + if fl or a == ':': + f2py_flags2.append(a) + if f2py_flags2 and f2py_flags2[-1] != ':': + f2py_flags2.append(':') + f2py_flags.extend(f2py_flags2) + + sys.argv = [_m for _m in sys.argv if _m not in f2py_flags2] + _reg3 = re.compile( + r'--((f(90)?compiler(-exec|)|compiler)=|help-compiler)') + flib_flags = [_m for _m in sys.argv[1:] if _reg3.match(_m)] + sys.argv = [_m for _m in sys.argv if _m not in flib_flags] + _reg4 = re.compile( + r'--((f(77|90)(flags|exec)|opt|arch)=|(debug|noopt|noarch|help-fcompiler))') + fc_flags = [_m for _m in sys.argv[1:] if _reg4.match(_m)] + sys.argv = [_m for _m in sys.argv if _m not in fc_flags] + + if 1: + del_list = [] + for s in flib_flags: + v = '--fcompiler=' + if s[:len(v)] == v: + from numpy.distutils import fcompiler + fcompiler.load_all_fcompiler_classes() + allowed_keys = list(fcompiler.fcompiler_class.keys()) + nv = ov = s[len(v):].lower() + if ov not in allowed_keys: + vmap = {} # XXX + try: + nv = vmap[ov] + except KeyError: + if ov not in vmap.values(): + print('Unknown vendor: "%s"' % (s[len(v):])) + nv = ov + i = flib_flags.index(s) + flib_flags[i] = '--fcompiler=' + nv + continue + for s in del_list: + i = flib_flags.index(s) + del flib_flags[i] + assert len(flib_flags) <= 2, repr(flib_flags) + + _reg5 = re.compile(r'--(verbose)') + setup_flags = [_m for _m in sys.argv[1:] if _reg5.match(_m)] + sys.argv = [_m for _m in sys.argv if _m not in setup_flags] + + if '--quiet' in f2py_flags: + setup_flags.append('--quiet') + + modulename = 'untitled' + sources = sys.argv[1:] + + for optname in ['--include_paths', '--include-paths', '--f2cmap']: + if optname in sys.argv: + i = sys.argv.index(optname) + f2py_flags.extend(sys.argv[i:i + 2]) + del sys.argv[i + 1], sys.argv[i] + sources = sys.argv[1:] + + if '-m' in sys.argv: + i = sys.argv.index('-m') + modulename = sys.argv[i + 1] + del sys.argv[i + 1], sys.argv[i] + sources = sys.argv[1:] + else: + from numpy.distutils.command.build_src import get_f2py_modulename + pyf_files, sources = filter_files('', '[.]pyf([.]src|)', sources) + sources = pyf_files + sources + for f in pyf_files: + modulename = get_f2py_modulename(f) + if modulename: + break + + extra_objects, sources = filter_files('', '[.](o|a|so|dylib)', sources) + include_dirs, sources = filter_files('-I', '', sources, remove_prefix=1) + library_dirs, sources = filter_files('-L', '', sources, remove_prefix=1) + libraries, sources = filter_files('-l', '', sources, remove_prefix=1) + undef_macros, sources = filter_files('-U', '', sources, remove_prefix=1) + define_macros, sources = filter_files('-D', '', sources, remove_prefix=1) + for i in range(len(define_macros)): + name_value = define_macros[i].split('=', 1) + if len(name_value) == 1: + name_value.append(None) + if len(name_value) == 2: + define_macros[i] = tuple(name_value) + else: + print('Invalid use of -D:', name_value) + + from numpy.distutils.system_info import get_info + + num_info = {} + if num_info: + include_dirs.extend(num_info.get('include_dirs', [])) + + from numpy.distutils.core import setup, Extension + ext_args = {'name': modulename, 'sources': sources, + 'include_dirs': include_dirs, + 'library_dirs': library_dirs, + 'libraries': libraries, + 'define_macros': define_macros, + 'undef_macros': undef_macros, + 'extra_objects': extra_objects, + 'f2py_options': f2py_flags, + } + + if sysinfo_flags: + from numpy.distutils.misc_util import dict_append + for n in sysinfo_flags: + i = get_info(n) + if not i: + outmess('No %s resources found in system' + ' (try `f2py --help-link`)\n' % (repr(n))) + dict_append(ext_args, **i) + + ext = Extension(**ext_args) + sys.argv = [sys.argv[0]] + setup_flags + sys.argv.extend(['build', + '--build-temp', build_dir, + '--build-base', build_dir, + '--build-platlib', '.', + # disable CCompilerOpt + '--disable-optimization']) + if fc_flags: + sys.argv.extend(['config_fc'] + fc_flags) + if flib_flags: + sys.argv.extend(['build_ext'] + flib_flags) + + setup(ext_modules=[ext]) + + if remove_build_dir and os.path.exists(build_dir): + import shutil + outmess('Removing build directory %s\n' % (build_dir)) + shutil.rmtree(build_dir) + + +def main(): + if '--help-link' in sys.argv[1:]: + sys.argv.remove('--help-link') + from numpy.distutils.system_info import show_all + show_all() + return + + # Probably outdated options that were not working before 1.16 + if '--g3-numpy' in sys.argv[1:]: + sys.stderr.write("G3 f2py support is not implemented, yet.\\n") + sys.exit(1) + elif '--2e-numeric' in sys.argv[1:]: + sys.argv.remove('--2e-numeric') + elif '--2e-numarray' in sys.argv[1:]: + # Note that this errors becaust the -DNUMARRAY argument is + # not recognized. Just here for back compatibility and the + # error message. + sys.argv.append("-DNUMARRAY") + sys.argv.remove('--2e-numarray') + elif '--2e-numpy' in sys.argv[1:]: + sys.argv.remove('--2e-numpy') + else: + pass + + if '-c' in sys.argv[1:]: + run_compile() + else: + run_main(sys.argv[1:]) diff --git a/venv/Lib/site-packages/numpy/f2py/f2py_testing.py b/venv/Lib/site-packages/numpy/f2py/f2py_testing.py new file mode 100644 index 0000000..1f109e6 --- /dev/null +++ b/venv/Lib/site-packages/numpy/f2py/f2py_testing.py @@ -0,0 +1,46 @@ +import sys +import re + +from numpy.testing import jiffies, memusage + + +def cmdline(): + m = re.compile(r'\A\d+\Z') + args = [] + repeat = 1 + for a in sys.argv[1:]: + if m.match(a): + repeat = eval(a) + else: + args.append(a) + f2py_opts = ' '.join(args) + return repeat, f2py_opts + + +def run(runtest, test_functions, repeat=1): + l = [(t, repr(t.__doc__.split('\n')[1].strip())) for t in test_functions] + start_memusage = memusage() + diff_memusage = None + start_jiffies = jiffies() + i = 0 + while i < repeat: + i += 1 + for t, fname in l: + runtest(t) + if start_memusage is None: + continue + if diff_memusage is None: + diff_memusage = memusage() - start_memusage + else: + diff_memusage2 = memusage() - start_memusage + if diff_memusage2 != diff_memusage: + print('memory usage change at step %i:' % i, + diff_memusage2 - diff_memusage, + fname) + diff_memusage = diff_memusage2 + current_memusage = memusage() + print('run', repeat * len(test_functions), 'tests', + 'in %.2f seconds' % ((jiffies() - start_jiffies) / 100.0)) + if start_memusage: + print('initial virtual memory size:', start_memusage, 'bytes') + print('current virtual memory size:', current_memusage, 'bytes') diff --git a/venv/Lib/site-packages/numpy/f2py/f90mod_rules.py b/venv/Lib/site-packages/numpy/f2py/f90mod_rules.py new file mode 100644 index 0000000..122fa89 --- /dev/null +++ b/venv/Lib/site-packages/numpy/f2py/f90mod_rules.py @@ -0,0 +1,269 @@ +#!/usr/bin/env python3 +""" + +Build F90 module support for f2py2e. + +Copyright 2000 Pearu Peterson all rights reserved, +Pearu Peterson +Permission to use, modify, and distribute this software is given under the +terms of the NumPy License. + +NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. +$Date: 2005/02/03 19:30:23 $ +Pearu Peterson + +""" +__version__ = "$Revision: 1.27 $"[10:-1] + +f2py_version = 'See `f2py -v`' + +import numpy as np + +from . import capi_maps +from . import func2subr +from .crackfortran import undo_rmbadname, undo_rmbadname1 + +# The environment provided by auxfuncs.py is needed for some calls to eval. +# As the needed functions cannot be determined by static inspection of the +# code, it is safest to use import * pending a major refactoring of f2py. +from .auxfuncs import * + +options = {} + + +def findf90modules(m): + if ismodule(m): + return [m] + if not hasbody(m): + return [] + ret = [] + for b in m['body']: + if ismodule(b): + ret.append(b) + else: + ret = ret + findf90modules(b) + return ret + +fgetdims1 = """\ + external f2pysetdata + logical ns + integer r,i + integer(%d) s(*) + ns = .FALSE. + if (allocated(d)) then + do i=1,r + if ((size(d,i).ne.s(i)).and.(s(i).ge.0)) then + ns = .TRUE. + end if + end do + if (ns) then + deallocate(d) + end if + end if + if ((.not.allocated(d)).and.(s(1).ge.1)) then""" % np.intp().itemsize + +fgetdims2 = """\ + end if + if (allocated(d)) then + do i=1,r + s(i) = size(d,i) + end do + end if + flag = 1 + call f2pysetdata(d,allocated(d))""" + +fgetdims2_sa = """\ + end if + if (allocated(d)) then + do i=1,r + s(i) = size(d,i) + end do + !s(r) must be equal to len(d(1)) + end if + flag = 2 + call f2pysetdata(d,allocated(d))""" + + +def buildhooks(pymod): + from . import rules + ret = {'f90modhooks': [], 'initf90modhooks': [], 'body': [], + 'need': ['F_FUNC', 'arrayobject.h'], + 'separatorsfor': {'includes0': '\n', 'includes': '\n'}, + 'docs': ['"Fortran 90/95 modules:\\n"'], + 'latexdoc': []} + fhooks = [''] + + def fadd(line, s=fhooks): + s[0] = '%s\n %s' % (s[0], line) + doc = [''] + + def dadd(line, s=doc): + s[0] = '%s\n%s' % (s[0], line) + for m in findf90modules(pymod): + sargs, fargs, efargs, modobjs, notvars, onlyvars = [], [], [], [], [ + m['name']], [] + sargsp = [] + ifargs = [] + mfargs = [] + if hasbody(m): + for b in m['body']: + notvars.append(b['name']) + for n in m['vars'].keys(): + var = m['vars'][n] + if (n not in notvars) and (not l_or(isintent_hide, isprivate)(var)): + onlyvars.append(n) + mfargs.append(n) + outmess('\t\tConstructing F90 module support for "%s"...\n' % + (m['name'])) + if onlyvars: + outmess('\t\t Variables: %s\n' % (' '.join(onlyvars))) + chooks = [''] + + def cadd(line, s=chooks): + s[0] = '%s\n%s' % (s[0], line) + ihooks = [''] + + def iadd(line, s=ihooks): + s[0] = '%s\n%s' % (s[0], line) + + vrd = capi_maps.modsign2map(m) + cadd('static FortranDataDef f2py_%s_def[] = {' % (m['name'])) + dadd('\\subsection{Fortran 90/95 module \\texttt{%s}}\n' % (m['name'])) + if hasnote(m): + note = m['note'] + if isinstance(note, list): + note = '\n'.join(note) + dadd(note) + if onlyvars: + dadd('\\begin{description}') + for n in onlyvars: + var = m['vars'][n] + modobjs.append(n) + ct = capi_maps.getctype(var) + at = capi_maps.c2capi_map[ct] + dm = capi_maps.getarrdims(n, var) + dms = dm['dims'].replace('*', '-1').strip() + dms = dms.replace(':', '-1').strip() + if not dms: + dms = '-1' + use_fgetdims2 = fgetdims2 + if isstringarray(var): + if 'charselector' in var and 'len' in var['charselector']: + cadd('\t{"%s",%s,{{%s,%s}},%s},' + % (undo_rmbadname1(n), dm['rank'], dms, var['charselector']['len'], at)) + use_fgetdims2 = fgetdims2_sa + else: + cadd('\t{"%s",%s,{{%s}},%s},' % + (undo_rmbadname1(n), dm['rank'], dms, at)) + else: + cadd('\t{"%s",%s,{{%s}},%s},' % + (undo_rmbadname1(n), dm['rank'], dms, at)) + dadd('\\item[]{{}\\verb@%s@{}}' % + (capi_maps.getarrdocsign(n, var))) + if hasnote(var): + note = var['note'] + if isinstance(note, list): + note = '\n'.join(note) + dadd('--- %s' % (note)) + if isallocatable(var): + fargs.append('f2py_%s_getdims_%s' % (m['name'], n)) + efargs.append(fargs[-1]) + sargs.append( + 'void (*%s)(int*,int*,void(*)(char*,int*),int*)' % (n)) + sargsp.append('void (*)(int*,int*,void(*)(char*,int*),int*)') + iadd('\tf2py_%s_def[i_f2py++].func = %s;' % (m['name'], n)) + fadd('subroutine %s(r,s,f2pysetdata,flag)' % (fargs[-1])) + fadd('use %s, only: d => %s\n' % + (m['name'], undo_rmbadname1(n))) + fadd('integer flag\n') + fhooks[0] = fhooks[0] + fgetdims1 + dms = range(1, int(dm['rank']) + 1) + fadd(' allocate(d(%s))\n' % + (','.join(['s(%s)' % i for i in dms]))) + fhooks[0] = fhooks[0] + use_fgetdims2 + fadd('end subroutine %s' % (fargs[-1])) + else: + fargs.append(n) + sargs.append('char *%s' % (n)) + sargsp.append('char*') + iadd('\tf2py_%s_def[i_f2py++].data = %s;' % (m['name'], n)) + if onlyvars: + dadd('\\end{description}') + if hasbody(m): + for b in m['body']: + if not isroutine(b): + print('Skipping', b['block'], b['name']) + continue + modobjs.append('%s()' % (b['name'])) + b['modulename'] = m['name'] + api, wrap = rules.buildapi(b) + if isfunction(b): + fhooks[0] = fhooks[0] + wrap + fargs.append('f2pywrap_%s_%s' % (m['name'], b['name'])) + ifargs.append(func2subr.createfuncwrapper(b, signature=1)) + else: + if wrap: + fhooks[0] = fhooks[0] + wrap + fargs.append('f2pywrap_%s_%s' % (m['name'], b['name'])) + ifargs.append( + func2subr.createsubrwrapper(b, signature=1)) + else: + fargs.append(b['name']) + mfargs.append(fargs[-1]) + api['externroutines'] = [] + ar = applyrules(api, vrd) + ar['docs'] = [] + ar['docshort'] = [] + ret = dictappend(ret, ar) + cadd('\t{"%s",-1,{{-1}},0,NULL,(void *)f2py_rout_#modulename#_%s_%s,doc_f2py_rout_#modulename#_%s_%s},' % + (b['name'], m['name'], b['name'], m['name'], b['name'])) + sargs.append('char *%s' % (b['name'])) + sargsp.append('char *') + iadd('\tf2py_%s_def[i_f2py++].data = %s;' % + (m['name'], b['name'])) + cadd('\t{NULL}\n};\n') + iadd('}') + ihooks[0] = 'static void f2py_setup_%s(%s) {\n\tint i_f2py=0;%s' % ( + m['name'], ','.join(sargs), ihooks[0]) + if '_' in m['name']: + F_FUNC = 'F_FUNC_US' + else: + F_FUNC = 'F_FUNC' + iadd('extern void %s(f2pyinit%s,F2PYINIT%s)(void (*)(%s));' + % (F_FUNC, m['name'], m['name'].upper(), ','.join(sargsp))) + iadd('static void f2py_init_%s(void) {' % (m['name'])) + iadd('\t%s(f2pyinit%s,F2PYINIT%s)(f2py_setup_%s);' + % (F_FUNC, m['name'], m['name'].upper(), m['name'])) + iadd('}\n') + ret['f90modhooks'] = ret['f90modhooks'] + chooks + ihooks + ret['initf90modhooks'] = ['\tPyDict_SetItemString(d, "%s", PyFortranObject_New(f2py_%s_def,f2py_init_%s));' % ( + m['name'], m['name'], m['name'])] + ret['initf90modhooks'] + fadd('') + fadd('subroutine f2pyinit%s(f2pysetupfunc)' % (m['name'])) + if mfargs: + for a in undo_rmbadname(mfargs): + fadd('use %s, only : %s' % (m['name'], a)) + if ifargs: + fadd(' '.join(['interface'] + ifargs)) + fadd('end interface') + fadd('external f2pysetupfunc') + if efargs: + for a in undo_rmbadname(efargs): + fadd('external %s' % (a)) + fadd('call f2pysetupfunc(%s)' % (','.join(undo_rmbadname(fargs)))) + fadd('end subroutine f2pyinit%s\n' % (m['name'])) + + dadd('\n'.join(ret['latexdoc']).replace( + r'\subsection{', r'\subsubsection{')) + + ret['latexdoc'] = [] + ret['docs'].append('"\t%s --- %s"' % (m['name'], + ','.join(undo_rmbadname(modobjs)))) + + ret['routine_defs'] = '' + ret['doc'] = [] + ret['docshort'] = [] + ret['latexdoc'] = doc[0] + if len(ret['docs']) <= 1: + ret['docs'] = '' + return ret, fhooks[0] diff --git a/venv/Lib/site-packages/numpy/f2py/func2subr.py b/venv/Lib/site-packages/numpy/f2py/func2subr.py new file mode 100644 index 0000000..21d4c00 --- /dev/null +++ b/venv/Lib/site-packages/numpy/f2py/func2subr.py @@ -0,0 +1,300 @@ +#!/usr/bin/env python3 +""" + +Rules for building C/API module with f2py2e. + +Copyright 1999,2000 Pearu Peterson all rights reserved, +Pearu Peterson +Permission to use, modify, and distribute this software is given under the +terms of the NumPy License. + +NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. +$Date: 2004/11/26 11:13:06 $ +Pearu Peterson + +""" +__version__ = "$Revision: 1.16 $"[10:-1] + +f2py_version = 'See `f2py -v`' + +import copy + +from .auxfuncs import ( + getfortranname, isexternal, isfunction, isfunction_wrap, isintent_in, + isintent_out, islogicalfunction, ismoduleroutine, isscalar, + issubroutine, issubroutine_wrap, outmess, show +) + + +def var2fixfortran(vars, a, fa=None, f90mode=None): + if fa is None: + fa = a + if a not in vars: + show(vars) + outmess('var2fixfortran: No definition for argument "%s".\n' % a) + return '' + if 'typespec' not in vars[a]: + show(vars[a]) + outmess('var2fixfortran: No typespec for argument "%s".\n' % a) + return '' + vardef = vars[a]['typespec'] + if vardef == 'type' and 'typename' in vars[a]: + vardef = '%s(%s)' % (vardef, vars[a]['typename']) + selector = {} + lk = '' + if 'kindselector' in vars[a]: + selector = vars[a]['kindselector'] + lk = 'kind' + elif 'charselector' in vars[a]: + selector = vars[a]['charselector'] + lk = 'len' + if '*' in selector: + if f90mode: + if selector['*'] in ['*', ':', '(*)']: + vardef = '%s(len=*)' % (vardef) + else: + vardef = '%s(%s=%s)' % (vardef, lk, selector['*']) + else: + if selector['*'] in ['*', ':']: + vardef = '%s*(%s)' % (vardef, selector['*']) + else: + vardef = '%s*%s' % (vardef, selector['*']) + else: + if 'len' in selector: + vardef = '%s(len=%s' % (vardef, selector['len']) + if 'kind' in selector: + vardef = '%s,kind=%s)' % (vardef, selector['kind']) + else: + vardef = '%s)' % (vardef) + elif 'kind' in selector: + vardef = '%s(kind=%s)' % (vardef, selector['kind']) + + vardef = '%s %s' % (vardef, fa) + if 'dimension' in vars[a]: + vardef = '%s(%s)' % (vardef, ','.join(vars[a]['dimension'])) + return vardef + + +def createfuncwrapper(rout, signature=0): + assert isfunction(rout) + + extra_args = [] + vars = rout['vars'] + for a in rout['args']: + v = rout['vars'][a] + for i, d in enumerate(v.get('dimension', [])): + if d == ':': + dn = 'f2py_%s_d%s' % (a, i) + dv = dict(typespec='integer', intent=['hide']) + dv['='] = 'shape(%s, %s)' % (a, i) + extra_args.append(dn) + vars[dn] = dv + v['dimension'][i] = dn + rout['args'].extend(extra_args) + need_interface = bool(extra_args) + + ret = [''] + + def add(line, ret=ret): + ret[0] = '%s\n %s' % (ret[0], line) + name = rout['name'] + fortranname = getfortranname(rout) + f90mode = ismoduleroutine(rout) + newname = '%sf2pywrap' % (name) + + if newname not in vars: + vars[newname] = vars[name] + args = [newname] + rout['args'][1:] + else: + args = [newname] + rout['args'] + + l = var2fixfortran(vars, name, newname, f90mode) + if l[:13] == 'character*(*)': + if f90mode: + l = 'character(len=10)' + l[13:] + else: + l = 'character*10' + l[13:] + charselect = vars[name]['charselector'] + if charselect.get('*', '') == '(*)': + charselect['*'] = '10' + sargs = ', '.join(args) + if f90mode: + add('subroutine f2pywrap_%s_%s (%s)' % + (rout['modulename'], name, sargs)) + if not signature: + add('use %s, only : %s' % (rout['modulename'], fortranname)) + else: + add('subroutine f2pywrap%s (%s)' % (name, sargs)) + if not need_interface: + add('external %s' % (fortranname)) + l = l + ', ' + fortranname + if need_interface: + for line in rout['saved_interface'].split('\n'): + if line.lstrip().startswith('use ') and '__user__' not in line: + add(line) + + args = args[1:] + dumped_args = [] + for a in args: + if isexternal(vars[a]): + add('external %s' % (a)) + dumped_args.append(a) + for a in args: + if a in dumped_args: + continue + if isscalar(vars[a]): + add(var2fixfortran(vars, a, f90mode=f90mode)) + dumped_args.append(a) + for a in args: + if a in dumped_args: + continue + if isintent_in(vars[a]): + add(var2fixfortran(vars, a, f90mode=f90mode)) + dumped_args.append(a) + for a in args: + if a in dumped_args: + continue + add(var2fixfortran(vars, a, f90mode=f90mode)) + + add(l) + + if need_interface: + if f90mode: + # f90 module already defines needed interface + pass + else: + add('interface') + add(rout['saved_interface'].lstrip()) + add('end interface') + + sargs = ', '.join([a for a in args if a not in extra_args]) + + if not signature: + if islogicalfunction(rout): + add('%s = .not.(.not.%s(%s))' % (newname, fortranname, sargs)) + else: + add('%s = %s(%s)' % (newname, fortranname, sargs)) + if f90mode: + add('end subroutine f2pywrap_%s_%s' % (rout['modulename'], name)) + else: + add('end') + return ret[0] + + +def createsubrwrapper(rout, signature=0): + assert issubroutine(rout) + + extra_args = [] + vars = rout['vars'] + for a in rout['args']: + v = rout['vars'][a] + for i, d in enumerate(v.get('dimension', [])): + if d == ':': + dn = 'f2py_%s_d%s' % (a, i) + dv = dict(typespec='integer', intent=['hide']) + dv['='] = 'shape(%s, %s)' % (a, i) + extra_args.append(dn) + vars[dn] = dv + v['dimension'][i] = dn + rout['args'].extend(extra_args) + need_interface = bool(extra_args) + + ret = [''] + + def add(line, ret=ret): + ret[0] = '%s\n %s' % (ret[0], line) + name = rout['name'] + fortranname = getfortranname(rout) + f90mode = ismoduleroutine(rout) + + args = rout['args'] + + sargs = ', '.join(args) + if f90mode: + add('subroutine f2pywrap_%s_%s (%s)' % + (rout['modulename'], name, sargs)) + if not signature: + add('use %s, only : %s' % (rout['modulename'], fortranname)) + else: + add('subroutine f2pywrap%s (%s)' % (name, sargs)) + if not need_interface: + add('external %s' % (fortranname)) + + if need_interface: + for line in rout['saved_interface'].split('\n'): + if line.lstrip().startswith('use ') and '__user__' not in line: + add(line) + + dumped_args = [] + for a in args: + if isexternal(vars[a]): + add('external %s' % (a)) + dumped_args.append(a) + for a in args: + if a in dumped_args: + continue + if isscalar(vars[a]): + add(var2fixfortran(vars, a, f90mode=f90mode)) + dumped_args.append(a) + for a in args: + if a in dumped_args: + continue + add(var2fixfortran(vars, a, f90mode=f90mode)) + + if need_interface: + if f90mode: + # f90 module already defines needed interface + pass + else: + add('interface') + for line in rout['saved_interface'].split('\n'): + if line.lstrip().startswith('use ') and '__user__' in line: + continue + add(line) + add('end interface') + + sargs = ', '.join([a for a in args if a not in extra_args]) + + if not signature: + add('call %s(%s)' % (fortranname, sargs)) + if f90mode: + add('end subroutine f2pywrap_%s_%s' % (rout['modulename'], name)) + else: + add('end') + return ret[0] + + +def assubr(rout): + if isfunction_wrap(rout): + fortranname = getfortranname(rout) + name = rout['name'] + outmess('\t\tCreating wrapper for Fortran function "%s"("%s")...\n' % ( + name, fortranname)) + rout = copy.copy(rout) + fname = name + rname = fname + if 'result' in rout: + rname = rout['result'] + rout['vars'][fname] = rout['vars'][rname] + fvar = rout['vars'][fname] + if not isintent_out(fvar): + if 'intent' not in fvar: + fvar['intent'] = [] + fvar['intent'].append('out') + flag = 1 + for i in fvar['intent']: + if i.startswith('out='): + flag = 0 + break + if flag: + fvar['intent'].append('out=%s' % (rname)) + rout['args'][:] = [fname] + rout['args'] + return rout, createfuncwrapper(rout) + if issubroutine_wrap(rout): + fortranname = getfortranname(rout) + name = rout['name'] + outmess('\t\tCreating wrapper for Fortran subroutine "%s"("%s")...\n' % ( + name, fortranname)) + rout = copy.copy(rout) + return rout, createsubrwrapper(rout) + return rout, '' diff --git a/venv/Lib/site-packages/numpy/f2py/rules.py b/venv/Lib/site-packages/numpy/f2py/rules.py new file mode 100644 index 0000000..b9cbc54 --- /dev/null +++ b/venv/Lib/site-packages/numpy/f2py/rules.py @@ -0,0 +1,1460 @@ +#!/usr/bin/env python3 +""" + +Rules for building C/API module with f2py2e. + +Here is a skeleton of a new wrapper function (13Dec2001): + +wrapper_function(args) + declarations + get_python_arguments, say, `a' and `b' + + get_a_from_python + if (successful) { + + get_b_from_python + if (successful) { + + callfortran + if (successful) { + + put_a_to_python + if (successful) { + + put_b_to_python + if (successful) { + + buildvalue = ... + + } + + } + + } + + } + cleanup_b + + } + cleanup_a + + return buildvalue + +Copyright 1999,2000 Pearu Peterson all rights reserved, +Pearu Peterson +Permission to use, modify, and distribute this software is given under the +terms of the NumPy License. + +NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. +$Date: 2005/08/30 08:58:42 $ +Pearu Peterson + +""" +import os +import time +import copy + +# __version__.version is now the same as the NumPy version +from . import __version__ +f2py_version = __version__.version +numpy_version = __version__.version + +from .auxfuncs import ( + applyrules, debugcapi, dictappend, errmess, gentitle, getargs2, + hascallstatement, hasexternals, hasinitvalue, hasnote, hasresultnote, + isarray, isarrayofstrings, iscomplex, iscomplexarray, + iscomplexfunction, iscomplexfunction_warn, isdummyroutine, isexternal, + isfunction, isfunction_wrap, isint1array, isintent_aux, isintent_c, + isintent_callback, isintent_copy, isintent_hide, isintent_inout, + isintent_nothide, isintent_out, isintent_overwrite, islogical, + islong_complex, islong_double, islong_doublefunction, islong_long, + islong_longfunction, ismoduleroutine, isoptional, isrequired, isscalar, + issigned_long_longarray, isstring, isstringarray, isstringfunction, + issubroutine, issubroutine_wrap, isthreadsafe, isunsigned, + isunsigned_char, isunsigned_chararray, isunsigned_long_long, + isunsigned_long_longarray, isunsigned_short, isunsigned_shortarray, + l_and, l_not, l_or, outmess, replace, stripcomma, requiresf90wrapper +) + +from . import capi_maps +from . import cfuncs +from . import common_rules +from . import use_rules +from . import f90mod_rules +from . import func2subr + +options = {} +sepdict = {} +#for k in ['need_cfuncs']: sepdict[k]=',' +for k in ['decl', + 'frompyobj', + 'cleanupfrompyobj', + 'topyarr', 'method', + 'pyobjfrom', 'closepyobjfrom', + 'freemem', + 'userincludes', + 'includes0', 'includes', 'typedefs', 'typedefs_generated', + 'cppmacros', 'cfuncs', 'callbacks', + 'latexdoc', + 'restdoc', + 'routine_defs', 'externroutines', + 'initf2pywraphooks', + 'commonhooks', 'initcommonhooks', + 'f90modhooks', 'initf90modhooks']: + sepdict[k] = '\n' + +#################### Rules for C/API module ################# + +generationtime = int(os.environ.get('SOURCE_DATE_EPOCH', time.time())) +module_rules = { + 'modulebody': """\ +/* File: #modulename#module.c + * This file is auto-generated with f2py (version:#f2py_version#). + * f2py is a Fortran to Python Interface Generator (FPIG), Second Edition, + * written by Pearu Peterson . + * Generation date: """ + time.asctime(time.gmtime(generationtime)) + """ + * Do not edit this file directly unless you know what you are doing!!! + */ + +#ifdef __cplusplus +extern \"C\" { +#endif + +""" + gentitle("See f2py2e/cfuncs.py: includes") + """ +#includes# +#includes0# + +""" + gentitle("See f2py2e/rules.py: mod_rules['modulebody']") + """ +static PyObject *#modulename#_error; +static PyObject *#modulename#_module; + +""" + gentitle("See f2py2e/cfuncs.py: typedefs") + """ +#typedefs# + +""" + gentitle("See f2py2e/cfuncs.py: typedefs_generated") + """ +#typedefs_generated# + +""" + gentitle("See f2py2e/cfuncs.py: cppmacros") + """ +#cppmacros# + +""" + gentitle("See f2py2e/cfuncs.py: cfuncs") + """ +#cfuncs# + +""" + gentitle("See f2py2e/cfuncs.py: userincludes") + """ +#userincludes# + +""" + gentitle("See f2py2e/capi_rules.py: usercode") + """ +#usercode# + +/* See f2py2e/rules.py */ +#externroutines# + +""" + gentitle("See f2py2e/capi_rules.py: usercode1") + """ +#usercode1# + +""" + gentitle("See f2py2e/cb_rules.py: buildcallback") + """ +#callbacks# + +""" + gentitle("See f2py2e/rules.py: buildapi") + """ +#body# + +""" + gentitle("See f2py2e/f90mod_rules.py: buildhooks") + """ +#f90modhooks# + +""" + gentitle("See f2py2e/rules.py: module_rules['modulebody']") + """ + +""" + gentitle("See f2py2e/common_rules.py: buildhooks") + """ +#commonhooks# + +""" + gentitle("See f2py2e/rules.py") + """ + +static FortranDataDef f2py_routine_defs[] = { +#routine_defs# +\t{NULL} +}; + +static PyMethodDef f2py_module_methods[] = { +#pymethoddef# +\t{NULL,NULL} +}; + +static struct PyModuleDef moduledef = { +\tPyModuleDef_HEAD_INIT, +\t"#modulename#", +\tNULL, +\t-1, +\tf2py_module_methods, +\tNULL, +\tNULL, +\tNULL, +\tNULL +}; + +PyMODINIT_FUNC PyInit_#modulename#(void) { +\tint i; +\tPyObject *m,*d, *s, *tmp; +\tm = #modulename#_module = PyModule_Create(&moduledef); +\tPy_SET_TYPE(&PyFortran_Type, &PyType_Type); +\timport_array(); +\tif (PyErr_Occurred()) +\t\t{PyErr_SetString(PyExc_ImportError, \"can't initialize module #modulename# (failed to import numpy)\"); return m;} +\td = PyModule_GetDict(m); +\ts = PyUnicode_FromString(\"#f2py_version#\"); +\tPyDict_SetItemString(d, \"__version__\", s); +\tPy_DECREF(s); +\ts = PyUnicode_FromString( +\t\t\"This module '#modulename#' is auto-generated with f2py (version:#f2py_version#).\\nFunctions:\\n\"\n#docs#\".\"); +\tPyDict_SetItemString(d, \"__doc__\", s); +\tPy_DECREF(s); +\ts = PyUnicode_FromString(\"""" + numpy_version + """\"); +\tPyDict_SetItemString(d, \"__f2py_numpy_version__\", s); +\tPy_DECREF(s); +\t#modulename#_error = PyErr_NewException (\"#modulename#.error\", NULL, NULL); +\t/* +\t * Store the error object inside the dict, so that it could get deallocated. +\t * (in practice, this is a module, so it likely will not and cannot.) +\t */ +\tPyDict_SetItemString(d, \"_#modulename#_error\", #modulename#_error); +\tPy_DECREF(#modulename#_error); +\tfor(i=0;f2py_routine_defs[i].name!=NULL;i++) { +\t\ttmp = PyFortranObject_NewAsAttr(&f2py_routine_defs[i]); +\t\tPyDict_SetItemString(d, f2py_routine_defs[i].name, tmp); +\t\tPy_DECREF(tmp); +\t} +#initf2pywraphooks# +#initf90modhooks# +#initcommonhooks# +#interface_usercode# + +#ifdef F2PY_REPORT_ATEXIT +\tif (! PyErr_Occurred()) +\t\ton_exit(f2py_report_on_exit,(void*)\"#modulename#\"); +#endif +\treturn m; +} +#ifdef __cplusplus +} +#endif +""", + 'separatorsfor': {'latexdoc': '\n\n', + 'restdoc': '\n\n'}, + 'latexdoc': ['\\section{Module \\texttt{#texmodulename#}}\n', + '#modnote#\n', + '#latexdoc#'], + 'restdoc': ['Module #modulename#\n' + '=' * 80, + '\n#restdoc#'] +} + +defmod_rules = [ + {'body': '/*eof body*/', + 'method': '/*eof method*/', + 'externroutines': '/*eof externroutines*/', + 'routine_defs': '/*eof routine_defs*/', + 'initf90modhooks': '/*eof initf90modhooks*/', + 'initf2pywraphooks': '/*eof initf2pywraphooks*/', + 'initcommonhooks': '/*eof initcommonhooks*/', + 'latexdoc': '', + 'restdoc': '', + 'modnote': {hasnote: '#note#', l_not(hasnote): ''}, + } +] + +routine_rules = { + 'separatorsfor': sepdict, + 'body': """ +#begintitle# +static char doc_#apiname#[] = \"\\\n#docreturn##name#(#docsignatureshort#)\\n\\nWrapper for ``#name#``.\\\n\\n#docstrsigns#\"; +/* #declfortranroutine# */ +static PyObject *#apiname#(const PyObject *capi_self, + PyObject *capi_args, + PyObject *capi_keywds, + #functype# (*f2py_func)(#callprotoargument#)) { + PyObject * volatile capi_buildvalue = NULL; + volatile int f2py_success = 1; +#decl# + static char *capi_kwlist[] = {#kwlist##kwlistopt##kwlistxa#NULL}; +#usercode# +#routdebugenter# +#ifdef F2PY_REPORT_ATEXIT +f2py_start_clock(); +#endif + if (!PyArg_ParseTupleAndKeywords(capi_args,capi_keywds,\\ + \"#argformat#|#keyformat##xaformat#:#pyname#\",\\ + capi_kwlist#args_capi##keys_capi##keys_xa#))\n return NULL; +#frompyobj# +/*end of frompyobj*/ +#ifdef F2PY_REPORT_ATEXIT +f2py_start_call_clock(); +#endif +#callfortranroutine# +if (PyErr_Occurred()) + f2py_success = 0; +#ifdef F2PY_REPORT_ATEXIT +f2py_stop_call_clock(); +#endif +/*end of callfortranroutine*/ + if (f2py_success) { +#pyobjfrom# +/*end of pyobjfrom*/ + CFUNCSMESS(\"Building return value.\\n\"); + capi_buildvalue = Py_BuildValue(\"#returnformat#\"#return#); +/*closepyobjfrom*/ +#closepyobjfrom# + } /*if (f2py_success) after callfortranroutine*/ +/*cleanupfrompyobj*/ +#cleanupfrompyobj# + if (capi_buildvalue == NULL) { +#routdebugfailure# + } else { +#routdebugleave# + } + CFUNCSMESS(\"Freeing memory.\\n\"); +#freemem# +#ifdef F2PY_REPORT_ATEXIT +f2py_stop_clock(); +#endif + return capi_buildvalue; +} +#endtitle# +""", + 'routine_defs': '#routine_def#', + 'initf2pywraphooks': '#initf2pywraphook#', + 'externroutines': '#declfortranroutine#', + 'doc': '#docreturn##name#(#docsignature#)', + 'docshort': '#docreturn##name#(#docsignatureshort#)', + 'docs': '"\t#docreturn##name#(#docsignature#)\\n"\n', + 'need': ['arrayobject.h', 'CFUNCSMESS', 'MINMAX'], + 'cppmacros': {debugcapi: '#define DEBUGCFUNCS'}, + 'latexdoc': ['\\subsection{Wrapper function \\texttt{#texname#}}\n', + """ +\\noindent{{}\\verb@#docreturn##name#@{}}\\texttt{(#latexdocsignatureshort#)} +#routnote# + +#latexdocstrsigns# +"""], + 'restdoc': ['Wrapped function ``#name#``\n' + '-' * 80, + + ] +} + +################## Rules for C/API function ############## + +rout_rules = [ + { # Init + 'separatorsfor': {'callfortranroutine': '\n', 'routdebugenter': '\n', 'decl': '\n', + 'routdebugleave': '\n', 'routdebugfailure': '\n', + 'setjmpbuf': ' || ', + 'docstrreq': '\n', 'docstropt': '\n', 'docstrout': '\n', + 'docstrcbs': '\n', 'docstrsigns': '\\n"\n"', + 'latexdocstrsigns': '\n', + 'latexdocstrreq': '\n', 'latexdocstropt': '\n', + 'latexdocstrout': '\n', 'latexdocstrcbs': '\n', + }, + 'kwlist': '', 'kwlistopt': '', 'callfortran': '', 'callfortranappend': '', + 'docsign': '', 'docsignopt': '', 'decl': '/*decl*/', + 'freemem': '/*freemem*/', + 'docsignshort': '', 'docsignoptshort': '', + 'docstrsigns': '', 'latexdocstrsigns': '', + 'docstrreq': '\\nParameters\\n----------', + 'docstropt': '\\nOther Parameters\\n----------------', + 'docstrout': '\\nReturns\\n-------', + 'docstrcbs': '\\nNotes\\n-----\\nCall-back functions::\\n', + 'latexdocstrreq': '\\noindent Required arguments:', + 'latexdocstropt': '\\noindent Optional arguments:', + 'latexdocstrout': '\\noindent Return objects:', + 'latexdocstrcbs': '\\noindent Call-back functions:', + 'args_capi': '', 'keys_capi': '', 'functype': '', + 'frompyobj': '/*frompyobj*/', + # this list will be reversed + 'cleanupfrompyobj': ['/*end of cleanupfrompyobj*/'], + 'pyobjfrom': '/*pyobjfrom*/', + # this list will be reversed + 'closepyobjfrom': ['/*end of closepyobjfrom*/'], + 'topyarr': '/*topyarr*/', 'routdebugleave': '/*routdebugleave*/', + 'routdebugenter': '/*routdebugenter*/', + 'routdebugfailure': '/*routdebugfailure*/', + 'callfortranroutine': '/*callfortranroutine*/', + 'argformat': '', 'keyformat': '', 'need_cfuncs': '', + 'docreturn': '', 'return': '', 'returnformat': '', 'rformat': '', + 'kwlistxa': '', 'keys_xa': '', 'xaformat': '', 'docsignxa': '', 'docsignxashort': '', + 'initf2pywraphook': '', + 'routnote': {hasnote: '--- #note#', l_not(hasnote): ''}, + }, { + 'apiname': 'f2py_rout_#modulename#_#name#', + 'pyname': '#modulename#.#name#', + 'decl': '', + '_check': l_not(ismoduleroutine) + }, { + 'apiname': 'f2py_rout_#modulename#_#f90modulename#_#name#', + 'pyname': '#modulename#.#f90modulename#.#name#', + 'decl': '', + '_check': ismoduleroutine + }, { # Subroutine + 'functype': 'void', + 'declfortranroutine': {l_and(l_not(l_or(ismoduleroutine, isintent_c)), l_not(isdummyroutine)): 'extern void #F_FUNC#(#fortranname#,#FORTRANNAME#)(#callprotoargument#);', + l_and(l_not(ismoduleroutine), isintent_c, l_not(isdummyroutine)): 'extern void #fortranname#(#callprotoargument#);', + ismoduleroutine: '', + isdummyroutine: '' + }, + 'routine_def': {l_not(l_or(ismoduleroutine, isintent_c, isdummyroutine)): '\t{\"#name#\",-1,{{-1}},0,(char *)#F_FUNC#(#fortranname#,#FORTRANNAME#),(f2py_init_func)#apiname#,doc_#apiname#},', + l_and(l_not(ismoduleroutine), isintent_c, l_not(isdummyroutine)): '\t{\"#name#\",-1,{{-1}},0,(char *)#fortranname#,(f2py_init_func)#apiname#,doc_#apiname#},', + l_and(l_not(ismoduleroutine), isdummyroutine): '\t{\"#name#\",-1,{{-1}},0,NULL,(f2py_init_func)#apiname#,doc_#apiname#},', + }, + 'need': {l_and(l_not(l_or(ismoduleroutine, isintent_c)), l_not(isdummyroutine)): 'F_FUNC'}, + 'callfortranroutine': [ + {debugcapi: [ + """\tfprintf(stderr,\"debug-capi:Fortran subroutine `#fortranname#(#callfortran#)\'\\n\");"""]}, + {hasexternals: """\ +\t\tif (#setjmpbuf#) { +\t\t\tf2py_success = 0; +\t\t} else {"""}, + {isthreadsafe: '\t\t\tPy_BEGIN_ALLOW_THREADS'}, + {hascallstatement: '''\t\t\t\t#callstatement#; +\t\t\t\t/*(*f2py_func)(#callfortran#);*/'''}, + {l_not(l_or(hascallstatement, isdummyroutine)) + : '\t\t\t\t(*f2py_func)(#callfortran#);'}, + {isthreadsafe: '\t\t\tPy_END_ALLOW_THREADS'}, + {hasexternals: """\t\t}"""} + ], + '_check': l_and(issubroutine, l_not(issubroutine_wrap)), + }, { # Wrapped function + 'functype': 'void', + 'declfortranroutine': {l_not(l_or(ismoduleroutine, isdummyroutine)): 'extern void #F_WRAPPEDFUNC#(#name_lower#,#NAME#)(#callprotoargument#);', + isdummyroutine: '', + }, + + 'routine_def': {l_not(l_or(ismoduleroutine, isdummyroutine)): '\t{\"#name#\",-1,{{-1}},0,(char *)#F_WRAPPEDFUNC#(#name_lower#,#NAME#),(f2py_init_func)#apiname#,doc_#apiname#},', + isdummyroutine: '\t{\"#name#\",-1,{{-1}},0,NULL,(f2py_init_func)#apiname#,doc_#apiname#},', + }, + 'initf2pywraphook': {l_not(l_or(ismoduleroutine, isdummyroutine)): ''' + { + extern #ctype# #F_FUNC#(#name_lower#,#NAME#)(void); + PyObject* o = PyDict_GetItemString(d,"#name#"); + tmp = F2PyCapsule_FromVoidPtr((void*)#F_FUNC#(#name_lower#,#NAME#),NULL); + PyObject_SetAttrString(o,"_cpointer", tmp); + Py_DECREF(tmp); + s = PyUnicode_FromString("#name#"); + PyObject_SetAttrString(o,"__name__", s); + Py_DECREF(s); + } + '''}, + 'need': {l_not(l_or(ismoduleroutine, isdummyroutine)): ['F_WRAPPEDFUNC', 'F_FUNC']}, + 'callfortranroutine': [ + {debugcapi: [ + """\tfprintf(stderr,\"debug-capi:Fortran subroutine `f2pywrap#name_lower#(#callfortran#)\'\\n\");"""]}, + {hasexternals: """\ +\tif (#setjmpbuf#) { +\t\tf2py_success = 0; +\t} else {"""}, + {isthreadsafe: '\tPy_BEGIN_ALLOW_THREADS'}, + {l_not(l_or(hascallstatement, isdummyroutine)) + : '\t(*f2py_func)(#callfortran#);'}, + {hascallstatement: + '\t#callstatement#;\n\t/*(*f2py_func)(#callfortran#);*/'}, + {isthreadsafe: '\tPy_END_ALLOW_THREADS'}, + {hasexternals: '\t}'} + ], + '_check': isfunction_wrap, + }, { # Wrapped subroutine + 'functype': 'void', + 'declfortranroutine': {l_not(l_or(ismoduleroutine, isdummyroutine)): 'extern void #F_WRAPPEDFUNC#(#name_lower#,#NAME#)(#callprotoargument#);', + isdummyroutine: '', + }, + + 'routine_def': {l_not(l_or(ismoduleroutine, isdummyroutine)): '\t{\"#name#\",-1,{{-1}},0,(char *)#F_WRAPPEDFUNC#(#name_lower#,#NAME#),(f2py_init_func)#apiname#,doc_#apiname#},', + isdummyroutine: '\t{\"#name#\",-1,{{-1}},0,NULL,(f2py_init_func)#apiname#,doc_#apiname#},', + }, + 'initf2pywraphook': {l_not(l_or(ismoduleroutine, isdummyroutine)): ''' + { + extern void #F_FUNC#(#name_lower#,#NAME#)(void); + PyObject* o = PyDict_GetItemString(d,"#name#"); + tmp = F2PyCapsule_FromVoidPtr((void*)#F_FUNC#(#name_lower#,#NAME#),NULL); + PyObject_SetAttrString(o,"_cpointer", tmp); + Py_DECREF(tmp); + s = PyUnicode_FromString("#name#"); + PyObject_SetAttrString(o,"__name__", s); + Py_DECREF(s); + } + '''}, + 'need': {l_not(l_or(ismoduleroutine, isdummyroutine)): ['F_WRAPPEDFUNC', 'F_FUNC']}, + 'callfortranroutine': [ + {debugcapi: [ + """\tfprintf(stderr,\"debug-capi:Fortran subroutine `f2pywrap#name_lower#(#callfortran#)\'\\n\");"""]}, + {hasexternals: """\ +\tif (#setjmpbuf#) { +\t\tf2py_success = 0; +\t} else {"""}, + {isthreadsafe: '\tPy_BEGIN_ALLOW_THREADS'}, + {l_not(l_or(hascallstatement, isdummyroutine)) + : '\t(*f2py_func)(#callfortran#);'}, + {hascallstatement: + '\t#callstatement#;\n\t/*(*f2py_func)(#callfortran#);*/'}, + {isthreadsafe: '\tPy_END_ALLOW_THREADS'}, + {hasexternals: '\t}'} + ], + '_check': issubroutine_wrap, + }, { # Function + 'functype': '#ctype#', + 'docreturn': {l_not(isintent_hide): '#rname#,'}, + 'docstrout': '#pydocsignout#', + 'latexdocstrout': ['\\item[]{{}\\verb@#pydocsignout#@{}}', + {hasresultnote: '--- #resultnote#'}], + 'callfortranroutine': [{l_and(debugcapi, isstringfunction): """\ +#ifdef USESCOMPAQFORTRAN +\tfprintf(stderr,\"debug-capi:Fortran function #ctype# #fortranname#(#callcompaqfortran#)\\n\"); +#else +\tfprintf(stderr,\"debug-capi:Fortran function #ctype# #fortranname#(#callfortran#)\\n\"); +#endif +"""}, + {l_and(debugcapi, l_not(isstringfunction)): """\ +\tfprintf(stderr,\"debug-capi:Fortran function #ctype# #fortranname#(#callfortran#)\\n\"); +"""} + ], + '_check': l_and(isfunction, l_not(isfunction_wrap)) + }, { # Scalar function + 'declfortranroutine': {l_and(l_not(l_or(ismoduleroutine, isintent_c)), l_not(isdummyroutine)): 'extern #ctype# #F_FUNC#(#fortranname#,#FORTRANNAME#)(#callprotoargument#);', + l_and(l_not(ismoduleroutine), isintent_c, l_not(isdummyroutine)): 'extern #ctype# #fortranname#(#callprotoargument#);', + isdummyroutine: '' + }, + 'routine_def': {l_and(l_not(l_or(ismoduleroutine, isintent_c)), l_not(isdummyroutine)): '\t{\"#name#\",-1,{{-1}},0,(char *)#F_FUNC#(#fortranname#,#FORTRANNAME#),(f2py_init_func)#apiname#,doc_#apiname#},', + l_and(l_not(ismoduleroutine), isintent_c, l_not(isdummyroutine)): '\t{\"#name#\",-1,{{-1}},0,(char *)#fortranname#,(f2py_init_func)#apiname#,doc_#apiname#},', + isdummyroutine: '\t{\"#name#\",-1,{{-1}},0,NULL,(f2py_init_func)#apiname#,doc_#apiname#},', + }, + 'decl': [{iscomplexfunction_warn: '\t#ctype# #name#_return_value={0,0};', + l_not(iscomplexfunction): '\t#ctype# #name#_return_value=0;'}, + {iscomplexfunction: + '\tPyObject *#name#_return_value_capi = Py_None;'} + ], + 'callfortranroutine': [ + {hasexternals: """\ +\tif (#setjmpbuf#) { +\t\tf2py_success = 0; +\t} else {"""}, + {isthreadsafe: '\tPy_BEGIN_ALLOW_THREADS'}, + {hascallstatement: '''\t#callstatement#; +/*\t#name#_return_value = (*f2py_func)(#callfortran#);*/ +'''}, + {l_not(l_or(hascallstatement, isdummyroutine)) + : '\t#name#_return_value = (*f2py_func)(#callfortran#);'}, + {isthreadsafe: '\tPy_END_ALLOW_THREADS'}, + {hasexternals: '\t}'}, + {l_and(debugcapi, iscomplexfunction) + : '\tfprintf(stderr,"#routdebugshowvalue#\\n",#name#_return_value.r,#name#_return_value.i);'}, + {l_and(debugcapi, l_not(iscomplexfunction)): '\tfprintf(stderr,"#routdebugshowvalue#\\n",#name#_return_value);'}], + 'pyobjfrom': {iscomplexfunction: '\t#name#_return_value_capi = pyobj_from_#ctype#1(#name#_return_value);'}, + 'need': [{l_not(isdummyroutine): 'F_FUNC'}, + {iscomplexfunction: 'pyobj_from_#ctype#1'}, + {islong_longfunction: 'long_long'}, + {islong_doublefunction: 'long_double'}], + 'returnformat': {l_not(isintent_hide): '#rformat#'}, + 'return': {iscomplexfunction: ',#name#_return_value_capi', + l_not(l_or(iscomplexfunction, isintent_hide)): ',#name#_return_value'}, + '_check': l_and(isfunction, l_not(isstringfunction), l_not(isfunction_wrap)) + }, { # String function # in use for --no-wrap + 'declfortranroutine': 'extern void #F_FUNC#(#fortranname#,#FORTRANNAME#)(#callprotoargument#);', + 'routine_def': {l_not(l_or(ismoduleroutine, isintent_c)): + '\t{\"#name#\",-1,{{-1}},0,(char *)#F_FUNC#(#fortranname#,#FORTRANNAME#),(f2py_init_func)#apiname#,doc_#apiname#},', + l_and(l_not(ismoduleroutine), isintent_c): + '\t{\"#name#\",-1,{{-1}},0,(char *)#fortranname#,(f2py_init_func)#apiname#,doc_#apiname#},' + }, + 'decl': ['\t#ctype# #name#_return_value = NULL;', + '\tint #name#_return_value_len = 0;'], + 'callfortran':'#name#_return_value,#name#_return_value_len,', + 'callfortranroutine':['\t#name#_return_value_len = #rlength#;', + '\tif ((#name#_return_value = (string)malloc(sizeof(char)*(#name#_return_value_len+1))) == NULL) {', + '\t\tPyErr_SetString(PyExc_MemoryError, \"out of memory\");', + '\t\tf2py_success = 0;', + '\t} else {', + "\t\t(#name#_return_value)[#name#_return_value_len] = '\\0';", + '\t}', + '\tif (f2py_success) {', + {hasexternals: """\ +\t\tif (#setjmpbuf#) { +\t\t\tf2py_success = 0; +\t\t} else {"""}, + {isthreadsafe: '\t\tPy_BEGIN_ALLOW_THREADS'}, + """\ +#ifdef USESCOMPAQFORTRAN +\t\t(*f2py_func)(#callcompaqfortran#); +#else +\t\t(*f2py_func)(#callfortran#); +#endif +""", + {isthreadsafe: '\t\tPy_END_ALLOW_THREADS'}, + {hasexternals: '\t\t}'}, + {debugcapi: + '\t\tfprintf(stderr,"#routdebugshowvalue#\\n",#name#_return_value_len,#name#_return_value);'}, + '\t} /* if (f2py_success) after (string)malloc */', + ], + 'returnformat': '#rformat#', + 'return': ',#name#_return_value', + 'freemem': '\tSTRINGFREE(#name#_return_value);', + 'need': ['F_FUNC', '#ctype#', 'STRINGFREE'], + '_check':l_and(isstringfunction, l_not(isfunction_wrap)) # ???obsolete + }, + { # Debugging + 'routdebugenter': '\tfprintf(stderr,"debug-capi:Python C/API function #modulename#.#name#(#docsignature#)\\n");', + 'routdebugleave': '\tfprintf(stderr,"debug-capi:Python C/API function #modulename#.#name#: successful.\\n");', + 'routdebugfailure': '\tfprintf(stderr,"debug-capi:Python C/API function #modulename#.#name#: failure.\\n");', + '_check': debugcapi + } +] + +################ Rules for arguments ################## + +typedef_need_dict = {islong_long: 'long_long', + islong_double: 'long_double', + islong_complex: 'complex_long_double', + isunsigned_char: 'unsigned_char', + isunsigned_short: 'unsigned_short', + isunsigned: 'unsigned', + isunsigned_long_long: 'unsigned_long_long', + isunsigned_chararray: 'unsigned_char', + isunsigned_shortarray: 'unsigned_short', + isunsigned_long_longarray: 'unsigned_long_long', + issigned_long_longarray: 'long_long', + } + +aux_rules = [ + { + 'separatorsfor': sepdict + }, + { # Common + 'frompyobj': ['\t/* Processing auxiliary variable #varname# */', + {debugcapi: '\tfprintf(stderr,"#vardebuginfo#\\n");'}, ], + 'cleanupfrompyobj': '\t/* End of cleaning variable #varname# */', + 'need': typedef_need_dict, + }, + # Scalars (not complex) + { # Common + 'decl': '\t#ctype# #varname# = 0;', + 'need': {hasinitvalue: 'math.h'}, + 'frompyobj': {hasinitvalue: '\t#varname# = #init#;'}, + '_check': l_and(isscalar, l_not(iscomplex)), + }, + { + 'return': ',#varname#', + 'docstrout': '#pydocsignout#', + 'docreturn': '#outvarname#,', + 'returnformat': '#varrformat#', + '_check': l_and(isscalar, l_not(iscomplex), isintent_out), + }, + # Complex scalars + { # Common + 'decl': '\t#ctype# #varname#;', + 'frompyobj': {hasinitvalue: '\t#varname#.r = #init.r#, #varname#.i = #init.i#;'}, + '_check': iscomplex + }, + # String + { # Common + 'decl': ['\t#ctype# #varname# = NULL;', + '\tint slen(#varname#);', + ], + 'need':['len..'], + '_check':isstring + }, + # Array + { # Common + 'decl': ['\t#ctype# *#varname# = NULL;', + '\tnpy_intp #varname#_Dims[#rank#] = {#rank*[-1]#};', + '\tconst int #varname#_Rank = #rank#;', + ], + 'need':['len..', {hasinitvalue: 'forcomb'}, {hasinitvalue: 'CFUNCSMESS'}], + '_check': isarray + }, + # Scalararray + { # Common + '_check': l_and(isarray, l_not(iscomplexarray)) + }, { # Not hidden + '_check': l_and(isarray, l_not(iscomplexarray), isintent_nothide) + }, + # Integer*1 array + {'need': '#ctype#', + '_check': isint1array, + '_depend': '' + }, + # Integer*-1 array + {'need': '#ctype#', + '_check': isunsigned_chararray, + '_depend': '' + }, + # Integer*-2 array + {'need': '#ctype#', + '_check': isunsigned_shortarray, + '_depend': '' + }, + # Integer*-8 array + {'need': '#ctype#', + '_check': isunsigned_long_longarray, + '_depend': '' + }, + # Complexarray + {'need': '#ctype#', + '_check': iscomplexarray, + '_depend': '' + }, + # Stringarray + { + 'callfortranappend': {isarrayofstrings: 'flen(#varname#),'}, + 'need': 'string', + '_check': isstringarray + } +] + +arg_rules = [ + { + 'separatorsfor': sepdict + }, + { # Common + 'frompyobj': ['\t/* Processing variable #varname# */', + {debugcapi: '\tfprintf(stderr,"#vardebuginfo#\\n");'}, ], + 'cleanupfrompyobj': '\t/* End of cleaning variable #varname# */', + '_depend': '', + 'need': typedef_need_dict, + }, + # Doc signatures + { + 'docstropt': {l_and(isoptional, isintent_nothide): '#pydocsign#'}, + 'docstrreq': {l_and(isrequired, isintent_nothide): '#pydocsign#'}, + 'docstrout': {isintent_out: '#pydocsignout#'}, + 'latexdocstropt': {l_and(isoptional, isintent_nothide): ['\\item[]{{}\\verb@#pydocsign#@{}}', + {hasnote: '--- #note#'}]}, + 'latexdocstrreq': {l_and(isrequired, isintent_nothide): ['\\item[]{{}\\verb@#pydocsign#@{}}', + {hasnote: '--- #note#'}]}, + 'latexdocstrout': {isintent_out: ['\\item[]{{}\\verb@#pydocsignout#@{}}', + {l_and(hasnote, isintent_hide): '--- #note#', + l_and(hasnote, isintent_nothide): '--- See above.'}]}, + 'depend': '' + }, + # Required/Optional arguments + { + 'kwlist': '"#varname#",', + 'docsign': '#varname#,', + '_check': l_and(isintent_nothide, l_not(isoptional)) + }, + { + 'kwlistopt': '"#varname#",', + 'docsignopt': '#varname#=#showinit#,', + 'docsignoptshort': '#varname#,', + '_check': l_and(isintent_nothide, isoptional) + }, + # Docstring/BuildValue + { + 'docreturn': '#outvarname#,', + 'returnformat': '#varrformat#', + '_check': isintent_out + }, + # Externals (call-back functions) + { # Common + 'docsignxa': {isintent_nothide: '#varname#_extra_args=(),'}, + 'docsignxashort': {isintent_nothide: '#varname#_extra_args,'}, + 'docstropt': {isintent_nothide: '#varname#_extra_args : input tuple, optional\\n Default: ()'}, + 'docstrcbs': '#cbdocstr#', + 'latexdocstrcbs': '\\item[] #cblatexdocstr#', + 'latexdocstropt': {isintent_nothide: '\\item[]{{}\\verb@#varname#_extra_args := () input tuple@{}} --- Extra arguments for call-back function {{}\\verb@#varname#@{}}.'}, + 'decl': [' #cbname#_t #varname#_cb = { Py_None, NULL, 0 };', + ' #cbname#_t *#varname#_cb_ptr = &#varname#_cb;', + ' PyTupleObject *#varname#_xa_capi = NULL;', + {l_not(isintent_callback): + ' #cbname#_typedef #varname#_cptr;'} + ], + 'kwlistxa': {isintent_nothide: '"#varname#_extra_args",'}, + 'argformat': {isrequired: 'O'}, + 'keyformat': {isoptional: 'O'}, + 'xaformat': {isintent_nothide: 'O!'}, + 'args_capi': {isrequired: ',&#varname#_cb.capi'}, + 'keys_capi': {isoptional: ',&#varname#_cb.capi'}, + 'keys_xa': ',&PyTuple_Type,&#varname#_xa_capi', + 'setjmpbuf': '(setjmp(#varname#_cb.jmpbuf))', + 'callfortran': {l_not(isintent_callback): '#varname#_cptr,'}, + 'need': ['#cbname#', 'setjmp.h'], + '_check':isexternal + }, + { + 'frompyobj': [{l_not(isintent_callback): """\ +if(F2PyCapsule_Check(#varname#_cb.capi)) { + #varname#_cptr = F2PyCapsule_AsVoidPtr(#varname#_cb.capi); +} else { + #varname#_cptr = #cbname#; +} +"""}, {isintent_callback: """\ +if (#varname#_cb.capi==Py_None) { + #varname#_cb.capi = PyObject_GetAttrString(#modulename#_module,\"#varname#\"); + if (#varname#_cb.capi) { + if (#varname#_xa_capi==NULL) { + if (PyObject_HasAttrString(#modulename#_module,\"#varname#_extra_args\")) { + PyObject* capi_tmp = PyObject_GetAttrString(#modulename#_module,\"#varname#_extra_args\"); + if (capi_tmp) { + #varname#_xa_capi = (PyTupleObject *)PySequence_Tuple(capi_tmp); + Py_DECREF(capi_tmp); + } + else { + #varname#_xa_capi = (PyTupleObject *)Py_BuildValue(\"()\"); + } + if (#varname#_xa_capi==NULL) { + PyErr_SetString(#modulename#_error,\"Failed to convert #modulename#.#varname#_extra_args to tuple.\\n\"); + return NULL; + } + } + } + } + if (#varname#_cb.capi==NULL) { + PyErr_SetString(#modulename#_error,\"Callback #varname# not defined (as an argument or module #modulename# attribute).\\n\"); + return NULL; + } +} +"""}, + """\ + if (create_cb_arglist(#varname#_cb.capi,#varname#_xa_capi,#maxnofargs#,#nofoptargs#,&#varname#_cb.nofargs,&#varname#_cb.args_capi,\"failed in processing argument list for call-back #varname#.\")) { +""", + {debugcapi: ["""\ + fprintf(stderr,\"debug-capi:Assuming %d arguments; at most #maxnofargs#(-#nofoptargs#) is expected.\\n\",#varname#_cb.nofargs); + CFUNCSMESSPY(\"for #varname#=\",#varname#_cb.capi);""", + {l_not(isintent_callback): """ fprintf(stderr,\"#vardebugshowvalue# (call-back in C).\\n\",#cbname#);"""}]}, + """\ + CFUNCSMESS(\"Saving callback variables for `#varname#`.\\n\"); + #varname#_cb_ptr = swap_active_#cbname#(#varname#_cb_ptr);""", + ], + 'cleanupfrompyobj': + """\ + CFUNCSMESS(\"Restoring callback variables for `#varname#`.\\n\"); + #varname#_cb_ptr = swap_active_#cbname#(#varname#_cb_ptr); + Py_DECREF(#varname#_cb.args_capi); + }""", + 'need': ['SWAP', 'create_cb_arglist'], + '_check':isexternal, + '_depend':'' + }, + # Scalars (not complex) + { # Common + 'decl': '\t#ctype# #varname# = 0;', + 'pyobjfrom': {debugcapi: '\tfprintf(stderr,"#vardebugshowvalue#\\n",#varname#);'}, + 'callfortran': {isintent_c: '#varname#,', l_not(isintent_c): '&#varname#,'}, + 'return': {isintent_out: ',#varname#'}, + '_check': l_and(isscalar, l_not(iscomplex)) + }, { + 'need': {hasinitvalue: 'math.h'}, + '_check': l_and(isscalar, l_not(iscomplex)), + }, { # Not hidden + 'decl': '\tPyObject *#varname#_capi = Py_None;', + 'argformat': {isrequired: 'O'}, + 'keyformat': {isoptional: 'O'}, + 'args_capi': {isrequired: ',&#varname#_capi'}, + 'keys_capi': {isoptional: ',&#varname#_capi'}, + 'pyobjfrom': {isintent_inout: """\ +\tf2py_success = try_pyarr_from_#ctype#(#varname#_capi,&#varname#); +\tif (f2py_success) {"""}, + 'closepyobjfrom': {isintent_inout: "\t} /*if (f2py_success) of #varname# pyobjfrom*/"}, + 'need': {isintent_inout: 'try_pyarr_from_#ctype#'}, + '_check': l_and(isscalar, l_not(iscomplex), isintent_nothide) + }, { + 'frompyobj': [ + # hasinitvalue... + # if pyobj is None: + # varname = init + # else + # from_pyobj(varname) + # + # isoptional and noinitvalue... + # if pyobj is not None: + # from_pyobj(varname) + # else: + # varname is uninitialized + # + # ... + # from_pyobj(varname) + # + {hasinitvalue: '\tif (#varname#_capi == Py_None) #varname# = #init#; else', + '_depend': ''}, + {l_and(isoptional, l_not(hasinitvalue)): '\tif (#varname#_capi != Py_None)', + '_depend': ''}, + {l_not(islogical): '''\ +\t\tf2py_success = #ctype#_from_pyobj(&#varname#,#varname#_capi,"#pyname#() #nth# (#varname#) can\'t be converted to #ctype#"); +\tif (f2py_success) {'''}, + {islogical: '''\ +\t\t#varname# = (#ctype#)PyObject_IsTrue(#varname#_capi); +\t\tf2py_success = 1; +\tif (f2py_success) {'''}, + ], + 'cleanupfrompyobj': '\t} /*if (f2py_success) of #varname#*/', + 'need': {l_not(islogical): '#ctype#_from_pyobj'}, + '_check': l_and(isscalar, l_not(iscomplex), isintent_nothide), + '_depend': '' + }, { # Hidden + 'frompyobj': {hasinitvalue: '\t#varname# = #init#;'}, + 'need': typedef_need_dict, + '_check': l_and(isscalar, l_not(iscomplex), isintent_hide), + '_depend': '' + }, { # Common + 'frompyobj': {debugcapi: '\tfprintf(stderr,"#vardebugshowvalue#\\n",#varname#);'}, + '_check': l_and(isscalar, l_not(iscomplex)), + '_depend': '' + }, + # Complex scalars + { # Common + 'decl': '\t#ctype# #varname#;', + 'callfortran': {isintent_c: '#varname#,', l_not(isintent_c): '&#varname#,'}, + 'pyobjfrom': {debugcapi: '\tfprintf(stderr,"#vardebugshowvalue#\\n",#varname#.r,#varname#.i);'}, + 'return': {isintent_out: ',#varname#_capi'}, + '_check': iscomplex + }, { # Not hidden + 'decl': '\tPyObject *#varname#_capi = Py_None;', + 'argformat': {isrequired: 'O'}, + 'keyformat': {isoptional: 'O'}, + 'args_capi': {isrequired: ',&#varname#_capi'}, + 'keys_capi': {isoptional: ',&#varname#_capi'}, + 'need': {isintent_inout: 'try_pyarr_from_#ctype#'}, + 'pyobjfrom': {isintent_inout: """\ +\t\tf2py_success = try_pyarr_from_#ctype#(#varname#_capi,&#varname#); +\t\tif (f2py_success) {"""}, + 'closepyobjfrom': {isintent_inout: "\t\t} /*if (f2py_success) of #varname# pyobjfrom*/"}, + '_check': l_and(iscomplex, isintent_nothide) + }, { + 'frompyobj': [{hasinitvalue: '\tif (#varname#_capi==Py_None) {#varname#.r = #init.r#, #varname#.i = #init.i#;} else'}, + {l_and(isoptional, l_not(hasinitvalue)) + : '\tif (#varname#_capi != Py_None)'}, + '\t\tf2py_success = #ctype#_from_pyobj(&#varname#,#varname#_capi,"#pyname#() #nth# (#varname#) can\'t be converted to #ctype#");' + '\n\tif (f2py_success) {'], + 'cleanupfrompyobj': '\t} /*if (f2py_success) of #varname# frompyobj*/', + 'need': ['#ctype#_from_pyobj'], + '_check': l_and(iscomplex, isintent_nothide), + '_depend': '' + }, { # Hidden + 'decl': {isintent_out: '\tPyObject *#varname#_capi = Py_None;'}, + '_check': l_and(iscomplex, isintent_hide) + }, { + 'frompyobj': {hasinitvalue: '\t#varname#.r = #init.r#, #varname#.i = #init.i#;'}, + '_check': l_and(iscomplex, isintent_hide), + '_depend': '' + }, { # Common + 'pyobjfrom': {isintent_out: '\t#varname#_capi = pyobj_from_#ctype#1(#varname#);'}, + 'need': ['pyobj_from_#ctype#1'], + '_check': iscomplex + }, { + 'frompyobj': {debugcapi: '\tfprintf(stderr,"#vardebugshowvalue#\\n",#varname#.r,#varname#.i);'}, + '_check': iscomplex, + '_depend': '' + }, + # String + { # Common + 'decl': ['\t#ctype# #varname# = NULL;', + '\tint slen(#varname#);', + '\tPyObject *#varname#_capi = Py_None;'], + 'callfortran':'#varname#,', + 'callfortranappend':'slen(#varname#),', + 'pyobjfrom':{debugcapi: '\tfprintf(stderr,"#vardebugshowvalue#\\n",slen(#varname#),#varname#);'}, + 'return': {isintent_out: ',#varname#'}, + 'need': ['len..'], # 'STRINGFREE'], + '_check':isstring + }, { # Common + 'frompyobj': """\ +\tslen(#varname#) = #length#; +\tf2py_success = #ctype#_from_pyobj(&#varname#,&slen(#varname#),#init#,#varname#_capi,\"#ctype#_from_pyobj failed in converting #nth# `#varname#\' of #pyname# to C #ctype#\"); +\tif (f2py_success) {""", + 'cleanupfrompyobj': """\ +\t\tSTRINGFREE(#varname#); +\t} /*if (f2py_success) of #varname#*/""", + 'need': ['#ctype#_from_pyobj', 'len..', 'STRINGFREE'], + '_check':isstring, + '_depend':'' + }, { # Not hidden + 'argformat': {isrequired: 'O'}, + 'keyformat': {isoptional: 'O'}, + 'args_capi': {isrequired: ',&#varname#_capi'}, + 'keys_capi': {isoptional: ',&#varname#_capi'}, + 'pyobjfrom': {isintent_inout: '''\ +\tf2py_success = try_pyarr_from_#ctype#(#varname#_capi,#varname#); +\tif (f2py_success) {'''}, + 'closepyobjfrom': {isintent_inout: '\t} /*if (f2py_success) of #varname# pyobjfrom*/'}, + 'need': {isintent_inout: 'try_pyarr_from_#ctype#'}, + '_check': l_and(isstring, isintent_nothide) + }, { # Hidden + '_check': l_and(isstring, isintent_hide) + }, { + 'frompyobj': {debugcapi: '\tfprintf(stderr,"#vardebugshowvalue#\\n",slen(#varname#),#varname#);'}, + '_check': isstring, + '_depend': '' + }, + # Array + { # Common + 'decl': ['\t#ctype# *#varname# = NULL;', + '\tnpy_intp #varname#_Dims[#rank#] = {#rank*[-1]#};', + '\tconst int #varname#_Rank = #rank#;', + '\tPyArrayObject *capi_#varname#_tmp = NULL;', + '\tint capi_#varname#_intent = 0;', + ], + 'callfortran':'#varname#,', + 'return':{isintent_out: ',capi_#varname#_tmp'}, + 'need': 'len..', + '_check': isarray + }, { # intent(overwrite) array + 'decl': '\tint capi_overwrite_#varname# = 1;', + 'kwlistxa': '"overwrite_#varname#",', + 'xaformat': 'i', + 'keys_xa': ',&capi_overwrite_#varname#', + 'docsignxa': 'overwrite_#varname#=1,', + 'docsignxashort': 'overwrite_#varname#,', + 'docstropt': 'overwrite_#varname# : input int, optional\\n Default: 1', + '_check': l_and(isarray, isintent_overwrite), + }, { + 'frompyobj': '\tcapi_#varname#_intent |= (capi_overwrite_#varname#?0:F2PY_INTENT_COPY);', + '_check': l_and(isarray, isintent_overwrite), + '_depend': '', + }, + { # intent(copy) array + 'decl': '\tint capi_overwrite_#varname# = 0;', + 'kwlistxa': '"overwrite_#varname#",', + 'xaformat': 'i', + 'keys_xa': ',&capi_overwrite_#varname#', + 'docsignxa': 'overwrite_#varname#=0,', + 'docsignxashort': 'overwrite_#varname#,', + 'docstropt': 'overwrite_#varname# : input int, optional\\n Default: 0', + '_check': l_and(isarray, isintent_copy), + }, { + 'frompyobj': '\tcapi_#varname#_intent |= (capi_overwrite_#varname#?0:F2PY_INTENT_COPY);', + '_check': l_and(isarray, isintent_copy), + '_depend': '', + }, { + 'need': [{hasinitvalue: 'forcomb'}, {hasinitvalue: 'CFUNCSMESS'}], + '_check': isarray, + '_depend': '' + }, { # Not hidden + 'decl': '\tPyObject *#varname#_capi = Py_None;', + 'argformat': {isrequired: 'O'}, + 'keyformat': {isoptional: 'O'}, + 'args_capi': {isrequired: ',&#varname#_capi'}, + 'keys_capi': {isoptional: ',&#varname#_capi'}, + '_check': l_and(isarray, isintent_nothide) + }, { + 'frompyobj': ['\t#setdims#;', + '\tcapi_#varname#_intent |= #intent#;', + {isintent_hide: + '\tcapi_#varname#_tmp = array_from_pyobj(#atype#,#varname#_Dims,#varname#_Rank,capi_#varname#_intent,Py_None);'}, + {isintent_nothide: + '\tcapi_#varname#_tmp = array_from_pyobj(#atype#,#varname#_Dims,#varname#_Rank,capi_#varname#_intent,#varname#_capi);'}, + """\ +\tif (capi_#varname#_tmp == NULL) { +\t\tPyObject *exc, *val, *tb; +\t\tPyErr_Fetch(&exc, &val, &tb); +\t\tPyErr_SetString(exc ? exc : #modulename#_error,\"failed in converting #nth# `#varname#\' of #pyname# to C/Fortran array\" ); +\t\tnpy_PyErr_ChainExceptionsCause(exc, val, tb); +\t} else { +\t\t#varname# = (#ctype# *)(PyArray_DATA(capi_#varname#_tmp)); +""", + {hasinitvalue: [ + {isintent_nothide: + '\tif (#varname#_capi == Py_None) {'}, + {isintent_hide: '\t{'}, + {iscomplexarray: '\t\t#ctype# capi_c;'}, + """\ +\t\tint *_i,capi_i=0; +\t\tCFUNCSMESS(\"#name#: Initializing #varname#=#init#\\n\"); +\t\tif (initforcomb(PyArray_DIMS(capi_#varname#_tmp),PyArray_NDIM(capi_#varname#_tmp),1)) { +\t\t\twhile ((_i = nextforcomb())) +\t\t\t\t#varname#[capi_i++] = #init#; /* fortran way */ +\t\t} else { +\t\t\tPyObject *exc, *val, *tb; +\t\t\tPyErr_Fetch(&exc, &val, &tb); +\t\t\tPyErr_SetString(exc ? exc : #modulename#_error,\"Initialization of #nth# #varname# failed (initforcomb).\"); +\t\t\tnpy_PyErr_ChainExceptionsCause(exc, val, tb); +\t\t\tf2py_success = 0; +\t\t} +\t} +\tif (f2py_success) {"""]}, + ], + 'cleanupfrompyobj': [ # note that this list will be reversed + '\t} /*if (capi_#varname#_tmp == NULL) ... else of #varname#*/', + {l_not(l_or(isintent_out, isintent_hide)): """\ +\tif((PyObject *)capi_#varname#_tmp!=#varname#_capi) { +\t\tPy_XDECREF(capi_#varname#_tmp); }"""}, + {l_and(isintent_hide, l_not(isintent_out)) + : """\t\tPy_XDECREF(capi_#varname#_tmp);"""}, + {hasinitvalue: '\t} /*if (f2py_success) of #varname# init*/'}, + ], + '_check': isarray, + '_depend': '' + }, + # Scalararray + { # Common + '_check': l_and(isarray, l_not(iscomplexarray)) + }, { # Not hidden + '_check': l_and(isarray, l_not(iscomplexarray), isintent_nothide) + }, + # Integer*1 array + {'need': '#ctype#', + '_check': isint1array, + '_depend': '' + }, + # Integer*-1 array + {'need': '#ctype#', + '_check': isunsigned_chararray, + '_depend': '' + }, + # Integer*-2 array + {'need': '#ctype#', + '_check': isunsigned_shortarray, + '_depend': '' + }, + # Integer*-8 array + {'need': '#ctype#', + '_check': isunsigned_long_longarray, + '_depend': '' + }, + # Complexarray + {'need': '#ctype#', + '_check': iscomplexarray, + '_depend': '' + }, + # Stringarray + { + 'callfortranappend': {isarrayofstrings: 'flen(#varname#),'}, + 'need': 'string', + '_check': isstringarray + } +] + +################# Rules for checking ############### + +check_rules = [ + { + 'frompyobj': {debugcapi: '\tfprintf(stderr,\"debug-capi:Checking `#check#\'\\n\");'}, + 'need': 'len..' + }, { + 'frompyobj': '\tCHECKSCALAR(#check#,\"#check#\",\"#nth# #varname#\",\"#varshowvalue#\",#varname#) {', + 'cleanupfrompyobj': '\t} /*CHECKSCALAR(#check#)*/', + 'need': 'CHECKSCALAR', + '_check': l_and(isscalar, l_not(iscomplex)), + '_break': '' + }, { + 'frompyobj': '\tCHECKSTRING(#check#,\"#check#\",\"#nth# #varname#\",\"#varshowvalue#\",#varname#) {', + 'cleanupfrompyobj': '\t} /*CHECKSTRING(#check#)*/', + 'need': 'CHECKSTRING', + '_check': isstring, + '_break': '' + }, { + 'need': 'CHECKARRAY', + 'frompyobj': '\tCHECKARRAY(#check#,\"#check#\",\"#nth# #varname#\") {', + 'cleanupfrompyobj': '\t} /*CHECKARRAY(#check#)*/', + '_check': isarray, + '_break': '' + }, { + 'need': 'CHECKGENERIC', + 'frompyobj': '\tCHECKGENERIC(#check#,\"#check#\",\"#nth# #varname#\") {', + 'cleanupfrompyobj': '\t} /*CHECKGENERIC(#check#)*/', + } +] + +########## Applying the rules. No need to modify what follows ############# + +#################### Build C/API module ####################### + + +def buildmodule(m, um): + """ + Return + """ + outmess('\tBuilding module "%s"...\n' % (m['name'])) + ret = {} + mod_rules = defmod_rules[:] + vrd = capi_maps.modsign2map(m) + rd = dictappend({'f2py_version': f2py_version}, vrd) + funcwrappers = [] + funcwrappers2 = [] # F90 codes + for n in m['interfaced']: + nb = None + for bi in m['body']: + if not bi['block'] == 'interface': + errmess('buildmodule: Expected interface block. Skipping.\n') + continue + for b in bi['body']: + if b['name'] == n: + nb = b + break + + if not nb: + errmess( + 'buildmodule: Could not found the body of interfaced routine "%s". Skipping.\n' % (n)) + continue + nb_list = [nb] + if 'entry' in nb: + for k, a in nb['entry'].items(): + nb1 = copy.deepcopy(nb) + del nb1['entry'] + nb1['name'] = k + nb1['args'] = a + nb_list.append(nb1) + for nb in nb_list: + # requiresf90wrapper must be called before buildapi as it + # rewrites assumed shape arrays as automatic arrays. + isf90 = requiresf90wrapper(nb) + api, wrap = buildapi(nb) + if wrap: + if isf90: + funcwrappers2.append(wrap) + else: + funcwrappers.append(wrap) + ar = applyrules(api, vrd) + rd = dictappend(rd, ar) + + # Construct COMMON block support + cr, wrap = common_rules.buildhooks(m) + if wrap: + funcwrappers.append(wrap) + ar = applyrules(cr, vrd) + rd = dictappend(rd, ar) + + # Construct F90 module support + mr, wrap = f90mod_rules.buildhooks(m) + if wrap: + funcwrappers2.append(wrap) + ar = applyrules(mr, vrd) + rd = dictappend(rd, ar) + + for u in um: + ar = use_rules.buildusevars(u, m['use'][u['name']]) + rd = dictappend(rd, ar) + + needs = cfuncs.get_needs() + code = {} + for n in needs.keys(): + code[n] = [] + for k in needs[n]: + c = '' + if k in cfuncs.includes0: + c = cfuncs.includes0[k] + elif k in cfuncs.includes: + c = cfuncs.includes[k] + elif k in cfuncs.userincludes: + c = cfuncs.userincludes[k] + elif k in cfuncs.typedefs: + c = cfuncs.typedefs[k] + elif k in cfuncs.typedefs_generated: + c = cfuncs.typedefs_generated[k] + elif k in cfuncs.cppmacros: + c = cfuncs.cppmacros[k] + elif k in cfuncs.cfuncs: + c = cfuncs.cfuncs[k] + elif k in cfuncs.callbacks: + c = cfuncs.callbacks[k] + elif k in cfuncs.f90modhooks: + c = cfuncs.f90modhooks[k] + elif k in cfuncs.commonhooks: + c = cfuncs.commonhooks[k] + else: + errmess('buildmodule: unknown need %s.\n' % (repr(k))) + continue + code[n].append(c) + mod_rules.append(code) + for r in mod_rules: + if ('_check' in r and r['_check'](m)) or ('_check' not in r): + ar = applyrules(r, vrd, m) + rd = dictappend(rd, ar) + ar = applyrules(module_rules, rd) + + fn = os.path.join(options['buildpath'], vrd['coutput']) + ret['csrc'] = fn + with open(fn, 'w') as f: + f.write(ar['modulebody'].replace('\t', 2 * ' ')) + outmess('\tWrote C/API module "%s" to file "%s"\n' % (m['name'], fn)) + + if options['dorestdoc']: + fn = os.path.join( + options['buildpath'], vrd['modulename'] + 'module.rest') + with open(fn, 'w') as f: + f.write('.. -*- rest -*-\n') + f.write('\n'.join(ar['restdoc'])) + outmess('\tReST Documentation is saved to file "%s/%smodule.rest"\n' % + (options['buildpath'], vrd['modulename'])) + if options['dolatexdoc']: + fn = os.path.join( + options['buildpath'], vrd['modulename'] + 'module.tex') + ret['ltx'] = fn + with open(fn, 'w') as f: + f.write( + '%% This file is auto-generated with f2py (version:%s)\n' % (f2py_version)) + if 'shortlatex' not in options: + f.write( + '\\documentclass{article}\n\\usepackage{a4wide}\n\\begin{document}\n\\tableofcontents\n\n') + f.write('\n'.join(ar['latexdoc'])) + if 'shortlatex' not in options: + f.write('\\end{document}') + outmess('\tDocumentation is saved to file "%s/%smodule.tex"\n' % + (options['buildpath'], vrd['modulename'])) + if funcwrappers: + wn = os.path.join(options['buildpath'], vrd['f2py_wrapper_output']) + ret['fsrc'] = wn + with open(wn, 'w') as f: + f.write('C -*- fortran -*-\n') + f.write( + 'C This file is autogenerated with f2py (version:%s)\n' % (f2py_version)) + f.write( + 'C It contains Fortran 77 wrappers to fortran functions.\n') + lines = [] + for l in ('\n\n'.join(funcwrappers) + '\n').split('\n'): + if 0 <= l.find('!') < 66: + # don't split comment lines + lines.append(l + '\n') + elif l and l[0] == ' ': + while len(l) >= 66: + lines.append(l[:66] + '\n &') + l = l[66:] + lines.append(l + '\n') + else: + lines.append(l + '\n') + lines = ''.join(lines).replace('\n &\n', '\n') + f.write(lines) + outmess('\tFortran 77 wrappers are saved to "%s"\n' % (wn)) + if funcwrappers2: + wn = os.path.join( + options['buildpath'], '%s-f2pywrappers2.f90' % (vrd['modulename'])) + ret['fsrc'] = wn + with open(wn, 'w') as f: + f.write('! -*- f90 -*-\n') + f.write( + '! This file is autogenerated with f2py (version:%s)\n' % (f2py_version)) + f.write( + '! It contains Fortran 90 wrappers to fortran functions.\n') + lines = [] + for l in ('\n\n'.join(funcwrappers2) + '\n').split('\n'): + if 0 <= l.find('!') < 72: + # don't split comment lines + lines.append(l + '\n') + elif len(l) > 72 and l[0] == ' ': + lines.append(l[:72] + '&\n &') + l = l[72:] + while len(l) > 66: + lines.append(l[:66] + '&\n &') + l = l[66:] + lines.append(l + '\n') + else: + lines.append(l + '\n') + lines = ''.join(lines).replace('\n &\n', '\n') + f.write(lines) + outmess('\tFortran 90 wrappers are saved to "%s"\n' % (wn)) + return ret + +################## Build C/API function ############# + +stnd = {1: 'st', 2: 'nd', 3: 'rd', 4: 'th', 5: 'th', + 6: 'th', 7: 'th', 8: 'th', 9: 'th', 0: 'th'} + + +def buildapi(rout): + rout, wrap = func2subr.assubr(rout) + args, depargs = getargs2(rout) + capi_maps.depargs = depargs + var = rout['vars'] + + if ismoduleroutine(rout): + outmess('\t\t\tConstructing wrapper function "%s.%s"...\n' % + (rout['modulename'], rout['name'])) + else: + outmess('\t\tConstructing wrapper function "%s"...\n' % (rout['name'])) + # Routine + vrd = capi_maps.routsign2map(rout) + rd = dictappend({}, vrd) + for r in rout_rules: + if ('_check' in r and r['_check'](rout)) or ('_check' not in r): + ar = applyrules(r, vrd, rout) + rd = dictappend(rd, ar) + + # Args + nth, nthk = 0, 0 + savevrd = {} + for a in args: + vrd = capi_maps.sign2map(a, var[a]) + if isintent_aux(var[a]): + _rules = aux_rules + else: + _rules = arg_rules + if not isintent_hide(var[a]): + if not isoptional(var[a]): + nth = nth + 1 + vrd['nth'] = repr(nth) + stnd[nth % 10] + ' argument' + else: + nthk = nthk + 1 + vrd['nth'] = repr(nthk) + stnd[nthk % 10] + ' keyword' + else: + vrd['nth'] = 'hidden' + savevrd[a] = vrd + for r in _rules: + if '_depend' in r: + continue + if ('_check' in r and r['_check'](var[a])) or ('_check' not in r): + ar = applyrules(r, vrd, var[a]) + rd = dictappend(rd, ar) + if '_break' in r: + break + for a in depargs: + if isintent_aux(var[a]): + _rules = aux_rules + else: + _rules = arg_rules + vrd = savevrd[a] + for r in _rules: + if '_depend' not in r: + continue + if ('_check' in r and r['_check'](var[a])) or ('_check' not in r): + ar = applyrules(r, vrd, var[a]) + rd = dictappend(rd, ar) + if '_break' in r: + break + if 'check' in var[a]: + for c in var[a]['check']: + vrd['check'] = c + ar = applyrules(check_rules, vrd, var[a]) + rd = dictappend(rd, ar) + if isinstance(rd['cleanupfrompyobj'], list): + rd['cleanupfrompyobj'].reverse() + if isinstance(rd['closepyobjfrom'], list): + rd['closepyobjfrom'].reverse() + rd['docsignature'] = stripcomma(replace('#docsign##docsignopt##docsignxa#', + {'docsign': rd['docsign'], + 'docsignopt': rd['docsignopt'], + 'docsignxa': rd['docsignxa']})) + optargs = stripcomma(replace('#docsignopt##docsignxa#', + {'docsignxa': rd['docsignxashort'], + 'docsignopt': rd['docsignoptshort']} + )) + if optargs == '': + rd['docsignatureshort'] = stripcomma( + replace('#docsign#', {'docsign': rd['docsign']})) + else: + rd['docsignatureshort'] = replace('#docsign#[#docsignopt#]', + {'docsign': rd['docsign'], + 'docsignopt': optargs, + }) + rd['latexdocsignatureshort'] = rd['docsignatureshort'].replace('_', '\\_') + rd['latexdocsignatureshort'] = rd[ + 'latexdocsignatureshort'].replace(',', ', ') + cfs = stripcomma(replace('#callfortran##callfortranappend#', { + 'callfortran': rd['callfortran'], 'callfortranappend': rd['callfortranappend']})) + if len(rd['callfortranappend']) > 1: + rd['callcompaqfortran'] = stripcomma(replace('#callfortran# 0,#callfortranappend#', { + 'callfortran': rd['callfortran'], 'callfortranappend': rd['callfortranappend']})) + else: + rd['callcompaqfortran'] = cfs + rd['callfortran'] = cfs + if isinstance(rd['docreturn'], list): + rd['docreturn'] = stripcomma( + replace('#docreturn#', {'docreturn': rd['docreturn']})) + ' = ' + rd['docstrsigns'] = [] + rd['latexdocstrsigns'] = [] + for k in ['docstrreq', 'docstropt', 'docstrout', 'docstrcbs']: + if k in rd and isinstance(rd[k], list): + rd['docstrsigns'] = rd['docstrsigns'] + rd[k] + k = 'latex' + k + if k in rd and isinstance(rd[k], list): + rd['latexdocstrsigns'] = rd['latexdocstrsigns'] + rd[k][0:1] +\ + ['\\begin{description}'] + rd[k][1:] +\ + ['\\end{description}'] + + ar = applyrules(routine_rules, rd) + if ismoduleroutine(rout): + outmess('\t\t\t %s\n' % (ar['docshort'])) + else: + outmess('\t\t %s\n' % (ar['docshort'])) + return ar, wrap + + +#################### EOF rules.py ####################### diff --git a/venv/Lib/site-packages/numpy/f2py/setup.py b/venv/Lib/site-packages/numpy/f2py/setup.py new file mode 100644 index 0000000..0a35db4 --- /dev/null +++ b/venv/Lib/site-packages/numpy/f2py/setup.py @@ -0,0 +1,73 @@ +#!/usr/bin/env python3 +""" +setup.py for installing F2PY + +Usage: + pip install . + +Copyright 2001-2005 Pearu Peterson all rights reserved, +Pearu Peterson +Permission to use, modify, and distribute this software is given under the +terms of the NumPy License. + +NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. +$Revision: 1.32 $ +$Date: 2005/01/30 17:22:14 $ +Pearu Peterson + +""" +from numpy.distutils.core import setup +from numpy.distutils.misc_util import Configuration + + +from __version__ import version + + +def configuration(parent_package='', top_path=None): + config = Configuration('f2py', parent_package, top_path) + config.add_subpackage('tests') + config.add_data_dir('tests/src') + config.add_data_files( + 'src/fortranobject.c', + 'src/fortranobject.h') + config.add_data_files('*.pyi') + return config + + +if __name__ == "__main__": + + config = configuration(top_path='') + config = config.todict() + + config['download_url'] = "http://cens.ioc.ee/projects/f2py2e/2.x"\ + "/F2PY-2-latest.tar.gz" + config['classifiers'] = [ + 'Development Status :: 5 - Production/Stable', + 'Intended Audience :: Developers', + 'Intended Audience :: Science/Research', + 'License :: OSI Approved :: NumPy License', + 'Natural Language :: English', + 'Operating System :: OS Independent', + 'Programming Language :: C', + 'Programming Language :: Fortran', + 'Programming Language :: Python', + 'Topic :: Scientific/Engineering', + 'Topic :: Software Development :: Code Generators', + ] + setup(version=version, + description="F2PY - Fortran to Python Interface Generator", + author="Pearu Peterson", + author_email="pearu@cens.ioc.ee", + maintainer="Pearu Peterson", + maintainer_email="pearu@cens.ioc.ee", + license="BSD", + platforms="Unix, Windows (mingw|cygwin), Mac OSX", + long_description="""\ +The Fortran to Python Interface Generator, or F2PY for short, is a +command line tool (f2py) for generating Python C/API modules for +wrapping Fortran 77/90/95 subroutines, accessing common blocks from +Python, and calling Python functions from Fortran (call-backs). +Interfacing subroutines/data from Fortran 90/95 modules is supported.""", + url="http://cens.ioc.ee/projects/f2py2e/", + keywords=['Fortran', 'f2py'], + **config) diff --git a/venv/Lib/site-packages/numpy/f2py/src/fortranobject.c b/venv/Lib/site-packages/numpy/f2py/src/fortranobject.c new file mode 100644 index 0000000..b9ef187 --- /dev/null +++ b/venv/Lib/site-packages/numpy/f2py/src/fortranobject.c @@ -0,0 +1,1107 @@ +#define FORTRANOBJECT_C +#include "fortranobject.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +/* + This file implements: FortranObject, array_from_pyobj, copy_ND_array + + Author: Pearu Peterson + $Revision: 1.52 $ + $Date: 2005/07/11 07:44:20 $ +*/ + +int +F2PyDict_SetItemString(PyObject *dict, char *name, PyObject *obj) +{ + if (obj==NULL) { + fprintf(stderr, "Error loading %s\n", name); + if (PyErr_Occurred()) { + PyErr_Print(); + PyErr_Clear(); + } + return -1; + } + return PyDict_SetItemString(dict, name, obj); +} + +/* + * Python-only fallback for thread-local callback pointers + */ +void *F2PySwapThreadLocalCallbackPtr(char *key, void *ptr) +{ + PyObject *local_dict, *value; + void *prev; + + local_dict = PyThreadState_GetDict(); + if (local_dict == NULL) { + Py_FatalError("F2PySwapThreadLocalCallbackPtr: PyThreadState_GetDict failed"); + } + + value = PyDict_GetItemString(local_dict, key); + if (value != NULL) { + prev = PyLong_AsVoidPtr(value); + if (PyErr_Occurred()) { + Py_FatalError("F2PySwapThreadLocalCallbackPtr: PyLong_AsVoidPtr failed"); + } + } + else { + prev = NULL; + } + + value = PyLong_FromVoidPtr((void *)ptr); + if (value == NULL) { + Py_FatalError("F2PySwapThreadLocalCallbackPtr: PyLong_FromVoidPtr failed"); + } + + if (PyDict_SetItemString(local_dict, key, value) != 0) { + Py_FatalError("F2PySwapThreadLocalCallbackPtr: PyDict_SetItemString failed"); + } + + Py_DECREF(value); + + return prev; +} + +void *F2PyGetThreadLocalCallbackPtr(char *key) +{ + PyObject *local_dict, *value; + void *prev; + + local_dict = PyThreadState_GetDict(); + if (local_dict == NULL) { + Py_FatalError("F2PyGetThreadLocalCallbackPtr: PyThreadState_GetDict failed"); + } + + value = PyDict_GetItemString(local_dict, key); + if (value != NULL) { + prev = PyLong_AsVoidPtr(value); + if (PyErr_Occurred()) { + Py_FatalError("F2PyGetThreadLocalCallbackPtr: PyLong_AsVoidPtr failed"); + } + } + else { + prev = NULL; + } + + return prev; +} + +/************************* FortranObject *******************************/ + +typedef PyObject *(*fortranfunc)(PyObject *,PyObject *,PyObject *,void *); + +PyObject * +PyFortranObject_New(FortranDataDef* defs, f2py_void_func init) { + int i; + PyFortranObject *fp = NULL; + PyObject *v = NULL; + if (init!=NULL) { /* Initialize F90 module objects */ + (*(init))(); + } + fp = PyObject_New(PyFortranObject, &PyFortran_Type); + if (fp == NULL) { + return NULL; + } + if ((fp->dict = PyDict_New()) == NULL) { + Py_DECREF(fp); + return NULL; + } + fp->len = 0; + while (defs[fp->len].name != NULL) { + fp->len++; + } + if (fp->len == 0) { + goto fail; + } + fp->defs = defs; + for (i=0;ilen;i++) { + if (fp->defs[i].rank == -1) { /* Is Fortran routine */ + v = PyFortranObject_NewAsAttr(&(fp->defs[i])); + if (v==NULL) { + goto fail; + } + PyDict_SetItemString(fp->dict,fp->defs[i].name,v); + Py_XDECREF(v); + } else + if ((fp->defs[i].data)!=NULL) { /* Is Fortran variable or array (not allocatable) */ + if (fp->defs[i].type == NPY_STRING) { + int n = fp->defs[i].rank-1; + v = PyArray_New(&PyArray_Type, n, fp->defs[i].dims.d, + NPY_STRING, NULL, fp->defs[i].data, fp->defs[i].dims.d[n], + NPY_ARRAY_FARRAY, NULL); + } + else { + v = PyArray_New(&PyArray_Type, fp->defs[i].rank, fp->defs[i].dims.d, + fp->defs[i].type, NULL, fp->defs[i].data, 0, NPY_ARRAY_FARRAY, + NULL); + } + if (v==NULL) { + goto fail; + } + PyDict_SetItemString(fp->dict,fp->defs[i].name,v); + Py_XDECREF(v); + } + } + return (PyObject *)fp; + fail: + Py_XDECREF(fp); + return NULL; +} + +PyObject * +PyFortranObject_NewAsAttr(FortranDataDef* defs) { /* used for calling F90 module routines */ + PyFortranObject *fp = NULL; + fp = PyObject_New(PyFortranObject, &PyFortran_Type); + if (fp == NULL) return NULL; + if ((fp->dict = PyDict_New())==NULL) { + PyObject_Del(fp); + return NULL; + } + fp->len = 1; + fp->defs = defs; + return (PyObject *)fp; +} + +/* Fortran methods */ + +static void +fortran_dealloc(PyFortranObject *fp) { + Py_XDECREF(fp->dict); + PyObject_Del(fp); +} + + +/* Returns number of bytes consumed from buf, or -1 on error. */ +static Py_ssize_t +format_def(char *buf, Py_ssize_t size, FortranDataDef def) +{ + char *p = buf; + int i, n; + + n = PyOS_snprintf(p, size, "array(%" NPY_INTP_FMT, def.dims.d[0]); + if (n < 0 || n >= size) { + return -1; + } + p += n; + size -= n; + + for (i = 1; i < def.rank; i++) { + n = PyOS_snprintf(p, size, ",%" NPY_INTP_FMT, def.dims.d[i]); + if (n < 0 || n >= size) { + return -1; + } + p += n; + size -= n; + } + + if (size <= 0) { + return -1; + } + + *p++ = ')'; + size--; + + if (def.data == NULL) { + static const char notalloc[] = ", not allocated"; + if ((size_t) size < sizeof(notalloc)) { + return -1; + } + memcpy(p, notalloc, sizeof(notalloc)); + p += sizeof(notalloc); + size -= sizeof(notalloc); + } + + return p - buf; +} + +static PyObject * +fortran_doc(FortranDataDef def) +{ + char *buf, *p; + PyObject *s = NULL; + Py_ssize_t n, origsize, size = 100; + + if (def.doc != NULL) { + size += strlen(def.doc); + } + origsize = size; + buf = p = (char *)PyMem_Malloc(size); + if (buf == NULL) { + return PyErr_NoMemory(); + } + + if (def.rank == -1) { + if (def.doc) { + n = strlen(def.doc); + if (n > size) { + goto fail; + } + memcpy(p, def.doc, n); + p += n; + size -= n; + } + else { + n = PyOS_snprintf(p, size, "%s - no docs available", def.name); + if (n < 0 || n >= size) { + goto fail; + } + p += n; + size -= n; + } + } + else { + PyArray_Descr *d = PyArray_DescrFromType(def.type); + n = PyOS_snprintf(p, size, "%s : '%c'-", def.name, d->type); + Py_DECREF(d); + if (n < 0 || n >= size) { + goto fail; + } + p += n; + size -= n; + + if (def.data == NULL) { + n = format_def(p, size, def); + if (n < 0) { + goto fail; + } + p += n; + size -= n; + } + else if (def.rank > 0) { + n = format_def(p, size, def); + if (n < 0) { + goto fail; + } + p += n; + size -= n; + } + else { + n = strlen("scalar"); + if (size < n) { + goto fail; + } + memcpy(p, "scalar", n); + p += n; + size -= n; + } + + } + if (size <= 1) { + goto fail; + } + *p++ = '\n'; + size--; + + /* p now points one beyond the last character of the string in buf */ + s = PyUnicode_FromStringAndSize(buf, p - buf); + + PyMem_Free(buf); + return s; + + fail: + fprintf(stderr, "fortranobject.c: fortran_doc: len(p)=%zd>%zd=size:" + " too long docstring required, increase size\n", + p - buf, origsize); + PyMem_Free(buf); + return NULL; +} + +static FortranDataDef *save_def; /* save pointer of an allocatable array */ +static void set_data(char *d,npy_intp *f) { /* callback from Fortran */ + if (*f) /* In fortran f=allocated(d) */ + save_def->data = d; + else + save_def->data = NULL; + /* printf("set_data: d=%p,f=%d\n",d,*f); */ +} + +static PyObject * +fortran_getattr(PyFortranObject *fp, char *name) { + int i,j,k,flag; + if (fp->dict != NULL) { + PyObject *v = _PyDict_GetItemStringWithError(fp->dict, name); + if (v == NULL && PyErr_Occurred()) { + return NULL; + } + else if (v != NULL) { + Py_INCREF(v); + return v; + } + } + for (i=0,j=1;ilen && (j=strcmp(name,fp->defs[i].name));i++); + if (j==0) + if (fp->defs[i].rank!=-1) { /* F90 allocatable array */ + if (fp->defs[i].func==NULL) return NULL; + for(k=0;kdefs[i].rank;++k) + fp->defs[i].dims.d[k]=-1; + save_def = &fp->defs[i]; + (*(fp->defs[i].func))(&fp->defs[i].rank,fp->defs[i].dims.d,set_data,&flag); + if (flag==2) + k = fp->defs[i].rank + 1; + else + k = fp->defs[i].rank; + if (fp->defs[i].data !=NULL) { /* array is allocated */ + PyObject *v = PyArray_New(&PyArray_Type, k, fp->defs[i].dims.d, + fp->defs[i].type, NULL, fp->defs[i].data, 0, NPY_ARRAY_FARRAY, + NULL); + if (v==NULL) return NULL; + /* Py_INCREF(v); */ + return v; + } else { /* array is not allocated */ + Py_RETURN_NONE; + } + } + if (strcmp(name,"__dict__")==0) { + Py_INCREF(fp->dict); + return fp->dict; + } + if (strcmp(name,"__doc__")==0) { + PyObject *s = PyUnicode_FromString(""), *s2, *s3; + for (i=0;ilen;i++) { + s2 = fortran_doc(fp->defs[i]); + s3 = PyUnicode_Concat(s, s2); + Py_DECREF(s2); + Py_DECREF(s); + s = s3; + } + if (PyDict_SetItemString(fp->dict, name, s)) + return NULL; + return s; + } + if ((strcmp(name,"_cpointer")==0) && (fp->len==1)) { + PyObject *cobj = F2PyCapsule_FromVoidPtr((void *)(fp->defs[0].data),NULL); + if (PyDict_SetItemString(fp->dict, name, cobj)) + return NULL; + return cobj; + } + PyObject *str, *ret; + str = PyUnicode_FromString(name); + ret = PyObject_GenericGetAttr((PyObject *)fp, str); + Py_DECREF(str); + return ret; +} + +static int +fortran_setattr(PyFortranObject *fp, char *name, PyObject *v) { + int i,j,flag; + PyArrayObject *arr = NULL; + for (i=0,j=1;ilen && (j=strcmp(name,fp->defs[i].name));i++); + if (j==0) { + if (fp->defs[i].rank==-1) { + PyErr_SetString(PyExc_AttributeError,"over-writing fortran routine"); + return -1; + } + if (fp->defs[i].func!=NULL) { /* is allocatable array */ + npy_intp dims[F2PY_MAX_DIMS]; + int k; + save_def = &fp->defs[i]; + if (v!=Py_None) { /* set new value (reallocate if needed -- + see f2py generated code for more + details ) */ + for(k=0;kdefs[i].rank;k++) dims[k]=-1; + if ((arr = array_from_pyobj(fp->defs[i].type,dims,fp->defs[i].rank,F2PY_INTENT_IN,v))==NULL) + return -1; + (*(fp->defs[i].func))(&fp->defs[i].rank,PyArray_DIMS(arr),set_data,&flag); + } else { /* deallocate */ + for(k=0;kdefs[i].rank;k++) dims[k]=0; + (*(fp->defs[i].func))(&fp->defs[i].rank,dims,set_data,&flag); + for(k=0;kdefs[i].rank;k++) dims[k]=-1; + } + memcpy(fp->defs[i].dims.d,dims,fp->defs[i].rank*sizeof(npy_intp)); + } else { /* not allocatable array */ + if ((arr = array_from_pyobj(fp->defs[i].type,fp->defs[i].dims.d,fp->defs[i].rank,F2PY_INTENT_IN,v))==NULL) + return -1; + } + if (fp->defs[i].data!=NULL) { /* copy Python object to Fortran array */ + npy_intp s = PyArray_MultiplyList(fp->defs[i].dims.d,PyArray_NDIM(arr)); + if (s==-1) + s = PyArray_MultiplyList(PyArray_DIMS(arr),PyArray_NDIM(arr)); + if (s<0 || + (memcpy(fp->defs[i].data,PyArray_DATA(arr),s*PyArray_ITEMSIZE(arr)))==NULL) { + if ((PyObject*)arr!=v) { + Py_DECREF(arr); + } + return -1; + } + if ((PyObject*)arr!=v) { + Py_DECREF(arr); + } + } else return (fp->defs[i].func==NULL?-1:0); + return 0; /* successful */ + } + if (fp->dict == NULL) { + fp->dict = PyDict_New(); + if (fp->dict == NULL) + return -1; + } + if (v == NULL) { + int rv = PyDict_DelItemString(fp->dict, name); + if (rv < 0) + PyErr_SetString(PyExc_AttributeError,"delete non-existing fortran attribute"); + return rv; + } + else + return PyDict_SetItemString(fp->dict, name, v); +} + +static PyObject* +fortran_call(PyFortranObject *fp, PyObject *arg, PyObject *kw) { + int i = 0; + /* printf("fortran call + name=%s,func=%p,data=%p,%p\n",fp->defs[i].name, + fp->defs[i].func,fp->defs[i].data,&fp->defs[i].data); */ + if (fp->defs[i].rank==-1) {/* is Fortran routine */ + if (fp->defs[i].func==NULL) { + PyErr_Format(PyExc_RuntimeError, "no function to call"); + return NULL; + } + else if (fp->defs[i].data==NULL) + /* dummy routine */ + return (*((fortranfunc)(fp->defs[i].func)))((PyObject *)fp,arg,kw,NULL); + else + return (*((fortranfunc)(fp->defs[i].func)))((PyObject *)fp,arg,kw, + (void *)fp->defs[i].data); + } + PyErr_Format(PyExc_TypeError, "this fortran object is not callable"); + return NULL; +} + +static PyObject * +fortran_repr(PyFortranObject *fp) +{ + PyObject *name = NULL, *repr = NULL; + name = PyObject_GetAttrString((PyObject *)fp, "__name__"); + PyErr_Clear(); + if (name != NULL && PyUnicode_Check(name)) { + repr = PyUnicode_FromFormat("", name); + } + else { + repr = PyUnicode_FromString(""); + } + Py_XDECREF(name); + return repr; +} + + +PyTypeObject PyFortran_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + .tp_name ="fortran", + .tp_basicsize = sizeof(PyFortranObject), + .tp_dealloc = (destructor)fortran_dealloc, + .tp_getattr = (getattrfunc)fortran_getattr, + .tp_setattr = (setattrfunc)fortran_setattr, + .tp_repr = (reprfunc)fortran_repr, + .tp_call = (ternaryfunc)fortran_call, +}; + +/************************* f2py_report_atexit *******************************/ + +#ifdef F2PY_REPORT_ATEXIT +static int passed_time = 0; +static int passed_counter = 0; +static int passed_call_time = 0; +static struct timeb start_time; +static struct timeb stop_time; +static struct timeb start_call_time; +static struct timeb stop_call_time; +static int cb_passed_time = 0; +static int cb_passed_counter = 0; +static int cb_passed_call_time = 0; +static struct timeb cb_start_time; +static struct timeb cb_stop_time; +static struct timeb cb_start_call_time; +static struct timeb cb_stop_call_time; + +extern void f2py_start_clock(void) { ftime(&start_time); } +extern +void f2py_start_call_clock(void) { + f2py_stop_clock(); + ftime(&start_call_time); +} +extern +void f2py_stop_clock(void) { + ftime(&stop_time); + passed_time += 1000*(stop_time.time - start_time.time); + passed_time += stop_time.millitm - start_time.millitm; +} +extern +void f2py_stop_call_clock(void) { + ftime(&stop_call_time); + passed_call_time += 1000*(stop_call_time.time - start_call_time.time); + passed_call_time += stop_call_time.millitm - start_call_time.millitm; + passed_counter += 1; + f2py_start_clock(); +} + +extern void f2py_cb_start_clock(void) { ftime(&cb_start_time); } +extern +void f2py_cb_start_call_clock(void) { + f2py_cb_stop_clock(); + ftime(&cb_start_call_time); +} +extern +void f2py_cb_stop_clock(void) { + ftime(&cb_stop_time); + cb_passed_time += 1000*(cb_stop_time.time - cb_start_time.time); + cb_passed_time += cb_stop_time.millitm - cb_start_time.millitm; +} +extern +void f2py_cb_stop_call_clock(void) { + ftime(&cb_stop_call_time); + cb_passed_call_time += 1000*(cb_stop_call_time.time - cb_start_call_time.time); + cb_passed_call_time += cb_stop_call_time.millitm - cb_start_call_time.millitm; + cb_passed_counter += 1; + f2py_cb_start_clock(); +} + +static int f2py_report_on_exit_been_here = 0; +extern +void f2py_report_on_exit(int exit_flag,void *name) { + if (f2py_report_on_exit_been_here) { + fprintf(stderr," %s\n",(char*)name); + return; + } + f2py_report_on_exit_been_here = 1; + fprintf(stderr," /-----------------------\\\n"); + fprintf(stderr," < F2PY performance report >\n"); + fprintf(stderr," \\-----------------------/\n"); + fprintf(stderr,"Overall time spent in ...\n"); + fprintf(stderr,"(a) wrapped (Fortran/C) functions : %8d msec\n", + passed_call_time); + fprintf(stderr,"(b) f2py interface, %6d calls : %8d msec\n", + passed_counter,passed_time); + fprintf(stderr,"(c) call-back (Python) functions : %8d msec\n", + cb_passed_call_time); + fprintf(stderr,"(d) f2py call-back interface, %6d calls : %8d msec\n", + cb_passed_counter,cb_passed_time); + + fprintf(stderr,"(e) wrapped (Fortran/C) functions (actual) : %8d msec\n\n", + passed_call_time-cb_passed_call_time-cb_passed_time); + fprintf(stderr,"Use -DF2PY_REPORT_ATEXIT_DISABLE to disable this message.\n"); + fprintf(stderr,"Exit status: %d\n",exit_flag); + fprintf(stderr,"Modules : %s\n",(char*)name); +} +#endif + +/********************** report on array copy ****************************/ + +#ifdef F2PY_REPORT_ON_ARRAY_COPY +static void f2py_report_on_array_copy(PyArrayObject* arr) { + const npy_intp arr_size = PyArray_Size((PyObject *)arr); + if (arr_size>F2PY_REPORT_ON_ARRAY_COPY) { + fprintf(stderr,"copied an array: size=%ld, elsize=%"NPY_INTP_FMT"\n", + arr_size, (npy_intp)PyArray_ITEMSIZE(arr)); + } +} +static void f2py_report_on_array_copy_fromany(void) { + fprintf(stderr,"created an array from object\n"); +} + +#define F2PY_REPORT_ON_ARRAY_COPY_FROMARR f2py_report_on_array_copy((PyArrayObject *)arr) +#define F2PY_REPORT_ON_ARRAY_COPY_FROMANY f2py_report_on_array_copy_fromany() +#else +#define F2PY_REPORT_ON_ARRAY_COPY_FROMARR +#define F2PY_REPORT_ON_ARRAY_COPY_FROMANY +#endif + + +/************************* array_from_obj *******************************/ + +/* + * File: array_from_pyobj.c + * + * Description: + * ------------ + * Provides array_from_pyobj function that returns a contiguous array + * object with the given dimensions and required storage order, either + * in row-major (C) or column-major (Fortran) order. The function + * array_from_pyobj is very flexible about its Python object argument + * that can be any number, list, tuple, or array. + * + * array_from_pyobj is used in f2py generated Python extension + * modules. + * + * Author: Pearu Peterson + * Created: 13-16 January 2002 + * $Id: fortranobject.c,v 1.52 2005/07/11 07:44:20 pearu Exp $ + */ + +static int check_and_fix_dimensions(const PyArrayObject* arr, + const int rank, + npy_intp *dims); + +static int +count_negative_dimensions(const int rank, + const npy_intp *dims) { + int i=0,r=0; + while (iflags,size); + printf("\tstrides = "); + dump_dims(rank,arr->strides); + printf("\tdimensions = "); + dump_dims(rank,arr->dimensions); +} +#endif + +#define SWAPTYPE(a,b,t) {t c; c = (a); (a) = (b); (b) = c; } + +static int swap_arrays(PyArrayObject* obj1, PyArrayObject* obj2) { + PyArrayObject_fields *arr1 = (PyArrayObject_fields*) obj1, + *arr2 = (PyArrayObject_fields*) obj2; + SWAPTYPE(arr1->data,arr2->data,char*); + SWAPTYPE(arr1->nd,arr2->nd,int); + SWAPTYPE(arr1->dimensions,arr2->dimensions,npy_intp*); + SWAPTYPE(arr1->strides,arr2->strides,npy_intp*); + SWAPTYPE(arr1->base,arr2->base,PyObject*); + SWAPTYPE(arr1->descr,arr2->descr,PyArray_Descr*); + SWAPTYPE(arr1->flags,arr2->flags,int); + /* SWAPTYPE(arr1->weakreflist,arr2->weakreflist,PyObject*); */ + return 0; +} + +#define ARRAY_ISCOMPATIBLE(arr,type_num) \ + ( (PyArray_ISINTEGER(arr) && PyTypeNum_ISINTEGER(type_num)) \ + ||(PyArray_ISFLOAT(arr) && PyTypeNum_ISFLOAT(type_num)) \ + ||(PyArray_ISCOMPLEX(arr) && PyTypeNum_ISCOMPLEX(type_num)) \ + ||(PyArray_ISBOOL(arr) && PyTypeNum_ISBOOL(type_num)) \ + ) + +extern +PyArrayObject* array_from_pyobj(const int type_num, + npy_intp *dims, + const int rank, + const int intent, + PyObject *obj) { + /* + * Note about reference counting + * ----------------------------- + * If the caller returns the array to Python, it must be done with + * Py_BuildValue("N",arr). + * Otherwise, if obj!=arr then the caller must call Py_DECREF(arr). + * + * Note on intent(cache,out,..) + * --------------------- + * Don't expect correct data when returning intent(cache) array. + * + */ + char mess[200]; + PyArrayObject *arr = NULL; + PyArray_Descr *descr; + char typechar; + int elsize; + + if ((intent & F2PY_INTENT_HIDE) + || ((intent & F2PY_INTENT_CACHE) && (obj==Py_None)) + || ((intent & F2PY_OPTIONAL) && (obj==Py_None)) + ) { + /* intent(cache), optional, intent(hide) */ + if (count_negative_dimensions(rank,dims) > 0) { + int i; + strcpy(mess, "failed to create intent(cache|hide)|optional array" + "-- must have defined dimensions but got ("); + for(i=0;ielsize = 1; + descr->type = NPY_CHARLTR; + } + elsize = descr->elsize; + typechar = descr->type; + Py_DECREF(descr); + if (PyArray_Check(obj)) { + arr = (PyArrayObject *)obj; + + if (intent & F2PY_INTENT_CACHE) { + /* intent(cache) */ + if (PyArray_ISONESEGMENT(arr) + && PyArray_ITEMSIZE(arr)>=elsize) { + if (check_and_fix_dimensions(arr, rank, dims)) { + return NULL; + } + if (intent & F2PY_INTENT_OUT) + Py_INCREF(arr); + return arr; + } + strcpy(mess, "failed to initialize intent(cache) array"); + if (!PyArray_ISONESEGMENT(arr)) + strcat(mess, " -- input must be in one segment"); + if (PyArray_ITEMSIZE(arr)type,typechar); + if (!(F2PY_CHECK_ALIGNMENT(arr, intent))) + sprintf(mess+strlen(mess)," -- input not %d-aligned", F2PY_GET_ALIGNMENT(intent)); + PyErr_SetString(PyExc_ValueError,mess); + return NULL; + } + + /* here we have always intent(in) or intent(inplace) */ + + { + PyArrayObject * retarr; + retarr = (PyArrayObject *) \ + PyArray_New(&PyArray_Type, PyArray_NDIM(arr), PyArray_DIMS(arr), type_num, + NULL,NULL,1, + !(intent&F2PY_INTENT_C), + NULL); + if (retarr==NULL) + return NULL; + F2PY_REPORT_ON_ARRAY_COPY_FROMARR; + if (PyArray_CopyInto(retarr, arr)) { + Py_DECREF(retarr); + return NULL; + } + if (intent & F2PY_INTENT_INPLACE) { + if (swap_arrays(arr,retarr)) + return NULL; /* XXX: set exception */ + Py_XDECREF(retarr); + if (intent & F2PY_INTENT_OUT) + Py_INCREF(arr); + } else { + arr = retarr; + } + } + return arr; + } + + if ((intent & F2PY_INTENT_INOUT) || + (intent & F2PY_INTENT_INPLACE) || + (intent & F2PY_INTENT_CACHE)) { + PyErr_Format(PyExc_TypeError, + "failed to initialize intent(inout|inplace|cache) " + "array, input '%s' object is not an array", + Py_TYPE(obj)->tp_name); + return NULL; + } + + { + PyArray_Descr * descr = PyArray_DescrFromType(type_num); + /* compatibility with NPY_CHAR */ + if (type_num == NPY_STRING) { + PyArray_DESCR_REPLACE(descr); + if (descr == NULL) { + return NULL; + } + descr->elsize = 1; + descr->type = NPY_CHARLTR; + } + F2PY_REPORT_ON_ARRAY_COPY_FROMANY; + arr = (PyArrayObject *) \ + PyArray_FromAny(obj, descr, 0,0, + ((intent & F2PY_INTENT_C)?NPY_ARRAY_CARRAY:NPY_ARRAY_FARRAY) \ + | NPY_ARRAY_FORCECAST, NULL); + if (arr==NULL) + return NULL; + if (check_and_fix_dimensions(arr, rank, dims)) { + return NULL; + } + return arr; + } + +} + +/*****************************************/ +/* Helper functions for array_from_pyobj */ +/*****************************************/ + +static +int check_and_fix_dimensions(const PyArrayObject* arr, const int rank, npy_intp *dims) +{ + /* + * This function fills in blanks (that are -1's) in dims list using + * the dimensions from arr. It also checks that non-blank dims will + * match with the corresponding values in arr dimensions. + * + * Returns 0 if the function is successful. + * + * If an error condition is detected, an exception is set and 1 is returned. + */ + const npy_intp arr_size = (PyArray_NDIM(arr))?PyArray_Size((PyObject *)arr):1; +#ifdef DEBUG_COPY_ND_ARRAY + dump_attrs(arr); + printf("check_and_fix_dimensions:init: dims="); + dump_dims(rank,dims); +#endif + if (rank > PyArray_NDIM(arr)) { /* [1,2] -> [[1],[2]]; 1 -> [[1]] */ + npy_intp new_size = 1; + int free_axe = -1; + int i; + npy_intp d; + /* Fill dims where -1 or 0; check dimensions; calc new_size; */ + for(i=0;i= 0) { + if (d>1 && dims[i]!=d) { + PyErr_Format(PyExc_ValueError, + "%d-th dimension must be fixed to %" + NPY_INTP_FMT " but got %" NPY_INTP_FMT "\n", + i, dims[i], d); + return 1; + } + if (!dims[i]) dims[i] = 1; + } else { + dims[i] = d ? d : 1; + } + new_size *= dims[i]; + } + for(i=PyArray_NDIM(arr);i1) { + PyErr_Format(PyExc_ValueError, + "%d-th dimension must be %" NPY_INTP_FMT + " but got 0 (not defined).\n", + i, dims[i]); + return 1; + } else if (free_axe<0) + free_axe = i; + else + dims[i] = 1; + if (free_axe>=0) { + dims[free_axe] = arr_size/new_size; + new_size *= dims[free_axe]; + } + if (new_size != arr_size) { + PyErr_Format(PyExc_ValueError, + "unexpected array size: new_size=%" NPY_INTP_FMT + ", got array with arr_size=%" NPY_INTP_FMT + " (maybe too many free indices)\n", + new_size, arr_size); + return 1; + } + } else if (rank==PyArray_NDIM(arr)) { + npy_intp new_size = 1; + int i; + npy_intp d; + for (i=0; i=0) { + if (d > 1 && d!=dims[i]) { + PyErr_Format(PyExc_ValueError, + "%d-th dimension must be fixed to %" + NPY_INTP_FMT " but got %" NPY_INTP_FMT "\n", + i, dims[i], d); + return 1; + } + if (!dims[i]) dims[i] = 1; + } else dims[i] = d; + new_size *= dims[i]; + } + if (new_size != arr_size) { + PyErr_Format(PyExc_ValueError, + "unexpected array size: new_size=%" NPY_INTP_FMT + ", got array with arr_size=%" NPY_INTP_FMT "\n", + new_size, arr_size); + return 1; + } + } else { /* [[1,2]] -> [[1],[2]] */ + int i,j; + npy_intp d; + int effrank; + npy_intp size; + for (i=0,effrank=0;i1) ++effrank; + if (dims[rank-1]>=0) + if (effrank>rank) { + PyErr_Format(PyExc_ValueError, + "too many axes: %d (effrank=%d), " + "expected rank=%d\n", + PyArray_NDIM(arr), effrank, rank); + return 1; + } + + for (i=0,j=0;i=PyArray_NDIM(arr)) d = 1; + else d = PyArray_DIM(arr,j++); + if (dims[i]>=0) { + if (d>1 && d!=dims[i]) { + PyErr_Format(PyExc_ValueError, + "%d-th dimension must be fixed to %" + NPY_INTP_FMT " but got %" NPY_INTP_FMT + " (real index=%d)\n", + i, dims[i], d, j-1); + return 1; + } + if (!dims[i]) dims[i] = 1; + } else + dims[i] = d; + } + + for (i=rank;i [1,2,3,4] */ + while (j=PyArray_NDIM(arr)) d = 1; + else d = PyArray_DIM(arr,j++); + dims[rank-1] *= d; + } + for (i=0,size=1;i + extern void f2py_start_clock(void); + extern void f2py_stop_clock(void); + extern void f2py_start_call_clock(void); + extern void f2py_stop_call_clock(void); + extern void f2py_cb_start_clock(void); + extern void f2py_cb_stop_clock(void); + extern void f2py_cb_start_call_clock(void); + extern void f2py_cb_stop_call_clock(void); + extern void f2py_report_on_exit(int,void*); +#endif + +#ifdef DMALLOC +#include "dmalloc.h" +#endif + +/* Fortran object interface */ + +/* +123456789-123456789-123456789-123456789-123456789-123456789-123456789-12 + +PyFortranObject represents various Fortran objects: +Fortran (module) routines, COMMON blocks, module data. + +Author: Pearu Peterson +*/ + +#define F2PY_MAX_DIMS 40 + +typedef void (*f2py_set_data_func)(char*,npy_intp*); +typedef void (*f2py_void_func)(void); +typedef void (*f2py_init_func)(int*,npy_intp*,f2py_set_data_func,int*); + + /*typedef void* (*f2py_c_func)(void*,...);*/ + +typedef void *(*f2pycfunc)(void); + +typedef struct { + char *name; /* attribute (array||routine) name */ + int rank; /* array rank, 0 for scalar, max is F2PY_MAX_DIMS, + || rank=-1 for Fortran routine */ + struct {npy_intp d[F2PY_MAX_DIMS];} dims; /* dimensions of the array, || not used */ + int type; /* PyArray_ || not used */ + char *data; /* pointer to array || Fortran routine */ + f2py_init_func func; /* initialization function for + allocatable arrays: + func(&rank,dims,set_ptr_func,name,len(name)) + || C/API wrapper for Fortran routine */ + char *doc; /* documentation string; only recommended + for routines. */ +} FortranDataDef; + +typedef struct { + PyObject_HEAD + int len; /* Number of attributes */ + FortranDataDef *defs; /* An array of FortranDataDef's */ + PyObject *dict; /* Fortran object attribute dictionary */ +} PyFortranObject; + +#define PyFortran_Check(op) (Py_TYPE(op) == &PyFortran_Type) +#define PyFortran_Check1(op) (0==strcmp(Py_TYPE(op)->tp_name,"fortran")) + + extern PyTypeObject PyFortran_Type; + extern int F2PyDict_SetItemString(PyObject* dict, char *name, PyObject *obj); + extern PyObject * PyFortranObject_New(FortranDataDef* defs, f2py_void_func init); + extern PyObject * PyFortranObject_NewAsAttr(FortranDataDef* defs); + +PyObject * F2PyCapsule_FromVoidPtr(void *ptr, void (*dtor)(PyObject *)); +void * F2PyCapsule_AsVoidPtr(PyObject *obj); +int F2PyCapsule_Check(PyObject *ptr); + +extern void *F2PySwapThreadLocalCallbackPtr(char *key, void *ptr); +extern void *F2PyGetThreadLocalCallbackPtr(char *key); + +#define ISCONTIGUOUS(m) (PyArray_FLAGS(m) & NPY_ARRAY_C_CONTIGUOUS) +#define F2PY_INTENT_IN 1 +#define F2PY_INTENT_INOUT 2 +#define F2PY_INTENT_OUT 4 +#define F2PY_INTENT_HIDE 8 +#define F2PY_INTENT_CACHE 16 +#define F2PY_INTENT_COPY 32 +#define F2PY_INTENT_C 64 +#define F2PY_OPTIONAL 128 +#define F2PY_INTENT_INPLACE 256 +#define F2PY_INTENT_ALIGNED4 512 +#define F2PY_INTENT_ALIGNED8 1024 +#define F2PY_INTENT_ALIGNED16 2048 + +#define ARRAY_ISALIGNED(ARR, SIZE) ((size_t)(PyArray_DATA(ARR)) % (SIZE) == 0) +#define F2PY_ALIGN4(intent) (intent & F2PY_INTENT_ALIGNED4) +#define F2PY_ALIGN8(intent) (intent & F2PY_INTENT_ALIGNED8) +#define F2PY_ALIGN16(intent) (intent & F2PY_INTENT_ALIGNED16) + +#define F2PY_GET_ALIGNMENT(intent) \ + (F2PY_ALIGN4(intent) ? 4 : \ + (F2PY_ALIGN8(intent) ? 8 : \ + (F2PY_ALIGN16(intent) ? 16 : 1) )) +#define F2PY_CHECK_ALIGNMENT(arr, intent) ARRAY_ISALIGNED(arr, F2PY_GET_ALIGNMENT(intent)) + + extern PyArrayObject* array_from_pyobj(const int type_num, + npy_intp *dims, + const int rank, + const int intent, + PyObject *obj); + extern int copy_ND_array(const PyArrayObject *in, PyArrayObject *out); + +#ifdef DEBUG_COPY_ND_ARRAY + extern void dump_attrs(const PyArrayObject* arr); +#endif + + +#ifdef __cplusplus +} +#endif +#endif /* !Py_FORTRANOBJECT_H */ diff --git a/venv/Lib/site-packages/numpy/f2py/tests/__init__.py b/venv/Lib/site-packages/numpy/f2py/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/venv/Lib/site-packages/numpy/f2py/tests/src/array_from_pyobj/wrapmodule.c b/venv/Lib/site-packages/numpy/f2py/tests/src/array_from_pyobj/wrapmodule.c new file mode 100644 index 0000000..0411b62 --- /dev/null +++ b/venv/Lib/site-packages/numpy/f2py/tests/src/array_from_pyobj/wrapmodule.c @@ -0,0 +1,228 @@ +/* + * This file was auto-generated with f2py (version:2_1330) and hand edited by + * Pearu for testing purposes. Do not edit this file unless you know what you + * are doing!!! + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/*********************** See f2py2e/cfuncs.py: includes ***********************/ +#include "Python.h" +#include "fortranobject.h" +#include + +static PyObject *wrap_error; +static PyObject *wrap_module; + +/************************************ call ************************************/ +static char doc_f2py_rout_wrap_call[] = "\ +Function signature:\n\ + arr = call(type_num,dims,intent,obj)\n\ +Required arguments:\n" +" type_num : input int\n" +" dims : input int-sequence\n" +" intent : input int\n" +" obj : input python object\n" +"Return objects:\n" +" arr : array"; +static PyObject *f2py_rout_wrap_call(PyObject *capi_self, + PyObject *capi_args) { + PyObject * volatile capi_buildvalue = NULL; + int type_num = 0; + npy_intp *dims = NULL; + PyObject *dims_capi = Py_None; + int rank = 0; + int intent = 0; + PyArrayObject *capi_arr_tmp = NULL; + PyObject *arr_capi = Py_None; + int i; + + if (!PyArg_ParseTuple(capi_args,"iOiO|:wrap.call",\ + &type_num,&dims_capi,&intent,&arr_capi)) + return NULL; + rank = PySequence_Length(dims_capi); + dims = malloc(rank*sizeof(npy_intp)); + for (i=0;ikind, + PyArray_DESCR(arr)->type, + PyArray_TYPE(arr), + PyArray_ITEMSIZE(arr), + PyArray_DESCR(arr)->alignment, + PyArray_FLAGS(arr), + PyArray_ITEMSIZE(arr)); +} + +static PyMethodDef f2py_module_methods[] = { + + {"call",f2py_rout_wrap_call,METH_VARARGS,doc_f2py_rout_wrap_call}, + {"array_attrs",f2py_rout_wrap_attrs,METH_VARARGS,doc_f2py_rout_wrap_attrs}, + {NULL,NULL} +}; + +static struct PyModuleDef moduledef = { + PyModuleDef_HEAD_INIT, + "test_array_from_pyobj_ext", + NULL, + -1, + f2py_module_methods, + NULL, + NULL, + NULL, + NULL +}; + +PyMODINIT_FUNC PyInit_test_array_from_pyobj_ext(void) { + PyObject *m,*d, *s; + m = wrap_module = PyModule_Create(&moduledef); + Py_SET_TYPE(&PyFortran_Type, &PyType_Type); + import_array(); + if (PyErr_Occurred()) + Py_FatalError("can't initialize module wrap (failed to import numpy)"); + d = PyModule_GetDict(m); + s = PyUnicode_FromString("This module 'wrap' is auto-generated with f2py (version:2_1330).\nFunctions:\n" + " arr = call(type_num,dims,intent,obj)\n" + "."); + PyDict_SetItemString(d, "__doc__", s); + wrap_error = PyErr_NewException ("wrap.error", NULL, NULL); + Py_DECREF(s); + +#define ADDCONST(NAME, CONST) \ + s = PyLong_FromLong(CONST); \ + PyDict_SetItemString(d, NAME, s); \ + Py_DECREF(s) + + ADDCONST("F2PY_INTENT_IN", F2PY_INTENT_IN); + ADDCONST("F2PY_INTENT_INOUT", F2PY_INTENT_INOUT); + ADDCONST("F2PY_INTENT_OUT", F2PY_INTENT_OUT); + ADDCONST("F2PY_INTENT_HIDE", F2PY_INTENT_HIDE); + ADDCONST("F2PY_INTENT_CACHE", F2PY_INTENT_CACHE); + ADDCONST("F2PY_INTENT_COPY", F2PY_INTENT_COPY); + ADDCONST("F2PY_INTENT_C", F2PY_INTENT_C); + ADDCONST("F2PY_OPTIONAL", F2PY_OPTIONAL); + ADDCONST("F2PY_INTENT_INPLACE", F2PY_INTENT_INPLACE); + ADDCONST("NPY_BOOL", NPY_BOOL); + ADDCONST("NPY_BYTE", NPY_BYTE); + ADDCONST("NPY_UBYTE", NPY_UBYTE); + ADDCONST("NPY_SHORT", NPY_SHORT); + ADDCONST("NPY_USHORT", NPY_USHORT); + ADDCONST("NPY_INT", NPY_INT); + ADDCONST("NPY_UINT", NPY_UINT); + ADDCONST("NPY_INTP", NPY_INTP); + ADDCONST("NPY_UINTP", NPY_UINTP); + ADDCONST("NPY_LONG", NPY_LONG); + ADDCONST("NPY_ULONG", NPY_ULONG); + ADDCONST("NPY_LONGLONG", NPY_LONGLONG); + ADDCONST("NPY_ULONGLONG", NPY_ULONGLONG); + ADDCONST("NPY_FLOAT", NPY_FLOAT); + ADDCONST("NPY_DOUBLE", NPY_DOUBLE); + ADDCONST("NPY_LONGDOUBLE", NPY_LONGDOUBLE); + ADDCONST("NPY_CFLOAT", NPY_CFLOAT); + ADDCONST("NPY_CDOUBLE", NPY_CDOUBLE); + ADDCONST("NPY_CLONGDOUBLE", NPY_CLONGDOUBLE); + ADDCONST("NPY_OBJECT", NPY_OBJECT); + ADDCONST("NPY_STRING", NPY_STRING); + ADDCONST("NPY_UNICODE", NPY_UNICODE); + ADDCONST("NPY_VOID", NPY_VOID); + ADDCONST("NPY_NTYPES", NPY_NTYPES); + ADDCONST("NPY_NOTYPE", NPY_NOTYPE); + ADDCONST("NPY_USERDEF", NPY_USERDEF); + + ADDCONST("CONTIGUOUS", NPY_ARRAY_C_CONTIGUOUS); + ADDCONST("FORTRAN", NPY_ARRAY_F_CONTIGUOUS); + ADDCONST("OWNDATA", NPY_ARRAY_OWNDATA); + ADDCONST("FORCECAST", NPY_ARRAY_FORCECAST); + ADDCONST("ENSURECOPY", NPY_ARRAY_ENSURECOPY); + ADDCONST("ENSUREARRAY", NPY_ARRAY_ENSUREARRAY); + ADDCONST("ALIGNED", NPY_ARRAY_ALIGNED); + ADDCONST("WRITEABLE", NPY_ARRAY_WRITEABLE); + ADDCONST("UPDATEIFCOPY", NPY_ARRAY_UPDATEIFCOPY); + ADDCONST("WRITEBACKIFCOPY", NPY_ARRAY_WRITEBACKIFCOPY); + + ADDCONST("BEHAVED", NPY_ARRAY_BEHAVED); + ADDCONST("BEHAVED_NS", NPY_ARRAY_BEHAVED_NS); + ADDCONST("CARRAY", NPY_ARRAY_CARRAY); + ADDCONST("FARRAY", NPY_ARRAY_FARRAY); + ADDCONST("CARRAY_RO", NPY_ARRAY_CARRAY_RO); + ADDCONST("FARRAY_RO", NPY_ARRAY_FARRAY_RO); + ADDCONST("DEFAULT", NPY_ARRAY_DEFAULT); + ADDCONST("UPDATE_ALL", NPY_ARRAY_UPDATE_ALL); + +#undef ADDCONST( + + if (PyErr_Occurred()) + Py_FatalError("can't initialize module wrap"); + +#ifdef F2PY_REPORT_ATEXIT + on_exit(f2py_report_on_exit,(void*)"array_from_pyobj.wrap.call"); +#endif + + return m; +} +#ifdef __cplusplus +} +#endif diff --git a/venv/Lib/site-packages/numpy/f2py/tests/src/assumed_shape/.f2py_f2cmap b/venv/Lib/site-packages/numpy/f2py/tests/src/assumed_shape/.f2py_f2cmap new file mode 100644 index 0000000..2665f89 --- /dev/null +++ b/venv/Lib/site-packages/numpy/f2py/tests/src/assumed_shape/.f2py_f2cmap @@ -0,0 +1 @@ +dict(real=dict(rk="double")) diff --git a/venv/Lib/site-packages/numpy/f2py/tests/src/assumed_shape/foo_free.f90 b/venv/Lib/site-packages/numpy/f2py/tests/src/assumed_shape/foo_free.f90 new file mode 100644 index 0000000..b301710 --- /dev/null +++ b/venv/Lib/site-packages/numpy/f2py/tests/src/assumed_shape/foo_free.f90 @@ -0,0 +1,34 @@ + +subroutine sum(x, res) + implicit none + real, intent(in) :: x(:) + real, intent(out) :: res + + integer :: i + + !print *, "sum: size(x) = ", size(x) + + res = 0.0 + + do i = 1, size(x) + res = res + x(i) + enddo + +end subroutine sum + +function fsum(x) result (res) + implicit none + real, intent(in) :: x(:) + real :: res + + integer :: i + + !print *, "fsum: size(x) = ", size(x) + + res = 0.0 + + do i = 1, size(x) + res = res + x(i) + enddo + +end function fsum diff --git a/venv/Lib/site-packages/numpy/f2py/tests/src/assumed_shape/foo_mod.f90 b/venv/Lib/site-packages/numpy/f2py/tests/src/assumed_shape/foo_mod.f90 new file mode 100644 index 0000000..cbe6317 --- /dev/null +++ b/venv/Lib/site-packages/numpy/f2py/tests/src/assumed_shape/foo_mod.f90 @@ -0,0 +1,41 @@ + +module mod + +contains + +subroutine sum(x, res) + implicit none + real, intent(in) :: x(:) + real, intent(out) :: res + + integer :: i + + !print *, "sum: size(x) = ", size(x) + + res = 0.0 + + do i = 1, size(x) + res = res + x(i) + enddo + +end subroutine sum + +function fsum(x) result (res) + implicit none + real, intent(in) :: x(:) + real :: res + + integer :: i + + !print *, "fsum: size(x) = ", size(x) + + res = 0.0 + + do i = 1, size(x) + res = res + x(i) + enddo + +end function fsum + + +end module mod diff --git a/venv/Lib/site-packages/numpy/f2py/tests/src/assumed_shape/foo_use.f90 b/venv/Lib/site-packages/numpy/f2py/tests/src/assumed_shape/foo_use.f90 new file mode 100644 index 0000000..337465a --- /dev/null +++ b/venv/Lib/site-packages/numpy/f2py/tests/src/assumed_shape/foo_use.f90 @@ -0,0 +1,19 @@ +subroutine sum_with_use(x, res) + use precision + + implicit none + + real(kind=rk), intent(in) :: x(:) + real(kind=rk), intent(out) :: res + + integer :: i + + !print *, "size(x) = ", size(x) + + res = 0.0 + + do i = 1, size(x) + res = res + x(i) + enddo + + end subroutine diff --git a/venv/Lib/site-packages/numpy/f2py/tests/src/assumed_shape/precision.f90 b/venv/Lib/site-packages/numpy/f2py/tests/src/assumed_shape/precision.f90 new file mode 100644 index 0000000..ed6c70c --- /dev/null +++ b/venv/Lib/site-packages/numpy/f2py/tests/src/assumed_shape/precision.f90 @@ -0,0 +1,4 @@ +module precision + integer, parameter :: rk = selected_real_kind(8) + integer, parameter :: ik = selected_real_kind(4) +end module diff --git a/venv/Lib/site-packages/numpy/f2py/tests/src/common/block.f b/venv/Lib/site-packages/numpy/f2py/tests/src/common/block.f new file mode 100644 index 0000000..7ea7968 --- /dev/null +++ b/venv/Lib/site-packages/numpy/f2py/tests/src/common/block.f @@ -0,0 +1,11 @@ + SUBROUTINE INITCB + DOUBLE PRECISION LONG + CHARACTER STRING + INTEGER OK + + COMMON /BLOCK/ LONG, STRING, OK + LONG = 1.0 + STRING = '2' + OK = 3 + RETURN + END diff --git a/venv/Lib/site-packages/numpy/f2py/tests/src/kind/foo.f90 b/venv/Lib/site-packages/numpy/f2py/tests/src/kind/foo.f90 new file mode 100644 index 0000000..d3d15cf --- /dev/null +++ b/venv/Lib/site-packages/numpy/f2py/tests/src/kind/foo.f90 @@ -0,0 +1,20 @@ + + +subroutine selectedrealkind(p, r, res) + implicit none + + integer, intent(in) :: p, r + !f2py integer :: r=0 + integer, intent(out) :: res + res = selected_real_kind(p, r) + +end subroutine + +subroutine selectedintkind(p, res) + implicit none + + integer, intent(in) :: p + integer, intent(out) :: res + res = selected_int_kind(p) + +end subroutine diff --git a/venv/Lib/site-packages/numpy/f2py/tests/src/mixed/foo.f b/venv/Lib/site-packages/numpy/f2py/tests/src/mixed/foo.f new file mode 100644 index 0000000..c347425 --- /dev/null +++ b/venv/Lib/site-packages/numpy/f2py/tests/src/mixed/foo.f @@ -0,0 +1,5 @@ + subroutine bar11(a) +cf2py intent(out) a + integer a + a = 11 + end diff --git a/venv/Lib/site-packages/numpy/f2py/tests/src/mixed/foo_fixed.f90 b/venv/Lib/site-packages/numpy/f2py/tests/src/mixed/foo_fixed.f90 new file mode 100644 index 0000000..7543a6a --- /dev/null +++ b/venv/Lib/site-packages/numpy/f2py/tests/src/mixed/foo_fixed.f90 @@ -0,0 +1,8 @@ + module foo_fixed + contains + subroutine bar12(a) +!f2py intent(out) a + integer a + a = 12 + end subroutine bar12 + end module foo_fixed diff --git a/venv/Lib/site-packages/numpy/f2py/tests/src/mixed/foo_free.f90 b/venv/Lib/site-packages/numpy/f2py/tests/src/mixed/foo_free.f90 new file mode 100644 index 0000000..c1b641f --- /dev/null +++ b/venv/Lib/site-packages/numpy/f2py/tests/src/mixed/foo_free.f90 @@ -0,0 +1,8 @@ +module foo_free +contains + subroutine bar13(a) + !f2py intent(out) a + integer a + a = 13 + end subroutine bar13 +end module foo_free diff --git a/venv/Lib/site-packages/numpy/f2py/tests/src/module_data/mod.mod b/venv/Lib/site-packages/numpy/f2py/tests/src/module_data/mod.mod new file mode 100644 index 0000000000000000000000000000000000000000..8670a97e911c48ff2cae2cf83dd14f42f8a7004a GIT binary patch literal 412 zcmV;N0b~9jiwFP!000001GSW0Z-OushVT0;&RyYROTn+~vcl1jVKEi9c}1AuVlpLB zx9sPyl#lp1-Qv81mPp@ZV7twwwq`<~;4U^s!8gj|Hg zD3T3PHo`hCwbY_|)(GHGKn?`EpR)sWaU)yHeSiME3{GQoYlK~p(v`nqTyWzIMi1!MKNavb zzF2!@e0|MasAF;@XrC#v;wM)8!Wh`P+!(Z~bIjCM#Yth%sr+Hk)owB9ndBRfe&AZC G1pojXWXECv literal 0 HcmV?d00001 diff --git a/venv/Lib/site-packages/numpy/f2py/tests/src/module_data/module_data_docstring.f90 b/venv/Lib/site-packages/numpy/f2py/tests/src/module_data/module_data_docstring.f90 new file mode 100644 index 0000000..4505e0c --- /dev/null +++ b/venv/Lib/site-packages/numpy/f2py/tests/src/module_data/module_data_docstring.f90 @@ -0,0 +1,12 @@ +module mod + integer :: i + integer :: x(4) + real, dimension(2,3) :: a + real, allocatable, dimension(:,:) :: b +contains + subroutine foo + integer :: k + k = 1 + a(1,2) = a(1,2)+3 + end subroutine foo +end module mod diff --git a/venv/Lib/site-packages/numpy/f2py/tests/src/parameter/constant_both.f90 b/venv/Lib/site-packages/numpy/f2py/tests/src/parameter/constant_both.f90 new file mode 100644 index 0000000..ac90ced --- /dev/null +++ b/venv/Lib/site-packages/numpy/f2py/tests/src/parameter/constant_both.f90 @@ -0,0 +1,57 @@ +! Check that parameters are correct intercepted. +! Constants with comma separations are commonly +! used, for instance Pi = 3._dp +subroutine foo(x) + implicit none + integer, parameter :: sp = selected_real_kind(6) + integer, parameter :: dp = selected_real_kind(15) + integer, parameter :: ii = selected_int_kind(9) + integer, parameter :: il = selected_int_kind(18) + real(dp), intent(inout) :: x + dimension x(3) + real(sp), parameter :: three_s = 3._sp + real(dp), parameter :: three_d = 3._dp + integer(ii), parameter :: three_i = 3_ii + integer(il), parameter :: three_l = 3_il + x(1) = x(1) + x(2) * three_s * three_i + x(3) * three_d * three_l + x(2) = x(2) * three_s + x(3) = x(3) * three_l + return +end subroutine + + +subroutine foo_no(x) + implicit none + integer, parameter :: sp = selected_real_kind(6) + integer, parameter :: dp = selected_real_kind(15) + integer, parameter :: ii = selected_int_kind(9) + integer, parameter :: il = selected_int_kind(18) + real(dp), intent(inout) :: x + dimension x(3) + real(sp), parameter :: three_s = 3. + real(dp), parameter :: three_d = 3. + integer(ii), parameter :: three_i = 3 + integer(il), parameter :: three_l = 3 + x(1) = x(1) + x(2) * three_s * three_i + x(3) * three_d * three_l + x(2) = x(2) * three_s + x(3) = x(3) * three_l + return +end subroutine + +subroutine foo_sum(x) + implicit none + integer, parameter :: sp = selected_real_kind(6) + integer, parameter :: dp = selected_real_kind(15) + integer, parameter :: ii = selected_int_kind(9) + integer, parameter :: il = selected_int_kind(18) + real(dp), intent(inout) :: x + dimension x(3) + real(sp), parameter :: three_s = 2._sp + 1._sp + real(dp), parameter :: three_d = 1._dp + 2._dp + integer(ii), parameter :: three_i = 2_ii + 1_ii + integer(il), parameter :: three_l = 1_il + 2_il + x(1) = x(1) + x(2) * three_s * three_i + x(3) * three_d * three_l + x(2) = x(2) * three_s + x(3) = x(3) * three_l + return +end subroutine diff --git a/venv/Lib/site-packages/numpy/f2py/tests/src/parameter/constant_compound.f90 b/venv/Lib/site-packages/numpy/f2py/tests/src/parameter/constant_compound.f90 new file mode 100644 index 0000000..e51f5e9 --- /dev/null +++ b/venv/Lib/site-packages/numpy/f2py/tests/src/parameter/constant_compound.f90 @@ -0,0 +1,15 @@ +! Check that parameters are correct intercepted. +! Constants with comma separations are commonly +! used, for instance Pi = 3._dp +subroutine foo_compound_int(x) + implicit none + integer, parameter :: ii = selected_int_kind(9) + integer(ii), intent(inout) :: x + dimension x(3) + integer(ii), parameter :: three = 3_ii + integer(ii), parameter :: two = 2_ii + integer(ii), parameter :: six = three * 1_ii * two + + x(1) = x(1) + x(2) + x(3) * six + return +end subroutine diff --git a/venv/Lib/site-packages/numpy/f2py/tests/src/parameter/constant_integer.f90 b/venv/Lib/site-packages/numpy/f2py/tests/src/parameter/constant_integer.f90 new file mode 100644 index 0000000..aaa83d2 --- /dev/null +++ b/venv/Lib/site-packages/numpy/f2py/tests/src/parameter/constant_integer.f90 @@ -0,0 +1,22 @@ +! Check that parameters are correct intercepted. +! Constants with comma separations are commonly +! used, for instance Pi = 3._dp +subroutine foo_int(x) + implicit none + integer, parameter :: ii = selected_int_kind(9) + integer(ii), intent(inout) :: x + dimension x(3) + integer(ii), parameter :: three = 3_ii + x(1) = x(1) + x(2) + x(3) * three + return +end subroutine + +subroutine foo_long(x) + implicit none + integer, parameter :: ii = selected_int_kind(18) + integer(ii), intent(inout) :: x + dimension x(3) + integer(ii), parameter :: three = 3_ii + x(1) = x(1) + x(2) + x(3) * three + return +end subroutine diff --git a/venv/Lib/site-packages/numpy/f2py/tests/src/parameter/constant_non_compound.f90 b/venv/Lib/site-packages/numpy/f2py/tests/src/parameter/constant_non_compound.f90 new file mode 100644 index 0000000..62c9a5b --- /dev/null +++ b/venv/Lib/site-packages/numpy/f2py/tests/src/parameter/constant_non_compound.f90 @@ -0,0 +1,23 @@ +! Check that parameters are correct intercepted. +! Specifically that types of constants without +! compound kind specs are correctly inferred +! adapted Gibbs iteration code from pymc +! for this test case +subroutine foo_non_compound_int(x) + implicit none + integer, parameter :: ii = selected_int_kind(9) + + integer(ii) maxiterates + parameter (maxiterates=2) + + integer(ii) maxseries + parameter (maxseries=2) + + integer(ii) wasize + parameter (wasize=maxiterates*maxseries) + integer(ii), intent(inout) :: x + dimension x(wasize) + + x(1) = x(1) + x(2) + x(3) + x(4) * wasize + return +end subroutine diff --git a/venv/Lib/site-packages/numpy/f2py/tests/src/parameter/constant_real.f90 b/venv/Lib/site-packages/numpy/f2py/tests/src/parameter/constant_real.f90 new file mode 100644 index 0000000..02ac9dd --- /dev/null +++ b/venv/Lib/site-packages/numpy/f2py/tests/src/parameter/constant_real.f90 @@ -0,0 +1,23 @@ +! Check that parameters are correct intercepted. +! Constants with comma separations are commonly +! used, for instance Pi = 3._dp +subroutine foo_single(x) + implicit none + integer, parameter :: rp = selected_real_kind(6) + real(rp), intent(inout) :: x + dimension x(3) + real(rp), parameter :: three = 3._rp + x(1) = x(1) + x(2) + x(3) * three + return +end subroutine + +subroutine foo_double(x) + implicit none + integer, parameter :: rp = selected_real_kind(15) + real(rp), intent(inout) :: x + dimension x(3) + real(rp), parameter :: three = 3._rp + x(1) = x(1) + x(2) + x(3) * three + return +end subroutine + diff --git a/venv/Lib/site-packages/numpy/f2py/tests/src/regression/inout.f90 b/venv/Lib/site-packages/numpy/f2py/tests/src/regression/inout.f90 new file mode 100644 index 0000000..80cdad9 --- /dev/null +++ b/venv/Lib/site-packages/numpy/f2py/tests/src/regression/inout.f90 @@ -0,0 +1,9 @@ +! Check that intent(in out) translates as intent(inout). +! The separation seems to be a common usage. + subroutine foo(x) + implicit none + real(4), intent(in out) :: x + dimension x(3) + x(1) = x(1) + x(2) + x(3) + return + end diff --git a/venv/Lib/site-packages/numpy/f2py/tests/src/size/foo.f90 b/venv/Lib/site-packages/numpy/f2py/tests/src/size/foo.f90 new file mode 100644 index 0000000..5b66f8c --- /dev/null +++ b/venv/Lib/site-packages/numpy/f2py/tests/src/size/foo.f90 @@ -0,0 +1,44 @@ + +subroutine foo(a, n, m, b) + implicit none + + real, intent(in) :: a(n, m) + integer, intent(in) :: n, m + real, intent(out) :: b(size(a, 1)) + + integer :: i + + do i = 1, size(b) + b(i) = sum(a(i,:)) + enddo +end subroutine + +subroutine trans(x,y) + implicit none + real, intent(in), dimension(:,:) :: x + real, intent(out), dimension( size(x,2), size(x,1) ) :: y + integer :: N, M, i, j + N = size(x,1) + M = size(x,2) + DO i=1,N + do j=1,M + y(j,i) = x(i,j) + END DO + END DO +end subroutine trans + +subroutine flatten(x,y) + implicit none + real, intent(in), dimension(:,:) :: x + real, intent(out), dimension( size(x) ) :: y + integer :: N, M, i, j, k + N = size(x,1) + M = size(x,2) + k = 1 + DO i=1,N + do j=1,M + y(k) = x(i,j) + k = k + 1 + END DO + END DO +end subroutine flatten diff --git a/venv/Lib/site-packages/numpy/f2py/tests/src/string/char.f90 b/venv/Lib/site-packages/numpy/f2py/tests/src/string/char.f90 new file mode 100644 index 0000000..bb7985c --- /dev/null +++ b/venv/Lib/site-packages/numpy/f2py/tests/src/string/char.f90 @@ -0,0 +1,29 @@ +MODULE char_test + +CONTAINS + +SUBROUTINE change_strings(strings, n_strs, out_strings) + IMPLICIT NONE + + ! Inputs + INTEGER, INTENT(IN) :: n_strs + CHARACTER, INTENT(IN), DIMENSION(2,n_strs) :: strings + CHARACTER, INTENT(OUT), DIMENSION(2,n_strs) :: out_strings + +!f2py INTEGER, INTENT(IN) :: n_strs +!f2py CHARACTER, INTENT(IN), DIMENSION(2,n_strs) :: strings +!f2py CHARACTER, INTENT(OUT), DIMENSION(2,n_strs) :: strings + + ! Misc. + INTEGER*4 :: j + + + DO j=1, n_strs + out_strings(1,j) = strings(1,j) + out_strings(2,j) = 'A' + END DO + +END SUBROUTINE change_strings + +END MODULE char_test + diff --git a/venv/Lib/site-packages/numpy/f2py/tests/test_array_from_pyobj.py b/venv/Lib/site-packages/numpy/f2py/tests/test_array_from_pyobj.py new file mode 100644 index 0000000..77149e4 --- /dev/null +++ b/venv/Lib/site-packages/numpy/f2py/tests/test_array_from_pyobj.py @@ -0,0 +1,592 @@ +import os +import sys +import copy +import pytest + +import numpy as np + +from numpy.testing import assert_, assert_equal +from numpy.core.multiarray import typeinfo +from . import util + +wrap = None + + +def setup_module(): + """ + Build the required testing extension module + + """ + global wrap + + # Check compiler availability first + if not util.has_c_compiler(): + pytest.skip("No C compiler available") + + if wrap is None: + config_code = """ + config.add_extension('test_array_from_pyobj_ext', + sources=['wrapmodule.c', 'fortranobject.c'], + define_macros=[]) + """ + d = os.path.dirname(__file__) + src = [os.path.join(d, 'src', 'array_from_pyobj', 'wrapmodule.c'), + os.path.join(d, '..', 'src', 'fortranobject.c'), + os.path.join(d, '..', 'src', 'fortranobject.h')] + wrap = util.build_module_distutils(src, config_code, + 'test_array_from_pyobj_ext') + + +def flags_info(arr): + flags = wrap.array_attrs(arr)[6] + return flags2names(flags) + + +def flags2names(flags): + info = [] + for flagname in ['CONTIGUOUS', 'FORTRAN', 'OWNDATA', 'ENSURECOPY', + 'ENSUREARRAY', 'ALIGNED', 'NOTSWAPPED', 'WRITEABLE', + 'WRITEBACKIFCOPY', 'UPDATEIFCOPY', 'BEHAVED', 'BEHAVED_RO', + 'CARRAY', 'FARRAY' + ]: + if abs(flags) & getattr(wrap, flagname, 0): + info.append(flagname) + return info + + +class Intent: + + def __init__(self, intent_list=[]): + self.intent_list = intent_list[:] + flags = 0 + for i in intent_list: + if i == 'optional': + flags |= wrap.F2PY_OPTIONAL + else: + flags |= getattr(wrap, 'F2PY_INTENT_' + i.upper()) + self.flags = flags + + def __getattr__(self, name): + name = name.lower() + if name == 'in_': + name = 'in' + return self.__class__(self.intent_list + [name]) + + def __str__(self): + return 'intent(%s)' % (','.join(self.intent_list)) + + def __repr__(self): + return 'Intent(%r)' % (self.intent_list) + + def is_intent(self, *names): + for name in names: + if name not in self.intent_list: + return False + return True + + def is_intent_exact(self, *names): + return len(self.intent_list) == len(names) and self.is_intent(*names) + +intent = Intent() + +_type_names = ['BOOL', 'BYTE', 'UBYTE', 'SHORT', 'USHORT', 'INT', 'UINT', + 'LONG', 'ULONG', 'LONGLONG', 'ULONGLONG', + 'FLOAT', 'DOUBLE', 'CFLOAT'] + +_cast_dict = {'BOOL': ['BOOL']} +_cast_dict['BYTE'] = _cast_dict['BOOL'] + ['BYTE'] +_cast_dict['UBYTE'] = _cast_dict['BOOL'] + ['UBYTE'] +_cast_dict['BYTE'] = ['BYTE'] +_cast_dict['UBYTE'] = ['UBYTE'] +_cast_dict['SHORT'] = _cast_dict['BYTE'] + ['UBYTE', 'SHORT'] +_cast_dict['USHORT'] = _cast_dict['UBYTE'] + ['BYTE', 'USHORT'] +_cast_dict['INT'] = _cast_dict['SHORT'] + ['USHORT', 'INT'] +_cast_dict['UINT'] = _cast_dict['USHORT'] + ['SHORT', 'UINT'] + +_cast_dict['LONG'] = _cast_dict['INT'] + ['LONG'] +_cast_dict['ULONG'] = _cast_dict['UINT'] + ['ULONG'] + +_cast_dict['LONGLONG'] = _cast_dict['LONG'] + ['LONGLONG'] +_cast_dict['ULONGLONG'] = _cast_dict['ULONG'] + ['ULONGLONG'] + +_cast_dict['FLOAT'] = _cast_dict['SHORT'] + ['USHORT', 'FLOAT'] +_cast_dict['DOUBLE'] = _cast_dict['INT'] + ['UINT', 'FLOAT', 'DOUBLE'] + +_cast_dict['CFLOAT'] = _cast_dict['FLOAT'] + ['CFLOAT'] + +# 32 bit system malloc typically does not provide the alignment required by +# 16 byte long double types this means the inout intent cannot be satisfied +# and several tests fail as the alignment flag can be randomly true or fals +# when numpy gains an aligned allocator the tests could be enabled again +if ((np.intp().dtype.itemsize != 4 or np.clongdouble().dtype.alignment <= 8) and + sys.platform != 'win32'): + _type_names.extend(['LONGDOUBLE', 'CDOUBLE', 'CLONGDOUBLE']) + _cast_dict['LONGDOUBLE'] = _cast_dict['LONG'] + \ + ['ULONG', 'FLOAT', 'DOUBLE', 'LONGDOUBLE'] + _cast_dict['CLONGDOUBLE'] = _cast_dict['LONGDOUBLE'] + \ + ['CFLOAT', 'CDOUBLE', 'CLONGDOUBLE'] + _cast_dict['CDOUBLE'] = _cast_dict['DOUBLE'] + ['CFLOAT', 'CDOUBLE'] + + +class Type: + _type_cache = {} + + def __new__(cls, name): + if isinstance(name, np.dtype): + dtype0 = name + name = None + for n, i in typeinfo.items(): + if not isinstance(i, type) and dtype0.type is i.type: + name = n + break + obj = cls._type_cache.get(name.upper(), None) + if obj is not None: + return obj + obj = object.__new__(cls) + obj._init(name) + cls._type_cache[name.upper()] = obj + return obj + + def _init(self, name): + self.NAME = name.upper() + info = typeinfo[self.NAME] + self.type_num = getattr(wrap, 'NPY_' + self.NAME) + assert_equal(self.type_num, info.num) + self.dtype = np.dtype(info.type) + self.type = info.type + self.elsize = info.bits / 8 + self.dtypechar = info.char + + def cast_types(self): + return [self.__class__(_m) for _m in _cast_dict[self.NAME]] + + def all_types(self): + return [self.__class__(_m) for _m in _type_names] + + def smaller_types(self): + bits = typeinfo[self.NAME].alignment + types = [] + for name in _type_names: + if typeinfo[name].alignment < bits: + types.append(Type(name)) + return types + + def equal_types(self): + bits = typeinfo[self.NAME].alignment + types = [] + for name in _type_names: + if name == self.NAME: + continue + if typeinfo[name].alignment == bits: + types.append(Type(name)) + return types + + def larger_types(self): + bits = typeinfo[self.NAME].alignment + types = [] + for name in _type_names: + if typeinfo[name].alignment > bits: + types.append(Type(name)) + return types + + +class Array: + + def __init__(self, typ, dims, intent, obj): + self.type = typ + self.dims = dims + self.intent = intent + self.obj_copy = copy.deepcopy(obj) + self.obj = obj + + # arr.dtypechar may be different from typ.dtypechar + self.arr = wrap.call(typ.type_num, dims, intent.flags, obj) + + assert_(isinstance(self.arr, np.ndarray), repr(type(self.arr))) + + self.arr_attr = wrap.array_attrs(self.arr) + + if len(dims) > 1: + if self.intent.is_intent('c'): + assert_(intent.flags & wrap.F2PY_INTENT_C) + assert_(not self.arr.flags['FORTRAN'], + repr((self.arr.flags, getattr(obj, 'flags', None)))) + assert_(self.arr.flags['CONTIGUOUS']) + assert_(not self.arr_attr[6] & wrap.FORTRAN) + else: + assert_(not intent.flags & wrap.F2PY_INTENT_C) + assert_(self.arr.flags['FORTRAN']) + assert_(not self.arr.flags['CONTIGUOUS']) + assert_(self.arr_attr[6] & wrap.FORTRAN) + + if obj is None: + self.pyarr = None + self.pyarr_attr = None + return + + if intent.is_intent('cache'): + assert_(isinstance(obj, np.ndarray), repr(type(obj))) + self.pyarr = np.array(obj).reshape(*dims).copy() + else: + self.pyarr = np.array( + np.array(obj, dtype=typ.dtypechar).reshape(*dims), + order=self.intent.is_intent('c') and 'C' or 'F') + assert_(self.pyarr.dtype == typ, + repr((self.pyarr.dtype, typ))) + self.pyarr.setflags(write=self.arr.flags['WRITEABLE']) + assert_(self.pyarr.flags['OWNDATA'], (obj, intent)) + self.pyarr_attr = wrap.array_attrs(self.pyarr) + + if len(dims) > 1: + if self.intent.is_intent('c'): + assert_(not self.pyarr.flags['FORTRAN']) + assert_(self.pyarr.flags['CONTIGUOUS']) + assert_(not self.pyarr_attr[6] & wrap.FORTRAN) + else: + assert_(self.pyarr.flags['FORTRAN']) + assert_(not self.pyarr.flags['CONTIGUOUS']) + assert_(self.pyarr_attr[6] & wrap.FORTRAN) + + assert_(self.arr_attr[1] == self.pyarr_attr[1]) # nd + assert_(self.arr_attr[2] == self.pyarr_attr[2]) # dimensions + if self.arr_attr[1] <= 1: + assert_(self.arr_attr[3] == self.pyarr_attr[3], + repr((self.arr_attr[3], self.pyarr_attr[3], + self.arr.tobytes(), self.pyarr.tobytes()))) # strides + assert_(self.arr_attr[5][-2:] == self.pyarr_attr[5][-2:], + repr((self.arr_attr[5], self.pyarr_attr[5]))) # descr + assert_(self.arr_attr[6] == self.pyarr_attr[6], + repr((self.arr_attr[6], self.pyarr_attr[6], + flags2names(0 * self.arr_attr[6] - self.pyarr_attr[6]), + flags2names(self.arr_attr[6]), intent))) # flags + + if intent.is_intent('cache'): + assert_(self.arr_attr[5][3] >= self.type.elsize, + repr((self.arr_attr[5][3], self.type.elsize))) + else: + assert_(self.arr_attr[5][3] == self.type.elsize, + repr((self.arr_attr[5][3], self.type.elsize))) + assert_(self.arr_equal(self.pyarr, self.arr)) + + if isinstance(self.obj, np.ndarray): + if typ.elsize == Type(obj.dtype).elsize: + if not intent.is_intent('copy') and self.arr_attr[1] <= 1: + assert_(self.has_shared_memory()) + + def arr_equal(self, arr1, arr2): + if arr1.shape != arr2.shape: + return False + return (arr1 == arr2).all() + + def __str__(self): + return str(self.arr) + + def has_shared_memory(self): + """Check that created array shares data with input array. + """ + if self.obj is self.arr: + return True + if not isinstance(self.obj, np.ndarray): + return False + obj_attr = wrap.array_attrs(self.obj) + return obj_attr[0] == self.arr_attr[0] + + +class TestIntent: + + def test_in_out(self): + assert_equal(str(intent.in_.out), 'intent(in,out)') + assert_(intent.in_.c.is_intent('c')) + assert_(not intent.in_.c.is_intent_exact('c')) + assert_(intent.in_.c.is_intent_exact('c', 'in')) + assert_(intent.in_.c.is_intent_exact('in', 'c')) + assert_(not intent.in_.is_intent('c')) + + +class TestSharedMemory: + num2seq = [1, 2] + num23seq = [[1, 2, 3], [4, 5, 6]] + + @pytest.fixture(autouse=True, scope='class', params=_type_names) + def setup_type(self, request): + request.cls.type = Type(request.param) + request.cls.array = lambda self, dims, intent, obj: \ + Array(Type(request.param), dims, intent, obj) + + def test_in_from_2seq(self): + a = self.array([2], intent.in_, self.num2seq) + assert_(not a.has_shared_memory()) + + def test_in_from_2casttype(self): + for t in self.type.cast_types(): + obj = np.array(self.num2seq, dtype=t.dtype) + a = self.array([len(self.num2seq)], intent.in_, obj) + if t.elsize == self.type.elsize: + assert_( + a.has_shared_memory(), repr((self.type.dtype, t.dtype))) + else: + assert_(not a.has_shared_memory(), repr(t.dtype)) + + @pytest.mark.parametrize('write', ['w', 'ro']) + @pytest.mark.parametrize('order', ['C', 'F']) + @pytest.mark.parametrize('inp', ['2seq', '23seq']) + def test_in_nocopy(self, write, order, inp): + """Test if intent(in) array can be passed without copies + """ + seq = getattr(self, 'num' + inp) + obj = np.array(seq, dtype=self.type.dtype, order=order) + obj.setflags(write=(write == 'w')) + a = self.array(obj.shape, ((order=='C' and intent.in_.c) or intent.in_), obj) + assert a.has_shared_memory() + + def test_inout_2seq(self): + obj = np.array(self.num2seq, dtype=self.type.dtype) + a = self.array([len(self.num2seq)], intent.inout, obj) + assert_(a.has_shared_memory()) + + try: + a = self.array([2], intent.in_.inout, self.num2seq) + except TypeError as msg: + if not str(msg).startswith('failed to initialize intent' + '(inout|inplace|cache) array'): + raise + else: + raise SystemError('intent(inout) should have failed on sequence') + + def test_f_inout_23seq(self): + obj = np.array(self.num23seq, dtype=self.type.dtype, order='F') + shape = (len(self.num23seq), len(self.num23seq[0])) + a = self.array(shape, intent.in_.inout, obj) + assert_(a.has_shared_memory()) + + obj = np.array(self.num23seq, dtype=self.type.dtype, order='C') + shape = (len(self.num23seq), len(self.num23seq[0])) + try: + a = self.array(shape, intent.in_.inout, obj) + except ValueError as msg: + if not str(msg).startswith('failed to initialize intent' + '(inout) array'): + raise + else: + raise SystemError( + 'intent(inout) should have failed on improper array') + + def test_c_inout_23seq(self): + obj = np.array(self.num23seq, dtype=self.type.dtype) + shape = (len(self.num23seq), len(self.num23seq[0])) + a = self.array(shape, intent.in_.c.inout, obj) + assert_(a.has_shared_memory()) + + def test_in_copy_from_2casttype(self): + for t in self.type.cast_types(): + obj = np.array(self.num2seq, dtype=t.dtype) + a = self.array([len(self.num2seq)], intent.in_.copy, obj) + assert_(not a.has_shared_memory(), repr(t.dtype)) + + def test_c_in_from_23seq(self): + a = self.array([len(self.num23seq), len(self.num23seq[0])], + intent.in_, self.num23seq) + assert_(not a.has_shared_memory()) + + def test_in_from_23casttype(self): + for t in self.type.cast_types(): + obj = np.array(self.num23seq, dtype=t.dtype) + a = self.array([len(self.num23seq), len(self.num23seq[0])], + intent.in_, obj) + assert_(not a.has_shared_memory(), repr(t.dtype)) + + def test_f_in_from_23casttype(self): + for t in self.type.cast_types(): + obj = np.array(self.num23seq, dtype=t.dtype, order='F') + a = self.array([len(self.num23seq), len(self.num23seq[0])], + intent.in_, obj) + if t.elsize == self.type.elsize: + assert_(a.has_shared_memory(), repr(t.dtype)) + else: + assert_(not a.has_shared_memory(), repr(t.dtype)) + + def test_c_in_from_23casttype(self): + for t in self.type.cast_types(): + obj = np.array(self.num23seq, dtype=t.dtype) + a = self.array([len(self.num23seq), len(self.num23seq[0])], + intent.in_.c, obj) + if t.elsize == self.type.elsize: + assert_(a.has_shared_memory(), repr(t.dtype)) + else: + assert_(not a.has_shared_memory(), repr(t.dtype)) + + def test_f_copy_in_from_23casttype(self): + for t in self.type.cast_types(): + obj = np.array(self.num23seq, dtype=t.dtype, order='F') + a = self.array([len(self.num23seq), len(self.num23seq[0])], + intent.in_.copy, obj) + assert_(not a.has_shared_memory(), repr(t.dtype)) + + def test_c_copy_in_from_23casttype(self): + for t in self.type.cast_types(): + obj = np.array(self.num23seq, dtype=t.dtype) + a = self.array([len(self.num23seq), len(self.num23seq[0])], + intent.in_.c.copy, obj) + assert_(not a.has_shared_memory(), repr(t.dtype)) + + def test_in_cache_from_2casttype(self): + for t in self.type.all_types(): + if t.elsize != self.type.elsize: + continue + obj = np.array(self.num2seq, dtype=t.dtype) + shape = (len(self.num2seq),) + a = self.array(shape, intent.in_.c.cache, obj) + assert_(a.has_shared_memory(), repr(t.dtype)) + + a = self.array(shape, intent.in_.cache, obj) + assert_(a.has_shared_memory(), repr(t.dtype)) + + obj = np.array(self.num2seq, dtype=t.dtype, order='F') + a = self.array(shape, intent.in_.c.cache, obj) + assert_(a.has_shared_memory(), repr(t.dtype)) + + a = self.array(shape, intent.in_.cache, obj) + assert_(a.has_shared_memory(), repr(t.dtype)) + + try: + a = self.array(shape, intent.in_.cache, obj[::-1]) + except ValueError as msg: + if not str(msg).startswith('failed to initialize' + ' intent(cache) array'): + raise + else: + raise SystemError( + 'intent(cache) should have failed on multisegmented array') + + def test_in_cache_from_2casttype_failure(self): + for t in self.type.all_types(): + if t.elsize >= self.type.elsize: + continue + obj = np.array(self.num2seq, dtype=t.dtype) + shape = (len(self.num2seq),) + try: + self.array(shape, intent.in_.cache, obj) # Should succeed + except ValueError as msg: + if not str(msg).startswith('failed to initialize' + ' intent(cache) array'): + raise + else: + raise SystemError( + 'intent(cache) should have failed on smaller array') + + def test_cache_hidden(self): + shape = (2,) + a = self.array(shape, intent.cache.hide, None) + assert_(a.arr.shape == shape) + + shape = (2, 3) + a = self.array(shape, intent.cache.hide, None) + assert_(a.arr.shape == shape) + + shape = (-1, 3) + try: + a = self.array(shape, intent.cache.hide, None) + except ValueError as msg: + if not str(msg).startswith('failed to create intent' + '(cache|hide)|optional array'): + raise + else: + raise SystemError( + 'intent(cache) should have failed on undefined dimensions') + + def test_hidden(self): + shape = (2,) + a = self.array(shape, intent.hide, None) + assert_(a.arr.shape == shape) + assert_(a.arr_equal(a.arr, np.zeros(shape, dtype=self.type.dtype))) + + shape = (2, 3) + a = self.array(shape, intent.hide, None) + assert_(a.arr.shape == shape) + assert_(a.arr_equal(a.arr, np.zeros(shape, dtype=self.type.dtype))) + assert_(a.arr.flags['FORTRAN'] and not a.arr.flags['CONTIGUOUS']) + + shape = (2, 3) + a = self.array(shape, intent.c.hide, None) + assert_(a.arr.shape == shape) + assert_(a.arr_equal(a.arr, np.zeros(shape, dtype=self.type.dtype))) + assert_(not a.arr.flags['FORTRAN'] and a.arr.flags['CONTIGUOUS']) + + shape = (-1, 3) + try: + a = self.array(shape, intent.hide, None) + except ValueError as msg: + if not str(msg).startswith('failed to create intent' + '(cache|hide)|optional array'): + raise + else: + raise SystemError('intent(hide) should have failed' + ' on undefined dimensions') + + def test_optional_none(self): + shape = (2,) + a = self.array(shape, intent.optional, None) + assert_(a.arr.shape == shape) + assert_(a.arr_equal(a.arr, np.zeros(shape, dtype=self.type.dtype))) + + shape = (2, 3) + a = self.array(shape, intent.optional, None) + assert_(a.arr.shape == shape) + assert_(a.arr_equal(a.arr, np.zeros(shape, dtype=self.type.dtype))) + assert_(a.arr.flags['FORTRAN'] and not a.arr.flags['CONTIGUOUS']) + + shape = (2, 3) + a = self.array(shape, intent.c.optional, None) + assert_(a.arr.shape == shape) + assert_(a.arr_equal(a.arr, np.zeros(shape, dtype=self.type.dtype))) + assert_(not a.arr.flags['FORTRAN'] and a.arr.flags['CONTIGUOUS']) + + def test_optional_from_2seq(self): + obj = self.num2seq + shape = (len(obj),) + a = self.array(shape, intent.optional, obj) + assert_(a.arr.shape == shape) + assert_(not a.has_shared_memory()) + + def test_optional_from_23seq(self): + obj = self.num23seq + shape = (len(obj), len(obj[0])) + a = self.array(shape, intent.optional, obj) + assert_(a.arr.shape == shape) + assert_(not a.has_shared_memory()) + + a = self.array(shape, intent.optional.c, obj) + assert_(a.arr.shape == shape) + assert_(not a.has_shared_memory()) + + def test_inplace(self): + obj = np.array(self.num23seq, dtype=self.type.dtype) + assert_(not obj.flags['FORTRAN'] and obj.flags['CONTIGUOUS']) + shape = obj.shape + a = self.array(shape, intent.inplace, obj) + assert_(obj[1][2] == a.arr[1][2], repr((obj, a.arr))) + a.arr[1][2] = 54 + assert_(obj[1][2] == a.arr[1][2] == + np.array(54, dtype=self.type.dtype), repr((obj, a.arr))) + assert_(a.arr is obj) + assert_(obj.flags['FORTRAN']) # obj attributes are changed inplace! + assert_(not obj.flags['CONTIGUOUS']) + + def test_inplace_from_casttype(self): + for t in self.type.cast_types(): + if t is self.type: + continue + obj = np.array(self.num23seq, dtype=t.dtype) + assert_(obj.dtype.type == t.type) + assert_(obj.dtype.type is not self.type.type) + assert_(not obj.flags['FORTRAN'] and obj.flags['CONTIGUOUS']) + shape = obj.shape + a = self.array(shape, intent.inplace, obj) + assert_(obj[1][2] == a.arr[1][2], repr((obj, a.arr))) + a.arr[1][2] = 54 + assert_(obj[1][2] == a.arr[1][2] == + np.array(54, dtype=self.type.dtype), repr((obj, a.arr))) + assert_(a.arr is obj) + assert_(obj.flags['FORTRAN']) # obj attributes changed inplace! + assert_(not obj.flags['CONTIGUOUS']) + assert_(obj.dtype.type is self.type.type) # obj changed inplace! diff --git a/venv/Lib/site-packages/numpy/f2py/tests/test_assumed_shape.py b/venv/Lib/site-packages/numpy/f2py/tests/test_assumed_shape.py new file mode 100644 index 0000000..dfc2526 --- /dev/null +++ b/venv/Lib/site-packages/numpy/f2py/tests/test_assumed_shape.py @@ -0,0 +1,53 @@ +import os +import pytest +import tempfile + +from numpy.testing import assert_ +from . import util + + +def _path(*a): + return os.path.join(*((os.path.dirname(__file__),) + a)) + + +class TestAssumedShapeSumExample(util.F2PyTest): + sources = [_path('src', 'assumed_shape', 'foo_free.f90'), + _path('src', 'assumed_shape', 'foo_use.f90'), + _path('src', 'assumed_shape', 'precision.f90'), + _path('src', 'assumed_shape', 'foo_mod.f90'), + _path('src', 'assumed_shape', '.f2py_f2cmap'), + ] + + @pytest.mark.slow + def test_all(self): + r = self.module.fsum([1, 2]) + assert_(r == 3, repr(r)) + r = self.module.sum([1, 2]) + assert_(r == 3, repr(r)) + r = self.module.sum_with_use([1, 2]) + assert_(r == 3, repr(r)) + + r = self.module.mod.sum([1, 2]) + assert_(r == 3, repr(r)) + r = self.module.mod.fsum([1, 2]) + assert_(r == 3, repr(r)) + + +class TestF2cmapOption(TestAssumedShapeSumExample): + def setup(self): + # Use a custom file name for .f2py_f2cmap + self.sources = list(self.sources) + f2cmap_src = self.sources.pop(-1) + + self.f2cmap_file = tempfile.NamedTemporaryFile(delete=False) + with open(f2cmap_src, 'rb') as f: + self.f2cmap_file.write(f.read()) + self.f2cmap_file.close() + + self.sources.append(self.f2cmap_file.name) + self.options = ["--f2cmap", self.f2cmap_file.name] + + super(TestF2cmapOption, self).setup() + + def teardown(self): + os.unlink(self.f2cmap_file.name) diff --git a/venv/Lib/site-packages/numpy/f2py/tests/test_block_docstring.py b/venv/Lib/site-packages/numpy/f2py/tests/test_block_docstring.py new file mode 100644 index 0000000..7d72516 --- /dev/null +++ b/venv/Lib/site-packages/numpy/f2py/tests/test_block_docstring.py @@ -0,0 +1,23 @@ +import sys +import pytest +from . import util + +from numpy.testing import assert_equal, IS_PYPY + +class TestBlockDocString(util.F2PyTest): + code = """ + SUBROUTINE FOO() + INTEGER BAR(2, 3) + + COMMON /BLOCK/ BAR + RETURN + END + """ + + @pytest.mark.skipif(sys.platform=='win32', + reason='Fails with MinGW64 Gfortran (Issue #9673)') + @pytest.mark.xfail(IS_PYPY, + reason="PyPy cannot modify tp_doc after PyType_Ready") + def test_block_docstring(self): + expected = "bar : 'i'-array(2,3)\n" + assert_equal(self.module.block.__doc__, expected) diff --git a/venv/Lib/site-packages/numpy/f2py/tests/test_callback.py b/venv/Lib/site-packages/numpy/f2py/tests/test_callback.py new file mode 100644 index 0000000..2cb429e --- /dev/null +++ b/venv/Lib/site-packages/numpy/f2py/tests/test_callback.py @@ -0,0 +1,326 @@ +import math +import textwrap +import sys +import pytest +import threading +import traceback +import time +import random + +import numpy as np +from numpy.testing import assert_, assert_equal, IS_PYPY +from . import util + + +class TestF77Callback(util.F2PyTest): + code = """ + subroutine t(fun,a) + integer a +cf2py intent(out) a + external fun + call fun(a) + end + + subroutine func(a) +cf2py intent(in,out) a + integer a + a = a + 11 + end + + subroutine func0(a) +cf2py intent(out) a + integer a + a = 11 + end + + subroutine t2(a) +cf2py intent(callback) fun + integer a +cf2py intent(out) a + external fun + call fun(a) + end + + subroutine string_callback(callback, a) + external callback + double precision callback + double precision a + character*1 r +cf2py intent(out) a + r = 'r' + a = callback(r) + end + + subroutine string_callback_array(callback, cu, lencu, a) + external callback + integer callback + integer lencu + character*8 cu(lencu) + integer a +cf2py intent(out) a + + a = callback(cu, lencu) + end + + subroutine hidden_callback(a, r) + external global_f +cf2py intent(callback, hide) global_f + integer a, r, global_f +cf2py intent(out) r + r = global_f(a) + end + + subroutine hidden_callback2(a, r) + external global_f + integer a, r, global_f +cf2py intent(out) r + r = global_f(a) + end + """ + + @pytest.mark.parametrize('name', 't,t2'.split(',')) + def test_all(self, name): + self.check_function(name) + + @pytest.mark.xfail(IS_PYPY, + reason="PyPy cannot modify tp_doc after PyType_Ready") + def test_docstring(self): + expected = textwrap.dedent("""\ + a = t(fun,[fun_extra_args]) + + Wrapper for ``t``. + + Parameters + ---------- + fun : call-back function + + Other Parameters + ---------------- + fun_extra_args : input tuple, optional + Default: () + + Returns + ------- + a : int + + Notes + ----- + Call-back functions:: + + def fun(): return a + Return objects: + a : int + """) + assert_equal(self.module.t.__doc__, expected) + + def check_function(self, name): + t = getattr(self.module, name) + r = t(lambda: 4) + assert_(r == 4, repr(r)) + r = t(lambda a: 5, fun_extra_args=(6,)) + assert_(r == 5, repr(r)) + r = t(lambda a: a, fun_extra_args=(6,)) + assert_(r == 6, repr(r)) + r = t(lambda a: 5 + a, fun_extra_args=(7,)) + assert_(r == 12, repr(r)) + r = t(lambda a: math.degrees(a), fun_extra_args=(math.pi,)) + assert_(r == 180, repr(r)) + r = t(math.degrees, fun_extra_args=(math.pi,)) + assert_(r == 180, repr(r)) + + r = t(self.module.func, fun_extra_args=(6,)) + assert_(r == 17, repr(r)) + r = t(self.module.func0) + assert_(r == 11, repr(r)) + r = t(self.module.func0._cpointer) + assert_(r == 11, repr(r)) + + class A: + + def __call__(self): + return 7 + + def mth(self): + return 9 + a = A() + r = t(a) + assert_(r == 7, repr(r)) + r = t(a.mth) + assert_(r == 9, repr(r)) + + @pytest.mark.skipif(sys.platform=='win32', + reason='Fails with MinGW64 Gfortran (Issue #9673)') + def test_string_callback(self): + + def callback(code): + if code == 'r': + return 0 + else: + return 1 + + f = getattr(self.module, 'string_callback') + r = f(callback) + assert_(r == 0, repr(r)) + + @pytest.mark.skipif(sys.platform=='win32', + reason='Fails with MinGW64 Gfortran (Issue #9673)') + def test_string_callback_array(self): + # See gh-10027 + cu = np.zeros((1, 8), 'S1') + + def callback(cu, lencu): + if cu.shape != (lencu, 8): + return 1 + if cu.dtype != 'S1': + return 2 + if not np.all(cu == b''): + return 3 + return 0 + + f = getattr(self.module, 'string_callback_array') + res = f(callback, cu, len(cu)) + assert_(res == 0, repr(res)) + + def test_threadsafety(self): + # Segfaults if the callback handling is not threadsafe + + errors = [] + + def cb(): + # Sleep here to make it more likely for another thread + # to call their callback at the same time. + time.sleep(1e-3) + + # Check reentrancy + r = self.module.t(lambda: 123) + assert_(r == 123) + + return 42 + + def runner(name): + try: + for j in range(50): + r = self.module.t(cb) + assert_(r == 42) + self.check_function(name) + except Exception: + errors.append(traceback.format_exc()) + + threads = [threading.Thread(target=runner, args=(arg,)) + for arg in ("t", "t2") for n in range(20)] + + for t in threads: + t.start() + + for t in threads: + t.join() + + errors = "\n\n".join(errors) + if errors: + raise AssertionError(errors) + + def test_hidden_callback(self): + try: + self.module.hidden_callback(2) + except Exception as msg: + assert_(str(msg).startswith('Callback global_f not defined')) + + try: + self.module.hidden_callback2(2) + except Exception as msg: + assert_(str(msg).startswith('cb: Callback global_f not defined')) + + self.module.global_f = lambda x: x + 1 + r = self.module.hidden_callback(2) + assert_(r == 3) + + self.module.global_f = lambda x: x + 2 + r = self.module.hidden_callback(2) + assert_(r == 4) + + del self.module.global_f + try: + self.module.hidden_callback(2) + except Exception as msg: + assert_(str(msg).startswith('Callback global_f not defined')) + + self.module.global_f = lambda x=0: x + 3 + r = self.module.hidden_callback(2) + assert_(r == 5) + + # reproducer of gh18341 + r = self.module.hidden_callback2(2) + assert_(r == 3) + + +class TestF77CallbackPythonTLS(TestF77Callback): + """ + Callback tests using Python thread-local storage instead of + compiler-provided + """ + options = ["-DF2PY_USE_PYTHON_TLS"] + + +class TestF90Callback(util.F2PyTest): + + suffix = '.f90' + + code = textwrap.dedent( + """ + function gh17797(f, y) result(r) + external f + integer(8) :: r, f + integer(8), dimension(:) :: y + r = f(0) + r = r + sum(y) + end function gh17797 + """) + + def test_gh17797(self): + + def incr(x): + return x + 123 + + y = np.array([1, 2, 3], dtype=np.int64) + r = self.module.gh17797(incr, y) + assert r == 123 + 1 + 2 + 3 + + +class TestGH18335(util.F2PyTest): + """The reproduction of the reported issue requires specific input that + extensions may break the issue conditions, so the reproducer is + implemented as a separate test class. Do not extend this test with + other tests! + """ + + suffix = '.f90' + + code = textwrap.dedent( + """ + ! When gh18335_workaround is defined as an extension, + ! the issue cannot be reproduced. + !subroutine gh18335_workaround(f, y) + ! implicit none + ! external f + ! integer(kind=1) :: y(1) + ! call f(y) + !end subroutine gh18335_workaround + + function gh18335(f) result (r) + implicit none + external f + integer(kind=1) :: y(1), r + y(1) = 123 + call f(y) + r = y(1) + end function gh18335 + """) + + def test_gh18335(self): + + def foo(x): + x[0] += 1 + + y = np.array([1, 2, 3], dtype=np.int8) + r = self.module.gh18335(foo) + assert r == 123 + 1 diff --git a/venv/Lib/site-packages/numpy/f2py/tests/test_common.py b/venv/Lib/site-packages/numpy/f2py/tests/test_common.py new file mode 100644 index 0000000..e4bf355 --- /dev/null +++ b/venv/Lib/site-packages/numpy/f2py/tests/test_common.py @@ -0,0 +1,25 @@ +import os +import sys +import pytest + +import numpy as np +from . import util + +from numpy.testing import assert_array_equal + +def _path(*a): + return os.path.join(*((os.path.dirname(__file__),) + a)) + +class TestCommonBlock(util.F2PyTest): + sources = [_path('src', 'common', 'block.f')] + + @pytest.mark.skipif(sys.platform=='win32', + reason='Fails with MinGW64 Gfortran (Issue #9673)') + def test_common_block(self): + self.module.initcb() + assert_array_equal(self.module.block.long_bn, + np.array(1.0, dtype=np.float64)) + assert_array_equal(self.module.block.string_bn, + np.array('2', dtype='|S1')) + assert_array_equal(self.module.block.ok, + np.array(3, dtype=np.int32)) diff --git a/venv/Lib/site-packages/numpy/f2py/tests/test_compile_function.py b/venv/Lib/site-packages/numpy/f2py/tests/test_compile_function.py new file mode 100644 index 0000000..f76fd64 --- /dev/null +++ b/venv/Lib/site-packages/numpy/f2py/tests/test_compile_function.py @@ -0,0 +1,125 @@ +"""See https://github.com/numpy/numpy/pull/11937. + +""" +import sys +import os +import uuid +from importlib import import_module +import pytest + +import numpy.f2py + +from numpy.testing import assert_equal +from . import util + + +def setup_module(): + if not util.has_c_compiler(): + pytest.skip("Needs C compiler") + if not util.has_f77_compiler(): + pytest.skip('Needs FORTRAN 77 compiler') + + +# extra_args can be a list (since gh-11937) or string. +# also test absence of extra_args +@pytest.mark.parametrize( + "extra_args", [['--noopt', '--debug'], '--noopt --debug', ''] + ) +@pytest.mark.leaks_references(reason="Imported module seems never deleted.") +def test_f2py_init_compile(extra_args): + # flush through the f2py __init__ compile() function code path as a + # crude test for input handling following migration from + # exec_command() to subprocess.check_output() in gh-11937 + + # the Fortran 77 syntax requires 6 spaces before any commands, but + # more space may be added/ + fsource = """ + integer function foo() + foo = 10 + 5 + return + end + """ + # use various helper functions in util.py to enable robust build / + # compile and reimport cycle in test suite + moddir = util.get_module_dir() + modname = util.get_temp_module_name() + + cwd = os.getcwd() + target = os.path.join(moddir, str(uuid.uuid4()) + '.f') + # try running compile() with and without a source_fn provided so + # that the code path where a temporary file for writing Fortran + # source is created is also explored + for source_fn in [target, None]: + # mimic the path changing behavior used by build_module() in + # util.py, but don't actually use build_module() because it has + # its own invocation of subprocess that circumvents the + # f2py.compile code block under test + try: + os.chdir(moddir) + ret_val = numpy.f2py.compile( + fsource, + modulename=modname, + extra_args=extra_args, + source_fn=source_fn + ) + finally: + os.chdir(cwd) + + # check for compile success return value + assert_equal(ret_val, 0) + + # we are not currently able to import the Python-Fortran + # interface module on Windows / Appveyor, even though we do get + # successful compilation on that platform with Python 3.x + if sys.platform != 'win32': + # check for sensible result of Fortran function; that means + # we can import the module name in Python and retrieve the + # result of the sum operation + return_check = import_module(modname) + calc_result = return_check.foo() + assert_equal(calc_result, 15) + # Removal from sys.modules, is not as such necessary. Even with + # removal, the module (dict) stays alive. + del sys.modules[modname] + + +def test_f2py_init_compile_failure(): + # verify an appropriate integer status value returned by + # f2py.compile() when invalid Fortran is provided + ret_val = numpy.f2py.compile(b"invalid") + assert_equal(ret_val, 1) + + +def test_f2py_init_compile_bad_cmd(): + # verify that usage of invalid command in f2py.compile() returns + # status value of 127 for historic consistency with exec_command() + # error handling + + # patch the sys Python exe path temporarily to induce an OSError + # downstream NOTE: how bad of an idea is this patching? + try: + temp = sys.executable + sys.executable = 'does not exist' + + # the OSError should take precedence over invalid Fortran + ret_val = numpy.f2py.compile(b"invalid") + assert_equal(ret_val, 127) + finally: + sys.executable = temp + + +@pytest.mark.parametrize('fsource', + ['program test_f2py\nend program test_f2py', + b'program test_f2py\nend program test_f2py',]) +def test_compile_from_strings(tmpdir, fsource): + # Make sure we can compile str and bytes gh-12796 + cwd = os.getcwd() + try: + os.chdir(str(tmpdir)) + ret_val = numpy.f2py.compile( + fsource, + modulename='test_compile_from_strings', + extension='.f90') + assert_equal(ret_val, 0) + finally: + os.chdir(cwd) diff --git a/venv/Lib/site-packages/numpy/f2py/tests/test_crackfortran.py b/venv/Lib/site-packages/numpy/f2py/tests/test_crackfortran.py new file mode 100644 index 0000000..827c71a --- /dev/null +++ b/venv/Lib/site-packages/numpy/f2py/tests/test_crackfortran.py @@ -0,0 +1,117 @@ +import numpy as np +from numpy.testing import assert_array_equal +from . import util +from numpy.f2py import crackfortran +import tempfile +import textwrap + + +class TestNoSpace(util.F2PyTest): + # issue gh-15035: add handling for endsubroutine, endfunction with no space + # between "end" and the block name + code = """ + subroutine subb(k) + real(8), intent(inout) :: k(:) + k=k+1 + endsubroutine + + subroutine subc(w,k) + real(8), intent(in) :: w(:) + real(8), intent(out) :: k(size(w)) + k=w+1 + endsubroutine + + function t0(value) + character value + character t0 + t0 = value + endfunction + """ + + def test_module(self): + k = np.array([1, 2, 3], dtype=np.float64) + w = np.array([1, 2, 3], dtype=np.float64) + self.module.subb(k) + assert_array_equal(k, w + 1) + self.module.subc([w, k]) + assert_array_equal(k, w + 1) + assert self.module.t0(23) == b'2' + +class TestPublicPrivate(): + def test_defaultPrivate(self, tmp_path): + f_path = tmp_path / "mod.f90" + with f_path.open('w') as ff: + ff.write(textwrap.dedent("""\ + module foo + private + integer :: a + public :: setA + integer :: b + contains + subroutine setA(v) + integer, intent(in) :: v + a = v + end subroutine setA + end module foo + """)) + mod = crackfortran.crackfortran([str(f_path)]) + assert len(mod) == 1 + mod = mod[0] + assert 'private' in mod['vars']['a']['attrspec'] + assert 'public' not in mod['vars']['a']['attrspec'] + assert 'private' in mod['vars']['b']['attrspec'] + assert 'public' not in mod['vars']['b']['attrspec'] + assert 'private' not in mod['vars']['seta']['attrspec'] + assert 'public' in mod['vars']['seta']['attrspec'] + + def test_defaultPublic(self, tmp_path): + f_path = tmp_path / "mod.f90" + with f_path.open('w') as ff: + ff.write(textwrap.dedent("""\ + module foo + public + integer, private :: a + public :: setA + contains + subroutine setA(v) + integer, intent(in) :: v + a = v + end subroutine setA + end module foo + """)) + mod = crackfortran.crackfortran([str(f_path)]) + assert len(mod) == 1 + mod = mod[0] + assert 'private' in mod['vars']['a']['attrspec'] + assert 'public' not in mod['vars']['a']['attrspec'] + assert 'private' not in mod['vars']['seta']['attrspec'] + assert 'public' in mod['vars']['seta']['attrspec'] + +class TestExternal(util.F2PyTest): + # issue gh-17859: add external attribute support + code = """ + integer(8) function external_as_statement(fcn) + implicit none + external fcn + integer(8) :: fcn + external_as_statement = fcn(0) + end + + integer(8) function external_as_attribute(fcn) + implicit none + integer(8), external :: fcn + external_as_attribute = fcn(0) + end + """ + + def test_external_as_statement(self): + def incr(x): + return x + 123 + r = self.module.external_as_statement(incr) + assert r == 123 + + def test_external_as_attribute(self): + def incr(x): + return x + 123 + r = self.module.external_as_attribute(incr) + assert r == 123 diff --git a/venv/Lib/site-packages/numpy/f2py/tests/test_kind.py b/venv/Lib/site-packages/numpy/f2py/tests/test_kind.py new file mode 100644 index 0000000..a7e2b28 --- /dev/null +++ b/venv/Lib/site-packages/numpy/f2py/tests/test_kind.py @@ -0,0 +1,32 @@ +import os +import pytest + +from numpy.testing import assert_ +from numpy.f2py.crackfortran import ( + _selected_int_kind_func as selected_int_kind, + _selected_real_kind_func as selected_real_kind + ) +from . import util + + +def _path(*a): + return os.path.join(*((os.path.dirname(__file__),) + a)) + + +class TestKind(util.F2PyTest): + sources = [_path('src', 'kind', 'foo.f90')] + + @pytest.mark.slow + def test_all(self): + selectedrealkind = self.module.selectedrealkind + selectedintkind = self.module.selectedintkind + + for i in range(40): + assert_(selectedintkind(i) in [selected_int_kind(i), -1], + 'selectedintkind(%s): expected %r but got %r' % + (i, selected_int_kind(i), selectedintkind(i))) + + for i in range(20): + assert_(selectedrealkind(i) in [selected_real_kind(i), -1], + 'selectedrealkind(%s): expected %r but got %r' % + (i, selected_real_kind(i), selectedrealkind(i))) diff --git a/venv/Lib/site-packages/numpy/f2py/tests/test_mixed.py b/venv/Lib/site-packages/numpy/f2py/tests/test_mixed.py new file mode 100644 index 0000000..04266ca --- /dev/null +++ b/venv/Lib/site-packages/numpy/f2py/tests/test_mixed.py @@ -0,0 +1,35 @@ +import os +import textwrap +import pytest + +from numpy.testing import assert_, assert_equal, IS_PYPY +from . import util + + +def _path(*a): + return os.path.join(*((os.path.dirname(__file__),) + a)) + + +class TestMixed(util.F2PyTest): + sources = [_path('src', 'mixed', 'foo.f'), + _path('src', 'mixed', 'foo_fixed.f90'), + _path('src', 'mixed', 'foo_free.f90')] + + def test_all(self): + assert_(self.module.bar11() == 11) + assert_(self.module.foo_fixed.bar12() == 12) + assert_(self.module.foo_free.bar13() == 13) + + @pytest.mark.xfail(IS_PYPY, + reason="PyPy cannot modify tp_doc after PyType_Ready") + def test_docstring(self): + expected = textwrap.dedent("""\ + a = bar11() + + Wrapper for ``bar11``. + + Returns + ------- + a : int + """) + assert_equal(self.module.bar11.__doc__, expected) diff --git a/venv/Lib/site-packages/numpy/f2py/tests/test_module_doc.py b/venv/Lib/site-packages/numpy/f2py/tests/test_module_doc.py new file mode 100644 index 0000000..4b9555c --- /dev/null +++ b/venv/Lib/site-packages/numpy/f2py/tests/test_module_doc.py @@ -0,0 +1,30 @@ +import os +import sys +import pytest +import textwrap + +from . import util +from numpy.testing import assert_equal, IS_PYPY + + +def _path(*a): + return os.path.join(*((os.path.dirname(__file__),) + a)) + + +class TestModuleDocString(util.F2PyTest): + sources = [_path('src', 'module_data', 'module_data_docstring.f90')] + + @pytest.mark.skipif(sys.platform=='win32', + reason='Fails with MinGW64 Gfortran (Issue #9673)') + @pytest.mark.xfail(IS_PYPY, + reason="PyPy cannot modify tp_doc after PyType_Ready") + def test_module_docstring(self): + assert_equal(self.module.mod.__doc__, + textwrap.dedent('''\ + i : 'i'-scalar + x : 'i'-array(4) + a : 'f'-array(2,3) + b : 'f'-array(-1,-1), not allocated\x00 + foo()\n + Wrapper for ``foo``.\n\n''') + ) diff --git a/venv/Lib/site-packages/numpy/f2py/tests/test_parameter.py b/venv/Lib/site-packages/numpy/f2py/tests/test_parameter.py new file mode 100644 index 0000000..b618271 --- /dev/null +++ b/venv/Lib/site-packages/numpy/f2py/tests/test_parameter.py @@ -0,0 +1,116 @@ +import os +import pytest + +import numpy as np +from numpy.testing import assert_raises, assert_equal + +from . import util + + +def _path(*a): + return os.path.join(*((os.path.dirname(__file__),) + a)) + + +class TestParameters(util.F2PyTest): + # Check that intent(in out) translates as intent(inout) + sources = [_path('src', 'parameter', 'constant_real.f90'), + _path('src', 'parameter', 'constant_integer.f90'), + _path('src', 'parameter', 'constant_both.f90'), + _path('src', 'parameter', 'constant_compound.f90'), + _path('src', 'parameter', 'constant_non_compound.f90'), + ] + + @pytest.mark.slow + def test_constant_real_single(self): + # non-contiguous should raise error + x = np.arange(6, dtype=np.float32)[::2] + assert_raises(ValueError, self.module.foo_single, x) + + # check values with contiguous array + x = np.arange(3, dtype=np.float32) + self.module.foo_single(x) + assert_equal(x, [0 + 1 + 2*3, 1, 2]) + + @pytest.mark.slow + def test_constant_real_double(self): + # non-contiguous should raise error + x = np.arange(6, dtype=np.float64)[::2] + assert_raises(ValueError, self.module.foo_double, x) + + # check values with contiguous array + x = np.arange(3, dtype=np.float64) + self.module.foo_double(x) + assert_equal(x, [0 + 1 + 2*3, 1, 2]) + + @pytest.mark.slow + def test_constant_compound_int(self): + # non-contiguous should raise error + x = np.arange(6, dtype=np.int32)[::2] + assert_raises(ValueError, self.module.foo_compound_int, x) + + # check values with contiguous array + x = np.arange(3, dtype=np.int32) + self.module.foo_compound_int(x) + assert_equal(x, [0 + 1 + 2*6, 1, 2]) + + @pytest.mark.slow + def test_constant_non_compound_int(self): + # check values + x = np.arange(4, dtype=np.int32) + self.module.foo_non_compound_int(x) + assert_equal(x, [0 + 1 + 2 + 3*4, 1, 2, 3]) + + @pytest.mark.slow + def test_constant_integer_int(self): + # non-contiguous should raise error + x = np.arange(6, dtype=np.int32)[::2] + assert_raises(ValueError, self.module.foo_int, x) + + # check values with contiguous array + x = np.arange(3, dtype=np.int32) + self.module.foo_int(x) + assert_equal(x, [0 + 1 + 2*3, 1, 2]) + + @pytest.mark.slow + def test_constant_integer_long(self): + # non-contiguous should raise error + x = np.arange(6, dtype=np.int64)[::2] + assert_raises(ValueError, self.module.foo_long, x) + + # check values with contiguous array + x = np.arange(3, dtype=np.int64) + self.module.foo_long(x) + assert_equal(x, [0 + 1 + 2*3, 1, 2]) + + @pytest.mark.slow + def test_constant_both(self): + # non-contiguous should raise error + x = np.arange(6, dtype=np.float64)[::2] + assert_raises(ValueError, self.module.foo, x) + + # check values with contiguous array + x = np.arange(3, dtype=np.float64) + self.module.foo(x) + assert_equal(x, [0 + 1*3*3 + 2*3*3, 1*3, 2*3]) + + @pytest.mark.slow + def test_constant_no(self): + # non-contiguous should raise error + x = np.arange(6, dtype=np.float64)[::2] + assert_raises(ValueError, self.module.foo_no, x) + + # check values with contiguous array + x = np.arange(3, dtype=np.float64) + self.module.foo_no(x) + assert_equal(x, [0 + 1*3*3 + 2*3*3, 1*3, 2*3]) + + @pytest.mark.slow + def test_constant_sum(self): + # non-contiguous should raise error + x = np.arange(6, dtype=np.float64)[::2] + assert_raises(ValueError, self.module.foo_sum, x) + + # check values with contiguous array + x = np.arange(3, dtype=np.float64) + self.module.foo_sum(x) + assert_equal(x, [0 + 1*3*3 + 2*3*3, 1*3, 2*3]) diff --git a/venv/Lib/site-packages/numpy/f2py/tests/test_quoted_character.py b/venv/Lib/site-packages/numpy/f2py/tests/test_quoted_character.py new file mode 100644 index 0000000..20c7766 --- /dev/null +++ b/venv/Lib/site-packages/numpy/f2py/tests/test_quoted_character.py @@ -0,0 +1,32 @@ +"""See https://github.com/numpy/numpy/pull/10676. + +""" +import sys +import pytest + +from numpy.testing import assert_equal +from . import util + + +class TestQuotedCharacter(util.F2PyTest): + code = """ + SUBROUTINE FOO(OUT1, OUT2, OUT3, OUT4, OUT5, OUT6) + CHARACTER SINGLE, DOUBLE, SEMICOL, EXCLA, OPENPAR, CLOSEPAR + PARAMETER (SINGLE="'", DOUBLE='"', SEMICOL=';', EXCLA="!", + 1 OPENPAR="(", CLOSEPAR=")") + CHARACTER OUT1, OUT2, OUT3, OUT4, OUT5, OUT6 +Cf2py intent(out) OUT1, OUT2, OUT3, OUT4, OUT5, OUT6 + OUT1 = SINGLE + OUT2 = DOUBLE + OUT3 = SEMICOL + OUT4 = EXCLA + OUT5 = OPENPAR + OUT6 = CLOSEPAR + RETURN + END + """ + + @pytest.mark.skipif(sys.platform=='win32', + reason='Fails with MinGW64 Gfortran (Issue #9673)') + def test_quoted_character(self): + assert_equal(self.module.foo(), (b"'", b'"', b';', b'!', b'(', b')')) diff --git a/venv/Lib/site-packages/numpy/f2py/tests/test_regression.py b/venv/Lib/site-packages/numpy/f2py/tests/test_regression.py new file mode 100644 index 0000000..a1b7720 --- /dev/null +++ b/venv/Lib/site-packages/numpy/f2py/tests/test_regression.py @@ -0,0 +1,47 @@ +import os +import pytest + +import numpy as np +from numpy.testing import assert_, assert_raises, assert_equal, assert_string_equal + +from . import util + + +def _path(*a): + return os.path.join(*((os.path.dirname(__file__),) + a)) + + +class TestIntentInOut(util.F2PyTest): + # Check that intent(in out) translates as intent(inout) + sources = [_path('src', 'regression', 'inout.f90')] + + @pytest.mark.slow + def test_inout(self): + # non-contiguous should raise error + x = np.arange(6, dtype=np.float32)[::2] + assert_raises(ValueError, self.module.foo, x) + + # check values with contiguous array + x = np.arange(3, dtype=np.float32) + self.module.foo(x) + assert_equal(x, [3, 1, 2]) + + +class TestNumpyVersionAttribute(util.F2PyTest): + # Check that th attribute __f2py_numpy_version__ is present + # in the compiled module and that has the value np.__version__. + sources = [_path('src', 'regression', 'inout.f90')] + + @pytest.mark.slow + def test_numpy_version_attribute(self): + + # Check that self.module has an attribute named "__f2py_numpy_version__" + assert_(hasattr(self.module, "__f2py_numpy_version__"), + msg="Fortran module does not have __f2py_numpy_version__") + + # Check that the attribute __f2py_numpy_version__ is a string + assert_(isinstance(self.module.__f2py_numpy_version__, str), + msg="__f2py_numpy_version__ is not a string") + + # Check that __f2py_numpy_version__ has the value numpy.__version__ + assert_string_equal(np.__version__, self.module.__f2py_numpy_version__) diff --git a/venv/Lib/site-packages/numpy/f2py/tests/test_return_character.py b/venv/Lib/site-packages/numpy/f2py/tests/test_return_character.py new file mode 100644 index 0000000..429e69b --- /dev/null +++ b/venv/Lib/site-packages/numpy/f2py/tests/test_return_character.py @@ -0,0 +1,145 @@ +import pytest + +from numpy import array +from numpy.testing import assert_ +from . import util +import platform +IS_S390X = platform.machine() == 's390x' + + +class TestReturnCharacter(util.F2PyTest): + + def check_function(self, t, tname): + if tname in ['t0', 't1', 's0', 's1']: + assert_(t(23) == b'2') + r = t('ab') + assert_(r == b'a', repr(r)) + r = t(array('ab')) + assert_(r == b'a', repr(r)) + r = t(array(77, 'u1')) + assert_(r == b'M', repr(r)) + #assert_(_raises(ValueError, t, array([77,87]))) + #assert_(_raises(ValueError, t, array(77))) + elif tname in ['ts', 'ss']: + assert_(t(23) == b'23 ', repr(t(23))) + assert_(t('123456789abcdef') == b'123456789a') + elif tname in ['t5', 's5']: + assert_(t(23) == b'23 ', repr(t(23))) + assert_(t('ab') == b'ab ', repr(t('ab'))) + assert_(t('123456789abcdef') == b'12345') + else: + raise NotImplementedError + + +class TestF77ReturnCharacter(TestReturnCharacter): + code = """ + function t0(value) + character value + character t0 + t0 = value + end + function t1(value) + character*1 value + character*1 t1 + t1 = value + end + function t5(value) + character*5 value + character*5 t5 + t5 = value + end + function ts(value) + character*(*) value + character*(*) ts + ts = value + end + + subroutine s0(t0,value) + character value + character t0 +cf2py intent(out) t0 + t0 = value + end + subroutine s1(t1,value) + character*1 value + character*1 t1 +cf2py intent(out) t1 + t1 = value + end + subroutine s5(t5,value) + character*5 value + character*5 t5 +cf2py intent(out) t5 + t5 = value + end + subroutine ss(ts,value) + character*(*) value + character*10 ts +cf2py intent(out) ts + ts = value + end + """ + + @pytest.mark.xfail(IS_S390X, reason="calback returns ' '") + @pytest.mark.parametrize('name', 't0,t1,t5,s0,s1,s5,ss'.split(',')) + def test_all(self, name): + self.check_function(getattr(self.module, name), name) + + +class TestF90ReturnCharacter(TestReturnCharacter): + suffix = ".f90" + code = """ +module f90_return_char + contains + function t0(value) + character :: value + character :: t0 + t0 = value + end function t0 + function t1(value) + character(len=1) :: value + character(len=1) :: t1 + t1 = value + end function t1 + function t5(value) + character(len=5) :: value + character(len=5) :: t5 + t5 = value + end function t5 + function ts(value) + character(len=*) :: value + character(len=10) :: ts + ts = value + end function ts + + subroutine s0(t0,value) + character :: value + character :: t0 +!f2py intent(out) t0 + t0 = value + end subroutine s0 + subroutine s1(t1,value) + character(len=1) :: value + character(len=1) :: t1 +!f2py intent(out) t1 + t1 = value + end subroutine s1 + subroutine s5(t5,value) + character(len=5) :: value + character(len=5) :: t5 +!f2py intent(out) t5 + t5 = value + end subroutine s5 + subroutine ss(ts,value) + character(len=*) :: value + character(len=10) :: ts +!f2py intent(out) ts + ts = value + end subroutine ss +end module f90_return_char + """ + + @pytest.mark.xfail(IS_S390X, reason="calback returns ' '") + @pytest.mark.parametrize('name', 't0,t1,t5,ts,s0,s1,s5,ss'.split(',')) + def test_all(self, name): + self.check_function(getattr(self.module.f90_return_char, name), name) diff --git a/venv/Lib/site-packages/numpy/f2py/tests/test_return_complex.py b/venv/Lib/site-packages/numpy/f2py/tests/test_return_complex.py new file mode 100644 index 0000000..3d2e2b9 --- /dev/null +++ b/venv/Lib/site-packages/numpy/f2py/tests/test_return_complex.py @@ -0,0 +1,163 @@ +import pytest + +from numpy import array +from numpy.testing import assert_, assert_raises +from . import util + + +class TestReturnComplex(util.F2PyTest): + + def check_function(self, t, tname): + if tname in ['t0', 't8', 's0', 's8']: + err = 1e-5 + else: + err = 0.0 + assert_(abs(t(234j) - 234.0j) <= err) + assert_(abs(t(234.6) - 234.6) <= err) + assert_(abs(t(234) - 234.0) <= err) + assert_(abs(t(234.6 + 3j) - (234.6 + 3j)) <= err) + #assert_( abs(t('234')-234.)<=err) + #assert_( abs(t('234.6')-234.6)<=err) + assert_(abs(t(-234) + 234.) <= err) + assert_(abs(t([234]) - 234.) <= err) + assert_(abs(t((234,)) - 234.) <= err) + assert_(abs(t(array(234)) - 234.) <= err) + assert_(abs(t(array(23 + 4j, 'F')) - (23 + 4j)) <= err) + assert_(abs(t(array([234])) - 234.) <= err) + assert_(abs(t(array([[234]])) - 234.) <= err) + assert_(abs(t(array([234], 'b')) + 22.) <= err) + assert_(abs(t(array([234], 'h')) - 234.) <= err) + assert_(abs(t(array([234], 'i')) - 234.) <= err) + assert_(abs(t(array([234], 'l')) - 234.) <= err) + assert_(abs(t(array([234], 'q')) - 234.) <= err) + assert_(abs(t(array([234], 'f')) - 234.) <= err) + assert_(abs(t(array([234], 'd')) - 234.) <= err) + assert_(abs(t(array([234 + 3j], 'F')) - (234 + 3j)) <= err) + assert_(abs(t(array([234], 'D')) - 234.) <= err) + + #assert_raises(TypeError, t, array([234], 'a1')) + assert_raises(TypeError, t, 'abc') + + assert_raises(IndexError, t, []) + assert_raises(IndexError, t, ()) + + assert_raises(TypeError, t, t) + assert_raises(TypeError, t, {}) + + try: + r = t(10 ** 400) + assert_(repr(r) in ['(inf+0j)', '(Infinity+0j)'], repr(r)) + except OverflowError: + pass + + +class TestF77ReturnComplex(TestReturnComplex): + code = """ + function t0(value) + complex value + complex t0 + t0 = value + end + function t8(value) + complex*8 value + complex*8 t8 + t8 = value + end + function t16(value) + complex*16 value + complex*16 t16 + t16 = value + end + function td(value) + double complex value + double complex td + td = value + end + + subroutine s0(t0,value) + complex value + complex t0 +cf2py intent(out) t0 + t0 = value + end + subroutine s8(t8,value) + complex*8 value + complex*8 t8 +cf2py intent(out) t8 + t8 = value + end + subroutine s16(t16,value) + complex*16 value + complex*16 t16 +cf2py intent(out) t16 + t16 = value + end + subroutine sd(td,value) + double complex value + double complex td +cf2py intent(out) td + td = value + end + """ + + @pytest.mark.parametrize('name', 't0,t8,t16,td,s0,s8,s16,sd'.split(',')) + def test_all(self, name): + self.check_function(getattr(self.module, name), name) + + +class TestF90ReturnComplex(TestReturnComplex): + suffix = ".f90" + code = """ +module f90_return_complex + contains + function t0(value) + complex :: value + complex :: t0 + t0 = value + end function t0 + function t8(value) + complex(kind=4) :: value + complex(kind=4) :: t8 + t8 = value + end function t8 + function t16(value) + complex(kind=8) :: value + complex(kind=8) :: t16 + t16 = value + end function t16 + function td(value) + double complex :: value + double complex :: td + td = value + end function td + + subroutine s0(t0,value) + complex :: value + complex :: t0 +!f2py intent(out) t0 + t0 = value + end subroutine s0 + subroutine s8(t8,value) + complex(kind=4) :: value + complex(kind=4) :: t8 +!f2py intent(out) t8 + t8 = value + end subroutine s8 + subroutine s16(t16,value) + complex(kind=8) :: value + complex(kind=8) :: t16 +!f2py intent(out) t16 + t16 = value + end subroutine s16 + subroutine sd(td,value) + double complex :: value + double complex :: td +!f2py intent(out) td + td = value + end subroutine sd +end module f90_return_complex + """ + + @pytest.mark.parametrize('name', 't0,t8,t16,td,s0,s8,s16,sd'.split(',')) + def test_all(self, name): + self.check_function(getattr(self.module.f90_return_complex, name), name) diff --git a/venv/Lib/site-packages/numpy/f2py/tests/test_return_integer.py b/venv/Lib/site-packages/numpy/f2py/tests/test_return_integer.py new file mode 100644 index 0000000..0a8121d --- /dev/null +++ b/venv/Lib/site-packages/numpy/f2py/tests/test_return_integer.py @@ -0,0 +1,175 @@ +import pytest + +from numpy import array +from numpy.testing import assert_, assert_raises +from . import util + + +class TestReturnInteger(util.F2PyTest): + + def check_function(self, t, tname): + assert_(t(123) == 123, repr(t(123))) + assert_(t(123.6) == 123) + assert_(t('123') == 123) + assert_(t(-123) == -123) + assert_(t([123]) == 123) + assert_(t((123,)) == 123) + assert_(t(array(123)) == 123) + assert_(t(array([123])) == 123) + assert_(t(array([[123]])) == 123) + assert_(t(array([123], 'b')) == 123) + assert_(t(array([123], 'h')) == 123) + assert_(t(array([123], 'i')) == 123) + assert_(t(array([123], 'l')) == 123) + assert_(t(array([123], 'B')) == 123) + assert_(t(array([123], 'f')) == 123) + assert_(t(array([123], 'd')) == 123) + + #assert_raises(ValueError, t, array([123],'S3')) + assert_raises(ValueError, t, 'abc') + + assert_raises(IndexError, t, []) + assert_raises(IndexError, t, ()) + + assert_raises(Exception, t, t) + assert_raises(Exception, t, {}) + + if tname in ['t8', 's8']: + assert_raises(OverflowError, t, 100000000000000000000000) + assert_raises(OverflowError, t, 10000000011111111111111.23) + + +class TestF77ReturnInteger(TestReturnInteger): + code = """ + function t0(value) + integer value + integer t0 + t0 = value + end + function t1(value) + integer*1 value + integer*1 t1 + t1 = value + end + function t2(value) + integer*2 value + integer*2 t2 + t2 = value + end + function t4(value) + integer*4 value + integer*4 t4 + t4 = value + end + function t8(value) + integer*8 value + integer*8 t8 + t8 = value + end + + subroutine s0(t0,value) + integer value + integer t0 +cf2py intent(out) t0 + t0 = value + end + subroutine s1(t1,value) + integer*1 value + integer*1 t1 +cf2py intent(out) t1 + t1 = value + end + subroutine s2(t2,value) + integer*2 value + integer*2 t2 +cf2py intent(out) t2 + t2 = value + end + subroutine s4(t4,value) + integer*4 value + integer*4 t4 +cf2py intent(out) t4 + t4 = value + end + subroutine s8(t8,value) + integer*8 value + integer*8 t8 +cf2py intent(out) t8 + t8 = value + end + """ + + @pytest.mark.parametrize('name', + 't0,t1,t2,t4,t8,s0,s1,s2,s4,s8'.split(',')) + def test_all(self, name): + self.check_function(getattr(self.module, name), name) + + +class TestF90ReturnInteger(TestReturnInteger): + suffix = ".f90" + code = """ +module f90_return_integer + contains + function t0(value) + integer :: value + integer :: t0 + t0 = value + end function t0 + function t1(value) + integer(kind=1) :: value + integer(kind=1) :: t1 + t1 = value + end function t1 + function t2(value) + integer(kind=2) :: value + integer(kind=2) :: t2 + t2 = value + end function t2 + function t4(value) + integer(kind=4) :: value + integer(kind=4) :: t4 + t4 = value + end function t4 + function t8(value) + integer(kind=8) :: value + integer(kind=8) :: t8 + t8 = value + end function t8 + + subroutine s0(t0,value) + integer :: value + integer :: t0 +!f2py intent(out) t0 + t0 = value + end subroutine s0 + subroutine s1(t1,value) + integer(kind=1) :: value + integer(kind=1) :: t1 +!f2py intent(out) t1 + t1 = value + end subroutine s1 + subroutine s2(t2,value) + integer(kind=2) :: value + integer(kind=2) :: t2 +!f2py intent(out) t2 + t2 = value + end subroutine s2 + subroutine s4(t4,value) + integer(kind=4) :: value + integer(kind=4) :: t4 +!f2py intent(out) t4 + t4 = value + end subroutine s4 + subroutine s8(t8,value) + integer(kind=8) :: value + integer(kind=8) :: t8 +!f2py intent(out) t8 + t8 = value + end subroutine s8 +end module f90_return_integer + """ + + @pytest.mark.parametrize('name', + 't0,t1,t2,t4,t8,s0,s1,s2,s4,s8'.split(',')) + def test_all(self, name): + self.check_function(getattr(self.module.f90_return_integer, name), name) diff --git a/venv/Lib/site-packages/numpy/f2py/tests/test_return_logical.py b/venv/Lib/site-packages/numpy/f2py/tests/test_return_logical.py new file mode 100644 index 0000000..9db939c --- /dev/null +++ b/venv/Lib/site-packages/numpy/f2py/tests/test_return_logical.py @@ -0,0 +1,185 @@ +import pytest + +from numpy import array +from numpy.testing import assert_, assert_raises +from . import util + + +class TestReturnLogical(util.F2PyTest): + + def check_function(self, t): + assert_(t(True) == 1, repr(t(True))) + assert_(t(False) == 0, repr(t(False))) + assert_(t(0) == 0) + assert_(t(None) == 0) + assert_(t(0.0) == 0) + assert_(t(0j) == 0) + assert_(t(1j) == 1) + assert_(t(234) == 1) + assert_(t(234.6) == 1) + assert_(t(234.6 + 3j) == 1) + assert_(t('234') == 1) + assert_(t('aaa') == 1) + assert_(t('') == 0) + assert_(t([]) == 0) + assert_(t(()) == 0) + assert_(t({}) == 0) + assert_(t(t) == 1) + assert_(t(-234) == 1) + assert_(t(10 ** 100) == 1) + assert_(t([234]) == 1) + assert_(t((234,)) == 1) + assert_(t(array(234)) == 1) + assert_(t(array([234])) == 1) + assert_(t(array([[234]])) == 1) + assert_(t(array([234], 'b')) == 1) + assert_(t(array([234], 'h')) == 1) + assert_(t(array([234], 'i')) == 1) + assert_(t(array([234], 'l')) == 1) + assert_(t(array([234], 'f')) == 1) + assert_(t(array([234], 'd')) == 1) + assert_(t(array([234 + 3j], 'F')) == 1) + assert_(t(array([234], 'D')) == 1) + assert_(t(array(0)) == 0) + assert_(t(array([0])) == 0) + assert_(t(array([[0]])) == 0) + assert_(t(array([0j])) == 0) + assert_(t(array([1])) == 1) + assert_raises(ValueError, t, array([0, 0])) + + +class TestF77ReturnLogical(TestReturnLogical): + code = """ + function t0(value) + logical value + logical t0 + t0 = value + end + function t1(value) + logical*1 value + logical*1 t1 + t1 = value + end + function t2(value) + logical*2 value + logical*2 t2 + t2 = value + end + function t4(value) + logical*4 value + logical*4 t4 + t4 = value + end +c function t8(value) +c logical*8 value +c logical*8 t8 +c t8 = value +c end + + subroutine s0(t0,value) + logical value + logical t0 +cf2py intent(out) t0 + t0 = value + end + subroutine s1(t1,value) + logical*1 value + logical*1 t1 +cf2py intent(out) t1 + t1 = value + end + subroutine s2(t2,value) + logical*2 value + logical*2 t2 +cf2py intent(out) t2 + t2 = value + end + subroutine s4(t4,value) + logical*4 value + logical*4 t4 +cf2py intent(out) t4 + t4 = value + end +c subroutine s8(t8,value) +c logical*8 value +c logical*8 t8 +cf2py intent(out) t8 +c t8 = value +c end + """ + + @pytest.mark.slow + @pytest.mark.parametrize('name', 't0,t1,t2,t4,s0,s1,s2,s4'.split(',')) + def test_all(self, name): + self.check_function(getattr(self.module, name)) + + +class TestF90ReturnLogical(TestReturnLogical): + suffix = ".f90" + code = """ +module f90_return_logical + contains + function t0(value) + logical :: value + logical :: t0 + t0 = value + end function t0 + function t1(value) + logical(kind=1) :: value + logical(kind=1) :: t1 + t1 = value + end function t1 + function t2(value) + logical(kind=2) :: value + logical(kind=2) :: t2 + t2 = value + end function t2 + function t4(value) + logical(kind=4) :: value + logical(kind=4) :: t4 + t4 = value + end function t4 + function t8(value) + logical(kind=8) :: value + logical(kind=8) :: t8 + t8 = value + end function t8 + + subroutine s0(t0,value) + logical :: value + logical :: t0 +!f2py intent(out) t0 + t0 = value + end subroutine s0 + subroutine s1(t1,value) + logical(kind=1) :: value + logical(kind=1) :: t1 +!f2py intent(out) t1 + t1 = value + end subroutine s1 + subroutine s2(t2,value) + logical(kind=2) :: value + logical(kind=2) :: t2 +!f2py intent(out) t2 + t2 = value + end subroutine s2 + subroutine s4(t4,value) + logical(kind=4) :: value + logical(kind=4) :: t4 +!f2py intent(out) t4 + t4 = value + end subroutine s4 + subroutine s8(t8,value) + logical(kind=8) :: value + logical(kind=8) :: t8 +!f2py intent(out) t8 + t8 = value + end subroutine s8 +end module f90_return_logical + """ + + @pytest.mark.slow + @pytest.mark.parametrize('name', + 't0,t1,t2,t4,t8,s0,s1,s2,s4,s8'.split(',')) + def test_all(self, name): + self.check_function(getattr(self.module.f90_return_logical, name)) diff --git a/venv/Lib/site-packages/numpy/f2py/tests/test_return_real.py b/venv/Lib/site-packages/numpy/f2py/tests/test_return_real.py new file mode 100644 index 0000000..8e5022a --- /dev/null +++ b/venv/Lib/site-packages/numpy/f2py/tests/test_return_real.py @@ -0,0 +1,203 @@ +import platform +import pytest + +from numpy import array +from numpy.testing import assert_, assert_raises +from . import util + + +class TestReturnReal(util.F2PyTest): + + def check_function(self, t, tname): + if tname in ['t0', 't4', 's0', 's4']: + err = 1e-5 + else: + err = 0.0 + assert_(abs(t(234) - 234.0) <= err) + assert_(abs(t(234.6) - 234.6) <= err) + assert_(abs(t('234') - 234) <= err) + assert_(abs(t('234.6') - 234.6) <= err) + assert_(abs(t(-234) + 234) <= err) + assert_(abs(t([234]) - 234) <= err) + assert_(abs(t((234,)) - 234.) <= err) + assert_(abs(t(array(234)) - 234.) <= err) + assert_(abs(t(array([234])) - 234.) <= err) + assert_(abs(t(array([[234]])) - 234.) <= err) + assert_(abs(t(array([234], 'b')) + 22) <= err) + assert_(abs(t(array([234], 'h')) - 234.) <= err) + assert_(abs(t(array([234], 'i')) - 234.) <= err) + assert_(abs(t(array([234], 'l')) - 234.) <= err) + assert_(abs(t(array([234], 'B')) - 234.) <= err) + assert_(abs(t(array([234], 'f')) - 234.) <= err) + assert_(abs(t(array([234], 'd')) - 234.) <= err) + if tname in ['t0', 't4', 's0', 's4']: + assert_(t(1e200) == t(1e300)) # inf + + #assert_raises(ValueError, t, array([234], 'S1')) + assert_raises(ValueError, t, 'abc') + + assert_raises(IndexError, t, []) + assert_raises(IndexError, t, ()) + + assert_raises(Exception, t, t) + assert_raises(Exception, t, {}) + + try: + r = t(10 ** 400) + assert_(repr(r) in ['inf', 'Infinity'], repr(r)) + except OverflowError: + pass + + + +@pytest.mark.skipif( + platform.system() == 'Darwin', + reason="Prone to error when run with numpy/f2py/tests on mac os, " + "but not when run in isolation") +class TestCReturnReal(TestReturnReal): + suffix = ".pyf" + module_name = "c_ext_return_real" + code = """ +python module c_ext_return_real +usercode \'\'\' +float t4(float value) { return value; } +void s4(float *t4, float value) { *t4 = value; } +double t8(double value) { return value; } +void s8(double *t8, double value) { *t8 = value; } +\'\'\' +interface + function t4(value) + real*4 intent(c) :: t4,value + end + function t8(value) + real*8 intent(c) :: t8,value + end + subroutine s4(t4,value) + intent(c) s4 + real*4 intent(out) :: t4 + real*4 intent(c) :: value + end + subroutine s8(t8,value) + intent(c) s8 + real*8 intent(out) :: t8 + real*8 intent(c) :: value + end +end interface +end python module c_ext_return_real + """ + + @pytest.mark.parametrize('name', 't4,t8,s4,s8'.split(',')) + def test_all(self, name): + self.check_function(getattr(self.module, name), name) + + +class TestF77ReturnReal(TestReturnReal): + code = """ + function t0(value) + real value + real t0 + t0 = value + end + function t4(value) + real*4 value + real*4 t4 + t4 = value + end + function t8(value) + real*8 value + real*8 t8 + t8 = value + end + function td(value) + double precision value + double precision td + td = value + end + + subroutine s0(t0,value) + real value + real t0 +cf2py intent(out) t0 + t0 = value + end + subroutine s4(t4,value) + real*4 value + real*4 t4 +cf2py intent(out) t4 + t4 = value + end + subroutine s8(t8,value) + real*8 value + real*8 t8 +cf2py intent(out) t8 + t8 = value + end + subroutine sd(td,value) + double precision value + double precision td +cf2py intent(out) td + td = value + end + """ + + @pytest.mark.parametrize('name', 't0,t4,t8,td,s0,s4,s8,sd'.split(',')) + def test_all(self, name): + self.check_function(getattr(self.module, name), name) + + +class TestF90ReturnReal(TestReturnReal): + suffix = ".f90" + code = """ +module f90_return_real + contains + function t0(value) + real :: value + real :: t0 + t0 = value + end function t0 + function t4(value) + real(kind=4) :: value + real(kind=4) :: t4 + t4 = value + end function t4 + function t8(value) + real(kind=8) :: value + real(kind=8) :: t8 + t8 = value + end function t8 + function td(value) + double precision :: value + double precision :: td + td = value + end function td + + subroutine s0(t0,value) + real :: value + real :: t0 +!f2py intent(out) t0 + t0 = value + end subroutine s0 + subroutine s4(t4,value) + real(kind=4) :: value + real(kind=4) :: t4 +!f2py intent(out) t4 + t4 = value + end subroutine s4 + subroutine s8(t8,value) + real(kind=8) :: value + real(kind=8) :: t8 +!f2py intent(out) t8 + t8 = value + end subroutine s8 + subroutine sd(td,value) + double precision :: value + double precision :: td +!f2py intent(out) td + td = value + end subroutine sd +end module f90_return_real + """ + + @pytest.mark.parametrize('name', 't0,t4,t8,td,s0,s4,s8,sd'.split(',')) + def test_all(self, name): + self.check_function(getattr(self.module.f90_return_real, name), name) diff --git a/venv/Lib/site-packages/numpy/f2py/tests/test_semicolon_split.py b/venv/Lib/site-packages/numpy/f2py/tests/test_semicolon_split.py new file mode 100644 index 0000000..d8b4bf2 --- /dev/null +++ b/venv/Lib/site-packages/numpy/f2py/tests/test_semicolon_split.py @@ -0,0 +1,63 @@ +import platform +import pytest + +from . import util +from numpy.testing import assert_equal + +@pytest.mark.skipif( + platform.system() == 'Darwin', + reason="Prone to error when run with numpy/f2py/tests on mac os, " + "but not when run in isolation") +class TestMultiline(util.F2PyTest): + suffix = ".pyf" + module_name = "multiline" + code = """ +python module {module} + usercode ''' +void foo(int* x) {{ + char dummy = ';'; + *x = 42; +}} +''' + interface + subroutine foo(x) + intent(c) foo + integer intent(out) :: x + end subroutine foo + end interface +end python module {module} + """.format(module=module_name) + + def test_multiline(self): + assert_equal(self.module.foo(), 42) + + +@pytest.mark.skipif( + platform.system() == 'Darwin', + reason="Prone to error when run with numpy/f2py/tests on mac os, " + "but not when run in isolation") +class TestCallstatement(util.F2PyTest): + suffix = ".pyf" + module_name = "callstatement" + code = """ +python module {module} + usercode ''' +void foo(int* x) {{ +}} +''' + interface + subroutine foo(x) + intent(c) foo + integer intent(out) :: x + callprotoargument int* + callstatement {{ & + ; & + x = 42; & + }} + end subroutine foo + end interface +end python module {module} + """.format(module=module_name) + + def test_callstatement(self): + assert_equal(self.module.foo(), 42) diff --git a/venv/Lib/site-packages/numpy/f2py/tests/test_size.py b/venv/Lib/site-packages/numpy/f2py/tests/test_size.py new file mode 100644 index 0000000..b609fa7 --- /dev/null +++ b/venv/Lib/site-packages/numpy/f2py/tests/test_size.py @@ -0,0 +1,49 @@ +import os +import pytest + +from numpy.testing import assert_equal +from . import util + + +def _path(*a): + return os.path.join(*((os.path.dirname(__file__),) + a)) + + +class TestSizeSumExample(util.F2PyTest): + sources = [_path('src', 'size', 'foo.f90')] + + @pytest.mark.slow + def test_all(self): + r = self.module.foo([[]]) + assert_equal(r, [0], repr(r)) + + r = self.module.foo([[1, 2]]) + assert_equal(r, [3], repr(r)) + + r = self.module.foo([[1, 2], [3, 4]]) + assert_equal(r, [3, 7], repr(r)) + + r = self.module.foo([[1, 2], [3, 4], [5, 6]]) + assert_equal(r, [3, 7, 11], repr(r)) + + @pytest.mark.slow + def test_transpose(self): + r = self.module.trans([[]]) + assert_equal(r.T, [[]], repr(r)) + + r = self.module.trans([[1, 2]]) + assert_equal(r, [[1], [2]], repr(r)) + + r = self.module.trans([[1, 2, 3], [4, 5, 6]]) + assert_equal(r, [[1, 4], [2, 5], [3, 6]], repr(r)) + + @pytest.mark.slow + def test_flatten(self): + r = self.module.flatten([[]]) + assert_equal(r, [], repr(r)) + + r = self.module.flatten([[1, 2]]) + assert_equal(r, [1, 2], repr(r)) + + r = self.module.flatten([[1, 2, 3], [4, 5, 6]]) + assert_equal(r, [1, 2, 3, 4, 5, 6], repr(r)) diff --git a/venv/Lib/site-packages/numpy/f2py/tests/test_string.py b/venv/Lib/site-packages/numpy/f2py/tests/test_string.py new file mode 100644 index 0000000..e3ec96a --- /dev/null +++ b/venv/Lib/site-packages/numpy/f2py/tests/test_string.py @@ -0,0 +1,22 @@ +import os +import pytest + +from numpy.testing import assert_array_equal +import numpy as np +from . import util + + +def _path(*a): + return os.path.join(*((os.path.dirname(__file__),) + a)) + +class TestString(util.F2PyTest): + sources = [_path('src', 'string', 'char.f90')] + + @pytest.mark.slow + def test_char(self): + strings = np.array(['ab', 'cd', 'ef'], dtype='c').T + inp, out = self.module.char_test.change_strings(strings, strings.shape[1]) + assert_array_equal(inp, strings) + expected = strings.copy() + expected[1, :] = 'AAA' + assert_array_equal(out, expected) diff --git a/venv/Lib/site-packages/numpy/f2py/tests/util.py b/venv/Lib/site-packages/numpy/f2py/tests/util.py new file mode 100644 index 0000000..d5fa76f --- /dev/null +++ b/venv/Lib/site-packages/numpy/f2py/tests/util.py @@ -0,0 +1,359 @@ +""" +Utility functions for + +- building and importing modules on test time, using a temporary location +- detecting if compilers are present + +""" +import os +import sys +import subprocess +import tempfile +import shutil +import atexit +import textwrap +import re +import pytest + +from numpy.compat import asbytes, asstr +from numpy.testing import temppath +from importlib import import_module + +# +# Maintaining a temporary module directory +# + +_module_dir = None +_module_num = 5403 + + +def _cleanup(): + global _module_dir + if _module_dir is not None: + try: + sys.path.remove(_module_dir) + except ValueError: + pass + try: + shutil.rmtree(_module_dir) + except (IOError, OSError): + pass + _module_dir = None + + +def get_module_dir(): + global _module_dir + if _module_dir is None: + _module_dir = tempfile.mkdtemp() + atexit.register(_cleanup) + if _module_dir not in sys.path: + sys.path.insert(0, _module_dir) + return _module_dir + + +def get_temp_module_name(): + # Assume single-threaded, and the module dir usable only by this thread + global _module_num + d = get_module_dir() + name = "_test_ext_module_%d" % _module_num + _module_num += 1 + if name in sys.modules: + # this should not be possible, but check anyway + raise RuntimeError("Temporary module name already in use.") + return name + + +def _memoize(func): + memo = {} + + def wrapper(*a, **kw): + key = repr((a, kw)) + if key not in memo: + try: + memo[key] = func(*a, **kw) + except Exception as e: + memo[key] = e + raise + ret = memo[key] + if isinstance(ret, Exception): + raise ret + return ret + wrapper.__name__ = func.__name__ + return wrapper + +# +# Building modules +# + + +@_memoize +def build_module(source_files, options=[], skip=[], only=[], module_name=None): + """ + Compile and import a f2py module, built from the given files. + + """ + + code = ("import sys; sys.path = %s; import numpy.f2py as f2py2e; " + "f2py2e.main()" % repr(sys.path)) + + d = get_module_dir() + + # Copy files + dst_sources = [] + f2py_sources = [] + for fn in source_files: + if not os.path.isfile(fn): + raise RuntimeError("%s is not a file" % fn) + dst = os.path.join(d, os.path.basename(fn)) + shutil.copyfile(fn, dst) + dst_sources.append(dst) + + base, ext = os.path.splitext(dst) + if ext in ('.f90', '.f', '.c', '.pyf'): + f2py_sources.append(dst) + + # Prepare options + if module_name is None: + module_name = get_temp_module_name() + f2py_opts = ['-c', '-m', module_name] + options + f2py_sources + if skip: + f2py_opts += ['skip:'] + skip + if only: + f2py_opts += ['only:'] + only + + # Build + cwd = os.getcwd() + try: + os.chdir(d) + cmd = [sys.executable, '-c', code] + f2py_opts + p = subprocess.Popen(cmd, stdout=subprocess.PIPE, + stderr=subprocess.STDOUT) + out, err = p.communicate() + if p.returncode != 0: + raise RuntimeError("Running f2py failed: %s\n%s" + % (cmd[4:], asstr(out))) + finally: + os.chdir(cwd) + + # Partial cleanup + for fn in dst_sources: + os.unlink(fn) + + # Import + return import_module(module_name) + + +@_memoize +def build_code(source_code, options=[], skip=[], only=[], suffix=None, + module_name=None): + """ + Compile and import Fortran code using f2py. + + """ + if suffix is None: + suffix = '.f' + with temppath(suffix=suffix) as path: + with open(path, 'w') as f: + f.write(source_code) + return build_module([path], options=options, skip=skip, only=only, + module_name=module_name) + +# +# Check if compilers are available at all... +# + +_compiler_status = None + + +def _get_compiler_status(): + global _compiler_status + if _compiler_status is not None: + return _compiler_status + + _compiler_status = (False, False, False) + + # XXX: this is really ugly. But I don't know how to invoke Distutils + # in a safer way... + code = textwrap.dedent("""\ + import os + import sys + sys.path = %(syspath)s + + def configuration(parent_name='',top_path=None): + global config + from numpy.distutils.misc_util import Configuration + config = Configuration('', parent_name, top_path) + return config + + from numpy.distutils.core import setup + setup(configuration=configuration) + + config_cmd = config.get_config_cmd() + have_c = config_cmd.try_compile('void foo() {}') + print('COMPILERS:%%d,%%d,%%d' %% (have_c, + config.have_f77c(), + config.have_f90c())) + sys.exit(99) + """) + code = code % dict(syspath=repr(sys.path)) + + tmpdir = tempfile.mkdtemp() + try: + script = os.path.join(tmpdir, 'setup.py') + + with open(script, 'w') as f: + f.write(code) + + cmd = [sys.executable, 'setup.py', 'config'] + p = subprocess.Popen(cmd, stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + cwd=tmpdir) + out, err = p.communicate() + finally: + shutil.rmtree(tmpdir) + + m = re.search(br'COMPILERS:(\d+),(\d+),(\d+)', out) + if m: + _compiler_status = (bool(int(m.group(1))), bool(int(m.group(2))), + bool(int(m.group(3)))) + # Finished + return _compiler_status + + +def has_c_compiler(): + return _get_compiler_status()[0] + + +def has_f77_compiler(): + return _get_compiler_status()[1] + + +def has_f90_compiler(): + return _get_compiler_status()[2] + +# +# Building with distutils +# + + +@_memoize +def build_module_distutils(source_files, config_code, module_name, **kw): + """ + Build a module via distutils and import it. + + """ + from numpy.distutils.misc_util import Configuration + from numpy.distutils.core import setup + + d = get_module_dir() + + # Copy files + dst_sources = [] + for fn in source_files: + if not os.path.isfile(fn): + raise RuntimeError("%s is not a file" % fn) + dst = os.path.join(d, os.path.basename(fn)) + shutil.copyfile(fn, dst) + dst_sources.append(dst) + + # Build script + config_code = textwrap.dedent(config_code).replace("\n", "\n ") + + code = textwrap.dedent("""\ + import os + import sys + sys.path = %(syspath)s + + def configuration(parent_name='',top_path=None): + from numpy.distutils.misc_util import Configuration + config = Configuration('', parent_name, top_path) + %(config_code)s + return config + + if __name__ == "__main__": + from numpy.distutils.core import setup + setup(configuration=configuration) + """) % dict(config_code=config_code, syspath=repr(sys.path)) + + script = os.path.join(d, get_temp_module_name() + '.py') + dst_sources.append(script) + with open(script, 'wb') as f: + f.write(asbytes(code)) + + # Build + cwd = os.getcwd() + try: + os.chdir(d) + cmd = [sys.executable, script, 'build_ext', '-i'] + p = subprocess.Popen(cmd, stdout=subprocess.PIPE, + stderr=subprocess.STDOUT) + out, err = p.communicate() + if p.returncode != 0: + raise RuntimeError("Running distutils build failed: %s\n%s" + % (cmd[4:], asstr(out))) + finally: + os.chdir(cwd) + + # Partial cleanup + for fn in dst_sources: + os.unlink(fn) + + # Import + __import__(module_name) + return sys.modules[module_name] + +# +# Unittest convenience +# + + +class F2PyTest: + code = None + sources = None + options = [] + skip = [] + only = [] + suffix = '.f' + module = None + module_name = None + + def setup(self): + if sys.platform == 'win32': + pytest.skip('Fails with MinGW64 Gfortran (Issue #9673)') + + if self.module is not None: + return + + # Check compiler availability first + if not has_c_compiler(): + pytest.skip("No C compiler available") + + codes = [] + if self.sources: + codes.extend(self.sources) + if self.code is not None: + codes.append(self.suffix) + + needs_f77 = False + needs_f90 = False + for fn in codes: + if fn.endswith('.f'): + needs_f77 = True + elif fn.endswith('.f90'): + needs_f90 = True + if needs_f77 and not has_f77_compiler(): + pytest.skip("No Fortran 77 compiler available") + if needs_f90 and not has_f90_compiler(): + pytest.skip("No Fortran 90 compiler available") + + # Build the module + if self.code is not None: + self.module = build_code(self.code, options=self.options, + skip=self.skip, only=self.only, + suffix=self.suffix, + module_name=self.module_name) + + if self.sources is not None: + self.module = build_module(self.sources, options=self.options, + skip=self.skip, only=self.only, + module_name=self.module_name) diff --git a/venv/Lib/site-packages/numpy/f2py/use_rules.py b/venv/Lib/site-packages/numpy/f2py/use_rules.py new file mode 100644 index 0000000..f1b71e8 --- /dev/null +++ b/venv/Lib/site-packages/numpy/f2py/use_rules.py @@ -0,0 +1,113 @@ +#!/usr/bin/env python3 +""" + +Build 'use others module data' mechanism for f2py2e. + +Unfinished. + +Copyright 2000 Pearu Peterson all rights reserved, +Pearu Peterson +Permission to use, modify, and distribute this software is given under the +terms of the NumPy License. + +NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. +$Date: 2000/09/10 12:35:43 $ +Pearu Peterson + +""" +__version__ = "$Revision: 1.3 $"[10:-1] + +f2py_version = 'See `f2py -v`' + + +from .auxfuncs import ( + applyrules, dictappend, gentitle, hasnote, outmess +) + + +usemodule_rules = { + 'body': """ +#begintitle# +static char doc_#apiname#[] = \"\\\nVariable wrapper signature:\\n\\ +\t #name# = get_#name#()\\n\\ +Arguments:\\n\\ +#docstr#\"; +extern F_MODFUNC(#usemodulename#,#USEMODULENAME#,#realname#,#REALNAME#); +static PyObject *#apiname#(PyObject *capi_self, PyObject *capi_args) { +/*#decl#*/ +\tif (!PyArg_ParseTuple(capi_args, \"\")) goto capi_fail; +printf(\"c: %d\\n\",F_MODFUNC(#usemodulename#,#USEMODULENAME#,#realname#,#REALNAME#)); +\treturn Py_BuildValue(\"\"); +capi_fail: +\treturn NULL; +} +""", + 'method': '\t{\"get_#name#\",#apiname#,METH_VARARGS|METH_KEYWORDS,doc_#apiname#},', + 'need': ['F_MODFUNC'] +} + +################ + + +def buildusevars(m, r): + ret = {} + outmess( + '\t\tBuilding use variable hooks for module "%s" (feature only for F90/F95)...\n' % (m['name'])) + varsmap = {} + revmap = {} + if 'map' in r: + for k in r['map'].keys(): + if r['map'][k] in revmap: + outmess('\t\t\tVariable "%s<=%s" is already mapped by "%s". Skipping.\n' % ( + r['map'][k], k, revmap[r['map'][k]])) + else: + revmap[r['map'][k]] = k + if 'only' in r and r['only']: + for v in r['map'].keys(): + if r['map'][v] in m['vars']: + + if revmap[r['map'][v]] == v: + varsmap[v] = r['map'][v] + else: + outmess('\t\t\tIgnoring map "%s=>%s". See above.\n' % + (v, r['map'][v])) + else: + outmess( + '\t\t\tNo definition for variable "%s=>%s". Skipping.\n' % (v, r['map'][v])) + else: + for v in m['vars'].keys(): + if v in revmap: + varsmap[v] = revmap[v] + else: + varsmap[v] = v + for v in varsmap.keys(): + ret = dictappend(ret, buildusevar(v, varsmap[v], m['vars'], m['name'])) + return ret + + +def buildusevar(name, realname, vars, usemodulename): + outmess('\t\t\tConstructing wrapper function for variable "%s=>%s"...\n' % ( + name, realname)) + ret = {} + vrd = {'name': name, + 'realname': realname, + 'REALNAME': realname.upper(), + 'usemodulename': usemodulename, + 'USEMODULENAME': usemodulename.upper(), + 'texname': name.replace('_', '\\_'), + 'begintitle': gentitle('%s=>%s' % (name, realname)), + 'endtitle': gentitle('end of %s=>%s' % (name, realname)), + 'apiname': '#modulename#_use_%s_from_%s' % (realname, usemodulename) + } + nummap = {0: 'Ro', 1: 'Ri', 2: 'Rii', 3: 'Riii', 4: 'Riv', + 5: 'Rv', 6: 'Rvi', 7: 'Rvii', 8: 'Rviii', 9: 'Rix'} + vrd['texnamename'] = name + for i in nummap.keys(): + vrd['texnamename'] = vrd['texnamename'].replace(repr(i), nummap[i]) + if hasnote(vars[realname]): + vrd['note'] = vars[realname]['note'] + rd = dictappend({}, vrd) + + print(name, realname, vars[realname]) + ret = applyrules(usemodule_rules, rd) + return ret diff --git a/venv/Lib/site-packages/numpy/fft/__init__.py b/venv/Lib/site-packages/numpy/fft/__init__.py new file mode 100644 index 0000000..a86bb3a --- /dev/null +++ b/venv/Lib/site-packages/numpy/fft/__init__.py @@ -0,0 +1,208 @@ +""" +Discrete Fourier Transform (:mod:`numpy.fft`) +============================================= + +.. currentmodule:: numpy.fft + +The SciPy module `scipy.fft` is a more comprehensive superset +of ``numpy.fft``, which includes only a basic set of routines. + +Standard FFTs +------------- + +.. autosummary:: + :toctree: generated/ + + fft Discrete Fourier transform. + ifft Inverse discrete Fourier transform. + fft2 Discrete Fourier transform in two dimensions. + ifft2 Inverse discrete Fourier transform in two dimensions. + fftn Discrete Fourier transform in N-dimensions. + ifftn Inverse discrete Fourier transform in N dimensions. + +Real FFTs +--------- + +.. autosummary:: + :toctree: generated/ + + rfft Real discrete Fourier transform. + irfft Inverse real discrete Fourier transform. + rfft2 Real discrete Fourier transform in two dimensions. + irfft2 Inverse real discrete Fourier transform in two dimensions. + rfftn Real discrete Fourier transform in N dimensions. + irfftn Inverse real discrete Fourier transform in N dimensions. + +Hermitian FFTs +-------------- + +.. autosummary:: + :toctree: generated/ + + hfft Hermitian discrete Fourier transform. + ihfft Inverse Hermitian discrete Fourier transform. + +Helper routines +--------------- + +.. autosummary:: + :toctree: generated/ + + fftfreq Discrete Fourier Transform sample frequencies. + rfftfreq DFT sample frequencies (for usage with rfft, irfft). + fftshift Shift zero-frequency component to center of spectrum. + ifftshift Inverse of fftshift. + + +Background information +---------------------- + +Fourier analysis is fundamentally a method for expressing a function as a +sum of periodic components, and for recovering the function from those +components. When both the function and its Fourier transform are +replaced with discretized counterparts, it is called the discrete Fourier +transform (DFT). The DFT has become a mainstay of numerical computing in +part because of a very fast algorithm for computing it, called the Fast +Fourier Transform (FFT), which was known to Gauss (1805) and was brought +to light in its current form by Cooley and Tukey [CT]_. Press et al. [NR]_ +provide an accessible introduction to Fourier analysis and its +applications. + +Because the discrete Fourier transform separates its input into +components that contribute at discrete frequencies, it has a great number +of applications in digital signal processing, e.g., for filtering, and in +this context the discretized input to the transform is customarily +referred to as a *signal*, which exists in the *time domain*. The output +is called a *spectrum* or *transform* and exists in the *frequency +domain*. + +Implementation details +---------------------- + +There are many ways to define the DFT, varying in the sign of the +exponent, normalization, etc. In this implementation, the DFT is defined +as + +.. math:: + A_k = \\sum_{m=0}^{n-1} a_m \\exp\\left\\{-2\\pi i{mk \\over n}\\right\\} + \\qquad k = 0,\\ldots,n-1. + +The DFT is in general defined for complex inputs and outputs, and a +single-frequency component at linear frequency :math:`f` is +represented by a complex exponential +:math:`a_m = \\exp\\{2\\pi i\\,f m\\Delta t\\}`, where :math:`\\Delta t` +is the sampling interval. + +The values in the result follow so-called "standard" order: If ``A = +fft(a, n)``, then ``A[0]`` contains the zero-frequency term (the sum of +the signal), which is always purely real for real inputs. Then ``A[1:n/2]`` +contains the positive-frequency terms, and ``A[n/2+1:]`` contains the +negative-frequency terms, in order of decreasingly negative frequency. +For an even number of input points, ``A[n/2]`` represents both positive and +negative Nyquist frequency, and is also purely real for real input. For +an odd number of input points, ``A[(n-1)/2]`` contains the largest positive +frequency, while ``A[(n+1)/2]`` contains the largest negative frequency. +The routine ``np.fft.fftfreq(n)`` returns an array giving the frequencies +of corresponding elements in the output. The routine +``np.fft.fftshift(A)`` shifts transforms and their frequencies to put the +zero-frequency components in the middle, and ``np.fft.ifftshift(A)`` undoes +that shift. + +When the input `a` is a time-domain signal and ``A = fft(a)``, ``np.abs(A)`` +is its amplitude spectrum and ``np.abs(A)**2`` is its power spectrum. +The phase spectrum is obtained by ``np.angle(A)``. + +The inverse DFT is defined as + +.. math:: + a_m = \\frac{1}{n}\\sum_{k=0}^{n-1}A_k\\exp\\left\\{2\\pi i{mk\\over n}\\right\\} + \\qquad m = 0,\\ldots,n-1. + +It differs from the forward transform by the sign of the exponential +argument and the default normalization by :math:`1/n`. + +Type Promotion +-------------- + +`numpy.fft` promotes ``float32`` and ``complex64`` arrays to ``float64`` and +``complex128`` arrays respectively. For an FFT implementation that does not +promote input arrays, see `scipy.fftpack`. + +Normalization +------------- + +The argument ``norm`` indicates which direction of the pair of direct/inverse +transforms is scaled and with what normalization factor. +The default normalization (``"backward"``) has the direct (forward) transforms +unscaled and the inverse (backward) transforms scaled by :math:`1/n`. It is +possible to obtain unitary transforms by setting the keyword argument ``norm`` +to ``"ortho"`` so that both direct and inverse transforms are scaled by +:math:`1/\\sqrt{n}`. Finally, setting the keyword argument ``norm`` to +``"forward"`` has the direct transforms scaled by :math:`1/n` and the inverse +transforms unscaled (i.e. exactly opposite to the default ``"backward"``). +`None` is an alias of the default option ``"backward"`` for backward +compatibility. + +Real and Hermitian transforms +----------------------------- + +When the input is purely real, its transform is Hermitian, i.e., the +component at frequency :math:`f_k` is the complex conjugate of the +component at frequency :math:`-f_k`, which means that for real +inputs there is no information in the negative frequency components that +is not already available from the positive frequency components. +The family of `rfft` functions is +designed to operate on real inputs, and exploits this symmetry by +computing only the positive frequency components, up to and including the +Nyquist frequency. Thus, ``n`` input points produce ``n/2+1`` complex +output points. The inverses of this family assumes the same symmetry of +its input, and for an output of ``n`` points uses ``n/2+1`` input points. + +Correspondingly, when the spectrum is purely real, the signal is +Hermitian. The `hfft` family of functions exploits this symmetry by +using ``n/2+1`` complex points in the input (time) domain for ``n`` real +points in the frequency domain. + +In higher dimensions, FFTs are used, e.g., for image analysis and +filtering. The computational efficiency of the FFT means that it can +also be a faster way to compute large convolutions, using the property +that a convolution in the time domain is equivalent to a point-by-point +multiplication in the frequency domain. + +Higher dimensions +----------------- + +In two dimensions, the DFT is defined as + +.. math:: + A_{kl} = \\sum_{m=0}^{M-1} \\sum_{n=0}^{N-1} + a_{mn}\\exp\\left\\{-2\\pi i \\left({mk\\over M}+{nl\\over N}\\right)\\right\\} + \\qquad k = 0, \\ldots, M-1;\\quad l = 0, \\ldots, N-1, + +which extends in the obvious way to higher dimensions, and the inverses +in higher dimensions also extend in the same way. + +References +---------- + +.. [CT] Cooley, James W., and John W. Tukey, 1965, "An algorithm for the + machine calculation of complex Fourier series," *Math. Comput.* + 19: 297-301. + +.. [NR] Press, W., Teukolsky, S., Vetterline, W.T., and Flannery, B.P., + 2007, *Numerical Recipes: The Art of Scientific Computing*, ch. + 12-13. Cambridge Univ. Press, Cambridge, UK. + +Examples +-------- + +For examples, see the various functions. + +""" + +from ._pocketfft import * +from .helper import * + +from numpy._pytesttester import PytestTester +test = PytestTester(__name__) +del PytestTester diff --git a/venv/Lib/site-packages/numpy/fft/__init__.pyi b/venv/Lib/site-packages/numpy/fft/__init__.pyi new file mode 100644 index 0000000..4519051 --- /dev/null +++ b/venv/Lib/site-packages/numpy/fft/__init__.pyi @@ -0,0 +1,20 @@ +from typing import Any + +fft: Any +ifft: Any +rfft: Any +irfft: Any +hfft: Any +ihfft: Any +rfftn: Any +irfftn: Any +rfft2: Any +irfft2: Any +fft2: Any +ifft2: Any +fftn: Any +ifftn: Any +fftshift: Any +ifftshift: Any +fftfreq: Any +rfftfreq: Any diff --git a/venv/Lib/site-packages/numpy/fft/_pocketfft.py b/venv/Lib/site-packages/numpy/fft/_pocketfft.py new file mode 100644 index 0000000..83ac860 --- /dev/null +++ b/venv/Lib/site-packages/numpy/fft/_pocketfft.py @@ -0,0 +1,1403 @@ +""" +Discrete Fourier Transforms + +Routines in this module: + +fft(a, n=None, axis=-1, norm="backward") +ifft(a, n=None, axis=-1, norm="backward") +rfft(a, n=None, axis=-1, norm="backward") +irfft(a, n=None, axis=-1, norm="backward") +hfft(a, n=None, axis=-1, norm="backward") +ihfft(a, n=None, axis=-1, norm="backward") +fftn(a, s=None, axes=None, norm="backward") +ifftn(a, s=None, axes=None, norm="backward") +rfftn(a, s=None, axes=None, norm="backward") +irfftn(a, s=None, axes=None, norm="backward") +fft2(a, s=None, axes=(-2,-1), norm="backward") +ifft2(a, s=None, axes=(-2, -1), norm="backward") +rfft2(a, s=None, axes=(-2,-1), norm="backward") +irfft2(a, s=None, axes=(-2, -1), norm="backward") + +i = inverse transform +r = transform of purely real data +h = Hermite transform +n = n-dimensional transform +2 = 2-dimensional transform +(Note: 2D routines are just nD routines with different default +behavior.) + +""" +__all__ = ['fft', 'ifft', 'rfft', 'irfft', 'hfft', 'ihfft', 'rfftn', + 'irfftn', 'rfft2', 'irfft2', 'fft2', 'ifft2', 'fftn', 'ifftn'] + +import functools + +from numpy.core import asarray, zeros, swapaxes, conjugate, take, sqrt +from . import _pocketfft_internal as pfi +from numpy.core.multiarray import normalize_axis_index +from numpy.core import overrides + + +array_function_dispatch = functools.partial( + overrides.array_function_dispatch, module='numpy.fft') + + +# `inv_norm` is a float by which the result of the transform needs to be +# divided. This replaces the original, more intuitive 'fct` parameter to avoid +# divisions by zero (or alternatively additional checks) in the case of +# zero-length axes during its computation. +def _raw_fft(a, n, axis, is_real, is_forward, inv_norm): + axis = normalize_axis_index(axis, a.ndim) + if n is None: + n = a.shape[axis] + + fct = 1/inv_norm + + if a.shape[axis] != n: + s = list(a.shape) + index = [slice(None)]*len(s) + if s[axis] > n: + index[axis] = slice(0, n) + a = a[tuple(index)] + else: + index[axis] = slice(0, s[axis]) + s[axis] = n + z = zeros(s, a.dtype.char) + z[tuple(index)] = a + a = z + + if axis == a.ndim-1: + r = pfi.execute(a, is_real, is_forward, fct) + else: + a = swapaxes(a, axis, -1) + r = pfi.execute(a, is_real, is_forward, fct) + r = swapaxes(r, axis, -1) + return r + + +def _get_forward_norm(n, norm): + if n < 1: + raise ValueError(f"Invalid number of FFT data points ({n}) specified.") + + if norm is None or norm == "backward": + return 1 + elif norm == "ortho": + return sqrt(n) + elif norm == "forward": + return n + raise ValueError(f'Invalid norm value {norm}; should be "backward",' + '"ortho" or "forward".') + + +def _get_backward_norm(n, norm): + if n < 1: + raise ValueError(f"Invalid number of FFT data points ({n}) specified.") + + if norm is None or norm == "backward": + return n + elif norm == "ortho": + return sqrt(n) + elif norm == "forward": + return 1 + raise ValueError(f'Invalid norm value {norm}; should be "backward", ' + '"ortho" or "forward".') + + +_SWAP_DIRECTION_MAP = {"backward": "forward", None: "forward", + "ortho": "ortho", "forward": "backward"} + + +def _swap_direction(norm): + try: + return _SWAP_DIRECTION_MAP[norm] + except KeyError: + raise ValueError(f'Invalid norm value {norm}; should be "backward", ' + '"ortho" or "forward".') + + +def _fft_dispatcher(a, n=None, axis=None, norm=None): + return (a,) + + +@array_function_dispatch(_fft_dispatcher) +def fft(a, n=None, axis=-1, norm=None): + """ + Compute the one-dimensional discrete Fourier Transform. + + This function computes the one-dimensional *n*-point discrete Fourier + Transform (DFT) with the efficient Fast Fourier Transform (FFT) + algorithm [CT]. + + Parameters + ---------- + a : array_like + Input array, can be complex. + n : int, optional + Length of the transformed axis of the output. + If `n` is smaller than the length of the input, the input is cropped. + If it is larger, the input is padded with zeros. If `n` is not given, + the length of the input along the axis specified by `axis` is used. + axis : int, optional + Axis over which to compute the FFT. If not given, the last axis is + used. + norm : {"backward", "ortho", "forward"}, optional + .. versionadded:: 1.10.0 + + Normalization mode (see `numpy.fft`). Default is "backward". + Indicates which direction of the forward/backward pair of transforms + is scaled and with what normalization factor. + + .. versionadded:: 1.20.0 + + The "backward", "forward" values were added. + + Returns + ------- + out : complex ndarray + The truncated or zero-padded input, transformed along the axis + indicated by `axis`, or the last one if `axis` is not specified. + + Raises + ------ + IndexError + if `axes` is larger than the last axis of `a`. + + See Also + -------- + numpy.fft : for definition of the DFT and conventions used. + ifft : The inverse of `fft`. + fft2 : The two-dimensional FFT. + fftn : The *n*-dimensional FFT. + rfftn : The *n*-dimensional FFT of real input. + fftfreq : Frequency bins for given FFT parameters. + + Notes + ----- + FFT (Fast Fourier Transform) refers to a way the discrete Fourier + Transform (DFT) can be calculated efficiently, by using symmetries in the + calculated terms. The symmetry is highest when `n` is a power of 2, and + the transform is therefore most efficient for these sizes. + + The DFT is defined, with the conventions used in this implementation, in + the documentation for the `numpy.fft` module. + + References + ---------- + .. [CT] Cooley, James W., and John W. Tukey, 1965, "An algorithm for the + machine calculation of complex Fourier series," *Math. Comput.* + 19: 297-301. + + Examples + -------- + >>> np.fft.fft(np.exp(2j * np.pi * np.arange(8) / 8)) + array([-2.33486982e-16+1.14423775e-17j, 8.00000000e+00-1.25557246e-15j, + 2.33486982e-16+2.33486982e-16j, 0.00000000e+00+1.22464680e-16j, + -1.14423775e-17+2.33486982e-16j, 0.00000000e+00+5.20784380e-16j, + 1.14423775e-17+1.14423775e-17j, 0.00000000e+00+1.22464680e-16j]) + + In this example, real input has an FFT which is Hermitian, i.e., symmetric + in the real part and anti-symmetric in the imaginary part, as described in + the `numpy.fft` documentation: + + >>> import matplotlib.pyplot as plt + >>> t = np.arange(256) + >>> sp = np.fft.fft(np.sin(t)) + >>> freq = np.fft.fftfreq(t.shape[-1]) + >>> plt.plot(freq, sp.real, freq, sp.imag) + [, ] + >>> plt.show() + + """ + a = asarray(a) + if n is None: + n = a.shape[axis] + inv_norm = _get_forward_norm(n, norm) + output = _raw_fft(a, n, axis, False, True, inv_norm) + return output + + +@array_function_dispatch(_fft_dispatcher) +def ifft(a, n=None, axis=-1, norm=None): + """ + Compute the one-dimensional inverse discrete Fourier Transform. + + This function computes the inverse of the one-dimensional *n*-point + discrete Fourier transform computed by `fft`. In other words, + ``ifft(fft(a)) == a`` to within numerical accuracy. + For a general description of the algorithm and definitions, + see `numpy.fft`. + + The input should be ordered in the same way as is returned by `fft`, + i.e., + + * ``a[0]`` should contain the zero frequency term, + * ``a[1:n//2]`` should contain the positive-frequency terms, + * ``a[n//2 + 1:]`` should contain the negative-frequency terms, in + increasing order starting from the most negative frequency. + + For an even number of input points, ``A[n//2]`` represents the sum of + the values at the positive and negative Nyquist frequencies, as the two + are aliased together. See `numpy.fft` for details. + + Parameters + ---------- + a : array_like + Input array, can be complex. + n : int, optional + Length of the transformed axis of the output. + If `n` is smaller than the length of the input, the input is cropped. + If it is larger, the input is padded with zeros. If `n` is not given, + the length of the input along the axis specified by `axis` is used. + See notes about padding issues. + axis : int, optional + Axis over which to compute the inverse DFT. If not given, the last + axis is used. + norm : {"backward", "ortho", "forward"}, optional + .. versionadded:: 1.10.0 + + Normalization mode (see `numpy.fft`). Default is "backward". + Indicates which direction of the forward/backward pair of transforms + is scaled and with what normalization factor. + + .. versionadded:: 1.20.0 + + The "backward", "forward" values were added. + + Returns + ------- + out : complex ndarray + The truncated or zero-padded input, transformed along the axis + indicated by `axis`, or the last one if `axis` is not specified. + + Raises + ------ + IndexError + If `axes` is larger than the last axis of `a`. + + See Also + -------- + numpy.fft : An introduction, with definitions and general explanations. + fft : The one-dimensional (forward) FFT, of which `ifft` is the inverse + ifft2 : The two-dimensional inverse FFT. + ifftn : The n-dimensional inverse FFT. + + Notes + ----- + If the input parameter `n` is larger than the size of the input, the input + is padded by appending zeros at the end. Even though this is the common + approach, it might lead to surprising results. If a different padding is + desired, it must be performed before calling `ifft`. + + Examples + -------- + >>> np.fft.ifft([0, 4, 0, 0]) + array([ 1.+0.j, 0.+1.j, -1.+0.j, 0.-1.j]) # may vary + + Create and plot a band-limited signal with random phases: + + >>> import matplotlib.pyplot as plt + >>> t = np.arange(400) + >>> n = np.zeros((400,), dtype=complex) + >>> n[40:60] = np.exp(1j*np.random.uniform(0, 2*np.pi, (20,))) + >>> s = np.fft.ifft(n) + >>> plt.plot(t, s.real, 'b-', t, s.imag, 'r--') + [, ] + >>> plt.legend(('real', 'imaginary')) + + >>> plt.show() + + """ + a = asarray(a) + if n is None: + n = a.shape[axis] + inv_norm = _get_backward_norm(n, norm) + output = _raw_fft(a, n, axis, False, False, inv_norm) + return output + + +@array_function_dispatch(_fft_dispatcher) +def rfft(a, n=None, axis=-1, norm=None): + """ + Compute the one-dimensional discrete Fourier Transform for real input. + + This function computes the one-dimensional *n*-point discrete Fourier + Transform (DFT) of a real-valued array by means of an efficient algorithm + called the Fast Fourier Transform (FFT). + + Parameters + ---------- + a : array_like + Input array + n : int, optional + Number of points along transformation axis in the input to use. + If `n` is smaller than the length of the input, the input is cropped. + If it is larger, the input is padded with zeros. If `n` is not given, + the length of the input along the axis specified by `axis` is used. + axis : int, optional + Axis over which to compute the FFT. If not given, the last axis is + used. + norm : {"backward", "ortho", "forward"}, optional + .. versionadded:: 1.10.0 + + Normalization mode (see `numpy.fft`). Default is "backward". + Indicates which direction of the forward/backward pair of transforms + is scaled and with what normalization factor. + + .. versionadded:: 1.20.0 + + The "backward", "forward" values were added. + + Returns + ------- + out : complex ndarray + The truncated or zero-padded input, transformed along the axis + indicated by `axis`, or the last one if `axis` is not specified. + If `n` is even, the length of the transformed axis is ``(n/2)+1``. + If `n` is odd, the length is ``(n+1)/2``. + + Raises + ------ + IndexError + If `axis` is larger than the last axis of `a`. + + See Also + -------- + numpy.fft : For definition of the DFT and conventions used. + irfft : The inverse of `rfft`. + fft : The one-dimensional FFT of general (complex) input. + fftn : The *n*-dimensional FFT. + rfftn : The *n*-dimensional FFT of real input. + + Notes + ----- + When the DFT is computed for purely real input, the output is + Hermitian-symmetric, i.e. the negative frequency terms are just the complex + conjugates of the corresponding positive-frequency terms, and the + negative-frequency terms are therefore redundant. This function does not + compute the negative frequency terms, and the length of the transformed + axis of the output is therefore ``n//2 + 1``. + + When ``A = rfft(a)`` and fs is the sampling frequency, ``A[0]`` contains + the zero-frequency term 0*fs, which is real due to Hermitian symmetry. + + If `n` is even, ``A[-1]`` contains the term representing both positive + and negative Nyquist frequency (+fs/2 and -fs/2), and must also be purely + real. If `n` is odd, there is no term at fs/2; ``A[-1]`` contains + the largest positive frequency (fs/2*(n-1)/n), and is complex in the + general case. + + If the input `a` contains an imaginary part, it is silently discarded. + + Examples + -------- + >>> np.fft.fft([0, 1, 0, 0]) + array([ 1.+0.j, 0.-1.j, -1.+0.j, 0.+1.j]) # may vary + >>> np.fft.rfft([0, 1, 0, 0]) + array([ 1.+0.j, 0.-1.j, -1.+0.j]) # may vary + + Notice how the final element of the `fft` output is the complex conjugate + of the second element, for real input. For `rfft`, this symmetry is + exploited to compute only the non-negative frequency terms. + + """ + a = asarray(a) + if n is None: + n = a.shape[axis] + inv_norm = _get_forward_norm(n, norm) + output = _raw_fft(a, n, axis, True, True, inv_norm) + return output + + +@array_function_dispatch(_fft_dispatcher) +def irfft(a, n=None, axis=-1, norm=None): + """ + Computes the inverse of `rfft`. + + This function computes the inverse of the one-dimensional *n*-point + discrete Fourier Transform of real input computed by `rfft`. + In other words, ``irfft(rfft(a), len(a)) == a`` to within numerical + accuracy. (See Notes below for why ``len(a)`` is necessary here.) + + The input is expected to be in the form returned by `rfft`, i.e. the + real zero-frequency term followed by the complex positive frequency terms + in order of increasing frequency. Since the discrete Fourier Transform of + real input is Hermitian-symmetric, the negative frequency terms are taken + to be the complex conjugates of the corresponding positive frequency terms. + + Parameters + ---------- + a : array_like + The input array. + n : int, optional + Length of the transformed axis of the output. + For `n` output points, ``n//2+1`` input points are necessary. If the + input is longer than this, it is cropped. If it is shorter than this, + it is padded with zeros. If `n` is not given, it is taken to be + ``2*(m-1)`` where ``m`` is the length of the input along the axis + specified by `axis`. + axis : int, optional + Axis over which to compute the inverse FFT. If not given, the last + axis is used. + norm : {"backward", "ortho", "forward"}, optional + .. versionadded:: 1.10.0 + + Normalization mode (see `numpy.fft`). Default is "backward". + Indicates which direction of the forward/backward pair of transforms + is scaled and with what normalization factor. + + .. versionadded:: 1.20.0 + + The "backward", "forward" values were added. + + Returns + ------- + out : ndarray + The truncated or zero-padded input, transformed along the axis + indicated by `axis`, or the last one if `axis` is not specified. + The length of the transformed axis is `n`, or, if `n` is not given, + ``2*(m-1)`` where ``m`` is the length of the transformed axis of the + input. To get an odd number of output points, `n` must be specified. + + Raises + ------ + IndexError + If `axis` is larger than the last axis of `a`. + + See Also + -------- + numpy.fft : For definition of the DFT and conventions used. + rfft : The one-dimensional FFT of real input, of which `irfft` is inverse. + fft : The one-dimensional FFT. + irfft2 : The inverse of the two-dimensional FFT of real input. + irfftn : The inverse of the *n*-dimensional FFT of real input. + + Notes + ----- + Returns the real valued `n`-point inverse discrete Fourier transform + of `a`, where `a` contains the non-negative frequency terms of a + Hermitian-symmetric sequence. `n` is the length of the result, not the + input. + + If you specify an `n` such that `a` must be zero-padded or truncated, the + extra/removed values will be added/removed at high frequencies. One can + thus resample a series to `m` points via Fourier interpolation by: + ``a_resamp = irfft(rfft(a), m)``. + + The correct interpretation of the hermitian input depends on the length of + the original data, as given by `n`. This is because each input shape could + correspond to either an odd or even length signal. By default, `irfft` + assumes an even output length which puts the last entry at the Nyquist + frequency; aliasing with its symmetric counterpart. By Hermitian symmetry, + the value is thus treated as purely real. To avoid losing information, the + correct length of the real input **must** be given. + + Examples + -------- + >>> np.fft.ifft([1, -1j, -1, 1j]) + array([0.+0.j, 1.+0.j, 0.+0.j, 0.+0.j]) # may vary + >>> np.fft.irfft([1, -1j, -1]) + array([0., 1., 0., 0.]) + + Notice how the last term in the input to the ordinary `ifft` is the + complex conjugate of the second term, and the output has zero imaginary + part everywhere. When calling `irfft`, the negative frequencies are not + specified, and the output array is purely real. + + """ + a = asarray(a) + if n is None: + n = (a.shape[axis] - 1) * 2 + inv_norm = _get_backward_norm(n, norm) + output = _raw_fft(a, n, axis, True, False, inv_norm) + return output + + +@array_function_dispatch(_fft_dispatcher) +def hfft(a, n=None, axis=-1, norm=None): + """ + Compute the FFT of a signal that has Hermitian symmetry, i.e., a real + spectrum. + + Parameters + ---------- + a : array_like + The input array. + n : int, optional + Length of the transformed axis of the output. For `n` output + points, ``n//2 + 1`` input points are necessary. If the input is + longer than this, it is cropped. If it is shorter than this, it is + padded with zeros. If `n` is not given, it is taken to be ``2*(m-1)`` + where ``m`` is the length of the input along the axis specified by + `axis`. + axis : int, optional + Axis over which to compute the FFT. If not given, the last + axis is used. + norm : {"backward", "ortho", "forward"}, optional + .. versionadded:: 1.10.0 + + Normalization mode (see `numpy.fft`). Default is "backward". + Indicates which direction of the forward/backward pair of transforms + is scaled and with what normalization factor. + + .. versionadded:: 1.20.0 + + The "backward", "forward" values were added. + + Returns + ------- + out : ndarray + The truncated or zero-padded input, transformed along the axis + indicated by `axis`, or the last one if `axis` is not specified. + The length of the transformed axis is `n`, or, if `n` is not given, + ``2*m - 2`` where ``m`` is the length of the transformed axis of + the input. To get an odd number of output points, `n` must be + specified, for instance as ``2*m - 1`` in the typical case, + + Raises + ------ + IndexError + If `axis` is larger than the last axis of `a`. + + See also + -------- + rfft : Compute the one-dimensional FFT for real input. + ihfft : The inverse of `hfft`. + + Notes + ----- + `hfft`/`ihfft` are a pair analogous to `rfft`/`irfft`, but for the + opposite case: here the signal has Hermitian symmetry in the time + domain and is real in the frequency domain. So here it's `hfft` for + which you must supply the length of the result if it is to be odd. + + * even: ``ihfft(hfft(a, 2*len(a) - 2)) == a``, within roundoff error, + * odd: ``ihfft(hfft(a, 2*len(a) - 1)) == a``, within roundoff error. + + The correct interpretation of the hermitian input depends on the length of + the original data, as given by `n`. This is because each input shape could + correspond to either an odd or even length signal. By default, `hfft` + assumes an even output length which puts the last entry at the Nyquist + frequency; aliasing with its symmetric counterpart. By Hermitian symmetry, + the value is thus treated as purely real. To avoid losing information, the + shape of the full signal **must** be given. + + Examples + -------- + >>> signal = np.array([1, 2, 3, 4, 3, 2]) + >>> np.fft.fft(signal) + array([15.+0.j, -4.+0.j, 0.+0.j, -1.-0.j, 0.+0.j, -4.+0.j]) # may vary + >>> np.fft.hfft(signal[:4]) # Input first half of signal + array([15., -4., 0., -1., 0., -4.]) + >>> np.fft.hfft(signal, 6) # Input entire signal and truncate + array([15., -4., 0., -1., 0., -4.]) + + + >>> signal = np.array([[1, 1.j], [-1.j, 2]]) + >>> np.conj(signal.T) - signal # check Hermitian symmetry + array([[ 0.-0.j, -0.+0.j], # may vary + [ 0.+0.j, 0.-0.j]]) + >>> freq_spectrum = np.fft.hfft(signal) + >>> freq_spectrum + array([[ 1., 1.], + [ 2., -2.]]) + + """ + a = asarray(a) + if n is None: + n = (a.shape[axis] - 1) * 2 + new_norm = _swap_direction(norm) + output = irfft(conjugate(a), n, axis, norm=new_norm) + return output + + +@array_function_dispatch(_fft_dispatcher) +def ihfft(a, n=None, axis=-1, norm=None): + """ + Compute the inverse FFT of a signal that has Hermitian symmetry. + + Parameters + ---------- + a : array_like + Input array. + n : int, optional + Length of the inverse FFT, the number of points along + transformation axis in the input to use. If `n` is smaller than + the length of the input, the input is cropped. If it is larger, + the input is padded with zeros. If `n` is not given, the length of + the input along the axis specified by `axis` is used. + axis : int, optional + Axis over which to compute the inverse FFT. If not given, the last + axis is used. + norm : {"backward", "ortho", "forward"}, optional + .. versionadded:: 1.10.0 + + Normalization mode (see `numpy.fft`). Default is "backward". + Indicates which direction of the forward/backward pair of transforms + is scaled and with what normalization factor. + + .. versionadded:: 1.20.0 + + The "backward", "forward" values were added. + + Returns + ------- + out : complex ndarray + The truncated or zero-padded input, transformed along the axis + indicated by `axis`, or the last one if `axis` is not specified. + The length of the transformed axis is ``n//2 + 1``. + + See also + -------- + hfft, irfft + + Notes + ----- + `hfft`/`ihfft` are a pair analogous to `rfft`/`irfft`, but for the + opposite case: here the signal has Hermitian symmetry in the time + domain and is real in the frequency domain. So here it's `hfft` for + which you must supply the length of the result if it is to be odd: + + * even: ``ihfft(hfft(a, 2*len(a) - 2)) == a``, within roundoff error, + * odd: ``ihfft(hfft(a, 2*len(a) - 1)) == a``, within roundoff error. + + Examples + -------- + >>> spectrum = np.array([ 15, -4, 0, -1, 0, -4]) + >>> np.fft.ifft(spectrum) + array([1.+0.j, 2.+0.j, 3.+0.j, 4.+0.j, 3.+0.j, 2.+0.j]) # may vary + >>> np.fft.ihfft(spectrum) + array([ 1.-0.j, 2.-0.j, 3.-0.j, 4.-0.j]) # may vary + + """ + a = asarray(a) + if n is None: + n = a.shape[axis] + new_norm = _swap_direction(norm) + output = conjugate(rfft(a, n, axis, norm=new_norm)) + return output + + +def _cook_nd_args(a, s=None, axes=None, invreal=0): + if s is None: + shapeless = 1 + if axes is None: + s = list(a.shape) + else: + s = take(a.shape, axes) + else: + shapeless = 0 + s = list(s) + if axes is None: + axes = list(range(-len(s), 0)) + if len(s) != len(axes): + raise ValueError("Shape and axes have different lengths.") + if invreal and shapeless: + s[-1] = (a.shape[axes[-1]] - 1) * 2 + return s, axes + + +def _raw_fftnd(a, s=None, axes=None, function=fft, norm=None): + a = asarray(a) + s, axes = _cook_nd_args(a, s, axes) + itl = list(range(len(axes))) + itl.reverse() + for ii in itl: + a = function(a, n=s[ii], axis=axes[ii], norm=norm) + return a + + +def _fftn_dispatcher(a, s=None, axes=None, norm=None): + return (a,) + + +@array_function_dispatch(_fftn_dispatcher) +def fftn(a, s=None, axes=None, norm=None): + """ + Compute the N-dimensional discrete Fourier Transform. + + This function computes the *N*-dimensional discrete Fourier Transform over + any number of axes in an *M*-dimensional array by means of the Fast Fourier + Transform (FFT). + + Parameters + ---------- + a : array_like + Input array, can be complex. + s : sequence of ints, optional + Shape (length of each transformed axis) of the output + (``s[0]`` refers to axis 0, ``s[1]`` to axis 1, etc.). + This corresponds to ``n`` for ``fft(x, n)``. + Along any axis, if the given shape is smaller than that of the input, + the input is cropped. If it is larger, the input is padded with zeros. + if `s` is not given, the shape of the input along the axes specified + by `axes` is used. + axes : sequence of ints, optional + Axes over which to compute the FFT. If not given, the last ``len(s)`` + axes are used, or all axes if `s` is also not specified. + Repeated indices in `axes` means that the transform over that axis is + performed multiple times. + norm : {"backward", "ortho", "forward"}, optional + .. versionadded:: 1.10.0 + + Normalization mode (see `numpy.fft`). Default is "backward". + Indicates which direction of the forward/backward pair of transforms + is scaled and with what normalization factor. + + .. versionadded:: 1.20.0 + + The "backward", "forward" values were added. + + Returns + ------- + out : complex ndarray + The truncated or zero-padded input, transformed along the axes + indicated by `axes`, or by a combination of `s` and `a`, + as explained in the parameters section above. + + Raises + ------ + ValueError + If `s` and `axes` have different length. + IndexError + If an element of `axes` is larger than than the number of axes of `a`. + + See Also + -------- + numpy.fft : Overall view of discrete Fourier transforms, with definitions + and conventions used. + ifftn : The inverse of `fftn`, the inverse *n*-dimensional FFT. + fft : The one-dimensional FFT, with definitions and conventions used. + rfftn : The *n*-dimensional FFT of real input. + fft2 : The two-dimensional FFT. + fftshift : Shifts zero-frequency terms to centre of array + + Notes + ----- + The output, analogously to `fft`, contains the term for zero frequency in + the low-order corner of all axes, the positive frequency terms in the + first half of all axes, the term for the Nyquist frequency in the middle + of all axes and the negative frequency terms in the second half of all + axes, in order of decreasingly negative frequency. + + See `numpy.fft` for details, definitions and conventions used. + + Examples + -------- + >>> a = np.mgrid[:3, :3, :3][0] + >>> np.fft.fftn(a, axes=(1, 2)) + array([[[ 0.+0.j, 0.+0.j, 0.+0.j], # may vary + [ 0.+0.j, 0.+0.j, 0.+0.j], + [ 0.+0.j, 0.+0.j, 0.+0.j]], + [[ 9.+0.j, 0.+0.j, 0.+0.j], + [ 0.+0.j, 0.+0.j, 0.+0.j], + [ 0.+0.j, 0.+0.j, 0.+0.j]], + [[18.+0.j, 0.+0.j, 0.+0.j], + [ 0.+0.j, 0.+0.j, 0.+0.j], + [ 0.+0.j, 0.+0.j, 0.+0.j]]]) + >>> np.fft.fftn(a, (2, 2), axes=(0, 1)) + array([[[ 2.+0.j, 2.+0.j, 2.+0.j], # may vary + [ 0.+0.j, 0.+0.j, 0.+0.j]], + [[-2.+0.j, -2.+0.j, -2.+0.j], + [ 0.+0.j, 0.+0.j, 0.+0.j]]]) + + >>> import matplotlib.pyplot as plt + >>> [X, Y] = np.meshgrid(2 * np.pi * np.arange(200) / 12, + ... 2 * np.pi * np.arange(200) / 34) + >>> S = np.sin(X) + np.cos(Y) + np.random.uniform(0, 1, X.shape) + >>> FS = np.fft.fftn(S) + >>> plt.imshow(np.log(np.abs(np.fft.fftshift(FS))**2)) + + >>> plt.show() + + """ + return _raw_fftnd(a, s, axes, fft, norm) + + +@array_function_dispatch(_fftn_dispatcher) +def ifftn(a, s=None, axes=None, norm=None): + """ + Compute the N-dimensional inverse discrete Fourier Transform. + + This function computes the inverse of the N-dimensional discrete + Fourier Transform over any number of axes in an M-dimensional array by + means of the Fast Fourier Transform (FFT). In other words, + ``ifftn(fftn(a)) == a`` to within numerical accuracy. + For a description of the definitions and conventions used, see `numpy.fft`. + + The input, analogously to `ifft`, should be ordered in the same way as is + returned by `fftn`, i.e. it should have the term for zero frequency + in all axes in the low-order corner, the positive frequency terms in the + first half of all axes, the term for the Nyquist frequency in the middle + of all axes and the negative frequency terms in the second half of all + axes, in order of decreasingly negative frequency. + + Parameters + ---------- + a : array_like + Input array, can be complex. + s : sequence of ints, optional + Shape (length of each transformed axis) of the output + (``s[0]`` refers to axis 0, ``s[1]`` to axis 1, etc.). + This corresponds to ``n`` for ``ifft(x, n)``. + Along any axis, if the given shape is smaller than that of the input, + the input is cropped. If it is larger, the input is padded with zeros. + if `s` is not given, the shape of the input along the axes specified + by `axes` is used. See notes for issue on `ifft` zero padding. + axes : sequence of ints, optional + Axes over which to compute the IFFT. If not given, the last ``len(s)`` + axes are used, or all axes if `s` is also not specified. + Repeated indices in `axes` means that the inverse transform over that + axis is performed multiple times. + norm : {"backward", "ortho", "forward"}, optional + .. versionadded:: 1.10.0 + + Normalization mode (see `numpy.fft`). Default is "backward". + Indicates which direction of the forward/backward pair of transforms + is scaled and with what normalization factor. + + .. versionadded:: 1.20.0 + + The "backward", "forward" values were added. + + Returns + ------- + out : complex ndarray + The truncated or zero-padded input, transformed along the axes + indicated by `axes`, or by a combination of `s` or `a`, + as explained in the parameters section above. + + Raises + ------ + ValueError + If `s` and `axes` have different length. + IndexError + If an element of `axes` is larger than than the number of axes of `a`. + + See Also + -------- + numpy.fft : Overall view of discrete Fourier transforms, with definitions + and conventions used. + fftn : The forward *n*-dimensional FFT, of which `ifftn` is the inverse. + ifft : The one-dimensional inverse FFT. + ifft2 : The two-dimensional inverse FFT. + ifftshift : Undoes `fftshift`, shifts zero-frequency terms to beginning + of array. + + Notes + ----- + See `numpy.fft` for definitions and conventions used. + + Zero-padding, analogously with `ifft`, is performed by appending zeros to + the input along the specified dimension. Although this is the common + approach, it might lead to surprising results. If another form of zero + padding is desired, it must be performed before `ifftn` is called. + + Examples + -------- + >>> a = np.eye(4) + >>> np.fft.ifftn(np.fft.fftn(a, axes=(0,)), axes=(1,)) + array([[1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j], # may vary + [0.+0.j, 1.+0.j, 0.+0.j, 0.+0.j], + [0.+0.j, 0.+0.j, 1.+0.j, 0.+0.j], + [0.+0.j, 0.+0.j, 0.+0.j, 1.+0.j]]) + + + Create and plot an image with band-limited frequency content: + + >>> import matplotlib.pyplot as plt + >>> n = np.zeros((200,200), dtype=complex) + >>> n[60:80, 20:40] = np.exp(1j*np.random.uniform(0, 2*np.pi, (20, 20))) + >>> im = np.fft.ifftn(n).real + >>> plt.imshow(im) + + >>> plt.show() + + """ + return _raw_fftnd(a, s, axes, ifft, norm) + + +@array_function_dispatch(_fftn_dispatcher) +def fft2(a, s=None, axes=(-2, -1), norm=None): + """ + Compute the 2-dimensional discrete Fourier Transform. + + This function computes the *n*-dimensional discrete Fourier Transform + over any axes in an *M*-dimensional array by means of the + Fast Fourier Transform (FFT). By default, the transform is computed over + the last two axes of the input array, i.e., a 2-dimensional FFT. + + Parameters + ---------- + a : array_like + Input array, can be complex + s : sequence of ints, optional + Shape (length of each transformed axis) of the output + (``s[0]`` refers to axis 0, ``s[1]`` to axis 1, etc.). + This corresponds to ``n`` for ``fft(x, n)``. + Along each axis, if the given shape is smaller than that of the input, + the input is cropped. If it is larger, the input is padded with zeros. + if `s` is not given, the shape of the input along the axes specified + by `axes` is used. + axes : sequence of ints, optional + Axes over which to compute the FFT. If not given, the last two + axes are used. A repeated index in `axes` means the transform over + that axis is performed multiple times. A one-element sequence means + that a one-dimensional FFT is performed. + norm : {"backward", "ortho", "forward"}, optional + .. versionadded:: 1.10.0 + + Normalization mode (see `numpy.fft`). Default is "backward". + Indicates which direction of the forward/backward pair of transforms + is scaled and with what normalization factor. + + .. versionadded:: 1.20.0 + + The "backward", "forward" values were added. + + Returns + ------- + out : complex ndarray + The truncated or zero-padded input, transformed along the axes + indicated by `axes`, or the last two axes if `axes` is not given. + + Raises + ------ + ValueError + If `s` and `axes` have different length, or `axes` not given and + ``len(s) != 2``. + IndexError + If an element of `axes` is larger than than the number of axes of `a`. + + See Also + -------- + numpy.fft : Overall view of discrete Fourier transforms, with definitions + and conventions used. + ifft2 : The inverse two-dimensional FFT. + fft : The one-dimensional FFT. + fftn : The *n*-dimensional FFT. + fftshift : Shifts zero-frequency terms to the center of the array. + For two-dimensional input, swaps first and third quadrants, and second + and fourth quadrants. + + Notes + ----- + `fft2` is just `fftn` with a different default for `axes`. + + The output, analogously to `fft`, contains the term for zero frequency in + the low-order corner of the transformed axes, the positive frequency terms + in the first half of these axes, the term for the Nyquist frequency in the + middle of the axes and the negative frequency terms in the second half of + the axes, in order of decreasingly negative frequency. + + See `fftn` for details and a plotting example, and `numpy.fft` for + definitions and conventions used. + + + Examples + -------- + >>> a = np.mgrid[:5, :5][0] + >>> np.fft.fft2(a) + array([[ 50. +0.j , 0. +0.j , 0. +0.j , # may vary + 0. +0.j , 0. +0.j ], + [-12.5+17.20477401j, 0. +0.j , 0. +0.j , + 0. +0.j , 0. +0.j ], + [-12.5 +4.0614962j , 0. +0.j , 0. +0.j , + 0. +0.j , 0. +0.j ], + [-12.5 -4.0614962j , 0. +0.j , 0. +0.j , + 0. +0.j , 0. +0.j ], + [-12.5-17.20477401j, 0. +0.j , 0. +0.j , + 0. +0.j , 0. +0.j ]]) + + """ + return _raw_fftnd(a, s, axes, fft, norm) + + +@array_function_dispatch(_fftn_dispatcher) +def ifft2(a, s=None, axes=(-2, -1), norm=None): + """ + Compute the 2-dimensional inverse discrete Fourier Transform. + + This function computes the inverse of the 2-dimensional discrete Fourier + Transform over any number of axes in an M-dimensional array by means of + the Fast Fourier Transform (FFT). In other words, ``ifft2(fft2(a)) == a`` + to within numerical accuracy. By default, the inverse transform is + computed over the last two axes of the input array. + + The input, analogously to `ifft`, should be ordered in the same way as is + returned by `fft2`, i.e. it should have the term for zero frequency + in the low-order corner of the two axes, the positive frequency terms in + the first half of these axes, the term for the Nyquist frequency in the + middle of the axes and the negative frequency terms in the second half of + both axes, in order of decreasingly negative frequency. + + Parameters + ---------- + a : array_like + Input array, can be complex. + s : sequence of ints, optional + Shape (length of each axis) of the output (``s[0]`` refers to axis 0, + ``s[1]`` to axis 1, etc.). This corresponds to `n` for ``ifft(x, n)``. + Along each axis, if the given shape is smaller than that of the input, + the input is cropped. If it is larger, the input is padded with zeros. + if `s` is not given, the shape of the input along the axes specified + by `axes` is used. See notes for issue on `ifft` zero padding. + axes : sequence of ints, optional + Axes over which to compute the FFT. If not given, the last two + axes are used. A repeated index in `axes` means the transform over + that axis is performed multiple times. A one-element sequence means + that a one-dimensional FFT is performed. + norm : {"backward", "ortho", "forward"}, optional + .. versionadded:: 1.10.0 + + Normalization mode (see `numpy.fft`). Default is "backward". + Indicates which direction of the forward/backward pair of transforms + is scaled and with what normalization factor. + + .. versionadded:: 1.20.0 + + The "backward", "forward" values were added. + + Returns + ------- + out : complex ndarray + The truncated or zero-padded input, transformed along the axes + indicated by `axes`, or the last two axes if `axes` is not given. + + Raises + ------ + ValueError + If `s` and `axes` have different length, or `axes` not given and + ``len(s) != 2``. + IndexError + If an element of `axes` is larger than than the number of axes of `a`. + + See Also + -------- + numpy.fft : Overall view of discrete Fourier transforms, with definitions + and conventions used. + fft2 : The forward 2-dimensional FFT, of which `ifft2` is the inverse. + ifftn : The inverse of the *n*-dimensional FFT. + fft : The one-dimensional FFT. + ifft : The one-dimensional inverse FFT. + + Notes + ----- + `ifft2` is just `ifftn` with a different default for `axes`. + + See `ifftn` for details and a plotting example, and `numpy.fft` for + definition and conventions used. + + Zero-padding, analogously with `ifft`, is performed by appending zeros to + the input along the specified dimension. Although this is the common + approach, it might lead to surprising results. If another form of zero + padding is desired, it must be performed before `ifft2` is called. + + Examples + -------- + >>> a = 4 * np.eye(4) + >>> np.fft.ifft2(a) + array([[1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j], # may vary + [0.+0.j, 0.+0.j, 0.+0.j, 1.+0.j], + [0.+0.j, 0.+0.j, 1.+0.j, 0.+0.j], + [0.+0.j, 1.+0.j, 0.+0.j, 0.+0.j]]) + + """ + return _raw_fftnd(a, s, axes, ifft, norm) + + +@array_function_dispatch(_fftn_dispatcher) +def rfftn(a, s=None, axes=None, norm=None): + """ + Compute the N-dimensional discrete Fourier Transform for real input. + + This function computes the N-dimensional discrete Fourier Transform over + any number of axes in an M-dimensional real array by means of the Fast + Fourier Transform (FFT). By default, all axes are transformed, with the + real transform performed over the last axis, while the remaining + transforms are complex. + + Parameters + ---------- + a : array_like + Input array, taken to be real. + s : sequence of ints, optional + Shape (length along each transformed axis) to use from the input. + (``s[0]`` refers to axis 0, ``s[1]`` to axis 1, etc.). + The final element of `s` corresponds to `n` for ``rfft(x, n)``, while + for the remaining axes, it corresponds to `n` for ``fft(x, n)``. + Along any axis, if the given shape is smaller than that of the input, + the input is cropped. If it is larger, the input is padded with zeros. + if `s` is not given, the shape of the input along the axes specified + by `axes` is used. + axes : sequence of ints, optional + Axes over which to compute the FFT. If not given, the last ``len(s)`` + axes are used, or all axes if `s` is also not specified. + norm : {"backward", "ortho", "forward"}, optional + .. versionadded:: 1.10.0 + + Normalization mode (see `numpy.fft`). Default is "backward". + Indicates which direction of the forward/backward pair of transforms + is scaled and with what normalization factor. + + .. versionadded:: 1.20.0 + + The "backward", "forward" values were added. + + Returns + ------- + out : complex ndarray + The truncated or zero-padded input, transformed along the axes + indicated by `axes`, or by a combination of `s` and `a`, + as explained in the parameters section above. + The length of the last axis transformed will be ``s[-1]//2+1``, + while the remaining transformed axes will have lengths according to + `s`, or unchanged from the input. + + Raises + ------ + ValueError + If `s` and `axes` have different length. + IndexError + If an element of `axes` is larger than than the number of axes of `a`. + + See Also + -------- + irfftn : The inverse of `rfftn`, i.e. the inverse of the n-dimensional FFT + of real input. + fft : The one-dimensional FFT, with definitions and conventions used. + rfft : The one-dimensional FFT of real input. + fftn : The n-dimensional FFT. + rfft2 : The two-dimensional FFT of real input. + + Notes + ----- + The transform for real input is performed over the last transformation + axis, as by `rfft`, then the transform over the remaining axes is + performed as by `fftn`. The order of the output is as for `rfft` for the + final transformation axis, and as for `fftn` for the remaining + transformation axes. + + See `fft` for details, definitions and conventions used. + + Examples + -------- + >>> a = np.ones((2, 2, 2)) + >>> np.fft.rfftn(a) + array([[[8.+0.j, 0.+0.j], # may vary + [0.+0.j, 0.+0.j]], + [[0.+0.j, 0.+0.j], + [0.+0.j, 0.+0.j]]]) + + >>> np.fft.rfftn(a, axes=(2, 0)) + array([[[4.+0.j, 0.+0.j], # may vary + [4.+0.j, 0.+0.j]], + [[0.+0.j, 0.+0.j], + [0.+0.j, 0.+0.j]]]) + + """ + a = asarray(a) + s, axes = _cook_nd_args(a, s, axes) + a = rfft(a, s[-1], axes[-1], norm) + for ii in range(len(axes)-1): + a = fft(a, s[ii], axes[ii], norm) + return a + + +@array_function_dispatch(_fftn_dispatcher) +def rfft2(a, s=None, axes=(-2, -1), norm=None): + """ + Compute the 2-dimensional FFT of a real array. + + Parameters + ---------- + a : array + Input array, taken to be real. + s : sequence of ints, optional + Shape of the FFT. + axes : sequence of ints, optional + Axes over which to compute the FFT. + norm : {"backward", "ortho", "forward"}, optional + .. versionadded:: 1.10.0 + + Normalization mode (see `numpy.fft`). Default is "backward". + Indicates which direction of the forward/backward pair of transforms + is scaled and with what normalization factor. + + .. versionadded:: 1.20.0 + + The "backward", "forward" values were added. + + Returns + ------- + out : ndarray + The result of the real 2-D FFT. + + See Also + -------- + rfftn : Compute the N-dimensional discrete Fourier Transform for real + input. + + Notes + ----- + This is really just `rfftn` with different default behavior. + For more details see `rfftn`. + + """ + return rfftn(a, s, axes, norm) + + +@array_function_dispatch(_fftn_dispatcher) +def irfftn(a, s=None, axes=None, norm=None): + """ + Computes the inverse of `rfftn`. + + This function computes the inverse of the N-dimensional discrete + Fourier Transform for real input over any number of axes in an + M-dimensional array by means of the Fast Fourier Transform (FFT). In + other words, ``irfftn(rfftn(a), a.shape) == a`` to within numerical + accuracy. (The ``a.shape`` is necessary like ``len(a)`` is for `irfft`, + and for the same reason.) + + The input should be ordered in the same way as is returned by `rfftn`, + i.e. as for `irfft` for the final transformation axis, and as for `ifftn` + along all the other axes. + + Parameters + ---------- + a : array_like + Input array. + s : sequence of ints, optional + Shape (length of each transformed axis) of the output + (``s[0]`` refers to axis 0, ``s[1]`` to axis 1, etc.). `s` is also the + number of input points used along this axis, except for the last axis, + where ``s[-1]//2+1`` points of the input are used. + Along any axis, if the shape indicated by `s` is smaller than that of + the input, the input is cropped. If it is larger, the input is padded + with zeros. If `s` is not given, the shape of the input along the axes + specified by axes is used. Except for the last axis which is taken to + be ``2*(m-1)`` where ``m`` is the length of the input along that axis. + axes : sequence of ints, optional + Axes over which to compute the inverse FFT. If not given, the last + `len(s)` axes are used, or all axes if `s` is also not specified. + Repeated indices in `axes` means that the inverse transform over that + axis is performed multiple times. + norm : {"backward", "ortho", "forward"}, optional + .. versionadded:: 1.10.0 + + Normalization mode (see `numpy.fft`). Default is "backward". + Indicates which direction of the forward/backward pair of transforms + is scaled and with what normalization factor. + + .. versionadded:: 1.20.0 + + The "backward", "forward" values were added. + + Returns + ------- + out : ndarray + The truncated or zero-padded input, transformed along the axes + indicated by `axes`, or by a combination of `s` or `a`, + as explained in the parameters section above. + The length of each transformed axis is as given by the corresponding + element of `s`, or the length of the input in every axis except for the + last one if `s` is not given. In the final transformed axis the length + of the output when `s` is not given is ``2*(m-1)`` where ``m`` is the + length of the final transformed axis of the input. To get an odd + number of output points in the final axis, `s` must be specified. + + Raises + ------ + ValueError + If `s` and `axes` have different length. + IndexError + If an element of `axes` is larger than than the number of axes of `a`. + + See Also + -------- + rfftn : The forward n-dimensional FFT of real input, + of which `ifftn` is the inverse. + fft : The one-dimensional FFT, with definitions and conventions used. + irfft : The inverse of the one-dimensional FFT of real input. + irfft2 : The inverse of the two-dimensional FFT of real input. + + Notes + ----- + See `fft` for definitions and conventions used. + + See `rfft` for definitions and conventions used for real input. + + The correct interpretation of the hermitian input depends on the shape of + the original data, as given by `s`. This is because each input shape could + correspond to either an odd or even length signal. By default, `irfftn` + assumes an even output length which puts the last entry at the Nyquist + frequency; aliasing with its symmetric counterpart. When performing the + final complex to real transform, the last value is thus treated as purely + real. To avoid losing information, the correct shape of the real input + **must** be given. + + Examples + -------- + >>> a = np.zeros((3, 2, 2)) + >>> a[0, 0, 0] = 3 * 2 * 2 + >>> np.fft.irfftn(a) + array([[[1., 1.], + [1., 1.]], + [[1., 1.], + [1., 1.]], + [[1., 1.], + [1., 1.]]]) + + """ + a = asarray(a) + s, axes = _cook_nd_args(a, s, axes, invreal=1) + for ii in range(len(axes)-1): + a = ifft(a, s[ii], axes[ii], norm) + a = irfft(a, s[-1], axes[-1], norm) + return a + + +@array_function_dispatch(_fftn_dispatcher) +def irfft2(a, s=None, axes=(-2, -1), norm=None): + """ + Computes the inverse of `rfft2`. + + Parameters + ---------- + a : array_like + The input array + s : sequence of ints, optional + Shape of the real output to the inverse FFT. + axes : sequence of ints, optional + The axes over which to compute the inverse fft. + Default is the last two axes. + norm : {"backward", "ortho", "forward"}, optional + .. versionadded:: 1.10.0 + + Normalization mode (see `numpy.fft`). Default is "backward". + Indicates which direction of the forward/backward pair of transforms + is scaled and with what normalization factor. + + .. versionadded:: 1.20.0 + + The "backward", "forward" values were added. + + Returns + ------- + out : ndarray + The result of the inverse real 2-D FFT. + + See Also + -------- + rfft2 : The forward two-dimensional FFT of real input, + of which `irfft2` is the inverse. + rfft : The one-dimensional FFT for real input. + irfft : The inverse of the one-dimensional FFT of real input. + irfftn : Compute the inverse of the N-dimensional FFT of real input. + + Notes + ----- + This is really `irfftn` with different defaults. + For more details see `irfftn`. + + """ + return irfftn(a, s, axes, norm) diff --git a/venv/Lib/site-packages/numpy/fft/helper.py b/venv/Lib/site-packages/numpy/fft/helper.py new file mode 100644 index 0000000..927ee1a --- /dev/null +++ b/venv/Lib/site-packages/numpy/fft/helper.py @@ -0,0 +1,221 @@ +""" +Discrete Fourier Transforms - helper.py + +""" +from numpy.core import integer, empty, arange, asarray, roll +from numpy.core.overrides import array_function_dispatch, set_module + +# Created by Pearu Peterson, September 2002 + +__all__ = ['fftshift', 'ifftshift', 'fftfreq', 'rfftfreq'] + +integer_types = (int, integer) + + +def _fftshift_dispatcher(x, axes=None): + return (x,) + + +@array_function_dispatch(_fftshift_dispatcher, module='numpy.fft') +def fftshift(x, axes=None): + """ + Shift the zero-frequency component to the center of the spectrum. + + This function swaps half-spaces for all axes listed (defaults to all). + Note that ``y[0]`` is the Nyquist component only if ``len(x)`` is even. + + Parameters + ---------- + x : array_like + Input array. + axes : int or shape tuple, optional + Axes over which to shift. Default is None, which shifts all axes. + + Returns + ------- + y : ndarray + The shifted array. + + See Also + -------- + ifftshift : The inverse of `fftshift`. + + Examples + -------- + >>> freqs = np.fft.fftfreq(10, 0.1) + >>> freqs + array([ 0., 1., 2., ..., -3., -2., -1.]) + >>> np.fft.fftshift(freqs) + array([-5., -4., -3., -2., -1., 0., 1., 2., 3., 4.]) + + Shift the zero-frequency component only along the second axis: + + >>> freqs = np.fft.fftfreq(9, d=1./9).reshape(3, 3) + >>> freqs + array([[ 0., 1., 2.], + [ 3., 4., -4.], + [-3., -2., -1.]]) + >>> np.fft.fftshift(freqs, axes=(1,)) + array([[ 2., 0., 1.], + [-4., 3., 4.], + [-1., -3., -2.]]) + + """ + x = asarray(x) + if axes is None: + axes = tuple(range(x.ndim)) + shift = [dim // 2 for dim in x.shape] + elif isinstance(axes, integer_types): + shift = x.shape[axes] // 2 + else: + shift = [x.shape[ax] // 2 for ax in axes] + + return roll(x, shift, axes) + + +@array_function_dispatch(_fftshift_dispatcher, module='numpy.fft') +def ifftshift(x, axes=None): + """ + The inverse of `fftshift`. Although identical for even-length `x`, the + functions differ by one sample for odd-length `x`. + + Parameters + ---------- + x : array_like + Input array. + axes : int or shape tuple, optional + Axes over which to calculate. Defaults to None, which shifts all axes. + + Returns + ------- + y : ndarray + The shifted array. + + See Also + -------- + fftshift : Shift zero-frequency component to the center of the spectrum. + + Examples + -------- + >>> freqs = np.fft.fftfreq(9, d=1./9).reshape(3, 3) + >>> freqs + array([[ 0., 1., 2.], + [ 3., 4., -4.], + [-3., -2., -1.]]) + >>> np.fft.ifftshift(np.fft.fftshift(freqs)) + array([[ 0., 1., 2.], + [ 3., 4., -4.], + [-3., -2., -1.]]) + + """ + x = asarray(x) + if axes is None: + axes = tuple(range(x.ndim)) + shift = [-(dim // 2) for dim in x.shape] + elif isinstance(axes, integer_types): + shift = -(x.shape[axes] // 2) + else: + shift = [-(x.shape[ax] // 2) for ax in axes] + + return roll(x, shift, axes) + + +@set_module('numpy.fft') +def fftfreq(n, d=1.0): + """ + Return the Discrete Fourier Transform sample frequencies. + + The returned float array `f` contains the frequency bin centers in cycles + per unit of the sample spacing (with zero at the start). For instance, if + the sample spacing is in seconds, then the frequency unit is cycles/second. + + Given a window length `n` and a sample spacing `d`:: + + f = [0, 1, ..., n/2-1, -n/2, ..., -1] / (d*n) if n is even + f = [0, 1, ..., (n-1)/2, -(n-1)/2, ..., -1] / (d*n) if n is odd + + Parameters + ---------- + n : int + Window length. + d : scalar, optional + Sample spacing (inverse of the sampling rate). Defaults to 1. + + Returns + ------- + f : ndarray + Array of length `n` containing the sample frequencies. + + Examples + -------- + >>> signal = np.array([-2, 8, 6, 4, 1, 0, 3, 5], dtype=float) + >>> fourier = np.fft.fft(signal) + >>> n = signal.size + >>> timestep = 0.1 + >>> freq = np.fft.fftfreq(n, d=timestep) + >>> freq + array([ 0. , 1.25, 2.5 , ..., -3.75, -2.5 , -1.25]) + + """ + if not isinstance(n, integer_types): + raise ValueError("n should be an integer") + val = 1.0 / (n * d) + results = empty(n, int) + N = (n-1)//2 + 1 + p1 = arange(0, N, dtype=int) + results[:N] = p1 + p2 = arange(-(n//2), 0, dtype=int) + results[N:] = p2 + return results * val + + +@set_module('numpy.fft') +def rfftfreq(n, d=1.0): + """ + Return the Discrete Fourier Transform sample frequencies + (for usage with rfft, irfft). + + The returned float array `f` contains the frequency bin centers in cycles + per unit of the sample spacing (with zero at the start). For instance, if + the sample spacing is in seconds, then the frequency unit is cycles/second. + + Given a window length `n` and a sample spacing `d`:: + + f = [0, 1, ..., n/2-1, n/2] / (d*n) if n is even + f = [0, 1, ..., (n-1)/2-1, (n-1)/2] / (d*n) if n is odd + + Unlike `fftfreq` (but like `scipy.fftpack.rfftfreq`) + the Nyquist frequency component is considered to be positive. + + Parameters + ---------- + n : int + Window length. + d : scalar, optional + Sample spacing (inverse of the sampling rate). Defaults to 1. + + Returns + ------- + f : ndarray + Array of length ``n//2 + 1`` containing the sample frequencies. + + Examples + -------- + >>> signal = np.array([-2, 8, 6, 4, 1, 0, 3, 5, -3, 4], dtype=float) + >>> fourier = np.fft.rfft(signal) + >>> n = signal.size + >>> sample_rate = 100 + >>> freq = np.fft.fftfreq(n, d=1./sample_rate) + >>> freq + array([ 0., 10., 20., ..., -30., -20., -10.]) + >>> freq = np.fft.rfftfreq(n, d=1./sample_rate) + >>> freq + array([ 0., 10., 20., 30., 40., 50.]) + + """ + if not isinstance(n, integer_types): + raise ValueError("n should be an integer") + val = 1.0/(n*d) + N = n//2 + 1 + results = arange(0, N, dtype=int) + return results * val diff --git a/venv/Lib/site-packages/numpy/fft/setup.py b/venv/Lib/site-packages/numpy/fft/setup.py new file mode 100644 index 0000000..477948a --- /dev/null +++ b/venv/Lib/site-packages/numpy/fft/setup.py @@ -0,0 +1,22 @@ +import sys + +def configuration(parent_package='',top_path=None): + from numpy.distutils.misc_util import Configuration + config = Configuration('fft', parent_package, top_path) + + config.add_subpackage('tests') + + # AIX needs to be told to use large file support - at all times + defs = [('_LARGE_FILES', None)] if sys.platform[:3] == "aix" else [] + # Configure pocketfft_internal + config.add_extension('_pocketfft_internal', + sources=['_pocketfft.c'], + define_macros=defs, + ) + + config.add_data_files('*.pyi') + return config + +if __name__ == '__main__': + from numpy.distutils.core import setup + setup(configuration=configuration) diff --git a/venv/Lib/site-packages/numpy/fft/tests/__init__.py b/venv/Lib/site-packages/numpy/fft/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/venv/Lib/site-packages/numpy/fft/tests/test_helper.py b/venv/Lib/site-packages/numpy/fft/tests/test_helper.py new file mode 100644 index 0000000..3fb700b --- /dev/null +++ b/venv/Lib/site-packages/numpy/fft/tests/test_helper.py @@ -0,0 +1,167 @@ +"""Test functions for fftpack.helper module + +Copied from fftpack.helper by Pearu Peterson, October 2005 + +""" +import numpy as np +from numpy.testing import assert_array_almost_equal +from numpy import fft, pi + + +class TestFFTShift: + + def test_definition(self): + x = [0, 1, 2, 3, 4, -4, -3, -2, -1] + y = [-4, -3, -2, -1, 0, 1, 2, 3, 4] + assert_array_almost_equal(fft.fftshift(x), y) + assert_array_almost_equal(fft.ifftshift(y), x) + x = [0, 1, 2, 3, 4, -5, -4, -3, -2, -1] + y = [-5, -4, -3, -2, -1, 0, 1, 2, 3, 4] + assert_array_almost_equal(fft.fftshift(x), y) + assert_array_almost_equal(fft.ifftshift(y), x) + + def test_inverse(self): + for n in [1, 4, 9, 100, 211]: + x = np.random.random((n,)) + assert_array_almost_equal(fft.ifftshift(fft.fftshift(x)), x) + + def test_axes_keyword(self): + freqs = [[0, 1, 2], [3, 4, -4], [-3, -2, -1]] + shifted = [[-1, -3, -2], [2, 0, 1], [-4, 3, 4]] + assert_array_almost_equal(fft.fftshift(freqs, axes=(0, 1)), shifted) + assert_array_almost_equal(fft.fftshift(freqs, axes=0), + fft.fftshift(freqs, axes=(0,))) + assert_array_almost_equal(fft.ifftshift(shifted, axes=(0, 1)), freqs) + assert_array_almost_equal(fft.ifftshift(shifted, axes=0), + fft.ifftshift(shifted, axes=(0,))) + + assert_array_almost_equal(fft.fftshift(freqs), shifted) + assert_array_almost_equal(fft.ifftshift(shifted), freqs) + + def test_uneven_dims(self): + """ Test 2D input, which has uneven dimension sizes """ + freqs = [ + [0, 1], + [2, 3], + [4, 5] + ] + + # shift in dimension 0 + shift_dim0 = [ + [4, 5], + [0, 1], + [2, 3] + ] + assert_array_almost_equal(fft.fftshift(freqs, axes=0), shift_dim0) + assert_array_almost_equal(fft.ifftshift(shift_dim0, axes=0), freqs) + assert_array_almost_equal(fft.fftshift(freqs, axes=(0,)), shift_dim0) + assert_array_almost_equal(fft.ifftshift(shift_dim0, axes=[0]), freqs) + + # shift in dimension 1 + shift_dim1 = [ + [1, 0], + [3, 2], + [5, 4] + ] + assert_array_almost_equal(fft.fftshift(freqs, axes=1), shift_dim1) + assert_array_almost_equal(fft.ifftshift(shift_dim1, axes=1), freqs) + + # shift in both dimensions + shift_dim_both = [ + [5, 4], + [1, 0], + [3, 2] + ] + assert_array_almost_equal(fft.fftshift(freqs, axes=(0, 1)), shift_dim_both) + assert_array_almost_equal(fft.ifftshift(shift_dim_both, axes=(0, 1)), freqs) + assert_array_almost_equal(fft.fftshift(freqs, axes=[0, 1]), shift_dim_both) + assert_array_almost_equal(fft.ifftshift(shift_dim_both, axes=[0, 1]), freqs) + + # axes=None (default) shift in all dimensions + assert_array_almost_equal(fft.fftshift(freqs, axes=None), shift_dim_both) + assert_array_almost_equal(fft.ifftshift(shift_dim_both, axes=None), freqs) + assert_array_almost_equal(fft.fftshift(freqs), shift_dim_both) + assert_array_almost_equal(fft.ifftshift(shift_dim_both), freqs) + + def test_equal_to_original(self): + """ Test that the new (>=v1.15) implementation (see #10073) is equal to the original (<=v1.14) """ + from numpy.core import asarray, concatenate, arange, take + + def original_fftshift(x, axes=None): + """ How fftshift was implemented in v1.14""" + tmp = asarray(x) + ndim = tmp.ndim + if axes is None: + axes = list(range(ndim)) + elif isinstance(axes, int): + axes = (axes,) + y = tmp + for k in axes: + n = tmp.shape[k] + p2 = (n + 1) // 2 + mylist = concatenate((arange(p2, n), arange(p2))) + y = take(y, mylist, k) + return y + + def original_ifftshift(x, axes=None): + """ How ifftshift was implemented in v1.14 """ + tmp = asarray(x) + ndim = tmp.ndim + if axes is None: + axes = list(range(ndim)) + elif isinstance(axes, int): + axes = (axes,) + y = tmp + for k in axes: + n = tmp.shape[k] + p2 = n - (n + 1) // 2 + mylist = concatenate((arange(p2, n), arange(p2))) + y = take(y, mylist, k) + return y + + # create possible 2d array combinations and try all possible keywords + # compare output to original functions + for i in range(16): + for j in range(16): + for axes_keyword in [0, 1, None, (0,), (0, 1)]: + inp = np.random.rand(i, j) + + assert_array_almost_equal(fft.fftshift(inp, axes_keyword), + original_fftshift(inp, axes_keyword)) + + assert_array_almost_equal(fft.ifftshift(inp, axes_keyword), + original_ifftshift(inp, axes_keyword)) + + +class TestFFTFreq: + + def test_definition(self): + x = [0, 1, 2, 3, 4, -4, -3, -2, -1] + assert_array_almost_equal(9*fft.fftfreq(9), x) + assert_array_almost_equal(9*pi*fft.fftfreq(9, pi), x) + x = [0, 1, 2, 3, 4, -5, -4, -3, -2, -1] + assert_array_almost_equal(10*fft.fftfreq(10), x) + assert_array_almost_equal(10*pi*fft.fftfreq(10, pi), x) + + +class TestRFFTFreq: + + def test_definition(self): + x = [0, 1, 2, 3, 4] + assert_array_almost_equal(9*fft.rfftfreq(9), x) + assert_array_almost_equal(9*pi*fft.rfftfreq(9, pi), x) + x = [0, 1, 2, 3, 4, 5] + assert_array_almost_equal(10*fft.rfftfreq(10), x) + assert_array_almost_equal(10*pi*fft.rfftfreq(10, pi), x) + + +class TestIRFFTN: + + def test_not_last_axis_success(self): + ar, ai = np.random.random((2, 16, 8, 32)) + a = ar + 1j*ai + + axes = (-2,) + + # Should not raise error + fft.irfftn(a, axes=axes) diff --git a/venv/Lib/site-packages/numpy/fft/tests/test_pocketfft.py b/venv/Lib/site-packages/numpy/fft/tests/test_pocketfft.py new file mode 100644 index 0000000..604ac8f --- /dev/null +++ b/venv/Lib/site-packages/numpy/fft/tests/test_pocketfft.py @@ -0,0 +1,307 @@ +import numpy as np +import pytest +from numpy.random import random +from numpy.testing import ( + assert_array_equal, assert_raises, assert_allclose + ) +import threading +import queue + + +def fft1(x): + L = len(x) + phase = -2j*np.pi*(np.arange(L)/float(L)) + phase = np.arange(L).reshape(-1, 1) * phase + return np.sum(x*np.exp(phase), axis=1) + + +class TestFFTShift: + + def test_fft_n(self): + assert_raises(ValueError, np.fft.fft, [1, 2, 3], 0) + + +class TestFFT1D: + + def test_identity(self): + maxlen = 512 + x = random(maxlen) + 1j*random(maxlen) + xr = random(maxlen) + for i in range(1, maxlen): + assert_allclose(np.fft.ifft(np.fft.fft(x[0:i])), x[0:i], + atol=1e-12) + assert_allclose(np.fft.irfft(np.fft.rfft(xr[0:i]), i), + xr[0:i], atol=1e-12) + + def test_fft(self): + x = random(30) + 1j*random(30) + assert_allclose(fft1(x), np.fft.fft(x), atol=1e-6) + assert_allclose(fft1(x), np.fft.fft(x, norm="backward"), atol=1e-6) + assert_allclose(fft1(x) / np.sqrt(30), + np.fft.fft(x, norm="ortho"), atol=1e-6) + assert_allclose(fft1(x) / 30., + np.fft.fft(x, norm="forward"), atol=1e-6) + + @pytest.mark.parametrize('norm', (None, 'backward', 'ortho', 'forward')) + def test_ifft(self, norm): + x = random(30) + 1j*random(30) + assert_allclose( + x, np.fft.ifft(np.fft.fft(x, norm=norm), norm=norm), + atol=1e-6) + # Ensure we get the correct error message + with pytest.raises(ValueError, + match='Invalid number of FFT data points'): + np.fft.ifft([], norm=norm) + + def test_fft2(self): + x = random((30, 20)) + 1j*random((30, 20)) + assert_allclose(np.fft.fft(np.fft.fft(x, axis=1), axis=0), + np.fft.fft2(x), atol=1e-6) + assert_allclose(np.fft.fft2(x), + np.fft.fft2(x, norm="backward"), atol=1e-6) + assert_allclose(np.fft.fft2(x) / np.sqrt(30 * 20), + np.fft.fft2(x, norm="ortho"), atol=1e-6) + assert_allclose(np.fft.fft2(x) / (30. * 20.), + np.fft.fft2(x, norm="forward"), atol=1e-6) + + def test_ifft2(self): + x = random((30, 20)) + 1j*random((30, 20)) + assert_allclose(np.fft.ifft(np.fft.ifft(x, axis=1), axis=0), + np.fft.ifft2(x), atol=1e-6) + assert_allclose(np.fft.ifft2(x), + np.fft.ifft2(x, norm="backward"), atol=1e-6) + assert_allclose(np.fft.ifft2(x) * np.sqrt(30 * 20), + np.fft.ifft2(x, norm="ortho"), atol=1e-6) + assert_allclose(np.fft.ifft2(x) * (30. * 20.), + np.fft.ifft2(x, norm="forward"), atol=1e-6) + + def test_fftn(self): + x = random((30, 20, 10)) + 1j*random((30, 20, 10)) + assert_allclose( + np.fft.fft(np.fft.fft(np.fft.fft(x, axis=2), axis=1), axis=0), + np.fft.fftn(x), atol=1e-6) + assert_allclose(np.fft.fftn(x), + np.fft.fftn(x, norm="backward"), atol=1e-6) + assert_allclose(np.fft.fftn(x) / np.sqrt(30 * 20 * 10), + np.fft.fftn(x, norm="ortho"), atol=1e-6) + assert_allclose(np.fft.fftn(x) / (30. * 20. * 10.), + np.fft.fftn(x, norm="forward"), atol=1e-6) + + def test_ifftn(self): + x = random((30, 20, 10)) + 1j*random((30, 20, 10)) + assert_allclose( + np.fft.ifft(np.fft.ifft(np.fft.ifft(x, axis=2), axis=1), axis=0), + np.fft.ifftn(x), atol=1e-6) + assert_allclose(np.fft.ifftn(x), + np.fft.ifftn(x, norm="backward"), atol=1e-6) + assert_allclose(np.fft.ifftn(x) * np.sqrt(30 * 20 * 10), + np.fft.ifftn(x, norm="ortho"), atol=1e-6) + assert_allclose(np.fft.ifftn(x) * (30. * 20. * 10.), + np.fft.ifftn(x, norm="forward"), atol=1e-6) + + def test_rfft(self): + x = random(30) + for n in [x.size, 2*x.size]: + for norm in [None, 'backward', 'ortho', 'forward']: + assert_allclose( + np.fft.fft(x, n=n, norm=norm)[:(n//2 + 1)], + np.fft.rfft(x, n=n, norm=norm), atol=1e-6) + assert_allclose( + np.fft.rfft(x, n=n), + np.fft.rfft(x, n=n, norm="backward"), atol=1e-6) + assert_allclose( + np.fft.rfft(x, n=n) / np.sqrt(n), + np.fft.rfft(x, n=n, norm="ortho"), atol=1e-6) + assert_allclose( + np.fft.rfft(x, n=n) / n, + np.fft.rfft(x, n=n, norm="forward"), atol=1e-6) + + def test_irfft(self): + x = random(30) + assert_allclose(x, np.fft.irfft(np.fft.rfft(x)), atol=1e-6) + assert_allclose(x, np.fft.irfft(np.fft.rfft(x, norm="backward"), + norm="backward"), atol=1e-6) + assert_allclose(x, np.fft.irfft(np.fft.rfft(x, norm="ortho"), + norm="ortho"), atol=1e-6) + assert_allclose(x, np.fft.irfft(np.fft.rfft(x, norm="forward"), + norm="forward"), atol=1e-6) + + def test_rfft2(self): + x = random((30, 20)) + assert_allclose(np.fft.fft2(x)[:, :11], np.fft.rfft2(x), atol=1e-6) + assert_allclose(np.fft.rfft2(x), + np.fft.rfft2(x, norm="backward"), atol=1e-6) + assert_allclose(np.fft.rfft2(x) / np.sqrt(30 * 20), + np.fft.rfft2(x, norm="ortho"), atol=1e-6) + assert_allclose(np.fft.rfft2(x) / (30. * 20.), + np.fft.rfft2(x, norm="forward"), atol=1e-6) + + def test_irfft2(self): + x = random((30, 20)) + assert_allclose(x, np.fft.irfft2(np.fft.rfft2(x)), atol=1e-6) + assert_allclose(x, np.fft.irfft2(np.fft.rfft2(x, norm="backward"), + norm="backward"), atol=1e-6) + assert_allclose(x, np.fft.irfft2(np.fft.rfft2(x, norm="ortho"), + norm="ortho"), atol=1e-6) + assert_allclose(x, np.fft.irfft2(np.fft.rfft2(x, norm="forward"), + norm="forward"), atol=1e-6) + + def test_rfftn(self): + x = random((30, 20, 10)) + assert_allclose(np.fft.fftn(x)[:, :, :6], np.fft.rfftn(x), atol=1e-6) + assert_allclose(np.fft.rfftn(x), + np.fft.rfftn(x, norm="backward"), atol=1e-6) + assert_allclose(np.fft.rfftn(x) / np.sqrt(30 * 20 * 10), + np.fft.rfftn(x, norm="ortho"), atol=1e-6) + assert_allclose(np.fft.rfftn(x) / (30. * 20. * 10.), + np.fft.rfftn(x, norm="forward"), atol=1e-6) + + def test_irfftn(self): + x = random((30, 20, 10)) + assert_allclose(x, np.fft.irfftn(np.fft.rfftn(x)), atol=1e-6) + assert_allclose(x, np.fft.irfftn(np.fft.rfftn(x, norm="backward"), + norm="backward"), atol=1e-6) + assert_allclose(x, np.fft.irfftn(np.fft.rfftn(x, norm="ortho"), + norm="ortho"), atol=1e-6) + assert_allclose(x, np.fft.irfftn(np.fft.rfftn(x, norm="forward"), + norm="forward"), atol=1e-6) + + def test_hfft(self): + x = random(14) + 1j*random(14) + x_herm = np.concatenate((random(1), x, random(1))) + x = np.concatenate((x_herm, x[::-1].conj())) + assert_allclose(np.fft.fft(x), np.fft.hfft(x_herm), atol=1e-6) + assert_allclose(np.fft.hfft(x_herm), + np.fft.hfft(x_herm, norm="backward"), atol=1e-6) + assert_allclose(np.fft.hfft(x_herm) / np.sqrt(30), + np.fft.hfft(x_herm, norm="ortho"), atol=1e-6) + assert_allclose(np.fft.hfft(x_herm) / 30., + np.fft.hfft(x_herm, norm="forward"), atol=1e-6) + + def test_ihfft(self): + x = random(14) + 1j*random(14) + x_herm = np.concatenate((random(1), x, random(1))) + x = np.concatenate((x_herm, x[::-1].conj())) + assert_allclose(x_herm, np.fft.ihfft(np.fft.hfft(x_herm)), atol=1e-6) + assert_allclose(x_herm, np.fft.ihfft(np.fft.hfft(x_herm, + norm="backward"), norm="backward"), atol=1e-6) + assert_allclose(x_herm, np.fft.ihfft(np.fft.hfft(x_herm, + norm="ortho"), norm="ortho"), atol=1e-6) + assert_allclose(x_herm, np.fft.ihfft(np.fft.hfft(x_herm, + norm="forward"), norm="forward"), atol=1e-6) + + @pytest.mark.parametrize("op", [np.fft.fftn, np.fft.ifftn, + np.fft.rfftn, np.fft.irfftn]) + def test_axes(self, op): + x = random((30, 20, 10)) + axes = [(0, 1, 2), (0, 2, 1), (1, 0, 2), (1, 2, 0), (2, 0, 1), (2, 1, 0)] + for a in axes: + op_tr = op(np.transpose(x, a)) + tr_op = np.transpose(op(x, axes=a), a) + assert_allclose(op_tr, tr_op, atol=1e-6) + + def test_all_1d_norm_preserving(self): + # verify that round-trip transforms are norm-preserving + x = random(30) + x_norm = np.linalg.norm(x) + n = x.size * 2 + func_pairs = [(np.fft.fft, np.fft.ifft), + (np.fft.rfft, np.fft.irfft), + # hfft: order so the first function takes x.size samples + # (necessary for comparison to x_norm above) + (np.fft.ihfft, np.fft.hfft), + ] + for forw, back in func_pairs: + for n in [x.size, 2*x.size]: + for norm in [None, 'backward', 'ortho', 'forward']: + tmp = forw(x, n=n, norm=norm) + tmp = back(tmp, n=n, norm=norm) + assert_allclose(x_norm, + np.linalg.norm(tmp), atol=1e-6) + + @pytest.mark.parametrize("dtype", [np.half, np.single, np.double, + np.longdouble]) + def test_dtypes(self, dtype): + # make sure that all input precisions are accepted and internally + # converted to 64bit + x = random(30).astype(dtype) + assert_allclose(np.fft.ifft(np.fft.fft(x)), x, atol=1e-6) + assert_allclose(np.fft.irfft(np.fft.rfft(x)), x, atol=1e-6) + + +@pytest.mark.parametrize( + "dtype", + [np.float32, np.float64, np.complex64, np.complex128]) +@pytest.mark.parametrize("order", ["F", 'non-contiguous']) +@pytest.mark.parametrize( + "fft", + [np.fft.fft, np.fft.fft2, np.fft.fftn, + np.fft.ifft, np.fft.ifft2, np.fft.ifftn]) +def test_fft_with_order(dtype, order, fft): + # Check that FFT/IFFT produces identical results for C, Fortran and + # non contiguous arrays + rng = np.random.RandomState(42) + X = rng.rand(8, 7, 13).astype(dtype, copy=False) + # See discussion in pull/14178 + _tol = 8.0 * np.sqrt(np.log2(X.size)) * np.finfo(X.dtype).eps + if order == 'F': + Y = np.asfortranarray(X) + else: + # Make a non contiguous array + Y = X[::-1] + X = np.ascontiguousarray(X[::-1]) + + if fft.__name__.endswith('fft'): + for axis in range(3): + X_res = fft(X, axis=axis) + Y_res = fft(Y, axis=axis) + assert_allclose(X_res, Y_res, atol=_tol, rtol=_tol) + elif fft.__name__.endswith(('fft2', 'fftn')): + axes = [(0, 1), (1, 2), (0, 2)] + if fft.__name__.endswith('fftn'): + axes.extend([(0,), (1,), (2,), None]) + for ax in axes: + X_res = fft(X, axes=ax) + Y_res = fft(Y, axes=ax) + assert_allclose(X_res, Y_res, atol=_tol, rtol=_tol) + else: + raise ValueError() + + +class TestFFTThreadSafe: + threads = 16 + input_shape = (800, 200) + + def _test_mtsame(self, func, *args): + def worker(args, q): + q.put(func(*args)) + + q = queue.Queue() + expected = func(*args) + + # Spin off a bunch of threads to call the same function simultaneously + t = [threading.Thread(target=worker, args=(args, q)) + for i in range(self.threads)] + [x.start() for x in t] + + [x.join() for x in t] + # Make sure all threads returned the correct value + for i in range(self.threads): + assert_array_equal(q.get(timeout=5), expected, + 'Function returned wrong value in multithreaded context') + + def test_fft(self): + a = np.ones(self.input_shape) * 1+0j + self._test_mtsame(np.fft.fft, a) + + def test_ifft(self): + a = np.ones(self.input_shape) * 1+0j + self._test_mtsame(np.fft.ifft, a) + + def test_rfft(self): + a = np.ones(self.input_shape) + self._test_mtsame(np.fft.rfft, a) + + def test_irfft(self): + a = np.ones(self.input_shape) * 1+0j + self._test_mtsame(np.fft.irfft, a) diff --git a/venv/Lib/site-packages/numpy/lib/__init__.py b/venv/Lib/site-packages/numpy/lib/__init__.py new file mode 100644 index 0000000..ad88ba3 --- /dev/null +++ b/venv/Lib/site-packages/numpy/lib/__init__.py @@ -0,0 +1,61 @@ +""" +**Note:** almost all functions in the ``numpy.lib`` namespace +are also present in the main ``numpy`` namespace. Please use the +functions as ``np.`` where possible. + +``numpy.lib`` is mostly a space for implementing functions that don't +belong in core or in another NumPy submodule with a clear purpose +(e.g. ``random``, ``fft``, ``linalg``, ``ma``). + +Most contains basic functions that are used by several submodules and are +useful to have in the main name-space. + +""" +import math + +from numpy.version import version as __version__ + +# Public submodules +# Note: recfunctions and (maybe) format are public too, but not imported +from . import mixins +from . import scimath as emath + +# Private submodules +from .type_check import * +from .index_tricks import * +from .function_base import * +from .nanfunctions import * +from .shape_base import * +from .stride_tricks import * +from .twodim_base import * +from .ufunclike import * +from .histograms import * + +from .polynomial import * +from .utils import * +from .arraysetops import * +from .npyio import * +from .arrayterator import Arrayterator +from .arraypad import * +from ._version import * +from numpy.core._multiarray_umath import tracemalloc_domain + +__all__ = ['emath', 'math', 'tracemalloc_domain', 'Arrayterator'] +__all__ += type_check.__all__ +__all__ += index_tricks.__all__ +__all__ += function_base.__all__ +__all__ += shape_base.__all__ +__all__ += stride_tricks.__all__ +__all__ += twodim_base.__all__ +__all__ += ufunclike.__all__ +__all__ += arraypad.__all__ +__all__ += polynomial.__all__ +__all__ += utils.__all__ +__all__ += arraysetops.__all__ +__all__ += npyio.__all__ +__all__ += nanfunctions.__all__ +__all__ += histograms.__all__ + +from numpy._pytesttester import PytestTester +test = PytestTester(__name__) +del PytestTester diff --git a/venv/Lib/site-packages/numpy/lib/__init__.pyi b/venv/Lib/site-packages/numpy/lib/__init__.pyi new file mode 100644 index 0000000..9844239 --- /dev/null +++ b/venv/Lib/site-packages/numpy/lib/__init__.pyi @@ -0,0 +1,187 @@ +from typing import Any, List + +from numpy.lib import ( + format as format, + mixins as mixins, + scimath as scimath, + stride_tricks as stride_stricks, +) + +__all__: List[str] + +emath: Any +math: Any +tracemalloc_domain: Any +Arrayterator: Any +iscomplexobj: Any +isrealobj: Any +imag: Any +iscomplex: Any +isreal: Any +nan_to_num: Any +real: Any +real_if_close: Any +typename: Any +asfarray: Any +mintypecode: Any +asscalar: Any +common_type: Any +ravel_multi_index: Any +unravel_index: Any +mgrid: Any +ogrid: Any +r_: Any +c_: Any +s_: Any +index_exp: Any +ix_: Any +ndenumerate: Any +ndindex: Any +fill_diagonal: Any +diag_indices: Any +diag_indices_from: Any +select: Any +piecewise: Any +trim_zeros: Any +copy: Any +iterable: Any +percentile: Any +diff: Any +gradient: Any +angle: Any +unwrap: Any +sort_complex: Any +disp: Any +flip: Any +rot90: Any +extract: Any +place: Any +vectorize: Any +asarray_chkfinite: Any +average: Any +bincount: Any +digitize: Any +cov: Any +corrcoef: Any +msort: Any +median: Any +sinc: Any +hamming: Any +hanning: Any +bartlett: Any +blackman: Any +kaiser: Any +trapz: Any +i0: Any +add_newdoc: Any +add_docstring: Any +meshgrid: Any +delete: Any +insert: Any +append: Any +interp: Any +add_newdoc_ufunc: Any +quantile: Any +column_stack: Any +row_stack: Any +dstack: Any +array_split: Any +split: Any +hsplit: Any +vsplit: Any +dsplit: Any +apply_over_axes: Any +expand_dims: Any +apply_along_axis: Any +kron: Any +tile: Any +get_array_wrap: Any +take_along_axis: Any +put_along_axis: Any +broadcast_to: Any +broadcast_arrays: Any +diag: Any +diagflat: Any +eye: Any +fliplr: Any +flipud: Any +tri: Any +triu: Any +tril: Any +vander: Any +histogram2d: Any +mask_indices: Any +tril_indices: Any +tril_indices_from: Any +triu_indices: Any +triu_indices_from: Any +fix: Any +isneginf: Any +isposinf: Any +pad: Any +poly: Any +roots: Any +polyint: Any +polyder: Any +polyadd: Any +polysub: Any +polymul: Any +polydiv: Any +polyval: Any +poly1d: Any +polyfit: Any +RankWarning: Any +issubclass_: Any +issubsctype: Any +issubdtype: Any +deprecate: Any +deprecate_with_doc: Any +get_include: Any +info: Any +source: Any +who: Any +lookfor: Any +byte_bounds: Any +safe_eval: Any +ediff1d: Any +intersect1d: Any +setxor1d: Any +union1d: Any +setdiff1d: Any +unique: Any +in1d: Any +isin: Any +savetxt: Any +loadtxt: Any +genfromtxt: Any +ndfromtxt: Any +mafromtxt: Any +recfromtxt: Any +recfromcsv: Any +load: Any +loads: Any +save: Any +savez: Any +savez_compressed: Any +packbits: Any +unpackbits: Any +fromregex: Any +DataSource: Any +nansum: Any +nanmax: Any +nanmin: Any +nanargmax: Any +nanargmin: Any +nanmean: Any +nanmedian: Any +nanpercentile: Any +nanvar: Any +nanstd: Any +nanprod: Any +nancumsum: Any +nancumprod: Any +nanquantile: Any +histogram: Any +histogramdd: Any +histogram_bin_edges: Any +NumpyVersion: Any diff --git a/venv/Lib/site-packages/numpy/lib/_datasource.py b/venv/Lib/site-packages/numpy/lib/_datasource.py new file mode 100644 index 0000000..7a23b16 --- /dev/null +++ b/venv/Lib/site-packages/numpy/lib/_datasource.py @@ -0,0 +1,702 @@ +"""A file interface for handling local and remote data files. + +The goal of datasource is to abstract some of the file system operations +when dealing with data files so the researcher doesn't have to know all the +low-level details. Through datasource, a researcher can obtain and use a +file with one function call, regardless of location of the file. + +DataSource is meant to augment standard python libraries, not replace them. +It should work seamlessly with standard file IO operations and the os +module. + +DataSource files can originate locally or remotely: + +- local files : '/home/guido/src/local/data.txt' +- URLs (http, ftp, ...) : 'http://www.scipy.org/not/real/data.txt' + +DataSource files can also be compressed or uncompressed. Currently only +gzip, bz2 and xz are supported. + +Example:: + + >>> # Create a DataSource, use os.curdir (default) for local storage. + >>> from numpy import DataSource + >>> ds = DataSource() + >>> + >>> # Open a remote file. + >>> # DataSource downloads the file, stores it locally in: + >>> # './www.google.com/index.html' + >>> # opens the file and returns a file object. + >>> fp = ds.open('http://www.google.com/') # doctest: +SKIP + >>> + >>> # Use the file as you normally would + >>> fp.read() # doctest: +SKIP + >>> fp.close() # doctest: +SKIP + +""" +import os +import shutil +import io + +from numpy.core.overrides import set_module + + +_open = open + + +def _check_mode(mode, encoding, newline): + """Check mode and that encoding and newline are compatible. + + Parameters + ---------- + mode : str + File open mode. + encoding : str + File encoding. + newline : str + Newline for text files. + + """ + if "t" in mode: + if "b" in mode: + raise ValueError("Invalid mode: %r" % (mode,)) + else: + if encoding is not None: + raise ValueError("Argument 'encoding' not supported in binary mode") + if newline is not None: + raise ValueError("Argument 'newline' not supported in binary mode") + + +# Using a class instead of a module-level dictionary +# to reduce the initial 'import numpy' overhead by +# deferring the import of lzma, bz2 and gzip until needed + +# TODO: .zip support, .tar support? +class _FileOpeners: + """ + Container for different methods to open (un-)compressed files. + + `_FileOpeners` contains a dictionary that holds one method for each + supported file format. Attribute lookup is implemented in such a way + that an instance of `_FileOpeners` itself can be indexed with the keys + of that dictionary. Currently uncompressed files as well as files + compressed with ``gzip``, ``bz2`` or ``xz`` compression are supported. + + Notes + ----- + `_file_openers`, an instance of `_FileOpeners`, is made available for + use in the `_datasource` module. + + Examples + -------- + >>> import gzip + >>> np.lib._datasource._file_openers.keys() + [None, '.bz2', '.gz', '.xz', '.lzma'] + >>> np.lib._datasource._file_openers['.gz'] is gzip.open + True + + """ + + def __init__(self): + self._loaded = False + self._file_openers = {None: io.open} + + def _load(self): + if self._loaded: + return + + try: + import bz2 + self._file_openers[".bz2"] = bz2.open + except ImportError: + pass + + try: + import gzip + self._file_openers[".gz"] = gzip.open + except ImportError: + pass + + try: + import lzma + self._file_openers[".xz"] = lzma.open + self._file_openers[".lzma"] = lzma.open + except (ImportError, AttributeError): + # There are incompatible backports of lzma that do not have the + # lzma.open attribute, so catch that as well as ImportError. + pass + + self._loaded = True + + def keys(self): + """ + Return the keys of currently supported file openers. + + Parameters + ---------- + None + + Returns + ------- + keys : list + The keys are None for uncompressed files and the file extension + strings (i.e. ``'.gz'``, ``'.xz'``) for supported compression + methods. + + """ + self._load() + return list(self._file_openers.keys()) + + def __getitem__(self, key): + self._load() + return self._file_openers[key] + +_file_openers = _FileOpeners() + +def open(path, mode='r', destpath=os.curdir, encoding=None, newline=None): + """ + Open `path` with `mode` and return the file object. + + If ``path`` is an URL, it will be downloaded, stored in the + `DataSource` `destpath` directory and opened from there. + + Parameters + ---------- + path : str + Local file path or URL to open. + mode : str, optional + Mode to open `path`. Mode 'r' for reading, 'w' for writing, 'a' to + append. Available modes depend on the type of object specified by + path. Default is 'r'. + destpath : str, optional + Path to the directory where the source file gets downloaded to for + use. If `destpath` is None, a temporary directory will be created. + The default path is the current directory. + encoding : {None, str}, optional + Open text file with given encoding. The default encoding will be + what `io.open` uses. + newline : {None, str}, optional + Newline to use when reading text file. + + Returns + ------- + out : file object + The opened file. + + Notes + ----- + This is a convenience function that instantiates a `DataSource` and + returns the file object from ``DataSource.open(path)``. + + """ + + ds = DataSource(destpath) + return ds.open(path, mode, encoding=encoding, newline=newline) + + +@set_module('numpy') +class DataSource: + """ + DataSource(destpath='.') + + A generic data source file (file, http, ftp, ...). + + DataSources can be local files or remote files/URLs. The files may + also be compressed or uncompressed. DataSource hides some of the + low-level details of downloading the file, allowing you to simply pass + in a valid file path (or URL) and obtain a file object. + + Parameters + ---------- + destpath : str or None, optional + Path to the directory where the source file gets downloaded to for + use. If `destpath` is None, a temporary directory will be created. + The default path is the current directory. + + Notes + ----- + URLs require a scheme string (``http://``) to be used, without it they + will fail:: + + >>> repos = np.DataSource() + >>> repos.exists('www.google.com/index.html') + False + >>> repos.exists('http://www.google.com/index.html') + True + + Temporary directories are deleted when the DataSource is deleted. + + Examples + -------- + :: + + >>> ds = np.DataSource('/home/guido') + >>> urlname = 'http://www.google.com/' + >>> gfile = ds.open('http://www.google.com/') + >>> ds.abspath(urlname) + '/home/guido/www.google.com/index.html' + + >>> ds = np.DataSource(None) # use with temporary file + >>> ds.open('/home/guido/foobar.txt') + + >>> ds.abspath('/home/guido/foobar.txt') + '/tmp/.../home/guido/foobar.txt' + + """ + + def __init__(self, destpath=os.curdir): + """Create a DataSource with a local path at destpath.""" + if destpath: + self._destpath = os.path.abspath(destpath) + self._istmpdest = False + else: + import tempfile # deferring import to improve startup time + self._destpath = tempfile.mkdtemp() + self._istmpdest = True + + def __del__(self): + # Remove temp directories + if hasattr(self, '_istmpdest') and self._istmpdest: + shutil.rmtree(self._destpath) + + def _iszip(self, filename): + """Test if the filename is a zip file by looking at the file extension. + + """ + fname, ext = os.path.splitext(filename) + return ext in _file_openers.keys() + + def _iswritemode(self, mode): + """Test if the given mode will open a file for writing.""" + + # Currently only used to test the bz2 files. + _writemodes = ("w", "+") + for c in mode: + if c in _writemodes: + return True + return False + + def _splitzipext(self, filename): + """Split zip extension from filename and return filename. + + *Returns*: + base, zip_ext : {tuple} + + """ + + if self._iszip(filename): + return os.path.splitext(filename) + else: + return filename, None + + def _possible_names(self, filename): + """Return a tuple containing compressed filename variations.""" + names = [filename] + if not self._iszip(filename): + for zipext in _file_openers.keys(): + if zipext: + names.append(filename+zipext) + return names + + def _isurl(self, path): + """Test if path is a net location. Tests the scheme and netloc.""" + + # We do this here to reduce the 'import numpy' initial import time. + from urllib.parse import urlparse + + # BUG : URLs require a scheme string ('http://') to be used. + # www.google.com will fail. + # Should we prepend the scheme for those that don't have it and + # test that also? Similar to the way we append .gz and test for + # for compressed versions of files. + + scheme, netloc, upath, uparams, uquery, ufrag = urlparse(path) + return bool(scheme and netloc) + + def _cache(self, path): + """Cache the file specified by path. + + Creates a copy of the file in the datasource cache. + + """ + # We import these here because importing urllib is slow and + # a significant fraction of numpy's total import time. + from urllib.request import urlopen + from urllib.error import URLError + + upath = self.abspath(path) + + # ensure directory exists + if not os.path.exists(os.path.dirname(upath)): + os.makedirs(os.path.dirname(upath)) + + # TODO: Doesn't handle compressed files! + if self._isurl(path): + with urlopen(path) as openedurl: + with _open(upath, 'wb') as f: + shutil.copyfileobj(openedurl, f) + else: + shutil.copyfile(path, upath) + return upath + + def _findfile(self, path): + """Searches for ``path`` and returns full path if found. + + If path is an URL, _findfile will cache a local copy and return the + path to the cached file. If path is a local file, _findfile will + return a path to that local file. + + The search will include possible compressed versions of the file + and return the first occurrence found. + + """ + + # Build list of possible local file paths + if not self._isurl(path): + # Valid local paths + filelist = self._possible_names(path) + # Paths in self._destpath + filelist += self._possible_names(self.abspath(path)) + else: + # Cached URLs in self._destpath + filelist = self._possible_names(self.abspath(path)) + # Remote URLs + filelist = filelist + self._possible_names(path) + + for name in filelist: + if self.exists(name): + if self._isurl(name): + name = self._cache(name) + return name + return None + + def abspath(self, path): + """ + Return absolute path of file in the DataSource directory. + + If `path` is an URL, then `abspath` will return either the location + the file exists locally or the location it would exist when opened + using the `open` method. + + Parameters + ---------- + path : str + Can be a local file or a remote URL. + + Returns + ------- + out : str + Complete path, including the `DataSource` destination directory. + + Notes + ----- + The functionality is based on `os.path.abspath`. + + """ + # We do this here to reduce the 'import numpy' initial import time. + from urllib.parse import urlparse + + # TODO: This should be more robust. Handles case where path includes + # the destpath, but not other sub-paths. Failing case: + # path = /home/guido/datafile.txt + # destpath = /home/alex/ + # upath = self.abspath(path) + # upath == '/home/alex/home/guido/datafile.txt' + + # handle case where path includes self._destpath + splitpath = path.split(self._destpath, 2) + if len(splitpath) > 1: + path = splitpath[1] + scheme, netloc, upath, uparams, uquery, ufrag = urlparse(path) + netloc = self._sanitize_relative_path(netloc) + upath = self._sanitize_relative_path(upath) + return os.path.join(self._destpath, netloc, upath) + + def _sanitize_relative_path(self, path): + """Return a sanitised relative path for which + os.path.abspath(os.path.join(base, path)).startswith(base) + """ + last = None + path = os.path.normpath(path) + while path != last: + last = path + # Note: os.path.join treats '/' as os.sep on Windows + path = path.lstrip(os.sep).lstrip('/') + path = path.lstrip(os.pardir).lstrip('..') + drive, path = os.path.splitdrive(path) # for Windows + return path + + def exists(self, path): + """ + Test if path exists. + + Test if `path` exists as (and in this order): + + - a local file. + - a remote URL that has been downloaded and stored locally in the + `DataSource` directory. + - a remote URL that has not been downloaded, but is valid and + accessible. + + Parameters + ---------- + path : str + Can be a local file or a remote URL. + + Returns + ------- + out : bool + True if `path` exists. + + Notes + ----- + When `path` is an URL, `exists` will return True if it's either + stored locally in the `DataSource` directory, or is a valid remote + URL. `DataSource` does not discriminate between the two, the file + is accessible if it exists in either location. + + """ + + # First test for local path + if os.path.exists(path): + return True + + # We import this here because importing urllib is slow and + # a significant fraction of numpy's total import time. + from urllib.request import urlopen + from urllib.error import URLError + + # Test cached url + upath = self.abspath(path) + if os.path.exists(upath): + return True + + # Test remote url + if self._isurl(path): + try: + netfile = urlopen(path) + netfile.close() + del(netfile) + return True + except URLError: + return False + return False + + def open(self, path, mode='r', encoding=None, newline=None): + """ + Open and return file-like object. + + If `path` is an URL, it will be downloaded, stored in the + `DataSource` directory and opened from there. + + Parameters + ---------- + path : str + Local file path or URL to open. + mode : {'r', 'w', 'a'}, optional + Mode to open `path`. Mode 'r' for reading, 'w' for writing, + 'a' to append. Available modes depend on the type of object + specified by `path`. Default is 'r'. + encoding : {None, str}, optional + Open text file with given encoding. The default encoding will be + what `io.open` uses. + newline : {None, str}, optional + Newline to use when reading text file. + + Returns + ------- + out : file object + File object. + + """ + + # TODO: There is no support for opening a file for writing which + # doesn't exist yet (creating a file). Should there be? + + # TODO: Add a ``subdir`` parameter for specifying the subdirectory + # used to store URLs in self._destpath. + + if self._isurl(path) and self._iswritemode(mode): + raise ValueError("URLs are not writeable") + + # NOTE: _findfile will fail on a new file opened for writing. + found = self._findfile(path) + if found: + _fname, ext = self._splitzipext(found) + if ext == 'bz2': + mode.replace("+", "") + return _file_openers[ext](found, mode=mode, + encoding=encoding, newline=newline) + else: + raise IOError("%s not found." % path) + + +class Repository (DataSource): + """ + Repository(baseurl, destpath='.') + + A data repository where multiple DataSource's share a base + URL/directory. + + `Repository` extends `DataSource` by prepending a base URL (or + directory) to all the files it handles. Use `Repository` when you will + be working with multiple files from one base URL. Initialize + `Repository` with the base URL, then refer to each file by its filename + only. + + Parameters + ---------- + baseurl : str + Path to the local directory or remote location that contains the + data files. + destpath : str or None, optional + Path to the directory where the source file gets downloaded to for + use. If `destpath` is None, a temporary directory will be created. + The default path is the current directory. + + Examples + -------- + To analyze all files in the repository, do something like this + (note: this is not self-contained code):: + + >>> repos = np.lib._datasource.Repository('/home/user/data/dir/') + >>> for filename in filelist: + ... fp = repos.open(filename) + ... fp.analyze() + ... fp.close() + + Similarly you could use a URL for a repository:: + + >>> repos = np.lib._datasource.Repository('http://www.xyz.edu/data') + + """ + + def __init__(self, baseurl, destpath=os.curdir): + """Create a Repository with a shared url or directory of baseurl.""" + DataSource.__init__(self, destpath=destpath) + self._baseurl = baseurl + + def __del__(self): + DataSource.__del__(self) + + def _fullpath(self, path): + """Return complete path for path. Prepends baseurl if necessary.""" + splitpath = path.split(self._baseurl, 2) + if len(splitpath) == 1: + result = os.path.join(self._baseurl, path) + else: + result = path # path contains baseurl already + return result + + def _findfile(self, path): + """Extend DataSource method to prepend baseurl to ``path``.""" + return DataSource._findfile(self, self._fullpath(path)) + + def abspath(self, path): + """ + Return absolute path of file in the Repository directory. + + If `path` is an URL, then `abspath` will return either the location + the file exists locally or the location it would exist when opened + using the `open` method. + + Parameters + ---------- + path : str + Can be a local file or a remote URL. This may, but does not + have to, include the `baseurl` with which the `Repository` was + initialized. + + Returns + ------- + out : str + Complete path, including the `DataSource` destination directory. + + """ + return DataSource.abspath(self, self._fullpath(path)) + + def exists(self, path): + """ + Test if path exists prepending Repository base URL to path. + + Test if `path` exists as (and in this order): + + - a local file. + - a remote URL that has been downloaded and stored locally in the + `DataSource` directory. + - a remote URL that has not been downloaded, but is valid and + accessible. + + Parameters + ---------- + path : str + Can be a local file or a remote URL. This may, but does not + have to, include the `baseurl` with which the `Repository` was + initialized. + + Returns + ------- + out : bool + True if `path` exists. + + Notes + ----- + When `path` is an URL, `exists` will return True if it's either + stored locally in the `DataSource` directory, or is a valid remote + URL. `DataSource` does not discriminate between the two, the file + is accessible if it exists in either location. + + """ + return DataSource.exists(self, self._fullpath(path)) + + def open(self, path, mode='r', encoding=None, newline=None): + """ + Open and return file-like object prepending Repository base URL. + + If `path` is an URL, it will be downloaded, stored in the + DataSource directory and opened from there. + + Parameters + ---------- + path : str + Local file path or URL to open. This may, but does not have to, + include the `baseurl` with which the `Repository` was + initialized. + mode : {'r', 'w', 'a'}, optional + Mode to open `path`. Mode 'r' for reading, 'w' for writing, + 'a' to append. Available modes depend on the type of object + specified by `path`. Default is 'r'. + encoding : {None, str}, optional + Open text file with given encoding. The default encoding will be + what `io.open` uses. + newline : {None, str}, optional + Newline to use when reading text file. + + Returns + ------- + out : file object + File object. + + """ + return DataSource.open(self, self._fullpath(path), mode, + encoding=encoding, newline=newline) + + def listdir(self): + """ + List files in the source Repository. + + Returns + ------- + files : list of str + List of file names (not containing a directory part). + + Notes + ----- + Does not currently work for remote repositories. + + """ + if self._isurl(self._baseurl): + raise NotImplementedError( + "Directory listing of URLs, not supported yet.") + else: + return os.listdir(self._baseurl) diff --git a/venv/Lib/site-packages/numpy/lib/_iotools.py b/venv/Lib/site-packages/numpy/lib/_iotools.py new file mode 100644 index 0000000..a576925 --- /dev/null +++ b/venv/Lib/site-packages/numpy/lib/_iotools.py @@ -0,0 +1,898 @@ +"""A collection of functions designed to help I/O with ascii files. + +""" +__docformat__ = "restructuredtext en" + +import numpy as np +import numpy.core.numeric as nx +from numpy.compat import asbytes, asunicode + + +def _decode_line(line, encoding=None): + """Decode bytes from binary input streams. + + Defaults to decoding from 'latin1'. That differs from the behavior of + np.compat.asunicode that decodes from 'ascii'. + + Parameters + ---------- + line : str or bytes + Line to be decoded. + encoding : str + Encoding used to decode `line`. + + Returns + ------- + decoded_line : unicode + Unicode in Python 2, a str (unicode) in Python 3. + + """ + if type(line) is bytes: + if encoding is None: + encoding = "latin1" + line = line.decode(encoding) + + return line + + +def _is_string_like(obj): + """ + Check whether obj behaves like a string. + """ + try: + obj + '' + except (TypeError, ValueError): + return False + return True + + +def _is_bytes_like(obj): + """ + Check whether obj behaves like a bytes object. + """ + try: + obj + b'' + except (TypeError, ValueError): + return False + return True + + +def has_nested_fields(ndtype): + """ + Returns whether one or several fields of a dtype are nested. + + Parameters + ---------- + ndtype : dtype + Data-type of a structured array. + + Raises + ------ + AttributeError + If `ndtype` does not have a `names` attribute. + + Examples + -------- + >>> dt = np.dtype([('name', 'S4'), ('x', float), ('y', float)]) + >>> np.lib._iotools.has_nested_fields(dt) + False + + """ + for name in ndtype.names or (): + if ndtype[name].names is not None: + return True + return False + + +def flatten_dtype(ndtype, flatten_base=False): + """ + Unpack a structured data-type by collapsing nested fields and/or fields + with a shape. + + Note that the field names are lost. + + Parameters + ---------- + ndtype : dtype + The datatype to collapse + flatten_base : bool, optional + If True, transform a field with a shape into several fields. Default is + False. + + Examples + -------- + >>> dt = np.dtype([('name', 'S4'), ('x', float), ('y', float), + ... ('block', int, (2, 3))]) + >>> np.lib._iotools.flatten_dtype(dt) + [dtype('S4'), dtype('float64'), dtype('float64'), dtype('int64')] + >>> np.lib._iotools.flatten_dtype(dt, flatten_base=True) + [dtype('S4'), + dtype('float64'), + dtype('float64'), + dtype('int64'), + dtype('int64'), + dtype('int64'), + dtype('int64'), + dtype('int64'), + dtype('int64')] + + """ + names = ndtype.names + if names is None: + if flatten_base: + return [ndtype.base] * int(np.prod(ndtype.shape)) + return [ndtype.base] + else: + types = [] + for field in names: + info = ndtype.fields[field] + flat_dt = flatten_dtype(info[0], flatten_base) + types.extend(flat_dt) + return types + + +class LineSplitter: + """ + Object to split a string at a given delimiter or at given places. + + Parameters + ---------- + delimiter : str, int, or sequence of ints, optional + If a string, character used to delimit consecutive fields. + If an integer or a sequence of integers, width(s) of each field. + comments : str, optional + Character used to mark the beginning of a comment. Default is '#'. + autostrip : bool, optional + Whether to strip each individual field. Default is True. + + """ + + def autostrip(self, method): + """ + Wrapper to strip each member of the output of `method`. + + Parameters + ---------- + method : function + Function that takes a single argument and returns a sequence of + strings. + + Returns + ------- + wrapped : function + The result of wrapping `method`. `wrapped` takes a single input + argument and returns a list of strings that are stripped of + white-space. + + """ + return lambda input: [_.strip() for _ in method(input)] + + def __init__(self, delimiter=None, comments='#', autostrip=True, + encoding=None): + delimiter = _decode_line(delimiter) + comments = _decode_line(comments) + + self.comments = comments + + # Delimiter is a character + if (delimiter is None) or isinstance(delimiter, str): + delimiter = delimiter or None + _handyman = self._delimited_splitter + # Delimiter is a list of field widths + elif hasattr(delimiter, '__iter__'): + _handyman = self._variablewidth_splitter + idx = np.cumsum([0] + list(delimiter)) + delimiter = [slice(i, j) for (i, j) in zip(idx[:-1], idx[1:])] + # Delimiter is a single integer + elif int(delimiter): + (_handyman, delimiter) = ( + self._fixedwidth_splitter, int(delimiter)) + else: + (_handyman, delimiter) = (self._delimited_splitter, None) + self.delimiter = delimiter + if autostrip: + self._handyman = self.autostrip(_handyman) + else: + self._handyman = _handyman + self.encoding = encoding + + def _delimited_splitter(self, line): + """Chop off comments, strip, and split at delimiter. """ + if self.comments is not None: + line = line.split(self.comments)[0] + line = line.strip(" \r\n") + if not line: + return [] + return line.split(self.delimiter) + + def _fixedwidth_splitter(self, line): + if self.comments is not None: + line = line.split(self.comments)[0] + line = line.strip("\r\n") + if not line: + return [] + fixed = self.delimiter + slices = [slice(i, i + fixed) for i in range(0, len(line), fixed)] + return [line[s] for s in slices] + + def _variablewidth_splitter(self, line): + if self.comments is not None: + line = line.split(self.comments)[0] + if not line: + return [] + slices = self.delimiter + return [line[s] for s in slices] + + def __call__(self, line): + return self._handyman(_decode_line(line, self.encoding)) + + +class NameValidator: + """ + Object to validate a list of strings to use as field names. + + The strings are stripped of any non alphanumeric character, and spaces + are replaced by '_'. During instantiation, the user can define a list + of names to exclude, as well as a list of invalid characters. Names in + the exclusion list are appended a '_' character. + + Once an instance has been created, it can be called with a list of + names, and a list of valid names will be created. The `__call__` + method accepts an optional keyword "default" that sets the default name + in case of ambiguity. By default this is 'f', so that names will + default to `f0`, `f1`, etc. + + Parameters + ---------- + excludelist : sequence, optional + A list of names to exclude. This list is appended to the default + list ['return', 'file', 'print']. Excluded names are appended an + underscore: for example, `file` becomes `file_` if supplied. + deletechars : str, optional + A string combining invalid characters that must be deleted from the + names. + case_sensitive : {True, False, 'upper', 'lower'}, optional + * If True, field names are case-sensitive. + * If False or 'upper', field names are converted to upper case. + * If 'lower', field names are converted to lower case. + + The default value is True. + replace_space : '_', optional + Character(s) used in replacement of white spaces. + + Notes + ----- + Calling an instance of `NameValidator` is the same as calling its + method `validate`. + + Examples + -------- + >>> validator = np.lib._iotools.NameValidator() + >>> validator(['file', 'field2', 'with space', 'CaSe']) + ('file_', 'field2', 'with_space', 'CaSe') + + >>> validator = np.lib._iotools.NameValidator(excludelist=['excl'], + ... deletechars='q', + ... case_sensitive=False) + >>> validator(['excl', 'field2', 'no_q', 'with space', 'CaSe']) + ('EXCL', 'FIELD2', 'NO_Q', 'WITH_SPACE', 'CASE') + + """ + + defaultexcludelist = ['return', 'file', 'print'] + defaultdeletechars = set(r"""~!@#$%^&*()-=+~\|]}[{';: /?.>,<""") + + def __init__(self, excludelist=None, deletechars=None, + case_sensitive=None, replace_space='_'): + # Process the exclusion list .. + if excludelist is None: + excludelist = [] + excludelist.extend(self.defaultexcludelist) + self.excludelist = excludelist + # Process the list of characters to delete + if deletechars is None: + delete = self.defaultdeletechars + else: + delete = set(deletechars) + delete.add('"') + self.deletechars = delete + # Process the case option ..... + if (case_sensitive is None) or (case_sensitive is True): + self.case_converter = lambda x: x + elif (case_sensitive is False) or case_sensitive.startswith('u'): + self.case_converter = lambda x: x.upper() + elif case_sensitive.startswith('l'): + self.case_converter = lambda x: x.lower() + else: + msg = 'unrecognized case_sensitive value %s.' % case_sensitive + raise ValueError(msg) + + self.replace_space = replace_space + + def validate(self, names, defaultfmt="f%i", nbfields=None): + """ + Validate a list of strings as field names for a structured array. + + Parameters + ---------- + names : sequence of str + Strings to be validated. + defaultfmt : str, optional + Default format string, used if validating a given string + reduces its length to zero. + nbfields : integer, optional + Final number of validated names, used to expand or shrink the + initial list of names. + + Returns + ------- + validatednames : list of str + The list of validated field names. + + Notes + ----- + A `NameValidator` instance can be called directly, which is the + same as calling `validate`. For examples, see `NameValidator`. + + """ + # Initial checks .............. + if (names is None): + if (nbfields is None): + return None + names = [] + if isinstance(names, str): + names = [names, ] + if nbfields is not None: + nbnames = len(names) + if (nbnames < nbfields): + names = list(names) + [''] * (nbfields - nbnames) + elif (nbnames > nbfields): + names = names[:nbfields] + # Set some shortcuts ........... + deletechars = self.deletechars + excludelist = self.excludelist + case_converter = self.case_converter + replace_space = self.replace_space + # Initializes some variables ... + validatednames = [] + seen = dict() + nbempty = 0 + + for item in names: + item = case_converter(item).strip() + if replace_space: + item = item.replace(' ', replace_space) + item = ''.join([c for c in item if c not in deletechars]) + if item == '': + item = defaultfmt % nbempty + while item in names: + nbempty += 1 + item = defaultfmt % nbempty + nbempty += 1 + elif item in excludelist: + item += '_' + cnt = seen.get(item, 0) + if cnt > 0: + validatednames.append(item + '_%d' % cnt) + else: + validatednames.append(item) + seen[item] = cnt + 1 + return tuple(validatednames) + + def __call__(self, names, defaultfmt="f%i", nbfields=None): + return self.validate(names, defaultfmt=defaultfmt, nbfields=nbfields) + + +def str2bool(value): + """ + Tries to transform a string supposed to represent a boolean to a boolean. + + Parameters + ---------- + value : str + The string that is transformed to a boolean. + + Returns + ------- + boolval : bool + The boolean representation of `value`. + + Raises + ------ + ValueError + If the string is not 'True' or 'False' (case independent) + + Examples + -------- + >>> np.lib._iotools.str2bool('TRUE') + True + >>> np.lib._iotools.str2bool('false') + False + + """ + value = value.upper() + if value == 'TRUE': + return True + elif value == 'FALSE': + return False + else: + raise ValueError("Invalid boolean") + + +class ConverterError(Exception): + """ + Exception raised when an error occurs in a converter for string values. + + """ + pass + + +class ConverterLockError(ConverterError): + """ + Exception raised when an attempt is made to upgrade a locked converter. + + """ + pass + + +class ConversionWarning(UserWarning): + """ + Warning issued when a string converter has a problem. + + Notes + ----- + In `genfromtxt` a `ConversionWarning` is issued if raising exceptions + is explicitly suppressed with the "invalid_raise" keyword. + + """ + pass + + +class StringConverter: + """ + Factory class for function transforming a string into another object + (int, float). + + After initialization, an instance can be called to transform a string + into another object. If the string is recognized as representing a + missing value, a default value is returned. + + Attributes + ---------- + func : function + Function used for the conversion. + default : any + Default value to return when the input corresponds to a missing + value. + type : type + Type of the output. + _status : int + Integer representing the order of the conversion. + _mapper : sequence of tuples + Sequence of tuples (dtype, function, default value) to evaluate in + order. + _locked : bool + Holds `locked` parameter. + + Parameters + ---------- + dtype_or_func : {None, dtype, function}, optional + If a `dtype`, specifies the input data type, used to define a basic + function and a default value for missing data. For example, when + `dtype` is float, the `func` attribute is set to `float` and the + default value to `np.nan`. If a function, this function is used to + convert a string to another object. In this case, it is recommended + to give an associated default value as input. + default : any, optional + Value to return by default, that is, when the string to be + converted is flagged as missing. If not given, `StringConverter` + tries to supply a reasonable default value. + missing_values : {None, sequence of str}, optional + ``None`` or sequence of strings indicating a missing value. If ``None`` + then missing values are indicated by empty entries. The default is + ``None``. + locked : bool, optional + Whether the StringConverter should be locked to prevent automatic + upgrade or not. Default is False. + + """ + _mapper = [(nx.bool_, str2bool, False), + (nx.int_, int, -1),] + + # On 32-bit systems, we need to make sure that we explicitly include + # nx.int64 since ns.int_ is nx.int32. + if nx.dtype(nx.int_).itemsize < nx.dtype(nx.int64).itemsize: + _mapper.append((nx.int64, int, -1)) + + _mapper.extend([(nx.float64, float, nx.nan), + (nx.complex128, complex, nx.nan + 0j), + (nx.longdouble, nx.longdouble, nx.nan), + # If a non-default dtype is passed, fall back to generic + # ones (should only be used for the converter) + (nx.integer, int, -1), + (nx.floating, float, nx.nan), + (nx.complexfloating, complex, nx.nan + 0j), + # Last, try with the string types (must be last, because + # `_mapper[-1]` is used as default in some cases) + (nx.unicode_, asunicode, '???'), + (nx.string_, asbytes, '???'), + ]) + + @classmethod + def _getdtype(cls, val): + """Returns the dtype of the input variable.""" + return np.array(val).dtype + + @classmethod + def _getsubdtype(cls, val): + """Returns the type of the dtype of the input variable.""" + return np.array(val).dtype.type + + @classmethod + def _dtypeortype(cls, dtype): + """Returns dtype for datetime64 and type of dtype otherwise.""" + + # This is a bit annoying. We want to return the "general" type in most + # cases (ie. "string" rather than "S10"), but we want to return the + # specific type for datetime64 (ie. "datetime64[us]" rather than + # "datetime64"). + if dtype.type == np.datetime64: + return dtype + return dtype.type + + @classmethod + def upgrade_mapper(cls, func, default=None): + """ + Upgrade the mapper of a StringConverter by adding a new function and + its corresponding default. + + The input function (or sequence of functions) and its associated + default value (if any) is inserted in penultimate position of the + mapper. The corresponding type is estimated from the dtype of the + default value. + + Parameters + ---------- + func : var + Function, or sequence of functions + + Examples + -------- + >>> import dateutil.parser + >>> import datetime + >>> dateparser = dateutil.parser.parse + >>> defaultdate = datetime.date(2000, 1, 1) + >>> StringConverter.upgrade_mapper(dateparser, default=defaultdate) + """ + # Func is a single functions + if hasattr(func, '__call__'): + cls._mapper.insert(-1, (cls._getsubdtype(default), func, default)) + return + elif hasattr(func, '__iter__'): + if isinstance(func[0], (tuple, list)): + for _ in func: + cls._mapper.insert(-1, _) + return + if default is None: + default = [None] * len(func) + else: + default = list(default) + default.append([None] * (len(func) - len(default))) + for fct, dft in zip(func, default): + cls._mapper.insert(-1, (cls._getsubdtype(dft), fct, dft)) + + @classmethod + def _find_map_entry(cls, dtype): + # if a converter for the specific dtype is available use that + for i, (deftype, func, default_def) in enumerate(cls._mapper): + if dtype.type == deftype: + return i, (deftype, func, default_def) + + # otherwise find an inexact match + for i, (deftype, func, default_def) in enumerate(cls._mapper): + if np.issubdtype(dtype.type, deftype): + return i, (deftype, func, default_def) + + raise LookupError + + def __init__(self, dtype_or_func=None, default=None, missing_values=None, + locked=False): + # Defines a lock for upgrade + self._locked = bool(locked) + # No input dtype: minimal initialization + if dtype_or_func is None: + self.func = str2bool + self._status = 0 + self.default = default or False + dtype = np.dtype('bool') + else: + # Is the input a np.dtype ? + try: + self.func = None + dtype = np.dtype(dtype_or_func) + except TypeError: + # dtype_or_func must be a function, then + if not hasattr(dtype_or_func, '__call__'): + errmsg = ("The input argument `dtype` is neither a" + " function nor a dtype (got '%s' instead)") + raise TypeError(errmsg % type(dtype_or_func)) + # Set the function + self.func = dtype_or_func + # If we don't have a default, try to guess it or set it to + # None + if default is None: + try: + default = self.func('0') + except ValueError: + default = None + dtype = self._getdtype(default) + + # find the best match in our mapper + try: + self._status, (_, func, default_def) = self._find_map_entry(dtype) + except LookupError: + # no match + self.default = default + _, func, _ = self._mapper[-1] + self._status = 0 + else: + # use the found default only if we did not already have one + if default is None: + self.default = default_def + else: + self.default = default + + # If the input was a dtype, set the function to the last we saw + if self.func is None: + self.func = func + + # If the status is 1 (int), change the function to + # something more robust. + if self.func == self._mapper[1][1]: + if issubclass(dtype.type, np.uint64): + self.func = np.uint64 + elif issubclass(dtype.type, np.int64): + self.func = np.int64 + else: + self.func = lambda x: int(float(x)) + # Store the list of strings corresponding to missing values. + if missing_values is None: + self.missing_values = {''} + else: + if isinstance(missing_values, str): + missing_values = missing_values.split(",") + self.missing_values = set(list(missing_values) + ['']) + + self._callingfunction = self._strict_call + self.type = self._dtypeortype(dtype) + self._checked = False + self._initial_default = default + + def _loose_call(self, value): + try: + return self.func(value) + except ValueError: + return self.default + + def _strict_call(self, value): + try: + + # We check if we can convert the value using the current function + new_value = self.func(value) + + # In addition to having to check whether func can convert the + # value, we also have to make sure that we don't get overflow + # errors for integers. + if self.func is int: + try: + np.array(value, dtype=self.type) + except OverflowError: + raise ValueError + + # We're still here so we can now return the new value + return new_value + + except ValueError: + if value.strip() in self.missing_values: + if not self._status: + self._checked = False + return self.default + raise ValueError("Cannot convert string '%s'" % value) + + def __call__(self, value): + return self._callingfunction(value) + + def _do_upgrade(self): + # Raise an exception if we locked the converter... + if self._locked: + errmsg = "Converter is locked and cannot be upgraded" + raise ConverterLockError(errmsg) + _statusmax = len(self._mapper) + # Complains if we try to upgrade by the maximum + _status = self._status + if _status == _statusmax: + errmsg = "Could not find a valid conversion function" + raise ConverterError(errmsg) + elif _status < _statusmax - 1: + _status += 1 + self.type, self.func, default = self._mapper[_status] + self._status = _status + if self._initial_default is not None: + self.default = self._initial_default + else: + self.default = default + + def upgrade(self, value): + """ + Find the best converter for a given string, and return the result. + + The supplied string `value` is converted by testing different + converters in order. First the `func` method of the + `StringConverter` instance is tried, if this fails other available + converters are tried. The order in which these other converters + are tried is determined by the `_status` attribute of the instance. + + Parameters + ---------- + value : str + The string to convert. + + Returns + ------- + out : any + The result of converting `value` with the appropriate converter. + + """ + self._checked = True + try: + return self._strict_call(value) + except ValueError: + self._do_upgrade() + return self.upgrade(value) + + def iterupgrade(self, value): + self._checked = True + if not hasattr(value, '__iter__'): + value = (value,) + _strict_call = self._strict_call + try: + for _m in value: + _strict_call(_m) + except ValueError: + self._do_upgrade() + self.iterupgrade(value) + + def update(self, func, default=None, testing_value=None, + missing_values='', locked=False): + """ + Set StringConverter attributes directly. + + Parameters + ---------- + func : function + Conversion function. + default : any, optional + Value to return by default, that is, when the string to be + converted is flagged as missing. If not given, + `StringConverter` tries to supply a reasonable default value. + testing_value : str, optional + A string representing a standard input value of the converter. + This string is used to help defining a reasonable default + value. + missing_values : {sequence of str, None}, optional + Sequence of strings indicating a missing value. If ``None``, then + the existing `missing_values` are cleared. The default is `''`. + locked : bool, optional + Whether the StringConverter should be locked to prevent + automatic upgrade or not. Default is False. + + Notes + ----- + `update` takes the same parameters as the constructor of + `StringConverter`, except that `func` does not accept a `dtype` + whereas `dtype_or_func` in the constructor does. + + """ + self.func = func + self._locked = locked + + # Don't reset the default to None if we can avoid it + if default is not None: + self.default = default + self.type = self._dtypeortype(self._getdtype(default)) + else: + try: + tester = func(testing_value or '1') + except (TypeError, ValueError): + tester = None + self.type = self._dtypeortype(self._getdtype(tester)) + + # Add the missing values to the existing set or clear it. + if missing_values is None: + # Clear all missing values even though the ctor initializes it to + # set(['']) when the argument is None. + self.missing_values = set() + else: + if not np.iterable(missing_values): + missing_values = [missing_values] + if not all(isinstance(v, str) for v in missing_values): + raise TypeError("missing_values must be strings or unicode") + self.missing_values.update(missing_values) + + +def easy_dtype(ndtype, names=None, defaultfmt="f%i", **validationargs): + """ + Convenience function to create a `np.dtype` object. + + The function processes the input `dtype` and matches it with the given + names. + + Parameters + ---------- + ndtype : var + Definition of the dtype. Can be any string or dictionary recognized + by the `np.dtype` function, or a sequence of types. + names : str or sequence, optional + Sequence of strings to use as field names for a structured dtype. + For convenience, `names` can be a string of a comma-separated list + of names. + defaultfmt : str, optional + Format string used to define missing names, such as ``"f%i"`` + (default) or ``"fields_%02i"``. + validationargs : optional + A series of optional arguments used to initialize a + `NameValidator`. + + Examples + -------- + >>> np.lib._iotools.easy_dtype(float) + dtype('float64') + >>> np.lib._iotools.easy_dtype("i4, f8") + dtype([('f0', '>> np.lib._iotools.easy_dtype("i4, f8", defaultfmt="field_%03i") + dtype([('field_000', '>> np.lib._iotools.easy_dtype((int, float, float), names="a,b,c") + dtype([('a', '>> np.lib._iotools.easy_dtype(float, names="a,b,c") + dtype([('a', ' 9) in principle): + + - Released version: '1.8.0', '1.8.1', etc. + - Alpha: '1.8.0a1', '1.8.0a2', etc. + - Beta: '1.8.0b1', '1.8.0b2', etc. + - Release candidates: '1.8.0rc1', '1.8.0rc2', etc. + - Development versions: '1.8.0.dev-f1234afa' (git commit hash appended) + - Development versions after a1: '1.8.0a1.dev-f1234afa', + '1.8.0b2.dev-f1234afa', + '1.8.1rc1.dev-f1234afa', etc. + - Development versions (no git hash available): '1.8.0.dev-Unknown' + + Comparing needs to be done against a valid version string or other + `NumpyVersion` instance. Note that all development versions of the same + (pre-)release compare equal. + + .. versionadded:: 1.9.0 + + Parameters + ---------- + vstring : str + NumPy version string (``np.__version__``). + + Examples + -------- + >>> from numpy.lib import NumpyVersion + >>> if NumpyVersion(np.__version__) < '1.7.0': + ... print('skip') + >>> # skip + + >>> NumpyVersion('1.7') # raises ValueError, add ".0" + Traceback (most recent call last): + ... + ValueError: Not a valid numpy version string + + """ + + def __init__(self, vstring): + self.vstring = vstring + ver_main = re.match(r'\d[.]\d+[.]\d+', vstring) + if not ver_main: + raise ValueError("Not a valid numpy version string") + + self.version = ver_main.group() + self.major, self.minor, self.bugfix = [int(x) for x in + self.version.split('.')] + if len(vstring) == ver_main.end(): + self.pre_release = 'final' + else: + alpha = re.match(r'a\d', vstring[ver_main.end():]) + beta = re.match(r'b\d', vstring[ver_main.end():]) + rc = re.match(r'rc\d', vstring[ver_main.end():]) + pre_rel = [m for m in [alpha, beta, rc] if m is not None] + if pre_rel: + self.pre_release = pre_rel[0].group() + else: + self.pre_release = '' + + self.is_devversion = bool(re.search(r'.dev', vstring)) + + def _compare_version(self, other): + """Compare major.minor.bugfix""" + if self.major == other.major: + if self.minor == other.minor: + if self.bugfix == other.bugfix: + vercmp = 0 + elif self.bugfix > other.bugfix: + vercmp = 1 + else: + vercmp = -1 + elif self.minor > other.minor: + vercmp = 1 + else: + vercmp = -1 + elif self.major > other.major: + vercmp = 1 + else: + vercmp = -1 + + return vercmp + + def _compare_pre_release(self, other): + """Compare alpha/beta/rc/final.""" + if self.pre_release == other.pre_release: + vercmp = 0 + elif self.pre_release == 'final': + vercmp = 1 + elif other.pre_release == 'final': + vercmp = -1 + elif self.pre_release > other.pre_release: + vercmp = 1 + else: + vercmp = -1 + + return vercmp + + def _compare(self, other): + if not isinstance(other, (str, NumpyVersion)): + raise ValueError("Invalid object to compare with NumpyVersion.") + + if isinstance(other, str): + other = NumpyVersion(other) + + vercmp = self._compare_version(other) + if vercmp == 0: + # Same x.y.z version, check for alpha/beta/rc + vercmp = self._compare_pre_release(other) + if vercmp == 0: + # Same version and same pre-release, check if dev version + if self.is_devversion is other.is_devversion: + vercmp = 0 + elif self.is_devversion: + vercmp = -1 + else: + vercmp = 1 + + return vercmp + + def __lt__(self, other): + return self._compare(other) < 0 + + def __le__(self, other): + return self._compare(other) <= 0 + + def __eq__(self, other): + return self._compare(other) == 0 + + def __ne__(self, other): + return self._compare(other) != 0 + + def __gt__(self, other): + return self._compare(other) > 0 + + def __ge__(self, other): + return self._compare(other) >= 0 + + def __repr(self): + return "NumpyVersion(%s)" % self.vstring diff --git a/venv/Lib/site-packages/numpy/lib/arraypad.py b/venv/Lib/site-packages/numpy/lib/arraypad.py new file mode 100644 index 0000000..8830b81 --- /dev/null +++ b/venv/Lib/site-packages/numpy/lib/arraypad.py @@ -0,0 +1,876 @@ +""" +The arraypad module contains a group of functions to pad values onto the edges +of an n-dimensional array. + +""" +import numpy as np +from numpy.core.overrides import array_function_dispatch +from numpy.lib.index_tricks import ndindex + + +__all__ = ['pad'] + + +############################################################################### +# Private utility functions. + + +def _round_if_needed(arr, dtype): + """ + Rounds arr inplace if destination dtype is integer. + + Parameters + ---------- + arr : ndarray + Input array. + dtype : dtype + The dtype of the destination array. + """ + if np.issubdtype(dtype, np.integer): + arr.round(out=arr) + + +def _slice_at_axis(sl, axis): + """ + Construct tuple of slices to slice an array in the given dimension. + + Parameters + ---------- + sl : slice + The slice for the given dimension. + axis : int + The axis to which `sl` is applied. All other dimensions are left + "unsliced". + + Returns + ------- + sl : tuple of slices + A tuple with slices matching `shape` in length. + + Examples + -------- + >>> _slice_at_axis(slice(None, 3, -1), 1) + (slice(None, None, None), slice(None, 3, -1), (...,)) + """ + return (slice(None),) * axis + (sl,) + (...,) + + +def _view_roi(array, original_area_slice, axis): + """ + Get a view of the current region of interest during iterative padding. + + When padding multiple dimensions iteratively corner values are + unnecessarily overwritten multiple times. This function reduces the + working area for the first dimensions so that corners are excluded. + + Parameters + ---------- + array : ndarray + The array with the region of interest. + original_area_slice : tuple of slices + Denotes the area with original values of the unpadded array. + axis : int + The currently padded dimension assuming that `axis` is padded before + `axis` + 1. + + Returns + ------- + roi : ndarray + The region of interest of the original `array`. + """ + axis += 1 + sl = (slice(None),) * axis + original_area_slice[axis:] + return array[sl] + + +def _pad_simple(array, pad_width, fill_value=None): + """ + Pad array on all sides with either a single value or undefined values. + + Parameters + ---------- + array : ndarray + Array to grow. + pad_width : sequence of tuple[int, int] + Pad width on both sides for each dimension in `arr`. + fill_value : scalar, optional + If provided the padded area is filled with this value, otherwise + the pad area left undefined. + + Returns + ------- + padded : ndarray + The padded array with the same dtype as`array`. Its order will default + to C-style if `array` is not F-contiguous. + original_area_slice : tuple + A tuple of slices pointing to the area of the original array. + """ + # Allocate grown array + new_shape = tuple( + left + size + right + for size, (left, right) in zip(array.shape, pad_width) + ) + order = 'F' if array.flags.fnc else 'C' # Fortran and not also C-order + padded = np.empty(new_shape, dtype=array.dtype, order=order) + + if fill_value is not None: + padded.fill(fill_value) + + # Copy old array into correct space + original_area_slice = tuple( + slice(left, left + size) + for size, (left, right) in zip(array.shape, pad_width) + ) + padded[original_area_slice] = array + + return padded, original_area_slice + + +def _set_pad_area(padded, axis, width_pair, value_pair): + """ + Set empty-padded area in given dimension. + + Parameters + ---------- + padded : ndarray + Array with the pad area which is modified inplace. + axis : int + Dimension with the pad area to set. + width_pair : (int, int) + Pair of widths that mark the pad area on both sides in the given + dimension. + value_pair : tuple of scalars or ndarrays + Values inserted into the pad area on each side. It must match or be + broadcastable to the shape of `arr`. + """ + left_slice = _slice_at_axis(slice(None, width_pair[0]), axis) + padded[left_slice] = value_pair[0] + + right_slice = _slice_at_axis( + slice(padded.shape[axis] - width_pair[1], None), axis) + padded[right_slice] = value_pair[1] + + +def _get_edges(padded, axis, width_pair): + """ + Retrieve edge values from empty-padded array in given dimension. + + Parameters + ---------- + padded : ndarray + Empty-padded array. + axis : int + Dimension in which the edges are considered. + width_pair : (int, int) + Pair of widths that mark the pad area on both sides in the given + dimension. + + Returns + ------- + left_edge, right_edge : ndarray + Edge values of the valid area in `padded` in the given dimension. Its + shape will always match `padded` except for the dimension given by + `axis` which will have a length of 1. + """ + left_index = width_pair[0] + left_slice = _slice_at_axis(slice(left_index, left_index + 1), axis) + left_edge = padded[left_slice] + + right_index = padded.shape[axis] - width_pair[1] + right_slice = _slice_at_axis(slice(right_index - 1, right_index), axis) + right_edge = padded[right_slice] + + return left_edge, right_edge + + +def _get_linear_ramps(padded, axis, width_pair, end_value_pair): + """ + Construct linear ramps for empty-padded array in given dimension. + + Parameters + ---------- + padded : ndarray + Empty-padded array. + axis : int + Dimension in which the ramps are constructed. + width_pair : (int, int) + Pair of widths that mark the pad area on both sides in the given + dimension. + end_value_pair : (scalar, scalar) + End values for the linear ramps which form the edge of the fully padded + array. These values are included in the linear ramps. + + Returns + ------- + left_ramp, right_ramp : ndarray + Linear ramps to set on both sides of `padded`. + """ + edge_pair = _get_edges(padded, axis, width_pair) + + left_ramp, right_ramp = ( + np.linspace( + start=end_value, + stop=edge.squeeze(axis), # Dimension is replaced by linspace + num=width, + endpoint=False, + dtype=padded.dtype, + axis=axis + ) + for end_value, edge, width in zip( + end_value_pair, edge_pair, width_pair + ) + ) + + # Reverse linear space in appropriate dimension + right_ramp = right_ramp[_slice_at_axis(slice(None, None, -1), axis)] + + return left_ramp, right_ramp + + +def _get_stats(padded, axis, width_pair, length_pair, stat_func): + """ + Calculate statistic for the empty-padded array in given dimension. + + Parameters + ---------- + padded : ndarray + Empty-padded array. + axis : int + Dimension in which the statistic is calculated. + width_pair : (int, int) + Pair of widths that mark the pad area on both sides in the given + dimension. + length_pair : 2-element sequence of None or int + Gives the number of values in valid area from each side that is + taken into account when calculating the statistic. If None the entire + valid area in `padded` is considered. + stat_func : function + Function to compute statistic. The expected signature is + ``stat_func(x: ndarray, axis: int, keepdims: bool) -> ndarray``. + + Returns + ------- + left_stat, right_stat : ndarray + Calculated statistic for both sides of `padded`. + """ + # Calculate indices of the edges of the area with original values + left_index = width_pair[0] + right_index = padded.shape[axis] - width_pair[1] + # as well as its length + max_length = right_index - left_index + + # Limit stat_lengths to max_length + left_length, right_length = length_pair + if left_length is None or max_length < left_length: + left_length = max_length + if right_length is None or max_length < right_length: + right_length = max_length + + if (left_length == 0 or right_length == 0) \ + and stat_func in {np.amax, np.amin}: + # amax and amin can't operate on an empty array, + # raise a more descriptive warning here instead of the default one + raise ValueError("stat_length of 0 yields no value for padding") + + # Calculate statistic for the left side + left_slice = _slice_at_axis( + slice(left_index, left_index + left_length), axis) + left_chunk = padded[left_slice] + left_stat = stat_func(left_chunk, axis=axis, keepdims=True) + _round_if_needed(left_stat, padded.dtype) + + if left_length == right_length == max_length: + # return early as right_stat must be identical to left_stat + return left_stat, left_stat + + # Calculate statistic for the right side + right_slice = _slice_at_axis( + slice(right_index - right_length, right_index), axis) + right_chunk = padded[right_slice] + right_stat = stat_func(right_chunk, axis=axis, keepdims=True) + _round_if_needed(right_stat, padded.dtype) + + return left_stat, right_stat + + +def _set_reflect_both(padded, axis, width_pair, method, include_edge=False): + """ + Pad `axis` of `arr` with reflection. + + Parameters + ---------- + padded : ndarray + Input array of arbitrary shape. + axis : int + Axis along which to pad `arr`. + width_pair : (int, int) + Pair of widths that mark the pad area on both sides in the given + dimension. + method : str + Controls method of reflection; options are 'even' or 'odd'. + include_edge : bool + If true, edge value is included in reflection, otherwise the edge + value forms the symmetric axis to the reflection. + + Returns + ------- + pad_amt : tuple of ints, length 2 + New index positions of padding to do along the `axis`. If these are + both 0, padding is done in this dimension. + """ + left_pad, right_pad = width_pair + old_length = padded.shape[axis] - right_pad - left_pad + + if include_edge: + # Edge is included, we need to offset the pad amount by 1 + edge_offset = 1 + else: + edge_offset = 0 # Edge is not included, no need to offset pad amount + old_length -= 1 # but must be omitted from the chunk + + if left_pad > 0: + # Pad with reflected values on left side: + # First limit chunk size which can't be larger than pad area + chunk_length = min(old_length, left_pad) + # Slice right to left, stop on or next to edge, start relative to stop + stop = left_pad - edge_offset + start = stop + chunk_length + left_slice = _slice_at_axis(slice(start, stop, -1), axis) + left_chunk = padded[left_slice] + + if method == "odd": + # Negate chunk and align with edge + edge_slice = _slice_at_axis(slice(left_pad, left_pad + 1), axis) + left_chunk = 2 * padded[edge_slice] - left_chunk + + # Insert chunk into padded area + start = left_pad - chunk_length + stop = left_pad + pad_area = _slice_at_axis(slice(start, stop), axis) + padded[pad_area] = left_chunk + # Adjust pointer to left edge for next iteration + left_pad -= chunk_length + + if right_pad > 0: + # Pad with reflected values on right side: + # First limit chunk size which can't be larger than pad area + chunk_length = min(old_length, right_pad) + # Slice right to left, start on or next to edge, stop relative to start + start = -right_pad + edge_offset - 2 + stop = start - chunk_length + right_slice = _slice_at_axis(slice(start, stop, -1), axis) + right_chunk = padded[right_slice] + + if method == "odd": + # Negate chunk and align with edge + edge_slice = _slice_at_axis( + slice(-right_pad - 1, -right_pad), axis) + right_chunk = 2 * padded[edge_slice] - right_chunk + + # Insert chunk into padded area + start = padded.shape[axis] - right_pad + stop = start + chunk_length + pad_area = _slice_at_axis(slice(start, stop), axis) + padded[pad_area] = right_chunk + # Adjust pointer to right edge for next iteration + right_pad -= chunk_length + + return left_pad, right_pad + + +def _set_wrap_both(padded, axis, width_pair): + """ + Pad `axis` of `arr` with wrapped values. + + Parameters + ---------- + padded : ndarray + Input array of arbitrary shape. + axis : int + Axis along which to pad `arr`. + width_pair : (int, int) + Pair of widths that mark the pad area on both sides in the given + dimension. + + Returns + ------- + pad_amt : tuple of ints, length 2 + New index positions of padding to do along the `axis`. If these are + both 0, padding is done in this dimension. + """ + left_pad, right_pad = width_pair + period = padded.shape[axis] - right_pad - left_pad + + # If the current dimension of `arr` doesn't contain enough valid values + # (not part of the undefined pad area) we need to pad multiple times. + # Each time the pad area shrinks on both sides which is communicated with + # these variables. + new_left_pad = 0 + new_right_pad = 0 + + if left_pad > 0: + # Pad with wrapped values on left side + # First slice chunk from right side of the non-pad area. + # Use min(period, left_pad) to ensure that chunk is not larger than + # pad area + right_slice = _slice_at_axis( + slice(-right_pad - min(period, left_pad), + -right_pad if right_pad != 0 else None), + axis + ) + right_chunk = padded[right_slice] + + if left_pad > period: + # Chunk is smaller than pad area + pad_area = _slice_at_axis(slice(left_pad - period, left_pad), axis) + new_left_pad = left_pad - period + else: + # Chunk matches pad area + pad_area = _slice_at_axis(slice(None, left_pad), axis) + padded[pad_area] = right_chunk + + if right_pad > 0: + # Pad with wrapped values on right side + # First slice chunk from left side of the non-pad area. + # Use min(period, right_pad) to ensure that chunk is not larger than + # pad area + left_slice = _slice_at_axis( + slice(left_pad, left_pad + min(period, right_pad),), axis) + left_chunk = padded[left_slice] + + if right_pad > period: + # Chunk is smaller than pad area + pad_area = _slice_at_axis( + slice(-right_pad, -right_pad + period), axis) + new_right_pad = right_pad - period + else: + # Chunk matches pad area + pad_area = _slice_at_axis(slice(-right_pad, None), axis) + padded[pad_area] = left_chunk + + return new_left_pad, new_right_pad + + +def _as_pairs(x, ndim, as_index=False): + """ + Broadcast `x` to an array with the shape (`ndim`, 2). + + A helper function for `pad` that prepares and validates arguments like + `pad_width` for iteration in pairs. + + Parameters + ---------- + x : {None, scalar, array-like} + The object to broadcast to the shape (`ndim`, 2). + ndim : int + Number of pairs the broadcasted `x` will have. + as_index : bool, optional + If `x` is not None, try to round each element of `x` to an integer + (dtype `np.intp`) and ensure every element is positive. + + Returns + ------- + pairs : nested iterables, shape (`ndim`, 2) + The broadcasted version of `x`. + + Raises + ------ + ValueError + If `as_index` is True and `x` contains negative elements. + Or if `x` is not broadcastable to the shape (`ndim`, 2). + """ + if x is None: + # Pass through None as a special case, otherwise np.round(x) fails + # with an AttributeError + return ((None, None),) * ndim + + x = np.array(x) + if as_index: + x = np.round(x).astype(np.intp, copy=False) + + if x.ndim < 3: + # Optimization: Possibly use faster paths for cases where `x` has + # only 1 or 2 elements. `np.broadcast_to` could handle these as well + # but is currently slower + + if x.size == 1: + # x was supplied as a single value + x = x.ravel() # Ensure x[0] works for x.ndim == 0, 1, 2 + if as_index and x < 0: + raise ValueError("index can't contain negative values") + return ((x[0], x[0]),) * ndim + + if x.size == 2 and x.shape != (2, 1): + # x was supplied with a single value for each side + # but except case when each dimension has a single value + # which should be broadcasted to a pair, + # e.g. [[1], [2]] -> [[1, 1], [2, 2]] not [[1, 2], [1, 2]] + x = x.ravel() # Ensure x[0], x[1] works + if as_index and (x[0] < 0 or x[1] < 0): + raise ValueError("index can't contain negative values") + return ((x[0], x[1]),) * ndim + + if as_index and x.min() < 0: + raise ValueError("index can't contain negative values") + + # Converting the array with `tolist` seems to improve performance + # when iterating and indexing the result (see usage in `pad`) + return np.broadcast_to(x, (ndim, 2)).tolist() + + +def _pad_dispatcher(array, pad_width, mode=None, **kwargs): + return (array,) + + +############################################################################### +# Public functions + + +@array_function_dispatch(_pad_dispatcher, module='numpy') +def pad(array, pad_width, mode='constant', **kwargs): + """ + Pad an array. + + Parameters + ---------- + array : array_like of rank N + The array to pad. + pad_width : {sequence, array_like, int} + Number of values padded to the edges of each axis. + ((before_1, after_1), ... (before_N, after_N)) unique pad widths + for each axis. + ((before, after),) yields same before and after pad for each axis. + (pad,) or int is a shortcut for before = after = pad width for all + axes. + mode : str or function, optional + One of the following string values or a user supplied function. + + 'constant' (default) + Pads with a constant value. + 'edge' + Pads with the edge values of array. + 'linear_ramp' + Pads with the linear ramp between end_value and the + array edge value. + 'maximum' + Pads with the maximum value of all or part of the + vector along each axis. + 'mean' + Pads with the mean value of all or part of the + vector along each axis. + 'median' + Pads with the median value of all or part of the + vector along each axis. + 'minimum' + Pads with the minimum value of all or part of the + vector along each axis. + 'reflect' + Pads with the reflection of the vector mirrored on + the first and last values of the vector along each + axis. + 'symmetric' + Pads with the reflection of the vector mirrored + along the edge of the array. + 'wrap' + Pads with the wrap of the vector along the axis. + The first values are used to pad the end and the + end values are used to pad the beginning. + 'empty' + Pads with undefined values. + + .. versionadded:: 1.17 + + + Padding function, see Notes. + stat_length : sequence or int, optional + Used in 'maximum', 'mean', 'median', and 'minimum'. Number of + values at edge of each axis used to calculate the statistic value. + + ((before_1, after_1), ... (before_N, after_N)) unique statistic + lengths for each axis. + + ((before, after),) yields same before and after statistic lengths + for each axis. + + (stat_length,) or int is a shortcut for before = after = statistic + length for all axes. + + Default is ``None``, to use the entire axis. + constant_values : sequence or scalar, optional + Used in 'constant'. The values to set the padded values for each + axis. + + ``((before_1, after_1), ... (before_N, after_N))`` unique pad constants + for each axis. + + ``((before, after),)`` yields same before and after constants for each + axis. + + ``(constant,)`` or ``constant`` is a shortcut for ``before = after = constant`` for + all axes. + + Default is 0. + end_values : sequence or scalar, optional + Used in 'linear_ramp'. The values used for the ending value of the + linear_ramp and that will form the edge of the padded array. + + ``((before_1, after_1), ... (before_N, after_N))`` unique end values + for each axis. + + ``((before, after),)`` yields same before and after end values for each + axis. + + ``(constant,)`` or ``constant`` is a shortcut for ``before = after = constant`` for + all axes. + + Default is 0. + reflect_type : {'even', 'odd'}, optional + Used in 'reflect', and 'symmetric'. The 'even' style is the + default with an unaltered reflection around the edge value. For + the 'odd' style, the extended part of the array is created by + subtracting the reflected values from two times the edge value. + + Returns + ------- + pad : ndarray + Padded array of rank equal to `array` with shape increased + according to `pad_width`. + + Notes + ----- + .. versionadded:: 1.7.0 + + For an array with rank greater than 1, some of the padding of later + axes is calculated from padding of previous axes. This is easiest to + think about with a rank 2 array where the corners of the padded array + are calculated by using padded values from the first axis. + + The padding function, if used, should modify a rank 1 array in-place. It + has the following signature:: + + padding_func(vector, iaxis_pad_width, iaxis, kwargs) + + where + + vector : ndarray + A rank 1 array already padded with zeros. Padded values are + vector[:iaxis_pad_width[0]] and vector[-iaxis_pad_width[1]:]. + iaxis_pad_width : tuple + A 2-tuple of ints, iaxis_pad_width[0] represents the number of + values padded at the beginning of vector where + iaxis_pad_width[1] represents the number of values padded at + the end of vector. + iaxis : int + The axis currently being calculated. + kwargs : dict + Any keyword arguments the function requires. + + Examples + -------- + >>> a = [1, 2, 3, 4, 5] + >>> np.pad(a, (2, 3), 'constant', constant_values=(4, 6)) + array([4, 4, 1, ..., 6, 6, 6]) + + >>> np.pad(a, (2, 3), 'edge') + array([1, 1, 1, ..., 5, 5, 5]) + + >>> np.pad(a, (2, 3), 'linear_ramp', end_values=(5, -4)) + array([ 5, 3, 1, 2, 3, 4, 5, 2, -1, -4]) + + >>> np.pad(a, (2,), 'maximum') + array([5, 5, 1, 2, 3, 4, 5, 5, 5]) + + >>> np.pad(a, (2,), 'mean') + array([3, 3, 1, 2, 3, 4, 5, 3, 3]) + + >>> np.pad(a, (2,), 'median') + array([3, 3, 1, 2, 3, 4, 5, 3, 3]) + + >>> a = [[1, 2], [3, 4]] + >>> np.pad(a, ((3, 2), (2, 3)), 'minimum') + array([[1, 1, 1, 2, 1, 1, 1], + [1, 1, 1, 2, 1, 1, 1], + [1, 1, 1, 2, 1, 1, 1], + [1, 1, 1, 2, 1, 1, 1], + [3, 3, 3, 4, 3, 3, 3], + [1, 1, 1, 2, 1, 1, 1], + [1, 1, 1, 2, 1, 1, 1]]) + + >>> a = [1, 2, 3, 4, 5] + >>> np.pad(a, (2, 3), 'reflect') + array([3, 2, 1, 2, 3, 4, 5, 4, 3, 2]) + + >>> np.pad(a, (2, 3), 'reflect', reflect_type='odd') + array([-1, 0, 1, 2, 3, 4, 5, 6, 7, 8]) + + >>> np.pad(a, (2, 3), 'symmetric') + array([2, 1, 1, 2, 3, 4, 5, 5, 4, 3]) + + >>> np.pad(a, (2, 3), 'symmetric', reflect_type='odd') + array([0, 1, 1, 2, 3, 4, 5, 5, 6, 7]) + + >>> np.pad(a, (2, 3), 'wrap') + array([4, 5, 1, 2, 3, 4, 5, 1, 2, 3]) + + >>> def pad_with(vector, pad_width, iaxis, kwargs): + ... pad_value = kwargs.get('padder', 10) + ... vector[:pad_width[0]] = pad_value + ... vector[-pad_width[1]:] = pad_value + >>> a = np.arange(6) + >>> a = a.reshape((2, 3)) + >>> np.pad(a, 2, pad_with) + array([[10, 10, 10, 10, 10, 10, 10], + [10, 10, 10, 10, 10, 10, 10], + [10, 10, 0, 1, 2, 10, 10], + [10, 10, 3, 4, 5, 10, 10], + [10, 10, 10, 10, 10, 10, 10], + [10, 10, 10, 10, 10, 10, 10]]) + >>> np.pad(a, 2, pad_with, padder=100) + array([[100, 100, 100, 100, 100, 100, 100], + [100, 100, 100, 100, 100, 100, 100], + [100, 100, 0, 1, 2, 100, 100], + [100, 100, 3, 4, 5, 100, 100], + [100, 100, 100, 100, 100, 100, 100], + [100, 100, 100, 100, 100, 100, 100]]) + """ + array = np.asarray(array) + pad_width = np.asarray(pad_width) + + if not pad_width.dtype.kind == 'i': + raise TypeError('`pad_width` must be of integral type.') + + # Broadcast to shape (array.ndim, 2) + pad_width = _as_pairs(pad_width, array.ndim, as_index=True) + + if callable(mode): + # Old behavior: Use user-supplied function with np.apply_along_axis + function = mode + # Create a new zero padded array + padded, _ = _pad_simple(array, pad_width, fill_value=0) + # And apply along each axis + + for axis in range(padded.ndim): + # Iterate using ndindex as in apply_along_axis, but assuming that + # function operates inplace on the padded array. + + # view with the iteration axis at the end + view = np.moveaxis(padded, axis, -1) + + # compute indices for the iteration axes, and append a trailing + # ellipsis to prevent 0d arrays decaying to scalars (gh-8642) + inds = ndindex(view.shape[:-1]) + inds = (ind + (Ellipsis,) for ind in inds) + for ind in inds: + function(view[ind], pad_width[axis], axis, kwargs) + + return padded + + # Make sure that no unsupported keywords were passed for the current mode + allowed_kwargs = { + 'empty': [], 'edge': [], 'wrap': [], + 'constant': ['constant_values'], + 'linear_ramp': ['end_values'], + 'maximum': ['stat_length'], + 'mean': ['stat_length'], + 'median': ['stat_length'], + 'minimum': ['stat_length'], + 'reflect': ['reflect_type'], + 'symmetric': ['reflect_type'], + } + try: + unsupported_kwargs = set(kwargs) - set(allowed_kwargs[mode]) + except KeyError: + raise ValueError("mode '{}' is not supported".format(mode)) from None + if unsupported_kwargs: + raise ValueError("unsupported keyword arguments for mode '{}': {}" + .format(mode, unsupported_kwargs)) + + stat_functions = {"maximum": np.amax, "minimum": np.amin, + "mean": np.mean, "median": np.median} + + # Create array with final shape and original values + # (padded area is undefined) + padded, original_area_slice = _pad_simple(array, pad_width) + # And prepare iteration over all dimensions + # (zipping may be more readable than using enumerate) + axes = range(padded.ndim) + + if mode == "constant": + values = kwargs.get("constant_values", 0) + values = _as_pairs(values, padded.ndim) + for axis, width_pair, value_pair in zip(axes, pad_width, values): + roi = _view_roi(padded, original_area_slice, axis) + _set_pad_area(roi, axis, width_pair, value_pair) + + elif mode == "empty": + pass # Do nothing as _pad_simple already returned the correct result + + elif array.size == 0: + # Only modes "constant" and "empty" can extend empty axes, all other + # modes depend on `array` not being empty + # -> ensure every empty axis is only "padded with 0" + for axis, width_pair in zip(axes, pad_width): + if array.shape[axis] == 0 and any(width_pair): + raise ValueError( + "can't extend empty axis {} using modes other than " + "'constant' or 'empty'".format(axis) + ) + # passed, don't need to do anything more as _pad_simple already + # returned the correct result + + elif mode == "edge": + for axis, width_pair in zip(axes, pad_width): + roi = _view_roi(padded, original_area_slice, axis) + edge_pair = _get_edges(roi, axis, width_pair) + _set_pad_area(roi, axis, width_pair, edge_pair) + + elif mode == "linear_ramp": + end_values = kwargs.get("end_values", 0) + end_values = _as_pairs(end_values, padded.ndim) + for axis, width_pair, value_pair in zip(axes, pad_width, end_values): + roi = _view_roi(padded, original_area_slice, axis) + ramp_pair = _get_linear_ramps(roi, axis, width_pair, value_pair) + _set_pad_area(roi, axis, width_pair, ramp_pair) + + elif mode in stat_functions: + func = stat_functions[mode] + length = kwargs.get("stat_length", None) + length = _as_pairs(length, padded.ndim, as_index=True) + for axis, width_pair, length_pair in zip(axes, pad_width, length): + roi = _view_roi(padded, original_area_slice, axis) + stat_pair = _get_stats(roi, axis, width_pair, length_pair, func) + _set_pad_area(roi, axis, width_pair, stat_pair) + + elif mode in {"reflect", "symmetric"}: + method = kwargs.get("reflect_type", "even") + include_edge = True if mode == "symmetric" else False + for axis, (left_index, right_index) in zip(axes, pad_width): + if array.shape[axis] == 1 and (left_index > 0 or right_index > 0): + # Extending singleton dimension for 'reflect' is legacy + # behavior; it really should raise an error. + edge_pair = _get_edges(padded, axis, (left_index, right_index)) + _set_pad_area( + padded, axis, (left_index, right_index), edge_pair) + continue + + roi = _view_roi(padded, original_area_slice, axis) + while left_index > 0 or right_index > 0: + # Iteratively pad until dimension is filled with reflected + # values. This is necessary if the pad area is larger than + # the length of the original values in the current dimension. + left_index, right_index = _set_reflect_both( + roi, axis, (left_index, right_index), + method, include_edge + ) + + elif mode == "wrap": + for axis, (left_index, right_index) in zip(axes, pad_width): + roi = _view_roi(padded, original_area_slice, axis) + while left_index > 0 or right_index > 0: + # Iteratively pad until dimension is filled with wrapped + # values. This is necessary if the pad area is larger than + # the length of the original values in the current dimension. + left_index, right_index = _set_wrap_both( + roi, axis, (left_index, right_index)) + + return padded diff --git a/venv/Lib/site-packages/numpy/lib/arraysetops.py b/venv/Lib/site-packages/numpy/lib/arraysetops.py new file mode 100644 index 0000000..6c6c1ff --- /dev/null +++ b/venv/Lib/site-packages/numpy/lib/arraysetops.py @@ -0,0 +1,801 @@ +""" +Set operations for arrays based on sorting. + +Notes +----- + +For floating point arrays, inaccurate results may appear due to usual round-off +and floating point comparison issues. + +Speed could be gained in some operations by an implementation of +`numpy.sort`, that can provide directly the permutation vectors, thus avoiding +calls to `numpy.argsort`. + +Original author: Robert Cimrman + +""" +import functools + +import numpy as np +from numpy.core import overrides + + +array_function_dispatch = functools.partial( + overrides.array_function_dispatch, module='numpy') + + +__all__ = [ + 'ediff1d', 'intersect1d', 'setxor1d', 'union1d', 'setdiff1d', 'unique', + 'in1d', 'isin' + ] + + +def _ediff1d_dispatcher(ary, to_end=None, to_begin=None): + return (ary, to_end, to_begin) + + +@array_function_dispatch(_ediff1d_dispatcher) +def ediff1d(ary, to_end=None, to_begin=None): + """ + The differences between consecutive elements of an array. + + Parameters + ---------- + ary : array_like + If necessary, will be flattened before the differences are taken. + to_end : array_like, optional + Number(s) to append at the end of the returned differences. + to_begin : array_like, optional + Number(s) to prepend at the beginning of the returned differences. + + Returns + ------- + ediff1d : ndarray + The differences. Loosely, this is ``ary.flat[1:] - ary.flat[:-1]``. + + See Also + -------- + diff, gradient + + Notes + ----- + When applied to masked arrays, this function drops the mask information + if the `to_begin` and/or `to_end` parameters are used. + + Examples + -------- + >>> x = np.array([1, 2, 4, 7, 0]) + >>> np.ediff1d(x) + array([ 1, 2, 3, -7]) + + >>> np.ediff1d(x, to_begin=-99, to_end=np.array([88, 99])) + array([-99, 1, 2, ..., -7, 88, 99]) + + The returned array is always 1D. + + >>> y = [[1, 2, 4], [1, 6, 24]] + >>> np.ediff1d(y) + array([ 1, 2, -3, 5, 18]) + + """ + # force a 1d array + ary = np.asanyarray(ary).ravel() + + # enforce that the dtype of `ary` is used for the output + dtype_req = ary.dtype + + # fast track default case + if to_begin is None and to_end is None: + return ary[1:] - ary[:-1] + + if to_begin is None: + l_begin = 0 + else: + to_begin = np.asanyarray(to_begin) + if not np.can_cast(to_begin, dtype_req, casting="same_kind"): + raise TypeError("dtype of `to_begin` must be compatible " + "with input `ary` under the `same_kind` rule.") + + to_begin = to_begin.ravel() + l_begin = len(to_begin) + + if to_end is None: + l_end = 0 + else: + to_end = np.asanyarray(to_end) + if not np.can_cast(to_end, dtype_req, casting="same_kind"): + raise TypeError("dtype of `to_end` must be compatible " + "with input `ary` under the `same_kind` rule.") + + to_end = to_end.ravel() + l_end = len(to_end) + + # do the calculation in place and copy to_begin and to_end + l_diff = max(len(ary) - 1, 0) + result = np.empty(l_diff + l_begin + l_end, dtype=ary.dtype) + result = ary.__array_wrap__(result) + if l_begin > 0: + result[:l_begin] = to_begin + if l_end > 0: + result[l_begin + l_diff:] = to_end + np.subtract(ary[1:], ary[:-1], result[l_begin:l_begin + l_diff]) + return result + + +def _unpack_tuple(x): + """ Unpacks one-element tuples for use as return values """ + if len(x) == 1: + return x[0] + else: + return x + + +def _unique_dispatcher(ar, return_index=None, return_inverse=None, + return_counts=None, axis=None): + return (ar,) + + +@array_function_dispatch(_unique_dispatcher) +def unique(ar, return_index=False, return_inverse=False, + return_counts=False, axis=None): + """ + Find the unique elements of an array. + + Returns the sorted unique elements of an array. There are three optional + outputs in addition to the unique elements: + + * the indices of the input array that give the unique values + * the indices of the unique array that reconstruct the input array + * the number of times each unique value comes up in the input array + + Parameters + ---------- + ar : array_like + Input array. Unless `axis` is specified, this will be flattened if it + is not already 1-D. + return_index : bool, optional + If True, also return the indices of `ar` (along the specified axis, + if provided, or in the flattened array) that result in the unique array. + return_inverse : bool, optional + If True, also return the indices of the unique array (for the specified + axis, if provided) that can be used to reconstruct `ar`. + return_counts : bool, optional + If True, also return the number of times each unique item appears + in `ar`. + + .. versionadded:: 1.9.0 + + axis : int or None, optional + The axis to operate on. If None, `ar` will be flattened. If an integer, + the subarrays indexed by the given axis will be flattened and treated + as the elements of a 1-D array with the dimension of the given axis, + see the notes for more details. Object arrays or structured arrays + that contain objects are not supported if the `axis` kwarg is used. The + default is None. + + .. versionadded:: 1.13.0 + + Returns + ------- + unique : ndarray + The sorted unique values. + unique_indices : ndarray, optional + The indices of the first occurrences of the unique values in the + original array. Only provided if `return_index` is True. + unique_inverse : ndarray, optional + The indices to reconstruct the original array from the + unique array. Only provided if `return_inverse` is True. + unique_counts : ndarray, optional + The number of times each of the unique values comes up in the + original array. Only provided if `return_counts` is True. + + .. versionadded:: 1.9.0 + + See Also + -------- + numpy.lib.arraysetops : Module with a number of other functions for + performing set operations on arrays. + repeat : Repeat elements of an array. + + Notes + ----- + When an axis is specified the subarrays indexed by the axis are sorted. + This is done by making the specified axis the first dimension of the array + (move the axis to the first dimension to keep the order of the other axes) + and then flattening the subarrays in C order. The flattened subarrays are + then viewed as a structured type with each element given a label, with the + effect that we end up with a 1-D array of structured types that can be + treated in the same way as any other 1-D array. The result is that the + flattened subarrays are sorted in lexicographic order starting with the + first element. + + Examples + -------- + >>> np.unique([1, 1, 2, 2, 3, 3]) + array([1, 2, 3]) + >>> a = np.array([[1, 1], [2, 3]]) + >>> np.unique(a) + array([1, 2, 3]) + + Return the unique rows of a 2D array + + >>> a = np.array([[1, 0, 0], [1, 0, 0], [2, 3, 4]]) + >>> np.unique(a, axis=0) + array([[1, 0, 0], [2, 3, 4]]) + + Return the indices of the original array that give the unique values: + + >>> a = np.array(['a', 'b', 'b', 'c', 'a']) + >>> u, indices = np.unique(a, return_index=True) + >>> u + array(['a', 'b', 'c'], dtype='>> indices + array([0, 1, 3]) + >>> a[indices] + array(['a', 'b', 'c'], dtype='>> a = np.array([1, 2, 6, 4, 2, 3, 2]) + >>> u, indices = np.unique(a, return_inverse=True) + >>> u + array([1, 2, 3, 4, 6]) + >>> indices + array([0, 1, 4, 3, 1, 2, 1]) + >>> u[indices] + array([1, 2, 6, 4, 2, 3, 2]) + + Reconstruct the input values from the unique values and counts: + + >>> a = np.array([1, 2, 6, 4, 2, 3, 2]) + >>> values, counts = np.unique(a, return_counts=True) + >>> values + array([1, 2, 3, 4, 6]) + >>> counts + array([1, 3, 1, 1, 1]) + >>> np.repeat(values, counts) + array([1, 2, 2, 2, 3, 4, 6]) # original order not preserved + + """ + ar = np.asanyarray(ar) + if axis is None: + ret = _unique1d(ar, return_index, return_inverse, return_counts) + return _unpack_tuple(ret) + + # axis was specified and not None + try: + ar = np.moveaxis(ar, axis, 0) + except np.AxisError: + # this removes the "axis1" or "axis2" prefix from the error message + raise np.AxisError(axis, ar.ndim) from None + + # Must reshape to a contiguous 2D array for this to work... + orig_shape, orig_dtype = ar.shape, ar.dtype + ar = ar.reshape(orig_shape[0], np.prod(orig_shape[1:], dtype=np.intp)) + ar = np.ascontiguousarray(ar) + dtype = [('f{i}'.format(i=i), ar.dtype) for i in range(ar.shape[1])] + + # At this point, `ar` has shape `(n, m)`, and `dtype` is a structured + # data type with `m` fields where each field has the data type of `ar`. + # In the following, we create the array `consolidated`, which has + # shape `(n,)` with data type `dtype`. + try: + if ar.shape[1] > 0: + consolidated = ar.view(dtype) + else: + # If ar.shape[1] == 0, then dtype will be `np.dtype([])`, which is + # a data type with itemsize 0, and the call `ar.view(dtype)` will + # fail. Instead, we'll use `np.empty` to explicitly create the + # array with shape `(len(ar),)`. Because `dtype` in this case has + # itemsize 0, the total size of the result is still 0 bytes. + consolidated = np.empty(len(ar), dtype=dtype) + except TypeError as e: + # There's no good way to do this for object arrays, etc... + msg = 'The axis argument to unique is not supported for dtype {dt}' + raise TypeError(msg.format(dt=ar.dtype)) from e + + def reshape_uniq(uniq): + n = len(uniq) + uniq = uniq.view(orig_dtype) + uniq = uniq.reshape(n, *orig_shape[1:]) + uniq = np.moveaxis(uniq, 0, axis) + return uniq + + output = _unique1d(consolidated, return_index, + return_inverse, return_counts) + output = (reshape_uniq(output[0]),) + output[1:] + return _unpack_tuple(output) + + +def _unique1d(ar, return_index=False, return_inverse=False, + return_counts=False): + """ + Find the unique elements of an array, ignoring shape. + """ + ar = np.asanyarray(ar).flatten() + + optional_indices = return_index or return_inverse + + if optional_indices: + perm = ar.argsort(kind='mergesort' if return_index else 'quicksort') + aux = ar[perm] + else: + ar.sort() + aux = ar + mask = np.empty(aux.shape, dtype=np.bool_) + mask[:1] = True + mask[1:] = aux[1:] != aux[:-1] + + ret = (aux[mask],) + if return_index: + ret += (perm[mask],) + if return_inverse: + imask = np.cumsum(mask) - 1 + inv_idx = np.empty(mask.shape, dtype=np.intp) + inv_idx[perm] = imask + ret += (inv_idx,) + if return_counts: + idx = np.concatenate(np.nonzero(mask) + ([mask.size],)) + ret += (np.diff(idx),) + return ret + + +def _intersect1d_dispatcher( + ar1, ar2, assume_unique=None, return_indices=None): + return (ar1, ar2) + + +@array_function_dispatch(_intersect1d_dispatcher) +def intersect1d(ar1, ar2, assume_unique=False, return_indices=False): + """ + Find the intersection of two arrays. + + Return the sorted, unique values that are in both of the input arrays. + + Parameters + ---------- + ar1, ar2 : array_like + Input arrays. Will be flattened if not already 1D. + assume_unique : bool + If True, the input arrays are both assumed to be unique, which + can speed up the calculation. If True but ``ar1`` or ``ar2`` are not + unique, incorrect results and out-of-bounds indices could result. + Default is False. + return_indices : bool + If True, the indices which correspond to the intersection of the two + arrays are returned. The first instance of a value is used if there are + multiple. Default is False. + + .. versionadded:: 1.15.0 + + Returns + ------- + intersect1d : ndarray + Sorted 1D array of common and unique elements. + comm1 : ndarray + The indices of the first occurrences of the common values in `ar1`. + Only provided if `return_indices` is True. + comm2 : ndarray + The indices of the first occurrences of the common values in `ar2`. + Only provided if `return_indices` is True. + + + See Also + -------- + numpy.lib.arraysetops : Module with a number of other functions for + performing set operations on arrays. + + Examples + -------- + >>> np.intersect1d([1, 3, 4, 3], [3, 1, 2, 1]) + array([1, 3]) + + To intersect more than two arrays, use functools.reduce: + + >>> from functools import reduce + >>> reduce(np.intersect1d, ([1, 3, 4, 3], [3, 1, 2, 1], [6, 3, 4, 2])) + array([3]) + + To return the indices of the values common to the input arrays + along with the intersected values: + + >>> x = np.array([1, 1, 2, 3, 4]) + >>> y = np.array([2, 1, 4, 6]) + >>> xy, x_ind, y_ind = np.intersect1d(x, y, return_indices=True) + >>> x_ind, y_ind + (array([0, 2, 4]), array([1, 0, 2])) + >>> xy, x[x_ind], y[y_ind] + (array([1, 2, 4]), array([1, 2, 4]), array([1, 2, 4])) + + """ + ar1 = np.asanyarray(ar1) + ar2 = np.asanyarray(ar2) + + if not assume_unique: + if return_indices: + ar1, ind1 = unique(ar1, return_index=True) + ar2, ind2 = unique(ar2, return_index=True) + else: + ar1 = unique(ar1) + ar2 = unique(ar2) + else: + ar1 = ar1.ravel() + ar2 = ar2.ravel() + + aux = np.concatenate((ar1, ar2)) + if return_indices: + aux_sort_indices = np.argsort(aux, kind='mergesort') + aux = aux[aux_sort_indices] + else: + aux.sort() + + mask = aux[1:] == aux[:-1] + int1d = aux[:-1][mask] + + if return_indices: + ar1_indices = aux_sort_indices[:-1][mask] + ar2_indices = aux_sort_indices[1:][mask] - ar1.size + if not assume_unique: + ar1_indices = ind1[ar1_indices] + ar2_indices = ind2[ar2_indices] + + return int1d, ar1_indices, ar2_indices + else: + return int1d + + +def _setxor1d_dispatcher(ar1, ar2, assume_unique=None): + return (ar1, ar2) + + +@array_function_dispatch(_setxor1d_dispatcher) +def setxor1d(ar1, ar2, assume_unique=False): + """ + Find the set exclusive-or of two arrays. + + Return the sorted, unique values that are in only one (not both) of the + input arrays. + + Parameters + ---------- + ar1, ar2 : array_like + Input arrays. + assume_unique : bool + If True, the input arrays are both assumed to be unique, which + can speed up the calculation. Default is False. + + Returns + ------- + setxor1d : ndarray + Sorted 1D array of unique values that are in only one of the input + arrays. + + Examples + -------- + >>> a = np.array([1, 2, 3, 2, 4]) + >>> b = np.array([2, 3, 5, 7, 5]) + >>> np.setxor1d(a,b) + array([1, 4, 5, 7]) + + """ + if not assume_unique: + ar1 = unique(ar1) + ar2 = unique(ar2) + + aux = np.concatenate((ar1, ar2)) + if aux.size == 0: + return aux + + aux.sort() + flag = np.concatenate(([True], aux[1:] != aux[:-1], [True])) + return aux[flag[1:] & flag[:-1]] + + +def _in1d_dispatcher(ar1, ar2, assume_unique=None, invert=None): + return (ar1, ar2) + + +@array_function_dispatch(_in1d_dispatcher) +def in1d(ar1, ar2, assume_unique=False, invert=False): + """ + Test whether each element of a 1-D array is also present in a second array. + + Returns a boolean array the same length as `ar1` that is True + where an element of `ar1` is in `ar2` and False otherwise. + + We recommend using :func:`isin` instead of `in1d` for new code. + + Parameters + ---------- + ar1 : (M,) array_like + Input array. + ar2 : array_like + The values against which to test each value of `ar1`. + assume_unique : bool, optional + If True, the input arrays are both assumed to be unique, which + can speed up the calculation. Default is False. + invert : bool, optional + If True, the values in the returned array are inverted (that is, + False where an element of `ar1` is in `ar2` and True otherwise). + Default is False. ``np.in1d(a, b, invert=True)`` is equivalent + to (but is faster than) ``np.invert(in1d(a, b))``. + + .. versionadded:: 1.8.0 + + Returns + ------- + in1d : (M,) ndarray, bool + The values `ar1[in1d]` are in `ar2`. + + See Also + -------- + isin : Version of this function that preserves the + shape of ar1. + numpy.lib.arraysetops : Module with a number of other functions for + performing set operations on arrays. + + Notes + ----- + `in1d` can be considered as an element-wise function version of the + python keyword `in`, for 1-D sequences. ``in1d(a, b)`` is roughly + equivalent to ``np.array([item in b for item in a])``. + However, this idea fails if `ar2` is a set, or similar (non-sequence) + container: As ``ar2`` is converted to an array, in those cases + ``asarray(ar2)`` is an object array rather than the expected array of + contained values. + + .. versionadded:: 1.4.0 + + Examples + -------- + >>> test = np.array([0, 1, 2, 5, 0]) + >>> states = [0, 2] + >>> mask = np.in1d(test, states) + >>> mask + array([ True, False, True, False, True]) + >>> test[mask] + array([0, 2, 0]) + >>> mask = np.in1d(test, states, invert=True) + >>> mask + array([False, True, False, True, False]) + >>> test[mask] + array([1, 5]) + """ + # Ravel both arrays, behavior for the first array could be different + ar1 = np.asarray(ar1).ravel() + ar2 = np.asarray(ar2).ravel() + + # Check if one of the arrays may contain arbitrary objects + contains_object = ar1.dtype.hasobject or ar2.dtype.hasobject + + # This code is run when + # a) the first condition is true, making the code significantly faster + # b) the second condition is true (i.e. `ar1` or `ar2` may contain + # arbitrary objects), since then sorting is not guaranteed to work + if len(ar2) < 10 * len(ar1) ** 0.145 or contains_object: + if invert: + mask = np.ones(len(ar1), dtype=bool) + for a in ar2: + mask &= (ar1 != a) + else: + mask = np.zeros(len(ar1), dtype=bool) + for a in ar2: + mask |= (ar1 == a) + return mask + + # Otherwise use sorting + if not assume_unique: + ar1, rev_idx = np.unique(ar1, return_inverse=True) + ar2 = np.unique(ar2) + + ar = np.concatenate((ar1, ar2)) + # We need this to be a stable sort, so always use 'mergesort' + # here. The values from the first array should always come before + # the values from the second array. + order = ar.argsort(kind='mergesort') + sar = ar[order] + if invert: + bool_ar = (sar[1:] != sar[:-1]) + else: + bool_ar = (sar[1:] == sar[:-1]) + flag = np.concatenate((bool_ar, [invert])) + ret = np.empty(ar.shape, dtype=bool) + ret[order] = flag + + if assume_unique: + return ret[:len(ar1)] + else: + return ret[rev_idx] + + +def _isin_dispatcher(element, test_elements, assume_unique=None, invert=None): + return (element, test_elements) + + +@array_function_dispatch(_isin_dispatcher) +def isin(element, test_elements, assume_unique=False, invert=False): + """ + Calculates `element in test_elements`, broadcasting over `element` only. + Returns a boolean array of the same shape as `element` that is True + where an element of `element` is in `test_elements` and False otherwise. + + Parameters + ---------- + element : array_like + Input array. + test_elements : array_like + The values against which to test each value of `element`. + This argument is flattened if it is an array or array_like. + See notes for behavior with non-array-like parameters. + assume_unique : bool, optional + If True, the input arrays are both assumed to be unique, which + can speed up the calculation. Default is False. + invert : bool, optional + If True, the values in the returned array are inverted, as if + calculating `element not in test_elements`. Default is False. + ``np.isin(a, b, invert=True)`` is equivalent to (but faster + than) ``np.invert(np.isin(a, b))``. + + Returns + ------- + isin : ndarray, bool + Has the same shape as `element`. The values `element[isin]` + are in `test_elements`. + + See Also + -------- + in1d : Flattened version of this function. + numpy.lib.arraysetops : Module with a number of other functions for + performing set operations on arrays. + + Notes + ----- + + `isin` is an element-wise function version of the python keyword `in`. + ``isin(a, b)`` is roughly equivalent to + ``np.array([item in b for item in a])`` if `a` and `b` are 1-D sequences. + + `element` and `test_elements` are converted to arrays if they are not + already. If `test_elements` is a set (or other non-sequence collection) + it will be converted to an object array with one element, rather than an + array of the values contained in `test_elements`. This is a consequence + of the `array` constructor's way of handling non-sequence collections. + Converting the set to a list usually gives the desired behavior. + + .. versionadded:: 1.13.0 + + Examples + -------- + >>> element = 2*np.arange(4).reshape((2, 2)) + >>> element + array([[0, 2], + [4, 6]]) + >>> test_elements = [1, 2, 4, 8] + >>> mask = np.isin(element, test_elements) + >>> mask + array([[False, True], + [ True, False]]) + >>> element[mask] + array([2, 4]) + + The indices of the matched values can be obtained with `nonzero`: + + >>> np.nonzero(mask) + (array([0, 1]), array([1, 0])) + + The test can also be inverted: + + >>> mask = np.isin(element, test_elements, invert=True) + >>> mask + array([[ True, False], + [False, True]]) + >>> element[mask] + array([0, 6]) + + Because of how `array` handles sets, the following does not + work as expected: + + >>> test_set = {1, 2, 4, 8} + >>> np.isin(element, test_set) + array([[False, False], + [False, False]]) + + Casting the set to a list gives the expected result: + + >>> np.isin(element, list(test_set)) + array([[False, True], + [ True, False]]) + """ + element = np.asarray(element) + return in1d(element, test_elements, assume_unique=assume_unique, + invert=invert).reshape(element.shape) + + +def _union1d_dispatcher(ar1, ar2): + return (ar1, ar2) + + +@array_function_dispatch(_union1d_dispatcher) +def union1d(ar1, ar2): + """ + Find the union of two arrays. + + Return the unique, sorted array of values that are in either of the two + input arrays. + + Parameters + ---------- + ar1, ar2 : array_like + Input arrays. They are flattened if they are not already 1D. + + Returns + ------- + union1d : ndarray + Unique, sorted union of the input arrays. + + See Also + -------- + numpy.lib.arraysetops : Module with a number of other functions for + performing set operations on arrays. + + Examples + -------- + >>> np.union1d([-1, 0, 1], [-2, 0, 2]) + array([-2, -1, 0, 1, 2]) + + To find the union of more than two arrays, use functools.reduce: + + >>> from functools import reduce + >>> reduce(np.union1d, ([1, 3, 4, 3], [3, 1, 2, 1], [6, 3, 4, 2])) + array([1, 2, 3, 4, 6]) + """ + return unique(np.concatenate((ar1, ar2), axis=None)) + + +def _setdiff1d_dispatcher(ar1, ar2, assume_unique=None): + return (ar1, ar2) + + +@array_function_dispatch(_setdiff1d_dispatcher) +def setdiff1d(ar1, ar2, assume_unique=False): + """ + Find the set difference of two arrays. + + Return the unique values in `ar1` that are not in `ar2`. + + Parameters + ---------- + ar1 : array_like + Input array. + ar2 : array_like + Input comparison array. + assume_unique : bool + If True, the input arrays are both assumed to be unique, which + can speed up the calculation. Default is False. + + Returns + ------- + setdiff1d : ndarray + 1D array of values in `ar1` that are not in `ar2`. The result + is sorted when `assume_unique=False`, but otherwise only sorted + if the input is sorted. + + See Also + -------- + numpy.lib.arraysetops : Module with a number of other functions for + performing set operations on arrays. + + Examples + -------- + >>> a = np.array([1, 2, 3, 2, 4, 1]) + >>> b = np.array([3, 4, 5, 6]) + >>> np.setdiff1d(a, b) + array([1, 2]) + + """ + if assume_unique: + ar1 = np.asarray(ar1).ravel() + else: + ar1 = unique(ar1) + ar2 = unique(ar2) + return ar1[in1d(ar1, ar2, assume_unique=True, invert=True)] diff --git a/venv/Lib/site-packages/numpy/lib/arrayterator.py b/venv/Lib/site-packages/numpy/lib/arrayterator.py new file mode 100644 index 0000000..b9ea21f --- /dev/null +++ b/venv/Lib/site-packages/numpy/lib/arrayterator.py @@ -0,0 +1,219 @@ +""" +A buffered iterator for big arrays. + +This module solves the problem of iterating over a big file-based array +without having to read it into memory. The `Arrayterator` class wraps +an array object, and when iterated it will return sub-arrays with at most +a user-specified number of elements. + +""" +from operator import mul +from functools import reduce + +__all__ = ['Arrayterator'] + + +class Arrayterator: + """ + Buffered iterator for big arrays. + + `Arrayterator` creates a buffered iterator for reading big arrays in small + contiguous blocks. The class is useful for objects stored in the + file system. It allows iteration over the object *without* reading + everything in memory; instead, small blocks are read and iterated over. + + `Arrayterator` can be used with any object that supports multidimensional + slices. This includes NumPy arrays, but also variables from + Scientific.IO.NetCDF or pynetcdf for example. + + Parameters + ---------- + var : array_like + The object to iterate over. + buf_size : int, optional + The buffer size. If `buf_size` is supplied, the maximum amount of + data that will be read into memory is `buf_size` elements. + Default is None, which will read as many element as possible + into memory. + + Attributes + ---------- + var + buf_size + start + stop + step + shape + flat + + See Also + -------- + ndenumerate : Multidimensional array iterator. + flatiter : Flat array iterator. + memmap : Create a memory-map to an array stored in a binary file on disk. + + Notes + ----- + The algorithm works by first finding a "running dimension", along which + the blocks will be extracted. Given an array of dimensions + ``(d1, d2, ..., dn)``, e.g. if `buf_size` is smaller than ``d1``, the + first dimension will be used. If, on the other hand, + ``d1 < buf_size < d1*d2`` the second dimension will be used, and so on. + Blocks are extracted along this dimension, and when the last block is + returned the process continues from the next dimension, until all + elements have been read. + + Examples + -------- + >>> a = np.arange(3 * 4 * 5 * 6).reshape(3, 4, 5, 6) + >>> a_itor = np.lib.Arrayterator(a, 2) + >>> a_itor.shape + (3, 4, 5, 6) + + Now we can iterate over ``a_itor``, and it will return arrays of size + two. Since `buf_size` was smaller than any dimension, the first + dimension will be iterated over first: + + >>> for subarr in a_itor: + ... if not subarr.all(): + ... print(subarr, subarr.shape) # doctest: +SKIP + >>> # [[[[0 1]]]] (1, 1, 1, 2) + + """ + + def __init__(self, var, buf_size=None): + self.var = var + self.buf_size = buf_size + + self.start = [0 for dim in var.shape] + self.stop = [dim for dim in var.shape] + self.step = [1 for dim in var.shape] + + def __getattr__(self, attr): + return getattr(self.var, attr) + + def __getitem__(self, index): + """ + Return a new arrayterator. + + """ + # Fix index, handling ellipsis and incomplete slices. + if not isinstance(index, tuple): + index = (index,) + fixed = [] + length, dims = len(index), self.ndim + for slice_ in index: + if slice_ is Ellipsis: + fixed.extend([slice(None)] * (dims-length+1)) + length = len(fixed) + elif isinstance(slice_, int): + fixed.append(slice(slice_, slice_+1, 1)) + else: + fixed.append(slice_) + index = tuple(fixed) + if len(index) < dims: + index += (slice(None),) * (dims-len(index)) + + # Return a new arrayterator object. + out = self.__class__(self.var, self.buf_size) + for i, (start, stop, step, slice_) in enumerate( + zip(self.start, self.stop, self.step, index)): + out.start[i] = start + (slice_.start or 0) + out.step[i] = step * (slice_.step or 1) + out.stop[i] = start + (slice_.stop or stop-start) + out.stop[i] = min(stop, out.stop[i]) + return out + + def __array__(self): + """ + Return corresponding data. + + """ + slice_ = tuple(slice(*t) for t in zip( + self.start, self.stop, self.step)) + return self.var[slice_] + + @property + def flat(self): + """ + A 1-D flat iterator for Arrayterator objects. + + This iterator returns elements of the array to be iterated over in + `Arrayterator` one by one. It is similar to `flatiter`. + + See Also + -------- + Arrayterator + flatiter + + Examples + -------- + >>> a = np.arange(3 * 4 * 5 * 6).reshape(3, 4, 5, 6) + >>> a_itor = np.lib.Arrayterator(a, 2) + + >>> for subarr in a_itor.flat: + ... if not subarr: + ... print(subarr, type(subarr)) + ... + 0 + + """ + for block in self: + yield from block.flat + + @property + def shape(self): + """ + The shape of the array to be iterated over. + + For an example, see `Arrayterator`. + + """ + return tuple(((stop-start-1)//step+1) for start, stop, step in + zip(self.start, self.stop, self.step)) + + def __iter__(self): + # Skip arrays with degenerate dimensions + if [dim for dim in self.shape if dim <= 0]: + return + + start = self.start[:] + stop = self.stop[:] + step = self.step[:] + ndims = self.var.ndim + + while True: + count = self.buf_size or reduce(mul, self.shape) + + # iterate over each dimension, looking for the + # running dimension (ie, the dimension along which + # the blocks will be built from) + rundim = 0 + for i in range(ndims-1, -1, -1): + # if count is zero we ran out of elements to read + # along higher dimensions, so we read only a single position + if count == 0: + stop[i] = start[i]+1 + elif count <= self.shape[i]: + # limit along this dimension + stop[i] = start[i] + count*step[i] + rundim = i + else: + # read everything along this dimension + stop[i] = self.stop[i] + stop[i] = min(self.stop[i], stop[i]) + count = count//self.shape[i] + + # yield a block + slice_ = tuple(slice(*t) for t in zip(start, stop, step)) + yield self.var[slice_] + + # Update start position, taking care of overflow to + # other dimensions + start[rundim] = stop[rundim] # start where we stopped + for i in range(ndims-1, 0, -1): + if start[i] >= self.stop[i]: + start[i] = self.start[i] + start[i-1] += self.step[i-1] + if start[0] >= self.stop[0]: + return diff --git a/venv/Lib/site-packages/numpy/lib/format.py b/venv/Lib/site-packages/numpy/lib/format.py new file mode 100644 index 0000000..5d951e2 --- /dev/null +++ b/venv/Lib/site-packages/numpy/lib/format.py @@ -0,0 +1,914 @@ +""" +Binary serialization + +NPY format +========== + +A simple format for saving numpy arrays to disk with the full +information about them. + +The ``.npy`` format is the standard binary file format in NumPy for +persisting a *single* arbitrary NumPy array on disk. The format stores all +of the shape and dtype information necessary to reconstruct the array +correctly even on another machine with a different architecture. +The format is designed to be as simple as possible while achieving +its limited goals. + +The ``.npz`` format is the standard format for persisting *multiple* NumPy +arrays on disk. A ``.npz`` file is a zip file containing multiple ``.npy`` +files, one for each array. + +Capabilities +------------ + +- Can represent all NumPy arrays including nested record arrays and + object arrays. + +- Represents the data in its native binary form. + +- Supports Fortran-contiguous arrays directly. + +- Stores all of the necessary information to reconstruct the array + including shape and dtype on a machine of a different + architecture. Both little-endian and big-endian arrays are + supported, and a file with little-endian numbers will yield + a little-endian array on any machine reading the file. The + types are described in terms of their actual sizes. For example, + if a machine with a 64-bit C "long int" writes out an array with + "long ints", a reading machine with 32-bit C "long ints" will yield + an array with 64-bit integers. + +- Is straightforward to reverse engineer. Datasets often live longer than + the programs that created them. A competent developer should be + able to create a solution in their preferred programming language to + read most ``.npy`` files that they have been given without much + documentation. + +- Allows memory-mapping of the data. See `open_memmep`. + +- Can be read from a filelike stream object instead of an actual file. + +- Stores object arrays, i.e. arrays containing elements that are arbitrary + Python objects. Files with object arrays are not to be mmapable, but + can be read and written to disk. + +Limitations +----------- + +- Arbitrary subclasses of numpy.ndarray are not completely preserved. + Subclasses will be accepted for writing, but only the array data will + be written out. A regular numpy.ndarray object will be created + upon reading the file. + +.. warning:: + + Due to limitations in the interpretation of structured dtypes, dtypes + with fields with empty names will have the names replaced by 'f0', 'f1', + etc. Such arrays will not round-trip through the format entirely + accurately. The data is intact; only the field names will differ. We are + working on a fix for this. This fix will not require a change in the + file format. The arrays with such structures can still be saved and + restored, and the correct dtype may be restored by using the + ``loadedarray.view(correct_dtype)`` method. + +File extensions +--------------- + +We recommend using the ``.npy`` and ``.npz`` extensions for files saved +in this format. This is by no means a requirement; applications may wish +to use these file formats but use an extension specific to the +application. In the absence of an obvious alternative, however, +we suggest using ``.npy`` and ``.npz``. + +Version numbering +----------------- + +The version numbering of these formats is independent of NumPy version +numbering. If the format is upgraded, the code in `numpy.io` will still +be able to read and write Version 1.0 files. + +Format Version 1.0 +------------------ + +The first 6 bytes are a magic string: exactly ``\\x93NUMPY``. + +The next 1 byte is an unsigned byte: the major version number of the file +format, e.g. ``\\x01``. + +The next 1 byte is an unsigned byte: the minor version number of the file +format, e.g. ``\\x00``. Note: the version of the file format is not tied +to the version of the numpy package. + +The next 2 bytes form a little-endian unsigned short int: the length of +the header data HEADER_LEN. + +The next HEADER_LEN bytes form the header data describing the array's +format. It is an ASCII string which contains a Python literal expression +of a dictionary. It is terminated by a newline (``\\n``) and padded with +spaces (``\\x20``) to make the total of +``len(magic string) + 2 + len(length) + HEADER_LEN`` be evenly divisible +by 64 for alignment purposes. + +The dictionary contains three keys: + + "descr" : dtype.descr + An object that can be passed as an argument to the `numpy.dtype` + constructor to create the array's dtype. + "fortran_order" : bool + Whether the array data is Fortran-contiguous or not. Since + Fortran-contiguous arrays are a common form of non-C-contiguity, + we allow them to be written directly to disk for efficiency. + "shape" : tuple of int + The shape of the array. + +For repeatability and readability, the dictionary keys are sorted in +alphabetic order. This is for convenience only. A writer SHOULD implement +this if possible. A reader MUST NOT depend on this. + +Following the header comes the array data. If the dtype contains Python +objects (i.e. ``dtype.hasobject is True``), then the data is a Python +pickle of the array. Otherwise the data is the contiguous (either C- +or Fortran-, depending on ``fortran_order``) bytes of the array. +Consumers can figure out the number of bytes by multiplying the number +of elements given by the shape (noting that ``shape=()`` means there is +1 element) by ``dtype.itemsize``. + +Format Version 2.0 +------------------ + +The version 1.0 format only allowed the array header to have a total size of +65535 bytes. This can be exceeded by structured arrays with a large number of +columns. The version 2.0 format extends the header size to 4 GiB. +`numpy.save` will automatically save in 2.0 format if the data requires it, +else it will always use the more compatible 1.0 format. + +The description of the fourth element of the header therefore has become: +"The next 4 bytes form a little-endian unsigned int: the length of the header +data HEADER_LEN." + +Format Version 3.0 +------------------ + +This version replaces the ASCII string (which in practice was latin1) with +a utf8-encoded string, so supports structured types with any unicode field +names. + +Notes +----- +The ``.npy`` format, including motivation for creating it and a comparison of +alternatives, is described in the +:doc:`"npy-format" NEP `, however details have +evolved with time and this document is more current. + +""" +import numpy +import io +import warnings +from numpy.lib.utils import safe_eval +from numpy.compat import ( + isfileobj, os_fspath, pickle + ) + + +__all__ = [] + + +MAGIC_PREFIX = b'\x93NUMPY' +MAGIC_LEN = len(MAGIC_PREFIX) + 2 +ARRAY_ALIGN = 64 # plausible values are powers of 2 between 16 and 4096 +BUFFER_SIZE = 2**18 # size of buffer for reading npz files in bytes + +# difference between version 1.0 and 2.0 is a 4 byte (I) header length +# instead of 2 bytes (H) allowing storage of large structured arrays +_header_size_info = { + (1, 0): (' 255: + raise ValueError("major version must be 0 <= major < 256") + if minor < 0 or minor > 255: + raise ValueError("minor version must be 0 <= minor < 256") + return MAGIC_PREFIX + bytes([major, minor]) + +def read_magic(fp): + """ Read the magic string to get the version of the file format. + + Parameters + ---------- + fp : filelike object + + Returns + ------- + major : int + minor : int + """ + magic_str = _read_bytes(fp, MAGIC_LEN, "magic string") + if magic_str[:-2] != MAGIC_PREFIX: + msg = "the magic string is not correct; expected %r, got %r" + raise ValueError(msg % (MAGIC_PREFIX, magic_str[:-2])) + major, minor = magic_str[-2:] + return major, minor + +def _has_metadata(dt): + if dt.metadata is not None: + return True + elif dt.names is not None: + return any(_has_metadata(dt[k]) for k in dt.names) + elif dt.subdtype is not None: + return _has_metadata(dt.base) + else: + return False + +def dtype_to_descr(dtype): + """ + Get a serializable descriptor from the dtype. + + The .descr attribute of a dtype object cannot be round-tripped through + the dtype() constructor. Simple types, like dtype('float32'), have + a descr which looks like a record array with one field with '' as + a name. The dtype() constructor interprets this as a request to give + a default name. Instead, we construct descriptor that can be passed to + dtype(). + + Parameters + ---------- + dtype : dtype + The dtype of the array that will be written to disk. + + Returns + ------- + descr : object + An object that can be passed to `numpy.dtype()` in order to + replicate the input dtype. + + """ + if _has_metadata(dtype): + warnings.warn("metadata on a dtype may be saved or ignored, but will " + "raise if saved when read. Use another form of storage.", + UserWarning, stacklevel=2) + if dtype.names is not None: + # This is a record array. The .descr is fine. XXX: parts of the + # record array with an empty name, like padding bytes, still get + # fiddled with. This needs to be fixed in the C implementation of + # dtype(). + return dtype.descr + else: + return dtype.str + +def descr_to_dtype(descr): + """ + Returns a dtype based off the given description. + + This is essentially the reverse of `dtype_to_descr()`. It will remove + the valueless padding fields created by, i.e. simple fields like + dtype('float32'), and then convert the description to its corresponding + dtype. + + Parameters + ---------- + descr : object + The object retreived by dtype.descr. Can be passed to + `numpy.dtype()` in order to replicate the input dtype. + + Returns + ------- + dtype : dtype + The dtype constructed by the description. + + """ + if isinstance(descr, str): + # No padding removal needed + return numpy.dtype(descr) + elif isinstance(descr, tuple): + # subtype, will always have a shape descr[1] + dt = descr_to_dtype(descr[0]) + return numpy.dtype((dt, descr[1])) + + titles = [] + names = [] + formats = [] + offsets = [] + offset = 0 + for field in descr: + if len(field) == 2: + name, descr_str = field + dt = descr_to_dtype(descr_str) + else: + name, descr_str, shape = field + dt = numpy.dtype((descr_to_dtype(descr_str), shape)) + + # Ignore padding bytes, which will be void bytes with '' as name + # Once support for blank names is removed, only "if name == ''" needed) + is_pad = (name == '' and dt.type is numpy.void and dt.names is None) + if not is_pad: + title, name = name if isinstance(name, tuple) else (None, name) + titles.append(title) + names.append(name) + formats.append(dt) + offsets.append(offset) + offset += dt.itemsize + + return numpy.dtype({'names': names, 'formats': formats, 'titles': titles, + 'offsets': offsets, 'itemsize': offset}) + +def header_data_from_array_1_0(array): + """ Get the dictionary of header metadata from a numpy.ndarray. + + Parameters + ---------- + array : numpy.ndarray + + Returns + ------- + d : dict + This has the appropriate entries for writing its string representation + to the header of the file. + """ + d = {'shape': array.shape} + if array.flags.c_contiguous: + d['fortran_order'] = False + elif array.flags.f_contiguous: + d['fortran_order'] = True + else: + # Totally non-contiguous data. We will have to make it C-contiguous + # before writing. Note that we need to test for C_CONTIGUOUS first + # because a 1-D array is both C_CONTIGUOUS and F_CONTIGUOUS. + d['fortran_order'] = False + + d['descr'] = dtype_to_descr(array.dtype) + return d + + +def _wrap_header(header, version): + """ + Takes a stringified header, and attaches the prefix and padding to it + """ + import struct + assert version is not None + fmt, encoding = _header_size_info[version] + if not isinstance(header, bytes): # always true on python 3 + header = header.encode(encoding) + hlen = len(header) + 1 + padlen = ARRAY_ALIGN - ((MAGIC_LEN + struct.calcsize(fmt) + hlen) % ARRAY_ALIGN) + try: + header_prefix = magic(*version) + struct.pack(fmt, hlen + padlen) + except struct.error: + msg = "Header length {} too big for version={}".format(hlen, version) + raise ValueError(msg) + + # Pad the header with spaces and a final newline such that the magic + # string, the header-length short and the header are aligned on a + # ARRAY_ALIGN byte boundary. This supports memory mapping of dtypes + # aligned up to ARRAY_ALIGN on systems like Linux where mmap() + # offset must be page-aligned (i.e. the beginning of the file). + return header_prefix + header + b' '*padlen + b'\n' + + +def _wrap_header_guess_version(header): + """ + Like `_wrap_header`, but chooses an appropriate version given the contents + """ + try: + return _wrap_header(header, (1, 0)) + except ValueError: + pass + + try: + ret = _wrap_header(header, (2, 0)) + except UnicodeEncodeError: + pass + else: + warnings.warn("Stored array in format 2.0. It can only be" + "read by NumPy >= 1.9", UserWarning, stacklevel=2) + return ret + + header = _wrap_header(header, (3, 0)) + warnings.warn("Stored array in format 3.0. It can only be " + "read by NumPy >= 1.17", UserWarning, stacklevel=2) + return header + + +def _write_array_header(fp, d, version=None): + """ Write the header for an array and returns the version used + + Parameters + ---------- + fp : filelike object + d : dict + This has the appropriate entries for writing its string representation + to the header of the file. + version: tuple or None + None means use oldest that works + explicit version will raise a ValueError if the format does not + allow saving this data. Default: None + """ + header = ["{"] + for key, value in sorted(d.items()): + # Need to use repr here, since we eval these when reading + header.append("'%s': %s, " % (key, repr(value))) + header.append("}") + header = "".join(header) + header = _filter_header(header) + if version is None: + header = _wrap_header_guess_version(header) + else: + header = _wrap_header(header, version) + fp.write(header) + +def write_array_header_1_0(fp, d): + """ Write the header for an array using the 1.0 format. + + Parameters + ---------- + fp : filelike object + d : dict + This has the appropriate entries for writing its string + representation to the header of the file. + """ + _write_array_header(fp, d, (1, 0)) + + +def write_array_header_2_0(fp, d): + """ Write the header for an array using the 2.0 format. + The 2.0 format allows storing very large structured arrays. + + .. versionadded:: 1.9.0 + + Parameters + ---------- + fp : filelike object + d : dict + This has the appropriate entries for writing its string + representation to the header of the file. + """ + _write_array_header(fp, d, (2, 0)) + +def read_array_header_1_0(fp): + """ + Read an array header from a filelike object using the 1.0 file format + version. + + This will leave the file object located just after the header. + + Parameters + ---------- + fp : filelike object + A file object or something with a `.read()` method like a file. + + Returns + ------- + shape : tuple of int + The shape of the array. + fortran_order : bool + The array data will be written out directly if it is either + C-contiguous or Fortran-contiguous. Otherwise, it will be made + contiguous before writing it out. + dtype : dtype + The dtype of the file's data. + + Raises + ------ + ValueError + If the data is invalid. + + """ + return _read_array_header(fp, version=(1, 0)) + +def read_array_header_2_0(fp): + """ + Read an array header from a filelike object using the 2.0 file format + version. + + This will leave the file object located just after the header. + + .. versionadded:: 1.9.0 + + Parameters + ---------- + fp : filelike object + A file object or something with a `.read()` method like a file. + + Returns + ------- + shape : tuple of int + The shape of the array. + fortran_order : bool + The array data will be written out directly if it is either + C-contiguous or Fortran-contiguous. Otherwise, it will be made + contiguous before writing it out. + dtype : dtype + The dtype of the file's data. + + Raises + ------ + ValueError + If the data is invalid. + + """ + return _read_array_header(fp, version=(2, 0)) + + +def _filter_header(s): + """Clean up 'L' in npz header ints. + + Cleans up the 'L' in strings representing integers. Needed to allow npz + headers produced in Python2 to be read in Python3. + + Parameters + ---------- + s : string + Npy file header. + + Returns + ------- + header : str + Cleaned up header. + + """ + import tokenize + from io import StringIO + + tokens = [] + last_token_was_number = False + for token in tokenize.generate_tokens(StringIO(s).readline): + token_type = token[0] + token_string = token[1] + if (last_token_was_number and + token_type == tokenize.NAME and + token_string == "L"): + continue + else: + tokens.append(token) + last_token_was_number = (token_type == tokenize.NUMBER) + return tokenize.untokenize(tokens) + + +def _read_array_header(fp, version): + """ + see read_array_header_1_0 + """ + # Read an unsigned, little-endian short int which has the length of the + # header. + import struct + hinfo = _header_size_info.get(version) + if hinfo is None: + raise ValueError("Invalid version {!r}".format(version)) + hlength_type, encoding = hinfo + + hlength_str = _read_bytes(fp, struct.calcsize(hlength_type), "array header length") + header_length = struct.unpack(hlength_type, hlength_str)[0] + header = _read_bytes(fp, header_length, "array header") + header = header.decode(encoding) + + # The header is a pretty-printed string representation of a literal + # Python dictionary with trailing newlines padded to a ARRAY_ALIGN byte + # boundary. The keys are strings. + # "shape" : tuple of int + # "fortran_order" : bool + # "descr" : dtype.descr + header = _filter_header(header) + try: + d = safe_eval(header) + except SyntaxError as e: + msg = "Cannot parse header: {!r}\nException: {!r}" + raise ValueError(msg.format(header, e)) + if not isinstance(d, dict): + msg = "Header is not a dictionary: {!r}" + raise ValueError(msg.format(d)) + keys = sorted(d.keys()) + if keys != ['descr', 'fortran_order', 'shape']: + msg = "Header does not contain the correct keys: {!r}" + raise ValueError(msg.format(keys)) + + # Sanity-check the values. + if (not isinstance(d['shape'], tuple) or + not numpy.all([isinstance(x, int) for x in d['shape']])): + msg = "shape is not valid: {!r}" + raise ValueError(msg.format(d['shape'])) + if not isinstance(d['fortran_order'], bool): + msg = "fortran_order is not a valid bool: {!r}" + raise ValueError(msg.format(d['fortran_order'])) + try: + dtype = descr_to_dtype(d['descr']) + except TypeError: + msg = "descr is not a valid dtype descriptor: {!r}" + raise ValueError(msg.format(d['descr'])) + + return d['shape'], d['fortran_order'], dtype + +def write_array(fp, array, version=None, allow_pickle=True, pickle_kwargs=None): + """ + Write an array to an NPY file, including a header. + + If the array is neither C-contiguous nor Fortran-contiguous AND the + file_like object is not a real file object, this function will have to + copy data in memory. + + Parameters + ---------- + fp : file_like object + An open, writable file object, or similar object with a + ``.write()`` method. + array : ndarray + The array to write to disk. + version : (int, int) or None, optional + The version number of the format. None means use the oldest + supported version that is able to store the data. Default: None + allow_pickle : bool, optional + Whether to allow writing pickled data. Default: True + pickle_kwargs : dict, optional + Additional keyword arguments to pass to pickle.dump, excluding + 'protocol'. These are only useful when pickling objects in object + arrays on Python 3 to Python 2 compatible format. + + Raises + ------ + ValueError + If the array cannot be persisted. This includes the case of + allow_pickle=False and array being an object array. + Various other errors + If the array contains Python objects as part of its dtype, the + process of pickling them may raise various errors if the objects + are not picklable. + + """ + _check_version(version) + _write_array_header(fp, header_data_from_array_1_0(array), version) + + if array.itemsize == 0: + buffersize = 0 + else: + # Set buffer size to 16 MiB to hide the Python loop overhead. + buffersize = max(16 * 1024 ** 2 // array.itemsize, 1) + + if array.dtype.hasobject: + # We contain Python objects so we cannot write out the data + # directly. Instead, we will pickle it out + if not allow_pickle: + raise ValueError("Object arrays cannot be saved when " + "allow_pickle=False") + if pickle_kwargs is None: + pickle_kwargs = {} + pickle.dump(array, fp, protocol=3, **pickle_kwargs) + elif array.flags.f_contiguous and not array.flags.c_contiguous: + if isfileobj(fp): + array.T.tofile(fp) + else: + for chunk in numpy.nditer( + array, flags=['external_loop', 'buffered', 'zerosize_ok'], + buffersize=buffersize, order='F'): + fp.write(chunk.tobytes('C')) + else: + if isfileobj(fp): + array.tofile(fp) + else: + for chunk in numpy.nditer( + array, flags=['external_loop', 'buffered', 'zerosize_ok'], + buffersize=buffersize, order='C'): + fp.write(chunk.tobytes('C')) + + +def read_array(fp, allow_pickle=False, pickle_kwargs=None): + """ + Read an array from an NPY file. + + Parameters + ---------- + fp : file_like object + If this is not a real file object, then this may take extra memory + and time. + allow_pickle : bool, optional + Whether to allow writing pickled data. Default: False + + .. versionchanged:: 1.16.3 + Made default False in response to CVE-2019-6446. + + pickle_kwargs : dict + Additional keyword arguments to pass to pickle.load. These are only + useful when loading object arrays saved on Python 2 when using + Python 3. + + Returns + ------- + array : ndarray + The array from the data on disk. + + Raises + ------ + ValueError + If the data is invalid, or allow_pickle=False and the file contains + an object array. + + """ + version = read_magic(fp) + _check_version(version) + shape, fortran_order, dtype = _read_array_header(fp, version) + if len(shape) == 0: + count = 1 + else: + count = numpy.multiply.reduce(shape, dtype=numpy.int64) + + # Now read the actual data. + if dtype.hasobject: + # The array contained Python objects. We need to unpickle the data. + if not allow_pickle: + raise ValueError("Object arrays cannot be loaded when " + "allow_pickle=False") + if pickle_kwargs is None: + pickle_kwargs = {} + try: + array = pickle.load(fp, **pickle_kwargs) + except UnicodeError as err: + # Friendlier error message + raise UnicodeError("Unpickling a python object failed: %r\n" + "You may need to pass the encoding= option " + "to numpy.load" % (err,)) from err + else: + if isfileobj(fp): + # We can use the fast fromfile() function. + array = numpy.fromfile(fp, dtype=dtype, count=count) + else: + # This is not a real file. We have to read it the + # memory-intensive way. + # crc32 module fails on reads greater than 2 ** 32 bytes, + # breaking large reads from gzip streams. Chunk reads to + # BUFFER_SIZE bytes to avoid issue and reduce memory overhead + # of the read. In non-chunked case count < max_read_count, so + # only one read is performed. + + # Use np.ndarray instead of np.empty since the latter does + # not correctly instantiate zero-width string dtypes; see + # https://github.com/numpy/numpy/pull/6430 + array = numpy.ndarray(count, dtype=dtype) + + if dtype.itemsize > 0: + # If dtype.itemsize == 0 then there's nothing more to read + max_read_count = BUFFER_SIZE // min(BUFFER_SIZE, dtype.itemsize) + + for i in range(0, count, max_read_count): + read_count = min(max_read_count, count - i) + read_size = int(read_count * dtype.itemsize) + data = _read_bytes(fp, read_size, "array data") + array[i:i+read_count] = numpy.frombuffer(data, dtype=dtype, + count=read_count) + + if fortran_order: + array.shape = shape[::-1] + array = array.transpose() + else: + array.shape = shape + + return array + + +def open_memmap(filename, mode='r+', dtype=None, shape=None, + fortran_order=False, version=None): + """ + Open a .npy file as a memory-mapped array. + + This may be used to read an existing file or create a new one. + + Parameters + ---------- + filename : str or path-like + The name of the file on disk. This may *not* be a file-like + object. + mode : str, optional + The mode in which to open the file; the default is 'r+'. In + addition to the standard file modes, 'c' is also accepted to mean + "copy on write." See `memmap` for the available mode strings. + dtype : data-type, optional + The data type of the array if we are creating a new file in "write" + mode, if not, `dtype` is ignored. The default value is None, which + results in a data-type of `float64`. + shape : tuple of int + The shape of the array if we are creating a new file in "write" + mode, in which case this parameter is required. Otherwise, this + parameter is ignored and is thus optional. + fortran_order : bool, optional + Whether the array should be Fortran-contiguous (True) or + C-contiguous (False, the default) if we are creating a new file in + "write" mode. + version : tuple of int (major, minor) or None + If the mode is a "write" mode, then this is the version of the file + format used to create the file. None means use the oldest + supported version that is able to store the data. Default: None + + Returns + ------- + marray : memmap + The memory-mapped array. + + Raises + ------ + ValueError + If the data or the mode is invalid. + IOError + If the file is not found or cannot be opened correctly. + + See Also + -------- + numpy.memmap + + """ + if isfileobj(filename): + raise ValueError("Filename must be a string or a path-like object." + " Memmap cannot use existing file handles.") + + if 'w' in mode: + # We are creating the file, not reading it. + # Check if we ought to create the file. + _check_version(version) + # Ensure that the given dtype is an authentic dtype object rather + # than just something that can be interpreted as a dtype object. + dtype = numpy.dtype(dtype) + if dtype.hasobject: + msg = "Array can't be memory-mapped: Python objects in dtype." + raise ValueError(msg) + d = dict( + descr=dtype_to_descr(dtype), + fortran_order=fortran_order, + shape=shape, + ) + # If we got here, then it should be safe to create the file. + with open(os_fspath(filename), mode+'b') as fp: + _write_array_header(fp, d, version) + offset = fp.tell() + else: + # Read the header of the file first. + with open(os_fspath(filename), 'rb') as fp: + version = read_magic(fp) + _check_version(version) + + shape, fortran_order, dtype = _read_array_header(fp, version) + if dtype.hasobject: + msg = "Array can't be memory-mapped: Python objects in dtype." + raise ValueError(msg) + offset = fp.tell() + + if fortran_order: + order = 'F' + else: + order = 'C' + + # We need to change a write-only mode to a read-write mode since we've + # already written data to the file. + if mode == 'w+': + mode = 'r+' + + marray = numpy.memmap(filename, dtype=dtype, shape=shape, order=order, + mode=mode, offset=offset) + + return marray + + +def _read_bytes(fp, size, error_template="ran out of data"): + """ + Read from file-like object until size bytes are read. + Raises ValueError if not EOF is encountered before size bytes are read. + Non-blocking objects only supported if they derive from io objects. + + Required as e.g. ZipExtFile in python 2.6 can return less data than + requested. + """ + data = bytes() + while True: + # io files (default in python3) return None or raise on + # would-block, python2 file will truncate, probably nothing can be + # done about that. note that regular files can't be non-blocking + try: + r = fp.read(size - len(data)) + data += r + if len(r) == 0 or len(data) == size: + break + except io.BlockingIOError: + pass + if len(data) != size: + msg = "EOF: reading %s, expected %d bytes got %d" + raise ValueError(msg % (error_template, size, len(data))) + else: + return data diff --git a/venv/Lib/site-packages/numpy/lib/function_base.py b/venv/Lib/site-packages/numpy/lib/function_base.py new file mode 100644 index 0000000..984f308 --- /dev/null +++ b/venv/Lib/site-packages/numpy/lib/function_base.py @@ -0,0 +1,4860 @@ +import collections.abc +import functools +import re +import sys +import warnings + +import numpy as np +import numpy.core.numeric as _nx +from numpy.core import transpose +from numpy.core.numeric import ( + ones, zeros, arange, concatenate, array, asarray, asanyarray, empty, + ndarray, around, floor, ceil, take, dot, where, intp, + integer, isscalar, absolute + ) +from numpy.core.umath import ( + pi, add, arctan2, frompyfunc, cos, less_equal, sqrt, sin, + mod, exp, not_equal, subtract + ) +from numpy.core.fromnumeric import ( + ravel, nonzero, partition, mean, any, sum + ) +from numpy.core.numerictypes import typecodes +from numpy.core.overrides import set_module +from numpy.core import overrides +from numpy.core.function_base import add_newdoc +from numpy.lib.twodim_base import diag +from numpy.core.multiarray import ( + _insert, add_docstring, bincount, normalize_axis_index, _monotonicity, + interp as compiled_interp, interp_complex as compiled_interp_complex + ) +from numpy.core.umath import _add_newdoc_ufunc as add_newdoc_ufunc + +import builtins + +# needed in this module for compatibility +from numpy.lib.histograms import histogram, histogramdd + + +array_function_dispatch = functools.partial( + overrides.array_function_dispatch, module='numpy') + + +__all__ = [ + 'select', 'piecewise', 'trim_zeros', 'copy', 'iterable', 'percentile', + 'diff', 'gradient', 'angle', 'unwrap', 'sort_complex', 'disp', 'flip', + 'rot90', 'extract', 'place', 'vectorize', 'asarray_chkfinite', 'average', + 'bincount', 'digitize', 'cov', 'corrcoef', + 'msort', 'median', 'sinc', 'hamming', 'hanning', 'bartlett', + 'blackman', 'kaiser', 'trapz', 'i0', 'add_newdoc', 'add_docstring', + 'meshgrid', 'delete', 'insert', 'append', 'interp', 'add_newdoc_ufunc', + 'quantile' + ] + + +def _rot90_dispatcher(m, k=None, axes=None): + return (m,) + + +@array_function_dispatch(_rot90_dispatcher) +def rot90(m, k=1, axes=(0, 1)): + """ + Rotate an array by 90 degrees in the plane specified by axes. + + Rotation direction is from the first towards the second axis. + + Parameters + ---------- + m : array_like + Array of two or more dimensions. + k : integer + Number of times the array is rotated by 90 degrees. + axes: (2,) array_like + The array is rotated in the plane defined by the axes. + Axes must be different. + + .. versionadded:: 1.12.0 + + Returns + ------- + y : ndarray + A rotated view of `m`. + + See Also + -------- + flip : Reverse the order of elements in an array along the given axis. + fliplr : Flip an array horizontally. + flipud : Flip an array vertically. + + Notes + ----- + rot90(m, k=1, axes=(1,0)) is the reverse of rot90(m, k=1, axes=(0,1)) + rot90(m, k=1, axes=(1,0)) is equivalent to rot90(m, k=-1, axes=(0,1)) + + Examples + -------- + >>> m = np.array([[1,2],[3,4]], int) + >>> m + array([[1, 2], + [3, 4]]) + >>> np.rot90(m) + array([[2, 4], + [1, 3]]) + >>> np.rot90(m, 2) + array([[4, 3], + [2, 1]]) + >>> m = np.arange(8).reshape((2,2,2)) + >>> np.rot90(m, 1, (1,2)) + array([[[1, 3], + [0, 2]], + [[5, 7], + [4, 6]]]) + + """ + axes = tuple(axes) + if len(axes) != 2: + raise ValueError("len(axes) must be 2.") + + m = asanyarray(m) + + if axes[0] == axes[1] or absolute(axes[0] - axes[1]) == m.ndim: + raise ValueError("Axes must be different.") + + if (axes[0] >= m.ndim or axes[0] < -m.ndim + or axes[1] >= m.ndim or axes[1] < -m.ndim): + raise ValueError("Axes={} out of range for array of ndim={}." + .format(axes, m.ndim)) + + k %= 4 + + if k == 0: + return m[:] + if k == 2: + return flip(flip(m, axes[0]), axes[1]) + + axes_list = arange(0, m.ndim) + (axes_list[axes[0]], axes_list[axes[1]]) = (axes_list[axes[1]], + axes_list[axes[0]]) + + if k == 1: + return transpose(flip(m, axes[1]), axes_list) + else: + # k == 3 + return flip(transpose(m, axes_list), axes[1]) + + +def _flip_dispatcher(m, axis=None): + return (m,) + + +@array_function_dispatch(_flip_dispatcher) +def flip(m, axis=None): + """ + Reverse the order of elements in an array along the given axis. + + The shape of the array is preserved, but the elements are reordered. + + .. versionadded:: 1.12.0 + + Parameters + ---------- + m : array_like + Input array. + axis : None or int or tuple of ints, optional + Axis or axes along which to flip over. The default, + axis=None, will flip over all of the axes of the input array. + If axis is negative it counts from the last to the first axis. + + If axis is a tuple of ints, flipping is performed on all of the axes + specified in the tuple. + + .. versionchanged:: 1.15.0 + None and tuples of axes are supported + + Returns + ------- + out : array_like + A view of `m` with the entries of axis reversed. Since a view is + returned, this operation is done in constant time. + + See Also + -------- + flipud : Flip an array vertically (axis=0). + fliplr : Flip an array horizontally (axis=1). + + Notes + ----- + flip(m, 0) is equivalent to flipud(m). + + flip(m, 1) is equivalent to fliplr(m). + + flip(m, n) corresponds to ``m[...,::-1,...]`` with ``::-1`` at position n. + + flip(m) corresponds to ``m[::-1,::-1,...,::-1]`` with ``::-1`` at all + positions. + + flip(m, (0, 1)) corresponds to ``m[::-1,::-1,...]`` with ``::-1`` at + position 0 and position 1. + + Examples + -------- + >>> A = np.arange(8).reshape((2,2,2)) + >>> A + array([[[0, 1], + [2, 3]], + [[4, 5], + [6, 7]]]) + >>> np.flip(A, 0) + array([[[4, 5], + [6, 7]], + [[0, 1], + [2, 3]]]) + >>> np.flip(A, 1) + array([[[2, 3], + [0, 1]], + [[6, 7], + [4, 5]]]) + >>> np.flip(A) + array([[[7, 6], + [5, 4]], + [[3, 2], + [1, 0]]]) + >>> np.flip(A, (0, 2)) + array([[[5, 4], + [7, 6]], + [[1, 0], + [3, 2]]]) + >>> A = np.random.randn(3,4,5) + >>> np.all(np.flip(A,2) == A[:,:,::-1,...]) + True + """ + if not hasattr(m, 'ndim'): + m = asarray(m) + if axis is None: + indexer = (np.s_[::-1],) * m.ndim + else: + axis = _nx.normalize_axis_tuple(axis, m.ndim) + indexer = [np.s_[:]] * m.ndim + for ax in axis: + indexer[ax] = np.s_[::-1] + indexer = tuple(indexer) + return m[indexer] + + +@set_module('numpy') +def iterable(y): + """ + Check whether or not an object can be iterated over. + + Parameters + ---------- + y : object + Input object. + + Returns + ------- + b : bool + Return ``True`` if the object has an iterator method or is a + sequence and ``False`` otherwise. + + + Examples + -------- + >>> np.iterable([1, 2, 3]) + True + >>> np.iterable(2) + False + + """ + try: + iter(y) + except TypeError: + return False + return True + + +def _average_dispatcher(a, axis=None, weights=None, returned=None): + return (a, weights) + + +@array_function_dispatch(_average_dispatcher) +def average(a, axis=None, weights=None, returned=False): + """ + Compute the weighted average along the specified axis. + + Parameters + ---------- + a : array_like + Array containing data to be averaged. If `a` is not an array, a + conversion is attempted. + axis : None or int or tuple of ints, optional + Axis or axes along which to average `a`. The default, + axis=None, will average over all of the elements of the input array. + If axis is negative it counts from the last to the first axis. + + .. versionadded:: 1.7.0 + + If axis is a tuple of ints, averaging is performed on all of the axes + specified in the tuple instead of a single axis or all the axes as + before. + weights : array_like, optional + An array of weights associated with the values in `a`. Each value in + `a` contributes to the average according to its associated weight. + The weights array can either be 1-D (in which case its length must be + the size of `a` along the given axis) or of the same shape as `a`. + If `weights=None`, then all data in `a` are assumed to have a + weight equal to one. The 1-D calculation is:: + + avg = sum(a * weights) / sum(weights) + + The only constraint on `weights` is that `sum(weights)` must not be 0. + returned : bool, optional + Default is `False`. If `True`, the tuple (`average`, `sum_of_weights`) + is returned, otherwise only the average is returned. + If `weights=None`, `sum_of_weights` is equivalent to the number of + elements over which the average is taken. + + Returns + ------- + retval, [sum_of_weights] : array_type or double + Return the average along the specified axis. When `returned` is `True`, + return a tuple with the average as the first element and the sum + of the weights as the second element. `sum_of_weights` is of the + same type as `retval`. The result dtype follows a genereal pattern. + If `weights` is None, the result dtype will be that of `a` , or ``float64`` + if `a` is integral. Otherwise, if `weights` is not None and `a` is non- + integral, the result type will be the type of lowest precision capable of + representing values of both `a` and `weights`. If `a` happens to be + integral, the previous rules still applies but the result dtype will + at least be ``float64``. + + Raises + ------ + ZeroDivisionError + When all weights along axis are zero. See `numpy.ma.average` for a + version robust to this type of error. + TypeError + When the length of 1D `weights` is not the same as the shape of `a` + along axis. + + See Also + -------- + mean + + ma.average : average for masked arrays -- useful if your data contains + "missing" values + numpy.result_type : Returns the type that results from applying the + numpy type promotion rules to the arguments. + + Examples + -------- + >>> data = np.arange(1, 5) + >>> data + array([1, 2, 3, 4]) + >>> np.average(data) + 2.5 + >>> np.average(np.arange(1, 11), weights=np.arange(10, 0, -1)) + 4.0 + + >>> data = np.arange(6).reshape((3,2)) + >>> data + array([[0, 1], + [2, 3], + [4, 5]]) + >>> np.average(data, axis=1, weights=[1./4, 3./4]) + array([0.75, 2.75, 4.75]) + >>> np.average(data, weights=[1./4, 3./4]) + Traceback (most recent call last): + ... + TypeError: Axis must be specified when shapes of a and weights differ. + + >>> a = np.ones(5, dtype=np.float128) + >>> w = np.ones(5, dtype=np.complex64) + >>> avg = np.average(a, weights=w) + >>> print(avg.dtype) + complex256 + """ + a = np.asanyarray(a) + + if weights is None: + avg = a.mean(axis) + scl = avg.dtype.type(a.size/avg.size) + else: + wgt = np.asanyarray(weights) + + if issubclass(a.dtype.type, (np.integer, np.bool_)): + result_dtype = np.result_type(a.dtype, wgt.dtype, 'f8') + else: + result_dtype = np.result_type(a.dtype, wgt.dtype) + + # Sanity checks + if a.shape != wgt.shape: + if axis is None: + raise TypeError( + "Axis must be specified when shapes of a and weights " + "differ.") + if wgt.ndim != 1: + raise TypeError( + "1D weights expected when shapes of a and weights differ.") + if wgt.shape[0] != a.shape[axis]: + raise ValueError( + "Length of weights not compatible with specified axis.") + + # setup wgt to broadcast along axis + wgt = np.broadcast_to(wgt, (a.ndim-1)*(1,) + wgt.shape) + wgt = wgt.swapaxes(-1, axis) + + scl = wgt.sum(axis=axis, dtype=result_dtype) + if np.any(scl == 0.0): + raise ZeroDivisionError( + "Weights sum to zero, can't be normalized") + + avg = np.multiply(a, wgt, dtype=result_dtype).sum(axis)/scl + + if returned: + if scl.shape != avg.shape: + scl = np.broadcast_to(scl, avg.shape).copy() + return avg, scl + else: + return avg + + +@set_module('numpy') +def asarray_chkfinite(a, dtype=None, order=None): + """Convert the input to an array, checking for NaNs or Infs. + + Parameters + ---------- + a : array_like + Input data, in any form that can be converted to an array. This + includes lists, lists of tuples, tuples, tuples of tuples, tuples + of lists and ndarrays. Success requires no NaNs or Infs. + dtype : data-type, optional + By default, the data-type is inferred from the input data. + order : {'C', 'F', 'A', 'K'}, optional + Memory layout. 'A' and 'K' depend on the order of input array a. + 'C' row-major (C-style), + 'F' column-major (Fortran-style) memory representation. + 'A' (any) means 'F' if `a` is Fortran contiguous, 'C' otherwise + 'K' (keep) preserve input order + Defaults to 'C'. + + Returns + ------- + out : ndarray + Array interpretation of `a`. No copy is performed if the input + is already an ndarray. If `a` is a subclass of ndarray, a base + class ndarray is returned. + + Raises + ------ + ValueError + Raises ValueError if `a` contains NaN (Not a Number) or Inf (Infinity). + + See Also + -------- + asarray : Create and array. + asanyarray : Similar function which passes through subclasses. + ascontiguousarray : Convert input to a contiguous array. + asfarray : Convert input to a floating point ndarray. + asfortranarray : Convert input to an ndarray with column-major + memory order. + fromiter : Create an array from an iterator. + fromfunction : Construct an array by executing a function on grid + positions. + + Examples + -------- + Convert a list into an array. If all elements are finite + ``asarray_chkfinite`` is identical to ``asarray``. + + >>> a = [1, 2] + >>> np.asarray_chkfinite(a, dtype=float) + array([1., 2.]) + + Raises ValueError if array_like contains Nans or Infs. + + >>> a = [1, 2, np.inf] + >>> try: + ... np.asarray_chkfinite(a) + ... except ValueError: + ... print('ValueError') + ... + ValueError + + """ + a = asarray(a, dtype=dtype, order=order) + if a.dtype.char in typecodes['AllFloat'] and not np.isfinite(a).all(): + raise ValueError( + "array must not contain infs or NaNs") + return a + + +def _piecewise_dispatcher(x, condlist, funclist, *args, **kw): + yield x + # support the undocumented behavior of allowing scalars + if np.iterable(condlist): + yield from condlist + + +@array_function_dispatch(_piecewise_dispatcher) +def piecewise(x, condlist, funclist, *args, **kw): + """ + Evaluate a piecewise-defined function. + + Given a set of conditions and corresponding functions, evaluate each + function on the input data wherever its condition is true. + + Parameters + ---------- + x : ndarray or scalar + The input domain. + condlist : list of bool arrays or bool scalars + Each boolean array corresponds to a function in `funclist`. Wherever + `condlist[i]` is True, `funclist[i](x)` is used as the output value. + + Each boolean array in `condlist` selects a piece of `x`, + and should therefore be of the same shape as `x`. + + The length of `condlist` must correspond to that of `funclist`. + If one extra function is given, i.e. if + ``len(funclist) == len(condlist) + 1``, then that extra function + is the default value, used wherever all conditions are false. + funclist : list of callables, f(x,*args,**kw), or scalars + Each function is evaluated over `x` wherever its corresponding + condition is True. It should take a 1d array as input and give an 1d + array or a scalar value as output. If, instead of a callable, + a scalar is provided then a constant function (``lambda x: scalar``) is + assumed. + args : tuple, optional + Any further arguments given to `piecewise` are passed to the functions + upon execution, i.e., if called ``piecewise(..., ..., 1, 'a')``, then + each function is called as ``f(x, 1, 'a')``. + kw : dict, optional + Keyword arguments used in calling `piecewise` are passed to the + functions upon execution, i.e., if called + ``piecewise(..., ..., alpha=1)``, then each function is called as + ``f(x, alpha=1)``. + + Returns + ------- + out : ndarray + The output is the same shape and type as x and is found by + calling the functions in `funclist` on the appropriate portions of `x`, + as defined by the boolean arrays in `condlist`. Portions not covered + by any condition have a default value of 0. + + + See Also + -------- + choose, select, where + + Notes + ----- + This is similar to choose or select, except that functions are + evaluated on elements of `x` that satisfy the corresponding condition from + `condlist`. + + The result is:: + + |-- + |funclist[0](x[condlist[0]]) + out = |funclist[1](x[condlist[1]]) + |... + |funclist[n2](x[condlist[n2]]) + |-- + + Examples + -------- + Define the sigma function, which is -1 for ``x < 0`` and +1 for ``x >= 0``. + + >>> x = np.linspace(-2.5, 2.5, 6) + >>> np.piecewise(x, [x < 0, x >= 0], [-1, 1]) + array([-1., -1., -1., 1., 1., 1.]) + + Define the absolute value, which is ``-x`` for ``x <0`` and ``x`` for + ``x >= 0``. + + >>> np.piecewise(x, [x < 0, x >= 0], [lambda x: -x, lambda x: x]) + array([2.5, 1.5, 0.5, 0.5, 1.5, 2.5]) + + Apply the same function to a scalar value. + + >>> y = -2 + >>> np.piecewise(y, [y < 0, y >= 0], [lambda x: -x, lambda x: x]) + array(2) + + """ + x = asanyarray(x) + n2 = len(funclist) + + # undocumented: single condition is promoted to a list of one condition + if isscalar(condlist) or ( + not isinstance(condlist[0], (list, ndarray)) and x.ndim != 0): + condlist = [condlist] + + condlist = array(condlist, dtype=bool) + n = len(condlist) + + if n == n2 - 1: # compute the "otherwise" condition. + condelse = ~np.any(condlist, axis=0, keepdims=True) + condlist = np.concatenate([condlist, condelse], axis=0) + n += 1 + elif n != n2: + raise ValueError( + "with {} condition(s), either {} or {} functions are expected" + .format(n, n, n+1) + ) + + y = zeros(x.shape, x.dtype) + for cond, func in zip(condlist, funclist): + if not isinstance(func, collections.abc.Callable): + y[cond] = func + else: + vals = x[cond] + if vals.size > 0: + y[cond] = func(vals, *args, **kw) + + return y + + +def _select_dispatcher(condlist, choicelist, default=None): + yield from condlist + yield from choicelist + + +@array_function_dispatch(_select_dispatcher) +def select(condlist, choicelist, default=0): + """ + Return an array drawn from elements in choicelist, depending on conditions. + + Parameters + ---------- + condlist : list of bool ndarrays + The list of conditions which determine from which array in `choicelist` + the output elements are taken. When multiple conditions are satisfied, + the first one encountered in `condlist` is used. + choicelist : list of ndarrays + The list of arrays from which the output elements are taken. It has + to be of the same length as `condlist`. + default : scalar, optional + The element inserted in `output` when all conditions evaluate to False. + + Returns + ------- + output : ndarray + The output at position m is the m-th element of the array in + `choicelist` where the m-th element of the corresponding array in + `condlist` is True. + + See Also + -------- + where : Return elements from one of two arrays depending on condition. + take, choose, compress, diag, diagonal + + Examples + -------- + >>> x = np.arange(10) + >>> condlist = [x<3, x>5] + >>> choicelist = [x, x**2] + >>> np.select(condlist, choicelist) + array([ 0, 1, 2, ..., 49, 64, 81]) + + """ + # Check the size of condlist and choicelist are the same, or abort. + if len(condlist) != len(choicelist): + raise ValueError( + 'list of cases must be same length as list of conditions') + + # Now that the dtype is known, handle the deprecated select([], []) case + if len(condlist) == 0: + raise ValueError("select with an empty condition list is not possible") + + choicelist = [np.asarray(choice) for choice in choicelist] + choicelist.append(np.asarray(default)) + + # need to get the result type before broadcasting for correct scalar + # behaviour + dtype = np.result_type(*choicelist) + + # Convert conditions to arrays and broadcast conditions and choices + # as the shape is needed for the result. Doing it separately optimizes + # for example when all choices are scalars. + condlist = np.broadcast_arrays(*condlist) + choicelist = np.broadcast_arrays(*choicelist) + + # If cond array is not an ndarray in boolean format or scalar bool, abort. + for i, cond in enumerate(condlist): + if cond.dtype.type is not np.bool_: + raise TypeError( + 'invalid entry {} in condlist: should be boolean ndarray'.format(i)) + + if choicelist[0].ndim == 0: + # This may be common, so avoid the call. + result_shape = condlist[0].shape + else: + result_shape = np.broadcast_arrays(condlist[0], choicelist[0])[0].shape + + result = np.full(result_shape, choicelist[-1], dtype) + + # Use np.copyto to burn each choicelist array onto result, using the + # corresponding condlist as a boolean mask. This is done in reverse + # order since the first choice should take precedence. + choicelist = choicelist[-2::-1] + condlist = condlist[::-1] + for choice, cond in zip(choicelist, condlist): + np.copyto(result, choice, where=cond) + + return result + + +def _copy_dispatcher(a, order=None, subok=None): + return (a,) + + +@array_function_dispatch(_copy_dispatcher) +def copy(a, order='K', subok=False): + """ + Return an array copy of the given object. + + Parameters + ---------- + a : array_like + Input data. + order : {'C', 'F', 'A', 'K'}, optional + Controls the memory layout of the copy. 'C' means C-order, + 'F' means F-order, 'A' means 'F' if `a` is Fortran contiguous, + 'C' otherwise. 'K' means match the layout of `a` as closely + as possible. (Note that this function and :meth:`ndarray.copy` are very + similar, but have different default values for their order= + arguments.) + subok : bool, optional + If True, then sub-classes will be passed-through, otherwise the + returned array will be forced to be a base-class array (defaults to False). + + .. versionadded:: 1.19.0 + + Returns + ------- + arr : ndarray + Array interpretation of `a`. + + See Also + -------- + ndarray.copy : Preferred method for creating an array copy + + Notes + ----- + This is equivalent to: + + >>> np.array(a, copy=True) #doctest: +SKIP + + Examples + -------- + Create an array x, with a reference y and a copy z: + + >>> x = np.array([1, 2, 3]) + >>> y = x + >>> z = np.copy(x) + + Note that, when we modify x, y changes, but not z: + + >>> x[0] = 10 + >>> x[0] == y[0] + True + >>> x[0] == z[0] + False + + Note that np.copy is a shallow copy and will not copy object + elements within arrays. This is mainly important for arrays + containing Python objects. The new array will contain the + same object which may lead to surprises if that object can + be modified (is mutable): + + >>> a = np.array([1, 'm', [2, 3, 4]], dtype=object) + >>> b = np.copy(a) + >>> b[2][0] = 10 + >>> a + array([1, 'm', list([10, 3, 4])], dtype=object) + + To ensure all elements within an ``object`` array are copied, + use `copy.deepcopy`: + + >>> import copy + >>> a = np.array([1, 'm', [2, 3, 4]], dtype=object) + >>> c = copy.deepcopy(a) + >>> c[2][0] = 10 + >>> c + array([1, 'm', list([10, 3, 4])], dtype=object) + >>> a + array([1, 'm', list([2, 3, 4])], dtype=object) + + """ + return array(a, order=order, subok=subok, copy=True) + +# Basic operations + + +def _gradient_dispatcher(f, *varargs, axis=None, edge_order=None): + yield f + yield from varargs + + +@array_function_dispatch(_gradient_dispatcher) +def gradient(f, *varargs, axis=None, edge_order=1): + """ + Return the gradient of an N-dimensional array. + + The gradient is computed using second order accurate central differences + in the interior points and either first or second order accurate one-sides + (forward or backwards) differences at the boundaries. + The returned gradient hence has the same shape as the input array. + + Parameters + ---------- + f : array_like + An N-dimensional array containing samples of a scalar function. + varargs : list of scalar or array, optional + Spacing between f values. Default unitary spacing for all dimensions. + Spacing can be specified using: + + 1. single scalar to specify a sample distance for all dimensions. + 2. N scalars to specify a constant sample distance for each dimension. + i.e. `dx`, `dy`, `dz`, ... + 3. N arrays to specify the coordinates of the values along each + dimension of F. The length of the array must match the size of + the corresponding dimension + 4. Any combination of N scalars/arrays with the meaning of 2. and 3. + + If `axis` is given, the number of varargs must equal the number of axes. + Default: 1. + + edge_order : {1, 2}, optional + Gradient is calculated using N-th order accurate differences + at the boundaries. Default: 1. + + .. versionadded:: 1.9.1 + + axis : None or int or tuple of ints, optional + Gradient is calculated only along the given axis or axes + The default (axis = None) is to calculate the gradient for all the axes + of the input array. axis may be negative, in which case it counts from + the last to the first axis. + + .. versionadded:: 1.11.0 + + Returns + ------- + gradient : ndarray or list of ndarray + A set of ndarrays (or a single ndarray if there is only one dimension) + corresponding to the derivatives of f with respect to each dimension. + Each derivative has the same shape as f. + + Examples + -------- + >>> f = np.array([1, 2, 4, 7, 11, 16], dtype=float) + >>> np.gradient(f) + array([1. , 1.5, 2.5, 3.5, 4.5, 5. ]) + >>> np.gradient(f, 2) + array([0.5 , 0.75, 1.25, 1.75, 2.25, 2.5 ]) + + Spacing can be also specified with an array that represents the coordinates + of the values F along the dimensions. + For instance a uniform spacing: + + >>> x = np.arange(f.size) + >>> np.gradient(f, x) + array([1. , 1.5, 2.5, 3.5, 4.5, 5. ]) + + Or a non uniform one: + + >>> x = np.array([0., 1., 1.5, 3.5, 4., 6.], dtype=float) + >>> np.gradient(f, x) + array([1. , 3. , 3.5, 6.7, 6.9, 2.5]) + + For two dimensional arrays, the return will be two arrays ordered by + axis. In this example the first array stands for the gradient in + rows and the second one in columns direction: + + >>> np.gradient(np.array([[1, 2, 6], [3, 4, 5]], dtype=float)) + [array([[ 2., 2., -1.], + [ 2., 2., -1.]]), array([[1. , 2.5, 4. ], + [1. , 1. , 1. ]])] + + In this example the spacing is also specified: + uniform for axis=0 and non uniform for axis=1 + + >>> dx = 2. + >>> y = [1., 1.5, 3.5] + >>> np.gradient(np.array([[1, 2, 6], [3, 4, 5]], dtype=float), dx, y) + [array([[ 1. , 1. , -0.5], + [ 1. , 1. , -0.5]]), array([[2. , 2. , 2. ], + [2. , 1.7, 0.5]])] + + It is possible to specify how boundaries are treated using `edge_order` + + >>> x = np.array([0, 1, 2, 3, 4]) + >>> f = x**2 + >>> np.gradient(f, edge_order=1) + array([1., 2., 4., 6., 7.]) + >>> np.gradient(f, edge_order=2) + array([0., 2., 4., 6., 8.]) + + The `axis` keyword can be used to specify a subset of axes of which the + gradient is calculated + + >>> np.gradient(np.array([[1, 2, 6], [3, 4, 5]], dtype=float), axis=0) + array([[ 2., 2., -1.], + [ 2., 2., -1.]]) + + Notes + ----- + Assuming that :math:`f\\in C^{3}` (i.e., :math:`f` has at least 3 continuous + derivatives) and let :math:`h_{*}` be a non-homogeneous stepsize, we + minimize the "consistency error" :math:`\\eta_{i}` between the true gradient + and its estimate from a linear combination of the neighboring grid-points: + + .. math:: + + \\eta_{i} = f_{i}^{\\left(1\\right)} - + \\left[ \\alpha f\\left(x_{i}\\right) + + \\beta f\\left(x_{i} + h_{d}\\right) + + \\gamma f\\left(x_{i}-h_{s}\\right) + \\right] + + By substituting :math:`f(x_{i} + h_{d})` and :math:`f(x_{i} - h_{s})` + with their Taylor series expansion, this translates into solving + the following the linear system: + + .. math:: + + \\left\\{ + \\begin{array}{r} + \\alpha+\\beta+\\gamma=0 \\\\ + \\beta h_{d}-\\gamma h_{s}=1 \\\\ + \\beta h_{d}^{2}+\\gamma h_{s}^{2}=0 + \\end{array} + \\right. + + The resulting approximation of :math:`f_{i}^{(1)}` is the following: + + .. math:: + + \\hat f_{i}^{(1)} = + \\frac{ + h_{s}^{2}f\\left(x_{i} + h_{d}\\right) + + \\left(h_{d}^{2} - h_{s}^{2}\\right)f\\left(x_{i}\\right) + - h_{d}^{2}f\\left(x_{i}-h_{s}\\right)} + { h_{s}h_{d}\\left(h_{d} + h_{s}\\right)} + + \\mathcal{O}\\left(\\frac{h_{d}h_{s}^{2} + + h_{s}h_{d}^{2}}{h_{d} + + h_{s}}\\right) + + It is worth noting that if :math:`h_{s}=h_{d}` + (i.e., data are evenly spaced) + we find the standard second order approximation: + + .. math:: + + \\hat f_{i}^{(1)}= + \\frac{f\\left(x_{i+1}\\right) - f\\left(x_{i-1}\\right)}{2h} + + \\mathcal{O}\\left(h^{2}\\right) + + With a similar procedure the forward/backward approximations used for + boundaries can be derived. + + References + ---------- + .. [1] Quarteroni A., Sacco R., Saleri F. (2007) Numerical Mathematics + (Texts in Applied Mathematics). New York: Springer. + .. [2] Durran D. R. (1999) Numerical Methods for Wave Equations + in Geophysical Fluid Dynamics. New York: Springer. + .. [3] Fornberg B. (1988) Generation of Finite Difference Formulas on + Arbitrarily Spaced Grids, + Mathematics of Computation 51, no. 184 : 699-706. + `PDF `_. + """ + f = np.asanyarray(f) + N = f.ndim # number of dimensions + + if axis is None: + axes = tuple(range(N)) + else: + axes = _nx.normalize_axis_tuple(axis, N) + + len_axes = len(axes) + n = len(varargs) + if n == 0: + # no spacing argument - use 1 in all axes + dx = [1.0] * len_axes + elif n == 1 and np.ndim(varargs[0]) == 0: + # single scalar for all axes + dx = varargs * len_axes + elif n == len_axes: + # scalar or 1d array for each axis + dx = list(varargs) + for i, distances in enumerate(dx): + distances = np.asanyarray(distances) + if distances.ndim == 0: + continue + elif distances.ndim != 1: + raise ValueError("distances must be either scalars or 1d") + if len(distances) != f.shape[axes[i]]: + raise ValueError("when 1d, distances must match " + "the length of the corresponding dimension") + if np.issubdtype(distances.dtype, np.integer): + # Convert numpy integer types to float64 to avoid modular + # arithmetic in np.diff(distances). + distances = distances.astype(np.float64) + diffx = np.diff(distances) + # if distances are constant reduce to the scalar case + # since it brings a consistent speedup + if (diffx == diffx[0]).all(): + diffx = diffx[0] + dx[i] = diffx + else: + raise TypeError("invalid number of arguments") + + if edge_order > 2: + raise ValueError("'edge_order' greater than 2 not supported") + + # use central differences on interior and one-sided differences on the + # endpoints. This preserves second order-accuracy over the full domain. + + outvals = [] + + # create slice objects --- initially all are [:, :, ..., :] + slice1 = [slice(None)]*N + slice2 = [slice(None)]*N + slice3 = [slice(None)]*N + slice4 = [slice(None)]*N + + otype = f.dtype + if otype.type is np.datetime64: + # the timedelta dtype with the same unit information + otype = np.dtype(otype.name.replace('datetime', 'timedelta')) + # view as timedelta to allow addition + f = f.view(otype) + elif otype.type is np.timedelta64: + pass + elif np.issubdtype(otype, np.inexact): + pass + else: + # All other types convert to floating point. + # First check if f is a numpy integer type; if so, convert f to float64 + # to avoid modular arithmetic when computing the changes in f. + if np.issubdtype(otype, np.integer): + f = f.astype(np.float64) + otype = np.float64 + + for axis, ax_dx in zip(axes, dx): + if f.shape[axis] < edge_order + 1: + raise ValueError( + "Shape of array too small to calculate a numerical gradient, " + "at least (edge_order + 1) elements are required.") + # result allocation + out = np.empty_like(f, dtype=otype) + + # spacing for the current axis + uniform_spacing = np.ndim(ax_dx) == 0 + + # Numerical differentiation: 2nd order interior + slice1[axis] = slice(1, -1) + slice2[axis] = slice(None, -2) + slice3[axis] = slice(1, -1) + slice4[axis] = slice(2, None) + + if uniform_spacing: + out[tuple(slice1)] = (f[tuple(slice4)] - f[tuple(slice2)]) / (2. * ax_dx) + else: + dx1 = ax_dx[0:-1] + dx2 = ax_dx[1:] + a = -(dx2)/(dx1 * (dx1 + dx2)) + b = (dx2 - dx1) / (dx1 * dx2) + c = dx1 / (dx2 * (dx1 + dx2)) + # fix the shape for broadcasting + shape = np.ones(N, dtype=int) + shape[axis] = -1 + a.shape = b.shape = c.shape = shape + # 1D equivalent -- out[1:-1] = a * f[:-2] + b * f[1:-1] + c * f[2:] + out[tuple(slice1)] = a * f[tuple(slice2)] + b * f[tuple(slice3)] + c * f[tuple(slice4)] + + # Numerical differentiation: 1st order edges + if edge_order == 1: + slice1[axis] = 0 + slice2[axis] = 1 + slice3[axis] = 0 + dx_0 = ax_dx if uniform_spacing else ax_dx[0] + # 1D equivalent -- out[0] = (f[1] - f[0]) / (x[1] - x[0]) + out[tuple(slice1)] = (f[tuple(slice2)] - f[tuple(slice3)]) / dx_0 + + slice1[axis] = -1 + slice2[axis] = -1 + slice3[axis] = -2 + dx_n = ax_dx if uniform_spacing else ax_dx[-1] + # 1D equivalent -- out[-1] = (f[-1] - f[-2]) / (x[-1] - x[-2]) + out[tuple(slice1)] = (f[tuple(slice2)] - f[tuple(slice3)]) / dx_n + + # Numerical differentiation: 2nd order edges + else: + slice1[axis] = 0 + slice2[axis] = 0 + slice3[axis] = 1 + slice4[axis] = 2 + if uniform_spacing: + a = -1.5 / ax_dx + b = 2. / ax_dx + c = -0.5 / ax_dx + else: + dx1 = ax_dx[0] + dx2 = ax_dx[1] + a = -(2. * dx1 + dx2)/(dx1 * (dx1 + dx2)) + b = (dx1 + dx2) / (dx1 * dx2) + c = - dx1 / (dx2 * (dx1 + dx2)) + # 1D equivalent -- out[0] = a * f[0] + b * f[1] + c * f[2] + out[tuple(slice1)] = a * f[tuple(slice2)] + b * f[tuple(slice3)] + c * f[tuple(slice4)] + + slice1[axis] = -1 + slice2[axis] = -3 + slice3[axis] = -2 + slice4[axis] = -1 + if uniform_spacing: + a = 0.5 / ax_dx + b = -2. / ax_dx + c = 1.5 / ax_dx + else: + dx1 = ax_dx[-2] + dx2 = ax_dx[-1] + a = (dx2) / (dx1 * (dx1 + dx2)) + b = - (dx2 + dx1) / (dx1 * dx2) + c = (2. * dx2 + dx1) / (dx2 * (dx1 + dx2)) + # 1D equivalent -- out[-1] = a * f[-3] + b * f[-2] + c * f[-1] + out[tuple(slice1)] = a * f[tuple(slice2)] + b * f[tuple(slice3)] + c * f[tuple(slice4)] + + outvals.append(out) + + # reset the slice object in this dimension to ":" + slice1[axis] = slice(None) + slice2[axis] = slice(None) + slice3[axis] = slice(None) + slice4[axis] = slice(None) + + if len_axes == 1: + return outvals[0] + else: + return outvals + + +def _diff_dispatcher(a, n=None, axis=None, prepend=None, append=None): + return (a, prepend, append) + + +@array_function_dispatch(_diff_dispatcher) +def diff(a, n=1, axis=-1, prepend=np._NoValue, append=np._NoValue): + """ + Calculate the n-th discrete difference along the given axis. + + The first difference is given by ``out[i] = a[i+1] - a[i]`` along + the given axis, higher differences are calculated by using `diff` + recursively. + + Parameters + ---------- + a : array_like + Input array + n : int, optional + The number of times values are differenced. If zero, the input + is returned as-is. + axis : int, optional + The axis along which the difference is taken, default is the + last axis. + prepend, append : array_like, optional + Values to prepend or append to `a` along axis prior to + performing the difference. Scalar values are expanded to + arrays with length 1 in the direction of axis and the shape + of the input array in along all other axes. Otherwise the + dimension and shape must match `a` except along axis. + + .. versionadded:: 1.16.0 + + Returns + ------- + diff : ndarray + The n-th differences. The shape of the output is the same as `a` + except along `axis` where the dimension is smaller by `n`. The + type of the output is the same as the type of the difference + between any two elements of `a`. This is the same as the type of + `a` in most cases. A notable exception is `datetime64`, which + results in a `timedelta64` output array. + + See Also + -------- + gradient, ediff1d, cumsum + + Notes + ----- + Type is preserved for boolean arrays, so the result will contain + `False` when consecutive elements are the same and `True` when they + differ. + + For unsigned integer arrays, the results will also be unsigned. This + should not be surprising, as the result is consistent with + calculating the difference directly: + + >>> u8_arr = np.array([1, 0], dtype=np.uint8) + >>> np.diff(u8_arr) + array([255], dtype=uint8) + >>> u8_arr[1,...] - u8_arr[0,...] + 255 + + If this is not desirable, then the array should be cast to a larger + integer type first: + + >>> i16_arr = u8_arr.astype(np.int16) + >>> np.diff(i16_arr) + array([-1], dtype=int16) + + Examples + -------- + >>> x = np.array([1, 2, 4, 7, 0]) + >>> np.diff(x) + array([ 1, 2, 3, -7]) + >>> np.diff(x, n=2) + array([ 1, 1, -10]) + + >>> x = np.array([[1, 3, 6, 10], [0, 5, 6, 8]]) + >>> np.diff(x) + array([[2, 3, 4], + [5, 1, 2]]) + >>> np.diff(x, axis=0) + array([[-1, 2, 0, -2]]) + + >>> x = np.arange('1066-10-13', '1066-10-16', dtype=np.datetime64) + >>> np.diff(x) + array([1, 1], dtype='timedelta64[D]') + + """ + if n == 0: + return a + if n < 0: + raise ValueError( + "order must be non-negative but got " + repr(n)) + + a = asanyarray(a) + nd = a.ndim + if nd == 0: + raise ValueError("diff requires input that is at least one dimensional") + axis = normalize_axis_index(axis, nd) + + combined = [] + if prepend is not np._NoValue: + prepend = np.asanyarray(prepend) + if prepend.ndim == 0: + shape = list(a.shape) + shape[axis] = 1 + prepend = np.broadcast_to(prepend, tuple(shape)) + combined.append(prepend) + + combined.append(a) + + if append is not np._NoValue: + append = np.asanyarray(append) + if append.ndim == 0: + shape = list(a.shape) + shape[axis] = 1 + append = np.broadcast_to(append, tuple(shape)) + combined.append(append) + + if len(combined) > 1: + a = np.concatenate(combined, axis) + + slice1 = [slice(None)] * nd + slice2 = [slice(None)] * nd + slice1[axis] = slice(1, None) + slice2[axis] = slice(None, -1) + slice1 = tuple(slice1) + slice2 = tuple(slice2) + + op = not_equal if a.dtype == np.bool_ else subtract + for _ in range(n): + a = op(a[slice1], a[slice2]) + + return a + + +def _interp_dispatcher(x, xp, fp, left=None, right=None, period=None): + return (x, xp, fp) + + +@array_function_dispatch(_interp_dispatcher) +def interp(x, xp, fp, left=None, right=None, period=None): + """ + One-dimensional linear interpolation. + + Returns the one-dimensional piecewise linear interpolant to a function + with given discrete data points (`xp`, `fp`), evaluated at `x`. + + Parameters + ---------- + x : array_like + The x-coordinates at which to evaluate the interpolated values. + + xp : 1-D sequence of floats + The x-coordinates of the data points, must be increasing if argument + `period` is not specified. Otherwise, `xp` is internally sorted after + normalizing the periodic boundaries with ``xp = xp % period``. + + fp : 1-D sequence of float or complex + The y-coordinates of the data points, same length as `xp`. + + left : optional float or complex corresponding to fp + Value to return for `x < xp[0]`, default is `fp[0]`. + + right : optional float or complex corresponding to fp + Value to return for `x > xp[-1]`, default is `fp[-1]`. + + period : None or float, optional + A period for the x-coordinates. This parameter allows the proper + interpolation of angular x-coordinates. Parameters `left` and `right` + are ignored if `period` is specified. + + .. versionadded:: 1.10.0 + + Returns + ------- + y : float or complex (corresponding to fp) or ndarray + The interpolated values, same shape as `x`. + + Raises + ------ + ValueError + If `xp` and `fp` have different length + If `xp` or `fp` are not 1-D sequences + If `period == 0` + + See Also + -------- + scipy.interpolate + + Notes + ----- + The x-coordinate sequence is expected to be increasing, but this is not + explicitly enforced. However, if the sequence `xp` is non-increasing, + interpolation results are meaningless. + + Note that, since NaN is unsortable, `xp` also cannot contain NaNs. + + A simple check for `xp` being strictly increasing is:: + + np.all(np.diff(xp) > 0) + + Examples + -------- + >>> xp = [1, 2, 3] + >>> fp = [3, 2, 0] + >>> np.interp(2.5, xp, fp) + 1.0 + >>> np.interp([0, 1, 1.5, 2.72, 3.14], xp, fp) + array([3. , 3. , 2.5 , 0.56, 0. ]) + >>> UNDEF = -99.0 + >>> np.interp(3.14, xp, fp, right=UNDEF) + -99.0 + + Plot an interpolant to the sine function: + + >>> x = np.linspace(0, 2*np.pi, 10) + >>> y = np.sin(x) + >>> xvals = np.linspace(0, 2*np.pi, 50) + >>> yinterp = np.interp(xvals, x, y) + >>> import matplotlib.pyplot as plt + >>> plt.plot(x, y, 'o') + [] + >>> plt.plot(xvals, yinterp, '-x') + [] + >>> plt.show() + + Interpolation with periodic x-coordinates: + + >>> x = [-180, -170, -185, 185, -10, -5, 0, 365] + >>> xp = [190, -190, 350, -350] + >>> fp = [5, 10, 3, 4] + >>> np.interp(x, xp, fp, period=360) + array([7.5 , 5. , 8.75, 6.25, 3. , 3.25, 3.5 , 3.75]) + + Complex interpolation: + + >>> x = [1.5, 4.0] + >>> xp = [2,3,5] + >>> fp = [1.0j, 0, 2+3j] + >>> np.interp(x, xp, fp) + array([0.+1.j , 1.+1.5j]) + + """ + + fp = np.asarray(fp) + + if np.iscomplexobj(fp): + interp_func = compiled_interp_complex + input_dtype = np.complex128 + else: + interp_func = compiled_interp + input_dtype = np.float64 + + if period is not None: + if period == 0: + raise ValueError("period must be a non-zero value") + period = abs(period) + left = None + right = None + + x = np.asarray(x, dtype=np.float64) + xp = np.asarray(xp, dtype=np.float64) + fp = np.asarray(fp, dtype=input_dtype) + + if xp.ndim != 1 or fp.ndim != 1: + raise ValueError("Data points must be 1-D sequences") + if xp.shape[0] != fp.shape[0]: + raise ValueError("fp and xp are not of the same length") + # normalizing periodic boundaries + x = x % period + xp = xp % period + asort_xp = np.argsort(xp) + xp = xp[asort_xp] + fp = fp[asort_xp] + xp = np.concatenate((xp[-1:]-period, xp, xp[0:1]+period)) + fp = np.concatenate((fp[-1:], fp, fp[0:1])) + + return interp_func(x, xp, fp, left, right) + + +def _angle_dispatcher(z, deg=None): + return (z,) + + +@array_function_dispatch(_angle_dispatcher) +def angle(z, deg=False): + """ + Return the angle of the complex argument. + + Parameters + ---------- + z : array_like + A complex number or sequence of complex numbers. + deg : bool, optional + Return angle in degrees if True, radians if False (default). + + Returns + ------- + angle : ndarray or scalar + The counterclockwise angle from the positive real axis on the complex + plane in the range ``(-pi, pi]``, with dtype as numpy.float64. + + .. versionchanged:: 1.16.0 + This function works on subclasses of ndarray like `ma.array`. + + See Also + -------- + arctan2 + absolute + + Notes + ----- + Although the angle of the complex number 0 is undefined, ``numpy.angle(0)`` + returns the value 0. + + Examples + -------- + >>> np.angle([1.0, 1.0j, 1+1j]) # in radians + array([ 0. , 1.57079633, 0.78539816]) # may vary + >>> np.angle(1+1j, deg=True) # in degrees + 45.0 + + """ + z = asanyarray(z) + if issubclass(z.dtype.type, _nx.complexfloating): + zimag = z.imag + zreal = z.real + else: + zimag = 0 + zreal = z + + a = arctan2(zimag, zreal) + if deg: + a *= 180/pi + return a + + +def _unwrap_dispatcher(p, discont=None, axis=None): + return (p,) + + +@array_function_dispatch(_unwrap_dispatcher) +def unwrap(p, discont=pi, axis=-1): + """ + Unwrap by changing deltas between values to 2*pi complement. + + Unwrap radian phase `p` by changing absolute jumps greater than + `discont` to their 2*pi complement along the given axis. + + Parameters + ---------- + p : array_like + Input array. + discont : float, optional + Maximum discontinuity between values, default is ``pi``. + axis : int, optional + Axis along which unwrap will operate, default is the last axis. + + Returns + ------- + out : ndarray + Output array. + + See Also + -------- + rad2deg, deg2rad + + Notes + ----- + If the discontinuity in `p` is smaller than ``pi``, but larger than + `discont`, no unwrapping is done because taking the 2*pi complement + would only make the discontinuity larger. + + Examples + -------- + >>> phase = np.linspace(0, np.pi, num=5) + >>> phase[3:] += np.pi + >>> phase + array([ 0. , 0.78539816, 1.57079633, 5.49778714, 6.28318531]) # may vary + >>> np.unwrap(phase) + array([ 0. , 0.78539816, 1.57079633, -0.78539816, 0. ]) # may vary + + """ + p = asarray(p) + nd = p.ndim + dd = diff(p, axis=axis) + slice1 = [slice(None, None)]*nd # full slices + slice1[axis] = slice(1, None) + slice1 = tuple(slice1) + ddmod = mod(dd + pi, 2*pi) - pi + _nx.copyto(ddmod, pi, where=(ddmod == -pi) & (dd > 0)) + ph_correct = ddmod - dd + _nx.copyto(ph_correct, 0, where=abs(dd) < discont) + up = array(p, copy=True, dtype='d') + up[slice1] = p[slice1] + ph_correct.cumsum(axis) + return up + + +def _sort_complex(a): + return (a,) + + +@array_function_dispatch(_sort_complex) +def sort_complex(a): + """ + Sort a complex array using the real part first, then the imaginary part. + + Parameters + ---------- + a : array_like + Input array + + Returns + ------- + out : complex ndarray + Always returns a sorted complex array. + + Examples + -------- + >>> np.sort_complex([5, 3, 6, 2, 1]) + array([1.+0.j, 2.+0.j, 3.+0.j, 5.+0.j, 6.+0.j]) + + >>> np.sort_complex([1 + 2j, 2 - 1j, 3 - 2j, 3 - 3j, 3 + 5j]) + array([1.+2.j, 2.-1.j, 3.-3.j, 3.-2.j, 3.+5.j]) + + """ + b = array(a, copy=True) + b.sort() + if not issubclass(b.dtype.type, _nx.complexfloating): + if b.dtype.char in 'bhBH': + return b.astype('F') + elif b.dtype.char == 'g': + return b.astype('G') + else: + return b.astype('D') + else: + return b + + +def _trim_zeros(filt, trim=None): + return (filt,) + + +@array_function_dispatch(_trim_zeros) +def trim_zeros(filt, trim='fb'): + """ + Trim the leading and/or trailing zeros from a 1-D array or sequence. + + Parameters + ---------- + filt : 1-D array or sequence + Input array. + trim : str, optional + A string with 'f' representing trim from front and 'b' to trim from + back. Default is 'fb', trim zeros from both front and back of the + array. + + Returns + ------- + trimmed : 1-D array or sequence + The result of trimming the input. The input data type is preserved. + + Examples + -------- + >>> a = np.array((0, 0, 0, 1, 2, 3, 0, 2, 1, 0)) + >>> np.trim_zeros(a) + array([1, 2, 3, 0, 2, 1]) + + >>> np.trim_zeros(a, 'b') + array([0, 0, 0, ..., 0, 2, 1]) + + The input data type is preserved, list/tuple in means list/tuple out. + + >>> np.trim_zeros([0, 1, 2, 0]) + [1, 2] + + """ + + first = 0 + trim = trim.upper() + if 'F' in trim: + for i in filt: + if i != 0.: + break + else: + first = first + 1 + last = len(filt) + if 'B' in trim: + for i in filt[::-1]: + if i != 0.: + break + else: + last = last - 1 + return filt[first:last] + + +def _extract_dispatcher(condition, arr): + return (condition, arr) + + +@array_function_dispatch(_extract_dispatcher) +def extract(condition, arr): + """ + Return the elements of an array that satisfy some condition. + + This is equivalent to ``np.compress(ravel(condition), ravel(arr))``. If + `condition` is boolean ``np.extract`` is equivalent to ``arr[condition]``. + + Note that `place` does the exact opposite of `extract`. + + Parameters + ---------- + condition : array_like + An array whose nonzero or True entries indicate the elements of `arr` + to extract. + arr : array_like + Input array of the same size as `condition`. + + Returns + ------- + extract : ndarray + Rank 1 array of values from `arr` where `condition` is True. + + See Also + -------- + take, put, copyto, compress, place + + Examples + -------- + >>> arr = np.arange(12).reshape((3, 4)) + >>> arr + array([[ 0, 1, 2, 3], + [ 4, 5, 6, 7], + [ 8, 9, 10, 11]]) + >>> condition = np.mod(arr, 3)==0 + >>> condition + array([[ True, False, False, True], + [False, False, True, False], + [False, True, False, False]]) + >>> np.extract(condition, arr) + array([0, 3, 6, 9]) + + + If `condition` is boolean: + + >>> arr[condition] + array([0, 3, 6, 9]) + + """ + return _nx.take(ravel(arr), nonzero(ravel(condition))[0]) + + +def _place_dispatcher(arr, mask, vals): + return (arr, mask, vals) + + +@array_function_dispatch(_place_dispatcher) +def place(arr, mask, vals): + """ + Change elements of an array based on conditional and input values. + + Similar to ``np.copyto(arr, vals, where=mask)``, the difference is that + `place` uses the first N elements of `vals`, where N is the number of + True values in `mask`, while `copyto` uses the elements where `mask` + is True. + + Note that `extract` does the exact opposite of `place`. + + Parameters + ---------- + arr : ndarray + Array to put data into. + mask : array_like + Boolean mask array. Must have the same size as `a`. + vals : 1-D sequence + Values to put into `a`. Only the first N elements are used, where + N is the number of True values in `mask`. If `vals` is smaller + than N, it will be repeated, and if elements of `a` are to be masked, + this sequence must be non-empty. + + See Also + -------- + copyto, put, take, extract + + Examples + -------- + >>> arr = np.arange(6).reshape(2, 3) + >>> np.place(arr, arr>2, [44, 55]) + >>> arr + array([[ 0, 1, 2], + [44, 55, 44]]) + + """ + if not isinstance(arr, np.ndarray): + raise TypeError("argument 1 must be numpy.ndarray, " + "not {name}".format(name=type(arr).__name__)) + + return _insert(arr, mask, vals) + + +def disp(mesg, device=None, linefeed=True): + """ + Display a message on a device. + + Parameters + ---------- + mesg : str + Message to display. + device : object + Device to write message. If None, defaults to ``sys.stdout`` which is + very similar to ``print``. `device` needs to have ``write()`` and + ``flush()`` methods. + linefeed : bool, optional + Option whether to print a line feed or not. Defaults to True. + + Raises + ------ + AttributeError + If `device` does not have a ``write()`` or ``flush()`` method. + + Examples + -------- + Besides ``sys.stdout``, a file-like object can also be used as it has + both required methods: + + >>> from io import StringIO + >>> buf = StringIO() + >>> np.disp(u'"Display" in a file', device=buf) + >>> buf.getvalue() + '"Display" in a file\\n' + + """ + if device is None: + device = sys.stdout + if linefeed: + device.write('%s\n' % mesg) + else: + device.write('%s' % mesg) + device.flush() + return + + +# See https://docs.scipy.org/doc/numpy/reference/c-api.generalized-ufuncs.html +_DIMENSION_NAME = r'\w+' +_CORE_DIMENSION_LIST = '(?:{0:}(?:,{0:})*)?'.format(_DIMENSION_NAME) +_ARGUMENT = r'\({}\)'.format(_CORE_DIMENSION_LIST) +_ARGUMENT_LIST = '{0:}(?:,{0:})*'.format(_ARGUMENT) +_SIGNATURE = '^{0:}->{0:}$'.format(_ARGUMENT_LIST) + + +def _parse_gufunc_signature(signature): + """ + Parse string signatures for a generalized universal function. + + Arguments + --------- + signature : string + Generalized universal function signature, e.g., ``(m,n),(n,p)->(m,p)`` + for ``np.matmul``. + + Returns + ------- + Tuple of input and output core dimensions parsed from the signature, each + of the form List[Tuple[str, ...]]. + """ + if not re.match(_SIGNATURE, signature): + raise ValueError( + 'not a valid gufunc signature: {}'.format(signature)) + return tuple([tuple(re.findall(_DIMENSION_NAME, arg)) + for arg in re.findall(_ARGUMENT, arg_list)] + for arg_list in signature.split('->')) + + +def _update_dim_sizes(dim_sizes, arg, core_dims): + """ + Incrementally check and update core dimension sizes for a single argument. + + Arguments + --------- + dim_sizes : Dict[str, int] + Sizes of existing core dimensions. Will be updated in-place. + arg : ndarray + Argument to examine. + core_dims : Tuple[str, ...] + Core dimensions for this argument. + """ + if not core_dims: + return + + num_core_dims = len(core_dims) + if arg.ndim < num_core_dims: + raise ValueError( + '%d-dimensional argument does not have enough ' + 'dimensions for all core dimensions %r' + % (arg.ndim, core_dims)) + + core_shape = arg.shape[-num_core_dims:] + for dim, size in zip(core_dims, core_shape): + if dim in dim_sizes: + if size != dim_sizes[dim]: + raise ValueError( + 'inconsistent size for core dimension %r: %r vs %r' + % (dim, size, dim_sizes[dim])) + else: + dim_sizes[dim] = size + + +def _parse_input_dimensions(args, input_core_dims): + """ + Parse broadcast and core dimensions for vectorize with a signature. + + Arguments + --------- + args : Tuple[ndarray, ...] + Tuple of input arguments to examine. + input_core_dims : List[Tuple[str, ...]] + List of core dimensions corresponding to each input. + + Returns + ------- + broadcast_shape : Tuple[int, ...] + Common shape to broadcast all non-core dimensions to. + dim_sizes : Dict[str, int] + Common sizes for named core dimensions. + """ + broadcast_args = [] + dim_sizes = {} + for arg, core_dims in zip(args, input_core_dims): + _update_dim_sizes(dim_sizes, arg, core_dims) + ndim = arg.ndim - len(core_dims) + dummy_array = np.lib.stride_tricks.as_strided(0, arg.shape[:ndim]) + broadcast_args.append(dummy_array) + broadcast_shape = np.lib.stride_tricks._broadcast_shape(*broadcast_args) + return broadcast_shape, dim_sizes + + +def _calculate_shapes(broadcast_shape, dim_sizes, list_of_core_dims): + """Helper for calculating broadcast shapes with core dimensions.""" + return [broadcast_shape + tuple(dim_sizes[dim] for dim in core_dims) + for core_dims in list_of_core_dims] + + +def _create_arrays(broadcast_shape, dim_sizes, list_of_core_dims, dtypes): + """Helper for creating output arrays in vectorize.""" + shapes = _calculate_shapes(broadcast_shape, dim_sizes, list_of_core_dims) + arrays = tuple(np.empty(shape, dtype=dtype) + for shape, dtype in zip(shapes, dtypes)) + return arrays + + +@set_module('numpy') +class vectorize: + """ + vectorize(pyfunc, otypes=None, doc=None, excluded=None, cache=False, + signature=None) + + Generalized function class. + + Define a vectorized function which takes a nested sequence of objects or + numpy arrays as inputs and returns a single numpy array or a tuple of numpy + arrays. The vectorized function evaluates `pyfunc` over successive tuples + of the input arrays like the python map function, except it uses the + broadcasting rules of numpy. + + The data type of the output of `vectorized` is determined by calling + the function with the first element of the input. This can be avoided + by specifying the `otypes` argument. + + Parameters + ---------- + pyfunc : callable + A python function or method. + otypes : str or list of dtypes, optional + The output data type. It must be specified as either a string of + typecode characters or a list of data type specifiers. There should + be one data type specifier for each output. + doc : str, optional + The docstring for the function. If None, the docstring will be the + ``pyfunc.__doc__``. + excluded : set, optional + Set of strings or integers representing the positional or keyword + arguments for which the function will not be vectorized. These will be + passed directly to `pyfunc` unmodified. + + .. versionadded:: 1.7.0 + + cache : bool, optional + If `True`, then cache the first function call that determines the number + of outputs if `otypes` is not provided. + + .. versionadded:: 1.7.0 + + signature : string, optional + Generalized universal function signature, e.g., ``(m,n),(n)->(m)`` for + vectorized matrix-vector multiplication. If provided, ``pyfunc`` will + be called with (and expected to return) arrays with shapes given by the + size of corresponding core dimensions. By default, ``pyfunc`` is + assumed to take scalars as input and output. + + .. versionadded:: 1.12.0 + + Returns + ------- + vectorized : callable + Vectorized function. + + See Also + -------- + frompyfunc : Takes an arbitrary Python function and returns a ufunc + + Notes + ----- + The `vectorize` function is provided primarily for convenience, not for + performance. The implementation is essentially a for loop. + + If `otypes` is not specified, then a call to the function with the + first argument will be used to determine the number of outputs. The + results of this call will be cached if `cache` is `True` to prevent + calling the function twice. However, to implement the cache, the + original function must be wrapped which will slow down subsequent + calls, so only do this if your function is expensive. + + The new keyword argument interface and `excluded` argument support + further degrades performance. + + References + ---------- + .. [1] :doc:`/reference/c-api/generalized-ufuncs` + + Examples + -------- + >>> def myfunc(a, b): + ... "Return a-b if a>b, otherwise return a+b" + ... if a > b: + ... return a - b + ... else: + ... return a + b + + >>> vfunc = np.vectorize(myfunc) + >>> vfunc([1, 2, 3, 4], 2) + array([3, 4, 1, 2]) + + The docstring is taken from the input function to `vectorize` unless it + is specified: + + >>> vfunc.__doc__ + 'Return a-b if a>b, otherwise return a+b' + >>> vfunc = np.vectorize(myfunc, doc='Vectorized `myfunc`') + >>> vfunc.__doc__ + 'Vectorized `myfunc`' + + The output type is determined by evaluating the first element of the input, + unless it is specified: + + >>> out = vfunc([1, 2, 3, 4], 2) + >>> type(out[0]) + + >>> vfunc = np.vectorize(myfunc, otypes=[float]) + >>> out = vfunc([1, 2, 3, 4], 2) + >>> type(out[0]) + + + The `excluded` argument can be used to prevent vectorizing over certain + arguments. This can be useful for array-like arguments of a fixed length + such as the coefficients for a polynomial as in `polyval`: + + >>> def mypolyval(p, x): + ... _p = list(p) + ... res = _p.pop(0) + ... while _p: + ... res = res*x + _p.pop(0) + ... return res + >>> vpolyval = np.vectorize(mypolyval, excluded=['p']) + >>> vpolyval(p=[1, 2, 3], x=[0, 1]) + array([3, 6]) + + Positional arguments may also be excluded by specifying their position: + + >>> vpolyval.excluded.add(0) + >>> vpolyval([1, 2, 3], x=[0, 1]) + array([3, 6]) + + The `signature` argument allows for vectorizing functions that act on + non-scalar arrays of fixed length. For example, you can use it for a + vectorized calculation of Pearson correlation coefficient and its p-value: + + >>> import scipy.stats + >>> pearsonr = np.vectorize(scipy.stats.pearsonr, + ... signature='(n),(n)->(),()') + >>> pearsonr([[0, 1, 2, 3]], [[1, 2, 3, 4], [4, 3, 2, 1]]) + (array([ 1., -1.]), array([ 0., 0.])) + + Or for a vectorized convolution: + + >>> convolve = np.vectorize(np.convolve, signature='(n),(m)->(k)') + >>> convolve(np.eye(4), [1, 2, 1]) + array([[1., 2., 1., 0., 0., 0.], + [0., 1., 2., 1., 0., 0.], + [0., 0., 1., 2., 1., 0.], + [0., 0., 0., 1., 2., 1.]]) + + """ + def __init__(self, pyfunc, otypes=None, doc=None, excluded=None, + cache=False, signature=None): + self.pyfunc = pyfunc + self.cache = cache + self.signature = signature + self._ufunc = {} # Caching to improve default performance + + if doc is None: + self.__doc__ = pyfunc.__doc__ + else: + self.__doc__ = doc + + if isinstance(otypes, str): + for char in otypes: + if char not in typecodes['All']: + raise ValueError("Invalid otype specified: %s" % (char,)) + elif iterable(otypes): + otypes = ''.join([_nx.dtype(x).char for x in otypes]) + elif otypes is not None: + raise ValueError("Invalid otype specification") + self.otypes = otypes + + # Excluded variable support + if excluded is None: + excluded = set() + self.excluded = set(excluded) + + if signature is not None: + self._in_and_out_core_dims = _parse_gufunc_signature(signature) + else: + self._in_and_out_core_dims = None + + def __call__(self, *args, **kwargs): + """ + Return arrays with the results of `pyfunc` broadcast (vectorized) over + `args` and `kwargs` not in `excluded`. + """ + excluded = self.excluded + if not kwargs and not excluded: + func = self.pyfunc + vargs = args + else: + # The wrapper accepts only positional arguments: we use `names` and + # `inds` to mutate `the_args` and `kwargs` to pass to the original + # function. + nargs = len(args) + + names = [_n for _n in kwargs if _n not in excluded] + inds = [_i for _i in range(nargs) if _i not in excluded] + the_args = list(args) + + def func(*vargs): + for _n, _i in enumerate(inds): + the_args[_i] = vargs[_n] + kwargs.update(zip(names, vargs[len(inds):])) + return self.pyfunc(*the_args, **kwargs) + + vargs = [args[_i] for _i in inds] + vargs.extend([kwargs[_n] for _n in names]) + + return self._vectorize_call(func=func, args=vargs) + + def _get_ufunc_and_otypes(self, func, args): + """Return (ufunc, otypes).""" + # frompyfunc will fail if args is empty + if not args: + raise ValueError('args can not be empty') + + if self.otypes is not None: + otypes = self.otypes + + # self._ufunc is a dictionary whose keys are the number of + # arguments (i.e. len(args)) and whose values are ufuncs created + # by frompyfunc. len(args) can be different for different calls if + # self.pyfunc has parameters with default values. We only use the + # cache when func is self.pyfunc, which occurs when the call uses + # only positional arguments and no arguments are excluded. + + nin = len(args) + nout = len(self.otypes) + if func is not self.pyfunc or nin not in self._ufunc: + ufunc = frompyfunc(func, nin, nout) + else: + ufunc = None # We'll get it from self._ufunc + if func is self.pyfunc: + ufunc = self._ufunc.setdefault(nin, ufunc) + else: + # Get number of outputs and output types by calling the function on + # the first entries of args. We also cache the result to prevent + # the subsequent call when the ufunc is evaluated. + # Assumes that ufunc first evaluates the 0th elements in the input + # arrays (the input values are not checked to ensure this) + args = [asarray(arg) for arg in args] + if builtins.any(arg.size == 0 for arg in args): + raise ValueError('cannot call `vectorize` on size 0 inputs ' + 'unless `otypes` is set') + + inputs = [arg.flat[0] for arg in args] + outputs = func(*inputs) + + # Performance note: profiling indicates that -- for simple + # functions at least -- this wrapping can almost double the + # execution time. + # Hence we make it optional. + if self.cache: + _cache = [outputs] + + def _func(*vargs): + if _cache: + return _cache.pop() + else: + return func(*vargs) + else: + _func = func + + if isinstance(outputs, tuple): + nout = len(outputs) + else: + nout = 1 + outputs = (outputs,) + + otypes = ''.join([asarray(outputs[_k]).dtype.char + for _k in range(nout)]) + + # Performance note: profiling indicates that creating the ufunc is + # not a significant cost compared with wrapping so it seems not + # worth trying to cache this. + ufunc = frompyfunc(_func, len(args), nout) + + return ufunc, otypes + + def _vectorize_call(self, func, args): + """Vectorized call to `func` over positional `args`.""" + if self.signature is not None: + res = self._vectorize_call_with_signature(func, args) + elif not args: + res = func() + else: + ufunc, otypes = self._get_ufunc_and_otypes(func=func, args=args) + + # Convert args to object arrays first + inputs = [array(a, copy=False, subok=True, dtype=object) + for a in args] + + outputs = ufunc(*inputs) + + if ufunc.nout == 1: + res = array(outputs, copy=False, subok=True, dtype=otypes[0]) + else: + res = tuple([array(x, copy=False, subok=True, dtype=t) + for x, t in zip(outputs, otypes)]) + return res + + def _vectorize_call_with_signature(self, func, args): + """Vectorized call over positional arguments with a signature.""" + input_core_dims, output_core_dims = self._in_and_out_core_dims + + if len(args) != len(input_core_dims): + raise TypeError('wrong number of positional arguments: ' + 'expected %r, got %r' + % (len(input_core_dims), len(args))) + args = tuple(asanyarray(arg) for arg in args) + + broadcast_shape, dim_sizes = _parse_input_dimensions( + args, input_core_dims) + input_shapes = _calculate_shapes(broadcast_shape, dim_sizes, + input_core_dims) + args = [np.broadcast_to(arg, shape, subok=True) + for arg, shape in zip(args, input_shapes)] + + outputs = None + otypes = self.otypes + nout = len(output_core_dims) + + for index in np.ndindex(*broadcast_shape): + results = func(*(arg[index] for arg in args)) + + n_results = len(results) if isinstance(results, tuple) else 1 + + if nout != n_results: + raise ValueError( + 'wrong number of outputs from pyfunc: expected %r, got %r' + % (nout, n_results)) + + if nout == 1: + results = (results,) + + if outputs is None: + for result, core_dims in zip(results, output_core_dims): + _update_dim_sizes(dim_sizes, result, core_dims) + + if otypes is None: + otypes = [asarray(result).dtype for result in results] + + outputs = _create_arrays(broadcast_shape, dim_sizes, + output_core_dims, otypes) + + for output, result in zip(outputs, results): + output[index] = result + + if outputs is None: + # did not call the function even once + if otypes is None: + raise ValueError('cannot call `vectorize` on size 0 inputs ' + 'unless `otypes` is set') + if builtins.any(dim not in dim_sizes + for dims in output_core_dims + for dim in dims): + raise ValueError('cannot call `vectorize` with a signature ' + 'including new output dimensions on size 0 ' + 'inputs') + outputs = _create_arrays(broadcast_shape, dim_sizes, + output_core_dims, otypes) + + return outputs[0] if nout == 1 else outputs + + +def _cov_dispatcher(m, y=None, rowvar=None, bias=None, ddof=None, + fweights=None, aweights=None, *, dtype=None): + return (m, y, fweights, aweights) + + +@array_function_dispatch(_cov_dispatcher) +def cov(m, y=None, rowvar=True, bias=False, ddof=None, fweights=None, + aweights=None, *, dtype=None): + """ + Estimate a covariance matrix, given data and weights. + + Covariance indicates the level to which two variables vary together. + If we examine N-dimensional samples, :math:`X = [x_1, x_2, ... x_N]^T`, + then the covariance matrix element :math:`C_{ij}` is the covariance of + :math:`x_i` and :math:`x_j`. The element :math:`C_{ii}` is the variance + of :math:`x_i`. + + See the notes for an outline of the algorithm. + + Parameters + ---------- + m : array_like + A 1-D or 2-D array containing multiple variables and observations. + Each row of `m` represents a variable, and each column a single + observation of all those variables. Also see `rowvar` below. + y : array_like, optional + An additional set of variables and observations. `y` has the same form + as that of `m`. + rowvar : bool, optional + If `rowvar` is True (default), then each row represents a + variable, with observations in the columns. Otherwise, the relationship + is transposed: each column represents a variable, while the rows + contain observations. + bias : bool, optional + Default normalization (False) is by ``(N - 1)``, where ``N`` is the + number of observations given (unbiased estimate). If `bias` is True, + then normalization is by ``N``. These values can be overridden by using + the keyword ``ddof`` in numpy versions >= 1.5. + ddof : int, optional + If not ``None`` the default value implied by `bias` is overridden. + Note that ``ddof=1`` will return the unbiased estimate, even if both + `fweights` and `aweights` are specified, and ``ddof=0`` will return + the simple average. See the notes for the details. The default value + is ``None``. + + .. versionadded:: 1.5 + fweights : array_like, int, optional + 1-D array of integer frequency weights; the number of times each + observation vector should be repeated. + + .. versionadded:: 1.10 + aweights : array_like, optional + 1-D array of observation vector weights. These relative weights are + typically large for observations considered "important" and smaller for + observations considered less "important". If ``ddof=0`` the array of + weights can be used to assign probabilities to observation vectors. + + .. versionadded:: 1.10 + dtype : data-type, optional + Data-type of the result. By default, the return data-type will have + at least `numpy.float64` precision. + + .. versionadded:: 1.20 + + Returns + ------- + out : ndarray + The covariance matrix of the variables. + + See Also + -------- + corrcoef : Normalized covariance matrix + + Notes + ----- + Assume that the observations are in the columns of the observation + array `m` and let ``f = fweights`` and ``a = aweights`` for brevity. The + steps to compute the weighted covariance are as follows:: + + >>> m = np.arange(10, dtype=np.float64) + >>> f = np.arange(10) * 2 + >>> a = np.arange(10) ** 2. + >>> ddof = 1 + >>> w = f * a + >>> v1 = np.sum(w) + >>> v2 = np.sum(w * a) + >>> m -= np.sum(m * w, axis=None, keepdims=True) / v1 + >>> cov = np.dot(m * w, m.T) * v1 / (v1**2 - ddof * v2) + + Note that when ``a == 1``, the normalization factor + ``v1 / (v1**2 - ddof * v2)`` goes over to ``1 / (np.sum(f) - ddof)`` + as it should. + + Examples + -------- + Consider two variables, :math:`x_0` and :math:`x_1`, which + correlate perfectly, but in opposite directions: + + >>> x = np.array([[0, 2], [1, 1], [2, 0]]).T + >>> x + array([[0, 1, 2], + [2, 1, 0]]) + + Note how :math:`x_0` increases while :math:`x_1` decreases. The covariance + matrix shows this clearly: + + >>> np.cov(x) + array([[ 1., -1.], + [-1., 1.]]) + + Note that element :math:`C_{0,1}`, which shows the correlation between + :math:`x_0` and :math:`x_1`, is negative. + + Further, note how `x` and `y` are combined: + + >>> x = [-2.1, -1, 4.3] + >>> y = [3, 1.1, 0.12] + >>> X = np.stack((x, y), axis=0) + >>> np.cov(X) + array([[11.71 , -4.286 ], # may vary + [-4.286 , 2.144133]]) + >>> np.cov(x, y) + array([[11.71 , -4.286 ], # may vary + [-4.286 , 2.144133]]) + >>> np.cov(x) + array(11.71) + + """ + # Check inputs + if ddof is not None and ddof != int(ddof): + raise ValueError( + "ddof must be integer") + + # Handles complex arrays too + m = np.asarray(m) + if m.ndim > 2: + raise ValueError("m has more than 2 dimensions") + + if y is not None: + y = np.asarray(y) + if y.ndim > 2: + raise ValueError("y has more than 2 dimensions") + + if dtype is None: + if y is None: + dtype = np.result_type(m, np.float64) + else: + dtype = np.result_type(m, y, np.float64) + + X = array(m, ndmin=2, dtype=dtype) + if not rowvar and X.shape[0] != 1: + X = X.T + if X.shape[0] == 0: + return np.array([]).reshape(0, 0) + if y is not None: + y = array(y, copy=False, ndmin=2, dtype=dtype) + if not rowvar and y.shape[0] != 1: + y = y.T + X = np.concatenate((X, y), axis=0) + + if ddof is None: + if bias == 0: + ddof = 1 + else: + ddof = 0 + + # Get the product of frequencies and weights + w = None + if fweights is not None: + fweights = np.asarray(fweights, dtype=float) + if not np.all(fweights == np.around(fweights)): + raise TypeError( + "fweights must be integer") + if fweights.ndim > 1: + raise RuntimeError( + "cannot handle multidimensional fweights") + if fweights.shape[0] != X.shape[1]: + raise RuntimeError( + "incompatible numbers of samples and fweights") + if any(fweights < 0): + raise ValueError( + "fweights cannot be negative") + w = fweights + if aweights is not None: + aweights = np.asarray(aweights, dtype=float) + if aweights.ndim > 1: + raise RuntimeError( + "cannot handle multidimensional aweights") + if aweights.shape[0] != X.shape[1]: + raise RuntimeError( + "incompatible numbers of samples and aweights") + if any(aweights < 0): + raise ValueError( + "aweights cannot be negative") + if w is None: + w = aweights + else: + w *= aweights + + avg, w_sum = average(X, axis=1, weights=w, returned=True) + w_sum = w_sum[0] + + # Determine the normalization + if w is None: + fact = X.shape[1] - ddof + elif ddof == 0: + fact = w_sum + elif aweights is None: + fact = w_sum - ddof + else: + fact = w_sum - ddof*sum(w*aweights)/w_sum + + if fact <= 0: + warnings.warn("Degrees of freedom <= 0 for slice", + RuntimeWarning, stacklevel=3) + fact = 0.0 + + X -= avg[:, None] + if w is None: + X_T = X.T + else: + X_T = (X*w).T + c = dot(X, X_T.conj()) + c *= np.true_divide(1, fact) + return c.squeeze() + + +def _corrcoef_dispatcher(x, y=None, rowvar=None, bias=None, ddof=None, *, + dtype=None): + return (x, y) + + +@array_function_dispatch(_corrcoef_dispatcher) +def corrcoef(x, y=None, rowvar=True, bias=np._NoValue, ddof=np._NoValue, *, + dtype=None): + """ + Return Pearson product-moment correlation coefficients. + + Please refer to the documentation for `cov` for more detail. The + relationship between the correlation coefficient matrix, `R`, and the + covariance matrix, `C`, is + + .. math:: R_{ij} = \\frac{ C_{ij} } { \\sqrt{ C_{ii} * C_{jj} } } + + The values of `R` are between -1 and 1, inclusive. + + Parameters + ---------- + x : array_like + A 1-D or 2-D array containing multiple variables and observations. + Each row of `x` represents a variable, and each column a single + observation of all those variables. Also see `rowvar` below. + y : array_like, optional + An additional set of variables and observations. `y` has the same + shape as `x`. + rowvar : bool, optional + If `rowvar` is True (default), then each row represents a + variable, with observations in the columns. Otherwise, the relationship + is transposed: each column represents a variable, while the rows + contain observations. + bias : _NoValue, optional + Has no effect, do not use. + + .. deprecated:: 1.10.0 + ddof : _NoValue, optional + Has no effect, do not use. + + .. deprecated:: 1.10.0 + dtype : data-type, optional + Data-type of the result. By default, the return data-type will have + at least `numpy.float64` precision. + + .. versionadded:: 1.20 + + Returns + ------- + R : ndarray + The correlation coefficient matrix of the variables. + + See Also + -------- + cov : Covariance matrix + + Notes + ----- + Due to floating point rounding the resulting array may not be Hermitian, + the diagonal elements may not be 1, and the elements may not satisfy the + inequality abs(a) <= 1. The real and imaginary parts are clipped to the + interval [-1, 1] in an attempt to improve on that situation but is not + much help in the complex case. + + This function accepts but discards arguments `bias` and `ddof`. This is + for backwards compatibility with previous versions of this function. These + arguments had no effect on the return values of the function and can be + safely ignored in this and previous versions of numpy. + + Examples + -------- + In this example we generate two random arrays, ``xarr`` and ``yarr``, and + compute the row-wise and column-wise Pearson correlation coefficients, + ``R``. Since ``rowvar`` is true by default, we first find the row-wise + Pearson correlation coefficients between the variables of ``xarr``. + + >>> import numpy as np + >>> rng = np.random.default_rng(seed=42) + >>> xarr = rng.random((3, 3)) + >>> xarr + array([[0.77395605, 0.43887844, 0.85859792], + [0.69736803, 0.09417735, 0.97562235], + [0.7611397 , 0.78606431, 0.12811363]]) + >>> R1 = np.corrcoef(xarr) + >>> R1 + array([[ 1. , 0.99256089, -0.68080986], + [ 0.99256089, 1. , -0.76492172], + [-0.68080986, -0.76492172, 1. ]]) + + If we add another set of variables and observations ``yarr``, we can + compute the row-wise Pearson correlation coefficients between the + variables in ``xarr`` and ``yarr``. + + >>> yarr = rng.random((3, 3)) + >>> yarr + array([[0.45038594, 0.37079802, 0.92676499], + [0.64386512, 0.82276161, 0.4434142 ], + [0.22723872, 0.55458479, 0.06381726]]) + >>> R2 = np.corrcoef(xarr, yarr) + >>> R2 + array([[ 1. , 0.99256089, -0.68080986, 0.75008178, -0.934284 , + -0.99004057], + [ 0.99256089, 1. , -0.76492172, 0.82502011, -0.97074098, + -0.99981569], + [-0.68080986, -0.76492172, 1. , -0.99507202, 0.89721355, + 0.77714685], + [ 0.75008178, 0.82502011, -0.99507202, 1. , -0.93657855, + -0.83571711], + [-0.934284 , -0.97074098, 0.89721355, -0.93657855, 1. , + 0.97517215], + [-0.99004057, -0.99981569, 0.77714685, -0.83571711, 0.97517215, + 1. ]]) + + Finally if we use the option ``rowvar=False``, the columns are now + being treated as the variables and we will find the column-wise Pearson + correlation coefficients between variables in ``xarr`` and ``yarr``. + + >>> R3 = np.corrcoef(xarr, yarr, rowvar=False) + >>> R3 + array([[ 1. , 0.77598074, -0.47458546, -0.75078643, -0.9665554 , + 0.22423734], + [ 0.77598074, 1. , -0.92346708, -0.99923895, -0.58826587, + -0.44069024], + [-0.47458546, -0.92346708, 1. , 0.93773029, 0.23297648, + 0.75137473], + [-0.75078643, -0.99923895, 0.93773029, 1. , 0.55627469, + 0.47536961], + [-0.9665554 , -0.58826587, 0.23297648, 0.55627469, 1. , + -0.46666491], + [ 0.22423734, -0.44069024, 0.75137473, 0.47536961, -0.46666491, + 1. ]]) + + """ + if bias is not np._NoValue or ddof is not np._NoValue: + # 2015-03-15, 1.10 + warnings.warn('bias and ddof have no effect and are deprecated', + DeprecationWarning, stacklevel=3) + c = cov(x, y, rowvar, dtype=dtype) + try: + d = diag(c) + except ValueError: + # scalar covariance + # nan if incorrect value (nan, inf, 0), 1 otherwise + return c / c + stddev = sqrt(d.real) + c /= stddev[:, None] + c /= stddev[None, :] + + # Clip real and imaginary parts to [-1, 1]. This does not guarantee + # abs(a[i,j]) <= 1 for complex arrays, but is the best we can do without + # excessive work. + np.clip(c.real, -1, 1, out=c.real) + if np.iscomplexobj(c): + np.clip(c.imag, -1, 1, out=c.imag) + + return c + + +@set_module('numpy') +def blackman(M): + """ + Return the Blackman window. + + The Blackman window is a taper formed by using the first three + terms of a summation of cosines. It was designed to have close to the + minimal leakage possible. It is close to optimal, only slightly worse + than a Kaiser window. + + Parameters + ---------- + M : int + Number of points in the output window. If zero or less, an empty + array is returned. + + Returns + ------- + out : ndarray + The window, with the maximum value normalized to one (the value one + appears only if the number of samples is odd). + + See Also + -------- + bartlett, hamming, hanning, kaiser + + Notes + ----- + The Blackman window is defined as + + .. math:: w(n) = 0.42 - 0.5 \\cos(2\\pi n/M) + 0.08 \\cos(4\\pi n/M) + + Most references to the Blackman window come from the signal processing + literature, where it is used as one of many windowing functions for + smoothing values. It is also known as an apodization (which means + "removing the foot", i.e. smoothing discontinuities at the beginning + and end of the sampled signal) or tapering function. It is known as a + "near optimal" tapering function, almost as good (by some measures) + as the kaiser window. + + References + ---------- + Blackman, R.B. and Tukey, J.W., (1958) The measurement of power spectra, + Dover Publications, New York. + + Oppenheim, A.V., and R.W. Schafer. Discrete-Time Signal Processing. + Upper Saddle River, NJ: Prentice-Hall, 1999, pp. 468-471. + + Examples + -------- + >>> import matplotlib.pyplot as plt + >>> np.blackman(12) + array([-1.38777878e-17, 3.26064346e-02, 1.59903635e-01, # may vary + 4.14397981e-01, 7.36045180e-01, 9.67046769e-01, + 9.67046769e-01, 7.36045180e-01, 4.14397981e-01, + 1.59903635e-01, 3.26064346e-02, -1.38777878e-17]) + + Plot the window and the frequency response: + + >>> from numpy.fft import fft, fftshift + >>> window = np.blackman(51) + >>> plt.plot(window) + [] + >>> plt.title("Blackman window") + Text(0.5, 1.0, 'Blackman window') + >>> plt.ylabel("Amplitude") + Text(0, 0.5, 'Amplitude') + >>> plt.xlabel("Sample") + Text(0.5, 0, 'Sample') + >>> plt.show() + + >>> plt.figure() +

    + >>> A = fft(window, 2048) / 25.5 + >>> mag = np.abs(fftshift(A)) + >>> freq = np.linspace(-0.5, 0.5, len(A)) + >>> with np.errstate(divide='ignore', invalid='ignore'): + ... response = 20 * np.log10(mag) + ... + >>> response = np.clip(response, -100, 100) + >>> plt.plot(freq, response) + [] + >>> plt.title("Frequency response of Blackman window") + Text(0.5, 1.0, 'Frequency response of Blackman window') + >>> plt.ylabel("Magnitude [dB]") + Text(0, 0.5, 'Magnitude [dB]') + >>> plt.xlabel("Normalized frequency [cycles per sample]") + Text(0.5, 0, 'Normalized frequency [cycles per sample]') + >>> _ = plt.axis('tight') + >>> plt.show() + + """ + if M < 1: + return array([]) + if M == 1: + return ones(1, float) + n = arange(1-M, M, 2) + return 0.42 + 0.5*cos(pi*n/(M-1)) + 0.08*cos(2.0*pi*n/(M-1)) + + +@set_module('numpy') +def bartlett(M): + """ + Return the Bartlett window. + + The Bartlett window is very similar to a triangular window, except + that the end points are at zero. It is often used in signal + processing for tapering a signal, without generating too much + ripple in the frequency domain. + + Parameters + ---------- + M : int + Number of points in the output window. If zero or less, an + empty array is returned. + + Returns + ------- + out : array + The triangular window, with the maximum value normalized to one + (the value one appears only if the number of samples is odd), with + the first and last samples equal to zero. + + See Also + -------- + blackman, hamming, hanning, kaiser + + Notes + ----- + The Bartlett window is defined as + + .. math:: w(n) = \\frac{2}{M-1} \\left( + \\frac{M-1}{2} - \\left|n - \\frac{M-1}{2}\\right| + \\right) + + Most references to the Bartlett window come from the signal + processing literature, where it is used as one of many windowing + functions for smoothing values. Note that convolution with this + window produces linear interpolation. It is also known as an + apodization (which means"removing the foot", i.e. smoothing + discontinuities at the beginning and end of the sampled signal) or + tapering function. The fourier transform of the Bartlett is the product + of two sinc functions. + Note the excellent discussion in Kanasewich. + + References + ---------- + .. [1] M.S. Bartlett, "Periodogram Analysis and Continuous Spectra", + Biometrika 37, 1-16, 1950. + .. [2] E.R. Kanasewich, "Time Sequence Analysis in Geophysics", + The University of Alberta Press, 1975, pp. 109-110. + .. [3] A.V. Oppenheim and R.W. Schafer, "Discrete-Time Signal + Processing", Prentice-Hall, 1999, pp. 468-471. + .. [4] Wikipedia, "Window function", + https://en.wikipedia.org/wiki/Window_function + .. [5] W.H. Press, B.P. Flannery, S.A. Teukolsky, and W.T. Vetterling, + "Numerical Recipes", Cambridge University Press, 1986, page 429. + + Examples + -------- + >>> import matplotlib.pyplot as plt + >>> np.bartlett(12) + array([ 0. , 0.18181818, 0.36363636, 0.54545455, 0.72727273, # may vary + 0.90909091, 0.90909091, 0.72727273, 0.54545455, 0.36363636, + 0.18181818, 0. ]) + + Plot the window and its frequency response (requires SciPy and matplotlib): + + >>> from numpy.fft import fft, fftshift + >>> window = np.bartlett(51) + >>> plt.plot(window) + [] + >>> plt.title("Bartlett window") + Text(0.5, 1.0, 'Bartlett window') + >>> plt.ylabel("Amplitude") + Text(0, 0.5, 'Amplitude') + >>> plt.xlabel("Sample") + Text(0.5, 0, 'Sample') + >>> plt.show() + + >>> plt.figure() +
    + >>> A = fft(window, 2048) / 25.5 + >>> mag = np.abs(fftshift(A)) + >>> freq = np.linspace(-0.5, 0.5, len(A)) + >>> with np.errstate(divide='ignore', invalid='ignore'): + ... response = 20 * np.log10(mag) + ... + >>> response = np.clip(response, -100, 100) + >>> plt.plot(freq, response) + [] + >>> plt.title("Frequency response of Bartlett window") + Text(0.5, 1.0, 'Frequency response of Bartlett window') + >>> plt.ylabel("Magnitude [dB]") + Text(0, 0.5, 'Magnitude [dB]') + >>> plt.xlabel("Normalized frequency [cycles per sample]") + Text(0.5, 0, 'Normalized frequency [cycles per sample]') + >>> _ = plt.axis('tight') + >>> plt.show() + + """ + if M < 1: + return array([]) + if M == 1: + return ones(1, float) + n = arange(1-M, M, 2) + return where(less_equal(n, 0), 1 + n/(M-1), 1 - n/(M-1)) + + +@set_module('numpy') +def hanning(M): + """ + Return the Hanning window. + + The Hanning window is a taper formed by using a weighted cosine. + + Parameters + ---------- + M : int + Number of points in the output window. If zero or less, an + empty array is returned. + + Returns + ------- + out : ndarray, shape(M,) + The window, with the maximum value normalized to one (the value + one appears only if `M` is odd). + + See Also + -------- + bartlett, blackman, hamming, kaiser + + Notes + ----- + The Hanning window is defined as + + .. math:: w(n) = 0.5 - 0.5cos\\left(\\frac{2\\pi{n}}{M-1}\\right) + \\qquad 0 \\leq n \\leq M-1 + + The Hanning was named for Julius von Hann, an Austrian meteorologist. + It is also known as the Cosine Bell. Some authors prefer that it be + called a Hann window, to help avoid confusion with the very similar + Hamming window. + + Most references to the Hanning window come from the signal processing + literature, where it is used as one of many windowing functions for + smoothing values. It is also known as an apodization (which means + "removing the foot", i.e. smoothing discontinuities at the beginning + and end of the sampled signal) or tapering function. + + References + ---------- + .. [1] Blackman, R.B. and Tukey, J.W., (1958) The measurement of power + spectra, Dover Publications, New York. + .. [2] E.R. Kanasewich, "Time Sequence Analysis in Geophysics", + The University of Alberta Press, 1975, pp. 106-108. + .. [3] Wikipedia, "Window function", + https://en.wikipedia.org/wiki/Window_function + .. [4] W.H. Press, B.P. Flannery, S.A. Teukolsky, and W.T. Vetterling, + "Numerical Recipes", Cambridge University Press, 1986, page 425. + + Examples + -------- + >>> np.hanning(12) + array([0. , 0.07937323, 0.29229249, 0.57115742, 0.82743037, + 0.97974649, 0.97974649, 0.82743037, 0.57115742, 0.29229249, + 0.07937323, 0. ]) + + Plot the window and its frequency response: + + >>> import matplotlib.pyplot as plt + >>> from numpy.fft import fft, fftshift + >>> window = np.hanning(51) + >>> plt.plot(window) + [] + >>> plt.title("Hann window") + Text(0.5, 1.0, 'Hann window') + >>> plt.ylabel("Amplitude") + Text(0, 0.5, 'Amplitude') + >>> plt.xlabel("Sample") + Text(0.5, 0, 'Sample') + >>> plt.show() + + >>> plt.figure() +
    + >>> A = fft(window, 2048) / 25.5 + >>> mag = np.abs(fftshift(A)) + >>> freq = np.linspace(-0.5, 0.5, len(A)) + >>> with np.errstate(divide='ignore', invalid='ignore'): + ... response = 20 * np.log10(mag) + ... + >>> response = np.clip(response, -100, 100) + >>> plt.plot(freq, response) + [] + >>> plt.title("Frequency response of the Hann window") + Text(0.5, 1.0, 'Frequency response of the Hann window') + >>> plt.ylabel("Magnitude [dB]") + Text(0, 0.5, 'Magnitude [dB]') + >>> plt.xlabel("Normalized frequency [cycles per sample]") + Text(0.5, 0, 'Normalized frequency [cycles per sample]') + >>> plt.axis('tight') + ... + >>> plt.show() + + """ + if M < 1: + return array([]) + if M == 1: + return ones(1, float) + n = arange(1-M, M, 2) + return 0.5 + 0.5*cos(pi*n/(M-1)) + + +@set_module('numpy') +def hamming(M): + """ + Return the Hamming window. + + The Hamming window is a taper formed by using a weighted cosine. + + Parameters + ---------- + M : int + Number of points in the output window. If zero or less, an + empty array is returned. + + Returns + ------- + out : ndarray + The window, with the maximum value normalized to one (the value + one appears only if the number of samples is odd). + + See Also + -------- + bartlett, blackman, hanning, kaiser + + Notes + ----- + The Hamming window is defined as + + .. math:: w(n) = 0.54 - 0.46cos\\left(\\frac{2\\pi{n}}{M-1}\\right) + \\qquad 0 \\leq n \\leq M-1 + + The Hamming was named for R. W. Hamming, an associate of J. W. Tukey + and is described in Blackman and Tukey. It was recommended for + smoothing the truncated autocovariance function in the time domain. + Most references to the Hamming window come from the signal processing + literature, where it is used as one of many windowing functions for + smoothing values. It is also known as an apodization (which means + "removing the foot", i.e. smoothing discontinuities at the beginning + and end of the sampled signal) or tapering function. + + References + ---------- + .. [1] Blackman, R.B. and Tukey, J.W., (1958) The measurement of power + spectra, Dover Publications, New York. + .. [2] E.R. Kanasewich, "Time Sequence Analysis in Geophysics", The + University of Alberta Press, 1975, pp. 109-110. + .. [3] Wikipedia, "Window function", + https://en.wikipedia.org/wiki/Window_function + .. [4] W.H. Press, B.P. Flannery, S.A. Teukolsky, and W.T. Vetterling, + "Numerical Recipes", Cambridge University Press, 1986, page 425. + + Examples + -------- + >>> np.hamming(12) + array([ 0.08 , 0.15302337, 0.34890909, 0.60546483, 0.84123594, # may vary + 0.98136677, 0.98136677, 0.84123594, 0.60546483, 0.34890909, + 0.15302337, 0.08 ]) + + Plot the window and the frequency response: + + >>> import matplotlib.pyplot as plt + >>> from numpy.fft import fft, fftshift + >>> window = np.hamming(51) + >>> plt.plot(window) + [] + >>> plt.title("Hamming window") + Text(0.5, 1.0, 'Hamming window') + >>> plt.ylabel("Amplitude") + Text(0, 0.5, 'Amplitude') + >>> plt.xlabel("Sample") + Text(0.5, 0, 'Sample') + >>> plt.show() + + >>> plt.figure() +
    + >>> A = fft(window, 2048) / 25.5 + >>> mag = np.abs(fftshift(A)) + >>> freq = np.linspace(-0.5, 0.5, len(A)) + >>> response = 20 * np.log10(mag) + >>> response = np.clip(response, -100, 100) + >>> plt.plot(freq, response) + [] + >>> plt.title("Frequency response of Hamming window") + Text(0.5, 1.0, 'Frequency response of Hamming window') + >>> plt.ylabel("Magnitude [dB]") + Text(0, 0.5, 'Magnitude [dB]') + >>> plt.xlabel("Normalized frequency [cycles per sample]") + Text(0.5, 0, 'Normalized frequency [cycles per sample]') + >>> plt.axis('tight') + ... + >>> plt.show() + + """ + if M < 1: + return array([]) + if M == 1: + return ones(1, float) + n = arange(1-M, M, 2) + return 0.54 + 0.46*cos(pi*n/(M-1)) + + +## Code from cephes for i0 + +_i0A = [ + -4.41534164647933937950E-18, + 3.33079451882223809783E-17, + -2.43127984654795469359E-16, + 1.71539128555513303061E-15, + -1.16853328779934516808E-14, + 7.67618549860493561688E-14, + -4.85644678311192946090E-13, + 2.95505266312963983461E-12, + -1.72682629144155570723E-11, + 9.67580903537323691224E-11, + -5.18979560163526290666E-10, + 2.65982372468238665035E-9, + -1.30002500998624804212E-8, + 6.04699502254191894932E-8, + -2.67079385394061173391E-7, + 1.11738753912010371815E-6, + -4.41673835845875056359E-6, + 1.64484480707288970893E-5, + -5.75419501008210370398E-5, + 1.88502885095841655729E-4, + -5.76375574538582365885E-4, + 1.63947561694133579842E-3, + -4.32430999505057594430E-3, + 1.05464603945949983183E-2, + -2.37374148058994688156E-2, + 4.93052842396707084878E-2, + -9.49010970480476444210E-2, + 1.71620901522208775349E-1, + -3.04682672343198398683E-1, + 6.76795274409476084995E-1 + ] + +_i0B = [ + -7.23318048787475395456E-18, + -4.83050448594418207126E-18, + 4.46562142029675999901E-17, + 3.46122286769746109310E-17, + -2.82762398051658348494E-16, + -3.42548561967721913462E-16, + 1.77256013305652638360E-15, + 3.81168066935262242075E-15, + -9.55484669882830764870E-15, + -4.15056934728722208663E-14, + 1.54008621752140982691E-14, + 3.85277838274214270114E-13, + 7.18012445138366623367E-13, + -1.79417853150680611778E-12, + -1.32158118404477131188E-11, + -3.14991652796324136454E-11, + 1.18891471078464383424E-11, + 4.94060238822496958910E-10, + 3.39623202570838634515E-9, + 2.26666899049817806459E-8, + 2.04891858946906374183E-7, + 2.89137052083475648297E-6, + 6.88975834691682398426E-5, + 3.36911647825569408990E-3, + 8.04490411014108831608E-1 + ] + + +def _chbevl(x, vals): + b0 = vals[0] + b1 = 0.0 + + for i in range(1, len(vals)): + b2 = b1 + b1 = b0 + b0 = x*b1 - b2 + vals[i] + + return 0.5*(b0 - b2) + + +def _i0_1(x): + return exp(x) * _chbevl(x/2.0-2, _i0A) + + +def _i0_2(x): + return exp(x) * _chbevl(32.0/x - 2.0, _i0B) / sqrt(x) + + +def _i0_dispatcher(x): + return (x,) + + +@array_function_dispatch(_i0_dispatcher) +def i0(x): + """ + Modified Bessel function of the first kind, order 0. + + Usually denoted :math:`I_0`. + + Parameters + ---------- + x : array_like of float + Argument of the Bessel function. + + Returns + ------- + out : ndarray, shape = x.shape, dtype = float + The modified Bessel function evaluated at each of the elements of `x`. + + See Also + -------- + scipy.special.i0, scipy.special.iv, scipy.special.ive + + Notes + ----- + The scipy implementation is recommended over this function: it is a + proper ufunc written in C, and more than an order of magnitude faster. + + We use the algorithm published by Clenshaw [1]_ and referenced by + Abramowitz and Stegun [2]_, for which the function domain is + partitioned into the two intervals [0,8] and (8,inf), and Chebyshev + polynomial expansions are employed in each interval. Relative error on + the domain [0,30] using IEEE arithmetic is documented [3]_ as having a + peak of 5.8e-16 with an rms of 1.4e-16 (n = 30000). + + References + ---------- + .. [1] C. W. Clenshaw, "Chebyshev series for mathematical functions", in + *National Physical Laboratory Mathematical Tables*, vol. 5, London: + Her Majesty's Stationery Office, 1962. + .. [2] M. Abramowitz and I. A. Stegun, *Handbook of Mathematical + Functions*, 10th printing, New York: Dover, 1964, pp. 379. + http://www.math.sfu.ca/~cbm/aands/page_379.htm + .. [3] https://metacpan.org/pod/distribution/Math-Cephes/lib/Math/Cephes.pod#i0:-Modified-Bessel-function-of-order-zero + + Examples + -------- + >>> np.i0(0.) + array(1.0) + >>> np.i0([0, 1, 2, 3]) + array([1. , 1.26606588, 2.2795853 , 4.88079259]) + + """ + x = np.asanyarray(x) + if x.dtype.kind == 'c': + raise TypeError("i0 not supported for complex values") + if x.dtype.kind != 'f': + x = x.astype(float) + x = np.abs(x) + return piecewise(x, [x <= 8.0], [_i0_1, _i0_2]) + +## End of cephes code for i0 + + +@set_module('numpy') +def kaiser(M, beta): + """ + Return the Kaiser window. + + The Kaiser window is a taper formed by using a Bessel function. + + Parameters + ---------- + M : int + Number of points in the output window. If zero or less, an + empty array is returned. + beta : float + Shape parameter for window. + + Returns + ------- + out : array + The window, with the maximum value normalized to one (the value + one appears only if the number of samples is odd). + + See Also + -------- + bartlett, blackman, hamming, hanning + + Notes + ----- + The Kaiser window is defined as + + .. math:: w(n) = I_0\\left( \\beta \\sqrt{1-\\frac{4n^2}{(M-1)^2}} + \\right)/I_0(\\beta) + + with + + .. math:: \\quad -\\frac{M-1}{2} \\leq n \\leq \\frac{M-1}{2}, + + where :math:`I_0` is the modified zeroth-order Bessel function. + + The Kaiser was named for Jim Kaiser, who discovered a simple + approximation to the DPSS window based on Bessel functions. The Kaiser + window is a very good approximation to the Digital Prolate Spheroidal + Sequence, or Slepian window, which is the transform which maximizes the + energy in the main lobe of the window relative to total energy. + + The Kaiser can approximate many other windows by varying the beta + parameter. + + ==== ======================= + beta Window shape + ==== ======================= + 0 Rectangular + 5 Similar to a Hamming + 6 Similar to a Hanning + 8.6 Similar to a Blackman + ==== ======================= + + A beta value of 14 is probably a good starting point. Note that as beta + gets large, the window narrows, and so the number of samples needs to be + large enough to sample the increasingly narrow spike, otherwise NaNs will + get returned. + + Most references to the Kaiser window come from the signal processing + literature, where it is used as one of many windowing functions for + smoothing values. It is also known as an apodization (which means + "removing the foot", i.e. smoothing discontinuities at the beginning + and end of the sampled signal) or tapering function. + + References + ---------- + .. [1] J. F. Kaiser, "Digital Filters" - Ch 7 in "Systems analysis by + digital computer", Editors: F.F. Kuo and J.F. Kaiser, p 218-285. + John Wiley and Sons, New York, (1966). + .. [2] E.R. Kanasewich, "Time Sequence Analysis in Geophysics", The + University of Alberta Press, 1975, pp. 177-178. + .. [3] Wikipedia, "Window function", + https://en.wikipedia.org/wiki/Window_function + + Examples + -------- + >>> import matplotlib.pyplot as plt + >>> np.kaiser(12, 14) + array([7.72686684e-06, 3.46009194e-03, 4.65200189e-02, # may vary + 2.29737120e-01, 5.99885316e-01, 9.45674898e-01, + 9.45674898e-01, 5.99885316e-01, 2.29737120e-01, + 4.65200189e-02, 3.46009194e-03, 7.72686684e-06]) + + + Plot the window and the frequency response: + + >>> from numpy.fft import fft, fftshift + >>> window = np.kaiser(51, 14) + >>> plt.plot(window) + [] + >>> plt.title("Kaiser window") + Text(0.5, 1.0, 'Kaiser window') + >>> plt.ylabel("Amplitude") + Text(0, 0.5, 'Amplitude') + >>> plt.xlabel("Sample") + Text(0.5, 0, 'Sample') + >>> plt.show() + + >>> plt.figure() +
    + >>> A = fft(window, 2048) / 25.5 + >>> mag = np.abs(fftshift(A)) + >>> freq = np.linspace(-0.5, 0.5, len(A)) + >>> response = 20 * np.log10(mag) + >>> response = np.clip(response, -100, 100) + >>> plt.plot(freq, response) + [] + >>> plt.title("Frequency response of Kaiser window") + Text(0.5, 1.0, 'Frequency response of Kaiser window') + >>> plt.ylabel("Magnitude [dB]") + Text(0, 0.5, 'Magnitude [dB]') + >>> plt.xlabel("Normalized frequency [cycles per sample]") + Text(0.5, 0, 'Normalized frequency [cycles per sample]') + >>> plt.axis('tight') + (-0.5, 0.5, -100.0, ...) # may vary + >>> plt.show() + + """ + if M == 1: + return np.array([1.]) + n = arange(0, M) + alpha = (M-1)/2.0 + return i0(beta * sqrt(1-((n-alpha)/alpha)**2.0))/i0(float(beta)) + + +def _sinc_dispatcher(x): + return (x,) + + +@array_function_dispatch(_sinc_dispatcher) +def sinc(x): + r""" + Return the normalized sinc function. + + The sinc function is :math:`\sin(\pi x)/(\pi x)`. + + .. note:: + + Note the normalization factor of ``pi`` used in the definition. + This is the most commonly used definition in signal processing. + Use ``sinc(x / np.pi)`` to obtain the unnormalized sinc function + :math:`\sin(x)/(x)` that is more common in mathematics. + + Parameters + ---------- + x : ndarray + Array (possibly multi-dimensional) of values for which to to + calculate ``sinc(x)``. + + Returns + ------- + out : ndarray + ``sinc(x)``, which has the same shape as the input. + + Notes + ----- + ``sinc(0)`` is the limit value 1. + + The name sinc is short for "sine cardinal" or "sinus cardinalis". + + The sinc function is used in various signal processing applications, + including in anti-aliasing, in the construction of a Lanczos resampling + filter, and in interpolation. + + For bandlimited interpolation of discrete-time signals, the ideal + interpolation kernel is proportional to the sinc function. + + References + ---------- + .. [1] Weisstein, Eric W. "Sinc Function." From MathWorld--A Wolfram Web + Resource. http://mathworld.wolfram.com/SincFunction.html + .. [2] Wikipedia, "Sinc function", + https://en.wikipedia.org/wiki/Sinc_function + + Examples + -------- + >>> import matplotlib.pyplot as plt + >>> x = np.linspace(-4, 4, 41) + >>> np.sinc(x) + array([-3.89804309e-17, -4.92362781e-02, -8.40918587e-02, # may vary + -8.90384387e-02, -5.84680802e-02, 3.89804309e-17, + 6.68206631e-02, 1.16434881e-01, 1.26137788e-01, + 8.50444803e-02, -3.89804309e-17, -1.03943254e-01, + -1.89206682e-01, -2.16236208e-01, -1.55914881e-01, + 3.89804309e-17, 2.33872321e-01, 5.04551152e-01, + 7.56826729e-01, 9.35489284e-01, 1.00000000e+00, + 9.35489284e-01, 7.56826729e-01, 5.04551152e-01, + 2.33872321e-01, 3.89804309e-17, -1.55914881e-01, + -2.16236208e-01, -1.89206682e-01, -1.03943254e-01, + -3.89804309e-17, 8.50444803e-02, 1.26137788e-01, + 1.16434881e-01, 6.68206631e-02, 3.89804309e-17, + -5.84680802e-02, -8.90384387e-02, -8.40918587e-02, + -4.92362781e-02, -3.89804309e-17]) + + >>> plt.plot(x, np.sinc(x)) + [] + >>> plt.title("Sinc Function") + Text(0.5, 1.0, 'Sinc Function') + >>> plt.ylabel("Amplitude") + Text(0, 0.5, 'Amplitude') + >>> plt.xlabel("X") + Text(0.5, 0, 'X') + >>> plt.show() + + """ + x = np.asanyarray(x) + y = pi * where(x == 0, 1.0e-20, x) + return sin(y)/y + + +def _msort_dispatcher(a): + return (a,) + + +@array_function_dispatch(_msort_dispatcher) +def msort(a): + """ + Return a copy of an array sorted along the first axis. + + Parameters + ---------- + a : array_like + Array to be sorted. + + Returns + ------- + sorted_array : ndarray + Array of the same type and shape as `a`. + + See Also + -------- + sort + + Notes + ----- + ``np.msort(a)`` is equivalent to ``np.sort(a, axis=0)``. + + """ + b = array(a, subok=True, copy=True) + b.sort(0) + return b + + +def _ureduce(a, func, **kwargs): + """ + Internal Function. + Call `func` with `a` as first argument swapping the axes to use extended + axis on functions that don't support it natively. + + Returns result and a.shape with axis dims set to 1. + + Parameters + ---------- + a : array_like + Input array or object that can be converted to an array. + func : callable + Reduction function capable of receiving a single axis argument. + It is called with `a` as first argument followed by `kwargs`. + kwargs : keyword arguments + additional keyword arguments to pass to `func`. + + Returns + ------- + result : tuple + Result of func(a, **kwargs) and a.shape with axis dims set to 1 + which can be used to reshape the result to the same shape a ufunc with + keepdims=True would produce. + + """ + a = np.asanyarray(a) + axis = kwargs.get('axis', None) + if axis is not None: + keepdim = list(a.shape) + nd = a.ndim + axis = _nx.normalize_axis_tuple(axis, nd) + + for ax in axis: + keepdim[ax] = 1 + + if len(axis) == 1: + kwargs['axis'] = axis[0] + else: + keep = set(range(nd)) - set(axis) + nkeep = len(keep) + # swap axis that should not be reduced to front + for i, s in enumerate(sorted(keep)): + a = a.swapaxes(i, s) + # merge reduced axis + a = a.reshape(a.shape[:nkeep] + (-1,)) + kwargs['axis'] = -1 + keepdim = tuple(keepdim) + else: + keepdim = (1,) * a.ndim + + r = func(a, **kwargs) + return r, keepdim + + +def _median_dispatcher( + a, axis=None, out=None, overwrite_input=None, keepdims=None): + return (a, out) + + +@array_function_dispatch(_median_dispatcher) +def median(a, axis=None, out=None, overwrite_input=False, keepdims=False): + """ + Compute the median along the specified axis. + + Returns the median of the array elements. + + Parameters + ---------- + a : array_like + Input array or object that can be converted to an array. + axis : {int, sequence of int, None}, optional + Axis or axes along which the medians are computed. The default + is to compute the median along a flattened version of the array. + A sequence of axes is supported since version 1.9.0. + out : ndarray, optional + Alternative output array in which to place the result. It must + have the same shape and buffer length as the expected output, + but the type (of the output) will be cast if necessary. + overwrite_input : bool, optional + If True, then allow use of memory of input array `a` for + calculations. The input array will be modified by the call to + `median`. This will save memory when you do not need to preserve + the contents of the input array. Treat the input as undefined, + but it will probably be fully or partially sorted. Default is + False. If `overwrite_input` is ``True`` and `a` is not already an + `ndarray`, an error will be raised. + keepdims : bool, optional + If this is set to True, the axes which are reduced are left + in the result as dimensions with size one. With this option, + the result will broadcast correctly against the original `arr`. + + .. versionadded:: 1.9.0 + + Returns + ------- + median : ndarray + A new array holding the result. If the input contains integers + or floats smaller than ``float64``, then the output data-type is + ``np.float64``. Otherwise, the data-type of the output is the + same as that of the input. If `out` is specified, that array is + returned instead. + + See Also + -------- + mean, percentile + + Notes + ----- + Given a vector ``V`` of length ``N``, the median of ``V`` is the + middle value of a sorted copy of ``V``, ``V_sorted`` - i + e., ``V_sorted[(N-1)/2]``, when ``N`` is odd, and the average of the + two middle values of ``V_sorted`` when ``N`` is even. + + Examples + -------- + >>> a = np.array([[10, 7, 4], [3, 2, 1]]) + >>> a + array([[10, 7, 4], + [ 3, 2, 1]]) + >>> np.median(a) + 3.5 + >>> np.median(a, axis=0) + array([6.5, 4.5, 2.5]) + >>> np.median(a, axis=1) + array([7., 2.]) + >>> m = np.median(a, axis=0) + >>> out = np.zeros_like(m) + >>> np.median(a, axis=0, out=m) + array([6.5, 4.5, 2.5]) + >>> m + array([6.5, 4.5, 2.5]) + >>> b = a.copy() + >>> np.median(b, axis=1, overwrite_input=True) + array([7., 2.]) + >>> assert not np.all(a==b) + >>> b = a.copy() + >>> np.median(b, axis=None, overwrite_input=True) + 3.5 + >>> assert not np.all(a==b) + + """ + r, k = _ureduce(a, func=_median, axis=axis, out=out, + overwrite_input=overwrite_input) + if keepdims: + return r.reshape(k) + else: + return r + + +def _median(a, axis=None, out=None, overwrite_input=False): + # can't be reasonably be implemented in terms of percentile as we have to + # call mean to not break astropy + a = np.asanyarray(a) + + # Set the partition indexes + if axis is None: + sz = a.size + else: + sz = a.shape[axis] + if sz % 2 == 0: + szh = sz // 2 + kth = [szh - 1, szh] + else: + kth = [(sz - 1) // 2] + # Check if the array contains any nan's + if np.issubdtype(a.dtype, np.inexact): + kth.append(-1) + + if overwrite_input: + if axis is None: + part = a.ravel() + part.partition(kth) + else: + a.partition(kth, axis=axis) + part = a + else: + part = partition(a, kth, axis=axis) + + if part.shape == (): + # make 0-D arrays work + return part.item() + if axis is None: + axis = 0 + + indexer = [slice(None)] * part.ndim + index = part.shape[axis] // 2 + if part.shape[axis] % 2 == 1: + # index with slice to allow mean (below) to work + indexer[axis] = slice(index, index+1) + else: + indexer[axis] = slice(index-1, index+1) + indexer = tuple(indexer) + + # Check if the array contains any nan's + if np.issubdtype(a.dtype, np.inexact) and sz > 0: + # warn and return nans like mean would + rout = mean(part[indexer], axis=axis, out=out) + return np.lib.utils._median_nancheck(part, rout, axis, out) + else: + # if there are no nans + # Use mean in odd and even case to coerce data type + # and check, use out array. + return mean(part[indexer], axis=axis, out=out) + + +def _percentile_dispatcher(a, q, axis=None, out=None, overwrite_input=None, + interpolation=None, keepdims=None): + return (a, q, out) + + +@array_function_dispatch(_percentile_dispatcher) +def percentile(a, q, axis=None, out=None, + overwrite_input=False, interpolation='linear', keepdims=False): + """ + Compute the q-th percentile of the data along the specified axis. + + Returns the q-th percentile(s) of the array elements. + + Parameters + ---------- + a : array_like + Input array or object that can be converted to an array. + q : array_like of float + Percentile or sequence of percentiles to compute, which must be between + 0 and 100 inclusive. + axis : {int, tuple of int, None}, optional + Axis or axes along which the percentiles are computed. The + default is to compute the percentile(s) along a flattened + version of the array. + + .. versionchanged:: 1.9.0 + A tuple of axes is supported + out : ndarray, optional + Alternative output array in which to place the result. It must + have the same shape and buffer length as the expected output, + but the type (of the output) will be cast if necessary. + overwrite_input : bool, optional + If True, then allow the input array `a` to be modified by intermediate + calculations, to save memory. In this case, the contents of the input + `a` after this function completes is undefined. + + interpolation : {'linear', 'lower', 'higher', 'midpoint', 'nearest'} + This optional parameter specifies the interpolation method to + use when the desired percentile lies between two data points + ``i < j``: + + * 'linear': ``i + (j - i) * fraction``, where ``fraction`` + is the fractional part of the index surrounded by ``i`` + and ``j``. + * 'lower': ``i``. + * 'higher': ``j``. + * 'nearest': ``i`` or ``j``, whichever is nearest. + * 'midpoint': ``(i + j) / 2``. + + .. versionadded:: 1.9.0 + keepdims : bool, optional + If this is set to True, the axes which are reduced are left in + the result as dimensions with size one. With this option, the + result will broadcast correctly against the original array `a`. + + .. versionadded:: 1.9.0 + + Returns + ------- + percentile : scalar or ndarray + If `q` is a single percentile and `axis=None`, then the result + is a scalar. If multiple percentiles are given, first axis of + the result corresponds to the percentiles. The other axes are + the axes that remain after the reduction of `a`. If the input + contains integers or floats smaller than ``float64``, the output + data-type is ``float64``. Otherwise, the output data-type is the + same as that of the input. If `out` is specified, that array is + returned instead. + + See Also + -------- + mean + median : equivalent to ``percentile(..., 50)`` + nanpercentile + quantile : equivalent to percentile, except with q in the range [0, 1]. + + Notes + ----- + Given a vector ``V`` of length ``N``, the q-th percentile of + ``V`` is the value ``q/100`` of the way from the minimum to the + maximum in a sorted copy of ``V``. The values and distances of + the two nearest neighbors as well as the `interpolation` parameter + will determine the percentile if the normalized ranking does not + match the location of ``q`` exactly. This function is the same as + the median if ``q=50``, the same as the minimum if ``q=0`` and the + same as the maximum if ``q=100``. + + Examples + -------- + >>> a = np.array([[10, 7, 4], [3, 2, 1]]) + >>> a + array([[10, 7, 4], + [ 3, 2, 1]]) + >>> np.percentile(a, 50) + 3.5 + >>> np.percentile(a, 50, axis=0) + array([6.5, 4.5, 2.5]) + >>> np.percentile(a, 50, axis=1) + array([7., 2.]) + >>> np.percentile(a, 50, axis=1, keepdims=True) + array([[7.], + [2.]]) + + >>> m = np.percentile(a, 50, axis=0) + >>> out = np.zeros_like(m) + >>> np.percentile(a, 50, axis=0, out=out) + array([6.5, 4.5, 2.5]) + >>> m + array([6.5, 4.5, 2.5]) + + >>> b = a.copy() + >>> np.percentile(b, 50, axis=1, overwrite_input=True) + array([7., 2.]) + >>> assert not np.all(a == b) + + The different types of interpolation can be visualized graphically: + + .. plot:: + + import matplotlib.pyplot as plt + + a = np.arange(4) + p = np.linspace(0, 100, 6001) + ax = plt.gca() + lines = [ + ('linear', None), + ('higher', '--'), + ('lower', '--'), + ('nearest', '-.'), + ('midpoint', '-.'), + ] + for interpolation, style in lines: + ax.plot( + p, np.percentile(a, p, interpolation=interpolation), + label=interpolation, linestyle=style) + ax.set( + title='Interpolation methods for list: ' + str(a), + xlabel='Percentile', + ylabel='List item returned', + yticks=a) + ax.legend() + plt.show() + + """ + q = np.true_divide(q, 100) + q = asanyarray(q) # undo any decay that the ufunc performed (see gh-13105) + if not _quantile_is_valid(q): + raise ValueError("Percentiles must be in the range [0, 100]") + return _quantile_unchecked( + a, q, axis, out, overwrite_input, interpolation, keepdims) + + +def _quantile_dispatcher(a, q, axis=None, out=None, overwrite_input=None, + interpolation=None, keepdims=None): + return (a, q, out) + + +@array_function_dispatch(_quantile_dispatcher) +def quantile(a, q, axis=None, out=None, + overwrite_input=False, interpolation='linear', keepdims=False): + """ + Compute the q-th quantile of the data along the specified axis. + + .. versionadded:: 1.15.0 + + Parameters + ---------- + a : array_like + Input array or object that can be converted to an array. + q : array_like of float + Quantile or sequence of quantiles to compute, which must be between + 0 and 1 inclusive. + axis : {int, tuple of int, None}, optional + Axis or axes along which the quantiles are computed. The + default is to compute the quantile(s) along a flattened + version of the array. + out : ndarray, optional + Alternative output array in which to place the result. It must + have the same shape and buffer length as the expected output, + but the type (of the output) will be cast if necessary. + overwrite_input : bool, optional + If True, then allow the input array `a` to be modified by intermediate + calculations, to save memory. In this case, the contents of the input + `a` after this function completes is undefined. + interpolation : {'linear', 'lower', 'higher', 'midpoint', 'nearest'} + This optional parameter specifies the interpolation method to + use when the desired quantile lies between two data points + ``i < j``: + + * linear: ``i + (j - i) * fraction``, where ``fraction`` + is the fractional part of the index surrounded by ``i`` + and ``j``. + * lower: ``i``. + * higher: ``j``. + * nearest: ``i`` or ``j``, whichever is nearest. + * midpoint: ``(i + j) / 2``. + keepdims : bool, optional + If this is set to True, the axes which are reduced are left in + the result as dimensions with size one. With this option, the + result will broadcast correctly against the original array `a`. + + Returns + ------- + quantile : scalar or ndarray + If `q` is a single quantile and `axis=None`, then the result + is a scalar. If multiple quantiles are given, first axis of + the result corresponds to the quantiles. The other axes are + the axes that remain after the reduction of `a`. If the input + contains integers or floats smaller than ``float64``, the output + data-type is ``float64``. Otherwise, the output data-type is the + same as that of the input. If `out` is specified, that array is + returned instead. + + See Also + -------- + mean + percentile : equivalent to quantile, but with q in the range [0, 100]. + median : equivalent to ``quantile(..., 0.5)`` + nanquantile + + Notes + ----- + Given a vector ``V`` of length ``N``, the q-th quantile of + ``V`` is the value ``q`` of the way from the minimum to the + maximum in a sorted copy of ``V``. The values and distances of + the two nearest neighbors as well as the `interpolation` parameter + will determine the quantile if the normalized ranking does not + match the location of ``q`` exactly. This function is the same as + the median if ``q=0.5``, the same as the minimum if ``q=0.0`` and the + same as the maximum if ``q=1.0``. + + Examples + -------- + >>> a = np.array([[10, 7, 4], [3, 2, 1]]) + >>> a + array([[10, 7, 4], + [ 3, 2, 1]]) + >>> np.quantile(a, 0.5) + 3.5 + >>> np.quantile(a, 0.5, axis=0) + array([6.5, 4.5, 2.5]) + >>> np.quantile(a, 0.5, axis=1) + array([7., 2.]) + >>> np.quantile(a, 0.5, axis=1, keepdims=True) + array([[7.], + [2.]]) + >>> m = np.quantile(a, 0.5, axis=0) + >>> out = np.zeros_like(m) + >>> np.quantile(a, 0.5, axis=0, out=out) + array([6.5, 4.5, 2.5]) + >>> m + array([6.5, 4.5, 2.5]) + >>> b = a.copy() + >>> np.quantile(b, 0.5, axis=1, overwrite_input=True) + array([7., 2.]) + >>> assert not np.all(a == b) + """ + q = np.asanyarray(q) + if not _quantile_is_valid(q): + raise ValueError("Quantiles must be in the range [0, 1]") + return _quantile_unchecked( + a, q, axis, out, overwrite_input, interpolation, keepdims) + + +def _quantile_unchecked(a, q, axis=None, out=None, overwrite_input=False, + interpolation='linear', keepdims=False): + """Assumes that q is in [0, 1], and is an ndarray""" + r, k = _ureduce(a, func=_quantile_ureduce_func, q=q, axis=axis, out=out, + overwrite_input=overwrite_input, + interpolation=interpolation) + if keepdims: + return r.reshape(q.shape + k) + else: + return r + + +def _quantile_is_valid(q): + # avoid expensive reductions, relevant for arrays with < O(1000) elements + if q.ndim == 1 and q.size < 10: + for i in range(q.size): + if q[i] < 0.0 or q[i] > 1.0: + return False + else: + # faster than any() + if np.count_nonzero(q < 0.0) or np.count_nonzero(q > 1.0): + return False + return True + + +def _lerp(a, b, t, out=None): + """ Linearly interpolate from a to b by a factor of t """ + diff_b_a = subtract(b, a) + # asanyarray is a stop-gap until gh-13105 + lerp_interpolation = asanyarray(add(a, diff_b_a*t, out=out)) + subtract(b, diff_b_a * (1 - t), out=lerp_interpolation, where=t>=0.5) + if lerp_interpolation.ndim == 0 and out is None: + lerp_interpolation = lerp_interpolation[()] # unpack 0d arrays + return lerp_interpolation + + +def _quantile_ureduce_func(a, q, axis=None, out=None, overwrite_input=False, + interpolation='linear', keepdims=False): + a = asarray(a) + + # ufuncs cause 0d array results to decay to scalars (see gh-13105), which + # makes them problematic for __setitem__ and attribute access. As a + # workaround, we call this on the result of every ufunc on a possibly-0d + # array. + not_scalar = np.asanyarray + + # prepare a for partitioning + if overwrite_input: + if axis is None: + ap = a.ravel() + else: + ap = a + else: + if axis is None: + ap = a.flatten() + else: + ap = a.copy() + + if axis is None: + axis = 0 + + if q.ndim > 2: + # The code below works fine for nd, but it might not have useful + # semantics. For now, keep the supported dimensions the same as it was + # before. + raise ValueError("q must be a scalar or 1d") + + Nx = ap.shape[axis] + indices = not_scalar(q * (Nx - 1)) + # round fractional indices according to interpolation method + if interpolation == 'lower': + indices = floor(indices).astype(intp) + elif interpolation == 'higher': + indices = ceil(indices).astype(intp) + elif interpolation == 'midpoint': + indices = 0.5 * (floor(indices) + ceil(indices)) + elif interpolation == 'nearest': + indices = around(indices).astype(intp) + elif interpolation == 'linear': + pass # keep index as fraction and interpolate + else: + raise ValueError( + "interpolation can only be 'linear', 'lower' 'higher', " + "'midpoint', or 'nearest'") + + # The dimensions of `q` are prepended to the output shape, so we need the + # axis being sampled from `ap` to be first. + ap = np.moveaxis(ap, axis, 0) + del axis + + if np.issubdtype(indices.dtype, np.integer): + # take the points along axis + + if np.issubdtype(a.dtype, np.inexact): + # may contain nan, which would sort to the end + ap.partition(concatenate((indices.ravel(), [-1])), axis=0) + n = np.isnan(ap[-1]) + else: + # cannot contain nan + ap.partition(indices.ravel(), axis=0) + n = np.array(False, dtype=bool) + + r = take(ap, indices, axis=0, out=out) + + else: + # weight the points above and below the indices + + indices_below = not_scalar(floor(indices)).astype(intp) + indices_above = not_scalar(indices_below + 1) + indices_above[indices_above > Nx - 1] = Nx - 1 + + if np.issubdtype(a.dtype, np.inexact): + # may contain nan, which would sort to the end + ap.partition(concatenate(( + indices_below.ravel(), indices_above.ravel(), [-1] + )), axis=0) + n = np.isnan(ap[-1]) + else: + # cannot contain nan + ap.partition(concatenate(( + indices_below.ravel(), indices_above.ravel() + )), axis=0) + n = np.array(False, dtype=bool) + + weights_shape = indices.shape + (1,) * (ap.ndim - 1) + weights_above = not_scalar(indices - indices_below).reshape(weights_shape) + + x_below = take(ap, indices_below, axis=0) + x_above = take(ap, indices_above, axis=0) + + r = _lerp(x_below, x_above, weights_above, out=out) + + # if any slice contained a nan, then all results on that slice are also nan + if np.any(n): + if r.ndim == 0 and out is None: + # can't write to a scalar + r = a.dtype.type(np.nan) + else: + r[..., n] = a.dtype.type(np.nan) + + return r + + +def _trapz_dispatcher(y, x=None, dx=None, axis=None): + return (y, x) + + +@array_function_dispatch(_trapz_dispatcher) +def trapz(y, x=None, dx=1.0, axis=-1): + """ + Integrate along the given axis using the composite trapezoidal rule. + + Integrate `y` (`x`) along given axis. + + Parameters + ---------- + y : array_like + Input array to integrate. + x : array_like, optional + The sample points corresponding to the `y` values. If `x` is None, + the sample points are assumed to be evenly spaced `dx` apart. The + default is None. + dx : scalar, optional + The spacing between sample points when `x` is None. The default is 1. + axis : int, optional + The axis along which to integrate. + + Returns + ------- + trapz : float + Definite integral as approximated by trapezoidal rule. + + See Also + -------- + sum, cumsum + + Notes + ----- + Image [2]_ illustrates trapezoidal rule -- y-axis locations of points + will be taken from `y` array, by default x-axis distances between + points will be 1.0, alternatively they can be provided with `x` array + or with `dx` scalar. Return value will be equal to combined area under + the red lines. + + + References + ---------- + .. [1] Wikipedia page: https://en.wikipedia.org/wiki/Trapezoidal_rule + + .. [2] Illustration image: + https://en.wikipedia.org/wiki/File:Composite_trapezoidal_rule_illustration.png + + Examples + -------- + >>> np.trapz([1,2,3]) + 4.0 + >>> np.trapz([1,2,3], x=[4,6,8]) + 8.0 + >>> np.trapz([1,2,3], dx=2) + 8.0 + >>> a = np.arange(6).reshape(2, 3) + >>> a + array([[0, 1, 2], + [3, 4, 5]]) + >>> np.trapz(a, axis=0) + array([1.5, 2.5, 3.5]) + >>> np.trapz(a, axis=1) + array([2., 8.]) + + """ + y = asanyarray(y) + if x is None: + d = dx + else: + x = asanyarray(x) + if x.ndim == 1: + d = diff(x) + # reshape to correct shape + shape = [1]*y.ndim + shape[axis] = d.shape[0] + d = d.reshape(shape) + else: + d = diff(x, axis=axis) + nd = y.ndim + slice1 = [slice(None)]*nd + slice2 = [slice(None)]*nd + slice1[axis] = slice(1, None) + slice2[axis] = slice(None, -1) + try: + ret = (d * (y[tuple(slice1)] + y[tuple(slice2)]) / 2.0).sum(axis) + except ValueError: + # Operations didn't work, cast to ndarray + d = np.asarray(d) + y = np.asarray(y) + ret = add.reduce(d * (y[tuple(slice1)]+y[tuple(slice2)])/2.0, axis) + return ret + + +def _meshgrid_dispatcher(*xi, copy=None, sparse=None, indexing=None): + return xi + + +# Based on scitools meshgrid +@array_function_dispatch(_meshgrid_dispatcher) +def meshgrid(*xi, copy=True, sparse=False, indexing='xy'): + """ + Return coordinate matrices from coordinate vectors. + + Make N-D coordinate arrays for vectorized evaluations of + N-D scalar/vector fields over N-D grids, given + one-dimensional coordinate arrays x1, x2,..., xn. + + .. versionchanged:: 1.9 + 1-D and 0-D cases are allowed. + + Parameters + ---------- + x1, x2,..., xn : array_like + 1-D arrays representing the coordinates of a grid. + indexing : {'xy', 'ij'}, optional + Cartesian ('xy', default) or matrix ('ij') indexing of output. + See Notes for more details. + + .. versionadded:: 1.7.0 + sparse : bool, optional + If True a sparse grid is returned in order to conserve memory. + Default is False. + + .. versionadded:: 1.7.0 + copy : bool, optional + If False, a view into the original arrays are returned in order to + conserve memory. Default is True. Please note that + ``sparse=False, copy=False`` will likely return non-contiguous + arrays. Furthermore, more than one element of a broadcast array + may refer to a single memory location. If you need to write to the + arrays, make copies first. + + .. versionadded:: 1.7.0 + + Returns + ------- + X1, X2,..., XN : ndarray + For vectors `x1`, `x2`,..., 'xn' with lengths ``Ni=len(xi)`` , + return ``(N1, N2, N3,...Nn)`` shaped arrays if indexing='ij' + or ``(N2, N1, N3,...Nn)`` shaped arrays if indexing='xy' + with the elements of `xi` repeated to fill the matrix along + the first dimension for `x1`, the second for `x2` and so on. + + Notes + ----- + This function supports both indexing conventions through the indexing + keyword argument. Giving the string 'ij' returns a meshgrid with + matrix indexing, while 'xy' returns a meshgrid with Cartesian indexing. + In the 2-D case with inputs of length M and N, the outputs are of shape + (N, M) for 'xy' indexing and (M, N) for 'ij' indexing. In the 3-D case + with inputs of length M, N and P, outputs are of shape (N, M, P) for + 'xy' indexing and (M, N, P) for 'ij' indexing. The difference is + illustrated by the following code snippet:: + + xv, yv = np.meshgrid(x, y, sparse=False, indexing='ij') + for i in range(nx): + for j in range(ny): + # treat xv[i,j], yv[i,j] + + xv, yv = np.meshgrid(x, y, sparse=False, indexing='xy') + for i in range(nx): + for j in range(ny): + # treat xv[j,i], yv[j,i] + + In the 1-D and 0-D case, the indexing and sparse keywords have no effect. + + See Also + -------- + mgrid : Construct a multi-dimensional "meshgrid" using indexing notation. + ogrid : Construct an open multi-dimensional "meshgrid" using indexing + notation. + + Examples + -------- + >>> nx, ny = (3, 2) + >>> x = np.linspace(0, 1, nx) + >>> y = np.linspace(0, 1, ny) + >>> xv, yv = np.meshgrid(x, y) + >>> xv + array([[0. , 0.5, 1. ], + [0. , 0.5, 1. ]]) + >>> yv + array([[0., 0., 0.], + [1., 1., 1.]]) + >>> xv, yv = np.meshgrid(x, y, sparse=True) # make sparse output arrays + >>> xv + array([[0. , 0.5, 1. ]]) + >>> yv + array([[0.], + [1.]]) + + `meshgrid` is very useful to evaluate functions on a grid. + + >>> import matplotlib.pyplot as plt + >>> x = np.arange(-5, 5, 0.1) + >>> y = np.arange(-5, 5, 0.1) + >>> xx, yy = np.meshgrid(x, y, sparse=True) + >>> z = np.sin(xx**2 + yy**2) / (xx**2 + yy**2) + >>> h = plt.contourf(x,y,z) + >>> plt.show() + + """ + ndim = len(xi) + + if indexing not in ['xy', 'ij']: + raise ValueError( + "Valid values for `indexing` are 'xy' and 'ij'.") + + s0 = (1,) * ndim + output = [np.asanyarray(x).reshape(s0[:i] + (-1,) + s0[i + 1:]) + for i, x in enumerate(xi)] + + if indexing == 'xy' and ndim > 1: + # switch first and second axis + output[0].shape = (1, -1) + s0[2:] + output[1].shape = (-1, 1) + s0[2:] + + if not sparse: + # Return the full N-D matrix (not only the 1-D vector) + output = np.broadcast_arrays(*output, subok=True) + + if copy: + output = [x.copy() for x in output] + + return output + + +def _delete_dispatcher(arr, obj, axis=None): + return (arr, obj) + + +@array_function_dispatch(_delete_dispatcher) +def delete(arr, obj, axis=None): + """ + Return a new array with sub-arrays along an axis deleted. For a one + dimensional array, this returns those entries not returned by + `arr[obj]`. + + Parameters + ---------- + arr : array_like + Input array. + obj : slice, int or array of ints + Indicate indices of sub-arrays to remove along the specified axis. + + .. versionchanged:: 1.19.0 + Boolean indices are now treated as a mask of elements to remove, + rather than being cast to the integers 0 and 1. + + axis : int, optional + The axis along which to delete the subarray defined by `obj`. + If `axis` is None, `obj` is applied to the flattened array. + + Returns + ------- + out : ndarray + A copy of `arr` with the elements specified by `obj` removed. Note + that `delete` does not occur in-place. If `axis` is None, `out` is + a flattened array. + + See Also + -------- + insert : Insert elements into an array. + append : Append elements at the end of an array. + + Notes + ----- + Often it is preferable to use a boolean mask. For example: + + >>> arr = np.arange(12) + 1 + >>> mask = np.ones(len(arr), dtype=bool) + >>> mask[[0,2,4]] = False + >>> result = arr[mask,...] + + Is equivalent to `np.delete(arr, [0,2,4], axis=0)`, but allows further + use of `mask`. + + Examples + -------- + >>> arr = np.array([[1,2,3,4], [5,6,7,8], [9,10,11,12]]) + >>> arr + array([[ 1, 2, 3, 4], + [ 5, 6, 7, 8], + [ 9, 10, 11, 12]]) + >>> np.delete(arr, 1, 0) + array([[ 1, 2, 3, 4], + [ 9, 10, 11, 12]]) + + >>> np.delete(arr, np.s_[::2], 1) + array([[ 2, 4], + [ 6, 8], + [10, 12]]) + >>> np.delete(arr, [1,3,5], None) + array([ 1, 3, 5, 7, 8, 9, 10, 11, 12]) + + """ + wrap = None + if type(arr) is not ndarray: + try: + wrap = arr.__array_wrap__ + except AttributeError: + pass + + arr = asarray(arr) + ndim = arr.ndim + arrorder = 'F' if arr.flags.fnc else 'C' + if axis is None: + if ndim != 1: + arr = arr.ravel() + # needed for np.matrix, which is still not 1d after being ravelled + ndim = arr.ndim + axis = ndim - 1 + else: + axis = normalize_axis_index(axis, ndim) + + slobj = [slice(None)]*ndim + N = arr.shape[axis] + newshape = list(arr.shape) + + if isinstance(obj, slice): + start, stop, step = obj.indices(N) + xr = range(start, stop, step) + numtodel = len(xr) + + if numtodel <= 0: + if wrap: + return wrap(arr.copy(order=arrorder)) + else: + return arr.copy(order=arrorder) + + # Invert if step is negative: + if step < 0: + step = -step + start = xr[-1] + stop = xr[0] + 1 + + newshape[axis] -= numtodel + new = empty(newshape, arr.dtype, arrorder) + # copy initial chunk + if start == 0: + pass + else: + slobj[axis] = slice(None, start) + new[tuple(slobj)] = arr[tuple(slobj)] + # copy end chunk + if stop == N: + pass + else: + slobj[axis] = slice(stop-numtodel, None) + slobj2 = [slice(None)]*ndim + slobj2[axis] = slice(stop, None) + new[tuple(slobj)] = arr[tuple(slobj2)] + # copy middle pieces + if step == 1: + pass + else: # use array indexing. + keep = ones(stop-start, dtype=bool) + keep[:stop-start:step] = False + slobj[axis] = slice(start, stop-numtodel) + slobj2 = [slice(None)]*ndim + slobj2[axis] = slice(start, stop) + arr = arr[tuple(slobj2)] + slobj2[axis] = keep + new[tuple(slobj)] = arr[tuple(slobj2)] + if wrap: + return wrap(new) + else: + return new + + if isinstance(obj, (int, integer)) and not isinstance(obj, bool): + # optimization for a single value + if (obj < -N or obj >= N): + raise IndexError( + "index %i is out of bounds for axis %i with " + "size %i" % (obj, axis, N)) + if (obj < 0): + obj += N + newshape[axis] -= 1 + new = empty(newshape, arr.dtype, arrorder) + slobj[axis] = slice(None, obj) + new[tuple(slobj)] = arr[tuple(slobj)] + slobj[axis] = slice(obj, None) + slobj2 = [slice(None)]*ndim + slobj2[axis] = slice(obj+1, None) + new[tuple(slobj)] = arr[tuple(slobj2)] + else: + _obj = obj + obj = np.asarray(obj) + if obj.size == 0 and not isinstance(_obj, np.ndarray): + obj = obj.astype(intp) + + if obj.dtype == bool: + if obj.shape != (N,): + raise ValueError('boolean array argument obj to delete ' + 'must be one dimensional and match the axis ' + 'length of {}'.format(N)) + + # optimization, the other branch is slower + keep = ~obj + else: + keep = ones(N, dtype=bool) + keep[obj,] = False + + slobj[axis] = keep + new = arr[tuple(slobj)] + + if wrap: + return wrap(new) + else: + return new + + +def _insert_dispatcher(arr, obj, values, axis=None): + return (arr, obj, values) + + +@array_function_dispatch(_insert_dispatcher) +def insert(arr, obj, values, axis=None): + """ + Insert values along the given axis before the given indices. + + Parameters + ---------- + arr : array_like + Input array. + obj : int, slice or sequence of ints + Object that defines the index or indices before which `values` is + inserted. + + .. versionadded:: 1.8.0 + + Support for multiple insertions when `obj` is a single scalar or a + sequence with one element (similar to calling insert multiple + times). + values : array_like + Values to insert into `arr`. If the type of `values` is different + from that of `arr`, `values` is converted to the type of `arr`. + `values` should be shaped so that ``arr[...,obj,...] = values`` + is legal. + axis : int, optional + Axis along which to insert `values`. If `axis` is None then `arr` + is flattened first. + + Returns + ------- + out : ndarray + A copy of `arr` with `values` inserted. Note that `insert` + does not occur in-place: a new array is returned. If + `axis` is None, `out` is a flattened array. + + See Also + -------- + append : Append elements at the end of an array. + concatenate : Join a sequence of arrays along an existing axis. + delete : Delete elements from an array. + + Notes + ----- + Note that for higher dimensional inserts `obj=0` behaves very different + from `obj=[0]` just like `arr[:,0,:] = values` is different from + `arr[:,[0],:] = values`. + + Examples + -------- + >>> a = np.array([[1, 1], [2, 2], [3, 3]]) + >>> a + array([[1, 1], + [2, 2], + [3, 3]]) + >>> np.insert(a, 1, 5) + array([1, 5, 1, ..., 2, 3, 3]) + >>> np.insert(a, 1, 5, axis=1) + array([[1, 5, 1], + [2, 5, 2], + [3, 5, 3]]) + + Difference between sequence and scalars: + + >>> np.insert(a, [1], [[1],[2],[3]], axis=1) + array([[1, 1, 1], + [2, 2, 2], + [3, 3, 3]]) + >>> np.array_equal(np.insert(a, 1, [1, 2, 3], axis=1), + ... np.insert(a, [1], [[1],[2],[3]], axis=1)) + True + + >>> b = a.flatten() + >>> b + array([1, 1, 2, 2, 3, 3]) + >>> np.insert(b, [2, 2], [5, 6]) + array([1, 1, 5, ..., 2, 3, 3]) + + >>> np.insert(b, slice(2, 4), [5, 6]) + array([1, 1, 5, ..., 2, 3, 3]) + + >>> np.insert(b, [2, 2], [7.13, False]) # type casting + array([1, 1, 7, ..., 2, 3, 3]) + + >>> x = np.arange(8).reshape(2, 4) + >>> idx = (1, 3) + >>> np.insert(x, idx, 999, axis=1) + array([[ 0, 999, 1, 2, 999, 3], + [ 4, 999, 5, 6, 999, 7]]) + + """ + wrap = None + if type(arr) is not ndarray: + try: + wrap = arr.__array_wrap__ + except AttributeError: + pass + + arr = asarray(arr) + ndim = arr.ndim + arrorder = 'F' if arr.flags.fnc else 'C' + if axis is None: + if ndim != 1: + arr = arr.ravel() + # needed for np.matrix, which is still not 1d after being ravelled + ndim = arr.ndim + axis = ndim - 1 + else: + axis = normalize_axis_index(axis, ndim) + slobj = [slice(None)]*ndim + N = arr.shape[axis] + newshape = list(arr.shape) + + if isinstance(obj, slice): + # turn it into a range object + indices = arange(*obj.indices(N), dtype=intp) + else: + # need to copy obj, because indices will be changed in-place + indices = np.array(obj) + if indices.dtype == bool: + # See also delete + # 2012-10-11, NumPy 1.8 + warnings.warn( + "in the future insert will treat boolean arrays and " + "array-likes as a boolean index instead of casting it to " + "integer", FutureWarning, stacklevel=3) + indices = indices.astype(intp) + # Code after warning period: + #if obj.ndim != 1: + # raise ValueError('boolean array argument obj to insert ' + # 'must be one dimensional') + #indices = np.flatnonzero(obj) + elif indices.ndim > 1: + raise ValueError( + "index array argument obj to insert must be one dimensional " + "or scalar") + if indices.size == 1: + index = indices.item() + if index < -N or index > N: + raise IndexError( + "index %i is out of bounds for axis %i with " + "size %i" % (obj, axis, N)) + if (index < 0): + index += N + + # There are some object array corner cases here, but we cannot avoid + # that: + values = array(values, copy=False, ndmin=arr.ndim, dtype=arr.dtype) + if indices.ndim == 0: + # broadcasting is very different here, since a[:,0,:] = ... behaves + # very different from a[:,[0],:] = ...! This changes values so that + # it works likes the second case. (here a[:,0:1,:]) + values = np.moveaxis(values, 0, axis) + numnew = values.shape[axis] + newshape[axis] += numnew + new = empty(newshape, arr.dtype, arrorder) + slobj[axis] = slice(None, index) + new[tuple(slobj)] = arr[tuple(slobj)] + slobj[axis] = slice(index, index+numnew) + new[tuple(slobj)] = values + slobj[axis] = slice(index+numnew, None) + slobj2 = [slice(None)] * ndim + slobj2[axis] = slice(index, None) + new[tuple(slobj)] = arr[tuple(slobj2)] + if wrap: + return wrap(new) + return new + elif indices.size == 0 and not isinstance(obj, np.ndarray): + # Can safely cast the empty list to intp + indices = indices.astype(intp) + + indices[indices < 0] += N + + numnew = len(indices) + order = indices.argsort(kind='mergesort') # stable sort + indices[order] += np.arange(numnew) + + newshape[axis] += numnew + old_mask = ones(newshape[axis], dtype=bool) + old_mask[indices] = False + + new = empty(newshape, arr.dtype, arrorder) + slobj2 = [slice(None)]*ndim + slobj[axis] = indices + slobj2[axis] = old_mask + new[tuple(slobj)] = values + new[tuple(slobj2)] = arr + + if wrap: + return wrap(new) + return new + + +def _append_dispatcher(arr, values, axis=None): + return (arr, values) + + +@array_function_dispatch(_append_dispatcher) +def append(arr, values, axis=None): + """ + Append values to the end of an array. + + Parameters + ---------- + arr : array_like + Values are appended to a copy of this array. + values : array_like + These values are appended to a copy of `arr`. It must be of the + correct shape (the same shape as `arr`, excluding `axis`). If + `axis` is not specified, `values` can be any shape and will be + flattened before use. + axis : int, optional + The axis along which `values` are appended. If `axis` is not + given, both `arr` and `values` are flattened before use. + + Returns + ------- + append : ndarray + A copy of `arr` with `values` appended to `axis`. Note that + `append` does not occur in-place: a new array is allocated and + filled. If `axis` is None, `out` is a flattened array. + + See Also + -------- + insert : Insert elements into an array. + delete : Delete elements from an array. + + Examples + -------- + >>> np.append([1, 2, 3], [[4, 5, 6], [7, 8, 9]]) + array([1, 2, 3, ..., 7, 8, 9]) + + When `axis` is specified, `values` must have the correct shape. + + >>> np.append([[1, 2, 3], [4, 5, 6]], [[7, 8, 9]], axis=0) + array([[1, 2, 3], + [4, 5, 6], + [7, 8, 9]]) + >>> np.append([[1, 2, 3], [4, 5, 6]], [7, 8, 9], axis=0) + Traceback (most recent call last): + ... + ValueError: all the input arrays must have same number of dimensions, but + the array at index 0 has 2 dimension(s) and the array at index 1 has 1 + dimension(s) + + """ + arr = asanyarray(arr) + if axis is None: + if arr.ndim != 1: + arr = arr.ravel() + values = ravel(values) + axis = arr.ndim-1 + return concatenate((arr, values), axis=axis) + + +def _digitize_dispatcher(x, bins, right=None): + return (x, bins) + + +@array_function_dispatch(_digitize_dispatcher) +def digitize(x, bins, right=False): + """ + Return the indices of the bins to which each value in input array belongs. + + ========= ============= ============================ + `right` order of bins returned index `i` satisfies + ========= ============= ============================ + ``False`` increasing ``bins[i-1] <= x < bins[i]`` + ``True`` increasing ``bins[i-1] < x <= bins[i]`` + ``False`` decreasing ``bins[i-1] > x >= bins[i]`` + ``True`` decreasing ``bins[i-1] >= x > bins[i]`` + ========= ============= ============================ + + If values in `x` are beyond the bounds of `bins`, 0 or ``len(bins)`` is + returned as appropriate. + + Parameters + ---------- + x : array_like + Input array to be binned. Prior to NumPy 1.10.0, this array had to + be 1-dimensional, but can now have any shape. + bins : array_like + Array of bins. It has to be 1-dimensional and monotonic. + right : bool, optional + Indicating whether the intervals include the right or the left bin + edge. Default behavior is (right==False) indicating that the interval + does not include the right edge. The left bin end is open in this + case, i.e., bins[i-1] <= x < bins[i] is the default behavior for + monotonically increasing bins. + + Returns + ------- + indices : ndarray of ints + Output array of indices, of same shape as `x`. + + Raises + ------ + ValueError + If `bins` is not monotonic. + TypeError + If the type of the input is complex. + + See Also + -------- + bincount, histogram, unique, searchsorted + + Notes + ----- + If values in `x` are such that they fall outside the bin range, + attempting to index `bins` with the indices that `digitize` returns + will result in an IndexError. + + .. versionadded:: 1.10.0 + + `np.digitize` is implemented in terms of `np.searchsorted`. This means + that a binary search is used to bin the values, which scales much better + for larger number of bins than the previous linear search. It also removes + the requirement for the input array to be 1-dimensional. + + For monotonically _increasing_ `bins`, the following are equivalent:: + + np.digitize(x, bins, right=True) + np.searchsorted(bins, x, side='left') + + Note that as the order of the arguments are reversed, the side must be too. + The `searchsorted` call is marginally faster, as it does not do any + monotonicity checks. Perhaps more importantly, it supports all dtypes. + + Examples + -------- + >>> x = np.array([0.2, 6.4, 3.0, 1.6]) + >>> bins = np.array([0.0, 1.0, 2.5, 4.0, 10.0]) + >>> inds = np.digitize(x, bins) + >>> inds + array([1, 4, 3, 2]) + >>> for n in range(x.size): + ... print(bins[inds[n]-1], "<=", x[n], "<", bins[inds[n]]) + ... + 0.0 <= 0.2 < 1.0 + 4.0 <= 6.4 < 10.0 + 2.5 <= 3.0 < 4.0 + 1.0 <= 1.6 < 2.5 + + >>> x = np.array([1.2, 10.0, 12.4, 15.5, 20.]) + >>> bins = np.array([0, 5, 10, 15, 20]) + >>> np.digitize(x,bins,right=True) + array([1, 2, 3, 4, 4]) + >>> np.digitize(x,bins,right=False) + array([1, 3, 3, 4, 5]) + """ + x = _nx.asarray(x) + bins = _nx.asarray(bins) + + # here for compatibility, searchsorted below is happy to take this + if np.issubdtype(x.dtype, _nx.complexfloating): + raise TypeError("x may not be complex") + + mono = _monotonicity(bins) + if mono == 0: + raise ValueError("bins must be monotonically increasing or decreasing") + + # this is backwards because the arguments below are swapped + side = 'left' if right else 'right' + if mono == -1: + # reverse the bins, and invert the results + return len(bins) - _nx.searchsorted(bins[::-1], x, side=side) + else: + return _nx.searchsorted(bins, x, side=side) diff --git a/venv/Lib/site-packages/numpy/lib/histograms.py b/venv/Lib/site-packages/numpy/lib/histograms.py new file mode 100644 index 0000000..1a9b41c --- /dev/null +++ b/venv/Lib/site-packages/numpy/lib/histograms.py @@ -0,0 +1,1128 @@ +""" +Histogram-related functions +""" +import contextlib +import functools +import operator +import warnings + +import numpy as np +from numpy.core import overrides + +__all__ = ['histogram', 'histogramdd', 'histogram_bin_edges'] + +array_function_dispatch = functools.partial( + overrides.array_function_dispatch, module='numpy') + +# range is a keyword argument to many functions, so save the builtin so they can +# use it. +_range = range + + +def _ptp(x): + """Peak-to-peak value of x. + + This implementation avoids the problem of signed integer arrays having a + peak-to-peak value that cannot be represented with the array's data type. + This function returns an unsigned value for signed integer arrays. + """ + return _unsigned_subtract(x.max(), x.min()) + + +def _hist_bin_sqrt(x, range): + """ + Square root histogram bin estimator. + + Bin width is inversely proportional to the data size. Used by many + programs for its simplicity. + + Parameters + ---------- + x : array_like + Input data that is to be histogrammed, trimmed to range. May not + be empty. + + Returns + ------- + h : An estimate of the optimal bin width for the given data. + """ + del range # unused + return _ptp(x) / np.sqrt(x.size) + + +def _hist_bin_sturges(x, range): + """ + Sturges histogram bin estimator. + + A very simplistic estimator based on the assumption of normality of + the data. This estimator has poor performance for non-normal data, + which becomes especially obvious for large data sets. The estimate + depends only on size of the data. + + Parameters + ---------- + x : array_like + Input data that is to be histogrammed, trimmed to range. May not + be empty. + + Returns + ------- + h : An estimate of the optimal bin width for the given data. + """ + del range # unused + return _ptp(x) / (np.log2(x.size) + 1.0) + + +def _hist_bin_rice(x, range): + """ + Rice histogram bin estimator. + + Another simple estimator with no normality assumption. It has better + performance for large data than Sturges, but tends to overestimate + the number of bins. The number of bins is proportional to the cube + root of data size (asymptotically optimal). The estimate depends + only on size of the data. + + Parameters + ---------- + x : array_like + Input data that is to be histogrammed, trimmed to range. May not + be empty. + + Returns + ------- + h : An estimate of the optimal bin width for the given data. + """ + del range # unused + return _ptp(x) / (2.0 * x.size ** (1.0 / 3)) + + +def _hist_bin_scott(x, range): + """ + Scott histogram bin estimator. + + The binwidth is proportional to the standard deviation of the data + and inversely proportional to the cube root of data size + (asymptotically optimal). + + Parameters + ---------- + x : array_like + Input data that is to be histogrammed, trimmed to range. May not + be empty. + + Returns + ------- + h : An estimate of the optimal bin width for the given data. + """ + del range # unused + return (24.0 * np.pi**0.5 / x.size)**(1.0 / 3.0) * np.std(x) + + +def _hist_bin_stone(x, range): + """ + Histogram bin estimator based on minimizing the estimated integrated squared error (ISE). + + The number of bins is chosen by minimizing the estimated ISE against the unknown true distribution. + The ISE is estimated using cross-validation and can be regarded as a generalization of Scott's rule. + https://en.wikipedia.org/wiki/Histogram#Scott.27s_normal_reference_rule + + This paper by Stone appears to be the origination of this rule. + http://digitalassets.lib.berkeley.edu/sdtr/ucb/text/34.pdf + + Parameters + ---------- + x : array_like + Input data that is to be histogrammed, trimmed to range. May not + be empty. + range : (float, float) + The lower and upper range of the bins. + + Returns + ------- + h : An estimate of the optimal bin width for the given data. + """ + + n = x.size + ptp_x = _ptp(x) + if n <= 1 or ptp_x == 0: + return 0 + + def jhat(nbins): + hh = ptp_x / nbins + p_k = np.histogram(x, bins=nbins, range=range)[0] / n + return (2 - (n + 1) * p_k.dot(p_k)) / hh + + nbins_upper_bound = max(100, int(np.sqrt(n))) + nbins = min(_range(1, nbins_upper_bound + 1), key=jhat) + if nbins == nbins_upper_bound: + warnings.warn("The number of bins estimated may be suboptimal.", + RuntimeWarning, stacklevel=3) + return ptp_x / nbins + + +def _hist_bin_doane(x, range): + """ + Doane's histogram bin estimator. + + Improved version of Sturges' formula which works better for + non-normal data. See + stats.stackexchange.com/questions/55134/doanes-formula-for-histogram-binning + + Parameters + ---------- + x : array_like + Input data that is to be histogrammed, trimmed to range. May not + be empty. + + Returns + ------- + h : An estimate of the optimal bin width for the given data. + """ + del range # unused + if x.size > 2: + sg1 = np.sqrt(6.0 * (x.size - 2) / ((x.size + 1.0) * (x.size + 3))) + sigma = np.std(x) + if sigma > 0.0: + # These three operations add up to + # g1 = np.mean(((x - np.mean(x)) / sigma)**3) + # but use only one temp array instead of three + temp = x - np.mean(x) + np.true_divide(temp, sigma, temp) + np.power(temp, 3, temp) + g1 = np.mean(temp) + return _ptp(x) / (1.0 + np.log2(x.size) + + np.log2(1.0 + np.absolute(g1) / sg1)) + return 0.0 + + +def _hist_bin_fd(x, range): + """ + The Freedman-Diaconis histogram bin estimator. + + The Freedman-Diaconis rule uses interquartile range (IQR) to + estimate binwidth. It is considered a variation of the Scott rule + with more robustness as the IQR is less affected by outliers than + the standard deviation. However, the IQR depends on fewer points + than the standard deviation, so it is less accurate, especially for + long tailed distributions. + + If the IQR is 0, this function returns 0 for the bin width. + Binwidth is inversely proportional to the cube root of data size + (asymptotically optimal). + + Parameters + ---------- + x : array_like + Input data that is to be histogrammed, trimmed to range. May not + be empty. + + Returns + ------- + h : An estimate of the optimal bin width for the given data. + """ + del range # unused + iqr = np.subtract(*np.percentile(x, [75, 25])) + return 2.0 * iqr * x.size ** (-1.0 / 3.0) + + +def _hist_bin_auto(x, range): + """ + Histogram bin estimator that uses the minimum width of the + Freedman-Diaconis and Sturges estimators if the FD bin width is non-zero. + If the bin width from the FD estimator is 0, the Sturges estimator is used. + + The FD estimator is usually the most robust method, but its width + estimate tends to be too large for small `x` and bad for data with limited + variance. The Sturges estimator is quite good for small (<1000) datasets + and is the default in the R language. This method gives good off-the-shelf + behaviour. + + .. versionchanged:: 1.15.0 + If there is limited variance the IQR can be 0, which results in the + FD bin width being 0 too. This is not a valid bin width, so + ``np.histogram_bin_edges`` chooses 1 bin instead, which may not be optimal. + If the IQR is 0, it's unlikely any variance-based estimators will be of + use, so we revert to the Sturges estimator, which only uses the size of the + dataset in its calculation. + + Parameters + ---------- + x : array_like + Input data that is to be histogrammed, trimmed to range. May not + be empty. + + Returns + ------- + h : An estimate of the optimal bin width for the given data. + + See Also + -------- + _hist_bin_fd, _hist_bin_sturges + """ + fd_bw = _hist_bin_fd(x, range) + sturges_bw = _hist_bin_sturges(x, range) + del range # unused + if fd_bw: + return min(fd_bw, sturges_bw) + else: + # limited variance, so we return a len dependent bw estimator + return sturges_bw + +# Private dict initialized at module load time +_hist_bin_selectors = {'stone': _hist_bin_stone, + 'auto': _hist_bin_auto, + 'doane': _hist_bin_doane, + 'fd': _hist_bin_fd, + 'rice': _hist_bin_rice, + 'scott': _hist_bin_scott, + 'sqrt': _hist_bin_sqrt, + 'sturges': _hist_bin_sturges} + + +def _ravel_and_check_weights(a, weights): + """ Check a and weights have matching shapes, and ravel both """ + a = np.asarray(a) + + # Ensure that the array is a "subtractable" dtype + if a.dtype == np.bool_: + warnings.warn("Converting input from {} to {} for compatibility." + .format(a.dtype, np.uint8), + RuntimeWarning, stacklevel=3) + a = a.astype(np.uint8) + + if weights is not None: + weights = np.asarray(weights) + if weights.shape != a.shape: + raise ValueError( + 'weights should have the same shape as a.') + weights = weights.ravel() + a = a.ravel() + return a, weights + + +def _get_outer_edges(a, range): + """ + Determine the outer bin edges to use, from either the data or the range + argument + """ + if range is not None: + first_edge, last_edge = range + if first_edge > last_edge: + raise ValueError( + 'max must be larger than min in range parameter.') + if not (np.isfinite(first_edge) and np.isfinite(last_edge)): + raise ValueError( + "supplied range of [{}, {}] is not finite".format(first_edge, last_edge)) + elif a.size == 0: + # handle empty arrays. Can't determine range, so use 0-1. + first_edge, last_edge = 0, 1 + else: + first_edge, last_edge = a.min(), a.max() + if not (np.isfinite(first_edge) and np.isfinite(last_edge)): + raise ValueError( + "autodetected range of [{}, {}] is not finite".format(first_edge, last_edge)) + + # expand empty range to avoid divide by zero + if first_edge == last_edge: + first_edge = first_edge - 0.5 + last_edge = last_edge + 0.5 + + return first_edge, last_edge + + +def _unsigned_subtract(a, b): + """ + Subtract two values where a >= b, and produce an unsigned result + + This is needed when finding the difference between the upper and lower + bound of an int16 histogram + """ + # coerce to a single type + signed_to_unsigned = { + np.byte: np.ubyte, + np.short: np.ushort, + np.intc: np.uintc, + np.int_: np.uint, + np.longlong: np.ulonglong + } + dt = np.result_type(a, b) + try: + dt = signed_to_unsigned[dt.type] + except KeyError: + return np.subtract(a, b, dtype=dt) + else: + # we know the inputs are integers, and we are deliberately casting + # signed to unsigned + return np.subtract(a, b, casting='unsafe', dtype=dt) + + +def _get_bin_edges(a, bins, range, weights): + """ + Computes the bins used internally by `histogram`. + + Parameters + ========== + a : ndarray + Ravelled data array + bins, range + Forwarded arguments from `histogram`. + weights : ndarray, optional + Ravelled weights array, or None + + Returns + ======= + bin_edges : ndarray + Array of bin edges + uniform_bins : (Number, Number, int): + The upper bound, lowerbound, and number of bins, used in the optimized + implementation of `histogram` that works on uniform bins. + """ + # parse the overloaded bins argument + n_equal_bins = None + bin_edges = None + + if isinstance(bins, str): + bin_name = bins + # if `bins` is a string for an automatic method, + # this will replace it with the number of bins calculated + if bin_name not in _hist_bin_selectors: + raise ValueError( + "{!r} is not a valid estimator for `bins`".format(bin_name)) + if weights is not None: + raise TypeError("Automated estimation of the number of " + "bins is not supported for weighted data") + + first_edge, last_edge = _get_outer_edges(a, range) + + # truncate the range if needed + if range is not None: + keep = (a >= first_edge) + keep &= (a <= last_edge) + if not np.logical_and.reduce(keep): + a = a[keep] + + if a.size == 0: + n_equal_bins = 1 + else: + # Do not call selectors on empty arrays + width = _hist_bin_selectors[bin_name](a, (first_edge, last_edge)) + if width: + n_equal_bins = int(np.ceil(_unsigned_subtract(last_edge, first_edge) / width)) + else: + # Width can be zero for some estimators, e.g. FD when + # the IQR of the data is zero. + n_equal_bins = 1 + + elif np.ndim(bins) == 0: + try: + n_equal_bins = operator.index(bins) + except TypeError as e: + raise TypeError( + '`bins` must be an integer, a string, or an array') from e + if n_equal_bins < 1: + raise ValueError('`bins` must be positive, when an integer') + + first_edge, last_edge = _get_outer_edges(a, range) + + elif np.ndim(bins) == 1: + bin_edges = np.asarray(bins) + if np.any(bin_edges[:-1] > bin_edges[1:]): + raise ValueError( + '`bins` must increase monotonically, when an array') + + else: + raise ValueError('`bins` must be 1d, when an array') + + if n_equal_bins is not None: + # gh-10322 means that type resolution rules are dependent on array + # shapes. To avoid this causing problems, we pick a type now and stick + # with it throughout. + bin_type = np.result_type(first_edge, last_edge, a) + if np.issubdtype(bin_type, np.integer): + bin_type = np.result_type(bin_type, float) + + # bin edges must be computed + bin_edges = np.linspace( + first_edge, last_edge, n_equal_bins + 1, + endpoint=True, dtype=bin_type) + return bin_edges, (first_edge, last_edge, n_equal_bins) + else: + return bin_edges, None + + +def _search_sorted_inclusive(a, v): + """ + Like `searchsorted`, but where the last item in `v` is placed on the right. + + In the context of a histogram, this makes the last bin edge inclusive + """ + return np.concatenate(( + a.searchsorted(v[:-1], 'left'), + a.searchsorted(v[-1:], 'right') + )) + + +def _histogram_bin_edges_dispatcher(a, bins=None, range=None, weights=None): + return (a, bins, weights) + + +@array_function_dispatch(_histogram_bin_edges_dispatcher) +def histogram_bin_edges(a, bins=10, range=None, weights=None): + r""" + Function to calculate only the edges of the bins used by the `histogram` + function. + + Parameters + ---------- + a : array_like + Input data. The histogram is computed over the flattened array. + bins : int or sequence of scalars or str, optional + If `bins` is an int, it defines the number of equal-width + bins in the given range (10, by default). If `bins` is a + sequence, it defines the bin edges, including the rightmost + edge, allowing for non-uniform bin widths. + + If `bins` is a string from the list below, `histogram_bin_edges` will use + the method chosen to calculate the optimal bin width and + consequently the number of bins (see `Notes` for more detail on + the estimators) from the data that falls within the requested + range. While the bin width will be optimal for the actual data + in the range, the number of bins will be computed to fill the + entire range, including the empty portions. For visualisation, + using the 'auto' option is suggested. Weighted data is not + supported for automated bin size selection. + + 'auto' + Maximum of the 'sturges' and 'fd' estimators. Provides good + all around performance. + + 'fd' (Freedman Diaconis Estimator) + Robust (resilient to outliers) estimator that takes into + account data variability and data size. + + 'doane' + An improved version of Sturges' estimator that works better + with non-normal datasets. + + 'scott' + Less robust estimator that that takes into account data + variability and data size. + + 'stone' + Estimator based on leave-one-out cross-validation estimate of + the integrated squared error. Can be regarded as a generalization + of Scott's rule. + + 'rice' + Estimator does not take variability into account, only data + size. Commonly overestimates number of bins required. + + 'sturges' + R's default method, only accounts for data size. Only + optimal for gaussian data and underestimates number of bins + for large non-gaussian datasets. + + 'sqrt' + Square root (of data size) estimator, used by Excel and + other programs for its speed and simplicity. + + range : (float, float), optional + The lower and upper range of the bins. If not provided, range + is simply ``(a.min(), a.max())``. Values outside the range are + ignored. The first element of the range must be less than or + equal to the second. `range` affects the automatic bin + computation as well. While bin width is computed to be optimal + based on the actual data within `range`, the bin count will fill + the entire range including portions containing no data. + + weights : array_like, optional + An array of weights, of the same shape as `a`. Each value in + `a` only contributes its associated weight towards the bin count + (instead of 1). This is currently not used by any of the bin estimators, + but may be in the future. + + Returns + ------- + bin_edges : array of dtype float + The edges to pass into `histogram` + + See Also + -------- + histogram + + Notes + ----- + The methods to estimate the optimal number of bins are well founded + in literature, and are inspired by the choices R provides for + histogram visualisation. Note that having the number of bins + proportional to :math:`n^{1/3}` is asymptotically optimal, which is + why it appears in most estimators. These are simply plug-in methods + that give good starting points for number of bins. In the equations + below, :math:`h` is the binwidth and :math:`n_h` is the number of + bins. All estimators that compute bin counts are recast to bin width + using the `ptp` of the data. The final bin count is obtained from + ``np.round(np.ceil(range / h))``. + + 'auto' (maximum of the 'sturges' and 'fd' estimators) + A compromise to get a good value. For small datasets the Sturges + value will usually be chosen, while larger datasets will usually + default to FD. Avoids the overly conservative behaviour of FD + and Sturges for small and large datasets respectively. + Switchover point is usually :math:`a.size \approx 1000`. + + 'fd' (Freedman Diaconis Estimator) + .. math:: h = 2 \frac{IQR}{n^{1/3}} + + The binwidth is proportional to the interquartile range (IQR) + and inversely proportional to cube root of a.size. Can be too + conservative for small datasets, but is quite good for large + datasets. The IQR is very robust to outliers. + + 'scott' + .. math:: h = \sigma \sqrt[3]{\frac{24 * \sqrt{\pi}}{n}} + + The binwidth is proportional to the standard deviation of the + data and inversely proportional to cube root of ``x.size``. Can + be too conservative for small datasets, but is quite good for + large datasets. The standard deviation is not very robust to + outliers. Values are very similar to the Freedman-Diaconis + estimator in the absence of outliers. + + 'rice' + .. math:: n_h = 2n^{1/3} + + The number of bins is only proportional to cube root of + ``a.size``. It tends to overestimate the number of bins and it + does not take into account data variability. + + 'sturges' + .. math:: n_h = \log _{2}n+1 + + The number of bins is the base 2 log of ``a.size``. This + estimator assumes normality of data and is too conservative for + larger, non-normal datasets. This is the default method in R's + ``hist`` method. + + 'doane' + .. math:: n_h = 1 + \log_{2}(n) + + \log_{2}(1 + \frac{|g_1|}{\sigma_{g_1}}) + + g_1 = mean[(\frac{x - \mu}{\sigma})^3] + + \sigma_{g_1} = \sqrt{\frac{6(n - 2)}{(n + 1)(n + 3)}} + + An improved version of Sturges' formula that produces better + estimates for non-normal datasets. This estimator attempts to + account for the skew of the data. + + 'sqrt' + .. math:: n_h = \sqrt n + + The simplest and fastest estimator. Only takes into account the + data size. + + Examples + -------- + >>> arr = np.array([0, 0, 0, 1, 2, 3, 3, 4, 5]) + >>> np.histogram_bin_edges(arr, bins='auto', range=(0, 1)) + array([0. , 0.25, 0.5 , 0.75, 1. ]) + >>> np.histogram_bin_edges(arr, bins=2) + array([0. , 2.5, 5. ]) + + For consistency with histogram, an array of pre-computed bins is + passed through unmodified: + + >>> np.histogram_bin_edges(arr, [1, 2]) + array([1, 2]) + + This function allows one set of bins to be computed, and reused across + multiple histograms: + + >>> shared_bins = np.histogram_bin_edges(arr, bins='auto') + >>> shared_bins + array([0., 1., 2., 3., 4., 5.]) + + >>> group_id = np.array([0, 1, 1, 0, 1, 1, 0, 1, 1]) + >>> hist_0, _ = np.histogram(arr[group_id == 0], bins=shared_bins) + >>> hist_1, _ = np.histogram(arr[group_id == 1], bins=shared_bins) + + >>> hist_0; hist_1 + array([1, 1, 0, 1, 0]) + array([2, 0, 1, 1, 2]) + + Which gives more easily comparable results than using separate bins for + each histogram: + + >>> hist_0, bins_0 = np.histogram(arr[group_id == 0], bins='auto') + >>> hist_1, bins_1 = np.histogram(arr[group_id == 1], bins='auto') + >>> hist_0; hist_1 + array([1, 1, 1]) + array([2, 1, 1, 2]) + >>> bins_0; bins_1 + array([0., 1., 2., 3.]) + array([0. , 1.25, 2.5 , 3.75, 5. ]) + + """ + a, weights = _ravel_and_check_weights(a, weights) + bin_edges, _ = _get_bin_edges(a, bins, range, weights) + return bin_edges + + +def _histogram_dispatcher( + a, bins=None, range=None, normed=None, weights=None, density=None): + return (a, bins, weights) + + +@array_function_dispatch(_histogram_dispatcher) +def histogram(a, bins=10, range=None, normed=None, weights=None, + density=None): + r""" + Compute the histogram of a set of data. + + Parameters + ---------- + a : array_like + Input data. The histogram is computed over the flattened array. + bins : int or sequence of scalars or str, optional + If `bins` is an int, it defines the number of equal-width + bins in the given range (10, by default). If `bins` is a + sequence, it defines a monotonically increasing array of bin edges, + including the rightmost edge, allowing for non-uniform bin widths. + + .. versionadded:: 1.11.0 + + If `bins` is a string, it defines the method used to calculate the + optimal bin width, as defined by `histogram_bin_edges`. + + range : (float, float), optional + The lower and upper range of the bins. If not provided, range + is simply ``(a.min(), a.max())``. Values outside the range are + ignored. The first element of the range must be less than or + equal to the second. `range` affects the automatic bin + computation as well. While bin width is computed to be optimal + based on the actual data within `range`, the bin count will fill + the entire range including portions containing no data. + normed : bool, optional + + .. deprecated:: 1.6.0 + + This is equivalent to the `density` argument, but produces incorrect + results for unequal bin widths. It should not be used. + + .. versionchanged:: 1.15.0 + DeprecationWarnings are actually emitted. + + weights : array_like, optional + An array of weights, of the same shape as `a`. Each value in + `a` only contributes its associated weight towards the bin count + (instead of 1). If `density` is True, the weights are + normalized, so that the integral of the density over the range + remains 1. + density : bool, optional + If ``False``, the result will contain the number of samples in + each bin. If ``True``, the result is the value of the + probability *density* function at the bin, normalized such that + the *integral* over the range is 1. Note that the sum of the + histogram values will not be equal to 1 unless bins of unity + width are chosen; it is not a probability *mass* function. + + Overrides the ``normed`` keyword if given. + + Returns + ------- + hist : array + The values of the histogram. See `density` and `weights` for a + description of the possible semantics. + bin_edges : array of dtype float + Return the bin edges ``(length(hist)+1)``. + + + See Also + -------- + histogramdd, bincount, searchsorted, digitize, histogram_bin_edges + + Notes + ----- + All but the last (righthand-most) bin is half-open. In other words, + if `bins` is:: + + [1, 2, 3, 4] + + then the first bin is ``[1, 2)`` (including 1, but excluding 2) and + the second ``[2, 3)``. The last bin, however, is ``[3, 4]``, which + *includes* 4. + + + Examples + -------- + >>> np.histogram([1, 2, 1], bins=[0, 1, 2, 3]) + (array([0, 2, 1]), array([0, 1, 2, 3])) + >>> np.histogram(np.arange(4), bins=np.arange(5), density=True) + (array([0.25, 0.25, 0.25, 0.25]), array([0, 1, 2, 3, 4])) + >>> np.histogram([[1, 2, 1], [1, 0, 1]], bins=[0,1,2,3]) + (array([1, 4, 1]), array([0, 1, 2, 3])) + + >>> a = np.arange(5) + >>> hist, bin_edges = np.histogram(a, density=True) + >>> hist + array([0.5, 0. , 0.5, 0. , 0. , 0.5, 0. , 0.5, 0. , 0.5]) + >>> hist.sum() + 2.4999999999999996 + >>> np.sum(hist * np.diff(bin_edges)) + 1.0 + + .. versionadded:: 1.11.0 + + Automated Bin Selection Methods example, using 2 peak random data + with 2000 points: + + >>> import matplotlib.pyplot as plt + >>> rng = np.random.RandomState(10) # deterministic random data + >>> a = np.hstack((rng.normal(size=1000), + ... rng.normal(loc=5, scale=2, size=1000))) + >>> _ = plt.hist(a, bins='auto') # arguments are passed to np.histogram + >>> plt.title("Histogram with 'auto' bins") + Text(0.5, 1.0, "Histogram with 'auto' bins") + >>> plt.show() + + """ + a, weights = _ravel_and_check_weights(a, weights) + + bin_edges, uniform_bins = _get_bin_edges(a, bins, range, weights) + + # Histogram is an integer or a float array depending on the weights. + if weights is None: + ntype = np.dtype(np.intp) + else: + ntype = weights.dtype + + # We set a block size, as this allows us to iterate over chunks when + # computing histograms, to minimize memory usage. + BLOCK = 65536 + + # The fast path uses bincount, but that only works for certain types + # of weight + simple_weights = ( + weights is None or + np.can_cast(weights.dtype, np.double) or + np.can_cast(weights.dtype, complex) + ) + + if uniform_bins is not None and simple_weights: + # Fast algorithm for equal bins + # We now convert values of a to bin indices, under the assumption of + # equal bin widths (which is valid here). + first_edge, last_edge, n_equal_bins = uniform_bins + + # Initialize empty histogram + n = np.zeros(n_equal_bins, ntype) + + # Pre-compute histogram scaling factor + norm = n_equal_bins / _unsigned_subtract(last_edge, first_edge) + + # We iterate over blocks here for two reasons: the first is that for + # large arrays, it is actually faster (for example for a 10^8 array it + # is 2x as fast) and it results in a memory footprint 3x lower in the + # limit of large arrays. + for i in _range(0, len(a), BLOCK): + tmp_a = a[i:i+BLOCK] + if weights is None: + tmp_w = None + else: + tmp_w = weights[i:i + BLOCK] + + # Only include values in the right range + keep = (tmp_a >= first_edge) + keep &= (tmp_a <= last_edge) + if not np.logical_and.reduce(keep): + tmp_a = tmp_a[keep] + if tmp_w is not None: + tmp_w = tmp_w[keep] + + # This cast ensures no type promotions occur below, which gh-10322 + # make unpredictable. Getting it wrong leads to precision errors + # like gh-8123. + tmp_a = tmp_a.astype(bin_edges.dtype, copy=False) + + # Compute the bin indices, and for values that lie exactly on + # last_edge we need to subtract one + f_indices = _unsigned_subtract(tmp_a, first_edge) * norm + indices = f_indices.astype(np.intp) + indices[indices == n_equal_bins] -= 1 + + # The index computation is not guaranteed to give exactly + # consistent results within ~1 ULP of the bin edges. + decrement = tmp_a < bin_edges[indices] + indices[decrement] -= 1 + # The last bin includes the right edge. The other bins do not. + increment = ((tmp_a >= bin_edges[indices + 1]) + & (indices != n_equal_bins - 1)) + indices[increment] += 1 + + # We now compute the histogram using bincount + if ntype.kind == 'c': + n.real += np.bincount(indices, weights=tmp_w.real, + minlength=n_equal_bins) + n.imag += np.bincount(indices, weights=tmp_w.imag, + minlength=n_equal_bins) + else: + n += np.bincount(indices, weights=tmp_w, + minlength=n_equal_bins).astype(ntype) + else: + # Compute via cumulative histogram + cum_n = np.zeros(bin_edges.shape, ntype) + if weights is None: + for i in _range(0, len(a), BLOCK): + sa = np.sort(a[i:i+BLOCK]) + cum_n += _search_sorted_inclusive(sa, bin_edges) + else: + zero = np.zeros(1, dtype=ntype) + for i in _range(0, len(a), BLOCK): + tmp_a = a[i:i+BLOCK] + tmp_w = weights[i:i+BLOCK] + sorting_index = np.argsort(tmp_a) + sa = tmp_a[sorting_index] + sw = tmp_w[sorting_index] + cw = np.concatenate((zero, sw.cumsum())) + bin_index = _search_sorted_inclusive(sa, bin_edges) + cum_n += cw[bin_index] + + n = np.diff(cum_n) + + # density overrides the normed keyword + if density is not None: + if normed is not None: + # 2018-06-13, numpy 1.15.0 (this was not noisily deprecated in 1.6) + warnings.warn( + "The normed argument is ignored when density is provided. " + "In future passing both will result in an error.", + DeprecationWarning, stacklevel=3) + normed = None + + if density: + db = np.array(np.diff(bin_edges), float) + return n/db/n.sum(), bin_edges + elif normed: + # 2018-06-13, numpy 1.15.0 (this was not noisily deprecated in 1.6) + warnings.warn( + "Passing `normed=True` on non-uniform bins has always been " + "broken, and computes neither the probability density " + "function nor the probability mass function. " + "The result is only correct if the bins are uniform, when " + "density=True will produce the same result anyway. " + "The argument will be removed in a future version of " + "numpy.", + np.VisibleDeprecationWarning, stacklevel=3) + + # this normalization is incorrect, but + db = np.array(np.diff(bin_edges), float) + return n/(n*db).sum(), bin_edges + else: + if normed is not None: + # 2018-06-13, numpy 1.15.0 (this was not noisily deprecated in 1.6) + warnings.warn( + "Passing normed=False is deprecated, and has no effect. " + "Consider passing the density argument instead.", + DeprecationWarning, stacklevel=3) + return n, bin_edges + + +def _histogramdd_dispatcher(sample, bins=None, range=None, normed=None, + weights=None, density=None): + if hasattr(sample, 'shape'): # same condition as used in histogramdd + yield sample + else: + yield from sample + with contextlib.suppress(TypeError): + yield from bins + yield weights + + +@array_function_dispatch(_histogramdd_dispatcher) +def histogramdd(sample, bins=10, range=None, normed=None, weights=None, + density=None): + """ + Compute the multidimensional histogram of some data. + + Parameters + ---------- + sample : (N, D) array, or (D, N) array_like + The data to be histogrammed. + + Note the unusual interpretation of sample when an array_like: + + * When an array, each row is a coordinate in a D-dimensional space - + such as ``histogramdd(np.array([p1, p2, p3]))``. + * When an array_like, each element is the list of values for single + coordinate - such as ``histogramdd((X, Y, Z))``. + + The first form should be preferred. + + bins : sequence or int, optional + The bin specification: + + * A sequence of arrays describing the monotonically increasing bin + edges along each dimension. + * The number of bins for each dimension (nx, ny, ... =bins) + * The number of bins for all dimensions (nx=ny=...=bins). + + range : sequence, optional + A sequence of length D, each an optional (lower, upper) tuple giving + the outer bin edges to be used if the edges are not given explicitly in + `bins`. + An entry of None in the sequence results in the minimum and maximum + values being used for the corresponding dimension. + The default, None, is equivalent to passing a tuple of D None values. + density : bool, optional + If False, the default, returns the number of samples in each bin. + If True, returns the probability *density* function at the bin, + ``bin_count / sample_count / bin_volume``. + normed : bool, optional + An alias for the density argument that behaves identically. To avoid + confusion with the broken normed argument to `histogram`, `density` + should be preferred. + weights : (N,) array_like, optional + An array of values `w_i` weighing each sample `(x_i, y_i, z_i, ...)`. + Weights are normalized to 1 if normed is True. If normed is False, + the values of the returned histogram are equal to the sum of the + weights belonging to the samples falling into each bin. + + Returns + ------- + H : ndarray + The multidimensional histogram of sample x. See normed and weights + for the different possible semantics. + edges : list + A list of D arrays describing the bin edges for each dimension. + + See Also + -------- + histogram: 1-D histogram + histogram2d: 2-D histogram + + Examples + -------- + >>> r = np.random.randn(100,3) + >>> H, edges = np.histogramdd(r, bins = (5, 8, 4)) + >>> H.shape, edges[0].size, edges[1].size, edges[2].size + ((5, 8, 4), 6, 9, 5) + + """ + + try: + # Sample is an ND-array. + N, D = sample.shape + except (AttributeError, ValueError): + # Sample is a sequence of 1D arrays. + sample = np.atleast_2d(sample).T + N, D = sample.shape + + nbin = np.empty(D, int) + edges = D*[None] + dedges = D*[None] + if weights is not None: + weights = np.asarray(weights) + + try: + M = len(bins) + if M != D: + raise ValueError( + 'The dimension of bins must be equal to the dimension of the ' + ' sample x.') + except TypeError: + # bins is an integer + bins = D*[bins] + + # normalize the range argument + if range is None: + range = (None,) * D + elif len(range) != D: + raise ValueError('range argument must have one entry per dimension') + + # Create edge arrays + for i in _range(D): + if np.ndim(bins[i]) == 0: + if bins[i] < 1: + raise ValueError( + '`bins[{}]` must be positive, when an integer'.format(i)) + smin, smax = _get_outer_edges(sample[:,i], range[i]) + try: + n = operator.index(bins[i]) + + except TypeError as e: + raise TypeError( + "`bins[{}]` must be an integer, when a scalar".format(i) + ) from e + + edges[i] = np.linspace(smin, smax, n + 1) + elif np.ndim(bins[i]) == 1: + edges[i] = np.asarray(bins[i]) + if np.any(edges[i][:-1] > edges[i][1:]): + raise ValueError( + '`bins[{}]` must be monotonically increasing, when an array' + .format(i)) + else: + raise ValueError( + '`bins[{}]` must be a scalar or 1d array'.format(i)) + + nbin[i] = len(edges[i]) + 1 # includes an outlier on each end + dedges[i] = np.diff(edges[i]) + + # Compute the bin number each sample falls into. + Ncount = tuple( + # avoid np.digitize to work around gh-11022 + np.searchsorted(edges[i], sample[:, i], side='right') + for i in _range(D) + ) + + # Using digitize, values that fall on an edge are put in the right bin. + # For the rightmost bin, we want values equal to the right edge to be + # counted in the last bin, and not as an outlier. + for i in _range(D): + # Find which points are on the rightmost edge. + on_edge = (sample[:, i] == edges[i][-1]) + # Shift these points one bin to the left. + Ncount[i][on_edge] -= 1 + + # Compute the sample indices in the flattened histogram matrix. + # This raises an error if the array is too large. + xy = np.ravel_multi_index(Ncount, nbin) + + # Compute the number of repetitions in xy and assign it to the + # flattened histmat. + hist = np.bincount(xy, weights, minlength=nbin.prod()) + + # Shape into a proper matrix + hist = hist.reshape(nbin) + + # This preserves the (bad) behavior observed in gh-7845, for now. + hist = hist.astype(float, casting='safe') + + # Remove outliers (indices 0 and -1 for each dimension). + core = D*(slice(1, -1),) + hist = hist[core] + + # handle the aliasing normed argument + if normed is None: + if density is None: + density = False + elif density is None: + # an explicit normed argument was passed, alias it to the new name + density = normed + else: + raise TypeError("Cannot specify both 'normed' and 'density'") + + if density: + # calculate the probability density function + s = hist.sum() + for i in _range(D): + shape = np.ones(D, int) + shape[i] = nbin[i] - 2 + hist = hist / dedges[i].reshape(shape) + hist /= s + + if (hist.shape != nbin - 2).any(): + raise RuntimeError( + "Internal Shape Error") + return hist, edges diff --git a/venv/Lib/site-packages/numpy/lib/index_tricks.py b/venv/Lib/site-packages/numpy/lib/index_tricks.py new file mode 100644 index 0000000..9d3de69 --- /dev/null +++ b/venv/Lib/site-packages/numpy/lib/index_tricks.py @@ -0,0 +1,1003 @@ +import functools +import sys +import math +import warnings + +import numpy.core.numeric as _nx +from numpy.core.numeric import ( + asarray, ScalarType, array, alltrue, cumprod, arange, ndim + ) +from numpy.core.numerictypes import find_common_type, issubdtype + +import numpy.matrixlib as matrixlib +from .function_base import diff +from numpy.core.multiarray import ravel_multi_index, unravel_index +from numpy.core.overrides import set_module +from numpy.core import overrides, linspace +from numpy.lib.stride_tricks import as_strided + + +array_function_dispatch = functools.partial( + overrides.array_function_dispatch, module='numpy') + + +__all__ = [ + 'ravel_multi_index', 'unravel_index', 'mgrid', 'ogrid', 'r_', 'c_', + 's_', 'index_exp', 'ix_', 'ndenumerate', 'ndindex', 'fill_diagonal', + 'diag_indices', 'diag_indices_from' + ] + + +def _ix__dispatcher(*args): + return args + + +@array_function_dispatch(_ix__dispatcher) +def ix_(*args): + """ + Construct an open mesh from multiple sequences. + + This function takes N 1-D sequences and returns N outputs with N + dimensions each, such that the shape is 1 in all but one dimension + and the dimension with the non-unit shape value cycles through all + N dimensions. + + Using `ix_` one can quickly construct index arrays that will index + the cross product. ``a[np.ix_([1,3],[2,5])]`` returns the array + ``[[a[1,2] a[1,5]], [a[3,2] a[3,5]]]``. + + Parameters + ---------- + args : 1-D sequences + Each sequence should be of integer or boolean type. + Boolean sequences will be interpreted as boolean masks for the + corresponding dimension (equivalent to passing in + ``np.nonzero(boolean_sequence)``). + + Returns + ------- + out : tuple of ndarrays + N arrays with N dimensions each, with N the number of input + sequences. Together these arrays form an open mesh. + + See Also + -------- + ogrid, mgrid, meshgrid + + Examples + -------- + >>> a = np.arange(10).reshape(2, 5) + >>> a + array([[0, 1, 2, 3, 4], + [5, 6, 7, 8, 9]]) + >>> ixgrid = np.ix_([0, 1], [2, 4]) + >>> ixgrid + (array([[0], + [1]]), array([[2, 4]])) + >>> ixgrid[0].shape, ixgrid[1].shape + ((2, 1), (1, 2)) + >>> a[ixgrid] + array([[2, 4], + [7, 9]]) + + >>> ixgrid = np.ix_([True, True], [2, 4]) + >>> a[ixgrid] + array([[2, 4], + [7, 9]]) + >>> ixgrid = np.ix_([True, True], [False, False, True, False, True]) + >>> a[ixgrid] + array([[2, 4], + [7, 9]]) + + """ + out = [] + nd = len(args) + for k, new in enumerate(args): + if not isinstance(new, _nx.ndarray): + new = asarray(new) + if new.size == 0: + # Explicitly type empty arrays to avoid float default + new = new.astype(_nx.intp) + if new.ndim != 1: + raise ValueError("Cross index must be 1 dimensional") + if issubdtype(new.dtype, _nx.bool_): + new, = new.nonzero() + new = new.reshape((1,)*k + (new.size,) + (1,)*(nd-k-1)) + out.append(new) + return tuple(out) + +class nd_grid: + """ + Construct a multi-dimensional "meshgrid". + + ``grid = nd_grid()`` creates an instance which will return a mesh-grid + when indexed. The dimension and number of the output arrays are equal + to the number of indexing dimensions. If the step length is not a + complex number, then the stop is not inclusive. + + However, if the step length is a **complex number** (e.g. 5j), then the + integer part of its magnitude is interpreted as specifying the + number of points to create between the start and stop values, where + the stop value **is inclusive**. + + If instantiated with an argument of ``sparse=True``, the mesh-grid is + open (or not fleshed out) so that only one-dimension of each returned + argument is greater than 1. + + Parameters + ---------- + sparse : bool, optional + Whether the grid is sparse or not. Default is False. + + Notes + ----- + Two instances of `nd_grid` are made available in the NumPy namespace, + `mgrid` and `ogrid`, approximately defined as:: + + mgrid = nd_grid(sparse=False) + ogrid = nd_grid(sparse=True) + + Users should use these pre-defined instances instead of using `nd_grid` + directly. + """ + + def __init__(self, sparse=False): + self.sparse = sparse + + def __getitem__(self, key): + try: + size = [] + typ = int + for k in range(len(key)): + step = key[k].step + start = key[k].start + if start is None: + start = 0 + if step is None: + step = 1 + if isinstance(step, (_nx.complexfloating, complex)): + size.append(int(abs(step))) + typ = float + else: + size.append( + int(math.ceil((key[k].stop - start)/(step*1.0)))) + if (isinstance(step, (_nx.floating, float)) or + isinstance(start, (_nx.floating, float)) or + isinstance(key[k].stop, (_nx.floating, float))): + typ = float + if self.sparse: + nn = [_nx.arange(_x, dtype=_t) + for _x, _t in zip(size, (typ,)*len(size))] + else: + nn = _nx.indices(size, typ) + for k in range(len(size)): + step = key[k].step + start = key[k].start + if start is None: + start = 0 + if step is None: + step = 1 + if isinstance(step, (_nx.complexfloating, complex)): + step = int(abs(step)) + if step != 1: + step = (key[k].stop - start)/float(step-1) + nn[k] = (nn[k]*step+start) + if self.sparse: + slobj = [_nx.newaxis]*len(size) + for k in range(len(size)): + slobj[k] = slice(None, None) + nn[k] = nn[k][tuple(slobj)] + slobj[k] = _nx.newaxis + return nn + except (IndexError, TypeError): + step = key.step + stop = key.stop + start = key.start + if start is None: + start = 0 + if isinstance(step, (_nx.complexfloating, complex)): + step = abs(step) + length = int(step) + if step != 1: + step = (key.stop-start)/float(step-1) + stop = key.stop + step + return _nx.arange(0, length, 1, float)*step + start + else: + return _nx.arange(start, stop, step) + + +class MGridClass(nd_grid): + """ + `nd_grid` instance which returns a dense multi-dimensional "meshgrid". + + An instance of `numpy.lib.index_tricks.nd_grid` which returns an dense + (or fleshed out) mesh-grid when indexed, so that each returned argument + has the same shape. The dimensions and number of the output arrays are + equal to the number of indexing dimensions. If the step length is not a + complex number, then the stop is not inclusive. + + However, if the step length is a **complex number** (e.g. 5j), then + the integer part of its magnitude is interpreted as specifying the + number of points to create between the start and stop values, where + the stop value **is inclusive**. + + Returns + ------- + mesh-grid `ndarrays` all of the same dimensions + + See Also + -------- + numpy.lib.index_tricks.nd_grid : class of `ogrid` and `mgrid` objects + ogrid : like mgrid but returns open (not fleshed out) mesh grids + r_ : array concatenator + + Examples + -------- + >>> np.mgrid[0:5,0:5] + array([[[0, 0, 0, 0, 0], + [1, 1, 1, 1, 1], + [2, 2, 2, 2, 2], + [3, 3, 3, 3, 3], + [4, 4, 4, 4, 4]], + [[0, 1, 2, 3, 4], + [0, 1, 2, 3, 4], + [0, 1, 2, 3, 4], + [0, 1, 2, 3, 4], + [0, 1, 2, 3, 4]]]) + >>> np.mgrid[-1:1:5j] + array([-1. , -0.5, 0. , 0.5, 1. ]) + + """ + def __init__(self): + super(MGridClass, self).__init__(sparse=False) + +mgrid = MGridClass() + +class OGridClass(nd_grid): + """ + `nd_grid` instance which returns an open multi-dimensional "meshgrid". + + An instance of `numpy.lib.index_tricks.nd_grid` which returns an open + (i.e. not fleshed out) mesh-grid when indexed, so that only one dimension + of each returned array is greater than 1. The dimension and number of the + output arrays are equal to the number of indexing dimensions. If the step + length is not a complex number, then the stop is not inclusive. + + However, if the step length is a **complex number** (e.g. 5j), then + the integer part of its magnitude is interpreted as specifying the + number of points to create between the start and stop values, where + the stop value **is inclusive**. + + Returns + ------- + mesh-grid + `ndarrays` with only one dimension not equal to 1 + + See Also + -------- + np.lib.index_tricks.nd_grid : class of `ogrid` and `mgrid` objects + mgrid : like `ogrid` but returns dense (or fleshed out) mesh grids + r_ : array concatenator + + Examples + -------- + >>> from numpy import ogrid + >>> ogrid[-1:1:5j] + array([-1. , -0.5, 0. , 0.5, 1. ]) + >>> ogrid[0:5,0:5] + [array([[0], + [1], + [2], + [3], + [4]]), array([[0, 1, 2, 3, 4]])] + + """ + def __init__(self): + super(OGridClass, self).__init__(sparse=True) + +ogrid = OGridClass() + + +class AxisConcatenator: + """ + Translates slice objects to concatenation along an axis. + + For detailed documentation on usage, see `r_`. + """ + # allow ma.mr_ to override this + concatenate = staticmethod(_nx.concatenate) + makemat = staticmethod(matrixlib.matrix) + + def __init__(self, axis=0, matrix=False, ndmin=1, trans1d=-1): + self.axis = axis + self.matrix = matrix + self.trans1d = trans1d + self.ndmin = ndmin + + def __getitem__(self, key): + # handle matrix builder syntax + if isinstance(key, str): + frame = sys._getframe().f_back + mymat = matrixlib.bmat(key, frame.f_globals, frame.f_locals) + return mymat + + if not isinstance(key, tuple): + key = (key,) + + # copy attributes, since they can be overridden in the first argument + trans1d = self.trans1d + ndmin = self.ndmin + matrix = self.matrix + axis = self.axis + + objs = [] + scalars = [] + arraytypes = [] + scalartypes = [] + + for k, item in enumerate(key): + scalar = False + if isinstance(item, slice): + step = item.step + start = item.start + stop = item.stop + if start is None: + start = 0 + if step is None: + step = 1 + if isinstance(step, (_nx.complexfloating, complex)): + size = int(abs(step)) + newobj = linspace(start, stop, num=size) + else: + newobj = _nx.arange(start, stop, step) + if ndmin > 1: + newobj = array(newobj, copy=False, ndmin=ndmin) + if trans1d != -1: + newobj = newobj.swapaxes(-1, trans1d) + elif isinstance(item, str): + if k != 0: + raise ValueError("special directives must be the " + "first entry.") + if item in ('r', 'c'): + matrix = True + col = (item == 'c') + continue + if ',' in item: + vec = item.split(',') + try: + axis, ndmin = [int(x) for x in vec[:2]] + if len(vec) == 3: + trans1d = int(vec[2]) + continue + except Exception as e: + raise ValueError( + "unknown special directive {!r}".format(item) + ) from e + try: + axis = int(item) + continue + except (ValueError, TypeError): + raise ValueError("unknown special directive") + elif type(item) in ScalarType: + newobj = array(item, ndmin=ndmin) + scalars.append(len(objs)) + scalar = True + scalartypes.append(newobj.dtype) + else: + item_ndim = ndim(item) + newobj = array(item, copy=False, subok=True, ndmin=ndmin) + if trans1d != -1 and item_ndim < ndmin: + k2 = ndmin - item_ndim + k1 = trans1d + if k1 < 0: + k1 += k2 + 1 + defaxes = list(range(ndmin)) + axes = defaxes[:k1] + defaxes[k2:] + defaxes[k1:k2] + newobj = newobj.transpose(axes) + objs.append(newobj) + if not scalar and isinstance(newobj, _nx.ndarray): + arraytypes.append(newobj.dtype) + + # Ensure that scalars won't up-cast unless warranted + final_dtype = find_common_type(arraytypes, scalartypes) + if final_dtype is not None: + for k in scalars: + objs[k] = objs[k].astype(final_dtype) + + res = self.concatenate(tuple(objs), axis=axis) + + if matrix: + oldndim = res.ndim + res = self.makemat(res) + if oldndim == 1 and col: + res = res.T + return res + + def __len__(self): + return 0 + +# separate classes are used here instead of just making r_ = concatentor(0), +# etc. because otherwise we couldn't get the doc string to come out right +# in help(r_) + +class RClass(AxisConcatenator): + """ + Translates slice objects to concatenation along the first axis. + + This is a simple way to build up arrays quickly. There are two use cases. + + 1. If the index expression contains comma separated arrays, then stack + them along their first axis. + 2. If the index expression contains slice notation or scalars then create + a 1-D array with a range indicated by the slice notation. + + If slice notation is used, the syntax ``start:stop:step`` is equivalent + to ``np.arange(start, stop, step)`` inside of the brackets. However, if + ``step`` is an imaginary number (i.e. 100j) then its integer portion is + interpreted as a number-of-points desired and the start and stop are + inclusive. In other words ``start:stop:stepj`` is interpreted as + ``np.linspace(start, stop, step, endpoint=1)`` inside of the brackets. + After expansion of slice notation, all comma separated sequences are + concatenated together. + + Optional character strings placed as the first element of the index + expression can be used to change the output. The strings 'r' or 'c' result + in matrix output. If the result is 1-D and 'r' is specified a 1 x N (row) + matrix is produced. If the result is 1-D and 'c' is specified, then a N x 1 + (column) matrix is produced. If the result is 2-D then both provide the + same matrix result. + + A string integer specifies which axis to stack multiple comma separated + arrays along. A string of two comma-separated integers allows indication + of the minimum number of dimensions to force each entry into as the + second integer (the axis to concatenate along is still the first integer). + + A string with three comma-separated integers allows specification of the + axis to concatenate along, the minimum number of dimensions to force the + entries to, and which axis should contain the start of the arrays which + are less than the specified number of dimensions. In other words the third + integer allows you to specify where the 1's should be placed in the shape + of the arrays that have their shapes upgraded. By default, they are placed + in the front of the shape tuple. The third argument allows you to specify + where the start of the array should be instead. Thus, a third argument of + '0' would place the 1's at the end of the array shape. Negative integers + specify where in the new shape tuple the last dimension of upgraded arrays + should be placed, so the default is '-1'. + + Parameters + ---------- + Not a function, so takes no parameters + + + Returns + ------- + A concatenated ndarray or matrix. + + See Also + -------- + concatenate : Join a sequence of arrays along an existing axis. + c_ : Translates slice objects to concatenation along the second axis. + + Examples + -------- + >>> np.r_[np.array([1,2,3]), 0, 0, np.array([4,5,6])] + array([1, 2, 3, ..., 4, 5, 6]) + >>> np.r_[-1:1:6j, [0]*3, 5, 6] + array([-1. , -0.6, -0.2, 0.2, 0.6, 1. , 0. , 0. , 0. , 5. , 6. ]) + + String integers specify the axis to concatenate along or the minimum + number of dimensions to force entries into. + + >>> a = np.array([[0, 1, 2], [3, 4, 5]]) + >>> np.r_['-1', a, a] # concatenate along last axis + array([[0, 1, 2, 0, 1, 2], + [3, 4, 5, 3, 4, 5]]) + >>> np.r_['0,2', [1,2,3], [4,5,6]] # concatenate along first axis, dim>=2 + array([[1, 2, 3], + [4, 5, 6]]) + + >>> np.r_['0,2,0', [1,2,3], [4,5,6]] + array([[1], + [2], + [3], + [4], + [5], + [6]]) + >>> np.r_['1,2,0', [1,2,3], [4,5,6]] + array([[1, 4], + [2, 5], + [3, 6]]) + + Using 'r' or 'c' as a first string argument creates a matrix. + + >>> np.r_['r',[1,2,3], [4,5,6]] + matrix([[1, 2, 3, 4, 5, 6]]) + + """ + + def __init__(self): + AxisConcatenator.__init__(self, 0) + +r_ = RClass() + +class CClass(AxisConcatenator): + """ + Translates slice objects to concatenation along the second axis. + + This is short-hand for ``np.r_['-1,2,0', index expression]``, which is + useful because of its common occurrence. In particular, arrays will be + stacked along their last axis after being upgraded to at least 2-D with + 1's post-pended to the shape (column vectors made out of 1-D arrays). + + See Also + -------- + column_stack : Stack 1-D arrays as columns into a 2-D array. + r_ : For more detailed documentation. + + Examples + -------- + >>> np.c_[np.array([1,2,3]), np.array([4,5,6])] + array([[1, 4], + [2, 5], + [3, 6]]) + >>> np.c_[np.array([[1,2,3]]), 0, 0, np.array([[4,5,6]])] + array([[1, 2, 3, ..., 4, 5, 6]]) + + """ + + def __init__(self): + AxisConcatenator.__init__(self, -1, ndmin=2, trans1d=0) + + +c_ = CClass() + + +@set_module('numpy') +class ndenumerate: + """ + Multidimensional index iterator. + + Return an iterator yielding pairs of array coordinates and values. + + Parameters + ---------- + arr : ndarray + Input array. + + See Also + -------- + ndindex, flatiter + + Examples + -------- + >>> a = np.array([[1, 2], [3, 4]]) + >>> for index, x in np.ndenumerate(a): + ... print(index, x) + (0, 0) 1 + (0, 1) 2 + (1, 0) 3 + (1, 1) 4 + + """ + + def __init__(self, arr): + self.iter = asarray(arr).flat + + def __next__(self): + """ + Standard iterator method, returns the index tuple and array value. + + Returns + ------- + coords : tuple of ints + The indices of the current iteration. + val : scalar + The array element of the current iteration. + + """ + return self.iter.coords, next(self.iter) + + def __iter__(self): + return self + + +@set_module('numpy') +class ndindex: + """ + An N-dimensional iterator object to index arrays. + + Given the shape of an array, an `ndindex` instance iterates over + the N-dimensional index of the array. At each iteration a tuple + of indices is returned, the last dimension is iterated over first. + + Parameters + ---------- + shape : ints, or a single tuple of ints + The size of each dimension of the array can be passed as + individual parameters or as the elements of a tuple. + + See Also + -------- + ndenumerate, flatiter + + Examples + -------- + # dimensions as individual arguments + >>> for index in np.ndindex(3, 2, 1): + ... print(index) + (0, 0, 0) + (0, 1, 0) + (1, 0, 0) + (1, 1, 0) + (2, 0, 0) + (2, 1, 0) + + # same dimensions - but in a tuple (3, 2, 1) + >>> for index in np.ndindex((3, 2, 1)): + ... print(index) + (0, 0, 0) + (0, 1, 0) + (1, 0, 0) + (1, 1, 0) + (2, 0, 0) + (2, 1, 0) + + """ + + def __init__(self, *shape): + if len(shape) == 1 and isinstance(shape[0], tuple): + shape = shape[0] + x = as_strided(_nx.zeros(1), shape=shape, + strides=_nx.zeros_like(shape)) + self._it = _nx.nditer(x, flags=['multi_index', 'zerosize_ok'], + order='C') + + def __iter__(self): + return self + + def ndincr(self): + """ + Increment the multi-dimensional index by one. + + This method is for backward compatibility only: do not use. + + .. deprecated:: 1.20.0 + This method has been advised against since numpy 1.8.0, but only + started emitting DeprecationWarning as of this version. + """ + # NumPy 1.20.0, 2020-09-08 + warnings.warn( + "`ndindex.ndincr()` is deprecated, use `next(ndindex)` instead", + DeprecationWarning, stacklevel=2) + next(self) + + def __next__(self): + """ + Standard iterator method, updates the index and returns the index + tuple. + + Returns + ------- + val : tuple of ints + Returns a tuple containing the indices of the current + iteration. + + """ + next(self._it) + return self._it.multi_index + + +# You can do all this with slice() plus a few special objects, +# but there's a lot to remember. This version is simpler because +# it uses the standard array indexing syntax. +# +# Written by Konrad Hinsen +# last revision: 1999-7-23 +# +# Cosmetic changes by T. Oliphant 2001 +# +# + +class IndexExpression: + """ + A nicer way to build up index tuples for arrays. + + .. note:: + Use one of the two predefined instances `index_exp` or `s_` + rather than directly using `IndexExpression`. + + For any index combination, including slicing and axis insertion, + ``a[indices]`` is the same as ``a[np.index_exp[indices]]`` for any + array `a`. However, ``np.index_exp[indices]`` can be used anywhere + in Python code and returns a tuple of slice objects that can be + used in the construction of complex index expressions. + + Parameters + ---------- + maketuple : bool + If True, always returns a tuple. + + See Also + -------- + index_exp : Predefined instance that always returns a tuple: + `index_exp = IndexExpression(maketuple=True)`. + s_ : Predefined instance without tuple conversion: + `s_ = IndexExpression(maketuple=False)`. + + Notes + ----- + You can do all this with `slice()` plus a few special objects, + but there's a lot to remember and this version is simpler because + it uses the standard array indexing syntax. + + Examples + -------- + >>> np.s_[2::2] + slice(2, None, 2) + >>> np.index_exp[2::2] + (slice(2, None, 2),) + + >>> np.array([0, 1, 2, 3, 4])[np.s_[2::2]] + array([2, 4]) + + """ + + def __init__(self, maketuple): + self.maketuple = maketuple + + def __getitem__(self, item): + if self.maketuple and not isinstance(item, tuple): + return (item,) + else: + return item + +index_exp = IndexExpression(maketuple=True) +s_ = IndexExpression(maketuple=False) + +# End contribution from Konrad. + + +# The following functions complement those in twodim_base, but are +# applicable to N-dimensions. + + +def _fill_diagonal_dispatcher(a, val, wrap=None): + return (a,) + + +@array_function_dispatch(_fill_diagonal_dispatcher) +def fill_diagonal(a, val, wrap=False): + """Fill the main diagonal of the given array of any dimensionality. + + For an array `a` with ``a.ndim >= 2``, the diagonal is the list of + locations with indices ``a[i, ..., i]`` all identical. This function + modifies the input array in-place, it does not return a value. + + Parameters + ---------- + a : array, at least 2-D. + Array whose diagonal is to be filled, it gets modified in-place. + + val : scalar or array_like + Value(s) to write on the diagonal. If `val` is scalar, the value is + written along the diagonal. If array-like, the flattened `val` is + written along the diagonal, repeating if necessary to fill all + diagonal entries. + + wrap : bool + For tall matrices in NumPy version up to 1.6.2, the + diagonal "wrapped" after N columns. You can have this behavior + with this option. This affects only tall matrices. + + See also + -------- + diag_indices, diag_indices_from + + Notes + ----- + .. versionadded:: 1.4.0 + + This functionality can be obtained via `diag_indices`, but internally + this version uses a much faster implementation that never constructs the + indices and uses simple slicing. + + Examples + -------- + >>> a = np.zeros((3, 3), int) + >>> np.fill_diagonal(a, 5) + >>> a + array([[5, 0, 0], + [0, 5, 0], + [0, 0, 5]]) + + The same function can operate on a 4-D array: + + >>> a = np.zeros((3, 3, 3, 3), int) + >>> np.fill_diagonal(a, 4) + + We only show a few blocks for clarity: + + >>> a[0, 0] + array([[4, 0, 0], + [0, 0, 0], + [0, 0, 0]]) + >>> a[1, 1] + array([[0, 0, 0], + [0, 4, 0], + [0, 0, 0]]) + >>> a[2, 2] + array([[0, 0, 0], + [0, 0, 0], + [0, 0, 4]]) + + The wrap option affects only tall matrices: + + >>> # tall matrices no wrap + >>> a = np.zeros((5, 3), int) + >>> np.fill_diagonal(a, 4) + >>> a + array([[4, 0, 0], + [0, 4, 0], + [0, 0, 4], + [0, 0, 0], + [0, 0, 0]]) + + >>> # tall matrices wrap + >>> a = np.zeros((5, 3), int) + >>> np.fill_diagonal(a, 4, wrap=True) + >>> a + array([[4, 0, 0], + [0, 4, 0], + [0, 0, 4], + [0, 0, 0], + [4, 0, 0]]) + + >>> # wide matrices + >>> a = np.zeros((3, 5), int) + >>> np.fill_diagonal(a, 4, wrap=True) + >>> a + array([[4, 0, 0, 0, 0], + [0, 4, 0, 0, 0], + [0, 0, 4, 0, 0]]) + + The anti-diagonal can be filled by reversing the order of elements + using either `numpy.flipud` or `numpy.fliplr`. + + >>> a = np.zeros((3, 3), int); + >>> np.fill_diagonal(np.fliplr(a), [1,2,3]) # Horizontal flip + >>> a + array([[0, 0, 1], + [0, 2, 0], + [3, 0, 0]]) + >>> np.fill_diagonal(np.flipud(a), [1,2,3]) # Vertical flip + >>> a + array([[0, 0, 3], + [0, 2, 0], + [1, 0, 0]]) + + Note that the order in which the diagonal is filled varies depending + on the flip function. + """ + if a.ndim < 2: + raise ValueError("array must be at least 2-d") + end = None + if a.ndim == 2: + # Explicit, fast formula for the common case. For 2-d arrays, we + # accept rectangular ones. + step = a.shape[1] + 1 + #This is needed to don't have tall matrix have the diagonal wrap. + if not wrap: + end = a.shape[1] * a.shape[1] + else: + # For more than d=2, the strided formula is only valid for arrays with + # all dimensions equal, so we check first. + if not alltrue(diff(a.shape) == 0): + raise ValueError("All dimensions of input must be of equal length") + step = 1 + (cumprod(a.shape[:-1])).sum() + + # Write the value out into the diagonal. + a.flat[:end:step] = val + + +@set_module('numpy') +def diag_indices(n, ndim=2): + """ + Return the indices to access the main diagonal of an array. + + This returns a tuple of indices that can be used to access the main + diagonal of an array `a` with ``a.ndim >= 2`` dimensions and shape + (n, n, ..., n). For ``a.ndim = 2`` this is the usual diagonal, for + ``a.ndim > 2`` this is the set of indices to access ``a[i, i, ..., i]`` + for ``i = [0..n-1]``. + + Parameters + ---------- + n : int + The size, along each dimension, of the arrays for which the returned + indices can be used. + + ndim : int, optional + The number of dimensions. + + See Also + -------- + diag_indices_from + + Notes + ----- + .. versionadded:: 1.4.0 + + Examples + -------- + Create a set of indices to access the diagonal of a (4, 4) array: + + >>> di = np.diag_indices(4) + >>> di + (array([0, 1, 2, 3]), array([0, 1, 2, 3])) + >>> a = np.arange(16).reshape(4, 4) + >>> a + array([[ 0, 1, 2, 3], + [ 4, 5, 6, 7], + [ 8, 9, 10, 11], + [12, 13, 14, 15]]) + >>> a[di] = 100 + >>> a + array([[100, 1, 2, 3], + [ 4, 100, 6, 7], + [ 8, 9, 100, 11], + [ 12, 13, 14, 100]]) + + Now, we create indices to manipulate a 3-D array: + + >>> d3 = np.diag_indices(2, 3) + >>> d3 + (array([0, 1]), array([0, 1]), array([0, 1])) + + And use it to set the diagonal of an array of zeros to 1: + + >>> a = np.zeros((2, 2, 2), dtype=int) + >>> a[d3] = 1 + >>> a + array([[[1, 0], + [0, 0]], + [[0, 0], + [0, 1]]]) + + """ + idx = arange(n) + return (idx,) * ndim + + +def _diag_indices_from(arr): + return (arr,) + + +@array_function_dispatch(_diag_indices_from) +def diag_indices_from(arr): + """ + Return the indices to access the main diagonal of an n-dimensional array. + + See `diag_indices` for full details. + + Parameters + ---------- + arr : array, at least 2-D + + See Also + -------- + diag_indices + + Notes + ----- + .. versionadded:: 1.4.0 + + """ + + if not arr.ndim >= 2: + raise ValueError("input array must be at least 2-d") + # For more than d=2, the strided formula is only valid for arrays with + # all dimensions equal, so we check first. + if not alltrue(diff(arr.shape) == 0): + raise ValueError("All dimensions of input must be of equal length") + + return diag_indices(arr.shape[0], arr.ndim) diff --git a/venv/Lib/site-packages/numpy/lib/mixins.py b/venv/Lib/site-packages/numpy/lib/mixins.py new file mode 100644 index 0000000..c81239f --- /dev/null +++ b/venv/Lib/site-packages/numpy/lib/mixins.py @@ -0,0 +1,176 @@ +"""Mixin classes for custom array types that don't inherit from ndarray.""" +from numpy.core import umath as um + + +__all__ = ['NDArrayOperatorsMixin'] + + +def _disables_array_ufunc(obj): + """True when __array_ufunc__ is set to None.""" + try: + return obj.__array_ufunc__ is None + except AttributeError: + return False + + +def _binary_method(ufunc, name): + """Implement a forward binary method with a ufunc, e.g., __add__.""" + def func(self, other): + if _disables_array_ufunc(other): + return NotImplemented + return ufunc(self, other) + func.__name__ = '__{}__'.format(name) + return func + + +def _reflected_binary_method(ufunc, name): + """Implement a reflected binary method with a ufunc, e.g., __radd__.""" + def func(self, other): + if _disables_array_ufunc(other): + return NotImplemented + return ufunc(other, self) + func.__name__ = '__r{}__'.format(name) + return func + + +def _inplace_binary_method(ufunc, name): + """Implement an in-place binary method with a ufunc, e.g., __iadd__.""" + def func(self, other): + return ufunc(self, other, out=(self,)) + func.__name__ = '__i{}__'.format(name) + return func + + +def _numeric_methods(ufunc, name): + """Implement forward, reflected and inplace binary methods with a ufunc.""" + return (_binary_method(ufunc, name), + _reflected_binary_method(ufunc, name), + _inplace_binary_method(ufunc, name)) + + +def _unary_method(ufunc, name): + """Implement a unary special method with a ufunc.""" + def func(self): + return ufunc(self) + func.__name__ = '__{}__'.format(name) + return func + + +class NDArrayOperatorsMixin: + """Mixin defining all operator special methods using __array_ufunc__. + + This class implements the special methods for almost all of Python's + builtin operators defined in the `operator` module, including comparisons + (``==``, ``>``, etc.) and arithmetic (``+``, ``*``, ``-``, etc.), by + deferring to the ``__array_ufunc__`` method, which subclasses must + implement. + + It is useful for writing classes that do not inherit from `numpy.ndarray`, + but that should support arithmetic and numpy universal functions like + arrays as described in `A Mechanism for Overriding Ufuncs + `_. + + As an trivial example, consider this implementation of an ``ArrayLike`` + class that simply wraps a NumPy array and ensures that the result of any + arithmetic operation is also an ``ArrayLike`` object:: + + class ArrayLike(np.lib.mixins.NDArrayOperatorsMixin): + def __init__(self, value): + self.value = np.asarray(value) + + # One might also consider adding the built-in list type to this + # list, to support operations like np.add(array_like, list) + _HANDLED_TYPES = (np.ndarray, numbers.Number) + + def __array_ufunc__(self, ufunc, method, *inputs, **kwargs): + out = kwargs.get('out', ()) + for x in inputs + out: + # Only support operations with instances of _HANDLED_TYPES. + # Use ArrayLike instead of type(self) for isinstance to + # allow subclasses that don't override __array_ufunc__ to + # handle ArrayLike objects. + if not isinstance(x, self._HANDLED_TYPES + (ArrayLike,)): + return NotImplemented + + # Defer to the implementation of the ufunc on unwrapped values. + inputs = tuple(x.value if isinstance(x, ArrayLike) else x + for x in inputs) + if out: + kwargs['out'] = tuple( + x.value if isinstance(x, ArrayLike) else x + for x in out) + result = getattr(ufunc, method)(*inputs, **kwargs) + + if type(result) is tuple: + # multiple return values + return tuple(type(self)(x) for x in result) + elif method == 'at': + # no return value + return None + else: + # one return value + return type(self)(result) + + def __repr__(self): + return '%s(%r)' % (type(self).__name__, self.value) + + In interactions between ``ArrayLike`` objects and numbers or numpy arrays, + the result is always another ``ArrayLike``: + + >>> x = ArrayLike([1, 2, 3]) + >>> x - 1 + ArrayLike(array([0, 1, 2])) + >>> 1 - x + ArrayLike(array([ 0, -1, -2])) + >>> np.arange(3) - x + ArrayLike(array([-1, -1, -1])) + >>> x - np.arange(3) + ArrayLike(array([1, 1, 1])) + + Note that unlike ``numpy.ndarray``, ``ArrayLike`` does not allow operations + with arbitrary, unrecognized types. This ensures that interactions with + ArrayLike preserve a well-defined casting hierarchy. + + .. versionadded:: 1.13 + """ + # Like np.ndarray, this mixin class implements "Option 1" from the ufunc + # overrides NEP. + + # comparisons don't have reflected and in-place versions + __lt__ = _binary_method(um.less, 'lt') + __le__ = _binary_method(um.less_equal, 'le') + __eq__ = _binary_method(um.equal, 'eq') + __ne__ = _binary_method(um.not_equal, 'ne') + __gt__ = _binary_method(um.greater, 'gt') + __ge__ = _binary_method(um.greater_equal, 'ge') + + # numeric methods + __add__, __radd__, __iadd__ = _numeric_methods(um.add, 'add') + __sub__, __rsub__, __isub__ = _numeric_methods(um.subtract, 'sub') + __mul__, __rmul__, __imul__ = _numeric_methods(um.multiply, 'mul') + __matmul__, __rmatmul__, __imatmul__ = _numeric_methods( + um.matmul, 'matmul') + # Python 3 does not use __div__, __rdiv__, or __idiv__ + __truediv__, __rtruediv__, __itruediv__ = _numeric_methods( + um.true_divide, 'truediv') + __floordiv__, __rfloordiv__, __ifloordiv__ = _numeric_methods( + um.floor_divide, 'floordiv') + __mod__, __rmod__, __imod__ = _numeric_methods(um.remainder, 'mod') + __divmod__ = _binary_method(um.divmod, 'divmod') + __rdivmod__ = _reflected_binary_method(um.divmod, 'divmod') + # __idivmod__ does not exist + # TODO: handle the optional third argument for __pow__? + __pow__, __rpow__, __ipow__ = _numeric_methods(um.power, 'pow') + __lshift__, __rlshift__, __ilshift__ = _numeric_methods( + um.left_shift, 'lshift') + __rshift__, __rrshift__, __irshift__ = _numeric_methods( + um.right_shift, 'rshift') + __and__, __rand__, __iand__ = _numeric_methods(um.bitwise_and, 'and') + __xor__, __rxor__, __ixor__ = _numeric_methods(um.bitwise_xor, 'xor') + __or__, __ror__, __ior__ = _numeric_methods(um.bitwise_or, 'or') + + # unary methods + __neg__ = _unary_method(um.negative, 'neg') + __pos__ = _unary_method(um.positive, 'pos') + __abs__ = _unary_method(um.absolute, 'abs') + __invert__ = _unary_method(um.invert, 'invert') diff --git a/venv/Lib/site-packages/numpy/lib/nanfunctions.py b/venv/Lib/site-packages/numpy/lib/nanfunctions.py new file mode 100644 index 0000000..409016a --- /dev/null +++ b/venv/Lib/site-packages/numpy/lib/nanfunctions.py @@ -0,0 +1,1670 @@ +""" +Functions that ignore NaN. + +Functions +--------- + +- `nanmin` -- minimum non-NaN value +- `nanmax` -- maximum non-NaN value +- `nanargmin` -- index of minimum non-NaN value +- `nanargmax` -- index of maximum non-NaN value +- `nansum` -- sum of non-NaN values +- `nanprod` -- product of non-NaN values +- `nancumsum` -- cumulative sum of non-NaN values +- `nancumprod` -- cumulative product of non-NaN values +- `nanmean` -- mean of non-NaN values +- `nanvar` -- variance of non-NaN values +- `nanstd` -- standard deviation of non-NaN values +- `nanmedian` -- median of non-NaN values +- `nanquantile` -- qth quantile of non-NaN values +- `nanpercentile` -- qth percentile of non-NaN values + +""" +import functools +import warnings +import numpy as np +from numpy.lib import function_base +from numpy.core import overrides + + +array_function_dispatch = functools.partial( + overrides.array_function_dispatch, module='numpy') + + +__all__ = [ + 'nansum', 'nanmax', 'nanmin', 'nanargmax', 'nanargmin', 'nanmean', + 'nanmedian', 'nanpercentile', 'nanvar', 'nanstd', 'nanprod', + 'nancumsum', 'nancumprod', 'nanquantile' + ] + + +def _nan_mask(a, out=None): + """ + Parameters + ---------- + a : array-like + Input array with at least 1 dimension. + out : ndarray, optional + Alternate output array in which to place the result. The default + is ``None``; if provided, it must have the same shape as the + expected output and will prevent the allocation of a new array. + + Returns + ------- + y : bool ndarray or True + A bool array where ``np.nan`` positions are marked with ``False`` + and other positions are marked with ``True``. If the type of ``a`` + is such that it can't possibly contain ``np.nan``, returns ``True``. + """ + # we assume that a is an array for this private function + + if a.dtype.kind not in 'fc': + return True + + y = np.isnan(a, out=out) + y = np.invert(y, out=y) + return y + +def _replace_nan(a, val): + """ + If `a` is of inexact type, make a copy of `a`, replace NaNs with + the `val` value, and return the copy together with a boolean mask + marking the locations where NaNs were present. If `a` is not of + inexact type, do nothing and return `a` together with a mask of None. + + Note that scalars will end up as array scalars, which is important + for using the result as the value of the out argument in some + operations. + + Parameters + ---------- + a : array-like + Input array. + val : float + NaN values are set to val before doing the operation. + + Returns + ------- + y : ndarray + If `a` is of inexact type, return a copy of `a` with the NaNs + replaced by the fill value, otherwise return `a`. + mask: {bool, None} + If `a` is of inexact type, return a boolean mask marking locations of + NaNs, otherwise return None. + + """ + a = np.asanyarray(a) + + if a.dtype == np.object_: + # object arrays do not support `isnan` (gh-9009), so make a guess + mask = np.not_equal(a, a, dtype=bool) + elif issubclass(a.dtype.type, np.inexact): + mask = np.isnan(a) + else: + mask = None + + if mask is not None: + a = np.array(a, subok=True, copy=True) + np.copyto(a, val, where=mask) + + return a, mask + + +def _copyto(a, val, mask): + """ + Replace values in `a` with NaN where `mask` is True. This differs from + copyto in that it will deal with the case where `a` is a numpy scalar. + + Parameters + ---------- + a : ndarray or numpy scalar + Array or numpy scalar some of whose values are to be replaced + by val. + val : numpy scalar + Value used a replacement. + mask : ndarray, scalar + Boolean array. Where True the corresponding element of `a` is + replaced by `val`. Broadcasts. + + Returns + ------- + res : ndarray, scalar + Array with elements replaced or scalar `val`. + + """ + if isinstance(a, np.ndarray): + np.copyto(a, val, where=mask, casting='unsafe') + else: + a = a.dtype.type(val) + return a + + +def _remove_nan_1d(arr1d, overwrite_input=False): + """ + Equivalent to arr1d[~arr1d.isnan()], but in a different order + + Presumably faster as it incurs fewer copies + + Parameters + ---------- + arr1d : ndarray + Array to remove nans from + overwrite_input : bool + True if `arr1d` can be modified in place + + Returns + ------- + res : ndarray + Array with nan elements removed + overwrite_input : bool + True if `res` can be modified in place, given the constraint on the + input + """ + + c = np.isnan(arr1d) + s = np.nonzero(c)[0] + if s.size == arr1d.size: + warnings.warn("All-NaN slice encountered", RuntimeWarning, + stacklevel=5) + return arr1d[:0], True + elif s.size == 0: + return arr1d, overwrite_input + else: + if not overwrite_input: + arr1d = arr1d.copy() + # select non-nans at end of array + enonan = arr1d[-s.size:][~c[-s.size:]] + # fill nans in beginning of array with non-nans of end + arr1d[s[:enonan.size]] = enonan + + return arr1d[:-s.size], True + + +def _divide_by_count(a, b, out=None): + """ + Compute a/b ignoring invalid results. If `a` is an array the division + is done in place. If `a` is a scalar, then its type is preserved in the + output. If out is None, then then a is used instead so that the + division is in place. Note that this is only called with `a` an inexact + type. + + Parameters + ---------- + a : {ndarray, numpy scalar} + Numerator. Expected to be of inexact type but not checked. + b : {ndarray, numpy scalar} + Denominator. + out : ndarray, optional + Alternate output array in which to place the result. The default + is ``None``; if provided, it must have the same shape as the + expected output, but the type will be cast if necessary. + + Returns + ------- + ret : {ndarray, numpy scalar} + The return value is a/b. If `a` was an ndarray the division is done + in place. If `a` is a numpy scalar, the division preserves its type. + + """ + with np.errstate(invalid='ignore', divide='ignore'): + if isinstance(a, np.ndarray): + if out is None: + return np.divide(a, b, out=a, casting='unsafe') + else: + return np.divide(a, b, out=out, casting='unsafe') + else: + if out is None: + return a.dtype.type(a / b) + else: + # This is questionable, but currently a numpy scalar can + # be output to a zero dimensional array. + return np.divide(a, b, out=out, casting='unsafe') + + +def _nanmin_dispatcher(a, axis=None, out=None, keepdims=None): + return (a, out) + + +@array_function_dispatch(_nanmin_dispatcher) +def nanmin(a, axis=None, out=None, keepdims=np._NoValue): + """ + Return minimum of an array or minimum along an axis, ignoring any NaNs. + When all-NaN slices are encountered a ``RuntimeWarning`` is raised and + Nan is returned for that slice. + + Parameters + ---------- + a : array_like + Array containing numbers whose minimum is desired. If `a` is not an + array, a conversion is attempted. + axis : {int, tuple of int, None}, optional + Axis or axes along which the minimum is computed. The default is to compute + the minimum of the flattened array. + out : ndarray, optional + Alternate output array in which to place the result. The default + is ``None``; if provided, it must have the same shape as the + expected output, but the type will be cast if necessary. See + :ref:`ufuncs-output-type` for more details. + + .. versionadded:: 1.8.0 + keepdims : bool, optional + If this is set to True, the axes which are reduced are left + in the result as dimensions with size one. With this option, + the result will broadcast correctly against the original `a`. + + If the value is anything but the default, then + `keepdims` will be passed through to the `min` method + of sub-classes of `ndarray`. If the sub-classes methods + does not implement `keepdims` any exceptions will be raised. + + .. versionadded:: 1.8.0 + + Returns + ------- + nanmin : ndarray + An array with the same shape as `a`, with the specified axis + removed. If `a` is a 0-d array, or if axis is None, an ndarray + scalar is returned. The same dtype as `a` is returned. + + See Also + -------- + nanmax : + The maximum value of an array along a given axis, ignoring any NaNs. + amin : + The minimum value of an array along a given axis, propagating any NaNs. + fmin : + Element-wise minimum of two arrays, ignoring any NaNs. + minimum : + Element-wise minimum of two arrays, propagating any NaNs. + isnan : + Shows which elements are Not a Number (NaN). + isfinite: + Shows which elements are neither NaN nor infinity. + + amax, fmax, maximum + + Notes + ----- + NumPy uses the IEEE Standard for Binary Floating-Point for Arithmetic + (IEEE 754). This means that Not a Number is not equivalent to infinity. + Positive infinity is treated as a very large number and negative + infinity is treated as a very small (i.e. negative) number. + + If the input has a integer type the function is equivalent to np.min. + + Examples + -------- + >>> a = np.array([[1, 2], [3, np.nan]]) + >>> np.nanmin(a) + 1.0 + >>> np.nanmin(a, axis=0) + array([1., 2.]) + >>> np.nanmin(a, axis=1) + array([1., 3.]) + + When positive infinity and negative infinity are present: + + >>> np.nanmin([1, 2, np.nan, np.inf]) + 1.0 + >>> np.nanmin([1, 2, np.nan, np.NINF]) + -inf + + """ + kwargs = {} + if keepdims is not np._NoValue: + kwargs['keepdims'] = keepdims + if type(a) is np.ndarray and a.dtype != np.object_: + # Fast, but not safe for subclasses of ndarray, or object arrays, + # which do not implement isnan (gh-9009), or fmin correctly (gh-8975) + res = np.fmin.reduce(a, axis=axis, out=out, **kwargs) + if np.isnan(res).any(): + warnings.warn("All-NaN slice encountered", RuntimeWarning, + stacklevel=3) + else: + # Slow, but safe for subclasses of ndarray + a, mask = _replace_nan(a, +np.inf) + res = np.amin(a, axis=axis, out=out, **kwargs) + if mask is None: + return res + + # Check for all-NaN axis + mask = np.all(mask, axis=axis, **kwargs) + if np.any(mask): + res = _copyto(res, np.nan, mask) + warnings.warn("All-NaN axis encountered", RuntimeWarning, + stacklevel=3) + return res + + +def _nanmax_dispatcher(a, axis=None, out=None, keepdims=None): + return (a, out) + + +@array_function_dispatch(_nanmax_dispatcher) +def nanmax(a, axis=None, out=None, keepdims=np._NoValue): + """ + Return the maximum of an array or maximum along an axis, ignoring any + NaNs. When all-NaN slices are encountered a ``RuntimeWarning`` is + raised and NaN is returned for that slice. + + Parameters + ---------- + a : array_like + Array containing numbers whose maximum is desired. If `a` is not an + array, a conversion is attempted. + axis : {int, tuple of int, None}, optional + Axis or axes along which the maximum is computed. The default is to compute + the maximum of the flattened array. + out : ndarray, optional + Alternate output array in which to place the result. The default + is ``None``; if provided, it must have the same shape as the + expected output, but the type will be cast if necessary. See + :ref:`ufuncs-output-type` for more details. + + .. versionadded:: 1.8.0 + keepdims : bool, optional + If this is set to True, the axes which are reduced are left + in the result as dimensions with size one. With this option, + the result will broadcast correctly against the original `a`. + + If the value is anything but the default, then + `keepdims` will be passed through to the `max` method + of sub-classes of `ndarray`. If the sub-classes methods + does not implement `keepdims` any exceptions will be raised. + + .. versionadded:: 1.8.0 + + Returns + ------- + nanmax : ndarray + An array with the same shape as `a`, with the specified axis removed. + If `a` is a 0-d array, or if axis is None, an ndarray scalar is + returned. The same dtype as `a` is returned. + + See Also + -------- + nanmin : + The minimum value of an array along a given axis, ignoring any NaNs. + amax : + The maximum value of an array along a given axis, propagating any NaNs. + fmax : + Element-wise maximum of two arrays, ignoring any NaNs. + maximum : + Element-wise maximum of two arrays, propagating any NaNs. + isnan : + Shows which elements are Not a Number (NaN). + isfinite: + Shows which elements are neither NaN nor infinity. + + amin, fmin, minimum + + Notes + ----- + NumPy uses the IEEE Standard for Binary Floating-Point for Arithmetic + (IEEE 754). This means that Not a Number is not equivalent to infinity. + Positive infinity is treated as a very large number and negative + infinity is treated as a very small (i.e. negative) number. + + If the input has a integer type the function is equivalent to np.max. + + Examples + -------- + >>> a = np.array([[1, 2], [3, np.nan]]) + >>> np.nanmax(a) + 3.0 + >>> np.nanmax(a, axis=0) + array([3., 2.]) + >>> np.nanmax(a, axis=1) + array([2., 3.]) + + When positive infinity and negative infinity are present: + + >>> np.nanmax([1, 2, np.nan, np.NINF]) + 2.0 + >>> np.nanmax([1, 2, np.nan, np.inf]) + inf + + """ + kwargs = {} + if keepdims is not np._NoValue: + kwargs['keepdims'] = keepdims + if type(a) is np.ndarray and a.dtype != np.object_: + # Fast, but not safe for subclasses of ndarray, or object arrays, + # which do not implement isnan (gh-9009), or fmax correctly (gh-8975) + res = np.fmax.reduce(a, axis=axis, out=out, **kwargs) + if np.isnan(res).any(): + warnings.warn("All-NaN slice encountered", RuntimeWarning, + stacklevel=3) + else: + # Slow, but safe for subclasses of ndarray + a, mask = _replace_nan(a, -np.inf) + res = np.amax(a, axis=axis, out=out, **kwargs) + if mask is None: + return res + + # Check for all-NaN axis + mask = np.all(mask, axis=axis, **kwargs) + if np.any(mask): + res = _copyto(res, np.nan, mask) + warnings.warn("All-NaN axis encountered", RuntimeWarning, + stacklevel=3) + return res + + +def _nanargmin_dispatcher(a, axis=None): + return (a,) + + +@array_function_dispatch(_nanargmin_dispatcher) +def nanargmin(a, axis=None): + """ + Return the indices of the minimum values in the specified axis ignoring + NaNs. For all-NaN slices ``ValueError`` is raised. Warning: the results + cannot be trusted if a slice contains only NaNs and Infs. + + Parameters + ---------- + a : array_like + Input data. + axis : int, optional + Axis along which to operate. By default flattened input is used. + + Returns + ------- + index_array : ndarray + An array of indices or a single index value. + + See Also + -------- + argmin, nanargmax + + Examples + -------- + >>> a = np.array([[np.nan, 4], [2, 3]]) + >>> np.argmin(a) + 0 + >>> np.nanargmin(a) + 2 + >>> np.nanargmin(a, axis=0) + array([1, 1]) + >>> np.nanargmin(a, axis=1) + array([1, 0]) + + """ + a, mask = _replace_nan(a, np.inf) + res = np.argmin(a, axis=axis) + if mask is not None: + mask = np.all(mask, axis=axis) + if np.any(mask): + raise ValueError("All-NaN slice encountered") + return res + + +def _nanargmax_dispatcher(a, axis=None): + return (a,) + + +@array_function_dispatch(_nanargmax_dispatcher) +def nanargmax(a, axis=None): + """ + Return the indices of the maximum values in the specified axis ignoring + NaNs. For all-NaN slices ``ValueError`` is raised. Warning: the + results cannot be trusted if a slice contains only NaNs and -Infs. + + + Parameters + ---------- + a : array_like + Input data. + axis : int, optional + Axis along which to operate. By default flattened input is used. + + Returns + ------- + index_array : ndarray + An array of indices or a single index value. + + See Also + -------- + argmax, nanargmin + + Examples + -------- + >>> a = np.array([[np.nan, 4], [2, 3]]) + >>> np.argmax(a) + 0 + >>> np.nanargmax(a) + 1 + >>> np.nanargmax(a, axis=0) + array([1, 0]) + >>> np.nanargmax(a, axis=1) + array([1, 1]) + + """ + a, mask = _replace_nan(a, -np.inf) + res = np.argmax(a, axis=axis) + if mask is not None: + mask = np.all(mask, axis=axis) + if np.any(mask): + raise ValueError("All-NaN slice encountered") + return res + + +def _nansum_dispatcher(a, axis=None, dtype=None, out=None, keepdims=None): + return (a, out) + + +@array_function_dispatch(_nansum_dispatcher) +def nansum(a, axis=None, dtype=None, out=None, keepdims=np._NoValue): + """ + Return the sum of array elements over a given axis treating Not a + Numbers (NaNs) as zero. + + In NumPy versions <= 1.9.0 Nan is returned for slices that are all-NaN or + empty. In later versions zero is returned. + + Parameters + ---------- + a : array_like + Array containing numbers whose sum is desired. If `a` is not an + array, a conversion is attempted. + axis : {int, tuple of int, None}, optional + Axis or axes along which the sum is computed. The default is to compute the + sum of the flattened array. + dtype : data-type, optional + The type of the returned array and of the accumulator in which the + elements are summed. By default, the dtype of `a` is used. An + exception is when `a` has an integer type with less precision than + the platform (u)intp. In that case, the default will be either + (u)int32 or (u)int64 depending on whether the platform is 32 or 64 + bits. For inexact inputs, dtype must be inexact. + + .. versionadded:: 1.8.0 + out : ndarray, optional + Alternate output array in which to place the result. The default + is ``None``. If provided, it must have the same shape as the + expected output, but the type will be cast if necessary. See + :ref:`ufuncs-output-type` for more details. The casting of NaN to integer + can yield unexpected results. + + .. versionadded:: 1.8.0 + keepdims : bool, optional + If this is set to True, the axes which are reduced are left + in the result as dimensions with size one. With this option, + the result will broadcast correctly against the original `a`. + + + If the value is anything but the default, then + `keepdims` will be passed through to the `mean` or `sum` methods + of sub-classes of `ndarray`. If the sub-classes methods + does not implement `keepdims` any exceptions will be raised. + + .. versionadded:: 1.8.0 + + Returns + ------- + nansum : ndarray. + A new array holding the result is returned unless `out` is + specified, in which it is returned. The result has the same + size as `a`, and the same shape as `a` if `axis` is not None + or `a` is a 1-d array. + + See Also + -------- + numpy.sum : Sum across array propagating NaNs. + isnan : Show which elements are NaN. + isfinite: Show which elements are not NaN or +/-inf. + + Notes + ----- + If both positive and negative infinity are present, the sum will be Not + A Number (NaN). + + Examples + -------- + >>> np.nansum(1) + 1 + >>> np.nansum([1]) + 1 + >>> np.nansum([1, np.nan]) + 1.0 + >>> a = np.array([[1, 1], [1, np.nan]]) + >>> np.nansum(a) + 3.0 + >>> np.nansum(a, axis=0) + array([2., 1.]) + >>> np.nansum([1, np.nan, np.inf]) + inf + >>> np.nansum([1, np.nan, np.NINF]) + -inf + >>> from numpy.testing import suppress_warnings + >>> with suppress_warnings() as sup: + ... sup.filter(RuntimeWarning) + ... np.nansum([1, np.nan, np.inf, -np.inf]) # both +/- infinity present + nan + + """ + a, mask = _replace_nan(a, 0) + return np.sum(a, axis=axis, dtype=dtype, out=out, keepdims=keepdims) + + +def _nanprod_dispatcher(a, axis=None, dtype=None, out=None, keepdims=None): + return (a, out) + + +@array_function_dispatch(_nanprod_dispatcher) +def nanprod(a, axis=None, dtype=None, out=None, keepdims=np._NoValue): + """ + Return the product of array elements over a given axis treating Not a + Numbers (NaNs) as ones. + + One is returned for slices that are all-NaN or empty. + + .. versionadded:: 1.10.0 + + Parameters + ---------- + a : array_like + Array containing numbers whose product is desired. If `a` is not an + array, a conversion is attempted. + axis : {int, tuple of int, None}, optional + Axis or axes along which the product is computed. The default is to compute + the product of the flattened array. + dtype : data-type, optional + The type of the returned array and of the accumulator in which the + elements are summed. By default, the dtype of `a` is used. An + exception is when `a` has an integer type with less precision than + the platform (u)intp. In that case, the default will be either + (u)int32 or (u)int64 depending on whether the platform is 32 or 64 + bits. For inexact inputs, dtype must be inexact. + out : ndarray, optional + Alternate output array in which to place the result. The default + is ``None``. If provided, it must have the same shape as the + expected output, but the type will be cast if necessary. See + :ref:`ufuncs-output-type` for more details. The casting of NaN to integer + can yield unexpected results. + keepdims : bool, optional + If True, the axes which are reduced are left in the result as + dimensions with size one. With this option, the result will + broadcast correctly against the original `arr`. + + Returns + ------- + nanprod : ndarray + A new array holding the result is returned unless `out` is + specified, in which case it is returned. + + See Also + -------- + numpy.prod : Product across array propagating NaNs. + isnan : Show which elements are NaN. + + Examples + -------- + >>> np.nanprod(1) + 1 + >>> np.nanprod([1]) + 1 + >>> np.nanprod([1, np.nan]) + 1.0 + >>> a = np.array([[1, 2], [3, np.nan]]) + >>> np.nanprod(a) + 6.0 + >>> np.nanprod(a, axis=0) + array([3., 2.]) + + """ + a, mask = _replace_nan(a, 1) + return np.prod(a, axis=axis, dtype=dtype, out=out, keepdims=keepdims) + + +def _nancumsum_dispatcher(a, axis=None, dtype=None, out=None): + return (a, out) + + +@array_function_dispatch(_nancumsum_dispatcher) +def nancumsum(a, axis=None, dtype=None, out=None): + """ + Return the cumulative sum of array elements over a given axis treating Not a + Numbers (NaNs) as zero. The cumulative sum does not change when NaNs are + encountered and leading NaNs are replaced by zeros. + + Zeros are returned for slices that are all-NaN or empty. + + .. versionadded:: 1.12.0 + + Parameters + ---------- + a : array_like + Input array. + axis : int, optional + Axis along which the cumulative sum is computed. The default + (None) is to compute the cumsum over the flattened array. + dtype : dtype, optional + Type of the returned array and of the accumulator in which the + elements are summed. If `dtype` is not specified, it defaults + to the dtype of `a`, unless `a` has an integer dtype with a + precision less than that of the default platform integer. In + that case, the default platform integer is used. + out : ndarray, optional + Alternative output array in which to place the result. It must + have the same shape and buffer length as the expected output + but the type will be cast if necessary. See :ref:`ufuncs-output-type` for + more details. + + Returns + ------- + nancumsum : ndarray. + A new array holding the result is returned unless `out` is + specified, in which it is returned. The result has the same + size as `a`, and the same shape as `a` if `axis` is not None + or `a` is a 1-d array. + + See Also + -------- + numpy.cumsum : Cumulative sum across array propagating NaNs. + isnan : Show which elements are NaN. + + Examples + -------- + >>> np.nancumsum(1) + array([1]) + >>> np.nancumsum([1]) + array([1]) + >>> np.nancumsum([1, np.nan]) + array([1., 1.]) + >>> a = np.array([[1, 2], [3, np.nan]]) + >>> np.nancumsum(a) + array([1., 3., 6., 6.]) + >>> np.nancumsum(a, axis=0) + array([[1., 2.], + [4., 2.]]) + >>> np.nancumsum(a, axis=1) + array([[1., 3.], + [3., 3.]]) + + """ + a, mask = _replace_nan(a, 0) + return np.cumsum(a, axis=axis, dtype=dtype, out=out) + + +def _nancumprod_dispatcher(a, axis=None, dtype=None, out=None): + return (a, out) + + +@array_function_dispatch(_nancumprod_dispatcher) +def nancumprod(a, axis=None, dtype=None, out=None): + """ + Return the cumulative product of array elements over a given axis treating Not a + Numbers (NaNs) as one. The cumulative product does not change when NaNs are + encountered and leading NaNs are replaced by ones. + + Ones are returned for slices that are all-NaN or empty. + + .. versionadded:: 1.12.0 + + Parameters + ---------- + a : array_like + Input array. + axis : int, optional + Axis along which the cumulative product is computed. By default + the input is flattened. + dtype : dtype, optional + Type of the returned array, as well as of the accumulator in which + the elements are multiplied. If *dtype* is not specified, it + defaults to the dtype of `a`, unless `a` has an integer dtype with + a precision less than that of the default platform integer. In + that case, the default platform integer is used instead. + out : ndarray, optional + Alternative output array in which to place the result. It must + have the same shape and buffer length as the expected output + but the type of the resulting values will be cast if necessary. + + Returns + ------- + nancumprod : ndarray + A new array holding the result is returned unless `out` is + specified, in which case it is returned. + + See Also + -------- + numpy.cumprod : Cumulative product across array propagating NaNs. + isnan : Show which elements are NaN. + + Examples + -------- + >>> np.nancumprod(1) + array([1]) + >>> np.nancumprod([1]) + array([1]) + >>> np.nancumprod([1, np.nan]) + array([1., 1.]) + >>> a = np.array([[1, 2], [3, np.nan]]) + >>> np.nancumprod(a) + array([1., 2., 6., 6.]) + >>> np.nancumprod(a, axis=0) + array([[1., 2.], + [3., 2.]]) + >>> np.nancumprod(a, axis=1) + array([[1., 2.], + [3., 3.]]) + + """ + a, mask = _replace_nan(a, 1) + return np.cumprod(a, axis=axis, dtype=dtype, out=out) + + +def _nanmean_dispatcher(a, axis=None, dtype=None, out=None, keepdims=None): + return (a, out) + + +@array_function_dispatch(_nanmean_dispatcher) +def nanmean(a, axis=None, dtype=None, out=None, keepdims=np._NoValue): + """ + Compute the arithmetic mean along the specified axis, ignoring NaNs. + + Returns the average of the array elements. The average is taken over + the flattened array by default, otherwise over the specified axis. + `float64` intermediate and return values are used for integer inputs. + + For all-NaN slices, NaN is returned and a `RuntimeWarning` is raised. + + .. versionadded:: 1.8.0 + + Parameters + ---------- + a : array_like + Array containing numbers whose mean is desired. If `a` is not an + array, a conversion is attempted. + axis : {int, tuple of int, None}, optional + Axis or axes along which the means are computed. The default is to compute + the mean of the flattened array. + dtype : data-type, optional + Type to use in computing the mean. For integer inputs, the default + is `float64`; for inexact inputs, it is the same as the input + dtype. + out : ndarray, optional + Alternate output array in which to place the result. The default + is ``None``; if provided, it must have the same shape as the + expected output, but the type will be cast if necessary. See + :ref:`ufuncs-output-type` for more details. + keepdims : bool, optional + If this is set to True, the axes which are reduced are left + in the result as dimensions with size one. With this option, + the result will broadcast correctly against the original `a`. + + If the value is anything but the default, then + `keepdims` will be passed through to the `mean` or `sum` methods + of sub-classes of `ndarray`. If the sub-classes methods + does not implement `keepdims` any exceptions will be raised. + + Returns + ------- + m : ndarray, see dtype parameter above + If `out=None`, returns a new array containing the mean values, + otherwise a reference to the output array is returned. Nan is + returned for slices that contain only NaNs. + + See Also + -------- + average : Weighted average + mean : Arithmetic mean taken while not ignoring NaNs + var, nanvar + + Notes + ----- + The arithmetic mean is the sum of the non-NaN elements along the axis + divided by the number of non-NaN elements. + + Note that for floating-point input, the mean is computed using the same + precision the input has. Depending on the input data, this can cause + the results to be inaccurate, especially for `float32`. Specifying a + higher-precision accumulator using the `dtype` keyword can alleviate + this issue. + + Examples + -------- + >>> a = np.array([[1, np.nan], [3, 4]]) + >>> np.nanmean(a) + 2.6666666666666665 + >>> np.nanmean(a, axis=0) + array([2., 4.]) + >>> np.nanmean(a, axis=1) + array([1., 3.5]) # may vary + + """ + arr, mask = _replace_nan(a, 0) + if mask is None: + return np.mean(arr, axis=axis, dtype=dtype, out=out, keepdims=keepdims) + + if dtype is not None: + dtype = np.dtype(dtype) + if dtype is not None and not issubclass(dtype.type, np.inexact): + raise TypeError("If a is inexact, then dtype must be inexact") + if out is not None and not issubclass(out.dtype.type, np.inexact): + raise TypeError("If a is inexact, then out must be inexact") + + cnt = np.sum(~mask, axis=axis, dtype=np.intp, keepdims=keepdims) + tot = np.sum(arr, axis=axis, dtype=dtype, out=out, keepdims=keepdims) + avg = _divide_by_count(tot, cnt, out=out) + + isbad = (cnt == 0) + if isbad.any(): + warnings.warn("Mean of empty slice", RuntimeWarning, stacklevel=3) + # NaN is the only possible bad value, so no further + # action is needed to handle bad results. + return avg + + +def _nanmedian1d(arr1d, overwrite_input=False): + """ + Private function for rank 1 arrays. Compute the median ignoring NaNs. + See nanmedian for parameter usage + """ + arr1d, overwrite_input = _remove_nan_1d(arr1d, + overwrite_input=overwrite_input) + if arr1d.size == 0: + return np.nan + + return np.median(arr1d, overwrite_input=overwrite_input) + + +def _nanmedian(a, axis=None, out=None, overwrite_input=False): + """ + Private function that doesn't support extended axis or keepdims. + These methods are extended to this function using _ureduce + See nanmedian for parameter usage + + """ + if axis is None or a.ndim == 1: + part = a.ravel() + if out is None: + return _nanmedian1d(part, overwrite_input) + else: + out[...] = _nanmedian1d(part, overwrite_input) + return out + else: + # for small medians use sort + indexing which is still faster than + # apply_along_axis + # benchmarked with shuffled (50, 50, x) containing a few NaN + if a.shape[axis] < 600: + return _nanmedian_small(a, axis, out, overwrite_input) + result = np.apply_along_axis(_nanmedian1d, axis, a, overwrite_input) + if out is not None: + out[...] = result + return result + + +def _nanmedian_small(a, axis=None, out=None, overwrite_input=False): + """ + sort + indexing median, faster for small medians along multiple + dimensions due to the high overhead of apply_along_axis + + see nanmedian for parameter usage + """ + a = np.ma.masked_array(a, np.isnan(a)) + m = np.ma.median(a, axis=axis, overwrite_input=overwrite_input) + for i in range(np.count_nonzero(m.mask.ravel())): + warnings.warn("All-NaN slice encountered", RuntimeWarning, + stacklevel=4) + if out is not None: + out[...] = m.filled(np.nan) + return out + return m.filled(np.nan) + + +def _nanmedian_dispatcher( + a, axis=None, out=None, overwrite_input=None, keepdims=None): + return (a, out) + + +@array_function_dispatch(_nanmedian_dispatcher) +def nanmedian(a, axis=None, out=None, overwrite_input=False, keepdims=np._NoValue): + """ + Compute the median along the specified axis, while ignoring NaNs. + + Returns the median of the array elements. + + .. versionadded:: 1.9.0 + + Parameters + ---------- + a : array_like + Input array or object that can be converted to an array. + axis : {int, sequence of int, None}, optional + Axis or axes along which the medians are computed. The default + is to compute the median along a flattened version of the array. + A sequence of axes is supported since version 1.9.0. + out : ndarray, optional + Alternative output array in which to place the result. It must + have the same shape and buffer length as the expected output, + but the type (of the output) will be cast if necessary. + overwrite_input : bool, optional + If True, then allow use of memory of input array `a` for + calculations. The input array will be modified by the call to + `median`. This will save memory when you do not need to preserve + the contents of the input array. Treat the input as undefined, + but it will probably be fully or partially sorted. Default is + False. If `overwrite_input` is ``True`` and `a` is not already an + `ndarray`, an error will be raised. + keepdims : bool, optional + If this is set to True, the axes which are reduced are left + in the result as dimensions with size one. With this option, + the result will broadcast correctly against the original `a`. + + If this is anything but the default value it will be passed + through (in the special case of an empty array) to the + `mean` function of the underlying array. If the array is + a sub-class and `mean` does not have the kwarg `keepdims` this + will raise a RuntimeError. + + Returns + ------- + median : ndarray + A new array holding the result. If the input contains integers + or floats smaller than ``float64``, then the output data-type is + ``np.float64``. Otherwise, the data-type of the output is the + same as that of the input. If `out` is specified, that array is + returned instead. + + See Also + -------- + mean, median, percentile + + Notes + ----- + Given a vector ``V`` of length ``N``, the median of ``V`` is the + middle value of a sorted copy of ``V``, ``V_sorted`` - i.e., + ``V_sorted[(N-1)/2]``, when ``N`` is odd and the average of the two + middle values of ``V_sorted`` when ``N`` is even. + + Examples + -------- + >>> a = np.array([[10.0, 7, 4], [3, 2, 1]]) + >>> a[0, 1] = np.nan + >>> a + array([[10., nan, 4.], + [ 3., 2., 1.]]) + >>> np.median(a) + nan + >>> np.nanmedian(a) + 3.0 + >>> np.nanmedian(a, axis=0) + array([6.5, 2. , 2.5]) + >>> np.median(a, axis=1) + array([nan, 2.]) + >>> b = a.copy() + >>> np.nanmedian(b, axis=1, overwrite_input=True) + array([7., 2.]) + >>> assert not np.all(a==b) + >>> b = a.copy() + >>> np.nanmedian(b, axis=None, overwrite_input=True) + 3.0 + >>> assert not np.all(a==b) + + """ + a = np.asanyarray(a) + # apply_along_axis in _nanmedian doesn't handle empty arrays well, + # so deal them upfront + if a.size == 0: + return np.nanmean(a, axis, out=out, keepdims=keepdims) + + r, k = function_base._ureduce(a, func=_nanmedian, axis=axis, out=out, + overwrite_input=overwrite_input) + if keepdims and keepdims is not np._NoValue: + return r.reshape(k) + else: + return r + + +def _nanpercentile_dispatcher(a, q, axis=None, out=None, overwrite_input=None, + interpolation=None, keepdims=None): + return (a, q, out) + + +@array_function_dispatch(_nanpercentile_dispatcher) +def nanpercentile(a, q, axis=None, out=None, overwrite_input=False, + interpolation='linear', keepdims=np._NoValue): + """ + Compute the qth percentile of the data along the specified axis, + while ignoring nan values. + + Returns the qth percentile(s) of the array elements. + + .. versionadded:: 1.9.0 + + Parameters + ---------- + a : array_like + Input array or object that can be converted to an array, containing + nan values to be ignored. + q : array_like of float + Percentile or sequence of percentiles to compute, which must be between + 0 and 100 inclusive. + axis : {int, tuple of int, None}, optional + Axis or axes along which the percentiles are computed. The + default is to compute the percentile(s) along a flattened + version of the array. + out : ndarray, optional + Alternative output array in which to place the result. It must + have the same shape and buffer length as the expected output, + but the type (of the output) will be cast if necessary. + overwrite_input : bool, optional + If True, then allow the input array `a` to be modified by intermediate + calculations, to save memory. In this case, the contents of the input + `a` after this function completes is undefined. + interpolation : {'linear', 'lower', 'higher', 'midpoint', 'nearest'} + This optional parameter specifies the interpolation method to + use when the desired percentile lies between two data points + ``i < j``: + + * 'linear': ``i + (j - i) * fraction``, where ``fraction`` + is the fractional part of the index surrounded by ``i`` + and ``j``. + * 'lower': ``i``. + * 'higher': ``j``. + * 'nearest': ``i`` or ``j``, whichever is nearest. + * 'midpoint': ``(i + j) / 2``. + keepdims : bool, optional + If this is set to True, the axes which are reduced are left in + the result as dimensions with size one. With this option, the + result will broadcast correctly against the original array `a`. + + If this is anything but the default value it will be passed + through (in the special case of an empty array) to the + `mean` function of the underlying array. If the array is + a sub-class and `mean` does not have the kwarg `keepdims` this + will raise a RuntimeError. + + Returns + ------- + percentile : scalar or ndarray + If `q` is a single percentile and `axis=None`, then the result + is a scalar. If multiple percentiles are given, first axis of + the result corresponds to the percentiles. The other axes are + the axes that remain after the reduction of `a`. If the input + contains integers or floats smaller than ``float64``, the output + data-type is ``float64``. Otherwise, the output data-type is the + same as that of the input. If `out` is specified, that array is + returned instead. + + See Also + -------- + nanmean + nanmedian : equivalent to ``nanpercentile(..., 50)`` + percentile, median, mean + nanquantile : equivalent to nanpercentile, but with q in the range [0, 1]. + + Notes + ----- + Given a vector ``V`` of length ``N``, the ``q``-th percentile of + ``V`` is the value ``q/100`` of the way from the minimum to the + maximum in a sorted copy of ``V``. The values and distances of + the two nearest neighbors as well as the `interpolation` parameter + will determine the percentile if the normalized ranking does not + match the location of ``q`` exactly. This function is the same as + the median if ``q=50``, the same as the minimum if ``q=0`` and the + same as the maximum if ``q=100``. + + Examples + -------- + >>> a = np.array([[10., 7., 4.], [3., 2., 1.]]) + >>> a[0][1] = np.nan + >>> a + array([[10., nan, 4.], + [ 3., 2., 1.]]) + >>> np.percentile(a, 50) + nan + >>> np.nanpercentile(a, 50) + 3.0 + >>> np.nanpercentile(a, 50, axis=0) + array([6.5, 2. , 2.5]) + >>> np.nanpercentile(a, 50, axis=1, keepdims=True) + array([[7.], + [2.]]) + >>> m = np.nanpercentile(a, 50, axis=0) + >>> out = np.zeros_like(m) + >>> np.nanpercentile(a, 50, axis=0, out=out) + array([6.5, 2. , 2.5]) + >>> m + array([6.5, 2. , 2.5]) + + >>> b = a.copy() + >>> np.nanpercentile(b, 50, axis=1, overwrite_input=True) + array([7., 2.]) + >>> assert not np.all(a==b) + + """ + a = np.asanyarray(a) + q = np.true_divide(q, 100.0) # handles the asarray for us too + if not function_base._quantile_is_valid(q): + raise ValueError("Percentiles must be in the range [0, 100]") + return _nanquantile_unchecked( + a, q, axis, out, overwrite_input, interpolation, keepdims) + + +def _nanquantile_dispatcher(a, q, axis=None, out=None, overwrite_input=None, + interpolation=None, keepdims=None): + return (a, q, out) + + +@array_function_dispatch(_nanquantile_dispatcher) +def nanquantile(a, q, axis=None, out=None, overwrite_input=False, + interpolation='linear', keepdims=np._NoValue): + """ + Compute the qth quantile of the data along the specified axis, + while ignoring nan values. + Returns the qth quantile(s) of the array elements. + + .. versionadded:: 1.15.0 + + Parameters + ---------- + a : array_like + Input array or object that can be converted to an array, containing + nan values to be ignored + q : array_like of float + Quantile or sequence of quantiles to compute, which must be between + 0 and 1 inclusive. + axis : {int, tuple of int, None}, optional + Axis or axes along which the quantiles are computed. The + default is to compute the quantile(s) along a flattened + version of the array. + out : ndarray, optional + Alternative output array in which to place the result. It must + have the same shape and buffer length as the expected output, + but the type (of the output) will be cast if necessary. + overwrite_input : bool, optional + If True, then allow the input array `a` to be modified by intermediate + calculations, to save memory. In this case, the contents of the input + `a` after this function completes is undefined. + interpolation : {'linear', 'lower', 'higher', 'midpoint', 'nearest'} + This optional parameter specifies the interpolation method to + use when the desired quantile lies between two data points + ``i < j``: + + * linear: ``i + (j - i) * fraction``, where ``fraction`` + is the fractional part of the index surrounded by ``i`` + and ``j``. + * lower: ``i``. + * higher: ``j``. + * nearest: ``i`` or ``j``, whichever is nearest. + * midpoint: ``(i + j) / 2``. + + keepdims : bool, optional + If this is set to True, the axes which are reduced are left in + the result as dimensions with size one. With this option, the + result will broadcast correctly against the original array `a`. + + If this is anything but the default value it will be passed + through (in the special case of an empty array) to the + `mean` function of the underlying array. If the array is + a sub-class and `mean` does not have the kwarg `keepdims` this + will raise a RuntimeError. + + Returns + ------- + quantile : scalar or ndarray + If `q` is a single percentile and `axis=None`, then the result + is a scalar. If multiple quantiles are given, first axis of + the result corresponds to the quantiles. The other axes are + the axes that remain after the reduction of `a`. If the input + contains integers or floats smaller than ``float64``, the output + data-type is ``float64``. Otherwise, the output data-type is the + same as that of the input. If `out` is specified, that array is + returned instead. + + See Also + -------- + quantile + nanmean, nanmedian + nanmedian : equivalent to ``nanquantile(..., 0.5)`` + nanpercentile : same as nanquantile, but with q in the range [0, 100]. + + Examples + -------- + >>> a = np.array([[10., 7., 4.], [3., 2., 1.]]) + >>> a[0][1] = np.nan + >>> a + array([[10., nan, 4.], + [ 3., 2., 1.]]) + >>> np.quantile(a, 0.5) + nan + >>> np.nanquantile(a, 0.5) + 3.0 + >>> np.nanquantile(a, 0.5, axis=0) + array([6.5, 2. , 2.5]) + >>> np.nanquantile(a, 0.5, axis=1, keepdims=True) + array([[7.], + [2.]]) + >>> m = np.nanquantile(a, 0.5, axis=0) + >>> out = np.zeros_like(m) + >>> np.nanquantile(a, 0.5, axis=0, out=out) + array([6.5, 2. , 2.5]) + >>> m + array([6.5, 2. , 2.5]) + >>> b = a.copy() + >>> np.nanquantile(b, 0.5, axis=1, overwrite_input=True) + array([7., 2.]) + >>> assert not np.all(a==b) + """ + a = np.asanyarray(a) + q = np.asanyarray(q) + if not function_base._quantile_is_valid(q): + raise ValueError("Quantiles must be in the range [0, 1]") + return _nanquantile_unchecked( + a, q, axis, out, overwrite_input, interpolation, keepdims) + + +def _nanquantile_unchecked(a, q, axis=None, out=None, overwrite_input=False, + interpolation='linear', keepdims=np._NoValue): + """Assumes that q is in [0, 1], and is an ndarray""" + # apply_along_axis in _nanpercentile doesn't handle empty arrays well, + # so deal them upfront + if a.size == 0: + return np.nanmean(a, axis, out=out, keepdims=keepdims) + + r, k = function_base._ureduce( + a, func=_nanquantile_ureduce_func, q=q, axis=axis, out=out, + overwrite_input=overwrite_input, interpolation=interpolation + ) + if keepdims and keepdims is not np._NoValue: + return r.reshape(q.shape + k) + else: + return r + + +def _nanquantile_ureduce_func(a, q, axis=None, out=None, overwrite_input=False, + interpolation='linear'): + """ + Private function that doesn't support extended axis or keepdims. + These methods are extended to this function using _ureduce + See nanpercentile for parameter usage + """ + if axis is None or a.ndim == 1: + part = a.ravel() + result = _nanquantile_1d(part, q, overwrite_input, interpolation) + else: + result = np.apply_along_axis(_nanquantile_1d, axis, a, q, + overwrite_input, interpolation) + # apply_along_axis fills in collapsed axis with results. + # Move that axis to the beginning to match percentile's + # convention. + if q.ndim != 0: + result = np.moveaxis(result, axis, 0) + + if out is not None: + out[...] = result + return result + + +def _nanquantile_1d(arr1d, q, overwrite_input=False, interpolation='linear'): + """ + Private function for rank 1 arrays. Compute quantile ignoring NaNs. + See nanpercentile for parameter usage + """ + arr1d, overwrite_input = _remove_nan_1d(arr1d, + overwrite_input=overwrite_input) + if arr1d.size == 0: + return np.full(q.shape, np.nan)[()] # convert to scalar + + return function_base._quantile_unchecked( + arr1d, q, overwrite_input=overwrite_input, interpolation=interpolation) + + +def _nanvar_dispatcher( + a, axis=None, dtype=None, out=None, ddof=None, keepdims=None): + return (a, out) + + +@array_function_dispatch(_nanvar_dispatcher) +def nanvar(a, axis=None, dtype=None, out=None, ddof=0, keepdims=np._NoValue): + """ + Compute the variance along the specified axis, while ignoring NaNs. + + Returns the variance of the array elements, a measure of the spread of + a distribution. The variance is computed for the flattened array by + default, otherwise over the specified axis. + + For all-NaN slices or slices with zero degrees of freedom, NaN is + returned and a `RuntimeWarning` is raised. + + .. versionadded:: 1.8.0 + + Parameters + ---------- + a : array_like + Array containing numbers whose variance is desired. If `a` is not an + array, a conversion is attempted. + axis : {int, tuple of int, None}, optional + Axis or axes along which the variance is computed. The default is to compute + the variance of the flattened array. + dtype : data-type, optional + Type to use in computing the variance. For arrays of integer type + the default is `float64`; for arrays of float types it is the same as + the array type. + out : ndarray, optional + Alternate output array in which to place the result. It must have + the same shape as the expected output, but the type is cast if + necessary. + ddof : int, optional + "Delta Degrees of Freedom": the divisor used in the calculation is + ``N - ddof``, where ``N`` represents the number of non-NaN + elements. By default `ddof` is zero. + keepdims : bool, optional + If this is set to True, the axes which are reduced are left + in the result as dimensions with size one. With this option, + the result will broadcast correctly against the original `a`. + + + Returns + ------- + variance : ndarray, see dtype parameter above + If `out` is None, return a new array containing the variance, + otherwise return a reference to the output array. If ddof is >= the + number of non-NaN elements in a slice or the slice contains only + NaNs, then the result for that slice is NaN. + + See Also + -------- + std : Standard deviation + mean : Average + var : Variance while not ignoring NaNs + nanstd, nanmean + :ref:`ufuncs-output-type` + + Notes + ----- + The variance is the average of the squared deviations from the mean, + i.e., ``var = mean(abs(x - x.mean())**2)``. + + The mean is normally calculated as ``x.sum() / N``, where ``N = len(x)``. + If, however, `ddof` is specified, the divisor ``N - ddof`` is used + instead. In standard statistical practice, ``ddof=1`` provides an + unbiased estimator of the variance of a hypothetical infinite + population. ``ddof=0`` provides a maximum likelihood estimate of the + variance for normally distributed variables. + + Note that for complex numbers, the absolute value is taken before + squaring, so that the result is always real and nonnegative. + + For floating-point input, the variance is computed using the same + precision the input has. Depending on the input data, this can cause + the results to be inaccurate, especially for `float32` (see example + below). Specifying a higher-accuracy accumulator using the ``dtype`` + keyword can alleviate this issue. + + For this function to work on sub-classes of ndarray, they must define + `sum` with the kwarg `keepdims` + + Examples + -------- + >>> a = np.array([[1, np.nan], [3, 4]]) + >>> np.nanvar(a) + 1.5555555555555554 + >>> np.nanvar(a, axis=0) + array([1., 0.]) + >>> np.nanvar(a, axis=1) + array([0., 0.25]) # may vary + + """ + arr, mask = _replace_nan(a, 0) + if mask is None: + return np.var(arr, axis=axis, dtype=dtype, out=out, ddof=ddof, + keepdims=keepdims) + + if dtype is not None: + dtype = np.dtype(dtype) + if dtype is not None and not issubclass(dtype.type, np.inexact): + raise TypeError("If a is inexact, then dtype must be inexact") + if out is not None and not issubclass(out.dtype.type, np.inexact): + raise TypeError("If a is inexact, then out must be inexact") + + # Compute mean + if type(arr) is np.matrix: + _keepdims = np._NoValue + else: + _keepdims = True + # we need to special case matrix for reverse compatibility + # in order for this to work, these sums need to be called with + # keepdims=True, however matrix now raises an error in this case, but + # the reason that it drops the keepdims kwarg is to force keepdims=True + # so this used to work by serendipity. + cnt = np.sum(~mask, axis=axis, dtype=np.intp, keepdims=_keepdims) + avg = np.sum(arr, axis=axis, dtype=dtype, keepdims=_keepdims) + avg = _divide_by_count(avg, cnt) + + # Compute squared deviation from mean. + np.subtract(arr, avg, out=arr, casting='unsafe') + arr = _copyto(arr, 0, mask) + if issubclass(arr.dtype.type, np.complexfloating): + sqr = np.multiply(arr, arr.conj(), out=arr).real + else: + sqr = np.multiply(arr, arr, out=arr) + + # Compute variance. + var = np.sum(sqr, axis=axis, dtype=dtype, out=out, keepdims=keepdims) + if var.ndim < cnt.ndim: + # Subclasses of ndarray may ignore keepdims, so check here. + cnt = cnt.squeeze(axis) + dof = cnt - ddof + var = _divide_by_count(var, dof) + + isbad = (dof <= 0) + if np.any(isbad): + warnings.warn("Degrees of freedom <= 0 for slice.", RuntimeWarning, + stacklevel=3) + # NaN, inf, or negative numbers are all possible bad + # values, so explicitly replace them with NaN. + var = _copyto(var, np.nan, isbad) + return var + + +def _nanstd_dispatcher( + a, axis=None, dtype=None, out=None, ddof=None, keepdims=None): + return (a, out) + + +@array_function_dispatch(_nanstd_dispatcher) +def nanstd(a, axis=None, dtype=None, out=None, ddof=0, keepdims=np._NoValue): + """ + Compute the standard deviation along the specified axis, while + ignoring NaNs. + + Returns the standard deviation, a measure of the spread of a + distribution, of the non-NaN array elements. The standard deviation is + computed for the flattened array by default, otherwise over the + specified axis. + + For all-NaN slices or slices with zero degrees of freedom, NaN is + returned and a `RuntimeWarning` is raised. + + .. versionadded:: 1.8.0 + + Parameters + ---------- + a : array_like + Calculate the standard deviation of the non-NaN values. + axis : {int, tuple of int, None}, optional + Axis or axes along which the standard deviation is computed. The default is + to compute the standard deviation of the flattened array. + dtype : dtype, optional + Type to use in computing the standard deviation. For arrays of + integer type the default is float64, for arrays of float types it + is the same as the array type. + out : ndarray, optional + Alternative output array in which to place the result. It must have + the same shape as the expected output but the type (of the + calculated values) will be cast if necessary. + ddof : int, optional + Means Delta Degrees of Freedom. The divisor used in calculations + is ``N - ddof``, where ``N`` represents the number of non-NaN + elements. By default `ddof` is zero. + + keepdims : bool, optional + If this is set to True, the axes which are reduced are left + in the result as dimensions with size one. With this option, + the result will broadcast correctly against the original `a`. + + If this value is anything but the default it is passed through + as-is to the relevant functions of the sub-classes. If these + functions do not have a `keepdims` kwarg, a RuntimeError will + be raised. + + Returns + ------- + standard_deviation : ndarray, see dtype parameter above. + If `out` is None, return a new array containing the standard + deviation, otherwise return a reference to the output array. If + ddof is >= the number of non-NaN elements in a slice or the slice + contains only NaNs, then the result for that slice is NaN. + + See Also + -------- + var, mean, std + nanvar, nanmean + :ref:`ufuncs-output-type` + + Notes + ----- + The standard deviation is the square root of the average of the squared + deviations from the mean: ``std = sqrt(mean(abs(x - x.mean())**2))``. + + The average squared deviation is normally calculated as + ``x.sum() / N``, where ``N = len(x)``. If, however, `ddof` is + specified, the divisor ``N - ddof`` is used instead. In standard + statistical practice, ``ddof=1`` provides an unbiased estimator of the + variance of the infinite population. ``ddof=0`` provides a maximum + likelihood estimate of the variance for normally distributed variables. + The standard deviation computed in this function is the square root of + the estimated variance, so even with ``ddof=1``, it will not be an + unbiased estimate of the standard deviation per se. + + Note that, for complex numbers, `std` takes the absolute value before + squaring, so that the result is always real and nonnegative. + + For floating-point input, the *std* is computed using the same + precision the input has. Depending on the input data, this can cause + the results to be inaccurate, especially for float32 (see example + below). Specifying a higher-accuracy accumulator using the `dtype` + keyword can alleviate this issue. + + Examples + -------- + >>> a = np.array([[1, np.nan], [3, 4]]) + >>> np.nanstd(a) + 1.247219128924647 + >>> np.nanstd(a, axis=0) + array([1., 0.]) + >>> np.nanstd(a, axis=1) + array([0., 0.5]) # may vary + + """ + var = nanvar(a, axis=axis, dtype=dtype, out=out, ddof=ddof, + keepdims=keepdims) + if isinstance(var, np.ndarray): + std = np.sqrt(var, out=var) + else: + std = var.dtype.type(np.sqrt(var)) + return std diff --git a/venv/Lib/site-packages/numpy/lib/npyio.py b/venv/Lib/site-packages/numpy/lib/npyio.py new file mode 100644 index 0000000..3b2de3e --- /dev/null +++ b/venv/Lib/site-packages/numpy/lib/npyio.py @@ -0,0 +1,2413 @@ +import sys +import os +import re +import functools +import itertools +import warnings +import weakref +import contextlib +from operator import itemgetter, index as opindex +from collections.abc import Mapping + +import numpy as np +from . import format +from ._datasource import DataSource +from numpy.core import overrides +from numpy.core.multiarray import packbits, unpackbits +from numpy.core.overrides import set_array_function_like_doc, set_module +from numpy.core._internal import recursive +from ._iotools import ( + LineSplitter, NameValidator, StringConverter, ConverterError, + ConverterLockError, ConversionWarning, _is_string_like, + has_nested_fields, flatten_dtype, easy_dtype, _decode_line + ) + +from numpy.compat import ( + asbytes, asstr, asunicode, os_fspath, os_PathLike, + pickle, contextlib_nullcontext + ) + + +@set_module('numpy') +def loads(*args, **kwargs): + # NumPy 1.15.0, 2017-12-10 + warnings.warn( + "np.loads is deprecated, use pickle.loads instead", + DeprecationWarning, stacklevel=2) + return pickle.loads(*args, **kwargs) + + +__all__ = [ + 'savetxt', 'loadtxt', 'genfromtxt', 'ndfromtxt', 'mafromtxt', + 'recfromtxt', 'recfromcsv', 'load', 'loads', 'save', 'savez', + 'savez_compressed', 'packbits', 'unpackbits', 'fromregex', 'DataSource' + ] + + +array_function_dispatch = functools.partial( + overrides.array_function_dispatch, module='numpy') + + +class BagObj: + """ + BagObj(obj) + + Convert attribute look-ups to getitems on the object passed in. + + Parameters + ---------- + obj : class instance + Object on which attribute look-up is performed. + + Examples + -------- + >>> from numpy.lib.npyio import BagObj as BO + >>> class BagDemo: + ... def __getitem__(self, key): # An instance of BagObj(BagDemo) + ... # will call this method when any + ... # attribute look-up is required + ... result = "Doesn't matter what you want, " + ... return result + "you're gonna get this" + ... + >>> demo_obj = BagDemo() + >>> bagobj = BO(demo_obj) + >>> bagobj.hello_there + "Doesn't matter what you want, you're gonna get this" + >>> bagobj.I_can_be_anything + "Doesn't matter what you want, you're gonna get this" + + """ + + def __init__(self, obj): + # Use weakref to make NpzFile objects collectable by refcount + self._obj = weakref.proxy(obj) + + def __getattribute__(self, key): + try: + return object.__getattribute__(self, '_obj')[key] + except KeyError: + raise AttributeError(key) from None + + def __dir__(self): + """ + Enables dir(bagobj) to list the files in an NpzFile. + + This also enables tab-completion in an interpreter or IPython. + """ + return list(object.__getattribute__(self, '_obj').keys()) + + +def zipfile_factory(file, *args, **kwargs): + """ + Create a ZipFile. + + Allows for Zip64, and the `file` argument can accept file, str, or + pathlib.Path objects. `args` and `kwargs` are passed to the zipfile.ZipFile + constructor. + """ + if not hasattr(file, 'read'): + file = os_fspath(file) + import zipfile + kwargs['allowZip64'] = True + return zipfile.ZipFile(file, *args, **kwargs) + + +class NpzFile(Mapping): + """ + NpzFile(fid) + + A dictionary-like object with lazy-loading of files in the zipped + archive provided on construction. + + `NpzFile` is used to load files in the NumPy ``.npz`` data archive + format. It assumes that files in the archive have a ``.npy`` extension, + other files are ignored. + + The arrays and file strings are lazily loaded on either + getitem access using ``obj['key']`` or attribute lookup using + ``obj.f.key``. A list of all files (without ``.npy`` extensions) can + be obtained with ``obj.files`` and the ZipFile object itself using + ``obj.zip``. + + Attributes + ---------- + files : list of str + List of all files in the archive with a ``.npy`` extension. + zip : ZipFile instance + The ZipFile object initialized with the zipped archive. + f : BagObj instance + An object on which attribute can be performed as an alternative + to getitem access on the `NpzFile` instance itself. + allow_pickle : bool, optional + Allow loading pickled data. Default: False + + .. versionchanged:: 1.16.3 + Made default False in response to CVE-2019-6446. + + pickle_kwargs : dict, optional + Additional keyword arguments to pass on to pickle.load. + These are only useful when loading object arrays saved on + Python 2 when using Python 3. + + Parameters + ---------- + fid : file or str + The zipped archive to open. This is either a file-like object + or a string containing the path to the archive. + own_fid : bool, optional + Whether NpzFile should close the file handle. + Requires that `fid` is a file-like object. + + Examples + -------- + >>> from tempfile import TemporaryFile + >>> outfile = TemporaryFile() + >>> x = np.arange(10) + >>> y = np.sin(x) + >>> np.savez(outfile, x=x, y=y) + >>> _ = outfile.seek(0) + + >>> npz = np.load(outfile) + >>> isinstance(npz, np.lib.io.NpzFile) + True + >>> sorted(npz.files) + ['x', 'y'] + >>> npz['x'] # getitem access + array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) + >>> npz.f.x # attribute lookup + array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) + + """ + # Make __exit__ safe if zipfile_factory raises an exception + zip = None + fid = None + + def __init__(self, fid, own_fid=False, allow_pickle=False, + pickle_kwargs=None): + # Import is postponed to here since zipfile depends on gzip, an + # optional component of the so-called standard library. + _zip = zipfile_factory(fid) + self._files = _zip.namelist() + self.files = [] + self.allow_pickle = allow_pickle + self.pickle_kwargs = pickle_kwargs + for x in self._files: + if x.endswith('.npy'): + self.files.append(x[:-4]) + else: + self.files.append(x) + self.zip = _zip + self.f = BagObj(self) + if own_fid: + self.fid = fid + + def __enter__(self): + return self + + def __exit__(self, exc_type, exc_value, traceback): + self.close() + + def close(self): + """ + Close the file. + + """ + if self.zip is not None: + self.zip.close() + self.zip = None + if self.fid is not None: + self.fid.close() + self.fid = None + self.f = None # break reference cycle + + def __del__(self): + self.close() + + # Implement the Mapping ABC + def __iter__(self): + return iter(self.files) + + def __len__(self): + return len(self.files) + + def __getitem__(self, key): + # FIXME: This seems like it will copy strings around + # more than is strictly necessary. The zipfile + # will read the string and then + # the format.read_array will copy the string + # to another place in memory. + # It would be better if the zipfile could read + # (or at least uncompress) the data + # directly into the array memory. + member = False + if key in self._files: + member = True + elif key in self.files: + member = True + key += '.npy' + if member: + bytes = self.zip.open(key) + magic = bytes.read(len(format.MAGIC_PREFIX)) + bytes.close() + if magic == format.MAGIC_PREFIX: + bytes = self.zip.open(key) + return format.read_array(bytes, + allow_pickle=self.allow_pickle, + pickle_kwargs=self.pickle_kwargs) + else: + return self.zip.read(key) + else: + raise KeyError("%s is not a file in the archive" % key) + + + # deprecate the python 2 dict apis that we supported by accident in + # python 3. We forgot to implement itervalues() at all in earlier + # versions of numpy, so no need to deprecated it here. + + def iteritems(self): + # Numpy 1.15, 2018-02-20 + warnings.warn( + "NpzFile.iteritems is deprecated in python 3, to match the " + "removal of dict.itertems. Use .items() instead.", + DeprecationWarning, stacklevel=2) + return self.items() + + def iterkeys(self): + # Numpy 1.15, 2018-02-20 + warnings.warn( + "NpzFile.iterkeys is deprecated in python 3, to match the " + "removal of dict.iterkeys. Use .keys() instead.", + DeprecationWarning, stacklevel=2) + return self.keys() + + +@set_module('numpy') +def load(file, mmap_mode=None, allow_pickle=False, fix_imports=True, + encoding='ASCII'): + """ + Load arrays or pickled objects from ``.npy``, ``.npz`` or pickled files. + + .. warning:: Loading files that contain object arrays uses the ``pickle`` + module, which is not secure against erroneous or maliciously + constructed data. Consider passing ``allow_pickle=False`` to + load data that is known not to contain object arrays for the + safer handling of untrusted sources. + + Parameters + ---------- + file : file-like object, string, or pathlib.Path + The file to read. File-like objects must support the + ``seek()`` and ``read()`` methods. Pickled files require that the + file-like object support the ``readline()`` method as well. + mmap_mode : {None, 'r+', 'r', 'w+', 'c'}, optional + If not None, then memory-map the file, using the given mode (see + `numpy.memmap` for a detailed description of the modes). A + memory-mapped array is kept on disk. However, it can be accessed + and sliced like any ndarray. Memory mapping is especially useful + for accessing small fragments of large files without reading the + entire file into memory. + allow_pickle : bool, optional + Allow loading pickled object arrays stored in npy files. Reasons for + disallowing pickles include security, as loading pickled data can + execute arbitrary code. If pickles are disallowed, loading object + arrays will fail. Default: False + + .. versionchanged:: 1.16.3 + Made default False in response to CVE-2019-6446. + + fix_imports : bool, optional + Only useful when loading Python 2 generated pickled files on Python 3, + which includes npy/npz files containing object arrays. If `fix_imports` + is True, pickle will try to map the old Python 2 names to the new names + used in Python 3. + encoding : str, optional + What encoding to use when reading Python 2 strings. Only useful when + loading Python 2 generated pickled files in Python 3, which includes + npy/npz files containing object arrays. Values other than 'latin1', + 'ASCII', and 'bytes' are not allowed, as they can corrupt numerical + data. Default: 'ASCII' + + Returns + ------- + result : array, tuple, dict, etc. + Data stored in the file. For ``.npz`` files, the returned instance + of NpzFile class must be closed to avoid leaking file descriptors. + + Raises + ------ + IOError + If the input file does not exist or cannot be read. + ValueError + The file contains an object array, but allow_pickle=False given. + + See Also + -------- + save, savez, savez_compressed, loadtxt + memmap : Create a memory-map to an array stored in a file on disk. + lib.format.open_memmap : Create or load a memory-mapped ``.npy`` file. + + Notes + ----- + - If the file contains pickle data, then whatever object is stored + in the pickle is returned. + - If the file is a ``.npy`` file, then a single array is returned. + - If the file is a ``.npz`` file, then a dictionary-like object is + returned, containing ``{filename: array}`` key-value pairs, one for + each file in the archive. + - If the file is a ``.npz`` file, the returned value supports the + context manager protocol in a similar fashion to the open function:: + + with load('foo.npz') as data: + a = data['a'] + + The underlying file descriptor is closed when exiting the 'with' + block. + + Examples + -------- + Store data to disk, and load it again: + + >>> np.save('/tmp/123', np.array([[1, 2, 3], [4, 5, 6]])) + >>> np.load('/tmp/123.npy') + array([[1, 2, 3], + [4, 5, 6]]) + + Store compressed data to disk, and load it again: + + >>> a=np.array([[1, 2, 3], [4, 5, 6]]) + >>> b=np.array([1, 2]) + >>> np.savez('/tmp/123.npz', a=a, b=b) + >>> data = np.load('/tmp/123.npz') + >>> data['a'] + array([[1, 2, 3], + [4, 5, 6]]) + >>> data['b'] + array([1, 2]) + >>> data.close() + + Mem-map the stored array, and then access the second row + directly from disk: + + >>> X = np.load('/tmp/123.npy', mmap_mode='r') + >>> X[1, :] + memmap([4, 5, 6]) + + """ + if encoding not in ('ASCII', 'latin1', 'bytes'): + # The 'encoding' value for pickle also affects what encoding + # the serialized binary data of NumPy arrays is loaded + # in. Pickle does not pass on the encoding information to + # NumPy. The unpickling code in numpy.core.multiarray is + # written to assume that unicode data appearing where binary + # should be is in 'latin1'. 'bytes' is also safe, as is 'ASCII'. + # + # Other encoding values can corrupt binary data, and we + # purposefully disallow them. For the same reason, the errors= + # argument is not exposed, as values other than 'strict' + # result can similarly silently corrupt numerical data. + raise ValueError("encoding must be 'ASCII', 'latin1', or 'bytes'") + + pickle_kwargs = dict(encoding=encoding, fix_imports=fix_imports) + + with contextlib.ExitStack() as stack: + if hasattr(file, 'read'): + fid = file + own_fid = False + else: + fid = stack.enter_context(open(os_fspath(file), "rb")) + own_fid = True + + # Code to distinguish from NumPy binary files and pickles. + _ZIP_PREFIX = b'PK\x03\x04' + _ZIP_SUFFIX = b'PK\x05\x06' # empty zip files start with this + N = len(format.MAGIC_PREFIX) + magic = fid.read(N) + # If the file size is less than N, we need to make sure not + # to seek past the beginning of the file + fid.seek(-min(N, len(magic)), 1) # back-up + if magic.startswith(_ZIP_PREFIX) or magic.startswith(_ZIP_SUFFIX): + # zip-file (assume .npz) + # Potentially transfer file ownership to NpzFile + stack.pop_all() + ret = NpzFile(fid, own_fid=own_fid, allow_pickle=allow_pickle, + pickle_kwargs=pickle_kwargs) + return ret + elif magic == format.MAGIC_PREFIX: + # .npy file + if mmap_mode: + return format.open_memmap(file, mode=mmap_mode) + else: + return format.read_array(fid, allow_pickle=allow_pickle, + pickle_kwargs=pickle_kwargs) + else: + # Try a pickle + if not allow_pickle: + raise ValueError("Cannot load file containing pickled data " + "when allow_pickle=False") + try: + return pickle.load(fid, **pickle_kwargs) + except Exception as e: + raise IOError( + "Failed to interpret file %s as a pickle" % repr(file)) from e + + +def _save_dispatcher(file, arr, allow_pickle=None, fix_imports=None): + return (arr,) + + +@array_function_dispatch(_save_dispatcher) +def save(file, arr, allow_pickle=True, fix_imports=True): + """ + Save an array to a binary file in NumPy ``.npy`` format. + + Parameters + ---------- + file : file, str, or pathlib.Path + File or filename to which the data is saved. If file is a file-object, + then the filename is unchanged. If file is a string or Path, a ``.npy`` + extension will be appended to the filename if it does not already + have one. + arr : array_like + Array data to be saved. + allow_pickle : bool, optional + Allow saving object arrays using Python pickles. Reasons for disallowing + pickles include security (loading pickled data can execute arbitrary + code) and portability (pickled objects may not be loadable on different + Python installations, for example if the stored objects require libraries + that are not available, and not all pickled data is compatible between + Python 2 and Python 3). + Default: True + fix_imports : bool, optional + Only useful in forcing objects in object arrays on Python 3 to be + pickled in a Python 2 compatible way. If `fix_imports` is True, pickle + will try to map the new Python 3 names to the old module names used in + Python 2, so that the pickle data stream is readable with Python 2. + + See Also + -------- + savez : Save several arrays into a ``.npz`` archive + savetxt, load + + Notes + ----- + For a description of the ``.npy`` format, see :py:mod:`numpy.lib.format`. + + Any data saved to the file is appended to the end of the file. + + Examples + -------- + >>> from tempfile import TemporaryFile + >>> outfile = TemporaryFile() + + >>> x = np.arange(10) + >>> np.save(outfile, x) + + >>> _ = outfile.seek(0) # Only needed here to simulate closing & reopening file + >>> np.load(outfile) + array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) + + + >>> with open('test.npy', 'wb') as f: + ... np.save(f, np.array([1, 2])) + ... np.save(f, np.array([1, 3])) + >>> with open('test.npy', 'rb') as f: + ... a = np.load(f) + ... b = np.load(f) + >>> print(a, b) + # [1 2] [1 3] + """ + if hasattr(file, 'write'): + file_ctx = contextlib_nullcontext(file) + else: + file = os_fspath(file) + if not file.endswith('.npy'): + file = file + '.npy' + file_ctx = open(file, "wb") + + with file_ctx as fid: + arr = np.asanyarray(arr) + format.write_array(fid, arr, allow_pickle=allow_pickle, + pickle_kwargs=dict(fix_imports=fix_imports)) + + +def _savez_dispatcher(file, *args, **kwds): + yield from args + yield from kwds.values() + + +@array_function_dispatch(_savez_dispatcher) +def savez(file, *args, **kwds): + """Save several arrays into a single file in uncompressed ``.npz`` format. + + If arguments are passed in with no keywords, the corresponding variable + names, in the ``.npz`` file, are 'arr_0', 'arr_1', etc. If keyword + arguments are given, the corresponding variable names, in the ``.npz`` + file will match the keyword names. + + Parameters + ---------- + file : str or file + Either the filename (string) or an open file (file-like object) + where the data will be saved. If file is a string or a Path, the + ``.npz`` extension will be appended to the filename if it is not + already there. + args : Arguments, optional + Arrays to save to the file. Since it is not possible for Python to + know the names of the arrays outside `savez`, the arrays will be saved + with names "arr_0", "arr_1", and so on. These arguments can be any + expression. + kwds : Keyword arguments, optional + Arrays to save to the file. Arrays will be saved in the file with the + keyword names. + + Returns + ------- + None + + See Also + -------- + save : Save a single array to a binary file in NumPy format. + savetxt : Save an array to a file as plain text. + savez_compressed : Save several arrays into a compressed ``.npz`` archive + + Notes + ----- + The ``.npz`` file format is a zipped archive of files named after the + variables they contain. The archive is not compressed and each file + in the archive contains one variable in ``.npy`` format. For a + description of the ``.npy`` format, see :py:mod:`numpy.lib.format`. + + When opening the saved ``.npz`` file with `load` a `NpzFile` object is + returned. This is a dictionary-like object which can be queried for + its list of arrays (with the ``.files`` attribute), and for the arrays + themselves. + + When saving dictionaries, the dictionary keys become filenames + inside the ZIP archive. Therefore, keys should be valid filenames. + E.g., avoid keys that begin with ``/`` or contain ``.``. + + Examples + -------- + >>> from tempfile import TemporaryFile + >>> outfile = TemporaryFile() + >>> x = np.arange(10) + >>> y = np.sin(x) + + Using `savez` with \\*args, the arrays are saved with default names. + + >>> np.savez(outfile, x, y) + >>> _ = outfile.seek(0) # Only needed here to simulate closing & reopening file + >>> npzfile = np.load(outfile) + >>> npzfile.files + ['arr_0', 'arr_1'] + >>> npzfile['arr_0'] + array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) + + Using `savez` with \\**kwds, the arrays are saved with the keyword names. + + >>> outfile = TemporaryFile() + >>> np.savez(outfile, x=x, y=y) + >>> _ = outfile.seek(0) + >>> npzfile = np.load(outfile) + >>> sorted(npzfile.files) + ['x', 'y'] + >>> npzfile['x'] + array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) + """ + _savez(file, args, kwds, False) + + +def _savez_compressed_dispatcher(file, *args, **kwds): + yield from args + yield from kwds.values() + + +@array_function_dispatch(_savez_compressed_dispatcher) +def savez_compressed(file, *args, **kwds): + """ + Save several arrays into a single file in compressed ``.npz`` format. + + If keyword arguments are given, then filenames are taken from the keywords. + If arguments are passed in with no keywords, then stored filenames are + arr_0, arr_1, etc. + + Parameters + ---------- + file : str or file + Either the filename (string) or an open file (file-like object) + where the data will be saved. If file is a string or a Path, the + ``.npz`` extension will be appended to the filename if it is not + already there. + args : Arguments, optional + Arrays to save to the file. Since it is not possible for Python to + know the names of the arrays outside `savez`, the arrays will be saved + with names "arr_0", "arr_1", and so on. These arguments can be any + expression. + kwds : Keyword arguments, optional + Arrays to save to the file. Arrays will be saved in the file with the + keyword names. + + Returns + ------- + None + + See Also + -------- + numpy.save : Save a single array to a binary file in NumPy format. + numpy.savetxt : Save an array to a file as plain text. + numpy.savez : Save several arrays into an uncompressed ``.npz`` file format + numpy.load : Load the files created by savez_compressed. + + Notes + ----- + The ``.npz`` file format is a zipped archive of files named after the + variables they contain. The archive is compressed with + ``zipfile.ZIP_DEFLATED`` and each file in the archive contains one variable + in ``.npy`` format. For a description of the ``.npy`` format, see + :py:mod:`numpy.lib.format`. + + + When opening the saved ``.npz`` file with `load` a `NpzFile` object is + returned. This is a dictionary-like object which can be queried for + its list of arrays (with the ``.files`` attribute), and for the arrays + themselves. + + Examples + -------- + >>> test_array = np.random.rand(3, 2) + >>> test_vector = np.random.rand(4) + >>> np.savez_compressed('/tmp/123', a=test_array, b=test_vector) + >>> loaded = np.load('/tmp/123.npz') + >>> print(np.array_equal(test_array, loaded['a'])) + True + >>> print(np.array_equal(test_vector, loaded['b'])) + True + + """ + _savez(file, args, kwds, True) + + +def _savez(file, args, kwds, compress, allow_pickle=True, pickle_kwargs=None): + # Import is postponed to here since zipfile depends on gzip, an optional + # component of the so-called standard library. + import zipfile + + if not hasattr(file, 'write'): + file = os_fspath(file) + if not file.endswith('.npz'): + file = file + '.npz' + + namedict = kwds + for i, val in enumerate(args): + key = 'arr_%d' % i + if key in namedict.keys(): + raise ValueError( + "Cannot use un-named variables and keyword %s" % key) + namedict[key] = val + + if compress: + compression = zipfile.ZIP_DEFLATED + else: + compression = zipfile.ZIP_STORED + + zipf = zipfile_factory(file, mode="w", compression=compression) + + for key, val in namedict.items(): + fname = key + '.npy' + val = np.asanyarray(val) + # always force zip64, gh-10776 + with zipf.open(fname, 'w', force_zip64=True) as fid: + format.write_array(fid, val, + allow_pickle=allow_pickle, + pickle_kwargs=pickle_kwargs) + + zipf.close() + + +def _getconv(dtype): + """ Find the correct dtype converter. Adapted from matplotlib """ + + def floatconv(x): + x.lower() + if '0x' in x: + return float.fromhex(x) + return float(x) + + typ = dtype.type + if issubclass(typ, np.bool_): + return lambda x: bool(int(x)) + if issubclass(typ, np.uint64): + return np.uint64 + if issubclass(typ, np.int64): + return np.int64 + if issubclass(typ, np.integer): + return lambda x: int(float(x)) + elif issubclass(typ, np.longdouble): + return np.longdouble + elif issubclass(typ, np.floating): + return floatconv + elif issubclass(typ, complex): + return lambda x: complex(asstr(x).replace('+-', '-')) + elif issubclass(typ, np.bytes_): + return asbytes + elif issubclass(typ, np.unicode_): + return asunicode + else: + return asstr + + +# amount of lines loadtxt reads in one chunk, can be overridden for testing +_loadtxt_chunksize = 50000 + + +def _loadtxt_dispatcher(fname, dtype=None, comments=None, delimiter=None, + converters=None, skiprows=None, usecols=None, unpack=None, + ndmin=None, encoding=None, max_rows=None, *, like=None): + return (like,) + + +@set_array_function_like_doc +@set_module('numpy') +def loadtxt(fname, dtype=float, comments='#', delimiter=None, + converters=None, skiprows=0, usecols=None, unpack=False, + ndmin=0, encoding='bytes', max_rows=None, *, like=None): + r""" + Load data from a text file. + + Each row in the text file must have the same number of values. + + Parameters + ---------- + fname : file, str, or pathlib.Path + File, filename, or generator to read. If the filename extension is + ``.gz`` or ``.bz2``, the file is first decompressed. Note that + generators should return byte strings. + dtype : data-type, optional + Data-type of the resulting array; default: float. If this is a + structured data-type, the resulting array will be 1-dimensional, and + each row will be interpreted as an element of the array. In this + case, the number of columns used must match the number of fields in + the data-type. + comments : str or sequence of str, optional + The characters or list of characters used to indicate the start of a + comment. None implies no comments. For backwards compatibility, byte + strings will be decoded as 'latin1'. The default is '#'. + delimiter : str, optional + The string used to separate values. For backwards compatibility, byte + strings will be decoded as 'latin1'. The default is whitespace. + converters : dict, optional + A dictionary mapping column number to a function that will parse the + column string into the desired value. E.g., if column 0 is a date + string: ``converters = {0: datestr2num}``. Converters can also be + used to provide a default value for missing data (but see also + `genfromtxt`): ``converters = {3: lambda s: float(s.strip() or 0)}``. + Default: None. + skiprows : int, optional + Skip the first `skiprows` lines, including comments; default: 0. + usecols : int or sequence, optional + Which columns to read, with 0 being the first. For example, + ``usecols = (1,4,5)`` will extract the 2nd, 5th and 6th columns. + The default, None, results in all columns being read. + + .. versionchanged:: 1.11.0 + When a single column has to be read it is possible to use + an integer instead of a tuple. E.g ``usecols = 3`` reads the + fourth column the same way as ``usecols = (3,)`` would. + unpack : bool, optional + If True, the returned array is transposed, so that arguments may be + unpacked using ``x, y, z = loadtxt(...)``. When used with a + structured data-type, arrays are returned for each field. + Default is False. + ndmin : int, optional + The returned array will have at least `ndmin` dimensions. + Otherwise mono-dimensional axes will be squeezed. + Legal values: 0 (default), 1 or 2. + + .. versionadded:: 1.6.0 + encoding : str, optional + Encoding used to decode the inputfile. Does not apply to input streams. + The special value 'bytes' enables backward compatibility workarounds + that ensures you receive byte arrays as results if possible and passes + 'latin1' encoded strings to converters. Override this value to receive + unicode arrays and pass strings as input to converters. If set to None + the system default is used. The default value is 'bytes'. + + .. versionadded:: 1.14.0 + max_rows : int, optional + Read `max_rows` lines of content after `skiprows` lines. The default + is to read all the lines. + + .. versionadded:: 1.16.0 + ${ARRAY_FUNCTION_LIKE} + + .. versionadded:: 1.20.0 + + Returns + ------- + out : ndarray + Data read from the text file. + + See Also + -------- + load, fromstring, fromregex + genfromtxt : Load data with missing values handled as specified. + scipy.io.loadmat : reads MATLAB data files + + Notes + ----- + This function aims to be a fast reader for simply formatted files. The + `genfromtxt` function provides more sophisticated handling of, e.g., + lines with missing values. + + .. versionadded:: 1.10.0 + + The strings produced by the Python float.hex method can be used as + input for floats. + + Examples + -------- + >>> from io import StringIO # StringIO behaves like a file object + >>> c = StringIO("0 1\n2 3") + >>> np.loadtxt(c) + array([[0., 1.], + [2., 3.]]) + + >>> d = StringIO("M 21 72\nF 35 58") + >>> np.loadtxt(d, dtype={'names': ('gender', 'age', 'weight'), + ... 'formats': ('S1', 'i4', 'f4')}) + array([(b'M', 21, 72.), (b'F', 35, 58.)], + dtype=[('gender', 'S1'), ('age', '>> c = StringIO("1,0,2\n3,0,4") + >>> x, y = np.loadtxt(c, delimiter=',', usecols=(0, 2), unpack=True) + >>> x + array([1., 3.]) + >>> y + array([2., 4.]) + + This example shows how `converters` can be used to convert a field + with a trailing minus sign into a negative number. + + >>> s = StringIO('10.01 31.25-\n19.22 64.31\n17.57- 63.94') + >>> def conv(fld): + ... return -float(fld[:-1]) if fld.endswith(b'-') else float(fld) + ... + >>> np.loadtxt(s, converters={0: conv, 1: conv}) + array([[ 10.01, -31.25], + [ 19.22, 64.31], + [-17.57, 63.94]]) + """ + + if like is not None: + return _loadtxt_with_like( + fname, dtype=dtype, comments=comments, delimiter=delimiter, + converters=converters, skiprows=skiprows, usecols=usecols, + unpack=unpack, ndmin=ndmin, encoding=encoding, + max_rows=max_rows, like=like + ) + + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + # Nested functions used by loadtxt. + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + # not to be confused with the flatten_dtype we import... + @recursive + def flatten_dtype_internal(self, dt): + """Unpack a structured data-type, and produce re-packing info.""" + if dt.names is None: + # If the dtype is flattened, return. + # If the dtype has a shape, the dtype occurs + # in the list more than once. + shape = dt.shape + if len(shape) == 0: + return ([dt.base], None) + else: + packing = [(shape[-1], list)] + if len(shape) > 1: + for dim in dt.shape[-2::-1]: + packing = [(dim*packing[0][0], packing*dim)] + return ([dt.base] * int(np.prod(dt.shape)), packing) + else: + types = [] + packing = [] + for field in dt.names: + tp, bytes = dt.fields[field] + flat_dt, flat_packing = self(tp) + types.extend(flat_dt) + # Avoid extra nesting for subarrays + if tp.ndim > 0: + packing.extend(flat_packing) + else: + packing.append((len(flat_dt), flat_packing)) + return (types, packing) + + @recursive + def pack_items(self, items, packing): + """Pack items into nested lists based on re-packing info.""" + if packing is None: + return items[0] + elif packing is tuple: + return tuple(items) + elif packing is list: + return list(items) + else: + start = 0 + ret = [] + for length, subpacking in packing: + ret.append(self(items[start:start+length], subpacking)) + start += length + return tuple(ret) + + def split_line(line): + """Chop off comments, strip, and split at delimiter. """ + line = _decode_line(line, encoding=encoding) + + if comments is not None: + line = regex_comments.split(line, maxsplit=1)[0] + line = line.strip('\r\n') + return line.split(delimiter) if line else [] + + def read_data(chunk_size): + """Parse each line, including the first. + + The file read, `fh`, is a global defined above. + + Parameters + ---------- + chunk_size : int + At most `chunk_size` lines are read at a time, with iteration + until all lines are read. + + """ + X = [] + line_iter = itertools.chain([first_line], fh) + line_iter = itertools.islice(line_iter, max_rows) + for i, line in enumerate(line_iter): + vals = split_line(line) + if len(vals) == 0: + continue + if usecols: + vals = [vals[j] for j in usecols] + if len(vals) != N: + line_num = i + skiprows + 1 + raise ValueError("Wrong number of columns at line %d" + % line_num) + + # Convert each value according to its column and store + items = [conv(val) for (conv, val) in zip(converters, vals)] + + # Then pack it according to the dtype's nesting + items = pack_items(items, packing) + X.append(items) + if len(X) > chunk_size: + yield X + X = [] + if X: + yield X + + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + # Main body of loadtxt. + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + # Check correctness of the values of `ndmin` + if ndmin not in [0, 1, 2]: + raise ValueError('Illegal value of ndmin keyword: %s' % ndmin) + + # Type conversions for Py3 convenience + if comments is not None: + if isinstance(comments, (str, bytes)): + comments = [comments] + comments = [_decode_line(x) for x in comments] + # Compile regex for comments beforehand + comments = (re.escape(comment) for comment in comments) + regex_comments = re.compile('|'.join(comments)) + + if delimiter is not None: + delimiter = _decode_line(delimiter) + + user_converters = converters + + byte_converters = False + if encoding == 'bytes': + encoding = None + byte_converters = True + + if usecols is not None: + # Allow usecols to be a single int or a sequence of ints + try: + usecols_as_list = list(usecols) + except TypeError: + usecols_as_list = [usecols] + for col_idx in usecols_as_list: + try: + opindex(col_idx) + except TypeError as e: + e.args = ( + "usecols must be an int or a sequence of ints but " + "it contains at least one element of type %s" % + type(col_idx), + ) + raise + # Fall back to existing code + usecols = usecols_as_list + + # Make sure we're dealing with a proper dtype + dtype = np.dtype(dtype) + defconv = _getconv(dtype) + + dtype_types, packing = flatten_dtype_internal(dtype) + + fown = False + try: + if isinstance(fname, os_PathLike): + fname = os_fspath(fname) + if _is_string_like(fname): + fh = np.lib._datasource.open(fname, 'rt', encoding=encoding) + fencoding = getattr(fh, 'encoding', 'latin1') + fh = iter(fh) + fown = True + else: + fh = iter(fname) + fencoding = getattr(fname, 'encoding', 'latin1') + except TypeError as e: + raise ValueError( + 'fname must be a string, file handle, or generator' + ) from e + + # input may be a python2 io stream + if encoding is not None: + fencoding = encoding + # we must assume local encoding + # TODO emit portability warning? + elif fencoding is None: + import locale + fencoding = locale.getpreferredencoding() + + try: + # Skip the first `skiprows` lines + for i in range(skiprows): + next(fh) + + # Read until we find a line with some values, and use + # it to estimate the number of columns, N. + first_vals = None + try: + while not first_vals: + first_line = next(fh) + first_vals = split_line(first_line) + except StopIteration: + # End of lines reached + first_line = '' + first_vals = [] + warnings.warn('loadtxt: Empty input file: "%s"' % fname, + stacklevel=2) + N = len(usecols or first_vals) + + # Now that we know N, create the default converters list, and + # set packing, if necessary. + if len(dtype_types) > 1: + # We're dealing with a structured array, each field of + # the dtype matches a column + converters = [_getconv(dt) for dt in dtype_types] + else: + # All fields have the same dtype + converters = [defconv for i in range(N)] + if N > 1: + packing = [(N, tuple)] + + # By preference, use the converters specified by the user + for i, conv in (user_converters or {}).items(): + if usecols: + try: + i = usecols.index(i) + except ValueError: + # Unused converter specified + continue + if byte_converters: + # converters may use decode to workaround numpy's old + # behaviour, so encode the string again before passing to + # the user converter + def tobytes_first(x, conv): + if type(x) is bytes: + return conv(x) + return conv(x.encode("latin1")) + converters[i] = functools.partial(tobytes_first, conv=conv) + else: + converters[i] = conv + + converters = [conv if conv is not bytes else + lambda x: x.encode(fencoding) for conv in converters] + + # read data in chunks and fill it into an array via resize + # over-allocating and shrinking the array later may be faster but is + # probably not relevant compared to the cost of actually reading and + # converting the data + X = None + for x in read_data(_loadtxt_chunksize): + if X is None: + X = np.array(x, dtype) + else: + nshape = list(X.shape) + pos = nshape[0] + nshape[0] += len(x) + X.resize(nshape, refcheck=False) + X[pos:, ...] = x + finally: + if fown: + fh.close() + + if X is None: + X = np.array([], dtype) + + # Multicolumn data are returned with shape (1, N, M), i.e. + # (1, 1, M) for a single row - remove the singleton dimension there + if X.ndim == 3 and X.shape[:2] == (1, 1): + X.shape = (1, -1) + + # Verify that the array has at least dimensions `ndmin`. + # Tweak the size and shape of the arrays - remove extraneous dimensions + if X.ndim > ndmin: + X = np.squeeze(X) + # and ensure we have the minimum number of dimensions asked for + # - has to be in this order for the odd case ndmin=1, X.squeeze().ndim=0 + if X.ndim < ndmin: + if ndmin == 1: + X = np.atleast_1d(X) + elif ndmin == 2: + X = np.atleast_2d(X).T + + if unpack: + if len(dtype_types) > 1: + # For structured arrays, return an array for each field. + return [X[field] for field in dtype.names] + else: + return X.T + else: + return X + + +_loadtxt_with_like = array_function_dispatch( + _loadtxt_dispatcher +)(loadtxt) + + +def _savetxt_dispatcher(fname, X, fmt=None, delimiter=None, newline=None, + header=None, footer=None, comments=None, + encoding=None): + return (X,) + + +@array_function_dispatch(_savetxt_dispatcher) +def savetxt(fname, X, fmt='%.18e', delimiter=' ', newline='\n', header='', + footer='', comments='# ', encoding=None): + """ + Save an array to a text file. + + Parameters + ---------- + fname : filename or file handle + If the filename ends in ``.gz``, the file is automatically saved in + compressed gzip format. `loadtxt` understands gzipped files + transparently. + X : 1D or 2D array_like + Data to be saved to a text file. + fmt : str or sequence of strs, optional + A single format (%10.5f), a sequence of formats, or a + multi-format string, e.g. 'Iteration %d -- %10.5f', in which + case `delimiter` is ignored. For complex `X`, the legal options + for `fmt` are: + + * a single specifier, `fmt='%.4e'`, resulting in numbers formatted + like `' (%s+%sj)' % (fmt, fmt)` + * a full string specifying every real and imaginary part, e.g. + `' %.4e %+.4ej %.4e %+.4ej %.4e %+.4ej'` for 3 columns + * a list of specifiers, one per column - in this case, the real + and imaginary part must have separate specifiers, + e.g. `['%.3e + %.3ej', '(%.15e%+.15ej)']` for 2 columns + delimiter : str, optional + String or character separating columns. + newline : str, optional + String or character separating lines. + + .. versionadded:: 1.5.0 + header : str, optional + String that will be written at the beginning of the file. + + .. versionadded:: 1.7.0 + footer : str, optional + String that will be written at the end of the file. + + .. versionadded:: 1.7.0 + comments : str, optional + String that will be prepended to the ``header`` and ``footer`` strings, + to mark them as comments. Default: '# ', as expected by e.g. + ``numpy.loadtxt``. + + .. versionadded:: 1.7.0 + encoding : {None, str}, optional + Encoding used to encode the outputfile. Does not apply to output + streams. If the encoding is something other than 'bytes' or 'latin1' + you will not be able to load the file in NumPy versions < 1.14. Default + is 'latin1'. + + .. versionadded:: 1.14.0 + + + See Also + -------- + save : Save an array to a binary file in NumPy ``.npy`` format + savez : Save several arrays into an uncompressed ``.npz`` archive + savez_compressed : Save several arrays into a compressed ``.npz`` archive + + Notes + ----- + Further explanation of the `fmt` parameter + (``%[flag]width[.precision]specifier``): + + flags: + ``-`` : left justify + + ``+`` : Forces to precede result with + or -. + + ``0`` : Left pad the number with zeros instead of space (see width). + + width: + Minimum number of characters to be printed. The value is not truncated + if it has more characters. + + precision: + - For integer specifiers (eg. ``d,i,o,x``), the minimum number of + digits. + - For ``e, E`` and ``f`` specifiers, the number of digits to print + after the decimal point. + - For ``g`` and ``G``, the maximum number of significant digits. + - For ``s``, the maximum number of characters. + + specifiers: + ``c`` : character + + ``d`` or ``i`` : signed decimal integer + + ``e`` or ``E`` : scientific notation with ``e`` or ``E``. + + ``f`` : decimal floating point + + ``g,G`` : use the shorter of ``e,E`` or ``f`` + + ``o`` : signed octal + + ``s`` : string of characters + + ``u`` : unsigned decimal integer + + ``x,X`` : unsigned hexadecimal integer + + This explanation of ``fmt`` is not complete, for an exhaustive + specification see [1]_. + + References + ---------- + .. [1] `Format Specification Mini-Language + `_, + Python Documentation. + + Examples + -------- + >>> x = y = z = np.arange(0.0,5.0,1.0) + >>> np.savetxt('test.out', x, delimiter=',') # X is an array + >>> np.savetxt('test.out', (x,y,z)) # x,y,z equal sized 1D arrays + >>> np.savetxt('test.out', x, fmt='%1.4e') # use exponential notation + + """ + + # Py3 conversions first + if isinstance(fmt, bytes): + fmt = asstr(fmt) + delimiter = asstr(delimiter) + + class WriteWrap: + """Convert to bytes on bytestream inputs. + + """ + def __init__(self, fh, encoding): + self.fh = fh + self.encoding = encoding + self.do_write = self.first_write + + def close(self): + self.fh.close() + + def write(self, v): + self.do_write(v) + + def write_bytes(self, v): + if isinstance(v, bytes): + self.fh.write(v) + else: + self.fh.write(v.encode(self.encoding)) + + def write_normal(self, v): + self.fh.write(asunicode(v)) + + def first_write(self, v): + try: + self.write_normal(v) + self.write = self.write_normal + except TypeError: + # input is probably a bytestream + self.write_bytes(v) + self.write = self.write_bytes + + own_fh = False + if isinstance(fname, os_PathLike): + fname = os_fspath(fname) + if _is_string_like(fname): + # datasource doesn't support creating a new file ... + open(fname, 'wt').close() + fh = np.lib._datasource.open(fname, 'wt', encoding=encoding) + own_fh = True + elif hasattr(fname, 'write'): + # wrap to handle byte output streams + fh = WriteWrap(fname, encoding or 'latin1') + else: + raise ValueError('fname must be a string or file handle') + + try: + X = np.asarray(X) + + # Handle 1-dimensional arrays + if X.ndim == 0 or X.ndim > 2: + raise ValueError( + "Expected 1D or 2D array, got %dD array instead" % X.ndim) + elif X.ndim == 1: + # Common case -- 1d array of numbers + if X.dtype.names is None: + X = np.atleast_2d(X).T + ncol = 1 + + # Complex dtype -- each field indicates a separate column + else: + ncol = len(X.dtype.names) + else: + ncol = X.shape[1] + + iscomplex_X = np.iscomplexobj(X) + # `fmt` can be a string with multiple insertion points or a + # list of formats. E.g. '%10.5f\t%10d' or ('%10.5f', '$10d') + if type(fmt) in (list, tuple): + if len(fmt) != ncol: + raise AttributeError('fmt has wrong shape. %s' % str(fmt)) + format = asstr(delimiter).join(map(asstr, fmt)) + elif isinstance(fmt, str): + n_fmt_chars = fmt.count('%') + error = ValueError('fmt has wrong number of %% formats: %s' % fmt) + if n_fmt_chars == 1: + if iscomplex_X: + fmt = [' (%s+%sj)' % (fmt, fmt), ] * ncol + else: + fmt = [fmt, ] * ncol + format = delimiter.join(fmt) + elif iscomplex_X and n_fmt_chars != (2 * ncol): + raise error + elif ((not iscomplex_X) and n_fmt_chars != ncol): + raise error + else: + format = fmt + else: + raise ValueError('invalid fmt: %r' % (fmt,)) + + if len(header) > 0: + header = header.replace('\n', '\n' + comments) + fh.write(comments + header + newline) + if iscomplex_X: + for row in X: + row2 = [] + for number in row: + row2.append(number.real) + row2.append(number.imag) + s = format % tuple(row2) + newline + fh.write(s.replace('+-', '-')) + else: + for row in X: + try: + v = format % tuple(row) + newline + except TypeError as e: + raise TypeError("Mismatch between array dtype ('%s') and " + "format specifier ('%s')" + % (str(X.dtype), format)) from e + fh.write(v) + + if len(footer) > 0: + footer = footer.replace('\n', '\n' + comments) + fh.write(comments + footer + newline) + finally: + if own_fh: + fh.close() + + +@set_module('numpy') +def fromregex(file, regexp, dtype, encoding=None): + """ + Construct an array from a text file, using regular expression parsing. + + The returned array is always a structured array, and is constructed from + all matches of the regular expression in the file. Groups in the regular + expression are converted to fields of the structured array. + + Parameters + ---------- + file : str or file + Filename or file object to read. + regexp : str or regexp + Regular expression used to parse the file. + Groups in the regular expression correspond to fields in the dtype. + dtype : dtype or list of dtypes + Dtype for the structured array. + encoding : str, optional + Encoding used to decode the inputfile. Does not apply to input streams. + + .. versionadded:: 1.14.0 + + Returns + ------- + output : ndarray + The output array, containing the part of the content of `file` that + was matched by `regexp`. `output` is always a structured array. + + Raises + ------ + TypeError + When `dtype` is not a valid dtype for a structured array. + + See Also + -------- + fromstring, loadtxt + + Notes + ----- + Dtypes for structured arrays can be specified in several forms, but all + forms specify at least the data type and field name. For details see + `basics.rec`. + + Examples + -------- + >>> f = open('test.dat', 'w') + >>> _ = f.write("1312 foo\\n1534 bar\\n444 qux") + >>> f.close() + + >>> regexp = r"(\\d+)\\s+(...)" # match [digits, whitespace, anything] + >>> output = np.fromregex('test.dat', regexp, + ... [('num', np.int64), ('key', 'S3')]) + >>> output + array([(1312, b'foo'), (1534, b'bar'), ( 444, b'qux')], + dtype=[('num', '>> output['num'] + array([1312, 1534, 444]) + + """ + own_fh = False + if not hasattr(file, "read"): + file = np.lib._datasource.open(file, 'rt', encoding=encoding) + own_fh = True + + try: + if not isinstance(dtype, np.dtype): + dtype = np.dtype(dtype) + + content = file.read() + if isinstance(content, bytes) and isinstance(regexp, np.compat.unicode): + regexp = asbytes(regexp) + elif isinstance(content, np.compat.unicode) and isinstance(regexp, bytes): + regexp = asstr(regexp) + + if not hasattr(regexp, 'match'): + regexp = re.compile(regexp) + seq = regexp.findall(content) + if seq and not isinstance(seq[0], tuple): + # Only one group is in the regexp. + # Create the new array as a single data-type and then + # re-interpret as a single-field structured array. + newdtype = np.dtype(dtype[dtype.names[0]]) + output = np.array(seq, dtype=newdtype) + output.dtype = dtype + else: + output = np.array(seq, dtype=dtype) + + return output + finally: + if own_fh: + file.close() + + +#####-------------------------------------------------------------------------- +#---- --- ASCII functions --- +#####-------------------------------------------------------------------------- + + +def _genfromtxt_dispatcher(fname, dtype=None, comments=None, delimiter=None, + skip_header=None, skip_footer=None, converters=None, + missing_values=None, filling_values=None, usecols=None, + names=None, excludelist=None, deletechars=None, + replace_space=None, autostrip=None, case_sensitive=None, + defaultfmt=None, unpack=None, usemask=None, loose=None, + invalid_raise=None, max_rows=None, encoding=None, *, + like=None): + return (like,) + + +@set_array_function_like_doc +@set_module('numpy') +def genfromtxt(fname, dtype=float, comments='#', delimiter=None, + skip_header=0, skip_footer=0, converters=None, + missing_values=None, filling_values=None, usecols=None, + names=None, excludelist=None, + deletechars=''.join(sorted(NameValidator.defaultdeletechars)), + replace_space='_', autostrip=False, case_sensitive=True, + defaultfmt="f%i", unpack=None, usemask=False, loose=True, + invalid_raise=True, max_rows=None, encoding='bytes', *, + like=None): + """ + Load data from a text file, with missing values handled as specified. + + Each line past the first `skip_header` lines is split at the `delimiter` + character, and characters following the `comments` character are discarded. + + Parameters + ---------- + fname : file, str, pathlib.Path, list of str, generator + File, filename, list, or generator to read. If the filename + extension is `.gz` or `.bz2`, the file is first decompressed. Note + that generators must return byte strings. The strings + in a list or produced by a generator are treated as lines. + dtype : dtype, optional + Data type of the resulting array. + If None, the dtypes will be determined by the contents of each + column, individually. + comments : str, optional + The character used to indicate the start of a comment. + All the characters occurring on a line after a comment are discarded + delimiter : str, int, or sequence, optional + The string used to separate values. By default, any consecutive + whitespaces act as delimiter. An integer or sequence of integers + can also be provided as width(s) of each field. + skiprows : int, optional + `skiprows` was removed in numpy 1.10. Please use `skip_header` instead. + skip_header : int, optional + The number of lines to skip at the beginning of the file. + skip_footer : int, optional + The number of lines to skip at the end of the file. + converters : variable, optional + The set of functions that convert the data of a column to a value. + The converters can also be used to provide a default value + for missing data: ``converters = {3: lambda s: float(s or 0)}``. + missing : variable, optional + `missing` was removed in numpy 1.10. Please use `missing_values` + instead. + missing_values : variable, optional + The set of strings corresponding to missing data. + filling_values : variable, optional + The set of values to be used as default when the data are missing. + usecols : sequence, optional + Which columns to read, with 0 being the first. For example, + ``usecols = (1, 4, 5)`` will extract the 2nd, 5th and 6th columns. + names : {None, True, str, sequence}, optional + If `names` is True, the field names are read from the first line after + the first `skip_header` lines. This line can optionally be proceeded + by a comment delimiter. If `names` is a sequence or a single-string of + comma-separated names, the names will be used to define the field names + in a structured dtype. If `names` is None, the names of the dtype + fields will be used, if any. + excludelist : sequence, optional + A list of names to exclude. This list is appended to the default list + ['return','file','print']. Excluded names are appended an underscore: + for example, `file` would become `file_`. + deletechars : str, optional + A string combining invalid characters that must be deleted from the + names. + defaultfmt : str, optional + A format used to define default field names, such as "f%i" or "f_%02i". + autostrip : bool, optional + Whether to automatically strip white spaces from the variables. + replace_space : char, optional + Character(s) used in replacement of white spaces in the variables + names. By default, use a '_'. + case_sensitive : {True, False, 'upper', 'lower'}, optional + If True, field names are case sensitive. + If False or 'upper', field names are converted to upper case. + If 'lower', field names are converted to lower case. + unpack : bool, optional + If True, the returned array is transposed, so that arguments may be + unpacked using ``x, y, z = genfromtxt(...)``. When used with a + structured data-type, arrays are returned for each field. + Default is False. + usemask : bool, optional + If True, return a masked array. + If False, return a regular array. + loose : bool, optional + If True, do not raise errors for invalid values. + invalid_raise : bool, optional + If True, an exception is raised if an inconsistency is detected in the + number of columns. + If False, a warning is emitted and the offending lines are skipped. + max_rows : int, optional + The maximum number of rows to read. Must not be used with skip_footer + at the same time. If given, the value must be at least 1. Default is + to read the entire file. + + .. versionadded:: 1.10.0 + encoding : str, optional + Encoding used to decode the inputfile. Does not apply when `fname` is + a file object. The special value 'bytes' enables backward compatibility + workarounds that ensure that you receive byte arrays when possible + and passes latin1 encoded strings to converters. Override this value to + receive unicode arrays and pass strings as input to converters. If set + to None the system default is used. The default value is 'bytes'. + + .. versionadded:: 1.14.0 + ${ARRAY_FUNCTION_LIKE} + + .. versionadded:: 1.20.0 + + Returns + ------- + out : ndarray + Data read from the text file. If `usemask` is True, this is a + masked array. + + See Also + -------- + numpy.loadtxt : equivalent function when no data is missing. + + Notes + ----- + * When spaces are used as delimiters, or when no delimiter has been given + as input, there should not be any missing data between two fields. + * When the variables are named (either by a flexible dtype or with `names`), + there must not be any header in the file (else a ValueError + exception is raised). + * Individual values are not stripped of spaces by default. + When using a custom converter, make sure the function does remove spaces. + + References + ---------- + .. [1] NumPy User Guide, section `I/O with NumPy + `_. + + Examples + -------- + >>> from io import StringIO + >>> import numpy as np + + Comma delimited file with mixed dtype + + >>> s = StringIO(u"1,1.3,abcde") + >>> data = np.genfromtxt(s, dtype=[('myint','i8'),('myfloat','f8'), + ... ('mystring','S5')], delimiter=",") + >>> data + array((1, 1.3, b'abcde'), + dtype=[('myint', '>> _ = s.seek(0) # needed for StringIO example only + >>> data = np.genfromtxt(s, dtype=None, + ... names = ['myint','myfloat','mystring'], delimiter=",") + >>> data + array((1, 1.3, b'abcde'), + dtype=[('myint', '>> _ = s.seek(0) + >>> data = np.genfromtxt(s, dtype="i8,f8,S5", + ... names=['myint','myfloat','mystring'], delimiter=",") + >>> data + array((1, 1.3, b'abcde'), + dtype=[('myint', '>> s = StringIO(u"11.3abcde") + >>> data = np.genfromtxt(s, dtype=None, names=['intvar','fltvar','strvar'], + ... delimiter=[1,3,5]) + >>> data + array((1, 1.3, b'abcde'), + dtype=[('intvar', '>> f = StringIO(''' + ... text,# of chars + ... hello world,11 + ... numpy,5''') + >>> np.genfromtxt(f, dtype='S12,S12', delimiter=',') + array([(b'text', b''), (b'hello world', b'11'), (b'numpy', b'5')], + dtype=[('f0', 'S12'), ('f1', 'S12')]) + + """ + + if like is not None: + return _genfromtxt_with_like( + fname, dtype=dtype, comments=comments, delimiter=delimiter, + skip_header=skip_header, skip_footer=skip_footer, + converters=converters, missing_values=missing_values, + filling_values=filling_values, usecols=usecols, names=names, + excludelist=excludelist, deletechars=deletechars, + replace_space=replace_space, autostrip=autostrip, + case_sensitive=case_sensitive, defaultfmt=defaultfmt, + unpack=unpack, usemask=usemask, loose=loose, + invalid_raise=invalid_raise, max_rows=max_rows, encoding=encoding, + like=like + ) + + if max_rows is not None: + if skip_footer: + raise ValueError( + "The keywords 'skip_footer' and 'max_rows' can not be " + "specified at the same time.") + if max_rows < 1: + raise ValueError("'max_rows' must be at least 1.") + + if usemask: + from numpy.ma import MaskedArray, make_mask_descr + # Check the input dictionary of converters + user_converters = converters or {} + if not isinstance(user_converters, dict): + raise TypeError( + "The input argument 'converter' should be a valid dictionary " + "(got '%s' instead)" % type(user_converters)) + + if encoding == 'bytes': + encoding = None + byte_converters = True + else: + byte_converters = False + + # Initialize the filehandle, the LineSplitter and the NameValidator + try: + if isinstance(fname, os_PathLike): + fname = os_fspath(fname) + if isinstance(fname, str): + fid = np.lib._datasource.open(fname, 'rt', encoding=encoding) + fid_ctx = contextlib.closing(fid) + else: + fid = fname + fid_ctx = contextlib_nullcontext(fid) + fhd = iter(fid) + except TypeError as e: + raise TypeError( + "fname must be a string, filehandle, list of strings, " + "or generator. Got %s instead." % type(fname)) from e + + with fid_ctx: + split_line = LineSplitter(delimiter=delimiter, comments=comments, + autostrip=autostrip, encoding=encoding) + validate_names = NameValidator(excludelist=excludelist, + deletechars=deletechars, + case_sensitive=case_sensitive, + replace_space=replace_space) + + # Skip the first `skip_header` rows + try: + for i in range(skip_header): + next(fhd) + + # Keep on until we find the first valid values + first_values = None + + while not first_values: + first_line = _decode_line(next(fhd), encoding) + if (names is True) and (comments is not None): + if comments in first_line: + first_line = ( + ''.join(first_line.split(comments)[1:])) + first_values = split_line(first_line) + except StopIteration: + # return an empty array if the datafile is empty + first_line = '' + first_values = [] + warnings.warn('genfromtxt: Empty input file: "%s"' % fname, stacklevel=2) + + # Should we take the first values as names ? + if names is True: + fval = first_values[0].strip() + if comments is not None: + if fval in comments: + del first_values[0] + + # Check the columns to use: make sure `usecols` is a list + if usecols is not None: + try: + usecols = [_.strip() for _ in usecols.split(",")] + except AttributeError: + try: + usecols = list(usecols) + except TypeError: + usecols = [usecols, ] + nbcols = len(usecols or first_values) + + # Check the names and overwrite the dtype.names if needed + if names is True: + names = validate_names([str(_.strip()) for _ in first_values]) + first_line = '' + elif _is_string_like(names): + names = validate_names([_.strip() for _ in names.split(',')]) + elif names: + names = validate_names(names) + # Get the dtype + if dtype is not None: + dtype = easy_dtype(dtype, defaultfmt=defaultfmt, names=names, + excludelist=excludelist, + deletechars=deletechars, + case_sensitive=case_sensitive, + replace_space=replace_space) + # Make sure the names is a list (for 2.5) + if names is not None: + names = list(names) + + if usecols: + for (i, current) in enumerate(usecols): + # if usecols is a list of names, convert to a list of indices + if _is_string_like(current): + usecols[i] = names.index(current) + elif current < 0: + usecols[i] = current + len(first_values) + # If the dtype is not None, make sure we update it + if (dtype is not None) and (len(dtype) > nbcols): + descr = dtype.descr + dtype = np.dtype([descr[_] for _ in usecols]) + names = list(dtype.names) + # If `names` is not None, update the names + elif (names is not None) and (len(names) > nbcols): + names = [names[_] for _ in usecols] + elif (names is not None) and (dtype is not None): + names = list(dtype.names) + + # Process the missing values ............................... + # Rename missing_values for convenience + user_missing_values = missing_values or () + if isinstance(user_missing_values, bytes): + user_missing_values = user_missing_values.decode('latin1') + + # Define the list of missing_values (one column: one list) + missing_values = [list(['']) for _ in range(nbcols)] + + # We have a dictionary: process it field by field + if isinstance(user_missing_values, dict): + # Loop on the items + for (key, val) in user_missing_values.items(): + # Is the key a string ? + if _is_string_like(key): + try: + # Transform it into an integer + key = names.index(key) + except ValueError: + # We couldn't find it: the name must have been dropped + continue + # Redefine the key as needed if it's a column number + if usecols: + try: + key = usecols.index(key) + except ValueError: + pass + # Transform the value as a list of string + if isinstance(val, (list, tuple)): + val = [str(_) for _ in val] + else: + val = [str(val), ] + # Add the value(s) to the current list of missing + if key is None: + # None acts as default + for miss in missing_values: + miss.extend(val) + else: + missing_values[key].extend(val) + # We have a sequence : each item matches a column + elif isinstance(user_missing_values, (list, tuple)): + for (value, entry) in zip(user_missing_values, missing_values): + value = str(value) + if value not in entry: + entry.append(value) + # We have a string : apply it to all entries + elif isinstance(user_missing_values, str): + user_value = user_missing_values.split(",") + for entry in missing_values: + entry.extend(user_value) + # We have something else: apply it to all entries + else: + for entry in missing_values: + entry.extend([str(user_missing_values)]) + + # Process the filling_values ............................... + # Rename the input for convenience + user_filling_values = filling_values + if user_filling_values is None: + user_filling_values = [] + # Define the default + filling_values = [None] * nbcols + # We have a dictionary : update each entry individually + if isinstance(user_filling_values, dict): + for (key, val) in user_filling_values.items(): + if _is_string_like(key): + try: + # Transform it into an integer + key = names.index(key) + except ValueError: + # We couldn't find it: the name must have been dropped, + continue + # Redefine the key if it's a column number and usecols is defined + if usecols: + try: + key = usecols.index(key) + except ValueError: + pass + # Add the value to the list + filling_values[key] = val + # We have a sequence : update on a one-to-one basis + elif isinstance(user_filling_values, (list, tuple)): + n = len(user_filling_values) + if (n <= nbcols): + filling_values[:n] = user_filling_values + else: + filling_values = user_filling_values[:nbcols] + # We have something else : use it for all entries + else: + filling_values = [user_filling_values] * nbcols + + # Initialize the converters ................................ + if dtype is None: + # Note: we can't use a [...]*nbcols, as we would have 3 times the same + # ... converter, instead of 3 different converters. + converters = [StringConverter(None, missing_values=miss, default=fill) + for (miss, fill) in zip(missing_values, filling_values)] + else: + dtype_flat = flatten_dtype(dtype, flatten_base=True) + # Initialize the converters + if len(dtype_flat) > 1: + # Flexible type : get a converter from each dtype + zipit = zip(dtype_flat, missing_values, filling_values) + converters = [StringConverter(dt, locked=True, + missing_values=miss, default=fill) + for (dt, miss, fill) in zipit] + else: + # Set to a default converter (but w/ different missing values) + zipit = zip(missing_values, filling_values) + converters = [StringConverter(dtype, locked=True, + missing_values=miss, default=fill) + for (miss, fill) in zipit] + # Update the converters to use the user-defined ones + uc_update = [] + for (j, conv) in user_converters.items(): + # If the converter is specified by column names, use the index instead + if _is_string_like(j): + try: + j = names.index(j) + i = j + except ValueError: + continue + elif usecols: + try: + i = usecols.index(j) + except ValueError: + # Unused converter specified + continue + else: + i = j + # Find the value to test - first_line is not filtered by usecols: + if len(first_line): + testing_value = first_values[j] + else: + testing_value = None + if conv is bytes: + user_conv = asbytes + elif byte_converters: + # converters may use decode to workaround numpy's old behaviour, + # so encode the string again before passing to the user converter + def tobytes_first(x, conv): + if type(x) is bytes: + return conv(x) + return conv(x.encode("latin1")) + user_conv = functools.partial(tobytes_first, conv=conv) + else: + user_conv = conv + converters[i].update(user_conv, locked=True, + testing_value=testing_value, + default=filling_values[i], + missing_values=missing_values[i],) + uc_update.append((i, user_conv)) + # Make sure we have the corrected keys in user_converters... + user_converters.update(uc_update) + + # Fixme: possible error as following variable never used. + # miss_chars = [_.missing_values for _ in converters] + + # Initialize the output lists ... + # ... rows + rows = [] + append_to_rows = rows.append + # ... masks + if usemask: + masks = [] + append_to_masks = masks.append + # ... invalid + invalid = [] + append_to_invalid = invalid.append + + # Parse each line + for (i, line) in enumerate(itertools.chain([first_line, ], fhd)): + values = split_line(line) + nbvalues = len(values) + # Skip an empty line + if nbvalues == 0: + continue + if usecols: + # Select only the columns we need + try: + values = [values[_] for _ in usecols] + except IndexError: + append_to_invalid((i + skip_header + 1, nbvalues)) + continue + elif nbvalues != nbcols: + append_to_invalid((i + skip_header + 1, nbvalues)) + continue + # Store the values + append_to_rows(tuple(values)) + if usemask: + append_to_masks(tuple([v.strip() in m + for (v, m) in zip(values, + missing_values)])) + if len(rows) == max_rows: + break + + # Upgrade the converters (if needed) + if dtype is None: + for (i, converter) in enumerate(converters): + current_column = [itemgetter(i)(_m) for _m in rows] + try: + converter.iterupgrade(current_column) + except ConverterLockError: + errmsg = "Converter #%i is locked and cannot be upgraded: " % i + current_column = map(itemgetter(i), rows) + for (j, value) in enumerate(current_column): + try: + converter.upgrade(value) + except (ConverterError, ValueError): + errmsg += "(occurred line #%i for value '%s')" + errmsg %= (j + 1 + skip_header, value) + raise ConverterError(errmsg) + + # Check that we don't have invalid values + nbinvalid = len(invalid) + if nbinvalid > 0: + nbrows = len(rows) + nbinvalid - skip_footer + # Construct the error message + template = " Line #%%i (got %%i columns instead of %i)" % nbcols + if skip_footer > 0: + nbinvalid_skipped = len([_ for _ in invalid + if _[0] > nbrows + skip_header]) + invalid = invalid[:nbinvalid - nbinvalid_skipped] + skip_footer -= nbinvalid_skipped +# +# nbrows -= skip_footer +# errmsg = [template % (i, nb) +# for (i, nb) in invalid if i < nbrows] +# else: + errmsg = [template % (i, nb) + for (i, nb) in invalid] + if len(errmsg): + errmsg.insert(0, "Some errors were detected !") + errmsg = "\n".join(errmsg) + # Raise an exception ? + if invalid_raise: + raise ValueError(errmsg) + # Issue a warning ? + else: + warnings.warn(errmsg, ConversionWarning, stacklevel=2) + + # Strip the last skip_footer data + if skip_footer > 0: + rows = rows[:-skip_footer] + if usemask: + masks = masks[:-skip_footer] + + # Convert each value according to the converter: + # We want to modify the list in place to avoid creating a new one... + if loose: + rows = list( + zip(*[[conv._loose_call(_r) for _r in map(itemgetter(i), rows)] + for (i, conv) in enumerate(converters)])) + else: + rows = list( + zip(*[[conv._strict_call(_r) for _r in map(itemgetter(i), rows)] + for (i, conv) in enumerate(converters)])) + + # Reset the dtype + data = rows + if dtype is None: + # Get the dtypes from the types of the converters + column_types = [conv.type for conv in converters] + # Find the columns with strings... + strcolidx = [i for (i, v) in enumerate(column_types) + if v == np.unicode_] + + if byte_converters and strcolidx: + # convert strings back to bytes for backward compatibility + warnings.warn( + "Reading unicode strings without specifying the encoding " + "argument is deprecated. Set the encoding, use None for the " + "system default.", + np.VisibleDeprecationWarning, stacklevel=2) + def encode_unicode_cols(row_tup): + row = list(row_tup) + for i in strcolidx: + row[i] = row[i].encode('latin1') + return tuple(row) + + try: + data = [encode_unicode_cols(r) for r in data] + except UnicodeEncodeError: + pass + else: + for i in strcolidx: + column_types[i] = np.bytes_ + + # Update string types to be the right length + sized_column_types = column_types[:] + for i, col_type in enumerate(column_types): + if np.issubdtype(col_type, np.character): + n_chars = max(len(row[i]) for row in data) + sized_column_types[i] = (col_type, n_chars) + + if names is None: + # If the dtype is uniform (before sizing strings) + base = { + c_type + for c, c_type in zip(converters, column_types) + if c._checked} + if len(base) == 1: + uniform_type, = base + (ddtype, mdtype) = (uniform_type, bool) + else: + ddtype = [(defaultfmt % i, dt) + for (i, dt) in enumerate(sized_column_types)] + if usemask: + mdtype = [(defaultfmt % i, bool) + for (i, dt) in enumerate(sized_column_types)] + else: + ddtype = list(zip(names, sized_column_types)) + mdtype = list(zip(names, [bool] * len(sized_column_types))) + output = np.array(data, dtype=ddtype) + if usemask: + outputmask = np.array(masks, dtype=mdtype) + else: + # Overwrite the initial dtype names if needed + if names and dtype.names is not None: + dtype.names = names + # Case 1. We have a structured type + if len(dtype_flat) > 1: + # Nested dtype, eg [('a', int), ('b', [('b0', int), ('b1', 'f4')])] + # First, create the array using a flattened dtype: + # [('a', int), ('b1', int), ('b2', float)] + # Then, view the array using the specified dtype. + if 'O' in (_.char for _ in dtype_flat): + if has_nested_fields(dtype): + raise NotImplementedError( + "Nested fields involving objects are not supported...") + else: + output = np.array(data, dtype=dtype) + else: + rows = np.array(data, dtype=[('', _) for _ in dtype_flat]) + output = rows.view(dtype) + # Now, process the rowmasks the same way + if usemask: + rowmasks = np.array( + masks, dtype=np.dtype([('', bool) for t in dtype_flat])) + # Construct the new dtype + mdtype = make_mask_descr(dtype) + outputmask = rowmasks.view(mdtype) + # Case #2. We have a basic dtype + else: + # We used some user-defined converters + if user_converters: + ishomogeneous = True + descr = [] + for i, ttype in enumerate([conv.type for conv in converters]): + # Keep the dtype of the current converter + if i in user_converters: + ishomogeneous &= (ttype == dtype.type) + if np.issubdtype(ttype, np.character): + ttype = (ttype, max(len(row[i]) for row in data)) + descr.append(('', ttype)) + else: + descr.append(('', dtype)) + # So we changed the dtype ? + if not ishomogeneous: + # We have more than one field + if len(descr) > 1: + dtype = np.dtype(descr) + # We have only one field: drop the name if not needed. + else: + dtype = np.dtype(ttype) + # + output = np.array(data, dtype) + if usemask: + if dtype.names is not None: + mdtype = [(_, bool) for _ in dtype.names] + else: + mdtype = bool + outputmask = np.array(masks, dtype=mdtype) + # Try to take care of the missing data we missed + names = output.dtype.names + if usemask and names: + for (name, conv) in zip(names, converters): + missing_values = [conv(_) for _ in conv.missing_values + if _ != ''] + for mval in missing_values: + outputmask[name] |= (output[name] == mval) + # Construct the final array + if usemask: + output = output.view(MaskedArray) + output._mask = outputmask + output = np.squeeze(output) + if unpack: + if names is None: + return output.T + elif len(names) == 1: + # squeeze single-name dtypes too + return output[names[0]] + else: + # For structured arrays with multiple fields, + # return an array for each field. + return [output[field] for field in names] + return output + + +_genfromtxt_with_like = array_function_dispatch( + _genfromtxt_dispatcher +)(genfromtxt) + + +def ndfromtxt(fname, **kwargs): + """ + Load ASCII data stored in a file and return it as a single array. + + .. deprecated:: 1.17 + ndfromtxt` is a deprecated alias of `genfromtxt` which + overwrites the ``usemask`` argument with `False` even when + explicitly called as ``ndfromtxt(..., usemask=True)``. + Use `genfromtxt` instead. + + Parameters + ---------- + fname, kwargs : For a description of input parameters, see `genfromtxt`. + + See Also + -------- + numpy.genfromtxt : generic function. + + """ + kwargs['usemask'] = False + # Numpy 1.17 + warnings.warn( + "np.ndfromtxt is a deprecated alias of np.genfromtxt, " + "prefer the latter.", + DeprecationWarning, stacklevel=2) + return genfromtxt(fname, **kwargs) + + +def mafromtxt(fname, **kwargs): + """ + Load ASCII data stored in a text file and return a masked array. + + .. deprecated:: 1.17 + np.mafromtxt is a deprecated alias of `genfromtxt` which + overwrites the ``usemask`` argument with `True` even when + explicitly called as ``mafromtxt(..., usemask=False)``. + Use `genfromtxt` instead. + + Parameters + ---------- + fname, kwargs : For a description of input parameters, see `genfromtxt`. + + See Also + -------- + numpy.genfromtxt : generic function to load ASCII data. + + """ + kwargs['usemask'] = True + # Numpy 1.17 + warnings.warn( + "np.mafromtxt is a deprecated alias of np.genfromtxt, " + "prefer the latter.", + DeprecationWarning, stacklevel=2) + return genfromtxt(fname, **kwargs) + + +def recfromtxt(fname, **kwargs): + """ + Load ASCII data from a file and return it in a record array. + + If ``usemask=False`` a standard `recarray` is returned, + if ``usemask=True`` a MaskedRecords array is returned. + + Parameters + ---------- + fname, kwargs : For a description of input parameters, see `genfromtxt`. + + See Also + -------- + numpy.genfromtxt : generic function + + Notes + ----- + By default, `dtype` is None, which means that the data-type of the output + array will be determined from the data. + + """ + kwargs.setdefault("dtype", None) + usemask = kwargs.get('usemask', False) + output = genfromtxt(fname, **kwargs) + if usemask: + from numpy.ma.mrecords import MaskedRecords + output = output.view(MaskedRecords) + else: + output = output.view(np.recarray) + return output + + +def recfromcsv(fname, **kwargs): + """ + Load ASCII data stored in a comma-separated file. + + The returned array is a record array (if ``usemask=False``, see + `recarray`) or a masked record array (if ``usemask=True``, + see `ma.mrecords.MaskedRecords`). + + Parameters + ---------- + fname, kwargs : For a description of input parameters, see `genfromtxt`. + + See Also + -------- + numpy.genfromtxt : generic function to load ASCII data. + + Notes + ----- + By default, `dtype` is None, which means that the data-type of the output + array will be determined from the data. + + """ + # Set default kwargs for genfromtxt as relevant to csv import. + kwargs.setdefault("case_sensitive", "lower") + kwargs.setdefault("names", True) + kwargs.setdefault("delimiter", ",") + kwargs.setdefault("dtype", None) + output = genfromtxt(fname, **kwargs) + + usemask = kwargs.get("usemask", False) + if usemask: + from numpy.ma.mrecords import MaskedRecords + output = output.view(MaskedRecords) + else: + output = output.view(np.recarray) + return output diff --git a/venv/Lib/site-packages/numpy/lib/polynomial.py b/venv/Lib/site-packages/numpy/lib/polynomial.py new file mode 100644 index 0000000..0fd9bbd --- /dev/null +++ b/venv/Lib/site-packages/numpy/lib/polynomial.py @@ -0,0 +1,1444 @@ +""" +Functions to operate on polynomials. + +""" +__all__ = ['poly', 'roots', 'polyint', 'polyder', 'polyadd', + 'polysub', 'polymul', 'polydiv', 'polyval', 'poly1d', + 'polyfit', 'RankWarning'] + +import functools +import re +import warnings +import numpy.core.numeric as NX + +from numpy.core import (isscalar, abs, finfo, atleast_1d, hstack, dot, array, + ones) +from numpy.core import overrides +from numpy.core.overrides import set_module +from numpy.lib.twodim_base import diag, vander +from numpy.lib.function_base import trim_zeros +from numpy.lib.type_check import iscomplex, real, imag, mintypecode +from numpy.linalg import eigvals, lstsq, inv + + +array_function_dispatch = functools.partial( + overrides.array_function_dispatch, module='numpy') + + +@set_module('numpy') +class RankWarning(UserWarning): + """ + Issued by `polyfit` when the Vandermonde matrix is rank deficient. + + For more information, a way to suppress the warning, and an example of + `RankWarning` being issued, see `polyfit`. + + """ + pass + + +def _poly_dispatcher(seq_of_zeros): + return seq_of_zeros + + +@array_function_dispatch(_poly_dispatcher) +def poly(seq_of_zeros): + """ + Find the coefficients of a polynomial with the given sequence of roots. + + .. note:: + This forms part of the old polynomial API. Since version 1.4, the + new polynomial API defined in `numpy.polynomial` is preferred. + A summary of the differences can be found in the + :doc:`transition guide `. + + Returns the coefficients of the polynomial whose leading coefficient + is one for the given sequence of zeros (multiple roots must be included + in the sequence as many times as their multiplicity; see Examples). + A square matrix (or array, which will be treated as a matrix) can also + be given, in which case the coefficients of the characteristic polynomial + of the matrix are returned. + + Parameters + ---------- + seq_of_zeros : array_like, shape (N,) or (N, N) + A sequence of polynomial roots, or a square array or matrix object. + + Returns + ------- + c : ndarray + 1D array of polynomial coefficients from highest to lowest degree: + + ``c[0] * x**(N) + c[1] * x**(N-1) + ... + c[N-1] * x + c[N]`` + where c[0] always equals 1. + + Raises + ------ + ValueError + If input is the wrong shape (the input must be a 1-D or square + 2-D array). + + See Also + -------- + polyval : Compute polynomial values. + roots : Return the roots of a polynomial. + polyfit : Least squares polynomial fit. + poly1d : A one-dimensional polynomial class. + + Notes + ----- + Specifying the roots of a polynomial still leaves one degree of + freedom, typically represented by an undetermined leading + coefficient. [1]_ In the case of this function, that coefficient - + the first one in the returned array - is always taken as one. (If + for some reason you have one other point, the only automatic way + presently to leverage that information is to use ``polyfit``.) + + The characteristic polynomial, :math:`p_a(t)`, of an `n`-by-`n` + matrix **A** is given by + + :math:`p_a(t) = \\mathrm{det}(t\\, \\mathbf{I} - \\mathbf{A})`, + + where **I** is the `n`-by-`n` identity matrix. [2]_ + + References + ---------- + .. [1] M. Sullivan and M. Sullivan, III, "Algebra and Trignometry, + Enhanced With Graphing Utilities," Prentice-Hall, pg. 318, 1996. + + .. [2] G. Strang, "Linear Algebra and Its Applications, 2nd Edition," + Academic Press, pg. 182, 1980. + + Examples + -------- + Given a sequence of a polynomial's zeros: + + >>> np.poly((0, 0, 0)) # Multiple root example + array([1., 0., 0., 0.]) + + The line above represents z**3 + 0*z**2 + 0*z + 0. + + >>> np.poly((-1./2, 0, 1./2)) + array([ 1. , 0. , -0.25, 0. ]) + + The line above represents z**3 - z/4 + + >>> np.poly((np.random.random(1)[0], 0, np.random.random(1)[0])) + array([ 1. , -0.77086955, 0.08618131, 0. ]) # random + + Given a square array object: + + >>> P = np.array([[0, 1./3], [-1./2, 0]]) + >>> np.poly(P) + array([1. , 0. , 0.16666667]) + + Note how in all cases the leading coefficient is always 1. + + """ + seq_of_zeros = atleast_1d(seq_of_zeros) + sh = seq_of_zeros.shape + + if len(sh) == 2 and sh[0] == sh[1] and sh[0] != 0: + seq_of_zeros = eigvals(seq_of_zeros) + elif len(sh) == 1: + dt = seq_of_zeros.dtype + # Let object arrays slip through, e.g. for arbitrary precision + if dt != object: + seq_of_zeros = seq_of_zeros.astype(mintypecode(dt.char)) + else: + raise ValueError("input must be 1d or non-empty square 2d array.") + + if len(seq_of_zeros) == 0: + return 1.0 + dt = seq_of_zeros.dtype + a = ones((1,), dtype=dt) + for k in range(len(seq_of_zeros)): + a = NX.convolve(a, array([1, -seq_of_zeros[k]], dtype=dt), + mode='full') + + if issubclass(a.dtype.type, NX.complexfloating): + # if complex roots are all complex conjugates, the roots are real. + roots = NX.asarray(seq_of_zeros, complex) + if NX.all(NX.sort(roots) == NX.sort(roots.conjugate())): + a = a.real.copy() + + return a + + +def _roots_dispatcher(p): + return p + + +@array_function_dispatch(_roots_dispatcher) +def roots(p): + """ + Return the roots of a polynomial with coefficients given in p. + + .. note:: + This forms part of the old polynomial API. Since version 1.4, the + new polynomial API defined in `numpy.polynomial` is preferred. + A summary of the differences can be found in the + :doc:`transition guide `. + + The values in the rank-1 array `p` are coefficients of a polynomial. + If the length of `p` is n+1 then the polynomial is described by:: + + p[0] * x**n + p[1] * x**(n-1) + ... + p[n-1]*x + p[n] + + Parameters + ---------- + p : array_like + Rank-1 array of polynomial coefficients. + + Returns + ------- + out : ndarray + An array containing the roots of the polynomial. + + Raises + ------ + ValueError + When `p` cannot be converted to a rank-1 array. + + See also + -------- + poly : Find the coefficients of a polynomial with a given sequence + of roots. + polyval : Compute polynomial values. + polyfit : Least squares polynomial fit. + poly1d : A one-dimensional polynomial class. + + Notes + ----- + The algorithm relies on computing the eigenvalues of the + companion matrix [1]_. + + References + ---------- + .. [1] R. A. Horn & C. R. Johnson, *Matrix Analysis*. Cambridge, UK: + Cambridge University Press, 1999, pp. 146-7. + + Examples + -------- + >>> coeff = [3.2, 2, 1] + >>> np.roots(coeff) + array([-0.3125+0.46351241j, -0.3125-0.46351241j]) + + """ + # If input is scalar, this makes it an array + p = atleast_1d(p) + if p.ndim != 1: + raise ValueError("Input must be a rank-1 array.") + + # find non-zero array entries + non_zero = NX.nonzero(NX.ravel(p))[0] + + # Return an empty array if polynomial is all zeros + if len(non_zero) == 0: + return NX.array([]) + + # find the number of trailing zeros -- this is the number of roots at 0. + trailing_zeros = len(p) - non_zero[-1] - 1 + + # strip leading and trailing zeros + p = p[int(non_zero[0]):int(non_zero[-1])+1] + + # casting: if incoming array isn't floating point, make it floating point. + if not issubclass(p.dtype.type, (NX.floating, NX.complexfloating)): + p = p.astype(float) + + N = len(p) + if N > 1: + # build companion matrix and find its eigenvalues (the roots) + A = diag(NX.ones((N-2,), p.dtype), -1) + A[0,:] = -p[1:] / p[0] + roots = eigvals(A) + else: + roots = NX.array([]) + + # tack any zeros onto the back of the array + roots = hstack((roots, NX.zeros(trailing_zeros, roots.dtype))) + return roots + + +def _polyint_dispatcher(p, m=None, k=None): + return (p,) + + +@array_function_dispatch(_polyint_dispatcher) +def polyint(p, m=1, k=None): + """ + Return an antiderivative (indefinite integral) of a polynomial. + + .. note:: + This forms part of the old polynomial API. Since version 1.4, the + new polynomial API defined in `numpy.polynomial` is preferred. + A summary of the differences can be found in the + :doc:`transition guide `. + + The returned order `m` antiderivative `P` of polynomial `p` satisfies + :math:`\\frac{d^m}{dx^m}P(x) = p(x)` and is defined up to `m - 1` + integration constants `k`. The constants determine the low-order + polynomial part + + .. math:: \\frac{k_{m-1}}{0!} x^0 + \\ldots + \\frac{k_0}{(m-1)!}x^{m-1} + + of `P` so that :math:`P^{(j)}(0) = k_{m-j-1}`. + + Parameters + ---------- + p : array_like or poly1d + Polynomial to integrate. + A sequence is interpreted as polynomial coefficients, see `poly1d`. + m : int, optional + Order of the antiderivative. (Default: 1) + k : list of `m` scalars or scalar, optional + Integration constants. They are given in the order of integration: + those corresponding to highest-order terms come first. + + If ``None`` (default), all constants are assumed to be zero. + If `m = 1`, a single scalar can be given instead of a list. + + See Also + -------- + polyder : derivative of a polynomial + poly1d.integ : equivalent method + + Examples + -------- + The defining property of the antiderivative: + + >>> p = np.poly1d([1,1,1]) + >>> P = np.polyint(p) + >>> P + poly1d([ 0.33333333, 0.5 , 1. , 0. ]) # may vary + >>> np.polyder(P) == p + True + + The integration constants default to zero, but can be specified: + + >>> P = np.polyint(p, 3) + >>> P(0) + 0.0 + >>> np.polyder(P)(0) + 0.0 + >>> np.polyder(P, 2)(0) + 0.0 + >>> P = np.polyint(p, 3, k=[6,5,3]) + >>> P + poly1d([ 0.01666667, 0.04166667, 0.16666667, 3. , 5. , 3. ]) # may vary + + Note that 3 = 6 / 2!, and that the constants are given in the order of + integrations. Constant of the highest-order polynomial term comes first: + + >>> np.polyder(P, 2)(0) + 6.0 + >>> np.polyder(P, 1)(0) + 5.0 + >>> P(0) + 3.0 + + """ + m = int(m) + if m < 0: + raise ValueError("Order of integral must be positive (see polyder)") + if k is None: + k = NX.zeros(m, float) + k = atleast_1d(k) + if len(k) == 1 and m > 1: + k = k[0]*NX.ones(m, float) + if len(k) < m: + raise ValueError( + "k must be a scalar or a rank-1 array of length 1 or >m.") + + truepoly = isinstance(p, poly1d) + p = NX.asarray(p) + if m == 0: + if truepoly: + return poly1d(p) + return p + else: + # Note: this must work also with object and integer arrays + y = NX.concatenate((p.__truediv__(NX.arange(len(p), 0, -1)), [k[0]])) + val = polyint(y, m - 1, k=k[1:]) + if truepoly: + return poly1d(val) + return val + + +def _polyder_dispatcher(p, m=None): + return (p,) + + +@array_function_dispatch(_polyder_dispatcher) +def polyder(p, m=1): + """ + Return the derivative of the specified order of a polynomial. + + .. note:: + This forms part of the old polynomial API. Since version 1.4, the + new polynomial API defined in `numpy.polynomial` is preferred. + A summary of the differences can be found in the + :doc:`transition guide `. + + Parameters + ---------- + p : poly1d or sequence + Polynomial to differentiate. + A sequence is interpreted as polynomial coefficients, see `poly1d`. + m : int, optional + Order of differentiation (default: 1) + + Returns + ------- + der : poly1d + A new polynomial representing the derivative. + + See Also + -------- + polyint : Anti-derivative of a polynomial. + poly1d : Class for one-dimensional polynomials. + + Examples + -------- + The derivative of the polynomial :math:`x^3 + x^2 + x^1 + 1` is: + + >>> p = np.poly1d([1,1,1,1]) + >>> p2 = np.polyder(p) + >>> p2 + poly1d([3, 2, 1]) + + which evaluates to: + + >>> p2(2.) + 17.0 + + We can verify this, approximating the derivative with + ``(f(x + h) - f(x))/h``: + + >>> (p(2. + 0.001) - p(2.)) / 0.001 + 17.007000999997857 + + The fourth-order derivative of a 3rd-order polynomial is zero: + + >>> np.polyder(p, 2) + poly1d([6, 2]) + >>> np.polyder(p, 3) + poly1d([6]) + >>> np.polyder(p, 4) + poly1d([0]) + + """ + m = int(m) + if m < 0: + raise ValueError("Order of derivative must be positive (see polyint)") + + truepoly = isinstance(p, poly1d) + p = NX.asarray(p) + n = len(p) - 1 + y = p[:-1] * NX.arange(n, 0, -1) + if m == 0: + val = p + else: + val = polyder(y, m - 1) + if truepoly: + val = poly1d(val) + return val + + +def _polyfit_dispatcher(x, y, deg, rcond=None, full=None, w=None, cov=None): + return (x, y, w) + + +@array_function_dispatch(_polyfit_dispatcher) +def polyfit(x, y, deg, rcond=None, full=False, w=None, cov=False): + """ + Least squares polynomial fit. + + .. note:: + This forms part of the old polynomial API. Since version 1.4, the + new polynomial API defined in `numpy.polynomial` is preferred. + A summary of the differences can be found in the + :doc:`transition guide `. + + Fit a polynomial ``p(x) = p[0] * x**deg + ... + p[deg]`` of degree `deg` + to points `(x, y)`. Returns a vector of coefficients `p` that minimises + the squared error in the order `deg`, `deg-1`, ... `0`. + + The `Polynomial.fit ` class + method is recommended for new code as it is more stable numerically. See + the documentation of the method for more information. + + Parameters + ---------- + x : array_like, shape (M,) + x-coordinates of the M sample points ``(x[i], y[i])``. + y : array_like, shape (M,) or (M, K) + y-coordinates of the sample points. Several data sets of sample + points sharing the same x-coordinates can be fitted at once by + passing in a 2D-array that contains one dataset per column. + deg : int + Degree of the fitting polynomial + rcond : float, optional + Relative condition number of the fit. Singular values smaller than + this relative to the largest singular value will be ignored. The + default value is len(x)*eps, where eps is the relative precision of + the float type, about 2e-16 in most cases. + full : bool, optional + Switch determining nature of return value. When it is False (the + default) just the coefficients are returned, when True diagnostic + information from the singular value decomposition is also returned. + w : array_like, shape (M,), optional + Weights to apply to the y-coordinates of the sample points. For + gaussian uncertainties, use 1/sigma (not 1/sigma**2). + cov : bool or str, optional + If given and not `False`, return not just the estimate but also its + covariance matrix. By default, the covariance are scaled by + chi2/dof, where dof = M - (deg + 1), i.e., the weights are presumed + to be unreliable except in a relative sense and everything is scaled + such that the reduced chi2 is unity. This scaling is omitted if + ``cov='unscaled'``, as is relevant for the case that the weights are + 1/sigma**2, with sigma known to be a reliable estimate of the + uncertainty. + + Returns + ------- + p : ndarray, shape (deg + 1,) or (deg + 1, K) + Polynomial coefficients, highest power first. If `y` was 2-D, the + coefficients for `k`-th data set are in ``p[:,k]``. + + residuals, rank, singular_values, rcond + Present only if `full` = True. Residuals is sum of squared residuals + of the least-squares fit, the effective rank of the scaled Vandermonde + coefficient matrix, its singular values, and the specified value of + `rcond`. For more details, see `linalg.lstsq`. + + V : ndarray, shape (M,M) or (M,M,K) + Present only if `full` = False and `cov`=True. The covariance + matrix of the polynomial coefficient estimates. The diagonal of + this matrix are the variance estimates for each coefficient. If y + is a 2-D array, then the covariance matrix for the `k`-th data set + are in ``V[:,:,k]`` + + + Warns + ----- + RankWarning + The rank of the coefficient matrix in the least-squares fit is + deficient. The warning is only raised if `full` = False. + + The warnings can be turned off by + + >>> import warnings + >>> warnings.simplefilter('ignore', np.RankWarning) + + See Also + -------- + polyval : Compute polynomial values. + linalg.lstsq : Computes a least-squares fit. + scipy.interpolate.UnivariateSpline : Computes spline fits. + + Notes + ----- + The solution minimizes the squared error + + .. math :: + E = \\sum_{j=0}^k |p(x_j) - y_j|^2 + + in the equations:: + + x[0]**n * p[0] + ... + x[0] * p[n-1] + p[n] = y[0] + x[1]**n * p[0] + ... + x[1] * p[n-1] + p[n] = y[1] + ... + x[k]**n * p[0] + ... + x[k] * p[n-1] + p[n] = y[k] + + The coefficient matrix of the coefficients `p` is a Vandermonde matrix. + + `polyfit` issues a `RankWarning` when the least-squares fit is badly + conditioned. This implies that the best fit is not well-defined due + to numerical error. The results may be improved by lowering the polynomial + degree or by replacing `x` by `x` - `x`.mean(). The `rcond` parameter + can also be set to a value smaller than its default, but the resulting + fit may be spurious: including contributions from the small singular + values can add numerical noise to the result. + + Note that fitting polynomial coefficients is inherently badly conditioned + when the degree of the polynomial is large or the interval of sample points + is badly centered. The quality of the fit should always be checked in these + cases. When polynomial fits are not satisfactory, splines may be a good + alternative. + + References + ---------- + .. [1] Wikipedia, "Curve fitting", + https://en.wikipedia.org/wiki/Curve_fitting + .. [2] Wikipedia, "Polynomial interpolation", + https://en.wikipedia.org/wiki/Polynomial_interpolation + + Examples + -------- + >>> import warnings + >>> x = np.array([0.0, 1.0, 2.0, 3.0, 4.0, 5.0]) + >>> y = np.array([0.0, 0.8, 0.9, 0.1, -0.8, -1.0]) + >>> z = np.polyfit(x, y, 3) + >>> z + array([ 0.08703704, -0.81349206, 1.69312169, -0.03968254]) # may vary + + It is convenient to use `poly1d` objects for dealing with polynomials: + + >>> p = np.poly1d(z) + >>> p(0.5) + 0.6143849206349179 # may vary + >>> p(3.5) + -0.34732142857143039 # may vary + >>> p(10) + 22.579365079365115 # may vary + + High-order polynomials may oscillate wildly: + + >>> with warnings.catch_warnings(): + ... warnings.simplefilter('ignore', np.RankWarning) + ... p30 = np.poly1d(np.polyfit(x, y, 30)) + ... + >>> p30(4) + -0.80000000000000204 # may vary + >>> p30(5) + -0.99999999999999445 # may vary + >>> p30(4.5) + -0.10547061179440398 # may vary + + Illustration: + + >>> import matplotlib.pyplot as plt + >>> xp = np.linspace(-2, 6, 100) + >>> _ = plt.plot(x, y, '.', xp, p(xp), '-', xp, p30(xp), '--') + >>> plt.ylim(-2,2) + (-2, 2) + >>> plt.show() + + """ + order = int(deg) + 1 + x = NX.asarray(x) + 0.0 + y = NX.asarray(y) + 0.0 + + # check arguments. + if deg < 0: + raise ValueError("expected deg >= 0") + if x.ndim != 1: + raise TypeError("expected 1D vector for x") + if x.size == 0: + raise TypeError("expected non-empty vector for x") + if y.ndim < 1 or y.ndim > 2: + raise TypeError("expected 1D or 2D array for y") + if x.shape[0] != y.shape[0]: + raise TypeError("expected x and y to have same length") + + # set rcond + if rcond is None: + rcond = len(x)*finfo(x.dtype).eps + + # set up least squares equation for powers of x + lhs = vander(x, order) + rhs = y + + # apply weighting + if w is not None: + w = NX.asarray(w) + 0.0 + if w.ndim != 1: + raise TypeError("expected a 1-d array for weights") + if w.shape[0] != y.shape[0]: + raise TypeError("expected w and y to have the same length") + lhs *= w[:, NX.newaxis] + if rhs.ndim == 2: + rhs *= w[:, NX.newaxis] + else: + rhs *= w + + # scale lhs to improve condition number and solve + scale = NX.sqrt((lhs*lhs).sum(axis=0)) + lhs /= scale + c, resids, rank, s = lstsq(lhs, rhs, rcond) + c = (c.T/scale).T # broadcast scale coefficients + + # warn on rank reduction, which indicates an ill conditioned matrix + if rank != order and not full: + msg = "Polyfit may be poorly conditioned" + warnings.warn(msg, RankWarning, stacklevel=4) + + if full: + return c, resids, rank, s, rcond + elif cov: + Vbase = inv(dot(lhs.T, lhs)) + Vbase /= NX.outer(scale, scale) + if cov == "unscaled": + fac = 1 + else: + if len(x) <= order: + raise ValueError("the number of data points must exceed order " + "to scale the covariance matrix") + # note, this used to be: fac = resids / (len(x) - order - 2.0) + # it was deciced that the "- 2" (originally justified by "Bayesian + # uncertainty analysis") is not was the user expects + # (see gh-11196 and gh-11197) + fac = resids / (len(x) - order) + if y.ndim == 1: + return c, Vbase * fac + else: + return c, Vbase[:,:, NX.newaxis] * fac + else: + return c + + +def _polyval_dispatcher(p, x): + return (p, x) + + +@array_function_dispatch(_polyval_dispatcher) +def polyval(p, x): + """ + Evaluate a polynomial at specific values. + + .. note:: + This forms part of the old polynomial API. Since version 1.4, the + new polynomial API defined in `numpy.polynomial` is preferred. + A summary of the differences can be found in the + :doc:`transition guide `. + + If `p` is of length N, this function returns the value: + + ``p[0]*x**(N-1) + p[1]*x**(N-2) + ... + p[N-2]*x + p[N-1]`` + + If `x` is a sequence, then `p(x)` is returned for each element of `x`. + If `x` is another polynomial then the composite polynomial `p(x(t))` + is returned. + + Parameters + ---------- + p : array_like or poly1d object + 1D array of polynomial coefficients (including coefficients equal + to zero) from highest degree to the constant term, or an + instance of poly1d. + x : array_like or poly1d object + A number, an array of numbers, or an instance of poly1d, at + which to evaluate `p`. + + Returns + ------- + values : ndarray or poly1d + If `x` is a poly1d instance, the result is the composition of the two + polynomials, i.e., `x` is "substituted" in `p` and the simplified + result is returned. In addition, the type of `x` - array_like or + poly1d - governs the type of the output: `x` array_like => `values` + array_like, `x` a poly1d object => `values` is also. + + See Also + -------- + poly1d: A polynomial class. + + Notes + ----- + Horner's scheme [1]_ is used to evaluate the polynomial. Even so, + for polynomials of high degree the values may be inaccurate due to + rounding errors. Use carefully. + + If `x` is a subtype of `ndarray` the return value will be of the same type. + + References + ---------- + .. [1] I. N. Bronshtein, K. A. Semendyayev, and K. A. Hirsch (Eng. + trans. Ed.), *Handbook of Mathematics*, New York, Van Nostrand + Reinhold Co., 1985, pg. 720. + + Examples + -------- + >>> np.polyval([3,0,1], 5) # 3 * 5**2 + 0 * 5**1 + 1 + 76 + >>> np.polyval([3,0,1], np.poly1d(5)) + poly1d([76]) + >>> np.polyval(np.poly1d([3,0,1]), 5) + 76 + >>> np.polyval(np.poly1d([3,0,1]), np.poly1d(5)) + poly1d([76]) + + """ + p = NX.asarray(p) + if isinstance(x, poly1d): + y = 0 + else: + x = NX.asanyarray(x) + y = NX.zeros_like(x) + for i in range(len(p)): + y = y * x + p[i] + return y + + +def _binary_op_dispatcher(a1, a2): + return (a1, a2) + + +@array_function_dispatch(_binary_op_dispatcher) +def polyadd(a1, a2): + """ + Find the sum of two polynomials. + + .. note:: + This forms part of the old polynomial API. Since version 1.4, the + new polynomial API defined in `numpy.polynomial` is preferred. + A summary of the differences can be found in the + :doc:`transition guide `. + + Returns the polynomial resulting from the sum of two input polynomials. + Each input must be either a poly1d object or a 1D sequence of polynomial + coefficients, from highest to lowest degree. + + Parameters + ---------- + a1, a2 : array_like or poly1d object + Input polynomials. + + Returns + ------- + out : ndarray or poly1d object + The sum of the inputs. If either input is a poly1d object, then the + output is also a poly1d object. Otherwise, it is a 1D array of + polynomial coefficients from highest to lowest degree. + + See Also + -------- + poly1d : A one-dimensional polynomial class. + poly, polyadd, polyder, polydiv, polyfit, polyint, polysub, polyval + + Examples + -------- + >>> np.polyadd([1, 2], [9, 5, 4]) + array([9, 6, 6]) + + Using poly1d objects: + + >>> p1 = np.poly1d([1, 2]) + >>> p2 = np.poly1d([9, 5, 4]) + >>> print(p1) + 1 x + 2 + >>> print(p2) + 2 + 9 x + 5 x + 4 + >>> print(np.polyadd(p1, p2)) + 2 + 9 x + 6 x + 6 + + """ + truepoly = (isinstance(a1, poly1d) or isinstance(a2, poly1d)) + a1 = atleast_1d(a1) + a2 = atleast_1d(a2) + diff = len(a2) - len(a1) + if diff == 0: + val = a1 + a2 + elif diff > 0: + zr = NX.zeros(diff, a1.dtype) + val = NX.concatenate((zr, a1)) + a2 + else: + zr = NX.zeros(abs(diff), a2.dtype) + val = a1 + NX.concatenate((zr, a2)) + if truepoly: + val = poly1d(val) + return val + + +@array_function_dispatch(_binary_op_dispatcher) +def polysub(a1, a2): + """ + Difference (subtraction) of two polynomials. + + .. note:: + This forms part of the old polynomial API. Since version 1.4, the + new polynomial API defined in `numpy.polynomial` is preferred. + A summary of the differences can be found in the + :doc:`transition guide `. + + Given two polynomials `a1` and `a2`, returns ``a1 - a2``. + `a1` and `a2` can be either array_like sequences of the polynomials' + coefficients (including coefficients equal to zero), or `poly1d` objects. + + Parameters + ---------- + a1, a2 : array_like or poly1d + Minuend and subtrahend polynomials, respectively. + + Returns + ------- + out : ndarray or poly1d + Array or `poly1d` object of the difference polynomial's coefficients. + + See Also + -------- + polyval, polydiv, polymul, polyadd + + Examples + -------- + .. math:: (2 x^2 + 10 x - 2) - (3 x^2 + 10 x -4) = (-x^2 + 2) + + >>> np.polysub([2, 10, -2], [3, 10, -4]) + array([-1, 0, 2]) + + """ + truepoly = (isinstance(a1, poly1d) or isinstance(a2, poly1d)) + a1 = atleast_1d(a1) + a2 = atleast_1d(a2) + diff = len(a2) - len(a1) + if diff == 0: + val = a1 - a2 + elif diff > 0: + zr = NX.zeros(diff, a1.dtype) + val = NX.concatenate((zr, a1)) - a2 + else: + zr = NX.zeros(abs(diff), a2.dtype) + val = a1 - NX.concatenate((zr, a2)) + if truepoly: + val = poly1d(val) + return val + + +@array_function_dispatch(_binary_op_dispatcher) +def polymul(a1, a2): + """ + Find the product of two polynomials. + + .. note:: + This forms part of the old polynomial API. Since version 1.4, the + new polynomial API defined in `numpy.polynomial` is preferred. + A summary of the differences can be found in the + :doc:`transition guide `. + + Finds the polynomial resulting from the multiplication of the two input + polynomials. Each input must be either a poly1d object or a 1D sequence + of polynomial coefficients, from highest to lowest degree. + + Parameters + ---------- + a1, a2 : array_like or poly1d object + Input polynomials. + + Returns + ------- + out : ndarray or poly1d object + The polynomial resulting from the multiplication of the inputs. If + either inputs is a poly1d object, then the output is also a poly1d + object. Otherwise, it is a 1D array of polynomial coefficients from + highest to lowest degree. + + See Also + -------- + poly1d : A one-dimensional polynomial class. + poly, polyadd, polyder, polydiv, polyfit, polyint, polysub, polyval + convolve : Array convolution. Same output as polymul, but has parameter + for overlap mode. + + Examples + -------- + >>> np.polymul([1, 2, 3], [9, 5, 1]) + array([ 9, 23, 38, 17, 3]) + + Using poly1d objects: + + >>> p1 = np.poly1d([1, 2, 3]) + >>> p2 = np.poly1d([9, 5, 1]) + >>> print(p1) + 2 + 1 x + 2 x + 3 + >>> print(p2) + 2 + 9 x + 5 x + 1 + >>> print(np.polymul(p1, p2)) + 4 3 2 + 9 x + 23 x + 38 x + 17 x + 3 + + """ + truepoly = (isinstance(a1, poly1d) or isinstance(a2, poly1d)) + a1, a2 = poly1d(a1), poly1d(a2) + val = NX.convolve(a1, a2) + if truepoly: + val = poly1d(val) + return val + + +def _polydiv_dispatcher(u, v): + return (u, v) + + +@array_function_dispatch(_polydiv_dispatcher) +def polydiv(u, v): + """ + Returns the quotient and remainder of polynomial division. + + .. note:: + This forms part of the old polynomial API. Since version 1.4, the + new polynomial API defined in `numpy.polynomial` is preferred. + A summary of the differences can be found in the + :doc:`transition guide `. + + The input arrays are the coefficients (including any coefficients + equal to zero) of the "numerator" (dividend) and "denominator" + (divisor) polynomials, respectively. + + Parameters + ---------- + u : array_like or poly1d + Dividend polynomial's coefficients. + + v : array_like or poly1d + Divisor polynomial's coefficients. + + Returns + ------- + q : ndarray + Coefficients, including those equal to zero, of the quotient. + r : ndarray + Coefficients, including those equal to zero, of the remainder. + + See Also + -------- + poly, polyadd, polyder, polydiv, polyfit, polyint, polymul, polysub + polyval + + Notes + ----- + Both `u` and `v` must be 0-d or 1-d (ndim = 0 or 1), but `u.ndim` need + not equal `v.ndim`. In other words, all four possible combinations - + ``u.ndim = v.ndim = 0``, ``u.ndim = v.ndim = 1``, + ``u.ndim = 1, v.ndim = 0``, and ``u.ndim = 0, v.ndim = 1`` - work. + + Examples + -------- + .. math:: \\frac{3x^2 + 5x + 2}{2x + 1} = 1.5x + 1.75, remainder 0.25 + + >>> x = np.array([3.0, 5.0, 2.0]) + >>> y = np.array([2.0, 1.0]) + >>> np.polydiv(x, y) + (array([1.5 , 1.75]), array([0.25])) + + """ + truepoly = (isinstance(u, poly1d) or isinstance(v, poly1d)) + u = atleast_1d(u) + 0.0 + v = atleast_1d(v) + 0.0 + # w has the common type + w = u[0] + v[0] + m = len(u) - 1 + n = len(v) - 1 + scale = 1. / v[0] + q = NX.zeros((max(m - n + 1, 1),), w.dtype) + r = u.astype(w.dtype) + for k in range(0, m-n+1): + d = scale * r[k] + q[k] = d + r[k:k+n+1] -= d*v + while NX.allclose(r[0], 0, rtol=1e-14) and (r.shape[-1] > 1): + r = r[1:] + if truepoly: + return poly1d(q), poly1d(r) + return q, r + +_poly_mat = re.compile(r"[*][*]([0-9]*)") +def _raise_power(astr, wrap=70): + n = 0 + line1 = '' + line2 = '' + output = ' ' + while True: + mat = _poly_mat.search(astr, n) + if mat is None: + break + span = mat.span() + power = mat.groups()[0] + partstr = astr[n:span[0]] + n = span[1] + toadd2 = partstr + ' '*(len(power)-1) + toadd1 = ' '*(len(partstr)-1) + power + if ((len(line2) + len(toadd2) > wrap) or + (len(line1) + len(toadd1) > wrap)): + output += line1 + "\n" + line2 + "\n " + line1 = toadd1 + line2 = toadd2 + else: + line2 += partstr + ' '*(len(power)-1) + line1 += ' '*(len(partstr)-1) + power + output += line1 + "\n" + line2 + return output + astr[n:] + + +@set_module('numpy') +class poly1d: + """ + A one-dimensional polynomial class. + + .. note:: + This forms part of the old polynomial API. Since version 1.4, the + new polynomial API defined in `numpy.polynomial` is preferred. + A summary of the differences can be found in the + :doc:`transition guide `. + + A convenience class, used to encapsulate "natural" operations on + polynomials so that said operations may take on their customary + form in code (see Examples). + + Parameters + ---------- + c_or_r : array_like + The polynomial's coefficients, in decreasing powers, or if + the value of the second parameter is True, the polynomial's + roots (values where the polynomial evaluates to 0). For example, + ``poly1d([1, 2, 3])`` returns an object that represents + :math:`x^2 + 2x + 3`, whereas ``poly1d([1, 2, 3], True)`` returns + one that represents :math:`(x-1)(x-2)(x-3) = x^3 - 6x^2 + 11x -6`. + r : bool, optional + If True, `c_or_r` specifies the polynomial's roots; the default + is False. + variable : str, optional + Changes the variable used when printing `p` from `x` to `variable` + (see Examples). + + Examples + -------- + Construct the polynomial :math:`x^2 + 2x + 3`: + + >>> p = np.poly1d([1, 2, 3]) + >>> print(np.poly1d(p)) + 2 + 1 x + 2 x + 3 + + Evaluate the polynomial at :math:`x = 0.5`: + + >>> p(0.5) + 4.25 + + Find the roots: + + >>> p.r + array([-1.+1.41421356j, -1.-1.41421356j]) + >>> p(p.r) + array([ -4.44089210e-16+0.j, -4.44089210e-16+0.j]) # may vary + + These numbers in the previous line represent (0, 0) to machine precision + + Show the coefficients: + + >>> p.c + array([1, 2, 3]) + + Display the order (the leading zero-coefficients are removed): + + >>> p.order + 2 + + Show the coefficient of the k-th power in the polynomial + (which is equivalent to ``p.c[-(i+1)]``): + + >>> p[1] + 2 + + Polynomials can be added, subtracted, multiplied, and divided + (returns quotient and remainder): + + >>> p * p + poly1d([ 1, 4, 10, 12, 9]) + + >>> (p**3 + 4) / p + (poly1d([ 1., 4., 10., 12., 9.]), poly1d([4.])) + + ``asarray(p)`` gives the coefficient array, so polynomials can be + used in all functions that accept arrays: + + >>> p**2 # square of polynomial + poly1d([ 1, 4, 10, 12, 9]) + + >>> np.square(p) # square of individual coefficients + array([1, 4, 9]) + + The variable used in the string representation of `p` can be modified, + using the `variable` parameter: + + >>> p = np.poly1d([1,2,3], variable='z') + >>> print(p) + 2 + 1 z + 2 z + 3 + + Construct a polynomial from its roots: + + >>> np.poly1d([1, 2], True) + poly1d([ 1., -3., 2.]) + + This is the same polynomial as obtained by: + + >>> np.poly1d([1, -1]) * np.poly1d([1, -2]) + poly1d([ 1, -3, 2]) + + """ + __hash__ = None + + @property + def coeffs(self): + """ The polynomial coefficients """ + return self._coeffs + + @coeffs.setter + def coeffs(self, value): + # allowing this makes p.coeffs *= 2 legal + if value is not self._coeffs: + raise AttributeError("Cannot set attribute") + + @property + def variable(self): + """ The name of the polynomial variable """ + return self._variable + + # calculated attributes + @property + def order(self): + """ The order or degree of the polynomial """ + return len(self._coeffs) - 1 + + @property + def roots(self): + """ The roots of the polynomial, where self(x) == 0 """ + return roots(self._coeffs) + + # our internal _coeffs property need to be backed by __dict__['coeffs'] for + # scipy to work correctly. + @property + def _coeffs(self): + return self.__dict__['coeffs'] + @_coeffs.setter + def _coeffs(self, coeffs): + self.__dict__['coeffs'] = coeffs + + # alias attributes + r = roots + c = coef = coefficients = coeffs + o = order + + def __init__(self, c_or_r, r=False, variable=None): + if isinstance(c_or_r, poly1d): + self._variable = c_or_r._variable + self._coeffs = c_or_r._coeffs + + if set(c_or_r.__dict__) - set(self.__dict__): + msg = ("In the future extra properties will not be copied " + "across when constructing one poly1d from another") + warnings.warn(msg, FutureWarning, stacklevel=2) + self.__dict__.update(c_or_r.__dict__) + + if variable is not None: + self._variable = variable + return + if r: + c_or_r = poly(c_or_r) + c_or_r = atleast_1d(c_or_r) + if c_or_r.ndim > 1: + raise ValueError("Polynomial must be 1d only.") + c_or_r = trim_zeros(c_or_r, trim='f') + if len(c_or_r) == 0: + c_or_r = NX.array([0], dtype=c_or_r.dtype) + self._coeffs = c_or_r + if variable is None: + variable = 'x' + self._variable = variable + + def __array__(self, t=None): + if t: + return NX.asarray(self.coeffs, t) + else: + return NX.asarray(self.coeffs) + + def __repr__(self): + vals = repr(self.coeffs) + vals = vals[6:-1] + return "poly1d(%s)" % vals + + def __len__(self): + return self.order + + def __str__(self): + thestr = "0" + var = self.variable + + # Remove leading zeros + coeffs = self.coeffs[NX.logical_or.accumulate(self.coeffs != 0)] + N = len(coeffs)-1 + + def fmt_float(q): + s = '%.4g' % q + if s.endswith('.0000'): + s = s[:-5] + return s + + for k in range(len(coeffs)): + if not iscomplex(coeffs[k]): + coefstr = fmt_float(real(coeffs[k])) + elif real(coeffs[k]) == 0: + coefstr = '%sj' % fmt_float(imag(coeffs[k])) + else: + coefstr = '(%s + %sj)' % (fmt_float(real(coeffs[k])), + fmt_float(imag(coeffs[k]))) + + power = (N-k) + if power == 0: + if coefstr != '0': + newstr = '%s' % (coefstr,) + else: + if k == 0: + newstr = '0' + else: + newstr = '' + elif power == 1: + if coefstr == '0': + newstr = '' + elif coefstr == 'b': + newstr = var + else: + newstr = '%s %s' % (coefstr, var) + else: + if coefstr == '0': + newstr = '' + elif coefstr == 'b': + newstr = '%s**%d' % (var, power,) + else: + newstr = '%s %s**%d' % (coefstr, var, power) + + if k > 0: + if newstr != '': + if newstr.startswith('-'): + thestr = "%s - %s" % (thestr, newstr[1:]) + else: + thestr = "%s + %s" % (thestr, newstr) + else: + thestr = newstr + return _raise_power(thestr) + + def __call__(self, val): + return polyval(self.coeffs, val) + + def __neg__(self): + return poly1d(-self.coeffs) + + def __pos__(self): + return self + + def __mul__(self, other): + if isscalar(other): + return poly1d(self.coeffs * other) + else: + other = poly1d(other) + return poly1d(polymul(self.coeffs, other.coeffs)) + + def __rmul__(self, other): + if isscalar(other): + return poly1d(other * self.coeffs) + else: + other = poly1d(other) + return poly1d(polymul(self.coeffs, other.coeffs)) + + def __add__(self, other): + other = poly1d(other) + return poly1d(polyadd(self.coeffs, other.coeffs)) + + def __radd__(self, other): + other = poly1d(other) + return poly1d(polyadd(self.coeffs, other.coeffs)) + + def __pow__(self, val): + if not isscalar(val) or int(val) != val or val < 0: + raise ValueError("Power to non-negative integers only.") + res = [1] + for _ in range(val): + res = polymul(self.coeffs, res) + return poly1d(res) + + def __sub__(self, other): + other = poly1d(other) + return poly1d(polysub(self.coeffs, other.coeffs)) + + def __rsub__(self, other): + other = poly1d(other) + return poly1d(polysub(other.coeffs, self.coeffs)) + + def __div__(self, other): + if isscalar(other): + return poly1d(self.coeffs/other) + else: + other = poly1d(other) + return polydiv(self, other) + + __truediv__ = __div__ + + def __rdiv__(self, other): + if isscalar(other): + return poly1d(other/self.coeffs) + else: + other = poly1d(other) + return polydiv(other, self) + + __rtruediv__ = __rdiv__ + + def __eq__(self, other): + if not isinstance(other, poly1d): + return NotImplemented + if self.coeffs.shape != other.coeffs.shape: + return False + return (self.coeffs == other.coeffs).all() + + def __ne__(self, other): + if not isinstance(other, poly1d): + return NotImplemented + return not self.__eq__(other) + + + def __getitem__(self, val): + ind = self.order - val + if val > self.order: + return 0 + if val < 0: + return 0 + return self.coeffs[ind] + + def __setitem__(self, key, val): + ind = self.order - key + if key < 0: + raise ValueError("Does not support negative powers.") + if key > self.order: + zr = NX.zeros(key-self.order, self.coeffs.dtype) + self._coeffs = NX.concatenate((zr, self.coeffs)) + ind = 0 + self._coeffs[ind] = val + return + + def __iter__(self): + return iter(self.coeffs) + + def integ(self, m=1, k=0): + """ + Return an antiderivative (indefinite integral) of this polynomial. + + Refer to `polyint` for full documentation. + + See Also + -------- + polyint : equivalent function + + """ + return poly1d(polyint(self.coeffs, m=m, k=k)) + + def deriv(self, m=1): + """ + Return a derivative of this polynomial. + + Refer to `polyder` for full documentation. + + See Also + -------- + polyder : equivalent function + + """ + return poly1d(polyder(self.coeffs, m=m)) + +# Stuff to do on module import + +warnings.simplefilter('always', RankWarning) diff --git a/venv/Lib/site-packages/numpy/lib/recfunctions.py b/venv/Lib/site-packages/numpy/lib/recfunctions.py new file mode 100644 index 0000000..fbfbca7 --- /dev/null +++ b/venv/Lib/site-packages/numpy/lib/recfunctions.py @@ -0,0 +1,1594 @@ +""" +Collection of utilities to manipulate structured arrays. + +Most of these functions were initially implemented by John Hunter for +matplotlib. They have been rewritten and extended for convenience. + +""" +import itertools +import numpy as np +import numpy.ma as ma +from numpy import ndarray, recarray +from numpy.ma import MaskedArray +from numpy.ma.mrecords import MaskedRecords +from numpy.core.overrides import array_function_dispatch +from numpy.lib._iotools import _is_string_like +from numpy.testing import suppress_warnings + +_check_fill_value = np.ma.core._check_fill_value + + +__all__ = [ + 'append_fields', 'apply_along_fields', 'assign_fields_by_name', + 'drop_fields', 'find_duplicates', 'flatten_descr', + 'get_fieldstructure', 'get_names', 'get_names_flat', + 'join_by', 'merge_arrays', 'rec_append_fields', + 'rec_drop_fields', 'rec_join', 'recursive_fill_fields', + 'rename_fields', 'repack_fields', 'require_fields', + 'stack_arrays', 'structured_to_unstructured', 'unstructured_to_structured', + ] + + +def _recursive_fill_fields_dispatcher(input, output): + return (input, output) + + +@array_function_dispatch(_recursive_fill_fields_dispatcher) +def recursive_fill_fields(input, output): + """ + Fills fields from output with fields from input, + with support for nested structures. + + Parameters + ---------- + input : ndarray + Input array. + output : ndarray + Output array. + + Notes + ----- + * `output` should be at least the same size as `input` + + Examples + -------- + >>> from numpy.lib import recfunctions as rfn + >>> a = np.array([(1, 10.), (2, 20.)], dtype=[('A', np.int64), ('B', np.float64)]) + >>> b = np.zeros((3,), dtype=a.dtype) + >>> rfn.recursive_fill_fields(a, b) + array([(1, 10.), (2, 20.), (0, 0.)], dtype=[('A', '>> dt = np.dtype([(('a', 'A'), np.int64), ('b', np.double, 3)]) + >>> dt.descr + [(('a', 'A'), '>> _get_fieldspec(dt) + [(('a', 'A'), dtype('int64')), ('b', dtype(('>> from numpy.lib import recfunctions as rfn + >>> rfn.get_names(np.empty((1,), dtype=int)) + Traceback (most recent call last): + ... + AttributeError: 'numpy.ndarray' object has no attribute 'names' + + >>> rfn.get_names(np.empty((1,), dtype=[('A',int), ('B', float)])) + Traceback (most recent call last): + ... + AttributeError: 'numpy.ndarray' object has no attribute 'names' + >>> adtype = np.dtype([('a', int), ('b', [('ba', int), ('bb', int)])]) + >>> rfn.get_names(adtype) + ('a', ('b', ('ba', 'bb'))) + """ + listnames = [] + names = adtype.names + for name in names: + current = adtype[name] + if current.names is not None: + listnames.append((name, tuple(get_names(current)))) + else: + listnames.append(name) + return tuple(listnames) + + +def get_names_flat(adtype): + """ + Returns the field names of the input datatype as a tuple. Nested structure + are flattened beforehand. + + Parameters + ---------- + adtype : dtype + Input datatype + + Examples + -------- + >>> from numpy.lib import recfunctions as rfn + >>> rfn.get_names_flat(np.empty((1,), dtype=int)) is None + Traceback (most recent call last): + ... + AttributeError: 'numpy.ndarray' object has no attribute 'names' + >>> rfn.get_names_flat(np.empty((1,), dtype=[('A',int), ('B', float)])) + Traceback (most recent call last): + ... + AttributeError: 'numpy.ndarray' object has no attribute 'names' + >>> adtype = np.dtype([('a', int), ('b', [('ba', int), ('bb', int)])]) + >>> rfn.get_names_flat(adtype) + ('a', 'b', 'ba', 'bb') + """ + listnames = [] + names = adtype.names + for name in names: + listnames.append(name) + current = adtype[name] + if current.names is not None: + listnames.extend(get_names_flat(current)) + return tuple(listnames) + + +def flatten_descr(ndtype): + """ + Flatten a structured data-type description. + + Examples + -------- + >>> from numpy.lib import recfunctions as rfn + >>> ndtype = np.dtype([('a', '>> rfn.flatten_descr(ndtype) + (('a', dtype('int32')), ('ba', dtype('float64')), ('bb', dtype('int32'))) + + """ + names = ndtype.names + if names is None: + return (('', ndtype),) + else: + descr = [] + for field in names: + (typ, _) = ndtype.fields[field] + if typ.names is not None: + descr.extend(flatten_descr(typ)) + else: + descr.append((field, typ)) + return tuple(descr) + + +def _zip_dtype(seqarrays, flatten=False): + newdtype = [] + if flatten: + for a in seqarrays: + newdtype.extend(flatten_descr(a.dtype)) + else: + for a in seqarrays: + current = a.dtype + if current.names is not None and len(current.names) == 1: + # special case - dtypes of 1 field are flattened + newdtype.extend(_get_fieldspec(current)) + else: + newdtype.append(('', current)) + return np.dtype(newdtype) + + +def _zip_descr(seqarrays, flatten=False): + """ + Combine the dtype description of a series of arrays. + + Parameters + ---------- + seqarrays : sequence of arrays + Sequence of arrays + flatten : {boolean}, optional + Whether to collapse nested descriptions. + """ + return _zip_dtype(seqarrays, flatten=flatten).descr + + +def get_fieldstructure(adtype, lastname=None, parents=None,): + """ + Returns a dictionary with fields indexing lists of their parent fields. + + This function is used to simplify access to fields nested in other fields. + + Parameters + ---------- + adtype : np.dtype + Input datatype + lastname : optional + Last processed field name (used internally during recursion). + parents : dictionary + Dictionary of parent fields (used interbally during recursion). + + Examples + -------- + >>> from numpy.lib import recfunctions as rfn + >>> ndtype = np.dtype([('A', int), + ... ('B', [('BA', int), + ... ('BB', [('BBA', int), ('BBB', int)])])]) + >>> rfn.get_fieldstructure(ndtype) + ... # XXX: possible regression, order of BBA and BBB is swapped + {'A': [], 'B': [], 'BA': ['B'], 'BB': ['B'], 'BBA': ['B', 'BB'], 'BBB': ['B', 'BB']} + + """ + if parents is None: + parents = {} + names = adtype.names + for name in names: + current = adtype[name] + if current.names is not None: + if lastname: + parents[name] = [lastname, ] + else: + parents[name] = [] + parents.update(get_fieldstructure(current, name, parents)) + else: + lastparent = [_ for _ in (parents.get(lastname, []) or [])] + if lastparent: + lastparent.append(lastname) + elif lastname: + lastparent = [lastname, ] + parents[name] = lastparent or [] + return parents + + +def _izip_fields_flat(iterable): + """ + Returns an iterator of concatenated fields from a sequence of arrays, + collapsing any nested structure. + + """ + for element in iterable: + if isinstance(element, np.void): + yield from _izip_fields_flat(tuple(element)) + else: + yield element + + +def _izip_fields(iterable): + """ + Returns an iterator of concatenated fields from a sequence of arrays. + + """ + for element in iterable: + if (hasattr(element, '__iter__') and + not isinstance(element, str)): + yield from _izip_fields(element) + elif isinstance(element, np.void) and len(tuple(element)) == 1: + # this statement is the same from the previous expression + yield from _izip_fields(element) + else: + yield element + + +def _izip_records(seqarrays, fill_value=None, flatten=True): + """ + Returns an iterator of concatenated items from a sequence of arrays. + + Parameters + ---------- + seqarrays : sequence of arrays + Sequence of arrays. + fill_value : {None, integer} + Value used to pad shorter iterables. + flatten : {True, False}, + Whether to + """ + + # Should we flatten the items, or just use a nested approach + if flatten: + zipfunc = _izip_fields_flat + else: + zipfunc = _izip_fields + + for tup in itertools.zip_longest(*seqarrays, fillvalue=fill_value): + yield tuple(zipfunc(tup)) + + +def _fix_output(output, usemask=True, asrecarray=False): + """ + Private function: return a recarray, a ndarray, a MaskedArray + or a MaskedRecords depending on the input parameters + """ + if not isinstance(output, MaskedArray): + usemask = False + if usemask: + if asrecarray: + output = output.view(MaskedRecords) + else: + output = ma.filled(output) + if asrecarray: + output = output.view(recarray) + return output + + +def _fix_defaults(output, defaults=None): + """ + Update the fill_value and masked data of `output` + from the default given in a dictionary defaults. + """ + names = output.dtype.names + (data, mask, fill_value) = (output.data, output.mask, output.fill_value) + for (k, v) in (defaults or {}).items(): + if k in names: + fill_value[k] = v + data[k][mask[k]] = v + return output + + +def _merge_arrays_dispatcher(seqarrays, fill_value=None, flatten=None, + usemask=None, asrecarray=None): + return seqarrays + + +@array_function_dispatch(_merge_arrays_dispatcher) +def merge_arrays(seqarrays, fill_value=-1, flatten=False, + usemask=False, asrecarray=False): + """ + Merge arrays field by field. + + Parameters + ---------- + seqarrays : sequence of ndarrays + Sequence of arrays + fill_value : {float}, optional + Filling value used to pad missing data on the shorter arrays. + flatten : {False, True}, optional + Whether to collapse nested fields. + usemask : {False, True}, optional + Whether to return a masked array or not. + asrecarray : {False, True}, optional + Whether to return a recarray (MaskedRecords) or not. + + Examples + -------- + >>> from numpy.lib import recfunctions as rfn + >>> rfn.merge_arrays((np.array([1, 2]), np.array([10., 20., 30.]))) + array([( 1, 10.), ( 2, 20.), (-1, 30.)], + dtype=[('f0', '>> rfn.merge_arrays((np.array([1, 2], dtype=np.int64), + ... np.array([10., 20., 30.])), usemask=False) + array([(1, 10.0), (2, 20.0), (-1, 30.0)], + dtype=[('f0', '>> rfn.merge_arrays((np.array([1, 2]).view([('a', np.int64)]), + ... np.array([10., 20., 30.])), + ... usemask=False, asrecarray=True) + rec.array([( 1, 10.), ( 2, 20.), (-1, 30.)], + dtype=[('a', '>> from numpy.lib import recfunctions as rfn + >>> a = np.array([(1, (2, 3.0)), (4, (5, 6.0))], + ... dtype=[('a', np.int64), ('b', [('ba', np.double), ('bb', np.int64)])]) + >>> rfn.drop_fields(a, 'a') + array([((2., 3),), ((5., 6),)], + dtype=[('b', [('ba', '>> rfn.drop_fields(a, 'ba') + array([(1, (3,)), (4, (6,))], dtype=[('a', '>> rfn.drop_fields(a, ['ba', 'bb']) + array([(1,), (4,)], dtype=[('a', '>> from numpy.lib import recfunctions as rfn + >>> a = np.array([(1, (2, [3.0, 30.])), (4, (5, [6.0, 60.]))], + ... dtype=[('a', int),('b', [('ba', float), ('bb', (float, 2))])]) + >>> rfn.rename_fields(a, {'a':'A', 'bb':'BB'}) + array([(1, (2., [ 3., 30.])), (4, (5., [ 6., 60.]))], + dtype=[('A', ' 1: + data = merge_arrays(data, flatten=True, usemask=usemask, + fill_value=fill_value) + else: + data = data.pop() + # + output = ma.masked_all( + max(len(base), len(data)), + dtype=_get_fieldspec(base.dtype) + _get_fieldspec(data.dtype)) + output = recursive_fill_fields(base, output) + output = recursive_fill_fields(data, output) + # + return _fix_output(output, usemask=usemask, asrecarray=asrecarray) + + +def _rec_append_fields_dispatcher(base, names, data, dtypes=None): + yield base + yield from data + + +@array_function_dispatch(_rec_append_fields_dispatcher) +def rec_append_fields(base, names, data, dtypes=None): + """ + Add new fields to an existing array. + + The names of the fields are given with the `names` arguments, + the corresponding values with the `data` arguments. + If a single field is appended, `names`, `data` and `dtypes` do not have + to be lists but just values. + + Parameters + ---------- + base : array + Input array to extend. + names : string, sequence + String or sequence of strings corresponding to the names + of the new fields. + data : array or sequence of arrays + Array or sequence of arrays storing the fields to add to the base. + dtypes : sequence of datatypes, optional + Datatype or sequence of datatypes. + If None, the datatypes are estimated from the `data`. + + See Also + -------- + append_fields + + Returns + ------- + appended_array : np.recarray + """ + return append_fields(base, names, data=data, dtypes=dtypes, + asrecarray=True, usemask=False) + + +def _repack_fields_dispatcher(a, align=None, recurse=None): + return (a,) + + +@array_function_dispatch(_repack_fields_dispatcher) +def repack_fields(a, align=False, recurse=False): + """ + Re-pack the fields of a structured array or dtype in memory. + + The memory layout of structured datatypes allows fields at arbitrary + byte offsets. This means the fields can be separated by padding bytes, + their offsets can be non-monotonically increasing, and they can overlap. + + This method removes any overlaps and reorders the fields in memory so they + have increasing byte offsets, and adds or removes padding bytes depending + on the `align` option, which behaves like the `align` option to `np.dtype`. + + If `align=False`, this method produces a "packed" memory layout in which + each field starts at the byte the previous field ended, and any padding + bytes are removed. + + If `align=True`, this methods produces an "aligned" memory layout in which + each field's offset is a multiple of its alignment, and the total itemsize + is a multiple of the largest alignment, by adding padding bytes as needed. + + Parameters + ---------- + a : ndarray or dtype + array or dtype for which to repack the fields. + align : boolean + If true, use an "aligned" memory layout, otherwise use a "packed" layout. + recurse : boolean + If True, also repack nested structures. + + Returns + ------- + repacked : ndarray or dtype + Copy of `a` with fields repacked, or `a` itself if no repacking was + needed. + + Examples + -------- + + >>> from numpy.lib import recfunctions as rfn + >>> def print_offsets(d): + ... print("offsets:", [d.fields[name][1] for name in d.names]) + ... print("itemsize:", d.itemsize) + ... + >>> dt = np.dtype('u1, >> dt + dtype({'names':['f0','f1','f2'], 'formats':['u1','>> print_offsets(dt) + offsets: [0, 8, 16] + itemsize: 24 + >>> packed_dt = rfn.repack_fields(dt) + >>> packed_dt + dtype([('f0', 'u1'), ('f1', '>> print_offsets(packed_dt) + offsets: [0, 1, 9] + itemsize: 17 + + """ + if not isinstance(a, np.dtype): + dt = repack_fields(a.dtype, align=align, recurse=recurse) + return a.astype(dt, copy=False) + + if a.names is None: + return a + + fieldinfo = [] + for name in a.names: + tup = a.fields[name] + if recurse: + fmt = repack_fields(tup[0], align=align, recurse=True) + else: + fmt = tup[0] + + if len(tup) == 3: + name = (tup[2], name) + + fieldinfo.append((name, fmt)) + + dt = np.dtype(fieldinfo, align=align) + return np.dtype((a.type, dt)) + +def _get_fields_and_offsets(dt, offset=0): + """ + Returns a flat list of (dtype, count, offset) tuples of all the + scalar fields in the dtype "dt", including nested fields, in left + to right order. + """ + + # counts up elements in subarrays, including nested subarrays, and returns + # base dtype and count + def count_elem(dt): + count = 1 + while dt.shape != (): + for size in dt.shape: + count *= size + dt = dt.base + return dt, count + + fields = [] + for name in dt.names: + field = dt.fields[name] + f_dt, f_offset = field[0], field[1] + f_dt, n = count_elem(f_dt) + + if f_dt.names is None: + fields.append((np.dtype((f_dt, (n,))), n, f_offset + offset)) + else: + subfields = _get_fields_and_offsets(f_dt, f_offset + offset) + size = f_dt.itemsize + + for i in range(n): + if i == 0: + # optimization: avoid list comprehension if no subarray + fields.extend(subfields) + else: + fields.extend([(d, c, o + i*size) for d, c, o in subfields]) + return fields + + +def _structured_to_unstructured_dispatcher(arr, dtype=None, copy=None, + casting=None): + return (arr,) + +@array_function_dispatch(_structured_to_unstructured_dispatcher) +def structured_to_unstructured(arr, dtype=None, copy=False, casting='unsafe'): + """ + Converts an n-D structured array into an (n+1)-D unstructured array. + + The new array will have a new last dimension equal in size to the + number of field-elements of the input array. If not supplied, the output + datatype is determined from the numpy type promotion rules applied to all + the field datatypes. + + Nested fields, as well as each element of any subarray fields, all count + as a single field-elements. + + Parameters + ---------- + arr : ndarray + Structured array or dtype to convert. Cannot contain object datatype. + dtype : dtype, optional + The dtype of the output unstructured array. + copy : bool, optional + See copy argument to `ndarray.astype`. If true, always return a copy. + If false, and `dtype` requirements are satisfied, a view is returned. + casting : {'no', 'equiv', 'safe', 'same_kind', 'unsafe'}, optional + See casting argument of `ndarray.astype`. Controls what kind of data + casting may occur. + + Returns + ------- + unstructured : ndarray + Unstructured array with one more dimension. + + Examples + -------- + + >>> from numpy.lib import recfunctions as rfn + >>> a = np.zeros(4, dtype=[('a', 'i4'), ('b', 'f4,u2'), ('c', 'f4', 2)]) + >>> a + array([(0, (0., 0), [0., 0.]), (0, (0., 0), [0., 0.]), + (0, (0., 0), [0., 0.]), (0, (0., 0), [0., 0.])], + dtype=[('a', '>> rfn.structured_to_unstructured(a) + array([[0., 0., 0., 0., 0.], + [0., 0., 0., 0., 0.], + [0., 0., 0., 0., 0.], + [0., 0., 0., 0., 0.]]) + + >>> b = np.array([(1, 2, 5), (4, 5, 7), (7, 8 ,11), (10, 11, 12)], + ... dtype=[('x', 'i4'), ('y', 'f4'), ('z', 'f8')]) + >>> np.mean(rfn.structured_to_unstructured(b[['x', 'z']]), axis=-1) + array([ 3. , 5.5, 9. , 11. ]) + + """ + if arr.dtype.names is None: + raise ValueError('arr must be a structured array') + + fields = _get_fields_and_offsets(arr.dtype) + n_fields = len(fields) + if n_fields == 0 and dtype is None: + raise ValueError("arr has no fields. Unable to guess dtype") + elif n_fields == 0: + # too many bugs elsewhere for this to work now + raise NotImplementedError("arr with no fields is not supported") + + dts, counts, offsets = zip(*fields) + names = ['f{}'.format(n) for n in range(n_fields)] + + if dtype is None: + out_dtype = np.result_type(*[dt.base for dt in dts]) + else: + out_dtype = dtype + + # Use a series of views and casts to convert to an unstructured array: + + # first view using flattened fields (doesn't work for object arrays) + # Note: dts may include a shape for subarrays + flattened_fields = np.dtype({'names': names, + 'formats': dts, + 'offsets': offsets, + 'itemsize': arr.dtype.itemsize}) + with suppress_warnings() as sup: # until 1.16 (gh-12447) + sup.filter(FutureWarning, "Numpy has detected") + arr = arr.view(flattened_fields) + + # next cast to a packed format with all fields converted to new dtype + packed_fields = np.dtype({'names': names, + 'formats': [(out_dtype, dt.shape) for dt in dts]}) + arr = arr.astype(packed_fields, copy=copy, casting=casting) + + # finally is it safe to view the packed fields as the unstructured type + return arr.view((out_dtype, (sum(counts),))) + + +def _unstructured_to_structured_dispatcher(arr, dtype=None, names=None, + align=None, copy=None, casting=None): + return (arr,) + +@array_function_dispatch(_unstructured_to_structured_dispatcher) +def unstructured_to_structured(arr, dtype=None, names=None, align=False, + copy=False, casting='unsafe'): + """ + Converts an n-D unstructured array into an (n-1)-D structured array. + + The last dimension of the input array is converted into a structure, with + number of field-elements equal to the size of the last dimension of the + input array. By default all output fields have the input array's dtype, but + an output structured dtype with an equal number of fields-elements can be + supplied instead. + + Nested fields, as well as each element of any subarray fields, all count + towards the number of field-elements. + + Parameters + ---------- + arr : ndarray + Unstructured array or dtype to convert. + dtype : dtype, optional + The structured dtype of the output array + names : list of strings, optional + If dtype is not supplied, this specifies the field names for the output + dtype, in order. The field dtypes will be the same as the input array. + align : boolean, optional + Whether to create an aligned memory layout. + copy : bool, optional + See copy argument to `ndarray.astype`. If true, always return a copy. + If false, and `dtype` requirements are satisfied, a view is returned. + casting : {'no', 'equiv', 'safe', 'same_kind', 'unsafe'}, optional + See casting argument of `ndarray.astype`. Controls what kind of data + casting may occur. + + Returns + ------- + structured : ndarray + Structured array with fewer dimensions. + + Examples + -------- + + >>> from numpy.lib import recfunctions as rfn + >>> dt = np.dtype([('a', 'i4'), ('b', 'f4,u2'), ('c', 'f4', 2)]) + >>> a = np.arange(20).reshape((4,5)) + >>> a + array([[ 0, 1, 2, 3, 4], + [ 5, 6, 7, 8, 9], + [10, 11, 12, 13, 14], + [15, 16, 17, 18, 19]]) + >>> rfn.unstructured_to_structured(a, dt) + array([( 0, ( 1., 2), [ 3., 4.]), ( 5, ( 6., 7), [ 8., 9.]), + (10, (11., 12), [13., 14.]), (15, (16., 17), [18., 19.])], + dtype=[('a', '>> from numpy.lib import recfunctions as rfn + >>> b = np.array([(1, 2, 5), (4, 5, 7), (7, 8 ,11), (10, 11, 12)], + ... dtype=[('x', 'i4'), ('y', 'f4'), ('z', 'f8')]) + >>> rfn.apply_along_fields(np.mean, b) + array([ 2.66666667, 5.33333333, 8.66666667, 11. ]) + >>> rfn.apply_along_fields(np.mean, b[['x', 'z']]) + array([ 3. , 5.5, 9. , 11. ]) + + """ + if arr.dtype.names is None: + raise ValueError('arr must be a structured array') + + uarr = structured_to_unstructured(arr) + return func(uarr, axis=-1) + # works and avoids axis requirement, but very, very slow: + #return np.apply_along_axis(func, -1, uarr) + +def _assign_fields_by_name_dispatcher(dst, src, zero_unassigned=None): + return dst, src + +@array_function_dispatch(_assign_fields_by_name_dispatcher) +def assign_fields_by_name(dst, src, zero_unassigned=True): + """ + Assigns values from one structured array to another by field name. + + Normally in numpy >= 1.14, assignment of one structured array to another + copies fields "by position", meaning that the first field from the src is + copied to the first field of the dst, and so on, regardless of field name. + + This function instead copies "by field name", such that fields in the dst + are assigned from the identically named field in the src. This applies + recursively for nested structures. This is how structure assignment worked + in numpy >= 1.6 to <= 1.13. + + Parameters + ---------- + dst : ndarray + src : ndarray + The source and destination arrays during assignment. + zero_unassigned : bool, optional + If True, fields in the dst for which there was no matching + field in the src are filled with the value 0 (zero). This + was the behavior of numpy <= 1.13. If False, those fields + are not modified. + """ + + if dst.dtype.names is None: + dst[...] = src + return + + for name in dst.dtype.names: + if name not in src.dtype.names: + if zero_unassigned: + dst[name] = 0 + else: + assign_fields_by_name(dst[name], src[name], + zero_unassigned) + +def _require_fields_dispatcher(array, required_dtype): + return (array,) + +@array_function_dispatch(_require_fields_dispatcher) +def require_fields(array, required_dtype): + """ + Casts a structured array to a new dtype using assignment by field-name. + + This function assigns from the old to the new array by name, so the + value of a field in the output array is the value of the field with the + same name in the source array. This has the effect of creating a new + ndarray containing only the fields "required" by the required_dtype. + + If a field name in the required_dtype does not exist in the + input array, that field is created and set to 0 in the output array. + + Parameters + ---------- + a : ndarray + array to cast + required_dtype : dtype + datatype for output array + + Returns + ------- + out : ndarray + array with the new dtype, with field values copied from the fields in + the input array with the same name + + Examples + -------- + + >>> from numpy.lib import recfunctions as rfn + >>> a = np.ones(4, dtype=[('a', 'i4'), ('b', 'f8'), ('c', 'u1')]) + >>> rfn.require_fields(a, [('b', 'f4'), ('c', 'u1')]) + array([(1., 1), (1., 1), (1., 1), (1., 1)], + dtype=[('b', '>> rfn.require_fields(a, [('b', 'f4'), ('newf', 'u1')]) + array([(1., 0), (1., 0), (1., 0), (1., 0)], + dtype=[('b', '>> from numpy.lib import recfunctions as rfn + >>> x = np.array([1, 2,]) + >>> rfn.stack_arrays(x) is x + True + >>> z = np.array([('A', 1), ('B', 2)], dtype=[('A', '|S3'), ('B', float)]) + >>> zz = np.array([('a', 10., 100.), ('b', 20., 200.), ('c', 30., 300.)], + ... dtype=[('A', '|S3'), ('B', np.double), ('C', np.double)]) + >>> test = rfn.stack_arrays((z,zz)) + >>> test + masked_array(data=[(b'A', 1.0, --), (b'B', 2.0, --), (b'a', 10.0, 100.0), + (b'b', 20.0, 200.0), (b'c', 30.0, 300.0)], + mask=[(False, False, True), (False, False, True), + (False, False, False), (False, False, False), + (False, False, False)], + fill_value=(b'N/A', 1.e+20, 1.e+20), + dtype=[('A', 'S3'), ('B', ' '%s'" % + (cdtype, fdtype)) + # Only one field: use concatenate + if len(newdescr) == 1: + output = ma.concatenate(seqarrays) + else: + # + output = ma.masked_all((np.sum(nrecords),), newdescr) + offset = np.cumsum(np.r_[0, nrecords]) + seen = [] + for (a, n, i, j) in zip(seqarrays, fldnames, offset[:-1], offset[1:]): + names = a.dtype.names + if names is None: + output['f%i' % len(seen)][i:j] = a + else: + for name in n: + output[name][i:j] = a[name] + if name not in seen: + seen.append(name) + # + return _fix_output(_fix_defaults(output, defaults), + usemask=usemask, asrecarray=asrecarray) + + +def _find_duplicates_dispatcher( + a, key=None, ignoremask=None, return_index=None): + return (a,) + + +@array_function_dispatch(_find_duplicates_dispatcher) +def find_duplicates(a, key=None, ignoremask=True, return_index=False): + """ + Find the duplicates in a structured array along a given key + + Parameters + ---------- + a : array-like + Input array + key : {string, None}, optional + Name of the fields along which to check the duplicates. + If None, the search is performed by records + ignoremask : {True, False}, optional + Whether masked data should be discarded or considered as duplicates. + return_index : {False, True}, optional + Whether to return the indices of the duplicated values. + + Examples + -------- + >>> from numpy.lib import recfunctions as rfn + >>> ndtype = [('a', int)] + >>> a = np.ma.array([1, 1, 1, 2, 2, 3, 3], + ... mask=[0, 0, 1, 0, 0, 0, 1]).view(ndtype) + >>> rfn.find_duplicates(a, ignoremask=True, return_index=True) + (masked_array(data=[(1,), (1,), (2,), (2,)], + mask=[(False,), (False,), (False,), (False,)], + fill_value=(999999,), + dtype=[('a', '= nb1)] - nb1 + (r1cmn, r2cmn) = (len(idx_1), len(idx_2)) + if jointype == 'inner': + (r1spc, r2spc) = (0, 0) + elif jointype == 'outer': + idx_out = idx_sort[~flag_in] + idx_1 = np.concatenate((idx_1, idx_out[(idx_out < nb1)])) + idx_2 = np.concatenate((idx_2, idx_out[(idx_out >= nb1)] - nb1)) + (r1spc, r2spc) = (len(idx_1) - r1cmn, len(idx_2) - r2cmn) + elif jointype == 'leftouter': + idx_out = idx_sort[~flag_in] + idx_1 = np.concatenate((idx_1, idx_out[(idx_out < nb1)])) + (r1spc, r2spc) = (len(idx_1) - r1cmn, 0) + # Select the entries from each input + (s1, s2) = (r1[idx_1], r2[idx_2]) + # + # Build the new description of the output array ....... + # Start with the key fields + ndtype = _get_fieldspec(r1k.dtype) + + # Add the fields from r1 + for fname, fdtype in _get_fieldspec(r1.dtype): + if fname not in key: + ndtype.append((fname, fdtype)) + + # Add the fields from r2 + for fname, fdtype in _get_fieldspec(r2.dtype): + # Have we seen the current name already ? + # we need to rebuild this list every time + names = list(name for name, dtype in ndtype) + try: + nameidx = names.index(fname) + except ValueError: + #... we haven't: just add the description to the current list + ndtype.append((fname, fdtype)) + else: + # collision + _, cdtype = ndtype[nameidx] + if fname in key: + # The current field is part of the key: take the largest dtype + ndtype[nameidx] = (fname, max(fdtype, cdtype)) + else: + # The current field is not part of the key: add the suffixes, + # and place the new field adjacent to the old one + ndtype[nameidx:nameidx + 1] = [ + (fname + r1postfix, cdtype), + (fname + r2postfix, fdtype) + ] + # Rebuild a dtype from the new fields + ndtype = np.dtype(ndtype) + # Find the largest nb of common fields : + # r1cmn and r2cmn should be equal, but... + cmn = max(r1cmn, r2cmn) + # Construct an empty array + output = ma.masked_all((cmn + r1spc + r2spc,), dtype=ndtype) + names = output.dtype.names + for f in r1names: + selected = s1[f] + if f not in names or (f in r2names and not r2postfix and f not in key): + f += r1postfix + current = output[f] + current[:r1cmn] = selected[:r1cmn] + if jointype in ('outer', 'leftouter'): + current[cmn:cmn + r1spc] = selected[r1cmn:] + for f in r2names: + selected = s2[f] + if f not in names or (f in r1names and not r1postfix and f not in key): + f += r2postfix + current = output[f] + current[:r2cmn] = selected[:r2cmn] + if (jointype == 'outer') and r2spc: + current[-r2spc:] = selected[r2cmn:] + # Sort and finalize the output + output.sort(order=key) + kwargs = dict(usemask=usemask, asrecarray=asrecarray) + return _fix_output(_fix_defaults(output, defaults), **kwargs) + + +def _rec_join_dispatcher( + key, r1, r2, jointype=None, r1postfix=None, r2postfix=None, + defaults=None): + return (r1, r2) + + +@array_function_dispatch(_rec_join_dispatcher) +def rec_join(key, r1, r2, jointype='inner', r1postfix='1', r2postfix='2', + defaults=None): + """ + Join arrays `r1` and `r2` on keys. + Alternative to join_by, that always returns a np.recarray. + + See Also + -------- + join_by : equivalent function + """ + kwargs = dict(jointype=jointype, r1postfix=r1postfix, r2postfix=r2postfix, + defaults=defaults, usemask=False, asrecarray=True) + return join_by(key, r1, r2, **kwargs) diff --git a/venv/Lib/site-packages/numpy/lib/scimath.py b/venv/Lib/site-packages/numpy/lib/scimath.py new file mode 100644 index 0000000..2b0d38c --- /dev/null +++ b/venv/Lib/site-packages/numpy/lib/scimath.py @@ -0,0 +1,617 @@ +""" +Wrapper functions to more user-friendly calling of certain math functions +whose output data-type is different than the input data-type in certain +domains of the input. + +For example, for functions like `log` with branch cuts, the versions in this +module provide the mathematically valid answers in the complex plane:: + + >>> import math + >>> from numpy.lib import scimath + >>> scimath.log(-math.exp(1)) == (1+1j*math.pi) + True + +Similarly, `sqrt`, other base logarithms, `power` and trig functions are +correctly handled. See their respective docstrings for specific examples. + +Functions +--------- + +.. autosummary:: + :toctree: generated/ + + sqrt + log + log2 + logn + log10 + power + arccos + arcsin + arctanh + +""" +import numpy.core.numeric as nx +import numpy.core.numerictypes as nt +from numpy.core.numeric import asarray, any +from numpy.core.overrides import array_function_dispatch +from numpy.lib.type_check import isreal + + +__all__ = [ + 'sqrt', 'log', 'log2', 'logn', 'log10', 'power', 'arccos', 'arcsin', + 'arctanh' + ] + + +_ln2 = nx.log(2.0) + + +def _tocomplex(arr): + """Convert its input `arr` to a complex array. + + The input is returned as a complex array of the smallest type that will fit + the original data: types like single, byte, short, etc. become csingle, + while others become cdouble. + + A copy of the input is always made. + + Parameters + ---------- + arr : array + + Returns + ------- + array + An array with the same input data as the input but in complex form. + + Examples + -------- + + First, consider an input of type short: + + >>> a = np.array([1,2,3],np.short) + + >>> ac = np.lib.scimath._tocomplex(a); ac + array([1.+0.j, 2.+0.j, 3.+0.j], dtype=complex64) + + >>> ac.dtype + dtype('complex64') + + If the input is of type double, the output is correspondingly of the + complex double type as well: + + >>> b = np.array([1,2,3],np.double) + + >>> bc = np.lib.scimath._tocomplex(b); bc + array([1.+0.j, 2.+0.j, 3.+0.j]) + + >>> bc.dtype + dtype('complex128') + + Note that even if the input was complex to begin with, a copy is still + made, since the astype() method always copies: + + >>> c = np.array([1,2,3],np.csingle) + + >>> cc = np.lib.scimath._tocomplex(c); cc + array([1.+0.j, 2.+0.j, 3.+0.j], dtype=complex64) + + >>> c *= 2; c + array([2.+0.j, 4.+0.j, 6.+0.j], dtype=complex64) + + >>> cc + array([1.+0.j, 2.+0.j, 3.+0.j], dtype=complex64) + """ + if issubclass(arr.dtype.type, (nt.single, nt.byte, nt.short, nt.ubyte, + nt.ushort, nt.csingle)): + return arr.astype(nt.csingle) + else: + return arr.astype(nt.cdouble) + + +def _fix_real_lt_zero(x): + """Convert `x` to complex if it has real, negative components. + + Otherwise, output is just the array version of the input (via asarray). + + Parameters + ---------- + x : array_like + + Returns + ------- + array + + Examples + -------- + >>> np.lib.scimath._fix_real_lt_zero([1,2]) + array([1, 2]) + + >>> np.lib.scimath._fix_real_lt_zero([-1,2]) + array([-1.+0.j, 2.+0.j]) + + """ + x = asarray(x) + if any(isreal(x) & (x < 0)): + x = _tocomplex(x) + return x + + +def _fix_int_lt_zero(x): + """Convert `x` to double if it has real, negative components. + + Otherwise, output is just the array version of the input (via asarray). + + Parameters + ---------- + x : array_like + + Returns + ------- + array + + Examples + -------- + >>> np.lib.scimath._fix_int_lt_zero([1,2]) + array([1, 2]) + + >>> np.lib.scimath._fix_int_lt_zero([-1,2]) + array([-1., 2.]) + """ + x = asarray(x) + if any(isreal(x) & (x < 0)): + x = x * 1.0 + return x + + +def _fix_real_abs_gt_1(x): + """Convert `x` to complex if it has real components x_i with abs(x_i)>1. + + Otherwise, output is just the array version of the input (via asarray). + + Parameters + ---------- + x : array_like + + Returns + ------- + array + + Examples + -------- + >>> np.lib.scimath._fix_real_abs_gt_1([0,1]) + array([0, 1]) + + >>> np.lib.scimath._fix_real_abs_gt_1([0,2]) + array([0.+0.j, 2.+0.j]) + """ + x = asarray(x) + if any(isreal(x) & (abs(x) > 1)): + x = _tocomplex(x) + return x + + +def _unary_dispatcher(x): + return (x,) + + +@array_function_dispatch(_unary_dispatcher) +def sqrt(x): + """ + Compute the square root of x. + + For negative input elements, a complex value is returned + (unlike `numpy.sqrt` which returns NaN). + + Parameters + ---------- + x : array_like + The input value(s). + + Returns + ------- + out : ndarray or scalar + The square root of `x`. If `x` was a scalar, so is `out`, + otherwise an array is returned. + + See Also + -------- + numpy.sqrt + + Examples + -------- + For real, non-negative inputs this works just like `numpy.sqrt`: + + >>> np.lib.scimath.sqrt(1) + 1.0 + >>> np.lib.scimath.sqrt([1, 4]) + array([1., 2.]) + + But it automatically handles negative inputs: + + >>> np.lib.scimath.sqrt(-1) + 1j + >>> np.lib.scimath.sqrt([-1,4]) + array([0.+1.j, 2.+0.j]) + + """ + x = _fix_real_lt_zero(x) + return nx.sqrt(x) + + +@array_function_dispatch(_unary_dispatcher) +def log(x): + """ + Compute the natural logarithm of `x`. + + Return the "principal value" (for a description of this, see `numpy.log`) + of :math:`log_e(x)`. For real `x > 0`, this is a real number (``log(0)`` + returns ``-inf`` and ``log(np.inf)`` returns ``inf``). Otherwise, the + complex principle value is returned. + + Parameters + ---------- + x : array_like + The value(s) whose log is (are) required. + + Returns + ------- + out : ndarray or scalar + The log of the `x` value(s). If `x` was a scalar, so is `out`, + otherwise an array is returned. + + See Also + -------- + numpy.log + + Notes + ----- + For a log() that returns ``NAN`` when real `x < 0`, use `numpy.log` + (note, however, that otherwise `numpy.log` and this `log` are identical, + i.e., both return ``-inf`` for `x = 0`, ``inf`` for `x = inf`, and, + notably, the complex principle value if ``x.imag != 0``). + + Examples + -------- + >>> np.emath.log(np.exp(1)) + 1.0 + + Negative arguments are handled "correctly" (recall that + ``exp(log(x)) == x`` does *not* hold for real ``x < 0``): + + >>> np.emath.log(-np.exp(1)) == (1 + np.pi * 1j) + True + + """ + x = _fix_real_lt_zero(x) + return nx.log(x) + + +@array_function_dispatch(_unary_dispatcher) +def log10(x): + """ + Compute the logarithm base 10 of `x`. + + Return the "principal value" (for a description of this, see + `numpy.log10`) of :math:`log_{10}(x)`. For real `x > 0`, this + is a real number (``log10(0)`` returns ``-inf`` and ``log10(np.inf)`` + returns ``inf``). Otherwise, the complex principle value is returned. + + Parameters + ---------- + x : array_like or scalar + The value(s) whose log base 10 is (are) required. + + Returns + ------- + out : ndarray or scalar + The log base 10 of the `x` value(s). If `x` was a scalar, so is `out`, + otherwise an array object is returned. + + See Also + -------- + numpy.log10 + + Notes + ----- + For a log10() that returns ``NAN`` when real `x < 0`, use `numpy.log10` + (note, however, that otherwise `numpy.log10` and this `log10` are + identical, i.e., both return ``-inf`` for `x = 0`, ``inf`` for `x = inf`, + and, notably, the complex principle value if ``x.imag != 0``). + + Examples + -------- + + (We set the printing precision so the example can be auto-tested) + + >>> np.set_printoptions(precision=4) + + >>> np.emath.log10(10**1) + 1.0 + + >>> np.emath.log10([-10**1, -10**2, 10**2]) + array([1.+1.3644j, 2.+1.3644j, 2.+0.j ]) + + """ + x = _fix_real_lt_zero(x) + return nx.log10(x) + + +def _logn_dispatcher(n, x): + return (n, x,) + + +@array_function_dispatch(_logn_dispatcher) +def logn(n, x): + """ + Take log base n of x. + + If `x` contains negative inputs, the answer is computed and returned in the + complex domain. + + Parameters + ---------- + n : array_like + The integer base(s) in which the log is taken. + x : array_like + The value(s) whose log base `n` is (are) required. + + Returns + ------- + out : ndarray or scalar + The log base `n` of the `x` value(s). If `x` was a scalar, so is + `out`, otherwise an array is returned. + + Examples + -------- + >>> np.set_printoptions(precision=4) + + >>> np.lib.scimath.logn(2, [4, 8]) + array([2., 3.]) + >>> np.lib.scimath.logn(2, [-4, -8, 8]) + array([2.+4.5324j, 3.+4.5324j, 3.+0.j ]) + + """ + x = _fix_real_lt_zero(x) + n = _fix_real_lt_zero(n) + return nx.log(x)/nx.log(n) + + +@array_function_dispatch(_unary_dispatcher) +def log2(x): + """ + Compute the logarithm base 2 of `x`. + + Return the "principal value" (for a description of this, see + `numpy.log2`) of :math:`log_2(x)`. For real `x > 0`, this is + a real number (``log2(0)`` returns ``-inf`` and ``log2(np.inf)`` returns + ``inf``). Otherwise, the complex principle value is returned. + + Parameters + ---------- + x : array_like + The value(s) whose log base 2 is (are) required. + + Returns + ------- + out : ndarray or scalar + The log base 2 of the `x` value(s). If `x` was a scalar, so is `out`, + otherwise an array is returned. + + See Also + -------- + numpy.log2 + + Notes + ----- + For a log2() that returns ``NAN`` when real `x < 0`, use `numpy.log2` + (note, however, that otherwise `numpy.log2` and this `log2` are + identical, i.e., both return ``-inf`` for `x = 0`, ``inf`` for `x = inf`, + and, notably, the complex principle value if ``x.imag != 0``). + + Examples + -------- + We set the printing precision so the example can be auto-tested: + + >>> np.set_printoptions(precision=4) + + >>> np.emath.log2(8) + 3.0 + >>> np.emath.log2([-4, -8, 8]) + array([2.+4.5324j, 3.+4.5324j, 3.+0.j ]) + + """ + x = _fix_real_lt_zero(x) + return nx.log2(x) + + +def _power_dispatcher(x, p): + return (x, p) + + +@array_function_dispatch(_power_dispatcher) +def power(x, p): + """ + Return x to the power p, (x**p). + + If `x` contains negative values, the output is converted to the + complex domain. + + Parameters + ---------- + x : array_like + The input value(s). + p : array_like of ints + The power(s) to which `x` is raised. If `x` contains multiple values, + `p` has to either be a scalar, or contain the same number of values + as `x`. In the latter case, the result is + ``x[0]**p[0], x[1]**p[1], ...``. + + Returns + ------- + out : ndarray or scalar + The result of ``x**p``. If `x` and `p` are scalars, so is `out`, + otherwise an array is returned. + + See Also + -------- + numpy.power + + Examples + -------- + >>> np.set_printoptions(precision=4) + + >>> np.lib.scimath.power([2, 4], 2) + array([ 4, 16]) + >>> np.lib.scimath.power([2, 4], -2) + array([0.25 , 0.0625]) + >>> np.lib.scimath.power([-2, 4], 2) + array([ 4.-0.j, 16.+0.j]) + + """ + x = _fix_real_lt_zero(x) + p = _fix_int_lt_zero(p) + return nx.power(x, p) + + +@array_function_dispatch(_unary_dispatcher) +def arccos(x): + """ + Compute the inverse cosine of x. + + Return the "principal value" (for a description of this, see + `numpy.arccos`) of the inverse cosine of `x`. For real `x` such that + `abs(x) <= 1`, this is a real number in the closed interval + :math:`[0, \\pi]`. Otherwise, the complex principle value is returned. + + Parameters + ---------- + x : array_like or scalar + The value(s) whose arccos is (are) required. + + Returns + ------- + out : ndarray or scalar + The inverse cosine(s) of the `x` value(s). If `x` was a scalar, so + is `out`, otherwise an array object is returned. + + See Also + -------- + numpy.arccos + + Notes + ----- + For an arccos() that returns ``NAN`` when real `x` is not in the + interval ``[-1,1]``, use `numpy.arccos`. + + Examples + -------- + >>> np.set_printoptions(precision=4) + + >>> np.emath.arccos(1) # a scalar is returned + 0.0 + + >>> np.emath.arccos([1,2]) + array([0.-0.j , 0.-1.317j]) + + """ + x = _fix_real_abs_gt_1(x) + return nx.arccos(x) + + +@array_function_dispatch(_unary_dispatcher) +def arcsin(x): + """ + Compute the inverse sine of x. + + Return the "principal value" (for a description of this, see + `numpy.arcsin`) of the inverse sine of `x`. For real `x` such that + `abs(x) <= 1`, this is a real number in the closed interval + :math:`[-\\pi/2, \\pi/2]`. Otherwise, the complex principle value is + returned. + + Parameters + ---------- + x : array_like or scalar + The value(s) whose arcsin is (are) required. + + Returns + ------- + out : ndarray or scalar + The inverse sine(s) of the `x` value(s). If `x` was a scalar, so + is `out`, otherwise an array object is returned. + + See Also + -------- + numpy.arcsin + + Notes + ----- + For an arcsin() that returns ``NAN`` when real `x` is not in the + interval ``[-1,1]``, use `numpy.arcsin`. + + Examples + -------- + >>> np.set_printoptions(precision=4) + + >>> np.emath.arcsin(0) + 0.0 + + >>> np.emath.arcsin([0,1]) + array([0. , 1.5708]) + + """ + x = _fix_real_abs_gt_1(x) + return nx.arcsin(x) + + +@array_function_dispatch(_unary_dispatcher) +def arctanh(x): + """ + Compute the inverse hyperbolic tangent of `x`. + + Return the "principal value" (for a description of this, see + `numpy.arctanh`) of `arctanh(x)`. For real `x` such that + `abs(x) < 1`, this is a real number. If `abs(x) > 1`, or if `x` is + complex, the result is complex. Finally, `x = 1` returns``inf`` and + `x=-1` returns ``-inf``. + + Parameters + ---------- + x : array_like + The value(s) whose arctanh is (are) required. + + Returns + ------- + out : ndarray or scalar + The inverse hyperbolic tangent(s) of the `x` value(s). If `x` was + a scalar so is `out`, otherwise an array is returned. + + + See Also + -------- + numpy.arctanh + + Notes + ----- + For an arctanh() that returns ``NAN`` when real `x` is not in the + interval ``(-1,1)``, use `numpy.arctanh` (this latter, however, does + return +/-inf for `x = +/-1`). + + Examples + -------- + >>> np.set_printoptions(precision=4) + + >>> from numpy.testing import suppress_warnings + >>> with suppress_warnings() as sup: + ... sup.filter(RuntimeWarning) + ... np.emath.arctanh(np.eye(2)) + array([[inf, 0.], + [ 0., inf]]) + >>> np.emath.arctanh([1j]) + array([0.+0.7854j]) + + """ + x = _fix_real_abs_gt_1(x) + return nx.arctanh(x) diff --git a/venv/Lib/site-packages/numpy/lib/setup.py b/venv/Lib/site-packages/numpy/lib/setup.py new file mode 100644 index 0000000..7520b72 --- /dev/null +++ b/venv/Lib/site-packages/numpy/lib/setup.py @@ -0,0 +1,12 @@ +def configuration(parent_package='',top_path=None): + from numpy.distutils.misc_util import Configuration + + config = Configuration('lib', parent_package, top_path) + config.add_subpackage('tests') + config.add_data_dir('tests/data') + config.add_data_files('*.pyi') + return config + +if __name__ == '__main__': + from numpy.distutils.core import setup + setup(configuration=configuration) diff --git a/venv/Lib/site-packages/numpy/lib/shape_base.py b/venv/Lib/site-packages/numpy/lib/shape_base.py new file mode 100644 index 0000000..cbc4641 --- /dev/null +++ b/venv/Lib/site-packages/numpy/lib/shape_base.py @@ -0,0 +1,1260 @@ +import functools + +import numpy.core.numeric as _nx +from numpy.core.numeric import ( + asarray, zeros, outer, concatenate, array, asanyarray + ) +from numpy.core.fromnumeric import reshape, transpose +from numpy.core.multiarray import normalize_axis_index +from numpy.core import overrides +from numpy.core import vstack, atleast_3d +from numpy.core.numeric import normalize_axis_tuple +from numpy.core.shape_base import _arrays_for_stack_dispatcher +from numpy.lib.index_tricks import ndindex +from numpy.matrixlib.defmatrix import matrix # this raises all the right alarm bells + + +__all__ = [ + 'column_stack', 'row_stack', 'dstack', 'array_split', 'split', + 'hsplit', 'vsplit', 'dsplit', 'apply_over_axes', 'expand_dims', + 'apply_along_axis', 'kron', 'tile', 'get_array_wrap', 'take_along_axis', + 'put_along_axis' + ] + + +array_function_dispatch = functools.partial( + overrides.array_function_dispatch, module='numpy') + + +def _make_along_axis_idx(arr_shape, indices, axis): + # compute dimensions to iterate over + if not _nx.issubdtype(indices.dtype, _nx.integer): + raise IndexError('`indices` must be an integer array') + if len(arr_shape) != indices.ndim: + raise ValueError( + "`indices` and `arr` must have the same number of dimensions") + shape_ones = (1,) * indices.ndim + dest_dims = list(range(axis)) + [None] + list(range(axis+1, indices.ndim)) + + # build a fancy index, consisting of orthogonal aranges, with the + # requested index inserted at the right location + fancy_index = [] + for dim, n in zip(dest_dims, arr_shape): + if dim is None: + fancy_index.append(indices) + else: + ind_shape = shape_ones[:dim] + (-1,) + shape_ones[dim+1:] + fancy_index.append(_nx.arange(n).reshape(ind_shape)) + + return tuple(fancy_index) + + +def _take_along_axis_dispatcher(arr, indices, axis): + return (arr, indices) + + +@array_function_dispatch(_take_along_axis_dispatcher) +def take_along_axis(arr, indices, axis): + """ + Take values from the input array by matching 1d index and data slices. + + This iterates over matching 1d slices oriented along the specified axis in + the index and data arrays, and uses the former to look up values in the + latter. These slices can be different lengths. + + Functions returning an index along an axis, like `argsort` and + `argpartition`, produce suitable indices for this function. + + .. versionadded:: 1.15.0 + + Parameters + ---------- + arr: ndarray (Ni..., M, Nk...) + Source array + indices: ndarray (Ni..., J, Nk...) + Indices to take along each 1d slice of `arr`. This must match the + dimension of arr, but dimensions Ni and Nj only need to broadcast + against `arr`. + axis: int + The axis to take 1d slices along. If axis is None, the input array is + treated as if it had first been flattened to 1d, for consistency with + `sort` and `argsort`. + + Returns + ------- + out: ndarray (Ni..., J, Nk...) + The indexed result. + + Notes + ----- + This is equivalent to (but faster than) the following use of `ndindex` and + `s_`, which sets each of ``ii`` and ``kk`` to a tuple of indices:: + + Ni, M, Nk = a.shape[:axis], a.shape[axis], a.shape[axis+1:] + J = indices.shape[axis] # Need not equal M + out = np.empty(Ni + (J,) + Nk) + + for ii in ndindex(Ni): + for kk in ndindex(Nk): + a_1d = a [ii + s_[:,] + kk] + indices_1d = indices[ii + s_[:,] + kk] + out_1d = out [ii + s_[:,] + kk] + for j in range(J): + out_1d[j] = a_1d[indices_1d[j]] + + Equivalently, eliminating the inner loop, the last two lines would be:: + + out_1d[:] = a_1d[indices_1d] + + See Also + -------- + take : Take along an axis, using the same indices for every 1d slice + put_along_axis : + Put values into the destination array by matching 1d index and data slices + + Examples + -------- + + For this sample array + + >>> a = np.array([[10, 30, 20], [60, 40, 50]]) + + We can sort either by using sort directly, or argsort and this function + + >>> np.sort(a, axis=1) + array([[10, 20, 30], + [40, 50, 60]]) + >>> ai = np.argsort(a, axis=1); ai + array([[0, 2, 1], + [1, 2, 0]]) + >>> np.take_along_axis(a, ai, axis=1) + array([[10, 20, 30], + [40, 50, 60]]) + + The same works for max and min, if you expand the dimensions: + + >>> np.expand_dims(np.max(a, axis=1), axis=1) + array([[30], + [60]]) + >>> ai = np.expand_dims(np.argmax(a, axis=1), axis=1) + >>> ai + array([[1], + [0]]) + >>> np.take_along_axis(a, ai, axis=1) + array([[30], + [60]]) + + If we want to get the max and min at the same time, we can stack the + indices first + + >>> ai_min = np.expand_dims(np.argmin(a, axis=1), axis=1) + >>> ai_max = np.expand_dims(np.argmax(a, axis=1), axis=1) + >>> ai = np.concatenate([ai_min, ai_max], axis=1) + >>> ai + array([[0, 1], + [1, 0]]) + >>> np.take_along_axis(a, ai, axis=1) + array([[10, 30], + [40, 60]]) + """ + # normalize inputs + if axis is None: + arr = arr.flat + arr_shape = (len(arr),) # flatiter has no .shape + axis = 0 + else: + axis = normalize_axis_index(axis, arr.ndim) + arr_shape = arr.shape + + # use the fancy index + return arr[_make_along_axis_idx(arr_shape, indices, axis)] + + +def _put_along_axis_dispatcher(arr, indices, values, axis): + return (arr, indices, values) + + +@array_function_dispatch(_put_along_axis_dispatcher) +def put_along_axis(arr, indices, values, axis): + """ + Put values into the destination array by matching 1d index and data slices. + + This iterates over matching 1d slices oriented along the specified axis in + the index and data arrays, and uses the former to place values into the + latter. These slices can be different lengths. + + Functions returning an index along an axis, like `argsort` and + `argpartition`, produce suitable indices for this function. + + .. versionadded:: 1.15.0 + + Parameters + ---------- + arr: ndarray (Ni..., M, Nk...) + Destination array. + indices: ndarray (Ni..., J, Nk...) + Indices to change along each 1d slice of `arr`. This must match the + dimension of arr, but dimensions in Ni and Nj may be 1 to broadcast + against `arr`. + values: array_like (Ni..., J, Nk...) + values to insert at those indices. Its shape and dimension are + broadcast to match that of `indices`. + axis: int + The axis to take 1d slices along. If axis is None, the destination + array is treated as if a flattened 1d view had been created of it. + + Notes + ----- + This is equivalent to (but faster than) the following use of `ndindex` and + `s_`, which sets each of ``ii`` and ``kk`` to a tuple of indices:: + + Ni, M, Nk = a.shape[:axis], a.shape[axis], a.shape[axis+1:] + J = indices.shape[axis] # Need not equal M + + for ii in ndindex(Ni): + for kk in ndindex(Nk): + a_1d = a [ii + s_[:,] + kk] + indices_1d = indices[ii + s_[:,] + kk] + values_1d = values [ii + s_[:,] + kk] + for j in range(J): + a_1d[indices_1d[j]] = values_1d[j] + + Equivalently, eliminating the inner loop, the last two lines would be:: + + a_1d[indices_1d] = values_1d + + See Also + -------- + take_along_axis : + Take values from the input array by matching 1d index and data slices + + Examples + -------- + + For this sample array + + >>> a = np.array([[10, 30, 20], [60, 40, 50]]) + + We can replace the maximum values with: + + >>> ai = np.expand_dims(np.argmax(a, axis=1), axis=1) + >>> ai + array([[1], + [0]]) + >>> np.put_along_axis(a, ai, 99, axis=1) + >>> a + array([[10, 99, 20], + [99, 40, 50]]) + + """ + # normalize inputs + if axis is None: + arr = arr.flat + axis = 0 + arr_shape = (len(arr),) # flatiter has no .shape + else: + axis = normalize_axis_index(axis, arr.ndim) + arr_shape = arr.shape + + # use the fancy index + arr[_make_along_axis_idx(arr_shape, indices, axis)] = values + + +def _apply_along_axis_dispatcher(func1d, axis, arr, *args, **kwargs): + return (arr,) + + +@array_function_dispatch(_apply_along_axis_dispatcher) +def apply_along_axis(func1d, axis, arr, *args, **kwargs): + """ + Apply a function to 1-D slices along the given axis. + + Execute `func1d(a, *args, **kwargs)` where `func1d` operates on 1-D arrays + and `a` is a 1-D slice of `arr` along `axis`. + + This is equivalent to (but faster than) the following use of `ndindex` and + `s_`, which sets each of ``ii``, ``jj``, and ``kk`` to a tuple of indices:: + + Ni, Nk = a.shape[:axis], a.shape[axis+1:] + for ii in ndindex(Ni): + for kk in ndindex(Nk): + f = func1d(arr[ii + s_[:,] + kk]) + Nj = f.shape + for jj in ndindex(Nj): + out[ii + jj + kk] = f[jj] + + Equivalently, eliminating the inner loop, this can be expressed as:: + + Ni, Nk = a.shape[:axis], a.shape[axis+1:] + for ii in ndindex(Ni): + for kk in ndindex(Nk): + out[ii + s_[...,] + kk] = func1d(arr[ii + s_[:,] + kk]) + + Parameters + ---------- + func1d : function (M,) -> (Nj...) + This function should accept 1-D arrays. It is applied to 1-D + slices of `arr` along the specified axis. + axis : integer + Axis along which `arr` is sliced. + arr : ndarray (Ni..., M, Nk...) + Input array. + args : any + Additional arguments to `func1d`. + kwargs : any + Additional named arguments to `func1d`. + + .. versionadded:: 1.9.0 + + + Returns + ------- + out : ndarray (Ni..., Nj..., Nk...) + The output array. The shape of `out` is identical to the shape of + `arr`, except along the `axis` dimension. This axis is removed, and + replaced with new dimensions equal to the shape of the return value + of `func1d`. So if `func1d` returns a scalar `out` will have one + fewer dimensions than `arr`. + + See Also + -------- + apply_over_axes : Apply a function repeatedly over multiple axes. + + Examples + -------- + >>> def my_func(a): + ... \"\"\"Average first and last element of a 1-D array\"\"\" + ... return (a[0] + a[-1]) * 0.5 + >>> b = np.array([[1,2,3], [4,5,6], [7,8,9]]) + >>> np.apply_along_axis(my_func, 0, b) + array([4., 5., 6.]) + >>> np.apply_along_axis(my_func, 1, b) + array([2., 5., 8.]) + + For a function that returns a 1D array, the number of dimensions in + `outarr` is the same as `arr`. + + >>> b = np.array([[8,1,7], [4,3,9], [5,2,6]]) + >>> np.apply_along_axis(sorted, 1, b) + array([[1, 7, 8], + [3, 4, 9], + [2, 5, 6]]) + + For a function that returns a higher dimensional array, those dimensions + are inserted in place of the `axis` dimension. + + >>> b = np.array([[1,2,3], [4,5,6], [7,8,9]]) + >>> np.apply_along_axis(np.diag, -1, b) + array([[[1, 0, 0], + [0, 2, 0], + [0, 0, 3]], + [[4, 0, 0], + [0, 5, 0], + [0, 0, 6]], + [[7, 0, 0], + [0, 8, 0], + [0, 0, 9]]]) + """ + # handle negative axes + arr = asanyarray(arr) + nd = arr.ndim + axis = normalize_axis_index(axis, nd) + + # arr, with the iteration axis at the end + in_dims = list(range(nd)) + inarr_view = transpose(arr, in_dims[:axis] + in_dims[axis+1:] + [axis]) + + # compute indices for the iteration axes, and append a trailing ellipsis to + # prevent 0d arrays decaying to scalars, which fixes gh-8642 + inds = ndindex(inarr_view.shape[:-1]) + inds = (ind + (Ellipsis,) for ind in inds) + + # invoke the function on the first item + try: + ind0 = next(inds) + except StopIteration as e: + raise ValueError( + 'Cannot apply_along_axis when any iteration dimensions are 0' + ) from None + res = asanyarray(func1d(inarr_view[ind0], *args, **kwargs)) + + # build a buffer for storing evaluations of func1d. + # remove the requested axis, and add the new ones on the end. + # laid out so that each write is contiguous. + # for a tuple index inds, buff[inds] = func1d(inarr_view[inds]) + buff = zeros(inarr_view.shape[:-1] + res.shape, res.dtype) + + # permutation of axes such that out = buff.transpose(buff_permute) + buff_dims = list(range(buff.ndim)) + buff_permute = ( + buff_dims[0 : axis] + + buff_dims[buff.ndim-res.ndim : buff.ndim] + + buff_dims[axis : buff.ndim-res.ndim] + ) + + # matrices have a nasty __array_prepare__ and __array_wrap__ + if not isinstance(res, matrix): + buff = res.__array_prepare__(buff) + + # save the first result, then compute and save all remaining results + buff[ind0] = res + for ind in inds: + buff[ind] = asanyarray(func1d(inarr_view[ind], *args, **kwargs)) + + if not isinstance(res, matrix): + # wrap the array, to preserve subclasses + buff = res.__array_wrap__(buff) + + # finally, rotate the inserted axes back to where they belong + return transpose(buff, buff_permute) + + else: + # matrices have to be transposed first, because they collapse dimensions! + out_arr = transpose(buff, buff_permute) + return res.__array_wrap__(out_arr) + + +def _apply_over_axes_dispatcher(func, a, axes): + return (a,) + + +@array_function_dispatch(_apply_over_axes_dispatcher) +def apply_over_axes(func, a, axes): + """ + Apply a function repeatedly over multiple axes. + + `func` is called as `res = func(a, axis)`, where `axis` is the first + element of `axes`. The result `res` of the function call must have + either the same dimensions as `a` or one less dimension. If `res` + has one less dimension than `a`, a dimension is inserted before + `axis`. The call to `func` is then repeated for each axis in `axes`, + with `res` as the first argument. + + Parameters + ---------- + func : function + This function must take two arguments, `func(a, axis)`. + a : array_like + Input array. + axes : array_like + Axes over which `func` is applied; the elements must be integers. + + Returns + ------- + apply_over_axis : ndarray + The output array. The number of dimensions is the same as `a`, + but the shape can be different. This depends on whether `func` + changes the shape of its output with respect to its input. + + See Also + -------- + apply_along_axis : + Apply a function to 1-D slices of an array along the given axis. + + Notes + ----- + This function is equivalent to tuple axis arguments to reorderable ufuncs + with keepdims=True. Tuple axis arguments to ufuncs have been available since + version 1.7.0. + + Examples + -------- + >>> a = np.arange(24).reshape(2,3,4) + >>> a + array([[[ 0, 1, 2, 3], + [ 4, 5, 6, 7], + [ 8, 9, 10, 11]], + [[12, 13, 14, 15], + [16, 17, 18, 19], + [20, 21, 22, 23]]]) + + Sum over axes 0 and 2. The result has same number of dimensions + as the original array: + + >>> np.apply_over_axes(np.sum, a, [0,2]) + array([[[ 60], + [ 92], + [124]]]) + + Tuple axis arguments to ufuncs are equivalent: + + >>> np.sum(a, axis=(0,2), keepdims=True) + array([[[ 60], + [ 92], + [124]]]) + + """ + val = asarray(a) + N = a.ndim + if array(axes).ndim == 0: + axes = (axes,) + for axis in axes: + if axis < 0: + axis = N + axis + args = (val, axis) + res = func(*args) + if res.ndim == val.ndim: + val = res + else: + res = expand_dims(res, axis) + if res.ndim == val.ndim: + val = res + else: + raise ValueError("function is not returning " + "an array of the correct shape") + return val + + +def _expand_dims_dispatcher(a, axis): + return (a,) + + +@array_function_dispatch(_expand_dims_dispatcher) +def expand_dims(a, axis): + """ + Expand the shape of an array. + + Insert a new axis that will appear at the `axis` position in the expanded + array shape. + + Parameters + ---------- + a : array_like + Input array. + axis : int or tuple of ints + Position in the expanded axes where the new axis (or axes) is placed. + + .. deprecated:: 1.13.0 + Passing an axis where ``axis > a.ndim`` will be treated as + ``axis == a.ndim``, and passing ``axis < -a.ndim - 1`` will + be treated as ``axis == 0``. This behavior is deprecated. + + .. versionchanged:: 1.18.0 + A tuple of axes is now supported. Out of range axes as + described above are now forbidden and raise an `AxisError`. + + Returns + ------- + result : ndarray + View of `a` with the number of dimensions increased. + + See Also + -------- + squeeze : The inverse operation, removing singleton dimensions + reshape : Insert, remove, and combine dimensions, and resize existing ones + doc.indexing, atleast_1d, atleast_2d, atleast_3d + + Examples + -------- + >>> x = np.array([1, 2]) + >>> x.shape + (2,) + + The following is equivalent to ``x[np.newaxis, :]`` or ``x[np.newaxis]``: + + >>> y = np.expand_dims(x, axis=0) + >>> y + array([[1, 2]]) + >>> y.shape + (1, 2) + + The following is equivalent to ``x[:, np.newaxis]``: + + >>> y = np.expand_dims(x, axis=1) + >>> y + array([[1], + [2]]) + >>> y.shape + (2, 1) + + ``axis`` may also be a tuple: + + >>> y = np.expand_dims(x, axis=(0, 1)) + >>> y + array([[[1, 2]]]) + + >>> y = np.expand_dims(x, axis=(2, 0)) + >>> y + array([[[1], + [2]]]) + + Note that some examples may use ``None`` instead of ``np.newaxis``. These + are the same objects: + + >>> np.newaxis is None + True + + """ + if isinstance(a, matrix): + a = asarray(a) + else: + a = asanyarray(a) + + if type(axis) not in (tuple, list): + axis = (axis,) + + out_ndim = len(axis) + a.ndim + axis = normalize_axis_tuple(axis, out_ndim) + + shape_it = iter(a.shape) + shape = [1 if ax in axis else next(shape_it) for ax in range(out_ndim)] + + return a.reshape(shape) + + +row_stack = vstack + + +def _column_stack_dispatcher(tup): + return _arrays_for_stack_dispatcher(tup) + + +@array_function_dispatch(_column_stack_dispatcher) +def column_stack(tup): + """ + Stack 1-D arrays as columns into a 2-D array. + + Take a sequence of 1-D arrays and stack them as columns + to make a single 2-D array. 2-D arrays are stacked as-is, + just like with `hstack`. 1-D arrays are turned into 2-D columns + first. + + Parameters + ---------- + tup : sequence of 1-D or 2-D arrays. + Arrays to stack. All of them must have the same first dimension. + + Returns + ------- + stacked : 2-D array + The array formed by stacking the given arrays. + + See Also + -------- + stack, hstack, vstack, concatenate + + Examples + -------- + >>> a = np.array((1,2,3)) + >>> b = np.array((2,3,4)) + >>> np.column_stack((a,b)) + array([[1, 2], + [2, 3], + [3, 4]]) + + """ + if not overrides.ARRAY_FUNCTION_ENABLED: + # raise warning if necessary + _arrays_for_stack_dispatcher(tup, stacklevel=2) + + arrays = [] + for v in tup: + arr = array(v, copy=False, subok=True) + if arr.ndim < 2: + arr = array(arr, copy=False, subok=True, ndmin=2).T + arrays.append(arr) + return _nx.concatenate(arrays, 1) + + +def _dstack_dispatcher(tup): + return _arrays_for_stack_dispatcher(tup) + + +@array_function_dispatch(_dstack_dispatcher) +def dstack(tup): + """ + Stack arrays in sequence depth wise (along third axis). + + This is equivalent to concatenation along the third axis after 2-D arrays + of shape `(M,N)` have been reshaped to `(M,N,1)` and 1-D arrays of shape + `(N,)` have been reshaped to `(1,N,1)`. Rebuilds arrays divided by + `dsplit`. + + This function makes most sense for arrays with up to 3 dimensions. For + instance, for pixel-data with a height (first axis), width (second axis), + and r/g/b channels (third axis). The functions `concatenate`, `stack` and + `block` provide more general stacking and concatenation operations. + + Parameters + ---------- + tup : sequence of arrays + The arrays must have the same shape along all but the third axis. + 1-D or 2-D arrays must have the same shape. + + Returns + ------- + stacked : ndarray + The array formed by stacking the given arrays, will be at least 3-D. + + See Also + -------- + concatenate : Join a sequence of arrays along an existing axis. + stack : Join a sequence of arrays along a new axis. + block : Assemble an nd-array from nested lists of blocks. + vstack : Stack arrays in sequence vertically (row wise). + hstack : Stack arrays in sequence horizontally (column wise). + column_stack : Stack 1-D arrays as columns into a 2-D array. + dsplit : Split array along third axis. + + Examples + -------- + >>> a = np.array((1,2,3)) + >>> b = np.array((2,3,4)) + >>> np.dstack((a,b)) + array([[[1, 2], + [2, 3], + [3, 4]]]) + + >>> a = np.array([[1],[2],[3]]) + >>> b = np.array([[2],[3],[4]]) + >>> np.dstack((a,b)) + array([[[1, 2]], + [[2, 3]], + [[3, 4]]]) + + """ + if not overrides.ARRAY_FUNCTION_ENABLED: + # raise warning if necessary + _arrays_for_stack_dispatcher(tup, stacklevel=2) + + arrs = atleast_3d(*tup) + if not isinstance(arrs, list): + arrs = [arrs] + return _nx.concatenate(arrs, 2) + + +def _replace_zero_by_x_arrays(sub_arys): + for i in range(len(sub_arys)): + if _nx.ndim(sub_arys[i]) == 0: + sub_arys[i] = _nx.empty(0, dtype=sub_arys[i].dtype) + elif _nx.sometrue(_nx.equal(_nx.shape(sub_arys[i]), 0)): + sub_arys[i] = _nx.empty(0, dtype=sub_arys[i].dtype) + return sub_arys + + +def _array_split_dispatcher(ary, indices_or_sections, axis=None): + return (ary, indices_or_sections) + + +@array_function_dispatch(_array_split_dispatcher) +def array_split(ary, indices_or_sections, axis=0): + """ + Split an array into multiple sub-arrays. + + Please refer to the ``split`` documentation. The only difference + between these functions is that ``array_split`` allows + `indices_or_sections` to be an integer that does *not* equally + divide the axis. For an array of length l that should be split + into n sections, it returns l % n sub-arrays of size l//n + 1 + and the rest of size l//n. + + See Also + -------- + split : Split array into multiple sub-arrays of equal size. + + Examples + -------- + >>> x = np.arange(8.0) + >>> np.array_split(x, 3) + [array([0., 1., 2.]), array([3., 4., 5.]), array([6., 7.])] + + >>> x = np.arange(9) + >>> np.array_split(x, 4) + [array([0, 1, 2]), array([3, 4]), array([5, 6]), array([7, 8])] + + """ + try: + Ntotal = ary.shape[axis] + except AttributeError: + Ntotal = len(ary) + try: + # handle array case. + Nsections = len(indices_or_sections) + 1 + div_points = [0] + list(indices_or_sections) + [Ntotal] + except TypeError: + # indices_or_sections is a scalar, not an array. + Nsections = int(indices_or_sections) + if Nsections <= 0: + raise ValueError('number sections must be larger than 0.') + Neach_section, extras = divmod(Ntotal, Nsections) + section_sizes = ([0] + + extras * [Neach_section+1] + + (Nsections-extras) * [Neach_section]) + div_points = _nx.array(section_sizes, dtype=_nx.intp).cumsum() + + sub_arys = [] + sary = _nx.swapaxes(ary, axis, 0) + for i in range(Nsections): + st = div_points[i] + end = div_points[i + 1] + sub_arys.append(_nx.swapaxes(sary[st:end], axis, 0)) + + return sub_arys + + +def _split_dispatcher(ary, indices_or_sections, axis=None): + return (ary, indices_or_sections) + + +@array_function_dispatch(_split_dispatcher) +def split(ary, indices_or_sections, axis=0): + """ + Split an array into multiple sub-arrays as views into `ary`. + + Parameters + ---------- + ary : ndarray + Array to be divided into sub-arrays. + indices_or_sections : int or 1-D array + If `indices_or_sections` is an integer, N, the array will be divided + into N equal arrays along `axis`. If such a split is not possible, + an error is raised. + + If `indices_or_sections` is a 1-D array of sorted integers, the entries + indicate where along `axis` the array is split. For example, + ``[2, 3]`` would, for ``axis=0``, result in + + - ary[:2] + - ary[2:3] + - ary[3:] + + If an index exceeds the dimension of the array along `axis`, + an empty sub-array is returned correspondingly. + axis : int, optional + The axis along which to split, default is 0. + + Returns + ------- + sub-arrays : list of ndarrays + A list of sub-arrays as views into `ary`. + + Raises + ------ + ValueError + If `indices_or_sections` is given as an integer, but + a split does not result in equal division. + + See Also + -------- + array_split : Split an array into multiple sub-arrays of equal or + near-equal size. Does not raise an exception if + an equal division cannot be made. + hsplit : Split array into multiple sub-arrays horizontally (column-wise). + vsplit : Split array into multiple sub-arrays vertically (row wise). + dsplit : Split array into multiple sub-arrays along the 3rd axis (depth). + concatenate : Join a sequence of arrays along an existing axis. + stack : Join a sequence of arrays along a new axis. + hstack : Stack arrays in sequence horizontally (column wise). + vstack : Stack arrays in sequence vertically (row wise). + dstack : Stack arrays in sequence depth wise (along third dimension). + + Examples + -------- + >>> x = np.arange(9.0) + >>> np.split(x, 3) + [array([0., 1., 2.]), array([3., 4., 5.]), array([6., 7., 8.])] + + >>> x = np.arange(8.0) + >>> np.split(x, [3, 5, 6, 10]) + [array([0., 1., 2.]), + array([3., 4.]), + array([5.]), + array([6., 7.]), + array([], dtype=float64)] + + """ + try: + len(indices_or_sections) + except TypeError: + sections = indices_or_sections + N = ary.shape[axis] + if N % sections: + raise ValueError( + 'array split does not result in an equal division') from None + return array_split(ary, indices_or_sections, axis) + + +def _hvdsplit_dispatcher(ary, indices_or_sections): + return (ary, indices_or_sections) + + +@array_function_dispatch(_hvdsplit_dispatcher) +def hsplit(ary, indices_or_sections): + """ + Split an array into multiple sub-arrays horizontally (column-wise). + + Please refer to the `split` documentation. `hsplit` is equivalent + to `split` with ``axis=1``, the array is always split along the second + axis regardless of the array dimension. + + See Also + -------- + split : Split an array into multiple sub-arrays of equal size. + + Examples + -------- + >>> x = np.arange(16.0).reshape(4, 4) + >>> x + array([[ 0., 1., 2., 3.], + [ 4., 5., 6., 7.], + [ 8., 9., 10., 11.], + [12., 13., 14., 15.]]) + >>> np.hsplit(x, 2) + [array([[ 0., 1.], + [ 4., 5.], + [ 8., 9.], + [12., 13.]]), + array([[ 2., 3.], + [ 6., 7.], + [10., 11.], + [14., 15.]])] + >>> np.hsplit(x, np.array([3, 6])) + [array([[ 0., 1., 2.], + [ 4., 5., 6.], + [ 8., 9., 10.], + [12., 13., 14.]]), + array([[ 3.], + [ 7.], + [11.], + [15.]]), + array([], shape=(4, 0), dtype=float64)] + + With a higher dimensional array the split is still along the second axis. + + >>> x = np.arange(8.0).reshape(2, 2, 2) + >>> x + array([[[0., 1.], + [2., 3.]], + [[4., 5.], + [6., 7.]]]) + >>> np.hsplit(x, 2) + [array([[[0., 1.]], + [[4., 5.]]]), + array([[[2., 3.]], + [[6., 7.]]])] + + """ + if _nx.ndim(ary) == 0: + raise ValueError('hsplit only works on arrays of 1 or more dimensions') + if ary.ndim > 1: + return split(ary, indices_or_sections, 1) + else: + return split(ary, indices_or_sections, 0) + + +@array_function_dispatch(_hvdsplit_dispatcher) +def vsplit(ary, indices_or_sections): + """ + Split an array into multiple sub-arrays vertically (row-wise). + + Please refer to the ``split`` documentation. ``vsplit`` is equivalent + to ``split`` with `axis=0` (default), the array is always split along the + first axis regardless of the array dimension. + + See Also + -------- + split : Split an array into multiple sub-arrays of equal size. + + Examples + -------- + >>> x = np.arange(16.0).reshape(4, 4) + >>> x + array([[ 0., 1., 2., 3.], + [ 4., 5., 6., 7.], + [ 8., 9., 10., 11.], + [12., 13., 14., 15.]]) + >>> np.vsplit(x, 2) + [array([[0., 1., 2., 3.], + [4., 5., 6., 7.]]), array([[ 8., 9., 10., 11.], + [12., 13., 14., 15.]])] + >>> np.vsplit(x, np.array([3, 6])) + [array([[ 0., 1., 2., 3.], + [ 4., 5., 6., 7.], + [ 8., 9., 10., 11.]]), array([[12., 13., 14., 15.]]), array([], shape=(0, 4), dtype=float64)] + + With a higher dimensional array the split is still along the first axis. + + >>> x = np.arange(8.0).reshape(2, 2, 2) + >>> x + array([[[0., 1.], + [2., 3.]], + [[4., 5.], + [6., 7.]]]) + >>> np.vsplit(x, 2) + [array([[[0., 1.], + [2., 3.]]]), array([[[4., 5.], + [6., 7.]]])] + + """ + if _nx.ndim(ary) < 2: + raise ValueError('vsplit only works on arrays of 2 or more dimensions') + return split(ary, indices_or_sections, 0) + + +@array_function_dispatch(_hvdsplit_dispatcher) +def dsplit(ary, indices_or_sections): + """ + Split array into multiple sub-arrays along the 3rd axis (depth). + + Please refer to the `split` documentation. `dsplit` is equivalent + to `split` with ``axis=2``, the array is always split along the third + axis provided the array dimension is greater than or equal to 3. + + See Also + -------- + split : Split an array into multiple sub-arrays of equal size. + + Examples + -------- + >>> x = np.arange(16.0).reshape(2, 2, 4) + >>> x + array([[[ 0., 1., 2., 3.], + [ 4., 5., 6., 7.]], + [[ 8., 9., 10., 11.], + [12., 13., 14., 15.]]]) + >>> np.dsplit(x, 2) + [array([[[ 0., 1.], + [ 4., 5.]], + [[ 8., 9.], + [12., 13.]]]), array([[[ 2., 3.], + [ 6., 7.]], + [[10., 11.], + [14., 15.]]])] + >>> np.dsplit(x, np.array([3, 6])) + [array([[[ 0., 1., 2.], + [ 4., 5., 6.]], + [[ 8., 9., 10.], + [12., 13., 14.]]]), + array([[[ 3.], + [ 7.]], + [[11.], + [15.]]]), + array([], shape=(2, 2, 0), dtype=float64)] + """ + if _nx.ndim(ary) < 3: + raise ValueError('dsplit only works on arrays of 3 or more dimensions') + return split(ary, indices_or_sections, 2) + +def get_array_prepare(*args): + """Find the wrapper for the array with the highest priority. + + In case of ties, leftmost wins. If no wrapper is found, return None + """ + wrappers = sorted((getattr(x, '__array_priority__', 0), -i, + x.__array_prepare__) for i, x in enumerate(args) + if hasattr(x, '__array_prepare__')) + if wrappers: + return wrappers[-1][-1] + return None + +def get_array_wrap(*args): + """Find the wrapper for the array with the highest priority. + + In case of ties, leftmost wins. If no wrapper is found, return None + """ + wrappers = sorted((getattr(x, '__array_priority__', 0), -i, + x.__array_wrap__) for i, x in enumerate(args) + if hasattr(x, '__array_wrap__')) + if wrappers: + return wrappers[-1][-1] + return None + + +def _kron_dispatcher(a, b): + return (a, b) + + +@array_function_dispatch(_kron_dispatcher) +def kron(a, b): + """ + Kronecker product of two arrays. + + Computes the Kronecker product, a composite array made of blocks of the + second array scaled by the first. + + Parameters + ---------- + a, b : array_like + + Returns + ------- + out : ndarray + + See Also + -------- + outer : The outer product + + Notes + ----- + The function assumes that the number of dimensions of `a` and `b` + are the same, if necessary prepending the smallest with ones. + If `a.shape = (r0,r1,..,rN)` and `b.shape = (s0,s1,...,sN)`, + the Kronecker product has shape `(r0*s0, r1*s1, ..., rN*SN)`. + The elements are products of elements from `a` and `b`, organized + explicitly by:: + + kron(a,b)[k0,k1,...,kN] = a[i0,i1,...,iN] * b[j0,j1,...,jN] + + where:: + + kt = it * st + jt, t = 0,...,N + + In the common 2-D case (N=1), the block structure can be visualized:: + + [[ a[0,0]*b, a[0,1]*b, ... , a[0,-1]*b ], + [ ... ... ], + [ a[-1,0]*b, a[-1,1]*b, ... , a[-1,-1]*b ]] + + + Examples + -------- + >>> np.kron([1,10,100], [5,6,7]) + array([ 5, 6, 7, ..., 500, 600, 700]) + >>> np.kron([5,6,7], [1,10,100]) + array([ 5, 50, 500, ..., 7, 70, 700]) + + >>> np.kron(np.eye(2), np.ones((2,2))) + array([[1., 1., 0., 0.], + [1., 1., 0., 0.], + [0., 0., 1., 1.], + [0., 0., 1., 1.]]) + + >>> a = np.arange(100).reshape((2,5,2,5)) + >>> b = np.arange(24).reshape((2,3,4)) + >>> c = np.kron(a,b) + >>> c.shape + (2, 10, 6, 20) + >>> I = (1,3,0,2) + >>> J = (0,2,1) + >>> J1 = (0,) + J # extend to ndim=4 + >>> S1 = (1,) + b.shape + >>> K = tuple(np.array(I) * np.array(S1) + np.array(J1)) + >>> c[K] == a[I]*b[J] + True + + """ + b = asanyarray(b) + a = array(a, copy=False, subok=True, ndmin=b.ndim) + ndb, nda = b.ndim, a.ndim + if (nda == 0 or ndb == 0): + return _nx.multiply(a, b) + as_ = a.shape + bs = b.shape + if not a.flags.contiguous: + a = reshape(a, as_) + if not b.flags.contiguous: + b = reshape(b, bs) + nd = ndb + if (ndb != nda): + if (ndb > nda): + as_ = (1,)*(ndb-nda) + as_ + else: + bs = (1,)*(nda-ndb) + bs + nd = nda + result = outer(a, b).reshape(as_+bs) + axis = nd-1 + for _ in range(nd): + result = concatenate(result, axis=axis) + wrapper = get_array_prepare(a, b) + if wrapper is not None: + result = wrapper(result) + wrapper = get_array_wrap(a, b) + if wrapper is not None: + result = wrapper(result) + return result + + +def _tile_dispatcher(A, reps): + return (A, reps) + + +@array_function_dispatch(_tile_dispatcher) +def tile(A, reps): + """ + Construct an array by repeating A the number of times given by reps. + + If `reps` has length ``d``, the result will have dimension of + ``max(d, A.ndim)``. + + If ``A.ndim < d``, `A` is promoted to be d-dimensional by prepending new + axes. So a shape (3,) array is promoted to (1, 3) for 2-D replication, + or shape (1, 1, 3) for 3-D replication. If this is not the desired + behavior, promote `A` to d-dimensions manually before calling this + function. + + If ``A.ndim > d``, `reps` is promoted to `A`.ndim by pre-pending 1's to it. + Thus for an `A` of shape (2, 3, 4, 5), a `reps` of (2, 2) is treated as + (1, 1, 2, 2). + + Note : Although tile may be used for broadcasting, it is strongly + recommended to use numpy's broadcasting operations and functions. + + Parameters + ---------- + A : array_like + The input array. + reps : array_like + The number of repetitions of `A` along each axis. + + Returns + ------- + c : ndarray + The tiled output array. + + See Also + -------- + repeat : Repeat elements of an array. + broadcast_to : Broadcast an array to a new shape + + Examples + -------- + >>> a = np.array([0, 1, 2]) + >>> np.tile(a, 2) + array([0, 1, 2, 0, 1, 2]) + >>> np.tile(a, (2, 2)) + array([[0, 1, 2, 0, 1, 2], + [0, 1, 2, 0, 1, 2]]) + >>> np.tile(a, (2, 1, 2)) + array([[[0, 1, 2, 0, 1, 2]], + [[0, 1, 2, 0, 1, 2]]]) + + >>> b = np.array([[1, 2], [3, 4]]) + >>> np.tile(b, 2) + array([[1, 2, 1, 2], + [3, 4, 3, 4]]) + >>> np.tile(b, (2, 1)) + array([[1, 2], + [3, 4], + [1, 2], + [3, 4]]) + + >>> c = np.array([1,2,3,4]) + >>> np.tile(c,(4,1)) + array([[1, 2, 3, 4], + [1, 2, 3, 4], + [1, 2, 3, 4], + [1, 2, 3, 4]]) + """ + try: + tup = tuple(reps) + except TypeError: + tup = (reps,) + d = len(tup) + if all(x == 1 for x in tup) and isinstance(A, _nx.ndarray): + # Fixes the problem that the function does not make a copy if A is a + # numpy array and the repetitions are 1 in all dimensions + return _nx.array(A, copy=True, subok=True, ndmin=d) + else: + # Note that no copy of zero-sized arrays is made. However since they + # have no data there is no risk of an inadvertent overwrite. + c = _nx.array(A, copy=False, subok=True, ndmin=d) + if (d < c.ndim): + tup = (1,)*(c.ndim-d) + tup + shape_out = tuple(s*t for s, t in zip(c.shape, tup)) + n = c.size + if n > 0: + for dim_in, nrep in zip(c.shape, tup): + if nrep != 1: + c = c.reshape(-1, n).repeat(nrep, 0) + n //= dim_in + return c.reshape(shape_out) diff --git a/venv/Lib/site-packages/numpy/lib/stride_tricks.py b/venv/Lib/site-packages/numpy/lib/stride_tricks.py new file mode 100644 index 0000000..82c8a57 --- /dev/null +++ b/venv/Lib/site-packages/numpy/lib/stride_tricks.py @@ -0,0 +1,545 @@ +""" +Utilities that manipulate strides to achieve desirable effects. + +An explanation of strides can be found in the "ndarray.rst" file in the +NumPy reference guide. + +""" +import numpy as np +from numpy.core.numeric import normalize_axis_tuple +from numpy.core.overrides import array_function_dispatch, set_module + +__all__ = ['broadcast_to', 'broadcast_arrays', 'broadcast_shapes'] + + +class DummyArray: + """Dummy object that just exists to hang __array_interface__ dictionaries + and possibly keep alive a reference to a base array. + """ + + def __init__(self, interface, base=None): + self.__array_interface__ = interface + self.base = base + + +def _maybe_view_as_subclass(original_array, new_array): + if type(original_array) is not type(new_array): + # if input was an ndarray subclass and subclasses were OK, + # then view the result as that subclass. + new_array = new_array.view(type=type(original_array)) + # Since we have done something akin to a view from original_array, we + # should let the subclass finalize (if it has it implemented, i.e., is + # not None). + if new_array.__array_finalize__: + new_array.__array_finalize__(original_array) + return new_array + + +def as_strided(x, shape=None, strides=None, subok=False, writeable=True): + """ + Create a view into the array with the given shape and strides. + + .. warning:: This function has to be used with extreme care, see notes. + + Parameters + ---------- + x : ndarray + Array to create a new. + shape : sequence of int, optional + The shape of the new array. Defaults to ``x.shape``. + strides : sequence of int, optional + The strides of the new array. Defaults to ``x.strides``. + subok : bool, optional + .. versionadded:: 1.10 + + If True, subclasses are preserved. + writeable : bool, optional + .. versionadded:: 1.12 + + If set to False, the returned array will always be readonly. + Otherwise it will be writable if the original array was. It + is advisable to set this to False if possible (see Notes). + + Returns + ------- + view : ndarray + + See also + -------- + broadcast_to : broadcast an array to a given shape. + reshape : reshape an array. + lib.stride_tricks.sliding_window_view : + userfriendly and safe function for the creation of sliding window views. + + Notes + ----- + ``as_strided`` creates a view into the array given the exact strides + and shape. This means it manipulates the internal data structure of + ndarray and, if done incorrectly, the array elements can point to + invalid memory and can corrupt results or crash your program. + It is advisable to always use the original ``x.strides`` when + calculating new strides to avoid reliance on a contiguous memory + layout. + + Furthermore, arrays created with this function often contain self + overlapping memory, so that two elements are identical. + Vectorized write operations on such arrays will typically be + unpredictable. They may even give different results for small, large, + or transposed arrays. + Since writing to these arrays has to be tested and done with great + care, you may want to use ``writeable=False`` to avoid accidental write + operations. + + For these reasons it is advisable to avoid ``as_strided`` when + possible. + """ + # first convert input to array, possibly keeping subclass + x = np.array(x, copy=False, subok=subok) + interface = dict(x.__array_interface__) + if shape is not None: + interface['shape'] = tuple(shape) + if strides is not None: + interface['strides'] = tuple(strides) + + array = np.asarray(DummyArray(interface, base=x)) + # The route via `__interface__` does not preserve structured + # dtypes. Since dtype should remain unchanged, we set it explicitly. + array.dtype = x.dtype + + view = _maybe_view_as_subclass(x, array) + + if view.flags.writeable and not writeable: + view.flags.writeable = False + + return view + + +def _sliding_window_view_dispatcher(x, window_shape, axis=None, *, + subok=None, writeable=None): + return (x,) + + +@array_function_dispatch(_sliding_window_view_dispatcher) +def sliding_window_view(x, window_shape, axis=None, *, + subok=False, writeable=False): + """ + Create a sliding window view into the array with the given window shape. + + Also known as rolling or moving window, the window slides across all + dimensions of the array and extracts subsets of the array at all window + positions. + + .. versionadded:: 1.20.0 + + Parameters + ---------- + x : array_like + Array to create the sliding window view from. + window_shape : int or tuple of int + Size of window over each axis that takes part in the sliding window. + If `axis` is not present, must have same length as the number of input + array dimensions. Single integers `i` are treated as if they were the + tuple `(i,)`. + axis : int or tuple of int, optional + Axis or axes along which the sliding window is applied. + By default, the sliding window is applied to all axes and + `window_shape[i]` will refer to axis `i` of `x`. + If `axis` is given as a `tuple of int`, `window_shape[i]` will refer to + the axis `axis[i]` of `x`. + Single integers `i` are treated as if they were the tuple `(i,)`. + subok : bool, optional + If True, sub-classes will be passed-through, otherwise the returned + array will be forced to be a base-class array (default). + writeable : bool, optional + When true, allow writing to the returned view. The default is false, + as this should be used with caution: the returned view contains the + same memory location multiple times, so writing to one location will + cause others to change. + + Returns + ------- + view : ndarray + Sliding window view of the array. The sliding window dimensions are + inserted at the end, and the original dimensions are trimmed as + required by the size of the sliding window. + That is, ``view.shape = x_shape_trimmed + window_shape``, where + ``x_shape_trimmed`` is ``x.shape`` with every entry reduced by one less + than the corresponding window size. + + See Also + -------- + lib.stride_tricks.as_strided: A lower-level and less safe routine for + creating arbitrary views from custom shape and strides. + broadcast_to: broadcast an array to a given shape. + + Notes + ----- + For many applications using a sliding window view can be convenient, but + potentially very slow. Often specialized solutions exist, for example: + + - `scipy.signal.fftconvolve` + + - filtering functions in `scipy.ndimage` + + - moving window functions provided by + `bottleneck `_. + + As a rough estimate, a sliding window approach with an input size of `N` + and a window size of `W` will scale as `O(N*W)` where frequently a special + algorithm can achieve `O(N)`. That means that the sliding window variant + for a window size of 100 can be a 100 times slower than a more specialized + version. + + Nevertheless, for small window sizes, when no custom algorithm exists, or + as a prototyping and developing tool, this function can be a good solution. + + Examples + -------- + >>> x = np.arange(6) + >>> x.shape + (6,) + >>> v = sliding_window_view(x, 3) + >>> v.shape + (4, 3) + >>> v + array([[0, 1, 2], + [1, 2, 3], + [2, 3, 4], + [3, 4, 5]]) + + This also works in more dimensions, e.g. + + >>> i, j = np.ogrid[:3, :4] + >>> x = 10*i + j + >>> x.shape + (3, 4) + >>> x + array([[ 0, 1, 2, 3], + [10, 11, 12, 13], + [20, 21, 22, 23]]) + >>> shape = (2,2) + >>> v = sliding_window_view(x, shape) + >>> v.shape + (2, 3, 2, 2) + >>> v + array([[[[ 0, 1], + [10, 11]], + [[ 1, 2], + [11, 12]], + [[ 2, 3], + [12, 13]]], + [[[10, 11], + [20, 21]], + [[11, 12], + [21, 22]], + [[12, 13], + [22, 23]]]]) + + The axis can be specified explicitly: + + >>> v = sliding_window_view(x, 3, 0) + >>> v.shape + (1, 4, 3) + >>> v + array([[[ 0, 10, 20], + [ 1, 11, 21], + [ 2, 12, 22], + [ 3, 13, 23]]]) + + The same axis can be used several times. In that case, every use reduces + the corresponding original dimension: + + >>> v = sliding_window_view(x, (2, 3), (1, 1)) + >>> v.shape + (3, 1, 2, 3) + >>> v + array([[[[ 0, 1, 2], + [ 1, 2, 3]]], + [[[10, 11, 12], + [11, 12, 13]]], + [[[20, 21, 22], + [21, 22, 23]]]]) + + Combining with stepped slicing (`::step`), this can be used to take sliding + views which skip elements: + + >>> x = np.arange(7) + >>> sliding_window_view(x, 5)[:, ::2] + array([[0, 2, 4], + [1, 3, 5], + [2, 4, 6]]) + + or views which move by multiple elements + + >>> x = np.arange(7) + >>> sliding_window_view(x, 3)[::2, :] + array([[0, 1, 2], + [2, 3, 4], + [4, 5, 6]]) + + A common application of `sliding_window_view` is the calculation of running + statistics. The simplest example is the + `moving average `_: + + >>> x = np.arange(6) + >>> x.shape + (6,) + >>> v = sliding_window_view(x, 3) + >>> v.shape + (4, 3) + >>> v + array([[0, 1, 2], + [1, 2, 3], + [2, 3, 4], + [3, 4, 5]]) + >>> moving_average = v.mean(axis=-1) + >>> moving_average + array([1., 2., 3., 4.]) + + Note that a sliding window approach is often **not** optimal (see Notes). + """ + window_shape = (tuple(window_shape) + if np.iterable(window_shape) + else (window_shape,)) + # first convert input to array, possibly keeping subclass + x = np.array(x, copy=False, subok=subok) + + window_shape_array = np.array(window_shape) + if np.any(window_shape_array < 0): + raise ValueError('`window_shape` cannot contain negative values') + + if axis is None: + axis = tuple(range(x.ndim)) + if len(window_shape) != len(axis): + raise ValueError(f'Since axis is `None`, must provide ' + f'window_shape for all dimensions of `x`; ' + f'got {len(window_shape)} window_shape elements ' + f'and `x.ndim` is {x.ndim}.') + else: + axis = normalize_axis_tuple(axis, x.ndim, allow_duplicate=True) + if len(window_shape) != len(axis): + raise ValueError(f'Must provide matching length window_shape and ' + f'axis; got {len(window_shape)} window_shape ' + f'elements and {len(axis)} axes elements.') + + out_strides = x.strides + tuple(x.strides[ax] for ax in axis) + + # note: same axis can be windowed repeatedly + x_shape_trimmed = list(x.shape) + for ax, dim in zip(axis, window_shape): + if x_shape_trimmed[ax] < dim: + raise ValueError( + 'window shape cannot be larger than input array shape') + x_shape_trimmed[ax] -= dim - 1 + out_shape = tuple(x_shape_trimmed) + window_shape + return as_strided(x, strides=out_strides, shape=out_shape, + subok=subok, writeable=writeable) + + +def _broadcast_to(array, shape, subok, readonly): + shape = tuple(shape) if np.iterable(shape) else (shape,) + array = np.array(array, copy=False, subok=subok) + if not shape and array.shape: + raise ValueError('cannot broadcast a non-scalar to a scalar array') + if any(size < 0 for size in shape): + raise ValueError('all elements of broadcast shape must be non-' + 'negative') + extras = [] + it = np.nditer( + (array,), flags=['multi_index', 'refs_ok', 'zerosize_ok'] + extras, + op_flags=['readonly'], itershape=shape, order='C') + with it: + # never really has writebackifcopy semantics + broadcast = it.itviews[0] + result = _maybe_view_as_subclass(array, broadcast) + # In a future version this will go away + if not readonly and array.flags._writeable_no_warn: + result.flags.writeable = True + result.flags._warn_on_write = True + return result + + +def _broadcast_to_dispatcher(array, shape, subok=None): + return (array,) + + +@array_function_dispatch(_broadcast_to_dispatcher, module='numpy') +def broadcast_to(array, shape, subok=False): + """Broadcast an array to a new shape. + + Parameters + ---------- + array : array_like + The array to broadcast. + shape : tuple + The shape of the desired array. + subok : bool, optional + If True, then sub-classes will be passed-through, otherwise + the returned array will be forced to be a base-class array (default). + + Returns + ------- + broadcast : array + A readonly view on the original array with the given shape. It is + typically not contiguous. Furthermore, more than one element of a + broadcasted array may refer to a single memory location. + + Raises + ------ + ValueError + If the array is not compatible with the new shape according to NumPy's + broadcasting rules. + + See Also + -------- + broadcast + broadcast_arrays + broadcast_shapes + + Notes + ----- + .. versionadded:: 1.10.0 + + Examples + -------- + >>> x = np.array([1, 2, 3]) + >>> np.broadcast_to(x, (3, 3)) + array([[1, 2, 3], + [1, 2, 3], + [1, 2, 3]]) + """ + return _broadcast_to(array, shape, subok=subok, readonly=True) + + +def _broadcast_shape(*args): + """Returns the shape of the arrays that would result from broadcasting the + supplied arrays against each other. + """ + # use the old-iterator because np.nditer does not handle size 0 arrays + # consistently + b = np.broadcast(*args[:32]) + # unfortunately, it cannot handle 32 or more arguments directly + for pos in range(32, len(args), 31): + # ironically, np.broadcast does not properly handle np.broadcast + # objects (it treats them as scalars) + # use broadcasting to avoid allocating the full array + b = broadcast_to(0, b.shape) + b = np.broadcast(b, *args[pos:(pos + 31)]) + return b.shape + + +@set_module('numpy') +def broadcast_shapes(*args): + """ + Broadcast the input shapes into a single shape. + + :ref:`Learn more about broadcasting here `. + + .. versionadded:: 1.20.0 + + Parameters + ---------- + `*args` : tuples of ints, or ints + The shapes to be broadcast against each other. + + Returns + ------- + tuple + Broadcasted shape. + + Raises + ------ + ValueError + If the shapes are not compatible and cannot be broadcast according + to NumPy's broadcasting rules. + + See Also + -------- + broadcast + broadcast_arrays + broadcast_to + + Examples + -------- + >>> np.broadcast_shapes((1, 2), (3, 1), (3, 2)) + (3, 2) + + >>> np.broadcast_shapes((6, 7), (5, 6, 1), (7,), (5, 1, 7)) + (5, 6, 7) + """ + arrays = [np.empty(x, dtype=[]) for x in args] + return _broadcast_shape(*arrays) + + +def _broadcast_arrays_dispatcher(*args, subok=None): + return args + + +@array_function_dispatch(_broadcast_arrays_dispatcher, module='numpy') +def broadcast_arrays(*args, subok=False): + """ + Broadcast any number of arrays against each other. + + Parameters + ---------- + `*args` : array_likes + The arrays to broadcast. + + subok : bool, optional + If True, then sub-classes will be passed-through, otherwise + the returned arrays will be forced to be a base-class array (default). + + Returns + ------- + broadcasted : list of arrays + These arrays are views on the original arrays. They are typically + not contiguous. Furthermore, more than one element of a + broadcasted array may refer to a single memory location. If you need + to write to the arrays, make copies first. While you can set the + ``writable`` flag True, writing to a single output value may end up + changing more than one location in the output array. + + .. deprecated:: 1.17 + The output is currently marked so that if written to, a deprecation + warning will be emitted. A future version will set the + ``writable`` flag False so writing to it will raise an error. + + See Also + -------- + broadcast + broadcast_to + broadcast_shapes + + Examples + -------- + >>> x = np.array([[1,2,3]]) + >>> y = np.array([[4],[5]]) + >>> np.broadcast_arrays(x, y) + [array([[1, 2, 3], + [1, 2, 3]]), array([[4, 4, 4], + [5, 5, 5]])] + + Here is a useful idiom for getting contiguous copies instead of + non-contiguous views. + + >>> [np.array(a) for a in np.broadcast_arrays(x, y)] + [array([[1, 2, 3], + [1, 2, 3]]), array([[4, 4, 4], + [5, 5, 5]])] + + """ + # nditer is not used here to avoid the limit of 32 arrays. + # Otherwise, something like the following one-liner would suffice: + # return np.nditer(args, flags=['multi_index', 'zerosize_ok'], + # order='C').itviews + + args = [np.array(_m, copy=False, subok=subok) for _m in args] + + shape = _broadcast_shape(*args) + + if all(array.shape == shape for array in args): + # Common case where nothing needs to be broadcasted. + return args + + return [_broadcast_to(array, shape, subok=subok, readonly=False) + for array in args] diff --git a/venv/Lib/site-packages/numpy/lib/tests/__init__.py b/venv/Lib/site-packages/numpy/lib/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/venv/Lib/site-packages/numpy/lib/tests/data/py2-objarr.npy b/venv/Lib/site-packages/numpy/lib/tests/data/py2-objarr.npy new file mode 100644 index 0000000000000000000000000000000000000000..12936c92d8f8a122f2342a7782f56e7506010c40 GIT binary patch literal 258 zcmbR27wQ`j$;jZwP_3SlTAW;@Zl$1J<8Ps^qoAIaUsO_*m=~X4l#&V(cT3DEP6dh= zXCxM+0{I#yI+{8PwF*dptAQywuQa!yQZG5bC{-`FG^Zppv8X7qk}JL_H90@8xTL5w zxrD2b5u%DKF9jl7$mGq?8p@c|9#qJz;mzpH(h60OQc_uv%2mh`%H(h1&EU-lRKTj? z%^b>D=)`A5Xs2k#!#)El3JWxq;934 zUgK|}uA`uymS0p-l$aNvUzCyx5_e0?DNY577iT0EqyqUGCOVor3bhJIfUAKiIj=Og zpi(b6zbI8Nw=}0DGqI>Bv63skC^b1huehYBG`WPUkP)JaD=!5iTgc?i&>G5^)E-pG ztl`b*&C&{0kWx}vkjhoa63XOn;mzR92voqT;msV%SmWpC=k*^5z=XGbNm6HQA)AI@ za(sMJX(rIxy!d#o3ZV1Tf!f(4*nl2>+Oq0J=lVj9P_`#KdOY;m z(`pL&{rvpA{sRG+@U|~06iDifEfm!7OOB6ED$N8sIxjw+s{-ixbf95EV9TGjta{P8 qzEC)WIf4gh_TeRmb{y(Gyy8&jq4k9#89+CQ1{I2>mK2I7=>Y(pm~NQ> literal 0 HcmV?d00001 diff --git a/venv/Lib/site-packages/numpy/lib/tests/data/py3-objarr.npz b/venv/Lib/site-packages/numpy/lib/tests/data/py3-objarr.npz new file mode 100644 index 0000000000000000000000000000000000000000..05eac0b76d8a034ffa25a9af78d12a85d5d99d0f GIT binary patch literal 449 zcmWIWW@Zs#009NYbhnl7|EvjRWMBYcR-jmgUS2`vWWP|~fJjCLH->8Ul+@znB6TYT z^%{Q*bsYuuwEUuyqQt!T{Gyapkhoi7PH`$wyf`DVAQi~hFwxP}QK(fw0$dGD$$6!@ z1(kZq`9-OExurQJnTbV3iIrUOMXAa8dBr6~rO72+g$xi?TzM%F*+NEdhSox+fhzn`C<*MA@Y6W;bEg#t;Pv4w&f ze#!CiNu`-UN9V=Ib5#I6pAIxk2yFS&mQ^o0*B1(BFh}qJ%|5*3(2hgBhgTfxJhZ-0 zBm?Ls(V#-H)RIE+B)tG{MkWzv+#wIt4h9X4APO800p6@2A2Kikp)p7h 2**32 + assert_equal(converter.upgrade('17179869184'), 17179869184) + assert_equal(converter._status, 1 + status_offset) + + # test float + assert_allclose(converter.upgrade('0.'), 0.0) + assert_equal(converter._status, 2 + status_offset) + + # test complex + assert_equal(converter.upgrade('0j'), complex('0j')) + assert_equal(converter._status, 3 + status_offset) + + # test str + # note that the longdouble type has been skipped, so the + # _status increases by 2. Everything should succeed with + # unicode conversion (8). + for s in ['a', b'a']: + res = converter.upgrade(s) + assert_(type(res) is str) + assert_equal(res, 'a') + assert_equal(converter._status, 8 + status_offset) + + def test_missing(self): + "Tests the use of missing values." + converter = StringConverter(missing_values=('missing', + 'missed')) + converter.upgrade('0') + assert_equal(converter('0'), 0) + assert_equal(converter(''), converter.default) + assert_equal(converter('missing'), converter.default) + assert_equal(converter('missed'), converter.default) + try: + converter('miss') + except ValueError: + pass + + def test_upgrademapper(self): + "Tests updatemapper" + dateparser = _bytes_to_date + _original_mapper = StringConverter._mapper[:] + try: + StringConverter.upgrade_mapper(dateparser, date(2000, 1, 1)) + convert = StringConverter(dateparser, date(2000, 1, 1)) + test = convert('2001-01-01') + assert_equal(test, date(2001, 1, 1)) + test = convert('2009-01-01') + assert_equal(test, date(2009, 1, 1)) + test = convert('') + assert_equal(test, date(2000, 1, 1)) + finally: + StringConverter._mapper = _original_mapper + + def test_string_to_object(self): + "Make sure that string-to-object functions are properly recognized" + old_mapper = StringConverter._mapper[:] # copy of list + conv = StringConverter(_bytes_to_date) + assert_equal(conv._mapper, old_mapper) + assert_(hasattr(conv, 'default')) + + def test_keep_default(self): + "Make sure we don't lose an explicit default" + converter = StringConverter(None, missing_values='', + default=-999) + converter.upgrade('3.14159265') + assert_equal(converter.default, -999) + assert_equal(converter.type, np.dtype(float)) + # + converter = StringConverter( + None, missing_values='', default=0) + converter.upgrade('3.14159265') + assert_equal(converter.default, 0) + assert_equal(converter.type, np.dtype(float)) + + def test_keep_default_zero(self): + "Check that we don't lose a default of 0" + converter = StringConverter(int, default=0, + missing_values="N/A") + assert_equal(converter.default, 0) + + def test_keep_missing_values(self): + "Check that we're not losing missing values" + converter = StringConverter(int, default=0, + missing_values="N/A") + assert_equal( + converter.missing_values, {'', 'N/A'}) + + def test_int64_dtype(self): + "Check that int64 integer types can be specified" + converter = StringConverter(np.int64, default=0) + val = "-9223372036854775807" + assert_(converter(val) == -9223372036854775807) + val = "9223372036854775807" + assert_(converter(val) == 9223372036854775807) + + def test_uint64_dtype(self): + "Check that uint64 integer types can be specified" + converter = StringConverter(np.uint64, default=0) + val = "9223372043271415339" + assert_(converter(val) == 9223372043271415339) + + +class TestMiscFunctions: + + def test_has_nested_dtype(self): + "Test has_nested_dtype" + ndtype = np.dtype(float) + assert_equal(has_nested_fields(ndtype), False) + ndtype = np.dtype([('A', '|S3'), ('B', float)]) + assert_equal(has_nested_fields(ndtype), False) + ndtype = np.dtype([('A', int), ('B', [('BA', float), ('BB', '|S1')])]) + assert_equal(has_nested_fields(ndtype), True) + + def test_easy_dtype(self): + "Test ndtype on dtypes" + # Simple case + ndtype = float + assert_equal(easy_dtype(ndtype), np.dtype(float)) + # As string w/o names + ndtype = "i4, f8" + assert_equal(easy_dtype(ndtype), + np.dtype([('f0', "i4"), ('f1', "f8")])) + # As string w/o names but different default format + assert_equal(easy_dtype(ndtype, defaultfmt="field_%03i"), + np.dtype([('field_000', "i4"), ('field_001', "f8")])) + # As string w/ names + ndtype = "i4, f8" + assert_equal(easy_dtype(ndtype, names="a, b"), + np.dtype([('a', "i4"), ('b', "f8")])) + # As string w/ names (too many) + ndtype = "i4, f8" + assert_equal(easy_dtype(ndtype, names="a, b, c"), + np.dtype([('a', "i4"), ('b', "f8")])) + # As string w/ names (not enough) + ndtype = "i4, f8" + assert_equal(easy_dtype(ndtype, names=", b"), + np.dtype([('f0', "i4"), ('b', "f8")])) + # ... (with different default format) + assert_equal(easy_dtype(ndtype, names="a", defaultfmt="f%02i"), + np.dtype([('a', "i4"), ('f00', "f8")])) + # As list of tuples w/o names + ndtype = [('A', int), ('B', float)] + assert_equal(easy_dtype(ndtype), np.dtype([('A', int), ('B', float)])) + # As list of tuples w/ names + assert_equal(easy_dtype(ndtype, names="a,b"), + np.dtype([('a', int), ('b', float)])) + # As list of tuples w/ not enough names + assert_equal(easy_dtype(ndtype, names="a"), + np.dtype([('a', int), ('f0', float)])) + # As list of tuples w/ too many names + assert_equal(easy_dtype(ndtype, names="a,b,c"), + np.dtype([('a', int), ('b', float)])) + # As list of types w/o names + ndtype = (int, float, float) + assert_equal(easy_dtype(ndtype), + np.dtype([('f0', int), ('f1', float), ('f2', float)])) + # As list of types w names + ndtype = (int, float, float) + assert_equal(easy_dtype(ndtype, names="a, b, c"), + np.dtype([('a', int), ('b', float), ('c', float)])) + # As simple dtype w/ names + ndtype = np.dtype(float) + assert_equal(easy_dtype(ndtype, names="a, b, c"), + np.dtype([(_, float) for _ in ('a', 'b', 'c')])) + # As simple dtype w/o names (but multiple fields) + ndtype = np.dtype(float) + assert_equal( + easy_dtype(ndtype, names=['', '', ''], defaultfmt="f%02i"), + np.dtype([(_, float) for _ in ('f00', 'f01', 'f02')])) + + def test_flatten_dtype(self): + "Testing flatten_dtype" + # Standard dtype + dt = np.dtype([("a", "f8"), ("b", "f8")]) + dt_flat = flatten_dtype(dt) + assert_equal(dt_flat, [float, float]) + # Recursive dtype + dt = np.dtype([("a", [("aa", '|S1'), ("ab", '|S2')]), ("b", int)]) + dt_flat = flatten_dtype(dt) + assert_equal(dt_flat, [np.dtype('|S1'), np.dtype('|S2'), int]) + # dtype with shaped fields + dt = np.dtype([("a", (float, 2)), ("b", (int, 3))]) + dt_flat = flatten_dtype(dt) + assert_equal(dt_flat, [float, int]) + dt_flat = flatten_dtype(dt, True) + assert_equal(dt_flat, [float] * 2 + [int] * 3) + # dtype w/ titles + dt = np.dtype([(("a", "A"), "f8"), (("b", "B"), "f8")]) + dt_flat = flatten_dtype(dt) + assert_equal(dt_flat, [float, float]) diff --git a/venv/Lib/site-packages/numpy/lib/tests/test__version.py b/venv/Lib/site-packages/numpy/lib/tests/test__version.py new file mode 100644 index 0000000..1825046 --- /dev/null +++ b/venv/Lib/site-packages/numpy/lib/tests/test__version.py @@ -0,0 +1,64 @@ +"""Tests for the NumpyVersion class. + +""" +from numpy.testing import assert_, assert_raises +from numpy.lib import NumpyVersion + + +def test_main_versions(): + assert_(NumpyVersion('1.8.0') == '1.8.0') + for ver in ['1.9.0', '2.0.0', '1.8.1']: + assert_(NumpyVersion('1.8.0') < ver) + + for ver in ['1.7.0', '1.7.1', '0.9.9']: + assert_(NumpyVersion('1.8.0') > ver) + + +def test_version_1_point_10(): + # regression test for gh-2998. + assert_(NumpyVersion('1.9.0') < '1.10.0') + assert_(NumpyVersion('1.11.0') < '1.11.1') + assert_(NumpyVersion('1.11.0') == '1.11.0') + assert_(NumpyVersion('1.99.11') < '1.99.12') + + +def test_alpha_beta_rc(): + assert_(NumpyVersion('1.8.0rc1') == '1.8.0rc1') + for ver in ['1.8.0', '1.8.0rc2']: + assert_(NumpyVersion('1.8.0rc1') < ver) + + for ver in ['1.8.0a2', '1.8.0b3', '1.7.2rc4']: + assert_(NumpyVersion('1.8.0rc1') > ver) + + assert_(NumpyVersion('1.8.0b1') > '1.8.0a2') + + +def test_dev_version(): + assert_(NumpyVersion('1.9.0.dev-Unknown') < '1.9.0') + for ver in ['1.9.0', '1.9.0a1', '1.9.0b2', '1.9.0b2.dev-ffffffff']: + assert_(NumpyVersion('1.9.0.dev-f16acvda') < ver) + + assert_(NumpyVersion('1.9.0.dev-f16acvda') == '1.9.0.dev-11111111') + + +def test_dev_a_b_rc_mixed(): + assert_(NumpyVersion('1.9.0a2.dev-f16acvda') == '1.9.0a2.dev-11111111') + assert_(NumpyVersion('1.9.0a2.dev-6acvda54') < '1.9.0a2') + + +def test_dev0_version(): + assert_(NumpyVersion('1.9.0.dev0+Unknown') < '1.9.0') + for ver in ['1.9.0', '1.9.0a1', '1.9.0b2', '1.9.0b2.dev0+ffffffff']: + assert_(NumpyVersion('1.9.0.dev0+f16acvda') < ver) + + assert_(NumpyVersion('1.9.0.dev0+f16acvda') == '1.9.0.dev0+11111111') + + +def test_dev0_a_b_rc_mixed(): + assert_(NumpyVersion('1.9.0a2.dev0+f16acvda') == '1.9.0a2.dev0+11111111') + assert_(NumpyVersion('1.9.0a2.dev0+6acvda54') < '1.9.0a2') + + +def test_raises(): + for ver in ['1.9', '1,9.0', '1.7.x']: + assert_raises(ValueError, NumpyVersion, ver) diff --git a/venv/Lib/site-packages/numpy/lib/tests/test_arraypad.py b/venv/Lib/site-packages/numpy/lib/tests/test_arraypad.py new file mode 100644 index 0000000..75db592 --- /dev/null +++ b/venv/Lib/site-packages/numpy/lib/tests/test_arraypad.py @@ -0,0 +1,1364 @@ +"""Tests for the array padding functions. + +""" +import pytest + +import numpy as np +from numpy.testing import assert_array_equal, assert_allclose, assert_equal +from numpy.lib.arraypad import _as_pairs + + +_numeric_dtypes = ( + np.sctypes["uint"] + + np.sctypes["int"] + + np.sctypes["float"] + + np.sctypes["complex"] +) +_all_modes = { + 'constant': {'constant_values': 0}, + 'edge': {}, + 'linear_ramp': {'end_values': 0}, + 'maximum': {'stat_length': None}, + 'mean': {'stat_length': None}, + 'median': {'stat_length': None}, + 'minimum': {'stat_length': None}, + 'reflect': {'reflect_type': 'even'}, + 'symmetric': {'reflect_type': 'even'}, + 'wrap': {}, + 'empty': {} +} + + +class TestAsPairs: + def test_single_value(self): + """Test casting for a single value.""" + expected = np.array([[3, 3]] * 10) + for x in (3, [3], [[3]]): + result = _as_pairs(x, 10) + assert_equal(result, expected) + # Test with dtype=object + obj = object() + assert_equal( + _as_pairs(obj, 10), + np.array([[obj, obj]] * 10) + ) + + def test_two_values(self): + """Test proper casting for two different values.""" + # Broadcasting in the first dimension with numbers + expected = np.array([[3, 4]] * 10) + for x in ([3, 4], [[3, 4]]): + result = _as_pairs(x, 10) + assert_equal(result, expected) + # and with dtype=object + obj = object() + assert_equal( + _as_pairs(["a", obj], 10), + np.array([["a", obj]] * 10) + ) + + # Broadcasting in the second / last dimension with numbers + assert_equal( + _as_pairs([[3], [4]], 2), + np.array([[3, 3], [4, 4]]) + ) + # and with dtype=object + assert_equal( + _as_pairs([["a"], [obj]], 2), + np.array([["a", "a"], [obj, obj]]) + ) + + def test_with_none(self): + expected = ((None, None), (None, None), (None, None)) + assert_equal( + _as_pairs(None, 3, as_index=False), + expected + ) + assert_equal( + _as_pairs(None, 3, as_index=True), + expected + ) + + def test_pass_through(self): + """Test if `x` already matching desired output are passed through.""" + expected = np.arange(12).reshape((6, 2)) + assert_equal( + _as_pairs(expected, 6), + expected + ) + + def test_as_index(self): + """Test results if `as_index=True`.""" + assert_equal( + _as_pairs([2.6, 3.3], 10, as_index=True), + np.array([[3, 3]] * 10, dtype=np.intp) + ) + assert_equal( + _as_pairs([2.6, 4.49], 10, as_index=True), + np.array([[3, 4]] * 10, dtype=np.intp) + ) + for x in (-3, [-3], [[-3]], [-3, 4], [3, -4], [[-3, 4]], [[4, -3]], + [[1, 2]] * 9 + [[1, -2]]): + with pytest.raises(ValueError, match="negative values"): + _as_pairs(x, 10, as_index=True) + + def test_exceptions(self): + """Ensure faulty usage is discovered.""" + with pytest.raises(ValueError, match="more dimensions than allowed"): + _as_pairs([[[3]]], 10) + with pytest.raises(ValueError, match="could not be broadcast"): + _as_pairs([[1, 2], [3, 4]], 3) + with pytest.raises(ValueError, match="could not be broadcast"): + _as_pairs(np.ones((2, 3)), 3) + + +class TestConditionalShortcuts: + @pytest.mark.parametrize("mode", _all_modes.keys()) + def test_zero_padding_shortcuts(self, mode): + test = np.arange(120).reshape(4, 5, 6) + pad_amt = [(0, 0) for _ in test.shape] + assert_array_equal(test, np.pad(test, pad_amt, mode=mode)) + + @pytest.mark.parametrize("mode", ['maximum', 'mean', 'median', 'minimum',]) + def test_shallow_statistic_range(self, mode): + test = np.arange(120).reshape(4, 5, 6) + pad_amt = [(1, 1) for _ in test.shape] + assert_array_equal(np.pad(test, pad_amt, mode='edge'), + np.pad(test, pad_amt, mode=mode, stat_length=1)) + + @pytest.mark.parametrize("mode", ['maximum', 'mean', 'median', 'minimum',]) + def test_clip_statistic_range(self, mode): + test = np.arange(30).reshape(5, 6) + pad_amt = [(3, 3) for _ in test.shape] + assert_array_equal(np.pad(test, pad_amt, mode=mode), + np.pad(test, pad_amt, mode=mode, stat_length=30)) + + +class TestStatistic: + def test_check_mean_stat_length(self): + a = np.arange(100).astype('f') + a = np.pad(a, ((25, 20), ), 'mean', stat_length=((2, 3), )) + b = np.array( + [0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, + 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, + 0.5, 0.5, 0.5, 0.5, 0.5, + + 0., 1., 2., 3., 4., 5., 6., 7., 8., 9., + 10., 11., 12., 13., 14., 15., 16., 17., 18., 19., + 20., 21., 22., 23., 24., 25., 26., 27., 28., 29., + 30., 31., 32., 33., 34., 35., 36., 37., 38., 39., + 40., 41., 42., 43., 44., 45., 46., 47., 48., 49., + 50., 51., 52., 53., 54., 55., 56., 57., 58., 59., + 60., 61., 62., 63., 64., 65., 66., 67., 68., 69., + 70., 71., 72., 73., 74., 75., 76., 77., 78., 79., + 80., 81., 82., 83., 84., 85., 86., 87., 88., 89., + 90., 91., 92., 93., 94., 95., 96., 97., 98., 99., + + 98., 98., 98., 98., 98., 98., 98., 98., 98., 98., + 98., 98., 98., 98., 98., 98., 98., 98., 98., 98. + ]) + assert_array_equal(a, b) + + def test_check_maximum_1(self): + a = np.arange(100) + a = np.pad(a, (25, 20), 'maximum') + b = np.array( + [99, 99, 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, + + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, + 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, + 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, + 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, + + 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, 99, 99] + ) + assert_array_equal(a, b) + + def test_check_maximum_2(self): + a = np.arange(100) + 1 + a = np.pad(a, (25, 20), 'maximum') + b = np.array( + [100, 100, 100, 100, 100, 100, 100, 100, 100, 100, + 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, + 100, 100, 100, 100, 100, + + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, + 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, + 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, + 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, + 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, + 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, + 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, + 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, + + 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, + 100, 100, 100, 100, 100, 100, 100, 100, 100, 100] + ) + assert_array_equal(a, b) + + def test_check_maximum_stat_length(self): + a = np.arange(100) + 1 + a = np.pad(a, (25, 20), 'maximum', stat_length=10) + b = np.array( + [10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, + + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, + 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, + 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, + 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, + 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, + 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, + 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, + 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, + + 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, + 100, 100, 100, 100, 100, 100, 100, 100, 100, 100] + ) + assert_array_equal(a, b) + + def test_check_minimum_1(self): + a = np.arange(100) + a = np.pad(a, (25, 20), 'minimum') + b = np.array( + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, + 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, + 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, + 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] + ) + assert_array_equal(a, b) + + def test_check_minimum_2(self): + a = np.arange(100) + 2 + a = np.pad(a, (25, 20), 'minimum') + b = np.array( + [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, + + 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, + 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, + 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, + 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, + 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, + 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, + 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, + 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, + + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2] + ) + assert_array_equal(a, b) + + def test_check_minimum_stat_length(self): + a = np.arange(100) + 1 + a = np.pad(a, (25, 20), 'minimum', stat_length=10) + b = np.array( + [ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, + + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, + 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, + 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, + 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, + 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, + 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, + 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, + 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, + + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91] + ) + assert_array_equal(a, b) + + def test_check_median(self): + a = np.arange(100).astype('f') + a = np.pad(a, (25, 20), 'median') + b = np.array( + [49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, + 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, + 49.5, 49.5, 49.5, 49.5, 49.5, + + 0., 1., 2., 3., 4., 5., 6., 7., 8., 9., + 10., 11., 12., 13., 14., 15., 16., 17., 18., 19., + 20., 21., 22., 23., 24., 25., 26., 27., 28., 29., + 30., 31., 32., 33., 34., 35., 36., 37., 38., 39., + 40., 41., 42., 43., 44., 45., 46., 47., 48., 49., + 50., 51., 52., 53., 54., 55., 56., 57., 58., 59., + 60., 61., 62., 63., 64., 65., 66., 67., 68., 69., + 70., 71., 72., 73., 74., 75., 76., 77., 78., 79., + 80., 81., 82., 83., 84., 85., 86., 87., 88., 89., + 90., 91., 92., 93., 94., 95., 96., 97., 98., 99., + + 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, + 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5] + ) + assert_array_equal(a, b) + + def test_check_median_01(self): + a = np.array([[3, 1, 4], [4, 5, 9], [9, 8, 2]]) + a = np.pad(a, 1, 'median') + b = np.array( + [[4, 4, 5, 4, 4], + + [3, 3, 1, 4, 3], + [5, 4, 5, 9, 5], + [8, 9, 8, 2, 8], + + [4, 4, 5, 4, 4]] + ) + assert_array_equal(a, b) + + def test_check_median_02(self): + a = np.array([[3, 1, 4], [4, 5, 9], [9, 8, 2]]) + a = np.pad(a.T, 1, 'median').T + b = np.array( + [[5, 4, 5, 4, 5], + + [3, 3, 1, 4, 3], + [5, 4, 5, 9, 5], + [8, 9, 8, 2, 8], + + [5, 4, 5, 4, 5]] + ) + assert_array_equal(a, b) + + def test_check_median_stat_length(self): + a = np.arange(100).astype('f') + a[1] = 2. + a[97] = 96. + a = np.pad(a, (25, 20), 'median', stat_length=(3, 5)) + b = np.array( + [ 2., 2., 2., 2., 2., 2., 2., 2., 2., 2., + 2., 2., 2., 2., 2., 2., 2., 2., 2., 2., + 2., 2., 2., 2., 2., + + 0., 2., 2., 3., 4., 5., 6., 7., 8., 9., + 10., 11., 12., 13., 14., 15., 16., 17., 18., 19., + 20., 21., 22., 23., 24., 25., 26., 27., 28., 29., + 30., 31., 32., 33., 34., 35., 36., 37., 38., 39., + 40., 41., 42., 43., 44., 45., 46., 47., 48., 49., + 50., 51., 52., 53., 54., 55., 56., 57., 58., 59., + 60., 61., 62., 63., 64., 65., 66., 67., 68., 69., + 70., 71., 72., 73., 74., 75., 76., 77., 78., 79., + 80., 81., 82., 83., 84., 85., 86., 87., 88., 89., + 90., 91., 92., 93., 94., 95., 96., 96., 98., 99., + + 96., 96., 96., 96., 96., 96., 96., 96., 96., 96., + 96., 96., 96., 96., 96., 96., 96., 96., 96., 96.] + ) + assert_array_equal(a, b) + + def test_check_mean_shape_one(self): + a = [[4, 5, 6]] + a = np.pad(a, (5, 7), 'mean', stat_length=2) + b = np.array( + [[4, 4, 4, 4, 4, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6], + [4, 4, 4, 4, 4, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6], + [4, 4, 4, 4, 4, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6], + [4, 4, 4, 4, 4, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6], + [4, 4, 4, 4, 4, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6], + + [4, 4, 4, 4, 4, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6], + + [4, 4, 4, 4, 4, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6], + [4, 4, 4, 4, 4, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6], + [4, 4, 4, 4, 4, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6], + [4, 4, 4, 4, 4, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6], + [4, 4, 4, 4, 4, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6], + [4, 4, 4, 4, 4, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6], + [4, 4, 4, 4, 4, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6]] + ) + assert_array_equal(a, b) + + def test_check_mean_2(self): + a = np.arange(100).astype('f') + a = np.pad(a, (25, 20), 'mean') + b = np.array( + [49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, + 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, + 49.5, 49.5, 49.5, 49.5, 49.5, + + 0., 1., 2., 3., 4., 5., 6., 7., 8., 9., + 10., 11., 12., 13., 14., 15., 16., 17., 18., 19., + 20., 21., 22., 23., 24., 25., 26., 27., 28., 29., + 30., 31., 32., 33., 34., 35., 36., 37., 38., 39., + 40., 41., 42., 43., 44., 45., 46., 47., 48., 49., + 50., 51., 52., 53., 54., 55., 56., 57., 58., 59., + 60., 61., 62., 63., 64., 65., 66., 67., 68., 69., + 70., 71., 72., 73., 74., 75., 76., 77., 78., 79., + 80., 81., 82., 83., 84., 85., 86., 87., 88., 89., + 90., 91., 92., 93., 94., 95., 96., 97., 98., 99., + + 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, + 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5] + ) + assert_array_equal(a, b) + + @pytest.mark.parametrize("mode", [ + "mean", + "median", + "minimum", + "maximum" + ]) + def test_same_prepend_append(self, mode): + """ Test that appended and prepended values are equal """ + # This test is constructed to trigger floating point rounding errors in + # a way that caused gh-11216 for mode=='mean' + a = np.array([-1, 2, -1]) + np.array([0, 1e-12, 0], dtype=np.float64) + a = np.pad(a, (1, 1), mode) + assert_equal(a[0], a[-1]) + + @pytest.mark.parametrize("mode", ["mean", "median", "minimum", "maximum"]) + @pytest.mark.parametrize( + "stat_length", [-2, (-2,), (3, -1), ((5, 2), (-2, 3)), ((-4,), (2,))] + ) + def test_check_negative_stat_length(self, mode, stat_length): + arr = np.arange(30).reshape((6, 5)) + match = "index can't contain negative values" + with pytest.raises(ValueError, match=match): + np.pad(arr, 2, mode, stat_length=stat_length) + + def test_simple_stat_length(self): + a = np.arange(30) + a = np.reshape(a, (6, 5)) + a = np.pad(a, ((2, 3), (3, 2)), mode='mean', stat_length=(3,)) + b = np.array( + [[6, 6, 6, 5, 6, 7, 8, 9, 8, 8], + [6, 6, 6, 5, 6, 7, 8, 9, 8, 8], + + [1, 1, 1, 0, 1, 2, 3, 4, 3, 3], + [6, 6, 6, 5, 6, 7, 8, 9, 8, 8], + [11, 11, 11, 10, 11, 12, 13, 14, 13, 13], + [16, 16, 16, 15, 16, 17, 18, 19, 18, 18], + [21, 21, 21, 20, 21, 22, 23, 24, 23, 23], + [26, 26, 26, 25, 26, 27, 28, 29, 28, 28], + + [21, 21, 21, 20, 21, 22, 23, 24, 23, 23], + [21, 21, 21, 20, 21, 22, 23, 24, 23, 23], + [21, 21, 21, 20, 21, 22, 23, 24, 23, 23]] + ) + assert_array_equal(a, b) + + @pytest.mark.filterwarnings("ignore:Mean of empty slice:RuntimeWarning") + @pytest.mark.filterwarnings( + "ignore:invalid value encountered in (true_divide|double_scalars):" + "RuntimeWarning" + ) + @pytest.mark.parametrize("mode", ["mean", "median"]) + def test_zero_stat_length_valid(self, mode): + arr = np.pad([1., 2.], (1, 2), mode, stat_length=0) + expected = np.array([np.nan, 1., 2., np.nan, np.nan]) + assert_equal(arr, expected) + + @pytest.mark.parametrize("mode", ["minimum", "maximum"]) + def test_zero_stat_length_invalid(self, mode): + match = "stat_length of 0 yields no value for padding" + with pytest.raises(ValueError, match=match): + np.pad([1., 2.], 0, mode, stat_length=0) + with pytest.raises(ValueError, match=match): + np.pad([1., 2.], 0, mode, stat_length=(1, 0)) + with pytest.raises(ValueError, match=match): + np.pad([1., 2.], 1, mode, stat_length=0) + with pytest.raises(ValueError, match=match): + np.pad([1., 2.], 1, mode, stat_length=(1, 0)) + + +class TestConstant: + def test_check_constant(self): + a = np.arange(100) + a = np.pad(a, (25, 20), 'constant', constant_values=(10, 20)) + b = np.array( + [10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, + + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, + 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, + 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, + 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, + + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20] + ) + assert_array_equal(a, b) + + def test_check_constant_zeros(self): + a = np.arange(100) + a = np.pad(a, (25, 20), 'constant') + b = np.array( + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, + 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, + 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, + 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] + ) + assert_array_equal(a, b) + + def test_check_constant_float(self): + # If input array is int, but constant_values are float, the dtype of + # the array to be padded is kept + arr = np.arange(30).reshape(5, 6) + test = np.pad(arr, (1, 2), mode='constant', + constant_values=1.1) + expected = np.array( + [[ 1, 1, 1, 1, 1, 1, 1, 1, 1], + + [ 1, 0, 1, 2, 3, 4, 5, 1, 1], + [ 1, 6, 7, 8, 9, 10, 11, 1, 1], + [ 1, 12, 13, 14, 15, 16, 17, 1, 1], + [ 1, 18, 19, 20, 21, 22, 23, 1, 1], + [ 1, 24, 25, 26, 27, 28, 29, 1, 1], + + [ 1, 1, 1, 1, 1, 1, 1, 1, 1], + [ 1, 1, 1, 1, 1, 1, 1, 1, 1]] + ) + assert_allclose(test, expected) + + def test_check_constant_float2(self): + # If input array is float, and constant_values are float, the dtype of + # the array to be padded is kept - here retaining the float constants + arr = np.arange(30).reshape(5, 6) + arr_float = arr.astype(np.float64) + test = np.pad(arr_float, ((1, 2), (1, 2)), mode='constant', + constant_values=1.1) + expected = np.array( + [[ 1.1, 1.1, 1.1, 1.1, 1.1, 1.1, 1.1, 1.1, 1.1], + + [ 1.1, 0. , 1. , 2. , 3. , 4. , 5. , 1.1, 1.1], + [ 1.1, 6. , 7. , 8. , 9. , 10. , 11. , 1.1, 1.1], + [ 1.1, 12. , 13. , 14. , 15. , 16. , 17. , 1.1, 1.1], + [ 1.1, 18. , 19. , 20. , 21. , 22. , 23. , 1.1, 1.1], + [ 1.1, 24. , 25. , 26. , 27. , 28. , 29. , 1.1, 1.1], + + [ 1.1, 1.1, 1.1, 1.1, 1.1, 1.1, 1.1, 1.1, 1.1], + [ 1.1, 1.1, 1.1, 1.1, 1.1, 1.1, 1.1, 1.1, 1.1]] + ) + assert_allclose(test, expected) + + def test_check_constant_float3(self): + a = np.arange(100, dtype=float) + a = np.pad(a, (25, 20), 'constant', constant_values=(-1.1, -1.2)) + b = np.array( + [-1.1, -1.1, -1.1, -1.1, -1.1, -1.1, -1.1, -1.1, -1.1, -1.1, + -1.1, -1.1, -1.1, -1.1, -1.1, -1.1, -1.1, -1.1, -1.1, -1.1, + -1.1, -1.1, -1.1, -1.1, -1.1, + + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, + 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, + 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, + 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, + + -1.2, -1.2, -1.2, -1.2, -1.2, -1.2, -1.2, -1.2, -1.2, -1.2, + -1.2, -1.2, -1.2, -1.2, -1.2, -1.2, -1.2, -1.2, -1.2, -1.2] + ) + assert_allclose(a, b) + + def test_check_constant_odd_pad_amount(self): + arr = np.arange(30).reshape(5, 6) + test = np.pad(arr, ((1,), (2,)), mode='constant', + constant_values=3) + expected = np.array( + [[ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3], + + [ 3, 3, 0, 1, 2, 3, 4, 5, 3, 3], + [ 3, 3, 6, 7, 8, 9, 10, 11, 3, 3], + [ 3, 3, 12, 13, 14, 15, 16, 17, 3, 3], + [ 3, 3, 18, 19, 20, 21, 22, 23, 3, 3], + [ 3, 3, 24, 25, 26, 27, 28, 29, 3, 3], + + [ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3]] + ) + assert_allclose(test, expected) + + def test_check_constant_pad_2d(self): + arr = np.arange(4).reshape(2, 2) + test = np.lib.pad(arr, ((1, 2), (1, 3)), mode='constant', + constant_values=((1, 2), (3, 4))) + expected = np.array( + [[3, 1, 1, 4, 4, 4], + [3, 0, 1, 4, 4, 4], + [3, 2, 3, 4, 4, 4], + [3, 2, 2, 4, 4, 4], + [3, 2, 2, 4, 4, 4]] + ) + assert_allclose(test, expected) + + def test_check_large_integers(self): + uint64_max = 2 ** 64 - 1 + arr = np.full(5, uint64_max, dtype=np.uint64) + test = np.pad(arr, 1, mode="constant", constant_values=arr.min()) + expected = np.full(7, uint64_max, dtype=np.uint64) + assert_array_equal(test, expected) + + int64_max = 2 ** 63 - 1 + arr = np.full(5, int64_max, dtype=np.int64) + test = np.pad(arr, 1, mode="constant", constant_values=arr.min()) + expected = np.full(7, int64_max, dtype=np.int64) + assert_array_equal(test, expected) + + def test_check_object_array(self): + arr = np.empty(1, dtype=object) + obj_a = object() + arr[0] = obj_a + obj_b = object() + obj_c = object() + arr = np.pad(arr, pad_width=1, mode='constant', + constant_values=(obj_b, obj_c)) + + expected = np.empty((3,), dtype=object) + expected[0] = obj_b + expected[1] = obj_a + expected[2] = obj_c + + assert_array_equal(arr, expected) + + def test_pad_empty_dimension(self): + arr = np.zeros((3, 0, 2)) + result = np.pad(arr, [(0,), (2,), (1,)], mode="constant") + assert result.shape == (3, 4, 4) + + +class TestLinearRamp: + def test_check_simple(self): + a = np.arange(100).astype('f') + a = np.pad(a, (25, 20), 'linear_ramp', end_values=(4, 5)) + b = np.array( + [4.00, 3.84, 3.68, 3.52, 3.36, 3.20, 3.04, 2.88, 2.72, 2.56, + 2.40, 2.24, 2.08, 1.92, 1.76, 1.60, 1.44, 1.28, 1.12, 0.96, + 0.80, 0.64, 0.48, 0.32, 0.16, + + 0.00, 1.00, 2.00, 3.00, 4.00, 5.00, 6.00, 7.00, 8.00, 9.00, + 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, + 20.0, 21.0, 22.0, 23.0, 24.0, 25.0, 26.0, 27.0, 28.0, 29.0, + 30.0, 31.0, 32.0, 33.0, 34.0, 35.0, 36.0, 37.0, 38.0, 39.0, + 40.0, 41.0, 42.0, 43.0, 44.0, 45.0, 46.0, 47.0, 48.0, 49.0, + 50.0, 51.0, 52.0, 53.0, 54.0, 55.0, 56.0, 57.0, 58.0, 59.0, + 60.0, 61.0, 62.0, 63.0, 64.0, 65.0, 66.0, 67.0, 68.0, 69.0, + 70.0, 71.0, 72.0, 73.0, 74.0, 75.0, 76.0, 77.0, 78.0, 79.0, + 80.0, 81.0, 82.0, 83.0, 84.0, 85.0, 86.0, 87.0, 88.0, 89.0, + 90.0, 91.0, 92.0, 93.0, 94.0, 95.0, 96.0, 97.0, 98.0, 99.0, + + 94.3, 89.6, 84.9, 80.2, 75.5, 70.8, 66.1, 61.4, 56.7, 52.0, + 47.3, 42.6, 37.9, 33.2, 28.5, 23.8, 19.1, 14.4, 9.7, 5.] + ) + assert_allclose(a, b, rtol=1e-5, atol=1e-5) + + def test_check_2d(self): + arr = np.arange(20).reshape(4, 5).astype(np.float64) + test = np.pad(arr, (2, 2), mode='linear_ramp', end_values=(0, 0)) + expected = np.array( + [[0., 0., 0., 0., 0., 0., 0., 0., 0.], + [0., 0., 0., 0.5, 1., 1.5, 2., 1., 0.], + [0., 0., 0., 1., 2., 3., 4., 2., 0.], + [0., 2.5, 5., 6., 7., 8., 9., 4.5, 0.], + [0., 5., 10., 11., 12., 13., 14., 7., 0.], + [0., 7.5, 15., 16., 17., 18., 19., 9.5, 0.], + [0., 3.75, 7.5, 8., 8.5, 9., 9.5, 4.75, 0.], + [0., 0., 0., 0., 0., 0., 0., 0., 0.]]) + assert_allclose(test, expected) + + @pytest.mark.xfail(exceptions=(AssertionError,)) + def test_object_array(self): + from fractions import Fraction + arr = np.array([Fraction(1, 2), Fraction(-1, 2)]) + actual = np.pad(arr, (2, 3), mode='linear_ramp', end_values=0) + + # deliberately chosen to have a non-power-of-2 denominator such that + # rounding to floats causes a failure. + expected = np.array([ + Fraction( 0, 12), + Fraction( 3, 12), + Fraction( 6, 12), + Fraction(-6, 12), + Fraction(-4, 12), + Fraction(-2, 12), + Fraction(-0, 12), + ]) + assert_equal(actual, expected) + + def test_end_values(self): + """Ensure that end values are exact.""" + a = np.pad(np.ones(10).reshape(2, 5), (223, 123), mode="linear_ramp") + assert_equal(a[:, 0], 0.) + assert_equal(a[:, -1], 0.) + assert_equal(a[0, :], 0.) + assert_equal(a[-1, :], 0.) + + @pytest.mark.parametrize("dtype", _numeric_dtypes) + def test_negative_difference(self, dtype): + """ + Check correct behavior of unsigned dtypes if there is a negative + difference between the edge to pad and `end_values`. Check both cases + to be independent of implementation. Test behavior for all other dtypes + in case dtype casting interferes with complex dtypes. See gh-14191. + """ + x = np.array([3], dtype=dtype) + result = np.pad(x, 3, mode="linear_ramp", end_values=0) + expected = np.array([0, 1, 2, 3, 2, 1, 0], dtype=dtype) + assert_equal(result, expected) + + x = np.array([0], dtype=dtype) + result = np.pad(x, 3, mode="linear_ramp", end_values=3) + expected = np.array([3, 2, 1, 0, 1, 2, 3], dtype=dtype) + assert_equal(result, expected) + + +class TestReflect: + def test_check_simple(self): + a = np.arange(100) + a = np.pad(a, (25, 20), 'reflect') + b = np.array( + [25, 24, 23, 22, 21, 20, 19, 18, 17, 16, + 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, + 5, 4, 3, 2, 1, + + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, + 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, + 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, + 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, + + 98, 97, 96, 95, 94, 93, 92, 91, 90, 89, + 88, 87, 86, 85, 84, 83, 82, 81, 80, 79] + ) + assert_array_equal(a, b) + + def test_check_odd_method(self): + a = np.arange(100) + a = np.pad(a, (25, 20), 'reflect', reflect_type='odd') + b = np.array( + [-25, -24, -23, -22, -21, -20, -19, -18, -17, -16, + -15, -14, -13, -12, -11, -10, -9, -8, -7, -6, + -5, -4, -3, -2, -1, + + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, + 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, + 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, + 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, + + 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, + 110, 111, 112, 113, 114, 115, 116, 117, 118, 119] + ) + assert_array_equal(a, b) + + def test_check_large_pad(self): + a = [[4, 5, 6], [6, 7, 8]] + a = np.pad(a, (5, 7), 'reflect') + b = np.array( + [[7, 6, 7, 8, 7, 6, 7, 8, 7, 6, 7, 8, 7, 6, 7], + [5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5], + [7, 6, 7, 8, 7, 6, 7, 8, 7, 6, 7, 8, 7, 6, 7], + [5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5], + [7, 6, 7, 8, 7, 6, 7, 8, 7, 6, 7, 8, 7, 6, 7], + + [5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5], + [7, 6, 7, 8, 7, 6, 7, 8, 7, 6, 7, 8, 7, 6, 7], + + [5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5], + [7, 6, 7, 8, 7, 6, 7, 8, 7, 6, 7, 8, 7, 6, 7], + [5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5], + [7, 6, 7, 8, 7, 6, 7, 8, 7, 6, 7, 8, 7, 6, 7], + [5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5], + [7, 6, 7, 8, 7, 6, 7, 8, 7, 6, 7, 8, 7, 6, 7], + [5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5]] + ) + assert_array_equal(a, b) + + def test_check_shape(self): + a = [[4, 5, 6]] + a = np.pad(a, (5, 7), 'reflect') + b = np.array( + [[5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5], + [5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5], + [5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5], + [5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5], + [5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5], + + [5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5], + + [5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5], + [5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5], + [5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5], + [5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5], + [5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5], + [5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5], + [5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5]] + ) + assert_array_equal(a, b) + + def test_check_01(self): + a = np.pad([1, 2, 3], 2, 'reflect') + b = np.array([3, 2, 1, 2, 3, 2, 1]) + assert_array_equal(a, b) + + def test_check_02(self): + a = np.pad([1, 2, 3], 3, 'reflect') + b = np.array([2, 3, 2, 1, 2, 3, 2, 1, 2]) + assert_array_equal(a, b) + + def test_check_03(self): + a = np.pad([1, 2, 3], 4, 'reflect') + b = np.array([1, 2, 3, 2, 1, 2, 3, 2, 1, 2, 3]) + assert_array_equal(a, b) + + +class TestEmptyArray: + """Check how padding behaves on arrays with an empty dimension.""" + + @pytest.mark.parametrize( + # Keep parametrization ordered, otherwise pytest-xdist might believe + # that different tests were collected during parallelization + "mode", sorted(_all_modes.keys() - {"constant", "empty"}) + ) + def test_pad_empty_dimension(self, mode): + match = ("can't extend empty axis 0 using modes other than 'constant' " + "or 'empty'") + with pytest.raises(ValueError, match=match): + np.pad([], 4, mode=mode) + with pytest.raises(ValueError, match=match): + np.pad(np.ndarray(0), 4, mode=mode) + with pytest.raises(ValueError, match=match): + np.pad(np.zeros((0, 3)), ((1,), (0,)), mode=mode) + + @pytest.mark.parametrize("mode", _all_modes.keys()) + def test_pad_non_empty_dimension(self, mode): + result = np.pad(np.ones((2, 0, 2)), ((3,), (0,), (1,)), mode=mode) + assert result.shape == (8, 0, 4) + + +class TestSymmetric: + def test_check_simple(self): + a = np.arange(100) + a = np.pad(a, (25, 20), 'symmetric') + b = np.array( + [24, 23, 22, 21, 20, 19, 18, 17, 16, 15, + 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, + 4, 3, 2, 1, 0, + + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, + 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, + 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, + 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, + + 99, 98, 97, 96, 95, 94, 93, 92, 91, 90, + 89, 88, 87, 86, 85, 84, 83, 82, 81, 80] + ) + assert_array_equal(a, b) + + def test_check_odd_method(self): + a = np.arange(100) + a = np.pad(a, (25, 20), 'symmetric', reflect_type='odd') + b = np.array( + [-24, -23, -22, -21, -20, -19, -18, -17, -16, -15, + -14, -13, -12, -11, -10, -9, -8, -7, -6, -5, + -4, -3, -2, -1, 0, + + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, + 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, + 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, + 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, + + 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, + 109, 110, 111, 112, 113, 114, 115, 116, 117, 118] + ) + assert_array_equal(a, b) + + def test_check_large_pad(self): + a = [[4, 5, 6], [6, 7, 8]] + a = np.pad(a, (5, 7), 'symmetric') + b = np.array( + [[5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6], + [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6], + [7, 8, 8, 7, 6, 6, 7, 8, 8, 7, 6, 6, 7, 8, 8], + [7, 8, 8, 7, 6, 6, 7, 8, 8, 7, 6, 6, 7, 8, 8], + [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6], + + [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6], + [7, 8, 8, 7, 6, 6, 7, 8, 8, 7, 6, 6, 7, 8, 8], + + [7, 8, 8, 7, 6, 6, 7, 8, 8, 7, 6, 6, 7, 8, 8], + [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6], + [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6], + [7, 8, 8, 7, 6, 6, 7, 8, 8, 7, 6, 6, 7, 8, 8], + [7, 8, 8, 7, 6, 6, 7, 8, 8, 7, 6, 6, 7, 8, 8], + [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6], + [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6]] + ) + + assert_array_equal(a, b) + + def test_check_large_pad_odd(self): + a = [[4, 5, 6], [6, 7, 8]] + a = np.pad(a, (5, 7), 'symmetric', reflect_type='odd') + b = np.array( + [[-3, -2, -2, -1, 0, 0, 1, 2, 2, 3, 4, 4, 5, 6, 6], + [-3, -2, -2, -1, 0, 0, 1, 2, 2, 3, 4, 4, 5, 6, 6], + [-1, 0, 0, 1, 2, 2, 3, 4, 4, 5, 6, 6, 7, 8, 8], + [-1, 0, 0, 1, 2, 2, 3, 4, 4, 5, 6, 6, 7, 8, 8], + [ 1, 2, 2, 3, 4, 4, 5, 6, 6, 7, 8, 8, 9, 10, 10], + + [ 1, 2, 2, 3, 4, 4, 5, 6, 6, 7, 8, 8, 9, 10, 10], + [ 3, 4, 4, 5, 6, 6, 7, 8, 8, 9, 10, 10, 11, 12, 12], + + [ 3, 4, 4, 5, 6, 6, 7, 8, 8, 9, 10, 10, 11, 12, 12], + [ 5, 6, 6, 7, 8, 8, 9, 10, 10, 11, 12, 12, 13, 14, 14], + [ 5, 6, 6, 7, 8, 8, 9, 10, 10, 11, 12, 12, 13, 14, 14], + [ 7, 8, 8, 9, 10, 10, 11, 12, 12, 13, 14, 14, 15, 16, 16], + [ 7, 8, 8, 9, 10, 10, 11, 12, 12, 13, 14, 14, 15, 16, 16], + [ 9, 10, 10, 11, 12, 12, 13, 14, 14, 15, 16, 16, 17, 18, 18], + [ 9, 10, 10, 11, 12, 12, 13, 14, 14, 15, 16, 16, 17, 18, 18]] + ) + assert_array_equal(a, b) + + def test_check_shape(self): + a = [[4, 5, 6]] + a = np.pad(a, (5, 7), 'symmetric') + b = np.array( + [[5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6], + [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6], + [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6], + [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6], + [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6], + + [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6], + [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6], + + [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6], + [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6], + [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6], + [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6], + [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6], + [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6]] + ) + assert_array_equal(a, b) + + def test_check_01(self): + a = np.pad([1, 2, 3], 2, 'symmetric') + b = np.array([2, 1, 1, 2, 3, 3, 2]) + assert_array_equal(a, b) + + def test_check_02(self): + a = np.pad([1, 2, 3], 3, 'symmetric') + b = np.array([3, 2, 1, 1, 2, 3, 3, 2, 1]) + assert_array_equal(a, b) + + def test_check_03(self): + a = np.pad([1, 2, 3], 6, 'symmetric') + b = np.array([1, 2, 3, 3, 2, 1, 1, 2, 3, 3, 2, 1, 1, 2, 3]) + assert_array_equal(a, b) + + +class TestWrap: + def test_check_simple(self): + a = np.arange(100) + a = np.pad(a, (25, 20), 'wrap') + b = np.array( + [75, 76, 77, 78, 79, 80, 81, 82, 83, 84, + 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, + 95, 96, 97, 98, 99, + + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, + 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, + 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, + 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, + + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19] + ) + assert_array_equal(a, b) + + def test_check_large_pad(self): + a = np.arange(12) + a = np.reshape(a, (3, 4)) + a = np.pad(a, (10, 12), 'wrap') + b = np.array( + [[10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10, + 11, 8, 9, 10, 11, 8, 9, 10, 11], + [2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, + 3, 0, 1, 2, 3, 0, 1, 2, 3], + [6, 7, 4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6, + 7, 4, 5, 6, 7, 4, 5, 6, 7], + [10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10, + 11, 8, 9, 10, 11, 8, 9, 10, 11], + [2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, + 3, 0, 1, 2, 3, 0, 1, 2, 3], + [6, 7, 4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6, + 7, 4, 5, 6, 7, 4, 5, 6, 7], + [10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10, + 11, 8, 9, 10, 11, 8, 9, 10, 11], + [2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, + 3, 0, 1, 2, 3, 0, 1, 2, 3], + [6, 7, 4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6, + 7, 4, 5, 6, 7, 4, 5, 6, 7], + [10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10, + 11, 8, 9, 10, 11, 8, 9, 10, 11], + + [2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, + 3, 0, 1, 2, 3, 0, 1, 2, 3], + [6, 7, 4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6, + 7, 4, 5, 6, 7, 4, 5, 6, 7], + [10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10, + 11, 8, 9, 10, 11, 8, 9, 10, 11], + + [2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, + 3, 0, 1, 2, 3, 0, 1, 2, 3], + [6, 7, 4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6, + 7, 4, 5, 6, 7, 4, 5, 6, 7], + [10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10, + 11, 8, 9, 10, 11, 8, 9, 10, 11], + [2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, + 3, 0, 1, 2, 3, 0, 1, 2, 3], + [6, 7, 4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6, + 7, 4, 5, 6, 7, 4, 5, 6, 7], + [10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10, + 11, 8, 9, 10, 11, 8, 9, 10, 11], + [2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, + 3, 0, 1, 2, 3, 0, 1, 2, 3], + [6, 7, 4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6, + 7, 4, 5, 6, 7, 4, 5, 6, 7], + [10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10, + 11, 8, 9, 10, 11, 8, 9, 10, 11], + [2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, + 3, 0, 1, 2, 3, 0, 1, 2, 3], + [6, 7, 4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6, + 7, 4, 5, 6, 7, 4, 5, 6, 7], + [10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10, + 11, 8, 9, 10, 11, 8, 9, 10, 11]] + ) + assert_array_equal(a, b) + + def test_check_01(self): + a = np.pad([1, 2, 3], 3, 'wrap') + b = np.array([1, 2, 3, 1, 2, 3, 1, 2, 3]) + assert_array_equal(a, b) + + def test_check_02(self): + a = np.pad([1, 2, 3], 4, 'wrap') + b = np.array([3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1]) + assert_array_equal(a, b) + + def test_pad_with_zero(self): + a = np.ones((3, 5)) + b = np.pad(a, (0, 5), mode="wrap") + assert_array_equal(a, b[:-5, :-5]) + + def test_repeated_wrapping(self): + """ + Check wrapping on each side individually if the wrapped area is longer + than the original array. + """ + a = np.arange(5) + b = np.pad(a, (12, 0), mode="wrap") + assert_array_equal(np.r_[a, a, a, a][3:], b) + + a = np.arange(5) + b = np.pad(a, (0, 12), mode="wrap") + assert_array_equal(np.r_[a, a, a, a][:-3], b) + + +class TestEdge: + def test_check_simple(self): + a = np.arange(12) + a = np.reshape(a, (4, 3)) + a = np.pad(a, ((2, 3), (3, 2)), 'edge') + b = np.array( + [[0, 0, 0, 0, 1, 2, 2, 2], + [0, 0, 0, 0, 1, 2, 2, 2], + + [0, 0, 0, 0, 1, 2, 2, 2], + [3, 3, 3, 3, 4, 5, 5, 5], + [6, 6, 6, 6, 7, 8, 8, 8], + [9, 9, 9, 9, 10, 11, 11, 11], + + [9, 9, 9, 9, 10, 11, 11, 11], + [9, 9, 9, 9, 10, 11, 11, 11], + [9, 9, 9, 9, 10, 11, 11, 11]] + ) + assert_array_equal(a, b) + + def test_check_width_shape_1_2(self): + # Check a pad_width of the form ((1, 2),). + # Regression test for issue gh-7808. + a = np.array([1, 2, 3]) + padded = np.pad(a, ((1, 2),), 'edge') + expected = np.array([1, 1, 2, 3, 3, 3]) + assert_array_equal(padded, expected) + + a = np.array([[1, 2, 3], [4, 5, 6]]) + padded = np.pad(a, ((1, 2),), 'edge') + expected = np.pad(a, ((1, 2), (1, 2)), 'edge') + assert_array_equal(padded, expected) + + a = np.arange(24).reshape(2, 3, 4) + padded = np.pad(a, ((1, 2),), 'edge') + expected = np.pad(a, ((1, 2), (1, 2), (1, 2)), 'edge') + assert_array_equal(padded, expected) + + +class TestEmpty: + def test_simple(self): + arr = np.arange(24).reshape(4, 6) + result = np.pad(arr, [(2, 3), (3, 1)], mode="empty") + assert result.shape == (9, 10) + assert_equal(arr, result[2:-3, 3:-1]) + + def test_pad_empty_dimension(self): + arr = np.zeros((3, 0, 2)) + result = np.pad(arr, [(0,), (2,), (1,)], mode="empty") + assert result.shape == (3, 4, 4) + + +def test_legacy_vector_functionality(): + def _padwithtens(vector, pad_width, iaxis, kwargs): + vector[:pad_width[0]] = 10 + vector[-pad_width[1]:] = 10 + + a = np.arange(6).reshape(2, 3) + a = np.pad(a, 2, _padwithtens) + b = np.array( + [[10, 10, 10, 10, 10, 10, 10], + [10, 10, 10, 10, 10, 10, 10], + + [10, 10, 0, 1, 2, 10, 10], + [10, 10, 3, 4, 5, 10, 10], + + [10, 10, 10, 10, 10, 10, 10], + [10, 10, 10, 10, 10, 10, 10]] + ) + assert_array_equal(a, b) + + +def test_unicode_mode(): + a = np.pad([1], 2, mode=u'constant') + b = np.array([0, 0, 1, 0, 0]) + assert_array_equal(a, b) + + +@pytest.mark.parametrize("mode", ["edge", "symmetric", "reflect", "wrap"]) +def test_object_input(mode): + # Regression test for issue gh-11395. + a = np.full((4, 3), fill_value=None) + pad_amt = ((2, 3), (3, 2)) + b = np.full((9, 8), fill_value=None) + assert_array_equal(np.pad(a, pad_amt, mode=mode), b) + + +class TestPadWidth: + @pytest.mark.parametrize("pad_width", [ + (4, 5, 6, 7), + ((1,), (2,), (3,)), + ((1, 2), (3, 4), (5, 6)), + ((3, 4, 5), (0, 1, 2)), + ]) + @pytest.mark.parametrize("mode", _all_modes.keys()) + def test_misshaped_pad_width(self, pad_width, mode): + arr = np.arange(30).reshape((6, 5)) + match = "operands could not be broadcast together" + with pytest.raises(ValueError, match=match): + np.pad(arr, pad_width, mode) + + @pytest.mark.parametrize("mode", _all_modes.keys()) + def test_misshaped_pad_width_2(self, mode): + arr = np.arange(30).reshape((6, 5)) + match = ("input operand has more dimensions than allowed by the axis " + "remapping") + with pytest.raises(ValueError, match=match): + np.pad(arr, (((3,), (4,), (5,)), ((0,), (1,), (2,))), mode) + + @pytest.mark.parametrize( + "pad_width", [-2, (-2,), (3, -1), ((5, 2), (-2, 3)), ((-4,), (2,))]) + @pytest.mark.parametrize("mode", _all_modes.keys()) + def test_negative_pad_width(self, pad_width, mode): + arr = np.arange(30).reshape((6, 5)) + match = "index can't contain negative values" + with pytest.raises(ValueError, match=match): + np.pad(arr, pad_width, mode) + + @pytest.mark.parametrize("pad_width, dtype", [ + ("3", None), + ("word", None), + (None, None), + (object(), None), + (3.4, None), + (((2, 3, 4), (3, 2)), object), + (complex(1, -1), None), + (((-2.1, 3), (3, 2)), None), + ]) + @pytest.mark.parametrize("mode", _all_modes.keys()) + def test_bad_type(self, pad_width, dtype, mode): + arr = np.arange(30).reshape((6, 5)) + match = "`pad_width` must be of integral type." + if dtype is not None: + # avoid DeprecationWarning when not specifying dtype + with pytest.raises(TypeError, match=match): + np.pad(arr, np.array(pad_width, dtype=dtype), mode) + else: + with pytest.raises(TypeError, match=match): + np.pad(arr, pad_width, mode) + with pytest.raises(TypeError, match=match): + np.pad(arr, np.array(pad_width), mode) + + def test_pad_width_as_ndarray(self): + a = np.arange(12) + a = np.reshape(a, (4, 3)) + a = np.pad(a, np.array(((2, 3), (3, 2))), 'edge') + b = np.array( + [[0, 0, 0, 0, 1, 2, 2, 2], + [0, 0, 0, 0, 1, 2, 2, 2], + + [0, 0, 0, 0, 1, 2, 2, 2], + [3, 3, 3, 3, 4, 5, 5, 5], + [6, 6, 6, 6, 7, 8, 8, 8], + [9, 9, 9, 9, 10, 11, 11, 11], + + [9, 9, 9, 9, 10, 11, 11, 11], + [9, 9, 9, 9, 10, 11, 11, 11], + [9, 9, 9, 9, 10, 11, 11, 11]] + ) + assert_array_equal(a, b) + + @pytest.mark.parametrize("pad_width", [0, (0, 0), ((0, 0), (0, 0))]) + @pytest.mark.parametrize("mode", _all_modes.keys()) + def test_zero_pad_width(self, pad_width, mode): + arr = np.arange(30).reshape(6, 5) + assert_array_equal(arr, np.pad(arr, pad_width, mode=mode)) + + +@pytest.mark.parametrize("mode", _all_modes.keys()) +def test_kwargs(mode): + """Test behavior of pad's kwargs for the given mode.""" + allowed = _all_modes[mode] + not_allowed = {} + for kwargs in _all_modes.values(): + if kwargs != allowed: + not_allowed.update(kwargs) + # Test if allowed keyword arguments pass + np.pad([1, 2, 3], 1, mode, **allowed) + # Test if prohibited keyword arguments of other modes raise an error + for key, value in not_allowed.items(): + match = "unsupported keyword arguments for mode '{}'".format(mode) + with pytest.raises(ValueError, match=match): + np.pad([1, 2, 3], 1, mode, **{key: value}) + + +def test_constant_zero_default(): + arr = np.array([1, 1]) + assert_array_equal(np.pad(arr, 2), [0, 0, 1, 1, 0, 0]) + + +@pytest.mark.parametrize("mode", [1, "const", object(), None, True, False]) +def test_unsupported_mode(mode): + match= "mode '{}' is not supported".format(mode) + with pytest.raises(ValueError, match=match): + np.pad([1, 2, 3], 4, mode=mode) + + +@pytest.mark.parametrize("mode", _all_modes.keys()) +def test_non_contiguous_array(mode): + arr = np.arange(24).reshape(4, 6)[::2, ::2] + result = np.pad(arr, (2, 3), mode) + assert result.shape == (7, 8) + assert_equal(result[2:-3, 2:-3], arr) + + +@pytest.mark.parametrize("mode", _all_modes.keys()) +def test_memory_layout_persistence(mode): + """Test if C and F order is preserved for all pad modes.""" + x = np.ones((5, 10), order='C') + assert np.pad(x, 5, mode).flags["C_CONTIGUOUS"] + x = np.ones((5, 10), order='F') + assert np.pad(x, 5, mode).flags["F_CONTIGUOUS"] + + +@pytest.mark.parametrize("dtype", _numeric_dtypes) +@pytest.mark.parametrize("mode", _all_modes.keys()) +def test_dtype_persistence(dtype, mode): + arr = np.zeros((3, 2, 1), dtype=dtype) + result = np.pad(arr, 1, mode=mode) + assert result.dtype == dtype diff --git a/venv/Lib/site-packages/numpy/lib/tests/test_arraysetops.py b/venv/Lib/site-packages/numpy/lib/tests/test_arraysetops.py new file mode 100644 index 0000000..847e6cb --- /dev/null +++ b/venv/Lib/site-packages/numpy/lib/tests/test_arraysetops.py @@ -0,0 +1,677 @@ +"""Test functions for 1D array set operations. + +""" +import numpy as np + +from numpy.testing import (assert_array_equal, assert_equal, + assert_raises, assert_raises_regex) +from numpy.lib.arraysetops import ( + ediff1d, intersect1d, setxor1d, union1d, setdiff1d, unique, in1d, isin + ) +import pytest + + +class TestSetOps: + + def test_intersect1d(self): + # unique inputs + a = np.array([5, 7, 1, 2]) + b = np.array([2, 4, 3, 1, 5]) + + ec = np.array([1, 2, 5]) + c = intersect1d(a, b, assume_unique=True) + assert_array_equal(c, ec) + + # non-unique inputs + a = np.array([5, 5, 7, 1, 2]) + b = np.array([2, 1, 4, 3, 3, 1, 5]) + + ed = np.array([1, 2, 5]) + c = intersect1d(a, b) + assert_array_equal(c, ed) + assert_array_equal([], intersect1d([], [])) + + def test_intersect1d_array_like(self): + # See gh-11772 + class Test: + def __array__(self): + return np.arange(3) + + a = Test() + res = intersect1d(a, a) + assert_array_equal(res, a) + res = intersect1d([1, 2, 3], [1, 2, 3]) + assert_array_equal(res, [1, 2, 3]) + + def test_intersect1d_indices(self): + # unique inputs + a = np.array([1, 2, 3, 4]) + b = np.array([2, 1, 4, 6]) + c, i1, i2 = intersect1d(a, b, assume_unique=True, return_indices=True) + ee = np.array([1, 2, 4]) + assert_array_equal(c, ee) + assert_array_equal(a[i1], ee) + assert_array_equal(b[i2], ee) + + # non-unique inputs + a = np.array([1, 2, 2, 3, 4, 3, 2]) + b = np.array([1, 8, 4, 2, 2, 3, 2, 3]) + c, i1, i2 = intersect1d(a, b, return_indices=True) + ef = np.array([1, 2, 3, 4]) + assert_array_equal(c, ef) + assert_array_equal(a[i1], ef) + assert_array_equal(b[i2], ef) + + # non1d, unique inputs + a = np.array([[2, 4, 5, 6], [7, 8, 1, 15]]) + b = np.array([[3, 2, 7, 6], [10, 12, 8, 9]]) + c, i1, i2 = intersect1d(a, b, assume_unique=True, return_indices=True) + ui1 = np.unravel_index(i1, a.shape) + ui2 = np.unravel_index(i2, b.shape) + ea = np.array([2, 6, 7, 8]) + assert_array_equal(ea, a[ui1]) + assert_array_equal(ea, b[ui2]) + + # non1d, not assumed to be uniqueinputs + a = np.array([[2, 4, 5, 6, 6], [4, 7, 8, 7, 2]]) + b = np.array([[3, 2, 7, 7], [10, 12, 8, 7]]) + c, i1, i2 = intersect1d(a, b, return_indices=True) + ui1 = np.unravel_index(i1, a.shape) + ui2 = np.unravel_index(i2, b.shape) + ea = np.array([2, 7, 8]) + assert_array_equal(ea, a[ui1]) + assert_array_equal(ea, b[ui2]) + + def test_setxor1d(self): + a = np.array([5, 7, 1, 2]) + b = np.array([2, 4, 3, 1, 5]) + + ec = np.array([3, 4, 7]) + c = setxor1d(a, b) + assert_array_equal(c, ec) + + a = np.array([1, 2, 3]) + b = np.array([6, 5, 4]) + + ec = np.array([1, 2, 3, 4, 5, 6]) + c = setxor1d(a, b) + assert_array_equal(c, ec) + + a = np.array([1, 8, 2, 3]) + b = np.array([6, 5, 4, 8]) + + ec = np.array([1, 2, 3, 4, 5, 6]) + c = setxor1d(a, b) + assert_array_equal(c, ec) + + assert_array_equal([], setxor1d([], [])) + + def test_ediff1d(self): + zero_elem = np.array([]) + one_elem = np.array([1]) + two_elem = np.array([1, 2]) + + assert_array_equal([], ediff1d(zero_elem)) + assert_array_equal([0], ediff1d(zero_elem, to_begin=0)) + assert_array_equal([0], ediff1d(zero_elem, to_end=0)) + assert_array_equal([-1, 0], ediff1d(zero_elem, to_begin=-1, to_end=0)) + assert_array_equal([], ediff1d(one_elem)) + assert_array_equal([1], ediff1d(two_elem)) + assert_array_equal([7, 1, 9], ediff1d(two_elem, to_begin=7, to_end=9)) + assert_array_equal([5, 6, 1, 7, 8], + ediff1d(two_elem, to_begin=[5, 6], to_end=[7, 8])) + assert_array_equal([1, 9], ediff1d(two_elem, to_end=9)) + assert_array_equal([1, 7, 8], ediff1d(two_elem, to_end=[7, 8])) + assert_array_equal([7, 1], ediff1d(two_elem, to_begin=7)) + assert_array_equal([5, 6, 1], ediff1d(two_elem, to_begin=[5, 6])) + + @pytest.mark.parametrize("ary, prepend, append, expected", [ + # should fail because trying to cast + # np.nan standard floating point value + # into an integer array: + (np.array([1, 2, 3], dtype=np.int64), + None, + np.nan, + 'to_end'), + # should fail because attempting + # to downcast to int type: + (np.array([1, 2, 3], dtype=np.int64), + np.array([5, 7, 2], dtype=np.float32), + None, + 'to_begin'), + # should fail because attempting to cast + # two special floating point values + # to integers (on both sides of ary), + # `to_begin` is in the error message as the impl checks this first: + (np.array([1., 3., 9.], dtype=np.int8), + np.nan, + np.nan, + 'to_begin'), + ]) + def test_ediff1d_forbidden_type_casts(self, ary, prepend, append, expected): + # verify resolution of gh-11490 + + # specifically, raise an appropriate + # Exception when attempting to append or + # prepend with an incompatible type + msg = 'dtype of `{}` must be compatible'.format(expected) + with assert_raises_regex(TypeError, msg): + ediff1d(ary=ary, + to_end=append, + to_begin=prepend) + + @pytest.mark.parametrize( + "ary,prepend,append,expected", + [ + (np.array([1, 2, 3], dtype=np.int16), + 2**16, # will be cast to int16 under same kind rule. + 2**16 + 4, + np.array([0, 1, 1, 4], dtype=np.int16)), + (np.array([1, 2, 3], dtype=np.float32), + np.array([5], dtype=np.float64), + None, + np.array([5, 1, 1], dtype=np.float32)), + (np.array([1, 2, 3], dtype=np.int32), + 0, + 0, + np.array([0, 1, 1, 0], dtype=np.int32)), + (np.array([1, 2, 3], dtype=np.int64), + 3, + -9, + np.array([3, 1, 1, -9], dtype=np.int64)), + ] + ) + def test_ediff1d_scalar_handling(self, + ary, + prepend, + append, + expected): + # maintain backwards-compatibility + # of scalar prepend / append behavior + # in ediff1d following fix for gh-11490 + actual = np.ediff1d(ary=ary, + to_end=append, + to_begin=prepend) + assert_equal(actual, expected) + assert actual.dtype == expected.dtype + + def test_isin(self): + # the tests for in1d cover most of isin's behavior + # if in1d is removed, would need to change those tests to test + # isin instead. + def _isin_slow(a, b): + b = np.asarray(b).flatten().tolist() + return a in b + isin_slow = np.vectorize(_isin_slow, otypes=[bool], excluded={1}) + + def assert_isin_equal(a, b): + x = isin(a, b) + y = isin_slow(a, b) + assert_array_equal(x, y) + + # multidimensional arrays in both arguments + a = np.arange(24).reshape([2, 3, 4]) + b = np.array([[10, 20, 30], [0, 1, 3], [11, 22, 33]]) + assert_isin_equal(a, b) + + # array-likes as both arguments + c = [(9, 8), (7, 6)] + d = (9, 7) + assert_isin_equal(c, d) + + # zero-d array: + f = np.array(3) + assert_isin_equal(f, b) + assert_isin_equal(a, f) + assert_isin_equal(f, f) + + # scalar: + assert_isin_equal(5, b) + assert_isin_equal(a, 6) + assert_isin_equal(5, 6) + + # empty array-like: + x = [] + assert_isin_equal(x, b) + assert_isin_equal(a, x) + assert_isin_equal(x, x) + + def test_in1d(self): + # we use two different sizes for the b array here to test the + # two different paths in in1d(). + for mult in (1, 10): + # One check without np.array to make sure lists are handled correct + a = [5, 7, 1, 2] + b = [2, 4, 3, 1, 5] * mult + ec = np.array([True, False, True, True]) + c = in1d(a, b, assume_unique=True) + assert_array_equal(c, ec) + + a[0] = 8 + ec = np.array([False, False, True, True]) + c = in1d(a, b, assume_unique=True) + assert_array_equal(c, ec) + + a[0], a[3] = 4, 8 + ec = np.array([True, False, True, False]) + c = in1d(a, b, assume_unique=True) + assert_array_equal(c, ec) + + a = np.array([5, 4, 5, 3, 4, 4, 3, 4, 3, 5, 2, 1, 5, 5]) + b = [2, 3, 4] * mult + ec = [False, True, False, True, True, True, True, True, True, + False, True, False, False, False] + c = in1d(a, b) + assert_array_equal(c, ec) + + b = b + [5, 5, 4] * mult + ec = [True, True, True, True, True, True, True, True, True, True, + True, False, True, True] + c = in1d(a, b) + assert_array_equal(c, ec) + + a = np.array([5, 7, 1, 2]) + b = np.array([2, 4, 3, 1, 5] * mult) + ec = np.array([True, False, True, True]) + c = in1d(a, b) + assert_array_equal(c, ec) + + a = np.array([5, 7, 1, 1, 2]) + b = np.array([2, 4, 3, 3, 1, 5] * mult) + ec = np.array([True, False, True, True, True]) + c = in1d(a, b) + assert_array_equal(c, ec) + + a = np.array([5, 5]) + b = np.array([2, 2] * mult) + ec = np.array([False, False]) + c = in1d(a, b) + assert_array_equal(c, ec) + + a = np.array([5]) + b = np.array([2]) + ec = np.array([False]) + c = in1d(a, b) + assert_array_equal(c, ec) + + assert_array_equal(in1d([], []), []) + + def test_in1d_char_array(self): + a = np.array(['a', 'b', 'c', 'd', 'e', 'c', 'e', 'b']) + b = np.array(['a', 'c']) + + ec = np.array([True, False, True, False, False, True, False, False]) + c = in1d(a, b) + + assert_array_equal(c, ec) + + def test_in1d_invert(self): + "Test in1d's invert parameter" + # We use two different sizes for the b array here to test the + # two different paths in in1d(). + for mult in (1, 10): + a = np.array([5, 4, 5, 3, 4, 4, 3, 4, 3, 5, 2, 1, 5, 5]) + b = [2, 3, 4] * mult + assert_array_equal(np.invert(in1d(a, b)), in1d(a, b, invert=True)) + + def test_in1d_ravel(self): + # Test that in1d ravels its input arrays. This is not documented + # behavior however. The test is to ensure consistentency. + a = np.arange(6).reshape(2, 3) + b = np.arange(3, 9).reshape(3, 2) + long_b = np.arange(3, 63).reshape(30, 2) + ec = np.array([False, False, False, True, True, True]) + + assert_array_equal(in1d(a, b, assume_unique=True), ec) + assert_array_equal(in1d(a, b, assume_unique=False), ec) + assert_array_equal(in1d(a, long_b, assume_unique=True), ec) + assert_array_equal(in1d(a, long_b, assume_unique=False), ec) + + def test_in1d_first_array_is_object(self): + ar1 = [None] + ar2 = np.array([1]*10) + expected = np.array([False]) + result = np.in1d(ar1, ar2) + assert_array_equal(result, expected) + + def test_in1d_second_array_is_object(self): + ar1 = 1 + ar2 = np.array([None]*10) + expected = np.array([False]) + result = np.in1d(ar1, ar2) + assert_array_equal(result, expected) + + def test_in1d_both_arrays_are_object(self): + ar1 = [None] + ar2 = np.array([None]*10) + expected = np.array([True]) + result = np.in1d(ar1, ar2) + assert_array_equal(result, expected) + + def test_in1d_both_arrays_have_structured_dtype(self): + # Test arrays of a structured data type containing an integer field + # and a field of dtype `object` allowing for arbitrary Python objects + dt = np.dtype([('field1', int), ('field2', object)]) + ar1 = np.array([(1, None)], dtype=dt) + ar2 = np.array([(1, None)]*10, dtype=dt) + expected = np.array([True]) + result = np.in1d(ar1, ar2) + assert_array_equal(result, expected) + + def test_union1d(self): + a = np.array([5, 4, 7, 1, 2]) + b = np.array([2, 4, 3, 3, 2, 1, 5]) + + ec = np.array([1, 2, 3, 4, 5, 7]) + c = union1d(a, b) + assert_array_equal(c, ec) + + # Tests gh-10340, arguments to union1d should be + # flattened if they are not already 1D + x = np.array([[0, 1, 2], [3, 4, 5]]) + y = np.array([0, 1, 2, 3, 4]) + ez = np.array([0, 1, 2, 3, 4, 5]) + z = union1d(x, y) + assert_array_equal(z, ez) + + assert_array_equal([], union1d([], [])) + + def test_setdiff1d(self): + a = np.array([6, 5, 4, 7, 1, 2, 7, 4]) + b = np.array([2, 4, 3, 3, 2, 1, 5]) + + ec = np.array([6, 7]) + c = setdiff1d(a, b) + assert_array_equal(c, ec) + + a = np.arange(21) + b = np.arange(19) + ec = np.array([19, 20]) + c = setdiff1d(a, b) + assert_array_equal(c, ec) + + assert_array_equal([], setdiff1d([], [])) + a = np.array((), np.uint32) + assert_equal(setdiff1d(a, []).dtype, np.uint32) + + def test_setdiff1d_unique(self): + a = np.array([3, 2, 1]) + b = np.array([7, 5, 2]) + expected = np.array([3, 1]) + actual = setdiff1d(a, b, assume_unique=True) + assert_equal(actual, expected) + + def test_setdiff1d_char_array(self): + a = np.array(['a', 'b', 'c']) + b = np.array(['a', 'b', 's']) + assert_array_equal(setdiff1d(a, b), np.array(['c'])) + + def test_manyways(self): + a = np.array([5, 7, 1, 2, 8]) + b = np.array([9, 8, 2, 4, 3, 1, 5]) + + c1 = setxor1d(a, b) + aux1 = intersect1d(a, b) + aux2 = union1d(a, b) + c2 = setdiff1d(aux2, aux1) + assert_array_equal(c1, c2) + + +class TestUnique: + + def test_unique_1d(self): + + def check_all(a, b, i1, i2, c, dt): + base_msg = 'check {0} failed for type {1}' + + msg = base_msg.format('values', dt) + v = unique(a) + assert_array_equal(v, b, msg) + + msg = base_msg.format('return_index', dt) + v, j = unique(a, True, False, False) + assert_array_equal(v, b, msg) + assert_array_equal(j, i1, msg) + + msg = base_msg.format('return_inverse', dt) + v, j = unique(a, False, True, False) + assert_array_equal(v, b, msg) + assert_array_equal(j, i2, msg) + + msg = base_msg.format('return_counts', dt) + v, j = unique(a, False, False, True) + assert_array_equal(v, b, msg) + assert_array_equal(j, c, msg) + + msg = base_msg.format('return_index and return_inverse', dt) + v, j1, j2 = unique(a, True, True, False) + assert_array_equal(v, b, msg) + assert_array_equal(j1, i1, msg) + assert_array_equal(j2, i2, msg) + + msg = base_msg.format('return_index and return_counts', dt) + v, j1, j2 = unique(a, True, False, True) + assert_array_equal(v, b, msg) + assert_array_equal(j1, i1, msg) + assert_array_equal(j2, c, msg) + + msg = base_msg.format('return_inverse and return_counts', dt) + v, j1, j2 = unique(a, False, True, True) + assert_array_equal(v, b, msg) + assert_array_equal(j1, i2, msg) + assert_array_equal(j2, c, msg) + + msg = base_msg.format(('return_index, return_inverse ' + 'and return_counts'), dt) + v, j1, j2, j3 = unique(a, True, True, True) + assert_array_equal(v, b, msg) + assert_array_equal(j1, i1, msg) + assert_array_equal(j2, i2, msg) + assert_array_equal(j3, c, msg) + + a = [5, 7, 1, 2, 1, 5, 7]*10 + b = [1, 2, 5, 7] + i1 = [2, 3, 0, 1] + i2 = [2, 3, 0, 1, 0, 2, 3]*10 + c = np.multiply([2, 1, 2, 2], 10) + + # test for numeric arrays + types = [] + types.extend(np.typecodes['AllInteger']) + types.extend(np.typecodes['AllFloat']) + types.append('datetime64[D]') + types.append('timedelta64[D]') + for dt in types: + aa = np.array(a, dt) + bb = np.array(b, dt) + check_all(aa, bb, i1, i2, c, dt) + + # test for object arrays + dt = 'O' + aa = np.empty(len(a), dt) + aa[:] = a + bb = np.empty(len(b), dt) + bb[:] = b + check_all(aa, bb, i1, i2, c, dt) + + # test for structured arrays + dt = [('', 'i'), ('', 'i')] + aa = np.array(list(zip(a, a)), dt) + bb = np.array(list(zip(b, b)), dt) + check_all(aa, bb, i1, i2, c, dt) + + # test for ticket #2799 + aa = [1. + 0.j, 1 - 1.j, 1] + assert_array_equal(np.unique(aa), [1. - 1.j, 1. + 0.j]) + + # test for ticket #4785 + a = [(1, 2), (1, 2), (2, 3)] + unq = [1, 2, 3] + inv = [0, 1, 0, 1, 1, 2] + a1 = unique(a) + assert_array_equal(a1, unq) + a2, a2_inv = unique(a, return_inverse=True) + assert_array_equal(a2, unq) + assert_array_equal(a2_inv, inv) + + # test for chararrays with return_inverse (gh-5099) + a = np.chararray(5) + a[...] = '' + a2, a2_inv = np.unique(a, return_inverse=True) + assert_array_equal(a2_inv, np.zeros(5)) + + # test for ticket #9137 + a = [] + a1_idx = np.unique(a, return_index=True)[1] + a2_inv = np.unique(a, return_inverse=True)[1] + a3_idx, a3_inv = np.unique(a, return_index=True, + return_inverse=True)[1:] + assert_equal(a1_idx.dtype, np.intp) + assert_equal(a2_inv.dtype, np.intp) + assert_equal(a3_idx.dtype, np.intp) + assert_equal(a3_inv.dtype, np.intp) + + def test_unique_axis_errors(self): + assert_raises(TypeError, self._run_axis_tests, object) + assert_raises(TypeError, self._run_axis_tests, + [('a', int), ('b', object)]) + + assert_raises(np.AxisError, unique, np.arange(10), axis=2) + assert_raises(np.AxisError, unique, np.arange(10), axis=-2) + + def test_unique_axis_list(self): + msg = "Unique failed on list of lists" + inp = [[0, 1, 0], [0, 1, 0]] + inp_arr = np.asarray(inp) + assert_array_equal(unique(inp, axis=0), unique(inp_arr, axis=0), msg) + assert_array_equal(unique(inp, axis=1), unique(inp_arr, axis=1), msg) + + def test_unique_axis(self): + types = [] + types.extend(np.typecodes['AllInteger']) + types.extend(np.typecodes['AllFloat']) + types.append('datetime64[D]') + types.append('timedelta64[D]') + types.append([('a', int), ('b', int)]) + types.append([('a', int), ('b', float)]) + + for dtype in types: + self._run_axis_tests(dtype) + + msg = 'Non-bitwise-equal booleans test failed' + data = np.arange(10, dtype=np.uint8).reshape(-1, 2).view(bool) + result = np.array([[False, True], [True, True]], dtype=bool) + assert_array_equal(unique(data, axis=0), result, msg) + + msg = 'Negative zero equality test failed' + data = np.array([[-0.0, 0.0], [0.0, -0.0], [-0.0, 0.0], [0.0, -0.0]]) + result = np.array([[-0.0, 0.0]]) + assert_array_equal(unique(data, axis=0), result, msg) + + @pytest.mark.parametrize("axis", [0, -1]) + def test_unique_1d_with_axis(self, axis): + x = np.array([4, 3, 2, 3, 2, 1, 2, 2]) + uniq = unique(x, axis=axis) + assert_array_equal(uniq, [1, 2, 3, 4]) + + def test_unique_axis_zeros(self): + # issue 15559 + single_zero = np.empty(shape=(2, 0), dtype=np.int8) + uniq, idx, inv, cnt = unique(single_zero, axis=0, return_index=True, + return_inverse=True, return_counts=True) + + # there's 1 element of shape (0,) along axis 0 + assert_equal(uniq.dtype, single_zero.dtype) + assert_array_equal(uniq, np.empty(shape=(1, 0))) + assert_array_equal(idx, np.array([0])) + assert_array_equal(inv, np.array([0, 0])) + assert_array_equal(cnt, np.array([2])) + + # there's 0 elements of shape (2,) along axis 1 + uniq, idx, inv, cnt = unique(single_zero, axis=1, return_index=True, + return_inverse=True, return_counts=True) + + assert_equal(uniq.dtype, single_zero.dtype) + assert_array_equal(uniq, np.empty(shape=(2, 0))) + assert_array_equal(idx, np.array([])) + assert_array_equal(inv, np.array([])) + assert_array_equal(cnt, np.array([])) + + # test a "complicated" shape + shape = (0, 2, 0, 3, 0, 4, 0) + multiple_zeros = np.empty(shape=shape) + for axis in range(len(shape)): + expected_shape = list(shape) + if shape[axis] == 0: + expected_shape[axis] = 0 + else: + expected_shape[axis] = 1 + + assert_array_equal(unique(multiple_zeros, axis=axis), + np.empty(shape=expected_shape)) + + def test_unique_masked(self): + # issue 8664 + x = np.array([64, 0, 1, 2, 3, 63, 63, 0, 0, 0, 1, 2, 0, 63, 0], + dtype='uint8') + y = np.ma.masked_equal(x, 0) + + v = np.unique(y) + v2, i, c = np.unique(y, return_index=True, return_counts=True) + + msg = 'Unique returned different results when asked for index' + assert_array_equal(v.data, v2.data, msg) + assert_array_equal(v.mask, v2.mask, msg) + + def test_unique_sort_order_with_axis(self): + # These tests fail if sorting along axis is done by treating subarrays + # as unsigned byte strings. See gh-10495. + fmt = "sort order incorrect for integer type '%s'" + for dt in 'bhilq': + a = np.array([[-1], [0]], dt) + b = np.unique(a, axis=0) + assert_array_equal(a, b, fmt % dt) + + def _run_axis_tests(self, dtype): + data = np.array([[0, 1, 0, 0], + [1, 0, 0, 0], + [0, 1, 0, 0], + [1, 0, 0, 0]]).astype(dtype) + + msg = 'Unique with 1d array and axis=0 failed' + result = np.array([0, 1]) + assert_array_equal(unique(data), result.astype(dtype), msg) + + msg = 'Unique with 2d array and axis=0 failed' + result = np.array([[0, 1, 0, 0], [1, 0, 0, 0]]) + assert_array_equal(unique(data, axis=0), result.astype(dtype), msg) + + msg = 'Unique with 2d array and axis=1 failed' + result = np.array([[0, 0, 1], [0, 1, 0], [0, 0, 1], [0, 1, 0]]) + assert_array_equal(unique(data, axis=1), result.astype(dtype), msg) + + msg = 'Unique with 3d array and axis=2 failed' + data3d = np.array([[[1, 1], + [1, 0]], + [[0, 1], + [0, 0]]]).astype(dtype) + result = np.take(data3d, [1, 0], axis=2) + assert_array_equal(unique(data3d, axis=2), result, msg) + + uniq, idx, inv, cnt = unique(data, axis=0, return_index=True, + return_inverse=True, return_counts=True) + msg = "Unique's return_index=True failed with axis=0" + assert_array_equal(data[idx], uniq, msg) + msg = "Unique's return_inverse=True failed with axis=0" + assert_array_equal(uniq[inv], data) + msg = "Unique's return_counts=True failed with axis=0" + assert_array_equal(cnt, np.array([2, 2]), msg) + + uniq, idx, inv, cnt = unique(data, axis=1, return_index=True, + return_inverse=True, return_counts=True) + msg = "Unique's return_index=True failed with axis=1" + assert_array_equal(data[:, idx], uniq) + msg = "Unique's return_inverse=True failed with axis=1" + assert_array_equal(uniq[:, inv], data) + msg = "Unique's return_counts=True failed with axis=1" + assert_array_equal(cnt, np.array([2, 1, 1]), msg) diff --git a/venv/Lib/site-packages/numpy/lib/tests/test_arrayterator.py b/venv/Lib/site-packages/numpy/lib/tests/test_arrayterator.py new file mode 100644 index 0000000..c00ed13 --- /dev/null +++ b/venv/Lib/site-packages/numpy/lib/tests/test_arrayterator.py @@ -0,0 +1,46 @@ +from operator import mul +from functools import reduce + +import numpy as np +from numpy.random import randint +from numpy.lib import Arrayterator +from numpy.testing import assert_ + + +def test(): + np.random.seed(np.arange(10)) + + # Create a random array + ndims = randint(5)+1 + shape = tuple(randint(10)+1 for dim in range(ndims)) + els = reduce(mul, shape) + a = np.arange(els) + a.shape = shape + + buf_size = randint(2*els) + b = Arrayterator(a, buf_size) + + # Check that each block has at most ``buf_size`` elements + for block in b: + assert_(len(block.flat) <= (buf_size or els)) + + # Check that all elements are iterated correctly + assert_(list(b.flat) == list(a.flat)) + + # Slice arrayterator + start = [randint(dim) for dim in shape] + stop = [randint(dim)+1 for dim in shape] + step = [randint(dim)+1 for dim in shape] + slice_ = tuple(slice(*t) for t in zip(start, stop, step)) + c = b[slice_] + d = a[slice_] + + # Check that each block has at most ``buf_size`` elements + for block in c: + assert_(len(block.flat) <= (buf_size or els)) + + # Check that the arrayterator is sliced correctly + assert_(np.all(c.__array__() == d)) + + # Check that all elements are iterated correctly + assert_(list(c.flat) == list(d.flat)) diff --git a/venv/Lib/site-packages/numpy/lib/tests/test_financial_expired.py b/venv/Lib/site-packages/numpy/lib/tests/test_financial_expired.py new file mode 100644 index 0000000..70b0cd7 --- /dev/null +++ b/venv/Lib/site-packages/numpy/lib/tests/test_financial_expired.py @@ -0,0 +1,13 @@ +import sys +import pytest +import numpy as np + + +@pytest.mark.skipif(sys.version_info[:2] < (3, 7), + reason="requires python 3.7 or higher") +def test_financial_expired(): + match = 'NEP 32' + with pytest.warns(DeprecationWarning, match=match): + func = np.fv + with pytest.raises(RuntimeError, match=match): + func(1, 2, 3) diff --git a/venv/Lib/site-packages/numpy/lib/tests/test_format.py b/venv/Lib/site-packages/numpy/lib/tests/test_format.py new file mode 100644 index 0000000..bac42fa --- /dev/null +++ b/venv/Lib/site-packages/numpy/lib/tests/test_format.py @@ -0,0 +1,962 @@ +# doctest +r''' Test the .npy file format. + +Set up: + + >>> import sys + >>> from io import BytesIO + >>> from numpy.lib import format + >>> + >>> scalars = [ + ... np.uint8, + ... np.int8, + ... np.uint16, + ... np.int16, + ... np.uint32, + ... np.int32, + ... np.uint64, + ... np.int64, + ... np.float32, + ... np.float64, + ... np.complex64, + ... np.complex128, + ... object, + ... ] + >>> + >>> basic_arrays = [] + >>> + >>> for scalar in scalars: + ... for endian in '<>': + ... dtype = np.dtype(scalar).newbyteorder(endian) + ... basic = np.arange(15).astype(dtype) + ... basic_arrays.extend([ + ... np.array([], dtype=dtype), + ... np.array(10, dtype=dtype), + ... basic, + ... basic.reshape((3,5)), + ... basic.reshape((3,5)).T, + ... basic.reshape((3,5))[::-1,::2], + ... ]) + ... + >>> + >>> Pdescr = [ + ... ('x', 'i4', (2,)), + ... ('y', 'f8', (2, 2)), + ... ('z', 'u1')] + >>> + >>> + >>> PbufferT = [ + ... ([3,2], [[6.,4.],[6.,4.]], 8), + ... ([4,3], [[7.,5.],[7.,5.]], 9), + ... ] + >>> + >>> + >>> Ndescr = [ + ... ('x', 'i4', (2,)), + ... ('Info', [ + ... ('value', 'c16'), + ... ('y2', 'f8'), + ... ('Info2', [ + ... ('name', 'S2'), + ... ('value', 'c16', (2,)), + ... ('y3', 'f8', (2,)), + ... ('z3', 'u4', (2,))]), + ... ('name', 'S2'), + ... ('z2', 'b1')]), + ... ('color', 'S2'), + ... ('info', [ + ... ('Name', 'U8'), + ... ('Value', 'c16')]), + ... ('y', 'f8', (2, 2)), + ... ('z', 'u1')] + >>> + >>> + >>> NbufferT = [ + ... ([3,2], (6j, 6., ('nn', [6j,4j], [6.,4.], [1,2]), 'NN', True), 'cc', ('NN', 6j), [[6.,4.],[6.,4.]], 8), + ... ([4,3], (7j, 7., ('oo', [7j,5j], [7.,5.], [2,1]), 'OO', False), 'dd', ('OO', 7j), [[7.,5.],[7.,5.]], 9), + ... ] + >>> + >>> + >>> record_arrays = [ + ... np.array(PbufferT, dtype=np.dtype(Pdescr).newbyteorder('<')), + ... np.array(NbufferT, dtype=np.dtype(Ndescr).newbyteorder('<')), + ... np.array(PbufferT, dtype=np.dtype(Pdescr).newbyteorder('>')), + ... np.array(NbufferT, dtype=np.dtype(Ndescr).newbyteorder('>')), + ... ] + +Test the magic string writing. + + >>> format.magic(1, 0) + '\x93NUMPY\x01\x00' + >>> format.magic(0, 0) + '\x93NUMPY\x00\x00' + >>> format.magic(255, 255) + '\x93NUMPY\xff\xff' + >>> format.magic(2, 5) + '\x93NUMPY\x02\x05' + +Test the magic string reading. + + >>> format.read_magic(BytesIO(format.magic(1, 0))) + (1, 0) + >>> format.read_magic(BytesIO(format.magic(0, 0))) + (0, 0) + >>> format.read_magic(BytesIO(format.magic(255, 255))) + (255, 255) + >>> format.read_magic(BytesIO(format.magic(2, 5))) + (2, 5) + +Test the header writing. + + >>> for arr in basic_arrays + record_arrays: + ... f = BytesIO() + ... format.write_array_header_1_0(f, arr) # XXX: arr is not a dict, items gets called on it + ... print(repr(f.getvalue())) + ... + "F\x00{'descr': '|u1', 'fortran_order': False, 'shape': (0,)} \n" + "F\x00{'descr': '|u1', 'fortran_order': False, 'shape': ()} \n" + "F\x00{'descr': '|u1', 'fortran_order': False, 'shape': (15,)} \n" + "F\x00{'descr': '|u1', 'fortran_order': False, 'shape': (3, 5)} \n" + "F\x00{'descr': '|u1', 'fortran_order': True, 'shape': (5, 3)} \n" + "F\x00{'descr': '|u1', 'fortran_order': False, 'shape': (3, 3)} \n" + "F\x00{'descr': '|u1', 'fortran_order': False, 'shape': (0,)} \n" + "F\x00{'descr': '|u1', 'fortran_order': False, 'shape': ()} \n" + "F\x00{'descr': '|u1', 'fortran_order': False, 'shape': (15,)} \n" + "F\x00{'descr': '|u1', 'fortran_order': False, 'shape': (3, 5)} \n" + "F\x00{'descr': '|u1', 'fortran_order': True, 'shape': (5, 3)} \n" + "F\x00{'descr': '|u1', 'fortran_order': False, 'shape': (3, 3)} \n" + "F\x00{'descr': '|i1', 'fortran_order': False, 'shape': (0,)} \n" + "F\x00{'descr': '|i1', 'fortran_order': False, 'shape': ()} \n" + "F\x00{'descr': '|i1', 'fortran_order': False, 'shape': (15,)} \n" + "F\x00{'descr': '|i1', 'fortran_order': False, 'shape': (3, 5)} \n" + "F\x00{'descr': '|i1', 'fortran_order': True, 'shape': (5, 3)} \n" + "F\x00{'descr': '|i1', 'fortran_order': False, 'shape': (3, 3)} \n" + "F\x00{'descr': '|i1', 'fortran_order': False, 'shape': (0,)} \n" + "F\x00{'descr': '|i1', 'fortran_order': False, 'shape': ()} \n" + "F\x00{'descr': '|i1', 'fortran_order': False, 'shape': (15,)} \n" + "F\x00{'descr': '|i1', 'fortran_order': False, 'shape': (3, 5)} \n" + "F\x00{'descr': '|i1', 'fortran_order': True, 'shape': (5, 3)} \n" + "F\x00{'descr': '|i1', 'fortran_order': False, 'shape': (3, 3)} \n" + "F\x00{'descr': 'u2', 'fortran_order': False, 'shape': (0,)} \n" + "F\x00{'descr': '>u2', 'fortran_order': False, 'shape': ()} \n" + "F\x00{'descr': '>u2', 'fortran_order': False, 'shape': (15,)} \n" + "F\x00{'descr': '>u2', 'fortran_order': False, 'shape': (3, 5)} \n" + "F\x00{'descr': '>u2', 'fortran_order': True, 'shape': (5, 3)} \n" + "F\x00{'descr': '>u2', 'fortran_order': False, 'shape': (3, 3)} \n" + "F\x00{'descr': 'i2', 'fortran_order': False, 'shape': (0,)} \n" + "F\x00{'descr': '>i2', 'fortran_order': False, 'shape': ()} \n" + "F\x00{'descr': '>i2', 'fortran_order': False, 'shape': (15,)} \n" + "F\x00{'descr': '>i2', 'fortran_order': False, 'shape': (3, 5)} \n" + "F\x00{'descr': '>i2', 'fortran_order': True, 'shape': (5, 3)} \n" + "F\x00{'descr': '>i2', 'fortran_order': False, 'shape': (3, 3)} \n" + "F\x00{'descr': 'u4', 'fortran_order': False, 'shape': (0,)} \n" + "F\x00{'descr': '>u4', 'fortran_order': False, 'shape': ()} \n" + "F\x00{'descr': '>u4', 'fortran_order': False, 'shape': (15,)} \n" + "F\x00{'descr': '>u4', 'fortran_order': False, 'shape': (3, 5)} \n" + "F\x00{'descr': '>u4', 'fortran_order': True, 'shape': (5, 3)} \n" + "F\x00{'descr': '>u4', 'fortran_order': False, 'shape': (3, 3)} \n" + "F\x00{'descr': 'i4', 'fortran_order': False, 'shape': (0,)} \n" + "F\x00{'descr': '>i4', 'fortran_order': False, 'shape': ()} \n" + "F\x00{'descr': '>i4', 'fortran_order': False, 'shape': (15,)} \n" + "F\x00{'descr': '>i4', 'fortran_order': False, 'shape': (3, 5)} \n" + "F\x00{'descr': '>i4', 'fortran_order': True, 'shape': (5, 3)} \n" + "F\x00{'descr': '>i4', 'fortran_order': False, 'shape': (3, 3)} \n" + "F\x00{'descr': 'u8', 'fortran_order': False, 'shape': (0,)} \n" + "F\x00{'descr': '>u8', 'fortran_order': False, 'shape': ()} \n" + "F\x00{'descr': '>u8', 'fortran_order': False, 'shape': (15,)} \n" + "F\x00{'descr': '>u8', 'fortran_order': False, 'shape': (3, 5)} \n" + "F\x00{'descr': '>u8', 'fortran_order': True, 'shape': (5, 3)} \n" + "F\x00{'descr': '>u8', 'fortran_order': False, 'shape': (3, 3)} \n" + "F\x00{'descr': 'i8', 'fortran_order': False, 'shape': (0,)} \n" + "F\x00{'descr': '>i8', 'fortran_order': False, 'shape': ()} \n" + "F\x00{'descr': '>i8', 'fortran_order': False, 'shape': (15,)} \n" + "F\x00{'descr': '>i8', 'fortran_order': False, 'shape': (3, 5)} \n" + "F\x00{'descr': '>i8', 'fortran_order': True, 'shape': (5, 3)} \n" + "F\x00{'descr': '>i8', 'fortran_order': False, 'shape': (3, 3)} \n" + "F\x00{'descr': 'f4', 'fortran_order': False, 'shape': (0,)} \n" + "F\x00{'descr': '>f4', 'fortran_order': False, 'shape': ()} \n" + "F\x00{'descr': '>f4', 'fortran_order': False, 'shape': (15,)} \n" + "F\x00{'descr': '>f4', 'fortran_order': False, 'shape': (3, 5)} \n" + "F\x00{'descr': '>f4', 'fortran_order': True, 'shape': (5, 3)} \n" + "F\x00{'descr': '>f4', 'fortran_order': False, 'shape': (3, 3)} \n" + "F\x00{'descr': 'f8', 'fortran_order': False, 'shape': (0,)} \n" + "F\x00{'descr': '>f8', 'fortran_order': False, 'shape': ()} \n" + "F\x00{'descr': '>f8', 'fortran_order': False, 'shape': (15,)} \n" + "F\x00{'descr': '>f8', 'fortran_order': False, 'shape': (3, 5)} \n" + "F\x00{'descr': '>f8', 'fortran_order': True, 'shape': (5, 3)} \n" + "F\x00{'descr': '>f8', 'fortran_order': False, 'shape': (3, 3)} \n" + "F\x00{'descr': 'c8', 'fortran_order': False, 'shape': (0,)} \n" + "F\x00{'descr': '>c8', 'fortran_order': False, 'shape': ()} \n" + "F\x00{'descr': '>c8', 'fortran_order': False, 'shape': (15,)} \n" + "F\x00{'descr': '>c8', 'fortran_order': False, 'shape': (3, 5)} \n" + "F\x00{'descr': '>c8', 'fortran_order': True, 'shape': (5, 3)} \n" + "F\x00{'descr': '>c8', 'fortran_order': False, 'shape': (3, 3)} \n" + "F\x00{'descr': 'c16', 'fortran_order': False, 'shape': (0,)} \n" + "F\x00{'descr': '>c16', 'fortran_order': False, 'shape': ()} \n" + "F\x00{'descr': '>c16', 'fortran_order': False, 'shape': (15,)} \n" + "F\x00{'descr': '>c16', 'fortran_order': False, 'shape': (3, 5)} \n" + "F\x00{'descr': '>c16', 'fortran_order': True, 'shape': (5, 3)} \n" + "F\x00{'descr': '>c16', 'fortran_order': False, 'shape': (3, 3)} \n" + "F\x00{'descr': 'O', 'fortran_order': False, 'shape': (0,)} \n" + "F\x00{'descr': 'O', 'fortran_order': False, 'shape': ()} \n" + "F\x00{'descr': 'O', 'fortran_order': False, 'shape': (15,)} \n" + "F\x00{'descr': 'O', 'fortran_order': False, 'shape': (3, 5)} \n" + "F\x00{'descr': 'O', 'fortran_order': True, 'shape': (5, 3)} \n" + "F\x00{'descr': 'O', 'fortran_order': False, 'shape': (3, 3)} \n" + "F\x00{'descr': 'O', 'fortran_order': False, 'shape': (0,)} \n" + "F\x00{'descr': 'O', 'fortran_order': False, 'shape': ()} \n" + "F\x00{'descr': 'O', 'fortran_order': False, 'shape': (15,)} \n" + "F\x00{'descr': 'O', 'fortran_order': False, 'shape': (3, 5)} \n" + "F\x00{'descr': 'O', 'fortran_order': True, 'shape': (5, 3)} \n" + "F\x00{'descr': 'O', 'fortran_order': False, 'shape': (3, 3)} \n" + "v\x00{'descr': [('x', 'i4', (2,)), ('y', '>f8', (2, 2)), ('z', '|u1')],\n 'fortran_order': False,\n 'shape': (2,)} \n" + "\x16\x02{'descr': [('x', '>i4', (2,)),\n ('Info',\n [('value', '>c16'),\n ('y2', '>f8'),\n ('Info2',\n [('name', '|S2'),\n ('value', '>c16', (2,)),\n ('y3', '>f8', (2,)),\n ('z3', '>u4', (2,))]),\n ('name', '|S2'),\n ('z2', '|b1')]),\n ('color', '|S2'),\n ('info', [('Name', '>U8'), ('Value', '>c16')]),\n ('y', '>f8', (2, 2)),\n ('z', '|u1')],\n 'fortran_order': False,\n 'shape': (2,)} \n" +''' +import sys +import os +import shutil +import tempfile +import warnings +import pytest +from io import BytesIO + +import numpy as np +from numpy.testing import ( + assert_, assert_array_equal, assert_raises, assert_raises_regex, + assert_warns, + ) +from numpy.lib import format + + +# Generate some basic arrays to test with. +scalars = [ + np.uint8, + np.int8, + np.uint16, + np.int16, + np.uint32, + np.int32, + np.uint64, + np.int64, + np.float32, + np.float64, + np.complex64, + np.complex128, + object, +] +basic_arrays = [] +for scalar in scalars: + for endian in '<>': + dtype = np.dtype(scalar).newbyteorder(endian) + basic = np.arange(1500).astype(dtype) + basic_arrays.extend([ + # Empty + np.array([], dtype=dtype), + # Rank-0 + np.array(10, dtype=dtype), + # 1-D + basic, + # 2-D C-contiguous + basic.reshape((30, 50)), + # 2-D F-contiguous + basic.reshape((30, 50)).T, + # 2-D non-contiguous + basic.reshape((30, 50))[::-1, ::2], + ]) + +# More complicated record arrays. +# This is the structure of the table used for plain objects: +# +# +-+-+-+ +# |x|y|z| +# +-+-+-+ + +# Structure of a plain array description: +Pdescr = [ + ('x', 'i4', (2,)), + ('y', 'f8', (2, 2)), + ('z', 'u1')] + +# A plain list of tuples with values for testing: +PbufferT = [ + # x y z + ([3, 2], [[6., 4.], [6., 4.]], 8), + ([4, 3], [[7., 5.], [7., 5.]], 9), + ] + + +# This is the structure of the table used for nested objects (DON'T PANIC!): +# +# +-+---------------------------------+-----+----------+-+-+ +# |x|Info |color|info |y|z| +# | +-----+--+----------------+----+--+ +----+-----+ | | +# | |value|y2|Info2 |name|z2| |Name|Value| | | +# | | | +----+-----+--+--+ | | | | | | | +# | | | |name|value|y3|z3| | | | | | | | +# +-+-----+--+----+-----+--+--+----+--+-----+----+-----+-+-+ +# + +# The corresponding nested array description: +Ndescr = [ + ('x', 'i4', (2,)), + ('Info', [ + ('value', 'c16'), + ('y2', 'f8'), + ('Info2', [ + ('name', 'S2'), + ('value', 'c16', (2,)), + ('y3', 'f8', (2,)), + ('z3', 'u4', (2,))]), + ('name', 'S2'), + ('z2', 'b1')]), + ('color', 'S2'), + ('info', [ + ('Name', 'U8'), + ('Value', 'c16')]), + ('y', 'f8', (2, 2)), + ('z', 'u1')] + +NbufferT = [ + # x Info color info y z + # value y2 Info2 name z2 Name Value + # name value y3 z3 + ([3, 2], (6j, 6., ('nn', [6j, 4j], [6., 4.], [1, 2]), 'NN', True), + 'cc', ('NN', 6j), [[6., 4.], [6., 4.]], 8), + ([4, 3], (7j, 7., ('oo', [7j, 5j], [7., 5.], [2, 1]), 'OO', False), + 'dd', ('OO', 7j), [[7., 5.], [7., 5.]], 9), + ] + +record_arrays = [ + np.array(PbufferT, dtype=np.dtype(Pdescr).newbyteorder('<')), + np.array(NbufferT, dtype=np.dtype(Ndescr).newbyteorder('<')), + np.array(PbufferT, dtype=np.dtype(Pdescr).newbyteorder('>')), + np.array(NbufferT, dtype=np.dtype(Ndescr).newbyteorder('>')), + np.zeros(1, dtype=[('c', (' 1, a) + assert_array_equal(b, [3, 2, 2, 3, 3]) + + def test_place(self): + # Make sure that non-np.ndarray objects + # raise an error instead of doing nothing + assert_raises(TypeError, place, [1, 2, 3], [True, False], [0, 1]) + + a = np.array([1, 4, 3, 2, 5, 8, 7]) + place(a, [0, 1, 0, 1, 0, 1, 0], [2, 4, 6]) + assert_array_equal(a, [1, 2, 3, 4, 5, 6, 7]) + + place(a, np.zeros(7), []) + assert_array_equal(a, np.arange(1, 8)) + + place(a, [1, 0, 1, 0, 1, 0, 1], [8, 9]) + assert_array_equal(a, [8, 2, 9, 4, 8, 6, 9]) + assert_raises_regex(ValueError, "Cannot insert from an empty array", + lambda: place(a, [0, 0, 0, 0, 0, 1, 0], [])) + + # See Issue #6974 + a = np.array(['12', '34']) + place(a, [0, 1], '9') + assert_array_equal(a, ['12', '9']) + + def test_both(self): + a = rand(10) + mask = a > 0.5 + ac = a.copy() + c = extract(mask, a) + place(a, mask, 0) + place(a, mask, c) + assert_array_equal(a, ac) + + +# _foo1 and _foo2 are used in some tests in TestVectorize. + +def _foo1(x, y=1.0): + return y*math.floor(x) + + +def _foo2(x, y=1.0, z=0.0): + return y*math.floor(x) + z + + +class TestVectorize: + + def test_simple(self): + def addsubtract(a, b): + if a > b: + return a - b + else: + return a + b + + f = vectorize(addsubtract) + r = f([0, 3, 6, 9], [1, 3, 5, 7]) + assert_array_equal(r, [1, 6, 1, 2]) + + def test_scalar(self): + def addsubtract(a, b): + if a > b: + return a - b + else: + return a + b + + f = vectorize(addsubtract) + r = f([0, 3, 6, 9], 5) + assert_array_equal(r, [5, 8, 1, 4]) + + def test_large(self): + x = np.linspace(-3, 2, 10000) + f = vectorize(lambda x: x) + y = f(x) + assert_array_equal(y, x) + + def test_ufunc(self): + f = vectorize(math.cos) + args = np.array([0, 0.5 * np.pi, np.pi, 1.5 * np.pi, 2 * np.pi]) + r1 = f(args) + r2 = np.cos(args) + assert_array_almost_equal(r1, r2) + + def test_keywords(self): + + def foo(a, b=1): + return a + b + + f = vectorize(foo) + args = np.array([1, 2, 3]) + r1 = f(args) + r2 = np.array([2, 3, 4]) + assert_array_equal(r1, r2) + r1 = f(args, 2) + r2 = np.array([3, 4, 5]) + assert_array_equal(r1, r2) + + def test_keywords_with_otypes_order1(self): + # gh-1620: The second call of f would crash with + # `ValueError: invalid number of arguments`. + f = vectorize(_foo1, otypes=[float]) + # We're testing the caching of ufuncs by vectorize, so the order + # of these function calls is an important part of the test. + r1 = f(np.arange(3.0), 1.0) + r2 = f(np.arange(3.0)) + assert_array_equal(r1, r2) + + def test_keywords_with_otypes_order2(self): + # gh-1620: The second call of f would crash with + # `ValueError: non-broadcastable output operand with shape () + # doesn't match the broadcast shape (3,)`. + f = vectorize(_foo1, otypes=[float]) + # We're testing the caching of ufuncs by vectorize, so the order + # of these function calls is an important part of the test. + r1 = f(np.arange(3.0)) + r2 = f(np.arange(3.0), 1.0) + assert_array_equal(r1, r2) + + def test_keywords_with_otypes_order3(self): + # gh-1620: The third call of f would crash with + # `ValueError: invalid number of arguments`. + f = vectorize(_foo1, otypes=[float]) + # We're testing the caching of ufuncs by vectorize, so the order + # of these function calls is an important part of the test. + r1 = f(np.arange(3.0)) + r2 = f(np.arange(3.0), y=1.0) + r3 = f(np.arange(3.0)) + assert_array_equal(r1, r2) + assert_array_equal(r1, r3) + + def test_keywords_with_otypes_several_kwd_args1(self): + # gh-1620 Make sure different uses of keyword arguments + # don't break the vectorized function. + f = vectorize(_foo2, otypes=[float]) + # We're testing the caching of ufuncs by vectorize, so the order + # of these function calls is an important part of the test. + r1 = f(10.4, z=100) + r2 = f(10.4, y=-1) + r3 = f(10.4) + assert_equal(r1, _foo2(10.4, z=100)) + assert_equal(r2, _foo2(10.4, y=-1)) + assert_equal(r3, _foo2(10.4)) + + def test_keywords_with_otypes_several_kwd_args2(self): + # gh-1620 Make sure different uses of keyword arguments + # don't break the vectorized function. + f = vectorize(_foo2, otypes=[float]) + # We're testing the caching of ufuncs by vectorize, so the order + # of these function calls is an important part of the test. + r1 = f(z=100, x=10.4, y=-1) + r2 = f(1, 2, 3) + assert_equal(r1, _foo2(z=100, x=10.4, y=-1)) + assert_equal(r2, _foo2(1, 2, 3)) + + def test_keywords_no_func_code(self): + # This needs to test a function that has keywords but + # no func_code attribute, since otherwise vectorize will + # inspect the func_code. + import random + try: + vectorize(random.randrange) # Should succeed + except Exception: + raise AssertionError() + + def test_keywords2_ticket_2100(self): + # Test kwarg support: enhancement ticket 2100 + + def foo(a, b=1): + return a + b + + f = vectorize(foo) + args = np.array([1, 2, 3]) + r1 = f(a=args) + r2 = np.array([2, 3, 4]) + assert_array_equal(r1, r2) + r1 = f(b=1, a=args) + assert_array_equal(r1, r2) + r1 = f(args, b=2) + r2 = np.array([3, 4, 5]) + assert_array_equal(r1, r2) + + def test_keywords3_ticket_2100(self): + # Test excluded with mixed positional and kwargs: ticket 2100 + def mypolyval(x, p): + _p = list(p) + res = _p.pop(0) + while _p: + res = res * x + _p.pop(0) + return res + + vpolyval = np.vectorize(mypolyval, excluded=['p', 1]) + ans = [3, 6] + assert_array_equal(ans, vpolyval(x=[0, 1], p=[1, 2, 3])) + assert_array_equal(ans, vpolyval([0, 1], p=[1, 2, 3])) + assert_array_equal(ans, vpolyval([0, 1], [1, 2, 3])) + + def test_keywords4_ticket_2100(self): + # Test vectorizing function with no positional args. + @vectorize + def f(**kw): + res = 1.0 + for _k in kw: + res *= kw[_k] + return res + + assert_array_equal(f(a=[1, 2], b=[3, 4]), [3, 8]) + + def test_keywords5_ticket_2100(self): + # Test vectorizing function with no kwargs args. + @vectorize + def f(*v): + return np.prod(v) + + assert_array_equal(f([1, 2], [3, 4]), [3, 8]) + + def test_coverage1_ticket_2100(self): + def foo(): + return 1 + + f = vectorize(foo) + assert_array_equal(f(), 1) + + def test_assigning_docstring(self): + def foo(x): + """Original documentation""" + return x + + f = vectorize(foo) + assert_equal(f.__doc__, foo.__doc__) + + doc = "Provided documentation" + f = vectorize(foo, doc=doc) + assert_equal(f.__doc__, doc) + + def test_UnboundMethod_ticket_1156(self): + # Regression test for issue 1156 + class Foo: + b = 2 + + def bar(self, a): + return a ** self.b + + assert_array_equal(vectorize(Foo().bar)(np.arange(9)), + np.arange(9) ** 2) + assert_array_equal(vectorize(Foo.bar)(Foo(), np.arange(9)), + np.arange(9) ** 2) + + def test_execution_order_ticket_1487(self): + # Regression test for dependence on execution order: issue 1487 + f1 = vectorize(lambda x: x) + res1a = f1(np.arange(3)) + res1b = f1(np.arange(0.1, 3)) + f2 = vectorize(lambda x: x) + res2b = f2(np.arange(0.1, 3)) + res2a = f2(np.arange(3)) + assert_equal(res1a, res2a) + assert_equal(res1b, res2b) + + def test_string_ticket_1892(self): + # Test vectorization over strings: issue 1892. + f = np.vectorize(lambda x: x) + s = '0123456789' * 10 + assert_equal(s, f(s)) + + def test_cache(self): + # Ensure that vectorized func called exactly once per argument. + _calls = [0] + + @vectorize + def f(x): + _calls[0] += 1 + return x ** 2 + + f.cache = True + x = np.arange(5) + assert_array_equal(f(x), x * x) + assert_equal(_calls[0], len(x)) + + def test_otypes(self): + f = np.vectorize(lambda x: x) + f.otypes = 'i' + x = np.arange(5) + assert_array_equal(f(x), x) + + def test_parse_gufunc_signature(self): + assert_equal(nfb._parse_gufunc_signature('(x)->()'), ([('x',)], [()])) + assert_equal(nfb._parse_gufunc_signature('(x,y)->()'), + ([('x', 'y')], [()])) + assert_equal(nfb._parse_gufunc_signature('(x),(y)->()'), + ([('x',), ('y',)], [()])) + assert_equal(nfb._parse_gufunc_signature('(x)->(y)'), + ([('x',)], [('y',)])) + assert_equal(nfb._parse_gufunc_signature('(x)->(y),()'), + ([('x',)], [('y',), ()])) + assert_equal(nfb._parse_gufunc_signature('(),(a,b,c),(d)->(d,e)'), + ([(), ('a', 'b', 'c'), ('d',)], [('d', 'e')])) + with assert_raises(ValueError): + nfb._parse_gufunc_signature('(x)(y)->()') + with assert_raises(ValueError): + nfb._parse_gufunc_signature('(x),(y)->') + with assert_raises(ValueError): + nfb._parse_gufunc_signature('((x))->(x)') + + def test_signature_simple(self): + def addsubtract(a, b): + if a > b: + return a - b + else: + return a + b + + f = vectorize(addsubtract, signature='(),()->()') + r = f([0, 3, 6, 9], [1, 3, 5, 7]) + assert_array_equal(r, [1, 6, 1, 2]) + + def test_signature_mean_last(self): + def mean(a): + return a.mean() + + f = vectorize(mean, signature='(n)->()') + r = f([[1, 3], [2, 4]]) + assert_array_equal(r, [2, 3]) + + def test_signature_center(self): + def center(a): + return a - a.mean() + + f = vectorize(center, signature='(n)->(n)') + r = f([[1, 3], [2, 4]]) + assert_array_equal(r, [[-1, 1], [-1, 1]]) + + def test_signature_two_outputs(self): + f = vectorize(lambda x: (x, x), signature='()->(),()') + r = f([1, 2, 3]) + assert_(isinstance(r, tuple) and len(r) == 2) + assert_array_equal(r[0], [1, 2, 3]) + assert_array_equal(r[1], [1, 2, 3]) + + def test_signature_outer(self): + f = vectorize(np.outer, signature='(a),(b)->(a,b)') + r = f([1, 2], [1, 2, 3]) + assert_array_equal(r, [[1, 2, 3], [2, 4, 6]]) + + r = f([[[1, 2]]], [1, 2, 3]) + assert_array_equal(r, [[[[1, 2, 3], [2, 4, 6]]]]) + + r = f([[1, 0], [2, 0]], [1, 2, 3]) + assert_array_equal(r, [[[1, 2, 3], [0, 0, 0]], + [[2, 4, 6], [0, 0, 0]]]) + + r = f([1, 2], [[1, 2, 3], [0, 0, 0]]) + assert_array_equal(r, [[[1, 2, 3], [2, 4, 6]], + [[0, 0, 0], [0, 0, 0]]]) + + def test_signature_computed_size(self): + f = vectorize(lambda x: x[:-1], signature='(n)->(m)') + r = f([1, 2, 3]) + assert_array_equal(r, [1, 2]) + + r = f([[1, 2, 3], [2, 3, 4]]) + assert_array_equal(r, [[1, 2], [2, 3]]) + + def test_signature_excluded(self): + + def foo(a, b=1): + return a + b + + f = vectorize(foo, signature='()->()', excluded={'b'}) + assert_array_equal(f([1, 2, 3]), [2, 3, 4]) + assert_array_equal(f([1, 2, 3], b=0), [1, 2, 3]) + + def test_signature_otypes(self): + f = vectorize(lambda x: x, signature='(n)->(n)', otypes=['float64']) + r = f([1, 2, 3]) + assert_equal(r.dtype, np.dtype('float64')) + assert_array_equal(r, [1, 2, 3]) + + def test_signature_invalid_inputs(self): + f = vectorize(operator.add, signature='(n),(n)->(n)') + with assert_raises_regex(TypeError, 'wrong number of positional'): + f([1, 2]) + with assert_raises_regex( + ValueError, 'does not have enough dimensions'): + f(1, 2) + with assert_raises_regex( + ValueError, 'inconsistent size for core dimension'): + f([1, 2], [1, 2, 3]) + + f = vectorize(operator.add, signature='()->()') + with assert_raises_regex(TypeError, 'wrong number of positional'): + f(1, 2) + + def test_signature_invalid_outputs(self): + + f = vectorize(lambda x: x[:-1], signature='(n)->(n)') + with assert_raises_regex( + ValueError, 'inconsistent size for core dimension'): + f([1, 2, 3]) + + f = vectorize(lambda x: x, signature='()->(),()') + with assert_raises_regex(ValueError, 'wrong number of outputs'): + f(1) + + f = vectorize(lambda x: (x, x), signature='()->()') + with assert_raises_regex(ValueError, 'wrong number of outputs'): + f([1, 2]) + + def test_size_zero_output(self): + # see issue 5868 + f = np.vectorize(lambda x: x) + x = np.zeros([0, 5], dtype=int) + with assert_raises_regex(ValueError, 'otypes'): + f(x) + + f.otypes = 'i' + assert_array_equal(f(x), x) + + f = np.vectorize(lambda x: x, signature='()->()') + with assert_raises_regex(ValueError, 'otypes'): + f(x) + + f = np.vectorize(lambda x: x, signature='()->()', otypes='i') + assert_array_equal(f(x), x) + + f = np.vectorize(lambda x: x, signature='(n)->(n)', otypes='i') + assert_array_equal(f(x), x) + + f = np.vectorize(lambda x: x, signature='(n)->(n)') + assert_array_equal(f(x.T), x.T) + + f = np.vectorize(lambda x: [x], signature='()->(n)', otypes='i') + with assert_raises_regex(ValueError, 'new output dimensions'): + f(x) + + +class TestLeaks: + class A: + iters = 20 + + def bound(self, *args): + return 0 + + @staticmethod + def unbound(*args): + return 0 + + @pytest.mark.skipif(not HAS_REFCOUNT, reason="Python lacks refcounts") + @pytest.mark.parametrize('name, incr', [ + ('bound', A.iters), + ('unbound', 0), + ]) + def test_frompyfunc_leaks(self, name, incr): + # exposed in gh-11867 as np.vectorized, but the problem stems from + # frompyfunc. + # class.attribute = np.frompyfunc() creates a + # reference cycle if is a bound class method. It requires a + # gc collection cycle to break the cycle (on CPython 3) + import gc + A_func = getattr(self.A, name) + gc.disable() + try: + refcount = sys.getrefcount(A_func) + for i in range(self.A.iters): + a = self.A() + a.f = np.frompyfunc(getattr(a, name), 1, 1) + out = a.f(np.arange(10)) + a = None + # A.func is part of a reference cycle if incr is non-zero + assert_equal(sys.getrefcount(A_func), refcount + incr) + for i in range(5): + gc.collect() + assert_equal(sys.getrefcount(A_func), refcount) + finally: + gc.enable() + +class TestDigitize: + + def test_forward(self): + x = np.arange(-6, 5) + bins = np.arange(-5, 5) + assert_array_equal(digitize(x, bins), np.arange(11)) + + def test_reverse(self): + x = np.arange(5, -6, -1) + bins = np.arange(5, -5, -1) + assert_array_equal(digitize(x, bins), np.arange(11)) + + def test_random(self): + x = rand(10) + bin = np.linspace(x.min(), x.max(), 10) + assert_(np.all(digitize(x, bin) != 0)) + + def test_right_basic(self): + x = [1, 5, 4, 10, 8, 11, 0] + bins = [1, 5, 10] + default_answer = [1, 2, 1, 3, 2, 3, 0] + assert_array_equal(digitize(x, bins), default_answer) + right_answer = [0, 1, 1, 2, 2, 3, 0] + assert_array_equal(digitize(x, bins, True), right_answer) + + def test_right_open(self): + x = np.arange(-6, 5) + bins = np.arange(-6, 4) + assert_array_equal(digitize(x, bins, True), np.arange(11)) + + def test_right_open_reverse(self): + x = np.arange(5, -6, -1) + bins = np.arange(4, -6, -1) + assert_array_equal(digitize(x, bins, True), np.arange(11)) + + def test_right_open_random(self): + x = rand(10) + bins = np.linspace(x.min(), x.max(), 10) + assert_(np.all(digitize(x, bins, True) != 10)) + + def test_monotonic(self): + x = [-1, 0, 1, 2] + bins = [0, 0, 1] + assert_array_equal(digitize(x, bins, False), [0, 2, 3, 3]) + assert_array_equal(digitize(x, bins, True), [0, 0, 2, 3]) + bins = [1, 1, 0] + assert_array_equal(digitize(x, bins, False), [3, 2, 0, 0]) + assert_array_equal(digitize(x, bins, True), [3, 3, 2, 0]) + bins = [1, 1, 1, 1] + assert_array_equal(digitize(x, bins, False), [0, 0, 4, 4]) + assert_array_equal(digitize(x, bins, True), [0, 0, 0, 4]) + bins = [0, 0, 1, 0] + assert_raises(ValueError, digitize, x, bins) + bins = [1, 1, 0, 1] + assert_raises(ValueError, digitize, x, bins) + + def test_casting_error(self): + x = [1, 2, 3 + 1.j] + bins = [1, 2, 3] + assert_raises(TypeError, digitize, x, bins) + x, bins = bins, x + assert_raises(TypeError, digitize, x, bins) + + def test_return_type(self): + # Functions returning indices should always return base ndarrays + class A(np.ndarray): + pass + a = np.arange(5).view(A) + b = np.arange(1, 3).view(A) + assert_(not isinstance(digitize(b, a, False), A)) + assert_(not isinstance(digitize(b, a, True), A)) + + def test_large_integers_increasing(self): + # gh-11022 + x = 2**54 # loses precision in a float + assert_equal(np.digitize(x, [x - 1, x + 1]), 1) + + @pytest.mark.xfail( + reason="gh-11022: np.core.multiarray._monoticity loses precision") + def test_large_integers_decreasing(self): + # gh-11022 + x = 2**54 # loses precision in a float + assert_equal(np.digitize(x, [x + 1, x - 1]), 1) + + +class TestUnwrap: + + def test_simple(self): + # check that unwrap removes jumps greater that 2*pi + assert_array_equal(unwrap([1, 1 + 2 * np.pi]), [1, 1]) + # check that unwrap maintains continuity + assert_(np.all(diff(unwrap(rand(10) * 100)) < np.pi)) + + +class TestFilterwindows: + + def test_hanning(self): + # check symmetry + w = hanning(10) + assert_equal(w, flipud(w)) + # check known value + assert_almost_equal(np.sum(w, axis=0), 4.500, 4) + + def test_hamming(self): + # check symmetry + w = hamming(10) + assert_equal(w, flipud(w)) + # check known value + assert_almost_equal(np.sum(w, axis=0), 4.9400, 4) + + def test_bartlett(self): + # check symmetry + w = bartlett(10) + assert_equal(w, flipud(w)) + # check known value + assert_almost_equal(np.sum(w, axis=0), 4.4444, 4) + + def test_blackman(self): + # check symmetry + w = blackman(10) + assert_equal(w, flipud(w)) + # check known value + assert_almost_equal(np.sum(w, axis=0), 3.7800, 4) + + +class TestTrapz: + + def test_simple(self): + x = np.arange(-10, 10, .1) + r = trapz(np.exp(-.5 * x ** 2) / np.sqrt(2 * np.pi), dx=0.1) + # check integral of normal equals 1 + assert_almost_equal(r, 1, 7) + + def test_ndim(self): + x = np.linspace(0, 1, 3) + y = np.linspace(0, 2, 8) + z = np.linspace(0, 3, 13) + + wx = np.ones_like(x) * (x[1] - x[0]) + wx[0] /= 2 + wx[-1] /= 2 + wy = np.ones_like(y) * (y[1] - y[0]) + wy[0] /= 2 + wy[-1] /= 2 + wz = np.ones_like(z) * (z[1] - z[0]) + wz[0] /= 2 + wz[-1] /= 2 + + q = x[:, None, None] + y[None,:, None] + z[None, None,:] + + qx = (q * wx[:, None, None]).sum(axis=0) + qy = (q * wy[None, :, None]).sum(axis=1) + qz = (q * wz[None, None, :]).sum(axis=2) + + # n-d `x` + r = trapz(q, x=x[:, None, None], axis=0) + assert_almost_equal(r, qx) + r = trapz(q, x=y[None,:, None], axis=1) + assert_almost_equal(r, qy) + r = trapz(q, x=z[None, None,:], axis=2) + assert_almost_equal(r, qz) + + # 1-d `x` + r = trapz(q, x=x, axis=0) + assert_almost_equal(r, qx) + r = trapz(q, x=y, axis=1) + assert_almost_equal(r, qy) + r = trapz(q, x=z, axis=2) + assert_almost_equal(r, qz) + + def test_masked(self): + # Testing that masked arrays behave as if the function is 0 where + # masked + x = np.arange(5) + y = x * x + mask = x == 2 + ym = np.ma.array(y, mask=mask) + r = 13.0 # sum(0.5 * (0 + 1) * 1.0 + 0.5 * (9 + 16)) + assert_almost_equal(trapz(ym, x), r) + + xm = np.ma.array(x, mask=mask) + assert_almost_equal(trapz(ym, xm), r) + + xm = np.ma.array(x, mask=mask) + assert_almost_equal(trapz(y, xm), r) + + +class TestSinc: + + def test_simple(self): + assert_(sinc(0) == 1) + w = sinc(np.linspace(-1, 1, 100)) + # check symmetry + assert_array_almost_equal(w, flipud(w), 7) + + def test_array_like(self): + x = [0, 0.5] + y1 = sinc(np.array(x)) + y2 = sinc(list(x)) + y3 = sinc(tuple(x)) + assert_array_equal(y1, y2) + assert_array_equal(y1, y3) + + +class TestUnique: + + def test_simple(self): + x = np.array([4, 3, 2, 1, 1, 2, 3, 4, 0]) + assert_(np.all(unique(x) == [0, 1, 2, 3, 4])) + assert_(unique(np.array([1, 1, 1, 1, 1])) == np.array([1])) + x = ['widget', 'ham', 'foo', 'bar', 'foo', 'ham'] + assert_(np.all(unique(x) == ['bar', 'foo', 'ham', 'widget'])) + x = np.array([5 + 6j, 1 + 1j, 1 + 10j, 10, 5 + 6j]) + assert_(np.all(unique(x) == [1 + 1j, 1 + 10j, 5 + 6j, 10])) + + +class TestCheckFinite: + + def test_simple(self): + a = [1, 2, 3] + b = [1, 2, np.inf] + c = [1, 2, np.nan] + np.lib.asarray_chkfinite(a) + assert_raises(ValueError, np.lib.asarray_chkfinite, b) + assert_raises(ValueError, np.lib.asarray_chkfinite, c) + + def test_dtype_order(self): + # Regression test for missing dtype and order arguments + a = [1, 2, 3] + a = np.lib.asarray_chkfinite(a, order='F', dtype=np.float64) + assert_(a.dtype == np.float64) + + +class TestCorrCoef: + A = np.array( + [[0.15391142, 0.18045767, 0.14197213], + [0.70461506, 0.96474128, 0.27906989], + [0.9297531, 0.32296769, 0.19267156]]) + B = np.array( + [[0.10377691, 0.5417086, 0.49807457], + [0.82872117, 0.77801674, 0.39226705], + [0.9314666, 0.66800209, 0.03538394]]) + res1 = np.array( + [[1., 0.9379533, -0.04931983], + [0.9379533, 1., 0.30007991], + [-0.04931983, 0.30007991, 1.]]) + res2 = np.array( + [[1., 0.9379533, -0.04931983, 0.30151751, 0.66318558, 0.51532523], + [0.9379533, 1., 0.30007991, -0.04781421, 0.88157256, 0.78052386], + [-0.04931983, 0.30007991, 1., -0.96717111, 0.71483595, 0.83053601], + [0.30151751, -0.04781421, -0.96717111, 1., -0.51366032, -0.66173113], + [0.66318558, 0.88157256, 0.71483595, -0.51366032, 1., 0.98317823], + [0.51532523, 0.78052386, 0.83053601, -0.66173113, 0.98317823, 1.]]) + + def test_non_array(self): + assert_almost_equal(np.corrcoef([0, 1, 0], [1, 0, 1]), + [[1., -1.], [-1., 1.]]) + + def test_simple(self): + tgt1 = corrcoef(self.A) + assert_almost_equal(tgt1, self.res1) + assert_(np.all(np.abs(tgt1) <= 1.0)) + + tgt2 = corrcoef(self.A, self.B) + assert_almost_equal(tgt2, self.res2) + assert_(np.all(np.abs(tgt2) <= 1.0)) + + def test_ddof(self): + # ddof raises DeprecationWarning + with suppress_warnings() as sup: + warnings.simplefilter("always") + assert_warns(DeprecationWarning, corrcoef, self.A, ddof=-1) + sup.filter(DeprecationWarning) + # ddof has no or negligible effect on the function + assert_almost_equal(corrcoef(self.A, ddof=-1), self.res1) + assert_almost_equal(corrcoef(self.A, self.B, ddof=-1), self.res2) + assert_almost_equal(corrcoef(self.A, ddof=3), self.res1) + assert_almost_equal(corrcoef(self.A, self.B, ddof=3), self.res2) + + def test_bias(self): + # bias raises DeprecationWarning + with suppress_warnings() as sup: + warnings.simplefilter("always") + assert_warns(DeprecationWarning, corrcoef, self.A, self.B, 1, 0) + assert_warns(DeprecationWarning, corrcoef, self.A, bias=0) + sup.filter(DeprecationWarning) + # bias has no or negligible effect on the function + assert_almost_equal(corrcoef(self.A, bias=1), self.res1) + + def test_complex(self): + x = np.array([[1, 2, 3], [1j, 2j, 3j]]) + res = corrcoef(x) + tgt = np.array([[1., -1.j], [1.j, 1.]]) + assert_allclose(res, tgt) + assert_(np.all(np.abs(res) <= 1.0)) + + def test_xy(self): + x = np.array([[1, 2, 3]]) + y = np.array([[1j, 2j, 3j]]) + assert_allclose(np.corrcoef(x, y), np.array([[1., -1.j], [1.j, 1.]])) + + def test_empty(self): + with warnings.catch_warnings(record=True): + warnings.simplefilter('always', RuntimeWarning) + assert_array_equal(corrcoef(np.array([])), np.nan) + assert_array_equal(corrcoef(np.array([]).reshape(0, 2)), + np.array([]).reshape(0, 0)) + assert_array_equal(corrcoef(np.array([]).reshape(2, 0)), + np.array([[np.nan, np.nan], [np.nan, np.nan]])) + + def test_extreme(self): + x = [[1e-100, 1e100], [1e100, 1e-100]] + with np.errstate(all='raise'): + c = corrcoef(x) + assert_array_almost_equal(c, np.array([[1., -1.], [-1., 1.]])) + assert_(np.all(np.abs(c) <= 1.0)) + + @pytest.mark.parametrize("test_type", [np.half, np.single, np.double, np.longdouble]) + def test_corrcoef_dtype(self, test_type): + cast_A = self.A.astype(test_type) + res = corrcoef(cast_A, dtype=test_type) + assert test_type == res.dtype + + +class TestCov: + x1 = np.array([[0, 2], [1, 1], [2, 0]]).T + res1 = np.array([[1., -1.], [-1., 1.]]) + x2 = np.array([0.0, 1.0, 2.0], ndmin=2) + frequencies = np.array([1, 4, 1]) + x2_repeats = np.array([[0.0], [1.0], [1.0], [1.0], [1.0], [2.0]]).T + res2 = np.array([[0.4, -0.4], [-0.4, 0.4]]) + unit_frequencies = np.ones(3, dtype=np.int_) + weights = np.array([1.0, 4.0, 1.0]) + res3 = np.array([[2. / 3., -2. / 3.], [-2. / 3., 2. / 3.]]) + unit_weights = np.ones(3) + x3 = np.array([0.3942, 0.5969, 0.7730, 0.9918, 0.7964]) + + def test_basic(self): + assert_allclose(cov(self.x1), self.res1) + + def test_complex(self): + x = np.array([[1, 2, 3], [1j, 2j, 3j]]) + res = np.array([[1., -1.j], [1.j, 1.]]) + assert_allclose(cov(x), res) + assert_allclose(cov(x, aweights=np.ones(3)), res) + + def test_xy(self): + x = np.array([[1, 2, 3]]) + y = np.array([[1j, 2j, 3j]]) + assert_allclose(cov(x, y), np.array([[1., -1.j], [1.j, 1.]])) + + def test_empty(self): + with warnings.catch_warnings(record=True): + warnings.simplefilter('always', RuntimeWarning) + assert_array_equal(cov(np.array([])), np.nan) + assert_array_equal(cov(np.array([]).reshape(0, 2)), + np.array([]).reshape(0, 0)) + assert_array_equal(cov(np.array([]).reshape(2, 0)), + np.array([[np.nan, np.nan], [np.nan, np.nan]])) + + def test_wrong_ddof(self): + with warnings.catch_warnings(record=True): + warnings.simplefilter('always', RuntimeWarning) + assert_array_equal(cov(self.x1, ddof=5), + np.array([[np.inf, -np.inf], + [-np.inf, np.inf]])) + + def test_1D_rowvar(self): + assert_allclose(cov(self.x3), cov(self.x3, rowvar=False)) + y = np.array([0.0780, 0.3107, 0.2111, 0.0334, 0.8501]) + assert_allclose(cov(self.x3, y), cov(self.x3, y, rowvar=False)) + + def test_1D_variance(self): + assert_allclose(cov(self.x3, ddof=1), np.var(self.x3, ddof=1)) + + def test_fweights(self): + assert_allclose(cov(self.x2, fweights=self.frequencies), + cov(self.x2_repeats)) + assert_allclose(cov(self.x1, fweights=self.frequencies), + self.res2) + assert_allclose(cov(self.x1, fweights=self.unit_frequencies), + self.res1) + nonint = self.frequencies + 0.5 + assert_raises(TypeError, cov, self.x1, fweights=nonint) + f = np.ones((2, 3), dtype=np.int_) + assert_raises(RuntimeError, cov, self.x1, fweights=f) + f = np.ones(2, dtype=np.int_) + assert_raises(RuntimeError, cov, self.x1, fweights=f) + f = -1 * np.ones(3, dtype=np.int_) + assert_raises(ValueError, cov, self.x1, fweights=f) + + def test_aweights(self): + assert_allclose(cov(self.x1, aweights=self.weights), self.res3) + assert_allclose(cov(self.x1, aweights=3.0 * self.weights), + cov(self.x1, aweights=self.weights)) + assert_allclose(cov(self.x1, aweights=self.unit_weights), self.res1) + w = np.ones((2, 3)) + assert_raises(RuntimeError, cov, self.x1, aweights=w) + w = np.ones(2) + assert_raises(RuntimeError, cov, self.x1, aweights=w) + w = -1.0 * np.ones(3) + assert_raises(ValueError, cov, self.x1, aweights=w) + + def test_unit_fweights_and_aweights(self): + assert_allclose(cov(self.x2, fweights=self.frequencies, + aweights=self.unit_weights), + cov(self.x2_repeats)) + assert_allclose(cov(self.x1, fweights=self.frequencies, + aweights=self.unit_weights), + self.res2) + assert_allclose(cov(self.x1, fweights=self.unit_frequencies, + aweights=self.unit_weights), + self.res1) + assert_allclose(cov(self.x1, fweights=self.unit_frequencies, + aweights=self.weights), + self.res3) + assert_allclose(cov(self.x1, fweights=self.unit_frequencies, + aweights=3.0 * self.weights), + cov(self.x1, aweights=self.weights)) + assert_allclose(cov(self.x1, fweights=self.unit_frequencies, + aweights=self.unit_weights), + self.res1) + + @pytest.mark.parametrize("test_type", [np.half, np.single, np.double, np.longdouble]) + def test_cov_dtype(self, test_type): + cast_x1 = self.x1.astype(test_type) + res = cov(cast_x1, dtype=test_type) + assert test_type == res.dtype + + +class Test_I0: + + def test_simple(self): + assert_almost_equal( + i0(0.5), + np.array(1.0634833707413234)) + + # need at least one test above 8, as the implementation is piecewise + A = np.array([0.49842636, 0.6969809, 0.22011976, 0.0155549, 10.0]) + expected = np.array([1.06307822, 1.12518299, 1.01214991, 1.00006049, 2815.71662847]) + assert_almost_equal(i0(A), expected) + assert_almost_equal(i0(-A), expected) + + B = np.array([[0.827002, 0.99959078], + [0.89694769, 0.39298162], + [0.37954418, 0.05206293], + [0.36465447, 0.72446427], + [0.48164949, 0.50324519]]) + assert_almost_equal( + i0(B), + np.array([[1.17843223, 1.26583466], + [1.21147086, 1.03898290], + [1.03633899, 1.00067775], + [1.03352052, 1.13557954], + [1.05884290, 1.06432317]])) + # Regression test for gh-11205 + i0_0 = np.i0([0.]) + assert_equal(i0_0.shape, (1,)) + assert_array_equal(np.i0([0.]), np.array([1.])) + + def test_non_array(self): + a = np.arange(4) + + class array_like: + __array_interface__ = a.__array_interface__ + + def __array_wrap__(self, arr): + return self + + # E.g. pandas series survive ufunc calls through array-wrap: + assert isinstance(np.abs(array_like()), array_like) + exp = np.i0(a) + res = np.i0(array_like()) + + assert_array_equal(exp, res) + + def test_complex(self): + a = np.array([0, 1 + 2j]) + with pytest.raises(TypeError, match="i0 not supported for complex values"): + res = i0(a) + +class TestKaiser: + + def test_simple(self): + assert_(np.isfinite(kaiser(1, 1.0))) + assert_almost_equal(kaiser(0, 1.0), + np.array([])) + assert_almost_equal(kaiser(2, 1.0), + np.array([0.78984831, 0.78984831])) + assert_almost_equal(kaiser(5, 1.0), + np.array([0.78984831, 0.94503323, 1., + 0.94503323, 0.78984831])) + assert_almost_equal(kaiser(5, 1.56789), + np.array([0.58285404, 0.88409679, 1., + 0.88409679, 0.58285404])) + + def test_int_beta(self): + kaiser(3, 4) + + +class TestMsort: + + def test_simple(self): + A = np.array([[0.44567325, 0.79115165, 0.54900530], + [0.36844147, 0.37325583, 0.96098397], + [0.64864341, 0.52929049, 0.39172155]]) + assert_almost_equal( + msort(A), + np.array([[0.36844147, 0.37325583, 0.39172155], + [0.44567325, 0.52929049, 0.54900530], + [0.64864341, 0.79115165, 0.96098397]])) + + +class TestMeshgrid: + + def test_simple(self): + [X, Y] = meshgrid([1, 2, 3], [4, 5, 6, 7]) + assert_array_equal(X, np.array([[1, 2, 3], + [1, 2, 3], + [1, 2, 3], + [1, 2, 3]])) + assert_array_equal(Y, np.array([[4, 4, 4], + [5, 5, 5], + [6, 6, 6], + [7, 7, 7]])) + + def test_single_input(self): + [X] = meshgrid([1, 2, 3, 4]) + assert_array_equal(X, np.array([1, 2, 3, 4])) + + def test_no_input(self): + args = [] + assert_array_equal([], meshgrid(*args)) + assert_array_equal([], meshgrid(*args, copy=False)) + + def test_indexing(self): + x = [1, 2, 3] + y = [4, 5, 6, 7] + [X, Y] = meshgrid(x, y, indexing='ij') + assert_array_equal(X, np.array([[1, 1, 1, 1], + [2, 2, 2, 2], + [3, 3, 3, 3]])) + assert_array_equal(Y, np.array([[4, 5, 6, 7], + [4, 5, 6, 7], + [4, 5, 6, 7]])) + + # Test expected shapes: + z = [8, 9] + assert_(meshgrid(x, y)[0].shape == (4, 3)) + assert_(meshgrid(x, y, indexing='ij')[0].shape == (3, 4)) + assert_(meshgrid(x, y, z)[0].shape == (4, 3, 2)) + assert_(meshgrid(x, y, z, indexing='ij')[0].shape == (3, 4, 2)) + + assert_raises(ValueError, meshgrid, x, y, indexing='notvalid') + + def test_sparse(self): + [X, Y] = meshgrid([1, 2, 3], [4, 5, 6, 7], sparse=True) + assert_array_equal(X, np.array([[1, 2, 3]])) + assert_array_equal(Y, np.array([[4], [5], [6], [7]])) + + def test_invalid_arguments(self): + # Test that meshgrid complains about invalid arguments + # Regression test for issue #4755: + # https://github.com/numpy/numpy/issues/4755 + assert_raises(TypeError, meshgrid, + [1, 2, 3], [4, 5, 6, 7], indices='ij') + + def test_return_type(self): + # Test for appropriate dtype in returned arrays. + # Regression test for issue #5297 + # https://github.com/numpy/numpy/issues/5297 + x = np.arange(0, 10, dtype=np.float32) + y = np.arange(10, 20, dtype=np.float64) + + X, Y = np.meshgrid(x,y) + + assert_(X.dtype == x.dtype) + assert_(Y.dtype == y.dtype) + + # copy + X, Y = np.meshgrid(x,y, copy=True) + + assert_(X.dtype == x.dtype) + assert_(Y.dtype == y.dtype) + + # sparse + X, Y = np.meshgrid(x,y, sparse=True) + + assert_(X.dtype == x.dtype) + assert_(Y.dtype == y.dtype) + + def test_writeback(self): + # Issue 8561 + X = np.array([1.1, 2.2]) + Y = np.array([3.3, 4.4]) + x, y = np.meshgrid(X, Y, sparse=False, copy=True) + + x[0, :] = 0 + assert_equal(x[0, :], 0) + assert_equal(x[1, :], X) + + +class TestPiecewise: + + def test_simple(self): + # Condition is single bool list + x = piecewise([0, 0], [True, False], [1]) + assert_array_equal(x, [1, 0]) + + # List of conditions: single bool list + x = piecewise([0, 0], [[True, False]], [1]) + assert_array_equal(x, [1, 0]) + + # Conditions is single bool array + x = piecewise([0, 0], np.array([True, False]), [1]) + assert_array_equal(x, [1, 0]) + + # Condition is single int array + x = piecewise([0, 0], np.array([1, 0]), [1]) + assert_array_equal(x, [1, 0]) + + # List of conditions: int array + x = piecewise([0, 0], [np.array([1, 0])], [1]) + assert_array_equal(x, [1, 0]) + + x = piecewise([0, 0], [[False, True]], [lambda x:-1]) + assert_array_equal(x, [0, -1]) + + assert_raises_regex(ValueError, '1 or 2 functions are expected', + piecewise, [0, 0], [[False, True]], []) + assert_raises_regex(ValueError, '1 or 2 functions are expected', + piecewise, [0, 0], [[False, True]], [1, 2, 3]) + + def test_two_conditions(self): + x = piecewise([1, 2], [[True, False], [False, True]], [3, 4]) + assert_array_equal(x, [3, 4]) + + def test_scalar_domains_three_conditions(self): + x = piecewise(3, [True, False, False], [4, 2, 0]) + assert_equal(x, 4) + + def test_default(self): + # No value specified for x[1], should be 0 + x = piecewise([1, 2], [True, False], [2]) + assert_array_equal(x, [2, 0]) + + # Should set x[1] to 3 + x = piecewise([1, 2], [True, False], [2, 3]) + assert_array_equal(x, [2, 3]) + + def test_0d(self): + x = np.array(3) + y = piecewise(x, x > 3, [4, 0]) + assert_(y.ndim == 0) + assert_(y == 0) + + x = 5 + y = piecewise(x, [True, False], [1, 0]) + assert_(y.ndim == 0) + assert_(y == 1) + + # With 3 ranges (It was failing, before) + y = piecewise(x, [False, False, True], [1, 2, 3]) + assert_array_equal(y, 3) + + def test_0d_comparison(self): + x = 3 + y = piecewise(x, [x <= 3, x > 3], [4, 0]) # Should succeed. + assert_equal(y, 4) + + # With 3 ranges (It was failing, before) + x = 4 + y = piecewise(x, [x <= 3, (x > 3) * (x <= 5), x > 5], [1, 2, 3]) + assert_array_equal(y, 2) + + assert_raises_regex(ValueError, '2 or 3 functions are expected', + piecewise, x, [x <= 3, x > 3], [1]) + assert_raises_regex(ValueError, '2 or 3 functions are expected', + piecewise, x, [x <= 3, x > 3], [1, 1, 1, 1]) + + def test_0d_0d_condition(self): + x = np.array(3) + c = np.array(x > 3) + y = piecewise(x, [c], [1, 2]) + assert_equal(y, 2) + + def test_multidimensional_extrafunc(self): + x = np.array([[-2.5, -1.5, -0.5], + [0.5, 1.5, 2.5]]) + y = piecewise(x, [x < 0, x >= 2], [-1, 1, 3]) + assert_array_equal(y, np.array([[-1., -1., -1.], + [3., 3., 1.]])) + + +class TestBincount: + + def test_simple(self): + y = np.bincount(np.arange(4)) + assert_array_equal(y, np.ones(4)) + + def test_simple2(self): + y = np.bincount(np.array([1, 5, 2, 4, 1])) + assert_array_equal(y, np.array([0, 2, 1, 0, 1, 1])) + + def test_simple_weight(self): + x = np.arange(4) + w = np.array([0.2, 0.3, 0.5, 0.1]) + y = np.bincount(x, w) + assert_array_equal(y, w) + + def test_simple_weight2(self): + x = np.array([1, 2, 4, 5, 2]) + w = np.array([0.2, 0.3, 0.5, 0.1, 0.2]) + y = np.bincount(x, w) + assert_array_equal(y, np.array([0, 0.2, 0.5, 0, 0.5, 0.1])) + + def test_with_minlength(self): + x = np.array([0, 1, 0, 1, 1]) + y = np.bincount(x, minlength=3) + assert_array_equal(y, np.array([2, 3, 0])) + x = [] + y = np.bincount(x, minlength=0) + assert_array_equal(y, np.array([])) + + def test_with_minlength_smaller_than_maxvalue(self): + x = np.array([0, 1, 1, 2, 2, 3, 3]) + y = np.bincount(x, minlength=2) + assert_array_equal(y, np.array([1, 2, 2, 2])) + y = np.bincount(x, minlength=0) + assert_array_equal(y, np.array([1, 2, 2, 2])) + + def test_with_minlength_and_weights(self): + x = np.array([1, 2, 4, 5, 2]) + w = np.array([0.2, 0.3, 0.5, 0.1, 0.2]) + y = np.bincount(x, w, 8) + assert_array_equal(y, np.array([0, 0.2, 0.5, 0, 0.5, 0.1, 0, 0])) + + def test_empty(self): + x = np.array([], dtype=int) + y = np.bincount(x) + assert_array_equal(x, y) + + def test_empty_with_minlength(self): + x = np.array([], dtype=int) + y = np.bincount(x, minlength=5) + assert_array_equal(y, np.zeros(5, dtype=int)) + + def test_with_incorrect_minlength(self): + x = np.array([], dtype=int) + assert_raises_regex(TypeError, + "'str' object cannot be interpreted", + lambda: np.bincount(x, minlength="foobar")) + assert_raises_regex(ValueError, + "must not be negative", + lambda: np.bincount(x, minlength=-1)) + + x = np.arange(5) + assert_raises_regex(TypeError, + "'str' object cannot be interpreted", + lambda: np.bincount(x, minlength="foobar")) + assert_raises_regex(ValueError, + "must not be negative", + lambda: np.bincount(x, minlength=-1)) + + @pytest.mark.skipif(not HAS_REFCOUNT, reason="Python lacks refcounts") + def test_dtype_reference_leaks(self): + # gh-6805 + intp_refcount = sys.getrefcount(np.dtype(np.intp)) + double_refcount = sys.getrefcount(np.dtype(np.double)) + + for j in range(10): + np.bincount([1, 2, 3]) + assert_equal(sys.getrefcount(np.dtype(np.intp)), intp_refcount) + assert_equal(sys.getrefcount(np.dtype(np.double)), double_refcount) + + for j in range(10): + np.bincount([1, 2, 3], [4, 5, 6]) + assert_equal(sys.getrefcount(np.dtype(np.intp)), intp_refcount) + assert_equal(sys.getrefcount(np.dtype(np.double)), double_refcount) + + @pytest.mark.parametrize("vals", [[[2, 2]], 2]) + def test_error_not_1d(self, vals): + # Test that values has to be 1-D (both as array and nested list) + vals_arr = np.asarray(vals) + with assert_raises(ValueError): + np.bincount(vals_arr) + with assert_raises(ValueError): + np.bincount(vals) + + +class TestInterp: + + def test_exceptions(self): + assert_raises(ValueError, interp, 0, [], []) + assert_raises(ValueError, interp, 0, [0], [1, 2]) + assert_raises(ValueError, interp, 0, [0, 1], [1, 2], period=0) + assert_raises(ValueError, interp, 0, [], [], period=360) + assert_raises(ValueError, interp, 0, [0], [1, 2], period=360) + + def test_basic(self): + x = np.linspace(0, 1, 5) + y = np.linspace(0, 1, 5) + x0 = np.linspace(0, 1, 50) + assert_almost_equal(np.interp(x0, x, y), x0) + + def test_right_left_behavior(self): + # Needs range of sizes to test different code paths. + # size ==1 is special cased, 1 < size < 5 is linear search, and + # size >= 5 goes through local search and possibly binary search. + for size in range(1, 10): + xp = np.arange(size, dtype=np.double) + yp = np.ones(size, dtype=np.double) + incpts = np.array([-1, 0, size - 1, size], dtype=np.double) + decpts = incpts[::-1] + + incres = interp(incpts, xp, yp) + decres = interp(decpts, xp, yp) + inctgt = np.array([1, 1, 1, 1], dtype=float) + dectgt = inctgt[::-1] + assert_equal(incres, inctgt) + assert_equal(decres, dectgt) + + incres = interp(incpts, xp, yp, left=0) + decres = interp(decpts, xp, yp, left=0) + inctgt = np.array([0, 1, 1, 1], dtype=float) + dectgt = inctgt[::-1] + assert_equal(incres, inctgt) + assert_equal(decres, dectgt) + + incres = interp(incpts, xp, yp, right=2) + decres = interp(decpts, xp, yp, right=2) + inctgt = np.array([1, 1, 1, 2], dtype=float) + dectgt = inctgt[::-1] + assert_equal(incres, inctgt) + assert_equal(decres, dectgt) + + incres = interp(incpts, xp, yp, left=0, right=2) + decres = interp(decpts, xp, yp, left=0, right=2) + inctgt = np.array([0, 1, 1, 2], dtype=float) + dectgt = inctgt[::-1] + assert_equal(incres, inctgt) + assert_equal(decres, dectgt) + + def test_scalar_interpolation_point(self): + x = np.linspace(0, 1, 5) + y = np.linspace(0, 1, 5) + x0 = 0 + assert_almost_equal(np.interp(x0, x, y), x0) + x0 = .3 + assert_almost_equal(np.interp(x0, x, y), x0) + x0 = np.float32(.3) + assert_almost_equal(np.interp(x0, x, y), x0) + x0 = np.float64(.3) + assert_almost_equal(np.interp(x0, x, y), x0) + x0 = np.nan + assert_almost_equal(np.interp(x0, x, y), x0) + + def test_non_finite_behavior_exact_x(self): + x = [1, 2, 2.5, 3, 4] + xp = [1, 2, 3, 4] + fp = [1, 2, np.inf, 4] + assert_almost_equal(np.interp(x, xp, fp), [1, 2, np.inf, np.inf, 4]) + fp = [1, 2, np.nan, 4] + assert_almost_equal(np.interp(x, xp, fp), [1, 2, np.nan, np.nan, 4]) + + @pytest.fixture(params=[ + lambda x: np.float_(x), + lambda x: _make_complex(x, 0), + lambda x: _make_complex(0, x), + lambda x: _make_complex(x, np.multiply(x, -2)) + ], ids=[ + 'real', + 'complex-real', + 'complex-imag', + 'complex-both' + ]) + def sc(self, request): + """ scale function used by the below tests """ + return request.param + + def test_non_finite_any_nan(self, sc): + """ test that nans are propagated """ + assert_equal(np.interp(0.5, [np.nan, 1], sc([ 0, 10])), sc(np.nan)) + assert_equal(np.interp(0.5, [ 0, np.nan], sc([ 0, 10])), sc(np.nan)) + assert_equal(np.interp(0.5, [ 0, 1], sc([np.nan, 10])), sc(np.nan)) + assert_equal(np.interp(0.5, [ 0, 1], sc([ 0, np.nan])), sc(np.nan)) + + def test_non_finite_inf(self, sc): + """ Test that interp between opposite infs gives nan """ + assert_equal(np.interp(0.5, [-np.inf, +np.inf], sc([ 0, 10])), sc(np.nan)) + assert_equal(np.interp(0.5, [ 0, 1], sc([-np.inf, +np.inf])), sc(np.nan)) + assert_equal(np.interp(0.5, [ 0, 1], sc([+np.inf, -np.inf])), sc(np.nan)) + + # unless the y values are equal + assert_equal(np.interp(0.5, [-np.inf, +np.inf], sc([ 10, 10])), sc(10)) + + def test_non_finite_half_inf_xf(self, sc): + """ Test that interp where both axes have a bound at inf gives nan """ + assert_equal(np.interp(0.5, [-np.inf, 1], sc([-np.inf, 10])), sc(np.nan)) + assert_equal(np.interp(0.5, [-np.inf, 1], sc([+np.inf, 10])), sc(np.nan)) + assert_equal(np.interp(0.5, [-np.inf, 1], sc([ 0, -np.inf])), sc(np.nan)) + assert_equal(np.interp(0.5, [-np.inf, 1], sc([ 0, +np.inf])), sc(np.nan)) + assert_equal(np.interp(0.5, [ 0, +np.inf], sc([-np.inf, 10])), sc(np.nan)) + assert_equal(np.interp(0.5, [ 0, +np.inf], sc([+np.inf, 10])), sc(np.nan)) + assert_equal(np.interp(0.5, [ 0, +np.inf], sc([ 0, -np.inf])), sc(np.nan)) + assert_equal(np.interp(0.5, [ 0, +np.inf], sc([ 0, +np.inf])), sc(np.nan)) + + def test_non_finite_half_inf_x(self, sc): + """ Test interp where the x axis has a bound at inf """ + assert_equal(np.interp(0.5, [-np.inf, -np.inf], sc([0, 10])), sc(10)) + assert_equal(np.interp(0.5, [-np.inf, 1 ], sc([0, 10])), sc(10)) + assert_equal(np.interp(0.5, [ 0, +np.inf], sc([0, 10])), sc(0)) + assert_equal(np.interp(0.5, [+np.inf, +np.inf], sc([0, 10])), sc(0)) + + def test_non_finite_half_inf_f(self, sc): + """ Test interp where the f axis has a bound at inf """ + assert_equal(np.interp(0.5, [0, 1], sc([ 0, -np.inf])), sc(-np.inf)) + assert_equal(np.interp(0.5, [0, 1], sc([ 0, +np.inf])), sc(+np.inf)) + assert_equal(np.interp(0.5, [0, 1], sc([-np.inf, 10])), sc(-np.inf)) + assert_equal(np.interp(0.5, [0, 1], sc([+np.inf, 10])), sc(+np.inf)) + assert_equal(np.interp(0.5, [0, 1], sc([-np.inf, -np.inf])), sc(-np.inf)) + assert_equal(np.interp(0.5, [0, 1], sc([+np.inf, +np.inf])), sc(+np.inf)) + + def test_complex_interp(self): + # test complex interpolation + x = np.linspace(0, 1, 5) + y = np.linspace(0, 1, 5) + (1 + np.linspace(0, 1, 5))*1.0j + x0 = 0.3 + y0 = x0 + (1+x0)*1.0j + assert_almost_equal(np.interp(x0, x, y), y0) + # test complex left and right + x0 = -1 + left = 2 + 3.0j + assert_almost_equal(np.interp(x0, x, y, left=left), left) + x0 = 2.0 + right = 2 + 3.0j + assert_almost_equal(np.interp(x0, x, y, right=right), right) + # test complex non finite + x = [1, 2, 2.5, 3, 4] + xp = [1, 2, 3, 4] + fp = [1, 2+1j, np.inf, 4] + y = [1, 2+1j, np.inf+0.5j, np.inf, 4] + assert_almost_equal(np.interp(x, xp, fp), y) + # test complex periodic + x = [-180, -170, -185, 185, -10, -5, 0, 365] + xp = [190, -190, 350, -350] + fp = [5+1.0j, 10+2j, 3+3j, 4+4j] + y = [7.5+1.5j, 5.+1.0j, 8.75+1.75j, 6.25+1.25j, 3.+3j, 3.25+3.25j, + 3.5+3.5j, 3.75+3.75j] + assert_almost_equal(np.interp(x, xp, fp, period=360), y) + + def test_zero_dimensional_interpolation_point(self): + x = np.linspace(0, 1, 5) + y = np.linspace(0, 1, 5) + x0 = np.array(.3) + assert_almost_equal(np.interp(x0, x, y), x0) + + xp = np.array([0, 2, 4]) + fp = np.array([1, -1, 1]) + + actual = np.interp(np.array(1), xp, fp) + assert_equal(actual, 0) + assert_(isinstance(actual, np.float64)) + + actual = np.interp(np.array(4.5), xp, fp, period=4) + assert_equal(actual, 0.5) + assert_(isinstance(actual, np.float64)) + + def test_if_len_x_is_small(self): + xp = np.arange(0, 10, 0.0001) + fp = np.sin(xp) + assert_almost_equal(np.interp(np.pi, xp, fp), 0.0) + + def test_period(self): + x = [-180, -170, -185, 185, -10, -5, 0, 365] + xp = [190, -190, 350, -350] + fp = [5, 10, 3, 4] + y = [7.5, 5., 8.75, 6.25, 3., 3.25, 3.5, 3.75] + assert_almost_equal(np.interp(x, xp, fp, period=360), y) + x = np.array(x, order='F').reshape(2, -1) + y = np.array(y, order='C').reshape(2, -1) + assert_almost_equal(np.interp(x, xp, fp, period=360), y) + + +def compare_results(res, desired): + for i in range(len(desired)): + assert_array_equal(res[i], desired[i]) + + +class TestPercentile: + + def test_basic(self): + x = np.arange(8) * 0.5 + assert_equal(np.percentile(x, 0), 0.) + assert_equal(np.percentile(x, 100), 3.5) + assert_equal(np.percentile(x, 50), 1.75) + x[1] = np.nan + assert_equal(np.percentile(x, 0), np.nan) + assert_equal(np.percentile(x, 0, interpolation='nearest'), np.nan) + + def test_fraction(self): + x = [Fraction(i, 2) for i in range(8)] + + p = np.percentile(x, Fraction(0)) + assert_equal(p, Fraction(0)) + assert_equal(type(p), Fraction) + + p = np.percentile(x, Fraction(100)) + assert_equal(p, Fraction(7, 2)) + assert_equal(type(p), Fraction) + + p = np.percentile(x, Fraction(50)) + assert_equal(p, Fraction(7, 4)) + assert_equal(type(p), Fraction) + + def test_api(self): + d = np.ones(5) + np.percentile(d, 5, None, None, False) + np.percentile(d, 5, None, None, False, 'linear') + o = np.ones((1,)) + np.percentile(d, 5, None, o, False, 'linear') + + def test_2D(self): + x = np.array([[1, 1, 1], + [1, 1, 1], + [4, 4, 3], + [1, 1, 1], + [1, 1, 1]]) + assert_array_equal(np.percentile(x, 50, axis=0), [1, 1, 1]) + + def test_linear(self): + + # Test defaults + assert_equal(np.percentile(range(10), 50), 4.5) + + # explicitly specify interpolation_method 'linear' (the default) + assert_equal(np.percentile(range(10), 50, + interpolation='linear'), 4.5) + + def test_lower_higher(self): + + # interpolation_method 'lower'/'higher' + assert_equal(np.percentile(range(10), 50, + interpolation='lower'), 4) + assert_equal(np.percentile(range(10), 50, + interpolation='higher'), 5) + + def test_midpoint(self): + assert_equal(np.percentile(range(10), 51, + interpolation='midpoint'), 4.5) + assert_equal(np.percentile(range(11), 51, + interpolation='midpoint'), 5.5) + assert_equal(np.percentile(range(11), 50, + interpolation='midpoint'), 5) + + def test_nearest(self): + assert_equal(np.percentile(range(10), 51, + interpolation='nearest'), 5) + assert_equal(np.percentile(range(10), 49, + interpolation='nearest'), 4) + + def test_sequence(self): + x = np.arange(8) * 0.5 + assert_equal(np.percentile(x, [0, 100, 50]), [0, 3.5, 1.75]) + + def test_axis(self): + x = np.arange(12).reshape(3, 4) + + assert_equal(np.percentile(x, (25, 50, 100)), [2.75, 5.5, 11.0]) + + r0 = [[2, 3, 4, 5], [4, 5, 6, 7], [8, 9, 10, 11]] + assert_equal(np.percentile(x, (25, 50, 100), axis=0), r0) + + r1 = [[0.75, 1.5, 3], [4.75, 5.5, 7], [8.75, 9.5, 11]] + assert_equal(np.percentile(x, (25, 50, 100), axis=1), np.array(r1).T) + + # ensure qth axis is always first as with np.array(old_percentile(..)) + x = np.arange(3 * 4 * 5 * 6).reshape(3, 4, 5, 6) + assert_equal(np.percentile(x, (25, 50)).shape, (2,)) + assert_equal(np.percentile(x, (25, 50, 75)).shape, (3,)) + assert_equal(np.percentile(x, (25, 50), axis=0).shape, (2, 4, 5, 6)) + assert_equal(np.percentile(x, (25, 50), axis=1).shape, (2, 3, 5, 6)) + assert_equal(np.percentile(x, (25, 50), axis=2).shape, (2, 3, 4, 6)) + assert_equal(np.percentile(x, (25, 50), axis=3).shape, (2, 3, 4, 5)) + assert_equal( + np.percentile(x, (25, 50, 75), axis=1).shape, (3, 3, 5, 6)) + assert_equal(np.percentile(x, (25, 50), + interpolation="higher").shape, (2,)) + assert_equal(np.percentile(x, (25, 50, 75), + interpolation="higher").shape, (3,)) + assert_equal(np.percentile(x, (25, 50), axis=0, + interpolation="higher").shape, (2, 4, 5, 6)) + assert_equal(np.percentile(x, (25, 50), axis=1, + interpolation="higher").shape, (2, 3, 5, 6)) + assert_equal(np.percentile(x, (25, 50), axis=2, + interpolation="higher").shape, (2, 3, 4, 6)) + assert_equal(np.percentile(x, (25, 50), axis=3, + interpolation="higher").shape, (2, 3, 4, 5)) + assert_equal(np.percentile(x, (25, 50, 75), axis=1, + interpolation="higher").shape, (3, 3, 5, 6)) + + def test_scalar_q(self): + # test for no empty dimensions for compatibility with old percentile + x = np.arange(12).reshape(3, 4) + assert_equal(np.percentile(x, 50), 5.5) + assert_(np.isscalar(np.percentile(x, 50))) + r0 = np.array([4., 5., 6., 7.]) + assert_equal(np.percentile(x, 50, axis=0), r0) + assert_equal(np.percentile(x, 50, axis=0).shape, r0.shape) + r1 = np.array([1.5, 5.5, 9.5]) + assert_almost_equal(np.percentile(x, 50, axis=1), r1) + assert_equal(np.percentile(x, 50, axis=1).shape, r1.shape) + + out = np.empty(1) + assert_equal(np.percentile(x, 50, out=out), 5.5) + assert_equal(out, 5.5) + out = np.empty(4) + assert_equal(np.percentile(x, 50, axis=0, out=out), r0) + assert_equal(out, r0) + out = np.empty(3) + assert_equal(np.percentile(x, 50, axis=1, out=out), r1) + assert_equal(out, r1) + + # test for no empty dimensions for compatibility with old percentile + x = np.arange(12).reshape(3, 4) + assert_equal(np.percentile(x, 50, interpolation='lower'), 5.) + assert_(np.isscalar(np.percentile(x, 50))) + r0 = np.array([4., 5., 6., 7.]) + c0 = np.percentile(x, 50, interpolation='lower', axis=0) + assert_equal(c0, r0) + assert_equal(c0.shape, r0.shape) + r1 = np.array([1., 5., 9.]) + c1 = np.percentile(x, 50, interpolation='lower', axis=1) + assert_almost_equal(c1, r1) + assert_equal(c1.shape, r1.shape) + + out = np.empty((), dtype=x.dtype) + c = np.percentile(x, 50, interpolation='lower', out=out) + assert_equal(c, 5) + assert_equal(out, 5) + out = np.empty(4, dtype=x.dtype) + c = np.percentile(x, 50, interpolation='lower', axis=0, out=out) + assert_equal(c, r0) + assert_equal(out, r0) + out = np.empty(3, dtype=x.dtype) + c = np.percentile(x, 50, interpolation='lower', axis=1, out=out) + assert_equal(c, r1) + assert_equal(out, r1) + + def test_exception(self): + assert_raises(ValueError, np.percentile, [1, 2], 56, + interpolation='foobar') + assert_raises(ValueError, np.percentile, [1], 101) + assert_raises(ValueError, np.percentile, [1], -1) + assert_raises(ValueError, np.percentile, [1], list(range(50)) + [101]) + assert_raises(ValueError, np.percentile, [1], list(range(50)) + [-0.1]) + + def test_percentile_list(self): + assert_equal(np.percentile([1, 2, 3], 0), 1) + + def test_percentile_out(self): + x = np.array([1, 2, 3]) + y = np.zeros((3,)) + p = (1, 2, 3) + np.percentile(x, p, out=y) + assert_equal(y, np.percentile(x, p)) + + x = np.array([[1, 2, 3], + [4, 5, 6]]) + + y = np.zeros((3, 3)) + np.percentile(x, p, axis=0, out=y) + assert_equal(y, np.percentile(x, p, axis=0)) + + y = np.zeros((3, 2)) + np.percentile(x, p, axis=1, out=y) + assert_equal(y, np.percentile(x, p, axis=1)) + + x = np.arange(12).reshape(3, 4) + # q.dim > 1, float + r0 = np.array([[2., 3., 4., 5.], [4., 5., 6., 7.]]) + out = np.empty((2, 4)) + assert_equal(np.percentile(x, (25, 50), axis=0, out=out), r0) + assert_equal(out, r0) + r1 = np.array([[0.75, 4.75, 8.75], [1.5, 5.5, 9.5]]) + out = np.empty((2, 3)) + assert_equal(np.percentile(x, (25, 50), axis=1, out=out), r1) + assert_equal(out, r1) + + # q.dim > 1, int + r0 = np.array([[0, 1, 2, 3], [4, 5, 6, 7]]) + out = np.empty((2, 4), dtype=x.dtype) + c = np.percentile(x, (25, 50), interpolation='lower', axis=0, out=out) + assert_equal(c, r0) + assert_equal(out, r0) + r1 = np.array([[0, 4, 8], [1, 5, 9]]) + out = np.empty((2, 3), dtype=x.dtype) + c = np.percentile(x, (25, 50), interpolation='lower', axis=1, out=out) + assert_equal(c, r1) + assert_equal(out, r1) + + def test_percentile_empty_dim(self): + # empty dims are preserved + d = np.arange(11 * 2).reshape(11, 1, 2, 1) + assert_array_equal(np.percentile(d, 50, axis=0).shape, (1, 2, 1)) + assert_array_equal(np.percentile(d, 50, axis=1).shape, (11, 2, 1)) + assert_array_equal(np.percentile(d, 50, axis=2).shape, (11, 1, 1)) + assert_array_equal(np.percentile(d, 50, axis=3).shape, (11, 1, 2)) + assert_array_equal(np.percentile(d, 50, axis=-1).shape, (11, 1, 2)) + assert_array_equal(np.percentile(d, 50, axis=-2).shape, (11, 1, 1)) + assert_array_equal(np.percentile(d, 50, axis=-3).shape, (11, 2, 1)) + assert_array_equal(np.percentile(d, 50, axis=-4).shape, (1, 2, 1)) + + assert_array_equal(np.percentile(d, 50, axis=2, + interpolation='midpoint').shape, + (11, 1, 1)) + assert_array_equal(np.percentile(d, 50, axis=-2, + interpolation='midpoint').shape, + (11, 1, 1)) + + assert_array_equal(np.array(np.percentile(d, [10, 50], axis=0)).shape, + (2, 1, 2, 1)) + assert_array_equal(np.array(np.percentile(d, [10, 50], axis=1)).shape, + (2, 11, 2, 1)) + assert_array_equal(np.array(np.percentile(d, [10, 50], axis=2)).shape, + (2, 11, 1, 1)) + assert_array_equal(np.array(np.percentile(d, [10, 50], axis=3)).shape, + (2, 11, 1, 2)) + + def test_percentile_no_overwrite(self): + a = np.array([2, 3, 4, 1]) + np.percentile(a, [50], overwrite_input=False) + assert_equal(a, np.array([2, 3, 4, 1])) + + a = np.array([2, 3, 4, 1]) + np.percentile(a, [50]) + assert_equal(a, np.array([2, 3, 4, 1])) + + def test_no_p_overwrite(self): + p = np.linspace(0., 100., num=5) + np.percentile(np.arange(100.), p, interpolation="midpoint") + assert_array_equal(p, np.linspace(0., 100., num=5)) + p = np.linspace(0., 100., num=5).tolist() + np.percentile(np.arange(100.), p, interpolation="midpoint") + assert_array_equal(p, np.linspace(0., 100., num=5).tolist()) + + def test_percentile_overwrite(self): + a = np.array([2, 3, 4, 1]) + b = np.percentile(a, [50], overwrite_input=True) + assert_equal(b, np.array([2.5])) + + b = np.percentile([2, 3, 4, 1], [50], overwrite_input=True) + assert_equal(b, np.array([2.5])) + + def test_extended_axis(self): + o = np.random.normal(size=(71, 23)) + x = np.dstack([o] * 10) + assert_equal(np.percentile(x, 30, axis=(0, 1)), np.percentile(o, 30)) + x = np.moveaxis(x, -1, 0) + assert_equal(np.percentile(x, 30, axis=(-2, -1)), np.percentile(o, 30)) + x = x.swapaxes(0, 1).copy() + assert_equal(np.percentile(x, 30, axis=(0, -1)), np.percentile(o, 30)) + x = x.swapaxes(0, 1).copy() + + assert_equal(np.percentile(x, [25, 60], axis=(0, 1, 2)), + np.percentile(x, [25, 60], axis=None)) + assert_equal(np.percentile(x, [25, 60], axis=(0,)), + np.percentile(x, [25, 60], axis=0)) + + d = np.arange(3 * 5 * 7 * 11).reshape((3, 5, 7, 11)) + np.random.shuffle(d.ravel()) + assert_equal(np.percentile(d, 25, axis=(0, 1, 2))[0], + np.percentile(d[:,:,:, 0].flatten(), 25)) + assert_equal(np.percentile(d, [10, 90], axis=(0, 1, 3))[:, 1], + np.percentile(d[:,:, 1,:].flatten(), [10, 90])) + assert_equal(np.percentile(d, 25, axis=(3, 1, -4))[2], + np.percentile(d[:,:, 2,:].flatten(), 25)) + assert_equal(np.percentile(d, 25, axis=(3, 1, 2))[2], + np.percentile(d[2,:,:,:].flatten(), 25)) + assert_equal(np.percentile(d, 25, axis=(3, 2))[2, 1], + np.percentile(d[2, 1,:,:].flatten(), 25)) + assert_equal(np.percentile(d, 25, axis=(1, -2))[2, 1], + np.percentile(d[2,:,:, 1].flatten(), 25)) + assert_equal(np.percentile(d, 25, axis=(1, 3))[2, 2], + np.percentile(d[2,:, 2,:].flatten(), 25)) + + def test_extended_axis_invalid(self): + d = np.ones((3, 5, 7, 11)) + assert_raises(np.AxisError, np.percentile, d, axis=-5, q=25) + assert_raises(np.AxisError, np.percentile, d, axis=(0, -5), q=25) + assert_raises(np.AxisError, np.percentile, d, axis=4, q=25) + assert_raises(np.AxisError, np.percentile, d, axis=(0, 4), q=25) + # each of these refers to the same axis twice + assert_raises(ValueError, np.percentile, d, axis=(1, 1), q=25) + assert_raises(ValueError, np.percentile, d, axis=(-1, -1), q=25) + assert_raises(ValueError, np.percentile, d, axis=(3, -1), q=25) + + def test_keepdims(self): + d = np.ones((3, 5, 7, 11)) + assert_equal(np.percentile(d, 7, axis=None, keepdims=True).shape, + (1, 1, 1, 1)) + assert_equal(np.percentile(d, 7, axis=(0, 1), keepdims=True).shape, + (1, 1, 7, 11)) + assert_equal(np.percentile(d, 7, axis=(0, 3), keepdims=True).shape, + (1, 5, 7, 1)) + assert_equal(np.percentile(d, 7, axis=(1,), keepdims=True).shape, + (3, 1, 7, 11)) + assert_equal(np.percentile(d, 7, (0, 1, 2, 3), keepdims=True).shape, + (1, 1, 1, 1)) + assert_equal(np.percentile(d, 7, axis=(0, 1, 3), keepdims=True).shape, + (1, 1, 7, 1)) + + assert_equal(np.percentile(d, [1, 7], axis=(0, 1, 3), + keepdims=True).shape, (2, 1, 1, 7, 1)) + assert_equal(np.percentile(d, [1, 7], axis=(0, 3), + keepdims=True).shape, (2, 1, 5, 7, 1)) + + def test_out(self): + o = np.zeros((4,)) + d = np.ones((3, 4)) + assert_equal(np.percentile(d, 0, 0, out=o), o) + assert_equal(np.percentile(d, 0, 0, interpolation='nearest', out=o), o) + o = np.zeros((3,)) + assert_equal(np.percentile(d, 1, 1, out=o), o) + assert_equal(np.percentile(d, 1, 1, interpolation='nearest', out=o), o) + + o = np.zeros(()) + assert_equal(np.percentile(d, 2, out=o), o) + assert_equal(np.percentile(d, 2, interpolation='nearest', out=o), o) + + def test_out_nan(self): + with warnings.catch_warnings(record=True): + warnings.filterwarnings('always', '', RuntimeWarning) + o = np.zeros((4,)) + d = np.ones((3, 4)) + d[2, 1] = np.nan + assert_equal(np.percentile(d, 0, 0, out=o), o) + assert_equal( + np.percentile(d, 0, 0, interpolation='nearest', out=o), o) + o = np.zeros((3,)) + assert_equal(np.percentile(d, 1, 1, out=o), o) + assert_equal( + np.percentile(d, 1, 1, interpolation='nearest', out=o), o) + o = np.zeros(()) + assert_equal(np.percentile(d, 1, out=o), o) + assert_equal( + np.percentile(d, 1, interpolation='nearest', out=o), o) + + def test_nan_behavior(self): + a = np.arange(24, dtype=float) + a[2] = np.nan + assert_equal(np.percentile(a, 0.3), np.nan) + assert_equal(np.percentile(a, 0.3, axis=0), np.nan) + assert_equal(np.percentile(a, [0.3, 0.6], axis=0), + np.array([np.nan] * 2)) + + a = np.arange(24, dtype=float).reshape(2, 3, 4) + a[1, 2, 3] = np.nan + a[1, 1, 2] = np.nan + + # no axis + assert_equal(np.percentile(a, 0.3), np.nan) + assert_equal(np.percentile(a, 0.3).ndim, 0) + + # axis0 zerod + b = np.percentile(np.arange(24, dtype=float).reshape(2, 3, 4), 0.3, 0) + b[2, 3] = np.nan + b[1, 2] = np.nan + assert_equal(np.percentile(a, 0.3, 0), b) + + # axis0 not zerod + b = np.percentile(np.arange(24, dtype=float).reshape(2, 3, 4), + [0.3, 0.6], 0) + b[:, 2, 3] = np.nan + b[:, 1, 2] = np.nan + assert_equal(np.percentile(a, [0.3, 0.6], 0), b) + + # axis1 zerod + b = np.percentile(np.arange(24, dtype=float).reshape(2, 3, 4), 0.3, 1) + b[1, 3] = np.nan + b[1, 2] = np.nan + assert_equal(np.percentile(a, 0.3, 1), b) + # axis1 not zerod + b = np.percentile( + np.arange(24, dtype=float).reshape(2, 3, 4), [0.3, 0.6], 1) + b[:, 1, 3] = np.nan + b[:, 1, 2] = np.nan + assert_equal(np.percentile(a, [0.3, 0.6], 1), b) + + # axis02 zerod + b = np.percentile( + np.arange(24, dtype=float).reshape(2, 3, 4), 0.3, (0, 2)) + b[1] = np.nan + b[2] = np.nan + assert_equal(np.percentile(a, 0.3, (0, 2)), b) + # axis02 not zerod + b = np.percentile(np.arange(24, dtype=float).reshape(2, 3, 4), + [0.3, 0.6], (0, 2)) + b[:, 1] = np.nan + b[:, 2] = np.nan + assert_equal(np.percentile(a, [0.3, 0.6], (0, 2)), b) + # axis02 not zerod with nearest interpolation + b = np.percentile(np.arange(24, dtype=float).reshape(2, 3, 4), + [0.3, 0.6], (0, 2), interpolation='nearest') + b[:, 1] = np.nan + b[:, 2] = np.nan + assert_equal(np.percentile( + a, [0.3, 0.6], (0, 2), interpolation='nearest'), b) + + +class TestQuantile: + # most of this is already tested by TestPercentile + + def test_basic(self): + x = np.arange(8) * 0.5 + assert_equal(np.quantile(x, 0), 0.) + assert_equal(np.quantile(x, 1), 3.5) + assert_equal(np.quantile(x, 0.5), 1.75) + + def test_correct_quantile_value(self): + a = np.array([True]) + tf_quant = np.quantile(True, False) + assert_equal(tf_quant, a[0]) + assert_equal(type(tf_quant), a.dtype) + a = np.array([False, True, True]) + quant_res = np.quantile(a, a) + assert_array_equal(quant_res, a) + assert_equal(a.dtype, quant_res.dtype) + + def test_fraction(self): + # fractional input, integral quantile + x = [Fraction(i, 2) for i in range(8)] + + q = np.quantile(x, 0) + assert_equal(q, 0) + assert_equal(type(q), Fraction) + + q = np.quantile(x, 1) + assert_equal(q, Fraction(7, 2)) + assert_equal(type(q), Fraction) + + q = np.quantile(x, Fraction(1, 2)) + assert_equal(q, Fraction(7, 4)) + assert_equal(type(q), Fraction) + + # repeat with integral input but fractional quantile + x = np.arange(8) + assert_equal(np.quantile(x, Fraction(1, 2)), Fraction(7, 2)) + + def test_no_p_overwrite(self): + # this is worth retesting, because quantile does not make a copy + p0 = np.array([0, 0.75, 0.25, 0.5, 1.0]) + p = p0.copy() + np.quantile(np.arange(100.), p, interpolation="midpoint") + assert_array_equal(p, p0) + + p0 = p0.tolist() + p = p.tolist() + np.quantile(np.arange(100.), p, interpolation="midpoint") + assert_array_equal(p, p0) + + def test_quantile_monotonic(self): + # GH 14685 + # test that the return value of quantile is monotonic if p0 is ordered + p0 = np.arange(0, 1, 0.01) + quantile = np.quantile(np.array([0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 1, 1, 9, 9, 9, + 8, 8, 7]) * 0.1, p0) + assert_equal(np.sort(quantile), quantile) + + @hypothesis.given( + arr=arrays(dtype=np.float64, + shape=st.integers(min_value=3, max_value=1000), + elements=st.floats(allow_infinity=False, allow_nan=False, + min_value=-1e300, max_value=1e300))) + def test_quantile_monotonic_hypo(self, arr): + p0 = np.arange(0, 1, 0.01) + quantile = np.quantile(arr, p0) + assert_equal(np.sort(quantile), quantile) + + +class TestLerp: + @hypothesis.given(t0=st.floats(allow_nan=False, allow_infinity=False, + min_value=0, max_value=1), + t1=st.floats(allow_nan=False, allow_infinity=False, + min_value=0, max_value=1), + a = st.floats(allow_nan=False, allow_infinity=False, + min_value=-1e300, max_value=1e300), + b = st.floats(allow_nan=False, allow_infinity=False, + min_value=-1e300, max_value=1e300)) + def test_lerp_monotonic(self, t0, t1, a, b): + l0 = np.lib.function_base._lerp(a, b, t0) + l1 = np.lib.function_base._lerp(a, b, t1) + if t0 == t1 or a == b: + assert l0 == l1 # uninteresting + elif (t0 < t1) == (a < b): + assert l0 <= l1 + else: + assert l0 >= l1 + + @hypothesis.given(t=st.floats(allow_nan=False, allow_infinity=False, + min_value=0, max_value=1), + a=st.floats(allow_nan=False, allow_infinity=False, + min_value=-1e300, max_value=1e300), + b=st.floats(allow_nan=False, allow_infinity=False, + min_value=-1e300, max_value=1e300)) + def test_lerp_bounded(self, t, a, b): + if a <= b: + assert a <= np.lib.function_base._lerp(a, b, t) <= b + else: + assert b <= np.lib.function_base._lerp(a, b, t) <= a + + @hypothesis.given(t=st.floats(allow_nan=False, allow_infinity=False, + min_value=0, max_value=1), + a=st.floats(allow_nan=False, allow_infinity=False, + min_value=-1e300, max_value=1e300), + b=st.floats(allow_nan=False, allow_infinity=False, + min_value=-1e300, max_value=1e300)) + def test_lerp_symmetric(self, t, a, b): + # double subtraction is needed to remove the extra precision of t < 0.5 + left = np.lib.function_base._lerp(a, b, 1 - (1 - t)) + right = np.lib.function_base._lerp(b, a, 1 - t) + assert left == right + + def test_lerp_0d_inputs(self): + a = np.array(2) + b = np.array(5) + t = np.array(0.2) + assert np.lib.function_base._lerp(a, b, t) == 2.6 + + +class TestMedian: + + def test_basic(self): + a0 = np.array(1) + a1 = np.arange(2) + a2 = np.arange(6).reshape(2, 3) + assert_equal(np.median(a0), 1) + assert_allclose(np.median(a1), 0.5) + assert_allclose(np.median(a2), 2.5) + assert_allclose(np.median(a2, axis=0), [1.5, 2.5, 3.5]) + assert_equal(np.median(a2, axis=1), [1, 4]) + assert_allclose(np.median(a2, axis=None), 2.5) + + a = np.array([0.0444502, 0.0463301, 0.141249, 0.0606775]) + assert_almost_equal((a[1] + a[3]) / 2., np.median(a)) + a = np.array([0.0463301, 0.0444502, 0.141249]) + assert_equal(a[0], np.median(a)) + a = np.array([0.0444502, 0.141249, 0.0463301]) + assert_equal(a[-1], np.median(a)) + # check array scalar result + assert_equal(np.median(a).ndim, 0) + a[1] = np.nan + assert_equal(np.median(a).ndim, 0) + + def test_axis_keyword(self): + a3 = np.array([[2, 3], + [0, 1], + [6, 7], + [4, 5]]) + for a in [a3, np.random.randint(0, 100, size=(2, 3, 4))]: + orig = a.copy() + np.median(a, axis=None) + for ax in range(a.ndim): + np.median(a, axis=ax) + assert_array_equal(a, orig) + + assert_allclose(np.median(a3, axis=0), [3, 4]) + assert_allclose(np.median(a3.T, axis=1), [3, 4]) + assert_allclose(np.median(a3), 3.5) + assert_allclose(np.median(a3, axis=None), 3.5) + assert_allclose(np.median(a3.T), 3.5) + + def test_overwrite_keyword(self): + a3 = np.array([[2, 3], + [0, 1], + [6, 7], + [4, 5]]) + a0 = np.array(1) + a1 = np.arange(2) + a2 = np.arange(6).reshape(2, 3) + assert_allclose(np.median(a0.copy(), overwrite_input=True), 1) + assert_allclose(np.median(a1.copy(), overwrite_input=True), 0.5) + assert_allclose(np.median(a2.copy(), overwrite_input=True), 2.5) + assert_allclose(np.median(a2.copy(), overwrite_input=True, axis=0), + [1.5, 2.5, 3.5]) + assert_allclose( + np.median(a2.copy(), overwrite_input=True, axis=1), [1, 4]) + assert_allclose( + np.median(a2.copy(), overwrite_input=True, axis=None), 2.5) + assert_allclose( + np.median(a3.copy(), overwrite_input=True, axis=0), [3, 4]) + assert_allclose(np.median(a3.T.copy(), overwrite_input=True, axis=1), + [3, 4]) + + a4 = np.arange(3 * 4 * 5, dtype=np.float32).reshape((3, 4, 5)) + np.random.shuffle(a4.ravel()) + assert_allclose(np.median(a4, axis=None), + np.median(a4.copy(), axis=None, overwrite_input=True)) + assert_allclose(np.median(a4, axis=0), + np.median(a4.copy(), axis=0, overwrite_input=True)) + assert_allclose(np.median(a4, axis=1), + np.median(a4.copy(), axis=1, overwrite_input=True)) + assert_allclose(np.median(a4, axis=2), + np.median(a4.copy(), axis=2, overwrite_input=True)) + + def test_array_like(self): + x = [1, 2, 3] + assert_almost_equal(np.median(x), 2) + x2 = [x] + assert_almost_equal(np.median(x2), 2) + assert_allclose(np.median(x2, axis=0), x) + + def test_subclass(self): + # gh-3846 + class MySubClass(np.ndarray): + + def __new__(cls, input_array, info=None): + obj = np.asarray(input_array).view(cls) + obj.info = info + return obj + + def mean(self, axis=None, dtype=None, out=None): + return -7 + + a = MySubClass([1, 2, 3]) + assert_equal(np.median(a), -7) + + def test_out(self): + o = np.zeros((4,)) + d = np.ones((3, 4)) + assert_equal(np.median(d, 0, out=o), o) + o = np.zeros((3,)) + assert_equal(np.median(d, 1, out=o), o) + o = np.zeros(()) + assert_equal(np.median(d, out=o), o) + + def test_out_nan(self): + with warnings.catch_warnings(record=True): + warnings.filterwarnings('always', '', RuntimeWarning) + o = np.zeros((4,)) + d = np.ones((3, 4)) + d[2, 1] = np.nan + assert_equal(np.median(d, 0, out=o), o) + o = np.zeros((3,)) + assert_equal(np.median(d, 1, out=o), o) + o = np.zeros(()) + assert_equal(np.median(d, out=o), o) + + def test_nan_behavior(self): + a = np.arange(24, dtype=float) + a[2] = np.nan + assert_equal(np.median(a), np.nan) + assert_equal(np.median(a, axis=0), np.nan) + + a = np.arange(24, dtype=float).reshape(2, 3, 4) + a[1, 2, 3] = np.nan + a[1, 1, 2] = np.nan + + # no axis + assert_equal(np.median(a), np.nan) + assert_equal(np.median(a).ndim, 0) + + # axis0 + b = np.median(np.arange(24, dtype=float).reshape(2, 3, 4), 0) + b[2, 3] = np.nan + b[1, 2] = np.nan + assert_equal(np.median(a, 0), b) + + # axis1 + b = np.median(np.arange(24, dtype=float).reshape(2, 3, 4), 1) + b[1, 3] = np.nan + b[1, 2] = np.nan + assert_equal(np.median(a, 1), b) + + # axis02 + b = np.median(np.arange(24, dtype=float).reshape(2, 3, 4), (0, 2)) + b[1] = np.nan + b[2] = np.nan + assert_equal(np.median(a, (0, 2)), b) + + def test_empty(self): + # mean(empty array) emits two warnings: empty slice and divide by 0 + a = np.array([], dtype=float) + with warnings.catch_warnings(record=True) as w: + warnings.filterwarnings('always', '', RuntimeWarning) + assert_equal(np.median(a), np.nan) + assert_(w[0].category is RuntimeWarning) + assert_equal(len(w), 2) + + # multiple dimensions + a = np.array([], dtype=float, ndmin=3) + # no axis + with warnings.catch_warnings(record=True) as w: + warnings.filterwarnings('always', '', RuntimeWarning) + assert_equal(np.median(a), np.nan) + assert_(w[0].category is RuntimeWarning) + + # axis 0 and 1 + b = np.array([], dtype=float, ndmin=2) + assert_equal(np.median(a, axis=0), b) + assert_equal(np.median(a, axis=1), b) + + # axis 2 + b = np.array(np.nan, dtype=float, ndmin=2) + with warnings.catch_warnings(record=True) as w: + warnings.filterwarnings('always', '', RuntimeWarning) + assert_equal(np.median(a, axis=2), b) + assert_(w[0].category is RuntimeWarning) + + def test_object(self): + o = np.arange(7.) + assert_(type(np.median(o.astype(object))), float) + o[2] = np.nan + assert_(type(np.median(o.astype(object))), float) + + def test_extended_axis(self): + o = np.random.normal(size=(71, 23)) + x = np.dstack([o] * 10) + assert_equal(np.median(x, axis=(0, 1)), np.median(o)) + x = np.moveaxis(x, -1, 0) + assert_equal(np.median(x, axis=(-2, -1)), np.median(o)) + x = x.swapaxes(0, 1).copy() + assert_equal(np.median(x, axis=(0, -1)), np.median(o)) + + assert_equal(np.median(x, axis=(0, 1, 2)), np.median(x, axis=None)) + assert_equal(np.median(x, axis=(0, )), np.median(x, axis=0)) + assert_equal(np.median(x, axis=(-1, )), np.median(x, axis=-1)) + + d = np.arange(3 * 5 * 7 * 11).reshape((3, 5, 7, 11)) + np.random.shuffle(d.ravel()) + assert_equal(np.median(d, axis=(0, 1, 2))[0], + np.median(d[:,:,:, 0].flatten())) + assert_equal(np.median(d, axis=(0, 1, 3))[1], + np.median(d[:,:, 1,:].flatten())) + assert_equal(np.median(d, axis=(3, 1, -4))[2], + np.median(d[:,:, 2,:].flatten())) + assert_equal(np.median(d, axis=(3, 1, 2))[2], + np.median(d[2,:,:,:].flatten())) + assert_equal(np.median(d, axis=(3, 2))[2, 1], + np.median(d[2, 1,:,:].flatten())) + assert_equal(np.median(d, axis=(1, -2))[2, 1], + np.median(d[2,:,:, 1].flatten())) + assert_equal(np.median(d, axis=(1, 3))[2, 2], + np.median(d[2,:, 2,:].flatten())) + + def test_extended_axis_invalid(self): + d = np.ones((3, 5, 7, 11)) + assert_raises(np.AxisError, np.median, d, axis=-5) + assert_raises(np.AxisError, np.median, d, axis=(0, -5)) + assert_raises(np.AxisError, np.median, d, axis=4) + assert_raises(np.AxisError, np.median, d, axis=(0, 4)) + assert_raises(ValueError, np.median, d, axis=(1, 1)) + + def test_keepdims(self): + d = np.ones((3, 5, 7, 11)) + assert_equal(np.median(d, axis=None, keepdims=True).shape, + (1, 1, 1, 1)) + assert_equal(np.median(d, axis=(0, 1), keepdims=True).shape, + (1, 1, 7, 11)) + assert_equal(np.median(d, axis=(0, 3), keepdims=True).shape, + (1, 5, 7, 1)) + assert_equal(np.median(d, axis=(1,), keepdims=True).shape, + (3, 1, 7, 11)) + assert_equal(np.median(d, axis=(0, 1, 2, 3), keepdims=True).shape, + (1, 1, 1, 1)) + assert_equal(np.median(d, axis=(0, 1, 3), keepdims=True).shape, + (1, 1, 7, 1)) + + +class TestAdd_newdoc_ufunc: + + def test_ufunc_arg(self): + assert_raises(TypeError, add_newdoc_ufunc, 2, "blah") + assert_raises(ValueError, add_newdoc_ufunc, np.add, "blah") + + def test_string_arg(self): + assert_raises(TypeError, add_newdoc_ufunc, np.add, 3) + + +class TestAdd_newdoc: + + @pytest.mark.skipif(sys.flags.optimize == 2, reason="Python running -OO") + @pytest.mark.xfail(IS_PYPY, reason="PyPy does not modify tp_doc") + def test_add_doc(self): + # test that np.add_newdoc did attach a docstring successfully: + tgt = "Current flat index into the array." + assert_equal(np.core.flatiter.index.__doc__[:len(tgt)], tgt) + assert_(len(np.core.ufunc.identity.__doc__) > 300) + assert_(len(np.lib.index_tricks.mgrid.__doc__) > 300) + + @pytest.mark.skipif(sys.flags.optimize == 2, reason="Python running -OO") + def test_errors_are_ignored(self): + prev_doc = np.core.flatiter.index.__doc__ + # nothing changed, but error ignored, this should probably + # give a warning (or even error) in the future. + np.add_newdoc("numpy.core", "flatiter", ("index", "bad docstring")) + assert prev_doc == np.core.flatiter.index.__doc__ + + +class TestAddDocstring(): + # Test should possibly be moved, but it also fits to be close to + # the newdoc tests... + @pytest.mark.skipif(sys.flags.optimize == 2, reason="Python running -OO") + @pytest.mark.skipif(IS_PYPY, reason="PyPy does not modify tp_doc") + def test_add_same_docstring(self): + # test for attributes (which are C-level defined) + np.add_docstring(np.ndarray.flat, np.ndarray.flat.__doc__) + # And typical functions: + def func(): + """docstring""" + return + + np.add_docstring(func, func.__doc__) + + @pytest.mark.skipif(sys.flags.optimize == 2, reason="Python running -OO") + def test_different_docstring_fails(self): + # test for attributes (which are C-level defined) + with assert_raises(RuntimeError): + np.add_docstring(np.ndarray.flat, "different docstring") + # And typical functions: + def func(): + """docstring""" + return + + with assert_raises(RuntimeError): + np.add_docstring(func, "different docstring") + + +class TestSortComplex: + + @pytest.mark.parametrize("type_in, type_out", [ + ('l', 'D'), + ('h', 'F'), + ('H', 'F'), + ('b', 'F'), + ('B', 'F'), + ('g', 'G'), + ]) + def test_sort_real(self, type_in, type_out): + # sort_complex() type casting for real input types + a = np.array([5, 3, 6, 2, 1], dtype=type_in) + actual = np.sort_complex(a) + expected = np.sort(a).astype(type_out) + assert_equal(actual, expected) + assert_equal(actual.dtype, expected.dtype) + + def test_sort_complex(self): + # sort_complex() handling of complex input + a = np.array([2 + 3j, 1 - 2j, 1 - 3j, 2 + 1j], dtype='D') + expected = np.array([1 - 3j, 1 - 2j, 2 + 1j, 2 + 3j], dtype='D') + actual = np.sort_complex(a) + assert_equal(actual, expected) + assert_equal(actual.dtype, expected.dtype) diff --git a/venv/Lib/site-packages/numpy/lib/tests/test_histograms.py b/venv/Lib/site-packages/numpy/lib/tests/test_histograms.py new file mode 100644 index 0000000..fc16b73 --- /dev/null +++ b/venv/Lib/site-packages/numpy/lib/tests/test_histograms.py @@ -0,0 +1,838 @@ +import numpy as np + +from numpy.lib.histograms import histogram, histogramdd, histogram_bin_edges +from numpy.testing import ( + assert_, assert_equal, assert_array_equal, assert_almost_equal, + assert_array_almost_equal, assert_raises, assert_allclose, + assert_array_max_ulp, assert_raises_regex, suppress_warnings, + ) +import pytest + + +class TestHistogram: + + def setup(self): + pass + + def teardown(self): + pass + + def test_simple(self): + n = 100 + v = np.random.rand(n) + (a, b) = histogram(v) + # check if the sum of the bins equals the number of samples + assert_equal(np.sum(a, axis=0), n) + # check that the bin counts are evenly spaced when the data is from + # a linear function + (a, b) = histogram(np.linspace(0, 10, 100)) + assert_array_equal(a, 10) + + def test_one_bin(self): + # Ticket 632 + hist, edges = histogram([1, 2, 3, 4], [1, 2]) + assert_array_equal(hist, [2, ]) + assert_array_equal(edges, [1, 2]) + assert_raises(ValueError, histogram, [1, 2], bins=0) + h, e = histogram([1, 2], bins=1) + assert_equal(h, np.array([2])) + assert_allclose(e, np.array([1., 2.])) + + def test_normed(self): + sup = suppress_warnings() + with sup: + rec = sup.record(np.VisibleDeprecationWarning, '.*normed.*') + # Check that the integral of the density equals 1. + n = 100 + v = np.random.rand(n) + a, b = histogram(v, normed=True) + area = np.sum(a * np.diff(b)) + assert_almost_equal(area, 1) + assert_equal(len(rec), 1) + + sup = suppress_warnings() + with sup: + rec = sup.record(np.VisibleDeprecationWarning, '.*normed.*') + # Check with non-constant bin widths (buggy but backwards + # compatible) + v = np.arange(10) + bins = [0, 1, 5, 9, 10] + a, b = histogram(v, bins, normed=True) + area = np.sum(a * np.diff(b)) + assert_almost_equal(area, 1) + assert_equal(len(rec), 1) + + def test_density(self): + # Check that the integral of the density equals 1. + n = 100 + v = np.random.rand(n) + a, b = histogram(v, density=True) + area = np.sum(a * np.diff(b)) + assert_almost_equal(area, 1) + + # Check with non-constant bin widths + v = np.arange(10) + bins = [0, 1, 3, 6, 10] + a, b = histogram(v, bins, density=True) + assert_array_equal(a, .1) + assert_equal(np.sum(a * np.diff(b)), 1) + + # Test that passing False works too + a, b = histogram(v, bins, density=False) + assert_array_equal(a, [1, 2, 3, 4]) + + # Variable bin widths are especially useful to deal with + # infinities. + v = np.arange(10) + bins = [0, 1, 3, 6, np.inf] + a, b = histogram(v, bins, density=True) + assert_array_equal(a, [.1, .1, .1, 0.]) + + # Taken from a bug report from N. Becker on the numpy-discussion + # mailing list Aug. 6, 2010. + counts, dmy = np.histogram( + [1, 2, 3, 4], [0.5, 1.5, np.inf], density=True) + assert_equal(counts, [.25, 0]) + + def test_outliers(self): + # Check that outliers are not tallied + a = np.arange(10) + .5 + + # Lower outliers + h, b = histogram(a, range=[0, 9]) + assert_equal(h.sum(), 9) + + # Upper outliers + h, b = histogram(a, range=[1, 10]) + assert_equal(h.sum(), 9) + + # Normalization + h, b = histogram(a, range=[1, 9], density=True) + assert_almost_equal((h * np.diff(b)).sum(), 1, decimal=15) + + # Weights + w = np.arange(10) + .5 + h, b = histogram(a, range=[1, 9], weights=w, density=True) + assert_equal((h * np.diff(b)).sum(), 1) + + h, b = histogram(a, bins=8, range=[1, 9], weights=w) + assert_equal(h, w[1:-1]) + + def test_arr_weights_mismatch(self): + a = np.arange(10) + .5 + w = np.arange(11) + .5 + with assert_raises_regex(ValueError, "same shape as"): + h, b = histogram(a, range=[1, 9], weights=w, density=True) + + + def test_type(self): + # Check the type of the returned histogram + a = np.arange(10) + .5 + h, b = histogram(a) + assert_(np.issubdtype(h.dtype, np.integer)) + + h, b = histogram(a, density=True) + assert_(np.issubdtype(h.dtype, np.floating)) + + h, b = histogram(a, weights=np.ones(10, int)) + assert_(np.issubdtype(h.dtype, np.integer)) + + h, b = histogram(a, weights=np.ones(10, float)) + assert_(np.issubdtype(h.dtype, np.floating)) + + def test_f32_rounding(self): + # gh-4799, check that the rounding of the edges works with float32 + x = np.array([276.318359, -69.593948, 21.329449], dtype=np.float32) + y = np.array([5005.689453, 4481.327637, 6010.369629], dtype=np.float32) + counts_hist, xedges, yedges = np.histogram2d(x, y, bins=100) + assert_equal(counts_hist.sum(), 3.) + + def test_bool_conversion(self): + # gh-12107 + # Reference integer histogram + a = np.array([1, 1, 0], dtype=np.uint8) + int_hist, int_edges = np.histogram(a) + + # Should raise an warning on booleans + # Ensure that the histograms are equivalent, need to suppress + # the warnings to get the actual outputs + with suppress_warnings() as sup: + rec = sup.record(RuntimeWarning, 'Converting input from .*') + hist, edges = np.histogram([True, True, False]) + # A warning should be issued + assert_equal(len(rec), 1) + assert_array_equal(hist, int_hist) + assert_array_equal(edges, int_edges) + + def test_weights(self): + v = np.random.rand(100) + w = np.ones(100) * 5 + a, b = histogram(v) + na, nb = histogram(v, density=True) + wa, wb = histogram(v, weights=w) + nwa, nwb = histogram(v, weights=w, density=True) + assert_array_almost_equal(a * 5, wa) + assert_array_almost_equal(na, nwa) + + # Check weights are properly applied. + v = np.linspace(0, 10, 10) + w = np.concatenate((np.zeros(5), np.ones(5))) + wa, wb = histogram(v, bins=np.arange(11), weights=w) + assert_array_almost_equal(wa, w) + + # Check with integer weights + wa, wb = histogram([1, 2, 2, 4], bins=4, weights=[4, 3, 2, 1]) + assert_array_equal(wa, [4, 5, 0, 1]) + wa, wb = histogram( + [1, 2, 2, 4], bins=4, weights=[4, 3, 2, 1], density=True) + assert_array_almost_equal(wa, np.array([4, 5, 0, 1]) / 10. / 3. * 4) + + # Check weights with non-uniform bin widths + a, b = histogram( + np.arange(9), [0, 1, 3, 6, 10], + weights=[2, 1, 1, 1, 1, 1, 1, 1, 1], density=True) + assert_almost_equal(a, [.2, .1, .1, .075]) + + def test_exotic_weights(self): + + # Test the use of weights that are not integer or floats, but e.g. + # complex numbers or object types. + + # Complex weights + values = np.array([1.3, 2.5, 2.3]) + weights = np.array([1, -1, 2]) + 1j * np.array([2, 1, 2]) + + # Check with custom bins + wa, wb = histogram(values, bins=[0, 2, 3], weights=weights) + assert_array_almost_equal(wa, np.array([1, 1]) + 1j * np.array([2, 3])) + + # Check with even bins + wa, wb = histogram(values, bins=2, range=[1, 3], weights=weights) + assert_array_almost_equal(wa, np.array([1, 1]) + 1j * np.array([2, 3])) + + # Decimal weights + from decimal import Decimal + values = np.array([1.3, 2.5, 2.3]) + weights = np.array([Decimal(1), Decimal(2), Decimal(3)]) + + # Check with custom bins + wa, wb = histogram(values, bins=[0, 2, 3], weights=weights) + assert_array_almost_equal(wa, [Decimal(1), Decimal(5)]) + + # Check with even bins + wa, wb = histogram(values, bins=2, range=[1, 3], weights=weights) + assert_array_almost_equal(wa, [Decimal(1), Decimal(5)]) + + def test_no_side_effects(self): + # This is a regression test that ensures that values passed to + # ``histogram`` are unchanged. + values = np.array([1.3, 2.5, 2.3]) + np.histogram(values, range=[-10, 10], bins=100) + assert_array_almost_equal(values, [1.3, 2.5, 2.3]) + + def test_empty(self): + a, b = histogram([], bins=([0, 1])) + assert_array_equal(a, np.array([0])) + assert_array_equal(b, np.array([0, 1])) + + def test_error_binnum_type (self): + # Tests if right Error is raised if bins argument is float + vals = np.linspace(0.0, 1.0, num=100) + histogram(vals, 5) + assert_raises(TypeError, histogram, vals, 2.4) + + def test_finite_range(self): + # Normal ranges should be fine + vals = np.linspace(0.0, 1.0, num=100) + histogram(vals, range=[0.25,0.75]) + assert_raises(ValueError, histogram, vals, range=[np.nan,0.75]) + assert_raises(ValueError, histogram, vals, range=[0.25,np.inf]) + + def test_invalid_range(self): + # start of range must be < end of range + vals = np.linspace(0.0, 1.0, num=100) + with assert_raises_regex(ValueError, "max must be larger than"): + np.histogram(vals, range=[0.1, 0.01]) + + def test_bin_edge_cases(self): + # Ensure that floating-point computations correctly place edge cases. + arr = np.array([337, 404, 739, 806, 1007, 1811, 2012]) + hist, edges = np.histogram(arr, bins=8296, range=(2, 2280)) + mask = hist > 0 + left_edges = edges[:-1][mask] + right_edges = edges[1:][mask] + for x, left, right in zip(arr, left_edges, right_edges): + assert_(x >= left) + assert_(x < right) + + def test_last_bin_inclusive_range(self): + arr = np.array([0., 0., 0., 1., 2., 3., 3., 4., 5.]) + hist, edges = np.histogram(arr, bins=30, range=(-0.5, 5)) + assert_equal(hist[-1], 1) + + def test_bin_array_dims(self): + # gracefully handle bins object > 1 dimension + vals = np.linspace(0.0, 1.0, num=100) + bins = np.array([[0, 0.5], [0.6, 1.0]]) + with assert_raises_regex(ValueError, "must be 1d"): + np.histogram(vals, bins=bins) + + def test_unsigned_monotonicity_check(self): + # Ensures ValueError is raised if bins not increasing monotonically + # when bins contain unsigned values (see #9222) + arr = np.array([2]) + bins = np.array([1, 3, 1], dtype='uint64') + with assert_raises(ValueError): + hist, edges = np.histogram(arr, bins=bins) + + def test_object_array_of_0d(self): + # gh-7864 + assert_raises(ValueError, + histogram, [np.array(0.4) for i in range(10)] + [-np.inf]) + assert_raises(ValueError, + histogram, [np.array(0.4) for i in range(10)] + [np.inf]) + + # these should not crash + np.histogram([np.array(0.5) for i in range(10)] + [.500000000000001]) + np.histogram([np.array(0.5) for i in range(10)] + [.5]) + + def test_some_nan_values(self): + # gh-7503 + one_nan = np.array([0, 1, np.nan]) + all_nan = np.array([np.nan, np.nan]) + + # the internal comparisons with NaN give warnings + sup = suppress_warnings() + sup.filter(RuntimeWarning) + with sup: + # can't infer range with nan + assert_raises(ValueError, histogram, one_nan, bins='auto') + assert_raises(ValueError, histogram, all_nan, bins='auto') + + # explicit range solves the problem + h, b = histogram(one_nan, bins='auto', range=(0, 1)) + assert_equal(h.sum(), 2) # nan is not counted + h, b = histogram(all_nan, bins='auto', range=(0, 1)) + assert_equal(h.sum(), 0) # nan is not counted + + # as does an explicit set of bins + h, b = histogram(one_nan, bins=[0, 1]) + assert_equal(h.sum(), 2) # nan is not counted + h, b = histogram(all_nan, bins=[0, 1]) + assert_equal(h.sum(), 0) # nan is not counted + + def test_datetime(self): + begin = np.datetime64('2000-01-01', 'D') + offsets = np.array([0, 0, 1, 1, 2, 3, 5, 10, 20]) + bins = np.array([0, 2, 7, 20]) + dates = begin + offsets + date_bins = begin + bins + + td = np.dtype('timedelta64[D]') + + # Results should be the same for integer offsets or datetime values. + # For now, only explicit bins are supported, since linspace does not + # work on datetimes or timedeltas + d_count, d_edge = histogram(dates, bins=date_bins) + t_count, t_edge = histogram(offsets.astype(td), bins=bins.astype(td)) + i_count, i_edge = histogram(offsets, bins=bins) + + assert_equal(d_count, i_count) + assert_equal(t_count, i_count) + + assert_equal((d_edge - begin).astype(int), i_edge) + assert_equal(t_edge.astype(int), i_edge) + + assert_equal(d_edge.dtype, dates.dtype) + assert_equal(t_edge.dtype, td) + + def do_signed_overflow_bounds(self, dtype): + exponent = 8 * np.dtype(dtype).itemsize - 1 + arr = np.array([-2**exponent + 4, 2**exponent - 4], dtype=dtype) + hist, e = histogram(arr, bins=2) + assert_equal(e, [-2**exponent + 4, 0, 2**exponent - 4]) + assert_equal(hist, [1, 1]) + + def test_signed_overflow_bounds(self): + self.do_signed_overflow_bounds(np.byte) + self.do_signed_overflow_bounds(np.short) + self.do_signed_overflow_bounds(np.intc) + self.do_signed_overflow_bounds(np.int_) + self.do_signed_overflow_bounds(np.longlong) + + def do_precision_lower_bound(self, float_small, float_large): + eps = np.finfo(float_large).eps + + arr = np.array([1.0], float_small) + range = np.array([1.0 + eps, 2.0], float_large) + + # test is looking for behavior when the bounds change between dtypes + if range.astype(float_small)[0] != 1: + return + + # previously crashed + count, x_loc = np.histogram(arr, bins=1, range=range) + assert_equal(count, [1]) + + # gh-10322 means that the type comes from arr - this may change + assert_equal(x_loc.dtype, float_small) + + def do_precision_upper_bound(self, float_small, float_large): + eps = np.finfo(float_large).eps + + arr = np.array([1.0], float_small) + range = np.array([0.0, 1.0 - eps], float_large) + + # test is looking for behavior when the bounds change between dtypes + if range.astype(float_small)[-1] != 1: + return + + # previously crashed + count, x_loc = np.histogram(arr, bins=1, range=range) + assert_equal(count, [1]) + + # gh-10322 means that the type comes from arr - this may change + assert_equal(x_loc.dtype, float_small) + + def do_precision(self, float_small, float_large): + self.do_precision_lower_bound(float_small, float_large) + self.do_precision_upper_bound(float_small, float_large) + + def test_precision(self): + # not looping results in a useful stack trace upon failure + self.do_precision(np.half, np.single) + self.do_precision(np.half, np.double) + self.do_precision(np.half, np.longdouble) + self.do_precision(np.single, np.double) + self.do_precision(np.single, np.longdouble) + self.do_precision(np.double, np.longdouble) + + def test_histogram_bin_edges(self): + hist, e = histogram([1, 2, 3, 4], [1, 2]) + edges = histogram_bin_edges([1, 2, 3, 4], [1, 2]) + assert_array_equal(edges, e) + + arr = np.array([0., 0., 0., 1., 2., 3., 3., 4., 5.]) + hist, e = histogram(arr, bins=30, range=(-0.5, 5)) + edges = histogram_bin_edges(arr, bins=30, range=(-0.5, 5)) + assert_array_equal(edges, e) + + hist, e = histogram(arr, bins='auto', range=(0, 1)) + edges = histogram_bin_edges(arr, bins='auto', range=(0, 1)) + assert_array_equal(edges, e) + + +class TestHistogramOptimBinNums: + """ + Provide test coverage when using provided estimators for optimal number of + bins + """ + + def test_empty(self): + estimator_list = ['fd', 'scott', 'rice', 'sturges', + 'doane', 'sqrt', 'auto', 'stone'] + # check it can deal with empty data + for estimator in estimator_list: + a, b = histogram([], bins=estimator) + assert_array_equal(a, np.array([0])) + assert_array_equal(b, np.array([0, 1])) + + def test_simple(self): + """ + Straightforward testing with a mixture of linspace data (for + consistency). All test values have been precomputed and the values + shouldn't change + """ + # Some basic sanity checking, with some fixed data. + # Checking for the correct number of bins + basic_test = {50: {'fd': 4, 'scott': 4, 'rice': 8, 'sturges': 7, + 'doane': 8, 'sqrt': 8, 'auto': 7, 'stone': 2}, + 500: {'fd': 8, 'scott': 8, 'rice': 16, 'sturges': 10, + 'doane': 12, 'sqrt': 23, 'auto': 10, 'stone': 9}, + 5000: {'fd': 17, 'scott': 17, 'rice': 35, 'sturges': 14, + 'doane': 17, 'sqrt': 71, 'auto': 17, 'stone': 20}} + + for testlen, expectedResults in basic_test.items(): + # Create some sort of non uniform data to test with + # (2 peak uniform mixture) + x1 = np.linspace(-10, -1, testlen // 5 * 2) + x2 = np.linspace(1, 10, testlen // 5 * 3) + x = np.concatenate((x1, x2)) + for estimator, numbins in expectedResults.items(): + a, b = np.histogram(x, estimator) + assert_equal(len(a), numbins, err_msg="For the {0} estimator " + "with datasize of {1}".format(estimator, testlen)) + + def test_small(self): + """ + Smaller datasets have the potential to cause issues with the data + adaptive methods, especially the FD method. All bin numbers have been + precalculated. + """ + small_dat = {1: {'fd': 1, 'scott': 1, 'rice': 1, 'sturges': 1, + 'doane': 1, 'sqrt': 1, 'stone': 1}, + 2: {'fd': 2, 'scott': 1, 'rice': 3, 'sturges': 2, + 'doane': 1, 'sqrt': 2, 'stone': 1}, + 3: {'fd': 2, 'scott': 2, 'rice': 3, 'sturges': 3, + 'doane': 3, 'sqrt': 2, 'stone': 1}} + + for testlen, expectedResults in small_dat.items(): + testdat = np.arange(testlen) + for estimator, expbins in expectedResults.items(): + a, b = np.histogram(testdat, estimator) + assert_equal(len(a), expbins, err_msg="For the {0} estimator " + "with datasize of {1}".format(estimator, testlen)) + + def test_incorrect_methods(self): + """ + Check a Value Error is thrown when an unknown string is passed in + """ + check_list = ['mad', 'freeman', 'histograms', 'IQR'] + for estimator in check_list: + assert_raises(ValueError, histogram, [1, 2, 3], estimator) + + def test_novariance(self): + """ + Check that methods handle no variance in data + Primarily for Scott and FD as the SD and IQR are both 0 in this case + """ + novar_dataset = np.ones(100) + novar_resultdict = {'fd': 1, 'scott': 1, 'rice': 1, 'sturges': 1, + 'doane': 1, 'sqrt': 1, 'auto': 1, 'stone': 1} + + for estimator, numbins in novar_resultdict.items(): + a, b = np.histogram(novar_dataset, estimator) + assert_equal(len(a), numbins, err_msg="{0} estimator, " + "No Variance test".format(estimator)) + + def test_limited_variance(self): + """ + Check when IQR is 0, but variance exists, we return the sturges value + and not the fd value. + """ + lim_var_data = np.ones(1000) + lim_var_data[:3] = 0 + lim_var_data[-4:] = 100 + + edges_auto = histogram_bin_edges(lim_var_data, 'auto') + assert_equal(edges_auto, np.linspace(0, 100, 12)) + + edges_fd = histogram_bin_edges(lim_var_data, 'fd') + assert_equal(edges_fd, np.array([0, 100])) + + edges_sturges = histogram_bin_edges(lim_var_data, 'sturges') + assert_equal(edges_sturges, np.linspace(0, 100, 12)) + + def test_outlier(self): + """ + Check the FD, Scott and Doane with outliers. + + The FD estimates a smaller binwidth since it's less affected by + outliers. Since the range is so (artificially) large, this means more + bins, most of which will be empty, but the data of interest usually is + unaffected. The Scott estimator is more affected and returns fewer bins, + despite most of the variance being in one area of the data. The Doane + estimator lies somewhere between the other two. + """ + xcenter = np.linspace(-10, 10, 50) + outlier_dataset = np.hstack((np.linspace(-110, -100, 5), xcenter)) + + outlier_resultdict = {'fd': 21, 'scott': 5, 'doane': 11, 'stone': 6} + + for estimator, numbins in outlier_resultdict.items(): + a, b = np.histogram(outlier_dataset, estimator) + assert_equal(len(a), numbins) + + def test_scott_vs_stone(self): + """Verify that Scott's rule and Stone's rule converges for normally distributed data""" + + def nbins_ratio(seed, size): + rng = np.random.RandomState(seed) + x = rng.normal(loc=0, scale=2, size=size) + a, b = len(np.histogram(x, 'stone')[0]), len(np.histogram(x, 'scott')[0]) + return a / (a + b) + + ll = [[nbins_ratio(seed, size) for size in np.geomspace(start=10, stop=100, num=4).round().astype(int)] + for seed in range(10)] + + # the average difference between the two methods decreases as the dataset size increases. + avg = abs(np.mean(ll, axis=0) - 0.5) + assert_almost_equal(avg, [0.15, 0.09, 0.08, 0.03], decimal=2) + + def test_simple_range(self): + """ + Straightforward testing with a mixture of linspace data (for + consistency). Adding in a 3rd mixture that will then be + completely ignored. All test values have been precomputed and + the shouldn't change. + """ + # some basic sanity checking, with some fixed data. + # Checking for the correct number of bins + basic_test = { + 50: {'fd': 8, 'scott': 8, 'rice': 15, + 'sturges': 14, 'auto': 14, 'stone': 8}, + 500: {'fd': 15, 'scott': 16, 'rice': 32, + 'sturges': 20, 'auto': 20, 'stone': 80}, + 5000: {'fd': 33, 'scott': 33, 'rice': 69, + 'sturges': 27, 'auto': 33, 'stone': 80} + } + + for testlen, expectedResults in basic_test.items(): + # create some sort of non uniform data to test with + # (3 peak uniform mixture) + x1 = np.linspace(-10, -1, testlen // 5 * 2) + x2 = np.linspace(1, 10, testlen // 5 * 3) + x3 = np.linspace(-100, -50, testlen) + x = np.hstack((x1, x2, x3)) + for estimator, numbins in expectedResults.items(): + a, b = np.histogram(x, estimator, range = (-20, 20)) + msg = "For the {0} estimator".format(estimator) + msg += " with datasize of {0}".format(testlen) + assert_equal(len(a), numbins, err_msg=msg) + + @pytest.mark.parametrize("bins", ['auto', 'fd', 'doane', 'scott', + 'stone', 'rice', 'sturges']) + def test_signed_integer_data(self, bins): + # Regression test for gh-14379. + a = np.array([-2, 0, 127], dtype=np.int8) + hist, edges = np.histogram(a, bins=bins) + hist32, edges32 = np.histogram(a.astype(np.int32), bins=bins) + assert_array_equal(hist, hist32) + assert_array_equal(edges, edges32) + + def test_simple_weighted(self): + """ + Check that weighted data raises a TypeError + """ + estimator_list = ['fd', 'scott', 'rice', 'sturges', 'auto'] + for estimator in estimator_list: + assert_raises(TypeError, histogram, [1, 2, 3], + estimator, weights=[1, 2, 3]) + + +class TestHistogramdd: + + def test_simple(self): + x = np.array([[-.5, .5, 1.5], [-.5, 1.5, 2.5], [-.5, 2.5, .5], + [.5, .5, 1.5], [.5, 1.5, 2.5], [.5, 2.5, 2.5]]) + H, edges = histogramdd(x, (2, 3, 3), + range=[[-1, 1], [0, 3], [0, 3]]) + answer = np.array([[[0, 1, 0], [0, 0, 1], [1, 0, 0]], + [[0, 1, 0], [0, 0, 1], [0, 0, 1]]]) + assert_array_equal(H, answer) + + # Check normalization + ed = [[-2, 0, 2], [0, 1, 2, 3], [0, 1, 2, 3]] + H, edges = histogramdd(x, bins=ed, density=True) + assert_(np.all(H == answer / 12.)) + + # Check that H has the correct shape. + H, edges = histogramdd(x, (2, 3, 4), + range=[[-1, 1], [0, 3], [0, 4]], + density=True) + answer = np.array([[[0, 1, 0, 0], [0, 0, 1, 0], [1, 0, 0, 0]], + [[0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 1, 0]]]) + assert_array_almost_equal(H, answer / 6., 4) + # Check that a sequence of arrays is accepted and H has the correct + # shape. + z = [np.squeeze(y) for y in np.split(x, 3, axis=1)] + H, edges = histogramdd( + z, bins=(4, 3, 2), range=[[-2, 2], [0, 3], [0, 2]]) + answer = np.array([[[0, 0], [0, 0], [0, 0]], + [[0, 1], [0, 0], [1, 0]], + [[0, 1], [0, 0], [0, 0]], + [[0, 0], [0, 0], [0, 0]]]) + assert_array_equal(H, answer) + + Z = np.zeros((5, 5, 5)) + Z[list(range(5)), list(range(5)), list(range(5))] = 1. + H, edges = histogramdd([np.arange(5), np.arange(5), np.arange(5)], 5) + assert_array_equal(H, Z) + + def test_shape_3d(self): + # All possible permutations for bins of different lengths in 3D. + bins = ((5, 4, 6), (6, 4, 5), (5, 6, 4), (4, 6, 5), (6, 5, 4), + (4, 5, 6)) + r = np.random.rand(10, 3) + for b in bins: + H, edges = histogramdd(r, b) + assert_(H.shape == b) + + def test_shape_4d(self): + # All possible permutations for bins of different lengths in 4D. + bins = ((7, 4, 5, 6), (4, 5, 7, 6), (5, 6, 4, 7), (7, 6, 5, 4), + (5, 7, 6, 4), (4, 6, 7, 5), (6, 5, 7, 4), (7, 5, 4, 6), + (7, 4, 6, 5), (6, 4, 7, 5), (6, 7, 5, 4), (4, 6, 5, 7), + (4, 7, 5, 6), (5, 4, 6, 7), (5, 7, 4, 6), (6, 7, 4, 5), + (6, 5, 4, 7), (4, 7, 6, 5), (4, 5, 6, 7), (7, 6, 4, 5), + (5, 4, 7, 6), (5, 6, 7, 4), (6, 4, 5, 7), (7, 5, 6, 4)) + + r = np.random.rand(10, 4) + for b in bins: + H, edges = histogramdd(r, b) + assert_(H.shape == b) + + def test_weights(self): + v = np.random.rand(100, 2) + hist, edges = histogramdd(v) + n_hist, edges = histogramdd(v, density=True) + w_hist, edges = histogramdd(v, weights=np.ones(100)) + assert_array_equal(w_hist, hist) + w_hist, edges = histogramdd(v, weights=np.ones(100) * 2, density=True) + assert_array_equal(w_hist, n_hist) + w_hist, edges = histogramdd(v, weights=np.ones(100, int) * 2) + assert_array_equal(w_hist, 2 * hist) + + def test_identical_samples(self): + x = np.zeros((10, 2), int) + hist, edges = histogramdd(x, bins=2) + assert_array_equal(edges[0], np.array([-0.5, 0., 0.5])) + + def test_empty(self): + a, b = histogramdd([[], []], bins=([0, 1], [0, 1])) + assert_array_max_ulp(a, np.array([[0.]])) + a, b = np.histogramdd([[], [], []], bins=2) + assert_array_max_ulp(a, np.zeros((2, 2, 2))) + + def test_bins_errors(self): + # There are two ways to specify bins. Check for the right errors + # when mixing those. + x = np.arange(8).reshape(2, 4) + assert_raises(ValueError, np.histogramdd, x, bins=[-1, 2, 4, 5]) + assert_raises(ValueError, np.histogramdd, x, bins=[1, 0.99, 1, 1]) + assert_raises( + ValueError, np.histogramdd, x, bins=[1, 1, 1, [1, 2, 3, -3]]) + assert_(np.histogramdd(x, bins=[1, 1, 1, [1, 2, 3, 4]])) + + def test_inf_edges(self): + # Test using +/-inf bin edges works. See #1788. + with np.errstate(invalid='ignore'): + x = np.arange(6).reshape(3, 2) + expected = np.array([[1, 0], [0, 1], [0, 1]]) + h, e = np.histogramdd(x, bins=[3, [-np.inf, 2, 10]]) + assert_allclose(h, expected) + h, e = np.histogramdd(x, bins=[3, np.array([-1, 2, np.inf])]) + assert_allclose(h, expected) + h, e = np.histogramdd(x, bins=[3, [-np.inf, 3, np.inf]]) + assert_allclose(h, expected) + + def test_rightmost_binedge(self): + # Test event very close to rightmost binedge. See Github issue #4266 + x = [0.9999999995] + bins = [[0., 0.5, 1.0]] + hist, _ = histogramdd(x, bins=bins) + assert_(hist[0] == 0.0) + assert_(hist[1] == 1.) + x = [1.0] + bins = [[0., 0.5, 1.0]] + hist, _ = histogramdd(x, bins=bins) + assert_(hist[0] == 0.0) + assert_(hist[1] == 1.) + x = [1.0000000001] + bins = [[0., 0.5, 1.0]] + hist, _ = histogramdd(x, bins=bins) + assert_(hist[0] == 0.0) + assert_(hist[1] == 0.0) + x = [1.0001] + bins = [[0., 0.5, 1.0]] + hist, _ = histogramdd(x, bins=bins) + assert_(hist[0] == 0.0) + assert_(hist[1] == 0.0) + + def test_finite_range(self): + vals = np.random.random((100, 3)) + histogramdd(vals, range=[[0.0, 1.0], [0.25, 0.75], [0.25, 0.5]]) + assert_raises(ValueError, histogramdd, vals, + range=[[0.0, 1.0], [0.25, 0.75], [0.25, np.inf]]) + assert_raises(ValueError, histogramdd, vals, + range=[[0.0, 1.0], [np.nan, 0.75], [0.25, 0.5]]) + + def test_equal_edges(self): + """ Test that adjacent entries in an edge array can be equal """ + x = np.array([0, 1, 2]) + y = np.array([0, 1, 2]) + x_edges = np.array([0, 2, 2]) + y_edges = 1 + hist, edges = histogramdd((x, y), bins=(x_edges, y_edges)) + + hist_expected = np.array([ + [2.], + [1.], # x == 2 falls in the final bin + ]) + assert_equal(hist, hist_expected) + + def test_edge_dtype(self): + """ Test that if an edge array is input, its type is preserved """ + x = np.array([0, 10, 20]) + y = x / 10 + x_edges = np.array([0, 5, 15, 20]) + y_edges = x_edges / 10 + hist, edges = histogramdd((x, y), bins=(x_edges, y_edges)) + + assert_equal(edges[0].dtype, x_edges.dtype) + assert_equal(edges[1].dtype, y_edges.dtype) + + def test_large_integers(self): + big = 2**60 # Too large to represent with a full precision float + + x = np.array([0], np.int64) + x_edges = np.array([-1, +1], np.int64) + y = big + x + y_edges = big + x_edges + + hist, edges = histogramdd((x, y), bins=(x_edges, y_edges)) + + assert_equal(hist[0, 0], 1) + + def test_density_non_uniform_2d(self): + # Defines the following grid: + # + # 0 2 8 + # 0+-+-----+ + # + | + + # + | + + # 6+-+-----+ + # 8+-+-----+ + x_edges = np.array([0, 2, 8]) + y_edges = np.array([0, 6, 8]) + relative_areas = np.array([ + [3, 9], + [1, 3]]) + + # ensure the number of points in each region is proportional to its area + x = np.array([1] + [1]*3 + [7]*3 + [7]*9) + y = np.array([7] + [1]*3 + [7]*3 + [1]*9) + + # sanity check that the above worked as intended + hist, edges = histogramdd((y, x), bins=(y_edges, x_edges)) + assert_equal(hist, relative_areas) + + # resulting histogram should be uniform, since counts and areas are proportional + hist, edges = histogramdd((y, x), bins=(y_edges, x_edges), density=True) + assert_equal(hist, 1 / (8*8)) + + def test_density_non_uniform_1d(self): + # compare to histogram to show the results are the same + v = np.arange(10) + bins = np.array([0, 1, 3, 6, 10]) + hist, edges = histogram(v, bins, density=True) + hist_dd, edges_dd = histogramdd((v,), (bins,), density=True) + assert_equal(hist, hist_dd) + assert_equal(edges, edges_dd[0]) + + def test_density_via_normed(self): + # normed should simply alias to density argument + v = np.arange(10) + bins = np.array([0, 1, 3, 6, 10]) + hist, edges = histogram(v, bins, density=True) + hist_dd, edges_dd = histogramdd((v,), (bins,), normed=True) + assert_equal(hist, hist_dd) + assert_equal(edges, edges_dd[0]) + + def test_density_normed_redundancy(self): + v = np.arange(10) + bins = np.array([0, 1, 3, 6, 10]) + with assert_raises_regex(TypeError, "Cannot specify both"): + hist_dd, edges_dd = histogramdd((v,), (bins,), + density=True, + normed=True) diff --git a/venv/Lib/site-packages/numpy/lib/tests/test_index_tricks.py b/venv/Lib/site-packages/numpy/lib/tests/test_index_tricks.py new file mode 100644 index 0000000..843e27c --- /dev/null +++ b/venv/Lib/site-packages/numpy/lib/tests/test_index_tricks.py @@ -0,0 +1,525 @@ +import pytest + +import numpy as np +from numpy.testing import ( + assert_, assert_equal, assert_array_equal, assert_almost_equal, + assert_array_almost_equal, assert_raises, assert_raises_regex, + assert_warns + ) +from numpy.lib.index_tricks import ( + mgrid, ogrid, ndenumerate, fill_diagonal, diag_indices, diag_indices_from, + index_exp, ndindex, r_, s_, ix_ + ) + + +class TestRavelUnravelIndex: + def test_basic(self): + assert_equal(np.unravel_index(2, (2, 2)), (1, 0)) + + # test backwards compatibility with older dims + # keyword argument; see Issue #10586 + with assert_warns(DeprecationWarning): + # we should achieve the correct result + # AND raise the appropriate warning + # when using older "dims" kw argument + assert_equal(np.unravel_index(indices=2, + dims=(2, 2)), + (1, 0)) + + # test that new shape argument works properly + assert_equal(np.unravel_index(indices=2, + shape=(2, 2)), + (1, 0)) + + # test that an invalid second keyword argument + # is properly handled + with assert_raises(TypeError): + np.unravel_index(indices=2, hape=(2, 2)) + + with assert_raises(TypeError): + np.unravel_index(2, hape=(2, 2)) + + with assert_raises(TypeError): + np.unravel_index(254, ims=(17, 94)) + + assert_equal(np.ravel_multi_index((1, 0), (2, 2)), 2) + assert_equal(np.unravel_index(254, (17, 94)), (2, 66)) + assert_equal(np.ravel_multi_index((2, 66), (17, 94)), 254) + assert_raises(ValueError, np.unravel_index, -1, (2, 2)) + assert_raises(TypeError, np.unravel_index, 0.5, (2, 2)) + assert_raises(ValueError, np.unravel_index, 4, (2, 2)) + assert_raises(ValueError, np.ravel_multi_index, (-3, 1), (2, 2)) + assert_raises(ValueError, np.ravel_multi_index, (2, 1), (2, 2)) + assert_raises(ValueError, np.ravel_multi_index, (0, -3), (2, 2)) + assert_raises(ValueError, np.ravel_multi_index, (0, 2), (2, 2)) + assert_raises(TypeError, np.ravel_multi_index, (0.1, 0.), (2, 2)) + + assert_equal(np.unravel_index((2*3 + 1)*6 + 4, (4, 3, 6)), [2, 1, 4]) + assert_equal( + np.ravel_multi_index([2, 1, 4], (4, 3, 6)), (2*3 + 1)*6 + 4) + + arr = np.array([[3, 6, 6], [4, 5, 1]]) + assert_equal(np.ravel_multi_index(arr, (7, 6)), [22, 41, 37]) + assert_equal( + np.ravel_multi_index(arr, (7, 6), order='F'), [31, 41, 13]) + assert_equal( + np.ravel_multi_index(arr, (4, 6), mode='clip'), [22, 23, 19]) + assert_equal(np.ravel_multi_index(arr, (4, 4), mode=('clip', 'wrap')), + [12, 13, 13]) + assert_equal(np.ravel_multi_index((3, 1, 4, 1), (6, 7, 8, 9)), 1621) + + assert_equal(np.unravel_index(np.array([22, 41, 37]), (7, 6)), + [[3, 6, 6], [4, 5, 1]]) + assert_equal( + np.unravel_index(np.array([31, 41, 13]), (7, 6), order='F'), + [[3, 6, 6], [4, 5, 1]]) + assert_equal(np.unravel_index(1621, (6, 7, 8, 9)), [3, 1, 4, 1]) + + def test_empty_indices(self): + msg1 = 'indices must be integral: the provided empty sequence was' + msg2 = 'only int indices permitted' + assert_raises_regex(TypeError, msg1, np.unravel_index, [], (10, 3, 5)) + assert_raises_regex(TypeError, msg1, np.unravel_index, (), (10, 3, 5)) + assert_raises_regex(TypeError, msg2, np.unravel_index, np.array([]), + (10, 3, 5)) + assert_equal(np.unravel_index(np.array([],dtype=int), (10, 3, 5)), + [[], [], []]) + assert_raises_regex(TypeError, msg1, np.ravel_multi_index, ([], []), + (10, 3)) + assert_raises_regex(TypeError, msg1, np.ravel_multi_index, ([], ['abc']), + (10, 3)) + assert_raises_regex(TypeError, msg2, np.ravel_multi_index, + (np.array([]), np.array([])), (5, 3)) + assert_equal(np.ravel_multi_index( + (np.array([], dtype=int), np.array([], dtype=int)), (5, 3)), []) + assert_equal(np.ravel_multi_index(np.array([[], []], dtype=int), + (5, 3)), []) + + def test_big_indices(self): + # ravel_multi_index for big indices (issue #7546) + if np.intp == np.int64: + arr = ([1, 29], [3, 5], [3, 117], [19, 2], + [2379, 1284], [2, 2], [0, 1]) + assert_equal( + np.ravel_multi_index(arr, (41, 7, 120, 36, 2706, 8, 6)), + [5627771580, 117259570957]) + + # test unravel_index for big indices (issue #9538) + assert_raises(ValueError, np.unravel_index, 1, (2**32-1, 2**31+1)) + + # test overflow checking for too big array (issue #7546) + dummy_arr = ([0],[0]) + half_max = np.iinfo(np.intp).max // 2 + assert_equal( + np.ravel_multi_index(dummy_arr, (half_max, 2)), [0]) + assert_raises(ValueError, + np.ravel_multi_index, dummy_arr, (half_max+1, 2)) + assert_equal( + np.ravel_multi_index(dummy_arr, (half_max, 2), order='F'), [0]) + assert_raises(ValueError, + np.ravel_multi_index, dummy_arr, (half_max+1, 2), order='F') + + def test_dtypes(self): + # Test with different data types + for dtype in [np.int16, np.uint16, np.int32, + np.uint32, np.int64, np.uint64]: + coords = np.array( + [[1, 0, 1, 2, 3, 4], [1, 6, 1, 3, 2, 0]], dtype=dtype) + shape = (5, 8) + uncoords = 8*coords[0]+coords[1] + assert_equal(np.ravel_multi_index(coords, shape), uncoords) + assert_equal(coords, np.unravel_index(uncoords, shape)) + uncoords = coords[0]+5*coords[1] + assert_equal( + np.ravel_multi_index(coords, shape, order='F'), uncoords) + assert_equal(coords, np.unravel_index(uncoords, shape, order='F')) + + coords = np.array( + [[1, 0, 1, 2, 3, 4], [1, 6, 1, 3, 2, 0], [1, 3, 1, 0, 9, 5]], + dtype=dtype) + shape = (5, 8, 10) + uncoords = 10*(8*coords[0]+coords[1])+coords[2] + assert_equal(np.ravel_multi_index(coords, shape), uncoords) + assert_equal(coords, np.unravel_index(uncoords, shape)) + uncoords = coords[0]+5*(coords[1]+8*coords[2]) + assert_equal( + np.ravel_multi_index(coords, shape, order='F'), uncoords) + assert_equal(coords, np.unravel_index(uncoords, shape, order='F')) + + def test_clipmodes(self): + # Test clipmodes + assert_equal( + np.ravel_multi_index([5, 1, -1, 2], (4, 3, 7, 12), mode='wrap'), + np.ravel_multi_index([1, 1, 6, 2], (4, 3, 7, 12))) + assert_equal(np.ravel_multi_index([5, 1, -1, 2], (4, 3, 7, 12), + mode=( + 'wrap', 'raise', 'clip', 'raise')), + np.ravel_multi_index([1, 1, 0, 2], (4, 3, 7, 12))) + assert_raises( + ValueError, np.ravel_multi_index, [5, 1, -1, 2], (4, 3, 7, 12)) + + def test_writeability(self): + # See gh-7269 + x, y = np.unravel_index([1, 2, 3], (4, 5)) + assert_(x.flags.writeable) + assert_(y.flags.writeable) + + def test_0d(self): + # gh-580 + x = np.unravel_index(0, ()) + assert_equal(x, ()) + + assert_raises_regex(ValueError, "0d array", np.unravel_index, [0], ()) + assert_raises_regex( + ValueError, "out of bounds", np.unravel_index, [1], ()) + + @pytest.mark.parametrize("mode", ["clip", "wrap", "raise"]) + def test_empty_array_ravel(self, mode): + res = np.ravel_multi_index( + np.zeros((3, 0), dtype=np.intp), (2, 1, 0), mode=mode) + assert(res.shape == (0,)) + + with assert_raises(ValueError): + np.ravel_multi_index( + np.zeros((3, 1), dtype=np.intp), (2, 1, 0), mode=mode) + + def test_empty_array_unravel(self): + res = np.unravel_index(np.zeros(0, dtype=np.intp), (2, 1, 0)) + # res is a tuple of three empty arrays + assert(len(res) == 3) + assert(all(a.shape == (0,) for a in res)) + + with assert_raises(ValueError): + np.unravel_index([1], (2, 1, 0)) + +class TestGrid: + def test_basic(self): + a = mgrid[-1:1:10j] + b = mgrid[-1:1:0.1] + assert_(a.shape == (10,)) + assert_(b.shape == (20,)) + assert_(a[0] == -1) + assert_almost_equal(a[-1], 1) + assert_(b[0] == -1) + assert_almost_equal(b[1]-b[0], 0.1, 11) + assert_almost_equal(b[-1], b[0]+19*0.1, 11) + assert_almost_equal(a[1]-a[0], 2.0/9.0, 11) + + def test_linspace_equivalence(self): + y, st = np.linspace(2, 10, retstep=True) + assert_almost_equal(st, 8/49.0) + assert_array_almost_equal(y, mgrid[2:10:50j], 13) + + def test_nd(self): + c = mgrid[-1:1:10j, -2:2:10j] + d = mgrid[-1:1:0.1, -2:2:0.2] + assert_(c.shape == (2, 10, 10)) + assert_(d.shape == (2, 20, 20)) + assert_array_equal(c[0][0, :], -np.ones(10, 'd')) + assert_array_equal(c[1][:, 0], -2*np.ones(10, 'd')) + assert_array_almost_equal(c[0][-1, :], np.ones(10, 'd'), 11) + assert_array_almost_equal(c[1][:, -1], 2*np.ones(10, 'd'), 11) + assert_array_almost_equal(d[0, 1, :] - d[0, 0, :], + 0.1*np.ones(20, 'd'), 11) + assert_array_almost_equal(d[1, :, 1] - d[1, :, 0], + 0.2*np.ones(20, 'd'), 11) + + def test_sparse(self): + grid_full = mgrid[-1:1:10j, -2:2:10j] + grid_sparse = ogrid[-1:1:10j, -2:2:10j] + + # sparse grids can be made dense by broadcasting + grid_broadcast = np.broadcast_arrays(*grid_sparse) + for f, b in zip(grid_full, grid_broadcast): + assert_equal(f, b) + + @pytest.mark.parametrize("start, stop, step, expected", [ + (None, 10, 10j, (200, 10)), + (-10, 20, None, (1800, 30)), + ]) + def test_mgrid_size_none_handling(self, start, stop, step, expected): + # regression test None value handling for + # start and step values used by mgrid; + # internally, this aims to cover previously + # unexplored code paths in nd_grid() + grid = mgrid[start:stop:step, start:stop:step] + # need a smaller grid to explore one of the + # untested code paths + grid_small = mgrid[start:stop:step] + assert_equal(grid.size, expected[0]) + assert_equal(grid_small.size, expected[1]) + + def test_accepts_npfloating(self): + # regression test for #16466 + grid64 = mgrid[0.1:0.33:0.1, ] + grid32 = mgrid[np.float32(0.1):np.float32(0.33):np.float32(0.1), ] + assert_(grid32.dtype == np.float64) + assert_array_almost_equal(grid64, grid32) + + # different code path for single slice + grid64 = mgrid[0.1:0.33:0.1] + grid32 = mgrid[np.float32(0.1):np.float32(0.33):np.float32(0.1)] + assert_(grid32.dtype == np.float64) + assert_array_almost_equal(grid64, grid32) + + def test_accepts_npcomplexfloating(self): + # Related to #16466 + assert_array_almost_equal( + mgrid[0.1:0.3:3j, ], mgrid[0.1:0.3:np.complex64(3j), ] + ) + + # different code path for single slice + assert_array_almost_equal( + mgrid[0.1:0.3:3j], mgrid[0.1:0.3:np.complex64(3j)] + ) + +class TestConcatenator: + def test_1d(self): + assert_array_equal(r_[1, 2, 3, 4, 5, 6], np.array([1, 2, 3, 4, 5, 6])) + b = np.ones(5) + c = r_[b, 0, 0, b] + assert_array_equal(c, [1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1]) + + def test_mixed_type(self): + g = r_[10.1, 1:10] + assert_(g.dtype == 'f8') + + def test_more_mixed_type(self): + g = r_[-10.1, np.array([1]), np.array([2, 3, 4]), 10.0] + assert_(g.dtype == 'f8') + + def test_complex_step(self): + # Regression test for #12262 + g = r_[0:36:100j] + assert_(g.shape == (100,)) + + # Related to #16466 + g = r_[0:36:np.complex64(100j)] + assert_(g.shape == (100,)) + + def test_2d(self): + b = np.random.rand(5, 5) + c = np.random.rand(5, 5) + d = r_['1', b, c] # append columns + assert_(d.shape == (5, 10)) + assert_array_equal(d[:, :5], b) + assert_array_equal(d[:, 5:], c) + d = r_[b, c] + assert_(d.shape == (10, 5)) + assert_array_equal(d[:5, :], b) + assert_array_equal(d[5:, :], c) + + def test_0d(self): + assert_equal(r_[0, np.array(1), 2], [0, 1, 2]) + assert_equal(r_[[0, 1, 2], np.array(3)], [0, 1, 2, 3]) + assert_equal(r_[np.array(0), [1, 2, 3]], [0, 1, 2, 3]) + + +class TestNdenumerate: + def test_basic(self): + a = np.array([[1, 2], [3, 4]]) + assert_equal(list(ndenumerate(a)), + [((0, 0), 1), ((0, 1), 2), ((1, 0), 3), ((1, 1), 4)]) + + +class TestIndexExpression: + def test_regression_1(self): + # ticket #1196 + a = np.arange(2) + assert_equal(a[:-1], a[s_[:-1]]) + assert_equal(a[:-1], a[index_exp[:-1]]) + + def test_simple_1(self): + a = np.random.rand(4, 5, 6) + + assert_equal(a[:, :3, [1, 2]], a[index_exp[:, :3, [1, 2]]]) + assert_equal(a[:, :3, [1, 2]], a[s_[:, :3, [1, 2]]]) + + +class TestIx_: + def test_regression_1(self): + # Test empty untyped inputs create outputs of indexing type, gh-5804 + a, = np.ix_(range(0)) + assert_equal(a.dtype, np.intp) + + a, = np.ix_([]) + assert_equal(a.dtype, np.intp) + + # but if the type is specified, don't change it + a, = np.ix_(np.array([], dtype=np.float32)) + assert_equal(a.dtype, np.float32) + + def test_shape_and_dtype(self): + sizes = (4, 5, 3, 2) + # Test both lists and arrays + for func in (range, np.arange): + arrays = np.ix_(*[func(sz) for sz in sizes]) + for k, (a, sz) in enumerate(zip(arrays, sizes)): + assert_equal(a.shape[k], sz) + assert_(all(sh == 1 for j, sh in enumerate(a.shape) if j != k)) + assert_(np.issubdtype(a.dtype, np.integer)) + + def test_bool(self): + bool_a = [True, False, True, True] + int_a, = np.nonzero(bool_a) + assert_equal(np.ix_(bool_a)[0], int_a) + + def test_1d_only(self): + idx2d = [[1, 2, 3], [4, 5, 6]] + assert_raises(ValueError, np.ix_, idx2d) + + def test_repeated_input(self): + length_of_vector = 5 + x = np.arange(length_of_vector) + out = ix_(x, x) + assert_equal(out[0].shape, (length_of_vector, 1)) + assert_equal(out[1].shape, (1, length_of_vector)) + # check that input shape is not modified + assert_equal(x.shape, (length_of_vector,)) + + +def test_c_(): + a = np.c_[np.array([[1, 2, 3]]), 0, 0, np.array([[4, 5, 6]])] + assert_equal(a, [[1, 2, 3, 0, 0, 4, 5, 6]]) + + +class TestFillDiagonal: + def test_basic(self): + a = np.zeros((3, 3), int) + fill_diagonal(a, 5) + assert_array_equal( + a, np.array([[5, 0, 0], + [0, 5, 0], + [0, 0, 5]]) + ) + + def test_tall_matrix(self): + a = np.zeros((10, 3), int) + fill_diagonal(a, 5) + assert_array_equal( + a, np.array([[5, 0, 0], + [0, 5, 0], + [0, 0, 5], + [0, 0, 0], + [0, 0, 0], + [0, 0, 0], + [0, 0, 0], + [0, 0, 0], + [0, 0, 0], + [0, 0, 0]]) + ) + + def test_tall_matrix_wrap(self): + a = np.zeros((10, 3), int) + fill_diagonal(a, 5, True) + assert_array_equal( + a, np.array([[5, 0, 0], + [0, 5, 0], + [0, 0, 5], + [0, 0, 0], + [5, 0, 0], + [0, 5, 0], + [0, 0, 5], + [0, 0, 0], + [5, 0, 0], + [0, 5, 0]]) + ) + + def test_wide_matrix(self): + a = np.zeros((3, 10), int) + fill_diagonal(a, 5) + assert_array_equal( + a, np.array([[5, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 5, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 5, 0, 0, 0, 0, 0, 0, 0]]) + ) + + def test_operate_4d_array(self): + a = np.zeros((3, 3, 3, 3), int) + fill_diagonal(a, 4) + i = np.array([0, 1, 2]) + assert_equal(np.where(a != 0), (i, i, i, i)) + + def test_low_dim_handling(self): + # raise error with low dimensionality + a = np.zeros(3, int) + with assert_raises_regex(ValueError, "at least 2-d"): + fill_diagonal(a, 5) + + def test_hetero_shape_handling(self): + # raise error with high dimensionality and + # shape mismatch + a = np.zeros((3,3,7,3), int) + with assert_raises_regex(ValueError, "equal length"): + fill_diagonal(a, 2) + + +def test_diag_indices(): + di = diag_indices(4) + a = np.array([[1, 2, 3, 4], + [5, 6, 7, 8], + [9, 10, 11, 12], + [13, 14, 15, 16]]) + a[di] = 100 + assert_array_equal( + a, np.array([[100, 2, 3, 4], + [5, 100, 7, 8], + [9, 10, 100, 12], + [13, 14, 15, 100]]) + ) + + # Now, we create indices to manipulate a 3-d array: + d3 = diag_indices(2, 3) + + # And use it to set the diagonal of a zeros array to 1: + a = np.zeros((2, 2, 2), int) + a[d3] = 1 + assert_array_equal( + a, np.array([[[1, 0], + [0, 0]], + [[0, 0], + [0, 1]]]) + ) + + +class TestDiagIndicesFrom: + + def test_diag_indices_from(self): + x = np.random.random((4, 4)) + r, c = diag_indices_from(x) + assert_array_equal(r, np.arange(4)) + assert_array_equal(c, np.arange(4)) + + def test_error_small_input(self): + x = np.ones(7) + with assert_raises_regex(ValueError, "at least 2-d"): + diag_indices_from(x) + + def test_error_shape_mismatch(self): + x = np.zeros((3, 3, 2, 3), int) + with assert_raises_regex(ValueError, "equal length"): + diag_indices_from(x) + + +def test_ndindex(): + x = list(ndindex(1, 2, 3)) + expected = [ix for ix, e in ndenumerate(np.zeros((1, 2, 3)))] + assert_array_equal(x, expected) + + x = list(ndindex((1, 2, 3))) + assert_array_equal(x, expected) + + # Test use of scalars and tuples + x = list(ndindex((3,))) + assert_array_equal(x, list(ndindex(3))) + + # Make sure size argument is optional + x = list(ndindex()) + assert_equal(x, [()]) + + x = list(ndindex(())) + assert_equal(x, [()]) + + # Make sure 0-sized ndindex works correctly + x = list(ndindex(*[0])) + assert_equal(x, []) diff --git a/venv/Lib/site-packages/numpy/lib/tests/test_io.py b/venv/Lib/site-packages/numpy/lib/tests/test_io.py new file mode 100644 index 0000000..534ab68 --- /dev/null +++ b/venv/Lib/site-packages/numpy/lib/tests/test_io.py @@ -0,0 +1,2660 @@ +import sys +import gc +import gzip +import os +import threading +import time +import warnings +import io +import re +import pytest +from pathlib import Path +from tempfile import NamedTemporaryFile +from io import BytesIO, StringIO +from datetime import datetime +import locale +from multiprocessing import Process, Value +from ctypes import c_bool + +import numpy as np +import numpy.ma as ma +from numpy.lib._iotools import ConverterError, ConversionWarning +from numpy.compat import asbytes +from numpy.ma.testutils import assert_equal +from numpy.testing import ( + assert_warns, assert_, assert_raises_regex, assert_raises, + assert_allclose, assert_array_equal, temppath, tempdir, IS_PYPY, + HAS_REFCOUNT, suppress_warnings, assert_no_gc_cycles, assert_no_warnings, + break_cycles + ) +from numpy.testing._private.utils import requires_memory + + +class TextIO(BytesIO): + """Helper IO class. + + Writes encode strings to bytes if needed, reads return bytes. + This makes it easier to emulate files opened in binary mode + without needing to explicitly convert strings to bytes in + setting up the test data. + + """ + def __init__(self, s=""): + BytesIO.__init__(self, asbytes(s)) + + def write(self, s): + BytesIO.write(self, asbytes(s)) + + def writelines(self, lines): + BytesIO.writelines(self, [asbytes(s) for s in lines]) + + +IS_64BIT = sys.maxsize > 2**32 +try: + import bz2 + HAS_BZ2 = True +except ImportError: + HAS_BZ2 = False +try: + import lzma + HAS_LZMA = True +except ImportError: + HAS_LZMA = False + + +def strptime(s, fmt=None): + """ + This function is available in the datetime module only from Python >= + 2.5. + + """ + if type(s) == bytes: + s = s.decode("latin1") + return datetime(*time.strptime(s, fmt)[:3]) + + +class RoundtripTest: + def roundtrip(self, save_func, *args, **kwargs): + """ + save_func : callable + Function used to save arrays to file. + file_on_disk : bool + If true, store the file on disk, instead of in a + string buffer. + save_kwds : dict + Parameters passed to `save_func`. + load_kwds : dict + Parameters passed to `numpy.load`. + args : tuple of arrays + Arrays stored to file. + + """ + save_kwds = kwargs.get('save_kwds', {}) + load_kwds = kwargs.get('load_kwds', {"allow_pickle": True}) + file_on_disk = kwargs.get('file_on_disk', False) + + if file_on_disk: + target_file = NamedTemporaryFile(delete=False) + load_file = target_file.name + else: + target_file = BytesIO() + load_file = target_file + + try: + arr = args + + save_func(target_file, *arr, **save_kwds) + target_file.flush() + target_file.seek(0) + + if sys.platform == 'win32' and not isinstance(target_file, BytesIO): + target_file.close() + + arr_reloaded = np.load(load_file, **load_kwds) + + self.arr = arr + self.arr_reloaded = arr_reloaded + finally: + if not isinstance(target_file, BytesIO): + target_file.close() + # holds an open file descriptor so it can't be deleted on win + if 'arr_reloaded' in locals(): + if not isinstance(arr_reloaded, np.lib.npyio.NpzFile): + os.remove(target_file.name) + + def check_roundtrips(self, a): + self.roundtrip(a) + self.roundtrip(a, file_on_disk=True) + self.roundtrip(np.asfortranarray(a)) + self.roundtrip(np.asfortranarray(a), file_on_disk=True) + if a.shape[0] > 1: + # neither C nor Fortran contiguous for 2D arrays or more + self.roundtrip(np.asfortranarray(a)[1:]) + self.roundtrip(np.asfortranarray(a)[1:], file_on_disk=True) + + def test_array(self): + a = np.array([], float) + self.check_roundtrips(a) + + a = np.array([[1, 2], [3, 4]], float) + self.check_roundtrips(a) + + a = np.array([[1, 2], [3, 4]], int) + self.check_roundtrips(a) + + a = np.array([[1 + 5j, 2 + 6j], [3 + 7j, 4 + 8j]], dtype=np.csingle) + self.check_roundtrips(a) + + a = np.array([[1 + 5j, 2 + 6j], [3 + 7j, 4 + 8j]], dtype=np.cdouble) + self.check_roundtrips(a) + + def test_array_object(self): + a = np.array([], object) + self.check_roundtrips(a) + + a = np.array([[1, 2], [3, 4]], object) + self.check_roundtrips(a) + + def test_1D(self): + a = np.array([1, 2, 3, 4], int) + self.roundtrip(a) + + @pytest.mark.skipif(sys.platform == 'win32', reason="Fails on Win32") + def test_mmap(self): + a = np.array([[1, 2.5], [4, 7.3]]) + self.roundtrip(a, file_on_disk=True, load_kwds={'mmap_mode': 'r'}) + + a = np.asfortranarray([[1, 2.5], [4, 7.3]]) + self.roundtrip(a, file_on_disk=True, load_kwds={'mmap_mode': 'r'}) + + def test_record(self): + a = np.array([(1, 2), (3, 4)], dtype=[('x', 'i4'), ('y', 'i4')]) + self.check_roundtrips(a) + + @pytest.mark.slow + def test_format_2_0(self): + dt = [(("%d" % i) * 100, float) for i in range(500)] + a = np.ones(1000, dtype=dt) + with warnings.catch_warnings(record=True): + warnings.filterwarnings('always', '', UserWarning) + self.check_roundtrips(a) + + +class TestSaveLoad(RoundtripTest): + def roundtrip(self, *args, **kwargs): + RoundtripTest.roundtrip(self, np.save, *args, **kwargs) + assert_equal(self.arr[0], self.arr_reloaded) + assert_equal(self.arr[0].dtype, self.arr_reloaded.dtype) + assert_equal(self.arr[0].flags.fnc, self.arr_reloaded.flags.fnc) + + +class TestSavezLoad(RoundtripTest): + def roundtrip(self, *args, **kwargs): + RoundtripTest.roundtrip(self, np.savez, *args, **kwargs) + try: + for n, arr in enumerate(self.arr): + reloaded = self.arr_reloaded['arr_%d' % n] + assert_equal(arr, reloaded) + assert_equal(arr.dtype, reloaded.dtype) + assert_equal(arr.flags.fnc, reloaded.flags.fnc) + finally: + # delete tempfile, must be done here on windows + if self.arr_reloaded.fid: + self.arr_reloaded.fid.close() + os.remove(self.arr_reloaded.fid.name) + + @pytest.mark.skipif(not IS_64BIT, reason="Needs 64bit platform") + @pytest.mark.slow + def test_big_arrays(self): + L = (1 << 31) + 100000 + a = np.empty(L, dtype=np.uint8) + with temppath(prefix="numpy_test_big_arrays_", suffix=".npz") as tmp: + np.savez(tmp, a=a) + del a + npfile = np.load(tmp) + a = npfile['a'] # Should succeed + npfile.close() + del a # Avoid pyflakes unused variable warning. + + def test_multiple_arrays(self): + a = np.array([[1, 2], [3, 4]], float) + b = np.array([[1 + 2j, 2 + 7j], [3 - 6j, 4 + 12j]], complex) + self.roundtrip(a, b) + + def test_named_arrays(self): + a = np.array([[1, 2], [3, 4]], float) + b = np.array([[1 + 2j, 2 + 7j], [3 - 6j, 4 + 12j]], complex) + c = BytesIO() + np.savez(c, file_a=a, file_b=b) + c.seek(0) + l = np.load(c) + assert_equal(a, l['file_a']) + assert_equal(b, l['file_b']) + + def test_BagObj(self): + a = np.array([[1, 2], [3, 4]], float) + b = np.array([[1 + 2j, 2 + 7j], [3 - 6j, 4 + 12j]], complex) + c = BytesIO() + np.savez(c, file_a=a, file_b=b) + c.seek(0) + l = np.load(c) + assert_equal(sorted(dir(l.f)), ['file_a','file_b']) + assert_equal(a, l.f.file_a) + assert_equal(b, l.f.file_b) + + def test_savez_filename_clashes(self): + # Test that issue #852 is fixed + # and savez functions in multithreaded environment + + def writer(error_list): + with temppath(suffix='.npz') as tmp: + arr = np.random.randn(500, 500) + try: + np.savez(tmp, arr=arr) + except OSError as err: + error_list.append(err) + + errors = [] + threads = [threading.Thread(target=writer, args=(errors,)) + for j in range(3)] + for t in threads: + t.start() + for t in threads: + t.join() + + if errors: + raise AssertionError(errors) + + def test_not_closing_opened_fid(self): + # Test that issue #2178 is fixed: + # verify could seek on 'loaded' file + with temppath(suffix='.npz') as tmp: + with open(tmp, 'wb') as fp: + np.savez(fp, data='LOVELY LOAD') + with open(tmp, 'rb', 10000) as fp: + fp.seek(0) + assert_(not fp.closed) + np.load(fp)['data'] + # fp must not get closed by .load + assert_(not fp.closed) + fp.seek(0) + assert_(not fp.closed) + + @pytest.mark.slow_pypy + def test_closing_fid(self): + # Test that issue #1517 (too many opened files) remains closed + # It might be a "weak" test since failed to get triggered on + # e.g. Debian sid of 2012 Jul 05 but was reported to + # trigger the failure on Ubuntu 10.04: + # http://projects.scipy.org/numpy/ticket/1517#comment:2 + with temppath(suffix='.npz') as tmp: + np.savez(tmp, data='LOVELY LOAD') + # We need to check if the garbage collector can properly close + # numpy npz file returned by np.load when their reference count + # goes to zero. Python 3 running in debug mode raises a + # ResourceWarning when file closing is left to the garbage + # collector, so we catch the warnings. + with suppress_warnings() as sup: + sup.filter(ResourceWarning) # TODO: specify exact message + for i in range(1, 1025): + try: + np.load(tmp)["data"] + except Exception as e: + msg = "Failed to load data from a file: %s" % e + raise AssertionError(msg) + finally: + if IS_PYPY: + gc.collect() + + def test_closing_zipfile_after_load(self): + # Check that zipfile owns file and can close it. This needs to + # pass a file name to load for the test. On windows failure will + # cause a second error will be raised when the attempt to remove + # the open file is made. + prefix = 'numpy_test_closing_zipfile_after_load_' + with temppath(suffix='.npz', prefix=prefix) as tmp: + np.savez(tmp, lab='place holder') + data = np.load(tmp) + fp = data.zip.fp + data.close() + assert_(fp.closed) + + +class TestSaveTxt: + def test_array(self): + a = np.array([[1, 2], [3, 4]], float) + fmt = "%.18e" + c = BytesIO() + np.savetxt(c, a, fmt=fmt) + c.seek(0) + assert_equal(c.readlines(), + [asbytes((fmt + ' ' + fmt + '\n') % (1, 2)), + asbytes((fmt + ' ' + fmt + '\n') % (3, 4))]) + + a = np.array([[1, 2], [3, 4]], int) + c = BytesIO() + np.savetxt(c, a, fmt='%d') + c.seek(0) + assert_equal(c.readlines(), [b'1 2\n', b'3 4\n']) + + def test_1D(self): + a = np.array([1, 2, 3, 4], int) + c = BytesIO() + np.savetxt(c, a, fmt='%d') + c.seek(0) + lines = c.readlines() + assert_equal(lines, [b'1\n', b'2\n', b'3\n', b'4\n']) + + def test_0D_3D(self): + c = BytesIO() + assert_raises(ValueError, np.savetxt, c, np.array(1)) + assert_raises(ValueError, np.savetxt, c, np.array([[[1], [2]]])) + + def test_structured(self): + a = np.array([(1, 2), (3, 4)], dtype=[('x', 'i4'), ('y', 'i4')]) + c = BytesIO() + np.savetxt(c, a, fmt='%d') + c.seek(0) + assert_equal(c.readlines(), [b'1 2\n', b'3 4\n']) + + def test_structured_padded(self): + # gh-13297 + a = np.array([(1, 2, 3),(4, 5, 6)], dtype=[ + ('foo', 'i4'), ('bar', 'i4'), ('baz', 'i4') + ]) + c = BytesIO() + np.savetxt(c, a[['foo', 'baz']], fmt='%d') + c.seek(0) + assert_equal(c.readlines(), [b'1 3\n', b'4 6\n']) + + def test_multifield_view(self): + a = np.ones(1, dtype=[('x', 'i4'), ('y', 'i4'), ('z', 'f4')]) + v = a[['x', 'z']] + with temppath(suffix='.npy') as path: + path = Path(path) + np.save(path, v) + data = np.load(path) + assert_array_equal(data, v) + + def test_delimiter(self): + a = np.array([[1., 2.], [3., 4.]]) + c = BytesIO() + np.savetxt(c, a, delimiter=',', fmt='%d') + c.seek(0) + assert_equal(c.readlines(), [b'1,2\n', b'3,4\n']) + + def test_format(self): + a = np.array([(1, 2), (3, 4)]) + c = BytesIO() + # Sequence of formats + np.savetxt(c, a, fmt=['%02d', '%3.1f']) + c.seek(0) + assert_equal(c.readlines(), [b'01 2.0\n', b'03 4.0\n']) + + # A single multiformat string + c = BytesIO() + np.savetxt(c, a, fmt='%02d : %3.1f') + c.seek(0) + lines = c.readlines() + assert_equal(lines, [b'01 : 2.0\n', b'03 : 4.0\n']) + + # Specify delimiter, should be overridden + c = BytesIO() + np.savetxt(c, a, fmt='%02d : %3.1f', delimiter=',') + c.seek(0) + lines = c.readlines() + assert_equal(lines, [b'01 : 2.0\n', b'03 : 4.0\n']) + + # Bad fmt, should raise a ValueError + c = BytesIO() + assert_raises(ValueError, np.savetxt, c, a, fmt=99) + + def test_header_footer(self): + # Test the functionality of the header and footer keyword argument. + + c = BytesIO() + a = np.array([(1, 2), (3, 4)], dtype=int) + test_header_footer = 'Test header / footer' + # Test the header keyword argument + np.savetxt(c, a, fmt='%1d', header=test_header_footer) + c.seek(0) + assert_equal(c.read(), + asbytes('# ' + test_header_footer + '\n1 2\n3 4\n')) + # Test the footer keyword argument + c = BytesIO() + np.savetxt(c, a, fmt='%1d', footer=test_header_footer) + c.seek(0) + assert_equal(c.read(), + asbytes('1 2\n3 4\n# ' + test_header_footer + '\n')) + # Test the commentstr keyword argument used on the header + c = BytesIO() + commentstr = '% ' + np.savetxt(c, a, fmt='%1d', + header=test_header_footer, comments=commentstr) + c.seek(0) + assert_equal(c.read(), + asbytes(commentstr + test_header_footer + '\n' + '1 2\n3 4\n')) + # Test the commentstr keyword argument used on the footer + c = BytesIO() + commentstr = '% ' + np.savetxt(c, a, fmt='%1d', + footer=test_header_footer, comments=commentstr) + c.seek(0) + assert_equal(c.read(), + asbytes('1 2\n3 4\n' + commentstr + test_header_footer + '\n')) + + def test_file_roundtrip(self): + with temppath() as name: + a = np.array([(1, 2), (3, 4)]) + np.savetxt(name, a) + b = np.loadtxt(name) + assert_array_equal(a, b) + + def test_complex_arrays(self): + ncols = 2 + nrows = 2 + a = np.zeros((ncols, nrows), dtype=np.complex128) + re = np.pi + im = np.e + a[:] = re + 1.0j * im + + # One format only + c = BytesIO() + np.savetxt(c, a, fmt=' %+.3e') + c.seek(0) + lines = c.readlines() + assert_equal( + lines, + [b' ( +3.142e+00+ +2.718e+00j) ( +3.142e+00+ +2.718e+00j)\n', + b' ( +3.142e+00+ +2.718e+00j) ( +3.142e+00+ +2.718e+00j)\n']) + + # One format for each real and imaginary part + c = BytesIO() + np.savetxt(c, a, fmt=' %+.3e' * 2 * ncols) + c.seek(0) + lines = c.readlines() + assert_equal( + lines, + [b' +3.142e+00 +2.718e+00 +3.142e+00 +2.718e+00\n', + b' +3.142e+00 +2.718e+00 +3.142e+00 +2.718e+00\n']) + + # One format for each complex number + c = BytesIO() + np.savetxt(c, a, fmt=['(%.3e%+.3ej)'] * ncols) + c.seek(0) + lines = c.readlines() + assert_equal( + lines, + [b'(3.142e+00+2.718e+00j) (3.142e+00+2.718e+00j)\n', + b'(3.142e+00+2.718e+00j) (3.142e+00+2.718e+00j)\n']) + + def test_complex_negative_exponent(self): + # Previous to 1.15, some formats generated x+-yj, gh 7895 + ncols = 2 + nrows = 2 + a = np.zeros((ncols, nrows), dtype=np.complex128) + re = np.pi + im = np.e + a[:] = re - 1.0j * im + c = BytesIO() + np.savetxt(c, a, fmt='%.3e') + c.seek(0) + lines = c.readlines() + assert_equal( + lines, + [b' (3.142e+00-2.718e+00j) (3.142e+00-2.718e+00j)\n', + b' (3.142e+00-2.718e+00j) (3.142e+00-2.718e+00j)\n']) + + + def test_custom_writer(self): + + class CustomWriter(list): + def write(self, text): + self.extend(text.split(b'\n')) + + w = CustomWriter() + a = np.array([(1, 2), (3, 4)]) + np.savetxt(w, a) + b = np.loadtxt(w) + assert_array_equal(a, b) + + def test_unicode(self): + utf8 = b'\xcf\x96'.decode('UTF-8') + a = np.array([utf8], dtype=np.unicode_) + with tempdir() as tmpdir: + # set encoding as on windows it may not be unicode even on py3 + np.savetxt(os.path.join(tmpdir, 'test.csv'), a, fmt=['%s'], + encoding='UTF-8') + + def test_unicode_roundtrip(self): + utf8 = b'\xcf\x96'.decode('UTF-8') + a = np.array([utf8], dtype=np.unicode_) + # our gz wrapper support encoding + suffixes = ['', '.gz'] + if HAS_BZ2: + suffixes.append('.bz2') + if HAS_LZMA: + suffixes.extend(['.xz', '.lzma']) + with tempdir() as tmpdir: + for suffix in suffixes: + np.savetxt(os.path.join(tmpdir, 'test.csv' + suffix), a, + fmt=['%s'], encoding='UTF-16-LE') + b = np.loadtxt(os.path.join(tmpdir, 'test.csv' + suffix), + encoding='UTF-16-LE', dtype=np.unicode_) + assert_array_equal(a, b) + + def test_unicode_bytestream(self): + utf8 = b'\xcf\x96'.decode('UTF-8') + a = np.array([utf8], dtype=np.unicode_) + s = BytesIO() + np.savetxt(s, a, fmt=['%s'], encoding='UTF-8') + s.seek(0) + assert_equal(s.read().decode('UTF-8'), utf8 + '\n') + + def test_unicode_stringstream(self): + utf8 = b'\xcf\x96'.decode('UTF-8') + a = np.array([utf8], dtype=np.unicode_) + s = StringIO() + np.savetxt(s, a, fmt=['%s'], encoding='UTF-8') + s.seek(0) + assert_equal(s.read(), utf8 + '\n') + + @pytest.mark.parametrize("fmt", [u"%f", b"%f"]) + @pytest.mark.parametrize("iotype", [StringIO, BytesIO]) + def test_unicode_and_bytes_fmt(self, fmt, iotype): + # string type of fmt should not matter, see also gh-4053 + a = np.array([1.]) + s = iotype() + np.savetxt(s, a, fmt=fmt) + s.seek(0) + if iotype is StringIO: + assert_equal(s.read(), u"%f\n" % 1.) + else: + assert_equal(s.read(), b"%f\n" % 1.) + + @pytest.mark.skipif(sys.platform=='win32', reason="files>4GB may not work") + @pytest.mark.slow + @requires_memory(free_bytes=7e9) + def test_large_zip(self): + def check_large_zip(memoryerror_raised): + memoryerror_raised.value = False + try: + # The test takes at least 6GB of memory, writes a file larger + # than 4GB. This tests the ``allowZip64`` kwarg to ``zipfile`` + test_data = np.asarray([np.random.rand( + np.random.randint(50,100),4) + for i in range(800000)], dtype=object) + with tempdir() as tmpdir: + np.savez(os.path.join(tmpdir, 'test.npz'), + test_data=test_data) + except MemoryError: + memoryerror_raised.value = True + raise + # run in a subprocess to ensure memory is released on PyPy, see gh-15775 + # Use an object in shared memory to re-raise the MemoryError exception + # in our process if needed, see gh-16889 + memoryerror_raised = Value(c_bool) + p = Process(target=check_large_zip, args=(memoryerror_raised,)) + p.start() + p.join() + if memoryerror_raised.value: + raise MemoryError("Child process raised a MemoryError exception") + # -9 indicates a SIGKILL, probably an OOM. + if p.exitcode == -9: + pytest.xfail("subprocess got a SIGKILL, apparently free memory was not sufficient") + assert p.exitcode == 0 + +class LoadTxtBase: + def check_compressed(self, fopen, suffixes): + # Test that we can load data from a compressed file + wanted = np.arange(6).reshape((2, 3)) + linesep = ('\n', '\r\n', '\r') + for sep in linesep: + data = '0 1 2' + sep + '3 4 5' + for suffix in suffixes: + with temppath(suffix=suffix) as name: + with fopen(name, mode='wt', encoding='UTF-32-LE') as f: + f.write(data) + res = self.loadfunc(name, encoding='UTF-32-LE') + assert_array_equal(res, wanted) + with fopen(name, "rt", encoding='UTF-32-LE') as f: + res = self.loadfunc(f) + assert_array_equal(res, wanted) + + def test_compressed_gzip(self): + self.check_compressed(gzip.open, ('.gz',)) + + @pytest.mark.skipif(not HAS_BZ2, reason="Needs bz2") + def test_compressed_bz2(self): + self.check_compressed(bz2.open, ('.bz2',)) + + @pytest.mark.skipif(not HAS_LZMA, reason="Needs lzma") + def test_compressed_lzma(self): + self.check_compressed(lzma.open, ('.xz', '.lzma')) + + def test_encoding(self): + with temppath() as path: + with open(path, "wb") as f: + f.write('0.\n1.\n2.'.encode("UTF-16")) + x = self.loadfunc(path, encoding="UTF-16") + assert_array_equal(x, [0., 1., 2.]) + + def test_stringload(self): + # umlaute + nonascii = b'\xc3\xb6\xc3\xbc\xc3\xb6'.decode("UTF-8") + with temppath() as path: + with open(path, "wb") as f: + f.write(nonascii.encode("UTF-16")) + x = self.loadfunc(path, encoding="UTF-16", dtype=np.unicode_) + assert_array_equal(x, nonascii) + + def test_binary_decode(self): + utf16 = b'\xff\xfeh\x04 \x00i\x04 \x00j\x04' + v = self.loadfunc(BytesIO(utf16), dtype=np.unicode_, encoding='UTF-16') + assert_array_equal(v, np.array(utf16.decode('UTF-16').split())) + + def test_converters_decode(self): + # test converters that decode strings + c = TextIO() + c.write(b'\xcf\x96') + c.seek(0) + x = self.loadfunc(c, dtype=np.unicode_, + converters={0: lambda x: x.decode('UTF-8')}) + a = np.array([b'\xcf\x96'.decode('UTF-8')]) + assert_array_equal(x, a) + + def test_converters_nodecode(self): + # test native string converters enabled by setting an encoding + utf8 = b'\xcf\x96'.decode('UTF-8') + with temppath() as path: + with io.open(path, 'wt', encoding='UTF-8') as f: + f.write(utf8) + x = self.loadfunc(path, dtype=np.unicode_, + converters={0: lambda x: x + 't'}, + encoding='UTF-8') + a = np.array([utf8 + 't']) + assert_array_equal(x, a) + + +class TestLoadTxt(LoadTxtBase): + loadfunc = staticmethod(np.loadtxt) + + def setup(self): + # lower chunksize for testing + self.orig_chunk = np.lib.npyio._loadtxt_chunksize + np.lib.npyio._loadtxt_chunksize = 1 + def teardown(self): + np.lib.npyio._loadtxt_chunksize = self.orig_chunk + + def test_record(self): + c = TextIO() + c.write('1 2\n3 4') + c.seek(0) + x = np.loadtxt(c, dtype=[('x', np.int32), ('y', np.int32)]) + a = np.array([(1, 2), (3, 4)], dtype=[('x', 'i4'), ('y', 'i4')]) + assert_array_equal(x, a) + + d = TextIO() + d.write('M 64.0 75.0\nF 25.0 60.0') + d.seek(0) + mydescriptor = {'names': ('gender', 'age', 'weight'), + 'formats': ('S1', 'i4', 'f4')} + b = np.array([('M', 64.0, 75.0), + ('F', 25.0, 60.0)], dtype=mydescriptor) + y = np.loadtxt(d, dtype=mydescriptor) + assert_array_equal(y, b) + + def test_array(self): + c = TextIO() + c.write('1 2\n3 4') + + c.seek(0) + x = np.loadtxt(c, dtype=int) + a = np.array([[1, 2], [3, 4]], int) + assert_array_equal(x, a) + + c.seek(0) + x = np.loadtxt(c, dtype=float) + a = np.array([[1, 2], [3, 4]], float) + assert_array_equal(x, a) + + def test_1D(self): + c = TextIO() + c.write('1\n2\n3\n4\n') + c.seek(0) + x = np.loadtxt(c, dtype=int) + a = np.array([1, 2, 3, 4], int) + assert_array_equal(x, a) + + c = TextIO() + c.write('1,2,3,4\n') + c.seek(0) + x = np.loadtxt(c, dtype=int, delimiter=',') + a = np.array([1, 2, 3, 4], int) + assert_array_equal(x, a) + + def test_missing(self): + c = TextIO() + c.write('1,2,3,,5\n') + c.seek(0) + x = np.loadtxt(c, dtype=int, delimiter=',', + converters={3: lambda s: int(s or - 999)}) + a = np.array([1, 2, 3, -999, 5], int) + assert_array_equal(x, a) + + def test_converters_with_usecols(self): + c = TextIO() + c.write('1,2,3,,5\n6,7,8,9,10\n') + c.seek(0) + x = np.loadtxt(c, dtype=int, delimiter=',', + converters={3: lambda s: int(s or - 999)}, + usecols=(1, 3,)) + a = np.array([[2, -999], [7, 9]], int) + assert_array_equal(x, a) + + def test_comments_unicode(self): + c = TextIO() + c.write('# comment\n1,2,3,5\n') + c.seek(0) + x = np.loadtxt(c, dtype=int, delimiter=',', + comments=u'#') + a = np.array([1, 2, 3, 5], int) + assert_array_equal(x, a) + + def test_comments_byte(self): + c = TextIO() + c.write('# comment\n1,2,3,5\n') + c.seek(0) + x = np.loadtxt(c, dtype=int, delimiter=',', + comments=b'#') + a = np.array([1, 2, 3, 5], int) + assert_array_equal(x, a) + + def test_comments_multiple(self): + c = TextIO() + c.write('# comment\n1,2,3\n@ comment2\n4,5,6 // comment3') + c.seek(0) + x = np.loadtxt(c, dtype=int, delimiter=',', + comments=['#', '@', '//']) + a = np.array([[1, 2, 3], [4, 5, 6]], int) + assert_array_equal(x, a) + + def test_comments_multi_chars(self): + c = TextIO() + c.write('/* comment\n1,2,3,5\n') + c.seek(0) + x = np.loadtxt(c, dtype=int, delimiter=',', + comments='/*') + a = np.array([1, 2, 3, 5], int) + assert_array_equal(x, a) + + # Check that '/*' is not transformed to ['/', '*'] + c = TextIO() + c.write('*/ comment\n1,2,3,5\n') + c.seek(0) + assert_raises(ValueError, np.loadtxt, c, dtype=int, delimiter=',', + comments='/*') + + def test_skiprows(self): + c = TextIO() + c.write('comment\n1,2,3,5\n') + c.seek(0) + x = np.loadtxt(c, dtype=int, delimiter=',', + skiprows=1) + a = np.array([1, 2, 3, 5], int) + assert_array_equal(x, a) + + c = TextIO() + c.write('# comment\n1,2,3,5\n') + c.seek(0) + x = np.loadtxt(c, dtype=int, delimiter=',', + skiprows=1) + a = np.array([1, 2, 3, 5], int) + assert_array_equal(x, a) + + def test_usecols(self): + a = np.array([[1, 2], [3, 4]], float) + c = BytesIO() + np.savetxt(c, a) + c.seek(0) + x = np.loadtxt(c, dtype=float, usecols=(1,)) + assert_array_equal(x, a[:, 1]) + + a = np.array([[1, 2, 3], [3, 4, 5]], float) + c = BytesIO() + np.savetxt(c, a) + c.seek(0) + x = np.loadtxt(c, dtype=float, usecols=(1, 2)) + assert_array_equal(x, a[:, 1:]) + + # Testing with arrays instead of tuples. + c.seek(0) + x = np.loadtxt(c, dtype=float, usecols=np.array([1, 2])) + assert_array_equal(x, a[:, 1:]) + + # Testing with an integer instead of a sequence + for int_type in [int, np.int8, np.int16, + np.int32, np.int64, np.uint8, np.uint16, + np.uint32, np.uint64]: + to_read = int_type(1) + c.seek(0) + x = np.loadtxt(c, dtype=float, usecols=to_read) + assert_array_equal(x, a[:, 1]) + + # Testing with some crazy custom integer type + class CrazyInt: + def __index__(self): + return 1 + + crazy_int = CrazyInt() + c.seek(0) + x = np.loadtxt(c, dtype=float, usecols=crazy_int) + assert_array_equal(x, a[:, 1]) + + c.seek(0) + x = np.loadtxt(c, dtype=float, usecols=(crazy_int,)) + assert_array_equal(x, a[:, 1]) + + # Checking with dtypes defined converters. + data = '''JOE 70.1 25.3 + BOB 60.5 27.9 + ''' + c = TextIO(data) + names = ['stid', 'temp'] + dtypes = ['S4', 'f8'] + arr = np.loadtxt(c, usecols=(0, 2), dtype=list(zip(names, dtypes))) + assert_equal(arr['stid'], [b"JOE", b"BOB"]) + assert_equal(arr['temp'], [25.3, 27.9]) + + # Testing non-ints in usecols + c.seek(0) + bogus_idx = 1.5 + assert_raises_regex( + TypeError, + '^usecols must be.*%s' % type(bogus_idx), + np.loadtxt, c, usecols=bogus_idx + ) + + assert_raises_regex( + TypeError, + '^usecols must be.*%s' % type(bogus_idx), + np.loadtxt, c, usecols=[0, bogus_idx, 0] + ) + + def test_fancy_dtype(self): + c = TextIO() + c.write('1,2,3.0\n4,5,6.0\n') + c.seek(0) + dt = np.dtype([('x', int), ('y', [('t', int), ('s', float)])]) + x = np.loadtxt(c, dtype=dt, delimiter=',') + a = np.array([(1, (2, 3.0)), (4, (5, 6.0))], dt) + assert_array_equal(x, a) + + def test_shaped_dtype(self): + c = TextIO("aaaa 1.0 8.0 1 2 3 4 5 6") + dt = np.dtype([('name', 'S4'), ('x', float), ('y', float), + ('block', int, (2, 3))]) + x = np.loadtxt(c, dtype=dt) + a = np.array([('aaaa', 1.0, 8.0, [[1, 2, 3], [4, 5, 6]])], + dtype=dt) + assert_array_equal(x, a) + + def test_3d_shaped_dtype(self): + c = TextIO("aaaa 1.0 8.0 1 2 3 4 5 6 7 8 9 10 11 12") + dt = np.dtype([('name', 'S4'), ('x', float), ('y', float), + ('block', int, (2, 2, 3))]) + x = np.loadtxt(c, dtype=dt) + a = np.array([('aaaa', 1.0, 8.0, + [[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]])], + dtype=dt) + assert_array_equal(x, a) + + def test_str_dtype(self): + # see gh-8033 + c = ["str1", "str2"] + + for dt in (str, np.bytes_): + a = np.array(["str1", "str2"], dtype=dt) + x = np.loadtxt(c, dtype=dt) + assert_array_equal(x, a) + + def test_empty_file(self): + with suppress_warnings() as sup: + sup.filter(message="loadtxt: Empty input file:") + c = TextIO() + x = np.loadtxt(c) + assert_equal(x.shape, (0,)) + x = np.loadtxt(c, dtype=np.int64) + assert_equal(x.shape, (0,)) + assert_(x.dtype == np.int64) + + def test_unused_converter(self): + c = TextIO() + c.writelines(['1 21\n', '3 42\n']) + c.seek(0) + data = np.loadtxt(c, usecols=(1,), + converters={0: lambda s: int(s, 16)}) + assert_array_equal(data, [21, 42]) + + c.seek(0) + data = np.loadtxt(c, usecols=(1,), + converters={1: lambda s: int(s, 16)}) + assert_array_equal(data, [33, 66]) + + def test_dtype_with_object(self): + # Test using an explicit dtype with an object + data = """ 1; 2001-01-01 + 2; 2002-01-31 """ + ndtype = [('idx', int), ('code', object)] + func = lambda s: strptime(s.strip(), "%Y-%m-%d") + converters = {1: func} + test = np.loadtxt(TextIO(data), delimiter=";", dtype=ndtype, + converters=converters) + control = np.array( + [(1, datetime(2001, 1, 1)), (2, datetime(2002, 1, 31))], + dtype=ndtype) + assert_equal(test, control) + + def test_uint64_type(self): + tgt = (9223372043271415339, 9223372043271415853) + c = TextIO() + c.write("%s %s" % tgt) + c.seek(0) + res = np.loadtxt(c, dtype=np.uint64) + assert_equal(res, tgt) + + def test_int64_type(self): + tgt = (-9223372036854775807, 9223372036854775807) + c = TextIO() + c.write("%s %s" % tgt) + c.seek(0) + res = np.loadtxt(c, dtype=np.int64) + assert_equal(res, tgt) + + def test_from_float_hex(self): + # IEEE doubles and floats only, otherwise the float32 + # conversion may fail. + tgt = np.logspace(-10, 10, 5).astype(np.float32) + tgt = np.hstack((tgt, -tgt)).astype(float) + inp = '\n'.join(map(float.hex, tgt)) + c = TextIO() + c.write(inp) + for dt in [float, np.float32]: + c.seek(0) + res = np.loadtxt(c, dtype=dt) + assert_equal(res, tgt, err_msg="%s" % dt) + + def test_from_complex(self): + tgt = (complex(1, 1), complex(1, -1)) + c = TextIO() + c.write("%s %s" % tgt) + c.seek(0) + res = np.loadtxt(c, dtype=complex) + assert_equal(res, tgt) + + def test_complex_misformatted(self): + # test for backward compatibility + # some complex formats used to generate x+-yj + a = np.zeros((2, 2), dtype=np.complex128) + re = np.pi + im = np.e + a[:] = re - 1.0j * im + c = BytesIO() + np.savetxt(c, a, fmt='%.16e') + c.seek(0) + txt = c.read() + c.seek(0) + # misformat the sign on the imaginary part, gh 7895 + txt_bad = txt.replace(b'e+00-', b'e00+-') + assert_(txt_bad != txt) + c.write(txt_bad) + c.seek(0) + res = np.loadtxt(c, dtype=complex) + assert_equal(res, a) + + def test_universal_newline(self): + with temppath() as name: + with open(name, 'w') as f: + f.write('1 21\r3 42\r') + data = np.loadtxt(name) + assert_array_equal(data, [[1, 21], [3, 42]]) + + def test_empty_field_after_tab(self): + c = TextIO() + c.write('1 \t2 \t3\tstart \n4\t5\t6\t \n7\t8\t9.5\t') + c.seek(0) + dt = {'names': ('x', 'y', 'z', 'comment'), + 'formats': (' num rows + c = TextIO() + c.write('comment\n1,2,3,5\n4,5,7,8\n2,1,4,5') + c.seek(0) + x = np.loadtxt(c, dtype=int, delimiter=',', + skiprows=1, max_rows=6) + a = np.array([[1, 2, 3, 5], [4, 5, 7, 8], [2, 1, 4, 5]], int) + assert_array_equal(x, a) + +class Testfromregex: + def test_record(self): + c = TextIO() + c.write('1.312 foo\n1.534 bar\n4.444 qux') + c.seek(0) + + dt = [('num', np.float64), ('val', 'S3')] + x = np.fromregex(c, r"([0-9.]+)\s+(...)", dt) + a = np.array([(1.312, 'foo'), (1.534, 'bar'), (4.444, 'qux')], + dtype=dt) + assert_array_equal(x, a) + + def test_record_2(self): + c = TextIO() + c.write('1312 foo\n1534 bar\n4444 qux') + c.seek(0) + + dt = [('num', np.int32), ('val', 'S3')] + x = np.fromregex(c, r"(\d+)\s+(...)", dt) + a = np.array([(1312, 'foo'), (1534, 'bar'), (4444, 'qux')], + dtype=dt) + assert_array_equal(x, a) + + def test_record_3(self): + c = TextIO() + c.write('1312 foo\n1534 bar\n4444 qux') + c.seek(0) + + dt = [('num', np.float64)] + x = np.fromregex(c, r"(\d+)\s+...", dt) + a = np.array([(1312,), (1534,), (4444,)], dtype=dt) + assert_array_equal(x, a) + + def test_record_unicode(self): + utf8 = b'\xcf\x96' + with temppath() as path: + with open(path, 'wb') as f: + f.write(b'1.312 foo' + utf8 + b' \n1.534 bar\n4.444 qux') + + dt = [('num', np.float64), ('val', 'U4')] + x = np.fromregex(path, r"(?u)([0-9.]+)\s+(\w+)", dt, encoding='UTF-8') + a = np.array([(1.312, 'foo' + utf8.decode('UTF-8')), (1.534, 'bar'), + (4.444, 'qux')], dtype=dt) + assert_array_equal(x, a) + + regexp = re.compile(r"([0-9.]+)\s+(\w+)", re.UNICODE) + x = np.fromregex(path, regexp, dt, encoding='UTF-8') + assert_array_equal(x, a) + + def test_compiled_bytes(self): + regexp = re.compile(b'(\\d)') + c = BytesIO(b'123') + dt = [('num', np.float64)] + a = np.array([1, 2, 3], dtype=dt) + x = np.fromregex(c, regexp, dt) + assert_array_equal(x, a) + +#####-------------------------------------------------------------------------- + + +class TestFromTxt(LoadTxtBase): + loadfunc = staticmethod(np.genfromtxt) + + def test_record(self): + # Test w/ explicit dtype + data = TextIO('1 2\n3 4') + test = np.genfromtxt(data, dtype=[('x', np.int32), ('y', np.int32)]) + control = np.array([(1, 2), (3, 4)], dtype=[('x', 'i4'), ('y', 'i4')]) + assert_equal(test, control) + # + data = TextIO('M 64.0 75.0\nF 25.0 60.0') + descriptor = {'names': ('gender', 'age', 'weight'), + 'formats': ('S1', 'i4', 'f4')} + control = np.array([('M', 64.0, 75.0), ('F', 25.0, 60.0)], + dtype=descriptor) + test = np.genfromtxt(data, dtype=descriptor) + assert_equal(test, control) + + def test_array(self): + # Test outputting a standard ndarray + data = TextIO('1 2\n3 4') + control = np.array([[1, 2], [3, 4]], dtype=int) + test = np.genfromtxt(data, dtype=int) + assert_array_equal(test, control) + # + data.seek(0) + control = np.array([[1, 2], [3, 4]], dtype=float) + test = np.loadtxt(data, dtype=float) + assert_array_equal(test, control) + + def test_1D(self): + # Test squeezing to 1D + control = np.array([1, 2, 3, 4], int) + # + data = TextIO('1\n2\n3\n4\n') + test = np.genfromtxt(data, dtype=int) + assert_array_equal(test, control) + # + data = TextIO('1,2,3,4\n') + test = np.genfromtxt(data, dtype=int, delimiter=',') + assert_array_equal(test, control) + + def test_comments(self): + # Test the stripping of comments + control = np.array([1, 2, 3, 5], int) + # Comment on its own line + data = TextIO('# comment\n1,2,3,5\n') + test = np.genfromtxt(data, dtype=int, delimiter=',', comments='#') + assert_equal(test, control) + # Comment at the end of a line + data = TextIO('1,2,3,5# comment\n') + test = np.genfromtxt(data, dtype=int, delimiter=',', comments='#') + assert_equal(test, control) + + def test_skiprows(self): + # Test row skipping + control = np.array([1, 2, 3, 5], int) + kwargs = dict(dtype=int, delimiter=',') + # + data = TextIO('comment\n1,2,3,5\n') + test = np.genfromtxt(data, skip_header=1, **kwargs) + assert_equal(test, control) + # + data = TextIO('# comment\n1,2,3,5\n') + test = np.loadtxt(data, skiprows=1, **kwargs) + assert_equal(test, control) + + def test_skip_footer(self): + data = ["# %i" % i for i in range(1, 6)] + data.append("A, B, C") + data.extend(["%i,%3.1f,%03s" % (i, i, i) for i in range(51)]) + data[-1] = "99,99" + kwargs = dict(delimiter=",", names=True, skip_header=5, skip_footer=10) + test = np.genfromtxt(TextIO("\n".join(data)), **kwargs) + ctrl = np.array([("%f" % i, "%f" % i, "%f" % i) for i in range(41)], + dtype=[(_, float) for _ in "ABC"]) + assert_equal(test, ctrl) + + def test_skip_footer_with_invalid(self): + with suppress_warnings() as sup: + sup.filter(ConversionWarning) + basestr = '1 1\n2 2\n3 3\n4 4\n5 \n6 \n7 \n' + # Footer too small to get rid of all invalid values + assert_raises(ValueError, np.genfromtxt, + TextIO(basestr), skip_footer=1) + # except ValueError: + # pass + a = np.genfromtxt( + TextIO(basestr), skip_footer=1, invalid_raise=False) + assert_equal(a, np.array([[1., 1.], [2., 2.], [3., 3.], [4., 4.]])) + # + a = np.genfromtxt(TextIO(basestr), skip_footer=3) + assert_equal(a, np.array([[1., 1.], [2., 2.], [3., 3.], [4., 4.]])) + # + basestr = '1 1\n2 \n3 3\n4 4\n5 \n6 6\n7 7\n' + a = np.genfromtxt( + TextIO(basestr), skip_footer=1, invalid_raise=False) + assert_equal(a, np.array([[1., 1.], [3., 3.], [4., 4.], [6., 6.]])) + a = np.genfromtxt( + TextIO(basestr), skip_footer=3, invalid_raise=False) + assert_equal(a, np.array([[1., 1.], [3., 3.], [4., 4.]])) + + def test_header(self): + # Test retrieving a header + data = TextIO('gender age weight\nM 64.0 75.0\nF 25.0 60.0') + with warnings.catch_warnings(record=True) as w: + warnings.filterwarnings('always', '', np.VisibleDeprecationWarning) + test = np.genfromtxt(data, dtype=None, names=True) + assert_(w[0].category is np.VisibleDeprecationWarning) + control = {'gender': np.array([b'M', b'F']), + 'age': np.array([64.0, 25.0]), + 'weight': np.array([75.0, 60.0])} + assert_equal(test['gender'], control['gender']) + assert_equal(test['age'], control['age']) + assert_equal(test['weight'], control['weight']) + + def test_auto_dtype(self): + # Test the automatic definition of the output dtype + data = TextIO('A 64 75.0 3+4j True\nBCD 25 60.0 5+6j False') + with warnings.catch_warnings(record=True) as w: + warnings.filterwarnings('always', '', np.VisibleDeprecationWarning) + test = np.genfromtxt(data, dtype=None) + assert_(w[0].category is np.VisibleDeprecationWarning) + control = [np.array([b'A', b'BCD']), + np.array([64, 25]), + np.array([75.0, 60.0]), + np.array([3 + 4j, 5 + 6j]), + np.array([True, False]), ] + assert_equal(test.dtype.names, ['f0', 'f1', 'f2', 'f3', 'f4']) + for (i, ctrl) in enumerate(control): + assert_equal(test['f%i' % i], ctrl) + + def test_auto_dtype_uniform(self): + # Tests whether the output dtype can be uniformized + data = TextIO('1 2 3 4\n5 6 7 8\n') + test = np.genfromtxt(data, dtype=None) + control = np.array([[1, 2, 3, 4], [5, 6, 7, 8]]) + assert_equal(test, control) + + def test_fancy_dtype(self): + # Check that a nested dtype isn't MIA + data = TextIO('1,2,3.0\n4,5,6.0\n') + fancydtype = np.dtype([('x', int), ('y', [('t', int), ('s', float)])]) + test = np.genfromtxt(data, dtype=fancydtype, delimiter=',') + control = np.array([(1, (2, 3.0)), (4, (5, 6.0))], dtype=fancydtype) + assert_equal(test, control) + + def test_names_overwrite(self): + # Test overwriting the names of the dtype + descriptor = {'names': ('g', 'a', 'w'), + 'formats': ('S1', 'i4', 'f4')} + data = TextIO(b'M 64.0 75.0\nF 25.0 60.0') + names = ('gender', 'age', 'weight') + test = np.genfromtxt(data, dtype=descriptor, names=names) + descriptor['names'] = names + control = np.array([('M', 64.0, 75.0), + ('F', 25.0, 60.0)], dtype=descriptor) + assert_equal(test, control) + + def test_commented_header(self): + # Check that names can be retrieved even if the line is commented out. + data = TextIO(""" +#gender age weight +M 21 72.100000 +F 35 58.330000 +M 33 21.99 + """) + # The # is part of the first name and should be deleted automatically. + with warnings.catch_warnings(record=True) as w: + warnings.filterwarnings('always', '', np.VisibleDeprecationWarning) + test = np.genfromtxt(data, names=True, dtype=None) + assert_(w[0].category is np.VisibleDeprecationWarning) + ctrl = np.array([('M', 21, 72.1), ('F', 35, 58.33), ('M', 33, 21.99)], + dtype=[('gender', '|S1'), ('age', int), ('weight', float)]) + assert_equal(test, ctrl) + # Ditto, but we should get rid of the first element + data = TextIO(b""" +# gender age weight +M 21 72.100000 +F 35 58.330000 +M 33 21.99 + """) + with warnings.catch_warnings(record=True) as w: + warnings.filterwarnings('always', '', np.VisibleDeprecationWarning) + test = np.genfromtxt(data, names=True, dtype=None) + assert_(w[0].category is np.VisibleDeprecationWarning) + assert_equal(test, ctrl) + + def test_names_and_comments_none(self): + # Tests case when names is true but comments is None (gh-10780) + data = TextIO('col1 col2\n 1 2\n 3 4') + test = np.genfromtxt(data, dtype=(int, int), comments=None, names=True) + control = np.array([(1, 2), (3, 4)], dtype=[('col1', int), ('col2', int)]) + assert_equal(test, control) + + def test_file_is_closed_on_error(self): + # gh-13200 + with tempdir() as tmpdir: + fpath = os.path.join(tmpdir, "test.csv") + with open(fpath, "wb") as f: + f.write(u'\N{GREEK PI SYMBOL}'.encode('utf8')) + + # ResourceWarnings are emitted from a destructor, so won't be + # detected by regular propagation to errors. + with assert_no_warnings(): + with pytest.raises(UnicodeDecodeError): + np.genfromtxt(fpath, encoding="ascii") + + def test_autonames_and_usecols(self): + # Tests names and usecols + data = TextIO('A B C D\n aaaa 121 45 9.1') + with warnings.catch_warnings(record=True) as w: + warnings.filterwarnings('always', '', np.VisibleDeprecationWarning) + test = np.genfromtxt(data, usecols=('A', 'C', 'D'), + names=True, dtype=None) + assert_(w[0].category is np.VisibleDeprecationWarning) + control = np.array(('aaaa', 45, 9.1), + dtype=[('A', '|S4'), ('C', int), ('D', float)]) + assert_equal(test, control) + + def test_converters_with_usecols(self): + # Test the combination user-defined converters and usecol + data = TextIO('1,2,3,,5\n6,7,8,9,10\n') + test = np.genfromtxt(data, dtype=int, delimiter=',', + converters={3: lambda s: int(s or - 999)}, + usecols=(1, 3,)) + control = np.array([[2, -999], [7, 9]], int) + assert_equal(test, control) + + def test_converters_with_usecols_and_names(self): + # Tests names and usecols + data = TextIO('A B C D\n aaaa 121 45 9.1') + with warnings.catch_warnings(record=True) as w: + warnings.filterwarnings('always', '', np.VisibleDeprecationWarning) + test = np.genfromtxt(data, usecols=('A', 'C', 'D'), names=True, + dtype=None, + converters={'C': lambda s: 2 * int(s)}) + assert_(w[0].category is np.VisibleDeprecationWarning) + control = np.array(('aaaa', 90, 9.1), + dtype=[('A', '|S4'), ('C', int), ('D', float)]) + assert_equal(test, control) + + def test_converters_cornercases(self): + # Test the conversion to datetime. + converter = { + 'date': lambda s: strptime(s, '%Y-%m-%d %H:%M:%SZ')} + data = TextIO('2009-02-03 12:00:00Z, 72214.0') + test = np.genfromtxt(data, delimiter=',', dtype=None, + names=['date', 'stid'], converters=converter) + control = np.array((datetime(2009, 2, 3), 72214.), + dtype=[('date', np.object_), ('stid', float)]) + assert_equal(test, control) + + def test_converters_cornercases2(self): + # Test the conversion to datetime64. + converter = { + 'date': lambda s: np.datetime64(strptime(s, '%Y-%m-%d %H:%M:%SZ'))} + data = TextIO('2009-02-03 12:00:00Z, 72214.0') + test = np.genfromtxt(data, delimiter=',', dtype=None, + names=['date', 'stid'], converters=converter) + control = np.array((datetime(2009, 2, 3), 72214.), + dtype=[('date', 'datetime64[us]'), ('stid', float)]) + assert_equal(test, control) + + def test_unused_converter(self): + # Test whether unused converters are forgotten + data = TextIO("1 21\n 3 42\n") + test = np.genfromtxt(data, usecols=(1,), + converters={0: lambda s: int(s, 16)}) + assert_equal(test, [21, 42]) + # + data.seek(0) + test = np.genfromtxt(data, usecols=(1,), + converters={1: lambda s: int(s, 16)}) + assert_equal(test, [33, 66]) + + def test_invalid_converter(self): + strip_rand = lambda x: float((b'r' in x.lower() and x.split()[-1]) or + (b'r' not in x.lower() and x.strip() or 0.0)) + strip_per = lambda x: float((b'%' in x.lower() and x.split()[0]) or + (b'%' not in x.lower() and x.strip() or 0.0)) + s = TextIO("D01N01,10/1/2003 ,1 %,R 75,400,600\r\n" + "L24U05,12/5/2003, 2 %,1,300, 150.5\r\n" + "D02N03,10/10/2004,R 1,,7,145.55") + kwargs = dict( + converters={2: strip_per, 3: strip_rand}, delimiter=",", + dtype=None) + assert_raises(ConverterError, np.genfromtxt, s, **kwargs) + + def test_tricky_converter_bug1666(self): + # Test some corner cases + s = TextIO('q1,2\nq3,4') + cnv = lambda s: float(s[1:]) + test = np.genfromtxt(s, delimiter=',', converters={0: cnv}) + control = np.array([[1., 2.], [3., 4.]]) + assert_equal(test, control) + + def test_dtype_with_converters(self): + dstr = "2009; 23; 46" + test = np.genfromtxt(TextIO(dstr,), + delimiter=";", dtype=float, converters={0: bytes}) + control = np.array([('2009', 23., 46)], + dtype=[('f0', '|S4'), ('f1', float), ('f2', float)]) + assert_equal(test, control) + test = np.genfromtxt(TextIO(dstr,), + delimiter=";", dtype=float, converters={0: float}) + control = np.array([2009., 23., 46],) + assert_equal(test, control) + + def test_dtype_with_converters_and_usecols(self): + dstr = "1,5,-1,1:1\n2,8,-1,1:n\n3,3,-2,m:n\n" + dmap = {'1:1':0, '1:n':1, 'm:1':2, 'm:n':3} + dtyp = [('e1','i4'),('e2','i4'),('e3','i2'),('n', 'i1')] + conv = {0: int, 1: int, 2: int, 3: lambda r: dmap[r.decode()]} + test = np.recfromcsv(TextIO(dstr,), dtype=dtyp, delimiter=',', + names=None, converters=conv) + control = np.rec.array([(1,5,-1,0), (2,8,-1,1), (3,3,-2,3)], dtype=dtyp) + assert_equal(test, control) + dtyp = [('e1','i4'),('e2','i4'),('n', 'i1')] + test = np.recfromcsv(TextIO(dstr,), dtype=dtyp, delimiter=',', + usecols=(0,1,3), names=None, converters=conv) + control = np.rec.array([(1,5,0), (2,8,1), (3,3,3)], dtype=dtyp) + assert_equal(test, control) + + def test_dtype_with_object(self): + # Test using an explicit dtype with an object + data = """ 1; 2001-01-01 + 2; 2002-01-31 """ + ndtype = [('idx', int), ('code', object)] + func = lambda s: strptime(s.strip(), "%Y-%m-%d") + converters = {1: func} + test = np.genfromtxt(TextIO(data), delimiter=";", dtype=ndtype, + converters=converters) + control = np.array( + [(1, datetime(2001, 1, 1)), (2, datetime(2002, 1, 31))], + dtype=ndtype) + assert_equal(test, control) + + ndtype = [('nest', [('idx', int), ('code', object)])] + with assert_raises_regex(NotImplementedError, + 'Nested fields.* not supported.*'): + test = np.genfromtxt(TextIO(data), delimiter=";", + dtype=ndtype, converters=converters) + + # nested but empty fields also aren't supported + ndtype = [('idx', int), ('code', object), ('nest', [])] + with assert_raises_regex(NotImplementedError, + 'Nested fields.* not supported.*'): + test = np.genfromtxt(TextIO(data), delimiter=";", + dtype=ndtype, converters=converters) + + def test_dtype_with_object_no_converter(self): + # Object without a converter uses bytes: + parsed = np.genfromtxt(TextIO("1"), dtype=object) + assert parsed[()] == b"1" + parsed = np.genfromtxt(TextIO("string"), dtype=object) + assert parsed[()] == b"string" + + def test_userconverters_with_explicit_dtype(self): + # Test user_converters w/ explicit (standard) dtype + data = TextIO('skip,skip,2001-01-01,1.0,skip') + test = np.genfromtxt(data, delimiter=",", names=None, dtype=float, + usecols=(2, 3), converters={2: bytes}) + control = np.array([('2001-01-01', 1.)], + dtype=[('', '|S10'), ('', float)]) + assert_equal(test, control) + + def test_utf8_userconverters_with_explicit_dtype(self): + utf8 = b'\xcf\x96' + with temppath() as path: + with open(path, 'wb') as f: + f.write(b'skip,skip,2001-01-01' + utf8 + b',1.0,skip') + test = np.genfromtxt(path, delimiter=",", names=None, dtype=float, + usecols=(2, 3), converters={2: np.compat.unicode}, + encoding='UTF-8') + control = np.array([('2001-01-01' + utf8.decode('UTF-8'), 1.)], + dtype=[('', '|U11'), ('', float)]) + assert_equal(test, control) + + def test_spacedelimiter(self): + # Test space delimiter + data = TextIO("1 2 3 4 5\n6 7 8 9 10") + test = np.genfromtxt(data) + control = np.array([[1., 2., 3., 4., 5.], + [6., 7., 8., 9., 10.]]) + assert_equal(test, control) + + def test_integer_delimiter(self): + # Test using an integer for delimiter + data = " 1 2 3\n 4 5 67\n890123 4" + test = np.genfromtxt(TextIO(data), delimiter=3) + control = np.array([[1, 2, 3], [4, 5, 67], [890, 123, 4]]) + assert_equal(test, control) + + def test_missing(self): + data = TextIO('1,2,3,,5\n') + test = np.genfromtxt(data, dtype=int, delimiter=',', + converters={3: lambda s: int(s or - 999)}) + control = np.array([1, 2, 3, -999, 5], int) + assert_equal(test, control) + + def test_missing_with_tabs(self): + # Test w/ a delimiter tab + txt = "1\t2\t3\n\t2\t\n1\t\t3" + test = np.genfromtxt(TextIO(txt), delimiter="\t", + usemask=True,) + ctrl_d = np.array([(1, 2, 3), (np.nan, 2, np.nan), (1, np.nan, 3)],) + ctrl_m = np.array([(0, 0, 0), (1, 0, 1), (0, 1, 0)], dtype=bool) + assert_equal(test.data, ctrl_d) + assert_equal(test.mask, ctrl_m) + + def test_usecols(self): + # Test the selection of columns + # Select 1 column + control = np.array([[1, 2], [3, 4]], float) + data = TextIO() + np.savetxt(data, control) + data.seek(0) + test = np.genfromtxt(data, dtype=float, usecols=(1,)) + assert_equal(test, control[:, 1]) + # + control = np.array([[1, 2, 3], [3, 4, 5]], float) + data = TextIO() + np.savetxt(data, control) + data.seek(0) + test = np.genfromtxt(data, dtype=float, usecols=(1, 2)) + assert_equal(test, control[:, 1:]) + # Testing with arrays instead of tuples. + data.seek(0) + test = np.genfromtxt(data, dtype=float, usecols=np.array([1, 2])) + assert_equal(test, control[:, 1:]) + + def test_usecols_as_css(self): + # Test giving usecols with a comma-separated string + data = "1 2 3\n4 5 6" + test = np.genfromtxt(TextIO(data), + names="a, b, c", usecols="a, c") + ctrl = np.array([(1, 3), (4, 6)], dtype=[(_, float) for _ in "ac"]) + assert_equal(test, ctrl) + + def test_usecols_with_structured_dtype(self): + # Test usecols with an explicit structured dtype + data = TextIO("JOE 70.1 25.3\nBOB 60.5 27.9") + names = ['stid', 'temp'] + dtypes = ['S4', 'f8'] + test = np.genfromtxt( + data, usecols=(0, 2), dtype=list(zip(names, dtypes))) + assert_equal(test['stid'], [b"JOE", b"BOB"]) + assert_equal(test['temp'], [25.3, 27.9]) + + def test_usecols_with_integer(self): + # Test usecols with an integer + test = np.genfromtxt(TextIO(b"1 2 3\n4 5 6"), usecols=0) + assert_equal(test, np.array([1., 4.])) + + def test_usecols_with_named_columns(self): + # Test usecols with named columns + ctrl = np.array([(1, 3), (4, 6)], dtype=[('a', float), ('c', float)]) + data = "1 2 3\n4 5 6" + kwargs = dict(names="a, b, c") + test = np.genfromtxt(TextIO(data), usecols=(0, -1), **kwargs) + assert_equal(test, ctrl) + test = np.genfromtxt(TextIO(data), + usecols=('a', 'c'), **kwargs) + assert_equal(test, ctrl) + + def test_empty_file(self): + # Test that an empty file raises the proper warning. + with suppress_warnings() as sup: + sup.filter(message="genfromtxt: Empty input file:") + data = TextIO() + test = np.genfromtxt(data) + assert_equal(test, np.array([])) + + # when skip_header > 0 + test = np.genfromtxt(data, skip_header=1) + assert_equal(test, np.array([])) + + def test_fancy_dtype_alt(self): + # Check that a nested dtype isn't MIA + data = TextIO('1,2,3.0\n4,5,6.0\n') + fancydtype = np.dtype([('x', int), ('y', [('t', int), ('s', float)])]) + test = np.genfromtxt(data, dtype=fancydtype, delimiter=',', usemask=True) + control = ma.array([(1, (2, 3.0)), (4, (5, 6.0))], dtype=fancydtype) + assert_equal(test, control) + + def test_shaped_dtype(self): + c = TextIO("aaaa 1.0 8.0 1 2 3 4 5 6") + dt = np.dtype([('name', 'S4'), ('x', float), ('y', float), + ('block', int, (2, 3))]) + x = np.genfromtxt(c, dtype=dt) + a = np.array([('aaaa', 1.0, 8.0, [[1, 2, 3], [4, 5, 6]])], + dtype=dt) + assert_array_equal(x, a) + + def test_withmissing(self): + data = TextIO('A,B\n0,1\n2,N/A') + kwargs = dict(delimiter=",", missing_values="N/A", names=True) + test = np.genfromtxt(data, dtype=None, usemask=True, **kwargs) + control = ma.array([(0, 1), (2, -1)], + mask=[(False, False), (False, True)], + dtype=[('A', int), ('B', int)]) + assert_equal(test, control) + assert_equal(test.mask, control.mask) + # + data.seek(0) + test = np.genfromtxt(data, usemask=True, **kwargs) + control = ma.array([(0, 1), (2, -1)], + mask=[(False, False), (False, True)], + dtype=[('A', float), ('B', float)]) + assert_equal(test, control) + assert_equal(test.mask, control.mask) + + def test_user_missing_values(self): + data = "A, B, C\n0, 0., 0j\n1, N/A, 1j\n-9, 2.2, N/A\n3, -99, 3j" + basekwargs = dict(dtype=None, delimiter=",", names=True,) + mdtype = [('A', int), ('B', float), ('C', complex)] + # + test = np.genfromtxt(TextIO(data), missing_values="N/A", + **basekwargs) + control = ma.array([(0, 0.0, 0j), (1, -999, 1j), + (-9, 2.2, -999j), (3, -99, 3j)], + mask=[(0, 0, 0), (0, 1, 0), (0, 0, 1), (0, 0, 0)], + dtype=mdtype) + assert_equal(test, control) + # + basekwargs['dtype'] = mdtype + test = np.genfromtxt(TextIO(data), + missing_values={0: -9, 1: -99, 2: -999j}, usemask=True, **basekwargs) + control = ma.array([(0, 0.0, 0j), (1, -999, 1j), + (-9, 2.2, -999j), (3, -99, 3j)], + mask=[(0, 0, 0), (0, 1, 0), (1, 0, 1), (0, 1, 0)], + dtype=mdtype) + assert_equal(test, control) + # + test = np.genfromtxt(TextIO(data), + missing_values={0: -9, 'B': -99, 'C': -999j}, + usemask=True, + **basekwargs) + control = ma.array([(0, 0.0, 0j), (1, -999, 1j), + (-9, 2.2, -999j), (3, -99, 3j)], + mask=[(0, 0, 0), (0, 1, 0), (1, 0, 1), (0, 1, 0)], + dtype=mdtype) + assert_equal(test, control) + + def test_user_filling_values(self): + # Test with missing and filling values + ctrl = np.array([(0, 3), (4, -999)], dtype=[('a', int), ('b', int)]) + data = "N/A, 2, 3\n4, ,???" + kwargs = dict(delimiter=",", + dtype=int, + names="a,b,c", + missing_values={0: "N/A", 'b': " ", 2: "???"}, + filling_values={0: 0, 'b': 0, 2: -999}) + test = np.genfromtxt(TextIO(data), **kwargs) + ctrl = np.array([(0, 2, 3), (4, 0, -999)], + dtype=[(_, int) for _ in "abc"]) + assert_equal(test, ctrl) + # + test = np.genfromtxt(TextIO(data), usecols=(0, -1), **kwargs) + ctrl = np.array([(0, 3), (4, -999)], dtype=[(_, int) for _ in "ac"]) + assert_equal(test, ctrl) + + data2 = "1,2,*,4\n5,*,7,8\n" + test = np.genfromtxt(TextIO(data2), delimiter=',', dtype=int, + missing_values="*", filling_values=0) + ctrl = np.array([[1, 2, 0, 4], [5, 0, 7, 8]]) + assert_equal(test, ctrl) + test = np.genfromtxt(TextIO(data2), delimiter=',', dtype=int, + missing_values="*", filling_values=-1) + ctrl = np.array([[1, 2, -1, 4], [5, -1, 7, 8]]) + assert_equal(test, ctrl) + + def test_withmissing_float(self): + data = TextIO('A,B\n0,1.5\n2,-999.00') + test = np.genfromtxt(data, dtype=None, delimiter=',', + missing_values='-999.0', names=True, usemask=True) + control = ma.array([(0, 1.5), (2, -1.)], + mask=[(False, False), (False, True)], + dtype=[('A', int), ('B', float)]) + assert_equal(test, control) + assert_equal(test.mask, control.mask) + + def test_with_masked_column_uniform(self): + # Test masked column + data = TextIO('1 2 3\n4 5 6\n') + test = np.genfromtxt(data, dtype=None, + missing_values='2,5', usemask=True) + control = ma.array([[1, 2, 3], [4, 5, 6]], mask=[[0, 1, 0], [0, 1, 0]]) + assert_equal(test, control) + + def test_with_masked_column_various(self): + # Test masked column + data = TextIO('True 2 3\nFalse 5 6\n') + test = np.genfromtxt(data, dtype=None, + missing_values='2,5', usemask=True) + control = ma.array([(1, 2, 3), (0, 5, 6)], + mask=[(0, 1, 0), (0, 1, 0)], + dtype=[('f0', bool), ('f1', bool), ('f2', int)]) + assert_equal(test, control) + + def test_invalid_raise(self): + # Test invalid raise + data = ["1, 1, 1, 1, 1"] * 50 + for i in range(5): + data[10 * i] = "2, 2, 2, 2 2" + data.insert(0, "a, b, c, d, e") + mdata = TextIO("\n".join(data)) + + kwargs = dict(delimiter=",", dtype=None, names=True) + def f(): + return np.genfromtxt(mdata, invalid_raise=False, **kwargs) + mtest = assert_warns(ConversionWarning, f) + assert_equal(len(mtest), 45) + assert_equal(mtest, np.ones(45, dtype=[(_, int) for _ in 'abcde'])) + # + mdata.seek(0) + assert_raises(ValueError, np.genfromtxt, mdata, + delimiter=",", names=True) + + def test_invalid_raise_with_usecols(self): + # Test invalid_raise with usecols + data = ["1, 1, 1, 1, 1"] * 50 + for i in range(5): + data[10 * i] = "2, 2, 2, 2 2" + data.insert(0, "a, b, c, d, e") + mdata = TextIO("\n".join(data)) + + kwargs = dict(delimiter=",", dtype=None, names=True, + invalid_raise=False) + def f(): + return np.genfromtxt(mdata, usecols=(0, 4), **kwargs) + mtest = assert_warns(ConversionWarning, f) + assert_equal(len(mtest), 45) + assert_equal(mtest, np.ones(45, dtype=[(_, int) for _ in 'ae'])) + # + mdata.seek(0) + mtest = np.genfromtxt(mdata, usecols=(0, 1), **kwargs) + assert_equal(len(mtest), 50) + control = np.ones(50, dtype=[(_, int) for _ in 'ab']) + control[[10 * _ for _ in range(5)]] = (2, 2) + assert_equal(mtest, control) + + def test_inconsistent_dtype(self): + # Test inconsistent dtype + data = ["1, 1, 1, 1, -1.1"] * 50 + mdata = TextIO("\n".join(data)) + + converters = {4: lambda x: "(%s)" % x.decode()} + kwargs = dict(delimiter=",", converters=converters, + dtype=[(_, int) for _ in 'abcde'],) + assert_raises(ValueError, np.genfromtxt, mdata, **kwargs) + + def test_default_field_format(self): + # Test default format + data = "0, 1, 2.3\n4, 5, 6.7" + mtest = np.genfromtxt(TextIO(data), + delimiter=",", dtype=None, defaultfmt="f%02i") + ctrl = np.array([(0, 1, 2.3), (4, 5, 6.7)], + dtype=[("f00", int), ("f01", int), ("f02", float)]) + assert_equal(mtest, ctrl) + + def test_single_dtype_wo_names(self): + # Test single dtype w/o names + data = "0, 1, 2.3\n4, 5, 6.7" + mtest = np.genfromtxt(TextIO(data), + delimiter=",", dtype=float, defaultfmt="f%02i") + ctrl = np.array([[0., 1., 2.3], [4., 5., 6.7]], dtype=float) + assert_equal(mtest, ctrl) + + def test_single_dtype_w_explicit_names(self): + # Test single dtype w explicit names + data = "0, 1, 2.3\n4, 5, 6.7" + mtest = np.genfromtxt(TextIO(data), + delimiter=",", dtype=float, names="a, b, c") + ctrl = np.array([(0., 1., 2.3), (4., 5., 6.7)], + dtype=[(_, float) for _ in "abc"]) + assert_equal(mtest, ctrl) + + def test_single_dtype_w_implicit_names(self): + # Test single dtype w implicit names + data = "a, b, c\n0, 1, 2.3\n4, 5, 6.7" + mtest = np.genfromtxt(TextIO(data), + delimiter=",", dtype=float, names=True) + ctrl = np.array([(0., 1., 2.3), (4., 5., 6.7)], + dtype=[(_, float) for _ in "abc"]) + assert_equal(mtest, ctrl) + + def test_easy_structured_dtype(self): + # Test easy structured dtype + data = "0, 1, 2.3\n4, 5, 6.7" + mtest = np.genfromtxt(TextIO(data), delimiter=",", + dtype=(int, float, float), defaultfmt="f_%02i") + ctrl = np.array([(0, 1., 2.3), (4, 5., 6.7)], + dtype=[("f_00", int), ("f_01", float), ("f_02", float)]) + assert_equal(mtest, ctrl) + + def test_autostrip(self): + # Test autostrip + data = "01/01/2003 , 1.3, abcde" + kwargs = dict(delimiter=",", dtype=None) + with warnings.catch_warnings(record=True) as w: + warnings.filterwarnings('always', '', np.VisibleDeprecationWarning) + mtest = np.genfromtxt(TextIO(data), **kwargs) + assert_(w[0].category is np.VisibleDeprecationWarning) + ctrl = np.array([('01/01/2003 ', 1.3, ' abcde')], + dtype=[('f0', '|S12'), ('f1', float), ('f2', '|S8')]) + assert_equal(mtest, ctrl) + with warnings.catch_warnings(record=True) as w: + warnings.filterwarnings('always', '', np.VisibleDeprecationWarning) + mtest = np.genfromtxt(TextIO(data), autostrip=True, **kwargs) + assert_(w[0].category is np.VisibleDeprecationWarning) + ctrl = np.array([('01/01/2003', 1.3, 'abcde')], + dtype=[('f0', '|S10'), ('f1', float), ('f2', '|S5')]) + assert_equal(mtest, ctrl) + + def test_replace_space(self): + # Test the 'replace_space' option + txt = "A.A, B (B), C:C\n1, 2, 3.14" + # Test default: replace ' ' by '_' and delete non-alphanum chars + test = np.genfromtxt(TextIO(txt), + delimiter=",", names=True, dtype=None) + ctrl_dtype = [("AA", int), ("B_B", int), ("CC", float)] + ctrl = np.array((1, 2, 3.14), dtype=ctrl_dtype) + assert_equal(test, ctrl) + # Test: no replace, no delete + test = np.genfromtxt(TextIO(txt), + delimiter=",", names=True, dtype=None, + replace_space='', deletechars='') + ctrl_dtype = [("A.A", int), ("B (B)", int), ("C:C", float)] + ctrl = np.array((1, 2, 3.14), dtype=ctrl_dtype) + assert_equal(test, ctrl) + # Test: no delete (spaces are replaced by _) + test = np.genfromtxt(TextIO(txt), + delimiter=",", names=True, dtype=None, + deletechars='') + ctrl_dtype = [("A.A", int), ("B_(B)", int), ("C:C", float)] + ctrl = np.array((1, 2, 3.14), dtype=ctrl_dtype) + assert_equal(test, ctrl) + + def test_replace_space_known_dtype(self): + # Test the 'replace_space' (and related) options when dtype != None + txt = "A.A, B (B), C:C\n1, 2, 3" + # Test default: replace ' ' by '_' and delete non-alphanum chars + test = np.genfromtxt(TextIO(txt), + delimiter=",", names=True, dtype=int) + ctrl_dtype = [("AA", int), ("B_B", int), ("CC", int)] + ctrl = np.array((1, 2, 3), dtype=ctrl_dtype) + assert_equal(test, ctrl) + # Test: no replace, no delete + test = np.genfromtxt(TextIO(txt), + delimiter=",", names=True, dtype=int, + replace_space='', deletechars='') + ctrl_dtype = [("A.A", int), ("B (B)", int), ("C:C", int)] + ctrl = np.array((1, 2, 3), dtype=ctrl_dtype) + assert_equal(test, ctrl) + # Test: no delete (spaces are replaced by _) + test = np.genfromtxt(TextIO(txt), + delimiter=",", names=True, dtype=int, + deletechars='') + ctrl_dtype = [("A.A", int), ("B_(B)", int), ("C:C", int)] + ctrl = np.array((1, 2, 3), dtype=ctrl_dtype) + assert_equal(test, ctrl) + + def test_incomplete_names(self): + # Test w/ incomplete names + data = "A,,C\n0,1,2\n3,4,5" + kwargs = dict(delimiter=",", names=True) + # w/ dtype=None + ctrl = np.array([(0, 1, 2), (3, 4, 5)], + dtype=[(_, int) for _ in ('A', 'f0', 'C')]) + test = np.genfromtxt(TextIO(data), dtype=None, **kwargs) + assert_equal(test, ctrl) + # w/ default dtype + ctrl = np.array([(0, 1, 2), (3, 4, 5)], + dtype=[(_, float) for _ in ('A', 'f0', 'C')]) + test = np.genfromtxt(TextIO(data), **kwargs) + + def test_names_auto_completion(self): + # Make sure that names are properly completed + data = "1 2 3\n 4 5 6" + test = np.genfromtxt(TextIO(data), + dtype=(int, float, int), names="a") + ctrl = np.array([(1, 2, 3), (4, 5, 6)], + dtype=[('a', int), ('f0', float), ('f1', int)]) + assert_equal(test, ctrl) + + def test_names_with_usecols_bug1636(self): + # Make sure we pick up the right names w/ usecols + data = "A,B,C,D,E\n0,1,2,3,4\n0,1,2,3,4\n0,1,2,3,4" + ctrl_names = ("A", "C", "E") + test = np.genfromtxt(TextIO(data), + dtype=(int, int, int), delimiter=",", + usecols=(0, 2, 4), names=True) + assert_equal(test.dtype.names, ctrl_names) + # + test = np.genfromtxt(TextIO(data), + dtype=(int, int, int), delimiter=",", + usecols=("A", "C", "E"), names=True) + assert_equal(test.dtype.names, ctrl_names) + # + test = np.genfromtxt(TextIO(data), + dtype=int, delimiter=",", + usecols=("A", "C", "E"), names=True) + assert_equal(test.dtype.names, ctrl_names) + + def test_fixed_width_names(self): + # Test fix-width w/ names + data = " A B C\n 0 1 2.3\n 45 67 9." + kwargs = dict(delimiter=(5, 5, 4), names=True, dtype=None) + ctrl = np.array([(0, 1, 2.3), (45, 67, 9.)], + dtype=[('A', int), ('B', int), ('C', float)]) + test = np.genfromtxt(TextIO(data), **kwargs) + assert_equal(test, ctrl) + # + kwargs = dict(delimiter=5, names=True, dtype=None) + ctrl = np.array([(0, 1, 2.3), (45, 67, 9.)], + dtype=[('A', int), ('B', int), ('C', float)]) + test = np.genfromtxt(TextIO(data), **kwargs) + assert_equal(test, ctrl) + + def test_filling_values(self): + # Test missing values + data = b"1, 2, 3\n1, , 5\n0, 6, \n" + kwargs = dict(delimiter=",", dtype=None, filling_values=-999) + ctrl = np.array([[1, 2, 3], [1, -999, 5], [0, 6, -999]], dtype=int) + test = np.genfromtxt(TextIO(data), **kwargs) + assert_equal(test, ctrl) + + def test_comments_is_none(self): + # Github issue 329 (None was previously being converted to 'None'). + with warnings.catch_warnings(record=True) as w: + warnings.filterwarnings('always', '', np.VisibleDeprecationWarning) + test = np.genfromtxt(TextIO("test1,testNonetherestofthedata"), + dtype=None, comments=None, delimiter=',') + assert_(w[0].category is np.VisibleDeprecationWarning) + assert_equal(test[1], b'testNonetherestofthedata') + with warnings.catch_warnings(record=True) as w: + warnings.filterwarnings('always', '', np.VisibleDeprecationWarning) + test = np.genfromtxt(TextIO("test1, testNonetherestofthedata"), + dtype=None, comments=None, delimiter=',') + assert_(w[0].category is np.VisibleDeprecationWarning) + assert_equal(test[1], b' testNonetherestofthedata') + + def test_latin1(self): + latin1 = b'\xf6\xfc\xf6' + norm = b"norm1,norm2,norm3\n" + enc = b"test1,testNonethe" + latin1 + b",test3\n" + s = norm + enc + norm + with warnings.catch_warnings(record=True) as w: + warnings.filterwarnings('always', '', np.VisibleDeprecationWarning) + test = np.genfromtxt(TextIO(s), + dtype=None, comments=None, delimiter=',') + assert_(w[0].category is np.VisibleDeprecationWarning) + assert_equal(test[1, 0], b"test1") + assert_equal(test[1, 1], b"testNonethe" + latin1) + assert_equal(test[1, 2], b"test3") + test = np.genfromtxt(TextIO(s), + dtype=None, comments=None, delimiter=',', + encoding='latin1') + assert_equal(test[1, 0], u"test1") + assert_equal(test[1, 1], u"testNonethe" + latin1.decode('latin1')) + assert_equal(test[1, 2], u"test3") + + with warnings.catch_warnings(record=True) as w: + warnings.filterwarnings('always', '', np.VisibleDeprecationWarning) + test = np.genfromtxt(TextIO(b"0,testNonethe" + latin1), + dtype=None, comments=None, delimiter=',') + assert_(w[0].category is np.VisibleDeprecationWarning) + assert_equal(test['f0'], 0) + assert_equal(test['f1'], b"testNonethe" + latin1) + + def test_binary_decode_autodtype(self): + utf16 = b'\xff\xfeh\x04 \x00i\x04 \x00j\x04' + v = self.loadfunc(BytesIO(utf16), dtype=None, encoding='UTF-16') + assert_array_equal(v, np.array(utf16.decode('UTF-16').split())) + + def test_utf8_byte_encoding(self): + utf8 = b"\xcf\x96" + norm = b"norm1,norm2,norm3\n" + enc = b"test1,testNonethe" + utf8 + b",test3\n" + s = norm + enc + norm + with warnings.catch_warnings(record=True) as w: + warnings.filterwarnings('always', '', np.VisibleDeprecationWarning) + test = np.genfromtxt(TextIO(s), + dtype=None, comments=None, delimiter=',') + assert_(w[0].category is np.VisibleDeprecationWarning) + ctl = np.array([ + [b'norm1', b'norm2', b'norm3'], + [b'test1', b'testNonethe' + utf8, b'test3'], + [b'norm1', b'norm2', b'norm3']]) + assert_array_equal(test, ctl) + + def test_utf8_file(self): + utf8 = b"\xcf\x96" + with temppath() as path: + with open(path, "wb") as f: + f.write((b"test1,testNonethe" + utf8 + b",test3\n") * 2) + test = np.genfromtxt(path, dtype=None, comments=None, + delimiter=',', encoding="UTF-8") + ctl = np.array([ + ["test1", "testNonethe" + utf8.decode("UTF-8"), "test3"], + ["test1", "testNonethe" + utf8.decode("UTF-8"), "test3"]], + dtype=np.unicode_) + assert_array_equal(test, ctl) + + # test a mixed dtype + with open(path, "wb") as f: + f.write(b"0,testNonethe" + utf8) + test = np.genfromtxt(path, dtype=None, comments=None, + delimiter=',', encoding="UTF-8") + assert_equal(test['f0'], 0) + assert_equal(test['f1'], "testNonethe" + utf8.decode("UTF-8")) + + def test_utf8_file_nodtype_unicode(self): + # bytes encoding with non-latin1 -> unicode upcast + utf8 = u'\u03d6' + latin1 = u'\xf6\xfc\xf6' + + # skip test if cannot encode utf8 test string with preferred + # encoding. The preferred encoding is assumed to be the default + # encoding of io.open. Will need to change this for PyTest, maybe + # using pytest.mark.xfail(raises=***). + try: + encoding = locale.getpreferredencoding() + utf8.encode(encoding) + except (UnicodeError, ImportError): + pytest.skip('Skipping test_utf8_file_nodtype_unicode, ' + 'unable to encode utf8 in preferred encoding') + + with temppath() as path: + with io.open(path, "wt") as f: + f.write(u"norm1,norm2,norm3\n") + f.write(u"norm1," + latin1 + u",norm3\n") + f.write(u"test1,testNonethe" + utf8 + u",test3\n") + with warnings.catch_warnings(record=True) as w: + warnings.filterwarnings('always', '', + np.VisibleDeprecationWarning) + test = np.genfromtxt(path, dtype=None, comments=None, + delimiter=',') + # Check for warning when encoding not specified. + assert_(w[0].category is np.VisibleDeprecationWarning) + ctl = np.array([ + ["norm1", "norm2", "norm3"], + ["norm1", latin1, "norm3"], + ["test1", "testNonethe" + utf8, "test3"]], + dtype=np.unicode_) + assert_array_equal(test, ctl) + + def test_recfromtxt(self): + # + data = TextIO('A,B\n0,1\n2,3') + kwargs = dict(delimiter=",", missing_values="N/A", names=True) + test = np.recfromtxt(data, **kwargs) + control = np.array([(0, 1), (2, 3)], + dtype=[('A', int), ('B', int)]) + assert_(isinstance(test, np.recarray)) + assert_equal(test, control) + # + data = TextIO('A,B\n0,1\n2,N/A') + test = np.recfromtxt(data, dtype=None, usemask=True, **kwargs) + control = ma.array([(0, 1), (2, -1)], + mask=[(False, False), (False, True)], + dtype=[('A', int), ('B', int)]) + assert_equal(test, control) + assert_equal(test.mask, control.mask) + assert_equal(test.A, [0, 2]) + + def test_recfromcsv(self): + # + data = TextIO('A,B\n0,1\n2,3') + kwargs = dict(missing_values="N/A", names=True, case_sensitive=True) + test = np.recfromcsv(data, dtype=None, **kwargs) + control = np.array([(0, 1), (2, 3)], + dtype=[('A', int), ('B', int)]) + assert_(isinstance(test, np.recarray)) + assert_equal(test, control) + # + data = TextIO('A,B\n0,1\n2,N/A') + test = np.recfromcsv(data, dtype=None, usemask=True, **kwargs) + control = ma.array([(0, 1), (2, -1)], + mask=[(False, False), (False, True)], + dtype=[('A', int), ('B', int)]) + assert_equal(test, control) + assert_equal(test.mask, control.mask) + assert_equal(test.A, [0, 2]) + # + data = TextIO('A,B\n0,1\n2,3') + test = np.recfromcsv(data, missing_values='N/A',) + control = np.array([(0, 1), (2, 3)], + dtype=[('a', int), ('b', int)]) + assert_(isinstance(test, np.recarray)) + assert_equal(test, control) + # + data = TextIO('A,B\n0,1\n2,3') + dtype = [('a', int), ('b', float)] + test = np.recfromcsv(data, missing_values='N/A', dtype=dtype) + control = np.array([(0, 1), (2, 3)], + dtype=dtype) + assert_(isinstance(test, np.recarray)) + assert_equal(test, control) + + #gh-10394 + data = TextIO('color\n"red"\n"blue"') + test = np.recfromcsv(data, converters={0: lambda x: x.strip(b'\"')}) + control = np.array([('red',), ('blue',)], dtype=[('color', (bytes, 4))]) + assert_equal(test.dtype, control.dtype) + assert_equal(test, control) + + def test_max_rows(self): + # Test the `max_rows` keyword argument. + data = '1 2\n3 4\n5 6\n7 8\n9 10\n' + txt = TextIO(data) + a1 = np.genfromtxt(txt, max_rows=3) + a2 = np.genfromtxt(txt) + assert_equal(a1, [[1, 2], [3, 4], [5, 6]]) + assert_equal(a2, [[7, 8], [9, 10]]) + + # max_rows must be at least 1. + assert_raises(ValueError, np.genfromtxt, TextIO(data), max_rows=0) + + # An input with several invalid rows. + data = '1 1\n2 2\n0 \n3 3\n4 4\n5 \n6 \n7 \n' + + test = np.genfromtxt(TextIO(data), max_rows=2) + control = np.array([[1., 1.], [2., 2.]]) + assert_equal(test, control) + + # Test keywords conflict + assert_raises(ValueError, np.genfromtxt, TextIO(data), skip_footer=1, + max_rows=4) + + # Test with invalid value + assert_raises(ValueError, np.genfromtxt, TextIO(data), max_rows=4) + + # Test with invalid not raise + with suppress_warnings() as sup: + sup.filter(ConversionWarning) + + test = np.genfromtxt(TextIO(data), max_rows=4, invalid_raise=False) + control = np.array([[1., 1.], [2., 2.], [3., 3.], [4., 4.]]) + assert_equal(test, control) + + test = np.genfromtxt(TextIO(data), max_rows=5, invalid_raise=False) + control = np.array([[1., 1.], [2., 2.], [3., 3.], [4., 4.]]) + assert_equal(test, control) + + # Structured array with field names. + data = 'a b\n#c d\n1 1\n2 2\n#0 \n3 3\n4 4\n5 5\n' + + # Test with header, names and comments + txt = TextIO(data) + test = np.genfromtxt(txt, skip_header=1, max_rows=3, names=True) + control = np.array([(1.0, 1.0), (2.0, 2.0), (3.0, 3.0)], + dtype=[('c', ' should convert to float + # 2**34 = 17179869184 => should convert to int64 + # 2**10 = 1024 => should convert to int (int32 on 32-bit systems, + # int64 on 64-bit systems) + + data = TextIO('73786976294838206464 17179869184 1024') + + test = np.genfromtxt(data, dtype=None) + + assert_equal(test.dtype.names, ['f0', 'f1', 'f2']) + + assert_(test.dtype['f0'] == float) + assert_(test.dtype['f1'] == np.int64) + assert_(test.dtype['f2'] == np.int_) + + assert_allclose(test['f0'], 73786976294838206464.) + assert_equal(test['f1'], 17179869184) + assert_equal(test['f2'], 1024) + + def test_unpack_structured(self): + # Regression test for gh-4341 + # Unpacking should work on structured arrays + txt = TextIO("M 21 72\nF 35 58") + dt = {'names': ('a', 'b', 'c'), 'formats': ('S1', 'i4', 'f4')} + a, b, c = np.genfromtxt(txt, dtype=dt, unpack=True) + assert_equal(a.dtype, np.dtype('S1')) + assert_equal(b.dtype, np.dtype('i4')) + assert_equal(c.dtype, np.dtype('f4')) + assert_array_equal(a, np.array([b'M', b'F'])) + assert_array_equal(b, np.array([21, 35])) + assert_array_equal(c, np.array([72., 58.])) + + def test_unpack_auto_dtype(self): + # Regression test for gh-4341 + # Unpacking should work when dtype=None + txt = TextIO("M 21 72.\nF 35 58.") + expected = (np.array(["M", "F"]), np.array([21, 35]), np.array([72., 58.])) + test = np.genfromtxt(txt, dtype=None, unpack=True, encoding="utf-8") + for arr, result in zip(expected, test): + assert_array_equal(arr, result) + assert_equal(arr.dtype, result.dtype) + + def test_unpack_single_name(self): + # Regression test for gh-4341 + # Unpacking should work when structured dtype has only one field + txt = TextIO("21\n35") + dt = {'names': ('a',), 'formats': ('i4',)} + expected = np.array([21, 35], dtype=np.int32) + test = np.genfromtxt(txt, dtype=dt, unpack=True) + assert_array_equal(expected, test) + assert_equal(expected.dtype, test.dtype) + + def test_squeeze_scalar(self): + # Regression test for gh-4341 + # Unpacking a scalar should give zero-dim output, + # even if dtype is structured + txt = TextIO("1") + dt = {'names': ('a',), 'formats': ('i4',)} + expected = np.array((1,), dtype=np.int32) + test = np.genfromtxt(txt, dtype=dt, unpack=True) + assert_array_equal(expected, test) + assert_equal((), test.shape) + assert_equal(expected.dtype, test.dtype) + + +class TestPathUsage: + # Test that pathlib.Path can be used + def test_loadtxt(self): + with temppath(suffix='.txt') as path: + path = Path(path) + a = np.array([[1.1, 2], [3, 4]]) + np.savetxt(path, a) + x = np.loadtxt(path) + assert_array_equal(x, a) + + def test_save_load(self): + # Test that pathlib.Path instances can be used with save. + with temppath(suffix='.npy') as path: + path = Path(path) + a = np.array([[1, 2], [3, 4]], int) + np.save(path, a) + data = np.load(path) + assert_array_equal(data, a) + + def test_save_load_memmap(self): + # Test that pathlib.Path instances can be loaded mem-mapped. + with temppath(suffix='.npy') as path: + path = Path(path) + a = np.array([[1, 2], [3, 4]], int) + np.save(path, a) + data = np.load(path, mmap_mode='r') + assert_array_equal(data, a) + # close the mem-mapped file + del data + if IS_PYPY: + break_cycles() + break_cycles() + + def test_save_load_memmap_readwrite(self): + # Test that pathlib.Path instances can be written mem-mapped. + with temppath(suffix='.npy') as path: + path = Path(path) + a = np.array([[1, 2], [3, 4]], int) + np.save(path, a) + b = np.load(path, mmap_mode='r+') + a[0][0] = 5 + b[0][0] = 5 + del b # closes the file + if IS_PYPY: + break_cycles() + break_cycles() + data = np.load(path) + assert_array_equal(data, a) + + def test_savez_load(self): + # Test that pathlib.Path instances can be used with savez. + with temppath(suffix='.npz') as path: + path = Path(path) + np.savez(path, lab='place holder') + with np.load(path) as data: + assert_array_equal(data['lab'], 'place holder') + + def test_savez_compressed_load(self): + # Test that pathlib.Path instances can be used with savez. + with temppath(suffix='.npz') as path: + path = Path(path) + np.savez_compressed(path, lab='place holder') + data = np.load(path) + assert_array_equal(data['lab'], 'place holder') + data.close() + + def test_genfromtxt(self): + with temppath(suffix='.txt') as path: + path = Path(path) + a = np.array([(1, 2), (3, 4)]) + np.savetxt(path, a) + data = np.genfromtxt(path) + assert_array_equal(a, data) + + def test_ndfromtxt(self): + # Test outputting a standard ndarray + with temppath(suffix='.txt') as path: + path = Path(path) + with path.open('w') as f: + f.write(u'1 2\n3 4') + + control = np.array([[1, 2], [3, 4]], dtype=int) + test = np.genfromtxt(path, dtype=int) + assert_array_equal(test, control) + + def test_mafromtxt(self): + # From `test_fancy_dtype_alt` above + with temppath(suffix='.txt') as path: + path = Path(path) + with path.open('w') as f: + f.write(u'1,2,3.0\n4,5,6.0\n') + + test = np.genfromtxt(path, delimiter=',', usemask=True) + control = ma.array([(1.0, 2.0, 3.0), (4.0, 5.0, 6.0)]) + assert_equal(test, control) + + def test_recfromtxt(self): + with temppath(suffix='.txt') as path: + path = Path(path) + with path.open('w') as f: + f.write(u'A,B\n0,1\n2,3') + + kwargs = dict(delimiter=",", missing_values="N/A", names=True) + test = np.recfromtxt(path, **kwargs) + control = np.array([(0, 1), (2, 3)], + dtype=[('A', int), ('B', int)]) + assert_(isinstance(test, np.recarray)) + assert_equal(test, control) + + def test_recfromcsv(self): + with temppath(suffix='.txt') as path: + path = Path(path) + with path.open('w') as f: + f.write(u'A,B\n0,1\n2,3') + + kwargs = dict(missing_values="N/A", names=True, case_sensitive=True) + test = np.recfromcsv(path, dtype=None, **kwargs) + control = np.array([(0, 1), (2, 3)], + dtype=[('A', int), ('B', int)]) + assert_(isinstance(test, np.recarray)) + assert_equal(test, control) + + +def test_gzip_load(): + a = np.random.random((5, 5)) + + s = BytesIO() + f = gzip.GzipFile(fileobj=s, mode="w") + + np.save(f, a) + f.close() + s.seek(0) + + f = gzip.GzipFile(fileobj=s, mode="r") + assert_array_equal(np.load(f), a) + + +# These next two classes encode the minimal API needed to save()/load() arrays. +# The `test_ducktyping` ensures they work correctly +class JustWriter: + def __init__(self, base): + self.base = base + + def write(self, s): + return self.base.write(s) + + def flush(self): + return self.base.flush() + +class JustReader: + def __init__(self, base): + self.base = base + + def read(self, n): + return self.base.read(n) + + def seek(self, off, whence=0): + return self.base.seek(off, whence) + + +def test_ducktyping(): + a = np.random.random((5, 5)) + + s = BytesIO() + f = JustWriter(s) + + np.save(f, a) + f.flush() + s.seek(0) + + f = JustReader(s) + assert_array_equal(np.load(f), a) + + + +def test_gzip_loadtxt(): + # Thanks to another windows brokenness, we can't use + # NamedTemporaryFile: a file created from this function cannot be + # reopened by another open call. So we first put the gzipped string + # of the test reference array, write it to a securely opened file, + # which is then read from by the loadtxt function + s = BytesIO() + g = gzip.GzipFile(fileobj=s, mode='w') + g.write(b'1 2 3\n') + g.close() + + s.seek(0) + with temppath(suffix='.gz') as name: + with open(name, 'wb') as f: + f.write(s.read()) + res = np.loadtxt(name) + s.close() + + assert_array_equal(res, [1, 2, 3]) + + +def test_gzip_loadtxt_from_string(): + s = BytesIO() + f = gzip.GzipFile(fileobj=s, mode="w") + f.write(b'1 2 3\n') + f.close() + s.seek(0) + + f = gzip.GzipFile(fileobj=s, mode="r") + assert_array_equal(np.loadtxt(f), [1, 2, 3]) + + +def test_npzfile_dict(): + s = BytesIO() + x = np.zeros((3, 3)) + y = np.zeros((3, 3)) + + np.savez(s, x=x, y=y) + s.seek(0) + + z = np.load(s) + + assert_('x' in z) + assert_('y' in z) + assert_('x' in z.keys()) + assert_('y' in z.keys()) + + for f, a in z.items(): + assert_(f in ['x', 'y']) + assert_equal(a.shape, (3, 3)) + + assert_(len(z.items()) == 2) + + for f in z: + assert_(f in ['x', 'y']) + + assert_('x' in z.keys()) + + +@pytest.mark.skipif(not HAS_REFCOUNT, reason="Python lacks refcounts") +def test_load_refcount(): + # Check that objects returned by np.load are directly freed based on + # their refcount, rather than needing the gc to collect them. + + f = BytesIO() + np.savez(f, [1, 2, 3]) + f.seek(0) + + with assert_no_gc_cycles(): + np.load(f) + + f.seek(0) + dt = [("a", 'u1', 2), ("b", 'u1', 2)] + with assert_no_gc_cycles(): + x = np.loadtxt(TextIO("0 1 2 3"), dtype=dt) + assert_equal(x, np.array([((0, 1), (2, 3))], dtype=dt)) diff --git a/venv/Lib/site-packages/numpy/lib/tests/test_mixins.py b/venv/Lib/site-packages/numpy/lib/tests/test_mixins.py new file mode 100644 index 0000000..6320587 --- /dev/null +++ b/venv/Lib/site-packages/numpy/lib/tests/test_mixins.py @@ -0,0 +1,216 @@ +import numbers +import operator + +import numpy as np +from numpy.testing import assert_, assert_equal, assert_raises + + +# NOTE: This class should be kept as an exact copy of the example from the +# docstring for NDArrayOperatorsMixin. + +class ArrayLike(np.lib.mixins.NDArrayOperatorsMixin): + def __init__(self, value): + self.value = np.asarray(value) + + # One might also consider adding the built-in list type to this + # list, to support operations like np.add(array_like, list) + _HANDLED_TYPES = (np.ndarray, numbers.Number) + + def __array_ufunc__(self, ufunc, method, *inputs, **kwargs): + out = kwargs.get('out', ()) + for x in inputs + out: + # Only support operations with instances of _HANDLED_TYPES. + # Use ArrayLike instead of type(self) for isinstance to + # allow subclasses that don't override __array_ufunc__ to + # handle ArrayLike objects. + if not isinstance(x, self._HANDLED_TYPES + (ArrayLike,)): + return NotImplemented + + # Defer to the implementation of the ufunc on unwrapped values. + inputs = tuple(x.value if isinstance(x, ArrayLike) else x + for x in inputs) + if out: + kwargs['out'] = tuple( + x.value if isinstance(x, ArrayLike) else x + for x in out) + result = getattr(ufunc, method)(*inputs, **kwargs) + + if type(result) is tuple: + # multiple return values + return tuple(type(self)(x) for x in result) + elif method == 'at': + # no return value + return None + else: + # one return value + return type(self)(result) + + def __repr__(self): + return '%s(%r)' % (type(self).__name__, self.value) + + +def wrap_array_like(result): + if type(result) is tuple: + return tuple(ArrayLike(r) for r in result) + else: + return ArrayLike(result) + + +def _assert_equal_type_and_value(result, expected, err_msg=None): + assert_equal(type(result), type(expected), err_msg=err_msg) + if isinstance(result, tuple): + assert_equal(len(result), len(expected), err_msg=err_msg) + for result_item, expected_item in zip(result, expected): + _assert_equal_type_and_value(result_item, expected_item, err_msg) + else: + assert_equal(result.value, expected.value, err_msg=err_msg) + assert_equal(getattr(result.value, 'dtype', None), + getattr(expected.value, 'dtype', None), err_msg=err_msg) + + +_ALL_BINARY_OPERATORS = [ + operator.lt, + operator.le, + operator.eq, + operator.ne, + operator.gt, + operator.ge, + operator.add, + operator.sub, + operator.mul, + operator.truediv, + operator.floordiv, + operator.mod, + divmod, + pow, + operator.lshift, + operator.rshift, + operator.and_, + operator.xor, + operator.or_, +] + + +class TestNDArrayOperatorsMixin: + + def test_array_like_add(self): + + def check(result): + _assert_equal_type_and_value(result, ArrayLike(0)) + + check(ArrayLike(0) + 0) + check(0 + ArrayLike(0)) + + check(ArrayLike(0) + np.array(0)) + check(np.array(0) + ArrayLike(0)) + + check(ArrayLike(np.array(0)) + 0) + check(0 + ArrayLike(np.array(0))) + + check(ArrayLike(np.array(0)) + np.array(0)) + check(np.array(0) + ArrayLike(np.array(0))) + + def test_inplace(self): + array_like = ArrayLike(np.array([0])) + array_like += 1 + _assert_equal_type_and_value(array_like, ArrayLike(np.array([1]))) + + array = np.array([0]) + array += ArrayLike(1) + _assert_equal_type_and_value(array, ArrayLike(np.array([1]))) + + def test_opt_out(self): + + class OptOut: + """Object that opts out of __array_ufunc__.""" + __array_ufunc__ = None + + def __add__(self, other): + return self + + def __radd__(self, other): + return self + + array_like = ArrayLike(1) + opt_out = OptOut() + + # supported operations + assert_(array_like + opt_out is opt_out) + assert_(opt_out + array_like is opt_out) + + # not supported + with assert_raises(TypeError): + # don't use the Python default, array_like = array_like + opt_out + array_like += opt_out + with assert_raises(TypeError): + array_like - opt_out + with assert_raises(TypeError): + opt_out - array_like + + def test_subclass(self): + + class SubArrayLike(ArrayLike): + """Should take precedence over ArrayLike.""" + + x = ArrayLike(0) + y = SubArrayLike(1) + _assert_equal_type_and_value(x + y, y) + _assert_equal_type_and_value(y + x, y) + + def test_object(self): + x = ArrayLike(0) + obj = object() + with assert_raises(TypeError): + x + obj + with assert_raises(TypeError): + obj + x + with assert_raises(TypeError): + x += obj + + def test_unary_methods(self): + array = np.array([-1, 0, 1, 2]) + array_like = ArrayLike(array) + for op in [operator.neg, + operator.pos, + abs, + operator.invert]: + _assert_equal_type_and_value(op(array_like), ArrayLike(op(array))) + + def test_forward_binary_methods(self): + array = np.array([-1, 0, 1, 2]) + array_like = ArrayLike(array) + for op in _ALL_BINARY_OPERATORS: + expected = wrap_array_like(op(array, 1)) + actual = op(array_like, 1) + err_msg = 'failed for operator {}'.format(op) + _assert_equal_type_and_value(expected, actual, err_msg=err_msg) + + def test_reflected_binary_methods(self): + for op in _ALL_BINARY_OPERATORS: + expected = wrap_array_like(op(2, 1)) + actual = op(2, ArrayLike(1)) + err_msg = 'failed for operator {}'.format(op) + _assert_equal_type_and_value(expected, actual, err_msg=err_msg) + + def test_matmul(self): + array = np.array([1, 2], dtype=np.float64) + array_like = ArrayLike(array) + expected = ArrayLike(np.float64(5)) + _assert_equal_type_and_value(expected, np.matmul(array_like, array)) + _assert_equal_type_and_value( + expected, operator.matmul(array_like, array)) + _assert_equal_type_and_value( + expected, operator.matmul(array, array_like)) + + def test_ufunc_at(self): + array = ArrayLike(np.array([1, 2, 3, 4])) + assert_(np.negative.at(array, np.array([0, 1])) is None) + _assert_equal_type_and_value(array, ArrayLike([-1, -2, 3, 4])) + + def test_ufunc_two_outputs(self): + mantissa, exponent = np.frexp(2 ** -3) + expected = (ArrayLike(mantissa), ArrayLike(exponent)) + _assert_equal_type_and_value( + np.frexp(ArrayLike(2 ** -3)), expected) + _assert_equal_type_and_value( + np.frexp(ArrayLike(np.array(2 ** -3))), expected) diff --git a/venv/Lib/site-packages/numpy/lib/tests/test_nanfunctions.py b/venv/Lib/site-packages/numpy/lib/tests/test_nanfunctions.py new file mode 100644 index 0000000..e0f723a --- /dev/null +++ b/venv/Lib/site-packages/numpy/lib/tests/test_nanfunctions.py @@ -0,0 +1,980 @@ +import warnings +import pytest + +import numpy as np +from numpy.lib.nanfunctions import _nan_mask, _replace_nan +from numpy.testing import ( + assert_, assert_equal, assert_almost_equal, assert_no_warnings, + assert_raises, assert_array_equal, suppress_warnings + ) + + +# Test data +_ndat = np.array([[0.6244, np.nan, 0.2692, 0.0116, np.nan, 0.1170], + [0.5351, -0.9403, np.nan, 0.2100, 0.4759, 0.2833], + [np.nan, np.nan, np.nan, 0.1042, np.nan, -0.5954], + [0.1610, np.nan, np.nan, 0.1859, 0.3146, np.nan]]) + + +# Rows of _ndat with nans removed +_rdat = [np.array([0.6244, 0.2692, 0.0116, 0.1170]), + np.array([0.5351, -0.9403, 0.2100, 0.4759, 0.2833]), + np.array([0.1042, -0.5954]), + np.array([0.1610, 0.1859, 0.3146])] + +# Rows of _ndat with nans converted to ones +_ndat_ones = np.array([[0.6244, 1.0, 0.2692, 0.0116, 1.0, 0.1170], + [0.5351, -0.9403, 1.0, 0.2100, 0.4759, 0.2833], + [1.0, 1.0, 1.0, 0.1042, 1.0, -0.5954], + [0.1610, 1.0, 1.0, 0.1859, 0.3146, 1.0]]) + +# Rows of _ndat with nans converted to zeros +_ndat_zeros = np.array([[0.6244, 0.0, 0.2692, 0.0116, 0.0, 0.1170], + [0.5351, -0.9403, 0.0, 0.2100, 0.4759, 0.2833], + [0.0, 0.0, 0.0, 0.1042, 0.0, -0.5954], + [0.1610, 0.0, 0.0, 0.1859, 0.3146, 0.0]]) + + +class TestNanFunctions_MinMax: + + nanfuncs = [np.nanmin, np.nanmax] + stdfuncs = [np.min, np.max] + + def test_mutation(self): + # Check that passed array is not modified. + ndat = _ndat.copy() + for f in self.nanfuncs: + f(ndat) + assert_equal(ndat, _ndat) + + def test_keepdims(self): + mat = np.eye(3) + for nf, rf in zip(self.nanfuncs, self.stdfuncs): + for axis in [None, 0, 1]: + tgt = rf(mat, axis=axis, keepdims=True) + res = nf(mat, axis=axis, keepdims=True) + assert_(res.ndim == tgt.ndim) + + def test_out(self): + mat = np.eye(3) + for nf, rf in zip(self.nanfuncs, self.stdfuncs): + resout = np.zeros(3) + tgt = rf(mat, axis=1) + res = nf(mat, axis=1, out=resout) + assert_almost_equal(res, resout) + assert_almost_equal(res, tgt) + + def test_dtype_from_input(self): + codes = 'efdgFDG' + for nf, rf in zip(self.nanfuncs, self.stdfuncs): + for c in codes: + mat = np.eye(3, dtype=c) + tgt = rf(mat, axis=1).dtype.type + res = nf(mat, axis=1).dtype.type + assert_(res is tgt) + # scalar case + tgt = rf(mat, axis=None).dtype.type + res = nf(mat, axis=None).dtype.type + assert_(res is tgt) + + def test_result_values(self): + for nf, rf in zip(self.nanfuncs, self.stdfuncs): + tgt = [rf(d) for d in _rdat] + res = nf(_ndat, axis=1) + assert_almost_equal(res, tgt) + + def test_allnans(self): + mat = np.array([np.nan]*9).reshape(3, 3) + for f in self.nanfuncs: + for axis in [None, 0, 1]: + with warnings.catch_warnings(record=True) as w: + warnings.simplefilter('always') + assert_(np.isnan(f(mat, axis=axis)).all()) + assert_(len(w) == 1, 'no warning raised') + assert_(issubclass(w[0].category, RuntimeWarning)) + # Check scalars + with warnings.catch_warnings(record=True) as w: + warnings.simplefilter('always') + assert_(np.isnan(f(np.nan))) + assert_(len(w) == 1, 'no warning raised') + assert_(issubclass(w[0].category, RuntimeWarning)) + + def test_masked(self): + mat = np.ma.fix_invalid(_ndat) + msk = mat._mask.copy() + for f in [np.nanmin]: + res = f(mat, axis=1) + tgt = f(_ndat, axis=1) + assert_equal(res, tgt) + assert_equal(mat._mask, msk) + assert_(not np.isinf(mat).any()) + + def test_scalar(self): + for f in self.nanfuncs: + assert_(f(0.) == 0.) + + def test_subclass(self): + class MyNDArray(np.ndarray): + pass + + # Check that it works and that type and + # shape are preserved + mine = np.eye(3).view(MyNDArray) + for f in self.nanfuncs: + res = f(mine, axis=0) + assert_(isinstance(res, MyNDArray)) + assert_(res.shape == (3,)) + res = f(mine, axis=1) + assert_(isinstance(res, MyNDArray)) + assert_(res.shape == (3,)) + res = f(mine) + assert_(res.shape == ()) + + # check that rows of nan are dealt with for subclasses (#4628) + mine[1] = np.nan + for f in self.nanfuncs: + with warnings.catch_warnings(record=True) as w: + warnings.simplefilter('always') + res = f(mine, axis=0) + assert_(isinstance(res, MyNDArray)) + assert_(not np.any(np.isnan(res))) + assert_(len(w) == 0) + + with warnings.catch_warnings(record=True) as w: + warnings.simplefilter('always') + res = f(mine, axis=1) + assert_(isinstance(res, MyNDArray)) + assert_(np.isnan(res[1]) and not np.isnan(res[0]) + and not np.isnan(res[2])) + assert_(len(w) == 1, 'no warning raised') + assert_(issubclass(w[0].category, RuntimeWarning)) + + with warnings.catch_warnings(record=True) as w: + warnings.simplefilter('always') + res = f(mine) + assert_(res.shape == ()) + assert_(res != np.nan) + assert_(len(w) == 0) + + def test_object_array(self): + arr = np.array([[1.0, 2.0], [np.nan, 4.0], [np.nan, np.nan]], dtype=object) + assert_equal(np.nanmin(arr), 1.0) + assert_equal(np.nanmin(arr, axis=0), [1.0, 2.0]) + + with warnings.catch_warnings(record=True) as w: + warnings.simplefilter('always') + # assert_equal does not work on object arrays of nan + assert_equal(list(np.nanmin(arr, axis=1)), [1.0, 4.0, np.nan]) + assert_(len(w) == 1, 'no warning raised') + assert_(issubclass(w[0].category, RuntimeWarning)) + + +class TestNanFunctions_ArgminArgmax: + + nanfuncs = [np.nanargmin, np.nanargmax] + + def test_mutation(self): + # Check that passed array is not modified. + ndat = _ndat.copy() + for f in self.nanfuncs: + f(ndat) + assert_equal(ndat, _ndat) + + def test_result_values(self): + for f, fcmp in zip(self.nanfuncs, [np.greater, np.less]): + for row in _ndat: + with suppress_warnings() as sup: + sup.filter(RuntimeWarning, "invalid value encountered in") + ind = f(row) + val = row[ind] + # comparing with NaN is tricky as the result + # is always false except for NaN != NaN + assert_(not np.isnan(val)) + assert_(not fcmp(val, row).any()) + assert_(not np.equal(val, row[:ind]).any()) + + def test_allnans(self): + mat = np.array([np.nan]*9).reshape(3, 3) + for f in self.nanfuncs: + for axis in [None, 0, 1]: + assert_raises(ValueError, f, mat, axis=axis) + assert_raises(ValueError, f, np.nan) + + def test_empty(self): + mat = np.zeros((0, 3)) + for f in self.nanfuncs: + for axis in [0, None]: + assert_raises(ValueError, f, mat, axis=axis) + for axis in [1]: + res = f(mat, axis=axis) + assert_equal(res, np.zeros(0)) + + def test_scalar(self): + for f in self.nanfuncs: + assert_(f(0.) == 0.) + + def test_subclass(self): + class MyNDArray(np.ndarray): + pass + + # Check that it works and that type and + # shape are preserved + mine = np.eye(3).view(MyNDArray) + for f in self.nanfuncs: + res = f(mine, axis=0) + assert_(isinstance(res, MyNDArray)) + assert_(res.shape == (3,)) + res = f(mine, axis=1) + assert_(isinstance(res, MyNDArray)) + assert_(res.shape == (3,)) + res = f(mine) + assert_(res.shape == ()) + + +class TestNanFunctions_IntTypes: + + int_types = (np.int8, np.int16, np.int32, np.int64, np.uint8, + np.uint16, np.uint32, np.uint64) + + mat = np.array([127, 39, 93, 87, 46]) + + def integer_arrays(self): + for dtype in self.int_types: + yield self.mat.astype(dtype) + + def test_nanmin(self): + tgt = np.min(self.mat) + for mat in self.integer_arrays(): + assert_equal(np.nanmin(mat), tgt) + + def test_nanmax(self): + tgt = np.max(self.mat) + for mat in self.integer_arrays(): + assert_equal(np.nanmax(mat), tgt) + + def test_nanargmin(self): + tgt = np.argmin(self.mat) + for mat in self.integer_arrays(): + assert_equal(np.nanargmin(mat), tgt) + + def test_nanargmax(self): + tgt = np.argmax(self.mat) + for mat in self.integer_arrays(): + assert_equal(np.nanargmax(mat), tgt) + + def test_nansum(self): + tgt = np.sum(self.mat) + for mat in self.integer_arrays(): + assert_equal(np.nansum(mat), tgt) + + def test_nanprod(self): + tgt = np.prod(self.mat) + for mat in self.integer_arrays(): + assert_equal(np.nanprod(mat), tgt) + + def test_nancumsum(self): + tgt = np.cumsum(self.mat) + for mat in self.integer_arrays(): + assert_equal(np.nancumsum(mat), tgt) + + def test_nancumprod(self): + tgt = np.cumprod(self.mat) + for mat in self.integer_arrays(): + assert_equal(np.nancumprod(mat), tgt) + + def test_nanmean(self): + tgt = np.mean(self.mat) + for mat in self.integer_arrays(): + assert_equal(np.nanmean(mat), tgt) + + def test_nanvar(self): + tgt = np.var(self.mat) + for mat in self.integer_arrays(): + assert_equal(np.nanvar(mat), tgt) + + tgt = np.var(mat, ddof=1) + for mat in self.integer_arrays(): + assert_equal(np.nanvar(mat, ddof=1), tgt) + + def test_nanstd(self): + tgt = np.std(self.mat) + for mat in self.integer_arrays(): + assert_equal(np.nanstd(mat), tgt) + + tgt = np.std(self.mat, ddof=1) + for mat in self.integer_arrays(): + assert_equal(np.nanstd(mat, ddof=1), tgt) + + +class SharedNanFunctionsTestsMixin: + def test_mutation(self): + # Check that passed array is not modified. + ndat = _ndat.copy() + for f in self.nanfuncs: + f(ndat) + assert_equal(ndat, _ndat) + + def test_keepdims(self): + mat = np.eye(3) + for nf, rf in zip(self.nanfuncs, self.stdfuncs): + for axis in [None, 0, 1]: + tgt = rf(mat, axis=axis, keepdims=True) + res = nf(mat, axis=axis, keepdims=True) + assert_(res.ndim == tgt.ndim) + + def test_out(self): + mat = np.eye(3) + for nf, rf in zip(self.nanfuncs, self.stdfuncs): + resout = np.zeros(3) + tgt = rf(mat, axis=1) + res = nf(mat, axis=1, out=resout) + assert_almost_equal(res, resout) + assert_almost_equal(res, tgt) + + def test_dtype_from_dtype(self): + mat = np.eye(3) + codes = 'efdgFDG' + for nf, rf in zip(self.nanfuncs, self.stdfuncs): + for c in codes: + with suppress_warnings() as sup: + if nf in {np.nanstd, np.nanvar} and c in 'FDG': + # Giving the warning is a small bug, see gh-8000 + sup.filter(np.ComplexWarning) + tgt = rf(mat, dtype=np.dtype(c), axis=1).dtype.type + res = nf(mat, dtype=np.dtype(c), axis=1).dtype.type + assert_(res is tgt) + # scalar case + tgt = rf(mat, dtype=np.dtype(c), axis=None).dtype.type + res = nf(mat, dtype=np.dtype(c), axis=None).dtype.type + assert_(res is tgt) + + def test_dtype_from_char(self): + mat = np.eye(3) + codes = 'efdgFDG' + for nf, rf in zip(self.nanfuncs, self.stdfuncs): + for c in codes: + with suppress_warnings() as sup: + if nf in {np.nanstd, np.nanvar} and c in 'FDG': + # Giving the warning is a small bug, see gh-8000 + sup.filter(np.ComplexWarning) + tgt = rf(mat, dtype=c, axis=1).dtype.type + res = nf(mat, dtype=c, axis=1).dtype.type + assert_(res is tgt) + # scalar case + tgt = rf(mat, dtype=c, axis=None).dtype.type + res = nf(mat, dtype=c, axis=None).dtype.type + assert_(res is tgt) + + def test_dtype_from_input(self): + codes = 'efdgFDG' + for nf, rf in zip(self.nanfuncs, self.stdfuncs): + for c in codes: + mat = np.eye(3, dtype=c) + tgt = rf(mat, axis=1).dtype.type + res = nf(mat, axis=1).dtype.type + assert_(res is tgt, "res %s, tgt %s" % (res, tgt)) + # scalar case + tgt = rf(mat, axis=None).dtype.type + res = nf(mat, axis=None).dtype.type + assert_(res is tgt) + + def test_result_values(self): + for nf, rf in zip(self.nanfuncs, self.stdfuncs): + tgt = [rf(d) for d in _rdat] + res = nf(_ndat, axis=1) + assert_almost_equal(res, tgt) + + def test_scalar(self): + for f in self.nanfuncs: + assert_(f(0.) == 0.) + + def test_subclass(self): + class MyNDArray(np.ndarray): + pass + + # Check that it works and that type and + # shape are preserved + array = np.eye(3) + mine = array.view(MyNDArray) + for f in self.nanfuncs: + expected_shape = f(array, axis=0).shape + res = f(mine, axis=0) + assert_(isinstance(res, MyNDArray)) + assert_(res.shape == expected_shape) + expected_shape = f(array, axis=1).shape + res = f(mine, axis=1) + assert_(isinstance(res, MyNDArray)) + assert_(res.shape == expected_shape) + expected_shape = f(array).shape + res = f(mine) + assert_(isinstance(res, MyNDArray)) + assert_(res.shape == expected_shape) + + +class TestNanFunctions_SumProd(SharedNanFunctionsTestsMixin): + + nanfuncs = [np.nansum, np.nanprod] + stdfuncs = [np.sum, np.prod] + + def test_allnans(self): + # Check for FutureWarning + with warnings.catch_warnings(record=True) as w: + warnings.simplefilter('always') + res = np.nansum([np.nan]*3, axis=None) + assert_(res == 0, 'result is not 0') + assert_(len(w) == 0, 'warning raised') + # Check scalar + res = np.nansum(np.nan) + assert_(res == 0, 'result is not 0') + assert_(len(w) == 0, 'warning raised') + # Check there is no warning for not all-nan + np.nansum([0]*3, axis=None) + assert_(len(w) == 0, 'unwanted warning raised') + + def test_empty(self): + for f, tgt_value in zip([np.nansum, np.nanprod], [0, 1]): + mat = np.zeros((0, 3)) + tgt = [tgt_value]*3 + res = f(mat, axis=0) + assert_equal(res, tgt) + tgt = [] + res = f(mat, axis=1) + assert_equal(res, tgt) + tgt = tgt_value + res = f(mat, axis=None) + assert_equal(res, tgt) + + +class TestNanFunctions_CumSumProd(SharedNanFunctionsTestsMixin): + + nanfuncs = [np.nancumsum, np.nancumprod] + stdfuncs = [np.cumsum, np.cumprod] + + def test_allnans(self): + for f, tgt_value in zip(self.nanfuncs, [0, 1]): + # Unlike other nan-functions, sum/prod/cumsum/cumprod don't warn on all nan input + with assert_no_warnings(): + res = f([np.nan]*3, axis=None) + tgt = tgt_value*np.ones((3)) + assert_(np.array_equal(res, tgt), 'result is not %s * np.ones((3))' % (tgt_value)) + # Check scalar + res = f(np.nan) + tgt = tgt_value*np.ones((1)) + assert_(np.array_equal(res, tgt), 'result is not %s * np.ones((1))' % (tgt_value)) + # Check there is no warning for not all-nan + f([0]*3, axis=None) + + def test_empty(self): + for f, tgt_value in zip(self.nanfuncs, [0, 1]): + mat = np.zeros((0, 3)) + tgt = tgt_value*np.ones((0, 3)) + res = f(mat, axis=0) + assert_equal(res, tgt) + tgt = mat + res = f(mat, axis=1) + assert_equal(res, tgt) + tgt = np.zeros((0)) + res = f(mat, axis=None) + assert_equal(res, tgt) + + def test_keepdims(self): + for f, g in zip(self.nanfuncs, self.stdfuncs): + mat = np.eye(3) + for axis in [None, 0, 1]: + tgt = f(mat, axis=axis, out=None) + res = g(mat, axis=axis, out=None) + assert_(res.ndim == tgt.ndim) + + for f in self.nanfuncs: + d = np.ones((3, 5, 7, 11)) + # Randomly set some elements to NaN: + rs = np.random.RandomState(0) + d[rs.rand(*d.shape) < 0.5] = np.nan + res = f(d, axis=None) + assert_equal(res.shape, (1155,)) + for axis in np.arange(4): + res = f(d, axis=axis) + assert_equal(res.shape, (3, 5, 7, 11)) + + def test_result_values(self): + for axis in (-2, -1, 0, 1, None): + tgt = np.cumprod(_ndat_ones, axis=axis) + res = np.nancumprod(_ndat, axis=axis) + assert_almost_equal(res, tgt) + tgt = np.cumsum(_ndat_zeros,axis=axis) + res = np.nancumsum(_ndat, axis=axis) + assert_almost_equal(res, tgt) + + def test_out(self): + mat = np.eye(3) + for nf, rf in zip(self.nanfuncs, self.stdfuncs): + resout = np.eye(3) + for axis in (-2, -1, 0, 1): + tgt = rf(mat, axis=axis) + res = nf(mat, axis=axis, out=resout) + assert_almost_equal(res, resout) + assert_almost_equal(res, tgt) + + +class TestNanFunctions_MeanVarStd(SharedNanFunctionsTestsMixin): + + nanfuncs = [np.nanmean, np.nanvar, np.nanstd] + stdfuncs = [np.mean, np.var, np.std] + + def test_dtype_error(self): + for f in self.nanfuncs: + for dtype in [np.bool_, np.int_, np.object_]: + assert_raises(TypeError, f, _ndat, axis=1, dtype=dtype) + + def test_out_dtype_error(self): + for f in self.nanfuncs: + for dtype in [np.bool_, np.int_, np.object_]: + out = np.empty(_ndat.shape[0], dtype=dtype) + assert_raises(TypeError, f, _ndat, axis=1, out=out) + + def test_ddof(self): + nanfuncs = [np.nanvar, np.nanstd] + stdfuncs = [np.var, np.std] + for nf, rf in zip(nanfuncs, stdfuncs): + for ddof in [0, 1]: + tgt = [rf(d, ddof=ddof) for d in _rdat] + res = nf(_ndat, axis=1, ddof=ddof) + assert_almost_equal(res, tgt) + + def test_ddof_too_big(self): + nanfuncs = [np.nanvar, np.nanstd] + stdfuncs = [np.var, np.std] + dsize = [len(d) for d in _rdat] + for nf, rf in zip(nanfuncs, stdfuncs): + for ddof in range(5): + with suppress_warnings() as sup: + sup.record(RuntimeWarning) + sup.filter(np.ComplexWarning) + tgt = [ddof >= d for d in dsize] + res = nf(_ndat, axis=1, ddof=ddof) + assert_equal(np.isnan(res), tgt) + if any(tgt): + assert_(len(sup.log) == 1) + else: + assert_(len(sup.log) == 0) + + def test_allnans(self): + mat = np.array([np.nan]*9).reshape(3, 3) + for f in self.nanfuncs: + for axis in [None, 0, 1]: + with warnings.catch_warnings(record=True) as w: + warnings.simplefilter('always') + assert_(np.isnan(f(mat, axis=axis)).all()) + assert_(len(w) == 1) + assert_(issubclass(w[0].category, RuntimeWarning)) + # Check scalar + assert_(np.isnan(f(np.nan))) + assert_(len(w) == 2) + assert_(issubclass(w[0].category, RuntimeWarning)) + + def test_empty(self): + mat = np.zeros((0, 3)) + for f in self.nanfuncs: + for axis in [0, None]: + with warnings.catch_warnings(record=True) as w: + warnings.simplefilter('always') + assert_(np.isnan(f(mat, axis=axis)).all()) + assert_(len(w) == 1) + assert_(issubclass(w[0].category, RuntimeWarning)) + for axis in [1]: + with warnings.catch_warnings(record=True) as w: + warnings.simplefilter('always') + assert_equal(f(mat, axis=axis), np.zeros([])) + assert_(len(w) == 0) + + +class TestNanFunctions_Median: + + def test_mutation(self): + # Check that passed array is not modified. + ndat = _ndat.copy() + np.nanmedian(ndat) + assert_equal(ndat, _ndat) + + def test_keepdims(self): + mat = np.eye(3) + for axis in [None, 0, 1]: + tgt = np.median(mat, axis=axis, out=None, overwrite_input=False) + res = np.nanmedian(mat, axis=axis, out=None, overwrite_input=False) + assert_(res.ndim == tgt.ndim) + + d = np.ones((3, 5, 7, 11)) + # Randomly set some elements to NaN: + w = np.random.random((4, 200)) * np.array(d.shape)[:, None] + w = w.astype(np.intp) + d[tuple(w)] = np.nan + with suppress_warnings() as sup: + sup.filter(RuntimeWarning) + res = np.nanmedian(d, axis=None, keepdims=True) + assert_equal(res.shape, (1, 1, 1, 1)) + res = np.nanmedian(d, axis=(0, 1), keepdims=True) + assert_equal(res.shape, (1, 1, 7, 11)) + res = np.nanmedian(d, axis=(0, 3), keepdims=True) + assert_equal(res.shape, (1, 5, 7, 1)) + res = np.nanmedian(d, axis=(1,), keepdims=True) + assert_equal(res.shape, (3, 1, 7, 11)) + res = np.nanmedian(d, axis=(0, 1, 2, 3), keepdims=True) + assert_equal(res.shape, (1, 1, 1, 1)) + res = np.nanmedian(d, axis=(0, 1, 3), keepdims=True) + assert_equal(res.shape, (1, 1, 7, 1)) + + def test_out(self): + mat = np.random.rand(3, 3) + nan_mat = np.insert(mat, [0, 2], np.nan, axis=1) + resout = np.zeros(3) + tgt = np.median(mat, axis=1) + res = np.nanmedian(nan_mat, axis=1, out=resout) + assert_almost_equal(res, resout) + assert_almost_equal(res, tgt) + # 0-d output: + resout = np.zeros(()) + tgt = np.median(mat, axis=None) + res = np.nanmedian(nan_mat, axis=None, out=resout) + assert_almost_equal(res, resout) + assert_almost_equal(res, tgt) + res = np.nanmedian(nan_mat, axis=(0, 1), out=resout) + assert_almost_equal(res, resout) + assert_almost_equal(res, tgt) + + def test_small_large(self): + # test the small and large code paths, current cutoff 400 elements + for s in [5, 20, 51, 200, 1000]: + d = np.random.randn(4, s) + # Randomly set some elements to NaN: + w = np.random.randint(0, d.size, size=d.size // 5) + d.ravel()[w] = np.nan + d[:,0] = 1. # ensure at least one good value + # use normal median without nans to compare + tgt = [] + for x in d: + nonan = np.compress(~np.isnan(x), x) + tgt.append(np.median(nonan, overwrite_input=True)) + + assert_array_equal(np.nanmedian(d, axis=-1), tgt) + + def test_result_values(self): + tgt = [np.median(d) for d in _rdat] + res = np.nanmedian(_ndat, axis=1) + assert_almost_equal(res, tgt) + + def test_allnans(self): + mat = np.array([np.nan]*9).reshape(3, 3) + for axis in [None, 0, 1]: + with suppress_warnings() as sup: + sup.record(RuntimeWarning) + + assert_(np.isnan(np.nanmedian(mat, axis=axis)).all()) + if axis is None: + assert_(len(sup.log) == 1) + else: + assert_(len(sup.log) == 3) + # Check scalar + assert_(np.isnan(np.nanmedian(np.nan))) + if axis is None: + assert_(len(sup.log) == 2) + else: + assert_(len(sup.log) == 4) + + def test_empty(self): + mat = np.zeros((0, 3)) + for axis in [0, None]: + with warnings.catch_warnings(record=True) as w: + warnings.simplefilter('always') + assert_(np.isnan(np.nanmedian(mat, axis=axis)).all()) + assert_(len(w) == 1) + assert_(issubclass(w[0].category, RuntimeWarning)) + for axis in [1]: + with warnings.catch_warnings(record=True) as w: + warnings.simplefilter('always') + assert_equal(np.nanmedian(mat, axis=axis), np.zeros([])) + assert_(len(w) == 0) + + def test_scalar(self): + assert_(np.nanmedian(0.) == 0.) + + def test_extended_axis_invalid(self): + d = np.ones((3, 5, 7, 11)) + assert_raises(np.AxisError, np.nanmedian, d, axis=-5) + assert_raises(np.AxisError, np.nanmedian, d, axis=(0, -5)) + assert_raises(np.AxisError, np.nanmedian, d, axis=4) + assert_raises(np.AxisError, np.nanmedian, d, axis=(0, 4)) + assert_raises(ValueError, np.nanmedian, d, axis=(1, 1)) + + def test_float_special(self): + with suppress_warnings() as sup: + sup.filter(RuntimeWarning) + for inf in [np.inf, -np.inf]: + a = np.array([[inf, np.nan], [np.nan, np.nan]]) + assert_equal(np.nanmedian(a, axis=0), [inf, np.nan]) + assert_equal(np.nanmedian(a, axis=1), [inf, np.nan]) + assert_equal(np.nanmedian(a), inf) + + # minimum fill value check + a = np.array([[np.nan, np.nan, inf], + [np.nan, np.nan, inf]]) + assert_equal(np.nanmedian(a), inf) + assert_equal(np.nanmedian(a, axis=0), [np.nan, np.nan, inf]) + assert_equal(np.nanmedian(a, axis=1), inf) + + # no mask path + a = np.array([[inf, inf], [inf, inf]]) + assert_equal(np.nanmedian(a, axis=1), inf) + + a = np.array([[inf, 7, -inf, -9], + [-10, np.nan, np.nan, 5], + [4, np.nan, np.nan, inf]], + dtype=np.float32) + if inf > 0: + assert_equal(np.nanmedian(a, axis=0), [4., 7., -inf, 5.]) + assert_equal(np.nanmedian(a), 4.5) + else: + assert_equal(np.nanmedian(a, axis=0), [-10., 7., -inf, -9.]) + assert_equal(np.nanmedian(a), -2.5) + assert_equal(np.nanmedian(a, axis=-1), [-1., -2.5, inf]) + + for i in range(0, 10): + for j in range(1, 10): + a = np.array([([np.nan] * i) + ([inf] * j)] * 2) + assert_equal(np.nanmedian(a), inf) + assert_equal(np.nanmedian(a, axis=1), inf) + assert_equal(np.nanmedian(a, axis=0), + ([np.nan] * i) + [inf] * j) + + a = np.array([([np.nan] * i) + ([-inf] * j)] * 2) + assert_equal(np.nanmedian(a), -inf) + assert_equal(np.nanmedian(a, axis=1), -inf) + assert_equal(np.nanmedian(a, axis=0), + ([np.nan] * i) + [-inf] * j) + + +class TestNanFunctions_Percentile: + + def test_mutation(self): + # Check that passed array is not modified. + ndat = _ndat.copy() + np.nanpercentile(ndat, 30) + assert_equal(ndat, _ndat) + + def test_keepdims(self): + mat = np.eye(3) + for axis in [None, 0, 1]: + tgt = np.percentile(mat, 70, axis=axis, out=None, + overwrite_input=False) + res = np.nanpercentile(mat, 70, axis=axis, out=None, + overwrite_input=False) + assert_(res.ndim == tgt.ndim) + + d = np.ones((3, 5, 7, 11)) + # Randomly set some elements to NaN: + w = np.random.random((4, 200)) * np.array(d.shape)[:, None] + w = w.astype(np.intp) + d[tuple(w)] = np.nan + with suppress_warnings() as sup: + sup.filter(RuntimeWarning) + res = np.nanpercentile(d, 90, axis=None, keepdims=True) + assert_equal(res.shape, (1, 1, 1, 1)) + res = np.nanpercentile(d, 90, axis=(0, 1), keepdims=True) + assert_equal(res.shape, (1, 1, 7, 11)) + res = np.nanpercentile(d, 90, axis=(0, 3), keepdims=True) + assert_equal(res.shape, (1, 5, 7, 1)) + res = np.nanpercentile(d, 90, axis=(1,), keepdims=True) + assert_equal(res.shape, (3, 1, 7, 11)) + res = np.nanpercentile(d, 90, axis=(0, 1, 2, 3), keepdims=True) + assert_equal(res.shape, (1, 1, 1, 1)) + res = np.nanpercentile(d, 90, axis=(0, 1, 3), keepdims=True) + assert_equal(res.shape, (1, 1, 7, 1)) + + def test_out(self): + mat = np.random.rand(3, 3) + nan_mat = np.insert(mat, [0, 2], np.nan, axis=1) + resout = np.zeros(3) + tgt = np.percentile(mat, 42, axis=1) + res = np.nanpercentile(nan_mat, 42, axis=1, out=resout) + assert_almost_equal(res, resout) + assert_almost_equal(res, tgt) + # 0-d output: + resout = np.zeros(()) + tgt = np.percentile(mat, 42, axis=None) + res = np.nanpercentile(nan_mat, 42, axis=None, out=resout) + assert_almost_equal(res, resout) + assert_almost_equal(res, tgt) + res = np.nanpercentile(nan_mat, 42, axis=(0, 1), out=resout) + assert_almost_equal(res, resout) + assert_almost_equal(res, tgt) + + def test_result_values(self): + tgt = [np.percentile(d, 28) for d in _rdat] + res = np.nanpercentile(_ndat, 28, axis=1) + assert_almost_equal(res, tgt) + # Transpose the array to fit the output convention of numpy.percentile + tgt = np.transpose([np.percentile(d, (28, 98)) for d in _rdat]) + res = np.nanpercentile(_ndat, (28, 98), axis=1) + assert_almost_equal(res, tgt) + + def test_allnans(self): + mat = np.array([np.nan]*9).reshape(3, 3) + for axis in [None, 0, 1]: + with warnings.catch_warnings(record=True) as w: + warnings.simplefilter('always') + assert_(np.isnan(np.nanpercentile(mat, 60, axis=axis)).all()) + if axis is None: + assert_(len(w) == 1) + else: + assert_(len(w) == 3) + assert_(issubclass(w[0].category, RuntimeWarning)) + # Check scalar + assert_(np.isnan(np.nanpercentile(np.nan, 60))) + if axis is None: + assert_(len(w) == 2) + else: + assert_(len(w) == 4) + assert_(issubclass(w[0].category, RuntimeWarning)) + + def test_empty(self): + mat = np.zeros((0, 3)) + for axis in [0, None]: + with warnings.catch_warnings(record=True) as w: + warnings.simplefilter('always') + assert_(np.isnan(np.nanpercentile(mat, 40, axis=axis)).all()) + assert_(len(w) == 1) + assert_(issubclass(w[0].category, RuntimeWarning)) + for axis in [1]: + with warnings.catch_warnings(record=True) as w: + warnings.simplefilter('always') + assert_equal(np.nanpercentile(mat, 40, axis=axis), np.zeros([])) + assert_(len(w) == 0) + + def test_scalar(self): + assert_equal(np.nanpercentile(0., 100), 0.) + a = np.arange(6) + r = np.nanpercentile(a, 50, axis=0) + assert_equal(r, 2.5) + assert_(np.isscalar(r)) + + def test_extended_axis_invalid(self): + d = np.ones((3, 5, 7, 11)) + assert_raises(np.AxisError, np.nanpercentile, d, q=5, axis=-5) + assert_raises(np.AxisError, np.nanpercentile, d, q=5, axis=(0, -5)) + assert_raises(np.AxisError, np.nanpercentile, d, q=5, axis=4) + assert_raises(np.AxisError, np.nanpercentile, d, q=5, axis=(0, 4)) + assert_raises(ValueError, np.nanpercentile, d, q=5, axis=(1, 1)) + + def test_multiple_percentiles(self): + perc = [50, 100] + mat = np.ones((4, 3)) + nan_mat = np.nan * mat + # For checking consistency in higher dimensional case + large_mat = np.ones((3, 4, 5)) + large_mat[:, 0:2:4, :] = 0 + large_mat[:, :, 3:] *= 2 + for axis in [None, 0, 1]: + for keepdim in [False, True]: + with suppress_warnings() as sup: + sup.filter(RuntimeWarning, "All-NaN slice encountered") + val = np.percentile(mat, perc, axis=axis, keepdims=keepdim) + nan_val = np.nanpercentile(nan_mat, perc, axis=axis, + keepdims=keepdim) + assert_equal(nan_val.shape, val.shape) + + val = np.percentile(large_mat, perc, axis=axis, + keepdims=keepdim) + nan_val = np.nanpercentile(large_mat, perc, axis=axis, + keepdims=keepdim) + assert_equal(nan_val, val) + + megamat = np.ones((3, 4, 5, 6)) + assert_equal(np.nanpercentile(megamat, perc, axis=(1, 2)).shape, (2, 3, 6)) + + +class TestNanFunctions_Quantile: + # most of this is already tested by TestPercentile + + def test_regression(self): + ar = np.arange(24).reshape(2, 3, 4).astype(float) + ar[0][1] = np.nan + + assert_equal(np.nanquantile(ar, q=0.5), np.nanpercentile(ar, q=50)) + assert_equal(np.nanquantile(ar, q=0.5, axis=0), + np.nanpercentile(ar, q=50, axis=0)) + assert_equal(np.nanquantile(ar, q=0.5, axis=1), + np.nanpercentile(ar, q=50, axis=1)) + assert_equal(np.nanquantile(ar, q=[0.5], axis=1), + np.nanpercentile(ar, q=[50], axis=1)) + assert_equal(np.nanquantile(ar, q=[0.25, 0.5, 0.75], axis=1), + np.nanpercentile(ar, q=[25, 50, 75], axis=1)) + + def test_basic(self): + x = np.arange(8) * 0.5 + assert_equal(np.nanquantile(x, 0), 0.) + assert_equal(np.nanquantile(x, 1), 3.5) + assert_equal(np.nanquantile(x, 0.5), 1.75) + + def test_no_p_overwrite(self): + # this is worth retesting, because quantile does not make a copy + p0 = np.array([0, 0.75, 0.25, 0.5, 1.0]) + p = p0.copy() + np.nanquantile(np.arange(100.), p, interpolation="midpoint") + assert_array_equal(p, p0) + + p0 = p0.tolist() + p = p.tolist() + np.nanquantile(np.arange(100.), p, interpolation="midpoint") + assert_array_equal(p, p0) + +@pytest.mark.parametrize("arr, expected", [ + # array of floats with some nans + (np.array([np.nan, 5.0, np.nan, np.inf]), + np.array([False, True, False, True])), + # int64 array that can't possibly have nans + (np.array([1, 5, 7, 9], dtype=np.int64), + True), + # bool array that can't possibly have nans + (np.array([False, True, False, True]), + True), + # 2-D complex array with nans + (np.array([[np.nan, 5.0], + [np.nan, np.inf]], dtype=np.complex64), + np.array([[False, True], + [False, True]])), + ]) +def test__nan_mask(arr, expected): + for out in [None, np.empty(arr.shape, dtype=np.bool_)]: + actual = _nan_mask(arr, out=out) + assert_equal(actual, expected) + # the above won't distinguish between True proper + # and an array of True values; we want True proper + # for types that can't possibly contain NaN + if type(expected) is not np.ndarray: + assert actual is True + + +def test__replace_nan(): + """ Test that _replace_nan returns the original array if there are no + NaNs, not a copy. + """ + for dtype in [np.bool_, np.int32, np.int64]: + arr = np.array([0, 1], dtype=dtype) + result, mask = _replace_nan(arr, 0) + assert mask is None + # do not make a copy if there are no nans + assert result is arr + + for dtype in [np.float32, np.float64]: + arr = np.array([0, 1], dtype=dtype) + result, mask = _replace_nan(arr, 2) + assert (mask == False).all() + # mask is not None, so we make a copy + assert result is not arr + assert_equal(result, arr) + + arr_nan = np.array([0, 1, np.nan], dtype=dtype) + result_nan, mask_nan = _replace_nan(arr_nan, 2) + assert_equal(mask_nan, np.array([False, False, True])) + assert result_nan is not arr_nan + assert_equal(result_nan, np.array([0, 1, 2])) + assert np.isnan(arr_nan[-1]) diff --git a/venv/Lib/site-packages/numpy/lib/tests/test_packbits.py b/venv/Lib/site-packages/numpy/lib/tests/test_packbits.py new file mode 100644 index 0000000..5b07f41 --- /dev/null +++ b/venv/Lib/site-packages/numpy/lib/tests/test_packbits.py @@ -0,0 +1,376 @@ +import numpy as np +from numpy.testing import assert_array_equal, assert_equal, assert_raises +import pytest +from itertools import chain + +def test_packbits(): + # Copied from the docstring. + a = [[[1, 0, 1], [0, 1, 0]], + [[1, 1, 0], [0, 0, 1]]] + for dt in '?bBhHiIlLqQ': + arr = np.array(a, dtype=dt) + b = np.packbits(arr, axis=-1) + assert_equal(b.dtype, np.uint8) + assert_array_equal(b, np.array([[[160], [64]], [[192], [32]]])) + + assert_raises(TypeError, np.packbits, np.array(a, dtype=float)) + + +def test_packbits_empty(): + shapes = [ + (0,), (10, 20, 0), (10, 0, 20), (0, 10, 20), (20, 0, 0), (0, 20, 0), + (0, 0, 20), (0, 0, 0), + ] + for dt in '?bBhHiIlLqQ': + for shape in shapes: + a = np.empty(shape, dtype=dt) + b = np.packbits(a) + assert_equal(b.dtype, np.uint8) + assert_equal(b.shape, (0,)) + + +def test_packbits_empty_with_axis(): + # Original shapes and lists of packed shapes for different axes. + shapes = [ + ((0,), [(0,)]), + ((10, 20, 0), [(2, 20, 0), (10, 3, 0), (10, 20, 0)]), + ((10, 0, 20), [(2, 0, 20), (10, 0, 20), (10, 0, 3)]), + ((0, 10, 20), [(0, 10, 20), (0, 2, 20), (0, 10, 3)]), + ((20, 0, 0), [(3, 0, 0), (20, 0, 0), (20, 0, 0)]), + ((0, 20, 0), [(0, 20, 0), (0, 3, 0), (0, 20, 0)]), + ((0, 0, 20), [(0, 0, 20), (0, 0, 20), (0, 0, 3)]), + ((0, 0, 0), [(0, 0, 0), (0, 0, 0), (0, 0, 0)]), + ] + for dt in '?bBhHiIlLqQ': + for in_shape, out_shapes in shapes: + for ax, out_shape in enumerate(out_shapes): + a = np.empty(in_shape, dtype=dt) + b = np.packbits(a, axis=ax) + assert_equal(b.dtype, np.uint8) + assert_equal(b.shape, out_shape) + +@pytest.mark.parametrize('bitorder', ('little', 'big')) +def test_packbits_large(bitorder): + # test data large enough for 16 byte vectorization + a = np.array([1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, + 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, + 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, + 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, + 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, + 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, + 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, + 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, + 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, + 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, + 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, + 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, + 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, + 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0]) + a = a.repeat(3) + for dtype in '?bBhHiIlLqQ': + arr = np.array(a, dtype=dtype) + b = np.packbits(arr, axis=None, bitorder=bitorder) + assert_equal(b.dtype, np.uint8) + r = [252, 127, 192, 3, 254, 7, 252, 0, 7, 31, 240, 0, 28, 1, 255, 252, + 113, 248, 3, 255, 192, 28, 15, 192, 28, 126, 0, 224, 127, 255, + 227, 142, 7, 31, 142, 63, 28, 126, 56, 227, 240, 0, 227, 128, 63, + 224, 14, 56, 252, 112, 56, 255, 241, 248, 3, 240, 56, 224, 112, + 63, 255, 255, 199, 224, 14, 0, 31, 143, 192, 3, 255, 199, 0, 1, + 255, 224, 1, 255, 252, 126, 63, 0, 1, 192, 252, 14, 63, 0, 15, + 199, 252, 113, 255, 3, 128, 56, 252, 14, 7, 0, 113, 255, 255, 142, 56, 227, + 129, 248, 227, 129, 199, 31, 128] + if bitorder == 'big': + assert_array_equal(b, r) + # equal for size being multiple of 8 + assert_array_equal(np.unpackbits(b, bitorder=bitorder)[:-4], a) + + # check last byte of different remainders (16 byte vectorization) + b = [np.packbits(arr[:-i], axis=None)[-1] for i in range(1, 16)] + assert_array_equal(b, [128, 128, 128, 31, 30, 28, 24, 16, 0, 0, 0, 199, + 198, 196, 192]) + + + arr = arr.reshape(36, 25) + b = np.packbits(arr, axis=0) + assert_equal(b.dtype, np.uint8) + assert_array_equal(b, [[190, 186, 178, 178, 150, 215, 87, 83, 83, 195, + 199, 206, 204, 204, 140, 140, 136, 136, 8, 40, 105, + 107, 75, 74, 88], + [72, 216, 248, 241, 227, 195, 202, 90, 90, 83, + 83, 119, 127, 109, 73, 64, 208, 244, 189, 45, + 41, 104, 122, 90, 18], + [113, 120, 248, 216, 152, 24, 60, 52, 182, 150, + 150, 150, 146, 210, 210, 246, 255, 255, 223, + 151, 21, 17, 17, 131, 163], + [214, 210, 210, 64, 68, 5, 5, 1, 72, 88, 92, + 92, 78, 110, 39, 181, 149, 220, 222, 218, 218, + 202, 234, 170, 168], + [0, 128, 128, 192, 80, 112, 48, 160, 160, 224, + 240, 208, 144, 128, 160, 224, 240, 208, 144, + 144, 176, 240, 224, 192, 128]]) + + b = np.packbits(arr, axis=1) + assert_equal(b.dtype, np.uint8) + assert_array_equal(b, [[252, 127, 192, 0], + [ 7, 252, 15, 128], + [240, 0, 28, 0], + [255, 128, 0, 128], + [192, 31, 255, 128], + [142, 63, 0, 0], + [255, 240, 7, 0], + [ 7, 224, 14, 0], + [126, 0, 224, 0], + [255, 255, 199, 0], + [ 56, 28, 126, 0], + [113, 248, 227, 128], + [227, 142, 63, 0], + [ 0, 28, 112, 0], + [ 15, 248, 3, 128], + [ 28, 126, 56, 0], + [ 56, 255, 241, 128], + [240, 7, 224, 0], + [227, 129, 192, 128], + [255, 255, 254, 0], + [126, 0, 224, 0], + [ 3, 241, 248, 0], + [ 0, 255, 241, 128], + [128, 0, 255, 128], + [224, 1, 255, 128], + [248, 252, 126, 0], + [ 0, 7, 3, 128], + [224, 113, 248, 0], + [ 0, 252, 127, 128], + [142, 63, 224, 0], + [224, 14, 63, 0], + [ 7, 3, 128, 0], + [113, 255, 255, 128], + [ 28, 113, 199, 0], + [ 7, 227, 142, 0], + [ 14, 56, 252, 0]]) + + arr = arr.T.copy() + b = np.packbits(arr, axis=0) + assert_equal(b.dtype, np.uint8) + assert_array_equal(b, [[252, 7, 240, 255, 192, 142, 255, 7, 126, 255, + 56, 113, 227, 0, 15, 28, 56, 240, 227, 255, + 126, 3, 0, 128, 224, 248, 0, 224, 0, 142, 224, + 7, 113, 28, 7, 14], + [127, 252, 0, 128, 31, 63, 240, 224, 0, 255, + 28, 248, 142, 28, 248, 126, 255, 7, 129, 255, + 0, 241, 255, 0, 1, 252, 7, 113, 252, 63, 14, + 3, 255, 113, 227, 56], + [192, 15, 28, 0, 255, 0, 7, 14, 224, 199, 126, + 227, 63, 112, 3, 56, 241, 224, 192, 254, 224, + 248, 241, 255, 255, 126, 3, 248, 127, 224, 63, + 128, 255, 199, 142, 252], + [0, 128, 0, 128, 128, 0, 0, 0, 0, 0, 0, 128, 0, + 0, 128, 0, 128, 0, 128, 0, 0, 0, 128, 128, + 128, 0, 128, 0, 128, 0, 0, 0, 128, 0, 0, 0]]) + + b = np.packbits(arr, axis=1) + assert_equal(b.dtype, np.uint8) + assert_array_equal(b, [[190, 72, 113, 214, 0], + [186, 216, 120, 210, 128], + [178, 248, 248, 210, 128], + [178, 241, 216, 64, 192], + [150, 227, 152, 68, 80], + [215, 195, 24, 5, 112], + [ 87, 202, 60, 5, 48], + [ 83, 90, 52, 1, 160], + [ 83, 90, 182, 72, 160], + [195, 83, 150, 88, 224], + [199, 83, 150, 92, 240], + [206, 119, 150, 92, 208], + [204, 127, 146, 78, 144], + [204, 109, 210, 110, 128], + [140, 73, 210, 39, 160], + [140, 64, 246, 181, 224], + [136, 208, 255, 149, 240], + [136, 244, 255, 220, 208], + [ 8, 189, 223, 222, 144], + [ 40, 45, 151, 218, 144], + [105, 41, 21, 218, 176], + [107, 104, 17, 202, 240], + [ 75, 122, 17, 234, 224], + [ 74, 90, 131, 170, 192], + [ 88, 18, 163, 168, 128]]) + + + # result is the same if input is multiplied with a nonzero value + for dtype in 'bBhHiIlLqQ': + arr = np.array(a, dtype=dtype) + rnd = np.random.randint(low=np.iinfo(dtype).min, + high=np.iinfo(dtype).max, size=arr.size, + dtype=dtype) + rnd[rnd == 0] = 1 + arr *= rnd.astype(dtype) + b = np.packbits(arr, axis=-1) + assert_array_equal(np.unpackbits(b)[:-4], a) + + assert_raises(TypeError, np.packbits, np.array(a, dtype=float)) + + +def test_packbits_very_large(): + # test some with a larger arrays gh-8637 + # code is covered earlier but larger array makes crash on bug more likely + for s in range(950, 1050): + for dt in '?bBhHiIlLqQ': + x = np.ones((200, s), dtype=bool) + np.packbits(x, axis=1) + + +def test_unpackbits(): + # Copied from the docstring. + a = np.array([[2], [7], [23]], dtype=np.uint8) + b = np.unpackbits(a, axis=1) + assert_equal(b.dtype, np.uint8) + assert_array_equal(b, np.array([[0, 0, 0, 0, 0, 0, 1, 0], + [0, 0, 0, 0, 0, 1, 1, 1], + [0, 0, 0, 1, 0, 1, 1, 1]])) + +def test_pack_unpack_order(): + a = np.array([[2], [7], [23]], dtype=np.uint8) + b = np.unpackbits(a, axis=1) + assert_equal(b.dtype, np.uint8) + b_little = np.unpackbits(a, axis=1, bitorder='little') + b_big = np.unpackbits(a, axis=1, bitorder='big') + assert_array_equal(b, b_big) + assert_array_equal(a, np.packbits(b_little, axis=1, bitorder='little')) + assert_array_equal(b[:,::-1], b_little) + assert_array_equal(a, np.packbits(b_big, axis=1, bitorder='big')) + assert_raises(ValueError, np.unpackbits, a, bitorder='r') + assert_raises(TypeError, np.unpackbits, a, bitorder=10) + + + +def test_unpackbits_empty(): + a = np.empty((0,), dtype=np.uint8) + b = np.unpackbits(a) + assert_equal(b.dtype, np.uint8) + assert_array_equal(b, np.empty((0,))) + + +def test_unpackbits_empty_with_axis(): + # Lists of packed shapes for different axes and unpacked shapes. + shapes = [ + ([(0,)], (0,)), + ([(2, 24, 0), (16, 3, 0), (16, 24, 0)], (16, 24, 0)), + ([(2, 0, 24), (16, 0, 24), (16, 0, 3)], (16, 0, 24)), + ([(0, 16, 24), (0, 2, 24), (0, 16, 3)], (0, 16, 24)), + ([(3, 0, 0), (24, 0, 0), (24, 0, 0)], (24, 0, 0)), + ([(0, 24, 0), (0, 3, 0), (0, 24, 0)], (0, 24, 0)), + ([(0, 0, 24), (0, 0, 24), (0, 0, 3)], (0, 0, 24)), + ([(0, 0, 0), (0, 0, 0), (0, 0, 0)], (0, 0, 0)), + ] + for in_shapes, out_shape in shapes: + for ax, in_shape in enumerate(in_shapes): + a = np.empty(in_shape, dtype=np.uint8) + b = np.unpackbits(a, axis=ax) + assert_equal(b.dtype, np.uint8) + assert_equal(b.shape, out_shape) + + +def test_unpackbits_large(): + # test all possible numbers via comparison to already tested packbits + d = np.arange(277, dtype=np.uint8) + assert_array_equal(np.packbits(np.unpackbits(d)), d) + assert_array_equal(np.packbits(np.unpackbits(d[::2])), d[::2]) + d = np.tile(d, (3, 1)) + assert_array_equal(np.packbits(np.unpackbits(d, axis=1), axis=1), d) + d = d.T.copy() + assert_array_equal(np.packbits(np.unpackbits(d, axis=0), axis=0), d) + + +class TestCount(): + x = np.array([ + [1, 0, 1, 0, 0, 1, 0], + [0, 1, 1, 1, 0, 0, 0], + [0, 0, 1, 0, 0, 1, 1], + [1, 1, 0, 0, 0, 1, 1], + [1, 0, 1, 0, 1, 0, 1], + [0, 0, 1, 1, 1, 0, 0], + [0, 1, 0, 1, 0, 1, 0], + ], dtype=np.uint8) + padded1 = np.zeros(57, dtype=np.uint8) + padded1[:49] = x.ravel() + padded1b = np.zeros(57, dtype=np.uint8) + padded1b[:49] = x[::-1].copy().ravel() + padded2 = np.zeros((9, 9), dtype=np.uint8) + padded2[:7, :7] = x + + @pytest.mark.parametrize('bitorder', ('little', 'big')) + @pytest.mark.parametrize('count', chain(range(58), range(-1, -57, -1))) + def test_roundtrip(self, bitorder, count): + if count < 0: + # one extra zero of padding + cutoff = count - 1 + else: + cutoff = count + # test complete invertibility of packbits and unpackbits with count + packed = np.packbits(self.x, bitorder=bitorder) + unpacked = np.unpackbits(packed, count=count, bitorder=bitorder) + assert_equal(unpacked.dtype, np.uint8) + assert_array_equal(unpacked, self.padded1[:cutoff]) + + @pytest.mark.parametrize('kwargs', [ + {}, {'count': None}, + ]) + def test_count(self, kwargs): + packed = np.packbits(self.x) + unpacked = np.unpackbits(packed, **kwargs) + assert_equal(unpacked.dtype, np.uint8) + assert_array_equal(unpacked, self.padded1[:-1]) + + @pytest.mark.parametrize('bitorder', ('little', 'big')) + # delta==-1 when count<0 because one extra zero of padding + @pytest.mark.parametrize('count', chain(range(8), range(-1, -9, -1))) + def test_roundtrip_axis(self, bitorder, count): + if count < 0: + # one extra zero of padding + cutoff = count - 1 + else: + cutoff = count + packed0 = np.packbits(self.x, axis=0, bitorder=bitorder) + unpacked0 = np.unpackbits(packed0, axis=0, count=count, + bitorder=bitorder) + assert_equal(unpacked0.dtype, np.uint8) + assert_array_equal(unpacked0, self.padded2[:cutoff, :self.x.shape[1]]) + + packed1 = np.packbits(self.x, axis=1, bitorder=bitorder) + unpacked1 = np.unpackbits(packed1, axis=1, count=count, + bitorder=bitorder) + assert_equal(unpacked1.dtype, np.uint8) + assert_array_equal(unpacked1, self.padded2[:self.x.shape[0], :cutoff]) + + @pytest.mark.parametrize('kwargs', [ + {}, {'count': None}, + {'bitorder' : 'little'}, + {'bitorder': 'little', 'count': None}, + {'bitorder' : 'big'}, + {'bitorder': 'big', 'count': None}, + ]) + def test_axis_count(self, kwargs): + packed0 = np.packbits(self.x, axis=0) + unpacked0 = np.unpackbits(packed0, axis=0, **kwargs) + assert_equal(unpacked0.dtype, np.uint8) + if kwargs.get('bitorder', 'big') == 'big': + assert_array_equal(unpacked0, self.padded2[:-1, :self.x.shape[1]]) + else: + assert_array_equal(unpacked0[::-1, :], self.padded2[:-1, :self.x.shape[1]]) + + packed1 = np.packbits(self.x, axis=1) + unpacked1 = np.unpackbits(packed1, axis=1, **kwargs) + assert_equal(unpacked1.dtype, np.uint8) + if kwargs.get('bitorder', 'big') == 'big': + assert_array_equal(unpacked1, self.padded2[:self.x.shape[0], :-1]) + else: + assert_array_equal(unpacked1[:, ::-1], self.padded2[:self.x.shape[0], :-1]) + + def test_bad_count(self): + packed0 = np.packbits(self.x, axis=0) + assert_raises(ValueError, np.unpackbits, packed0, axis=0, count=-9) + packed1 = np.packbits(self.x, axis=1) + assert_raises(ValueError, np.unpackbits, packed1, axis=1, count=-9) + packed = np.packbits(self.x) + assert_raises(ValueError, np.unpackbits, packed, count=-57) diff --git a/venv/Lib/site-packages/numpy/lib/tests/test_polynomial.py b/venv/Lib/site-packages/numpy/lib/tests/test_polynomial.py new file mode 100644 index 0000000..6c3e4fa --- /dev/null +++ b/venv/Lib/site-packages/numpy/lib/tests/test_polynomial.py @@ -0,0 +1,282 @@ +import numpy as np +from numpy.testing import ( + assert_, assert_equal, assert_array_equal, assert_almost_equal, + assert_array_almost_equal, assert_raises, assert_allclose + ) + + +class TestPolynomial: + def test_poly1d_str_and_repr(self): + p = np.poly1d([1., 2, 3]) + assert_equal(repr(p), 'poly1d([1., 2., 3.])') + assert_equal(str(p), + ' 2\n' + '1 x + 2 x + 3') + + q = np.poly1d([3., 2, 1]) + assert_equal(repr(q), 'poly1d([3., 2., 1.])') + assert_equal(str(q), + ' 2\n' + '3 x + 2 x + 1') + + r = np.poly1d([1.89999 + 2j, -3j, -5.12345678, 2 + 1j]) + assert_equal(str(r), + ' 3 2\n' + '(1.9 + 2j) x - 3j x - 5.123 x + (2 + 1j)') + + assert_equal(str(np.poly1d([-3, -2, -1])), + ' 2\n' + '-3 x - 2 x - 1') + + def test_poly1d_resolution(self): + p = np.poly1d([1., 2, 3]) + q = np.poly1d([3., 2, 1]) + assert_equal(p(0), 3.0) + assert_equal(p(5), 38.0) + assert_equal(q(0), 1.0) + assert_equal(q(5), 86.0) + + def test_poly1d_math(self): + # here we use some simple coeffs to make calculations easier + p = np.poly1d([1., 2, 4]) + q = np.poly1d([4., 2, 1]) + assert_equal(p/q, (np.poly1d([0.25]), np.poly1d([1.5, 3.75]))) + assert_equal(p.integ(), np.poly1d([1/3, 1., 4., 0.])) + assert_equal(p.integ(1), np.poly1d([1/3, 1., 4., 0.])) + + p = np.poly1d([1., 2, 3]) + q = np.poly1d([3., 2, 1]) + assert_equal(p * q, np.poly1d([3., 8., 14., 8., 3.])) + assert_equal(p + q, np.poly1d([4., 4., 4.])) + assert_equal(p - q, np.poly1d([-2., 0., 2.])) + assert_equal(p ** 4, np.poly1d([1., 8., 36., 104., 214., 312., 324., 216., 81.])) + assert_equal(p(q), np.poly1d([9., 12., 16., 8., 6.])) + assert_equal(q(p), np.poly1d([3., 12., 32., 40., 34.])) + assert_equal(p.deriv(), np.poly1d([2., 2.])) + assert_equal(p.deriv(2), np.poly1d([2.])) + assert_equal(np.polydiv(np.poly1d([1, 0, -1]), np.poly1d([1, 1])), + (np.poly1d([1., -1.]), np.poly1d([0.]))) + + def test_poly1d_misc(self): + p = np.poly1d([1., 2, 3]) + assert_equal(np.asarray(p), np.array([1., 2., 3.])) + assert_equal(len(p), 2) + assert_equal((p[0], p[1], p[2], p[3]), (3.0, 2.0, 1.0, 0)) + + def test_poly1d_variable_arg(self): + q = np.poly1d([1., 2, 3], variable='y') + assert_equal(str(q), + ' 2\n' + '1 y + 2 y + 3') + q = np.poly1d([1., 2, 3], variable='lambda') + assert_equal(str(q), + ' 2\n' + '1 lambda + 2 lambda + 3') + + def test_poly(self): + assert_array_almost_equal(np.poly([3, -np.sqrt(2), np.sqrt(2)]), + [1, -3, -2, 6]) + + # From matlab docs + A = [[1, 2, 3], [4, 5, 6], [7, 8, 0]] + assert_array_almost_equal(np.poly(A), [1, -6, -72, -27]) + + # Should produce real output for perfect conjugates + assert_(np.isrealobj(np.poly([+1.082j, +2.613j, -2.613j, -1.082j]))) + assert_(np.isrealobj(np.poly([0+1j, -0+-1j, 1+2j, + 1-2j, 1.+3.5j, 1-3.5j]))) + assert_(np.isrealobj(np.poly([1j, -1j, 1+2j, 1-2j, 1+3j, 1-3.j]))) + assert_(np.isrealobj(np.poly([1j, -1j, 1+2j, 1-2j]))) + assert_(np.isrealobj(np.poly([1j, -1j, 2j, -2j]))) + assert_(np.isrealobj(np.poly([1j, -1j]))) + assert_(np.isrealobj(np.poly([1, -1]))) + + assert_(np.iscomplexobj(np.poly([1j, -1.0000001j]))) + + np.random.seed(42) + a = np.random.randn(100) + 1j*np.random.randn(100) + assert_(np.isrealobj(np.poly(np.concatenate((a, np.conjugate(a)))))) + + def test_roots(self): + assert_array_equal(np.roots([1, 0, 0]), [0, 0]) + + def test_str_leading_zeros(self): + p = np.poly1d([4, 3, 2, 1]) + p[3] = 0 + assert_equal(str(p), + " 2\n" + "3 x + 2 x + 1") + + p = np.poly1d([1, 2]) + p[0] = 0 + p[1] = 0 + assert_equal(str(p), " \n0") + + def test_polyfit(self): + c = np.array([3., 2., 1.]) + x = np.linspace(0, 2, 7) + y = np.polyval(c, x) + err = [1, -1, 1, -1, 1, -1, 1] + weights = np.arange(8, 1, -1)**2/7.0 + + # Check exception when too few points for variance estimate. Note that + # the estimate requires the number of data points to exceed + # degree + 1 + assert_raises(ValueError, np.polyfit, + [1], [1], deg=0, cov=True) + + # check 1D case + m, cov = np.polyfit(x, y+err, 2, cov=True) + est = [3.8571, 0.2857, 1.619] + assert_almost_equal(est, m, decimal=4) + val0 = [[ 1.4694, -2.9388, 0.8163], + [-2.9388, 6.3673, -2.1224], + [ 0.8163, -2.1224, 1.161 ]] + assert_almost_equal(val0, cov, decimal=4) + + m2, cov2 = np.polyfit(x, y+err, 2, w=weights, cov=True) + assert_almost_equal([4.8927, -1.0177, 1.7768], m2, decimal=4) + val = [[ 4.3964, -5.0052, 0.4878], + [-5.0052, 6.8067, -0.9089], + [ 0.4878, -0.9089, 0.3337]] + assert_almost_equal(val, cov2, decimal=4) + + m3, cov3 = np.polyfit(x, y+err, 2, w=weights, cov="unscaled") + assert_almost_equal([4.8927, -1.0177, 1.7768], m3, decimal=4) + val = [[ 0.1473, -0.1677, 0.0163], + [-0.1677, 0.228 , -0.0304], + [ 0.0163, -0.0304, 0.0112]] + assert_almost_equal(val, cov3, decimal=4) + + # check 2D (n,1) case + y = y[:, np.newaxis] + c = c[:, np.newaxis] + assert_almost_equal(c, np.polyfit(x, y, 2)) + # check 2D (n,2) case + yy = np.concatenate((y, y), axis=1) + cc = np.concatenate((c, c), axis=1) + assert_almost_equal(cc, np.polyfit(x, yy, 2)) + + m, cov = np.polyfit(x, yy + np.array(err)[:, np.newaxis], 2, cov=True) + assert_almost_equal(est, m[:, 0], decimal=4) + assert_almost_equal(est, m[:, 1], decimal=4) + assert_almost_equal(val0, cov[:, :, 0], decimal=4) + assert_almost_equal(val0, cov[:, :, 1], decimal=4) + + # check order 1 (deg=0) case, were the analytic results are simple + np.random.seed(123) + y = np.random.normal(size=(4, 10000)) + mean, cov = np.polyfit(np.zeros(y.shape[0]), y, deg=0, cov=True) + # Should get sigma_mean = sigma/sqrt(N) = 1./sqrt(4) = 0.5. + assert_allclose(mean.std(), 0.5, atol=0.01) + assert_allclose(np.sqrt(cov.mean()), 0.5, atol=0.01) + # Without scaling, since reduced chi2 is 1, the result should be the same. + mean, cov = np.polyfit(np.zeros(y.shape[0]), y, w=np.ones(y.shape[0]), + deg=0, cov="unscaled") + assert_allclose(mean.std(), 0.5, atol=0.01) + assert_almost_equal(np.sqrt(cov.mean()), 0.5) + # If we estimate our errors wrong, no change with scaling: + w = np.full(y.shape[0], 1./0.5) + mean, cov = np.polyfit(np.zeros(y.shape[0]), y, w=w, deg=0, cov=True) + assert_allclose(mean.std(), 0.5, atol=0.01) + assert_allclose(np.sqrt(cov.mean()), 0.5, atol=0.01) + # But if we do not scale, our estimate for the error in the mean will + # differ. + mean, cov = np.polyfit(np.zeros(y.shape[0]), y, w=w, deg=0, cov="unscaled") + assert_allclose(mean.std(), 0.5, atol=0.01) + assert_almost_equal(np.sqrt(cov.mean()), 0.25) + + def test_objects(self): + from decimal import Decimal + p = np.poly1d([Decimal('4.0'), Decimal('3.0'), Decimal('2.0')]) + p2 = p * Decimal('1.333333333333333') + assert_(p2[1] == Decimal("3.9999999999999990")) + p2 = p.deriv() + assert_(p2[1] == Decimal('8.0')) + p2 = p.integ() + assert_(p2[3] == Decimal("1.333333333333333333333333333")) + assert_(p2[2] == Decimal('1.5')) + assert_(np.issubdtype(p2.coeffs.dtype, np.object_)) + p = np.poly([Decimal(1), Decimal(2)]) + assert_equal(np.poly([Decimal(1), Decimal(2)]), + [1, Decimal(-3), Decimal(2)]) + + def test_complex(self): + p = np.poly1d([3j, 2j, 1j]) + p2 = p.integ() + assert_((p2.coeffs == [1j, 1j, 1j, 0]).all()) + p2 = p.deriv() + assert_((p2.coeffs == [6j, 2j]).all()) + + def test_integ_coeffs(self): + p = np.poly1d([3, 2, 1]) + p2 = p.integ(3, k=[9, 7, 6]) + assert_( + (p2.coeffs == [1/4./5., 1/3./4., 1/2./3., 9/1./2., 7, 6]).all()) + + def test_zero_dims(self): + try: + np.poly(np.zeros((0, 0))) + except ValueError: + pass + + def test_poly_int_overflow(self): + """ + Regression test for gh-5096. + """ + v = np.arange(1, 21) + assert_almost_equal(np.poly(v), np.poly(np.diag(v))) + + def test_zero_poly_dtype(self): + """ + Regression test for gh-16354. + """ + z = np.array([0, 0, 0]) + p = np.poly1d(z.astype(np.int64)) + assert_equal(p.coeffs.dtype, np.int64) + + p = np.poly1d(z.astype(np.float32)) + assert_equal(p.coeffs.dtype, np.float32) + + p = np.poly1d(z.astype(np.complex64)) + assert_equal(p.coeffs.dtype, np.complex64) + + def test_poly_eq(self): + p = np.poly1d([1, 2, 3]) + p2 = np.poly1d([1, 2, 4]) + assert_equal(p == None, False) + assert_equal(p != None, True) + assert_equal(p == p, True) + assert_equal(p == p2, False) + assert_equal(p != p2, True) + + def test_polydiv(self): + b = np.poly1d([2, 6, 6, 1]) + a = np.poly1d([-1j, (1+2j), -(2+1j), 1]) + q, r = np.polydiv(b, a) + assert_equal(q.coeffs.dtype, np.complex128) + assert_equal(r.coeffs.dtype, np.complex128) + assert_equal(q*a + r, b) + + c = [1, 2, 3] + d = np.poly1d([1, 2, 3]) + s, t = np.polydiv(c, d) + assert isinstance(s, np.poly1d) + assert isinstance(t, np.poly1d) + u, v = np.polydiv(d, c) + assert isinstance(u, np.poly1d) + assert isinstance(v, np.poly1d) + + def test_poly_coeffs_mutable(self): + """ Coefficients should be modifiable """ + p = np.poly1d([1, 2, 3]) + + p.coeffs += 1 + assert_equal(p.coeffs, [2, 3, 4]) + + p.coeffs[2] += 10 + assert_equal(p.coeffs, [2, 3, 14]) + + # this never used to be allowed - let's not add features to deprecated + # APIs + assert_raises(AttributeError, setattr, p, 'coeffs', np.array(1)) diff --git a/venv/Lib/site-packages/numpy/lib/tests/test_recfunctions.py b/venv/Lib/site-packages/numpy/lib/tests/test_recfunctions.py new file mode 100644 index 0000000..2f3c14d --- /dev/null +++ b/venv/Lib/site-packages/numpy/lib/tests/test_recfunctions.py @@ -0,0 +1,979 @@ +import pytest + +import numpy as np +import numpy.ma as ma +from numpy.ma.mrecords import MaskedRecords +from numpy.ma.testutils import assert_equal +from numpy.testing import assert_, assert_raises +from numpy.lib.recfunctions import ( + drop_fields, rename_fields, get_fieldstructure, recursive_fill_fields, + find_duplicates, merge_arrays, append_fields, stack_arrays, join_by, + repack_fields, unstructured_to_structured, structured_to_unstructured, + apply_along_fields, require_fields, assign_fields_by_name) +get_fieldspec = np.lib.recfunctions._get_fieldspec +get_names = np.lib.recfunctions.get_names +get_names_flat = np.lib.recfunctions.get_names_flat +zip_descr = np.lib.recfunctions._zip_descr +zip_dtype = np.lib.recfunctions._zip_dtype + + +class TestRecFunctions: + # Misc tests + + def setup(self): + x = np.array([1, 2, ]) + y = np.array([10, 20, 30]) + z = np.array([('A', 1.), ('B', 2.)], + dtype=[('A', '|S3'), ('B', float)]) + w = np.array([(1, (2, 3.0)), (4, (5, 6.0))], + dtype=[('a', int), ('b', [('ba', float), ('bb', int)])]) + self.data = (w, x, y, z) + + def test_zip_descr(self): + # Test zip_descr + (w, x, y, z) = self.data + + # Std array + test = zip_descr((x, x), flatten=True) + assert_equal(test, + np.dtype([('', int), ('', int)])) + test = zip_descr((x, x), flatten=False) + assert_equal(test, + np.dtype([('', int), ('', int)])) + + # Std & flexible-dtype + test = zip_descr((x, z), flatten=True) + assert_equal(test, + np.dtype([('', int), ('A', '|S3'), ('B', float)])) + test = zip_descr((x, z), flatten=False) + assert_equal(test, + np.dtype([('', int), + ('', [('A', '|S3'), ('B', float)])])) + + # Standard & nested dtype + test = zip_descr((x, w), flatten=True) + assert_equal(test, + np.dtype([('', int), + ('a', int), + ('ba', float), ('bb', int)])) + test = zip_descr((x, w), flatten=False) + assert_equal(test, + np.dtype([('', int), + ('', [('a', int), + ('b', [('ba', float), ('bb', int)])])])) + + def test_drop_fields(self): + # Test drop_fields + a = np.array([(1, (2, 3.0)), (4, (5, 6.0))], + dtype=[('a', int), ('b', [('ba', float), ('bb', int)])]) + + # A basic field + test = drop_fields(a, 'a') + control = np.array([((2, 3.0),), ((5, 6.0),)], + dtype=[('b', [('ba', float), ('bb', int)])]) + assert_equal(test, control) + + # Another basic field (but nesting two fields) + test = drop_fields(a, 'b') + control = np.array([(1,), (4,)], dtype=[('a', int)]) + assert_equal(test, control) + + # A nested sub-field + test = drop_fields(a, ['ba', ]) + control = np.array([(1, (3.0,)), (4, (6.0,))], + dtype=[('a', int), ('b', [('bb', int)])]) + assert_equal(test, control) + + # All the nested sub-field from a field: zap that field + test = drop_fields(a, ['ba', 'bb']) + control = np.array([(1,), (4,)], dtype=[('a', int)]) + assert_equal(test, control) + + # dropping all fields results in an array with no fields + test = drop_fields(a, ['a', 'b']) + control = np.array([(), ()], dtype=[]) + assert_equal(test, control) + + def test_rename_fields(self): + # Test rename fields + a = np.array([(1, (2, [3.0, 30.])), (4, (5, [6.0, 60.]))], + dtype=[('a', int), + ('b', [('ba', float), ('bb', (float, 2))])]) + test = rename_fields(a, {'a': 'A', 'bb': 'BB'}) + newdtype = [('A', int), ('b', [('ba', float), ('BB', (float, 2))])] + control = a.view(newdtype) + assert_equal(test.dtype, newdtype) + assert_equal(test, control) + + def test_get_names(self): + # Test get_names + ndtype = np.dtype([('A', '|S3'), ('B', float)]) + test = get_names(ndtype) + assert_equal(test, ('A', 'B')) + + ndtype = np.dtype([('a', int), ('b', [('ba', float), ('bb', int)])]) + test = get_names(ndtype) + assert_equal(test, ('a', ('b', ('ba', 'bb')))) + + ndtype = np.dtype([('a', int), ('b', [])]) + test = get_names(ndtype) + assert_equal(test, ('a', ('b', ()))) + + ndtype = np.dtype([]) + test = get_names(ndtype) + assert_equal(test, ()) + + def test_get_names_flat(self): + # Test get_names_flat + ndtype = np.dtype([('A', '|S3'), ('B', float)]) + test = get_names_flat(ndtype) + assert_equal(test, ('A', 'B')) + + ndtype = np.dtype([('a', int), ('b', [('ba', float), ('bb', int)])]) + test = get_names_flat(ndtype) + assert_equal(test, ('a', 'b', 'ba', 'bb')) + + ndtype = np.dtype([('a', int), ('b', [])]) + test = get_names_flat(ndtype) + assert_equal(test, ('a', 'b')) + + ndtype = np.dtype([]) + test = get_names_flat(ndtype) + assert_equal(test, ()) + + def test_get_fieldstructure(self): + # Test get_fieldstructure + + # No nested fields + ndtype = np.dtype([('A', '|S3'), ('B', float)]) + test = get_fieldstructure(ndtype) + assert_equal(test, {'A': [], 'B': []}) + + # One 1-nested field + ndtype = np.dtype([('A', int), ('B', [('BA', float), ('BB', '|S1')])]) + test = get_fieldstructure(ndtype) + assert_equal(test, {'A': [], 'B': [], 'BA': ['B', ], 'BB': ['B']}) + + # One 2-nested fields + ndtype = np.dtype([('A', int), + ('B', [('BA', int), + ('BB', [('BBA', int), ('BBB', int)])])]) + test = get_fieldstructure(ndtype) + control = {'A': [], 'B': [], 'BA': ['B'], 'BB': ['B'], + 'BBA': ['B', 'BB'], 'BBB': ['B', 'BB']} + assert_equal(test, control) + + # 0 fields + ndtype = np.dtype([]) + test = get_fieldstructure(ndtype) + assert_equal(test, {}) + + def test_find_duplicates(self): + # Test find_duplicates + a = ma.array([(2, (2., 'B')), (1, (2., 'B')), (2, (2., 'B')), + (1, (1., 'B')), (2, (2., 'B')), (2, (2., 'C'))], + mask=[(0, (0, 0)), (0, (0, 0)), (0, (0, 0)), + (0, (0, 0)), (1, (0, 0)), (0, (1, 0))], + dtype=[('A', int), ('B', [('BA', float), ('BB', '|S1')])]) + + test = find_duplicates(a, ignoremask=False, return_index=True) + control = [0, 2] + assert_equal(sorted(test[-1]), control) + assert_equal(test[0], a[test[-1]]) + + test = find_duplicates(a, key='A', return_index=True) + control = [0, 1, 2, 3, 5] + assert_equal(sorted(test[-1]), control) + assert_equal(test[0], a[test[-1]]) + + test = find_duplicates(a, key='B', return_index=True) + control = [0, 1, 2, 4] + assert_equal(sorted(test[-1]), control) + assert_equal(test[0], a[test[-1]]) + + test = find_duplicates(a, key='BA', return_index=True) + control = [0, 1, 2, 4] + assert_equal(sorted(test[-1]), control) + assert_equal(test[0], a[test[-1]]) + + test = find_duplicates(a, key='BB', return_index=True) + control = [0, 1, 2, 3, 4] + assert_equal(sorted(test[-1]), control) + assert_equal(test[0], a[test[-1]]) + + def test_find_duplicates_ignoremask(self): + # Test the ignoremask option of find_duplicates + ndtype = [('a', int)] + a = ma.array([1, 1, 1, 2, 2, 3, 3], + mask=[0, 0, 1, 0, 0, 0, 1]).view(ndtype) + test = find_duplicates(a, ignoremask=True, return_index=True) + control = [0, 1, 3, 4] + assert_equal(sorted(test[-1]), control) + assert_equal(test[0], a[test[-1]]) + + test = find_duplicates(a, ignoremask=False, return_index=True) + control = [0, 1, 2, 3, 4, 6] + assert_equal(sorted(test[-1]), control) + assert_equal(test[0], a[test[-1]]) + + def test_repack_fields(self): + dt = np.dtype('u1,f4,i8', align=True) + a = np.zeros(2, dtype=dt) + + assert_equal(repack_fields(dt), np.dtype('u1,f4,i8')) + assert_equal(repack_fields(a).itemsize, 13) + assert_equal(repack_fields(repack_fields(dt), align=True), dt) + + # make sure type is preserved + dt = np.dtype((np.record, dt)) + assert_(repack_fields(dt).type is np.record) + + def test_structured_to_unstructured(self): + a = np.zeros(4, dtype=[('a', 'i4'), ('b', 'f4,u2'), ('c', 'f4', 2)]) + out = structured_to_unstructured(a) + assert_equal(out, np.zeros((4,5), dtype='f8')) + + b = np.array([(1, 2, 5), (4, 5, 7), (7, 8 ,11), (10, 11, 12)], + dtype=[('x', 'i4'), ('y', 'f4'), ('z', 'f8')]) + out = np.mean(structured_to_unstructured(b[['x', 'z']]), axis=-1) + assert_equal(out, np.array([ 3. , 5.5, 9. , 11. ])) + out = np.mean(structured_to_unstructured(b[['x']]), axis=-1) + assert_equal(out, np.array([ 1. , 4. , 7. , 10. ])) + + c = np.arange(20).reshape((4,5)) + out = unstructured_to_structured(c, a.dtype) + want = np.array([( 0, ( 1., 2), [ 3., 4.]), + ( 5, ( 6., 7), [ 8., 9.]), + (10, (11., 12), [13., 14.]), + (15, (16., 17), [18., 19.])], + dtype=[('a', 'i4'), + ('b', [('f0', 'f4'), ('f1', 'u2')]), + ('c', 'f4', (2,))]) + assert_equal(out, want) + + d = np.array([(1, 2, 5), (4, 5, 7), (7, 8 ,11), (10, 11, 12)], + dtype=[('x', 'i4'), ('y', 'f4'), ('z', 'f8')]) + assert_equal(apply_along_fields(np.mean, d), + np.array([ 8.0/3, 16.0/3, 26.0/3, 11. ])) + assert_equal(apply_along_fields(np.mean, d[['x', 'z']]), + np.array([ 3. , 5.5, 9. , 11. ])) + + # check that for uniform field dtypes we get a view, not a copy: + d = np.array([(1, 2, 5), (4, 5, 7), (7, 8 ,11), (10, 11, 12)], + dtype=[('x', 'i4'), ('y', 'i4'), ('z', 'i4')]) + dd = structured_to_unstructured(d) + ddd = unstructured_to_structured(dd, d.dtype) + assert_(dd.base is d) + assert_(ddd.base is d) + + # including uniform fields with subarrays unpacked + d = np.array([(1, [2, 3], [[ 4, 5], [ 6, 7]]), + (8, [9, 10], [[11, 12], [13, 14]])], + dtype=[('x0', 'i4'), ('x1', ('i4', 2)), + ('x2', ('i4', (2, 2)))]) + dd = structured_to_unstructured(d) + ddd = unstructured_to_structured(dd, d.dtype) + assert_(dd.base is d) + assert_(ddd.base is d) + + # test that nested fields with identical names don't break anything + point = np.dtype([('x', int), ('y', int)]) + triangle = np.dtype([('a', point), ('b', point), ('c', point)]) + arr = np.zeros(10, triangle) + res = structured_to_unstructured(arr, dtype=int) + assert_equal(res, np.zeros((10, 6), dtype=int)) + + + # test nested combinations of subarrays and structured arrays, gh-13333 + def subarray(dt, shape): + return np.dtype((dt, shape)) + + def structured(*dts): + return np.dtype([('x{}'.format(i), dt) for i, dt in enumerate(dts)]) + + def inspect(dt, dtype=None): + arr = np.zeros((), dt) + ret = structured_to_unstructured(arr, dtype=dtype) + backarr = unstructured_to_structured(ret, dt) + return ret.shape, ret.dtype, backarr.dtype + + dt = structured(subarray(structured(np.int32, np.int32), 3)) + assert_equal(inspect(dt), ((6,), np.int32, dt)) + + dt = structured(subarray(subarray(np.int32, 2), 2)) + assert_equal(inspect(dt), ((4,), np.int32, dt)) + + dt = structured(np.int32) + assert_equal(inspect(dt), ((1,), np.int32, dt)) + + dt = structured(np.int32, subarray(subarray(np.int32, 2), 2)) + assert_equal(inspect(dt), ((5,), np.int32, dt)) + + dt = structured() + assert_raises(ValueError, structured_to_unstructured, np.zeros(3, dt)) + + # these currently don't work, but we may make it work in the future + assert_raises(NotImplementedError, structured_to_unstructured, + np.zeros(3, dt), dtype=np.int32) + assert_raises(NotImplementedError, unstructured_to_structured, + np.zeros((3,0), dtype=np.int32)) + + def test_field_assignment_by_name(self): + a = np.ones(2, dtype=[('a', 'i4'), ('b', 'f8'), ('c', 'u1')]) + newdt = [('b', 'f4'), ('c', 'u1')] + + assert_equal(require_fields(a, newdt), np.ones(2, newdt)) + + b = np.array([(1,2), (3,4)], dtype=newdt) + assign_fields_by_name(a, b, zero_unassigned=False) + assert_equal(a, np.array([(1,1,2),(1,3,4)], dtype=a.dtype)) + assign_fields_by_name(a, b) + assert_equal(a, np.array([(0,1,2),(0,3,4)], dtype=a.dtype)) + + # test nested fields + a = np.ones(2, dtype=[('a', [('b', 'f8'), ('c', 'u1')])]) + newdt = [('a', [('c', 'u1')])] + assert_equal(require_fields(a, newdt), np.ones(2, newdt)) + b = np.array([((2,),), ((3,),)], dtype=newdt) + assign_fields_by_name(a, b, zero_unassigned=False) + assert_equal(a, np.array([((1,2),), ((1,3),)], dtype=a.dtype)) + assign_fields_by_name(a, b) + assert_equal(a, np.array([((0,2),), ((0,3),)], dtype=a.dtype)) + + # test unstructured code path for 0d arrays + a, b = np.array(3), np.array(0) + assign_fields_by_name(b, a) + assert_equal(b[()], 3) + + +class TestRecursiveFillFields: + # Test recursive_fill_fields. + def test_simple_flexible(self): + # Test recursive_fill_fields on flexible-array + a = np.array([(1, 10.), (2, 20.)], dtype=[('A', int), ('B', float)]) + b = np.zeros((3,), dtype=a.dtype) + test = recursive_fill_fields(a, b) + control = np.array([(1, 10.), (2, 20.), (0, 0.)], + dtype=[('A', int), ('B', float)]) + assert_equal(test, control) + + def test_masked_flexible(self): + # Test recursive_fill_fields on masked flexible-array + a = ma.array([(1, 10.), (2, 20.)], mask=[(0, 1), (1, 0)], + dtype=[('A', int), ('B', float)]) + b = ma.zeros((3,), dtype=a.dtype) + test = recursive_fill_fields(a, b) + control = ma.array([(1, 10.), (2, 20.), (0, 0.)], + mask=[(0, 1), (1, 0), (0, 0)], + dtype=[('A', int), ('B', float)]) + assert_equal(test, control) + + +class TestMergeArrays: + # Test merge_arrays + + def setup(self): + x = np.array([1, 2, ]) + y = np.array([10, 20, 30]) + z = np.array( + [('A', 1.), ('B', 2.)], dtype=[('A', '|S3'), ('B', float)]) + w = np.array( + [(1, (2, 3.0, ())), (4, (5, 6.0, ()))], + dtype=[('a', int), ('b', [('ba', float), ('bb', int), ('bc', [])])]) + self.data = (w, x, y, z) + + def test_solo(self): + # Test merge_arrays on a single array. + (_, x, _, z) = self.data + + test = merge_arrays(x) + control = np.array([(1,), (2,)], dtype=[('f0', int)]) + assert_equal(test, control) + test = merge_arrays((x,)) + assert_equal(test, control) + + test = merge_arrays(z, flatten=False) + assert_equal(test, z) + test = merge_arrays(z, flatten=True) + assert_equal(test, z) + + def test_solo_w_flatten(self): + # Test merge_arrays on a single array w & w/o flattening + w = self.data[0] + test = merge_arrays(w, flatten=False) + assert_equal(test, w) + + test = merge_arrays(w, flatten=True) + control = np.array([(1, 2, 3.0), (4, 5, 6.0)], + dtype=[('a', int), ('ba', float), ('bb', int)]) + assert_equal(test, control) + + def test_standard(self): + # Test standard & standard + # Test merge arrays + (_, x, y, _) = self.data + test = merge_arrays((x, y), usemask=False) + control = np.array([(1, 10), (2, 20), (-1, 30)], + dtype=[('f0', int), ('f1', int)]) + assert_equal(test, control) + + test = merge_arrays((x, y), usemask=True) + control = ma.array([(1, 10), (2, 20), (-1, 30)], + mask=[(0, 0), (0, 0), (1, 0)], + dtype=[('f0', int), ('f1', int)]) + assert_equal(test, control) + assert_equal(test.mask, control.mask) + + def test_flatten(self): + # Test standard & flexible + (_, x, _, z) = self.data + test = merge_arrays((x, z), flatten=True) + control = np.array([(1, 'A', 1.), (2, 'B', 2.)], + dtype=[('f0', int), ('A', '|S3'), ('B', float)]) + assert_equal(test, control) + + test = merge_arrays((x, z), flatten=False) + control = np.array([(1, ('A', 1.)), (2, ('B', 2.))], + dtype=[('f0', int), + ('f1', [('A', '|S3'), ('B', float)])]) + assert_equal(test, control) + + def test_flatten_wflexible(self): + # Test flatten standard & nested + (w, x, _, _) = self.data + test = merge_arrays((x, w), flatten=True) + control = np.array([(1, 1, 2, 3.0), (2, 4, 5, 6.0)], + dtype=[('f0', int), + ('a', int), ('ba', float), ('bb', int)]) + assert_equal(test, control) + + test = merge_arrays((x, w), flatten=False) + controldtype = [('f0', int), + ('f1', [('a', int), + ('b', [('ba', float), ('bb', int), ('bc', [])])])] + control = np.array([(1., (1, (2, 3.0, ()))), (2, (4, (5, 6.0, ())))], + dtype=controldtype) + assert_equal(test, control) + + def test_wmasked_arrays(self): + # Test merge_arrays masked arrays + (_, x, _, _) = self.data + mx = ma.array([1, 2, 3], mask=[1, 0, 0]) + test = merge_arrays((x, mx), usemask=True) + control = ma.array([(1, 1), (2, 2), (-1, 3)], + mask=[(0, 1), (0, 0), (1, 0)], + dtype=[('f0', int), ('f1', int)]) + assert_equal(test, control) + test = merge_arrays((x, mx), usemask=True, asrecarray=True) + assert_equal(test, control) + assert_(isinstance(test, MaskedRecords)) + + def test_w_singlefield(self): + # Test single field + test = merge_arrays((np.array([1, 2]).view([('a', int)]), + np.array([10., 20., 30.])),) + control = ma.array([(1, 10.), (2, 20.), (-1, 30.)], + mask=[(0, 0), (0, 0), (1, 0)], + dtype=[('a', int), ('f1', float)]) + assert_equal(test, control) + + def test_w_shorter_flex(self): + # Test merge_arrays w/ a shorter flexndarray. + z = self.data[-1] + + # Fixme, this test looks incomplete and broken + #test = merge_arrays((z, np.array([10, 20, 30]).view([('C', int)]))) + #control = np.array([('A', 1., 10), ('B', 2., 20), ('-1', -1, 20)], + # dtype=[('A', '|S3'), ('B', float), ('C', int)]) + #assert_equal(test, control) + + # Hack to avoid pyflakes warnings about unused variables + merge_arrays((z, np.array([10, 20, 30]).view([('C', int)]))) + np.array([('A', 1., 10), ('B', 2., 20), ('-1', -1, 20)], + dtype=[('A', '|S3'), ('B', float), ('C', int)]) + + def test_singlerecord(self): + (_, x, y, z) = self.data + test = merge_arrays((x[0], y[0], z[0]), usemask=False) + control = np.array([(1, 10, ('A', 1))], + dtype=[('f0', int), + ('f1', int), + ('f2', [('A', '|S3'), ('B', float)])]) + assert_equal(test, control) + + +class TestAppendFields: + # Test append_fields + + def setup(self): + x = np.array([1, 2, ]) + y = np.array([10, 20, 30]) + z = np.array( + [('A', 1.), ('B', 2.)], dtype=[('A', '|S3'), ('B', float)]) + w = np.array([(1, (2, 3.0)), (4, (5, 6.0))], + dtype=[('a', int), ('b', [('ba', float), ('bb', int)])]) + self.data = (w, x, y, z) + + def test_append_single(self): + # Test simple case + (_, x, _, _) = self.data + test = append_fields(x, 'A', data=[10, 20, 30]) + control = ma.array([(1, 10), (2, 20), (-1, 30)], + mask=[(0, 0), (0, 0), (1, 0)], + dtype=[('f0', int), ('A', int)],) + assert_equal(test, control) + + def test_append_double(self): + # Test simple case + (_, x, _, _) = self.data + test = append_fields(x, ('A', 'B'), data=[[10, 20, 30], [100, 200]]) + control = ma.array([(1, 10, 100), (2, 20, 200), (-1, 30, -1)], + mask=[(0, 0, 0), (0, 0, 0), (1, 0, 1)], + dtype=[('f0', int), ('A', int), ('B', int)],) + assert_equal(test, control) + + def test_append_on_flex(self): + # Test append_fields on flexible type arrays + z = self.data[-1] + test = append_fields(z, 'C', data=[10, 20, 30]) + control = ma.array([('A', 1., 10), ('B', 2., 20), (-1, -1., 30)], + mask=[(0, 0, 0), (0, 0, 0), (1, 1, 0)], + dtype=[('A', '|S3'), ('B', float), ('C', int)],) + assert_equal(test, control) + + def test_append_on_nested(self): + # Test append_fields on nested fields + w = self.data[0] + test = append_fields(w, 'C', data=[10, 20, 30]) + control = ma.array([(1, (2, 3.0), 10), + (4, (5, 6.0), 20), + (-1, (-1, -1.), 30)], + mask=[( + 0, (0, 0), 0), (0, (0, 0), 0), (1, (1, 1), 0)], + dtype=[('a', int), + ('b', [('ba', float), ('bb', int)]), + ('C', int)],) + assert_equal(test, control) + + +class TestStackArrays: + # Test stack_arrays + def setup(self): + x = np.array([1, 2, ]) + y = np.array([10, 20, 30]) + z = np.array( + [('A', 1.), ('B', 2.)], dtype=[('A', '|S3'), ('B', float)]) + w = np.array([(1, (2, 3.0)), (4, (5, 6.0))], + dtype=[('a', int), ('b', [('ba', float), ('bb', int)])]) + self.data = (w, x, y, z) + + def test_solo(self): + # Test stack_arrays on single arrays + (_, x, _, _) = self.data + test = stack_arrays((x,)) + assert_equal(test, x) + assert_(test is x) + + test = stack_arrays(x) + assert_equal(test, x) + assert_(test is x) + + def test_unnamed_fields(self): + # Tests combinations of arrays w/o named fields + (_, x, y, _) = self.data + + test = stack_arrays((x, x), usemask=False) + control = np.array([1, 2, 1, 2]) + assert_equal(test, control) + + test = stack_arrays((x, y), usemask=False) + control = np.array([1, 2, 10, 20, 30]) + assert_equal(test, control) + + test = stack_arrays((y, x), usemask=False) + control = np.array([10, 20, 30, 1, 2]) + assert_equal(test, control) + + def test_unnamed_and_named_fields(self): + # Test combination of arrays w/ & w/o named fields + (_, x, _, z) = self.data + + test = stack_arrays((x, z)) + control = ma.array([(1, -1, -1), (2, -1, -1), + (-1, 'A', 1), (-1, 'B', 2)], + mask=[(0, 1, 1), (0, 1, 1), + (1, 0, 0), (1, 0, 0)], + dtype=[('f0', int), ('A', '|S3'), ('B', float)]) + assert_equal(test, control) + assert_equal(test.mask, control.mask) + + test = stack_arrays((z, x)) + control = ma.array([('A', 1, -1), ('B', 2, -1), + (-1, -1, 1), (-1, -1, 2), ], + mask=[(0, 0, 1), (0, 0, 1), + (1, 1, 0), (1, 1, 0)], + dtype=[('A', '|S3'), ('B', float), ('f2', int)]) + assert_equal(test, control) + assert_equal(test.mask, control.mask) + + test = stack_arrays((z, z, x)) + control = ma.array([('A', 1, -1), ('B', 2, -1), + ('A', 1, -1), ('B', 2, -1), + (-1, -1, 1), (-1, -1, 2), ], + mask=[(0, 0, 1), (0, 0, 1), + (0, 0, 1), (0, 0, 1), + (1, 1, 0), (1, 1, 0)], + dtype=[('A', '|S3'), ('B', float), ('f2', int)]) + assert_equal(test, control) + + def test_matching_named_fields(self): + # Test combination of arrays w/ matching field names + (_, x, _, z) = self.data + zz = np.array([('a', 10., 100.), ('b', 20., 200.), ('c', 30., 300.)], + dtype=[('A', '|S3'), ('B', float), ('C', float)]) + test = stack_arrays((z, zz)) + control = ma.array([('A', 1, -1), ('B', 2, -1), + ( + 'a', 10., 100.), ('b', 20., 200.), ('c', 30., 300.)], + dtype=[('A', '|S3'), ('B', float), ('C', float)], + mask=[(0, 0, 1), (0, 0, 1), + (0, 0, 0), (0, 0, 0), (0, 0, 0)]) + assert_equal(test, control) + assert_equal(test.mask, control.mask) + + test = stack_arrays((z, zz, x)) + ndtype = [('A', '|S3'), ('B', float), ('C', float), ('f3', int)] + control = ma.array([('A', 1, -1, -1), ('B', 2, -1, -1), + ('a', 10., 100., -1), ('b', 20., 200., -1), + ('c', 30., 300., -1), + (-1, -1, -1, 1), (-1, -1, -1, 2)], + dtype=ndtype, + mask=[(0, 0, 1, 1), (0, 0, 1, 1), + (0, 0, 0, 1), (0, 0, 0, 1), (0, 0, 0, 1), + (1, 1, 1, 0), (1, 1, 1, 0)]) + assert_equal(test, control) + assert_equal(test.mask, control.mask) + + def test_defaults(self): + # Test defaults: no exception raised if keys of defaults are not fields. + (_, _, _, z) = self.data + zz = np.array([('a', 10., 100.), ('b', 20., 200.), ('c', 30., 300.)], + dtype=[('A', '|S3'), ('B', float), ('C', float)]) + defaults = {'A': '???', 'B': -999., 'C': -9999., 'D': -99999.} + test = stack_arrays((z, zz), defaults=defaults) + control = ma.array([('A', 1, -9999.), ('B', 2, -9999.), + ( + 'a', 10., 100.), ('b', 20., 200.), ('c', 30., 300.)], + dtype=[('A', '|S3'), ('B', float), ('C', float)], + mask=[(0, 0, 1), (0, 0, 1), + (0, 0, 0), (0, 0, 0), (0, 0, 0)]) + assert_equal(test, control) + assert_equal(test.data, control.data) + assert_equal(test.mask, control.mask) + + def test_autoconversion(self): + # Tests autoconversion + adtype = [('A', int), ('B', bool), ('C', float)] + a = ma.array([(1, 2, 3)], mask=[(0, 1, 0)], dtype=adtype) + bdtype = [('A', int), ('B', float), ('C', float)] + b = ma.array([(4, 5, 6)], dtype=bdtype) + control = ma.array([(1, 2, 3), (4, 5, 6)], mask=[(0, 1, 0), (0, 0, 0)], + dtype=bdtype) + test = stack_arrays((a, b), autoconvert=True) + assert_equal(test, control) + assert_equal(test.mask, control.mask) + with assert_raises(TypeError): + stack_arrays((a, b), autoconvert=False) + + def test_checktitles(self): + # Test using titles in the field names + adtype = [(('a', 'A'), int), (('b', 'B'), bool), (('c', 'C'), float)] + a = ma.array([(1, 2, 3)], mask=[(0, 1, 0)], dtype=adtype) + bdtype = [(('a', 'A'), int), (('b', 'B'), bool), (('c', 'C'), float)] + b = ma.array([(4, 5, 6)], dtype=bdtype) + test = stack_arrays((a, b)) + control = ma.array([(1, 2, 3), (4, 5, 6)], mask=[(0, 1, 0), (0, 0, 0)], + dtype=bdtype) + assert_equal(test, control) + assert_equal(test.mask, control.mask) + + def test_subdtype(self): + z = np.array([ + ('A', 1), ('B', 2) + ], dtype=[('A', '|S3'), ('B', float, (1,))]) + zz = np.array([ + ('a', [10.], 100.), ('b', [20.], 200.), ('c', [30.], 300.) + ], dtype=[('A', '|S3'), ('B', float, (1,)), ('C', float)]) + + res = stack_arrays((z, zz)) + expected = ma.array( + data=[ + (b'A', [1.0], 0), + (b'B', [2.0], 0), + (b'a', [10.0], 100.0), + (b'b', [20.0], 200.0), + (b'c', [30.0], 300.0)], + mask=[ + (False, [False], True), + (False, [False], True), + (False, [False], False), + (False, [False], False), + (False, [False], False) + ], + dtype=zz.dtype + ) + assert_equal(res.dtype, expected.dtype) + assert_equal(res, expected) + assert_equal(res.mask, expected.mask) + + +class TestJoinBy: + def setup(self): + self.a = np.array(list(zip(np.arange(10), np.arange(50, 60), + np.arange(100, 110))), + dtype=[('a', int), ('b', int), ('c', int)]) + self.b = np.array(list(zip(np.arange(5, 15), np.arange(65, 75), + np.arange(100, 110))), + dtype=[('a', int), ('b', int), ('d', int)]) + + def test_inner_join(self): + # Basic test of join_by + a, b = self.a, self.b + + test = join_by('a', a, b, jointype='inner') + control = np.array([(5, 55, 65, 105, 100), (6, 56, 66, 106, 101), + (7, 57, 67, 107, 102), (8, 58, 68, 108, 103), + (9, 59, 69, 109, 104)], + dtype=[('a', int), ('b1', int), ('b2', int), + ('c', int), ('d', int)]) + assert_equal(test, control) + + def test_join(self): + a, b = self.a, self.b + + # Fixme, this test is broken + #test = join_by(('a', 'b'), a, b) + #control = np.array([(5, 55, 105, 100), (6, 56, 106, 101), + # (7, 57, 107, 102), (8, 58, 108, 103), + # (9, 59, 109, 104)], + # dtype=[('a', int), ('b', int), + # ('c', int), ('d', int)]) + #assert_equal(test, control) + + # Hack to avoid pyflakes unused variable warnings + join_by(('a', 'b'), a, b) + np.array([(5, 55, 105, 100), (6, 56, 106, 101), + (7, 57, 107, 102), (8, 58, 108, 103), + (9, 59, 109, 104)], + dtype=[('a', int), ('b', int), + ('c', int), ('d', int)]) + + def test_join_subdtype(self): + # tests the bug in https://stackoverflow.com/q/44769632/102441 + foo = np.array([(1,)], + dtype=[('key', int)]) + bar = np.array([(1, np.array([1,2,3]))], + dtype=[('key', int), ('value', 'uint16', 3)]) + res = join_by('key', foo, bar) + assert_equal(res, bar.view(ma.MaskedArray)) + + def test_outer_join(self): + a, b = self.a, self.b + + test = join_by(('a', 'b'), a, b, 'outer') + control = ma.array([(0, 50, 100, -1), (1, 51, 101, -1), + (2, 52, 102, -1), (3, 53, 103, -1), + (4, 54, 104, -1), (5, 55, 105, -1), + (5, 65, -1, 100), (6, 56, 106, -1), + (6, 66, -1, 101), (7, 57, 107, -1), + (7, 67, -1, 102), (8, 58, 108, -1), + (8, 68, -1, 103), (9, 59, 109, -1), + (9, 69, -1, 104), (10, 70, -1, 105), + (11, 71, -1, 106), (12, 72, -1, 107), + (13, 73, -1, 108), (14, 74, -1, 109)], + mask=[(0, 0, 0, 1), (0, 0, 0, 1), + (0, 0, 0, 1), (0, 0, 0, 1), + (0, 0, 0, 1), (0, 0, 0, 1), + (0, 0, 1, 0), (0, 0, 0, 1), + (0, 0, 1, 0), (0, 0, 0, 1), + (0, 0, 1, 0), (0, 0, 0, 1), + (0, 0, 1, 0), (0, 0, 0, 1), + (0, 0, 1, 0), (0, 0, 1, 0), + (0, 0, 1, 0), (0, 0, 1, 0), + (0, 0, 1, 0), (0, 0, 1, 0)], + dtype=[('a', int), ('b', int), + ('c', int), ('d', int)]) + assert_equal(test, control) + + def test_leftouter_join(self): + a, b = self.a, self.b + + test = join_by(('a', 'b'), a, b, 'leftouter') + control = ma.array([(0, 50, 100, -1), (1, 51, 101, -1), + (2, 52, 102, -1), (3, 53, 103, -1), + (4, 54, 104, -1), (5, 55, 105, -1), + (6, 56, 106, -1), (7, 57, 107, -1), + (8, 58, 108, -1), (9, 59, 109, -1)], + mask=[(0, 0, 0, 1), (0, 0, 0, 1), + (0, 0, 0, 1), (0, 0, 0, 1), + (0, 0, 0, 1), (0, 0, 0, 1), + (0, 0, 0, 1), (0, 0, 0, 1), + (0, 0, 0, 1), (0, 0, 0, 1)], + dtype=[('a', int), ('b', int), ('c', int), ('d', int)]) + assert_equal(test, control) + + def test_different_field_order(self): + # gh-8940 + a = np.zeros(3, dtype=[('a', 'i4'), ('b', 'f4'), ('c', 'u1')]) + b = np.ones(3, dtype=[('c', 'u1'), ('b', 'f4'), ('a', 'i4')]) + # this should not give a FutureWarning: + j = join_by(['c', 'b'], a, b, jointype='inner', usemask=False) + assert_equal(j.dtype.names, ['b', 'c', 'a1', 'a2']) + + def test_duplicate_keys(self): + a = np.zeros(3, dtype=[('a', 'i4'), ('b', 'f4'), ('c', 'u1')]) + b = np.ones(3, dtype=[('c', 'u1'), ('b', 'f4'), ('a', 'i4')]) + assert_raises(ValueError, join_by, ['a', 'b', 'b'], a, b) + + @pytest.mark.xfail(reason="See comment at gh-9343") + def test_same_name_different_dtypes_key(self): + a_dtype = np.dtype([('key', 'S5'), ('value', ' 2**32 + + +def _add_keepdims(func): + """ hack in keepdims behavior into a function taking an axis """ + @functools.wraps(func) + def wrapped(a, axis, **kwargs): + res = func(a, axis=axis, **kwargs) + if axis is None: + axis = 0 # res is now a scalar, so we can insert this anywhere + return np.expand_dims(res, axis=axis) + return wrapped + + +class TestTakeAlongAxis: + def test_argequivalent(self): + """ Test it translates from arg to """ + from numpy.random import rand + a = rand(3, 4, 5) + + funcs = [ + (np.sort, np.argsort, dict()), + (_add_keepdims(np.min), _add_keepdims(np.argmin), dict()), + (_add_keepdims(np.max), _add_keepdims(np.argmax), dict()), + (np.partition, np.argpartition, dict(kth=2)), + ] + + for func, argfunc, kwargs in funcs: + for axis in list(range(a.ndim)) + [None]: + a_func = func(a, axis=axis, **kwargs) + ai_func = argfunc(a, axis=axis, **kwargs) + assert_equal(a_func, take_along_axis(a, ai_func, axis=axis)) + + def test_invalid(self): + """ Test it errors when indices has too few dimensions """ + a = np.ones((10, 10)) + ai = np.ones((10, 2), dtype=np.intp) + + # sanity check + take_along_axis(a, ai, axis=1) + + # not enough indices + assert_raises(ValueError, take_along_axis, a, np.array(1), axis=1) + # bool arrays not allowed + assert_raises(IndexError, take_along_axis, a, ai.astype(bool), axis=1) + # float arrays not allowed + assert_raises(IndexError, take_along_axis, a, ai.astype(float), axis=1) + # invalid axis + assert_raises(np.AxisError, take_along_axis, a, ai, axis=10) + + def test_empty(self): + """ Test everything is ok with empty results, even with inserted dims """ + a = np.ones((3, 4, 5)) + ai = np.ones((3, 0, 5), dtype=np.intp) + + actual = take_along_axis(a, ai, axis=1) + assert_equal(actual.shape, ai.shape) + + def test_broadcast(self): + """ Test that non-indexing dimensions are broadcast in both directions """ + a = np.ones((3, 4, 1)) + ai = np.ones((1, 2, 5), dtype=np.intp) + actual = take_along_axis(a, ai, axis=1) + assert_equal(actual.shape, (3, 2, 5)) + + +class TestPutAlongAxis: + def test_replace_max(self): + a_base = np.array([[10, 30, 20], [60, 40, 50]]) + + for axis in list(range(a_base.ndim)) + [None]: + # we mutate this in the loop + a = a_base.copy() + + # replace the max with a small value + i_max = _add_keepdims(np.argmax)(a, axis=axis) + put_along_axis(a, i_max, -99, axis=axis) + + # find the new minimum, which should max + i_min = _add_keepdims(np.argmin)(a, axis=axis) + + assert_equal(i_min, i_max) + + def test_broadcast(self): + """ Test that non-indexing dimensions are broadcast in both directions """ + a = np.ones((3, 4, 1)) + ai = np.arange(10, dtype=np.intp).reshape((1, 2, 5)) % 4 + put_along_axis(a, ai, 20, axis=1) + assert_equal(take_along_axis(a, ai, axis=1), 20) + + +class TestApplyAlongAxis: + def test_simple(self): + a = np.ones((20, 10), 'd') + assert_array_equal( + apply_along_axis(len, 0, a), len(a)*np.ones(a.shape[1])) + + def test_simple101(self): + a = np.ones((10, 101), 'd') + assert_array_equal( + apply_along_axis(len, 0, a), len(a)*np.ones(a.shape[1])) + + def test_3d(self): + a = np.arange(27).reshape((3, 3, 3)) + assert_array_equal(apply_along_axis(np.sum, 0, a), + [[27, 30, 33], [36, 39, 42], [45, 48, 51]]) + + def test_preserve_subclass(self): + def double(row): + return row * 2 + + class MyNDArray(np.ndarray): + pass + + m = np.array([[0, 1], [2, 3]]).view(MyNDArray) + expected = np.array([[0, 2], [4, 6]]).view(MyNDArray) + + result = apply_along_axis(double, 0, m) + assert_(isinstance(result, MyNDArray)) + assert_array_equal(result, expected) + + result = apply_along_axis(double, 1, m) + assert_(isinstance(result, MyNDArray)) + assert_array_equal(result, expected) + + def test_subclass(self): + class MinimalSubclass(np.ndarray): + data = 1 + + def minimal_function(array): + return array.data + + a = np.zeros((6, 3)).view(MinimalSubclass) + + assert_array_equal( + apply_along_axis(minimal_function, 0, a), np.array([1, 1, 1]) + ) + + def test_scalar_array(self, cls=np.ndarray): + a = np.ones((6, 3)).view(cls) + res = apply_along_axis(np.sum, 0, a) + assert_(isinstance(res, cls)) + assert_array_equal(res, np.array([6, 6, 6]).view(cls)) + + def test_0d_array(self, cls=np.ndarray): + def sum_to_0d(x): + """ Sum x, returning a 0d array of the same class """ + assert_equal(x.ndim, 1) + return np.squeeze(np.sum(x, keepdims=True)) + a = np.ones((6, 3)).view(cls) + res = apply_along_axis(sum_to_0d, 0, a) + assert_(isinstance(res, cls)) + assert_array_equal(res, np.array([6, 6, 6]).view(cls)) + + res = apply_along_axis(sum_to_0d, 1, a) + assert_(isinstance(res, cls)) + assert_array_equal(res, np.array([3, 3, 3, 3, 3, 3]).view(cls)) + + def test_axis_insertion(self, cls=np.ndarray): + def f1to2(x): + """produces an asymmetric non-square matrix from x""" + assert_equal(x.ndim, 1) + return (x[::-1] * x[1:,None]).view(cls) + + a2d = np.arange(6*3).reshape((6, 3)) + + # 2d insertion along first axis + actual = apply_along_axis(f1to2, 0, a2d) + expected = np.stack([ + f1to2(a2d[:,i]) for i in range(a2d.shape[1]) + ], axis=-1).view(cls) + assert_equal(type(actual), type(expected)) + assert_equal(actual, expected) + + # 2d insertion along last axis + actual = apply_along_axis(f1to2, 1, a2d) + expected = np.stack([ + f1to2(a2d[i,:]) for i in range(a2d.shape[0]) + ], axis=0).view(cls) + assert_equal(type(actual), type(expected)) + assert_equal(actual, expected) + + # 3d insertion along middle axis + a3d = np.arange(6*5*3).reshape((6, 5, 3)) + + actual = apply_along_axis(f1to2, 1, a3d) + expected = np.stack([ + np.stack([ + f1to2(a3d[i,:,j]) for i in range(a3d.shape[0]) + ], axis=0) + for j in range(a3d.shape[2]) + ], axis=-1).view(cls) + assert_equal(type(actual), type(expected)) + assert_equal(actual, expected) + + def test_subclass_preservation(self): + class MinimalSubclass(np.ndarray): + pass + self.test_scalar_array(MinimalSubclass) + self.test_0d_array(MinimalSubclass) + self.test_axis_insertion(MinimalSubclass) + + def test_axis_insertion_ma(self): + def f1to2(x): + """produces an asymmetric non-square matrix from x""" + assert_equal(x.ndim, 1) + res = x[::-1] * x[1:,None] + return np.ma.masked_where(res%5==0, res) + a = np.arange(6*3).reshape((6, 3)) + res = apply_along_axis(f1to2, 0, a) + assert_(isinstance(res, np.ma.masked_array)) + assert_equal(res.ndim, 3) + assert_array_equal(res[:,:,0].mask, f1to2(a[:,0]).mask) + assert_array_equal(res[:,:,1].mask, f1to2(a[:,1]).mask) + assert_array_equal(res[:,:,2].mask, f1to2(a[:,2]).mask) + + def test_tuple_func1d(self): + def sample_1d(x): + return x[1], x[0] + res = np.apply_along_axis(sample_1d, 1, np.array([[1, 2], [3, 4]])) + assert_array_equal(res, np.array([[2, 1], [4, 3]])) + + def test_empty(self): + # can't apply_along_axis when there's no chance to call the function + def never_call(x): + assert_(False) # should never be reached + + a = np.empty((0, 0)) + assert_raises(ValueError, np.apply_along_axis, never_call, 0, a) + assert_raises(ValueError, np.apply_along_axis, never_call, 1, a) + + # but it's sometimes ok with some non-zero dimensions + def empty_to_1(x): + assert_(len(x) == 0) + return 1 + + a = np.empty((10, 0)) + actual = np.apply_along_axis(empty_to_1, 1, a) + assert_equal(actual, np.ones(10)) + assert_raises(ValueError, np.apply_along_axis, empty_to_1, 0, a) + + def test_with_iterable_object(self): + # from issue 5248 + d = np.array([ + [{1, 11}, {2, 22}, {3, 33}], + [{4, 44}, {5, 55}, {6, 66}] + ]) + actual = np.apply_along_axis(lambda a: set.union(*a), 0, d) + expected = np.array([{1, 11, 4, 44}, {2, 22, 5, 55}, {3, 33, 6, 66}]) + + assert_equal(actual, expected) + + # issue 8642 - assert_equal doesn't detect this! + for i in np.ndindex(actual.shape): + assert_equal(type(actual[i]), type(expected[i])) + + +class TestApplyOverAxes: + def test_simple(self): + a = np.arange(24).reshape(2, 3, 4) + aoa_a = apply_over_axes(np.sum, a, [0, 2]) + assert_array_equal(aoa_a, np.array([[[60], [92], [124]]])) + + +class TestExpandDims: + def test_functionality(self): + s = (2, 3, 4, 5) + a = np.empty(s) + for axis in range(-5, 4): + b = expand_dims(a, axis) + assert_(b.shape[axis] == 1) + assert_(np.squeeze(b).shape == s) + + def test_axis_tuple(self): + a = np.empty((3, 3, 3)) + assert np.expand_dims(a, axis=(0, 1, 2)).shape == (1, 1, 1, 3, 3, 3) + assert np.expand_dims(a, axis=(0, -1, -2)).shape == (1, 3, 3, 3, 1, 1) + assert np.expand_dims(a, axis=(0, 3, 5)).shape == (1, 3, 3, 1, 3, 1) + assert np.expand_dims(a, axis=(0, -3, -5)).shape == (1, 1, 3, 1, 3, 3) + + def test_axis_out_of_range(self): + s = (2, 3, 4, 5) + a = np.empty(s) + assert_raises(np.AxisError, expand_dims, a, -6) + assert_raises(np.AxisError, expand_dims, a, 5) + + a = np.empty((3, 3, 3)) + assert_raises(np.AxisError, expand_dims, a, (0, -6)) + assert_raises(np.AxisError, expand_dims, a, (0, 5)) + + def test_repeated_axis(self): + a = np.empty((3, 3, 3)) + assert_raises(ValueError, expand_dims, a, axis=(1, 1)) + + def test_subclasses(self): + a = np.arange(10).reshape((2, 5)) + a = np.ma.array(a, mask=a%3 == 0) + + expanded = np.expand_dims(a, axis=1) + assert_(isinstance(expanded, np.ma.MaskedArray)) + assert_equal(expanded.shape, (2, 1, 5)) + assert_equal(expanded.mask.shape, (2, 1, 5)) + + +class TestArraySplit: + def test_integer_0_split(self): + a = np.arange(10) + assert_raises(ValueError, array_split, a, 0) + + def test_integer_split(self): + a = np.arange(10) + res = array_split(a, 1) + desired = [np.arange(10)] + compare_results(res, desired) + + res = array_split(a, 2) + desired = [np.arange(5), np.arange(5, 10)] + compare_results(res, desired) + + res = array_split(a, 3) + desired = [np.arange(4), np.arange(4, 7), np.arange(7, 10)] + compare_results(res, desired) + + res = array_split(a, 4) + desired = [np.arange(3), np.arange(3, 6), np.arange(6, 8), + np.arange(8, 10)] + compare_results(res, desired) + + res = array_split(a, 5) + desired = [np.arange(2), np.arange(2, 4), np.arange(4, 6), + np.arange(6, 8), np.arange(8, 10)] + compare_results(res, desired) + + res = array_split(a, 6) + desired = [np.arange(2), np.arange(2, 4), np.arange(4, 6), + np.arange(6, 8), np.arange(8, 9), np.arange(9, 10)] + compare_results(res, desired) + + res = array_split(a, 7) + desired = [np.arange(2), np.arange(2, 4), np.arange(4, 6), + np.arange(6, 7), np.arange(7, 8), np.arange(8, 9), + np.arange(9, 10)] + compare_results(res, desired) + + res = array_split(a, 8) + desired = [np.arange(2), np.arange(2, 4), np.arange(4, 5), + np.arange(5, 6), np.arange(6, 7), np.arange(7, 8), + np.arange(8, 9), np.arange(9, 10)] + compare_results(res, desired) + + res = array_split(a, 9) + desired = [np.arange(2), np.arange(2, 3), np.arange(3, 4), + np.arange(4, 5), np.arange(5, 6), np.arange(6, 7), + np.arange(7, 8), np.arange(8, 9), np.arange(9, 10)] + compare_results(res, desired) + + res = array_split(a, 10) + desired = [np.arange(1), np.arange(1, 2), np.arange(2, 3), + np.arange(3, 4), np.arange(4, 5), np.arange(5, 6), + np.arange(6, 7), np.arange(7, 8), np.arange(8, 9), + np.arange(9, 10)] + compare_results(res, desired) + + res = array_split(a, 11) + desired = [np.arange(1), np.arange(1, 2), np.arange(2, 3), + np.arange(3, 4), np.arange(4, 5), np.arange(5, 6), + np.arange(6, 7), np.arange(7, 8), np.arange(8, 9), + np.arange(9, 10), np.array([])] + compare_results(res, desired) + + def test_integer_split_2D_rows(self): + a = np.array([np.arange(10), np.arange(10)]) + res = array_split(a, 3, axis=0) + tgt = [np.array([np.arange(10)]), np.array([np.arange(10)]), + np.zeros((0, 10))] + compare_results(res, tgt) + assert_(a.dtype.type is res[-1].dtype.type) + + # Same thing for manual splits: + res = array_split(a, [0, 1, 2], axis=0) + tgt = [np.zeros((0, 10)), np.array([np.arange(10)]), + np.array([np.arange(10)])] + compare_results(res, tgt) + assert_(a.dtype.type is res[-1].dtype.type) + + def test_integer_split_2D_cols(self): + a = np.array([np.arange(10), np.arange(10)]) + res = array_split(a, 3, axis=-1) + desired = [np.array([np.arange(4), np.arange(4)]), + np.array([np.arange(4, 7), np.arange(4, 7)]), + np.array([np.arange(7, 10), np.arange(7, 10)])] + compare_results(res, desired) + + def test_integer_split_2D_default(self): + """ This will fail if we change default axis + """ + a = np.array([np.arange(10), np.arange(10)]) + res = array_split(a, 3) + tgt = [np.array([np.arange(10)]), np.array([np.arange(10)]), + np.zeros((0, 10))] + compare_results(res, tgt) + assert_(a.dtype.type is res[-1].dtype.type) + # perhaps should check higher dimensions + + @pytest.mark.skipif(not IS_64BIT, reason="Needs 64bit platform") + def test_integer_split_2D_rows_greater_max_int32(self): + a = np.broadcast_to([0], (1 << 32, 2)) + res = array_split(a, 4) + chunk = np.broadcast_to([0], (1 << 30, 2)) + tgt = [chunk] * 4 + for i in range(len(tgt)): + assert_equal(res[i].shape, tgt[i].shape) + + def test_index_split_simple(self): + a = np.arange(10) + indices = [1, 5, 7] + res = array_split(a, indices, axis=-1) + desired = [np.arange(0, 1), np.arange(1, 5), np.arange(5, 7), + np.arange(7, 10)] + compare_results(res, desired) + + def test_index_split_low_bound(self): + a = np.arange(10) + indices = [0, 5, 7] + res = array_split(a, indices, axis=-1) + desired = [np.array([]), np.arange(0, 5), np.arange(5, 7), + np.arange(7, 10)] + compare_results(res, desired) + + def test_index_split_high_bound(self): + a = np.arange(10) + indices = [0, 5, 7, 10, 12] + res = array_split(a, indices, axis=-1) + desired = [np.array([]), np.arange(0, 5), np.arange(5, 7), + np.arange(7, 10), np.array([]), np.array([])] + compare_results(res, desired) + + +class TestSplit: + # The split function is essentially the same as array_split, + # except that it test if splitting will result in an + # equal split. Only test for this case. + + def test_equal_split(self): + a = np.arange(10) + res = split(a, 2) + desired = [np.arange(5), np.arange(5, 10)] + compare_results(res, desired) + + def test_unequal_split(self): + a = np.arange(10) + assert_raises(ValueError, split, a, 3) + + +class TestColumnStack: + def test_non_iterable(self): + assert_raises(TypeError, column_stack, 1) + + def test_1D_arrays(self): + # example from docstring + a = np.array((1, 2, 3)) + b = np.array((2, 3, 4)) + expected = np.array([[1, 2], + [2, 3], + [3, 4]]) + actual = np.column_stack((a, b)) + assert_equal(actual, expected) + + def test_2D_arrays(self): + # same as hstack 2D docstring example + a = np.array([[1], [2], [3]]) + b = np.array([[2], [3], [4]]) + expected = np.array([[1, 2], + [2, 3], + [3, 4]]) + actual = np.column_stack((a, b)) + assert_equal(actual, expected) + + def test_generator(self): + with assert_warns(FutureWarning): + column_stack((np.arange(3) for _ in range(2))) + + +class TestDstack: + def test_non_iterable(self): + assert_raises(TypeError, dstack, 1) + + def test_0D_array(self): + a = np.array(1) + b = np.array(2) + res = dstack([a, b]) + desired = np.array([[[1, 2]]]) + assert_array_equal(res, desired) + + def test_1D_array(self): + a = np.array([1]) + b = np.array([2]) + res = dstack([a, b]) + desired = np.array([[[1, 2]]]) + assert_array_equal(res, desired) + + def test_2D_array(self): + a = np.array([[1], [2]]) + b = np.array([[1], [2]]) + res = dstack([a, b]) + desired = np.array([[[1, 1]], [[2, 2, ]]]) + assert_array_equal(res, desired) + + def test_2D_array2(self): + a = np.array([1, 2]) + b = np.array([1, 2]) + res = dstack([a, b]) + desired = np.array([[[1, 1], [2, 2]]]) + assert_array_equal(res, desired) + + def test_generator(self): + with assert_warns(FutureWarning): + dstack((np.arange(3) for _ in range(2))) + + +# array_split has more comprehensive test of splitting. +# only do simple test on hsplit, vsplit, and dsplit +class TestHsplit: + """Only testing for integer splits. + + """ + def test_non_iterable(self): + assert_raises(ValueError, hsplit, 1, 1) + + def test_0D_array(self): + a = np.array(1) + try: + hsplit(a, 2) + assert_(0) + except ValueError: + pass + + def test_1D_array(self): + a = np.array([1, 2, 3, 4]) + res = hsplit(a, 2) + desired = [np.array([1, 2]), np.array([3, 4])] + compare_results(res, desired) + + def test_2D_array(self): + a = np.array([[1, 2, 3, 4], + [1, 2, 3, 4]]) + res = hsplit(a, 2) + desired = [np.array([[1, 2], [1, 2]]), np.array([[3, 4], [3, 4]])] + compare_results(res, desired) + + +class TestVsplit: + """Only testing for integer splits. + + """ + def test_non_iterable(self): + assert_raises(ValueError, vsplit, 1, 1) + + def test_0D_array(self): + a = np.array(1) + assert_raises(ValueError, vsplit, a, 2) + + def test_1D_array(self): + a = np.array([1, 2, 3, 4]) + try: + vsplit(a, 2) + assert_(0) + except ValueError: + pass + + def test_2D_array(self): + a = np.array([[1, 2, 3, 4], + [1, 2, 3, 4]]) + res = vsplit(a, 2) + desired = [np.array([[1, 2, 3, 4]]), np.array([[1, 2, 3, 4]])] + compare_results(res, desired) + + +class TestDsplit: + # Only testing for integer splits. + def test_non_iterable(self): + assert_raises(ValueError, dsplit, 1, 1) + + def test_0D_array(self): + a = np.array(1) + assert_raises(ValueError, dsplit, a, 2) + + def test_1D_array(self): + a = np.array([1, 2, 3, 4]) + assert_raises(ValueError, dsplit, a, 2) + + def test_2D_array(self): + a = np.array([[1, 2, 3, 4], + [1, 2, 3, 4]]) + try: + dsplit(a, 2) + assert_(0) + except ValueError: + pass + + def test_3D_array(self): + a = np.array([[[1, 2, 3, 4], + [1, 2, 3, 4]], + [[1, 2, 3, 4], + [1, 2, 3, 4]]]) + res = dsplit(a, 2) + desired = [np.array([[[1, 2], [1, 2]], [[1, 2], [1, 2]]]), + np.array([[[3, 4], [3, 4]], [[3, 4], [3, 4]]])] + compare_results(res, desired) + + +class TestSqueeze: + def test_basic(self): + from numpy.random import rand + + a = rand(20, 10, 10, 1, 1) + b = rand(20, 1, 10, 1, 20) + c = rand(1, 1, 20, 10) + assert_array_equal(np.squeeze(a), np.reshape(a, (20, 10, 10))) + assert_array_equal(np.squeeze(b), np.reshape(b, (20, 10, 20))) + assert_array_equal(np.squeeze(c), np.reshape(c, (20, 10))) + + # Squeezing to 0-dim should still give an ndarray + a = [[[1.5]]] + res = np.squeeze(a) + assert_equal(res, 1.5) + assert_equal(res.ndim, 0) + assert_equal(type(res), np.ndarray) + + +class TestKron: + def test_return_type(self): + class myarray(np.ndarray): + __array_priority__ = 0.0 + + a = np.ones([2, 2]) + ma = myarray(a.shape, a.dtype, a.data) + assert_equal(type(kron(a, a)), np.ndarray) + assert_equal(type(kron(ma, ma)), myarray) + assert_equal(type(kron(a, ma)), np.ndarray) + assert_equal(type(kron(ma, a)), myarray) + + +class TestTile: + def test_basic(self): + a = np.array([0, 1, 2]) + b = [[1, 2], [3, 4]] + assert_equal(tile(a, 2), [0, 1, 2, 0, 1, 2]) + assert_equal(tile(a, (2, 2)), [[0, 1, 2, 0, 1, 2], [0, 1, 2, 0, 1, 2]]) + assert_equal(tile(a, (1, 2)), [[0, 1, 2, 0, 1, 2]]) + assert_equal(tile(b, 2), [[1, 2, 1, 2], [3, 4, 3, 4]]) + assert_equal(tile(b, (2, 1)), [[1, 2], [3, 4], [1, 2], [3, 4]]) + assert_equal(tile(b, (2, 2)), [[1, 2, 1, 2], [3, 4, 3, 4], + [1, 2, 1, 2], [3, 4, 3, 4]]) + + def test_tile_one_repetition_on_array_gh4679(self): + a = np.arange(5) + b = tile(a, 1) + b += 2 + assert_equal(a, np.arange(5)) + + def test_empty(self): + a = np.array([[[]]]) + b = np.array([[], []]) + c = tile(b, 2).shape + d = tile(a, (3, 2, 5)).shape + assert_equal(c, (2, 0)) + assert_equal(d, (3, 2, 0)) + + def test_kroncompare(self): + from numpy.random import randint + + reps = [(2,), (1, 2), (2, 1), (2, 2), (2, 3, 2), (3, 2)] + shape = [(3,), (2, 3), (3, 4, 3), (3, 2, 3), (4, 3, 2, 4), (2, 2)] + for s in shape: + b = randint(0, 10, size=s) + for r in reps: + a = np.ones(r, b.dtype) + large = tile(b, r) + klarge = kron(a, b) + assert_equal(large, klarge) + + +class TestMayShareMemory: + def test_basic(self): + d = np.ones((50, 60)) + d2 = np.ones((30, 60, 6)) + assert_(np.may_share_memory(d, d)) + assert_(np.may_share_memory(d, d[::-1])) + assert_(np.may_share_memory(d, d[::2])) + assert_(np.may_share_memory(d, d[1:, ::-1])) + + assert_(not np.may_share_memory(d[::-1], d2)) + assert_(not np.may_share_memory(d[::2], d2)) + assert_(not np.may_share_memory(d[1:, ::-1], d2)) + assert_(np.may_share_memory(d2[1:, ::-1], d2)) + + +# Utility +def compare_results(res, desired): + for i in range(len(desired)): + assert_array_equal(res[i], desired[i]) diff --git a/venv/Lib/site-packages/numpy/lib/tests/test_stride_tricks.py b/venv/Lib/site-packages/numpy/lib/tests/test_stride_tricks.py new file mode 100644 index 0000000..efec5d2 --- /dev/null +++ b/venv/Lib/site-packages/numpy/lib/tests/test_stride_tricks.py @@ -0,0 +1,645 @@ +import numpy as np +from numpy.core._rational_tests import rational +from numpy.testing import ( + assert_equal, assert_array_equal, assert_raises, assert_, + assert_raises_regex, assert_warns, + ) +from numpy.lib.stride_tricks import ( + as_strided, broadcast_arrays, _broadcast_shape, broadcast_to, + broadcast_shapes, sliding_window_view, + ) +import pytest + + +def assert_shapes_correct(input_shapes, expected_shape): + # Broadcast a list of arrays with the given input shapes and check the + # common output shape. + + inarrays = [np.zeros(s) for s in input_shapes] + outarrays = broadcast_arrays(*inarrays) + outshapes = [a.shape for a in outarrays] + expected = [expected_shape] * len(inarrays) + assert_equal(outshapes, expected) + + +def assert_incompatible_shapes_raise(input_shapes): + # Broadcast a list of arrays with the given (incompatible) input shapes + # and check that they raise a ValueError. + + inarrays = [np.zeros(s) for s in input_shapes] + assert_raises(ValueError, broadcast_arrays, *inarrays) + + +def assert_same_as_ufunc(shape0, shape1, transposed=False, flipped=False): + # Broadcast two shapes against each other and check that the data layout + # is the same as if a ufunc did the broadcasting. + + x0 = np.zeros(shape0, dtype=int) + # Note that multiply.reduce's identity element is 1.0, so when shape1==(), + # this gives the desired n==1. + n = int(np.multiply.reduce(shape1)) + x1 = np.arange(n).reshape(shape1) + if transposed: + x0 = x0.T + x1 = x1.T + if flipped: + x0 = x0[::-1] + x1 = x1[::-1] + # Use the add ufunc to do the broadcasting. Since we're adding 0s to x1, the + # result should be exactly the same as the broadcasted view of x1. + y = x0 + x1 + b0, b1 = broadcast_arrays(x0, x1) + assert_array_equal(y, b1) + + +def test_same(): + x = np.arange(10) + y = np.arange(10) + bx, by = broadcast_arrays(x, y) + assert_array_equal(x, bx) + assert_array_equal(y, by) + +def test_broadcast_kwargs(): + # ensure that a TypeError is appropriately raised when + # np.broadcast_arrays() is called with any keyword + # argument other than 'subok' + x = np.arange(10) + y = np.arange(10) + + with assert_raises_regex(TypeError, 'got an unexpected keyword'): + broadcast_arrays(x, y, dtype='float64') + + +def test_one_off(): + x = np.array([[1, 2, 3]]) + y = np.array([[1], [2], [3]]) + bx, by = broadcast_arrays(x, y) + bx0 = np.array([[1, 2, 3], [1, 2, 3], [1, 2, 3]]) + by0 = bx0.T + assert_array_equal(bx0, bx) + assert_array_equal(by0, by) + + +def test_same_input_shapes(): + # Check that the final shape is just the input shape. + + data = [ + (), + (1,), + (3,), + (0, 1), + (0, 3), + (1, 0), + (3, 0), + (1, 3), + (3, 1), + (3, 3), + ] + for shape in data: + input_shapes = [shape] + # Single input. + assert_shapes_correct(input_shapes, shape) + # Double input. + input_shapes2 = [shape, shape] + assert_shapes_correct(input_shapes2, shape) + # Triple input. + input_shapes3 = [shape, shape, shape] + assert_shapes_correct(input_shapes3, shape) + + +def test_two_compatible_by_ones_input_shapes(): + # Check that two different input shapes of the same length, but some have + # ones, broadcast to the correct shape. + + data = [ + [[(1,), (3,)], (3,)], + [[(1, 3), (3, 3)], (3, 3)], + [[(3, 1), (3, 3)], (3, 3)], + [[(1, 3), (3, 1)], (3, 3)], + [[(1, 1), (3, 3)], (3, 3)], + [[(1, 1), (1, 3)], (1, 3)], + [[(1, 1), (3, 1)], (3, 1)], + [[(1, 0), (0, 0)], (0, 0)], + [[(0, 1), (0, 0)], (0, 0)], + [[(1, 0), (0, 1)], (0, 0)], + [[(1, 1), (0, 0)], (0, 0)], + [[(1, 1), (1, 0)], (1, 0)], + [[(1, 1), (0, 1)], (0, 1)], + ] + for input_shapes, expected_shape in data: + assert_shapes_correct(input_shapes, expected_shape) + # Reverse the input shapes since broadcasting should be symmetric. + assert_shapes_correct(input_shapes[::-1], expected_shape) + + +def test_two_compatible_by_prepending_ones_input_shapes(): + # Check that two different input shapes (of different lengths) broadcast + # to the correct shape. + + data = [ + [[(), (3,)], (3,)], + [[(3,), (3, 3)], (3, 3)], + [[(3,), (3, 1)], (3, 3)], + [[(1,), (3, 3)], (3, 3)], + [[(), (3, 3)], (3, 3)], + [[(1, 1), (3,)], (1, 3)], + [[(1,), (3, 1)], (3, 1)], + [[(1,), (1, 3)], (1, 3)], + [[(), (1, 3)], (1, 3)], + [[(), (3, 1)], (3, 1)], + [[(), (0,)], (0,)], + [[(0,), (0, 0)], (0, 0)], + [[(0,), (0, 1)], (0, 0)], + [[(1,), (0, 0)], (0, 0)], + [[(), (0, 0)], (0, 0)], + [[(1, 1), (0,)], (1, 0)], + [[(1,), (0, 1)], (0, 1)], + [[(1,), (1, 0)], (1, 0)], + [[(), (1, 0)], (1, 0)], + [[(), (0, 1)], (0, 1)], + ] + for input_shapes, expected_shape in data: + assert_shapes_correct(input_shapes, expected_shape) + # Reverse the input shapes since broadcasting should be symmetric. + assert_shapes_correct(input_shapes[::-1], expected_shape) + + +def test_incompatible_shapes_raise_valueerror(): + # Check that a ValueError is raised for incompatible shapes. + + data = [ + [(3,), (4,)], + [(2, 3), (2,)], + [(3,), (3,), (4,)], + [(1, 3, 4), (2, 3, 3)], + ] + for input_shapes in data: + assert_incompatible_shapes_raise(input_shapes) + # Reverse the input shapes since broadcasting should be symmetric. + assert_incompatible_shapes_raise(input_shapes[::-1]) + + +def test_same_as_ufunc(): + # Check that the data layout is the same as if a ufunc did the operation. + + data = [ + [[(1,), (3,)], (3,)], + [[(1, 3), (3, 3)], (3, 3)], + [[(3, 1), (3, 3)], (3, 3)], + [[(1, 3), (3, 1)], (3, 3)], + [[(1, 1), (3, 3)], (3, 3)], + [[(1, 1), (1, 3)], (1, 3)], + [[(1, 1), (3, 1)], (3, 1)], + [[(1, 0), (0, 0)], (0, 0)], + [[(0, 1), (0, 0)], (0, 0)], + [[(1, 0), (0, 1)], (0, 0)], + [[(1, 1), (0, 0)], (0, 0)], + [[(1, 1), (1, 0)], (1, 0)], + [[(1, 1), (0, 1)], (0, 1)], + [[(), (3,)], (3,)], + [[(3,), (3, 3)], (3, 3)], + [[(3,), (3, 1)], (3, 3)], + [[(1,), (3, 3)], (3, 3)], + [[(), (3, 3)], (3, 3)], + [[(1, 1), (3,)], (1, 3)], + [[(1,), (3, 1)], (3, 1)], + [[(1,), (1, 3)], (1, 3)], + [[(), (1, 3)], (1, 3)], + [[(), (3, 1)], (3, 1)], + [[(), (0,)], (0,)], + [[(0,), (0, 0)], (0, 0)], + [[(0,), (0, 1)], (0, 0)], + [[(1,), (0, 0)], (0, 0)], + [[(), (0, 0)], (0, 0)], + [[(1, 1), (0,)], (1, 0)], + [[(1,), (0, 1)], (0, 1)], + [[(1,), (1, 0)], (1, 0)], + [[(), (1, 0)], (1, 0)], + [[(), (0, 1)], (0, 1)], + ] + for input_shapes, expected_shape in data: + assert_same_as_ufunc(input_shapes[0], input_shapes[1], + "Shapes: %s %s" % (input_shapes[0], input_shapes[1])) + # Reverse the input shapes since broadcasting should be symmetric. + assert_same_as_ufunc(input_shapes[1], input_shapes[0]) + # Try them transposed, too. + assert_same_as_ufunc(input_shapes[0], input_shapes[1], True) + # ... and flipped for non-rank-0 inputs in order to test negative + # strides. + if () not in input_shapes: + assert_same_as_ufunc(input_shapes[0], input_shapes[1], False, True) + assert_same_as_ufunc(input_shapes[0], input_shapes[1], True, True) + + +def test_broadcast_to_succeeds(): + data = [ + [np.array(0), (0,), np.array(0)], + [np.array(0), (1,), np.zeros(1)], + [np.array(0), (3,), np.zeros(3)], + [np.ones(1), (1,), np.ones(1)], + [np.ones(1), (2,), np.ones(2)], + [np.ones(1), (1, 2, 3), np.ones((1, 2, 3))], + [np.arange(3), (3,), np.arange(3)], + [np.arange(3), (1, 3), np.arange(3).reshape(1, -1)], + [np.arange(3), (2, 3), np.array([[0, 1, 2], [0, 1, 2]])], + # test if shape is not a tuple + [np.ones(0), 0, np.ones(0)], + [np.ones(1), 1, np.ones(1)], + [np.ones(1), 2, np.ones(2)], + # these cases with size 0 are strange, but they reproduce the behavior + # of broadcasting with ufuncs (see test_same_as_ufunc above) + [np.ones(1), (0,), np.ones(0)], + [np.ones((1, 2)), (0, 2), np.ones((0, 2))], + [np.ones((2, 1)), (2, 0), np.ones((2, 0))], + ] + for input_array, shape, expected in data: + actual = broadcast_to(input_array, shape) + assert_array_equal(expected, actual) + + +def test_broadcast_to_raises(): + data = [ + [(0,), ()], + [(1,), ()], + [(3,), ()], + [(3,), (1,)], + [(3,), (2,)], + [(3,), (4,)], + [(1, 2), (2, 1)], + [(1, 1), (1,)], + [(1,), -1], + [(1,), (-1,)], + [(1, 2), (-1, 2)], + ] + for orig_shape, target_shape in data: + arr = np.zeros(orig_shape) + assert_raises(ValueError, lambda: broadcast_to(arr, target_shape)) + + +def test_broadcast_shape(): + # tests internal _broadcast_shape + # _broadcast_shape is already exercised indirectly by broadcast_arrays + # _broadcast_shape is also exercised by the public broadcast_shapes function + assert_equal(_broadcast_shape(), ()) + assert_equal(_broadcast_shape([1, 2]), (2,)) + assert_equal(_broadcast_shape(np.ones((1, 1))), (1, 1)) + assert_equal(_broadcast_shape(np.ones((1, 1)), np.ones((3, 4))), (3, 4)) + assert_equal(_broadcast_shape(*([np.ones((1, 2))] * 32)), (1, 2)) + assert_equal(_broadcast_shape(*([np.ones((1, 2))] * 100)), (1, 2)) + + # regression tests for gh-5862 + assert_equal(_broadcast_shape(*([np.ones(2)] * 32 + [1])), (2,)) + bad_args = [np.ones(2)] * 32 + [np.ones(3)] * 32 + assert_raises(ValueError, lambda: _broadcast_shape(*bad_args)) + + +def test_broadcast_shapes_succeeds(): + # tests public broadcast_shapes + data = [ + [[], ()], + [[()], ()], + [[(7,)], (7,)], + [[(1, 2), (2,)], (1, 2)], + [[(1, 1)], (1, 1)], + [[(1, 1), (3, 4)], (3, 4)], + [[(6, 7), (5, 6, 1), (7,), (5, 1, 7)], (5, 6, 7)], + [[(5, 6, 1)], (5, 6, 1)], + [[(1, 3), (3, 1)], (3, 3)], + [[(1, 0), (0, 0)], (0, 0)], + [[(0, 1), (0, 0)], (0, 0)], + [[(1, 0), (0, 1)], (0, 0)], + [[(1, 1), (0, 0)], (0, 0)], + [[(1, 1), (1, 0)], (1, 0)], + [[(1, 1), (0, 1)], (0, 1)], + [[(), (0,)], (0,)], + [[(0,), (0, 0)], (0, 0)], + [[(0,), (0, 1)], (0, 0)], + [[(1,), (0, 0)], (0, 0)], + [[(), (0, 0)], (0, 0)], + [[(1, 1), (0,)], (1, 0)], + [[(1,), (0, 1)], (0, 1)], + [[(1,), (1, 0)], (1, 0)], + [[(), (1, 0)], (1, 0)], + [[(), (0, 1)], (0, 1)], + [[(1,), (3,)], (3,)], + [[2, (3, 2)], (3, 2)], + ] + for input_shapes, target_shape in data: + assert_equal(broadcast_shapes(*input_shapes), target_shape) + + assert_equal(broadcast_shapes(*([(1, 2)] * 32)), (1, 2)) + assert_equal(broadcast_shapes(*([(1, 2)] * 100)), (1, 2)) + + # regression tests for gh-5862 + assert_equal(broadcast_shapes(*([(2,)] * 32)), (2,)) + + +def test_broadcast_shapes_raises(): + # tests public broadcast_shapes + data = [ + [(3,), (4,)], + [(2, 3), (2,)], + [(3,), (3,), (4,)], + [(1, 3, 4), (2, 3, 3)], + [(1, 2), (3,1), (3,2), (10, 5)], + [2, (2, 3)], + ] + for input_shapes in data: + assert_raises(ValueError, lambda: broadcast_shapes(*input_shapes)) + + bad_args = [(2,)] * 32 + [(3,)] * 32 + assert_raises(ValueError, lambda: broadcast_shapes(*bad_args)) + + +def test_as_strided(): + a = np.array([None]) + a_view = as_strided(a) + expected = np.array([None]) + assert_array_equal(a_view, np.array([None])) + + a = np.array([1, 2, 3, 4]) + a_view = as_strided(a, shape=(2,), strides=(2 * a.itemsize,)) + expected = np.array([1, 3]) + assert_array_equal(a_view, expected) + + a = np.array([1, 2, 3, 4]) + a_view = as_strided(a, shape=(3, 4), strides=(0, 1 * a.itemsize)) + expected = np.array([[1, 2, 3, 4], [1, 2, 3, 4], [1, 2, 3, 4]]) + assert_array_equal(a_view, expected) + + # Regression test for gh-5081 + dt = np.dtype([('num', 'i4'), ('obj', 'O')]) + a = np.empty((4,), dtype=dt) + a['num'] = np.arange(1, 5) + a_view = as_strided(a, shape=(3, 4), strides=(0, a.itemsize)) + expected_num = [[1, 2, 3, 4]] * 3 + expected_obj = [[None]*4]*3 + assert_equal(a_view.dtype, dt) + assert_array_equal(expected_num, a_view['num']) + assert_array_equal(expected_obj, a_view['obj']) + + # Make sure that void types without fields are kept unchanged + a = np.empty((4,), dtype='V4') + a_view = as_strided(a, shape=(3, 4), strides=(0, a.itemsize)) + assert_equal(a.dtype, a_view.dtype) + + # Make sure that the only type that could fail is properly handled + dt = np.dtype({'names': [''], 'formats': ['V4']}) + a = np.empty((4,), dtype=dt) + a_view = as_strided(a, shape=(3, 4), strides=(0, a.itemsize)) + assert_equal(a.dtype, a_view.dtype) + + # Custom dtypes should not be lost (gh-9161) + r = [rational(i) for i in range(4)] + a = np.array(r, dtype=rational) + a_view = as_strided(a, shape=(3, 4), strides=(0, a.itemsize)) + assert_equal(a.dtype, a_view.dtype) + assert_array_equal([r] * 3, a_view) + + +class TestSlidingWindowView: + def test_1d(self): + arr = np.arange(5) + arr_view = sliding_window_view(arr, 2) + expected = np.array([[0, 1], + [1, 2], + [2, 3], + [3, 4]]) + assert_array_equal(arr_view, expected) + + def test_2d(self): + i, j = np.ogrid[:3, :4] + arr = 10*i + j + shape = (2, 2) + arr_view = sliding_window_view(arr, shape) + expected = np.array([[[[0, 1], [10, 11]], + [[1, 2], [11, 12]], + [[2, 3], [12, 13]]], + [[[10, 11], [20, 21]], + [[11, 12], [21, 22]], + [[12, 13], [22, 23]]]]) + assert_array_equal(arr_view, expected) + + def test_2d_with_axis(self): + i, j = np.ogrid[:3, :4] + arr = 10*i + j + arr_view = sliding_window_view(arr, 3, 0) + expected = np.array([[[0, 10, 20], + [1, 11, 21], + [2, 12, 22], + [3, 13, 23]]]) + assert_array_equal(arr_view, expected) + + def test_2d_repeated_axis(self): + i, j = np.ogrid[:3, :4] + arr = 10*i + j + arr_view = sliding_window_view(arr, (2, 3), (1, 1)) + expected = np.array([[[[0, 1, 2], + [1, 2, 3]]], + [[[10, 11, 12], + [11, 12, 13]]], + [[[20, 21, 22], + [21, 22, 23]]]]) + assert_array_equal(arr_view, expected) + + def test_2d_without_axis(self): + i, j = np.ogrid[:4, :4] + arr = 10*i + j + shape = (2, 3) + arr_view = sliding_window_view(arr, shape) + expected = np.array([[[[0, 1, 2], [10, 11, 12]], + [[1, 2, 3], [11, 12, 13]]], + [[[10, 11, 12], [20, 21, 22]], + [[11, 12, 13], [21, 22, 23]]], + [[[20, 21, 22], [30, 31, 32]], + [[21, 22, 23], [31, 32, 33]]]]) + assert_array_equal(arr_view, expected) + + def test_errors(self): + i, j = np.ogrid[:4, :4] + arr = 10*i + j + with pytest.raises(ValueError, match='cannot contain negative values'): + sliding_window_view(arr, (-1, 3)) + with pytest.raises( + ValueError, + match='must provide window_shape for all dimensions of `x`'): + sliding_window_view(arr, (1,)) + with pytest.raises( + ValueError, + match='Must provide matching length window_shape and axis'): + sliding_window_view(arr, (1, 3, 4), axis=(0, 1)) + with pytest.raises( + ValueError, + match='window shape cannot be larger than input array'): + sliding_window_view(arr, (5, 5)) + + def test_writeable(self): + arr = np.arange(5) + view = sliding_window_view(arr, 2, writeable=False) + assert_(not view.flags.writeable) + with pytest.raises( + ValueError, + match='assignment destination is read-only'): + view[0, 0] = 3 + view = sliding_window_view(arr, 2, writeable=True) + assert_(view.flags.writeable) + view[0, 1] = 3 + assert_array_equal(arr, np.array([0, 3, 2, 3, 4])) + + def test_subok(self): + class MyArray(np.ndarray): + pass + + arr = np.arange(5).view(MyArray) + assert_(not isinstance(sliding_window_view(arr, 2, + subok=False), + MyArray)) + assert_(isinstance(sliding_window_view(arr, 2, subok=True), MyArray)) + # Default behavior + assert_(not isinstance(sliding_window_view(arr, 2), MyArray)) + + +def as_strided_writeable(): + arr = np.ones(10) + view = as_strided(arr, writeable=False) + assert_(not view.flags.writeable) + + # Check that writeable also is fine: + view = as_strided(arr, writeable=True) + assert_(view.flags.writeable) + view[...] = 3 + assert_array_equal(arr, np.full_like(arr, 3)) + + # Test that things do not break down for readonly: + arr.flags.writeable = False + view = as_strided(arr, writeable=False) + view = as_strided(arr, writeable=True) + assert_(not view.flags.writeable) + + +class VerySimpleSubClass(np.ndarray): + def __new__(cls, *args, **kwargs): + return np.array(*args, subok=True, **kwargs).view(cls) + + +class SimpleSubClass(VerySimpleSubClass): + def __new__(cls, *args, **kwargs): + self = np.array(*args, subok=True, **kwargs).view(cls) + self.info = 'simple' + return self + + def __array_finalize__(self, obj): + self.info = getattr(obj, 'info', '') + ' finalized' + + +def test_subclasses(): + # test that subclass is preserved only if subok=True + a = VerySimpleSubClass([1, 2, 3, 4]) + assert_(type(a) is VerySimpleSubClass) + a_view = as_strided(a, shape=(2,), strides=(2 * a.itemsize,)) + assert_(type(a_view) is np.ndarray) + a_view = as_strided(a, shape=(2,), strides=(2 * a.itemsize,), subok=True) + assert_(type(a_view) is VerySimpleSubClass) + # test that if a subclass has __array_finalize__, it is used + a = SimpleSubClass([1, 2, 3, 4]) + a_view = as_strided(a, shape=(2,), strides=(2 * a.itemsize,), subok=True) + assert_(type(a_view) is SimpleSubClass) + assert_(a_view.info == 'simple finalized') + + # similar tests for broadcast_arrays + b = np.arange(len(a)).reshape(-1, 1) + a_view, b_view = broadcast_arrays(a, b) + assert_(type(a_view) is np.ndarray) + assert_(type(b_view) is np.ndarray) + assert_(a_view.shape == b_view.shape) + a_view, b_view = broadcast_arrays(a, b, subok=True) + assert_(type(a_view) is SimpleSubClass) + assert_(a_view.info == 'simple finalized') + assert_(type(b_view) is np.ndarray) + assert_(a_view.shape == b_view.shape) + + # and for broadcast_to + shape = (2, 4) + a_view = broadcast_to(a, shape) + assert_(type(a_view) is np.ndarray) + assert_(a_view.shape == shape) + a_view = broadcast_to(a, shape, subok=True) + assert_(type(a_view) is SimpleSubClass) + assert_(a_view.info == 'simple finalized') + assert_(a_view.shape == shape) + + +def test_writeable(): + # broadcast_to should return a readonly array + original = np.array([1, 2, 3]) + result = broadcast_to(original, (2, 3)) + assert_equal(result.flags.writeable, False) + assert_raises(ValueError, result.__setitem__, slice(None), 0) + + # but the result of broadcast_arrays needs to be writeable, to + # preserve backwards compatibility + for is_broadcast, results in [(False, broadcast_arrays(original,)), + (True, broadcast_arrays(0, original))]: + for result in results: + # This will change to False in a future version + if is_broadcast: + with assert_warns(FutureWarning): + assert_equal(result.flags.writeable, True) + with assert_warns(DeprecationWarning): + result[:] = 0 + # Warning not emitted, writing to the array resets it + assert_equal(result.flags.writeable, True) + else: + # No warning: + assert_equal(result.flags.writeable, True) + + for results in [broadcast_arrays(original), + broadcast_arrays(0, original)]: + for result in results: + # resets the warn_on_write DeprecationWarning + result.flags.writeable = True + # check: no warning emitted + assert_equal(result.flags.writeable, True) + result[:] = 0 + + # keep readonly input readonly + original.flags.writeable = False + _, result = broadcast_arrays(0, original) + assert_equal(result.flags.writeable, False) + + # regression test for GH6491 + shape = (2,) + strides = [0] + tricky_array = as_strided(np.array(0), shape, strides) + other = np.zeros((1,)) + first, second = broadcast_arrays(tricky_array, other) + assert_(first.shape == second.shape) + + +def test_writeable_memoryview(): + # The result of broadcast_arrays exports as a non-writeable memoryview + # because otherwise there is no good way to opt in to the new behaviour + # (i.e. you would need to set writeable to False explicitly). + # See gh-13929. + original = np.array([1, 2, 3]) + + for is_broadcast, results in [(False, broadcast_arrays(original,)), + (True, broadcast_arrays(0, original))]: + for result in results: + # This will change to False in a future version + if is_broadcast: + # memoryview(result, writable=True) will give warning but cannot + # be tested using the python API. + assert memoryview(result).readonly + else: + assert not memoryview(result).readonly + + +def test_reference_types(): + input_array = np.array('a', dtype=object) + expected = np.array(['a'] * 3, dtype=object) + actual = broadcast_to(input_array, (3,)) + assert_array_equal(expected, actual) + + actual, _ = broadcast_arrays(input_array, np.ones(3)) + assert_array_equal(expected, actual) diff --git a/venv/Lib/site-packages/numpy/lib/tests/test_twodim_base.py b/venv/Lib/site-packages/numpy/lib/tests/test_twodim_base.py new file mode 100644 index 0000000..cce683b --- /dev/null +++ b/venv/Lib/site-packages/numpy/lib/tests/test_twodim_base.py @@ -0,0 +1,532 @@ +"""Test functions for matrix module + +""" +from numpy.testing import ( + assert_equal, assert_array_equal, assert_array_max_ulp, + assert_array_almost_equal, assert_raises, assert_ + ) + +from numpy import ( + arange, add, fliplr, flipud, zeros, ones, eye, array, diag, histogram2d, + tri, mask_indices, triu_indices, triu_indices_from, tril_indices, + tril_indices_from, vander, + ) + +import numpy as np + + +from numpy.core.tests.test_overrides import requires_array_function + + +def get_mat(n): + data = arange(n) + data = add.outer(data, data) + return data + + +class TestEye: + def test_basic(self): + assert_equal(eye(4), + array([[1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [0, 0, 0, 1]])) + + assert_equal(eye(4, dtype='f'), + array([[1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [0, 0, 0, 1]], 'f')) + + assert_equal(eye(3) == 1, + eye(3, dtype=bool)) + + def test_diag(self): + assert_equal(eye(4, k=1), + array([[0, 1, 0, 0], + [0, 0, 1, 0], + [0, 0, 0, 1], + [0, 0, 0, 0]])) + + assert_equal(eye(4, k=-1), + array([[0, 0, 0, 0], + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0]])) + + def test_2d(self): + assert_equal(eye(4, 3), + array([[1, 0, 0], + [0, 1, 0], + [0, 0, 1], + [0, 0, 0]])) + + assert_equal(eye(3, 4), + array([[1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0]])) + + def test_diag2d(self): + assert_equal(eye(3, 4, k=2), + array([[0, 0, 1, 0], + [0, 0, 0, 1], + [0, 0, 0, 0]])) + + assert_equal(eye(4, 3, k=-2), + array([[0, 0, 0], + [0, 0, 0], + [1, 0, 0], + [0, 1, 0]])) + + def test_eye_bounds(self): + assert_equal(eye(2, 2, 1), [[0, 1], [0, 0]]) + assert_equal(eye(2, 2, -1), [[0, 0], [1, 0]]) + assert_equal(eye(2, 2, 2), [[0, 0], [0, 0]]) + assert_equal(eye(2, 2, -2), [[0, 0], [0, 0]]) + assert_equal(eye(3, 2, 2), [[0, 0], [0, 0], [0, 0]]) + assert_equal(eye(3, 2, 1), [[0, 1], [0, 0], [0, 0]]) + assert_equal(eye(3, 2, -1), [[0, 0], [1, 0], [0, 1]]) + assert_equal(eye(3, 2, -2), [[0, 0], [0, 0], [1, 0]]) + assert_equal(eye(3, 2, -3), [[0, 0], [0, 0], [0, 0]]) + + def test_strings(self): + assert_equal(eye(2, 2, dtype='S3'), + [[b'1', b''], [b'', b'1']]) + + def test_bool(self): + assert_equal(eye(2, 2, dtype=bool), [[True, False], [False, True]]) + + def test_order(self): + mat_c = eye(4, 3, k=-1) + mat_f = eye(4, 3, k=-1, order='F') + assert_equal(mat_c, mat_f) + assert mat_c.flags.c_contiguous + assert not mat_c.flags.f_contiguous + assert not mat_f.flags.c_contiguous + assert mat_f.flags.f_contiguous + + +class TestDiag: + def test_vector(self): + vals = (100 * arange(5)).astype('l') + b = zeros((5, 5)) + for k in range(5): + b[k, k] = vals[k] + assert_equal(diag(vals), b) + b = zeros((7, 7)) + c = b.copy() + for k in range(5): + b[k, k + 2] = vals[k] + c[k + 2, k] = vals[k] + assert_equal(diag(vals, k=2), b) + assert_equal(diag(vals, k=-2), c) + + def test_matrix(self, vals=None): + if vals is None: + vals = (100 * get_mat(5) + 1).astype('l') + b = zeros((5,)) + for k in range(5): + b[k] = vals[k, k] + assert_equal(diag(vals), b) + b = b * 0 + for k in range(3): + b[k] = vals[k, k + 2] + assert_equal(diag(vals, 2), b[:3]) + for k in range(3): + b[k] = vals[k + 2, k] + assert_equal(diag(vals, -2), b[:3]) + + def test_fortran_order(self): + vals = array((100 * get_mat(5) + 1), order='F', dtype='l') + self.test_matrix(vals) + + def test_diag_bounds(self): + A = [[1, 2], [3, 4], [5, 6]] + assert_equal(diag(A, k=2), []) + assert_equal(diag(A, k=1), [2]) + assert_equal(diag(A, k=0), [1, 4]) + assert_equal(diag(A, k=-1), [3, 6]) + assert_equal(diag(A, k=-2), [5]) + assert_equal(diag(A, k=-3), []) + + def test_failure(self): + assert_raises(ValueError, diag, [[[1]]]) + + +class TestFliplr: + def test_basic(self): + assert_raises(ValueError, fliplr, ones(4)) + a = get_mat(4) + b = a[:, ::-1] + assert_equal(fliplr(a), b) + a = [[0, 1, 2], + [3, 4, 5]] + b = [[2, 1, 0], + [5, 4, 3]] + assert_equal(fliplr(a), b) + + +class TestFlipud: + def test_basic(self): + a = get_mat(4) + b = a[::-1, :] + assert_equal(flipud(a), b) + a = [[0, 1, 2], + [3, 4, 5]] + b = [[3, 4, 5], + [0, 1, 2]] + assert_equal(flipud(a), b) + + +class TestHistogram2d: + def test_simple(self): + x = array( + [0.41702200, 0.72032449, 1.1437481e-4, 0.302332573, 0.146755891]) + y = array( + [0.09233859, 0.18626021, 0.34556073, 0.39676747, 0.53881673]) + xedges = np.linspace(0, 1, 10) + yedges = np.linspace(0, 1, 10) + H = histogram2d(x, y, (xedges, yedges))[0] + answer = array( + [[0, 0, 0, 1, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 1, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0], + [1, 0, 1, 0, 0, 0, 0, 0, 0], + [0, 1, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0]]) + assert_array_equal(H.T, answer) + H = histogram2d(x, y, xedges)[0] + assert_array_equal(H.T, answer) + H, xedges, yedges = histogram2d(list(range(10)), list(range(10))) + assert_array_equal(H, eye(10, 10)) + assert_array_equal(xedges, np.linspace(0, 9, 11)) + assert_array_equal(yedges, np.linspace(0, 9, 11)) + + def test_asym(self): + x = array([1, 1, 2, 3, 4, 4, 4, 5]) + y = array([1, 3, 2, 0, 1, 2, 3, 4]) + H, xed, yed = histogram2d( + x, y, (6, 5), range=[[0, 6], [0, 5]], density=True) + answer = array( + [[0., 0, 0, 0, 0], + [0, 1, 0, 1, 0], + [0, 0, 1, 0, 0], + [1, 0, 0, 0, 0], + [0, 1, 1, 1, 0], + [0, 0, 0, 0, 1]]) + assert_array_almost_equal(H, answer/8., 3) + assert_array_equal(xed, np.linspace(0, 6, 7)) + assert_array_equal(yed, np.linspace(0, 5, 6)) + + def test_density(self): + x = array([1, 2, 3, 1, 2, 3, 1, 2, 3]) + y = array([1, 1, 1, 2, 2, 2, 3, 3, 3]) + H, xed, yed = histogram2d( + x, y, [[1, 2, 3, 5], [1, 2, 3, 5]], density=True) + answer = array([[1, 1, .5], + [1, 1, .5], + [.5, .5, .25]])/9. + assert_array_almost_equal(H, answer, 3) + + def test_all_outliers(self): + r = np.random.rand(100) + 1. + 1e6 # histogramdd rounds by decimal=6 + H, xed, yed = histogram2d(r, r, (4, 5), range=([0, 1], [0, 1])) + assert_array_equal(H, 0) + + def test_empty(self): + a, edge1, edge2 = histogram2d([], [], bins=([0, 1], [0, 1])) + assert_array_max_ulp(a, array([[0.]])) + + a, edge1, edge2 = histogram2d([], [], bins=4) + assert_array_max_ulp(a, np.zeros((4, 4))) + + def test_binparameter_combination(self): + x = array( + [0, 0.09207008, 0.64575234, 0.12875982, 0.47390599, + 0.59944483, 1]) + y = array( + [0, 0.14344267, 0.48988575, 0.30558665, 0.44700682, + 0.15886423, 1]) + edges = (0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1) + H, xe, ye = histogram2d(x, y, (edges, 4)) + answer = array( + [[2., 0., 0., 0.], + [0., 1., 0., 0.], + [0., 0., 0., 0.], + [0., 0., 0., 0.], + [0., 1., 0., 0.], + [1., 0., 0., 0.], + [0., 1., 0., 0.], + [0., 0., 0., 0.], + [0., 0., 0., 0.], + [0., 0., 0., 1.]]) + assert_array_equal(H, answer) + assert_array_equal(ye, array([0., 0.25, 0.5, 0.75, 1])) + H, xe, ye = histogram2d(x, y, (4, edges)) + answer = array( + [[1., 1., 0., 1., 0., 0., 0., 0., 0., 0.], + [0., 0., 0., 0., 1., 0., 0., 0., 0., 0.], + [0., 1., 0., 0., 1., 0., 0., 0., 0., 0.], + [0., 0., 0., 0., 0., 0., 0., 0., 0., 1.]]) + assert_array_equal(H, answer) + assert_array_equal(xe, array([0., 0.25, 0.5, 0.75, 1])) + + @requires_array_function + def test_dispatch(self): + class ShouldDispatch: + def __array_function__(self, function, types, args, kwargs): + return types, args, kwargs + + xy = [1, 2] + s_d = ShouldDispatch() + r = histogram2d(s_d, xy) + # Cannot use assert_equal since that dispatches... + assert_(r == ((ShouldDispatch,), (s_d, xy), {})) + r = histogram2d(xy, s_d) + assert_(r == ((ShouldDispatch,), (xy, s_d), {})) + r = histogram2d(xy, xy, bins=s_d) + assert_(r, ((ShouldDispatch,), (xy, xy), dict(bins=s_d))) + r = histogram2d(xy, xy, bins=[s_d, 5]) + assert_(r, ((ShouldDispatch,), (xy, xy), dict(bins=[s_d, 5]))) + assert_raises(Exception, histogram2d, xy, xy, bins=[s_d]) + r = histogram2d(xy, xy, weights=s_d) + assert_(r, ((ShouldDispatch,), (xy, xy), dict(weights=s_d))) + + +class TestTri: + def test_dtype(self): + out = array([[1, 0, 0], + [1, 1, 0], + [1, 1, 1]]) + assert_array_equal(tri(3), out) + assert_array_equal(tri(3, dtype=bool), out.astype(bool)) + + +def test_tril_triu_ndim2(): + for dtype in np.typecodes['AllFloat'] + np.typecodes['AllInteger']: + a = np.ones((2, 2), dtype=dtype) + b = np.tril(a) + c = np.triu(a) + assert_array_equal(b, [[1, 0], [1, 1]]) + assert_array_equal(c, b.T) + # should return the same dtype as the original array + assert_equal(b.dtype, a.dtype) + assert_equal(c.dtype, a.dtype) + + +def test_tril_triu_ndim3(): + for dtype in np.typecodes['AllFloat'] + np.typecodes['AllInteger']: + a = np.array([ + [[1, 1], [1, 1]], + [[1, 1], [1, 0]], + [[1, 1], [0, 0]], + ], dtype=dtype) + a_tril_desired = np.array([ + [[1, 0], [1, 1]], + [[1, 0], [1, 0]], + [[1, 0], [0, 0]], + ], dtype=dtype) + a_triu_desired = np.array([ + [[1, 1], [0, 1]], + [[1, 1], [0, 0]], + [[1, 1], [0, 0]], + ], dtype=dtype) + a_triu_observed = np.triu(a) + a_tril_observed = np.tril(a) + assert_array_equal(a_triu_observed, a_triu_desired) + assert_array_equal(a_tril_observed, a_tril_desired) + assert_equal(a_triu_observed.dtype, a.dtype) + assert_equal(a_tril_observed.dtype, a.dtype) + + +def test_tril_triu_with_inf(): + # Issue 4859 + arr = np.array([[1, 1, np.inf], + [1, 1, 1], + [np.inf, 1, 1]]) + out_tril = np.array([[1, 0, 0], + [1, 1, 0], + [np.inf, 1, 1]]) + out_triu = out_tril.T + assert_array_equal(np.triu(arr), out_triu) + assert_array_equal(np.tril(arr), out_tril) + + +def test_tril_triu_dtype(): + # Issue 4916 + # tril and triu should return the same dtype as input + for c in np.typecodes['All']: + if c == 'V': + continue + arr = np.zeros((3, 3), dtype=c) + assert_equal(np.triu(arr).dtype, arr.dtype) + assert_equal(np.tril(arr).dtype, arr.dtype) + + # check special cases + arr = np.array([['2001-01-01T12:00', '2002-02-03T13:56'], + ['2004-01-01T12:00', '2003-01-03T13:45']], + dtype='datetime64') + assert_equal(np.triu(arr).dtype, arr.dtype) + assert_equal(np.tril(arr).dtype, arr.dtype) + + arr = np.zeros((3,3), dtype='f4,f4') + assert_equal(np.triu(arr).dtype, arr.dtype) + assert_equal(np.tril(arr).dtype, arr.dtype) + + +def test_mask_indices(): + # simple test without offset + iu = mask_indices(3, np.triu) + a = np.arange(9).reshape(3, 3) + assert_array_equal(a[iu], array([0, 1, 2, 4, 5, 8])) + # Now with an offset + iu1 = mask_indices(3, np.triu, 1) + assert_array_equal(a[iu1], array([1, 2, 5])) + + +def test_tril_indices(): + # indices without and with offset + il1 = tril_indices(4) + il2 = tril_indices(4, k=2) + il3 = tril_indices(4, m=5) + il4 = tril_indices(4, k=2, m=5) + + a = np.array([[1, 2, 3, 4], + [5, 6, 7, 8], + [9, 10, 11, 12], + [13, 14, 15, 16]]) + b = np.arange(1, 21).reshape(4, 5) + + # indexing: + assert_array_equal(a[il1], + array([1, 5, 6, 9, 10, 11, 13, 14, 15, 16])) + assert_array_equal(b[il3], + array([1, 6, 7, 11, 12, 13, 16, 17, 18, 19])) + + # And for assigning values: + a[il1] = -1 + assert_array_equal(a, + array([[-1, 2, 3, 4], + [-1, -1, 7, 8], + [-1, -1, -1, 12], + [-1, -1, -1, -1]])) + b[il3] = -1 + assert_array_equal(b, + array([[-1, 2, 3, 4, 5], + [-1, -1, 8, 9, 10], + [-1, -1, -1, 14, 15], + [-1, -1, -1, -1, 20]])) + # These cover almost the whole array (two diagonals right of the main one): + a[il2] = -10 + assert_array_equal(a, + array([[-10, -10, -10, 4], + [-10, -10, -10, -10], + [-10, -10, -10, -10], + [-10, -10, -10, -10]])) + b[il4] = -10 + assert_array_equal(b, + array([[-10, -10, -10, 4, 5], + [-10, -10, -10, -10, 10], + [-10, -10, -10, -10, -10], + [-10, -10, -10, -10, -10]])) + + +class TestTriuIndices: + def test_triu_indices(self): + iu1 = triu_indices(4) + iu2 = triu_indices(4, k=2) + iu3 = triu_indices(4, m=5) + iu4 = triu_indices(4, k=2, m=5) + + a = np.array([[1, 2, 3, 4], + [5, 6, 7, 8], + [9, 10, 11, 12], + [13, 14, 15, 16]]) + b = np.arange(1, 21).reshape(4, 5) + + # Both for indexing: + assert_array_equal(a[iu1], + array([1, 2, 3, 4, 6, 7, 8, 11, 12, 16])) + assert_array_equal(b[iu3], + array([1, 2, 3, 4, 5, 7, 8, 9, + 10, 13, 14, 15, 19, 20])) + + # And for assigning values: + a[iu1] = -1 + assert_array_equal(a, + array([[-1, -1, -1, -1], + [5, -1, -1, -1], + [9, 10, -1, -1], + [13, 14, 15, -1]])) + b[iu3] = -1 + assert_array_equal(b, + array([[-1, -1, -1, -1, -1], + [6, -1, -1, -1, -1], + [11, 12, -1, -1, -1], + [16, 17, 18, -1, -1]])) + + # These cover almost the whole array (two diagonals right of the + # main one): + a[iu2] = -10 + assert_array_equal(a, + array([[-1, -1, -10, -10], + [5, -1, -1, -10], + [9, 10, -1, -1], + [13, 14, 15, -1]])) + b[iu4] = -10 + assert_array_equal(b, + array([[-1, -1, -10, -10, -10], + [6, -1, -1, -10, -10], + [11, 12, -1, -1, -10], + [16, 17, 18, -1, -1]])) + + +class TestTrilIndicesFrom: + def test_exceptions(self): + assert_raises(ValueError, tril_indices_from, np.ones((2,))) + assert_raises(ValueError, tril_indices_from, np.ones((2, 2, 2))) + # assert_raises(ValueError, tril_indices_from, np.ones((2, 3))) + + +class TestTriuIndicesFrom: + def test_exceptions(self): + assert_raises(ValueError, triu_indices_from, np.ones((2,))) + assert_raises(ValueError, triu_indices_from, np.ones((2, 2, 2))) + # assert_raises(ValueError, triu_indices_from, np.ones((2, 3))) + + +class TestVander: + def test_basic(self): + c = np.array([0, 1, -2, 3]) + v = vander(c) + powers = np.array([[0, 0, 0, 0, 1], + [1, 1, 1, 1, 1], + [16, -8, 4, -2, 1], + [81, 27, 9, 3, 1]]) + # Check default value of N: + assert_array_equal(v, powers[:, 1:]) + # Check a range of N values, including 0 and 5 (greater than default) + m = powers.shape[1] + for n in range(6): + v = vander(c, N=n) + assert_array_equal(v, powers[:, m-n:m]) + + def test_dtypes(self): + c = array([11, -12, 13], dtype=np.int8) + v = vander(c) + expected = np.array([[121, 11, 1], + [144, -12, 1], + [169, 13, 1]]) + assert_array_equal(v, expected) + + c = array([1.0+1j, 1.0-1j]) + v = vander(c, N=3) + expected = np.array([[2j, 1+1j, 1], + [-2j, 1-1j, 1]]) + # The data is floating point, but the values are small integers, + # so assert_array_equal *should* be safe here (rather than, say, + # assert_array_almost_equal). + assert_array_equal(v, expected) diff --git a/venv/Lib/site-packages/numpy/lib/tests/test_type_check.py b/venv/Lib/site-packages/numpy/lib/tests/test_type_check.py new file mode 100644 index 0000000..3f4ca63 --- /dev/null +++ b/venv/Lib/site-packages/numpy/lib/tests/test_type_check.py @@ -0,0 +1,478 @@ +import numpy as np +from numpy.testing import ( + assert_, assert_equal, assert_array_equal, assert_raises + ) +from numpy.lib.type_check import ( + common_type, mintypecode, isreal, iscomplex, isposinf, isneginf, + nan_to_num, isrealobj, iscomplexobj, asfarray, real_if_close + ) + + +def assert_all(x): + assert_(np.all(x), x) + + +class TestCommonType: + def test_basic(self): + ai32 = np.array([[1, 2], [3, 4]], dtype=np.int32) + af16 = np.array([[1, 2], [3, 4]], dtype=np.float16) + af32 = np.array([[1, 2], [3, 4]], dtype=np.float32) + af64 = np.array([[1, 2], [3, 4]], dtype=np.float64) + acs = np.array([[1+5j, 2+6j], [3+7j, 4+8j]], dtype=np.csingle) + acd = np.array([[1+5j, 2+6j], [3+7j, 4+8j]], dtype=np.cdouble) + assert_(common_type(ai32) == np.float64) + assert_(common_type(af16) == np.float16) + assert_(common_type(af32) == np.float32) + assert_(common_type(af64) == np.float64) + assert_(common_type(acs) == np.csingle) + assert_(common_type(acd) == np.cdouble) + + +class TestMintypecode: + + def test_default_1(self): + for itype in '1bcsuwil': + assert_equal(mintypecode(itype), 'd') + assert_equal(mintypecode('f'), 'f') + assert_equal(mintypecode('d'), 'd') + assert_equal(mintypecode('F'), 'F') + assert_equal(mintypecode('D'), 'D') + + def test_default_2(self): + for itype in '1bcsuwil': + assert_equal(mintypecode(itype+'f'), 'f') + assert_equal(mintypecode(itype+'d'), 'd') + assert_equal(mintypecode(itype+'F'), 'F') + assert_equal(mintypecode(itype+'D'), 'D') + assert_equal(mintypecode('ff'), 'f') + assert_equal(mintypecode('fd'), 'd') + assert_equal(mintypecode('fF'), 'F') + assert_equal(mintypecode('fD'), 'D') + assert_equal(mintypecode('df'), 'd') + assert_equal(mintypecode('dd'), 'd') + #assert_equal(mintypecode('dF',savespace=1),'F') + assert_equal(mintypecode('dF'), 'D') + assert_equal(mintypecode('dD'), 'D') + assert_equal(mintypecode('Ff'), 'F') + #assert_equal(mintypecode('Fd',savespace=1),'F') + assert_equal(mintypecode('Fd'), 'D') + assert_equal(mintypecode('FF'), 'F') + assert_equal(mintypecode('FD'), 'D') + assert_equal(mintypecode('Df'), 'D') + assert_equal(mintypecode('Dd'), 'D') + assert_equal(mintypecode('DF'), 'D') + assert_equal(mintypecode('DD'), 'D') + + def test_default_3(self): + assert_equal(mintypecode('fdF'), 'D') + #assert_equal(mintypecode('fdF',savespace=1),'F') + assert_equal(mintypecode('fdD'), 'D') + assert_equal(mintypecode('fFD'), 'D') + assert_equal(mintypecode('dFD'), 'D') + + assert_equal(mintypecode('ifd'), 'd') + assert_equal(mintypecode('ifF'), 'F') + assert_equal(mintypecode('ifD'), 'D') + assert_equal(mintypecode('idF'), 'D') + #assert_equal(mintypecode('idF',savespace=1),'F') + assert_equal(mintypecode('idD'), 'D') + + +class TestIsscalar: + + def test_basic(self): + assert_(np.isscalar(3)) + assert_(not np.isscalar([3])) + assert_(not np.isscalar((3,))) + assert_(np.isscalar(3j)) + assert_(np.isscalar(4.0)) + + +class TestReal: + + def test_real(self): + y = np.random.rand(10,) + assert_array_equal(y, np.real(y)) + + y = np.array(1) + out = np.real(y) + assert_array_equal(y, out) + assert_(isinstance(out, np.ndarray)) + + y = 1 + out = np.real(y) + assert_equal(y, out) + assert_(not isinstance(out, np.ndarray)) + + def test_cmplx(self): + y = np.random.rand(10,)+1j*np.random.rand(10,) + assert_array_equal(y.real, np.real(y)) + + y = np.array(1 + 1j) + out = np.real(y) + assert_array_equal(y.real, out) + assert_(isinstance(out, np.ndarray)) + + y = 1 + 1j + out = np.real(y) + assert_equal(1.0, out) + assert_(not isinstance(out, np.ndarray)) + + +class TestImag: + + def test_real(self): + y = np.random.rand(10,) + assert_array_equal(0, np.imag(y)) + + y = np.array(1) + out = np.imag(y) + assert_array_equal(0, out) + assert_(isinstance(out, np.ndarray)) + + y = 1 + out = np.imag(y) + assert_equal(0, out) + assert_(not isinstance(out, np.ndarray)) + + def test_cmplx(self): + y = np.random.rand(10,)+1j*np.random.rand(10,) + assert_array_equal(y.imag, np.imag(y)) + + y = np.array(1 + 1j) + out = np.imag(y) + assert_array_equal(y.imag, out) + assert_(isinstance(out, np.ndarray)) + + y = 1 + 1j + out = np.imag(y) + assert_equal(1.0, out) + assert_(not isinstance(out, np.ndarray)) + + +class TestIscomplex: + + def test_fail(self): + z = np.array([-1, 0, 1]) + res = iscomplex(z) + assert_(not np.sometrue(res, axis=0)) + + def test_pass(self): + z = np.array([-1j, 1, 0]) + res = iscomplex(z) + assert_array_equal(res, [1, 0, 0]) + + +class TestIsreal: + + def test_pass(self): + z = np.array([-1, 0, 1j]) + res = isreal(z) + assert_array_equal(res, [1, 1, 0]) + + def test_fail(self): + z = np.array([-1j, 1, 0]) + res = isreal(z) + assert_array_equal(res, [0, 1, 1]) + + +class TestIscomplexobj: + + def test_basic(self): + z = np.array([-1, 0, 1]) + assert_(not iscomplexobj(z)) + z = np.array([-1j, 0, -1]) + assert_(iscomplexobj(z)) + + def test_scalar(self): + assert_(not iscomplexobj(1.0)) + assert_(iscomplexobj(1+0j)) + + def test_list(self): + assert_(iscomplexobj([3, 1+0j, True])) + assert_(not iscomplexobj([3, 1, True])) + + def test_duck(self): + class DummyComplexArray: + @property + def dtype(self): + return np.dtype(complex) + dummy = DummyComplexArray() + assert_(iscomplexobj(dummy)) + + def test_pandas_duck(self): + # This tests a custom np.dtype duck-typed class, such as used by pandas + # (pandas.core.dtypes) + class PdComplex(np.complex128): + pass + class PdDtype: + name = 'category' + names = None + type = PdComplex + kind = 'c' + str = ' 1e10) and assert_all(np.isfinite(vals[2])) + assert_equal(type(vals), np.ndarray) + + # perform the same tests but with nan, posinf and neginf keywords + with np.errstate(divide='ignore', invalid='ignore'): + vals = nan_to_num(np.array((-1., 0, 1))/0., + nan=10, posinf=20, neginf=30) + assert_equal(vals, [30, 10, 20]) + assert_all(np.isfinite(vals[[0, 2]])) + assert_equal(type(vals), np.ndarray) + + # perform the same test but in-place + with np.errstate(divide='ignore', invalid='ignore'): + vals = np.array((-1., 0, 1))/0. + result = nan_to_num(vals, copy=False) + + assert_(result is vals) + assert_all(vals[0] < -1e10) and assert_all(np.isfinite(vals[0])) + assert_(vals[1] == 0) + assert_all(vals[2] > 1e10) and assert_all(np.isfinite(vals[2])) + assert_equal(type(vals), np.ndarray) + + # perform the same test but in-place + with np.errstate(divide='ignore', invalid='ignore'): + vals = np.array((-1., 0, 1))/0. + result = nan_to_num(vals, copy=False, nan=10, posinf=20, neginf=30) + + assert_(result is vals) + assert_equal(vals, [30, 10, 20]) + assert_all(np.isfinite(vals[[0, 2]])) + assert_equal(type(vals), np.ndarray) + + def test_array(self): + vals = nan_to_num([1]) + assert_array_equal(vals, np.array([1], int)) + assert_equal(type(vals), np.ndarray) + vals = nan_to_num([1], nan=10, posinf=20, neginf=30) + assert_array_equal(vals, np.array([1], int)) + assert_equal(type(vals), np.ndarray) + + def test_integer(self): + vals = nan_to_num(1) + assert_all(vals == 1) + assert_equal(type(vals), np.int_) + vals = nan_to_num(1, nan=10, posinf=20, neginf=30) + assert_all(vals == 1) + assert_equal(type(vals), np.int_) + + def test_float(self): + vals = nan_to_num(1.0) + assert_all(vals == 1.0) + assert_equal(type(vals), np.float_) + vals = nan_to_num(1.1, nan=10, posinf=20, neginf=30) + assert_all(vals == 1.1) + assert_equal(type(vals), np.float_) + + def test_complex_good(self): + vals = nan_to_num(1+1j) + assert_all(vals == 1+1j) + assert_equal(type(vals), np.complex_) + vals = nan_to_num(1+1j, nan=10, posinf=20, neginf=30) + assert_all(vals == 1+1j) + assert_equal(type(vals), np.complex_) + + def test_complex_bad(self): + with np.errstate(divide='ignore', invalid='ignore'): + v = 1 + 1j + v += np.array(0+1.j)/0. + vals = nan_to_num(v) + # !! This is actually (unexpectedly) zero + assert_all(np.isfinite(vals)) + assert_equal(type(vals), np.complex_) + + def test_complex_bad2(self): + with np.errstate(divide='ignore', invalid='ignore'): + v = 1 + 1j + v += np.array(-1+1.j)/0. + vals = nan_to_num(v) + assert_all(np.isfinite(vals)) + assert_equal(type(vals), np.complex_) + # Fixme + #assert_all(vals.imag > 1e10) and assert_all(np.isfinite(vals)) + # !! This is actually (unexpectedly) positive + # !! inf. Comment out for now, and see if it + # !! changes + #assert_all(vals.real < -1e10) and assert_all(np.isfinite(vals)) + + def test_do_not_rewrite_previous_keyword(self): + # This is done to test that when, for instance, nan=np.inf then these + # values are not rewritten by posinf keyword to the posinf value. + with np.errstate(divide='ignore', invalid='ignore'): + vals = nan_to_num(np.array((-1., 0, 1))/0., nan=np.inf, posinf=999) + assert_all(np.isfinite(vals[[0, 2]])) + assert_all(vals[0] < -1e10) + assert_equal(vals[[1, 2]], [np.inf, 999]) + assert_equal(type(vals), np.ndarray) + + +class TestRealIfClose: + + def test_basic(self): + a = np.random.rand(10) + b = real_if_close(a+1e-15j) + assert_all(isrealobj(b)) + assert_array_equal(a, b) + b = real_if_close(a+1e-7j) + assert_all(iscomplexobj(b)) + b = real_if_close(a+1e-7j, tol=1e-6) + assert_all(isrealobj(b)) + + +class TestArrayConversion: + + def test_asfarray(self): + a = asfarray(np.array([1, 2, 3])) + assert_equal(a.__class__, np.ndarray) + assert_(np.issubdtype(a.dtype, np.floating)) + + # previously this would infer dtypes from arrays, unlike every single + # other numpy function + assert_raises(TypeError, + asfarray, np.array([1, 2, 3]), dtype=np.array(1.0)) diff --git a/venv/Lib/site-packages/numpy/lib/tests/test_ufunclike.py b/venv/Lib/site-packages/numpy/lib/tests/test_ufunclike.py new file mode 100644 index 0000000..c280b69 --- /dev/null +++ b/venv/Lib/site-packages/numpy/lib/tests/test_ufunclike.py @@ -0,0 +1,104 @@ +import numpy as np +import numpy.core as nx +import numpy.lib.ufunclike as ufl +from numpy.testing import ( + assert_, assert_equal, assert_array_equal, assert_warns, assert_raises +) + + +class TestUfunclike: + + def test_isposinf(self): + a = nx.array([nx.inf, -nx.inf, nx.nan, 0.0, 3.0, -3.0]) + out = nx.zeros(a.shape, bool) + tgt = nx.array([True, False, False, False, False, False]) + + res = ufl.isposinf(a) + assert_equal(res, tgt) + res = ufl.isposinf(a, out) + assert_equal(res, tgt) + assert_equal(out, tgt) + + a = a.astype(np.complex_) + with assert_raises(TypeError): + ufl.isposinf(a) + + def test_isneginf(self): + a = nx.array([nx.inf, -nx.inf, nx.nan, 0.0, 3.0, -3.0]) + out = nx.zeros(a.shape, bool) + tgt = nx.array([False, True, False, False, False, False]) + + res = ufl.isneginf(a) + assert_equal(res, tgt) + res = ufl.isneginf(a, out) + assert_equal(res, tgt) + assert_equal(out, tgt) + + a = a.astype(np.complex_) + with assert_raises(TypeError): + ufl.isneginf(a) + + def test_fix(self): + a = nx.array([[1.0, 1.1, 1.5, 1.8], [-1.0, -1.1, -1.5, -1.8]]) + out = nx.zeros(a.shape, float) + tgt = nx.array([[1., 1., 1., 1.], [-1., -1., -1., -1.]]) + + res = ufl.fix(a) + assert_equal(res, tgt) + res = ufl.fix(a, out) + assert_equal(res, tgt) + assert_equal(out, tgt) + assert_equal(ufl.fix(3.14), 3) + + def test_fix_with_subclass(self): + class MyArray(nx.ndarray): + def __new__(cls, data, metadata=None): + res = nx.array(data, copy=True).view(cls) + res.metadata = metadata + return res + + def __array_wrap__(self, obj, context=None): + if isinstance(obj, MyArray): + obj.metadata = self.metadata + return obj + + def __array_finalize__(self, obj): + self.metadata = getattr(obj, 'metadata', None) + return self + + a = nx.array([1.1, -1.1]) + m = MyArray(a, metadata='foo') + f = ufl.fix(m) + assert_array_equal(f, nx.array([1, -1])) + assert_(isinstance(f, MyArray)) + assert_equal(f.metadata, 'foo') + + # check 0d arrays don't decay to scalars + m0d = m[0,...] + m0d.metadata = 'bar' + f0d = ufl.fix(m0d) + assert_(isinstance(f0d, MyArray)) + assert_equal(f0d.metadata, 'bar') + + def test_deprecated(self): + # NumPy 1.13.0, 2017-04-26 + assert_warns(DeprecationWarning, ufl.fix, [1, 2], y=nx.empty(2)) + assert_warns(DeprecationWarning, ufl.isposinf, [1, 2], y=nx.empty(2)) + assert_warns(DeprecationWarning, ufl.isneginf, [1, 2], y=nx.empty(2)) + + def test_scalar(self): + x = np.inf + actual = np.isposinf(x) + expected = np.True_ + assert_equal(actual, expected) + assert_equal(type(actual), type(expected)) + + x = -3.4 + actual = np.fix(x) + expected = np.float64(-3.0) + assert_equal(actual, expected) + assert_equal(type(actual), type(expected)) + + out = np.array(0.0) + actual = np.fix(x, out=out) + assert_(actual is out) diff --git a/venv/Lib/site-packages/numpy/lib/tests/test_utils.py b/venv/Lib/site-packages/numpy/lib/tests/test_utils.py new file mode 100644 index 0000000..33951b9 --- /dev/null +++ b/venv/Lib/site-packages/numpy/lib/tests/test_utils.py @@ -0,0 +1,161 @@ +import inspect +import sys +import pytest + +from numpy.core import arange +from numpy.testing import assert_, assert_equal, assert_raises_regex +from numpy.lib import deprecate +import numpy.lib.utils as utils + +from io import StringIO + + +@pytest.mark.skipif(sys.flags.optimize == 2, reason="Python running -OO") +def test_lookfor(): + out = StringIO() + utils.lookfor('eigenvalue', module='numpy', output=out, + import_modules=False) + out = out.getvalue() + assert_('numpy.linalg.eig' in out) + + +@deprecate +def old_func(self, x): + return x + + +@deprecate(message="Rather use new_func2") +def old_func2(self, x): + return x + + +def old_func3(self, x): + return x +new_func3 = deprecate(old_func3, old_name="old_func3", new_name="new_func3") + + +def old_func4(self, x): + """Summary. + + Further info. + """ + return x +new_func4 = deprecate(old_func4) + + +def old_func5(self, x): + """Summary. + + Bizarre indentation. + """ + return x +new_func5 = deprecate(old_func5, message="This function is\ndeprecated.") + + +def old_func6(self, x): + """ + Also in PEP-257. + """ + return x +new_func6 = deprecate(old_func6) + + +def test_deprecate_decorator(): + assert_('deprecated' in old_func.__doc__) + + +def test_deprecate_decorator_message(): + assert_('Rather use new_func2' in old_func2.__doc__) + + +def test_deprecate_fn(): + assert_('old_func3' in new_func3.__doc__) + assert_('new_func3' in new_func3.__doc__) + + +@pytest.mark.skipif(sys.flags.optimize == 2, reason="-OO discards docstrings") +@pytest.mark.parametrize('old_func, new_func', [ + (old_func4, new_func4), + (old_func5, new_func5), + (old_func6, new_func6), +]) +def test_deprecate_help_indentation(old_func, new_func): + _compare_docs(old_func, new_func) + # Ensure we don't mess up the indentation + for knd, func in (('old', old_func), ('new', new_func)): + for li, line in enumerate(func.__doc__.split('\n')): + if li == 0: + assert line.startswith(' ') or not line.startswith(' '), knd + elif line: + assert line.startswith(' '), knd + + +def _compare_docs(old_func, new_func): + old_doc = inspect.getdoc(old_func) + new_doc = inspect.getdoc(new_func) + index = new_doc.index('\n\n') + 2 + assert_equal(new_doc[index:], old_doc) + + +@pytest.mark.skipif(sys.flags.optimize == 2, reason="-OO discards docstrings") +def test_deprecate_preserve_whitespace(): + assert_('\n Bizarre' in new_func5.__doc__) + + +def test_safe_eval_nameconstant(): + # Test if safe_eval supports Python 3.4 _ast.NameConstant + utils.safe_eval('None') + + +class TestByteBounds: + + def test_byte_bounds(self): + # pointer difference matches size * itemsize + # due to contiguity + a = arange(12).reshape(3, 4) + low, high = utils.byte_bounds(a) + assert_equal(high - low, a.size * a.itemsize) + + def test_unusual_order_positive_stride(self): + a = arange(12).reshape(3, 4) + b = a.T + low, high = utils.byte_bounds(b) + assert_equal(high - low, b.size * b.itemsize) + + def test_unusual_order_negative_stride(self): + a = arange(12).reshape(3, 4) + b = a.T[::-1] + low, high = utils.byte_bounds(b) + assert_equal(high - low, b.size * b.itemsize) + + def test_strided(self): + a = arange(12) + b = a[::2] + low, high = utils.byte_bounds(b) + # the largest pointer address is lost (even numbers only in the + # stride), and compensate addresses for striding by 2 + assert_equal(high - low, b.size * 2 * b.itemsize - b.itemsize) + + +def test_assert_raises_regex_context_manager(): + with assert_raises_regex(ValueError, 'no deprecation warning'): + raise ValueError('no deprecation warning') + + +def test_info_method_heading(): + # info(class) should only print "Methods:" heading if methods exist + + class NoPublicMethods: + pass + + class WithPublicMethods: + def first_method(): + pass + + def _has_method_heading(cls): + out = StringIO() + utils.info(cls, output=out) + return 'Methods:' in out.getvalue() + + assert _has_method_heading(WithPublicMethods) + assert not _has_method_heading(NoPublicMethods) diff --git a/venv/Lib/site-packages/numpy/lib/twodim_base.py b/venv/Lib/site-packages/numpy/lib/twodim_base.py new file mode 100644 index 0000000..22a8849 --- /dev/null +++ b/venv/Lib/site-packages/numpy/lib/twodim_base.py @@ -0,0 +1,1046 @@ +""" Basic functions for manipulating 2d arrays + +""" +import functools + +from numpy.core.numeric import ( + asanyarray, arange, zeros, greater_equal, multiply, ones, + asarray, where, int8, int16, int32, int64, intp, empty, promote_types, + diagonal, nonzero, indices + ) +from numpy.core.overrides import set_array_function_like_doc, set_module +from numpy.core import overrides +from numpy.core import iinfo + + +__all__ = [ + 'diag', 'diagflat', 'eye', 'fliplr', 'flipud', 'tri', 'triu', + 'tril', 'vander', 'histogram2d', 'mask_indices', 'tril_indices', + 'tril_indices_from', 'triu_indices', 'triu_indices_from', ] + + +array_function_dispatch = functools.partial( + overrides.array_function_dispatch, module='numpy') + + +i1 = iinfo(int8) +i2 = iinfo(int16) +i4 = iinfo(int32) + + +def _min_int(low, high): + """ get small int that fits the range """ + if high <= i1.max and low >= i1.min: + return int8 + if high <= i2.max and low >= i2.min: + return int16 + if high <= i4.max and low >= i4.min: + return int32 + return int64 + + +def _flip_dispatcher(m): + return (m,) + + +@array_function_dispatch(_flip_dispatcher) +def fliplr(m): + """ + Flip array in the left/right direction. + + Flip the entries in each row in the left/right direction. + Columns are preserved, but appear in a different order than before. + + Parameters + ---------- + m : array_like + Input array, must be at least 2-D. + + Returns + ------- + f : ndarray + A view of `m` with the columns reversed. Since a view + is returned, this operation is :math:`\\mathcal O(1)`. + + See Also + -------- + flipud : Flip array in the up/down direction. + rot90 : Rotate array counterclockwise. + + Notes + ----- + Equivalent to m[:,::-1]. Requires the array to be at least 2-D. + + Examples + -------- + >>> A = np.diag([1.,2.,3.]) + >>> A + array([[1., 0., 0.], + [0., 2., 0.], + [0., 0., 3.]]) + >>> np.fliplr(A) + array([[0., 0., 1.], + [0., 2., 0.], + [3., 0., 0.]]) + + >>> A = np.random.randn(2,3,5) + >>> np.all(np.fliplr(A) == A[:,::-1,...]) + True + + """ + m = asanyarray(m) + if m.ndim < 2: + raise ValueError("Input must be >= 2-d.") + return m[:, ::-1] + + +@array_function_dispatch(_flip_dispatcher) +def flipud(m): + """ + Flip array in the up/down direction. + + Flip the entries in each column in the up/down direction. + Rows are preserved, but appear in a different order than before. + + Parameters + ---------- + m : array_like + Input array. + + Returns + ------- + out : array_like + A view of `m` with the rows reversed. Since a view is + returned, this operation is :math:`\\mathcal O(1)`. + + See Also + -------- + fliplr : Flip array in the left/right direction. + rot90 : Rotate array counterclockwise. + + Notes + ----- + Equivalent to ``m[::-1,...]``. + Does not require the array to be two-dimensional. + + Examples + -------- + >>> A = np.diag([1.0, 2, 3]) + >>> A + array([[1., 0., 0.], + [0., 2., 0.], + [0., 0., 3.]]) + >>> np.flipud(A) + array([[0., 0., 3.], + [0., 2., 0.], + [1., 0., 0.]]) + + >>> A = np.random.randn(2,3,5) + >>> np.all(np.flipud(A) == A[::-1,...]) + True + + >>> np.flipud([1,2]) + array([2, 1]) + + """ + m = asanyarray(m) + if m.ndim < 1: + raise ValueError("Input must be >= 1-d.") + return m[::-1, ...] + + +def _eye_dispatcher(N, M=None, k=None, dtype=None, order=None, *, like=None): + return (like,) + + +@set_array_function_like_doc +@set_module('numpy') +def eye(N, M=None, k=0, dtype=float, order='C', *, like=None): + """ + Return a 2-D array with ones on the diagonal and zeros elsewhere. + + Parameters + ---------- + N : int + Number of rows in the output. + M : int, optional + Number of columns in the output. If None, defaults to `N`. + k : int, optional + Index of the diagonal: 0 (the default) refers to the main diagonal, + a positive value refers to an upper diagonal, and a negative value + to a lower diagonal. + dtype : data-type, optional + Data-type of the returned array. + order : {'C', 'F'}, optional + Whether the output should be stored in row-major (C-style) or + column-major (Fortran-style) order in memory. + + .. versionadded:: 1.14.0 + ${ARRAY_FUNCTION_LIKE} + + .. versionadded:: 1.20.0 + + Returns + ------- + I : ndarray of shape (N,M) + An array where all elements are equal to zero, except for the `k`-th + diagonal, whose values are equal to one. + + See Also + -------- + identity : (almost) equivalent function + diag : diagonal 2-D array from a 1-D array specified by the user. + + Examples + -------- + >>> np.eye(2, dtype=int) + array([[1, 0], + [0, 1]]) + >>> np.eye(3, k=1) + array([[0., 1., 0.], + [0., 0., 1.], + [0., 0., 0.]]) + + """ + if like is not None: + return _eye_with_like(N, M=M, k=k, dtype=dtype, order=order, like=like) + if M is None: + M = N + m = zeros((N, M), dtype=dtype, order=order) + if k >= M: + return m + if k >= 0: + i = k + else: + i = (-k) * M + m[:M-k].flat[i::M+1] = 1 + return m + + +_eye_with_like = array_function_dispatch( + _eye_dispatcher +)(eye) + + +def _diag_dispatcher(v, k=None): + return (v,) + + +@array_function_dispatch(_diag_dispatcher) +def diag(v, k=0): + """ + Extract a diagonal or construct a diagonal array. + + See the more detailed documentation for ``numpy.diagonal`` if you use this + function to extract a diagonal and wish to write to the resulting array; + whether it returns a copy or a view depends on what version of numpy you + are using. + + Parameters + ---------- + v : array_like + If `v` is a 2-D array, return a copy of its `k`-th diagonal. + If `v` is a 1-D array, return a 2-D array with `v` on the `k`-th + diagonal. + k : int, optional + Diagonal in question. The default is 0. Use `k>0` for diagonals + above the main diagonal, and `k<0` for diagonals below the main + diagonal. + + Returns + ------- + out : ndarray + The extracted diagonal or constructed diagonal array. + + See Also + -------- + diagonal : Return specified diagonals. + diagflat : Create a 2-D array with the flattened input as a diagonal. + trace : Sum along diagonals. + triu : Upper triangle of an array. + tril : Lower triangle of an array. + + Examples + -------- + >>> x = np.arange(9).reshape((3,3)) + >>> x + array([[0, 1, 2], + [3, 4, 5], + [6, 7, 8]]) + + >>> np.diag(x) + array([0, 4, 8]) + >>> np.diag(x, k=1) + array([1, 5]) + >>> np.diag(x, k=-1) + array([3, 7]) + + >>> np.diag(np.diag(x)) + array([[0, 0, 0], + [0, 4, 0], + [0, 0, 8]]) + + """ + v = asanyarray(v) + s = v.shape + if len(s) == 1: + n = s[0]+abs(k) + res = zeros((n, n), v.dtype) + if k >= 0: + i = k + else: + i = (-k) * n + res[:n-k].flat[i::n+1] = v + return res + elif len(s) == 2: + return diagonal(v, k) + else: + raise ValueError("Input must be 1- or 2-d.") + + +@array_function_dispatch(_diag_dispatcher) +def diagflat(v, k=0): + """ + Create a two-dimensional array with the flattened input as a diagonal. + + Parameters + ---------- + v : array_like + Input data, which is flattened and set as the `k`-th + diagonal of the output. + k : int, optional + Diagonal to set; 0, the default, corresponds to the "main" diagonal, + a positive (negative) `k` giving the number of the diagonal above + (below) the main. + + Returns + ------- + out : ndarray + The 2-D output array. + + See Also + -------- + diag : MATLAB work-alike for 1-D and 2-D arrays. + diagonal : Return specified diagonals. + trace : Sum along diagonals. + + Examples + -------- + >>> np.diagflat([[1,2], [3,4]]) + array([[1, 0, 0, 0], + [0, 2, 0, 0], + [0, 0, 3, 0], + [0, 0, 0, 4]]) + + >>> np.diagflat([1,2], 1) + array([[0, 1, 0], + [0, 0, 2], + [0, 0, 0]]) + + """ + try: + wrap = v.__array_wrap__ + except AttributeError: + wrap = None + v = asarray(v).ravel() + s = len(v) + n = s + abs(k) + res = zeros((n, n), v.dtype) + if (k >= 0): + i = arange(0, n-k, dtype=intp) + fi = i+k+i*n + else: + i = arange(0, n+k, dtype=intp) + fi = i+(i-k)*n + res.flat[fi] = v + if not wrap: + return res + return wrap(res) + + +def _tri_dispatcher(N, M=None, k=None, dtype=None, *, like=None): + return (like,) + + +@set_array_function_like_doc +@set_module('numpy') +def tri(N, M=None, k=0, dtype=float, *, like=None): + """ + An array with ones at and below the given diagonal and zeros elsewhere. + + Parameters + ---------- + N : int + Number of rows in the array. + M : int, optional + Number of columns in the array. + By default, `M` is taken equal to `N`. + k : int, optional + The sub-diagonal at and below which the array is filled. + `k` = 0 is the main diagonal, while `k` < 0 is below it, + and `k` > 0 is above. The default is 0. + dtype : dtype, optional + Data type of the returned array. The default is float. + ${ARRAY_FUNCTION_LIKE} + + .. versionadded:: 1.20.0 + + Returns + ------- + tri : ndarray of shape (N, M) + Array with its lower triangle filled with ones and zero elsewhere; + in other words ``T[i,j] == 1`` for ``j <= i + k``, 0 otherwise. + + Examples + -------- + >>> np.tri(3, 5, 2, dtype=int) + array([[1, 1, 1, 0, 0], + [1, 1, 1, 1, 0], + [1, 1, 1, 1, 1]]) + + >>> np.tri(3, 5, -1) + array([[0., 0., 0., 0., 0.], + [1., 0., 0., 0., 0.], + [1., 1., 0., 0., 0.]]) + + """ + if like is not None: + return _tri_with_like(N, M=M, k=k, dtype=dtype, like=like) + + if M is None: + M = N + + m = greater_equal.outer(arange(N, dtype=_min_int(0, N)), + arange(-k, M-k, dtype=_min_int(-k, M - k))) + + # Avoid making a copy if the requested type is already bool + m = m.astype(dtype, copy=False) + + return m + + +_tri_with_like = array_function_dispatch( + _tri_dispatcher +)(tri) + + +def _trilu_dispatcher(m, k=None): + return (m,) + + +@array_function_dispatch(_trilu_dispatcher) +def tril(m, k=0): + """ + Lower triangle of an array. + + Return a copy of an array with elements above the `k`-th diagonal zeroed. + + Parameters + ---------- + m : array_like, shape (M, N) + Input array. + k : int, optional + Diagonal above which to zero elements. `k = 0` (the default) is the + main diagonal, `k < 0` is below it and `k > 0` is above. + + Returns + ------- + tril : ndarray, shape (M, N) + Lower triangle of `m`, of same shape and data-type as `m`. + + See Also + -------- + triu : same thing, only for the upper triangle + + Examples + -------- + >>> np.tril([[1,2,3],[4,5,6],[7,8,9],[10,11,12]], -1) + array([[ 0, 0, 0], + [ 4, 0, 0], + [ 7, 8, 0], + [10, 11, 12]]) + + """ + m = asanyarray(m) + mask = tri(*m.shape[-2:], k=k, dtype=bool) + + return where(mask, m, zeros(1, m.dtype)) + + +@array_function_dispatch(_trilu_dispatcher) +def triu(m, k=0): + """ + Upper triangle of an array. + + Return a copy of an array with the elements below the `k`-th diagonal + zeroed. + + Please refer to the documentation for `tril` for further details. + + See Also + -------- + tril : lower triangle of an array + + Examples + -------- + >>> np.triu([[1,2,3],[4,5,6],[7,8,9],[10,11,12]], -1) + array([[ 1, 2, 3], + [ 4, 5, 6], + [ 0, 8, 9], + [ 0, 0, 12]]) + + """ + m = asanyarray(m) + mask = tri(*m.shape[-2:], k=k-1, dtype=bool) + + return where(mask, zeros(1, m.dtype), m) + + +def _vander_dispatcher(x, N=None, increasing=None): + return (x,) + + +# Originally borrowed from John Hunter and matplotlib +@array_function_dispatch(_vander_dispatcher) +def vander(x, N=None, increasing=False): + """ + Generate a Vandermonde matrix. + + The columns of the output matrix are powers of the input vector. The + order of the powers is determined by the `increasing` boolean argument. + Specifically, when `increasing` is False, the `i`-th output column is + the input vector raised element-wise to the power of ``N - i - 1``. Such + a matrix with a geometric progression in each row is named for Alexandre- + Theophile Vandermonde. + + Parameters + ---------- + x : array_like + 1-D input array. + N : int, optional + Number of columns in the output. If `N` is not specified, a square + array is returned (``N = len(x)``). + increasing : bool, optional + Order of the powers of the columns. If True, the powers increase + from left to right, if False (the default) they are reversed. + + .. versionadded:: 1.9.0 + + Returns + ------- + out : ndarray + Vandermonde matrix. If `increasing` is False, the first column is + ``x^(N-1)``, the second ``x^(N-2)`` and so forth. If `increasing` is + True, the columns are ``x^0, x^1, ..., x^(N-1)``. + + See Also + -------- + polynomial.polynomial.polyvander + + Examples + -------- + >>> x = np.array([1, 2, 3, 5]) + >>> N = 3 + >>> np.vander(x, N) + array([[ 1, 1, 1], + [ 4, 2, 1], + [ 9, 3, 1], + [25, 5, 1]]) + + >>> np.column_stack([x**(N-1-i) for i in range(N)]) + array([[ 1, 1, 1], + [ 4, 2, 1], + [ 9, 3, 1], + [25, 5, 1]]) + + >>> x = np.array([1, 2, 3, 5]) + >>> np.vander(x) + array([[ 1, 1, 1, 1], + [ 8, 4, 2, 1], + [ 27, 9, 3, 1], + [125, 25, 5, 1]]) + >>> np.vander(x, increasing=True) + array([[ 1, 1, 1, 1], + [ 1, 2, 4, 8], + [ 1, 3, 9, 27], + [ 1, 5, 25, 125]]) + + The determinant of a square Vandermonde matrix is the product + of the differences between the values of the input vector: + + >>> np.linalg.det(np.vander(x)) + 48.000000000000043 # may vary + >>> (5-3)*(5-2)*(5-1)*(3-2)*(3-1)*(2-1) + 48 + + """ + x = asarray(x) + if x.ndim != 1: + raise ValueError("x must be a one-dimensional array or sequence.") + if N is None: + N = len(x) + + v = empty((len(x), N), dtype=promote_types(x.dtype, int)) + tmp = v[:, ::-1] if not increasing else v + + if N > 0: + tmp[:, 0] = 1 + if N > 1: + tmp[:, 1:] = x[:, None] + multiply.accumulate(tmp[:, 1:], out=tmp[:, 1:], axis=1) + + return v + + +def _histogram2d_dispatcher(x, y, bins=None, range=None, normed=None, + weights=None, density=None): + yield x + yield y + + # This terrible logic is adapted from the checks in histogram2d + try: + N = len(bins) + except TypeError: + N = 1 + if N == 2: + yield from bins # bins=[x, y] + else: + yield bins + + yield weights + + +@array_function_dispatch(_histogram2d_dispatcher) +def histogram2d(x, y, bins=10, range=None, normed=None, weights=None, + density=None): + """ + Compute the bi-dimensional histogram of two data samples. + + Parameters + ---------- + x : array_like, shape (N,) + An array containing the x coordinates of the points to be + histogrammed. + y : array_like, shape (N,) + An array containing the y coordinates of the points to be + histogrammed. + bins : int or array_like or [int, int] or [array, array], optional + The bin specification: + + * If int, the number of bins for the two dimensions (nx=ny=bins). + * If array_like, the bin edges for the two dimensions + (x_edges=y_edges=bins). + * If [int, int], the number of bins in each dimension + (nx, ny = bins). + * If [array, array], the bin edges in each dimension + (x_edges, y_edges = bins). + * A combination [int, array] or [array, int], where int + is the number of bins and array is the bin edges. + + range : array_like, shape(2,2), optional + The leftmost and rightmost edges of the bins along each dimension + (if not specified explicitly in the `bins` parameters): + ``[[xmin, xmax], [ymin, ymax]]``. All values outside of this range + will be considered outliers and not tallied in the histogram. + density : bool, optional + If False, the default, returns the number of samples in each bin. + If True, returns the probability *density* function at the bin, + ``bin_count / sample_count / bin_area``. + normed : bool, optional + An alias for the density argument that behaves identically. To avoid + confusion with the broken normed argument to `histogram`, `density` + should be preferred. + weights : array_like, shape(N,), optional + An array of values ``w_i`` weighing each sample ``(x_i, y_i)``. + Weights are normalized to 1 if `normed` is True. If `normed` is + False, the values of the returned histogram are equal to the sum of + the weights belonging to the samples falling into each bin. + + Returns + ------- + H : ndarray, shape(nx, ny) + The bi-dimensional histogram of samples `x` and `y`. Values in `x` + are histogrammed along the first dimension and values in `y` are + histogrammed along the second dimension. + xedges : ndarray, shape(nx+1,) + The bin edges along the first dimension. + yedges : ndarray, shape(ny+1,) + The bin edges along the second dimension. + + See Also + -------- + histogram : 1D histogram + histogramdd : Multidimensional histogram + + Notes + ----- + When `normed` is True, then the returned histogram is the sample + density, defined such that the sum over bins of the product + ``bin_value * bin_area`` is 1. + + Please note that the histogram does not follow the Cartesian convention + where `x` values are on the abscissa and `y` values on the ordinate + axis. Rather, `x` is histogrammed along the first dimension of the + array (vertical), and `y` along the second dimension of the array + (horizontal). This ensures compatibility with `histogramdd`. + + Examples + -------- + >>> from matplotlib.image import NonUniformImage + >>> import matplotlib.pyplot as plt + + Construct a 2-D histogram with variable bin width. First define the bin + edges: + + >>> xedges = [0, 1, 3, 5] + >>> yedges = [0, 2, 3, 4, 6] + + Next we create a histogram H with random bin content: + + >>> x = np.random.normal(2, 1, 100) + >>> y = np.random.normal(1, 1, 100) + >>> H, xedges, yedges = np.histogram2d(x, y, bins=(xedges, yedges)) + >>> H = H.T # Let each row list bins with common y range. + + :func:`imshow ` can only display square bins: + + >>> fig = plt.figure(figsize=(7, 3)) + >>> ax = fig.add_subplot(131, title='imshow: square bins') + >>> plt.imshow(H, interpolation='nearest', origin='lower', + ... extent=[xedges[0], xedges[-1], yedges[0], yedges[-1]]) + + + :func:`pcolormesh ` can display actual edges: + + >>> ax = fig.add_subplot(132, title='pcolormesh: actual edges', + ... aspect='equal') + >>> X, Y = np.meshgrid(xedges, yedges) + >>> ax.pcolormesh(X, Y, H) + + + :class:`NonUniformImage ` can be used to + display actual bin edges with interpolation: + + >>> ax = fig.add_subplot(133, title='NonUniformImage: interpolated', + ... aspect='equal', xlim=xedges[[0, -1]], ylim=yedges[[0, -1]]) + >>> im = NonUniformImage(ax, interpolation='bilinear') + >>> xcenters = (xedges[:-1] + xedges[1:]) / 2 + >>> ycenters = (yedges[:-1] + yedges[1:]) / 2 + >>> im.set_data(xcenters, ycenters, H) + >>> ax.images.append(im) + >>> plt.show() + + """ + from numpy import histogramdd + + try: + N = len(bins) + except TypeError: + N = 1 + + if N != 1 and N != 2: + xedges = yedges = asarray(bins) + bins = [xedges, yedges] + hist, edges = histogramdd([x, y], bins, range, normed, weights, density) + return hist, edges[0], edges[1] + + +@set_module('numpy') +def mask_indices(n, mask_func, k=0): + """ + Return the indices to access (n, n) arrays, given a masking function. + + Assume `mask_func` is a function that, for a square array a of size + ``(n, n)`` with a possible offset argument `k`, when called as + ``mask_func(a, k)`` returns a new array with zeros in certain locations + (functions like `triu` or `tril` do precisely this). Then this function + returns the indices where the non-zero values would be located. + + Parameters + ---------- + n : int + The returned indices will be valid to access arrays of shape (n, n). + mask_func : callable + A function whose call signature is similar to that of `triu`, `tril`. + That is, ``mask_func(x, k)`` returns a boolean array, shaped like `x`. + `k` is an optional argument to the function. + k : scalar + An optional argument which is passed through to `mask_func`. Functions + like `triu`, `tril` take a second argument that is interpreted as an + offset. + + Returns + ------- + indices : tuple of arrays. + The `n` arrays of indices corresponding to the locations where + ``mask_func(np.ones((n, n)), k)`` is True. + + See Also + -------- + triu, tril, triu_indices, tril_indices + + Notes + ----- + .. versionadded:: 1.4.0 + + Examples + -------- + These are the indices that would allow you to access the upper triangular + part of any 3x3 array: + + >>> iu = np.mask_indices(3, np.triu) + + For example, if `a` is a 3x3 array: + + >>> a = np.arange(9).reshape(3, 3) + >>> a + array([[0, 1, 2], + [3, 4, 5], + [6, 7, 8]]) + >>> a[iu] + array([0, 1, 2, 4, 5, 8]) + + An offset can be passed also to the masking function. This gets us the + indices starting on the first diagonal right of the main one: + + >>> iu1 = np.mask_indices(3, np.triu, 1) + + with which we now extract only three elements: + + >>> a[iu1] + array([1, 2, 5]) + + """ + m = ones((n, n), int) + a = mask_func(m, k) + return nonzero(a != 0) + + +@set_module('numpy') +def tril_indices(n, k=0, m=None): + """ + Return the indices for the lower-triangle of an (n, m) array. + + Parameters + ---------- + n : int + The row dimension of the arrays for which the returned + indices will be valid. + k : int, optional + Diagonal offset (see `tril` for details). + m : int, optional + .. versionadded:: 1.9.0 + + The column dimension of the arrays for which the returned + arrays will be valid. + By default `m` is taken equal to `n`. + + + Returns + ------- + inds : tuple of arrays + The indices for the triangle. The returned tuple contains two arrays, + each with the indices along one dimension of the array. + + See also + -------- + triu_indices : similar function, for upper-triangular. + mask_indices : generic function accepting an arbitrary mask function. + tril, triu + + Notes + ----- + .. versionadded:: 1.4.0 + + Examples + -------- + Compute two different sets of indices to access 4x4 arrays, one for the + lower triangular part starting at the main diagonal, and one starting two + diagonals further right: + + >>> il1 = np.tril_indices(4) + >>> il2 = np.tril_indices(4, 2) + + Here is how they can be used with a sample array: + + >>> a = np.arange(16).reshape(4, 4) + >>> a + array([[ 0, 1, 2, 3], + [ 4, 5, 6, 7], + [ 8, 9, 10, 11], + [12, 13, 14, 15]]) + + Both for indexing: + + >>> a[il1] + array([ 0, 4, 5, ..., 13, 14, 15]) + + And for assigning values: + + >>> a[il1] = -1 + >>> a + array([[-1, 1, 2, 3], + [-1, -1, 6, 7], + [-1, -1, -1, 11], + [-1, -1, -1, -1]]) + + These cover almost the whole array (two diagonals right of the main one): + + >>> a[il2] = -10 + >>> a + array([[-10, -10, -10, 3], + [-10, -10, -10, -10], + [-10, -10, -10, -10], + [-10, -10, -10, -10]]) + + """ + return nonzero(tri(n, m, k=k, dtype=bool)) + + +def _trilu_indices_form_dispatcher(arr, k=None): + return (arr,) + + +@array_function_dispatch(_trilu_indices_form_dispatcher) +def tril_indices_from(arr, k=0): + """ + Return the indices for the lower-triangle of arr. + + See `tril_indices` for full details. + + Parameters + ---------- + arr : array_like + The indices will be valid for square arrays whose dimensions are + the same as arr. + k : int, optional + Diagonal offset (see `tril` for details). + + See Also + -------- + tril_indices, tril + + Notes + ----- + .. versionadded:: 1.4.0 + + """ + if arr.ndim != 2: + raise ValueError("input array must be 2-d") + return tril_indices(arr.shape[-2], k=k, m=arr.shape[-1]) + + +@set_module('numpy') +def triu_indices(n, k=0, m=None): + """ + Return the indices for the upper-triangle of an (n, m) array. + + Parameters + ---------- + n : int + The size of the arrays for which the returned indices will + be valid. + k : int, optional + Diagonal offset (see `triu` for details). + m : int, optional + .. versionadded:: 1.9.0 + + The column dimension of the arrays for which the returned + arrays will be valid. + By default `m` is taken equal to `n`. + + + Returns + ------- + inds : tuple, shape(2) of ndarrays, shape(`n`) + The indices for the triangle. The returned tuple contains two arrays, + each with the indices along one dimension of the array. Can be used + to slice a ndarray of shape(`n`, `n`). + + See also + -------- + tril_indices : similar function, for lower-triangular. + mask_indices : generic function accepting an arbitrary mask function. + triu, tril + + Notes + ----- + .. versionadded:: 1.4.0 + + Examples + -------- + Compute two different sets of indices to access 4x4 arrays, one for the + upper triangular part starting at the main diagonal, and one starting two + diagonals further right: + + >>> iu1 = np.triu_indices(4) + >>> iu2 = np.triu_indices(4, 2) + + Here is how they can be used with a sample array: + + >>> a = np.arange(16).reshape(4, 4) + >>> a + array([[ 0, 1, 2, 3], + [ 4, 5, 6, 7], + [ 8, 9, 10, 11], + [12, 13, 14, 15]]) + + Both for indexing: + + >>> a[iu1] + array([ 0, 1, 2, ..., 10, 11, 15]) + + And for assigning values: + + >>> a[iu1] = -1 + >>> a + array([[-1, -1, -1, -1], + [ 4, -1, -1, -1], + [ 8, 9, -1, -1], + [12, 13, 14, -1]]) + + These cover only a small part of the whole array (two diagonals right + of the main one): + + >>> a[iu2] = -10 + >>> a + array([[ -1, -1, -10, -10], + [ 4, -1, -1, -10], + [ 8, 9, -1, -1], + [ 12, 13, 14, -1]]) + + """ + return nonzero(~tri(n, m, k=k-1, dtype=bool)) + + +@array_function_dispatch(_trilu_indices_form_dispatcher) +def triu_indices_from(arr, k=0): + """ + Return the indices for the upper-triangle of arr. + + See `triu_indices` for full details. + + Parameters + ---------- + arr : ndarray, shape(N, N) + The indices will be valid for square arrays. + k : int, optional + Diagonal offset (see `triu` for details). + + Returns + ------- + triu_indices_from : tuple, shape(2) of ndarray, shape(N) + Indices for the upper-triangle of `arr`. + + See Also + -------- + triu_indices, triu + + Notes + ----- + .. versionadded:: 1.4.0 + + """ + if arr.ndim != 2: + raise ValueError("input array must be 2-d") + return triu_indices(arr.shape[-2], k=k, m=arr.shape[-1]) diff --git a/venv/Lib/site-packages/numpy/lib/type_check.py b/venv/Lib/site-packages/numpy/lib/type_check.py new file mode 100644 index 0000000..2a2982a --- /dev/null +++ b/venv/Lib/site-packages/numpy/lib/type_check.py @@ -0,0 +1,732 @@ +"""Automatically adapted for numpy Sep 19, 2005 by convertcode.py + +""" +import functools +import warnings + +__all__ = ['iscomplexobj', 'isrealobj', 'imag', 'iscomplex', + 'isreal', 'nan_to_num', 'real', 'real_if_close', + 'typename', 'asfarray', 'mintypecode', 'asscalar', + 'common_type'] + +import numpy.core.numeric as _nx +from numpy.core.numeric import asarray, asanyarray, isnan, zeros +from numpy.core.overrides import set_module +from numpy.core import overrides +from .ufunclike import isneginf, isposinf + + +array_function_dispatch = functools.partial( + overrides.array_function_dispatch, module='numpy') + + +_typecodes_by_elsize = 'GDFgdfQqLlIiHhBb?' + + +@set_module('numpy') +def mintypecode(typechars, typeset='GDFgdf', default='d'): + """ + Return the character for the minimum-size type to which given types can + be safely cast. + + The returned type character must represent the smallest size dtype such + that an array of the returned type can handle the data from an array of + all types in `typechars` (or if `typechars` is an array, then its + dtype.char). + + Parameters + ---------- + typechars : list of str or array_like + If a list of strings, each string should represent a dtype. + If array_like, the character representation of the array dtype is used. + typeset : str or list of str, optional + The set of characters that the returned character is chosen from. + The default set is 'GDFgdf'. + default : str, optional + The default character, this is returned if none of the characters in + `typechars` matches a character in `typeset`. + + Returns + ------- + typechar : str + The character representing the minimum-size type that was found. + + See Also + -------- + dtype, sctype2char, maximum_sctype + + Examples + -------- + >>> np.mintypecode(['d', 'f', 'S']) + 'd' + >>> x = np.array([1.1, 2-3.j]) + >>> np.mintypecode(x) + 'D' + + >>> np.mintypecode('abceh', default='G') + 'G' + + """ + typecodes = ((isinstance(t, str) and t) or asarray(t).dtype.char + for t in typechars) + intersection = set(t for t in typecodes if t in typeset) + if not intersection: + return default + if 'F' in intersection and 'd' in intersection: + return 'D' + return min(intersection, key=_typecodes_by_elsize.index) + + +def _asfarray_dispatcher(a, dtype=None): + return (a,) + + +@array_function_dispatch(_asfarray_dispatcher) +def asfarray(a, dtype=_nx.float_): + """ + Return an array converted to a float type. + + Parameters + ---------- + a : array_like + The input array. + dtype : str or dtype object, optional + Float type code to coerce input array `a`. If `dtype` is one of the + 'int' dtypes, it is replaced with float64. + + Returns + ------- + out : ndarray + The input `a` as a float ndarray. + + Examples + -------- + >>> np.asfarray([2, 3]) + array([2., 3.]) + >>> np.asfarray([2, 3], dtype='float') + array([2., 3.]) + >>> np.asfarray([2, 3], dtype='int8') + array([2., 3.]) + + """ + if not _nx.issubdtype(dtype, _nx.inexact): + dtype = _nx.float_ + return asarray(a, dtype=dtype) + + +def _real_dispatcher(val): + return (val,) + + +@array_function_dispatch(_real_dispatcher) +def real(val): + """ + Return the real part of the complex argument. + + Parameters + ---------- + val : array_like + Input array. + + Returns + ------- + out : ndarray or scalar + The real component of the complex argument. If `val` is real, the type + of `val` is used for the output. If `val` has complex elements, the + returned type is float. + + See Also + -------- + real_if_close, imag, angle + + Examples + -------- + >>> a = np.array([1+2j, 3+4j, 5+6j]) + >>> a.real + array([1., 3., 5.]) + >>> a.real = 9 + >>> a + array([9.+2.j, 9.+4.j, 9.+6.j]) + >>> a.real = np.array([9, 8, 7]) + >>> a + array([9.+2.j, 8.+4.j, 7.+6.j]) + >>> np.real(1 + 1j) + 1.0 + + """ + try: + return val.real + except AttributeError: + return asanyarray(val).real + + +def _imag_dispatcher(val): + return (val,) + + +@array_function_dispatch(_imag_dispatcher) +def imag(val): + """ + Return the imaginary part of the complex argument. + + Parameters + ---------- + val : array_like + Input array. + + Returns + ------- + out : ndarray or scalar + The imaginary component of the complex argument. If `val` is real, + the type of `val` is used for the output. If `val` has complex + elements, the returned type is float. + + See Also + -------- + real, angle, real_if_close + + Examples + -------- + >>> a = np.array([1+2j, 3+4j, 5+6j]) + >>> a.imag + array([2., 4., 6.]) + >>> a.imag = np.array([8, 10, 12]) + >>> a + array([1. +8.j, 3.+10.j, 5.+12.j]) + >>> np.imag(1 + 1j) + 1.0 + + """ + try: + return val.imag + except AttributeError: + return asanyarray(val).imag + + +def _is_type_dispatcher(x): + return (x,) + + +@array_function_dispatch(_is_type_dispatcher) +def iscomplex(x): + """ + Returns a bool array, where True if input element is complex. + + What is tested is whether the input has a non-zero imaginary part, not if + the input type is complex. + + Parameters + ---------- + x : array_like + Input array. + + Returns + ------- + out : ndarray of bools + Output array. + + See Also + -------- + isreal + iscomplexobj : Return True if x is a complex type or an array of complex + numbers. + + Examples + -------- + >>> np.iscomplex([1+1j, 1+0j, 4.5, 3, 2, 2j]) + array([ True, False, False, False, False, True]) + + """ + ax = asanyarray(x) + if issubclass(ax.dtype.type, _nx.complexfloating): + return ax.imag != 0 + res = zeros(ax.shape, bool) + return res[()] # convert to scalar if needed + + +@array_function_dispatch(_is_type_dispatcher) +def isreal(x): + """ + Returns a bool array, where True if input element is real. + + If element has complex type with zero complex part, the return value + for that element is True. + + Parameters + ---------- + x : array_like + Input array. + + Returns + ------- + out : ndarray, bool + Boolean array of same shape as `x`. + + See Also + -------- + iscomplex + isrealobj : Return True if x is not a complex type. + + Examples + -------- + >>> np.isreal([1+1j, 1+0j, 4.5, 3, 2, 2j]) + array([False, True, True, True, True, False]) + + """ + return imag(x) == 0 + + +@array_function_dispatch(_is_type_dispatcher) +def iscomplexobj(x): + """ + Check for a complex type or an array of complex numbers. + + The type of the input is checked, not the value. Even if the input + has an imaginary part equal to zero, `iscomplexobj` evaluates to True. + + Parameters + ---------- + x : any + The input can be of any type and shape. + + Returns + ------- + iscomplexobj : bool + The return value, True if `x` is of a complex type or has at least + one complex element. + + See Also + -------- + isrealobj, iscomplex + + Examples + -------- + >>> np.iscomplexobj(1) + False + >>> np.iscomplexobj(1+0j) + True + >>> np.iscomplexobj([3, 1+0j, True]) + True + + """ + try: + dtype = x.dtype + type_ = dtype.type + except AttributeError: + type_ = asarray(x).dtype.type + return issubclass(type_, _nx.complexfloating) + + +@array_function_dispatch(_is_type_dispatcher) +def isrealobj(x): + """ + Return True if x is a not complex type or an array of complex numbers. + + The type of the input is checked, not the value. So even if the input + has an imaginary part equal to zero, `isrealobj` evaluates to False + if the data type is complex. + + Parameters + ---------- + x : any + The input can be of any type and shape. + + Returns + ------- + y : bool + The return value, False if `x` is of a complex type. + + See Also + -------- + iscomplexobj, isreal + + Examples + -------- + >>> np.isrealobj(1) + True + >>> np.isrealobj(1+0j) + False + >>> np.isrealobj([3, 1+0j, True]) + False + + """ + return not iscomplexobj(x) + +#----------------------------------------------------------------------------- + +def _getmaxmin(t): + from numpy.core import getlimits + f = getlimits.finfo(t) + return f.max, f.min + + +def _nan_to_num_dispatcher(x, copy=None, nan=None, posinf=None, neginf=None): + return (x,) + + +@array_function_dispatch(_nan_to_num_dispatcher) +def nan_to_num(x, copy=True, nan=0.0, posinf=None, neginf=None): + """ + Replace NaN with zero and infinity with large finite numbers (default + behaviour) or with the numbers defined by the user using the `nan`, + `posinf` and/or `neginf` keywords. + + If `x` is inexact, NaN is replaced by zero or by the user defined value in + `nan` keyword, infinity is replaced by the largest finite floating point + values representable by ``x.dtype`` or by the user defined value in + `posinf` keyword and -infinity is replaced by the most negative finite + floating point values representable by ``x.dtype`` or by the user defined + value in `neginf` keyword. + + For complex dtypes, the above is applied to each of the real and + imaginary components of `x` separately. + + If `x` is not inexact, then no replacements are made. + + Parameters + ---------- + x : scalar or array_like + Input data. + copy : bool, optional + Whether to create a copy of `x` (True) or to replace values + in-place (False). The in-place operation only occurs if + casting to an array does not require a copy. + Default is True. + + .. versionadded:: 1.13 + nan : int, float, optional + Value to be used to fill NaN values. If no value is passed + then NaN values will be replaced with 0.0. + + .. versionadded:: 1.17 + posinf : int, float, optional + Value to be used to fill positive infinity values. If no value is + passed then positive infinity values will be replaced with a very + large number. + + .. versionadded:: 1.17 + neginf : int, float, optional + Value to be used to fill negative infinity values. If no value is + passed then negative infinity values will be replaced with a very + small (or negative) number. + + .. versionadded:: 1.17 + + + + Returns + ------- + out : ndarray + `x`, with the non-finite values replaced. If `copy` is False, this may + be `x` itself. + + See Also + -------- + isinf : Shows which elements are positive or negative infinity. + isneginf : Shows which elements are negative infinity. + isposinf : Shows which elements are positive infinity. + isnan : Shows which elements are Not a Number (NaN). + isfinite : Shows which elements are finite (not NaN, not infinity) + + Notes + ----- + NumPy uses the IEEE Standard for Binary Floating-Point for Arithmetic + (IEEE 754). This means that Not a Number is not equivalent to infinity. + + Examples + -------- + >>> np.nan_to_num(np.inf) + 1.7976931348623157e+308 + >>> np.nan_to_num(-np.inf) + -1.7976931348623157e+308 + >>> np.nan_to_num(np.nan) + 0.0 + >>> x = np.array([np.inf, -np.inf, np.nan, -128, 128]) + >>> np.nan_to_num(x) + array([ 1.79769313e+308, -1.79769313e+308, 0.00000000e+000, # may vary + -1.28000000e+002, 1.28000000e+002]) + >>> np.nan_to_num(x, nan=-9999, posinf=33333333, neginf=33333333) + array([ 3.3333333e+07, 3.3333333e+07, -9.9990000e+03, + -1.2800000e+02, 1.2800000e+02]) + >>> y = np.array([complex(np.inf, np.nan), np.nan, complex(np.nan, np.inf)]) + array([ 1.79769313e+308, -1.79769313e+308, 0.00000000e+000, # may vary + -1.28000000e+002, 1.28000000e+002]) + >>> np.nan_to_num(y) + array([ 1.79769313e+308 +0.00000000e+000j, # may vary + 0.00000000e+000 +0.00000000e+000j, + 0.00000000e+000 +1.79769313e+308j]) + >>> np.nan_to_num(y, nan=111111, posinf=222222) + array([222222.+111111.j, 111111. +0.j, 111111.+222222.j]) + """ + x = _nx.array(x, subok=True, copy=copy) + xtype = x.dtype.type + + isscalar = (x.ndim == 0) + + if not issubclass(xtype, _nx.inexact): + return x[()] if isscalar else x + + iscomplex = issubclass(xtype, _nx.complexfloating) + + dest = (x.real, x.imag) if iscomplex else (x,) + maxf, minf = _getmaxmin(x.real.dtype) + if posinf is not None: + maxf = posinf + if neginf is not None: + minf = neginf + for d in dest: + idx_nan = isnan(d) + idx_posinf = isposinf(d) + idx_neginf = isneginf(d) + _nx.copyto(d, nan, where=idx_nan) + _nx.copyto(d, maxf, where=idx_posinf) + _nx.copyto(d, minf, where=idx_neginf) + return x[()] if isscalar else x + +#----------------------------------------------------------------------------- + +def _real_if_close_dispatcher(a, tol=None): + return (a,) + + +@array_function_dispatch(_real_if_close_dispatcher) +def real_if_close(a, tol=100): + """ + If input is complex with all imaginary parts close to zero, return + real parts. + + "Close to zero" is defined as `tol` * (machine epsilon of the type for + `a`). + + Parameters + ---------- + a : array_like + Input array. + tol : float + Tolerance in machine epsilons for the complex part of the elements + in the array. + + Returns + ------- + out : ndarray + If `a` is real, the type of `a` is used for the output. If `a` + has complex elements, the returned type is float. + + See Also + -------- + real, imag, angle + + Notes + ----- + Machine epsilon varies from machine to machine and between data types + but Python floats on most platforms have a machine epsilon equal to + 2.2204460492503131e-16. You can use 'np.finfo(float).eps' to print + out the machine epsilon for floats. + + Examples + -------- + >>> np.finfo(float).eps + 2.2204460492503131e-16 # may vary + + >>> np.real_if_close([2.1 + 4e-14j, 5.2 + 3e-15j], tol=1000) + array([2.1, 5.2]) + >>> np.real_if_close([2.1 + 4e-13j, 5.2 + 3e-15j], tol=1000) + array([2.1+4.e-13j, 5.2 + 3e-15j]) + + """ + a = asanyarray(a) + if not issubclass(a.dtype.type, _nx.complexfloating): + return a + if tol > 1: + from numpy.core import getlimits + f = getlimits.finfo(a.dtype.type) + tol = f.eps * tol + if _nx.all(_nx.absolute(a.imag) < tol): + a = a.real + return a + + +def _asscalar_dispatcher(a): + # 2018-10-10, 1.16 + warnings.warn('np.asscalar(a) is deprecated since NumPy v1.16, use ' + 'a.item() instead', DeprecationWarning, stacklevel=3) + return (a,) + + +@array_function_dispatch(_asscalar_dispatcher) +def asscalar(a): + """ + Convert an array of size 1 to its scalar equivalent. + + .. deprecated:: 1.16 + + Deprecated, use `numpy.ndarray.item()` instead. + + Parameters + ---------- + a : ndarray + Input array of size 1. + + Returns + ------- + out : scalar + Scalar representation of `a`. The output data type is the same type + returned by the input's `item` method. + + Examples + -------- + >>> np.asscalar(np.array([24])) + 24 + """ + return a.item() + +#----------------------------------------------------------------------------- + +_namefromtype = {'S1': 'character', + '?': 'bool', + 'b': 'signed char', + 'B': 'unsigned char', + 'h': 'short', + 'H': 'unsigned short', + 'i': 'integer', + 'I': 'unsigned integer', + 'l': 'long integer', + 'L': 'unsigned long integer', + 'q': 'long long integer', + 'Q': 'unsigned long long integer', + 'f': 'single precision', + 'd': 'double precision', + 'g': 'long precision', + 'F': 'complex single precision', + 'D': 'complex double precision', + 'G': 'complex long double precision', + 'S': 'string', + 'U': 'unicode', + 'V': 'void', + 'O': 'object' + } + +@set_module('numpy') +def typename(char): + """ + Return a description for the given data type code. + + Parameters + ---------- + char : str + Data type code. + + Returns + ------- + out : str + Description of the input data type code. + + See Also + -------- + dtype, typecodes + + Examples + -------- + >>> typechars = ['S1', '?', 'B', 'D', 'G', 'F', 'I', 'H', 'L', 'O', 'Q', + ... 'S', 'U', 'V', 'b', 'd', 'g', 'f', 'i', 'h', 'l', 'q'] + >>> for typechar in typechars: + ... print(typechar, ' : ', np.typename(typechar)) + ... + S1 : character + ? : bool + B : unsigned char + D : complex double precision + G : complex long double precision + F : complex single precision + I : unsigned integer + H : unsigned short + L : unsigned long integer + O : object + Q : unsigned long long integer + S : string + U : unicode + V : void + b : signed char + d : double precision + g : long precision + f : single precision + i : integer + h : short + l : long integer + q : long long integer + + """ + return _namefromtype[char] + +#----------------------------------------------------------------------------- + +#determine the "minimum common type" for a group of arrays. +array_type = [[_nx.half, _nx.single, _nx.double, _nx.longdouble], + [None, _nx.csingle, _nx.cdouble, _nx.clongdouble]] +array_precision = {_nx.half: 0, + _nx.single: 1, + _nx.double: 2, + _nx.longdouble: 3, + _nx.csingle: 1, + _nx.cdouble: 2, + _nx.clongdouble: 3} + + +def _common_type_dispatcher(*arrays): + return arrays + + +@array_function_dispatch(_common_type_dispatcher) +def common_type(*arrays): + """ + Return a scalar type which is common to the input arrays. + + The return type will always be an inexact (i.e. floating point) scalar + type, even if all the arrays are integer arrays. If one of the inputs is + an integer array, the minimum precision type that is returned is a + 64-bit floating point dtype. + + All input arrays except int64 and uint64 can be safely cast to the + returned dtype without loss of information. + + Parameters + ---------- + array1, array2, ... : ndarrays + Input arrays. + + Returns + ------- + out : data type code + Data type code. + + See Also + -------- + dtype, mintypecode + + Examples + -------- + >>> np.common_type(np.arange(2, dtype=np.float32)) + + >>> np.common_type(np.arange(2, dtype=np.float32), np.arange(2)) + + >>> np.common_type(np.arange(4), np.array([45, 6.j]), np.array([45.0])) + + + """ + is_complex = False + precision = 0 + for a in arrays: + t = a.dtype.type + if iscomplexobj(a): + is_complex = True + if issubclass(t, _nx.integer): + p = 2 # array_precision[_nx.double] + else: + p = array_precision.get(t, None) + if p is None: + raise TypeError("can't get common type for non-numeric array") + precision = max(precision, p) + if is_complex: + return array_type[1][precision] + else: + return array_type[0][precision] diff --git a/venv/Lib/site-packages/numpy/lib/ufunclike.py b/venv/Lib/site-packages/numpy/lib/ufunclike.py new file mode 100644 index 0000000..1f26a18 --- /dev/null +++ b/venv/Lib/site-packages/numpy/lib/ufunclike.py @@ -0,0 +1,266 @@ +""" +Module of functions that are like ufuncs in acting on arrays and optionally +storing results in an output array. + +""" +__all__ = ['fix', 'isneginf', 'isposinf'] + +import numpy.core.numeric as nx +from numpy.core.overrides import ( + array_function_dispatch, ARRAY_FUNCTION_ENABLED, +) +import warnings +import functools + + +def _deprecate_out_named_y(f): + """ + Allow the out argument to be passed as the name `y` (deprecated) + + In future, this decorator should be removed. + """ + @functools.wraps(f) + def func(x, out=None, **kwargs): + if 'y' in kwargs: + if 'out' in kwargs: + raise TypeError( + "{} got multiple values for argument 'out'/'y'" + .format(f.__name__) + ) + out = kwargs.pop('y') + # NumPy 1.13.0, 2017-04-26 + warnings.warn( + "The name of the out argument to {} has changed from `y` to " + "`out`, to match other ufuncs.".format(f.__name__), + DeprecationWarning, stacklevel=3) + return f(x, out=out, **kwargs) + + return func + + +def _fix_out_named_y(f): + """ + Allow the out argument to be passed as the name `y` (deprecated) + + This decorator should only be used if _deprecate_out_named_y is used on + a corresponding dispatcher function. + """ + @functools.wraps(f) + def func(x, out=None, **kwargs): + if 'y' in kwargs: + # we already did error checking in _deprecate_out_named_y + out = kwargs.pop('y') + return f(x, out=out, **kwargs) + + return func + + +def _fix_and_maybe_deprecate_out_named_y(f): + """ + Use the appropriate decorator, depending upon if dispatching is being used. + """ + if ARRAY_FUNCTION_ENABLED: + return _fix_out_named_y(f) + else: + return _deprecate_out_named_y(f) + + +@_deprecate_out_named_y +def _dispatcher(x, out=None): + return (x, out) + + +@array_function_dispatch(_dispatcher, verify=False, module='numpy') +@_fix_and_maybe_deprecate_out_named_y +def fix(x, out=None): + """ + Round to nearest integer towards zero. + + Round an array of floats element-wise to nearest integer towards zero. + The rounded values are returned as floats. + + Parameters + ---------- + x : array_like + An array of floats to be rounded + out : ndarray, optional + A location into which the result is stored. If provided, it must have + a shape that the input broadcasts to. If not provided or None, a + freshly-allocated array is returned. + + Returns + ------- + out : ndarray of floats + A float array with the same dimensions as the input. + If second argument is not supplied then a float array is returned + with the rounded values. + + If a second argument is supplied the result is stored there. + The return value `out` is then a reference to that array. + + See Also + -------- + trunc, floor, ceil + around : Round to given number of decimals + + Examples + -------- + >>> np.fix(3.14) + 3.0 + >>> np.fix(3) + 3.0 + >>> np.fix([2.1, 2.9, -2.1, -2.9]) + array([ 2., 2., -2., -2.]) + + """ + # promote back to an array if flattened + res = nx.asanyarray(nx.ceil(x, out=out)) + res = nx.floor(x, out=res, where=nx.greater_equal(x, 0)) + + # when no out argument is passed and no subclasses are involved, flatten + # scalars + if out is None and type(res) is nx.ndarray: + res = res[()] + return res + + +@array_function_dispatch(_dispatcher, verify=False, module='numpy') +@_fix_and_maybe_deprecate_out_named_y +def isposinf(x, out=None): + """ + Test element-wise for positive infinity, return result as bool array. + + Parameters + ---------- + x : array_like + The input array. + out : array_like, optional + A location into which the result is stored. If provided, it must have a + shape that the input broadcasts to. If not provided or None, a + freshly-allocated boolean array is returned. + + Returns + ------- + out : ndarray + A boolean array with the same dimensions as the input. + If second argument is not supplied then a boolean array is returned + with values True where the corresponding element of the input is + positive infinity and values False where the element of the input is + not positive infinity. + + If a second argument is supplied the result is stored there. If the + type of that array is a numeric type the result is represented as zeros + and ones, if the type is boolean then as False and True. + The return value `out` is then a reference to that array. + + See Also + -------- + isinf, isneginf, isfinite, isnan + + Notes + ----- + NumPy uses the IEEE Standard for Binary Floating-Point for Arithmetic + (IEEE 754). + + Errors result if the second argument is also supplied when x is a scalar + input, if first and second arguments have different shapes, or if the + first argument has complex values + + Examples + -------- + >>> np.isposinf(np.PINF) + True + >>> np.isposinf(np.inf) + True + >>> np.isposinf(np.NINF) + False + >>> np.isposinf([-np.inf, 0., np.inf]) + array([False, False, True]) + + >>> x = np.array([-np.inf, 0., np.inf]) + >>> y = np.array([2, 2, 2]) + >>> np.isposinf(x, y) + array([0, 0, 1]) + >>> y + array([0, 0, 1]) + + """ + is_inf = nx.isinf(x) + try: + signbit = ~nx.signbit(x) + except TypeError as e: + raise TypeError('This operation is not supported for complex values ' + 'because it would be ambiguous.') from e + else: + return nx.logical_and(is_inf, signbit, out) + + +@array_function_dispatch(_dispatcher, verify=False, module='numpy') +@_fix_and_maybe_deprecate_out_named_y +def isneginf(x, out=None): + """ + Test element-wise for negative infinity, return result as bool array. + + Parameters + ---------- + x : array_like + The input array. + out : array_like, optional + A location into which the result is stored. If provided, it must have a + shape that the input broadcasts to. If not provided or None, a + freshly-allocated boolean array is returned. + + Returns + ------- + out : ndarray + A boolean array with the same dimensions as the input. + If second argument is not supplied then a numpy boolean array is + returned with values True where the corresponding element of the + input is negative infinity and values False where the element of + the input is not negative infinity. + + If a second argument is supplied the result is stored there. If the + type of that array is a numeric type the result is represented as + zeros and ones, if the type is boolean then as False and True. The + return value `out` is then a reference to that array. + + See Also + -------- + isinf, isposinf, isnan, isfinite + + Notes + ----- + NumPy uses the IEEE Standard for Binary Floating-Point for Arithmetic + (IEEE 754). + + Errors result if the second argument is also supplied when x is a scalar + input, if first and second arguments have different shapes, or if the + first argument has complex values. + + Examples + -------- + >>> np.isneginf(np.NINF) + True + >>> np.isneginf(np.inf) + False + >>> np.isneginf(np.PINF) + False + >>> np.isneginf([-np.inf, 0., np.inf]) + array([ True, False, False]) + + >>> x = np.array([-np.inf, 0., np.inf]) + >>> y = np.array([2, 2, 2]) + >>> np.isneginf(x, y) + array([1, 0, 0]) + >>> y + array([1, 0, 0]) + + """ + is_inf = nx.isinf(x) + try: + signbit = nx.signbit(x) + except TypeError as e: + raise TypeError('This operation is not supported for complex values ' + 'because it would be ambiguous.') from e + else: + return nx.logical_and(is_inf, signbit, out) diff --git a/venv/Lib/site-packages/numpy/lib/user_array.py b/venv/Lib/site-packages/numpy/lib/user_array.py new file mode 100644 index 0000000..0e96b47 --- /dev/null +++ b/venv/Lib/site-packages/numpy/lib/user_array.py @@ -0,0 +1,286 @@ +""" +Standard container-class for easy multiple-inheritance. + +Try to inherit from the ndarray instead of using this class as this is not +complete. + +""" +from numpy.core import ( + array, asarray, absolute, add, subtract, multiply, divide, + remainder, power, left_shift, right_shift, bitwise_and, bitwise_or, + bitwise_xor, invert, less, less_equal, not_equal, equal, greater, + greater_equal, shape, reshape, arange, sin, sqrt, transpose +) + + +class container: + """ + container(data, dtype=None, copy=True) + + Standard container-class for easy multiple-inheritance. + + Methods + ------- + copy + tostring + byteswap + astype + + """ + def __init__(self, data, dtype=None, copy=True): + self.array = array(data, dtype, copy=copy) + + def __repr__(self): + if self.ndim > 0: + return self.__class__.__name__ + repr(self.array)[len("array"):] + else: + return self.__class__.__name__ + "(" + repr(self.array) + ")" + + def __array__(self, t=None): + if t: + return self.array.astype(t) + return self.array + + # Array as sequence + def __len__(self): + return len(self.array) + + def __getitem__(self, index): + return self._rc(self.array[index]) + + def __setitem__(self, index, value): + self.array[index] = asarray(value, self.dtype) + + def __abs__(self): + return self._rc(absolute(self.array)) + + def __neg__(self): + return self._rc(-self.array) + + def __add__(self, other): + return self._rc(self.array + asarray(other)) + + __radd__ = __add__ + + def __iadd__(self, other): + add(self.array, other, self.array) + return self + + def __sub__(self, other): + return self._rc(self.array - asarray(other)) + + def __rsub__(self, other): + return self._rc(asarray(other) - self.array) + + def __isub__(self, other): + subtract(self.array, other, self.array) + return self + + def __mul__(self, other): + return self._rc(multiply(self.array, asarray(other))) + + __rmul__ = __mul__ + + def __imul__(self, other): + multiply(self.array, other, self.array) + return self + + def __div__(self, other): + return self._rc(divide(self.array, asarray(other))) + + def __rdiv__(self, other): + return self._rc(divide(asarray(other), self.array)) + + def __idiv__(self, other): + divide(self.array, other, self.array) + return self + + def __mod__(self, other): + return self._rc(remainder(self.array, other)) + + def __rmod__(self, other): + return self._rc(remainder(other, self.array)) + + def __imod__(self, other): + remainder(self.array, other, self.array) + return self + + def __divmod__(self, other): + return (self._rc(divide(self.array, other)), + self._rc(remainder(self.array, other))) + + def __rdivmod__(self, other): + return (self._rc(divide(other, self.array)), + self._rc(remainder(other, self.array))) + + def __pow__(self, other): + return self._rc(power(self.array, asarray(other))) + + def __rpow__(self, other): + return self._rc(power(asarray(other), self.array)) + + def __ipow__(self, other): + power(self.array, other, self.array) + return self + + def __lshift__(self, other): + return self._rc(left_shift(self.array, other)) + + def __rshift__(self, other): + return self._rc(right_shift(self.array, other)) + + def __rlshift__(self, other): + return self._rc(left_shift(other, self.array)) + + def __rrshift__(self, other): + return self._rc(right_shift(other, self.array)) + + def __ilshift__(self, other): + left_shift(self.array, other, self.array) + return self + + def __irshift__(self, other): + right_shift(self.array, other, self.array) + return self + + def __and__(self, other): + return self._rc(bitwise_and(self.array, other)) + + def __rand__(self, other): + return self._rc(bitwise_and(other, self.array)) + + def __iand__(self, other): + bitwise_and(self.array, other, self.array) + return self + + def __xor__(self, other): + return self._rc(bitwise_xor(self.array, other)) + + def __rxor__(self, other): + return self._rc(bitwise_xor(other, self.array)) + + def __ixor__(self, other): + bitwise_xor(self.array, other, self.array) + return self + + def __or__(self, other): + return self._rc(bitwise_or(self.array, other)) + + def __ror__(self, other): + return self._rc(bitwise_or(other, self.array)) + + def __ior__(self, other): + bitwise_or(self.array, other, self.array) + return self + + def __pos__(self): + return self._rc(self.array) + + def __invert__(self): + return self._rc(invert(self.array)) + + def _scalarfunc(self, func): + if self.ndim == 0: + return func(self[0]) + else: + raise TypeError( + "only rank-0 arrays can be converted to Python scalars.") + + def __complex__(self): + return self._scalarfunc(complex) + + def __float__(self): + return self._scalarfunc(float) + + def __int__(self): + return self._scalarfunc(int) + + def __hex__(self): + return self._scalarfunc(hex) + + def __oct__(self): + return self._scalarfunc(oct) + + def __lt__(self, other): + return self._rc(less(self.array, other)) + + def __le__(self, other): + return self._rc(less_equal(self.array, other)) + + def __eq__(self, other): + return self._rc(equal(self.array, other)) + + def __ne__(self, other): + return self._rc(not_equal(self.array, other)) + + def __gt__(self, other): + return self._rc(greater(self.array, other)) + + def __ge__(self, other): + return self._rc(greater_equal(self.array, other)) + + def copy(self): + "" + return self._rc(self.array.copy()) + + def tostring(self): + "" + return self.array.tostring() + + def tobytes(self): + "" + return self.array.tobytes() + + def byteswap(self): + "" + return self._rc(self.array.byteswap()) + + def astype(self, typecode): + "" + return self._rc(self.array.astype(typecode)) + + def _rc(self, a): + if len(shape(a)) == 0: + return a + else: + return self.__class__(a) + + def __array_wrap__(self, *args): + return self.__class__(args[0]) + + def __setattr__(self, attr, value): + if attr == 'array': + object.__setattr__(self, attr, value) + return + try: + self.array.__setattr__(attr, value) + except AttributeError: + object.__setattr__(self, attr, value) + + # Only called after other approaches fail. + def __getattr__(self, attr): + if (attr == 'array'): + return object.__getattribute__(self, attr) + return self.array.__getattribute__(attr) + +############################################################# +# Test of class container +############################################################# +if __name__ == '__main__': + temp = reshape(arange(10000), (100, 100)) + + ua = container(temp) + # new object created begin test + print(dir(ua)) + print(shape(ua), ua.shape) # I have changed Numeric.py + + ua_small = ua[:3, :5] + print(ua_small) + # this did not change ua[0,0], which is not normal behavior + ua_small[0, 0] = 10 + print(ua_small[0, 0], ua[0, 0]) + print(sin(ua_small) / 3. * 6. + sqrt(ua_small ** 2)) + print(less(ua_small, 103), type(less(ua_small, 103))) + print(type(ua_small * reshape(arange(15), shape(ua_small)))) + print(reshape(ua_small, (5, 3))) + print(transpose(ua_small)) diff --git a/venv/Lib/site-packages/numpy/lib/utils.py b/venv/Lib/site-packages/numpy/lib/utils.py new file mode 100644 index 0000000..5447608 --- /dev/null +++ b/venv/Lib/site-packages/numpy/lib/utils.py @@ -0,0 +1,1020 @@ +import os +import sys +import textwrap +import types +import re +import warnings + +from numpy.core.numerictypes import issubclass_, issubsctype, issubdtype +from numpy.core.overrides import set_module +from numpy.core import ndarray, ufunc, asarray +import numpy as np + +__all__ = [ + 'issubclass_', 'issubsctype', 'issubdtype', 'deprecate', + 'deprecate_with_doc', 'get_include', 'info', 'source', 'who', + 'lookfor', 'byte_bounds', 'safe_eval' + ] + +def get_include(): + """ + Return the directory that contains the NumPy \\*.h header files. + + Extension modules that need to compile against NumPy should use this + function to locate the appropriate include directory. + + Notes + ----- + When using ``distutils``, for example in ``setup.py``. + :: + + import numpy as np + ... + Extension('extension_name', ... + include_dirs=[np.get_include()]) + ... + + """ + import numpy + if numpy.show_config is None: + # running from numpy source directory + d = os.path.join(os.path.dirname(numpy.__file__), 'core', 'include') + else: + # using installed numpy core headers + import numpy.core as core + d = os.path.join(os.path.dirname(core.__file__), 'include') + return d + + +def _set_function_name(func, name): + func.__name__ = name + return func + + +class _Deprecate: + """ + Decorator class to deprecate old functions. + + Refer to `deprecate` for details. + + See Also + -------- + deprecate + + """ + + def __init__(self, old_name=None, new_name=None, message=None): + self.old_name = old_name + self.new_name = new_name + self.message = message + + def __call__(self, func, *args, **kwargs): + """ + Decorator call. Refer to ``decorate``. + + """ + old_name = self.old_name + new_name = self.new_name + message = self.message + + if old_name is None: + try: + old_name = func.__name__ + except AttributeError: + old_name = func.__name__ + if new_name is None: + depdoc = "`%s` is deprecated!" % old_name + else: + depdoc = "`%s` is deprecated, use `%s` instead!" % \ + (old_name, new_name) + + if message is not None: + depdoc += "\n" + message + + def newfunc(*args,**kwds): + """`arrayrange` is deprecated, use `arange` instead!""" + warnings.warn(depdoc, DeprecationWarning, stacklevel=2) + return func(*args, **kwds) + + newfunc = _set_function_name(newfunc, old_name) + doc = func.__doc__ + if doc is None: + doc = depdoc + else: + lines = doc.expandtabs().split('\n') + indent = _get_indent(lines[1:]) + if lines[0].lstrip(): + # Indent the original first line to let inspect.cleandoc() + # dedent the docstring despite the deprecation notice. + doc = indent * ' ' + doc + else: + # Remove the same leading blank lines as cleandoc() would. + skip = len(lines[0]) + 1 + for line in lines[1:]: + if len(line) > indent: + break + skip += len(line) + 1 + doc = doc[skip:] + depdoc = textwrap.indent(depdoc, ' ' * indent) + doc = '\n\n'.join([depdoc, doc]) + newfunc.__doc__ = doc + try: + d = func.__dict__ + except AttributeError: + pass + else: + newfunc.__dict__.update(d) + return newfunc + + +def _get_indent(lines): + """ + Determines the leading whitespace that could be removed from all the lines. + """ + indent = sys.maxsize + for line in lines: + content = len(line.lstrip()) + if content: + indent = min(indent, len(line) - content) + if indent == sys.maxsize: + indent = 0 + return indent + + +def deprecate(*args, **kwargs): + """ + Issues a DeprecationWarning, adds warning to `old_name`'s + docstring, rebinds ``old_name.__name__`` and returns the new + function object. + + This function may also be used as a decorator. + + Parameters + ---------- + func : function + The function to be deprecated. + old_name : str, optional + The name of the function to be deprecated. Default is None, in + which case the name of `func` is used. + new_name : str, optional + The new name for the function. Default is None, in which case the + deprecation message is that `old_name` is deprecated. If given, the + deprecation message is that `old_name` is deprecated and `new_name` + should be used instead. + message : str, optional + Additional explanation of the deprecation. Displayed in the + docstring after the warning. + + Returns + ------- + old_func : function + The deprecated function. + + Examples + -------- + Note that ``olduint`` returns a value after printing Deprecation + Warning: + + >>> olduint = np.deprecate(np.uint) + DeprecationWarning: `uint64` is deprecated! # may vary + >>> olduint(6) + 6 + + """ + # Deprecate may be run as a function or as a decorator + # If run as a function, we initialise the decorator class + # and execute its __call__ method. + + if args: + fn = args[0] + args = args[1:] + + return _Deprecate(*args, **kwargs)(fn) + else: + return _Deprecate(*args, **kwargs) + +deprecate_with_doc = lambda msg: _Deprecate(message=msg) + + +#-------------------------------------------- +# Determine if two arrays can share memory +#-------------------------------------------- + +def byte_bounds(a): + """ + Returns pointers to the end-points of an array. + + Parameters + ---------- + a : ndarray + Input array. It must conform to the Python-side of the array + interface. + + Returns + ------- + (low, high) : tuple of 2 integers + The first integer is the first byte of the array, the second + integer is just past the last byte of the array. If `a` is not + contiguous it will not use every byte between the (`low`, `high`) + values. + + Examples + -------- + >>> I = np.eye(2, dtype='f'); I.dtype + dtype('float32') + >>> low, high = np.byte_bounds(I) + >>> high - low == I.size*I.itemsize + True + >>> I = np.eye(2); I.dtype + dtype('float64') + >>> low, high = np.byte_bounds(I) + >>> high - low == I.size*I.itemsize + True + + """ + ai = a.__array_interface__ + a_data = ai['data'][0] + astrides = ai['strides'] + ashape = ai['shape'] + bytes_a = asarray(a).dtype.itemsize + + a_low = a_high = a_data + if astrides is None: + # contiguous case + a_high += a.size * bytes_a + else: + for shape, stride in zip(ashape, astrides): + if stride < 0: + a_low += (shape-1)*stride + else: + a_high += (shape-1)*stride + a_high += bytes_a + return a_low, a_high + + +#----------------------------------------------------------------------------- +# Function for output and information on the variables used. +#----------------------------------------------------------------------------- + + +def who(vardict=None): + """ + Print the NumPy arrays in the given dictionary. + + If there is no dictionary passed in or `vardict` is None then returns + NumPy arrays in the globals() dictionary (all NumPy arrays in the + namespace). + + Parameters + ---------- + vardict : dict, optional + A dictionary possibly containing ndarrays. Default is globals(). + + Returns + ------- + out : None + Returns 'None'. + + Notes + ----- + Prints out the name, shape, bytes and type of all of the ndarrays + present in `vardict`. + + Examples + -------- + >>> a = np.arange(10) + >>> b = np.ones(20) + >>> np.who() + Name Shape Bytes Type + =========================================================== + a 10 80 int64 + b 20 160 float64 + Upper bound on total bytes = 240 + + >>> d = {'x': np.arange(2.0), 'y': np.arange(3.0), 'txt': 'Some str', + ... 'idx':5} + >>> np.who(d) + Name Shape Bytes Type + =========================================================== + x 2 16 float64 + y 3 24 float64 + Upper bound on total bytes = 40 + + """ + if vardict is None: + frame = sys._getframe().f_back + vardict = frame.f_globals + sta = [] + cache = {} + for name in vardict.keys(): + if isinstance(vardict[name], ndarray): + var = vardict[name] + idv = id(var) + if idv in cache.keys(): + namestr = name + " (%s)" % cache[idv] + original = 0 + else: + cache[idv] = name + namestr = name + original = 1 + shapestr = " x ".join(map(str, var.shape)) + bytestr = str(var.nbytes) + sta.append([namestr, shapestr, bytestr, var.dtype.name, + original]) + + maxname = 0 + maxshape = 0 + maxbyte = 0 + totalbytes = 0 + for k in range(len(sta)): + val = sta[k] + if maxname < len(val[0]): + maxname = len(val[0]) + if maxshape < len(val[1]): + maxshape = len(val[1]) + if maxbyte < len(val[2]): + maxbyte = len(val[2]) + if val[4]: + totalbytes += int(val[2]) + + if len(sta) > 0: + sp1 = max(10, maxname) + sp2 = max(10, maxshape) + sp3 = max(10, maxbyte) + prval = "Name %s Shape %s Bytes %s Type" % (sp1*' ', sp2*' ', sp3*' ') + print(prval + "\n" + "="*(len(prval)+5) + "\n") + + for k in range(len(sta)): + val = sta[k] + print("%s %s %s %s %s %s %s" % (val[0], ' '*(sp1-len(val[0])+4), + val[1], ' '*(sp2-len(val[1])+5), + val[2], ' '*(sp3-len(val[2])+5), + val[3])) + print("\nUpper bound on total bytes = %d" % totalbytes) + return + +#----------------------------------------------------------------------------- + + +# NOTE: pydoc defines a help function which works similarly to this +# except it uses a pager to take over the screen. + +# combine name and arguments and split to multiple lines of width +# characters. End lines on a comma and begin argument list indented with +# the rest of the arguments. +def _split_line(name, arguments, width): + firstwidth = len(name) + k = firstwidth + newstr = name + sepstr = ", " + arglist = arguments.split(sepstr) + for argument in arglist: + if k == firstwidth: + addstr = "" + else: + addstr = sepstr + k = k + len(argument) + len(addstr) + if k > width: + k = firstwidth + 1 + len(argument) + newstr = newstr + ",\n" + " "*(firstwidth+2) + argument + else: + newstr = newstr + addstr + argument + return newstr + +_namedict = None +_dictlist = None + +# Traverse all module directories underneath globals +# to see if something is defined +def _makenamedict(module='numpy'): + module = __import__(module, globals(), locals(), []) + thedict = {module.__name__:module.__dict__} + dictlist = [module.__name__] + totraverse = [module.__dict__] + while True: + if len(totraverse) == 0: + break + thisdict = totraverse.pop(0) + for x in thisdict.keys(): + if isinstance(thisdict[x], types.ModuleType): + modname = thisdict[x].__name__ + if modname not in dictlist: + moddict = thisdict[x].__dict__ + dictlist.append(modname) + totraverse.append(moddict) + thedict[modname] = moddict + return thedict, dictlist + + +def _info(obj, output=sys.stdout): + """Provide information about ndarray obj. + + Parameters + ---------- + obj : ndarray + Must be ndarray, not checked. + output + Where printed output goes. + + Notes + ----- + Copied over from the numarray module prior to its removal. + Adapted somewhat as only numpy is an option now. + + Called by info. + + """ + extra = "" + tic = "" + bp = lambda x: x + cls = getattr(obj, '__class__', type(obj)) + nm = getattr(cls, '__name__', cls) + strides = obj.strides + endian = obj.dtype.byteorder + + print("class: ", nm, file=output) + print("shape: ", obj.shape, file=output) + print("strides: ", strides, file=output) + print("itemsize: ", obj.itemsize, file=output) + print("aligned: ", bp(obj.flags.aligned), file=output) + print("contiguous: ", bp(obj.flags.contiguous), file=output) + print("fortran: ", obj.flags.fortran, file=output) + print( + "data pointer: %s%s" % (hex(obj.ctypes._as_parameter_.value), extra), + file=output + ) + print("byteorder: ", end=' ', file=output) + if endian in ['|', '=']: + print("%s%s%s" % (tic, sys.byteorder, tic), file=output) + byteswap = False + elif endian == '>': + print("%sbig%s" % (tic, tic), file=output) + byteswap = sys.byteorder != "big" + else: + print("%slittle%s" % (tic, tic), file=output) + byteswap = sys.byteorder != "little" + print("byteswap: ", bp(byteswap), file=output) + print("type: %s" % obj.dtype, file=output) + + +@set_module('numpy') +def info(object=None, maxwidth=76, output=sys.stdout, toplevel='numpy'): + """ + Get help information for a function, class, or module. + + Parameters + ---------- + object : object or str, optional + Input object or name to get information about. If `object` is a + numpy object, its docstring is given. If it is a string, available + modules are searched for matching objects. If None, information + about `info` itself is returned. + maxwidth : int, optional + Printing width. + output : file like object, optional + File like object that the output is written to, default is + ``stdout``. The object has to be opened in 'w' or 'a' mode. + toplevel : str, optional + Start search at this level. + + See Also + -------- + source, lookfor + + Notes + ----- + When used interactively with an object, ``np.info(obj)`` is equivalent + to ``help(obj)`` on the Python prompt or ``obj?`` on the IPython + prompt. + + Examples + -------- + >>> np.info(np.polyval) # doctest: +SKIP + polyval(p, x) + Evaluate the polynomial p at x. + ... + + When using a string for `object` it is possible to get multiple results. + + >>> np.info('fft') # doctest: +SKIP + *** Found in numpy *** + Core FFT routines + ... + *** Found in numpy.fft *** + fft(a, n=None, axis=-1) + ... + *** Repeat reference found in numpy.fft.fftpack *** + *** Total of 3 references found. *** + + """ + global _namedict, _dictlist + # Local import to speed up numpy's import time. + import pydoc + import inspect + + if (hasattr(object, '_ppimport_importer') or + hasattr(object, '_ppimport_module')): + object = object._ppimport_module + elif hasattr(object, '_ppimport_attr'): + object = object._ppimport_attr + + if object is None: + info(info) + elif isinstance(object, ndarray): + _info(object, output=output) + elif isinstance(object, str): + if _namedict is None: + _namedict, _dictlist = _makenamedict(toplevel) + numfound = 0 + objlist = [] + for namestr in _dictlist: + try: + obj = _namedict[namestr][object] + if id(obj) in objlist: + print("\n " + "*** Repeat reference found in %s *** " % namestr, + file=output + ) + else: + objlist.append(id(obj)) + print(" *** Found in %s ***" % namestr, file=output) + info(obj) + print("-"*maxwidth, file=output) + numfound += 1 + except KeyError: + pass + if numfound == 0: + print("Help for %s not found." % object, file=output) + else: + print("\n " + "*** Total of %d references found. ***" % numfound, + file=output + ) + + elif inspect.isfunction(object) or inspect.ismethod(object): + name = object.__name__ + try: + arguments = str(inspect.signature(object)) + except Exception: + arguments = "()" + + if len(name+arguments) > maxwidth: + argstr = _split_line(name, arguments, maxwidth) + else: + argstr = name + arguments + + print(" " + argstr + "\n", file=output) + print(inspect.getdoc(object), file=output) + + elif inspect.isclass(object): + name = object.__name__ + try: + arguments = str(inspect.signature(object)) + except Exception: + arguments = "()" + + if len(name+arguments) > maxwidth: + argstr = _split_line(name, arguments, maxwidth) + else: + argstr = name + arguments + + print(" " + argstr + "\n", file=output) + doc1 = inspect.getdoc(object) + if doc1 is None: + if hasattr(object, '__init__'): + print(inspect.getdoc(object.__init__), file=output) + else: + print(inspect.getdoc(object), file=output) + + methods = pydoc.allmethods(object) + + public_methods = [meth for meth in methods if meth[0] != '_'] + if public_methods: + print("\n\nMethods:\n", file=output) + for meth in public_methods: + thisobj = getattr(object, meth, None) + if thisobj is not None: + methstr, other = pydoc.splitdoc( + inspect.getdoc(thisobj) or "None" + ) + print(" %s -- %s" % (meth, methstr), file=output) + + elif hasattr(object, '__doc__'): + print(inspect.getdoc(object), file=output) + + +@set_module('numpy') +def source(object, output=sys.stdout): + """ + Print or write to a file the source code for a NumPy object. + + The source code is only returned for objects written in Python. Many + functions and classes are defined in C and will therefore not return + useful information. + + Parameters + ---------- + object : numpy object + Input object. This can be any object (function, class, module, + ...). + output : file object, optional + If `output` not supplied then source code is printed to screen + (sys.stdout). File object must be created with either write 'w' or + append 'a' modes. + + See Also + -------- + lookfor, info + + Examples + -------- + >>> np.source(np.interp) #doctest: +SKIP + In file: /usr/lib/python2.6/dist-packages/numpy/lib/function_base.py + def interp(x, xp, fp, left=None, right=None): + \"\"\".... (full docstring printed)\"\"\" + if isinstance(x, (float, int, number)): + return compiled_interp([x], xp, fp, left, right).item() + else: + return compiled_interp(x, xp, fp, left, right) + + The source code is only returned for objects written in Python. + + >>> np.source(np.array) #doctest: +SKIP + Not available for this object. + + """ + # Local import to speed up numpy's import time. + import inspect + try: + print("In file: %s\n" % inspect.getsourcefile(object), file=output) + print(inspect.getsource(object), file=output) + except Exception: + print("Not available for this object.", file=output) + + +# Cache for lookfor: {id(module): {name: (docstring, kind, index), ...}...} +# where kind: "func", "class", "module", "object" +# and index: index in breadth-first namespace traversal +_lookfor_caches = {} + +# regexp whose match indicates that the string may contain a function +# signature +_function_signature_re = re.compile(r"[a-z0-9_]+\(.*[,=].*\)", re.I) + + +@set_module('numpy') +def lookfor(what, module=None, import_modules=True, regenerate=False, + output=None): + """ + Do a keyword search on docstrings. + + A list of objects that matched the search is displayed, + sorted by relevance. All given keywords need to be found in the + docstring for it to be returned as a result, but the order does + not matter. + + Parameters + ---------- + what : str + String containing words to look for. + module : str or list, optional + Name of module(s) whose docstrings to go through. + import_modules : bool, optional + Whether to import sub-modules in packages. Default is True. + regenerate : bool, optional + Whether to re-generate the docstring cache. Default is False. + output : file-like, optional + File-like object to write the output to. If omitted, use a pager. + + See Also + -------- + source, info + + Notes + ----- + Relevance is determined only roughly, by checking if the keywords occur + in the function name, at the start of a docstring, etc. + + Examples + -------- + >>> np.lookfor('binary representation') # doctest: +SKIP + Search results for 'binary representation' + ------------------------------------------ + numpy.binary_repr + Return the binary representation of the input number as a string. + numpy.core.setup_common.long_double_representation + Given a binary dump as given by GNU od -b, look for long double + numpy.base_repr + Return a string representation of a number in the given base system. + ... + + """ + import pydoc + + # Cache + cache = _lookfor_generate_cache(module, import_modules, regenerate) + + # Search + # XXX: maybe using a real stemming search engine would be better? + found = [] + whats = str(what).lower().split() + if not whats: + return + + for name, (docstring, kind, index) in cache.items(): + if kind in ('module', 'object'): + # don't show modules or objects + continue + doc = docstring.lower() + if all(w in doc for w in whats): + found.append(name) + + # Relevance sort + # XXX: this is full Harrison-Stetson heuristics now, + # XXX: it probably could be improved + + kind_relevance = {'func': 1000, 'class': 1000, + 'module': -1000, 'object': -1000} + + def relevance(name, docstr, kind, index): + r = 0 + # do the keywords occur within the start of the docstring? + first_doc = "\n".join(docstr.lower().strip().split("\n")[:3]) + r += sum([200 for w in whats if w in first_doc]) + # do the keywords occur in the function name? + r += sum([30 for w in whats if w in name]) + # is the full name long? + r += -len(name) * 5 + # is the object of bad type? + r += kind_relevance.get(kind, -1000) + # is the object deep in namespace hierarchy? + r += -name.count('.') * 10 + r += max(-index / 100, -100) + return r + + def relevance_value(a): + return relevance(a, *cache[a]) + found.sort(key=relevance_value) + + # Pretty-print + s = "Search results for '%s'" % (' '.join(whats)) + help_text = [s, "-"*len(s)] + for name in found[::-1]: + doc, kind, ix = cache[name] + + doclines = [line.strip() for line in doc.strip().split("\n") + if line.strip()] + + # find a suitable short description + try: + first_doc = doclines[0].strip() + if _function_signature_re.search(first_doc): + first_doc = doclines[1].strip() + except IndexError: + first_doc = "" + help_text.append("%s\n %s" % (name, first_doc)) + + if not found: + help_text.append("Nothing found.") + + # Output + if output is not None: + output.write("\n".join(help_text)) + elif len(help_text) > 10: + pager = pydoc.getpager() + pager("\n".join(help_text)) + else: + print("\n".join(help_text)) + +def _lookfor_generate_cache(module, import_modules, regenerate): + """ + Generate docstring cache for given module. + + Parameters + ---------- + module : str, None, module + Module for which to generate docstring cache + import_modules : bool + Whether to import sub-modules in packages. + regenerate : bool + Re-generate the docstring cache + + Returns + ------- + cache : dict {obj_full_name: (docstring, kind, index), ...} + Docstring cache for the module, either cached one (regenerate=False) + or newly generated. + + """ + # Local import to speed up numpy's import time. + import inspect + + from io import StringIO + + if module is None: + module = "numpy" + + if isinstance(module, str): + try: + __import__(module) + except ImportError: + return {} + module = sys.modules[module] + elif isinstance(module, list) or isinstance(module, tuple): + cache = {} + for mod in module: + cache.update(_lookfor_generate_cache(mod, import_modules, + regenerate)) + return cache + + if id(module) in _lookfor_caches and not regenerate: + return _lookfor_caches[id(module)] + + # walk items and collect docstrings + cache = {} + _lookfor_caches[id(module)] = cache + seen = {} + index = 0 + stack = [(module.__name__, module)] + while stack: + name, item = stack.pop(0) + if id(item) in seen: + continue + seen[id(item)] = True + + index += 1 + kind = "object" + + if inspect.ismodule(item): + kind = "module" + try: + _all = item.__all__ + except AttributeError: + _all = None + + # import sub-packages + if import_modules and hasattr(item, '__path__'): + for pth in item.__path__: + for mod_path in os.listdir(pth): + this_py = os.path.join(pth, mod_path) + init_py = os.path.join(pth, mod_path, '__init__.py') + if (os.path.isfile(this_py) and + mod_path.endswith('.py')): + to_import = mod_path[:-3] + elif os.path.isfile(init_py): + to_import = mod_path + else: + continue + if to_import == '__init__': + continue + + try: + old_stdout = sys.stdout + old_stderr = sys.stderr + try: + sys.stdout = StringIO() + sys.stderr = StringIO() + __import__("%s.%s" % (name, to_import)) + finally: + sys.stdout = old_stdout + sys.stderr = old_stderr + # Catch SystemExit, too + except BaseException: + continue + + for n, v in _getmembers(item): + try: + item_name = getattr(v, '__name__', "%s.%s" % (name, n)) + mod_name = getattr(v, '__module__', None) + except NameError: + # ref. SWIG's global cvars + # NameError: Unknown C global variable + item_name = "%s.%s" % (name, n) + mod_name = None + if '.' not in item_name and mod_name: + item_name = "%s.%s" % (mod_name, item_name) + + if not item_name.startswith(name + '.'): + # don't crawl "foreign" objects + if isinstance(v, ufunc): + # ... unless they are ufuncs + pass + else: + continue + elif not (inspect.ismodule(v) or _all is None or n in _all): + continue + stack.append(("%s.%s" % (name, n), v)) + elif inspect.isclass(item): + kind = "class" + for n, v in _getmembers(item): + stack.append(("%s.%s" % (name, n), v)) + elif hasattr(item, "__call__"): + kind = "func" + + try: + doc = inspect.getdoc(item) + except NameError: + # ref SWIG's NameError: Unknown C global variable + doc = None + if doc is not None: + cache[name] = (doc, kind, index) + + return cache + +def _getmembers(item): + import inspect + try: + members = inspect.getmembers(item) + except Exception: + members = [(x, getattr(item, x)) for x in dir(item) + if hasattr(item, x)] + return members + + +def safe_eval(source): + """ + Protected string evaluation. + + Evaluate a string containing a Python literal expression without + allowing the execution of arbitrary non-literal code. + + Parameters + ---------- + source : str + The string to evaluate. + + Returns + ------- + obj : object + The result of evaluating `source`. + + Raises + ------ + SyntaxError + If the code has invalid Python syntax, or if it contains + non-literal code. + + Examples + -------- + >>> np.safe_eval('1') + 1 + >>> np.safe_eval('[1, 2, 3]') + [1, 2, 3] + >>> np.safe_eval('{"foo": ("bar", 10.0)}') + {'foo': ('bar', 10.0)} + + >>> np.safe_eval('import os') + Traceback (most recent call last): + ... + SyntaxError: invalid syntax + + >>> np.safe_eval('open("/home/user/.ssh/id_dsa").read()') + Traceback (most recent call last): + ... + ValueError: malformed node or string: <_ast.Call object at 0x...> + + """ + # Local import to speed up numpy's import time. + import ast + return ast.literal_eval(source) + + +def _median_nancheck(data, result, axis, out): + """ + Utility function to check median result from data for NaN values at the end + and return NaN in that case. Input result can also be a MaskedArray. + + Parameters + ---------- + data : array + Input data to median function + result : Array or MaskedArray + Result of median function + axis : {int, sequence of int, None}, optional + Axis or axes along which the median was computed. + out : ndarray, optional + Output array in which to place the result. + Returns + ------- + median : scalar or ndarray + Median or NaN in axes which contained NaN in the input. + """ + if data.size == 0: + return result + data = np.moveaxis(data, axis, -1) + n = np.isnan(data[..., -1]) + # masked NaN values are ok + if np.ma.isMaskedArray(n): + n = n.filled(False) + if result.ndim == 0: + if n == True: + if out is not None: + out[...] = data.dtype.type(np.nan) + result = out + else: + result = data.dtype.type(np.nan) + elif np.count_nonzero(n.ravel()) > 0: + result[n] = np.nan + return result + +#----------------------------------------------------------------------------- diff --git a/venv/Lib/site-packages/numpy/linalg/__init__.py b/venv/Lib/site-packages/numpy/linalg/__init__.py new file mode 100644 index 0000000..3a53ac6 --- /dev/null +++ b/venv/Lib/site-packages/numpy/linalg/__init__.py @@ -0,0 +1,77 @@ +""" +``numpy.linalg`` +================ + +The NumPy linear algebra functions rely on BLAS and LAPACK to provide efficient +low level implementations of standard linear algebra algorithms. Those +libraries may be provided by NumPy itself using C versions of a subset of their +reference implementations but, when possible, highly optimized libraries that +take advantage of specialized processor functionality are preferred. Examples +of such libraries are OpenBLAS, MKL (TM), and ATLAS. Because those libraries +are multithreaded and processor dependent, environmental variables and external +packages such as threadpoolctl may be needed to control the number of threads +or specify the processor architecture. + +- OpenBLAS: https://www.openblas.net/ +- threadpoolctl: https://github.com/joblib/threadpoolctl + +Please note that the most-used linear algebra functions in NumPy are present in +the main ``numpy`` namespace rather than in ``numpy.linalg``. There are: +``dot``, ``vdot``, ``inner``, ``outer``, ``matmul``, ``tensordot``, ``einsum``, +``einsum_path`` and ``kron``. + +Functions present in numpy.linalg are listed below. + + +Matrix and vector products +-------------------------- + + multi_dot + matrix_power + +Decompositions +-------------- + + cholesky + qr + svd + +Matrix eigenvalues +------------------ + + eig + eigh + eigvals + eigvalsh + +Norms and other numbers +----------------------- + + norm + cond + det + matrix_rank + slogdet + +Solving equations and inverting matrices +---------------------------------------- + + solve + tensorsolve + lstsq + inv + pinv + tensorinv + +Exceptions +---------- + + LinAlgError + +""" +# To get sub-modules +from .linalg import * + +from numpy._pytesttester import PytestTester +test = PytestTester(__name__) +del PytestTester diff --git a/venv/Lib/site-packages/numpy/linalg/__init__.pyi b/venv/Lib/site-packages/numpy/linalg/__init__.pyi new file mode 100644 index 0000000..ffb05bb --- /dev/null +++ b/venv/Lib/site-packages/numpy/linalg/__init__.pyi @@ -0,0 +1,23 @@ +from typing import Any + +matrix_power: Any +solve: Any +tensorsolve: Any +tensorinv: Any +inv: Any +cholesky: Any +eigvals: Any +eigvalsh: Any +pinv: Any +slogdet: Any +det: Any +svd: Any +eig: Any +eigh: Any +lstsq: Any +norm: Any +qr: Any +cond: Any +matrix_rank: Any +LinAlgError: Any +multi_dot: Any diff --git a/venv/Lib/site-packages/numpy/linalg/linalg.py b/venv/Lib/site-packages/numpy/linalg/linalg.py new file mode 100644 index 0000000..7775e4c --- /dev/null +++ b/venv/Lib/site-packages/numpy/linalg/linalg.py @@ -0,0 +1,2813 @@ +"""Lite version of scipy.linalg. + +Notes +----- +This module is a lite version of the linalg.py module in SciPy which +contains high-level Python interface to the LAPACK library. The lite +version only accesses the following LAPACK functions: dgesv, zgesv, +dgeev, zgeev, dgesdd, zgesdd, dgelsd, zgelsd, dsyevd, zheevd, dgetrf, +zgetrf, dpotrf, zpotrf, dgeqrf, zgeqrf, zungqr, dorgqr. +""" + +__all__ = ['matrix_power', 'solve', 'tensorsolve', 'tensorinv', 'inv', + 'cholesky', 'eigvals', 'eigvalsh', 'pinv', 'slogdet', 'det', + 'svd', 'eig', 'eigh', 'lstsq', 'norm', 'qr', 'cond', 'matrix_rank', + 'LinAlgError', 'multi_dot'] + +import functools +import operator +import warnings + +from numpy.core import ( + array, asarray, zeros, empty, empty_like, intc, single, double, + csingle, cdouble, inexact, complexfloating, newaxis, all, Inf, dot, + add, multiply, sqrt, fastCopyAndTranspose, sum, isfinite, + finfo, errstate, geterrobj, moveaxis, amin, amax, product, abs, + atleast_2d, intp, asanyarray, object_, matmul, + swapaxes, divide, count_nonzero, isnan, sign, argsort, sort +) +from numpy.core.multiarray import normalize_axis_index +from numpy.core.overrides import set_module +from numpy.core import overrides +from numpy.lib.twodim_base import triu, eye +from numpy.linalg import lapack_lite, _umath_linalg + + +array_function_dispatch = functools.partial( + overrides.array_function_dispatch, module='numpy.linalg') + + +fortran_int = intc + + +@set_module('numpy.linalg') +class LinAlgError(Exception): + """ + Generic Python-exception-derived object raised by linalg functions. + + General purpose exception class, derived from Python's exception.Exception + class, programmatically raised in linalg functions when a Linear + Algebra-related condition would prevent further correct execution of the + function. + + Parameters + ---------- + None + + Examples + -------- + >>> from numpy import linalg as LA + >>> LA.inv(np.zeros((2,2))) + Traceback (most recent call last): + File "", line 1, in + File "...linalg.py", line 350, + in inv return wrap(solve(a, identity(a.shape[0], dtype=a.dtype))) + File "...linalg.py", line 249, + in solve + raise LinAlgError('Singular matrix') + numpy.linalg.LinAlgError: Singular matrix + + """ + + +def _determine_error_states(): + errobj = geterrobj() + bufsize = errobj[0] + + with errstate(invalid='call', over='ignore', + divide='ignore', under='ignore'): + invalid_call_errmask = geterrobj()[1] + + return [bufsize, invalid_call_errmask, None] + +# Dealing with errors in _umath_linalg +_linalg_error_extobj = _determine_error_states() +del _determine_error_states + +def _raise_linalgerror_singular(err, flag): + raise LinAlgError("Singular matrix") + +def _raise_linalgerror_nonposdef(err, flag): + raise LinAlgError("Matrix is not positive definite") + +def _raise_linalgerror_eigenvalues_nonconvergence(err, flag): + raise LinAlgError("Eigenvalues did not converge") + +def _raise_linalgerror_svd_nonconvergence(err, flag): + raise LinAlgError("SVD did not converge") + +def _raise_linalgerror_lstsq(err, flag): + raise LinAlgError("SVD did not converge in Linear Least Squares") + +def get_linalg_error_extobj(callback): + extobj = list(_linalg_error_extobj) # make a copy + extobj[2] = callback + return extobj + +def _makearray(a): + new = asarray(a) + wrap = getattr(a, "__array_prepare__", new.__array_wrap__) + return new, wrap + +def isComplexType(t): + return issubclass(t, complexfloating) + +_real_types_map = {single : single, + double : double, + csingle : single, + cdouble : double} + +_complex_types_map = {single : csingle, + double : cdouble, + csingle : csingle, + cdouble : cdouble} + +def _realType(t, default=double): + return _real_types_map.get(t, default) + +def _complexType(t, default=cdouble): + return _complex_types_map.get(t, default) + +def _linalgRealType(t): + """Cast the type t to either double or cdouble.""" + return double + +def _commonType(*arrays): + # in lite version, use higher precision (always double or cdouble) + result_type = single + is_complex = False + for a in arrays: + if issubclass(a.dtype.type, inexact): + if isComplexType(a.dtype.type): + is_complex = True + rt = _realType(a.dtype.type, default=None) + if rt is None: + # unsupported inexact scalar + raise TypeError("array type %s is unsupported in linalg" % + (a.dtype.name,)) + else: + rt = double + if rt is double: + result_type = double + if is_complex: + t = cdouble + result_type = _complex_types_map[result_type] + else: + t = double + return t, result_type + + +# _fastCopyAndTranpose assumes the input is 2D (as all the calls in here are). + +_fastCT = fastCopyAndTranspose + +def _to_native_byte_order(*arrays): + ret = [] + for arr in arrays: + if arr.dtype.byteorder not in ('=', '|'): + ret.append(asarray(arr, dtype=arr.dtype.newbyteorder('='))) + else: + ret.append(arr) + if len(ret) == 1: + return ret[0] + else: + return ret + +def _fastCopyAndTranspose(type, *arrays): + cast_arrays = () + for a in arrays: + if a.dtype.type is not type: + a = a.astype(type) + cast_arrays = cast_arrays + (_fastCT(a),) + if len(cast_arrays) == 1: + return cast_arrays[0] + else: + return cast_arrays + +def _assert_2d(*arrays): + for a in arrays: + if a.ndim != 2: + raise LinAlgError('%d-dimensional array given. Array must be ' + 'two-dimensional' % a.ndim) + +def _assert_stacked_2d(*arrays): + for a in arrays: + if a.ndim < 2: + raise LinAlgError('%d-dimensional array given. Array must be ' + 'at least two-dimensional' % a.ndim) + +def _assert_stacked_square(*arrays): + for a in arrays: + m, n = a.shape[-2:] + if m != n: + raise LinAlgError('Last 2 dimensions of the array must be square') + +def _assert_finite(*arrays): + for a in arrays: + if not isfinite(a).all(): + raise LinAlgError("Array must not contain infs or NaNs") + +def _is_empty_2d(arr): + # check size first for efficiency + return arr.size == 0 and product(arr.shape[-2:]) == 0 + + +def transpose(a): + """ + Transpose each matrix in a stack of matrices. + + Unlike np.transpose, this only swaps the last two axes, rather than all of + them + + Parameters + ---------- + a : (...,M,N) array_like + + Returns + ------- + aT : (...,N,M) ndarray + """ + return swapaxes(a, -1, -2) + +# Linear equations + +def _tensorsolve_dispatcher(a, b, axes=None): + return (a, b) + + +@array_function_dispatch(_tensorsolve_dispatcher) +def tensorsolve(a, b, axes=None): + """ + Solve the tensor equation ``a x = b`` for x. + + It is assumed that all indices of `x` are summed over in the product, + together with the rightmost indices of `a`, as is done in, for example, + ``tensordot(a, x, axes=b.ndim)``. + + Parameters + ---------- + a : array_like + Coefficient tensor, of shape ``b.shape + Q``. `Q`, a tuple, equals + the shape of that sub-tensor of `a` consisting of the appropriate + number of its rightmost indices, and must be such that + ``prod(Q) == prod(b.shape)`` (in which sense `a` is said to be + 'square'). + b : array_like + Right-hand tensor, which can be of any shape. + axes : tuple of ints, optional + Axes in `a` to reorder to the right, before inversion. + If None (default), no reordering is done. + + Returns + ------- + x : ndarray, shape Q + + Raises + ------ + LinAlgError + If `a` is singular or not 'square' (in the above sense). + + See Also + -------- + numpy.tensordot, tensorinv, numpy.einsum + + Examples + -------- + >>> a = np.eye(2*3*4) + >>> a.shape = (2*3, 4, 2, 3, 4) + >>> b = np.random.randn(2*3, 4) + >>> x = np.linalg.tensorsolve(a, b) + >>> x.shape + (2, 3, 4) + >>> np.allclose(np.tensordot(a, x, axes=3), b) + True + + """ + a, wrap = _makearray(a) + b = asarray(b) + an = a.ndim + + if axes is not None: + allaxes = list(range(0, an)) + for k in axes: + allaxes.remove(k) + allaxes.insert(an, k) + a = a.transpose(allaxes) + + oldshape = a.shape[-(an-b.ndim):] + prod = 1 + for k in oldshape: + prod *= k + + a = a.reshape(-1, prod) + b = b.ravel() + res = wrap(solve(a, b)) + res.shape = oldshape + return res + + +def _solve_dispatcher(a, b): + return (a, b) + + +@array_function_dispatch(_solve_dispatcher) +def solve(a, b): + """ + Solve a linear matrix equation, or system of linear scalar equations. + + Computes the "exact" solution, `x`, of the well-determined, i.e., full + rank, linear matrix equation `ax = b`. + + Parameters + ---------- + a : (..., M, M) array_like + Coefficient matrix. + b : {(..., M,), (..., M, K)}, array_like + Ordinate or "dependent variable" values. + + Returns + ------- + x : {(..., M,), (..., M, K)} ndarray + Solution to the system a x = b. Returned shape is identical to `b`. + + Raises + ------ + LinAlgError + If `a` is singular or not square. + + See Also + -------- + scipy.linalg.solve : Similar function in SciPy. + + Notes + ----- + + .. versionadded:: 1.8.0 + + Broadcasting rules apply, see the `numpy.linalg` documentation for + details. + + The solutions are computed using LAPACK routine ``_gesv``. + + `a` must be square and of full-rank, i.e., all rows (or, equivalently, + columns) must be linearly independent; if either is not true, use + `lstsq` for the least-squares best "solution" of the + system/equation. + + References + ---------- + .. [1] G. Strang, *Linear Algebra and Its Applications*, 2nd Ed., Orlando, + FL, Academic Press, Inc., 1980, pg. 22. + + Examples + -------- + Solve the system of equations ``x0 + 2 * x1 = 1`` and ``3 * x0 + 5 * x1 = 2``: + + >>> a = np.array([[1, 2], [3, 5]]) + >>> b = np.array([1, 2]) + >>> x = np.linalg.solve(a, b) + >>> x + array([-1., 1.]) + + Check that the solution is correct: + + >>> np.allclose(np.dot(a, x), b) + True + + """ + a, _ = _makearray(a) + _assert_stacked_2d(a) + _assert_stacked_square(a) + b, wrap = _makearray(b) + t, result_t = _commonType(a, b) + + # We use the b = (..., M,) logic, only if the number of extra dimensions + # match exactly + if b.ndim == a.ndim - 1: + gufunc = _umath_linalg.solve1 + else: + gufunc = _umath_linalg.solve + + signature = 'DD->D' if isComplexType(t) else 'dd->d' + extobj = get_linalg_error_extobj(_raise_linalgerror_singular) + r = gufunc(a, b, signature=signature, extobj=extobj) + + return wrap(r.astype(result_t, copy=False)) + + +def _tensorinv_dispatcher(a, ind=None): + return (a,) + + +@array_function_dispatch(_tensorinv_dispatcher) +def tensorinv(a, ind=2): + """ + Compute the 'inverse' of an N-dimensional array. + + The result is an inverse for `a` relative to the tensordot operation + ``tensordot(a, b, ind)``, i. e., up to floating-point accuracy, + ``tensordot(tensorinv(a), a, ind)`` is the "identity" tensor for the + tensordot operation. + + Parameters + ---------- + a : array_like + Tensor to 'invert'. Its shape must be 'square', i. e., + ``prod(a.shape[:ind]) == prod(a.shape[ind:])``. + ind : int, optional + Number of first indices that are involved in the inverse sum. + Must be a positive integer, default is 2. + + Returns + ------- + b : ndarray + `a`'s tensordot inverse, shape ``a.shape[ind:] + a.shape[:ind]``. + + Raises + ------ + LinAlgError + If `a` is singular or not 'square' (in the above sense). + + See Also + -------- + numpy.tensordot, tensorsolve + + Examples + -------- + >>> a = np.eye(4*6) + >>> a.shape = (4, 6, 8, 3) + >>> ainv = np.linalg.tensorinv(a, ind=2) + >>> ainv.shape + (8, 3, 4, 6) + >>> b = np.random.randn(4, 6) + >>> np.allclose(np.tensordot(ainv, b), np.linalg.tensorsolve(a, b)) + True + + >>> a = np.eye(4*6) + >>> a.shape = (24, 8, 3) + >>> ainv = np.linalg.tensorinv(a, ind=1) + >>> ainv.shape + (8, 3, 24) + >>> b = np.random.randn(24) + >>> np.allclose(np.tensordot(ainv, b, 1), np.linalg.tensorsolve(a, b)) + True + + """ + a = asarray(a) + oldshape = a.shape + prod = 1 + if ind > 0: + invshape = oldshape[ind:] + oldshape[:ind] + for k in oldshape[ind:]: + prod *= k + else: + raise ValueError("Invalid ind argument.") + a = a.reshape(prod, -1) + ia = inv(a) + return ia.reshape(*invshape) + + +# Matrix inversion + +def _unary_dispatcher(a): + return (a,) + + +@array_function_dispatch(_unary_dispatcher) +def inv(a): + """ + Compute the (multiplicative) inverse of a matrix. + + Given a square matrix `a`, return the matrix `ainv` satisfying + ``dot(a, ainv) = dot(ainv, a) = eye(a.shape[0])``. + + Parameters + ---------- + a : (..., M, M) array_like + Matrix to be inverted. + + Returns + ------- + ainv : (..., M, M) ndarray or matrix + (Multiplicative) inverse of the matrix `a`. + + Raises + ------ + LinAlgError + If `a` is not square or inversion fails. + + See Also + -------- + scipy.linalg.inv : Similar function in SciPy. + + Notes + ----- + + .. versionadded:: 1.8.0 + + Broadcasting rules apply, see the `numpy.linalg` documentation for + details. + + Examples + -------- + >>> from numpy.linalg import inv + >>> a = np.array([[1., 2.], [3., 4.]]) + >>> ainv = inv(a) + >>> np.allclose(np.dot(a, ainv), np.eye(2)) + True + >>> np.allclose(np.dot(ainv, a), np.eye(2)) + True + + If a is a matrix object, then the return value is a matrix as well: + + >>> ainv = inv(np.matrix(a)) + >>> ainv + matrix([[-2. , 1. ], + [ 1.5, -0.5]]) + + Inverses of several matrices can be computed at once: + + >>> a = np.array([[[1., 2.], [3., 4.]], [[1, 3], [3, 5]]]) + >>> inv(a) + array([[[-2. , 1. ], + [ 1.5 , -0.5 ]], + [[-1.25, 0.75], + [ 0.75, -0.25]]]) + + """ + a, wrap = _makearray(a) + _assert_stacked_2d(a) + _assert_stacked_square(a) + t, result_t = _commonType(a) + + signature = 'D->D' if isComplexType(t) else 'd->d' + extobj = get_linalg_error_extobj(_raise_linalgerror_singular) + ainv = _umath_linalg.inv(a, signature=signature, extobj=extobj) + return wrap(ainv.astype(result_t, copy=False)) + + +def _matrix_power_dispatcher(a, n): + return (a,) + + +@array_function_dispatch(_matrix_power_dispatcher) +def matrix_power(a, n): + """ + Raise a square matrix to the (integer) power `n`. + + For positive integers `n`, the power is computed by repeated matrix + squarings and matrix multiplications. If ``n == 0``, the identity matrix + of the same shape as M is returned. If ``n < 0``, the inverse + is computed and then raised to the ``abs(n)``. + + .. note:: Stacks of object matrices are not currently supported. + + Parameters + ---------- + a : (..., M, M) array_like + Matrix to be "powered". + n : int + The exponent can be any integer or long integer, positive, + negative, or zero. + + Returns + ------- + a**n : (..., M, M) ndarray or matrix object + The return value is the same shape and type as `M`; + if the exponent is positive or zero then the type of the + elements is the same as those of `M`. If the exponent is + negative the elements are floating-point. + + Raises + ------ + LinAlgError + For matrices that are not square or that (for negative powers) cannot + be inverted numerically. + + Examples + -------- + >>> from numpy.linalg import matrix_power + >>> i = np.array([[0, 1], [-1, 0]]) # matrix equiv. of the imaginary unit + >>> matrix_power(i, 3) # should = -i + array([[ 0, -1], + [ 1, 0]]) + >>> matrix_power(i, 0) + array([[1, 0], + [0, 1]]) + >>> matrix_power(i, -3) # should = 1/(-i) = i, but w/ f.p. elements + array([[ 0., 1.], + [-1., 0.]]) + + Somewhat more sophisticated example + + >>> q = np.zeros((4, 4)) + >>> q[0:2, 0:2] = -i + >>> q[2:4, 2:4] = i + >>> q # one of the three quaternion units not equal to 1 + array([[ 0., -1., 0., 0.], + [ 1., 0., 0., 0.], + [ 0., 0., 0., 1.], + [ 0., 0., -1., 0.]]) + >>> matrix_power(q, 2) # = -np.eye(4) + array([[-1., 0., 0., 0.], + [ 0., -1., 0., 0.], + [ 0., 0., -1., 0.], + [ 0., 0., 0., -1.]]) + + """ + a = asanyarray(a) + _assert_stacked_2d(a) + _assert_stacked_square(a) + + try: + n = operator.index(n) + except TypeError as e: + raise TypeError("exponent must be an integer") from e + + # Fall back on dot for object arrays. Object arrays are not supported by + # the current implementation of matmul using einsum + if a.dtype != object: + fmatmul = matmul + elif a.ndim == 2: + fmatmul = dot + else: + raise NotImplementedError( + "matrix_power not supported for stacks of object arrays") + + if n == 0: + a = empty_like(a) + a[...] = eye(a.shape[-2], dtype=a.dtype) + return a + + elif n < 0: + a = inv(a) + n = abs(n) + + # short-cuts. + if n == 1: + return a + + elif n == 2: + return fmatmul(a, a) + + elif n == 3: + return fmatmul(fmatmul(a, a), a) + + # Use binary decomposition to reduce the number of matrix multiplications. + # Here, we iterate over the bits of n, from LSB to MSB, raise `a` to + # increasing powers of 2, and multiply into the result as needed. + z = result = None + while n > 0: + z = a if z is None else fmatmul(z, z) + n, bit = divmod(n, 2) + if bit: + result = z if result is None else fmatmul(result, z) + + return result + + +# Cholesky decomposition + + +@array_function_dispatch(_unary_dispatcher) +def cholesky(a): + """ + Cholesky decomposition. + + Return the Cholesky decomposition, `L * L.H`, of the square matrix `a`, + where `L` is lower-triangular and .H is the conjugate transpose operator + (which is the ordinary transpose if `a` is real-valued). `a` must be + Hermitian (symmetric if real-valued) and positive-definite. No + checking is performed to verify whether `a` is Hermitian or not. + In addition, only the lower-triangular and diagonal elements of `a` + are used. Only `L` is actually returned. + + Parameters + ---------- + a : (..., M, M) array_like + Hermitian (symmetric if all elements are real), positive-definite + input matrix. + + Returns + ------- + L : (..., M, M) array_like + Upper or lower-triangular Cholesky factor of `a`. Returns a + matrix object if `a` is a matrix object. + + Raises + ------ + LinAlgError + If the decomposition fails, for example, if `a` is not + positive-definite. + + See Also + -------- + scipy.linalg.cholesky : Similar function in SciPy. + scipy.linalg.cholesky_banded : Cholesky decompose a banded Hermitian + positive-definite matrix. + scipy.linalg.cho_factor : Cholesky decomposition of a matrix, to use in + `scipy.linalg.cho_solve`. + + Notes + ----- + + .. versionadded:: 1.8.0 + + Broadcasting rules apply, see the `numpy.linalg` documentation for + details. + + The Cholesky decomposition is often used as a fast way of solving + + .. math:: A \\mathbf{x} = \\mathbf{b} + + (when `A` is both Hermitian/symmetric and positive-definite). + + First, we solve for :math:`\\mathbf{y}` in + + .. math:: L \\mathbf{y} = \\mathbf{b}, + + and then for :math:`\\mathbf{x}` in + + .. math:: L.H \\mathbf{x} = \\mathbf{y}. + + Examples + -------- + >>> A = np.array([[1,-2j],[2j,5]]) + >>> A + array([[ 1.+0.j, -0.-2.j], + [ 0.+2.j, 5.+0.j]]) + >>> L = np.linalg.cholesky(A) + >>> L + array([[1.+0.j, 0.+0.j], + [0.+2.j, 1.+0.j]]) + >>> np.dot(L, L.T.conj()) # verify that L * L.H = A + array([[1.+0.j, 0.-2.j], + [0.+2.j, 5.+0.j]]) + >>> A = [[1,-2j],[2j,5]] # what happens if A is only array_like? + >>> np.linalg.cholesky(A) # an ndarray object is returned + array([[1.+0.j, 0.+0.j], + [0.+2.j, 1.+0.j]]) + >>> # But a matrix object is returned if A is a matrix object + >>> np.linalg.cholesky(np.matrix(A)) + matrix([[ 1.+0.j, 0.+0.j], + [ 0.+2.j, 1.+0.j]]) + + """ + extobj = get_linalg_error_extobj(_raise_linalgerror_nonposdef) + gufunc = _umath_linalg.cholesky_lo + a, wrap = _makearray(a) + _assert_stacked_2d(a) + _assert_stacked_square(a) + t, result_t = _commonType(a) + signature = 'D->D' if isComplexType(t) else 'd->d' + r = gufunc(a, signature=signature, extobj=extobj) + return wrap(r.astype(result_t, copy=False)) + + +# QR decomposition + +def _qr_dispatcher(a, mode=None): + return (a,) + + +@array_function_dispatch(_qr_dispatcher) +def qr(a, mode='reduced'): + """ + Compute the qr factorization of a matrix. + + Factor the matrix `a` as *qr*, where `q` is orthonormal and `r` is + upper-triangular. + + Parameters + ---------- + a : array_like, shape (M, N) + Matrix to be factored. + mode : {'reduced', 'complete', 'r', 'raw'}, optional + If K = min(M, N), then + + * 'reduced' : returns q, r with dimensions (M, K), (K, N) (default) + * 'complete' : returns q, r with dimensions (M, M), (M, N) + * 'r' : returns r only with dimensions (K, N) + * 'raw' : returns h, tau with dimensions (N, M), (K,) + + The options 'reduced', 'complete, and 'raw' are new in numpy 1.8, + see the notes for more information. The default is 'reduced', and to + maintain backward compatibility with earlier versions of numpy both + it and the old default 'full' can be omitted. Note that array h + returned in 'raw' mode is transposed for calling Fortran. The + 'economic' mode is deprecated. The modes 'full' and 'economic' may + be passed using only the first letter for backwards compatibility, + but all others must be spelled out. See the Notes for more + explanation. + + + Returns + ------- + q : ndarray of float or complex, optional + A matrix with orthonormal columns. When mode = 'complete' the + result is an orthogonal/unitary matrix depending on whether or not + a is real/complex. The determinant may be either +/- 1 in that + case. + r : ndarray of float or complex, optional + The upper-triangular matrix. + (h, tau) : ndarrays of np.double or np.cdouble, optional + The array h contains the Householder reflectors that generate q + along with r. The tau array contains scaling factors for the + reflectors. In the deprecated 'economic' mode only h is returned. + + Raises + ------ + LinAlgError + If factoring fails. + + See Also + -------- + scipy.linalg.qr : Similar function in SciPy. + scipy.linalg.rq : Compute RQ decomposition of a matrix. + + Notes + ----- + This is an interface to the LAPACK routines ``dgeqrf``, ``zgeqrf``, + ``dorgqr``, and ``zungqr``. + + For more information on the qr factorization, see for example: + https://en.wikipedia.org/wiki/QR_factorization + + Subclasses of `ndarray` are preserved except for the 'raw' mode. So if + `a` is of type `matrix`, all the return values will be matrices too. + + New 'reduced', 'complete', and 'raw' options for mode were added in + NumPy 1.8.0 and the old option 'full' was made an alias of 'reduced'. In + addition the options 'full' and 'economic' were deprecated. Because + 'full' was the previous default and 'reduced' is the new default, + backward compatibility can be maintained by letting `mode` default. + The 'raw' option was added so that LAPACK routines that can multiply + arrays by q using the Householder reflectors can be used. Note that in + this case the returned arrays are of type np.double or np.cdouble and + the h array is transposed to be FORTRAN compatible. No routines using + the 'raw' return are currently exposed by numpy, but some are available + in lapack_lite and just await the necessary work. + + Examples + -------- + >>> a = np.random.randn(9, 6) + >>> q, r = np.linalg.qr(a) + >>> np.allclose(a, np.dot(q, r)) # a does equal qr + True + >>> r2 = np.linalg.qr(a, mode='r') + >>> np.allclose(r, r2) # mode='r' returns the same r as mode='full' + True + + Example illustrating a common use of `qr`: solving of least squares + problems + + What are the least-squares-best `m` and `y0` in ``y = y0 + mx`` for + the following data: {(0,1), (1,0), (1,2), (2,1)}. (Graph the points + and you'll see that it should be y0 = 0, m = 1.) The answer is provided + by solving the over-determined matrix equation ``Ax = b``, where:: + + A = array([[0, 1], [1, 1], [1, 1], [2, 1]]) + x = array([[y0], [m]]) + b = array([[1], [0], [2], [1]]) + + If A = qr such that q is orthonormal (which is always possible via + Gram-Schmidt), then ``x = inv(r) * (q.T) * b``. (In numpy practice, + however, we simply use `lstsq`.) + + >>> A = np.array([[0, 1], [1, 1], [1, 1], [2, 1]]) + >>> A + array([[0, 1], + [1, 1], + [1, 1], + [2, 1]]) + >>> b = np.array([1, 0, 2, 1]) + >>> q, r = np.linalg.qr(A) + >>> p = np.dot(q.T, b) + >>> np.dot(np.linalg.inv(r), p) + array([ 1.1e-16, 1.0e+00]) + + """ + if mode not in ('reduced', 'complete', 'r', 'raw'): + if mode in ('f', 'full'): + # 2013-04-01, 1.8 + msg = "".join(( + "The 'full' option is deprecated in favor of 'reduced'.\n", + "For backward compatibility let mode default.")) + warnings.warn(msg, DeprecationWarning, stacklevel=3) + mode = 'reduced' + elif mode in ('e', 'economic'): + # 2013-04-01, 1.8 + msg = "The 'economic' option is deprecated." + warnings.warn(msg, DeprecationWarning, stacklevel=3) + mode = 'economic' + else: + raise ValueError(f"Unrecognized mode '{mode}'") + + a, wrap = _makearray(a) + _assert_2d(a) + m, n = a.shape + t, result_t = _commonType(a) + a = _fastCopyAndTranspose(t, a) + a = _to_native_byte_order(a) + mn = min(m, n) + tau = zeros((mn,), t) + + if isComplexType(t): + lapack_routine = lapack_lite.zgeqrf + routine_name = 'zgeqrf' + else: + lapack_routine = lapack_lite.dgeqrf + routine_name = 'dgeqrf' + + # calculate optimal size of work data 'work' + lwork = 1 + work = zeros((lwork,), t) + results = lapack_routine(m, n, a, max(1, m), tau, work, -1, 0) + if results['info'] != 0: + raise LinAlgError('%s returns %d' % (routine_name, results['info'])) + + # do qr decomposition + lwork = max(1, n, int(abs(work[0]))) + work = zeros((lwork,), t) + results = lapack_routine(m, n, a, max(1, m), tau, work, lwork, 0) + if results['info'] != 0: + raise LinAlgError('%s returns %d' % (routine_name, results['info'])) + + # handle modes that don't return q + if mode == 'r': + r = _fastCopyAndTranspose(result_t, a[:, :mn]) + return wrap(triu(r)) + + if mode == 'raw': + return a, tau + + if mode == 'economic': + if t != result_t : + a = a.astype(result_t, copy=False) + return wrap(a.T) + + # generate q from a + if mode == 'complete' and m > n: + mc = m + q = empty((m, m), t) + else: + mc = mn + q = empty((n, m), t) + q[:n] = a + + if isComplexType(t): + lapack_routine = lapack_lite.zungqr + routine_name = 'zungqr' + else: + lapack_routine = lapack_lite.dorgqr + routine_name = 'dorgqr' + + # determine optimal lwork + lwork = 1 + work = zeros((lwork,), t) + results = lapack_routine(m, mc, mn, q, max(1, m), tau, work, -1, 0) + if results['info'] != 0: + raise LinAlgError('%s returns %d' % (routine_name, results['info'])) + + # compute q + lwork = max(1, n, int(abs(work[0]))) + work = zeros((lwork,), t) + results = lapack_routine(m, mc, mn, q, max(1, m), tau, work, lwork, 0) + if results['info'] != 0: + raise LinAlgError('%s returns %d' % (routine_name, results['info'])) + + q = _fastCopyAndTranspose(result_t, q[:mc]) + r = _fastCopyAndTranspose(result_t, a[:, :mc]) + + return wrap(q), wrap(triu(r)) + + +# Eigenvalues + + +@array_function_dispatch(_unary_dispatcher) +def eigvals(a): + """ + Compute the eigenvalues of a general matrix. + + Main difference between `eigvals` and `eig`: the eigenvectors aren't + returned. + + Parameters + ---------- + a : (..., M, M) array_like + A complex- or real-valued matrix whose eigenvalues will be computed. + + Returns + ------- + w : (..., M,) ndarray + The eigenvalues, each repeated according to its multiplicity. + They are not necessarily ordered, nor are they necessarily + real for real matrices. + + Raises + ------ + LinAlgError + If the eigenvalue computation does not converge. + + See Also + -------- + eig : eigenvalues and right eigenvectors of general arrays + eigvalsh : eigenvalues of real symmetric or complex Hermitian + (conjugate symmetric) arrays. + eigh : eigenvalues and eigenvectors of real symmetric or complex + Hermitian (conjugate symmetric) arrays. + scipy.linalg.eigvals : Similar function in SciPy. + + Notes + ----- + + .. versionadded:: 1.8.0 + + Broadcasting rules apply, see the `numpy.linalg` documentation for + details. + + This is implemented using the ``_geev`` LAPACK routines which compute + the eigenvalues and eigenvectors of general square arrays. + + Examples + -------- + Illustration, using the fact that the eigenvalues of a diagonal matrix + are its diagonal elements, that multiplying a matrix on the left + by an orthogonal matrix, `Q`, and on the right by `Q.T` (the transpose + of `Q`), preserves the eigenvalues of the "middle" matrix. In other words, + if `Q` is orthogonal, then ``Q * A * Q.T`` has the same eigenvalues as + ``A``: + + >>> from numpy import linalg as LA + >>> x = np.random.random() + >>> Q = np.array([[np.cos(x), -np.sin(x)], [np.sin(x), np.cos(x)]]) + >>> LA.norm(Q[0, :]), LA.norm(Q[1, :]), np.dot(Q[0, :],Q[1, :]) + (1.0, 1.0, 0.0) + + Now multiply a diagonal matrix by ``Q`` on one side and by ``Q.T`` on the other: + + >>> D = np.diag((-1,1)) + >>> LA.eigvals(D) + array([-1., 1.]) + >>> A = np.dot(Q, D) + >>> A = np.dot(A, Q.T) + >>> LA.eigvals(A) + array([ 1., -1.]) # random + + """ + a, wrap = _makearray(a) + _assert_stacked_2d(a) + _assert_stacked_square(a) + _assert_finite(a) + t, result_t = _commonType(a) + + extobj = get_linalg_error_extobj( + _raise_linalgerror_eigenvalues_nonconvergence) + signature = 'D->D' if isComplexType(t) else 'd->D' + w = _umath_linalg.eigvals(a, signature=signature, extobj=extobj) + + if not isComplexType(t): + if all(w.imag == 0): + w = w.real + result_t = _realType(result_t) + else: + result_t = _complexType(result_t) + + return w.astype(result_t, copy=False) + + +def _eigvalsh_dispatcher(a, UPLO=None): + return (a,) + + +@array_function_dispatch(_eigvalsh_dispatcher) +def eigvalsh(a, UPLO='L'): + """ + Compute the eigenvalues of a complex Hermitian or real symmetric matrix. + + Main difference from eigh: the eigenvectors are not computed. + + Parameters + ---------- + a : (..., M, M) array_like + A complex- or real-valued matrix whose eigenvalues are to be + computed. + UPLO : {'L', 'U'}, optional + Specifies whether the calculation is done with the lower triangular + part of `a` ('L', default) or the upper triangular part ('U'). + Irrespective of this value only the real parts of the diagonal will + be considered in the computation to preserve the notion of a Hermitian + matrix. It therefore follows that the imaginary part of the diagonal + will always be treated as zero. + + Returns + ------- + w : (..., M,) ndarray + The eigenvalues in ascending order, each repeated according to + its multiplicity. + + Raises + ------ + LinAlgError + If the eigenvalue computation does not converge. + + See Also + -------- + eigh : eigenvalues and eigenvectors of real symmetric or complex Hermitian + (conjugate symmetric) arrays. + eigvals : eigenvalues of general real or complex arrays. + eig : eigenvalues and right eigenvectors of general real or complex + arrays. + scipy.linalg.eigvalsh : Similar function in SciPy. + + Notes + ----- + + .. versionadded:: 1.8.0 + + Broadcasting rules apply, see the `numpy.linalg` documentation for + details. + + The eigenvalues are computed using LAPACK routines ``_syevd``, ``_heevd``. + + Examples + -------- + >>> from numpy import linalg as LA + >>> a = np.array([[1, -2j], [2j, 5]]) + >>> LA.eigvalsh(a) + array([ 0.17157288, 5.82842712]) # may vary + + >>> # demonstrate the treatment of the imaginary part of the diagonal + >>> a = np.array([[5+2j, 9-2j], [0+2j, 2-1j]]) + >>> a + array([[5.+2.j, 9.-2.j], + [0.+2.j, 2.-1.j]]) + >>> # with UPLO='L' this is numerically equivalent to using LA.eigvals() + >>> # with: + >>> b = np.array([[5.+0.j, 0.-2.j], [0.+2.j, 2.-0.j]]) + >>> b + array([[5.+0.j, 0.-2.j], + [0.+2.j, 2.+0.j]]) + >>> wa = LA.eigvalsh(a) + >>> wb = LA.eigvals(b) + >>> wa; wb + array([1., 6.]) + array([6.+0.j, 1.+0.j]) + + """ + UPLO = UPLO.upper() + if UPLO not in ('L', 'U'): + raise ValueError("UPLO argument must be 'L' or 'U'") + + extobj = get_linalg_error_extobj( + _raise_linalgerror_eigenvalues_nonconvergence) + if UPLO == 'L': + gufunc = _umath_linalg.eigvalsh_lo + else: + gufunc = _umath_linalg.eigvalsh_up + + a, wrap = _makearray(a) + _assert_stacked_2d(a) + _assert_stacked_square(a) + t, result_t = _commonType(a) + signature = 'D->d' if isComplexType(t) else 'd->d' + w = gufunc(a, signature=signature, extobj=extobj) + return w.astype(_realType(result_t), copy=False) + +def _convertarray(a): + t, result_t = _commonType(a) + a = _fastCT(a.astype(t)) + return a, t, result_t + + +# Eigenvectors + + +@array_function_dispatch(_unary_dispatcher) +def eig(a): + """ + Compute the eigenvalues and right eigenvectors of a square array. + + Parameters + ---------- + a : (..., M, M) array + Matrices for which the eigenvalues and right eigenvectors will + be computed + + Returns + ------- + w : (..., M) array + The eigenvalues, each repeated according to its multiplicity. + The eigenvalues are not necessarily ordered. The resulting + array will be of complex type, unless the imaginary part is + zero in which case it will be cast to a real type. When `a` + is real the resulting eigenvalues will be real (0 imaginary + part) or occur in conjugate pairs + + v : (..., M, M) array + The normalized (unit "length") eigenvectors, such that the + column ``v[:,i]`` is the eigenvector corresponding to the + eigenvalue ``w[i]``. + + Raises + ------ + LinAlgError + If the eigenvalue computation does not converge. + + See Also + -------- + eigvals : eigenvalues of a non-symmetric array. + eigh : eigenvalues and eigenvectors of a real symmetric or complex + Hermitian (conjugate symmetric) array. + eigvalsh : eigenvalues of a real symmetric or complex Hermitian + (conjugate symmetric) array. + scipy.linalg.eig : Similar function in SciPy that also solves the + generalized eigenvalue problem. + scipy.linalg.schur : Best choice for unitary and other non-Hermitian + normal matrices. + + Notes + ----- + + .. versionadded:: 1.8.0 + + Broadcasting rules apply, see the `numpy.linalg` documentation for + details. + + This is implemented using the ``_geev`` LAPACK routines which compute + the eigenvalues and eigenvectors of general square arrays. + + The number `w` is an eigenvalue of `a` if there exists a vector + `v` such that ``a @ v = w * v``. Thus, the arrays `a`, `w`, and + `v` satisfy the equations ``a @ v[:,i] = w[i] * v[:,i]`` + for :math:`i \\in \\{0,...,M-1\\}`. + + The array `v` of eigenvectors may not be of maximum rank, that is, some + of the columns may be linearly dependent, although round-off error may + obscure that fact. If the eigenvalues are all different, then theoretically + the eigenvectors are linearly independent and `a` can be diagonalized by + a similarity transformation using `v`, i.e, ``inv(v) @ a @ v`` is diagonal. + + For non-Hermitian normal matrices the SciPy function `scipy.linalg.schur` + is preferred because the matrix `v` is guaranteed to be unitary, which is + not the case when using `eig`. The Schur factorization produces an + upper triangular matrix rather than a diagonal matrix, but for normal + matrices only the diagonal of the upper triangular matrix is needed, the + rest is roundoff error. + + Finally, it is emphasized that `v` consists of the *right* (as in + right-hand side) eigenvectors of `a`. A vector `y` satisfying + ``y.T @ a = z * y.T`` for some number `z` is called a *left* + eigenvector of `a`, and, in general, the left and right eigenvectors + of a matrix are not necessarily the (perhaps conjugate) transposes + of each other. + + References + ---------- + G. Strang, *Linear Algebra and Its Applications*, 2nd Ed., Orlando, FL, + Academic Press, Inc., 1980, Various pp. + + Examples + -------- + >>> from numpy import linalg as LA + + (Almost) trivial example with real e-values and e-vectors. + + >>> w, v = LA.eig(np.diag((1, 2, 3))) + >>> w; v + array([1., 2., 3.]) + array([[1., 0., 0.], + [0., 1., 0.], + [0., 0., 1.]]) + + Real matrix possessing complex e-values and e-vectors; note that the + e-values are complex conjugates of each other. + + >>> w, v = LA.eig(np.array([[1, -1], [1, 1]])) + >>> w; v + array([1.+1.j, 1.-1.j]) + array([[0.70710678+0.j , 0.70710678-0.j ], + [0. -0.70710678j, 0. +0.70710678j]]) + + Complex-valued matrix with real e-values (but complex-valued e-vectors); + note that ``a.conj().T == a``, i.e., `a` is Hermitian. + + >>> a = np.array([[1, 1j], [-1j, 1]]) + >>> w, v = LA.eig(a) + >>> w; v + array([2.+0.j, 0.+0.j]) + array([[ 0. +0.70710678j, 0.70710678+0.j ], # may vary + [ 0.70710678+0.j , -0. +0.70710678j]]) + + Be careful about round-off error! + + >>> a = np.array([[1 + 1e-9, 0], [0, 1 - 1e-9]]) + >>> # Theor. e-values are 1 +/- 1e-9 + >>> w, v = LA.eig(a) + >>> w; v + array([1., 1.]) + array([[1., 0.], + [0., 1.]]) + + """ + a, wrap = _makearray(a) + _assert_stacked_2d(a) + _assert_stacked_square(a) + _assert_finite(a) + t, result_t = _commonType(a) + + extobj = get_linalg_error_extobj( + _raise_linalgerror_eigenvalues_nonconvergence) + signature = 'D->DD' if isComplexType(t) else 'd->DD' + w, vt = _umath_linalg.eig(a, signature=signature, extobj=extobj) + + if not isComplexType(t) and all(w.imag == 0.0): + w = w.real + vt = vt.real + result_t = _realType(result_t) + else: + result_t = _complexType(result_t) + + vt = vt.astype(result_t, copy=False) + return w.astype(result_t, copy=False), wrap(vt) + + +@array_function_dispatch(_eigvalsh_dispatcher) +def eigh(a, UPLO='L'): + """ + Return the eigenvalues and eigenvectors of a complex Hermitian + (conjugate symmetric) or a real symmetric matrix. + + Returns two objects, a 1-D array containing the eigenvalues of `a`, and + a 2-D square array or matrix (depending on the input type) of the + corresponding eigenvectors (in columns). + + Parameters + ---------- + a : (..., M, M) array + Hermitian or real symmetric matrices whose eigenvalues and + eigenvectors are to be computed. + UPLO : {'L', 'U'}, optional + Specifies whether the calculation is done with the lower triangular + part of `a` ('L', default) or the upper triangular part ('U'). + Irrespective of this value only the real parts of the diagonal will + be considered in the computation to preserve the notion of a Hermitian + matrix. It therefore follows that the imaginary part of the diagonal + will always be treated as zero. + + Returns + ------- + w : (..., M) ndarray + The eigenvalues in ascending order, each repeated according to + its multiplicity. + v : {(..., M, M) ndarray, (..., M, M) matrix} + The column ``v[:, i]`` is the normalized eigenvector corresponding + to the eigenvalue ``w[i]``. Will return a matrix object if `a` is + a matrix object. + + Raises + ------ + LinAlgError + If the eigenvalue computation does not converge. + + See Also + -------- + eigvalsh : eigenvalues of real symmetric or complex Hermitian + (conjugate symmetric) arrays. + eig : eigenvalues and right eigenvectors for non-symmetric arrays. + eigvals : eigenvalues of non-symmetric arrays. + scipy.linalg.eigh : Similar function in SciPy (but also solves the + generalized eigenvalue problem). + + Notes + ----- + + .. versionadded:: 1.8.0 + + Broadcasting rules apply, see the `numpy.linalg` documentation for + details. + + The eigenvalues/eigenvectors are computed using LAPACK routines ``_syevd``, + ``_heevd``. + + The eigenvalues of real symmetric or complex Hermitian matrices are + always real. [1]_ The array `v` of (column) eigenvectors is unitary + and `a`, `w`, and `v` satisfy the equations + ``dot(a, v[:, i]) = w[i] * v[:, i]``. + + References + ---------- + .. [1] G. Strang, *Linear Algebra and Its Applications*, 2nd Ed., Orlando, + FL, Academic Press, Inc., 1980, pg. 222. + + Examples + -------- + >>> from numpy import linalg as LA + >>> a = np.array([[1, -2j], [2j, 5]]) + >>> a + array([[ 1.+0.j, -0.-2.j], + [ 0.+2.j, 5.+0.j]]) + >>> w, v = LA.eigh(a) + >>> w; v + array([0.17157288, 5.82842712]) + array([[-0.92387953+0.j , -0.38268343+0.j ], # may vary + [ 0. +0.38268343j, 0. -0.92387953j]]) + + >>> np.dot(a, v[:, 0]) - w[0] * v[:, 0] # verify 1st e-val/vec pair + array([5.55111512e-17+0.0000000e+00j, 0.00000000e+00+1.2490009e-16j]) + >>> np.dot(a, v[:, 1]) - w[1] * v[:, 1] # verify 2nd e-val/vec pair + array([0.+0.j, 0.+0.j]) + + >>> A = np.matrix(a) # what happens if input is a matrix object + >>> A + matrix([[ 1.+0.j, -0.-2.j], + [ 0.+2.j, 5.+0.j]]) + >>> w, v = LA.eigh(A) + >>> w; v + array([0.17157288, 5.82842712]) + matrix([[-0.92387953+0.j , -0.38268343+0.j ], # may vary + [ 0. +0.38268343j, 0. -0.92387953j]]) + + >>> # demonstrate the treatment of the imaginary part of the diagonal + >>> a = np.array([[5+2j, 9-2j], [0+2j, 2-1j]]) + >>> a + array([[5.+2.j, 9.-2.j], + [0.+2.j, 2.-1.j]]) + >>> # with UPLO='L' this is numerically equivalent to using LA.eig() with: + >>> b = np.array([[5.+0.j, 0.-2.j], [0.+2.j, 2.-0.j]]) + >>> b + array([[5.+0.j, 0.-2.j], + [0.+2.j, 2.+0.j]]) + >>> wa, va = LA.eigh(a) + >>> wb, vb = LA.eig(b) + >>> wa; wb + array([1., 6.]) + array([6.+0.j, 1.+0.j]) + >>> va; vb + array([[-0.4472136 +0.j , -0.89442719+0.j ], # may vary + [ 0. +0.89442719j, 0. -0.4472136j ]]) + array([[ 0.89442719+0.j , -0. +0.4472136j], + [-0. +0.4472136j, 0.89442719+0.j ]]) + """ + UPLO = UPLO.upper() + if UPLO not in ('L', 'U'): + raise ValueError("UPLO argument must be 'L' or 'U'") + + a, wrap = _makearray(a) + _assert_stacked_2d(a) + _assert_stacked_square(a) + t, result_t = _commonType(a) + + extobj = get_linalg_error_extobj( + _raise_linalgerror_eigenvalues_nonconvergence) + if UPLO == 'L': + gufunc = _umath_linalg.eigh_lo + else: + gufunc = _umath_linalg.eigh_up + + signature = 'D->dD' if isComplexType(t) else 'd->dd' + w, vt = gufunc(a, signature=signature, extobj=extobj) + w = w.astype(_realType(result_t), copy=False) + vt = vt.astype(result_t, copy=False) + return w, wrap(vt) + + +# Singular value decomposition + +def _svd_dispatcher(a, full_matrices=None, compute_uv=None, hermitian=None): + return (a,) + + +@array_function_dispatch(_svd_dispatcher) +def svd(a, full_matrices=True, compute_uv=True, hermitian=False): + """ + Singular Value Decomposition. + + When `a` is a 2D array, it is factorized as ``u @ np.diag(s) @ vh + = (u * s) @ vh``, where `u` and `vh` are 2D unitary arrays and `s` is a 1D + array of `a`'s singular values. When `a` is higher-dimensional, SVD is + applied in stacked mode as explained below. + + Parameters + ---------- + a : (..., M, N) array_like + A real or complex array with ``a.ndim >= 2``. + full_matrices : bool, optional + If True (default), `u` and `vh` have the shapes ``(..., M, M)`` and + ``(..., N, N)``, respectively. Otherwise, the shapes are + ``(..., M, K)`` and ``(..., K, N)``, respectively, where + ``K = min(M, N)``. + compute_uv : bool, optional + Whether or not to compute `u` and `vh` in addition to `s`. True + by default. + hermitian : bool, optional + If True, `a` is assumed to be Hermitian (symmetric if real-valued), + enabling a more efficient method for finding singular values. + Defaults to False. + + .. versionadded:: 1.17.0 + + Returns + ------- + u : { (..., M, M), (..., M, K) } array + Unitary array(s). The first ``a.ndim - 2`` dimensions have the same + size as those of the input `a`. The size of the last two dimensions + depends on the value of `full_matrices`. Only returned when + `compute_uv` is True. + s : (..., K) array + Vector(s) with the singular values, within each vector sorted in + descending order. The first ``a.ndim - 2`` dimensions have the same + size as those of the input `a`. + vh : { (..., N, N), (..., K, N) } array + Unitary array(s). The first ``a.ndim - 2`` dimensions have the same + size as those of the input `a`. The size of the last two dimensions + depends on the value of `full_matrices`. Only returned when + `compute_uv` is True. + + Raises + ------ + LinAlgError + If SVD computation does not converge. + + See Also + -------- + scipy.linalg.svd : Similar function in SciPy. + scipy.linalg.svdvals : Compute singular values of a matrix. + + Notes + ----- + + .. versionchanged:: 1.8.0 + Broadcasting rules apply, see the `numpy.linalg` documentation for + details. + + The decomposition is performed using LAPACK routine ``_gesdd``. + + SVD is usually described for the factorization of a 2D matrix :math:`A`. + The higher-dimensional case will be discussed below. In the 2D case, SVD is + written as :math:`A = U S V^H`, where :math:`A = a`, :math:`U= u`, + :math:`S= \\mathtt{np.diag}(s)` and :math:`V^H = vh`. The 1D array `s` + contains the singular values of `a` and `u` and `vh` are unitary. The rows + of `vh` are the eigenvectors of :math:`A^H A` and the columns of `u` are + the eigenvectors of :math:`A A^H`. In both cases the corresponding + (possibly non-zero) eigenvalues are given by ``s**2``. + + If `a` has more than two dimensions, then broadcasting rules apply, as + explained in :ref:`routines.linalg-broadcasting`. This means that SVD is + working in "stacked" mode: it iterates over all indices of the first + ``a.ndim - 2`` dimensions and for each combination SVD is applied to the + last two indices. The matrix `a` can be reconstructed from the + decomposition with either ``(u * s[..., None, :]) @ vh`` or + ``u @ (s[..., None] * vh)``. (The ``@`` operator can be replaced by the + function ``np.matmul`` for python versions below 3.5.) + + If `a` is a ``matrix`` object (as opposed to an ``ndarray``), then so are + all the return values. + + Examples + -------- + >>> a = np.random.randn(9, 6) + 1j*np.random.randn(9, 6) + >>> b = np.random.randn(2, 7, 8, 3) + 1j*np.random.randn(2, 7, 8, 3) + + Reconstruction based on full SVD, 2D case: + + >>> u, s, vh = np.linalg.svd(a, full_matrices=True) + >>> u.shape, s.shape, vh.shape + ((9, 9), (6,), (6, 6)) + >>> np.allclose(a, np.dot(u[:, :6] * s, vh)) + True + >>> smat = np.zeros((9, 6), dtype=complex) + >>> smat[:6, :6] = np.diag(s) + >>> np.allclose(a, np.dot(u, np.dot(smat, vh))) + True + + Reconstruction based on reduced SVD, 2D case: + + >>> u, s, vh = np.linalg.svd(a, full_matrices=False) + >>> u.shape, s.shape, vh.shape + ((9, 6), (6,), (6, 6)) + >>> np.allclose(a, np.dot(u * s, vh)) + True + >>> smat = np.diag(s) + >>> np.allclose(a, np.dot(u, np.dot(smat, vh))) + True + + Reconstruction based on full SVD, 4D case: + + >>> u, s, vh = np.linalg.svd(b, full_matrices=True) + >>> u.shape, s.shape, vh.shape + ((2, 7, 8, 8), (2, 7, 3), (2, 7, 3, 3)) + >>> np.allclose(b, np.matmul(u[..., :3] * s[..., None, :], vh)) + True + >>> np.allclose(b, np.matmul(u[..., :3], s[..., None] * vh)) + True + + Reconstruction based on reduced SVD, 4D case: + + >>> u, s, vh = np.linalg.svd(b, full_matrices=False) + >>> u.shape, s.shape, vh.shape + ((2, 7, 8, 3), (2, 7, 3), (2, 7, 3, 3)) + >>> np.allclose(b, np.matmul(u * s[..., None, :], vh)) + True + >>> np.allclose(b, np.matmul(u, s[..., None] * vh)) + True + + """ + import numpy as _nx + a, wrap = _makearray(a) + + if hermitian: + # note: lapack svd returns eigenvalues with s ** 2 sorted descending, + # but eig returns s sorted ascending, so we re-order the eigenvalues + # and related arrays to have the correct order + if compute_uv: + s, u = eigh(a) + sgn = sign(s) + s = abs(s) + sidx = argsort(s)[..., ::-1] + sgn = _nx.take_along_axis(sgn, sidx, axis=-1) + s = _nx.take_along_axis(s, sidx, axis=-1) + u = _nx.take_along_axis(u, sidx[..., None, :], axis=-1) + # singular values are unsigned, move the sign into v + vt = transpose(u * sgn[..., None, :]).conjugate() + return wrap(u), s, wrap(vt) + else: + s = eigvalsh(a) + s = s[..., ::-1] + s = abs(s) + return sort(s)[..., ::-1] + + _assert_stacked_2d(a) + t, result_t = _commonType(a) + + extobj = get_linalg_error_extobj(_raise_linalgerror_svd_nonconvergence) + + m, n = a.shape[-2:] + if compute_uv: + if full_matrices: + if m < n: + gufunc = _umath_linalg.svd_m_f + else: + gufunc = _umath_linalg.svd_n_f + else: + if m < n: + gufunc = _umath_linalg.svd_m_s + else: + gufunc = _umath_linalg.svd_n_s + + signature = 'D->DdD' if isComplexType(t) else 'd->ddd' + u, s, vh = gufunc(a, signature=signature, extobj=extobj) + u = u.astype(result_t, copy=False) + s = s.astype(_realType(result_t), copy=False) + vh = vh.astype(result_t, copy=False) + return wrap(u), s, wrap(vh) + else: + if m < n: + gufunc = _umath_linalg.svd_m + else: + gufunc = _umath_linalg.svd_n + + signature = 'D->d' if isComplexType(t) else 'd->d' + s = gufunc(a, signature=signature, extobj=extobj) + s = s.astype(_realType(result_t), copy=False) + return s + + +def _cond_dispatcher(x, p=None): + return (x,) + + +@array_function_dispatch(_cond_dispatcher) +def cond(x, p=None): + """ + Compute the condition number of a matrix. + + This function is capable of returning the condition number using + one of seven different norms, depending on the value of `p` (see + Parameters below). + + Parameters + ---------- + x : (..., M, N) array_like + The matrix whose condition number is sought. + p : {None, 1, -1, 2, -2, inf, -inf, 'fro'}, optional + Order of the norm: + + ===== ============================ + p norm for matrices + ===== ============================ + None 2-norm, computed directly using the ``SVD`` + 'fro' Frobenius norm + inf max(sum(abs(x), axis=1)) + -inf min(sum(abs(x), axis=1)) + 1 max(sum(abs(x), axis=0)) + -1 min(sum(abs(x), axis=0)) + 2 2-norm (largest sing. value) + -2 smallest singular value + ===== ============================ + + inf means the numpy.inf object, and the Frobenius norm is + the root-of-sum-of-squares norm. + + Returns + ------- + c : {float, inf} + The condition number of the matrix. May be infinite. + + See Also + -------- + numpy.linalg.norm + + Notes + ----- + The condition number of `x` is defined as the norm of `x` times the + norm of the inverse of `x` [1]_; the norm can be the usual L2-norm + (root-of-sum-of-squares) or one of a number of other matrix norms. + + References + ---------- + .. [1] G. Strang, *Linear Algebra and Its Applications*, Orlando, FL, + Academic Press, Inc., 1980, pg. 285. + + Examples + -------- + >>> from numpy import linalg as LA + >>> a = np.array([[1, 0, -1], [0, 1, 0], [1, 0, 1]]) + >>> a + array([[ 1, 0, -1], + [ 0, 1, 0], + [ 1, 0, 1]]) + >>> LA.cond(a) + 1.4142135623730951 + >>> LA.cond(a, 'fro') + 3.1622776601683795 + >>> LA.cond(a, np.inf) + 2.0 + >>> LA.cond(a, -np.inf) + 1.0 + >>> LA.cond(a, 1) + 2.0 + >>> LA.cond(a, -1) + 1.0 + >>> LA.cond(a, 2) + 1.4142135623730951 + >>> LA.cond(a, -2) + 0.70710678118654746 # may vary + >>> min(LA.svd(a, compute_uv=False))*min(LA.svd(LA.inv(a), compute_uv=False)) + 0.70710678118654746 # may vary + + """ + x = asarray(x) # in case we have a matrix + if _is_empty_2d(x): + raise LinAlgError("cond is not defined on empty arrays") + if p is None or p == 2 or p == -2: + s = svd(x, compute_uv=False) + with errstate(all='ignore'): + if p == -2: + r = s[..., -1] / s[..., 0] + else: + r = s[..., 0] / s[..., -1] + else: + # Call inv(x) ignoring errors. The result array will + # contain nans in the entries where inversion failed. + _assert_stacked_2d(x) + _assert_stacked_square(x) + t, result_t = _commonType(x) + signature = 'D->D' if isComplexType(t) else 'd->d' + with errstate(all='ignore'): + invx = _umath_linalg.inv(x, signature=signature) + r = norm(x, p, axis=(-2, -1)) * norm(invx, p, axis=(-2, -1)) + r = r.astype(result_t, copy=False) + + # Convert nans to infs unless the original array had nan entries + r = asarray(r) + nan_mask = isnan(r) + if nan_mask.any(): + nan_mask &= ~isnan(x).any(axis=(-2, -1)) + if r.ndim > 0: + r[nan_mask] = Inf + elif nan_mask: + r[()] = Inf + + # Convention is to return scalars instead of 0d arrays + if r.ndim == 0: + r = r[()] + + return r + + +def _matrix_rank_dispatcher(M, tol=None, hermitian=None): + return (M,) + + +@array_function_dispatch(_matrix_rank_dispatcher) +def matrix_rank(M, tol=None, hermitian=False): + """ + Return matrix rank of array using SVD method + + Rank of the array is the number of singular values of the array that are + greater than `tol`. + + .. versionchanged:: 1.14 + Can now operate on stacks of matrices + + Parameters + ---------- + M : {(M,), (..., M, N)} array_like + Input vector or stack of matrices. + tol : (...) array_like, float, optional + Threshold below which SVD values are considered zero. If `tol` is + None, and ``S`` is an array with singular values for `M`, and + ``eps`` is the epsilon value for datatype of ``S``, then `tol` is + set to ``S.max() * max(M.shape) * eps``. + + .. versionchanged:: 1.14 + Broadcasted against the stack of matrices + hermitian : bool, optional + If True, `M` is assumed to be Hermitian (symmetric if real-valued), + enabling a more efficient method for finding singular values. + Defaults to False. + + .. versionadded:: 1.14 + + Returns + ------- + rank : (...) array_like + Rank of M. + + Notes + ----- + The default threshold to detect rank deficiency is a test on the magnitude + of the singular values of `M`. By default, we identify singular values less + than ``S.max() * max(M.shape) * eps`` as indicating rank deficiency (with + the symbols defined above). This is the algorithm MATLAB uses [1]. It also + appears in *Numerical recipes* in the discussion of SVD solutions for linear + least squares [2]. + + This default threshold is designed to detect rank deficiency accounting for + the numerical errors of the SVD computation. Imagine that there is a column + in `M` that is an exact (in floating point) linear combination of other + columns in `M`. Computing the SVD on `M` will not produce a singular value + exactly equal to 0 in general: any difference of the smallest SVD value from + 0 will be caused by numerical imprecision in the calculation of the SVD. + Our threshold for small SVD values takes this numerical imprecision into + account, and the default threshold will detect such numerical rank + deficiency. The threshold may declare a matrix `M` rank deficient even if + the linear combination of some columns of `M` is not exactly equal to + another column of `M` but only numerically very close to another column of + `M`. + + We chose our default threshold because it is in wide use. Other thresholds + are possible. For example, elsewhere in the 2007 edition of *Numerical + recipes* there is an alternative threshold of ``S.max() * + np.finfo(M.dtype).eps / 2. * np.sqrt(m + n + 1.)``. The authors describe + this threshold as being based on "expected roundoff error" (p 71). + + The thresholds above deal with floating point roundoff error in the + calculation of the SVD. However, you may have more information about the + sources of error in `M` that would make you consider other tolerance values + to detect *effective* rank deficiency. The most useful measure of the + tolerance depends on the operations you intend to use on your matrix. For + example, if your data come from uncertain measurements with uncertainties + greater than floating point epsilon, choosing a tolerance near that + uncertainty may be preferable. The tolerance may be absolute if the + uncertainties are absolute rather than relative. + + References + ---------- + .. [1] MATLAB reference documention, "Rank" + https://www.mathworks.com/help/techdoc/ref/rank.html + .. [2] W. H. Press, S. A. Teukolsky, W. T. Vetterling and B. P. Flannery, + "Numerical Recipes (3rd edition)", Cambridge University Press, 2007, + page 795. + + Examples + -------- + >>> from numpy.linalg import matrix_rank + >>> matrix_rank(np.eye(4)) # Full rank matrix + 4 + >>> I=np.eye(4); I[-1,-1] = 0. # rank deficient matrix + >>> matrix_rank(I) + 3 + >>> matrix_rank(np.ones((4,))) # 1 dimension - rank 1 unless all 0 + 1 + >>> matrix_rank(np.zeros((4,))) + 0 + """ + M = asarray(M) + if M.ndim < 2: + return int(not all(M==0)) + S = svd(M, compute_uv=False, hermitian=hermitian) + if tol is None: + tol = S.max(axis=-1, keepdims=True) * max(M.shape[-2:]) * finfo(S.dtype).eps + else: + tol = asarray(tol)[..., newaxis] + return count_nonzero(S > tol, axis=-1) + + +# Generalized inverse + +def _pinv_dispatcher(a, rcond=None, hermitian=None): + return (a,) + + +@array_function_dispatch(_pinv_dispatcher) +def pinv(a, rcond=1e-15, hermitian=False): + """ + Compute the (Moore-Penrose) pseudo-inverse of a matrix. + + Calculate the generalized inverse of a matrix using its + singular-value decomposition (SVD) and including all + *large* singular values. + + .. versionchanged:: 1.14 + Can now operate on stacks of matrices + + Parameters + ---------- + a : (..., M, N) array_like + Matrix or stack of matrices to be pseudo-inverted. + rcond : (...) array_like of float + Cutoff for small singular values. + Singular values less than or equal to + ``rcond * largest_singular_value`` are set to zero. + Broadcasts against the stack of matrices. + hermitian : bool, optional + If True, `a` is assumed to be Hermitian (symmetric if real-valued), + enabling a more efficient method for finding singular values. + Defaults to False. + + .. versionadded:: 1.17.0 + + Returns + ------- + B : (..., N, M) ndarray + The pseudo-inverse of `a`. If `a` is a `matrix` instance, then so + is `B`. + + Raises + ------ + LinAlgError + If the SVD computation does not converge. + + See Also + -------- + scipy.linalg.pinv : Similar function in SciPy. + scipy.linalg.pinv2 : Similar function in SciPy (SVD-based). + scipy.linalg.pinvh : Compute the (Moore-Penrose) pseudo-inverse of a + Hermitian matrix. + + Notes + ----- + The pseudo-inverse of a matrix A, denoted :math:`A^+`, is + defined as: "the matrix that 'solves' [the least-squares problem] + :math:`Ax = b`," i.e., if :math:`\\bar{x}` is said solution, then + :math:`A^+` is that matrix such that :math:`\\bar{x} = A^+b`. + + It can be shown that if :math:`Q_1 \\Sigma Q_2^T = A` is the singular + value decomposition of A, then + :math:`A^+ = Q_2 \\Sigma^+ Q_1^T`, where :math:`Q_{1,2}` are + orthogonal matrices, :math:`\\Sigma` is a diagonal matrix consisting + of A's so-called singular values, (followed, typically, by + zeros), and then :math:`\\Sigma^+` is simply the diagonal matrix + consisting of the reciprocals of A's singular values + (again, followed by zeros). [1]_ + + References + ---------- + .. [1] G. Strang, *Linear Algebra and Its Applications*, 2nd Ed., Orlando, + FL, Academic Press, Inc., 1980, pp. 139-142. + + Examples + -------- + The following example checks that ``a * a+ * a == a`` and + ``a+ * a * a+ == a+``: + + >>> a = np.random.randn(9, 6) + >>> B = np.linalg.pinv(a) + >>> np.allclose(a, np.dot(a, np.dot(B, a))) + True + >>> np.allclose(B, np.dot(B, np.dot(a, B))) + True + + """ + a, wrap = _makearray(a) + rcond = asarray(rcond) + if _is_empty_2d(a): + m, n = a.shape[-2:] + res = empty(a.shape[:-2] + (n, m), dtype=a.dtype) + return wrap(res) + a = a.conjugate() + u, s, vt = svd(a, full_matrices=False, hermitian=hermitian) + + # discard small singular values + cutoff = rcond[..., newaxis] * amax(s, axis=-1, keepdims=True) + large = s > cutoff + s = divide(1, s, where=large, out=s) + s[~large] = 0 + + res = matmul(transpose(vt), multiply(s[..., newaxis], transpose(u))) + return wrap(res) + + +# Determinant + + +@array_function_dispatch(_unary_dispatcher) +def slogdet(a): + """ + Compute the sign and (natural) logarithm of the determinant of an array. + + If an array has a very small or very large determinant, then a call to + `det` may overflow or underflow. This routine is more robust against such + issues, because it computes the logarithm of the determinant rather than + the determinant itself. + + Parameters + ---------- + a : (..., M, M) array_like + Input array, has to be a square 2-D array. + + Returns + ------- + sign : (...) array_like + A number representing the sign of the determinant. For a real matrix, + this is 1, 0, or -1. For a complex matrix, this is a complex number + with absolute value 1 (i.e., it is on the unit circle), or else 0. + logdet : (...) array_like + The natural log of the absolute value of the determinant. + + If the determinant is zero, then `sign` will be 0 and `logdet` will be + -Inf. In all cases, the determinant is equal to ``sign * np.exp(logdet)``. + + See Also + -------- + det + + Notes + ----- + + .. versionadded:: 1.8.0 + + Broadcasting rules apply, see the `numpy.linalg` documentation for + details. + + .. versionadded:: 1.6.0 + + The determinant is computed via LU factorization using the LAPACK + routine ``z/dgetrf``. + + + Examples + -------- + The determinant of a 2-D array ``[[a, b], [c, d]]`` is ``ad - bc``: + + >>> a = np.array([[1, 2], [3, 4]]) + >>> (sign, logdet) = np.linalg.slogdet(a) + >>> (sign, logdet) + (-1, 0.69314718055994529) # may vary + >>> sign * np.exp(logdet) + -2.0 + + Computing log-determinants for a stack of matrices: + + >>> a = np.array([ [[1, 2], [3, 4]], [[1, 2], [2, 1]], [[1, 3], [3, 1]] ]) + >>> a.shape + (3, 2, 2) + >>> sign, logdet = np.linalg.slogdet(a) + >>> (sign, logdet) + (array([-1., -1., -1.]), array([ 0.69314718, 1.09861229, 2.07944154])) + >>> sign * np.exp(logdet) + array([-2., -3., -8.]) + + This routine succeeds where ordinary `det` does not: + + >>> np.linalg.det(np.eye(500) * 0.1) + 0.0 + >>> np.linalg.slogdet(np.eye(500) * 0.1) + (1, -1151.2925464970228) + + """ + a = asarray(a) + _assert_stacked_2d(a) + _assert_stacked_square(a) + t, result_t = _commonType(a) + real_t = _realType(result_t) + signature = 'D->Dd' if isComplexType(t) else 'd->dd' + sign, logdet = _umath_linalg.slogdet(a, signature=signature) + sign = sign.astype(result_t, copy=False) + logdet = logdet.astype(real_t, copy=False) + return sign, logdet + + +@array_function_dispatch(_unary_dispatcher) +def det(a): + """ + Compute the determinant of an array. + + Parameters + ---------- + a : (..., M, M) array_like + Input array to compute determinants for. + + Returns + ------- + det : (...) array_like + Determinant of `a`. + + See Also + -------- + slogdet : Another way to represent the determinant, more suitable + for large matrices where underflow/overflow may occur. + scipy.linalg.det : Similar function in SciPy. + + Notes + ----- + + .. versionadded:: 1.8.0 + + Broadcasting rules apply, see the `numpy.linalg` documentation for + details. + + The determinant is computed via LU factorization using the LAPACK + routine ``z/dgetrf``. + + Examples + -------- + The determinant of a 2-D array [[a, b], [c, d]] is ad - bc: + + >>> a = np.array([[1, 2], [3, 4]]) + >>> np.linalg.det(a) + -2.0 # may vary + + Computing determinants for a stack of matrices: + + >>> a = np.array([ [[1, 2], [3, 4]], [[1, 2], [2, 1]], [[1, 3], [3, 1]] ]) + >>> a.shape + (3, 2, 2) + >>> np.linalg.det(a) + array([-2., -3., -8.]) + + """ + a = asarray(a) + _assert_stacked_2d(a) + _assert_stacked_square(a) + t, result_t = _commonType(a) + signature = 'D->D' if isComplexType(t) else 'd->d' + r = _umath_linalg.det(a, signature=signature) + r = r.astype(result_t, copy=False) + return r + + +# Linear Least Squares + +def _lstsq_dispatcher(a, b, rcond=None): + return (a, b) + + +@array_function_dispatch(_lstsq_dispatcher) +def lstsq(a, b, rcond="warn"): + r""" + Return the least-squares solution to a linear matrix equation. + + Computes the vector x that approximatively solves the equation + ``a @ x = b``. The equation may be under-, well-, or over-determined + (i.e., the number of linearly independent rows of `a` can be less than, + equal to, or greater than its number of linearly independent columns). + If `a` is square and of full rank, then `x` (but for round-off error) + is the "exact" solution of the equation. Else, `x` minimizes the + Euclidean 2-norm :math:`|| b - a x ||`. + + Parameters + ---------- + a : (M, N) array_like + "Coefficient" matrix. + b : {(M,), (M, K)} array_like + Ordinate or "dependent variable" values. If `b` is two-dimensional, + the least-squares solution is calculated for each of the `K` columns + of `b`. + rcond : float, optional + Cut-off ratio for small singular values of `a`. + For the purposes of rank determination, singular values are treated + as zero if they are smaller than `rcond` times the largest singular + value of `a`. + + .. versionchanged:: 1.14.0 + If not set, a FutureWarning is given. The previous default + of ``-1`` will use the machine precision as `rcond` parameter, + the new default will use the machine precision times `max(M, N)`. + To silence the warning and use the new default, use ``rcond=None``, + to keep using the old behavior, use ``rcond=-1``. + + Returns + ------- + x : {(N,), (N, K)} ndarray + Least-squares solution. If `b` is two-dimensional, + the solutions are in the `K` columns of `x`. + residuals : {(1,), (K,), (0,)} ndarray + Sums of squared residuals: Squared Euclidean 2-norm for each column in + ``b - a @ x``. + If the rank of `a` is < N or M <= N, this is an empty array. + If `b` is 1-dimensional, this is a (1,) shape array. + Otherwise the shape is (K,). + rank : int + Rank of matrix `a`. + s : (min(M, N),) ndarray + Singular values of `a`. + + Raises + ------ + LinAlgError + If computation does not converge. + + See Also + -------- + scipy.linalg.lstsq : Similar function in SciPy. + + Notes + ----- + If `b` is a matrix, then all array results are returned as matrices. + + Examples + -------- + Fit a line, ``y = mx + c``, through some noisy data-points: + + >>> x = np.array([0, 1, 2, 3]) + >>> y = np.array([-1, 0.2, 0.9, 2.1]) + + By examining the coefficients, we see that the line should have a + gradient of roughly 1 and cut the y-axis at, more or less, -1. + + We can rewrite the line equation as ``y = Ap``, where ``A = [[x 1]]`` + and ``p = [[m], [c]]``. Now use `lstsq` to solve for `p`: + + >>> A = np.vstack([x, np.ones(len(x))]).T + >>> A + array([[ 0., 1.], + [ 1., 1.], + [ 2., 1.], + [ 3., 1.]]) + + >>> m, c = np.linalg.lstsq(A, y, rcond=None)[0] + >>> m, c + (1.0 -0.95) # may vary + + Plot the data along with the fitted line: + + >>> import matplotlib.pyplot as plt + >>> _ = plt.plot(x, y, 'o', label='Original data', markersize=10) + >>> _ = plt.plot(x, m*x + c, 'r', label='Fitted line') + >>> _ = plt.legend() + >>> plt.show() + + """ + a, _ = _makearray(a) + b, wrap = _makearray(b) + is_1d = b.ndim == 1 + if is_1d: + b = b[:, newaxis] + _assert_2d(a, b) + m, n = a.shape[-2:] + m2, n_rhs = b.shape[-2:] + if m != m2: + raise LinAlgError('Incompatible dimensions') + + t, result_t = _commonType(a, b) + # FIXME: real_t is unused + real_t = _linalgRealType(t) + result_real_t = _realType(result_t) + + # Determine default rcond value + if rcond == "warn": + # 2017-08-19, 1.14.0 + warnings.warn("`rcond` parameter will change to the default of " + "machine precision times ``max(M, N)`` where M and N " + "are the input matrix dimensions.\n" + "To use the future default and silence this warning " + "we advise to pass `rcond=None`, to keep using the old, " + "explicitly pass `rcond=-1`.", + FutureWarning, stacklevel=3) + rcond = -1 + if rcond is None: + rcond = finfo(t).eps * max(n, m) + + if m <= n: + gufunc = _umath_linalg.lstsq_m + else: + gufunc = _umath_linalg.lstsq_n + + signature = 'DDd->Ddid' if isComplexType(t) else 'ddd->ddid' + extobj = get_linalg_error_extobj(_raise_linalgerror_lstsq) + if n_rhs == 0: + # lapack can't handle n_rhs = 0 - so allocate the array one larger in that axis + b = zeros(b.shape[:-2] + (m, n_rhs + 1), dtype=b.dtype) + x, resids, rank, s = gufunc(a, b, rcond, signature=signature, extobj=extobj) + if m == 0: + x[...] = 0 + if n_rhs == 0: + # remove the item we added + x = x[..., :n_rhs] + resids = resids[..., :n_rhs] + + # remove the axis we added + if is_1d: + x = x.squeeze(axis=-1) + # we probably should squeeze resids too, but we can't + # without breaking compatibility. + + # as documented + if rank != n or m <= n: + resids = array([], result_real_t) + + # coerce output arrays + s = s.astype(result_real_t, copy=False) + resids = resids.astype(result_real_t, copy=False) + x = x.astype(result_t, copy=True) # Copying lets the memory in r_parts be freed + return wrap(x), wrap(resids), rank, s + + +def _multi_svd_norm(x, row_axis, col_axis, op): + """Compute a function of the singular values of the 2-D matrices in `x`. + + This is a private utility function used by `numpy.linalg.norm()`. + + Parameters + ---------- + x : ndarray + row_axis, col_axis : int + The axes of `x` that hold the 2-D matrices. + op : callable + This should be either numpy.amin or `numpy.amax` or `numpy.sum`. + + Returns + ------- + result : float or ndarray + If `x` is 2-D, the return values is a float. + Otherwise, it is an array with ``x.ndim - 2`` dimensions. + The return values are either the minimum or maximum or sum of the + singular values of the matrices, depending on whether `op` + is `numpy.amin` or `numpy.amax` or `numpy.sum`. + + """ + y = moveaxis(x, (row_axis, col_axis), (-2, -1)) + result = op(svd(y, compute_uv=False), axis=-1) + return result + + +def _norm_dispatcher(x, ord=None, axis=None, keepdims=None): + return (x,) + + +@array_function_dispatch(_norm_dispatcher) +def norm(x, ord=None, axis=None, keepdims=False): + """ + Matrix or vector norm. + + This function is able to return one of eight different matrix norms, + or one of an infinite number of vector norms (described below), depending + on the value of the ``ord`` parameter. + + Parameters + ---------- + x : array_like + Input array. If `axis` is None, `x` must be 1-D or 2-D, unless `ord` + is None. If both `axis` and `ord` are None, the 2-norm of + ``x.ravel`` will be returned. + ord : {non-zero int, inf, -inf, 'fro', 'nuc'}, optional + Order of the norm (see table under ``Notes``). inf means numpy's + `inf` object. The default is None. + axis : {None, int, 2-tuple of ints}, optional. + If `axis` is an integer, it specifies the axis of `x` along which to + compute the vector norms. If `axis` is a 2-tuple, it specifies the + axes that hold 2-D matrices, and the matrix norms of these matrices + are computed. If `axis` is None then either a vector norm (when `x` + is 1-D) or a matrix norm (when `x` is 2-D) is returned. The default + is None. + + .. versionadded:: 1.8.0 + + keepdims : bool, optional + If this is set to True, the axes which are normed over are left in the + result as dimensions with size one. With this option the result will + broadcast correctly against the original `x`. + + .. versionadded:: 1.10.0 + + Returns + ------- + n : float or ndarray + Norm of the matrix or vector(s). + + See Also + -------- + scipy.linalg.norm : Similar function in SciPy. + + Notes + ----- + For values of ``ord < 1``, the result is, strictly speaking, not a + mathematical 'norm', but it may still be useful for various numerical + purposes. + + The following norms can be calculated: + + ===== ============================ ========================== + ord norm for matrices norm for vectors + ===== ============================ ========================== + None Frobenius norm 2-norm + 'fro' Frobenius norm -- + 'nuc' nuclear norm -- + inf max(sum(abs(x), axis=1)) max(abs(x)) + -inf min(sum(abs(x), axis=1)) min(abs(x)) + 0 -- sum(x != 0) + 1 max(sum(abs(x), axis=0)) as below + -1 min(sum(abs(x), axis=0)) as below + 2 2-norm (largest sing. value) as below + -2 smallest singular value as below + other -- sum(abs(x)**ord)**(1./ord) + ===== ============================ ========================== + + The Frobenius norm is given by [1]_: + + :math:`||A||_F = [\\sum_{i,j} abs(a_{i,j})^2]^{1/2}` + + The nuclear norm is the sum of the singular values. + + Both the Frobenius and nuclear norm orders are only defined for + matrices and raise a ValueError when ``x.ndim != 2``. + + References + ---------- + .. [1] G. H. Golub and C. F. Van Loan, *Matrix Computations*, + Baltimore, MD, Johns Hopkins University Press, 1985, pg. 15 + + Examples + -------- + >>> from numpy import linalg as LA + >>> a = np.arange(9) - 4 + >>> a + array([-4, -3, -2, ..., 2, 3, 4]) + >>> b = a.reshape((3, 3)) + >>> b + array([[-4, -3, -2], + [-1, 0, 1], + [ 2, 3, 4]]) + + >>> LA.norm(a) + 7.745966692414834 + >>> LA.norm(b) + 7.745966692414834 + >>> LA.norm(b, 'fro') + 7.745966692414834 + >>> LA.norm(a, np.inf) + 4.0 + >>> LA.norm(b, np.inf) + 9.0 + >>> LA.norm(a, -np.inf) + 0.0 + >>> LA.norm(b, -np.inf) + 2.0 + + >>> LA.norm(a, 1) + 20.0 + >>> LA.norm(b, 1) + 7.0 + >>> LA.norm(a, -1) + -4.6566128774142013e-010 + >>> LA.norm(b, -1) + 6.0 + >>> LA.norm(a, 2) + 7.745966692414834 + >>> LA.norm(b, 2) + 7.3484692283495345 + + >>> LA.norm(a, -2) + 0.0 + >>> LA.norm(b, -2) + 1.8570331885190563e-016 # may vary + >>> LA.norm(a, 3) + 5.8480354764257312 # may vary + >>> LA.norm(a, -3) + 0.0 + + Using the `axis` argument to compute vector norms: + + >>> c = np.array([[ 1, 2, 3], + ... [-1, 1, 4]]) + >>> LA.norm(c, axis=0) + array([ 1.41421356, 2.23606798, 5. ]) + >>> LA.norm(c, axis=1) + array([ 3.74165739, 4.24264069]) + >>> LA.norm(c, ord=1, axis=1) + array([ 6., 6.]) + + Using the `axis` argument to compute matrix norms: + + >>> m = np.arange(8).reshape(2,2,2) + >>> LA.norm(m, axis=(1,2)) + array([ 3.74165739, 11.22497216]) + >>> LA.norm(m[0, :, :]), LA.norm(m[1, :, :]) + (3.7416573867739413, 11.224972160321824) + + """ + x = asarray(x) + + if not issubclass(x.dtype.type, (inexact, object_)): + x = x.astype(float) + + # Immediately handle some default, simple, fast, and common cases. + if axis is None: + ndim = x.ndim + if ((ord is None) or + (ord in ('f', 'fro') and ndim == 2) or + (ord == 2 and ndim == 1)): + + x = x.ravel(order='K') + if isComplexType(x.dtype.type): + sqnorm = dot(x.real, x.real) + dot(x.imag, x.imag) + else: + sqnorm = dot(x, x) + ret = sqrt(sqnorm) + if keepdims: + ret = ret.reshape(ndim*[1]) + return ret + + # Normalize the `axis` argument to a tuple. + nd = x.ndim + if axis is None: + axis = tuple(range(nd)) + elif not isinstance(axis, tuple): + try: + axis = int(axis) + except Exception as e: + raise TypeError("'axis' must be None, an integer or a tuple of integers") from e + axis = (axis,) + + if len(axis) == 1: + if ord == Inf: + return abs(x).max(axis=axis, keepdims=keepdims) + elif ord == -Inf: + return abs(x).min(axis=axis, keepdims=keepdims) + elif ord == 0: + # Zero norm + return (x != 0).astype(x.real.dtype).sum(axis=axis, keepdims=keepdims) + elif ord == 1: + # special case for speedup + return add.reduce(abs(x), axis=axis, keepdims=keepdims) + elif ord is None or ord == 2: + # special case for speedup + s = (x.conj() * x).real + return sqrt(add.reduce(s, axis=axis, keepdims=keepdims)) + # None of the str-type keywords for ord ('fro', 'nuc') + # are valid for vectors + elif isinstance(ord, str): + raise ValueError(f"Invalid norm order '{ord}' for vectors") + else: + absx = abs(x) + absx **= ord + ret = add.reduce(absx, axis=axis, keepdims=keepdims) + ret **= (1 / ord) + return ret + elif len(axis) == 2: + row_axis, col_axis = axis + row_axis = normalize_axis_index(row_axis, nd) + col_axis = normalize_axis_index(col_axis, nd) + if row_axis == col_axis: + raise ValueError('Duplicate axes given.') + if ord == 2: + ret = _multi_svd_norm(x, row_axis, col_axis, amax) + elif ord == -2: + ret = _multi_svd_norm(x, row_axis, col_axis, amin) + elif ord == 1: + if col_axis > row_axis: + col_axis -= 1 + ret = add.reduce(abs(x), axis=row_axis).max(axis=col_axis) + elif ord == Inf: + if row_axis > col_axis: + row_axis -= 1 + ret = add.reduce(abs(x), axis=col_axis).max(axis=row_axis) + elif ord == -1: + if col_axis > row_axis: + col_axis -= 1 + ret = add.reduce(abs(x), axis=row_axis).min(axis=col_axis) + elif ord == -Inf: + if row_axis > col_axis: + row_axis -= 1 + ret = add.reduce(abs(x), axis=col_axis).min(axis=row_axis) + elif ord in [None, 'fro', 'f']: + ret = sqrt(add.reduce((x.conj() * x).real, axis=axis)) + elif ord == 'nuc': + ret = _multi_svd_norm(x, row_axis, col_axis, sum) + else: + raise ValueError("Invalid norm order for matrices.") + if keepdims: + ret_shape = list(x.shape) + ret_shape[axis[0]] = 1 + ret_shape[axis[1]] = 1 + ret = ret.reshape(ret_shape) + return ret + else: + raise ValueError("Improper number of dimensions to norm.") + + +# multi_dot + +def _multidot_dispatcher(arrays, *, out=None): + yield from arrays + yield out + + +@array_function_dispatch(_multidot_dispatcher) +def multi_dot(arrays, *, out=None): + """ + Compute the dot product of two or more arrays in a single function call, + while automatically selecting the fastest evaluation order. + + `multi_dot` chains `numpy.dot` and uses optimal parenthesization + of the matrices [1]_ [2]_. Depending on the shapes of the matrices, + this can speed up the multiplication a lot. + + If the first argument is 1-D it is treated as a row vector. + If the last argument is 1-D it is treated as a column vector. + The other arguments must be 2-D. + + Think of `multi_dot` as:: + + def multi_dot(arrays): return functools.reduce(np.dot, arrays) + + + Parameters + ---------- + arrays : sequence of array_like + If the first argument is 1-D it is treated as row vector. + If the last argument is 1-D it is treated as column vector. + The other arguments must be 2-D. + out : ndarray, optional + Output argument. This must have the exact kind that would be returned + if it was not used. In particular, it must have the right type, must be + C-contiguous, and its dtype must be the dtype that would be returned + for `dot(a, b)`. This is a performance feature. Therefore, if these + conditions are not met, an exception is raised, instead of attempting + to be flexible. + + .. versionadded:: 1.19.0 + + Returns + ------- + output : ndarray + Returns the dot product of the supplied arrays. + + See Also + -------- + numpy.dot : dot multiplication with two arguments. + + References + ---------- + + .. [1] Cormen, "Introduction to Algorithms", Chapter 15.2, p. 370-378 + .. [2] https://en.wikipedia.org/wiki/Matrix_chain_multiplication + + Examples + -------- + `multi_dot` allows you to write:: + + >>> from numpy.linalg import multi_dot + >>> # Prepare some data + >>> A = np.random.random((10000, 100)) + >>> B = np.random.random((100, 1000)) + >>> C = np.random.random((1000, 5)) + >>> D = np.random.random((5, 333)) + >>> # the actual dot multiplication + >>> _ = multi_dot([A, B, C, D]) + + instead of:: + + >>> _ = np.dot(np.dot(np.dot(A, B), C), D) + >>> # or + >>> _ = A.dot(B).dot(C).dot(D) + + Notes + ----- + The cost for a matrix multiplication can be calculated with the + following function:: + + def cost(A, B): + return A.shape[0] * A.shape[1] * B.shape[1] + + Assume we have three matrices + :math:`A_{10x100}, B_{100x5}, C_{5x50}`. + + The costs for the two different parenthesizations are as follows:: + + cost((AB)C) = 10*100*5 + 10*5*50 = 5000 + 2500 = 7500 + cost(A(BC)) = 10*100*50 + 100*5*50 = 50000 + 25000 = 75000 + + """ + n = len(arrays) + # optimization only makes sense for len(arrays) > 2 + if n < 2: + raise ValueError("Expecting at least two arrays.") + elif n == 2: + return dot(arrays[0], arrays[1], out=out) + + arrays = [asanyarray(a) for a in arrays] + + # save original ndim to reshape the result array into the proper form later + ndim_first, ndim_last = arrays[0].ndim, arrays[-1].ndim + # Explicitly convert vectors to 2D arrays to keep the logic of the internal + # _multi_dot_* functions as simple as possible. + if arrays[0].ndim == 1: + arrays[0] = atleast_2d(arrays[0]) + if arrays[-1].ndim == 1: + arrays[-1] = atleast_2d(arrays[-1]).T + _assert_2d(*arrays) + + # _multi_dot_three is much faster than _multi_dot_matrix_chain_order + if n == 3: + result = _multi_dot_three(arrays[0], arrays[1], arrays[2], out=out) + else: + order = _multi_dot_matrix_chain_order(arrays) + result = _multi_dot(arrays, order, 0, n - 1, out=out) + + # return proper shape + if ndim_first == 1 and ndim_last == 1: + return result[0, 0] # scalar + elif ndim_first == 1 or ndim_last == 1: + return result.ravel() # 1-D + else: + return result + + +def _multi_dot_three(A, B, C, out=None): + """ + Find the best order for three arrays and do the multiplication. + + For three arguments `_multi_dot_three` is approximately 15 times faster + than `_multi_dot_matrix_chain_order` + + """ + a0, a1b0 = A.shape + b1c0, c1 = C.shape + # cost1 = cost((AB)C) = a0*a1b0*b1c0 + a0*b1c0*c1 + cost1 = a0 * b1c0 * (a1b0 + c1) + # cost2 = cost(A(BC)) = a1b0*b1c0*c1 + a0*a1b0*c1 + cost2 = a1b0 * c1 * (a0 + b1c0) + + if cost1 < cost2: + return dot(dot(A, B), C, out=out) + else: + return dot(A, dot(B, C), out=out) + + +def _multi_dot_matrix_chain_order(arrays, return_costs=False): + """ + Return a np.array that encodes the optimal order of mutiplications. + + The optimal order array is then used by `_multi_dot()` to do the + multiplication. + + Also return the cost matrix if `return_costs` is `True` + + The implementation CLOSELY follows Cormen, "Introduction to Algorithms", + Chapter 15.2, p. 370-378. Note that Cormen uses 1-based indices. + + cost[i, j] = min([ + cost[prefix] + cost[suffix] + cost_mult(prefix, suffix) + for k in range(i, j)]) + + """ + n = len(arrays) + # p stores the dimensions of the matrices + # Example for p: A_{10x100}, B_{100x5}, C_{5x50} --> p = [10, 100, 5, 50] + p = [a.shape[0] for a in arrays] + [arrays[-1].shape[1]] + # m is a matrix of costs of the subproblems + # m[i,j]: min number of scalar multiplications needed to compute A_{i..j} + m = zeros((n, n), dtype=double) + # s is the actual ordering + # s[i, j] is the value of k at which we split the product A_i..A_j + s = empty((n, n), dtype=intp) + + for l in range(1, n): + for i in range(n - l): + j = i + l + m[i, j] = Inf + for k in range(i, j): + q = m[i, k] + m[k+1, j] + p[i]*p[k+1]*p[j+1] + if q < m[i, j]: + m[i, j] = q + s[i, j] = k # Note that Cormen uses 1-based index + + return (s, m) if return_costs else s + + +def _multi_dot(arrays, order, i, j, out=None): + """Actually do the multiplication with the given order.""" + if i == j: + # the initial call with non-None out should never get here + assert out is None + + return arrays[i] + else: + return dot(_multi_dot(arrays, order, i, order[i, j]), + _multi_dot(arrays, order, order[i, j] + 1, j), + out=out) diff --git a/venv/Lib/site-packages/numpy/linalg/setup.py b/venv/Lib/site-packages/numpy/linalg/setup.py new file mode 100644 index 0000000..5c9f2a4 --- /dev/null +++ b/venv/Lib/site-packages/numpy/linalg/setup.py @@ -0,0 +1,88 @@ +import os +import sys + +def configuration(parent_package='', top_path=None): + from numpy.distutils.misc_util import Configuration + from numpy.distutils.system_info import ( + get_info, system_info, lapack_opt_info, blas_opt_info) + config = Configuration('linalg', parent_package, top_path) + + config.add_subpackage('tests') + + # Accelerate is buggy, disallow it. See also numpy/core/setup.py + for opt_order in (blas_opt_info.blas_order, lapack_opt_info.lapack_order): + if 'accelerate' in opt_order: + opt_order.remove('accelerate') + + # Configure lapack_lite + + src_dir = 'lapack_lite' + lapack_lite_src = [ + os.path.join(src_dir, 'python_xerbla.c'), + os.path.join(src_dir, 'f2c_z_lapack.c'), + os.path.join(src_dir, 'f2c_c_lapack.c'), + os.path.join(src_dir, 'f2c_d_lapack.c'), + os.path.join(src_dir, 'f2c_s_lapack.c'), + os.path.join(src_dir, 'f2c_lapack.c'), + os.path.join(src_dir, 'f2c_blas.c'), + os.path.join(src_dir, 'f2c_config.c'), + os.path.join(src_dir, 'f2c.c'), + ] + all_sources = config.paths(lapack_lite_src) + + if os.environ.get('NPY_USE_BLAS_ILP64', "0") != "0": + lapack_info = get_info('lapack_ilp64_opt', 2) + else: + lapack_info = get_info('lapack_opt', 0) # and {} + + use_lapack_lite = not lapack_info + + if use_lapack_lite: + # This makes numpy.distutils write the fact that lapack_lite + # is being used to numpy.__config__ + class numpy_linalg_lapack_lite(system_info): + def calc_info(self): + info = {'language': 'c'} + if sys.maxsize > 2**32: + # Build lapack-lite in 64-bit integer mode. + # The suffix is arbitrary (lapack_lite symbols follow it), + # but use the "64_" convention here. + info['define_macros'] = [ + ('HAVE_BLAS_ILP64', None), + ('BLAS_SYMBOL_SUFFIX', '64_') + ] + self.set_info(**info) + + lapack_info = numpy_linalg_lapack_lite().get_info(2) + + def get_lapack_lite_sources(ext, build_dir): + if use_lapack_lite: + print("### Warning: Using unoptimized lapack ###") + return all_sources + else: + if sys.platform == 'win32': + print("### Warning: python_xerbla.c is disabled ###") + return [] + return [all_sources[0]] + + config.add_extension( + 'lapack_lite', + sources=['lapack_litemodule.c', get_lapack_lite_sources], + depends=['lapack_lite/f2c.h'], + extra_info=lapack_info, + ) + + # umath_linalg module + config.add_extension( + '_umath_linalg', + sources=['umath_linalg.c.src', get_lapack_lite_sources], + depends=['lapack_lite/f2c.h'], + extra_info=lapack_info, + libraries=['npymath'], + ) + config.add_data_files('*.pyi') + return config + +if __name__ == '__main__': + from numpy.distutils.core import setup + setup(configuration=configuration) diff --git a/venv/Lib/site-packages/numpy/linalg/tests/__init__.py b/venv/Lib/site-packages/numpy/linalg/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/venv/Lib/site-packages/numpy/linalg/tests/test_build.py b/venv/Lib/site-packages/numpy/linalg/tests/test_build.py new file mode 100644 index 0000000..4859226 --- /dev/null +++ b/venv/Lib/site-packages/numpy/linalg/tests/test_build.py @@ -0,0 +1,53 @@ +from subprocess import PIPE, Popen +import sys +import re +import pytest + +from numpy.linalg import lapack_lite +from numpy.testing import assert_ + + +class FindDependenciesLdd: + + def __init__(self): + self.cmd = ['ldd'] + + try: + p = Popen(self.cmd, stdout=PIPE, stderr=PIPE) + stdout, stderr = p.communicate() + except OSError: + raise RuntimeError(f'command {self.cmd} cannot be run') + + def get_dependencies(self, lfile): + p = Popen(self.cmd + [lfile], stdout=PIPE, stderr=PIPE) + stdout, stderr = p.communicate() + if not (p.returncode == 0): + raise RuntimeError(f'failed dependencies check for {lfile}') + + return stdout + + def grep_dependencies(self, lfile, deps): + stdout = self.get_dependencies(lfile) + + rdeps = dict([(dep, re.compile(dep)) for dep in deps]) + founds = [] + for l in stdout.splitlines(): + for k, v in rdeps.items(): + if v.search(l): + founds.append(k) + + return founds + + +class TestF77Mismatch: + + @pytest.mark.skipif(not(sys.platform[:5] == 'linux'), + reason="no fortran compiler on non-Linux platform") + def test_lapack(self): + f = FindDependenciesLdd() + deps = f.grep_dependencies(lapack_lite.__file__, + [b'libg2c', b'libgfortran']) + assert_(len(deps) <= 1, + """Both g77 and gfortran runtimes linked in lapack_lite ! This is likely to +cause random crashes and wrong results. See numpy INSTALL.txt for more +information.""") diff --git a/venv/Lib/site-packages/numpy/linalg/tests/test_deprecations.py b/venv/Lib/site-packages/numpy/linalg/tests/test_deprecations.py new file mode 100644 index 0000000..cd4c108 --- /dev/null +++ b/venv/Lib/site-packages/numpy/linalg/tests/test_deprecations.py @@ -0,0 +1,20 @@ +"""Test deprecation and future warnings. + +""" +import numpy as np +from numpy.testing import assert_warns + + +def test_qr_mode_full_future_warning(): + """Check mode='full' FutureWarning. + + In numpy 1.8 the mode options 'full' and 'economic' in linalg.qr were + deprecated. The release date will probably be sometime in the summer + of 2013. + + """ + a = np.eye(2) + assert_warns(DeprecationWarning, np.linalg.qr, a, mode='full') + assert_warns(DeprecationWarning, np.linalg.qr, a, mode='f') + assert_warns(DeprecationWarning, np.linalg.qr, a, mode='economic') + assert_warns(DeprecationWarning, np.linalg.qr, a, mode='e') diff --git a/venv/Lib/site-packages/numpy/linalg/tests/test_linalg.py b/venv/Lib/site-packages/numpy/linalg/tests/test_linalg.py new file mode 100644 index 0000000..21fab58 --- /dev/null +++ b/venv/Lib/site-packages/numpy/linalg/tests/test_linalg.py @@ -0,0 +1,2089 @@ +""" Test functions for linalg module + +""" +import os +import sys +import itertools +import traceback +import textwrap +import subprocess +import pytest + +import numpy as np +from numpy import array, single, double, csingle, cdouble, dot, identity, matmul +from numpy import multiply, atleast_2d, inf, asarray +from numpy import linalg +from numpy.linalg import matrix_power, norm, matrix_rank, multi_dot, LinAlgError +from numpy.linalg.linalg import _multi_dot_matrix_chain_order +from numpy.testing import ( + assert_, assert_equal, assert_raises, assert_array_equal, + assert_almost_equal, assert_allclose, suppress_warnings, + assert_raises_regex, HAS_LAPACK64, + ) +from numpy.testing._private.utils import requires_memory + + +def consistent_subclass(out, in_): + # For ndarray subclass input, our output should have the same subclass + # (non-ndarray input gets converted to ndarray). + return type(out) is (type(in_) if isinstance(in_, np.ndarray) + else np.ndarray) + + +old_assert_almost_equal = assert_almost_equal + + +def assert_almost_equal(a, b, single_decimal=6, double_decimal=12, **kw): + if asarray(a).dtype.type in (single, csingle): + decimal = single_decimal + else: + decimal = double_decimal + old_assert_almost_equal(a, b, decimal=decimal, **kw) + + +def get_real_dtype(dtype): + return {single: single, double: double, + csingle: single, cdouble: double}[dtype] + + +def get_complex_dtype(dtype): + return {single: csingle, double: cdouble, + csingle: csingle, cdouble: cdouble}[dtype] + + +def get_rtol(dtype): + # Choose a safe rtol + if dtype in (single, csingle): + return 1e-5 + else: + return 1e-11 + + +# used to categorize tests +all_tags = { + 'square', 'nonsquare', 'hermitian', # mutually exclusive + 'generalized', 'size-0', 'strided' # optional additions +} + + +class LinalgCase: + def __init__(self, name, a, b, tags=set()): + """ + A bundle of arguments to be passed to a test case, with an identifying + name, the operands a and b, and a set of tags to filter the tests + """ + assert_(isinstance(name, str)) + self.name = name + self.a = a + self.b = b + self.tags = frozenset(tags) # prevent shared tags + + def check(self, do): + """ + Run the function `do` on this test case, expanding arguments + """ + do(self.a, self.b, tags=self.tags) + + def __repr__(self): + return f'' + + +def apply_tag(tag, cases): + """ + Add the given tag (a string) to each of the cases (a list of LinalgCase + objects) + """ + assert tag in all_tags, "Invalid tag" + for case in cases: + case.tags = case.tags | {tag} + return cases + + +# +# Base test cases +# + +np.random.seed(1234) + +CASES = [] + +# square test cases +CASES += apply_tag('square', [ + LinalgCase("single", + array([[1., 2.], [3., 4.]], dtype=single), + array([2., 1.], dtype=single)), + LinalgCase("double", + array([[1., 2.], [3., 4.]], dtype=double), + array([2., 1.], dtype=double)), + LinalgCase("double_2", + array([[1., 2.], [3., 4.]], dtype=double), + array([[2., 1., 4.], [3., 4., 6.]], dtype=double)), + LinalgCase("csingle", + array([[1. + 2j, 2 + 3j], [3 + 4j, 4 + 5j]], dtype=csingle), + array([2. + 1j, 1. + 2j], dtype=csingle)), + LinalgCase("cdouble", + array([[1. + 2j, 2 + 3j], [3 + 4j, 4 + 5j]], dtype=cdouble), + array([2. + 1j, 1. + 2j], dtype=cdouble)), + LinalgCase("cdouble_2", + array([[1. + 2j, 2 + 3j], [3 + 4j, 4 + 5j]], dtype=cdouble), + array([[2. + 1j, 1. + 2j, 1 + 3j], [1 - 2j, 1 - 3j, 1 - 6j]], dtype=cdouble)), + LinalgCase("0x0", + np.empty((0, 0), dtype=double), + np.empty((0,), dtype=double), + tags={'size-0'}), + LinalgCase("8x8", + np.random.rand(8, 8), + np.random.rand(8)), + LinalgCase("1x1", + np.random.rand(1, 1), + np.random.rand(1)), + LinalgCase("nonarray", + [[1, 2], [3, 4]], + [2, 1]), +]) + +# non-square test-cases +CASES += apply_tag('nonsquare', [ + LinalgCase("single_nsq_1", + array([[1., 2., 3.], [3., 4., 6.]], dtype=single), + array([2., 1.], dtype=single)), + LinalgCase("single_nsq_2", + array([[1., 2.], [3., 4.], [5., 6.]], dtype=single), + array([2., 1., 3.], dtype=single)), + LinalgCase("double_nsq_1", + array([[1., 2., 3.], [3., 4., 6.]], dtype=double), + array([2., 1.], dtype=double)), + LinalgCase("double_nsq_2", + array([[1., 2.], [3., 4.], [5., 6.]], dtype=double), + array([2., 1., 3.], dtype=double)), + LinalgCase("csingle_nsq_1", + array( + [[1. + 1j, 2. + 2j, 3. - 3j], [3. - 5j, 4. + 9j, 6. + 2j]], dtype=csingle), + array([2. + 1j, 1. + 2j], dtype=csingle)), + LinalgCase("csingle_nsq_2", + array( + [[1. + 1j, 2. + 2j], [3. - 3j, 4. - 9j], [5. - 4j, 6. + 8j]], dtype=csingle), + array([2. + 1j, 1. + 2j, 3. - 3j], dtype=csingle)), + LinalgCase("cdouble_nsq_1", + array( + [[1. + 1j, 2. + 2j, 3. - 3j], [3. - 5j, 4. + 9j, 6. + 2j]], dtype=cdouble), + array([2. + 1j, 1. + 2j], dtype=cdouble)), + LinalgCase("cdouble_nsq_2", + array( + [[1. + 1j, 2. + 2j], [3. - 3j, 4. - 9j], [5. - 4j, 6. + 8j]], dtype=cdouble), + array([2. + 1j, 1. + 2j, 3. - 3j], dtype=cdouble)), + LinalgCase("cdouble_nsq_1_2", + array( + [[1. + 1j, 2. + 2j, 3. - 3j], [3. - 5j, 4. + 9j, 6. + 2j]], dtype=cdouble), + array([[2. + 1j, 1. + 2j], [1 - 1j, 2 - 2j]], dtype=cdouble)), + LinalgCase("cdouble_nsq_2_2", + array( + [[1. + 1j, 2. + 2j], [3. - 3j, 4. - 9j], [5. - 4j, 6. + 8j]], dtype=cdouble), + array([[2. + 1j, 1. + 2j], [1 - 1j, 2 - 2j], [1 - 1j, 2 - 2j]], dtype=cdouble)), + LinalgCase("8x11", + np.random.rand(8, 11), + np.random.rand(8)), + LinalgCase("1x5", + np.random.rand(1, 5), + np.random.rand(1)), + LinalgCase("5x1", + np.random.rand(5, 1), + np.random.rand(5)), + LinalgCase("0x4", + np.random.rand(0, 4), + np.random.rand(0), + tags={'size-0'}), + LinalgCase("4x0", + np.random.rand(4, 0), + np.random.rand(4), + tags={'size-0'}), +]) + +# hermitian test-cases +CASES += apply_tag('hermitian', [ + LinalgCase("hsingle", + array([[1., 2.], [2., 1.]], dtype=single), + None), + LinalgCase("hdouble", + array([[1., 2.], [2., 1.]], dtype=double), + None), + LinalgCase("hcsingle", + array([[1., 2 + 3j], [2 - 3j, 1]], dtype=csingle), + None), + LinalgCase("hcdouble", + array([[1., 2 + 3j], [2 - 3j, 1]], dtype=cdouble), + None), + LinalgCase("hempty", + np.empty((0, 0), dtype=double), + None, + tags={'size-0'}), + LinalgCase("hnonarray", + [[1, 2], [2, 1]], + None), + LinalgCase("matrix_b_only", + array([[1., 2.], [2., 1.]]), + None), + LinalgCase("hmatrix_1x1", + np.random.rand(1, 1), + None), +]) + + +# +# Gufunc test cases +# +def _make_generalized_cases(): + new_cases = [] + + for case in CASES: + if not isinstance(case.a, np.ndarray): + continue + + a = np.array([case.a, 2 * case.a, 3 * case.a]) + if case.b is None: + b = None + else: + b = np.array([case.b, 7 * case.b, 6 * case.b]) + new_case = LinalgCase(case.name + "_tile3", a, b, + tags=case.tags | {'generalized'}) + new_cases.append(new_case) + + a = np.array([case.a] * 2 * 3).reshape((3, 2) + case.a.shape) + if case.b is None: + b = None + else: + b = np.array([case.b] * 2 * 3).reshape((3, 2) + case.b.shape) + new_case = LinalgCase(case.name + "_tile213", a, b, + tags=case.tags | {'generalized'}) + new_cases.append(new_case) + + return new_cases + + +CASES += _make_generalized_cases() + + +# +# Generate stride combination variations of the above +# +def _stride_comb_iter(x): + """ + Generate cartesian product of strides for all axes + """ + + if not isinstance(x, np.ndarray): + yield x, "nop" + return + + stride_set = [(1,)] * x.ndim + stride_set[-1] = (1, 3, -4) + if x.ndim > 1: + stride_set[-2] = (1, 3, -4) + if x.ndim > 2: + stride_set[-3] = (1, -4) + + for repeats in itertools.product(*tuple(stride_set)): + new_shape = [abs(a * b) for a, b in zip(x.shape, repeats)] + slices = tuple([slice(None, None, repeat) for repeat in repeats]) + + # new array with different strides, but same data + xi = np.empty(new_shape, dtype=x.dtype) + xi.view(np.uint32).fill(0xdeadbeef) + xi = xi[slices] + xi[...] = x + xi = xi.view(x.__class__) + assert_(np.all(xi == x)) + yield xi, "stride_" + "_".join(["%+d" % j for j in repeats]) + + # generate also zero strides if possible + if x.ndim >= 1 and x.shape[-1] == 1: + s = list(x.strides) + s[-1] = 0 + xi = np.lib.stride_tricks.as_strided(x, strides=s) + yield xi, "stride_xxx_0" + if x.ndim >= 2 and x.shape[-2] == 1: + s = list(x.strides) + s[-2] = 0 + xi = np.lib.stride_tricks.as_strided(x, strides=s) + yield xi, "stride_xxx_0_x" + if x.ndim >= 2 and x.shape[:-2] == (1, 1): + s = list(x.strides) + s[-1] = 0 + s[-2] = 0 + xi = np.lib.stride_tricks.as_strided(x, strides=s) + yield xi, "stride_xxx_0_0" + + +def _make_strided_cases(): + new_cases = [] + for case in CASES: + for a, a_label in _stride_comb_iter(case.a): + for b, b_label in _stride_comb_iter(case.b): + new_case = LinalgCase(case.name + "_" + a_label + "_" + b_label, a, b, + tags=case.tags | {'strided'}) + new_cases.append(new_case) + return new_cases + + +CASES += _make_strided_cases() + + +# +# Test different routines against the above cases +# +class LinalgTestCase: + TEST_CASES = CASES + + def check_cases(self, require=set(), exclude=set()): + """ + Run func on each of the cases with all of the tags in require, and none + of the tags in exclude + """ + for case in self.TEST_CASES: + # filter by require and exclude + if case.tags & require != require: + continue + if case.tags & exclude: + continue + + try: + case.check(self.do) + except Exception: + msg = f'In test case: {case!r}\n\n' + msg += traceback.format_exc() + raise AssertionError(msg) + + +class LinalgSquareTestCase(LinalgTestCase): + + def test_sq_cases(self): + self.check_cases(require={'square'}, + exclude={'generalized', 'size-0'}) + + def test_empty_sq_cases(self): + self.check_cases(require={'square', 'size-0'}, + exclude={'generalized'}) + + +class LinalgNonsquareTestCase(LinalgTestCase): + + def test_nonsq_cases(self): + self.check_cases(require={'nonsquare'}, + exclude={'generalized', 'size-0'}) + + def test_empty_nonsq_cases(self): + self.check_cases(require={'nonsquare', 'size-0'}, + exclude={'generalized'}) + + +class HermitianTestCase(LinalgTestCase): + + def test_herm_cases(self): + self.check_cases(require={'hermitian'}, + exclude={'generalized', 'size-0'}) + + def test_empty_herm_cases(self): + self.check_cases(require={'hermitian', 'size-0'}, + exclude={'generalized'}) + + +class LinalgGeneralizedSquareTestCase(LinalgTestCase): + + @pytest.mark.slow + def test_generalized_sq_cases(self): + self.check_cases(require={'generalized', 'square'}, + exclude={'size-0'}) + + @pytest.mark.slow + def test_generalized_empty_sq_cases(self): + self.check_cases(require={'generalized', 'square', 'size-0'}) + + +class LinalgGeneralizedNonsquareTestCase(LinalgTestCase): + + @pytest.mark.slow + def test_generalized_nonsq_cases(self): + self.check_cases(require={'generalized', 'nonsquare'}, + exclude={'size-0'}) + + @pytest.mark.slow + def test_generalized_empty_nonsq_cases(self): + self.check_cases(require={'generalized', 'nonsquare', 'size-0'}) + + +class HermitianGeneralizedTestCase(LinalgTestCase): + + @pytest.mark.slow + def test_generalized_herm_cases(self): + self.check_cases(require={'generalized', 'hermitian'}, + exclude={'size-0'}) + + @pytest.mark.slow + def test_generalized_empty_herm_cases(self): + self.check_cases(require={'generalized', 'hermitian', 'size-0'}, + exclude={'none'}) + + +def dot_generalized(a, b): + a = asarray(a) + if a.ndim >= 3: + if a.ndim == b.ndim: + # matrix x matrix + new_shape = a.shape[:-1] + b.shape[-1:] + elif a.ndim == b.ndim + 1: + # matrix x vector + new_shape = a.shape[:-1] + else: + raise ValueError("Not implemented...") + r = np.empty(new_shape, dtype=np.common_type(a, b)) + for c in itertools.product(*map(range, a.shape[:-2])): + r[c] = dot(a[c], b[c]) + return r + else: + return dot(a, b) + + +def identity_like_generalized(a): + a = asarray(a) + if a.ndim >= 3: + r = np.empty(a.shape, dtype=a.dtype) + r[...] = identity(a.shape[-2]) + return r + else: + return identity(a.shape[0]) + + +class SolveCases(LinalgSquareTestCase, LinalgGeneralizedSquareTestCase): + # kept apart from TestSolve for use for testing with matrices. + def do(self, a, b, tags): + x = linalg.solve(a, b) + assert_almost_equal(b, dot_generalized(a, x)) + assert_(consistent_subclass(x, b)) + + +class TestSolve(SolveCases): + @pytest.mark.parametrize('dtype', [single, double, csingle, cdouble]) + def test_types(self, dtype): + x = np.array([[1, 0.5], [0.5, 1]], dtype=dtype) + assert_equal(linalg.solve(x, x).dtype, dtype) + + def test_0_size(self): + class ArraySubclass(np.ndarray): + pass + # Test system of 0x0 matrices + a = np.arange(8).reshape(2, 2, 2) + b = np.arange(6).reshape(1, 2, 3).view(ArraySubclass) + + expected = linalg.solve(a, b)[:, 0:0, :] + result = linalg.solve(a[:, 0:0, 0:0], b[:, 0:0, :]) + assert_array_equal(result, expected) + assert_(isinstance(result, ArraySubclass)) + + # Test errors for non-square and only b's dimension being 0 + assert_raises(linalg.LinAlgError, linalg.solve, a[:, 0:0, 0:1], b) + assert_raises(ValueError, linalg.solve, a, b[:, 0:0, :]) + + # Test broadcasting error + b = np.arange(6).reshape(1, 3, 2) # broadcasting error + assert_raises(ValueError, linalg.solve, a, b) + assert_raises(ValueError, linalg.solve, a[0:0], b[0:0]) + + # Test zero "single equations" with 0x0 matrices. + b = np.arange(2).reshape(1, 2).view(ArraySubclass) + expected = linalg.solve(a, b)[:, 0:0] + result = linalg.solve(a[:, 0:0, 0:0], b[:, 0:0]) + assert_array_equal(result, expected) + assert_(isinstance(result, ArraySubclass)) + + b = np.arange(3).reshape(1, 3) + assert_raises(ValueError, linalg.solve, a, b) + assert_raises(ValueError, linalg.solve, a[0:0], b[0:0]) + assert_raises(ValueError, linalg.solve, a[:, 0:0, 0:0], b) + + def test_0_size_k(self): + # test zero multiple equation (K=0) case. + class ArraySubclass(np.ndarray): + pass + a = np.arange(4).reshape(1, 2, 2) + b = np.arange(6).reshape(3, 2, 1).view(ArraySubclass) + + expected = linalg.solve(a, b)[:, :, 0:0] + result = linalg.solve(a, b[:, :, 0:0]) + assert_array_equal(result, expected) + assert_(isinstance(result, ArraySubclass)) + + # test both zero. + expected = linalg.solve(a, b)[:, 0:0, 0:0] + result = linalg.solve(a[:, 0:0, 0:0], b[:, 0:0, 0:0]) + assert_array_equal(result, expected) + assert_(isinstance(result, ArraySubclass)) + + +class InvCases(LinalgSquareTestCase, LinalgGeneralizedSquareTestCase): + + def do(self, a, b, tags): + a_inv = linalg.inv(a) + assert_almost_equal(dot_generalized(a, a_inv), + identity_like_generalized(a)) + assert_(consistent_subclass(a_inv, a)) + + +class TestInv(InvCases): + @pytest.mark.parametrize('dtype', [single, double, csingle, cdouble]) + def test_types(self, dtype): + x = np.array([[1, 0.5], [0.5, 1]], dtype=dtype) + assert_equal(linalg.inv(x).dtype, dtype) + + def test_0_size(self): + # Check that all kinds of 0-sized arrays work + class ArraySubclass(np.ndarray): + pass + a = np.zeros((0, 1, 1), dtype=np.int_).view(ArraySubclass) + res = linalg.inv(a) + assert_(res.dtype.type is np.float64) + assert_equal(a.shape, res.shape) + assert_(isinstance(res, ArraySubclass)) + + a = np.zeros((0, 0), dtype=np.complex64).view(ArraySubclass) + res = linalg.inv(a) + assert_(res.dtype.type is np.complex64) + assert_equal(a.shape, res.shape) + assert_(isinstance(res, ArraySubclass)) + + +class EigvalsCases(LinalgSquareTestCase, LinalgGeneralizedSquareTestCase): + + def do(self, a, b, tags): + ev = linalg.eigvals(a) + evalues, evectors = linalg.eig(a) + assert_almost_equal(ev, evalues) + + +class TestEigvals(EigvalsCases): + @pytest.mark.parametrize('dtype', [single, double, csingle, cdouble]) + def test_types(self, dtype): + x = np.array([[1, 0.5], [0.5, 1]], dtype=dtype) + assert_equal(linalg.eigvals(x).dtype, dtype) + x = np.array([[1, 0.5], [-1, 1]], dtype=dtype) + assert_equal(linalg.eigvals(x).dtype, get_complex_dtype(dtype)) + + def test_0_size(self): + # Check that all kinds of 0-sized arrays work + class ArraySubclass(np.ndarray): + pass + a = np.zeros((0, 1, 1), dtype=np.int_).view(ArraySubclass) + res = linalg.eigvals(a) + assert_(res.dtype.type is np.float64) + assert_equal((0, 1), res.shape) + # This is just for documentation, it might make sense to change: + assert_(isinstance(res, np.ndarray)) + + a = np.zeros((0, 0), dtype=np.complex64).view(ArraySubclass) + res = linalg.eigvals(a) + assert_(res.dtype.type is np.complex64) + assert_equal((0,), res.shape) + # This is just for documentation, it might make sense to change: + assert_(isinstance(res, np.ndarray)) + + +class EigCases(LinalgSquareTestCase, LinalgGeneralizedSquareTestCase): + + def do(self, a, b, tags): + evalues, evectors = linalg.eig(a) + assert_allclose(dot_generalized(a, evectors), + np.asarray(evectors) * np.asarray(evalues)[..., None, :], + rtol=get_rtol(evalues.dtype)) + assert_(consistent_subclass(evectors, a)) + + +class TestEig(EigCases): + @pytest.mark.parametrize('dtype', [single, double, csingle, cdouble]) + def test_types(self, dtype): + x = np.array([[1, 0.5], [0.5, 1]], dtype=dtype) + w, v = np.linalg.eig(x) + assert_equal(w.dtype, dtype) + assert_equal(v.dtype, dtype) + + x = np.array([[1, 0.5], [-1, 1]], dtype=dtype) + w, v = np.linalg.eig(x) + assert_equal(w.dtype, get_complex_dtype(dtype)) + assert_equal(v.dtype, get_complex_dtype(dtype)) + + def test_0_size(self): + # Check that all kinds of 0-sized arrays work + class ArraySubclass(np.ndarray): + pass + a = np.zeros((0, 1, 1), dtype=np.int_).view(ArraySubclass) + res, res_v = linalg.eig(a) + assert_(res_v.dtype.type is np.float64) + assert_(res.dtype.type is np.float64) + assert_equal(a.shape, res_v.shape) + assert_equal((0, 1), res.shape) + # This is just for documentation, it might make sense to change: + assert_(isinstance(a, np.ndarray)) + + a = np.zeros((0, 0), dtype=np.complex64).view(ArraySubclass) + res, res_v = linalg.eig(a) + assert_(res_v.dtype.type is np.complex64) + assert_(res.dtype.type is np.complex64) + assert_equal(a.shape, res_v.shape) + assert_equal((0,), res.shape) + # This is just for documentation, it might make sense to change: + assert_(isinstance(a, np.ndarray)) + + +class SVDBaseTests: + hermitian = False + + @pytest.mark.parametrize('dtype', [single, double, csingle, cdouble]) + def test_types(self, dtype): + x = np.array([[1, 0.5], [0.5, 1]], dtype=dtype) + u, s, vh = linalg.svd(x) + assert_equal(u.dtype, dtype) + assert_equal(s.dtype, get_real_dtype(dtype)) + assert_equal(vh.dtype, dtype) + s = linalg.svd(x, compute_uv=False, hermitian=self.hermitian) + assert_equal(s.dtype, get_real_dtype(dtype)) + + +class SVDCases(LinalgSquareTestCase, LinalgGeneralizedSquareTestCase): + + def do(self, a, b, tags): + u, s, vt = linalg.svd(a, False) + assert_allclose(a, dot_generalized(np.asarray(u) * np.asarray(s)[..., None, :], + np.asarray(vt)), + rtol=get_rtol(u.dtype)) + assert_(consistent_subclass(u, a)) + assert_(consistent_subclass(vt, a)) + + +class TestSVD(SVDCases, SVDBaseTests): + def test_empty_identity(self): + """ Empty input should put an identity matrix in u or vh """ + x = np.empty((4, 0)) + u, s, vh = linalg.svd(x, compute_uv=True, hermitian=self.hermitian) + assert_equal(u.shape, (4, 4)) + assert_equal(vh.shape, (0, 0)) + assert_equal(u, np.eye(4)) + + x = np.empty((0, 4)) + u, s, vh = linalg.svd(x, compute_uv=True, hermitian=self.hermitian) + assert_equal(u.shape, (0, 0)) + assert_equal(vh.shape, (4, 4)) + assert_equal(vh, np.eye(4)) + + +class SVDHermitianCases(HermitianTestCase, HermitianGeneralizedTestCase): + + def do(self, a, b, tags): + u, s, vt = linalg.svd(a, False, hermitian=True) + assert_allclose(a, dot_generalized(np.asarray(u) * np.asarray(s)[..., None, :], + np.asarray(vt)), + rtol=get_rtol(u.dtype)) + def hermitian(mat): + axes = list(range(mat.ndim)) + axes[-1], axes[-2] = axes[-2], axes[-1] + return np.conj(np.transpose(mat, axes=axes)) + + assert_almost_equal(np.matmul(u, hermitian(u)), np.broadcast_to(np.eye(u.shape[-1]), u.shape)) + assert_almost_equal(np.matmul(vt, hermitian(vt)), np.broadcast_to(np.eye(vt.shape[-1]), vt.shape)) + assert_equal(np.sort(s)[..., ::-1], s) + assert_(consistent_subclass(u, a)) + assert_(consistent_subclass(vt, a)) + + +class TestSVDHermitian(SVDHermitianCases, SVDBaseTests): + hermitian = True + + +class CondCases(LinalgSquareTestCase, LinalgGeneralizedSquareTestCase): + # cond(x, p) for p in (None, 2, -2) + + def do(self, a, b, tags): + c = asarray(a) # a might be a matrix + if 'size-0' in tags: + assert_raises(LinAlgError, linalg.cond, c) + return + + # +-2 norms + s = linalg.svd(c, compute_uv=False) + assert_almost_equal( + linalg.cond(a), s[..., 0] / s[..., -1], + single_decimal=5, double_decimal=11) + assert_almost_equal( + linalg.cond(a, 2), s[..., 0] / s[..., -1], + single_decimal=5, double_decimal=11) + assert_almost_equal( + linalg.cond(a, -2), s[..., -1] / s[..., 0], + single_decimal=5, double_decimal=11) + + # Other norms + cinv = np.linalg.inv(c) + assert_almost_equal( + linalg.cond(a, 1), + abs(c).sum(-2).max(-1) * abs(cinv).sum(-2).max(-1), + single_decimal=5, double_decimal=11) + assert_almost_equal( + linalg.cond(a, -1), + abs(c).sum(-2).min(-1) * abs(cinv).sum(-2).min(-1), + single_decimal=5, double_decimal=11) + assert_almost_equal( + linalg.cond(a, np.inf), + abs(c).sum(-1).max(-1) * abs(cinv).sum(-1).max(-1), + single_decimal=5, double_decimal=11) + assert_almost_equal( + linalg.cond(a, -np.inf), + abs(c).sum(-1).min(-1) * abs(cinv).sum(-1).min(-1), + single_decimal=5, double_decimal=11) + assert_almost_equal( + linalg.cond(a, 'fro'), + np.sqrt((abs(c)**2).sum(-1).sum(-1) + * (abs(cinv)**2).sum(-1).sum(-1)), + single_decimal=5, double_decimal=11) + + +class TestCond(CondCases): + def test_basic_nonsvd(self): + # Smoketest the non-svd norms + A = array([[1., 0, 1], [0, -2., 0], [0, 0, 3.]]) + assert_almost_equal(linalg.cond(A, inf), 4) + assert_almost_equal(linalg.cond(A, -inf), 2/3) + assert_almost_equal(linalg.cond(A, 1), 4) + assert_almost_equal(linalg.cond(A, -1), 0.5) + assert_almost_equal(linalg.cond(A, 'fro'), np.sqrt(265 / 12)) + + def test_singular(self): + # Singular matrices have infinite condition number for + # positive norms, and negative norms shouldn't raise + # exceptions + As = [np.zeros((2, 2)), np.ones((2, 2))] + p_pos = [None, 1, 2, 'fro'] + p_neg = [-1, -2] + for A, p in itertools.product(As, p_pos): + # Inversion may not hit exact infinity, so just check the + # number is large + assert_(linalg.cond(A, p) > 1e15) + for A, p in itertools.product(As, p_neg): + linalg.cond(A, p) + + def test_nan(self): + # nans should be passed through, not converted to infs + ps = [None, 1, -1, 2, -2, 'fro'] + p_pos = [None, 1, 2, 'fro'] + + A = np.ones((2, 2)) + A[0,1] = np.nan + for p in ps: + c = linalg.cond(A, p) + assert_(isinstance(c, np.float_)) + assert_(np.isnan(c)) + + A = np.ones((3, 2, 2)) + A[1,0,1] = np.nan + for p in ps: + c = linalg.cond(A, p) + assert_(np.isnan(c[1])) + if p in p_pos: + assert_(c[0] > 1e15) + assert_(c[2] > 1e15) + else: + assert_(not np.isnan(c[0])) + assert_(not np.isnan(c[2])) + + def test_stacked_singular(self): + # Check behavior when only some of the stacked matrices are + # singular + np.random.seed(1234) + A = np.random.rand(2, 2, 2, 2) + A[0,0] = 0 + A[1,1] = 0 + + for p in (None, 1, 2, 'fro', -1, -2): + c = linalg.cond(A, p) + assert_equal(c[0,0], np.inf) + assert_equal(c[1,1], np.inf) + assert_(np.isfinite(c[0,1])) + assert_(np.isfinite(c[1,0])) + + +class PinvCases(LinalgSquareTestCase, + LinalgNonsquareTestCase, + LinalgGeneralizedSquareTestCase, + LinalgGeneralizedNonsquareTestCase): + + def do(self, a, b, tags): + a_ginv = linalg.pinv(a) + # `a @ a_ginv == I` does not hold if a is singular + dot = dot_generalized + assert_almost_equal(dot(dot(a, a_ginv), a), a, single_decimal=5, double_decimal=11) + assert_(consistent_subclass(a_ginv, a)) + + +class TestPinv(PinvCases): + pass + + +class PinvHermitianCases(HermitianTestCase, HermitianGeneralizedTestCase): + + def do(self, a, b, tags): + a_ginv = linalg.pinv(a, hermitian=True) + # `a @ a_ginv == I` does not hold if a is singular + dot = dot_generalized + assert_almost_equal(dot(dot(a, a_ginv), a), a, single_decimal=5, double_decimal=11) + assert_(consistent_subclass(a_ginv, a)) + + +class TestPinvHermitian(PinvHermitianCases): + pass + + +class DetCases(LinalgSquareTestCase, LinalgGeneralizedSquareTestCase): + + def do(self, a, b, tags): + d = linalg.det(a) + (s, ld) = linalg.slogdet(a) + if asarray(a).dtype.type in (single, double): + ad = asarray(a).astype(double) + else: + ad = asarray(a).astype(cdouble) + ev = linalg.eigvals(ad) + assert_almost_equal(d, multiply.reduce(ev, axis=-1)) + assert_almost_equal(s * np.exp(ld), multiply.reduce(ev, axis=-1)) + + s = np.atleast_1d(s) + ld = np.atleast_1d(ld) + m = (s != 0) + assert_almost_equal(np.abs(s[m]), 1) + assert_equal(ld[~m], -inf) + + +class TestDet(DetCases): + def test_zero(self): + assert_equal(linalg.det([[0.0]]), 0.0) + assert_equal(type(linalg.det([[0.0]])), double) + assert_equal(linalg.det([[0.0j]]), 0.0) + assert_equal(type(linalg.det([[0.0j]])), cdouble) + + assert_equal(linalg.slogdet([[0.0]]), (0.0, -inf)) + assert_equal(type(linalg.slogdet([[0.0]])[0]), double) + assert_equal(type(linalg.slogdet([[0.0]])[1]), double) + assert_equal(linalg.slogdet([[0.0j]]), (0.0j, -inf)) + assert_equal(type(linalg.slogdet([[0.0j]])[0]), cdouble) + assert_equal(type(linalg.slogdet([[0.0j]])[1]), double) + + @pytest.mark.parametrize('dtype', [single, double, csingle, cdouble]) + def test_types(self, dtype): + x = np.array([[1, 0.5], [0.5, 1]], dtype=dtype) + assert_equal(np.linalg.det(x).dtype, dtype) + ph, s = np.linalg.slogdet(x) + assert_equal(s.dtype, get_real_dtype(dtype)) + assert_equal(ph.dtype, dtype) + + def test_0_size(self): + a = np.zeros((0, 0), dtype=np.complex64) + res = linalg.det(a) + assert_equal(res, 1.) + assert_(res.dtype.type is np.complex64) + res = linalg.slogdet(a) + assert_equal(res, (1, 0)) + assert_(res[0].dtype.type is np.complex64) + assert_(res[1].dtype.type is np.float32) + + a = np.zeros((0, 0), dtype=np.float64) + res = linalg.det(a) + assert_equal(res, 1.) + assert_(res.dtype.type is np.float64) + res = linalg.slogdet(a) + assert_equal(res, (1, 0)) + assert_(res[0].dtype.type is np.float64) + assert_(res[1].dtype.type is np.float64) + + +class LstsqCases(LinalgSquareTestCase, LinalgNonsquareTestCase): + + def do(self, a, b, tags): + arr = np.asarray(a) + m, n = arr.shape + u, s, vt = linalg.svd(a, False) + x, residuals, rank, sv = linalg.lstsq(a, b, rcond=-1) + if m == 0: + assert_((x == 0).all()) + if m <= n: + assert_almost_equal(b, dot(a, x)) + assert_equal(rank, m) + else: + assert_equal(rank, n) + assert_almost_equal(sv, sv.__array_wrap__(s)) + if rank == n and m > n: + expect_resids = ( + np.asarray(abs(np.dot(a, x) - b)) ** 2).sum(axis=0) + expect_resids = np.asarray(expect_resids) + if np.asarray(b).ndim == 1: + expect_resids.shape = (1,) + assert_equal(residuals.shape, expect_resids.shape) + else: + expect_resids = np.array([]).view(type(x)) + assert_almost_equal(residuals, expect_resids) + assert_(np.issubdtype(residuals.dtype, np.floating)) + assert_(consistent_subclass(x, b)) + assert_(consistent_subclass(residuals, b)) + + +class TestLstsq(LstsqCases): + def test_future_rcond(self): + a = np.array([[0., 1., 0., 1., 2., 0.], + [0., 2., 0., 0., 1., 0.], + [1., 0., 1., 0., 0., 4.], + [0., 0., 0., 2., 3., 0.]]).T + + b = np.array([1, 0, 0, 0, 0, 0]) + with suppress_warnings() as sup: + w = sup.record(FutureWarning, "`rcond` parameter will change") + x, residuals, rank, s = linalg.lstsq(a, b) + assert_(rank == 4) + x, residuals, rank, s = linalg.lstsq(a, b, rcond=-1) + assert_(rank == 4) + x, residuals, rank, s = linalg.lstsq(a, b, rcond=None) + assert_(rank == 3) + # Warning should be raised exactly once (first command) + assert_(len(w) == 1) + + @pytest.mark.parametrize(["m", "n", "n_rhs"], [ + (4, 2, 2), + (0, 4, 1), + (0, 4, 2), + (4, 0, 1), + (4, 0, 2), + (4, 2, 0), + (0, 0, 0) + ]) + def test_empty_a_b(self, m, n, n_rhs): + a = np.arange(m * n).reshape(m, n) + b = np.ones((m, n_rhs)) + x, residuals, rank, s = linalg.lstsq(a, b, rcond=None) + if m == 0: + assert_((x == 0).all()) + assert_equal(x.shape, (n, n_rhs)) + assert_equal(residuals.shape, ((n_rhs,) if m > n else (0,))) + if m > n and n_rhs > 0: + # residuals are exactly the squared norms of b's columns + r = b - np.dot(a, x) + assert_almost_equal(residuals, (r * r).sum(axis=-2)) + assert_equal(rank, min(m, n)) + assert_equal(s.shape, (min(m, n),)) + + def test_incompatible_dims(self): + # use modified version of docstring example + x = np.array([0, 1, 2, 3]) + y = np.array([-1, 0.2, 0.9, 2.1, 3.3]) + A = np.vstack([x, np.ones(len(x))]).T + with assert_raises_regex(LinAlgError, "Incompatible dimensions"): + linalg.lstsq(A, y, rcond=None) + + +@pytest.mark.parametrize('dt', [np.dtype(c) for c in '?bBhHiIqQefdgFDGO']) +class TestMatrixPower: + + rshft_0 = np.eye(4) + rshft_1 = rshft_0[[3, 0, 1, 2]] + rshft_2 = rshft_0[[2, 3, 0, 1]] + rshft_3 = rshft_0[[1, 2, 3, 0]] + rshft_all = [rshft_0, rshft_1, rshft_2, rshft_3] + noninv = array([[1, 0], [0, 0]]) + stacked = np.block([[[rshft_0]]]*2) + #FIXME the 'e' dtype might work in future + dtnoinv = [object, np.dtype('e'), np.dtype('g'), np.dtype('G')] + + def test_large_power(self, dt): + rshft = self.rshft_1.astype(dt) + assert_equal( + matrix_power(rshft, 2**100 + 2**10 + 2**5 + 0), self.rshft_0) + assert_equal( + matrix_power(rshft, 2**100 + 2**10 + 2**5 + 1), self.rshft_1) + assert_equal( + matrix_power(rshft, 2**100 + 2**10 + 2**5 + 2), self.rshft_2) + assert_equal( + matrix_power(rshft, 2**100 + 2**10 + 2**5 + 3), self.rshft_3) + + def test_power_is_zero(self, dt): + def tz(M): + mz = matrix_power(M, 0) + assert_equal(mz, identity_like_generalized(M)) + assert_equal(mz.dtype, M.dtype) + + for mat in self.rshft_all: + tz(mat.astype(dt)) + if dt != object: + tz(self.stacked.astype(dt)) + + def test_power_is_one(self, dt): + def tz(mat): + mz = matrix_power(mat, 1) + assert_equal(mz, mat) + assert_equal(mz.dtype, mat.dtype) + + for mat in self.rshft_all: + tz(mat.astype(dt)) + if dt != object: + tz(self.stacked.astype(dt)) + + def test_power_is_two(self, dt): + def tz(mat): + mz = matrix_power(mat, 2) + mmul = matmul if mat.dtype != object else dot + assert_equal(mz, mmul(mat, mat)) + assert_equal(mz.dtype, mat.dtype) + + for mat in self.rshft_all: + tz(mat.astype(dt)) + if dt != object: + tz(self.stacked.astype(dt)) + + def test_power_is_minus_one(self, dt): + def tz(mat): + invmat = matrix_power(mat, -1) + mmul = matmul if mat.dtype != object else dot + assert_almost_equal( + mmul(invmat, mat), identity_like_generalized(mat)) + + for mat in self.rshft_all: + if dt not in self.dtnoinv: + tz(mat.astype(dt)) + + def test_exceptions_bad_power(self, dt): + mat = self.rshft_0.astype(dt) + assert_raises(TypeError, matrix_power, mat, 1.5) + assert_raises(TypeError, matrix_power, mat, [1]) + + def test_exceptions_non_square(self, dt): + assert_raises(LinAlgError, matrix_power, np.array([1], dt), 1) + assert_raises(LinAlgError, matrix_power, np.array([[1], [2]], dt), 1) + assert_raises(LinAlgError, matrix_power, np.ones((4, 3, 2), dt), 1) + + def test_exceptions_not_invertible(self, dt): + if dt in self.dtnoinv: + return + mat = self.noninv.astype(dt) + assert_raises(LinAlgError, matrix_power, mat, -1) + + + +class TestEigvalshCases(HermitianTestCase, HermitianGeneralizedTestCase): + + def do(self, a, b, tags): + # note that eigenvalue arrays returned by eig must be sorted since + # their order isn't guaranteed. + ev = linalg.eigvalsh(a, 'L') + evalues, evectors = linalg.eig(a) + evalues.sort(axis=-1) + assert_allclose(ev, evalues, rtol=get_rtol(ev.dtype)) + + ev2 = linalg.eigvalsh(a, 'U') + assert_allclose(ev2, evalues, rtol=get_rtol(ev.dtype)) + + +class TestEigvalsh: + @pytest.mark.parametrize('dtype', [single, double, csingle, cdouble]) + def test_types(self, dtype): + x = np.array([[1, 0.5], [0.5, 1]], dtype=dtype) + w = np.linalg.eigvalsh(x) + assert_equal(w.dtype, get_real_dtype(dtype)) + + def test_invalid(self): + x = np.array([[1, 0.5], [0.5, 1]], dtype=np.float32) + assert_raises(ValueError, np.linalg.eigvalsh, x, UPLO="lrong") + assert_raises(ValueError, np.linalg.eigvalsh, x, "lower") + assert_raises(ValueError, np.linalg.eigvalsh, x, "upper") + + def test_UPLO(self): + Klo = np.array([[0, 0], [1, 0]], dtype=np.double) + Kup = np.array([[0, 1], [0, 0]], dtype=np.double) + tgt = np.array([-1, 1], dtype=np.double) + rtol = get_rtol(np.double) + + # Check default is 'L' + w = np.linalg.eigvalsh(Klo) + assert_allclose(w, tgt, rtol=rtol) + # Check 'L' + w = np.linalg.eigvalsh(Klo, UPLO='L') + assert_allclose(w, tgt, rtol=rtol) + # Check 'l' + w = np.linalg.eigvalsh(Klo, UPLO='l') + assert_allclose(w, tgt, rtol=rtol) + # Check 'U' + w = np.linalg.eigvalsh(Kup, UPLO='U') + assert_allclose(w, tgt, rtol=rtol) + # Check 'u' + w = np.linalg.eigvalsh(Kup, UPLO='u') + assert_allclose(w, tgt, rtol=rtol) + + def test_0_size(self): + # Check that all kinds of 0-sized arrays work + class ArraySubclass(np.ndarray): + pass + a = np.zeros((0, 1, 1), dtype=np.int_).view(ArraySubclass) + res = linalg.eigvalsh(a) + assert_(res.dtype.type is np.float64) + assert_equal((0, 1), res.shape) + # This is just for documentation, it might make sense to change: + assert_(isinstance(res, np.ndarray)) + + a = np.zeros((0, 0), dtype=np.complex64).view(ArraySubclass) + res = linalg.eigvalsh(a) + assert_(res.dtype.type is np.float32) + assert_equal((0,), res.shape) + # This is just for documentation, it might make sense to change: + assert_(isinstance(res, np.ndarray)) + + +class TestEighCases(HermitianTestCase, HermitianGeneralizedTestCase): + + def do(self, a, b, tags): + # note that eigenvalue arrays returned by eig must be sorted since + # their order isn't guaranteed. + ev, evc = linalg.eigh(a) + evalues, evectors = linalg.eig(a) + evalues.sort(axis=-1) + assert_almost_equal(ev, evalues) + + assert_allclose(dot_generalized(a, evc), + np.asarray(ev)[..., None, :] * np.asarray(evc), + rtol=get_rtol(ev.dtype)) + + ev2, evc2 = linalg.eigh(a, 'U') + assert_almost_equal(ev2, evalues) + + assert_allclose(dot_generalized(a, evc2), + np.asarray(ev2)[..., None, :] * np.asarray(evc2), + rtol=get_rtol(ev.dtype), err_msg=repr(a)) + + +class TestEigh: + @pytest.mark.parametrize('dtype', [single, double, csingle, cdouble]) + def test_types(self, dtype): + x = np.array([[1, 0.5], [0.5, 1]], dtype=dtype) + w, v = np.linalg.eigh(x) + assert_equal(w.dtype, get_real_dtype(dtype)) + assert_equal(v.dtype, dtype) + + def test_invalid(self): + x = np.array([[1, 0.5], [0.5, 1]], dtype=np.float32) + assert_raises(ValueError, np.linalg.eigh, x, UPLO="lrong") + assert_raises(ValueError, np.linalg.eigh, x, "lower") + assert_raises(ValueError, np.linalg.eigh, x, "upper") + + def test_UPLO(self): + Klo = np.array([[0, 0], [1, 0]], dtype=np.double) + Kup = np.array([[0, 1], [0, 0]], dtype=np.double) + tgt = np.array([-1, 1], dtype=np.double) + rtol = get_rtol(np.double) + + # Check default is 'L' + w, v = np.linalg.eigh(Klo) + assert_allclose(w, tgt, rtol=rtol) + # Check 'L' + w, v = np.linalg.eigh(Klo, UPLO='L') + assert_allclose(w, tgt, rtol=rtol) + # Check 'l' + w, v = np.linalg.eigh(Klo, UPLO='l') + assert_allclose(w, tgt, rtol=rtol) + # Check 'U' + w, v = np.linalg.eigh(Kup, UPLO='U') + assert_allclose(w, tgt, rtol=rtol) + # Check 'u' + w, v = np.linalg.eigh(Kup, UPLO='u') + assert_allclose(w, tgt, rtol=rtol) + + def test_0_size(self): + # Check that all kinds of 0-sized arrays work + class ArraySubclass(np.ndarray): + pass + a = np.zeros((0, 1, 1), dtype=np.int_).view(ArraySubclass) + res, res_v = linalg.eigh(a) + assert_(res_v.dtype.type is np.float64) + assert_(res.dtype.type is np.float64) + assert_equal(a.shape, res_v.shape) + assert_equal((0, 1), res.shape) + # This is just for documentation, it might make sense to change: + assert_(isinstance(a, np.ndarray)) + + a = np.zeros((0, 0), dtype=np.complex64).view(ArraySubclass) + res, res_v = linalg.eigh(a) + assert_(res_v.dtype.type is np.complex64) + assert_(res.dtype.type is np.float32) + assert_equal(a.shape, res_v.shape) + assert_equal((0,), res.shape) + # This is just for documentation, it might make sense to change: + assert_(isinstance(a, np.ndarray)) + + +class _TestNormBase: + dt = None + dec = None + + +class _TestNormGeneral(_TestNormBase): + + def test_empty(self): + assert_equal(norm([]), 0.0) + assert_equal(norm(array([], dtype=self.dt)), 0.0) + assert_equal(norm(atleast_2d(array([], dtype=self.dt))), 0.0) + + def test_vector_return_type(self): + a = np.array([1, 0, 1]) + + exact_types = np.typecodes['AllInteger'] + inexact_types = np.typecodes['AllFloat'] + + all_types = exact_types + inexact_types + + for each_inexact_types in all_types: + at = a.astype(each_inexact_types) + + an = norm(at, -np.inf) + assert_(issubclass(an.dtype.type, np.floating)) + assert_almost_equal(an, 0.0) + + with suppress_warnings() as sup: + sup.filter(RuntimeWarning, "divide by zero encountered") + an = norm(at, -1) + assert_(issubclass(an.dtype.type, np.floating)) + assert_almost_equal(an, 0.0) + + an = norm(at, 0) + assert_(issubclass(an.dtype.type, np.floating)) + assert_almost_equal(an, 2) + + an = norm(at, 1) + assert_(issubclass(an.dtype.type, np.floating)) + assert_almost_equal(an, 2.0) + + an = norm(at, 2) + assert_(issubclass(an.dtype.type, np.floating)) + assert_almost_equal(an, an.dtype.type(2.0)**an.dtype.type(1.0/2.0)) + + an = norm(at, 4) + assert_(issubclass(an.dtype.type, np.floating)) + assert_almost_equal(an, an.dtype.type(2.0)**an.dtype.type(1.0/4.0)) + + an = norm(at, np.inf) + assert_(issubclass(an.dtype.type, np.floating)) + assert_almost_equal(an, 1.0) + + def test_vector(self): + a = [1, 2, 3, 4] + b = [-1, -2, -3, -4] + c = [-1, 2, -3, 4] + + def _test(v): + np.testing.assert_almost_equal(norm(v), 30 ** 0.5, + decimal=self.dec) + np.testing.assert_almost_equal(norm(v, inf), 4.0, + decimal=self.dec) + np.testing.assert_almost_equal(norm(v, -inf), 1.0, + decimal=self.dec) + np.testing.assert_almost_equal(norm(v, 1), 10.0, + decimal=self.dec) + np.testing.assert_almost_equal(norm(v, -1), 12.0 / 25, + decimal=self.dec) + np.testing.assert_almost_equal(norm(v, 2), 30 ** 0.5, + decimal=self.dec) + np.testing.assert_almost_equal(norm(v, -2), ((205. / 144) ** -0.5), + decimal=self.dec) + np.testing.assert_almost_equal(norm(v, 0), 4, + decimal=self.dec) + + for v in (a, b, c,): + _test(v) + + for v in (array(a, dtype=self.dt), array(b, dtype=self.dt), + array(c, dtype=self.dt)): + _test(v) + + def test_axis(self): + # Vector norms. + # Compare the use of `axis` with computing the norm of each row + # or column separately. + A = array([[1, 2, 3], [4, 5, 6]], dtype=self.dt) + for order in [None, -1, 0, 1, 2, 3, np.Inf, -np.Inf]: + expected0 = [norm(A[:, k], ord=order) for k in range(A.shape[1])] + assert_almost_equal(norm(A, ord=order, axis=0), expected0) + expected1 = [norm(A[k, :], ord=order) for k in range(A.shape[0])] + assert_almost_equal(norm(A, ord=order, axis=1), expected1) + + # Matrix norms. + B = np.arange(1, 25, dtype=self.dt).reshape(2, 3, 4) + nd = B.ndim + for order in [None, -2, 2, -1, 1, np.Inf, -np.Inf, 'fro']: + for axis in itertools.combinations(range(-nd, nd), 2): + row_axis, col_axis = axis + if row_axis < 0: + row_axis += nd + if col_axis < 0: + col_axis += nd + if row_axis == col_axis: + assert_raises(ValueError, norm, B, ord=order, axis=axis) + else: + n = norm(B, ord=order, axis=axis) + + # The logic using k_index only works for nd = 3. + # This has to be changed if nd is increased. + k_index = nd - (row_axis + col_axis) + if row_axis < col_axis: + expected = [norm(B[:].take(k, axis=k_index), ord=order) + for k in range(B.shape[k_index])] + else: + expected = [norm(B[:].take(k, axis=k_index).T, ord=order) + for k in range(B.shape[k_index])] + assert_almost_equal(n, expected) + + def test_keepdims(self): + A = np.arange(1, 25, dtype=self.dt).reshape(2, 3, 4) + + allclose_err = 'order {0}, axis = {1}' + shape_err = 'Shape mismatch found {0}, expected {1}, order={2}, axis={3}' + + # check the order=None, axis=None case + expected = norm(A, ord=None, axis=None) + found = norm(A, ord=None, axis=None, keepdims=True) + assert_allclose(np.squeeze(found), expected, + err_msg=allclose_err.format(None, None)) + expected_shape = (1, 1, 1) + assert_(found.shape == expected_shape, + shape_err.format(found.shape, expected_shape, None, None)) + + # Vector norms. + for order in [None, -1, 0, 1, 2, 3, np.Inf, -np.Inf]: + for k in range(A.ndim): + expected = norm(A, ord=order, axis=k) + found = norm(A, ord=order, axis=k, keepdims=True) + assert_allclose(np.squeeze(found), expected, + err_msg=allclose_err.format(order, k)) + expected_shape = list(A.shape) + expected_shape[k] = 1 + expected_shape = tuple(expected_shape) + assert_(found.shape == expected_shape, + shape_err.format(found.shape, expected_shape, order, k)) + + # Matrix norms. + for order in [None, -2, 2, -1, 1, np.Inf, -np.Inf, 'fro', 'nuc']: + for k in itertools.permutations(range(A.ndim), 2): + expected = norm(A, ord=order, axis=k) + found = norm(A, ord=order, axis=k, keepdims=True) + assert_allclose(np.squeeze(found), expected, + err_msg=allclose_err.format(order, k)) + expected_shape = list(A.shape) + expected_shape[k[0]] = 1 + expected_shape[k[1]] = 1 + expected_shape = tuple(expected_shape) + assert_(found.shape == expected_shape, + shape_err.format(found.shape, expected_shape, order, k)) + + +class _TestNorm2D(_TestNormBase): + # Define the part for 2d arrays separately, so we can subclass this + # and run the tests using np.matrix in matrixlib.tests.test_matrix_linalg. + array = np.array + + def test_matrix_empty(self): + assert_equal(norm(self.array([[]], dtype=self.dt)), 0.0) + + def test_matrix_return_type(self): + a = self.array([[1, 0, 1], [0, 1, 1]]) + + exact_types = np.typecodes['AllInteger'] + + # float32, complex64, float64, complex128 types are the only types + # allowed by `linalg`, which performs the matrix operations used + # within `norm`. + inexact_types = 'fdFD' + + all_types = exact_types + inexact_types + + for each_inexact_types in all_types: + at = a.astype(each_inexact_types) + + an = norm(at, -np.inf) + assert_(issubclass(an.dtype.type, np.floating)) + assert_almost_equal(an, 2.0) + + with suppress_warnings() as sup: + sup.filter(RuntimeWarning, "divide by zero encountered") + an = norm(at, -1) + assert_(issubclass(an.dtype.type, np.floating)) + assert_almost_equal(an, 1.0) + + an = norm(at, 1) + assert_(issubclass(an.dtype.type, np.floating)) + assert_almost_equal(an, 2.0) + + an = norm(at, 2) + assert_(issubclass(an.dtype.type, np.floating)) + assert_almost_equal(an, 3.0**(1.0/2.0)) + + an = norm(at, -2) + assert_(issubclass(an.dtype.type, np.floating)) + assert_almost_equal(an, 1.0) + + an = norm(at, np.inf) + assert_(issubclass(an.dtype.type, np.floating)) + assert_almost_equal(an, 2.0) + + an = norm(at, 'fro') + assert_(issubclass(an.dtype.type, np.floating)) + assert_almost_equal(an, 2.0) + + an = norm(at, 'nuc') + assert_(issubclass(an.dtype.type, np.floating)) + # Lower bar needed to support low precision floats. + # They end up being off by 1 in the 7th place. + np.testing.assert_almost_equal(an, 2.7320508075688772, decimal=6) + + def test_matrix_2x2(self): + A = self.array([[1, 3], [5, 7]], dtype=self.dt) + assert_almost_equal(norm(A), 84 ** 0.5) + assert_almost_equal(norm(A, 'fro'), 84 ** 0.5) + assert_almost_equal(norm(A, 'nuc'), 10.0) + assert_almost_equal(norm(A, inf), 12.0) + assert_almost_equal(norm(A, -inf), 4.0) + assert_almost_equal(norm(A, 1), 10.0) + assert_almost_equal(norm(A, -1), 6.0) + assert_almost_equal(norm(A, 2), 9.1231056256176615) + assert_almost_equal(norm(A, -2), 0.87689437438234041) + + assert_raises(ValueError, norm, A, 'nofro') + assert_raises(ValueError, norm, A, -3) + assert_raises(ValueError, norm, A, 0) + + def test_matrix_3x3(self): + # This test has been added because the 2x2 example + # happened to have equal nuclear norm and induced 1-norm. + # The 1/10 scaling factor accommodates the absolute tolerance + # used in assert_almost_equal. + A = (1 / 10) * \ + self.array([[1, 2, 3], [6, 0, 5], [3, 2, 1]], dtype=self.dt) + assert_almost_equal(norm(A), (1 / 10) * 89 ** 0.5) + assert_almost_equal(norm(A, 'fro'), (1 / 10) * 89 ** 0.5) + assert_almost_equal(norm(A, 'nuc'), 1.3366836911774836) + assert_almost_equal(norm(A, inf), 1.1) + assert_almost_equal(norm(A, -inf), 0.6) + assert_almost_equal(norm(A, 1), 1.0) + assert_almost_equal(norm(A, -1), 0.4) + assert_almost_equal(norm(A, 2), 0.88722940323461277) + assert_almost_equal(norm(A, -2), 0.19456584790481812) + + def test_bad_args(self): + # Check that bad arguments raise the appropriate exceptions. + + A = self.array([[1, 2, 3], [4, 5, 6]], dtype=self.dt) + B = np.arange(1, 25, dtype=self.dt).reshape(2, 3, 4) + + # Using `axis=` or passing in a 1-D array implies vector + # norms are being computed, so also using `ord='fro'` + # or `ord='nuc'` or any other string raises a ValueError. + assert_raises(ValueError, norm, A, 'fro', 0) + assert_raises(ValueError, norm, A, 'nuc', 0) + assert_raises(ValueError, norm, [3, 4], 'fro', None) + assert_raises(ValueError, norm, [3, 4], 'nuc', None) + assert_raises(ValueError, norm, [3, 4], 'test', None) + + # Similarly, norm should raise an exception when ord is any finite + # number other than 1, 2, -1 or -2 when computing matrix norms. + for order in [0, 3]: + assert_raises(ValueError, norm, A, order, None) + assert_raises(ValueError, norm, A, order, (0, 1)) + assert_raises(ValueError, norm, B, order, (1, 2)) + + # Invalid axis + assert_raises(np.AxisError, norm, B, None, 3) + assert_raises(np.AxisError, norm, B, None, (2, 3)) + assert_raises(ValueError, norm, B, None, (0, 1, 2)) + + +class _TestNorm(_TestNorm2D, _TestNormGeneral): + pass + + +class TestNorm_NonSystematic: + + def test_longdouble_norm(self): + # Non-regression test: p-norm of longdouble would previously raise + # UnboundLocalError. + x = np.arange(10, dtype=np.longdouble) + old_assert_almost_equal(norm(x, ord=3), 12.65, decimal=2) + + def test_intmin(self): + # Non-regression test: p-norm of signed integer would previously do + # float cast and abs in the wrong order. + x = np.array([-2 ** 31], dtype=np.int32) + old_assert_almost_equal(norm(x, ord=3), 2 ** 31, decimal=5) + + def test_complex_high_ord(self): + # gh-4156 + d = np.empty((2,), dtype=np.clongdouble) + d[0] = 6 + 7j + d[1] = -6 + 7j + res = 11.615898132184 + old_assert_almost_equal(np.linalg.norm(d, ord=3), res, decimal=10) + d = d.astype(np.complex128) + old_assert_almost_equal(np.linalg.norm(d, ord=3), res, decimal=9) + d = d.astype(np.complex64) + old_assert_almost_equal(np.linalg.norm(d, ord=3), res, decimal=5) + + +# Separate definitions so we can use them for matrix tests. +class _TestNormDoubleBase(_TestNormBase): + dt = np.double + dec = 12 + + +class _TestNormSingleBase(_TestNormBase): + dt = np.float32 + dec = 6 + + +class _TestNormInt64Base(_TestNormBase): + dt = np.int64 + dec = 12 + + +class TestNormDouble(_TestNorm, _TestNormDoubleBase): + pass + + +class TestNormSingle(_TestNorm, _TestNormSingleBase): + pass + + +class TestNormInt64(_TestNorm, _TestNormInt64Base): + pass + + +class TestMatrixRank: + + def test_matrix_rank(self): + # Full rank matrix + assert_equal(4, matrix_rank(np.eye(4))) + # rank deficient matrix + I = np.eye(4) + I[-1, -1] = 0. + assert_equal(matrix_rank(I), 3) + # All zeros - zero rank + assert_equal(matrix_rank(np.zeros((4, 4))), 0) + # 1 dimension - rank 1 unless all 0 + assert_equal(matrix_rank([1, 0, 0, 0]), 1) + assert_equal(matrix_rank(np.zeros((4,))), 0) + # accepts array-like + assert_equal(matrix_rank([1]), 1) + # greater than 2 dimensions treated as stacked matrices + ms = np.array([I, np.eye(4), np.zeros((4,4))]) + assert_equal(matrix_rank(ms), np.array([3, 4, 0])) + # works on scalar + assert_equal(matrix_rank(1), 1) + + def test_symmetric_rank(self): + assert_equal(4, matrix_rank(np.eye(4), hermitian=True)) + assert_equal(1, matrix_rank(np.ones((4, 4)), hermitian=True)) + assert_equal(0, matrix_rank(np.zeros((4, 4)), hermitian=True)) + # rank deficient matrix + I = np.eye(4) + I[-1, -1] = 0. + assert_equal(3, matrix_rank(I, hermitian=True)) + # manually supplied tolerance + I[-1, -1] = 1e-8 + assert_equal(4, matrix_rank(I, hermitian=True, tol=0.99e-8)) + assert_equal(3, matrix_rank(I, hermitian=True, tol=1.01e-8)) + + +def test_reduced_rank(): + # Test matrices with reduced rank + rng = np.random.RandomState(20120714) + for i in range(100): + # Make a rank deficient matrix + X = rng.normal(size=(40, 10)) + X[:, 0] = X[:, 1] + X[:, 2] + # Assert that matrix_rank detected deficiency + assert_equal(matrix_rank(X), 9) + X[:, 3] = X[:, 4] + X[:, 5] + assert_equal(matrix_rank(X), 8) + + +class TestQR: + # Define the array class here, so run this on matrices elsewhere. + array = np.array + + def check_qr(self, a): + # This test expects the argument `a` to be an ndarray or + # a subclass of an ndarray of inexact type. + a_type = type(a) + a_dtype = a.dtype + m, n = a.shape + k = min(m, n) + + # mode == 'complete' + q, r = linalg.qr(a, mode='complete') + assert_(q.dtype == a_dtype) + assert_(r.dtype == a_dtype) + assert_(isinstance(q, a_type)) + assert_(isinstance(r, a_type)) + assert_(q.shape == (m, m)) + assert_(r.shape == (m, n)) + assert_almost_equal(dot(q, r), a) + assert_almost_equal(dot(q.T.conj(), q), np.eye(m)) + assert_almost_equal(np.triu(r), r) + + # mode == 'reduced' + q1, r1 = linalg.qr(a, mode='reduced') + assert_(q1.dtype == a_dtype) + assert_(r1.dtype == a_dtype) + assert_(isinstance(q1, a_type)) + assert_(isinstance(r1, a_type)) + assert_(q1.shape == (m, k)) + assert_(r1.shape == (k, n)) + assert_almost_equal(dot(q1, r1), a) + assert_almost_equal(dot(q1.T.conj(), q1), np.eye(k)) + assert_almost_equal(np.triu(r1), r1) + + # mode == 'r' + r2 = linalg.qr(a, mode='r') + assert_(r2.dtype == a_dtype) + assert_(isinstance(r2, a_type)) + assert_almost_equal(r2, r1) + + + @pytest.mark.parametrize(["m", "n"], [ + (3, 0), + (0, 3), + (0, 0) + ]) + def test_qr_empty(self, m, n): + k = min(m, n) + a = np.empty((m, n)) + + self.check_qr(a) + + h, tau = np.linalg.qr(a, mode='raw') + assert_equal(h.dtype, np.double) + assert_equal(tau.dtype, np.double) + assert_equal(h.shape, (n, m)) + assert_equal(tau.shape, (k,)) + + def test_mode_raw(self): + # The factorization is not unique and varies between libraries, + # so it is not possible to check against known values. Functional + # testing is a possibility, but awaits the exposure of more + # of the functions in lapack_lite. Consequently, this test is + # very limited in scope. Note that the results are in FORTRAN + # order, hence the h arrays are transposed. + a = self.array([[1, 2], [3, 4], [5, 6]], dtype=np.double) + + # Test double + h, tau = linalg.qr(a, mode='raw') + assert_(h.dtype == np.double) + assert_(tau.dtype == np.double) + assert_(h.shape == (2, 3)) + assert_(tau.shape == (2,)) + + h, tau = linalg.qr(a.T, mode='raw') + assert_(h.dtype == np.double) + assert_(tau.dtype == np.double) + assert_(h.shape == (3, 2)) + assert_(tau.shape == (2,)) + + def test_mode_all_but_economic(self): + a = self.array([[1, 2], [3, 4]]) + b = self.array([[1, 2], [3, 4], [5, 6]]) + for dt in "fd": + m1 = a.astype(dt) + m2 = b.astype(dt) + self.check_qr(m1) + self.check_qr(m2) + self.check_qr(m2.T) + + for dt in "fd": + m1 = 1 + 1j * a.astype(dt) + m2 = 1 + 1j * b.astype(dt) + self.check_qr(m1) + self.check_qr(m2) + self.check_qr(m2.T) + + +class TestCholesky: + # TODO: are there no other tests for cholesky? + + def test_basic_property(self): + # Check A = L L^H + shapes = [(1, 1), (2, 2), (3, 3), (50, 50), (3, 10, 10)] + dtypes = (np.float32, np.float64, np.complex64, np.complex128) + + for shape, dtype in itertools.product(shapes, dtypes): + np.random.seed(1) + a = np.random.randn(*shape) + if np.issubdtype(dtype, np.complexfloating): + a = a + 1j*np.random.randn(*shape) + + t = list(range(len(shape))) + t[-2:] = -1, -2 + + a = np.matmul(a.transpose(t).conj(), a) + a = np.asarray(a, dtype=dtype) + + c = np.linalg.cholesky(a) + + b = np.matmul(c, c.transpose(t).conj()) + assert_allclose(b, a, + err_msg=f'{shape} {dtype}\n{a}\n{c}', + atol=500 * a.shape[0] * np.finfo(dtype).eps) + + def test_0_size(self): + class ArraySubclass(np.ndarray): + pass + a = np.zeros((0, 1, 1), dtype=np.int_).view(ArraySubclass) + res = linalg.cholesky(a) + assert_equal(a.shape, res.shape) + assert_(res.dtype.type is np.float64) + # for documentation purpose: + assert_(isinstance(res, np.ndarray)) + + a = np.zeros((1, 0, 0), dtype=np.complex64).view(ArraySubclass) + res = linalg.cholesky(a) + assert_equal(a.shape, res.shape) + assert_(res.dtype.type is np.complex64) + assert_(isinstance(res, np.ndarray)) + + +def test_byteorder_check(): + # Byte order check should pass for native order + if sys.byteorder == 'little': + native = '<' + else: + native = '>' + + for dtt in (np.float32, np.float64): + arr = np.eye(4, dtype=dtt) + n_arr = arr.newbyteorder(native) + sw_arr = arr.newbyteorder('S').byteswap() + assert_equal(arr.dtype.byteorder, '=') + for routine in (linalg.inv, linalg.det, linalg.pinv): + # Normal call + res = routine(arr) + # Native but not '=' + assert_array_equal(res, routine(n_arr)) + # Swapped + assert_array_equal(res, routine(sw_arr)) + + +def test_generalized_raise_multiloop(): + # It should raise an error even if the error doesn't occur in the + # last iteration of the ufunc inner loop + + invertible = np.array([[1, 2], [3, 4]]) + non_invertible = np.array([[1, 1], [1, 1]]) + + x = np.zeros([4, 4, 2, 2])[1::2] + x[...] = invertible + x[0, 0] = non_invertible + + assert_raises(np.linalg.LinAlgError, np.linalg.inv, x) + + +def test_xerbla_override(): + # Check that our xerbla has been successfully linked in. If it is not, + # the default xerbla routine is called, which prints a message to stdout + # and may, or may not, abort the process depending on the LAPACK package. + + XERBLA_OK = 255 + + try: + pid = os.fork() + except (OSError, AttributeError): + # fork failed, or not running on POSIX + pytest.skip("Not POSIX or fork failed.") + + if pid == 0: + # child; close i/o file handles + os.close(1) + os.close(0) + # Avoid producing core files. + import resource + resource.setrlimit(resource.RLIMIT_CORE, (0, 0)) + # These calls may abort. + try: + np.linalg.lapack_lite.xerbla() + except ValueError: + pass + except Exception: + os._exit(os.EX_CONFIG) + + try: + a = np.array([[1.]]) + np.linalg.lapack_lite.dorgqr( + 1, 1, 1, a, + 0, # <- invalid value + a, a, 0, 0) + except ValueError as e: + if "DORGQR parameter number 5" in str(e): + # success, reuse error code to mark success as + # FORTRAN STOP returns as success. + os._exit(XERBLA_OK) + + # Did not abort, but our xerbla was not linked in. + os._exit(os.EX_CONFIG) + else: + # parent + pid, status = os.wait() + if os.WEXITSTATUS(status) != XERBLA_OK: + pytest.skip('Numpy xerbla not linked in.') + + +@pytest.mark.slow +def test_sdot_bug_8577(): + # Regression test that loading certain other libraries does not + # result to wrong results in float32 linear algebra. + # + # There's a bug gh-8577 on OSX that can trigger this, and perhaps + # there are also other situations in which it occurs. + # + # Do the check in a separate process. + + bad_libs = ['PyQt5.QtWidgets', 'IPython'] + + template = textwrap.dedent(""" + import sys + {before} + try: + import {bad_lib} + except ImportError: + sys.exit(0) + {after} + x = np.ones(2, dtype=np.float32) + sys.exit(0 if np.allclose(x.dot(x), 2.0) else 1) + """) + + for bad_lib in bad_libs: + code = template.format(before="import numpy as np", after="", + bad_lib=bad_lib) + subprocess.check_call([sys.executable, "-c", code]) + + # Swapped import order + code = template.format(after="import numpy as np", before="", + bad_lib=bad_lib) + subprocess.check_call([sys.executable, "-c", code]) + + +class TestMultiDot: + + def test_basic_function_with_three_arguments(self): + # multi_dot with three arguments uses a fast hand coded algorithm to + # determine the optimal order. Therefore test it separately. + A = np.random.random((6, 2)) + B = np.random.random((2, 6)) + C = np.random.random((6, 2)) + + assert_almost_equal(multi_dot([A, B, C]), A.dot(B).dot(C)) + assert_almost_equal(multi_dot([A, B, C]), np.dot(A, np.dot(B, C))) + + def test_basic_function_with_two_arguments(self): + # separate code path with two arguments + A = np.random.random((6, 2)) + B = np.random.random((2, 6)) + + assert_almost_equal(multi_dot([A, B]), A.dot(B)) + assert_almost_equal(multi_dot([A, B]), np.dot(A, B)) + + def test_basic_function_with_dynamic_programing_optimization(self): + # multi_dot with four or more arguments uses the dynamic programing + # optimization and therefore deserve a separate + A = np.random.random((6, 2)) + B = np.random.random((2, 6)) + C = np.random.random((6, 2)) + D = np.random.random((2, 1)) + assert_almost_equal(multi_dot([A, B, C, D]), A.dot(B).dot(C).dot(D)) + + def test_vector_as_first_argument(self): + # The first argument can be 1-D + A1d = np.random.random(2) # 1-D + B = np.random.random((2, 6)) + C = np.random.random((6, 2)) + D = np.random.random((2, 2)) + + # the result should be 1-D + assert_equal(multi_dot([A1d, B, C, D]).shape, (2,)) + + def test_vector_as_last_argument(self): + # The last argument can be 1-D + A = np.random.random((6, 2)) + B = np.random.random((2, 6)) + C = np.random.random((6, 2)) + D1d = np.random.random(2) # 1-D + + # the result should be 1-D + assert_equal(multi_dot([A, B, C, D1d]).shape, (6,)) + + def test_vector_as_first_and_last_argument(self): + # The first and last arguments can be 1-D + A1d = np.random.random(2) # 1-D + B = np.random.random((2, 6)) + C = np.random.random((6, 2)) + D1d = np.random.random(2) # 1-D + + # the result should be a scalar + assert_equal(multi_dot([A1d, B, C, D1d]).shape, ()) + + def test_three_arguments_and_out(self): + # multi_dot with three arguments uses a fast hand coded algorithm to + # determine the optimal order. Therefore test it separately. + A = np.random.random((6, 2)) + B = np.random.random((2, 6)) + C = np.random.random((6, 2)) + + out = np.zeros((6, 2)) + ret = multi_dot([A, B, C], out=out) + assert out is ret + assert_almost_equal(out, A.dot(B).dot(C)) + assert_almost_equal(out, np.dot(A, np.dot(B, C))) + + def test_two_arguments_and_out(self): + # separate code path with two arguments + A = np.random.random((6, 2)) + B = np.random.random((2, 6)) + out = np.zeros((6, 6)) + ret = multi_dot([A, B], out=out) + assert out is ret + assert_almost_equal(out, A.dot(B)) + assert_almost_equal(out, np.dot(A, B)) + + def test_dynamic_programing_optimization_and_out(self): + # multi_dot with four or more arguments uses the dynamic programing + # optimization and therefore deserve a separate test + A = np.random.random((6, 2)) + B = np.random.random((2, 6)) + C = np.random.random((6, 2)) + D = np.random.random((2, 1)) + out = np.zeros((6, 1)) + ret = multi_dot([A, B, C, D], out=out) + assert out is ret + assert_almost_equal(out, A.dot(B).dot(C).dot(D)) + + def test_dynamic_programming_logic(self): + # Test for the dynamic programming part + # This test is directly taken from Cormen page 376. + arrays = [np.random.random((30, 35)), + np.random.random((35, 15)), + np.random.random((15, 5)), + np.random.random((5, 10)), + np.random.random((10, 20)), + np.random.random((20, 25))] + m_expected = np.array([[0., 15750., 7875., 9375., 11875., 15125.], + [0., 0., 2625., 4375., 7125., 10500.], + [0., 0., 0., 750., 2500., 5375.], + [0., 0., 0., 0., 1000., 3500.], + [0., 0., 0., 0., 0., 5000.], + [0., 0., 0., 0., 0., 0.]]) + s_expected = np.array([[0, 1, 1, 3, 3, 3], + [0, 0, 2, 3, 3, 3], + [0, 0, 0, 3, 3, 3], + [0, 0, 0, 0, 4, 5], + [0, 0, 0, 0, 0, 5], + [0, 0, 0, 0, 0, 0]], dtype=int) + s_expected -= 1 # Cormen uses 1-based index, python does not. + + s, m = _multi_dot_matrix_chain_order(arrays, return_costs=True) + + # Only the upper triangular part (without the diagonal) is interesting. + assert_almost_equal(np.triu(s[:-1, 1:]), + np.triu(s_expected[:-1, 1:])) + assert_almost_equal(np.triu(m), np.triu(m_expected)) + + def test_too_few_input_arrays(self): + assert_raises(ValueError, multi_dot, []) + assert_raises(ValueError, multi_dot, [np.random.random((3, 3))]) + + +class TestTensorinv: + + @pytest.mark.parametrize("arr, ind", [ + (np.ones((4, 6, 8, 2)), 2), + (np.ones((3, 3, 2)), 1), + ]) + def test_non_square_handling(self, arr, ind): + with assert_raises(LinAlgError): + linalg.tensorinv(arr, ind=ind) + + @pytest.mark.parametrize("shape, ind", [ + # examples from docstring + ((4, 6, 8, 3), 2), + ((24, 8, 3), 1), + ]) + def test_tensorinv_shape(self, shape, ind): + a = np.eye(24) + a.shape = shape + ainv = linalg.tensorinv(a=a, ind=ind) + expected = a.shape[ind:] + a.shape[:ind] + actual = ainv.shape + assert_equal(actual, expected) + + @pytest.mark.parametrize("ind", [ + 0, -2, + ]) + def test_tensorinv_ind_limit(self, ind): + a = np.eye(24) + a.shape = (4, 6, 8, 3) + with assert_raises(ValueError): + linalg.tensorinv(a=a, ind=ind) + + def test_tensorinv_result(self): + # mimic a docstring example + a = np.eye(24) + a.shape = (24, 8, 3) + ainv = linalg.tensorinv(a, ind=1) + b = np.ones(24) + assert_allclose(np.tensordot(ainv, b, 1), np.linalg.tensorsolve(a, b)) + + +def test_unsupported_commontype(): + # linalg gracefully handles unsupported type + arr = np.array([[1, -2], [2, 5]], dtype='float16') + with assert_raises_regex(TypeError, "unsupported in linalg"): + linalg.cholesky(arr) + + +@pytest.mark.slow +@pytest.mark.xfail(not HAS_LAPACK64, run=False, + reason="Numpy not compiled with 64-bit BLAS/LAPACK") +@requires_memory(free_bytes=16e9) +def test_blas64_dot(): + n = 2**32 + a = np.zeros([1, n], dtype=np.float32) + b = np.ones([1, 1], dtype=np.float32) + a[0,-1] = 1 + c = np.dot(b, a) + assert_equal(c[0,-1], 1) + + +@pytest.mark.xfail(not HAS_LAPACK64, + reason="Numpy not compiled with 64-bit BLAS/LAPACK") +def test_blas64_geqrf_lwork_smoketest(): + # Smoke test LAPACK geqrf lwork call with 64-bit integers + dtype = np.float64 + lapack_routine = np.linalg.lapack_lite.dgeqrf + + m = 2**32 + 1 + n = 2**32 + 1 + lda = m + + # Dummy arrays, not referenced by the lapack routine, so don't + # need to be of the right size + a = np.zeros([1, 1], dtype=dtype) + work = np.zeros([1], dtype=dtype) + tau = np.zeros([1], dtype=dtype) + + # Size query + results = lapack_routine(m, n, a, lda, tau, work, -1, 0) + assert_equal(results['info'], 0) + assert_equal(results['m'], m) + assert_equal(results['n'], m) + + # Should result to an integer of a reasonable size + lwork = int(work.item()) + assert_(2**32 < lwork < 2**42) diff --git a/venv/Lib/site-packages/numpy/linalg/tests/test_regression.py b/venv/Lib/site-packages/numpy/linalg/tests/test_regression.py new file mode 100644 index 0000000..7ed932b --- /dev/null +++ b/venv/Lib/site-packages/numpy/linalg/tests/test_regression.py @@ -0,0 +1,148 @@ +""" Test functions for linalg module +""" +import warnings + +import numpy as np +from numpy import linalg, arange, float64, array, dot, transpose +from numpy.testing import ( + assert_, assert_raises, assert_equal, assert_array_equal, + assert_array_almost_equal, assert_array_less +) + + +class TestRegression: + + def test_eig_build(self): + # Ticket #652 + rva = array([1.03221168e+02 + 0.j, + -1.91843603e+01 + 0.j, + -6.04004526e-01 + 15.84422474j, + -6.04004526e-01 - 15.84422474j, + -1.13692929e+01 + 0.j, + -6.57612485e-01 + 10.41755503j, + -6.57612485e-01 - 10.41755503j, + 1.82126812e+01 + 0.j, + 1.06011014e+01 + 0.j, + 7.80732773e+00 + 0.j, + -7.65390898e-01 + 0.j, + 1.51971555e-15 + 0.j, + -1.51308713e-15 + 0.j]) + a = arange(13 * 13, dtype=float64) + a.shape = (13, 13) + a = a % 17 + va, ve = linalg.eig(a) + va.sort() + rva.sort() + assert_array_almost_equal(va, rva) + + def test_eigh_build(self): + # Ticket 662. + rvals = [68.60568999, 89.57756725, 106.67185574] + + cov = array([[77.70273908, 3.51489954, 15.64602427], + [3.51489954, 88.97013878, -1.07431931], + [15.64602427, -1.07431931, 98.18223512]]) + + vals, vecs = linalg.eigh(cov) + assert_array_almost_equal(vals, rvals) + + def test_svd_build(self): + # Ticket 627. + a = array([[0., 1.], [1., 1.], [2., 1.], [3., 1.]]) + m, n = a.shape + u, s, vh = linalg.svd(a) + + b = dot(transpose(u[:, n:]), a) + + assert_array_almost_equal(b, np.zeros((2, 2))) + + def test_norm_vector_badarg(self): + # Regression for #786: Frobenius norm for vectors raises + # ValueError. + assert_raises(ValueError, linalg.norm, array([1., 2., 3.]), 'fro') + + def test_lapack_endian(self): + # For bug #1482 + a = array([[5.7998084, -2.1825367], + [-2.1825367, 9.85910595]], dtype='>f8') + b = array(a, dtype=' 0.5) + assert_equal(c, 1) + assert_equal(np.linalg.matrix_rank(a), 1) + assert_array_less(1, np.linalg.norm(a, ord=2)) + + def test_norm_object_array(self): + # gh-7575 + testvector = np.array([np.array([0, 1]), 0, 0], dtype=object) + + norm = linalg.norm(testvector) + assert_array_equal(norm, [0, 1]) + assert_(norm.dtype == np.dtype('float64')) + + norm = linalg.norm(testvector, ord=1) + assert_array_equal(norm, [0, 1]) + assert_(norm.dtype != np.dtype('float64')) + + norm = linalg.norm(testvector, ord=2) + assert_array_equal(norm, [0, 1]) + assert_(norm.dtype == np.dtype('float64')) + + assert_raises(ValueError, linalg.norm, testvector, ord='fro') + assert_raises(ValueError, linalg.norm, testvector, ord='nuc') + assert_raises(ValueError, linalg.norm, testvector, ord=np.inf) + assert_raises(ValueError, linalg.norm, testvector, ord=-np.inf) + with warnings.catch_warnings(): + warnings.simplefilter("error", DeprecationWarning) + assert_raises((AttributeError, DeprecationWarning), + linalg.norm, testvector, ord=0) + assert_raises(ValueError, linalg.norm, testvector, ord=-1) + assert_raises(ValueError, linalg.norm, testvector, ord=-2) + + testmatrix = np.array([[np.array([0, 1]), 0, 0], + [0, 0, 0]], dtype=object) + + norm = linalg.norm(testmatrix) + assert_array_equal(norm, [0, 1]) + assert_(norm.dtype == np.dtype('float64')) + + norm = linalg.norm(testmatrix, ord='fro') + assert_array_equal(norm, [0, 1]) + assert_(norm.dtype == np.dtype('float64')) + + assert_raises(TypeError, linalg.norm, testmatrix, ord='nuc') + assert_raises(ValueError, linalg.norm, testmatrix, ord=np.inf) + assert_raises(ValueError, linalg.norm, testmatrix, ord=-np.inf) + assert_raises(ValueError, linalg.norm, testmatrix, ord=0) + assert_raises(ValueError, linalg.norm, testmatrix, ord=1) + assert_raises(ValueError, linalg.norm, testmatrix, ord=-1) + assert_raises(TypeError, linalg.norm, testmatrix, ord=2) + assert_raises(TypeError, linalg.norm, testmatrix, ord=-2) + assert_raises(ValueError, linalg.norm, testmatrix, ord=3) + + def test_lstsq_complex_larger_rhs(self): + # gh-9891 + size = 20 + n_rhs = 70 + G = np.random.randn(size, size) + 1j * np.random.randn(size, size) + u = np.random.randn(size, n_rhs) + 1j * np.random.randn(size, n_rhs) + b = G.dot(u) + # This should work without segmentation fault. + u_lstsq, res, rank, sv = linalg.lstsq(G, b, rcond=None) + # check results just in case + assert_array_almost_equal(u_lstsq, u) diff --git a/venv/Lib/site-packages/numpy/ma/__init__.py b/venv/Lib/site-packages/numpy/ma/__init__.py new file mode 100644 index 0000000..870cc4e --- /dev/null +++ b/venv/Lib/site-packages/numpy/ma/__init__.py @@ -0,0 +1,54 @@ +""" +============= +Masked Arrays +============= + +Arrays sometimes contain invalid or missing data. When doing operations +on such arrays, we wish to suppress invalid values, which is the purpose masked +arrays fulfill (an example of typical use is given below). + +For example, examine the following array: + +>>> x = np.array([2, 1, 3, np.nan, 5, 2, 3, np.nan]) + +When we try to calculate the mean of the data, the result is undetermined: + +>>> np.mean(x) +nan + +The mean is calculated using roughly ``np.sum(x)/len(x)``, but since +any number added to ``NaN`` [1]_ produces ``NaN``, this doesn't work. Enter +masked arrays: + +>>> m = np.ma.masked_array(x, np.isnan(x)) +>>> m +masked_array(data = [2.0 1.0 3.0 -- 5.0 2.0 3.0 --], + mask = [False False False True False False False True], + fill_value=1e+20) + +Here, we construct a masked array that suppress all ``NaN`` values. We +may now proceed to calculate the mean of the other values: + +>>> np.mean(m) +2.6666666666666665 + +.. [1] Not-a-Number, a floating point value that is the result of an + invalid operation. + +.. moduleauthor:: Pierre Gerard-Marchant +.. moduleauthor:: Jarrod Millman + +""" +from . import core +from .core import * + +from . import extras +from .extras import * + +__all__ = ['core', 'extras'] +__all__ += core.__all__ +__all__ += extras.__all__ + +from numpy._pytesttester import PytestTester +test = PytestTester(__name__) +del PytestTester diff --git a/venv/Lib/site-packages/numpy/ma/__init__.pyi b/venv/Lib/site-packages/numpy/ma/__init__.pyi new file mode 100644 index 0000000..16e0262 --- /dev/null +++ b/venv/Lib/site-packages/numpy/ma/__init__.pyi @@ -0,0 +1,229 @@ +from typing import Any, List + +from numpy.ma import extras as extras + +__all__: List[str] + +core: Any +extras: Any +MAError: Any +MaskError: Any +MaskType: Any +MaskedArray: Any +abs: Any +absolute: Any +add: Any +all: Any +allclose: Any +allequal: Any +alltrue: Any +amax: Any +amin: Any +angle: Any +anom: Any +anomalies: Any +any: Any +append: Any +arange: Any +arccos: Any +arccosh: Any +arcsin: Any +arcsinh: Any +arctan: Any +arctan2: Any +arctanh: Any +argmax: Any +argmin: Any +argsort: Any +around: Any +array: Any +asanyarray: Any +asarray: Any +bitwise_and: Any +bitwise_or: Any +bitwise_xor: Any +bool_: Any +ceil: Any +choose: Any +clip: Any +common_fill_value: Any +compress: Any +compressed: Any +concatenate: Any +conjugate: Any +convolve: Any +copy: Any +correlate: Any +cos: Any +cosh: Any +count: Any +cumprod: Any +cumsum: Any +default_fill_value: Any +diag: Any +diagonal: Any +diff: Any +divide: Any +empty: Any +empty_like: Any +equal: Any +exp: Any +expand_dims: Any +fabs: Any +filled: Any +fix_invalid: Any +flatten_mask: Any +flatten_structured_array: Any +floor: Any +floor_divide: Any +fmod: Any +frombuffer: Any +fromflex: Any +fromfunction: Any +getdata: Any +getmask: Any +getmaskarray: Any +greater: Any +greater_equal: Any +harden_mask: Any +hypot: Any +identity: Any +ids: Any +indices: Any +inner: Any +innerproduct: Any +isMA: Any +isMaskedArray: Any +is_mask: Any +is_masked: Any +isarray: Any +left_shift: Any +less: Any +less_equal: Any +log: Any +log10: Any +log2: Any +logical_and: Any +logical_not: Any +logical_or: Any +logical_xor: Any +make_mask: Any +make_mask_descr: Any +make_mask_none: Any +mask_or: Any +masked: Any +masked_array: Any +masked_equal: Any +masked_greater: Any +masked_greater_equal: Any +masked_inside: Any +masked_invalid: Any +masked_less: Any +masked_less_equal: Any +masked_not_equal: Any +masked_object: Any +masked_outside: Any +masked_print_option: Any +masked_singleton: Any +masked_values: Any +masked_where: Any +max: Any +maximum: Any +maximum_fill_value: Any +mean: Any +min: Any +minimum: Any +minimum_fill_value: Any +mod: Any +multiply: Any +mvoid: Any +ndim: Any +negative: Any +nomask: Any +nonzero: Any +not_equal: Any +ones: Any +outer: Any +outerproduct: Any +power: Any +prod: Any +product: Any +ptp: Any +put: Any +putmask: Any +ravel: Any +remainder: Any +repeat: Any +reshape: Any +resize: Any +right_shift: Any +round: Any +round_: Any +set_fill_value: Any +shape: Any +sin: Any +sinh: Any +size: Any +soften_mask: Any +sometrue: Any +sort: Any +sqrt: Any +squeeze: Any +std: Any +subtract: Any +sum: Any +swapaxes: Any +take: Any +tan: Any +tanh: Any +trace: Any +transpose: Any +true_divide: Any +var: Any +where: Any +zeros: Any +apply_along_axis: Any +apply_over_axes: Any +atleast_1d: Any +atleast_2d: Any +atleast_3d: Any +average: Any +clump_masked: Any +clump_unmasked: Any +column_stack: Any +compress_cols: Any +compress_nd: Any +compress_rowcols: Any +compress_rows: Any +count_masked: Any +corrcoef: Any +cov: Any +diagflat: Any +dot: Any +dstack: Any +ediff1d: Any +flatnotmasked_contiguous: Any +flatnotmasked_edges: Any +hsplit: Any +hstack: Any +isin: Any +in1d: Any +intersect1d: Any +mask_cols: Any +mask_rowcols: Any +mask_rows: Any +masked_all: Any +masked_all_like: Any +median: Any +mr_: Any +notmasked_contiguous: Any +notmasked_edges: Any +polyfit: Any +row_stack: Any +setdiff1d: Any +setxor1d: Any +stack: Any +unique: Any +union1d: Any +vander: Any +vstack: Any diff --git a/venv/Lib/site-packages/numpy/ma/bench.py b/venv/Lib/site-packages/numpy/ma/bench.py new file mode 100644 index 0000000..e29d543 --- /dev/null +++ b/venv/Lib/site-packages/numpy/ma/bench.py @@ -0,0 +1,131 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +import timeit +import numpy + + +############################################################################### +# Global variables # +############################################################################### + + +# Small arrays +xs = numpy.random.uniform(-1, 1, 6).reshape(2, 3) +ys = numpy.random.uniform(-1, 1, 6).reshape(2, 3) +zs = xs + 1j * ys +m1 = [[True, False, False], [False, False, True]] +m2 = [[True, False, True], [False, False, True]] +nmxs = numpy.ma.array(xs, mask=m1) +nmys = numpy.ma.array(ys, mask=m2) +nmzs = numpy.ma.array(zs, mask=m1) + +# Big arrays +xl = numpy.random.uniform(-1, 1, 100*100).reshape(100, 100) +yl = numpy.random.uniform(-1, 1, 100*100).reshape(100, 100) +zl = xl + 1j * yl +maskx = xl > 0.8 +masky = yl < -0.8 +nmxl = numpy.ma.array(xl, mask=maskx) +nmyl = numpy.ma.array(yl, mask=masky) +nmzl = numpy.ma.array(zl, mask=maskx) + + +############################################################################### +# Functions # +############################################################################### + + +def timer(s, v='', nloop=500, nrep=3): + units = ["s", "ms", "µs", "ns"] + scaling = [1, 1e3, 1e6, 1e9] + print("%s : %-50s : " % (v, s), end=' ') + varnames = ["%ss,nm%ss,%sl,nm%sl" % tuple(x*4) for x in 'xyz'] + setup = 'from __main__ import numpy, ma, %s' % ','.join(varnames) + Timer = timeit.Timer(stmt=s, setup=setup) + best = min(Timer.repeat(nrep, nloop)) / nloop + if best > 0.0: + order = min(-int(numpy.floor(numpy.log10(best)) // 3), 3) + else: + order = 3 + print("%d loops, best of %d: %.*g %s per loop" % (nloop, nrep, + 3, + best * scaling[order], + units[order])) + + +def compare_functions_1v(func, nloop=500, + xs=xs, nmxs=nmxs, xl=xl, nmxl=nmxl): + funcname = func.__name__ + print("-"*50) + print(f'{funcname} on small arrays') + module, data = "numpy.ma", "nmxs" + timer("%(module)s.%(funcname)s(%(data)s)" % locals(), v="%11s" % module, nloop=nloop) + + print("%s on large arrays" % funcname) + module, data = "numpy.ma", "nmxl" + timer("%(module)s.%(funcname)s(%(data)s)" % locals(), v="%11s" % module, nloop=nloop) + return + +def compare_methods(methodname, args, vars='x', nloop=500, test=True, + xs=xs, nmxs=nmxs, xl=xl, nmxl=nmxl): + print("-"*50) + print(f'{methodname} on small arrays') + data, ver = f'nm{vars}l', 'numpy.ma' + timer("%(data)s.%(methodname)s(%(args)s)" % locals(), v=ver, nloop=nloop) + + print("%s on large arrays" % methodname) + data, ver = "nm%sl" % vars, 'numpy.ma' + timer("%(data)s.%(methodname)s(%(args)s)" % locals(), v=ver, nloop=nloop) + return + +def compare_functions_2v(func, nloop=500, test=True, + xs=xs, nmxs=nmxs, + ys=ys, nmys=nmys, + xl=xl, nmxl=nmxl, + yl=yl, nmyl=nmyl): + funcname = func.__name__ + print("-"*50) + print(f'{funcname} on small arrays') + module, data = "numpy.ma", "nmxs,nmys" + timer("%(module)s.%(funcname)s(%(data)s)" % locals(), v="%11s" % module, nloop=nloop) + + print(f'{funcname} on large arrays') + module, data = "numpy.ma", "nmxl,nmyl" + timer("%(module)s.%(funcname)s(%(data)s)" % locals(), v="%11s" % module, nloop=nloop) + return + + +if __name__ == '__main__': + compare_functions_1v(numpy.sin) + compare_functions_1v(numpy.log) + compare_functions_1v(numpy.sqrt) + + compare_functions_2v(numpy.multiply) + compare_functions_2v(numpy.divide) + compare_functions_2v(numpy.power) + + compare_methods('ravel', '', nloop=1000) + compare_methods('conjugate', '', 'z', nloop=1000) + compare_methods('transpose', '', nloop=1000) + compare_methods('compressed', '', nloop=1000) + compare_methods('__getitem__', '0', nloop=1000) + compare_methods('__getitem__', '(0,0)', nloop=1000) + compare_methods('__getitem__', '[0,-1]', nloop=1000) + compare_methods('__setitem__', '0, 17', nloop=1000, test=False) + compare_methods('__setitem__', '(0,0), 17', nloop=1000, test=False) + + print("-"*50) + print("__setitem__ on small arrays") + timer('nmxs.__setitem__((-1,0),numpy.ma.masked)', 'numpy.ma ', nloop=10000) + + print("-"*50) + print("__setitem__ on large arrays") + timer('nmxl.__setitem__((-1,0),numpy.ma.masked)', 'numpy.ma ', nloop=10000) + + print("-"*50) + print("where on small arrays") + timer('numpy.ma.where(nmxs>2,nmxs,nmys)', 'numpy.ma ', nloop=1000) + print("-"*50) + print("where on large arrays") + timer('numpy.ma.where(nmxl>2,nmxl,nmyl)', 'numpy.ma ', nloop=100) diff --git a/venv/Lib/site-packages/numpy/ma/core.py b/venv/Lib/site-packages/numpy/ma/core.py new file mode 100644 index 0000000..492070b --- /dev/null +++ b/venv/Lib/site-packages/numpy/ma/core.py @@ -0,0 +1,8184 @@ +""" +numpy.ma : a package to handle missing or invalid values. + +This package was initially written for numarray by Paul F. Dubois +at Lawrence Livermore National Laboratory. +In 2006, the package was completely rewritten by Pierre Gerard-Marchant +(University of Georgia) to make the MaskedArray class a subclass of ndarray, +and to improve support of structured arrays. + + +Copyright 1999, 2000, 2001 Regents of the University of California. +Released for unlimited redistribution. + +* Adapted for numpy_core 2005 by Travis Oliphant and (mainly) Paul Dubois. +* Subclassing of the base `ndarray` 2006 by Pierre Gerard-Marchant + (pgmdevlist_AT_gmail_DOT_com) +* Improvements suggested by Reggie Dugard (reggie_AT_merfinllc_DOT_com) + +.. moduleauthor:: Pierre Gerard-Marchant + +""" +# pylint: disable-msg=E1002 +import builtins +import inspect +import operator +import warnings +import textwrap +import re +from functools import reduce + +import numpy as np +import numpy.core.umath as umath +import numpy.core.numerictypes as ntypes +from numpy import ndarray, amax, amin, iscomplexobj, bool_, _NoValue +from numpy import array as narray +from numpy.lib.function_base import angle +from numpy.compat import ( + getargspec, formatargspec, long, unicode, bytes + ) +from numpy import expand_dims +from numpy.core.numeric import normalize_axis_tuple +from numpy.core._internal import recursive +from numpy.compat import pickle + + +__all__ = [ + 'MAError', 'MaskError', 'MaskType', 'MaskedArray', 'abs', 'absolute', + 'add', 'all', 'allclose', 'allequal', 'alltrue', 'amax', 'amin', + 'angle', 'anom', 'anomalies', 'any', 'append', 'arange', 'arccos', + 'arccosh', 'arcsin', 'arcsinh', 'arctan', 'arctan2', 'arctanh', + 'argmax', 'argmin', 'argsort', 'around', 'array', 'asanyarray', + 'asarray', 'bitwise_and', 'bitwise_or', 'bitwise_xor', 'bool_', 'ceil', + 'choose', 'clip', 'common_fill_value', 'compress', 'compressed', + 'concatenate', 'conjugate', 'convolve', 'copy', 'correlate', 'cos', 'cosh', + 'count', 'cumprod', 'cumsum', 'default_fill_value', 'diag', 'diagonal', + 'diff', 'divide', 'empty', 'empty_like', 'equal', 'exp', + 'expand_dims', 'fabs', 'filled', 'fix_invalid', 'flatten_mask', + 'flatten_structured_array', 'floor', 'floor_divide', 'fmod', + 'frombuffer', 'fromflex', 'fromfunction', 'getdata', 'getmask', + 'getmaskarray', 'greater', 'greater_equal', 'harden_mask', 'hypot', + 'identity', 'ids', 'indices', 'inner', 'innerproduct', 'isMA', + 'isMaskedArray', 'is_mask', 'is_masked', 'isarray', 'left_shift', + 'less', 'less_equal', 'log', 'log10', 'log2', + 'logical_and', 'logical_not', 'logical_or', 'logical_xor', 'make_mask', + 'make_mask_descr', 'make_mask_none', 'mask_or', 'masked', + 'masked_array', 'masked_equal', 'masked_greater', + 'masked_greater_equal', 'masked_inside', 'masked_invalid', + 'masked_less', 'masked_less_equal', 'masked_not_equal', + 'masked_object', 'masked_outside', 'masked_print_option', + 'masked_singleton', 'masked_values', 'masked_where', 'max', 'maximum', + 'maximum_fill_value', 'mean', 'min', 'minimum', 'minimum_fill_value', + 'mod', 'multiply', 'mvoid', 'ndim', 'negative', 'nomask', 'nonzero', + 'not_equal', 'ones', 'outer', 'outerproduct', 'power', 'prod', + 'product', 'ptp', 'put', 'putmask', 'ravel', 'remainder', + 'repeat', 'reshape', 'resize', 'right_shift', 'round', 'round_', + 'set_fill_value', 'shape', 'sin', 'sinh', 'size', 'soften_mask', + 'sometrue', 'sort', 'sqrt', 'squeeze', 'std', 'subtract', 'sum', + 'swapaxes', 'take', 'tan', 'tanh', 'trace', 'transpose', 'true_divide', + 'var', 'where', 'zeros', + ] + +MaskType = np.bool_ +nomask = MaskType(0) + +class MaskedArrayFutureWarning(FutureWarning): + pass + +def _deprecate_argsort_axis(arr): + """ + Adjust the axis passed to argsort, warning if necessary + + Parameters + ---------- + arr + The array which argsort was called on + + np.ma.argsort has a long-term bug where the default of the axis argument + is wrong (gh-8701), which now must be kept for backwards compatibility. + Thankfully, this only makes a difference when arrays are 2- or more- + dimensional, so we only need a warning then. + """ + if arr.ndim <= 1: + # no warning needed - but switch to -1 anyway, to avoid surprising + # subclasses, which are more likely to implement scalar axes. + return -1 + else: + # 2017-04-11, Numpy 1.13.0, gh-8701: warn on axis default + warnings.warn( + "In the future the default for argsort will be axis=-1, not the " + "current None, to match its documentation and np.argsort. " + "Explicitly pass -1 or None to silence this warning.", + MaskedArrayFutureWarning, stacklevel=3) + return None + + +def doc_note(initialdoc, note): + """ + Adds a Notes section to an existing docstring. + + """ + if initialdoc is None: + return + if note is None: + return initialdoc + + notesplit = re.split(r'\n\s*?Notes\n\s*?-----', inspect.cleandoc(initialdoc)) + notedoc = "\n\nNotes\n-----\n%s\n" % inspect.cleandoc(note) + + return ''.join(notesplit[:1] + [notedoc] + notesplit[1:]) + + +def get_object_signature(obj): + """ + Get the signature from obj + + """ + try: + sig = formatargspec(*getargspec(obj)) + except TypeError: + sig = '' + return sig + + +############################################################################### +# Exceptions # +############################################################################### + + +class MAError(Exception): + """ + Class for masked array related errors. + + """ + pass + + +class MaskError(MAError): + """ + Class for mask related errors. + + """ + pass + + +############################################################################### +# Filling options # +############################################################################### + + +# b: boolean - c: complex - f: floats - i: integer - O: object - S: string +default_filler = {'b': True, + 'c': 1.e20 + 0.0j, + 'f': 1.e20, + 'i': 999999, + 'O': '?', + 'S': b'N/A', + 'u': 999999, + 'V': b'???', + 'U': u'N/A' + } + +# Add datetime64 and timedelta64 types +for v in ["Y", "M", "W", "D", "h", "m", "s", "ms", "us", "ns", "ps", + "fs", "as"]: + default_filler["M8[" + v + "]"] = np.datetime64("NaT", v) + default_filler["m8[" + v + "]"] = np.timedelta64("NaT", v) + +float_types_list = [np.half, np.single, np.double, np.longdouble, + np.csingle, np.cdouble, np.clongdouble] +max_filler = ntypes._minvals +max_filler.update([(k, -np.inf) for k in float_types_list[:4]]) +max_filler.update([(k, complex(-np.inf, -np.inf)) for k in float_types_list[-3:]]) + +min_filler = ntypes._maxvals +min_filler.update([(k, +np.inf) for k in float_types_list[:4]]) +min_filler.update([(k, complex(+np.inf, +np.inf)) for k in float_types_list[-3:]]) + +del float_types_list + +def _recursive_fill_value(dtype, f): + """ + Recursively produce a fill value for `dtype`, calling f on scalar dtypes + """ + if dtype.names is not None: + vals = tuple(_recursive_fill_value(dtype[name], f) for name in dtype.names) + return np.array(vals, dtype=dtype)[()] # decay to void scalar from 0d + elif dtype.subdtype: + subtype, shape = dtype.subdtype + subval = _recursive_fill_value(subtype, f) + return np.full(shape, subval) + else: + return f(dtype) + + +def _get_dtype_of(obj): + """ Convert the argument for *_fill_value into a dtype """ + if isinstance(obj, np.dtype): + return obj + elif hasattr(obj, 'dtype'): + return obj.dtype + else: + return np.asanyarray(obj).dtype + + +def default_fill_value(obj): + """ + Return the default fill value for the argument object. + + The default filling value depends on the datatype of the input + array or the type of the input scalar: + + ======== ======== + datatype default + ======== ======== + bool True + int 999999 + float 1.e20 + complex 1.e20+0j + object '?' + string 'N/A' + ======== ======== + + For structured types, a structured scalar is returned, with each field the + default fill value for its type. + + For subarray types, the fill value is an array of the same size containing + the default scalar fill value. + + Parameters + ---------- + obj : ndarray, dtype or scalar + The array data-type or scalar for which the default fill value + is returned. + + Returns + ------- + fill_value : scalar + The default fill value. + + Examples + -------- + >>> np.ma.default_fill_value(1) + 999999 + >>> np.ma.default_fill_value(np.array([1.1, 2., np.pi])) + 1e+20 + >>> np.ma.default_fill_value(np.dtype(complex)) + (1e+20+0j) + + """ + def _scalar_fill_value(dtype): + if dtype.kind in 'Mm': + return default_filler.get(dtype.str[1:], '?') + else: + return default_filler.get(dtype.kind, '?') + + dtype = _get_dtype_of(obj) + return _recursive_fill_value(dtype, _scalar_fill_value) + + +def _extremum_fill_value(obj, extremum, extremum_name): + + def _scalar_fill_value(dtype): + try: + return extremum[dtype] + except KeyError as e: + raise TypeError( + f"Unsuitable type {dtype} for calculating {extremum_name}." + ) from None + + dtype = _get_dtype_of(obj) + return _recursive_fill_value(dtype, _scalar_fill_value) + + +def minimum_fill_value(obj): + """ + Return the maximum value that can be represented by the dtype of an object. + + This function is useful for calculating a fill value suitable for + taking the minimum of an array with a given dtype. + + Parameters + ---------- + obj : ndarray, dtype or scalar + An object that can be queried for it's numeric type. + + Returns + ------- + val : scalar + The maximum representable value. + + Raises + ------ + TypeError + If `obj` isn't a suitable numeric type. + + See Also + -------- + maximum_fill_value : The inverse function. + set_fill_value : Set the filling value of a masked array. + MaskedArray.fill_value : Return current fill value. + + Examples + -------- + >>> import numpy.ma as ma + >>> a = np.int8() + >>> ma.minimum_fill_value(a) + 127 + >>> a = np.int32() + >>> ma.minimum_fill_value(a) + 2147483647 + + An array of numeric data can also be passed. + + >>> a = np.array([1, 2, 3], dtype=np.int8) + >>> ma.minimum_fill_value(a) + 127 + >>> a = np.array([1, 2, 3], dtype=np.float32) + >>> ma.minimum_fill_value(a) + inf + + """ + return _extremum_fill_value(obj, min_filler, "minimum") + + +def maximum_fill_value(obj): + """ + Return the minimum value that can be represented by the dtype of an object. + + This function is useful for calculating a fill value suitable for + taking the maximum of an array with a given dtype. + + Parameters + ---------- + obj : ndarray, dtype or scalar + An object that can be queried for it's numeric type. + + Returns + ------- + val : scalar + The minimum representable value. + + Raises + ------ + TypeError + If `obj` isn't a suitable numeric type. + + See Also + -------- + minimum_fill_value : The inverse function. + set_fill_value : Set the filling value of a masked array. + MaskedArray.fill_value : Return current fill value. + + Examples + -------- + >>> import numpy.ma as ma + >>> a = np.int8() + >>> ma.maximum_fill_value(a) + -128 + >>> a = np.int32() + >>> ma.maximum_fill_value(a) + -2147483648 + + An array of numeric data can also be passed. + + >>> a = np.array([1, 2, 3], dtype=np.int8) + >>> ma.maximum_fill_value(a) + -128 + >>> a = np.array([1, 2, 3], dtype=np.float32) + >>> ma.maximum_fill_value(a) + -inf + + """ + return _extremum_fill_value(obj, max_filler, "maximum") + + +def _recursive_set_fill_value(fillvalue, dt): + """ + Create a fill value for a structured dtype. + + Parameters + ---------- + fillvalue: scalar or array_like + Scalar or array representing the fill value. If it is of shorter + length than the number of fields in dt, it will be resized. + dt: dtype + The structured dtype for which to create the fill value. + + Returns + ------- + val: tuple + A tuple of values corresponding to the structured fill value. + + """ + fillvalue = np.resize(fillvalue, len(dt.names)) + output_value = [] + for (fval, name) in zip(fillvalue, dt.names): + cdtype = dt[name] + if cdtype.subdtype: + cdtype = cdtype.subdtype[0] + + if cdtype.names is not None: + output_value.append(tuple(_recursive_set_fill_value(fval, cdtype))) + else: + output_value.append(np.array(fval, dtype=cdtype).item()) + return tuple(output_value) + + +def _check_fill_value(fill_value, ndtype): + """ + Private function validating the given `fill_value` for the given dtype. + + If fill_value is None, it is set to the default corresponding to the dtype. + + If fill_value is not None, its value is forced to the given dtype. + + The result is always a 0d array. + + """ + ndtype = np.dtype(ndtype) + if fill_value is None: + fill_value = default_fill_value(ndtype) + elif ndtype.names is not None: + if isinstance(fill_value, (ndarray, np.void)): + try: + fill_value = np.array(fill_value, copy=False, dtype=ndtype) + except ValueError as e: + err_msg = "Unable to transform %s to dtype %s" + raise ValueError(err_msg % (fill_value, ndtype)) from e + else: + fill_value = np.asarray(fill_value, dtype=object) + fill_value = np.array(_recursive_set_fill_value(fill_value, ndtype), + dtype=ndtype) + else: + if isinstance(fill_value, str) and (ndtype.char not in 'OSVU'): + # Note this check doesn't work if fill_value is not a scalar + err_msg = "Cannot set fill value of string with array of dtype %s" + raise TypeError(err_msg % ndtype) + else: + # In case we want to convert 1e20 to int. + # Also in case of converting string arrays. + try: + fill_value = np.array(fill_value, copy=False, dtype=ndtype) + except (OverflowError, ValueError) as e: + # Raise TypeError instead of OverflowError or ValueError. + # OverflowError is seldom used, and the real problem here is + # that the passed fill_value is not compatible with the ndtype. + err_msg = "Cannot convert fill_value %s to dtype %s" + raise TypeError(err_msg % (fill_value, ndtype)) from e + return np.array(fill_value) + + +def set_fill_value(a, fill_value): + """ + Set the filling value of a, if a is a masked array. + + This function changes the fill value of the masked array `a` in place. + If `a` is not a masked array, the function returns silently, without + doing anything. + + Parameters + ---------- + a : array_like + Input array. + fill_value : dtype + Filling value. A consistency test is performed to make sure + the value is compatible with the dtype of `a`. + + Returns + ------- + None + Nothing returned by this function. + + See Also + -------- + maximum_fill_value : Return the default fill value for a dtype. + MaskedArray.fill_value : Return current fill value. + MaskedArray.set_fill_value : Equivalent method. + + Examples + -------- + >>> import numpy.ma as ma + >>> a = np.arange(5) + >>> a + array([0, 1, 2, 3, 4]) + >>> a = ma.masked_where(a < 3, a) + >>> a + masked_array(data=[--, --, --, 3, 4], + mask=[ True, True, True, False, False], + fill_value=999999) + >>> ma.set_fill_value(a, -999) + >>> a + masked_array(data=[--, --, --, 3, 4], + mask=[ True, True, True, False, False], + fill_value=-999) + + Nothing happens if `a` is not a masked array. + + >>> a = list(range(5)) + >>> a + [0, 1, 2, 3, 4] + >>> ma.set_fill_value(a, 100) + >>> a + [0, 1, 2, 3, 4] + >>> a = np.arange(5) + >>> a + array([0, 1, 2, 3, 4]) + >>> ma.set_fill_value(a, 100) + >>> a + array([0, 1, 2, 3, 4]) + + """ + if isinstance(a, MaskedArray): + a.set_fill_value(fill_value) + return + + +def get_fill_value(a): + """ + Return the filling value of a, if any. Otherwise, returns the + default filling value for that type. + + """ + if isinstance(a, MaskedArray): + result = a.fill_value + else: + result = default_fill_value(a) + return result + + +def common_fill_value(a, b): + """ + Return the common filling value of two masked arrays, if any. + + If ``a.fill_value == b.fill_value``, return the fill value, + otherwise return None. + + Parameters + ---------- + a, b : MaskedArray + The masked arrays for which to compare fill values. + + Returns + ------- + fill_value : scalar or None + The common fill value, or None. + + Examples + -------- + >>> x = np.ma.array([0, 1.], fill_value=3) + >>> y = np.ma.array([0, 1.], fill_value=3) + >>> np.ma.common_fill_value(x, y) + 3.0 + + """ + t1 = get_fill_value(a) + t2 = get_fill_value(b) + if t1 == t2: + return t1 + return None + + +def filled(a, fill_value=None): + """ + Return input as an array with masked data replaced by a fill value. + + If `a` is not a `MaskedArray`, `a` itself is returned. + If `a` is a `MaskedArray` and `fill_value` is None, `fill_value` is set to + ``a.fill_value``. + + Parameters + ---------- + a : MaskedArray or array_like + An input object. + fill_value : array_like, optional. + Can be scalar or non-scalar. If non-scalar, the + resulting filled array should be broadcastable + over input array. Default is None. + + Returns + ------- + a : ndarray + The filled array. + + See Also + -------- + compressed + + Examples + -------- + >>> x = np.ma.array(np.arange(9).reshape(3, 3), mask=[[1, 0, 0], + ... [1, 0, 0], + ... [0, 0, 0]]) + >>> x.filled() + array([[999999, 1, 2], + [999999, 4, 5], + [ 6, 7, 8]]) + >>> x.filled(fill_value=333) + array([[333, 1, 2], + [333, 4, 5], + [ 6, 7, 8]]) + >>> x.filled(fill_value=np.arange(3)) + array([[0, 1, 2], + [0, 4, 5], + [6, 7, 8]]) + + """ + if hasattr(a, 'filled'): + return a.filled(fill_value) + + elif isinstance(a, ndarray): + # Should we check for contiguity ? and a.flags['CONTIGUOUS']: + return a + elif isinstance(a, dict): + return np.array(a, 'O') + else: + return np.array(a) + + +def get_masked_subclass(*arrays): + """ + Return the youngest subclass of MaskedArray from a list of (masked) arrays. + + In case of siblings, the first listed takes over. + + """ + if len(arrays) == 1: + arr = arrays[0] + if isinstance(arr, MaskedArray): + rcls = type(arr) + else: + rcls = MaskedArray + else: + arrcls = [type(a) for a in arrays] + rcls = arrcls[0] + if not issubclass(rcls, MaskedArray): + rcls = MaskedArray + for cls in arrcls[1:]: + if issubclass(cls, rcls): + rcls = cls + # Don't return MaskedConstant as result: revert to MaskedArray + if rcls.__name__ == 'MaskedConstant': + return MaskedArray + return rcls + + +def getdata(a, subok=True): + """ + Return the data of a masked array as an ndarray. + + Return the data of `a` (if any) as an ndarray if `a` is a ``MaskedArray``, + else return `a` as a ndarray or subclass (depending on `subok`) if not. + + Parameters + ---------- + a : array_like + Input ``MaskedArray``, alternatively a ndarray or a subclass thereof. + subok : bool + Whether to force the output to be a `pure` ndarray (False) or to + return a subclass of ndarray if appropriate (True, default). + + See Also + -------- + getmask : Return the mask of a masked array, or nomask. + getmaskarray : Return the mask of a masked array, or full array of False. + + Examples + -------- + >>> import numpy.ma as ma + >>> a = ma.masked_equal([[1,2],[3,4]], 2) + >>> a + masked_array( + data=[[1, --], + [3, 4]], + mask=[[False, True], + [False, False]], + fill_value=2) + >>> ma.getdata(a) + array([[1, 2], + [3, 4]]) + + Equivalently use the ``MaskedArray`` `data` attribute. + + >>> a.data + array([[1, 2], + [3, 4]]) + + """ + try: + data = a._data + except AttributeError: + data = np.array(a, copy=False, subok=subok) + if not subok: + return data.view(ndarray) + return data + + +get_data = getdata + + +def fix_invalid(a, mask=nomask, copy=True, fill_value=None): + """ + Return input with invalid data masked and replaced by a fill value. + + Invalid data means values of `nan`, `inf`, etc. + + Parameters + ---------- + a : array_like + Input array, a (subclass of) ndarray. + mask : sequence, optional + Mask. Must be convertible to an array of booleans with the same + shape as `data`. True indicates a masked (i.e. invalid) data. + copy : bool, optional + Whether to use a copy of `a` (True) or to fix `a` in place (False). + Default is True. + fill_value : scalar, optional + Value used for fixing invalid data. Default is None, in which case + the ``a.fill_value`` is used. + + Returns + ------- + b : MaskedArray + The input array with invalid entries fixed. + + Notes + ----- + A copy is performed by default. + + Examples + -------- + >>> x = np.ma.array([1., -1, np.nan, np.inf], mask=[1] + [0]*3) + >>> x + masked_array(data=[--, -1.0, nan, inf], + mask=[ True, False, False, False], + fill_value=1e+20) + >>> np.ma.fix_invalid(x) + masked_array(data=[--, -1.0, --, --], + mask=[ True, False, True, True], + fill_value=1e+20) + + >>> fixed = np.ma.fix_invalid(x) + >>> fixed.data + array([ 1.e+00, -1.e+00, 1.e+20, 1.e+20]) + >>> x.data + array([ 1., -1., nan, inf]) + + """ + a = masked_array(a, copy=copy, mask=mask, subok=True) + invalid = np.logical_not(np.isfinite(a._data)) + if not invalid.any(): + return a + a._mask |= invalid + if fill_value is None: + fill_value = a.fill_value + a._data[invalid] = fill_value + return a + +def is_string_or_list_of_strings(val): + return (isinstance(val, str) or + (isinstance(val, list) and val and + builtins.all(isinstance(s, str) for s in val))) + +############################################################################### +# Ufuncs # +############################################################################### + + +ufunc_domain = {} +ufunc_fills = {} + + +class _DomainCheckInterval: + """ + Define a valid interval, so that : + + ``domain_check_interval(a,b)(x) == True`` where + ``x < a`` or ``x > b``. + + """ + + def __init__(self, a, b): + "domain_check_interval(a,b)(x) = true where x < a or y > b" + if a > b: + (a, b) = (b, a) + self.a = a + self.b = b + + def __call__(self, x): + "Execute the call behavior." + # nans at masked positions cause RuntimeWarnings, even though + # they are masked. To avoid this we suppress warnings. + with np.errstate(invalid='ignore'): + return umath.logical_or(umath.greater(x, self.b), + umath.less(x, self.a)) + + +class _DomainTan: + """ + Define a valid interval for the `tan` function, so that: + + ``domain_tan(eps) = True`` where ``abs(cos(x)) < eps`` + + """ + + def __init__(self, eps): + "domain_tan(eps) = true where abs(cos(x)) < eps)" + self.eps = eps + + def __call__(self, x): + "Executes the call behavior." + with np.errstate(invalid='ignore'): + return umath.less(umath.absolute(umath.cos(x)), self.eps) + + +class _DomainSafeDivide: + """ + Define a domain for safe division. + + """ + + def __init__(self, tolerance=None): + self.tolerance = tolerance + + def __call__(self, a, b): + # Delay the selection of the tolerance to here in order to reduce numpy + # import times. The calculation of these parameters is a substantial + # component of numpy's import time. + if self.tolerance is None: + self.tolerance = np.finfo(float).tiny + # don't call ma ufuncs from __array_wrap__ which would fail for scalars + a, b = np.asarray(a), np.asarray(b) + with np.errstate(invalid='ignore'): + return umath.absolute(a) * self.tolerance >= umath.absolute(b) + + +class _DomainGreater: + """ + DomainGreater(v)(x) is True where x <= v. + + """ + + def __init__(self, critical_value): + "DomainGreater(v)(x) = true where x <= v" + self.critical_value = critical_value + + def __call__(self, x): + "Executes the call behavior." + with np.errstate(invalid='ignore'): + return umath.less_equal(x, self.critical_value) + + +class _DomainGreaterEqual: + """ + DomainGreaterEqual(v)(x) is True where x < v. + + """ + + def __init__(self, critical_value): + "DomainGreaterEqual(v)(x) = true where x < v" + self.critical_value = critical_value + + def __call__(self, x): + "Executes the call behavior." + with np.errstate(invalid='ignore'): + return umath.less(x, self.critical_value) + + +class _MaskedUFunc: + def __init__(self, ufunc): + self.f = ufunc + self.__doc__ = ufunc.__doc__ + self.__name__ = ufunc.__name__ + + def __str__(self): + return f"Masked version of {self.f}" + + +class _MaskedUnaryOperation(_MaskedUFunc): + """ + Defines masked version of unary operations, where invalid values are + pre-masked. + + Parameters + ---------- + mufunc : callable + The function for which to define a masked version. Made available + as ``_MaskedUnaryOperation.f``. + fill : scalar, optional + Filling value, default is 0. + domain : class instance + Domain for the function. Should be one of the ``_Domain*`` + classes. Default is None. + + """ + + def __init__(self, mufunc, fill=0, domain=None): + super(_MaskedUnaryOperation, self).__init__(mufunc) + self.fill = fill + self.domain = domain + ufunc_domain[mufunc] = domain + ufunc_fills[mufunc] = fill + + def __call__(self, a, *args, **kwargs): + """ + Execute the call behavior. + + """ + d = getdata(a) + # Deal with domain + if self.domain is not None: + # Case 1.1. : Domained function + # nans at masked positions cause RuntimeWarnings, even though + # they are masked. To avoid this we suppress warnings. + with np.errstate(divide='ignore', invalid='ignore'): + result = self.f(d, *args, **kwargs) + # Make a mask + m = ~umath.isfinite(result) + m |= self.domain(d) + m |= getmask(a) + else: + # Case 1.2. : Function without a domain + # Get the result and the mask + with np.errstate(divide='ignore', invalid='ignore'): + result = self.f(d, *args, **kwargs) + m = getmask(a) + + if not result.ndim: + # Case 2.1. : The result is scalarscalar + if m: + return masked + return result + + if m is not nomask: + # Case 2.2. The result is an array + # We need to fill the invalid data back w/ the input Now, + # that's plain silly: in C, we would just skip the element and + # keep the original, but we do have to do it that way in Python + + # In case result has a lower dtype than the inputs (as in + # equal) + try: + np.copyto(result, d, where=m) + except TypeError: + pass + # Transform to + masked_result = result.view(get_masked_subclass(a)) + masked_result._mask = m + masked_result._update_from(a) + return masked_result + + +class _MaskedBinaryOperation(_MaskedUFunc): + """ + Define masked version of binary operations, where invalid + values are pre-masked. + + Parameters + ---------- + mbfunc : function + The function for which to define a masked version. Made available + as ``_MaskedBinaryOperation.f``. + domain : class instance + Default domain for the function. Should be one of the ``_Domain*`` + classes. Default is None. + fillx : scalar, optional + Filling value for the first argument, default is 0. + filly : scalar, optional + Filling value for the second argument, default is 0. + + """ + + def __init__(self, mbfunc, fillx=0, filly=0): + """ + abfunc(fillx, filly) must be defined. + + abfunc(x, filly) = x for all x to enable reduce. + + """ + super(_MaskedBinaryOperation, self).__init__(mbfunc) + self.fillx = fillx + self.filly = filly + ufunc_domain[mbfunc] = None + ufunc_fills[mbfunc] = (fillx, filly) + + def __call__(self, a, b, *args, **kwargs): + """ + Execute the call behavior. + + """ + # Get the data, as ndarray + (da, db) = (getdata(a), getdata(b)) + # Get the result + with np.errstate(): + np.seterr(divide='ignore', invalid='ignore') + result = self.f(da, db, *args, **kwargs) + # Get the mask for the result + (ma, mb) = (getmask(a), getmask(b)) + if ma is nomask: + if mb is nomask: + m = nomask + else: + m = umath.logical_or(getmaskarray(a), mb) + elif mb is nomask: + m = umath.logical_or(ma, getmaskarray(b)) + else: + m = umath.logical_or(ma, mb) + + # Case 1. : scalar + if not result.ndim: + if m: + return masked + return result + + # Case 2. : array + # Revert result to da where masked + if m is not nomask and m.any(): + # any errors, just abort; impossible to guarantee masked values + try: + np.copyto(result, da, casting='unsafe', where=m) + except Exception: + pass + + # Transforms to a (subclass of) MaskedArray + masked_result = result.view(get_masked_subclass(a, b)) + masked_result._mask = m + if isinstance(a, MaskedArray): + masked_result._update_from(a) + elif isinstance(b, MaskedArray): + masked_result._update_from(b) + return masked_result + + def reduce(self, target, axis=0, dtype=None): + """ + Reduce `target` along the given `axis`. + + """ + tclass = get_masked_subclass(target) + m = getmask(target) + t = filled(target, self.filly) + if t.shape == (): + t = t.reshape(1) + if m is not nomask: + m = make_mask(m, copy=True) + m.shape = (1,) + + if m is nomask: + tr = self.f.reduce(t, axis) + mr = nomask + else: + tr = self.f.reduce(t, axis, dtype=dtype or t.dtype) + mr = umath.logical_and.reduce(m, axis) + + if not tr.shape: + if mr: + return masked + else: + return tr + masked_tr = tr.view(tclass) + masked_tr._mask = mr + return masked_tr + + def outer(self, a, b): + """ + Return the function applied to the outer product of a and b. + + """ + (da, db) = (getdata(a), getdata(b)) + d = self.f.outer(da, db) + ma = getmask(a) + mb = getmask(b) + if ma is nomask and mb is nomask: + m = nomask + else: + ma = getmaskarray(a) + mb = getmaskarray(b) + m = umath.logical_or.outer(ma, mb) + if (not m.ndim) and m: + return masked + if m is not nomask: + np.copyto(d, da, where=m) + if not d.shape: + return d + masked_d = d.view(get_masked_subclass(a, b)) + masked_d._mask = m + return masked_d + + def accumulate(self, target, axis=0): + """Accumulate `target` along `axis` after filling with y fill + value. + + """ + tclass = get_masked_subclass(target) + t = filled(target, self.filly) + result = self.f.accumulate(t, axis) + masked_result = result.view(tclass) + return masked_result + + + +class _DomainedBinaryOperation(_MaskedUFunc): + """ + Define binary operations that have a domain, like divide. + + They have no reduce, outer or accumulate. + + Parameters + ---------- + mbfunc : function + The function for which to define a masked version. Made available + as ``_DomainedBinaryOperation.f``. + domain : class instance + Default domain for the function. Should be one of the ``_Domain*`` + classes. + fillx : scalar, optional + Filling value for the first argument, default is 0. + filly : scalar, optional + Filling value for the second argument, default is 0. + + """ + + def __init__(self, dbfunc, domain, fillx=0, filly=0): + """abfunc(fillx, filly) must be defined. + abfunc(x, filly) = x for all x to enable reduce. + """ + super(_DomainedBinaryOperation, self).__init__(dbfunc) + self.domain = domain + self.fillx = fillx + self.filly = filly + ufunc_domain[dbfunc] = domain + ufunc_fills[dbfunc] = (fillx, filly) + + def __call__(self, a, b, *args, **kwargs): + "Execute the call behavior." + # Get the data + (da, db) = (getdata(a), getdata(b)) + # Get the result + with np.errstate(divide='ignore', invalid='ignore'): + result = self.f(da, db, *args, **kwargs) + # Get the mask as a combination of the source masks and invalid + m = ~umath.isfinite(result) + m |= getmask(a) + m |= getmask(b) + # Apply the domain + domain = ufunc_domain.get(self.f, None) + if domain is not None: + m |= domain(da, db) + # Take care of the scalar case first + if not m.ndim: + if m: + return masked + else: + return result + # When the mask is True, put back da if possible + # any errors, just abort; impossible to guarantee masked values + try: + np.copyto(result, 0, casting='unsafe', where=m) + # avoid using "*" since this may be overlaid + masked_da = umath.multiply(m, da) + # only add back if it can be cast safely + if np.can_cast(masked_da.dtype, result.dtype, casting='safe'): + result += masked_da + except Exception: + pass + + # Transforms to a (subclass of) MaskedArray + masked_result = result.view(get_masked_subclass(a, b)) + masked_result._mask = m + if isinstance(a, MaskedArray): + masked_result._update_from(a) + elif isinstance(b, MaskedArray): + masked_result._update_from(b) + return masked_result + + +# Unary ufuncs +exp = _MaskedUnaryOperation(umath.exp) +conjugate = _MaskedUnaryOperation(umath.conjugate) +sin = _MaskedUnaryOperation(umath.sin) +cos = _MaskedUnaryOperation(umath.cos) +arctan = _MaskedUnaryOperation(umath.arctan) +arcsinh = _MaskedUnaryOperation(umath.arcsinh) +sinh = _MaskedUnaryOperation(umath.sinh) +cosh = _MaskedUnaryOperation(umath.cosh) +tanh = _MaskedUnaryOperation(umath.tanh) +abs = absolute = _MaskedUnaryOperation(umath.absolute) +angle = _MaskedUnaryOperation(angle) # from numpy.lib.function_base +fabs = _MaskedUnaryOperation(umath.fabs) +negative = _MaskedUnaryOperation(umath.negative) +floor = _MaskedUnaryOperation(umath.floor) +ceil = _MaskedUnaryOperation(umath.ceil) +around = _MaskedUnaryOperation(np.round_) +logical_not = _MaskedUnaryOperation(umath.logical_not) + +# Domained unary ufuncs +sqrt = _MaskedUnaryOperation(umath.sqrt, 0.0, + _DomainGreaterEqual(0.0)) +log = _MaskedUnaryOperation(umath.log, 1.0, + _DomainGreater(0.0)) +log2 = _MaskedUnaryOperation(umath.log2, 1.0, + _DomainGreater(0.0)) +log10 = _MaskedUnaryOperation(umath.log10, 1.0, + _DomainGreater(0.0)) +tan = _MaskedUnaryOperation(umath.tan, 0.0, + _DomainTan(1e-35)) +arcsin = _MaskedUnaryOperation(umath.arcsin, 0.0, + _DomainCheckInterval(-1.0, 1.0)) +arccos = _MaskedUnaryOperation(umath.arccos, 0.0, + _DomainCheckInterval(-1.0, 1.0)) +arccosh = _MaskedUnaryOperation(umath.arccosh, 1.0, + _DomainGreaterEqual(1.0)) +arctanh = _MaskedUnaryOperation(umath.arctanh, 0.0, + _DomainCheckInterval(-1.0 + 1e-15, 1.0 - 1e-15)) + +# Binary ufuncs +add = _MaskedBinaryOperation(umath.add) +subtract = _MaskedBinaryOperation(umath.subtract) +multiply = _MaskedBinaryOperation(umath.multiply, 1, 1) +arctan2 = _MaskedBinaryOperation(umath.arctan2, 0.0, 1.0) +equal = _MaskedBinaryOperation(umath.equal) +equal.reduce = None +not_equal = _MaskedBinaryOperation(umath.not_equal) +not_equal.reduce = None +less_equal = _MaskedBinaryOperation(umath.less_equal) +less_equal.reduce = None +greater_equal = _MaskedBinaryOperation(umath.greater_equal) +greater_equal.reduce = None +less = _MaskedBinaryOperation(umath.less) +less.reduce = None +greater = _MaskedBinaryOperation(umath.greater) +greater.reduce = None +logical_and = _MaskedBinaryOperation(umath.logical_and) +alltrue = _MaskedBinaryOperation(umath.logical_and, 1, 1).reduce +logical_or = _MaskedBinaryOperation(umath.logical_or) +sometrue = logical_or.reduce +logical_xor = _MaskedBinaryOperation(umath.logical_xor) +bitwise_and = _MaskedBinaryOperation(umath.bitwise_and) +bitwise_or = _MaskedBinaryOperation(umath.bitwise_or) +bitwise_xor = _MaskedBinaryOperation(umath.bitwise_xor) +hypot = _MaskedBinaryOperation(umath.hypot) + +# Domained binary ufuncs +divide = _DomainedBinaryOperation(umath.divide, _DomainSafeDivide(), 0, 1) +true_divide = _DomainedBinaryOperation(umath.true_divide, + _DomainSafeDivide(), 0, 1) +floor_divide = _DomainedBinaryOperation(umath.floor_divide, + _DomainSafeDivide(), 0, 1) +remainder = _DomainedBinaryOperation(umath.remainder, + _DomainSafeDivide(), 0, 1) +fmod = _DomainedBinaryOperation(umath.fmod, _DomainSafeDivide(), 0, 1) +mod = _DomainedBinaryOperation(umath.mod, _DomainSafeDivide(), 0, 1) + + +############################################################################### +# Mask creation functions # +############################################################################### + + +def _replace_dtype_fields_recursive(dtype, primitive_dtype): + "Private function allowing recursion in _replace_dtype_fields." + _recurse = _replace_dtype_fields_recursive + + # Do we have some name fields ? + if dtype.names is not None: + descr = [] + for name in dtype.names: + field = dtype.fields[name] + if len(field) == 3: + # Prepend the title to the name + name = (field[-1], name) + descr.append((name, _recurse(field[0], primitive_dtype))) + new_dtype = np.dtype(descr) + + # Is this some kind of composite a la (float,2) + elif dtype.subdtype: + descr = list(dtype.subdtype) + descr[0] = _recurse(dtype.subdtype[0], primitive_dtype) + new_dtype = np.dtype(tuple(descr)) + + # this is a primitive type, so do a direct replacement + else: + new_dtype = primitive_dtype + + # preserve identity of dtypes + if new_dtype == dtype: + new_dtype = dtype + + return new_dtype + + +def _replace_dtype_fields(dtype, primitive_dtype): + """ + Construct a dtype description list from a given dtype. + + Returns a new dtype object, with all fields and subtypes in the given type + recursively replaced with `primitive_dtype`. + + Arguments are coerced to dtypes first. + """ + dtype = np.dtype(dtype) + primitive_dtype = np.dtype(primitive_dtype) + return _replace_dtype_fields_recursive(dtype, primitive_dtype) + + +def make_mask_descr(ndtype): + """ + Construct a dtype description list from a given dtype. + + Returns a new dtype object, with the type of all fields in `ndtype` to a + boolean type. Field names are not altered. + + Parameters + ---------- + ndtype : dtype + The dtype to convert. + + Returns + ------- + result : dtype + A dtype that looks like `ndtype`, the type of all fields is boolean. + + Examples + -------- + >>> import numpy.ma as ma + >>> dtype = np.dtype({'names':['foo', 'bar'], + ... 'formats':[np.float32, np.int64]}) + >>> dtype + dtype([('foo', '>> ma.make_mask_descr(dtype) + dtype([('foo', '|b1'), ('bar', '|b1')]) + >>> ma.make_mask_descr(np.float32) + dtype('bool') + + """ + return _replace_dtype_fields(ndtype, MaskType) + + +def getmask(a): + """ + Return the mask of a masked array, or nomask. + + Return the mask of `a` as an ndarray if `a` is a `MaskedArray` and the + mask is not `nomask`, else return `nomask`. To guarantee a full array + of booleans of the same shape as a, use `getmaskarray`. + + Parameters + ---------- + a : array_like + Input `MaskedArray` for which the mask is required. + + See Also + -------- + getdata : Return the data of a masked array as an ndarray. + getmaskarray : Return the mask of a masked array, or full array of False. + + Examples + -------- + >>> import numpy.ma as ma + >>> a = ma.masked_equal([[1,2],[3,4]], 2) + >>> a + masked_array( + data=[[1, --], + [3, 4]], + mask=[[False, True], + [False, False]], + fill_value=2) + >>> ma.getmask(a) + array([[False, True], + [False, False]]) + + Equivalently use the `MaskedArray` `mask` attribute. + + >>> a.mask + array([[False, True], + [False, False]]) + + Result when mask == `nomask` + + >>> b = ma.masked_array([[1,2],[3,4]]) + >>> b + masked_array( + data=[[1, 2], + [3, 4]], + mask=False, + fill_value=999999) + >>> ma.nomask + False + >>> ma.getmask(b) == ma.nomask + True + >>> b.mask == ma.nomask + True + + """ + return getattr(a, '_mask', nomask) + + +get_mask = getmask + + +def getmaskarray(arr): + """ + Return the mask of a masked array, or full boolean array of False. + + Return the mask of `arr` as an ndarray if `arr` is a `MaskedArray` and + the mask is not `nomask`, else return a full boolean array of False of + the same shape as `arr`. + + Parameters + ---------- + arr : array_like + Input `MaskedArray` for which the mask is required. + + See Also + -------- + getmask : Return the mask of a masked array, or nomask. + getdata : Return the data of a masked array as an ndarray. + + Examples + -------- + >>> import numpy.ma as ma + >>> a = ma.masked_equal([[1,2],[3,4]], 2) + >>> a + masked_array( + data=[[1, --], + [3, 4]], + mask=[[False, True], + [False, False]], + fill_value=2) + >>> ma.getmaskarray(a) + array([[False, True], + [False, False]]) + + Result when mask == ``nomask`` + + >>> b = ma.masked_array([[1,2],[3,4]]) + >>> b + masked_array( + data=[[1, 2], + [3, 4]], + mask=False, + fill_value=999999) + >>> ma.getmaskarray(b) + array([[False, False], + [False, False]]) + + """ + mask = getmask(arr) + if mask is nomask: + mask = make_mask_none(np.shape(arr), getattr(arr, 'dtype', None)) + return mask + + +def is_mask(m): + """ + Return True if m is a valid, standard mask. + + This function does not check the contents of the input, only that the + type is MaskType. In particular, this function returns False if the + mask has a flexible dtype. + + Parameters + ---------- + m : array_like + Array to test. + + Returns + ------- + result : bool + True if `m.dtype.type` is MaskType, False otherwise. + + See Also + -------- + ma.isMaskedArray : Test whether input is an instance of MaskedArray. + + Examples + -------- + >>> import numpy.ma as ma + >>> m = ma.masked_equal([0, 1, 0, 2, 3], 0) + >>> m + masked_array(data=[--, 1, --, 2, 3], + mask=[ True, False, True, False, False], + fill_value=0) + >>> ma.is_mask(m) + False + >>> ma.is_mask(m.mask) + True + + Input must be an ndarray (or have similar attributes) + for it to be considered a valid mask. + + >>> m = [False, True, False] + >>> ma.is_mask(m) + False + >>> m = np.array([False, True, False]) + >>> m + array([False, True, False]) + >>> ma.is_mask(m) + True + + Arrays with complex dtypes don't return True. + + >>> dtype = np.dtype({'names':['monty', 'pithon'], + ... 'formats':[bool, bool]}) + >>> dtype + dtype([('monty', '|b1'), ('pithon', '|b1')]) + >>> m = np.array([(True, False), (False, True), (True, False)], + ... dtype=dtype) + >>> m + array([( True, False), (False, True), ( True, False)], + dtype=[('monty', '?'), ('pithon', '?')]) + >>> ma.is_mask(m) + False + + """ + try: + return m.dtype.type is MaskType + except AttributeError: + return False + + +def _shrink_mask(m): + """ + Shrink a mask to nomask if possible + """ + if m.dtype.names is None and not m.any(): + return nomask + else: + return m + + +def make_mask(m, copy=False, shrink=True, dtype=MaskType): + """ + Create a boolean mask from an array. + + Return `m` as a boolean mask, creating a copy if necessary or requested. + The function can accept any sequence that is convertible to integers, + or ``nomask``. Does not require that contents must be 0s and 1s, values + of 0 are interpreted as False, everything else as True. + + Parameters + ---------- + m : array_like + Potential mask. + copy : bool, optional + Whether to return a copy of `m` (True) or `m` itself (False). + shrink : bool, optional + Whether to shrink `m` to ``nomask`` if all its values are False. + dtype : dtype, optional + Data-type of the output mask. By default, the output mask has a + dtype of MaskType (bool). If the dtype is flexible, each field has + a boolean dtype. This is ignored when `m` is ``nomask``, in which + case ``nomask`` is always returned. + + Returns + ------- + result : ndarray + A boolean mask derived from `m`. + + Examples + -------- + >>> import numpy.ma as ma + >>> m = [True, False, True, True] + >>> ma.make_mask(m) + array([ True, False, True, True]) + >>> m = [1, 0, 1, 1] + >>> ma.make_mask(m) + array([ True, False, True, True]) + >>> m = [1, 0, 2, -3] + >>> ma.make_mask(m) + array([ True, False, True, True]) + + Effect of the `shrink` parameter. + + >>> m = np.zeros(4) + >>> m + array([0., 0., 0., 0.]) + >>> ma.make_mask(m) + False + >>> ma.make_mask(m, shrink=False) + array([False, False, False, False]) + + Using a flexible `dtype`. + + >>> m = [1, 0, 1, 1] + >>> n = [0, 1, 0, 0] + >>> arr = [] + >>> for man, mouse in zip(m, n): + ... arr.append((man, mouse)) + >>> arr + [(1, 0), (0, 1), (1, 0), (1, 0)] + >>> dtype = np.dtype({'names':['man', 'mouse'], + ... 'formats':[np.int64, np.int64]}) + >>> arr = np.array(arr, dtype=dtype) + >>> arr + array([(1, 0), (0, 1), (1, 0), (1, 0)], + dtype=[('man', '>> ma.make_mask(arr, dtype=dtype) + array([(True, False), (False, True), (True, False), (True, False)], + dtype=[('man', '|b1'), ('mouse', '|b1')]) + + """ + if m is nomask: + return nomask + + # Make sure the input dtype is valid. + dtype = make_mask_descr(dtype) + + # legacy boolean special case: "existence of fields implies true" + if isinstance(m, ndarray) and m.dtype.fields and dtype == np.bool_: + return np.ones(m.shape, dtype=dtype) + + # Fill the mask in case there are missing data; turn it into an ndarray. + result = np.array(filled(m, True), copy=copy, dtype=dtype, subok=True) + # Bas les masques ! + if shrink: + result = _shrink_mask(result) + return result + + +def make_mask_none(newshape, dtype=None): + """ + Return a boolean mask of the given shape, filled with False. + + This function returns a boolean ndarray with all entries False, that can + be used in common mask manipulations. If a complex dtype is specified, the + type of each field is converted to a boolean type. + + Parameters + ---------- + newshape : tuple + A tuple indicating the shape of the mask. + dtype : {None, dtype}, optional + If None, use a MaskType instance. Otherwise, use a new datatype with + the same fields as `dtype`, converted to boolean types. + + Returns + ------- + result : ndarray + An ndarray of appropriate shape and dtype, filled with False. + + See Also + -------- + make_mask : Create a boolean mask from an array. + make_mask_descr : Construct a dtype description list from a given dtype. + + Examples + -------- + >>> import numpy.ma as ma + >>> ma.make_mask_none((3,)) + array([False, False, False]) + + Defining a more complex dtype. + + >>> dtype = np.dtype({'names':['foo', 'bar'], + ... 'formats':[np.float32, np.int64]}) + >>> dtype + dtype([('foo', '>> ma.make_mask_none((3,), dtype=dtype) + array([(False, False), (False, False), (False, False)], + dtype=[('foo', '|b1'), ('bar', '|b1')]) + + """ + if dtype is None: + result = np.zeros(newshape, dtype=MaskType) + else: + result = np.zeros(newshape, dtype=make_mask_descr(dtype)) + return result + + +def mask_or(m1, m2, copy=False, shrink=True): + """ + Combine two masks with the ``logical_or`` operator. + + The result may be a view on `m1` or `m2` if the other is `nomask` + (i.e. False). + + Parameters + ---------- + m1, m2 : array_like + Input masks. + copy : bool, optional + If copy is False and one of the inputs is `nomask`, return a view + of the other input mask. Defaults to False. + shrink : bool, optional + Whether to shrink the output to `nomask` if all its values are + False. Defaults to True. + + Returns + ------- + mask : output mask + The result masks values that are masked in either `m1` or `m2`. + + Raises + ------ + ValueError + If `m1` and `m2` have different flexible dtypes. + + Examples + -------- + >>> m1 = np.ma.make_mask([0, 1, 1, 0]) + >>> m2 = np.ma.make_mask([1, 0, 0, 0]) + >>> np.ma.mask_or(m1, m2) + array([ True, True, True, False]) + + """ + + @recursive + def _recursive_mask_or(self, m1, m2, newmask): + names = m1.dtype.names + for name in names: + current1 = m1[name] + if current1.dtype.names is not None: + self(current1, m2[name], newmask[name]) + else: + umath.logical_or(current1, m2[name], newmask[name]) + return + + if (m1 is nomask) or (m1 is False): + dtype = getattr(m2, 'dtype', MaskType) + return make_mask(m2, copy=copy, shrink=shrink, dtype=dtype) + if (m2 is nomask) or (m2 is False): + dtype = getattr(m1, 'dtype', MaskType) + return make_mask(m1, copy=copy, shrink=shrink, dtype=dtype) + if m1 is m2 and is_mask(m1): + return m1 + (dtype1, dtype2) = (getattr(m1, 'dtype', None), getattr(m2, 'dtype', None)) + if dtype1 != dtype2: + raise ValueError("Incompatible dtypes '%s'<>'%s'" % (dtype1, dtype2)) + if dtype1.names is not None: + # Allocate an output mask array with the properly broadcast shape. + newmask = np.empty(np.broadcast(m1, m2).shape, dtype1) + _recursive_mask_or(m1, m2, newmask) + return newmask + return make_mask(umath.logical_or(m1, m2), copy=copy, shrink=shrink) + + +def flatten_mask(mask): + """ + Returns a completely flattened version of the mask, where nested fields + are collapsed. + + Parameters + ---------- + mask : array_like + Input array, which will be interpreted as booleans. + + Returns + ------- + flattened_mask : ndarray of bools + The flattened input. + + Examples + -------- + >>> mask = np.array([0, 0, 1]) + >>> np.ma.flatten_mask(mask) + array([False, False, True]) + + >>> mask = np.array([(0, 0), (0, 1)], dtype=[('a', bool), ('b', bool)]) + >>> np.ma.flatten_mask(mask) + array([False, False, False, True]) + + >>> mdtype = [('a', bool), ('b', [('ba', bool), ('bb', bool)])] + >>> mask = np.array([(0, (0, 0)), (0, (0, 1))], dtype=mdtype) + >>> np.ma.flatten_mask(mask) + array([False, False, False, False, False, True]) + + """ + + def _flatmask(mask): + "Flatten the mask and returns a (maybe nested) sequence of booleans." + mnames = mask.dtype.names + if mnames is not None: + return [flatten_mask(mask[name]) for name in mnames] + else: + return mask + + def _flatsequence(sequence): + "Generates a flattened version of the sequence." + try: + for element in sequence: + if hasattr(element, '__iter__'): + yield from _flatsequence(element) + else: + yield element + except TypeError: + yield sequence + + mask = np.asarray(mask) + flattened = _flatsequence(_flatmask(mask)) + return np.array([_ for _ in flattened], dtype=bool) + + +def _check_mask_axis(mask, axis, keepdims=np._NoValue): + "Check whether there are masked values along the given axis" + kwargs = {} if keepdims is np._NoValue else {'keepdims': keepdims} + if mask is not nomask: + return mask.all(axis=axis, **kwargs) + return nomask + + +############################################################################### +# Masking functions # +############################################################################### + +def masked_where(condition, a, copy=True): + """ + Mask an array where a condition is met. + + Return `a` as an array masked where `condition` is True. + Any masked values of `a` or `condition` are also masked in the output. + + Parameters + ---------- + condition : array_like + Masking condition. When `condition` tests floating point values for + equality, consider using ``masked_values`` instead. + a : array_like + Array to mask. + copy : bool + If True (default) make a copy of `a` in the result. If False modify + `a` in place and return a view. + + Returns + ------- + result : MaskedArray + The result of masking `a` where `condition` is True. + + See Also + -------- + masked_values : Mask using floating point equality. + masked_equal : Mask where equal to a given value. + masked_not_equal : Mask where `not` equal to a given value. + masked_less_equal : Mask where less than or equal to a given value. + masked_greater_equal : Mask where greater than or equal to a given value. + masked_less : Mask where less than a given value. + masked_greater : Mask where greater than a given value. + masked_inside : Mask inside a given interval. + masked_outside : Mask outside a given interval. + masked_invalid : Mask invalid values (NaNs or infs). + + Examples + -------- + >>> import numpy.ma as ma + >>> a = np.arange(4) + >>> a + array([0, 1, 2, 3]) + >>> ma.masked_where(a <= 2, a) + masked_array(data=[--, --, --, 3], + mask=[ True, True, True, False], + fill_value=999999) + + Mask array `b` conditional on `a`. + + >>> b = ['a', 'b', 'c', 'd'] + >>> ma.masked_where(a == 2, b) + masked_array(data=['a', 'b', --, 'd'], + mask=[False, False, True, False], + fill_value='N/A', + dtype='>> c = ma.masked_where(a <= 2, a) + >>> c + masked_array(data=[--, --, --, 3], + mask=[ True, True, True, False], + fill_value=999999) + >>> c[0] = 99 + >>> c + masked_array(data=[99, --, --, 3], + mask=[False, True, True, False], + fill_value=999999) + >>> a + array([0, 1, 2, 3]) + >>> c = ma.masked_where(a <= 2, a, copy=False) + >>> c[0] = 99 + >>> c + masked_array(data=[99, --, --, 3], + mask=[False, True, True, False], + fill_value=999999) + >>> a + array([99, 1, 2, 3]) + + When `condition` or `a` contain masked values. + + >>> a = np.arange(4) + >>> a = ma.masked_where(a == 2, a) + >>> a + masked_array(data=[0, 1, --, 3], + mask=[False, False, True, False], + fill_value=999999) + >>> b = np.arange(4) + >>> b = ma.masked_where(b == 0, b) + >>> b + masked_array(data=[--, 1, 2, 3], + mask=[ True, False, False, False], + fill_value=999999) + >>> ma.masked_where(a == 3, b) + masked_array(data=[--, 1, --, --], + mask=[ True, False, True, True], + fill_value=999999) + + """ + # Make sure that condition is a valid standard-type mask. + cond = make_mask(condition, shrink=False) + a = np.array(a, copy=copy, subok=True) + + (cshape, ashape) = (cond.shape, a.shape) + if cshape and cshape != ashape: + raise IndexError("Inconsistent shape between the condition and the input" + " (got %s and %s)" % (cshape, ashape)) + if hasattr(a, '_mask'): + cond = mask_or(cond, a._mask) + cls = type(a) + else: + cls = MaskedArray + result = a.view(cls) + # Assign to *.mask so that structured masks are handled correctly. + result.mask = _shrink_mask(cond) + return result + + +def masked_greater(x, value, copy=True): + """ + Mask an array where greater than a given value. + + This function is a shortcut to ``masked_where``, with + `condition` = (x > value). + + See Also + -------- + masked_where : Mask where a condition is met. + + Examples + -------- + >>> import numpy.ma as ma + >>> a = np.arange(4) + >>> a + array([0, 1, 2, 3]) + >>> ma.masked_greater(a, 2) + masked_array(data=[0, 1, 2, --], + mask=[False, False, False, True], + fill_value=999999) + + """ + return masked_where(greater(x, value), x, copy=copy) + + +def masked_greater_equal(x, value, copy=True): + """ + Mask an array where greater than or equal to a given value. + + This function is a shortcut to ``masked_where``, with + `condition` = (x >= value). + + See Also + -------- + masked_where : Mask where a condition is met. + + Examples + -------- + >>> import numpy.ma as ma + >>> a = np.arange(4) + >>> a + array([0, 1, 2, 3]) + >>> ma.masked_greater_equal(a, 2) + masked_array(data=[0, 1, --, --], + mask=[False, False, True, True], + fill_value=999999) + + """ + return masked_where(greater_equal(x, value), x, copy=copy) + + +def masked_less(x, value, copy=True): + """ + Mask an array where less than a given value. + + This function is a shortcut to ``masked_where``, with + `condition` = (x < value). + + See Also + -------- + masked_where : Mask where a condition is met. + + Examples + -------- + >>> import numpy.ma as ma + >>> a = np.arange(4) + >>> a + array([0, 1, 2, 3]) + >>> ma.masked_less(a, 2) + masked_array(data=[--, --, 2, 3], + mask=[ True, True, False, False], + fill_value=999999) + + """ + return masked_where(less(x, value), x, copy=copy) + + +def masked_less_equal(x, value, copy=True): + """ + Mask an array where less than or equal to a given value. + + This function is a shortcut to ``masked_where``, with + `condition` = (x <= value). + + See Also + -------- + masked_where : Mask where a condition is met. + + Examples + -------- + >>> import numpy.ma as ma + >>> a = np.arange(4) + >>> a + array([0, 1, 2, 3]) + >>> ma.masked_less_equal(a, 2) + masked_array(data=[--, --, --, 3], + mask=[ True, True, True, False], + fill_value=999999) + + """ + return masked_where(less_equal(x, value), x, copy=copy) + + +def masked_not_equal(x, value, copy=True): + """ + Mask an array where `not` equal to a given value. + + This function is a shortcut to ``masked_where``, with + `condition` = (x != value). + + See Also + -------- + masked_where : Mask where a condition is met. + + Examples + -------- + >>> import numpy.ma as ma + >>> a = np.arange(4) + >>> a + array([0, 1, 2, 3]) + >>> ma.masked_not_equal(a, 2) + masked_array(data=[--, --, 2, --], + mask=[ True, True, False, True], + fill_value=999999) + + """ + return masked_where(not_equal(x, value), x, copy=copy) + + +def masked_equal(x, value, copy=True): + """ + Mask an array where equal to a given value. + + This function is a shortcut to ``masked_where``, with + `condition` = (x == value). For floating point arrays, + consider using ``masked_values(x, value)``. + + See Also + -------- + masked_where : Mask where a condition is met. + masked_values : Mask using floating point equality. + + Examples + -------- + >>> import numpy.ma as ma + >>> a = np.arange(4) + >>> a + array([0, 1, 2, 3]) + >>> ma.masked_equal(a, 2) + masked_array(data=[0, 1, --, 3], + mask=[False, False, True, False], + fill_value=2) + + """ + output = masked_where(equal(x, value), x, copy=copy) + output.fill_value = value + return output + + +def masked_inside(x, v1, v2, copy=True): + """ + Mask an array inside a given interval. + + Shortcut to ``masked_where``, where `condition` is True for `x` inside + the interval [v1,v2] (v1 <= x <= v2). The boundaries `v1` and `v2` + can be given in either order. + + See Also + -------- + masked_where : Mask where a condition is met. + + Notes + ----- + The array `x` is prefilled with its filling value. + + Examples + -------- + >>> import numpy.ma as ma + >>> x = [0.31, 1.2, 0.01, 0.2, -0.4, -1.1] + >>> ma.masked_inside(x, -0.3, 0.3) + masked_array(data=[0.31, 1.2, --, --, -0.4, -1.1], + mask=[False, False, True, True, False, False], + fill_value=1e+20) + + The order of `v1` and `v2` doesn't matter. + + >>> ma.masked_inside(x, 0.3, -0.3) + masked_array(data=[0.31, 1.2, --, --, -0.4, -1.1], + mask=[False, False, True, True, False, False], + fill_value=1e+20) + + """ + if v2 < v1: + (v1, v2) = (v2, v1) + xf = filled(x) + condition = (xf >= v1) & (xf <= v2) + return masked_where(condition, x, copy=copy) + + +def masked_outside(x, v1, v2, copy=True): + """ + Mask an array outside a given interval. + + Shortcut to ``masked_where``, where `condition` is True for `x` outside + the interval [v1,v2] (x < v1)|(x > v2). + The boundaries `v1` and `v2` can be given in either order. + + See Also + -------- + masked_where : Mask where a condition is met. + + Notes + ----- + The array `x` is prefilled with its filling value. + + Examples + -------- + >>> import numpy.ma as ma + >>> x = [0.31, 1.2, 0.01, 0.2, -0.4, -1.1] + >>> ma.masked_outside(x, -0.3, 0.3) + masked_array(data=[--, --, 0.01, 0.2, --, --], + mask=[ True, True, False, False, True, True], + fill_value=1e+20) + + The order of `v1` and `v2` doesn't matter. + + >>> ma.masked_outside(x, 0.3, -0.3) + masked_array(data=[--, --, 0.01, 0.2, --, --], + mask=[ True, True, False, False, True, True], + fill_value=1e+20) + + """ + if v2 < v1: + (v1, v2) = (v2, v1) + xf = filled(x) + condition = (xf < v1) | (xf > v2) + return masked_where(condition, x, copy=copy) + + +def masked_object(x, value, copy=True, shrink=True): + """ + Mask the array `x` where the data are exactly equal to value. + + This function is similar to `masked_values`, but only suitable + for object arrays: for floating point, use `masked_values` instead. + + Parameters + ---------- + x : array_like + Array to mask + value : object + Comparison value + copy : {True, False}, optional + Whether to return a copy of `x`. + shrink : {True, False}, optional + Whether to collapse a mask full of False to nomask + + Returns + ------- + result : MaskedArray + The result of masking `x` where equal to `value`. + + See Also + -------- + masked_where : Mask where a condition is met. + masked_equal : Mask where equal to a given value (integers). + masked_values : Mask using floating point equality. + + Examples + -------- + >>> import numpy.ma as ma + >>> food = np.array(['green_eggs', 'ham'], dtype=object) + >>> # don't eat spoiled food + >>> eat = ma.masked_object(food, 'green_eggs') + >>> eat + masked_array(data=[--, 'ham'], + mask=[ True, False], + fill_value='green_eggs', + dtype=object) + >>> # plain ol` ham is boring + >>> fresh_food = np.array(['cheese', 'ham', 'pineapple'], dtype=object) + >>> eat = ma.masked_object(fresh_food, 'green_eggs') + >>> eat + masked_array(data=['cheese', 'ham', 'pineapple'], + mask=False, + fill_value='green_eggs', + dtype=object) + + Note that `mask` is set to ``nomask`` if possible. + + >>> eat + masked_array(data=['cheese', 'ham', 'pineapple'], + mask=False, + fill_value='green_eggs', + dtype=object) + + """ + if isMaskedArray(x): + condition = umath.equal(x._data, value) + mask = x._mask + else: + condition = umath.equal(np.asarray(x), value) + mask = nomask + mask = mask_or(mask, make_mask(condition, shrink=shrink)) + return masked_array(x, mask=mask, copy=copy, fill_value=value) + + +def masked_values(x, value, rtol=1e-5, atol=1e-8, copy=True, shrink=True): + """ + Mask using floating point equality. + + Return a MaskedArray, masked where the data in array `x` are approximately + equal to `value`, determined using `isclose`. The default tolerances for + `masked_values` are the same as those for `isclose`. + + For integer types, exact equality is used, in the same way as + `masked_equal`. + + The fill_value is set to `value` and the mask is set to ``nomask`` if + possible. + + Parameters + ---------- + x : array_like + Array to mask. + value : float + Masking value. + rtol, atol : float, optional + Tolerance parameters passed on to `isclose` + copy : bool, optional + Whether to return a copy of `x`. + shrink : bool, optional + Whether to collapse a mask full of False to ``nomask``. + + Returns + ------- + result : MaskedArray + The result of masking `x` where approximately equal to `value`. + + See Also + -------- + masked_where : Mask where a condition is met. + masked_equal : Mask where equal to a given value (integers). + + Examples + -------- + >>> import numpy.ma as ma + >>> x = np.array([1, 1.1, 2, 1.1, 3]) + >>> ma.masked_values(x, 1.1) + masked_array(data=[1.0, --, 2.0, --, 3.0], + mask=[False, True, False, True, False], + fill_value=1.1) + + Note that `mask` is set to ``nomask`` if possible. + + >>> ma.masked_values(x, 1.5) + masked_array(data=[1. , 1.1, 2. , 1.1, 3. ], + mask=False, + fill_value=1.5) + + For integers, the fill value will be different in general to the + result of ``masked_equal``. + + >>> x = np.arange(5) + >>> x + array([0, 1, 2, 3, 4]) + >>> ma.masked_values(x, 2) + masked_array(data=[0, 1, --, 3, 4], + mask=[False, False, True, False, False], + fill_value=2) + >>> ma.masked_equal(x, 2) + masked_array(data=[0, 1, --, 3, 4], + mask=[False, False, True, False, False], + fill_value=2) + + """ + xnew = filled(x, value) + if np.issubdtype(xnew.dtype, np.floating): + mask = np.isclose(xnew, value, atol=atol, rtol=rtol) + else: + mask = umath.equal(xnew, value) + ret = masked_array(xnew, mask=mask, copy=copy, fill_value=value) + if shrink: + ret.shrink_mask() + return ret + + +def masked_invalid(a, copy=True): + """ + Mask an array where invalid values occur (NaNs or infs). + + This function is a shortcut to ``masked_where``, with + `condition` = ~(np.isfinite(a)). Any pre-existing mask is conserved. + Only applies to arrays with a dtype where NaNs or infs make sense + (i.e. floating point types), but accepts any array_like object. + + See Also + -------- + masked_where : Mask where a condition is met. + + Examples + -------- + >>> import numpy.ma as ma + >>> a = np.arange(5, dtype=float) + >>> a[2] = np.NaN + >>> a[3] = np.PINF + >>> a + array([ 0., 1., nan, inf, 4.]) + >>> ma.masked_invalid(a) + masked_array(data=[0.0, 1.0, --, --, 4.0], + mask=[False, False, True, True, False], + fill_value=1e+20) + + """ + a = np.array(a, copy=copy, subok=True) + mask = getattr(a, '_mask', None) + if mask is not None: + condition = ~(np.isfinite(getdata(a))) + if mask is not nomask: + condition |= mask + cls = type(a) + else: + condition = ~(np.isfinite(a)) + cls = MaskedArray + result = a.view(cls) + result._mask = condition + return result + + +############################################################################### +# Printing options # +############################################################################### + + +class _MaskedPrintOption: + """ + Handle the string used to represent missing data in a masked array. + + """ + + def __init__(self, display): + """ + Create the masked_print_option object. + + """ + self._display = display + self._enabled = True + + def display(self): + """ + Display the string to print for masked values. + + """ + return self._display + + def set_display(self, s): + """ + Set the string to print for masked values. + + """ + self._display = s + + def enabled(self): + """ + Is the use of the display value enabled? + + """ + return self._enabled + + def enable(self, shrink=1): + """ + Set the enabling shrink to `shrink`. + + """ + self._enabled = shrink + + def __str__(self): + return str(self._display) + + __repr__ = __str__ + +# if you single index into a masked location you get this object. +masked_print_option = _MaskedPrintOption('--') + + +def _recursive_printoption(result, mask, printopt): + """ + Puts printoptions in result where mask is True. + + Private function allowing for recursion + + """ + names = result.dtype.names + if names is not None: + for name in names: + curdata = result[name] + curmask = mask[name] + _recursive_printoption(curdata, curmask, printopt) + else: + np.copyto(result, printopt, where=mask) + return + +# For better or worse, these end in a newline +_legacy_print_templates = dict( + long_std=textwrap.dedent("""\ + masked_%(name)s(data = + %(data)s, + %(nlen)s mask = + %(mask)s, + %(nlen)s fill_value = %(fill)s) + """), + long_flx=textwrap.dedent("""\ + masked_%(name)s(data = + %(data)s, + %(nlen)s mask = + %(mask)s, + %(nlen)s fill_value = %(fill)s, + %(nlen)s dtype = %(dtype)s) + """), + short_std=textwrap.dedent("""\ + masked_%(name)s(data = %(data)s, + %(nlen)s mask = %(mask)s, + %(nlen)s fill_value = %(fill)s) + """), + short_flx=textwrap.dedent("""\ + masked_%(name)s(data = %(data)s, + %(nlen)s mask = %(mask)s, + %(nlen)s fill_value = %(fill)s, + %(nlen)s dtype = %(dtype)s) + """) +) + +############################################################################### +# MaskedArray class # +############################################################################### + + +def _recursive_filled(a, mask, fill_value): + """ + Recursively fill `a` with `fill_value`. + + """ + names = a.dtype.names + for name in names: + current = a[name] + if current.dtype.names is not None: + _recursive_filled(current, mask[name], fill_value[name]) + else: + np.copyto(current, fill_value[name], where=mask[name]) + + +def flatten_structured_array(a): + """ + Flatten a structured array. + + The data type of the output is chosen such that it can represent all of the + (nested) fields. + + Parameters + ---------- + a : structured array + + Returns + ------- + output : masked array or ndarray + A flattened masked array if the input is a masked array, otherwise a + standard ndarray. + + Examples + -------- + >>> ndtype = [('a', int), ('b', float)] + >>> a = np.array([(1, 1), (2, 2)], dtype=ndtype) + >>> np.ma.flatten_structured_array(a) + array([[1., 1.], + [2., 2.]]) + + """ + + def flatten_sequence(iterable): + """ + Flattens a compound of nested iterables. + + """ + for elm in iter(iterable): + if hasattr(elm, '__iter__'): + yield from flatten_sequence(elm) + else: + yield elm + + a = np.asanyarray(a) + inishape = a.shape + a = a.ravel() + if isinstance(a, MaskedArray): + out = np.array([tuple(flatten_sequence(d.item())) for d in a._data]) + out = out.view(MaskedArray) + out._mask = np.array([tuple(flatten_sequence(d.item())) + for d in getmaskarray(a)]) + else: + out = np.array([tuple(flatten_sequence(d.item())) for d in a]) + if len(inishape) > 1: + newshape = list(out.shape) + newshape[0] = inishape + out.shape = tuple(flatten_sequence(newshape)) + return out + + +def _arraymethod(funcname, onmask=True): + """ + Return a class method wrapper around a basic array method. + + Creates a class method which returns a masked array, where the new + ``_data`` array is the output of the corresponding basic method called + on the original ``_data``. + + If `onmask` is True, the new mask is the output of the method called + on the initial mask. Otherwise, the new mask is just a reference + to the initial mask. + + Parameters + ---------- + funcname : str + Name of the function to apply on data. + onmask : bool + Whether the mask must be processed also (True) or left + alone (False). Default is True. Make available as `_onmask` + attribute. + + Returns + ------- + method : instancemethod + Class method wrapper of the specified basic array method. + + """ + def wrapped_method(self, *args, **params): + result = getattr(self._data, funcname)(*args, **params) + result = result.view(type(self)) + result._update_from(self) + mask = self._mask + if not onmask: + result.__setmask__(mask) + elif mask is not nomask: + # __setmask__ makes a copy, which we don't want + result._mask = getattr(mask, funcname)(*args, **params) + return result + methdoc = getattr(ndarray, funcname, None) or getattr(np, funcname, None) + if methdoc is not None: + wrapped_method.__doc__ = methdoc.__doc__ + wrapped_method.__name__ = funcname + return wrapped_method + + +class MaskedIterator: + """ + Flat iterator object to iterate over masked arrays. + + A `MaskedIterator` iterator is returned by ``x.flat`` for any masked array + `x`. It allows iterating over the array as if it were a 1-D array, + either in a for-loop or by calling its `next` method. + + Iteration is done in C-contiguous style, with the last index varying the + fastest. The iterator can also be indexed using basic slicing or + advanced indexing. + + See Also + -------- + MaskedArray.flat : Return a flat iterator over an array. + MaskedArray.flatten : Returns a flattened copy of an array. + + Notes + ----- + `MaskedIterator` is not exported by the `ma` module. Instead of + instantiating a `MaskedIterator` directly, use `MaskedArray.flat`. + + Examples + -------- + >>> x = np.ma.array(arange(6).reshape(2, 3)) + >>> fl = x.flat + >>> type(fl) + + >>> for item in fl: + ... print(item) + ... + 0 + 1 + 2 + 3 + 4 + 5 + + Extracting more than a single element b indexing the `MaskedIterator` + returns a masked array: + + >>> fl[2:4] + masked_array(data = [2 3], + mask = False, + fill_value = 999999) + + """ + + def __init__(self, ma): + self.ma = ma + self.dataiter = ma._data.flat + + if ma._mask is nomask: + self.maskiter = None + else: + self.maskiter = ma._mask.flat + + def __iter__(self): + return self + + def __getitem__(self, indx): + result = self.dataiter.__getitem__(indx).view(type(self.ma)) + if self.maskiter is not None: + _mask = self.maskiter.__getitem__(indx) + if isinstance(_mask, ndarray): + # set shape to match that of data; this is needed for matrices + _mask.shape = result.shape + result._mask = _mask + elif isinstance(_mask, np.void): + return mvoid(result, mask=_mask, hardmask=self.ma._hardmask) + elif _mask: # Just a scalar, masked + return masked + return result + + # This won't work if ravel makes a copy + def __setitem__(self, index, value): + self.dataiter[index] = getdata(value) + if self.maskiter is not None: + self.maskiter[index] = getmaskarray(value) + + def __next__(self): + """ + Return the next value, or raise StopIteration. + + Examples + -------- + >>> x = np.ma.array([3, 2], mask=[0, 1]) + >>> fl = x.flat + >>> next(fl) + 3 + >>> next(fl) + masked + >>> next(fl) + Traceback (most recent call last): + ... + StopIteration + + """ + d = next(self.dataiter) + if self.maskiter is not None: + m = next(self.maskiter) + if isinstance(m, np.void): + return mvoid(d, mask=m, hardmask=self.ma._hardmask) + elif m: # Just a scalar, masked + return masked + return d + + +class MaskedArray(ndarray): + """ + An array class with possibly masked values. + + Masked values of True exclude the corresponding element from any + computation. + + Construction:: + + x = MaskedArray(data, mask=nomask, dtype=None, copy=False, subok=True, + ndmin=0, fill_value=None, keep_mask=True, hard_mask=None, + shrink=True, order=None) + + Parameters + ---------- + data : array_like + Input data. + mask : sequence, optional + Mask. Must be convertible to an array of booleans with the same + shape as `data`. True indicates a masked (i.e. invalid) data. + dtype : dtype, optional + Data type of the output. + If `dtype` is None, the type of the data argument (``data.dtype``) + is used. If `dtype` is not None and different from ``data.dtype``, + a copy is performed. + copy : bool, optional + Whether to copy the input data (True), or to use a reference instead. + Default is False. + subok : bool, optional + Whether to return a subclass of `MaskedArray` if possible (True) or a + plain `MaskedArray`. Default is True. + ndmin : int, optional + Minimum number of dimensions. Default is 0. + fill_value : scalar, optional + Value used to fill in the masked values when necessary. + If None, a default based on the data-type is used. + keep_mask : bool, optional + Whether to combine `mask` with the mask of the input data, if any + (True), or to use only `mask` for the output (False). Default is True. + hard_mask : bool, optional + Whether to use a hard mask or not. With a hard mask, masked values + cannot be unmasked. Default is False. + shrink : bool, optional + Whether to force compression of an empty mask. Default is True. + order : {'C', 'F', 'A'}, optional + Specify the order of the array. If order is 'C', then the array + will be in C-contiguous order (last-index varies the fastest). + If order is 'F', then the returned array will be in + Fortran-contiguous order (first-index varies the fastest). + If order is 'A' (default), then the returned array may be + in any order (either C-, Fortran-contiguous, or even discontiguous), + unless a copy is required, in which case it will be C-contiguous. + + Examples + -------- + + The ``mask`` can be initialized with an array of boolean values + with the same shape as ``data``. + + >>> data = np.arange(6).reshape((2, 3)) + >>> np.ma.MaskedArray(data, mask=[[False, True, False], + ... [False, False, True]]) + masked_array( + data=[[0, --, 2], + [3, 4, --]], + mask=[[False, True, False], + [False, False, True]], + fill_value=999999) + + Alternatively, the ``mask`` can be initialized to homogeneous boolean + array with the same shape as ``data`` by passing in a scalar + boolean value: + + >>> np.ma.MaskedArray(data, mask=False) + masked_array( + data=[[0, 1, 2], + [3, 4, 5]], + mask=[[False, False, False], + [False, False, False]], + fill_value=999999) + + >>> np.ma.MaskedArray(data, mask=True) + masked_array( + data=[[--, --, --], + [--, --, --]], + mask=[[ True, True, True], + [ True, True, True]], + fill_value=999999, + dtype=int64) + + .. note:: + The recommended practice for initializing ``mask`` with a scalar + boolean value is to use ``True``/``False`` rather than + ``np.True_``/``np.False_``. The reason is :attr:`nomask` + is represented internally as ``np.False_``. + + >>> np.False_ is np.ma.nomask + True + + """ + + __array_priority__ = 15 + _defaultmask = nomask + _defaulthardmask = False + _baseclass = ndarray + + # Maximum number of elements per axis used when printing an array. The + # 1d case is handled separately because we need more values in this case. + _print_width = 100 + _print_width_1d = 1500 + + def __new__(cls, data=None, mask=nomask, dtype=None, copy=False, + subok=True, ndmin=0, fill_value=None, keep_mask=True, + hard_mask=None, shrink=True, order=None): + """ + Create a new masked array from scratch. + + Notes + ----- + A masked array can also be created by taking a .view(MaskedArray). + + """ + # Process data. + _data = np.array(data, dtype=dtype, copy=copy, + order=order, subok=True, ndmin=ndmin) + _baseclass = getattr(data, '_baseclass', type(_data)) + # Check that we're not erasing the mask. + if isinstance(data, MaskedArray) and (data.shape != _data.shape): + copy = True + + # Here, we copy the _view_, so that we can attach new properties to it + # we must never do .view(MaskedConstant), as that would create a new + # instance of np.ma.masked, which make identity comparison fail + if isinstance(data, cls) and subok and not isinstance(data, MaskedConstant): + _data = ndarray.view(_data, type(data)) + else: + _data = ndarray.view(_data, cls) + # Backwards compatibility w/ numpy.core.ma. + if hasattr(data, '_mask') and not isinstance(data, ndarray): + _data._mask = data._mask + # FIXME _sharedmask is never used. + _sharedmask = True + # Process mask. + # Type of the mask + mdtype = make_mask_descr(_data.dtype) + + if mask is nomask: + # Case 1. : no mask in input. + # Erase the current mask ? + if not keep_mask: + # With a reduced version + if shrink: + _data._mask = nomask + # With full version + else: + _data._mask = np.zeros(_data.shape, dtype=mdtype) + # Check whether we missed something + elif isinstance(data, (tuple, list)): + try: + # If data is a sequence of masked array + mask = np.array( + [getmaskarray(np.asanyarray(m, dtype=_data.dtype)) + for m in data], dtype=mdtype) + except ValueError: + # If data is nested + mask = nomask + # Force shrinking of the mask if needed (and possible) + if (mdtype == MaskType) and mask.any(): + _data._mask = mask + _data._sharedmask = False + else: + _data._sharedmask = not copy + if copy: + _data._mask = _data._mask.copy() + # Reset the shape of the original mask + if getmask(data) is not nomask: + data._mask.shape = data.shape + else: + # Case 2. : With a mask in input. + # If mask is boolean, create an array of True or False + if mask is True and mdtype == MaskType: + mask = np.ones(_data.shape, dtype=mdtype) + elif mask is False and mdtype == MaskType: + mask = np.zeros(_data.shape, dtype=mdtype) + else: + # Read the mask with the current mdtype + try: + mask = np.array(mask, copy=copy, dtype=mdtype) + # Or assume it's a sequence of bool/int + except TypeError: + mask = np.array([tuple([m] * len(mdtype)) for m in mask], + dtype=mdtype) + # Make sure the mask and the data have the same shape + if mask.shape != _data.shape: + (nd, nm) = (_data.size, mask.size) + if nm == 1: + mask = np.resize(mask, _data.shape) + elif nm == nd: + mask = np.reshape(mask, _data.shape) + else: + msg = "Mask and data not compatible: data size is %i, " + \ + "mask size is %i." + raise MaskError(msg % (nd, nm)) + copy = True + # Set the mask to the new value + if _data._mask is nomask: + _data._mask = mask + _data._sharedmask = not copy + else: + if not keep_mask: + _data._mask = mask + _data._sharedmask = not copy + else: + if _data.dtype.names is not None: + def _recursive_or(a, b): + "do a|=b on each field of a, recursively" + for name in a.dtype.names: + (af, bf) = (a[name], b[name]) + if af.dtype.names is not None: + _recursive_or(af, bf) + else: + af |= bf + + _recursive_or(_data._mask, mask) + else: + _data._mask = np.logical_or(mask, _data._mask) + _data._sharedmask = False + # Update fill_value. + if fill_value is None: + fill_value = getattr(data, '_fill_value', None) + # But don't run the check unless we have something to check. + if fill_value is not None: + _data._fill_value = _check_fill_value(fill_value, _data.dtype) + # Process extra options .. + if hard_mask is None: + _data._hardmask = getattr(data, '_hardmask', False) + else: + _data._hardmask = hard_mask + _data._baseclass = _baseclass + return _data + + + def _update_from(self, obj): + """ + Copies some attributes of obj to self. + + """ + if isinstance(obj, ndarray): + _baseclass = type(obj) + else: + _baseclass = ndarray + # We need to copy the _basedict to avoid backward propagation + _optinfo = {} + _optinfo.update(getattr(obj, '_optinfo', {})) + _optinfo.update(getattr(obj, '_basedict', {})) + if not isinstance(obj, MaskedArray): + _optinfo.update(getattr(obj, '__dict__', {})) + _dict = dict(_fill_value=getattr(obj, '_fill_value', None), + _hardmask=getattr(obj, '_hardmask', False), + _sharedmask=getattr(obj, '_sharedmask', False), + _isfield=getattr(obj, '_isfield', False), + _baseclass=getattr(obj, '_baseclass', _baseclass), + _optinfo=_optinfo, + _basedict=_optinfo) + self.__dict__.update(_dict) + self.__dict__.update(_optinfo) + return + + def __array_finalize__(self, obj): + """ + Finalizes the masked array. + + """ + # Get main attributes. + self._update_from(obj) + + # We have to decide how to initialize self.mask, based on + # obj.mask. This is very difficult. There might be some + # correspondence between the elements in the array we are being + # created from (= obj) and us. Or there might not. This method can + # be called in all kinds of places for all kinds of reasons -- could + # be empty_like, could be slicing, could be a ufunc, could be a view. + # The numpy subclassing interface simply doesn't give us any way + # to know, which means that at best this method will be based on + # guesswork and heuristics. To make things worse, there isn't even any + # clear consensus about what the desired behavior is. For instance, + # most users think that np.empty_like(marr) -- which goes via this + # method -- should return a masked array with an empty mask (see + # gh-3404 and linked discussions), but others disagree, and they have + # existing code which depends on empty_like returning an array that + # matches the input mask. + # + # Historically our algorithm was: if the template object mask had the + # same *number of elements* as us, then we used *it's mask object + # itself* as our mask, so that writes to us would also write to the + # original array. This is horribly broken in multiple ways. + # + # Now what we do instead is, if the template object mask has the same + # number of elements as us, and we do not have the same base pointer + # as the template object (b/c views like arr[...] should keep the same + # mask), then we make a copy of the template object mask and use + # that. This is also horribly broken but somewhat less so. Maybe. + if isinstance(obj, ndarray): + # XX: This looks like a bug -- shouldn't it check self.dtype + # instead? + if obj.dtype.names is not None: + _mask = getmaskarray(obj) + else: + _mask = getmask(obj) + + # If self and obj point to exactly the same data, then probably + # self is a simple view of obj (e.g., self = obj[...]), so they + # should share the same mask. (This isn't 100% reliable, e.g. self + # could be the first row of obj, or have strange strides, but as a + # heuristic it's not bad.) In all other cases, we make a copy of + # the mask, so that future modifications to 'self' do not end up + # side-effecting 'obj' as well. + if (_mask is not nomask and obj.__array_interface__["data"][0] + != self.__array_interface__["data"][0]): + # We should make a copy. But we could get here via astype, + # in which case the mask might need a new dtype as well + # (e.g., changing to or from a structured dtype), and the + # order could have changed. So, change the mask type if + # needed and use astype instead of copy. + if self.dtype == obj.dtype: + _mask_dtype = _mask.dtype + else: + _mask_dtype = make_mask_descr(self.dtype) + + if self.flags.c_contiguous: + order = "C" + elif self.flags.f_contiguous: + order = "F" + else: + order = "K" + + _mask = _mask.astype(_mask_dtype, order) + else: + # Take a view so shape changes, etc., do not propagate back. + _mask = _mask.view() + else: + _mask = nomask + + self._mask = _mask + # Finalize the mask + if self._mask is not nomask: + try: + self._mask.shape = self.shape + except ValueError: + self._mask = nomask + except (TypeError, AttributeError): + # When _mask.shape is not writable (because it's a void) + pass + + # Finalize the fill_value + if self._fill_value is not None: + self._fill_value = _check_fill_value(self._fill_value, self.dtype) + elif self.dtype.names is not None: + # Finalize the default fill_value for structured arrays + self._fill_value = _check_fill_value(None, self.dtype) + + def __array_wrap__(self, obj, context=None): + """ + Special hook for ufuncs. + + Wraps the numpy array and sets the mask according to context. + + """ + if obj is self: # for in-place operations + result = obj + else: + result = obj.view(type(self)) + result._update_from(self) + + if context is not None: + result._mask = result._mask.copy() + func, args, out_i = context + # args sometimes contains outputs (gh-10459), which we don't want + input_args = args[:func.nin] + m = reduce(mask_or, [getmaskarray(arg) for arg in input_args]) + # Get the domain mask + domain = ufunc_domain.get(func, None) + if domain is not None: + # Take the domain, and make sure it's a ndarray + with np.errstate(divide='ignore', invalid='ignore'): + d = filled(domain(*input_args), True) + + if d.any(): + # Fill the result where the domain is wrong + try: + # Binary domain: take the last value + fill_value = ufunc_fills[func][-1] + except TypeError: + # Unary domain: just use this one + fill_value = ufunc_fills[func] + except KeyError: + # Domain not recognized, use fill_value instead + fill_value = self.fill_value + + np.copyto(result, fill_value, where=d) + + # Update the mask + if m is nomask: + m = d + else: + # Don't modify inplace, we risk back-propagation + m = (m | d) + + # Make sure the mask has the proper size + if result is not self and result.shape == () and m: + return masked + else: + result._mask = m + result._sharedmask = False + + return result + + def view(self, dtype=None, type=None, fill_value=None): + """ + Return a view of the MaskedArray data. + + Parameters + ---------- + dtype : data-type or ndarray sub-class, optional + Data-type descriptor of the returned view, e.g., float32 or int16. + The default, None, results in the view having the same data-type + as `a`. As with ``ndarray.view``, dtype can also be specified as + an ndarray sub-class, which then specifies the type of the + returned object (this is equivalent to setting the ``type`` + parameter). + type : Python type, optional + Type of the returned view, either ndarray or a subclass. The + default None results in type preservation. + fill_value : scalar, optional + The value to use for invalid entries (None by default). + If None, then this argument is inferred from the passed `dtype`, or + in its absence the original array, as discussed in the notes below. + + See Also + -------- + numpy.ndarray.view : Equivalent method on ndarray object. + + Notes + ----- + + ``a.view()`` is used two different ways: + + ``a.view(some_dtype)`` or ``a.view(dtype=some_dtype)`` constructs a view + of the array's memory with a different data-type. This can cause a + reinterpretation of the bytes of memory. + + ``a.view(ndarray_subclass)`` or ``a.view(type=ndarray_subclass)`` just + returns an instance of `ndarray_subclass` that looks at the same array + (same shape, dtype, etc.) This does not cause a reinterpretation of the + memory. + + If `fill_value` is not specified, but `dtype` is specified (and is not + an ndarray sub-class), the `fill_value` of the MaskedArray will be + reset. If neither `fill_value` nor `dtype` are specified (or if + `dtype` is an ndarray sub-class), then the fill value is preserved. + Finally, if `fill_value` is specified, but `dtype` is not, the fill + value is set to the specified value. + + For ``a.view(some_dtype)``, if ``some_dtype`` has a different number of + bytes per entry than the previous dtype (for example, converting a + regular array to a structured array), then the behavior of the view + cannot be predicted just from the superficial appearance of ``a`` (shown + by ``print(a)``). It also depends on exactly how ``a`` is stored in + memory. Therefore if ``a`` is C-ordered versus fortran-ordered, versus + defined as a slice or transpose, etc., the view may give different + results. + """ + + if dtype is None: + if type is None: + output = ndarray.view(self) + else: + output = ndarray.view(self, type) + elif type is None: + try: + if issubclass(dtype, ndarray): + output = ndarray.view(self, dtype) + dtype = None + else: + output = ndarray.view(self, dtype) + except TypeError: + output = ndarray.view(self, dtype) + else: + output = ndarray.view(self, dtype, type) + + # also make the mask be a view (so attr changes to the view's + # mask do no affect original object's mask) + # (especially important to avoid affecting np.masked singleton) + if getmask(output) is not nomask: + output._mask = output._mask.view() + + # Make sure to reset the _fill_value if needed + if getattr(output, '_fill_value', None) is not None: + if fill_value is None: + if dtype is None: + pass # leave _fill_value as is + else: + output._fill_value = None + else: + output.fill_value = fill_value + return output + + def __getitem__(self, indx): + """ + x.__getitem__(y) <==> x[y] + + Return the item described by i, as a masked array. + + """ + # We could directly use ndarray.__getitem__ on self. + # But then we would have to modify __array_finalize__ to prevent the + # mask of being reshaped if it hasn't been set up properly yet + # So it's easier to stick to the current version + dout = self.data[indx] + _mask = self._mask + + def _is_scalar(m): + return not isinstance(m, np.ndarray) + + def _scalar_heuristic(arr, elem): + """ + Return whether `elem` is a scalar result of indexing `arr`, or None + if undecidable without promoting nomask to a full mask + """ + # obviously a scalar + if not isinstance(elem, np.ndarray): + return True + + # object array scalar indexing can return anything + elif arr.dtype.type is np.object_: + if arr.dtype is not elem.dtype: + # elem is an array, but dtypes do not match, so must be + # an element + return True + + # well-behaved subclass that only returns 0d arrays when + # expected - this is not a scalar + elif type(arr).__getitem__ == ndarray.__getitem__: + return False + + return None + + if _mask is not nomask: + # _mask cannot be a subclass, so it tells us whether we should + # expect a scalar. It also cannot be of dtype object. + mout = _mask[indx] + scalar_expected = _is_scalar(mout) + + else: + # attempt to apply the heuristic to avoid constructing a full mask + mout = nomask + scalar_expected = _scalar_heuristic(self.data, dout) + if scalar_expected is None: + # heuristics have failed + # construct a full array, so we can be certain. This is costly. + # we could also fall back on ndarray.__getitem__(self.data, indx) + scalar_expected = _is_scalar(getmaskarray(self)[indx]) + + # Did we extract a single item? + if scalar_expected: + # A record + if isinstance(dout, np.void): + # We should always re-cast to mvoid, otherwise users can + # change masks on rows that already have masked values, but not + # on rows that have no masked values, which is inconsistent. + return mvoid(dout, mask=mout, hardmask=self._hardmask) + + # special case introduced in gh-5962 + elif (self.dtype.type is np.object_ and + isinstance(dout, np.ndarray) and + dout is not masked): + # If masked, turn into a MaskedArray, with everything masked. + if mout: + return MaskedArray(dout, mask=True) + else: + return dout + + # Just a scalar + else: + if mout: + return masked + else: + return dout + else: + # Force dout to MA + dout = dout.view(type(self)) + # Inherit attributes from self + dout._update_from(self) + # Check the fill_value + if is_string_or_list_of_strings(indx): + if self._fill_value is not None: + dout._fill_value = self._fill_value[indx] + + # Something like gh-15895 has happened if this check fails. + # _fill_value should always be an ndarray. + if not isinstance(dout._fill_value, np.ndarray): + raise RuntimeError('Internal NumPy error.') + # If we're indexing a multidimensional field in a + # structured array (such as dtype("(2,)i2,(2,)i1")), + # dimensionality goes up (M[field].ndim == M.ndim + + # M.dtype[field].ndim). That's fine for + # M[field] but problematic for M[field].fill_value + # which should have shape () to avoid breaking several + # methods. There is no great way out, so set to + # first element. See issue #6723. + if dout._fill_value.ndim > 0: + if not (dout._fill_value == + dout._fill_value.flat[0]).all(): + warnings.warn( + "Upon accessing multidimensional field " + f"{indx!s}, need to keep dimensionality " + "of fill_value at 0. Discarding " + "heterogeneous fill_value and setting " + f"all to {dout._fill_value[0]!s}.", + stacklevel=2) + # Need to use `.flat[0:1].squeeze(...)` instead of just + # `.flat[0]` to ensure the result is a 0d array and not + # a scalar. + dout._fill_value = dout._fill_value.flat[0:1].squeeze(axis=0) + dout._isfield = True + # Update the mask if needed + if mout is not nomask: + # set shape to match that of data; this is needed for matrices + dout._mask = reshape(mout, dout.shape) + dout._sharedmask = True + # Note: Don't try to check for m.any(), that'll take too long + return dout + + def __setitem__(self, indx, value): + """ + x.__setitem__(i, y) <==> x[i]=y + + Set item described by index. If value is masked, masks those + locations. + + """ + if self is masked: + raise MaskError('Cannot alter the masked element.') + _data = self._data + _mask = self._mask + if isinstance(indx, str): + _data[indx] = value + if _mask is nomask: + self._mask = _mask = make_mask_none(self.shape, self.dtype) + _mask[indx] = getmask(value) + return + + _dtype = _data.dtype + + if value is masked: + # The mask wasn't set: create a full version. + if _mask is nomask: + _mask = self._mask = make_mask_none(self.shape, _dtype) + # Now, set the mask to its value. + if _dtype.names is not None: + _mask[indx] = tuple([True] * len(_dtype.names)) + else: + _mask[indx] = True + return + + # Get the _data part of the new value + dval = getattr(value, '_data', value) + # Get the _mask part of the new value + mval = getmask(value) + if _dtype.names is not None and mval is nomask: + mval = tuple([False] * len(_dtype.names)) + if _mask is nomask: + # Set the data, then the mask + _data[indx] = dval + if mval is not nomask: + _mask = self._mask = make_mask_none(self.shape, _dtype) + _mask[indx] = mval + elif not self._hardmask: + # Set the data, then the mask + _data[indx] = dval + _mask[indx] = mval + elif hasattr(indx, 'dtype') and (indx.dtype == MaskType): + indx = indx * umath.logical_not(_mask) + _data[indx] = dval + else: + if _dtype.names is not None: + err_msg = "Flexible 'hard' masks are not yet supported." + raise NotImplementedError(err_msg) + mindx = mask_or(_mask[indx], mval, copy=True) + dindx = self._data[indx] + if dindx.size > 1: + np.copyto(dindx, dval, where=~mindx) + elif mindx is nomask: + dindx = dval + _data[indx] = dindx + _mask[indx] = mindx + return + + # Define so that we can overwrite the setter. + @property + def dtype(self): + return super(MaskedArray, self).dtype + + @dtype.setter + def dtype(self, dtype): + super(MaskedArray, type(self)).dtype.__set__(self, dtype) + if self._mask is not nomask: + self._mask = self._mask.view(make_mask_descr(dtype), ndarray) + # Try to reset the shape of the mask (if we don't have a void). + # This raises a ValueError if the dtype change won't work. + try: + self._mask.shape = self.shape + except (AttributeError, TypeError): + pass + + @property + def shape(self): + return super(MaskedArray, self).shape + + @shape.setter + def shape(self, shape): + super(MaskedArray, type(self)).shape.__set__(self, shape) + # Cannot use self._mask, since it may not (yet) exist when a + # masked matrix sets the shape. + if getmask(self) is not nomask: + self._mask.shape = self.shape + + def __setmask__(self, mask, copy=False): + """ + Set the mask. + + """ + idtype = self.dtype + current_mask = self._mask + if mask is masked: + mask = True + + if current_mask is nomask: + # Make sure the mask is set + # Just don't do anything if there's nothing to do. + if mask is nomask: + return + current_mask = self._mask = make_mask_none(self.shape, idtype) + + if idtype.names is None: + # No named fields. + # Hardmask: don't unmask the data + if self._hardmask: + current_mask |= mask + # Softmask: set everything to False + # If it's obviously a compatible scalar, use a quick update + # method. + elif isinstance(mask, (int, float, np.bool_, np.number)): + current_mask[...] = mask + # Otherwise fall back to the slower, general purpose way. + else: + current_mask.flat = mask + else: + # Named fields w/ + mdtype = current_mask.dtype + mask = np.array(mask, copy=False) + # Mask is a singleton + if not mask.ndim: + # It's a boolean : make a record + if mask.dtype.kind == 'b': + mask = np.array(tuple([mask.item()] * len(mdtype)), + dtype=mdtype) + # It's a record: make sure the dtype is correct + else: + mask = mask.astype(mdtype) + # Mask is a sequence + else: + # Make sure the new mask is a ndarray with the proper dtype + try: + mask = np.array(mask, copy=copy, dtype=mdtype) + # Or assume it's a sequence of bool/int + except TypeError: + mask = np.array([tuple([m] * len(mdtype)) for m in mask], + dtype=mdtype) + # Hardmask: don't unmask the data + if self._hardmask: + for n in idtype.names: + current_mask[n] |= mask[n] + # Softmask: set everything to False + # If it's obviously a compatible scalar, use a quick update + # method. + elif isinstance(mask, (int, float, np.bool_, np.number)): + current_mask[...] = mask + # Otherwise fall back to the slower, general purpose way. + else: + current_mask.flat = mask + # Reshape if needed + if current_mask.shape: + current_mask.shape = self.shape + return + + _set_mask = __setmask__ + + @property + def mask(self): + """ Current mask. """ + + # We could try to force a reshape, but that wouldn't work in some + # cases. + # Return a view so that the dtype and shape cannot be changed in place + # This still preserves nomask by identity + return self._mask.view() + + @mask.setter + def mask(self, value): + self.__setmask__(value) + + @property + def recordmask(self): + """ + Get or set the mask of the array if it has no named fields. For + structured arrays, returns a ndarray of booleans where entries are + ``True`` if **all** the fields are masked, ``False`` otherwise: + + >>> x = np.ma.array([(1, 1), (2, 2), (3, 3), (4, 4), (5, 5)], + ... mask=[(0, 0), (1, 0), (1, 1), (0, 1), (0, 0)], + ... dtype=[('a', int), ('b', int)]) + >>> x.recordmask + array([False, False, True, False, False]) + """ + + _mask = self._mask.view(ndarray) + if _mask.dtype.names is None: + return _mask + return np.all(flatten_structured_array(_mask), axis=-1) + + @recordmask.setter + def recordmask(self, mask): + raise NotImplementedError("Coming soon: setting the mask per records!") + + def harden_mask(self): + """ + Force the mask to hard. + + Whether the mask of a masked array is hard or soft is determined by + its `~ma.MaskedArray.hardmask` property. `harden_mask` sets + `~ma.MaskedArray.hardmask` to ``True``. + + See Also + -------- + ma.MaskedArray.hardmask + + """ + self._hardmask = True + return self + + def soften_mask(self): + """ + Force the mask to soft. + + Whether the mask of a masked array is hard or soft is determined by + its `~ma.MaskedArray.hardmask` property. `soften_mask` sets + `~ma.MaskedArray.hardmask` to ``False``. + + See Also + -------- + ma.MaskedArray.hardmask + + """ + self._hardmask = False + return self + + @property + def hardmask(self): + """ Hardness of the mask """ + return self._hardmask + + def unshare_mask(self): + """ + Copy the mask and set the sharedmask flag to False. + + Whether the mask is shared between masked arrays can be seen from + the `sharedmask` property. `unshare_mask` ensures the mask is not shared. + A copy of the mask is only made if it was shared. + + See Also + -------- + sharedmask + + """ + if self._sharedmask: + self._mask = self._mask.copy() + self._sharedmask = False + return self + + @property + def sharedmask(self): + """ Share status of the mask (read-only). """ + return self._sharedmask + + def shrink_mask(self): + """ + Reduce a mask to nomask when possible. + + Parameters + ---------- + None + + Returns + ------- + None + + Examples + -------- + >>> x = np.ma.array([[1,2 ], [3, 4]], mask=[0]*4) + >>> x.mask + array([[False, False], + [False, False]]) + >>> x.shrink_mask() + masked_array( + data=[[1, 2], + [3, 4]], + mask=False, + fill_value=999999) + >>> x.mask + False + + """ + self._mask = _shrink_mask(self._mask) + return self + + @property + def baseclass(self): + """ Class of the underlying data (read-only). """ + return self._baseclass + + def _get_data(self): + """ + Returns the underlying data, as a view of the masked array. + + If the underlying data is a subclass of :class:`numpy.ndarray`, it is + returned as such. + + >>> x = np.ma.array(np.matrix([[1, 2], [3, 4]]), mask=[[0, 1], [1, 0]]) + >>> x.data + matrix([[1, 2], + [3, 4]]) + + The type of the data can be accessed through the :attr:`baseclass` + attribute. + """ + return ndarray.view(self, self._baseclass) + + _data = property(fget=_get_data) + data = property(fget=_get_data) + + @property + def flat(self): + """ Return a flat iterator, or set a flattened version of self to value. """ + return MaskedIterator(self) + + @flat.setter + def flat(self, value): + y = self.ravel() + y[:] = value + + @property + def fill_value(self): + """ + The filling value of the masked array is a scalar. When setting, None + will set to a default based on the data type. + + Examples + -------- + >>> for dt in [np.int32, np.int64, np.float64, np.complex128]: + ... np.ma.array([0, 1], dtype=dt).get_fill_value() + ... + 999999 + 999999 + 1e+20 + (1e+20+0j) + + >>> x = np.ma.array([0, 1.], fill_value=-np.inf) + >>> x.fill_value + -inf + >>> x.fill_value = np.pi + >>> x.fill_value + 3.1415926535897931 # may vary + + Reset to default: + + >>> x.fill_value = None + >>> x.fill_value + 1e+20 + + """ + if self._fill_value is None: + self._fill_value = _check_fill_value(None, self.dtype) + + # Temporary workaround to account for the fact that str and bytes + # scalars cannot be indexed with (), whereas all other numpy + # scalars can. See issues #7259 and #7267. + # The if-block can be removed after #7267 has been fixed. + if isinstance(self._fill_value, ndarray): + return self._fill_value[()] + return self._fill_value + + @fill_value.setter + def fill_value(self, value=None): + target = _check_fill_value(value, self.dtype) + if not target.ndim == 0: + # 2019-11-12, 1.18.0 + warnings.warn( + "Non-scalar arrays for the fill value are deprecated. Use " + "arrays with scalar values instead. The filled function " + "still supports any array as `fill_value`.", + DeprecationWarning, stacklevel=2) + + _fill_value = self._fill_value + if _fill_value is None: + # Create the attribute if it was undefined + self._fill_value = target + else: + # Don't overwrite the attribute, just fill it (for propagation) + _fill_value[()] = target + + # kept for compatibility + get_fill_value = fill_value.fget + set_fill_value = fill_value.fset + + def filled(self, fill_value=None): + """ + Return a copy of self, with masked values filled with a given value. + **However**, if there are no masked values to fill, self will be + returned instead as an ndarray. + + Parameters + ---------- + fill_value : array_like, optional + The value to use for invalid entries. Can be scalar or non-scalar. + If non-scalar, the resulting ndarray must be broadcastable over + input array. Default is None, in which case, the `fill_value` + attribute of the array is used instead. + + Returns + ------- + filled_array : ndarray + A copy of ``self`` with invalid entries replaced by *fill_value* + (be it the function argument or the attribute of ``self``), or + ``self`` itself as an ndarray if there are no invalid entries to + be replaced. + + Notes + ----- + The result is **not** a MaskedArray! + + Examples + -------- + >>> x = np.ma.array([1,2,3,4,5], mask=[0,0,1,0,1], fill_value=-999) + >>> x.filled() + array([ 1, 2, -999, 4, -999]) + >>> x.filled(fill_value=1000) + array([ 1, 2, 1000, 4, 1000]) + >>> type(x.filled()) + + + Subclassing is preserved. This means that if, e.g., the data part of + the masked array is a recarray, `filled` returns a recarray: + + >>> x = np.array([(-1, 2), (-3, 4)], dtype='i8,i8').view(np.recarray) + >>> m = np.ma.array(x, mask=[(True, False), (False, True)]) + >>> m.filled() + rec.array([(999999, 2), ( -3, 999999)], + dtype=[('f0', '>> x = np.ma.array(np.arange(5), mask=[0]*2 + [1]*3) + >>> x.compressed() + array([0, 1]) + >>> type(x.compressed()) + + + """ + data = ndarray.ravel(self._data) + if self._mask is not nomask: + data = data.compress(np.logical_not(ndarray.ravel(self._mask))) + return data + + def compress(self, condition, axis=None, out=None): + """ + Return `a` where condition is ``True``. + + If condition is a `~ma.MaskedArray`, missing values are considered + as ``False``. + + Parameters + ---------- + condition : var + Boolean 1-d array selecting which entries to return. If len(condition) + is less than the size of a along the axis, then output is truncated + to length of condition array. + axis : {None, int}, optional + Axis along which the operation must be performed. + out : {None, ndarray}, optional + Alternative output array in which to place the result. It must have + the same shape as the expected output but the type will be cast if + necessary. + + Returns + ------- + result : MaskedArray + A :class:`~ma.MaskedArray` object. + + Notes + ----- + Please note the difference with :meth:`compressed` ! + The output of :meth:`compress` has a mask, the output of + :meth:`compressed` does not. + + Examples + -------- + >>> x = np.ma.array([[1,2,3],[4,5,6],[7,8,9]], mask=[0] + [1,0]*4) + >>> x + masked_array( + data=[[1, --, 3], + [--, 5, --], + [7, --, 9]], + mask=[[False, True, False], + [ True, False, True], + [False, True, False]], + fill_value=999999) + >>> x.compress([1, 0, 1]) + masked_array(data=[1, 3], + mask=[False, False], + fill_value=999999) + + >>> x.compress([1, 0, 1], axis=1) + masked_array( + data=[[1, 3], + [--, --], + [7, 9]], + mask=[[False, False], + [ True, True], + [False, False]], + fill_value=999999) + + """ + # Get the basic components + (_data, _mask) = (self._data, self._mask) + + # Force the condition to a regular ndarray and forget the missing + # values. + condition = np.array(condition, copy=False, subok=False) + + _new = _data.compress(condition, axis=axis, out=out).view(type(self)) + _new._update_from(self) + if _mask is not nomask: + _new._mask = _mask.compress(condition, axis=axis) + return _new + + def _insert_masked_print(self): + """ + Replace masked values with masked_print_option, casting all innermost + dtypes to object. + """ + if masked_print_option.enabled(): + mask = self._mask + if mask is nomask: + res = self._data + else: + # convert to object array to make filled work + data = self._data + # For big arrays, to avoid a costly conversion to the + # object dtype, extract the corners before the conversion. + print_width = (self._print_width if self.ndim > 1 + else self._print_width_1d) + for axis in range(self.ndim): + if data.shape[axis] > print_width: + ind = print_width // 2 + arr = np.split(data, (ind, -ind), axis=axis) + data = np.concatenate((arr[0], arr[2]), axis=axis) + arr = np.split(mask, (ind, -ind), axis=axis) + mask = np.concatenate((arr[0], arr[2]), axis=axis) + + rdtype = _replace_dtype_fields(self.dtype, "O") + res = data.astype(rdtype) + _recursive_printoption(res, mask, masked_print_option) + else: + res = self.filled(self.fill_value) + return res + + def __str__(self): + return str(self._insert_masked_print()) + + def __repr__(self): + """ + Literal string representation. + + """ + if self._baseclass is np.ndarray: + name = 'array' + else: + name = self._baseclass.__name__ + + + # 2016-11-19: Demoted to legacy format + if np.get_printoptions()['legacy'] == '1.13': + is_long = self.ndim > 1 + parameters = dict( + name=name, + nlen=" " * len(name), + data=str(self), + mask=str(self._mask), + fill=str(self.fill_value), + dtype=str(self.dtype) + ) + is_structured = bool(self.dtype.names) + key = '{}_{}'.format( + 'long' if is_long else 'short', + 'flx' if is_structured else 'std' + ) + return _legacy_print_templates[key] % parameters + + prefix = f"masked_{name}(" + + dtype_needed = ( + not np.core.arrayprint.dtype_is_implied(self.dtype) or + np.all(self.mask) or + self.size == 0 + ) + + # determine which keyword args need to be shown + keys = ['data', 'mask', 'fill_value'] + if dtype_needed: + keys.append('dtype') + + # array has only one row (non-column) + is_one_row = builtins.all(dim == 1 for dim in self.shape[:-1]) + + # choose what to indent each keyword with + min_indent = 2 + if is_one_row: + # first key on the same line as the type, remaining keys + # aligned by equals + indents = {} + indents[keys[0]] = prefix + for k in keys[1:]: + n = builtins.max(min_indent, len(prefix + keys[0]) - len(k)) + indents[k] = ' ' * n + prefix = '' # absorbed into the first indent + else: + # each key on its own line, indented by two spaces + indents = {k: ' ' * min_indent for k in keys} + prefix = prefix + '\n' # first key on the next line + + # format the field values + reprs = {} + reprs['data'] = np.array2string( + self._insert_masked_print(), + separator=", ", + prefix=indents['data'] + 'data=', + suffix=',') + reprs['mask'] = np.array2string( + self._mask, + separator=", ", + prefix=indents['mask'] + 'mask=', + suffix=',') + reprs['fill_value'] = repr(self.fill_value) + if dtype_needed: + reprs['dtype'] = np.core.arrayprint.dtype_short_repr(self.dtype) + + # join keys with values and indentations + result = ',\n'.join( + '{}{}={}'.format(indents[k], k, reprs[k]) + for k in keys + ) + return prefix + result + ')' + + def _delegate_binop(self, other): + # This emulates the logic in + # private/binop_override.h:forward_binop_should_defer + if isinstance(other, type(self)): + return False + array_ufunc = getattr(other, "__array_ufunc__", False) + if array_ufunc is False: + other_priority = getattr(other, "__array_priority__", -1000000) + return self.__array_priority__ < other_priority + else: + # If array_ufunc is not None, it will be called inside the ufunc; + # None explicitly tells us to not call the ufunc, i.e., defer. + return array_ufunc is None + + def _comparison(self, other, compare): + """Compare self with other using operator.eq or operator.ne. + + When either of the elements is masked, the result is masked as well, + but the underlying boolean data are still set, with self and other + considered equal if both are masked, and unequal otherwise. + + For structured arrays, all fields are combined, with masked values + ignored. The result is masked if all fields were masked, with self + and other considered equal only if both were fully masked. + """ + omask = getmask(other) + smask = self.mask + mask = mask_or(smask, omask, copy=True) + + odata = getdata(other) + if mask.dtype.names is not None: + # For possibly masked structured arrays we need to be careful, + # since the standard structured array comparison will use all + # fields, masked or not. To avoid masked fields influencing the + # outcome, we set all masked fields in self to other, so they'll + # count as equal. To prepare, we ensure we have the right shape. + broadcast_shape = np.broadcast(self, odata).shape + sbroadcast = np.broadcast_to(self, broadcast_shape, subok=True) + sbroadcast._mask = mask + sdata = sbroadcast.filled(odata) + # Now take care of the mask; the merged mask should have an item + # masked if all fields were masked (in one and/or other). + mask = (mask == np.ones((), mask.dtype)) + + else: + # For regular arrays, just use the data as they come. + sdata = self.data + + check = compare(sdata, odata) + + if isinstance(check, (np.bool_, bool)): + return masked if mask else check + + if mask is not nomask: + # Adjust elements that were masked, which should be treated + # as equal if masked in both, unequal if masked in one. + # Note that this works automatically for structured arrays too. + check = np.where(mask, compare(smask, omask), check) + if mask.shape != check.shape: + # Guarantee consistency of the shape, making a copy since the + # the mask may need to get written to later. + mask = np.broadcast_to(mask, check.shape).copy() + + check = check.view(type(self)) + check._update_from(self) + check._mask = mask + + # Cast fill value to bool_ if needed. If it cannot be cast, the + # default boolean fill value is used. + if check._fill_value is not None: + try: + fill = _check_fill_value(check._fill_value, np.bool_) + except (TypeError, ValueError): + fill = _check_fill_value(None, np.bool_) + check._fill_value = fill + + return check + + def __eq__(self, other): + """Check whether other equals self elementwise. + + When either of the elements is masked, the result is masked as well, + but the underlying boolean data are still set, with self and other + considered equal if both are masked, and unequal otherwise. + + For structured arrays, all fields are combined, with masked values + ignored. The result is masked if all fields were masked, with self + and other considered equal only if both were fully masked. + """ + return self._comparison(other, operator.eq) + + def __ne__(self, other): + """Check whether other does not equal self elementwise. + + When either of the elements is masked, the result is masked as well, + but the underlying boolean data are still set, with self and other + considered equal if both are masked, and unequal otherwise. + + For structured arrays, all fields are combined, with masked values + ignored. The result is masked if all fields were masked, with self + and other considered equal only if both were fully masked. + """ + return self._comparison(other, operator.ne) + + def __add__(self, other): + """ + Add self to other, and return a new masked array. + + """ + if self._delegate_binop(other): + return NotImplemented + return add(self, other) + + def __radd__(self, other): + """ + Add other to self, and return a new masked array. + + """ + # In analogy with __rsub__ and __rdiv__, use original order: + # we get here from `other + self`. + return add(other, self) + + def __sub__(self, other): + """ + Subtract other from self, and return a new masked array. + + """ + if self._delegate_binop(other): + return NotImplemented + return subtract(self, other) + + def __rsub__(self, other): + """ + Subtract self from other, and return a new masked array. + + """ + return subtract(other, self) + + def __mul__(self, other): + "Multiply self by other, and return a new masked array." + if self._delegate_binop(other): + return NotImplemented + return multiply(self, other) + + def __rmul__(self, other): + """ + Multiply other by self, and return a new masked array. + + """ + # In analogy with __rsub__ and __rdiv__, use original order: + # we get here from `other * self`. + return multiply(other, self) + + def __div__(self, other): + """ + Divide other into self, and return a new masked array. + + """ + if self._delegate_binop(other): + return NotImplemented + return divide(self, other) + + def __truediv__(self, other): + """ + Divide other into self, and return a new masked array. + + """ + if self._delegate_binop(other): + return NotImplemented + return true_divide(self, other) + + def __rtruediv__(self, other): + """ + Divide self into other, and return a new masked array. + + """ + return true_divide(other, self) + + def __floordiv__(self, other): + """ + Divide other into self, and return a new masked array. + + """ + if self._delegate_binop(other): + return NotImplemented + return floor_divide(self, other) + + def __rfloordiv__(self, other): + """ + Divide self into other, and return a new masked array. + + """ + return floor_divide(other, self) + + def __pow__(self, other): + """ + Raise self to the power other, masking the potential NaNs/Infs + + """ + if self._delegate_binop(other): + return NotImplemented + return power(self, other) + + def __rpow__(self, other): + """ + Raise other to the power self, masking the potential NaNs/Infs + + """ + return power(other, self) + + def __iadd__(self, other): + """ + Add other to self in-place. + + """ + m = getmask(other) + if self._mask is nomask: + if m is not nomask and m.any(): + self._mask = make_mask_none(self.shape, self.dtype) + self._mask += m + else: + if m is not nomask: + self._mask += m + self._data.__iadd__(np.where(self._mask, self.dtype.type(0), + getdata(other))) + return self + + def __isub__(self, other): + """ + Subtract other from self in-place. + + """ + m = getmask(other) + if self._mask is nomask: + if m is not nomask and m.any(): + self._mask = make_mask_none(self.shape, self.dtype) + self._mask += m + elif m is not nomask: + self._mask += m + self._data.__isub__(np.where(self._mask, self.dtype.type(0), + getdata(other))) + return self + + def __imul__(self, other): + """ + Multiply self by other in-place. + + """ + m = getmask(other) + if self._mask is nomask: + if m is not nomask and m.any(): + self._mask = make_mask_none(self.shape, self.dtype) + self._mask += m + elif m is not nomask: + self._mask += m + self._data.__imul__(np.where(self._mask, self.dtype.type(1), + getdata(other))) + return self + + def __idiv__(self, other): + """ + Divide self by other in-place. + + """ + other_data = getdata(other) + dom_mask = _DomainSafeDivide().__call__(self._data, other_data) + other_mask = getmask(other) + new_mask = mask_or(other_mask, dom_mask) + # The following 3 lines control the domain filling + if dom_mask.any(): + (_, fval) = ufunc_fills[np.divide] + other_data = np.where(dom_mask, fval, other_data) + self._mask |= new_mask + self._data.__idiv__(np.where(self._mask, self.dtype.type(1), + other_data)) + return self + + def __ifloordiv__(self, other): + """ + Floor divide self by other in-place. + + """ + other_data = getdata(other) + dom_mask = _DomainSafeDivide().__call__(self._data, other_data) + other_mask = getmask(other) + new_mask = mask_or(other_mask, dom_mask) + # The following 3 lines control the domain filling + if dom_mask.any(): + (_, fval) = ufunc_fills[np.floor_divide] + other_data = np.where(dom_mask, fval, other_data) + self._mask |= new_mask + self._data.__ifloordiv__(np.where(self._mask, self.dtype.type(1), + other_data)) + return self + + def __itruediv__(self, other): + """ + True divide self by other in-place. + + """ + other_data = getdata(other) + dom_mask = _DomainSafeDivide().__call__(self._data, other_data) + other_mask = getmask(other) + new_mask = mask_or(other_mask, dom_mask) + # The following 3 lines control the domain filling + if dom_mask.any(): + (_, fval) = ufunc_fills[np.true_divide] + other_data = np.where(dom_mask, fval, other_data) + self._mask |= new_mask + self._data.__itruediv__(np.where(self._mask, self.dtype.type(1), + other_data)) + return self + + def __ipow__(self, other): + """ + Raise self to the power other, in place. + + """ + other_data = getdata(other) + other_mask = getmask(other) + with np.errstate(divide='ignore', invalid='ignore'): + self._data.__ipow__(np.where(self._mask, self.dtype.type(1), + other_data)) + invalid = np.logical_not(np.isfinite(self._data)) + if invalid.any(): + if self._mask is not nomask: + self._mask |= invalid + else: + self._mask = invalid + np.copyto(self._data, self.fill_value, where=invalid) + new_mask = mask_or(other_mask, invalid) + self._mask = mask_or(self._mask, new_mask) + return self + + def __float__(self): + """ + Convert to float. + + """ + if self.size > 1: + raise TypeError("Only length-1 arrays can be converted " + "to Python scalars") + elif self._mask: + warnings.warn("Warning: converting a masked element to nan.", stacklevel=2) + return np.nan + return float(self.item()) + + def __int__(self): + """ + Convert to int. + + """ + if self.size > 1: + raise TypeError("Only length-1 arrays can be converted " + "to Python scalars") + elif self._mask: + raise MaskError('Cannot convert masked element to a Python int.') + return int(self.item()) + + @property + def imag(self): + """ + The imaginary part of the masked array. + + This property is a view on the imaginary part of this `MaskedArray`. + + See Also + -------- + real + + Examples + -------- + >>> x = np.ma.array([1+1.j, -2j, 3.45+1.6j], mask=[False, True, False]) + >>> x.imag + masked_array(data=[1.0, --, 1.6], + mask=[False, True, False], + fill_value=1e+20) + + """ + result = self._data.imag.view(type(self)) + result.__setmask__(self._mask) + return result + + # kept for compatibility + get_imag = imag.fget + + @property + def real(self): + """ + The real part of the masked array. + + This property is a view on the real part of this `MaskedArray`. + + See Also + -------- + imag + + Examples + -------- + >>> x = np.ma.array([1+1.j, -2j, 3.45+1.6j], mask=[False, True, False]) + >>> x.real + masked_array(data=[1.0, --, 3.45], + mask=[False, True, False], + fill_value=1e+20) + + """ + result = self._data.real.view(type(self)) + result.__setmask__(self._mask) + return result + + # kept for compatibility + get_real = real.fget + + def count(self, axis=None, keepdims=np._NoValue): + """ + Count the non-masked elements of the array along the given axis. + + Parameters + ---------- + axis : None or int or tuple of ints, optional + Axis or axes along which the count is performed. + The default, None, performs the count over all + the dimensions of the input array. `axis` may be negative, in + which case it counts from the last to the first axis. + + .. versionadded:: 1.10.0 + + If this is a tuple of ints, the count is performed on multiple + axes, instead of a single axis or all the axes as before. + keepdims : bool, optional + If this is set to True, the axes which are reduced are left + in the result as dimensions with size one. With this option, + the result will broadcast correctly against the array. + + Returns + ------- + result : ndarray or scalar + An array with the same shape as the input array, with the specified + axis removed. If the array is a 0-d array, or if `axis` is None, a + scalar is returned. + + See Also + -------- + ma.count_masked : Count masked elements in array or along a given axis. + + Examples + -------- + >>> import numpy.ma as ma + >>> a = ma.arange(6).reshape((2, 3)) + >>> a[1, :] = ma.masked + >>> a + masked_array( + data=[[0, 1, 2], + [--, --, --]], + mask=[[False, False, False], + [ True, True, True]], + fill_value=999999) + >>> a.count() + 3 + + When the `axis` keyword is specified an array of appropriate size is + returned. + + >>> a.count(axis=0) + array([1, 1, 1]) + >>> a.count(axis=1) + array([3, 0]) + + """ + kwargs = {} if keepdims is np._NoValue else {'keepdims': keepdims} + + m = self._mask + # special case for matrices (we assume no other subclasses modify + # their dimensions) + if isinstance(self.data, np.matrix): + if m is nomask: + m = np.zeros(self.shape, dtype=np.bool_) + m = m.view(type(self.data)) + + if m is nomask: + # compare to _count_reduce_items in _methods.py + + if self.shape == (): + if axis not in (None, 0): + raise np.AxisError(axis=axis, ndim=self.ndim) + return 1 + elif axis is None: + if kwargs.get('keepdims', False): + return np.array(self.size, dtype=np.intp, ndmin=self.ndim) + return self.size + + axes = normalize_axis_tuple(axis, self.ndim) + items = 1 + for ax in axes: + items *= self.shape[ax] + + if kwargs.get('keepdims', False): + out_dims = list(self.shape) + for a in axes: + out_dims[a] = 1 + else: + out_dims = [d for n, d in enumerate(self.shape) + if n not in axes] + # make sure to return a 0-d array if axis is supplied + return np.full(out_dims, items, dtype=np.intp) + + # take care of the masked singleton + if self is masked: + return 0 + + return (~m).sum(axis=axis, dtype=np.intp, **kwargs) + + def ravel(self, order='C'): + """ + Returns a 1D version of self, as a view. + + Parameters + ---------- + order : {'C', 'F', 'A', 'K'}, optional + The elements of `a` are read using this index order. 'C' means to + index the elements in C-like order, with the last axis index + changing fastest, back to the first axis index changing slowest. + 'F' means to index the elements in Fortran-like index order, with + the first index changing fastest, and the last index changing + slowest. Note that the 'C' and 'F' options take no account of the + memory layout of the underlying array, and only refer to the order + of axis indexing. 'A' means to read the elements in Fortran-like + index order if `m` is Fortran *contiguous* in memory, C-like order + otherwise. 'K' means to read the elements in the order they occur + in memory, except for reversing the data when strides are negative. + By default, 'C' index order is used. + + Returns + ------- + MaskedArray + Output view is of shape ``(self.size,)`` (or + ``(np.ma.product(self.shape),)``). + + Examples + -------- + >>> x = np.ma.array([[1,2,3],[4,5,6],[7,8,9]], mask=[0] + [1,0]*4) + >>> x + masked_array( + data=[[1, --, 3], + [--, 5, --], + [7, --, 9]], + mask=[[False, True, False], + [ True, False, True], + [False, True, False]], + fill_value=999999) + >>> x.ravel() + masked_array(data=[1, --, 3, --, 5, --, 7, --, 9], + mask=[False, True, False, True, False, True, False, True, + False], + fill_value=999999) + + """ + r = ndarray.ravel(self._data, order=order).view(type(self)) + r._update_from(self) + if self._mask is not nomask: + r._mask = ndarray.ravel(self._mask, order=order).reshape(r.shape) + else: + r._mask = nomask + return r + + + def reshape(self, *s, **kwargs): + """ + Give a new shape to the array without changing its data. + + Returns a masked array containing the same data, but with a new shape. + The result is a view on the original array; if this is not possible, a + ValueError is raised. + + Parameters + ---------- + shape : int or tuple of ints + The new shape should be compatible with the original shape. If an + integer is supplied, then the result will be a 1-D array of that + length. + order : {'C', 'F'}, optional + Determines whether the array data should be viewed as in C + (row-major) or FORTRAN (column-major) order. + + Returns + ------- + reshaped_array : array + A new view on the array. + + See Also + -------- + reshape : Equivalent function in the masked array module. + numpy.ndarray.reshape : Equivalent method on ndarray object. + numpy.reshape : Equivalent function in the NumPy module. + + Notes + ----- + The reshaping operation cannot guarantee that a copy will not be made, + to modify the shape in place, use ``a.shape = s`` + + Examples + -------- + >>> x = np.ma.array([[1,2],[3,4]], mask=[1,0,0,1]) + >>> x + masked_array( + data=[[--, 2], + [3, --]], + mask=[[ True, False], + [False, True]], + fill_value=999999) + >>> x = x.reshape((4,1)) + >>> x + masked_array( + data=[[--], + [2], + [3], + [--]], + mask=[[ True], + [False], + [False], + [ True]], + fill_value=999999) + + """ + kwargs.update(order=kwargs.get('order', 'C')) + result = self._data.reshape(*s, **kwargs).view(type(self)) + result._update_from(self) + mask = self._mask + if mask is not nomask: + result._mask = mask.reshape(*s, **kwargs) + return result + + def resize(self, newshape, refcheck=True, order=False): + """ + .. warning:: + + This method does nothing, except raise a ValueError exception. A + masked array does not own its data and therefore cannot safely be + resized in place. Use the `numpy.ma.resize` function instead. + + This method is difficult to implement safely and may be deprecated in + future releases of NumPy. + + """ + # Note : the 'order' keyword looks broken, let's just drop it + errmsg = "A masked array does not own its data "\ + "and therefore cannot be resized.\n" \ + "Use the numpy.ma.resize function instead." + raise ValueError(errmsg) + + def put(self, indices, values, mode='raise'): + """ + Set storage-indexed locations to corresponding values. + + Sets self._data.flat[n] = values[n] for each n in indices. + If `values` is shorter than `indices` then it will repeat. + If `values` has some masked values, the initial mask is updated + in consequence, else the corresponding values are unmasked. + + Parameters + ---------- + indices : 1-D array_like + Target indices, interpreted as integers. + values : array_like + Values to place in self._data copy at target indices. + mode : {'raise', 'wrap', 'clip'}, optional + Specifies how out-of-bounds indices will behave. + 'raise' : raise an error. + 'wrap' : wrap around. + 'clip' : clip to the range. + + Notes + ----- + `values` can be a scalar or length 1 array. + + Examples + -------- + >>> x = np.ma.array([[1,2,3],[4,5,6],[7,8,9]], mask=[0] + [1,0]*4) + >>> x + masked_array( + data=[[1, --, 3], + [--, 5, --], + [7, --, 9]], + mask=[[False, True, False], + [ True, False, True], + [False, True, False]], + fill_value=999999) + >>> x.put([0,4,8],[10,20,30]) + >>> x + masked_array( + data=[[10, --, 3], + [--, 20, --], + [7, --, 30]], + mask=[[False, True, False], + [ True, False, True], + [False, True, False]], + fill_value=999999) + + >>> x.put(4,999) + >>> x + masked_array( + data=[[10, --, 3], + [--, 999, --], + [7, --, 30]], + mask=[[False, True, False], + [ True, False, True], + [False, True, False]], + fill_value=999999) + + """ + # Hard mask: Get rid of the values/indices that fall on masked data + if self._hardmask and self._mask is not nomask: + mask = self._mask[indices] + indices = narray(indices, copy=False) + values = narray(values, copy=False, subok=True) + values.resize(indices.shape) + indices = indices[~mask] + values = values[~mask] + + self._data.put(indices, values, mode=mode) + + # short circuit if neither self nor values are masked + if self._mask is nomask and getmask(values) is nomask: + return + + m = getmaskarray(self) + + if getmask(values) is nomask: + m.put(indices, False, mode=mode) + else: + m.put(indices, values._mask, mode=mode) + m = make_mask(m, copy=False, shrink=True) + self._mask = m + return + + def ids(self): + """ + Return the addresses of the data and mask areas. + + Parameters + ---------- + None + + Examples + -------- + >>> x = np.ma.array([1, 2, 3], mask=[0, 1, 1]) + >>> x.ids() + (166670640, 166659832) # may vary + + If the array has no mask, the address of `nomask` is returned. This address + is typically not close to the data in memory: + + >>> x = np.ma.array([1, 2, 3]) + >>> x.ids() + (166691080, 3083169284) # may vary + + """ + if self._mask is nomask: + return (self.ctypes.data, id(nomask)) + return (self.ctypes.data, self._mask.ctypes.data) + + def iscontiguous(self): + """ + Return a boolean indicating whether the data is contiguous. + + Parameters + ---------- + None + + Examples + -------- + >>> x = np.ma.array([1, 2, 3]) + >>> x.iscontiguous() + True + + `iscontiguous` returns one of the flags of the masked array: + + >>> x.flags + C_CONTIGUOUS : True + F_CONTIGUOUS : True + OWNDATA : False + WRITEABLE : True + ALIGNED : True + WRITEBACKIFCOPY : False + UPDATEIFCOPY : False + + """ + return self.flags['CONTIGUOUS'] + + def all(self, axis=None, out=None, keepdims=np._NoValue): + """ + Returns True if all elements evaluate to True. + + The output array is masked where all the values along the given axis + are masked: if the output would have been a scalar and that all the + values are masked, then the output is `masked`. + + Refer to `numpy.all` for full documentation. + + See Also + -------- + numpy.ndarray.all : corresponding function for ndarrays + numpy.all : equivalent function + + Examples + -------- + >>> np.ma.array([1,2,3]).all() + True + >>> a = np.ma.array([1,2,3], mask=True) + >>> (a.all() is np.ma.masked) + True + + """ + kwargs = {} if keepdims is np._NoValue else {'keepdims': keepdims} + + mask = _check_mask_axis(self._mask, axis, **kwargs) + if out is None: + d = self.filled(True).all(axis=axis, **kwargs).view(type(self)) + if d.ndim: + d.__setmask__(mask) + elif mask: + return masked + return d + self.filled(True).all(axis=axis, out=out, **kwargs) + if isinstance(out, MaskedArray): + if out.ndim or mask: + out.__setmask__(mask) + return out + + def any(self, axis=None, out=None, keepdims=np._NoValue): + """ + Returns True if any of the elements of `a` evaluate to True. + + Masked values are considered as False during computation. + + Refer to `numpy.any` for full documentation. + + See Also + -------- + numpy.ndarray.any : corresponding function for ndarrays + numpy.any : equivalent function + + """ + kwargs = {} if keepdims is np._NoValue else {'keepdims': keepdims} + + mask = _check_mask_axis(self._mask, axis, **kwargs) + if out is None: + d = self.filled(False).any(axis=axis, **kwargs).view(type(self)) + if d.ndim: + d.__setmask__(mask) + elif mask: + d = masked + return d + self.filled(False).any(axis=axis, out=out, **kwargs) + if isinstance(out, MaskedArray): + if out.ndim or mask: + out.__setmask__(mask) + return out + + def nonzero(self): + """ + Return the indices of unmasked elements that are not zero. + + Returns a tuple of arrays, one for each dimension, containing the + indices of the non-zero elements in that dimension. The corresponding + non-zero values can be obtained with:: + + a[a.nonzero()] + + To group the indices by element, rather than dimension, use + instead:: + + np.transpose(a.nonzero()) + + The result of this is always a 2d array, with a row for each non-zero + element. + + Parameters + ---------- + None + + Returns + ------- + tuple_of_arrays : tuple + Indices of elements that are non-zero. + + See Also + -------- + numpy.nonzero : + Function operating on ndarrays. + flatnonzero : + Return indices that are non-zero in the flattened version of the input + array. + numpy.ndarray.nonzero : + Equivalent ndarray method. + count_nonzero : + Counts the number of non-zero elements in the input array. + + Examples + -------- + >>> import numpy.ma as ma + >>> x = ma.array(np.eye(3)) + >>> x + masked_array( + data=[[1., 0., 0.], + [0., 1., 0.], + [0., 0., 1.]], + mask=False, + fill_value=1e+20) + >>> x.nonzero() + (array([0, 1, 2]), array([0, 1, 2])) + + Masked elements are ignored. + + >>> x[1, 1] = ma.masked + >>> x + masked_array( + data=[[1.0, 0.0, 0.0], + [0.0, --, 0.0], + [0.0, 0.0, 1.0]], + mask=[[False, False, False], + [False, True, False], + [False, False, False]], + fill_value=1e+20) + >>> x.nonzero() + (array([0, 2]), array([0, 2])) + + Indices can also be grouped by element. + + >>> np.transpose(x.nonzero()) + array([[0, 0], + [2, 2]]) + + A common use for ``nonzero`` is to find the indices of an array, where + a condition is True. Given an array `a`, the condition `a` > 3 is a + boolean array and since False is interpreted as 0, ma.nonzero(a > 3) + yields the indices of the `a` where the condition is true. + + >>> a = ma.array([[1,2,3],[4,5,6],[7,8,9]]) + >>> a > 3 + masked_array( + data=[[False, False, False], + [ True, True, True], + [ True, True, True]], + mask=False, + fill_value=True) + >>> ma.nonzero(a > 3) + (array([1, 1, 1, 2, 2, 2]), array([0, 1, 2, 0, 1, 2])) + + The ``nonzero`` method of the condition array can also be called. + + >>> (a > 3).nonzero() + (array([1, 1, 1, 2, 2, 2]), array([0, 1, 2, 0, 1, 2])) + + """ + return narray(self.filled(0), copy=False).nonzero() + + def trace(self, offset=0, axis1=0, axis2=1, dtype=None, out=None): + """ + (this docstring should be overwritten) + """ + #!!!: implement out + test! + m = self._mask + if m is nomask: + result = super(MaskedArray, self).trace(offset=offset, axis1=axis1, + axis2=axis2, out=out) + return result.astype(dtype) + else: + D = self.diagonal(offset=offset, axis1=axis1, axis2=axis2) + return D.astype(dtype).filled(0).sum(axis=-1, out=out) + trace.__doc__ = ndarray.trace.__doc__ + + def dot(self, b, out=None, strict=False): + """ + a.dot(b, out=None) + + Masked dot product of two arrays. Note that `out` and `strict` are + located in different positions than in `ma.dot`. In order to + maintain compatibility with the functional version, it is + recommended that the optional arguments be treated as keyword only. + At some point that may be mandatory. + + .. versionadded:: 1.10.0 + + Parameters + ---------- + b : masked_array_like + Inputs array. + out : masked_array, optional + Output argument. This must have the exact kind that would be + returned if it was not used. In particular, it must have the + right type, must be C-contiguous, and its dtype must be the + dtype that would be returned for `ma.dot(a,b)`. This is a + performance feature. Therefore, if these conditions are not + met, an exception is raised, instead of attempting to be + flexible. + strict : bool, optional + Whether masked data are propagated (True) or set to 0 (False) + for the computation. Default is False. Propagating the mask + means that if a masked value appears in a row or column, the + whole row or column is considered masked. + + .. versionadded:: 1.10.2 + + See Also + -------- + numpy.ma.dot : equivalent function + + """ + return dot(self, b, out=out, strict=strict) + + def sum(self, axis=None, dtype=None, out=None, keepdims=np._NoValue): + """ + Return the sum of the array elements over the given axis. + + Masked elements are set to 0 internally. + + Refer to `numpy.sum` for full documentation. + + See Also + -------- + numpy.ndarray.sum : corresponding function for ndarrays + numpy.sum : equivalent function + + Examples + -------- + >>> x = np.ma.array([[1,2,3],[4,5,6],[7,8,9]], mask=[0] + [1,0]*4) + >>> x + masked_array( + data=[[1, --, 3], + [--, 5, --], + [7, --, 9]], + mask=[[False, True, False], + [ True, False, True], + [False, True, False]], + fill_value=999999) + >>> x.sum() + 25 + >>> x.sum(axis=1) + masked_array(data=[4, 5, 16], + mask=[False, False, False], + fill_value=999999) + >>> x.sum(axis=0) + masked_array(data=[8, 5, 12], + mask=[False, False, False], + fill_value=999999) + >>> print(type(x.sum(axis=0, dtype=np.int64)[0])) + + + """ + kwargs = {} if keepdims is np._NoValue else {'keepdims': keepdims} + + _mask = self._mask + newmask = _check_mask_axis(_mask, axis, **kwargs) + # No explicit output + if out is None: + result = self.filled(0).sum(axis, dtype=dtype, **kwargs) + rndim = getattr(result, 'ndim', 0) + if rndim: + result = result.view(type(self)) + result.__setmask__(newmask) + elif newmask: + result = masked + return result + # Explicit output + result = self.filled(0).sum(axis, dtype=dtype, out=out, **kwargs) + if isinstance(out, MaskedArray): + outmask = getmask(out) + if outmask is nomask: + outmask = out._mask = make_mask_none(out.shape) + outmask.flat = newmask + return out + + def cumsum(self, axis=None, dtype=None, out=None): + """ + Return the cumulative sum of the array elements over the given axis. + + Masked values are set to 0 internally during the computation. + However, their position is saved, and the result will be masked at + the same locations. + + Refer to `numpy.cumsum` for full documentation. + + Notes + ----- + The mask is lost if `out` is not a valid :class:`ma.MaskedArray` ! + + Arithmetic is modular when using integer types, and no error is + raised on overflow. + + See Also + -------- + numpy.ndarray.cumsum : corresponding function for ndarrays + numpy.cumsum : equivalent function + + Examples + -------- + >>> marr = np.ma.array(np.arange(10), mask=[0,0,0,1,1,1,0,0,0,0]) + >>> marr.cumsum() + masked_array(data=[0, 1, 3, --, --, --, 9, 16, 24, 33], + mask=[False, False, False, True, True, True, False, False, + False, False], + fill_value=999999) + + """ + result = self.filled(0).cumsum(axis=axis, dtype=dtype, out=out) + if out is not None: + if isinstance(out, MaskedArray): + out.__setmask__(self.mask) + return out + result = result.view(type(self)) + result.__setmask__(self._mask) + return result + + def prod(self, axis=None, dtype=None, out=None, keepdims=np._NoValue): + """ + Return the product of the array elements over the given axis. + + Masked elements are set to 1 internally for computation. + + Refer to `numpy.prod` for full documentation. + + Notes + ----- + Arithmetic is modular when using integer types, and no error is raised + on overflow. + + See Also + -------- + numpy.ndarray.prod : corresponding function for ndarrays + numpy.prod : equivalent function + """ + kwargs = {} if keepdims is np._NoValue else {'keepdims': keepdims} + + _mask = self._mask + newmask = _check_mask_axis(_mask, axis, **kwargs) + # No explicit output + if out is None: + result = self.filled(1).prod(axis, dtype=dtype, **kwargs) + rndim = getattr(result, 'ndim', 0) + if rndim: + result = result.view(type(self)) + result.__setmask__(newmask) + elif newmask: + result = masked + return result + # Explicit output + result = self.filled(1).prod(axis, dtype=dtype, out=out, **kwargs) + if isinstance(out, MaskedArray): + outmask = getmask(out) + if outmask is nomask: + outmask = out._mask = make_mask_none(out.shape) + outmask.flat = newmask + return out + product = prod + + def cumprod(self, axis=None, dtype=None, out=None): + """ + Return the cumulative product of the array elements over the given axis. + + Masked values are set to 1 internally during the computation. + However, their position is saved, and the result will be masked at + the same locations. + + Refer to `numpy.cumprod` for full documentation. + + Notes + ----- + The mask is lost if `out` is not a valid MaskedArray ! + + Arithmetic is modular when using integer types, and no error is + raised on overflow. + + See Also + -------- + numpy.ndarray.cumprod : corresponding function for ndarrays + numpy.cumprod : equivalent function + """ + result = self.filled(1).cumprod(axis=axis, dtype=dtype, out=out) + if out is not None: + if isinstance(out, MaskedArray): + out.__setmask__(self._mask) + return out + result = result.view(type(self)) + result.__setmask__(self._mask) + return result + + def mean(self, axis=None, dtype=None, out=None, keepdims=np._NoValue): + """ + Returns the average of the array elements along given axis. + + Masked entries are ignored, and result elements which are not + finite will be masked. + + Refer to `numpy.mean` for full documentation. + + See Also + -------- + numpy.ndarray.mean : corresponding function for ndarrays + numpy.mean : Equivalent function + numpy.ma.average: Weighted average. + + Examples + -------- + >>> a = np.ma.array([1,2,3], mask=[False, False, True]) + >>> a + masked_array(data=[1, 2, --], + mask=[False, False, True], + fill_value=999999) + >>> a.mean() + 1.5 + + """ + kwargs = {} if keepdims is np._NoValue else {'keepdims': keepdims} + + if self._mask is nomask: + result = super(MaskedArray, self).mean(axis=axis, + dtype=dtype, **kwargs)[()] + else: + dsum = self.sum(axis=axis, dtype=dtype, **kwargs) + cnt = self.count(axis=axis, **kwargs) + if cnt.shape == () and (cnt == 0): + result = masked + else: + result = dsum * 1. / cnt + if out is not None: + out.flat = result + if isinstance(out, MaskedArray): + outmask = getmask(out) + if outmask is nomask: + outmask = out._mask = make_mask_none(out.shape) + outmask.flat = getmask(result) + return out + return result + + def anom(self, axis=None, dtype=None): + """ + Compute the anomalies (deviations from the arithmetic mean) + along the given axis. + + Returns an array of anomalies, with the same shape as the input and + where the arithmetic mean is computed along the given axis. + + Parameters + ---------- + axis : int, optional + Axis over which the anomalies are taken. + The default is to use the mean of the flattened array as reference. + dtype : dtype, optional + Type to use in computing the variance. For arrays of integer type + the default is float32; for arrays of float types it is the same as + the array type. + + See Also + -------- + mean : Compute the mean of the array. + + Examples + -------- + >>> a = np.ma.array([1,2,3]) + >>> a.anom() + masked_array(data=[-1., 0., 1.], + mask=False, + fill_value=1e+20) + + """ + m = self.mean(axis, dtype) + if m is masked: + return m + + if not axis: + return self - m + else: + return self - expand_dims(m, axis) + + def var(self, axis=None, dtype=None, out=None, ddof=0, + keepdims=np._NoValue): + """ + Returns the variance of the array elements along given axis. + + Masked entries are ignored, and result elements which are not + finite will be masked. + + Refer to `numpy.var` for full documentation. + + See Also + -------- + numpy.ndarray.var : corresponding function for ndarrays + numpy.var : Equivalent function + """ + kwargs = {} if keepdims is np._NoValue else {'keepdims': keepdims} + + # Easy case: nomask, business as usual + if self._mask is nomask: + ret = super(MaskedArray, self).var(axis=axis, dtype=dtype, out=out, + ddof=ddof, **kwargs)[()] + if out is not None: + if isinstance(out, MaskedArray): + out.__setmask__(nomask) + return out + return ret + + # Some data are masked, yay! + cnt = self.count(axis=axis, **kwargs) - ddof + danom = self - self.mean(axis, dtype, keepdims=True) + if iscomplexobj(self): + danom = umath.absolute(danom) ** 2 + else: + danom *= danom + dvar = divide(danom.sum(axis, **kwargs), cnt).view(type(self)) + # Apply the mask if it's not a scalar + if dvar.ndim: + dvar._mask = mask_or(self._mask.all(axis, **kwargs), (cnt <= 0)) + dvar._update_from(self) + elif getmask(dvar): + # Make sure that masked is returned when the scalar is masked. + dvar = masked + if out is not None: + if isinstance(out, MaskedArray): + out.flat = 0 + out.__setmask__(True) + elif out.dtype.kind in 'biu': + errmsg = "Masked data information would be lost in one or "\ + "more location." + raise MaskError(errmsg) + else: + out.flat = np.nan + return out + # In case with have an explicit output + if out is not None: + # Set the data + out.flat = dvar + # Set the mask if needed + if isinstance(out, MaskedArray): + out.__setmask__(dvar.mask) + return out + return dvar + var.__doc__ = np.var.__doc__ + + def std(self, axis=None, dtype=None, out=None, ddof=0, + keepdims=np._NoValue): + """ + Returns the standard deviation of the array elements along given axis. + + Masked entries are ignored. + + Refer to `numpy.std` for full documentation. + + See Also + -------- + numpy.ndarray.std : corresponding function for ndarrays + numpy.std : Equivalent function + """ + kwargs = {} if keepdims is np._NoValue else {'keepdims': keepdims} + + dvar = self.var(axis, dtype, out, ddof, **kwargs) + if dvar is not masked: + if out is not None: + np.power(out, 0.5, out=out, casting='unsafe') + return out + dvar = sqrt(dvar) + return dvar + + def round(self, decimals=0, out=None): + """ + Return each element rounded to the given number of decimals. + + Refer to `numpy.around` for full documentation. + + See Also + -------- + numpy.ndarray.round : corresponding function for ndarrays + numpy.around : equivalent function + """ + result = self._data.round(decimals=decimals, out=out).view(type(self)) + if result.ndim > 0: + result._mask = self._mask + result._update_from(self) + elif self._mask: + # Return masked when the scalar is masked + result = masked + # No explicit output: we're done + if out is None: + return result + if isinstance(out, MaskedArray): + out.__setmask__(self._mask) + return out + + def argsort(self, axis=np._NoValue, kind=None, order=None, + endwith=True, fill_value=None): + """ + Return an ndarray of indices that sort the array along the + specified axis. Masked values are filled beforehand to + `fill_value`. + + Parameters + ---------- + axis : int, optional + Axis along which to sort. If None, the default, the flattened array + is used. + + .. versionchanged:: 1.13.0 + Previously, the default was documented to be -1, but that was + in error. At some future date, the default will change to -1, as + originally intended. + Until then, the axis should be given explicitly when + ``arr.ndim > 1``, to avoid a FutureWarning. + kind : {'quicksort', 'mergesort', 'heapsort', 'stable'}, optional + The sorting algorithm used. + order : list, optional + When `a` is an array with fields defined, this argument specifies + which fields to compare first, second, etc. Not all fields need be + specified. + endwith : {True, False}, optional + Whether missing values (if any) should be treated as the largest values + (True) or the smallest values (False) + When the array contains unmasked values at the same extremes of the + datatype, the ordering of these values and the masked values is + undefined. + fill_value : {var}, optional + Value used internally for the masked values. + If ``fill_value`` is not None, it supersedes ``endwith``. + + Returns + ------- + index_array : ndarray, int + Array of indices that sort `a` along the specified axis. + In other words, ``a[index_array]`` yields a sorted `a`. + + See Also + -------- + ma.MaskedArray.sort : Describes sorting algorithms used. + lexsort : Indirect stable sort with multiple keys. + numpy.ndarray.sort : Inplace sort. + + Notes + ----- + See `sort` for notes on the different sorting algorithms. + + Examples + -------- + >>> a = np.ma.array([3,2,1], mask=[False, False, True]) + >>> a + masked_array(data=[3, 2, --], + mask=[False, False, True], + fill_value=999999) + >>> a.argsort() + array([1, 0, 2]) + + """ + + # 2017-04-11, Numpy 1.13.0, gh-8701: warn on axis default + if axis is np._NoValue: + axis = _deprecate_argsort_axis(self) + + if fill_value is None: + if endwith: + # nan > inf + if np.issubdtype(self.dtype, np.floating): + fill_value = np.nan + else: + fill_value = minimum_fill_value(self) + else: + fill_value = maximum_fill_value(self) + + filled = self.filled(fill_value) + return filled.argsort(axis=axis, kind=kind, order=order) + + def argmin(self, axis=None, fill_value=None, out=None): + """ + Return array of indices to the minimum values along the given axis. + + Parameters + ---------- + axis : {None, integer} + If None, the index is into the flattened array, otherwise along + the specified axis + fill_value : {var}, optional + Value used to fill in the masked values. If None, the output of + minimum_fill_value(self._data) is used instead. + out : {None, array}, optional + Array into which the result can be placed. Its type is preserved + and it must be of the right shape to hold the output. + + Returns + ------- + ndarray or scalar + If multi-dimension input, returns a new ndarray of indices to the + minimum values along the given axis. Otherwise, returns a scalar + of index to the minimum values along the given axis. + + Examples + -------- + >>> x = np.ma.array(np.arange(4), mask=[1,1,0,0]) + >>> x.shape = (2,2) + >>> x + masked_array( + data=[[--, --], + [2, 3]], + mask=[[ True, True], + [False, False]], + fill_value=999999) + >>> x.argmin(axis=0, fill_value=-1) + array([0, 0]) + >>> x.argmin(axis=0, fill_value=9) + array([1, 1]) + + """ + if fill_value is None: + fill_value = minimum_fill_value(self) + d = self.filled(fill_value).view(ndarray) + return d.argmin(axis, out=out) + + def argmax(self, axis=None, fill_value=None, out=None): + """ + Returns array of indices of the maximum values along the given axis. + Masked values are treated as if they had the value fill_value. + + Parameters + ---------- + axis : {None, integer} + If None, the index is into the flattened array, otherwise along + the specified axis + fill_value : {var}, optional + Value used to fill in the masked values. If None, the output of + maximum_fill_value(self._data) is used instead. + out : {None, array}, optional + Array into which the result can be placed. Its type is preserved + and it must be of the right shape to hold the output. + + Returns + ------- + index_array : {integer_array} + + Examples + -------- + >>> a = np.arange(6).reshape(2,3) + >>> a.argmax() + 5 + >>> a.argmax(0) + array([1, 1, 1]) + >>> a.argmax(1) + array([2, 2]) + + """ + if fill_value is None: + fill_value = maximum_fill_value(self._data) + d = self.filled(fill_value).view(ndarray) + return d.argmax(axis, out=out) + + def sort(self, axis=-1, kind=None, order=None, + endwith=True, fill_value=None): + """ + Sort the array, in-place + + Parameters + ---------- + a : array_like + Array to be sorted. + axis : int, optional + Axis along which to sort. If None, the array is flattened before + sorting. The default is -1, which sorts along the last axis. + kind : {'quicksort', 'mergesort', 'heapsort', 'stable'}, optional + The sorting algorithm used. + order : list, optional + When `a` is a structured array, this argument specifies which fields + to compare first, second, and so on. This list does not need to + include all of the fields. + endwith : {True, False}, optional + Whether missing values (if any) should be treated as the largest values + (True) or the smallest values (False) + When the array contains unmasked values sorting at the same extremes of the + datatype, the ordering of these values and the masked values is + undefined. + fill_value : {var}, optional + Value used internally for the masked values. + If ``fill_value`` is not None, it supersedes ``endwith``. + + Returns + ------- + sorted_array : ndarray + Array of the same type and shape as `a`. + + See Also + -------- + numpy.ndarray.sort : Method to sort an array in-place. + argsort : Indirect sort. + lexsort : Indirect stable sort on multiple keys. + searchsorted : Find elements in a sorted array. + + Notes + ----- + See ``sort`` for notes on the different sorting algorithms. + + Examples + -------- + >>> a = np.ma.array([1, 2, 5, 4, 3],mask=[0, 1, 0, 1, 0]) + >>> # Default + >>> a.sort() + >>> a + masked_array(data=[1, 3, 5, --, --], + mask=[False, False, False, True, True], + fill_value=999999) + + >>> a = np.ma.array([1, 2, 5, 4, 3],mask=[0, 1, 0, 1, 0]) + >>> # Put missing values in the front + >>> a.sort(endwith=False) + >>> a + masked_array(data=[--, --, 1, 3, 5], + mask=[ True, True, False, False, False], + fill_value=999999) + + >>> a = np.ma.array([1, 2, 5, 4, 3],mask=[0, 1, 0, 1, 0]) + >>> # fill_value takes over endwith + >>> a.sort(endwith=False, fill_value=3) + >>> a + masked_array(data=[1, --, --, 3, 5], + mask=[False, True, True, False, False], + fill_value=999999) + + """ + if self._mask is nomask: + ndarray.sort(self, axis=axis, kind=kind, order=order) + return + + if self is masked: + return + + sidx = self.argsort(axis=axis, kind=kind, order=order, + fill_value=fill_value, endwith=endwith) + + self[...] = np.take_along_axis(self, sidx, axis=axis) + + def min(self, axis=None, out=None, fill_value=None, keepdims=np._NoValue): + """ + Return the minimum along a given axis. + + Parameters + ---------- + axis : {None, int}, optional + Axis along which to operate. By default, ``axis`` is None and the + flattened input is used. + out : array_like, optional + Alternative output array in which to place the result. Must be of + the same shape and buffer length as the expected output. + fill_value : {var}, optional + Value used to fill in the masked values. + If None, use the output of `minimum_fill_value`. + keepdims : bool, optional + If this is set to True, the axes which are reduced are left + in the result as dimensions with size one. With this option, + the result will broadcast correctly against the array. + + Returns + ------- + amin : array_like + New array holding the result. + If ``out`` was specified, ``out`` is returned. + + See Also + -------- + ma.minimum_fill_value + Returns the minimum filling value for a given datatype. + + """ + kwargs = {} if keepdims is np._NoValue else {'keepdims': keepdims} + + _mask = self._mask + newmask = _check_mask_axis(_mask, axis, **kwargs) + if fill_value is None: + fill_value = minimum_fill_value(self) + # No explicit output + if out is None: + result = self.filled(fill_value).min( + axis=axis, out=out, **kwargs).view(type(self)) + if result.ndim: + # Set the mask + result.__setmask__(newmask) + # Get rid of Infs + if newmask.ndim: + np.copyto(result, result.fill_value, where=newmask) + elif newmask: + result = masked + return result + # Explicit output + result = self.filled(fill_value).min(axis=axis, out=out, **kwargs) + if isinstance(out, MaskedArray): + outmask = getmask(out) + if outmask is nomask: + outmask = out._mask = make_mask_none(out.shape) + outmask.flat = newmask + else: + if out.dtype.kind in 'biu': + errmsg = "Masked data information would be lost in one or more"\ + " location." + raise MaskError(errmsg) + np.copyto(out, np.nan, where=newmask) + return out + + # unique to masked arrays + def mini(self, axis=None): + """ + Return the array minimum along the specified axis. + + .. deprecated:: 1.13.0 + This function is identical to both: + + * ``self.min(keepdims=True, axis=axis).squeeze(axis=axis)`` + * ``np.ma.minimum.reduce(self, axis=axis)`` + + Typically though, ``self.min(axis=axis)`` is sufficient. + + Parameters + ---------- + axis : int, optional + The axis along which to find the minima. Default is None, in which case + the minimum value in the whole array is returned. + + Returns + ------- + min : scalar or MaskedArray + If `axis` is None, the result is a scalar. Otherwise, if `axis` is + given and the array is at least 2-D, the result is a masked array with + dimension one smaller than the array on which `mini` is called. + + Examples + -------- + >>> x = np.ma.array(np.arange(6), mask=[0 ,1, 0, 0, 0 ,1]).reshape(3, 2) + >>> x + masked_array( + data=[[0, --], + [2, 3], + [4, --]], + mask=[[False, True], + [False, False], + [False, True]], + fill_value=999999) + >>> x.mini() + masked_array(data=0, + mask=False, + fill_value=999999) + >>> x.mini(axis=0) + masked_array(data=[0, 3], + mask=[False, False], + fill_value=999999) + >>> x.mini(axis=1) + masked_array(data=[0, 2, 4], + mask=[False, False, False], + fill_value=999999) + + There is a small difference between `mini` and `min`: + + >>> x[:,1].mini(axis=0) + masked_array(data=3, + mask=False, + fill_value=999999) + >>> x[:,1].min(axis=0) + 3 + """ + + # 2016-04-13, 1.13.0, gh-8764 + warnings.warn( + "`mini` is deprecated; use the `min` method or " + "`np.ma.minimum.reduce instead.", + DeprecationWarning, stacklevel=2) + return minimum.reduce(self, axis) + + def max(self, axis=None, out=None, fill_value=None, keepdims=np._NoValue): + """ + Return the maximum along a given axis. + + Parameters + ---------- + axis : {None, int}, optional + Axis along which to operate. By default, ``axis`` is None and the + flattened input is used. + out : array_like, optional + Alternative output array in which to place the result. Must + be of the same shape and buffer length as the expected output. + fill_value : {var}, optional + Value used to fill in the masked values. + If None, use the output of maximum_fill_value(). + keepdims : bool, optional + If this is set to True, the axes which are reduced are left + in the result as dimensions with size one. With this option, + the result will broadcast correctly against the array. + + Returns + ------- + amax : array_like + New array holding the result. + If ``out`` was specified, ``out`` is returned. + + See Also + -------- + ma.maximum_fill_value + Returns the maximum filling value for a given datatype. + + """ + kwargs = {} if keepdims is np._NoValue else {'keepdims': keepdims} + + _mask = self._mask + newmask = _check_mask_axis(_mask, axis, **kwargs) + if fill_value is None: + fill_value = maximum_fill_value(self) + # No explicit output + if out is None: + result = self.filled(fill_value).max( + axis=axis, out=out, **kwargs).view(type(self)) + if result.ndim: + # Set the mask + result.__setmask__(newmask) + # Get rid of Infs + if newmask.ndim: + np.copyto(result, result.fill_value, where=newmask) + elif newmask: + result = masked + return result + # Explicit output + result = self.filled(fill_value).max(axis=axis, out=out, **kwargs) + if isinstance(out, MaskedArray): + outmask = getmask(out) + if outmask is nomask: + outmask = out._mask = make_mask_none(out.shape) + outmask.flat = newmask + else: + + if out.dtype.kind in 'biu': + errmsg = "Masked data information would be lost in one or more"\ + " location." + raise MaskError(errmsg) + np.copyto(out, np.nan, where=newmask) + return out + + def ptp(self, axis=None, out=None, fill_value=None, keepdims=False): + """ + Return (maximum - minimum) along the given dimension + (i.e. peak-to-peak value). + + .. warning:: + `ptp` preserves the data type of the array. This means the + return value for an input of signed integers with n bits + (e.g. `np.int8`, `np.int16`, etc) is also a signed integer + with n bits. In that case, peak-to-peak values greater than + ``2**(n-1)-1`` will be returned as negative values. An example + with a work-around is shown below. + + Parameters + ---------- + axis : {None, int}, optional + Axis along which to find the peaks. If None (default) the + flattened array is used. + out : {None, array_like}, optional + Alternative output array in which to place the result. It must + have the same shape and buffer length as the expected output + but the type will be cast if necessary. + fill_value : {var}, optional + Value used to fill in the masked values. + keepdims : bool, optional + If this is set to True, the axes which are reduced are left + in the result as dimensions with size one. With this option, + the result will broadcast correctly against the array. + + Returns + ------- + ptp : ndarray. + A new array holding the result, unless ``out`` was + specified, in which case a reference to ``out`` is returned. + + Examples + -------- + >>> x = np.ma.MaskedArray([[4, 9, 2, 10], + ... [6, 9, 7, 12]]) + + >>> x.ptp(axis=1) + masked_array(data=[8, 6], + mask=False, + fill_value=999999) + + >>> x.ptp(axis=0) + masked_array(data=[2, 0, 5, 2], + mask=False, + fill_value=999999) + + >>> x.ptp() + 10 + + This example shows that a negative value can be returned when + the input is an array of signed integers. + + >>> y = np.ma.MaskedArray([[1, 127], + ... [0, 127], + ... [-1, 127], + ... [-2, 127]], dtype=np.int8) + >>> y.ptp(axis=1) + masked_array(data=[ 126, 127, -128, -127], + mask=False, + fill_value=999999, + dtype=int8) + + A work-around is to use the `view()` method to view the result as + unsigned integers with the same bit width: + + >>> y.ptp(axis=1).view(np.uint8) + masked_array(data=[126, 127, 128, 129], + mask=False, + fill_value=999999, + dtype=uint8) + """ + if out is None: + result = self.max(axis=axis, fill_value=fill_value, + keepdims=keepdims) + result -= self.min(axis=axis, fill_value=fill_value, + keepdims=keepdims) + return result + out.flat = self.max(axis=axis, out=out, fill_value=fill_value, + keepdims=keepdims) + min_value = self.min(axis=axis, fill_value=fill_value, + keepdims=keepdims) + np.subtract(out, min_value, out=out, casting='unsafe') + return out + + def partition(self, *args, **kwargs): + warnings.warn("Warning: 'partition' will ignore the 'mask' " + f"of the {self.__class__.__name__}.", + stacklevel=2) + return super(MaskedArray, self).partition(*args, **kwargs) + + def argpartition(self, *args, **kwargs): + warnings.warn("Warning: 'argpartition' will ignore the 'mask' " + f"of the {self.__class__.__name__}.", + stacklevel=2) + return super(MaskedArray, self).argpartition(*args, **kwargs) + + def take(self, indices, axis=None, out=None, mode='raise'): + """ + """ + (_data, _mask) = (self._data, self._mask) + cls = type(self) + # Make sure the indices are not masked + maskindices = getmask(indices) + if maskindices is not nomask: + indices = indices.filled(0) + # Get the data, promoting scalars to 0d arrays with [...] so that + # .view works correctly + if out is None: + out = _data.take(indices, axis=axis, mode=mode)[...].view(cls) + else: + np.take(_data, indices, axis=axis, mode=mode, out=out) + # Get the mask + if isinstance(out, MaskedArray): + if _mask is nomask: + outmask = maskindices + else: + outmask = _mask.take(indices, axis=axis, mode=mode) + outmask |= maskindices + out.__setmask__(outmask) + # demote 0d arrays back to scalars, for consistency with ndarray.take + return out[()] + + # Array methods + copy = _arraymethod('copy') + diagonal = _arraymethod('diagonal') + flatten = _arraymethod('flatten') + repeat = _arraymethod('repeat') + squeeze = _arraymethod('squeeze') + swapaxes = _arraymethod('swapaxes') + T = property(fget=lambda self: self.transpose()) + transpose = _arraymethod('transpose') + + def tolist(self, fill_value=None): + """ + Return the data portion of the masked array as a hierarchical Python list. + + Data items are converted to the nearest compatible Python type. + Masked values are converted to `fill_value`. If `fill_value` is None, + the corresponding entries in the output list will be ``None``. + + Parameters + ---------- + fill_value : scalar, optional + The value to use for invalid entries. Default is None. + + Returns + ------- + result : list + The Python list representation of the masked array. + + Examples + -------- + >>> x = np.ma.array([[1,2,3], [4,5,6], [7,8,9]], mask=[0] + [1,0]*4) + >>> x.tolist() + [[1, None, 3], [None, 5, None], [7, None, 9]] + >>> x.tolist(-999) + [[1, -999, 3], [-999, 5, -999], [7, -999, 9]] + + """ + _mask = self._mask + # No mask ? Just return .data.tolist ? + if _mask is nomask: + return self._data.tolist() + # Explicit fill_value: fill the array and get the list + if fill_value is not None: + return self.filled(fill_value).tolist() + # Structured array. + names = self.dtype.names + if names: + result = self._data.astype([(_, object) for _ in names]) + for n in names: + result[n][_mask[n]] = None + return result.tolist() + # Standard arrays. + if _mask is nomask: + return [None] + # Set temps to save time when dealing w/ marrays. + inishape = self.shape + result = np.array(self._data.ravel(), dtype=object) + result[_mask.ravel()] = None + result.shape = inishape + return result.tolist() + + def tostring(self, fill_value=None, order='C'): + r""" + A compatibility alias for `tobytes`, with exactly the same behavior. + + Despite its name, it returns `bytes` not `str`\ s. + + .. deprecated:: 1.19.0 + """ + # 2020-03-30, Numpy 1.19.0 + warnings.warn( + "tostring() is deprecated. Use tobytes() instead.", + DeprecationWarning, stacklevel=2) + + return self.tobytes(fill_value, order=order) + + def tobytes(self, fill_value=None, order='C'): + """ + Return the array data as a string containing the raw bytes in the array. + + The array is filled with a fill value before the string conversion. + + .. versionadded:: 1.9.0 + + Parameters + ---------- + fill_value : scalar, optional + Value used to fill in the masked values. Default is None, in which + case `MaskedArray.fill_value` is used. + order : {'C','F','A'}, optional + Order of the data item in the copy. Default is 'C'. + + - 'C' -- C order (row major). + - 'F' -- Fortran order (column major). + - 'A' -- Any, current order of array. + - None -- Same as 'A'. + + See Also + -------- + numpy.ndarray.tobytes + tolist, tofile + + Notes + ----- + As for `ndarray.tobytes`, information about the shape, dtype, etc., + but also about `fill_value`, will be lost. + + Examples + -------- + >>> x = np.ma.array(np.array([[1, 2], [3, 4]]), mask=[[0, 1], [1, 0]]) + >>> x.tobytes() + b'\\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x00?B\\x0f\\x00\\x00\\x00\\x00\\x00?B\\x0f\\x00\\x00\\x00\\x00\\x00\\x04\\x00\\x00\\x00\\x00\\x00\\x00\\x00' + + """ + return self.filled(fill_value).tobytes(order=order) + + def tofile(self, fid, sep="", format="%s"): + """ + Save a masked array to a file in binary format. + + .. warning:: + This function is not implemented yet. + + Raises + ------ + NotImplementedError + When `tofile` is called. + + """ + raise NotImplementedError("MaskedArray.tofile() not implemented yet.") + + def toflex(self): + """ + Transforms a masked array into a flexible-type array. + + The flexible type array that is returned will have two fields: + + * the ``_data`` field stores the ``_data`` part of the array. + * the ``_mask`` field stores the ``_mask`` part of the array. + + Parameters + ---------- + None + + Returns + ------- + record : ndarray + A new flexible-type `ndarray` with two fields: the first element + containing a value, the second element containing the corresponding + mask boolean. The returned record shape matches self.shape. + + Notes + ----- + A side-effect of transforming a masked array into a flexible `ndarray` is + that meta information (``fill_value``, ...) will be lost. + + Examples + -------- + >>> x = np.ma.array([[1,2,3],[4,5,6],[7,8,9]], mask=[0] + [1,0]*4) + >>> x + masked_array( + data=[[1, --, 3], + [--, 5, --], + [7, --, 9]], + mask=[[False, True, False], + [ True, False, True], + [False, True, False]], + fill_value=999999) + >>> x.toflex() + array([[(1, False), (2, True), (3, False)], + [(4, True), (5, False), (6, True)], + [(7, False), (8, True), (9, False)]], + dtype=[('_data', 'i2", (2,))]) + # x = A[0]; y = x["A"]; then y.mask["A"].size==2 + # and we can not say masked/unmasked. + # The result is no longer mvoid! + # See also issue #6724. + return masked_array( + data=self._data[indx], mask=m[indx], + fill_value=self._fill_value[indx], + hard_mask=self._hardmask) + if m is not nomask and m[indx]: + return masked + return self._data[indx] + + def __setitem__(self, indx, value): + self._data[indx] = value + if self._hardmask: + self._mask[indx] |= getattr(value, "_mask", False) + else: + self._mask[indx] = getattr(value, "_mask", False) + + def __str__(self): + m = self._mask + if m is nomask: + return str(self._data) + + rdtype = _replace_dtype_fields(self._data.dtype, "O") + data_arr = super(mvoid, self)._data + res = data_arr.astype(rdtype) + _recursive_printoption(res, self._mask, masked_print_option) + return str(res) + + __repr__ = __str__ + + def __iter__(self): + "Defines an iterator for mvoid" + (_data, _mask) = (self._data, self._mask) + if _mask is nomask: + yield from _data + else: + for (d, m) in zip(_data, _mask): + if m: + yield masked + else: + yield d + + def __len__(self): + return self._data.__len__() + + def filled(self, fill_value=None): + """ + Return a copy with masked fields filled with a given value. + + Parameters + ---------- + fill_value : array_like, optional + The value to use for invalid entries. Can be scalar or + non-scalar. If latter is the case, the filled array should + be broadcastable over input array. Default is None, in + which case the `fill_value` attribute is used instead. + + Returns + ------- + filled_void + A `np.void` object + + See Also + -------- + MaskedArray.filled + + """ + return asarray(self).filled(fill_value)[()] + + def tolist(self): + """ + Transforms the mvoid object into a tuple. + + Masked fields are replaced by None. + + Returns + ------- + returned_tuple + Tuple of fields + """ + _mask = self._mask + if _mask is nomask: + return self._data.tolist() + result = [] + for (d, m) in zip(self._data, self._mask): + if m: + result.append(None) + else: + # .item() makes sure we return a standard Python object + result.append(d.item()) + return tuple(result) + + +############################################################################## +# Shortcuts # +############################################################################## + + +def isMaskedArray(x): + """ + Test whether input is an instance of MaskedArray. + + This function returns True if `x` is an instance of MaskedArray + and returns False otherwise. Any object is accepted as input. + + Parameters + ---------- + x : object + Object to test. + + Returns + ------- + result : bool + True if `x` is a MaskedArray. + + See Also + -------- + isMA : Alias to isMaskedArray. + isarray : Alias to isMaskedArray. + + Examples + -------- + >>> import numpy.ma as ma + >>> a = np.eye(3, 3) + >>> a + array([[ 1., 0., 0.], + [ 0., 1., 0.], + [ 0., 0., 1.]]) + >>> m = ma.masked_values(a, 0) + >>> m + masked_array( + data=[[1.0, --, --], + [--, 1.0, --], + [--, --, 1.0]], + mask=[[False, True, True], + [ True, False, True], + [ True, True, False]], + fill_value=0.0) + >>> ma.isMaskedArray(a) + False + >>> ma.isMaskedArray(m) + True + >>> ma.isMaskedArray([0, 1, 2]) + False + + """ + return isinstance(x, MaskedArray) + + +isarray = isMaskedArray +isMA = isMaskedArray # backward compatibility + + +class MaskedConstant(MaskedArray): + # the lone np.ma.masked instance + __singleton = None + + @classmethod + def __has_singleton(cls): + # second case ensures `cls.__singleton` is not just a view on the + # superclass singleton + return cls.__singleton is not None and type(cls.__singleton) is cls + + def __new__(cls): + if not cls.__has_singleton(): + # We define the masked singleton as a float for higher precedence. + # Note that it can be tricky sometimes w/ type comparison + data = np.array(0.) + mask = np.array(True) + + # prevent any modifications + data.flags.writeable = False + mask.flags.writeable = False + + # don't fall back on MaskedArray.__new__(MaskedConstant), since + # that might confuse it - this way, the construction is entirely + # within our control + cls.__singleton = MaskedArray(data, mask=mask).view(cls) + + return cls.__singleton + + def __array_finalize__(self, obj): + if not self.__has_singleton(): + # this handles the `.view` in __new__, which we want to copy across + # properties normally + return super(MaskedConstant, self).__array_finalize__(obj) + elif self is self.__singleton: + # not clear how this can happen, play it safe + pass + else: + # everywhere else, we want to downcast to MaskedArray, to prevent a + # duplicate maskedconstant. + self.__class__ = MaskedArray + MaskedArray.__array_finalize__(self, obj) + + def __array_prepare__(self, obj, context=None): + return self.view(MaskedArray).__array_prepare__(obj, context) + + def __array_wrap__(self, obj, context=None): + return self.view(MaskedArray).__array_wrap__(obj, context) + + def __str__(self): + return str(masked_print_option._display) + + def __repr__(self): + if self is MaskedConstant.__singleton: + return 'masked' + else: + # it's a subclass, or something is wrong, make it obvious + return object.__repr__(self) + + def __format__(self, format_spec): + # Replace ndarray.__format__ with the default, which supports no format characters. + # Supporting format characters is unwise here, because we do not know what type + # the user was expecting - better to not guess. + try: + return object.__format__(self, format_spec) + except TypeError: + # 2020-03-23, NumPy 1.19.0 + warnings.warn( + "Format strings passed to MaskedConstant are ignored, but in future may " + "error or produce different behavior", + FutureWarning, stacklevel=2 + ) + return object.__format__(self, "") + + def __reduce__(self): + """Override of MaskedArray's __reduce__. + """ + return (self.__class__, ()) + + # inplace operations have no effect. We have to override them to avoid + # trying to modify the readonly data and mask arrays + def __iop__(self, other): + return self + __iadd__ = \ + __isub__ = \ + __imul__ = \ + __ifloordiv__ = \ + __itruediv__ = \ + __ipow__ = \ + __iop__ + del __iop__ # don't leave this around + + def copy(self, *args, **kwargs): + """ Copy is a no-op on the maskedconstant, as it is a scalar """ + # maskedconstant is a scalar, so copy doesn't need to copy. There's + # precedent for this with `np.bool_` scalars. + return self + + def __copy__(self): + return self + + def __deepcopy__(self, memo): + return self + + def __setattr__(self, attr, value): + if not self.__has_singleton(): + # allow the singleton to be initialized + return super(MaskedConstant, self).__setattr__(attr, value) + elif self is self.__singleton: + raise AttributeError( + f"attributes of {self!r} are not writeable") + else: + # duplicate instance - we can end up here from __array_finalize__, + # where we set the __class__ attribute + return super(MaskedConstant, self).__setattr__(attr, value) + + +masked = masked_singleton = MaskedConstant() +masked_array = MaskedArray + + +def array(data, dtype=None, copy=False, order=None, + mask=nomask, fill_value=None, keep_mask=True, + hard_mask=False, shrink=True, subok=True, ndmin=0): + """ + Shortcut to MaskedArray. + + The options are in a different order for convenience and backwards + compatibility. + + """ + return MaskedArray(data, mask=mask, dtype=dtype, copy=copy, + subok=subok, keep_mask=keep_mask, + hard_mask=hard_mask, fill_value=fill_value, + ndmin=ndmin, shrink=shrink, order=order) +array.__doc__ = masked_array.__doc__ + + +def is_masked(x): + """ + Determine whether input has masked values. + + Accepts any object as input, but always returns False unless the + input is a MaskedArray containing masked values. + + Parameters + ---------- + x : array_like + Array to check for masked values. + + Returns + ------- + result : bool + True if `x` is a MaskedArray with masked values, False otherwise. + + Examples + -------- + >>> import numpy.ma as ma + >>> x = ma.masked_equal([0, 1, 0, 2, 3], 0) + >>> x + masked_array(data=[--, 1, --, 2, 3], + mask=[ True, False, True, False, False], + fill_value=0) + >>> ma.is_masked(x) + True + >>> x = ma.masked_equal([0, 1, 0, 2, 3], 42) + >>> x + masked_array(data=[0, 1, 0, 2, 3], + mask=False, + fill_value=42) + >>> ma.is_masked(x) + False + + Always returns False if `x` isn't a MaskedArray. + + >>> x = [False, True, False] + >>> ma.is_masked(x) + False + >>> x = 'a string' + >>> ma.is_masked(x) + False + + """ + m = getmask(x) + if m is nomask: + return False + elif m.any(): + return True + return False + + +############################################################################## +# Extrema functions # +############################################################################## + + +class _extrema_operation(_MaskedUFunc): + """ + Generic class for maximum/minimum functions. + + .. note:: + This is the base class for `_maximum_operation` and + `_minimum_operation`. + + """ + def __init__(self, ufunc, compare, fill_value): + super(_extrema_operation, self).__init__(ufunc) + self.compare = compare + self.fill_value_func = fill_value + + def __call__(self, a, b=None): + "Executes the call behavior." + if b is None: + # 2016-04-13, 1.13.0 + warnings.warn( + f"Single-argument form of np.ma.{self.__name__} is deprecated. Use " + f"np.ma.{self.__name__}.reduce instead.", + DeprecationWarning, stacklevel=2) + return self.reduce(a) + return where(self.compare(a, b), a, b) + + def reduce(self, target, axis=np._NoValue): + "Reduce target along the given axis." + target = narray(target, copy=False, subok=True) + m = getmask(target) + + if axis is np._NoValue and target.ndim > 1: + # 2017-05-06, Numpy 1.13.0: warn on axis default + warnings.warn( + f"In the future the default for ma.{self.__name__}.reduce will be axis=0, " + f"not the current None, to match np.{self.__name__}.reduce. " + "Explicitly pass 0 or None to silence this warning.", + MaskedArrayFutureWarning, stacklevel=2) + axis = None + + if axis is not np._NoValue: + kwargs = dict(axis=axis) + else: + kwargs = dict() + + if m is nomask: + t = self.f.reduce(target, **kwargs) + else: + target = target.filled( + self.fill_value_func(target)).view(type(target)) + t = self.f.reduce(target, **kwargs) + m = umath.logical_and.reduce(m, **kwargs) + if hasattr(t, '_mask'): + t._mask = m + elif m: + t = masked + return t + + def outer(self, a, b): + "Return the function applied to the outer product of a and b." + ma = getmask(a) + mb = getmask(b) + if ma is nomask and mb is nomask: + m = nomask + else: + ma = getmaskarray(a) + mb = getmaskarray(b) + m = logical_or.outer(ma, mb) + result = self.f.outer(filled(a), filled(b)) + if not isinstance(result, MaskedArray): + result = result.view(MaskedArray) + result._mask = m + return result + +def min(obj, axis=None, out=None, fill_value=None, keepdims=np._NoValue): + kwargs = {} if keepdims is np._NoValue else {'keepdims': keepdims} + + try: + return obj.min(axis=axis, fill_value=fill_value, out=out, **kwargs) + except (AttributeError, TypeError): + # If obj doesn't have a min method, or if the method doesn't accept a + # fill_value argument + return asanyarray(obj).min(axis=axis, fill_value=fill_value, + out=out, **kwargs) +min.__doc__ = MaskedArray.min.__doc__ + +def max(obj, axis=None, out=None, fill_value=None, keepdims=np._NoValue): + kwargs = {} if keepdims is np._NoValue else {'keepdims': keepdims} + + try: + return obj.max(axis=axis, fill_value=fill_value, out=out, **kwargs) + except (AttributeError, TypeError): + # If obj doesn't have a max method, or if the method doesn't accept a + # fill_value argument + return asanyarray(obj).max(axis=axis, fill_value=fill_value, + out=out, **kwargs) +max.__doc__ = MaskedArray.max.__doc__ + + +def ptp(obj, axis=None, out=None, fill_value=None, keepdims=np._NoValue): + kwargs = {} if keepdims is np._NoValue else {'keepdims': keepdims} + try: + return obj.ptp(axis, out=out, fill_value=fill_value, **kwargs) + except (AttributeError, TypeError): + # If obj doesn't have a ptp method or if the method doesn't accept + # a fill_value argument + return asanyarray(obj).ptp(axis=axis, fill_value=fill_value, + out=out, **kwargs) +ptp.__doc__ = MaskedArray.ptp.__doc__ + + +############################################################################## +# Definition of functions from the corresponding methods # +############################################################################## + + +class _frommethod: + """ + Define functions from existing MaskedArray methods. + + Parameters + ---------- + methodname : str + Name of the method to transform. + + """ + + def __init__(self, methodname, reversed=False): + self.__name__ = methodname + self.__doc__ = self.getdoc() + self.reversed = reversed + + def getdoc(self): + "Return the doc of the function (from the doc of the method)." + meth = getattr(MaskedArray, self.__name__, None) or\ + getattr(np, self.__name__, None) + signature = self.__name__ + get_object_signature(meth) + if meth is not None: + doc = """ %s\n%s""" % ( + signature, getattr(meth, '__doc__', None)) + return doc + + def __call__(self, a, *args, **params): + if self.reversed: + args = list(args) + a, args[0] = args[0], a + + marr = asanyarray(a) + method_name = self.__name__ + method = getattr(type(marr), method_name, None) + if method is None: + # use the corresponding np function + method = getattr(np, method_name) + + return method(marr, *args, **params) + + +all = _frommethod('all') +anomalies = anom = _frommethod('anom') +any = _frommethod('any') +compress = _frommethod('compress', reversed=True) +cumprod = _frommethod('cumprod') +cumsum = _frommethod('cumsum') +copy = _frommethod('copy') +diagonal = _frommethod('diagonal') +harden_mask = _frommethod('harden_mask') +ids = _frommethod('ids') +maximum = _extrema_operation(umath.maximum, greater, maximum_fill_value) +mean = _frommethod('mean') +minimum = _extrema_operation(umath.minimum, less, minimum_fill_value) +nonzero = _frommethod('nonzero') +prod = _frommethod('prod') +product = _frommethod('prod') +ravel = _frommethod('ravel') +repeat = _frommethod('repeat') +shrink_mask = _frommethod('shrink_mask') +soften_mask = _frommethod('soften_mask') +std = _frommethod('std') +sum = _frommethod('sum') +swapaxes = _frommethod('swapaxes') +#take = _frommethod('take') +trace = _frommethod('trace') +var = _frommethod('var') + +count = _frommethod('count') + +def take(a, indices, axis=None, out=None, mode='raise'): + """ + """ + a = masked_array(a) + return a.take(indices, axis=axis, out=out, mode=mode) + + +def power(a, b, third=None): + """ + Returns element-wise base array raised to power from second array. + + This is the masked array version of `numpy.power`. For details see + `numpy.power`. + + See Also + -------- + numpy.power + + Notes + ----- + The *out* argument to `numpy.power` is not supported, `third` has to be + None. + + """ + if third is not None: + raise MaskError("3-argument power not supported.") + # Get the masks + ma = getmask(a) + mb = getmask(b) + m = mask_or(ma, mb) + # Get the rawdata + fa = getdata(a) + fb = getdata(b) + # Get the type of the result (so that we preserve subclasses) + if isinstance(a, MaskedArray): + basetype = type(a) + else: + basetype = MaskedArray + # Get the result and view it as a (subclass of) MaskedArray + with np.errstate(divide='ignore', invalid='ignore'): + result = np.where(m, fa, umath.power(fa, fb)).view(basetype) + result._update_from(a) + # Find where we're in trouble w/ NaNs and Infs + invalid = np.logical_not(np.isfinite(result.view(ndarray))) + # Add the initial mask + if m is not nomask: + if not result.ndim: + return masked + result._mask = np.logical_or(m, invalid) + # Fix the invalid parts + if invalid.any(): + if not result.ndim: + return masked + elif result._mask is nomask: + result._mask = invalid + result._data[invalid] = result.fill_value + return result + +argmin = _frommethod('argmin') +argmax = _frommethod('argmax') + +def argsort(a, axis=np._NoValue, kind=None, order=None, endwith=True, fill_value=None): + "Function version of the eponymous method." + a = np.asanyarray(a) + + # 2017-04-11, Numpy 1.13.0, gh-8701: warn on axis default + if axis is np._NoValue: + axis = _deprecate_argsort_axis(a) + + if isinstance(a, MaskedArray): + return a.argsort(axis=axis, kind=kind, order=order, + endwith=endwith, fill_value=fill_value) + else: + return a.argsort(axis=axis, kind=kind, order=order) +argsort.__doc__ = MaskedArray.argsort.__doc__ + +def sort(a, axis=-1, kind=None, order=None, endwith=True, fill_value=None): + """ + Return a sorted copy of the masked array. + + Equivalent to creating a copy of the array + and applying the MaskedArray ``sort()`` method. + + Refer to ``MaskedArray.sort`` for the full documentation + + See Also + -------- + MaskedArray.sort : equivalent method + """ + a = np.array(a, copy=True, subok=True) + if axis is None: + a = a.flatten() + axis = 0 + + if isinstance(a, MaskedArray): + a.sort(axis=axis, kind=kind, order=order, + endwith=endwith, fill_value=fill_value) + else: + a.sort(axis=axis, kind=kind, order=order) + return a + + +def compressed(x): + """ + Return all the non-masked data as a 1-D array. + + This function is equivalent to calling the "compressed" method of a + `ma.MaskedArray`, see `ma.MaskedArray.compressed` for details. + + See Also + -------- + ma.MaskedArray.compressed + Equivalent method. + + """ + return asanyarray(x).compressed() + + +def concatenate(arrays, axis=0): + """ + Concatenate a sequence of arrays along the given axis. + + Parameters + ---------- + arrays : sequence of array_like + The arrays must have the same shape, except in the dimension + corresponding to `axis` (the first, by default). + axis : int, optional + The axis along which the arrays will be joined. Default is 0. + + Returns + ------- + result : MaskedArray + The concatenated array with any masked entries preserved. + + See Also + -------- + numpy.concatenate : Equivalent function in the top-level NumPy module. + + Examples + -------- + >>> import numpy.ma as ma + >>> a = ma.arange(3) + >>> a[1] = ma.masked + >>> b = ma.arange(2, 5) + >>> a + masked_array(data=[0, --, 2], + mask=[False, True, False], + fill_value=999999) + >>> b + masked_array(data=[2, 3, 4], + mask=False, + fill_value=999999) + >>> ma.concatenate([a, b]) + masked_array(data=[0, --, 2, 2, 3, 4], + mask=[False, True, False, False, False, False], + fill_value=999999) + + """ + d = np.concatenate([getdata(a) for a in arrays], axis) + rcls = get_masked_subclass(*arrays) + data = d.view(rcls) + # Check whether one of the arrays has a non-empty mask. + for x in arrays: + if getmask(x) is not nomask: + break + else: + return data + # OK, so we have to concatenate the masks + dm = np.concatenate([getmaskarray(a) for a in arrays], axis) + dm = dm.reshape(d.shape) + + # If we decide to keep a '_shrinkmask' option, we want to check that + # all of them are True, and then check for dm.any() + data._mask = _shrink_mask(dm) + return data + + +def diag(v, k=0): + """ + Extract a diagonal or construct a diagonal array. + + This function is the equivalent of `numpy.diag` that takes masked + values into account, see `numpy.diag` for details. + + See Also + -------- + numpy.diag : Equivalent function for ndarrays. + + """ + output = np.diag(v, k).view(MaskedArray) + if getmask(v) is not nomask: + output._mask = np.diag(v._mask, k) + return output + + +def left_shift(a, n): + """ + Shift the bits of an integer to the left. + + This is the masked array version of `numpy.left_shift`, for details + see that function. + + See Also + -------- + numpy.left_shift + + """ + m = getmask(a) + if m is nomask: + d = umath.left_shift(filled(a), n) + return masked_array(d) + else: + d = umath.left_shift(filled(a, 0), n) + return masked_array(d, mask=m) + + +def right_shift(a, n): + """ + Shift the bits of an integer to the right. + + This is the masked array version of `numpy.right_shift`, for details + see that function. + + See Also + -------- + numpy.right_shift + + """ + m = getmask(a) + if m is nomask: + d = umath.right_shift(filled(a), n) + return masked_array(d) + else: + d = umath.right_shift(filled(a, 0), n) + return masked_array(d, mask=m) + + +def put(a, indices, values, mode='raise'): + """ + Set storage-indexed locations to corresponding values. + + This function is equivalent to `MaskedArray.put`, see that method + for details. + + See Also + -------- + MaskedArray.put + + """ + # We can't use 'frommethod', the order of arguments is different + try: + return a.put(indices, values, mode=mode) + except AttributeError: + return narray(a, copy=False).put(indices, values, mode=mode) + + +def putmask(a, mask, values): # , mode='raise'): + """ + Changes elements of an array based on conditional and input values. + + This is the masked array version of `numpy.putmask`, for details see + `numpy.putmask`. + + See Also + -------- + numpy.putmask + + Notes + ----- + Using a masked array as `values` will **not** transform a `ndarray` into + a `MaskedArray`. + + """ + # We can't use 'frommethod', the order of arguments is different + if not isinstance(a, MaskedArray): + a = a.view(MaskedArray) + (valdata, valmask) = (getdata(values), getmask(values)) + if getmask(a) is nomask: + if valmask is not nomask: + a._sharedmask = True + a._mask = make_mask_none(a.shape, a.dtype) + np.copyto(a._mask, valmask, where=mask) + elif a._hardmask: + if valmask is not nomask: + m = a._mask.copy() + np.copyto(m, valmask, where=mask) + a.mask |= m + else: + if valmask is nomask: + valmask = getmaskarray(values) + np.copyto(a._mask, valmask, where=mask) + np.copyto(a._data, valdata, where=mask) + return + + +def transpose(a, axes=None): + """ + Permute the dimensions of an array. + + This function is exactly equivalent to `numpy.transpose`. + + See Also + -------- + numpy.transpose : Equivalent function in top-level NumPy module. + + Examples + -------- + >>> import numpy.ma as ma + >>> x = ma.arange(4).reshape((2,2)) + >>> x[1, 1] = ma.masked + >>> x + masked_array( + data=[[0, 1], + [2, --]], + mask=[[False, False], + [False, True]], + fill_value=999999) + + >>> ma.transpose(x) + masked_array( + data=[[0, 2], + [1, --]], + mask=[[False, False], + [False, True]], + fill_value=999999) + """ + # We can't use 'frommethod', as 'transpose' doesn't take keywords + try: + return a.transpose(axes) + except AttributeError: + return narray(a, copy=False).transpose(axes).view(MaskedArray) + + +def reshape(a, new_shape, order='C'): + """ + Returns an array containing the same data with a new shape. + + Refer to `MaskedArray.reshape` for full documentation. + + See Also + -------- + MaskedArray.reshape : equivalent function + + """ + # We can't use 'frommethod', it whine about some parameters. Dmmit. + try: + return a.reshape(new_shape, order=order) + except AttributeError: + _tmp = narray(a, copy=False).reshape(new_shape, order=order) + return _tmp.view(MaskedArray) + + +def resize(x, new_shape): + """ + Return a new masked array with the specified size and shape. + + This is the masked equivalent of the `numpy.resize` function. The new + array is filled with repeated copies of `x` (in the order that the + data are stored in memory). If `x` is masked, the new array will be + masked, and the new mask will be a repetition of the old one. + + See Also + -------- + numpy.resize : Equivalent function in the top level NumPy module. + + Examples + -------- + >>> import numpy.ma as ma + >>> a = ma.array([[1, 2] ,[3, 4]]) + >>> a[0, 1] = ma.masked + >>> a + masked_array( + data=[[1, --], + [3, 4]], + mask=[[False, True], + [False, False]], + fill_value=999999) + >>> np.resize(a, (3, 3)) + masked_array( + data=[[1, 2, 3], + [4, 1, 2], + [3, 4, 1]], + mask=False, + fill_value=999999) + >>> ma.resize(a, (3, 3)) + masked_array( + data=[[1, --, 3], + [4, 1, --], + [3, 4, 1]], + mask=[[False, True, False], + [False, False, True], + [False, False, False]], + fill_value=999999) + + A MaskedArray is always returned, regardless of the input type. + + >>> a = np.array([[1, 2] ,[3, 4]]) + >>> ma.resize(a, (3, 3)) + masked_array( + data=[[1, 2, 3], + [4, 1, 2], + [3, 4, 1]], + mask=False, + fill_value=999999) + + """ + # We can't use _frommethods here, as N.resize is notoriously whiny. + m = getmask(x) + if m is not nomask: + m = np.resize(m, new_shape) + result = np.resize(x, new_shape).view(get_masked_subclass(x)) + if result.ndim: + result._mask = m + return result + + +def ndim(obj): + """ + maskedarray version of the numpy function. + + """ + return np.ndim(getdata(obj)) + +ndim.__doc__ = np.ndim.__doc__ + + +def shape(obj): + "maskedarray version of the numpy function." + return np.shape(getdata(obj)) +shape.__doc__ = np.shape.__doc__ + + +def size(obj, axis=None): + "maskedarray version of the numpy function." + return np.size(getdata(obj), axis) +size.__doc__ = np.size.__doc__ + + +############################################################################## +# Extra functions # +############################################################################## + + +def where(condition, x=_NoValue, y=_NoValue): + """ + Return a masked array with elements from `x` or `y`, depending on condition. + + .. note:: + When only `condition` is provided, this function is identical to + `nonzero`. The rest of this documentation covers only the case where + all three arguments are provided. + + Parameters + ---------- + condition : array_like, bool + Where True, yield `x`, otherwise yield `y`. + x, y : array_like, optional + Values from which to choose. `x`, `y` and `condition` need to be + broadcastable to some shape. + + Returns + ------- + out : MaskedArray + An masked array with `masked` elements where the condition is masked, + elements from `x` where `condition` is True, and elements from `y` + elsewhere. + + See Also + -------- + numpy.where : Equivalent function in the top-level NumPy module. + nonzero : The function that is called when x and y are omitted + + Examples + -------- + >>> x = np.ma.array(np.arange(9.).reshape(3, 3), mask=[[0, 1, 0], + ... [1, 0, 1], + ... [0, 1, 0]]) + >>> x + masked_array( + data=[[0.0, --, 2.0], + [--, 4.0, --], + [6.0, --, 8.0]], + mask=[[False, True, False], + [ True, False, True], + [False, True, False]], + fill_value=1e+20) + >>> np.ma.where(x > 5, x, -3.1416) + masked_array( + data=[[-3.1416, --, -3.1416], + [--, -3.1416, --], + [6.0, --, 8.0]], + mask=[[False, True, False], + [ True, False, True], + [False, True, False]], + fill_value=1e+20) + + """ + + # handle the single-argument case + missing = (x is _NoValue, y is _NoValue).count(True) + if missing == 1: + raise ValueError("Must provide both 'x' and 'y' or neither.") + if missing == 2: + return nonzero(condition) + + # we only care if the condition is true - false or masked pick y + cf = filled(condition, False) + xd = getdata(x) + yd = getdata(y) + + # we need the full arrays here for correct final dimensions + cm = getmaskarray(condition) + xm = getmaskarray(x) + ym = getmaskarray(y) + + # deal with the fact that masked.dtype == float64, but we don't actually + # want to treat it as that. + if x is masked and y is not masked: + xd = np.zeros((), dtype=yd.dtype) + xm = np.ones((), dtype=ym.dtype) + elif y is masked and x is not masked: + yd = np.zeros((), dtype=xd.dtype) + ym = np.ones((), dtype=xm.dtype) + + data = np.where(cf, xd, yd) + mask = np.where(cf, xm, ym) + mask = np.where(cm, np.ones((), dtype=mask.dtype), mask) + + # collapse the mask, for backwards compatibility + mask = _shrink_mask(mask) + + return masked_array(data, mask=mask) + + +def choose(indices, choices, out=None, mode='raise'): + """ + Use an index array to construct a new array from a set of choices. + + Given an array of integers and a set of n choice arrays, this method + will create a new array that merges each of the choice arrays. Where a + value in `a` is i, the new array will have the value that choices[i] + contains in the same place. + + Parameters + ---------- + a : ndarray of ints + This array must contain integers in ``[0, n-1]``, where n is the + number of choices. + choices : sequence of arrays + Choice arrays. The index array and all of the choices should be + broadcastable to the same shape. + out : array, optional + If provided, the result will be inserted into this array. It should + be of the appropriate shape and `dtype`. + mode : {'raise', 'wrap', 'clip'}, optional + Specifies how out-of-bounds indices will behave. + + * 'raise' : raise an error + * 'wrap' : wrap around + * 'clip' : clip to the range + + Returns + ------- + merged_array : array + + See Also + -------- + choose : equivalent function + + Examples + -------- + >>> choice = np.array([[1,1,1], [2,2,2], [3,3,3]]) + >>> a = np.array([2, 1, 0]) + >>> np.ma.choose(a, choice) + masked_array(data=[3, 2, 1], + mask=False, + fill_value=999999) + + """ + def fmask(x): + "Returns the filled array, or True if masked." + if x is masked: + return True + return filled(x) + + def nmask(x): + "Returns the mask, True if ``masked``, False if ``nomask``." + if x is masked: + return True + return getmask(x) + # Get the indices. + c = filled(indices, 0) + # Get the masks. + masks = [nmask(x) for x in choices] + data = [fmask(x) for x in choices] + # Construct the mask + outputmask = np.choose(c, masks, mode=mode) + outputmask = make_mask(mask_or(outputmask, getmask(indices)), + copy=False, shrink=True) + # Get the choices. + d = np.choose(c, data, mode=mode, out=out).view(MaskedArray) + if out is not None: + if isinstance(out, MaskedArray): + out.__setmask__(outputmask) + return out + d.__setmask__(outputmask) + return d + + +def round_(a, decimals=0, out=None): + """ + Return a copy of a, rounded to 'decimals' places. + + When 'decimals' is negative, it specifies the number of positions + to the left of the decimal point. The real and imaginary parts of + complex numbers are rounded separately. Nothing is done if the + array is not of float type and 'decimals' is greater than or equal + to 0. + + Parameters + ---------- + decimals : int + Number of decimals to round to. May be negative. + out : array_like + Existing array to use for output. + If not given, returns a default copy of a. + + Notes + ----- + If out is given and does not have a mask attribute, the mask of a + is lost! + + """ + if out is None: + return np.round_(a, decimals, out) + else: + np.round_(getdata(a), decimals, out) + if hasattr(out, '_mask'): + out._mask = getmask(a) + return out +round = round_ + + +# Needed by dot, so move here from extras.py. It will still be exported +# from extras.py for compatibility. +def mask_rowcols(a, axis=None): + """ + Mask rows and/or columns of a 2D array that contain masked values. + + Mask whole rows and/or columns of a 2D array that contain + masked values. The masking behavior is selected using the + `axis` parameter. + + - If `axis` is None, rows *and* columns are masked. + - If `axis` is 0, only rows are masked. + - If `axis` is 1 or -1, only columns are masked. + + Parameters + ---------- + a : array_like, MaskedArray + The array to mask. If not a MaskedArray instance (or if no array + elements are masked). The result is a MaskedArray with `mask` set + to `nomask` (False). Must be a 2D array. + axis : int, optional + Axis along which to perform the operation. If None, applies to a + flattened version of the array. + + Returns + ------- + a : MaskedArray + A modified version of the input array, masked depending on the value + of the `axis` parameter. + + Raises + ------ + NotImplementedError + If input array `a` is not 2D. + + See Also + -------- + mask_rows : Mask rows of a 2D array that contain masked values. + mask_cols : Mask cols of a 2D array that contain masked values. + masked_where : Mask where a condition is met. + + Notes + ----- + The input array's mask is modified by this function. + + Examples + -------- + >>> import numpy.ma as ma + >>> a = np.zeros((3, 3), dtype=int) + >>> a[1, 1] = 1 + >>> a + array([[0, 0, 0], + [0, 1, 0], + [0, 0, 0]]) + >>> a = ma.masked_equal(a, 1) + >>> a + masked_array( + data=[[0, 0, 0], + [0, --, 0], + [0, 0, 0]], + mask=[[False, False, False], + [False, True, False], + [False, False, False]], + fill_value=1) + >>> ma.mask_rowcols(a) + masked_array( + data=[[0, --, 0], + [--, --, --], + [0, --, 0]], + mask=[[False, True, False], + [ True, True, True], + [False, True, False]], + fill_value=1) + + """ + a = array(a, subok=False) + if a.ndim != 2: + raise NotImplementedError("mask_rowcols works for 2D arrays only.") + m = getmask(a) + # Nothing is masked: return a + if m is nomask or not m.any(): + return a + maskedval = m.nonzero() + a._mask = a._mask.copy() + if not axis: + a[np.unique(maskedval[0])] = masked + if axis in [None, 1, -1]: + a[:, np.unique(maskedval[1])] = masked + return a + + +# Include masked dot here to avoid import problems in getting it from +# extras.py. Note that it is not included in __all__, but rather exported +# from extras in order to avoid backward compatibility problems. +def dot(a, b, strict=False, out=None): + """ + Return the dot product of two arrays. + + This function is the equivalent of `numpy.dot` that takes masked values + into account. Note that `strict` and `out` are in different position + than in the method version. In order to maintain compatibility with the + corresponding method, it is recommended that the optional arguments be + treated as keyword only. At some point that may be mandatory. + + .. note:: + Works only with 2-D arrays at the moment. + + + Parameters + ---------- + a, b : masked_array_like + Inputs arrays. + strict : bool, optional + Whether masked data are propagated (True) or set to 0 (False) for + the computation. Default is False. Propagating the mask means that + if a masked value appears in a row or column, the whole row or + column is considered masked. + out : masked_array, optional + Output argument. This must have the exact kind that would be returned + if it was not used. In particular, it must have the right type, must be + C-contiguous, and its dtype must be the dtype that would be returned + for `dot(a,b)`. This is a performance feature. Therefore, if these + conditions are not met, an exception is raised, instead of attempting + to be flexible. + + .. versionadded:: 1.10.2 + + See Also + -------- + numpy.dot : Equivalent function for ndarrays. + + Examples + -------- + >>> a = np.ma.array([[1, 2, 3], [4, 5, 6]], mask=[[1, 0, 0], [0, 0, 0]]) + >>> b = np.ma.array([[1, 2], [3, 4], [5, 6]], mask=[[1, 0], [0, 0], [0, 0]]) + >>> np.ma.dot(a, b) + masked_array( + data=[[21, 26], + [45, 64]], + mask=[[False, False], + [False, False]], + fill_value=999999) + >>> np.ma.dot(a, b, strict=True) + masked_array( + data=[[--, --], + [--, 64]], + mask=[[ True, True], + [ True, False]], + fill_value=999999) + + """ + # !!!: Works only with 2D arrays. There should be a way to get it to run + # with higher dimension + if strict and (a.ndim == 2) and (b.ndim == 2): + a = mask_rowcols(a, 0) + b = mask_rowcols(b, 1) + am = ~getmaskarray(a) + bm = ~getmaskarray(b) + + if out is None: + d = np.dot(filled(a, 0), filled(b, 0)) + m = ~np.dot(am, bm) + if d.ndim == 0: + d = np.asarray(d) + r = d.view(get_masked_subclass(a, b)) + r.__setmask__(m) + return r + else: + d = np.dot(filled(a, 0), filled(b, 0), out._data) + if out.mask.shape != d.shape: + out._mask = np.empty(d.shape, MaskType) + np.dot(am, bm, out._mask) + np.logical_not(out._mask, out._mask) + return out + + +def inner(a, b): + """ + Returns the inner product of a and b for arrays of floating point types. + + Like the generic NumPy equivalent the product sum is over the last dimension + of a and b. The first argument is not conjugated. + + """ + fa = filled(a, 0) + fb = filled(b, 0) + if fa.ndim == 0: + fa.shape = (1,) + if fb.ndim == 0: + fb.shape = (1,) + return np.inner(fa, fb).view(MaskedArray) +inner.__doc__ = doc_note(np.inner.__doc__, + "Masked values are replaced by 0.") +innerproduct = inner + + +def outer(a, b): + "maskedarray version of the numpy function." + fa = filled(a, 0).ravel() + fb = filled(b, 0).ravel() + d = np.outer(fa, fb) + ma = getmask(a) + mb = getmask(b) + if ma is nomask and mb is nomask: + return masked_array(d) + ma = getmaskarray(a) + mb = getmaskarray(b) + m = make_mask(1 - np.outer(1 - ma, 1 - mb), copy=False) + return masked_array(d, mask=m) +outer.__doc__ = doc_note(np.outer.__doc__, + "Masked values are replaced by 0.") +outerproduct = outer + + +def _convolve_or_correlate(f, a, v, mode, propagate_mask): + """ + Helper function for ma.correlate and ma.convolve + """ + if propagate_mask: + # results which are contributed to by either item in any pair being invalid + mask = ( + f(getmaskarray(a), np.ones(np.shape(v), dtype=bool), mode=mode) + | f(np.ones(np.shape(a), dtype=bool), getmaskarray(v), mode=mode) + ) + data = f(getdata(a), getdata(v), mode=mode) + else: + # results which are not contributed to by any pair of valid elements + mask = ~f(~getmaskarray(a), ~getmaskarray(v)) + data = f(filled(a, 0), filled(v, 0), mode=mode) + + return masked_array(data, mask=mask) + + +def correlate(a, v, mode='valid', propagate_mask=True): + """ + Cross-correlation of two 1-dimensional sequences. + + Parameters + ---------- + a, v : array_like + Input sequences. + mode : {'valid', 'same', 'full'}, optional + Refer to the `np.convolve` docstring. Note that the default + is 'valid', unlike `convolve`, which uses 'full'. + propagate_mask : bool + If True, then a result element is masked if any masked element contributes towards it. + If False, then a result element is only masked if no non-masked element + contribute towards it + + Returns + ------- + out : MaskedArray + Discrete cross-correlation of `a` and `v`. + + See Also + -------- + numpy.correlate : Equivalent function in the top-level NumPy module. + """ + return _convolve_or_correlate(np.correlate, a, v, mode, propagate_mask) + + +def convolve(a, v, mode='full', propagate_mask=True): + """ + Returns the discrete, linear convolution of two one-dimensional sequences. + + Parameters + ---------- + a, v : array_like + Input sequences. + mode : {'valid', 'same', 'full'}, optional + Refer to the `np.convolve` docstring. + propagate_mask : bool + If True, then if any masked element is included in the sum for a result + element, then the result is masked. + If False, then the result element is only masked if no non-masked cells + contribute towards it + + Returns + ------- + out : MaskedArray + Discrete, linear convolution of `a` and `v`. + + See Also + -------- + numpy.convolve : Equivalent function in the top-level NumPy module. + """ + return _convolve_or_correlate(np.convolve, a, v, mode, propagate_mask) + + +def allequal(a, b, fill_value=True): + """ + Return True if all entries of a and b are equal, using + fill_value as a truth value where either or both are masked. + + Parameters + ---------- + a, b : array_like + Input arrays to compare. + fill_value : bool, optional + Whether masked values in a or b are considered equal (True) or not + (False). + + Returns + ------- + y : bool + Returns True if the two arrays are equal within the given + tolerance, False otherwise. If either array contains NaN, + then False is returned. + + See Also + -------- + all, any + numpy.ma.allclose + + Examples + -------- + >>> a = np.ma.array([1e10, 1e-7, 42.0], mask=[0, 0, 1]) + >>> a + masked_array(data=[10000000000.0, 1e-07, --], + mask=[False, False, True], + fill_value=1e+20) + + >>> b = np.array([1e10, 1e-7, -42.0]) + >>> b + array([ 1.00000000e+10, 1.00000000e-07, -4.20000000e+01]) + >>> np.ma.allequal(a, b, fill_value=False) + False + >>> np.ma.allequal(a, b) + True + + """ + m = mask_or(getmask(a), getmask(b)) + if m is nomask: + x = getdata(a) + y = getdata(b) + d = umath.equal(x, y) + return d.all() + elif fill_value: + x = getdata(a) + y = getdata(b) + d = umath.equal(x, y) + dm = array(d, mask=m, copy=False) + return dm.filled(True).all(None) + else: + return False + + +def allclose(a, b, masked_equal=True, rtol=1e-5, atol=1e-8): + """ + Returns True if two arrays are element-wise equal within a tolerance. + + This function is equivalent to `allclose` except that masked values + are treated as equal (default) or unequal, depending on the `masked_equal` + argument. + + Parameters + ---------- + a, b : array_like + Input arrays to compare. + masked_equal : bool, optional + Whether masked values in `a` and `b` are considered equal (True) or not + (False). They are considered equal by default. + rtol : float, optional + Relative tolerance. The relative difference is equal to ``rtol * b``. + Default is 1e-5. + atol : float, optional + Absolute tolerance. The absolute difference is equal to `atol`. + Default is 1e-8. + + Returns + ------- + y : bool + Returns True if the two arrays are equal within the given + tolerance, False otherwise. If either array contains NaN, then + False is returned. + + See Also + -------- + all, any + numpy.allclose : the non-masked `allclose`. + + Notes + ----- + If the following equation is element-wise True, then `allclose` returns + True:: + + absolute(`a` - `b`) <= (`atol` + `rtol` * absolute(`b`)) + + Return True if all elements of `a` and `b` are equal subject to + given tolerances. + + Examples + -------- + >>> a = np.ma.array([1e10, 1e-7, 42.0], mask=[0, 0, 1]) + >>> a + masked_array(data=[10000000000.0, 1e-07, --], + mask=[False, False, True], + fill_value=1e+20) + >>> b = np.ma.array([1e10, 1e-8, -42.0], mask=[0, 0, 1]) + >>> np.ma.allclose(a, b) + False + + >>> a = np.ma.array([1e10, 1e-8, 42.0], mask=[0, 0, 1]) + >>> b = np.ma.array([1.00001e10, 1e-9, -42.0], mask=[0, 0, 1]) + >>> np.ma.allclose(a, b) + True + >>> np.ma.allclose(a, b, masked_equal=False) + False + + Masked values are not compared directly. + + >>> a = np.ma.array([1e10, 1e-8, 42.0], mask=[0, 0, 1]) + >>> b = np.ma.array([1.00001e10, 1e-9, 42.0], mask=[0, 0, 1]) + >>> np.ma.allclose(a, b) + True + >>> np.ma.allclose(a, b, masked_equal=False) + False + + """ + x = masked_array(a, copy=False) + y = masked_array(b, copy=False) + + # make sure y is an inexact type to avoid abs(MIN_INT); will cause + # casting of x later. + # NOTE: We explicitly allow timedelta, which used to work. This could + # possibly be deprecated. See also gh-18286. + # timedelta works if `atol` is an integer or also a timedelta. + # Although, the default tolerances are unlikely to be useful + if y.dtype.kind != "m": + dtype = np.result_type(y, 1.) + if y.dtype != dtype: + y = masked_array(y, dtype=dtype, copy=False) + + m = mask_or(getmask(x), getmask(y)) + xinf = np.isinf(masked_array(x, copy=False, mask=m)).filled(False) + # If we have some infs, they should fall at the same place. + if not np.all(xinf == filled(np.isinf(y), False)): + return False + # No infs at all + if not np.any(xinf): + d = filled(less_equal(absolute(x - y), atol + rtol * absolute(y)), + masked_equal) + return np.all(d) + + if not np.all(filled(x[xinf] == y[xinf], masked_equal)): + return False + x = x[~xinf] + y = y[~xinf] + + d = filled(less_equal(absolute(x - y), atol + rtol * absolute(y)), + masked_equal) + + return np.all(d) + + +def asarray(a, dtype=None, order=None): + """ + Convert the input to a masked array of the given data-type. + + No copy is performed if the input is already an `ndarray`. If `a` is + a subclass of `MaskedArray`, a base class `MaskedArray` is returned. + + Parameters + ---------- + a : array_like + Input data, in any form that can be converted to a masked array. This + includes lists, lists of tuples, tuples, tuples of tuples, tuples + of lists, ndarrays and masked arrays. + dtype : dtype, optional + By default, the data-type is inferred from the input data. + order : {'C', 'F'}, optional + Whether to use row-major ('C') or column-major ('FORTRAN') memory + representation. Default is 'C'. + + Returns + ------- + out : MaskedArray + Masked array interpretation of `a`. + + See Also + -------- + asanyarray : Similar to `asarray`, but conserves subclasses. + + Examples + -------- + >>> x = np.arange(10.).reshape(2, 5) + >>> x + array([[0., 1., 2., 3., 4.], + [5., 6., 7., 8., 9.]]) + >>> np.ma.asarray(x) + masked_array( + data=[[0., 1., 2., 3., 4.], + [5., 6., 7., 8., 9.]], + mask=False, + fill_value=1e+20) + >>> type(np.ma.asarray(x)) + + + """ + order = order or 'C' + return masked_array(a, dtype=dtype, copy=False, keep_mask=True, + subok=False, order=order) + + +def asanyarray(a, dtype=None): + """ + Convert the input to a masked array, conserving subclasses. + + If `a` is a subclass of `MaskedArray`, its class is conserved. + No copy is performed if the input is already an `ndarray`. + + Parameters + ---------- + a : array_like + Input data, in any form that can be converted to an array. + dtype : dtype, optional + By default, the data-type is inferred from the input data. + order : {'C', 'F'}, optional + Whether to use row-major ('C') or column-major ('FORTRAN') memory + representation. Default is 'C'. + + Returns + ------- + out : MaskedArray + MaskedArray interpretation of `a`. + + See Also + -------- + asarray : Similar to `asanyarray`, but does not conserve subclass. + + Examples + -------- + >>> x = np.arange(10.).reshape(2, 5) + >>> x + array([[0., 1., 2., 3., 4.], + [5., 6., 7., 8., 9.]]) + >>> np.ma.asanyarray(x) + masked_array( + data=[[0., 1., 2., 3., 4.], + [5., 6., 7., 8., 9.]], + mask=False, + fill_value=1e+20) + >>> type(np.ma.asanyarray(x)) + + + """ + # workaround for #8666, to preserve identity. Ideally the bottom line + # would handle this for us. + if isinstance(a, MaskedArray) and (dtype is None or dtype == a.dtype): + return a + return masked_array(a, dtype=dtype, copy=False, keep_mask=True, subok=True) + + +############################################################################## +# Pickling # +############################################################################## + +def _pickle_warn(method): + # NumPy 1.15.0, 2017-12-10 + warnings.warn( + f"np.ma.{method} is deprecated, use pickle.{method} instead", + DeprecationWarning, stacklevel=3) + + +def fromfile(file, dtype=float, count=-1, sep=''): + raise NotImplementedError( + "fromfile() not yet implemented for a MaskedArray.") + + +def fromflex(fxarray): + """ + Build a masked array from a suitable flexible-type array. + + The input array has to have a data-type with ``_data`` and ``_mask`` + fields. This type of array is output by `MaskedArray.toflex`. + + Parameters + ---------- + fxarray : ndarray + The structured input array, containing ``_data`` and ``_mask`` + fields. If present, other fields are discarded. + + Returns + ------- + result : MaskedArray + The constructed masked array. + + See Also + -------- + MaskedArray.toflex : Build a flexible-type array from a masked array. + + Examples + -------- + >>> x = np.ma.array(np.arange(9).reshape(3, 3), mask=[0] + [1, 0] * 4) + >>> rec = x.toflex() + >>> rec + array([[(0, False), (1, True), (2, False)], + [(3, True), (4, False), (5, True)], + [(6, False), (7, True), (8, False)]], + dtype=[('_data', '>> x2 = np.ma.fromflex(rec) + >>> x2 + masked_array( + data=[[0, --, 2], + [--, 4, --], + [6, --, 8]], + mask=[[False, True, False], + [ True, False, True], + [False, True, False]], + fill_value=999999) + + Extra fields can be present in the structured array but are discarded: + + >>> dt = [('_data', '>> rec2 = np.zeros((2, 2), dtype=dt) + >>> rec2 + array([[(0, False, 0.), (0, False, 0.)], + [(0, False, 0.), (0, False, 0.)]], + dtype=[('_data', '>> y = np.ma.fromflex(rec2) + >>> y + masked_array( + data=[[0, 0], + [0, 0]], + mask=[[False, False], + [False, False]], + fill_value=999999, + dtype=int32) + + """ + return masked_array(fxarray['_data'], mask=fxarray['_mask']) + + +class _convert2ma: + + """ + Convert functions from numpy to numpy.ma. + + Parameters + ---------- + _methodname : string + Name of the method to transform. + + """ + __doc__ = None + + def __init__(self, funcname, params=None): + self._func = getattr(np, funcname) + self.__doc__ = self.getdoc() + self._extras = params or {} + + def getdoc(self): + "Return the doc of the function (from the doc of the method)." + doc = getattr(self._func, '__doc__', None) + sig = get_object_signature(self._func) + if doc: + # Add the signature of the function at the beginning of the doc + if sig: + sig = "%s%s\n" % (self._func.__name__, sig) + doc = sig + doc + return doc + + def __call__(self, *args, **params): + # Find the common parameters to the call and the definition + _extras = self._extras + common_params = set(params).intersection(_extras) + # Drop the common parameters from the call + for p in common_params: + _extras[p] = params.pop(p) + # Get the result + result = self._func.__call__(*args, **params).view(MaskedArray) + if "fill_value" in common_params: + result.fill_value = _extras.get("fill_value", None) + if "hardmask" in common_params: + result._hardmask = bool(_extras.get("hard_mask", False)) + return result + +arange = _convert2ma('arange', params=dict(fill_value=None, hardmask=False)) +clip = np.clip +diff = np.diff +empty = _convert2ma('empty', params=dict(fill_value=None, hardmask=False)) +empty_like = _convert2ma('empty_like') +frombuffer = _convert2ma('frombuffer') +fromfunction = _convert2ma('fromfunction') +identity = _convert2ma( + 'identity', params=dict(fill_value=None, hardmask=False)) +indices = np.indices +ones = _convert2ma('ones', params=dict(fill_value=None, hardmask=False)) +ones_like = np.ones_like +squeeze = np.squeeze +zeros = _convert2ma('zeros', params=dict(fill_value=None, hardmask=False)) +zeros_like = np.zeros_like + + +def append(a, b, axis=None): + """Append values to the end of an array. + + .. versionadded:: 1.9.0 + + Parameters + ---------- + a : array_like + Values are appended to a copy of this array. + b : array_like + These values are appended to a copy of `a`. It must be of the + correct shape (the same shape as `a`, excluding `axis`). If `axis` + is not specified, `b` can be any shape and will be flattened + before use. + axis : int, optional + The axis along which `v` are appended. If `axis` is not given, + both `a` and `b` are flattened before use. + + Returns + ------- + append : MaskedArray + A copy of `a` with `b` appended to `axis`. Note that `append` + does not occur in-place: a new array is allocated and filled. If + `axis` is None, the result is a flattened array. + + See Also + -------- + numpy.append : Equivalent function in the top-level NumPy module. + + Examples + -------- + >>> import numpy.ma as ma + >>> a = ma.masked_values([1, 2, 3], 2) + >>> b = ma.masked_values([[4, 5, 6], [7, 8, 9]], 7) + >>> ma.append(a, b) + masked_array(data=[1, --, 3, 4, 5, 6, --, 8, 9], + mask=[False, True, False, False, False, False, True, False, + False], + fill_value=999999) + """ + return concatenate([a, b], axis) diff --git a/venv/Lib/site-packages/numpy/ma/extras.py b/venv/Lib/site-packages/numpy/ma/extras.py new file mode 100644 index 0000000..1bf03e9 --- /dev/null +++ b/venv/Lib/site-packages/numpy/ma/extras.py @@ -0,0 +1,1923 @@ +""" +Masked arrays add-ons. + +A collection of utilities for `numpy.ma`. + +:author: Pierre Gerard-Marchant +:contact: pierregm_at_uga_dot_edu +:version: $Id: extras.py 3473 2007-10-29 15:18:13Z jarrod.millman $ + +""" +__all__ = [ + 'apply_along_axis', 'apply_over_axes', 'atleast_1d', 'atleast_2d', + 'atleast_3d', 'average', 'clump_masked', 'clump_unmasked', + 'column_stack', 'compress_cols', 'compress_nd', 'compress_rowcols', + 'compress_rows', 'count_masked', 'corrcoef', 'cov', 'diagflat', 'dot', + 'dstack', 'ediff1d', 'flatnotmasked_contiguous', 'flatnotmasked_edges', + 'hsplit', 'hstack', 'isin', 'in1d', 'intersect1d', 'mask_cols', 'mask_rowcols', + 'mask_rows', 'masked_all', 'masked_all_like', 'median', 'mr_', + 'notmasked_contiguous', 'notmasked_edges', 'polyfit', 'row_stack', + 'setdiff1d', 'setxor1d', 'stack', 'unique', 'union1d', 'vander', 'vstack', + ] + +import itertools +import warnings + +from . import core as ma +from .core import ( + MaskedArray, MAError, add, array, asarray, concatenate, filled, count, + getmask, getmaskarray, make_mask_descr, masked, masked_array, mask_or, + nomask, ones, sort, zeros, getdata, get_masked_subclass, dot, + mask_rowcols + ) + +import numpy as np +from numpy import ndarray, array as nxarray +import numpy.core.umath as umath +from numpy.core.multiarray import normalize_axis_index +from numpy.core.numeric import normalize_axis_tuple +from numpy.lib.function_base import _ureduce +from numpy.lib.index_tricks import AxisConcatenator + + +def issequence(seq): + """ + Is seq a sequence (ndarray, list or tuple)? + + """ + return isinstance(seq, (ndarray, tuple, list)) + + +def count_masked(arr, axis=None): + """ + Count the number of masked elements along the given axis. + + Parameters + ---------- + arr : array_like + An array with (possibly) masked elements. + axis : int, optional + Axis along which to count. If None (default), a flattened + version of the array is used. + + Returns + ------- + count : int, ndarray + The total number of masked elements (axis=None) or the number + of masked elements along each slice of the given axis. + + See Also + -------- + MaskedArray.count : Count non-masked elements. + + Examples + -------- + >>> import numpy.ma as ma + >>> a = np.arange(9).reshape((3,3)) + >>> a = ma.array(a) + >>> a[1, 0] = ma.masked + >>> a[1, 2] = ma.masked + >>> a[2, 1] = ma.masked + >>> a + masked_array( + data=[[0, 1, 2], + [--, 4, --], + [6, --, 8]], + mask=[[False, False, False], + [ True, False, True], + [False, True, False]], + fill_value=999999) + >>> ma.count_masked(a) + 3 + + When the `axis` keyword is used an array is returned. + + >>> ma.count_masked(a, axis=0) + array([1, 1, 1]) + >>> ma.count_masked(a, axis=1) + array([0, 2, 1]) + + """ + m = getmaskarray(arr) + return m.sum(axis) + + +def masked_all(shape, dtype=float): + """ + Empty masked array with all elements masked. + + Return an empty masked array of the given shape and dtype, where all the + data are masked. + + Parameters + ---------- + shape : tuple + Shape of the required MaskedArray. + dtype : dtype, optional + Data type of the output. + + Returns + ------- + a : MaskedArray + A masked array with all data masked. + + See Also + -------- + masked_all_like : Empty masked array modelled on an existing array. + + Examples + -------- + >>> import numpy.ma as ma + >>> ma.masked_all((3, 3)) + masked_array( + data=[[--, --, --], + [--, --, --], + [--, --, --]], + mask=[[ True, True, True], + [ True, True, True], + [ True, True, True]], + fill_value=1e+20, + dtype=float64) + + The `dtype` parameter defines the underlying data type. + + >>> a = ma.masked_all((3, 3)) + >>> a.dtype + dtype('float64') + >>> a = ma.masked_all((3, 3), dtype=np.int32) + >>> a.dtype + dtype('int32') + + """ + a = masked_array(np.empty(shape, dtype), + mask=np.ones(shape, make_mask_descr(dtype))) + return a + + +def masked_all_like(arr): + """ + Empty masked array with the properties of an existing array. + + Return an empty masked array of the same shape and dtype as + the array `arr`, where all the data are masked. + + Parameters + ---------- + arr : ndarray + An array describing the shape and dtype of the required MaskedArray. + + Returns + ------- + a : MaskedArray + A masked array with all data masked. + + Raises + ------ + AttributeError + If `arr` doesn't have a shape attribute (i.e. not an ndarray) + + See Also + -------- + masked_all : Empty masked array with all elements masked. + + Examples + -------- + >>> import numpy.ma as ma + >>> arr = np.zeros((2, 3), dtype=np.float32) + >>> arr + array([[0., 0., 0.], + [0., 0., 0.]], dtype=float32) + >>> ma.masked_all_like(arr) + masked_array( + data=[[--, --, --], + [--, --, --]], + mask=[[ True, True, True], + [ True, True, True]], + fill_value=1e+20, + dtype=float32) + + The dtype of the masked array matches the dtype of `arr`. + + >>> arr.dtype + dtype('float32') + >>> ma.masked_all_like(arr).dtype + dtype('float32') + + """ + a = np.empty_like(arr).view(MaskedArray) + a._mask = np.ones(a.shape, dtype=make_mask_descr(a.dtype)) + return a + + +#####-------------------------------------------------------------------------- +#---- --- Standard functions --- +#####-------------------------------------------------------------------------- +class _fromnxfunction: + """ + Defines a wrapper to adapt NumPy functions to masked arrays. + + + An instance of `_fromnxfunction` can be called with the same parameters + as the wrapped NumPy function. The docstring of `newfunc` is adapted from + the wrapped function as well, see `getdoc`. + + This class should not be used directly. Instead, one of its extensions that + provides support for a specific type of input should be used. + + Parameters + ---------- + funcname : str + The name of the function to be adapted. The function should be + in the NumPy namespace (i.e. ``np.funcname``). + + """ + + def __init__(self, funcname): + self.__name__ = funcname + self.__doc__ = self.getdoc() + + def getdoc(self): + """ + Retrieve the docstring and signature from the function. + + The ``__doc__`` attribute of the function is used as the docstring for + the new masked array version of the function. A note on application + of the function to the mask is appended. + + Parameters + ---------- + None + + """ + npfunc = getattr(np, self.__name__, None) + doc = getattr(npfunc, '__doc__', None) + if doc: + sig = self.__name__ + ma.get_object_signature(npfunc) + doc = ma.doc_note(doc, "The function is applied to both the _data " + "and the _mask, if any.") + return '\n\n'.join((sig, doc)) + return + + def __call__(self, *args, **params): + pass + + +class _fromnxfunction_single(_fromnxfunction): + """ + A version of `_fromnxfunction` that is called with a single array + argument followed by auxiliary args that are passed verbatim for + both the data and mask calls. + """ + def __call__(self, x, *args, **params): + func = getattr(np, self.__name__) + if isinstance(x, ndarray): + _d = func(x.__array__(), *args, **params) + _m = func(getmaskarray(x), *args, **params) + return masked_array(_d, mask=_m) + else: + _d = func(np.asarray(x), *args, **params) + _m = func(getmaskarray(x), *args, **params) + return masked_array(_d, mask=_m) + + +class _fromnxfunction_seq(_fromnxfunction): + """ + A version of `_fromnxfunction` that is called with a single sequence + of arrays followed by auxiliary args that are passed verbatim for + both the data and mask calls. + """ + def __call__(self, x, *args, **params): + func = getattr(np, self.__name__) + _d = func(tuple([np.asarray(a) for a in x]), *args, **params) + _m = func(tuple([getmaskarray(a) for a in x]), *args, **params) + return masked_array(_d, mask=_m) + + +class _fromnxfunction_args(_fromnxfunction): + """ + A version of `_fromnxfunction` that is called with multiple array + arguments. The first non-array-like input marks the beginning of the + arguments that are passed verbatim for both the data and mask calls. + Array arguments are processed independently and the results are + returned in a list. If only one array is found, the return value is + just the processed array instead of a list. + """ + def __call__(self, *args, **params): + func = getattr(np, self.__name__) + arrays = [] + args = list(args) + while len(args) > 0 and issequence(args[0]): + arrays.append(args.pop(0)) + res = [] + for x in arrays: + _d = func(np.asarray(x), *args, **params) + _m = func(getmaskarray(x), *args, **params) + res.append(masked_array(_d, mask=_m)) + if len(arrays) == 1: + return res[0] + return res + + +class _fromnxfunction_allargs(_fromnxfunction): + """ + A version of `_fromnxfunction` that is called with multiple array + arguments. Similar to `_fromnxfunction_args` except that all args + are converted to arrays even if they are not so already. This makes + it possible to process scalars as 1-D arrays. Only keyword arguments + are passed through verbatim for the data and mask calls. Arrays + arguments are processed independently and the results are returned + in a list. If only one arg is present, the return value is just the + processed array instead of a list. + """ + def __call__(self, *args, **params): + func = getattr(np, self.__name__) + res = [] + for x in args: + _d = func(np.asarray(x), **params) + _m = func(getmaskarray(x), **params) + res.append(masked_array(_d, mask=_m)) + if len(args) == 1: + return res[0] + return res + + +atleast_1d = _fromnxfunction_allargs('atleast_1d') +atleast_2d = _fromnxfunction_allargs('atleast_2d') +atleast_3d = _fromnxfunction_allargs('atleast_3d') + +vstack = row_stack = _fromnxfunction_seq('vstack') +hstack = _fromnxfunction_seq('hstack') +column_stack = _fromnxfunction_seq('column_stack') +dstack = _fromnxfunction_seq('dstack') +stack = _fromnxfunction_seq('stack') + +hsplit = _fromnxfunction_single('hsplit') + +diagflat = _fromnxfunction_single('diagflat') + + +#####-------------------------------------------------------------------------- +#---- +#####-------------------------------------------------------------------------- +def flatten_inplace(seq): + """Flatten a sequence in place.""" + k = 0 + while (k != len(seq)): + while hasattr(seq[k], '__iter__'): + seq[k:(k + 1)] = seq[k] + k += 1 + return seq + + +def apply_along_axis(func1d, axis, arr, *args, **kwargs): + """ + (This docstring should be overwritten) + """ + arr = array(arr, copy=False, subok=True) + nd = arr.ndim + axis = normalize_axis_index(axis, nd) + ind = [0] * (nd - 1) + i = np.zeros(nd, 'O') + indlist = list(range(nd)) + indlist.remove(axis) + i[axis] = slice(None, None) + outshape = np.asarray(arr.shape).take(indlist) + i.put(indlist, ind) + res = func1d(arr[tuple(i.tolist())], *args, **kwargs) + # if res is a number, then we have a smaller output array + asscalar = np.isscalar(res) + if not asscalar: + try: + len(res) + except TypeError: + asscalar = True + # Note: we shouldn't set the dtype of the output from the first result + # so we force the type to object, and build a list of dtypes. We'll + # just take the largest, to avoid some downcasting + dtypes = [] + if asscalar: + dtypes.append(np.asarray(res).dtype) + outarr = zeros(outshape, object) + outarr[tuple(ind)] = res + Ntot = np.product(outshape) + k = 1 + while k < Ntot: + # increment the index + ind[-1] += 1 + n = -1 + while (ind[n] >= outshape[n]) and (n > (1 - nd)): + ind[n - 1] += 1 + ind[n] = 0 + n -= 1 + i.put(indlist, ind) + res = func1d(arr[tuple(i.tolist())], *args, **kwargs) + outarr[tuple(ind)] = res + dtypes.append(asarray(res).dtype) + k += 1 + else: + res = array(res, copy=False, subok=True) + j = i.copy() + j[axis] = ([slice(None, None)] * res.ndim) + j.put(indlist, ind) + Ntot = np.product(outshape) + holdshape = outshape + outshape = list(arr.shape) + outshape[axis] = res.shape + dtypes.append(asarray(res).dtype) + outshape = flatten_inplace(outshape) + outarr = zeros(outshape, object) + outarr[tuple(flatten_inplace(j.tolist()))] = res + k = 1 + while k < Ntot: + # increment the index + ind[-1] += 1 + n = -1 + while (ind[n] >= holdshape[n]) and (n > (1 - nd)): + ind[n - 1] += 1 + ind[n] = 0 + n -= 1 + i.put(indlist, ind) + j.put(indlist, ind) + res = func1d(arr[tuple(i.tolist())], *args, **kwargs) + outarr[tuple(flatten_inplace(j.tolist()))] = res + dtypes.append(asarray(res).dtype) + k += 1 + max_dtypes = np.dtype(np.asarray(dtypes).max()) + if not hasattr(arr, '_mask'): + result = np.asarray(outarr, dtype=max_dtypes) + else: + result = asarray(outarr, dtype=max_dtypes) + result.fill_value = ma.default_fill_value(result) + return result +apply_along_axis.__doc__ = np.apply_along_axis.__doc__ + + +def apply_over_axes(func, a, axes): + """ + (This docstring will be overwritten) + """ + val = asarray(a) + N = a.ndim + if array(axes).ndim == 0: + axes = (axes,) + for axis in axes: + if axis < 0: + axis = N + axis + args = (val, axis) + res = func(*args) + if res.ndim == val.ndim: + val = res + else: + res = ma.expand_dims(res, axis) + if res.ndim == val.ndim: + val = res + else: + raise ValueError("function is not returning " + "an array of the correct shape") + return val + +if apply_over_axes.__doc__ is not None: + apply_over_axes.__doc__ = np.apply_over_axes.__doc__[ + :np.apply_over_axes.__doc__.find('Notes')].rstrip() + \ + """ + + Examples + -------- + >>> a = np.ma.arange(24).reshape(2,3,4) + >>> a[:,0,1] = np.ma.masked + >>> a[:,1,:] = np.ma.masked + >>> a + masked_array( + data=[[[0, --, 2, 3], + [--, --, --, --], + [8, 9, 10, 11]], + [[12, --, 14, 15], + [--, --, --, --], + [20, 21, 22, 23]]], + mask=[[[False, True, False, False], + [ True, True, True, True], + [False, False, False, False]], + [[False, True, False, False], + [ True, True, True, True], + [False, False, False, False]]], + fill_value=999999) + >>> np.ma.apply_over_axes(np.ma.sum, a, [0,2]) + masked_array( + data=[[[46], + [--], + [124]]], + mask=[[[False], + [ True], + [False]]], + fill_value=999999) + + Tuple axis arguments to ufuncs are equivalent: + + >>> np.ma.sum(a, axis=(0,2)).reshape((1,-1,1)) + masked_array( + data=[[[46], + [--], + [124]]], + mask=[[[False], + [ True], + [False]]], + fill_value=999999) + """ + + +def average(a, axis=None, weights=None, returned=False): + """ + Return the weighted average of array over the given axis. + + Parameters + ---------- + a : array_like + Data to be averaged. + Masked entries are not taken into account in the computation. + axis : int, optional + Axis along which to average `a`. If None, averaging is done over + the flattened array. + weights : array_like, optional + The importance that each element has in the computation of the average. + The weights array can either be 1-D (in which case its length must be + the size of `a` along the given axis) or of the same shape as `a`. + If ``weights=None``, then all data in `a` are assumed to have a + weight equal to one. The 1-D calculation is:: + + avg = sum(a * weights) / sum(weights) + + The only constraint on `weights` is that `sum(weights)` must not be 0. + returned : bool, optional + Flag indicating whether a tuple ``(result, sum of weights)`` + should be returned as output (True), or just the result (False). + Default is False. + + Returns + ------- + average, [sum_of_weights] : (tuple of) scalar or MaskedArray + The average along the specified axis. When returned is `True`, + return a tuple with the average as the first element and the sum + of the weights as the second element. The return type is `np.float64` + if `a` is of integer type and floats smaller than `float64`, or the + input data-type, otherwise. If returned, `sum_of_weights` is always + `float64`. + + Examples + -------- + >>> a = np.ma.array([1., 2., 3., 4.], mask=[False, False, True, True]) + >>> np.ma.average(a, weights=[3, 1, 0, 0]) + 1.25 + + >>> x = np.ma.arange(6.).reshape(3, 2) + >>> x + masked_array( + data=[[0., 1.], + [2., 3.], + [4., 5.]], + mask=False, + fill_value=1e+20) + >>> avg, sumweights = np.ma.average(x, axis=0, weights=[1, 2, 3], + ... returned=True) + >>> avg + masked_array(data=[2.6666666666666665, 3.6666666666666665], + mask=[False, False], + fill_value=1e+20) + + """ + a = asarray(a) + m = getmask(a) + + # inspired by 'average' in numpy/lib/function_base.py + + if weights is None: + avg = a.mean(axis) + scl = avg.dtype.type(a.count(axis)) + else: + wgt = np.asanyarray(weights) + + if issubclass(a.dtype.type, (np.integer, np.bool_)): + result_dtype = np.result_type(a.dtype, wgt.dtype, 'f8') + else: + result_dtype = np.result_type(a.dtype, wgt.dtype) + + # Sanity checks + if a.shape != wgt.shape: + if axis is None: + raise TypeError( + "Axis must be specified when shapes of a and weights " + "differ.") + if wgt.ndim != 1: + raise TypeError( + "1D weights expected when shapes of a and weights differ.") + if wgt.shape[0] != a.shape[axis]: + raise ValueError( + "Length of weights not compatible with specified axis.") + + # setup wgt to broadcast along axis + wgt = np.broadcast_to(wgt, (a.ndim-1)*(1,) + wgt.shape) + wgt = wgt.swapaxes(-1, axis) + + if m is not nomask: + wgt = wgt*(~a.mask) + + scl = wgt.sum(axis=axis, dtype=result_dtype) + avg = np.multiply(a, wgt, dtype=result_dtype).sum(axis)/scl + + if returned: + if scl.shape != avg.shape: + scl = np.broadcast_to(scl, avg.shape).copy() + return avg, scl + else: + return avg + + +def median(a, axis=None, out=None, overwrite_input=False, keepdims=False): + """ + Compute the median along the specified axis. + + Returns the median of the array elements. + + Parameters + ---------- + a : array_like + Input array or object that can be converted to an array. + axis : int, optional + Axis along which the medians are computed. The default (None) is + to compute the median along a flattened version of the array. + out : ndarray, optional + Alternative output array in which to place the result. It must + have the same shape and buffer length as the expected output + but the type will be cast if necessary. + overwrite_input : bool, optional + If True, then allow use of memory of input array (a) for + calculations. The input array will be modified by the call to + median. This will save memory when you do not need to preserve + the contents of the input array. Treat the input as undefined, + but it will probably be fully or partially sorted. Default is + False. Note that, if `overwrite_input` is True, and the input + is not already an `ndarray`, an error will be raised. + keepdims : bool, optional + If this is set to True, the axes which are reduced are left + in the result as dimensions with size one. With this option, + the result will broadcast correctly against the input array. + + .. versionadded:: 1.10.0 + + Returns + ------- + median : ndarray + A new array holding the result is returned unless out is + specified, in which case a reference to out is returned. + Return data-type is `float64` for integers and floats smaller than + `float64`, or the input data-type, otherwise. + + See Also + -------- + mean + + Notes + ----- + Given a vector ``V`` with ``N`` non masked values, the median of ``V`` + is the middle value of a sorted copy of ``V`` (``Vs``) - i.e. + ``Vs[(N-1)/2]``, when ``N`` is odd, or ``{Vs[N/2 - 1] + Vs[N/2]}/2`` + when ``N`` is even. + + Examples + -------- + >>> x = np.ma.array(np.arange(8), mask=[0]*4 + [1]*4) + >>> np.ma.median(x) + 1.5 + + >>> x = np.ma.array(np.arange(10).reshape(2, 5), mask=[0]*6 + [1]*4) + >>> np.ma.median(x) + 2.5 + >>> np.ma.median(x, axis=-1, overwrite_input=True) + masked_array(data=[2.0, 5.0], + mask=[False, False], + fill_value=1e+20) + + """ + if not hasattr(a, 'mask'): + m = np.median(getdata(a, subok=True), axis=axis, + out=out, overwrite_input=overwrite_input, + keepdims=keepdims) + if isinstance(m, np.ndarray) and 1 <= m.ndim: + return masked_array(m, copy=False) + else: + return m + + r, k = _ureduce(a, func=_median, axis=axis, out=out, + overwrite_input=overwrite_input) + if keepdims: + return r.reshape(k) + else: + return r + +def _median(a, axis=None, out=None, overwrite_input=False): + # when an unmasked NaN is present return it, so we need to sort the NaN + # values behind the mask + if np.issubdtype(a.dtype, np.inexact): + fill_value = np.inf + else: + fill_value = None + if overwrite_input: + if axis is None: + asorted = a.ravel() + asorted.sort(fill_value=fill_value) + else: + a.sort(axis=axis, fill_value=fill_value) + asorted = a + else: + asorted = sort(a, axis=axis, fill_value=fill_value) + + if axis is None: + axis = 0 + else: + axis = normalize_axis_index(axis, asorted.ndim) + + if asorted.shape[axis] == 0: + # for empty axis integer indices fail so use slicing to get same result + # as median (which is mean of empty slice = nan) + indexer = [slice(None)] * asorted.ndim + indexer[axis] = slice(0, 0) + indexer = tuple(indexer) + return np.ma.mean(asorted[indexer], axis=axis, out=out) + + if asorted.ndim == 1: + counts = count(asorted) + idx, odd = divmod(count(asorted), 2) + mid = asorted[idx + odd - 1:idx + 1] + if np.issubdtype(asorted.dtype, np.inexact) and asorted.size > 0: + # avoid inf / x = masked + s = mid.sum(out=out) + if not odd: + s = np.true_divide(s, 2., casting='safe', out=out) + s = np.lib.utils._median_nancheck(asorted, s, axis, out) + else: + s = mid.mean(out=out) + + # if result is masked either the input contained enough + # minimum_fill_value so that it would be the median or all values + # masked + if np.ma.is_masked(s) and not np.all(asorted.mask): + return np.ma.minimum_fill_value(asorted) + return s + + counts = count(asorted, axis=axis, keepdims=True) + h = counts // 2 + + # duplicate high if odd number of elements so mean does nothing + odd = counts % 2 == 1 + l = np.where(odd, h, h-1) + + lh = np.concatenate([l,h], axis=axis) + + # get low and high median + low_high = np.take_along_axis(asorted, lh, axis=axis) + + def replace_masked(s): + # Replace masked entries with minimum_full_value unless it all values + # are masked. This is required as the sort order of values equal or + # larger than the fill value is undefined and a valid value placed + # elsewhere, e.g. [4, --, inf]. + if np.ma.is_masked(s): + rep = (~np.all(asorted.mask, axis=axis, keepdims=True)) & s.mask + s.data[rep] = np.ma.minimum_fill_value(asorted) + s.mask[rep] = False + + replace_masked(low_high) + + if np.issubdtype(asorted.dtype, np.inexact): + # avoid inf / x = masked + s = np.ma.sum(low_high, axis=axis, out=out) + np.true_divide(s.data, 2., casting='unsafe', out=s.data) + + s = np.lib.utils._median_nancheck(asorted, s, axis, out) + else: + s = np.ma.mean(low_high, axis=axis, out=out) + + return s + + +def compress_nd(x, axis=None): + """Suppress slices from multiple dimensions which contain masked values. + + Parameters + ---------- + x : array_like, MaskedArray + The array to operate on. If not a MaskedArray instance (or if no array + elements are masked), `x` is interpreted as a MaskedArray with `mask` + set to `nomask`. + axis : tuple of ints or int, optional + Which dimensions to suppress slices from can be configured with this + parameter. + - If axis is a tuple of ints, those are the axes to suppress slices from. + - If axis is an int, then that is the only axis to suppress slices from. + - If axis is None, all axis are selected. + + Returns + ------- + compress_array : ndarray + The compressed array. + """ + x = asarray(x) + m = getmask(x) + # Set axis to tuple of ints + if axis is None: + axis = tuple(range(x.ndim)) + else: + axis = normalize_axis_tuple(axis, x.ndim) + + # Nothing is masked: return x + if m is nomask or not m.any(): + return x._data + # All is masked: return empty + if m.all(): + return nxarray([]) + # Filter elements through boolean indexing + data = x._data + for ax in axis: + axes = tuple(list(range(ax)) + list(range(ax + 1, x.ndim))) + data = data[(slice(None),)*ax + (~m.any(axis=axes),)] + return data + +def compress_rowcols(x, axis=None): + """ + Suppress the rows and/or columns of a 2-D array that contain + masked values. + + The suppression behavior is selected with the `axis` parameter. + + - If axis is None, both rows and columns are suppressed. + - If axis is 0, only rows are suppressed. + - If axis is 1 or -1, only columns are suppressed. + + Parameters + ---------- + x : array_like, MaskedArray + The array to operate on. If not a MaskedArray instance (or if no array + elements are masked), `x` is interpreted as a MaskedArray with + `mask` set to `nomask`. Must be a 2D array. + axis : int, optional + Axis along which to perform the operation. Default is None. + + Returns + ------- + compressed_array : ndarray + The compressed array. + + Examples + -------- + >>> x = np.ma.array(np.arange(9).reshape(3, 3), mask=[[1, 0, 0], + ... [1, 0, 0], + ... [0, 0, 0]]) + >>> x + masked_array( + data=[[--, 1, 2], + [--, 4, 5], + [6, 7, 8]], + mask=[[ True, False, False], + [ True, False, False], + [False, False, False]], + fill_value=999999) + + >>> np.ma.compress_rowcols(x) + array([[7, 8]]) + >>> np.ma.compress_rowcols(x, 0) + array([[6, 7, 8]]) + >>> np.ma.compress_rowcols(x, 1) + array([[1, 2], + [4, 5], + [7, 8]]) + + """ + if asarray(x).ndim != 2: + raise NotImplementedError("compress_rowcols works for 2D arrays only.") + return compress_nd(x, axis=axis) + + +def compress_rows(a): + """ + Suppress whole rows of a 2-D array that contain masked values. + + This is equivalent to ``np.ma.compress_rowcols(a, 0)``, see + `compress_rowcols` for details. + + See Also + -------- + compress_rowcols + + """ + a = asarray(a) + if a.ndim != 2: + raise NotImplementedError("compress_rows works for 2D arrays only.") + return compress_rowcols(a, 0) + +def compress_cols(a): + """ + Suppress whole columns of a 2-D array that contain masked values. + + This is equivalent to ``np.ma.compress_rowcols(a, 1)``, see + `compress_rowcols` for details. + + See Also + -------- + compress_rowcols + + """ + a = asarray(a) + if a.ndim != 2: + raise NotImplementedError("compress_cols works for 2D arrays only.") + return compress_rowcols(a, 1) + +def mask_rows(a, axis=np._NoValue): + """ + Mask rows of a 2D array that contain masked values. + + This function is a shortcut to ``mask_rowcols`` with `axis` equal to 0. + + See Also + -------- + mask_rowcols : Mask rows and/or columns of a 2D array. + masked_where : Mask where a condition is met. + + Examples + -------- + >>> import numpy.ma as ma + >>> a = np.zeros((3, 3), dtype=int) + >>> a[1, 1] = 1 + >>> a + array([[0, 0, 0], + [0, 1, 0], + [0, 0, 0]]) + >>> a = ma.masked_equal(a, 1) + >>> a + masked_array( + data=[[0, 0, 0], + [0, --, 0], + [0, 0, 0]], + mask=[[False, False, False], + [False, True, False], + [False, False, False]], + fill_value=1) + + >>> ma.mask_rows(a) + masked_array( + data=[[0, 0, 0], + [--, --, --], + [0, 0, 0]], + mask=[[False, False, False], + [ True, True, True], + [False, False, False]], + fill_value=1) + + """ + if axis is not np._NoValue: + # remove the axis argument when this deprecation expires + # NumPy 1.18.0, 2019-11-28 + warnings.warn( + "The axis argument has always been ignored, in future passing it " + "will raise TypeError", DeprecationWarning, stacklevel=2) + return mask_rowcols(a, 0) + +def mask_cols(a, axis=np._NoValue): + """ + Mask columns of a 2D array that contain masked values. + + This function is a shortcut to ``mask_rowcols`` with `axis` equal to 1. + + See Also + -------- + mask_rowcols : Mask rows and/or columns of a 2D array. + masked_where : Mask where a condition is met. + + Examples + -------- + >>> import numpy.ma as ma + >>> a = np.zeros((3, 3), dtype=int) + >>> a[1, 1] = 1 + >>> a + array([[0, 0, 0], + [0, 1, 0], + [0, 0, 0]]) + >>> a = ma.masked_equal(a, 1) + >>> a + masked_array( + data=[[0, 0, 0], + [0, --, 0], + [0, 0, 0]], + mask=[[False, False, False], + [False, True, False], + [False, False, False]], + fill_value=1) + >>> ma.mask_cols(a) + masked_array( + data=[[0, --, 0], + [0, --, 0], + [0, --, 0]], + mask=[[False, True, False], + [False, True, False], + [False, True, False]], + fill_value=1) + + """ + if axis is not np._NoValue: + # remove the axis argument when this deprecation expires + # NumPy 1.18.0, 2019-11-28 + warnings.warn( + "The axis argument has always been ignored, in future passing it " + "will raise TypeError", DeprecationWarning, stacklevel=2) + return mask_rowcols(a, 1) + + +#####-------------------------------------------------------------------------- +#---- --- arraysetops --- +#####-------------------------------------------------------------------------- + +def ediff1d(arr, to_end=None, to_begin=None): + """ + Compute the differences between consecutive elements of an array. + + This function is the equivalent of `numpy.ediff1d` that takes masked + values into account, see `numpy.ediff1d` for details. + + See Also + -------- + numpy.ediff1d : Equivalent function for ndarrays. + + """ + arr = ma.asanyarray(arr).flat + ed = arr[1:] - arr[:-1] + arrays = [ed] + # + if to_begin is not None: + arrays.insert(0, to_begin) + if to_end is not None: + arrays.append(to_end) + # + if len(arrays) != 1: + # We'll save ourselves a copy of a potentially large array in the common + # case where neither to_begin or to_end was given. + ed = hstack(arrays) + # + return ed + + +def unique(ar1, return_index=False, return_inverse=False): + """ + Finds the unique elements of an array. + + Masked values are considered the same element (masked). The output array + is always a masked array. See `numpy.unique` for more details. + + See Also + -------- + numpy.unique : Equivalent function for ndarrays. + + """ + output = np.unique(ar1, + return_index=return_index, + return_inverse=return_inverse) + if isinstance(output, tuple): + output = list(output) + output[0] = output[0].view(MaskedArray) + output = tuple(output) + else: + output = output.view(MaskedArray) + return output + + +def intersect1d(ar1, ar2, assume_unique=False): + """ + Returns the unique elements common to both arrays. + + Masked values are considered equal one to the other. + The output is always a masked array. + + See `numpy.intersect1d` for more details. + + See Also + -------- + numpy.intersect1d : Equivalent function for ndarrays. + + Examples + -------- + >>> x = np.ma.array([1, 3, 3, 3], mask=[0, 0, 0, 1]) + >>> y = np.ma.array([3, 1, 1, 1], mask=[0, 0, 0, 1]) + >>> np.ma.intersect1d(x, y) + masked_array(data=[1, 3, --], + mask=[False, False, True], + fill_value=999999) + + """ + if assume_unique: + aux = ma.concatenate((ar1, ar2)) + else: + # Might be faster than unique( intersect1d( ar1, ar2 ) )? + aux = ma.concatenate((unique(ar1), unique(ar2))) + aux.sort() + return aux[:-1][aux[1:] == aux[:-1]] + + +def setxor1d(ar1, ar2, assume_unique=False): + """ + Set exclusive-or of 1-D arrays with unique elements. + + The output is always a masked array. See `numpy.setxor1d` for more details. + + See Also + -------- + numpy.setxor1d : Equivalent function for ndarrays. + + """ + if not assume_unique: + ar1 = unique(ar1) + ar2 = unique(ar2) + + aux = ma.concatenate((ar1, ar2)) + if aux.size == 0: + return aux + aux.sort() + auxf = aux.filled() +# flag = ediff1d( aux, to_end = 1, to_begin = 1 ) == 0 + flag = ma.concatenate(([True], (auxf[1:] != auxf[:-1]), [True])) +# flag2 = ediff1d( flag ) == 0 + flag2 = (flag[1:] == flag[:-1]) + return aux[flag2] + + +def in1d(ar1, ar2, assume_unique=False, invert=False): + """ + Test whether each element of an array is also present in a second + array. + + The output is always a masked array. See `numpy.in1d` for more details. + + We recommend using :func:`isin` instead of `in1d` for new code. + + See Also + -------- + isin : Version of this function that preserves the shape of ar1. + numpy.in1d : Equivalent function for ndarrays. + + Notes + ----- + .. versionadded:: 1.4.0 + + """ + if not assume_unique: + ar1, rev_idx = unique(ar1, return_inverse=True) + ar2 = unique(ar2) + + ar = ma.concatenate((ar1, ar2)) + # We need this to be a stable sort, so always use 'mergesort' + # here. The values from the first array should always come before + # the values from the second array. + order = ar.argsort(kind='mergesort') + sar = ar[order] + if invert: + bool_ar = (sar[1:] != sar[:-1]) + else: + bool_ar = (sar[1:] == sar[:-1]) + flag = ma.concatenate((bool_ar, [invert])) + indx = order.argsort(kind='mergesort')[:len(ar1)] + + if assume_unique: + return flag[indx] + else: + return flag[indx][rev_idx] + + +def isin(element, test_elements, assume_unique=False, invert=False): + """ + Calculates `element in test_elements`, broadcasting over + `element` only. + + The output is always a masked array of the same shape as `element`. + See `numpy.isin` for more details. + + See Also + -------- + in1d : Flattened version of this function. + numpy.isin : Equivalent function for ndarrays. + + Notes + ----- + .. versionadded:: 1.13.0 + + """ + element = ma.asarray(element) + return in1d(element, test_elements, assume_unique=assume_unique, + invert=invert).reshape(element.shape) + + +def union1d(ar1, ar2): + """ + Union of two arrays. + + The output is always a masked array. See `numpy.union1d` for more details. + + See also + -------- + numpy.union1d : Equivalent function for ndarrays. + + """ + return unique(ma.concatenate((ar1, ar2), axis=None)) + + +def setdiff1d(ar1, ar2, assume_unique=False): + """ + Set difference of 1D arrays with unique elements. + + The output is always a masked array. See `numpy.setdiff1d` for more + details. + + See Also + -------- + numpy.setdiff1d : Equivalent function for ndarrays. + + Examples + -------- + >>> x = np.ma.array([1, 2, 3, 4], mask=[0, 1, 0, 1]) + >>> np.ma.setdiff1d(x, [1, 2]) + masked_array(data=[3, --], + mask=[False, True], + fill_value=999999) + + """ + if assume_unique: + ar1 = ma.asarray(ar1).ravel() + else: + ar1 = unique(ar1) + ar2 = unique(ar2) + return ar1[in1d(ar1, ar2, assume_unique=True, invert=True)] + + +############################################################################### +# Covariance # +############################################################################### + + +def _covhelper(x, y=None, rowvar=True, allow_masked=True): + """ + Private function for the computation of covariance and correlation + coefficients. + + """ + x = ma.array(x, ndmin=2, copy=True, dtype=float) + xmask = ma.getmaskarray(x) + # Quick exit if we can't process masked data + if not allow_masked and xmask.any(): + raise ValueError("Cannot process masked data.") + # + if x.shape[0] == 1: + rowvar = True + # Make sure that rowvar is either 0 or 1 + rowvar = int(bool(rowvar)) + axis = 1 - rowvar + if rowvar: + tup = (slice(None), None) + else: + tup = (None, slice(None)) + # + if y is None: + xnotmask = np.logical_not(xmask).astype(int) + else: + y = array(y, copy=False, ndmin=2, dtype=float) + ymask = ma.getmaskarray(y) + if not allow_masked and ymask.any(): + raise ValueError("Cannot process masked data.") + if xmask.any() or ymask.any(): + if y.shape == x.shape: + # Define some common mask + common_mask = np.logical_or(xmask, ymask) + if common_mask is not nomask: + xmask = x._mask = y._mask = ymask = common_mask + x._sharedmask = False + y._sharedmask = False + x = ma.concatenate((x, y), axis) + xnotmask = np.logical_not(np.concatenate((xmask, ymask), axis)).astype(int) + x -= x.mean(axis=rowvar)[tup] + return (x, xnotmask, rowvar) + + +def cov(x, y=None, rowvar=True, bias=False, allow_masked=True, ddof=None): + """ + Estimate the covariance matrix. + + Except for the handling of missing data this function does the same as + `numpy.cov`. For more details and examples, see `numpy.cov`. + + By default, masked values are recognized as such. If `x` and `y` have the + same shape, a common mask is allocated: if ``x[i,j]`` is masked, then + ``y[i,j]`` will also be masked. + Setting `allow_masked` to False will raise an exception if values are + missing in either of the input arrays. + + Parameters + ---------- + x : array_like + A 1-D or 2-D array containing multiple variables and observations. + Each row of `x` represents a variable, and each column a single + observation of all those variables. Also see `rowvar` below. + y : array_like, optional + An additional set of variables and observations. `y` has the same + form as `x`. + rowvar : bool, optional + If `rowvar` is True (default), then each row represents a + variable, with observations in the columns. Otherwise, the relationship + is transposed: each column represents a variable, while the rows + contain observations. + bias : bool, optional + Default normalization (False) is by ``(N-1)``, where ``N`` is the + number of observations given (unbiased estimate). If `bias` is True, + then normalization is by ``N``. This keyword can be overridden by + the keyword ``ddof`` in numpy versions >= 1.5. + allow_masked : bool, optional + If True, masked values are propagated pair-wise: if a value is masked + in `x`, the corresponding value is masked in `y`. + If False, raises a `ValueError` exception when some values are missing. + ddof : {None, int}, optional + If not ``None`` normalization is by ``(N - ddof)``, where ``N`` is + the number of observations; this overrides the value implied by + ``bias``. The default value is ``None``. + + .. versionadded:: 1.5 + + Raises + ------ + ValueError + Raised if some values are missing and `allow_masked` is False. + + See Also + -------- + numpy.cov + + """ + # Check inputs + if ddof is not None and ddof != int(ddof): + raise ValueError("ddof must be an integer") + # Set up ddof + if ddof is None: + if bias: + ddof = 0 + else: + ddof = 1 + + (x, xnotmask, rowvar) = _covhelper(x, y, rowvar, allow_masked) + if not rowvar: + fact = np.dot(xnotmask.T, xnotmask) * 1. - ddof + result = (dot(x.T, x.conj(), strict=False) / fact).squeeze() + else: + fact = np.dot(xnotmask, xnotmask.T) * 1. - ddof + result = (dot(x, x.T.conj(), strict=False) / fact).squeeze() + return result + + +def corrcoef(x, y=None, rowvar=True, bias=np._NoValue, allow_masked=True, + ddof=np._NoValue): + """ + Return Pearson product-moment correlation coefficients. + + Except for the handling of missing data this function does the same as + `numpy.corrcoef`. For more details and examples, see `numpy.corrcoef`. + + Parameters + ---------- + x : array_like + A 1-D or 2-D array containing multiple variables and observations. + Each row of `x` represents a variable, and each column a single + observation of all those variables. Also see `rowvar` below. + y : array_like, optional + An additional set of variables and observations. `y` has the same + shape as `x`. + rowvar : bool, optional + If `rowvar` is True (default), then each row represents a + variable, with observations in the columns. Otherwise, the relationship + is transposed: each column represents a variable, while the rows + contain observations. + bias : _NoValue, optional + Has no effect, do not use. + + .. deprecated:: 1.10.0 + allow_masked : bool, optional + If True, masked values are propagated pair-wise: if a value is masked + in `x`, the corresponding value is masked in `y`. + If False, raises an exception. Because `bias` is deprecated, this + argument needs to be treated as keyword only to avoid a warning. + ddof : _NoValue, optional + Has no effect, do not use. + + .. deprecated:: 1.10.0 + + See Also + -------- + numpy.corrcoef : Equivalent function in top-level NumPy module. + cov : Estimate the covariance matrix. + + Notes + ----- + This function accepts but discards arguments `bias` and `ddof`. This is + for backwards compatibility with previous versions of this function. These + arguments had no effect on the return values of the function and can be + safely ignored in this and previous versions of numpy. + """ + msg = 'bias and ddof have no effect and are deprecated' + if bias is not np._NoValue or ddof is not np._NoValue: + # 2015-03-15, 1.10 + warnings.warn(msg, DeprecationWarning, stacklevel=2) + # Get the data + (x, xnotmask, rowvar) = _covhelper(x, y, rowvar, allow_masked) + # Compute the covariance matrix + if not rowvar: + fact = np.dot(xnotmask.T, xnotmask) * 1. + c = (dot(x.T, x.conj(), strict=False) / fact).squeeze() + else: + fact = np.dot(xnotmask, xnotmask.T) * 1. + c = (dot(x, x.T.conj(), strict=False) / fact).squeeze() + # Check whether we have a scalar + try: + diag = ma.diagonal(c) + except ValueError: + return 1 + # + if xnotmask.all(): + _denom = ma.sqrt(ma.multiply.outer(diag, diag)) + else: + _denom = diagflat(diag) + _denom._sharedmask = False # We know return is always a copy + n = x.shape[1 - rowvar] + if rowvar: + for i in range(n - 1): + for j in range(i + 1, n): + _x = mask_cols(vstack((x[i], x[j]))).var(axis=1) + _denom[i, j] = _denom[j, i] = ma.sqrt(ma.multiply.reduce(_x)) + else: + for i in range(n - 1): + for j in range(i + 1, n): + _x = mask_cols( + vstack((x[:, i], x[:, j]))).var(axis=1) + _denom[i, j] = _denom[j, i] = ma.sqrt(ma.multiply.reduce(_x)) + return c / _denom + +#####-------------------------------------------------------------------------- +#---- --- Concatenation helpers --- +#####-------------------------------------------------------------------------- + +class MAxisConcatenator(AxisConcatenator): + """ + Translate slice objects to concatenation along an axis. + + For documentation on usage, see `mr_class`. + + See Also + -------- + mr_class + + """ + concatenate = staticmethod(concatenate) + + @classmethod + def makemat(cls, arr): + # There used to be a view as np.matrix here, but we may eventually + # deprecate that class. In preparation, we use the unmasked version + # to construct the matrix (with copy=False for backwards compatibility + # with the .view) + data = super(MAxisConcatenator, cls).makemat(arr.data, copy=False) + return array(data, mask=arr.mask) + + def __getitem__(self, key): + # matrix builder syntax, like 'a, b; c, d' + if isinstance(key, str): + raise MAError("Unavailable for masked array.") + + return super(MAxisConcatenator, self).__getitem__(key) + + +class mr_class(MAxisConcatenator): + """ + Translate slice objects to concatenation along the first axis. + + This is the masked array version of `lib.index_tricks.RClass`. + + See Also + -------- + lib.index_tricks.RClass + + Examples + -------- + >>> np.ma.mr_[np.ma.array([1,2,3]), 0, 0, np.ma.array([4,5,6])] + masked_array(data=[1, 2, 3, ..., 4, 5, 6], + mask=False, + fill_value=999999) + + """ + def __init__(self): + MAxisConcatenator.__init__(self, 0) + +mr_ = mr_class() + +#####-------------------------------------------------------------------------- +#---- Find unmasked data --- +#####-------------------------------------------------------------------------- + +def flatnotmasked_edges(a): + """ + Find the indices of the first and last unmasked values. + + Expects a 1-D `MaskedArray`, returns None if all values are masked. + + Parameters + ---------- + a : array_like + Input 1-D `MaskedArray` + + Returns + ------- + edges : ndarray or None + The indices of first and last non-masked value in the array. + Returns None if all values are masked. + + See Also + -------- + flatnotmasked_contiguous, notmasked_contiguous, notmasked_edges + clump_masked, clump_unmasked + + Notes + ----- + Only accepts 1-D arrays. + + Examples + -------- + >>> a = np.ma.arange(10) + >>> np.ma.flatnotmasked_edges(a) + array([0, 9]) + + >>> mask = (a < 3) | (a > 8) | (a == 5) + >>> a[mask] = np.ma.masked + >>> np.array(a[~a.mask]) + array([3, 4, 6, 7, 8]) + + >>> np.ma.flatnotmasked_edges(a) + array([3, 8]) + + >>> a[:] = np.ma.masked + >>> print(np.ma.flatnotmasked_edges(a)) + None + + """ + m = getmask(a) + if m is nomask or not np.any(m): + return np.array([0, a.size - 1]) + unmasked = np.flatnonzero(~m) + if len(unmasked) > 0: + return unmasked[[0, -1]] + else: + return None + + +def notmasked_edges(a, axis=None): + """ + Find the indices of the first and last unmasked values along an axis. + + If all values are masked, return None. Otherwise, return a list + of two tuples, corresponding to the indices of the first and last + unmasked values respectively. + + Parameters + ---------- + a : array_like + The input array. + axis : int, optional + Axis along which to perform the operation. + If None (default), applies to a flattened version of the array. + + Returns + ------- + edges : ndarray or list + An array of start and end indexes if there are any masked data in + the array. If there are no masked data in the array, `edges` is a + list of the first and last index. + + See Also + -------- + flatnotmasked_contiguous, flatnotmasked_edges, notmasked_contiguous + clump_masked, clump_unmasked + + Examples + -------- + >>> a = np.arange(9).reshape((3, 3)) + >>> m = np.zeros_like(a) + >>> m[1:, 1:] = 1 + + >>> am = np.ma.array(a, mask=m) + >>> np.array(am[~am.mask]) + array([0, 1, 2, 3, 6]) + + >>> np.ma.notmasked_edges(am) + array([0, 6]) + + """ + a = asarray(a) + if axis is None or a.ndim == 1: + return flatnotmasked_edges(a) + m = getmaskarray(a) + idx = array(np.indices(a.shape), mask=np.asarray([m] * a.ndim)) + return [tuple([idx[i].min(axis).compressed() for i in range(a.ndim)]), + tuple([idx[i].max(axis).compressed() for i in range(a.ndim)]), ] + + +def flatnotmasked_contiguous(a): + """ + Find contiguous unmasked data in a masked array along the given axis. + + Parameters + ---------- + a : narray + The input array. + + Returns + ------- + slice_list : list + A sorted sequence of `slice` objects (start index, end index). + + .. versionchanged:: 1.15.0 + Now returns an empty list instead of None for a fully masked array + + See Also + -------- + flatnotmasked_edges, notmasked_contiguous, notmasked_edges + clump_masked, clump_unmasked + + Notes + ----- + Only accepts 2-D arrays at most. + + Examples + -------- + >>> a = np.ma.arange(10) + >>> np.ma.flatnotmasked_contiguous(a) + [slice(0, 10, None)] + + >>> mask = (a < 3) | (a > 8) | (a == 5) + >>> a[mask] = np.ma.masked + >>> np.array(a[~a.mask]) + array([3, 4, 6, 7, 8]) + + >>> np.ma.flatnotmasked_contiguous(a) + [slice(3, 5, None), slice(6, 9, None)] + >>> a[:] = np.ma.masked + >>> np.ma.flatnotmasked_contiguous(a) + [] + + """ + m = getmask(a) + if m is nomask: + return [slice(0, a.size)] + i = 0 + result = [] + for (k, g) in itertools.groupby(m.ravel()): + n = len(list(g)) + if not k: + result.append(slice(i, i + n)) + i += n + return result + +def notmasked_contiguous(a, axis=None): + """ + Find contiguous unmasked data in a masked array along the given axis. + + Parameters + ---------- + a : array_like + The input array. + axis : int, optional + Axis along which to perform the operation. + If None (default), applies to a flattened version of the array, and this + is the same as `flatnotmasked_contiguous`. + + Returns + ------- + endpoints : list + A list of slices (start and end indexes) of unmasked indexes + in the array. + + If the input is 2d and axis is specified, the result is a list of lists. + + See Also + -------- + flatnotmasked_edges, flatnotmasked_contiguous, notmasked_edges + clump_masked, clump_unmasked + + Notes + ----- + Only accepts 2-D arrays at most. + + Examples + -------- + >>> a = np.arange(12).reshape((3, 4)) + >>> mask = np.zeros_like(a) + >>> mask[1:, :-1] = 1; mask[0, 1] = 1; mask[-1, 0] = 0 + >>> ma = np.ma.array(a, mask=mask) + >>> ma + masked_array( + data=[[0, --, 2, 3], + [--, --, --, 7], + [8, --, --, 11]], + mask=[[False, True, False, False], + [ True, True, True, False], + [False, True, True, False]], + fill_value=999999) + >>> np.array(ma[~ma.mask]) + array([ 0, 2, 3, 7, 8, 11]) + + >>> np.ma.notmasked_contiguous(ma) + [slice(0, 1, None), slice(2, 4, None), slice(7, 9, None), slice(11, 12, None)] + + >>> np.ma.notmasked_contiguous(ma, axis=0) + [[slice(0, 1, None), slice(2, 3, None)], [], [slice(0, 1, None)], [slice(0, 3, None)]] + + >>> np.ma.notmasked_contiguous(ma, axis=1) + [[slice(0, 1, None), slice(2, 4, None)], [slice(3, 4, None)], [slice(0, 1, None), slice(3, 4, None)]] + + """ + a = asarray(a) + nd = a.ndim + if nd > 2: + raise NotImplementedError("Currently limited to atmost 2D array.") + if axis is None or nd == 1: + return flatnotmasked_contiguous(a) + # + result = [] + # + other = (axis + 1) % 2 + idx = [0, 0] + idx[axis] = slice(None, None) + # + for i in range(a.shape[other]): + idx[other] = i + result.append(flatnotmasked_contiguous(a[tuple(idx)])) + return result + + +def _ezclump(mask): + """ + Finds the clumps (groups of data with the same values) for a 1D bool array. + + Returns a series of slices. + """ + if mask.ndim > 1: + mask = mask.ravel() + idx = (mask[1:] ^ mask[:-1]).nonzero() + idx = idx[0] + 1 + + if mask[0]: + if len(idx) == 0: + return [slice(0, mask.size)] + + r = [slice(0, idx[0])] + r.extend((slice(left, right) + for left, right in zip(idx[1:-1:2], idx[2::2]))) + else: + if len(idx) == 0: + return [] + + r = [slice(left, right) for left, right in zip(idx[:-1:2], idx[1::2])] + + if mask[-1]: + r.append(slice(idx[-1], mask.size)) + return r + + +def clump_unmasked(a): + """ + Return list of slices corresponding to the unmasked clumps of a 1-D array. + (A "clump" is defined as a contiguous region of the array). + + Parameters + ---------- + a : ndarray + A one-dimensional masked array. + + Returns + ------- + slices : list of slice + The list of slices, one for each continuous region of unmasked + elements in `a`. + + Notes + ----- + .. versionadded:: 1.4.0 + + See Also + -------- + flatnotmasked_edges, flatnotmasked_contiguous, notmasked_edges + notmasked_contiguous, clump_masked + + Examples + -------- + >>> a = np.ma.masked_array(np.arange(10)) + >>> a[[0, 1, 2, 6, 8, 9]] = np.ma.masked + >>> np.ma.clump_unmasked(a) + [slice(3, 6, None), slice(7, 8, None)] + + """ + mask = getattr(a, '_mask', nomask) + if mask is nomask: + return [slice(0, a.size)] + return _ezclump(~mask) + + +def clump_masked(a): + """ + Returns a list of slices corresponding to the masked clumps of a 1-D array. + (A "clump" is defined as a contiguous region of the array). + + Parameters + ---------- + a : ndarray + A one-dimensional masked array. + + Returns + ------- + slices : list of slice + The list of slices, one for each continuous region of masked elements + in `a`. + + Notes + ----- + .. versionadded:: 1.4.0 + + See Also + -------- + flatnotmasked_edges, flatnotmasked_contiguous, notmasked_edges + notmasked_contiguous, clump_unmasked + + Examples + -------- + >>> a = np.ma.masked_array(np.arange(10)) + >>> a[[0, 1, 2, 6, 8, 9]] = np.ma.masked + >>> np.ma.clump_masked(a) + [slice(0, 3, None), slice(6, 7, None), slice(8, 10, None)] + + """ + mask = ma.getmask(a) + if mask is nomask: + return [] + return _ezclump(mask) + + +############################################################################### +# Polynomial fit # +############################################################################### + + +def vander(x, n=None): + """ + Masked values in the input array result in rows of zeros. + + """ + _vander = np.vander(x, n) + m = getmask(x) + if m is not nomask: + _vander[m] = 0 + return _vander + +vander.__doc__ = ma.doc_note(np.vander.__doc__, vander.__doc__) + + +def polyfit(x, y, deg, rcond=None, full=False, w=None, cov=False): + """ + Any masked values in x is propagated in y, and vice-versa. + + """ + x = asarray(x) + y = asarray(y) + + m = getmask(x) + if y.ndim == 1: + m = mask_or(m, getmask(y)) + elif y.ndim == 2: + my = getmask(mask_rows(y)) + if my is not nomask: + m = mask_or(m, my[:, 0]) + else: + raise TypeError("Expected a 1D or 2D array for y!") + + if w is not None: + w = asarray(w) + if w.ndim != 1: + raise TypeError("expected a 1-d array for weights") + if w.shape[0] != y.shape[0]: + raise TypeError("expected w and y to have the same length") + m = mask_or(m, getmask(w)) + + if m is not nomask: + not_m = ~m + if w is not None: + w = w[not_m] + return np.polyfit(x[not_m], y[not_m], deg, rcond, full, w, cov) + else: + return np.polyfit(x, y, deg, rcond, full, w, cov) + +polyfit.__doc__ = ma.doc_note(np.polyfit.__doc__, polyfit.__doc__) diff --git a/venv/Lib/site-packages/numpy/ma/mrecords.py b/venv/Lib/site-packages/numpy/ma/mrecords.py new file mode 100644 index 0000000..7008763 --- /dev/null +++ b/venv/Lib/site-packages/numpy/ma/mrecords.py @@ -0,0 +1,770 @@ +""":mod:`numpy.ma..mrecords` + +Defines the equivalent of :class:`numpy.recarrays` for masked arrays, +where fields can be accessed as attributes. +Note that :class:`numpy.ma.MaskedArray` already supports structured datatypes +and the masking of individual fields. + +.. moduleauthor:: Pierre Gerard-Marchant + +""" +# We should make sure that no field is called '_mask','mask','_fieldmask', +# or whatever restricted keywords. An idea would be to no bother in the +# first place, and then rename the invalid fields with a trailing +# underscore. Maybe we could just overload the parser function ? + +import warnings + +import numpy as np +from numpy import ( + bool_, dtype, ndarray, recarray, array as narray + ) +from numpy.core.records import ( + fromarrays as recfromarrays, fromrecords as recfromrecords + ) + +_byteorderconv = np.core.records._byteorderconv + +import numpy.ma as ma +from numpy.ma import ( + MAError, MaskedArray, masked, nomask, masked_array, getdata, + getmaskarray, filled + ) + +_check_fill_value = ma.core._check_fill_value + + +__all__ = [ + 'MaskedRecords', 'mrecarray', 'fromarrays', 'fromrecords', + 'fromtextfile', 'addfield', + ] + +reserved_fields = ['_data', '_mask', '_fieldmask', 'dtype'] + + +def _checknames(descr, names=None): + """ + Checks that field names ``descr`` are not reserved keywords. + + If this is the case, a default 'f%i' is substituted. If the argument + `names` is not None, updates the field names to valid names. + + """ + ndescr = len(descr) + default_names = ['f%i' % i for i in range(ndescr)] + if names is None: + new_names = default_names + else: + if isinstance(names, (tuple, list)): + new_names = names + elif isinstance(names, str): + new_names = names.split(',') + else: + raise NameError(f'illegal input names {names!r}') + nnames = len(new_names) + if nnames < ndescr: + new_names += default_names[nnames:] + ndescr = [] + for (n, d, t) in zip(new_names, default_names, descr.descr): + if n in reserved_fields: + if t[0] in reserved_fields: + ndescr.append((d, t[1])) + else: + ndescr.append(t) + else: + ndescr.append((n, t[1])) + return np.dtype(ndescr) + + +def _get_fieldmask(self): + mdescr = [(n, '|b1') for n in self.dtype.names] + fdmask = np.empty(self.shape, dtype=mdescr) + fdmask.flat = tuple([False] * len(mdescr)) + return fdmask + + +class MaskedRecords(MaskedArray): + """ + + Attributes + ---------- + _data : recarray + Underlying data, as a record array. + _mask : boolean array + Mask of the records. A record is masked when all its fields are + masked. + _fieldmask : boolean recarray + Record array of booleans, setting the mask of each individual field + of each record. + _fill_value : record + Filling values for each field. + + """ + + def __new__(cls, shape, dtype=None, buf=None, offset=0, strides=None, + formats=None, names=None, titles=None, + byteorder=None, aligned=False, + mask=nomask, hard_mask=False, fill_value=None, keep_mask=True, + copy=False, + **options): + + self = recarray.__new__(cls, shape, dtype=dtype, buf=buf, offset=offset, + strides=strides, formats=formats, names=names, + titles=titles, byteorder=byteorder, + aligned=aligned,) + + mdtype = ma.make_mask_descr(self.dtype) + if mask is nomask or not np.size(mask): + if not keep_mask: + self._mask = tuple([False] * len(mdtype)) + else: + mask = np.array(mask, copy=copy) + if mask.shape != self.shape: + (nd, nm) = (self.size, mask.size) + if nm == 1: + mask = np.resize(mask, self.shape) + elif nm == nd: + mask = np.reshape(mask, self.shape) + else: + msg = "Mask and data not compatible: data size is %i, " + \ + "mask size is %i." + raise MAError(msg % (nd, nm)) + copy = True + if not keep_mask: + self.__setmask__(mask) + self._sharedmask = True + else: + if mask.dtype == mdtype: + _mask = mask + else: + _mask = np.array([tuple([m] * len(mdtype)) for m in mask], + dtype=mdtype) + self._mask = _mask + return self + + def __array_finalize__(self, obj): + # Make sure we have a _fieldmask by default + _mask = getattr(obj, '_mask', None) + if _mask is None: + objmask = getattr(obj, '_mask', nomask) + _dtype = ndarray.__getattribute__(self, 'dtype') + if objmask is nomask: + _mask = ma.make_mask_none(self.shape, dtype=_dtype) + else: + mdescr = ma.make_mask_descr(_dtype) + _mask = narray([tuple([m] * len(mdescr)) for m in objmask], + dtype=mdescr).view(recarray) + # Update some of the attributes + _dict = self.__dict__ + _dict.update(_mask=_mask) + self._update_from(obj) + if _dict['_baseclass'] == ndarray: + _dict['_baseclass'] = recarray + return + + @property + def _data(self): + """ + Returns the data as a recarray. + + """ + return ndarray.view(self, recarray) + + @property + def _fieldmask(self): + """ + Alias to mask. + + """ + return self._mask + + def __len__(self): + """ + Returns the length + + """ + # We have more than one record + if self.ndim: + return len(self._data) + # We have only one record: return the nb of fields + return len(self.dtype) + + def __getattribute__(self, attr): + try: + return object.__getattribute__(self, attr) + except AttributeError: + # attr must be a fieldname + pass + fielddict = ndarray.__getattribute__(self, 'dtype').fields + try: + res = fielddict[attr][:2] + except (TypeError, KeyError) as e: + raise AttributeError(f'record array has no attribute {attr}') from e + # So far, so good + _localdict = ndarray.__getattribute__(self, '__dict__') + _data = ndarray.view(self, _localdict['_baseclass']) + obj = _data.getfield(*res) + if obj.dtype.names is not None: + raise NotImplementedError("MaskedRecords is currently limited to" + "simple records.") + # Get some special attributes + # Reset the object's mask + hasmasked = False + _mask = _localdict.get('_mask', None) + if _mask is not None: + try: + _mask = _mask[attr] + except IndexError: + # Couldn't find a mask: use the default (nomask) + pass + tp_len = len(_mask.dtype) + hasmasked = _mask.view((bool, ((tp_len,) if tp_len else ()))).any() + if (obj.shape or hasmasked): + obj = obj.view(MaskedArray) + obj._baseclass = ndarray + obj._isfield = True + obj._mask = _mask + # Reset the field values + _fill_value = _localdict.get('_fill_value', None) + if _fill_value is not None: + try: + obj._fill_value = _fill_value[attr] + except ValueError: + obj._fill_value = None + else: + obj = obj.item() + return obj + + def __setattr__(self, attr, val): + """ + Sets the attribute attr to the value val. + + """ + # Should we call __setmask__ first ? + if attr in ['mask', 'fieldmask']: + self.__setmask__(val) + return + # Create a shortcut (so that we don't have to call getattr all the time) + _localdict = object.__getattribute__(self, '__dict__') + # Check whether we're creating a new field + newattr = attr not in _localdict + try: + # Is attr a generic attribute ? + ret = object.__setattr__(self, attr, val) + except Exception: + # Not a generic attribute: exit if it's not a valid field + fielddict = ndarray.__getattribute__(self, 'dtype').fields or {} + optinfo = ndarray.__getattribute__(self, '_optinfo') or {} + if not (attr in fielddict or attr in optinfo): + raise + else: + # Get the list of names + fielddict = ndarray.__getattribute__(self, 'dtype').fields or {} + # Check the attribute + if attr not in fielddict: + return ret + if newattr: + # We just added this one or this setattr worked on an + # internal attribute. + try: + object.__delattr__(self, attr) + except Exception: + return ret + # Let's try to set the field + try: + res = fielddict[attr][:2] + except (TypeError, KeyError): + raise AttributeError(f'record array has no attribute {attr}') + + if val is masked: + _fill_value = _localdict['_fill_value'] + if _fill_value is not None: + dval = _localdict['_fill_value'][attr] + else: + dval = val + mval = True + else: + dval = filled(val) + mval = getmaskarray(val) + obj = ndarray.__getattribute__(self, '_data').setfield(dval, *res) + _localdict['_mask'].__setitem__(attr, mval) + return obj + + def __getitem__(self, indx): + """ + Returns all the fields sharing the same fieldname base. + + The fieldname base is either `_data` or `_mask`. + + """ + _localdict = self.__dict__ + _mask = ndarray.__getattribute__(self, '_mask') + _data = ndarray.view(self, _localdict['_baseclass']) + # We want a field + if isinstance(indx, str): + # Make sure _sharedmask is True to propagate back to _fieldmask + # Don't use _set_mask, there are some copies being made that + # break propagation Don't force the mask to nomask, that wreaks + # easy masking + obj = _data[indx].view(MaskedArray) + obj._mask = _mask[indx] + obj._sharedmask = True + fval = _localdict['_fill_value'] + if fval is not None: + obj._fill_value = fval[indx] + # Force to masked if the mask is True + if not obj.ndim and obj._mask: + return masked + return obj + # We want some elements. + # First, the data. + obj = np.array(_data[indx], copy=False).view(mrecarray) + obj._mask = np.array(_mask[indx], copy=False).view(recarray) + return obj + + def __setitem__(self, indx, value): + """ + Sets the given record to value. + + """ + MaskedArray.__setitem__(self, indx, value) + if isinstance(indx, str): + self._mask[indx] = ma.getmaskarray(value) + + def __str__(self): + """ + Calculates the string representation. + + """ + if self.size > 1: + mstr = [f"({','.join([str(i) for i in s])})" + for s in zip(*[getattr(self, f) for f in self.dtype.names])] + return f"[{', '.join(mstr)}]" + else: + mstr = [f"{','.join([str(i) for i in s])}" + for s in zip([getattr(self, f) for f in self.dtype.names])] + return f"({', '.join(mstr)})" + + def __repr__(self): + """ + Calculates the repr representation. + + """ + _names = self.dtype.names + fmt = "%%%is : %%s" % (max([len(n) for n in _names]) + 4,) + reprstr = [fmt % (f, getattr(self, f)) for f in self.dtype.names] + reprstr.insert(0, 'masked_records(') + reprstr.extend([fmt % (' fill_value', self.fill_value), + ' )']) + return str("\n".join(reprstr)) + + def view(self, dtype=None, type=None): + """ + Returns a view of the mrecarray. + + """ + # OK, basic copy-paste from MaskedArray.view. + if dtype is None: + if type is None: + output = ndarray.view(self) + else: + output = ndarray.view(self, type) + # Here again. + elif type is None: + try: + if issubclass(dtype, ndarray): + output = ndarray.view(self, dtype) + dtype = None + else: + output = ndarray.view(self, dtype) + # OK, there's the change + except TypeError: + dtype = np.dtype(dtype) + # we need to revert to MaskedArray, but keeping the possibility + # of subclasses (eg, TimeSeriesRecords), so we'll force a type + # set to the first parent + if dtype.fields is None: + basetype = self.__class__.__bases__[0] + output = self.__array__().view(dtype, basetype) + output._update_from(self) + else: + output = ndarray.view(self, dtype) + output._fill_value = None + else: + output = ndarray.view(self, dtype, type) + # Update the mask, just like in MaskedArray.view + if (getattr(output, '_mask', nomask) is not nomask): + mdtype = ma.make_mask_descr(output.dtype) + output._mask = self._mask.view(mdtype, ndarray) + output._mask.shape = output.shape + return output + + def harden_mask(self): + """ + Forces the mask to hard. + + """ + self._hardmask = True + + def soften_mask(self): + """ + Forces the mask to soft + + """ + self._hardmask = False + + def copy(self): + """ + Returns a copy of the masked record. + + """ + copied = self._data.copy().view(type(self)) + copied._mask = self._mask.copy() + return copied + + def tolist(self, fill_value=None): + """ + Return the data portion of the array as a list. + + Data items are converted to the nearest compatible Python type. + Masked values are converted to fill_value. If fill_value is None, + the corresponding entries in the output list will be ``None``. + + """ + if fill_value is not None: + return self.filled(fill_value).tolist() + result = narray(self.filled().tolist(), dtype=object) + mask = narray(self._mask.tolist()) + result[mask] = None + return result.tolist() + + def __getstate__(self): + """Return the internal state of the masked array. + + This is for pickling. + + """ + state = (1, + self.shape, + self.dtype, + self.flags.fnc, + self._data.tobytes(), + self._mask.tobytes(), + self._fill_value, + ) + return state + + def __setstate__(self, state): + """ + Restore the internal state of the masked array. + + This is for pickling. ``state`` is typically the output of the + ``__getstate__`` output, and is a 5-tuple: + + - class name + - a tuple giving the shape of the data + - a typecode for the data + - a binary string for the data + - a binary string for the mask. + + """ + (ver, shp, typ, isf, raw, msk, flv) = state + ndarray.__setstate__(self, (shp, typ, isf, raw)) + mdtype = dtype([(k, bool_) for (k, _) in self.dtype.descr]) + self.__dict__['_mask'].__setstate__((shp, mdtype, isf, msk)) + self.fill_value = flv + + def __reduce__(self): + """ + Return a 3-tuple for pickling a MaskedArray. + + """ + return (_mrreconstruct, + (self.__class__, self._baseclass, (0,), 'b',), + self.__getstate__()) + +def _mrreconstruct(subtype, baseclass, baseshape, basetype,): + """ + Build a new MaskedArray from the information stored in a pickle. + + """ + _data = ndarray.__new__(baseclass, baseshape, basetype).view(subtype) + _mask = ndarray.__new__(ndarray, baseshape, 'b1') + return subtype.__new__(subtype, _data, mask=_mask, dtype=basetype,) + +mrecarray = MaskedRecords + + +############################################################################### +# Constructors # +############################################################################### + + +def fromarrays(arraylist, dtype=None, shape=None, formats=None, + names=None, titles=None, aligned=False, byteorder=None, + fill_value=None): + """ + Creates a mrecarray from a (flat) list of masked arrays. + + Parameters + ---------- + arraylist : sequence + A list of (masked) arrays. Each element of the sequence is first converted + to a masked array if needed. If a 2D array is passed as argument, it is + processed line by line + dtype : {None, dtype}, optional + Data type descriptor. + shape : {None, integer}, optional + Number of records. If None, shape is defined from the shape of the + first array in the list. + formats : {None, sequence}, optional + Sequence of formats for each individual field. If None, the formats will + be autodetected by inspecting the fields and selecting the highest dtype + possible. + names : {None, sequence}, optional + Sequence of the names of each field. + fill_value : {None, sequence}, optional + Sequence of data to be used as filling values. + + Notes + ----- + Lists of tuples should be preferred over lists of lists for faster processing. + + """ + datalist = [getdata(x) for x in arraylist] + masklist = [np.atleast_1d(getmaskarray(x)) for x in arraylist] + _array = recfromarrays(datalist, + dtype=dtype, shape=shape, formats=formats, + names=names, titles=titles, aligned=aligned, + byteorder=byteorder).view(mrecarray) + _array._mask.flat = list(zip(*masklist)) + if fill_value is not None: + _array.fill_value = fill_value + return _array + + +def fromrecords(reclist, dtype=None, shape=None, formats=None, names=None, + titles=None, aligned=False, byteorder=None, + fill_value=None, mask=nomask): + """ + Creates a MaskedRecords from a list of records. + + Parameters + ---------- + reclist : sequence + A list of records. Each element of the sequence is first converted + to a masked array if needed. If a 2D array is passed as argument, it is + processed line by line + dtype : {None, dtype}, optional + Data type descriptor. + shape : {None,int}, optional + Number of records. If None, ``shape`` is defined from the shape of the + first array in the list. + formats : {None, sequence}, optional + Sequence of formats for each individual field. If None, the formats will + be autodetected by inspecting the fields and selecting the highest dtype + possible. + names : {None, sequence}, optional + Sequence of the names of each field. + fill_value : {None, sequence}, optional + Sequence of data to be used as filling values. + mask : {nomask, sequence}, optional. + External mask to apply on the data. + + Notes + ----- + Lists of tuples should be preferred over lists of lists for faster processing. + + """ + # Grab the initial _fieldmask, if needed: + _mask = getattr(reclist, '_mask', None) + # Get the list of records. + if isinstance(reclist, ndarray): + # Make sure we don't have some hidden mask + if isinstance(reclist, MaskedArray): + reclist = reclist.filled().view(ndarray) + # Grab the initial dtype, just in case + if dtype is None: + dtype = reclist.dtype + reclist = reclist.tolist() + mrec = recfromrecords(reclist, dtype=dtype, shape=shape, formats=formats, + names=names, titles=titles, + aligned=aligned, byteorder=byteorder).view(mrecarray) + # Set the fill_value if needed + if fill_value is not None: + mrec.fill_value = fill_value + # Now, let's deal w/ the mask + if mask is not nomask: + mask = np.array(mask, copy=False) + maskrecordlength = len(mask.dtype) + if maskrecordlength: + mrec._mask.flat = mask + elif mask.ndim == 2: + mrec._mask.flat = [tuple(m) for m in mask] + else: + mrec.__setmask__(mask) + if _mask is not None: + mrec._mask[:] = _mask + return mrec + + +def _guessvartypes(arr): + """ + Tries to guess the dtypes of the str_ ndarray `arr`. + + Guesses by testing element-wise conversion. Returns a list of dtypes. + The array is first converted to ndarray. If the array is 2D, the test + is performed on the first line. An exception is raised if the file is + 3D or more. + + """ + vartypes = [] + arr = np.asarray(arr) + if arr.ndim == 2: + arr = arr[0] + elif arr.ndim > 2: + raise ValueError("The array should be 2D at most!") + # Start the conversion loop. + for f in arr: + try: + int(f) + except (ValueError, TypeError): + try: + float(f) + except (ValueError, TypeError): + try: + complex(f) + except (ValueError, TypeError): + vartypes.append(arr.dtype) + else: + vartypes.append(np.dtype(complex)) + else: + vartypes.append(np.dtype(float)) + else: + vartypes.append(np.dtype(int)) + return vartypes + + +def openfile(fname): + """ + Opens the file handle of file `fname`. + + """ + # A file handle + if hasattr(fname, 'readline'): + return fname + # Try to open the file and guess its type + try: + f = open(fname) + except IOError: + raise IOError(f"No such file: '{fname}'") + if f.readline()[:2] != "\\x": + f.seek(0, 0) + return f + f.close() + raise NotImplementedError("Wow, binary file") + + +def fromtextfile(fname, delimitor=None, commentchar='#', missingchar='', + varnames=None, vartypes=None): + """ + Creates a mrecarray from data stored in the file `filename`. + + Parameters + ---------- + fname : {file name/handle} + Handle of an opened file. + delimitor : {None, string}, optional + Alphanumeric character used to separate columns in the file. + If None, any (group of) white spacestring(s) will be used. + commentchar : {'#', string}, optional + Alphanumeric character used to mark the start of a comment. + missingchar : {'', string}, optional + String indicating missing data, and used to create the masks. + varnames : {None, sequence}, optional + Sequence of the variable names. If None, a list will be created from + the first non empty line of the file. + vartypes : {None, sequence}, optional + Sequence of the variables dtypes. If None, it will be estimated from + the first non-commented line. + + + Ultra simple: the varnames are in the header, one line""" + # Try to open the file. + ftext = openfile(fname) + + # Get the first non-empty line as the varnames + while True: + line = ftext.readline() + firstline = line[:line.find(commentchar)].strip() + _varnames = firstline.split(delimitor) + if len(_varnames) > 1: + break + if varnames is None: + varnames = _varnames + + # Get the data. + _variables = masked_array([line.strip().split(delimitor) for line in ftext + if line[0] != commentchar and len(line) > 1]) + (_, nfields) = _variables.shape + ftext.close() + + # Try to guess the dtype. + if vartypes is None: + vartypes = _guessvartypes(_variables[0]) + else: + vartypes = [np.dtype(v) for v in vartypes] + if len(vartypes) != nfields: + msg = "Attempting to %i dtypes for %i fields!" + msg += " Reverting to default." + warnings.warn(msg % (len(vartypes), nfields), stacklevel=2) + vartypes = _guessvartypes(_variables[0]) + + # Construct the descriptor. + mdescr = [(n, f) for (n, f) in zip(varnames, vartypes)] + mfillv = [ma.default_fill_value(f) for f in vartypes] + + # Get the data and the mask. + # We just need a list of masked_arrays. It's easier to create it like that: + _mask = (_variables.T == missingchar) + _datalist = [masked_array(a, mask=m, dtype=t, fill_value=f) + for (a, m, t, f) in zip(_variables.T, _mask, vartypes, mfillv)] + + return fromarrays(_datalist, dtype=mdescr) + + +def addfield(mrecord, newfield, newfieldname=None): + """Adds a new field to the masked record array + + Uses `newfield` as data and `newfieldname` as name. If `newfieldname` + is None, the new field name is set to 'fi', where `i` is the number of + existing fields. + + """ + _data = mrecord._data + _mask = mrecord._mask + if newfieldname is None or newfieldname in reserved_fields: + newfieldname = 'f%i' % len(_data.dtype) + newfield = ma.array(newfield) + # Get the new data. + # Create a new empty recarray + newdtype = np.dtype(_data.dtype.descr + [(newfieldname, newfield.dtype)]) + newdata = recarray(_data.shape, newdtype) + # Add the existing field + [newdata.setfield(_data.getfield(*f), *f) + for f in _data.dtype.fields.values()] + # Add the new field + newdata.setfield(newfield._data, *newdata.dtype.fields[newfieldname]) + newdata = newdata.view(MaskedRecords) + # Get the new mask + # Create a new empty recarray + newmdtype = np.dtype([(n, bool_) for n in newdtype.names]) + newmask = recarray(_data.shape, newmdtype) + # Add the old masks + [newmask.setfield(_mask.getfield(*f), *f) + for f in _mask.dtype.fields.values()] + # Add the mask of the new field + newmask.setfield(getmaskarray(newfield), + *newmask.dtype.fields[newfieldname]) + newdata._mask = newmask + return newdata diff --git a/venv/Lib/site-packages/numpy/ma/setup.py b/venv/Lib/site-packages/numpy/ma/setup.py new file mode 100644 index 0000000..018d38c --- /dev/null +++ b/venv/Lib/site-packages/numpy/ma/setup.py @@ -0,0 +1,12 @@ +#!/usr/bin/env python3 +def configuration(parent_package='',top_path=None): + from numpy.distutils.misc_util import Configuration + config = Configuration('ma', parent_package, top_path) + config.add_subpackage('tests') + config.add_data_files('*.pyi') + return config + +if __name__ == "__main__": + from numpy.distutils.core import setup + config = configuration(top_path='').todict() + setup(**config) diff --git a/venv/Lib/site-packages/numpy/ma/tests/__init__.py b/venv/Lib/site-packages/numpy/ma/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/venv/Lib/site-packages/numpy/ma/tests/test_core.py b/venv/Lib/site-packages/numpy/ma/tests/test_core.py new file mode 100644 index 0000000..9bfb82d --- /dev/null +++ b/venv/Lib/site-packages/numpy/ma/tests/test_core.py @@ -0,0 +1,5355 @@ +# pylint: disable-msg=W0400,W0511,W0611,W0612,W0614,R0201,E1102 +"""Tests suite for MaskedArray & subclassing. + +:author: Pierre Gerard-Marchant +:contact: pierregm_at_uga_dot_edu +""" +__author__ = "Pierre GF Gerard-Marchant" + +import sys +import warnings +import operator +import itertools +import textwrap +import pytest + +from functools import reduce + + +import numpy as np +import numpy.ma.core +import numpy.core.fromnumeric as fromnumeric +import numpy.core.umath as umath +from numpy.testing import ( + assert_raises, assert_warns, suppress_warnings + ) +from numpy import ndarray +from numpy.compat import asbytes +from numpy.ma.testutils import ( + assert_, assert_array_equal, assert_equal, assert_almost_equal, + assert_equal_records, fail_if_equal, assert_not_equal, + assert_mask_equal + ) +from numpy.ma.core import ( + MAError, MaskError, MaskType, MaskedArray, abs, absolute, add, all, + allclose, allequal, alltrue, angle, anom, arange, arccos, arccosh, arctan2, + arcsin, arctan, argsort, array, asarray, choose, concatenate, + conjugate, cos, cosh, count, default_fill_value, diag, divide, doc_note, + empty, empty_like, equal, exp, flatten_mask, filled, fix_invalid, + flatten_structured_array, fromflex, getmask, getmaskarray, greater, + greater_equal, identity, inner, isMaskedArray, less, less_equal, log, + log10, make_mask, make_mask_descr, mask_or, masked, masked_array, + masked_equal, masked_greater, masked_greater_equal, masked_inside, + masked_less, masked_less_equal, masked_not_equal, masked_outside, + masked_print_option, masked_values, masked_where, max, maximum, + maximum_fill_value, min, minimum, minimum_fill_value, mod, multiply, + mvoid, nomask, not_equal, ones, outer, power, product, put, putmask, + ravel, repeat, reshape, resize, shape, sin, sinh, sometrue, sort, sqrt, + subtract, sum, take, tan, tanh, transpose, where, zeros, + ) +from numpy.compat import pickle + +pi = np.pi + + +suppress_copy_mask_on_assignment = suppress_warnings() +suppress_copy_mask_on_assignment.filter( + numpy.ma.core.MaskedArrayFutureWarning, + "setting an item on a masked array which has a shared mask will not copy") + + +# For parametrized numeric testing +num_dts = [np.dtype(dt_) for dt_ in '?bhilqBHILQefdgFD'] +num_ids = [dt_.char for dt_ in num_dts] + + +class TestMaskedArray: + # Base test class for MaskedArrays. + + def setup(self): + # Base data definition. + x = np.array([1., 1., 1., -2., pi/2.0, 4., 5., -10., 10., 1., 2., 3.]) + y = np.array([5., 0., 3., 2., -1., -4., 0., -10., 10., 1., 0., 3.]) + a10 = 10. + m1 = [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0] + m2 = [0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1] + xm = masked_array(x, mask=m1) + ym = masked_array(y, mask=m2) + z = np.array([-.5, 0., .5, .8]) + zm = masked_array(z, mask=[0, 1, 0, 0]) + xf = np.where(m1, 1e+20, x) + xm.set_fill_value(1e+20) + self.d = (x, y, a10, m1, m2, xm, ym, z, zm, xf) + + def test_basicattributes(self): + # Tests some basic array attributes. + a = array([1, 3, 2]) + b = array([1, 3, 2], mask=[1, 0, 1]) + assert_equal(a.ndim, 1) + assert_equal(b.ndim, 1) + assert_equal(a.size, 3) + assert_equal(b.size, 3) + assert_equal(a.shape, (3,)) + assert_equal(b.shape, (3,)) + + def test_basic0d(self): + # Checks masking a scalar + x = masked_array(0) + assert_equal(str(x), '0') + x = masked_array(0, mask=True) + assert_equal(str(x), str(masked_print_option)) + x = masked_array(0, mask=False) + assert_equal(str(x), '0') + x = array(0, mask=1) + assert_(x.filled().dtype is x._data.dtype) + + def test_basic1d(self): + # Test of basic array creation and properties in 1 dimension. + (x, y, a10, m1, m2, xm, ym, z, zm, xf) = self.d + assert_(not isMaskedArray(x)) + assert_(isMaskedArray(xm)) + assert_((xm - ym).filled(0).any()) + fail_if_equal(xm.mask.astype(int), ym.mask.astype(int)) + s = x.shape + assert_equal(np.shape(xm), s) + assert_equal(xm.shape, s) + assert_equal(xm.dtype, x.dtype) + assert_equal(zm.dtype, z.dtype) + assert_equal(xm.size, reduce(lambda x, y:x * y, s)) + assert_equal(count(xm), len(m1) - reduce(lambda x, y:x + y, m1)) + assert_array_equal(xm, xf) + assert_array_equal(filled(xm, 1.e20), xf) + assert_array_equal(x, xm) + + def test_basic2d(self): + # Test of basic array creation and properties in 2 dimensions. + (x, y, a10, m1, m2, xm, ym, z, zm, xf) = self.d + for s in [(4, 3), (6, 2)]: + x.shape = s + y.shape = s + xm.shape = s + ym.shape = s + xf.shape = s + + assert_(not isMaskedArray(x)) + assert_(isMaskedArray(xm)) + assert_equal(shape(xm), s) + assert_equal(xm.shape, s) + assert_equal(xm.size, reduce(lambda x, y:x * y, s)) + assert_equal(count(xm), len(m1) - reduce(lambda x, y:x + y, m1)) + assert_equal(xm, xf) + assert_equal(filled(xm, 1.e20), xf) + assert_equal(x, xm) + + def test_concatenate_basic(self): + # Tests concatenations. + (x, y, a10, m1, m2, xm, ym, z, zm, xf) = self.d + # basic concatenation + assert_equal(np.concatenate((x, y)), concatenate((xm, ym))) + assert_equal(np.concatenate((x, y)), concatenate((x, y))) + assert_equal(np.concatenate((x, y)), concatenate((xm, y))) + assert_equal(np.concatenate((x, y, x)), concatenate((x, ym, x))) + + def test_concatenate_alongaxis(self): + # Tests concatenations. + (x, y, a10, m1, m2, xm, ym, z, zm, xf) = self.d + # Concatenation along an axis + s = (3, 4) + x.shape = y.shape = xm.shape = ym.shape = s + assert_equal(xm.mask, np.reshape(m1, s)) + assert_equal(ym.mask, np.reshape(m2, s)) + xmym = concatenate((xm, ym), 1) + assert_equal(np.concatenate((x, y), 1), xmym) + assert_equal(np.concatenate((xm.mask, ym.mask), 1), xmym._mask) + + x = zeros(2) + y = array(ones(2), mask=[False, True]) + z = concatenate((x, y)) + assert_array_equal(z, [0, 0, 1, 1]) + assert_array_equal(z.mask, [False, False, False, True]) + z = concatenate((y, x)) + assert_array_equal(z, [1, 1, 0, 0]) + assert_array_equal(z.mask, [False, True, False, False]) + + def test_concatenate_flexible(self): + # Tests the concatenation on flexible arrays. + data = masked_array(list(zip(np.random.rand(10), + np.arange(10))), + dtype=[('a', float), ('b', int)]) + + test = concatenate([data[:5], data[5:]]) + assert_equal_records(test, data) + + def test_creation_ndmin(self): + # Check the use of ndmin + x = array([1, 2, 3], mask=[1, 0, 0], ndmin=2) + assert_equal(x.shape, (1, 3)) + assert_equal(x._data, [[1, 2, 3]]) + assert_equal(x._mask, [[1, 0, 0]]) + + def test_creation_ndmin_from_maskedarray(self): + # Make sure we're not losing the original mask w/ ndmin + x = array([1, 2, 3]) + x[-1] = masked + xx = array(x, ndmin=2, dtype=float) + assert_equal(x.shape, x._mask.shape) + assert_equal(xx.shape, xx._mask.shape) + + def test_creation_maskcreation(self): + # Tests how masks are initialized at the creation of Maskedarrays. + data = arange(24, dtype=float) + data[[3, 6, 15]] = masked + dma_1 = MaskedArray(data) + assert_equal(dma_1.mask, data.mask) + dma_2 = MaskedArray(dma_1) + assert_equal(dma_2.mask, dma_1.mask) + dma_3 = MaskedArray(dma_1, mask=[1, 0, 0, 0] * 6) + fail_if_equal(dma_3.mask, dma_1.mask) + + x = array([1, 2, 3], mask=True) + assert_equal(x._mask, [True, True, True]) + x = array([1, 2, 3], mask=False) + assert_equal(x._mask, [False, False, False]) + y = array([1, 2, 3], mask=x._mask, copy=False) + assert_(np.may_share_memory(x.mask, y.mask)) + y = array([1, 2, 3], mask=x._mask, copy=True) + assert_(not np.may_share_memory(x.mask, y.mask)) + + def test_masked_singleton_array_creation_warns(self): + # The first works, but should not (ideally), there may be no way + # to solve this, however, as long as `np.ma.masked` is an ndarray. + np.array(np.ma.masked) + with pytest.warns(UserWarning): + # Tries to create a float array, using `float(np.ma.masked)`. + # We may want to define this is invalid behaviour in the future! + # (requiring np.ma.masked to be a known NumPy scalar probably + # with a DType.) + np.array([3., np.ma.masked]) + + def test_creation_with_list_of_maskedarrays(self): + # Tests creating a masked array from a list of masked arrays. + x = array(np.arange(5), mask=[1, 0, 0, 0, 0]) + data = array((x, x[::-1])) + assert_equal(data, [[0, 1, 2, 3, 4], [4, 3, 2, 1, 0]]) + assert_equal(data._mask, [[1, 0, 0, 0, 0], [0, 0, 0, 0, 1]]) + + x.mask = nomask + data = array((x, x[::-1])) + assert_equal(data, [[0, 1, 2, 3, 4], [4, 3, 2, 1, 0]]) + assert_(data.mask is nomask) + + def test_creation_with_list_of_maskedarrays_no_bool_cast(self): + # Tests the regression in gh-18551 + masked_str = np.ma.masked_array(['a', 'b'], mask=[True, False]) + normal_int = np.arange(2) + res = np.ma.asarray([masked_str, normal_int], dtype="U21") + assert_array_equal(res.mask, [[True, False], [False, False]]) + + # The above only failed due a long chain of oddity, try also with + # an object array that cannot be converted to bool always: + class NotBool(): + def __bool__(self): + raise ValueError("not a bool!") + masked_obj = np.ma.masked_array([NotBool(), 'b'], mask=[True, False]) + # Check that the NotBool actually fails like we would expect: + with pytest.raises(ValueError, match="not a bool!"): + np.asarray([masked_obj], dtype=bool) + + res = np.ma.asarray([masked_obj, normal_int]) + assert_array_equal(res.mask, [[True, False], [False, False]]) + + def test_creation_from_ndarray_with_padding(self): + x = np.array([('A', 0)], dtype={'names':['f0','f1'], + 'formats':['S4','i8'], + 'offsets':[0,8]}) + array(x) # used to fail due to 'V' padding field in x.dtype.descr + + def test_unknown_keyword_parameter(self): + with pytest.raises(TypeError, match="unexpected keyword argument"): + MaskedArray([1, 2, 3], maks=[0, 1, 0]) # `mask` is misspelled. + + def test_asarray(self): + (x, y, a10, m1, m2, xm, ym, z, zm, xf) = self.d + xm.fill_value = -9999 + xm._hardmask = True + xmm = asarray(xm) + assert_equal(xmm._data, xm._data) + assert_equal(xmm._mask, xm._mask) + assert_equal(xmm.fill_value, xm.fill_value) + assert_equal(xmm._hardmask, xm._hardmask) + + def test_asarray_default_order(self): + # See Issue #6646 + m = np.eye(3).T + assert_(not m.flags.c_contiguous) + + new_m = asarray(m) + assert_(new_m.flags.c_contiguous) + + def test_asarray_enforce_order(self): + # See Issue #6646 + m = np.eye(3).T + assert_(not m.flags.c_contiguous) + + new_m = asarray(m, order='C') + assert_(new_m.flags.c_contiguous) + + def test_fix_invalid(self): + # Checks fix_invalid. + with np.errstate(invalid='ignore'): + data = masked_array([np.nan, 0., 1.], mask=[0, 0, 1]) + data_fixed = fix_invalid(data) + assert_equal(data_fixed._data, [data.fill_value, 0., 1.]) + assert_equal(data_fixed._mask, [1., 0., 1.]) + + def test_maskedelement(self): + # Test of masked element + x = arange(6) + x[1] = masked + assert_(str(masked) == '--') + assert_(x[1] is masked) + assert_equal(filled(x[1], 0), 0) + + def test_set_element_as_object(self): + # Tests setting elements with object + a = empty(1, dtype=object) + x = (1, 2, 3, 4, 5) + a[0] = x + assert_equal(a[0], x) + assert_(a[0] is x) + + import datetime + dt = datetime.datetime.now() + a[0] = dt + assert_(a[0] is dt) + + def test_indexing(self): + # Tests conversions and indexing + x1 = np.array([1, 2, 4, 3]) + x2 = array(x1, mask=[1, 0, 0, 0]) + x3 = array(x1, mask=[0, 1, 0, 1]) + x4 = array(x1) + # test conversion to strings + str(x2) # raises? + repr(x2) # raises? + assert_equal(np.sort(x1), sort(x2, endwith=False)) + # tests of indexing + assert_(type(x2[1]) is type(x1[1])) + assert_(x1[1] == x2[1]) + assert_(x2[0] is masked) + assert_equal(x1[2], x2[2]) + assert_equal(x1[2:5], x2[2:5]) + assert_equal(x1[:], x2[:]) + assert_equal(x1[1:], x3[1:]) + x1[2] = 9 + x2[2] = 9 + assert_equal(x1, x2) + x1[1:3] = 99 + x2[1:3] = 99 + assert_equal(x1, x2) + x2[1] = masked + assert_equal(x1, x2) + x2[1:3] = masked + assert_equal(x1, x2) + x2[:] = x1 + x2[1] = masked + assert_(allequal(getmask(x2), array([0, 1, 0, 0]))) + x3[:] = masked_array([1, 2, 3, 4], [0, 1, 1, 0]) + assert_(allequal(getmask(x3), array([0, 1, 1, 0]))) + x4[:] = masked_array([1, 2, 3, 4], [0, 1, 1, 0]) + assert_(allequal(getmask(x4), array([0, 1, 1, 0]))) + assert_(allequal(x4, array([1, 2, 3, 4]))) + x1 = np.arange(5) * 1.0 + x2 = masked_values(x1, 3.0) + assert_equal(x1, x2) + assert_(allequal(array([0, 0, 0, 1, 0], MaskType), x2.mask)) + assert_equal(3.0, x2.fill_value) + x1 = array([1, 'hello', 2, 3], object) + x2 = np.array([1, 'hello', 2, 3], object) + s1 = x1[1] + s2 = x2[1] + assert_equal(type(s2), str) + assert_equal(type(s1), str) + assert_equal(s1, s2) + assert_(x1[1:1].shape == (0,)) + + @suppress_copy_mask_on_assignment + def test_copy(self): + # Tests of some subtle points of copying and sizing. + n = [0, 0, 1, 0, 0] + m = make_mask(n) + m2 = make_mask(m) + assert_(m is m2) + m3 = make_mask(m, copy=True) + assert_(m is not m3) + + x1 = np.arange(5) + y1 = array(x1, mask=m) + assert_equal(y1._data.__array_interface__, x1.__array_interface__) + assert_(allequal(x1, y1.data)) + assert_equal(y1._mask.__array_interface__, m.__array_interface__) + + y1a = array(y1) + # Default for masked array is not to copy; see gh-10318. + assert_(y1a._data.__array_interface__ == + y1._data.__array_interface__) + assert_(y1a._mask.__array_interface__ == + y1._mask.__array_interface__) + + y2 = array(x1, mask=m3) + assert_(y2._data.__array_interface__ == x1.__array_interface__) + assert_(y2._mask.__array_interface__ == m3.__array_interface__) + assert_(y2[2] is masked) + y2[2] = 9 + assert_(y2[2] is not masked) + assert_(y2._mask.__array_interface__ == m3.__array_interface__) + assert_(allequal(y2.mask, 0)) + + y2a = array(x1, mask=m, copy=1) + assert_(y2a._data.__array_interface__ != x1.__array_interface__) + #assert_( y2a._mask is not m) + assert_(y2a._mask.__array_interface__ != m.__array_interface__) + assert_(y2a[2] is masked) + y2a[2] = 9 + assert_(y2a[2] is not masked) + #assert_( y2a._mask is not m) + assert_(y2a._mask.__array_interface__ != m.__array_interface__) + assert_(allequal(y2a.mask, 0)) + + y3 = array(x1 * 1.0, mask=m) + assert_(filled(y3).dtype is (x1 * 1.0).dtype) + + x4 = arange(4) + x4[2] = masked + y4 = resize(x4, (8,)) + assert_equal(concatenate([x4, x4]), y4) + assert_equal(getmask(y4), [0, 0, 1, 0, 0, 0, 1, 0]) + y5 = repeat(x4, (2, 2, 2, 2), axis=0) + assert_equal(y5, [0, 0, 1, 1, 2, 2, 3, 3]) + y6 = repeat(x4, 2, axis=0) + assert_equal(y5, y6) + y7 = x4.repeat((2, 2, 2, 2), axis=0) + assert_equal(y5, y7) + y8 = x4.repeat(2, 0) + assert_equal(y5, y8) + + y9 = x4.copy() + assert_equal(y9._data, x4._data) + assert_equal(y9._mask, x4._mask) + + x = masked_array([1, 2, 3], mask=[0, 1, 0]) + # Copy is False by default + y = masked_array(x) + assert_equal(y._data.ctypes.data, x._data.ctypes.data) + assert_equal(y._mask.ctypes.data, x._mask.ctypes.data) + y = masked_array(x, copy=True) + assert_not_equal(y._data.ctypes.data, x._data.ctypes.data) + assert_not_equal(y._mask.ctypes.data, x._mask.ctypes.data) + + def test_copy_0d(self): + # gh-9430 + x = np.ma.array(43, mask=True) + xc = x.copy() + assert_equal(xc.mask, True) + + def test_copy_on_python_builtins(self): + # Tests copy works on python builtins (issue#8019) + assert_(isMaskedArray(np.ma.copy([1,2,3]))) + assert_(isMaskedArray(np.ma.copy((1,2,3)))) + + def test_copy_immutable(self): + # Tests that the copy method is immutable, GitHub issue #5247 + a = np.ma.array([1, 2, 3]) + b = np.ma.array([4, 5, 6]) + a_copy_method = a.copy + b.copy + assert_equal(a_copy_method(), [1, 2, 3]) + + def test_deepcopy(self): + from copy import deepcopy + a = array([0, 1, 2], mask=[False, True, False]) + copied = deepcopy(a) + assert_equal(copied.mask, a.mask) + assert_not_equal(id(a._mask), id(copied._mask)) + + copied[1] = 1 + assert_equal(copied.mask, [0, 0, 0]) + assert_equal(a.mask, [0, 1, 0]) + + copied = deepcopy(a) + assert_equal(copied.mask, a.mask) + copied.mask[1] = False + assert_equal(copied.mask, [0, 0, 0]) + assert_equal(a.mask, [0, 1, 0]) + + def test_format(self): + a = array([0, 1, 2], mask=[False, True, False]) + assert_equal(format(a), "[0 -- 2]") + assert_equal(format(masked), "--") + assert_equal(format(masked, ""), "--") + + # Postponed from PR #15410, perhaps address in the future. + # assert_equal(format(masked, " >5"), " --") + # assert_equal(format(masked, " <5"), "-- ") + + # Expect a FutureWarning for using format_spec with MaskedElement + with assert_warns(FutureWarning): + with_format_string = format(masked, " >5") + assert_equal(with_format_string, "--") + + def test_str_repr(self): + a = array([0, 1, 2], mask=[False, True, False]) + assert_equal(str(a), '[0 -- 2]') + assert_equal( + repr(a), + textwrap.dedent('''\ + masked_array(data=[0, --, 2], + mask=[False, True, False], + fill_value=999999)''') + ) + + # arrays with a continuation + a = np.ma.arange(2000) + a[1:50] = np.ma.masked + assert_equal( + repr(a), + textwrap.dedent('''\ + masked_array(data=[0, --, --, ..., 1997, 1998, 1999], + mask=[False, True, True, ..., False, False, False], + fill_value=999999)''') + ) + + # line-wrapped 1d arrays are correctly aligned + a = np.ma.arange(20) + assert_equal( + repr(a), + textwrap.dedent('''\ + masked_array(data=[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, + 14, 15, 16, 17, 18, 19], + mask=False, + fill_value=999999)''') + ) + + # 2d arrays cause wrapping + a = array([[1, 2, 3], [4, 5, 6]], dtype=np.int8) + a[1,1] = np.ma.masked + assert_equal( + repr(a), + textwrap.dedent('''\ + masked_array( + data=[[1, 2, 3], + [4, --, 6]], + mask=[[False, False, False], + [False, True, False]], + fill_value=999999, + dtype=int8)''') + ) + + # but not it they're a row vector + assert_equal( + repr(a[:1]), + textwrap.dedent('''\ + masked_array(data=[[1, 2, 3]], + mask=[[False, False, False]], + fill_value=999999, + dtype=int8)''') + ) + + # dtype=int is implied, so not shown + assert_equal( + repr(a.astype(int)), + textwrap.dedent('''\ + masked_array( + data=[[1, 2, 3], + [4, --, 6]], + mask=[[False, False, False], + [False, True, False]], + fill_value=999999)''') + ) + + def test_str_repr_legacy(self): + oldopts = np.get_printoptions() + np.set_printoptions(legacy='1.13') + try: + a = array([0, 1, 2], mask=[False, True, False]) + assert_equal(str(a), '[0 -- 2]') + assert_equal(repr(a), 'masked_array(data = [0 -- 2],\n' + ' mask = [False True False],\n' + ' fill_value = 999999)\n') + + a = np.ma.arange(2000) + a[1:50] = np.ma.masked + assert_equal( + repr(a), + 'masked_array(data = [0 -- -- ..., 1997 1998 1999],\n' + ' mask = [False True True ..., False False False],\n' + ' fill_value = 999999)\n' + ) + finally: + np.set_printoptions(**oldopts) + + def test_0d_unicode(self): + u = u'caf\xe9' + utype = type(u) + + arr_nomask = np.ma.array(u) + arr_masked = np.ma.array(u, mask=True) + + assert_equal(utype(arr_nomask), u) + assert_equal(utype(arr_masked), u'--') + + def test_pickling(self): + # Tests pickling + for dtype in (int, float, str, object): + a = arange(10).astype(dtype) + a.fill_value = 999 + + masks = ([0, 0, 0, 1, 0, 1, 0, 1, 0, 1], # partially masked + True, # Fully masked + False) # Fully unmasked + + for proto in range(2, pickle.HIGHEST_PROTOCOL + 1): + for mask in masks: + a.mask = mask + a_pickled = pickle.loads(pickle.dumps(a, protocol=proto)) + assert_equal(a_pickled._mask, a._mask) + assert_equal(a_pickled._data, a._data) + if dtype in (object, int): + assert_equal(a_pickled.fill_value, 999) + else: + assert_equal(a_pickled.fill_value, dtype(999)) + assert_array_equal(a_pickled.mask, mask) + + def test_pickling_subbaseclass(self): + # Test pickling w/ a subclass of ndarray + x = np.array([(1.0, 2), (3.0, 4)], + dtype=[('x', float), ('y', int)]).view(np.recarray) + a = masked_array(x, mask=[(True, False), (False, True)]) + for proto in range(2, pickle.HIGHEST_PROTOCOL + 1): + a_pickled = pickle.loads(pickle.dumps(a, protocol=proto)) + assert_equal(a_pickled._mask, a._mask) + assert_equal(a_pickled, a) + assert_(isinstance(a_pickled._data, np.recarray)) + + def test_pickling_maskedconstant(self): + # Test pickling MaskedConstant + mc = np.ma.masked + for proto in range(2, pickle.HIGHEST_PROTOCOL + 1): + mc_pickled = pickle.loads(pickle.dumps(mc, protocol=proto)) + assert_equal(mc_pickled._baseclass, mc._baseclass) + assert_equal(mc_pickled._mask, mc._mask) + assert_equal(mc_pickled._data, mc._data) + + def test_pickling_wstructured(self): + # Tests pickling w/ structured array + a = array([(1, 1.), (2, 2.)], mask=[(0, 0), (0, 1)], + dtype=[('a', int), ('b', float)]) + for proto in range(2, pickle.HIGHEST_PROTOCOL + 1): + a_pickled = pickle.loads(pickle.dumps(a, protocol=proto)) + assert_equal(a_pickled._mask, a._mask) + assert_equal(a_pickled, a) + + def test_pickling_keepalignment(self): + # Tests pickling w/ F_CONTIGUOUS arrays + a = arange(10) + a.shape = (-1, 2) + b = a.T + for proto in range(2, pickle.HIGHEST_PROTOCOL + 1): + test = pickle.loads(pickle.dumps(b, protocol=proto)) + assert_equal(test, b) + + def test_single_element_subscript(self): + # Tests single element subscripts of Maskedarrays. + a = array([1, 3, 2]) + b = array([1, 3, 2], mask=[1, 0, 1]) + assert_equal(a[0].shape, ()) + assert_equal(b[0].shape, ()) + assert_equal(b[1].shape, ()) + + def test_topython(self): + # Tests some communication issues with Python. + assert_equal(1, int(array(1))) + assert_equal(1.0, float(array(1))) + assert_equal(1, int(array([[[1]]]))) + assert_equal(1.0, float(array([[1]]))) + assert_raises(TypeError, float, array([1, 1])) + + with suppress_warnings() as sup: + sup.filter(UserWarning, 'Warning: converting a masked element') + assert_(np.isnan(float(array([1], mask=[1])))) + + a = array([1, 2, 3], mask=[1, 0, 0]) + assert_raises(TypeError, lambda: float(a)) + assert_equal(float(a[-1]), 3.) + assert_(np.isnan(float(a[0]))) + assert_raises(TypeError, int, a) + assert_equal(int(a[-1]), 3) + assert_raises(MAError, lambda:int(a[0])) + + def test_oddfeatures_1(self): + # Test of other odd features + x = arange(20) + x = x.reshape(4, 5) + x.flat[5] = 12 + assert_(x[1, 0] == 12) + z = x + 10j * x + assert_equal(z.real, x) + assert_equal(z.imag, 10 * x) + assert_equal((z * conjugate(z)).real, 101 * x * x) + z.imag[...] = 0.0 + + x = arange(10) + x[3] = masked + assert_(str(x[3]) == str(masked)) + c = x >= 8 + assert_(count(where(c, masked, masked)) == 0) + assert_(shape(where(c, masked, masked)) == c.shape) + + z = masked_where(c, x) + assert_(z.dtype is x.dtype) + assert_(z[3] is masked) + assert_(z[4] is not masked) + assert_(z[7] is not masked) + assert_(z[8] is masked) + assert_(z[9] is masked) + assert_equal(x, z) + + def test_oddfeatures_2(self): + # Tests some more features. + x = array([1., 2., 3., 4., 5.]) + c = array([1, 1, 1, 0, 0]) + x[2] = masked + z = where(c, x, -x) + assert_equal(z, [1., 2., 0., -4., -5]) + c[0] = masked + z = where(c, x, -x) + assert_equal(z, [1., 2., 0., -4., -5]) + assert_(z[0] is masked) + assert_(z[1] is not masked) + assert_(z[2] is masked) + + @suppress_copy_mask_on_assignment + def test_oddfeatures_3(self): + # Tests some generic features + atest = array([10], mask=True) + btest = array([20]) + idx = atest.mask + atest[idx] = btest[idx] + assert_equal(atest, [20]) + + def test_filled_with_object_dtype(self): + a = np.ma.masked_all(1, dtype='O') + assert_equal(a.filled('x')[0], 'x') + + def test_filled_with_flexible_dtype(self): + # Test filled w/ flexible dtype + flexi = array([(1, 1, 1)], + dtype=[('i', int), ('s', '|S8'), ('f', float)]) + flexi[0] = masked + assert_equal(flexi.filled(), + np.array([(default_fill_value(0), + default_fill_value('0'), + default_fill_value(0.),)], dtype=flexi.dtype)) + flexi[0] = masked + assert_equal(flexi.filled(1), + np.array([(1, '1', 1.)], dtype=flexi.dtype)) + + def test_filled_with_mvoid(self): + # Test filled w/ mvoid + ndtype = [('a', int), ('b', float)] + a = mvoid((1, 2.), mask=[(0, 1)], dtype=ndtype) + # Filled using default + test = a.filled() + assert_equal(tuple(test), (1, default_fill_value(1.))) + # Explicit fill_value + test = a.filled((-1, -1)) + assert_equal(tuple(test), (1, -1)) + # Using predefined filling values + a.fill_value = (-999, -999) + assert_equal(tuple(a.filled()), (1, -999)) + + def test_filled_with_nested_dtype(self): + # Test filled w/ nested dtype + ndtype = [('A', int), ('B', [('BA', int), ('BB', int)])] + a = array([(1, (1, 1)), (2, (2, 2))], + mask=[(0, (1, 0)), (0, (0, 1))], dtype=ndtype) + test = a.filled(0) + control = np.array([(1, (0, 1)), (2, (2, 0))], dtype=ndtype) + assert_equal(test, control) + + test = a['B'].filled(0) + control = np.array([(0, 1), (2, 0)], dtype=a['B'].dtype) + assert_equal(test, control) + + # test if mask gets set correctly (see #6760) + Z = numpy.ma.zeros(2, numpy.dtype([("A", "(2,2)i1,(2,2)i1", (2,2))])) + assert_equal(Z.data.dtype, numpy.dtype([('A', [('f0', 'i1', (2, 2)), + ('f1', 'i1', (2, 2))], (2, 2))])) + assert_equal(Z.mask.dtype, numpy.dtype([('A', [('f0', '?', (2, 2)), + ('f1', '?', (2, 2))], (2, 2))])) + + def test_filled_with_f_order(self): + # Test filled w/ F-contiguous array + a = array(np.array([(0, 1, 2), (4, 5, 6)], order='F'), + mask=np.array([(0, 0, 1), (1, 0, 0)], order='F'), + order='F') # this is currently ignored + assert_(a.flags['F_CONTIGUOUS']) + assert_(a.filled(0).flags['F_CONTIGUOUS']) + + def test_optinfo_propagation(self): + # Checks that _optinfo dictionary isn't back-propagated + x = array([1, 2, 3, ], dtype=float) + x._optinfo['info'] = '???' + y = x.copy() + assert_equal(y._optinfo['info'], '???') + y._optinfo['info'] = '!!!' + assert_equal(x._optinfo['info'], '???') + + def test_optinfo_forward_propagation(self): + a = array([1,2,2,4]) + a._optinfo["key"] = "value" + assert_equal(a._optinfo["key"], (a == 2)._optinfo["key"]) + assert_equal(a._optinfo["key"], (a != 2)._optinfo["key"]) + assert_equal(a._optinfo["key"], (a > 2)._optinfo["key"]) + assert_equal(a._optinfo["key"], (a >= 2)._optinfo["key"]) + assert_equal(a._optinfo["key"], (a <= 2)._optinfo["key"]) + assert_equal(a._optinfo["key"], (a + 2)._optinfo["key"]) + assert_equal(a._optinfo["key"], (a - 2)._optinfo["key"]) + assert_equal(a._optinfo["key"], (a * 2)._optinfo["key"]) + assert_equal(a._optinfo["key"], (a / 2)._optinfo["key"]) + assert_equal(a._optinfo["key"], a[:2]._optinfo["key"]) + assert_equal(a._optinfo["key"], a[[0,0,2]]._optinfo["key"]) + assert_equal(a._optinfo["key"], np.exp(a)._optinfo["key"]) + assert_equal(a._optinfo["key"], np.abs(a)._optinfo["key"]) + assert_equal(a._optinfo["key"], array(a, copy=True)._optinfo["key"]) + assert_equal(a._optinfo["key"], np.zeros_like(a)._optinfo["key"]) + + def test_fancy_printoptions(self): + # Test printing a masked array w/ fancy dtype. + fancydtype = np.dtype([('x', int), ('y', [('t', int), ('s', float)])]) + test = array([(1, (2, 3.0)), (4, (5, 6.0))], + mask=[(1, (0, 1)), (0, (1, 0))], + dtype=fancydtype) + control = "[(--, (2, --)) (4, (--, 6.0))]" + assert_equal(str(test), control) + + # Test 0-d array with multi-dimensional dtype + t_2d0 = masked_array(data = (0, [[0.0, 0.0, 0.0], + [0.0, 0.0, 0.0]], + 0.0), + mask = (False, [[True, False, True], + [False, False, True]], + False), + dtype = "int, (2,3)float, float") + control = "(0, [[--, 0.0, --], [0.0, 0.0, --]], 0.0)" + assert_equal(str(t_2d0), control) + + def test_flatten_structured_array(self): + # Test flatten_structured_array on arrays + # On ndarray + ndtype = [('a', int), ('b', float)] + a = np.array([(1, 1), (2, 2)], dtype=ndtype) + test = flatten_structured_array(a) + control = np.array([[1., 1.], [2., 2.]], dtype=float) + assert_equal(test, control) + assert_equal(test.dtype, control.dtype) + # On masked_array + a = array([(1, 1), (2, 2)], mask=[(0, 1), (1, 0)], dtype=ndtype) + test = flatten_structured_array(a) + control = array([[1., 1.], [2., 2.]], + mask=[[0, 1], [1, 0]], dtype=float) + assert_equal(test, control) + assert_equal(test.dtype, control.dtype) + assert_equal(test.mask, control.mask) + # On masked array with nested structure + ndtype = [('a', int), ('b', [('ba', int), ('bb', float)])] + a = array([(1, (1, 1.1)), (2, (2, 2.2))], + mask=[(0, (1, 0)), (1, (0, 1))], dtype=ndtype) + test = flatten_structured_array(a) + control = array([[1., 1., 1.1], [2., 2., 2.2]], + mask=[[0, 1, 0], [1, 0, 1]], dtype=float) + assert_equal(test, control) + assert_equal(test.dtype, control.dtype) + assert_equal(test.mask, control.mask) + # Keeping the initial shape + ndtype = [('a', int), ('b', float)] + a = np.array([[(1, 1), ], [(2, 2), ]], dtype=ndtype) + test = flatten_structured_array(a) + control = np.array([[[1., 1.], ], [[2., 2.], ]], dtype=float) + assert_equal(test, control) + assert_equal(test.dtype, control.dtype) + + def test_void0d(self): + # Test creating a mvoid object + ndtype = [('a', int), ('b', int)] + a = np.array([(1, 2,)], dtype=ndtype)[0] + f = mvoid(a) + assert_(isinstance(f, mvoid)) + + a = masked_array([(1, 2)], mask=[(1, 0)], dtype=ndtype)[0] + assert_(isinstance(a, mvoid)) + + a = masked_array([(1, 2), (1, 2)], mask=[(1, 0), (0, 0)], dtype=ndtype) + f = mvoid(a._data[0], a._mask[0]) + assert_(isinstance(f, mvoid)) + + def test_mvoid_getitem(self): + # Test mvoid.__getitem__ + ndtype = [('a', int), ('b', int)] + a = masked_array([(1, 2,), (3, 4)], mask=[(0, 0), (1, 0)], + dtype=ndtype) + # w/o mask + f = a[0] + assert_(isinstance(f, mvoid)) + assert_equal((f[0], f['a']), (1, 1)) + assert_equal(f['b'], 2) + # w/ mask + f = a[1] + assert_(isinstance(f, mvoid)) + assert_(f[0] is masked) + assert_(f['a'] is masked) + assert_equal(f[1], 4) + + # exotic dtype + A = masked_array(data=[([0,1],)], + mask=[([True, False],)], + dtype=[("A", ">i2", (2,))]) + assert_equal(A[0]["A"], A["A"][0]) + assert_equal(A[0]["A"], masked_array(data=[0, 1], + mask=[True, False], dtype=">i2")) + + def test_mvoid_iter(self): + # Test iteration on __getitem__ + ndtype = [('a', int), ('b', int)] + a = masked_array([(1, 2,), (3, 4)], mask=[(0, 0), (1, 0)], + dtype=ndtype) + # w/o mask + assert_equal(list(a[0]), [1, 2]) + # w/ mask + assert_equal(list(a[1]), [masked, 4]) + + def test_mvoid_print(self): + # Test printing a mvoid + mx = array([(1, 1), (2, 2)], dtype=[('a', int), ('b', int)]) + assert_equal(str(mx[0]), "(1, 1)") + mx['b'][0] = masked + ini_display = masked_print_option._display + masked_print_option.set_display("-X-") + try: + assert_equal(str(mx[0]), "(1, -X-)") + assert_equal(repr(mx[0]), "(1, -X-)") + finally: + masked_print_option.set_display(ini_display) + + # also check if there are object datatypes (see gh-7493) + mx = array([(1,), (2,)], dtype=[('a', 'O')]) + assert_equal(str(mx[0]), "(1,)") + + def test_mvoid_multidim_print(self): + + # regression test for gh-6019 + t_ma = masked_array(data = [([1, 2, 3],)], + mask = [([False, True, False],)], + fill_value = ([999999, 999999, 999999],), + dtype = [('a', ' 1: + assert_equal(np.concatenate((x, y), 1), concatenate((xm, ym), 1)) + assert_equal(np.add.reduce(x, 1), add.reduce(x, 1)) + assert_equal(np.sum(x, 1), sum(x, 1)) + assert_equal(np.product(x, 1), product(x, 1)) + + def test_binops_d2D(self): + # Test binary operations on 2D data + a = array([[1.], [2.], [3.]], mask=[[False], [True], [True]]) + b = array([[2., 3.], [4., 5.], [6., 7.]]) + + test = a * b + control = array([[2., 3.], [2., 2.], [3., 3.]], + mask=[[0, 0], [1, 1], [1, 1]]) + assert_equal(test, control) + assert_equal(test.data, control.data) + assert_equal(test.mask, control.mask) + + test = b * a + control = array([[2., 3.], [4., 5.], [6., 7.]], + mask=[[0, 0], [1, 1], [1, 1]]) + assert_equal(test, control) + assert_equal(test.data, control.data) + assert_equal(test.mask, control.mask) + + a = array([[1.], [2.], [3.]]) + b = array([[2., 3.], [4., 5.], [6., 7.]], + mask=[[0, 0], [0, 0], [0, 1]]) + test = a * b + control = array([[2, 3], [8, 10], [18, 3]], + mask=[[0, 0], [0, 0], [0, 1]]) + assert_equal(test, control) + assert_equal(test.data, control.data) + assert_equal(test.mask, control.mask) + + test = b * a + control = array([[2, 3], [8, 10], [18, 7]], + mask=[[0, 0], [0, 0], [0, 1]]) + assert_equal(test, control) + assert_equal(test.data, control.data) + assert_equal(test.mask, control.mask) + + def test_domained_binops_d2D(self): + # Test domained binary operations on 2D data + a = array([[1.], [2.], [3.]], mask=[[False], [True], [True]]) + b = array([[2., 3.], [4., 5.], [6., 7.]]) + + test = a / b + control = array([[1. / 2., 1. / 3.], [2., 2.], [3., 3.]], + mask=[[0, 0], [1, 1], [1, 1]]) + assert_equal(test, control) + assert_equal(test.data, control.data) + assert_equal(test.mask, control.mask) + + test = b / a + control = array([[2. / 1., 3. / 1.], [4., 5.], [6., 7.]], + mask=[[0, 0], [1, 1], [1, 1]]) + assert_equal(test, control) + assert_equal(test.data, control.data) + assert_equal(test.mask, control.mask) + + a = array([[1.], [2.], [3.]]) + b = array([[2., 3.], [4., 5.], [6., 7.]], + mask=[[0, 0], [0, 0], [0, 1]]) + test = a / b + control = array([[1. / 2, 1. / 3], [2. / 4, 2. / 5], [3. / 6, 3]], + mask=[[0, 0], [0, 0], [0, 1]]) + assert_equal(test, control) + assert_equal(test.data, control.data) + assert_equal(test.mask, control.mask) + + test = b / a + control = array([[2 / 1., 3 / 1.], [4 / 2., 5 / 2.], [6 / 3., 7]], + mask=[[0, 0], [0, 0], [0, 1]]) + assert_equal(test, control) + assert_equal(test.data, control.data) + assert_equal(test.mask, control.mask) + + def test_noshrinking(self): + # Check that we don't shrink a mask when not wanted + # Binary operations + a = masked_array([1., 2., 3.], mask=[False, False, False], + shrink=False) + b = a + 1 + assert_equal(b.mask, [0, 0, 0]) + # In place binary operation + a += 1 + assert_equal(a.mask, [0, 0, 0]) + # Domained binary operation + b = a / 1. + assert_equal(b.mask, [0, 0, 0]) + # In place binary operation + a /= 1. + assert_equal(a.mask, [0, 0, 0]) + + def test_ufunc_nomask(self): + # check the case ufuncs should set the mask to false + m = np.ma.array([1]) + # check we don't get array([False], dtype=bool) + assert_equal(np.true_divide(m, 5).mask.shape, ()) + + def test_noshink_on_creation(self): + # Check that the mask is not shrunk on array creation when not wanted + a = np.ma.masked_values([1., 2.5, 3.1], 1.5, shrink=False) + assert_equal(a.mask, [0, 0, 0]) + + def test_mod(self): + # Tests mod + (x, y, a10, m1, m2, xm, ym, z, zm, xf) = self.d + assert_equal(mod(x, y), mod(xm, ym)) + test = mod(ym, xm) + assert_equal(test, np.mod(ym, xm)) + assert_equal(test.mask, mask_or(xm.mask, ym.mask)) + test = mod(xm, ym) + assert_equal(test, np.mod(xm, ym)) + assert_equal(test.mask, mask_or(mask_or(xm.mask, ym.mask), (ym == 0))) + + def test_TakeTransposeInnerOuter(self): + # Test of take, transpose, inner, outer products + x = arange(24) + y = np.arange(24) + x[5:6] = masked + x = x.reshape(2, 3, 4) + y = y.reshape(2, 3, 4) + assert_equal(np.transpose(y, (2, 0, 1)), transpose(x, (2, 0, 1))) + assert_equal(np.take(y, (2, 0, 1), 1), take(x, (2, 0, 1), 1)) + assert_equal(np.inner(filled(x, 0), filled(y, 0)), + inner(x, y)) + assert_equal(np.outer(filled(x, 0), filled(y, 0)), + outer(x, y)) + y = array(['abc', 1, 'def', 2, 3], object) + y[2] = masked + t = take(y, [0, 3, 4]) + assert_(t[0] == 'abc') + assert_(t[1] == 2) + assert_(t[2] == 3) + + def test_imag_real(self): + # Check complex + xx = array([1 + 10j, 20 + 2j], mask=[1, 0]) + assert_equal(xx.imag, [10, 2]) + assert_equal(xx.imag.filled(), [1e+20, 2]) + assert_equal(xx.imag.dtype, xx._data.imag.dtype) + assert_equal(xx.real, [1, 20]) + assert_equal(xx.real.filled(), [1e+20, 20]) + assert_equal(xx.real.dtype, xx._data.real.dtype) + + def test_methods_with_output(self): + xm = array(np.random.uniform(0, 10, 12)).reshape(3, 4) + xm[:, 0] = xm[0] = xm[-1, -1] = masked + + funclist = ('sum', 'prod', 'var', 'std', 'max', 'min', 'ptp', 'mean',) + + for funcname in funclist: + npfunc = getattr(np, funcname) + xmmeth = getattr(xm, funcname) + # A ndarray as explicit input + output = np.empty(4, dtype=float) + output.fill(-9999) + result = npfunc(xm, axis=0, out=output) + # ... the result should be the given output + assert_(result is output) + assert_equal(result, xmmeth(axis=0, out=output)) + + output = empty(4, dtype=int) + result = xmmeth(axis=0, out=output) + assert_(result is output) + assert_(output[0] is masked) + + def test_eq_on_structured(self): + # Test the equality of structured arrays + ndtype = [('A', int), ('B', int)] + a = array([(1, 1), (2, 2)], mask=[(0, 1), (0, 0)], dtype=ndtype) + + test = (a == a) + assert_equal(test.data, [True, True]) + assert_equal(test.mask, [False, False]) + assert_(test.fill_value == True) + + test = (a == a[0]) + assert_equal(test.data, [True, False]) + assert_equal(test.mask, [False, False]) + assert_(test.fill_value == True) + + b = array([(1, 1), (2, 2)], mask=[(1, 0), (0, 0)], dtype=ndtype) + test = (a == b) + assert_equal(test.data, [False, True]) + assert_equal(test.mask, [True, False]) + assert_(test.fill_value == True) + + test = (a[0] == b) + assert_equal(test.data, [False, False]) + assert_equal(test.mask, [True, False]) + assert_(test.fill_value == True) + + b = array([(1, 1), (2, 2)], mask=[(0, 1), (1, 0)], dtype=ndtype) + test = (a == b) + assert_equal(test.data, [True, True]) + assert_equal(test.mask, [False, False]) + assert_(test.fill_value == True) + + # complicated dtype, 2-dimensional array. + ndtype = [('A', int), ('B', [('BA', int), ('BB', int)])] + a = array([[(1, (1, 1)), (2, (2, 2))], + [(3, (3, 3)), (4, (4, 4))]], + mask=[[(0, (1, 0)), (0, (0, 1))], + [(1, (0, 0)), (1, (1, 1))]], dtype=ndtype) + test = (a[0, 0] == a) + assert_equal(test.data, [[True, False], [False, False]]) + assert_equal(test.mask, [[False, False], [False, True]]) + assert_(test.fill_value == True) + + def test_ne_on_structured(self): + # Test the equality of structured arrays + ndtype = [('A', int), ('B', int)] + a = array([(1, 1), (2, 2)], mask=[(0, 1), (0, 0)], dtype=ndtype) + + test = (a != a) + assert_equal(test.data, [False, False]) + assert_equal(test.mask, [False, False]) + assert_(test.fill_value == True) + + test = (a != a[0]) + assert_equal(test.data, [False, True]) + assert_equal(test.mask, [False, False]) + assert_(test.fill_value == True) + + b = array([(1, 1), (2, 2)], mask=[(1, 0), (0, 0)], dtype=ndtype) + test = (a != b) + assert_equal(test.data, [True, False]) + assert_equal(test.mask, [True, False]) + assert_(test.fill_value == True) + + test = (a[0] != b) + assert_equal(test.data, [True, True]) + assert_equal(test.mask, [True, False]) + assert_(test.fill_value == True) + + b = array([(1, 1), (2, 2)], mask=[(0, 1), (1, 0)], dtype=ndtype) + test = (a != b) + assert_equal(test.data, [False, False]) + assert_equal(test.mask, [False, False]) + assert_(test.fill_value == True) + + # complicated dtype, 2-dimensional array. + ndtype = [('A', int), ('B', [('BA', int), ('BB', int)])] + a = array([[(1, (1, 1)), (2, (2, 2))], + [(3, (3, 3)), (4, (4, 4))]], + mask=[[(0, (1, 0)), (0, (0, 1))], + [(1, (0, 0)), (1, (1, 1))]], dtype=ndtype) + test = (a[0, 0] != a) + assert_equal(test.data, [[False, True], [True, True]]) + assert_equal(test.mask, [[False, False], [False, True]]) + assert_(test.fill_value == True) + + def test_eq_ne_structured_extra(self): + # ensure simple examples are symmetric and make sense. + # from https://github.com/numpy/numpy/pull/8590#discussion_r101126465 + dt = np.dtype('i4,i4') + for m1 in (mvoid((1, 2), mask=(0, 0), dtype=dt), + mvoid((1, 2), mask=(0, 1), dtype=dt), + mvoid((1, 2), mask=(1, 0), dtype=dt), + mvoid((1, 2), mask=(1, 1), dtype=dt)): + ma1 = m1.view(MaskedArray) + r1 = ma1.view('2i4') + for m2 in (np.array((1, 1), dtype=dt), + mvoid((1, 1), dtype=dt), + mvoid((1, 0), mask=(0, 1), dtype=dt), + mvoid((3, 2), mask=(0, 1), dtype=dt)): + ma2 = m2.view(MaskedArray) + r2 = ma2.view('2i4') + eq_expected = (r1 == r2).all() + assert_equal(m1 == m2, eq_expected) + assert_equal(m2 == m1, eq_expected) + assert_equal(ma1 == m2, eq_expected) + assert_equal(m1 == ma2, eq_expected) + assert_equal(ma1 == ma2, eq_expected) + # Also check it is the same if we do it element by element. + el_by_el = [m1[name] == m2[name] for name in dt.names] + assert_equal(array(el_by_el, dtype=bool).all(), eq_expected) + ne_expected = (r1 != r2).any() + assert_equal(m1 != m2, ne_expected) + assert_equal(m2 != m1, ne_expected) + assert_equal(ma1 != m2, ne_expected) + assert_equal(m1 != ma2, ne_expected) + assert_equal(ma1 != ma2, ne_expected) + el_by_el = [m1[name] != m2[name] for name in dt.names] + assert_equal(array(el_by_el, dtype=bool).any(), ne_expected) + + @pytest.mark.parametrize('dt', ['S', 'U']) + @pytest.mark.parametrize('fill', [None, 'A']) + def test_eq_for_strings(self, dt, fill): + # Test the equality of structured arrays + a = array(['a', 'b'], dtype=dt, mask=[0, 1], fill_value=fill) + + test = (a == a) + assert_equal(test.data, [True, True]) + assert_equal(test.mask, [False, True]) + assert_(test.fill_value == True) + + test = (a == a[0]) + assert_equal(test.data, [True, False]) + assert_equal(test.mask, [False, True]) + assert_(test.fill_value == True) + + b = array(['a', 'b'], dtype=dt, mask=[1, 0], fill_value=fill) + test = (a == b) + assert_equal(test.data, [False, False]) + assert_equal(test.mask, [True, True]) + assert_(test.fill_value == True) + + test = (a[0] == b) + assert_equal(test.data, [False, False]) + assert_equal(test.mask, [True, False]) + assert_(test.fill_value == True) + + test = (b == a[0]) + assert_equal(test.data, [False, False]) + assert_equal(test.mask, [True, False]) + assert_(test.fill_value == True) + + @pytest.mark.parametrize('dt', ['S', 'U']) + @pytest.mark.parametrize('fill', [None, 'A']) + def test_ne_for_strings(self, dt, fill): + # Test the equality of structured arrays + a = array(['a', 'b'], dtype=dt, mask=[0, 1], fill_value=fill) + + test = (a != a) + assert_equal(test.data, [False, False]) + assert_equal(test.mask, [False, True]) + assert_(test.fill_value == True) + + test = (a != a[0]) + assert_equal(test.data, [False, True]) + assert_equal(test.mask, [False, True]) + assert_(test.fill_value == True) + + b = array(['a', 'b'], dtype=dt, mask=[1, 0], fill_value=fill) + test = (a != b) + assert_equal(test.data, [True, True]) + assert_equal(test.mask, [True, True]) + assert_(test.fill_value == True) + + test = (a[0] != b) + assert_equal(test.data, [True, True]) + assert_equal(test.mask, [True, False]) + assert_(test.fill_value == True) + + test = (b != a[0]) + assert_equal(test.data, [True, True]) + assert_equal(test.mask, [True, False]) + assert_(test.fill_value == True) + + @pytest.mark.parametrize('dt1', num_dts, ids=num_ids) + @pytest.mark.parametrize('dt2', num_dts, ids=num_ids) + @pytest.mark.parametrize('fill', [None, 1]) + def test_eq_for_numeric(self, dt1, dt2, fill): + # Test the equality of structured arrays + a = array([0, 1], dtype=dt1, mask=[0, 1], fill_value=fill) + + test = (a == a) + assert_equal(test.data, [True, True]) + assert_equal(test.mask, [False, True]) + assert_(test.fill_value == True) + + test = (a == a[0]) + assert_equal(test.data, [True, False]) + assert_equal(test.mask, [False, True]) + assert_(test.fill_value == True) + + b = array([0, 1], dtype=dt2, mask=[1, 0], fill_value=fill) + test = (a == b) + assert_equal(test.data, [False, False]) + assert_equal(test.mask, [True, True]) + assert_(test.fill_value == True) + + test = (a[0] == b) + assert_equal(test.data, [False, False]) + assert_equal(test.mask, [True, False]) + assert_(test.fill_value == True) + + test = (b == a[0]) + assert_equal(test.data, [False, False]) + assert_equal(test.mask, [True, False]) + assert_(test.fill_value == True) + + @pytest.mark.parametrize('dt1', num_dts, ids=num_ids) + @pytest.mark.parametrize('dt2', num_dts, ids=num_ids) + @pytest.mark.parametrize('fill', [None, 1]) + def test_ne_for_numeric(self, dt1, dt2, fill): + # Test the equality of structured arrays + a = array([0, 1], dtype=dt1, mask=[0, 1], fill_value=fill) + + test = (a != a) + assert_equal(test.data, [False, False]) + assert_equal(test.mask, [False, True]) + assert_(test.fill_value == True) + + test = (a != a[0]) + assert_equal(test.data, [False, True]) + assert_equal(test.mask, [False, True]) + assert_(test.fill_value == True) + + b = array([0, 1], dtype=dt2, mask=[1, 0], fill_value=fill) + test = (a != b) + assert_equal(test.data, [True, True]) + assert_equal(test.mask, [True, True]) + assert_(test.fill_value == True) + + test = (a[0] != b) + assert_equal(test.data, [True, True]) + assert_equal(test.mask, [True, False]) + assert_(test.fill_value == True) + + test = (b != a[0]) + assert_equal(test.data, [True, True]) + assert_equal(test.mask, [True, False]) + assert_(test.fill_value == True) + + def test_eq_with_None(self): + # Really, comparisons with None should not be done, but check them + # anyway. Note that pep8 will flag these tests. + # Deprecation is in place for arrays, and when it happens this + # test will fail (and have to be changed accordingly). + + # With partial mask + with suppress_warnings() as sup: + sup.filter(FutureWarning, "Comparison to `None`") + a = array([None, 1], mask=[0, 1]) + assert_equal(a == None, array([True, False], mask=[0, 1])) + assert_equal(a.data == None, [True, False]) + assert_equal(a != None, array([False, True], mask=[0, 1])) + # With nomask + a = array([None, 1], mask=False) + assert_equal(a == None, [True, False]) + assert_equal(a != None, [False, True]) + # With complete mask + a = array([None, 2], mask=True) + assert_equal(a == None, array([False, True], mask=True)) + assert_equal(a != None, array([True, False], mask=True)) + # Fully masked, even comparison to None should return "masked" + a = masked + assert_equal(a == None, masked) + + def test_eq_with_scalar(self): + a = array(1) + assert_equal(a == 1, True) + assert_equal(a == 0, False) + assert_equal(a != 1, False) + assert_equal(a != 0, True) + b = array(1, mask=True) + assert_equal(b == 0, masked) + assert_equal(b == 1, masked) + assert_equal(b != 0, masked) + assert_equal(b != 1, masked) + + def test_eq_different_dimensions(self): + m1 = array([1, 1], mask=[0, 1]) + # test comparison with both masked and regular arrays. + for m2 in (array([[0, 1], [1, 2]]), + np.array([[0, 1], [1, 2]])): + test = (m1 == m2) + assert_equal(test.data, [[False, False], + [True, False]]) + assert_equal(test.mask, [[False, True], + [False, True]]) + + def test_numpyarithmetics(self): + # Check that the mask is not back-propagated when using numpy functions + a = masked_array([-1, 0, 1, 2, 3], mask=[0, 0, 0, 0, 1]) + control = masked_array([np.nan, np.nan, 0, np.log(2), -1], + mask=[1, 1, 0, 0, 1]) + + test = log(a) + assert_equal(test, control) + assert_equal(test.mask, control.mask) + assert_equal(a.mask, [0, 0, 0, 0, 1]) + + test = np.log(a) + assert_equal(test, control) + assert_equal(test.mask, control.mask) + assert_equal(a.mask, [0, 0, 0, 0, 1]) + + +class TestMaskedArrayAttributes: + + def test_keepmask(self): + # Tests the keep mask flag + x = masked_array([1, 2, 3], mask=[1, 0, 0]) + mx = masked_array(x) + assert_equal(mx.mask, x.mask) + mx = masked_array(x, mask=[0, 1, 0], keep_mask=False) + assert_equal(mx.mask, [0, 1, 0]) + mx = masked_array(x, mask=[0, 1, 0], keep_mask=True) + assert_equal(mx.mask, [1, 1, 0]) + # We default to true + mx = masked_array(x, mask=[0, 1, 0]) + assert_equal(mx.mask, [1, 1, 0]) + + def test_hardmask(self): + # Test hard_mask + d = arange(5) + n = [0, 0, 0, 1, 1] + m = make_mask(n) + xh = array(d, mask=m, hard_mask=True) + # We need to copy, to avoid updating d in xh ! + xs = array(d, mask=m, hard_mask=False, copy=True) + xh[[1, 4]] = [10, 40] + xs[[1, 4]] = [10, 40] + assert_equal(xh._data, [0, 10, 2, 3, 4]) + assert_equal(xs._data, [0, 10, 2, 3, 40]) + assert_equal(xs.mask, [0, 0, 0, 1, 0]) + assert_(xh._hardmask) + assert_(not xs._hardmask) + xh[1:4] = [10, 20, 30] + xs[1:4] = [10, 20, 30] + assert_equal(xh._data, [0, 10, 20, 3, 4]) + assert_equal(xs._data, [0, 10, 20, 30, 40]) + assert_equal(xs.mask, nomask) + xh[0] = masked + xs[0] = masked + assert_equal(xh.mask, [1, 0, 0, 1, 1]) + assert_equal(xs.mask, [1, 0, 0, 0, 0]) + xh[:] = 1 + xs[:] = 1 + assert_equal(xh._data, [0, 1, 1, 3, 4]) + assert_equal(xs._data, [1, 1, 1, 1, 1]) + assert_equal(xh.mask, [1, 0, 0, 1, 1]) + assert_equal(xs.mask, nomask) + # Switch to soft mask + xh.soften_mask() + xh[:] = arange(5) + assert_equal(xh._data, [0, 1, 2, 3, 4]) + assert_equal(xh.mask, nomask) + # Switch back to hard mask + xh.harden_mask() + xh[xh < 3] = masked + assert_equal(xh._data, [0, 1, 2, 3, 4]) + assert_equal(xh._mask, [1, 1, 1, 0, 0]) + xh[filled(xh > 1, False)] = 5 + assert_equal(xh._data, [0, 1, 2, 5, 5]) + assert_equal(xh._mask, [1, 1, 1, 0, 0]) + + xh = array([[1, 2], [3, 4]], mask=[[1, 0], [0, 0]], hard_mask=True) + xh[0] = 0 + assert_equal(xh._data, [[1, 0], [3, 4]]) + assert_equal(xh._mask, [[1, 0], [0, 0]]) + xh[-1, -1] = 5 + assert_equal(xh._data, [[1, 0], [3, 5]]) + assert_equal(xh._mask, [[1, 0], [0, 0]]) + xh[filled(xh < 5, False)] = 2 + assert_equal(xh._data, [[1, 2], [2, 5]]) + assert_equal(xh._mask, [[1, 0], [0, 0]]) + + def test_hardmask_again(self): + # Another test of hardmask + d = arange(5) + n = [0, 0, 0, 1, 1] + m = make_mask(n) + xh = array(d, mask=m, hard_mask=True) + xh[4:5] = 999 + xh[0:1] = 999 + assert_equal(xh._data, [999, 1, 2, 3, 4]) + + def test_hardmask_oncemore_yay(self): + # OK, yet another test of hardmask + # Make sure that harden_mask/soften_mask//unshare_mask returns self + a = array([1, 2, 3], mask=[1, 0, 0]) + b = a.harden_mask() + assert_equal(a, b) + b[0] = 0 + assert_equal(a, b) + assert_equal(b, array([1, 2, 3], mask=[1, 0, 0])) + a = b.soften_mask() + a[0] = 0 + assert_equal(a, b) + assert_equal(b, array([0, 2, 3], mask=[0, 0, 0])) + + def test_smallmask(self): + # Checks the behaviour of _smallmask + a = arange(10) + a[1] = masked + a[1] = 1 + assert_equal(a._mask, nomask) + a = arange(10) + a._smallmask = False + a[1] = masked + a[1] = 1 + assert_equal(a._mask, zeros(10)) + + def test_shrink_mask(self): + # Tests .shrink_mask() + a = array([1, 2, 3], mask=[0, 0, 0]) + b = a.shrink_mask() + assert_equal(a, b) + assert_equal(a.mask, nomask) + + # Mask cannot be shrunk on structured types, so is a no-op + a = np.ma.array([(1, 2.0)], [('a', int), ('b', float)]) + b = a.copy() + a.shrink_mask() + assert_equal(a.mask, b.mask) + + def test_flat(self): + # Test that flat can return all types of items [#4585, #4615] + # test 2-D record array + # ... on structured array w/ masked records + x = array([[(1, 1.1, 'one'), (2, 2.2, 'two'), (3, 3.3, 'thr')], + [(4, 4.4, 'fou'), (5, 5.5, 'fiv'), (6, 6.6, 'six')]], + dtype=[('a', int), ('b', float), ('c', '|S8')]) + x['a'][0, 1] = masked + x['b'][1, 0] = masked + x['c'][0, 2] = masked + x[-1, -1] = masked + xflat = x.flat + assert_equal(xflat[0], x[0, 0]) + assert_equal(xflat[1], x[0, 1]) + assert_equal(xflat[2], x[0, 2]) + assert_equal(xflat[:3], x[0]) + assert_equal(xflat[3], x[1, 0]) + assert_equal(xflat[4], x[1, 1]) + assert_equal(xflat[5], x[1, 2]) + assert_equal(xflat[3:], x[1]) + assert_equal(xflat[-1], x[-1, -1]) + i = 0 + j = 0 + for xf in xflat: + assert_equal(xf, x[j, i]) + i += 1 + if i >= x.shape[-1]: + i = 0 + j += 1 + + def test_assign_dtype(self): + # check that the mask's dtype is updated when dtype is changed + a = np.zeros(4, dtype='f4,i4') + + m = np.ma.array(a) + m.dtype = np.dtype('f4') + repr(m) # raises? + assert_equal(m.dtype, np.dtype('f4')) + + # check that dtype changes that change shape of mask too much + # are not allowed + def assign(): + m = np.ma.array(a) + m.dtype = np.dtype('f8') + assert_raises(ValueError, assign) + + b = a.view(dtype='f4', type=np.ma.MaskedArray) # raises? + assert_equal(b.dtype, np.dtype('f4')) + + # check that nomask is preserved + a = np.zeros(4, dtype='f4') + m = np.ma.array(a) + m.dtype = np.dtype('f4,i4') + assert_equal(m.dtype, np.dtype('f4,i4')) + assert_equal(m._mask, np.ma.nomask) + + +class TestFillingValues: + + def test_check_on_scalar(self): + # Test _check_fill_value set to valid and invalid values + _check_fill_value = np.ma.core._check_fill_value + + fval = _check_fill_value(0, int) + assert_equal(fval, 0) + fval = _check_fill_value(None, int) + assert_equal(fval, default_fill_value(0)) + + fval = _check_fill_value(0, "|S3") + assert_equal(fval, b"0") + fval = _check_fill_value(None, "|S3") + assert_equal(fval, default_fill_value(b"camelot!")) + assert_raises(TypeError, _check_fill_value, 1e+20, int) + assert_raises(TypeError, _check_fill_value, 'stuff', int) + + def test_check_on_fields(self): + # Tests _check_fill_value with records + _check_fill_value = np.ma.core._check_fill_value + ndtype = [('a', int), ('b', float), ('c', "|S3")] + # A check on a list should return a single record + fval = _check_fill_value([-999, -12345678.9, "???"], ndtype) + assert_(isinstance(fval, ndarray)) + assert_equal(fval.item(), [-999, -12345678.9, b"???"]) + # A check on None should output the defaults + fval = _check_fill_value(None, ndtype) + assert_(isinstance(fval, ndarray)) + assert_equal(fval.item(), [default_fill_value(0), + default_fill_value(0.), + asbytes(default_fill_value("0"))]) + #.....Using a structured type as fill_value should work + fill_val = np.array((-999, -12345678.9, "???"), dtype=ndtype) + fval = _check_fill_value(fill_val, ndtype) + assert_(isinstance(fval, ndarray)) + assert_equal(fval.item(), [-999, -12345678.9, b"???"]) + + #.....Using a flexible type w/ a different type shouldn't matter + # BEHAVIOR in 1.5 and earlier, and 1.13 and later: match structured + # types by position + fill_val = np.array((-999, -12345678.9, "???"), + dtype=[("A", int), ("B", float), ("C", "|S3")]) + fval = _check_fill_value(fill_val, ndtype) + assert_(isinstance(fval, ndarray)) + assert_equal(fval.item(), [-999, -12345678.9, b"???"]) + + #.....Using an object-array shouldn't matter either + fill_val = np.ndarray(shape=(1,), dtype=object) + fill_val[0] = (-999, -12345678.9, b"???") + fval = _check_fill_value(fill_val, object) + assert_(isinstance(fval, ndarray)) + assert_equal(fval.item(), [-999, -12345678.9, b"???"]) + # NOTE: This test was never run properly as "fill_value" rather than + # "fill_val" was assigned. Written properly, it fails. + #fill_val = np.array((-999, -12345678.9, "???")) + #fval = _check_fill_value(fill_val, ndtype) + #assert_(isinstance(fval, ndarray)) + #assert_equal(fval.item(), [-999, -12345678.9, b"???"]) + #.....One-field-only flexible type should work as well + ndtype = [("a", int)] + fval = _check_fill_value(-999999999, ndtype) + assert_(isinstance(fval, ndarray)) + assert_equal(fval.item(), (-999999999,)) + + def test_fillvalue_conversion(self): + # Tests the behavior of fill_value during conversion + # We had a tailored comment to make sure special attributes are + # properly dealt with + a = array([b'3', b'4', b'5']) + a._optinfo.update({'comment':"updated!"}) + + b = array(a, dtype=int) + assert_equal(b._data, [3, 4, 5]) + assert_equal(b.fill_value, default_fill_value(0)) + + b = array(a, dtype=float) + assert_equal(b._data, [3, 4, 5]) + assert_equal(b.fill_value, default_fill_value(0.)) + + b = a.astype(int) + assert_equal(b._data, [3, 4, 5]) + assert_equal(b.fill_value, default_fill_value(0)) + assert_equal(b._optinfo['comment'], "updated!") + + b = a.astype([('a', '|S3')]) + assert_equal(b['a']._data, a._data) + assert_equal(b['a'].fill_value, a.fill_value) + + def test_default_fill_value(self): + # check all calling conventions + f1 = default_fill_value(1.) + f2 = default_fill_value(np.array(1.)) + f3 = default_fill_value(np.array(1.).dtype) + assert_equal(f1, f2) + assert_equal(f1, f3) + + def test_default_fill_value_structured(self): + fields = array([(1, 1, 1)], + dtype=[('i', int), ('s', '|S8'), ('f', float)]) + + f1 = default_fill_value(fields) + f2 = default_fill_value(fields.dtype) + expected = np.array((default_fill_value(0), + default_fill_value('0'), + default_fill_value(0.)), dtype=fields.dtype) + assert_equal(f1, expected) + assert_equal(f2, expected) + + def test_default_fill_value_void(self): + dt = np.dtype([('v', 'V7')]) + f = default_fill_value(dt) + assert_equal(f['v'], np.array(default_fill_value(dt['v']), dt['v'])) + + def test_fillvalue(self): + # Yet more fun with the fill_value + data = masked_array([1, 2, 3], fill_value=-999) + series = data[[0, 2, 1]] + assert_equal(series._fill_value, data._fill_value) + + mtype = [('f', float), ('s', '|S3')] + x = array([(1, 'a'), (2, 'b'), (pi, 'pi')], dtype=mtype) + x.fill_value = 999 + assert_equal(x.fill_value.item(), [999., b'999']) + assert_equal(x['f'].fill_value, 999) + assert_equal(x['s'].fill_value, b'999') + + x.fill_value = (9, '???') + assert_equal(x.fill_value.item(), (9, b'???')) + assert_equal(x['f'].fill_value, 9) + assert_equal(x['s'].fill_value, b'???') + + x = array([1, 2, 3.1]) + x.fill_value = 999 + assert_equal(np.asarray(x.fill_value).dtype, float) + assert_equal(x.fill_value, 999.) + assert_equal(x._fill_value, np.array(999.)) + + def test_subarray_fillvalue(self): + # gh-10483 test multi-field index fill value + fields = array([(1, 1, 1)], + dtype=[('i', int), ('s', '|S8'), ('f', float)]) + with suppress_warnings() as sup: + sup.filter(FutureWarning, "Numpy has detected") + subfields = fields[['i', 'f']] + assert_equal(tuple(subfields.fill_value), (999999, 1.e+20)) + # test comparison does not raise: + subfields[1:] == subfields[:-1] + + def test_fillvalue_exotic_dtype(self): + # Tests yet more exotic flexible dtypes + _check_fill_value = np.ma.core._check_fill_value + ndtype = [('i', int), ('s', '|S8'), ('f', float)] + control = np.array((default_fill_value(0), + default_fill_value('0'), + default_fill_value(0.),), + dtype=ndtype) + assert_equal(_check_fill_value(None, ndtype), control) + # The shape shouldn't matter + ndtype = [('f0', float, (2, 2))] + control = np.array((default_fill_value(0.),), + dtype=[('f0', float)]).astype(ndtype) + assert_equal(_check_fill_value(None, ndtype), control) + control = np.array((0,), dtype=[('f0', float)]).astype(ndtype) + assert_equal(_check_fill_value(0, ndtype), control) + + ndtype = np.dtype("int, (2,3)float, float") + control = np.array((default_fill_value(0), + default_fill_value(0.), + default_fill_value(0.),), + dtype="int, float, float").astype(ndtype) + test = _check_fill_value(None, ndtype) + assert_equal(test, control) + control = np.array((0, 0, 0), dtype="int, float, float").astype(ndtype) + assert_equal(_check_fill_value(0, ndtype), control) + # but when indexing, fill value should become scalar not tuple + # See issue #6723 + M = masked_array(control) + assert_equal(M["f1"].fill_value.ndim, 0) + + def test_fillvalue_datetime_timedelta(self): + # Test default fillvalue for datetime64 and timedelta64 types. + # See issue #4476, this would return '?' which would cause errors + # elsewhere + + for timecode in ("as", "fs", "ps", "ns", "us", "ms", "s", "m", + "h", "D", "W", "M", "Y"): + control = numpy.datetime64("NaT", timecode) + test = default_fill_value(numpy.dtype(" 0 + + # test different unary domains + sqrt(m) + log(m) + tan(m) + arcsin(m) + arccos(m) + arccosh(m) + + # test binary domains + divide(m, 2) + + # also check that allclose uses ma ufuncs, to avoid warning + allclose(m, 0.5) + +class TestMaskedArrayInPlaceArithmetics: + # Test MaskedArray Arithmetics + + def setup(self): + x = arange(10) + y = arange(10) + xm = arange(10) + xm[2] = masked + self.intdata = (x, y, xm) + self.floatdata = (x.astype(float), y.astype(float), xm.astype(float)) + self.othertypes = np.typecodes['AllInteger'] + np.typecodes['AllFloat'] + self.othertypes = [np.dtype(_).type for _ in self.othertypes] + self.uint8data = ( + x.astype(np.uint8), + y.astype(np.uint8), + xm.astype(np.uint8) + ) + + def test_inplace_addition_scalar(self): + # Test of inplace additions + (x, y, xm) = self.intdata + xm[2] = masked + x += 1 + assert_equal(x, y + 1) + xm += 1 + assert_equal(xm, y + 1) + + (x, _, xm) = self.floatdata + id1 = x.data.ctypes.data + x += 1. + assert_(id1 == x.data.ctypes.data) + assert_equal(x, y + 1.) + + def test_inplace_addition_array(self): + # Test of inplace additions + (x, y, xm) = self.intdata + m = xm.mask + a = arange(10, dtype=np.int16) + a[-1] = masked + x += a + xm += a + assert_equal(x, y + a) + assert_equal(xm, y + a) + assert_equal(xm.mask, mask_or(m, a.mask)) + + def test_inplace_subtraction_scalar(self): + # Test of inplace subtractions + (x, y, xm) = self.intdata + x -= 1 + assert_equal(x, y - 1) + xm -= 1 + assert_equal(xm, y - 1) + + def test_inplace_subtraction_array(self): + # Test of inplace subtractions + (x, y, xm) = self.floatdata + m = xm.mask + a = arange(10, dtype=float) + a[-1] = masked + x -= a + xm -= a + assert_equal(x, y - a) + assert_equal(xm, y - a) + assert_equal(xm.mask, mask_or(m, a.mask)) + + def test_inplace_multiplication_scalar(self): + # Test of inplace multiplication + (x, y, xm) = self.floatdata + x *= 2.0 + assert_equal(x, y * 2) + xm *= 2.0 + assert_equal(xm, y * 2) + + def test_inplace_multiplication_array(self): + # Test of inplace multiplication + (x, y, xm) = self.floatdata + m = xm.mask + a = arange(10, dtype=float) + a[-1] = masked + x *= a + xm *= a + assert_equal(x, y * a) + assert_equal(xm, y * a) + assert_equal(xm.mask, mask_or(m, a.mask)) + + def test_inplace_division_scalar_int(self): + # Test of inplace division + (x, y, xm) = self.intdata + x = arange(10) * 2 + xm = arange(10) * 2 + xm[2] = masked + x //= 2 + assert_equal(x, y) + xm //= 2 + assert_equal(xm, y) + + def test_inplace_division_scalar_float(self): + # Test of inplace division + (x, y, xm) = self.floatdata + x /= 2.0 + assert_equal(x, y / 2.0) + xm /= arange(10) + assert_equal(xm, ones((10,))) + + def test_inplace_division_array_float(self): + # Test of inplace division + (x, y, xm) = self.floatdata + m = xm.mask + a = arange(10, dtype=float) + a[-1] = masked + x /= a + xm /= a + assert_equal(x, y / a) + assert_equal(xm, y / a) + assert_equal(xm.mask, mask_or(mask_or(m, a.mask), (a == 0))) + + def test_inplace_division_misc(self): + + x = [1., 1., 1., -2., pi / 2., 4., 5., -10., 10., 1., 2., 3.] + y = [5., 0., 3., 2., -1., -4., 0., -10., 10., 1., 0., 3.] + m1 = [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0] + m2 = [0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1] + xm = masked_array(x, mask=m1) + ym = masked_array(y, mask=m2) + + z = xm / ym + assert_equal(z._mask, [1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1]) + assert_equal(z._data, + [1., 1., 1., -1., -pi / 2., 4., 5., 1., 1., 1., 2., 3.]) + + xm = xm.copy() + xm /= ym + assert_equal(xm._mask, [1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1]) + assert_equal(z._data, + [1., 1., 1., -1., -pi / 2., 4., 5., 1., 1., 1., 2., 3.]) + + def test_datafriendly_add(self): + # Test keeping data w/ (inplace) addition + x = array([1, 2, 3], mask=[0, 0, 1]) + # Test add w/ scalar + xx = x + 1 + assert_equal(xx.data, [2, 3, 3]) + assert_equal(xx.mask, [0, 0, 1]) + # Test iadd w/ scalar + x += 1 + assert_equal(x.data, [2, 3, 3]) + assert_equal(x.mask, [0, 0, 1]) + # Test add w/ array + x = array([1, 2, 3], mask=[0, 0, 1]) + xx = x + array([1, 2, 3], mask=[1, 0, 0]) + assert_equal(xx.data, [1, 4, 3]) + assert_equal(xx.mask, [1, 0, 1]) + # Test iadd w/ array + x = array([1, 2, 3], mask=[0, 0, 1]) + x += array([1, 2, 3], mask=[1, 0, 0]) + assert_equal(x.data, [1, 4, 3]) + assert_equal(x.mask, [1, 0, 1]) + + def test_datafriendly_sub(self): + # Test keeping data w/ (inplace) subtraction + # Test sub w/ scalar + x = array([1, 2, 3], mask=[0, 0, 1]) + xx = x - 1 + assert_equal(xx.data, [0, 1, 3]) + assert_equal(xx.mask, [0, 0, 1]) + # Test isub w/ scalar + x = array([1, 2, 3], mask=[0, 0, 1]) + x -= 1 + assert_equal(x.data, [0, 1, 3]) + assert_equal(x.mask, [0, 0, 1]) + # Test sub w/ array + x = array([1, 2, 3], mask=[0, 0, 1]) + xx = x - array([1, 2, 3], mask=[1, 0, 0]) + assert_equal(xx.data, [1, 0, 3]) + assert_equal(xx.mask, [1, 0, 1]) + # Test isub w/ array + x = array([1, 2, 3], mask=[0, 0, 1]) + x -= array([1, 2, 3], mask=[1, 0, 0]) + assert_equal(x.data, [1, 0, 3]) + assert_equal(x.mask, [1, 0, 1]) + + def test_datafriendly_mul(self): + # Test keeping data w/ (inplace) multiplication + # Test mul w/ scalar + x = array([1, 2, 3], mask=[0, 0, 1]) + xx = x * 2 + assert_equal(xx.data, [2, 4, 3]) + assert_equal(xx.mask, [0, 0, 1]) + # Test imul w/ scalar + x = array([1, 2, 3], mask=[0, 0, 1]) + x *= 2 + assert_equal(x.data, [2, 4, 3]) + assert_equal(x.mask, [0, 0, 1]) + # Test mul w/ array + x = array([1, 2, 3], mask=[0, 0, 1]) + xx = x * array([10, 20, 30], mask=[1, 0, 0]) + assert_equal(xx.data, [1, 40, 3]) + assert_equal(xx.mask, [1, 0, 1]) + # Test imul w/ array + x = array([1, 2, 3], mask=[0, 0, 1]) + x *= array([10, 20, 30], mask=[1, 0, 0]) + assert_equal(x.data, [1, 40, 3]) + assert_equal(x.mask, [1, 0, 1]) + + def test_datafriendly_div(self): + # Test keeping data w/ (inplace) division + # Test div on scalar + x = array([1, 2, 3], mask=[0, 0, 1]) + xx = x / 2. + assert_equal(xx.data, [1 / 2., 2 / 2., 3]) + assert_equal(xx.mask, [0, 0, 1]) + # Test idiv on scalar + x = array([1., 2., 3.], mask=[0, 0, 1]) + x /= 2. + assert_equal(x.data, [1 / 2., 2 / 2., 3]) + assert_equal(x.mask, [0, 0, 1]) + # Test div on array + x = array([1., 2., 3.], mask=[0, 0, 1]) + xx = x / array([10., 20., 30.], mask=[1, 0, 0]) + assert_equal(xx.data, [1., 2. / 20., 3.]) + assert_equal(xx.mask, [1, 0, 1]) + # Test idiv on array + x = array([1., 2., 3.], mask=[0, 0, 1]) + x /= array([10., 20., 30.], mask=[1, 0, 0]) + assert_equal(x.data, [1., 2 / 20., 3.]) + assert_equal(x.mask, [1, 0, 1]) + + def test_datafriendly_pow(self): + # Test keeping data w/ (inplace) power + # Test pow on scalar + x = array([1., 2., 3.], mask=[0, 0, 1]) + xx = x ** 2.5 + assert_equal(xx.data, [1., 2. ** 2.5, 3.]) + assert_equal(xx.mask, [0, 0, 1]) + # Test ipow on scalar + x **= 2.5 + assert_equal(x.data, [1., 2. ** 2.5, 3]) + assert_equal(x.mask, [0, 0, 1]) + + def test_datafriendly_add_arrays(self): + a = array([[1, 1], [3, 3]]) + b = array([1, 1], mask=[0, 0]) + a += b + assert_equal(a, [[2, 2], [4, 4]]) + if a.mask is not nomask: + assert_equal(a.mask, [[0, 0], [0, 0]]) + + a = array([[1, 1], [3, 3]]) + b = array([1, 1], mask=[0, 1]) + a += b + assert_equal(a, [[2, 2], [4, 4]]) + assert_equal(a.mask, [[0, 1], [0, 1]]) + + def test_datafriendly_sub_arrays(self): + a = array([[1, 1], [3, 3]]) + b = array([1, 1], mask=[0, 0]) + a -= b + assert_equal(a, [[0, 0], [2, 2]]) + if a.mask is not nomask: + assert_equal(a.mask, [[0, 0], [0, 0]]) + + a = array([[1, 1], [3, 3]]) + b = array([1, 1], mask=[0, 1]) + a -= b + assert_equal(a, [[0, 0], [2, 2]]) + assert_equal(a.mask, [[0, 1], [0, 1]]) + + def test_datafriendly_mul_arrays(self): + a = array([[1, 1], [3, 3]]) + b = array([1, 1], mask=[0, 0]) + a *= b + assert_equal(a, [[1, 1], [3, 3]]) + if a.mask is not nomask: + assert_equal(a.mask, [[0, 0], [0, 0]]) + + a = array([[1, 1], [3, 3]]) + b = array([1, 1], mask=[0, 1]) + a *= b + assert_equal(a, [[1, 1], [3, 3]]) + assert_equal(a.mask, [[0, 1], [0, 1]]) + + def test_inplace_addition_scalar_type(self): + # Test of inplace additions + for t in self.othertypes: + with warnings.catch_warnings(record=True) as w: + warnings.filterwarnings("always") + (x, y, xm) = (_.astype(t) for _ in self.uint8data) + xm[2] = masked + x += t(1) + assert_equal(x, y + t(1)) + xm += t(1) + assert_equal(xm, y + t(1)) + + assert_equal(len(w), 0, f'Failed on type={t}.') + + def test_inplace_addition_array_type(self): + # Test of inplace additions + for t in self.othertypes: + with warnings.catch_warnings(record=True) as w: + warnings.filterwarnings("always") + (x, y, xm) = (_.astype(t) for _ in self.uint8data) + m = xm.mask + a = arange(10, dtype=t) + a[-1] = masked + x += a + xm += a + assert_equal(x, y + a) + assert_equal(xm, y + a) + assert_equal(xm.mask, mask_or(m, a.mask)) + + assert_equal(len(w), 0, f'Failed on type={t}.') + + def test_inplace_subtraction_scalar_type(self): + # Test of inplace subtractions + for t in self.othertypes: + with warnings.catch_warnings(record=True) as w: + warnings.filterwarnings("always") + (x, y, xm) = (_.astype(t) for _ in self.uint8data) + x -= t(1) + assert_equal(x, y - t(1)) + xm -= t(1) + assert_equal(xm, y - t(1)) + + assert_equal(len(w), 0, f'Failed on type={t}.') + + def test_inplace_subtraction_array_type(self): + # Test of inplace subtractions + for t in self.othertypes: + with warnings.catch_warnings(record=True) as w: + warnings.filterwarnings("always") + (x, y, xm) = (_.astype(t) for _ in self.uint8data) + m = xm.mask + a = arange(10, dtype=t) + a[-1] = masked + x -= a + xm -= a + assert_equal(x, y - a) + assert_equal(xm, y - a) + assert_equal(xm.mask, mask_or(m, a.mask)) + + assert_equal(len(w), 0, f'Failed on type={t}.') + + def test_inplace_multiplication_scalar_type(self): + # Test of inplace multiplication + for t in self.othertypes: + with warnings.catch_warnings(record=True) as w: + warnings.filterwarnings("always") + (x, y, xm) = (_.astype(t) for _ in self.uint8data) + x *= t(2) + assert_equal(x, y * t(2)) + xm *= t(2) + assert_equal(xm, y * t(2)) + + assert_equal(len(w), 0, f'Failed on type={t}.') + + def test_inplace_multiplication_array_type(self): + # Test of inplace multiplication + for t in self.othertypes: + with warnings.catch_warnings(record=True) as w: + warnings.filterwarnings("always") + (x, y, xm) = (_.astype(t) for _ in self.uint8data) + m = xm.mask + a = arange(10, dtype=t) + a[-1] = masked + x *= a + xm *= a + assert_equal(x, y * a) + assert_equal(xm, y * a) + assert_equal(xm.mask, mask_or(m, a.mask)) + + assert_equal(len(w), 0, f'Failed on type={t}.') + + def test_inplace_floor_division_scalar_type(self): + # Test of inplace division + for t in self.othertypes: + with warnings.catch_warnings(record=True) as w: + warnings.filterwarnings("always") + (x, y, xm) = (_.astype(t) for _ in self.uint8data) + x = arange(10, dtype=t) * t(2) + xm = arange(10, dtype=t) * t(2) + xm[2] = masked + x //= t(2) + xm //= t(2) + assert_equal(x, y) + assert_equal(xm, y) + + assert_equal(len(w), 0, "Failed on type=%s." % t) + + def test_inplace_floor_division_array_type(self): + # Test of inplace division + for t in self.othertypes: + with warnings.catch_warnings(record=True) as w: + warnings.filterwarnings("always") + (x, y, xm) = (_.astype(t) for _ in self.uint8data) + m = xm.mask + a = arange(10, dtype=t) + a[-1] = masked + x //= a + xm //= a + assert_equal(x, y // a) + assert_equal(xm, y // a) + assert_equal( + xm.mask, + mask_or(mask_or(m, a.mask), (a == t(0))) + ) + + assert_equal(len(w), 0, f'Failed on type={t}.') + + def test_inplace_division_scalar_type(self): + # Test of inplace division + for t in self.othertypes: + with suppress_warnings() as sup: + sup.record(UserWarning) + + (x, y, xm) = (_.astype(t) for _ in self.uint8data) + x = arange(10, dtype=t) * t(2) + xm = arange(10, dtype=t) * t(2) + xm[2] = masked + + # May get a DeprecationWarning or a TypeError. + # + # This is a consequence of the fact that this is true divide + # and will require casting to float for calculation and + # casting back to the original type. This will only be raised + # with integers. Whether it is an error or warning is only + # dependent on how stringent the casting rules are. + # + # Will handle the same way. + try: + x /= t(2) + assert_equal(x, y) + except (DeprecationWarning, TypeError) as e: + warnings.warn(str(e), stacklevel=1) + try: + xm /= t(2) + assert_equal(xm, y) + except (DeprecationWarning, TypeError) as e: + warnings.warn(str(e), stacklevel=1) + + if issubclass(t, np.integer): + assert_equal(len(sup.log), 2, f'Failed on type={t}.') + else: + assert_equal(len(sup.log), 0, f'Failed on type={t}.') + + def test_inplace_division_array_type(self): + # Test of inplace division + for t in self.othertypes: + with suppress_warnings() as sup: + sup.record(UserWarning) + (x, y, xm) = (_.astype(t) for _ in self.uint8data) + m = xm.mask + a = arange(10, dtype=t) + a[-1] = masked + + # May get a DeprecationWarning or a TypeError. + # + # This is a consequence of the fact that this is true divide + # and will require casting to float for calculation and + # casting back to the original type. This will only be raised + # with integers. Whether it is an error or warning is only + # dependent on how stringent the casting rules are. + # + # Will handle the same way. + try: + x /= a + assert_equal(x, y / a) + except (DeprecationWarning, TypeError) as e: + warnings.warn(str(e), stacklevel=1) + try: + xm /= a + assert_equal(xm, y / a) + assert_equal( + xm.mask, + mask_or(mask_or(m, a.mask), (a == t(0))) + ) + except (DeprecationWarning, TypeError) as e: + warnings.warn(str(e), stacklevel=1) + + if issubclass(t, np.integer): + assert_equal(len(sup.log), 2, f'Failed on type={t}.') + else: + assert_equal(len(sup.log), 0, f'Failed on type={t}.') + + def test_inplace_pow_type(self): + # Test keeping data w/ (inplace) power + for t in self.othertypes: + with warnings.catch_warnings(record=True) as w: + warnings.filterwarnings("always") + # Test pow on scalar + x = array([1, 2, 3], mask=[0, 0, 1], dtype=t) + xx = x ** t(2) + xx_r = array([1, 2 ** 2, 3], mask=[0, 0, 1], dtype=t) + assert_equal(xx.data, xx_r.data) + assert_equal(xx.mask, xx_r.mask) + # Test ipow on scalar + x **= t(2) + assert_equal(x.data, xx_r.data) + assert_equal(x.mask, xx_r.mask) + + assert_equal(len(w), 0, f'Failed on type={t}.') + + +class TestMaskedArrayMethods: + # Test class for miscellaneous MaskedArrays methods. + def setup(self): + # Base data definition. + x = np.array([8.375, 7.545, 8.828, 8.5, 1.757, 5.928, + 8.43, 7.78, 9.865, 5.878, 8.979, 4.732, + 3.012, 6.022, 5.095, 3.116, 5.238, 3.957, + 6.04, 9.63, 7.712, 3.382, 4.489, 6.479, + 7.189, 9.645, 5.395, 4.961, 9.894, 2.893, + 7.357, 9.828, 6.272, 3.758, 6.693, 0.993]) + X = x.reshape(6, 6) + XX = x.reshape(3, 2, 2, 3) + + m = np.array([0, 1, 0, 1, 0, 0, + 1, 0, 1, 1, 0, 1, + 0, 0, 0, 1, 0, 1, + 0, 0, 0, 1, 1, 1, + 1, 0, 0, 1, 0, 0, + 0, 0, 1, 0, 1, 0]) + mx = array(data=x, mask=m) + mX = array(data=X, mask=m.reshape(X.shape)) + mXX = array(data=XX, mask=m.reshape(XX.shape)) + + m2 = np.array([1, 1, 0, 1, 0, 0, + 1, 1, 1, 1, 0, 1, + 0, 0, 1, 1, 0, 1, + 0, 0, 0, 1, 1, 1, + 1, 0, 0, 1, 1, 0, + 0, 0, 1, 0, 1, 1]) + m2x = array(data=x, mask=m2) + m2X = array(data=X, mask=m2.reshape(X.shape)) + m2XX = array(data=XX, mask=m2.reshape(XX.shape)) + self.d = (x, X, XX, m, mx, mX, mXX, m2x, m2X, m2XX) + + def test_generic_methods(self): + # Tests some MaskedArray methods. + a = array([1, 3, 2]) + assert_equal(a.any(), a._data.any()) + assert_equal(a.all(), a._data.all()) + assert_equal(a.argmax(), a._data.argmax()) + assert_equal(a.argmin(), a._data.argmin()) + assert_equal(a.choose(0, 1, 2, 3, 4), a._data.choose(0, 1, 2, 3, 4)) + assert_equal(a.compress([1, 0, 1]), a._data.compress([1, 0, 1])) + assert_equal(a.conj(), a._data.conj()) + assert_equal(a.conjugate(), a._data.conjugate()) + + m = array([[1, 2], [3, 4]]) + assert_equal(m.diagonal(), m._data.diagonal()) + assert_equal(a.sum(), a._data.sum()) + assert_equal(a.take([1, 2]), a._data.take([1, 2])) + assert_equal(m.transpose(), m._data.transpose()) + + def test_allclose(self): + # Tests allclose on arrays + a = np.random.rand(10) + b = a + np.random.rand(10) * 1e-8 + assert_(allclose(a, b)) + # Test allclose w/ infs + a[0] = np.inf + assert_(not allclose(a, b)) + b[0] = np.inf + assert_(allclose(a, b)) + # Test allclose w/ masked + a = masked_array(a) + a[-1] = masked + assert_(allclose(a, b, masked_equal=True)) + assert_(not allclose(a, b, masked_equal=False)) + # Test comparison w/ scalar + a *= 1e-8 + a[0] = 0 + assert_(allclose(a, 0, masked_equal=True)) + + # Test that the function works for MIN_INT integer typed arrays + a = masked_array([np.iinfo(np.int_).min], dtype=np.int_) + assert_(allclose(a, a)) + + def test_allclose_timedelta(self): + # Allclose currently works for timedelta64 as long as `atol` is + # an integer or also a timedelta64 + a = np.array([[1, 2, 3, 4]], dtype="m8[ns]") + assert allclose(a, a, atol=0) + assert allclose(a, a, atol=np.timedelta64(1, "ns")) + + def test_allany(self): + # Checks the any/all methods/functions. + x = np.array([[0.13, 0.26, 0.90], + [0.28, 0.33, 0.63], + [0.31, 0.87, 0.70]]) + m = np.array([[True, False, False], + [False, False, False], + [True, True, False]], dtype=np.bool_) + mx = masked_array(x, mask=m) + mxbig = (mx > 0.5) + mxsmall = (mx < 0.5) + + assert_(not mxbig.all()) + assert_(mxbig.any()) + assert_equal(mxbig.all(0), [False, False, True]) + assert_equal(mxbig.all(1), [False, False, True]) + assert_equal(mxbig.any(0), [False, False, True]) + assert_equal(mxbig.any(1), [True, True, True]) + + assert_(not mxsmall.all()) + assert_(mxsmall.any()) + assert_equal(mxsmall.all(0), [True, True, False]) + assert_equal(mxsmall.all(1), [False, False, False]) + assert_equal(mxsmall.any(0), [True, True, False]) + assert_equal(mxsmall.any(1), [True, True, False]) + + def test_allany_oddities(self): + # Some fun with all and any + store = empty((), dtype=bool) + full = array([1, 2, 3], mask=True) + + assert_(full.all() is masked) + full.all(out=store) + assert_(store) + assert_(store._mask, True) + assert_(store is not masked) + + store = empty((), dtype=bool) + assert_(full.any() is masked) + full.any(out=store) + assert_(not store) + assert_(store._mask, True) + assert_(store is not masked) + + def test_argmax_argmin(self): + # Tests argmin & argmax on MaskedArrays. + (x, X, XX, m, mx, mX, mXX, m2x, m2X, m2XX) = self.d + + assert_equal(mx.argmin(), 35) + assert_equal(mX.argmin(), 35) + assert_equal(m2x.argmin(), 4) + assert_equal(m2X.argmin(), 4) + assert_equal(mx.argmax(), 28) + assert_equal(mX.argmax(), 28) + assert_equal(m2x.argmax(), 31) + assert_equal(m2X.argmax(), 31) + + assert_equal(mX.argmin(0), [2, 2, 2, 5, 0, 5]) + assert_equal(m2X.argmin(0), [2, 2, 4, 5, 0, 4]) + assert_equal(mX.argmax(0), [0, 5, 0, 5, 4, 0]) + assert_equal(m2X.argmax(0), [5, 5, 0, 5, 1, 0]) + + assert_equal(mX.argmin(1), [4, 1, 0, 0, 5, 5, ]) + assert_equal(m2X.argmin(1), [4, 4, 0, 0, 5, 3]) + assert_equal(mX.argmax(1), [2, 4, 1, 1, 4, 1]) + assert_equal(m2X.argmax(1), [2, 4, 1, 1, 1, 1]) + + def test_clip(self): + # Tests clip on MaskedArrays. + x = np.array([8.375, 7.545, 8.828, 8.5, 1.757, 5.928, + 8.43, 7.78, 9.865, 5.878, 8.979, 4.732, + 3.012, 6.022, 5.095, 3.116, 5.238, 3.957, + 6.04, 9.63, 7.712, 3.382, 4.489, 6.479, + 7.189, 9.645, 5.395, 4.961, 9.894, 2.893, + 7.357, 9.828, 6.272, 3.758, 6.693, 0.993]) + m = np.array([0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, + 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, + 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0]) + mx = array(x, mask=m) + clipped = mx.clip(2, 8) + assert_equal(clipped.mask, mx.mask) + assert_equal(clipped._data, x.clip(2, 8)) + assert_equal(clipped._data, mx._data.clip(2, 8)) + + def test_clip_out(self): + # gh-14140 + a = np.arange(10) + m = np.ma.MaskedArray(a, mask=[0, 1] * 5) + m.clip(0, 5, out=m) + assert_equal(m.mask, [0, 1] * 5) + + def test_compress(self): + # test compress + a = masked_array([1., 2., 3., 4., 5.], fill_value=9999) + condition = (a > 1.5) & (a < 3.5) + assert_equal(a.compress(condition), [2., 3.]) + + a[[2, 3]] = masked + b = a.compress(condition) + assert_equal(b._data, [2., 3.]) + assert_equal(b._mask, [0, 1]) + assert_equal(b.fill_value, 9999) + assert_equal(b, a[condition]) + + condition = (a < 4.) + b = a.compress(condition) + assert_equal(b._data, [1., 2., 3.]) + assert_equal(b._mask, [0, 0, 1]) + assert_equal(b.fill_value, 9999) + assert_equal(b, a[condition]) + + a = masked_array([[10, 20, 30], [40, 50, 60]], + mask=[[0, 0, 1], [1, 0, 0]]) + b = a.compress(a.ravel() >= 22) + assert_equal(b._data, [30, 40, 50, 60]) + assert_equal(b._mask, [1, 1, 0, 0]) + + x = np.array([3, 1, 2]) + b = a.compress(x >= 2, axis=1) + assert_equal(b._data, [[10, 30], [40, 60]]) + assert_equal(b._mask, [[0, 1], [1, 0]]) + + def test_compressed(self): + # Tests compressed + a = array([1, 2, 3, 4], mask=[0, 0, 0, 0]) + b = a.compressed() + assert_equal(b, a) + a[0] = masked + b = a.compressed() + assert_equal(b, [2, 3, 4]) + + def test_empty(self): + # Tests empty/like + datatype = [('a', int), ('b', float), ('c', '|S8')] + a = masked_array([(1, 1.1, '1.1'), (2, 2.2, '2.2'), (3, 3.3, '3.3')], + dtype=datatype) + assert_equal(len(a.fill_value.item()), len(datatype)) + + b = empty_like(a) + assert_equal(b.shape, a.shape) + assert_equal(b.fill_value, a.fill_value) + + b = empty(len(a), dtype=datatype) + assert_equal(b.shape, a.shape) + assert_equal(b.fill_value, a.fill_value) + + # check empty_like mask handling + a = masked_array([1, 2, 3], mask=[False, True, False]) + b = empty_like(a) + assert_(not np.may_share_memory(a.mask, b.mask)) + b = a.view(masked_array) + assert_(np.may_share_memory(a.mask, b.mask)) + + @suppress_copy_mask_on_assignment + def test_put(self): + # Tests put. + d = arange(5) + n = [0, 0, 0, 1, 1] + m = make_mask(n) + x = array(d, mask=m) + assert_(x[3] is masked) + assert_(x[4] is masked) + x[[1, 4]] = [10, 40] + assert_(x[3] is masked) + assert_(x[4] is not masked) + assert_equal(x, [0, 10, 2, -1, 40]) + + x = masked_array(arange(10), mask=[1, 0, 0, 0, 0] * 2) + i = [0, 2, 4, 6] + x.put(i, [6, 4, 2, 0]) + assert_equal(x, asarray([6, 1, 4, 3, 2, 5, 0, 7, 8, 9, ])) + assert_equal(x.mask, [0, 0, 0, 0, 0, 1, 0, 0, 0, 0]) + x.put(i, masked_array([0, 2, 4, 6], [1, 0, 1, 0])) + assert_array_equal(x, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, ]) + assert_equal(x.mask, [1, 0, 0, 0, 1, 1, 0, 0, 0, 0]) + + x = masked_array(arange(10), mask=[1, 0, 0, 0, 0] * 2) + put(x, i, [6, 4, 2, 0]) + assert_equal(x, asarray([6, 1, 4, 3, 2, 5, 0, 7, 8, 9, ])) + assert_equal(x.mask, [0, 0, 0, 0, 0, 1, 0, 0, 0, 0]) + put(x, i, masked_array([0, 2, 4, 6], [1, 0, 1, 0])) + assert_array_equal(x, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, ]) + assert_equal(x.mask, [1, 0, 0, 0, 1, 1, 0, 0, 0, 0]) + + def test_put_nomask(self): + # GitHub issue 6425 + x = zeros(10) + z = array([3., -1.], mask=[False, True]) + + x.put([1, 2], z) + assert_(x[0] is not masked) + assert_equal(x[0], 0) + assert_(x[1] is not masked) + assert_equal(x[1], 3) + assert_(x[2] is masked) + assert_(x[3] is not masked) + assert_equal(x[3], 0) + + def test_put_hardmask(self): + # Tests put on hardmask + d = arange(5) + n = [0, 0, 0, 1, 1] + m = make_mask(n) + xh = array(d + 1, mask=m, hard_mask=True, copy=True) + xh.put([4, 2, 0, 1, 3], [1, 2, 3, 4, 5]) + assert_equal(xh._data, [3, 4, 2, 4, 5]) + + def test_putmask(self): + x = arange(6) + 1 + mx = array(x, mask=[0, 0, 0, 1, 1, 1]) + mask = [0, 0, 1, 0, 0, 1] + # w/o mask, w/o masked values + xx = x.copy() + putmask(xx, mask, 99) + assert_equal(xx, [1, 2, 99, 4, 5, 99]) + # w/ mask, w/o masked values + mxx = mx.copy() + putmask(mxx, mask, 99) + assert_equal(mxx._data, [1, 2, 99, 4, 5, 99]) + assert_equal(mxx._mask, [0, 0, 0, 1, 1, 0]) + # w/o mask, w/ masked values + values = array([10, 20, 30, 40, 50, 60], mask=[1, 1, 1, 0, 0, 0]) + xx = x.copy() + putmask(xx, mask, values) + assert_equal(xx._data, [1, 2, 30, 4, 5, 60]) + assert_equal(xx._mask, [0, 0, 1, 0, 0, 0]) + # w/ mask, w/ masked values + mxx = mx.copy() + putmask(mxx, mask, values) + assert_equal(mxx._data, [1, 2, 30, 4, 5, 60]) + assert_equal(mxx._mask, [0, 0, 1, 1, 1, 0]) + # w/ mask, w/ masked values + hardmask + mxx = mx.copy() + mxx.harden_mask() + putmask(mxx, mask, values) + assert_equal(mxx, [1, 2, 30, 4, 5, 60]) + + def test_ravel(self): + # Tests ravel + a = array([[1, 2, 3, 4, 5]], mask=[[0, 1, 0, 0, 0]]) + aravel = a.ravel() + assert_equal(aravel._mask.shape, aravel.shape) + a = array([0, 0], mask=[1, 1]) + aravel = a.ravel() + assert_equal(aravel._mask.shape, a.shape) + # Checks that small_mask is preserved + a = array([1, 2, 3, 4], mask=[0, 0, 0, 0], shrink=False) + assert_equal(a.ravel()._mask, [0, 0, 0, 0]) + # Test that the fill_value is preserved + a.fill_value = -99 + a.shape = (2, 2) + ar = a.ravel() + assert_equal(ar._mask, [0, 0, 0, 0]) + assert_equal(ar._data, [1, 2, 3, 4]) + assert_equal(ar.fill_value, -99) + # Test index ordering + assert_equal(a.ravel(order='C'), [1, 2, 3, 4]) + assert_equal(a.ravel(order='F'), [1, 3, 2, 4]) + + def test_reshape(self): + # Tests reshape + x = arange(4) + x[0] = masked + y = x.reshape(2, 2) + assert_equal(y.shape, (2, 2,)) + assert_equal(y._mask.shape, (2, 2,)) + assert_equal(x.shape, (4,)) + assert_equal(x._mask.shape, (4,)) + + def test_sort(self): + # Test sort + x = array([1, 4, 2, 3], mask=[0, 1, 0, 0], dtype=np.uint8) + + sortedx = sort(x) + assert_equal(sortedx._data, [1, 2, 3, 4]) + assert_equal(sortedx._mask, [0, 0, 0, 1]) + + sortedx = sort(x, endwith=False) + assert_equal(sortedx._data, [4, 1, 2, 3]) + assert_equal(sortedx._mask, [1, 0, 0, 0]) + + x.sort() + assert_equal(x._data, [1, 2, 3, 4]) + assert_equal(x._mask, [0, 0, 0, 1]) + + x = array([1, 4, 2, 3], mask=[0, 1, 0, 0], dtype=np.uint8) + x.sort(endwith=False) + assert_equal(x._data, [4, 1, 2, 3]) + assert_equal(x._mask, [1, 0, 0, 0]) + + x = [1, 4, 2, 3] + sortedx = sort(x) + assert_(not isinstance(sorted, MaskedArray)) + + x = array([0, 1, -1, -2, 2], mask=nomask, dtype=np.int8) + sortedx = sort(x, endwith=False) + assert_equal(sortedx._data, [-2, -1, 0, 1, 2]) + x = array([0, 1, -1, -2, 2], mask=[0, 1, 0, 0, 1], dtype=np.int8) + sortedx = sort(x, endwith=False) + assert_equal(sortedx._data, [1, 2, -2, -1, 0]) + assert_equal(sortedx._mask, [1, 1, 0, 0, 0]) + + def test_stable_sort(self): + x = array([1, 2, 3, 1, 2, 3], dtype=np.uint8) + expected = array([0, 3, 1, 4, 2, 5]) + computed = argsort(x, kind='stable') + assert_equal(computed, expected) + + def test_argsort_matches_sort(self): + x = array([1, 4, 2, 3], mask=[0, 1, 0, 0], dtype=np.uint8) + + for kwargs in [dict(), + dict(endwith=True), + dict(endwith=False), + dict(fill_value=2), + dict(fill_value=2, endwith=True), + dict(fill_value=2, endwith=False)]: + sortedx = sort(x, **kwargs) + argsortedx = x[argsort(x, **kwargs)] + assert_equal(sortedx._data, argsortedx._data) + assert_equal(sortedx._mask, argsortedx._mask) + + def test_sort_2d(self): + # Check sort of 2D array. + # 2D array w/o mask + a = masked_array([[8, 4, 1], [2, 0, 9]]) + a.sort(0) + assert_equal(a, [[2, 0, 1], [8, 4, 9]]) + a = masked_array([[8, 4, 1], [2, 0, 9]]) + a.sort(1) + assert_equal(a, [[1, 4, 8], [0, 2, 9]]) + # 2D array w/mask + a = masked_array([[8, 4, 1], [2, 0, 9]], mask=[[1, 0, 0], [0, 0, 1]]) + a.sort(0) + assert_equal(a, [[2, 0, 1], [8, 4, 9]]) + assert_equal(a._mask, [[0, 0, 0], [1, 0, 1]]) + a = masked_array([[8, 4, 1], [2, 0, 9]], mask=[[1, 0, 0], [0, 0, 1]]) + a.sort(1) + assert_equal(a, [[1, 4, 8], [0, 2, 9]]) + assert_equal(a._mask, [[0, 0, 1], [0, 0, 1]]) + # 3D + a = masked_array([[[7, 8, 9], [4, 5, 6], [1, 2, 3]], + [[1, 2, 3], [7, 8, 9], [4, 5, 6]], + [[7, 8, 9], [1, 2, 3], [4, 5, 6]], + [[4, 5, 6], [1, 2, 3], [7, 8, 9]]]) + a[a % 4 == 0] = masked + am = a.copy() + an = a.filled(99) + am.sort(0) + an.sort(0) + assert_equal(am, an) + am = a.copy() + an = a.filled(99) + am.sort(1) + an.sort(1) + assert_equal(am, an) + am = a.copy() + an = a.filled(99) + am.sort(2) + an.sort(2) + assert_equal(am, an) + + def test_sort_flexible(self): + # Test sort on structured dtype. + a = array( + data=[(3, 3), (3, 2), (2, 2), (2, 1), (1, 0), (1, 1), (1, 2)], + mask=[(0, 0), (0, 1), (0, 0), (0, 0), (1, 0), (0, 0), (0, 0)], + dtype=[('A', int), ('B', int)]) + mask_last = array( + data=[(1, 1), (1, 2), (2, 1), (2, 2), (3, 3), (3, 2), (1, 0)], + mask=[(0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 1), (1, 0)], + dtype=[('A', int), ('B', int)]) + mask_first = array( + data=[(1, 0), (1, 1), (1, 2), (2, 1), (2, 2), (3, 2), (3, 3)], + mask=[(1, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0, 1), (0, 0)], + dtype=[('A', int), ('B', int)]) + + test = sort(a) + assert_equal(test, mask_last) + assert_equal(test.mask, mask_last.mask) + + test = sort(a, endwith=False) + assert_equal(test, mask_first) + assert_equal(test.mask, mask_first.mask) + + # Test sort on dtype with subarray (gh-8069) + # Just check that the sort does not error, structured array subarrays + # are treated as byte strings and that leads to differing behavior + # depending on endianess and `endwith`. + dt = np.dtype([('v', int, 2)]) + a = a.view(dt) + test = sort(a) + test = sort(a, endwith=False) + + def test_argsort(self): + # Test argsort + a = array([1, 5, 2, 4, 3], mask=[1, 0, 0, 1, 0]) + assert_equal(np.argsort(a), argsort(a)) + + def test_squeeze(self): + # Check squeeze + data = masked_array([[1, 2, 3]]) + assert_equal(data.squeeze(), [1, 2, 3]) + data = masked_array([[1, 2, 3]], mask=[[1, 1, 1]]) + assert_equal(data.squeeze(), [1, 2, 3]) + assert_equal(data.squeeze()._mask, [1, 1, 1]) + + # normal ndarrays return a view + arr = np.array([[1]]) + arr_sq = arr.squeeze() + assert_equal(arr_sq, 1) + arr_sq[...] = 2 + assert_equal(arr[0,0], 2) + + # so maskedarrays should too + m_arr = masked_array([[1]], mask=True) + m_arr_sq = m_arr.squeeze() + assert_(m_arr_sq is not np.ma.masked) + assert_equal(m_arr_sq.mask, True) + m_arr_sq[...] = 2 + assert_equal(m_arr[0,0], 2) + + def test_swapaxes(self): + # Tests swapaxes on MaskedArrays. + x = np.array([8.375, 7.545, 8.828, 8.5, 1.757, 5.928, + 8.43, 7.78, 9.865, 5.878, 8.979, 4.732, + 3.012, 6.022, 5.095, 3.116, 5.238, 3.957, + 6.04, 9.63, 7.712, 3.382, 4.489, 6.479, + 7.189, 9.645, 5.395, 4.961, 9.894, 2.893, + 7.357, 9.828, 6.272, 3.758, 6.693, 0.993]) + m = np.array([0, 1, 0, 1, 0, 0, + 1, 0, 1, 1, 0, 1, + 0, 0, 0, 1, 0, 1, + 0, 0, 0, 1, 1, 1, + 1, 0, 0, 1, 0, 0, + 0, 0, 1, 0, 1, 0]) + mX = array(x, mask=m).reshape(6, 6) + mXX = mX.reshape(3, 2, 2, 3) + + mXswapped = mX.swapaxes(0, 1) + assert_equal(mXswapped[-1], mX[:, -1]) + + mXXswapped = mXX.swapaxes(0, 2) + assert_equal(mXXswapped.shape, (2, 2, 3, 3)) + + def test_take(self): + # Tests take + x = masked_array([10, 20, 30, 40], [0, 1, 0, 1]) + assert_equal(x.take([0, 0, 3]), masked_array([10, 10, 40], [0, 0, 1])) + assert_equal(x.take([0, 0, 3]), x[[0, 0, 3]]) + assert_equal(x.take([[0, 1], [0, 1]]), + masked_array([[10, 20], [10, 20]], [[0, 1], [0, 1]])) + + # assert_equal crashes when passed np.ma.mask + assert_(x[1] is np.ma.masked) + assert_(x.take(1) is np.ma.masked) + + x = array([[10, 20, 30], [40, 50, 60]], mask=[[0, 0, 1], [1, 0, 0, ]]) + assert_equal(x.take([0, 2], axis=1), + array([[10, 30], [40, 60]], mask=[[0, 1], [1, 0]])) + assert_equal(take(x, [0, 2], axis=1), + array([[10, 30], [40, 60]], mask=[[0, 1], [1, 0]])) + + def test_take_masked_indices(self): + # Test take w/ masked indices + a = np.array((40, 18, 37, 9, 22)) + indices = np.arange(3)[None,:] + np.arange(5)[:, None] + mindices = array(indices, mask=(indices >= len(a))) + # No mask + test = take(a, mindices, mode='clip') + ctrl = array([[40, 18, 37], + [18, 37, 9], + [37, 9, 22], + [9, 22, 22], + [22, 22, 22]]) + assert_equal(test, ctrl) + # Masked indices + test = take(a, mindices) + ctrl = array([[40, 18, 37], + [18, 37, 9], + [37, 9, 22], + [9, 22, 40], + [22, 40, 40]]) + ctrl[3, 2] = ctrl[4, 1] = ctrl[4, 2] = masked + assert_equal(test, ctrl) + assert_equal(test.mask, ctrl.mask) + # Masked input + masked indices + a = array((40, 18, 37, 9, 22), mask=(0, 1, 0, 0, 0)) + test = take(a, mindices) + ctrl[0, 1] = ctrl[1, 0] = masked + assert_equal(test, ctrl) + assert_equal(test.mask, ctrl.mask) + + def test_tolist(self): + # Tests to list + # ... on 1D + x = array(np.arange(12)) + x[[1, -2]] = masked + xlist = x.tolist() + assert_(xlist[1] is None) + assert_(xlist[-2] is None) + # ... on 2D + x.shape = (3, 4) + xlist = x.tolist() + ctrl = [[0, None, 2, 3], [4, 5, 6, 7], [8, 9, None, 11]] + assert_equal(xlist[0], [0, None, 2, 3]) + assert_equal(xlist[1], [4, 5, 6, 7]) + assert_equal(xlist[2], [8, 9, None, 11]) + assert_equal(xlist, ctrl) + # ... on structured array w/ masked records + x = array(list(zip([1, 2, 3], + [1.1, 2.2, 3.3], + ['one', 'two', 'thr'])), + dtype=[('a', int), ('b', float), ('c', '|S8')]) + x[-1] = masked + assert_equal(x.tolist(), + [(1, 1.1, b'one'), + (2, 2.2, b'two'), + (None, None, None)]) + # ... on structured array w/ masked fields + a = array([(1, 2,), (3, 4)], mask=[(0, 1), (0, 0)], + dtype=[('a', int), ('b', int)]) + test = a.tolist() + assert_equal(test, [[1, None], [3, 4]]) + # ... on mvoid + a = a[0] + test = a.tolist() + assert_equal(test, [1, None]) + + def test_tolist_specialcase(self): + # Test mvoid.tolist: make sure we return a standard Python object + a = array([(0, 1), (2, 3)], dtype=[('a', int), ('b', int)]) + # w/o mask: each entry is a np.void whose elements are standard Python + for entry in a: + for item in entry.tolist(): + assert_(not isinstance(item, np.generic)) + # w/ mask: each entry is a ma.void whose elements should be + # standard Python + a.mask[0] = (0, 1) + for entry in a: + for item in entry.tolist(): + assert_(not isinstance(item, np.generic)) + + def test_toflex(self): + # Test the conversion to records + data = arange(10) + record = data.toflex() + assert_equal(record['_data'], data._data) + assert_equal(record['_mask'], data._mask) + + data[[0, 1, 2, -1]] = masked + record = data.toflex() + assert_equal(record['_data'], data._data) + assert_equal(record['_mask'], data._mask) + + ndtype = [('i', int), ('s', '|S3'), ('f', float)] + data = array([(i, s, f) for (i, s, f) in zip(np.arange(10), + 'ABCDEFGHIJKLM', + np.random.rand(10))], + dtype=ndtype) + data[[0, 1, 2, -1]] = masked + record = data.toflex() + assert_equal(record['_data'], data._data) + assert_equal(record['_mask'], data._mask) + + ndtype = np.dtype("int, (2,3)float, float") + data = array([(i, f, ff) for (i, f, ff) in zip(np.arange(10), + np.random.rand(10), + np.random.rand(10))], + dtype=ndtype) + data[[0, 1, 2, -1]] = masked + record = data.toflex() + assert_equal_records(record['_data'], data._data) + assert_equal_records(record['_mask'], data._mask) + + def test_fromflex(self): + # Test the reconstruction of a masked_array from a record + a = array([1, 2, 3]) + test = fromflex(a.toflex()) + assert_equal(test, a) + assert_equal(test.mask, a.mask) + + a = array([1, 2, 3], mask=[0, 0, 1]) + test = fromflex(a.toflex()) + assert_equal(test, a) + assert_equal(test.mask, a.mask) + + a = array([(1, 1.), (2, 2.), (3, 3.)], mask=[(1, 0), (0, 0), (0, 1)], + dtype=[('A', int), ('B', float)]) + test = fromflex(a.toflex()) + assert_equal(test, a) + assert_equal(test.data, a.data) + + def test_arraymethod(self): + # Test a _arraymethod w/ n argument + marray = masked_array([[1, 2, 3, 4, 5]], mask=[0, 0, 1, 0, 0]) + control = masked_array([[1], [2], [3], [4], [5]], + mask=[0, 0, 1, 0, 0]) + assert_equal(marray.T, control) + assert_equal(marray.transpose(), control) + + assert_equal(MaskedArray.cumsum(marray.T, 0), control.cumsum(0)) + + def test_arraymethod_0d(self): + # gh-9430 + x = np.ma.array(42, mask=True) + assert_equal(x.T.mask, x.mask) + assert_equal(x.T.data, x.data) + + def test_transpose_view(self): + x = np.ma.array([[1, 2, 3], [4, 5, 6]]) + x[0,1] = np.ma.masked + xt = x.T + + xt[1,0] = 10 + xt[0,1] = np.ma.masked + + assert_equal(x.data, xt.T.data) + assert_equal(x.mask, xt.T.mask) + + def test_diagonal_view(self): + x = np.ma.zeros((3,3)) + x[0,0] = 10 + x[1,1] = np.ma.masked + x[2,2] = 20 + xd = x.diagonal() + x[1,1] = 15 + assert_equal(xd.mask, x.diagonal().mask) + assert_equal(xd.data, x.diagonal().data) + + +class TestMaskedArrayMathMethods: + + def setup(self): + # Base data definition. + x = np.array([8.375, 7.545, 8.828, 8.5, 1.757, 5.928, + 8.43, 7.78, 9.865, 5.878, 8.979, 4.732, + 3.012, 6.022, 5.095, 3.116, 5.238, 3.957, + 6.04, 9.63, 7.712, 3.382, 4.489, 6.479, + 7.189, 9.645, 5.395, 4.961, 9.894, 2.893, + 7.357, 9.828, 6.272, 3.758, 6.693, 0.993]) + X = x.reshape(6, 6) + XX = x.reshape(3, 2, 2, 3) + + m = np.array([0, 1, 0, 1, 0, 0, + 1, 0, 1, 1, 0, 1, + 0, 0, 0, 1, 0, 1, + 0, 0, 0, 1, 1, 1, + 1, 0, 0, 1, 0, 0, + 0, 0, 1, 0, 1, 0]) + mx = array(data=x, mask=m) + mX = array(data=X, mask=m.reshape(X.shape)) + mXX = array(data=XX, mask=m.reshape(XX.shape)) + + m2 = np.array([1, 1, 0, 1, 0, 0, + 1, 1, 1, 1, 0, 1, + 0, 0, 1, 1, 0, 1, + 0, 0, 0, 1, 1, 1, + 1, 0, 0, 1, 1, 0, + 0, 0, 1, 0, 1, 1]) + m2x = array(data=x, mask=m2) + m2X = array(data=X, mask=m2.reshape(X.shape)) + m2XX = array(data=XX, mask=m2.reshape(XX.shape)) + self.d = (x, X, XX, m, mx, mX, mXX, m2x, m2X, m2XX) + + def test_cumsumprod(self): + # Tests cumsum & cumprod on MaskedArrays. + (x, X, XX, m, mx, mX, mXX, m2x, m2X, m2XX) = self.d + mXcp = mX.cumsum(0) + assert_equal(mXcp._data, mX.filled(0).cumsum(0)) + mXcp = mX.cumsum(1) + assert_equal(mXcp._data, mX.filled(0).cumsum(1)) + + mXcp = mX.cumprod(0) + assert_equal(mXcp._data, mX.filled(1).cumprod(0)) + mXcp = mX.cumprod(1) + assert_equal(mXcp._data, mX.filled(1).cumprod(1)) + + def test_cumsumprod_with_output(self): + # Tests cumsum/cumprod w/ output + xm = array(np.random.uniform(0, 10, 12)).reshape(3, 4) + xm[:, 0] = xm[0] = xm[-1, -1] = masked + + for funcname in ('cumsum', 'cumprod'): + npfunc = getattr(np, funcname) + xmmeth = getattr(xm, funcname) + + # A ndarray as explicit input + output = np.empty((3, 4), dtype=float) + output.fill(-9999) + result = npfunc(xm, axis=0, out=output) + # ... the result should be the given output + assert_(result is output) + assert_equal(result, xmmeth(axis=0, out=output)) + + output = empty((3, 4), dtype=int) + result = xmmeth(axis=0, out=output) + assert_(result is output) + + def test_ptp(self): + # Tests ptp on MaskedArrays. + (x, X, XX, m, mx, mX, mXX, m2x, m2X, m2XX) = self.d + (n, m) = X.shape + assert_equal(mx.ptp(), mx.compressed().ptp()) + rows = np.zeros(n, float) + cols = np.zeros(m, float) + for k in range(m): + cols[k] = mX[:, k].compressed().ptp() + for k in range(n): + rows[k] = mX[k].compressed().ptp() + assert_equal(mX.ptp(0), cols) + assert_equal(mX.ptp(1), rows) + + def test_add_object(self): + x = masked_array(['a', 'b'], mask=[1, 0], dtype=object) + y = x + 'x' + assert_equal(y[1], 'bx') + assert_(y.mask[0]) + + def test_sum_object(self): + # Test sum on object dtype + a = masked_array([1, 2, 3], mask=[1, 0, 0], dtype=object) + assert_equal(a.sum(), 5) + a = masked_array([[1, 2, 3], [4, 5, 6]], dtype=object) + assert_equal(a.sum(axis=0), [5, 7, 9]) + + def test_prod_object(self): + # Test prod on object dtype + a = masked_array([1, 2, 3], mask=[1, 0, 0], dtype=object) + assert_equal(a.prod(), 2 * 3) + a = masked_array([[1, 2, 3], [4, 5, 6]], dtype=object) + assert_equal(a.prod(axis=0), [4, 10, 18]) + + def test_meananom_object(self): + # Test mean/anom on object dtype + a = masked_array([1, 2, 3], dtype=object) + assert_equal(a.mean(), 2) + assert_equal(a.anom(), [-1, 0, 1]) + + def test_trace(self): + # Tests trace on MaskedArrays. + (x, X, XX, m, mx, mX, mXX, m2x, m2X, m2XX) = self.d + mXdiag = mX.diagonal() + assert_equal(mX.trace(), mX.diagonal().compressed().sum()) + assert_almost_equal(mX.trace(), + X.trace() - sum(mXdiag.mask * X.diagonal(), + axis=0)) + assert_equal(np.trace(mX), mX.trace()) + + # gh-5560 + arr = np.arange(2*4*4).reshape(2,4,4) + m_arr = np.ma.masked_array(arr, False) + assert_equal(arr.trace(axis1=1, axis2=2), m_arr.trace(axis1=1, axis2=2)) + + def test_dot(self): + # Tests dot on MaskedArrays. + (x, X, XX, m, mx, mX, mXX, m2x, m2X, m2XX) = self.d + fx = mx.filled(0) + r = mx.dot(mx) + assert_almost_equal(r.filled(0), fx.dot(fx)) + assert_(r.mask is nomask) + + fX = mX.filled(0) + r = mX.dot(mX) + assert_almost_equal(r.filled(0), fX.dot(fX)) + assert_(r.mask[1,3]) + r1 = empty_like(r) + mX.dot(mX, out=r1) + assert_almost_equal(r, r1) + + mYY = mXX.swapaxes(-1, -2) + fXX, fYY = mXX.filled(0), mYY.filled(0) + r = mXX.dot(mYY) + assert_almost_equal(r.filled(0), fXX.dot(fYY)) + r1 = empty_like(r) + mXX.dot(mYY, out=r1) + assert_almost_equal(r, r1) + + def test_dot_shape_mismatch(self): + # regression test + x = masked_array([[1,2],[3,4]], mask=[[0,1],[0,0]]) + y = masked_array([[1,2],[3,4]], mask=[[0,1],[0,0]]) + z = masked_array([[0,1],[3,3]]) + x.dot(y, out=z) + assert_almost_equal(z.filled(0), [[1, 0], [15, 16]]) + assert_almost_equal(z.mask, [[0, 1], [0, 0]]) + + def test_varmean_nomask(self): + # gh-5769 + foo = array([1,2,3,4], dtype='f8') + bar = array([1,2,3,4], dtype='f8') + assert_equal(type(foo.mean()), np.float64) + assert_equal(type(foo.var()), np.float64) + assert((foo.mean() == bar.mean()) is np.bool_(True)) + + # check array type is preserved and out works + foo = array(np.arange(16).reshape((4,4)), dtype='f8') + bar = empty(4, dtype='f4') + assert_equal(type(foo.mean(axis=1)), MaskedArray) + assert_equal(type(foo.var(axis=1)), MaskedArray) + assert_(foo.mean(axis=1, out=bar) is bar) + assert_(foo.var(axis=1, out=bar) is bar) + + def test_varstd(self): + # Tests var & std on MaskedArrays. + (x, X, XX, m, mx, mX, mXX, m2x, m2X, m2XX) = self.d + assert_almost_equal(mX.var(axis=None), mX.compressed().var()) + assert_almost_equal(mX.std(axis=None), mX.compressed().std()) + assert_almost_equal(mX.std(axis=None, ddof=1), + mX.compressed().std(ddof=1)) + assert_almost_equal(mX.var(axis=None, ddof=1), + mX.compressed().var(ddof=1)) + assert_equal(mXX.var(axis=3).shape, XX.var(axis=3).shape) + assert_equal(mX.var().shape, X.var().shape) + (mXvar0, mXvar1) = (mX.var(axis=0), mX.var(axis=1)) + assert_almost_equal(mX.var(axis=None, ddof=2), + mX.compressed().var(ddof=2)) + assert_almost_equal(mX.std(axis=None, ddof=2), + mX.compressed().std(ddof=2)) + for k in range(6): + assert_almost_equal(mXvar1[k], mX[k].compressed().var()) + assert_almost_equal(mXvar0[k], mX[:, k].compressed().var()) + assert_almost_equal(np.sqrt(mXvar0[k]), + mX[:, k].compressed().std()) + + @suppress_copy_mask_on_assignment + def test_varstd_specialcases(self): + # Test a special case for var + nout = np.array(-1, dtype=float) + mout = array(-1, dtype=float) + + x = array(arange(10), mask=True) + for methodname in ('var', 'std'): + method = getattr(x, methodname) + assert_(method() is masked) + assert_(method(0) is masked) + assert_(method(-1) is masked) + # Using a masked array as explicit output + method(out=mout) + assert_(mout is not masked) + assert_equal(mout.mask, True) + # Using a ndarray as explicit output + method(out=nout) + assert_(np.isnan(nout)) + + x = array(arange(10), mask=True) + x[-1] = 9 + for methodname in ('var', 'std'): + method = getattr(x, methodname) + assert_(method(ddof=1) is masked) + assert_(method(0, ddof=1) is masked) + assert_(method(-1, ddof=1) is masked) + # Using a masked array as explicit output + method(out=mout, ddof=1) + assert_(mout is not masked) + assert_equal(mout.mask, True) + # Using a ndarray as explicit output + method(out=nout, ddof=1) + assert_(np.isnan(nout)) + + def test_varstd_ddof(self): + a = array([[1, 1, 0], [1, 1, 0]], mask=[[0, 0, 1], [0, 0, 1]]) + test = a.std(axis=0, ddof=0) + assert_equal(test.filled(0), [0, 0, 0]) + assert_equal(test.mask, [0, 0, 1]) + test = a.std(axis=0, ddof=1) + assert_equal(test.filled(0), [0, 0, 0]) + assert_equal(test.mask, [0, 0, 1]) + test = a.std(axis=0, ddof=2) + assert_equal(test.filled(0), [0, 0, 0]) + assert_equal(test.mask, [1, 1, 1]) + + def test_diag(self): + # Test diag + x = arange(9).reshape((3, 3)) + x[1, 1] = masked + out = np.diag(x) + assert_equal(out, [0, 4, 8]) + out = diag(x) + assert_equal(out, [0, 4, 8]) + assert_equal(out.mask, [0, 1, 0]) + out = diag(out) + control = array([[0, 0, 0], [0, 4, 0], [0, 0, 8]], + mask=[[0, 0, 0], [0, 1, 0], [0, 0, 0]]) + assert_equal(out, control) + + def test_axis_methods_nomask(self): + # Test the combination nomask & methods w/ axis + a = array([[1, 2, 3], [4, 5, 6]]) + + assert_equal(a.sum(0), [5, 7, 9]) + assert_equal(a.sum(-1), [6, 15]) + assert_equal(a.sum(1), [6, 15]) + + assert_equal(a.prod(0), [4, 10, 18]) + assert_equal(a.prod(-1), [6, 120]) + assert_equal(a.prod(1), [6, 120]) + + assert_equal(a.min(0), [1, 2, 3]) + assert_equal(a.min(-1), [1, 4]) + assert_equal(a.min(1), [1, 4]) + + assert_equal(a.max(0), [4, 5, 6]) + assert_equal(a.max(-1), [3, 6]) + assert_equal(a.max(1), [3, 6]) + + +class TestMaskedArrayMathMethodsComplex: + # Test class for miscellaneous MaskedArrays methods. + def setup(self): + # Base data definition. + x = np.array([8.375j, 7.545j, 8.828j, 8.5j, 1.757j, 5.928, + 8.43, 7.78, 9.865, 5.878, 8.979, 4.732, + 3.012, 6.022, 5.095, 3.116, 5.238, 3.957, + 6.04, 9.63, 7.712, 3.382, 4.489, 6.479j, + 7.189j, 9.645, 5.395, 4.961, 9.894, 2.893, + 7.357, 9.828, 6.272, 3.758, 6.693, 0.993j]) + X = x.reshape(6, 6) + XX = x.reshape(3, 2, 2, 3) + + m = np.array([0, 1, 0, 1, 0, 0, + 1, 0, 1, 1, 0, 1, + 0, 0, 0, 1, 0, 1, + 0, 0, 0, 1, 1, 1, + 1, 0, 0, 1, 0, 0, + 0, 0, 1, 0, 1, 0]) + mx = array(data=x, mask=m) + mX = array(data=X, mask=m.reshape(X.shape)) + mXX = array(data=XX, mask=m.reshape(XX.shape)) + + m2 = np.array([1, 1, 0, 1, 0, 0, + 1, 1, 1, 1, 0, 1, + 0, 0, 1, 1, 0, 1, + 0, 0, 0, 1, 1, 1, + 1, 0, 0, 1, 1, 0, + 0, 0, 1, 0, 1, 1]) + m2x = array(data=x, mask=m2) + m2X = array(data=X, mask=m2.reshape(X.shape)) + m2XX = array(data=XX, mask=m2.reshape(XX.shape)) + self.d = (x, X, XX, m, mx, mX, mXX, m2x, m2X, m2XX) + + def test_varstd(self): + # Tests var & std on MaskedArrays. + (x, X, XX, m, mx, mX, mXX, m2x, m2X, m2XX) = self.d + assert_almost_equal(mX.var(axis=None), mX.compressed().var()) + assert_almost_equal(mX.std(axis=None), mX.compressed().std()) + assert_equal(mXX.var(axis=3).shape, XX.var(axis=3).shape) + assert_equal(mX.var().shape, X.var().shape) + (mXvar0, mXvar1) = (mX.var(axis=0), mX.var(axis=1)) + assert_almost_equal(mX.var(axis=None, ddof=2), + mX.compressed().var(ddof=2)) + assert_almost_equal(mX.std(axis=None, ddof=2), + mX.compressed().std(ddof=2)) + for k in range(6): + assert_almost_equal(mXvar1[k], mX[k].compressed().var()) + assert_almost_equal(mXvar0[k], mX[:, k].compressed().var()) + assert_almost_equal(np.sqrt(mXvar0[k]), + mX[:, k].compressed().std()) + + +class TestMaskedArrayFunctions: + # Test class for miscellaneous functions. + + def setup(self): + x = np.array([1., 1., 1., -2., pi/2.0, 4., 5., -10., 10., 1., 2., 3.]) + y = np.array([5., 0., 3., 2., -1., -4., 0., -10., 10., 1., 0., 3.]) + m1 = [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0] + m2 = [0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1] + xm = masked_array(x, mask=m1) + ym = masked_array(y, mask=m2) + xm.set_fill_value(1e+20) + self.info = (xm, ym) + + def test_masked_where_bool(self): + x = [1, 2] + y = masked_where(False, x) + assert_equal(y, [1, 2]) + assert_equal(y[1], 2) + + def test_masked_equal_wlist(self): + x = [1, 2, 3] + mx = masked_equal(x, 3) + assert_equal(mx, x) + assert_equal(mx._mask, [0, 0, 1]) + mx = masked_not_equal(x, 3) + assert_equal(mx, x) + assert_equal(mx._mask, [1, 1, 0]) + + def test_masked_equal_fill_value(self): + x = [1, 2, 3] + mx = masked_equal(x, 3) + assert_equal(mx._mask, [0, 0, 1]) + assert_equal(mx.fill_value, 3) + + def test_masked_where_condition(self): + # Tests masking functions. + x = array([1., 2., 3., 4., 5.]) + x[2] = masked + assert_equal(masked_where(greater(x, 2), x), masked_greater(x, 2)) + assert_equal(masked_where(greater_equal(x, 2), x), + masked_greater_equal(x, 2)) + assert_equal(masked_where(less(x, 2), x), masked_less(x, 2)) + assert_equal(masked_where(less_equal(x, 2), x), + masked_less_equal(x, 2)) + assert_equal(masked_where(not_equal(x, 2), x), masked_not_equal(x, 2)) + assert_equal(masked_where(equal(x, 2), x), masked_equal(x, 2)) + assert_equal(masked_where(not_equal(x, 2), x), masked_not_equal(x, 2)) + assert_equal(masked_where([1, 1, 0, 0, 0], [1, 2, 3, 4, 5]), + [99, 99, 3, 4, 5]) + + def test_masked_where_oddities(self): + # Tests some generic features. + atest = ones((10, 10, 10), dtype=float) + btest = zeros(atest.shape, MaskType) + ctest = masked_where(btest, atest) + assert_equal(atest, ctest) + + def test_masked_where_shape_constraint(self): + a = arange(10) + with assert_raises(IndexError): + masked_equal(1, a) + test = masked_equal(a, 1) + assert_equal(test.mask, [0, 1, 0, 0, 0, 0, 0, 0, 0, 0]) + + def test_masked_where_structured(self): + # test that masked_where on a structured array sets a structured + # mask (see issue #2972) + a = np.zeros(10, dtype=[("A", " 6, x) + + def test_masked_otherfunctions(self): + assert_equal(masked_inside(list(range(5)), 1, 3), + [0, 199, 199, 199, 4]) + assert_equal(masked_outside(list(range(5)), 1, 3), [199, 1, 2, 3, 199]) + assert_equal(masked_inside(array(list(range(5)), + mask=[1, 0, 0, 0, 0]), 1, 3).mask, + [1, 1, 1, 1, 0]) + assert_equal(masked_outside(array(list(range(5)), + mask=[0, 1, 0, 0, 0]), 1, 3).mask, + [1, 1, 0, 0, 1]) + assert_equal(masked_equal(array(list(range(5)), + mask=[1, 0, 0, 0, 0]), 2).mask, + [1, 0, 1, 0, 0]) + assert_equal(masked_not_equal(array([2, 2, 1, 2, 1], + mask=[1, 0, 0, 0, 0]), 2).mask, + [1, 0, 1, 0, 1]) + + def test_round(self): + a = array([1.23456, 2.34567, 3.45678, 4.56789, 5.67890], + mask=[0, 1, 0, 0, 0]) + assert_equal(a.round(), [1., 2., 3., 5., 6.]) + assert_equal(a.round(1), [1.2, 2.3, 3.5, 4.6, 5.7]) + assert_equal(a.round(3), [1.235, 2.346, 3.457, 4.568, 5.679]) + b = empty_like(a) + a.round(out=b) + assert_equal(b, [1., 2., 3., 5., 6.]) + + x = array([1., 2., 3., 4., 5.]) + c = array([1, 1, 1, 0, 0]) + x[2] = masked + z = where(c, x, -x) + assert_equal(z, [1., 2., 0., -4., -5]) + c[0] = masked + z = where(c, x, -x) + assert_equal(z, [1., 2., 0., -4., -5]) + assert_(z[0] is masked) + assert_(z[1] is not masked) + assert_(z[2] is masked) + + def test_round_with_output(self): + # Testing round with an explicit output + + xm = array(np.random.uniform(0, 10, 12)).reshape(3, 4) + xm[:, 0] = xm[0] = xm[-1, -1] = masked + + # A ndarray as explicit input + output = np.empty((3, 4), dtype=float) + output.fill(-9999) + result = np.round(xm, decimals=2, out=output) + # ... the result should be the given output + assert_(result is output) + assert_equal(result, xm.round(decimals=2, out=output)) + + output = empty((3, 4), dtype=float) + result = xm.round(decimals=2, out=output) + assert_(result is output) + + def test_round_with_scalar(self): + # Testing round with scalar/zero dimension input + # GH issue 2244 + a = array(1.1, mask=[False]) + assert_equal(a.round(), 1) + + a = array(1.1, mask=[True]) + assert_(a.round() is masked) + + a = array(1.1, mask=[False]) + output = np.empty(1, dtype=float) + output.fill(-9999) + a.round(out=output) + assert_equal(output, 1) + + a = array(1.1, mask=[False]) + output = array(-9999., mask=[True]) + a.round(out=output) + assert_equal(output[()], 1) + + a = array(1.1, mask=[True]) + output = array(-9999., mask=[False]) + a.round(out=output) + assert_(output[()] is masked) + + def test_identity(self): + a = identity(5) + assert_(isinstance(a, MaskedArray)) + assert_equal(a, np.identity(5)) + + def test_power(self): + x = -1.1 + assert_almost_equal(power(x, 2.), 1.21) + assert_(power(x, masked) is masked) + x = array([-1.1, -1.1, 1.1, 1.1, 0.]) + b = array([0.5, 2., 0.5, 2., -1.], mask=[0, 0, 0, 0, 1]) + y = power(x, b) + assert_almost_equal(y, [0, 1.21, 1.04880884817, 1.21, 0.]) + assert_equal(y._mask, [1, 0, 0, 0, 1]) + b.mask = nomask + y = power(x, b) + assert_equal(y._mask, [1, 0, 0, 0, 1]) + z = x ** b + assert_equal(z._mask, y._mask) + assert_almost_equal(z, y) + assert_almost_equal(z._data, y._data) + x **= b + assert_equal(x._mask, y._mask) + assert_almost_equal(x, y) + assert_almost_equal(x._data, y._data) + + def test_power_with_broadcasting(self): + # Test power w/ broadcasting + a2 = np.array([[1., 2., 3.], [4., 5., 6.]]) + a2m = array(a2, mask=[[1, 0, 0], [0, 0, 1]]) + b1 = np.array([2, 4, 3]) + b2 = np.array([b1, b1]) + b2m = array(b2, mask=[[0, 1, 0], [0, 1, 0]]) + + ctrl = array([[1 ** 2, 2 ** 4, 3 ** 3], [4 ** 2, 5 ** 4, 6 ** 3]], + mask=[[1, 1, 0], [0, 1, 1]]) + # No broadcasting, base & exp w/ mask + test = a2m ** b2m + assert_equal(test, ctrl) + assert_equal(test.mask, ctrl.mask) + # No broadcasting, base w/ mask, exp w/o mask + test = a2m ** b2 + assert_equal(test, ctrl) + assert_equal(test.mask, a2m.mask) + # No broadcasting, base w/o mask, exp w/ mask + test = a2 ** b2m + assert_equal(test, ctrl) + assert_equal(test.mask, b2m.mask) + + ctrl = array([[2 ** 2, 4 ** 4, 3 ** 3], [2 ** 2, 4 ** 4, 3 ** 3]], + mask=[[0, 1, 0], [0, 1, 0]]) + test = b1 ** b2m + assert_equal(test, ctrl) + assert_equal(test.mask, ctrl.mask) + test = b2m ** b1 + assert_equal(test, ctrl) + assert_equal(test.mask, ctrl.mask) + + def test_where(self): + # Test the where function + x = np.array([1., 1., 1., -2., pi/2.0, 4., 5., -10., 10., 1., 2., 3.]) + y = np.array([5., 0., 3., 2., -1., -4., 0., -10., 10., 1., 0., 3.]) + m1 = [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0] + m2 = [0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1] + xm = masked_array(x, mask=m1) + ym = masked_array(y, mask=m2) + xm.set_fill_value(1e+20) + + d = where(xm > 2, xm, -9) + assert_equal(d, [-9., -9., -9., -9., -9., 4., + -9., -9., 10., -9., -9., 3.]) + assert_equal(d._mask, xm._mask) + d = where(xm > 2, -9, ym) + assert_equal(d, [5., 0., 3., 2., -1., -9., + -9., -10., -9., 1., 0., -9.]) + assert_equal(d._mask, [1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0]) + d = where(xm > 2, xm, masked) + assert_equal(d, [-9., -9., -9., -9., -9., 4., + -9., -9., 10., -9., -9., 3.]) + tmp = xm._mask.copy() + tmp[(xm <= 2).filled(True)] = True + assert_equal(d._mask, tmp) + + ixm = xm.astype(int) + d = where(ixm > 2, ixm, masked) + assert_equal(d, [-9, -9, -9, -9, -9, 4, -9, -9, 10, -9, -9, 3]) + assert_equal(d.dtype, ixm.dtype) + + def test_where_object(self): + a = np.array(None) + b = masked_array(None) + r = b.copy() + assert_equal(np.ma.where(True, a, a), r) + assert_equal(np.ma.where(True, b, b), r) + + def test_where_with_masked_choice(self): + x = arange(10) + x[3] = masked + c = x >= 8 + # Set False to masked + z = where(c, x, masked) + assert_(z.dtype is x.dtype) + assert_(z[3] is masked) + assert_(z[4] is masked) + assert_(z[7] is masked) + assert_(z[8] is not masked) + assert_(z[9] is not masked) + assert_equal(x, z) + # Set True to masked + z = where(c, masked, x) + assert_(z.dtype is x.dtype) + assert_(z[3] is masked) + assert_(z[4] is not masked) + assert_(z[7] is not masked) + assert_(z[8] is masked) + assert_(z[9] is masked) + + def test_where_with_masked_condition(self): + x = array([1., 2., 3., 4., 5.]) + c = array([1, 1, 1, 0, 0]) + x[2] = masked + z = where(c, x, -x) + assert_equal(z, [1., 2., 0., -4., -5]) + c[0] = masked + z = where(c, x, -x) + assert_equal(z, [1., 2., 0., -4., -5]) + assert_(z[0] is masked) + assert_(z[1] is not masked) + assert_(z[2] is masked) + + x = arange(1, 6) + x[-1] = masked + y = arange(1, 6) * 10 + y[2] = masked + c = array([1, 1, 1, 0, 0], mask=[1, 0, 0, 0, 0]) + cm = c.filled(1) + z = where(c, x, y) + zm = where(cm, x, y) + assert_equal(z, zm) + assert_(getmask(zm) is nomask) + assert_equal(zm, [1, 2, 3, 40, 50]) + z = where(c, masked, 1) + assert_equal(z, [99, 99, 99, 1, 1]) + z = where(c, 1, masked) + assert_equal(z, [99, 1, 1, 99, 99]) + + def test_where_type(self): + # Test the type conservation with where + x = np.arange(4, dtype=np.int32) + y = np.arange(4, dtype=np.float32) * 2.2 + test = where(x > 1.5, y, x).dtype + control = np.find_common_type([np.int32, np.float32], []) + assert_equal(test, control) + + def test_where_broadcast(self): + # Issue 8599 + x = np.arange(9).reshape(3, 3) + y = np.zeros(3) + core = np.where([1, 0, 1], x, y) + ma = where([1, 0, 1], x, y) + + assert_equal(core, ma) + assert_equal(core.dtype, ma.dtype) + + def test_where_structured(self): + # Issue 8600 + dt = np.dtype([('a', int), ('b', int)]) + x = np.array([(1, 2), (3, 4), (5, 6)], dtype=dt) + y = np.array((10, 20), dtype=dt) + core = np.where([0, 1, 1], x, y) + ma = np.where([0, 1, 1], x, y) + + assert_equal(core, ma) + assert_equal(core.dtype, ma.dtype) + + def test_where_structured_masked(self): + dt = np.dtype([('a', int), ('b', int)]) + x = np.array([(1, 2), (3, 4), (5, 6)], dtype=dt) + + ma = where([0, 1, 1], x, masked) + expected = masked_where([1, 0, 0], x) + + assert_equal(ma.dtype, expected.dtype) + assert_equal(ma, expected) + assert_equal(ma.mask, expected.mask) + + def test_choose(self): + # Test choose + choices = [[0, 1, 2, 3], [10, 11, 12, 13], + [20, 21, 22, 23], [30, 31, 32, 33]] + chosen = choose([2, 3, 1, 0], choices) + assert_equal(chosen, array([20, 31, 12, 3])) + chosen = choose([2, 4, 1, 0], choices, mode='clip') + assert_equal(chosen, array([20, 31, 12, 3])) + chosen = choose([2, 4, 1, 0], choices, mode='wrap') + assert_equal(chosen, array([20, 1, 12, 3])) + # Check with some masked indices + indices_ = array([2, 4, 1, 0], mask=[1, 0, 0, 1]) + chosen = choose(indices_, choices, mode='wrap') + assert_equal(chosen, array([99, 1, 12, 99])) + assert_equal(chosen.mask, [1, 0, 0, 1]) + # Check with some masked choices + choices = array(choices, mask=[[0, 0, 0, 1], [1, 1, 0, 1], + [1, 0, 0, 0], [0, 0, 0, 0]]) + indices_ = [2, 3, 1, 0] + chosen = choose(indices_, choices, mode='wrap') + assert_equal(chosen, array([20, 31, 12, 3])) + assert_equal(chosen.mask, [1, 0, 0, 1]) + + def test_choose_with_out(self): + # Test choose with an explicit out keyword + choices = [[0, 1, 2, 3], [10, 11, 12, 13], + [20, 21, 22, 23], [30, 31, 32, 33]] + store = empty(4, dtype=int) + chosen = choose([2, 3, 1, 0], choices, out=store) + assert_equal(store, array([20, 31, 12, 3])) + assert_(store is chosen) + # Check with some masked indices + out + store = empty(4, dtype=int) + indices_ = array([2, 3, 1, 0], mask=[1, 0, 0, 1]) + chosen = choose(indices_, choices, mode='wrap', out=store) + assert_equal(store, array([99, 31, 12, 99])) + assert_equal(store.mask, [1, 0, 0, 1]) + # Check with some masked choices + out ina ndarray ! + choices = array(choices, mask=[[0, 0, 0, 1], [1, 1, 0, 1], + [1, 0, 0, 0], [0, 0, 0, 0]]) + indices_ = [2, 3, 1, 0] + store = empty(4, dtype=int).view(ndarray) + chosen = choose(indices_, choices, mode='wrap', out=store) + assert_equal(store, array([999999, 31, 12, 999999])) + + def test_reshape(self): + a = arange(10) + a[0] = masked + # Try the default + b = a.reshape((5, 2)) + assert_equal(b.shape, (5, 2)) + assert_(b.flags['C']) + # Try w/ arguments as list instead of tuple + b = a.reshape(5, 2) + assert_equal(b.shape, (5, 2)) + assert_(b.flags['C']) + # Try w/ order + b = a.reshape((5, 2), order='F') + assert_equal(b.shape, (5, 2)) + assert_(b.flags['F']) + # Try w/ order + b = a.reshape(5, 2, order='F') + assert_equal(b.shape, (5, 2)) + assert_(b.flags['F']) + + c = np.reshape(a, (2, 5)) + assert_(isinstance(c, MaskedArray)) + assert_equal(c.shape, (2, 5)) + assert_(c[0, 0] is masked) + assert_(c.flags['C']) + + def test_make_mask_descr(self): + # Flexible + ntype = [('a', float), ('b', float)] + test = make_mask_descr(ntype) + assert_equal(test, [('a', bool), ('b', bool)]) + assert_(test is make_mask_descr(test)) + + # Standard w/ shape + ntype = (float, 2) + test = make_mask_descr(ntype) + assert_equal(test, (bool, 2)) + assert_(test is make_mask_descr(test)) + + # Standard standard + ntype = float + test = make_mask_descr(ntype) + assert_equal(test, np.dtype(bool)) + assert_(test is make_mask_descr(test)) + + # Nested + ntype = [('a', float), ('b', [('ba', float), ('bb', float)])] + test = make_mask_descr(ntype) + control = np.dtype([('a', 'b1'), ('b', [('ba', 'b1'), ('bb', 'b1')])]) + assert_equal(test, control) + assert_(test is make_mask_descr(test)) + + # Named+ shape + ntype = [('a', (float, 2))] + test = make_mask_descr(ntype) + assert_equal(test, np.dtype([('a', (bool, 2))])) + assert_(test is make_mask_descr(test)) + + # 2 names + ntype = [(('A', 'a'), float)] + test = make_mask_descr(ntype) + assert_equal(test, np.dtype([(('A', 'a'), bool)])) + assert_(test is make_mask_descr(test)) + + # nested boolean types should preserve identity + base_type = np.dtype([('a', int, 3)]) + base_mtype = make_mask_descr(base_type) + sub_type = np.dtype([('a', int), ('b', base_mtype)]) + test = make_mask_descr(sub_type) + assert_equal(test, np.dtype([('a', bool), ('b', [('a', bool, 3)])])) + assert_(test.fields['b'][0] is base_mtype) + + def test_make_mask(self): + # Test make_mask + # w/ a list as an input + mask = [0, 1] + test = make_mask(mask) + assert_equal(test.dtype, MaskType) + assert_equal(test, [0, 1]) + # w/ a ndarray as an input + mask = np.array([0, 1], dtype=bool) + test = make_mask(mask) + assert_equal(test.dtype, MaskType) + assert_equal(test, [0, 1]) + # w/ a flexible-type ndarray as an input - use default + mdtype = [('a', bool), ('b', bool)] + mask = np.array([(0, 0), (0, 1)], dtype=mdtype) + test = make_mask(mask) + assert_equal(test.dtype, MaskType) + assert_equal(test, [1, 1]) + # w/ a flexible-type ndarray as an input - use input dtype + mdtype = [('a', bool), ('b', bool)] + mask = np.array([(0, 0), (0, 1)], dtype=mdtype) + test = make_mask(mask, dtype=mask.dtype) + assert_equal(test.dtype, mdtype) + assert_equal(test, mask) + # w/ a flexible-type ndarray as an input - use input dtype + mdtype = [('a', float), ('b', float)] + bdtype = [('a', bool), ('b', bool)] + mask = np.array([(0, 0), (0, 1)], dtype=mdtype) + test = make_mask(mask, dtype=mask.dtype) + assert_equal(test.dtype, bdtype) + assert_equal(test, np.array([(0, 0), (0, 1)], dtype=bdtype)) + # Ensure this also works for void + mask = np.array((False, True), dtype='?,?')[()] + assert_(isinstance(mask, np.void)) + test = make_mask(mask, dtype=mask.dtype) + assert_equal(test, mask) + assert_(test is not mask) + mask = np.array((0, 1), dtype='i4,i4')[()] + test2 = make_mask(mask, dtype=mask.dtype) + assert_equal(test2, test) + # test that nomask is returned when m is nomask. + bools = [True, False] + dtypes = [MaskType, float] + msgformat = 'copy=%s, shrink=%s, dtype=%s' + for cpy, shr, dt in itertools.product(bools, bools, dtypes): + res = make_mask(nomask, copy=cpy, shrink=shr, dtype=dt) + assert_(res is nomask, msgformat % (cpy, shr, dt)) + + def test_mask_or(self): + # Initialize + mtype = [('a', bool), ('b', bool)] + mask = np.array([(0, 0), (0, 1), (1, 0), (0, 0)], dtype=mtype) + # Test using nomask as input + test = mask_or(mask, nomask) + assert_equal(test, mask) + test = mask_or(nomask, mask) + assert_equal(test, mask) + # Using False as input + test = mask_or(mask, False) + assert_equal(test, mask) + # Using another array w / the same dtype + other = np.array([(0, 1), (0, 1), (0, 1), (0, 1)], dtype=mtype) + test = mask_or(mask, other) + control = np.array([(0, 1), (0, 1), (1, 1), (0, 1)], dtype=mtype) + assert_equal(test, control) + # Using another array w / a different dtype + othertype = [('A', bool), ('B', bool)] + other = np.array([(0, 1), (0, 1), (0, 1), (0, 1)], dtype=othertype) + try: + test = mask_or(mask, other) + except ValueError: + pass + # Using nested arrays + dtype = [('a', bool), ('b', [('ba', bool), ('bb', bool)])] + amask = np.array([(0, (1, 0)), (0, (1, 0))], dtype=dtype) + bmask = np.array([(1, (0, 1)), (0, (0, 0))], dtype=dtype) + cntrl = np.array([(1, (1, 1)), (0, (1, 0))], dtype=dtype) + assert_equal(mask_or(amask, bmask), cntrl) + + def test_flatten_mask(self): + # Tests flatten mask + # Standard dtype + mask = np.array([0, 0, 1], dtype=bool) + assert_equal(flatten_mask(mask), mask) + # Flexible dtype + mask = np.array([(0, 0), (0, 1)], dtype=[('a', bool), ('b', bool)]) + test = flatten_mask(mask) + control = np.array([0, 0, 0, 1], dtype=bool) + assert_equal(test, control) + + mdtype = [('a', bool), ('b', [('ba', bool), ('bb', bool)])] + data = [(0, (0, 0)), (0, (0, 1))] + mask = np.array(data, dtype=mdtype) + test = flatten_mask(mask) + control = np.array([0, 0, 0, 0, 0, 1], dtype=bool) + assert_equal(test, control) + + def test_on_ndarray(self): + # Test functions on ndarrays + a = np.array([1, 2, 3, 4]) + m = array(a, mask=False) + test = anom(a) + assert_equal(test, m.anom()) + test = reshape(a, (2, 2)) + assert_equal(test, m.reshape(2, 2)) + + def test_compress(self): + # Test compress function on ndarray and masked array + # Address Github #2495. + arr = np.arange(8) + arr.shape = 4, 2 + cond = np.array([True, False, True, True]) + control = arr[[0, 2, 3]] + test = np.ma.compress(cond, arr, axis=0) + assert_equal(test, control) + marr = np.ma.array(arr) + test = np.ma.compress(cond, marr, axis=0) + assert_equal(test, control) + + def test_compressed(self): + # Test ma.compressed function. + # Address gh-4026 + a = np.ma.array([1, 2]) + test = np.ma.compressed(a) + assert_(type(test) is np.ndarray) + + # Test case when input data is ndarray subclass + class A(np.ndarray): + pass + + a = np.ma.array(A(shape=0)) + test = np.ma.compressed(a) + assert_(type(test) is A) + + # Test that compress flattens + test = np.ma.compressed([[1],[2]]) + assert_equal(test.ndim, 1) + test = np.ma.compressed([[[[[1]]]]]) + assert_equal(test.ndim, 1) + + # Test case when input is MaskedArray subclass + class M(MaskedArray): + pass + + test = np.ma.compressed(M([[[]], [[]]])) + assert_equal(test.ndim, 1) + + # with .compressed() overridden + class M(MaskedArray): + def compressed(self): + return 42 + + test = np.ma.compressed(M([[[]], [[]]])) + assert_equal(test, 42) + + def test_convolve(self): + a = masked_equal(np.arange(5), 2) + b = np.array([1, 1]) + test = np.ma.convolve(a, b) + assert_equal(test, masked_equal([0, 1, -1, -1, 7, 4], -1)) + + test = np.ma.convolve(a, b, propagate_mask=False) + assert_equal(test, masked_equal([0, 1, 1, 3, 7, 4], -1)) + + test = np.ma.convolve([1, 1], [1, 1, 1]) + assert_equal(test, masked_equal([1, 2, 2, 1], -1)) + + a = [1, 1] + b = masked_equal([1, -1, -1, 1], -1) + test = np.ma.convolve(a, b, propagate_mask=False) + assert_equal(test, masked_equal([1, 1, -1, 1, 1], -1)) + test = np.ma.convolve(a, b, propagate_mask=True) + assert_equal(test, masked_equal([-1, -1, -1, -1, -1], -1)) + + +class TestMaskedFields: + + def setup(self): + ilist = [1, 2, 3, 4, 5] + flist = [1.1, 2.2, 3.3, 4.4, 5.5] + slist = ['one', 'two', 'three', 'four', 'five'] + ddtype = [('a', int), ('b', float), ('c', '|S8')] + mdtype = [('a', bool), ('b', bool), ('c', bool)] + mask = [0, 1, 0, 0, 1] + base = array(list(zip(ilist, flist, slist)), mask=mask, dtype=ddtype) + self.data = dict(base=base, mask=mask, ddtype=ddtype, mdtype=mdtype) + + def test_set_records_masks(self): + base = self.data['base'] + mdtype = self.data['mdtype'] + # Set w/ nomask or masked + base.mask = nomask + assert_equal_records(base._mask, np.zeros(base.shape, dtype=mdtype)) + base.mask = masked + assert_equal_records(base._mask, np.ones(base.shape, dtype=mdtype)) + # Set w/ simple boolean + base.mask = False + assert_equal_records(base._mask, np.zeros(base.shape, dtype=mdtype)) + base.mask = True + assert_equal_records(base._mask, np.ones(base.shape, dtype=mdtype)) + # Set w/ list + base.mask = [0, 0, 0, 1, 1] + assert_equal_records(base._mask, + np.array([(x, x, x) for x in [0, 0, 0, 1, 1]], + dtype=mdtype)) + + def test_set_record_element(self): + # Check setting an element of a record) + base = self.data['base'] + (base_a, base_b, base_c) = (base['a'], base['b'], base['c']) + base[0] = (pi, pi, 'pi') + + assert_equal(base_a.dtype, int) + assert_equal(base_a._data, [3, 2, 3, 4, 5]) + + assert_equal(base_b.dtype, float) + assert_equal(base_b._data, [pi, 2.2, 3.3, 4.4, 5.5]) + + assert_equal(base_c.dtype, '|S8') + assert_equal(base_c._data, + [b'pi', b'two', b'three', b'four', b'five']) + + def test_set_record_slice(self): + base = self.data['base'] + (base_a, base_b, base_c) = (base['a'], base['b'], base['c']) + base[:3] = (pi, pi, 'pi') + + assert_equal(base_a.dtype, int) + assert_equal(base_a._data, [3, 3, 3, 4, 5]) + + assert_equal(base_b.dtype, float) + assert_equal(base_b._data, [pi, pi, pi, 4.4, 5.5]) + + assert_equal(base_c.dtype, '|S8') + assert_equal(base_c._data, + [b'pi', b'pi', b'pi', b'four', b'five']) + + def test_mask_element(self): + "Check record access" + base = self.data['base'] + base[0] = masked + + for n in ('a', 'b', 'c'): + assert_equal(base[n].mask, [1, 1, 0, 0, 1]) + assert_equal(base[n]._data, base._data[n]) + + def test_getmaskarray(self): + # Test getmaskarray on flexible dtype + ndtype = [('a', int), ('b', float)] + test = empty(3, dtype=ndtype) + assert_equal(getmaskarray(test), + np.array([(0, 0), (0, 0), (0, 0)], + dtype=[('a', '|b1'), ('b', '|b1')])) + test[:] = masked + assert_equal(getmaskarray(test), + np.array([(1, 1), (1, 1), (1, 1)], + dtype=[('a', '|b1'), ('b', '|b1')])) + + def test_view(self): + # Test view w/ flexible dtype + iterator = list(zip(np.arange(10), np.random.rand(10))) + data = np.array(iterator) + a = array(iterator, dtype=[('a', float), ('b', float)]) + a.mask[0] = (1, 0) + controlmask = np.array([1] + 19 * [0], dtype=bool) + # Transform globally to simple dtype + test = a.view(float) + assert_equal(test, data.ravel()) + assert_equal(test.mask, controlmask) + # Transform globally to dty + test = a.view((float, 2)) + assert_equal(test, data) + assert_equal(test.mask, controlmask.reshape(-1, 2)) + + def test_getitem(self): + ndtype = [('a', float), ('b', float)] + a = array(list(zip(np.random.rand(10), np.arange(10))), dtype=ndtype) + a.mask = np.array(list(zip([0, 0, 0, 0, 0, 0, 0, 0, 1, 1], + [1, 0, 0, 0, 0, 0, 0, 0, 1, 0])), + dtype=[('a', bool), ('b', bool)]) + + def _test_index(i): + assert_equal(type(a[i]), mvoid) + assert_equal_records(a[i]._data, a._data[i]) + assert_equal_records(a[i]._mask, a._mask[i]) + + assert_equal(type(a[i, ...]), MaskedArray) + assert_equal_records(a[i,...]._data, a._data[i,...]) + assert_equal_records(a[i,...]._mask, a._mask[i,...]) + + _test_index(1) # No mask + _test_index(0) # One element masked + _test_index(-2) # All element masked + + def test_setitem(self): + # Issue 4866: check that one can set individual items in [record][col] + # and [col][record] order + ndtype = np.dtype([('a', float), ('b', int)]) + ma = np.ma.MaskedArray([(1.0, 1), (2.0, 2)], dtype=ndtype) + ma['a'][1] = 3.0 + assert_equal(ma['a'], np.array([1.0, 3.0])) + ma[1]['a'] = 4.0 + assert_equal(ma['a'], np.array([1.0, 4.0])) + # Issue 2403 + mdtype = np.dtype([('a', bool), ('b', bool)]) + # soft mask + control = np.array([(False, True), (True, True)], dtype=mdtype) + a = np.ma.masked_all((2,), dtype=ndtype) + a['a'][0] = 2 + assert_equal(a.mask, control) + a = np.ma.masked_all((2,), dtype=ndtype) + a[0]['a'] = 2 + assert_equal(a.mask, control) + # hard mask + control = np.array([(True, True), (True, True)], dtype=mdtype) + a = np.ma.masked_all((2,), dtype=ndtype) + a.harden_mask() + a['a'][0] = 2 + assert_equal(a.mask, control) + a = np.ma.masked_all((2,), dtype=ndtype) + a.harden_mask() + a[0]['a'] = 2 + assert_equal(a.mask, control) + + def test_setitem_scalar(self): + # 8510 + mask_0d = np.ma.masked_array(1, mask=True) + arr = np.ma.arange(3) + arr[0] = mask_0d + assert_array_equal(arr.mask, [True, False, False]) + + def test_element_len(self): + # check that len() works for mvoid (Github issue #576) + for rec in self.data['base']: + assert_equal(len(rec), len(self.data['ddtype'])) + + +class TestMaskedObjectArray: + + def test_getitem(self): + arr = np.ma.array([None, None]) + for dt in [float, object]: + a0 = np.eye(2).astype(dt) + a1 = np.eye(3).astype(dt) + arr[0] = a0 + arr[1] = a1 + + assert_(arr[0] is a0) + assert_(arr[1] is a1) + assert_(isinstance(arr[0,...], MaskedArray)) + assert_(isinstance(arr[1,...], MaskedArray)) + assert_(arr[0,...][()] is a0) + assert_(arr[1,...][()] is a1) + + arr[0] = np.ma.masked + + assert_(arr[1] is a1) + assert_(isinstance(arr[0,...], MaskedArray)) + assert_(isinstance(arr[1,...], MaskedArray)) + assert_equal(arr[0,...].mask, True) + assert_(arr[1,...][()] is a1) + + # gh-5962 - object arrays of arrays do something special + assert_equal(arr[0].data, a0) + assert_equal(arr[0].mask, True) + assert_equal(arr[0,...][()].data, a0) + assert_equal(arr[0,...][()].mask, True) + + def test_nested_ma(self): + + arr = np.ma.array([None, None]) + # set the first object to be an unmasked masked constant. A little fiddly + arr[0,...] = np.array([np.ma.masked], object)[0,...] + + # check the above line did what we were aiming for + assert_(arr.data[0] is np.ma.masked) + + # test that getitem returned the value by identity + assert_(arr[0] is np.ma.masked) + + # now mask the masked value! + arr[0] = np.ma.masked + assert_(arr[0] is np.ma.masked) + + +class TestMaskedView: + + def setup(self): + iterator = list(zip(np.arange(10), np.random.rand(10))) + data = np.array(iterator) + a = array(iterator, dtype=[('a', float), ('b', float)]) + a.mask[0] = (1, 0) + controlmask = np.array([1] + 19 * [0], dtype=bool) + self.data = (data, a, controlmask) + + def test_view_to_nothing(self): + (data, a, controlmask) = self.data + test = a.view() + assert_(isinstance(test, MaskedArray)) + assert_equal(test._data, a._data) + assert_equal(test._mask, a._mask) + + def test_view_to_type(self): + (data, a, controlmask) = self.data + test = a.view(np.ndarray) + assert_(not isinstance(test, MaskedArray)) + assert_equal(test, a._data) + assert_equal_records(test, data.view(a.dtype).squeeze()) + + def test_view_to_simple_dtype(self): + (data, a, controlmask) = self.data + # View globally + test = a.view(float) + assert_(isinstance(test, MaskedArray)) + assert_equal(test, data.ravel()) + assert_equal(test.mask, controlmask) + + def test_view_to_flexible_dtype(self): + (data, a, controlmask) = self.data + + test = a.view([('A', float), ('B', float)]) + assert_equal(test.mask.dtype.names, ('A', 'B')) + assert_equal(test['A'], a['a']) + assert_equal(test['B'], a['b']) + + test = a[0].view([('A', float), ('B', float)]) + assert_(isinstance(test, MaskedArray)) + assert_equal(test.mask.dtype.names, ('A', 'B')) + assert_equal(test['A'], a['a'][0]) + assert_equal(test['B'], a['b'][0]) + + test = a[-1].view([('A', float), ('B', float)]) + assert_(isinstance(test, MaskedArray)) + assert_equal(test.dtype.names, ('A', 'B')) + assert_equal(test['A'], a['a'][-1]) + assert_equal(test['B'], a['b'][-1]) + + def test_view_to_subdtype(self): + (data, a, controlmask) = self.data + # View globally + test = a.view((float, 2)) + assert_(isinstance(test, MaskedArray)) + assert_equal(test, data) + assert_equal(test.mask, controlmask.reshape(-1, 2)) + # View on 1 masked element + test = a[0].view((float, 2)) + assert_(isinstance(test, MaskedArray)) + assert_equal(test, data[0]) + assert_equal(test.mask, (1, 0)) + # View on 1 unmasked element + test = a[-1].view((float, 2)) + assert_(isinstance(test, MaskedArray)) + assert_equal(test, data[-1]) + + def test_view_to_dtype_and_type(self): + (data, a, controlmask) = self.data + + test = a.view((float, 2), np.recarray) + assert_equal(test, data) + assert_(isinstance(test, np.recarray)) + assert_(not isinstance(test, MaskedArray)) + + +class TestOptionalArgs: + def test_ndarrayfuncs(self): + # test axis arg behaves the same as ndarray (including multiple axes) + + d = np.arange(24.0).reshape((2,3,4)) + m = np.zeros(24, dtype=bool).reshape((2,3,4)) + # mask out last element of last dimension + m[:,:,-1] = True + a = np.ma.array(d, mask=m) + + def testaxis(f, a, d): + numpy_f = numpy.__getattribute__(f) + ma_f = np.ma.__getattribute__(f) + + # test axis arg + assert_equal(ma_f(a, axis=1)[...,:-1], numpy_f(d[...,:-1], axis=1)) + assert_equal(ma_f(a, axis=(0,1))[...,:-1], + numpy_f(d[...,:-1], axis=(0,1))) + + def testkeepdims(f, a, d): + numpy_f = numpy.__getattribute__(f) + ma_f = np.ma.__getattribute__(f) + + # test keepdims arg + assert_equal(ma_f(a, keepdims=True).shape, + numpy_f(d, keepdims=True).shape) + assert_equal(ma_f(a, keepdims=False).shape, + numpy_f(d, keepdims=False).shape) + + # test both at once + assert_equal(ma_f(a, axis=1, keepdims=True)[...,:-1], + numpy_f(d[...,:-1], axis=1, keepdims=True)) + assert_equal(ma_f(a, axis=(0,1), keepdims=True)[...,:-1], + numpy_f(d[...,:-1], axis=(0,1), keepdims=True)) + + for f in ['sum', 'prod', 'mean', 'var', 'std']: + testaxis(f, a, d) + testkeepdims(f, a, d) + + for f in ['min', 'max']: + testaxis(f, a, d) + + d = (np.arange(24).reshape((2,3,4))%2 == 0) + a = np.ma.array(d, mask=m) + for f in ['all', 'any']: + testaxis(f, a, d) + testkeepdims(f, a, d) + + def test_count(self): + # test np.ma.count specially + + d = np.arange(24.0).reshape((2,3,4)) + m = np.zeros(24, dtype=bool).reshape((2,3,4)) + m[:,0,:] = True + a = np.ma.array(d, mask=m) + + assert_equal(count(a), 16) + assert_equal(count(a, axis=1), 2*ones((2,4))) + assert_equal(count(a, axis=(0,1)), 4*ones((4,))) + assert_equal(count(a, keepdims=True), 16*ones((1,1,1))) + assert_equal(count(a, axis=1, keepdims=True), 2*ones((2,1,4))) + assert_equal(count(a, axis=(0,1), keepdims=True), 4*ones((1,1,4))) + assert_equal(count(a, axis=-2), 2*ones((2,4))) + assert_raises(ValueError, count, a, axis=(1,1)) + assert_raises(np.AxisError, count, a, axis=3) + + # check the 'nomask' path + a = np.ma.array(d, mask=nomask) + + assert_equal(count(a), 24) + assert_equal(count(a, axis=1), 3*ones((2,4))) + assert_equal(count(a, axis=(0,1)), 6*ones((4,))) + assert_equal(count(a, keepdims=True), 24*ones((1,1,1))) + assert_equal(np.ndim(count(a, keepdims=True)), 3) + assert_equal(count(a, axis=1, keepdims=True), 3*ones((2,1,4))) + assert_equal(count(a, axis=(0,1), keepdims=True), 6*ones((1,1,4))) + assert_equal(count(a, axis=-2), 3*ones((2,4))) + assert_raises(ValueError, count, a, axis=(1,1)) + assert_raises(np.AxisError, count, a, axis=3) + + # check the 'masked' singleton + assert_equal(count(np.ma.masked), 0) + + # check 0-d arrays do not allow axis > 0 + assert_raises(np.AxisError, count, np.ma.array(1), axis=1) + + +class TestMaskedConstant: + def _do_add_test(self, add): + # sanity check + assert_(add(np.ma.masked, 1) is np.ma.masked) + + # now try with a vector + vector = np.array([1, 2, 3]) + result = add(np.ma.masked, vector) + + # lots of things could go wrong here + assert_(result is not np.ma.masked) + assert_(not isinstance(result, np.ma.core.MaskedConstant)) + assert_equal(result.shape, vector.shape) + assert_equal(np.ma.getmask(result), np.ones(vector.shape, dtype=bool)) + + def test_ufunc(self): + self._do_add_test(np.add) + + def test_operator(self): + self._do_add_test(lambda a, b: a + b) + + def test_ctor(self): + m = np.ma.array(np.ma.masked) + + # most importantly, we do not want to create a new MaskedConstant + # instance + assert_(not isinstance(m, np.ma.core.MaskedConstant)) + assert_(m is not np.ma.masked) + + def test_repr(self): + # copies should not exist, but if they do, it should be obvious that + # something is wrong + assert_equal(repr(np.ma.masked), 'masked') + + # create a new instance in a weird way + masked2 = np.ma.MaskedArray.__new__(np.ma.core.MaskedConstant) + assert_not_equal(repr(masked2), 'masked') + + def test_pickle(self): + from io import BytesIO + + for proto in range(2, pickle.HIGHEST_PROTOCOL + 1): + with BytesIO() as f: + pickle.dump(np.ma.masked, f, protocol=proto) + f.seek(0) + res = pickle.load(f) + assert_(res is np.ma.masked) + + def test_copy(self): + # gh-9328 + # copy is a no-op, like it is with np.True_ + assert_equal( + np.ma.masked.copy() is np.ma.masked, + np.True_.copy() is np.True_) + + def test__copy(self): + import copy + assert_( + copy.copy(np.ma.masked) is np.ma.masked) + + def test_deepcopy(self): + import copy + assert_( + copy.deepcopy(np.ma.masked) is np.ma.masked) + + def test_immutable(self): + orig = np.ma.masked + assert_raises(np.ma.core.MaskError, operator.setitem, orig, (), 1) + assert_raises(ValueError,operator.setitem, orig.data, (), 1) + assert_raises(ValueError, operator.setitem, orig.mask, (), False) + + view = np.ma.masked.view(np.ma.MaskedArray) + assert_raises(ValueError, operator.setitem, view, (), 1) + assert_raises(ValueError, operator.setitem, view.data, (), 1) + assert_raises(ValueError, operator.setitem, view.mask, (), False) + + def test_coercion_int(self): + a_i = np.zeros((), int) + assert_raises(MaskError, operator.setitem, a_i, (), np.ma.masked) + assert_raises(MaskError, int, np.ma.masked) + + def test_coercion_float(self): + a_f = np.zeros((), float) + assert_warns(UserWarning, operator.setitem, a_f, (), np.ma.masked) + assert_(np.isnan(a_f[()])) + + @pytest.mark.xfail(reason="See gh-9750") + def test_coercion_unicode(self): + a_u = np.zeros((), 'U10') + a_u[()] = np.ma.masked + assert_equal(a_u[()], u'--') + + @pytest.mark.xfail(reason="See gh-9750") + def test_coercion_bytes(self): + a_b = np.zeros((), 'S10') + a_b[()] = np.ma.masked + assert_equal(a_b[()], b'--') + + def test_subclass(self): + # https://github.com/astropy/astropy/issues/6645 + class Sub(type(np.ma.masked)): pass + + a = Sub() + assert_(a is Sub()) + assert_(a is not np.ma.masked) + assert_not_equal(repr(a), 'masked') + + def test_attributes_readonly(self): + assert_raises(AttributeError, setattr, np.ma.masked, 'shape', (1,)) + assert_raises(AttributeError, setattr, np.ma.masked, 'dtype', np.int64) + + +class TestMaskedWhereAliases: + + # TODO: Test masked_object, masked_equal, ... + + def test_masked_values(self): + res = masked_values(np.array([-32768.0]), np.int16(-32768)) + assert_equal(res.mask, [True]) + + res = masked_values(np.inf, np.inf) + assert_equal(res.mask, True) + + res = np.ma.masked_values(np.inf, -np.inf) + assert_equal(res.mask, False) + + res = np.ma.masked_values([1, 2, 3, 4], 5, shrink=True) + assert_(res.mask is np.ma.nomask) + + res = np.ma.masked_values([1, 2, 3, 4], 5, shrink=False) + assert_equal(res.mask, [False] * 4) + + +def test_masked_array(): + a = np.ma.array([0, 1, 2, 3], mask=[0, 0, 1, 0]) + assert_equal(np.argwhere(a), [[1], [3]]) + +def test_append_masked_array(): + a = np.ma.masked_equal([1,2,3], value=2) + b = np.ma.masked_equal([4,3,2], value=2) + + result = np.ma.append(a, b) + expected_data = [1, 2, 3, 4, 3, 2] + expected_mask = [False, True, False, False, False, True] + assert_array_equal(result.data, expected_data) + assert_array_equal(result.mask, expected_mask) + + a = np.ma.masked_all((2,2)) + b = np.ma.ones((3,1)) + + result = np.ma.append(a, b) + expected_data = [1] * 3 + expected_mask = [True] * 4 + [False] * 3 + assert_array_equal(result.data[-3], expected_data) + assert_array_equal(result.mask, expected_mask) + + result = np.ma.append(a, b, axis=None) + assert_array_equal(result.data[-3], expected_data) + assert_array_equal(result.mask, expected_mask) + + +def test_append_masked_array_along_axis(): + a = np.ma.masked_equal([1,2,3], value=2) + b = np.ma.masked_values([[4, 5, 6], [7, 8, 9]], 7) + + # When `axis` is specified, `values` must have the correct shape. + assert_raises(ValueError, np.ma.append, a, b, axis=0) + + result = np.ma.append(a[np.newaxis,:], b, axis=0) + expected = np.ma.arange(1, 10) + expected[[1, 6]] = np.ma.masked + expected = expected.reshape((3,3)) + assert_array_equal(result.data, expected.data) + assert_array_equal(result.mask, expected.mask) + + +def test_default_fill_value_complex(): + # regression test for Python 3, where 'unicode' was not defined + assert_(default_fill_value(1 + 1j) == 1.e20 + 0.0j) + + +def test_ufunc_with_output(): + # check that giving an output argument always returns that output. + # Regression test for gh-8416. + x = array([1., 2., 3.], mask=[0, 0, 1]) + y = np.add(x, 1., out=x) + assert_(y is x) + + +def test_ufunc_with_out_varied(): + """ Test that masked arrays are immune to gh-10459 """ + # the mask of the output should not affect the result, however it is passed + a = array([ 1, 2, 3], mask=[1, 0, 0]) + b = array([10, 20, 30], mask=[1, 0, 0]) + out = array([ 0, 0, 0], mask=[0, 0, 1]) + expected = array([11, 22, 33], mask=[1, 0, 0]) + + out_pos = out.copy() + res_pos = np.add(a, b, out_pos) + + out_kw = out.copy() + res_kw = np.add(a, b, out=out_kw) + + out_tup = out.copy() + res_tup = np.add(a, b, out=(out_tup,)) + + assert_equal(res_kw.mask, expected.mask) + assert_equal(res_kw.data, expected.data) + assert_equal(res_tup.mask, expected.mask) + assert_equal(res_tup.data, expected.data) + assert_equal(res_pos.mask, expected.mask) + assert_equal(res_pos.data, expected.data) + + +def test_astype_mask_ordering(): + descr = [('v', int, 3), ('x', [('y', float)])] + x = array([ + [([1, 2, 3], (1.0,)), ([1, 2, 3], (2.0,))], + [([1, 2, 3], (3.0,)), ([1, 2, 3], (4.0,))]], dtype=descr) + x[0]['v'][0] = np.ma.masked + + x_a = x.astype(descr) + assert x_a.dtype.names == np.dtype(descr).names + assert x_a.mask.dtype.names == np.dtype(descr).names + assert_equal(x, x_a) + + assert_(x is x.astype(x.dtype, copy=False)) + assert_equal(type(x.astype(x.dtype, subok=False)), np.ndarray) + + x_f = x.astype(x.dtype, order='F') + assert_(x_f.flags.f_contiguous) + assert_(x_f.mask.flags.f_contiguous) + + # Also test the same indirectly, via np.array + x_a2 = np.array(x, dtype=descr, subok=True) + assert x_a2.dtype.names == np.dtype(descr).names + assert x_a2.mask.dtype.names == np.dtype(descr).names + assert_equal(x, x_a2) + + assert_(x is np.array(x, dtype=descr, copy=False, subok=True)) + + x_f2 = np.array(x, dtype=x.dtype, order='F', subok=True) + assert_(x_f2.flags.f_contiguous) + assert_(x_f2.mask.flags.f_contiguous) + + +@pytest.mark.parametrize('dt1', num_dts, ids=num_ids) +@pytest.mark.parametrize('dt2', num_dts, ids=num_ids) +@pytest.mark.filterwarnings('ignore::numpy.ComplexWarning') +def test_astype_basic(dt1, dt2): + # See gh-12070 + src = np.ma.array(ones(3, dt1), fill_value=1) + dst = src.astype(dt2) + + assert_(src.fill_value == 1) + assert_(src.dtype == dt1) + assert_(src.fill_value.dtype == dt1) + + assert_(dst.fill_value == 1) + assert_(dst.dtype == dt2) + assert_(dst.fill_value.dtype == dt2) + + assert_equal(src, dst) + + +def test_fieldless_void(): + dt = np.dtype([]) # a void dtype with no fields + x = np.empty(4, dt) + + # these arrays contain no values, so there's little to test - but this + # shouldn't crash + mx = np.ma.array(x) + assert_equal(mx.dtype, x.dtype) + assert_equal(mx.shape, x.shape) + + mx = np.ma.array(x, mask=x) + assert_equal(mx.dtype, x.dtype) + assert_equal(mx.shape, x.shape) + + +def test_mask_shape_assignment_does_not_break_masked(): + a = np.ma.masked + b = np.ma.array(1, mask=a.mask) + b.shape = (1,) + assert_equal(a.mask.shape, ()) + +@pytest.mark.skipif(sys.flags.optimize > 1, + reason="no docstrings present to inspect when PYTHONOPTIMIZE/Py_OptimizeFlag > 1") +def test_doc_note(): + def method(self): + """This docstring + + Has multiple lines + + And notes + + Notes + ----- + original note + """ + pass + + expected_doc = """This docstring + +Has multiple lines + +And notes + +Notes +----- +note + +original note""" + + assert_equal(np.ma.core.doc_note(method.__doc__, "note"), expected_doc) diff --git a/venv/Lib/site-packages/numpy/ma/tests/test_deprecations.py b/venv/Lib/site-packages/numpy/ma/tests/test_deprecations.py new file mode 100644 index 0000000..14f6973 --- /dev/null +++ b/venv/Lib/site-packages/numpy/ma/tests/test_deprecations.py @@ -0,0 +1,68 @@ +"""Test deprecation and future warnings. + +""" +import numpy as np +from numpy.testing import assert_warns +from numpy.ma.testutils import assert_equal +from numpy.ma.core import MaskedArrayFutureWarning + +class TestArgsort: + """ gh-8701 """ + def _test_base(self, argsort, cls): + arr_0d = np.array(1).view(cls) + argsort(arr_0d) + + arr_1d = np.array([1, 2, 3]).view(cls) + argsort(arr_1d) + + # argsort has a bad default for >1d arrays + arr_2d = np.array([[1, 2], [3, 4]]).view(cls) + result = assert_warns( + np.ma.core.MaskedArrayFutureWarning, argsort, arr_2d) + assert_equal(result, argsort(arr_2d, axis=None)) + + # should be no warnings for explicitly specifying it + argsort(arr_2d, axis=None) + argsort(arr_2d, axis=-1) + + def test_function_ndarray(self): + return self._test_base(np.ma.argsort, np.ndarray) + + def test_function_maskedarray(self): + return self._test_base(np.ma.argsort, np.ma.MaskedArray) + + def test_method(self): + return self._test_base(np.ma.MaskedArray.argsort, np.ma.MaskedArray) + + +class TestMinimumMaximum: + def test_minimum(self): + assert_warns(DeprecationWarning, np.ma.minimum, np.ma.array([1, 2])) + + def test_maximum(self): + assert_warns(DeprecationWarning, np.ma.maximum, np.ma.array([1, 2])) + + def test_axis_default(self): + # NumPy 1.13, 2017-05-06 + + data1d = np.ma.arange(6) + data2d = data1d.reshape(2, 3) + + ma_min = np.ma.minimum.reduce + ma_max = np.ma.maximum.reduce + + # check that the default axis is still None, but warns on 2d arrays + result = assert_warns(MaskedArrayFutureWarning, ma_max, data2d) + assert_equal(result, ma_max(data2d, axis=None)) + + result = assert_warns(MaskedArrayFutureWarning, ma_min, data2d) + assert_equal(result, ma_min(data2d, axis=None)) + + # no warnings on 1d, as both new and old defaults are equivalent + result = ma_min(data1d) + assert_equal(result, ma_min(data1d, axis=None)) + assert_equal(result, ma_min(data1d, axis=0)) + + result = ma_max(data1d) + assert_equal(result, ma_max(data1d, axis=None)) + assert_equal(result, ma_max(data1d, axis=0)) diff --git a/venv/Lib/site-packages/numpy/ma/tests/test_extras.py b/venv/Lib/site-packages/numpy/ma/tests/test_extras.py new file mode 100644 index 0000000..d237829 --- /dev/null +++ b/venv/Lib/site-packages/numpy/ma/tests/test_extras.py @@ -0,0 +1,1688 @@ +# pylint: disable-msg=W0611, W0612, W0511 +"""Tests suite for MaskedArray. +Adapted from the original test_ma by Pierre Gerard-Marchant + +:author: Pierre Gerard-Marchant +:contact: pierregm_at_uga_dot_edu +:version: $Id: test_extras.py 3473 2007-10-29 15:18:13Z jarrod.millman $ + +""" +import warnings +import itertools +import pytest + +import numpy as np +from numpy.testing import ( + assert_warns, suppress_warnings + ) +from numpy.ma.testutils import ( + assert_, assert_array_equal, assert_equal, assert_almost_equal + ) +from numpy.ma.core import ( + array, arange, masked, MaskedArray, masked_array, getmaskarray, shape, + nomask, ones, zeros, count + ) +from numpy.ma.extras import ( + atleast_1d, atleast_2d, atleast_3d, mr_, dot, polyfit, cov, corrcoef, + median, average, unique, setxor1d, setdiff1d, union1d, intersect1d, in1d, + ediff1d, apply_over_axes, apply_along_axis, compress_nd, compress_rowcols, + mask_rowcols, clump_masked, clump_unmasked, flatnotmasked_contiguous, + notmasked_contiguous, notmasked_edges, masked_all, masked_all_like, isin, + diagflat, stack, vstack + ) + + +class TestGeneric: + # + def test_masked_all(self): + # Tests masked_all + # Standard dtype + test = masked_all((2,), dtype=float) + control = array([1, 1], mask=[1, 1], dtype=float) + assert_equal(test, control) + # Flexible dtype + dt = np.dtype({'names': ['a', 'b'], 'formats': ['f', 'f']}) + test = masked_all((2,), dtype=dt) + control = array([(0, 0), (0, 0)], mask=[(1, 1), (1, 1)], dtype=dt) + assert_equal(test, control) + test = masked_all((2, 2), dtype=dt) + control = array([[(0, 0), (0, 0)], [(0, 0), (0, 0)]], + mask=[[(1, 1), (1, 1)], [(1, 1), (1, 1)]], + dtype=dt) + assert_equal(test, control) + # Nested dtype + dt = np.dtype([('a', 'f'), ('b', [('ba', 'f'), ('bb', 'f')])]) + test = masked_all((2,), dtype=dt) + control = array([(1, (1, 1)), (1, (1, 1))], + mask=[(1, (1, 1)), (1, (1, 1))], dtype=dt) + assert_equal(test, control) + test = masked_all((2,), dtype=dt) + control = array([(1, (1, 1)), (1, (1, 1))], + mask=[(1, (1, 1)), (1, (1, 1))], dtype=dt) + assert_equal(test, control) + test = masked_all((1, 1), dtype=dt) + control = array([[(1, (1, 1))]], mask=[[(1, (1, 1))]], dtype=dt) + assert_equal(test, control) + + def test_masked_all_with_object_nested(self): + # Test masked_all works with nested array with dtype of an 'object' + # refers to issue #15895 + my_dtype = np.dtype([('b', ([('c', object)], (1,)))]) + masked_arr = np.ma.masked_all((1,), my_dtype) + + assert_equal(type(masked_arr['b']), np.ma.core.MaskedArray) + assert_equal(type(masked_arr['b']['c']), np.ma.core.MaskedArray) + assert_equal(len(masked_arr['b']['c']), 1) + assert_equal(masked_arr['b']['c'].shape, (1, 1)) + assert_equal(masked_arr['b']['c']._fill_value.shape, ()) + + def test_masked_all_with_object(self): + # same as above except that the array is not nested + my_dtype = np.dtype([('b', (object, (1,)))]) + masked_arr = np.ma.masked_all((1,), my_dtype) + + assert_equal(type(masked_arr['b']), np.ma.core.MaskedArray) + assert_equal(len(masked_arr['b']), 1) + assert_equal(masked_arr['b'].shape, (1, 1)) + assert_equal(masked_arr['b']._fill_value.shape, ()) + + def test_masked_all_like(self): + # Tests masked_all + # Standard dtype + base = array([1, 2], dtype=float) + test = masked_all_like(base) + control = array([1, 1], mask=[1, 1], dtype=float) + assert_equal(test, control) + # Flexible dtype + dt = np.dtype({'names': ['a', 'b'], 'formats': ['f', 'f']}) + base = array([(0, 0), (0, 0)], mask=[(1, 1), (1, 1)], dtype=dt) + test = masked_all_like(base) + control = array([(10, 10), (10, 10)], mask=[(1, 1), (1, 1)], dtype=dt) + assert_equal(test, control) + # Nested dtype + dt = np.dtype([('a', 'f'), ('b', [('ba', 'f'), ('bb', 'f')])]) + control = array([(1, (1, 1)), (1, (1, 1))], + mask=[(1, (1, 1)), (1, (1, 1))], dtype=dt) + test = masked_all_like(control) + assert_equal(test, control) + + def check_clump(self, f): + for i in range(1, 7): + for j in range(2**i): + k = np.arange(i, dtype=int) + ja = np.full(i, j, dtype=int) + a = masked_array(2**k) + a.mask = (ja & (2**k)) != 0 + s = 0 + for sl in f(a): + s += a.data[sl].sum() + if f == clump_unmasked: + assert_equal(a.compressed().sum(), s) + else: + a.mask = ~a.mask + assert_equal(a.compressed().sum(), s) + + def test_clump_masked(self): + # Test clump_masked + a = masked_array(np.arange(10)) + a[[0, 1, 2, 6, 8, 9]] = masked + # + test = clump_masked(a) + control = [slice(0, 3), slice(6, 7), slice(8, 10)] + assert_equal(test, control) + + self.check_clump(clump_masked) + + def test_clump_unmasked(self): + # Test clump_unmasked + a = masked_array(np.arange(10)) + a[[0, 1, 2, 6, 8, 9]] = masked + test = clump_unmasked(a) + control = [slice(3, 6), slice(7, 8), ] + assert_equal(test, control) + + self.check_clump(clump_unmasked) + + def test_flatnotmasked_contiguous(self): + # Test flatnotmasked_contiguous + a = arange(10) + # No mask + test = flatnotmasked_contiguous(a) + assert_equal(test, [slice(0, a.size)]) + # mask of all false + a.mask = np.zeros(10, dtype=bool) + assert_equal(test, [slice(0, a.size)]) + # Some mask + a[(a < 3) | (a > 8) | (a == 5)] = masked + test = flatnotmasked_contiguous(a) + assert_equal(test, [slice(3, 5), slice(6, 9)]) + # + a[:] = masked + test = flatnotmasked_contiguous(a) + assert_equal(test, []) + + +class TestAverage: + # Several tests of average. Why so many ? Good point... + def test_testAverage1(self): + # Test of average. + ott = array([0., 1., 2., 3.], mask=[True, False, False, False]) + assert_equal(2.0, average(ott, axis=0)) + assert_equal(2.0, average(ott, weights=[1., 1., 2., 1.])) + result, wts = average(ott, weights=[1., 1., 2., 1.], returned=True) + assert_equal(2.0, result) + assert_(wts == 4.0) + ott[:] = masked + assert_equal(average(ott, axis=0).mask, [True]) + ott = array([0., 1., 2., 3.], mask=[True, False, False, False]) + ott = ott.reshape(2, 2) + ott[:, 1] = masked + assert_equal(average(ott, axis=0), [2.0, 0.0]) + assert_equal(average(ott, axis=1).mask[0], [True]) + assert_equal([2., 0.], average(ott, axis=0)) + result, wts = average(ott, axis=0, returned=True) + assert_equal(wts, [1., 0.]) + + def test_testAverage2(self): + # More tests of average. + w1 = [0, 1, 1, 1, 1, 0] + w2 = [[0, 1, 1, 1, 1, 0], [1, 0, 0, 0, 0, 1]] + x = arange(6, dtype=np.float_) + assert_equal(average(x, axis=0), 2.5) + assert_equal(average(x, axis=0, weights=w1), 2.5) + y = array([arange(6, dtype=np.float_), 2.0 * arange(6)]) + assert_equal(average(y, None), np.add.reduce(np.arange(6)) * 3. / 12.) + assert_equal(average(y, axis=0), np.arange(6) * 3. / 2.) + assert_equal(average(y, axis=1), + [average(x, axis=0), average(x, axis=0) * 2.0]) + assert_equal(average(y, None, weights=w2), 20. / 6.) + assert_equal(average(y, axis=0, weights=w2), + [0., 1., 2., 3., 4., 10.]) + assert_equal(average(y, axis=1), + [average(x, axis=0), average(x, axis=0) * 2.0]) + m1 = zeros(6) + m2 = [0, 0, 1, 1, 0, 0] + m3 = [[0, 0, 1, 1, 0, 0], [0, 1, 1, 1, 1, 0]] + m4 = ones(6) + m5 = [0, 1, 1, 1, 1, 1] + assert_equal(average(masked_array(x, m1), axis=0), 2.5) + assert_equal(average(masked_array(x, m2), axis=0), 2.5) + assert_equal(average(masked_array(x, m4), axis=0).mask, [True]) + assert_equal(average(masked_array(x, m5), axis=0), 0.0) + assert_equal(count(average(masked_array(x, m4), axis=0)), 0) + z = masked_array(y, m3) + assert_equal(average(z, None), 20. / 6.) + assert_equal(average(z, axis=0), [0., 1., 99., 99., 4.0, 7.5]) + assert_equal(average(z, axis=1), [2.5, 5.0]) + assert_equal(average(z, axis=0, weights=w2), + [0., 1., 99., 99., 4.0, 10.0]) + + def test_testAverage3(self): + # Yet more tests of average! + a = arange(6) + b = arange(6) * 3 + r1, w1 = average([[a, b], [b, a]], axis=1, returned=True) + assert_equal(shape(r1), shape(w1)) + assert_equal(r1.shape, w1.shape) + r2, w2 = average(ones((2, 2, 3)), axis=0, weights=[3, 1], returned=True) + assert_equal(shape(w2), shape(r2)) + r2, w2 = average(ones((2, 2, 3)), returned=True) + assert_equal(shape(w2), shape(r2)) + r2, w2 = average(ones((2, 2, 3)), weights=ones((2, 2, 3)), returned=True) + assert_equal(shape(w2), shape(r2)) + a2d = array([[1, 2], [0, 4]], float) + a2dm = masked_array(a2d, [[False, False], [True, False]]) + a2da = average(a2d, axis=0) + assert_equal(a2da, [0.5, 3.0]) + a2dma = average(a2dm, axis=0) + assert_equal(a2dma, [1.0, 3.0]) + a2dma = average(a2dm, axis=None) + assert_equal(a2dma, 7. / 3.) + a2dma = average(a2dm, axis=1) + assert_equal(a2dma, [1.5, 4.0]) + + def test_onintegers_with_mask(self): + # Test average on integers with mask + a = average(array([1, 2])) + assert_equal(a, 1.5) + a = average(array([1, 2, 3, 4], mask=[False, False, True, True])) + assert_equal(a, 1.5) + + def test_complex(self): + # Test with complex data. + # (Regression test for https://github.com/numpy/numpy/issues/2684) + mask = np.array([[0, 0, 0, 1, 0], + [0, 1, 0, 0, 0]], dtype=bool) + a = masked_array([[0, 1+2j, 3+4j, 5+6j, 7+8j], + [9j, 0+1j, 2+3j, 4+5j, 7+7j]], + mask=mask) + + av = average(a) + expected = np.average(a.compressed()) + assert_almost_equal(av.real, expected.real) + assert_almost_equal(av.imag, expected.imag) + + av0 = average(a, axis=0) + expected0 = average(a.real, axis=0) + average(a.imag, axis=0)*1j + assert_almost_equal(av0.real, expected0.real) + assert_almost_equal(av0.imag, expected0.imag) + + av1 = average(a, axis=1) + expected1 = average(a.real, axis=1) + average(a.imag, axis=1)*1j + assert_almost_equal(av1.real, expected1.real) + assert_almost_equal(av1.imag, expected1.imag) + + # Test with the 'weights' argument. + wts = np.array([[0.5, 1.0, 2.0, 1.0, 0.5], + [1.0, 1.0, 1.0, 1.0, 1.0]]) + wav = average(a, weights=wts) + expected = np.average(a.compressed(), weights=wts[~mask]) + assert_almost_equal(wav.real, expected.real) + assert_almost_equal(wav.imag, expected.imag) + + wav0 = average(a, weights=wts, axis=0) + expected0 = (average(a.real, weights=wts, axis=0) + + average(a.imag, weights=wts, axis=0)*1j) + assert_almost_equal(wav0.real, expected0.real) + assert_almost_equal(wav0.imag, expected0.imag) + + wav1 = average(a, weights=wts, axis=1) + expected1 = (average(a.real, weights=wts, axis=1) + + average(a.imag, weights=wts, axis=1)*1j) + assert_almost_equal(wav1.real, expected1.real) + assert_almost_equal(wav1.imag, expected1.imag) + + +class TestConcatenator: + # Tests for mr_, the equivalent of r_ for masked arrays. + + def test_1d(self): + # Tests mr_ on 1D arrays. + assert_array_equal(mr_[1, 2, 3, 4, 5, 6], array([1, 2, 3, 4, 5, 6])) + b = ones(5) + m = [1, 0, 0, 0, 0] + d = masked_array(b, mask=m) + c = mr_[d, 0, 0, d] + assert_(isinstance(c, MaskedArray)) + assert_array_equal(c, [1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1]) + assert_array_equal(c.mask, mr_[m, 0, 0, m]) + + def test_2d(self): + # Tests mr_ on 2D arrays. + a_1 = np.random.rand(5, 5) + a_2 = np.random.rand(5, 5) + m_1 = np.round_(np.random.rand(5, 5), 0) + m_2 = np.round_(np.random.rand(5, 5), 0) + b_1 = masked_array(a_1, mask=m_1) + b_2 = masked_array(a_2, mask=m_2) + # append columns + d = mr_['1', b_1, b_2] + assert_(d.shape == (5, 10)) + assert_array_equal(d[:, :5], b_1) + assert_array_equal(d[:, 5:], b_2) + assert_array_equal(d.mask, np.r_['1', m_1, m_2]) + d = mr_[b_1, b_2] + assert_(d.shape == (10, 5)) + assert_array_equal(d[:5,:], b_1) + assert_array_equal(d[5:,:], b_2) + assert_array_equal(d.mask, np.r_[m_1, m_2]) + + def test_masked_constant(self): + actual = mr_[np.ma.masked, 1] + assert_equal(actual.mask, [True, False]) + assert_equal(actual.data[1], 1) + + actual = mr_[[1, 2], np.ma.masked] + assert_equal(actual.mask, [False, False, True]) + assert_equal(actual.data[:2], [1, 2]) + + +class TestNotMasked: + # Tests notmasked_edges and notmasked_contiguous. + + def test_edges(self): + # Tests unmasked_edges + data = masked_array(np.arange(25).reshape(5, 5), + mask=[[0, 0, 1, 0, 0], + [0, 0, 0, 1, 1], + [1, 1, 0, 0, 0], + [0, 0, 0, 0, 0], + [1, 1, 1, 0, 0]],) + test = notmasked_edges(data, None) + assert_equal(test, [0, 24]) + test = notmasked_edges(data, 0) + assert_equal(test[0], [(0, 0, 1, 0, 0), (0, 1, 2, 3, 4)]) + assert_equal(test[1], [(3, 3, 3, 4, 4), (0, 1, 2, 3, 4)]) + test = notmasked_edges(data, 1) + assert_equal(test[0], [(0, 1, 2, 3, 4), (0, 0, 2, 0, 3)]) + assert_equal(test[1], [(0, 1, 2, 3, 4), (4, 2, 4, 4, 4)]) + # + test = notmasked_edges(data.data, None) + assert_equal(test, [0, 24]) + test = notmasked_edges(data.data, 0) + assert_equal(test[0], [(0, 0, 0, 0, 0), (0, 1, 2, 3, 4)]) + assert_equal(test[1], [(4, 4, 4, 4, 4), (0, 1, 2, 3, 4)]) + test = notmasked_edges(data.data, -1) + assert_equal(test[0], [(0, 1, 2, 3, 4), (0, 0, 0, 0, 0)]) + assert_equal(test[1], [(0, 1, 2, 3, 4), (4, 4, 4, 4, 4)]) + # + data[-2] = masked + test = notmasked_edges(data, 0) + assert_equal(test[0], [(0, 0, 1, 0, 0), (0, 1, 2, 3, 4)]) + assert_equal(test[1], [(1, 1, 2, 4, 4), (0, 1, 2, 3, 4)]) + test = notmasked_edges(data, -1) + assert_equal(test[0], [(0, 1, 2, 4), (0, 0, 2, 3)]) + assert_equal(test[1], [(0, 1, 2, 4), (4, 2, 4, 4)]) + + def test_contiguous(self): + # Tests notmasked_contiguous + a = masked_array(np.arange(24).reshape(3, 8), + mask=[[0, 0, 0, 0, 1, 1, 1, 1], + [1, 1, 1, 1, 1, 1, 1, 1], + [0, 0, 0, 0, 0, 0, 1, 0]]) + tmp = notmasked_contiguous(a, None) + assert_equal(tmp, [ + slice(0, 4, None), + slice(16, 22, None), + slice(23, 24, None) + ]) + + tmp = notmasked_contiguous(a, 0) + assert_equal(tmp, [ + [slice(0, 1, None), slice(2, 3, None)], + [slice(0, 1, None), slice(2, 3, None)], + [slice(0, 1, None), slice(2, 3, None)], + [slice(0, 1, None), slice(2, 3, None)], + [slice(2, 3, None)], + [slice(2, 3, None)], + [], + [slice(2, 3, None)] + ]) + # + tmp = notmasked_contiguous(a, 1) + assert_equal(tmp, [ + [slice(0, 4, None)], + [], + [slice(0, 6, None), slice(7, 8, None)] + ]) + + +class TestCompressFunctions: + + def test_compress_nd(self): + # Tests compress_nd + x = np.array(list(range(3*4*5))).reshape(3, 4, 5) + m = np.zeros((3,4,5)).astype(bool) + m[1,1,1] = True + x = array(x, mask=m) + + # axis=None + a = compress_nd(x) + assert_equal(a, [[[ 0, 2, 3, 4], + [10, 12, 13, 14], + [15, 17, 18, 19]], + [[40, 42, 43, 44], + [50, 52, 53, 54], + [55, 57, 58, 59]]]) + + # axis=0 + a = compress_nd(x, 0) + assert_equal(a, [[[ 0, 1, 2, 3, 4], + [ 5, 6, 7, 8, 9], + [10, 11, 12, 13, 14], + [15, 16, 17, 18, 19]], + [[40, 41, 42, 43, 44], + [45, 46, 47, 48, 49], + [50, 51, 52, 53, 54], + [55, 56, 57, 58, 59]]]) + + # axis=1 + a = compress_nd(x, 1) + assert_equal(a, [[[ 0, 1, 2, 3, 4], + [10, 11, 12, 13, 14], + [15, 16, 17, 18, 19]], + [[20, 21, 22, 23, 24], + [30, 31, 32, 33, 34], + [35, 36, 37, 38, 39]], + [[40, 41, 42, 43, 44], + [50, 51, 52, 53, 54], + [55, 56, 57, 58, 59]]]) + + a2 = compress_nd(x, (1,)) + a3 = compress_nd(x, -2) + a4 = compress_nd(x, (-2,)) + assert_equal(a, a2) + assert_equal(a, a3) + assert_equal(a, a4) + + # axis=2 + a = compress_nd(x, 2) + assert_equal(a, [[[ 0, 2, 3, 4], + [ 5, 7, 8, 9], + [10, 12, 13, 14], + [15, 17, 18, 19]], + [[20, 22, 23, 24], + [25, 27, 28, 29], + [30, 32, 33, 34], + [35, 37, 38, 39]], + [[40, 42, 43, 44], + [45, 47, 48, 49], + [50, 52, 53, 54], + [55, 57, 58, 59]]]) + + a2 = compress_nd(x, (2,)) + a3 = compress_nd(x, -1) + a4 = compress_nd(x, (-1,)) + assert_equal(a, a2) + assert_equal(a, a3) + assert_equal(a, a4) + + # axis=(0, 1) + a = compress_nd(x, (0, 1)) + assert_equal(a, [[[ 0, 1, 2, 3, 4], + [10, 11, 12, 13, 14], + [15, 16, 17, 18, 19]], + [[40, 41, 42, 43, 44], + [50, 51, 52, 53, 54], + [55, 56, 57, 58, 59]]]) + a2 = compress_nd(x, (0, -2)) + assert_equal(a, a2) + + # axis=(1, 2) + a = compress_nd(x, (1, 2)) + assert_equal(a, [[[ 0, 2, 3, 4], + [10, 12, 13, 14], + [15, 17, 18, 19]], + [[20, 22, 23, 24], + [30, 32, 33, 34], + [35, 37, 38, 39]], + [[40, 42, 43, 44], + [50, 52, 53, 54], + [55, 57, 58, 59]]]) + + a2 = compress_nd(x, (-2, 2)) + a3 = compress_nd(x, (1, -1)) + a4 = compress_nd(x, (-2, -1)) + assert_equal(a, a2) + assert_equal(a, a3) + assert_equal(a, a4) + + # axis=(0, 2) + a = compress_nd(x, (0, 2)) + assert_equal(a, [[[ 0, 2, 3, 4], + [ 5, 7, 8, 9], + [10, 12, 13, 14], + [15, 17, 18, 19]], + [[40, 42, 43, 44], + [45, 47, 48, 49], + [50, 52, 53, 54], + [55, 57, 58, 59]]]) + + a2 = compress_nd(x, (0, -1)) + assert_equal(a, a2) + + def test_compress_rowcols(self): + # Tests compress_rowcols + x = array(np.arange(9).reshape(3, 3), + mask=[[1, 0, 0], [0, 0, 0], [0, 0, 0]]) + assert_equal(compress_rowcols(x), [[4, 5], [7, 8]]) + assert_equal(compress_rowcols(x, 0), [[3, 4, 5], [6, 7, 8]]) + assert_equal(compress_rowcols(x, 1), [[1, 2], [4, 5], [7, 8]]) + x = array(x._data, mask=[[0, 0, 0], [0, 1, 0], [0, 0, 0]]) + assert_equal(compress_rowcols(x), [[0, 2], [6, 8]]) + assert_equal(compress_rowcols(x, 0), [[0, 1, 2], [6, 7, 8]]) + assert_equal(compress_rowcols(x, 1), [[0, 2], [3, 5], [6, 8]]) + x = array(x._data, mask=[[1, 0, 0], [0, 1, 0], [0, 0, 0]]) + assert_equal(compress_rowcols(x), [[8]]) + assert_equal(compress_rowcols(x, 0), [[6, 7, 8]]) + assert_equal(compress_rowcols(x, 1,), [[2], [5], [8]]) + x = array(x._data, mask=[[1, 0, 0], [0, 1, 0], [0, 0, 1]]) + assert_equal(compress_rowcols(x).size, 0) + assert_equal(compress_rowcols(x, 0).size, 0) + assert_equal(compress_rowcols(x, 1).size, 0) + + def test_mask_rowcols(self): + # Tests mask_rowcols. + x = array(np.arange(9).reshape(3, 3), + mask=[[1, 0, 0], [0, 0, 0], [0, 0, 0]]) + assert_equal(mask_rowcols(x).mask, + [[1, 1, 1], [1, 0, 0], [1, 0, 0]]) + assert_equal(mask_rowcols(x, 0).mask, + [[1, 1, 1], [0, 0, 0], [0, 0, 0]]) + assert_equal(mask_rowcols(x, 1).mask, + [[1, 0, 0], [1, 0, 0], [1, 0, 0]]) + x = array(x._data, mask=[[0, 0, 0], [0, 1, 0], [0, 0, 0]]) + assert_equal(mask_rowcols(x).mask, + [[0, 1, 0], [1, 1, 1], [0, 1, 0]]) + assert_equal(mask_rowcols(x, 0).mask, + [[0, 0, 0], [1, 1, 1], [0, 0, 0]]) + assert_equal(mask_rowcols(x, 1).mask, + [[0, 1, 0], [0, 1, 0], [0, 1, 0]]) + x = array(x._data, mask=[[1, 0, 0], [0, 1, 0], [0, 0, 0]]) + assert_equal(mask_rowcols(x).mask, + [[1, 1, 1], [1, 1, 1], [1, 1, 0]]) + assert_equal(mask_rowcols(x, 0).mask, + [[1, 1, 1], [1, 1, 1], [0, 0, 0]]) + assert_equal(mask_rowcols(x, 1,).mask, + [[1, 1, 0], [1, 1, 0], [1, 1, 0]]) + x = array(x._data, mask=[[1, 0, 0], [0, 1, 0], [0, 0, 1]]) + assert_(mask_rowcols(x).all() is masked) + assert_(mask_rowcols(x, 0).all() is masked) + assert_(mask_rowcols(x, 1).all() is masked) + assert_(mask_rowcols(x).mask.all()) + assert_(mask_rowcols(x, 0).mask.all()) + assert_(mask_rowcols(x, 1).mask.all()) + + @pytest.mark.parametrize("axis", [None, 0, 1]) + @pytest.mark.parametrize(["func", "rowcols_axis"], + [(np.ma.mask_rows, 0), (np.ma.mask_cols, 1)]) + def test_mask_row_cols_axis_deprecation(self, axis, func, rowcols_axis): + # Test deprecation of the axis argument to `mask_rows` and `mask_cols` + x = array(np.arange(9).reshape(3, 3), + mask=[[1, 0, 0], [0, 0, 0], [0, 0, 0]]) + + with assert_warns(DeprecationWarning): + res = func(x, axis=axis) + assert_equal(res, mask_rowcols(x, rowcols_axis)) + + def test_dot(self): + # Tests dot product + n = np.arange(1, 7) + # + m = [1, 0, 0, 0, 0, 0] + a = masked_array(n, mask=m).reshape(2, 3) + b = masked_array(n, mask=m).reshape(3, 2) + c = dot(a, b, strict=True) + assert_equal(c.mask, [[1, 1], [1, 0]]) + c = dot(b, a, strict=True) + assert_equal(c.mask, [[1, 1, 1], [1, 0, 0], [1, 0, 0]]) + c = dot(a, b, strict=False) + assert_equal(c, np.dot(a.filled(0), b.filled(0))) + c = dot(b, a, strict=False) + assert_equal(c, np.dot(b.filled(0), a.filled(0))) + # + m = [0, 0, 0, 0, 0, 1] + a = masked_array(n, mask=m).reshape(2, 3) + b = masked_array(n, mask=m).reshape(3, 2) + c = dot(a, b, strict=True) + assert_equal(c.mask, [[0, 1], [1, 1]]) + c = dot(b, a, strict=True) + assert_equal(c.mask, [[0, 0, 1], [0, 0, 1], [1, 1, 1]]) + c = dot(a, b, strict=False) + assert_equal(c, np.dot(a.filled(0), b.filled(0))) + assert_equal(c, dot(a, b)) + c = dot(b, a, strict=False) + assert_equal(c, np.dot(b.filled(0), a.filled(0))) + # + m = [0, 0, 0, 0, 0, 0] + a = masked_array(n, mask=m).reshape(2, 3) + b = masked_array(n, mask=m).reshape(3, 2) + c = dot(a, b) + assert_equal(c.mask, nomask) + c = dot(b, a) + assert_equal(c.mask, nomask) + # + a = masked_array(n, mask=[1, 0, 0, 0, 0, 0]).reshape(2, 3) + b = masked_array(n, mask=[0, 0, 0, 0, 0, 0]).reshape(3, 2) + c = dot(a, b, strict=True) + assert_equal(c.mask, [[1, 1], [0, 0]]) + c = dot(a, b, strict=False) + assert_equal(c, np.dot(a.filled(0), b.filled(0))) + c = dot(b, a, strict=True) + assert_equal(c.mask, [[1, 0, 0], [1, 0, 0], [1, 0, 0]]) + c = dot(b, a, strict=False) + assert_equal(c, np.dot(b.filled(0), a.filled(0))) + # + a = masked_array(n, mask=[0, 0, 0, 0, 0, 1]).reshape(2, 3) + b = masked_array(n, mask=[0, 0, 0, 0, 0, 0]).reshape(3, 2) + c = dot(a, b, strict=True) + assert_equal(c.mask, [[0, 0], [1, 1]]) + c = dot(a, b) + assert_equal(c, np.dot(a.filled(0), b.filled(0))) + c = dot(b, a, strict=True) + assert_equal(c.mask, [[0, 0, 1], [0, 0, 1], [0, 0, 1]]) + c = dot(b, a, strict=False) + assert_equal(c, np.dot(b.filled(0), a.filled(0))) + # + a = masked_array(n, mask=[0, 0, 0, 0, 0, 1]).reshape(2, 3) + b = masked_array(n, mask=[0, 0, 1, 0, 0, 0]).reshape(3, 2) + c = dot(a, b, strict=True) + assert_equal(c.mask, [[1, 0], [1, 1]]) + c = dot(a, b, strict=False) + assert_equal(c, np.dot(a.filled(0), b.filled(0))) + c = dot(b, a, strict=True) + assert_equal(c.mask, [[0, 0, 1], [1, 1, 1], [0, 0, 1]]) + c = dot(b, a, strict=False) + assert_equal(c, np.dot(b.filled(0), a.filled(0))) + + def test_dot_returns_maskedarray(self): + # See gh-6611 + a = np.eye(3) + b = array(a) + assert_(type(dot(a, a)) is MaskedArray) + assert_(type(dot(a, b)) is MaskedArray) + assert_(type(dot(b, a)) is MaskedArray) + assert_(type(dot(b, b)) is MaskedArray) + + def test_dot_out(self): + a = array(np.eye(3)) + out = array(np.zeros((3, 3))) + res = dot(a, a, out=out) + assert_(res is out) + assert_equal(a, res) + + +class TestApplyAlongAxis: + # Tests 2D functions + def test_3d(self): + a = arange(12.).reshape(2, 2, 3) + + def myfunc(b): + return b[1] + + xa = apply_along_axis(myfunc, 2, a) + assert_equal(xa, [[1, 4], [7, 10]]) + + # Tests kwargs functions + def test_3d_kwargs(self): + a = arange(12).reshape(2, 2, 3) + + def myfunc(b, offset=0): + return b[1+offset] + + xa = apply_along_axis(myfunc, 2, a, offset=1) + assert_equal(xa, [[2, 5], [8, 11]]) + + +class TestApplyOverAxes: + # Tests apply_over_axes + def test_basic(self): + a = arange(24).reshape(2, 3, 4) + test = apply_over_axes(np.sum, a, [0, 2]) + ctrl = np.array([[[60], [92], [124]]]) + assert_equal(test, ctrl) + a[(a % 2).astype(bool)] = masked + test = apply_over_axes(np.sum, a, [0, 2]) + ctrl = np.array([[[28], [44], [60]]]) + assert_equal(test, ctrl) + + +class TestMedian: + def test_pytype(self): + r = np.ma.median([[np.inf, np.inf], [np.inf, np.inf]], axis=-1) + assert_equal(r, np.inf) + + def test_inf(self): + # test that even which computes handles inf / x = masked + r = np.ma.median(np.ma.masked_array([[np.inf, np.inf], + [np.inf, np.inf]]), axis=-1) + assert_equal(r, np.inf) + r = np.ma.median(np.ma.masked_array([[np.inf, np.inf], + [np.inf, np.inf]]), axis=None) + assert_equal(r, np.inf) + # all masked + r = np.ma.median(np.ma.masked_array([[np.inf, np.inf], + [np.inf, np.inf]], mask=True), + axis=-1) + assert_equal(r.mask, True) + r = np.ma.median(np.ma.masked_array([[np.inf, np.inf], + [np.inf, np.inf]], mask=True), + axis=None) + assert_equal(r.mask, True) + + def test_non_masked(self): + x = np.arange(9) + assert_equal(np.ma.median(x), 4.) + assert_(type(np.ma.median(x)) is not MaskedArray) + x = range(8) + assert_equal(np.ma.median(x), 3.5) + assert_(type(np.ma.median(x)) is not MaskedArray) + x = 5 + assert_equal(np.ma.median(x), 5.) + assert_(type(np.ma.median(x)) is not MaskedArray) + # integer + x = np.arange(9 * 8).reshape(9, 8) + assert_equal(np.ma.median(x, axis=0), np.median(x, axis=0)) + assert_equal(np.ma.median(x, axis=1), np.median(x, axis=1)) + assert_(np.ma.median(x, axis=1) is not MaskedArray) + # float + x = np.arange(9 * 8.).reshape(9, 8) + assert_equal(np.ma.median(x, axis=0), np.median(x, axis=0)) + assert_equal(np.ma.median(x, axis=1), np.median(x, axis=1)) + assert_(np.ma.median(x, axis=1) is not MaskedArray) + + def test_docstring_examples(self): + "test the examples given in the docstring of ma.median" + x = array(np.arange(8), mask=[0]*4 + [1]*4) + assert_equal(np.ma.median(x), 1.5) + assert_equal(np.ma.median(x).shape, (), "shape mismatch") + assert_(type(np.ma.median(x)) is not MaskedArray) + x = array(np.arange(10).reshape(2, 5), mask=[0]*6 + [1]*4) + assert_equal(np.ma.median(x), 2.5) + assert_equal(np.ma.median(x).shape, (), "shape mismatch") + assert_(type(np.ma.median(x)) is not MaskedArray) + ma_x = np.ma.median(x, axis=-1, overwrite_input=True) + assert_equal(ma_x, [2., 5.]) + assert_equal(ma_x.shape, (2,), "shape mismatch") + assert_(type(ma_x) is MaskedArray) + + def test_axis_argument_errors(self): + msg = "mask = %s, ndim = %s, axis = %s, overwrite_input = %s" + for ndmin in range(5): + for mask in [False, True]: + x = array(1, ndmin=ndmin, mask=mask) + + # Valid axis values should not raise exception + args = itertools.product(range(-ndmin, ndmin), [False, True]) + for axis, over in args: + try: + np.ma.median(x, axis=axis, overwrite_input=over) + except Exception: + raise AssertionError(msg % (mask, ndmin, axis, over)) + + # Invalid axis values should raise exception + args = itertools.product([-(ndmin + 1), ndmin], [False, True]) + for axis, over in args: + try: + np.ma.median(x, axis=axis, overwrite_input=over) + except np.AxisError: + pass + else: + raise AssertionError(msg % (mask, ndmin, axis, over)) + + def test_masked_0d(self): + # Check values + x = array(1, mask=False) + assert_equal(np.ma.median(x), 1) + x = array(1, mask=True) + assert_equal(np.ma.median(x), np.ma.masked) + + def test_masked_1d(self): + x = array(np.arange(5), mask=True) + assert_equal(np.ma.median(x), np.ma.masked) + assert_equal(np.ma.median(x).shape, (), "shape mismatch") + assert_(type(np.ma.median(x)) is np.ma.core.MaskedConstant) + x = array(np.arange(5), mask=False) + assert_equal(np.ma.median(x), 2.) + assert_equal(np.ma.median(x).shape, (), "shape mismatch") + assert_(type(np.ma.median(x)) is not MaskedArray) + x = array(np.arange(5), mask=[0,1,0,0,0]) + assert_equal(np.ma.median(x), 2.5) + assert_equal(np.ma.median(x).shape, (), "shape mismatch") + assert_(type(np.ma.median(x)) is not MaskedArray) + x = array(np.arange(5), mask=[0,1,1,1,1]) + assert_equal(np.ma.median(x), 0.) + assert_equal(np.ma.median(x).shape, (), "shape mismatch") + assert_(type(np.ma.median(x)) is not MaskedArray) + # integer + x = array(np.arange(5), mask=[0,1,1,0,0]) + assert_equal(np.ma.median(x), 3.) + assert_equal(np.ma.median(x).shape, (), "shape mismatch") + assert_(type(np.ma.median(x)) is not MaskedArray) + # float + x = array(np.arange(5.), mask=[0,1,1,0,0]) + assert_equal(np.ma.median(x), 3.) + assert_equal(np.ma.median(x).shape, (), "shape mismatch") + assert_(type(np.ma.median(x)) is not MaskedArray) + # integer + x = array(np.arange(6), mask=[0,1,1,1,1,0]) + assert_equal(np.ma.median(x), 2.5) + assert_equal(np.ma.median(x).shape, (), "shape mismatch") + assert_(type(np.ma.median(x)) is not MaskedArray) + # float + x = array(np.arange(6.), mask=[0,1,1,1,1,0]) + assert_equal(np.ma.median(x), 2.5) + assert_equal(np.ma.median(x).shape, (), "shape mismatch") + assert_(type(np.ma.median(x)) is not MaskedArray) + + def test_1d_shape_consistency(self): + assert_equal(np.ma.median(array([1,2,3],mask=[0,0,0])).shape, + np.ma.median(array([1,2,3],mask=[0,1,0])).shape ) + + def test_2d(self): + # Tests median w/ 2D + (n, p) = (101, 30) + x = masked_array(np.linspace(-1., 1., n),) + x[:10] = x[-10:] = masked + z = masked_array(np.empty((n, p), dtype=float)) + z[:, 0] = x[:] + idx = np.arange(len(x)) + for i in range(1, p): + np.random.shuffle(idx) + z[:, i] = x[idx] + assert_equal(median(z[:, 0]), 0) + assert_equal(median(z), 0) + assert_equal(median(z, axis=0), np.zeros(p)) + assert_equal(median(z.T, axis=1), np.zeros(p)) + + def test_2d_waxis(self): + # Tests median w/ 2D arrays and different axis. + x = masked_array(np.arange(30).reshape(10, 3)) + x[:3] = x[-3:] = masked + assert_equal(median(x), 14.5) + assert_(type(np.ma.median(x)) is not MaskedArray) + assert_equal(median(x, axis=0), [13.5, 14.5, 15.5]) + assert_(type(np.ma.median(x, axis=0)) is MaskedArray) + assert_equal(median(x, axis=1), [0, 0, 0, 10, 13, 16, 19, 0, 0, 0]) + assert_(type(np.ma.median(x, axis=1)) is MaskedArray) + assert_equal(median(x, axis=1).mask, [1, 1, 1, 0, 0, 0, 0, 1, 1, 1]) + + def test_3d(self): + # Tests median w/ 3D + x = np.ma.arange(24).reshape(3, 4, 2) + x[x % 3 == 0] = masked + assert_equal(median(x, 0), [[12, 9], [6, 15], [12, 9], [18, 15]]) + x.shape = (4, 3, 2) + assert_equal(median(x, 0), [[99, 10], [11, 99], [13, 14]]) + x = np.ma.arange(24).reshape(4, 3, 2) + x[x % 5 == 0] = masked + assert_equal(median(x, 0), [[12, 10], [8, 9], [16, 17]]) + + def test_neg_axis(self): + x = masked_array(np.arange(30).reshape(10, 3)) + x[:3] = x[-3:] = masked + assert_equal(median(x, axis=-1), median(x, axis=1)) + + def test_out_1d(self): + # integer float even odd + for v in (30, 30., 31, 31.): + x = masked_array(np.arange(v)) + x[:3] = x[-3:] = masked + out = masked_array(np.ones(())) + r = median(x, out=out) + if v == 30: + assert_equal(out, 14.5) + else: + assert_equal(out, 15.) + assert_(r is out) + assert_(type(r) is MaskedArray) + + def test_out(self): + # integer float even odd + for v in (40, 40., 30, 30.): + x = masked_array(np.arange(v).reshape(10, -1)) + x[:3] = x[-3:] = masked + out = masked_array(np.ones(10)) + r = median(x, axis=1, out=out) + if v == 30: + e = masked_array([0.]*3 + [10, 13, 16, 19] + [0.]*3, + mask=[True] * 3 + [False] * 4 + [True] * 3) + else: + e = masked_array([0.]*3 + [13.5, 17.5, 21.5, 25.5] + [0.]*3, + mask=[True]*3 + [False]*4 + [True]*3) + assert_equal(r, e) + assert_(r is out) + assert_(type(r) is MaskedArray) + + def test_single_non_masked_value_on_axis(self): + data = [[1., 0.], + [0., 3.], + [0., 0.]] + masked_arr = np.ma.masked_equal(data, 0) + expected = [1., 3.] + assert_array_equal(np.ma.median(masked_arr, axis=0), + expected) + + def test_nan(self): + for mask in (False, np.zeros(6, dtype=bool)): + dm = np.ma.array([[1, np.nan, 3], [1, 2, 3]]) + dm.mask = mask + + # scalar result + r = np.ma.median(dm, axis=None) + assert_(np.isscalar(r)) + assert_array_equal(r, np.nan) + r = np.ma.median(dm.ravel(), axis=0) + assert_(np.isscalar(r)) + assert_array_equal(r, np.nan) + + r = np.ma.median(dm, axis=0) + assert_equal(type(r), MaskedArray) + assert_array_equal(r, [1, np.nan, 3]) + r = np.ma.median(dm, axis=1) + assert_equal(type(r), MaskedArray) + assert_array_equal(r, [np.nan, 2]) + r = np.ma.median(dm, axis=-1) + assert_equal(type(r), MaskedArray) + assert_array_equal(r, [np.nan, 2]) + + dm = np.ma.array([[1, np.nan, 3], [1, 2, 3]]) + dm[:, 2] = np.ma.masked + assert_array_equal(np.ma.median(dm, axis=None), np.nan) + assert_array_equal(np.ma.median(dm, axis=0), [1, np.nan, 3]) + assert_array_equal(np.ma.median(dm, axis=1), [np.nan, 1.5]) + + def test_out_nan(self): + o = np.ma.masked_array(np.zeros((4,))) + d = np.ma.masked_array(np.ones((3, 4))) + d[2, 1] = np.nan + d[2, 2] = np.ma.masked + assert_equal(np.ma.median(d, 0, out=o), o) + o = np.ma.masked_array(np.zeros((3,))) + assert_equal(np.ma.median(d, 1, out=o), o) + o = np.ma.masked_array(np.zeros(())) + assert_equal(np.ma.median(d, out=o), o) + + def test_nan_behavior(self): + a = np.ma.masked_array(np.arange(24, dtype=float)) + a[::3] = np.ma.masked + a[2] = np.nan + assert_array_equal(np.ma.median(a), np.nan) + assert_array_equal(np.ma.median(a, axis=0), np.nan) + + a = np.ma.masked_array(np.arange(24, dtype=float).reshape(2, 3, 4)) + a.mask = np.arange(a.size) % 2 == 1 + aorig = a.copy() + a[1, 2, 3] = np.nan + a[1, 1, 2] = np.nan + + # no axis + assert_array_equal(np.ma.median(a), np.nan) + assert_(np.isscalar(np.ma.median(a))) + + # axis0 + b = np.ma.median(aorig, axis=0) + b[2, 3] = np.nan + b[1, 2] = np.nan + assert_equal(np.ma.median(a, 0), b) + + # axis1 + b = np.ma.median(aorig, axis=1) + b[1, 3] = np.nan + b[1, 2] = np.nan + assert_equal(np.ma.median(a, 1), b) + + # axis02 + b = np.ma.median(aorig, axis=(0, 2)) + b[1] = np.nan + b[2] = np.nan + assert_equal(np.ma.median(a, (0, 2)), b) + + def test_ambigous_fill(self): + # 255 is max value, used as filler for sort + a = np.array([[3, 3, 255], [3, 3, 255]], dtype=np.uint8) + a = np.ma.masked_array(a, mask=a == 3) + assert_array_equal(np.ma.median(a, axis=1), 255) + assert_array_equal(np.ma.median(a, axis=1).mask, False) + assert_array_equal(np.ma.median(a, axis=0), a[0]) + assert_array_equal(np.ma.median(a), 255) + + def test_special(self): + for inf in [np.inf, -np.inf]: + a = np.array([[inf, np.nan], [np.nan, np.nan]]) + a = np.ma.masked_array(a, mask=np.isnan(a)) + assert_equal(np.ma.median(a, axis=0), [inf, np.nan]) + assert_equal(np.ma.median(a, axis=1), [inf, np.nan]) + assert_equal(np.ma.median(a), inf) + + a = np.array([[np.nan, np.nan, inf], [np.nan, np.nan, inf]]) + a = np.ma.masked_array(a, mask=np.isnan(a)) + assert_array_equal(np.ma.median(a, axis=1), inf) + assert_array_equal(np.ma.median(a, axis=1).mask, False) + assert_array_equal(np.ma.median(a, axis=0), a[0]) + assert_array_equal(np.ma.median(a), inf) + + # no mask + a = np.array([[inf, inf], [inf, inf]]) + assert_equal(np.ma.median(a), inf) + assert_equal(np.ma.median(a, axis=0), inf) + assert_equal(np.ma.median(a, axis=1), inf) + + a = np.array([[inf, 7, -inf, -9], + [-10, np.nan, np.nan, 5], + [4, np.nan, np.nan, inf]], + dtype=np.float32) + a = np.ma.masked_array(a, mask=np.isnan(a)) + if inf > 0: + assert_equal(np.ma.median(a, axis=0), [4., 7., -inf, 5.]) + assert_equal(np.ma.median(a), 4.5) + else: + assert_equal(np.ma.median(a, axis=0), [-10., 7., -inf, -9.]) + assert_equal(np.ma.median(a), -2.5) + assert_equal(np.ma.median(a, axis=1), [-1., -2.5, inf]) + + for i in range(0, 10): + for j in range(1, 10): + a = np.array([([np.nan] * i) + ([inf] * j)] * 2) + a = np.ma.masked_array(a, mask=np.isnan(a)) + assert_equal(np.ma.median(a), inf) + assert_equal(np.ma.median(a, axis=1), inf) + assert_equal(np.ma.median(a, axis=0), + ([np.nan] * i) + [inf] * j) + + def test_empty(self): + # empty arrays + a = np.ma.masked_array(np.array([], dtype=float)) + with suppress_warnings() as w: + w.record(RuntimeWarning) + assert_array_equal(np.ma.median(a), np.nan) + assert_(w.log[0].category is RuntimeWarning) + + # multiple dimensions + a = np.ma.masked_array(np.array([], dtype=float, ndmin=3)) + # no axis + with suppress_warnings() as w: + w.record(RuntimeWarning) + warnings.filterwarnings('always', '', RuntimeWarning) + assert_array_equal(np.ma.median(a), np.nan) + assert_(w.log[0].category is RuntimeWarning) + + # axis 0 and 1 + b = np.ma.masked_array(np.array([], dtype=float, ndmin=2)) + assert_equal(np.ma.median(a, axis=0), b) + assert_equal(np.ma.median(a, axis=1), b) + + # axis 2 + b = np.ma.masked_array(np.array(np.nan, dtype=float, ndmin=2)) + with warnings.catch_warnings(record=True) as w: + warnings.filterwarnings('always', '', RuntimeWarning) + assert_equal(np.ma.median(a, axis=2), b) + assert_(w[0].category is RuntimeWarning) + + def test_object(self): + o = np.ma.masked_array(np.arange(7.)) + assert_(type(np.ma.median(o.astype(object))), float) + o[2] = np.nan + assert_(type(np.ma.median(o.astype(object))), float) + + +class TestCov: + + def setup(self): + self.data = array(np.random.rand(12)) + + def test_1d_without_missing(self): + # Test cov on 1D variable w/o missing values + x = self.data + assert_almost_equal(np.cov(x), cov(x)) + assert_almost_equal(np.cov(x, rowvar=False), cov(x, rowvar=False)) + assert_almost_equal(np.cov(x, rowvar=False, bias=True), + cov(x, rowvar=False, bias=True)) + + def test_2d_without_missing(self): + # Test cov on 1 2D variable w/o missing values + x = self.data.reshape(3, 4) + assert_almost_equal(np.cov(x), cov(x)) + assert_almost_equal(np.cov(x, rowvar=False), cov(x, rowvar=False)) + assert_almost_equal(np.cov(x, rowvar=False, bias=True), + cov(x, rowvar=False, bias=True)) + + def test_1d_with_missing(self): + # Test cov 1 1D variable w/missing values + x = self.data + x[-1] = masked + x -= x.mean() + nx = x.compressed() + assert_almost_equal(np.cov(nx), cov(x)) + assert_almost_equal(np.cov(nx, rowvar=False), cov(x, rowvar=False)) + assert_almost_equal(np.cov(nx, rowvar=False, bias=True), + cov(x, rowvar=False, bias=True)) + # + try: + cov(x, allow_masked=False) + except ValueError: + pass + # + # 2 1D variables w/ missing values + nx = x[1:-1] + assert_almost_equal(np.cov(nx, nx[::-1]), cov(x, x[::-1])) + assert_almost_equal(np.cov(nx, nx[::-1], rowvar=False), + cov(x, x[::-1], rowvar=False)) + assert_almost_equal(np.cov(nx, nx[::-1], rowvar=False, bias=True), + cov(x, x[::-1], rowvar=False, bias=True)) + + def test_2d_with_missing(self): + # Test cov on 2D variable w/ missing value + x = self.data + x[-1] = masked + x = x.reshape(3, 4) + valid = np.logical_not(getmaskarray(x)).astype(int) + frac = np.dot(valid, valid.T) + xf = (x - x.mean(1)[:, None]).filled(0) + assert_almost_equal(cov(x), + np.cov(xf) * (x.shape[1] - 1) / (frac - 1.)) + assert_almost_equal(cov(x, bias=True), + np.cov(xf, bias=True) * x.shape[1] / frac) + frac = np.dot(valid.T, valid) + xf = (x - x.mean(0)).filled(0) + assert_almost_equal(cov(x, rowvar=False), + (np.cov(xf, rowvar=False) * + (x.shape[0] - 1) / (frac - 1.))) + assert_almost_equal(cov(x, rowvar=False, bias=True), + (np.cov(xf, rowvar=False, bias=True) * + x.shape[0] / frac)) + + +class TestCorrcoef: + + def setup(self): + self.data = array(np.random.rand(12)) + self.data2 = array(np.random.rand(12)) + + def test_ddof(self): + # ddof raises DeprecationWarning + x, y = self.data, self.data2 + expected = np.corrcoef(x) + expected2 = np.corrcoef(x, y) + with suppress_warnings() as sup: + warnings.simplefilter("always") + assert_warns(DeprecationWarning, corrcoef, x, ddof=-1) + sup.filter(DeprecationWarning, "bias and ddof have no effect") + # ddof has no or negligible effect on the function + assert_almost_equal(np.corrcoef(x, ddof=0), corrcoef(x, ddof=0)) + assert_almost_equal(corrcoef(x, ddof=-1), expected) + assert_almost_equal(corrcoef(x, y, ddof=-1), expected2) + assert_almost_equal(corrcoef(x, ddof=3), expected) + assert_almost_equal(corrcoef(x, y, ddof=3), expected2) + + def test_bias(self): + x, y = self.data, self.data2 + expected = np.corrcoef(x) + # bias raises DeprecationWarning + with suppress_warnings() as sup: + warnings.simplefilter("always") + assert_warns(DeprecationWarning, corrcoef, x, y, True, False) + assert_warns(DeprecationWarning, corrcoef, x, y, True, True) + assert_warns(DeprecationWarning, corrcoef, x, bias=False) + sup.filter(DeprecationWarning, "bias and ddof have no effect") + # bias has no or negligible effect on the function + assert_almost_equal(corrcoef(x, bias=1), expected) + + def test_1d_without_missing(self): + # Test cov on 1D variable w/o missing values + x = self.data + assert_almost_equal(np.corrcoef(x), corrcoef(x)) + assert_almost_equal(np.corrcoef(x, rowvar=False), + corrcoef(x, rowvar=False)) + with suppress_warnings() as sup: + sup.filter(DeprecationWarning, "bias and ddof have no effect") + assert_almost_equal(np.corrcoef(x, rowvar=False, bias=True), + corrcoef(x, rowvar=False, bias=True)) + + def test_2d_without_missing(self): + # Test corrcoef on 1 2D variable w/o missing values + x = self.data.reshape(3, 4) + assert_almost_equal(np.corrcoef(x), corrcoef(x)) + assert_almost_equal(np.corrcoef(x, rowvar=False), + corrcoef(x, rowvar=False)) + with suppress_warnings() as sup: + sup.filter(DeprecationWarning, "bias and ddof have no effect") + assert_almost_equal(np.corrcoef(x, rowvar=False, bias=True), + corrcoef(x, rowvar=False, bias=True)) + + def test_1d_with_missing(self): + # Test corrcoef 1 1D variable w/missing values + x = self.data + x[-1] = masked + x -= x.mean() + nx = x.compressed() + assert_almost_equal(np.corrcoef(nx), corrcoef(x)) + assert_almost_equal(np.corrcoef(nx, rowvar=False), + corrcoef(x, rowvar=False)) + with suppress_warnings() as sup: + sup.filter(DeprecationWarning, "bias and ddof have no effect") + assert_almost_equal(np.corrcoef(nx, rowvar=False, bias=True), + corrcoef(x, rowvar=False, bias=True)) + try: + corrcoef(x, allow_masked=False) + except ValueError: + pass + # 2 1D variables w/ missing values + nx = x[1:-1] + assert_almost_equal(np.corrcoef(nx, nx[::-1]), corrcoef(x, x[::-1])) + assert_almost_equal(np.corrcoef(nx, nx[::-1], rowvar=False), + corrcoef(x, x[::-1], rowvar=False)) + with suppress_warnings() as sup: + sup.filter(DeprecationWarning, "bias and ddof have no effect") + # ddof and bias have no or negligible effect on the function + assert_almost_equal(np.corrcoef(nx, nx[::-1]), + corrcoef(x, x[::-1], bias=1)) + assert_almost_equal(np.corrcoef(nx, nx[::-1]), + corrcoef(x, x[::-1], ddof=2)) + + def test_2d_with_missing(self): + # Test corrcoef on 2D variable w/ missing value + x = self.data + x[-1] = masked + x = x.reshape(3, 4) + + test = corrcoef(x) + control = np.corrcoef(x) + assert_almost_equal(test[:-1, :-1], control[:-1, :-1]) + with suppress_warnings() as sup: + sup.filter(DeprecationWarning, "bias and ddof have no effect") + # ddof and bias have no or negligible effect on the function + assert_almost_equal(corrcoef(x, ddof=-2)[:-1, :-1], + control[:-1, :-1]) + assert_almost_equal(corrcoef(x, ddof=3)[:-1, :-1], + control[:-1, :-1]) + assert_almost_equal(corrcoef(x, bias=1)[:-1, :-1], + control[:-1, :-1]) + + +class TestPolynomial: + # + def test_polyfit(self): + # Tests polyfit + # On ndarrays + x = np.random.rand(10) + y = np.random.rand(20).reshape(-1, 2) + assert_almost_equal(polyfit(x, y, 3), np.polyfit(x, y, 3)) + # ON 1D maskedarrays + x = x.view(MaskedArray) + x[0] = masked + y = y.view(MaskedArray) + y[0, 0] = y[-1, -1] = masked + # + (C, R, K, S, D) = polyfit(x, y[:, 0], 3, full=True) + (c, r, k, s, d) = np.polyfit(x[1:], y[1:, 0].compressed(), 3, + full=True) + for (a, a_) in zip((C, R, K, S, D), (c, r, k, s, d)): + assert_almost_equal(a, a_) + # + (C, R, K, S, D) = polyfit(x, y[:, -1], 3, full=True) + (c, r, k, s, d) = np.polyfit(x[1:-1], y[1:-1, -1], 3, full=True) + for (a, a_) in zip((C, R, K, S, D), (c, r, k, s, d)): + assert_almost_equal(a, a_) + # + (C, R, K, S, D) = polyfit(x, y, 3, full=True) + (c, r, k, s, d) = np.polyfit(x[1:-1], y[1:-1,:], 3, full=True) + for (a, a_) in zip((C, R, K, S, D), (c, r, k, s, d)): + assert_almost_equal(a, a_) + # + w = np.random.rand(10) + 1 + wo = w.copy() + xs = x[1:-1] + ys = y[1:-1] + ws = w[1:-1] + (C, R, K, S, D) = polyfit(x, y, 3, full=True, w=w) + (c, r, k, s, d) = np.polyfit(xs, ys, 3, full=True, w=ws) + assert_equal(w, wo) + for (a, a_) in zip((C, R, K, S, D), (c, r, k, s, d)): + assert_almost_equal(a, a_) + + def test_polyfit_with_masked_NaNs(self): + x = np.random.rand(10) + y = np.random.rand(20).reshape(-1, 2) + + x[0] = np.nan + y[-1,-1] = np.nan + x = x.view(MaskedArray) + y = y.view(MaskedArray) + x[0] = masked + y[-1,-1] = masked + + (C, R, K, S, D) = polyfit(x, y, 3, full=True) + (c, r, k, s, d) = np.polyfit(x[1:-1], y[1:-1,:], 3, full=True) + for (a, a_) in zip((C, R, K, S, D), (c, r, k, s, d)): + assert_almost_equal(a, a_) + + +class TestArraySetOps: + + def test_unique_onlist(self): + # Test unique on list + data = [1, 1, 1, 2, 2, 3] + test = unique(data, return_index=True, return_inverse=True) + assert_(isinstance(test[0], MaskedArray)) + assert_equal(test[0], masked_array([1, 2, 3], mask=[0, 0, 0])) + assert_equal(test[1], [0, 3, 5]) + assert_equal(test[2], [0, 0, 0, 1, 1, 2]) + + def test_unique_onmaskedarray(self): + # Test unique on masked data w/use_mask=True + data = masked_array([1, 1, 1, 2, 2, 3], mask=[0, 0, 1, 0, 1, 0]) + test = unique(data, return_index=True, return_inverse=True) + assert_equal(test[0], masked_array([1, 2, 3, -1], mask=[0, 0, 0, 1])) + assert_equal(test[1], [0, 3, 5, 2]) + assert_equal(test[2], [0, 0, 3, 1, 3, 2]) + # + data.fill_value = 3 + data = masked_array(data=[1, 1, 1, 2, 2, 3], + mask=[0, 0, 1, 0, 1, 0], fill_value=3) + test = unique(data, return_index=True, return_inverse=True) + assert_equal(test[0], masked_array([1, 2, 3, -1], mask=[0, 0, 0, 1])) + assert_equal(test[1], [0, 3, 5, 2]) + assert_equal(test[2], [0, 0, 3, 1, 3, 2]) + + def test_unique_allmasked(self): + # Test all masked + data = masked_array([1, 1, 1], mask=True) + test = unique(data, return_index=True, return_inverse=True) + assert_equal(test[0], masked_array([1, ], mask=[True])) + assert_equal(test[1], [0]) + assert_equal(test[2], [0, 0, 0]) + # + # Test masked + data = masked + test = unique(data, return_index=True, return_inverse=True) + assert_equal(test[0], masked_array(masked)) + assert_equal(test[1], [0]) + assert_equal(test[2], [0]) + + def test_ediff1d(self): + # Tests mediff1d + x = masked_array(np.arange(5), mask=[1, 0, 0, 0, 1]) + control = array([1, 1, 1, 4], mask=[1, 0, 0, 1]) + test = ediff1d(x) + assert_equal(test, control) + assert_equal(test.filled(0), control.filled(0)) + assert_equal(test.mask, control.mask) + + def test_ediff1d_tobegin(self): + # Test ediff1d w/ to_begin + x = masked_array(np.arange(5), mask=[1, 0, 0, 0, 1]) + test = ediff1d(x, to_begin=masked) + control = array([0, 1, 1, 1, 4], mask=[1, 1, 0, 0, 1]) + assert_equal(test, control) + assert_equal(test.filled(0), control.filled(0)) + assert_equal(test.mask, control.mask) + # + test = ediff1d(x, to_begin=[1, 2, 3]) + control = array([1, 2, 3, 1, 1, 1, 4], mask=[0, 0, 0, 1, 0, 0, 1]) + assert_equal(test, control) + assert_equal(test.filled(0), control.filled(0)) + assert_equal(test.mask, control.mask) + + def test_ediff1d_toend(self): + # Test ediff1d w/ to_end + x = masked_array(np.arange(5), mask=[1, 0, 0, 0, 1]) + test = ediff1d(x, to_end=masked) + control = array([1, 1, 1, 4, 0], mask=[1, 0, 0, 1, 1]) + assert_equal(test, control) + assert_equal(test.filled(0), control.filled(0)) + assert_equal(test.mask, control.mask) + # + test = ediff1d(x, to_end=[1, 2, 3]) + control = array([1, 1, 1, 4, 1, 2, 3], mask=[1, 0, 0, 1, 0, 0, 0]) + assert_equal(test, control) + assert_equal(test.filled(0), control.filled(0)) + assert_equal(test.mask, control.mask) + + def test_ediff1d_tobegin_toend(self): + # Test ediff1d w/ to_begin and to_end + x = masked_array(np.arange(5), mask=[1, 0, 0, 0, 1]) + test = ediff1d(x, to_end=masked, to_begin=masked) + control = array([0, 1, 1, 1, 4, 0], mask=[1, 1, 0, 0, 1, 1]) + assert_equal(test, control) + assert_equal(test.filled(0), control.filled(0)) + assert_equal(test.mask, control.mask) + # + test = ediff1d(x, to_end=[1, 2, 3], to_begin=masked) + control = array([0, 1, 1, 1, 4, 1, 2, 3], + mask=[1, 1, 0, 0, 1, 0, 0, 0]) + assert_equal(test, control) + assert_equal(test.filled(0), control.filled(0)) + assert_equal(test.mask, control.mask) + + def test_ediff1d_ndarray(self): + # Test ediff1d w/ a ndarray + x = np.arange(5) + test = ediff1d(x) + control = array([1, 1, 1, 1], mask=[0, 0, 0, 0]) + assert_equal(test, control) + assert_(isinstance(test, MaskedArray)) + assert_equal(test.filled(0), control.filled(0)) + assert_equal(test.mask, control.mask) + # + test = ediff1d(x, to_end=masked, to_begin=masked) + control = array([0, 1, 1, 1, 1, 0], mask=[1, 0, 0, 0, 0, 1]) + assert_(isinstance(test, MaskedArray)) + assert_equal(test.filled(0), control.filled(0)) + assert_equal(test.mask, control.mask) + + def test_intersect1d(self): + # Test intersect1d + x = array([1, 3, 3, 3], mask=[0, 0, 0, 1]) + y = array([3, 1, 1, 1], mask=[0, 0, 0, 1]) + test = intersect1d(x, y) + control = array([1, 3, -1], mask=[0, 0, 1]) + assert_equal(test, control) + + def test_setxor1d(self): + # Test setxor1d + a = array([1, 2, 5, 7, -1], mask=[0, 0, 0, 0, 1]) + b = array([1, 2, 3, 4, 5, -1], mask=[0, 0, 0, 0, 0, 1]) + test = setxor1d(a, b) + assert_equal(test, array([3, 4, 7])) + # + a = array([1, 2, 5, 7, -1], mask=[0, 0, 0, 0, 1]) + b = [1, 2, 3, 4, 5] + test = setxor1d(a, b) + assert_equal(test, array([3, 4, 7, -1], mask=[0, 0, 0, 1])) + # + a = array([1, 2, 3]) + b = array([6, 5, 4]) + test = setxor1d(a, b) + assert_(isinstance(test, MaskedArray)) + assert_equal(test, [1, 2, 3, 4, 5, 6]) + # + a = array([1, 8, 2, 3], mask=[0, 1, 0, 0]) + b = array([6, 5, 4, 8], mask=[0, 0, 0, 1]) + test = setxor1d(a, b) + assert_(isinstance(test, MaskedArray)) + assert_equal(test, [1, 2, 3, 4, 5, 6]) + # + assert_array_equal([], setxor1d([], [])) + + def test_isin(self): + # the tests for in1d cover most of isin's behavior + # if in1d is removed, would need to change those tests to test + # isin instead. + a = np.arange(24).reshape([2, 3, 4]) + mask = np.zeros([2, 3, 4]) + mask[1, 2, 0] = 1 + a = array(a, mask=mask) + b = array(data=[0, 10, 20, 30, 1, 3, 11, 22, 33], + mask=[0, 1, 0, 1, 0, 1, 0, 1, 0]) + ec = zeros((2, 3, 4), dtype=bool) + ec[0, 0, 0] = True + ec[0, 0, 1] = True + ec[0, 2, 3] = True + c = isin(a, b) + assert_(isinstance(c, MaskedArray)) + assert_array_equal(c, ec) + #compare results of np.isin to ma.isin + d = np.isin(a, b[~b.mask]) & ~a.mask + assert_array_equal(c, d) + + def test_in1d(self): + # Test in1d + a = array([1, 2, 5, 7, -1], mask=[0, 0, 0, 0, 1]) + b = array([1, 2, 3, 4, 5, -1], mask=[0, 0, 0, 0, 0, 1]) + test = in1d(a, b) + assert_equal(test, [True, True, True, False, True]) + # + a = array([5, 5, 2, 1, -1], mask=[0, 0, 0, 0, 1]) + b = array([1, 5, -1], mask=[0, 0, 1]) + test = in1d(a, b) + assert_equal(test, [True, True, False, True, True]) + # + assert_array_equal([], in1d([], [])) + + def test_in1d_invert(self): + # Test in1d's invert parameter + a = array([1, 2, 5, 7, -1], mask=[0, 0, 0, 0, 1]) + b = array([1, 2, 3, 4, 5, -1], mask=[0, 0, 0, 0, 0, 1]) + assert_equal(np.invert(in1d(a, b)), in1d(a, b, invert=True)) + + a = array([5, 5, 2, 1, -1], mask=[0, 0, 0, 0, 1]) + b = array([1, 5, -1], mask=[0, 0, 1]) + assert_equal(np.invert(in1d(a, b)), in1d(a, b, invert=True)) + + assert_array_equal([], in1d([], [], invert=True)) + + def test_union1d(self): + # Test union1d + a = array([1, 2, 5, 7, 5, -1], mask=[0, 0, 0, 0, 0, 1]) + b = array([1, 2, 3, 4, 5, -1], mask=[0, 0, 0, 0, 0, 1]) + test = union1d(a, b) + control = array([1, 2, 3, 4, 5, 7, -1], mask=[0, 0, 0, 0, 0, 0, 1]) + assert_equal(test, control) + + # Tests gh-10340, arguments to union1d should be + # flattened if they are not already 1D + x = array([[0, 1, 2], [3, 4, 5]], mask=[[0, 0, 0], [0, 0, 1]]) + y = array([0, 1, 2, 3, 4], mask=[0, 0, 0, 0, 1]) + ez = array([0, 1, 2, 3, 4, 5], mask=[0, 0, 0, 0, 0, 1]) + z = union1d(x, y) + assert_equal(z, ez) + # + assert_array_equal([], union1d([], [])) + + def test_setdiff1d(self): + # Test setdiff1d + a = array([6, 5, 4, 7, 7, 1, 2, 1], mask=[0, 0, 0, 0, 0, 0, 0, 1]) + b = array([2, 4, 3, 3, 2, 1, 5]) + test = setdiff1d(a, b) + assert_equal(test, array([6, 7, -1], mask=[0, 0, 1])) + # + a = arange(10) + b = arange(8) + assert_equal(setdiff1d(a, b), array([8, 9])) + a = array([], np.uint32, mask=[]) + assert_equal(setdiff1d(a, []).dtype, np.uint32) + + def test_setdiff1d_char_array(self): + # Test setdiff1d_charray + a = np.array(['a', 'b', 'c']) + b = np.array(['a', 'b', 's']) + assert_array_equal(setdiff1d(a, b), np.array(['c'])) + + +class TestShapeBase: + + def test_atleast_2d(self): + # Test atleast_2d + a = masked_array([0, 1, 2], mask=[0, 1, 0]) + b = atleast_2d(a) + assert_equal(b.shape, (1, 3)) + assert_equal(b.mask.shape, b.data.shape) + assert_equal(a.shape, (3,)) + assert_equal(a.mask.shape, a.data.shape) + assert_equal(b.mask.shape, b.data.shape) + + def test_shape_scalar(self): + # the atleast and diagflat function should work with scalars + # GitHub issue #3367 + # Additionally, the atleast functions should accept multiple scalars + # correctly + b = atleast_1d(1.0) + assert_equal(b.shape, (1,)) + assert_equal(b.mask.shape, b.shape) + assert_equal(b.data.shape, b.shape) + + b = atleast_1d(1.0, 2.0) + for a in b: + assert_equal(a.shape, (1,)) + assert_equal(a.mask.shape, a.shape) + assert_equal(a.data.shape, a.shape) + + b = atleast_2d(1.0) + assert_equal(b.shape, (1, 1)) + assert_equal(b.mask.shape, b.shape) + assert_equal(b.data.shape, b.shape) + + b = atleast_2d(1.0, 2.0) + for a in b: + assert_equal(a.shape, (1, 1)) + assert_equal(a.mask.shape, a.shape) + assert_equal(a.data.shape, a.shape) + + b = atleast_3d(1.0) + assert_equal(b.shape, (1, 1, 1)) + assert_equal(b.mask.shape, b.shape) + assert_equal(b.data.shape, b.shape) + + b = atleast_3d(1.0, 2.0) + for a in b: + assert_equal(a.shape, (1, 1, 1)) + assert_equal(a.mask.shape, a.shape) + assert_equal(a.data.shape, a.shape) + + + b = diagflat(1.0) + assert_equal(b.shape, (1, 1)) + assert_equal(b.mask.shape, b.data.shape) + + +class TestStack: + + def test_stack_1d(self): + a = masked_array([0, 1, 2], mask=[0, 1, 0]) + b = masked_array([9, 8, 7], mask=[1, 0, 0]) + + c = stack([a, b], axis=0) + assert_equal(c.shape, (2, 3)) + assert_array_equal(a.mask, c[0].mask) + assert_array_equal(b.mask, c[1].mask) + + d = vstack([a, b]) + assert_array_equal(c.data, d.data) + assert_array_equal(c.mask, d.mask) + + c = stack([a, b], axis=1) + assert_equal(c.shape, (3, 2)) + assert_array_equal(a.mask, c[:, 0].mask) + assert_array_equal(b.mask, c[:, 1].mask) + + def test_stack_masks(self): + a = masked_array([0, 1, 2], mask=True) + b = masked_array([9, 8, 7], mask=False) + + c = stack([a, b], axis=0) + assert_equal(c.shape, (2, 3)) + assert_array_equal(a.mask, c[0].mask) + assert_array_equal(b.mask, c[1].mask) + + d = vstack([a, b]) + assert_array_equal(c.data, d.data) + assert_array_equal(c.mask, d.mask) + + c = stack([a, b], axis=1) + assert_equal(c.shape, (3, 2)) + assert_array_equal(a.mask, c[:, 0].mask) + assert_array_equal(b.mask, c[:, 1].mask) + + def test_stack_nd(self): + # 2D + shp = (3, 2) + d1 = np.random.randint(0, 10, shp) + d2 = np.random.randint(0, 10, shp) + m1 = np.random.randint(0, 2, shp).astype(bool) + m2 = np.random.randint(0, 2, shp).astype(bool) + a1 = masked_array(d1, mask=m1) + a2 = masked_array(d2, mask=m2) + + c = stack([a1, a2], axis=0) + c_shp = (2,) + shp + assert_equal(c.shape, c_shp) + assert_array_equal(a1.mask, c[0].mask) + assert_array_equal(a2.mask, c[1].mask) + + c = stack([a1, a2], axis=-1) + c_shp = shp + (2,) + assert_equal(c.shape, c_shp) + assert_array_equal(a1.mask, c[..., 0].mask) + assert_array_equal(a2.mask, c[..., 1].mask) + + # 4D + shp = (3, 2, 4, 5,) + d1 = np.random.randint(0, 10, shp) + d2 = np.random.randint(0, 10, shp) + m1 = np.random.randint(0, 2, shp).astype(bool) + m2 = np.random.randint(0, 2, shp).astype(bool) + a1 = masked_array(d1, mask=m1) + a2 = masked_array(d2, mask=m2) + + c = stack([a1, a2], axis=0) + c_shp = (2,) + shp + assert_equal(c.shape, c_shp) + assert_array_equal(a1.mask, c[0].mask) + assert_array_equal(a2.mask, c[1].mask) + + c = stack([a1, a2], axis=-1) + c_shp = shp + (2,) + assert_equal(c.shape, c_shp) + assert_array_equal(a1.mask, c[..., 0].mask) + assert_array_equal(a2.mask, c[..., 1].mask) diff --git a/venv/Lib/site-packages/numpy/ma/tests/test_mrecords.py b/venv/Lib/site-packages/numpy/ma/tests/test_mrecords.py new file mode 100644 index 0000000..c2f8592 --- /dev/null +++ b/venv/Lib/site-packages/numpy/ma/tests/test_mrecords.py @@ -0,0 +1,493 @@ +# pylint: disable-msg=W0611, W0612, W0511,R0201 +"""Tests suite for mrecords. + +:author: Pierre Gerard-Marchant +:contact: pierregm_at_uga_dot_edu + +""" +import numpy as np +import numpy.ma as ma +from numpy import recarray +from numpy.ma import masked, nomask +from numpy.testing import temppath +from numpy.core.records import ( + fromrecords as recfromrecords, fromarrays as recfromarrays + ) +from numpy.ma.mrecords import ( + MaskedRecords, mrecarray, fromarrays, fromtextfile, fromrecords, + addfield + ) +from numpy.ma.testutils import ( + assert_, assert_equal, + assert_equal_records, + ) +from numpy.compat import pickle + + +class TestMRecords: + + ilist = [1, 2, 3, 4, 5] + flist = [1.1, 2.2, 3.3, 4.4, 5.5] + slist = [b'one', b'two', b'three', b'four', b'five'] + ddtype = [('a', int), ('b', float), ('c', '|S8')] + mask = [0, 1, 0, 0, 1] + base = ma.array(list(zip(ilist, flist, slist)), mask=mask, dtype=ddtype) + + def test_byview(self): + # Test creation by view + base = self.base + mbase = base.view(mrecarray) + assert_equal(mbase.recordmask, base.recordmask) + assert_equal_records(mbase._mask, base._mask) + assert_(isinstance(mbase._data, recarray)) + assert_equal_records(mbase._data, base._data.view(recarray)) + for field in ('a', 'b', 'c'): + assert_equal(base[field], mbase[field]) + assert_equal_records(mbase.view(mrecarray), mbase) + + def test_get(self): + # Tests fields retrieval + base = self.base.copy() + mbase = base.view(mrecarray) + # As fields.......... + for field in ('a', 'b', 'c'): + assert_equal(getattr(mbase, field), mbase[field]) + assert_equal(base[field], mbase[field]) + # as elements ....... + mbase_first = mbase[0] + assert_(isinstance(mbase_first, mrecarray)) + assert_equal(mbase_first.dtype, mbase.dtype) + assert_equal(mbase_first.tolist(), (1, 1.1, b'one')) + # Used to be mask, now it's recordmask + assert_equal(mbase_first.recordmask, nomask) + assert_equal(mbase_first._mask.item(), (False, False, False)) + assert_equal(mbase_first['a'], mbase['a'][0]) + mbase_last = mbase[-1] + assert_(isinstance(mbase_last, mrecarray)) + assert_equal(mbase_last.dtype, mbase.dtype) + assert_equal(mbase_last.tolist(), (None, None, None)) + # Used to be mask, now it's recordmask + assert_equal(mbase_last.recordmask, True) + assert_equal(mbase_last._mask.item(), (True, True, True)) + assert_equal(mbase_last['a'], mbase['a'][-1]) + assert_((mbase_last['a'] is masked)) + # as slice .......... + mbase_sl = mbase[:2] + assert_(isinstance(mbase_sl, mrecarray)) + assert_equal(mbase_sl.dtype, mbase.dtype) + # Used to be mask, now it's recordmask + assert_equal(mbase_sl.recordmask, [0, 1]) + assert_equal_records(mbase_sl.mask, + np.array([(False, False, False), + (True, True, True)], + dtype=mbase._mask.dtype)) + assert_equal_records(mbase_sl, base[:2].view(mrecarray)) + for field in ('a', 'b', 'c'): + assert_equal(getattr(mbase_sl, field), base[:2][field]) + + def test_set_fields(self): + # Tests setting fields. + base = self.base.copy() + mbase = base.view(mrecarray) + mbase = mbase.copy() + mbase.fill_value = (999999, 1e20, 'N/A') + # Change the data, the mask should be conserved + mbase.a._data[:] = 5 + assert_equal(mbase['a']._data, [5, 5, 5, 5, 5]) + assert_equal(mbase['a']._mask, [0, 1, 0, 0, 1]) + # Change the elements, and the mask will follow + mbase.a = 1 + assert_equal(mbase['a']._data, [1]*5) + assert_equal(ma.getmaskarray(mbase['a']), [0]*5) + # Use to be _mask, now it's recordmask + assert_equal(mbase.recordmask, [False]*5) + assert_equal(mbase._mask.tolist(), + np.array([(0, 0, 0), + (0, 1, 1), + (0, 0, 0), + (0, 0, 0), + (0, 1, 1)], + dtype=bool)) + # Set a field to mask ........................ + mbase.c = masked + # Use to be mask, and now it's still mask ! + assert_equal(mbase.c.mask, [1]*5) + assert_equal(mbase.c.recordmask, [1]*5) + assert_equal(ma.getmaskarray(mbase['c']), [1]*5) + assert_equal(ma.getdata(mbase['c']), [b'N/A']*5) + assert_equal(mbase._mask.tolist(), + np.array([(0, 0, 1), + (0, 1, 1), + (0, 0, 1), + (0, 0, 1), + (0, 1, 1)], + dtype=bool)) + # Set fields by slices ....................... + mbase = base.view(mrecarray).copy() + mbase.a[3:] = 5 + assert_equal(mbase.a, [1, 2, 3, 5, 5]) + assert_equal(mbase.a._mask, [0, 1, 0, 0, 0]) + mbase.b[3:] = masked + assert_equal(mbase.b, base['b']) + assert_equal(mbase.b._mask, [0, 1, 0, 1, 1]) + # Set fields globally.......................... + ndtype = [('alpha', '|S1'), ('num', int)] + data = ma.array([('a', 1), ('b', 2), ('c', 3)], dtype=ndtype) + rdata = data.view(MaskedRecords) + val = ma.array([10, 20, 30], mask=[1, 0, 0]) + + rdata['num'] = val + assert_equal(rdata.num, val) + assert_equal(rdata.num.mask, [1, 0, 0]) + + def test_set_fields_mask(self): + # Tests setting the mask of a field. + base = self.base.copy() + # This one has already a mask.... + mbase = base.view(mrecarray) + mbase['a'][-2] = masked + assert_equal(mbase.a, [1, 2, 3, 4, 5]) + assert_equal(mbase.a._mask, [0, 1, 0, 1, 1]) + # This one has not yet + mbase = fromarrays([np.arange(5), np.random.rand(5)], + dtype=[('a', int), ('b', float)]) + mbase['a'][-2] = masked + assert_equal(mbase.a, [0, 1, 2, 3, 4]) + assert_equal(mbase.a._mask, [0, 0, 0, 1, 0]) + + def test_set_mask(self): + base = self.base.copy() + mbase = base.view(mrecarray) + # Set the mask to True ....................... + mbase.mask = masked + assert_equal(ma.getmaskarray(mbase['b']), [1]*5) + assert_equal(mbase['a']._mask, mbase['b']._mask) + assert_equal(mbase['a']._mask, mbase['c']._mask) + assert_equal(mbase._mask.tolist(), + np.array([(1, 1, 1)]*5, dtype=bool)) + # Delete the mask ............................ + mbase.mask = nomask + assert_equal(ma.getmaskarray(mbase['c']), [0]*5) + assert_equal(mbase._mask.tolist(), + np.array([(0, 0, 0)]*5, dtype=bool)) + + def test_set_mask_fromarray(self): + base = self.base.copy() + mbase = base.view(mrecarray) + # Sets the mask w/ an array + mbase.mask = [1, 0, 0, 0, 1] + assert_equal(mbase.a.mask, [1, 0, 0, 0, 1]) + assert_equal(mbase.b.mask, [1, 0, 0, 0, 1]) + assert_equal(mbase.c.mask, [1, 0, 0, 0, 1]) + # Yay, once more ! + mbase.mask = [0, 0, 0, 0, 1] + assert_equal(mbase.a.mask, [0, 0, 0, 0, 1]) + assert_equal(mbase.b.mask, [0, 0, 0, 0, 1]) + assert_equal(mbase.c.mask, [0, 0, 0, 0, 1]) + + def test_set_mask_fromfields(self): + mbase = self.base.copy().view(mrecarray) + + nmask = np.array( + [(0, 1, 0), (0, 1, 0), (1, 0, 1), (1, 0, 1), (0, 0, 0)], + dtype=[('a', bool), ('b', bool), ('c', bool)]) + mbase.mask = nmask + assert_equal(mbase.a.mask, [0, 0, 1, 1, 0]) + assert_equal(mbase.b.mask, [1, 1, 0, 0, 0]) + assert_equal(mbase.c.mask, [0, 0, 1, 1, 0]) + # Reinitialize and redo + mbase.mask = False + mbase.fieldmask = nmask + assert_equal(mbase.a.mask, [0, 0, 1, 1, 0]) + assert_equal(mbase.b.mask, [1, 1, 0, 0, 0]) + assert_equal(mbase.c.mask, [0, 0, 1, 1, 0]) + + def test_set_elements(self): + base = self.base.copy() + # Set an element to mask ..................... + mbase = base.view(mrecarray).copy() + mbase[-2] = masked + assert_equal( + mbase._mask.tolist(), + np.array([(0, 0, 0), (1, 1, 1), (0, 0, 0), (1, 1, 1), (1, 1, 1)], + dtype=bool)) + # Used to be mask, now it's recordmask! + assert_equal(mbase.recordmask, [0, 1, 0, 1, 1]) + # Set slices ................................. + mbase = base.view(mrecarray).copy() + mbase[:2] = (5, 5, 5) + assert_equal(mbase.a._data, [5, 5, 3, 4, 5]) + assert_equal(mbase.a._mask, [0, 0, 0, 0, 1]) + assert_equal(mbase.b._data, [5., 5., 3.3, 4.4, 5.5]) + assert_equal(mbase.b._mask, [0, 0, 0, 0, 1]) + assert_equal(mbase.c._data, + [b'5', b'5', b'three', b'four', b'five']) + assert_equal(mbase.b._mask, [0, 0, 0, 0, 1]) + + mbase = base.view(mrecarray).copy() + mbase[:2] = masked + assert_equal(mbase.a._data, [1, 2, 3, 4, 5]) + assert_equal(mbase.a._mask, [1, 1, 0, 0, 1]) + assert_equal(mbase.b._data, [1.1, 2.2, 3.3, 4.4, 5.5]) + assert_equal(mbase.b._mask, [1, 1, 0, 0, 1]) + assert_equal(mbase.c._data, + [b'one', b'two', b'three', b'four', b'five']) + assert_equal(mbase.b._mask, [1, 1, 0, 0, 1]) + + def test_setslices_hardmask(self): + # Tests setting slices w/ hardmask. + base = self.base.copy() + mbase = base.view(mrecarray) + mbase.harden_mask() + try: + mbase[-2:] = (5, 5, 5) + assert_equal(mbase.a._data, [1, 2, 3, 5, 5]) + assert_equal(mbase.b._data, [1.1, 2.2, 3.3, 5, 5.5]) + assert_equal(mbase.c._data, + [b'one', b'two', b'three', b'5', b'five']) + assert_equal(mbase.a._mask, [0, 1, 0, 0, 1]) + assert_equal(mbase.b._mask, mbase.a._mask) + assert_equal(mbase.b._mask, mbase.c._mask) + except NotImplementedError: + # OK, not implemented yet... + pass + except AssertionError: + raise + else: + raise Exception("Flexible hard masks should be supported !") + # Not using a tuple should crash + try: + mbase[-2:] = 3 + except (NotImplementedError, TypeError): + pass + else: + raise TypeError("Should have expected a readable buffer object!") + + def test_hardmask(self): + # Test hardmask + base = self.base.copy() + mbase = base.view(mrecarray) + mbase.harden_mask() + assert_(mbase._hardmask) + mbase.mask = nomask + assert_equal_records(mbase._mask, base._mask) + mbase.soften_mask() + assert_(not mbase._hardmask) + mbase.mask = nomask + # So, the mask of a field is no longer set to nomask... + assert_equal_records(mbase._mask, + ma.make_mask_none(base.shape, base.dtype)) + assert_(ma.make_mask(mbase['b']._mask) is nomask) + assert_equal(mbase['a']._mask, mbase['b']._mask) + + def test_pickling(self): + # Test pickling + base = self.base.copy() + mrec = base.view(mrecarray) + for proto in range(2, pickle.HIGHEST_PROTOCOL + 1): + _ = pickle.dumps(mrec, protocol=proto) + mrec_ = pickle.loads(_) + assert_equal(mrec_.dtype, mrec.dtype) + assert_equal_records(mrec_._data, mrec._data) + assert_equal(mrec_._mask, mrec._mask) + assert_equal_records(mrec_._mask, mrec._mask) + + def test_filled(self): + # Test filling the array + _a = ma.array([1, 2, 3], mask=[0, 0, 1], dtype=int) + _b = ma.array([1.1, 2.2, 3.3], mask=[0, 0, 1], dtype=float) + _c = ma.array(['one', 'two', 'three'], mask=[0, 0, 1], dtype='|S8') + ddtype = [('a', int), ('b', float), ('c', '|S8')] + mrec = fromarrays([_a, _b, _c], dtype=ddtype, + fill_value=(99999, 99999., 'N/A')) + mrecfilled = mrec.filled() + assert_equal(mrecfilled['a'], np.array((1, 2, 99999), dtype=int)) + assert_equal(mrecfilled['b'], np.array((1.1, 2.2, 99999.), + dtype=float)) + assert_equal(mrecfilled['c'], np.array(('one', 'two', 'N/A'), + dtype='|S8')) + + def test_tolist(self): + # Test tolist. + _a = ma.array([1, 2, 3], mask=[0, 0, 1], dtype=int) + _b = ma.array([1.1, 2.2, 3.3], mask=[0, 0, 1], dtype=float) + _c = ma.array(['one', 'two', 'three'], mask=[1, 0, 0], dtype='|S8') + ddtype = [('a', int), ('b', float), ('c', '|S8')] + mrec = fromarrays([_a, _b, _c], dtype=ddtype, + fill_value=(99999, 99999., 'N/A')) + + assert_equal(mrec.tolist(), + [(1, 1.1, None), (2, 2.2, b'two'), + (None, None, b'three')]) + + def test_withnames(self): + # Test the creation w/ format and names + x = mrecarray(1, formats=float, names='base') + x[0]['base'] = 10 + assert_equal(x['base'][0], 10) + + def test_exotic_formats(self): + # Test that 'exotic' formats are processed properly + easy = mrecarray(1, dtype=[('i', int), ('s', '|S8'), ('f', float)]) + easy[0] = masked + assert_equal(easy.filled(1).item(), (1, b'1', 1.)) + + solo = mrecarray(1, dtype=[('f0', ' 1: + assert_(eq(np.concatenate((x, y), 1), + concatenate((xm, ym), 1))) + assert_(eq(np.add.reduce(x, 1), add.reduce(x, 1))) + assert_(eq(np.sum(x, 1), sum(x, 1))) + assert_(eq(np.product(x, 1), product(x, 1))) + + def test_testCI(self): + # Test of conversions and indexing + x1 = np.array([1, 2, 4, 3]) + x2 = array(x1, mask=[1, 0, 0, 0]) + x3 = array(x1, mask=[0, 1, 0, 1]) + x4 = array(x1) + # test conversion to strings + str(x2) # raises? + repr(x2) # raises? + assert_(eq(np.sort(x1), sort(x2, fill_value=0))) + # tests of indexing + assert_(type(x2[1]) is type(x1[1])) + assert_(x1[1] == x2[1]) + assert_(x2[0] is masked) + assert_(eq(x1[2], x2[2])) + assert_(eq(x1[2:5], x2[2:5])) + assert_(eq(x1[:], x2[:])) + assert_(eq(x1[1:], x3[1:])) + x1[2] = 9 + x2[2] = 9 + assert_(eq(x1, x2)) + x1[1:3] = 99 + x2[1:3] = 99 + assert_(eq(x1, x2)) + x2[1] = masked + assert_(eq(x1, x2)) + x2[1:3] = masked + assert_(eq(x1, x2)) + x2[:] = x1 + x2[1] = masked + assert_(allequal(getmask(x2), array([0, 1, 0, 0]))) + x3[:] = masked_array([1, 2, 3, 4], [0, 1, 1, 0]) + assert_(allequal(getmask(x3), array([0, 1, 1, 0]))) + x4[:] = masked_array([1, 2, 3, 4], [0, 1, 1, 0]) + assert_(allequal(getmask(x4), array([0, 1, 1, 0]))) + assert_(allequal(x4, array([1, 2, 3, 4]))) + x1 = np.arange(5) * 1.0 + x2 = masked_values(x1, 3.0) + assert_(eq(x1, x2)) + assert_(allequal(array([0, 0, 0, 1, 0], MaskType), x2.mask)) + assert_(eq(3.0, x2.fill_value)) + x1 = array([1, 'hello', 2, 3], object) + x2 = np.array([1, 'hello', 2, 3], object) + s1 = x1[1] + s2 = x2[1] + assert_equal(type(s2), str) + assert_equal(type(s1), str) + assert_equal(s1, s2) + assert_(x1[1:1].shape == (0,)) + + def test_testCopySize(self): + # Tests of some subtle points of copying and sizing. + n = [0, 0, 1, 0, 0] + m = make_mask(n) + m2 = make_mask(m) + assert_(m is m2) + m3 = make_mask(m, copy=True) + assert_(m is not m3) + + x1 = np.arange(5) + y1 = array(x1, mask=m) + assert_(y1._data is not x1) + assert_(allequal(x1, y1._data)) + assert_(y1._mask is m) + + y1a = array(y1, copy=0) + # For copy=False, one might expect that the array would just + # passed on, i.e., that it would be "is" instead of "==". + # See gh-4043 for discussion. + assert_(y1a._mask.__array_interface__ == + y1._mask.__array_interface__) + + y2 = array(x1, mask=m3, copy=0) + assert_(y2._mask is m3) + assert_(y2[2] is masked) + y2[2] = 9 + assert_(y2[2] is not masked) + assert_(y2._mask is m3) + assert_(allequal(y2.mask, 0)) + + y2a = array(x1, mask=m, copy=1) + assert_(y2a._mask is not m) + assert_(y2a[2] is masked) + y2a[2] = 9 + assert_(y2a[2] is not masked) + assert_(y2a._mask is not m) + assert_(allequal(y2a.mask, 0)) + + y3 = array(x1 * 1.0, mask=m) + assert_(filled(y3).dtype is (x1 * 1.0).dtype) + + x4 = arange(4) + x4[2] = masked + y4 = resize(x4, (8,)) + assert_(eq(concatenate([x4, x4]), y4)) + assert_(eq(getmask(y4), [0, 0, 1, 0, 0, 0, 1, 0])) + y5 = repeat(x4, (2, 2, 2, 2), axis=0) + assert_(eq(y5, [0, 0, 1, 1, 2, 2, 3, 3])) + y6 = repeat(x4, 2, axis=0) + assert_(eq(y5, y6)) + + def test_testPut(self): + # Test of put + d = arange(5) + n = [0, 0, 0, 1, 1] + m = make_mask(n) + m2 = m.copy() + x = array(d, mask=m) + assert_(x[3] is masked) + assert_(x[4] is masked) + x[[1, 4]] = [10, 40] + assert_(x._mask is m) + assert_(x[3] is masked) + assert_(x[4] is not masked) + assert_(eq(x, [0, 10, 2, -1, 40])) + + x = array(d, mask=m2, copy=True) + x.put([0, 1, 2], [-1, 100, 200]) + assert_(x._mask is not m2) + assert_(x[3] is masked) + assert_(x[4] is masked) + assert_(eq(x, [-1, 100, 200, 0, 0])) + + def test_testPut2(self): + # Test of put + d = arange(5) + x = array(d, mask=[0, 0, 0, 0, 0]) + z = array([10, 40], mask=[1, 0]) + assert_(x[2] is not masked) + assert_(x[3] is not masked) + x[2:4] = z + assert_(x[2] is masked) + assert_(x[3] is not masked) + assert_(eq(x, [0, 1, 10, 40, 4])) + + d = arange(5) + x = array(d, mask=[0, 0, 0, 0, 0]) + y = x[2:4] + z = array([10, 40], mask=[1, 0]) + assert_(x[2] is not masked) + assert_(x[3] is not masked) + y[:] = z + assert_(y[0] is masked) + assert_(y[1] is not masked) + assert_(eq(y, [10, 40])) + assert_(x[2] is masked) + assert_(x[3] is not masked) + assert_(eq(x, [0, 1, 10, 40, 4])) + + def test_testMaPut(self): + (x, y, a10, m1, m2, xm, ym, z, zm, xf, s) = self.d + m = [1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1] + i = np.nonzero(m)[0] + put(ym, i, zm) + assert_(all(take(ym, i, axis=0) == zm)) + + def test_testOddFeatures(self): + # Test of other odd features + x = arange(20) + x = x.reshape(4, 5) + x.flat[5] = 12 + assert_(x[1, 0] == 12) + z = x + 10j * x + assert_(eq(z.real, x)) + assert_(eq(z.imag, 10 * x)) + assert_(eq((z * conjugate(z)).real, 101 * x * x)) + z.imag[...] = 0.0 + + x = arange(10) + x[3] = masked + assert_(str(x[3]) == str(masked)) + c = x >= 8 + assert_(count(where(c, masked, masked)) == 0) + assert_(shape(where(c, masked, masked)) == c.shape) + z = where(c, x, masked) + assert_(z.dtype is x.dtype) + assert_(z[3] is masked) + assert_(z[4] is masked) + assert_(z[7] is masked) + assert_(z[8] is not masked) + assert_(z[9] is not masked) + assert_(eq(x, z)) + z = where(c, masked, x) + assert_(z.dtype is x.dtype) + assert_(z[3] is masked) + assert_(z[4] is not masked) + assert_(z[7] is not masked) + assert_(z[8] is masked) + assert_(z[9] is masked) + z = masked_where(c, x) + assert_(z.dtype is x.dtype) + assert_(z[3] is masked) + assert_(z[4] is not masked) + assert_(z[7] is not masked) + assert_(z[8] is masked) + assert_(z[9] is masked) + assert_(eq(x, z)) + x = array([1., 2., 3., 4., 5.]) + c = array([1, 1, 1, 0, 0]) + x[2] = masked + z = where(c, x, -x) + assert_(eq(z, [1., 2., 0., -4., -5])) + c[0] = masked + z = where(c, x, -x) + assert_(eq(z, [1., 2., 0., -4., -5])) + assert_(z[0] is masked) + assert_(z[1] is not masked) + assert_(z[2] is masked) + assert_(eq(masked_where(greater(x, 2), x), masked_greater(x, 2))) + assert_(eq(masked_where(greater_equal(x, 2), x), + masked_greater_equal(x, 2))) + assert_(eq(masked_where(less(x, 2), x), masked_less(x, 2))) + assert_(eq(masked_where(less_equal(x, 2), x), masked_less_equal(x, 2))) + assert_(eq(masked_where(not_equal(x, 2), x), masked_not_equal(x, 2))) + assert_(eq(masked_where(equal(x, 2), x), masked_equal(x, 2))) + assert_(eq(masked_where(not_equal(x, 2), x), masked_not_equal(x, 2))) + assert_(eq(masked_inside(list(range(5)), 1, 3), [0, 199, 199, 199, 4])) + assert_(eq(masked_outside(list(range(5)), 1, 3), [199, 1, 2, 3, 199])) + assert_(eq(masked_inside(array(list(range(5)), + mask=[1, 0, 0, 0, 0]), 1, 3).mask, + [1, 1, 1, 1, 0])) + assert_(eq(masked_outside(array(list(range(5)), + mask=[0, 1, 0, 0, 0]), 1, 3).mask, + [1, 1, 0, 0, 1])) + assert_(eq(masked_equal(array(list(range(5)), + mask=[1, 0, 0, 0, 0]), 2).mask, + [1, 0, 1, 0, 0])) + assert_(eq(masked_not_equal(array([2, 2, 1, 2, 1], + mask=[1, 0, 0, 0, 0]), 2).mask, + [1, 0, 1, 0, 1])) + assert_(eq(masked_where([1, 1, 0, 0, 0], [1, 2, 3, 4, 5]), + [99, 99, 3, 4, 5])) + atest = ones((10, 10, 10), dtype=np.float32) + btest = zeros(atest.shape, MaskType) + ctest = masked_where(btest, atest) + assert_(eq(atest, ctest)) + z = choose(c, (-x, x)) + assert_(eq(z, [1., 2., 0., -4., -5])) + assert_(z[0] is masked) + assert_(z[1] is not masked) + assert_(z[2] is masked) + x = arange(6) + x[5] = masked + y = arange(6) * 10 + y[2] = masked + c = array([1, 1, 1, 0, 0, 0], mask=[1, 0, 0, 0, 0, 0]) + cm = c.filled(1) + z = where(c, x, y) + zm = where(cm, x, y) + assert_(eq(z, zm)) + assert_(getmask(zm) is nomask) + assert_(eq(zm, [0, 1, 2, 30, 40, 50])) + z = where(c, masked, 1) + assert_(eq(z, [99, 99, 99, 1, 1, 1])) + z = where(c, 1, masked) + assert_(eq(z, [99, 1, 1, 99, 99, 99])) + + def test_testMinMax2(self): + # Test of minimum, maximum. + assert_(eq(minimum([1, 2, 3], [4, 0, 9]), [1, 0, 3])) + assert_(eq(maximum([1, 2, 3], [4, 0, 9]), [4, 2, 9])) + x = arange(5) + y = arange(5) - 2 + x[3] = masked + y[0] = masked + assert_(eq(minimum(x, y), where(less(x, y), x, y))) + assert_(eq(maximum(x, y), where(greater(x, y), x, y))) + assert_(minimum.reduce(x) == 0) + assert_(maximum.reduce(x) == 4) + + def test_testTakeTransposeInnerOuter(self): + # Test of take, transpose, inner, outer products + x = arange(24) + y = np.arange(24) + x[5:6] = masked + x = x.reshape(2, 3, 4) + y = y.reshape(2, 3, 4) + assert_(eq(np.transpose(y, (2, 0, 1)), transpose(x, (2, 0, 1)))) + assert_(eq(np.take(y, (2, 0, 1), 1), take(x, (2, 0, 1), 1))) + assert_(eq(np.inner(filled(x, 0), filled(y, 0)), + inner(x, y))) + assert_(eq(np.outer(filled(x, 0), filled(y, 0)), + outer(x, y))) + y = array(['abc', 1, 'def', 2, 3], object) + y[2] = masked + t = take(y, [0, 3, 4]) + assert_(t[0] == 'abc') + assert_(t[1] == 2) + assert_(t[2] == 3) + + def test_testInplace(self): + # Test of inplace operations and rich comparisons + y = arange(10) + + x = arange(10) + xm = arange(10) + xm[2] = masked + x += 1 + assert_(eq(x, y + 1)) + xm += 1 + assert_(eq(x, y + 1)) + + x = arange(10) + xm = arange(10) + xm[2] = masked + x -= 1 + assert_(eq(x, y - 1)) + xm -= 1 + assert_(eq(xm, y - 1)) + + x = arange(10) * 1.0 + xm = arange(10) * 1.0 + xm[2] = masked + x *= 2.0 + assert_(eq(x, y * 2)) + xm *= 2.0 + assert_(eq(xm, y * 2)) + + x = arange(10) * 2 + xm = arange(10) + xm[2] = masked + x //= 2 + assert_(eq(x, y)) + xm //= 2 + assert_(eq(x, y)) + + x = arange(10) * 1.0 + xm = arange(10) * 1.0 + xm[2] = masked + x /= 2.0 + assert_(eq(x, y / 2.0)) + xm /= arange(10) + assert_(eq(xm, ones((10,)))) + + x = arange(10).astype(np.float32) + xm = arange(10) + xm[2] = masked + x += 1. + assert_(eq(x, y + 1.)) + + def test_testPickle(self): + # Test of pickling + x = arange(12) + x[4:10:2] = masked + x = x.reshape(4, 3) + for proto in range(2, pickle.HIGHEST_PROTOCOL + 1): + s = pickle.dumps(x, protocol=proto) + y = pickle.loads(s) + assert_(eq(x, y)) + + def test_testMasked(self): + # Test of masked element + xx = arange(6) + xx[1] = masked + assert_(str(masked) == '--') + assert_(xx[1] is masked) + assert_equal(filled(xx[1], 0), 0) + + def test_testAverage1(self): + # Test of average. + ott = array([0., 1., 2., 3.], mask=[1, 0, 0, 0]) + assert_(eq(2.0, average(ott, axis=0))) + assert_(eq(2.0, average(ott, weights=[1., 1., 2., 1.]))) + result, wts = average(ott, weights=[1., 1., 2., 1.], returned=True) + assert_(eq(2.0, result)) + assert_(wts == 4.0) + ott[:] = masked + assert_(average(ott, axis=0) is masked) + ott = array([0., 1., 2., 3.], mask=[1, 0, 0, 0]) + ott = ott.reshape(2, 2) + ott[:, 1] = masked + assert_(eq(average(ott, axis=0), [2.0, 0.0])) + assert_(average(ott, axis=1)[0] is masked) + assert_(eq([2., 0.], average(ott, axis=0))) + result, wts = average(ott, axis=0, returned=True) + assert_(eq(wts, [1., 0.])) + + def test_testAverage2(self): + # More tests of average. + w1 = [0, 1, 1, 1, 1, 0] + w2 = [[0, 1, 1, 1, 1, 0], [1, 0, 0, 0, 0, 1]] + x = arange(6) + assert_(allclose(average(x, axis=0), 2.5)) + assert_(allclose(average(x, axis=0, weights=w1), 2.5)) + y = array([arange(6), 2.0 * arange(6)]) + assert_(allclose(average(y, None), + np.add.reduce(np.arange(6)) * 3. / 12.)) + assert_(allclose(average(y, axis=0), np.arange(6) * 3. / 2.)) + assert_(allclose(average(y, axis=1), + [average(x, axis=0), average(x, axis=0)*2.0])) + assert_(allclose(average(y, None, weights=w2), 20. / 6.)) + assert_(allclose(average(y, axis=0, weights=w2), + [0., 1., 2., 3., 4., 10.])) + assert_(allclose(average(y, axis=1), + [average(x, axis=0), average(x, axis=0)*2.0])) + m1 = zeros(6) + m2 = [0, 0, 1, 1, 0, 0] + m3 = [[0, 0, 1, 1, 0, 0], [0, 1, 1, 1, 1, 0]] + m4 = ones(6) + m5 = [0, 1, 1, 1, 1, 1] + assert_(allclose(average(masked_array(x, m1), axis=0), 2.5)) + assert_(allclose(average(masked_array(x, m2), axis=0), 2.5)) + assert_(average(masked_array(x, m4), axis=0) is masked) + assert_equal(average(masked_array(x, m5), axis=0), 0.0) + assert_equal(count(average(masked_array(x, m4), axis=0)), 0) + z = masked_array(y, m3) + assert_(allclose(average(z, None), 20. / 6.)) + assert_(allclose(average(z, axis=0), + [0., 1., 99., 99., 4.0, 7.5])) + assert_(allclose(average(z, axis=1), [2.5, 5.0])) + assert_(allclose(average(z, axis=0, weights=w2), + [0., 1., 99., 99., 4.0, 10.0])) + + a = arange(6) + b = arange(6) * 3 + r1, w1 = average([[a, b], [b, a]], axis=1, returned=True) + assert_equal(shape(r1), shape(w1)) + assert_equal(r1.shape, w1.shape) + r2, w2 = average(ones((2, 2, 3)), axis=0, weights=[3, 1], returned=True) + assert_equal(shape(w2), shape(r2)) + r2, w2 = average(ones((2, 2, 3)), returned=True) + assert_equal(shape(w2), shape(r2)) + r2, w2 = average(ones((2, 2, 3)), weights=ones((2, 2, 3)), returned=True) + assert_(shape(w2) == shape(r2)) + a2d = array([[1, 2], [0, 4]], float) + a2dm = masked_array(a2d, [[0, 0], [1, 0]]) + a2da = average(a2d, axis=0) + assert_(eq(a2da, [0.5, 3.0])) + a2dma = average(a2dm, axis=0) + assert_(eq(a2dma, [1.0, 3.0])) + a2dma = average(a2dm, axis=None) + assert_(eq(a2dma, 7. / 3.)) + a2dma = average(a2dm, axis=1) + assert_(eq(a2dma, [1.5, 4.0])) + + def test_testToPython(self): + assert_equal(1, int(array(1))) + assert_equal(1.0, float(array(1))) + assert_equal(1, int(array([[[1]]]))) + assert_equal(1.0, float(array([[1]]))) + assert_raises(TypeError, float, array([1, 1])) + assert_raises(ValueError, bool, array([0, 1])) + assert_raises(ValueError, bool, array([0, 0], mask=[0, 1])) + + def test_testScalarArithmetic(self): + xm = array(0, mask=1) + #TODO FIXME: Find out what the following raises a warning in r8247 + with np.errstate(divide='ignore'): + assert_((1 / array(0)).mask) + assert_((1 + xm).mask) + assert_((-xm).mask) + assert_((-xm).mask) + assert_(maximum(xm, xm).mask) + assert_(minimum(xm, xm).mask) + assert_(xm.filled().dtype is xm._data.dtype) + x = array(0, mask=0) + assert_(x.filled() == x._data) + assert_equal(str(xm), str(masked_print_option)) + + def test_testArrayMethods(self): + a = array([1, 3, 2]) + assert_(eq(a.any(), a._data.any())) + assert_(eq(a.all(), a._data.all())) + assert_(eq(a.argmax(), a._data.argmax())) + assert_(eq(a.argmin(), a._data.argmin())) + assert_(eq(a.choose(0, 1, 2, 3, 4), + a._data.choose(0, 1, 2, 3, 4))) + assert_(eq(a.compress([1, 0, 1]), a._data.compress([1, 0, 1]))) + assert_(eq(a.conj(), a._data.conj())) + assert_(eq(a.conjugate(), a._data.conjugate())) + m = array([[1, 2], [3, 4]]) + assert_(eq(m.diagonal(), m._data.diagonal())) + assert_(eq(a.sum(), a._data.sum())) + assert_(eq(a.take([1, 2]), a._data.take([1, 2]))) + assert_(eq(m.transpose(), m._data.transpose())) + + def test_testArrayAttributes(self): + a = array([1, 3, 2]) + assert_equal(a.ndim, 1) + + def test_testAPI(self): + assert_(not [m for m in dir(np.ndarray) + if m not in dir(MaskedArray) and + not m.startswith('_')]) + + def test_testSingleElementSubscript(self): + a = array([1, 3, 2]) + b = array([1, 3, 2], mask=[1, 0, 1]) + assert_equal(a[0].shape, ()) + assert_equal(b[0].shape, ()) + assert_equal(b[1].shape, ()) + + +class TestUfuncs: + def setup(self): + self.d = (array([1.0, 0, -1, pi / 2] * 2, mask=[0, 1] + [0] * 6), + array([1.0, 0, -1, pi / 2] * 2, mask=[1, 0] + [0] * 6),) + + def test_testUfuncRegression(self): + f_invalid_ignore = [ + 'sqrt', 'arctanh', 'arcsin', 'arccos', + 'arccosh', 'arctanh', 'log', 'log10', 'divide', + 'true_divide', 'floor_divide', 'remainder', 'fmod'] + for f in ['sqrt', 'log', 'log10', 'exp', 'conjugate', + 'sin', 'cos', 'tan', + 'arcsin', 'arccos', 'arctan', + 'sinh', 'cosh', 'tanh', + 'arcsinh', + 'arccosh', + 'arctanh', + 'absolute', 'fabs', 'negative', + 'floor', 'ceil', + 'logical_not', + 'add', 'subtract', 'multiply', + 'divide', 'true_divide', 'floor_divide', + 'remainder', 'fmod', 'hypot', 'arctan2', + 'equal', 'not_equal', 'less_equal', 'greater_equal', + 'less', 'greater', + 'logical_and', 'logical_or', 'logical_xor']: + try: + uf = getattr(umath, f) + except AttributeError: + uf = getattr(fromnumeric, f) + mf = getattr(np.ma, f) + args = self.d[:uf.nin] + with np.errstate(): + if f in f_invalid_ignore: + np.seterr(invalid='ignore') + if f in ['arctanh', 'log', 'log10']: + np.seterr(divide='ignore') + ur = uf(*args) + mr = mf(*args) + assert_(eq(ur.filled(0), mr.filled(0), f)) + assert_(eqmask(ur.mask, mr.mask)) + + def test_reduce(self): + a = self.d[0] + assert_(not alltrue(a, axis=0)) + assert_(sometrue(a, axis=0)) + assert_equal(sum(a[:3], axis=0), 0) + assert_equal(product(a, axis=0), 0) + + def test_minmax(self): + a = arange(1, 13).reshape(3, 4) + amask = masked_where(a < 5, a) + assert_equal(amask.max(), a.max()) + assert_equal(amask.min(), 5) + assert_((amask.max(0) == a.max(0)).all()) + assert_((amask.min(0) == [5, 6, 7, 8]).all()) + assert_(amask.max(1)[0].mask) + assert_(amask.min(1)[0].mask) + + def test_nonzero(self): + for t in "?bhilqpBHILQPfdgFDGO": + x = array([1, 0, 2, 0], mask=[0, 0, 1, 1]) + assert_(eq(nonzero(x), [0])) + + +class TestArrayMethods: + + def setup(self): + x = np.array([8.375, 7.545, 8.828, 8.5, 1.757, 5.928, + 8.43, 7.78, 9.865, 5.878, 8.979, 4.732, + 3.012, 6.022, 5.095, 3.116, 5.238, 3.957, + 6.04, 9.63, 7.712, 3.382, 4.489, 6.479, + 7.189, 9.645, 5.395, 4.961, 9.894, 2.893, + 7.357, 9.828, 6.272, 3.758, 6.693, 0.993]) + X = x.reshape(6, 6) + XX = x.reshape(3, 2, 2, 3) + + m = np.array([0, 1, 0, 1, 0, 0, + 1, 0, 1, 1, 0, 1, + 0, 0, 0, 1, 0, 1, + 0, 0, 0, 1, 1, 1, + 1, 0, 0, 1, 0, 0, + 0, 0, 1, 0, 1, 0]) + mx = array(data=x, mask=m) + mX = array(data=X, mask=m.reshape(X.shape)) + mXX = array(data=XX, mask=m.reshape(XX.shape)) + + self.d = (x, X, XX, m, mx, mX, mXX) + + def test_trace(self): + (x, X, XX, m, mx, mX, mXX,) = self.d + mXdiag = mX.diagonal() + assert_equal(mX.trace(), mX.diagonal().compressed().sum()) + assert_(eq(mX.trace(), + X.trace() - sum(mXdiag.mask * X.diagonal(), + axis=0))) + + def test_clip(self): + (x, X, XX, m, mx, mX, mXX,) = self.d + clipped = mx.clip(2, 8) + assert_(eq(clipped.mask, mx.mask)) + assert_(eq(clipped._data, x.clip(2, 8))) + assert_(eq(clipped._data, mx._data.clip(2, 8))) + + def test_ptp(self): + (x, X, XX, m, mx, mX, mXX,) = self.d + (n, m) = X.shape + assert_equal(mx.ptp(), mx.compressed().ptp()) + rows = np.zeros(n, np.float_) + cols = np.zeros(m, np.float_) + for k in range(m): + cols[k] = mX[:, k].compressed().ptp() + for k in range(n): + rows[k] = mX[k].compressed().ptp() + assert_(eq(mX.ptp(0), cols)) + assert_(eq(mX.ptp(1), rows)) + + def test_swapaxes(self): + (x, X, XX, m, mx, mX, mXX,) = self.d + mXswapped = mX.swapaxes(0, 1) + assert_(eq(mXswapped[-1], mX[:, -1])) + mXXswapped = mXX.swapaxes(0, 2) + assert_equal(mXXswapped.shape, (2, 2, 3, 3)) + + def test_cumprod(self): + (x, X, XX, m, mx, mX, mXX,) = self.d + mXcp = mX.cumprod(0) + assert_(eq(mXcp._data, mX.filled(1).cumprod(0))) + mXcp = mX.cumprod(1) + assert_(eq(mXcp._data, mX.filled(1).cumprod(1))) + + def test_cumsum(self): + (x, X, XX, m, mx, mX, mXX,) = self.d + mXcp = mX.cumsum(0) + assert_(eq(mXcp._data, mX.filled(0).cumsum(0))) + mXcp = mX.cumsum(1) + assert_(eq(mXcp._data, mX.filled(0).cumsum(1))) + + def test_varstd(self): + (x, X, XX, m, mx, mX, mXX,) = self.d + assert_(eq(mX.var(axis=None), mX.compressed().var())) + assert_(eq(mX.std(axis=None), mX.compressed().std())) + assert_(eq(mXX.var(axis=3).shape, XX.var(axis=3).shape)) + assert_(eq(mX.var().shape, X.var().shape)) + (mXvar0, mXvar1) = (mX.var(axis=0), mX.var(axis=1)) + for k in range(6): + assert_(eq(mXvar1[k], mX[k].compressed().var())) + assert_(eq(mXvar0[k], mX[:, k].compressed().var())) + assert_(eq(np.sqrt(mXvar0[k]), + mX[:, k].compressed().std())) + + +def eqmask(m1, m2): + if m1 is nomask: + return m2 is nomask + if m2 is nomask: + return m1 is nomask + return (m1 == m2).all() diff --git a/venv/Lib/site-packages/numpy/ma/tests/test_regression.py b/venv/Lib/site-packages/numpy/ma/tests/test_regression.py new file mode 100644 index 0000000..7e76eb0 --- /dev/null +++ b/venv/Lib/site-packages/numpy/ma/tests/test_regression.py @@ -0,0 +1,91 @@ +import numpy as np +from numpy.testing import ( + assert_, assert_array_equal, assert_allclose, suppress_warnings + ) + + +class TestRegression: + def test_masked_array_create(self): + # Ticket #17 + x = np.ma.masked_array([0, 1, 2, 3, 0, 4, 5, 6], + mask=[0, 0, 0, 1, 1, 1, 0, 0]) + assert_array_equal(np.ma.nonzero(x), [[1, 2, 6, 7]]) + + def test_masked_array(self): + # Ticket #61 + np.ma.array(1, mask=[1]) + + def test_mem_masked_where(self): + # Ticket #62 + from numpy.ma import masked_where, MaskType + a = np.zeros((1, 1)) + b = np.zeros(a.shape, MaskType) + c = masked_where(b, a) + a-c + + def test_masked_array_multiply(self): + # Ticket #254 + a = np.ma.zeros((4, 1)) + a[2, 0] = np.ma.masked + b = np.zeros((4, 2)) + a*b + b*a + + def test_masked_array_repeat(self): + # Ticket #271 + np.ma.array([1], mask=False).repeat(10) + + def test_masked_array_repr_unicode(self): + # Ticket #1256 + repr(np.ma.array(u"Unicode")) + + def test_atleast_2d(self): + # Ticket #1559 + a = np.ma.masked_array([0.0, 1.2, 3.5], mask=[False, True, False]) + b = np.atleast_2d(a) + assert_(a.mask.ndim == 1) + assert_(b.mask.ndim == 2) + + def test_set_fill_value_unicode_py3(self): + # Ticket #2733 + a = np.ma.masked_array(['a', 'b', 'c'], mask=[1, 0, 0]) + a.fill_value = 'X' + assert_(a.fill_value == 'X') + + def test_var_sets_maskedarray_scalar(self): + # Issue gh-2757 + a = np.ma.array(np.arange(5), mask=True) + mout = np.ma.array(-1, dtype=float) + a.var(out=mout) + assert_(mout._data == 0) + + def test_ddof_corrcoef(self): + # See gh-3336 + x = np.ma.masked_equal([1, 2, 3, 4, 5], 4) + y = np.array([2, 2.5, 3.1, 3, 5]) + # this test can be removed after deprecation. + with suppress_warnings() as sup: + sup.filter(DeprecationWarning, "bias and ddof have no effect") + r0 = np.ma.corrcoef(x, y, ddof=0) + r1 = np.ma.corrcoef(x, y, ddof=1) + # ddof should not have an effect (it gets cancelled out) + assert_allclose(r0.data, r1.data) + + def test_mask_not_backmangled(self): + # See gh-10314. Test case taken from gh-3140. + a = np.ma.MaskedArray([1., 2.], mask=[False, False]) + assert_(a.mask.shape == (2,)) + b = np.tile(a, (2, 1)) + # Check that the above no longer changes a.shape to (1, 2) + assert_(a.mask.shape == (2,)) + assert_(b.shape == (2, 2)) + assert_(b.mask.shape == (2, 2)) + + def test_empty_list_on_structured(self): + # See gh-12464. Indexing with empty list should give empty result. + ma = np.ma.MaskedArray([(1, 1.), (2, 2.), (3, 3.)], dtype='i4,f4') + assert_array_equal(ma[[]], ma[:0]) + + def test_masked_array_tobytes_fortran(self): + ma = np.ma.arange(4).reshape((2,2)) + assert_array_equal(ma.tobytes(order='F'), ma.T.tobytes()) diff --git a/venv/Lib/site-packages/numpy/ma/tests/test_subclassing.py b/venv/Lib/site-packages/numpy/ma/tests/test_subclassing.py new file mode 100644 index 0000000..f262340 --- /dev/null +++ b/venv/Lib/site-packages/numpy/ma/tests/test_subclassing.py @@ -0,0 +1,347 @@ +# pylint: disable-msg=W0611, W0612, W0511,R0201 +"""Tests suite for MaskedArray & subclassing. + +:author: Pierre Gerard-Marchant +:contact: pierregm_at_uga_dot_edu +:version: $Id: test_subclassing.py 3473 2007-10-29 15:18:13Z jarrod.millman $ + +""" +import numpy as np +from numpy.testing import assert_, assert_raises +from numpy.ma.testutils import assert_equal +from numpy.ma.core import ( + array, arange, masked, MaskedArray, masked_array, log, add, hypot, + divide, asarray, asanyarray, nomask + ) +# from numpy.ma.core import ( + +def assert_startswith(a, b): + # produces a better error message than assert_(a.startswith(b)) + assert_equal(a[:len(b)], b) + +class SubArray(np.ndarray): + # Defines a generic np.ndarray subclass, that stores some metadata + # in the dictionary `info`. + def __new__(cls,arr,info={}): + x = np.asanyarray(arr).view(cls) + x.info = info.copy() + return x + + def __array_finalize__(self, obj): + if callable(getattr(super(SubArray, self), + '__array_finalize__', None)): + super(SubArray, self).__array_finalize__(obj) + self.info = getattr(obj, 'info', {}).copy() + return + + def __add__(self, other): + result = super(SubArray, self).__add__(other) + result.info['added'] = result.info.get('added', 0) + 1 + return result + + def __iadd__(self, other): + result = super(SubArray, self).__iadd__(other) + result.info['iadded'] = result.info.get('iadded', 0) + 1 + return result + + +subarray = SubArray + + +class SubMaskedArray(MaskedArray): + """Pure subclass of MaskedArray, keeping some info on subclass.""" + def __new__(cls, info=None, **kwargs): + obj = super(SubMaskedArray, cls).__new__(cls, **kwargs) + obj._optinfo['info'] = info + return obj + + +class MSubArray(SubArray, MaskedArray): + + def __new__(cls, data, info={}, mask=nomask): + subarr = SubArray(data, info) + _data = MaskedArray.__new__(cls, data=subarr, mask=mask) + _data.info = subarr.info + return _data + + @property + def _series(self): + _view = self.view(MaskedArray) + _view._sharedmask = False + return _view + +msubarray = MSubArray + + +# Also a subclass that overrides __str__, __repr__ and __setitem__, disallowing +# setting to non-class values (and thus np.ma.core.masked_print_option) +# and overrides __array_wrap__, updating the info dict, to check that this +# doesn't get destroyed by MaskedArray._update_from. But this one also needs +# its own iterator... +class CSAIterator: + """ + Flat iterator object that uses its own setter/getter + (works around ndarray.flat not propagating subclass setters/getters + see https://github.com/numpy/numpy/issues/4564) + roughly following MaskedIterator + """ + def __init__(self, a): + self._original = a + self._dataiter = a.view(np.ndarray).flat + + def __iter__(self): + return self + + def __getitem__(self, indx): + out = self._dataiter.__getitem__(indx) + if not isinstance(out, np.ndarray): + out = out.__array__() + out = out.view(type(self._original)) + return out + + def __setitem__(self, index, value): + self._dataiter[index] = self._original._validate_input(value) + + def __next__(self): + return next(self._dataiter).__array__().view(type(self._original)) + + +class ComplicatedSubArray(SubArray): + + def __str__(self): + return f'myprefix {self.view(SubArray)} mypostfix' + + def __repr__(self): + # Return a repr that does not start with 'name(' + return f'<{self.__class__.__name__} {self}>' + + def _validate_input(self, value): + if not isinstance(value, ComplicatedSubArray): + raise ValueError("Can only set to MySubArray values") + return value + + def __setitem__(self, item, value): + # validation ensures direct assignment with ndarray or + # masked_print_option will fail + super(ComplicatedSubArray, self).__setitem__( + item, self._validate_input(value)) + + def __getitem__(self, item): + # ensure getter returns our own class also for scalars + value = super(ComplicatedSubArray, self).__getitem__(item) + if not isinstance(value, np.ndarray): # scalar + value = value.__array__().view(ComplicatedSubArray) + return value + + @property + def flat(self): + return CSAIterator(self) + + @flat.setter + def flat(self, value): + y = self.ravel() + y[:] = value + + def __array_wrap__(self, obj, context=None): + obj = super(ComplicatedSubArray, self).__array_wrap__(obj, context) + if context is not None and context[0] is np.multiply: + obj.info['multiplied'] = obj.info.get('multiplied', 0) + 1 + + return obj + + +class TestSubclassing: + # Test suite for masked subclasses of ndarray. + + def setup(self): + x = np.arange(5, dtype='float') + mx = msubarray(x, mask=[0, 1, 0, 0, 0]) + self.data = (x, mx) + + def test_data_subclassing(self): + # Tests whether the subclass is kept. + x = np.arange(5) + m = [0, 0, 1, 0, 0] + xsub = SubArray(x) + xmsub = masked_array(xsub, mask=m) + assert_(isinstance(xmsub, MaskedArray)) + assert_equal(xmsub._data, xsub) + assert_(isinstance(xmsub._data, SubArray)) + + def test_maskedarray_subclassing(self): + # Tests subclassing MaskedArray + (x, mx) = self.data + assert_(isinstance(mx._data, subarray)) + + def test_masked_unary_operations(self): + # Tests masked_unary_operation + (x, mx) = self.data + with np.errstate(divide='ignore'): + assert_(isinstance(log(mx), msubarray)) + assert_equal(log(x), np.log(x)) + + def test_masked_binary_operations(self): + # Tests masked_binary_operation + (x, mx) = self.data + # Result should be a msubarray + assert_(isinstance(add(mx, mx), msubarray)) + assert_(isinstance(add(mx, x), msubarray)) + # Result should work + assert_equal(add(mx, x), mx+x) + assert_(isinstance(add(mx, mx)._data, subarray)) + assert_(isinstance(add.outer(mx, mx), msubarray)) + assert_(isinstance(hypot(mx, mx), msubarray)) + assert_(isinstance(hypot(mx, x), msubarray)) + + def test_masked_binary_operations2(self): + # Tests domained_masked_binary_operation + (x, mx) = self.data + xmx = masked_array(mx.data.__array__(), mask=mx.mask) + assert_(isinstance(divide(mx, mx), msubarray)) + assert_(isinstance(divide(mx, x), msubarray)) + assert_equal(divide(mx, mx), divide(xmx, xmx)) + + def test_attributepropagation(self): + x = array(arange(5), mask=[0]+[1]*4) + my = masked_array(subarray(x)) + ym = msubarray(x) + # + z = (my+1) + assert_(isinstance(z, MaskedArray)) + assert_(not isinstance(z, MSubArray)) + assert_(isinstance(z._data, SubArray)) + assert_equal(z._data.info, {}) + # + z = (ym+1) + assert_(isinstance(z, MaskedArray)) + assert_(isinstance(z, MSubArray)) + assert_(isinstance(z._data, SubArray)) + assert_(z._data.info['added'] > 0) + # Test that inplace methods from data get used (gh-4617) + ym += 1 + assert_(isinstance(ym, MaskedArray)) + assert_(isinstance(ym, MSubArray)) + assert_(isinstance(ym._data, SubArray)) + assert_(ym._data.info['iadded'] > 0) + # + ym._set_mask([1, 0, 0, 0, 1]) + assert_equal(ym._mask, [1, 0, 0, 0, 1]) + ym._series._set_mask([0, 0, 0, 0, 1]) + assert_equal(ym._mask, [0, 0, 0, 0, 1]) + # + xsub = subarray(x, info={'name':'x'}) + mxsub = masked_array(xsub) + assert_(hasattr(mxsub, 'info')) + assert_equal(mxsub.info, xsub.info) + + def test_subclasspreservation(self): + # Checks that masked_array(...,subok=True) preserves the class. + x = np.arange(5) + m = [0, 0, 1, 0, 0] + xinfo = [(i, j) for (i, j) in zip(x, m)] + xsub = MSubArray(x, mask=m, info={'xsub':xinfo}) + # + mxsub = masked_array(xsub, subok=False) + assert_(not isinstance(mxsub, MSubArray)) + assert_(isinstance(mxsub, MaskedArray)) + assert_equal(mxsub._mask, m) + # + mxsub = asarray(xsub) + assert_(not isinstance(mxsub, MSubArray)) + assert_(isinstance(mxsub, MaskedArray)) + assert_equal(mxsub._mask, m) + # + mxsub = masked_array(xsub, subok=True) + assert_(isinstance(mxsub, MSubArray)) + assert_equal(mxsub.info, xsub.info) + assert_equal(mxsub._mask, xsub._mask) + # + mxsub = asanyarray(xsub) + assert_(isinstance(mxsub, MSubArray)) + assert_equal(mxsub.info, xsub.info) + assert_equal(mxsub._mask, m) + + def test_subclass_items(self): + """test that getter and setter go via baseclass""" + x = np.arange(5) + xcsub = ComplicatedSubArray(x) + mxcsub = masked_array(xcsub, mask=[True, False, True, False, False]) + # getter should return a ComplicatedSubArray, even for single item + # first check we wrote ComplicatedSubArray correctly + assert_(isinstance(xcsub[1], ComplicatedSubArray)) + assert_(isinstance(xcsub[1,...], ComplicatedSubArray)) + assert_(isinstance(xcsub[1:4], ComplicatedSubArray)) + + # now that it propagates inside the MaskedArray + assert_(isinstance(mxcsub[1], ComplicatedSubArray)) + assert_(isinstance(mxcsub[1,...].data, ComplicatedSubArray)) + assert_(mxcsub[0] is masked) + assert_(isinstance(mxcsub[0,...].data, ComplicatedSubArray)) + assert_(isinstance(mxcsub[1:4].data, ComplicatedSubArray)) + + # also for flattened version (which goes via MaskedIterator) + assert_(isinstance(mxcsub.flat[1].data, ComplicatedSubArray)) + assert_(mxcsub.flat[0] is masked) + assert_(isinstance(mxcsub.flat[1:4].base, ComplicatedSubArray)) + + # setter should only work with ComplicatedSubArray input + # first check we wrote ComplicatedSubArray correctly + assert_raises(ValueError, xcsub.__setitem__, 1, x[4]) + # now that it propagates inside the MaskedArray + assert_raises(ValueError, mxcsub.__setitem__, 1, x[4]) + assert_raises(ValueError, mxcsub.__setitem__, slice(1, 4), x[1:4]) + mxcsub[1] = xcsub[4] + mxcsub[1:4] = xcsub[1:4] + # also for flattened version (which goes via MaskedIterator) + assert_raises(ValueError, mxcsub.flat.__setitem__, 1, x[4]) + assert_raises(ValueError, mxcsub.flat.__setitem__, slice(1, 4), x[1:4]) + mxcsub.flat[1] = xcsub[4] + mxcsub.flat[1:4] = xcsub[1:4] + + def test_subclass_nomask_items(self): + x = np.arange(5) + xcsub = ComplicatedSubArray(x) + mxcsub_nomask = masked_array(xcsub) + + assert_(isinstance(mxcsub_nomask[1,...].data, ComplicatedSubArray)) + assert_(isinstance(mxcsub_nomask[0,...].data, ComplicatedSubArray)) + + assert_(isinstance(mxcsub_nomask[1], ComplicatedSubArray)) + assert_(isinstance(mxcsub_nomask[0], ComplicatedSubArray)) + + def test_subclass_repr(self): + """test that repr uses the name of the subclass + and 'array' for np.ndarray""" + x = np.arange(5) + mx = masked_array(x, mask=[True, False, True, False, False]) + assert_startswith(repr(mx), 'masked_array') + xsub = SubArray(x) + mxsub = masked_array(xsub, mask=[True, False, True, False, False]) + assert_startswith(repr(mxsub), + f'masked_{SubArray.__name__}(data=[--, 1, --, 3, 4]') + + def test_subclass_str(self): + """test str with subclass that has overridden str, setitem""" + # first without override + x = np.arange(5) + xsub = SubArray(x) + mxsub = masked_array(xsub, mask=[True, False, True, False, False]) + assert_equal(str(mxsub), '[-- 1 -- 3 4]') + + xcsub = ComplicatedSubArray(x) + assert_raises(ValueError, xcsub.__setitem__, 0, + np.ma.core.masked_print_option) + mxcsub = masked_array(xcsub, mask=[True, False, True, False, False]) + assert_equal(str(mxcsub), 'myprefix [-- 1 -- 3 4] mypostfix') + + def test_pure_subclass_info_preservation(self): + # Test that ufuncs and methods conserve extra information consistently; + # see gh-7122. + arr1 = SubMaskedArray('test', data=[1,2,3,4,5,6]) + arr2 = SubMaskedArray(data=[0,1,2,3,4,5]) + diff1 = np.subtract(arr1, arr2) + assert_('info' in diff1._optinfo) + assert_(diff1._optinfo['info'] == 'test') + diff2 = arr1 - arr2 + assert_('info' in diff2._optinfo) + assert_(diff2._optinfo['info'] == 'test') diff --git a/venv/Lib/site-packages/numpy/ma/testutils.py b/venv/Lib/site-packages/numpy/ma/testutils.py new file mode 100644 index 0000000..8d55e17 --- /dev/null +++ b/venv/Lib/site-packages/numpy/ma/testutils.py @@ -0,0 +1,288 @@ +"""Miscellaneous functions for testing masked arrays and subclasses + +:author: Pierre Gerard-Marchant +:contact: pierregm_at_uga_dot_edu +:version: $Id: testutils.py 3529 2007-11-13 08:01:14Z jarrod.millman $ + +""" +import operator + +import numpy as np +from numpy import ndarray, float_ +import numpy.core.umath as umath +import numpy.testing +from numpy.testing import ( + assert_, assert_allclose, assert_array_almost_equal_nulp, + assert_raises, build_err_msg + ) +from .core import mask_or, getmask, masked_array, nomask, masked, filled + +__all__masked = [ + 'almost', 'approx', 'assert_almost_equal', 'assert_array_almost_equal', + 'assert_array_approx_equal', 'assert_array_compare', + 'assert_array_equal', 'assert_array_less', 'assert_close', + 'assert_equal', 'assert_equal_records', 'assert_mask_equal', + 'assert_not_equal', 'fail_if_array_equal', + ] + +# Include some normal test functions to avoid breaking other projects who +# have mistakenly included them from this file. SciPy is one. That is +# unfortunate, as some of these functions are not intended to work with +# masked arrays. But there was no way to tell before. +from unittest import TestCase +__some__from_testing = [ + 'TestCase', 'assert_', 'assert_allclose', 'assert_array_almost_equal_nulp', + 'assert_raises' + ] + +__all__ = __all__masked + __some__from_testing + + +def approx(a, b, fill_value=True, rtol=1e-5, atol=1e-8): + """ + Returns true if all components of a and b are equal to given tolerances. + + If fill_value is True, masked values considered equal. Otherwise, + masked values are considered unequal. The relative error rtol should + be positive and << 1.0 The absolute error atol comes into play for + those elements of b that are very small or zero; it says how small a + must be also. + + """ + m = mask_or(getmask(a), getmask(b)) + d1 = filled(a) + d2 = filled(b) + if d1.dtype.char == "O" or d2.dtype.char == "O": + return np.equal(d1, d2).ravel() + x = filled(masked_array(d1, copy=False, mask=m), fill_value).astype(float_) + y = filled(masked_array(d2, copy=False, mask=m), 1).astype(float_) + d = np.less_equal(umath.absolute(x - y), atol + rtol * umath.absolute(y)) + return d.ravel() + + +def almost(a, b, decimal=6, fill_value=True): + """ + Returns True if a and b are equal up to decimal places. + + If fill_value is True, masked values considered equal. Otherwise, + masked values are considered unequal. + + """ + m = mask_or(getmask(a), getmask(b)) + d1 = filled(a) + d2 = filled(b) + if d1.dtype.char == "O" or d2.dtype.char == "O": + return np.equal(d1, d2).ravel() + x = filled(masked_array(d1, copy=False, mask=m), fill_value).astype(float_) + y = filled(masked_array(d2, copy=False, mask=m), 1).astype(float_) + d = np.around(np.abs(x - y), decimal) <= 10.0 ** (-decimal) + return d.ravel() + + +def _assert_equal_on_sequences(actual, desired, err_msg=''): + """ + Asserts the equality of two non-array sequences. + + """ + assert_equal(len(actual), len(desired), err_msg) + for k in range(len(desired)): + assert_equal(actual[k], desired[k], f'item={k!r}\n{err_msg}') + return + + +def assert_equal_records(a, b): + """ + Asserts that two records are equal. + + Pretty crude for now. + + """ + assert_equal(a.dtype, b.dtype) + for f in a.dtype.names: + (af, bf) = (operator.getitem(a, f), operator.getitem(b, f)) + if not (af is masked) and not (bf is masked): + assert_equal(operator.getitem(a, f), operator.getitem(b, f)) + return + + +def assert_equal(actual, desired, err_msg=''): + """ + Asserts that two items are equal. + + """ + # Case #1: dictionary ..... + if isinstance(desired, dict): + if not isinstance(actual, dict): + raise AssertionError(repr(type(actual))) + assert_equal(len(actual), len(desired), err_msg) + for k, i in desired.items(): + if k not in actual: + raise AssertionError(f"{k} not in {actual}") + assert_equal(actual[k], desired[k], f'key={k!r}\n{err_msg}') + return + # Case #2: lists ..... + if isinstance(desired, (list, tuple)) and isinstance(actual, (list, tuple)): + return _assert_equal_on_sequences(actual, desired, err_msg='') + if not (isinstance(actual, ndarray) or isinstance(desired, ndarray)): + msg = build_err_msg([actual, desired], err_msg,) + if not desired == actual: + raise AssertionError(msg) + return + # Case #4. arrays or equivalent + if ((actual is masked) and not (desired is masked)) or \ + ((desired is masked) and not (actual is masked)): + msg = build_err_msg([actual, desired], + err_msg, header='', names=('x', 'y')) + raise ValueError(msg) + actual = np.array(actual, copy=False, subok=True) + desired = np.array(desired, copy=False, subok=True) + (actual_dtype, desired_dtype) = (actual.dtype, desired.dtype) + if actual_dtype.char == "S" and desired_dtype.char == "S": + return _assert_equal_on_sequences(actual.tolist(), + desired.tolist(), + err_msg='') + return assert_array_equal(actual, desired, err_msg) + + +def fail_if_equal(actual, desired, err_msg='',): + """ + Raises an assertion error if two items are equal. + + """ + if isinstance(desired, dict): + if not isinstance(actual, dict): + raise AssertionError(repr(type(actual))) + fail_if_equal(len(actual), len(desired), err_msg) + for k, i in desired.items(): + if k not in actual: + raise AssertionError(repr(k)) + fail_if_equal(actual[k], desired[k], f'key={k!r}\n{err_msg}') + return + if isinstance(desired, (list, tuple)) and isinstance(actual, (list, tuple)): + fail_if_equal(len(actual), len(desired), err_msg) + for k in range(len(desired)): + fail_if_equal(actual[k], desired[k], f'item={k!r}\n{err_msg}') + return + if isinstance(actual, np.ndarray) or isinstance(desired, np.ndarray): + return fail_if_array_equal(actual, desired, err_msg) + msg = build_err_msg([actual, desired], err_msg) + if not desired != actual: + raise AssertionError(msg) + + +assert_not_equal = fail_if_equal + + +def assert_almost_equal(actual, desired, decimal=7, err_msg='', verbose=True): + """ + Asserts that two items are almost equal. + + The test is equivalent to abs(desired-actual) < 0.5 * 10**(-decimal). + + """ + if isinstance(actual, np.ndarray) or isinstance(desired, np.ndarray): + return assert_array_almost_equal(actual, desired, decimal=decimal, + err_msg=err_msg, verbose=verbose) + msg = build_err_msg([actual, desired], + err_msg=err_msg, verbose=verbose) + if not round(abs(desired - actual), decimal) == 0: + raise AssertionError(msg) + + +assert_close = assert_almost_equal + + +def assert_array_compare(comparison, x, y, err_msg='', verbose=True, header='', + fill_value=True): + """ + Asserts that comparison between two masked arrays is satisfied. + + The comparison is elementwise. + + """ + # Allocate a common mask and refill + m = mask_or(getmask(x), getmask(y)) + x = masked_array(x, copy=False, mask=m, keep_mask=False, subok=False) + y = masked_array(y, copy=False, mask=m, keep_mask=False, subok=False) + if ((x is masked) and not (y is masked)) or \ + ((y is masked) and not (x is masked)): + msg = build_err_msg([x, y], err_msg=err_msg, verbose=verbose, + header=header, names=('x', 'y')) + raise ValueError(msg) + # OK, now run the basic tests on filled versions + return np.testing.assert_array_compare(comparison, + x.filled(fill_value), + y.filled(fill_value), + err_msg=err_msg, + verbose=verbose, header=header) + + +def assert_array_equal(x, y, err_msg='', verbose=True): + """ + Checks the elementwise equality of two masked arrays. + + """ + assert_array_compare(operator.__eq__, x, y, + err_msg=err_msg, verbose=verbose, + header='Arrays are not equal') + + +def fail_if_array_equal(x, y, err_msg='', verbose=True): + """ + Raises an assertion error if two masked arrays are not equal elementwise. + + """ + def compare(x, y): + return (not np.alltrue(approx(x, y))) + assert_array_compare(compare, x, y, err_msg=err_msg, verbose=verbose, + header='Arrays are not equal') + + +def assert_array_approx_equal(x, y, decimal=6, err_msg='', verbose=True): + """ + Checks the equality of two masked arrays, up to given number odecimals. + + The equality is checked elementwise. + + """ + def compare(x, y): + "Returns the result of the loose comparison between x and y)." + return approx(x, y, rtol=10. ** -decimal) + assert_array_compare(compare, x, y, err_msg=err_msg, verbose=verbose, + header='Arrays are not almost equal') + + +def assert_array_almost_equal(x, y, decimal=6, err_msg='', verbose=True): + """ + Checks the equality of two masked arrays, up to given number odecimals. + + The equality is checked elementwise. + + """ + def compare(x, y): + "Returns the result of the loose comparison between x and y)." + return almost(x, y, decimal) + assert_array_compare(compare, x, y, err_msg=err_msg, verbose=verbose, + header='Arrays are not almost equal') + + +def assert_array_less(x, y, err_msg='', verbose=True): + """ + Checks that x is smaller than y elementwise. + + """ + assert_array_compare(operator.__lt__, x, y, + err_msg=err_msg, verbose=verbose, + header='Arrays are not less-ordered') + + +def assert_mask_equal(m1, m2, err_msg=''): + """ + Asserts the equality of two masks. + + """ + if m1 is nomask: + assert_(m2 is nomask) + if m2 is nomask: + assert_(m1 is nomask) + assert_array_equal(m1, m2, err_msg=err_msg) diff --git a/venv/Lib/site-packages/numpy/ma/timer_comparison.py b/venv/Lib/site-packages/numpy/ma/timer_comparison.py new file mode 100644 index 0000000..9eb1a23 --- /dev/null +++ b/venv/Lib/site-packages/numpy/ma/timer_comparison.py @@ -0,0 +1,443 @@ +import timeit +from functools import reduce + +import numpy as np +from numpy import float_ +import numpy.core.fromnumeric as fromnumeric + +from numpy.testing import build_err_msg + + +pi = np.pi + +class ModuleTester: + def __init__(self, module): + self.module = module + self.allequal = module.allequal + self.arange = module.arange + self.array = module.array + self.concatenate = module.concatenate + self.count = module.count + self.equal = module.equal + self.filled = module.filled + self.getmask = module.getmask + self.getmaskarray = module.getmaskarray + self.id = id + self.inner = module.inner + self.make_mask = module.make_mask + self.masked = module.masked + self.masked_array = module.masked_array + self.masked_values = module.masked_values + self.mask_or = module.mask_or + self.nomask = module.nomask + self.ones = module.ones + self.outer = module.outer + self.repeat = module.repeat + self.resize = module.resize + self.sort = module.sort + self.take = module.take + self.transpose = module.transpose + self.zeros = module.zeros + self.MaskType = module.MaskType + try: + self.umath = module.umath + except AttributeError: + self.umath = module.core.umath + self.testnames = [] + + def assert_array_compare(self, comparison, x, y, err_msg='', header='', + fill_value=True): + """ + Assert that a comparison of two masked arrays is satisfied elementwise. + + """ + xf = self.filled(x) + yf = self.filled(y) + m = self.mask_or(self.getmask(x), self.getmask(y)) + + x = self.filled(self.masked_array(xf, mask=m), fill_value) + y = self.filled(self.masked_array(yf, mask=m), fill_value) + if (x.dtype.char != "O"): + x = x.astype(float_) + if isinstance(x, np.ndarray) and x.size > 1: + x[np.isnan(x)] = 0 + elif np.isnan(x): + x = 0 + if (y.dtype.char != "O"): + y = y.astype(float_) + if isinstance(y, np.ndarray) and y.size > 1: + y[np.isnan(y)] = 0 + elif np.isnan(y): + y = 0 + try: + cond = (x.shape == () or y.shape == ()) or x.shape == y.shape + if not cond: + msg = build_err_msg([x, y], + err_msg + + f'\n(shapes {x.shape}, {y.shape} mismatch)', + header=header, + names=('x', 'y')) + assert cond, msg + val = comparison(x, y) + if m is not self.nomask and fill_value: + val = self.masked_array(val, mask=m) + if isinstance(val, bool): + cond = val + reduced = [0] + else: + reduced = val.ravel() + cond = reduced.all() + reduced = reduced.tolist() + if not cond: + match = 100-100.0*reduced.count(1)/len(reduced) + msg = build_err_msg([x, y], + err_msg + + '\n(mismatch %s%%)' % (match,), + header=header, + names=('x', 'y')) + assert cond, msg + except ValueError as e: + msg = build_err_msg([x, y], err_msg, header=header, names=('x', 'y')) + raise ValueError(msg) from e + + def assert_array_equal(self, x, y, err_msg=''): + """ + Checks the elementwise equality of two masked arrays. + + """ + self.assert_array_compare(self.equal, x, y, err_msg=err_msg, + header='Arrays are not equal') + + @np.errstate(all='ignore') + def test_0(self): + """ + Tests creation + + """ + x = np.array([1., 1., 1., -2., pi/2.0, 4., 5., -10., 10., 1., 2., 3.]) + m = [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0] + xm = self.masked_array(x, mask=m) + xm[0] + + @np.errstate(all='ignore') + def test_1(self): + """ + Tests creation + + """ + x = np.array([1., 1., 1., -2., pi/2.0, 4., 5., -10., 10., 1., 2., 3.]) + y = np.array([5., 0., 3., 2., -1., -4., 0., -10., 10., 1., 0., 3.]) + m1 = [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0] + m2 = [0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1] + xm = self.masked_array(x, mask=m1) + ym = self.masked_array(y, mask=m2) + xf = np.where(m1, 1.e+20, x) + xm.set_fill_value(1.e+20) + + assert((xm-ym).filled(0).any()) + s = x.shape + assert(xm.size == reduce(lambda x, y:x*y, s)) + assert(self.count(xm) == len(m1) - reduce(lambda x, y:x+y, m1)) + + for s in [(4, 3), (6, 2)]: + x.shape = s + y.shape = s + xm.shape = s + ym.shape = s + xf.shape = s + assert(self.count(xm) == len(m1) - reduce(lambda x, y:x+y, m1)) + + @np.errstate(all='ignore') + def test_2(self): + """ + Tests conversions and indexing. + + """ + x1 = np.array([1, 2, 4, 3]) + x2 = self.array(x1, mask=[1, 0, 0, 0]) + x3 = self.array(x1, mask=[0, 1, 0, 1]) + x4 = self.array(x1) + # test conversion to strings, no errors + str(x2) + repr(x2) + # tests of indexing + assert type(x2[1]) is type(x1[1]) + assert x1[1] == x2[1] + x1[2] = 9 + x2[2] = 9 + self.assert_array_equal(x1, x2) + x1[1:3] = 99 + x2[1:3] = 99 + x2[1] = self.masked + x2[1:3] = self.masked + x2[:] = x1 + x2[1] = self.masked + x3[:] = self.masked_array([1, 2, 3, 4], [0, 1, 1, 0]) + x4[:] = self.masked_array([1, 2, 3, 4], [0, 1, 1, 0]) + x1 = np.arange(5)*1.0 + x2 = self.masked_values(x1, 3.0) + x1 = self.array([1, 'hello', 2, 3], object) + x2 = np.array([1, 'hello', 2, 3], object) + # check that no error occurs. + x1[1] + x2[1] + assert x1[1:1].shape == (0,) + # Tests copy-size + n = [0, 0, 1, 0, 0] + m = self.make_mask(n) + m2 = self.make_mask(m) + assert(m is m2) + m3 = self.make_mask(m, copy=1) + assert(m is not m3) + + @np.errstate(all='ignore') + def test_3(self): + """ + Tests resize/repeat + + """ + x4 = self.arange(4) + x4[2] = self.masked + y4 = self.resize(x4, (8,)) + assert self.allequal(self.concatenate([x4, x4]), y4) + assert self.allequal(self.getmask(y4), [0, 0, 1, 0, 0, 0, 1, 0]) + y5 = self.repeat(x4, (2, 2, 2, 2), axis=0) + self.assert_array_equal(y5, [0, 0, 1, 1, 2, 2, 3, 3]) + y6 = self.repeat(x4, 2, axis=0) + assert self.allequal(y5, y6) + y7 = x4.repeat((2, 2, 2, 2), axis=0) + assert self.allequal(y5, y7) + y8 = x4.repeat(2, 0) + assert self.allequal(y5, y8) + + @np.errstate(all='ignore') + def test_4(self): + """ + Test of take, transpose, inner, outer products. + + """ + x = self.arange(24) + y = np.arange(24) + x[5:6] = self.masked + x = x.reshape(2, 3, 4) + y = y.reshape(2, 3, 4) + assert self.allequal(np.transpose(y, (2, 0, 1)), self.transpose(x, (2, 0, 1))) + assert self.allequal(np.take(y, (2, 0, 1), 1), self.take(x, (2, 0, 1), 1)) + assert self.allequal(np.inner(self.filled(x, 0), self.filled(y, 0)), + self.inner(x, y)) + assert self.allequal(np.outer(self.filled(x, 0), self.filled(y, 0)), + self.outer(x, y)) + y = self.array(['abc', 1, 'def', 2, 3], object) + y[2] = self.masked + t = self.take(y, [0, 3, 4]) + assert t[0] == 'abc' + assert t[1] == 2 + assert t[2] == 3 + + @np.errstate(all='ignore') + def test_5(self): + """ + Tests inplace w/ scalar + + """ + x = self.arange(10) + y = self.arange(10) + xm = self.arange(10) + xm[2] = self.masked + x += 1 + assert self.allequal(x, y+1) + xm += 1 + assert self.allequal(xm, y+1) + + x = self.arange(10) + xm = self.arange(10) + xm[2] = self.masked + x -= 1 + assert self.allequal(x, y-1) + xm -= 1 + assert self.allequal(xm, y-1) + + x = self.arange(10)*1.0 + xm = self.arange(10)*1.0 + xm[2] = self.masked + x *= 2.0 + assert self.allequal(x, y*2) + xm *= 2.0 + assert self.allequal(xm, y*2) + + x = self.arange(10)*2 + xm = self.arange(10)*2 + xm[2] = self.masked + x /= 2 + assert self.allequal(x, y) + xm /= 2 + assert self.allequal(xm, y) + + x = self.arange(10)*1.0 + xm = self.arange(10)*1.0 + xm[2] = self.masked + x /= 2.0 + assert self.allequal(x, y/2.0) + xm /= self.arange(10) + self.assert_array_equal(xm, self.ones((10,))) + + x = self.arange(10).astype(float_) + xm = self.arange(10) + xm[2] = self.masked + x += 1. + assert self.allequal(x, y + 1.) + + @np.errstate(all='ignore') + def test_6(self): + """ + Tests inplace w/ array + + """ + x = self.arange(10, dtype=float_) + y = self.arange(10) + xm = self.arange(10, dtype=float_) + xm[2] = self.masked + m = xm.mask + a = self.arange(10, dtype=float_) + a[-1] = self.masked + x += a + xm += a + assert self.allequal(x, y+a) + assert self.allequal(xm, y+a) + assert self.allequal(xm.mask, self.mask_or(m, a.mask)) + + x = self.arange(10, dtype=float_) + xm = self.arange(10, dtype=float_) + xm[2] = self.masked + m = xm.mask + a = self.arange(10, dtype=float_) + a[-1] = self.masked + x -= a + xm -= a + assert self.allequal(x, y-a) + assert self.allequal(xm, y-a) + assert self.allequal(xm.mask, self.mask_or(m, a.mask)) + + x = self.arange(10, dtype=float_) + xm = self.arange(10, dtype=float_) + xm[2] = self.masked + m = xm.mask + a = self.arange(10, dtype=float_) + a[-1] = self.masked + x *= a + xm *= a + assert self.allequal(x, y*a) + assert self.allequal(xm, y*a) + assert self.allequal(xm.mask, self.mask_or(m, a.mask)) + + x = self.arange(10, dtype=float_) + xm = self.arange(10, dtype=float_) + xm[2] = self.masked + m = xm.mask + a = self.arange(10, dtype=float_) + a[-1] = self.masked + x /= a + xm /= a + + @np.errstate(all='ignore') + def test_7(self): + "Tests ufunc" + d = (self.array([1.0, 0, -1, pi/2]*2, mask=[0, 1]+[0]*6), + self.array([1.0, 0, -1, pi/2]*2, mask=[1, 0]+[0]*6),) + for f in ['sqrt', 'log', 'log10', 'exp', 'conjugate', +# 'sin', 'cos', 'tan', +# 'arcsin', 'arccos', 'arctan', +# 'sinh', 'cosh', 'tanh', +# 'arcsinh', +# 'arccosh', +# 'arctanh', +# 'absolute', 'fabs', 'negative', +# # 'nonzero', 'around', +# 'floor', 'ceil', +# # 'sometrue', 'alltrue', +# 'logical_not', +# 'add', 'subtract', 'multiply', +# 'divide', 'true_divide', 'floor_divide', +# 'remainder', 'fmod', 'hypot', 'arctan2', +# 'equal', 'not_equal', 'less_equal', 'greater_equal', +# 'less', 'greater', +# 'logical_and', 'logical_or', 'logical_xor', + ]: + try: + uf = getattr(self.umath, f) + except AttributeError: + uf = getattr(fromnumeric, f) + mf = getattr(self.module, f) + args = d[:uf.nin] + ur = uf(*args) + mr = mf(*args) + self.assert_array_equal(ur.filled(0), mr.filled(0), f) + self.assert_array_equal(ur._mask, mr._mask) + + @np.errstate(all='ignore') + def test_99(self): + # test average + ott = self.array([0., 1., 2., 3.], mask=[1, 0, 0, 0]) + self.assert_array_equal(2.0, self.average(ott, axis=0)) + self.assert_array_equal(2.0, self.average(ott, weights=[1., 1., 2., 1.])) + result, wts = self.average(ott, weights=[1., 1., 2., 1.], returned=1) + self.assert_array_equal(2.0, result) + assert(wts == 4.0) + ott[:] = self.masked + assert(self.average(ott, axis=0) is self.masked) + ott = self.array([0., 1., 2., 3.], mask=[1, 0, 0, 0]) + ott = ott.reshape(2, 2) + ott[:, 1] = self.masked + self.assert_array_equal(self.average(ott, axis=0), [2.0, 0.0]) + assert(self.average(ott, axis=1)[0] is self.masked) + self.assert_array_equal([2., 0.], self.average(ott, axis=0)) + result, wts = self.average(ott, axis=0, returned=1) + self.assert_array_equal(wts, [1., 0.]) + w1 = [0, 1, 1, 1, 1, 0] + w2 = [[0, 1, 1, 1, 1, 0], [1, 0, 0, 0, 0, 1]] + x = self.arange(6) + self.assert_array_equal(self.average(x, axis=0), 2.5) + self.assert_array_equal(self.average(x, axis=0, weights=w1), 2.5) + y = self.array([self.arange(6), 2.0*self.arange(6)]) + self.assert_array_equal(self.average(y, None), np.add.reduce(np.arange(6))*3./12.) + self.assert_array_equal(self.average(y, axis=0), np.arange(6) * 3./2.) + self.assert_array_equal(self.average(y, axis=1), [self.average(x, axis=0), self.average(x, axis=0) * 2.0]) + self.assert_array_equal(self.average(y, None, weights=w2), 20./6.) + self.assert_array_equal(self.average(y, axis=0, weights=w2), [0., 1., 2., 3., 4., 10.]) + self.assert_array_equal(self.average(y, axis=1), [self.average(x, axis=0), self.average(x, axis=0) * 2.0]) + m1 = self.zeros(6) + m2 = [0, 0, 1, 1, 0, 0] + m3 = [[0, 0, 1, 1, 0, 0], [0, 1, 1, 1, 1, 0]] + m4 = self.ones(6) + m5 = [0, 1, 1, 1, 1, 1] + self.assert_array_equal(self.average(self.masked_array(x, m1), axis=0), 2.5) + self.assert_array_equal(self.average(self.masked_array(x, m2), axis=0), 2.5) + self.assert_array_equal(self.average(self.masked_array(x, m5), axis=0), 0.0) + self.assert_array_equal(self.count(self.average(self.masked_array(x, m4), axis=0)), 0) + z = self.masked_array(y, m3) + self.assert_array_equal(self.average(z, None), 20./6.) + self.assert_array_equal(self.average(z, axis=0), [0., 1., 99., 99., 4.0, 7.5]) + self.assert_array_equal(self.average(z, axis=1), [2.5, 5.0]) + self.assert_array_equal(self.average(z, axis=0, weights=w2), [0., 1., 99., 99., 4.0, 10.0]) + + @np.errstate(all='ignore') + def test_A(self): + x = self.arange(24) + x[5:6] = self.masked + x = x.reshape(2, 3, 4) + + +if __name__ == '__main__': + setup_base = ("from __main__ import ModuleTester \n" + "import numpy\n" + "tester = ModuleTester(module)\n") + setup_cur = "import numpy.ma.core as module\n" + setup_base + (nrepeat, nloop) = (10, 10) + + for i in range(1, 8): + func = 'tester.test_%i()' % i + cur = timeit.Timer(func, setup_cur).repeat(nrepeat, nloop*10) + cur = np.sort(cur) + print("#%i" % i + 50*'.') + print(eval("ModuleTester.test_%i.__doc__" % i)) + print(f'core_current : {cur[0]:.3f} - {cur[1]:.3f}') diff --git a/venv/Lib/site-packages/numpy/matlib.py b/venv/Lib/site-packages/numpy/matlib.py new file mode 100644 index 0000000..bd6b632 --- /dev/null +++ b/venv/Lib/site-packages/numpy/matlib.py @@ -0,0 +1,376 @@ +import warnings + +# 2018-05-29, PendingDeprecationWarning added to matrix.__new__ +# 2020-01-23, numpy 1.19.0 PendingDeprecatonWarning +warnings.warn("Importing from numpy.matlib is deprecated since 1.19.0. " + "The matrix subclass is not the recommended way to represent " + "matrices or deal with linear algebra (see " + "https://docs.scipy.org/doc/numpy/user/numpy-for-matlab-users.html). " + "Please adjust your code to use regular ndarray. ", + PendingDeprecationWarning, stacklevel=2) + +import numpy as np +from numpy.matrixlib.defmatrix import matrix, asmatrix +# Matlib.py contains all functions in the numpy namespace with a few +# replacements. See doc/source/reference/routines.matlib.rst for details. +# Need * as we're copying the numpy namespace. +from numpy import * # noqa: F403 + +__version__ = np.__version__ + +__all__ = np.__all__[:] # copy numpy namespace +__all__ += ['rand', 'randn', 'repmat'] + +def empty(shape, dtype=None, order='C'): + """Return a new matrix of given shape and type, without initializing entries. + + Parameters + ---------- + shape : int or tuple of int + Shape of the empty matrix. + dtype : data-type, optional + Desired output data-type. + order : {'C', 'F'}, optional + Whether to store multi-dimensional data in row-major + (C-style) or column-major (Fortran-style) order in + memory. + + See Also + -------- + empty_like, zeros + + Notes + ----- + `empty`, unlike `zeros`, does not set the matrix values to zero, + and may therefore be marginally faster. On the other hand, it requires + the user to manually set all the values in the array, and should be + used with caution. + + Examples + -------- + >>> import numpy.matlib + >>> np.matlib.empty((2, 2)) # filled with random data + matrix([[ 6.76425276e-320, 9.79033856e-307], # random + [ 7.39337286e-309, 3.22135945e-309]]) + >>> np.matlib.empty((2, 2), dtype=int) + matrix([[ 6600475, 0], # random + [ 6586976, 22740995]]) + + """ + return ndarray.__new__(matrix, shape, dtype, order=order) + +def ones(shape, dtype=None, order='C'): + """ + Matrix of ones. + + Return a matrix of given shape and type, filled with ones. + + Parameters + ---------- + shape : {sequence of ints, int} + Shape of the matrix + dtype : data-type, optional + The desired data-type for the matrix, default is np.float64. + order : {'C', 'F'}, optional + Whether to store matrix in C- or Fortran-contiguous order, + default is 'C'. + + Returns + ------- + out : matrix + Matrix of ones of given shape, dtype, and order. + + See Also + -------- + ones : Array of ones. + matlib.zeros : Zero matrix. + + Notes + ----- + If `shape` has length one i.e. ``(N,)``, or is a scalar ``N``, + `out` becomes a single row matrix of shape ``(1,N)``. + + Examples + -------- + >>> np.matlib.ones((2,3)) + matrix([[1., 1., 1.], + [1., 1., 1.]]) + + >>> np.matlib.ones(2) + matrix([[1., 1.]]) + + """ + a = ndarray.__new__(matrix, shape, dtype, order=order) + a.fill(1) + return a + +def zeros(shape, dtype=None, order='C'): + """ + Return a matrix of given shape and type, filled with zeros. + + Parameters + ---------- + shape : int or sequence of ints + Shape of the matrix + dtype : data-type, optional + The desired data-type for the matrix, default is float. + order : {'C', 'F'}, optional + Whether to store the result in C- or Fortran-contiguous order, + default is 'C'. + + Returns + ------- + out : matrix + Zero matrix of given shape, dtype, and order. + + See Also + -------- + numpy.zeros : Equivalent array function. + matlib.ones : Return a matrix of ones. + + Notes + ----- + If `shape` has length one i.e. ``(N,)``, or is a scalar ``N``, + `out` becomes a single row matrix of shape ``(1,N)``. + + Examples + -------- + >>> import numpy.matlib + >>> np.matlib.zeros((2, 3)) + matrix([[0., 0., 0.], + [0., 0., 0.]]) + + >>> np.matlib.zeros(2) + matrix([[0., 0.]]) + + """ + a = ndarray.__new__(matrix, shape, dtype, order=order) + a.fill(0) + return a + +def identity(n,dtype=None): + """ + Returns the square identity matrix of given size. + + Parameters + ---------- + n : int + Size of the returned identity matrix. + dtype : data-type, optional + Data-type of the output. Defaults to ``float``. + + Returns + ------- + out : matrix + `n` x `n` matrix with its main diagonal set to one, + and all other elements zero. + + See Also + -------- + numpy.identity : Equivalent array function. + matlib.eye : More general matrix identity function. + + Examples + -------- + >>> import numpy.matlib + >>> np.matlib.identity(3, dtype=int) + matrix([[1, 0, 0], + [0, 1, 0], + [0, 0, 1]]) + + """ + a = array([1]+n*[0], dtype=dtype) + b = empty((n, n), dtype=dtype) + b.flat = a + return b + +def eye(n,M=None, k=0, dtype=float, order='C'): + """ + Return a matrix with ones on the diagonal and zeros elsewhere. + + Parameters + ---------- + n : int + Number of rows in the output. + M : int, optional + Number of columns in the output, defaults to `n`. + k : int, optional + Index of the diagonal: 0 refers to the main diagonal, + a positive value refers to an upper diagonal, + and a negative value to a lower diagonal. + dtype : dtype, optional + Data-type of the returned matrix. + order : {'C', 'F'}, optional + Whether the output should be stored in row-major (C-style) or + column-major (Fortran-style) order in memory. + + .. versionadded:: 1.14.0 + + Returns + ------- + I : matrix + A `n` x `M` matrix where all elements are equal to zero, + except for the `k`-th diagonal, whose values are equal to one. + + See Also + -------- + numpy.eye : Equivalent array function. + identity : Square identity matrix. + + Examples + -------- + >>> import numpy.matlib + >>> np.matlib.eye(3, k=1, dtype=float) + matrix([[0., 1., 0.], + [0., 0., 1.], + [0., 0., 0.]]) + + """ + return asmatrix(np.eye(n, M=M, k=k, dtype=dtype, order=order)) + +def rand(*args): + """ + Return a matrix of random values with given shape. + + Create a matrix of the given shape and propagate it with + random samples from a uniform distribution over ``[0, 1)``. + + Parameters + ---------- + \\*args : Arguments + Shape of the output. + If given as N integers, each integer specifies the size of one + dimension. + If given as a tuple, this tuple gives the complete shape. + + Returns + ------- + out : ndarray + The matrix of random values with shape given by `\\*args`. + + See Also + -------- + randn, numpy.random.RandomState.rand + + Examples + -------- + >>> np.random.seed(123) + >>> import numpy.matlib + >>> np.matlib.rand(2, 3) + matrix([[0.69646919, 0.28613933, 0.22685145], + [0.55131477, 0.71946897, 0.42310646]]) + >>> np.matlib.rand((2, 3)) + matrix([[0.9807642 , 0.68482974, 0.4809319 ], + [0.39211752, 0.34317802, 0.72904971]]) + + If the first argument is a tuple, other arguments are ignored: + + >>> np.matlib.rand((2, 3), 4) + matrix([[0.43857224, 0.0596779 , 0.39804426], + [0.73799541, 0.18249173, 0.17545176]]) + + """ + if isinstance(args[0], tuple): + args = args[0] + return asmatrix(np.random.rand(*args)) + +def randn(*args): + """ + Return a random matrix with data from the "standard normal" distribution. + + `randn` generates a matrix filled with random floats sampled from a + univariate "normal" (Gaussian) distribution of mean 0 and variance 1. + + Parameters + ---------- + \\*args : Arguments + Shape of the output. + If given as N integers, each integer specifies the size of one + dimension. If given as a tuple, this tuple gives the complete shape. + + Returns + ------- + Z : matrix of floats + A matrix of floating-point samples drawn from the standard normal + distribution. + + See Also + -------- + rand, numpy.random.RandomState.randn + + Notes + ----- + For random samples from :math:`N(\\mu, \\sigma^2)`, use: + + ``sigma * np.matlib.randn(...) + mu`` + + Examples + -------- + >>> np.random.seed(123) + >>> import numpy.matlib + >>> np.matlib.randn(1) + matrix([[-1.0856306]]) + >>> np.matlib.randn(1, 2, 3) + matrix([[ 0.99734545, 0.2829785 , -1.50629471], + [-0.57860025, 1.65143654, -2.42667924]]) + + Two-by-four matrix of samples from :math:`N(3, 6.25)`: + + >>> 2.5 * np.matlib.randn((2, 4)) + 3 + matrix([[1.92771843, 6.16484065, 0.83314899, 1.30278462], + [2.76322758, 6.72847407, 1.40274501, 1.8900451 ]]) + + """ + if isinstance(args[0], tuple): + args = args[0] + return asmatrix(np.random.randn(*args)) + +def repmat(a, m, n): + """ + Repeat a 0-D to 2-D array or matrix MxN times. + + Parameters + ---------- + a : array_like + The array or matrix to be repeated. + m, n : int + The number of times `a` is repeated along the first and second axes. + + Returns + ------- + out : ndarray + The result of repeating `a`. + + Examples + -------- + >>> import numpy.matlib + >>> a0 = np.array(1) + >>> np.matlib.repmat(a0, 2, 3) + array([[1, 1, 1], + [1, 1, 1]]) + + >>> a1 = np.arange(4) + >>> np.matlib.repmat(a1, 2, 2) + array([[0, 1, 2, 3, 0, 1, 2, 3], + [0, 1, 2, 3, 0, 1, 2, 3]]) + + >>> a2 = np.asmatrix(np.arange(6).reshape(2, 3)) + >>> np.matlib.repmat(a2, 2, 3) + matrix([[0, 1, 2, 0, 1, 2, 0, 1, 2], + [3, 4, 5, 3, 4, 5, 3, 4, 5], + [0, 1, 2, 0, 1, 2, 0, 1, 2], + [3, 4, 5, 3, 4, 5, 3, 4, 5]]) + + """ + a = asanyarray(a) + ndim = a.ndim + if ndim == 0: + origrows, origcols = (1, 1) + elif ndim == 1: + origrows, origcols = (1, a.shape[0]) + else: + origrows, origcols = a.shape + rows = origrows * m + cols = origcols * n + c = a.reshape(1, a.size).repeat(m, 0).reshape(rows, origcols).repeat(n, 0) + return c.reshape(rows, cols) diff --git a/venv/Lib/site-packages/numpy/matrixlib/__init__.py b/venv/Lib/site-packages/numpy/matrixlib/__init__.py new file mode 100644 index 0000000..54154d1 --- /dev/null +++ b/venv/Lib/site-packages/numpy/matrixlib/__init__.py @@ -0,0 +1,10 @@ +"""Sub-package containing the matrix class and related functions. + +""" +from .defmatrix import * + +__all__ = defmatrix.__all__ + +from numpy._pytesttester import PytestTester +test = PytestTester(__name__) +del PytestTester diff --git a/venv/Lib/site-packages/numpy/matrixlib/__init__.pyi b/venv/Lib/site-packages/numpy/matrixlib/__init__.pyi new file mode 100644 index 0000000..b9005c4 --- /dev/null +++ b/venv/Lib/site-packages/numpy/matrixlib/__init__.pyi @@ -0,0 +1,8 @@ +from typing import Any, List + +__all__: List[str] + +matrix: Any +bmat: Any +mat: Any +asmatrix: Any diff --git a/venv/Lib/site-packages/numpy/matrixlib/defmatrix.py b/venv/Lib/site-packages/numpy/matrixlib/defmatrix.py new file mode 100644 index 0000000..a414ee9 --- /dev/null +++ b/venv/Lib/site-packages/numpy/matrixlib/defmatrix.py @@ -0,0 +1,1113 @@ +__all__ = ['matrix', 'bmat', 'mat', 'asmatrix'] + +import sys +import warnings +import ast +import numpy.core.numeric as N +from numpy.core.numeric import concatenate, isscalar +from numpy.core.overrides import set_module +# While not in __all__, matrix_power used to be defined here, so we import +# it for backward compatibility. +from numpy.linalg import matrix_power + + +def _convert_from_string(data): + for char in '[]': + data = data.replace(char, '') + + rows = data.split(';') + newdata = [] + count = 0 + for row in rows: + trow = row.split(',') + newrow = [] + for col in trow: + temp = col.split() + newrow.extend(map(ast.literal_eval, temp)) + if count == 0: + Ncols = len(newrow) + elif len(newrow) != Ncols: + raise ValueError("Rows not the same size.") + count += 1 + newdata.append(newrow) + return newdata + + +@set_module('numpy') +def asmatrix(data, dtype=None): + """ + Interpret the input as a matrix. + + Unlike `matrix`, `asmatrix` does not make a copy if the input is already + a matrix or an ndarray. Equivalent to ``matrix(data, copy=False)``. + + Parameters + ---------- + data : array_like + Input data. + dtype : data-type + Data-type of the output matrix. + + Returns + ------- + mat : matrix + `data` interpreted as a matrix. + + Examples + -------- + >>> x = np.array([[1, 2], [3, 4]]) + + >>> m = np.asmatrix(x) + + >>> x[0,0] = 5 + + >>> m + matrix([[5, 2], + [3, 4]]) + + """ + return matrix(data, dtype=dtype, copy=False) + + +@set_module('numpy') +class matrix(N.ndarray): + """ + matrix(data, dtype=None, copy=True) + + .. note:: It is no longer recommended to use this class, even for linear + algebra. Instead use regular arrays. The class may be removed + in the future. + + Returns a matrix from an array-like object, or from a string of data. + A matrix is a specialized 2-D array that retains its 2-D nature + through operations. It has certain special operators, such as ``*`` + (matrix multiplication) and ``**`` (matrix power). + + Parameters + ---------- + data : array_like or string + If `data` is a string, it is interpreted as a matrix with commas + or spaces separating columns, and semicolons separating rows. + dtype : data-type + Data-type of the output matrix. + copy : bool + If `data` is already an `ndarray`, then this flag determines + whether the data is copied (the default), or whether a view is + constructed. + + See Also + -------- + array + + Examples + -------- + >>> a = np.matrix('1 2; 3 4') + >>> a + matrix([[1, 2], + [3, 4]]) + + >>> np.matrix([[1, 2], [3, 4]]) + matrix([[1, 2], + [3, 4]]) + + """ + __array_priority__ = 10.0 + def __new__(subtype, data, dtype=None, copy=True): + warnings.warn('the matrix subclass is not the recommended way to ' + 'represent matrices or deal with linear algebra (see ' + 'https://docs.scipy.org/doc/numpy/user/' + 'numpy-for-matlab-users.html). ' + 'Please adjust your code to use regular ndarray.', + PendingDeprecationWarning, stacklevel=2) + if isinstance(data, matrix): + dtype2 = data.dtype + if (dtype is None): + dtype = dtype2 + if (dtype2 == dtype) and (not copy): + return data + return data.astype(dtype) + + if isinstance(data, N.ndarray): + if dtype is None: + intype = data.dtype + else: + intype = N.dtype(dtype) + new = data.view(subtype) + if intype != data.dtype: + return new.astype(intype) + if copy: return new.copy() + else: return new + + if isinstance(data, str): + data = _convert_from_string(data) + + # now convert data to an array + arr = N.array(data, dtype=dtype, copy=copy) + ndim = arr.ndim + shape = arr.shape + if (ndim > 2): + raise ValueError("matrix must be 2-dimensional") + elif ndim == 0: + shape = (1, 1) + elif ndim == 1: + shape = (1, shape[0]) + + order = 'C' + if (ndim == 2) and arr.flags.fortran: + order = 'F' + + if not (order or arr.flags.contiguous): + arr = arr.copy() + + ret = N.ndarray.__new__(subtype, shape, arr.dtype, + buffer=arr, + order=order) + return ret + + def __array_finalize__(self, obj): + self._getitem = False + if (isinstance(obj, matrix) and obj._getitem): return + ndim = self.ndim + if (ndim == 2): + return + if (ndim > 2): + newshape = tuple([x for x in self.shape if x > 1]) + ndim = len(newshape) + if ndim == 2: + self.shape = newshape + return + elif (ndim > 2): + raise ValueError("shape too large to be a matrix.") + else: + newshape = self.shape + if ndim == 0: + self.shape = (1, 1) + elif ndim == 1: + self.shape = (1, newshape[0]) + return + + def __getitem__(self, index): + self._getitem = True + + try: + out = N.ndarray.__getitem__(self, index) + finally: + self._getitem = False + + if not isinstance(out, N.ndarray): + return out + + if out.ndim == 0: + return out[()] + if out.ndim == 1: + sh = out.shape[0] + # Determine when we should have a column array + try: + n = len(index) + except Exception: + n = 0 + if n > 1 and isscalar(index[1]): + out.shape = (sh, 1) + else: + out.shape = (1, sh) + return out + + def __mul__(self, other): + if isinstance(other, (N.ndarray, list, tuple)) : + # This promotes 1-D vectors to row vectors + return N.dot(self, asmatrix(other)) + if isscalar(other) or not hasattr(other, '__rmul__') : + return N.dot(self, other) + return NotImplemented + + def __rmul__(self, other): + return N.dot(other, self) + + def __imul__(self, other): + self[:] = self * other + return self + + def __pow__(self, other): + return matrix_power(self, other) + + def __ipow__(self, other): + self[:] = self ** other + return self + + def __rpow__(self, other): + return NotImplemented + + def _align(self, axis): + """A convenience function for operations that need to preserve axis + orientation. + """ + if axis is None: + return self[0, 0] + elif axis==0: + return self + elif axis==1: + return self.transpose() + else: + raise ValueError("unsupported axis") + + def _collapse(self, axis): + """A convenience function for operations that want to collapse + to a scalar like _align, but are using keepdims=True + """ + if axis is None: + return self[0, 0] + else: + return self + + # Necessary because base-class tolist expects dimension + # reduction by x[0] + def tolist(self): + """ + Return the matrix as a (possibly nested) list. + + See `ndarray.tolist` for full documentation. + + See Also + -------- + ndarray.tolist + + Examples + -------- + >>> x = np.matrix(np.arange(12).reshape((3,4))); x + matrix([[ 0, 1, 2, 3], + [ 4, 5, 6, 7], + [ 8, 9, 10, 11]]) + >>> x.tolist() + [[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11]] + + """ + return self.__array__().tolist() + + # To preserve orientation of result... + def sum(self, axis=None, dtype=None, out=None): + """ + Returns the sum of the matrix elements, along the given axis. + + Refer to `numpy.sum` for full documentation. + + See Also + -------- + numpy.sum + + Notes + ----- + This is the same as `ndarray.sum`, except that where an `ndarray` would + be returned, a `matrix` object is returned instead. + + Examples + -------- + >>> x = np.matrix([[1, 2], [4, 3]]) + >>> x.sum() + 10 + >>> x.sum(axis=1) + matrix([[3], + [7]]) + >>> x.sum(axis=1, dtype='float') + matrix([[3.], + [7.]]) + >>> out = np.zeros((2, 1), dtype='float') + >>> x.sum(axis=1, dtype='float', out=np.asmatrix(out)) + matrix([[3.], + [7.]]) + + """ + return N.ndarray.sum(self, axis, dtype, out, keepdims=True)._collapse(axis) + + + # To update docstring from array to matrix... + def squeeze(self, axis=None): + """ + Return a possibly reshaped matrix. + + Refer to `numpy.squeeze` for more documentation. + + Parameters + ---------- + axis : None or int or tuple of ints, optional + Selects a subset of the axes of length one in the shape. + If an axis is selected with shape entry greater than one, + an error is raised. + + Returns + ------- + squeezed : matrix + The matrix, but as a (1, N) matrix if it had shape (N, 1). + + See Also + -------- + numpy.squeeze : related function + + Notes + ----- + If `m` has a single column then that column is returned + as the single row of a matrix. Otherwise `m` is returned. + The returned matrix is always either `m` itself or a view into `m`. + Supplying an axis keyword argument will not affect the returned matrix + but it may cause an error to be raised. + + Examples + -------- + >>> c = np.matrix([[1], [2]]) + >>> c + matrix([[1], + [2]]) + >>> c.squeeze() + matrix([[1, 2]]) + >>> r = c.T + >>> r + matrix([[1, 2]]) + >>> r.squeeze() + matrix([[1, 2]]) + >>> m = np.matrix([[1, 2], [3, 4]]) + >>> m.squeeze() + matrix([[1, 2], + [3, 4]]) + + """ + return N.ndarray.squeeze(self, axis=axis) + + + # To update docstring from array to matrix... + def flatten(self, order='C'): + """ + Return a flattened copy of the matrix. + + All `N` elements of the matrix are placed into a single row. + + Parameters + ---------- + order : {'C', 'F', 'A', 'K'}, optional + 'C' means to flatten in row-major (C-style) order. 'F' means to + flatten in column-major (Fortran-style) order. 'A' means to + flatten in column-major order if `m` is Fortran *contiguous* in + memory, row-major order otherwise. 'K' means to flatten `m` in + the order the elements occur in memory. The default is 'C'. + + Returns + ------- + y : matrix + A copy of the matrix, flattened to a `(1, N)` matrix where `N` + is the number of elements in the original matrix. + + See Also + -------- + ravel : Return a flattened array. + flat : A 1-D flat iterator over the matrix. + + Examples + -------- + >>> m = np.matrix([[1,2], [3,4]]) + >>> m.flatten() + matrix([[1, 2, 3, 4]]) + >>> m.flatten('F') + matrix([[1, 3, 2, 4]]) + + """ + return N.ndarray.flatten(self, order=order) + + def mean(self, axis=None, dtype=None, out=None): + """ + Returns the average of the matrix elements along the given axis. + + Refer to `numpy.mean` for full documentation. + + See Also + -------- + numpy.mean + + Notes + ----- + Same as `ndarray.mean` except that, where that returns an `ndarray`, + this returns a `matrix` object. + + Examples + -------- + >>> x = np.matrix(np.arange(12).reshape((3, 4))) + >>> x + matrix([[ 0, 1, 2, 3], + [ 4, 5, 6, 7], + [ 8, 9, 10, 11]]) + >>> x.mean() + 5.5 + >>> x.mean(0) + matrix([[4., 5., 6., 7.]]) + >>> x.mean(1) + matrix([[ 1.5], + [ 5.5], + [ 9.5]]) + + """ + return N.ndarray.mean(self, axis, dtype, out, keepdims=True)._collapse(axis) + + def std(self, axis=None, dtype=None, out=None, ddof=0): + """ + Return the standard deviation of the array elements along the given axis. + + Refer to `numpy.std` for full documentation. + + See Also + -------- + numpy.std + + Notes + ----- + This is the same as `ndarray.std`, except that where an `ndarray` would + be returned, a `matrix` object is returned instead. + + Examples + -------- + >>> x = np.matrix(np.arange(12).reshape((3, 4))) + >>> x + matrix([[ 0, 1, 2, 3], + [ 4, 5, 6, 7], + [ 8, 9, 10, 11]]) + >>> x.std() + 3.4520525295346629 # may vary + >>> x.std(0) + matrix([[ 3.26598632, 3.26598632, 3.26598632, 3.26598632]]) # may vary + >>> x.std(1) + matrix([[ 1.11803399], + [ 1.11803399], + [ 1.11803399]]) + + """ + return N.ndarray.std(self, axis, dtype, out, ddof, keepdims=True)._collapse(axis) + + def var(self, axis=None, dtype=None, out=None, ddof=0): + """ + Returns the variance of the matrix elements, along the given axis. + + Refer to `numpy.var` for full documentation. + + See Also + -------- + numpy.var + + Notes + ----- + This is the same as `ndarray.var`, except that where an `ndarray` would + be returned, a `matrix` object is returned instead. + + Examples + -------- + >>> x = np.matrix(np.arange(12).reshape((3, 4))) + >>> x + matrix([[ 0, 1, 2, 3], + [ 4, 5, 6, 7], + [ 8, 9, 10, 11]]) + >>> x.var() + 11.916666666666666 + >>> x.var(0) + matrix([[ 10.66666667, 10.66666667, 10.66666667, 10.66666667]]) # may vary + >>> x.var(1) + matrix([[1.25], + [1.25], + [1.25]]) + + """ + return N.ndarray.var(self, axis, dtype, out, ddof, keepdims=True)._collapse(axis) + + def prod(self, axis=None, dtype=None, out=None): + """ + Return the product of the array elements over the given axis. + + Refer to `prod` for full documentation. + + See Also + -------- + prod, ndarray.prod + + Notes + ----- + Same as `ndarray.prod`, except, where that returns an `ndarray`, this + returns a `matrix` object instead. + + Examples + -------- + >>> x = np.matrix(np.arange(12).reshape((3,4))); x + matrix([[ 0, 1, 2, 3], + [ 4, 5, 6, 7], + [ 8, 9, 10, 11]]) + >>> x.prod() + 0 + >>> x.prod(0) + matrix([[ 0, 45, 120, 231]]) + >>> x.prod(1) + matrix([[ 0], + [ 840], + [7920]]) + + """ + return N.ndarray.prod(self, axis, dtype, out, keepdims=True)._collapse(axis) + + def any(self, axis=None, out=None): + """ + Test whether any array element along a given axis evaluates to True. + + Refer to `numpy.any` for full documentation. + + Parameters + ---------- + axis : int, optional + Axis along which logical OR is performed + out : ndarray, optional + Output to existing array instead of creating new one, must have + same shape as expected output + + Returns + ------- + any : bool, ndarray + Returns a single bool if `axis` is ``None``; otherwise, + returns `ndarray` + + """ + return N.ndarray.any(self, axis, out, keepdims=True)._collapse(axis) + + def all(self, axis=None, out=None): + """ + Test whether all matrix elements along a given axis evaluate to True. + + Parameters + ---------- + See `numpy.all` for complete descriptions + + See Also + -------- + numpy.all + + Notes + ----- + This is the same as `ndarray.all`, but it returns a `matrix` object. + + Examples + -------- + >>> x = np.matrix(np.arange(12).reshape((3,4))); x + matrix([[ 0, 1, 2, 3], + [ 4, 5, 6, 7], + [ 8, 9, 10, 11]]) + >>> y = x[0]; y + matrix([[0, 1, 2, 3]]) + >>> (x == y) + matrix([[ True, True, True, True], + [False, False, False, False], + [False, False, False, False]]) + >>> (x == y).all() + False + >>> (x == y).all(0) + matrix([[False, False, False, False]]) + >>> (x == y).all(1) + matrix([[ True], + [False], + [False]]) + + """ + return N.ndarray.all(self, axis, out, keepdims=True)._collapse(axis) + + def max(self, axis=None, out=None): + """ + Return the maximum value along an axis. + + Parameters + ---------- + See `amax` for complete descriptions + + See Also + -------- + amax, ndarray.max + + Notes + ----- + This is the same as `ndarray.max`, but returns a `matrix` object + where `ndarray.max` would return an ndarray. + + Examples + -------- + >>> x = np.matrix(np.arange(12).reshape((3,4))); x + matrix([[ 0, 1, 2, 3], + [ 4, 5, 6, 7], + [ 8, 9, 10, 11]]) + >>> x.max() + 11 + >>> x.max(0) + matrix([[ 8, 9, 10, 11]]) + >>> x.max(1) + matrix([[ 3], + [ 7], + [11]]) + + """ + return N.ndarray.max(self, axis, out, keepdims=True)._collapse(axis) + + def argmax(self, axis=None, out=None): + """ + Indexes of the maximum values along an axis. + + Return the indexes of the first occurrences of the maximum values + along the specified axis. If axis is None, the index is for the + flattened matrix. + + Parameters + ---------- + See `numpy.argmax` for complete descriptions + + See Also + -------- + numpy.argmax + + Notes + ----- + This is the same as `ndarray.argmax`, but returns a `matrix` object + where `ndarray.argmax` would return an `ndarray`. + + Examples + -------- + >>> x = np.matrix(np.arange(12).reshape((3,4))); x + matrix([[ 0, 1, 2, 3], + [ 4, 5, 6, 7], + [ 8, 9, 10, 11]]) + >>> x.argmax() + 11 + >>> x.argmax(0) + matrix([[2, 2, 2, 2]]) + >>> x.argmax(1) + matrix([[3], + [3], + [3]]) + + """ + return N.ndarray.argmax(self, axis, out)._align(axis) + + def min(self, axis=None, out=None): + """ + Return the minimum value along an axis. + + Parameters + ---------- + See `amin` for complete descriptions. + + See Also + -------- + amin, ndarray.min + + Notes + ----- + This is the same as `ndarray.min`, but returns a `matrix` object + where `ndarray.min` would return an ndarray. + + Examples + -------- + >>> x = -np.matrix(np.arange(12).reshape((3,4))); x + matrix([[ 0, -1, -2, -3], + [ -4, -5, -6, -7], + [ -8, -9, -10, -11]]) + >>> x.min() + -11 + >>> x.min(0) + matrix([[ -8, -9, -10, -11]]) + >>> x.min(1) + matrix([[ -3], + [ -7], + [-11]]) + + """ + return N.ndarray.min(self, axis, out, keepdims=True)._collapse(axis) + + def argmin(self, axis=None, out=None): + """ + Indexes of the minimum values along an axis. + + Return the indexes of the first occurrences of the minimum values + along the specified axis. If axis is None, the index is for the + flattened matrix. + + Parameters + ---------- + See `numpy.argmin` for complete descriptions. + + See Also + -------- + numpy.argmin + + Notes + ----- + This is the same as `ndarray.argmin`, but returns a `matrix` object + where `ndarray.argmin` would return an `ndarray`. + + Examples + -------- + >>> x = -np.matrix(np.arange(12).reshape((3,4))); x + matrix([[ 0, -1, -2, -3], + [ -4, -5, -6, -7], + [ -8, -9, -10, -11]]) + >>> x.argmin() + 11 + >>> x.argmin(0) + matrix([[2, 2, 2, 2]]) + >>> x.argmin(1) + matrix([[3], + [3], + [3]]) + + """ + return N.ndarray.argmin(self, axis, out)._align(axis) + + def ptp(self, axis=None, out=None): + """ + Peak-to-peak (maximum - minimum) value along the given axis. + + Refer to `numpy.ptp` for full documentation. + + See Also + -------- + numpy.ptp + + Notes + ----- + Same as `ndarray.ptp`, except, where that would return an `ndarray` object, + this returns a `matrix` object. + + Examples + -------- + >>> x = np.matrix(np.arange(12).reshape((3,4))); x + matrix([[ 0, 1, 2, 3], + [ 4, 5, 6, 7], + [ 8, 9, 10, 11]]) + >>> x.ptp() + 11 + >>> x.ptp(0) + matrix([[8, 8, 8, 8]]) + >>> x.ptp(1) + matrix([[3], + [3], + [3]]) + + """ + return N.ndarray.ptp(self, axis, out)._align(axis) + + @property + def I(self): + """ + Returns the (multiplicative) inverse of invertible `self`. + + Parameters + ---------- + None + + Returns + ------- + ret : matrix object + If `self` is non-singular, `ret` is such that ``ret * self`` == + ``self * ret`` == ``np.matrix(np.eye(self[0,:].size))`` all return + ``True``. + + Raises + ------ + numpy.linalg.LinAlgError: Singular matrix + If `self` is singular. + + See Also + -------- + linalg.inv + + Examples + -------- + >>> m = np.matrix('[1, 2; 3, 4]'); m + matrix([[1, 2], + [3, 4]]) + >>> m.getI() + matrix([[-2. , 1. ], + [ 1.5, -0.5]]) + >>> m.getI() * m + matrix([[ 1., 0.], # may vary + [ 0., 1.]]) + + """ + M, N = self.shape + if M == N: + from numpy.linalg import inv as func + else: + from numpy.linalg import pinv as func + return asmatrix(func(self)) + + @property + def A(self): + """ + Return `self` as an `ndarray` object. + + Equivalent to ``np.asarray(self)``. + + Parameters + ---------- + None + + Returns + ------- + ret : ndarray + `self` as an `ndarray` + + Examples + -------- + >>> x = np.matrix(np.arange(12).reshape((3,4))); x + matrix([[ 0, 1, 2, 3], + [ 4, 5, 6, 7], + [ 8, 9, 10, 11]]) + >>> x.getA() + array([[ 0, 1, 2, 3], + [ 4, 5, 6, 7], + [ 8, 9, 10, 11]]) + + """ + return self.__array__() + + @property + def A1(self): + """ + Return `self` as a flattened `ndarray`. + + Equivalent to ``np.asarray(x).ravel()`` + + Parameters + ---------- + None + + Returns + ------- + ret : ndarray + `self`, 1-D, as an `ndarray` + + Examples + -------- + >>> x = np.matrix(np.arange(12).reshape((3,4))); x + matrix([[ 0, 1, 2, 3], + [ 4, 5, 6, 7], + [ 8, 9, 10, 11]]) + >>> x.getA1() + array([ 0, 1, 2, ..., 9, 10, 11]) + + + """ + return self.__array__().ravel() + + + def ravel(self, order='C'): + """ + Return a flattened matrix. + + Refer to `numpy.ravel` for more documentation. + + Parameters + ---------- + order : {'C', 'F', 'A', 'K'}, optional + The elements of `m` are read using this index order. 'C' means to + index the elements in C-like order, with the last axis index + changing fastest, back to the first axis index changing slowest. + 'F' means to index the elements in Fortran-like index order, with + the first index changing fastest, and the last index changing + slowest. Note that the 'C' and 'F' options take no account of the + memory layout of the underlying array, and only refer to the order + of axis indexing. 'A' means to read the elements in Fortran-like + index order if `m` is Fortran *contiguous* in memory, C-like order + otherwise. 'K' means to read the elements in the order they occur + in memory, except for reversing the data when strides are negative. + By default, 'C' index order is used. + + Returns + ------- + ret : matrix + Return the matrix flattened to shape `(1, N)` where `N` + is the number of elements in the original matrix. + A copy is made only if necessary. + + See Also + -------- + matrix.flatten : returns a similar output matrix but always a copy + matrix.flat : a flat iterator on the array. + numpy.ravel : related function which returns an ndarray + + """ + return N.ndarray.ravel(self, order=order) + + @property + def T(self): + """ + Returns the transpose of the matrix. + + Does *not* conjugate! For the complex conjugate transpose, use ``.H``. + + Parameters + ---------- + None + + Returns + ------- + ret : matrix object + The (non-conjugated) transpose of the matrix. + + See Also + -------- + transpose, getH + + Examples + -------- + >>> m = np.matrix('[1, 2; 3, 4]') + >>> m + matrix([[1, 2], + [3, 4]]) + >>> m.getT() + matrix([[1, 3], + [2, 4]]) + + """ + return self.transpose() + + @property + def H(self): + """ + Returns the (complex) conjugate transpose of `self`. + + Equivalent to ``np.transpose(self)`` if `self` is real-valued. + + Parameters + ---------- + None + + Returns + ------- + ret : matrix object + complex conjugate transpose of `self` + + Examples + -------- + >>> x = np.matrix(np.arange(12).reshape((3,4))) + >>> z = x - 1j*x; z + matrix([[ 0. +0.j, 1. -1.j, 2. -2.j, 3. -3.j], + [ 4. -4.j, 5. -5.j, 6. -6.j, 7. -7.j], + [ 8. -8.j, 9. -9.j, 10.-10.j, 11.-11.j]]) + >>> z.getH() + matrix([[ 0. -0.j, 4. +4.j, 8. +8.j], + [ 1. +1.j, 5. +5.j, 9. +9.j], + [ 2. +2.j, 6. +6.j, 10.+10.j], + [ 3. +3.j, 7. +7.j, 11.+11.j]]) + + """ + if issubclass(self.dtype.type, N.complexfloating): + return self.transpose().conjugate() + else: + return self.transpose() + + # kept for compatibility + getT = T.fget + getA = A.fget + getA1 = A1.fget + getH = H.fget + getI = I.fget + +def _from_string(str, gdict, ldict): + rows = str.split(';') + rowtup = [] + for row in rows: + trow = row.split(',') + newrow = [] + for x in trow: + newrow.extend(x.split()) + trow = newrow + coltup = [] + for col in trow: + col = col.strip() + try: + thismat = ldict[col] + except KeyError: + try: + thismat = gdict[col] + except KeyError as e: + raise NameError(f"name {col!r} is not defined") from None + + coltup.append(thismat) + rowtup.append(concatenate(coltup, axis=-1)) + return concatenate(rowtup, axis=0) + + +@set_module('numpy') +def bmat(obj, ldict=None, gdict=None): + """ + Build a matrix object from a string, nested sequence, or array. + + Parameters + ---------- + obj : str or array_like + Input data. If a string, variables in the current scope may be + referenced by name. + ldict : dict, optional + A dictionary that replaces local operands in current frame. + Ignored if `obj` is not a string or `gdict` is None. + gdict : dict, optional + A dictionary that replaces global operands in current frame. + Ignored if `obj` is not a string. + + Returns + ------- + out : matrix + Returns a matrix object, which is a specialized 2-D array. + + See Also + -------- + block : + A generalization of this function for N-d arrays, that returns normal + ndarrays. + + Examples + -------- + >>> A = np.mat('1 1; 1 1') + >>> B = np.mat('2 2; 2 2') + >>> C = np.mat('3 4; 5 6') + >>> D = np.mat('7 8; 9 0') + + All the following expressions construct the same block matrix: + + >>> np.bmat([[A, B], [C, D]]) + matrix([[1, 1, 2, 2], + [1, 1, 2, 2], + [3, 4, 7, 8], + [5, 6, 9, 0]]) + >>> np.bmat(np.r_[np.c_[A, B], np.c_[C, D]]) + matrix([[1, 1, 2, 2], + [1, 1, 2, 2], + [3, 4, 7, 8], + [5, 6, 9, 0]]) + >>> np.bmat('A,B; C,D') + matrix([[1, 1, 2, 2], + [1, 1, 2, 2], + [3, 4, 7, 8], + [5, 6, 9, 0]]) + + """ + if isinstance(obj, str): + if gdict is None: + # get previous frame + frame = sys._getframe().f_back + glob_dict = frame.f_globals + loc_dict = frame.f_locals + else: + glob_dict = gdict + loc_dict = ldict + + return matrix(_from_string(obj, glob_dict, loc_dict)) + + if isinstance(obj, (tuple, list)): + # [[A,B],[C,D]] + arr_rows = [] + for row in obj: + if isinstance(row, N.ndarray): # not 2-d + return matrix(concatenate(obj, axis=-1)) + else: + arr_rows.append(concatenate(row, axis=-1)) + return matrix(concatenate(arr_rows, axis=0)) + if isinstance(obj, N.ndarray): + return matrix(obj) + +mat = asmatrix diff --git a/venv/Lib/site-packages/numpy/matrixlib/setup.py b/venv/Lib/site-packages/numpy/matrixlib/setup.py new file mode 100644 index 0000000..4fed75d --- /dev/null +++ b/venv/Lib/site-packages/numpy/matrixlib/setup.py @@ -0,0 +1,12 @@ +#!/usr/bin/env python3 +def configuration(parent_package='', top_path=None): + from numpy.distutils.misc_util import Configuration + config = Configuration('matrixlib', parent_package, top_path) + config.add_subpackage('tests') + config.add_data_files('*.pyi') + return config + +if __name__ == "__main__": + from numpy.distutils.core import setup + config = configuration(top_path='').todict() + setup(**config) diff --git a/venv/Lib/site-packages/numpy/matrixlib/tests/__init__.py b/venv/Lib/site-packages/numpy/matrixlib/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/venv/Lib/site-packages/numpy/matrixlib/tests/test_defmatrix.py b/venv/Lib/site-packages/numpy/matrixlib/tests/test_defmatrix.py new file mode 100644 index 0000000..4cb5f3a --- /dev/null +++ b/venv/Lib/site-packages/numpy/matrixlib/tests/test_defmatrix.py @@ -0,0 +1,453 @@ +import collections.abc + +import numpy as np +from numpy import matrix, asmatrix, bmat +from numpy.testing import ( + assert_, assert_equal, assert_almost_equal, assert_array_equal, + assert_array_almost_equal, assert_raises + ) +from numpy.linalg import matrix_power +from numpy.matrixlib import mat + +class TestCtor: + def test_basic(self): + A = np.array([[1, 2], [3, 4]]) + mA = matrix(A) + assert_(np.all(mA.A == A)) + + B = bmat("A,A;A,A") + C = bmat([[A, A], [A, A]]) + D = np.array([[1, 2, 1, 2], + [3, 4, 3, 4], + [1, 2, 1, 2], + [3, 4, 3, 4]]) + assert_(np.all(B.A == D)) + assert_(np.all(C.A == D)) + + E = np.array([[5, 6], [7, 8]]) + AEresult = matrix([[1, 2, 5, 6], [3, 4, 7, 8]]) + assert_(np.all(bmat([A, E]) == AEresult)) + + vec = np.arange(5) + mvec = matrix(vec) + assert_(mvec.shape == (1, 5)) + + def test_exceptions(self): + # Check for ValueError when called with invalid string data. + assert_raises(ValueError, matrix, "invalid") + + def test_bmat_nondefault_str(self): + A = np.array([[1, 2], [3, 4]]) + B = np.array([[5, 6], [7, 8]]) + Aresult = np.array([[1, 2, 1, 2], + [3, 4, 3, 4], + [1, 2, 1, 2], + [3, 4, 3, 4]]) + mixresult = np.array([[1, 2, 5, 6], + [3, 4, 7, 8], + [5, 6, 1, 2], + [7, 8, 3, 4]]) + assert_(np.all(bmat("A,A;A,A") == Aresult)) + assert_(np.all(bmat("A,A;A,A", ldict={'A':B}) == Aresult)) + assert_raises(TypeError, bmat, "A,A;A,A", gdict={'A':B}) + assert_( + np.all(bmat("A,A;A,A", ldict={'A':A}, gdict={'A':B}) == Aresult)) + b2 = bmat("A,B;C,D", ldict={'A':A,'B':B}, gdict={'C':B,'D':A}) + assert_(np.all(b2 == mixresult)) + + +class TestProperties: + def test_sum(self): + """Test whether matrix.sum(axis=1) preserves orientation. + Fails in NumPy <= 0.9.6.2127. + """ + M = matrix([[1, 2, 0, 0], + [3, 4, 0, 0], + [1, 2, 1, 2], + [3, 4, 3, 4]]) + sum0 = matrix([8, 12, 4, 6]) + sum1 = matrix([3, 7, 6, 14]).T + sumall = 30 + assert_array_equal(sum0, M.sum(axis=0)) + assert_array_equal(sum1, M.sum(axis=1)) + assert_equal(sumall, M.sum()) + + assert_array_equal(sum0, np.sum(M, axis=0)) + assert_array_equal(sum1, np.sum(M, axis=1)) + assert_equal(sumall, np.sum(M)) + + def test_prod(self): + x = matrix([[1, 2, 3], [4, 5, 6]]) + assert_equal(x.prod(), 720) + assert_equal(x.prod(0), matrix([[4, 10, 18]])) + assert_equal(x.prod(1), matrix([[6], [120]])) + + assert_equal(np.prod(x), 720) + assert_equal(np.prod(x, axis=0), matrix([[4, 10, 18]])) + assert_equal(np.prod(x, axis=1), matrix([[6], [120]])) + + y = matrix([0, 1, 3]) + assert_(y.prod() == 0) + + def test_max(self): + x = matrix([[1, 2, 3], [4, 5, 6]]) + assert_equal(x.max(), 6) + assert_equal(x.max(0), matrix([[4, 5, 6]])) + assert_equal(x.max(1), matrix([[3], [6]])) + + assert_equal(np.max(x), 6) + assert_equal(np.max(x, axis=0), matrix([[4, 5, 6]])) + assert_equal(np.max(x, axis=1), matrix([[3], [6]])) + + def test_min(self): + x = matrix([[1, 2, 3], [4, 5, 6]]) + assert_equal(x.min(), 1) + assert_equal(x.min(0), matrix([[1, 2, 3]])) + assert_equal(x.min(1), matrix([[1], [4]])) + + assert_equal(np.min(x), 1) + assert_equal(np.min(x, axis=0), matrix([[1, 2, 3]])) + assert_equal(np.min(x, axis=1), matrix([[1], [4]])) + + def test_ptp(self): + x = np.arange(4).reshape((2, 2)) + assert_(x.ptp() == 3) + assert_(np.all(x.ptp(0) == np.array([2, 2]))) + assert_(np.all(x.ptp(1) == np.array([1, 1]))) + + def test_var(self): + x = np.arange(9).reshape((3, 3)) + mx = x.view(np.matrix) + assert_equal(x.var(ddof=0), mx.var(ddof=0)) + assert_equal(x.var(ddof=1), mx.var(ddof=1)) + + def test_basic(self): + import numpy.linalg as linalg + + A = np.array([[1., 2.], + [3., 4.]]) + mA = matrix(A) + assert_(np.allclose(linalg.inv(A), mA.I)) + assert_(np.all(np.array(np.transpose(A) == mA.T))) + assert_(np.all(np.array(np.transpose(A) == mA.H))) + assert_(np.all(A == mA.A)) + + B = A + 2j*A + mB = matrix(B) + assert_(np.allclose(linalg.inv(B), mB.I)) + assert_(np.all(np.array(np.transpose(B) == mB.T))) + assert_(np.all(np.array(np.transpose(B).conj() == mB.H))) + + def test_pinv(self): + x = matrix(np.arange(6).reshape(2, 3)) + xpinv = matrix([[-0.77777778, 0.27777778], + [-0.11111111, 0.11111111], + [ 0.55555556, -0.05555556]]) + assert_almost_equal(x.I, xpinv) + + def test_comparisons(self): + A = np.arange(100).reshape(10, 10) + mA = matrix(A) + mB = matrix(A) + 0.1 + assert_(np.all(mB == A+0.1)) + assert_(np.all(mB == matrix(A+0.1))) + assert_(not np.any(mB == matrix(A-0.1))) + assert_(np.all(mA < mB)) + assert_(np.all(mA <= mB)) + assert_(np.all(mA <= mA)) + assert_(not np.any(mA < mA)) + + assert_(not np.any(mB < mA)) + assert_(np.all(mB >= mA)) + assert_(np.all(mB >= mB)) + assert_(not np.any(mB > mB)) + + assert_(np.all(mA == mA)) + assert_(not np.any(mA == mB)) + assert_(np.all(mB != mA)) + + assert_(not np.all(abs(mA) > 0)) + assert_(np.all(abs(mB > 0))) + + def test_asmatrix(self): + A = np.arange(100).reshape(10, 10) + mA = asmatrix(A) + A[0, 0] = -10 + assert_(A[0, 0] == mA[0, 0]) + + def test_noaxis(self): + A = matrix([[1, 0], [0, 1]]) + assert_(A.sum() == matrix(2)) + assert_(A.mean() == matrix(0.5)) + + def test_repr(self): + A = matrix([[1, 0], [0, 1]]) + assert_(repr(A) == "matrix([[1, 0],\n [0, 1]])") + + def test_make_bool_matrix_from_str(self): + A = matrix('True; True; False') + B = matrix([[True], [True], [False]]) + assert_array_equal(A, B) + +class TestCasting: + def test_basic(self): + A = np.arange(100).reshape(10, 10) + mA = matrix(A) + + mB = mA.copy() + O = np.ones((10, 10), np.float64) * 0.1 + mB = mB + O + assert_(mB.dtype.type == np.float64) + assert_(np.all(mA != mB)) + assert_(np.all(mB == mA+0.1)) + + mC = mA.copy() + O = np.ones((10, 10), np.complex128) + mC = mC * O + assert_(mC.dtype.type == np.complex128) + assert_(np.all(mA != mB)) + + +class TestAlgebra: + def test_basic(self): + import numpy.linalg as linalg + + A = np.array([[1., 2.], [3., 4.]]) + mA = matrix(A) + + B = np.identity(2) + for i in range(6): + assert_(np.allclose((mA ** i).A, B)) + B = np.dot(B, A) + + Ainv = linalg.inv(A) + B = np.identity(2) + for i in range(6): + assert_(np.allclose((mA ** -i).A, B)) + B = np.dot(B, Ainv) + + assert_(np.allclose((mA * mA).A, np.dot(A, A))) + assert_(np.allclose((mA + mA).A, (A + A))) + assert_(np.allclose((3*mA).A, (3*A))) + + mA2 = matrix(A) + mA2 *= 3 + assert_(np.allclose(mA2.A, 3*A)) + + def test_pow(self): + """Test raising a matrix to an integer power works as expected.""" + m = matrix("1. 2.; 3. 4.") + m2 = m.copy() + m2 **= 2 + mi = m.copy() + mi **= -1 + m4 = m2.copy() + m4 **= 2 + assert_array_almost_equal(m2, m**2) + assert_array_almost_equal(m4, np.dot(m2, m2)) + assert_array_almost_equal(np.dot(mi, m), np.eye(2)) + + def test_scalar_type_pow(self): + m = matrix([[1, 2], [3, 4]]) + for scalar_t in [np.int8, np.uint8]: + two = scalar_t(2) + assert_array_almost_equal(m ** 2, m ** two) + + def test_notimplemented(self): + '''Check that 'not implemented' operations produce a failure.''' + A = matrix([[1., 2.], + [3., 4.]]) + + # __rpow__ + with assert_raises(TypeError): + 1.0**A + + # __mul__ with something not a list, ndarray, tuple, or scalar + with assert_raises(TypeError): + A*object() + + +class TestMatrixReturn: + def test_instance_methods(self): + a = matrix([1.0], dtype='f8') + methodargs = { + 'astype': ('intc',), + 'clip': (0.0, 1.0), + 'compress': ([1],), + 'repeat': (1,), + 'reshape': (1,), + 'swapaxes': (0, 0), + 'dot': np.array([1.0]), + } + excluded_methods = [ + 'argmin', 'choose', 'dump', 'dumps', 'fill', 'getfield', + 'getA', 'getA1', 'item', 'nonzero', 'put', 'putmask', 'resize', + 'searchsorted', 'setflags', 'setfield', 'sort', + 'partition', 'argpartition', + 'take', 'tofile', 'tolist', 'tostring', 'tobytes', 'all', 'any', + 'sum', 'argmax', 'argmin', 'min', 'max', 'mean', 'var', 'ptp', + 'prod', 'std', 'ctypes', 'itemset', + ] + for attrib in dir(a): + if attrib.startswith('_') or attrib in excluded_methods: + continue + f = getattr(a, attrib) + if isinstance(f, collections.abc.Callable): + # reset contents of a + a.astype('f8') + a.fill(1.0) + if attrib in methodargs: + args = methodargs[attrib] + else: + args = () + b = f(*args) + assert_(type(b) is matrix, "%s" % attrib) + assert_(type(a.real) is matrix) + assert_(type(a.imag) is matrix) + c, d = matrix([0.0]).nonzero() + assert_(type(c) is np.ndarray) + assert_(type(d) is np.ndarray) + + +class TestIndexing: + def test_basic(self): + x = asmatrix(np.zeros((3, 2), float)) + y = np.zeros((3, 1), float) + y[:, 0] = [0.8, 0.2, 0.3] + x[:, 1] = y > 0.5 + assert_equal(x, [[0, 1], [0, 0], [0, 0]]) + + +class TestNewScalarIndexing: + a = matrix([[1, 2], [3, 4]]) + + def test_dimesions(self): + a = self.a + x = a[0] + assert_equal(x.ndim, 2) + + def test_array_from_matrix_list(self): + a = self.a + x = np.array([a, a]) + assert_equal(x.shape, [2, 2, 2]) + + def test_array_to_list(self): + a = self.a + assert_equal(a.tolist(), [[1, 2], [3, 4]]) + + def test_fancy_indexing(self): + a = self.a + x = a[1, [0, 1, 0]] + assert_(isinstance(x, matrix)) + assert_equal(x, matrix([[3, 4, 3]])) + x = a[[1, 0]] + assert_(isinstance(x, matrix)) + assert_equal(x, matrix([[3, 4], [1, 2]])) + x = a[[[1], [0]], [[1, 0], [0, 1]]] + assert_(isinstance(x, matrix)) + assert_equal(x, matrix([[4, 3], [1, 2]])) + + def test_matrix_element(self): + x = matrix([[1, 2, 3], [4, 5, 6]]) + assert_equal(x[0][0], matrix([[1, 2, 3]])) + assert_equal(x[0][0].shape, (1, 3)) + assert_equal(x[0].shape, (1, 3)) + assert_equal(x[:, 0].shape, (2, 1)) + + x = matrix(0) + assert_equal(x[0, 0], 0) + assert_equal(x[0], 0) + assert_equal(x[:, 0].shape, x.shape) + + def test_scalar_indexing(self): + x = asmatrix(np.zeros((3, 2), float)) + assert_equal(x[0, 0], x[0][0]) + + def test_row_column_indexing(self): + x = asmatrix(np.eye(2)) + assert_array_equal(x[0,:], [[1, 0]]) + assert_array_equal(x[1,:], [[0, 1]]) + assert_array_equal(x[:, 0], [[1], [0]]) + assert_array_equal(x[:, 1], [[0], [1]]) + + def test_boolean_indexing(self): + A = np.arange(6) + A.shape = (3, 2) + x = asmatrix(A) + assert_array_equal(x[:, np.array([True, False])], x[:, 0]) + assert_array_equal(x[np.array([True, False, False]),:], x[0,:]) + + def test_list_indexing(self): + A = np.arange(6) + A.shape = (3, 2) + x = asmatrix(A) + assert_array_equal(x[:, [1, 0]], x[:, ::-1]) + assert_array_equal(x[[2, 1, 0],:], x[::-1,:]) + + +class TestPower: + def test_returntype(self): + a = np.array([[0, 1], [0, 0]]) + assert_(type(matrix_power(a, 2)) is np.ndarray) + a = mat(a) + assert_(type(matrix_power(a, 2)) is matrix) + + def test_list(self): + assert_array_equal(matrix_power([[0, 1], [0, 0]], 2), [[0, 0], [0, 0]]) + + +class TestShape: + + a = np.array([[1], [2]]) + m = matrix([[1], [2]]) + + def test_shape(self): + assert_equal(self.a.shape, (2, 1)) + assert_equal(self.m.shape, (2, 1)) + + def test_numpy_ravel(self): + assert_equal(np.ravel(self.a).shape, (2,)) + assert_equal(np.ravel(self.m).shape, (2,)) + + def test_member_ravel(self): + assert_equal(self.a.ravel().shape, (2,)) + assert_equal(self.m.ravel().shape, (1, 2)) + + def test_member_flatten(self): + assert_equal(self.a.flatten().shape, (2,)) + assert_equal(self.m.flatten().shape, (1, 2)) + + def test_numpy_ravel_order(self): + x = np.array([[1, 2, 3], [4, 5, 6]]) + assert_equal(np.ravel(x), [1, 2, 3, 4, 5, 6]) + assert_equal(np.ravel(x, order='F'), [1, 4, 2, 5, 3, 6]) + assert_equal(np.ravel(x.T), [1, 4, 2, 5, 3, 6]) + assert_equal(np.ravel(x.T, order='A'), [1, 2, 3, 4, 5, 6]) + x = matrix([[1, 2, 3], [4, 5, 6]]) + assert_equal(np.ravel(x), [1, 2, 3, 4, 5, 6]) + assert_equal(np.ravel(x, order='F'), [1, 4, 2, 5, 3, 6]) + assert_equal(np.ravel(x.T), [1, 4, 2, 5, 3, 6]) + assert_equal(np.ravel(x.T, order='A'), [1, 2, 3, 4, 5, 6]) + + def test_matrix_ravel_order(self): + x = matrix([[1, 2, 3], [4, 5, 6]]) + assert_equal(x.ravel(), [[1, 2, 3, 4, 5, 6]]) + assert_equal(x.ravel(order='F'), [[1, 4, 2, 5, 3, 6]]) + assert_equal(x.T.ravel(), [[1, 4, 2, 5, 3, 6]]) + assert_equal(x.T.ravel(order='A'), [[1, 2, 3, 4, 5, 6]]) + + def test_array_memory_sharing(self): + assert_(np.may_share_memory(self.a, self.a.ravel())) + assert_(not np.may_share_memory(self.a, self.a.flatten())) + + def test_matrix_memory_sharing(self): + assert_(np.may_share_memory(self.m, self.m.ravel())) + assert_(not np.may_share_memory(self.m, self.m.flatten())) + + def test_expand_dims_matrix(self): + # matrices are always 2d - so expand_dims only makes sense when the + # type is changed away from matrix. + a = np.arange(10).reshape((2, 5)).view(np.matrix) + expanded = np.expand_dims(a, axis=1) + assert_equal(expanded.ndim, 3) + assert_(not isinstance(expanded, np.matrix)) diff --git a/venv/Lib/site-packages/numpy/matrixlib/tests/test_interaction.py b/venv/Lib/site-packages/numpy/matrixlib/tests/test_interaction.py new file mode 100644 index 0000000..5154bd6 --- /dev/null +++ b/venv/Lib/site-packages/numpy/matrixlib/tests/test_interaction.py @@ -0,0 +1,354 @@ +"""Tests of interaction of matrix with other parts of numpy. + +Note that tests with MaskedArray and linalg are done in separate files. +""" +import pytest + +import textwrap +import warnings + +import numpy as np +from numpy.testing import (assert_, assert_equal, assert_raises, + assert_raises_regex, assert_array_equal, + assert_almost_equal, assert_array_almost_equal) + + +def test_fancy_indexing(): + # The matrix class messes with the shape. While this is always + # weird (getitem is not used, it does not have setitem nor knows + # about fancy indexing), this tests gh-3110 + # 2018-04-29: moved here from core.tests.test_index. + m = np.matrix([[1, 2], [3, 4]]) + + assert_(isinstance(m[[0, 1, 0], :], np.matrix)) + + # gh-3110. Note the transpose currently because matrices do *not* + # support dimension fixing for fancy indexing correctly. + x = np.asmatrix(np.arange(50).reshape(5, 10)) + assert_equal(x[:2, np.array(-1)], x[:2, -1].T) + + +def test_polynomial_mapdomain(): + # test that polynomial preserved matrix subtype. + # 2018-04-29: moved here from polynomial.tests.polyutils. + dom1 = [0, 4] + dom2 = [1, 3] + x = np.matrix([dom1, dom1]) + res = np.polynomial.polyutils.mapdomain(x, dom1, dom2) + assert_(isinstance(res, np.matrix)) + + +def test_sort_matrix_none(): + # 2018-04-29: moved here from core.tests.test_multiarray + a = np.matrix([[2, 1, 0]]) + actual = np.sort(a, axis=None) + expected = np.matrix([[0, 1, 2]]) + assert_equal(actual, expected) + assert_(type(expected) is np.matrix) + + +def test_partition_matrix_none(): + # gh-4301 + # 2018-04-29: moved here from core.tests.test_multiarray + a = np.matrix([[2, 1, 0]]) + actual = np.partition(a, 1, axis=None) + expected = np.matrix([[0, 1, 2]]) + assert_equal(actual, expected) + assert_(type(expected) is np.matrix) + + +def test_dot_scalar_and_matrix_of_objects(): + # Ticket #2469 + # 2018-04-29: moved here from core.tests.test_multiarray + arr = np.matrix([1, 2], dtype=object) + desired = np.matrix([[3, 6]], dtype=object) + assert_equal(np.dot(arr, 3), desired) + assert_equal(np.dot(3, arr), desired) + + +def test_inner_scalar_and_matrix(): + # 2018-04-29: moved here from core.tests.test_multiarray + for dt in np.typecodes['AllInteger'] + np.typecodes['AllFloat'] + '?': + sca = np.array(3, dtype=dt)[()] + arr = np.matrix([[1, 2], [3, 4]], dtype=dt) + desired = np.matrix([[3, 6], [9, 12]], dtype=dt) + assert_equal(np.inner(arr, sca), desired) + assert_equal(np.inner(sca, arr), desired) + + +def test_inner_scalar_and_matrix_of_objects(): + # Ticket #4482 + # 2018-04-29: moved here from core.tests.test_multiarray + arr = np.matrix([1, 2], dtype=object) + desired = np.matrix([[3, 6]], dtype=object) + assert_equal(np.inner(arr, 3), desired) + assert_equal(np.inner(3, arr), desired) + + +def test_iter_allocate_output_subtype(): + # Make sure that the subtype with priority wins + # 2018-04-29: moved here from core.tests.test_nditer, given the + # matrix specific shape test. + + # matrix vs ndarray + a = np.matrix([[1, 2], [3, 4]]) + b = np.arange(4).reshape(2, 2).T + i = np.nditer([a, b, None], [], + [['readonly'], ['readonly'], ['writeonly', 'allocate']]) + assert_(type(i.operands[2]) is np.matrix) + assert_(type(i.operands[2]) is not np.ndarray) + assert_equal(i.operands[2].shape, (2, 2)) + + # matrix always wants things to be 2D + b = np.arange(4).reshape(1, 2, 2) + assert_raises(RuntimeError, np.nditer, [a, b, None], [], + [['readonly'], ['readonly'], ['writeonly', 'allocate']]) + # but if subtypes are disabled, the result can still work + i = np.nditer([a, b, None], [], + [['readonly'], ['readonly'], + ['writeonly', 'allocate', 'no_subtype']]) + assert_(type(i.operands[2]) is np.ndarray) + assert_(type(i.operands[2]) is not np.matrix) + assert_equal(i.operands[2].shape, (1, 2, 2)) + + +def like_function(): + # 2018-04-29: moved here from core.tests.test_numeric + a = np.matrix([[1, 2], [3, 4]]) + for like_function in np.zeros_like, np.ones_like, np.empty_like: + b = like_function(a) + assert_(type(b) is np.matrix) + + c = like_function(a, subok=False) + assert_(type(c) is not np.matrix) + + +def test_array_astype(): + # 2018-04-29: copied here from core.tests.test_api + # subok=True passes through a matrix + a = np.matrix([[0, 1, 2], [3, 4, 5]], dtype='f4') + b = a.astype('f4', subok=True, copy=False) + assert_(a is b) + + # subok=True is default, and creates a subtype on a cast + b = a.astype('i4', copy=False) + assert_equal(a, b) + assert_equal(type(b), np.matrix) + + # subok=False never returns a matrix + b = a.astype('f4', subok=False, copy=False) + assert_equal(a, b) + assert_(not (a is b)) + assert_(type(b) is not np.matrix) + + +def test_stack(): + # 2018-04-29: copied here from core.tests.test_shape_base + # check np.matrix cannot be stacked + m = np.matrix([[1, 2], [3, 4]]) + assert_raises_regex(ValueError, 'shape too large to be a matrix', + np.stack, [m, m]) + + +def test_object_scalar_multiply(): + # Tickets #2469 and #4482 + # 2018-04-29: moved here from core.tests.test_ufunc + arr = np.matrix([1, 2], dtype=object) + desired = np.matrix([[3, 6]], dtype=object) + assert_equal(np.multiply(arr, 3), desired) + assert_equal(np.multiply(3, arr), desired) + + +def test_nanfunctions_matrices(): + # Check that it works and that type and + # shape are preserved + # 2018-04-29: moved here from core.tests.test_nanfunctions + mat = np.matrix(np.eye(3)) + for f in [np.nanmin, np.nanmax]: + res = f(mat, axis=0) + assert_(isinstance(res, np.matrix)) + assert_(res.shape == (1, 3)) + res = f(mat, axis=1) + assert_(isinstance(res, np.matrix)) + assert_(res.shape == (3, 1)) + res = f(mat) + assert_(np.isscalar(res)) + # check that rows of nan are dealt with for subclasses (#4628) + mat[1] = np.nan + for f in [np.nanmin, np.nanmax]: + with warnings.catch_warnings(record=True) as w: + warnings.simplefilter('always') + res = f(mat, axis=0) + assert_(isinstance(res, np.matrix)) + assert_(not np.any(np.isnan(res))) + assert_(len(w) == 0) + + with warnings.catch_warnings(record=True) as w: + warnings.simplefilter('always') + res = f(mat, axis=1) + assert_(isinstance(res, np.matrix)) + assert_(np.isnan(res[1, 0]) and not np.isnan(res[0, 0]) + and not np.isnan(res[2, 0])) + assert_(len(w) == 1, 'no warning raised') + assert_(issubclass(w[0].category, RuntimeWarning)) + + with warnings.catch_warnings(record=True) as w: + warnings.simplefilter('always') + res = f(mat) + assert_(np.isscalar(res)) + assert_(res != np.nan) + assert_(len(w) == 0) + + +def test_nanfunctions_matrices_general(): + # Check that it works and that type and + # shape are preserved + # 2018-04-29: moved here from core.tests.test_nanfunctions + mat = np.matrix(np.eye(3)) + for f in (np.nanargmin, np.nanargmax, np.nansum, np.nanprod, + np.nanmean, np.nanvar, np.nanstd): + res = f(mat, axis=0) + assert_(isinstance(res, np.matrix)) + assert_(res.shape == (1, 3)) + res = f(mat, axis=1) + assert_(isinstance(res, np.matrix)) + assert_(res.shape == (3, 1)) + res = f(mat) + assert_(np.isscalar(res)) + + for f in np.nancumsum, np.nancumprod: + res = f(mat, axis=0) + assert_(isinstance(res, np.matrix)) + assert_(res.shape == (3, 3)) + res = f(mat, axis=1) + assert_(isinstance(res, np.matrix)) + assert_(res.shape == (3, 3)) + res = f(mat) + assert_(isinstance(res, np.matrix)) + assert_(res.shape == (1, 3*3)) + + +def test_average_matrix(): + # 2018-04-29: moved here from core.tests.test_function_base. + y = np.matrix(np.random.rand(5, 5)) + assert_array_equal(y.mean(0), np.average(y, 0)) + + a = np.matrix([[1, 2], [3, 4]]) + w = np.matrix([[1, 2], [3, 4]]) + + r = np.average(a, axis=0, weights=w) + assert_equal(type(r), np.matrix) + assert_equal(r, [[2.5, 10.0/3]]) + + +def test_trapz_matrix(): + # Test to make sure matrices give the same answer as ndarrays + # 2018-04-29: moved here from core.tests.test_function_base. + x = np.linspace(0, 5) + y = x * x + r = np.trapz(y, x) + mx = np.matrix(x) + my = np.matrix(y) + mr = np.trapz(my, mx) + assert_almost_equal(mr, r) + + +def test_ediff1d_matrix(): + # 2018-04-29: moved here from core.tests.test_arraysetops. + assert(isinstance(np.ediff1d(np.matrix(1)), np.matrix)) + assert(isinstance(np.ediff1d(np.matrix(1), to_begin=1), np.matrix)) + + +def test_apply_along_axis_matrix(): + # this test is particularly malicious because matrix + # refuses to become 1d + # 2018-04-29: moved here from core.tests.test_shape_base. + def double(row): + return row * 2 + + m = np.matrix([[0, 1], [2, 3]]) + expected = np.matrix([[0, 2], [4, 6]]) + + result = np.apply_along_axis(double, 0, m) + assert_(isinstance(result, np.matrix)) + assert_array_equal(result, expected) + + result = np.apply_along_axis(double, 1, m) + assert_(isinstance(result, np.matrix)) + assert_array_equal(result, expected) + + +def test_kron_matrix(): + # 2018-04-29: moved here from core.tests.test_shape_base. + a = np.ones([2, 2]) + m = np.asmatrix(a) + assert_equal(type(np.kron(a, a)), np.ndarray) + assert_equal(type(np.kron(m, m)), np.matrix) + assert_equal(type(np.kron(a, m)), np.matrix) + assert_equal(type(np.kron(m, a)), np.matrix) + + +class TestConcatenatorMatrix: + # 2018-04-29: moved here from core.tests.test_index_tricks. + def test_matrix(self): + a = [1, 2] + b = [3, 4] + + ab_r = np.r_['r', a, b] + ab_c = np.r_['c', a, b] + + assert_equal(type(ab_r), np.matrix) + assert_equal(type(ab_c), np.matrix) + + assert_equal(np.array(ab_r), [[1, 2, 3, 4]]) + assert_equal(np.array(ab_c), [[1], [2], [3], [4]]) + + assert_raises(ValueError, lambda: np.r_['rc', a, b]) + + def test_matrix_scalar(self): + r = np.r_['r', [1, 2], 3] + assert_equal(type(r), np.matrix) + assert_equal(np.array(r), [[1, 2, 3]]) + + def test_matrix_builder(self): + a = np.array([1]) + b = np.array([2]) + c = np.array([3]) + d = np.array([4]) + actual = np.r_['a, b; c, d'] + expected = np.bmat([[a, b], [c, d]]) + + assert_equal(actual, expected) + assert_equal(type(actual), type(expected)) + + +def test_array_equal_error_message_matrix(): + # 2018-04-29: moved here from testing.tests.test_utils. + with pytest.raises(AssertionError) as exc_info: + assert_equal(np.array([1, 2]), np.matrix([1, 2])) + msg = str(exc_info.value) + msg_reference = textwrap.dedent("""\ + + Arrays are not equal + + (shapes (2,), (1, 2) mismatch) + x: array([1, 2]) + y: matrix([[1, 2]])""") + assert_equal(msg, msg_reference) + + +def test_array_almost_equal_matrix(): + # Matrix slicing keeps things 2-D, while array does not necessarily. + # See gh-8452. + # 2018-04-29: moved here from testing.tests.test_utils. + m1 = np.matrix([[1., 2.]]) + m2 = np.matrix([[1., np.nan]]) + m3 = np.matrix([[1., -np.inf]]) + m4 = np.matrix([[np.nan, np.inf]]) + m5 = np.matrix([[1., 2.], [np.nan, np.inf]]) + for assert_func in assert_array_almost_equal, assert_almost_equal: + for m in m1, m2, m3, m4, m5: + assert_func(m, m) + a = np.array(m) + assert_func(a, m) + assert_func(m, a) diff --git a/venv/Lib/site-packages/numpy/matrixlib/tests/test_masked_matrix.py b/venv/Lib/site-packages/numpy/matrixlib/tests/test_masked_matrix.py new file mode 100644 index 0000000..95d3f44 --- /dev/null +++ b/venv/Lib/site-packages/numpy/matrixlib/tests/test_masked_matrix.py @@ -0,0 +1,231 @@ +import numpy as np +from numpy.testing import assert_warns +from numpy.ma.testutils import (assert_, assert_equal, assert_raises, + assert_array_equal) +from numpy.ma.core import (masked_array, masked_values, masked, allequal, + MaskType, getmask, MaskedArray, nomask, + log, add, hypot, divide) +from numpy.ma.extras import mr_ +from numpy.compat import pickle + + +class MMatrix(MaskedArray, np.matrix,): + + def __new__(cls, data, mask=nomask): + mat = np.matrix(data) + _data = MaskedArray.__new__(cls, data=mat, mask=mask) + return _data + + def __array_finalize__(self, obj): + np.matrix.__array_finalize__(self, obj) + MaskedArray.__array_finalize__(self, obj) + return + + @property + def _series(self): + _view = self.view(MaskedArray) + _view._sharedmask = False + return _view + + +class TestMaskedMatrix: + def test_matrix_indexing(self): + # Tests conversions and indexing + x1 = np.matrix([[1, 2, 3], [4, 3, 2]]) + x2 = masked_array(x1, mask=[[1, 0, 0], [0, 1, 0]]) + x3 = masked_array(x1, mask=[[0, 1, 0], [1, 0, 0]]) + x4 = masked_array(x1) + # test conversion to strings + str(x2) # raises? + repr(x2) # raises? + # tests of indexing + assert_(type(x2[1, 0]) is type(x1[1, 0])) + assert_(x1[1, 0] == x2[1, 0]) + assert_(x2[1, 1] is masked) + assert_equal(x1[0, 2], x2[0, 2]) + assert_equal(x1[0, 1:], x2[0, 1:]) + assert_equal(x1[:, 2], x2[:, 2]) + assert_equal(x1[:], x2[:]) + assert_equal(x1[1:], x3[1:]) + x1[0, 2] = 9 + x2[0, 2] = 9 + assert_equal(x1, x2) + x1[0, 1:] = 99 + x2[0, 1:] = 99 + assert_equal(x1, x2) + x2[0, 1] = masked + assert_equal(x1, x2) + x2[0, 1:] = masked + assert_equal(x1, x2) + x2[0, :] = x1[0, :] + x2[0, 1] = masked + assert_(allequal(getmask(x2), np.array([[0, 1, 0], [0, 1, 0]]))) + x3[1, :] = masked_array([1, 2, 3], [1, 1, 0]) + assert_(allequal(getmask(x3)[1], masked_array([1, 1, 0]))) + assert_(allequal(getmask(x3[1]), masked_array([1, 1, 0]))) + x4[1, :] = masked_array([1, 2, 3], [1, 1, 0]) + assert_(allequal(getmask(x4[1]), masked_array([1, 1, 0]))) + assert_(allequal(x4[1], masked_array([1, 2, 3]))) + x1 = np.matrix(np.arange(5) * 1.0) + x2 = masked_values(x1, 3.0) + assert_equal(x1, x2) + assert_(allequal(masked_array([0, 0, 0, 1, 0], dtype=MaskType), + x2.mask)) + assert_equal(3.0, x2.fill_value) + + def test_pickling_subbaseclass(self): + # Test pickling w/ a subclass of ndarray + a = masked_array(np.matrix(list(range(10))), mask=[1, 0, 1, 0, 0] * 2) + for proto in range(2, pickle.HIGHEST_PROTOCOL + 1): + a_pickled = pickle.loads(pickle.dumps(a, protocol=proto)) + assert_equal(a_pickled._mask, a._mask) + assert_equal(a_pickled, a) + assert_(isinstance(a_pickled._data, np.matrix)) + + def test_count_mean_with_matrix(self): + m = masked_array(np.matrix([[1, 2], [3, 4]]), mask=np.zeros((2, 2))) + + assert_equal(m.count(axis=0).shape, (1, 2)) + assert_equal(m.count(axis=1).shape, (2, 1)) + + # Make sure broadcasting inside mean and var work + assert_equal(m.mean(axis=0), [[2., 3.]]) + assert_equal(m.mean(axis=1), [[1.5], [3.5]]) + + def test_flat(self): + # Test that flat can return items even for matrices [#4585, #4615] + # test simple access + test = masked_array(np.matrix([[1, 2, 3]]), mask=[0, 0, 1]) + assert_equal(test.flat[1], 2) + assert_equal(test.flat[2], masked) + assert_(np.all(test.flat[0:2] == test[0, 0:2])) + # Test flat on masked_matrices + test = masked_array(np.matrix([[1, 2, 3]]), mask=[0, 0, 1]) + test.flat = masked_array([3, 2, 1], mask=[1, 0, 0]) + control = masked_array(np.matrix([[3, 2, 1]]), mask=[1, 0, 0]) + assert_equal(test, control) + # Test setting + test = masked_array(np.matrix([[1, 2, 3]]), mask=[0, 0, 1]) + testflat = test.flat + testflat[:] = testflat[[2, 1, 0]] + assert_equal(test, control) + testflat[0] = 9 + # test that matrices keep the correct shape (#4615) + a = masked_array(np.matrix(np.eye(2)), mask=0) + b = a.flat + b01 = b[:2] + assert_equal(b01.data, np.array([[1., 0.]])) + assert_equal(b01.mask, np.array([[False, False]])) + + def test_allany_onmatrices(self): + x = np.array([[0.13, 0.26, 0.90], + [0.28, 0.33, 0.63], + [0.31, 0.87, 0.70]]) + X = np.matrix(x) + m = np.array([[True, False, False], + [False, False, False], + [True, True, False]], dtype=np.bool_) + mX = masked_array(X, mask=m) + mXbig = (mX > 0.5) + mXsmall = (mX < 0.5) + + assert_(not mXbig.all()) + assert_(mXbig.any()) + assert_equal(mXbig.all(0), np.matrix([False, False, True])) + assert_equal(mXbig.all(1), np.matrix([False, False, True]).T) + assert_equal(mXbig.any(0), np.matrix([False, False, True])) + assert_equal(mXbig.any(1), np.matrix([True, True, True]).T) + + assert_(not mXsmall.all()) + assert_(mXsmall.any()) + assert_equal(mXsmall.all(0), np.matrix([True, True, False])) + assert_equal(mXsmall.all(1), np.matrix([False, False, False]).T) + assert_equal(mXsmall.any(0), np.matrix([True, True, False])) + assert_equal(mXsmall.any(1), np.matrix([True, True, False]).T) + + def test_compressed(self): + a = masked_array(np.matrix([1, 2, 3, 4]), mask=[0, 0, 0, 0]) + b = a.compressed() + assert_equal(b, a) + assert_(isinstance(b, np.matrix)) + a[0, 0] = masked + b = a.compressed() + assert_equal(b, [[2, 3, 4]]) + + def test_ravel(self): + a = masked_array(np.matrix([1, 2, 3, 4, 5]), mask=[[0, 1, 0, 0, 0]]) + aravel = a.ravel() + assert_equal(aravel.shape, (1, 5)) + assert_equal(aravel._mask.shape, a.shape) + + def test_view(self): + # Test view w/ flexible dtype + iterator = list(zip(np.arange(10), np.random.rand(10))) + data = np.array(iterator) + a = masked_array(iterator, dtype=[('a', float), ('b', float)]) + a.mask[0] = (1, 0) + test = a.view((float, 2), np.matrix) + assert_equal(test, data) + assert_(isinstance(test, np.matrix)) + assert_(not isinstance(test, MaskedArray)) + + +class TestSubclassing: + # Test suite for masked subclasses of ndarray. + + def setup(self): + x = np.arange(5, dtype='float') + mx = MMatrix(x, mask=[0, 1, 0, 0, 0]) + self.data = (x, mx) + + def test_maskedarray_subclassing(self): + # Tests subclassing MaskedArray + (x, mx) = self.data + assert_(isinstance(mx._data, np.matrix)) + + def test_masked_unary_operations(self): + # Tests masked_unary_operation + (x, mx) = self.data + with np.errstate(divide='ignore'): + assert_(isinstance(log(mx), MMatrix)) + assert_equal(log(x), np.log(x)) + + def test_masked_binary_operations(self): + # Tests masked_binary_operation + (x, mx) = self.data + # Result should be a MMatrix + assert_(isinstance(add(mx, mx), MMatrix)) + assert_(isinstance(add(mx, x), MMatrix)) + # Result should work + assert_equal(add(mx, x), mx+x) + assert_(isinstance(add(mx, mx)._data, np.matrix)) + with assert_warns(DeprecationWarning): + assert_(isinstance(add.outer(mx, mx), MMatrix)) + assert_(isinstance(hypot(mx, mx), MMatrix)) + assert_(isinstance(hypot(mx, x), MMatrix)) + + def test_masked_binary_operations2(self): + # Tests domained_masked_binary_operation + (x, mx) = self.data + xmx = masked_array(mx.data.__array__(), mask=mx.mask) + assert_(isinstance(divide(mx, mx), MMatrix)) + assert_(isinstance(divide(mx, x), MMatrix)) + assert_equal(divide(mx, mx), divide(xmx, xmx)) + +class TestConcatenator: + # Tests for mr_, the equivalent of r_ for masked arrays. + + def test_matrix_builder(self): + assert_raises(np.ma.MAError, lambda: mr_['1, 2; 3, 4']) + + def test_matrix(self): + # Test consistency with unmasked version. If we ever deprecate + # matrix, this test should either still pass, or both actual and + # expected should fail to be build. + actual = mr_['r', 1, 2, 3] + expected = np.ma.array(np.r_['r', 1, 2, 3]) + assert_array_equal(actual, expected) + + # outer type is masked array, inner type is matrix + assert_equal(type(actual), type(expected)) + assert_equal(type(actual.data), type(expected.data)) diff --git a/venv/Lib/site-packages/numpy/matrixlib/tests/test_matrix_linalg.py b/venv/Lib/site-packages/numpy/matrixlib/tests/test_matrix_linalg.py new file mode 100644 index 0000000..106c2e3 --- /dev/null +++ b/venv/Lib/site-packages/numpy/matrixlib/tests/test_matrix_linalg.py @@ -0,0 +1,93 @@ +""" Test functions for linalg module using the matrix class.""" +import numpy as np + +from numpy.linalg.tests.test_linalg import ( + LinalgCase, apply_tag, TestQR as _TestQR, LinalgTestCase, + _TestNorm2D, _TestNormDoubleBase, _TestNormSingleBase, _TestNormInt64Base, + SolveCases, InvCases, EigvalsCases, EigCases, SVDCases, CondCases, + PinvCases, DetCases, LstsqCases) + + +CASES = [] + +# square test cases +CASES += apply_tag('square', [ + LinalgCase("0x0_matrix", + np.empty((0, 0), dtype=np.double).view(np.matrix), + np.empty((0, 1), dtype=np.double).view(np.matrix), + tags={'size-0'}), + LinalgCase("matrix_b_only", + np.array([[1., 2.], [3., 4.]]), + np.matrix([2., 1.]).T), + LinalgCase("matrix_a_and_b", + np.matrix([[1., 2.], [3., 4.]]), + np.matrix([2., 1.]).T), +]) + +# hermitian test-cases +CASES += apply_tag('hermitian', [ + LinalgCase("hmatrix_a_and_b", + np.matrix([[1., 2.], [2., 1.]]), + None), +]) +# No need to make generalized or strided cases for matrices. + + +class MatrixTestCase(LinalgTestCase): + TEST_CASES = CASES + + +class TestSolveMatrix(SolveCases, MatrixTestCase): + pass + + +class TestInvMatrix(InvCases, MatrixTestCase): + pass + + +class TestEigvalsMatrix(EigvalsCases, MatrixTestCase): + pass + + +class TestEigMatrix(EigCases, MatrixTestCase): + pass + + +class TestSVDMatrix(SVDCases, MatrixTestCase): + pass + + +class TestCondMatrix(CondCases, MatrixTestCase): + pass + + +class TestPinvMatrix(PinvCases, MatrixTestCase): + pass + + +class TestDetMatrix(DetCases, MatrixTestCase): + pass + + +class TestLstsqMatrix(LstsqCases, MatrixTestCase): + pass + + +class _TestNorm2DMatrix(_TestNorm2D): + array = np.matrix + + +class TestNormDoubleMatrix(_TestNorm2DMatrix, _TestNormDoubleBase): + pass + + +class TestNormSingleMatrix(_TestNorm2DMatrix, _TestNormSingleBase): + pass + + +class TestNormInt64Matrix(_TestNorm2DMatrix, _TestNormInt64Base): + pass + + +class TestQRMatrix(_TestQR): + array = np.matrix diff --git a/venv/Lib/site-packages/numpy/matrixlib/tests/test_multiarray.py b/venv/Lib/site-packages/numpy/matrixlib/tests/test_multiarray.py new file mode 100644 index 0000000..638d0d1 --- /dev/null +++ b/venv/Lib/site-packages/numpy/matrixlib/tests/test_multiarray.py @@ -0,0 +1,16 @@ +import numpy as np +from numpy.testing import assert_, assert_equal, assert_array_equal + +class TestView: + def test_type(self): + x = np.array([1, 2, 3]) + assert_(isinstance(x.view(np.matrix), np.matrix)) + + def test_keywords(self): + x = np.array([(1, 2)], dtype=[('a', np.int8), ('b', np.int8)]) + # We must be specific about the endianness here: + y = x.view(dtype='>> from numpy.polynomial import Chebyshev + >>> c = Chebyshev.fit(xdata, ydata, deg=1) + +is preferred over the `chebyshev.chebfit` function from the +`numpy.polynomial.chebyshev` module:: + + >>> from numpy.polynomial.chebyshev import chebfit + >>> c = chebfit(xdata, ydata, deg=1) + +See :doc:`routines.polynomials.classes` for more details. + +Convenience Classes +=================== + +The following lists the various constants and methods common to all of +the classes representing the various kinds of polynomials. In the following, +the term ``Poly`` represents any one of the convenience classes (e.g. +``Polynomial``, ``Chebyshev``, ``Hermite``, etc.) while the lowercase ``p`` +represents an **instance** of a polynomial class. + +Constants +--------- + +- ``Poly.domain`` -- Default domain +- ``Poly.window`` -- Default window +- ``Poly.basis_name`` -- String used to represent the basis +- ``Poly.maxpower`` -- Maximum value ``n`` such that ``p**n`` is allowed +- ``Poly.nickname`` -- String used in printing + +Creation +-------- + +Methods for creating polynomial instances. + +- ``Poly.basis(degree)`` -- Basis polynomial of given degree +- ``Poly.identity()`` -- ``p`` where ``p(x) = x`` for all ``x`` +- ``Poly.fit(x, y, deg)`` -- ``p`` of degree ``deg`` with coefficients + determined by the least-squares fit to the data ``x``, ``y`` +- ``Poly.fromroots(roots)`` -- ``p`` with specified roots +- ``p.copy()`` -- Create a copy of ``p`` + +Conversion +---------- + +Methods for converting a polynomial instance of one kind to another. + +- ``p.cast(Poly)`` -- Convert ``p`` to instance of kind ``Poly`` +- ``p.convert(Poly)`` -- Convert ``p`` to instance of kind ``Poly`` or map + between ``domain`` and ``window`` + +Calculus +-------- +- ``p.deriv()`` -- Take the derivative of ``p`` +- ``p.integ()`` -- Integrate ``p`` + +Validation +---------- +- ``Poly.has_samecoef(p1, p2)`` -- Check if coefficients match +- ``Poly.has_samedomain(p1, p2)`` -- Check if domains match +- ``Poly.has_sametype(p1, p2)`` -- Check if types match +- ``Poly.has_samewindow(p1, p2)`` -- Check if windows match + +Misc +---- +- ``p.linspace()`` -- Return ``x, p(x)`` at equally-spaced points in ``domain`` +- ``p.mapparms()`` -- Return the parameters for the linear mapping between + ``domain`` and ``window``. +- ``p.roots()`` -- Return the roots of `p`. +- ``p.trim()`` -- Remove trailing coefficients. +- ``p.cutdeg(degree)`` -- Truncate p to given degree +- ``p.truncate(size)`` -- Truncate p to given size + +""" +from .polynomial import Polynomial +from .chebyshev import Chebyshev +from .legendre import Legendre +from .hermite import Hermite +from .hermite_e import HermiteE +from .laguerre import Laguerre + + +def set_default_printstyle(style): + """ + Set the default format for the string representation of polynomials. + + Values for ``style`` must be valid inputs to ``__format__``, i.e. 'ascii' + or 'unicode'. + + Parameters + ---------- + style : str + Format string for default printing style. Must be either 'ascii' or + 'unicode'. + + Notes + ----- + The default format depends on the platform: 'unicode' is used on + Unix-based systems and 'ascii' on Windows. This determination is based on + default font support for the unicode superscript and subscript ranges. + + Examples + -------- + >>> p = np.polynomial.Polynomial([1, 2, 3]) + >>> c = np.polynomial.Chebyshev([1, 2, 3]) + >>> np.polynomial.set_default_printstyle('unicode') + >>> print(p) + 1.0 + 2.0·x¹ + 3.0·x² + >>> print(c) + 1.0 + 2.0·Tâ‚(x) + 3.0·Tâ‚‚(x) + >>> np.polynomial.set_default_printstyle('ascii') + >>> print(p) + 1.0 + 2.0 x**1 + 3.0 x**2 + >>> print(c) + 1.0 + 2.0 T_1(x) + 3.0 T_2(x) + >>> # Formatting supercedes all class/package-level defaults + >>> print(f"{p:unicode}") + 1.0 + 2.0·x¹ + 3.0·x² + """ + if style not in ('unicode', 'ascii'): + raise ValueError( + f"Unsupported format string '{style}'. Valid options are 'ascii' " + f"and 'unicode'" + ) + _use_unicode = True + if style == 'ascii': + _use_unicode = False + from ._polybase import ABCPolyBase + ABCPolyBase._use_unicode = _use_unicode + + +from numpy._pytesttester import PytestTester +test = PytestTester(__name__) +del PytestTester diff --git a/venv/Lib/site-packages/numpy/polynomial/__init__.pyi b/venv/Lib/site-packages/numpy/polynomial/__init__.pyi new file mode 100644 index 0000000..755f752 --- /dev/null +++ b/venv/Lib/site-packages/numpy/polynomial/__init__.pyi @@ -0,0 +1,18 @@ +from typing import Any + +from numpy.polynomial import ( + chebyshev as chebyshev, + hermite as hermite, + hermite_e as hermite_e, + laguerre as laguerre, + legendre as legendre, + polynomial as polynomial, +) + +Polynomial: Any +Chebyshev: Any +Legendre: Any +Hermite: Any +HermiteE: Any +Laguerre: Any +set_default_printstyle: Any diff --git a/venv/Lib/site-packages/numpy/polynomial/_polybase.py b/venv/Lib/site-packages/numpy/polynomial/_polybase.py new file mode 100644 index 0000000..59c380f --- /dev/null +++ b/venv/Lib/site-packages/numpy/polynomial/_polybase.py @@ -0,0 +1,1144 @@ +""" +Abstract base class for the various polynomial Classes. + +The ABCPolyBase class provides the methods needed to implement the common API +for the various polynomial classes. It operates as a mixin, but uses the +abc module from the stdlib, hence it is only available for Python >= 2.6. + +""" +import os +import abc +import numbers + +import numpy as np +from . import polyutils as pu + +__all__ = ['ABCPolyBase'] + +class ABCPolyBase(abc.ABC): + """An abstract base class for immutable series classes. + + ABCPolyBase provides the standard Python numerical methods + '+', '-', '*', '//', '%', 'divmod', '**', and '()' along with the + methods listed below. + + .. versionadded:: 1.9.0 + + Parameters + ---------- + coef : array_like + Series coefficients in order of increasing degree, i.e., + ``(1, 2, 3)`` gives ``1*P_0(x) + 2*P_1(x) + 3*P_2(x)``, where + ``P_i`` is the basis polynomials of degree ``i``. + domain : (2,) array_like, optional + Domain to use. The interval ``[domain[0], domain[1]]`` is mapped + to the interval ``[window[0], window[1]]`` by shifting and scaling. + The default value is the derived class domain. + window : (2,) array_like, optional + Window, see domain for its use. The default value is the + derived class window. + + Attributes + ---------- + coef : (N,) ndarray + Series coefficients in order of increasing degree. + domain : (2,) ndarray + Domain that is mapped to window. + window : (2,) ndarray + Window that domain is mapped to. + + Class Attributes + ---------------- + maxpower : int + Maximum power allowed, i.e., the largest number ``n`` such that + ``p(x)**n`` is allowed. This is to limit runaway polynomial size. + domain : (2,) ndarray + Default domain of the class. + window : (2,) ndarray + Default window of the class. + + """ + + # Not hashable + __hash__ = None + + # Opt out of numpy ufuncs and Python ops with ndarray subclasses. + __array_ufunc__ = None + + # Limit runaway size. T_n^m has degree n*m + maxpower = 100 + + # Unicode character mappings for improved __str__ + _superscript_mapping = str.maketrans({ + "0": "â°", + "1": "¹", + "2": "²", + "3": "³", + "4": "â´", + "5": "âµ", + "6": "â¶", + "7": "â·", + "8": "â¸", + "9": "â¹" + }) + _subscript_mapping = str.maketrans({ + "0": "â‚€", + "1": "â‚", + "2": "â‚‚", + "3": "₃", + "4": "â‚„", + "5": "â‚…", + "6": "₆", + "7": "₇", + "8": "₈", + "9": "₉" + }) + # Some fonts don't support full unicode character ranges necessary for + # the full set of superscripts and subscripts, including common/default + # fonts in Windows shells/terminals. Therefore, default to ascii-only + # printing on windows. + _use_unicode = not os.name == 'nt' + + @property + @abc.abstractmethod + def domain(self): + pass + + @property + @abc.abstractmethod + def window(self): + pass + + @property + @abc.abstractmethod + def basis_name(self): + pass + + @staticmethod + @abc.abstractmethod + def _add(c1, c2): + pass + + @staticmethod + @abc.abstractmethod + def _sub(c1, c2): + pass + + @staticmethod + @abc.abstractmethod + def _mul(c1, c2): + pass + + @staticmethod + @abc.abstractmethod + def _div(c1, c2): + pass + + @staticmethod + @abc.abstractmethod + def _pow(c, pow, maxpower=None): + pass + + @staticmethod + @abc.abstractmethod + def _val(x, c): + pass + + @staticmethod + @abc.abstractmethod + def _int(c, m, k, lbnd, scl): + pass + + @staticmethod + @abc.abstractmethod + def _der(c, m, scl): + pass + + @staticmethod + @abc.abstractmethod + def _fit(x, y, deg, rcond, full): + pass + + @staticmethod + @abc.abstractmethod + def _line(off, scl): + pass + + @staticmethod + @abc.abstractmethod + def _roots(c): + pass + + @staticmethod + @abc.abstractmethod + def _fromroots(r): + pass + + def has_samecoef(self, other): + """Check if coefficients match. + + .. versionadded:: 1.6.0 + + Parameters + ---------- + other : class instance + The other class must have the ``coef`` attribute. + + Returns + ------- + bool : boolean + True if the coefficients are the same, False otherwise. + + """ + if len(self.coef) != len(other.coef): + return False + elif not np.all(self.coef == other.coef): + return False + else: + return True + + def has_samedomain(self, other): + """Check if domains match. + + .. versionadded:: 1.6.0 + + Parameters + ---------- + other : class instance + The other class must have the ``domain`` attribute. + + Returns + ------- + bool : boolean + True if the domains are the same, False otherwise. + + """ + return np.all(self.domain == other.domain) + + def has_samewindow(self, other): + """Check if windows match. + + .. versionadded:: 1.6.0 + + Parameters + ---------- + other : class instance + The other class must have the ``window`` attribute. + + Returns + ------- + bool : boolean + True if the windows are the same, False otherwise. + + """ + return np.all(self.window == other.window) + + def has_sametype(self, other): + """Check if types match. + + .. versionadded:: 1.7.0 + + Parameters + ---------- + other : object + Class instance. + + Returns + ------- + bool : boolean + True if other is same class as self + + """ + return isinstance(other, self.__class__) + + def _get_coefficients(self, other): + """Interpret other as polynomial coefficients. + + The `other` argument is checked to see if it is of the same + class as self with identical domain and window. If so, + return its coefficients, otherwise return `other`. + + .. versionadded:: 1.9.0 + + Parameters + ---------- + other : anything + Object to be checked. + + Returns + ------- + coef + The coefficients of`other` if it is a compatible instance, + of ABCPolyBase, otherwise `other`. + + Raises + ------ + TypeError + When `other` is an incompatible instance of ABCPolyBase. + + """ + if isinstance(other, ABCPolyBase): + if not isinstance(other, self.__class__): + raise TypeError("Polynomial types differ") + elif not np.all(self.domain == other.domain): + raise TypeError("Domains differ") + elif not np.all(self.window == other.window): + raise TypeError("Windows differ") + return other.coef + return other + + def __init__(self, coef, domain=None, window=None): + [coef] = pu.as_series([coef], trim=False) + self.coef = coef + + if domain is not None: + [domain] = pu.as_series([domain], trim=False) + if len(domain) != 2: + raise ValueError("Domain has wrong number of elements.") + self.domain = domain + + if window is not None: + [window] = pu.as_series([window], trim=False) + if len(window) != 2: + raise ValueError("Window has wrong number of elements.") + self.window = window + + def __repr__(self): + coef = repr(self.coef)[6:-1] + domain = repr(self.domain)[6:-1] + window = repr(self.window)[6:-1] + name = self.__class__.__name__ + return f"{name}({coef}, domain={domain}, window={window})" + + def __format__(self, fmt_str): + if fmt_str == '': + return self.__str__() + if fmt_str not in ('ascii', 'unicode'): + raise ValueError( + f"Unsupported format string '{fmt_str}' passed to " + f"{self.__class__}.__format__. Valid options are " + f"'ascii' and 'unicode'" + ) + if fmt_str == 'ascii': + return self._generate_string(self._str_term_ascii) + return self._generate_string(self._str_term_unicode) + + def __str__(self): + if self._use_unicode: + return self._generate_string(self._str_term_unicode) + return self._generate_string(self._str_term_ascii) + + def _generate_string(self, term_method): + """ + Generate the full string representation of the polynomial, using + ``term_method`` to generate each polynomial term. + """ + # Get configuration for line breaks + linewidth = np.get_printoptions().get('linewidth', 75) + if linewidth < 1: + linewidth = 1 + out = f"{self.coef[0]}" + for i, coef in enumerate(self.coef[1:]): + out += " " + power = str(i + 1) + # Polynomial coefficient + # The coefficient array can be an object array with elements that + # will raise a TypeError with >= 0 (e.g. strings or Python + # complex). In this case, represent the coeficient as-is. + try: + if coef >= 0: + next_term = f"+ {coef}" + else: + next_term = f"- {-coef}" + except TypeError: + next_term = f"+ {coef}" + # Polynomial term + next_term += term_method(power, "x") + # Length of the current line with next term added + line_len = len(out.split('\n')[-1]) + len(next_term) + # If not the last term in the polynomial, it will be two + # characters longer due to the +/- with the next term + if i < len(self.coef[1:]) - 1: + line_len += 2 + # Handle linebreaking + if line_len >= linewidth: + next_term = next_term.replace(" ", "\n", 1) + out += next_term + return out + + @classmethod + def _str_term_unicode(cls, i, arg_str): + """ + String representation of single polynomial term using unicode + characters for superscripts and subscripts. + """ + if cls.basis_name is None: + raise NotImplementedError( + "Subclasses must define either a basis_name, or override " + "_str_term_unicode(cls, i, arg_str)" + ) + return (f"·{cls.basis_name}{i.translate(cls._subscript_mapping)}" + f"({arg_str})") + + @classmethod + def _str_term_ascii(cls, i, arg_str): + """ + String representation of a single polynomial term using ** and _ to + represent superscripts and subscripts, respectively. + """ + if cls.basis_name is None: + raise NotImplementedError( + "Subclasses must define either a basis_name, or override " + "_str_term_ascii(cls, i, arg_str)" + ) + return f" {cls.basis_name}_{i}({arg_str})" + + @classmethod + def _repr_latex_term(cls, i, arg_str, needs_parens): + if cls.basis_name is None: + raise NotImplementedError( + "Subclasses must define either a basis name, or override " + "_repr_latex_term(i, arg_str, needs_parens)") + # since we always add parens, we don't care if the expression needs them + return f"{{{cls.basis_name}}}_{{{i}}}({arg_str})" + + @staticmethod + def _repr_latex_scalar(x): + # TODO: we're stuck with disabling math formatting until we handle + # exponents in this function + return r'\text{{{}}}'.format(x) + + def _repr_latex_(self): + # get the scaled argument string to the basis functions + off, scale = self.mapparms() + if off == 0 and scale == 1: + term = 'x' + needs_parens = False + elif scale == 1: + term = f"{self._repr_latex_scalar(off)} + x" + needs_parens = True + elif off == 0: + term = f"{self._repr_latex_scalar(scale)}x" + needs_parens = True + else: + term = ( + f"{self._repr_latex_scalar(off)} + " + f"{self._repr_latex_scalar(scale)}x" + ) + needs_parens = True + + mute = r"\color{{LightGray}}{{{}}}".format + + parts = [] + for i, c in enumerate(self.coef): + # prevent duplication of + and - signs + if i == 0: + coef_str = f"{self._repr_latex_scalar(c)}" + elif not isinstance(c, numbers.Real): + coef_str = f" + ({self._repr_latex_scalar(c)})" + elif not np.signbit(c): + coef_str = f" + {self._repr_latex_scalar(c)}" + else: + coef_str = f" - {self._repr_latex_scalar(-c)}" + + # produce the string for the term + term_str = self._repr_latex_term(i, term, needs_parens) + if term_str == '1': + part = coef_str + else: + part = rf"{coef_str}\,{term_str}" + + if c == 0: + part = mute(part) + + parts.append(part) + + if parts: + body = ''.join(parts) + else: + # in case somehow there are no coefficients at all + body = '0' + + return rf"$x \mapsto {body}$" + + + + # Pickle and copy + + def __getstate__(self): + ret = self.__dict__.copy() + ret['coef'] = self.coef.copy() + ret['domain'] = self.domain.copy() + ret['window'] = self.window.copy() + return ret + + def __setstate__(self, dict): + self.__dict__ = dict + + # Call + + def __call__(self, arg): + off, scl = pu.mapparms(self.domain, self.window) + arg = off + scl*arg + return self._val(arg, self.coef) + + def __iter__(self): + return iter(self.coef) + + def __len__(self): + return len(self.coef) + + # Numeric properties. + + def __neg__(self): + return self.__class__(-self.coef, self.domain, self.window) + + def __pos__(self): + return self + + def __add__(self, other): + othercoef = self._get_coefficients(other) + try: + coef = self._add(self.coef, othercoef) + except Exception: + return NotImplemented + return self.__class__(coef, self.domain, self.window) + + def __sub__(self, other): + othercoef = self._get_coefficients(other) + try: + coef = self._sub(self.coef, othercoef) + except Exception: + return NotImplemented + return self.__class__(coef, self.domain, self.window) + + def __mul__(self, other): + othercoef = self._get_coefficients(other) + try: + coef = self._mul(self.coef, othercoef) + except Exception: + return NotImplemented + return self.__class__(coef, self.domain, self.window) + + def __truediv__(self, other): + # there is no true divide if the rhs is not a Number, although it + # could return the first n elements of an infinite series. + # It is hard to see where n would come from, though. + if not isinstance(other, numbers.Number) or isinstance(other, bool): + raise TypeError( + f"unsupported types for true division: " + f"'{type(self)}', '{type(other)}'" + ) + return self.__floordiv__(other) + + def __floordiv__(self, other): + res = self.__divmod__(other) + if res is NotImplemented: + return res + return res[0] + + def __mod__(self, other): + res = self.__divmod__(other) + if res is NotImplemented: + return res + return res[1] + + def __divmod__(self, other): + othercoef = self._get_coefficients(other) + try: + quo, rem = self._div(self.coef, othercoef) + except ZeroDivisionError: + raise + except Exception: + return NotImplemented + quo = self.__class__(quo, self.domain, self.window) + rem = self.__class__(rem, self.domain, self.window) + return quo, rem + + def __pow__(self, other): + coef = self._pow(self.coef, other, maxpower=self.maxpower) + res = self.__class__(coef, self.domain, self.window) + return res + + def __radd__(self, other): + try: + coef = self._add(other, self.coef) + except Exception: + return NotImplemented + return self.__class__(coef, self.domain, self.window) + + def __rsub__(self, other): + try: + coef = self._sub(other, self.coef) + except Exception: + return NotImplemented + return self.__class__(coef, self.domain, self.window) + + def __rmul__(self, other): + try: + coef = self._mul(other, self.coef) + except Exception: + return NotImplemented + return self.__class__(coef, self.domain, self.window) + + def __rdiv__(self, other): + # set to __floordiv__ /. + return self.__rfloordiv__(other) + + def __rtruediv__(self, other): + # An instance of ABCPolyBase is not considered a + # Number. + return NotImplemented + + def __rfloordiv__(self, other): + res = self.__rdivmod__(other) + if res is NotImplemented: + return res + return res[0] + + def __rmod__(self, other): + res = self.__rdivmod__(other) + if res is NotImplemented: + return res + return res[1] + + def __rdivmod__(self, other): + try: + quo, rem = self._div(other, self.coef) + except ZeroDivisionError: + raise + except Exception: + return NotImplemented + quo = self.__class__(quo, self.domain, self.window) + rem = self.__class__(rem, self.domain, self.window) + return quo, rem + + def __eq__(self, other): + res = (isinstance(other, self.__class__) and + np.all(self.domain == other.domain) and + np.all(self.window == other.window) and + (self.coef.shape == other.coef.shape) and + np.all(self.coef == other.coef)) + return res + + def __ne__(self, other): + return not self.__eq__(other) + + # + # Extra methods. + # + + def copy(self): + """Return a copy. + + Returns + ------- + new_series : series + Copy of self. + + """ + return self.__class__(self.coef, self.domain, self.window) + + def degree(self): + """The degree of the series. + + .. versionadded:: 1.5.0 + + Returns + ------- + degree : int + Degree of the series, one less than the number of coefficients. + + """ + return len(self) - 1 + + def cutdeg(self, deg): + """Truncate series to the given degree. + + Reduce the degree of the series to `deg` by discarding the + high order terms. If `deg` is greater than the current degree a + copy of the current series is returned. This can be useful in least + squares where the coefficients of the high degree terms may be very + small. + + .. versionadded:: 1.5.0 + + Parameters + ---------- + deg : non-negative int + The series is reduced to degree `deg` by discarding the high + order terms. The value of `deg` must be a non-negative integer. + + Returns + ------- + new_series : series + New instance of series with reduced degree. + + """ + return self.truncate(deg + 1) + + def trim(self, tol=0): + """Remove trailing coefficients + + Remove trailing coefficients until a coefficient is reached whose + absolute value greater than `tol` or the beginning of the series is + reached. If all the coefficients would be removed the series is set + to ``[0]``. A new series instance is returned with the new + coefficients. The current instance remains unchanged. + + Parameters + ---------- + tol : non-negative number. + All trailing coefficients less than `tol` will be removed. + + Returns + ------- + new_series : series + Contains the new set of coefficients. + + """ + coef = pu.trimcoef(self.coef, tol) + return self.__class__(coef, self.domain, self.window) + + def truncate(self, size): + """Truncate series to length `size`. + + Reduce the series to length `size` by discarding the high + degree terms. The value of `size` must be a positive integer. This + can be useful in least squares where the coefficients of the + high degree terms may be very small. + + Parameters + ---------- + size : positive int + The series is reduced to length `size` by discarding the high + degree terms. The value of `size` must be a positive integer. + + Returns + ------- + new_series : series + New instance of series with truncated coefficients. + + """ + isize = int(size) + if isize != size or isize < 1: + raise ValueError("size must be a positive integer") + if isize >= len(self.coef): + coef = self.coef + else: + coef = self.coef[:isize] + return self.__class__(coef, self.domain, self.window) + + def convert(self, domain=None, kind=None, window=None): + """Convert series to a different kind and/or domain and/or window. + + Parameters + ---------- + domain : array_like, optional + The domain of the converted series. If the value is None, + the default domain of `kind` is used. + kind : class, optional + The polynomial series type class to which the current instance + should be converted. If kind is None, then the class of the + current instance is used. + window : array_like, optional + The window of the converted series. If the value is None, + the default window of `kind` is used. + + Returns + ------- + new_series : series + The returned class can be of different type than the current + instance and/or have a different domain and/or different + window. + + Notes + ----- + Conversion between domains and class types can result in + numerically ill defined series. + + Examples + -------- + + """ + if kind is None: + kind = self.__class__ + if domain is None: + domain = kind.domain + if window is None: + window = kind.window + return self(kind.identity(domain, window=window)) + + def mapparms(self): + """Return the mapping parameters. + + The returned values define a linear map ``off + scl*x`` that is + applied to the input arguments before the series is evaluated. The + map depends on the ``domain`` and ``window``; if the current + ``domain`` is equal to the ``window`` the resulting map is the + identity. If the coefficients of the series instance are to be + used by themselves outside this class, then the linear function + must be substituted for the ``x`` in the standard representation of + the base polynomials. + + Returns + ------- + off, scl : float or complex + The mapping function is defined by ``off + scl*x``. + + Notes + ----- + If the current domain is the interval ``[l1, r1]`` and the window + is ``[l2, r2]``, then the linear mapping function ``L`` is + defined by the equations:: + + L(l1) = l2 + L(r1) = r2 + + """ + return pu.mapparms(self.domain, self.window) + + def integ(self, m=1, k=[], lbnd=None): + """Integrate. + + Return a series instance that is the definite integral of the + current series. + + Parameters + ---------- + m : non-negative int + The number of integrations to perform. + k : array_like + Integration constants. The first constant is applied to the + first integration, the second to the second, and so on. The + list of values must less than or equal to `m` in length and any + missing values are set to zero. + lbnd : Scalar + The lower bound of the definite integral. + + Returns + ------- + new_series : series + A new series representing the integral. The domain is the same + as the domain of the integrated series. + + """ + off, scl = self.mapparms() + if lbnd is None: + lbnd = 0 + else: + lbnd = off + scl*lbnd + coef = self._int(self.coef, m, k, lbnd, 1./scl) + return self.__class__(coef, self.domain, self.window) + + def deriv(self, m=1): + """Differentiate. + + Return a series instance of that is the derivative of the current + series. + + Parameters + ---------- + m : non-negative int + Find the derivative of order `m`. + + Returns + ------- + new_series : series + A new series representing the derivative. The domain is the same + as the domain of the differentiated series. + + """ + off, scl = self.mapparms() + coef = self._der(self.coef, m, scl) + return self.__class__(coef, self.domain, self.window) + + def roots(self): + """Return the roots of the series polynomial. + + Compute the roots for the series. Note that the accuracy of the + roots decrease the further outside the domain they lie. + + Returns + ------- + roots : ndarray + Array containing the roots of the series. + + """ + roots = self._roots(self.coef) + return pu.mapdomain(roots, self.window, self.domain) + + def linspace(self, n=100, domain=None): + """Return x, y values at equally spaced points in domain. + + Returns the x, y values at `n` linearly spaced points across the + domain. Here y is the value of the polynomial at the points x. By + default the domain is the same as that of the series instance. + This method is intended mostly as a plotting aid. + + .. versionadded:: 1.5.0 + + Parameters + ---------- + n : int, optional + Number of point pairs to return. The default value is 100. + domain : {None, array_like}, optional + If not None, the specified domain is used instead of that of + the calling instance. It should be of the form ``[beg,end]``. + The default is None which case the class domain is used. + + Returns + ------- + x, y : ndarray + x is equal to linspace(self.domain[0], self.domain[1], n) and + y is the series evaluated at element of x. + + """ + if domain is None: + domain = self.domain + x = np.linspace(domain[0], domain[1], n) + y = self(x) + return x, y + + @classmethod + def fit(cls, x, y, deg, domain=None, rcond=None, full=False, w=None, + window=None): + """Least squares fit to data. + + Return a series instance that is the least squares fit to the data + `y` sampled at `x`. The domain of the returned instance can be + specified and this will often result in a superior fit with less + chance of ill conditioning. + + Parameters + ---------- + x : array_like, shape (M,) + x-coordinates of the M sample points ``(x[i], y[i])``. + y : array_like, shape (M,) + y-coordinates of the M sample points ``(x[i], y[i])``. + deg : int or 1-D array_like + Degree(s) of the fitting polynomials. If `deg` is a single integer + all terms up to and including the `deg`'th term are included in the + fit. For NumPy versions >= 1.11.0 a list of integers specifying the + degrees of the terms to include may be used instead. + domain : {None, [beg, end], []}, optional + Domain to use for the returned series. If ``None``, + then a minimal domain that covers the points `x` is chosen. If + ``[]`` the class domain is used. The default value was the + class domain in NumPy 1.4 and ``None`` in later versions. + The ``[]`` option was added in numpy 1.5.0. + rcond : float, optional + Relative condition number of the fit. Singular values smaller + than this relative to the largest singular value will be + ignored. The default value is len(x)*eps, where eps is the + relative precision of the float type, about 2e-16 in most + cases. + full : bool, optional + Switch determining nature of return value. When it is False + (the default) just the coefficients are returned, when True + diagnostic information from the singular value decomposition is + also returned. + w : array_like, shape (M,), optional + Weights. If not None the contribution of each point + ``(x[i],y[i])`` to the fit is weighted by `w[i]`. Ideally the + weights are chosen so that the errors of the products + ``w[i]*y[i]`` all have the same variance. The default value is + None. + + .. versionadded:: 1.5.0 + window : {[beg, end]}, optional + Window to use for the returned series. The default + value is the default class domain + + .. versionadded:: 1.6.0 + + Returns + ------- + new_series : series + A series that represents the least squares fit to the data and + has the domain and window specified in the call. If the + coefficients for the unscaled and unshifted basis polynomials are + of interest, do ``new_series.convert().coef``. + + [resid, rank, sv, rcond] : list + These values are only returned if `full` = True + + resid -- sum of squared residuals of the least squares fit + rank -- the numerical rank of the scaled Vandermonde matrix + sv -- singular values of the scaled Vandermonde matrix + rcond -- value of `rcond`. + + For more details, see `linalg.lstsq`. + + """ + if domain is None: + domain = pu.getdomain(x) + elif type(domain) is list and len(domain) == 0: + domain = cls.domain + + if window is None: + window = cls.window + + xnew = pu.mapdomain(x, domain, window) + res = cls._fit(xnew, y, deg, w=w, rcond=rcond, full=full) + if full: + [coef, status] = res + return cls(coef, domain=domain, window=window), status + else: + coef = res + return cls(coef, domain=domain, window=window) + + @classmethod + def fromroots(cls, roots, domain=[], window=None): + """Return series instance that has the specified roots. + + Returns a series representing the product + ``(x - r[0])*(x - r[1])*...*(x - r[n-1])``, where ``r`` is a + list of roots. + + Parameters + ---------- + roots : array_like + List of roots. + domain : {[], None, array_like}, optional + Domain for the resulting series. If None the domain is the + interval from the smallest root to the largest. If [] the + domain is the class domain. The default is []. + window : {None, array_like}, optional + Window for the returned series. If None the class window is + used. The default is None. + + Returns + ------- + new_series : series + Series with the specified roots. + + """ + [roots] = pu.as_series([roots], trim=False) + if domain is None: + domain = pu.getdomain(roots) + elif type(domain) is list and len(domain) == 0: + domain = cls.domain + + if window is None: + window = cls.window + + deg = len(roots) + off, scl = pu.mapparms(domain, window) + rnew = off + scl*roots + coef = cls._fromroots(rnew) / scl**deg + return cls(coef, domain=domain, window=window) + + @classmethod + def identity(cls, domain=None, window=None): + """Identity function. + + If ``p`` is the returned series, then ``p(x) == x`` for all + values of x. + + Parameters + ---------- + domain : {None, array_like}, optional + If given, the array must be of the form ``[beg, end]``, where + ``beg`` and ``end`` are the endpoints of the domain. If None is + given then the class domain is used. The default is None. + window : {None, array_like}, optional + If given, the resulting array must be if the form + ``[beg, end]``, where ``beg`` and ``end`` are the endpoints of + the window. If None is given then the class window is used. The + default is None. + + Returns + ------- + new_series : series + Series of representing the identity. + + """ + if domain is None: + domain = cls.domain + if window is None: + window = cls.window + off, scl = pu.mapparms(window, domain) + coef = cls._line(off, scl) + return cls(coef, domain, window) + + @classmethod + def basis(cls, deg, domain=None, window=None): + """Series basis polynomial of degree `deg`. + + Returns the series representing the basis polynomial of degree `deg`. + + .. versionadded:: 1.7.0 + + Parameters + ---------- + deg : int + Degree of the basis polynomial for the series. Must be >= 0. + domain : {None, array_like}, optional + If given, the array must be of the form ``[beg, end]``, where + ``beg`` and ``end`` are the endpoints of the domain. If None is + given then the class domain is used. The default is None. + window : {None, array_like}, optional + If given, the resulting array must be if the form + ``[beg, end]``, where ``beg`` and ``end`` are the endpoints of + the window. If None is given then the class window is used. The + default is None. + + Returns + ------- + new_series : series + A series with the coefficient of the `deg` term set to one and + all others zero. + + """ + if domain is None: + domain = cls.domain + if window is None: + window = cls.window + ideg = int(deg) + + if ideg != deg or ideg < 0: + raise ValueError("deg must be non-negative integer") + return cls([0]*ideg + [1], domain, window) + + @classmethod + def cast(cls, series, domain=None, window=None): + """Convert series to series of this class. + + The `series` is expected to be an instance of some polynomial + series of one of the types supported by by the numpy.polynomial + module, but could be some other class that supports the convert + method. + + .. versionadded:: 1.7.0 + + Parameters + ---------- + series : series + The series instance to be converted. + domain : {None, array_like}, optional + If given, the array must be of the form ``[beg, end]``, where + ``beg`` and ``end`` are the endpoints of the domain. If None is + given then the class domain is used. The default is None. + window : {None, array_like}, optional + If given, the resulting array must be if the form + ``[beg, end]``, where ``beg`` and ``end`` are the endpoints of + the window. If None is given then the class window is used. The + default is None. + + Returns + ------- + new_series : series + A series of the same kind as the calling class and equal to + `series` when evaluated. + + See Also + -------- + convert : similar instance method + + """ + if domain is None: + domain = cls.domain + if window is None: + window = cls.window + return series.convert(domain, cls, window) diff --git a/venv/Lib/site-packages/numpy/polynomial/chebyshev.py b/venv/Lib/site-packages/numpy/polynomial/chebyshev.py new file mode 100644 index 0000000..6745c93 --- /dev/null +++ b/venv/Lib/site-packages/numpy/polynomial/chebyshev.py @@ -0,0 +1,2077 @@ +""" +==================================================== +Chebyshev Series (:mod:`numpy.polynomial.chebyshev`) +==================================================== + +This module provides a number of objects (mostly functions) useful for +dealing with Chebyshev series, including a `Chebyshev` class that +encapsulates the usual arithmetic operations. (General information +on how this module represents and works with such polynomials is in the +docstring for its "parent" sub-package, `numpy.polynomial`). + +Classes +------- + +.. autosummary:: + :toctree: generated/ + + Chebyshev + + +Constants +--------- + +.. autosummary:: + :toctree: generated/ + + chebdomain + chebzero + chebone + chebx + +Arithmetic +---------- + +.. autosummary:: + :toctree: generated/ + + chebadd + chebsub + chebmulx + chebmul + chebdiv + chebpow + chebval + chebval2d + chebval3d + chebgrid2d + chebgrid3d + +Calculus +-------- + +.. autosummary:: + :toctree: generated/ + + chebder + chebint + +Misc Functions +-------------- + +.. autosummary:: + :toctree: generated/ + + chebfromroots + chebroots + chebvander + chebvander2d + chebvander3d + chebgauss + chebweight + chebcompanion + chebfit + chebpts1 + chebpts2 + chebtrim + chebline + cheb2poly + poly2cheb + chebinterpolate + +See also +-------- +`numpy.polynomial` + +Notes +----- +The implementations of multiplication, division, integration, and +differentiation use the algebraic identities [1]_: + +.. math :: + T_n(x) = \\frac{z^n + z^{-n}}{2} \\\\ + z\\frac{dx}{dz} = \\frac{z - z^{-1}}{2}. + +where + +.. math :: x = \\frac{z + z^{-1}}{2}. + +These identities allow a Chebyshev series to be expressed as a finite, +symmetric Laurent series. In this module, this sort of Laurent series +is referred to as a "z-series." + +References +---------- +.. [1] A. T. Benjamin, et al., "Combinatorial Trigonometry with Chebyshev + Polynomials," *Journal of Statistical Planning and Inference 14*, 2008 + (https://web.archive.org/web/20080221202153/https://www.math.hmc.edu/~benjamin/papers/CombTrig.pdf, pg. 4) + +""" +import numpy as np +import numpy.linalg as la +from numpy.core.multiarray import normalize_axis_index + +from . import polyutils as pu +from ._polybase import ABCPolyBase + +__all__ = [ + 'chebzero', 'chebone', 'chebx', 'chebdomain', 'chebline', 'chebadd', + 'chebsub', 'chebmulx', 'chebmul', 'chebdiv', 'chebpow', 'chebval', + 'chebder', 'chebint', 'cheb2poly', 'poly2cheb', 'chebfromroots', + 'chebvander', 'chebfit', 'chebtrim', 'chebroots', 'chebpts1', + 'chebpts2', 'Chebyshev', 'chebval2d', 'chebval3d', 'chebgrid2d', + 'chebgrid3d', 'chebvander2d', 'chebvander3d', 'chebcompanion', + 'chebgauss', 'chebweight', 'chebinterpolate'] + +chebtrim = pu.trimcoef + +# +# A collection of functions for manipulating z-series. These are private +# functions and do minimal error checking. +# + +def _cseries_to_zseries(c): + """Covert Chebyshev series to z-series. + + Covert a Chebyshev series to the equivalent z-series. The result is + never an empty array. The dtype of the return is the same as that of + the input. No checks are run on the arguments as this routine is for + internal use. + + Parameters + ---------- + c : 1-D ndarray + Chebyshev coefficients, ordered from low to high + + Returns + ------- + zs : 1-D ndarray + Odd length symmetric z-series, ordered from low to high. + + """ + n = c.size + zs = np.zeros(2*n-1, dtype=c.dtype) + zs[n-1:] = c/2 + return zs + zs[::-1] + + +def _zseries_to_cseries(zs): + """Covert z-series to a Chebyshev series. + + Covert a z series to the equivalent Chebyshev series. The result is + never an empty array. The dtype of the return is the same as that of + the input. No checks are run on the arguments as this routine is for + internal use. + + Parameters + ---------- + zs : 1-D ndarray + Odd length symmetric z-series, ordered from low to high. + + Returns + ------- + c : 1-D ndarray + Chebyshev coefficients, ordered from low to high. + + """ + n = (zs.size + 1)//2 + c = zs[n-1:].copy() + c[1:n] *= 2 + return c + + +def _zseries_mul(z1, z2): + """Multiply two z-series. + + Multiply two z-series to produce a z-series. + + Parameters + ---------- + z1, z2 : 1-D ndarray + The arrays must be 1-D but this is not checked. + + Returns + ------- + product : 1-D ndarray + The product z-series. + + Notes + ----- + This is simply convolution. If symmetric/anti-symmetric z-series are + denoted by S/A then the following rules apply: + + S*S, A*A -> S + S*A, A*S -> A + + """ + return np.convolve(z1, z2) + + +def _zseries_div(z1, z2): + """Divide the first z-series by the second. + + Divide `z1` by `z2` and return the quotient and remainder as z-series. + Warning: this implementation only applies when both z1 and z2 have the + same symmetry, which is sufficient for present purposes. + + Parameters + ---------- + z1, z2 : 1-D ndarray + The arrays must be 1-D and have the same symmetry, but this is not + checked. + + Returns + ------- + + (quotient, remainder) : 1-D ndarrays + Quotient and remainder as z-series. + + Notes + ----- + This is not the same as polynomial division on account of the desired form + of the remainder. If symmetric/anti-symmetric z-series are denoted by S/A + then the following rules apply: + + S/S -> S,S + A/A -> S,A + + The restriction to types of the same symmetry could be fixed but seems like + unneeded generality. There is no natural form for the remainder in the case + where there is no symmetry. + + """ + z1 = z1.copy() + z2 = z2.copy() + lc1 = len(z1) + lc2 = len(z2) + if lc2 == 1: + z1 /= z2 + return z1, z1[:1]*0 + elif lc1 < lc2: + return z1[:1]*0, z1 + else: + dlen = lc1 - lc2 + scl = z2[0] + z2 /= scl + quo = np.empty(dlen + 1, dtype=z1.dtype) + i = 0 + j = dlen + while i < j: + r = z1[i] + quo[i] = z1[i] + quo[dlen - i] = r + tmp = r*z2 + z1[i:i+lc2] -= tmp + z1[j:j+lc2] -= tmp + i += 1 + j -= 1 + r = z1[i] + quo[i] = r + tmp = r*z2 + z1[i:i+lc2] -= tmp + quo /= scl + rem = z1[i+1:i-1+lc2].copy() + return quo, rem + + +def _zseries_der(zs): + """Differentiate a z-series. + + The derivative is with respect to x, not z. This is achieved using the + chain rule and the value of dx/dz given in the module notes. + + Parameters + ---------- + zs : z-series + The z-series to differentiate. + + Returns + ------- + derivative : z-series + The derivative + + Notes + ----- + The zseries for x (ns) has been multiplied by two in order to avoid + using floats that are incompatible with Decimal and likely other + specialized scalar types. This scaling has been compensated by + multiplying the value of zs by two also so that the two cancels in the + division. + + """ + n = len(zs)//2 + ns = np.array([-1, 0, 1], dtype=zs.dtype) + zs *= np.arange(-n, n+1)*2 + d, r = _zseries_div(zs, ns) + return d + + +def _zseries_int(zs): + """Integrate a z-series. + + The integral is with respect to x, not z. This is achieved by a change + of variable using dx/dz given in the module notes. + + Parameters + ---------- + zs : z-series + The z-series to integrate + + Returns + ------- + integral : z-series + The indefinite integral + + Notes + ----- + The zseries for x (ns) has been multiplied by two in order to avoid + using floats that are incompatible with Decimal and likely other + specialized scalar types. This scaling has been compensated by + dividing the resulting zs by two. + + """ + n = 1 + len(zs)//2 + ns = np.array([-1, 0, 1], dtype=zs.dtype) + zs = _zseries_mul(zs, ns) + div = np.arange(-n, n+1)*2 + zs[:n] /= div[:n] + zs[n+1:] /= div[n+1:] + zs[n] = 0 + return zs + +# +# Chebyshev series functions +# + + +def poly2cheb(pol): + """ + Convert a polynomial to a Chebyshev series. + + Convert an array representing the coefficients of a polynomial (relative + to the "standard" basis) ordered from lowest degree to highest, to an + array of the coefficients of the equivalent Chebyshev series, ordered + from lowest to highest degree. + + Parameters + ---------- + pol : array_like + 1-D array containing the polynomial coefficients + + Returns + ------- + c : ndarray + 1-D array containing the coefficients of the equivalent Chebyshev + series. + + See Also + -------- + cheb2poly + + Notes + ----- + The easy way to do conversions between polynomial basis sets + is to use the convert method of a class instance. + + Examples + -------- + >>> from numpy import polynomial as P + >>> p = P.Polynomial(range(4)) + >>> p + Polynomial([0., 1., 2., 3.], domain=[-1, 1], window=[-1, 1]) + >>> c = p.convert(kind=P.Chebyshev) + >>> c + Chebyshev([1. , 3.25, 1. , 0.75], domain=[-1., 1.], window=[-1., 1.]) + >>> P.chebyshev.poly2cheb(range(4)) + array([1. , 3.25, 1. , 0.75]) + + """ + [pol] = pu.as_series([pol]) + deg = len(pol) - 1 + res = 0 + for i in range(deg, -1, -1): + res = chebadd(chebmulx(res), pol[i]) + return res + + +def cheb2poly(c): + """ + Convert a Chebyshev series to a polynomial. + + Convert an array representing the coefficients of a Chebyshev series, + ordered from lowest degree to highest, to an array of the coefficients + of the equivalent polynomial (relative to the "standard" basis) ordered + from lowest to highest degree. + + Parameters + ---------- + c : array_like + 1-D array containing the Chebyshev series coefficients, ordered + from lowest order term to highest. + + Returns + ------- + pol : ndarray + 1-D array containing the coefficients of the equivalent polynomial + (relative to the "standard" basis) ordered from lowest order term + to highest. + + See Also + -------- + poly2cheb + + Notes + ----- + The easy way to do conversions between polynomial basis sets + is to use the convert method of a class instance. + + Examples + -------- + >>> from numpy import polynomial as P + >>> c = P.Chebyshev(range(4)) + >>> c + Chebyshev([0., 1., 2., 3.], domain=[-1, 1], window=[-1, 1]) + >>> p = c.convert(kind=P.Polynomial) + >>> p + Polynomial([-2., -8., 4., 12.], domain=[-1., 1.], window=[-1., 1.]) + >>> P.chebyshev.cheb2poly(range(4)) + array([-2., -8., 4., 12.]) + + """ + from .polynomial import polyadd, polysub, polymulx + + [c] = pu.as_series([c]) + n = len(c) + if n < 3: + return c + else: + c0 = c[-2] + c1 = c[-1] + # i is the current degree of c1 + for i in range(n - 1, 1, -1): + tmp = c0 + c0 = polysub(c[i - 2], c1) + c1 = polyadd(tmp, polymulx(c1)*2) + return polyadd(c0, polymulx(c1)) + + +# +# These are constant arrays are of integer type so as to be compatible +# with the widest range of other types, such as Decimal. +# + +# Chebyshev default domain. +chebdomain = np.array([-1, 1]) + +# Chebyshev coefficients representing zero. +chebzero = np.array([0]) + +# Chebyshev coefficients representing one. +chebone = np.array([1]) + +# Chebyshev coefficients representing the identity x. +chebx = np.array([0, 1]) + + +def chebline(off, scl): + """ + Chebyshev series whose graph is a straight line. + + Parameters + ---------- + off, scl : scalars + The specified line is given by ``off + scl*x``. + + Returns + ------- + y : ndarray + This module's representation of the Chebyshev series for + ``off + scl*x``. + + See Also + -------- + numpy.polynomial.polynomial.polyline + numpy.polynomial.legendre.legline + numpy.polynomial.laguerre.lagline + numpy.polynomial.hermite.hermline + numpy.polynomial.hermite_e.hermeline + + Examples + -------- + >>> import numpy.polynomial.chebyshev as C + >>> C.chebline(3,2) + array([3, 2]) + >>> C.chebval(-3, C.chebline(3,2)) # should be -3 + -3.0 + + """ + if scl != 0: + return np.array([off, scl]) + else: + return np.array([off]) + + +def chebfromroots(roots): + """ + Generate a Chebyshev series with given roots. + + The function returns the coefficients of the polynomial + + .. math:: p(x) = (x - r_0) * (x - r_1) * ... * (x - r_n), + + in Chebyshev form, where the `r_n` are the roots specified in `roots`. + If a zero has multiplicity n, then it must appear in `roots` n times. + For instance, if 2 is a root of multiplicity three and 3 is a root of + multiplicity 2, then `roots` looks something like [2, 2, 2, 3, 3]. The + roots can appear in any order. + + If the returned coefficients are `c`, then + + .. math:: p(x) = c_0 + c_1 * T_1(x) + ... + c_n * T_n(x) + + The coefficient of the last term is not generally 1 for monic + polynomials in Chebyshev form. + + Parameters + ---------- + roots : array_like + Sequence containing the roots. + + Returns + ------- + out : ndarray + 1-D array of coefficients. If all roots are real then `out` is a + real array, if some of the roots are complex, then `out` is complex + even if all the coefficients in the result are real (see Examples + below). + + See Also + -------- + numpy.polynomial.polynomial.polyfromroots + numpy.polynomial.legendre.legfromroots + numpy.polynomial.laguerre.lagfromroots + numpy.polynomial.hermite.hermfromroots + numpy.polynomial.hermite_e.hermefromroots + + Examples + -------- + >>> import numpy.polynomial.chebyshev as C + >>> C.chebfromroots((-1,0,1)) # x^3 - x relative to the standard basis + array([ 0. , -0.25, 0. , 0.25]) + >>> j = complex(0,1) + >>> C.chebfromroots((-j,j)) # x^2 + 1 relative to the standard basis + array([1.5+0.j, 0. +0.j, 0.5+0.j]) + + """ + return pu._fromroots(chebline, chebmul, roots) + + +def chebadd(c1, c2): + """ + Add one Chebyshev series to another. + + Returns the sum of two Chebyshev series `c1` + `c2`. The arguments + are sequences of coefficients ordered from lowest order term to + highest, i.e., [1,2,3] represents the series ``T_0 + 2*T_1 + 3*T_2``. + + Parameters + ---------- + c1, c2 : array_like + 1-D arrays of Chebyshev series coefficients ordered from low to + high. + + Returns + ------- + out : ndarray + Array representing the Chebyshev series of their sum. + + See Also + -------- + chebsub, chebmulx, chebmul, chebdiv, chebpow + + Notes + ----- + Unlike multiplication, division, etc., the sum of two Chebyshev series + is a Chebyshev series (without having to "reproject" the result onto + the basis set) so addition, just like that of "standard" polynomials, + is simply "component-wise." + + Examples + -------- + >>> from numpy.polynomial import chebyshev as C + >>> c1 = (1,2,3) + >>> c2 = (3,2,1) + >>> C.chebadd(c1,c2) + array([4., 4., 4.]) + + """ + return pu._add(c1, c2) + + +def chebsub(c1, c2): + """ + Subtract one Chebyshev series from another. + + Returns the difference of two Chebyshev series `c1` - `c2`. The + sequences of coefficients are from lowest order term to highest, i.e., + [1,2,3] represents the series ``T_0 + 2*T_1 + 3*T_2``. + + Parameters + ---------- + c1, c2 : array_like + 1-D arrays of Chebyshev series coefficients ordered from low to + high. + + Returns + ------- + out : ndarray + Of Chebyshev series coefficients representing their difference. + + See Also + -------- + chebadd, chebmulx, chebmul, chebdiv, chebpow + + Notes + ----- + Unlike multiplication, division, etc., the difference of two Chebyshev + series is a Chebyshev series (without having to "reproject" the result + onto the basis set) so subtraction, just like that of "standard" + polynomials, is simply "component-wise." + + Examples + -------- + >>> from numpy.polynomial import chebyshev as C + >>> c1 = (1,2,3) + >>> c2 = (3,2,1) + >>> C.chebsub(c1,c2) + array([-2., 0., 2.]) + >>> C.chebsub(c2,c1) # -C.chebsub(c1,c2) + array([ 2., 0., -2.]) + + """ + return pu._sub(c1, c2) + + +def chebmulx(c): + """Multiply a Chebyshev series by x. + + Multiply the polynomial `c` by x, where x is the independent + variable. + + + Parameters + ---------- + c : array_like + 1-D array of Chebyshev series coefficients ordered from low to + high. + + Returns + ------- + out : ndarray + Array representing the result of the multiplication. + + Notes + ----- + + .. versionadded:: 1.5.0 + + Examples + -------- + >>> from numpy.polynomial import chebyshev as C + >>> C.chebmulx([1,2,3]) + array([1. , 2.5, 1. , 1.5]) + + """ + # c is a trimmed copy + [c] = pu.as_series([c]) + # The zero series needs special treatment + if len(c) == 1 and c[0] == 0: + return c + + prd = np.empty(len(c) + 1, dtype=c.dtype) + prd[0] = c[0]*0 + prd[1] = c[0] + if len(c) > 1: + tmp = c[1:]/2 + prd[2:] = tmp + prd[0:-2] += tmp + return prd + + +def chebmul(c1, c2): + """ + Multiply one Chebyshev series by another. + + Returns the product of two Chebyshev series `c1` * `c2`. The arguments + are sequences of coefficients, from lowest order "term" to highest, + e.g., [1,2,3] represents the series ``T_0 + 2*T_1 + 3*T_2``. + + Parameters + ---------- + c1, c2 : array_like + 1-D arrays of Chebyshev series coefficients ordered from low to + high. + + Returns + ------- + out : ndarray + Of Chebyshev series coefficients representing their product. + + See Also + -------- + chebadd, chebsub, chebmulx, chebdiv, chebpow + + Notes + ----- + In general, the (polynomial) product of two C-series results in terms + that are not in the Chebyshev polynomial basis set. Thus, to express + the product as a C-series, it is typically necessary to "reproject" + the product onto said basis set, which typically produces + "unintuitive live" (but correct) results; see Examples section below. + + Examples + -------- + >>> from numpy.polynomial import chebyshev as C + >>> c1 = (1,2,3) + >>> c2 = (3,2,1) + >>> C.chebmul(c1,c2) # multiplication requires "reprojection" + array([ 6.5, 12. , 12. , 4. , 1.5]) + + """ + # c1, c2 are trimmed copies + [c1, c2] = pu.as_series([c1, c2]) + z1 = _cseries_to_zseries(c1) + z2 = _cseries_to_zseries(c2) + prd = _zseries_mul(z1, z2) + ret = _zseries_to_cseries(prd) + return pu.trimseq(ret) + + +def chebdiv(c1, c2): + """ + Divide one Chebyshev series by another. + + Returns the quotient-with-remainder of two Chebyshev series + `c1` / `c2`. The arguments are sequences of coefficients from lowest + order "term" to highest, e.g., [1,2,3] represents the series + ``T_0 + 2*T_1 + 3*T_2``. + + Parameters + ---------- + c1, c2 : array_like + 1-D arrays of Chebyshev series coefficients ordered from low to + high. + + Returns + ------- + [quo, rem] : ndarrays + Of Chebyshev series coefficients representing the quotient and + remainder. + + See Also + -------- + chebadd, chebsub, chebmulx, chebmul, chebpow + + Notes + ----- + In general, the (polynomial) division of one C-series by another + results in quotient and remainder terms that are not in the Chebyshev + polynomial basis set. Thus, to express these results as C-series, it + is typically necessary to "reproject" the results onto said basis + set, which typically produces "unintuitive" (but correct) results; + see Examples section below. + + Examples + -------- + >>> from numpy.polynomial import chebyshev as C + >>> c1 = (1,2,3) + >>> c2 = (3,2,1) + >>> C.chebdiv(c1,c2) # quotient "intuitive," remainder not + (array([3.]), array([-8., -4.])) + >>> c2 = (0,1,2,3) + >>> C.chebdiv(c2,c1) # neither "intuitive" + (array([0., 2.]), array([-2., -4.])) + + """ + # c1, c2 are trimmed copies + [c1, c2] = pu.as_series([c1, c2]) + if c2[-1] == 0: + raise ZeroDivisionError() + + # note: this is more efficient than `pu._div(chebmul, c1, c2)` + lc1 = len(c1) + lc2 = len(c2) + if lc1 < lc2: + return c1[:1]*0, c1 + elif lc2 == 1: + return c1/c2[-1], c1[:1]*0 + else: + z1 = _cseries_to_zseries(c1) + z2 = _cseries_to_zseries(c2) + quo, rem = _zseries_div(z1, z2) + quo = pu.trimseq(_zseries_to_cseries(quo)) + rem = pu.trimseq(_zseries_to_cseries(rem)) + return quo, rem + + +def chebpow(c, pow, maxpower=16): + """Raise a Chebyshev series to a power. + + Returns the Chebyshev series `c` raised to the power `pow`. The + argument `c` is a sequence of coefficients ordered from low to high. + i.e., [1,2,3] is the series ``T_0 + 2*T_1 + 3*T_2.`` + + Parameters + ---------- + c : array_like + 1-D array of Chebyshev series coefficients ordered from low to + high. + pow : integer + Power to which the series will be raised + maxpower : integer, optional + Maximum power allowed. This is mainly to limit growth of the series + to unmanageable size. Default is 16 + + Returns + ------- + coef : ndarray + Chebyshev series of power. + + See Also + -------- + chebadd, chebsub, chebmulx, chebmul, chebdiv + + Examples + -------- + >>> from numpy.polynomial import chebyshev as C + >>> C.chebpow([1, 2, 3, 4], 2) + array([15.5, 22. , 16. , ..., 12.5, 12. , 8. ]) + + """ + # note: this is more efficient than `pu._pow(chebmul, c1, c2)`, as it + # avoids converting between z and c series repeatedly + + # c is a trimmed copy + [c] = pu.as_series([c]) + power = int(pow) + if power != pow or power < 0: + raise ValueError("Power must be a non-negative integer.") + elif maxpower is not None and power > maxpower: + raise ValueError("Power is too large") + elif power == 0: + return np.array([1], dtype=c.dtype) + elif power == 1: + return c + else: + # This can be made more efficient by using powers of two + # in the usual way. + zs = _cseries_to_zseries(c) + prd = zs + for i in range(2, power + 1): + prd = np.convolve(prd, zs) + return _zseries_to_cseries(prd) + + +def chebder(c, m=1, scl=1, axis=0): + """ + Differentiate a Chebyshev series. + + Returns the Chebyshev series coefficients `c` differentiated `m` times + along `axis`. At each iteration the result is multiplied by `scl` (the + scaling factor is for use in a linear change of variable). The argument + `c` is an array of coefficients from low to high degree along each + axis, e.g., [1,2,3] represents the series ``1*T_0 + 2*T_1 + 3*T_2`` + while [[1,2],[1,2]] represents ``1*T_0(x)*T_0(y) + 1*T_1(x)*T_0(y) + + 2*T_0(x)*T_1(y) + 2*T_1(x)*T_1(y)`` if axis=0 is ``x`` and axis=1 is + ``y``. + + Parameters + ---------- + c : array_like + Array of Chebyshev series coefficients. If c is multidimensional + the different axis correspond to different variables with the + degree in each axis given by the corresponding index. + m : int, optional + Number of derivatives taken, must be non-negative. (Default: 1) + scl : scalar, optional + Each differentiation is multiplied by `scl`. The end result is + multiplication by ``scl**m``. This is for use in a linear change of + variable. (Default: 1) + axis : int, optional + Axis over which the derivative is taken. (Default: 0). + + .. versionadded:: 1.7.0 + + Returns + ------- + der : ndarray + Chebyshev series of the derivative. + + See Also + -------- + chebint + + Notes + ----- + In general, the result of differentiating a C-series needs to be + "reprojected" onto the C-series basis set. Thus, typically, the + result of this function is "unintuitive," albeit correct; see Examples + section below. + + Examples + -------- + >>> from numpy.polynomial import chebyshev as C + >>> c = (1,2,3,4) + >>> C.chebder(c) + array([14., 12., 24.]) + >>> C.chebder(c,3) + array([96.]) + >>> C.chebder(c,scl=-1) + array([-14., -12., -24.]) + >>> C.chebder(c,2,-1) + array([12., 96.]) + + """ + c = np.array(c, ndmin=1, copy=True) + if c.dtype.char in '?bBhHiIlLqQpP': + c = c.astype(np.double) + cnt = pu._deprecate_as_int(m, "the order of derivation") + iaxis = pu._deprecate_as_int(axis, "the axis") + if cnt < 0: + raise ValueError("The order of derivation must be non-negative") + iaxis = normalize_axis_index(iaxis, c.ndim) + + if cnt == 0: + return c + + c = np.moveaxis(c, iaxis, 0) + n = len(c) + if cnt >= n: + c = c[:1]*0 + else: + for i in range(cnt): + n = n - 1 + c *= scl + der = np.empty((n,) + c.shape[1:], dtype=c.dtype) + for j in range(n, 2, -1): + der[j - 1] = (2*j)*c[j] + c[j - 2] += (j*c[j])/(j - 2) + if n > 1: + der[1] = 4*c[2] + der[0] = c[1] + c = der + c = np.moveaxis(c, 0, iaxis) + return c + + +def chebint(c, m=1, k=[], lbnd=0, scl=1, axis=0): + """ + Integrate a Chebyshev series. + + Returns the Chebyshev series coefficients `c` integrated `m` times from + `lbnd` along `axis`. At each iteration the resulting series is + **multiplied** by `scl` and an integration constant, `k`, is added. + The scaling factor is for use in a linear change of variable. ("Buyer + beware": note that, depending on what one is doing, one may want `scl` + to be the reciprocal of what one might expect; for more information, + see the Notes section below.) The argument `c` is an array of + coefficients from low to high degree along each axis, e.g., [1,2,3] + represents the series ``T_0 + 2*T_1 + 3*T_2`` while [[1,2],[1,2]] + represents ``1*T_0(x)*T_0(y) + 1*T_1(x)*T_0(y) + 2*T_0(x)*T_1(y) + + 2*T_1(x)*T_1(y)`` if axis=0 is ``x`` and axis=1 is ``y``. + + Parameters + ---------- + c : array_like + Array of Chebyshev series coefficients. If c is multidimensional + the different axis correspond to different variables with the + degree in each axis given by the corresponding index. + m : int, optional + Order of integration, must be positive. (Default: 1) + k : {[], list, scalar}, optional + Integration constant(s). The value of the first integral at zero + is the first value in the list, the value of the second integral + at zero is the second value, etc. If ``k == []`` (the default), + all constants are set to zero. If ``m == 1``, a single scalar can + be given instead of a list. + lbnd : scalar, optional + The lower bound of the integral. (Default: 0) + scl : scalar, optional + Following each integration the result is *multiplied* by `scl` + before the integration constant is added. (Default: 1) + axis : int, optional + Axis over which the integral is taken. (Default: 0). + + .. versionadded:: 1.7.0 + + Returns + ------- + S : ndarray + C-series coefficients of the integral. + + Raises + ------ + ValueError + If ``m < 1``, ``len(k) > m``, ``np.ndim(lbnd) != 0``, or + ``np.ndim(scl) != 0``. + + See Also + -------- + chebder + + Notes + ----- + Note that the result of each integration is *multiplied* by `scl`. + Why is this important to note? Say one is making a linear change of + variable :math:`u = ax + b` in an integral relative to `x`. Then + :math:`dx = du/a`, so one will need to set `scl` equal to + :math:`1/a`- perhaps not what one would have first thought. + + Also note that, in general, the result of integrating a C-series needs + to be "reprojected" onto the C-series basis set. Thus, typically, + the result of this function is "unintuitive," albeit correct; see + Examples section below. + + Examples + -------- + >>> from numpy.polynomial import chebyshev as C + >>> c = (1,2,3) + >>> C.chebint(c) + array([ 0.5, -0.5, 0.5, 0.5]) + >>> C.chebint(c,3) + array([ 0.03125 , -0.1875 , 0.04166667, -0.05208333, 0.01041667, # may vary + 0.00625 ]) + >>> C.chebint(c, k=3) + array([ 3.5, -0.5, 0.5, 0.5]) + >>> C.chebint(c,lbnd=-2) + array([ 8.5, -0.5, 0.5, 0.5]) + >>> C.chebint(c,scl=-2) + array([-1., 1., -1., -1.]) + + """ + c = np.array(c, ndmin=1, copy=True) + if c.dtype.char in '?bBhHiIlLqQpP': + c = c.astype(np.double) + if not np.iterable(k): + k = [k] + cnt = pu._deprecate_as_int(m, "the order of integration") + iaxis = pu._deprecate_as_int(axis, "the axis") + if cnt < 0: + raise ValueError("The order of integration must be non-negative") + if len(k) > cnt: + raise ValueError("Too many integration constants") + if np.ndim(lbnd) != 0: + raise ValueError("lbnd must be a scalar.") + if np.ndim(scl) != 0: + raise ValueError("scl must be a scalar.") + iaxis = normalize_axis_index(iaxis, c.ndim) + + if cnt == 0: + return c + + c = np.moveaxis(c, iaxis, 0) + k = list(k) + [0]*(cnt - len(k)) + for i in range(cnt): + n = len(c) + c *= scl + if n == 1 and np.all(c[0] == 0): + c[0] += k[i] + else: + tmp = np.empty((n + 1,) + c.shape[1:], dtype=c.dtype) + tmp[0] = c[0]*0 + tmp[1] = c[0] + if n > 1: + tmp[2] = c[1]/4 + for j in range(2, n): + tmp[j + 1] = c[j]/(2*(j + 1)) + tmp[j - 1] -= c[j]/(2*(j - 1)) + tmp[0] += k[i] - chebval(lbnd, tmp) + c = tmp + c = np.moveaxis(c, 0, iaxis) + return c + + +def chebval(x, c, tensor=True): + """ + Evaluate a Chebyshev series at points x. + + If `c` is of length `n + 1`, this function returns the value: + + .. math:: p(x) = c_0 * T_0(x) + c_1 * T_1(x) + ... + c_n * T_n(x) + + The parameter `x` is converted to an array only if it is a tuple or a + list, otherwise it is treated as a scalar. In either case, either `x` + or its elements must support multiplication and addition both with + themselves and with the elements of `c`. + + If `c` is a 1-D array, then `p(x)` will have the same shape as `x`. If + `c` is multidimensional, then the shape of the result depends on the + value of `tensor`. If `tensor` is true the shape will be c.shape[1:] + + x.shape. If `tensor` is false the shape will be c.shape[1:]. Note that + scalars have shape (,). + + Trailing zeros in the coefficients will be used in the evaluation, so + they should be avoided if efficiency is a concern. + + Parameters + ---------- + x : array_like, compatible object + If `x` is a list or tuple, it is converted to an ndarray, otherwise + it is left unchanged and treated as a scalar. In either case, `x` + or its elements must support addition and multiplication with + with themselves and with the elements of `c`. + c : array_like + Array of coefficients ordered so that the coefficients for terms of + degree n are contained in c[n]. If `c` is multidimensional the + remaining indices enumerate multiple polynomials. In the two + dimensional case the coefficients may be thought of as stored in + the columns of `c`. + tensor : boolean, optional + If True, the shape of the coefficient array is extended with ones + on the right, one for each dimension of `x`. Scalars have dimension 0 + for this action. The result is that every column of coefficients in + `c` is evaluated for every element of `x`. If False, `x` is broadcast + over the columns of `c` for the evaluation. This keyword is useful + when `c` is multidimensional. The default value is True. + + .. versionadded:: 1.7.0 + + Returns + ------- + values : ndarray, algebra_like + The shape of the return value is described above. + + See Also + -------- + chebval2d, chebgrid2d, chebval3d, chebgrid3d + + Notes + ----- + The evaluation uses Clenshaw recursion, aka synthetic division. + + Examples + -------- + + """ + c = np.array(c, ndmin=1, copy=True) + if c.dtype.char in '?bBhHiIlLqQpP': + c = c.astype(np.double) + if isinstance(x, (tuple, list)): + x = np.asarray(x) + if isinstance(x, np.ndarray) and tensor: + c = c.reshape(c.shape + (1,)*x.ndim) + + if len(c) == 1: + c0 = c[0] + c1 = 0 + elif len(c) == 2: + c0 = c[0] + c1 = c[1] + else: + x2 = 2*x + c0 = c[-2] + c1 = c[-1] + for i in range(3, len(c) + 1): + tmp = c0 + c0 = c[-i] - c1 + c1 = tmp + c1*x2 + return c0 + c1*x + + +def chebval2d(x, y, c): + """ + Evaluate a 2-D Chebyshev series at points (x, y). + + This function returns the values: + + .. math:: p(x,y) = \\sum_{i,j} c_{i,j} * T_i(x) * T_j(y) + + The parameters `x` and `y` are converted to arrays only if they are + tuples or a lists, otherwise they are treated as a scalars and they + must have the same shape after conversion. In either case, either `x` + and `y` or their elements must support multiplication and addition both + with themselves and with the elements of `c`. + + If `c` is a 1-D array a one is implicitly appended to its shape to make + it 2-D. The shape of the result will be c.shape[2:] + x.shape. + + Parameters + ---------- + x, y : array_like, compatible objects + The two dimensional series is evaluated at the points `(x, y)`, + where `x` and `y` must have the same shape. If `x` or `y` is a list + or tuple, it is first converted to an ndarray, otherwise it is left + unchanged and if it isn't an ndarray it is treated as a scalar. + c : array_like + Array of coefficients ordered so that the coefficient of the term + of multi-degree i,j is contained in ``c[i,j]``. If `c` has + dimension greater than 2 the remaining indices enumerate multiple + sets of coefficients. + + Returns + ------- + values : ndarray, compatible object + The values of the two dimensional Chebyshev series at points formed + from pairs of corresponding values from `x` and `y`. + + See Also + -------- + chebval, chebgrid2d, chebval3d, chebgrid3d + + Notes + ----- + + .. versionadded:: 1.7.0 + + """ + return pu._valnd(chebval, c, x, y) + + +def chebgrid2d(x, y, c): + """ + Evaluate a 2-D Chebyshev series on the Cartesian product of x and y. + + This function returns the values: + + .. math:: p(a,b) = \\sum_{i,j} c_{i,j} * T_i(a) * T_j(b), + + where the points `(a, b)` consist of all pairs formed by taking + `a` from `x` and `b` from `y`. The resulting points form a grid with + `x` in the first dimension and `y` in the second. + + The parameters `x` and `y` are converted to arrays only if they are + tuples or a lists, otherwise they are treated as a scalars. In either + case, either `x` and `y` or their elements must support multiplication + and addition both with themselves and with the elements of `c`. + + If `c` has fewer than two dimensions, ones are implicitly appended to + its shape to make it 2-D. The shape of the result will be c.shape[2:] + + x.shape + y.shape. + + Parameters + ---------- + x, y : array_like, compatible objects + The two dimensional series is evaluated at the points in the + Cartesian product of `x` and `y`. If `x` or `y` is a list or + tuple, it is first converted to an ndarray, otherwise it is left + unchanged and, if it isn't an ndarray, it is treated as a scalar. + c : array_like + Array of coefficients ordered so that the coefficient of the term of + multi-degree i,j is contained in `c[i,j]`. If `c` has dimension + greater than two the remaining indices enumerate multiple sets of + coefficients. + + Returns + ------- + values : ndarray, compatible object + The values of the two dimensional Chebyshev series at points in the + Cartesian product of `x` and `y`. + + See Also + -------- + chebval, chebval2d, chebval3d, chebgrid3d + + Notes + ----- + + .. versionadded:: 1.7.0 + + """ + return pu._gridnd(chebval, c, x, y) + + +def chebval3d(x, y, z, c): + """ + Evaluate a 3-D Chebyshev series at points (x, y, z). + + This function returns the values: + + .. math:: p(x,y,z) = \\sum_{i,j,k} c_{i,j,k} * T_i(x) * T_j(y) * T_k(z) + + The parameters `x`, `y`, and `z` are converted to arrays only if + they are tuples or a lists, otherwise they are treated as a scalars and + they must have the same shape after conversion. In either case, either + `x`, `y`, and `z` or their elements must support multiplication and + addition both with themselves and with the elements of `c`. + + If `c` has fewer than 3 dimensions, ones are implicitly appended to its + shape to make it 3-D. The shape of the result will be c.shape[3:] + + x.shape. + + Parameters + ---------- + x, y, z : array_like, compatible object + The three dimensional series is evaluated at the points + `(x, y, z)`, where `x`, `y`, and `z` must have the same shape. If + any of `x`, `y`, or `z` is a list or tuple, it is first converted + to an ndarray, otherwise it is left unchanged and if it isn't an + ndarray it is treated as a scalar. + c : array_like + Array of coefficients ordered so that the coefficient of the term of + multi-degree i,j,k is contained in ``c[i,j,k]``. If `c` has dimension + greater than 3 the remaining indices enumerate multiple sets of + coefficients. + + Returns + ------- + values : ndarray, compatible object + The values of the multidimensional polynomial on points formed with + triples of corresponding values from `x`, `y`, and `z`. + + See Also + -------- + chebval, chebval2d, chebgrid2d, chebgrid3d + + Notes + ----- + + .. versionadded:: 1.7.0 + + """ + return pu._valnd(chebval, c, x, y, z) + + +def chebgrid3d(x, y, z, c): + """ + Evaluate a 3-D Chebyshev series on the Cartesian product of x, y, and z. + + This function returns the values: + + .. math:: p(a,b,c) = \\sum_{i,j,k} c_{i,j,k} * T_i(a) * T_j(b) * T_k(c) + + where the points `(a, b, c)` consist of all triples formed by taking + `a` from `x`, `b` from `y`, and `c` from `z`. The resulting points form + a grid with `x` in the first dimension, `y` in the second, and `z` in + the third. + + The parameters `x`, `y`, and `z` are converted to arrays only if they + are tuples or a lists, otherwise they are treated as a scalars. In + either case, either `x`, `y`, and `z` or their elements must support + multiplication and addition both with themselves and with the elements + of `c`. + + If `c` has fewer than three dimensions, ones are implicitly appended to + its shape to make it 3-D. The shape of the result will be c.shape[3:] + + x.shape + y.shape + z.shape. + + Parameters + ---------- + x, y, z : array_like, compatible objects + The three dimensional series is evaluated at the points in the + Cartesian product of `x`, `y`, and `z`. If `x`,`y`, or `z` is a + list or tuple, it is first converted to an ndarray, otherwise it is + left unchanged and, if it isn't an ndarray, it is treated as a + scalar. + c : array_like + Array of coefficients ordered so that the coefficients for terms of + degree i,j are contained in ``c[i,j]``. If `c` has dimension + greater than two the remaining indices enumerate multiple sets of + coefficients. + + Returns + ------- + values : ndarray, compatible object + The values of the two dimensional polynomial at points in the Cartesian + product of `x` and `y`. + + See Also + -------- + chebval, chebval2d, chebgrid2d, chebval3d + + Notes + ----- + + .. versionadded:: 1.7.0 + + """ + return pu._gridnd(chebval, c, x, y, z) + + +def chebvander(x, deg): + """Pseudo-Vandermonde matrix of given degree. + + Returns the pseudo-Vandermonde matrix of degree `deg` and sample points + `x`. The pseudo-Vandermonde matrix is defined by + + .. math:: V[..., i] = T_i(x), + + where `0 <= i <= deg`. The leading indices of `V` index the elements of + `x` and the last index is the degree of the Chebyshev polynomial. + + If `c` is a 1-D array of coefficients of length `n + 1` and `V` is the + matrix ``V = chebvander(x, n)``, then ``np.dot(V, c)`` and + ``chebval(x, c)`` are the same up to roundoff. This equivalence is + useful both for least squares fitting and for the evaluation of a large + number of Chebyshev series of the same degree and sample points. + + Parameters + ---------- + x : array_like + Array of points. The dtype is converted to float64 or complex128 + depending on whether any of the elements are complex. If `x` is + scalar it is converted to a 1-D array. + deg : int + Degree of the resulting matrix. + + Returns + ------- + vander : ndarray + The pseudo Vandermonde matrix. The shape of the returned matrix is + ``x.shape + (deg + 1,)``, where The last index is the degree of the + corresponding Chebyshev polynomial. The dtype will be the same as + the converted `x`. + + """ + ideg = pu._deprecate_as_int(deg, "deg") + if ideg < 0: + raise ValueError("deg must be non-negative") + + x = np.array(x, copy=False, ndmin=1) + 0.0 + dims = (ideg + 1,) + x.shape + dtyp = x.dtype + v = np.empty(dims, dtype=dtyp) + # Use forward recursion to generate the entries. + v[0] = x*0 + 1 + if ideg > 0: + x2 = 2*x + v[1] = x + for i in range(2, ideg + 1): + v[i] = v[i-1]*x2 - v[i-2] + return np.moveaxis(v, 0, -1) + + +def chebvander2d(x, y, deg): + """Pseudo-Vandermonde matrix of given degrees. + + Returns the pseudo-Vandermonde matrix of degrees `deg` and sample + points `(x, y)`. The pseudo-Vandermonde matrix is defined by + + .. math:: V[..., (deg[1] + 1)*i + j] = T_i(x) * T_j(y), + + where `0 <= i <= deg[0]` and `0 <= j <= deg[1]`. The leading indices of + `V` index the points `(x, y)` and the last index encodes the degrees of + the Chebyshev polynomials. + + If ``V = chebvander2d(x, y, [xdeg, ydeg])``, then the columns of `V` + correspond to the elements of a 2-D coefficient array `c` of shape + (xdeg + 1, ydeg + 1) in the order + + .. math:: c_{00}, c_{01}, c_{02} ... , c_{10}, c_{11}, c_{12} ... + + and ``np.dot(V, c.flat)`` and ``chebval2d(x, y, c)`` will be the same + up to roundoff. This equivalence is useful both for least squares + fitting and for the evaluation of a large number of 2-D Chebyshev + series of the same degrees and sample points. + + Parameters + ---------- + x, y : array_like + Arrays of point coordinates, all of the same shape. The dtypes + will be converted to either float64 or complex128 depending on + whether any of the elements are complex. Scalars are converted to + 1-D arrays. + deg : list of ints + List of maximum degrees of the form [x_deg, y_deg]. + + Returns + ------- + vander2d : ndarray + The shape of the returned matrix is ``x.shape + (order,)``, where + :math:`order = (deg[0]+1)*(deg[1]+1)`. The dtype will be the same + as the converted `x` and `y`. + + See Also + -------- + chebvander, chebvander3d, chebval2d, chebval3d + + Notes + ----- + + .. versionadded:: 1.7.0 + + """ + return pu._vander_nd_flat((chebvander, chebvander), (x, y), deg) + + +def chebvander3d(x, y, z, deg): + """Pseudo-Vandermonde matrix of given degrees. + + Returns the pseudo-Vandermonde matrix of degrees `deg` and sample + points `(x, y, z)`. If `l, m, n` are the given degrees in `x, y, z`, + then The pseudo-Vandermonde matrix is defined by + + .. math:: V[..., (m+1)(n+1)i + (n+1)j + k] = T_i(x)*T_j(y)*T_k(z), + + where `0 <= i <= l`, `0 <= j <= m`, and `0 <= j <= n`. The leading + indices of `V` index the points `(x, y, z)` and the last index encodes + the degrees of the Chebyshev polynomials. + + If ``V = chebvander3d(x, y, z, [xdeg, ydeg, zdeg])``, then the columns + of `V` correspond to the elements of a 3-D coefficient array `c` of + shape (xdeg + 1, ydeg + 1, zdeg + 1) in the order + + .. math:: c_{000}, c_{001}, c_{002},... , c_{010}, c_{011}, c_{012},... + + and ``np.dot(V, c.flat)`` and ``chebval3d(x, y, z, c)`` will be the + same up to roundoff. This equivalence is useful both for least squares + fitting and for the evaluation of a large number of 3-D Chebyshev + series of the same degrees and sample points. + + Parameters + ---------- + x, y, z : array_like + Arrays of point coordinates, all of the same shape. The dtypes will + be converted to either float64 or complex128 depending on whether + any of the elements are complex. Scalars are converted to 1-D + arrays. + deg : list of ints + List of maximum degrees of the form [x_deg, y_deg, z_deg]. + + Returns + ------- + vander3d : ndarray + The shape of the returned matrix is ``x.shape + (order,)``, where + :math:`order = (deg[0]+1)*(deg[1]+1)*(deg[2]+1)`. The dtype will + be the same as the converted `x`, `y`, and `z`. + + See Also + -------- + chebvander, chebvander3d, chebval2d, chebval3d + + Notes + ----- + + .. versionadded:: 1.7.0 + + """ + return pu._vander_nd_flat((chebvander, chebvander, chebvander), (x, y, z), deg) + + +def chebfit(x, y, deg, rcond=None, full=False, w=None): + """ + Least squares fit of Chebyshev series to data. + + Return the coefficients of a Chebyshev series of degree `deg` that is the + least squares fit to the data values `y` given at points `x`. If `y` is + 1-D the returned coefficients will also be 1-D. If `y` is 2-D multiple + fits are done, one for each column of `y`, and the resulting + coefficients are stored in the corresponding columns of a 2-D return. + The fitted polynomial(s) are in the form + + .. math:: p(x) = c_0 + c_1 * T_1(x) + ... + c_n * T_n(x), + + where `n` is `deg`. + + Parameters + ---------- + x : array_like, shape (M,) + x-coordinates of the M sample points ``(x[i], y[i])``. + y : array_like, shape (M,) or (M, K) + y-coordinates of the sample points. Several data sets of sample + points sharing the same x-coordinates can be fitted at once by + passing in a 2D-array that contains one dataset per column. + deg : int or 1-D array_like + Degree(s) of the fitting polynomials. If `deg` is a single integer, + all terms up to and including the `deg`'th term are included in the + fit. For NumPy versions >= 1.11.0 a list of integers specifying the + degrees of the terms to include may be used instead. + rcond : float, optional + Relative condition number of the fit. Singular values smaller than + this relative to the largest singular value will be ignored. The + default value is len(x)*eps, where eps is the relative precision of + the float type, about 2e-16 in most cases. + full : bool, optional + Switch determining nature of return value. When it is False (the + default) just the coefficients are returned, when True diagnostic + information from the singular value decomposition is also returned. + w : array_like, shape (`M`,), optional + Weights. If not None, the contribution of each point + ``(x[i],y[i])`` to the fit is weighted by `w[i]`. Ideally the + weights are chosen so that the errors of the products ``w[i]*y[i]`` + all have the same variance. The default value is None. + + .. versionadded:: 1.5.0 + + Returns + ------- + coef : ndarray, shape (M,) or (M, K) + Chebyshev coefficients ordered from low to high. If `y` was 2-D, + the coefficients for the data in column k of `y` are in column + `k`. + + [residuals, rank, singular_values, rcond] : list + These values are only returned if `full` = True + + resid -- sum of squared residuals of the least squares fit + rank -- the numerical rank of the scaled Vandermonde matrix + sv -- singular values of the scaled Vandermonde matrix + rcond -- value of `rcond`. + + For more details, see `numpy.linalg.lstsq`. + + Warns + ----- + RankWarning + The rank of the coefficient matrix in the least-squares fit is + deficient. The warning is only raised if `full` = False. The + warnings can be turned off by + + >>> import warnings + >>> warnings.simplefilter('ignore', np.RankWarning) + + See Also + -------- + numpy.polynomial.polynomial.polyfit + numpy.polynomial.legendre.legfit + numpy.polynomial.laguerre.lagfit + numpy.polynomial.hermite.hermfit + numpy.polynomial.hermite_e.hermefit + chebval : Evaluates a Chebyshev series. + chebvander : Vandermonde matrix of Chebyshev series. + chebweight : Chebyshev weight function. + numpy.linalg.lstsq : Computes a least-squares fit from the matrix. + scipy.interpolate.UnivariateSpline : Computes spline fits. + + Notes + ----- + The solution is the coefficients of the Chebyshev series `p` that + minimizes the sum of the weighted squared errors + + .. math:: E = \\sum_j w_j^2 * |y_j - p(x_j)|^2, + + where :math:`w_j` are the weights. This problem is solved by setting up + as the (typically) overdetermined matrix equation + + .. math:: V(x) * c = w * y, + + where `V` is the weighted pseudo Vandermonde matrix of `x`, `c` are the + coefficients to be solved for, `w` are the weights, and `y` are the + observed values. This equation is then solved using the singular value + decomposition of `V`. + + If some of the singular values of `V` are so small that they are + neglected, then a `RankWarning` will be issued. This means that the + coefficient values may be poorly determined. Using a lower order fit + will usually get rid of the warning. The `rcond` parameter can also be + set to a value smaller than its default, but the resulting fit may be + spurious and have large contributions from roundoff error. + + Fits using Chebyshev series are usually better conditioned than fits + using power series, but much can depend on the distribution of the + sample points and the smoothness of the data. If the quality of the fit + is inadequate splines may be a good alternative. + + References + ---------- + .. [1] Wikipedia, "Curve fitting", + https://en.wikipedia.org/wiki/Curve_fitting + + Examples + -------- + + """ + return pu._fit(chebvander, x, y, deg, rcond, full, w) + + +def chebcompanion(c): + """Return the scaled companion matrix of c. + + The basis polynomials are scaled so that the companion matrix is + symmetric when `c` is a Chebyshev basis polynomial. This provides + better eigenvalue estimates than the unscaled case and for basis + polynomials the eigenvalues are guaranteed to be real if + `numpy.linalg.eigvalsh` is used to obtain them. + + Parameters + ---------- + c : array_like + 1-D array of Chebyshev series coefficients ordered from low to high + degree. + + Returns + ------- + mat : ndarray + Scaled companion matrix of dimensions (deg, deg). + + Notes + ----- + + .. versionadded:: 1.7.0 + + """ + # c is a trimmed copy + [c] = pu.as_series([c]) + if len(c) < 2: + raise ValueError('Series must have maximum degree of at least 1.') + if len(c) == 2: + return np.array([[-c[0]/c[1]]]) + + n = len(c) - 1 + mat = np.zeros((n, n), dtype=c.dtype) + scl = np.array([1.] + [np.sqrt(.5)]*(n-1)) + top = mat.reshape(-1)[1::n+1] + bot = mat.reshape(-1)[n::n+1] + top[0] = np.sqrt(.5) + top[1:] = 1/2 + bot[...] = top + mat[:, -1] -= (c[:-1]/c[-1])*(scl/scl[-1])*.5 + return mat + + +def chebroots(c): + """ + Compute the roots of a Chebyshev series. + + Return the roots (a.k.a. "zeros") of the polynomial + + .. math:: p(x) = \\sum_i c[i] * T_i(x). + + Parameters + ---------- + c : 1-D array_like + 1-D array of coefficients. + + Returns + ------- + out : ndarray + Array of the roots of the series. If all the roots are real, + then `out` is also real, otherwise it is complex. + + See Also + -------- + numpy.polynomial.polynomial.polyroots + numpy.polynomial.legendre.legroots + numpy.polynomial.laguerre.lagroots + numpy.polynomial.hermite.hermroots + numpy.polynomial.hermite_e.hermeroots + + Notes + ----- + The root estimates are obtained as the eigenvalues of the companion + matrix, Roots far from the origin of the complex plane may have large + errors due to the numerical instability of the series for such + values. Roots with multiplicity greater than 1 will also show larger + errors as the value of the series near such points is relatively + insensitive to errors in the roots. Isolated roots near the origin can + be improved by a few iterations of Newton's method. + + The Chebyshev series basis polynomials aren't powers of `x` so the + results of this function may seem unintuitive. + + Examples + -------- + >>> import numpy.polynomial.chebyshev as cheb + >>> cheb.chebroots((-1, 1,-1, 1)) # T3 - T2 + T1 - T0 has real roots + array([ -5.00000000e-01, 2.60860684e-17, 1.00000000e+00]) # may vary + + """ + # c is a trimmed copy + [c] = pu.as_series([c]) + if len(c) < 2: + return np.array([], dtype=c.dtype) + if len(c) == 2: + return np.array([-c[0]/c[1]]) + + # rotated companion matrix reduces error + m = chebcompanion(c)[::-1,::-1] + r = la.eigvals(m) + r.sort() + return r + + +def chebinterpolate(func, deg, args=()): + """Interpolate a function at the Chebyshev points of the first kind. + + Returns the Chebyshev series that interpolates `func` at the Chebyshev + points of the first kind in the interval [-1, 1]. The interpolating + series tends to a minmax approximation to `func` with increasing `deg` + if the function is continuous in the interval. + + .. versionadded:: 1.14.0 + + Parameters + ---------- + func : function + The function to be approximated. It must be a function of a single + variable of the form ``f(x, a, b, c...)``, where ``a, b, c...`` are + extra arguments passed in the `args` parameter. + deg : int + Degree of the interpolating polynomial + args : tuple, optional + Extra arguments to be used in the function call. Default is no extra + arguments. + + Returns + ------- + coef : ndarray, shape (deg + 1,) + Chebyshev coefficients of the interpolating series ordered from low to + high. + + Examples + -------- + >>> import numpy.polynomial.chebyshev as C + >>> C.chebfromfunction(lambda x: np.tanh(x) + 0.5, 8) + array([ 5.00000000e-01, 8.11675684e-01, -9.86864911e-17, + -5.42457905e-02, -2.71387850e-16, 4.51658839e-03, + 2.46716228e-17, -3.79694221e-04, -3.26899002e-16]) + + Notes + ----- + + The Chebyshev polynomials used in the interpolation are orthogonal when + sampled at the Chebyshev points of the first kind. If it is desired to + constrain some of the coefficients they can simply be set to the desired + value after the interpolation, no new interpolation or fit is needed. This + is especially useful if it is known apriori that some of coefficients are + zero. For instance, if the function is even then the coefficients of the + terms of odd degree in the result can be set to zero. + + """ + deg = np.asarray(deg) + + # check arguments. + if deg.ndim > 0 or deg.dtype.kind not in 'iu' or deg.size == 0: + raise TypeError("deg must be an int") + if deg < 0: + raise ValueError("expected deg >= 0") + + order = deg + 1 + xcheb = chebpts1(order) + yfunc = func(xcheb, *args) + m = chebvander(xcheb, deg) + c = np.dot(m.T, yfunc) + c[0] /= order + c[1:] /= 0.5*order + + return c + + +def chebgauss(deg): + """ + Gauss-Chebyshev quadrature. + + Computes the sample points and weights for Gauss-Chebyshev quadrature. + These sample points and weights will correctly integrate polynomials of + degree :math:`2*deg - 1` or less over the interval :math:`[-1, 1]` with + the weight function :math:`f(x) = 1/\\sqrt{1 - x^2}`. + + Parameters + ---------- + deg : int + Number of sample points and weights. It must be >= 1. + + Returns + ------- + x : ndarray + 1-D ndarray containing the sample points. + y : ndarray + 1-D ndarray containing the weights. + + Notes + ----- + + .. versionadded:: 1.7.0 + + The results have only been tested up to degree 100, higher degrees may + be problematic. For Gauss-Chebyshev there are closed form solutions for + the sample points and weights. If n = `deg`, then + + .. math:: x_i = \\cos(\\pi (2 i - 1) / (2 n)) + + .. math:: w_i = \\pi / n + + """ + ideg = pu._deprecate_as_int(deg, "deg") + if ideg <= 0: + raise ValueError("deg must be a positive integer") + + x = np.cos(np.pi * np.arange(1, 2*ideg, 2) / (2.0*ideg)) + w = np.ones(ideg)*(np.pi/ideg) + + return x, w + + +def chebweight(x): + """ + The weight function of the Chebyshev polynomials. + + The weight function is :math:`1/\\sqrt{1 - x^2}` and the interval of + integration is :math:`[-1, 1]`. The Chebyshev polynomials are + orthogonal, but not normalized, with respect to this weight function. + + Parameters + ---------- + x : array_like + Values at which the weight function will be computed. + + Returns + ------- + w : ndarray + The weight function at `x`. + + Notes + ----- + + .. versionadded:: 1.7.0 + + """ + w = 1./(np.sqrt(1. + x) * np.sqrt(1. - x)) + return w + + +def chebpts1(npts): + """ + Chebyshev points of the first kind. + + The Chebyshev points of the first kind are the points ``cos(x)``, + where ``x = [pi*(k + .5)/npts for k in range(npts)]``. + + Parameters + ---------- + npts : int + Number of sample points desired. + + Returns + ------- + pts : ndarray + The Chebyshev points of the first kind. + + See Also + -------- + chebpts2 + + Notes + ----- + + .. versionadded:: 1.5.0 + + """ + _npts = int(npts) + if _npts != npts: + raise ValueError("npts must be integer") + if _npts < 1: + raise ValueError("npts must be >= 1") + + x = np.linspace(-np.pi, 0, _npts, endpoint=False) + np.pi/(2*_npts) + return np.cos(x) + + +def chebpts2(npts): + """ + Chebyshev points of the second kind. + + The Chebyshev points of the second kind are the points ``cos(x)``, + where ``x = [pi*k/(npts - 1) for k in range(npts)]``. + + Parameters + ---------- + npts : int + Number of sample points desired. + + Returns + ------- + pts : ndarray + The Chebyshev points of the second kind. + + Notes + ----- + + .. versionadded:: 1.5.0 + + """ + _npts = int(npts) + if _npts != npts: + raise ValueError("npts must be integer") + if _npts < 2: + raise ValueError("npts must be >= 2") + + x = np.linspace(-np.pi, 0, _npts) + return np.cos(x) + + +# +# Chebyshev series class +# + +class Chebyshev(ABCPolyBase): + """A Chebyshev series class. + + The Chebyshev class provides the standard Python numerical methods + '+', '-', '*', '//', '%', 'divmod', '**', and '()' as well as the + methods listed below. + + Parameters + ---------- + coef : array_like + Chebyshev coefficients in order of increasing degree, i.e., + ``(1, 2, 3)`` gives ``1*T_0(x) + 2*T_1(x) + 3*T_2(x)``. + domain : (2,) array_like, optional + Domain to use. The interval ``[domain[0], domain[1]]`` is mapped + to the interval ``[window[0], window[1]]`` by shifting and scaling. + The default value is [-1, 1]. + window : (2,) array_like, optional + Window, see `domain` for its use. The default value is [-1, 1]. + + .. versionadded:: 1.6.0 + + """ + # Virtual Functions + _add = staticmethod(chebadd) + _sub = staticmethod(chebsub) + _mul = staticmethod(chebmul) + _div = staticmethod(chebdiv) + _pow = staticmethod(chebpow) + _val = staticmethod(chebval) + _int = staticmethod(chebint) + _der = staticmethod(chebder) + _fit = staticmethod(chebfit) + _line = staticmethod(chebline) + _roots = staticmethod(chebroots) + _fromroots = staticmethod(chebfromroots) + + @classmethod + def interpolate(cls, func, deg, domain=None, args=()): + """Interpolate a function at the Chebyshev points of the first kind. + + Returns the series that interpolates `func` at the Chebyshev points of + the first kind scaled and shifted to the `domain`. The resulting series + tends to a minmax approximation of `func` when the function is + continuous in the domain. + + .. versionadded:: 1.14.0 + + Parameters + ---------- + func : function + The function to be interpolated. It must be a function of a single + variable of the form ``f(x, a, b, c...)``, where ``a, b, c...`` are + extra arguments passed in the `args` parameter. + deg : int + Degree of the interpolating polynomial. + domain : {None, [beg, end]}, optional + Domain over which `func` is interpolated. The default is None, in + which case the domain is [-1, 1]. + args : tuple, optional + Extra arguments to be used in the function call. Default is no + extra arguments. + + Returns + ------- + polynomial : Chebyshev instance + Interpolating Chebyshev instance. + + Notes + ----- + See `numpy.polynomial.chebfromfunction` for more details. + + """ + if domain is None: + domain = cls.domain + xfunc = lambda x: func(pu.mapdomain(x, cls.window, domain), *args) + coef = chebinterpolate(xfunc, deg) + return cls(coef, domain=domain) + + # Virtual properties + domain = np.array(chebdomain) + window = np.array(chebdomain) + basis_name = 'T' diff --git a/venv/Lib/site-packages/numpy/polynomial/hermite.py b/venv/Lib/site-packages/numpy/polynomial/hermite.py new file mode 100644 index 0000000..c679c52 --- /dev/null +++ b/venv/Lib/site-packages/numpy/polynomial/hermite.py @@ -0,0 +1,1696 @@ +""" +============================================================== +Hermite Series, "Physicists" (:mod:`numpy.polynomial.hermite`) +============================================================== + +This module provides a number of objects (mostly functions) useful for +dealing with Hermite series, including a `Hermite` class that +encapsulates the usual arithmetic operations. (General information +on how this module represents and works with such polynomials is in the +docstring for its "parent" sub-package, `numpy.polynomial`). + +Classes +------- +.. autosummary:: + :toctree: generated/ + + Hermite + +Constants +--------- +.. autosummary:: + :toctree: generated/ + + hermdomain + hermzero + hermone + hermx + +Arithmetic +---------- +.. autosummary:: + :toctree: generated/ + + hermadd + hermsub + hermmulx + hermmul + hermdiv + hermpow + hermval + hermval2d + hermval3d + hermgrid2d + hermgrid3d + +Calculus +-------- +.. autosummary:: + :toctree: generated/ + + hermder + hermint + +Misc Functions +-------------- +.. autosummary:: + :toctree: generated/ + + hermfromroots + hermroots + hermvander + hermvander2d + hermvander3d + hermgauss + hermweight + hermcompanion + hermfit + hermtrim + hermline + herm2poly + poly2herm + +See also +-------- +`numpy.polynomial` + +""" +import numpy as np +import numpy.linalg as la +from numpy.core.multiarray import normalize_axis_index + +from . import polyutils as pu +from ._polybase import ABCPolyBase + +__all__ = [ + 'hermzero', 'hermone', 'hermx', 'hermdomain', 'hermline', 'hermadd', + 'hermsub', 'hermmulx', 'hermmul', 'hermdiv', 'hermpow', 'hermval', + 'hermder', 'hermint', 'herm2poly', 'poly2herm', 'hermfromroots', + 'hermvander', 'hermfit', 'hermtrim', 'hermroots', 'Hermite', + 'hermval2d', 'hermval3d', 'hermgrid2d', 'hermgrid3d', 'hermvander2d', + 'hermvander3d', 'hermcompanion', 'hermgauss', 'hermweight'] + +hermtrim = pu.trimcoef + + +def poly2herm(pol): + """ + poly2herm(pol) + + Convert a polynomial to a Hermite series. + + Convert an array representing the coefficients of a polynomial (relative + to the "standard" basis) ordered from lowest degree to highest, to an + array of the coefficients of the equivalent Hermite series, ordered + from lowest to highest degree. + + Parameters + ---------- + pol : array_like + 1-D array containing the polynomial coefficients + + Returns + ------- + c : ndarray + 1-D array containing the coefficients of the equivalent Hermite + series. + + See Also + -------- + herm2poly + + Notes + ----- + The easy way to do conversions between polynomial basis sets + is to use the convert method of a class instance. + + Examples + -------- + >>> from numpy.polynomial.hermite import poly2herm + >>> poly2herm(np.arange(4)) + array([1. , 2.75 , 0.5 , 0.375]) + + """ + [pol] = pu.as_series([pol]) + deg = len(pol) - 1 + res = 0 + for i in range(deg, -1, -1): + res = hermadd(hermmulx(res), pol[i]) + return res + + +def herm2poly(c): + """ + Convert a Hermite series to a polynomial. + + Convert an array representing the coefficients of a Hermite series, + ordered from lowest degree to highest, to an array of the coefficients + of the equivalent polynomial (relative to the "standard" basis) ordered + from lowest to highest degree. + + Parameters + ---------- + c : array_like + 1-D array containing the Hermite series coefficients, ordered + from lowest order term to highest. + + Returns + ------- + pol : ndarray + 1-D array containing the coefficients of the equivalent polynomial + (relative to the "standard" basis) ordered from lowest order term + to highest. + + See Also + -------- + poly2herm + + Notes + ----- + The easy way to do conversions between polynomial basis sets + is to use the convert method of a class instance. + + Examples + -------- + >>> from numpy.polynomial.hermite import herm2poly + >>> herm2poly([ 1. , 2.75 , 0.5 , 0.375]) + array([0., 1., 2., 3.]) + + """ + from .polynomial import polyadd, polysub, polymulx + + [c] = pu.as_series([c]) + n = len(c) + if n == 1: + return c + if n == 2: + c[1] *= 2 + return c + else: + c0 = c[-2] + c1 = c[-1] + # i is the current degree of c1 + for i in range(n - 1, 1, -1): + tmp = c0 + c0 = polysub(c[i - 2], c1*(2*(i - 1))) + c1 = polyadd(tmp, polymulx(c1)*2) + return polyadd(c0, polymulx(c1)*2) + +# +# These are constant arrays are of integer type so as to be compatible +# with the widest range of other types, such as Decimal. +# + +# Hermite +hermdomain = np.array([-1, 1]) + +# Hermite coefficients representing zero. +hermzero = np.array([0]) + +# Hermite coefficients representing one. +hermone = np.array([1]) + +# Hermite coefficients representing the identity x. +hermx = np.array([0, 1/2]) + + +def hermline(off, scl): + """ + Hermite series whose graph is a straight line. + + + + Parameters + ---------- + off, scl : scalars + The specified line is given by ``off + scl*x``. + + Returns + ------- + y : ndarray + This module's representation of the Hermite series for + ``off + scl*x``. + + See Also + -------- + numpy.polynomial.polynomial.polyline + numpy.polynomial.chebyshev.chebline + numpy.polynomial.legendre.legline + numpy.polynomial.laguerre.lagline + numpy.polynomial.hermite_e.hermeline + + Examples + -------- + >>> from numpy.polynomial.hermite import hermline, hermval + >>> hermval(0,hermline(3, 2)) + 3.0 + >>> hermval(1,hermline(3, 2)) + 5.0 + + """ + if scl != 0: + return np.array([off, scl/2]) + else: + return np.array([off]) + + +def hermfromroots(roots): + """ + Generate a Hermite series with given roots. + + The function returns the coefficients of the polynomial + + .. math:: p(x) = (x - r_0) * (x - r_1) * ... * (x - r_n), + + in Hermite form, where the `r_n` are the roots specified in `roots`. + If a zero has multiplicity n, then it must appear in `roots` n times. + For instance, if 2 is a root of multiplicity three and 3 is a root of + multiplicity 2, then `roots` looks something like [2, 2, 2, 3, 3]. The + roots can appear in any order. + + If the returned coefficients are `c`, then + + .. math:: p(x) = c_0 + c_1 * H_1(x) + ... + c_n * H_n(x) + + The coefficient of the last term is not generally 1 for monic + polynomials in Hermite form. + + Parameters + ---------- + roots : array_like + Sequence containing the roots. + + Returns + ------- + out : ndarray + 1-D array of coefficients. If all roots are real then `out` is a + real array, if some of the roots are complex, then `out` is complex + even if all the coefficients in the result are real (see Examples + below). + + See Also + -------- + numpy.polynomial.polynomial.polyfromroots + numpy.polynomial.legendre.legfromroots + numpy.polynomial.laguerre.lagfromroots + numpy.polynomial.chebyshev.chebfromroots + numpy.polynomial.hermite_e.hermefromroots + + Examples + -------- + >>> from numpy.polynomial.hermite import hermfromroots, hermval + >>> coef = hermfromroots((-1, 0, 1)) + >>> hermval((-1, 0, 1), coef) + array([0., 0., 0.]) + >>> coef = hermfromroots((-1j, 1j)) + >>> hermval((-1j, 1j), coef) + array([0.+0.j, 0.+0.j]) + + """ + return pu._fromroots(hermline, hermmul, roots) + + +def hermadd(c1, c2): + """ + Add one Hermite series to another. + + Returns the sum of two Hermite series `c1` + `c2`. The arguments + are sequences of coefficients ordered from lowest order term to + highest, i.e., [1,2,3] represents the series ``P_0 + 2*P_1 + 3*P_2``. + + Parameters + ---------- + c1, c2 : array_like + 1-D arrays of Hermite series coefficients ordered from low to + high. + + Returns + ------- + out : ndarray + Array representing the Hermite series of their sum. + + See Also + -------- + hermsub, hermmulx, hermmul, hermdiv, hermpow + + Notes + ----- + Unlike multiplication, division, etc., the sum of two Hermite series + is a Hermite series (without having to "reproject" the result onto + the basis set) so addition, just like that of "standard" polynomials, + is simply "component-wise." + + Examples + -------- + >>> from numpy.polynomial.hermite import hermadd + >>> hermadd([1, 2, 3], [1, 2, 3, 4]) + array([2., 4., 6., 4.]) + + """ + return pu._add(c1, c2) + + +def hermsub(c1, c2): + """ + Subtract one Hermite series from another. + + Returns the difference of two Hermite series `c1` - `c2`. The + sequences of coefficients are from lowest order term to highest, i.e., + [1,2,3] represents the series ``P_0 + 2*P_1 + 3*P_2``. + + Parameters + ---------- + c1, c2 : array_like + 1-D arrays of Hermite series coefficients ordered from low to + high. + + Returns + ------- + out : ndarray + Of Hermite series coefficients representing their difference. + + See Also + -------- + hermadd, hermmulx, hermmul, hermdiv, hermpow + + Notes + ----- + Unlike multiplication, division, etc., the difference of two Hermite + series is a Hermite series (without having to "reproject" the result + onto the basis set) so subtraction, just like that of "standard" + polynomials, is simply "component-wise." + + Examples + -------- + >>> from numpy.polynomial.hermite import hermsub + >>> hermsub([1, 2, 3, 4], [1, 2, 3]) + array([0., 0., 0., 4.]) + + """ + return pu._sub(c1, c2) + + +def hermmulx(c): + """Multiply a Hermite series by x. + + Multiply the Hermite series `c` by x, where x is the independent + variable. + + + Parameters + ---------- + c : array_like + 1-D array of Hermite series coefficients ordered from low to + high. + + Returns + ------- + out : ndarray + Array representing the result of the multiplication. + + See Also + -------- + hermadd, hermsub, hermmul, hermdiv, hermpow + + Notes + ----- + The multiplication uses the recursion relationship for Hermite + polynomials in the form + + .. math:: + + xP_i(x) = (P_{i + 1}(x)/2 + i*P_{i - 1}(x)) + + Examples + -------- + >>> from numpy.polynomial.hermite import hermmulx + >>> hermmulx([1, 2, 3]) + array([2. , 6.5, 1. , 1.5]) + + """ + # c is a trimmed copy + [c] = pu.as_series([c]) + # The zero series needs special treatment + if len(c) == 1 and c[0] == 0: + return c + + prd = np.empty(len(c) + 1, dtype=c.dtype) + prd[0] = c[0]*0 + prd[1] = c[0]/2 + for i in range(1, len(c)): + prd[i + 1] = c[i]/2 + prd[i - 1] += c[i]*i + return prd + + +def hermmul(c1, c2): + """ + Multiply one Hermite series by another. + + Returns the product of two Hermite series `c1` * `c2`. The arguments + are sequences of coefficients, from lowest order "term" to highest, + e.g., [1,2,3] represents the series ``P_0 + 2*P_1 + 3*P_2``. + + Parameters + ---------- + c1, c2 : array_like + 1-D arrays of Hermite series coefficients ordered from low to + high. + + Returns + ------- + out : ndarray + Of Hermite series coefficients representing their product. + + See Also + -------- + hermadd, hermsub, hermmulx, hermdiv, hermpow + + Notes + ----- + In general, the (polynomial) product of two C-series results in terms + that are not in the Hermite polynomial basis set. Thus, to express + the product as a Hermite series, it is necessary to "reproject" the + product onto said basis set, which may produce "unintuitive" (but + correct) results; see Examples section below. + + Examples + -------- + >>> from numpy.polynomial.hermite import hermmul + >>> hermmul([1, 2, 3], [0, 1, 2]) + array([52., 29., 52., 7., 6.]) + + """ + # s1, s2 are trimmed copies + [c1, c2] = pu.as_series([c1, c2]) + + if len(c1) > len(c2): + c = c2 + xs = c1 + else: + c = c1 + xs = c2 + + if len(c) == 1: + c0 = c[0]*xs + c1 = 0 + elif len(c) == 2: + c0 = c[0]*xs + c1 = c[1]*xs + else: + nd = len(c) + c0 = c[-2]*xs + c1 = c[-1]*xs + for i in range(3, len(c) + 1): + tmp = c0 + nd = nd - 1 + c0 = hermsub(c[-i]*xs, c1*(2*(nd - 1))) + c1 = hermadd(tmp, hermmulx(c1)*2) + return hermadd(c0, hermmulx(c1)*2) + + +def hermdiv(c1, c2): + """ + Divide one Hermite series by another. + + Returns the quotient-with-remainder of two Hermite series + `c1` / `c2`. The arguments are sequences of coefficients from lowest + order "term" to highest, e.g., [1,2,3] represents the series + ``P_0 + 2*P_1 + 3*P_2``. + + Parameters + ---------- + c1, c2 : array_like + 1-D arrays of Hermite series coefficients ordered from low to + high. + + Returns + ------- + [quo, rem] : ndarrays + Of Hermite series coefficients representing the quotient and + remainder. + + See Also + -------- + hermadd, hermsub, hermmulx, hermmul, hermpow + + Notes + ----- + In general, the (polynomial) division of one Hermite series by another + results in quotient and remainder terms that are not in the Hermite + polynomial basis set. Thus, to express these results as a Hermite + series, it is necessary to "reproject" the results onto the Hermite + basis set, which may produce "unintuitive" (but correct) results; see + Examples section below. + + Examples + -------- + >>> from numpy.polynomial.hermite import hermdiv + >>> hermdiv([ 52., 29., 52., 7., 6.], [0, 1, 2]) + (array([1., 2., 3.]), array([0.])) + >>> hermdiv([ 54., 31., 52., 7., 6.], [0, 1, 2]) + (array([1., 2., 3.]), array([2., 2.])) + >>> hermdiv([ 53., 30., 52., 7., 6.], [0, 1, 2]) + (array([1., 2., 3.]), array([1., 1.])) + + """ + return pu._div(hermmul, c1, c2) + + +def hermpow(c, pow, maxpower=16): + """Raise a Hermite series to a power. + + Returns the Hermite series `c` raised to the power `pow`. The + argument `c` is a sequence of coefficients ordered from low to high. + i.e., [1,2,3] is the series ``P_0 + 2*P_1 + 3*P_2.`` + + Parameters + ---------- + c : array_like + 1-D array of Hermite series coefficients ordered from low to + high. + pow : integer + Power to which the series will be raised + maxpower : integer, optional + Maximum power allowed. This is mainly to limit growth of the series + to unmanageable size. Default is 16 + + Returns + ------- + coef : ndarray + Hermite series of power. + + See Also + -------- + hermadd, hermsub, hermmulx, hermmul, hermdiv + + Examples + -------- + >>> from numpy.polynomial.hermite import hermpow + >>> hermpow([1, 2, 3], 2) + array([81., 52., 82., 12., 9.]) + + """ + return pu._pow(hermmul, c, pow, maxpower) + + +def hermder(c, m=1, scl=1, axis=0): + """ + Differentiate a Hermite series. + + Returns the Hermite series coefficients `c` differentiated `m` times + along `axis`. At each iteration the result is multiplied by `scl` (the + scaling factor is for use in a linear change of variable). The argument + `c` is an array of coefficients from low to high degree along each + axis, e.g., [1,2,3] represents the series ``1*H_0 + 2*H_1 + 3*H_2`` + while [[1,2],[1,2]] represents ``1*H_0(x)*H_0(y) + 1*H_1(x)*H_0(y) + + 2*H_0(x)*H_1(y) + 2*H_1(x)*H_1(y)`` if axis=0 is ``x`` and axis=1 is + ``y``. + + Parameters + ---------- + c : array_like + Array of Hermite series coefficients. If `c` is multidimensional the + different axis correspond to different variables with the degree in + each axis given by the corresponding index. + m : int, optional + Number of derivatives taken, must be non-negative. (Default: 1) + scl : scalar, optional + Each differentiation is multiplied by `scl`. The end result is + multiplication by ``scl**m``. This is for use in a linear change of + variable. (Default: 1) + axis : int, optional + Axis over which the derivative is taken. (Default: 0). + + .. versionadded:: 1.7.0 + + Returns + ------- + der : ndarray + Hermite series of the derivative. + + See Also + -------- + hermint + + Notes + ----- + In general, the result of differentiating a Hermite series does not + resemble the same operation on a power series. Thus the result of this + function may be "unintuitive," albeit correct; see Examples section + below. + + Examples + -------- + >>> from numpy.polynomial.hermite import hermder + >>> hermder([ 1. , 0.5, 0.5, 0.5]) + array([1., 2., 3.]) + >>> hermder([-0.5, 1./2., 1./8., 1./12., 1./16.], m=2) + array([1., 2., 3.]) + + """ + c = np.array(c, ndmin=1, copy=True) + if c.dtype.char in '?bBhHiIlLqQpP': + c = c.astype(np.double) + cnt = pu._deprecate_as_int(m, "the order of derivation") + iaxis = pu._deprecate_as_int(axis, "the axis") + if cnt < 0: + raise ValueError("The order of derivation must be non-negative") + iaxis = normalize_axis_index(iaxis, c.ndim) + + if cnt == 0: + return c + + c = np.moveaxis(c, iaxis, 0) + n = len(c) + if cnt >= n: + c = c[:1]*0 + else: + for i in range(cnt): + n = n - 1 + c *= scl + der = np.empty((n,) + c.shape[1:], dtype=c.dtype) + for j in range(n, 0, -1): + der[j - 1] = (2*j)*c[j] + c = der + c = np.moveaxis(c, 0, iaxis) + return c + + +def hermint(c, m=1, k=[], lbnd=0, scl=1, axis=0): + """ + Integrate a Hermite series. + + Returns the Hermite series coefficients `c` integrated `m` times from + `lbnd` along `axis`. At each iteration the resulting series is + **multiplied** by `scl` and an integration constant, `k`, is added. + The scaling factor is for use in a linear change of variable. ("Buyer + beware": note that, depending on what one is doing, one may want `scl` + to be the reciprocal of what one might expect; for more information, + see the Notes section below.) The argument `c` is an array of + coefficients from low to high degree along each axis, e.g., [1,2,3] + represents the series ``H_0 + 2*H_1 + 3*H_2`` while [[1,2],[1,2]] + represents ``1*H_0(x)*H_0(y) + 1*H_1(x)*H_0(y) + 2*H_0(x)*H_1(y) + + 2*H_1(x)*H_1(y)`` if axis=0 is ``x`` and axis=1 is ``y``. + + Parameters + ---------- + c : array_like + Array of Hermite series coefficients. If c is multidimensional the + different axis correspond to different variables with the degree in + each axis given by the corresponding index. + m : int, optional + Order of integration, must be positive. (Default: 1) + k : {[], list, scalar}, optional + Integration constant(s). The value of the first integral at + ``lbnd`` is the first value in the list, the value of the second + integral at ``lbnd`` is the second value, etc. If ``k == []`` (the + default), all constants are set to zero. If ``m == 1``, a single + scalar can be given instead of a list. + lbnd : scalar, optional + The lower bound of the integral. (Default: 0) + scl : scalar, optional + Following each integration the result is *multiplied* by `scl` + before the integration constant is added. (Default: 1) + axis : int, optional + Axis over which the integral is taken. (Default: 0). + + .. versionadded:: 1.7.0 + + Returns + ------- + S : ndarray + Hermite series coefficients of the integral. + + Raises + ------ + ValueError + If ``m < 0``, ``len(k) > m``, ``np.ndim(lbnd) != 0``, or + ``np.ndim(scl) != 0``. + + See Also + -------- + hermder + + Notes + ----- + Note that the result of each integration is *multiplied* by `scl`. + Why is this important to note? Say one is making a linear change of + variable :math:`u = ax + b` in an integral relative to `x`. Then + :math:`dx = du/a`, so one will need to set `scl` equal to + :math:`1/a` - perhaps not what one would have first thought. + + Also note that, in general, the result of integrating a C-series needs + to be "reprojected" onto the C-series basis set. Thus, typically, + the result of this function is "unintuitive," albeit correct; see + Examples section below. + + Examples + -------- + >>> from numpy.polynomial.hermite import hermint + >>> hermint([1,2,3]) # integrate once, value 0 at 0. + array([1. , 0.5, 0.5, 0.5]) + >>> hermint([1,2,3], m=2) # integrate twice, value & deriv 0 at 0 + array([-0.5 , 0.5 , 0.125 , 0.08333333, 0.0625 ]) # may vary + >>> hermint([1,2,3], k=1) # integrate once, value 1 at 0. + array([2. , 0.5, 0.5, 0.5]) + >>> hermint([1,2,3], lbnd=-1) # integrate once, value 0 at -1 + array([-2. , 0.5, 0.5, 0.5]) + >>> hermint([1,2,3], m=2, k=[1,2], lbnd=-1) + array([ 1.66666667, -0.5 , 0.125 , 0.08333333, 0.0625 ]) # may vary + + """ + c = np.array(c, ndmin=1, copy=True) + if c.dtype.char in '?bBhHiIlLqQpP': + c = c.astype(np.double) + if not np.iterable(k): + k = [k] + cnt = pu._deprecate_as_int(m, "the order of integration") + iaxis = pu._deprecate_as_int(axis, "the axis") + if cnt < 0: + raise ValueError("The order of integration must be non-negative") + if len(k) > cnt: + raise ValueError("Too many integration constants") + if np.ndim(lbnd) != 0: + raise ValueError("lbnd must be a scalar.") + if np.ndim(scl) != 0: + raise ValueError("scl must be a scalar.") + iaxis = normalize_axis_index(iaxis, c.ndim) + + if cnt == 0: + return c + + c = np.moveaxis(c, iaxis, 0) + k = list(k) + [0]*(cnt - len(k)) + for i in range(cnt): + n = len(c) + c *= scl + if n == 1 and np.all(c[0] == 0): + c[0] += k[i] + else: + tmp = np.empty((n + 1,) + c.shape[1:], dtype=c.dtype) + tmp[0] = c[0]*0 + tmp[1] = c[0]/2 + for j in range(1, n): + tmp[j + 1] = c[j]/(2*(j + 1)) + tmp[0] += k[i] - hermval(lbnd, tmp) + c = tmp + c = np.moveaxis(c, 0, iaxis) + return c + + +def hermval(x, c, tensor=True): + """ + Evaluate an Hermite series at points x. + + If `c` is of length `n + 1`, this function returns the value: + + .. math:: p(x) = c_0 * H_0(x) + c_1 * H_1(x) + ... + c_n * H_n(x) + + The parameter `x` is converted to an array only if it is a tuple or a + list, otherwise it is treated as a scalar. In either case, either `x` + or its elements must support multiplication and addition both with + themselves and with the elements of `c`. + + If `c` is a 1-D array, then `p(x)` will have the same shape as `x`. If + `c` is multidimensional, then the shape of the result depends on the + value of `tensor`. If `tensor` is true the shape will be c.shape[1:] + + x.shape. If `tensor` is false the shape will be c.shape[1:]. Note that + scalars have shape (,). + + Trailing zeros in the coefficients will be used in the evaluation, so + they should be avoided if efficiency is a concern. + + Parameters + ---------- + x : array_like, compatible object + If `x` is a list or tuple, it is converted to an ndarray, otherwise + it is left unchanged and treated as a scalar. In either case, `x` + or its elements must support addition and multiplication with + with themselves and with the elements of `c`. + c : array_like + Array of coefficients ordered so that the coefficients for terms of + degree n are contained in c[n]. If `c` is multidimensional the + remaining indices enumerate multiple polynomials. In the two + dimensional case the coefficients may be thought of as stored in + the columns of `c`. + tensor : boolean, optional + If True, the shape of the coefficient array is extended with ones + on the right, one for each dimension of `x`. Scalars have dimension 0 + for this action. The result is that every column of coefficients in + `c` is evaluated for every element of `x`. If False, `x` is broadcast + over the columns of `c` for the evaluation. This keyword is useful + when `c` is multidimensional. The default value is True. + + .. versionadded:: 1.7.0 + + Returns + ------- + values : ndarray, algebra_like + The shape of the return value is described above. + + See Also + -------- + hermval2d, hermgrid2d, hermval3d, hermgrid3d + + Notes + ----- + The evaluation uses Clenshaw recursion, aka synthetic division. + + Examples + -------- + >>> from numpy.polynomial.hermite import hermval + >>> coef = [1,2,3] + >>> hermval(1, coef) + 11.0 + >>> hermval([[1,2],[3,4]], coef) + array([[ 11., 51.], + [115., 203.]]) + + """ + c = np.array(c, ndmin=1, copy=False) + if c.dtype.char in '?bBhHiIlLqQpP': + c = c.astype(np.double) + if isinstance(x, (tuple, list)): + x = np.asarray(x) + if isinstance(x, np.ndarray) and tensor: + c = c.reshape(c.shape + (1,)*x.ndim) + + x2 = x*2 + if len(c) == 1: + c0 = c[0] + c1 = 0 + elif len(c) == 2: + c0 = c[0] + c1 = c[1] + else: + nd = len(c) + c0 = c[-2] + c1 = c[-1] + for i in range(3, len(c) + 1): + tmp = c0 + nd = nd - 1 + c0 = c[-i] - c1*(2*(nd - 1)) + c1 = tmp + c1*x2 + return c0 + c1*x2 + + +def hermval2d(x, y, c): + """ + Evaluate a 2-D Hermite series at points (x, y). + + This function returns the values: + + .. math:: p(x,y) = \\sum_{i,j} c_{i,j} * H_i(x) * H_j(y) + + The parameters `x` and `y` are converted to arrays only if they are + tuples or a lists, otherwise they are treated as a scalars and they + must have the same shape after conversion. In either case, either `x` + and `y` or their elements must support multiplication and addition both + with themselves and with the elements of `c`. + + If `c` is a 1-D array a one is implicitly appended to its shape to make + it 2-D. The shape of the result will be c.shape[2:] + x.shape. + + Parameters + ---------- + x, y : array_like, compatible objects + The two dimensional series is evaluated at the points `(x, y)`, + where `x` and `y` must have the same shape. If `x` or `y` is a list + or tuple, it is first converted to an ndarray, otherwise it is left + unchanged and if it isn't an ndarray it is treated as a scalar. + c : array_like + Array of coefficients ordered so that the coefficient of the term + of multi-degree i,j is contained in ``c[i,j]``. If `c` has + dimension greater than two the remaining indices enumerate multiple + sets of coefficients. + + Returns + ------- + values : ndarray, compatible object + The values of the two dimensional polynomial at points formed with + pairs of corresponding values from `x` and `y`. + + See Also + -------- + hermval, hermgrid2d, hermval3d, hermgrid3d + + Notes + ----- + + .. versionadded:: 1.7.0 + + """ + return pu._valnd(hermval, c, x, y) + + +def hermgrid2d(x, y, c): + """ + Evaluate a 2-D Hermite series on the Cartesian product of x and y. + + This function returns the values: + + .. math:: p(a,b) = \\sum_{i,j} c_{i,j} * H_i(a) * H_j(b) + + where the points `(a, b)` consist of all pairs formed by taking + `a` from `x` and `b` from `y`. The resulting points form a grid with + `x` in the first dimension and `y` in the second. + + The parameters `x` and `y` are converted to arrays only if they are + tuples or a lists, otherwise they are treated as a scalars. In either + case, either `x` and `y` or their elements must support multiplication + and addition both with themselves and with the elements of `c`. + + If `c` has fewer than two dimensions, ones are implicitly appended to + its shape to make it 2-D. The shape of the result will be c.shape[2:] + + x.shape. + + Parameters + ---------- + x, y : array_like, compatible objects + The two dimensional series is evaluated at the points in the + Cartesian product of `x` and `y`. If `x` or `y` is a list or + tuple, it is first converted to an ndarray, otherwise it is left + unchanged and, if it isn't an ndarray, it is treated as a scalar. + c : array_like + Array of coefficients ordered so that the coefficients for terms of + degree i,j are contained in ``c[i,j]``. If `c` has dimension + greater than two the remaining indices enumerate multiple sets of + coefficients. + + Returns + ------- + values : ndarray, compatible object + The values of the two dimensional polynomial at points in the Cartesian + product of `x` and `y`. + + See Also + -------- + hermval, hermval2d, hermval3d, hermgrid3d + + Notes + ----- + + .. versionadded:: 1.7.0 + + """ + return pu._gridnd(hermval, c, x, y) + + +def hermval3d(x, y, z, c): + """ + Evaluate a 3-D Hermite series at points (x, y, z). + + This function returns the values: + + .. math:: p(x,y,z) = \\sum_{i,j,k} c_{i,j,k} * H_i(x) * H_j(y) * H_k(z) + + The parameters `x`, `y`, and `z` are converted to arrays only if + they are tuples or a lists, otherwise they are treated as a scalars and + they must have the same shape after conversion. In either case, either + `x`, `y`, and `z` or their elements must support multiplication and + addition both with themselves and with the elements of `c`. + + If `c` has fewer than 3 dimensions, ones are implicitly appended to its + shape to make it 3-D. The shape of the result will be c.shape[3:] + + x.shape. + + Parameters + ---------- + x, y, z : array_like, compatible object + The three dimensional series is evaluated at the points + `(x, y, z)`, where `x`, `y`, and `z` must have the same shape. If + any of `x`, `y`, or `z` is a list or tuple, it is first converted + to an ndarray, otherwise it is left unchanged and if it isn't an + ndarray it is treated as a scalar. + c : array_like + Array of coefficients ordered so that the coefficient of the term of + multi-degree i,j,k is contained in ``c[i,j,k]``. If `c` has dimension + greater than 3 the remaining indices enumerate multiple sets of + coefficients. + + Returns + ------- + values : ndarray, compatible object + The values of the multidimensional polynomial on points formed with + triples of corresponding values from `x`, `y`, and `z`. + + See Also + -------- + hermval, hermval2d, hermgrid2d, hermgrid3d + + Notes + ----- + + .. versionadded:: 1.7.0 + + """ + return pu._valnd(hermval, c, x, y, z) + + +def hermgrid3d(x, y, z, c): + """ + Evaluate a 3-D Hermite series on the Cartesian product of x, y, and z. + + This function returns the values: + + .. math:: p(a,b,c) = \\sum_{i,j,k} c_{i,j,k} * H_i(a) * H_j(b) * H_k(c) + + where the points `(a, b, c)` consist of all triples formed by taking + `a` from `x`, `b` from `y`, and `c` from `z`. The resulting points form + a grid with `x` in the first dimension, `y` in the second, and `z` in + the third. + + The parameters `x`, `y`, and `z` are converted to arrays only if they + are tuples or a lists, otherwise they are treated as a scalars. In + either case, either `x`, `y`, and `z` or their elements must support + multiplication and addition both with themselves and with the elements + of `c`. + + If `c` has fewer than three dimensions, ones are implicitly appended to + its shape to make it 3-D. The shape of the result will be c.shape[3:] + + x.shape + y.shape + z.shape. + + Parameters + ---------- + x, y, z : array_like, compatible objects + The three dimensional series is evaluated at the points in the + Cartesian product of `x`, `y`, and `z`. If `x`,`y`, or `z` is a + list or tuple, it is first converted to an ndarray, otherwise it is + left unchanged and, if it isn't an ndarray, it is treated as a + scalar. + c : array_like + Array of coefficients ordered so that the coefficients for terms of + degree i,j are contained in ``c[i,j]``. If `c` has dimension + greater than two the remaining indices enumerate multiple sets of + coefficients. + + Returns + ------- + values : ndarray, compatible object + The values of the two dimensional polynomial at points in the Cartesian + product of `x` and `y`. + + See Also + -------- + hermval, hermval2d, hermgrid2d, hermval3d + + Notes + ----- + + .. versionadded:: 1.7.0 + + """ + return pu._gridnd(hermval, c, x, y, z) + + +def hermvander(x, deg): + """Pseudo-Vandermonde matrix of given degree. + + Returns the pseudo-Vandermonde matrix of degree `deg` and sample points + `x`. The pseudo-Vandermonde matrix is defined by + + .. math:: V[..., i] = H_i(x), + + where `0 <= i <= deg`. The leading indices of `V` index the elements of + `x` and the last index is the degree of the Hermite polynomial. + + If `c` is a 1-D array of coefficients of length `n + 1` and `V` is the + array ``V = hermvander(x, n)``, then ``np.dot(V, c)`` and + ``hermval(x, c)`` are the same up to roundoff. This equivalence is + useful both for least squares fitting and for the evaluation of a large + number of Hermite series of the same degree and sample points. + + Parameters + ---------- + x : array_like + Array of points. The dtype is converted to float64 or complex128 + depending on whether any of the elements are complex. If `x` is + scalar it is converted to a 1-D array. + deg : int + Degree of the resulting matrix. + + Returns + ------- + vander : ndarray + The pseudo-Vandermonde matrix. The shape of the returned matrix is + ``x.shape + (deg + 1,)``, where The last index is the degree of the + corresponding Hermite polynomial. The dtype will be the same as + the converted `x`. + + Examples + -------- + >>> from numpy.polynomial.hermite import hermvander + >>> x = np.array([-1, 0, 1]) + >>> hermvander(x, 3) + array([[ 1., -2., 2., 4.], + [ 1., 0., -2., -0.], + [ 1., 2., 2., -4.]]) + + """ + ideg = pu._deprecate_as_int(deg, "deg") + if ideg < 0: + raise ValueError("deg must be non-negative") + + x = np.array(x, copy=False, ndmin=1) + 0.0 + dims = (ideg + 1,) + x.shape + dtyp = x.dtype + v = np.empty(dims, dtype=dtyp) + v[0] = x*0 + 1 + if ideg > 0: + x2 = x*2 + v[1] = x2 + for i in range(2, ideg + 1): + v[i] = (v[i-1]*x2 - v[i-2]*(2*(i - 1))) + return np.moveaxis(v, 0, -1) + + +def hermvander2d(x, y, deg): + """Pseudo-Vandermonde matrix of given degrees. + + Returns the pseudo-Vandermonde matrix of degrees `deg` and sample + points `(x, y)`. The pseudo-Vandermonde matrix is defined by + + .. math:: V[..., (deg[1] + 1)*i + j] = H_i(x) * H_j(y), + + where `0 <= i <= deg[0]` and `0 <= j <= deg[1]`. The leading indices of + `V` index the points `(x, y)` and the last index encodes the degrees of + the Hermite polynomials. + + If ``V = hermvander2d(x, y, [xdeg, ydeg])``, then the columns of `V` + correspond to the elements of a 2-D coefficient array `c` of shape + (xdeg + 1, ydeg + 1) in the order + + .. math:: c_{00}, c_{01}, c_{02} ... , c_{10}, c_{11}, c_{12} ... + + and ``np.dot(V, c.flat)`` and ``hermval2d(x, y, c)`` will be the same + up to roundoff. This equivalence is useful both for least squares + fitting and for the evaluation of a large number of 2-D Hermite + series of the same degrees and sample points. + + Parameters + ---------- + x, y : array_like + Arrays of point coordinates, all of the same shape. The dtypes + will be converted to either float64 or complex128 depending on + whether any of the elements are complex. Scalars are converted to 1-D + arrays. + deg : list of ints + List of maximum degrees of the form [x_deg, y_deg]. + + Returns + ------- + vander2d : ndarray + The shape of the returned matrix is ``x.shape + (order,)``, where + :math:`order = (deg[0]+1)*(deg[1]+1)`. The dtype will be the same + as the converted `x` and `y`. + + See Also + -------- + hermvander, hermvander3d, hermval2d, hermval3d + + Notes + ----- + + .. versionadded:: 1.7.0 + + """ + return pu._vander_nd_flat((hermvander, hermvander), (x, y), deg) + + +def hermvander3d(x, y, z, deg): + """Pseudo-Vandermonde matrix of given degrees. + + Returns the pseudo-Vandermonde matrix of degrees `deg` and sample + points `(x, y, z)`. If `l, m, n` are the given degrees in `x, y, z`, + then The pseudo-Vandermonde matrix is defined by + + .. math:: V[..., (m+1)(n+1)i + (n+1)j + k] = H_i(x)*H_j(y)*H_k(z), + + where `0 <= i <= l`, `0 <= j <= m`, and `0 <= j <= n`. The leading + indices of `V` index the points `(x, y, z)` and the last index encodes + the degrees of the Hermite polynomials. + + If ``V = hermvander3d(x, y, z, [xdeg, ydeg, zdeg])``, then the columns + of `V` correspond to the elements of a 3-D coefficient array `c` of + shape (xdeg + 1, ydeg + 1, zdeg + 1) in the order + + .. math:: c_{000}, c_{001}, c_{002},... , c_{010}, c_{011}, c_{012},... + + and ``np.dot(V, c.flat)`` and ``hermval3d(x, y, z, c)`` will be the + same up to roundoff. This equivalence is useful both for least squares + fitting and for the evaluation of a large number of 3-D Hermite + series of the same degrees and sample points. + + Parameters + ---------- + x, y, z : array_like + Arrays of point coordinates, all of the same shape. The dtypes will + be converted to either float64 or complex128 depending on whether + any of the elements are complex. Scalars are converted to 1-D + arrays. + deg : list of ints + List of maximum degrees of the form [x_deg, y_deg, z_deg]. + + Returns + ------- + vander3d : ndarray + The shape of the returned matrix is ``x.shape + (order,)``, where + :math:`order = (deg[0]+1)*(deg[1]+1)*(deg[2]+1)`. The dtype will + be the same as the converted `x`, `y`, and `z`. + + See Also + -------- + hermvander, hermvander3d, hermval2d, hermval3d + + Notes + ----- + + .. versionadded:: 1.7.0 + + """ + return pu._vander_nd_flat((hermvander, hermvander, hermvander), (x, y, z), deg) + + +def hermfit(x, y, deg, rcond=None, full=False, w=None): + """ + Least squares fit of Hermite series to data. + + Return the coefficients of a Hermite series of degree `deg` that is the + least squares fit to the data values `y` given at points `x`. If `y` is + 1-D the returned coefficients will also be 1-D. If `y` is 2-D multiple + fits are done, one for each column of `y`, and the resulting + coefficients are stored in the corresponding columns of a 2-D return. + The fitted polynomial(s) are in the form + + .. math:: p(x) = c_0 + c_1 * H_1(x) + ... + c_n * H_n(x), + + where `n` is `deg`. + + Parameters + ---------- + x : array_like, shape (M,) + x-coordinates of the M sample points ``(x[i], y[i])``. + y : array_like, shape (M,) or (M, K) + y-coordinates of the sample points. Several data sets of sample + points sharing the same x-coordinates can be fitted at once by + passing in a 2D-array that contains one dataset per column. + deg : int or 1-D array_like + Degree(s) of the fitting polynomials. If `deg` is a single integer + all terms up to and including the `deg`'th term are included in the + fit. For NumPy versions >= 1.11.0 a list of integers specifying the + degrees of the terms to include may be used instead. + rcond : float, optional + Relative condition number of the fit. Singular values smaller than + this relative to the largest singular value will be ignored. The + default value is len(x)*eps, where eps is the relative precision of + the float type, about 2e-16 in most cases. + full : bool, optional + Switch determining nature of return value. When it is False (the + default) just the coefficients are returned, when True diagnostic + information from the singular value decomposition is also returned. + w : array_like, shape (`M`,), optional + Weights. If not None, the contribution of each point + ``(x[i],y[i])`` to the fit is weighted by `w[i]`. Ideally the + weights are chosen so that the errors of the products ``w[i]*y[i]`` + all have the same variance. The default value is None. + + Returns + ------- + coef : ndarray, shape (M,) or (M, K) + Hermite coefficients ordered from low to high. If `y` was 2-D, + the coefficients for the data in column k of `y` are in column + `k`. + + [residuals, rank, singular_values, rcond] : list + These values are only returned if `full` = True + + resid -- sum of squared residuals of the least squares fit + rank -- the numerical rank of the scaled Vandermonde matrix + sv -- singular values of the scaled Vandermonde matrix + rcond -- value of `rcond`. + + For more details, see `numpy.linalg.lstsq`. + + Warns + ----- + RankWarning + The rank of the coefficient matrix in the least-squares fit is + deficient. The warning is only raised if `full` = False. The + warnings can be turned off by + + >>> import warnings + >>> warnings.simplefilter('ignore', np.RankWarning) + + See Also + -------- + numpy.polynomial.chebyshev.chebfit + numpy.polynomial.legendre.legfit + numpy.polynomial.laguerre.lagfit + numpy.polynomial.polynomial.polyfit + numpy.polynomial.hermite_e.hermefit + hermval : Evaluates a Hermite series. + hermvander : Vandermonde matrix of Hermite series. + hermweight : Hermite weight function + numpy.linalg.lstsq : Computes a least-squares fit from the matrix. + scipy.interpolate.UnivariateSpline : Computes spline fits. + + Notes + ----- + The solution is the coefficients of the Hermite series `p` that + minimizes the sum of the weighted squared errors + + .. math:: E = \\sum_j w_j^2 * |y_j - p(x_j)|^2, + + where the :math:`w_j` are the weights. This problem is solved by + setting up the (typically) overdetermined matrix equation + + .. math:: V(x) * c = w * y, + + where `V` is the weighted pseudo Vandermonde matrix of `x`, `c` are the + coefficients to be solved for, `w` are the weights, `y` are the + observed values. This equation is then solved using the singular value + decomposition of `V`. + + If some of the singular values of `V` are so small that they are + neglected, then a `RankWarning` will be issued. This means that the + coefficient values may be poorly determined. Using a lower order fit + will usually get rid of the warning. The `rcond` parameter can also be + set to a value smaller than its default, but the resulting fit may be + spurious and have large contributions from roundoff error. + + Fits using Hermite series are probably most useful when the data can be + approximated by ``sqrt(w(x)) * p(x)``, where `w(x)` is the Hermite + weight. In that case the weight ``sqrt(w(x[i]))`` should be used + together with data values ``y[i]/sqrt(w(x[i]))``. The weight function is + available as `hermweight`. + + References + ---------- + .. [1] Wikipedia, "Curve fitting", + https://en.wikipedia.org/wiki/Curve_fitting + + Examples + -------- + >>> from numpy.polynomial.hermite import hermfit, hermval + >>> x = np.linspace(-10, 10) + >>> err = np.random.randn(len(x))/10 + >>> y = hermval(x, [1, 2, 3]) + err + >>> hermfit(x, y, 2) + array([1.0218, 1.9986, 2.9999]) # may vary + + """ + return pu._fit(hermvander, x, y, deg, rcond, full, w) + + +def hermcompanion(c): + """Return the scaled companion matrix of c. + + The basis polynomials are scaled so that the companion matrix is + symmetric when `c` is an Hermite basis polynomial. This provides + better eigenvalue estimates than the unscaled case and for basis + polynomials the eigenvalues are guaranteed to be real if + `numpy.linalg.eigvalsh` is used to obtain them. + + Parameters + ---------- + c : array_like + 1-D array of Hermite series coefficients ordered from low to high + degree. + + Returns + ------- + mat : ndarray + Scaled companion matrix of dimensions (deg, deg). + + Notes + ----- + + .. versionadded:: 1.7.0 + + """ + # c is a trimmed copy + [c] = pu.as_series([c]) + if len(c) < 2: + raise ValueError('Series must have maximum degree of at least 1.') + if len(c) == 2: + return np.array([[-.5*c[0]/c[1]]]) + + n = len(c) - 1 + mat = np.zeros((n, n), dtype=c.dtype) + scl = np.hstack((1., 1./np.sqrt(2.*np.arange(n - 1, 0, -1)))) + scl = np.multiply.accumulate(scl)[::-1] + top = mat.reshape(-1)[1::n+1] + bot = mat.reshape(-1)[n::n+1] + top[...] = np.sqrt(.5*np.arange(1, n)) + bot[...] = top + mat[:, -1] -= scl*c[:-1]/(2.0*c[-1]) + return mat + + +def hermroots(c): + """ + Compute the roots of a Hermite series. + + Return the roots (a.k.a. "zeros") of the polynomial + + .. math:: p(x) = \\sum_i c[i] * H_i(x). + + Parameters + ---------- + c : 1-D array_like + 1-D array of coefficients. + + Returns + ------- + out : ndarray + Array of the roots of the series. If all the roots are real, + then `out` is also real, otherwise it is complex. + + See Also + -------- + numpy.polynomial.polynomial.polyroots + numpy.polynomial.legendre.legroots + numpy.polynomial.laguerre.lagroots + numpy.polynomial.chebyshev.chebroots + numpy.polynomial.hermite_e.hermeroots + + Notes + ----- + The root estimates are obtained as the eigenvalues of the companion + matrix, Roots far from the origin of the complex plane may have large + errors due to the numerical instability of the series for such + values. Roots with multiplicity greater than 1 will also show larger + errors as the value of the series near such points is relatively + insensitive to errors in the roots. Isolated roots near the origin can + be improved by a few iterations of Newton's method. + + The Hermite series basis polynomials aren't powers of `x` so the + results of this function may seem unintuitive. + + Examples + -------- + >>> from numpy.polynomial.hermite import hermroots, hermfromroots + >>> coef = hermfromroots([-1, 0, 1]) + >>> coef + array([0. , 0.25 , 0. , 0.125]) + >>> hermroots(coef) + array([-1.00000000e+00, -1.38777878e-17, 1.00000000e+00]) + + """ + # c is a trimmed copy + [c] = pu.as_series([c]) + if len(c) <= 1: + return np.array([], dtype=c.dtype) + if len(c) == 2: + return np.array([-.5*c[0]/c[1]]) + + # rotated companion matrix reduces error + m = hermcompanion(c)[::-1,::-1] + r = la.eigvals(m) + r.sort() + return r + + +def _normed_hermite_n(x, n): + """ + Evaluate a normalized Hermite polynomial. + + Compute the value of the normalized Hermite polynomial of degree ``n`` + at the points ``x``. + + + Parameters + ---------- + x : ndarray of double. + Points at which to evaluate the function + n : int + Degree of the normalized Hermite function to be evaluated. + + Returns + ------- + values : ndarray + The shape of the return value is described above. + + Notes + ----- + .. versionadded:: 1.10.0 + + This function is needed for finding the Gauss points and integration + weights for high degrees. The values of the standard Hermite functions + overflow when n >= 207. + + """ + if n == 0: + return np.full(x.shape, 1/np.sqrt(np.sqrt(np.pi))) + + c0 = 0. + c1 = 1./np.sqrt(np.sqrt(np.pi)) + nd = float(n) + for i in range(n - 1): + tmp = c0 + c0 = -c1*np.sqrt((nd - 1.)/nd) + c1 = tmp + c1*x*np.sqrt(2./nd) + nd = nd - 1.0 + return c0 + c1*x*np.sqrt(2) + + +def hermgauss(deg): + """ + Gauss-Hermite quadrature. + + Computes the sample points and weights for Gauss-Hermite quadrature. + These sample points and weights will correctly integrate polynomials of + degree :math:`2*deg - 1` or less over the interval :math:`[-\\inf, \\inf]` + with the weight function :math:`f(x) = \\exp(-x^2)`. + + Parameters + ---------- + deg : int + Number of sample points and weights. It must be >= 1. + + Returns + ------- + x : ndarray + 1-D ndarray containing the sample points. + y : ndarray + 1-D ndarray containing the weights. + + Notes + ----- + + .. versionadded:: 1.7.0 + + The results have only been tested up to degree 100, higher degrees may + be problematic. The weights are determined by using the fact that + + .. math:: w_k = c / (H'_n(x_k) * H_{n-1}(x_k)) + + where :math:`c` is a constant independent of :math:`k` and :math:`x_k` + is the k'th root of :math:`H_n`, and then scaling the results to get + the right value when integrating 1. + + """ + ideg = pu._deprecate_as_int(deg, "deg") + if ideg <= 0: + raise ValueError("deg must be a positive integer") + + # first approximation of roots. We use the fact that the companion + # matrix is symmetric in this case in order to obtain better zeros. + c = np.array([0]*deg + [1], dtype=np.float64) + m = hermcompanion(c) + x = la.eigvalsh(m) + + # improve roots by one application of Newton + dy = _normed_hermite_n(x, ideg) + df = _normed_hermite_n(x, ideg - 1) * np.sqrt(2*ideg) + x -= dy/df + + # compute the weights. We scale the factor to avoid possible numerical + # overflow. + fm = _normed_hermite_n(x, ideg - 1) + fm /= np.abs(fm).max() + w = 1/(fm * fm) + + # for Hermite we can also symmetrize + w = (w + w[::-1])/2 + x = (x - x[::-1])/2 + + # scale w to get the right value + w *= np.sqrt(np.pi) / w.sum() + + return x, w + + +def hermweight(x): + """ + Weight function of the Hermite polynomials. + + The weight function is :math:`\\exp(-x^2)` and the interval of + integration is :math:`[-\\inf, \\inf]`. the Hermite polynomials are + orthogonal, but not normalized, with respect to this weight function. + + Parameters + ---------- + x : array_like + Values at which the weight function will be computed. + + Returns + ------- + w : ndarray + The weight function at `x`. + + Notes + ----- + + .. versionadded:: 1.7.0 + + """ + w = np.exp(-x**2) + return w + + +# +# Hermite series class +# + +class Hermite(ABCPolyBase): + """An Hermite series class. + + The Hermite class provides the standard Python numerical methods + '+', '-', '*', '//', '%', 'divmod', '**', and '()' as well as the + attributes and methods listed in the `ABCPolyBase` documentation. + + Parameters + ---------- + coef : array_like + Hermite coefficients in order of increasing degree, i.e, + ``(1, 2, 3)`` gives ``1*H_0(x) + 2*H_1(X) + 3*H_2(x)``. + domain : (2,) array_like, optional + Domain to use. The interval ``[domain[0], domain[1]]`` is mapped + to the interval ``[window[0], window[1]]`` by shifting and scaling. + The default value is [-1, 1]. + window : (2,) array_like, optional + Window, see `domain` for its use. The default value is [-1, 1]. + + .. versionadded:: 1.6.0 + + """ + # Virtual Functions + _add = staticmethod(hermadd) + _sub = staticmethod(hermsub) + _mul = staticmethod(hermmul) + _div = staticmethod(hermdiv) + _pow = staticmethod(hermpow) + _val = staticmethod(hermval) + _int = staticmethod(hermint) + _der = staticmethod(hermder) + _fit = staticmethod(hermfit) + _line = staticmethod(hermline) + _roots = staticmethod(hermroots) + _fromroots = staticmethod(hermfromroots) + + # Virtual properties + domain = np.array(hermdomain) + window = np.array(hermdomain) + basis_name = 'H' diff --git a/venv/Lib/site-packages/numpy/polynomial/hermite_e.py b/venv/Lib/site-packages/numpy/polynomial/hermite_e.py new file mode 100644 index 0000000..1ce8ebe --- /dev/null +++ b/venv/Lib/site-packages/numpy/polynomial/hermite_e.py @@ -0,0 +1,1688 @@ +""" +=================================================================== +HermiteE Series, "Probabilists" (:mod:`numpy.polynomial.hermite_e`) +=================================================================== + +This module provides a number of objects (mostly functions) useful for +dealing with Hermite_e series, including a `HermiteE` class that +encapsulates the usual arithmetic operations. (General information +on how this module represents and works with such polynomials is in the +docstring for its "parent" sub-package, `numpy.polynomial`). + +Classes +------- +.. autosummary:: + :toctree: generated/ + + HermiteE + +Constants +--------- +.. autosummary:: + :toctree: generated/ + + hermedomain + hermezero + hermeone + hermex + +Arithmetic +---------- +.. autosummary:: + :toctree: generated/ + + hermeadd + hermesub + hermemulx + hermemul + hermediv + hermepow + hermeval + hermeval2d + hermeval3d + hermegrid2d + hermegrid3d + +Calculus +-------- +.. autosummary:: + :toctree: generated/ + + hermeder + hermeint + +Misc Functions +-------------- +.. autosummary:: + :toctree: generated/ + + hermefromroots + hermeroots + hermevander + hermevander2d + hermevander3d + hermegauss + hermeweight + hermecompanion + hermefit + hermetrim + hermeline + herme2poly + poly2herme + +See also +-------- +`numpy.polynomial` + +""" +import numpy as np +import numpy.linalg as la +from numpy.core.multiarray import normalize_axis_index + +from . import polyutils as pu +from ._polybase import ABCPolyBase + +__all__ = [ + 'hermezero', 'hermeone', 'hermex', 'hermedomain', 'hermeline', + 'hermeadd', 'hermesub', 'hermemulx', 'hermemul', 'hermediv', + 'hermepow', 'hermeval', 'hermeder', 'hermeint', 'herme2poly', + 'poly2herme', 'hermefromroots', 'hermevander', 'hermefit', 'hermetrim', + 'hermeroots', 'HermiteE', 'hermeval2d', 'hermeval3d', 'hermegrid2d', + 'hermegrid3d', 'hermevander2d', 'hermevander3d', 'hermecompanion', + 'hermegauss', 'hermeweight'] + +hermetrim = pu.trimcoef + + +def poly2herme(pol): + """ + poly2herme(pol) + + Convert a polynomial to a Hermite series. + + Convert an array representing the coefficients of a polynomial (relative + to the "standard" basis) ordered from lowest degree to highest, to an + array of the coefficients of the equivalent Hermite series, ordered + from lowest to highest degree. + + Parameters + ---------- + pol : array_like + 1-D array containing the polynomial coefficients + + Returns + ------- + c : ndarray + 1-D array containing the coefficients of the equivalent Hermite + series. + + See Also + -------- + herme2poly + + Notes + ----- + The easy way to do conversions between polynomial basis sets + is to use the convert method of a class instance. + + Examples + -------- + >>> from numpy.polynomial.hermite_e import poly2herme + >>> poly2herme(np.arange(4)) + array([ 2., 10., 2., 3.]) + + """ + [pol] = pu.as_series([pol]) + deg = len(pol) - 1 + res = 0 + for i in range(deg, -1, -1): + res = hermeadd(hermemulx(res), pol[i]) + return res + + +def herme2poly(c): + """ + Convert a Hermite series to a polynomial. + + Convert an array representing the coefficients of a Hermite series, + ordered from lowest degree to highest, to an array of the coefficients + of the equivalent polynomial (relative to the "standard" basis) ordered + from lowest to highest degree. + + Parameters + ---------- + c : array_like + 1-D array containing the Hermite series coefficients, ordered + from lowest order term to highest. + + Returns + ------- + pol : ndarray + 1-D array containing the coefficients of the equivalent polynomial + (relative to the "standard" basis) ordered from lowest order term + to highest. + + See Also + -------- + poly2herme + + Notes + ----- + The easy way to do conversions between polynomial basis sets + is to use the convert method of a class instance. + + Examples + -------- + >>> from numpy.polynomial.hermite_e import herme2poly + >>> herme2poly([ 2., 10., 2., 3.]) + array([0., 1., 2., 3.]) + + """ + from .polynomial import polyadd, polysub, polymulx + + [c] = pu.as_series([c]) + n = len(c) + if n == 1: + return c + if n == 2: + return c + else: + c0 = c[-2] + c1 = c[-1] + # i is the current degree of c1 + for i in range(n - 1, 1, -1): + tmp = c0 + c0 = polysub(c[i - 2], c1*(i - 1)) + c1 = polyadd(tmp, polymulx(c1)) + return polyadd(c0, polymulx(c1)) + +# +# These are constant arrays are of integer type so as to be compatible +# with the widest range of other types, such as Decimal. +# + +# Hermite +hermedomain = np.array([-1, 1]) + +# Hermite coefficients representing zero. +hermezero = np.array([0]) + +# Hermite coefficients representing one. +hermeone = np.array([1]) + +# Hermite coefficients representing the identity x. +hermex = np.array([0, 1]) + + +def hermeline(off, scl): + """ + Hermite series whose graph is a straight line. + + Parameters + ---------- + off, scl : scalars + The specified line is given by ``off + scl*x``. + + Returns + ------- + y : ndarray + This module's representation of the Hermite series for + ``off + scl*x``. + + See Also + -------- + numpy.polynomial.polynomial.polyline + numpy.polynomial.chebyshev.chebline + numpy.polynomial.legendre.legline + numpy.polynomial.laguerre.lagline + numpy.polynomial.hermite.hermline + + Examples + -------- + >>> from numpy.polynomial.hermite_e import hermeline + >>> from numpy.polynomial.hermite_e import hermeline, hermeval + >>> hermeval(0,hermeline(3, 2)) + 3.0 + >>> hermeval(1,hermeline(3, 2)) + 5.0 + + """ + if scl != 0: + return np.array([off, scl]) + else: + return np.array([off]) + + +def hermefromroots(roots): + """ + Generate a HermiteE series with given roots. + + The function returns the coefficients of the polynomial + + .. math:: p(x) = (x - r_0) * (x - r_1) * ... * (x - r_n), + + in HermiteE form, where the `r_n` are the roots specified in `roots`. + If a zero has multiplicity n, then it must appear in `roots` n times. + For instance, if 2 is a root of multiplicity three and 3 is a root of + multiplicity 2, then `roots` looks something like [2, 2, 2, 3, 3]. The + roots can appear in any order. + + If the returned coefficients are `c`, then + + .. math:: p(x) = c_0 + c_1 * He_1(x) + ... + c_n * He_n(x) + + The coefficient of the last term is not generally 1 for monic + polynomials in HermiteE form. + + Parameters + ---------- + roots : array_like + Sequence containing the roots. + + Returns + ------- + out : ndarray + 1-D array of coefficients. If all roots are real then `out` is a + real array, if some of the roots are complex, then `out` is complex + even if all the coefficients in the result are real (see Examples + below). + + See Also + -------- + numpy.polynomial.polynomial.polyfromroots + numpy.polynomial.legendre.legfromroots + numpy.polynomial.laguerre.lagfromroots + numpy.polynomial.hermite.hermfromroots + numpy.polynomial.chebyshev.chebfromroots + + Examples + -------- + >>> from numpy.polynomial.hermite_e import hermefromroots, hermeval + >>> coef = hermefromroots((-1, 0, 1)) + >>> hermeval((-1, 0, 1), coef) + array([0., 0., 0.]) + >>> coef = hermefromroots((-1j, 1j)) + >>> hermeval((-1j, 1j), coef) + array([0.+0.j, 0.+0.j]) + + """ + return pu._fromroots(hermeline, hermemul, roots) + + +def hermeadd(c1, c2): + """ + Add one Hermite series to another. + + Returns the sum of two Hermite series `c1` + `c2`. The arguments + are sequences of coefficients ordered from lowest order term to + highest, i.e., [1,2,3] represents the series ``P_0 + 2*P_1 + 3*P_2``. + + Parameters + ---------- + c1, c2 : array_like + 1-D arrays of Hermite series coefficients ordered from low to + high. + + Returns + ------- + out : ndarray + Array representing the Hermite series of their sum. + + See Also + -------- + hermesub, hermemulx, hermemul, hermediv, hermepow + + Notes + ----- + Unlike multiplication, division, etc., the sum of two Hermite series + is a Hermite series (without having to "reproject" the result onto + the basis set) so addition, just like that of "standard" polynomials, + is simply "component-wise." + + Examples + -------- + >>> from numpy.polynomial.hermite_e import hermeadd + >>> hermeadd([1, 2, 3], [1, 2, 3, 4]) + array([2., 4., 6., 4.]) + + """ + return pu._add(c1, c2) + + +def hermesub(c1, c2): + """ + Subtract one Hermite series from another. + + Returns the difference of two Hermite series `c1` - `c2`. The + sequences of coefficients are from lowest order term to highest, i.e., + [1,2,3] represents the series ``P_0 + 2*P_1 + 3*P_2``. + + Parameters + ---------- + c1, c2 : array_like + 1-D arrays of Hermite series coefficients ordered from low to + high. + + Returns + ------- + out : ndarray + Of Hermite series coefficients representing their difference. + + See Also + -------- + hermeadd, hermemulx, hermemul, hermediv, hermepow + + Notes + ----- + Unlike multiplication, division, etc., the difference of two Hermite + series is a Hermite series (without having to "reproject" the result + onto the basis set) so subtraction, just like that of "standard" + polynomials, is simply "component-wise." + + Examples + -------- + >>> from numpy.polynomial.hermite_e import hermesub + >>> hermesub([1, 2, 3, 4], [1, 2, 3]) + array([0., 0., 0., 4.]) + + """ + return pu._sub(c1, c2) + + +def hermemulx(c): + """Multiply a Hermite series by x. + + Multiply the Hermite series `c` by x, where x is the independent + variable. + + + Parameters + ---------- + c : array_like + 1-D array of Hermite series coefficients ordered from low to + high. + + Returns + ------- + out : ndarray + Array representing the result of the multiplication. + + Notes + ----- + The multiplication uses the recursion relationship for Hermite + polynomials in the form + + .. math:: + + xP_i(x) = (P_{i + 1}(x) + iP_{i - 1}(x))) + + Examples + -------- + >>> from numpy.polynomial.hermite_e import hermemulx + >>> hermemulx([1, 2, 3]) + array([2., 7., 2., 3.]) + + """ + # c is a trimmed copy + [c] = pu.as_series([c]) + # The zero series needs special treatment + if len(c) == 1 and c[0] == 0: + return c + + prd = np.empty(len(c) + 1, dtype=c.dtype) + prd[0] = c[0]*0 + prd[1] = c[0] + for i in range(1, len(c)): + prd[i + 1] = c[i] + prd[i - 1] += c[i]*i + return prd + + +def hermemul(c1, c2): + """ + Multiply one Hermite series by another. + + Returns the product of two Hermite series `c1` * `c2`. The arguments + are sequences of coefficients, from lowest order "term" to highest, + e.g., [1,2,3] represents the series ``P_0 + 2*P_1 + 3*P_2``. + + Parameters + ---------- + c1, c2 : array_like + 1-D arrays of Hermite series coefficients ordered from low to + high. + + Returns + ------- + out : ndarray + Of Hermite series coefficients representing their product. + + See Also + -------- + hermeadd, hermesub, hermemulx, hermediv, hermepow + + Notes + ----- + In general, the (polynomial) product of two C-series results in terms + that are not in the Hermite polynomial basis set. Thus, to express + the product as a Hermite series, it is necessary to "reproject" the + product onto said basis set, which may produce "unintuitive" (but + correct) results; see Examples section below. + + Examples + -------- + >>> from numpy.polynomial.hermite_e import hermemul + >>> hermemul([1, 2, 3], [0, 1, 2]) + array([14., 15., 28., 7., 6.]) + + """ + # s1, s2 are trimmed copies + [c1, c2] = pu.as_series([c1, c2]) + + if len(c1) > len(c2): + c = c2 + xs = c1 + else: + c = c1 + xs = c2 + + if len(c) == 1: + c0 = c[0]*xs + c1 = 0 + elif len(c) == 2: + c0 = c[0]*xs + c1 = c[1]*xs + else: + nd = len(c) + c0 = c[-2]*xs + c1 = c[-1]*xs + for i in range(3, len(c) + 1): + tmp = c0 + nd = nd - 1 + c0 = hermesub(c[-i]*xs, c1*(nd - 1)) + c1 = hermeadd(tmp, hermemulx(c1)) + return hermeadd(c0, hermemulx(c1)) + + +def hermediv(c1, c2): + """ + Divide one Hermite series by another. + + Returns the quotient-with-remainder of two Hermite series + `c1` / `c2`. The arguments are sequences of coefficients from lowest + order "term" to highest, e.g., [1,2,3] represents the series + ``P_0 + 2*P_1 + 3*P_2``. + + Parameters + ---------- + c1, c2 : array_like + 1-D arrays of Hermite series coefficients ordered from low to + high. + + Returns + ------- + [quo, rem] : ndarrays + Of Hermite series coefficients representing the quotient and + remainder. + + See Also + -------- + hermeadd, hermesub, hermemulx, hermemul, hermepow + + Notes + ----- + In general, the (polynomial) division of one Hermite series by another + results in quotient and remainder terms that are not in the Hermite + polynomial basis set. Thus, to express these results as a Hermite + series, it is necessary to "reproject" the results onto the Hermite + basis set, which may produce "unintuitive" (but correct) results; see + Examples section below. + + Examples + -------- + >>> from numpy.polynomial.hermite_e import hermediv + >>> hermediv([ 14., 15., 28., 7., 6.], [0, 1, 2]) + (array([1., 2., 3.]), array([0.])) + >>> hermediv([ 15., 17., 28., 7., 6.], [0, 1, 2]) + (array([1., 2., 3.]), array([1., 2.])) + + """ + return pu._div(hermemul, c1, c2) + + +def hermepow(c, pow, maxpower=16): + """Raise a Hermite series to a power. + + Returns the Hermite series `c` raised to the power `pow`. The + argument `c` is a sequence of coefficients ordered from low to high. + i.e., [1,2,3] is the series ``P_0 + 2*P_1 + 3*P_2.`` + + Parameters + ---------- + c : array_like + 1-D array of Hermite series coefficients ordered from low to + high. + pow : integer + Power to which the series will be raised + maxpower : integer, optional + Maximum power allowed. This is mainly to limit growth of the series + to unmanageable size. Default is 16 + + Returns + ------- + coef : ndarray + Hermite series of power. + + See Also + -------- + hermeadd, hermesub, hermemulx, hermemul, hermediv + + Examples + -------- + >>> from numpy.polynomial.hermite_e import hermepow + >>> hermepow([1, 2, 3], 2) + array([23., 28., 46., 12., 9.]) + + """ + return pu._pow(hermemul, c, pow, maxpower) + + +def hermeder(c, m=1, scl=1, axis=0): + """ + Differentiate a Hermite_e series. + + Returns the series coefficients `c` differentiated `m` times along + `axis`. At each iteration the result is multiplied by `scl` (the + scaling factor is for use in a linear change of variable). The argument + `c` is an array of coefficients from low to high degree along each + axis, e.g., [1,2,3] represents the series ``1*He_0 + 2*He_1 + 3*He_2`` + while [[1,2],[1,2]] represents ``1*He_0(x)*He_0(y) + 1*He_1(x)*He_0(y) + + 2*He_0(x)*He_1(y) + 2*He_1(x)*He_1(y)`` if axis=0 is ``x`` and axis=1 + is ``y``. + + Parameters + ---------- + c : array_like + Array of Hermite_e series coefficients. If `c` is multidimensional + the different axis correspond to different variables with the + degree in each axis given by the corresponding index. + m : int, optional + Number of derivatives taken, must be non-negative. (Default: 1) + scl : scalar, optional + Each differentiation is multiplied by `scl`. The end result is + multiplication by ``scl**m``. This is for use in a linear change of + variable. (Default: 1) + axis : int, optional + Axis over which the derivative is taken. (Default: 0). + + .. versionadded:: 1.7.0 + + Returns + ------- + der : ndarray + Hermite series of the derivative. + + See Also + -------- + hermeint + + Notes + ----- + In general, the result of differentiating a Hermite series does not + resemble the same operation on a power series. Thus the result of this + function may be "unintuitive," albeit correct; see Examples section + below. + + Examples + -------- + >>> from numpy.polynomial.hermite_e import hermeder + >>> hermeder([ 1., 1., 1., 1.]) + array([1., 2., 3.]) + >>> hermeder([-0.25, 1., 1./2., 1./3., 1./4 ], m=2) + array([1., 2., 3.]) + + """ + c = np.array(c, ndmin=1, copy=True) + if c.dtype.char in '?bBhHiIlLqQpP': + c = c.astype(np.double) + cnt = pu._deprecate_as_int(m, "the order of derivation") + iaxis = pu._deprecate_as_int(axis, "the axis") + if cnt < 0: + raise ValueError("The order of derivation must be non-negative") + iaxis = normalize_axis_index(iaxis, c.ndim) + + if cnt == 0: + return c + + c = np.moveaxis(c, iaxis, 0) + n = len(c) + if cnt >= n: + return c[:1]*0 + else: + for i in range(cnt): + n = n - 1 + c *= scl + der = np.empty((n,) + c.shape[1:], dtype=c.dtype) + for j in range(n, 0, -1): + der[j - 1] = j*c[j] + c = der + c = np.moveaxis(c, 0, iaxis) + return c + + +def hermeint(c, m=1, k=[], lbnd=0, scl=1, axis=0): + """ + Integrate a Hermite_e series. + + Returns the Hermite_e series coefficients `c` integrated `m` times from + `lbnd` along `axis`. At each iteration the resulting series is + **multiplied** by `scl` and an integration constant, `k`, is added. + The scaling factor is for use in a linear change of variable. ("Buyer + beware": note that, depending on what one is doing, one may want `scl` + to be the reciprocal of what one might expect; for more information, + see the Notes section below.) The argument `c` is an array of + coefficients from low to high degree along each axis, e.g., [1,2,3] + represents the series ``H_0 + 2*H_1 + 3*H_2`` while [[1,2],[1,2]] + represents ``1*H_0(x)*H_0(y) + 1*H_1(x)*H_0(y) + 2*H_0(x)*H_1(y) + + 2*H_1(x)*H_1(y)`` if axis=0 is ``x`` and axis=1 is ``y``. + + Parameters + ---------- + c : array_like + Array of Hermite_e series coefficients. If c is multidimensional + the different axis correspond to different variables with the + degree in each axis given by the corresponding index. + m : int, optional + Order of integration, must be positive. (Default: 1) + k : {[], list, scalar}, optional + Integration constant(s). The value of the first integral at + ``lbnd`` is the first value in the list, the value of the second + integral at ``lbnd`` is the second value, etc. If ``k == []`` (the + default), all constants are set to zero. If ``m == 1``, a single + scalar can be given instead of a list. + lbnd : scalar, optional + The lower bound of the integral. (Default: 0) + scl : scalar, optional + Following each integration the result is *multiplied* by `scl` + before the integration constant is added. (Default: 1) + axis : int, optional + Axis over which the integral is taken. (Default: 0). + + .. versionadded:: 1.7.0 + + Returns + ------- + S : ndarray + Hermite_e series coefficients of the integral. + + Raises + ------ + ValueError + If ``m < 0``, ``len(k) > m``, ``np.ndim(lbnd) != 0``, or + ``np.ndim(scl) != 0``. + + See Also + -------- + hermeder + + Notes + ----- + Note that the result of each integration is *multiplied* by `scl`. + Why is this important to note? Say one is making a linear change of + variable :math:`u = ax + b` in an integral relative to `x`. Then + :math:`dx = du/a`, so one will need to set `scl` equal to + :math:`1/a` - perhaps not what one would have first thought. + + Also note that, in general, the result of integrating a C-series needs + to be "reprojected" onto the C-series basis set. Thus, typically, + the result of this function is "unintuitive," albeit correct; see + Examples section below. + + Examples + -------- + >>> from numpy.polynomial.hermite_e import hermeint + >>> hermeint([1, 2, 3]) # integrate once, value 0 at 0. + array([1., 1., 1., 1.]) + >>> hermeint([1, 2, 3], m=2) # integrate twice, value & deriv 0 at 0 + array([-0.25 , 1. , 0.5 , 0.33333333, 0.25 ]) # may vary + >>> hermeint([1, 2, 3], k=1) # integrate once, value 1 at 0. + array([2., 1., 1., 1.]) + >>> hermeint([1, 2, 3], lbnd=-1) # integrate once, value 0 at -1 + array([-1., 1., 1., 1.]) + >>> hermeint([1, 2, 3], m=2, k=[1, 2], lbnd=-1) + array([ 1.83333333, 0. , 0.5 , 0.33333333, 0.25 ]) # may vary + + """ + c = np.array(c, ndmin=1, copy=True) + if c.dtype.char in '?bBhHiIlLqQpP': + c = c.astype(np.double) + if not np.iterable(k): + k = [k] + cnt = pu._deprecate_as_int(m, "the order of integration") + iaxis = pu._deprecate_as_int(axis, "the axis") + if cnt < 0: + raise ValueError("The order of integration must be non-negative") + if len(k) > cnt: + raise ValueError("Too many integration constants") + if np.ndim(lbnd) != 0: + raise ValueError("lbnd must be a scalar.") + if np.ndim(scl) != 0: + raise ValueError("scl must be a scalar.") + iaxis = normalize_axis_index(iaxis, c.ndim) + + if cnt == 0: + return c + + c = np.moveaxis(c, iaxis, 0) + k = list(k) + [0]*(cnt - len(k)) + for i in range(cnt): + n = len(c) + c *= scl + if n == 1 and np.all(c[0] == 0): + c[0] += k[i] + else: + tmp = np.empty((n + 1,) + c.shape[1:], dtype=c.dtype) + tmp[0] = c[0]*0 + tmp[1] = c[0] + for j in range(1, n): + tmp[j + 1] = c[j]/(j + 1) + tmp[0] += k[i] - hermeval(lbnd, tmp) + c = tmp + c = np.moveaxis(c, 0, iaxis) + return c + + +def hermeval(x, c, tensor=True): + """ + Evaluate an HermiteE series at points x. + + If `c` is of length `n + 1`, this function returns the value: + + .. math:: p(x) = c_0 * He_0(x) + c_1 * He_1(x) + ... + c_n * He_n(x) + + The parameter `x` is converted to an array only if it is a tuple or a + list, otherwise it is treated as a scalar. In either case, either `x` + or its elements must support multiplication and addition both with + themselves and with the elements of `c`. + + If `c` is a 1-D array, then `p(x)` will have the same shape as `x`. If + `c` is multidimensional, then the shape of the result depends on the + value of `tensor`. If `tensor` is true the shape will be c.shape[1:] + + x.shape. If `tensor` is false the shape will be c.shape[1:]. Note that + scalars have shape (,). + + Trailing zeros in the coefficients will be used in the evaluation, so + they should be avoided if efficiency is a concern. + + Parameters + ---------- + x : array_like, compatible object + If `x` is a list or tuple, it is converted to an ndarray, otherwise + it is left unchanged and treated as a scalar. In either case, `x` + or its elements must support addition and multiplication with + with themselves and with the elements of `c`. + c : array_like + Array of coefficients ordered so that the coefficients for terms of + degree n are contained in c[n]. If `c` is multidimensional the + remaining indices enumerate multiple polynomials. In the two + dimensional case the coefficients may be thought of as stored in + the columns of `c`. + tensor : boolean, optional + If True, the shape of the coefficient array is extended with ones + on the right, one for each dimension of `x`. Scalars have dimension 0 + for this action. The result is that every column of coefficients in + `c` is evaluated for every element of `x`. If False, `x` is broadcast + over the columns of `c` for the evaluation. This keyword is useful + when `c` is multidimensional. The default value is True. + + .. versionadded:: 1.7.0 + + Returns + ------- + values : ndarray, algebra_like + The shape of the return value is described above. + + See Also + -------- + hermeval2d, hermegrid2d, hermeval3d, hermegrid3d + + Notes + ----- + The evaluation uses Clenshaw recursion, aka synthetic division. + + Examples + -------- + >>> from numpy.polynomial.hermite_e import hermeval + >>> coef = [1,2,3] + >>> hermeval(1, coef) + 3.0 + >>> hermeval([[1,2],[3,4]], coef) + array([[ 3., 14.], + [31., 54.]]) + + """ + c = np.array(c, ndmin=1, copy=False) + if c.dtype.char in '?bBhHiIlLqQpP': + c = c.astype(np.double) + if isinstance(x, (tuple, list)): + x = np.asarray(x) + if isinstance(x, np.ndarray) and tensor: + c = c.reshape(c.shape + (1,)*x.ndim) + + if len(c) == 1: + c0 = c[0] + c1 = 0 + elif len(c) == 2: + c0 = c[0] + c1 = c[1] + else: + nd = len(c) + c0 = c[-2] + c1 = c[-1] + for i in range(3, len(c) + 1): + tmp = c0 + nd = nd - 1 + c0 = c[-i] - c1*(nd - 1) + c1 = tmp + c1*x + return c0 + c1*x + + +def hermeval2d(x, y, c): + """ + Evaluate a 2-D HermiteE series at points (x, y). + + This function returns the values: + + .. math:: p(x,y) = \\sum_{i,j} c_{i,j} * He_i(x) * He_j(y) + + The parameters `x` and `y` are converted to arrays only if they are + tuples or a lists, otherwise they are treated as a scalars and they + must have the same shape after conversion. In either case, either `x` + and `y` or their elements must support multiplication and addition both + with themselves and with the elements of `c`. + + If `c` is a 1-D array a one is implicitly appended to its shape to make + it 2-D. The shape of the result will be c.shape[2:] + x.shape. + + Parameters + ---------- + x, y : array_like, compatible objects + The two dimensional series is evaluated at the points `(x, y)`, + where `x` and `y` must have the same shape. If `x` or `y` is a list + or tuple, it is first converted to an ndarray, otherwise it is left + unchanged and if it isn't an ndarray it is treated as a scalar. + c : array_like + Array of coefficients ordered so that the coefficient of the term + of multi-degree i,j is contained in ``c[i,j]``. If `c` has + dimension greater than two the remaining indices enumerate multiple + sets of coefficients. + + Returns + ------- + values : ndarray, compatible object + The values of the two dimensional polynomial at points formed with + pairs of corresponding values from `x` and `y`. + + See Also + -------- + hermeval, hermegrid2d, hermeval3d, hermegrid3d + + Notes + ----- + + .. versionadded:: 1.7.0 + + """ + return pu._valnd(hermeval, c, x, y) + + +def hermegrid2d(x, y, c): + """ + Evaluate a 2-D HermiteE series on the Cartesian product of x and y. + + This function returns the values: + + .. math:: p(a,b) = \\sum_{i,j} c_{i,j} * H_i(a) * H_j(b) + + where the points `(a, b)` consist of all pairs formed by taking + `a` from `x` and `b` from `y`. The resulting points form a grid with + `x` in the first dimension and `y` in the second. + + The parameters `x` and `y` are converted to arrays only if they are + tuples or a lists, otherwise they are treated as a scalars. In either + case, either `x` and `y` or their elements must support multiplication + and addition both with themselves and with the elements of `c`. + + If `c` has fewer than two dimensions, ones are implicitly appended to + its shape to make it 2-D. The shape of the result will be c.shape[2:] + + x.shape. + + Parameters + ---------- + x, y : array_like, compatible objects + The two dimensional series is evaluated at the points in the + Cartesian product of `x` and `y`. If `x` or `y` is a list or + tuple, it is first converted to an ndarray, otherwise it is left + unchanged and, if it isn't an ndarray, it is treated as a scalar. + c : array_like + Array of coefficients ordered so that the coefficients for terms of + degree i,j are contained in ``c[i,j]``. If `c` has dimension + greater than two the remaining indices enumerate multiple sets of + coefficients. + + Returns + ------- + values : ndarray, compatible object + The values of the two dimensional polynomial at points in the Cartesian + product of `x` and `y`. + + See Also + -------- + hermeval, hermeval2d, hermeval3d, hermegrid3d + + Notes + ----- + + .. versionadded:: 1.7.0 + + """ + return pu._gridnd(hermeval, c, x, y) + + +def hermeval3d(x, y, z, c): + """ + Evaluate a 3-D Hermite_e series at points (x, y, z). + + This function returns the values: + + .. math:: p(x,y,z) = \\sum_{i,j,k} c_{i,j,k} * He_i(x) * He_j(y) * He_k(z) + + The parameters `x`, `y`, and `z` are converted to arrays only if + they are tuples or a lists, otherwise they are treated as a scalars and + they must have the same shape after conversion. In either case, either + `x`, `y`, and `z` or their elements must support multiplication and + addition both with themselves and with the elements of `c`. + + If `c` has fewer than 3 dimensions, ones are implicitly appended to its + shape to make it 3-D. The shape of the result will be c.shape[3:] + + x.shape. + + Parameters + ---------- + x, y, z : array_like, compatible object + The three dimensional series is evaluated at the points + `(x, y, z)`, where `x`, `y`, and `z` must have the same shape. If + any of `x`, `y`, or `z` is a list or tuple, it is first converted + to an ndarray, otherwise it is left unchanged and if it isn't an + ndarray it is treated as a scalar. + c : array_like + Array of coefficients ordered so that the coefficient of the term of + multi-degree i,j,k is contained in ``c[i,j,k]``. If `c` has dimension + greater than 3 the remaining indices enumerate multiple sets of + coefficients. + + Returns + ------- + values : ndarray, compatible object + The values of the multidimensional polynomial on points formed with + triples of corresponding values from `x`, `y`, and `z`. + + See Also + -------- + hermeval, hermeval2d, hermegrid2d, hermegrid3d + + Notes + ----- + + .. versionadded:: 1.7.0 + + """ + return pu._valnd(hermeval, c, x, y, z) + + +def hermegrid3d(x, y, z, c): + """ + Evaluate a 3-D HermiteE series on the Cartesian product of x, y, and z. + + This function returns the values: + + .. math:: p(a,b,c) = \\sum_{i,j,k} c_{i,j,k} * He_i(a) * He_j(b) * He_k(c) + + where the points `(a, b, c)` consist of all triples formed by taking + `a` from `x`, `b` from `y`, and `c` from `z`. The resulting points form + a grid with `x` in the first dimension, `y` in the second, and `z` in + the third. + + The parameters `x`, `y`, and `z` are converted to arrays only if they + are tuples or a lists, otherwise they are treated as a scalars. In + either case, either `x`, `y`, and `z` or their elements must support + multiplication and addition both with themselves and with the elements + of `c`. + + If `c` has fewer than three dimensions, ones are implicitly appended to + its shape to make it 3-D. The shape of the result will be c.shape[3:] + + x.shape + y.shape + z.shape. + + Parameters + ---------- + x, y, z : array_like, compatible objects + The three dimensional series is evaluated at the points in the + Cartesian product of `x`, `y`, and `z`. If `x`,`y`, or `z` is a + list or tuple, it is first converted to an ndarray, otherwise it is + left unchanged and, if it isn't an ndarray, it is treated as a + scalar. + c : array_like + Array of coefficients ordered so that the coefficients for terms of + degree i,j are contained in ``c[i,j]``. If `c` has dimension + greater than two the remaining indices enumerate multiple sets of + coefficients. + + Returns + ------- + values : ndarray, compatible object + The values of the two dimensional polynomial at points in the Cartesian + product of `x` and `y`. + + See Also + -------- + hermeval, hermeval2d, hermegrid2d, hermeval3d + + Notes + ----- + + .. versionadded:: 1.7.0 + + """ + return pu._gridnd(hermeval, c, x, y, z) + + +def hermevander(x, deg): + """Pseudo-Vandermonde matrix of given degree. + + Returns the pseudo-Vandermonde matrix of degree `deg` and sample points + `x`. The pseudo-Vandermonde matrix is defined by + + .. math:: V[..., i] = He_i(x), + + where `0 <= i <= deg`. The leading indices of `V` index the elements of + `x` and the last index is the degree of the HermiteE polynomial. + + If `c` is a 1-D array of coefficients of length `n + 1` and `V` is the + array ``V = hermevander(x, n)``, then ``np.dot(V, c)`` and + ``hermeval(x, c)`` are the same up to roundoff. This equivalence is + useful both for least squares fitting and for the evaluation of a large + number of HermiteE series of the same degree and sample points. + + Parameters + ---------- + x : array_like + Array of points. The dtype is converted to float64 or complex128 + depending on whether any of the elements are complex. If `x` is + scalar it is converted to a 1-D array. + deg : int + Degree of the resulting matrix. + + Returns + ------- + vander : ndarray + The pseudo-Vandermonde matrix. The shape of the returned matrix is + ``x.shape + (deg + 1,)``, where The last index is the degree of the + corresponding HermiteE polynomial. The dtype will be the same as + the converted `x`. + + Examples + -------- + >>> from numpy.polynomial.hermite_e import hermevander + >>> x = np.array([-1, 0, 1]) + >>> hermevander(x, 3) + array([[ 1., -1., 0., 2.], + [ 1., 0., -1., -0.], + [ 1., 1., 0., -2.]]) + + """ + ideg = pu._deprecate_as_int(deg, "deg") + if ideg < 0: + raise ValueError("deg must be non-negative") + + x = np.array(x, copy=False, ndmin=1) + 0.0 + dims = (ideg + 1,) + x.shape + dtyp = x.dtype + v = np.empty(dims, dtype=dtyp) + v[0] = x*0 + 1 + if ideg > 0: + v[1] = x + for i in range(2, ideg + 1): + v[i] = (v[i-1]*x - v[i-2]*(i - 1)) + return np.moveaxis(v, 0, -1) + + +def hermevander2d(x, y, deg): + """Pseudo-Vandermonde matrix of given degrees. + + Returns the pseudo-Vandermonde matrix of degrees `deg` and sample + points `(x, y)`. The pseudo-Vandermonde matrix is defined by + + .. math:: V[..., (deg[1] + 1)*i + j] = He_i(x) * He_j(y), + + where `0 <= i <= deg[0]` and `0 <= j <= deg[1]`. The leading indices of + `V` index the points `(x, y)` and the last index encodes the degrees of + the HermiteE polynomials. + + If ``V = hermevander2d(x, y, [xdeg, ydeg])``, then the columns of `V` + correspond to the elements of a 2-D coefficient array `c` of shape + (xdeg + 1, ydeg + 1) in the order + + .. math:: c_{00}, c_{01}, c_{02} ... , c_{10}, c_{11}, c_{12} ... + + and ``np.dot(V, c.flat)`` and ``hermeval2d(x, y, c)`` will be the same + up to roundoff. This equivalence is useful both for least squares + fitting and for the evaluation of a large number of 2-D HermiteE + series of the same degrees and sample points. + + Parameters + ---------- + x, y : array_like + Arrays of point coordinates, all of the same shape. The dtypes + will be converted to either float64 or complex128 depending on + whether any of the elements are complex. Scalars are converted to + 1-D arrays. + deg : list of ints + List of maximum degrees of the form [x_deg, y_deg]. + + Returns + ------- + vander2d : ndarray + The shape of the returned matrix is ``x.shape + (order,)``, where + :math:`order = (deg[0]+1)*(deg[1]+1)`. The dtype will be the same + as the converted `x` and `y`. + + See Also + -------- + hermevander, hermevander3d, hermeval2d, hermeval3d + + Notes + ----- + + .. versionadded:: 1.7.0 + + """ + return pu._vander_nd_flat((hermevander, hermevander), (x, y), deg) + + +def hermevander3d(x, y, z, deg): + """Pseudo-Vandermonde matrix of given degrees. + + Returns the pseudo-Vandermonde matrix of degrees `deg` and sample + points `(x, y, z)`. If `l, m, n` are the given degrees in `x, y, z`, + then Hehe pseudo-Vandermonde matrix is defined by + + .. math:: V[..., (m+1)(n+1)i + (n+1)j + k] = He_i(x)*He_j(y)*He_k(z), + + where `0 <= i <= l`, `0 <= j <= m`, and `0 <= j <= n`. The leading + indices of `V` index the points `(x, y, z)` and the last index encodes + the degrees of the HermiteE polynomials. + + If ``V = hermevander3d(x, y, z, [xdeg, ydeg, zdeg])``, then the columns + of `V` correspond to the elements of a 3-D coefficient array `c` of + shape (xdeg + 1, ydeg + 1, zdeg + 1) in the order + + .. math:: c_{000}, c_{001}, c_{002},... , c_{010}, c_{011}, c_{012},... + + and ``np.dot(V, c.flat)`` and ``hermeval3d(x, y, z, c)`` will be the + same up to roundoff. This equivalence is useful both for least squares + fitting and for the evaluation of a large number of 3-D HermiteE + series of the same degrees and sample points. + + Parameters + ---------- + x, y, z : array_like + Arrays of point coordinates, all of the same shape. The dtypes will + be converted to either float64 or complex128 depending on whether + any of the elements are complex. Scalars are converted to 1-D + arrays. + deg : list of ints + List of maximum degrees of the form [x_deg, y_deg, z_deg]. + + Returns + ------- + vander3d : ndarray + The shape of the returned matrix is ``x.shape + (order,)``, where + :math:`order = (deg[0]+1)*(deg[1]+1)*(deg[2]+1)`. The dtype will + be the same as the converted `x`, `y`, and `z`. + + See Also + -------- + hermevander, hermevander3d, hermeval2d, hermeval3d + + Notes + ----- + + .. versionadded:: 1.7.0 + + """ + return pu._vander_nd_flat((hermevander, hermevander, hermevander), (x, y, z), deg) + + +def hermefit(x, y, deg, rcond=None, full=False, w=None): + """ + Least squares fit of Hermite series to data. + + Return the coefficients of a HermiteE series of degree `deg` that is + the least squares fit to the data values `y` given at points `x`. If + `y` is 1-D the returned coefficients will also be 1-D. If `y` is 2-D + multiple fits are done, one for each column of `y`, and the resulting + coefficients are stored in the corresponding columns of a 2-D return. + The fitted polynomial(s) are in the form + + .. math:: p(x) = c_0 + c_1 * He_1(x) + ... + c_n * He_n(x), + + where `n` is `deg`. + + Parameters + ---------- + x : array_like, shape (M,) + x-coordinates of the M sample points ``(x[i], y[i])``. + y : array_like, shape (M,) or (M, K) + y-coordinates of the sample points. Several data sets of sample + points sharing the same x-coordinates can be fitted at once by + passing in a 2D-array that contains one dataset per column. + deg : int or 1-D array_like + Degree(s) of the fitting polynomials. If `deg` is a single integer + all terms up to and including the `deg`'th term are included in the + fit. For NumPy versions >= 1.11.0 a list of integers specifying the + degrees of the terms to include may be used instead. + rcond : float, optional + Relative condition number of the fit. Singular values smaller than + this relative to the largest singular value will be ignored. The + default value is len(x)*eps, where eps is the relative precision of + the float type, about 2e-16 in most cases. + full : bool, optional + Switch determining nature of return value. When it is False (the + default) just the coefficients are returned, when True diagnostic + information from the singular value decomposition is also returned. + w : array_like, shape (`M`,), optional + Weights. If not None, the contribution of each point + ``(x[i],y[i])`` to the fit is weighted by `w[i]`. Ideally the + weights are chosen so that the errors of the products ``w[i]*y[i]`` + all have the same variance. The default value is None. + + Returns + ------- + coef : ndarray, shape (M,) or (M, K) + Hermite coefficients ordered from low to high. If `y` was 2-D, + the coefficients for the data in column k of `y` are in column + `k`. + + [residuals, rank, singular_values, rcond] : list + These values are only returned if `full` = True + + resid -- sum of squared residuals of the least squares fit + rank -- the numerical rank of the scaled Vandermonde matrix + sv -- singular values of the scaled Vandermonde matrix + rcond -- value of `rcond`. + + For more details, see `numpy.linalg.lstsq`. + + Warns + ----- + RankWarning + The rank of the coefficient matrix in the least-squares fit is + deficient. The warning is only raised if `full` = False. The + warnings can be turned off by + + >>> import warnings + >>> warnings.simplefilter('ignore', np.RankWarning) + + See Also + -------- + numpy.polynomial.chebyshev.chebfit + numpy.polynomial.legendre.legfit + numpy.polynomial.polynomial.polyfit + numpy.polynomial.hermite.hermfit + numpy.polynomial.laguerre.lagfit + hermeval : Evaluates a Hermite series. + hermevander : pseudo Vandermonde matrix of Hermite series. + hermeweight : HermiteE weight function. + numpy.linalg.lstsq : Computes a least-squares fit from the matrix. + scipy.interpolate.UnivariateSpline : Computes spline fits. + + Notes + ----- + The solution is the coefficients of the HermiteE series `p` that + minimizes the sum of the weighted squared errors + + .. math:: E = \\sum_j w_j^2 * |y_j - p(x_j)|^2, + + where the :math:`w_j` are the weights. This problem is solved by + setting up the (typically) overdetermined matrix equation + + .. math:: V(x) * c = w * y, + + where `V` is the pseudo Vandermonde matrix of `x`, the elements of `c` + are the coefficients to be solved for, and the elements of `y` are the + observed values. This equation is then solved using the singular value + decomposition of `V`. + + If some of the singular values of `V` are so small that they are + neglected, then a `RankWarning` will be issued. This means that the + coefficient values may be poorly determined. Using a lower order fit + will usually get rid of the warning. The `rcond` parameter can also be + set to a value smaller than its default, but the resulting fit may be + spurious and have large contributions from roundoff error. + + Fits using HermiteE series are probably most useful when the data can + be approximated by ``sqrt(w(x)) * p(x)``, where `w(x)` is the HermiteE + weight. In that case the weight ``sqrt(w(x[i]))`` should be used + together with data values ``y[i]/sqrt(w(x[i]))``. The weight function is + available as `hermeweight`. + + References + ---------- + .. [1] Wikipedia, "Curve fitting", + https://en.wikipedia.org/wiki/Curve_fitting + + Examples + -------- + >>> from numpy.polynomial.hermite_e import hermefit, hermeval + >>> x = np.linspace(-10, 10) + >>> np.random.seed(123) + >>> err = np.random.randn(len(x))/10 + >>> y = hermeval(x, [1, 2, 3]) + err + >>> hermefit(x, y, 2) + array([ 1.01690445, 1.99951418, 2.99948696]) # may vary + + """ + return pu._fit(hermevander, x, y, deg, rcond, full, w) + + +def hermecompanion(c): + """ + Return the scaled companion matrix of c. + + The basis polynomials are scaled so that the companion matrix is + symmetric when `c` is an HermiteE basis polynomial. This provides + better eigenvalue estimates than the unscaled case and for basis + polynomials the eigenvalues are guaranteed to be real if + `numpy.linalg.eigvalsh` is used to obtain them. + + Parameters + ---------- + c : array_like + 1-D array of HermiteE series coefficients ordered from low to high + degree. + + Returns + ------- + mat : ndarray + Scaled companion matrix of dimensions (deg, deg). + + Notes + ----- + + .. versionadded:: 1.7.0 + + """ + # c is a trimmed copy + [c] = pu.as_series([c]) + if len(c) < 2: + raise ValueError('Series must have maximum degree of at least 1.') + if len(c) == 2: + return np.array([[-c[0]/c[1]]]) + + n = len(c) - 1 + mat = np.zeros((n, n), dtype=c.dtype) + scl = np.hstack((1., 1./np.sqrt(np.arange(n - 1, 0, -1)))) + scl = np.multiply.accumulate(scl)[::-1] + top = mat.reshape(-1)[1::n+1] + bot = mat.reshape(-1)[n::n+1] + top[...] = np.sqrt(np.arange(1, n)) + bot[...] = top + mat[:, -1] -= scl*c[:-1]/c[-1] + return mat + + +def hermeroots(c): + """ + Compute the roots of a HermiteE series. + + Return the roots (a.k.a. "zeros") of the polynomial + + .. math:: p(x) = \\sum_i c[i] * He_i(x). + + Parameters + ---------- + c : 1-D array_like + 1-D array of coefficients. + + Returns + ------- + out : ndarray + Array of the roots of the series. If all the roots are real, + then `out` is also real, otherwise it is complex. + + See Also + -------- + numpy.polynomial.polynomial.polyroots + numpy.polynomial.legendre.legroots + numpy.polynomial.laguerre.lagroots + numpy.polynomial.hermite.hermroots + numpy.polynomial.chebyshev.chebroots + + Notes + ----- + The root estimates are obtained as the eigenvalues of the companion + matrix, Roots far from the origin of the complex plane may have large + errors due to the numerical instability of the series for such + values. Roots with multiplicity greater than 1 will also show larger + errors as the value of the series near such points is relatively + insensitive to errors in the roots. Isolated roots near the origin can + be improved by a few iterations of Newton's method. + + The HermiteE series basis polynomials aren't powers of `x` so the + results of this function may seem unintuitive. + + Examples + -------- + >>> from numpy.polynomial.hermite_e import hermeroots, hermefromroots + >>> coef = hermefromroots([-1, 0, 1]) + >>> coef + array([0., 2., 0., 1.]) + >>> hermeroots(coef) + array([-1., 0., 1.]) # may vary + + """ + # c is a trimmed copy + [c] = pu.as_series([c]) + if len(c) <= 1: + return np.array([], dtype=c.dtype) + if len(c) == 2: + return np.array([-c[0]/c[1]]) + + # rotated companion matrix reduces error + m = hermecompanion(c)[::-1,::-1] + r = la.eigvals(m) + r.sort() + return r + + +def _normed_hermite_e_n(x, n): + """ + Evaluate a normalized HermiteE polynomial. + + Compute the value of the normalized HermiteE polynomial of degree ``n`` + at the points ``x``. + + + Parameters + ---------- + x : ndarray of double. + Points at which to evaluate the function + n : int + Degree of the normalized HermiteE function to be evaluated. + + Returns + ------- + values : ndarray + The shape of the return value is described above. + + Notes + ----- + .. versionadded:: 1.10.0 + + This function is needed for finding the Gauss points and integration + weights for high degrees. The values of the standard HermiteE functions + overflow when n >= 207. + + """ + if n == 0: + return np.full(x.shape, 1/np.sqrt(np.sqrt(2*np.pi))) + + c0 = 0. + c1 = 1./np.sqrt(np.sqrt(2*np.pi)) + nd = float(n) + for i in range(n - 1): + tmp = c0 + c0 = -c1*np.sqrt((nd - 1.)/nd) + c1 = tmp + c1*x*np.sqrt(1./nd) + nd = nd - 1.0 + return c0 + c1*x + + +def hermegauss(deg): + """ + Gauss-HermiteE quadrature. + + Computes the sample points and weights for Gauss-HermiteE quadrature. + These sample points and weights will correctly integrate polynomials of + degree :math:`2*deg - 1` or less over the interval :math:`[-\\inf, \\inf]` + with the weight function :math:`f(x) = \\exp(-x^2/2)`. + + Parameters + ---------- + deg : int + Number of sample points and weights. It must be >= 1. + + Returns + ------- + x : ndarray + 1-D ndarray containing the sample points. + y : ndarray + 1-D ndarray containing the weights. + + Notes + ----- + + .. versionadded:: 1.7.0 + + The results have only been tested up to degree 100, higher degrees may + be problematic. The weights are determined by using the fact that + + .. math:: w_k = c / (He'_n(x_k) * He_{n-1}(x_k)) + + where :math:`c` is a constant independent of :math:`k` and :math:`x_k` + is the k'th root of :math:`He_n`, and then scaling the results to get + the right value when integrating 1. + + """ + ideg = pu._deprecate_as_int(deg, "deg") + if ideg <= 0: + raise ValueError("deg must be a positive integer") + + # first approximation of roots. We use the fact that the companion + # matrix is symmetric in this case in order to obtain better zeros. + c = np.array([0]*deg + [1]) + m = hermecompanion(c) + x = la.eigvalsh(m) + + # improve roots by one application of Newton + dy = _normed_hermite_e_n(x, ideg) + df = _normed_hermite_e_n(x, ideg - 1) * np.sqrt(ideg) + x -= dy/df + + # compute the weights. We scale the factor to avoid possible numerical + # overflow. + fm = _normed_hermite_e_n(x, ideg - 1) + fm /= np.abs(fm).max() + w = 1/(fm * fm) + + # for Hermite_e we can also symmetrize + w = (w + w[::-1])/2 + x = (x - x[::-1])/2 + + # scale w to get the right value + w *= np.sqrt(2*np.pi) / w.sum() + + return x, w + + +def hermeweight(x): + """Weight function of the Hermite_e polynomials. + + The weight function is :math:`\\exp(-x^2/2)` and the interval of + integration is :math:`[-\\inf, \\inf]`. the HermiteE polynomials are + orthogonal, but not normalized, with respect to this weight function. + + Parameters + ---------- + x : array_like + Values at which the weight function will be computed. + + Returns + ------- + w : ndarray + The weight function at `x`. + + Notes + ----- + + .. versionadded:: 1.7.0 + + """ + w = np.exp(-.5*x**2) + return w + + +# +# HermiteE series class +# + +class HermiteE(ABCPolyBase): + """An HermiteE series class. + + The HermiteE class provides the standard Python numerical methods + '+', '-', '*', '//', '%', 'divmod', '**', and '()' as well as the + attributes and methods listed in the `ABCPolyBase` documentation. + + Parameters + ---------- + coef : array_like + HermiteE coefficients in order of increasing degree, i.e, + ``(1, 2, 3)`` gives ``1*He_0(x) + 2*He_1(X) + 3*He_2(x)``. + domain : (2,) array_like, optional + Domain to use. The interval ``[domain[0], domain[1]]`` is mapped + to the interval ``[window[0], window[1]]`` by shifting and scaling. + The default value is [-1, 1]. + window : (2,) array_like, optional + Window, see `domain` for its use. The default value is [-1, 1]. + + .. versionadded:: 1.6.0 + + """ + # Virtual Functions + _add = staticmethod(hermeadd) + _sub = staticmethod(hermesub) + _mul = staticmethod(hermemul) + _div = staticmethod(hermediv) + _pow = staticmethod(hermepow) + _val = staticmethod(hermeval) + _int = staticmethod(hermeint) + _der = staticmethod(hermeder) + _fit = staticmethod(hermefit) + _line = staticmethod(hermeline) + _roots = staticmethod(hermeroots) + _fromroots = staticmethod(hermefromroots) + + # Virtual properties + domain = np.array(hermedomain) + window = np.array(hermedomain) + basis_name = 'He' diff --git a/venv/Lib/site-packages/numpy/polynomial/laguerre.py b/venv/Lib/site-packages/numpy/polynomial/laguerre.py new file mode 100644 index 0000000..9cff0b7 --- /dev/null +++ b/venv/Lib/site-packages/numpy/polynomial/laguerre.py @@ -0,0 +1,1644 @@ +""" +================================================== +Laguerre Series (:mod:`numpy.polynomial.laguerre`) +================================================== + +This module provides a number of objects (mostly functions) useful for +dealing with Laguerre series, including a `Laguerre` class that +encapsulates the usual arithmetic operations. (General information +on how this module represents and works with such polynomials is in the +docstring for its "parent" sub-package, `numpy.polynomial`). + +Classes +------- +.. autosummary:: + :toctree: generated/ + + Laguerre + +Constants +--------- +.. autosummary:: + :toctree: generated/ + + lagdomain + lagzero + lagone + lagx + +Arithmetic +---------- +.. autosummary:: + :toctree: generated/ + + lagadd + lagsub + lagmulx + lagmul + lagdiv + lagpow + lagval + lagval2d + lagval3d + laggrid2d + laggrid3d + +Calculus +-------- +.. autosummary:: + :toctree: generated/ + + lagder + lagint + +Misc Functions +-------------- +.. autosummary:: + :toctree: generated/ + + lagfromroots + lagroots + lagvander + lagvander2d + lagvander3d + laggauss + lagweight + lagcompanion + lagfit + lagtrim + lagline + lag2poly + poly2lag + +See also +-------- +`numpy.polynomial` + +""" +import numpy as np +import numpy.linalg as la +from numpy.core.multiarray import normalize_axis_index + +from . import polyutils as pu +from ._polybase import ABCPolyBase + +__all__ = [ + 'lagzero', 'lagone', 'lagx', 'lagdomain', 'lagline', 'lagadd', + 'lagsub', 'lagmulx', 'lagmul', 'lagdiv', 'lagpow', 'lagval', 'lagder', + 'lagint', 'lag2poly', 'poly2lag', 'lagfromroots', 'lagvander', + 'lagfit', 'lagtrim', 'lagroots', 'Laguerre', 'lagval2d', 'lagval3d', + 'laggrid2d', 'laggrid3d', 'lagvander2d', 'lagvander3d', 'lagcompanion', + 'laggauss', 'lagweight'] + +lagtrim = pu.trimcoef + + +def poly2lag(pol): + """ + poly2lag(pol) + + Convert a polynomial to a Laguerre series. + + Convert an array representing the coefficients of a polynomial (relative + to the "standard" basis) ordered from lowest degree to highest, to an + array of the coefficients of the equivalent Laguerre series, ordered + from lowest to highest degree. + + Parameters + ---------- + pol : array_like + 1-D array containing the polynomial coefficients + + Returns + ------- + c : ndarray + 1-D array containing the coefficients of the equivalent Laguerre + series. + + See Also + -------- + lag2poly + + Notes + ----- + The easy way to do conversions between polynomial basis sets + is to use the convert method of a class instance. + + Examples + -------- + >>> from numpy.polynomial.laguerre import poly2lag + >>> poly2lag(np.arange(4)) + array([ 23., -63., 58., -18.]) + + """ + [pol] = pu.as_series([pol]) + res = 0 + for p in pol[::-1]: + res = lagadd(lagmulx(res), p) + return res + + +def lag2poly(c): + """ + Convert a Laguerre series to a polynomial. + + Convert an array representing the coefficients of a Laguerre series, + ordered from lowest degree to highest, to an array of the coefficients + of the equivalent polynomial (relative to the "standard" basis) ordered + from lowest to highest degree. + + Parameters + ---------- + c : array_like + 1-D array containing the Laguerre series coefficients, ordered + from lowest order term to highest. + + Returns + ------- + pol : ndarray + 1-D array containing the coefficients of the equivalent polynomial + (relative to the "standard" basis) ordered from lowest order term + to highest. + + See Also + -------- + poly2lag + + Notes + ----- + The easy way to do conversions between polynomial basis sets + is to use the convert method of a class instance. + + Examples + -------- + >>> from numpy.polynomial.laguerre import lag2poly + >>> lag2poly([ 23., -63., 58., -18.]) + array([0., 1., 2., 3.]) + + """ + from .polynomial import polyadd, polysub, polymulx + + [c] = pu.as_series([c]) + n = len(c) + if n == 1: + return c + else: + c0 = c[-2] + c1 = c[-1] + # i is the current degree of c1 + for i in range(n - 1, 1, -1): + tmp = c0 + c0 = polysub(c[i - 2], (c1*(i - 1))/i) + c1 = polyadd(tmp, polysub((2*i - 1)*c1, polymulx(c1))/i) + return polyadd(c0, polysub(c1, polymulx(c1))) + +# +# These are constant arrays are of integer type so as to be compatible +# with the widest range of other types, such as Decimal. +# + +# Laguerre +lagdomain = np.array([0, 1]) + +# Laguerre coefficients representing zero. +lagzero = np.array([0]) + +# Laguerre coefficients representing one. +lagone = np.array([1]) + +# Laguerre coefficients representing the identity x. +lagx = np.array([1, -1]) + + +def lagline(off, scl): + """ + Laguerre series whose graph is a straight line. + + Parameters + ---------- + off, scl : scalars + The specified line is given by ``off + scl*x``. + + Returns + ------- + y : ndarray + This module's representation of the Laguerre series for + ``off + scl*x``. + + See Also + -------- + numpy.polynomial.polynomial.polyline + numpy.polynomial.chebyshev.chebline + numpy.polynomial.legendre.legline + numpy.polynomial.hermite.hermline + numpy.polynomial.hermite_e.hermeline + + Examples + -------- + >>> from numpy.polynomial.laguerre import lagline, lagval + >>> lagval(0,lagline(3, 2)) + 3.0 + >>> lagval(1,lagline(3, 2)) + 5.0 + + """ + if scl != 0: + return np.array([off + scl, -scl]) + else: + return np.array([off]) + + +def lagfromroots(roots): + """ + Generate a Laguerre series with given roots. + + The function returns the coefficients of the polynomial + + .. math:: p(x) = (x - r_0) * (x - r_1) * ... * (x - r_n), + + in Laguerre form, where the `r_n` are the roots specified in `roots`. + If a zero has multiplicity n, then it must appear in `roots` n times. + For instance, if 2 is a root of multiplicity three and 3 is a root of + multiplicity 2, then `roots` looks something like [2, 2, 2, 3, 3]. The + roots can appear in any order. + + If the returned coefficients are `c`, then + + .. math:: p(x) = c_0 + c_1 * L_1(x) + ... + c_n * L_n(x) + + The coefficient of the last term is not generally 1 for monic + polynomials in Laguerre form. + + Parameters + ---------- + roots : array_like + Sequence containing the roots. + + Returns + ------- + out : ndarray + 1-D array of coefficients. If all roots are real then `out` is a + real array, if some of the roots are complex, then `out` is complex + even if all the coefficients in the result are real (see Examples + below). + + See Also + -------- + numpy.polynomial.polynomial.polyfromroots + numpy.polynomial.legendre.legfromroots + numpy.polynomial.chebyshev.chebfromroots + numpy.polynomial.hermite.hermfromroots + numpy.polynomial.hermite_e.hermefromroots + + Examples + -------- + >>> from numpy.polynomial.laguerre import lagfromroots, lagval + >>> coef = lagfromroots((-1, 0, 1)) + >>> lagval((-1, 0, 1), coef) + array([0., 0., 0.]) + >>> coef = lagfromroots((-1j, 1j)) + >>> lagval((-1j, 1j), coef) + array([0.+0.j, 0.+0.j]) + + """ + return pu._fromroots(lagline, lagmul, roots) + + +def lagadd(c1, c2): + """ + Add one Laguerre series to another. + + Returns the sum of two Laguerre series `c1` + `c2`. The arguments + are sequences of coefficients ordered from lowest order term to + highest, i.e., [1,2,3] represents the series ``P_0 + 2*P_1 + 3*P_2``. + + Parameters + ---------- + c1, c2 : array_like + 1-D arrays of Laguerre series coefficients ordered from low to + high. + + Returns + ------- + out : ndarray + Array representing the Laguerre series of their sum. + + See Also + -------- + lagsub, lagmulx, lagmul, lagdiv, lagpow + + Notes + ----- + Unlike multiplication, division, etc., the sum of two Laguerre series + is a Laguerre series (without having to "reproject" the result onto + the basis set) so addition, just like that of "standard" polynomials, + is simply "component-wise." + + Examples + -------- + >>> from numpy.polynomial.laguerre import lagadd + >>> lagadd([1, 2, 3], [1, 2, 3, 4]) + array([2., 4., 6., 4.]) + + + """ + return pu._add(c1, c2) + + +def lagsub(c1, c2): + """ + Subtract one Laguerre series from another. + + Returns the difference of two Laguerre series `c1` - `c2`. The + sequences of coefficients are from lowest order term to highest, i.e., + [1,2,3] represents the series ``P_0 + 2*P_1 + 3*P_2``. + + Parameters + ---------- + c1, c2 : array_like + 1-D arrays of Laguerre series coefficients ordered from low to + high. + + Returns + ------- + out : ndarray + Of Laguerre series coefficients representing their difference. + + See Also + -------- + lagadd, lagmulx, lagmul, lagdiv, lagpow + + Notes + ----- + Unlike multiplication, division, etc., the difference of two Laguerre + series is a Laguerre series (without having to "reproject" the result + onto the basis set) so subtraction, just like that of "standard" + polynomials, is simply "component-wise." + + Examples + -------- + >>> from numpy.polynomial.laguerre import lagsub + >>> lagsub([1, 2, 3, 4], [1, 2, 3]) + array([0., 0., 0., 4.]) + + """ + return pu._sub(c1, c2) + + +def lagmulx(c): + """Multiply a Laguerre series by x. + + Multiply the Laguerre series `c` by x, where x is the independent + variable. + + + Parameters + ---------- + c : array_like + 1-D array of Laguerre series coefficients ordered from low to + high. + + Returns + ------- + out : ndarray + Array representing the result of the multiplication. + + See Also + -------- + lagadd, lagsub, lagmul, lagdiv, lagpow + + Notes + ----- + The multiplication uses the recursion relationship for Laguerre + polynomials in the form + + .. math:: + + xP_i(x) = (-(i + 1)*P_{i + 1}(x) + (2i + 1)P_{i}(x) - iP_{i - 1}(x)) + + Examples + -------- + >>> from numpy.polynomial.laguerre import lagmulx + >>> lagmulx([1, 2, 3]) + array([-1., -1., 11., -9.]) + + """ + # c is a trimmed copy + [c] = pu.as_series([c]) + # The zero series needs special treatment + if len(c) == 1 and c[0] == 0: + return c + + prd = np.empty(len(c) + 1, dtype=c.dtype) + prd[0] = c[0] + prd[1] = -c[0] + for i in range(1, len(c)): + prd[i + 1] = -c[i]*(i + 1) + prd[i] += c[i]*(2*i + 1) + prd[i - 1] -= c[i]*i + return prd + + +def lagmul(c1, c2): + """ + Multiply one Laguerre series by another. + + Returns the product of two Laguerre series `c1` * `c2`. The arguments + are sequences of coefficients, from lowest order "term" to highest, + e.g., [1,2,3] represents the series ``P_0 + 2*P_1 + 3*P_2``. + + Parameters + ---------- + c1, c2 : array_like + 1-D arrays of Laguerre series coefficients ordered from low to + high. + + Returns + ------- + out : ndarray + Of Laguerre series coefficients representing their product. + + See Also + -------- + lagadd, lagsub, lagmulx, lagdiv, lagpow + + Notes + ----- + In general, the (polynomial) product of two C-series results in terms + that are not in the Laguerre polynomial basis set. Thus, to express + the product as a Laguerre series, it is necessary to "reproject" the + product onto said basis set, which may produce "unintuitive" (but + correct) results; see Examples section below. + + Examples + -------- + >>> from numpy.polynomial.laguerre import lagmul + >>> lagmul([1, 2, 3], [0, 1, 2]) + array([ 8., -13., 38., -51., 36.]) + + """ + # s1, s2 are trimmed copies + [c1, c2] = pu.as_series([c1, c2]) + + if len(c1) > len(c2): + c = c2 + xs = c1 + else: + c = c1 + xs = c2 + + if len(c) == 1: + c0 = c[0]*xs + c1 = 0 + elif len(c) == 2: + c0 = c[0]*xs + c1 = c[1]*xs + else: + nd = len(c) + c0 = c[-2]*xs + c1 = c[-1]*xs + for i in range(3, len(c) + 1): + tmp = c0 + nd = nd - 1 + c0 = lagsub(c[-i]*xs, (c1*(nd - 1))/nd) + c1 = lagadd(tmp, lagsub((2*nd - 1)*c1, lagmulx(c1))/nd) + return lagadd(c0, lagsub(c1, lagmulx(c1))) + + +def lagdiv(c1, c2): + """ + Divide one Laguerre series by another. + + Returns the quotient-with-remainder of two Laguerre series + `c1` / `c2`. The arguments are sequences of coefficients from lowest + order "term" to highest, e.g., [1,2,3] represents the series + ``P_0 + 2*P_1 + 3*P_2``. + + Parameters + ---------- + c1, c2 : array_like + 1-D arrays of Laguerre series coefficients ordered from low to + high. + + Returns + ------- + [quo, rem] : ndarrays + Of Laguerre series coefficients representing the quotient and + remainder. + + See Also + -------- + lagadd, lagsub, lagmulx, lagmul, lagpow + + Notes + ----- + In general, the (polynomial) division of one Laguerre series by another + results in quotient and remainder terms that are not in the Laguerre + polynomial basis set. Thus, to express these results as a Laguerre + series, it is necessary to "reproject" the results onto the Laguerre + basis set, which may produce "unintuitive" (but correct) results; see + Examples section below. + + Examples + -------- + >>> from numpy.polynomial.laguerre import lagdiv + >>> lagdiv([ 8., -13., 38., -51., 36.], [0, 1, 2]) + (array([1., 2., 3.]), array([0.])) + >>> lagdiv([ 9., -12., 38., -51., 36.], [0, 1, 2]) + (array([1., 2., 3.]), array([1., 1.])) + + """ + return pu._div(lagmul, c1, c2) + + +def lagpow(c, pow, maxpower=16): + """Raise a Laguerre series to a power. + + Returns the Laguerre series `c` raised to the power `pow`. The + argument `c` is a sequence of coefficients ordered from low to high. + i.e., [1,2,3] is the series ``P_0 + 2*P_1 + 3*P_2.`` + + Parameters + ---------- + c : array_like + 1-D array of Laguerre series coefficients ordered from low to + high. + pow : integer + Power to which the series will be raised + maxpower : integer, optional + Maximum power allowed. This is mainly to limit growth of the series + to unmanageable size. Default is 16 + + Returns + ------- + coef : ndarray + Laguerre series of power. + + See Also + -------- + lagadd, lagsub, lagmulx, lagmul, lagdiv + + Examples + -------- + >>> from numpy.polynomial.laguerre import lagpow + >>> lagpow([1, 2, 3], 2) + array([ 14., -16., 56., -72., 54.]) + + """ + return pu._pow(lagmul, c, pow, maxpower) + + +def lagder(c, m=1, scl=1, axis=0): + """ + Differentiate a Laguerre series. + + Returns the Laguerre series coefficients `c` differentiated `m` times + along `axis`. At each iteration the result is multiplied by `scl` (the + scaling factor is for use in a linear change of variable). The argument + `c` is an array of coefficients from low to high degree along each + axis, e.g., [1,2,3] represents the series ``1*L_0 + 2*L_1 + 3*L_2`` + while [[1,2],[1,2]] represents ``1*L_0(x)*L_0(y) + 1*L_1(x)*L_0(y) + + 2*L_0(x)*L_1(y) + 2*L_1(x)*L_1(y)`` if axis=0 is ``x`` and axis=1 is + ``y``. + + Parameters + ---------- + c : array_like + Array of Laguerre series coefficients. If `c` is multidimensional + the different axis correspond to different variables with the + degree in each axis given by the corresponding index. + m : int, optional + Number of derivatives taken, must be non-negative. (Default: 1) + scl : scalar, optional + Each differentiation is multiplied by `scl`. The end result is + multiplication by ``scl**m``. This is for use in a linear change of + variable. (Default: 1) + axis : int, optional + Axis over which the derivative is taken. (Default: 0). + + .. versionadded:: 1.7.0 + + Returns + ------- + der : ndarray + Laguerre series of the derivative. + + See Also + -------- + lagint + + Notes + ----- + In general, the result of differentiating a Laguerre series does not + resemble the same operation on a power series. Thus the result of this + function may be "unintuitive," albeit correct; see Examples section + below. + + Examples + -------- + >>> from numpy.polynomial.laguerre import lagder + >>> lagder([ 1., 1., 1., -3.]) + array([1., 2., 3.]) + >>> lagder([ 1., 0., 0., -4., 3.], m=2) + array([1., 2., 3.]) + + """ + c = np.array(c, ndmin=1, copy=True) + if c.dtype.char in '?bBhHiIlLqQpP': + c = c.astype(np.double) + + cnt = pu._deprecate_as_int(m, "the order of derivation") + iaxis = pu._deprecate_as_int(axis, "the axis") + if cnt < 0: + raise ValueError("The order of derivation must be non-negative") + iaxis = normalize_axis_index(iaxis, c.ndim) + + if cnt == 0: + return c + + c = np.moveaxis(c, iaxis, 0) + n = len(c) + if cnt >= n: + c = c[:1]*0 + else: + for i in range(cnt): + n = n - 1 + c *= scl + der = np.empty((n,) + c.shape[1:], dtype=c.dtype) + for j in range(n, 1, -1): + der[j - 1] = -c[j] + c[j - 1] += c[j] + der[0] = -c[1] + c = der + c = np.moveaxis(c, 0, iaxis) + return c + + +def lagint(c, m=1, k=[], lbnd=0, scl=1, axis=0): + """ + Integrate a Laguerre series. + + Returns the Laguerre series coefficients `c` integrated `m` times from + `lbnd` along `axis`. At each iteration the resulting series is + **multiplied** by `scl` and an integration constant, `k`, is added. + The scaling factor is for use in a linear change of variable. ("Buyer + beware": note that, depending on what one is doing, one may want `scl` + to be the reciprocal of what one might expect; for more information, + see the Notes section below.) The argument `c` is an array of + coefficients from low to high degree along each axis, e.g., [1,2,3] + represents the series ``L_0 + 2*L_1 + 3*L_2`` while [[1,2],[1,2]] + represents ``1*L_0(x)*L_0(y) + 1*L_1(x)*L_0(y) + 2*L_0(x)*L_1(y) + + 2*L_1(x)*L_1(y)`` if axis=0 is ``x`` and axis=1 is ``y``. + + + Parameters + ---------- + c : array_like + Array of Laguerre series coefficients. If `c` is multidimensional + the different axis correspond to different variables with the + degree in each axis given by the corresponding index. + m : int, optional + Order of integration, must be positive. (Default: 1) + k : {[], list, scalar}, optional + Integration constant(s). The value of the first integral at + ``lbnd`` is the first value in the list, the value of the second + integral at ``lbnd`` is the second value, etc. If ``k == []`` (the + default), all constants are set to zero. If ``m == 1``, a single + scalar can be given instead of a list. + lbnd : scalar, optional + The lower bound of the integral. (Default: 0) + scl : scalar, optional + Following each integration the result is *multiplied* by `scl` + before the integration constant is added. (Default: 1) + axis : int, optional + Axis over which the integral is taken. (Default: 0). + + .. versionadded:: 1.7.0 + + Returns + ------- + S : ndarray + Laguerre series coefficients of the integral. + + Raises + ------ + ValueError + If ``m < 0``, ``len(k) > m``, ``np.ndim(lbnd) != 0``, or + ``np.ndim(scl) != 0``. + + See Also + -------- + lagder + + Notes + ----- + Note that the result of each integration is *multiplied* by `scl`. + Why is this important to note? Say one is making a linear change of + variable :math:`u = ax + b` in an integral relative to `x`. Then + :math:`dx = du/a`, so one will need to set `scl` equal to + :math:`1/a` - perhaps not what one would have first thought. + + Also note that, in general, the result of integrating a C-series needs + to be "reprojected" onto the C-series basis set. Thus, typically, + the result of this function is "unintuitive," albeit correct; see + Examples section below. + + Examples + -------- + >>> from numpy.polynomial.laguerre import lagint + >>> lagint([1,2,3]) + array([ 1., 1., 1., -3.]) + >>> lagint([1,2,3], m=2) + array([ 1., 0., 0., -4., 3.]) + >>> lagint([1,2,3], k=1) + array([ 2., 1., 1., -3.]) + >>> lagint([1,2,3], lbnd=-1) + array([11.5, 1. , 1. , -3. ]) + >>> lagint([1,2], m=2, k=[1,2], lbnd=-1) + array([ 11.16666667, -5. , -3. , 2. ]) # may vary + + """ + c = np.array(c, ndmin=1, copy=True) + if c.dtype.char in '?bBhHiIlLqQpP': + c = c.astype(np.double) + if not np.iterable(k): + k = [k] + cnt = pu._deprecate_as_int(m, "the order of integration") + iaxis = pu._deprecate_as_int(axis, "the axis") + if cnt < 0: + raise ValueError("The order of integration must be non-negative") + if len(k) > cnt: + raise ValueError("Too many integration constants") + if np.ndim(lbnd) != 0: + raise ValueError("lbnd must be a scalar.") + if np.ndim(scl) != 0: + raise ValueError("scl must be a scalar.") + iaxis = normalize_axis_index(iaxis, c.ndim) + + if cnt == 0: + return c + + c = np.moveaxis(c, iaxis, 0) + k = list(k) + [0]*(cnt - len(k)) + for i in range(cnt): + n = len(c) + c *= scl + if n == 1 and np.all(c[0] == 0): + c[0] += k[i] + else: + tmp = np.empty((n + 1,) + c.shape[1:], dtype=c.dtype) + tmp[0] = c[0] + tmp[1] = -c[0] + for j in range(1, n): + tmp[j] += c[j] + tmp[j + 1] = -c[j] + tmp[0] += k[i] - lagval(lbnd, tmp) + c = tmp + c = np.moveaxis(c, 0, iaxis) + return c + + +def lagval(x, c, tensor=True): + """ + Evaluate a Laguerre series at points x. + + If `c` is of length `n + 1`, this function returns the value: + + .. math:: p(x) = c_0 * L_0(x) + c_1 * L_1(x) + ... + c_n * L_n(x) + + The parameter `x` is converted to an array only if it is a tuple or a + list, otherwise it is treated as a scalar. In either case, either `x` + or its elements must support multiplication and addition both with + themselves and with the elements of `c`. + + If `c` is a 1-D array, then `p(x)` will have the same shape as `x`. If + `c` is multidimensional, then the shape of the result depends on the + value of `tensor`. If `tensor` is true the shape will be c.shape[1:] + + x.shape. If `tensor` is false the shape will be c.shape[1:]. Note that + scalars have shape (,). + + Trailing zeros in the coefficients will be used in the evaluation, so + they should be avoided if efficiency is a concern. + + Parameters + ---------- + x : array_like, compatible object + If `x` is a list or tuple, it is converted to an ndarray, otherwise + it is left unchanged and treated as a scalar. In either case, `x` + or its elements must support addition and multiplication with + with themselves and with the elements of `c`. + c : array_like + Array of coefficients ordered so that the coefficients for terms of + degree n are contained in c[n]. If `c` is multidimensional the + remaining indices enumerate multiple polynomials. In the two + dimensional case the coefficients may be thought of as stored in + the columns of `c`. + tensor : boolean, optional + If True, the shape of the coefficient array is extended with ones + on the right, one for each dimension of `x`. Scalars have dimension 0 + for this action. The result is that every column of coefficients in + `c` is evaluated for every element of `x`. If False, `x` is broadcast + over the columns of `c` for the evaluation. This keyword is useful + when `c` is multidimensional. The default value is True. + + .. versionadded:: 1.7.0 + + Returns + ------- + values : ndarray, algebra_like + The shape of the return value is described above. + + See Also + -------- + lagval2d, laggrid2d, lagval3d, laggrid3d + + Notes + ----- + The evaluation uses Clenshaw recursion, aka synthetic division. + + Examples + -------- + >>> from numpy.polynomial.laguerre import lagval + >>> coef = [1,2,3] + >>> lagval(1, coef) + -0.5 + >>> lagval([[1,2],[3,4]], coef) + array([[-0.5, -4. ], + [-4.5, -2. ]]) + + """ + c = np.array(c, ndmin=1, copy=False) + if c.dtype.char in '?bBhHiIlLqQpP': + c = c.astype(np.double) + if isinstance(x, (tuple, list)): + x = np.asarray(x) + if isinstance(x, np.ndarray) and tensor: + c = c.reshape(c.shape + (1,)*x.ndim) + + if len(c) == 1: + c0 = c[0] + c1 = 0 + elif len(c) == 2: + c0 = c[0] + c1 = c[1] + else: + nd = len(c) + c0 = c[-2] + c1 = c[-1] + for i in range(3, len(c) + 1): + tmp = c0 + nd = nd - 1 + c0 = c[-i] - (c1*(nd - 1))/nd + c1 = tmp + (c1*((2*nd - 1) - x))/nd + return c0 + c1*(1 - x) + + +def lagval2d(x, y, c): + """ + Evaluate a 2-D Laguerre series at points (x, y). + + This function returns the values: + + .. math:: p(x,y) = \\sum_{i,j} c_{i,j} * L_i(x) * L_j(y) + + The parameters `x` and `y` are converted to arrays only if they are + tuples or a lists, otherwise they are treated as a scalars and they + must have the same shape after conversion. In either case, either `x` + and `y` or their elements must support multiplication and addition both + with themselves and with the elements of `c`. + + If `c` is a 1-D array a one is implicitly appended to its shape to make + it 2-D. The shape of the result will be c.shape[2:] + x.shape. + + Parameters + ---------- + x, y : array_like, compatible objects + The two dimensional series is evaluated at the points `(x, y)`, + where `x` and `y` must have the same shape. If `x` or `y` is a list + or tuple, it is first converted to an ndarray, otherwise it is left + unchanged and if it isn't an ndarray it is treated as a scalar. + c : array_like + Array of coefficients ordered so that the coefficient of the term + of multi-degree i,j is contained in ``c[i,j]``. If `c` has + dimension greater than two the remaining indices enumerate multiple + sets of coefficients. + + Returns + ------- + values : ndarray, compatible object + The values of the two dimensional polynomial at points formed with + pairs of corresponding values from `x` and `y`. + + See Also + -------- + lagval, laggrid2d, lagval3d, laggrid3d + + Notes + ----- + + .. versionadded:: 1.7.0 + + """ + return pu._valnd(lagval, c, x, y) + + +def laggrid2d(x, y, c): + """ + Evaluate a 2-D Laguerre series on the Cartesian product of x and y. + + This function returns the values: + + .. math:: p(a,b) = \\sum_{i,j} c_{i,j} * L_i(a) * L_j(b) + + where the points `(a, b)` consist of all pairs formed by taking + `a` from `x` and `b` from `y`. The resulting points form a grid with + `x` in the first dimension and `y` in the second. + + The parameters `x` and `y` are converted to arrays only if they are + tuples or a lists, otherwise they are treated as a scalars. In either + case, either `x` and `y` or their elements must support multiplication + and addition both with themselves and with the elements of `c`. + + If `c` has fewer than two dimensions, ones are implicitly appended to + its shape to make it 2-D. The shape of the result will be c.shape[2:] + + x.shape + y.shape. + + Parameters + ---------- + x, y : array_like, compatible objects + The two dimensional series is evaluated at the points in the + Cartesian product of `x` and `y`. If `x` or `y` is a list or + tuple, it is first converted to an ndarray, otherwise it is left + unchanged and, if it isn't an ndarray, it is treated as a scalar. + c : array_like + Array of coefficients ordered so that the coefficient of the term of + multi-degree i,j is contained in `c[i,j]`. If `c` has dimension + greater than two the remaining indices enumerate multiple sets of + coefficients. + + Returns + ------- + values : ndarray, compatible object + The values of the two dimensional Chebyshev series at points in the + Cartesian product of `x` and `y`. + + See Also + -------- + lagval, lagval2d, lagval3d, laggrid3d + + Notes + ----- + + .. versionadded:: 1.7.0 + + """ + return pu._gridnd(lagval, c, x, y) + + +def lagval3d(x, y, z, c): + """ + Evaluate a 3-D Laguerre series at points (x, y, z). + + This function returns the values: + + .. math:: p(x,y,z) = \\sum_{i,j,k} c_{i,j,k} * L_i(x) * L_j(y) * L_k(z) + + The parameters `x`, `y`, and `z` are converted to arrays only if + they are tuples or a lists, otherwise they are treated as a scalars and + they must have the same shape after conversion. In either case, either + `x`, `y`, and `z` or their elements must support multiplication and + addition both with themselves and with the elements of `c`. + + If `c` has fewer than 3 dimensions, ones are implicitly appended to its + shape to make it 3-D. The shape of the result will be c.shape[3:] + + x.shape. + + Parameters + ---------- + x, y, z : array_like, compatible object + The three dimensional series is evaluated at the points + `(x, y, z)`, where `x`, `y`, and `z` must have the same shape. If + any of `x`, `y`, or `z` is a list or tuple, it is first converted + to an ndarray, otherwise it is left unchanged and if it isn't an + ndarray it is treated as a scalar. + c : array_like + Array of coefficients ordered so that the coefficient of the term of + multi-degree i,j,k is contained in ``c[i,j,k]``. If `c` has dimension + greater than 3 the remaining indices enumerate multiple sets of + coefficients. + + Returns + ------- + values : ndarray, compatible object + The values of the multidimension polynomial on points formed with + triples of corresponding values from `x`, `y`, and `z`. + + See Also + -------- + lagval, lagval2d, laggrid2d, laggrid3d + + Notes + ----- + + .. versionadded:: 1.7.0 + + """ + return pu._valnd(lagval, c, x, y, z) + + +def laggrid3d(x, y, z, c): + """ + Evaluate a 3-D Laguerre series on the Cartesian product of x, y, and z. + + This function returns the values: + + .. math:: p(a,b,c) = \\sum_{i,j,k} c_{i,j,k} * L_i(a) * L_j(b) * L_k(c) + + where the points `(a, b, c)` consist of all triples formed by taking + `a` from `x`, `b` from `y`, and `c` from `z`. The resulting points form + a grid with `x` in the first dimension, `y` in the second, and `z` in + the third. + + The parameters `x`, `y`, and `z` are converted to arrays only if they + are tuples or a lists, otherwise they are treated as a scalars. In + either case, either `x`, `y`, and `z` or their elements must support + multiplication and addition both with themselves and with the elements + of `c`. + + If `c` has fewer than three dimensions, ones are implicitly appended to + its shape to make it 3-D. The shape of the result will be c.shape[3:] + + x.shape + y.shape + z.shape. + + Parameters + ---------- + x, y, z : array_like, compatible objects + The three dimensional series is evaluated at the points in the + Cartesian product of `x`, `y`, and `z`. If `x`,`y`, or `z` is a + list or tuple, it is first converted to an ndarray, otherwise it is + left unchanged and, if it isn't an ndarray, it is treated as a + scalar. + c : array_like + Array of coefficients ordered so that the coefficients for terms of + degree i,j are contained in ``c[i,j]``. If `c` has dimension + greater than two the remaining indices enumerate multiple sets of + coefficients. + + Returns + ------- + values : ndarray, compatible object + The values of the two dimensional polynomial at points in the Cartesian + product of `x` and `y`. + + See Also + -------- + lagval, lagval2d, laggrid2d, lagval3d + + Notes + ----- + + .. versionadded:: 1.7.0 + + """ + return pu._gridnd(lagval, c, x, y, z) + + +def lagvander(x, deg): + """Pseudo-Vandermonde matrix of given degree. + + Returns the pseudo-Vandermonde matrix of degree `deg` and sample points + `x`. The pseudo-Vandermonde matrix is defined by + + .. math:: V[..., i] = L_i(x) + + where `0 <= i <= deg`. The leading indices of `V` index the elements of + `x` and the last index is the degree of the Laguerre polynomial. + + If `c` is a 1-D array of coefficients of length `n + 1` and `V` is the + array ``V = lagvander(x, n)``, then ``np.dot(V, c)`` and + ``lagval(x, c)`` are the same up to roundoff. This equivalence is + useful both for least squares fitting and for the evaluation of a large + number of Laguerre series of the same degree and sample points. + + Parameters + ---------- + x : array_like + Array of points. The dtype is converted to float64 or complex128 + depending on whether any of the elements are complex. If `x` is + scalar it is converted to a 1-D array. + deg : int + Degree of the resulting matrix. + + Returns + ------- + vander : ndarray + The pseudo-Vandermonde matrix. The shape of the returned matrix is + ``x.shape + (deg + 1,)``, where The last index is the degree of the + corresponding Laguerre polynomial. The dtype will be the same as + the converted `x`. + + Examples + -------- + >>> from numpy.polynomial.laguerre import lagvander + >>> x = np.array([0, 1, 2]) + >>> lagvander(x, 3) + array([[ 1. , 1. , 1. , 1. ], + [ 1. , 0. , -0.5 , -0.66666667], + [ 1. , -1. , -1. , -0.33333333]]) + + """ + ideg = pu._deprecate_as_int(deg, "deg") + if ideg < 0: + raise ValueError("deg must be non-negative") + + x = np.array(x, copy=False, ndmin=1) + 0.0 + dims = (ideg + 1,) + x.shape + dtyp = x.dtype + v = np.empty(dims, dtype=dtyp) + v[0] = x*0 + 1 + if ideg > 0: + v[1] = 1 - x + for i in range(2, ideg + 1): + v[i] = (v[i-1]*(2*i - 1 - x) - v[i-2]*(i - 1))/i + return np.moveaxis(v, 0, -1) + + +def lagvander2d(x, y, deg): + """Pseudo-Vandermonde matrix of given degrees. + + Returns the pseudo-Vandermonde matrix of degrees `deg` and sample + points `(x, y)`. The pseudo-Vandermonde matrix is defined by + + .. math:: V[..., (deg[1] + 1)*i + j] = L_i(x) * L_j(y), + + where `0 <= i <= deg[0]` and `0 <= j <= deg[1]`. The leading indices of + `V` index the points `(x, y)` and the last index encodes the degrees of + the Laguerre polynomials. + + If ``V = lagvander2d(x, y, [xdeg, ydeg])``, then the columns of `V` + correspond to the elements of a 2-D coefficient array `c` of shape + (xdeg + 1, ydeg + 1) in the order + + .. math:: c_{00}, c_{01}, c_{02} ... , c_{10}, c_{11}, c_{12} ... + + and ``np.dot(V, c.flat)`` and ``lagval2d(x, y, c)`` will be the same + up to roundoff. This equivalence is useful both for least squares + fitting and for the evaluation of a large number of 2-D Laguerre + series of the same degrees and sample points. + + Parameters + ---------- + x, y : array_like + Arrays of point coordinates, all of the same shape. The dtypes + will be converted to either float64 or complex128 depending on + whether any of the elements are complex. Scalars are converted to + 1-D arrays. + deg : list of ints + List of maximum degrees of the form [x_deg, y_deg]. + + Returns + ------- + vander2d : ndarray + The shape of the returned matrix is ``x.shape + (order,)``, where + :math:`order = (deg[0]+1)*(deg[1]+1)`. The dtype will be the same + as the converted `x` and `y`. + + See Also + -------- + lagvander, lagvander3d, lagval2d, lagval3d + + Notes + ----- + + .. versionadded:: 1.7.0 + + """ + return pu._vander_nd_flat((lagvander, lagvander), (x, y), deg) + + +def lagvander3d(x, y, z, deg): + """Pseudo-Vandermonde matrix of given degrees. + + Returns the pseudo-Vandermonde matrix of degrees `deg` and sample + points `(x, y, z)`. If `l, m, n` are the given degrees in `x, y, z`, + then The pseudo-Vandermonde matrix is defined by + + .. math:: V[..., (m+1)(n+1)i + (n+1)j + k] = L_i(x)*L_j(y)*L_k(z), + + where `0 <= i <= l`, `0 <= j <= m`, and `0 <= j <= n`. The leading + indices of `V` index the points `(x, y, z)` and the last index encodes + the degrees of the Laguerre polynomials. + + If ``V = lagvander3d(x, y, z, [xdeg, ydeg, zdeg])``, then the columns + of `V` correspond to the elements of a 3-D coefficient array `c` of + shape (xdeg + 1, ydeg + 1, zdeg + 1) in the order + + .. math:: c_{000}, c_{001}, c_{002},... , c_{010}, c_{011}, c_{012},... + + and ``np.dot(V, c.flat)`` and ``lagval3d(x, y, z, c)`` will be the + same up to roundoff. This equivalence is useful both for least squares + fitting and for the evaluation of a large number of 3-D Laguerre + series of the same degrees and sample points. + + Parameters + ---------- + x, y, z : array_like + Arrays of point coordinates, all of the same shape. The dtypes will + be converted to either float64 or complex128 depending on whether + any of the elements are complex. Scalars are converted to 1-D + arrays. + deg : list of ints + List of maximum degrees of the form [x_deg, y_deg, z_deg]. + + Returns + ------- + vander3d : ndarray + The shape of the returned matrix is ``x.shape + (order,)``, where + :math:`order = (deg[0]+1)*(deg[1]+1)*(deg[2]+1)`. The dtype will + be the same as the converted `x`, `y`, and `z`. + + See Also + -------- + lagvander, lagvander3d, lagval2d, lagval3d + + Notes + ----- + + .. versionadded:: 1.7.0 + + """ + return pu._vander_nd_flat((lagvander, lagvander, lagvander), (x, y, z), deg) + + +def lagfit(x, y, deg, rcond=None, full=False, w=None): + """ + Least squares fit of Laguerre series to data. + + Return the coefficients of a Laguerre series of degree `deg` that is the + least squares fit to the data values `y` given at points `x`. If `y` is + 1-D the returned coefficients will also be 1-D. If `y` is 2-D multiple + fits are done, one for each column of `y`, and the resulting + coefficients are stored in the corresponding columns of a 2-D return. + The fitted polynomial(s) are in the form + + .. math:: p(x) = c_0 + c_1 * L_1(x) + ... + c_n * L_n(x), + + where `n` is `deg`. + + Parameters + ---------- + x : array_like, shape (M,) + x-coordinates of the M sample points ``(x[i], y[i])``. + y : array_like, shape (M,) or (M, K) + y-coordinates of the sample points. Several data sets of sample + points sharing the same x-coordinates can be fitted at once by + passing in a 2D-array that contains one dataset per column. + deg : int or 1-D array_like + Degree(s) of the fitting polynomials. If `deg` is a single integer + all terms up to and including the `deg`'th term are included in the + fit. For NumPy versions >= 1.11.0 a list of integers specifying the + degrees of the terms to include may be used instead. + rcond : float, optional + Relative condition number of the fit. Singular values smaller than + this relative to the largest singular value will be ignored. The + default value is len(x)*eps, where eps is the relative precision of + the float type, about 2e-16 in most cases. + full : bool, optional + Switch determining nature of return value. When it is False (the + default) just the coefficients are returned, when True diagnostic + information from the singular value decomposition is also returned. + w : array_like, shape (`M`,), optional + Weights. If not None, the contribution of each point + ``(x[i],y[i])`` to the fit is weighted by `w[i]`. Ideally the + weights are chosen so that the errors of the products ``w[i]*y[i]`` + all have the same variance. The default value is None. + + Returns + ------- + coef : ndarray, shape (M,) or (M, K) + Laguerre coefficients ordered from low to high. If `y` was 2-D, + the coefficients for the data in column k of `y` are in column + `k`. + + [residuals, rank, singular_values, rcond] : list + These values are only returned if `full` = True + + resid -- sum of squared residuals of the least squares fit + rank -- the numerical rank of the scaled Vandermonde matrix + sv -- singular values of the scaled Vandermonde matrix + rcond -- value of `rcond`. + + For more details, see `numpy.linalg.lstsq`. + + Warns + ----- + RankWarning + The rank of the coefficient matrix in the least-squares fit is + deficient. The warning is only raised if `full` = False. The + warnings can be turned off by + + >>> import warnings + >>> warnings.simplefilter('ignore', np.RankWarning) + + See Also + -------- + numpy.polynomial.polynomial.polyfit + numpy.polynomial.legendre.legfit + numpy.polynomial.chebyshev.chebfit + numpy.polynomial.hermite.hermfit + numpy.polynomial.hermite_e.hermefit + lagval : Evaluates a Laguerre series. + lagvander : pseudo Vandermonde matrix of Laguerre series. + lagweight : Laguerre weight function. + numpy.linalg.lstsq : Computes a least-squares fit from the matrix. + scipy.interpolate.UnivariateSpline : Computes spline fits. + + Notes + ----- + The solution is the coefficients of the Laguerre series `p` that + minimizes the sum of the weighted squared errors + + .. math:: E = \\sum_j w_j^2 * |y_j - p(x_j)|^2, + + where the :math:`w_j` are the weights. This problem is solved by + setting up as the (typically) overdetermined matrix equation + + .. math:: V(x) * c = w * y, + + where `V` is the weighted pseudo Vandermonde matrix of `x`, `c` are the + coefficients to be solved for, `w` are the weights, and `y` are the + observed values. This equation is then solved using the singular value + decomposition of `V`. + + If some of the singular values of `V` are so small that they are + neglected, then a `RankWarning` will be issued. This means that the + coefficient values may be poorly determined. Using a lower order fit + will usually get rid of the warning. The `rcond` parameter can also be + set to a value smaller than its default, but the resulting fit may be + spurious and have large contributions from roundoff error. + + Fits using Laguerre series are probably most useful when the data can + be approximated by ``sqrt(w(x)) * p(x)``, where `w(x)` is the Laguerre + weight. In that case the weight ``sqrt(w(x[i]))`` should be used + together with data values ``y[i]/sqrt(w(x[i]))``. The weight function is + available as `lagweight`. + + References + ---------- + .. [1] Wikipedia, "Curve fitting", + https://en.wikipedia.org/wiki/Curve_fitting + + Examples + -------- + >>> from numpy.polynomial.laguerre import lagfit, lagval + >>> x = np.linspace(0, 10) + >>> err = np.random.randn(len(x))/10 + >>> y = lagval(x, [1, 2, 3]) + err + >>> lagfit(x, y, 2) + array([ 0.96971004, 2.00193749, 3.00288744]) # may vary + + """ + return pu._fit(lagvander, x, y, deg, rcond, full, w) + + +def lagcompanion(c): + """ + Return the companion matrix of c. + + The usual companion matrix of the Laguerre polynomials is already + symmetric when `c` is a basis Laguerre polynomial, so no scaling is + applied. + + Parameters + ---------- + c : array_like + 1-D array of Laguerre series coefficients ordered from low to high + degree. + + Returns + ------- + mat : ndarray + Companion matrix of dimensions (deg, deg). + + Notes + ----- + + .. versionadded:: 1.7.0 + + """ + # c is a trimmed copy + [c] = pu.as_series([c]) + if len(c) < 2: + raise ValueError('Series must have maximum degree of at least 1.') + if len(c) == 2: + return np.array([[1 + c[0]/c[1]]]) + + n = len(c) - 1 + mat = np.zeros((n, n), dtype=c.dtype) + top = mat.reshape(-1)[1::n+1] + mid = mat.reshape(-1)[0::n+1] + bot = mat.reshape(-1)[n::n+1] + top[...] = -np.arange(1, n) + mid[...] = 2.*np.arange(n) + 1. + bot[...] = top + mat[:, -1] += (c[:-1]/c[-1])*n + return mat + + +def lagroots(c): + """ + Compute the roots of a Laguerre series. + + Return the roots (a.k.a. "zeros") of the polynomial + + .. math:: p(x) = \\sum_i c[i] * L_i(x). + + Parameters + ---------- + c : 1-D array_like + 1-D array of coefficients. + + Returns + ------- + out : ndarray + Array of the roots of the series. If all the roots are real, + then `out` is also real, otherwise it is complex. + + See Also + -------- + numpy.polynomial.polynomial.polyroots + numpy.polynomial.legendre.legroots + numpy.polynomial.chebyshev.chebroots + numpy.polynomial.hermite.hermroots + numpy.polynomial.hermite_e.hermeroots + + Notes + ----- + The root estimates are obtained as the eigenvalues of the companion + matrix, Roots far from the origin of the complex plane may have large + errors due to the numerical instability of the series for such + values. Roots with multiplicity greater than 1 will also show larger + errors as the value of the series near such points is relatively + insensitive to errors in the roots. Isolated roots near the origin can + be improved by a few iterations of Newton's method. + + The Laguerre series basis polynomials aren't powers of `x` so the + results of this function may seem unintuitive. + + Examples + -------- + >>> from numpy.polynomial.laguerre import lagroots, lagfromroots + >>> coef = lagfromroots([0, 1, 2]) + >>> coef + array([ 2., -8., 12., -6.]) + >>> lagroots(coef) + array([-4.4408921e-16, 1.0000000e+00, 2.0000000e+00]) + + """ + # c is a trimmed copy + [c] = pu.as_series([c]) + if len(c) <= 1: + return np.array([], dtype=c.dtype) + if len(c) == 2: + return np.array([1 + c[0]/c[1]]) + + # rotated companion matrix reduces error + m = lagcompanion(c)[::-1,::-1] + r = la.eigvals(m) + r.sort() + return r + + +def laggauss(deg): + """ + Gauss-Laguerre quadrature. + + Computes the sample points and weights for Gauss-Laguerre quadrature. + These sample points and weights will correctly integrate polynomials of + degree :math:`2*deg - 1` or less over the interval :math:`[0, \\inf]` + with the weight function :math:`f(x) = \\exp(-x)`. + + Parameters + ---------- + deg : int + Number of sample points and weights. It must be >= 1. + + Returns + ------- + x : ndarray + 1-D ndarray containing the sample points. + y : ndarray + 1-D ndarray containing the weights. + + Notes + ----- + + .. versionadded:: 1.7.0 + + The results have only been tested up to degree 100 higher degrees may + be problematic. The weights are determined by using the fact that + + .. math:: w_k = c / (L'_n(x_k) * L_{n-1}(x_k)) + + where :math:`c` is a constant independent of :math:`k` and :math:`x_k` + is the k'th root of :math:`L_n`, and then scaling the results to get + the right value when integrating 1. + + """ + ideg = pu._deprecate_as_int(deg, "deg") + if ideg <= 0: + raise ValueError("deg must be a positive integer") + + # first approximation of roots. We use the fact that the companion + # matrix is symmetric in this case in order to obtain better zeros. + c = np.array([0]*deg + [1]) + m = lagcompanion(c) + x = la.eigvalsh(m) + + # improve roots by one application of Newton + dy = lagval(x, c) + df = lagval(x, lagder(c)) + x -= dy/df + + # compute the weights. We scale the factor to avoid possible numerical + # overflow. + fm = lagval(x, c[1:]) + fm /= np.abs(fm).max() + df /= np.abs(df).max() + w = 1/(fm * df) + + # scale w to get the right value, 1 in this case + w /= w.sum() + + return x, w + + +def lagweight(x): + """Weight function of the Laguerre polynomials. + + The weight function is :math:`exp(-x)` and the interval of integration + is :math:`[0, \\inf]`. The Laguerre polynomials are orthogonal, but not + normalized, with respect to this weight function. + + Parameters + ---------- + x : array_like + Values at which the weight function will be computed. + + Returns + ------- + w : ndarray + The weight function at `x`. + + Notes + ----- + + .. versionadded:: 1.7.0 + + """ + w = np.exp(-x) + return w + +# +# Laguerre series class +# + +class Laguerre(ABCPolyBase): + """A Laguerre series class. + + The Laguerre class provides the standard Python numerical methods + '+', '-', '*', '//', '%', 'divmod', '**', and '()' as well as the + attributes and methods listed in the `ABCPolyBase` documentation. + + Parameters + ---------- + coef : array_like + Laguerre coefficients in order of increasing degree, i.e, + ``(1, 2, 3)`` gives ``1*L_0(x) + 2*L_1(X) + 3*L_2(x)``. + domain : (2,) array_like, optional + Domain to use. The interval ``[domain[0], domain[1]]`` is mapped + to the interval ``[window[0], window[1]]`` by shifting and scaling. + The default value is [0, 1]. + window : (2,) array_like, optional + Window, see `domain` for its use. The default value is [0, 1]. + + .. versionadded:: 1.6.0 + + """ + # Virtual Functions + _add = staticmethod(lagadd) + _sub = staticmethod(lagsub) + _mul = staticmethod(lagmul) + _div = staticmethod(lagdiv) + _pow = staticmethod(lagpow) + _val = staticmethod(lagval) + _int = staticmethod(lagint) + _der = staticmethod(lagder) + _fit = staticmethod(lagfit) + _line = staticmethod(lagline) + _roots = staticmethod(lagroots) + _fromroots = staticmethod(lagfromroots) + + # Virtual properties + domain = np.array(lagdomain) + window = np.array(lagdomain) + basis_name = 'L' diff --git a/venv/Lib/site-packages/numpy/polynomial/legendre.py b/venv/Lib/site-packages/numpy/polynomial/legendre.py new file mode 100644 index 0000000..427f9f8 --- /dev/null +++ b/venv/Lib/site-packages/numpy/polynomial/legendre.py @@ -0,0 +1,1663 @@ +""" +================================================== +Legendre Series (:mod:`numpy.polynomial.legendre`) +================================================== + +This module provides a number of objects (mostly functions) useful for +dealing with Legendre series, including a `Legendre` class that +encapsulates the usual arithmetic operations. (General information +on how this module represents and works with such polynomials is in the +docstring for its "parent" sub-package, `numpy.polynomial`). + +Classes +------- +.. autosummary:: + :toctree: generated/ + + Legendre + +Constants +--------- + +.. autosummary:: + :toctree: generated/ + + legdomain + legzero + legone + legx + +Arithmetic +---------- + +.. autosummary:: + :toctree: generated/ + + legadd + legsub + legmulx + legmul + legdiv + legpow + legval + legval2d + legval3d + leggrid2d + leggrid3d + +Calculus +-------- + +.. autosummary:: + :toctree: generated/ + + legder + legint + +Misc Functions +-------------- + +.. autosummary:: + :toctree: generated/ + + legfromroots + legroots + legvander + legvander2d + legvander3d + leggauss + legweight + legcompanion + legfit + legtrim + legline + leg2poly + poly2leg + +See also +-------- +numpy.polynomial + +""" +import numpy as np +import numpy.linalg as la +from numpy.core.multiarray import normalize_axis_index + +from . import polyutils as pu +from ._polybase import ABCPolyBase + +__all__ = [ + 'legzero', 'legone', 'legx', 'legdomain', 'legline', 'legadd', + 'legsub', 'legmulx', 'legmul', 'legdiv', 'legpow', 'legval', 'legder', + 'legint', 'leg2poly', 'poly2leg', 'legfromroots', 'legvander', + 'legfit', 'legtrim', 'legroots', 'Legendre', 'legval2d', 'legval3d', + 'leggrid2d', 'leggrid3d', 'legvander2d', 'legvander3d', 'legcompanion', + 'leggauss', 'legweight'] + +legtrim = pu.trimcoef + + +def poly2leg(pol): + """ + Convert a polynomial to a Legendre series. + + Convert an array representing the coefficients of a polynomial (relative + to the "standard" basis) ordered from lowest degree to highest, to an + array of the coefficients of the equivalent Legendre series, ordered + from lowest to highest degree. + + Parameters + ---------- + pol : array_like + 1-D array containing the polynomial coefficients + + Returns + ------- + c : ndarray + 1-D array containing the coefficients of the equivalent Legendre + series. + + See Also + -------- + leg2poly + + Notes + ----- + The easy way to do conversions between polynomial basis sets + is to use the convert method of a class instance. + + Examples + -------- + >>> from numpy import polynomial as P + >>> p = P.Polynomial(np.arange(4)) + >>> p + Polynomial([0., 1., 2., 3.], domain=[-1, 1], window=[-1, 1]) + >>> c = P.Legendre(P.legendre.poly2leg(p.coef)) + >>> c + Legendre([ 1. , 3.25, 1. , 0.75], domain=[-1, 1], window=[-1, 1]) # may vary + + """ + [pol] = pu.as_series([pol]) + deg = len(pol) - 1 + res = 0 + for i in range(deg, -1, -1): + res = legadd(legmulx(res), pol[i]) + return res + + +def leg2poly(c): + """ + Convert a Legendre series to a polynomial. + + Convert an array representing the coefficients of a Legendre series, + ordered from lowest degree to highest, to an array of the coefficients + of the equivalent polynomial (relative to the "standard" basis) ordered + from lowest to highest degree. + + Parameters + ---------- + c : array_like + 1-D array containing the Legendre series coefficients, ordered + from lowest order term to highest. + + Returns + ------- + pol : ndarray + 1-D array containing the coefficients of the equivalent polynomial + (relative to the "standard" basis) ordered from lowest order term + to highest. + + See Also + -------- + poly2leg + + Notes + ----- + The easy way to do conversions between polynomial basis sets + is to use the convert method of a class instance. + + Examples + -------- + >>> from numpy import polynomial as P + >>> c = P.Legendre(range(4)) + >>> c + Legendre([0., 1., 2., 3.], domain=[-1, 1], window=[-1, 1]) + >>> p = c.convert(kind=P.Polynomial) + >>> p + Polynomial([-1. , -3.5, 3. , 7.5], domain=[-1., 1.], window=[-1., 1.]) + >>> P.leg2poly(range(4)) + array([-1. , -3.5, 3. , 7.5]) + + + """ + from .polynomial import polyadd, polysub, polymulx + + [c] = pu.as_series([c]) + n = len(c) + if n < 3: + return c + else: + c0 = c[-2] + c1 = c[-1] + # i is the current degree of c1 + for i in range(n - 1, 1, -1): + tmp = c0 + c0 = polysub(c[i - 2], (c1*(i - 1))/i) + c1 = polyadd(tmp, (polymulx(c1)*(2*i - 1))/i) + return polyadd(c0, polymulx(c1)) + +# +# These are constant arrays are of integer type so as to be compatible +# with the widest range of other types, such as Decimal. +# + +# Legendre +legdomain = np.array([-1, 1]) + +# Legendre coefficients representing zero. +legzero = np.array([0]) + +# Legendre coefficients representing one. +legone = np.array([1]) + +# Legendre coefficients representing the identity x. +legx = np.array([0, 1]) + + +def legline(off, scl): + """ + Legendre series whose graph is a straight line. + + + + Parameters + ---------- + off, scl : scalars + The specified line is given by ``off + scl*x``. + + Returns + ------- + y : ndarray + This module's representation of the Legendre series for + ``off + scl*x``. + + See Also + -------- + numpy.polynomial.polynomial.polyline + numpy.polynomial.chebyshev.chebline + numpy.polynomial.laguerre.lagline + numpy.polynomial.hermite.hermline + numpy.polynomial.hermite_e.hermeline + + Examples + -------- + >>> import numpy.polynomial.legendre as L + >>> L.legline(3,2) + array([3, 2]) + >>> L.legval(-3, L.legline(3,2)) # should be -3 + -3.0 + + """ + if scl != 0: + return np.array([off, scl]) + else: + return np.array([off]) + + +def legfromroots(roots): + """ + Generate a Legendre series with given roots. + + The function returns the coefficients of the polynomial + + .. math:: p(x) = (x - r_0) * (x - r_1) * ... * (x - r_n), + + in Legendre form, where the `r_n` are the roots specified in `roots`. + If a zero has multiplicity n, then it must appear in `roots` n times. + For instance, if 2 is a root of multiplicity three and 3 is a root of + multiplicity 2, then `roots` looks something like [2, 2, 2, 3, 3]. The + roots can appear in any order. + + If the returned coefficients are `c`, then + + .. math:: p(x) = c_0 + c_1 * L_1(x) + ... + c_n * L_n(x) + + The coefficient of the last term is not generally 1 for monic + polynomials in Legendre form. + + Parameters + ---------- + roots : array_like + Sequence containing the roots. + + Returns + ------- + out : ndarray + 1-D array of coefficients. If all roots are real then `out` is a + real array, if some of the roots are complex, then `out` is complex + even if all the coefficients in the result are real (see Examples + below). + + See Also + -------- + numpy.polynomial.polynomial.polyfromroots + numpy.polynomial.chebyshev.chebfromroots + numpy.polynomial.laguerre.lagfromroots + numpy.polynomial.hermite.hermfromroots + numpy.polynomial.hermite_e.hermefromroots + + Examples + -------- + >>> import numpy.polynomial.legendre as L + >>> L.legfromroots((-1,0,1)) # x^3 - x relative to the standard basis + array([ 0. , -0.4, 0. , 0.4]) + >>> j = complex(0,1) + >>> L.legfromroots((-j,j)) # x^2 + 1 relative to the standard basis + array([ 1.33333333+0.j, 0.00000000+0.j, 0.66666667+0.j]) # may vary + + """ + return pu._fromroots(legline, legmul, roots) + + +def legadd(c1, c2): + """ + Add one Legendre series to another. + + Returns the sum of two Legendre series `c1` + `c2`. The arguments + are sequences of coefficients ordered from lowest order term to + highest, i.e., [1,2,3] represents the series ``P_0 + 2*P_1 + 3*P_2``. + + Parameters + ---------- + c1, c2 : array_like + 1-D arrays of Legendre series coefficients ordered from low to + high. + + Returns + ------- + out : ndarray + Array representing the Legendre series of their sum. + + See Also + -------- + legsub, legmulx, legmul, legdiv, legpow + + Notes + ----- + Unlike multiplication, division, etc., the sum of two Legendre series + is a Legendre series (without having to "reproject" the result onto + the basis set) so addition, just like that of "standard" polynomials, + is simply "component-wise." + + Examples + -------- + >>> from numpy.polynomial import legendre as L + >>> c1 = (1,2,3) + >>> c2 = (3,2,1) + >>> L.legadd(c1,c2) + array([4., 4., 4.]) + + """ + return pu._add(c1, c2) + + +def legsub(c1, c2): + """ + Subtract one Legendre series from another. + + Returns the difference of two Legendre series `c1` - `c2`. The + sequences of coefficients are from lowest order term to highest, i.e., + [1,2,3] represents the series ``P_0 + 2*P_1 + 3*P_2``. + + Parameters + ---------- + c1, c2 : array_like + 1-D arrays of Legendre series coefficients ordered from low to + high. + + Returns + ------- + out : ndarray + Of Legendre series coefficients representing their difference. + + See Also + -------- + legadd, legmulx, legmul, legdiv, legpow + + Notes + ----- + Unlike multiplication, division, etc., the difference of two Legendre + series is a Legendre series (without having to "reproject" the result + onto the basis set) so subtraction, just like that of "standard" + polynomials, is simply "component-wise." + + Examples + -------- + >>> from numpy.polynomial import legendre as L + >>> c1 = (1,2,3) + >>> c2 = (3,2,1) + >>> L.legsub(c1,c2) + array([-2., 0., 2.]) + >>> L.legsub(c2,c1) # -C.legsub(c1,c2) + array([ 2., 0., -2.]) + + """ + return pu._sub(c1, c2) + + +def legmulx(c): + """Multiply a Legendre series by x. + + Multiply the Legendre series `c` by x, where x is the independent + variable. + + + Parameters + ---------- + c : array_like + 1-D array of Legendre series coefficients ordered from low to + high. + + Returns + ------- + out : ndarray + Array representing the result of the multiplication. + + See Also + -------- + legadd, legmul, legmul, legdiv, legpow + + Notes + ----- + The multiplication uses the recursion relationship for Legendre + polynomials in the form + + .. math:: + + xP_i(x) = ((i + 1)*P_{i + 1}(x) + i*P_{i - 1}(x))/(2i + 1) + + Examples + -------- + >>> from numpy.polynomial import legendre as L + >>> L.legmulx([1,2,3]) + array([ 0.66666667, 2.2, 1.33333333, 1.8]) # may vary + + """ + # c is a trimmed copy + [c] = pu.as_series([c]) + # The zero series needs special treatment + if len(c) == 1 and c[0] == 0: + return c + + prd = np.empty(len(c) + 1, dtype=c.dtype) + prd[0] = c[0]*0 + prd[1] = c[0] + for i in range(1, len(c)): + j = i + 1 + k = i - 1 + s = i + j + prd[j] = (c[i]*j)/s + prd[k] += (c[i]*i)/s + return prd + + +def legmul(c1, c2): + """ + Multiply one Legendre series by another. + + Returns the product of two Legendre series `c1` * `c2`. The arguments + are sequences of coefficients, from lowest order "term" to highest, + e.g., [1,2,3] represents the series ``P_0 + 2*P_1 + 3*P_2``. + + Parameters + ---------- + c1, c2 : array_like + 1-D arrays of Legendre series coefficients ordered from low to + high. + + Returns + ------- + out : ndarray + Of Legendre series coefficients representing their product. + + See Also + -------- + legadd, legsub, legmulx, legdiv, legpow + + Notes + ----- + In general, the (polynomial) product of two C-series results in terms + that are not in the Legendre polynomial basis set. Thus, to express + the product as a Legendre series, it is necessary to "reproject" the + product onto said basis set, which may produce "unintuitive" (but + correct) results; see Examples section below. + + Examples + -------- + >>> from numpy.polynomial import legendre as L + >>> c1 = (1,2,3) + >>> c2 = (3,2) + >>> L.legmul(c1,c2) # multiplication requires "reprojection" + array([ 4.33333333, 10.4 , 11.66666667, 3.6 ]) # may vary + + """ + # s1, s2 are trimmed copies + [c1, c2] = pu.as_series([c1, c2]) + + if len(c1) > len(c2): + c = c2 + xs = c1 + else: + c = c1 + xs = c2 + + if len(c) == 1: + c0 = c[0]*xs + c1 = 0 + elif len(c) == 2: + c0 = c[0]*xs + c1 = c[1]*xs + else: + nd = len(c) + c0 = c[-2]*xs + c1 = c[-1]*xs + for i in range(3, len(c) + 1): + tmp = c0 + nd = nd - 1 + c0 = legsub(c[-i]*xs, (c1*(nd - 1))/nd) + c1 = legadd(tmp, (legmulx(c1)*(2*nd - 1))/nd) + return legadd(c0, legmulx(c1)) + + +def legdiv(c1, c2): + """ + Divide one Legendre series by another. + + Returns the quotient-with-remainder of two Legendre series + `c1` / `c2`. The arguments are sequences of coefficients from lowest + order "term" to highest, e.g., [1,2,3] represents the series + ``P_0 + 2*P_1 + 3*P_2``. + + Parameters + ---------- + c1, c2 : array_like + 1-D arrays of Legendre series coefficients ordered from low to + high. + + Returns + ------- + quo, rem : ndarrays + Of Legendre series coefficients representing the quotient and + remainder. + + See Also + -------- + legadd, legsub, legmulx, legmul, legpow + + Notes + ----- + In general, the (polynomial) division of one Legendre series by another + results in quotient and remainder terms that are not in the Legendre + polynomial basis set. Thus, to express these results as a Legendre + series, it is necessary to "reproject" the results onto the Legendre + basis set, which may produce "unintuitive" (but correct) results; see + Examples section below. + + Examples + -------- + >>> from numpy.polynomial import legendre as L + >>> c1 = (1,2,3) + >>> c2 = (3,2,1) + >>> L.legdiv(c1,c2) # quotient "intuitive," remainder not + (array([3.]), array([-8., -4.])) + >>> c2 = (0,1,2,3) + >>> L.legdiv(c2,c1) # neither "intuitive" + (array([-0.07407407, 1.66666667]), array([-1.03703704, -2.51851852])) # may vary + + """ + return pu._div(legmul, c1, c2) + + +def legpow(c, pow, maxpower=16): + """Raise a Legendre series to a power. + + Returns the Legendre series `c` raised to the power `pow`. The + argument `c` is a sequence of coefficients ordered from low to high. + i.e., [1,2,3] is the series ``P_0 + 2*P_1 + 3*P_2.`` + + Parameters + ---------- + c : array_like + 1-D array of Legendre series coefficients ordered from low to + high. + pow : integer + Power to which the series will be raised + maxpower : integer, optional + Maximum power allowed. This is mainly to limit growth of the series + to unmanageable size. Default is 16 + + Returns + ------- + coef : ndarray + Legendre series of power. + + See Also + -------- + legadd, legsub, legmulx, legmul, legdiv + + Examples + -------- + + """ + return pu._pow(legmul, c, pow, maxpower) + + +def legder(c, m=1, scl=1, axis=0): + """ + Differentiate a Legendre series. + + Returns the Legendre series coefficients `c` differentiated `m` times + along `axis`. At each iteration the result is multiplied by `scl` (the + scaling factor is for use in a linear change of variable). The argument + `c` is an array of coefficients from low to high degree along each + axis, e.g., [1,2,3] represents the series ``1*L_0 + 2*L_1 + 3*L_2`` + while [[1,2],[1,2]] represents ``1*L_0(x)*L_0(y) + 1*L_1(x)*L_0(y) + + 2*L_0(x)*L_1(y) + 2*L_1(x)*L_1(y)`` if axis=0 is ``x`` and axis=1 is + ``y``. + + Parameters + ---------- + c : array_like + Array of Legendre series coefficients. If c is multidimensional the + different axis correspond to different variables with the degree in + each axis given by the corresponding index. + m : int, optional + Number of derivatives taken, must be non-negative. (Default: 1) + scl : scalar, optional + Each differentiation is multiplied by `scl`. The end result is + multiplication by ``scl**m``. This is for use in a linear change of + variable. (Default: 1) + axis : int, optional + Axis over which the derivative is taken. (Default: 0). + + .. versionadded:: 1.7.0 + + Returns + ------- + der : ndarray + Legendre series of the derivative. + + See Also + -------- + legint + + Notes + ----- + In general, the result of differentiating a Legendre series does not + resemble the same operation on a power series. Thus the result of this + function may be "unintuitive," albeit correct; see Examples section + below. + + Examples + -------- + >>> from numpy.polynomial import legendre as L + >>> c = (1,2,3,4) + >>> L.legder(c) + array([ 6., 9., 20.]) + >>> L.legder(c, 3) + array([60.]) + >>> L.legder(c, scl=-1) + array([ -6., -9., -20.]) + >>> L.legder(c, 2,-1) + array([ 9., 60.]) + + """ + c = np.array(c, ndmin=1, copy=True) + if c.dtype.char in '?bBhHiIlLqQpP': + c = c.astype(np.double) + cnt = pu._deprecate_as_int(m, "the order of derivation") + iaxis = pu._deprecate_as_int(axis, "the axis") + if cnt < 0: + raise ValueError("The order of derivation must be non-negative") + iaxis = normalize_axis_index(iaxis, c.ndim) + + if cnt == 0: + return c + + c = np.moveaxis(c, iaxis, 0) + n = len(c) + if cnt >= n: + c = c[:1]*0 + else: + for i in range(cnt): + n = n - 1 + c *= scl + der = np.empty((n,) + c.shape[1:], dtype=c.dtype) + for j in range(n, 2, -1): + der[j - 1] = (2*j - 1)*c[j] + c[j - 2] += c[j] + if n > 1: + der[1] = 3*c[2] + der[0] = c[1] + c = der + c = np.moveaxis(c, 0, iaxis) + return c + + +def legint(c, m=1, k=[], lbnd=0, scl=1, axis=0): + """ + Integrate a Legendre series. + + Returns the Legendre series coefficients `c` integrated `m` times from + `lbnd` along `axis`. At each iteration the resulting series is + **multiplied** by `scl` and an integration constant, `k`, is added. + The scaling factor is for use in a linear change of variable. ("Buyer + beware": note that, depending on what one is doing, one may want `scl` + to be the reciprocal of what one might expect; for more information, + see the Notes section below.) The argument `c` is an array of + coefficients from low to high degree along each axis, e.g., [1,2,3] + represents the series ``L_0 + 2*L_1 + 3*L_2`` while [[1,2],[1,2]] + represents ``1*L_0(x)*L_0(y) + 1*L_1(x)*L_0(y) + 2*L_0(x)*L_1(y) + + 2*L_1(x)*L_1(y)`` if axis=0 is ``x`` and axis=1 is ``y``. + + Parameters + ---------- + c : array_like + Array of Legendre series coefficients. If c is multidimensional the + different axis correspond to different variables with the degree in + each axis given by the corresponding index. + m : int, optional + Order of integration, must be positive. (Default: 1) + k : {[], list, scalar}, optional + Integration constant(s). The value of the first integral at + ``lbnd`` is the first value in the list, the value of the second + integral at ``lbnd`` is the second value, etc. If ``k == []`` (the + default), all constants are set to zero. If ``m == 1``, a single + scalar can be given instead of a list. + lbnd : scalar, optional + The lower bound of the integral. (Default: 0) + scl : scalar, optional + Following each integration the result is *multiplied* by `scl` + before the integration constant is added. (Default: 1) + axis : int, optional + Axis over which the integral is taken. (Default: 0). + + .. versionadded:: 1.7.0 + + Returns + ------- + S : ndarray + Legendre series coefficient array of the integral. + + Raises + ------ + ValueError + If ``m < 0``, ``len(k) > m``, ``np.ndim(lbnd) != 0``, or + ``np.ndim(scl) != 0``. + + See Also + -------- + legder + + Notes + ----- + Note that the result of each integration is *multiplied* by `scl`. + Why is this important to note? Say one is making a linear change of + variable :math:`u = ax + b` in an integral relative to `x`. Then + :math:`dx = du/a`, so one will need to set `scl` equal to + :math:`1/a` - perhaps not what one would have first thought. + + Also note that, in general, the result of integrating a C-series needs + to be "reprojected" onto the C-series basis set. Thus, typically, + the result of this function is "unintuitive," albeit correct; see + Examples section below. + + Examples + -------- + >>> from numpy.polynomial import legendre as L + >>> c = (1,2,3) + >>> L.legint(c) + array([ 0.33333333, 0.4 , 0.66666667, 0.6 ]) # may vary + >>> L.legint(c, 3) + array([ 1.66666667e-02, -1.78571429e-02, 4.76190476e-02, # may vary + -1.73472348e-18, 1.90476190e-02, 9.52380952e-03]) + >>> L.legint(c, k=3) + array([ 3.33333333, 0.4 , 0.66666667, 0.6 ]) # may vary + >>> L.legint(c, lbnd=-2) + array([ 7.33333333, 0.4 , 0.66666667, 0.6 ]) # may vary + >>> L.legint(c, scl=2) + array([ 0.66666667, 0.8 , 1.33333333, 1.2 ]) # may vary + + """ + c = np.array(c, ndmin=1, copy=True) + if c.dtype.char in '?bBhHiIlLqQpP': + c = c.astype(np.double) + if not np.iterable(k): + k = [k] + cnt = pu._deprecate_as_int(m, "the order of integration") + iaxis = pu._deprecate_as_int(axis, "the axis") + if cnt < 0: + raise ValueError("The order of integration must be non-negative") + if len(k) > cnt: + raise ValueError("Too many integration constants") + if np.ndim(lbnd) != 0: + raise ValueError("lbnd must be a scalar.") + if np.ndim(scl) != 0: + raise ValueError("scl must be a scalar.") + iaxis = normalize_axis_index(iaxis, c.ndim) + + if cnt == 0: + return c + + c = np.moveaxis(c, iaxis, 0) + k = list(k) + [0]*(cnt - len(k)) + for i in range(cnt): + n = len(c) + c *= scl + if n == 1 and np.all(c[0] == 0): + c[0] += k[i] + else: + tmp = np.empty((n + 1,) + c.shape[1:], dtype=c.dtype) + tmp[0] = c[0]*0 + tmp[1] = c[0] + if n > 1: + tmp[2] = c[1]/3 + for j in range(2, n): + t = c[j]/(2*j + 1) + tmp[j + 1] = t + tmp[j - 1] -= t + tmp[0] += k[i] - legval(lbnd, tmp) + c = tmp + c = np.moveaxis(c, 0, iaxis) + return c + + +def legval(x, c, tensor=True): + """ + Evaluate a Legendre series at points x. + + If `c` is of length `n + 1`, this function returns the value: + + .. math:: p(x) = c_0 * L_0(x) + c_1 * L_1(x) + ... + c_n * L_n(x) + + The parameter `x` is converted to an array only if it is a tuple or a + list, otherwise it is treated as a scalar. In either case, either `x` + or its elements must support multiplication and addition both with + themselves and with the elements of `c`. + + If `c` is a 1-D array, then `p(x)` will have the same shape as `x`. If + `c` is multidimensional, then the shape of the result depends on the + value of `tensor`. If `tensor` is true the shape will be c.shape[1:] + + x.shape. If `tensor` is false the shape will be c.shape[1:]. Note that + scalars have shape (,). + + Trailing zeros in the coefficients will be used in the evaluation, so + they should be avoided if efficiency is a concern. + + Parameters + ---------- + x : array_like, compatible object + If `x` is a list or tuple, it is converted to an ndarray, otherwise + it is left unchanged and treated as a scalar. In either case, `x` + or its elements must support addition and multiplication with + with themselves and with the elements of `c`. + c : array_like + Array of coefficients ordered so that the coefficients for terms of + degree n are contained in c[n]. If `c` is multidimensional the + remaining indices enumerate multiple polynomials. In the two + dimensional case the coefficients may be thought of as stored in + the columns of `c`. + tensor : boolean, optional + If True, the shape of the coefficient array is extended with ones + on the right, one for each dimension of `x`. Scalars have dimension 0 + for this action. The result is that every column of coefficients in + `c` is evaluated for every element of `x`. If False, `x` is broadcast + over the columns of `c` for the evaluation. This keyword is useful + when `c` is multidimensional. The default value is True. + + .. versionadded:: 1.7.0 + + Returns + ------- + values : ndarray, algebra_like + The shape of the return value is described above. + + See Also + -------- + legval2d, leggrid2d, legval3d, leggrid3d + + Notes + ----- + The evaluation uses Clenshaw recursion, aka synthetic division. + + Examples + -------- + + """ + c = np.array(c, ndmin=1, copy=False) + if c.dtype.char in '?bBhHiIlLqQpP': + c = c.astype(np.double) + if isinstance(x, (tuple, list)): + x = np.asarray(x) + if isinstance(x, np.ndarray) and tensor: + c = c.reshape(c.shape + (1,)*x.ndim) + + if len(c) == 1: + c0 = c[0] + c1 = 0 + elif len(c) == 2: + c0 = c[0] + c1 = c[1] + else: + nd = len(c) + c0 = c[-2] + c1 = c[-1] + for i in range(3, len(c) + 1): + tmp = c0 + nd = nd - 1 + c0 = c[-i] - (c1*(nd - 1))/nd + c1 = tmp + (c1*x*(2*nd - 1))/nd + return c0 + c1*x + + +def legval2d(x, y, c): + """ + Evaluate a 2-D Legendre series at points (x, y). + + This function returns the values: + + .. math:: p(x,y) = \\sum_{i,j} c_{i,j} * L_i(x) * L_j(y) + + The parameters `x` and `y` are converted to arrays only if they are + tuples or a lists, otherwise they are treated as a scalars and they + must have the same shape after conversion. In either case, either `x` + and `y` or their elements must support multiplication and addition both + with themselves and with the elements of `c`. + + If `c` is a 1-D array a one is implicitly appended to its shape to make + it 2-D. The shape of the result will be c.shape[2:] + x.shape. + + Parameters + ---------- + x, y : array_like, compatible objects + The two dimensional series is evaluated at the points `(x, y)`, + where `x` and `y` must have the same shape. If `x` or `y` is a list + or tuple, it is first converted to an ndarray, otherwise it is left + unchanged and if it isn't an ndarray it is treated as a scalar. + c : array_like + Array of coefficients ordered so that the coefficient of the term + of multi-degree i,j is contained in ``c[i,j]``. If `c` has + dimension greater than two the remaining indices enumerate multiple + sets of coefficients. + + Returns + ------- + values : ndarray, compatible object + The values of the two dimensional Legendre series at points formed + from pairs of corresponding values from `x` and `y`. + + See Also + -------- + legval, leggrid2d, legval3d, leggrid3d + + Notes + ----- + + .. versionadded:: 1.7.0 + + """ + return pu._valnd(legval, c, x, y) + + +def leggrid2d(x, y, c): + """ + Evaluate a 2-D Legendre series on the Cartesian product of x and y. + + This function returns the values: + + .. math:: p(a,b) = \\sum_{i,j} c_{i,j} * L_i(a) * L_j(b) + + where the points `(a, b)` consist of all pairs formed by taking + `a` from `x` and `b` from `y`. The resulting points form a grid with + `x` in the first dimension and `y` in the second. + + The parameters `x` and `y` are converted to arrays only if they are + tuples or a lists, otherwise they are treated as a scalars. In either + case, either `x` and `y` or their elements must support multiplication + and addition both with themselves and with the elements of `c`. + + If `c` has fewer than two dimensions, ones are implicitly appended to + its shape to make it 2-D. The shape of the result will be c.shape[2:] + + x.shape + y.shape. + + Parameters + ---------- + x, y : array_like, compatible objects + The two dimensional series is evaluated at the points in the + Cartesian product of `x` and `y`. If `x` or `y` is a list or + tuple, it is first converted to an ndarray, otherwise it is left + unchanged and, if it isn't an ndarray, it is treated as a scalar. + c : array_like + Array of coefficients ordered so that the coefficient of the term of + multi-degree i,j is contained in `c[i,j]`. If `c` has dimension + greater than two the remaining indices enumerate multiple sets of + coefficients. + + Returns + ------- + values : ndarray, compatible object + The values of the two dimensional Chebyshev series at points in the + Cartesian product of `x` and `y`. + + See Also + -------- + legval, legval2d, legval3d, leggrid3d + + Notes + ----- + + .. versionadded:: 1.7.0 + + """ + return pu._gridnd(legval, c, x, y) + + +def legval3d(x, y, z, c): + """ + Evaluate a 3-D Legendre series at points (x, y, z). + + This function returns the values: + + .. math:: p(x,y,z) = \\sum_{i,j,k} c_{i,j,k} * L_i(x) * L_j(y) * L_k(z) + + The parameters `x`, `y`, and `z` are converted to arrays only if + they are tuples or a lists, otherwise they are treated as a scalars and + they must have the same shape after conversion. In either case, either + `x`, `y`, and `z` or their elements must support multiplication and + addition both with themselves and with the elements of `c`. + + If `c` has fewer than 3 dimensions, ones are implicitly appended to its + shape to make it 3-D. The shape of the result will be c.shape[3:] + + x.shape. + + Parameters + ---------- + x, y, z : array_like, compatible object + The three dimensional series is evaluated at the points + `(x, y, z)`, where `x`, `y`, and `z` must have the same shape. If + any of `x`, `y`, or `z` is a list or tuple, it is first converted + to an ndarray, otherwise it is left unchanged and if it isn't an + ndarray it is treated as a scalar. + c : array_like + Array of coefficients ordered so that the coefficient of the term of + multi-degree i,j,k is contained in ``c[i,j,k]``. If `c` has dimension + greater than 3 the remaining indices enumerate multiple sets of + coefficients. + + Returns + ------- + values : ndarray, compatible object + The values of the multidimensional polynomial on points formed with + triples of corresponding values from `x`, `y`, and `z`. + + See Also + -------- + legval, legval2d, leggrid2d, leggrid3d + + Notes + ----- + + .. versionadded:: 1.7.0 + + """ + return pu._valnd(legval, c, x, y, z) + + +def leggrid3d(x, y, z, c): + """ + Evaluate a 3-D Legendre series on the Cartesian product of x, y, and z. + + This function returns the values: + + .. math:: p(a,b,c) = \\sum_{i,j,k} c_{i,j,k} * L_i(a) * L_j(b) * L_k(c) + + where the points `(a, b, c)` consist of all triples formed by taking + `a` from `x`, `b` from `y`, and `c` from `z`. The resulting points form + a grid with `x` in the first dimension, `y` in the second, and `z` in + the third. + + The parameters `x`, `y`, and `z` are converted to arrays only if they + are tuples or a lists, otherwise they are treated as a scalars. In + either case, either `x`, `y`, and `z` or their elements must support + multiplication and addition both with themselves and with the elements + of `c`. + + If `c` has fewer than three dimensions, ones are implicitly appended to + its shape to make it 3-D. The shape of the result will be c.shape[3:] + + x.shape + y.shape + z.shape. + + Parameters + ---------- + x, y, z : array_like, compatible objects + The three dimensional series is evaluated at the points in the + Cartesian product of `x`, `y`, and `z`. If `x`,`y`, or `z` is a + list or tuple, it is first converted to an ndarray, otherwise it is + left unchanged and, if it isn't an ndarray, it is treated as a + scalar. + c : array_like + Array of coefficients ordered so that the coefficients for terms of + degree i,j are contained in ``c[i,j]``. If `c` has dimension + greater than two the remaining indices enumerate multiple sets of + coefficients. + + Returns + ------- + values : ndarray, compatible object + The values of the two dimensional polynomial at points in the Cartesian + product of `x` and `y`. + + See Also + -------- + legval, legval2d, leggrid2d, legval3d + + Notes + ----- + + .. versionadded:: 1.7.0 + + """ + return pu._gridnd(legval, c, x, y, z) + + +def legvander(x, deg): + """Pseudo-Vandermonde matrix of given degree. + + Returns the pseudo-Vandermonde matrix of degree `deg` and sample points + `x`. The pseudo-Vandermonde matrix is defined by + + .. math:: V[..., i] = L_i(x) + + where `0 <= i <= deg`. The leading indices of `V` index the elements of + `x` and the last index is the degree of the Legendre polynomial. + + If `c` is a 1-D array of coefficients of length `n + 1` and `V` is the + array ``V = legvander(x, n)``, then ``np.dot(V, c)`` and + ``legval(x, c)`` are the same up to roundoff. This equivalence is + useful both for least squares fitting and for the evaluation of a large + number of Legendre series of the same degree and sample points. + + Parameters + ---------- + x : array_like + Array of points. The dtype is converted to float64 or complex128 + depending on whether any of the elements are complex. If `x` is + scalar it is converted to a 1-D array. + deg : int + Degree of the resulting matrix. + + Returns + ------- + vander : ndarray + The pseudo-Vandermonde matrix. The shape of the returned matrix is + ``x.shape + (deg + 1,)``, where The last index is the degree of the + corresponding Legendre polynomial. The dtype will be the same as + the converted `x`. + + """ + ideg = pu._deprecate_as_int(deg, "deg") + if ideg < 0: + raise ValueError("deg must be non-negative") + + x = np.array(x, copy=False, ndmin=1) + 0.0 + dims = (ideg + 1,) + x.shape + dtyp = x.dtype + v = np.empty(dims, dtype=dtyp) + # Use forward recursion to generate the entries. This is not as accurate + # as reverse recursion in this application but it is more efficient. + v[0] = x*0 + 1 + if ideg > 0: + v[1] = x + for i in range(2, ideg + 1): + v[i] = (v[i-1]*x*(2*i - 1) - v[i-2]*(i - 1))/i + return np.moveaxis(v, 0, -1) + + +def legvander2d(x, y, deg): + """Pseudo-Vandermonde matrix of given degrees. + + Returns the pseudo-Vandermonde matrix of degrees `deg` and sample + points `(x, y)`. The pseudo-Vandermonde matrix is defined by + + .. math:: V[..., (deg[1] + 1)*i + j] = L_i(x) * L_j(y), + + where `0 <= i <= deg[0]` and `0 <= j <= deg[1]`. The leading indices of + `V` index the points `(x, y)` and the last index encodes the degrees of + the Legendre polynomials. + + If ``V = legvander2d(x, y, [xdeg, ydeg])``, then the columns of `V` + correspond to the elements of a 2-D coefficient array `c` of shape + (xdeg + 1, ydeg + 1) in the order + + .. math:: c_{00}, c_{01}, c_{02} ... , c_{10}, c_{11}, c_{12} ... + + and ``np.dot(V, c.flat)`` and ``legval2d(x, y, c)`` will be the same + up to roundoff. This equivalence is useful both for least squares + fitting and for the evaluation of a large number of 2-D Legendre + series of the same degrees and sample points. + + Parameters + ---------- + x, y : array_like + Arrays of point coordinates, all of the same shape. The dtypes + will be converted to either float64 or complex128 depending on + whether any of the elements are complex. Scalars are converted to + 1-D arrays. + deg : list of ints + List of maximum degrees of the form [x_deg, y_deg]. + + Returns + ------- + vander2d : ndarray + The shape of the returned matrix is ``x.shape + (order,)``, where + :math:`order = (deg[0]+1)*(deg[1]+1)`. The dtype will be the same + as the converted `x` and `y`. + + See Also + -------- + legvander, legvander3d, legval2d, legval3d + + Notes + ----- + + .. versionadded:: 1.7.0 + + """ + return pu._vander_nd_flat((legvander, legvander), (x, y), deg) + + +def legvander3d(x, y, z, deg): + """Pseudo-Vandermonde matrix of given degrees. + + Returns the pseudo-Vandermonde matrix of degrees `deg` and sample + points `(x, y, z)`. If `l, m, n` are the given degrees in `x, y, z`, + then The pseudo-Vandermonde matrix is defined by + + .. math:: V[..., (m+1)(n+1)i + (n+1)j + k] = L_i(x)*L_j(y)*L_k(z), + + where `0 <= i <= l`, `0 <= j <= m`, and `0 <= j <= n`. The leading + indices of `V` index the points `(x, y, z)` and the last index encodes + the degrees of the Legendre polynomials. + + If ``V = legvander3d(x, y, z, [xdeg, ydeg, zdeg])``, then the columns + of `V` correspond to the elements of a 3-D coefficient array `c` of + shape (xdeg + 1, ydeg + 1, zdeg + 1) in the order + + .. math:: c_{000}, c_{001}, c_{002},... , c_{010}, c_{011}, c_{012},... + + and ``np.dot(V, c.flat)`` and ``legval3d(x, y, z, c)`` will be the + same up to roundoff. This equivalence is useful both for least squares + fitting and for the evaluation of a large number of 3-D Legendre + series of the same degrees and sample points. + + Parameters + ---------- + x, y, z : array_like + Arrays of point coordinates, all of the same shape. The dtypes will + be converted to either float64 or complex128 depending on whether + any of the elements are complex. Scalars are converted to 1-D + arrays. + deg : list of ints + List of maximum degrees of the form [x_deg, y_deg, z_deg]. + + Returns + ------- + vander3d : ndarray + The shape of the returned matrix is ``x.shape + (order,)``, where + :math:`order = (deg[0]+1)*(deg[1]+1)*(deg[2]+1)`. The dtype will + be the same as the converted `x`, `y`, and `z`. + + See Also + -------- + legvander, legvander3d, legval2d, legval3d + + Notes + ----- + + .. versionadded:: 1.7.0 + + """ + return pu._vander_nd_flat((legvander, legvander, legvander), (x, y, z), deg) + + +def legfit(x, y, deg, rcond=None, full=False, w=None): + """ + Least squares fit of Legendre series to data. + + Return the coefficients of a Legendre series of degree `deg` that is the + least squares fit to the data values `y` given at points `x`. If `y` is + 1-D the returned coefficients will also be 1-D. If `y` is 2-D multiple + fits are done, one for each column of `y`, and the resulting + coefficients are stored in the corresponding columns of a 2-D return. + The fitted polynomial(s) are in the form + + .. math:: p(x) = c_0 + c_1 * L_1(x) + ... + c_n * L_n(x), + + where `n` is `deg`. + + Parameters + ---------- + x : array_like, shape (M,) + x-coordinates of the M sample points ``(x[i], y[i])``. + y : array_like, shape (M,) or (M, K) + y-coordinates of the sample points. Several data sets of sample + points sharing the same x-coordinates can be fitted at once by + passing in a 2D-array that contains one dataset per column. + deg : int or 1-D array_like + Degree(s) of the fitting polynomials. If `deg` is a single integer + all terms up to and including the `deg`'th term are included in the + fit. For NumPy versions >= 1.11.0 a list of integers specifying the + degrees of the terms to include may be used instead. + rcond : float, optional + Relative condition number of the fit. Singular values smaller than + this relative to the largest singular value will be ignored. The + default value is len(x)*eps, where eps is the relative precision of + the float type, about 2e-16 in most cases. + full : bool, optional + Switch determining nature of return value. When it is False (the + default) just the coefficients are returned, when True diagnostic + information from the singular value decomposition is also returned. + w : array_like, shape (`M`,), optional + Weights. If not None, the contribution of each point + ``(x[i],y[i])`` to the fit is weighted by `w[i]`. Ideally the + weights are chosen so that the errors of the products ``w[i]*y[i]`` + all have the same variance. The default value is None. + + .. versionadded:: 1.5.0 + + Returns + ------- + coef : ndarray, shape (M,) or (M, K) + Legendre coefficients ordered from low to high. If `y` was + 2-D, the coefficients for the data in column k of `y` are in + column `k`. If `deg` is specified as a list, coefficients for + terms not included in the fit are set equal to zero in the + returned `coef`. + + [residuals, rank, singular_values, rcond] : list + These values are only returned if `full` = True + + resid -- sum of squared residuals of the least squares fit + rank -- the numerical rank of the scaled Vandermonde matrix + sv -- singular values of the scaled Vandermonde matrix + rcond -- value of `rcond`. + + For more details, see `numpy.linalg.lstsq`. + + Warns + ----- + RankWarning + The rank of the coefficient matrix in the least-squares fit is + deficient. The warning is only raised if `full` = False. The + warnings can be turned off by + + >>> import warnings + >>> warnings.simplefilter('ignore', np.RankWarning) + + See Also + -------- + numpy.polynomial.polynomial.polyfit + numpy.polynomial.chebyshev.chebfit + numpy.polynomial.laguerre.lagfit + numpy.polynomial.hermite.hermfit + numpy.polynomial.hermite_e.hermefit + legval : Evaluates a Legendre series. + legvander : Vandermonde matrix of Legendre series. + legweight : Legendre weight function (= 1). + numpy.linalg.lstsq : Computes a least-squares fit from the matrix. + scipy.interpolate.UnivariateSpline : Computes spline fits. + + Notes + ----- + The solution is the coefficients of the Legendre series `p` that + minimizes the sum of the weighted squared errors + + .. math:: E = \\sum_j w_j^2 * |y_j - p(x_j)|^2, + + where :math:`w_j` are the weights. This problem is solved by setting up + as the (typically) overdetermined matrix equation + + .. math:: V(x) * c = w * y, + + where `V` is the weighted pseudo Vandermonde matrix of `x`, `c` are the + coefficients to be solved for, `w` are the weights, and `y` are the + observed values. This equation is then solved using the singular value + decomposition of `V`. + + If some of the singular values of `V` are so small that they are + neglected, then a `RankWarning` will be issued. This means that the + coefficient values may be poorly determined. Using a lower order fit + will usually get rid of the warning. The `rcond` parameter can also be + set to a value smaller than its default, but the resulting fit may be + spurious and have large contributions from roundoff error. + + Fits using Legendre series are usually better conditioned than fits + using power series, but much can depend on the distribution of the + sample points and the smoothness of the data. If the quality of the fit + is inadequate splines may be a good alternative. + + References + ---------- + .. [1] Wikipedia, "Curve fitting", + https://en.wikipedia.org/wiki/Curve_fitting + + Examples + -------- + + """ + return pu._fit(legvander, x, y, deg, rcond, full, w) + + +def legcompanion(c): + """Return the scaled companion matrix of c. + + The basis polynomials are scaled so that the companion matrix is + symmetric when `c` is an Legendre basis polynomial. This provides + better eigenvalue estimates than the unscaled case and for basis + polynomials the eigenvalues are guaranteed to be real if + `numpy.linalg.eigvalsh` is used to obtain them. + + Parameters + ---------- + c : array_like + 1-D array of Legendre series coefficients ordered from low to high + degree. + + Returns + ------- + mat : ndarray + Scaled companion matrix of dimensions (deg, deg). + + Notes + ----- + + .. versionadded:: 1.7.0 + + """ + # c is a trimmed copy + [c] = pu.as_series([c]) + if len(c) < 2: + raise ValueError('Series must have maximum degree of at least 1.') + if len(c) == 2: + return np.array([[-c[0]/c[1]]]) + + n = len(c) - 1 + mat = np.zeros((n, n), dtype=c.dtype) + scl = 1./np.sqrt(2*np.arange(n) + 1) + top = mat.reshape(-1)[1::n+1] + bot = mat.reshape(-1)[n::n+1] + top[...] = np.arange(1, n)*scl[:n-1]*scl[1:n] + bot[...] = top + mat[:, -1] -= (c[:-1]/c[-1])*(scl/scl[-1])*(n/(2*n - 1)) + return mat + + +def legroots(c): + """ + Compute the roots of a Legendre series. + + Return the roots (a.k.a. "zeros") of the polynomial + + .. math:: p(x) = \\sum_i c[i] * L_i(x). + + Parameters + ---------- + c : 1-D array_like + 1-D array of coefficients. + + Returns + ------- + out : ndarray + Array of the roots of the series. If all the roots are real, + then `out` is also real, otherwise it is complex. + + See Also + -------- + numpy.polynomial.polynomial.polyroots + numpy.polynomial.chebyshev.chebroots + numpy.polynomial.laguerre.lagroots + numpy.polynomial.hermite.hermroots + numpy.polynomial.hermite_e.hermeroots + + Notes + ----- + The root estimates are obtained as the eigenvalues of the companion + matrix, Roots far from the origin of the complex plane may have large + errors due to the numerical instability of the series for such values. + Roots with multiplicity greater than 1 will also show larger errors as + the value of the series near such points is relatively insensitive to + errors in the roots. Isolated roots near the origin can be improved by + a few iterations of Newton's method. + + The Legendre series basis polynomials aren't powers of ``x`` so the + results of this function may seem unintuitive. + + Examples + -------- + >>> import numpy.polynomial.legendre as leg + >>> leg.legroots((1, 2, 3, 4)) # 4L_3 + 3L_2 + 2L_1 + 1L_0, all real roots + array([-0.85099543, -0.11407192, 0.51506735]) # may vary + + """ + # c is a trimmed copy + [c] = pu.as_series([c]) + if len(c) < 2: + return np.array([], dtype=c.dtype) + if len(c) == 2: + return np.array([-c[0]/c[1]]) + + # rotated companion matrix reduces error + m = legcompanion(c)[::-1,::-1] + r = la.eigvals(m) + r.sort() + return r + + +def leggauss(deg): + """ + Gauss-Legendre quadrature. + + Computes the sample points and weights for Gauss-Legendre quadrature. + These sample points and weights will correctly integrate polynomials of + degree :math:`2*deg - 1` or less over the interval :math:`[-1, 1]` with + the weight function :math:`f(x) = 1`. + + Parameters + ---------- + deg : int + Number of sample points and weights. It must be >= 1. + + Returns + ------- + x : ndarray + 1-D ndarray containing the sample points. + y : ndarray + 1-D ndarray containing the weights. + + Notes + ----- + + .. versionadded:: 1.7.0 + + The results have only been tested up to degree 100, higher degrees may + be problematic. The weights are determined by using the fact that + + .. math:: w_k = c / (L'_n(x_k) * L_{n-1}(x_k)) + + where :math:`c` is a constant independent of :math:`k` and :math:`x_k` + is the k'th root of :math:`L_n`, and then scaling the results to get + the right value when integrating 1. + + """ + ideg = pu._deprecate_as_int(deg, "deg") + if ideg <= 0: + raise ValueError("deg must be a positive integer") + + # first approximation of roots. We use the fact that the companion + # matrix is symmetric in this case in order to obtain better zeros. + c = np.array([0]*deg + [1]) + m = legcompanion(c) + x = la.eigvalsh(m) + + # improve roots by one application of Newton + dy = legval(x, c) + df = legval(x, legder(c)) + x -= dy/df + + # compute the weights. We scale the factor to avoid possible numerical + # overflow. + fm = legval(x, c[1:]) + fm /= np.abs(fm).max() + df /= np.abs(df).max() + w = 1/(fm * df) + + # for Legendre we can also symmetrize + w = (w + w[::-1])/2 + x = (x - x[::-1])/2 + + # scale w to get the right value + w *= 2. / w.sum() + + return x, w + + +def legweight(x): + """ + Weight function of the Legendre polynomials. + + The weight function is :math:`1` and the interval of integration is + :math:`[-1, 1]`. The Legendre polynomials are orthogonal, but not + normalized, with respect to this weight function. + + Parameters + ---------- + x : array_like + Values at which the weight function will be computed. + + Returns + ------- + w : ndarray + The weight function at `x`. + + Notes + ----- + + .. versionadded:: 1.7.0 + + """ + w = x*0.0 + 1.0 + return w + +# +# Legendre series class +# + +class Legendre(ABCPolyBase): + """A Legendre series class. + + The Legendre class provides the standard Python numerical methods + '+', '-', '*', '//', '%', 'divmod', '**', and '()' as well as the + attributes and methods listed in the `ABCPolyBase` documentation. + + Parameters + ---------- + coef : array_like + Legendre coefficients in order of increasing degree, i.e., + ``(1, 2, 3)`` gives ``1*P_0(x) + 2*P_1(x) + 3*P_2(x)``. + domain : (2,) array_like, optional + Domain to use. The interval ``[domain[0], domain[1]]`` is mapped + to the interval ``[window[0], window[1]]`` by shifting and scaling. + The default value is [-1, 1]. + window : (2,) array_like, optional + Window, see `domain` for its use. The default value is [-1, 1]. + + .. versionadded:: 1.6.0 + + """ + # Virtual Functions + _add = staticmethod(legadd) + _sub = staticmethod(legsub) + _mul = staticmethod(legmul) + _div = staticmethod(legdiv) + _pow = staticmethod(legpow) + _val = staticmethod(legval) + _int = staticmethod(legint) + _der = staticmethod(legder) + _fit = staticmethod(legfit) + _line = staticmethod(legline) + _roots = staticmethod(legroots) + _fromroots = staticmethod(legfromroots) + + # Virtual properties + domain = np.array(legdomain) + window = np.array(legdomain) + basis_name = 'P' diff --git a/venv/Lib/site-packages/numpy/polynomial/polynomial.py b/venv/Lib/site-packages/numpy/polynomial/polynomial.py new file mode 100644 index 0000000..1baa7d8 --- /dev/null +++ b/venv/Lib/site-packages/numpy/polynomial/polynomial.py @@ -0,0 +1,1529 @@ +""" +================================================= +Power Series (:mod:`numpy.polynomial.polynomial`) +================================================= + +This module provides a number of objects (mostly functions) useful for +dealing with polynomials, including a `Polynomial` class that +encapsulates the usual arithmetic operations. (General information +on how this module represents and works with polynomial objects is in +the docstring for its "parent" sub-package, `numpy.polynomial`). + +Classes +------- +.. autosummary:: + :toctree: generated/ + + Polynomial + +Constants +--------- +.. autosummary:: + :toctree: generated/ + + polydomain + polyzero + polyone + polyx + +Arithmetic +---------- +.. autosummary:: + :toctree: generated/ + + polyadd + polysub + polymulx + polymul + polydiv + polypow + polyval + polyval2d + polyval3d + polygrid2d + polygrid3d + +Calculus +-------- +.. autosummary:: + :toctree: generated/ + + polyder + polyint + +Misc Functions +-------------- +.. autosummary:: + :toctree: generated/ + + polyfromroots + polyroots + polyvalfromroots + polyvander + polyvander2d + polyvander3d + polycompanion + polyfit + polytrim + polyline + +See Also +-------- +`numpy.polynomial` + +""" +__all__ = [ + 'polyzero', 'polyone', 'polyx', 'polydomain', 'polyline', 'polyadd', + 'polysub', 'polymulx', 'polymul', 'polydiv', 'polypow', 'polyval', + 'polyvalfromroots', 'polyder', 'polyint', 'polyfromroots', 'polyvander', + 'polyfit', 'polytrim', 'polyroots', 'Polynomial', 'polyval2d', 'polyval3d', + 'polygrid2d', 'polygrid3d', 'polyvander2d', 'polyvander3d'] + +import numpy as np +import numpy.linalg as la +from numpy.core.multiarray import normalize_axis_index + +from . import polyutils as pu +from ._polybase import ABCPolyBase + +polytrim = pu.trimcoef + +# +# These are constant arrays are of integer type so as to be compatible +# with the widest range of other types, such as Decimal. +# + +# Polynomial default domain. +polydomain = np.array([-1, 1]) + +# Polynomial coefficients representing zero. +polyzero = np.array([0]) + +# Polynomial coefficients representing one. +polyone = np.array([1]) + +# Polynomial coefficients representing the identity x. +polyx = np.array([0, 1]) + +# +# Polynomial series functions +# + + +def polyline(off, scl): + """ + Returns an array representing a linear polynomial. + + Parameters + ---------- + off, scl : scalars + The "y-intercept" and "slope" of the line, respectively. + + Returns + ------- + y : ndarray + This module's representation of the linear polynomial ``off + + scl*x``. + + See Also + -------- + numpy.polynomial.chebyshev.chebline + numpy.polynomial.legendre.legline + numpy.polynomial.laguerre.lagline + numpy.polynomial.hermite.hermline + numpy.polynomial.hermite_e.hermeline + + Examples + -------- + >>> from numpy.polynomial import polynomial as P + >>> P.polyline(1,-1) + array([ 1, -1]) + >>> P.polyval(1, P.polyline(1,-1)) # should be 0 + 0.0 + + """ + if scl != 0: + return np.array([off, scl]) + else: + return np.array([off]) + + +def polyfromroots(roots): + """ + Generate a monic polynomial with given roots. + + Return the coefficients of the polynomial + + .. math:: p(x) = (x - r_0) * (x - r_1) * ... * (x - r_n), + + where the `r_n` are the roots specified in `roots`. If a zero has + multiplicity n, then it must appear in `roots` n times. For instance, + if 2 is a root of multiplicity three and 3 is a root of multiplicity 2, + then `roots` looks something like [2, 2, 2, 3, 3]. The roots can appear + in any order. + + If the returned coefficients are `c`, then + + .. math:: p(x) = c_0 + c_1 * x + ... + x^n + + The coefficient of the last term is 1 for monic polynomials in this + form. + + Parameters + ---------- + roots : array_like + Sequence containing the roots. + + Returns + ------- + out : ndarray + 1-D array of the polynomial's coefficients If all the roots are + real, then `out` is also real, otherwise it is complex. (see + Examples below). + + See Also + -------- + numpy.polynomial.chebyshev.chebfromroots + numpy.polynomial.legendre.legfromroots + numpy.polynomial.laguerre.lagfromroots + numpy.polynomial.hermite.hermfromroots + numpy.polynomial.hermite_e.hermefromroots + + Notes + ----- + The coefficients are determined by multiplying together linear factors + of the form `(x - r_i)`, i.e. + + .. math:: p(x) = (x - r_0) (x - r_1) ... (x - r_n) + + where ``n == len(roots) - 1``; note that this implies that `1` is always + returned for :math:`a_n`. + + Examples + -------- + >>> from numpy.polynomial import polynomial as P + >>> P.polyfromroots((-1,0,1)) # x(x - 1)(x + 1) = x^3 - x + array([ 0., -1., 0., 1.]) + >>> j = complex(0,1) + >>> P.polyfromroots((-j,j)) # complex returned, though values are real + array([1.+0.j, 0.+0.j, 1.+0.j]) + + """ + return pu._fromroots(polyline, polymul, roots) + + +def polyadd(c1, c2): + """ + Add one polynomial to another. + + Returns the sum of two polynomials `c1` + `c2`. The arguments are + sequences of coefficients from lowest order term to highest, i.e., + [1,2,3] represents the polynomial ``1 + 2*x + 3*x**2``. + + Parameters + ---------- + c1, c2 : array_like + 1-D arrays of polynomial coefficients ordered from low to high. + + Returns + ------- + out : ndarray + The coefficient array representing their sum. + + See Also + -------- + polysub, polymulx, polymul, polydiv, polypow + + Examples + -------- + >>> from numpy.polynomial import polynomial as P + >>> c1 = (1,2,3) + >>> c2 = (3,2,1) + >>> sum = P.polyadd(c1,c2); sum + array([4., 4., 4.]) + >>> P.polyval(2, sum) # 4 + 4(2) + 4(2**2) + 28.0 + + """ + return pu._add(c1, c2) + + +def polysub(c1, c2): + """ + Subtract one polynomial from another. + + Returns the difference of two polynomials `c1` - `c2`. The arguments + are sequences of coefficients from lowest order term to highest, i.e., + [1,2,3] represents the polynomial ``1 + 2*x + 3*x**2``. + + Parameters + ---------- + c1, c2 : array_like + 1-D arrays of polynomial coefficients ordered from low to + high. + + Returns + ------- + out : ndarray + Of coefficients representing their difference. + + See Also + -------- + polyadd, polymulx, polymul, polydiv, polypow + + Examples + -------- + >>> from numpy.polynomial import polynomial as P + >>> c1 = (1,2,3) + >>> c2 = (3,2,1) + >>> P.polysub(c1,c2) + array([-2., 0., 2.]) + >>> P.polysub(c2,c1) # -P.polysub(c1,c2) + array([ 2., 0., -2.]) + + """ + return pu._sub(c1, c2) + + +def polymulx(c): + """Multiply a polynomial by x. + + Multiply the polynomial `c` by x, where x is the independent + variable. + + + Parameters + ---------- + c : array_like + 1-D array of polynomial coefficients ordered from low to + high. + + Returns + ------- + out : ndarray + Array representing the result of the multiplication. + + See Also + -------- + polyadd, polysub, polymul, polydiv, polypow + + Notes + ----- + + .. versionadded:: 1.5.0 + + """ + # c is a trimmed copy + [c] = pu.as_series([c]) + # The zero series needs special treatment + if len(c) == 1 and c[0] == 0: + return c + + prd = np.empty(len(c) + 1, dtype=c.dtype) + prd[0] = c[0]*0 + prd[1:] = c + return prd + + +def polymul(c1, c2): + """ + Multiply one polynomial by another. + + Returns the product of two polynomials `c1` * `c2`. The arguments are + sequences of coefficients, from lowest order term to highest, e.g., + [1,2,3] represents the polynomial ``1 + 2*x + 3*x**2.`` + + Parameters + ---------- + c1, c2 : array_like + 1-D arrays of coefficients representing a polynomial, relative to the + "standard" basis, and ordered from lowest order term to highest. + + Returns + ------- + out : ndarray + Of the coefficients of their product. + + See Also + -------- + polyadd, polysub, polymulx, polydiv, polypow + + Examples + -------- + >>> from numpy.polynomial import polynomial as P + >>> c1 = (1,2,3) + >>> c2 = (3,2,1) + >>> P.polymul(c1,c2) + array([ 3., 8., 14., 8., 3.]) + + """ + # c1, c2 are trimmed copies + [c1, c2] = pu.as_series([c1, c2]) + ret = np.convolve(c1, c2) + return pu.trimseq(ret) + + +def polydiv(c1, c2): + """ + Divide one polynomial by another. + + Returns the quotient-with-remainder of two polynomials `c1` / `c2`. + The arguments are sequences of coefficients, from lowest order term + to highest, e.g., [1,2,3] represents ``1 + 2*x + 3*x**2``. + + Parameters + ---------- + c1, c2 : array_like + 1-D arrays of polynomial coefficients ordered from low to high. + + Returns + ------- + [quo, rem] : ndarrays + Of coefficient series representing the quotient and remainder. + + See Also + -------- + polyadd, polysub, polymulx, polymul, polypow + + Examples + -------- + >>> from numpy.polynomial import polynomial as P + >>> c1 = (1,2,3) + >>> c2 = (3,2,1) + >>> P.polydiv(c1,c2) + (array([3.]), array([-8., -4.])) + >>> P.polydiv(c2,c1) + (array([ 0.33333333]), array([ 2.66666667, 1.33333333])) # may vary + + """ + # c1, c2 are trimmed copies + [c1, c2] = pu.as_series([c1, c2]) + if c2[-1] == 0: + raise ZeroDivisionError() + + # note: this is more efficient than `pu._div(polymul, c1, c2)` + lc1 = len(c1) + lc2 = len(c2) + if lc1 < lc2: + return c1[:1]*0, c1 + elif lc2 == 1: + return c1/c2[-1], c1[:1]*0 + else: + dlen = lc1 - lc2 + scl = c2[-1] + c2 = c2[:-1]/scl + i = dlen + j = lc1 - 1 + while i >= 0: + c1[i:j] -= c2*c1[j] + i -= 1 + j -= 1 + return c1[j+1:]/scl, pu.trimseq(c1[:j+1]) + + +def polypow(c, pow, maxpower=None): + """Raise a polynomial to a power. + + Returns the polynomial `c` raised to the power `pow`. The argument + `c` is a sequence of coefficients ordered from low to high. i.e., + [1,2,3] is the series ``1 + 2*x + 3*x**2.`` + + Parameters + ---------- + c : array_like + 1-D array of array of series coefficients ordered from low to + high degree. + pow : integer + Power to which the series will be raised + maxpower : integer, optional + Maximum power allowed. This is mainly to limit growth of the series + to unmanageable size. Default is 16 + + Returns + ------- + coef : ndarray + Power series of power. + + See Also + -------- + polyadd, polysub, polymulx, polymul, polydiv + + Examples + -------- + >>> from numpy.polynomial import polynomial as P + >>> P.polypow([1,2,3], 2) + array([ 1., 4., 10., 12., 9.]) + + """ + # note: this is more efficient than `pu._pow(polymul, c1, c2)`, as it + # avoids calling `as_series` repeatedly + return pu._pow(np.convolve, c, pow, maxpower) + + +def polyder(c, m=1, scl=1, axis=0): + """ + Differentiate a polynomial. + + Returns the polynomial coefficients `c` differentiated `m` times along + `axis`. At each iteration the result is multiplied by `scl` (the + scaling factor is for use in a linear change of variable). The + argument `c` is an array of coefficients from low to high degree along + each axis, e.g., [1,2,3] represents the polynomial ``1 + 2*x + 3*x**2`` + while [[1,2],[1,2]] represents ``1 + 1*x + 2*y + 2*x*y`` if axis=0 is + ``x`` and axis=1 is ``y``. + + Parameters + ---------- + c : array_like + Array of polynomial coefficients. If c is multidimensional the + different axis correspond to different variables with the degree + in each axis given by the corresponding index. + m : int, optional + Number of derivatives taken, must be non-negative. (Default: 1) + scl : scalar, optional + Each differentiation is multiplied by `scl`. The end result is + multiplication by ``scl**m``. This is for use in a linear change + of variable. (Default: 1) + axis : int, optional + Axis over which the derivative is taken. (Default: 0). + + .. versionadded:: 1.7.0 + + Returns + ------- + der : ndarray + Polynomial coefficients of the derivative. + + See Also + -------- + polyint + + Examples + -------- + >>> from numpy.polynomial import polynomial as P + >>> c = (1,2,3,4) # 1 + 2x + 3x**2 + 4x**3 + >>> P.polyder(c) # (d/dx)(c) = 2 + 6x + 12x**2 + array([ 2., 6., 12.]) + >>> P.polyder(c,3) # (d**3/dx**3)(c) = 24 + array([24.]) + >>> P.polyder(c,scl=-1) # (d/d(-x))(c) = -2 - 6x - 12x**2 + array([ -2., -6., -12.]) + >>> P.polyder(c,2,-1) # (d**2/d(-x)**2)(c) = 6 + 24x + array([ 6., 24.]) + + """ + c = np.array(c, ndmin=1, copy=True) + if c.dtype.char in '?bBhHiIlLqQpP': + # astype fails with NA + c = c + 0.0 + cdt = c.dtype + cnt = pu._deprecate_as_int(m, "the order of derivation") + iaxis = pu._deprecate_as_int(axis, "the axis") + if cnt < 0: + raise ValueError("The order of derivation must be non-negative") + iaxis = normalize_axis_index(iaxis, c.ndim) + + if cnt == 0: + return c + + c = np.moveaxis(c, iaxis, 0) + n = len(c) + if cnt >= n: + c = c[:1]*0 + else: + for i in range(cnt): + n = n - 1 + c *= scl + der = np.empty((n,) + c.shape[1:], dtype=cdt) + for j in range(n, 0, -1): + der[j - 1] = j*c[j] + c = der + c = np.moveaxis(c, 0, iaxis) + return c + + +def polyint(c, m=1, k=[], lbnd=0, scl=1, axis=0): + """ + Integrate a polynomial. + + Returns the polynomial coefficients `c` integrated `m` times from + `lbnd` along `axis`. At each iteration the resulting series is + **multiplied** by `scl` and an integration constant, `k`, is added. + The scaling factor is for use in a linear change of variable. ("Buyer + beware": note that, depending on what one is doing, one may want `scl` + to be the reciprocal of what one might expect; for more information, + see the Notes section below.) The argument `c` is an array of + coefficients, from low to high degree along each axis, e.g., [1,2,3] + represents the polynomial ``1 + 2*x + 3*x**2`` while [[1,2],[1,2]] + represents ``1 + 1*x + 2*y + 2*x*y`` if axis=0 is ``x`` and axis=1 is + ``y``. + + Parameters + ---------- + c : array_like + 1-D array of polynomial coefficients, ordered from low to high. + m : int, optional + Order of integration, must be positive. (Default: 1) + k : {[], list, scalar}, optional + Integration constant(s). The value of the first integral at zero + is the first value in the list, the value of the second integral + at zero is the second value, etc. If ``k == []`` (the default), + all constants are set to zero. If ``m == 1``, a single scalar can + be given instead of a list. + lbnd : scalar, optional + The lower bound of the integral. (Default: 0) + scl : scalar, optional + Following each integration the result is *multiplied* by `scl` + before the integration constant is added. (Default: 1) + axis : int, optional + Axis over which the integral is taken. (Default: 0). + + .. versionadded:: 1.7.0 + + Returns + ------- + S : ndarray + Coefficient array of the integral. + + Raises + ------ + ValueError + If ``m < 1``, ``len(k) > m``, ``np.ndim(lbnd) != 0``, or + ``np.ndim(scl) != 0``. + + See Also + -------- + polyder + + Notes + ----- + Note that the result of each integration is *multiplied* by `scl`. Why + is this important to note? Say one is making a linear change of + variable :math:`u = ax + b` in an integral relative to `x`. Then + :math:`dx = du/a`, so one will need to set `scl` equal to + :math:`1/a` - perhaps not what one would have first thought. + + Examples + -------- + >>> from numpy.polynomial import polynomial as P + >>> c = (1,2,3) + >>> P.polyint(c) # should return array([0, 1, 1, 1]) + array([0., 1., 1., 1.]) + >>> P.polyint(c,3) # should return array([0, 0, 0, 1/6, 1/12, 1/20]) + array([ 0. , 0. , 0. , 0.16666667, 0.08333333, # may vary + 0.05 ]) + >>> P.polyint(c,k=3) # should return array([3, 1, 1, 1]) + array([3., 1., 1., 1.]) + >>> P.polyint(c,lbnd=-2) # should return array([6, 1, 1, 1]) + array([6., 1., 1., 1.]) + >>> P.polyint(c,scl=-2) # should return array([0, -2, -2, -2]) + array([ 0., -2., -2., -2.]) + + """ + c = np.array(c, ndmin=1, copy=True) + if c.dtype.char in '?bBhHiIlLqQpP': + # astype doesn't preserve mask attribute. + c = c + 0.0 + cdt = c.dtype + if not np.iterable(k): + k = [k] + cnt = pu._deprecate_as_int(m, "the order of integration") + iaxis = pu._deprecate_as_int(axis, "the axis") + if cnt < 0: + raise ValueError("The order of integration must be non-negative") + if len(k) > cnt: + raise ValueError("Too many integration constants") + if np.ndim(lbnd) != 0: + raise ValueError("lbnd must be a scalar.") + if np.ndim(scl) != 0: + raise ValueError("scl must be a scalar.") + iaxis = normalize_axis_index(iaxis, c.ndim) + + if cnt == 0: + return c + + k = list(k) + [0]*(cnt - len(k)) + c = np.moveaxis(c, iaxis, 0) + for i in range(cnt): + n = len(c) + c *= scl + if n == 1 and np.all(c[0] == 0): + c[0] += k[i] + else: + tmp = np.empty((n + 1,) + c.shape[1:], dtype=cdt) + tmp[0] = c[0]*0 + tmp[1] = c[0] + for j in range(1, n): + tmp[j + 1] = c[j]/(j + 1) + tmp[0] += k[i] - polyval(lbnd, tmp) + c = tmp + c = np.moveaxis(c, 0, iaxis) + return c + + +def polyval(x, c, tensor=True): + """ + Evaluate a polynomial at points x. + + If `c` is of length `n + 1`, this function returns the value + + .. math:: p(x) = c_0 + c_1 * x + ... + c_n * x^n + + The parameter `x` is converted to an array only if it is a tuple or a + list, otherwise it is treated as a scalar. In either case, either `x` + or its elements must support multiplication and addition both with + themselves and with the elements of `c`. + + If `c` is a 1-D array, then `p(x)` will have the same shape as `x`. If + `c` is multidimensional, then the shape of the result depends on the + value of `tensor`. If `tensor` is true the shape will be c.shape[1:] + + x.shape. If `tensor` is false the shape will be c.shape[1:]. Note that + scalars have shape (,). + + Trailing zeros in the coefficients will be used in the evaluation, so + they should be avoided if efficiency is a concern. + + Parameters + ---------- + x : array_like, compatible object + If `x` is a list or tuple, it is converted to an ndarray, otherwise + it is left unchanged and treated as a scalar. In either case, `x` + or its elements must support addition and multiplication with + with themselves and with the elements of `c`. + c : array_like + Array of coefficients ordered so that the coefficients for terms of + degree n are contained in c[n]. If `c` is multidimensional the + remaining indices enumerate multiple polynomials. In the two + dimensional case the coefficients may be thought of as stored in + the columns of `c`. + tensor : boolean, optional + If True, the shape of the coefficient array is extended with ones + on the right, one for each dimension of `x`. Scalars have dimension 0 + for this action. The result is that every column of coefficients in + `c` is evaluated for every element of `x`. If False, `x` is broadcast + over the columns of `c` for the evaluation. This keyword is useful + when `c` is multidimensional. The default value is True. + + .. versionadded:: 1.7.0 + + Returns + ------- + values : ndarray, compatible object + The shape of the returned array is described above. + + See Also + -------- + polyval2d, polygrid2d, polyval3d, polygrid3d + + Notes + ----- + The evaluation uses Horner's method. + + Examples + -------- + >>> from numpy.polynomial.polynomial import polyval + >>> polyval(1, [1,2,3]) + 6.0 + >>> a = np.arange(4).reshape(2,2) + >>> a + array([[0, 1], + [2, 3]]) + >>> polyval(a, [1,2,3]) + array([[ 1., 6.], + [17., 34.]]) + >>> coef = np.arange(4).reshape(2,2) # multidimensional coefficients + >>> coef + array([[0, 1], + [2, 3]]) + >>> polyval([1,2], coef, tensor=True) + array([[2., 4.], + [4., 7.]]) + >>> polyval([1,2], coef, tensor=False) + array([2., 7.]) + + """ + c = np.array(c, ndmin=1, copy=False) + if c.dtype.char in '?bBhHiIlLqQpP': + # astype fails with NA + c = c + 0.0 + if isinstance(x, (tuple, list)): + x = np.asarray(x) + if isinstance(x, np.ndarray) and tensor: + c = c.reshape(c.shape + (1,)*x.ndim) + + c0 = c[-1] + x*0 + for i in range(2, len(c) + 1): + c0 = c[-i] + c0*x + return c0 + + +def polyvalfromroots(x, r, tensor=True): + """ + Evaluate a polynomial specified by its roots at points x. + + If `r` is of length `N`, this function returns the value + + .. math:: p(x) = \\prod_{n=1}^{N} (x - r_n) + + The parameter `x` is converted to an array only if it is a tuple or a + list, otherwise it is treated as a scalar. In either case, either `x` + or its elements must support multiplication and addition both with + themselves and with the elements of `r`. + + If `r` is a 1-D array, then `p(x)` will have the same shape as `x`. If `r` + is multidimensional, then the shape of the result depends on the value of + `tensor`. If `tensor is ``True`` the shape will be r.shape[1:] + x.shape; + that is, each polynomial is evaluated at every value of `x`. If `tensor` is + ``False``, the shape will be r.shape[1:]; that is, each polynomial is + evaluated only for the corresponding broadcast value of `x`. Note that + scalars have shape (,). + + .. versionadded:: 1.12 + + Parameters + ---------- + x : array_like, compatible object + If `x` is a list or tuple, it is converted to an ndarray, otherwise + it is left unchanged and treated as a scalar. In either case, `x` + or its elements must support addition and multiplication with + with themselves and with the elements of `r`. + r : array_like + Array of roots. If `r` is multidimensional the first index is the + root index, while the remaining indices enumerate multiple + polynomials. For instance, in the two dimensional case the roots + of each polynomial may be thought of as stored in the columns of `r`. + tensor : boolean, optional + If True, the shape of the roots array is extended with ones on the + right, one for each dimension of `x`. Scalars have dimension 0 for this + action. The result is that every column of coefficients in `r` is + evaluated for every element of `x`. If False, `x` is broadcast over the + columns of `r` for the evaluation. This keyword is useful when `r` is + multidimensional. The default value is True. + + Returns + ------- + values : ndarray, compatible object + The shape of the returned array is described above. + + See Also + -------- + polyroots, polyfromroots, polyval + + Examples + -------- + >>> from numpy.polynomial.polynomial import polyvalfromroots + >>> polyvalfromroots(1, [1,2,3]) + 0.0 + >>> a = np.arange(4).reshape(2,2) + >>> a + array([[0, 1], + [2, 3]]) + >>> polyvalfromroots(a, [-1, 0, 1]) + array([[-0., 0.], + [ 6., 24.]]) + >>> r = np.arange(-2, 2).reshape(2,2) # multidimensional coefficients + >>> r # each column of r defines one polynomial + array([[-2, -1], + [ 0, 1]]) + >>> b = [-2, 1] + >>> polyvalfromroots(b, r, tensor=True) + array([[-0., 3.], + [ 3., 0.]]) + >>> polyvalfromroots(b, r, tensor=False) + array([-0., 0.]) + """ + r = np.array(r, ndmin=1, copy=False) + if r.dtype.char in '?bBhHiIlLqQpP': + r = r.astype(np.double) + if isinstance(x, (tuple, list)): + x = np.asarray(x) + if isinstance(x, np.ndarray): + if tensor: + r = r.reshape(r.shape + (1,)*x.ndim) + elif x.ndim >= r.ndim: + raise ValueError("x.ndim must be < r.ndim when tensor == False") + return np.prod(x - r, axis=0) + + +def polyval2d(x, y, c): + """ + Evaluate a 2-D polynomial at points (x, y). + + This function returns the value + + .. math:: p(x,y) = \\sum_{i,j} c_{i,j} * x^i * y^j + + The parameters `x` and `y` are converted to arrays only if they are + tuples or a lists, otherwise they are treated as a scalars and they + must have the same shape after conversion. In either case, either `x` + and `y` or their elements must support multiplication and addition both + with themselves and with the elements of `c`. + + If `c` has fewer than two dimensions, ones are implicitly appended to + its shape to make it 2-D. The shape of the result will be c.shape[2:] + + x.shape. + + Parameters + ---------- + x, y : array_like, compatible objects + The two dimensional series is evaluated at the points `(x, y)`, + where `x` and `y` must have the same shape. If `x` or `y` is a list + or tuple, it is first converted to an ndarray, otherwise it is left + unchanged and, if it isn't an ndarray, it is treated as a scalar. + c : array_like + Array of coefficients ordered so that the coefficient of the term + of multi-degree i,j is contained in `c[i,j]`. If `c` has + dimension greater than two the remaining indices enumerate multiple + sets of coefficients. + + Returns + ------- + values : ndarray, compatible object + The values of the two dimensional polynomial at points formed with + pairs of corresponding values from `x` and `y`. + + See Also + -------- + polyval, polygrid2d, polyval3d, polygrid3d + + Notes + ----- + + .. versionadded:: 1.7.0 + + """ + return pu._valnd(polyval, c, x, y) + + +def polygrid2d(x, y, c): + """ + Evaluate a 2-D polynomial on the Cartesian product of x and y. + + This function returns the values: + + .. math:: p(a,b) = \\sum_{i,j} c_{i,j} * a^i * b^j + + where the points `(a, b)` consist of all pairs formed by taking + `a` from `x` and `b` from `y`. The resulting points form a grid with + `x` in the first dimension and `y` in the second. + + The parameters `x` and `y` are converted to arrays only if they are + tuples or a lists, otherwise they are treated as a scalars. In either + case, either `x` and `y` or their elements must support multiplication + and addition both with themselves and with the elements of `c`. + + If `c` has fewer than two dimensions, ones are implicitly appended to + its shape to make it 2-D. The shape of the result will be c.shape[2:] + + x.shape + y.shape. + + Parameters + ---------- + x, y : array_like, compatible objects + The two dimensional series is evaluated at the points in the + Cartesian product of `x` and `y`. If `x` or `y` is a list or + tuple, it is first converted to an ndarray, otherwise it is left + unchanged and, if it isn't an ndarray, it is treated as a scalar. + c : array_like + Array of coefficients ordered so that the coefficients for terms of + degree i,j are contained in ``c[i,j]``. If `c` has dimension + greater than two the remaining indices enumerate multiple sets of + coefficients. + + Returns + ------- + values : ndarray, compatible object + The values of the two dimensional polynomial at points in the Cartesian + product of `x` and `y`. + + See Also + -------- + polyval, polyval2d, polyval3d, polygrid3d + + Notes + ----- + + .. versionadded:: 1.7.0 + + """ + return pu._gridnd(polyval, c, x, y) + + +def polyval3d(x, y, z, c): + """ + Evaluate a 3-D polynomial at points (x, y, z). + + This function returns the values: + + .. math:: p(x,y,z) = \\sum_{i,j,k} c_{i,j,k} * x^i * y^j * z^k + + The parameters `x`, `y`, and `z` are converted to arrays only if + they are tuples or a lists, otherwise they are treated as a scalars and + they must have the same shape after conversion. In either case, either + `x`, `y`, and `z` or their elements must support multiplication and + addition both with themselves and with the elements of `c`. + + If `c` has fewer than 3 dimensions, ones are implicitly appended to its + shape to make it 3-D. The shape of the result will be c.shape[3:] + + x.shape. + + Parameters + ---------- + x, y, z : array_like, compatible object + The three dimensional series is evaluated at the points + `(x, y, z)`, where `x`, `y`, and `z` must have the same shape. If + any of `x`, `y`, or `z` is a list or tuple, it is first converted + to an ndarray, otherwise it is left unchanged and if it isn't an + ndarray it is treated as a scalar. + c : array_like + Array of coefficients ordered so that the coefficient of the term of + multi-degree i,j,k is contained in ``c[i,j,k]``. If `c` has dimension + greater than 3 the remaining indices enumerate multiple sets of + coefficients. + + Returns + ------- + values : ndarray, compatible object + The values of the multidimensional polynomial on points formed with + triples of corresponding values from `x`, `y`, and `z`. + + See Also + -------- + polyval, polyval2d, polygrid2d, polygrid3d + + Notes + ----- + + .. versionadded:: 1.7.0 + + """ + return pu._valnd(polyval, c, x, y, z) + + +def polygrid3d(x, y, z, c): + """ + Evaluate a 3-D polynomial on the Cartesian product of x, y and z. + + This function returns the values: + + .. math:: p(a,b,c) = \\sum_{i,j,k} c_{i,j,k} * a^i * b^j * c^k + + where the points `(a, b, c)` consist of all triples formed by taking + `a` from `x`, `b` from `y`, and `c` from `z`. The resulting points form + a grid with `x` in the first dimension, `y` in the second, and `z` in + the third. + + The parameters `x`, `y`, and `z` are converted to arrays only if they + are tuples or a lists, otherwise they are treated as a scalars. In + either case, either `x`, `y`, and `z` or their elements must support + multiplication and addition both with themselves and with the elements + of `c`. + + If `c` has fewer than three dimensions, ones are implicitly appended to + its shape to make it 3-D. The shape of the result will be c.shape[3:] + + x.shape + y.shape + z.shape. + + Parameters + ---------- + x, y, z : array_like, compatible objects + The three dimensional series is evaluated at the points in the + Cartesian product of `x`, `y`, and `z`. If `x`,`y`, or `z` is a + list or tuple, it is first converted to an ndarray, otherwise it is + left unchanged and, if it isn't an ndarray, it is treated as a + scalar. + c : array_like + Array of coefficients ordered so that the coefficients for terms of + degree i,j are contained in ``c[i,j]``. If `c` has dimension + greater than two the remaining indices enumerate multiple sets of + coefficients. + + Returns + ------- + values : ndarray, compatible object + The values of the two dimensional polynomial at points in the Cartesian + product of `x` and `y`. + + See Also + -------- + polyval, polyval2d, polygrid2d, polyval3d + + Notes + ----- + + .. versionadded:: 1.7.0 + + """ + return pu._gridnd(polyval, c, x, y, z) + + +def polyvander(x, deg): + """Vandermonde matrix of given degree. + + Returns the Vandermonde matrix of degree `deg` and sample points + `x`. The Vandermonde matrix is defined by + + .. math:: V[..., i] = x^i, + + where `0 <= i <= deg`. The leading indices of `V` index the elements of + `x` and the last index is the power of `x`. + + If `c` is a 1-D array of coefficients of length `n + 1` and `V` is the + matrix ``V = polyvander(x, n)``, then ``np.dot(V, c)`` and + ``polyval(x, c)`` are the same up to roundoff. This equivalence is + useful both for least squares fitting and for the evaluation of a large + number of polynomials of the same degree and sample points. + + Parameters + ---------- + x : array_like + Array of points. The dtype is converted to float64 or complex128 + depending on whether any of the elements are complex. If `x` is + scalar it is converted to a 1-D array. + deg : int + Degree of the resulting matrix. + + Returns + ------- + vander : ndarray. + The Vandermonde matrix. The shape of the returned matrix is + ``x.shape + (deg + 1,)``, where the last index is the power of `x`. + The dtype will be the same as the converted `x`. + + See Also + -------- + polyvander2d, polyvander3d + + """ + ideg = pu._deprecate_as_int(deg, "deg") + if ideg < 0: + raise ValueError("deg must be non-negative") + + x = np.array(x, copy=False, ndmin=1) + 0.0 + dims = (ideg + 1,) + x.shape + dtyp = x.dtype + v = np.empty(dims, dtype=dtyp) + v[0] = x*0 + 1 + if ideg > 0: + v[1] = x + for i in range(2, ideg + 1): + v[i] = v[i-1]*x + return np.moveaxis(v, 0, -1) + + +def polyvander2d(x, y, deg): + """Pseudo-Vandermonde matrix of given degrees. + + Returns the pseudo-Vandermonde matrix of degrees `deg` and sample + points `(x, y)`. The pseudo-Vandermonde matrix is defined by + + .. math:: V[..., (deg[1] + 1)*i + j] = x^i * y^j, + + where `0 <= i <= deg[0]` and `0 <= j <= deg[1]`. The leading indices of + `V` index the points `(x, y)` and the last index encodes the powers of + `x` and `y`. + + If ``V = polyvander2d(x, y, [xdeg, ydeg])``, then the columns of `V` + correspond to the elements of a 2-D coefficient array `c` of shape + (xdeg + 1, ydeg + 1) in the order + + .. math:: c_{00}, c_{01}, c_{02} ... , c_{10}, c_{11}, c_{12} ... + + and ``np.dot(V, c.flat)`` and ``polyval2d(x, y, c)`` will be the same + up to roundoff. This equivalence is useful both for least squares + fitting and for the evaluation of a large number of 2-D polynomials + of the same degrees and sample points. + + Parameters + ---------- + x, y : array_like + Arrays of point coordinates, all of the same shape. The dtypes + will be converted to either float64 or complex128 depending on + whether any of the elements are complex. Scalars are converted to + 1-D arrays. + deg : list of ints + List of maximum degrees of the form [x_deg, y_deg]. + + Returns + ------- + vander2d : ndarray + The shape of the returned matrix is ``x.shape + (order,)``, where + :math:`order = (deg[0]+1)*(deg([1]+1)`. The dtype will be the same + as the converted `x` and `y`. + + See Also + -------- + polyvander, polyvander3d, polyval2d, polyval3d + + """ + return pu._vander_nd_flat((polyvander, polyvander), (x, y), deg) + + +def polyvander3d(x, y, z, deg): + """Pseudo-Vandermonde matrix of given degrees. + + Returns the pseudo-Vandermonde matrix of degrees `deg` and sample + points `(x, y, z)`. If `l, m, n` are the given degrees in `x, y, z`, + then The pseudo-Vandermonde matrix is defined by + + .. math:: V[..., (m+1)(n+1)i + (n+1)j + k] = x^i * y^j * z^k, + + where `0 <= i <= l`, `0 <= j <= m`, and `0 <= j <= n`. The leading + indices of `V` index the points `(x, y, z)` and the last index encodes + the powers of `x`, `y`, and `z`. + + If ``V = polyvander3d(x, y, z, [xdeg, ydeg, zdeg])``, then the columns + of `V` correspond to the elements of a 3-D coefficient array `c` of + shape (xdeg + 1, ydeg + 1, zdeg + 1) in the order + + .. math:: c_{000}, c_{001}, c_{002},... , c_{010}, c_{011}, c_{012},... + + and ``np.dot(V, c.flat)`` and ``polyval3d(x, y, z, c)`` will be the + same up to roundoff. This equivalence is useful both for least squares + fitting and for the evaluation of a large number of 3-D polynomials + of the same degrees and sample points. + + Parameters + ---------- + x, y, z : array_like + Arrays of point coordinates, all of the same shape. The dtypes will + be converted to either float64 or complex128 depending on whether + any of the elements are complex. Scalars are converted to 1-D + arrays. + deg : list of ints + List of maximum degrees of the form [x_deg, y_deg, z_deg]. + + Returns + ------- + vander3d : ndarray + The shape of the returned matrix is ``x.shape + (order,)``, where + :math:`order = (deg[0]+1)*(deg([1]+1)*(deg[2]+1)`. The dtype will + be the same as the converted `x`, `y`, and `z`. + + See Also + -------- + polyvander, polyvander3d, polyval2d, polyval3d + + Notes + ----- + + .. versionadded:: 1.7.0 + + """ + return pu._vander_nd_flat((polyvander, polyvander, polyvander), (x, y, z), deg) + + +def polyfit(x, y, deg, rcond=None, full=False, w=None): + """ + Least-squares fit of a polynomial to data. + + Return the coefficients of a polynomial of degree `deg` that is the + least squares fit to the data values `y` given at points `x`. If `y` is + 1-D the returned coefficients will also be 1-D. If `y` is 2-D multiple + fits are done, one for each column of `y`, and the resulting + coefficients are stored in the corresponding columns of a 2-D return. + The fitted polynomial(s) are in the form + + .. math:: p(x) = c_0 + c_1 * x + ... + c_n * x^n, + + where `n` is `deg`. + + Parameters + ---------- + x : array_like, shape (`M`,) + x-coordinates of the `M` sample (data) points ``(x[i], y[i])``. + y : array_like, shape (`M`,) or (`M`, `K`) + y-coordinates of the sample points. Several sets of sample points + sharing the same x-coordinates can be (independently) fit with one + call to `polyfit` by passing in for `y` a 2-D array that contains + one data set per column. + deg : int or 1-D array_like + Degree(s) of the fitting polynomials. If `deg` is a single integer + all terms up to and including the `deg`'th term are included in the + fit. For NumPy versions >= 1.11.0 a list of integers specifying the + degrees of the terms to include may be used instead. + rcond : float, optional + Relative condition number of the fit. Singular values smaller + than `rcond`, relative to the largest singular value, will be + ignored. The default value is ``len(x)*eps``, where `eps` is the + relative precision of the platform's float type, about 2e-16 in + most cases. + full : bool, optional + Switch determining the nature of the return value. When ``False`` + (the default) just the coefficients are returned; when ``True``, + diagnostic information from the singular value decomposition (used + to solve the fit's matrix equation) is also returned. + w : array_like, shape (`M`,), optional + Weights. If not None, the contribution of each point + ``(x[i],y[i])`` to the fit is weighted by `w[i]`. Ideally the + weights are chosen so that the errors of the products ``w[i]*y[i]`` + all have the same variance. The default value is None. + + .. versionadded:: 1.5.0 + + Returns + ------- + coef : ndarray, shape (`deg` + 1,) or (`deg` + 1, `K`) + Polynomial coefficients ordered from low to high. If `y` was 2-D, + the coefficients in column `k` of `coef` represent the polynomial + fit to the data in `y`'s `k`-th column. + + [residuals, rank, singular_values, rcond] : list + These values are only returned if `full` = True + + resid -- sum of squared residuals of the least squares fit + rank -- the numerical rank of the scaled Vandermonde matrix + sv -- singular values of the scaled Vandermonde matrix + rcond -- value of `rcond`. + + For more details, see `numpy.linalg.lstsq`. + + Raises + ------ + RankWarning + Raised if the matrix in the least-squares fit is rank deficient. + The warning is only raised if `full` == False. The warnings can + be turned off by: + + >>> import warnings + >>> warnings.simplefilter('ignore', np.RankWarning) + + See Also + -------- + numpy.polynomial.chebyshev.chebfit + numpy.polynomial.legendre.legfit + numpy.polynomial.laguerre.lagfit + numpy.polynomial.hermite.hermfit + numpy.polynomial.hermite_e.hermefit + polyval : Evaluates a polynomial. + polyvander : Vandermonde matrix for powers. + numpy.linalg.lstsq : Computes a least-squares fit from the matrix. + scipy.interpolate.UnivariateSpline : Computes spline fits. + + Notes + ----- + The solution is the coefficients of the polynomial `p` that minimizes + the sum of the weighted squared errors + + .. math :: E = \\sum_j w_j^2 * |y_j - p(x_j)|^2, + + where the :math:`w_j` are the weights. This problem is solved by + setting up the (typically) over-determined matrix equation: + + .. math :: V(x) * c = w * y, + + where `V` is the weighted pseudo Vandermonde matrix of `x`, `c` are the + coefficients to be solved for, `w` are the weights, and `y` are the + observed values. This equation is then solved using the singular value + decomposition of `V`. + + If some of the singular values of `V` are so small that they are + neglected (and `full` == ``False``), a `RankWarning` will be raised. + This means that the coefficient values may be poorly determined. + Fitting to a lower order polynomial will usually get rid of the warning + (but may not be what you want, of course; if you have independent + reason(s) for choosing the degree which isn't working, you may have to: + a) reconsider those reasons, and/or b) reconsider the quality of your + data). The `rcond` parameter can also be set to a value smaller than + its default, but the resulting fit may be spurious and have large + contributions from roundoff error. + + Polynomial fits using double precision tend to "fail" at about + (polynomial) degree 20. Fits using Chebyshev or Legendre series are + generally better conditioned, but much can still depend on the + distribution of the sample points and the smoothness of the data. If + the quality of the fit is inadequate, splines may be a good + alternative. + + Examples + -------- + >>> np.random.seed(123) + >>> from numpy.polynomial import polynomial as P + >>> x = np.linspace(-1,1,51) # x "data": [-1, -0.96, ..., 0.96, 1] + >>> y = x**3 - x + np.random.randn(len(x)) # x^3 - x + N(0,1) "noise" + >>> c, stats = P.polyfit(x,y,3,full=True) + >>> np.random.seed(123) + >>> c # c[0], c[2] should be approx. 0, c[1] approx. -1, c[3] approx. 1 + array([ 0.01909725, -1.30598256, -0.00577963, 1.02644286]) # may vary + >>> stats # note the large SSR, explaining the rather poor results + [array([ 38.06116253]), 4, array([ 1.38446749, 1.32119158, 0.50443316, # may vary + 0.28853036]), 1.1324274851176597e-014] + + Same thing without the added noise + + >>> y = x**3 - x + >>> c, stats = P.polyfit(x,y,3,full=True) + >>> c # c[0], c[2] should be "very close to 0", c[1] ~= -1, c[3] ~= 1 + array([-6.36925336e-18, -1.00000000e+00, -4.08053781e-16, 1.00000000e+00]) + >>> stats # note the minuscule SSR + [array([ 7.46346754e-31]), 4, array([ 1.38446749, 1.32119158, # may vary + 0.50443316, 0.28853036]), 1.1324274851176597e-014] + + """ + return pu._fit(polyvander, x, y, deg, rcond, full, w) + + +def polycompanion(c): + """ + Return the companion matrix of c. + + The companion matrix for power series cannot be made symmetric by + scaling the basis, so this function differs from those for the + orthogonal polynomials. + + Parameters + ---------- + c : array_like + 1-D array of polynomial coefficients ordered from low to high + degree. + + Returns + ------- + mat : ndarray + Companion matrix of dimensions (deg, deg). + + Notes + ----- + + .. versionadded:: 1.7.0 + + """ + # c is a trimmed copy + [c] = pu.as_series([c]) + if len(c) < 2: + raise ValueError('Series must have maximum degree of at least 1.') + if len(c) == 2: + return np.array([[-c[0]/c[1]]]) + + n = len(c) - 1 + mat = np.zeros((n, n), dtype=c.dtype) + bot = mat.reshape(-1)[n::n+1] + bot[...] = 1 + mat[:, -1] -= c[:-1]/c[-1] + return mat + + +def polyroots(c): + """ + Compute the roots of a polynomial. + + Return the roots (a.k.a. "zeros") of the polynomial + + .. math:: p(x) = \\sum_i c[i] * x^i. + + Parameters + ---------- + c : 1-D array_like + 1-D array of polynomial coefficients. + + Returns + ------- + out : ndarray + Array of the roots of the polynomial. If all the roots are real, + then `out` is also real, otherwise it is complex. + + See Also + -------- + numpy.polynomial.chebyshev.chebroots + numpy.polynomial.legendre.legroots + numpy.polynomial.laguerre.lagroots + numpy.polynomial.hermite.hermroots + numpy.polynomial.hermite_e.hermeroots + + Notes + ----- + The root estimates are obtained as the eigenvalues of the companion + matrix, Roots far from the origin of the complex plane may have large + errors due to the numerical instability of the power series for such + values. Roots with multiplicity greater than 1 will also show larger + errors as the value of the series near such points is relatively + insensitive to errors in the roots. Isolated roots near the origin can + be improved by a few iterations of Newton's method. + + Examples + -------- + >>> import numpy.polynomial.polynomial as poly + >>> poly.polyroots(poly.polyfromroots((-1,0,1))) + array([-1., 0., 1.]) + >>> poly.polyroots(poly.polyfromroots((-1,0,1))).dtype + dtype('float64') + >>> j = complex(0,1) + >>> poly.polyroots(poly.polyfromroots((-j,0,j))) + array([ 0.00000000e+00+0.j, 0.00000000e+00+1.j, 2.77555756e-17-1.j]) # may vary + + """ + # c is a trimmed copy + [c] = pu.as_series([c]) + if len(c) < 2: + return np.array([], dtype=c.dtype) + if len(c) == 2: + return np.array([-c[0]/c[1]]) + + # rotated companion matrix reduces error + m = polycompanion(c)[::-1,::-1] + r = la.eigvals(m) + r.sort() + return r + + +# +# polynomial class +# + +class Polynomial(ABCPolyBase): + """A power series class. + + The Polynomial class provides the standard Python numerical methods + '+', '-', '*', '//', '%', 'divmod', '**', and '()' as well as the + attributes and methods listed in the `ABCPolyBase` documentation. + + Parameters + ---------- + coef : array_like + Polynomial coefficients in order of increasing degree, i.e., + ``(1, 2, 3)`` give ``1 + 2*x + 3*x**2``. + domain : (2,) array_like, optional + Domain to use. The interval ``[domain[0], domain[1]]`` is mapped + to the interval ``[window[0], window[1]]`` by shifting and scaling. + The default value is [-1, 1]. + window : (2,) array_like, optional + Window, see `domain` for its use. The default value is [-1, 1]. + + .. versionadded:: 1.6.0 + + """ + # Virtual Functions + _add = staticmethod(polyadd) + _sub = staticmethod(polysub) + _mul = staticmethod(polymul) + _div = staticmethod(polydiv) + _pow = staticmethod(polypow) + _val = staticmethod(polyval) + _int = staticmethod(polyint) + _der = staticmethod(polyder) + _fit = staticmethod(polyfit) + _line = staticmethod(polyline) + _roots = staticmethod(polyroots) + _fromroots = staticmethod(polyfromroots) + + # Virtual properties + domain = np.array(polydomain) + window = np.array(polydomain) + basis_name = None + + @classmethod + def _str_term_unicode(cls, i, arg_str): + return f"·{arg_str}{i.translate(cls._superscript_mapping)}" + + @staticmethod + def _str_term_ascii(i, arg_str): + return f" {arg_str}**{i}" + + @staticmethod + def _repr_latex_term(i, arg_str, needs_parens): + if needs_parens: + arg_str = rf"\left({arg_str}\right)" + if i == 0: + return '1' + elif i == 1: + return arg_str + else: + return f"{arg_str}^{{{i}}}" diff --git a/venv/Lib/site-packages/numpy/polynomial/polyutils.py b/venv/Lib/site-packages/numpy/polynomial/polyutils.py new file mode 100644 index 0000000..d81ee97 --- /dev/null +++ b/venv/Lib/site-packages/numpy/polynomial/polyutils.py @@ -0,0 +1,796 @@ +""" +Utility classes and functions for the polynomial modules. + +This module provides: error and warning objects; a polynomial base class; +and some routines used in both the `polynomial` and `chebyshev` modules. + +Error objects +------------- + +.. autosummary:: + :toctree: generated/ + + PolyError base class for this sub-package's errors. + PolyDomainError raised when domains are mismatched. + +Warning objects +--------------- + +.. autosummary:: + :toctree: generated/ + + RankWarning raised in least-squares fit for rank-deficient matrix. + +Base class +---------- + +.. autosummary:: + :toctree: generated/ + + PolyBase Obsolete base class for the polynomial classes. Do not use. + +Functions +--------- + +.. autosummary:: + :toctree: generated/ + + as_series convert list of array_likes into 1-D arrays of common type. + trimseq remove trailing zeros. + trimcoef remove small trailing coefficients. + getdomain return the domain appropriate for a given set of abscissae. + mapdomain maps points between domains. + mapparms parameters of the linear map between domains. + +""" +import operator +import functools +import warnings + +import numpy as np + +__all__ = [ + 'RankWarning', 'PolyError', 'PolyDomainError', 'as_series', 'trimseq', + 'trimcoef', 'getdomain', 'mapdomain', 'mapparms', 'PolyBase'] + +# +# Warnings and Exceptions +# + +class RankWarning(UserWarning): + """Issued by chebfit when the design matrix is rank deficient.""" + pass + +class PolyError(Exception): + """Base class for errors in this module.""" + pass + +class PolyDomainError(PolyError): + """Issued by the generic Poly class when two domains don't match. + + This is raised when an binary operation is passed Poly objects with + different domains. + + """ + pass + +# +# Base class for all polynomial types +# + +class PolyBase: + """ + Base class for all polynomial types. + + Deprecated in numpy 1.9.0, use the abstract + ABCPolyBase class instead. Note that the latter + requires a number of virtual functions to be + implemented. + + """ + pass + +# +# Helper functions to convert inputs to 1-D arrays +# +def trimseq(seq): + """Remove small Poly series coefficients. + + Parameters + ---------- + seq : sequence + Sequence of Poly series coefficients. This routine fails for + empty sequences. + + Returns + ------- + series : sequence + Subsequence with trailing zeros removed. If the resulting sequence + would be empty, return the first element. The returned sequence may + or may not be a view. + + Notes + ----- + Do not lose the type info if the sequence contains unknown objects. + + """ + if len(seq) == 0: + return seq + else: + for i in range(len(seq) - 1, -1, -1): + if seq[i] != 0: + break + return seq[:i+1] + + +def as_series(alist, trim=True): + """ + Return argument as a list of 1-d arrays. + + The returned list contains array(s) of dtype double, complex double, or + object. A 1-d argument of shape ``(N,)`` is parsed into ``N`` arrays of + size one; a 2-d argument of shape ``(M,N)`` is parsed into ``M`` arrays + of size ``N`` (i.e., is "parsed by row"); and a higher dimensional array + raises a Value Error if it is not first reshaped into either a 1-d or 2-d + array. + + Parameters + ---------- + alist : array_like + A 1- or 2-d array_like + trim : boolean, optional + When True, trailing zeros are removed from the inputs. + When False, the inputs are passed through intact. + + Returns + ------- + [a1, a2,...] : list of 1-D arrays + A copy of the input data as a list of 1-d arrays. + + Raises + ------ + ValueError + Raised when `as_series` cannot convert its input to 1-d arrays, or at + least one of the resulting arrays is empty. + + Examples + -------- + >>> from numpy.polynomial import polyutils as pu + >>> a = np.arange(4) + >>> pu.as_series(a) + [array([0.]), array([1.]), array([2.]), array([3.])] + >>> b = np.arange(6).reshape((2,3)) + >>> pu.as_series(b) + [array([0., 1., 2.]), array([3., 4., 5.])] + + >>> pu.as_series((1, np.arange(3), np.arange(2, dtype=np.float16))) + [array([1.]), array([0., 1., 2.]), array([0., 1.])] + + >>> pu.as_series([2, [1.1, 0.]]) + [array([2.]), array([1.1])] + + >>> pu.as_series([2, [1.1, 0.]], trim=False) + [array([2.]), array([1.1, 0. ])] + + """ + arrays = [np.array(a, ndmin=1, copy=False) for a in alist] + if min([a.size for a in arrays]) == 0: + raise ValueError("Coefficient array is empty") + if any(a.ndim != 1 for a in arrays): + raise ValueError("Coefficient array is not 1-d") + if trim: + arrays = [trimseq(a) for a in arrays] + + if any(a.dtype == np.dtype(object) for a in arrays): + ret = [] + for a in arrays: + if a.dtype != np.dtype(object): + tmp = np.empty(len(a), dtype=np.dtype(object)) + tmp[:] = a[:] + ret.append(tmp) + else: + ret.append(a.copy()) + else: + try: + dtype = np.common_type(*arrays) + except Exception as e: + raise ValueError("Coefficient arrays have no common type") from e + ret = [np.array(a, copy=True, dtype=dtype) for a in arrays] + return ret + + +def trimcoef(c, tol=0): + """ + Remove "small" "trailing" coefficients from a polynomial. + + "Small" means "small in absolute value" and is controlled by the + parameter `tol`; "trailing" means highest order coefficient(s), e.g., in + ``[0, 1, 1, 0, 0]`` (which represents ``0 + x + x**2 + 0*x**3 + 0*x**4``) + both the 3-rd and 4-th order coefficients would be "trimmed." + + Parameters + ---------- + c : array_like + 1-d array of coefficients, ordered from lowest order to highest. + tol : number, optional + Trailing (i.e., highest order) elements with absolute value less + than or equal to `tol` (default value is zero) are removed. + + Returns + ------- + trimmed : ndarray + 1-d array with trailing zeros removed. If the resulting series + would be empty, a series containing a single zero is returned. + + Raises + ------ + ValueError + If `tol` < 0 + + See Also + -------- + trimseq + + Examples + -------- + >>> from numpy.polynomial import polyutils as pu + >>> pu.trimcoef((0,0,3,0,5,0,0)) + array([0., 0., 3., 0., 5.]) + >>> pu.trimcoef((0,0,1e-3,0,1e-5,0,0),1e-3) # item == tol is trimmed + array([0.]) + >>> i = complex(0,1) # works for complex + >>> pu.trimcoef((3e-4,1e-3*(1-i),5e-4,2e-5*(1+i)), 1e-3) + array([0.0003+0.j , 0.001 -0.001j]) + + """ + if tol < 0: + raise ValueError("tol must be non-negative") + + [c] = as_series([c]) + [ind] = np.nonzero(np.abs(c) > tol) + if len(ind) == 0: + return c[:1]*0 + else: + return c[:ind[-1] + 1].copy() + +def getdomain(x): + """ + Return a domain suitable for given abscissae. + + Find a domain suitable for a polynomial or Chebyshev series + defined at the values supplied. + + Parameters + ---------- + x : array_like + 1-d array of abscissae whose domain will be determined. + + Returns + ------- + domain : ndarray + 1-d array containing two values. If the inputs are complex, then + the two returned points are the lower left and upper right corners + of the smallest rectangle (aligned with the axes) in the complex + plane containing the points `x`. If the inputs are real, then the + two points are the ends of the smallest interval containing the + points `x`. + + See Also + -------- + mapparms, mapdomain + + Examples + -------- + >>> from numpy.polynomial import polyutils as pu + >>> points = np.arange(4)**2 - 5; points + array([-5, -4, -1, 4]) + >>> pu.getdomain(points) + array([-5., 4.]) + >>> c = np.exp(complex(0,1)*np.pi*np.arange(12)/6) # unit circle + >>> pu.getdomain(c) + array([-1.-1.j, 1.+1.j]) + + """ + [x] = as_series([x], trim=False) + if x.dtype.char in np.typecodes['Complex']: + rmin, rmax = x.real.min(), x.real.max() + imin, imax = x.imag.min(), x.imag.max() + return np.array((complex(rmin, imin), complex(rmax, imax))) + else: + return np.array((x.min(), x.max())) + +def mapparms(old, new): + """ + Linear map parameters between domains. + + Return the parameters of the linear map ``offset + scale*x`` that maps + `old` to `new` such that ``old[i] -> new[i]``, ``i = 0, 1``. + + Parameters + ---------- + old, new : array_like + Domains. Each domain must (successfully) convert to a 1-d array + containing precisely two values. + + Returns + ------- + offset, scale : scalars + The map ``L(x) = offset + scale*x`` maps the first domain to the + second. + + See Also + -------- + getdomain, mapdomain + + Notes + ----- + Also works for complex numbers, and thus can be used to calculate the + parameters required to map any line in the complex plane to any other + line therein. + + Examples + -------- + >>> from numpy.polynomial import polyutils as pu + >>> pu.mapparms((-1,1),(-1,1)) + (0.0, 1.0) + >>> pu.mapparms((1,-1),(-1,1)) + (-0.0, -1.0) + >>> i = complex(0,1) + >>> pu.mapparms((-i,-1),(1,i)) + ((1+1j), (1-0j)) + + """ + oldlen = old[1] - old[0] + newlen = new[1] - new[0] + off = (old[1]*new[0] - old[0]*new[1])/oldlen + scl = newlen/oldlen + return off, scl + +def mapdomain(x, old, new): + """ + Apply linear map to input points. + + The linear map ``offset + scale*x`` that maps the domain `old` to + the domain `new` is applied to the points `x`. + + Parameters + ---------- + x : array_like + Points to be mapped. If `x` is a subtype of ndarray the subtype + will be preserved. + old, new : array_like + The two domains that determine the map. Each must (successfully) + convert to 1-d arrays containing precisely two values. + + Returns + ------- + x_out : ndarray + Array of points of the same shape as `x`, after application of the + linear map between the two domains. + + See Also + -------- + getdomain, mapparms + + Notes + ----- + Effectively, this implements: + + .. math :: + x\\_out = new[0] + m(x - old[0]) + + where + + .. math :: + m = \\frac{new[1]-new[0]}{old[1]-old[0]} + + Examples + -------- + >>> from numpy.polynomial import polyutils as pu + >>> old_domain = (-1,1) + >>> new_domain = (0,2*np.pi) + >>> x = np.linspace(-1,1,6); x + array([-1. , -0.6, -0.2, 0.2, 0.6, 1. ]) + >>> x_out = pu.mapdomain(x, old_domain, new_domain); x_out + array([ 0. , 1.25663706, 2.51327412, 3.76991118, 5.02654825, # may vary + 6.28318531]) + >>> x - pu.mapdomain(x_out, new_domain, old_domain) + array([0., 0., 0., 0., 0., 0.]) + + Also works for complex numbers (and thus can be used to map any line in + the complex plane to any other line therein). + + >>> i = complex(0,1) + >>> old = (-1 - i, 1 + i) + >>> new = (-1 + i, 1 - i) + >>> z = np.linspace(old[0], old[1], 6); z + array([-1. -1.j , -0.6-0.6j, -0.2-0.2j, 0.2+0.2j, 0.6+0.6j, 1. +1.j ]) + >>> new_z = pu.mapdomain(z, old, new); new_z + array([-1.0+1.j , -0.6+0.6j, -0.2+0.2j, 0.2-0.2j, 0.6-0.6j, 1.0-1.j ]) # may vary + + """ + x = np.asanyarray(x) + off, scl = mapparms(old, new) + return off + scl*x + + +def _nth_slice(i, ndim): + sl = [np.newaxis] * ndim + sl[i] = slice(None) + return tuple(sl) + + +def _vander_nd(vander_fs, points, degrees): + r""" + A generalization of the Vandermonde matrix for N dimensions + + The result is built by combining the results of 1d Vandermonde matrices, + + .. math:: + W[i_0, \ldots, i_M, j_0, \ldots, j_N] = \prod_{k=0}^N{V_k(x_k)[i_0, \ldots, i_M, j_k]} + + where + + .. math:: + N &= \texttt{len(points)} = \texttt{len(degrees)} = \texttt{len(vander\_fs)} \\ + M &= \texttt{points[k].ndim} \\ + V_k &= \texttt{vander\_fs[k]} \\ + x_k &= \texttt{points[k]} \\ + 0 \le j_k &\le \texttt{degrees[k]} + + Expanding the one-dimensional :math:`V_k` functions gives: + + .. math:: + W[i_0, \ldots, i_M, j_0, \ldots, j_N] = \prod_{k=0}^N{B_{k, j_k}(x_k[i_0, \ldots, i_M])} + + where :math:`B_{k,m}` is the m'th basis of the polynomial construction used along + dimension :math:`k`. For a regular polynomial, :math:`B_{k, m}(x) = P_m(x) = x^m`. + + Parameters + ---------- + vander_fs : Sequence[function(array_like, int) -> ndarray] + The 1d vander function to use for each axis, such as ``polyvander`` + points : Sequence[array_like] + Arrays of point coordinates, all of the same shape. The dtypes + will be converted to either float64 or complex128 depending on + whether any of the elements are complex. Scalars are converted to + 1-D arrays. + This must be the same length as `vander_fs`. + degrees : Sequence[int] + The maximum degree (inclusive) to use for each axis. + This must be the same length as `vander_fs`. + + Returns + ------- + vander_nd : ndarray + An array of shape ``points[0].shape + tuple(d + 1 for d in degrees)``. + """ + n_dims = len(vander_fs) + if n_dims != len(points): + raise ValueError( + f"Expected {n_dims} dimensions of sample points, got {len(points)}") + if n_dims != len(degrees): + raise ValueError( + f"Expected {n_dims} dimensions of degrees, got {len(degrees)}") + if n_dims == 0: + raise ValueError("Unable to guess a dtype or shape when no points are given") + + # convert to the same shape and type + points = tuple(np.array(tuple(points), copy=False) + 0.0) + + # produce the vandermonde matrix for each dimension, placing the last + # axis of each in an independent trailing axis of the output + vander_arrays = ( + vander_fs[i](points[i], degrees[i])[(...,) + _nth_slice(i, n_dims)] + for i in range(n_dims) + ) + + # we checked this wasn't empty already, so no `initial` needed + return functools.reduce(operator.mul, vander_arrays) + + +def _vander_nd_flat(vander_fs, points, degrees): + """ + Like `_vander_nd`, but flattens the last ``len(degrees)`` axes into a single axis + + Used to implement the public ``vanderd`` functions. + """ + v = _vander_nd(vander_fs, points, degrees) + return v.reshape(v.shape[:-len(degrees)] + (-1,)) + + +def _fromroots(line_f, mul_f, roots): + """ + Helper function used to implement the ``fromroots`` functions. + + Parameters + ---------- + line_f : function(float, float) -> ndarray + The ``line`` function, such as ``polyline`` + mul_f : function(array_like, array_like) -> ndarray + The ``mul`` function, such as ``polymul`` + roots : + See the ``fromroots`` functions for more detail + """ + if len(roots) == 0: + return np.ones(1) + else: + [roots] = as_series([roots], trim=False) + roots.sort() + p = [line_f(-r, 1) for r in roots] + n = len(p) + while n > 1: + m, r = divmod(n, 2) + tmp = [mul_f(p[i], p[i+m]) for i in range(m)] + if r: + tmp[0] = mul_f(tmp[0], p[-1]) + p = tmp + n = m + return p[0] + + +def _valnd(val_f, c, *args): + """ + Helper function used to implement the ``vald`` functions. + + Parameters + ---------- + val_f : function(array_like, array_like, tensor: bool) -> array_like + The ``val`` function, such as ``polyval`` + c, args : + See the ``vald`` functions for more detail + """ + args = [np.asanyarray(a) for a in args] + shape0 = args[0].shape + if not all((a.shape == shape0 for a in args[1:])): + if len(args) == 3: + raise ValueError('x, y, z are incompatible') + elif len(args) == 2: + raise ValueError('x, y are incompatible') + else: + raise ValueError('ordinates are incompatible') + it = iter(args) + x0 = next(it) + + # use tensor on only the first + c = val_f(x0, c) + for xi in it: + c = val_f(xi, c, tensor=False) + return c + + +def _gridnd(val_f, c, *args): + """ + Helper function used to implement the ``gridd`` functions. + + Parameters + ---------- + val_f : function(array_like, array_like, tensor: bool) -> array_like + The ``val`` function, such as ``polyval`` + c, args : + See the ``gridd`` functions for more detail + """ + for xi in args: + c = val_f(xi, c) + return c + + +def _div(mul_f, c1, c2): + """ + Helper function used to implement the ``div`` functions. + + Implementation uses repeated subtraction of c2 multiplied by the nth basis. + For some polynomial types, a more efficient approach may be possible. + + Parameters + ---------- + mul_f : function(array_like, array_like) -> array_like + The ``mul`` function, such as ``polymul`` + c1, c2 : + See the ``div`` functions for more detail + """ + # c1, c2 are trimmed copies + [c1, c2] = as_series([c1, c2]) + if c2[-1] == 0: + raise ZeroDivisionError() + + lc1 = len(c1) + lc2 = len(c2) + if lc1 < lc2: + return c1[:1]*0, c1 + elif lc2 == 1: + return c1/c2[-1], c1[:1]*0 + else: + quo = np.empty(lc1 - lc2 + 1, dtype=c1.dtype) + rem = c1 + for i in range(lc1 - lc2, - 1, -1): + p = mul_f([0]*i + [1], c2) + q = rem[-1]/p[-1] + rem = rem[:-1] - q*p[:-1] + quo[i] = q + return quo, trimseq(rem) + + +def _add(c1, c2): + """ Helper function used to implement the ``add`` functions. """ + # c1, c2 are trimmed copies + [c1, c2] = as_series([c1, c2]) + if len(c1) > len(c2): + c1[:c2.size] += c2 + ret = c1 + else: + c2[:c1.size] += c1 + ret = c2 + return trimseq(ret) + + +def _sub(c1, c2): + """ Helper function used to implement the ``sub`` functions. """ + # c1, c2 are trimmed copies + [c1, c2] = as_series([c1, c2]) + if len(c1) > len(c2): + c1[:c2.size] -= c2 + ret = c1 + else: + c2 = -c2 + c2[:c1.size] += c1 + ret = c2 + return trimseq(ret) + + +def _fit(vander_f, x, y, deg, rcond=None, full=False, w=None): + """ + Helper function used to implement the ``fit`` functions. + + Parameters + ---------- + vander_f : function(array_like, int) -> ndarray + The 1d vander function, such as ``polyvander`` + c1, c2 : + See the ``fit`` functions for more detail + """ + x = np.asarray(x) + 0.0 + y = np.asarray(y) + 0.0 + deg = np.asarray(deg) + + # check arguments. + if deg.ndim > 1 or deg.dtype.kind not in 'iu' or deg.size == 0: + raise TypeError("deg must be an int or non-empty 1-D array of int") + if deg.min() < 0: + raise ValueError("expected deg >= 0") + if x.ndim != 1: + raise TypeError("expected 1D vector for x") + if x.size == 0: + raise TypeError("expected non-empty vector for x") + if y.ndim < 1 or y.ndim > 2: + raise TypeError("expected 1D or 2D array for y") + if len(x) != len(y): + raise TypeError("expected x and y to have same length") + + if deg.ndim == 0: + lmax = deg + order = lmax + 1 + van = vander_f(x, lmax) + else: + deg = np.sort(deg) + lmax = deg[-1] + order = len(deg) + van = vander_f(x, lmax)[:, deg] + + # set up the least squares matrices in transposed form + lhs = van.T + rhs = y.T + if w is not None: + w = np.asarray(w) + 0.0 + if w.ndim != 1: + raise TypeError("expected 1D vector for w") + if len(x) != len(w): + raise TypeError("expected x and w to have same length") + # apply weights. Don't use inplace operations as they + # can cause problems with NA. + lhs = lhs * w + rhs = rhs * w + + # set rcond + if rcond is None: + rcond = len(x)*np.finfo(x.dtype).eps + + # Determine the norms of the design matrix columns. + if issubclass(lhs.dtype.type, np.complexfloating): + scl = np.sqrt((np.square(lhs.real) + np.square(lhs.imag)).sum(1)) + else: + scl = np.sqrt(np.square(lhs).sum(1)) + scl[scl == 0] = 1 + + # Solve the least squares problem. + c, resids, rank, s = np.linalg.lstsq(lhs.T/scl, rhs.T, rcond) + c = (c.T/scl).T + + # Expand c to include non-fitted coefficients which are set to zero + if deg.ndim > 0: + if c.ndim == 2: + cc = np.zeros((lmax+1, c.shape[1]), dtype=c.dtype) + else: + cc = np.zeros(lmax+1, dtype=c.dtype) + cc[deg] = c + c = cc + + # warn on rank reduction + if rank != order and not full: + msg = "The fit may be poorly conditioned" + warnings.warn(msg, RankWarning, stacklevel=2) + + if full: + return c, [resids, rank, s, rcond] + else: + return c + + +def _pow(mul_f, c, pow, maxpower): + """ + Helper function used to implement the ``pow`` functions. + + Parameters + ---------- + vander_f : function(array_like, int) -> ndarray + The 1d vander function, such as ``polyvander`` + pow, maxpower : + See the ``pow`` functions for more detail + mul_f : function(array_like, array_like) -> ndarray + The ``mul`` function, such as ``polymul`` + """ + # c is a trimmed copy + [c] = as_series([c]) + power = int(pow) + if power != pow or power < 0: + raise ValueError("Power must be a non-negative integer.") + elif maxpower is not None and power > maxpower: + raise ValueError("Power is too large") + elif power == 0: + return np.array([1], dtype=c.dtype) + elif power == 1: + return c + else: + # This can be made more efficient by using powers of two + # in the usual way. + prd = c + for i in range(2, power + 1): + prd = mul_f(prd, c) + return prd + + +def _deprecate_as_int(x, desc): + """ + Like `operator.index`, but emits a deprecation warning when passed a float + + Parameters + ---------- + x : int-like, or float with integral value + Value to interpret as an integer + desc : str + description to include in any error message + + Raises + ------ + TypeError : if x is a non-integral float or non-numeric + DeprecationWarning : if x is an integral float + """ + try: + return operator.index(x) + except TypeError as e: + # Numpy 1.17.0, 2019-03-11 + try: + ix = int(x) + except TypeError: + pass + else: + if ix == x: + warnings.warn( + f"In future, this will raise TypeError, as {desc} will " + "need to be an integer not just an integral float.", + DeprecationWarning, + stacklevel=3 + ) + return ix + + raise TypeError(f"{desc} must be an integer") from e diff --git a/venv/Lib/site-packages/numpy/polynomial/setup.py b/venv/Lib/site-packages/numpy/polynomial/setup.py new file mode 100644 index 0000000..b58e867 --- /dev/null +++ b/venv/Lib/site-packages/numpy/polynomial/setup.py @@ -0,0 +1,10 @@ +def configuration(parent_package='',top_path=None): + from numpy.distutils.misc_util import Configuration + config = Configuration('polynomial', parent_package, top_path) + config.add_subpackage('tests') + config.add_data_files('*.pyi') + return config + +if __name__ == '__main__': + from numpy.distutils.core import setup + setup(configuration=configuration) diff --git a/venv/Lib/site-packages/numpy/polynomial/tests/__init__.py b/venv/Lib/site-packages/numpy/polynomial/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/venv/Lib/site-packages/numpy/polynomial/tests/test_chebyshev.py b/venv/Lib/site-packages/numpy/polynomial/tests/test_chebyshev.py new file mode 100644 index 0000000..2f54beb --- /dev/null +++ b/venv/Lib/site-packages/numpy/polynomial/tests/test_chebyshev.py @@ -0,0 +1,619 @@ +"""Tests for chebyshev module. + +""" +from functools import reduce + +import numpy as np +import numpy.polynomial.chebyshev as cheb +from numpy.polynomial.polynomial import polyval +from numpy.testing import ( + assert_almost_equal, assert_raises, assert_equal, assert_, + ) + + +def trim(x): + return cheb.chebtrim(x, tol=1e-6) + +T0 = [1] +T1 = [0, 1] +T2 = [-1, 0, 2] +T3 = [0, -3, 0, 4] +T4 = [1, 0, -8, 0, 8] +T5 = [0, 5, 0, -20, 0, 16] +T6 = [-1, 0, 18, 0, -48, 0, 32] +T7 = [0, -7, 0, 56, 0, -112, 0, 64] +T8 = [1, 0, -32, 0, 160, 0, -256, 0, 128] +T9 = [0, 9, 0, -120, 0, 432, 0, -576, 0, 256] + +Tlist = [T0, T1, T2, T3, T4, T5, T6, T7, T8, T9] + + +class TestPrivate: + + def test__cseries_to_zseries(self): + for i in range(5): + inp = np.array([2] + [1]*i, np.double) + tgt = np.array([.5]*i + [2] + [.5]*i, np.double) + res = cheb._cseries_to_zseries(inp) + assert_equal(res, tgt) + + def test__zseries_to_cseries(self): + for i in range(5): + inp = np.array([.5]*i + [2] + [.5]*i, np.double) + tgt = np.array([2] + [1]*i, np.double) + res = cheb._zseries_to_cseries(inp) + assert_equal(res, tgt) + + +class TestConstants: + + def test_chebdomain(self): + assert_equal(cheb.chebdomain, [-1, 1]) + + def test_chebzero(self): + assert_equal(cheb.chebzero, [0]) + + def test_chebone(self): + assert_equal(cheb.chebone, [1]) + + def test_chebx(self): + assert_equal(cheb.chebx, [0, 1]) + + +class TestArithmetic: + + def test_chebadd(self): + for i in range(5): + for j in range(5): + msg = f"At i={i}, j={j}" + tgt = np.zeros(max(i, j) + 1) + tgt[i] += 1 + tgt[j] += 1 + res = cheb.chebadd([0]*i + [1], [0]*j + [1]) + assert_equal(trim(res), trim(tgt), err_msg=msg) + + def test_chebsub(self): + for i in range(5): + for j in range(5): + msg = f"At i={i}, j={j}" + tgt = np.zeros(max(i, j) + 1) + tgt[i] += 1 + tgt[j] -= 1 + res = cheb.chebsub([0]*i + [1], [0]*j + [1]) + assert_equal(trim(res), trim(tgt), err_msg=msg) + + def test_chebmulx(self): + assert_equal(cheb.chebmulx([0]), [0]) + assert_equal(cheb.chebmulx([1]), [0, 1]) + for i in range(1, 5): + ser = [0]*i + [1] + tgt = [0]*(i - 1) + [.5, 0, .5] + assert_equal(cheb.chebmulx(ser), tgt) + + def test_chebmul(self): + for i in range(5): + for j in range(5): + msg = f"At i={i}, j={j}" + tgt = np.zeros(i + j + 1) + tgt[i + j] += .5 + tgt[abs(i - j)] += .5 + res = cheb.chebmul([0]*i + [1], [0]*j + [1]) + assert_equal(trim(res), trim(tgt), err_msg=msg) + + def test_chebdiv(self): + for i in range(5): + for j in range(5): + msg = f"At i={i}, j={j}" + ci = [0]*i + [1] + cj = [0]*j + [1] + tgt = cheb.chebadd(ci, cj) + quo, rem = cheb.chebdiv(tgt, ci) + res = cheb.chebadd(cheb.chebmul(quo, ci), rem) + assert_equal(trim(res), trim(tgt), err_msg=msg) + + def test_chebpow(self): + for i in range(5): + for j in range(5): + msg = f"At i={i}, j={j}" + c = np.arange(i + 1) + tgt = reduce(cheb.chebmul, [c]*j, np.array([1])) + res = cheb.chebpow(c, j) + assert_equal(trim(res), trim(tgt), err_msg=msg) + + +class TestEvaluation: + # coefficients of 1 + 2*x + 3*x**2 + c1d = np.array([2.5, 2., 1.5]) + c2d = np.einsum('i,j->ij', c1d, c1d) + c3d = np.einsum('i,j,k->ijk', c1d, c1d, c1d) + + # some random values in [-1, 1) + x = np.random.random((3, 5))*2 - 1 + y = polyval(x, [1., 2., 3.]) + + def test_chebval(self): + #check empty input + assert_equal(cheb.chebval([], [1]).size, 0) + + #check normal input) + x = np.linspace(-1, 1) + y = [polyval(x, c) for c in Tlist] + for i in range(10): + msg = f"At i={i}" + tgt = y[i] + res = cheb.chebval(x, [0]*i + [1]) + assert_almost_equal(res, tgt, err_msg=msg) + + #check that shape is preserved + for i in range(3): + dims = [2]*i + x = np.zeros(dims) + assert_equal(cheb.chebval(x, [1]).shape, dims) + assert_equal(cheb.chebval(x, [1, 0]).shape, dims) + assert_equal(cheb.chebval(x, [1, 0, 0]).shape, dims) + + def test_chebval2d(self): + x1, x2, x3 = self.x + y1, y2, y3 = self.y + + #test exceptions + assert_raises(ValueError, cheb.chebval2d, x1, x2[:2], self.c2d) + + #test values + tgt = y1*y2 + res = cheb.chebval2d(x1, x2, self.c2d) + assert_almost_equal(res, tgt) + + #test shape + z = np.ones((2, 3)) + res = cheb.chebval2d(z, z, self.c2d) + assert_(res.shape == (2, 3)) + + def test_chebval3d(self): + x1, x2, x3 = self.x + y1, y2, y3 = self.y + + #test exceptions + assert_raises(ValueError, cheb.chebval3d, x1, x2, x3[:2], self.c3d) + + #test values + tgt = y1*y2*y3 + res = cheb.chebval3d(x1, x2, x3, self.c3d) + assert_almost_equal(res, tgt) + + #test shape + z = np.ones((2, 3)) + res = cheb.chebval3d(z, z, z, self.c3d) + assert_(res.shape == (2, 3)) + + def test_chebgrid2d(self): + x1, x2, x3 = self.x + y1, y2, y3 = self.y + + #test values + tgt = np.einsum('i,j->ij', y1, y2) + res = cheb.chebgrid2d(x1, x2, self.c2d) + assert_almost_equal(res, tgt) + + #test shape + z = np.ones((2, 3)) + res = cheb.chebgrid2d(z, z, self.c2d) + assert_(res.shape == (2, 3)*2) + + def test_chebgrid3d(self): + x1, x2, x3 = self.x + y1, y2, y3 = self.y + + #test values + tgt = np.einsum('i,j,k->ijk', y1, y2, y3) + res = cheb.chebgrid3d(x1, x2, x3, self.c3d) + assert_almost_equal(res, tgt) + + #test shape + z = np.ones((2, 3)) + res = cheb.chebgrid3d(z, z, z, self.c3d) + assert_(res.shape == (2, 3)*3) + + +class TestIntegral: + + def test_chebint(self): + # check exceptions + assert_raises(TypeError, cheb.chebint, [0], .5) + assert_raises(ValueError, cheb.chebint, [0], -1) + assert_raises(ValueError, cheb.chebint, [0], 1, [0, 0]) + assert_raises(ValueError, cheb.chebint, [0], lbnd=[0]) + assert_raises(ValueError, cheb.chebint, [0], scl=[0]) + assert_raises(TypeError, cheb.chebint, [0], axis=.5) + + # test integration of zero polynomial + for i in range(2, 5): + k = [0]*(i - 2) + [1] + res = cheb.chebint([0], m=i, k=k) + assert_almost_equal(res, [0, 1]) + + # check single integration with integration constant + for i in range(5): + scl = i + 1 + pol = [0]*i + [1] + tgt = [i] + [0]*i + [1/scl] + chebpol = cheb.poly2cheb(pol) + chebint = cheb.chebint(chebpol, m=1, k=[i]) + res = cheb.cheb2poly(chebint) + assert_almost_equal(trim(res), trim(tgt)) + + # check single integration with integration constant and lbnd + for i in range(5): + scl = i + 1 + pol = [0]*i + [1] + chebpol = cheb.poly2cheb(pol) + chebint = cheb.chebint(chebpol, m=1, k=[i], lbnd=-1) + assert_almost_equal(cheb.chebval(-1, chebint), i) + + # check single integration with integration constant and scaling + for i in range(5): + scl = i + 1 + pol = [0]*i + [1] + tgt = [i] + [0]*i + [2/scl] + chebpol = cheb.poly2cheb(pol) + chebint = cheb.chebint(chebpol, m=1, k=[i], scl=2) + res = cheb.cheb2poly(chebint) + assert_almost_equal(trim(res), trim(tgt)) + + # check multiple integrations with default k + for i in range(5): + for j in range(2, 5): + pol = [0]*i + [1] + tgt = pol[:] + for k in range(j): + tgt = cheb.chebint(tgt, m=1) + res = cheb.chebint(pol, m=j) + assert_almost_equal(trim(res), trim(tgt)) + + # check multiple integrations with defined k + for i in range(5): + for j in range(2, 5): + pol = [0]*i + [1] + tgt = pol[:] + for k in range(j): + tgt = cheb.chebint(tgt, m=1, k=[k]) + res = cheb.chebint(pol, m=j, k=list(range(j))) + assert_almost_equal(trim(res), trim(tgt)) + + # check multiple integrations with lbnd + for i in range(5): + for j in range(2, 5): + pol = [0]*i + [1] + tgt = pol[:] + for k in range(j): + tgt = cheb.chebint(tgt, m=1, k=[k], lbnd=-1) + res = cheb.chebint(pol, m=j, k=list(range(j)), lbnd=-1) + assert_almost_equal(trim(res), trim(tgt)) + + # check multiple integrations with scaling + for i in range(5): + for j in range(2, 5): + pol = [0]*i + [1] + tgt = pol[:] + for k in range(j): + tgt = cheb.chebint(tgt, m=1, k=[k], scl=2) + res = cheb.chebint(pol, m=j, k=list(range(j)), scl=2) + assert_almost_equal(trim(res), trim(tgt)) + + def test_chebint_axis(self): + # check that axis keyword works + c2d = np.random.random((3, 4)) + + tgt = np.vstack([cheb.chebint(c) for c in c2d.T]).T + res = cheb.chebint(c2d, axis=0) + assert_almost_equal(res, tgt) + + tgt = np.vstack([cheb.chebint(c) for c in c2d]) + res = cheb.chebint(c2d, axis=1) + assert_almost_equal(res, tgt) + + tgt = np.vstack([cheb.chebint(c, k=3) for c in c2d]) + res = cheb.chebint(c2d, k=3, axis=1) + assert_almost_equal(res, tgt) + + +class TestDerivative: + + def test_chebder(self): + # check exceptions + assert_raises(TypeError, cheb.chebder, [0], .5) + assert_raises(ValueError, cheb.chebder, [0], -1) + + # check that zeroth derivative does nothing + for i in range(5): + tgt = [0]*i + [1] + res = cheb.chebder(tgt, m=0) + assert_equal(trim(res), trim(tgt)) + + # check that derivation is the inverse of integration + for i in range(5): + for j in range(2, 5): + tgt = [0]*i + [1] + res = cheb.chebder(cheb.chebint(tgt, m=j), m=j) + assert_almost_equal(trim(res), trim(tgt)) + + # check derivation with scaling + for i in range(5): + for j in range(2, 5): + tgt = [0]*i + [1] + res = cheb.chebder(cheb.chebint(tgt, m=j, scl=2), m=j, scl=.5) + assert_almost_equal(trim(res), trim(tgt)) + + def test_chebder_axis(self): + # check that axis keyword works + c2d = np.random.random((3, 4)) + + tgt = np.vstack([cheb.chebder(c) for c in c2d.T]).T + res = cheb.chebder(c2d, axis=0) + assert_almost_equal(res, tgt) + + tgt = np.vstack([cheb.chebder(c) for c in c2d]) + res = cheb.chebder(c2d, axis=1) + assert_almost_equal(res, tgt) + + +class TestVander: + # some random values in [-1, 1) + x = np.random.random((3, 5))*2 - 1 + + def test_chebvander(self): + # check for 1d x + x = np.arange(3) + v = cheb.chebvander(x, 3) + assert_(v.shape == (3, 4)) + for i in range(4): + coef = [0]*i + [1] + assert_almost_equal(v[..., i], cheb.chebval(x, coef)) + + # check for 2d x + x = np.array([[1, 2], [3, 4], [5, 6]]) + v = cheb.chebvander(x, 3) + assert_(v.shape == (3, 2, 4)) + for i in range(4): + coef = [0]*i + [1] + assert_almost_equal(v[..., i], cheb.chebval(x, coef)) + + def test_chebvander2d(self): + # also tests chebval2d for non-square coefficient array + x1, x2, x3 = self.x + c = np.random.random((2, 3)) + van = cheb.chebvander2d(x1, x2, [1, 2]) + tgt = cheb.chebval2d(x1, x2, c) + res = np.dot(van, c.flat) + assert_almost_equal(res, tgt) + + # check shape + van = cheb.chebvander2d([x1], [x2], [1, 2]) + assert_(van.shape == (1, 5, 6)) + + def test_chebvander3d(self): + # also tests chebval3d for non-square coefficient array + x1, x2, x3 = self.x + c = np.random.random((2, 3, 4)) + van = cheb.chebvander3d(x1, x2, x3, [1, 2, 3]) + tgt = cheb.chebval3d(x1, x2, x3, c) + res = np.dot(van, c.flat) + assert_almost_equal(res, tgt) + + # check shape + van = cheb.chebvander3d([x1], [x2], [x3], [1, 2, 3]) + assert_(van.shape == (1, 5, 24)) + + +class TestFitting: + + def test_chebfit(self): + def f(x): + return x*(x - 1)*(x - 2) + + def f2(x): + return x**4 + x**2 + 1 + + # Test exceptions + assert_raises(ValueError, cheb.chebfit, [1], [1], -1) + assert_raises(TypeError, cheb.chebfit, [[1]], [1], 0) + assert_raises(TypeError, cheb.chebfit, [], [1], 0) + assert_raises(TypeError, cheb.chebfit, [1], [[[1]]], 0) + assert_raises(TypeError, cheb.chebfit, [1, 2], [1], 0) + assert_raises(TypeError, cheb.chebfit, [1], [1, 2], 0) + assert_raises(TypeError, cheb.chebfit, [1], [1], 0, w=[[1]]) + assert_raises(TypeError, cheb.chebfit, [1], [1], 0, w=[1, 1]) + assert_raises(ValueError, cheb.chebfit, [1], [1], [-1,]) + assert_raises(ValueError, cheb.chebfit, [1], [1], [2, -1, 6]) + assert_raises(TypeError, cheb.chebfit, [1], [1], []) + + # Test fit + x = np.linspace(0, 2) + y = f(x) + # + coef3 = cheb.chebfit(x, y, 3) + assert_equal(len(coef3), 4) + assert_almost_equal(cheb.chebval(x, coef3), y) + coef3 = cheb.chebfit(x, y, [0, 1, 2, 3]) + assert_equal(len(coef3), 4) + assert_almost_equal(cheb.chebval(x, coef3), y) + # + coef4 = cheb.chebfit(x, y, 4) + assert_equal(len(coef4), 5) + assert_almost_equal(cheb.chebval(x, coef4), y) + coef4 = cheb.chebfit(x, y, [0, 1, 2, 3, 4]) + assert_equal(len(coef4), 5) + assert_almost_equal(cheb.chebval(x, coef4), y) + # check things still work if deg is not in strict increasing + coef4 = cheb.chebfit(x, y, [2, 3, 4, 1, 0]) + assert_equal(len(coef4), 5) + assert_almost_equal(cheb.chebval(x, coef4), y) + # + coef2d = cheb.chebfit(x, np.array([y, y]).T, 3) + assert_almost_equal(coef2d, np.array([coef3, coef3]).T) + coef2d = cheb.chebfit(x, np.array([y, y]).T, [0, 1, 2, 3]) + assert_almost_equal(coef2d, np.array([coef3, coef3]).T) + # test weighting + w = np.zeros_like(x) + yw = y.copy() + w[1::2] = 1 + y[0::2] = 0 + wcoef3 = cheb.chebfit(x, yw, 3, w=w) + assert_almost_equal(wcoef3, coef3) + wcoef3 = cheb.chebfit(x, yw, [0, 1, 2, 3], w=w) + assert_almost_equal(wcoef3, coef3) + # + wcoef2d = cheb.chebfit(x, np.array([yw, yw]).T, 3, w=w) + assert_almost_equal(wcoef2d, np.array([coef3, coef3]).T) + wcoef2d = cheb.chebfit(x, np.array([yw, yw]).T, [0, 1, 2, 3], w=w) + assert_almost_equal(wcoef2d, np.array([coef3, coef3]).T) + # test scaling with complex values x points whose square + # is zero when summed. + x = [1, 1j, -1, -1j] + assert_almost_equal(cheb.chebfit(x, x, 1), [0, 1]) + assert_almost_equal(cheb.chebfit(x, x, [0, 1]), [0, 1]) + # test fitting only even polynomials + x = np.linspace(-1, 1) + y = f2(x) + coef1 = cheb.chebfit(x, y, 4) + assert_almost_equal(cheb.chebval(x, coef1), y) + coef2 = cheb.chebfit(x, y, [0, 2, 4]) + assert_almost_equal(cheb.chebval(x, coef2), y) + assert_almost_equal(coef1, coef2) + + +class TestInterpolate: + + def f(self, x): + return x * (x - 1) * (x - 2) + + def test_raises(self): + assert_raises(ValueError, cheb.chebinterpolate, self.f, -1) + assert_raises(TypeError, cheb.chebinterpolate, self.f, 10.) + + def test_dimensions(self): + for deg in range(1, 5): + assert_(cheb.chebinterpolate(self.f, deg).shape == (deg + 1,)) + + def test_approximation(self): + + def powx(x, p): + return x**p + + x = np.linspace(-1, 1, 10) + for deg in range(0, 10): + for p in range(0, deg + 1): + c = cheb.chebinterpolate(powx, deg, (p,)) + assert_almost_equal(cheb.chebval(x, c), powx(x, p), decimal=12) + + +class TestCompanion: + + def test_raises(self): + assert_raises(ValueError, cheb.chebcompanion, []) + assert_raises(ValueError, cheb.chebcompanion, [1]) + + def test_dimensions(self): + for i in range(1, 5): + coef = [0]*i + [1] + assert_(cheb.chebcompanion(coef).shape == (i, i)) + + def test_linear_root(self): + assert_(cheb.chebcompanion([1, 2])[0, 0] == -.5) + + +class TestGauss: + + def test_100(self): + x, w = cheb.chebgauss(100) + + # test orthogonality. Note that the results need to be normalized, + # otherwise the huge values that can arise from fast growing + # functions like Laguerre can be very confusing. + v = cheb.chebvander(x, 99) + vv = np.dot(v.T * w, v) + vd = 1/np.sqrt(vv.diagonal()) + vv = vd[:, None] * vv * vd + assert_almost_equal(vv, np.eye(100)) + + # check that the integral of 1 is correct + tgt = np.pi + assert_almost_equal(w.sum(), tgt) + + +class TestMisc: + + def test_chebfromroots(self): + res = cheb.chebfromroots([]) + assert_almost_equal(trim(res), [1]) + for i in range(1, 5): + roots = np.cos(np.linspace(-np.pi, 0, 2*i + 1)[1::2]) + tgt = [0]*i + [1] + res = cheb.chebfromroots(roots)*2**(i-1) + assert_almost_equal(trim(res), trim(tgt)) + + def test_chebroots(self): + assert_almost_equal(cheb.chebroots([1]), []) + assert_almost_equal(cheb.chebroots([1, 2]), [-.5]) + for i in range(2, 5): + tgt = np.linspace(-1, 1, i) + res = cheb.chebroots(cheb.chebfromroots(tgt)) + assert_almost_equal(trim(res), trim(tgt)) + + def test_chebtrim(self): + coef = [2, -1, 1, 0] + + # Test exceptions + assert_raises(ValueError, cheb.chebtrim, coef, -1) + + # Test results + assert_equal(cheb.chebtrim(coef), coef[:-1]) + assert_equal(cheb.chebtrim(coef, 1), coef[:-3]) + assert_equal(cheb.chebtrim(coef, 2), [0]) + + def test_chebline(self): + assert_equal(cheb.chebline(3, 4), [3, 4]) + + def test_cheb2poly(self): + for i in range(10): + assert_almost_equal(cheb.cheb2poly([0]*i + [1]), Tlist[i]) + + def test_poly2cheb(self): + for i in range(10): + assert_almost_equal(cheb.poly2cheb(Tlist[i]), [0]*i + [1]) + + def test_weight(self): + x = np.linspace(-1, 1, 11)[1:-1] + tgt = 1./(np.sqrt(1 + x) * np.sqrt(1 - x)) + res = cheb.chebweight(x) + assert_almost_equal(res, tgt) + + def test_chebpts1(self): + #test exceptions + assert_raises(ValueError, cheb.chebpts1, 1.5) + assert_raises(ValueError, cheb.chebpts1, 0) + + #test points + tgt = [0] + assert_almost_equal(cheb.chebpts1(1), tgt) + tgt = [-0.70710678118654746, 0.70710678118654746] + assert_almost_equal(cheb.chebpts1(2), tgt) + tgt = [-0.86602540378443871, 0, 0.86602540378443871] + assert_almost_equal(cheb.chebpts1(3), tgt) + tgt = [-0.9238795325, -0.3826834323, 0.3826834323, 0.9238795325] + assert_almost_equal(cheb.chebpts1(4), tgt) + + def test_chebpts2(self): + #test exceptions + assert_raises(ValueError, cheb.chebpts2, 1.5) + assert_raises(ValueError, cheb.chebpts2, 1) + + #test points + tgt = [-1, 1] + assert_almost_equal(cheb.chebpts2(2), tgt) + tgt = [-1, 0, 1] + assert_almost_equal(cheb.chebpts2(3), tgt) + tgt = [-1, -0.5, .5, 1] + assert_almost_equal(cheb.chebpts2(4), tgt) + tgt = [-1.0, -0.707106781187, 0, 0.707106781187, 1.0] + assert_almost_equal(cheb.chebpts2(5), tgt) diff --git a/venv/Lib/site-packages/numpy/polynomial/tests/test_classes.py b/venv/Lib/site-packages/numpy/polynomial/tests/test_classes.py new file mode 100644 index 0000000..8e71a19 --- /dev/null +++ b/venv/Lib/site-packages/numpy/polynomial/tests/test_classes.py @@ -0,0 +1,600 @@ +"""Test inter-conversion of different polynomial classes. + +This tests the convert and cast methods of all the polynomial classes. + +""" +import operator as op +from numbers import Number + +import pytest +import numpy as np +from numpy.polynomial import ( + Polynomial, Legendre, Chebyshev, Laguerre, Hermite, HermiteE) +from numpy.testing import ( + assert_almost_equal, assert_raises, assert_equal, assert_, + ) +from numpy.polynomial.polyutils import RankWarning + +# +# fixtures +# + +classes = ( + Polynomial, Legendre, Chebyshev, Laguerre, + Hermite, HermiteE + ) +classids = tuple(cls.__name__ for cls in classes) + +@pytest.fixture(params=classes, ids=classids) +def Poly(request): + return request.param + +# +# helper functions +# +random = np.random.random + + +def assert_poly_almost_equal(p1, p2, msg=""): + try: + assert_(np.all(p1.domain == p2.domain)) + assert_(np.all(p1.window == p2.window)) + assert_almost_equal(p1.coef, p2.coef) + except AssertionError: + msg = f"Result: {p1}\nTarget: {p2}" + raise AssertionError(msg) + + +# +# Test conversion methods that depend on combinations of two classes. +# + +Poly1 = Poly +Poly2 = Poly + + +def test_conversion(Poly1, Poly2): + x = np.linspace(0, 1, 10) + coef = random((3,)) + + d1 = Poly1.domain + random((2,))*.25 + w1 = Poly1.window + random((2,))*.25 + p1 = Poly1(coef, domain=d1, window=w1) + + d2 = Poly2.domain + random((2,))*.25 + w2 = Poly2.window + random((2,))*.25 + p2 = p1.convert(kind=Poly2, domain=d2, window=w2) + + assert_almost_equal(p2.domain, d2) + assert_almost_equal(p2.window, w2) + assert_almost_equal(p2(x), p1(x)) + + +def test_cast(Poly1, Poly2): + x = np.linspace(0, 1, 10) + coef = random((3,)) + + d1 = Poly1.domain + random((2,))*.25 + w1 = Poly1.window + random((2,))*.25 + p1 = Poly1(coef, domain=d1, window=w1) + + d2 = Poly2.domain + random((2,))*.25 + w2 = Poly2.window + random((2,))*.25 + p2 = Poly2.cast(p1, domain=d2, window=w2) + + assert_almost_equal(p2.domain, d2) + assert_almost_equal(p2.window, w2) + assert_almost_equal(p2(x), p1(x)) + + +# +# test methods that depend on one class +# + + +def test_identity(Poly): + d = Poly.domain + random((2,))*.25 + w = Poly.window + random((2,))*.25 + x = np.linspace(d[0], d[1], 11) + p = Poly.identity(domain=d, window=w) + assert_equal(p.domain, d) + assert_equal(p.window, w) + assert_almost_equal(p(x), x) + + +def test_basis(Poly): + d = Poly.domain + random((2,))*.25 + w = Poly.window + random((2,))*.25 + p = Poly.basis(5, domain=d, window=w) + assert_equal(p.domain, d) + assert_equal(p.window, w) + assert_equal(p.coef, [0]*5 + [1]) + + +def test_fromroots(Poly): + # check that requested roots are zeros of a polynomial + # of correct degree, domain, and window. + d = Poly.domain + random((2,))*.25 + w = Poly.window + random((2,))*.25 + r = random((5,)) + p1 = Poly.fromroots(r, domain=d, window=w) + assert_equal(p1.degree(), len(r)) + assert_equal(p1.domain, d) + assert_equal(p1.window, w) + assert_almost_equal(p1(r), 0) + + # check that polynomial is monic + pdom = Polynomial.domain + pwin = Polynomial.window + p2 = Polynomial.cast(p1, domain=pdom, window=pwin) + assert_almost_equal(p2.coef[-1], 1) + + +def test_bad_conditioned_fit(Poly): + + x = [0., 0., 1.] + y = [1., 2., 3.] + + # check RankWarning is raised + with pytest.warns(RankWarning) as record: + Poly.fit(x, y, 2) + assert record[0].message.args[0] == "The fit may be poorly conditioned" + + +def test_fit(Poly): + + def f(x): + return x*(x - 1)*(x - 2) + x = np.linspace(0, 3) + y = f(x) + + # check default value of domain and window + p = Poly.fit(x, y, 3) + assert_almost_equal(p.domain, [0, 3]) + assert_almost_equal(p(x), y) + assert_equal(p.degree(), 3) + + # check with given domains and window + d = Poly.domain + random((2,))*.25 + w = Poly.window + random((2,))*.25 + p = Poly.fit(x, y, 3, domain=d, window=w) + assert_almost_equal(p(x), y) + assert_almost_equal(p.domain, d) + assert_almost_equal(p.window, w) + p = Poly.fit(x, y, [0, 1, 2, 3], domain=d, window=w) + assert_almost_equal(p(x), y) + assert_almost_equal(p.domain, d) + assert_almost_equal(p.window, w) + + # check with class domain default + p = Poly.fit(x, y, 3, []) + assert_equal(p.domain, Poly.domain) + assert_equal(p.window, Poly.window) + p = Poly.fit(x, y, [0, 1, 2, 3], []) + assert_equal(p.domain, Poly.domain) + assert_equal(p.window, Poly.window) + + # check that fit accepts weights. + w = np.zeros_like(x) + z = y + random(y.shape)*.25 + w[::2] = 1 + p1 = Poly.fit(x[::2], z[::2], 3) + p2 = Poly.fit(x, z, 3, w=w) + p3 = Poly.fit(x, z, [0, 1, 2, 3], w=w) + assert_almost_equal(p1(x), p2(x)) + assert_almost_equal(p2(x), p3(x)) + + +def test_equal(Poly): + p1 = Poly([1, 2, 3], domain=[0, 1], window=[2, 3]) + p2 = Poly([1, 1, 1], domain=[0, 1], window=[2, 3]) + p3 = Poly([1, 2, 3], domain=[1, 2], window=[2, 3]) + p4 = Poly([1, 2, 3], domain=[0, 1], window=[1, 2]) + assert_(p1 == p1) + assert_(not p1 == p2) + assert_(not p1 == p3) + assert_(not p1 == p4) + + +def test_not_equal(Poly): + p1 = Poly([1, 2, 3], domain=[0, 1], window=[2, 3]) + p2 = Poly([1, 1, 1], domain=[0, 1], window=[2, 3]) + p3 = Poly([1, 2, 3], domain=[1, 2], window=[2, 3]) + p4 = Poly([1, 2, 3], domain=[0, 1], window=[1, 2]) + assert_(not p1 != p1) + assert_(p1 != p2) + assert_(p1 != p3) + assert_(p1 != p4) + + +def test_add(Poly): + # This checks commutation, not numerical correctness + c1 = list(random((4,)) + .5) + c2 = list(random((3,)) + .5) + p1 = Poly(c1) + p2 = Poly(c2) + p3 = p1 + p2 + assert_poly_almost_equal(p2 + p1, p3) + assert_poly_almost_equal(p1 + c2, p3) + assert_poly_almost_equal(c2 + p1, p3) + assert_poly_almost_equal(p1 + tuple(c2), p3) + assert_poly_almost_equal(tuple(c2) + p1, p3) + assert_poly_almost_equal(p1 + np.array(c2), p3) + assert_poly_almost_equal(np.array(c2) + p1, p3) + assert_raises(TypeError, op.add, p1, Poly([0], domain=Poly.domain + 1)) + assert_raises(TypeError, op.add, p1, Poly([0], window=Poly.window + 1)) + if Poly is Polynomial: + assert_raises(TypeError, op.add, p1, Chebyshev([0])) + else: + assert_raises(TypeError, op.add, p1, Polynomial([0])) + + +def test_sub(Poly): + # This checks commutation, not numerical correctness + c1 = list(random((4,)) + .5) + c2 = list(random((3,)) + .5) + p1 = Poly(c1) + p2 = Poly(c2) + p3 = p1 - p2 + assert_poly_almost_equal(p2 - p1, -p3) + assert_poly_almost_equal(p1 - c2, p3) + assert_poly_almost_equal(c2 - p1, -p3) + assert_poly_almost_equal(p1 - tuple(c2), p3) + assert_poly_almost_equal(tuple(c2) - p1, -p3) + assert_poly_almost_equal(p1 - np.array(c2), p3) + assert_poly_almost_equal(np.array(c2) - p1, -p3) + assert_raises(TypeError, op.sub, p1, Poly([0], domain=Poly.domain + 1)) + assert_raises(TypeError, op.sub, p1, Poly([0], window=Poly.window + 1)) + if Poly is Polynomial: + assert_raises(TypeError, op.sub, p1, Chebyshev([0])) + else: + assert_raises(TypeError, op.sub, p1, Polynomial([0])) + + +def test_mul(Poly): + c1 = list(random((4,)) + .5) + c2 = list(random((3,)) + .5) + p1 = Poly(c1) + p2 = Poly(c2) + p3 = p1 * p2 + assert_poly_almost_equal(p2 * p1, p3) + assert_poly_almost_equal(p1 * c2, p3) + assert_poly_almost_equal(c2 * p1, p3) + assert_poly_almost_equal(p1 * tuple(c2), p3) + assert_poly_almost_equal(tuple(c2) * p1, p3) + assert_poly_almost_equal(p1 * np.array(c2), p3) + assert_poly_almost_equal(np.array(c2) * p1, p3) + assert_poly_almost_equal(p1 * 2, p1 * Poly([2])) + assert_poly_almost_equal(2 * p1, p1 * Poly([2])) + assert_raises(TypeError, op.mul, p1, Poly([0], domain=Poly.domain + 1)) + assert_raises(TypeError, op.mul, p1, Poly([0], window=Poly.window + 1)) + if Poly is Polynomial: + assert_raises(TypeError, op.mul, p1, Chebyshev([0])) + else: + assert_raises(TypeError, op.mul, p1, Polynomial([0])) + + +def test_floordiv(Poly): + c1 = list(random((4,)) + .5) + c2 = list(random((3,)) + .5) + c3 = list(random((2,)) + .5) + p1 = Poly(c1) + p2 = Poly(c2) + p3 = Poly(c3) + p4 = p1 * p2 + p3 + c4 = list(p4.coef) + assert_poly_almost_equal(p4 // p2, p1) + assert_poly_almost_equal(p4 // c2, p1) + assert_poly_almost_equal(c4 // p2, p1) + assert_poly_almost_equal(p4 // tuple(c2), p1) + assert_poly_almost_equal(tuple(c4) // p2, p1) + assert_poly_almost_equal(p4 // np.array(c2), p1) + assert_poly_almost_equal(np.array(c4) // p2, p1) + assert_poly_almost_equal(2 // p2, Poly([0])) + assert_poly_almost_equal(p2 // 2, 0.5*p2) + assert_raises( + TypeError, op.floordiv, p1, Poly([0], domain=Poly.domain + 1)) + assert_raises( + TypeError, op.floordiv, p1, Poly([0], window=Poly.window + 1)) + if Poly is Polynomial: + assert_raises(TypeError, op.floordiv, p1, Chebyshev([0])) + else: + assert_raises(TypeError, op.floordiv, p1, Polynomial([0])) + + +def test_truediv(Poly): + # true division is valid only if the denominator is a Number and + # not a python bool. + p1 = Poly([1,2,3]) + p2 = p1 * 5 + + for stype in np.ScalarType: + if not issubclass(stype, Number) or issubclass(stype, bool): + continue + s = stype(5) + assert_poly_almost_equal(op.truediv(p2, s), p1) + assert_raises(TypeError, op.truediv, s, p2) + for stype in (int, float): + s = stype(5) + assert_poly_almost_equal(op.truediv(p2, s), p1) + assert_raises(TypeError, op.truediv, s, p2) + for stype in [complex]: + s = stype(5, 0) + assert_poly_almost_equal(op.truediv(p2, s), p1) + assert_raises(TypeError, op.truediv, s, p2) + for s in [tuple(), list(), dict(), bool(), np.array([1])]: + assert_raises(TypeError, op.truediv, p2, s) + assert_raises(TypeError, op.truediv, s, p2) + for ptype in classes: + assert_raises(TypeError, op.truediv, p2, ptype(1)) + + +def test_mod(Poly): + # This checks commutation, not numerical correctness + c1 = list(random((4,)) + .5) + c2 = list(random((3,)) + .5) + c3 = list(random((2,)) + .5) + p1 = Poly(c1) + p2 = Poly(c2) + p3 = Poly(c3) + p4 = p1 * p2 + p3 + c4 = list(p4.coef) + assert_poly_almost_equal(p4 % p2, p3) + assert_poly_almost_equal(p4 % c2, p3) + assert_poly_almost_equal(c4 % p2, p3) + assert_poly_almost_equal(p4 % tuple(c2), p3) + assert_poly_almost_equal(tuple(c4) % p2, p3) + assert_poly_almost_equal(p4 % np.array(c2), p3) + assert_poly_almost_equal(np.array(c4) % p2, p3) + assert_poly_almost_equal(2 % p2, Poly([2])) + assert_poly_almost_equal(p2 % 2, Poly([0])) + assert_raises(TypeError, op.mod, p1, Poly([0], domain=Poly.domain + 1)) + assert_raises(TypeError, op.mod, p1, Poly([0], window=Poly.window + 1)) + if Poly is Polynomial: + assert_raises(TypeError, op.mod, p1, Chebyshev([0])) + else: + assert_raises(TypeError, op.mod, p1, Polynomial([0])) + + +def test_divmod(Poly): + # This checks commutation, not numerical correctness + c1 = list(random((4,)) + .5) + c2 = list(random((3,)) + .5) + c3 = list(random((2,)) + .5) + p1 = Poly(c1) + p2 = Poly(c2) + p3 = Poly(c3) + p4 = p1 * p2 + p3 + c4 = list(p4.coef) + quo, rem = divmod(p4, p2) + assert_poly_almost_equal(quo, p1) + assert_poly_almost_equal(rem, p3) + quo, rem = divmod(p4, c2) + assert_poly_almost_equal(quo, p1) + assert_poly_almost_equal(rem, p3) + quo, rem = divmod(c4, p2) + assert_poly_almost_equal(quo, p1) + assert_poly_almost_equal(rem, p3) + quo, rem = divmod(p4, tuple(c2)) + assert_poly_almost_equal(quo, p1) + assert_poly_almost_equal(rem, p3) + quo, rem = divmod(tuple(c4), p2) + assert_poly_almost_equal(quo, p1) + assert_poly_almost_equal(rem, p3) + quo, rem = divmod(p4, np.array(c2)) + assert_poly_almost_equal(quo, p1) + assert_poly_almost_equal(rem, p3) + quo, rem = divmod(np.array(c4), p2) + assert_poly_almost_equal(quo, p1) + assert_poly_almost_equal(rem, p3) + quo, rem = divmod(p2, 2) + assert_poly_almost_equal(quo, 0.5*p2) + assert_poly_almost_equal(rem, Poly([0])) + quo, rem = divmod(2, p2) + assert_poly_almost_equal(quo, Poly([0])) + assert_poly_almost_equal(rem, Poly([2])) + assert_raises(TypeError, divmod, p1, Poly([0], domain=Poly.domain + 1)) + assert_raises(TypeError, divmod, p1, Poly([0], window=Poly.window + 1)) + if Poly is Polynomial: + assert_raises(TypeError, divmod, p1, Chebyshev([0])) + else: + assert_raises(TypeError, divmod, p1, Polynomial([0])) + + +def test_roots(Poly): + d = Poly.domain * 1.25 + .25 + w = Poly.window + tgt = np.linspace(d[0], d[1], 5) + res = np.sort(Poly.fromroots(tgt, domain=d, window=w).roots()) + assert_almost_equal(res, tgt) + # default domain and window + res = np.sort(Poly.fromroots(tgt).roots()) + assert_almost_equal(res, tgt) + + +def test_degree(Poly): + p = Poly.basis(5) + assert_equal(p.degree(), 5) + + +def test_copy(Poly): + p1 = Poly.basis(5) + p2 = p1.copy() + assert_(p1 == p2) + assert_(p1 is not p2) + assert_(p1.coef is not p2.coef) + assert_(p1.domain is not p2.domain) + assert_(p1.window is not p2.window) + + +def test_integ(Poly): + P = Polynomial + # Check defaults + p0 = Poly.cast(P([1*2, 2*3, 3*4])) + p1 = P.cast(p0.integ()) + p2 = P.cast(p0.integ(2)) + assert_poly_almost_equal(p1, P([0, 2, 3, 4])) + assert_poly_almost_equal(p2, P([0, 0, 1, 1, 1])) + # Check with k + p0 = Poly.cast(P([1*2, 2*3, 3*4])) + p1 = P.cast(p0.integ(k=1)) + p2 = P.cast(p0.integ(2, k=[1, 1])) + assert_poly_almost_equal(p1, P([1, 2, 3, 4])) + assert_poly_almost_equal(p2, P([1, 1, 1, 1, 1])) + # Check with lbnd + p0 = Poly.cast(P([1*2, 2*3, 3*4])) + p1 = P.cast(p0.integ(lbnd=1)) + p2 = P.cast(p0.integ(2, lbnd=1)) + assert_poly_almost_equal(p1, P([-9, 2, 3, 4])) + assert_poly_almost_equal(p2, P([6, -9, 1, 1, 1])) + # Check scaling + d = 2*Poly.domain + p0 = Poly.cast(P([1*2, 2*3, 3*4]), domain=d) + p1 = P.cast(p0.integ()) + p2 = P.cast(p0.integ(2)) + assert_poly_almost_equal(p1, P([0, 2, 3, 4])) + assert_poly_almost_equal(p2, P([0, 0, 1, 1, 1])) + + +def test_deriv(Poly): + # Check that the derivative is the inverse of integration. It is + # assumes that the integration has been checked elsewhere. + d = Poly.domain + random((2,))*.25 + w = Poly.window + random((2,))*.25 + p1 = Poly([1, 2, 3], domain=d, window=w) + p2 = p1.integ(2, k=[1, 2]) + p3 = p1.integ(1, k=[1]) + assert_almost_equal(p2.deriv(1).coef, p3.coef) + assert_almost_equal(p2.deriv(2).coef, p1.coef) + # default domain and window + p1 = Poly([1, 2, 3]) + p2 = p1.integ(2, k=[1, 2]) + p3 = p1.integ(1, k=[1]) + assert_almost_equal(p2.deriv(1).coef, p3.coef) + assert_almost_equal(p2.deriv(2).coef, p1.coef) + + +def test_linspace(Poly): + d = Poly.domain + random((2,))*.25 + w = Poly.window + random((2,))*.25 + p = Poly([1, 2, 3], domain=d, window=w) + # check default domain + xtgt = np.linspace(d[0], d[1], 20) + ytgt = p(xtgt) + xres, yres = p.linspace(20) + assert_almost_equal(xres, xtgt) + assert_almost_equal(yres, ytgt) + # check specified domain + xtgt = np.linspace(0, 2, 20) + ytgt = p(xtgt) + xres, yres = p.linspace(20, domain=[0, 2]) + assert_almost_equal(xres, xtgt) + assert_almost_equal(yres, ytgt) + + +def test_pow(Poly): + d = Poly.domain + random((2,))*.25 + w = Poly.window + random((2,))*.25 + tgt = Poly([1], domain=d, window=w) + tst = Poly([1, 2, 3], domain=d, window=w) + for i in range(5): + assert_poly_almost_equal(tst**i, tgt) + tgt = tgt * tst + # default domain and window + tgt = Poly([1]) + tst = Poly([1, 2, 3]) + for i in range(5): + assert_poly_almost_equal(tst**i, tgt) + tgt = tgt * tst + # check error for invalid powers + assert_raises(ValueError, op.pow, tgt, 1.5) + assert_raises(ValueError, op.pow, tgt, -1) + + +def test_call(Poly): + P = Polynomial + d = Poly.domain + x = np.linspace(d[0], d[1], 11) + + # Check defaults + p = Poly.cast(P([1, 2, 3])) + tgt = 1 + x*(2 + 3*x) + res = p(x) + assert_almost_equal(res, tgt) + + +def test_cutdeg(Poly): + p = Poly([1, 2, 3]) + assert_raises(ValueError, p.cutdeg, .5) + assert_raises(ValueError, p.cutdeg, -1) + assert_equal(len(p.cutdeg(3)), 3) + assert_equal(len(p.cutdeg(2)), 3) + assert_equal(len(p.cutdeg(1)), 2) + assert_equal(len(p.cutdeg(0)), 1) + + +def test_truncate(Poly): + p = Poly([1, 2, 3]) + assert_raises(ValueError, p.truncate, .5) + assert_raises(ValueError, p.truncate, 0) + assert_equal(len(p.truncate(4)), 3) + assert_equal(len(p.truncate(3)), 3) + assert_equal(len(p.truncate(2)), 2) + assert_equal(len(p.truncate(1)), 1) + + +def test_trim(Poly): + c = [1, 1e-6, 1e-12, 0] + p = Poly(c) + assert_equal(p.trim().coef, c[:3]) + assert_equal(p.trim(1e-10).coef, c[:2]) + assert_equal(p.trim(1e-5).coef, c[:1]) + + +def test_mapparms(Poly): + # check with defaults. Should be identity. + d = Poly.domain + w = Poly.window + p = Poly([1], domain=d, window=w) + assert_almost_equal([0, 1], p.mapparms()) + # + w = 2*d + 1 + p = Poly([1], domain=d, window=w) + assert_almost_equal([1, 2], p.mapparms()) + + +def test_ufunc_override(Poly): + p = Poly([1, 2, 3]) + x = np.ones(3) + assert_raises(TypeError, np.add, p, x) + assert_raises(TypeError, np.add, x, p) + + +# +# Test class method that only exists for some classes +# + + +class TestInterpolate: + + def f(self, x): + return x * (x - 1) * (x - 2) + + def test_raises(self): + assert_raises(ValueError, Chebyshev.interpolate, self.f, -1) + assert_raises(TypeError, Chebyshev.interpolate, self.f, 10.) + + def test_dimensions(self): + for deg in range(1, 5): + assert_(Chebyshev.interpolate(self.f, deg).degree() == deg) + + def test_approximation(self): + + def powx(x, p): + return x**p + + x = np.linspace(0, 2, 10) + for deg in range(0, 10): + for t in range(0, deg + 1): + p = Chebyshev.interpolate(powx, deg, domain=[0, 2], args=(t,)) + assert_almost_equal(p(x), powx(x, t), decimal=12) diff --git a/venv/Lib/site-packages/numpy/polynomial/tests/test_hermite.py b/venv/Lib/site-packages/numpy/polynomial/tests/test_hermite.py new file mode 100644 index 0000000..53ee084 --- /dev/null +++ b/venv/Lib/site-packages/numpy/polynomial/tests/test_hermite.py @@ -0,0 +1,555 @@ +"""Tests for hermite module. + +""" +from functools import reduce + +import numpy as np +import numpy.polynomial.hermite as herm +from numpy.polynomial.polynomial import polyval +from numpy.testing import ( + assert_almost_equal, assert_raises, assert_equal, assert_, + ) + +H0 = np.array([1]) +H1 = np.array([0, 2]) +H2 = np.array([-2, 0, 4]) +H3 = np.array([0, -12, 0, 8]) +H4 = np.array([12, 0, -48, 0, 16]) +H5 = np.array([0, 120, 0, -160, 0, 32]) +H6 = np.array([-120, 0, 720, 0, -480, 0, 64]) +H7 = np.array([0, -1680, 0, 3360, 0, -1344, 0, 128]) +H8 = np.array([1680, 0, -13440, 0, 13440, 0, -3584, 0, 256]) +H9 = np.array([0, 30240, 0, -80640, 0, 48384, 0, -9216, 0, 512]) + +Hlist = [H0, H1, H2, H3, H4, H5, H6, H7, H8, H9] + + +def trim(x): + return herm.hermtrim(x, tol=1e-6) + + +class TestConstants: + + def test_hermdomain(self): + assert_equal(herm.hermdomain, [-1, 1]) + + def test_hermzero(self): + assert_equal(herm.hermzero, [0]) + + def test_hermone(self): + assert_equal(herm.hermone, [1]) + + def test_hermx(self): + assert_equal(herm.hermx, [0, .5]) + + +class TestArithmetic: + x = np.linspace(-3, 3, 100) + + def test_hermadd(self): + for i in range(5): + for j in range(5): + msg = f"At i={i}, j={j}" + tgt = np.zeros(max(i, j) + 1) + tgt[i] += 1 + tgt[j] += 1 + res = herm.hermadd([0]*i + [1], [0]*j + [1]) + assert_equal(trim(res), trim(tgt), err_msg=msg) + + def test_hermsub(self): + for i in range(5): + for j in range(5): + msg = f"At i={i}, j={j}" + tgt = np.zeros(max(i, j) + 1) + tgt[i] += 1 + tgt[j] -= 1 + res = herm.hermsub([0]*i + [1], [0]*j + [1]) + assert_equal(trim(res), trim(tgt), err_msg=msg) + + def test_hermmulx(self): + assert_equal(herm.hermmulx([0]), [0]) + assert_equal(herm.hermmulx([1]), [0, .5]) + for i in range(1, 5): + ser = [0]*i + [1] + tgt = [0]*(i - 1) + [i, 0, .5] + assert_equal(herm.hermmulx(ser), tgt) + + def test_hermmul(self): + # check values of result + for i in range(5): + pol1 = [0]*i + [1] + val1 = herm.hermval(self.x, pol1) + for j in range(5): + msg = f"At i={i}, j={j}" + pol2 = [0]*j + [1] + val2 = herm.hermval(self.x, pol2) + pol3 = herm.hermmul(pol1, pol2) + val3 = herm.hermval(self.x, pol3) + assert_(len(pol3) == i + j + 1, msg) + assert_almost_equal(val3, val1*val2, err_msg=msg) + + def test_hermdiv(self): + for i in range(5): + for j in range(5): + msg = f"At i={i}, j={j}" + ci = [0]*i + [1] + cj = [0]*j + [1] + tgt = herm.hermadd(ci, cj) + quo, rem = herm.hermdiv(tgt, ci) + res = herm.hermadd(herm.hermmul(quo, ci), rem) + assert_equal(trim(res), trim(tgt), err_msg=msg) + + def test_hermpow(self): + for i in range(5): + for j in range(5): + msg = f"At i={i}, j={j}" + c = np.arange(i + 1) + tgt = reduce(herm.hermmul, [c]*j, np.array([1])) + res = herm.hermpow(c, j) + assert_equal(trim(res), trim(tgt), err_msg=msg) + + +class TestEvaluation: + # coefficients of 1 + 2*x + 3*x**2 + c1d = np.array([2.5, 1., .75]) + c2d = np.einsum('i,j->ij', c1d, c1d) + c3d = np.einsum('i,j,k->ijk', c1d, c1d, c1d) + + # some random values in [-1, 1) + x = np.random.random((3, 5))*2 - 1 + y = polyval(x, [1., 2., 3.]) + + def test_hermval(self): + #check empty input + assert_equal(herm.hermval([], [1]).size, 0) + + #check normal input) + x = np.linspace(-1, 1) + y = [polyval(x, c) for c in Hlist] + for i in range(10): + msg = f"At i={i}" + tgt = y[i] + res = herm.hermval(x, [0]*i + [1]) + assert_almost_equal(res, tgt, err_msg=msg) + + #check that shape is preserved + for i in range(3): + dims = [2]*i + x = np.zeros(dims) + assert_equal(herm.hermval(x, [1]).shape, dims) + assert_equal(herm.hermval(x, [1, 0]).shape, dims) + assert_equal(herm.hermval(x, [1, 0, 0]).shape, dims) + + def test_hermval2d(self): + x1, x2, x3 = self.x + y1, y2, y3 = self.y + + #test exceptions + assert_raises(ValueError, herm.hermval2d, x1, x2[:2], self.c2d) + + #test values + tgt = y1*y2 + res = herm.hermval2d(x1, x2, self.c2d) + assert_almost_equal(res, tgt) + + #test shape + z = np.ones((2, 3)) + res = herm.hermval2d(z, z, self.c2d) + assert_(res.shape == (2, 3)) + + def test_hermval3d(self): + x1, x2, x3 = self.x + y1, y2, y3 = self.y + + #test exceptions + assert_raises(ValueError, herm.hermval3d, x1, x2, x3[:2], self.c3d) + + #test values + tgt = y1*y2*y3 + res = herm.hermval3d(x1, x2, x3, self.c3d) + assert_almost_equal(res, tgt) + + #test shape + z = np.ones((2, 3)) + res = herm.hermval3d(z, z, z, self.c3d) + assert_(res.shape == (2, 3)) + + def test_hermgrid2d(self): + x1, x2, x3 = self.x + y1, y2, y3 = self.y + + #test values + tgt = np.einsum('i,j->ij', y1, y2) + res = herm.hermgrid2d(x1, x2, self.c2d) + assert_almost_equal(res, tgt) + + #test shape + z = np.ones((2, 3)) + res = herm.hermgrid2d(z, z, self.c2d) + assert_(res.shape == (2, 3)*2) + + def test_hermgrid3d(self): + x1, x2, x3 = self.x + y1, y2, y3 = self.y + + #test values + tgt = np.einsum('i,j,k->ijk', y1, y2, y3) + res = herm.hermgrid3d(x1, x2, x3, self.c3d) + assert_almost_equal(res, tgt) + + #test shape + z = np.ones((2, 3)) + res = herm.hermgrid3d(z, z, z, self.c3d) + assert_(res.shape == (2, 3)*3) + + +class TestIntegral: + + def test_hermint(self): + # check exceptions + assert_raises(TypeError, herm.hermint, [0], .5) + assert_raises(ValueError, herm.hermint, [0], -1) + assert_raises(ValueError, herm.hermint, [0], 1, [0, 0]) + assert_raises(ValueError, herm.hermint, [0], lbnd=[0]) + assert_raises(ValueError, herm.hermint, [0], scl=[0]) + assert_raises(TypeError, herm.hermint, [0], axis=.5) + + # test integration of zero polynomial + for i in range(2, 5): + k = [0]*(i - 2) + [1] + res = herm.hermint([0], m=i, k=k) + assert_almost_equal(res, [0, .5]) + + # check single integration with integration constant + for i in range(5): + scl = i + 1 + pol = [0]*i + [1] + tgt = [i] + [0]*i + [1/scl] + hermpol = herm.poly2herm(pol) + hermint = herm.hermint(hermpol, m=1, k=[i]) + res = herm.herm2poly(hermint) + assert_almost_equal(trim(res), trim(tgt)) + + # check single integration with integration constant and lbnd + for i in range(5): + scl = i + 1 + pol = [0]*i + [1] + hermpol = herm.poly2herm(pol) + hermint = herm.hermint(hermpol, m=1, k=[i], lbnd=-1) + assert_almost_equal(herm.hermval(-1, hermint), i) + + # check single integration with integration constant and scaling + for i in range(5): + scl = i + 1 + pol = [0]*i + [1] + tgt = [i] + [0]*i + [2/scl] + hermpol = herm.poly2herm(pol) + hermint = herm.hermint(hermpol, m=1, k=[i], scl=2) + res = herm.herm2poly(hermint) + assert_almost_equal(trim(res), trim(tgt)) + + # check multiple integrations with default k + for i in range(5): + for j in range(2, 5): + pol = [0]*i + [1] + tgt = pol[:] + for k in range(j): + tgt = herm.hermint(tgt, m=1) + res = herm.hermint(pol, m=j) + assert_almost_equal(trim(res), trim(tgt)) + + # check multiple integrations with defined k + for i in range(5): + for j in range(2, 5): + pol = [0]*i + [1] + tgt = pol[:] + for k in range(j): + tgt = herm.hermint(tgt, m=1, k=[k]) + res = herm.hermint(pol, m=j, k=list(range(j))) + assert_almost_equal(trim(res), trim(tgt)) + + # check multiple integrations with lbnd + for i in range(5): + for j in range(2, 5): + pol = [0]*i + [1] + tgt = pol[:] + for k in range(j): + tgt = herm.hermint(tgt, m=1, k=[k], lbnd=-1) + res = herm.hermint(pol, m=j, k=list(range(j)), lbnd=-1) + assert_almost_equal(trim(res), trim(tgt)) + + # check multiple integrations with scaling + for i in range(5): + for j in range(2, 5): + pol = [0]*i + [1] + tgt = pol[:] + for k in range(j): + tgt = herm.hermint(tgt, m=1, k=[k], scl=2) + res = herm.hermint(pol, m=j, k=list(range(j)), scl=2) + assert_almost_equal(trim(res), trim(tgt)) + + def test_hermint_axis(self): + # check that axis keyword works + c2d = np.random.random((3, 4)) + + tgt = np.vstack([herm.hermint(c) for c in c2d.T]).T + res = herm.hermint(c2d, axis=0) + assert_almost_equal(res, tgt) + + tgt = np.vstack([herm.hermint(c) for c in c2d]) + res = herm.hermint(c2d, axis=1) + assert_almost_equal(res, tgt) + + tgt = np.vstack([herm.hermint(c, k=3) for c in c2d]) + res = herm.hermint(c2d, k=3, axis=1) + assert_almost_equal(res, tgt) + + +class TestDerivative: + + def test_hermder(self): + # check exceptions + assert_raises(TypeError, herm.hermder, [0], .5) + assert_raises(ValueError, herm.hermder, [0], -1) + + # check that zeroth derivative does nothing + for i in range(5): + tgt = [0]*i + [1] + res = herm.hermder(tgt, m=0) + assert_equal(trim(res), trim(tgt)) + + # check that derivation is the inverse of integration + for i in range(5): + for j in range(2, 5): + tgt = [0]*i + [1] + res = herm.hermder(herm.hermint(tgt, m=j), m=j) + assert_almost_equal(trim(res), trim(tgt)) + + # check derivation with scaling + for i in range(5): + for j in range(2, 5): + tgt = [0]*i + [1] + res = herm.hermder(herm.hermint(tgt, m=j, scl=2), m=j, scl=.5) + assert_almost_equal(trim(res), trim(tgt)) + + def test_hermder_axis(self): + # check that axis keyword works + c2d = np.random.random((3, 4)) + + tgt = np.vstack([herm.hermder(c) for c in c2d.T]).T + res = herm.hermder(c2d, axis=0) + assert_almost_equal(res, tgt) + + tgt = np.vstack([herm.hermder(c) for c in c2d]) + res = herm.hermder(c2d, axis=1) + assert_almost_equal(res, tgt) + + +class TestVander: + # some random values in [-1, 1) + x = np.random.random((3, 5))*2 - 1 + + def test_hermvander(self): + # check for 1d x + x = np.arange(3) + v = herm.hermvander(x, 3) + assert_(v.shape == (3, 4)) + for i in range(4): + coef = [0]*i + [1] + assert_almost_equal(v[..., i], herm.hermval(x, coef)) + + # check for 2d x + x = np.array([[1, 2], [3, 4], [5, 6]]) + v = herm.hermvander(x, 3) + assert_(v.shape == (3, 2, 4)) + for i in range(4): + coef = [0]*i + [1] + assert_almost_equal(v[..., i], herm.hermval(x, coef)) + + def test_hermvander2d(self): + # also tests hermval2d for non-square coefficient array + x1, x2, x3 = self.x + c = np.random.random((2, 3)) + van = herm.hermvander2d(x1, x2, [1, 2]) + tgt = herm.hermval2d(x1, x2, c) + res = np.dot(van, c.flat) + assert_almost_equal(res, tgt) + + # check shape + van = herm.hermvander2d([x1], [x2], [1, 2]) + assert_(van.shape == (1, 5, 6)) + + def test_hermvander3d(self): + # also tests hermval3d for non-square coefficient array + x1, x2, x3 = self.x + c = np.random.random((2, 3, 4)) + van = herm.hermvander3d(x1, x2, x3, [1, 2, 3]) + tgt = herm.hermval3d(x1, x2, x3, c) + res = np.dot(van, c.flat) + assert_almost_equal(res, tgt) + + # check shape + van = herm.hermvander3d([x1], [x2], [x3], [1, 2, 3]) + assert_(van.shape == (1, 5, 24)) + + +class TestFitting: + + def test_hermfit(self): + def f(x): + return x*(x - 1)*(x - 2) + + def f2(x): + return x**4 + x**2 + 1 + + # Test exceptions + assert_raises(ValueError, herm.hermfit, [1], [1], -1) + assert_raises(TypeError, herm.hermfit, [[1]], [1], 0) + assert_raises(TypeError, herm.hermfit, [], [1], 0) + assert_raises(TypeError, herm.hermfit, [1], [[[1]]], 0) + assert_raises(TypeError, herm.hermfit, [1, 2], [1], 0) + assert_raises(TypeError, herm.hermfit, [1], [1, 2], 0) + assert_raises(TypeError, herm.hermfit, [1], [1], 0, w=[[1]]) + assert_raises(TypeError, herm.hermfit, [1], [1], 0, w=[1, 1]) + assert_raises(ValueError, herm.hermfit, [1], [1], [-1,]) + assert_raises(ValueError, herm.hermfit, [1], [1], [2, -1, 6]) + assert_raises(TypeError, herm.hermfit, [1], [1], []) + + # Test fit + x = np.linspace(0, 2) + y = f(x) + # + coef3 = herm.hermfit(x, y, 3) + assert_equal(len(coef3), 4) + assert_almost_equal(herm.hermval(x, coef3), y) + coef3 = herm.hermfit(x, y, [0, 1, 2, 3]) + assert_equal(len(coef3), 4) + assert_almost_equal(herm.hermval(x, coef3), y) + # + coef4 = herm.hermfit(x, y, 4) + assert_equal(len(coef4), 5) + assert_almost_equal(herm.hermval(x, coef4), y) + coef4 = herm.hermfit(x, y, [0, 1, 2, 3, 4]) + assert_equal(len(coef4), 5) + assert_almost_equal(herm.hermval(x, coef4), y) + # check things still work if deg is not in strict increasing + coef4 = herm.hermfit(x, y, [2, 3, 4, 1, 0]) + assert_equal(len(coef4), 5) + assert_almost_equal(herm.hermval(x, coef4), y) + # + coef2d = herm.hermfit(x, np.array([y, y]).T, 3) + assert_almost_equal(coef2d, np.array([coef3, coef3]).T) + coef2d = herm.hermfit(x, np.array([y, y]).T, [0, 1, 2, 3]) + assert_almost_equal(coef2d, np.array([coef3, coef3]).T) + # test weighting + w = np.zeros_like(x) + yw = y.copy() + w[1::2] = 1 + y[0::2] = 0 + wcoef3 = herm.hermfit(x, yw, 3, w=w) + assert_almost_equal(wcoef3, coef3) + wcoef3 = herm.hermfit(x, yw, [0, 1, 2, 3], w=w) + assert_almost_equal(wcoef3, coef3) + # + wcoef2d = herm.hermfit(x, np.array([yw, yw]).T, 3, w=w) + assert_almost_equal(wcoef2d, np.array([coef3, coef3]).T) + wcoef2d = herm.hermfit(x, np.array([yw, yw]).T, [0, 1, 2, 3], w=w) + assert_almost_equal(wcoef2d, np.array([coef3, coef3]).T) + # test scaling with complex values x points whose square + # is zero when summed. + x = [1, 1j, -1, -1j] + assert_almost_equal(herm.hermfit(x, x, 1), [0, .5]) + assert_almost_equal(herm.hermfit(x, x, [0, 1]), [0, .5]) + # test fitting only even Legendre polynomials + x = np.linspace(-1, 1) + y = f2(x) + coef1 = herm.hermfit(x, y, 4) + assert_almost_equal(herm.hermval(x, coef1), y) + coef2 = herm.hermfit(x, y, [0, 2, 4]) + assert_almost_equal(herm.hermval(x, coef2), y) + assert_almost_equal(coef1, coef2) + + +class TestCompanion: + + def test_raises(self): + assert_raises(ValueError, herm.hermcompanion, []) + assert_raises(ValueError, herm.hermcompanion, [1]) + + def test_dimensions(self): + for i in range(1, 5): + coef = [0]*i + [1] + assert_(herm.hermcompanion(coef).shape == (i, i)) + + def test_linear_root(self): + assert_(herm.hermcompanion([1, 2])[0, 0] == -.25) + + +class TestGauss: + + def test_100(self): + x, w = herm.hermgauss(100) + + # test orthogonality. Note that the results need to be normalized, + # otherwise the huge values that can arise from fast growing + # functions like Laguerre can be very confusing. + v = herm.hermvander(x, 99) + vv = np.dot(v.T * w, v) + vd = 1/np.sqrt(vv.diagonal()) + vv = vd[:, None] * vv * vd + assert_almost_equal(vv, np.eye(100)) + + # check that the integral of 1 is correct + tgt = np.sqrt(np.pi) + assert_almost_equal(w.sum(), tgt) + + +class TestMisc: + + def test_hermfromroots(self): + res = herm.hermfromroots([]) + assert_almost_equal(trim(res), [1]) + for i in range(1, 5): + roots = np.cos(np.linspace(-np.pi, 0, 2*i + 1)[1::2]) + pol = herm.hermfromroots(roots) + res = herm.hermval(roots, pol) + tgt = 0 + assert_(len(pol) == i + 1) + assert_almost_equal(herm.herm2poly(pol)[-1], 1) + assert_almost_equal(res, tgt) + + def test_hermroots(self): + assert_almost_equal(herm.hermroots([1]), []) + assert_almost_equal(herm.hermroots([1, 1]), [-.5]) + for i in range(2, 5): + tgt = np.linspace(-1, 1, i) + res = herm.hermroots(herm.hermfromroots(tgt)) + assert_almost_equal(trim(res), trim(tgt)) + + def test_hermtrim(self): + coef = [2, -1, 1, 0] + + # Test exceptions + assert_raises(ValueError, herm.hermtrim, coef, -1) + + # Test results + assert_equal(herm.hermtrim(coef), coef[:-1]) + assert_equal(herm.hermtrim(coef, 1), coef[:-3]) + assert_equal(herm.hermtrim(coef, 2), [0]) + + def test_hermline(self): + assert_equal(herm.hermline(3, 4), [3, 2]) + + def test_herm2poly(self): + for i in range(10): + assert_almost_equal(herm.herm2poly([0]*i + [1]), Hlist[i]) + + def test_poly2herm(self): + for i in range(10): + assert_almost_equal(herm.poly2herm(Hlist[i]), [0]*i + [1]) + + def test_weight(self): + x = np.linspace(-5, 5, 11) + tgt = np.exp(-x**2) + res = herm.hermweight(x) + assert_almost_equal(res, tgt) diff --git a/venv/Lib/site-packages/numpy/polynomial/tests/test_hermite_e.py b/venv/Lib/site-packages/numpy/polynomial/tests/test_hermite_e.py new file mode 100644 index 0000000..2d262a3 --- /dev/null +++ b/venv/Lib/site-packages/numpy/polynomial/tests/test_hermite_e.py @@ -0,0 +1,556 @@ +"""Tests for hermite_e module. + +""" +from functools import reduce + +import numpy as np +import numpy.polynomial.hermite_e as herme +from numpy.polynomial.polynomial import polyval +from numpy.testing import ( + assert_almost_equal, assert_raises, assert_equal, assert_, + ) + +He0 = np.array([1]) +He1 = np.array([0, 1]) +He2 = np.array([-1, 0, 1]) +He3 = np.array([0, -3, 0, 1]) +He4 = np.array([3, 0, -6, 0, 1]) +He5 = np.array([0, 15, 0, -10, 0, 1]) +He6 = np.array([-15, 0, 45, 0, -15, 0, 1]) +He7 = np.array([0, -105, 0, 105, 0, -21, 0, 1]) +He8 = np.array([105, 0, -420, 0, 210, 0, -28, 0, 1]) +He9 = np.array([0, 945, 0, -1260, 0, 378, 0, -36, 0, 1]) + +Helist = [He0, He1, He2, He3, He4, He5, He6, He7, He8, He9] + + +def trim(x): + return herme.hermetrim(x, tol=1e-6) + + +class TestConstants: + + def test_hermedomain(self): + assert_equal(herme.hermedomain, [-1, 1]) + + def test_hermezero(self): + assert_equal(herme.hermezero, [0]) + + def test_hermeone(self): + assert_equal(herme.hermeone, [1]) + + def test_hermex(self): + assert_equal(herme.hermex, [0, 1]) + + +class TestArithmetic: + x = np.linspace(-3, 3, 100) + + def test_hermeadd(self): + for i in range(5): + for j in range(5): + msg = f"At i={i}, j={j}" + tgt = np.zeros(max(i, j) + 1) + tgt[i] += 1 + tgt[j] += 1 + res = herme.hermeadd([0]*i + [1], [0]*j + [1]) + assert_equal(trim(res), trim(tgt), err_msg=msg) + + def test_hermesub(self): + for i in range(5): + for j in range(5): + msg = f"At i={i}, j={j}" + tgt = np.zeros(max(i, j) + 1) + tgt[i] += 1 + tgt[j] -= 1 + res = herme.hermesub([0]*i + [1], [0]*j + [1]) + assert_equal(trim(res), trim(tgt), err_msg=msg) + + def test_hermemulx(self): + assert_equal(herme.hermemulx([0]), [0]) + assert_equal(herme.hermemulx([1]), [0, 1]) + for i in range(1, 5): + ser = [0]*i + [1] + tgt = [0]*(i - 1) + [i, 0, 1] + assert_equal(herme.hermemulx(ser), tgt) + + def test_hermemul(self): + # check values of result + for i in range(5): + pol1 = [0]*i + [1] + val1 = herme.hermeval(self.x, pol1) + for j in range(5): + msg = f"At i={i}, j={j}" + pol2 = [0]*j + [1] + val2 = herme.hermeval(self.x, pol2) + pol3 = herme.hermemul(pol1, pol2) + val3 = herme.hermeval(self.x, pol3) + assert_(len(pol3) == i + j + 1, msg) + assert_almost_equal(val3, val1*val2, err_msg=msg) + + def test_hermediv(self): + for i in range(5): + for j in range(5): + msg = f"At i={i}, j={j}" + ci = [0]*i + [1] + cj = [0]*j + [1] + tgt = herme.hermeadd(ci, cj) + quo, rem = herme.hermediv(tgt, ci) + res = herme.hermeadd(herme.hermemul(quo, ci), rem) + assert_equal(trim(res), trim(tgt), err_msg=msg) + + def test_hermepow(self): + for i in range(5): + for j in range(5): + msg = f"At i={i}, j={j}" + c = np.arange(i + 1) + tgt = reduce(herme.hermemul, [c]*j, np.array([1])) + res = herme.hermepow(c, j) + assert_equal(trim(res), trim(tgt), err_msg=msg) + + +class TestEvaluation: + # coefficients of 1 + 2*x + 3*x**2 + c1d = np.array([4., 2., 3.]) + c2d = np.einsum('i,j->ij', c1d, c1d) + c3d = np.einsum('i,j,k->ijk', c1d, c1d, c1d) + + # some random values in [-1, 1) + x = np.random.random((3, 5))*2 - 1 + y = polyval(x, [1., 2., 3.]) + + def test_hermeval(self): + #check empty input + assert_equal(herme.hermeval([], [1]).size, 0) + + #check normal input) + x = np.linspace(-1, 1) + y = [polyval(x, c) for c in Helist] + for i in range(10): + msg = f"At i={i}" + tgt = y[i] + res = herme.hermeval(x, [0]*i + [1]) + assert_almost_equal(res, tgt, err_msg=msg) + + #check that shape is preserved + for i in range(3): + dims = [2]*i + x = np.zeros(dims) + assert_equal(herme.hermeval(x, [1]).shape, dims) + assert_equal(herme.hermeval(x, [1, 0]).shape, dims) + assert_equal(herme.hermeval(x, [1, 0, 0]).shape, dims) + + def test_hermeval2d(self): + x1, x2, x3 = self.x + y1, y2, y3 = self.y + + #test exceptions + assert_raises(ValueError, herme.hermeval2d, x1, x2[:2], self.c2d) + + #test values + tgt = y1*y2 + res = herme.hermeval2d(x1, x2, self.c2d) + assert_almost_equal(res, tgt) + + #test shape + z = np.ones((2, 3)) + res = herme.hermeval2d(z, z, self.c2d) + assert_(res.shape == (2, 3)) + + def test_hermeval3d(self): + x1, x2, x3 = self.x + y1, y2, y3 = self.y + + #test exceptions + assert_raises(ValueError, herme.hermeval3d, x1, x2, x3[:2], self.c3d) + + #test values + tgt = y1*y2*y3 + res = herme.hermeval3d(x1, x2, x3, self.c3d) + assert_almost_equal(res, tgt) + + #test shape + z = np.ones((2, 3)) + res = herme.hermeval3d(z, z, z, self.c3d) + assert_(res.shape == (2, 3)) + + def test_hermegrid2d(self): + x1, x2, x3 = self.x + y1, y2, y3 = self.y + + #test values + tgt = np.einsum('i,j->ij', y1, y2) + res = herme.hermegrid2d(x1, x2, self.c2d) + assert_almost_equal(res, tgt) + + #test shape + z = np.ones((2, 3)) + res = herme.hermegrid2d(z, z, self.c2d) + assert_(res.shape == (2, 3)*2) + + def test_hermegrid3d(self): + x1, x2, x3 = self.x + y1, y2, y3 = self.y + + #test values + tgt = np.einsum('i,j,k->ijk', y1, y2, y3) + res = herme.hermegrid3d(x1, x2, x3, self.c3d) + assert_almost_equal(res, tgt) + + #test shape + z = np.ones((2, 3)) + res = herme.hermegrid3d(z, z, z, self.c3d) + assert_(res.shape == (2, 3)*3) + + +class TestIntegral: + + def test_hermeint(self): + # check exceptions + assert_raises(TypeError, herme.hermeint, [0], .5) + assert_raises(ValueError, herme.hermeint, [0], -1) + assert_raises(ValueError, herme.hermeint, [0], 1, [0, 0]) + assert_raises(ValueError, herme.hermeint, [0], lbnd=[0]) + assert_raises(ValueError, herme.hermeint, [0], scl=[0]) + assert_raises(TypeError, herme.hermeint, [0], axis=.5) + + # test integration of zero polynomial + for i in range(2, 5): + k = [0]*(i - 2) + [1] + res = herme.hermeint([0], m=i, k=k) + assert_almost_equal(res, [0, 1]) + + # check single integration with integration constant + for i in range(5): + scl = i + 1 + pol = [0]*i + [1] + tgt = [i] + [0]*i + [1/scl] + hermepol = herme.poly2herme(pol) + hermeint = herme.hermeint(hermepol, m=1, k=[i]) + res = herme.herme2poly(hermeint) + assert_almost_equal(trim(res), trim(tgt)) + + # check single integration with integration constant and lbnd + for i in range(5): + scl = i + 1 + pol = [0]*i + [1] + hermepol = herme.poly2herme(pol) + hermeint = herme.hermeint(hermepol, m=1, k=[i], lbnd=-1) + assert_almost_equal(herme.hermeval(-1, hermeint), i) + + # check single integration with integration constant and scaling + for i in range(5): + scl = i + 1 + pol = [0]*i + [1] + tgt = [i] + [0]*i + [2/scl] + hermepol = herme.poly2herme(pol) + hermeint = herme.hermeint(hermepol, m=1, k=[i], scl=2) + res = herme.herme2poly(hermeint) + assert_almost_equal(trim(res), trim(tgt)) + + # check multiple integrations with default k + for i in range(5): + for j in range(2, 5): + pol = [0]*i + [1] + tgt = pol[:] + for k in range(j): + tgt = herme.hermeint(tgt, m=1) + res = herme.hermeint(pol, m=j) + assert_almost_equal(trim(res), trim(tgt)) + + # check multiple integrations with defined k + for i in range(5): + for j in range(2, 5): + pol = [0]*i + [1] + tgt = pol[:] + for k in range(j): + tgt = herme.hermeint(tgt, m=1, k=[k]) + res = herme.hermeint(pol, m=j, k=list(range(j))) + assert_almost_equal(trim(res), trim(tgt)) + + # check multiple integrations with lbnd + for i in range(5): + for j in range(2, 5): + pol = [0]*i + [1] + tgt = pol[:] + for k in range(j): + tgt = herme.hermeint(tgt, m=1, k=[k], lbnd=-1) + res = herme.hermeint(pol, m=j, k=list(range(j)), lbnd=-1) + assert_almost_equal(trim(res), trim(tgt)) + + # check multiple integrations with scaling + for i in range(5): + for j in range(2, 5): + pol = [0]*i + [1] + tgt = pol[:] + for k in range(j): + tgt = herme.hermeint(tgt, m=1, k=[k], scl=2) + res = herme.hermeint(pol, m=j, k=list(range(j)), scl=2) + assert_almost_equal(trim(res), trim(tgt)) + + def test_hermeint_axis(self): + # check that axis keyword works + c2d = np.random.random((3, 4)) + + tgt = np.vstack([herme.hermeint(c) for c in c2d.T]).T + res = herme.hermeint(c2d, axis=0) + assert_almost_equal(res, tgt) + + tgt = np.vstack([herme.hermeint(c) for c in c2d]) + res = herme.hermeint(c2d, axis=1) + assert_almost_equal(res, tgt) + + tgt = np.vstack([herme.hermeint(c, k=3) for c in c2d]) + res = herme.hermeint(c2d, k=3, axis=1) + assert_almost_equal(res, tgt) + + +class TestDerivative: + + def test_hermeder(self): + # check exceptions + assert_raises(TypeError, herme.hermeder, [0], .5) + assert_raises(ValueError, herme.hermeder, [0], -1) + + # check that zeroth derivative does nothing + for i in range(5): + tgt = [0]*i + [1] + res = herme.hermeder(tgt, m=0) + assert_equal(trim(res), trim(tgt)) + + # check that derivation is the inverse of integration + for i in range(5): + for j in range(2, 5): + tgt = [0]*i + [1] + res = herme.hermeder(herme.hermeint(tgt, m=j), m=j) + assert_almost_equal(trim(res), trim(tgt)) + + # check derivation with scaling + for i in range(5): + for j in range(2, 5): + tgt = [0]*i + [1] + res = herme.hermeder( + herme.hermeint(tgt, m=j, scl=2), m=j, scl=.5) + assert_almost_equal(trim(res), trim(tgt)) + + def test_hermeder_axis(self): + # check that axis keyword works + c2d = np.random.random((3, 4)) + + tgt = np.vstack([herme.hermeder(c) for c in c2d.T]).T + res = herme.hermeder(c2d, axis=0) + assert_almost_equal(res, tgt) + + tgt = np.vstack([herme.hermeder(c) for c in c2d]) + res = herme.hermeder(c2d, axis=1) + assert_almost_equal(res, tgt) + + +class TestVander: + # some random values in [-1, 1) + x = np.random.random((3, 5))*2 - 1 + + def test_hermevander(self): + # check for 1d x + x = np.arange(3) + v = herme.hermevander(x, 3) + assert_(v.shape == (3, 4)) + for i in range(4): + coef = [0]*i + [1] + assert_almost_equal(v[..., i], herme.hermeval(x, coef)) + + # check for 2d x + x = np.array([[1, 2], [3, 4], [5, 6]]) + v = herme.hermevander(x, 3) + assert_(v.shape == (3, 2, 4)) + for i in range(4): + coef = [0]*i + [1] + assert_almost_equal(v[..., i], herme.hermeval(x, coef)) + + def test_hermevander2d(self): + # also tests hermeval2d for non-square coefficient array + x1, x2, x3 = self.x + c = np.random.random((2, 3)) + van = herme.hermevander2d(x1, x2, [1, 2]) + tgt = herme.hermeval2d(x1, x2, c) + res = np.dot(van, c.flat) + assert_almost_equal(res, tgt) + + # check shape + van = herme.hermevander2d([x1], [x2], [1, 2]) + assert_(van.shape == (1, 5, 6)) + + def test_hermevander3d(self): + # also tests hermeval3d for non-square coefficient array + x1, x2, x3 = self.x + c = np.random.random((2, 3, 4)) + van = herme.hermevander3d(x1, x2, x3, [1, 2, 3]) + tgt = herme.hermeval3d(x1, x2, x3, c) + res = np.dot(van, c.flat) + assert_almost_equal(res, tgt) + + # check shape + van = herme.hermevander3d([x1], [x2], [x3], [1, 2, 3]) + assert_(van.shape == (1, 5, 24)) + + +class TestFitting: + + def test_hermefit(self): + def f(x): + return x*(x - 1)*(x - 2) + + def f2(x): + return x**4 + x**2 + 1 + + # Test exceptions + assert_raises(ValueError, herme.hermefit, [1], [1], -1) + assert_raises(TypeError, herme.hermefit, [[1]], [1], 0) + assert_raises(TypeError, herme.hermefit, [], [1], 0) + assert_raises(TypeError, herme.hermefit, [1], [[[1]]], 0) + assert_raises(TypeError, herme.hermefit, [1, 2], [1], 0) + assert_raises(TypeError, herme.hermefit, [1], [1, 2], 0) + assert_raises(TypeError, herme.hermefit, [1], [1], 0, w=[[1]]) + assert_raises(TypeError, herme.hermefit, [1], [1], 0, w=[1, 1]) + assert_raises(ValueError, herme.hermefit, [1], [1], [-1,]) + assert_raises(ValueError, herme.hermefit, [1], [1], [2, -1, 6]) + assert_raises(TypeError, herme.hermefit, [1], [1], []) + + # Test fit + x = np.linspace(0, 2) + y = f(x) + # + coef3 = herme.hermefit(x, y, 3) + assert_equal(len(coef3), 4) + assert_almost_equal(herme.hermeval(x, coef3), y) + coef3 = herme.hermefit(x, y, [0, 1, 2, 3]) + assert_equal(len(coef3), 4) + assert_almost_equal(herme.hermeval(x, coef3), y) + # + coef4 = herme.hermefit(x, y, 4) + assert_equal(len(coef4), 5) + assert_almost_equal(herme.hermeval(x, coef4), y) + coef4 = herme.hermefit(x, y, [0, 1, 2, 3, 4]) + assert_equal(len(coef4), 5) + assert_almost_equal(herme.hermeval(x, coef4), y) + # check things still work if deg is not in strict increasing + coef4 = herme.hermefit(x, y, [2, 3, 4, 1, 0]) + assert_equal(len(coef4), 5) + assert_almost_equal(herme.hermeval(x, coef4), y) + # + coef2d = herme.hermefit(x, np.array([y, y]).T, 3) + assert_almost_equal(coef2d, np.array([coef3, coef3]).T) + coef2d = herme.hermefit(x, np.array([y, y]).T, [0, 1, 2, 3]) + assert_almost_equal(coef2d, np.array([coef3, coef3]).T) + # test weighting + w = np.zeros_like(x) + yw = y.copy() + w[1::2] = 1 + y[0::2] = 0 + wcoef3 = herme.hermefit(x, yw, 3, w=w) + assert_almost_equal(wcoef3, coef3) + wcoef3 = herme.hermefit(x, yw, [0, 1, 2, 3], w=w) + assert_almost_equal(wcoef3, coef3) + # + wcoef2d = herme.hermefit(x, np.array([yw, yw]).T, 3, w=w) + assert_almost_equal(wcoef2d, np.array([coef3, coef3]).T) + wcoef2d = herme.hermefit(x, np.array([yw, yw]).T, [0, 1, 2, 3], w=w) + assert_almost_equal(wcoef2d, np.array([coef3, coef3]).T) + # test scaling with complex values x points whose square + # is zero when summed. + x = [1, 1j, -1, -1j] + assert_almost_equal(herme.hermefit(x, x, 1), [0, 1]) + assert_almost_equal(herme.hermefit(x, x, [0, 1]), [0, 1]) + # test fitting only even Legendre polynomials + x = np.linspace(-1, 1) + y = f2(x) + coef1 = herme.hermefit(x, y, 4) + assert_almost_equal(herme.hermeval(x, coef1), y) + coef2 = herme.hermefit(x, y, [0, 2, 4]) + assert_almost_equal(herme.hermeval(x, coef2), y) + assert_almost_equal(coef1, coef2) + + +class TestCompanion: + + def test_raises(self): + assert_raises(ValueError, herme.hermecompanion, []) + assert_raises(ValueError, herme.hermecompanion, [1]) + + def test_dimensions(self): + for i in range(1, 5): + coef = [0]*i + [1] + assert_(herme.hermecompanion(coef).shape == (i, i)) + + def test_linear_root(self): + assert_(herme.hermecompanion([1, 2])[0, 0] == -.5) + + +class TestGauss: + + def test_100(self): + x, w = herme.hermegauss(100) + + # test orthogonality. Note that the results need to be normalized, + # otherwise the huge values that can arise from fast growing + # functions like Laguerre can be very confusing. + v = herme.hermevander(x, 99) + vv = np.dot(v.T * w, v) + vd = 1/np.sqrt(vv.diagonal()) + vv = vd[:, None] * vv * vd + assert_almost_equal(vv, np.eye(100)) + + # check that the integral of 1 is correct + tgt = np.sqrt(2*np.pi) + assert_almost_equal(w.sum(), tgt) + + +class TestMisc: + + def test_hermefromroots(self): + res = herme.hermefromroots([]) + assert_almost_equal(trim(res), [1]) + for i in range(1, 5): + roots = np.cos(np.linspace(-np.pi, 0, 2*i + 1)[1::2]) + pol = herme.hermefromroots(roots) + res = herme.hermeval(roots, pol) + tgt = 0 + assert_(len(pol) == i + 1) + assert_almost_equal(herme.herme2poly(pol)[-1], 1) + assert_almost_equal(res, tgt) + + def test_hermeroots(self): + assert_almost_equal(herme.hermeroots([1]), []) + assert_almost_equal(herme.hermeroots([1, 1]), [-1]) + for i in range(2, 5): + tgt = np.linspace(-1, 1, i) + res = herme.hermeroots(herme.hermefromroots(tgt)) + assert_almost_equal(trim(res), trim(tgt)) + + def test_hermetrim(self): + coef = [2, -1, 1, 0] + + # Test exceptions + assert_raises(ValueError, herme.hermetrim, coef, -1) + + # Test results + assert_equal(herme.hermetrim(coef), coef[:-1]) + assert_equal(herme.hermetrim(coef, 1), coef[:-3]) + assert_equal(herme.hermetrim(coef, 2), [0]) + + def test_hermeline(self): + assert_equal(herme.hermeline(3, 4), [3, 4]) + + def test_herme2poly(self): + for i in range(10): + assert_almost_equal(herme.herme2poly([0]*i + [1]), Helist[i]) + + def test_poly2herme(self): + for i in range(10): + assert_almost_equal(herme.poly2herme(Helist[i]), [0]*i + [1]) + + def test_weight(self): + x = np.linspace(-5, 5, 11) + tgt = np.exp(-.5*x**2) + res = herme.hermeweight(x) + assert_almost_equal(res, tgt) diff --git a/venv/Lib/site-packages/numpy/polynomial/tests/test_laguerre.py b/venv/Lib/site-packages/numpy/polynomial/tests/test_laguerre.py new file mode 100644 index 0000000..227ef3c --- /dev/null +++ b/venv/Lib/site-packages/numpy/polynomial/tests/test_laguerre.py @@ -0,0 +1,537 @@ +"""Tests for laguerre module. + +""" +from functools import reduce + +import numpy as np +import numpy.polynomial.laguerre as lag +from numpy.polynomial.polynomial import polyval +from numpy.testing import ( + assert_almost_equal, assert_raises, assert_equal, assert_, + ) + +L0 = np.array([1])/1 +L1 = np.array([1, -1])/1 +L2 = np.array([2, -4, 1])/2 +L3 = np.array([6, -18, 9, -1])/6 +L4 = np.array([24, -96, 72, -16, 1])/24 +L5 = np.array([120, -600, 600, -200, 25, -1])/120 +L6 = np.array([720, -4320, 5400, -2400, 450, -36, 1])/720 + +Llist = [L0, L1, L2, L3, L4, L5, L6] + + +def trim(x): + return lag.lagtrim(x, tol=1e-6) + + +class TestConstants: + + def test_lagdomain(self): + assert_equal(lag.lagdomain, [0, 1]) + + def test_lagzero(self): + assert_equal(lag.lagzero, [0]) + + def test_lagone(self): + assert_equal(lag.lagone, [1]) + + def test_lagx(self): + assert_equal(lag.lagx, [1, -1]) + + +class TestArithmetic: + x = np.linspace(-3, 3, 100) + + def test_lagadd(self): + for i in range(5): + for j in range(5): + msg = f"At i={i}, j={j}" + tgt = np.zeros(max(i, j) + 1) + tgt[i] += 1 + tgt[j] += 1 + res = lag.lagadd([0]*i + [1], [0]*j + [1]) + assert_equal(trim(res), trim(tgt), err_msg=msg) + + def test_lagsub(self): + for i in range(5): + for j in range(5): + msg = f"At i={i}, j={j}" + tgt = np.zeros(max(i, j) + 1) + tgt[i] += 1 + tgt[j] -= 1 + res = lag.lagsub([0]*i + [1], [0]*j + [1]) + assert_equal(trim(res), trim(tgt), err_msg=msg) + + def test_lagmulx(self): + assert_equal(lag.lagmulx([0]), [0]) + assert_equal(lag.lagmulx([1]), [1, -1]) + for i in range(1, 5): + ser = [0]*i + [1] + tgt = [0]*(i - 1) + [-i, 2*i + 1, -(i + 1)] + assert_almost_equal(lag.lagmulx(ser), tgt) + + def test_lagmul(self): + # check values of result + for i in range(5): + pol1 = [0]*i + [1] + val1 = lag.lagval(self.x, pol1) + for j in range(5): + msg = f"At i={i}, j={j}" + pol2 = [0]*j + [1] + val2 = lag.lagval(self.x, pol2) + pol3 = lag.lagmul(pol1, pol2) + val3 = lag.lagval(self.x, pol3) + assert_(len(pol3) == i + j + 1, msg) + assert_almost_equal(val3, val1*val2, err_msg=msg) + + def test_lagdiv(self): + for i in range(5): + for j in range(5): + msg = f"At i={i}, j={j}" + ci = [0]*i + [1] + cj = [0]*j + [1] + tgt = lag.lagadd(ci, cj) + quo, rem = lag.lagdiv(tgt, ci) + res = lag.lagadd(lag.lagmul(quo, ci), rem) + assert_almost_equal(trim(res), trim(tgt), err_msg=msg) + + def test_lagpow(self): + for i in range(5): + for j in range(5): + msg = f"At i={i}, j={j}" + c = np.arange(i + 1) + tgt = reduce(lag.lagmul, [c]*j, np.array([1])) + res = lag.lagpow(c, j) + assert_equal(trim(res), trim(tgt), err_msg=msg) + + +class TestEvaluation: + # coefficients of 1 + 2*x + 3*x**2 + c1d = np.array([9., -14., 6.]) + c2d = np.einsum('i,j->ij', c1d, c1d) + c3d = np.einsum('i,j,k->ijk', c1d, c1d, c1d) + + # some random values in [-1, 1) + x = np.random.random((3, 5))*2 - 1 + y = polyval(x, [1., 2., 3.]) + + def test_lagval(self): + #check empty input + assert_equal(lag.lagval([], [1]).size, 0) + + #check normal input) + x = np.linspace(-1, 1) + y = [polyval(x, c) for c in Llist] + for i in range(7): + msg = f"At i={i}" + tgt = y[i] + res = lag.lagval(x, [0]*i + [1]) + assert_almost_equal(res, tgt, err_msg=msg) + + #check that shape is preserved + for i in range(3): + dims = [2]*i + x = np.zeros(dims) + assert_equal(lag.lagval(x, [1]).shape, dims) + assert_equal(lag.lagval(x, [1, 0]).shape, dims) + assert_equal(lag.lagval(x, [1, 0, 0]).shape, dims) + + def test_lagval2d(self): + x1, x2, x3 = self.x + y1, y2, y3 = self.y + + #test exceptions + assert_raises(ValueError, lag.lagval2d, x1, x2[:2], self.c2d) + + #test values + tgt = y1*y2 + res = lag.lagval2d(x1, x2, self.c2d) + assert_almost_equal(res, tgt) + + #test shape + z = np.ones((2, 3)) + res = lag.lagval2d(z, z, self.c2d) + assert_(res.shape == (2, 3)) + + def test_lagval3d(self): + x1, x2, x3 = self.x + y1, y2, y3 = self.y + + #test exceptions + assert_raises(ValueError, lag.lagval3d, x1, x2, x3[:2], self.c3d) + + #test values + tgt = y1*y2*y3 + res = lag.lagval3d(x1, x2, x3, self.c3d) + assert_almost_equal(res, tgt) + + #test shape + z = np.ones((2, 3)) + res = lag.lagval3d(z, z, z, self.c3d) + assert_(res.shape == (2, 3)) + + def test_laggrid2d(self): + x1, x2, x3 = self.x + y1, y2, y3 = self.y + + #test values + tgt = np.einsum('i,j->ij', y1, y2) + res = lag.laggrid2d(x1, x2, self.c2d) + assert_almost_equal(res, tgt) + + #test shape + z = np.ones((2, 3)) + res = lag.laggrid2d(z, z, self.c2d) + assert_(res.shape == (2, 3)*2) + + def test_laggrid3d(self): + x1, x2, x3 = self.x + y1, y2, y3 = self.y + + #test values + tgt = np.einsum('i,j,k->ijk', y1, y2, y3) + res = lag.laggrid3d(x1, x2, x3, self.c3d) + assert_almost_equal(res, tgt) + + #test shape + z = np.ones((2, 3)) + res = lag.laggrid3d(z, z, z, self.c3d) + assert_(res.shape == (2, 3)*3) + + +class TestIntegral: + + def test_lagint(self): + # check exceptions + assert_raises(TypeError, lag.lagint, [0], .5) + assert_raises(ValueError, lag.lagint, [0], -1) + assert_raises(ValueError, lag.lagint, [0], 1, [0, 0]) + assert_raises(ValueError, lag.lagint, [0], lbnd=[0]) + assert_raises(ValueError, lag.lagint, [0], scl=[0]) + assert_raises(TypeError, lag.lagint, [0], axis=.5) + + # test integration of zero polynomial + for i in range(2, 5): + k = [0]*(i - 2) + [1] + res = lag.lagint([0], m=i, k=k) + assert_almost_equal(res, [1, -1]) + + # check single integration with integration constant + for i in range(5): + scl = i + 1 + pol = [0]*i + [1] + tgt = [i] + [0]*i + [1/scl] + lagpol = lag.poly2lag(pol) + lagint = lag.lagint(lagpol, m=1, k=[i]) + res = lag.lag2poly(lagint) + assert_almost_equal(trim(res), trim(tgt)) + + # check single integration with integration constant and lbnd + for i in range(5): + scl = i + 1 + pol = [0]*i + [1] + lagpol = lag.poly2lag(pol) + lagint = lag.lagint(lagpol, m=1, k=[i], lbnd=-1) + assert_almost_equal(lag.lagval(-1, lagint), i) + + # check single integration with integration constant and scaling + for i in range(5): + scl = i + 1 + pol = [0]*i + [1] + tgt = [i] + [0]*i + [2/scl] + lagpol = lag.poly2lag(pol) + lagint = lag.lagint(lagpol, m=1, k=[i], scl=2) + res = lag.lag2poly(lagint) + assert_almost_equal(trim(res), trim(tgt)) + + # check multiple integrations with default k + for i in range(5): + for j in range(2, 5): + pol = [0]*i + [1] + tgt = pol[:] + for k in range(j): + tgt = lag.lagint(tgt, m=1) + res = lag.lagint(pol, m=j) + assert_almost_equal(trim(res), trim(tgt)) + + # check multiple integrations with defined k + for i in range(5): + for j in range(2, 5): + pol = [0]*i + [1] + tgt = pol[:] + for k in range(j): + tgt = lag.lagint(tgt, m=1, k=[k]) + res = lag.lagint(pol, m=j, k=list(range(j))) + assert_almost_equal(trim(res), trim(tgt)) + + # check multiple integrations with lbnd + for i in range(5): + for j in range(2, 5): + pol = [0]*i + [1] + tgt = pol[:] + for k in range(j): + tgt = lag.lagint(tgt, m=1, k=[k], lbnd=-1) + res = lag.lagint(pol, m=j, k=list(range(j)), lbnd=-1) + assert_almost_equal(trim(res), trim(tgt)) + + # check multiple integrations with scaling + for i in range(5): + for j in range(2, 5): + pol = [0]*i + [1] + tgt = pol[:] + for k in range(j): + tgt = lag.lagint(tgt, m=1, k=[k], scl=2) + res = lag.lagint(pol, m=j, k=list(range(j)), scl=2) + assert_almost_equal(trim(res), trim(tgt)) + + def test_lagint_axis(self): + # check that axis keyword works + c2d = np.random.random((3, 4)) + + tgt = np.vstack([lag.lagint(c) for c in c2d.T]).T + res = lag.lagint(c2d, axis=0) + assert_almost_equal(res, tgt) + + tgt = np.vstack([lag.lagint(c) for c in c2d]) + res = lag.lagint(c2d, axis=1) + assert_almost_equal(res, tgt) + + tgt = np.vstack([lag.lagint(c, k=3) for c in c2d]) + res = lag.lagint(c2d, k=3, axis=1) + assert_almost_equal(res, tgt) + + +class TestDerivative: + + def test_lagder(self): + # check exceptions + assert_raises(TypeError, lag.lagder, [0], .5) + assert_raises(ValueError, lag.lagder, [0], -1) + + # check that zeroth derivative does nothing + for i in range(5): + tgt = [0]*i + [1] + res = lag.lagder(tgt, m=0) + assert_equal(trim(res), trim(tgt)) + + # check that derivation is the inverse of integration + for i in range(5): + for j in range(2, 5): + tgt = [0]*i + [1] + res = lag.lagder(lag.lagint(tgt, m=j), m=j) + assert_almost_equal(trim(res), trim(tgt)) + + # check derivation with scaling + for i in range(5): + for j in range(2, 5): + tgt = [0]*i + [1] + res = lag.lagder(lag.lagint(tgt, m=j, scl=2), m=j, scl=.5) + assert_almost_equal(trim(res), trim(tgt)) + + def test_lagder_axis(self): + # check that axis keyword works + c2d = np.random.random((3, 4)) + + tgt = np.vstack([lag.lagder(c) for c in c2d.T]).T + res = lag.lagder(c2d, axis=0) + assert_almost_equal(res, tgt) + + tgt = np.vstack([lag.lagder(c) for c in c2d]) + res = lag.lagder(c2d, axis=1) + assert_almost_equal(res, tgt) + + +class TestVander: + # some random values in [-1, 1) + x = np.random.random((3, 5))*2 - 1 + + def test_lagvander(self): + # check for 1d x + x = np.arange(3) + v = lag.lagvander(x, 3) + assert_(v.shape == (3, 4)) + for i in range(4): + coef = [0]*i + [1] + assert_almost_equal(v[..., i], lag.lagval(x, coef)) + + # check for 2d x + x = np.array([[1, 2], [3, 4], [5, 6]]) + v = lag.lagvander(x, 3) + assert_(v.shape == (3, 2, 4)) + for i in range(4): + coef = [0]*i + [1] + assert_almost_equal(v[..., i], lag.lagval(x, coef)) + + def test_lagvander2d(self): + # also tests lagval2d for non-square coefficient array + x1, x2, x3 = self.x + c = np.random.random((2, 3)) + van = lag.lagvander2d(x1, x2, [1, 2]) + tgt = lag.lagval2d(x1, x2, c) + res = np.dot(van, c.flat) + assert_almost_equal(res, tgt) + + # check shape + van = lag.lagvander2d([x1], [x2], [1, 2]) + assert_(van.shape == (1, 5, 6)) + + def test_lagvander3d(self): + # also tests lagval3d for non-square coefficient array + x1, x2, x3 = self.x + c = np.random.random((2, 3, 4)) + van = lag.lagvander3d(x1, x2, x3, [1, 2, 3]) + tgt = lag.lagval3d(x1, x2, x3, c) + res = np.dot(van, c.flat) + assert_almost_equal(res, tgt) + + # check shape + van = lag.lagvander3d([x1], [x2], [x3], [1, 2, 3]) + assert_(van.shape == (1, 5, 24)) + + +class TestFitting: + + def test_lagfit(self): + def f(x): + return x*(x - 1)*(x - 2) + + # Test exceptions + assert_raises(ValueError, lag.lagfit, [1], [1], -1) + assert_raises(TypeError, lag.lagfit, [[1]], [1], 0) + assert_raises(TypeError, lag.lagfit, [], [1], 0) + assert_raises(TypeError, lag.lagfit, [1], [[[1]]], 0) + assert_raises(TypeError, lag.lagfit, [1, 2], [1], 0) + assert_raises(TypeError, lag.lagfit, [1], [1, 2], 0) + assert_raises(TypeError, lag.lagfit, [1], [1], 0, w=[[1]]) + assert_raises(TypeError, lag.lagfit, [1], [1], 0, w=[1, 1]) + assert_raises(ValueError, lag.lagfit, [1], [1], [-1,]) + assert_raises(ValueError, lag.lagfit, [1], [1], [2, -1, 6]) + assert_raises(TypeError, lag.lagfit, [1], [1], []) + + # Test fit + x = np.linspace(0, 2) + y = f(x) + # + coef3 = lag.lagfit(x, y, 3) + assert_equal(len(coef3), 4) + assert_almost_equal(lag.lagval(x, coef3), y) + coef3 = lag.lagfit(x, y, [0, 1, 2, 3]) + assert_equal(len(coef3), 4) + assert_almost_equal(lag.lagval(x, coef3), y) + # + coef4 = lag.lagfit(x, y, 4) + assert_equal(len(coef4), 5) + assert_almost_equal(lag.lagval(x, coef4), y) + coef4 = lag.lagfit(x, y, [0, 1, 2, 3, 4]) + assert_equal(len(coef4), 5) + assert_almost_equal(lag.lagval(x, coef4), y) + # + coef2d = lag.lagfit(x, np.array([y, y]).T, 3) + assert_almost_equal(coef2d, np.array([coef3, coef3]).T) + coef2d = lag.lagfit(x, np.array([y, y]).T, [0, 1, 2, 3]) + assert_almost_equal(coef2d, np.array([coef3, coef3]).T) + # test weighting + w = np.zeros_like(x) + yw = y.copy() + w[1::2] = 1 + y[0::2] = 0 + wcoef3 = lag.lagfit(x, yw, 3, w=w) + assert_almost_equal(wcoef3, coef3) + wcoef3 = lag.lagfit(x, yw, [0, 1, 2, 3], w=w) + assert_almost_equal(wcoef3, coef3) + # + wcoef2d = lag.lagfit(x, np.array([yw, yw]).T, 3, w=w) + assert_almost_equal(wcoef2d, np.array([coef3, coef3]).T) + wcoef2d = lag.lagfit(x, np.array([yw, yw]).T, [0, 1, 2, 3], w=w) + assert_almost_equal(wcoef2d, np.array([coef3, coef3]).T) + # test scaling with complex values x points whose square + # is zero when summed. + x = [1, 1j, -1, -1j] + assert_almost_equal(lag.lagfit(x, x, 1), [1, -1]) + assert_almost_equal(lag.lagfit(x, x, [0, 1]), [1, -1]) + + +class TestCompanion: + + def test_raises(self): + assert_raises(ValueError, lag.lagcompanion, []) + assert_raises(ValueError, lag.lagcompanion, [1]) + + def test_dimensions(self): + for i in range(1, 5): + coef = [0]*i + [1] + assert_(lag.lagcompanion(coef).shape == (i, i)) + + def test_linear_root(self): + assert_(lag.lagcompanion([1, 2])[0, 0] == 1.5) + + +class TestGauss: + + def test_100(self): + x, w = lag.laggauss(100) + + # test orthogonality. Note that the results need to be normalized, + # otherwise the huge values that can arise from fast growing + # functions like Laguerre can be very confusing. + v = lag.lagvander(x, 99) + vv = np.dot(v.T * w, v) + vd = 1/np.sqrt(vv.diagonal()) + vv = vd[:, None] * vv * vd + assert_almost_equal(vv, np.eye(100)) + + # check that the integral of 1 is correct + tgt = 1.0 + assert_almost_equal(w.sum(), tgt) + + +class TestMisc: + + def test_lagfromroots(self): + res = lag.lagfromroots([]) + assert_almost_equal(trim(res), [1]) + for i in range(1, 5): + roots = np.cos(np.linspace(-np.pi, 0, 2*i + 1)[1::2]) + pol = lag.lagfromroots(roots) + res = lag.lagval(roots, pol) + tgt = 0 + assert_(len(pol) == i + 1) + assert_almost_equal(lag.lag2poly(pol)[-1], 1) + assert_almost_equal(res, tgt) + + def test_lagroots(self): + assert_almost_equal(lag.lagroots([1]), []) + assert_almost_equal(lag.lagroots([0, 1]), [1]) + for i in range(2, 5): + tgt = np.linspace(0, 3, i) + res = lag.lagroots(lag.lagfromroots(tgt)) + assert_almost_equal(trim(res), trim(tgt)) + + def test_lagtrim(self): + coef = [2, -1, 1, 0] + + # Test exceptions + assert_raises(ValueError, lag.lagtrim, coef, -1) + + # Test results + assert_equal(lag.lagtrim(coef), coef[:-1]) + assert_equal(lag.lagtrim(coef, 1), coef[:-3]) + assert_equal(lag.lagtrim(coef, 2), [0]) + + def test_lagline(self): + assert_equal(lag.lagline(3, 4), [7, -4]) + + def test_lag2poly(self): + for i in range(7): + assert_almost_equal(lag.lag2poly([0]*i + [1]), Llist[i]) + + def test_poly2lag(self): + for i in range(7): + assert_almost_equal(lag.poly2lag(Llist[i]), [0]*i + [1]) + + def test_weight(self): + x = np.linspace(0, 10, 11) + tgt = np.exp(-x) + res = lag.lagweight(x) + assert_almost_equal(res, tgt) diff --git a/venv/Lib/site-packages/numpy/polynomial/tests/test_legendre.py b/venv/Lib/site-packages/numpy/polynomial/tests/test_legendre.py new file mode 100644 index 0000000..a2a212c --- /dev/null +++ b/venv/Lib/site-packages/numpy/polynomial/tests/test_legendre.py @@ -0,0 +1,556 @@ +"""Tests for legendre module. + +""" +from functools import reduce + +import numpy as np +import numpy.polynomial.legendre as leg +from numpy.polynomial.polynomial import polyval +from numpy.testing import ( + assert_almost_equal, assert_raises, assert_equal, assert_, + ) + +L0 = np.array([1]) +L1 = np.array([0, 1]) +L2 = np.array([-1, 0, 3])/2 +L3 = np.array([0, -3, 0, 5])/2 +L4 = np.array([3, 0, -30, 0, 35])/8 +L5 = np.array([0, 15, 0, -70, 0, 63])/8 +L6 = np.array([-5, 0, 105, 0, -315, 0, 231])/16 +L7 = np.array([0, -35, 0, 315, 0, -693, 0, 429])/16 +L8 = np.array([35, 0, -1260, 0, 6930, 0, -12012, 0, 6435])/128 +L9 = np.array([0, 315, 0, -4620, 0, 18018, 0, -25740, 0, 12155])/128 + +Llist = [L0, L1, L2, L3, L4, L5, L6, L7, L8, L9] + + +def trim(x): + return leg.legtrim(x, tol=1e-6) + + +class TestConstants: + + def test_legdomain(self): + assert_equal(leg.legdomain, [-1, 1]) + + def test_legzero(self): + assert_equal(leg.legzero, [0]) + + def test_legone(self): + assert_equal(leg.legone, [1]) + + def test_legx(self): + assert_equal(leg.legx, [0, 1]) + + +class TestArithmetic: + x = np.linspace(-1, 1, 100) + + def test_legadd(self): + for i in range(5): + for j in range(5): + msg = f"At i={i}, j={j}" + tgt = np.zeros(max(i, j) + 1) + tgt[i] += 1 + tgt[j] += 1 + res = leg.legadd([0]*i + [1], [0]*j + [1]) + assert_equal(trim(res), trim(tgt), err_msg=msg) + + def test_legsub(self): + for i in range(5): + for j in range(5): + msg = f"At i={i}, j={j}" + tgt = np.zeros(max(i, j) + 1) + tgt[i] += 1 + tgt[j] -= 1 + res = leg.legsub([0]*i + [1], [0]*j + [1]) + assert_equal(trim(res), trim(tgt), err_msg=msg) + + def test_legmulx(self): + assert_equal(leg.legmulx([0]), [0]) + assert_equal(leg.legmulx([1]), [0, 1]) + for i in range(1, 5): + tmp = 2*i + 1 + ser = [0]*i + [1] + tgt = [0]*(i - 1) + [i/tmp, 0, (i + 1)/tmp] + assert_equal(leg.legmulx(ser), tgt) + + def test_legmul(self): + # check values of result + for i in range(5): + pol1 = [0]*i + [1] + val1 = leg.legval(self.x, pol1) + for j in range(5): + msg = f"At i={i}, j={j}" + pol2 = [0]*j + [1] + val2 = leg.legval(self.x, pol2) + pol3 = leg.legmul(pol1, pol2) + val3 = leg.legval(self.x, pol3) + assert_(len(pol3) == i + j + 1, msg) + assert_almost_equal(val3, val1*val2, err_msg=msg) + + def test_legdiv(self): + for i in range(5): + for j in range(5): + msg = f"At i={i}, j={j}" + ci = [0]*i + [1] + cj = [0]*j + [1] + tgt = leg.legadd(ci, cj) + quo, rem = leg.legdiv(tgt, ci) + res = leg.legadd(leg.legmul(quo, ci), rem) + assert_equal(trim(res), trim(tgt), err_msg=msg) + + def test_legpow(self): + for i in range(5): + for j in range(5): + msg = f"At i={i}, j={j}" + c = np.arange(i + 1) + tgt = reduce(leg.legmul, [c]*j, np.array([1])) + res = leg.legpow(c, j) + assert_equal(trim(res), trim(tgt), err_msg=msg) + + +class TestEvaluation: + # coefficients of 1 + 2*x + 3*x**2 + c1d = np.array([2., 2., 2.]) + c2d = np.einsum('i,j->ij', c1d, c1d) + c3d = np.einsum('i,j,k->ijk', c1d, c1d, c1d) + + # some random values in [-1, 1) + x = np.random.random((3, 5))*2 - 1 + y = polyval(x, [1., 2., 3.]) + + def test_legval(self): + #check empty input + assert_equal(leg.legval([], [1]).size, 0) + + #check normal input) + x = np.linspace(-1, 1) + y = [polyval(x, c) for c in Llist] + for i in range(10): + msg = f"At i={i}" + tgt = y[i] + res = leg.legval(x, [0]*i + [1]) + assert_almost_equal(res, tgt, err_msg=msg) + + #check that shape is preserved + for i in range(3): + dims = [2]*i + x = np.zeros(dims) + assert_equal(leg.legval(x, [1]).shape, dims) + assert_equal(leg.legval(x, [1, 0]).shape, dims) + assert_equal(leg.legval(x, [1, 0, 0]).shape, dims) + + def test_legval2d(self): + x1, x2, x3 = self.x + y1, y2, y3 = self.y + + #test exceptions + assert_raises(ValueError, leg.legval2d, x1, x2[:2], self.c2d) + + #test values + tgt = y1*y2 + res = leg.legval2d(x1, x2, self.c2d) + assert_almost_equal(res, tgt) + + #test shape + z = np.ones((2, 3)) + res = leg.legval2d(z, z, self.c2d) + assert_(res.shape == (2, 3)) + + def test_legval3d(self): + x1, x2, x3 = self.x + y1, y2, y3 = self.y + + #test exceptions + assert_raises(ValueError, leg.legval3d, x1, x2, x3[:2], self.c3d) + + #test values + tgt = y1*y2*y3 + res = leg.legval3d(x1, x2, x3, self.c3d) + assert_almost_equal(res, tgt) + + #test shape + z = np.ones((2, 3)) + res = leg.legval3d(z, z, z, self.c3d) + assert_(res.shape == (2, 3)) + + def test_leggrid2d(self): + x1, x2, x3 = self.x + y1, y2, y3 = self.y + + #test values + tgt = np.einsum('i,j->ij', y1, y2) + res = leg.leggrid2d(x1, x2, self.c2d) + assert_almost_equal(res, tgt) + + #test shape + z = np.ones((2, 3)) + res = leg.leggrid2d(z, z, self.c2d) + assert_(res.shape == (2, 3)*2) + + def test_leggrid3d(self): + x1, x2, x3 = self.x + y1, y2, y3 = self.y + + #test values + tgt = np.einsum('i,j,k->ijk', y1, y2, y3) + res = leg.leggrid3d(x1, x2, x3, self.c3d) + assert_almost_equal(res, tgt) + + #test shape + z = np.ones((2, 3)) + res = leg.leggrid3d(z, z, z, self.c3d) + assert_(res.shape == (2, 3)*3) + + +class TestIntegral: + + def test_legint(self): + # check exceptions + assert_raises(TypeError, leg.legint, [0], .5) + assert_raises(ValueError, leg.legint, [0], -1) + assert_raises(ValueError, leg.legint, [0], 1, [0, 0]) + assert_raises(ValueError, leg.legint, [0], lbnd=[0]) + assert_raises(ValueError, leg.legint, [0], scl=[0]) + assert_raises(TypeError, leg.legint, [0], axis=.5) + + # test integration of zero polynomial + for i in range(2, 5): + k = [0]*(i - 2) + [1] + res = leg.legint([0], m=i, k=k) + assert_almost_equal(res, [0, 1]) + + # check single integration with integration constant + for i in range(5): + scl = i + 1 + pol = [0]*i + [1] + tgt = [i] + [0]*i + [1/scl] + legpol = leg.poly2leg(pol) + legint = leg.legint(legpol, m=1, k=[i]) + res = leg.leg2poly(legint) + assert_almost_equal(trim(res), trim(tgt)) + + # check single integration with integration constant and lbnd + for i in range(5): + scl = i + 1 + pol = [0]*i + [1] + legpol = leg.poly2leg(pol) + legint = leg.legint(legpol, m=1, k=[i], lbnd=-1) + assert_almost_equal(leg.legval(-1, legint), i) + + # check single integration with integration constant and scaling + for i in range(5): + scl = i + 1 + pol = [0]*i + [1] + tgt = [i] + [0]*i + [2/scl] + legpol = leg.poly2leg(pol) + legint = leg.legint(legpol, m=1, k=[i], scl=2) + res = leg.leg2poly(legint) + assert_almost_equal(trim(res), trim(tgt)) + + # check multiple integrations with default k + for i in range(5): + for j in range(2, 5): + pol = [0]*i + [1] + tgt = pol[:] + for k in range(j): + tgt = leg.legint(tgt, m=1) + res = leg.legint(pol, m=j) + assert_almost_equal(trim(res), trim(tgt)) + + # check multiple integrations with defined k + for i in range(5): + for j in range(2, 5): + pol = [0]*i + [1] + tgt = pol[:] + for k in range(j): + tgt = leg.legint(tgt, m=1, k=[k]) + res = leg.legint(pol, m=j, k=list(range(j))) + assert_almost_equal(trim(res), trim(tgt)) + + # check multiple integrations with lbnd + for i in range(5): + for j in range(2, 5): + pol = [0]*i + [1] + tgt = pol[:] + for k in range(j): + tgt = leg.legint(tgt, m=1, k=[k], lbnd=-1) + res = leg.legint(pol, m=j, k=list(range(j)), lbnd=-1) + assert_almost_equal(trim(res), trim(tgt)) + + # check multiple integrations with scaling + for i in range(5): + for j in range(2, 5): + pol = [0]*i + [1] + tgt = pol[:] + for k in range(j): + tgt = leg.legint(tgt, m=1, k=[k], scl=2) + res = leg.legint(pol, m=j, k=list(range(j)), scl=2) + assert_almost_equal(trim(res), trim(tgt)) + + def test_legint_axis(self): + # check that axis keyword works + c2d = np.random.random((3, 4)) + + tgt = np.vstack([leg.legint(c) for c in c2d.T]).T + res = leg.legint(c2d, axis=0) + assert_almost_equal(res, tgt) + + tgt = np.vstack([leg.legint(c) for c in c2d]) + res = leg.legint(c2d, axis=1) + assert_almost_equal(res, tgt) + + tgt = np.vstack([leg.legint(c, k=3) for c in c2d]) + res = leg.legint(c2d, k=3, axis=1) + assert_almost_equal(res, tgt) + + +class TestDerivative: + + def test_legder(self): + # check exceptions + assert_raises(TypeError, leg.legder, [0], .5) + assert_raises(ValueError, leg.legder, [0], -1) + + # check that zeroth derivative does nothing + for i in range(5): + tgt = [0]*i + [1] + res = leg.legder(tgt, m=0) + assert_equal(trim(res), trim(tgt)) + + # check that derivation is the inverse of integration + for i in range(5): + for j in range(2, 5): + tgt = [0]*i + [1] + res = leg.legder(leg.legint(tgt, m=j), m=j) + assert_almost_equal(trim(res), trim(tgt)) + + # check derivation with scaling + for i in range(5): + for j in range(2, 5): + tgt = [0]*i + [1] + res = leg.legder(leg.legint(tgt, m=j, scl=2), m=j, scl=.5) + assert_almost_equal(trim(res), trim(tgt)) + + def test_legder_axis(self): + # check that axis keyword works + c2d = np.random.random((3, 4)) + + tgt = np.vstack([leg.legder(c) for c in c2d.T]).T + res = leg.legder(c2d, axis=0) + assert_almost_equal(res, tgt) + + tgt = np.vstack([leg.legder(c) for c in c2d]) + res = leg.legder(c2d, axis=1) + assert_almost_equal(res, tgt) + + +class TestVander: + # some random values in [-1, 1) + x = np.random.random((3, 5))*2 - 1 + + def test_legvander(self): + # check for 1d x + x = np.arange(3) + v = leg.legvander(x, 3) + assert_(v.shape == (3, 4)) + for i in range(4): + coef = [0]*i + [1] + assert_almost_equal(v[..., i], leg.legval(x, coef)) + + # check for 2d x + x = np.array([[1, 2], [3, 4], [5, 6]]) + v = leg.legvander(x, 3) + assert_(v.shape == (3, 2, 4)) + for i in range(4): + coef = [0]*i + [1] + assert_almost_equal(v[..., i], leg.legval(x, coef)) + + def test_legvander2d(self): + # also tests polyval2d for non-square coefficient array + x1, x2, x3 = self.x + c = np.random.random((2, 3)) + van = leg.legvander2d(x1, x2, [1, 2]) + tgt = leg.legval2d(x1, x2, c) + res = np.dot(van, c.flat) + assert_almost_equal(res, tgt) + + # check shape + van = leg.legvander2d([x1], [x2], [1, 2]) + assert_(van.shape == (1, 5, 6)) + + def test_legvander3d(self): + # also tests polyval3d for non-square coefficient array + x1, x2, x3 = self.x + c = np.random.random((2, 3, 4)) + van = leg.legvander3d(x1, x2, x3, [1, 2, 3]) + tgt = leg.legval3d(x1, x2, x3, c) + res = np.dot(van, c.flat) + assert_almost_equal(res, tgt) + + # check shape + van = leg.legvander3d([x1], [x2], [x3], [1, 2, 3]) + assert_(van.shape == (1, 5, 24)) + + +class TestFitting: + + def test_legfit(self): + def f(x): + return x*(x - 1)*(x - 2) + + def f2(x): + return x**4 + x**2 + 1 + + # Test exceptions + assert_raises(ValueError, leg.legfit, [1], [1], -1) + assert_raises(TypeError, leg.legfit, [[1]], [1], 0) + assert_raises(TypeError, leg.legfit, [], [1], 0) + assert_raises(TypeError, leg.legfit, [1], [[[1]]], 0) + assert_raises(TypeError, leg.legfit, [1, 2], [1], 0) + assert_raises(TypeError, leg.legfit, [1], [1, 2], 0) + assert_raises(TypeError, leg.legfit, [1], [1], 0, w=[[1]]) + assert_raises(TypeError, leg.legfit, [1], [1], 0, w=[1, 1]) + assert_raises(ValueError, leg.legfit, [1], [1], [-1,]) + assert_raises(ValueError, leg.legfit, [1], [1], [2, -1, 6]) + assert_raises(TypeError, leg.legfit, [1], [1], []) + + # Test fit + x = np.linspace(0, 2) + y = f(x) + # + coef3 = leg.legfit(x, y, 3) + assert_equal(len(coef3), 4) + assert_almost_equal(leg.legval(x, coef3), y) + coef3 = leg.legfit(x, y, [0, 1, 2, 3]) + assert_equal(len(coef3), 4) + assert_almost_equal(leg.legval(x, coef3), y) + # + coef4 = leg.legfit(x, y, 4) + assert_equal(len(coef4), 5) + assert_almost_equal(leg.legval(x, coef4), y) + coef4 = leg.legfit(x, y, [0, 1, 2, 3, 4]) + assert_equal(len(coef4), 5) + assert_almost_equal(leg.legval(x, coef4), y) + # check things still work if deg is not in strict increasing + coef4 = leg.legfit(x, y, [2, 3, 4, 1, 0]) + assert_equal(len(coef4), 5) + assert_almost_equal(leg.legval(x, coef4), y) + # + coef2d = leg.legfit(x, np.array([y, y]).T, 3) + assert_almost_equal(coef2d, np.array([coef3, coef3]).T) + coef2d = leg.legfit(x, np.array([y, y]).T, [0, 1, 2, 3]) + assert_almost_equal(coef2d, np.array([coef3, coef3]).T) + # test weighting + w = np.zeros_like(x) + yw = y.copy() + w[1::2] = 1 + y[0::2] = 0 + wcoef3 = leg.legfit(x, yw, 3, w=w) + assert_almost_equal(wcoef3, coef3) + wcoef3 = leg.legfit(x, yw, [0, 1, 2, 3], w=w) + assert_almost_equal(wcoef3, coef3) + # + wcoef2d = leg.legfit(x, np.array([yw, yw]).T, 3, w=w) + assert_almost_equal(wcoef2d, np.array([coef3, coef3]).T) + wcoef2d = leg.legfit(x, np.array([yw, yw]).T, [0, 1, 2, 3], w=w) + assert_almost_equal(wcoef2d, np.array([coef3, coef3]).T) + # test scaling with complex values x points whose square + # is zero when summed. + x = [1, 1j, -1, -1j] + assert_almost_equal(leg.legfit(x, x, 1), [0, 1]) + assert_almost_equal(leg.legfit(x, x, [0, 1]), [0, 1]) + # test fitting only even Legendre polynomials + x = np.linspace(-1, 1) + y = f2(x) + coef1 = leg.legfit(x, y, 4) + assert_almost_equal(leg.legval(x, coef1), y) + coef2 = leg.legfit(x, y, [0, 2, 4]) + assert_almost_equal(leg.legval(x, coef2), y) + assert_almost_equal(coef1, coef2) + + +class TestCompanion: + + def test_raises(self): + assert_raises(ValueError, leg.legcompanion, []) + assert_raises(ValueError, leg.legcompanion, [1]) + + def test_dimensions(self): + for i in range(1, 5): + coef = [0]*i + [1] + assert_(leg.legcompanion(coef).shape == (i, i)) + + def test_linear_root(self): + assert_(leg.legcompanion([1, 2])[0, 0] == -.5) + + +class TestGauss: + + def test_100(self): + x, w = leg.leggauss(100) + + # test orthogonality. Note that the results need to be normalized, + # otherwise the huge values that can arise from fast growing + # functions like Laguerre can be very confusing. + v = leg.legvander(x, 99) + vv = np.dot(v.T * w, v) + vd = 1/np.sqrt(vv.diagonal()) + vv = vd[:, None] * vv * vd + assert_almost_equal(vv, np.eye(100)) + + # check that the integral of 1 is correct + tgt = 2.0 + assert_almost_equal(w.sum(), tgt) + + +class TestMisc: + + def test_legfromroots(self): + res = leg.legfromroots([]) + assert_almost_equal(trim(res), [1]) + for i in range(1, 5): + roots = np.cos(np.linspace(-np.pi, 0, 2*i + 1)[1::2]) + pol = leg.legfromroots(roots) + res = leg.legval(roots, pol) + tgt = 0 + assert_(len(pol) == i + 1) + assert_almost_equal(leg.leg2poly(pol)[-1], 1) + assert_almost_equal(res, tgt) + + def test_legroots(self): + assert_almost_equal(leg.legroots([1]), []) + assert_almost_equal(leg.legroots([1, 2]), [-.5]) + for i in range(2, 5): + tgt = np.linspace(-1, 1, i) + res = leg.legroots(leg.legfromroots(tgt)) + assert_almost_equal(trim(res), trim(tgt)) + + def test_legtrim(self): + coef = [2, -1, 1, 0] + + # Test exceptions + assert_raises(ValueError, leg.legtrim, coef, -1) + + # Test results + assert_equal(leg.legtrim(coef), coef[:-1]) + assert_equal(leg.legtrim(coef, 1), coef[:-3]) + assert_equal(leg.legtrim(coef, 2), [0]) + + def test_legline(self): + assert_equal(leg.legline(3, 4), [3, 4]) + + def test_leg2poly(self): + for i in range(10): + assert_almost_equal(leg.leg2poly([0]*i + [1]), Llist[i]) + + def test_poly2leg(self): + for i in range(10): + assert_almost_equal(leg.poly2leg(Llist[i]), [0]*i + [1]) + + def test_weight(self): + x = np.linspace(-1, 1, 11) + tgt = 1. + res = leg.legweight(x) + assert_almost_equal(res, tgt) diff --git a/venv/Lib/site-packages/numpy/polynomial/tests/test_polynomial.py b/venv/Lib/site-packages/numpy/polynomial/tests/test_polynomial.py new file mode 100644 index 0000000..5fd1a82 --- /dev/null +++ b/venv/Lib/site-packages/numpy/polynomial/tests/test_polynomial.py @@ -0,0 +1,593 @@ +"""Tests for polynomial module. + +""" +from functools import reduce + +import numpy as np +import numpy.polynomial.polynomial as poly +from numpy.testing import ( + assert_almost_equal, assert_raises, assert_equal, assert_, + assert_warns, assert_array_equal, assert_raises_regex) + + +def trim(x): + return poly.polytrim(x, tol=1e-6) + +T0 = [1] +T1 = [0, 1] +T2 = [-1, 0, 2] +T3 = [0, -3, 0, 4] +T4 = [1, 0, -8, 0, 8] +T5 = [0, 5, 0, -20, 0, 16] +T6 = [-1, 0, 18, 0, -48, 0, 32] +T7 = [0, -7, 0, 56, 0, -112, 0, 64] +T8 = [1, 0, -32, 0, 160, 0, -256, 0, 128] +T9 = [0, 9, 0, -120, 0, 432, 0, -576, 0, 256] + +Tlist = [T0, T1, T2, T3, T4, T5, T6, T7, T8, T9] + + +class TestConstants: + + def test_polydomain(self): + assert_equal(poly.polydomain, [-1, 1]) + + def test_polyzero(self): + assert_equal(poly.polyzero, [0]) + + def test_polyone(self): + assert_equal(poly.polyone, [1]) + + def test_polyx(self): + assert_equal(poly.polyx, [0, 1]) + + +class TestArithmetic: + + def test_polyadd(self): + for i in range(5): + for j in range(5): + msg = f"At i={i}, j={j}" + tgt = np.zeros(max(i, j) + 1) + tgt[i] += 1 + tgt[j] += 1 + res = poly.polyadd([0]*i + [1], [0]*j + [1]) + assert_equal(trim(res), trim(tgt), err_msg=msg) + + def test_polysub(self): + for i in range(5): + for j in range(5): + msg = f"At i={i}, j={j}" + tgt = np.zeros(max(i, j) + 1) + tgt[i] += 1 + tgt[j] -= 1 + res = poly.polysub([0]*i + [1], [0]*j + [1]) + assert_equal(trim(res), trim(tgt), err_msg=msg) + + def test_polymulx(self): + assert_equal(poly.polymulx([0]), [0]) + assert_equal(poly.polymulx([1]), [0, 1]) + for i in range(1, 5): + ser = [0]*i + [1] + tgt = [0]*(i + 1) + [1] + assert_equal(poly.polymulx(ser), tgt) + + def test_polymul(self): + for i in range(5): + for j in range(5): + msg = f"At i={i}, j={j}" + tgt = np.zeros(i + j + 1) + tgt[i + j] += 1 + res = poly.polymul([0]*i + [1], [0]*j + [1]) + assert_equal(trim(res), trim(tgt), err_msg=msg) + + def test_polydiv(self): + # check zero division + assert_raises(ZeroDivisionError, poly.polydiv, [1], [0]) + + # check scalar division + quo, rem = poly.polydiv([2], [2]) + assert_equal((quo, rem), (1, 0)) + quo, rem = poly.polydiv([2, 2], [2]) + assert_equal((quo, rem), ((1, 1), 0)) + + # check rest. + for i in range(5): + for j in range(5): + msg = f"At i={i}, j={j}" + ci = [0]*i + [1, 2] + cj = [0]*j + [1, 2] + tgt = poly.polyadd(ci, cj) + quo, rem = poly.polydiv(tgt, ci) + res = poly.polyadd(poly.polymul(quo, ci), rem) + assert_equal(res, tgt, err_msg=msg) + + def test_polypow(self): + for i in range(5): + for j in range(5): + msg = f"At i={i}, j={j}" + c = np.arange(i + 1) + tgt = reduce(poly.polymul, [c]*j, np.array([1])) + res = poly.polypow(c, j) + assert_equal(trim(res), trim(tgt), err_msg=msg) + + +class TestEvaluation: + # coefficients of 1 + 2*x + 3*x**2 + c1d = np.array([1., 2., 3.]) + c2d = np.einsum('i,j->ij', c1d, c1d) + c3d = np.einsum('i,j,k->ijk', c1d, c1d, c1d) + + # some random values in [-1, 1) + x = np.random.random((3, 5))*2 - 1 + y = poly.polyval(x, [1., 2., 3.]) + + def test_polyval(self): + #check empty input + assert_equal(poly.polyval([], [1]).size, 0) + + #check normal input) + x = np.linspace(-1, 1) + y = [x**i for i in range(5)] + for i in range(5): + tgt = y[i] + res = poly.polyval(x, [0]*i + [1]) + assert_almost_equal(res, tgt) + tgt = x*(x**2 - 1) + res = poly.polyval(x, [0, -1, 0, 1]) + assert_almost_equal(res, tgt) + + #check that shape is preserved + for i in range(3): + dims = [2]*i + x = np.zeros(dims) + assert_equal(poly.polyval(x, [1]).shape, dims) + assert_equal(poly.polyval(x, [1, 0]).shape, dims) + assert_equal(poly.polyval(x, [1, 0, 0]).shape, dims) + + #check masked arrays are processed correctly + mask = [False, True, False] + mx = np.ma.array([1, 2, 3], mask=mask) + res = np.polyval([7, 5, 3], mx) + assert_array_equal(res.mask, mask) + + #check subtypes of ndarray are preserved + class C(np.ndarray): + pass + + cx = np.array([1, 2, 3]).view(C) + assert_equal(type(np.polyval([2, 3, 4], cx)), C) + + def test_polyvalfromroots(self): + # check exception for broadcasting x values over root array with + # too few dimensions + assert_raises(ValueError, poly.polyvalfromroots, + [1], [1], tensor=False) + + # check empty input + assert_equal(poly.polyvalfromroots([], [1]).size, 0) + assert_(poly.polyvalfromroots([], [1]).shape == (0,)) + + # check empty input + multidimensional roots + assert_equal(poly.polyvalfromroots([], [[1] * 5]).size, 0) + assert_(poly.polyvalfromroots([], [[1] * 5]).shape == (5, 0)) + + # check scalar input + assert_equal(poly.polyvalfromroots(1, 1), 0) + assert_(poly.polyvalfromroots(1, np.ones((3, 3))).shape == (3,)) + + # check normal input) + x = np.linspace(-1, 1) + y = [x**i for i in range(5)] + for i in range(1, 5): + tgt = y[i] + res = poly.polyvalfromroots(x, [0]*i) + assert_almost_equal(res, tgt) + tgt = x*(x - 1)*(x + 1) + res = poly.polyvalfromroots(x, [-1, 0, 1]) + assert_almost_equal(res, tgt) + + # check that shape is preserved + for i in range(3): + dims = [2]*i + x = np.zeros(dims) + assert_equal(poly.polyvalfromroots(x, [1]).shape, dims) + assert_equal(poly.polyvalfromroots(x, [1, 0]).shape, dims) + assert_equal(poly.polyvalfromroots(x, [1, 0, 0]).shape, dims) + + # check compatibility with factorization + ptest = [15, 2, -16, -2, 1] + r = poly.polyroots(ptest) + x = np.linspace(-1, 1) + assert_almost_equal(poly.polyval(x, ptest), + poly.polyvalfromroots(x, r)) + + # check multidimensional arrays of roots and values + # check tensor=False + rshape = (3, 5) + x = np.arange(-3, 2) + r = np.random.randint(-5, 5, size=rshape) + res = poly.polyvalfromroots(x, r, tensor=False) + tgt = np.empty(r.shape[1:]) + for ii in range(tgt.size): + tgt[ii] = poly.polyvalfromroots(x[ii], r[:, ii]) + assert_equal(res, tgt) + + # check tensor=True + x = np.vstack([x, 2*x]) + res = poly.polyvalfromroots(x, r, tensor=True) + tgt = np.empty(r.shape[1:] + x.shape) + for ii in range(r.shape[1]): + for jj in range(x.shape[0]): + tgt[ii, jj, :] = poly.polyvalfromroots(x[jj], r[:, ii]) + assert_equal(res, tgt) + + def test_polyval2d(self): + x1, x2, x3 = self.x + y1, y2, y3 = self.y + + #test exceptions + assert_raises_regex(ValueError, 'incompatible', + poly.polyval2d, x1, x2[:2], self.c2d) + + #test values + tgt = y1*y2 + res = poly.polyval2d(x1, x2, self.c2d) + assert_almost_equal(res, tgt) + + #test shape + z = np.ones((2, 3)) + res = poly.polyval2d(z, z, self.c2d) + assert_(res.shape == (2, 3)) + + def test_polyval3d(self): + x1, x2, x3 = self.x + y1, y2, y3 = self.y + + #test exceptions + assert_raises_regex(ValueError, 'incompatible', + poly.polyval3d, x1, x2, x3[:2], self.c3d) + + #test values + tgt = y1*y2*y3 + res = poly.polyval3d(x1, x2, x3, self.c3d) + assert_almost_equal(res, tgt) + + #test shape + z = np.ones((2, 3)) + res = poly.polyval3d(z, z, z, self.c3d) + assert_(res.shape == (2, 3)) + + def test_polygrid2d(self): + x1, x2, x3 = self.x + y1, y2, y3 = self.y + + #test values + tgt = np.einsum('i,j->ij', y1, y2) + res = poly.polygrid2d(x1, x2, self.c2d) + assert_almost_equal(res, tgt) + + #test shape + z = np.ones((2, 3)) + res = poly.polygrid2d(z, z, self.c2d) + assert_(res.shape == (2, 3)*2) + + def test_polygrid3d(self): + x1, x2, x3 = self.x + y1, y2, y3 = self.y + + #test values + tgt = np.einsum('i,j,k->ijk', y1, y2, y3) + res = poly.polygrid3d(x1, x2, x3, self.c3d) + assert_almost_equal(res, tgt) + + #test shape + z = np.ones((2, 3)) + res = poly.polygrid3d(z, z, z, self.c3d) + assert_(res.shape == (2, 3)*3) + + +class TestIntegral: + + def test_polyint(self): + # check exceptions + assert_raises(TypeError, poly.polyint, [0], .5) + assert_raises(ValueError, poly.polyint, [0], -1) + assert_raises(ValueError, poly.polyint, [0], 1, [0, 0]) + assert_raises(ValueError, poly.polyint, [0], lbnd=[0]) + assert_raises(ValueError, poly.polyint, [0], scl=[0]) + assert_raises(TypeError, poly.polyint, [0], axis=.5) + with assert_warns(DeprecationWarning): + poly.polyint([1, 1], 1.) + + # test integration of zero polynomial + for i in range(2, 5): + k = [0]*(i - 2) + [1] + res = poly.polyint([0], m=i, k=k) + assert_almost_equal(res, [0, 1]) + + # check single integration with integration constant + for i in range(5): + scl = i + 1 + pol = [0]*i + [1] + tgt = [i] + [0]*i + [1/scl] + res = poly.polyint(pol, m=1, k=[i]) + assert_almost_equal(trim(res), trim(tgt)) + + # check single integration with integration constant and lbnd + for i in range(5): + scl = i + 1 + pol = [0]*i + [1] + res = poly.polyint(pol, m=1, k=[i], lbnd=-1) + assert_almost_equal(poly.polyval(-1, res), i) + + # check single integration with integration constant and scaling + for i in range(5): + scl = i + 1 + pol = [0]*i + [1] + tgt = [i] + [0]*i + [2/scl] + res = poly.polyint(pol, m=1, k=[i], scl=2) + assert_almost_equal(trim(res), trim(tgt)) + + # check multiple integrations with default k + for i in range(5): + for j in range(2, 5): + pol = [0]*i + [1] + tgt = pol[:] + for k in range(j): + tgt = poly.polyint(tgt, m=1) + res = poly.polyint(pol, m=j) + assert_almost_equal(trim(res), trim(tgt)) + + # check multiple integrations with defined k + for i in range(5): + for j in range(2, 5): + pol = [0]*i + [1] + tgt = pol[:] + for k in range(j): + tgt = poly.polyint(tgt, m=1, k=[k]) + res = poly.polyint(pol, m=j, k=list(range(j))) + assert_almost_equal(trim(res), trim(tgt)) + + # check multiple integrations with lbnd + for i in range(5): + for j in range(2, 5): + pol = [0]*i + [1] + tgt = pol[:] + for k in range(j): + tgt = poly.polyint(tgt, m=1, k=[k], lbnd=-1) + res = poly.polyint(pol, m=j, k=list(range(j)), lbnd=-1) + assert_almost_equal(trim(res), trim(tgt)) + + # check multiple integrations with scaling + for i in range(5): + for j in range(2, 5): + pol = [0]*i + [1] + tgt = pol[:] + for k in range(j): + tgt = poly.polyint(tgt, m=1, k=[k], scl=2) + res = poly.polyint(pol, m=j, k=list(range(j)), scl=2) + assert_almost_equal(trim(res), trim(tgt)) + + def test_polyint_axis(self): + # check that axis keyword works + c2d = np.random.random((3, 4)) + + tgt = np.vstack([poly.polyint(c) for c in c2d.T]).T + res = poly.polyint(c2d, axis=0) + assert_almost_equal(res, tgt) + + tgt = np.vstack([poly.polyint(c) for c in c2d]) + res = poly.polyint(c2d, axis=1) + assert_almost_equal(res, tgt) + + tgt = np.vstack([poly.polyint(c, k=3) for c in c2d]) + res = poly.polyint(c2d, k=3, axis=1) + assert_almost_equal(res, tgt) + + +class TestDerivative: + + def test_polyder(self): + # check exceptions + assert_raises(TypeError, poly.polyder, [0], .5) + assert_raises(ValueError, poly.polyder, [0], -1) + + # check that zeroth derivative does nothing + for i in range(5): + tgt = [0]*i + [1] + res = poly.polyder(tgt, m=0) + assert_equal(trim(res), trim(tgt)) + + # check that derivation is the inverse of integration + for i in range(5): + for j in range(2, 5): + tgt = [0]*i + [1] + res = poly.polyder(poly.polyint(tgt, m=j), m=j) + assert_almost_equal(trim(res), trim(tgt)) + + # check derivation with scaling + for i in range(5): + for j in range(2, 5): + tgt = [0]*i + [1] + res = poly.polyder(poly.polyint(tgt, m=j, scl=2), m=j, scl=.5) + assert_almost_equal(trim(res), trim(tgt)) + + def test_polyder_axis(self): + # check that axis keyword works + c2d = np.random.random((3, 4)) + + tgt = np.vstack([poly.polyder(c) for c in c2d.T]).T + res = poly.polyder(c2d, axis=0) + assert_almost_equal(res, tgt) + + tgt = np.vstack([poly.polyder(c) for c in c2d]) + res = poly.polyder(c2d, axis=1) + assert_almost_equal(res, tgt) + + +class TestVander: + # some random values in [-1, 1) + x = np.random.random((3, 5))*2 - 1 + + def test_polyvander(self): + # check for 1d x + x = np.arange(3) + v = poly.polyvander(x, 3) + assert_(v.shape == (3, 4)) + for i in range(4): + coef = [0]*i + [1] + assert_almost_equal(v[..., i], poly.polyval(x, coef)) + + # check for 2d x + x = np.array([[1, 2], [3, 4], [5, 6]]) + v = poly.polyvander(x, 3) + assert_(v.shape == (3, 2, 4)) + for i in range(4): + coef = [0]*i + [1] + assert_almost_equal(v[..., i], poly.polyval(x, coef)) + + def test_polyvander2d(self): + # also tests polyval2d for non-square coefficient array + x1, x2, x3 = self.x + c = np.random.random((2, 3)) + van = poly.polyvander2d(x1, x2, [1, 2]) + tgt = poly.polyval2d(x1, x2, c) + res = np.dot(van, c.flat) + assert_almost_equal(res, tgt) + + # check shape + van = poly.polyvander2d([x1], [x2], [1, 2]) + assert_(van.shape == (1, 5, 6)) + + def test_polyvander3d(self): + # also tests polyval3d for non-square coefficient array + x1, x2, x3 = self.x + c = np.random.random((2, 3, 4)) + van = poly.polyvander3d(x1, x2, x3, [1, 2, 3]) + tgt = poly.polyval3d(x1, x2, x3, c) + res = np.dot(van, c.flat) + assert_almost_equal(res, tgt) + + # check shape + van = poly.polyvander3d([x1], [x2], [x3], [1, 2, 3]) + assert_(van.shape == (1, 5, 24)) + + +class TestCompanion: + + def test_raises(self): + assert_raises(ValueError, poly.polycompanion, []) + assert_raises(ValueError, poly.polycompanion, [1]) + + def test_dimensions(self): + for i in range(1, 5): + coef = [0]*i + [1] + assert_(poly.polycompanion(coef).shape == (i, i)) + + def test_linear_root(self): + assert_(poly.polycompanion([1, 2])[0, 0] == -.5) + + +class TestMisc: + + def test_polyfromroots(self): + res = poly.polyfromroots([]) + assert_almost_equal(trim(res), [1]) + for i in range(1, 5): + roots = np.cos(np.linspace(-np.pi, 0, 2*i + 1)[1::2]) + tgt = Tlist[i] + res = poly.polyfromroots(roots)*2**(i-1) + assert_almost_equal(trim(res), trim(tgt)) + + def test_polyroots(self): + assert_almost_equal(poly.polyroots([1]), []) + assert_almost_equal(poly.polyroots([1, 2]), [-.5]) + for i in range(2, 5): + tgt = np.linspace(-1, 1, i) + res = poly.polyroots(poly.polyfromroots(tgt)) + assert_almost_equal(trim(res), trim(tgt)) + + def test_polyfit(self): + def f(x): + return x*(x - 1)*(x - 2) + + def f2(x): + return x**4 + x**2 + 1 + + # Test exceptions + assert_raises(ValueError, poly.polyfit, [1], [1], -1) + assert_raises(TypeError, poly.polyfit, [[1]], [1], 0) + assert_raises(TypeError, poly.polyfit, [], [1], 0) + assert_raises(TypeError, poly.polyfit, [1], [[[1]]], 0) + assert_raises(TypeError, poly.polyfit, [1, 2], [1], 0) + assert_raises(TypeError, poly.polyfit, [1], [1, 2], 0) + assert_raises(TypeError, poly.polyfit, [1], [1], 0, w=[[1]]) + assert_raises(TypeError, poly.polyfit, [1], [1], 0, w=[1, 1]) + assert_raises(ValueError, poly.polyfit, [1], [1], [-1,]) + assert_raises(ValueError, poly.polyfit, [1], [1], [2, -1, 6]) + assert_raises(TypeError, poly.polyfit, [1], [1], []) + + # Test fit + x = np.linspace(0, 2) + y = f(x) + # + coef3 = poly.polyfit(x, y, 3) + assert_equal(len(coef3), 4) + assert_almost_equal(poly.polyval(x, coef3), y) + coef3 = poly.polyfit(x, y, [0, 1, 2, 3]) + assert_equal(len(coef3), 4) + assert_almost_equal(poly.polyval(x, coef3), y) + # + coef4 = poly.polyfit(x, y, 4) + assert_equal(len(coef4), 5) + assert_almost_equal(poly.polyval(x, coef4), y) + coef4 = poly.polyfit(x, y, [0, 1, 2, 3, 4]) + assert_equal(len(coef4), 5) + assert_almost_equal(poly.polyval(x, coef4), y) + # + coef2d = poly.polyfit(x, np.array([y, y]).T, 3) + assert_almost_equal(coef2d, np.array([coef3, coef3]).T) + coef2d = poly.polyfit(x, np.array([y, y]).T, [0, 1, 2, 3]) + assert_almost_equal(coef2d, np.array([coef3, coef3]).T) + # test weighting + w = np.zeros_like(x) + yw = y.copy() + w[1::2] = 1 + yw[0::2] = 0 + wcoef3 = poly.polyfit(x, yw, 3, w=w) + assert_almost_equal(wcoef3, coef3) + wcoef3 = poly.polyfit(x, yw, [0, 1, 2, 3], w=w) + assert_almost_equal(wcoef3, coef3) + # + wcoef2d = poly.polyfit(x, np.array([yw, yw]).T, 3, w=w) + assert_almost_equal(wcoef2d, np.array([coef3, coef3]).T) + wcoef2d = poly.polyfit(x, np.array([yw, yw]).T, [0, 1, 2, 3], w=w) + assert_almost_equal(wcoef2d, np.array([coef3, coef3]).T) + # test scaling with complex values x points whose square + # is zero when summed. + x = [1, 1j, -1, -1j] + assert_almost_equal(poly.polyfit(x, x, 1), [0, 1]) + assert_almost_equal(poly.polyfit(x, x, [0, 1]), [0, 1]) + # test fitting only even Polyendre polynomials + x = np.linspace(-1, 1) + y = f2(x) + coef1 = poly.polyfit(x, y, 4) + assert_almost_equal(poly.polyval(x, coef1), y) + coef2 = poly.polyfit(x, y, [0, 2, 4]) + assert_almost_equal(poly.polyval(x, coef2), y) + assert_almost_equal(coef1, coef2) + + def test_polytrim(self): + coef = [2, -1, 1, 0] + + # Test exceptions + assert_raises(ValueError, poly.polytrim, coef, -1) + + # Test results + assert_equal(poly.polytrim(coef), coef[:-1]) + assert_equal(poly.polytrim(coef, 1), coef[:-3]) + assert_equal(poly.polytrim(coef, 2), [0]) + + def test_polyline(self): + assert_equal(poly.polyline(3, 4), [3, 4]) diff --git a/venv/Lib/site-packages/numpy/polynomial/tests/test_polyutils.py b/venv/Lib/site-packages/numpy/polynomial/tests/test_polyutils.py new file mode 100644 index 0000000..1b27f53 --- /dev/null +++ b/venv/Lib/site-packages/numpy/polynomial/tests/test_polyutils.py @@ -0,0 +1,106 @@ +"""Tests for polyutils module. + +""" +import numpy as np +import numpy.polynomial.polyutils as pu +from numpy.testing import ( + assert_almost_equal, assert_raises, assert_equal, assert_, + ) + + +class TestMisc: + + def test_trimseq(self): + for i in range(5): + tgt = [1] + res = pu.trimseq([1] + [0]*5) + assert_equal(res, tgt) + + def test_as_series(self): + # check exceptions + assert_raises(ValueError, pu.as_series, [[]]) + assert_raises(ValueError, pu.as_series, [[[1, 2]]]) + assert_raises(ValueError, pu.as_series, [[1], ['a']]) + # check common types + types = ['i', 'd', 'O'] + for i in range(len(types)): + for j in range(i): + ci = np.ones(1, types[i]) + cj = np.ones(1, types[j]) + [resi, resj] = pu.as_series([ci, cj]) + assert_(resi.dtype.char == resj.dtype.char) + assert_(resj.dtype.char == types[i]) + + def test_trimcoef(self): + coef = [2, -1, 1, 0] + # Test exceptions + assert_raises(ValueError, pu.trimcoef, coef, -1) + # Test results + assert_equal(pu.trimcoef(coef), coef[:-1]) + assert_equal(pu.trimcoef(coef, 1), coef[:-3]) + assert_equal(pu.trimcoef(coef, 2), [0]) + + +class TestDomain: + + def test_getdomain(self): + # test for real values + x = [1, 10, 3, -1] + tgt = [-1, 10] + res = pu.getdomain(x) + assert_almost_equal(res, tgt) + + # test for complex values + x = [1 + 1j, 1 - 1j, 0, 2] + tgt = [-1j, 2 + 1j] + res = pu.getdomain(x) + assert_almost_equal(res, tgt) + + def test_mapdomain(self): + # test for real values + dom1 = [0, 4] + dom2 = [1, 3] + tgt = dom2 + res = pu.mapdomain(dom1, dom1, dom2) + assert_almost_equal(res, tgt) + + # test for complex values + dom1 = [0 - 1j, 2 + 1j] + dom2 = [-2, 2] + tgt = dom2 + x = dom1 + res = pu.mapdomain(x, dom1, dom2) + assert_almost_equal(res, tgt) + + # test for multidimensional arrays + dom1 = [0, 4] + dom2 = [1, 3] + tgt = np.array([dom2, dom2]) + x = np.array([dom1, dom1]) + res = pu.mapdomain(x, dom1, dom2) + assert_almost_equal(res, tgt) + + # test that subtypes are preserved. + class MyNDArray(np.ndarray): + pass + + dom1 = [0, 4] + dom2 = [1, 3] + x = np.array([dom1, dom1]).view(MyNDArray) + res = pu.mapdomain(x, dom1, dom2) + assert_(isinstance(res, MyNDArray)) + + def test_mapparms(self): + # test for real values + dom1 = [0, 4] + dom2 = [1, 3] + tgt = [1, .5] + res = pu. mapparms(dom1, dom2) + assert_almost_equal(res, tgt) + + # test for complex values + dom1 = [0 - 1j, 2 + 1j] + dom2 = [-2, 2] + tgt = [-1 + 1j, 1 - 1j] + res = pu.mapparms(dom1, dom2) + assert_almost_equal(res, tgt) diff --git a/venv/Lib/site-packages/numpy/polynomial/tests/test_printing.py b/venv/Lib/site-packages/numpy/polynomial/tests/test_printing.py new file mode 100644 index 0000000..4e9902a --- /dev/null +++ b/venv/Lib/site-packages/numpy/polynomial/tests/test_printing.py @@ -0,0 +1,390 @@ +import pytest +from numpy.core import array, arange, printoptions +import numpy.polynomial as poly +from numpy.testing import assert_equal, assert_ + +# For testing polynomial printing with object arrays +from fractions import Fraction +from decimal import Decimal + + +class TestStrUnicodeSuperSubscripts: + + @pytest.fixture(scope='class', autouse=True) + def use_unicode(self): + poly.set_default_printstyle('unicode') + + @pytest.mark.parametrize(('inp', 'tgt'), ( + ([1, 2, 3], "1.0 + 2.0·x¹ + 3.0·x²"), + ([-1, 0, 3, -1], "-1.0 + 0.0·x¹ + 3.0·x² - 1.0·x³"), + (arange(12), ("0.0 + 1.0·x¹ + 2.0·x² + 3.0·x³ + 4.0·xâ´ + 5.0·xâµ + " + "6.0·xâ¶ + 7.0·xâ· +\n8.0·x⸠+ 9.0·xâ¹ + 10.0·x¹Ⱐ+ " + "11.0·x¹¹")), + )) + def test_polynomial_str(self, inp, tgt): + res = str(poly.Polynomial(inp)) + assert_equal(res, tgt) + + @pytest.mark.parametrize(('inp', 'tgt'), ( + ([1, 2, 3], "1.0 + 2.0·Tâ‚(x) + 3.0·Tâ‚‚(x)"), + ([-1, 0, 3, -1], "-1.0 + 0.0·Tâ‚(x) + 3.0·Tâ‚‚(x) - 1.0·T₃(x)"), + (arange(12), ("0.0 + 1.0·Tâ‚(x) + 2.0·Tâ‚‚(x) + 3.0·T₃(x) + 4.0·Tâ‚„(x) + " + "5.0·Tâ‚…(x) +\n6.0·T₆(x) + 7.0·T₇(x) + 8.0·T₈(x) + " + "9.0·T₉(x) + 10.0·Tâ‚â‚€(x) + 11.0·Tâ‚â‚(x)")), + )) + def test_chebyshev_str(self, inp, tgt): + res = str(poly.Chebyshev(inp)) + assert_equal(res, tgt) + + @pytest.mark.parametrize(('inp', 'tgt'), ( + ([1, 2, 3], "1.0 + 2.0·Pâ‚(x) + 3.0·Pâ‚‚(x)"), + ([-1, 0, 3, -1], "-1.0 + 0.0·Pâ‚(x) + 3.0·Pâ‚‚(x) - 1.0·P₃(x)"), + (arange(12), ("0.0 + 1.0·Pâ‚(x) + 2.0·Pâ‚‚(x) + 3.0·P₃(x) + 4.0·Pâ‚„(x) + " + "5.0·Pâ‚…(x) +\n6.0·P₆(x) + 7.0·P₇(x) + 8.0·P₈(x) + " + "9.0·P₉(x) + 10.0·Pâ‚â‚€(x) + 11.0·Pâ‚â‚(x)")), + )) + def test_legendre_str(self, inp, tgt): + res = str(poly.Legendre(inp)) + assert_equal(res, tgt) + + @pytest.mark.parametrize(('inp', 'tgt'), ( + ([1, 2, 3], "1.0 + 2.0·Hâ‚(x) + 3.0·Hâ‚‚(x)"), + ([-1, 0, 3, -1], "-1.0 + 0.0·Hâ‚(x) + 3.0·Hâ‚‚(x) - 1.0·H₃(x)"), + (arange(12), ("0.0 + 1.0·Hâ‚(x) + 2.0·Hâ‚‚(x) + 3.0·H₃(x) + 4.0·Hâ‚„(x) + " + "5.0·Hâ‚…(x) +\n6.0·H₆(x) + 7.0·H₇(x) + 8.0·H₈(x) + " + "9.0·H₉(x) + 10.0·Hâ‚â‚€(x) + 11.0·Hâ‚â‚(x)")), + )) + def test_hermite_str(self, inp, tgt): + res = str(poly.Hermite(inp)) + assert_equal(res, tgt) + + @pytest.mark.parametrize(('inp', 'tgt'), ( + ([1, 2, 3], "1.0 + 2.0·Heâ‚(x) + 3.0·Heâ‚‚(x)"), + ([-1, 0, 3, -1], "-1.0 + 0.0·Heâ‚(x) + 3.0·Heâ‚‚(x) - 1.0·He₃(x)"), + (arange(12), ("0.0 + 1.0·Heâ‚(x) + 2.0·Heâ‚‚(x) + 3.0·He₃(x) + " + "4.0·Heâ‚„(x) + 5.0·Heâ‚…(x) +\n6.0·He₆(x) + 7.0·He₇(x) + " + "8.0·He₈(x) + 9.0·He₉(x) + 10.0·Heâ‚â‚€(x) +\n" + "11.0·Heâ‚â‚(x)")), + )) + def test_hermiteE_str(self, inp, tgt): + res = str(poly.HermiteE(inp)) + assert_equal(res, tgt) + + @pytest.mark.parametrize(('inp', 'tgt'), ( + ([1, 2, 3], "1.0 + 2.0·Lâ‚(x) + 3.0·Lâ‚‚(x)"), + ([-1, 0, 3, -1], "-1.0 + 0.0·Lâ‚(x) + 3.0·Lâ‚‚(x) - 1.0·L₃(x)"), + (arange(12), ("0.0 + 1.0·Lâ‚(x) + 2.0·Lâ‚‚(x) + 3.0·L₃(x) + 4.0·Lâ‚„(x) + " + "5.0·Lâ‚…(x) +\n6.0·L₆(x) + 7.0·L₇(x) + 8.0·L₈(x) + " + "9.0·L₉(x) + 10.0·Lâ‚â‚€(x) + 11.0·Lâ‚â‚(x)")), + )) + def test_laguerre_str(self, inp, tgt): + res = str(poly.Laguerre(inp)) + assert_equal(res, tgt) + + +class TestStrAscii: + + @pytest.fixture(scope='class', autouse=True) + def use_ascii(self): + poly.set_default_printstyle('ascii') + + @pytest.mark.parametrize(('inp', 'tgt'), ( + ([1, 2, 3], "1.0 + 2.0 x**1 + 3.0 x**2"), + ([-1, 0, 3, -1], "-1.0 + 0.0 x**1 + 3.0 x**2 - 1.0 x**3"), + (arange(12), ("0.0 + 1.0 x**1 + 2.0 x**2 + 3.0 x**3 + 4.0 x**4 + " + "5.0 x**5 + 6.0 x**6 +\n7.0 x**7 + 8.0 x**8 + " + "9.0 x**9 + 10.0 x**10 + 11.0 x**11")), + )) + def test_polynomial_str(self, inp, tgt): + res = str(poly.Polynomial(inp)) + assert_equal(res, tgt) + + @pytest.mark.parametrize(('inp', 'tgt'), ( + ([1, 2, 3], "1.0 + 2.0 T_1(x) + 3.0 T_2(x)"), + ([-1, 0, 3, -1], "-1.0 + 0.0 T_1(x) + 3.0 T_2(x) - 1.0 T_3(x)"), + (arange(12), ("0.0 + 1.0 T_1(x) + 2.0 T_2(x) + 3.0 T_3(x) + " + "4.0 T_4(x) + 5.0 T_5(x) +\n6.0 T_6(x) + 7.0 T_7(x) + " + "8.0 T_8(x) + 9.0 T_9(x) + 10.0 T_10(x) +\n" + "11.0 T_11(x)")), + )) + def test_chebyshev_str(self, inp, tgt): + res = str(poly.Chebyshev(inp)) + assert_equal(res, tgt) + + @pytest.mark.parametrize(('inp', 'tgt'), ( + ([1, 2, 3], "1.0 + 2.0 P_1(x) + 3.0 P_2(x)"), + ([-1, 0, 3, -1], "-1.0 + 0.0 P_1(x) + 3.0 P_2(x) - 1.0 P_3(x)"), + (arange(12), ("0.0 + 1.0 P_1(x) + 2.0 P_2(x) + 3.0 P_3(x) + " + "4.0 P_4(x) + 5.0 P_5(x) +\n6.0 P_6(x) + 7.0 P_7(x) + " + "8.0 P_8(x) + 9.0 P_9(x) + 10.0 P_10(x) +\n" + "11.0 P_11(x)")), + )) + def test_legendre_str(self, inp, tgt): + res = str(poly.Legendre(inp)) + assert_equal(res, tgt) + + @pytest.mark.parametrize(('inp', 'tgt'), ( + ([1, 2, 3], "1.0 + 2.0 H_1(x) + 3.0 H_2(x)"), + ([-1, 0, 3, -1], "-1.0 + 0.0 H_1(x) + 3.0 H_2(x) - 1.0 H_3(x)"), + (arange(12), ("0.0 + 1.0 H_1(x) + 2.0 H_2(x) + 3.0 H_3(x) + " + "4.0 H_4(x) + 5.0 H_5(x) +\n6.0 H_6(x) + 7.0 H_7(x) + " + "8.0 H_8(x) + 9.0 H_9(x) + 10.0 H_10(x) +\n" + "11.0 H_11(x)")), + )) + def test_hermite_str(self, inp, tgt): + res = str(poly.Hermite(inp)) + assert_equal(res, tgt) + + @pytest.mark.parametrize(('inp', 'tgt'), ( + ([1, 2, 3], "1.0 + 2.0 He_1(x) + 3.0 He_2(x)"), + ([-1, 0, 3, -1], "-1.0 + 0.0 He_1(x) + 3.0 He_2(x) - 1.0 He_3(x)"), + (arange(12), ("0.0 + 1.0 He_1(x) + 2.0 He_2(x) + 3.0 He_3(x) + " + "4.0 He_4(x) +\n5.0 He_5(x) + 6.0 He_6(x) + " + "7.0 He_7(x) + 8.0 He_8(x) + 9.0 He_9(x) +\n" + "10.0 He_10(x) + 11.0 He_11(x)")), + )) + def test_hermiteE_str(self, inp, tgt): + res = str(poly.HermiteE(inp)) + assert_equal(res, tgt) + + @pytest.mark.parametrize(('inp', 'tgt'), ( + ([1, 2, 3], "1.0 + 2.0 L_1(x) + 3.0 L_2(x)"), + ([-1, 0, 3, -1], "-1.0 + 0.0 L_1(x) + 3.0 L_2(x) - 1.0 L_3(x)"), + (arange(12), ("0.0 + 1.0 L_1(x) + 2.0 L_2(x) + 3.0 L_3(x) + " + "4.0 L_4(x) + 5.0 L_5(x) +\n6.0 L_6(x) + 7.0 L_7(x) + " + "8.0 L_8(x) + 9.0 L_9(x) + 10.0 L_10(x) +\n" + "11.0 L_11(x)")), + )) + def test_laguerre_str(self, inp, tgt): + res = str(poly.Laguerre(inp)) + assert_equal(res, tgt) + + +class TestLinebreaking: + + @pytest.fixture(scope='class', autouse=True) + def use_ascii(self): + poly.set_default_printstyle('ascii') + + def test_single_line_one_less(self): + # With 'ascii' style, len(str(p)) is default linewidth - 1 (i.e. 74) + p = poly.Polynomial([123456789, 123456789, 123456789, 1234, 1]) + assert_equal(len(str(p)), 74) + assert_equal(str(p), ( + '123456789.0 + 123456789.0 x**1 + 123456789.0 x**2 + ' + '1234.0 x**3 + 1.0 x**4' + )) + + def test_num_chars_is_linewidth(self): + # len(str(p)) == default linewidth == 75 + p = poly.Polynomial([123456789, 123456789, 123456789, 1234, 10]) + assert_equal(len(str(p)), 75) + assert_equal(str(p), ( + '123456789.0 + 123456789.0 x**1 + 123456789.0 x**2 + ' + '1234.0 x**3 +\n10.0 x**4' + )) + + def test_first_linebreak_multiline_one_less_than_linewidth(self): + # Multiline str where len(first_line) + len(next_term) == lw - 1 == 74 + p = poly.Polynomial( + [123456789, 123456789, 123456789, 12, 1, 123456789] + ) + assert_equal(len(str(p).split('\n')[0]), 74) + assert_equal(str(p), ( + '123456789.0 + 123456789.0 x**1 + 123456789.0 x**2 + ' + '12.0 x**3 + 1.0 x**4 +\n123456789.0 x**5' + )) + + def test_first_linebreak_multiline_on_linewidth(self): + # First line is one character longer than previous test + p = poly.Polynomial( + [123456789, 123456789, 123456789, 123, 1, 123456789] + ) + assert_equal(str(p), ( + '123456789.0 + 123456789.0 x**1 + 123456789.0 x**2 + ' + '123.0 x**3 +\n1.0 x**4 + 123456789.0 x**5' + )) + + @pytest.mark.parametrize(('lw', 'tgt'), ( + (75, ('0.0 + 10.0 x**1 + 200.0 x**2 + 3000.0 x**3 + 40000.0 x**4 +\n' + '500000.0 x**5 + 600000.0 x**6 + 70000.0 x**7 + 8000.0 x**8 + ' + '900.0 x**9')), + (45, ('0.0 + 10.0 x**1 + 200.0 x**2 + 3000.0 x**3 +\n40000.0 x**4 + ' + '500000.0 x**5 +\n600000.0 x**6 + 70000.0 x**7 + 8000.0 x**8 +\n' + '900.0 x**9')), + (132, ('0.0 + 10.0 x**1 + 200.0 x**2 + 3000.0 x**3 + 40000.0 x**4 + ' + '500000.0 x**5 + 600000.0 x**6 + 70000.0 x**7 + 8000.0 x**8 + ' + '900.0 x**9')), + )) + def test_linewidth_printoption(self, lw, tgt): + p = poly.Polynomial( + [0, 10, 200, 3000, 40000, 500000, 600000, 70000, 8000, 900] + ) + with printoptions(linewidth=lw): + assert_equal(str(p), tgt) + for line in str(p).split('\n'): + assert_(len(line) < lw) + + +def test_set_default_printoptions(): + p = poly.Polynomial([1, 2, 3]) + c = poly.Chebyshev([1, 2, 3]) + poly.set_default_printstyle('ascii') + assert_equal(str(p), "1.0 + 2.0 x**1 + 3.0 x**2") + assert_equal(str(c), "1.0 + 2.0 T_1(x) + 3.0 T_2(x)") + poly.set_default_printstyle('unicode') + assert_equal(str(p), "1.0 + 2.0·x¹ + 3.0·x²") + assert_equal(str(c), "1.0 + 2.0·Tâ‚(x) + 3.0·Tâ‚‚(x)") + with pytest.raises(ValueError): + poly.set_default_printstyle('invalid_input') + + +def test_complex_coefficients(): + """Test both numpy and built-in complex.""" + coefs = [0+1j, 1+1j, -2+2j, 3+0j] + # numpy complex + p1 = poly.Polynomial(coefs) + # Python complex + p2 = poly.Polynomial(array(coefs, dtype=object)) + poly.set_default_printstyle('unicode') + assert_equal(str(p1), "1j + (1+1j)·x¹ - (2-2j)·x² + (3+0j)·x³") + assert_equal(str(p2), "1j + (1+1j)·x¹ + (-2+2j)·x² + (3+0j)·x³") + poly.set_default_printstyle('ascii') + assert_equal(str(p1), "1j + (1+1j) x**1 - (2-2j) x**2 + (3+0j) x**3") + assert_equal(str(p2), "1j + (1+1j) x**1 + (-2+2j) x**2 + (3+0j) x**3") + + +@pytest.mark.parametrize(('coefs', 'tgt'), ( + (array([Fraction(1, 2), Fraction(3, 4)], dtype=object), ( + "1/2 + 3/4·x¹" + )), + (array([1, 2, Fraction(5, 7)], dtype=object), ( + "1 + 2·x¹ + 5/7·x²" + )), + (array([Decimal('1.00'), Decimal('2.2'), 3], dtype=object), ( + "1.00 + 2.2·x¹ + 3·x²" + )), +)) +def test_numeric_object_coefficients(coefs, tgt): + p = poly.Polynomial(coefs) + poly.set_default_printstyle('unicode') + assert_equal(str(p), tgt) + + +@pytest.mark.parametrize(('coefs', 'tgt'), ( + (array([1, 2, 'f'], dtype=object), '1 + 2·x¹ + f·x²'), + (array([1, 2, [3, 4]], dtype=object), '1 + 2·x¹ + [3, 4]·x²'), +)) +def test_nonnumeric_object_coefficients(coefs, tgt): + """ + Test coef fallback for object arrays of non-numeric coefficients. + """ + p = poly.Polynomial(coefs) + poly.set_default_printstyle('unicode') + assert_equal(str(p), tgt) + + +class TestFormat: + def test_format_unicode(self): + poly.set_default_printstyle('ascii') + p = poly.Polynomial([1, 2, 0, -1]) + assert_equal(format(p, 'unicode'), "1.0 + 2.0·x¹ + 0.0·x² - 1.0·x³") + + def test_format_ascii(self): + poly.set_default_printstyle('unicode') + p = poly.Polynomial([1, 2, 0, -1]) + assert_equal( + format(p, 'ascii'), "1.0 + 2.0 x**1 + 0.0 x**2 - 1.0 x**3" + ) + + def test_empty_formatstr(self): + poly.set_default_printstyle('ascii') + p = poly.Polynomial([1, 2, 3]) + assert_equal(format(p), "1.0 + 2.0 x**1 + 3.0 x**2") + assert_equal(f"{p}", "1.0 + 2.0 x**1 + 3.0 x**2") + + def test_bad_formatstr(self): + p = poly.Polynomial([1, 2, 0, -1]) + with pytest.raises(ValueError): + format(p, '.2f') + + +class TestRepr: + def test_polynomial_str(self): + res = repr(poly.Polynomial([0, 1])) + tgt = 'Polynomial([0., 1.], domain=[-1, 1], window=[-1, 1])' + assert_equal(res, tgt) + + def test_chebyshev_str(self): + res = repr(poly.Chebyshev([0, 1])) + tgt = 'Chebyshev([0., 1.], domain=[-1, 1], window=[-1, 1])' + assert_equal(res, tgt) + + def test_legendre_repr(self): + res = repr(poly.Legendre([0, 1])) + tgt = 'Legendre([0., 1.], domain=[-1, 1], window=[-1, 1])' + assert_equal(res, tgt) + + def test_hermite_repr(self): + res = repr(poly.Hermite([0, 1])) + tgt = 'Hermite([0., 1.], domain=[-1, 1], window=[-1, 1])' + assert_equal(res, tgt) + + def test_hermiteE_repr(self): + res = repr(poly.HermiteE([0, 1])) + tgt = 'HermiteE([0., 1.], domain=[-1, 1], window=[-1, 1])' + assert_equal(res, tgt) + + def test_laguerre_repr(self): + res = repr(poly.Laguerre([0, 1])) + tgt = 'Laguerre([0., 1.], domain=[0, 1], window=[0, 1])' + assert_equal(res, tgt) + + +class TestLatexRepr: + """Test the latex repr used by Jupyter""" + + def as_latex(self, obj): + # right now we ignore the formatting of scalars in our tests, since + # it makes them too verbose. Ideally, the formatting of scalars will + # be fixed such that tests below continue to pass + obj._repr_latex_scalar = lambda x: str(x) + try: + return obj._repr_latex_() + finally: + del obj._repr_latex_scalar + + def test_simple_polynomial(self): + # default input + p = poly.Polynomial([1, 2, 3]) + assert_equal(self.as_latex(p), + r'$x \mapsto 1.0 + 2.0\,x + 3.0\,x^{2}$') + + # translated input + p = poly.Polynomial([1, 2, 3], domain=[-2, 0]) + assert_equal(self.as_latex(p), + r'$x \mapsto 1.0 + 2.0\,\left(1.0 + x\right) + 3.0\,\left(1.0 + x\right)^{2}$') + + # scaled input + p = poly.Polynomial([1, 2, 3], domain=[-0.5, 0.5]) + assert_equal(self.as_latex(p), + r'$x \mapsto 1.0 + 2.0\,\left(2.0x\right) + 3.0\,\left(2.0x\right)^{2}$') + + # affine input + p = poly.Polynomial([1, 2, 3], domain=[-1, 0]) + assert_equal(self.as_latex(p), + r'$x \mapsto 1.0 + 2.0\,\left(1.0 + 2.0x\right) + 3.0\,\left(1.0 + 2.0x\right)^{2}$') + + def test_basis_func(self): + p = poly.Chebyshev([1, 2, 3]) + assert_equal(self.as_latex(p), + r'$x \mapsto 1.0\,{T}_{0}(x) + 2.0\,{T}_{1}(x) + 3.0\,{T}_{2}(x)$') + # affine input - check no surplus parens are added + p = poly.Chebyshev([1, 2, 3], domain=[-1, 0]) + assert_equal(self.as_latex(p), + r'$x \mapsto 1.0\,{T}_{0}(1.0 + 2.0x) + 2.0\,{T}_{1}(1.0 + 2.0x) + 3.0\,{T}_{2}(1.0 + 2.0x)$') + + def test_multichar_basis_func(self): + p = poly.HermiteE([1, 2, 3]) + assert_equal(self.as_latex(p), + r'$x \mapsto 1.0\,{He}_{0}(x) + 2.0\,{He}_{1}(x) + 3.0\,{He}_{2}(x)$') diff --git a/venv/Lib/site-packages/numpy/py.typed b/venv/Lib/site-packages/numpy/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/venv/Lib/site-packages/numpy/random/__init__.pxd b/venv/Lib/site-packages/numpy/random/__init__.pxd new file mode 100644 index 0000000..1f90572 --- /dev/null +++ b/venv/Lib/site-packages/numpy/random/__init__.pxd @@ -0,0 +1,14 @@ +cimport numpy as np +from libc.stdint cimport uint32_t, uint64_t + +cdef extern from "numpy/random/bitgen.h": + struct bitgen: + void *state + uint64_t (*next_uint64)(void *st) nogil + uint32_t (*next_uint32)(void *st) nogil + double (*next_double)(void *st) nogil + uint64_t (*next_raw)(void *st) nogil + + ctypedef bitgen bitgen_t + +from numpy.random.bit_generator cimport BitGenerator, SeedSequence diff --git a/venv/Lib/site-packages/numpy/random/__init__.py b/venv/Lib/site-packages/numpy/random/__init__.py new file mode 100644 index 0000000..7efa5c0 --- /dev/null +++ b/venv/Lib/site-packages/numpy/random/__init__.py @@ -0,0 +1,213 @@ +""" +======================== +Random Number Generation +======================== + +Use ``default_rng()`` to create a `Generator` and call its methods. + +=============== ========================================================= +Generator +--------------- --------------------------------------------------------- +Generator Class implementing all of the random number distributions +default_rng Default constructor for ``Generator`` +=============== ========================================================= + +============================================= === +BitGenerator Streams that work with Generator +--------------------------------------------- --- +MT19937 +PCG64 +Philox +SFC64 +============================================= === + +============================================= === +Getting entropy to initialize a BitGenerator +--------------------------------------------- --- +SeedSequence +============================================= === + + +Legacy +------ + +For backwards compatibility with previous versions of numpy before 1.17, the +various aliases to the global `RandomState` methods are left alone and do not +use the new `Generator` API. + +==================== ========================================================= +Utility functions +-------------------- --------------------------------------------------------- +random Uniformly distributed floats over ``[0, 1)`` +bytes Uniformly distributed random bytes. +permutation Randomly permute a sequence / generate a random sequence. +shuffle Randomly permute a sequence in place. +choice Random sample from 1-D array. +==================== ========================================================= + +==================== ========================================================= +Compatibility +functions - removed +in the new API +-------------------- --------------------------------------------------------- +rand Uniformly distributed values. +randn Normally distributed values. +ranf Uniformly distributed floating point numbers. +random_integers Uniformly distributed integers in a given range. + (deprecated, use ``integers(..., closed=True)`` instead) +random_sample Alias for `random_sample` +randint Uniformly distributed integers in a given range +seed Seed the legacy random number generator. +==================== ========================================================= + +==================== ========================================================= +Univariate +distributions +-------------------- --------------------------------------------------------- +beta Beta distribution over ``[0, 1]``. +binomial Binomial distribution. +chisquare :math:`\\chi^2` distribution. +exponential Exponential distribution. +f F (Fisher-Snedecor) distribution. +gamma Gamma distribution. +geometric Geometric distribution. +gumbel Gumbel distribution. +hypergeometric Hypergeometric distribution. +laplace Laplace distribution. +logistic Logistic distribution. +lognormal Log-normal distribution. +logseries Logarithmic series distribution. +negative_binomial Negative binomial distribution. +noncentral_chisquare Non-central chi-square distribution. +noncentral_f Non-central F distribution. +normal Normal / Gaussian distribution. +pareto Pareto distribution. +poisson Poisson distribution. +power Power distribution. +rayleigh Rayleigh distribution. +triangular Triangular distribution. +uniform Uniform distribution. +vonmises Von Mises circular distribution. +wald Wald (inverse Gaussian) distribution. +weibull Weibull distribution. +zipf Zipf's distribution over ranked data. +==================== ========================================================= + +==================== ========================================================== +Multivariate +distributions +-------------------- ---------------------------------------------------------- +dirichlet Multivariate generalization of Beta distribution. +multinomial Multivariate generalization of the binomial distribution. +multivariate_normal Multivariate generalization of the normal distribution. +==================== ========================================================== + +==================== ========================================================= +Standard +distributions +-------------------- --------------------------------------------------------- +standard_cauchy Standard Cauchy-Lorentz distribution. +standard_exponential Standard exponential distribution. +standard_gamma Standard Gamma distribution. +standard_normal Standard normal distribution. +standard_t Standard Student's t-distribution. +==================== ========================================================= + +==================== ========================================================= +Internal functions +-------------------- --------------------------------------------------------- +get_state Get tuple representing internal state of generator. +set_state Set state of generator. +==================== ========================================================= + + +""" +__all__ = [ + 'beta', + 'binomial', + 'bytes', + 'chisquare', + 'choice', + 'dirichlet', + 'exponential', + 'f', + 'gamma', + 'geometric', + 'get_state', + 'gumbel', + 'hypergeometric', + 'laplace', + 'logistic', + 'lognormal', + 'logseries', + 'multinomial', + 'multivariate_normal', + 'negative_binomial', + 'noncentral_chisquare', + 'noncentral_f', + 'normal', + 'pareto', + 'permutation', + 'poisson', + 'power', + 'rand', + 'randint', + 'randn', + 'random', + 'random_integers', + 'random_sample', + 'ranf', + 'rayleigh', + 'sample', + 'seed', + 'set_state', + 'shuffle', + 'standard_cauchy', + 'standard_exponential', + 'standard_gamma', + 'standard_normal', + 'standard_t', + 'triangular', + 'uniform', + 'vonmises', + 'wald', + 'weibull', + 'zipf', +] + +# add these for module-freeze analysis (like PyInstaller) +from . import _pickle +from . import _common +from . import _bounded_integers + +from ._generator import Generator, default_rng +from .bit_generator import SeedSequence, BitGenerator +from ._mt19937 import MT19937 +from ._pcg64 import PCG64 +from ._philox import Philox +from ._sfc64 import SFC64 +from .mtrand import * + +__all__ += ['Generator', 'RandomState', 'SeedSequence', 'MT19937', + 'Philox', 'PCG64', 'SFC64', 'default_rng', 'BitGenerator'] + + +def __RandomState_ctor(): + """Return a RandomState instance. + + This function exists solely to assist (un)pickling. + + Note that the state of the RandomState returned here is irrelevant, as this + function's entire purpose is to return a newly allocated RandomState whose + state pickle can set. Consequently the RandomState returned by this function + is a freshly allocated copy with a seed=0. + + See https://github.com/numpy/numpy/issues/4763 for a detailed discussion + + """ + return RandomState(seed=0) + + +from numpy._pytesttester import PytestTester +test = PytestTester(__name__) +del PytestTester diff --git a/venv/Lib/site-packages/numpy/random/__init__.pyi b/venv/Lib/site-packages/numpy/random/__init__.pyi new file mode 100644 index 0000000..bd5ece5 --- /dev/null +++ b/venv/Lib/site-packages/numpy/random/__init__.pyi @@ -0,0 +1,63 @@ +from typing import Any, List + +__all__: List[str] + +beta: Any +binomial: Any +bytes: Any +chisquare: Any +choice: Any +dirichlet: Any +exponential: Any +f: Any +gamma: Any +geometric: Any +get_state: Any +gumbel: Any +hypergeometric: Any +laplace: Any +logistic: Any +lognormal: Any +logseries: Any +multinomial: Any +multivariate_normal: Any +negative_binomial: Any +noncentral_chisquare: Any +noncentral_f: Any +normal: Any +pareto: Any +permutation: Any +poisson: Any +power: Any +rand: Any +randint: Any +randn: Any +random: Any +random_integers: Any +random_sample: Any +ranf: Any +rayleigh: Any +sample: Any +seed: Any +set_state: Any +shuffle: Any +standard_cauchy: Any +standard_exponential: Any +standard_gamma: Any +standard_normal: Any +standard_t: Any +triangular: Any +uniform: Any +vonmises: Any +wald: Any +weibull: Any +zipf: Any +Generator: Any +RandomState: Any +SeedSequence: Any +MT19937: Any +Philox: Any +PCG64: Any +SFC64: Any +default_rng: Any +BitGenerator: Any diff --git a/venv/Lib/site-packages/numpy/random/_bounded_integers.pxd b/venv/Lib/site-packages/numpy/random/_bounded_integers.pxd new file mode 100644 index 0000000..7e41463 --- /dev/null +++ b/venv/Lib/site-packages/numpy/random/_bounded_integers.pxd @@ -0,0 +1,29 @@ +from libc.stdint cimport (uint8_t, uint16_t, uint32_t, uint64_t, + int8_t, int16_t, int32_t, int64_t, intptr_t) +import numpy as np +cimport numpy as np +ctypedef np.npy_bool bool_t + +from numpy.random cimport bitgen_t + +cdef inline uint64_t _gen_mask(uint64_t max_val) nogil: + """Mask generator for use in bounded random numbers""" + # Smallest bit mask >= max + cdef uint64_t mask = max_val + mask |= mask >> 1 + mask |= mask >> 2 + mask |= mask >> 4 + mask |= mask >> 8 + mask |= mask >> 16 + mask |= mask >> 32 + return mask + +cdef object _rand_uint64(object low, object high, object size, bint use_masked, bint closed, bitgen_t *state, object lock) +cdef object _rand_uint32(object low, object high, object size, bint use_masked, bint closed, bitgen_t *state, object lock) +cdef object _rand_uint16(object low, object high, object size, bint use_masked, bint closed, bitgen_t *state, object lock) +cdef object _rand_uint8(object low, object high, object size, bint use_masked, bint closed, bitgen_t *state, object lock) +cdef object _rand_bool(object low, object high, object size, bint use_masked, bint closed, bitgen_t *state, object lock) +cdef object _rand_int64(object low, object high, object size, bint use_masked, bint closed, bitgen_t *state, object lock) +cdef object _rand_int32(object low, object high, object size, bint use_masked, bint closed, bitgen_t *state, object lock) +cdef object _rand_int16(object low, object high, object size, bint use_masked, bint closed, bitgen_t *state, object lock) +cdef object _rand_int8(object low, object high, object size, bint use_masked, bint closed, bitgen_t *state, object lock) diff --git a/venv/Lib/site-packages/numpy/random/_common.pxd b/venv/Lib/site-packages/numpy/random/_common.pxd new file mode 100644 index 0000000..4f404b7 --- /dev/null +++ b/venv/Lib/site-packages/numpy/random/_common.pxd @@ -0,0 +1,106 @@ +#cython: language_level=3 + +from libc.stdint cimport uint32_t, uint64_t, int32_t, int64_t + +import numpy as np +cimport numpy as np + +from numpy.random cimport bitgen_t + +cdef double POISSON_LAM_MAX +cdef double LEGACY_POISSON_LAM_MAX +cdef uint64_t MAXSIZE + +cdef enum ConstraintType: + CONS_NONE + CONS_NON_NEGATIVE + CONS_POSITIVE + CONS_POSITIVE_NOT_NAN + CONS_BOUNDED_0_1 + CONS_BOUNDED_0_1_NOTNAN + CONS_BOUNDED_GT_0_1 + CONS_GT_1 + CONS_GTE_1 + CONS_POISSON + LEGACY_CONS_POISSON + +ctypedef ConstraintType constraint_type + +cdef object benchmark(bitgen_t *bitgen, object lock, Py_ssize_t cnt, object method) +cdef object random_raw(bitgen_t *bitgen, object lock, object size, object output) +cdef object prepare_cffi(bitgen_t *bitgen) +cdef object prepare_ctypes(bitgen_t *bitgen) +cdef int check_constraint(double val, object name, constraint_type cons) except -1 +cdef int check_array_constraint(np.ndarray val, object name, constraint_type cons) except -1 + +cdef extern from "include/aligned_malloc.h": + cdef void *PyArray_realloc_aligned(void *p, size_t n) + cdef void *PyArray_malloc_aligned(size_t n) + cdef void *PyArray_calloc_aligned(size_t n, size_t s) + cdef void PyArray_free_aligned(void *p) + +ctypedef double (*random_double_fill)(bitgen_t *state, np.npy_intp count, double* out) nogil +ctypedef double (*random_double_0)(void *state) nogil +ctypedef double (*random_double_1)(void *state, double a) nogil +ctypedef double (*random_double_2)(void *state, double a, double b) nogil +ctypedef double (*random_double_3)(void *state, double a, double b, double c) nogil + +ctypedef double (*random_float_fill)(bitgen_t *state, np.npy_intp count, float* out) nogil +ctypedef float (*random_float_0)(bitgen_t *state) nogil +ctypedef float (*random_float_1)(bitgen_t *state, float a) nogil + +ctypedef int64_t (*random_uint_0)(void *state) nogil +ctypedef int64_t (*random_uint_d)(void *state, double a) nogil +ctypedef int64_t (*random_uint_dd)(void *state, double a, double b) nogil +ctypedef int64_t (*random_uint_di)(void *state, double a, uint64_t b) nogil +ctypedef int64_t (*random_uint_i)(void *state, int64_t a) nogil +ctypedef int64_t (*random_uint_iii)(void *state, int64_t a, int64_t b, int64_t c) nogil + +ctypedef uint32_t (*random_uint_0_32)(bitgen_t *state) nogil +ctypedef uint32_t (*random_uint_1_i_32)(bitgen_t *state, uint32_t a) nogil + +ctypedef int32_t (*random_int_2_i_32)(bitgen_t *state, int32_t a, int32_t b) nogil +ctypedef int64_t (*random_int_2_i)(bitgen_t *state, int64_t a, int64_t b) nogil + +cdef double kahan_sum(double *darr, np.npy_intp n) + +cdef inline double uint64_to_double(uint64_t rnd) nogil: + return (rnd >> 11) * (1.0 / 9007199254740992.0) + +cdef object double_fill(void *func, bitgen_t *state, object size, object lock, object out) + +cdef object float_fill(void *func, bitgen_t *state, object size, object lock, object out) + +cdef object float_fill_from_double(void *func, bitgen_t *state, object size, object lock, object out) + +cdef object wrap_int(object val, object bits) + +cdef np.ndarray int_to_array(object value, object name, object bits, object uint_size) + +cdef validate_output_shape(iter_shape, np.ndarray output) + +cdef object cont(void *func, void *state, object size, object lock, int narg, + object a, object a_name, constraint_type a_constraint, + object b, object b_name, constraint_type b_constraint, + object c, object c_name, constraint_type c_constraint, + object out) + +cdef object disc(void *func, void *state, object size, object lock, + int narg_double, int narg_int64, + object a, object a_name, constraint_type a_constraint, + object b, object b_name, constraint_type b_constraint, + object c, object c_name, constraint_type c_constraint) + +cdef object cont_f(void *func, bitgen_t *state, object size, object lock, + object a, object a_name, constraint_type a_constraint, + object out) + +cdef object cont_broadcast_3(void *func, void *state, object size, object lock, + np.ndarray a_arr, object a_name, constraint_type a_constraint, + np.ndarray b_arr, object b_name, constraint_type b_constraint, + np.ndarray c_arr, object c_name, constraint_type c_constraint) + +cdef object discrete_broadcast_iii(void *func, void *state, object size, object lock, + np.ndarray a_arr, object a_name, constraint_type a_constraint, + np.ndarray b_arr, object b_name, constraint_type b_constraint, + np.ndarray c_arr, object c_name, constraint_type c_constraint) diff --git a/venv/Lib/site-packages/numpy/random/_examples/cffi/extending.py b/venv/Lib/site-packages/numpy/random/_examples/cffi/extending.py new file mode 100644 index 0000000..8440d40 --- /dev/null +++ b/venv/Lib/site-packages/numpy/random/_examples/cffi/extending.py @@ -0,0 +1,40 @@ +""" +Use cffi to access any of the underlying C functions from distributions.h +""" +import os +import numpy as np +import cffi +from .parse import parse_distributions_h +ffi = cffi.FFI() + +inc_dir = os.path.join(np.get_include(), 'numpy') + +# Basic numpy types +ffi.cdef(''' + typedef intptr_t npy_intp; + typedef unsigned char npy_bool; + +''') + +parse_distributions_h(ffi, inc_dir) + +lib = ffi.dlopen(np.random._generator.__file__) + +# Compare the distributions.h random_standard_normal_fill to +# Generator.standard_random +bit_gen = np.random.PCG64() +rng = np.random.Generator(bit_gen) +state = bit_gen.state + +interface = rng.bit_generator.cffi +n = 100 +vals_cffi = ffi.new('double[%d]' % n) +lib.random_standard_normal_fill(interface.bit_generator, n, vals_cffi) + +# reset the state +bit_gen.state = state + +vals = rng.standard_normal(n) + +for i in range(n): + assert vals[i] == vals_cffi[i] diff --git a/venv/Lib/site-packages/numpy/random/_examples/cffi/parse.py b/venv/Lib/site-packages/numpy/random/_examples/cffi/parse.py new file mode 100644 index 0000000..daff6bd --- /dev/null +++ b/venv/Lib/site-packages/numpy/random/_examples/cffi/parse.py @@ -0,0 +1,55 @@ +import os + + +def parse_distributions_h(ffi, inc_dir): + """ + Parse distributions.h located in inc_dir for CFFI, filling in the ffi.cdef + + Read the function declarations without the "#define ..." macros that will + be filled in when loading the library. + """ + + with open(os.path.join(inc_dir, 'random', 'bitgen.h')) as fid: + s = [] + for line in fid: + # massage the include file + if line.strip().startswith('#'): + continue + s.append(line) + ffi.cdef('\n'.join(s)) + + with open(os.path.join(inc_dir, 'random', 'distributions.h')) as fid: + s = [] + in_skip = 0 + ignoring = False + for line in fid: + # check for and remove extern "C" guards + if ignoring: + if line.strip().startswith('#endif'): + ignoring = False + continue + if line.strip().startswith('#ifdef __cplusplus'): + ignoring = True + + # massage the include file + if line.strip().startswith('#'): + continue + + # skip any inlined function definition + # which starts with 'static NPY_INLINE xxx(...) {' + # and ends with a closing '}' + if line.strip().startswith('static NPY_INLINE'): + in_skip += line.count('{') + continue + elif in_skip > 0: + in_skip += line.count('{') + in_skip -= line.count('}') + continue + + # replace defines with their value or remove them + line = line.replace('DECLDIR', '') + line = line.replace('NPY_INLINE', '') + line = line.replace('RAND_INT_TYPE', 'int64_t') + s.append(line) + ffi.cdef('\n'.join(s)) + diff --git a/venv/Lib/site-packages/numpy/random/_examples/cython/extending.pyx b/venv/Lib/site-packages/numpy/random/_examples/cython/extending.pyx new file mode 100644 index 0000000..3a7f81a --- /dev/null +++ b/venv/Lib/site-packages/numpy/random/_examples/cython/extending.pyx @@ -0,0 +1,78 @@ +#!/usr/bin/env python3 +#cython: language_level=3 + +from libc.stdint cimport uint32_t +from cpython.pycapsule cimport PyCapsule_IsValid, PyCapsule_GetPointer + +import numpy as np +cimport numpy as np +cimport cython + +from numpy.random cimport bitgen_t +from numpy.random import PCG64 + +np.import_array() + + +@cython.boundscheck(False) +@cython.wraparound(False) +def uniform_mean(Py_ssize_t n): + cdef Py_ssize_t i + cdef bitgen_t *rng + cdef const char *capsule_name = "BitGenerator" + cdef double[::1] random_values + cdef np.ndarray randoms + + x = PCG64() + capsule = x.capsule + if not PyCapsule_IsValid(capsule, capsule_name): + raise ValueError("Invalid pointer to anon_func_state") + rng = PyCapsule_GetPointer(capsule, capsule_name) + random_values = np.empty(n) + # Best practice is to acquire the lock whenever generating random values. + # This prevents other threads from modifying the state. Acquiring the lock + # is only necessary if if the GIL is also released, as in this example. + with x.lock, nogil: + for i in range(n): + random_values[i] = rng.next_double(rng.state) + randoms = np.asarray(random_values) + return randoms.mean() + + +# This function is declared nogil so it can be used without the GIL below +cdef uint32_t bounded_uint(uint32_t lb, uint32_t ub, bitgen_t *rng) nogil: + cdef uint32_t mask, delta, val + mask = delta = ub - lb + mask |= mask >> 1 + mask |= mask >> 2 + mask |= mask >> 4 + mask |= mask >> 8 + mask |= mask >> 16 + + val = rng.next_uint32(rng.state) & mask + while val > delta: + val = rng.next_uint32(rng.state) & mask + + return lb + val + + +@cython.boundscheck(False) +@cython.wraparound(False) +def bounded_uints(uint32_t lb, uint32_t ub, Py_ssize_t n): + cdef Py_ssize_t i + cdef bitgen_t *rng + cdef uint32_t[::1] out + cdef const char *capsule_name = "BitGenerator" + + x = PCG64() + out = np.empty(n, dtype=np.uint32) + capsule = x.capsule + + if not PyCapsule_IsValid(capsule, capsule_name): + raise ValueError("Invalid pointer to anon_func_state") + rng = PyCapsule_GetPointer(capsule, capsule_name) + + with x.lock, nogil: + for i in range(n): + out[i] = bounded_uint(lb, ub, rng) + return np.asarray(out) diff --git a/venv/Lib/site-packages/numpy/random/_examples/cython/extending_distributions.pyx b/venv/Lib/site-packages/numpy/random/_examples/cython/extending_distributions.pyx new file mode 100644 index 0000000..d908e92 --- /dev/null +++ b/venv/Lib/site-packages/numpy/random/_examples/cython/extending_distributions.pyx @@ -0,0 +1,117 @@ +#!/usr/bin/env python3 +#cython: language_level=3 +""" +This file shows how the to use a BitGenerator to create a distribution. +""" +import numpy as np +cimport numpy as np +cimport cython +from cpython.pycapsule cimport PyCapsule_IsValid, PyCapsule_GetPointer +from libc.stdint cimport uint16_t, uint64_t +from numpy.random cimport bitgen_t +from numpy.random import PCG64 +from numpy.random.c_distributions cimport ( + random_standard_uniform_fill, random_standard_uniform_fill_f) + + +@cython.boundscheck(False) +@cython.wraparound(False) +def uniforms(Py_ssize_t n): + """ + Create an array of `n` uniformly distributed doubles. + A 'real' distribution would want to process the values into + some non-uniform distribution + """ + cdef Py_ssize_t i + cdef bitgen_t *rng + cdef const char *capsule_name = "BitGenerator" + cdef double[::1] random_values + + x = PCG64() + capsule = x.capsule + # Optional check that the capsule if from a BitGenerator + if not PyCapsule_IsValid(capsule, capsule_name): + raise ValueError("Invalid pointer to anon_func_state") + # Cast the pointer + rng = PyCapsule_GetPointer(capsule, capsule_name) + random_values = np.empty(n, dtype='float64') + with x.lock, nogil: + for i in range(n): + # Call the function + random_values[i] = rng.next_double(rng.state) + randoms = np.asarray(random_values) + + return randoms + +# cython example 2 +@cython.boundscheck(False) +@cython.wraparound(False) +def uint10_uniforms(Py_ssize_t n): + """Uniform 10 bit integers stored as 16-bit unsigned integers""" + cdef Py_ssize_t i + cdef bitgen_t *rng + cdef const char *capsule_name = "BitGenerator" + cdef uint16_t[::1] random_values + cdef int bits_remaining + cdef int width = 10 + cdef uint64_t buff, mask = 0x3FF + + x = PCG64() + capsule = x.capsule + if not PyCapsule_IsValid(capsule, capsule_name): + raise ValueError("Invalid pointer to anon_func_state") + rng = PyCapsule_GetPointer(capsule, capsule_name) + random_values = np.empty(n, dtype='uint16') + # Best practice is to release GIL and acquire the lock + bits_remaining = 0 + with x.lock, nogil: + for i in range(n): + if bits_remaining < width: + buff = rng.next_uint64(rng.state) + random_values[i] = buff & mask + buff >>= width + + randoms = np.asarray(random_values) + return randoms + +# cython example 3 +def uniforms_ex(bit_generator, Py_ssize_t n, dtype=np.float64): + """ + Create an array of `n` uniformly distributed doubles via a "fill" function. + + A 'real' distribution would want to process the values into + some non-uniform distribution + + Parameters + ---------- + bit_generator: BitGenerator instance + n: int + Output vector length + dtype: {str, dtype}, optional + Desired dtype, either 'd' (or 'float64') or 'f' (or 'float32'). The + default dtype value is 'd' + """ + cdef Py_ssize_t i + cdef bitgen_t *rng + cdef const char *capsule_name = "BitGenerator" + cdef np.ndarray randoms + + capsule = bit_generator.capsule + # Optional check that the capsule if from a BitGenerator + if not PyCapsule_IsValid(capsule, capsule_name): + raise ValueError("Invalid pointer to anon_func_state") + # Cast the pointer + rng = PyCapsule_GetPointer(capsule, capsule_name) + + _dtype = np.dtype(dtype) + randoms = np.empty(n, dtype=_dtype) + if _dtype == np.float32: + with bit_generator.lock: + random_standard_uniform_fill_f(rng, n, np.PyArray_DATA(randoms)) + elif _dtype == np.float64: + with bit_generator.lock: + random_standard_uniform_fill(rng, n, np.PyArray_DATA(randoms)) + else: + raise TypeError('Unsupported dtype %r for random' % _dtype) + return randoms + diff --git a/venv/Lib/site-packages/numpy/random/_examples/cython/setup.py b/venv/Lib/site-packages/numpy/random/_examples/cython/setup.py new file mode 100644 index 0000000..83f06fd --- /dev/null +++ b/venv/Lib/site-packages/numpy/random/_examples/cython/setup.py @@ -0,0 +1,41 @@ +#!/usr/bin/env python3 +""" +Build the Cython demonstrations of low-level access to NumPy random + +Usage: python setup.py build_ext -i +""" + +import numpy as np +from distutils.core import setup +from Cython.Build import cythonize +from setuptools.extension import Extension +from os.path import join, dirname + +path = dirname(__file__) +src_dir = join(dirname(path), '..', 'src') +defs = [('NPY_NO_DEPRECATED_API', 0)] +inc_path = np.get_include() +# not so nice. We need the random/lib library from numpy +lib_path = join(np.get_include(), '..', '..', 'random', 'lib') + +extending = Extension("extending", + sources=[join('.', 'extending.pyx')], + include_dirs=[ + np.get_include(), + join(path, '..', '..') + ], + define_macros=defs, + ) +distributions = Extension("extending_distributions", + sources=[join('.', 'extending_distributions.pyx')], + include_dirs=[inc_path], + library_dirs=[lib_path], + libraries=['npyrandom'], + define_macros=defs, + ) + +extensions = [extending, distributions] + +setup( + ext_modules=cythonize(extensions) +) diff --git a/venv/Lib/site-packages/numpy/random/_examples/numba/extending.py b/venv/Lib/site-packages/numpy/random/_examples/numba/extending.py new file mode 100644 index 0000000..f387db6 --- /dev/null +++ b/venv/Lib/site-packages/numpy/random/_examples/numba/extending.py @@ -0,0 +1,84 @@ +import numpy as np +import numba as nb + +from numpy.random import PCG64 +from timeit import timeit + +bit_gen = PCG64() +next_d = bit_gen.cffi.next_double +state_addr = bit_gen.cffi.state_address + +def normals(n, state): + out = np.empty(n) + for i in range((n + 1) // 2): + x1 = 2.0 * next_d(state) - 1.0 + x2 = 2.0 * next_d(state) - 1.0 + r2 = x1 * x1 + x2 * x2 + while r2 >= 1.0 or r2 == 0.0: + x1 = 2.0 * next_d(state) - 1.0 + x2 = 2.0 * next_d(state) - 1.0 + r2 = x1 * x1 + x2 * x2 + f = np.sqrt(-2.0 * np.log(r2) / r2) + out[2 * i] = f * x1 + if 2 * i + 1 < n: + out[2 * i + 1] = f * x2 + return out + +# Compile using Numba +normalsj = nb.jit(normals, nopython=True) +# Must use state address not state with numba +n = 10000 + +def numbacall(): + return normalsj(n, state_addr) + +rg = np.random.Generator(PCG64()) + +def numpycall(): + return rg.normal(size=n) + +# Check that the functions work +r1 = numbacall() +r2 = numpycall() +assert r1.shape == (n,) +assert r1.shape == r2.shape + +t1 = timeit(numbacall, number=1000) +print(f'{t1:.2f} secs for {n} PCG64 (Numba/PCG64) gaussian randoms') +t2 = timeit(numpycall, number=1000) +print(f'{t2:.2f} secs for {n} PCG64 (NumPy/PCG64) gaussian randoms') + +# example 2 + +next_u32 = bit_gen.ctypes.next_uint32 +ctypes_state = bit_gen.ctypes.state + +@nb.jit(nopython=True) +def bounded_uint(lb, ub, state): + mask = delta = ub - lb + mask |= mask >> 1 + mask |= mask >> 2 + mask |= mask >> 4 + mask |= mask >> 8 + mask |= mask >> 16 + + val = next_u32(state) & mask + while val > delta: + val = next_u32(state) & mask + + return lb + val + + +print(bounded_uint(323, 2394691, ctypes_state.value)) + + +@nb.jit(nopython=True) +def bounded_uints(lb, ub, n, state): + out = np.empty(n, dtype=np.uint32) + for i in range(n): + out[i] = bounded_uint(lb, ub, state) + + +bounded_uints(323, 2394691, 10000000, ctypes_state.value) + + diff --git a/venv/Lib/site-packages/numpy/random/_examples/numba/extending_distributions.py b/venv/Lib/site-packages/numpy/random/_examples/numba/extending_distributions.py new file mode 100644 index 0000000..7cf8bf0 --- /dev/null +++ b/venv/Lib/site-packages/numpy/random/_examples/numba/extending_distributions.py @@ -0,0 +1,67 @@ +r""" +Building the required library in this example requires a source distribution +of NumPy or clone of the NumPy git repository since distributions.c is not +included in binary distributions. + +On *nix, execute in numpy/random/src/distributions + +export ${PYTHON_VERSION}=3.8 # Python version +export PYTHON_INCLUDE=#path to Python's include folder, usually \ + ${PYTHON_HOME}/include/python${PYTHON_VERSION}m +export NUMPY_INCLUDE=#path to numpy's include folder, usually \ + ${PYTHON_HOME}/lib/python${PYTHON_VERSION}/site-packages/numpy/core/include +gcc -shared -o libdistributions.so -fPIC distributions.c \ + -I${NUMPY_INCLUDE} -I${PYTHON_INCLUDE} +mv libdistributions.so ../../_examples/numba/ + +On Windows + +rem PYTHON_HOME and PYTHON_VERSION are setup dependent, this is an example +set PYTHON_HOME=c:\Anaconda +set PYTHON_VERSION=38 +cl.exe /LD .\distributions.c -DDLL_EXPORT \ + -I%PYTHON_HOME%\lib\site-packages\numpy\core\include \ + -I%PYTHON_HOME%\include %PYTHON_HOME%\libs\python%PYTHON_VERSION%.lib +move distributions.dll ../../_examples/numba/ +""" +import os + +import numba as nb +import numpy as np +from cffi import FFI + +from numpy.random import PCG64 + +ffi = FFI() +if os.path.exists('./distributions.dll'): + lib = ffi.dlopen('./distributions.dll') +elif os.path.exists('./libdistributions.so'): + lib = ffi.dlopen('./libdistributions.so') +else: + raise RuntimeError('Required DLL/so file was not found.') + +ffi.cdef(""" +double random_standard_normal(void *bitgen_state); +""") +x = PCG64() +xffi = x.cffi +bit_generator = xffi.bit_generator + +random_standard_normal = lib.random_standard_normal + + +def normals(n, bit_generator): + out = np.empty(n) + for i in range(n): + out[i] = random_standard_normal(bit_generator) + return out + + +normalsj = nb.jit(normals, nopython=True) + +# Numba requires a memory address for void * +# Can also get address from x.ctypes.bit_generator.value +bit_generator_address = int(ffi.cast('uintptr_t', bit_generator)) + +norm = normalsj(1000, bit_generator_address) +print(norm[:12]) diff --git a/venv/Lib/site-packages/numpy/random/_pickle.py b/venv/Lib/site-packages/numpy/random/_pickle.py new file mode 100644 index 0000000..29ff696 --- /dev/null +++ b/venv/Lib/site-packages/numpy/random/_pickle.py @@ -0,0 +1,82 @@ +from .mtrand import RandomState +from ._philox import Philox +from ._pcg64 import PCG64 +from ._sfc64 import SFC64 + +from ._generator import Generator +from ._mt19937 import MT19937 + +BitGenerators = {'MT19937': MT19937, + 'PCG64': PCG64, + 'Philox': Philox, + 'SFC64': SFC64, + } + + +def __generator_ctor(bit_generator_name='MT19937'): + """ + Pickling helper function that returns a Generator object + + Parameters + ---------- + bit_generator_name: str + String containing the core BitGenerator + + Returns + ------- + rg: Generator + Generator using the named core BitGenerator + """ + if bit_generator_name in BitGenerators: + bit_generator = BitGenerators[bit_generator_name] + else: + raise ValueError(str(bit_generator_name) + ' is not a known ' + 'BitGenerator module.') + + return Generator(bit_generator()) + + +def __bit_generator_ctor(bit_generator_name='MT19937'): + """ + Pickling helper function that returns a bit generator object + + Parameters + ---------- + bit_generator_name: str + String containing the name of the BitGenerator + + Returns + ------- + bit_generator: BitGenerator + BitGenerator instance + """ + if bit_generator_name in BitGenerators: + bit_generator = BitGenerators[bit_generator_name] + else: + raise ValueError(str(bit_generator_name) + ' is not a known ' + 'BitGenerator module.') + + return bit_generator() + + +def __randomstate_ctor(bit_generator_name='MT19937'): + """ + Pickling helper function that returns a legacy RandomState-like object + + Parameters + ---------- + bit_generator_name: str + String containing the core BitGenerator + + Returns + ------- + rs: RandomState + Legacy RandomState using the named core BitGenerator + """ + if bit_generator_name in BitGenerators: + bit_generator = BitGenerators[bit_generator_name] + else: + raise ValueError(str(bit_generator_name) + ' is not a known ' + 'BitGenerator module.') + + return RandomState(bit_generator()) diff --git a/venv/Lib/site-packages/numpy/random/bit_generator.pxd b/venv/Lib/site-packages/numpy/random/bit_generator.pxd new file mode 100644 index 0000000..dfa7d0a --- /dev/null +++ b/venv/Lib/site-packages/numpy/random/bit_generator.pxd @@ -0,0 +1,35 @@ +cimport numpy as np +from libc.stdint cimport uint32_t, uint64_t + +cdef extern from "numpy/random/bitgen.h": + struct bitgen: + void *state + uint64_t (*next_uint64)(void *st) nogil + uint32_t (*next_uint32)(void *st) nogil + double (*next_double)(void *st) nogil + uint64_t (*next_raw)(void *st) nogil + + ctypedef bitgen bitgen_t + +cdef class BitGenerator(): + cdef readonly object _seed_seq + cdef readonly object lock + cdef bitgen_t _bitgen + cdef readonly object _ctypes + cdef readonly object _cffi + cdef readonly object capsule + + +cdef class SeedSequence(): + cdef readonly object entropy + cdef readonly tuple spawn_key + cdef readonly Py_ssize_t pool_size + cdef readonly object pool + cdef readonly uint32_t n_children_spawned + + cdef mix_entropy(self, np.ndarray[np.npy_uint32, ndim=1] mixer, + np.ndarray[np.npy_uint32, ndim=1] entropy_array) + cdef get_assembled_entropy(self) + +cdef class SeedlessSequence(): + pass diff --git a/venv/Lib/site-packages/numpy/random/c_distributions.pxd b/venv/Lib/site-packages/numpy/random/c_distributions.pxd new file mode 100644 index 0000000..6f905ed --- /dev/null +++ b/venv/Lib/site-packages/numpy/random/c_distributions.pxd @@ -0,0 +1,114 @@ +#!python +#cython: wraparound=False, nonecheck=False, boundscheck=False, cdivision=True, language_level=3 +from numpy cimport npy_intp + +from libc.stdint cimport (uint64_t, int32_t, int64_t) +from numpy.random cimport bitgen_t + +cdef extern from "numpy/random/distributions.h": + + struct s_binomial_t: + int has_binomial + double psave + int64_t nsave + double r + double q + double fm + int64_t m + double p1 + double xm + double xl + double xr + double c + double laml + double lamr + double p2 + double p3 + double p4 + + ctypedef s_binomial_t binomial_t + + double random_standard_uniform(bitgen_t *bitgen_state) nogil + void random_standard_uniform_fill(bitgen_t* bitgen_state, npy_intp cnt, double *out) nogil + double random_standard_exponential(bitgen_t *bitgen_state) nogil + double random_standard_exponential_f(bitgen_t *bitgen_state) nogil + void random_standard_exponential_fill(bitgen_t *bitgen_state, npy_intp cnt, double *out) nogil + void random_standard_exponential_fill_f(bitgen_t *bitgen_state, npy_intp cnt, double *out) nogil + void random_standard_exponential_inv_fill(bitgen_t *bitgen_state, npy_intp cnt, double *out) nogil + void random_standard_exponential_inv_fill_f(bitgen_t *bitgen_state, npy_intp cnt, double *out) nogil + double random_standard_normal(bitgen_t* bitgen_state) nogil + void random_standard_normal_fill(bitgen_t *bitgen_state, npy_intp count, double *out) nogil + void random_standard_normal_fill_f(bitgen_t *bitgen_state, npy_intp count, float *out) nogil + double random_standard_gamma(bitgen_t *bitgen_state, double shape) nogil + + float random_standard_uniform_f(bitgen_t *bitgen_state) nogil + void random_standard_uniform_fill_f(bitgen_t* bitgen_state, npy_intp cnt, float *out) nogil + float random_standard_normal_f(bitgen_t* bitgen_state) nogil + float random_standard_gamma_f(bitgen_t *bitgen_state, float shape) nogil + + int64_t random_positive_int64(bitgen_t *bitgen_state) nogil + int32_t random_positive_int32(bitgen_t *bitgen_state) nogil + int64_t random_positive_int(bitgen_t *bitgen_state) nogil + uint64_t random_uint(bitgen_t *bitgen_state) nogil + + double random_normal(bitgen_t *bitgen_state, double loc, double scale) nogil + + double random_gamma(bitgen_t *bitgen_state, double shape, double scale) nogil + float random_gamma_f(bitgen_t *bitgen_state, float shape, float scale) nogil + + double random_exponential(bitgen_t *bitgen_state, double scale) nogil + double random_uniform(bitgen_t *bitgen_state, double lower, double range) nogil + double random_beta(bitgen_t *bitgen_state, double a, double b) nogil + double random_chisquare(bitgen_t *bitgen_state, double df) nogil + double random_f(bitgen_t *bitgen_state, double dfnum, double dfden) nogil + double random_standard_cauchy(bitgen_t *bitgen_state) nogil + double random_pareto(bitgen_t *bitgen_state, double a) nogil + double random_weibull(bitgen_t *bitgen_state, double a) nogil + double random_power(bitgen_t *bitgen_state, double a) nogil + double random_laplace(bitgen_t *bitgen_state, double loc, double scale) nogil + double random_gumbel(bitgen_t *bitgen_state, double loc, double scale) nogil + double random_logistic(bitgen_t *bitgen_state, double loc, double scale) nogil + double random_lognormal(bitgen_t *bitgen_state, double mean, double sigma) nogil + double random_rayleigh(bitgen_t *bitgen_state, double mode) nogil + double random_standard_t(bitgen_t *bitgen_state, double df) nogil + double random_noncentral_chisquare(bitgen_t *bitgen_state, double df, + double nonc) nogil + double random_noncentral_f(bitgen_t *bitgen_state, double dfnum, + double dfden, double nonc) nogil + double random_wald(bitgen_t *bitgen_state, double mean, double scale) nogil + double random_vonmises(bitgen_t *bitgen_state, double mu, double kappa) nogil + double random_triangular(bitgen_t *bitgen_state, double left, double mode, + double right) nogil + + int64_t random_poisson(bitgen_t *bitgen_state, double lam) nogil + int64_t random_negative_binomial(bitgen_t *bitgen_state, double n, double p) nogil + int64_t random_binomial(bitgen_t *bitgen_state, double p, int64_t n, binomial_t *binomial) nogil + int64_t random_logseries(bitgen_t *bitgen_state, double p) nogil + int64_t random_geometric_search(bitgen_t *bitgen_state, double p) nogil + int64_t random_geometric_inversion(bitgen_t *bitgen_state, double p) nogil + int64_t random_geometric(bitgen_t *bitgen_state, double p) nogil + int64_t random_zipf(bitgen_t *bitgen_state, double a) nogil + int64_t random_hypergeometric(bitgen_t *bitgen_state, int64_t good, int64_t bad, + int64_t sample) nogil + + uint64_t random_interval(bitgen_t *bitgen_state, uint64_t max) nogil + + # Generate random uint64 numbers in closed interval [off, off + rng]. + uint64_t random_bounded_uint64(bitgen_t *bitgen_state, + uint64_t off, uint64_t rng, + uint64_t mask, bint use_masked) nogil + + void random_multinomial(bitgen_t *bitgen_state, int64_t n, int64_t *mnix, + double *pix, npy_intp d, binomial_t *binomial) nogil + + int random_multivariate_hypergeometric_count(bitgen_t *bitgen_state, + int64_t total, + size_t num_colors, int64_t *colors, + int64_t nsample, + size_t num_variates, int64_t *variates) nogil + void random_multivariate_hypergeometric_marginals(bitgen_t *bitgen_state, + int64_t total, + size_t num_colors, int64_t *colors, + int64_t nsample, + size_t num_variates, int64_t *variates) nogil + diff --git a/venv/Lib/site-packages/numpy/random/lib/npyrandom.lib b/venv/Lib/site-packages/numpy/random/lib/npyrandom.lib new file mode 100644 index 0000000000000000000000000000000000000000..c21f6c9a88dbceecbcfd54b17e1bbe837ef15640 GIT binary patch literal 110126 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 lseek64 etc.) + if sys.platform[:3] == "aix": + defs = [('_LARGE_FILES', None)] + else: + defs = [('_FILE_OFFSET_BITS', '64'), + ('_LARGEFILE_SOURCE', '1'), + ('_LARGEFILE64_SOURCE', '1')] + + defs.append(('NPY_NO_DEPRECATED_API', 0)) + config.add_subpackage('tests') + config.add_data_dir('tests/data') + config.add_data_dir('_examples') + + EXTRA_LINK_ARGS = [] + EXTRA_LIBRARIES = ['npyrandom'] + if os.name != 'nt': + # Math lib + EXTRA_LIBRARIES.append('m') + # Some bit generators exclude GCC inlining + EXTRA_COMPILE_ARGS = ['-U__GNUC_GNU_INLINE__'] + + if is_msvc and platform_bits == 32: + # 32-bit windows requires explicit sse2 option + EXTRA_COMPILE_ARGS += ['/arch:SSE2'] + elif not is_msvc: + # Some bit generators require c99 + EXTRA_COMPILE_ARGS += ['-std=c99'] + + # Use legacy integer variable sizes + LEGACY_DEFS = [('NP_RANDOM_LEGACY', '1')] + PCG64_DEFS = [] + # One can force emulated 128-bit arithmetic if one wants. + #PCG64_DEFS += [('PCG_FORCE_EMULATED_128BIT_MATH', '1')] + depends = ['__init__.pxd', 'c_distributions.pxd', 'bit_generator.pxd'] + + # npyrandom - a library like npymath + npyrandom_sources = [ + 'src/distributions/logfactorial.c', + 'src/distributions/distributions.c', + 'src/distributions/random_mvhg_count.c', + 'src/distributions/random_mvhg_marginals.c', + 'src/distributions/random_hypergeometric.c', + ] + config.add_installed_library('npyrandom', + sources=npyrandom_sources, + install_dir='lib', + build_info={ + 'include_dirs' : [], # empty list required for creating npyrandom.h + 'extra_compiler_args' : (['/GL-'] if is_msvc else []), + }) + + for gen in ['mt19937']: + # gen.pyx, src/gen/gen.c, src/gen/gen-jump.c + config.add_extension(f'_{gen}', + sources=[f'_{gen}.c', + f'src/{gen}/{gen}.c', + f'src/{gen}/{gen}-jump.c'], + include_dirs=['.', 'src', join('src', gen)], + libraries=EXTRA_LIBRARIES, + extra_compile_args=EXTRA_COMPILE_ARGS, + extra_link_args=EXTRA_LINK_ARGS, + depends=depends + [f'_{gen}.pyx'], + define_macros=defs, + ) + for gen in ['philox', 'pcg64', 'sfc64']: + # gen.pyx, src/gen/gen.c + _defs = defs + PCG64_DEFS if gen == 'pcg64' else defs + config.add_extension(f'_{gen}', + sources=[f'_{gen}.c', + f'src/{gen}/{gen}.c'], + include_dirs=['.', 'src', join('src', gen)], + libraries=EXTRA_LIBRARIES, + extra_compile_args=EXTRA_COMPILE_ARGS, + extra_link_args=EXTRA_LINK_ARGS, + depends=depends + [f'_{gen}.pyx', + 'bit_generator.pyx', 'bit_generator.pxd'], + define_macros=_defs, + ) + for gen in ['_common', 'bit_generator']: + # gen.pyx + config.add_extension(gen, + sources=[f'{gen}.c'], + libraries=EXTRA_LIBRARIES, + extra_compile_args=EXTRA_COMPILE_ARGS, + extra_link_args=EXTRA_LINK_ARGS, + include_dirs=['.', 'src'], + depends=depends + [f'{gen}.pyx', f'{gen}.pxd',], + define_macros=defs, + ) + config.add_data_files(f'{gen}.pxd') + for gen in ['_generator', '_bounded_integers']: + # gen.pyx, src/distributions/distributions.c + config.add_extension(gen, + sources=[f'{gen}.c'], + libraries=EXTRA_LIBRARIES, + extra_compile_args=EXTRA_COMPILE_ARGS, + include_dirs=['.', 'src'], + extra_link_args=EXTRA_LINK_ARGS, + depends=depends + [f'{gen}.pyx'], + define_macros=defs, + ) + config.add_data_files('_bounded_integers.pxd') + config.add_extension('mtrand', + sources=['mtrand.c', + 'src/legacy/legacy-distributions.c', + 'src/distributions/distributions.c', + ], + include_dirs=['.', 'src', 'src/legacy'], + libraries=['m'] if os.name != 'nt' else [], + extra_compile_args=EXTRA_COMPILE_ARGS, + extra_link_args=EXTRA_LINK_ARGS, + depends=depends + ['mtrand.pyx'], + define_macros=defs + LEGACY_DEFS, + ) + config.add_data_files(*depends) + config.add_data_files('*.pyi') + return config + + +if __name__ == '__main__': + from numpy.distutils.core import setup + + setup(configuration=configuration) diff --git a/venv/Lib/site-packages/numpy/random/tests/__init__.py b/venv/Lib/site-packages/numpy/random/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/venv/Lib/site-packages/numpy/random/tests/data/__init__.py b/venv/Lib/site-packages/numpy/random/tests/data/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/venv/Lib/site-packages/numpy/random/tests/data/mt19937-testset-1.csv b/venv/Lib/site-packages/numpy/random/tests/data/mt19937-testset-1.csv new file mode 100644 index 0000000..b97bfa6 --- /dev/null +++ b/venv/Lib/site-packages/numpy/random/tests/data/mt19937-testset-1.csv @@ -0,0 +1,1001 @@ +seed, 0xdeadbeaf +0, 0xc816921f +1, 0xb3623c6d +2, 0x5fa391bb +3, 0x40178d9 +4, 0x7dcc9811 +5, 0x548eb8e6 +6, 0x92ba3125 +7, 0x65fde68d +8, 0x2f81ec95 +9, 0xbd94f7a2 +10, 0xdc4d9bcc +11, 0xa672bf13 +12, 0xb41113e +13, 0xec7e0066 +14, 0x50239372 +15, 0xd9d66b1d +16, 0xab72a161 +17, 0xddc2e29f +18, 0x7ea29ab4 +19, 0x80d141ba +20, 0xb1c7edf1 +21, 0x44d29203 +22, 0xe224d98 +23, 0x5b3e9d26 +24, 0x14fd567c +25, 0x27d98c96 +26, 0x838779fc +27, 0x92a138a +28, 0x5d08965b +29, 0x531e0ad6 +30, 0x984ee8f4 +31, 0x1ed78539 +32, 0x32bd6d8d +33, 0xc37c8516 +34, 0x9aef5c6b +35, 0x3aacd139 +36, 0xd96ed154 +37, 0x489cd1ed +38, 0x2cba4b3b +39, 0x76c6ae72 +40, 0x2dae02b9 +41, 0x52ac5fd6 +42, 0xc2b5e265 +43, 0x630e6a28 +44, 0x3f560d5d +45, 0x9315bdf3 +46, 0xf1055aba +47, 0x840e42c6 +48, 0xf2099c6b +49, 0x15ff7696 +50, 0x7948d146 +51, 0x97342961 +52, 0x7a7a21c +53, 0xc66f4fb1 +54, 0x23c4103e +55, 0xd7321f98 +56, 0xeb7efb75 +57, 0xe02490b5 +58, 0x2aa02de +59, 0x8bee0bf7 +60, 0xfc2da059 +61, 0xae835034 +62, 0x678f2075 +63, 0x6d03094b +64, 0x56455e05 +65, 0x18b32373 +66, 0x8ff0356b +67, 0x1fe442fb +68, 0x3f1ab6c3 +69, 0xb6fd21b +70, 0xfc310eb2 +71, 0xb19e9a4d +72, 0x17ddee72 +73, 0xfd534251 +74, 0x9e500564 +75, 0x9013a036 +76, 0xcf08f118 +77, 0x6b6d5969 +78, 0x3ccf1977 +79, 0x7cc11497 +80, 0x651c6ac9 +81, 0x4d6b104b +82, 0x9a28314e +83, 0x14c237be +84, 0x9cfc8d52 +85, 0x2947fad5 +86, 0xd71eff49 +87, 0x5188730e +88, 0x4b894614 +89, 0xf4fa2a34 +90, 0x42f7cc69 +91, 0x4089c9e8 +92, 0xbf0bbfe4 +93, 0x3cea65c +94, 0xc6221207 +95, 0x1bb71a8f +96, 0x54843fe7 +97, 0xbc59de4c +98, 0x79c6ee64 +99, 0x14e57a26 +100, 0x68d88fe +101, 0x2b86ef64 +102, 0x8ffff3c1 +103, 0x5bdd573f +104, 0x85671813 +105, 0xefe32ca2 +106, 0x105ded1e +107, 0x90ca2769 +108, 0xb33963ac +109, 0x363fbbc3 +110, 0x3b3763ae +111, 0x1d50ab88 +112, 0xc9ec01eb +113, 0xc8bbeada +114, 0x5d704692 +115, 0x5fd9e40 +116, 0xe61c125 +117, 0x2fe05792 +118, 0xda8afb72 +119, 0x4cbaa653 +120, 0xdd2243df +121, 0x896fd3f5 +122, 0x5bc23db +123, 0xa1c4e807 +124, 0x57d1a24d +125, 0x66503ddc +126, 0xcf7c0838 +127, 0x19e034fc +128, 0x66807450 +129, 0xfc219b3b +130, 0xe8a843e7 +131, 0x9ce61f08 +132, 0x92b950d6 +133, 0xce955ec4 +134, 0xda0d1f0d +135, 0x960c6250 +136, 0x39552432 +137, 0xde845e84 +138, 0xff3b4b11 +139, 0x5d918e6f +140, 0xbb930df2 +141, 0x7cfb0993 +142, 0x5400e1e9 +143, 0x3bfa0954 +144, 0x7e2605fb +145, 0x11941591 +146, 0x887e6994 +147, 0xdc8bed45 +148, 0x45b3fb50 +149, 0xfbdf8358 +150, 0x41507468 +151, 0x34c87166 +152, 0x17f64d77 +153, 0x3bbaf4f8 +154, 0x4f26f37e +155, 0x4a56ebf2 +156, 0x81100f1 +157, 0x96d94eae +158, 0xca88fda5 +159, 0x2eef3a60 +160, 0x952afbd3 +161, 0x2bec88c7 +162, 0x52335c4b +163, 0x8296db8e +164, 0x4da7d00a +165, 0xc00ac899 +166, 0xadff8c72 +167, 0xbecf26cf +168, 0x8835c83c +169, 0x1d13c804 +170, 0xaa940ddc +171, 0x68222cfe +172, 0x4569c0e1 +173, 0x29077976 +174, 0x32d4a5af +175, 0xd31fcdef +176, 0xdc60682b +177, 0x7c95c368 +178, 0x75a70213 +179, 0x43021751 +180, 0x5e52e0a6 +181, 0xf7e190b5 +182, 0xee3e4bb +183, 0x2fe3b150 +184, 0xcf419c07 +185, 0x478a4570 +186, 0xe5c3ea50 +187, 0x417f30a8 +188, 0xf0cfdaa0 +189, 0xd1f7f738 +190, 0x2c70fc23 +191, 0x54fc89f9 +192, 0x444dcf01 +193, 0xec2a002d +194, 0xef0c3a88 +195, 0xde21be9 +196, 0x88ab3296 +197, 0x3028897c +198, 0x264b200b +199, 0xd8ae0706 +200, 0x9eef901a +201, 0xbd1b96e0 +202, 0xea71366c +203, 0x1465b694 +204, 0x5a794650 +205, 0x83df52d4 +206, 0x8262413d +207, 0x5bc148c0 +208, 0xe0ecd80c +209, 0x40649571 +210, 0xb4d2ee5f +211, 0xedfd7d09 +212, 0xa082e25f +213, 0xc62992d1 +214, 0xbc7e65ee +215, 0x5499cf8a +216, 0xac28f775 +217, 0x649840fb +218, 0xd4c54805 +219, 0x1d166ba6 +220, 0xbeb1171f +221, 0x45b66703 +222, 0x78c03349 +223, 0x38d2a6ff +224, 0x935cae8b +225, 0x1d07dc3f +226, 0x6c1ed365 +227, 0x579fc585 +228, 0x1320c0ec +229, 0x632757eb +230, 0xd265a397 +231, 0x70e9b6c2 +232, 0xc81e322c +233, 0xa27153cf +234, 0x2118ba19 +235, 0x514ec400 +236, 0x2bd0ecd6 +237, 0xc3e7dae3 +238, 0xfa39355e +239, 0x48f23cc1 +240, 0xbcf75948 +241, 0x53ccc70c +242, 0x75346423 +243, 0x951181e0 +244, 0x348e90df +245, 0x14365d7f +246, 0xfbc95d7a +247, 0xdc98a9e6 +248, 0xed202df7 +249, 0xa59ec913 +250, 0x6b6e9ae2 +251, 0x1697f265 +252, 0x15d322d0 +253, 0xa2e7ee0a +254, 0x88860b7e +255, 0x455d8b9d +256, 0x2f5c59cb +257, 0xac49c9f1 +258, 0xa6a6a039 +259, 0xc057f56b +260, 0xf1ff1208 +261, 0x5eb8dc9d +262, 0xe6702509 +263, 0xe238b0ed +264, 0x5ae32e3d +265, 0xa88ebbdf +266, 0xef885ae7 +267, 0xafa6d49b +268, 0xc94499e0 +269, 0x1a196325 +270, 0x88938da3 +271, 0x14f4345 +272, 0xd8e33637 +273, 0xa3551bd5 +274, 0x73fe35c7 +275, 0x9561e94b +276, 0xd673bf68 +277, 0x16134872 +278, 0x68c42f9f +279, 0xdf7574c8 +280, 0x8809bab9 +281, 0x1432cf69 +282, 0xafb66bf1 +283, 0xc184aa7b +284, 0xedbf2007 +285, 0xbd420ce1 +286, 0x761033a0 +287, 0xff7e351f +288, 0xd6c3780e +289, 0x5844416f +290, 0xc6c0ee1c +291, 0xd2e147db +292, 0x92ac601a +293, 0x393e846b +294, 0x18196cca +295, 0x54a22be +296, 0x32bab1c4 +297, 0x60365183 +298, 0x64fa342 +299, 0xca24a493 +300, 0xd8cc8b83 +301, 0x3faf102b +302, 0x6e09bb58 +303, 0x812f0ea +304, 0x592c95d8 +305, 0xe45ea4c5 +306, 0x23aebf83 +307, 0xbd9691d4 +308, 0xf47b4baa +309, 0x4ac7b487 +310, 0xcce18803 +311, 0x3377556e +312, 0x3ff8e6b6 +313, 0x99d22063 +314, 0x23250bec +315, 0x4e1f9861 +316, 0x8554249b +317, 0x8635c2fc +318, 0xe8426e8a +319, 0x966c29d8 +320, 0x270b6082 +321, 0x3180a8a1 +322, 0xe7e1668b +323, 0x7f868dc +324, 0xcf4c17cf +325, 0xe31de4d1 +326, 0xc8c8aff4 +327, 0xae8db704 +328, 0x3c928cc2 +329, 0xe12cd48 +330, 0xb33ecd04 +331, 0xb93d7cbe +332, 0x49c69d6a +333, 0x7d3bce64 +334, 0x86bc219 +335, 0x8408233b +336, 0x44dc7479 +337, 0xdf80d538 +338, 0xf3db02c3 +339, 0xbbbd31d7 +340, 0x121281f +341, 0x7521e9a3 +342, 0x8859675a +343, 0x75aa6502 +344, 0x430ed15b +345, 0xecf0a28d +346, 0x659774fd +347, 0xd58a2311 +348, 0x512389a9 +349, 0xff65e1ff +350, 0xb6ddf222 +351, 0xe3458895 +352, 0x8b13cd6e +353, 0xd4a22870 +354, 0xe604c50c +355, 0x27f54f26 +356, 0x8f7f422f +357, 0x9735b4cf +358, 0x414072b0 +359, 0x76a1c6d5 +360, 0xa2208c06 +361, 0x83cd0f61 +362, 0x6c4f7ead +363, 0x6553cf76 +364, 0xeffcf44 +365, 0x7f434a3f +366, 0x9dc364bd +367, 0x3cdf52ed +368, 0xad597594 +369, 0x9c3e211b +370, 0x6c04a33f +371, 0x885dafa6 +372, 0xbbdaca71 +373, 0x7ae5dd5c +374, 0x37675644 +375, 0x251853c6 +376, 0x130b086b +377, 0x143fa54b +378, 0x54cdc282 +379, 0x9faff5b3 +380, 0x502a5c8b +381, 0xd9524550 +382, 0xae221aa6 +383, 0x55cf759b +384, 0x24782da4 +385, 0xd715d815 +386, 0x250ea09a +387, 0x4e0744ac +388, 0x11e15814 +389, 0xabe5f9df +390, 0xc8146350 +391, 0xfba67d9b +392, 0x2b82e42f +393, 0xd4ea96fc +394, 0x5ffc179e +395, 0x1598bafe +396, 0x7fb6d662 +397, 0x1a12a0db +398, 0x450cee4a +399, 0x85f8e12 +400, 0xce71b594 +401, 0xd4bb1d19 +402, 0x968f379d +403, 0x54cc1d52 +404, 0x467e6066 +405, 0x7da5f9a9 +406, 0x70977034 +407, 0x49e65c4b +408, 0xd08570d1 +409, 0x7acdf60b +410, 0xdffa038b +411, 0x9ce14e4c +412, 0x107cbbf8 +413, 0xdd746ca0 +414, 0xc6370a46 +415, 0xe7f83312 +416, 0x373fa9ce +417, 0xd822a2c6 +418, 0x1d4efea6 +419, 0xc53dcadb +420, 0x9b4e898f +421, 0x71daa6bf +422, 0x7a0bc78b +423, 0xd7b86f50 +424, 0x1b8b3286 +425, 0xcf9425dd +426, 0xd5263220 +427, 0x4ea0b647 +428, 0xc767fe64 +429, 0xcfc5e67 +430, 0xcc6a2942 +431, 0xa51eff00 +432, 0x76092e1b +433, 0xf606e80f +434, 0x824b5e20 +435, 0xebb55e14 +436, 0x783d96a6 +437, 0x10696512 +438, 0x17ee510a +439, 0x3ab70a1f +440, 0xcce6b210 +441, 0x8f72f0fb +442, 0xf0610b41 +443, 0x83d01fb5 +444, 0x6b3de36 +445, 0xe4c2e84f +446, 0x9c43bb15 +447, 0xddf2905 +448, 0x7dd63556 +449, 0x3662ca09 +450, 0xfb81f35b +451, 0xc2c8a72a +452, 0x8e93c37 +453, 0xa93da2d4 +454, 0xa03af8f1 +455, 0x8d75159a +456, 0x15f010b0 +457, 0xa296ab06 +458, 0xe55962ba +459, 0xeae700a9 +460, 0xe388964a +461, 0x917f2bec +462, 0x1c203fea +463, 0x792a01ba +464, 0xa93a80ac +465, 0x9eb8a197 +466, 0x56c0bc73 +467, 0xb8f05799 +468, 0xf429a8c8 +469, 0xb92cee42 +470, 0xf8864ec +471, 0x62f2518a +472, 0x3a7bfa3e +473, 0x12e56e6d +474, 0xd7a18313 +475, 0x41fa3899 +476, 0xa09c4956 +477, 0xebcfd94a +478, 0xc485f90b +479, 0x4391ce40 +480, 0x742a3333 +481, 0xc932f9e5 +482, 0x75c6c263 +483, 0x80937f0 +484, 0xcf21833c +485, 0x16027520 +486, 0xd42e669f +487, 0xb0f01fb7 +488, 0xb35896f1 +489, 0x763737a9 +490, 0x1bb20209 +491, 0x3551f189 +492, 0x56bc2602 +493, 0xb6eacf4 +494, 0x42ec4d11 +495, 0x245cc68 +496, 0xc27ac43b +497, 0x9d903466 +498, 0xce3f0c05 +499, 0xb708c31c +500, 0xc0fd37eb +501, 0x95938b2c +502, 0xf20175a7 +503, 0x4a86ee9b +504, 0xbe039a58 +505, 0xd41cabe7 +506, 0x83bc99ba +507, 0x761d60e1 +508, 0x7737cc2e +509, 0x2b82fc4b +510, 0x375aa401 +511, 0xfe9597a0 +512, 0x5543806a +513, 0x44f31238 +514, 0x7df31538 +515, 0x74cfa770 +516, 0x8755d881 +517, 0x1fde665a +518, 0xda8bf315 +519, 0x973d8e95 +520, 0x72205228 +521, 0x8fe59717 +522, 0x7bb90b34 +523, 0xef6ed945 +524, 0x16fd4a38 +525, 0x5db44de1 +526, 0xf09f93b3 +527, 0xe84824cc +528, 0x945bb50e +529, 0xd0be4aa5 +530, 0x47c277c2 +531, 0xd3800c28 +532, 0xac1c33ec +533, 0xd3dacce +534, 0x811c8387 +535, 0x6761b36 +536, 0x70d3882f +537, 0xd6e62e3a +538, 0xea25daa2 +539, 0xb07f39d1 +540, 0x391d89d7 +541, 0x84b6fb5e +542, 0x3dda3fca +543, 0x229e80a4 +544, 0x3d94a4b7 +545, 0x5d3d576a +546, 0xad7818a0 +547, 0xce23b03a +548, 0x7aa2079c +549, 0x9a6be555 +550, 0x83f3b34a +551, 0x1848f9d9 +552, 0xd8fefc1c +553, 0x48e6ce48 +554, 0x52e55750 +555, 0xf41a71cf +556, 0xba08e259 +557, 0xfaf06a15 +558, 0xeaaac0fb +559, 0x34f90098 +560, 0xb1dfffbb +561, 0x718daec2 +562, 0xab4dda21 +563, 0xd27cc1ee +564, 0x4aafbc4c +565, 0x356dfb4f +566, 0x83fcdfd6 +567, 0x8f0bcde0 +568, 0x4363f844 +569, 0xadc0f4d5 +570, 0x3bde994e +571, 0x3884d452 +572, 0x21876b4a +573, 0x9c985398 +574, 0xca55a226 +575, 0x3a88c583 +576, 0x916dc33c +577, 0x8f67d1d7 +578, 0x3b26a667 +579, 0xe4ddeb4b +580, 0x1a9d8c33 +581, 0x81c9b74f +582, 0x9ed1e9df +583, 0x6e61aecf +584, 0x95e95a5d +585, 0x68864ff5 +586, 0xb8fa5b9 +587, 0x72b1b3de +588, 0x5e18a86b +589, 0xd7f2337d +590, 0xd70e0925 +591, 0xb573a4c1 +592, 0xc77b3f8a +593, 0x389b20de +594, 0x16cf6afb +595, 0xa39bd275 +596, 0xf491cf01 +597, 0x6f88a802 +598, 0x8510af05 +599, 0xe7cd549a +600, 0x8603179a +601, 0xef43f191 +602, 0xf9b64c60 +603, 0xb00254a7 +604, 0xd7c06a2d +605, 0x17e9380b +606, 0x529e727b +607, 0xaaa8fe0a +608, 0xfb64ff4c +609, 0xcd75af26 +610, 0xfb717c87 +611, 0xa0789899 +612, 0x10391ec9 +613, 0x7e9b40b3 +614, 0x18536554 +615, 0x728c05f7 +616, 0x787dca98 +617, 0xad948d1 +618, 0x44c18def +619, 0x3303f2ec +620, 0xa15acb5 +621, 0xb58d38f4 +622, 0xfe041ef8 +623, 0xd151a956 +624, 0x7b9168e8 +625, 0x5ebeca06 +626, 0x90fe95df +627, 0xf76875aa +628, 0xb2e0d664 +629, 0x2e3253b7 +630, 0x68e34469 +631, 0x1f0c2d89 +632, 0x13a34ac2 +633, 0x5ffeb841 +634, 0xe381e91c +635, 0xb8549a92 +636, 0x3f35cf1 +637, 0xda0f9dcb +638, 0xdd9828a6 +639, 0xe1428f29 +640, 0xf4db80b5 +641, 0xdac30af5 +642, 0x1af1dd17 +643, 0x9a540254 +644, 0xcab68a38 +645, 0x33560361 +646, 0x2fbf3886 +647, 0xbc785923 +648, 0xe081cd10 +649, 0x8e473356 +650, 0xd102c357 +651, 0xeea4fe48 +652, 0x248d3453 +653, 0x1da79ac +654, 0x815a65ff +655, 0x27693e76 +656, 0xb7d5af40 +657, 0x6d245d30 +658, 0x9e06fa8f +659, 0xb0570dcb +660, 0x469f0005 +661, 0x3e0ca132 +662, 0xd89bbf3 +663, 0xd61ccd47 +664, 0x6383878 +665, 0x62b5956 +666, 0x4dc83675 +667, 0x93fd8492 +668, 0x5a0091f5 +669, 0xc9f9bc3 +670, 0xa26e7778 +671, 0xeabf2d01 +672, 0xe612dc06 +673, 0x85d89ff9 +674, 0xd1763179 +675, 0xcb88947b +676, 0x9e8757a5 +677, 0xe100e85c +678, 0x904166eb +679, 0x4996243d +680, 0x4038e1cb +681, 0x2be2c63d +682, 0x77017e81 +683, 0x3b1f556b +684, 0x1c785c77 +685, 0x6869b8bd +686, 0xe1217ed4 +687, 0x4012ab2f +688, 0xc06c0d8e +689, 0x2122eb68 +690, 0xad1783fd +691, 0x5f0c80e3 +692, 0x828f7efa +693, 0x29328399 +694, 0xeadf1087 +695, 0x85dc0037 +696, 0x9691ef26 +697, 0xc0947a53 +698, 0x2a178d2a +699, 0x2a2c7e8f +700, 0x90378380 +701, 0xaad8d326 +702, 0x9cf1c3c8 +703, 0x84eccd44 +704, 0x79e61808 +705, 0x8b3f454e +706, 0x209e6e1 +707, 0x51f88378 +708, 0xc210226f +709, 0xd982adb5 +710, 0x55d44a31 +711, 0x9817d443 +712, 0xa328c626 +713, 0x13455966 +714, 0xb8f681d3 +715, 0x2a3c713b +716, 0xc186959b +717, 0x814a74b0 +718, 0xed7bc90 +719, 0xa88d3d6d +720, 0x88a9f561 +721, 0x73aa1c0a +722, 0xdfeff404 +723, 0xec037e4b +724, 0xa5c209f0 +725, 0xb3a223b4 +726, 0x24ce3709 +727, 0x3184c790 +728, 0xa1398c62 +729, 0x2f92034e +730, 0xbb37a79a +731, 0x605287b4 +732, 0x8faa772c +733, 0x6ce56c1d +734, 0xc035fb4c +735, 0x7cf5b316 +736, 0x6502645 +737, 0xa283d810 +738, 0x778bc2f1 +739, 0xfdf99313 +740, 0x1f513265 +741, 0xbd3837e2 +742, 0x9b84a9a +743, 0x2139ce91 +744, 0x61a8e890 +745, 0xf9ff12db +746, 0xb43d2ea7 +747, 0x88532e61 +748, 0x175a6655 +749, 0x7a6c4f72 +750, 0x6dafc1b7 +751, 0x449b1459 +752, 0x514f654f +753, 0x9a6731e2 +754, 0x8632da43 +755, 0xc81b0422 +756, 0x81fe9005 +757, 0x15b79618 +758, 0xb5fa629f +759, 0x987a474f +760, 0x1c74f54e +761, 0xf9743232 +762, 0xec4b55f +763, 0x87d761e5 +764, 0xd1ad78b7 +765, 0x453d9350 +766, 0xc7a7d85 +767, 0xb2576ff5 +768, 0xcdde49b7 +769, 0x8e1f763e +770, 0x1338583e +771, 0xfd65b9dc +772, 0x4f19c4f4 +773, 0x3a52d73d +774, 0xd3509c4c +775, 0xda24fe31 +776, 0xe2de56ba +777, 0x2db5e540 +778, 0x23172734 +779, 0x4db572f +780, 0xeb941718 +781, 0x84c2649a +782, 0x3b1e5b6a +783, 0x4c9c61b9 +784, 0x3bccd11 +785, 0xb4d7b78e +786, 0x48580ae5 +787, 0xd273ab68 +788, 0x25c11615 +789, 0x470b53f6 +790, 0x329c2068 +791, 0x1693721b +792, 0xf8c9aacf +793, 0x4c3d5693 +794, 0xd778284e +795, 0xae1cb24f +796, 0x3c11d1b3 +797, 0xddd2b0c0 +798, 0x90269fa7 +799, 0x5666e0a2 +800, 0xf9f195a4 +801, 0x61d78eb2 +802, 0xada5a7c0 +803, 0xaa272fbe +804, 0xba3bae2f +805, 0xd0b70fc2 +806, 0x529f32b +807, 0xda7a3e21 +808, 0x9a776a20 +809, 0xb21f9635 +810, 0xb3acc14e +811, 0xac55f56 +812, 0x29dccf41 +813, 0x32dabdb3 +814, 0xaa032f58 +815, 0xfa406af4 +816, 0xce3c415d +817, 0xb44fb4d9 +818, 0x32248d1c +819, 0x680c6440 +820, 0xae2337b +821, 0x294cb597 +822, 0x5bca48fe +823, 0xaef19f40 +824, 0xad60406 +825, 0x4781f090 +826, 0xfd691ffc +827, 0xb6568268 +828, 0xa56c72cb +829, 0xf8a9e0fc +830, 0x9af4fd02 +831, 0x2cd30932 +832, 0x776cefd7 +833, 0xe31f476e +834, 0x6d94a437 +835, 0xb3cab598 +836, 0xf582d13f +837, 0x3bf8759d +838, 0xc3777dc +839, 0x5e425ea8 +840, 0x1c7ff4ed +841, 0x1c2e97d1 +842, 0xc062d2b4 +843, 0x46dc80e0 +844, 0xbcdb47e6 +845, 0x32282fe0 +846, 0xaba89063 +847, 0x5e94e9bb +848, 0x3e667f78 +849, 0xea6eb21a +850, 0xe56e54e8 +851, 0xa0383510 +852, 0x6768fe2b +853, 0xb53ac3e0 +854, 0x779569a0 +855, 0xeca83c6a +856, 0x24db4d2d +857, 0x4585f696 +858, 0xf84748b2 +859, 0xf6a4dd5b +860, 0x31fb524d +861, 0x67ab39fe +862, 0x5882a899 +863, 0x9a05fcf6 +864, 0x712b5674 +865, 0xe8c6958f +866, 0x4b448bb3 +867, 0x530b9abf +868, 0xb491f491 +869, 0x98352c62 +870, 0x2d0a50e3 +871, 0xeb4384da +872, 0x36246f07 +873, 0xcbc5c1a +874, 0xae24031d +875, 0x44d11ed6 +876, 0xf07f1608 +877, 0xf296aadd +878, 0x3bcfe3be +879, 0x8fa1e7df +880, 0xfd317a6e +881, 0xe4975c44 +882, 0x15205892 +883, 0xa762d4df +884, 0xf1167365 +885, 0x6811cc00 +886, 0x8315f23 +887, 0xe045b4b1 +888, 0xa8496414 +889, 0xbed313ae +890, 0xcdae3ddb +891, 0xa9c22c9 +892, 0x275fab1a +893, 0xedd65fa +894, 0x4c188229 +895, 0x63a83e58 +896, 0x18aa9207 +897, 0xa41f2e78 +898, 0xd9f63653 +899, 0xbe2be73b +900, 0xa3364d39 +901, 0x896d5428 +902, 0xc737539e +903, 0x745a78c6 +904, 0xf0b2b042 +905, 0x510773b4 +906, 0x92ad8e37 +907, 0x27f2f8c4 +908, 0x23704cc8 +909, 0x3d95a77f +910, 0xf08587a4 +911, 0xbd696a25 +912, 0x948924f3 +913, 0x8cddb634 +914, 0xcd2a4910 +915, 0x8e0e300e +916, 0x83815a9b +917, 0x67383510 +918, 0x3c18f0d0 +919, 0xc7a7bccc +920, 0x7cc2d3a2 +921, 0x52eb2eeb +922, 0xe4a257e5 +923, 0xec76160e +924, 0x63f9ad68 +925, 0x36d0bbbf +926, 0x957bc4e4 +927, 0xc9ed90ff +928, 0x4cb6059d +929, 0x2f86eca1 +930, 0x3e3665a3 +931, 0x9b7eb6f4 +932, 0x492e7e18 +933, 0xa098aa51 +934, 0x7eb568b2 +935, 0x3fd639ba +936, 0x7bebcf1 +937, 0x99c844ad +938, 0x43cb5ec7 +939, 0x8dfbbef5 +940, 0x5be413ff +941, 0xd93b976d +942, 0xc1c7a86d +943, 0x1f0e93d0 +944, 0x498204a2 +945, 0xe8fe832a +946, 0x2236bd7 +947, 0x89953769 +948, 0x2acc3491 +949, 0x2c4f22c6 +950, 0xd7996277 +951, 0x3bcdc349 +952, 0xfc286630 +953, 0x5f8909fd +954, 0x242677c0 +955, 0x4cb34104 +956, 0xa6ff8100 +957, 0x39ea47ec +958, 0x9bd54140 +959, 0x7502ffe8 +960, 0x7ebef8ae +961, 0x1ed8abe4 +962, 0xfaba8450 +963, 0xc197b65f +964, 0x19431455 +965, 0xe229c176 +966, 0xeb2967da +967, 0xe0c5dc05 +968, 0xa84e3227 +969, 0x10dd9e0f +970, 0xbdb70b02 +971, 0xce24808a +972, 0x423edab8 +973, 0x194caf71 +974, 0x144f150d +975, 0xf811c2d2 +976, 0xc224ee85 +977, 0x2b217a5b +978, 0xf78a5a79 +979, 0x6554a4b1 +980, 0x769582df +981, 0xf4b2cf93 +982, 0x89648483 +983, 0xb3283a3e +984, 0x82b895db +985, 0x79388ef0 +986, 0x54bc42a6 +987, 0xc4dd39d9 +988, 0x45b33b7d +989, 0x8703b2c1 +990, 0x1cc94806 +991, 0xe0f43e49 +992, 0xcaa7b6bc +993, 0x4f88e9af +994, 0x1477cce5 +995, 0x347dd115 +996, 0x36e335fa +997, 0xb93c9a31 +998, 0xaac3a175 +999, 0x68a19647 diff --git a/venv/Lib/site-packages/numpy/random/tests/data/mt19937-testset-2.csv b/venv/Lib/site-packages/numpy/random/tests/data/mt19937-testset-2.csv new file mode 100644 index 0000000..cdb8e47 --- /dev/null +++ b/venv/Lib/site-packages/numpy/random/tests/data/mt19937-testset-2.csv @@ -0,0 +1,1001 @@ +seed, 0x0 +0, 0x7ab4ea94 +1, 0x9b561119 +2, 0x4957d02e +3, 0x7dd3fdc2 +4, 0x5affe54 +5, 0x5a01741c +6, 0x8b9e8c1f +7, 0xda5bf11a +8, 0x509226 +9, 0x64e2ea17 +10, 0x82c6dab5 +11, 0xe4302515 +12, 0x8198b873 +13, 0xc3ec9a82 +14, 0x829dff28 +15, 0x5278e44f +16, 0x994a7d2c +17, 0xf1c89398 +18, 0xaf2fddec +19, 0x22abc6ee +20, 0x963dbd43 +21, 0xc29edffb +22, 0x41c1ce07 +23, 0x9c90034d +24, 0x1f17a796 +25, 0x3833caa8 +26, 0xb8795528 +27, 0xebc595a2 +28, 0xf8f5b5dd +29, 0xc2881f72 +30, 0x18e5d3f0 +31, 0x9b19ac7a +32, 0xb9992436 +33, 0xc00052b3 +34, 0xb63f4475 +35, 0x962642d9 +36, 0x63506c10 +37, 0x2be6b127 +38, 0x569bdbc6 +39, 0x7f185e01 +40, 0xebb55f53 +41, 0x1c30198c +42, 0x7c8d75c6 +43, 0xd3f2186b +44, 0xaca5b9b1 +45, 0xbc49ff45 +46, 0xc4a802af +47, 0x2cecd86f +48, 0x8e0da529 +49, 0x1f22b00e +50, 0x4559ea80 +51, 0x60f587d8 +52, 0x7c7460e9 +53, 0x67be0a4a +54, 0x987a0183 +55, 0x7bd30f1 +56, 0xab18c4ac +57, 0xffdbfb64 +58, 0x9ea917f9 +59, 0x1239dab7 +60, 0x38efabeb +61, 0x5da91888 +62, 0x8f49ed62 +63, 0x83f60b1e +64, 0x5950a3fc +65, 0xd8911104 +66, 0x19e8859e +67, 0x1a4d89ec +68, 0x968ca180 +69, 0x9e1b6da3 +70, 0x3d99c2c +71, 0x55f76289 +72, 0x8fa28b9e +73, 0x9fe01d33 +74, 0xdade4e38 +75, 0x1ea04290 +76, 0xa7263313 +77, 0xaafc762e +78, 0x460476d6 +79, 0x31226e12 +80, 0x451d3f05 +81, 0xd0d2764b +82, 0xd06e1ab3 +83, 0x1394e3f4 +84, 0x2fc04ea3 +85, 0x5b8401c +86, 0xebd6c929 +87, 0xe881687c +88, 0x94bdd66a +89, 0xabf85983 +90, 0x223ad12d +91, 0x2aaeeaa3 +92, 0x1f704934 +93, 0x2db2efb6 +94, 0xf49b8dfb +95, 0x5bdbbb9d +96, 0xba0cd0db +97, 0x4ec4674e +98, 0xad0129e +99, 0x7a66129b +100, 0x50d12c5e +101, 0x85b1d335 +102, 0x3efda58a +103, 0xecd886fb +104, 0x8ecadd3d +105, 0x60ebac0f +106, 0x5e10fe79 +107, 0xa84f7e5d +108, 0x43931288 +109, 0xfacf448 +110, 0x4ee01997 +111, 0xcdc0a651 +112, 0x33c87037 +113, 0x8b50fc03 +114, 0xf52aad34 +115, 0xda6cd856 +116, 0x7585bea0 +117, 0xe947c762 +118, 0x4ddff5d8 +119, 0xe0e79b3b +120, 0xb804cf09 +121, 0x84765c44 +122, 0x3ff666b4 +123, 0xe31621ad +124, 0x816f2236 +125, 0x228176bc +126, 0xfdc14904 +127, 0x635f5077 +128, 0x6981a817 +129, 0xfd9a0300 +130, 0xd3fa8a24 +131, 0xd67c1a77 +132, 0x903fe97a +133, 0xf7c4a4d5 +134, 0x109f2058 +135, 0x48ab87fe +136, 0xfd6f1928 +137, 0x707e9452 +138, 0xf327db9e +139, 0x7b80d76d +140, 0xfb6ba193 +141, 0x454a1ad0 +142, 0xe20b51e +143, 0xb774d085 +144, 0x6b1ed574 +145, 0xb1e77de4 +146, 0xe2a83b37 +147, 0x33d3176f +148, 0x2f0ca0fc +149, 0x17f51e2 +150, 0x7c1fbf55 +151, 0xf09e9cd0 +152, 0xe3d9bacd +153, 0x4244db0a +154, 0x876c09fc +155, 0x9db4fc2f +156, 0xd3771d60 +157, 0x25fc6a75 +158, 0xb309915c +159, 0xc50ee027 +160, 0xaa5b7b38 +161, 0x4c650ded +162, 0x1acb2879 +163, 0x50db5887 +164, 0x90054847 +165, 0xfef23e5b +166, 0x2dd7b7d5 +167, 0x990b8c2e +168, 0x6001a601 +169, 0xb5d314c4 +170, 0xfbfb7bf9 +171, 0x1aba997d +172, 0x814e7304 +173, 0x989d956a +174, 0x86d5a29c +175, 0x70a9fa08 +176, 0xc4ccba87 +177, 0x7e9cb366 +178, 0xee18eb0a +179, 0x44f5be58 +180, 0x91d4af2d +181, 0x5ab6e593 +182, 0x9fd6bb4d +183, 0x85894ce +184, 0x728a2401 +185, 0xf006f6d4 +186, 0xd782741e +187, 0x842cd5bd +188, 0xfb5883aa +189, 0x7e5a471 +190, 0x83ff6965 +191, 0xc9675c6b +192, 0xb6ced3c7 +193, 0x3de6425b +194, 0x25e14db4 +195, 0x69ca3dec +196, 0x81342d13 +197, 0xd7cd8417 +198, 0x88d15e69 +199, 0xefba17c9 +200, 0x43d595e6 +201, 0x89d4cf25 +202, 0x7cae9b9b +203, 0x2242c621 +204, 0x27fc3598 +205, 0x467b1d84 +206, 0xe84d4622 +207, 0xa26bf980 +208, 0x80411010 +209, 0xe2c2bfea +210, 0xbc6ca25a +211, 0x3ddb592a +212, 0xdd46eb9e +213, 0xdfe8f657 +214, 0x2cedc974 +215, 0xf0dc546b +216, 0xd46be68f +217, 0x26d8a5aa +218, 0x76e96ba3 +219, 0x7d5b5353 +220, 0xf532237c +221, 0x6478b79 +222, 0x9b81a5e5 +223, 0x5fc68e5c +224, 0x68436e70 +225, 0x2a0043f9 +226, 0x108d523c +227, 0x7a4c32a3 +228, 0x9c84c742 +229, 0x6f813dae +230, 0xfcc5bbcc +231, 0x215b6f3a +232, 0x84cb321d +233, 0x7913a248 +234, 0xb1e6b585 +235, 0x49376b31 +236, 0x1dc896b0 +237, 0x347051ad +238, 0x5524c042 +239, 0xda0eef9d +240, 0xf2e73342 +241, 0xbeee2f9d +242, 0x7c702874 +243, 0x9eb3bd34 +244, 0x97b09700 +245, 0xcdbab1d4 +246, 0x4a2f6ed1 +247, 0x2047bda5 +248, 0x3ecc7005 +249, 0x8d0d5e67 +250, 0x40876fb5 +251, 0xb5fd2187 +252, 0xe915d8af +253, 0x9a2351c7 +254, 0xccc658ae +255, 0xebb1eddc +256, 0xc4a83671 +257, 0xffb2548f +258, 0xe4fe387a +259, 0x477aaab4 +260, 0x8475a4e4 +261, 0xf8823e46 +262, 0xe4130f71 +263, 0xbdb54482 +264, 0x98fe0462 +265, 0xf36b27b8 +266, 0xed7733da +267, 0x5f428afc +268, 0x43a3a21a +269, 0xf8370b55 +270, 0xfade1de1 +271, 0xd9a038ea +272, 0x3c69af23 +273, 0x24df7dd0 +274, 0xf66d9353 +275, 0x71d811be +276, 0xcc4d024b +277, 0xb8c30bf0 +278, 0x4198509d +279, 0x8b37ba36 +280, 0xa41ae29a +281, 0x8cf7799e +282, 0x5cd0136a +283, 0xa11324ef +284, 0x2f8b6d4b +285, 0x3657cf17 +286, 0x35b6873f +287, 0xee6e5bd7 +288, 0xbeeaa98 +289, 0x9ad3c581 +290, 0xe2376c3f +291, 0x738027cc +292, 0x536ac839 +293, 0xf066227 +294, 0x6c9cb0f9 +295, 0x84082ae6 +296, 0xab38ae9d +297, 0x493eade9 +298, 0xcb630b3a +299, 0x64d44250 +300, 0xe5efb557 +301, 0xea2424d9 +302, 0x11a690ba +303, 0x30a48ae4 +304, 0x58987e53 +305, 0x94ec6076 +306, 0x5d3308fa +307, 0xf1635ebb +308, 0x56a5ab90 +309, 0x2b2f2ee4 +310, 0x6f9e6483 +311, 0x8b93e327 +312, 0xa7ce140b +313, 0x4c8aa42 +314, 0x7657bb3f +315, 0xf250fd75 +316, 0x1edfcb0f +317, 0xdb42ace3 +318, 0xf8147e16 +319, 0xd1992bd +320, 0x64bb14d1 +321, 0x423e724d +322, 0x7b172f7c +323, 0x17171696 +324, 0x4acaf83b +325, 0x7a83527e +326, 0xfc980c60 +327, 0xc8b56bb +328, 0x2453f77f +329, 0x85ad1bf9 +330, 0x62a85dfe +331, 0x48238c4d +332, 0xbb3ec1eb +333, 0x4c1c039c +334, 0x1f37f571 +335, 0x98aecb63 +336, 0xc3b3ddd6 +337, 0xd22dad4 +338, 0xe49671a3 +339, 0xe3baf945 +340, 0xb9e21680 +341, 0xda562856 +342, 0xe8b88ce4 +343, 0x86f88de2 +344, 0x986faf76 +345, 0x6f0025c3 +346, 0x3fe21234 +347, 0xd8d3f729 +348, 0xc2d11c6f +349, 0xd4f9e8f +350, 0xf61a0aa +351, 0xc48bb313 +352, 0xe944e940 +353, 0xf1801b2e +354, 0x253590be +355, 0x981f069d +356, 0x891454d8 +357, 0xa4f824ad +358, 0x6dd2cc48 +359, 0x3018827e +360, 0x3fb329e6 +361, 0x65276517 +362, 0x8d2c0dd2 +363, 0xc965b48e +364, 0x85d14d90 +365, 0x5a51623c +366, 0xa9573d6a +367, 0x82d00edf +368, 0x5ed7ce07 +369, 0x1d946abc +370, 0x24fa567b +371, 0x83ef5ecc +372, 0x9001724a +373, 0xc4fe48f3 +374, 0x1e07c25c +375, 0xf4d5e65e +376, 0xb734f6e9 +377, 0x327a2df8 +378, 0x766d59b7 +379, 0x625e6b61 +380, 0xe82f32d7 +381, 0x1566c638 +382, 0x2e815871 +383, 0x606514aa +384, 0x36b7386e +385, 0xcaa8ce08 +386, 0xb453fe9c +387, 0x48574e23 +388, 0x71f0da06 +389, 0xa8a79463 +390, 0x6b590210 +391, 0x86e989db +392, 0x42899f4f +393, 0x7a654ef9 +394, 0x4c4fe932 +395, 0x77b2fd10 +396, 0xb6b4565c +397, 0xa2e537a3 +398, 0xef5a3dca +399, 0x41235ea8 +400, 0x95c90541 +401, 0x50ad32c4 +402, 0xc1b8e0a4 +403, 0x498e9aab +404, 0xffc965f1 +405, 0x72633485 +406, 0x3a731aef +407, 0x7cfddd0b +408, 0xb04d4129 +409, 0x184fc28e +410, 0x424369b0 +411, 0xf9ae13a1 +412, 0xaf357c8d +413, 0x7a19228e +414, 0xb46de2a8 +415, 0xeff2ac76 +416, 0xa6c9357b +417, 0x614f19c1 +418, 0x8ee1a53f +419, 0xbe1257b1 +420, 0xf72651fe +421, 0xd347c298 +422, 0x96dd2f23 +423, 0x5bb1d63e +424, 0x32e10887 +425, 0x36a144da +426, 0x9d70e791 +427, 0x5e535a25 +428, 0x214253da +429, 0x2e43dd40 +430, 0xfc0413f4 +431, 0x1f5ea409 +432, 0x1754c126 +433, 0xcdbeebbe +434, 0x1fb44a14 +435, 0xaec7926 +436, 0xb9d9a1e +437, 0x9e4a6577 +438, 0x8b1f04c5 +439, 0x19854e8a +440, 0x531080cd +441, 0xc0cbd73 +442, 0x20399d77 +443, 0x7d8e9ed5 +444, 0x66177598 +445, 0x4d18a5c2 +446, 0xe08ebf58 +447, 0xb1f9c87b +448, 0x66bedb10 +449, 0x26670d21 +450, 0x7a7892da +451, 0x69b69d86 +452, 0xd04f1d1c +453, 0xaf469625 +454, 0x7946b813 +455, 0x1ee596bd +456, 0x7f365d85 +457, 0x795b662b +458, 0x194ad02d +459, 0x5a9649b5 +460, 0x6085e278 +461, 0x2cf54550 +462, 0x9c77ea0b +463, 0x3c6ff8b +464, 0x2141cd34 +465, 0xb90bc671 +466, 0x35037c4b +467, 0xd04c0d76 +468, 0xc75bff8 +469, 0x8f52003b +470, 0xfad3d031 +471, 0x667024bc +472, 0xcb04ea36 +473, 0x3e03d587 +474, 0x2644d3a0 +475, 0xa8fe99ba +476, 0x2b9a55fc +477, 0x45c4d44a +478, 0xd059881 +479, 0xe07fcd20 +480, 0x4e22046c +481, 0x7c2cbf81 +482, 0xbf7f23de +483, 0x69d924c3 +484, 0xe53cd01 +485, 0x3879017c +486, 0xa590e558 +487, 0x263bc076 +488, 0x245465b1 +489, 0x449212c6 +490, 0x249dcb29 +491, 0x703d42d7 +492, 0x140eb9ec +493, 0xc86c5741 +494, 0x7992aa5b +495, 0xb8b76a91 +496, 0x771dac3d +497, 0x4ecd81e3 +498, 0xe5ac30b3 +499, 0xf4d7a5a6 +500, 0xac24b97 +501, 0x63494d78 +502, 0x627ffa89 +503, 0xfa4f330 +504, 0x8098a1aa +505, 0xcc0c61dc +506, 0x34749fa0 +507, 0x7f217822 +508, 0x418d6f15 +509, 0xa4b6e51e +510, 0x1036de68 +511, 0x1436986e +512, 0x44df961d +513, 0x368e4651 +514, 0x6a9e5d8c +515, 0x27d1597e +516, 0xa1926c62 +517, 0x8d1f2b55 +518, 0x5797eb42 +519, 0xa90f9e81 +520, 0x57547b10 +521, 0xdbbcca8e +522, 0x9edd2d86 +523, 0xbb0a7527 +524, 0x7662380c +525, 0xe7c98590 +526, 0x950fbf3f +527, 0xdc2b76b3 +528, 0x8a945102 +529, 0x3f0a1a85 +530, 0xeb215834 +531, 0xc59f2802 +532, 0xe2a4610 +533, 0x8b5a8665 +534, 0x8b2d9933 +535, 0x40a4f0bc +536, 0xaab5bc67 +537, 0x1442a69e +538, 0xdf531193 +539, 0x698d3db4 +540, 0x2d40324e +541, 0x1a25feb2 +542, 0xe8cc898f +543, 0xf12e98f5 +544, 0xc03ad34c +545, 0xf62fceff +546, 0xdd827e1e +547, 0x7d8ccb3b +548, 0xab2d6bc1 +549, 0xc323a124 +550, 0x8184a19a +551, 0xc3c4e934 +552, 0x5487424d +553, 0xd6a81a44 +554, 0x90a8689d +555, 0xe69c4c67 +556, 0xbdae02dd +557, 0x72a18a79 +558, 0x2a88e907 +559, 0x31cf4b5d +560, 0xb157772f +561, 0x206ba601 +562, 0x18529232 +563, 0x7dac90d8 +564, 0x3a5f8a09 +565, 0x9f4b64a3 +566, 0xae373af9 +567, 0x1d79447c +568, 0x2a23684b +569, 0x41fb7ba4 +570, 0x55e4bb9e +571, 0xd7619d3e +572, 0xc04e4dd8 +573, 0x8418d516 +574, 0x2b2ca585 +575, 0xfa8eedf +576, 0x5bafd977 +577, 0x31974fb0 +578, 0x9eb6697b +579, 0xc8be22f5 +580, 0x173b126a +581, 0x8809becf +582, 0x3e41efe1 +583, 0x3d6cbbb8 +584, 0x278c81d8 +585, 0xa6f08434 +586, 0xa0e6601d +587, 0x2fccd88d +588, 0x3cbc8beb +589, 0x5f65d864 +590, 0xa1ff8ddf +591, 0x609dcb7c +592, 0x4a4e1663 +593, 0xeae5531 +594, 0x962a7c85 +595, 0x1e110607 +596, 0x8c5db5d0 +597, 0xc7f2337e +598, 0xc94fcc9c +599, 0xe7f62629 +600, 0x6c9aa9f8 +601, 0x2e27fe0e +602, 0x4d0dae12 +603, 0x9eecf588 +604, 0x977ba3f2 +605, 0xed0a51af +606, 0x3f3ec633 +607, 0xc174b2ec +608, 0x590be8a9 +609, 0x4f630d18 +610, 0xf579e989 +611, 0xe2a55584 +612, 0xee11edcd +613, 0x150a4833 +614, 0xc0a0535c +615, 0xb5e00993 +616, 0xb6435700 +617, 0xa98dbff +618, 0x315716af +619, 0x94395776 +620, 0x6cbd48d9 +621, 0xab17f8fc +622, 0xa794ffb7 +623, 0x6b55e231 +624, 0x89ff5783 +625, 0x431dcb26 +626, 0x270f9bf8 +627, 0x2af1b8d0 +628, 0x881745ed +629, 0x17e1be4e +630, 0x132a0ec4 +631, 0x5712df17 +632, 0x2dfb3334 +633, 0xf5a35519 +634, 0xcafbdac6 +635, 0x73b6189d +636, 0x10107cac +637, 0x18c1045e +638, 0xbc19bbad +639, 0x8b4f05ac +640, 0x5830d038 +641, 0x468cd98a +642, 0x5b83a201 +643, 0xf0ccdd9c +644, 0xcb20c4bd +645, 0x1ff186c9 +646, 0xcdddb47f +647, 0x5c65ce6 +648, 0xb748c580 +649, 0x23b6f262 +650, 0xe2ba8e5c +651, 0x9a164a03 +652, 0x62d3322e +653, 0x918d8b43 +654, 0x45c8b49d +655, 0xce172c6e +656, 0x23febc6 +657, 0x84fdc5b7 +658, 0xe7d1fd82 +659, 0xf0ddf3a6 +660, 0x87050436 +661, 0x13d46375 +662, 0x5b191c78 +663, 0x2cbd99c0 +664, 0x7686c7f +665, 0xcff56c84 +666, 0x7f9b4486 +667, 0xefc997fe +668, 0x984d4588 +669, 0xfa44f36a +670, 0x7a5276c1 +671, 0xcfde6176 +672, 0xcacf7b1d +673, 0xcffae9a7 +674, 0xe98848d5 +675, 0xd4346001 +676, 0xa2196cac +677, 0x217f07dc +678, 0x42d5bef +679, 0x6f2e8838 +680, 0x4677a24 +681, 0x4ad9cd54 +682, 0x43df42af +683, 0x2dde417 +684, 0xaef5acb1 +685, 0xf377f4b3 +686, 0x7d870d40 +687, 0xe53df1c2 +688, 0xaeb5be50 +689, 0x7c92eac0 +690, 0x4f00838c +691, 0x91e05e84 +692, 0x23856c80 +693, 0xc4266fa6 +694, 0x912fddb +695, 0x34d42d22 +696, 0x6c02ffa +697, 0xe47d093 +698, 0x183c55b3 +699, 0xc161d142 +700, 0x3d43ff5f +701, 0xc944a36 +702, 0x27bb9fc6 +703, 0x75c91080 +704, 0x2460d0dc +705, 0xd2174558 +706, 0x68062dbf +707, 0x778e5c6e +708, 0xa4dc9a +709, 0x7a191e69 +710, 0xc084b2ba +711, 0xbb391d2 +712, 0x88849be +713, 0x69c02714 +714, 0x69d4a389 +715, 0x8f51854d +716, 0xaf10bb82 +717, 0x4d5d1c77 +718, 0x53b53109 +719, 0xa0a92aa0 +720, 0x83ecb757 +721, 0x5325752a +722, 0x114e466e +723, 0x4b3f2780 +724, 0xa7a6a39c +725, 0x5e723357 +726, 0xa6b8be9b +727, 0x157c32ff +728, 0x8b898012 +729, 0xd7ff2b1e +730, 0x69cd8444 +731, 0x6ad8030c +732, 0xa08a49ec +733, 0xfbc055d3 +734, 0xedf17e46 +735, 0xc9526200 +736, 0x3849b88a +737, 0x2746860b +738, 0xae13d0c1 +739, 0x4f15154f +740, 0xd65c3975 +741, 0x6a377278 +742, 0x54d501f7 +743, 0x81a054ea +744, 0x143592ba +745, 0x97714ad6 +746, 0x4f9926d9 +747, 0x4f7ac56d +748, 0xe87ca939 +749, 0x58b76f6f +750, 0x60901ad8 +751, 0x3e401bb6 +752, 0xa058468e +753, 0xc0bb14f6 +754, 0x2cb8f02a +755, 0x7c2cf756 +756, 0x34c31de5 +757, 0x9b243e83 +758, 0xa5c85ab4 +759, 0x2741e3b3 +760, 0x1249000e +761, 0x3fc4e72b +762, 0xa3e038a2 +763, 0x952dd92c +764, 0x2b821966 +765, 0xfa81b365 +766, 0x530919b9 +767, 0x4486d66f +768, 0xccf4f3c1 +769, 0xa8bddd1d +770, 0xcc295eb9 +771, 0xfccbe42f +772, 0x38bacd8d +773, 0x2261854f +774, 0x56068c62 +775, 0x9bdaeb8 +776, 0x555fa5b6 +777, 0x20fe615e +778, 0x49fb23d3 +779, 0xd093bad6 +780, 0x54919e86 +781, 0x7373eb24 +782, 0xfbaa7a98 +783, 0x5f62fb39 +784, 0xe03bc9ec +785, 0xa5074d41 +786, 0xa1cefb1 +787, 0x13912d74 +788, 0xf6421b8 +789, 0xfcb48812 +790, 0x8f1db50b +791, 0xc1654b87 +792, 0x948b43c2 +793, 0xf503ef77 +794, 0x117d891d +795, 0x5493ffa +796, 0x171313b1 +797, 0xa4b62e1e +798, 0x77454ea6 +799, 0xbea0aff0 +800, 0x13c36389 +801, 0xe3b60bac +802, 0xa176bed3 +803, 0x2863d428 +804, 0xe2314f46 +805, 0xa85cd3d4 +806, 0x7866e57 +807, 0x8f03f5bc +808, 0x239ae +809, 0x46f279fb +810, 0xcca00559 +811, 0xaa07a104 +812, 0x89123d08 +813, 0x2e6856ba +814, 0x43a9780d +815, 0x676cff25 +816, 0x6744b87d +817, 0xee260d4f +818, 0xb98d8b77 +819, 0x9b0ca455 +820, 0x659f6fe +821, 0x28d20d1c +822, 0x601f2657 +823, 0xdec3073e +824, 0x61263863 +825, 0x1a13435a +826, 0x27497d1e +827, 0x17a8458e +828, 0xdddc407d +829, 0x4bb2e8ac +830, 0x16b2aedb +831, 0x77ccd696 +832, 0x9d108fcd +833, 0x25ad233e +834, 0xaa9bc370 +835, 0xa873ab50 +836, 0xaf19c9d9 +837, 0x696e1e6b +838, 0x1fdc4bf4 +839, 0x4c2ebc81 +840, 0xde4929ed +841, 0xf4d0c10c +842, 0xb6595b76 +843, 0x75cbb1b3 +844, 0xbcb6de49 +845, 0xe23157fd +846, 0x5e596078 +847, 0xa69b0d29 +848, 0x2118a41 +849, 0x7088c16 +850, 0xc75e1e1 +851, 0x6a4af2d6 +852, 0xf19c6521 +853, 0xaff7b3b1 +854, 0x615295c7 +855, 0xbda3a8d7 +856, 0x5b5ca72e +857, 0xdad9d80f +858, 0xfa81c084 +859, 0xf4703fa +860, 0x3ca54540 +861, 0xa8961d51 +862, 0x53d1ecc2 +863, 0x808d83b6 +864, 0x68e8c48e +865, 0x89be2039 +866, 0x9088ea11 +867, 0xb8665d12 +868, 0x91272f9 +869, 0x53dddff2 +870, 0xb7a54ab +871, 0xd2b645ca +872, 0x99fb8590 +873, 0x5315c8e +874, 0x2a913806 +875, 0x7f15eb2b +876, 0xa7f1cc5d +877, 0xbb2ee836 +878, 0xd9fafd60 +879, 0x17448d6f +880, 0x999ec436 +881, 0x482ec606 +882, 0x9b403c0e +883, 0x569eb51b +884, 0xb275d1a6 +885, 0xadd29c31 +886, 0xb7ebdb15 +887, 0xdfef3662 +888, 0x51aba6db +889, 0x6d41946d +890, 0x77bf8896 +891, 0xcafa6fab +892, 0x976ab40f +893, 0x49a6d86b +894, 0x56639e55 +895, 0x9945b996 +896, 0x81459b50 +897, 0xbce97542 +898, 0xe397c9c9 +899, 0x247a5955 +900, 0xb72b1573 +901, 0x86306f86 +902, 0x34f65dc5 +903, 0x909360c0 +904, 0xf3f696ef +905, 0xcb9faae5 +906, 0x93daecd9 +907, 0xde1af7af +908, 0x43a1f2d +909, 0x6d75cde5 +910, 0x9e412b6 +911, 0x5673fed +912, 0x16bb511a +913, 0x35ef4cca +914, 0x4e615aca +915, 0x5cdaf47a +916, 0x26676047 +917, 0x8c199325 +918, 0x2adf0cb9 +919, 0x84f2e6fd +920, 0x5e627f64 +921, 0xb7cee354 +922, 0x542ab4a6 +923, 0xe59cd83b +924, 0x89cc3f10 +925, 0x92b0f5f +926, 0xc1328370 +927, 0x8208d9f7 +928, 0x68eb00cf +929, 0xfadd4ac4 +930, 0x2517784f +931, 0x4042b99 +932, 0x75ce0230 +933, 0x97c5a1b4 +934, 0x1a97f709 +935, 0x4c62781e +936, 0xf530a83 +937, 0x75776413 +938, 0x321c7240 +939, 0x6afe4e36 +940, 0xad00a2b4 +941, 0xbc05477d +942, 0xb0911e80 +943, 0x9935b87d +944, 0xd535eec5 +945, 0x149af45e +946, 0x786934b0 +947, 0xbc13cdac +948, 0x208bfa2e +949, 0xcf4b39cc +950, 0x6ac6c172 +951, 0xbfa9a37 +952, 0x42d28db6 +953, 0x2bf1ea63 +954, 0xbed6e677 +955, 0x50325d27 +956, 0xa79d3b8b +957, 0x52448bb1 +958, 0xefaad1bd +959, 0x833a2e54 +960, 0xd9de549a +961, 0x9f59672f +962, 0x9d5f5f16 +963, 0x1c914489 +964, 0xc08fa058 +965, 0xb188698b +966, 0xdc4672b5 +967, 0x594f720e +968, 0x56ed428f +969, 0x9b0898af +970, 0x8a64d3d5 +971, 0x773308d6 +972, 0x84d62098 +973, 0x46da7cf9 +974, 0x1114eae7 +975, 0xf9f2a092 +976, 0x5363a28 +977, 0xf2db7b3a +978, 0x102c71a9 +979, 0xe8e76aaf +980, 0x77a97b3b +981, 0x77b090d +982, 0x1099620e +983, 0xa6daaae6 +984, 0x86ff4713 +985, 0xc0ef85b8 +986, 0xf621d409 +987, 0xfd1561e2 +988, 0x4bcc687d +989, 0x596f760 +990, 0x7c8819f9 +991, 0x8cb865b8 +992, 0xadea115a +993, 0x56609348 +994, 0xb321ac14 +995, 0x1bac7db2 +996, 0x5fe6ee2 +997, 0xe9bfe072 +998, 0x15549e74 +999, 0xad8c191b diff --git a/venv/Lib/site-packages/numpy/random/tests/data/pcg64-testset-1.csv b/venv/Lib/site-packages/numpy/random/tests/data/pcg64-testset-1.csv new file mode 100644 index 0000000..0c8271f --- /dev/null +++ b/venv/Lib/site-packages/numpy/random/tests/data/pcg64-testset-1.csv @@ -0,0 +1,1001 @@ +seed, 0xdeadbeaf +0, 0x60d24054e17a0698 +1, 0xd5e79d89856e4f12 +2, 0xd254972fe64bd782 +3, 0xf1e3072a53c72571 +4, 0xd7c1d7393d4115c9 +5, 0x77b75928b763e1e2 +6, 0xee6dee05190f7909 +7, 0x15f7b1c51d7fa319 +8, 0x27e44105f26ac2d7 +9, 0xcc0d88b29e5b415 +10, 0xe07b1a90c685e361 +11, 0xd2e430240de95e38 +12, 0x3260bca9a24ca9da +13, 0x9b3cf2e92385adb7 +14, 0x30b5514548271976 +15, 0xa3a1fa16c124faf9 +16, 0xf53e17e918e45bb6 +17, 0x26f19faaeb833bfc +18, 0x95e1d605730cce1b +19, 0xa7b520c5c093c1aa +20, 0x4b68c010c9b106a3 +21, 0x25e19fe91df703f0 +22, 0x898364bb0bf593cb +23, 0x5bd6ab7dbaa125db +24, 0xd1fe47f25152045c +25, 0x3bb11919addf2409 +26, 0x26a8cb7b3f54af8 +27, 0xe6a27ee11200aa24 +28, 0x7cb585ab01e22000 +29, 0x78e60028676d2ef3 +30, 0x5c32535e5a899528 +31, 0x83e8b6f8c4a46fb3 +32, 0xe56ef7668a161246 +33, 0x36dcbc15aeb73055 +34, 0x5ea247f0bd188acb +35, 0x438b547b84601a80 +36, 0x8acda2a1273e9e3d +37, 0x2b05e30a4b40c24c +38, 0xfd87236bd13af032 +39, 0x471df211d8d985ef +40, 0x18e8a5609a793292 +41, 0x46f0951fab6dc4e3 +42, 0x6c199c4e700f6795 +43, 0xf04aa16bfb7d22cb +44, 0xd763d269fbaffc89 +45, 0x9991930cefbe5c2b +46, 0xb2a11b953f824c96 +47, 0x63fd9f52172c44b0 +48, 0x183bdad907b1d848 +49, 0xe17953cddb931c52 +50, 0x515cf16726ec205a +51, 0x88c327605150711a +52, 0xc7090dd79cbc8dc3 +53, 0xcb487cedeb00a350 +54, 0xc8abf254d87b657 +55, 0xd43cc4cbfb493d1a +56, 0x8705452e5d9ed1e +57, 0xcecd11446769cf43 +58, 0xde72156c8d65bc69 +59, 0x796a8f0f47d52ee8 +60, 0xb4c0da443917d6c3 +61, 0xe07ad7568a8e3dc3 +62, 0xc24a8da39ce6dc21 +63, 0x92b21ea80a8556eb +64, 0x572f21e531edf3af +65, 0x9b917ed56bbed198 +66, 0xe65fd8ddc5ab3d7d +67, 0xf55a80a8ec84fa18 +68, 0x18fc22e1a5227b61 +69, 0x72305dc7eeaa79d3 +70, 0x47ce58a36e7592cf +71, 0x14c6374340c0f7cc +72, 0x6f98273d4eb5a2c +73, 0x59a8702c46fe8f8a +74, 0xb67cbd8113cfe57f +75, 0xaa03c5db5f5b7690 +76, 0x3fb0f77ea4568013 +77, 0x756530990398b26e +78, 0x4c1952b2a3a6a343 +79, 0x1da15c5383074582 +80, 0xb405b21c81c274f7 +81, 0xbe664677a16788b +82, 0x9d2e37550bcee656 +83, 0x8b4589f0d9defe02 +84, 0x2935f018ee06a59 +85, 0x3834bf88be97ed11 +86, 0xa610d049cea79b6d +87, 0xd49ffc0d09a59ea9 +88, 0x4073365b76567adf +89, 0x499eefb9bb7513e2 +90, 0x74a743ee6b0138a9 +91, 0x3bf0880f2d947594 +92, 0x555d1c0498600a99 +93, 0x923b32a88ef2ffa4 +94, 0x7325411065fbedea +95, 0x9f4129ff8b79d300 +96, 0xab2b0a9b8a3785dc +97, 0x11734bdfba3a1713 +98, 0xc8333398841ba585 +99, 0xee2409cc234e6742 +100, 0xf6638e700872ecd2 +101, 0x10875300c13cd284 +102, 0x27a9bbed7c15b2d3 +103, 0x3c87f8fef31ce9bd +104, 0x92be263cd0914a95 +105, 0xa7b0f11bc742307e +106, 0x4a56f788cc1c1a3c +107, 0x4a130fa32257a48b +108, 0x5d4d9eda16e90286 +109, 0x7cc2af564844bedc +110, 0x2532867bfe7cda1a +111, 0xb1c504676611fd17 +112, 0xce8e86cfb4189aee +113, 0x99685898980d1970 +114, 0x8c3b67db23bcf1e +115, 0x73e14c93905b135f +116, 0xf0271b64ac2bd4d3 +117, 0xf4beba82f3ec1b2d +118, 0x1cdbf3ee9f210af +119, 0x2e938557c09c3ea6 +120, 0x2d314ccfa6ffd81d +121, 0x31ad47079950ade4 +122, 0x342b27547b900872 +123, 0x171b0e20b9ef1a76 +124, 0xdf10ce6318b03654 +125, 0x1d625df4aa718897 +126, 0x8712715a9f6e02ec +127, 0xb4a072da725bca3b +128, 0x19d346cb7734bd42 +129, 0xfd4281d311cb2958 +130, 0x58274c9519fc8789 +131, 0x4cacf29d885fd544 +132, 0x784b14d1c2523b80 +133, 0x2d25242131bb2373 +134, 0xcd2a5e43a7d9abf9 +135, 0x15eda3806e650ecb +136, 0xdaac5e277d764d96 +137, 0xdc5a5dd59aaa94e0 +138, 0x40d00237a46d5999 +139, 0x6205dd35a692743f +140, 0xbbd8236740361f09 +141, 0x1625c9f4e7288bf9 +142, 0xb74f12df1479e3ce +143, 0xb2d72a51b43d7131 +144, 0xf006a324b3707c83 +145, 0x28e8ab4abe7655b8 +146, 0xfb480093ad7ab55 +147, 0x3f8abd0d6ff8d272 +148, 0xc81a94177ac26bb7 +149, 0x3cdc178307751b14 +150, 0x9de84cc2b10ba025 +151, 0x3f8ab5aefcd046e2 +152, 0x43bdb894e1ee83b2 +153, 0xe288a40f3f06ac9d +154, 0xdab62a7d04b4f30f +155, 0x49f4e20295e1a805 +156, 0x3643764805e0edef +157, 0x9449954618b6b +158, 0x6c87e0d4508e0ce0 +159, 0x3a334be688a9dd7b +160, 0xb35c39228776e499 +161, 0xc4118bfff938490e +162, 0x88cbde3dcbb034b2 +163, 0xf91b287793c417c3 +164, 0x42b15f731a59f5b3 +165, 0xffa27104bbe4814d +166, 0x1b6789d138beccde +167, 0x542c2c1440d0ceb9 +168, 0x367294504d18fa0d +169, 0xf918b60e804a1b58 +170, 0xd390964e33a9d0e3 +171, 0x23bb1be7c4030fe8 +172, 0x9731054d039a8afb +173, 0x1a6205026b9d139b +174, 0x2fa13b318254a07e +175, 0x69571de7d8520626 +176, 0x641a13d7c03332b7 +177, 0x76a6237818f7a441 +178, 0x4e77860d0c660d81 +179, 0x4441448a1c1cbdb2 +180, 0xccd7783a042046e5 +181, 0xf620d8e0805e3200 +182, 0x7de02971367fdd0c +183, 0x539c263c5914cab1 +184, 0x9c3b9ba1a87bbf08 +185, 0x6d95baa34cda215f +186, 0x2db3f83ace0bac5f +187, 0x7f5af1da2dc670a4 +188, 0xfcc098d16c891bfb +189, 0x81a33df1d7a5ab12 +190, 0x767b0f863c8e9882 +191, 0x7a92983830de483d +192, 0xfa7598c37a79ac25 +193, 0xb89b3ca42ce03053 +194, 0x457a542b8efed4f7 +195, 0x571b7737fd0eeda7 +196, 0xa0f59e524485c0a +197, 0x82dca766b7901efd +198, 0xa68243caf6a3bd5d +199, 0x1bac981c6c740e5e +200, 0xbcd51bedf9103e44 +201, 0x4e197efd3ae5a7bf +202, 0x523568efd782268b +203, 0x5ec4ef1191fef09 +204, 0xed751ed5e31c9ab +205, 0x44eac24de03e1b29 +206, 0x9237d57c011d3fb3 +207, 0xa8c6da0f7692f235 +208, 0x9f9eb6bc15d6cac7 +209, 0x34bb8e0c93427aad +210, 0x115febd738eaac4a +211, 0xa439991ed139d27a +212, 0x45c7c2633d8710a2 +213, 0x48b7475f3405a3ce +214, 0x80158497c77bd00b +215, 0x935c316a5b1657cb +216, 0x59c5d54440e9695e +217, 0x337c78c5b3d0ede2 +218, 0x8c46bb956b93790d +219, 0xbf1dd03e471d71c5 +220, 0x2d375e90a4bef583 +221, 0xd0365428331b3790 +222, 0xfcd3969ac827ecd4 +223, 0x392fb6c580498410 +224, 0x6d6db4ceab5ea6c0 +225, 0x9bf84f1972e24786 +226, 0x798dfd820959dcc5 +227, 0x2e425095e65e8bfb +228, 0x8c1aa11536b1c9c3 +229, 0xd28e2ef9b12f6f74 +230, 0x86583bc98c8f78d2 +231, 0x489877530e3f93e7 +232, 0xb1d9430631104a15 +233, 0x1814f6098e6263bd +234, 0x8e2658a4e0d4cd53 +235, 0x5afe20e2531cdb2a +236, 0x30d02f7c4755c9bf +237, 0xe1e217cda16ed2d2 +238, 0xccb4913a42e3b791 +239, 0xfff21363ac183226 +240, 0xe788690bbda147a7 +241, 0x76905cf5917bfc6a +242, 0x2a8fa58f7916f52c +243, 0xf903c0cc0357815a +244, 0x15d20f243a4998d2 +245, 0x5b7decee5a86ea44 +246, 0x114f7fc421211185 +247, 0x328eb21715764c50 +248, 0xaffaa3f45c0678fd +249, 0x2579e6ef50378393 +250, 0x7610ab7743c19795 +251, 0xf9923d2bd101b197 +252, 0x57e42e7a62ba7e53 +253, 0x9f1dc217b4f02901 +254, 0x88a9ebd86509b234 +255, 0x867fc926aecc8591 +256, 0xaf22c1bfef04c718 +257, 0x39f701f0313f4288 +258, 0x6171ad397e6faab2 +259, 0x239bb5b9abdec4fc +260, 0xd9a591e25dd01c6e +261, 0x826dc4a75b628e49 +262, 0xf112b152c408f47 +263, 0x6843a06110f86c0 +264, 0x965e56a7185c1332 +265, 0x8d84492edbc71710 +266, 0xeee8ec111cfd1319 +267, 0xf2858e94ad98e458 +268, 0xbc9589fdf5f3a97e +269, 0xaf0ceef3bc375130 +270, 0x48f4aaf13fa75c1e +271, 0x111e9db47bee758f +272, 0xea3171df130164ba +273, 0x2a7bbe30bf827ab6 +274, 0xc516c3fdbf758c35 +275, 0xec55097754b04be5 +276, 0x374a997d52b6d3e6 +277, 0x487df5456085ffbc +278, 0x528883b84df8eafe +279, 0x805f77ab5ba26f86 +280, 0x8eb81477dc04f213 +281, 0x471ea08ec6794d72 +282, 0x69d3667ecc4d2176 +283, 0x98b7b6e295548a66 +284, 0x3877713c173f8f2 +285, 0xa00542570d0e8de3 +286, 0xf534b1bfa4033e50 +287, 0x7e1fedeac8bf6b26 +288, 0x8043f37c89628af4 +289, 0x1dd7039ec295e86d +290, 0xce9c05b763a40cc4 +291, 0x246926481e61028f +292, 0xb7cb0f1babf5893b +293, 0xefe6b777f37fc63e +294, 0xebbcabb4cb35cdcb +295, 0x39fa63cd711eeea9 +296, 0xad5d3ba7aaf30c8d +297, 0x8e9e78fe46021990 +298, 0xc7eaef6e7d5a3c62 +299, 0xefccdd5495d3f386 +300, 0x2179557ee8cfc76a +301, 0x88a77f621f0885ce +302, 0xafda62674543d90c +303, 0xb8e6fbe2e13e56c0 +304, 0x8bfbbe26a14f9b1a +305, 0x1404f59f5851f8c3 +306, 0x1140c53a0489566d +307, 0x3edf2d138b5c3f1d +308, 0x75d6bb275d817dc +309, 0x8e660ae27107664e +310, 0x7a8021038ee303e1 +311, 0x2042ef5eefa9079f +312, 0xe3e7b90bbf6d457a +313, 0xf3f819d2bb9405b +314, 0x522e42155cae0c10 +315, 0xf5bfbb975b40e233 +316, 0x2cf82b614dd95cfa +317, 0x183ef4a96bc40e55 +318, 0x9f6e351c5ba4e752 +319, 0x37c1110683c90846 +320, 0x1d89b7a996d8a977 +321, 0x18a444f77c7cb4d9 +322, 0xd0a8a971b78dc893 +323, 0x860232fb9e6543f1 +324, 0x60b6097f51002555 +325, 0xca1e5214123e3894 +326, 0xe03fe695c95f99bb +327, 0x2c7c6779d5f03622 +328, 0xafeeee42f63055d1 +329, 0x670dde905515936a +330, 0x9a922f42b59fb094 +331, 0xddb5ff49af5a651a +332, 0xe61b04c9e58ebbf8 +333, 0x4e459dcf272e7fc4 +334, 0xd549e92c16adceeb +335, 0x7a17dba1299d4a9c +336, 0x825d756109f2b585 +337, 0xba142e61a9cb203e +338, 0xc2a19f00e9c04a30 +339, 0x2d0f8140d23d0652 +340, 0x8b866d4d4d6caaf4 +341, 0x4f11d90dd91f8217 +342, 0xf6efc37373b9e0d +343, 0x248493d6cd6a4736 +344, 0xd12b6ae74a951a3e +345, 0x56e34722070b70a7 +346, 0x22d3f201cc9fa0eb +347, 0xbfdcc320008291b7 +348, 0x1a7a6922e9204fbd +349, 0x831421e0c4945ae4 +350, 0x66316feddddf0e11 +351, 0xa8c86a1517456554 +352, 0x14a9049ad989e335 +353, 0x837022259f141ecd +354, 0xcb71793a06c261f7 +355, 0x4aeefc07ebe09a79 +356, 0x8982f15aa3b6594b +357, 0x67bccfa7ed9b0d5b +358, 0xb377463b523e9dec +359, 0x53d3d594870fecb7 +360, 0xa5274b1caec5a60a +361, 0xd6316d0cb643db39 +362, 0xabc1a9b536de88ce +363, 0xed2fdb1383d2a077 +364, 0x12319c6feb97221b +365, 0x7e0f6cd40ef47403 +366, 0x86135c84fe26dbf8 +367, 0xc96622d3fbbee19b +368, 0xe3989d8d8511573f +369, 0x42cc365554d1fdc7 +370, 0x4c1a1eb8bbce8b4f +371, 0xfc4e30e7ef2034c1 +372, 0xc490444317a91e76 +373, 0x7ccdf469ff5dc81c +374, 0xf5a0da4110cc09d7 +375, 0x505227baf34c0fb5 +376, 0xbe58737e8a35cc88 +377, 0xd449bee91b3e8c41 +378, 0x3e590e23299d0e6 +379, 0x291a7d9e0a64caf7 +380, 0xdc6fafbdfebd2293 +381, 0x8223f1e259fe8a65 +382, 0x6186fbc9efd9e3df +383, 0xfda39b07e4007ffb +384, 0xfc19aea98574dc02 +385, 0xd0e10d354fcacd8c +386, 0xc9619916544a55a5 +387, 0xd454d50a8c8558cd +388, 0xcd94a246712d91e +389, 0x76a771f5d1231cce +390, 0xdd20cb2b7b370ee5 +391, 0xa6f4f50feca57c49 +392, 0x78c8fb431f17ab9c +393, 0x1b692b79a59b43cc +394, 0x4c45045d287da7e6 +395, 0x522132e18bf43928 +396, 0x25c458983138b41c +397, 0x2a1fb426ef229796 +398, 0x74dc324c74e5dd3d +399, 0x6df75e3eb6eb5374 +400, 0xb63f2f4f9ca25b61 +401, 0xac72286112ee54d6 +402, 0x5a966f3d0a6863c4 +403, 0x8d7046bc64a46fc2 +404, 0xa7b740fd6e3087eb +405, 0xcdbcbe0340cfcdf5 +406, 0xcb632613bf312b65 +407, 0xa91b3f2c2aac238b +408, 0xa06deb3f5ae555a3 +409, 0x29d72e1f8db69 +410, 0x2d004bae09728ea6 +411, 0xc6eee5dce0736cc1 +412, 0xa7493145500ff60f +413, 0xc4d68c4aa18ab93c +414, 0x8210c29e79d48d7f +415, 0xd0999d7889ecbef6 +416, 0x6e3bd61e66e93566 +417, 0xe6cc13d47d7d7b1f +418, 0x3d6f181f42e03979 +419, 0xbed4e14fd867604a +420, 0xbe511c84067bd86d +421, 0x49a876d89e697d38 +422, 0xc04c3dde8f889c98 +423, 0xaf293eeab0f53e3f +424, 0x9f6291dd65732cd6 +425, 0xd7811ac01de78c01 +426, 0xe385cf0261d50ec2 +427, 0x5a64134b3542bbf +428, 0xf9d1302bc6f13a68 +429, 0x5d2aabbea37d8c31 +430, 0xd9842e99a5192970 +431, 0x713eadc4cd30e837 +432, 0xb7b002fc72abb413 +433, 0x276cfeea526af1cf +434, 0x8519fe79b633a0ce +435, 0x2f0e87363705a3e2 +436, 0x9adbac0be3c371e7 +437, 0xf3f44ba899a6173c +438, 0x782d6c29618fde2b +439, 0x7f61062acec408f +440, 0x6e79cd836359258f +441, 0x5c8e9b138df5785a +442, 0xa54359c9f39a9a84 +443, 0xeec3f033135084b0 +444, 0x883ee717787a535c +445, 0x9a2422b513a73b00 +446, 0x2dd4beddcdd64a58 +447, 0x90c8a13202239c7b +448, 0x85b352ab759646d9 +449, 0x139f5cb2e46c53aa +450, 0xe1d3ba6c721c66d1 +451, 0xaa66e0edc4b60a98 +452, 0x3521275c75be29b6 +453, 0x490a5190b3edfa5d +454, 0xd2abcdd2ccb2f14e +455, 0x9d9be8bef4a5857d +456, 0xde19676f13ef7755 +457, 0xdac2fee2e42615f3 +458, 0xf4239801cb02f2ab +459, 0xaa8bf923ed91875c +460, 0x61d18a1940e4c7c0 +461, 0x1eb6aa3d5f077a6d +462, 0xee7374c063bf29d8 +463, 0x2f0a59e34d76268d +464, 0xc92e80e17d1eb3e9 +465, 0xafd05b3ec3d2ca72 +466, 0x28a61ad8d6c497b8 +467, 0xa7094d6834ad7d47 +468, 0x57d80ea9eccbb4f +469, 0xb047e0fee6cdaf16 +470, 0x44f41b5eb48c00bb +471, 0xd6dc8e1eb9c8c9ba +472, 0x47adfd2c638c7849 +473, 0x365d63db7d526c68 +474, 0xc21cda439016135d +475, 0x14d10c3f0f98863c +476, 0xa93e56f74e037602 +477, 0x3b4e9c8915bdc9 +478, 0xb46f5ae155e54aa2 +479, 0x8e470d21ce1943e1 +480, 0x60b96301b5ba2e8d +481, 0x1b473a41d381f9ff +482, 0xabcf5a8e3269e73f +483, 0xd410f6e94fb21fa1 +484, 0x65d1a47eebf87e5e +485, 0x48eaa201c61cb843 +486, 0x212c1abc2499bfc5 +487, 0x4255ad8377d2d8d +488, 0x44caeef472010612 +489, 0xffae764524f572f2 +490, 0x78d374d20c9ee550 +491, 0x6e003206c0511cee +492, 0x7998a159145bfb82 +493, 0x921239650bda1d4d +494, 0xae05025509bcfdc5 +495, 0xc6430c980be407b4 +496, 0x78524f1744b153f1 +497, 0x84089e6f468181fe +498, 0x8d0d21d7dfb6c254 +499, 0x90bad90502a33603 +500, 0x3072a403cbd16315 +501, 0xdfadddf3f1c040c2 +502, 0x22f0b0639d9ff975 +503, 0xb49e48a4cad0765b +504, 0x95a0a04f8239709d +505, 0x56e147a24a4c481f +506, 0xacf16ef61dea4c7e +507, 0x424040afd2700de6 +508, 0xc67e8096a3c717a9 +509, 0x39f164181dd0a399 +510, 0x2449cedc1d62198c +511, 0x7a53df11a1f1a61c +512, 0x5596f1d4a3badae3 +513, 0x38ed4c822072b3d0 +514, 0xf07ef346b3fd730a +515, 0xfd349c35c3ed51fd +516, 0x2f15c9c7890f8f32 +517, 0x3b470df52b173c29 +518, 0xd31bfc8981281af7 +519, 0xbbcc9bdf561215bb +520, 0x5782fffea326574f +521, 0xb0ebdcfcc5e03290 +522, 0x7fd89d93d2b3fbef +523, 0x280ea1865d9ba2 +524, 0xe726959845b2c100 +525, 0xd0361f032cd7dbb1 +526, 0x3c65ec2028b81a22 +527, 0x5221e9b2188920bf +528, 0xeb5ab27c4125ec20 +529, 0x80a32dd48b54f0a4 +530, 0x369b5ced1012bebb +531, 0x582d35d76530bc6f +532, 0x7b50dc9b48e1e37d +533, 0x37fdfe8bbacf8dad +534, 0x7a0cb7e6e93840ea +535, 0xa1132c870be0b2ce +536, 0x9d8ac2c68267cd1a +537, 0x470969b647fa7df4 +538, 0xabcb7d8adf7e2d24 +539, 0xacdebec9bdf9eb1c +540, 0xe30f4cbf7eb6a59 +541, 0x746673836c4df41d +542, 0x75120a6b647bb326 +543, 0x2f4eab556c3f6878 +544, 0xd84651ab05405b7a +545, 0x9e695808b9622284 +546, 0xc93b71e56aa6e1a5 +547, 0x2be7f3be4a7b7050 +548, 0x6497e910b6733241 +549, 0xcf7050dfd08076fc +550, 0x4e3cc156eca183f7 +551, 0xf801a33d9326c265 +552, 0x6aa293c8a47d40e6 +553, 0x28c429755faa6230 +554, 0x82b818651f54e7bb +555, 0xa84d726d7acdbead +556, 0x5cfa535d5774965d +557, 0x4a34b7b1cb48d53 +558, 0x86a7b5bce426de84 +559, 0xfcd2307cecdb7318 +560, 0x16dbaaa71181a038 +561, 0x88e7e8cd261c2547 +562, 0x3c09ba6d1d5ea913 +563, 0x5dd3d643734ee5b6 +564, 0x326d725fe8cbb33 +565, 0x7bcca9ca2da8e784 +566, 0x482dcf6b11d7f9a4 +567, 0x1291b605b4cd3e04 +568, 0x6988181b50e2f4a8 +569, 0x649e3c37131fc292 +570, 0x4eeb67b9e21eba54 +571, 0xc051d39073dec45f +572, 0xc99c52e110270d67 +573, 0xcb813d5d77868add +574, 0x423a5f13573e7ac0 +575, 0x231ac4cc4fe73616 +576, 0x4c22b888a6e600ea +577, 0x8059a6dc7c9e25c6 +578, 0x49f498a5b8ad22de +579, 0xf1e812cc6d1826c8 +580, 0xbbaf60abe8b11e00 +581, 0x1d31d7f4d8be9a6a +582, 0xfeadce70a9a10c14 +583, 0xb47c635bc136996a +584, 0xd88e694c8da030cb +585, 0xc41bbe132aff1364 +586, 0x34249ab18a4b0800 +587, 0xf14b5c825aa736cc +588, 0x2710be6b08df78e +589, 0x2ab56bcc9bf9e740 +590, 0x9b7f6e591b5f648 +591, 0xfb665c3772f34135 +592, 0x628a0a5d2db5d8d5 +593, 0xb3e3f251e61b5259 +594, 0x82310ae33faf1b23 +595, 0x24af8723a65cbd0b +596, 0x671c93282fc4ad97 +597, 0x6cabeaac77270cad +598, 0xef4643fe38b02b7f +599, 0x7b011549d1ac6653 +600, 0xe2af87b9fccfe89 +601, 0x36b71ad67197ac8a +602, 0xdbba55d06f2fd93b +603, 0xf571dbd764b7f7e5 +604, 0x38ea402501cdbd45 +605, 0xb8ab5b5b1bab2913 +606, 0xfab973c4d45f32bd +607, 0x9364f1717c2636b9 +608, 0xfad00f4d983e00fe +609, 0xc90c532a11aef75a +610, 0x64a6eda96e44783c +611, 0x35891f2eb84520be +612, 0x28d216080caed43 +613, 0x129629cc5bd206f6 +614, 0x22c3d39822cbb4b3 +615, 0xf1efbf4cce1eaa2b +616, 0x7070cba12524ed08 +617, 0xa7ed0be9deabf20d +618, 0x8ddb4cd6b454f76b +619, 0xb82814b1db37b63 +620, 0x418e83b36de01876 +621, 0x9a538c7f39c6413 +622, 0xee0cd7abf8a2ecb9 +623, 0xa9222b07e95590f3 +624, 0x6296a415d68341e6 +625, 0x981e0a5a8f811929 +626, 0x4bb372d3b0de283d +627, 0xa9805b5971866e16 +628, 0xaf3b5f5183497657 +629, 0x2152b0fd23c3d9f +630, 0xb730c325b7173180 +631, 0x1e3439d231608c19 +632, 0x1c5ba6031379823c +633, 0x87f5d12d6d365cbc +634, 0xd3bc7f29614bc594 +635, 0x63102214bb391268 +636, 0x482bbd5bba648a44 +637, 0x6a23604690759dc4 +638, 0x4091d41408d3a39e +639, 0x7cd017f922101b15 +640, 0x7ce9004ac5f9231 +641, 0x978bc3d8ec7f7fdf +642, 0x5bd0c4d780580c11 +643, 0x4313c068bb040153 +644, 0x3ab7dab7bc38bf80 +645, 0x3aaf9c187728deea +646, 0x6633a4ce8efb88d9 +647, 0x7263b089878f00fc +648, 0xd0d767e96fe00eb8 +649, 0x184a7c0c01908028 +650, 0x1ebdf41e6f76e186 +651, 0xeb740ee1d0402083 +652, 0xfccf4974edb1c339 +653, 0x16e2707aa28306d +654, 0x1684f0bdb018c3a5 +655, 0x887b6b67b88aa862 +656, 0x923d7810a2bea33a +657, 0x56b3560babef5d6b +658, 0xb39a14614c54b8c6 +659, 0x33e4dc545a509fc8 +660, 0x26e21f84142da9b +661, 0xdd07598125756855 +662, 0x572d49a071d7ae0a +663, 0xba3c7e3baea28760 +664, 0x7ecdb2d714db4b61 +665, 0x1c62b4920e1b2fe2 +666, 0x71bfafb70092834a +667, 0xd710a4228f60d56a +668, 0xeb16277d4ce4e95b +669, 0x968168c90b16d3a1 +670, 0xac3439dfe8ad0062 +671, 0x5a8226f9dd5876ad +672, 0xb843affe917291b0 +673, 0xd76d1e67051f8259 +674, 0xb73a6638cce8ccde +675, 0xa0e6afd3c7295f9 +676, 0xff8857b4bbb5f4c6 +677, 0x99becf78938f0426 +678, 0xfcd17edc1e70f004 +679, 0x6223b8b23f2f50 +680, 0xca875f3e84587b4c +681, 0x7d1e81e589f87fb9 +682, 0x9eb621586aa826fc +683, 0xf46fb9ef5b9c2086 +684, 0x2882c9b7092725f3 +685, 0x5493f099bbedcd02 +686, 0x90c1ec979ffa811d +687, 0x963f765025bcc53 +688, 0x56194e3ec3d9d4e9 +689, 0x7ec4720954cac1f0 +690, 0xfab3145171af7f90 +691, 0x52a0b4e41a13b593 +692, 0x740e2d4d5909d126 +693, 0x98f5339c09c94a28 +694, 0x1700e462fe8dec76 +695, 0x3dbffc2aa4695ac3 +696, 0x5763edacabdfe2a1 +697, 0x7b5b623ce49ef21d +698, 0x30addc66f49860df +699, 0xcc7511a6c31bceda +700, 0x1b25b61ca75db43b +701, 0x416bc4c298e59046 +702, 0x4cd11fe2d74e4649 +703, 0xb54458a9229fc978 +704, 0x8c21a27882b6ca35 +705, 0x57887c8b5e01639b +706, 0xf4e893da996680bb +707, 0x8d601297702c9c0d +708, 0x2a27904a30aa53af +709, 0x497800f6917ea8d0 +710, 0xe96db3340ada9c00 +711, 0xcc23166f14c010ee +712, 0x782690d78fa65ec9 +713, 0xf3e00d74a0878eda +714, 0xa7cbb683decca0a3 +715, 0xdd2e038e683a94aa +716, 0xe2096ff8da896ca5 +717, 0xf7c83400afdabe11 +718, 0x395b8c6f6a4086a4 +719, 0x4a164ec05bee71d4 +720, 0xe87aa5d1ca0462fe +721, 0x8dbc5aed6dff9ceb +722, 0x12120d1e9552707b +723, 0x877dca6889b3e6cd +724, 0xbd65605c01e900fb +725, 0xbd6b82c4157c3115 +726, 0x8b60282732caf78a +727, 0x279fcf5e5de9e57f +728, 0x34b34ebfb6a37eae +729, 0xd258cc1a14e03b7b +730, 0x9a528ba3db4a13fb +731, 0xffa0aea59d057746 +732, 0x27fa7f456cd37c4e +733, 0xe1117a57a6fdce63 +734, 0xdc8fc903970a1551 +735, 0x492dd104f30faf29 +736, 0x110def0959e5652b +737, 0x7f8d1997636fdd15 +738, 0xfb77b05e538a9b59 +739, 0x2e41fa35b4b01fc6 +740, 0xbc35ae69a3374085 +741, 0x192c2a681c2d9b4b +742, 0x12566b8866c189d6 +743, 0x9d88ea785c5185c8 +744, 0x30a621ad5f983c4 +745, 0x8b875efe1206f587 +746, 0x224d25c3af6e3423 +747, 0x7503e976a1ac7bcc +748, 0x3c98aa869e823859 +749, 0x3d8835304b646892 +750, 0xf6353330ff970bc2 +751, 0x8a673f5e2edb8acb +752, 0xf2fdcc53493838b9 +753, 0x85ddcd526236af16 +754, 0x60afb99814c676c5 +755, 0x32a1c2749e281ca8 +756, 0x2367a92ae3bee9ca +757, 0x219fe082703743cc +758, 0x34d8b74dc85182a9 +759, 0xdd04164c72db23f +760, 0xe293ac28fe2671a9 +761, 0x9ca7d169cbda6f45 +762, 0x705c47972b4240ed +763, 0xc10eda9eeb536209 +764, 0xc36ddacd0c94e85d +765, 0x8eb592c27e8cd0d2 +766, 0x3e815991c76e7cc4 +767, 0xac9cfce31acf7580 +768, 0xbf7a4cb31c7aee94 +769, 0x663077444aceecf6 +770, 0xe7f614ff386eb568 +771, 0x79d7a229c66912c0 +772, 0x161ed4311f63e1f3 +773, 0x308a5faeb9982ede +774, 0x7b38ddb9b7efd10 +775, 0x1e103a2589b27ecf +776, 0x67b02baf4259f27e +777, 0x868921c115ea2eee +778, 0x959791912200f71e +779, 0x4dd55f36dec10557 +780, 0xe3464d90080cb99d +781, 0xfb2d4f6accce652f +782, 0x109900a9257d77ba +783, 0x3c4bda8e2c83684c +784, 0xc9ae040fb7f868c6 +785, 0x78098ffe994f4905 +786, 0x7a94c33eca77f0b4 +787, 0xbe6a2a95e9b5c0e8 +788, 0x797d39cf963f4837 +789, 0x8d2e249e4425d06d +790, 0x6ae2c30cd5da06f4 +791, 0x904489de762b179f +792, 0x84713e2dfb591e3b +793, 0x6405a40da3f6f51b +794, 0x976b560d663a2df1 +795, 0xed1c544784ba1e22 +796, 0xca658e995ed9344c +797, 0x2b1c6b8e4db49025 +798, 0x52b1513da528bad +799, 0x3c63406d256d9968 +800, 0x63a31ca3d423f85e +801, 0xb05a81f55789a720 +802, 0xd04412992c476c8e +803, 0x828ec2f77a150a3d +804, 0xee50926671bb60c6 +805, 0x5aa70f93e2df61b4 +806, 0x94d60fa2e8655858 +807, 0x3f5e5b770703cc7d +808, 0xc62dfb2688ca7784 +809, 0xaaf02e1e8ba89fe4 +810, 0x4ab74e0d8c047405 +811, 0x31ee04fbac6fcead +812, 0x1203b78b8228f5af +813, 0x412a70836f9aa71a +814, 0xab51cf98c03f1819 +815, 0x783a3ce9ce137f65 +816, 0x8897085b0a072cf2 +817, 0x685dd9bde8798cb +818, 0x9a1fac7b1705e2c1 +819, 0xf3e9ff98de48e9cb +820, 0x5c2d3eb1a1fbe917 +821, 0x3bda718b6b54d82e +822, 0x29f2dd18f22f0821 +823, 0xb992da1572ac3597 +824, 0xacb69e7aa14b34f7 +825, 0xcd36e3ad14f088d1 +826, 0x6aaacc96a1ec55e8 +827, 0xf8ac593f154fe68f +828, 0x18fc9cbff012339f +829, 0x2f3368ccbbb99899 +830, 0x7cec7d17f37031f7 +831, 0x96e86bfaadcb8fc2 +832, 0x74f9e7ee3d42a752 +833, 0xbd52f6c7d9b0733 +834, 0xa48e6d96bb6ce1c9 +835, 0xaefa058254b82133 +836, 0xb7a19edfd0929107 +837, 0x6160ce9125b26e26 +838, 0x6537dbbde1d2aed +839, 0xc567f9a6bec52dde +840, 0xca29fd3f22443342 +841, 0x7732aa6db6a1c476 +842, 0x8f5a4d7df6b11b3 +843, 0x76649262aa7e31e1 +844, 0x60a13eb125fbc829 +845, 0xc81e4d123dd21ac1 +846, 0x643cbb09bb72f86b +847, 0xf971a98fb25555a6 +848, 0xffa2774c66692d56 +849, 0xcb33c16c50b13ea9 +850, 0xfabf388dffda0e9b +851, 0x55d41ec12ca24b9f +852, 0x91cf693a3467e807 +853, 0x6be2c00b2c31d6dd +854, 0xc5cf513b5251ae28 +855, 0xffc4384212403dec +856, 0x45d4e1865255a69d +857, 0xfb1dcf956972086a +858, 0xcae946a55c4c55b8 +859, 0x7351ac7720e385c1 +860, 0x19aa8ffd86240254 +861, 0x8f515ae78f4040da +862, 0x1e1ed2058de50fce +863, 0x22d006dcdb374243 +864, 0x6e0f0ede7c95b441 +865, 0x70e8aa81b53b4d25 +866, 0x998f309ea41e3814 +867, 0x89ed6598fb66f390 +868, 0xb5997dc3278060df +869, 0xb2a021eac4f7e046 +870, 0x3705b60aa2fd0768 +871, 0xfc415079ab9200e +872, 0xf2871ac4cf45ecc9 +873, 0x24bf758d2246175f +874, 0xac503dd6f8141b3 +875, 0x4e879d12d9f03b3 +876, 0x82034af8cf93b644 +877, 0x59899dd7e478a6c7 +878, 0xae90addb6eb11507 +879, 0x1524ddf76730cdef +880, 0x6fd4afd5456b1c9d +881, 0xcddb9221ea001cbc +882, 0x64ff400bbf2e8604 +883, 0x6dda10549b06ed9b +884, 0xed2c85104c261527 +885, 0xc7e09217d29929a8 +886, 0x56284df611a428b1 +887, 0x1a7608289c0a61 +888, 0x7cb63db15166ff66 +889, 0xc6013c76fcdcdc72 +890, 0x8e5dd566c7a5a676 +891, 0x5a8e8565f40d133b +892, 0xe465973455848c44 +893, 0xf92eecbfe0f3c2c0 +894, 0x7d64155d4dcc5cac +895, 0xf17595706f988dad +896, 0xd590a001a6a19c5c +897, 0x82a164475758db3d +898, 0x6b144993ea1bbe32 +899, 0x22a81a7a6e453779 +900, 0x8e8c298df1a68a73 +901, 0x78056afd6d936b4c +902, 0xaaceef0325faaf62 +903, 0xe78bb7699f82266f +904, 0x523a2d283c5a5166 +905, 0x7076d87088f6c6db +906, 0x6087dd54cff5aeb2 +907, 0x7ef82e62cb851680 +908, 0x4e8bcc8ed84d03d8 +909, 0xd12fa0361df3cfd3 +910, 0xefb89c79f8127297 +911, 0xa9af4e2fbce0b1f8 +912, 0x462136685b70331e +913, 0xe9e74c93da699b77 +914, 0x9ec69215fb11d0c3 +915, 0xc10f229939e3e111 +916, 0x3f67fa79e41d2374 +917, 0xd5e7c1a9a7185162 +918, 0xa1dcce9ec91492fe +919, 0xd4e61f0727b5d21b +920, 0xdf6cdce46551800a +921, 0xa3f256ce906982d3 +922, 0x209742a6b9ffc27 +923, 0x4006c96958526a57 +924, 0x9606aebc75a1967e +925, 0x91b9f42fb64189df +926, 0xb27119defcb938bc +927, 0x128cc7a84ba05597 +928, 0x6c3df613c62d0d30 +929, 0x3adf69d48b629ec7 +930, 0xda42ee493837b128 +931, 0xb8e770480e760bb5 +932, 0x9feb55d57c99c626 +933, 0x29812d80afdae3ed +934, 0xae4222a64276a8c7 +935, 0xe3897212a5b4ed53 +936, 0x98bedfd13886e669 +937, 0xca858675d7fc0d0e +938, 0x28a359f665354234 +939, 0xfac2ccabe4128b35 +940, 0x61373cc5d11ca180 +941, 0x7007605a4512a87a +942, 0xe71f8eade7b30b3d +943, 0x3a9e77f9b99bd04d +944, 0x70d3e42488098866 +945, 0xd30fc159c7cd4d99 +946, 0xe4d3f6600d2e2d6f +947, 0x1088324dfa955c25 +948, 0x516437acd4764623 +949, 0x38a31abe50d0aa03 +950, 0x72e1054e9dc02ba +951, 0xe6971dd664d1a2e2 +952, 0xf6698cb095d3b702 +953, 0xad995a5a8c19bd92 +954, 0x34e53c6936f656e6 +955, 0x10de240bc07c757a +956, 0x3e3b9a6861c2bd1c +957, 0x9c0b0b97d3712ec9 +958, 0xabf1505a75043aed +959, 0xbdf93d3de3274179 +960, 0x28fa5904d3f62c28 +961, 0xc3b97b39ef6c5133 +962, 0xf2b2219225b8679d +963, 0x8be4ec0f930c0aaa +964, 0x47de5a56aa590643 +965, 0xb6f871b304129856 +966, 0x80a61c06233ab0f9 +967, 0x3ce6c3af8101b055 +968, 0x85b911708274e7d1 +969, 0x4cab65d093a488b7 +970, 0xaabc4b10661fe28e +971, 0x35b16dea64474a68 +972, 0x1d6eb5b093361223 +973, 0xc39107b92f0fe1fb +974, 0x1d09e048073c4841 +975, 0xc6a02f43aca8cb2f +976, 0xaf6613dbc7da909c +977, 0x5ac2a40c230aa756 +978, 0x33afb5e7c01c39a5 +979, 0xc7b0b20ea8b7d0ef +980, 0xdf7306c8ccb1bbea +981, 0x9710efc0c188b2a0 +982, 0xd6303eadb72c873e +983, 0xa38ca609b118f35a +984, 0x8390613065c6e535 +985, 0xdf9a0106757e431f +986, 0x8bcf77039788e143 +987, 0x6026806a986b378e +988, 0x482ff3b1394cb1dc +989, 0x2a27d0ccac9ede9c +990, 0x53c77f26e271b3ab +991, 0x1ba004cf276cf3f +992, 0xc135b0517dc81f7c +993, 0x5d137838db75e442 +994, 0x3fe505f93d1dbdd7 +995, 0x351654ae7d598294 +996, 0x173f8d182af9d84d +997, 0xf97dfcd164fe11c5 +998, 0xcda423e5ad43b290 +999, 0xa5cb380b8de10d10 diff --git a/venv/Lib/site-packages/numpy/random/tests/data/pcg64-testset-2.csv b/venv/Lib/site-packages/numpy/random/tests/data/pcg64-testset-2.csv new file mode 100644 index 0000000..7c13e31 --- /dev/null +++ b/venv/Lib/site-packages/numpy/random/tests/data/pcg64-testset-2.csv @@ -0,0 +1,1001 @@ +seed, 0x0 +0, 0xa30febcfd9c2825f +1, 0x4510bdf882d9d721 +2, 0xa7d3da94ecde8b8 +3, 0x43b27b61342f01d +4, 0xd0327a782cde513b +5, 0xe9aa5979a6401c4e +6, 0x9b4c7b7180edb27f +7, 0xbac0495ff8829a45 +8, 0x8b2b01e7a1dc7fbf +9, 0xef60e8078f56bfed +10, 0xd0dbc74d4700374c +11, 0xb37868abbe90b0 +12, 0xdb7ed8bf64e6f5f0 +13, 0x89910738de7951f +14, 0xbacab307c3cfd379 +15, 0x2cf7c449d8b927a6 +16, 0xdcf94b3a16db7f0e +17, 0x8a9d33d905a8792e +18, 0x4cb9eb2014951238 +19, 0x6c353acf7b26d6f1 +20, 0x73ff53d673aa30c +21, 0x1fd10760015eca68 +22, 0xabae0aa9021eeba8 +23, 0xa5ae363a868ee2bb +24, 0x9d89e0f041de6631 +25, 0x6238b133c3991a65 +26, 0xff49267d75fef51a +27, 0xfb180656ce13c53f +28, 0xaf7fadf36128712d +29, 0xa6847fc6f339c63e +30, 0xb03e0b80d71ea5bc +31, 0x63905abcb43969af +32, 0x2295af3ee00a3bba +33, 0xb8b375b994330415 +34, 0x867d9ef1d8716a3b +35, 0x4f6c02f5601b4e18 +36, 0x7c5fb4c16c470d18 +37, 0xe3b57986b804b343 +38, 0xef1d79d212aca692 +39, 0x5b98774c8806209c +40, 0x924fc76bac38a5d1 +41, 0x5266084c412ddeed +42, 0x98240bf9b831d6a3 +43, 0x5681599e81219442 +44, 0x6441248fc2ba92bc +45, 0xe3e9051a540349ea +46, 0x3a2700034390baa3 +47, 0x9f893155b6d402bc +48, 0x158207910c6d8aef +49, 0xd5282ab7608c2cbc +50, 0xc97f4651669dee4f +51, 0x3d4750d95103ed60 +52, 0xe0614542caac1f04 +53, 0xefe5092144cfc6c +54, 0x560bc486abd7e9ae +55, 0x2678b71392daa4b8 +56, 0x734970d3dc2ba416 +57, 0xcbdbe849e51e4aaf +58, 0x3b0b5e28b491556c +59, 0xd51449ac45abd88 +60, 0x6790b59991f1b7ab +61, 0x32d1c039ff2415bc +62, 0x173b9772f24f72e0 +63, 0x9490a9ca9f883b1b +64, 0x4c775989e6214222 +65, 0xac07db37e6ee6114 +66, 0x331371b2e3f10aee +67, 0xf12e5326c21c28e4 +68, 0x5d77dc280c70d614 +69, 0x1b01bd17a2f281ec +70, 0xa10d3b5882938487 +71, 0xed5a0033c394ae8f +72, 0x70bc8ea568ea44b4 +73, 0xf4600ae77965e730 +74, 0x7ff92c0b321ce233 +75, 0x6cdbc87d0cc1d670 +76, 0x9ec64f0cf2000eb1 +77, 0xfebea50259800f68 +78, 0xf2edf9019a8fd343 +79, 0x75c584ac042e5468 +80, 0xc1fa8481d5bf9a1d +81, 0x7f57180168514ac2 +82, 0x878100716b94f81e +83, 0xc929406e3af17fd2 +84, 0x6a26e2c013e4bf4d +85, 0xbc071d8848280955 +86, 0xb60d75abbfd1bdac +87, 0xee9b76afeca9fa69 +88, 0x1d6c399d2f452810 +89, 0xbaa0bc1621e25c83 +90, 0xed6ba792f8671ba5 +91, 0xf7ca02c2ab11d8d7 +92, 0x3c3cadadf0b21e3 +93, 0xdd1784571e864e9c +94, 0xfb2f992015157509 +95, 0xf50bb9f0d3ced743 +96, 0x261565f75c3e185f +97, 0xf8fe33b284513e60 +98, 0xe3d2d10b5e024664 +99, 0xd28717566242cf35 +100, 0x7ae07d133ac5b789 +101, 0x3b7ccaaa53ac338e +102, 0xcd480bace4871650 +103, 0xec6c78f923c080e9 +104, 0x44211d0ff8919d59 +105, 0x89f79af76d2a45fe +106, 0x71583fd8a837548b +107, 0xee57269c261511f5 +108, 0xa5ee8f3b128c5d1 +109, 0xbb64c20ed0765a17 +110, 0x9d4790ab2eeaf7e4 +111, 0x742f3db806d9e98 +112, 0xb81ec97aed6a0d1b +113, 0x41808b34f6a8a23 +114, 0xc20913af175dfd4d +115, 0x834427db263b22bb +116, 0xedd9c632e611828a +117, 0x10eac8524496f571 +118, 0xd76091b97eb00ab7 +119, 0x111298ae9fe95666 +120, 0x5824b2e2a6719c43 +121, 0x6e280ec539e934ed +122, 0xf74fd832df90083e +123, 0x8fee6d0f241c2e97 +124, 0x4244f331c2f19c3c +125, 0x3dde75a845cce97f +126, 0xe35bb8e635a9915b +127, 0x39d2943037f7932e +128, 0x1fe2d134201d0970 +129, 0x49d00b63c749b804 +130, 0x960c2942cd4e4e04 +131, 0x8dd8e009dbc0435f +132, 0xcf493495c3a055cd +133, 0x8f7b5a1c0f9fe9cd +134, 0x49d5f90374641a25 +135, 0x69b3932073d3524c +136, 0xd170603e7de84ee2 +137, 0xa062ba3ed3539948 +138, 0xf5861cc5b5d56c82 +139, 0x5e914998a30c7e76 +140, 0x8d77f2ad1503c0f1 +141, 0x980b6a9e3b4181fb +142, 0xd9299cd50694c084 +143, 0x253dc0f8f1cec4c5 +144, 0x68110fb9d1b3e695 +145, 0xe8f3120d0aabc461 +146, 0xb066e7df0dfb042 +147, 0xd29ce0f797e6b60b +148, 0x6a569bb7ca33bd42 +149, 0xd46e08b2dc2385f8 +150, 0x28c61d11d055767 +151, 0x5d73aa3d1a2bb725 +152, 0x1421191e1c14829a +153, 0xa711bfb6423df35e +154, 0x461af97a86308006 +155, 0xb3e1018ff3519367 +156, 0xf19cf866a268ef2b +157, 0x207715eac9199d1d +158, 0xdd621c410975b78c +159, 0xf390aea68683610 +160, 0x617a2d107a0047d9 +161, 0x6e05ac416e5bebf0 +162, 0x7d253e70506c1bed +163, 0xf9f96f4a7dd53810 +164, 0xc693b29cb1573f73 +165, 0x4f1146b0020ea544 +166, 0x45140608fbd40579 +167, 0xdcf57219828ce6be +168, 0xe19d58cca37b5b32 +169, 0x82bda95b2a161235 +170, 0x5823c3d8a2b6c9ba +171, 0xfeb2e74092fdf89a +172, 0x50e1ad1abc8f869d +173, 0x2ec63d0c105eb8da +174, 0xe14e1c4845a3264a +175, 0xcff53670455eb6aa +176, 0xaafaccd24619fa3e +177, 0xf55a988486e2422a +178, 0xecfba16a90ff4d04 +179, 0xbf8d36c2f644757a +180, 0xdc56ed75a0dd6249 +181, 0x3f45023eff17c3bb +182, 0x2428bbfe90023fab +183, 0xab892c611adcb70c +184, 0xb6f13d8c0c2b9d74 +185, 0x2ac3fb11d224f2a8 +186, 0x65433dcfae2d9351 +187, 0xe906859ae4b45f82 +188, 0x8fb7f5f093d76a3b +189, 0x940dd290b5e88d1a +190, 0x31b27d21bef116e7 +191, 0x86a964e2c83b5296 +192, 0x85ffd17bc079a9e8 +193, 0x16c47c724e7ab7f1 +194, 0xfb6098a9867e7d7f +195, 0x9246fb69092c6cb2 +196, 0x1a4033572760f32 +197, 0xc5cc568a8b273b84 +198, 0xfa6f9f2fbdd44abc +199, 0x9701b8e087718ba3 +200, 0x51d6a7dcf73f8f3a +201, 0x30008172cc6a972d +202, 0xac2ab49a5ca6ac81 +203, 0x31f28ef79461e54c +204, 0x93e35a8da8cc6132 +205, 0x9a2c58beeba3d5b9 +206, 0xf6615c1de266ac39 +207, 0x127ff9f8166b766b +208, 0x7ffe380e80a69556 +209, 0xbe7d2c228e1542f7 +210, 0x2d5ebb4e50ba1746 +211, 0x63585761ae1bf684 +212, 0x1019eb5cee022fea +213, 0xb9d3540ab58da30d +214, 0x1677f4cb45620eb9 +215, 0x6524baee51783822 +216, 0xdf9f2ddcfabb0adc +217, 0x78e8acc43b287935 +218, 0xe9a1974e999222b5 +219, 0xc41324ec2291e780 +220, 0xea52abc9ecdcbc9f +221, 0x209d7bcd46ec6b04 +222, 0x12d504c09803db2e +223, 0x1200e6bf21475d81 +224, 0xde6d3c2b35fd2cfc +225, 0xa2526900ac33bd3c +226, 0x7f1f5290fc432bc5 +227, 0x29ddfb380a3d69c8 +228, 0xac79cb6942a2909d +229, 0x516996685b67a92a +230, 0xb5fc39041cb828bb +231, 0x75d9d8ca0644a276 +232, 0x81e98b76be92a3e9 +233, 0xca27888fafe12179 +234, 0x17be2ae039925765 +235, 0x9429846c0e6d0342 +236, 0x327dfd50439815e9 +237, 0xcee20cd7bc254aeb +238, 0x7d250389f453f29e +239, 0xfd1b232a85c95569 +240, 0x2ed55fac80f3e9e9 +241, 0xf6886c20417a1be7 +242, 0xcd08e61f0b0fdfde +243, 0x7b33e34da5c27bff +244, 0xd043c4b7d5603dd5 +245, 0x9a544e4c70a3b686 +246, 0xa7b60398c381f771 +247, 0xe9e7a3487c4bd4f2 +248, 0x10b58fdfe1ff112c +249, 0xd5c1c9748c0f4ceb +250, 0x61be9d09159d54ff +251, 0x5356f51e8239f510 +252, 0xfe7889d9b202ecef +253, 0xc7fc19ca5d263d5d +254, 0x7c4c07e61dfd9f69 +255, 0x6c315fe5015f300a +256, 0xe0a5bc00039747b4 +257, 0x16397fdcf829ee80 +258, 0xb55aee80d16a5169 +259, 0xca0609944d007eea +260, 0xcc982249f65a02ce +261, 0x528161feb149c148 +262, 0xcbf08ba49b41c006 +263, 0x39af1ff0b6f14138 +264, 0x5cc036be69799aec +265, 0x6adde125b1db21c5 +266, 0x8a99d83d6b613b67 +267, 0x1cd43fca9451f74c +268, 0x682dbb26ecc96365 +269, 0x13b4be2ceb43e3 +270, 0xbe8fbc3b6f4f581e +271, 0xda148a2f4bda5719 +272, 0x239106ca3319f393 +273, 0xb42b4dde641f0dd5 +274, 0xd233cfdf4cb0af74 +275, 0xfb5919d905589afc +276, 0xd802a8860c10b66a +277, 0x6c923e1d00e7b5bc +278, 0xfacce1134f383b89 +279, 0xf9570abda7a6d553 +280, 0x80f0f9796a208f18 +281, 0xc0e1df5280951c57 +282, 0xe9f143f08257bbe0 +283, 0x79e4c6463123d588 +284, 0xdd2118583f2b1684 +285, 0xb399ff5f2329fa18 +286, 0x4b3e9ebae96f813c +287, 0xc484dbf247787384 +288, 0x921865eb97603f2c +289, 0x18063c68e257d300 +290, 0x643181f345e7fc26 +291, 0x12e0b0e8eadf9fa7 +292, 0x79e613fe73dfa354 +293, 0x6db4c59203b7217a +294, 0x6c7a0e9ba6139eaf +295, 0x9617c7ac4e3f6d97 +296, 0x1f68a7b4fb1b4b75 +297, 0xef0b7ab24944f466 +298, 0xaf1dee1f4be1bc89 +299, 0xd2e355c959f5fd8d +300, 0xe594c3fb95d96efc +301, 0x9554766ca3342906 +302, 0xa4bbdc77d12842c +303, 0xb62400211ee489a8 +304, 0x91abadaaa3bbe67c +305, 0xd371eeb91deb42bb +306, 0x883bab35cbd2b6e5 +307, 0xd030c3d9411a9041 +308, 0xff3c110a858ff000 +309, 0x59bdf5ca47d0bde7 +310, 0x2bc80fa3cdba1853 +311, 0x6444ccb652662cb8 +312, 0xc0c7e256b9e90339 +313, 0x70714ea9c9d72302 +314, 0x96a0142f9d897d27 +315, 0x209a9097c5a91ef7 +316, 0xb9e33afc5171e009 +317, 0x47b37af433a58d40 +318, 0x30cc4ffbfa831d26 +319, 0xdcea4a85ff815466 +320, 0x907d5bd027f2e5cc +321, 0x7c081f6852e04a4b +322, 0xe61950749c1d502b +323, 0x1604e937ee69834a +324, 0xb2372d952dd25309 +325, 0x53f6a5b834c72577 +326, 0x2ce7a74395e0b694 +327, 0xacbf9ab4fe91f225 +328, 0x5ce1e63d3a2bb90f +329, 0x54740da3a5ed139b +330, 0xf194ddb39f29880b +331, 0x3305374f5d8ec08b +332, 0x831dd0164927ff4a +333, 0x625baa78e4458cf +334, 0x29d27dc0a4a71152 +335, 0xe227bae9a1401034 +336, 0xca0c209831846b2b +337, 0x8e8cc54b08b5a411 +338, 0x38f2b4acaac27db6 +339, 0x8ec88baac814e86b +340, 0x31c08e46b007bde +341, 0xb686c02722794c09 +342, 0xb77cf8fc682e3907 +343, 0xa56334e7f606f4b2 +344, 0x9c80b127bddd5f4f +345, 0x12df14834cd858bf +346, 0x3f14762a9cf5fb9f +347, 0x930a70941ef5779e +348, 0x64e96c849c30c080 +349, 0xfdf53bfba1300484 +350, 0xec7a9363c21bc616 +351, 0x26e9fd6a115ecb47 +352, 0x9707a84b5bc77fbb +353, 0xb23b2737b20d5903 +354, 0x22f4825ae80f6501 +355, 0x500644b12be6a01b +356, 0xb746645b2af082db +357, 0xe6af051f697892f8 +358, 0x577c724248a1cfc6 +359, 0x3d2b6a434c84eed3 +360, 0xd260f5efd7328314 +361, 0x95c16cc84bb3f55c +362, 0x7a01b2e4e0e80ca7 +363, 0x41930c3ce70a0935 +364, 0x1299bccf39d4e110 +365, 0x494883ba1a8a87f +366, 0x9478ecfe2d918e60 +367, 0x30ec9a5670cda8af +368, 0xf9bc877e833e2b99 +369, 0x1b83a0acfbb4a8db +370, 0x73bc1740c0d18880 +371, 0x65086ca9773cb3e1 +372, 0x3b78c3ccd63cff2e +373, 0xbfae748795acfb31 +374, 0xa4c9d5d56a15ba20 +375, 0xb9cb41721e52b71e +376, 0x1532f15d4dc47748 +377, 0x5a4d647a4b9ee632 +378, 0x8513c7c5a50898d9 +379, 0x6d3d98ccd5461b2e +380, 0xa65e99be2fe98d6 +381, 0x31abc8855334a0e5 +382, 0xf1ed22a661dca5b8 +383, 0x299e2b63229e03be +384, 0xda201a06687bce48 +385, 0xd27794b302142c55 +386, 0x642bd3e1c7898a9d +387, 0x777f1ff00afa1a87 +388, 0xd2f1c84fb3877baa +389, 0xae417583289191fd +390, 0xd641f1d88e0e2d55 +391, 0xc1f1d98fb5d18ebf +392, 0xb0f72aecdadce97b +393, 0xe9b8abc764f6018a +394, 0xd2a37cff8e890594 +395, 0x2dd70d631a528771 +396, 0xbf8ba0478c18e336 +397, 0x1630bf47f372ce0a +398, 0x6d04ea20dc3f46b8 +399, 0x6591881bf34337f2 +400, 0x33c149c7eb5b4103 +401, 0xf01a8c9857c86748 +402, 0x184348cdfc16d215 +403, 0x141168b253d2ed7 +404, 0x52aaf012ef50a6f1 +405, 0xfda1722387e16f4c +406, 0x43c30f57d6c038fa +407, 0xd4a8611f5f96d214 +408, 0x2c512ce17e987f2c +409, 0x961ce450f0fa2822 +410, 0xf55a506ec6cea9cd +411, 0xb76d694d9c7f5ef6 +412, 0xfb029216dbd8e988 +413, 0x93162501896a0081 +414, 0xfbbbd2c5ab300f5c +415, 0xd648b6da7387d491 +416, 0xc73b4697471d9d98 +417, 0xe37412bf1c93ee76 +418, 0xa1a96d96570e6637 +419, 0x5b3ab4f82428f65c +420, 0x873d849b188aa36f +421, 0x39fbee0ffc9fa9ff +422, 0xc70d21b744d677fe +423, 0x2b8a43c23043d209 +424, 0x93c33eaa37370d16 +425, 0x8930ac1880f2b0ef +426, 0xac01d27707036af0 +427, 0xc2af3fee504343a0 +428, 0x1c1dae2ad5535d97 +429, 0x9ffc21804b76a480 +430, 0x69f903412cc13563 +431, 0x9d3c4e2759a0c47d +432, 0xb1a8f894be6302b9 +433, 0x95e1fd7951479506 +434, 0xbb9e6c03cd4ae8e3 +435, 0x85206010c9b737cf +436, 0x767e813694d6238c +437, 0x4969af329ccbb30a +438, 0x3aa9af1075aaea5c +439, 0xb1ff519e8118a993 +440, 0xb21a23a3c91180fe +441, 0x320b24582ca3fd88 +442, 0xf8ca56415fb4e453 +443, 0xabd0899c07205e77 +444, 0x87fdc7a44b4ad50f +445, 0xd75744911641a278 +446, 0x7c8c9a65df6fcb95 +447, 0x79d785e3c7a5b695 +448, 0x421e4565ba1f592f +449, 0x27f87eb2517835cf +450, 0xb62cc4297441c83e +451, 0xd817a80ac815ca6d +452, 0xad84388130df2aa8 +453, 0x5e6b1640452d6ac8 +454, 0x936285e15edce2a3 +455, 0x903bccc4969768e8 +456, 0xefc2cb7b109d3140 +457, 0x633e9dfdda2d903a +458, 0x2a2f3225925678a1 +459, 0xe07eac91a27f8547 +460, 0xe50ced40eda78cb3 +461, 0xc5b22500e1c7441 +462, 0x32becf61bca3aa72 +463, 0xa2e37c4b30671344 +464, 0xc9f1c1910f45d544 +465, 0x9b50333b2dcdf730 +466, 0x310bfd53a1684b94 +467, 0x1e1dc21e66ac6455 +468, 0x81876c2bfb1ed5a1 +469, 0xd0c54a3e25eadc7b +470, 0x3791b6fbbd5c7ba0 +471, 0x133be57356c599fc +472, 0x8d1148eb8e83fdea +473, 0x311aedba0d8b42cc +474, 0x1142ae52745f94bb +475, 0xc5f4ab2fbde8c4a3 +476, 0xd23be827b5b24f6d +477, 0x65f95194cd122715 +478, 0x4b48969d73125922 +479, 0x46f165052b8ff988 +480, 0x5c689f94b9275ff4 +481, 0x93b03823ff2d536b +482, 0x871f3775aa4e3523 +483, 0x5af829f7cc0f66a5 +484, 0xa32e05739cbeac8c +485, 0xacff1856ddace0fe +486, 0x8eeb5e7f991a5322 +487, 0x6325c2720e0dbdea +488, 0x9fb817bc4fdf5200 +489, 0x9786f0d850e43d78 +490, 0x571f76dd7f9fb77a +491, 0x4d9e94e181cbc63f +492, 0x8bb632d3376c547a +493, 0x9cc26d9efd1c88b9 +494, 0x9c5d49579df52b0b +495, 0x6201abf7e1cda07b +496, 0x90d68f0c6c884963 +497, 0xfc5b66188ef7f561 +498, 0x6d9303cf2e0e0f95 +499, 0xd7cfcff535f5ed07 +500, 0x14d1a1228daa4ac6 +501, 0xe00ef5762f66ae50 +502, 0xf113a79471582978 +503, 0x430985281785dc7a +504, 0x31914108c206ed5 +505, 0x7ba6707b6419971c +506, 0x2ec63b033ce112e5 +507, 0xf8bcd36ced3b41e3 +508, 0xe5cf908c8010414b +509, 0xf5ee224b7c703e30 +510, 0x9a9733af0b12338b +511, 0x83e18cc00ace34f8 +512, 0xd52cff39e23008b8 +513, 0xa700578136b9c0c5 +514, 0x3fa179d32ac51f99 +515, 0xef2d5eab6d4ad380 +516, 0x709024a5abd032df +517, 0xc607c7ee349ede87 +518, 0x803d784e9731eb5f +519, 0x2ef06f4ba769282d +520, 0x4bc1dca1e9f07eb9 +521, 0x930c958a7a72f94d +522, 0x249bc8db2cc7a3bf +523, 0x3845305798f9a5d +524, 0x6f137eca9ab6f948 +525, 0xc31f5a963d31bd67 +526, 0x9d39693d5383626f +527, 0x52fb41c335a8b98e +528, 0xb79d1a29a06006ec +529, 0x7c0926a7a3eda2cc +530, 0xffdf5214406fd53e +531, 0xc6aa02a7e94282b9 +532, 0xd4a4431b4aa301ee +533, 0x4271cc0f9420d3ab +534, 0x26fccd7cc7fc2485 +535, 0x330594bb945b8d5a +536, 0x6ea8eaad12e5cb8c +537, 0x831c3467726bede3 +538, 0x31d1eb10017eaa61 +539, 0xc7aa75e41508f5cb +540, 0xde51810f0cadd0b5 +541, 0x50e5b3e73692f80b +542, 0x82107ec55636e188 +543, 0x9828ef175d843ab4 +544, 0xb8edc6a860dd421e +545, 0x25c0c138fd537ac3 +546, 0x47e72a771e8eb563 +547, 0xbb0f8c5333f4a2cc +548, 0x91750d2fb9b2d479 +549, 0xe662d8f6fe38df36 +550, 0x72a6d879fb5619f0 +551, 0x6817c7878dcbf077 +552, 0x4e7741cb484661e8 +553, 0x3b3b3ba0be5711bf +554, 0xa6989f5d25868765 +555, 0x43c276398997e4e0 +556, 0xdcbe16a94da28870 +557, 0x454936980a699c99 +558, 0xac614bfa8f0266c6 +559, 0x9174841392e213d5 +560, 0xa0e2acffc5fc9d1f +561, 0xe53a08a7a0e6521a +562, 0x2b845cf7c24172e0 +563, 0x265a4fc5f7adec0d +564, 0x1f34fbe5f1e49420 +565, 0x139181f6fb647f20 +566, 0x88c35d46e2fcd05e +567, 0x2a6d5b55903c0459 +568, 0xcea28eb621ad7bf1 +569, 0x5c9cdc13e7aaa30 +570, 0x5fe63e14746e7103 +571, 0x7923e53d73835db9 +572, 0x376e661210bf1b06 +573, 0x5b1cab85450efdd5 +574, 0x3908dc096c70b452 +575, 0x4825e303cd1f396f +576, 0xed476bfd702957c3 +577, 0x6acc013aff5db743 +578, 0x62c80b776343d488 +579, 0x9c75edcd5b012697 +580, 0xaa053362a3b9770a +581, 0xa907e236c7c07e94 +582, 0x15b2c380451692c0 +583, 0x94f79142697bd61f +584, 0xbc657d31ea98d44f +585, 0xcbaa5e52517a1f5e +586, 0x96aa2e44a7c4a03f +587, 0x216d3c66db2b515d +588, 0x157001807e3ca88a +589, 0x52b3a596bdd3859a +590, 0xed747e7fc5e3adac +591, 0x78fd765ddb2c448d +592, 0xe53dc7299ed8614e +593, 0x75ad41fb1d7a790a +594, 0xc14f6b944b0e6cb1 +595, 0x7c314b69fce3df1c +596, 0xb56d82eb740d7abc +597, 0x5132a93c41251fdb +598, 0xe3ce35bd2a82f958 +599, 0x440571a981c722f2 +600, 0x194cdfd9f186bc9 +601, 0xb89e522a5db00939 +602, 0xad35f339f68df3c8 +603, 0xa82ab18420322293 +604, 0xaffa6df9b72b27c4 +605, 0x9615694d23beaa2c +606, 0x1d82ebe563abad91 +607, 0xab50ef65fbd94385 +608, 0x1b070dbd70a9a14 +609, 0x2ececa796abbadf0 +610, 0x6bbeafe9e81ab2a2 +611, 0x60dcd0d2a9b76914 +612, 0x1e748039ef05c33f +613, 0x6d4d17f2213ccdff +614, 0x9fa56132957bc987 +615, 0x60a17185de2428eb +616, 0xb56038ddf306479c +617, 0x3b1db5df92d06d8b +618, 0x24d1bba8bdedf580 +619, 0xbfb7e6740ebaa4d9 +620, 0xab31c4473e46f61d +621, 0x6deb3cdd8fd5869f +622, 0x23032e47746d72d6 +623, 0xa9e72d734e10f2e8 +624, 0xbffd199b6157bc23 +625, 0x29f8254df273fb62 +626, 0xb076142130ee55ec +627, 0x5b0b08374126c309 +628, 0xea4536aae979521f +629, 0xc064e7abec91a174 +630, 0x46133ef80c59d935 +631, 0xf0227e2da1b14160 +632, 0x675a76641e1af5a +633, 0x2f50a069b33d198c +634, 0x3ded5a65e1d657eb +635, 0xbb6999b020694f6b +636, 0x86b2f2b33487aed7 +637, 0x76e14e85f8bfb4cf +638, 0x38f7f1e44bd4e0db +639, 0xc1a7d41b7e80d4ae +640, 0x1dfaaf80bbceb42e +641, 0x3f51c11497720c2b +642, 0xce6da1415ddb8b80 +643, 0x7377d8bcd359b5f3 +644, 0xe077208f3f810aca +645, 0x9a06a8a2dacbffce +646, 0xca1f99156b09b735 +647, 0x2ff9a93064d91451 +648, 0x50f3ea93f351a7ef +649, 0x606fceccb07054de +650, 0x7e83d6d2f8f6685d +651, 0x78f3995291c5d407 +652, 0xd28d2460e22d0228 +653, 0x2c5636f68a0054dd +654, 0xd9fafb1c56c8f6cb +655, 0xe39889b5f9d74464 +656, 0x1355372bf5db2cc1 +657, 0x26768426b9ac323 +658, 0x4af1dbdc1111fd89 +659, 0x66973587943b927f +660, 0xf86f5f50684dfb1d +661, 0x1247d574ff79b534 +662, 0xc8039f3259210fe2 +663, 0x79b573235c92a9f5 +664, 0x213f642d8450e2f0 +665, 0x5db7706973376566 +666, 0x6182c12e69b373d7 +667, 0x3e5ac47300aec07f +668, 0x4b5b6c57b1574376 +669, 0x6b7fcceefd56b17c +670, 0xf656c3455cb9d4b8 +671, 0x7577e2e13329721f +672, 0xf33c0c53ce956e8d +673, 0x7d0f328ee356174 +674, 0x10ec9a168088686e +675, 0x71ef1776d062dfa +676, 0xaa7b590a488a6bc4 +677, 0x38612b6dd8049a1c +678, 0x939045e36874f731 +679, 0xcb9d1d74c56d5ac9 +680, 0x54f1c1c8fef1d8ff +681, 0x3ee4b85c8c7e939e +682, 0xb9b4608e019f352c +683, 0x79d4701275d12e6a +684, 0x2632a2d9835c7f19 +685, 0x1662cd9fba293692 +686, 0xbcb70265115ee944 +687, 0xdc43fb9761468604 +688, 0xe3eec4e7d3871352 +689, 0x829531753226989d +690, 0x2748cc67f540e074 +691, 0x39c4af25d607837d +692, 0x741a243f4cb5df99 +693, 0xda1353287e18b49a +694, 0xa6735689d751ea74 +695, 0x46326d587340ce0b +696, 0xc18531df4550012b +697, 0x6f7901e05dd4b818 +698, 0xfb966afc4c001d63 +699, 0x6dc10fca67a9cfdb +700, 0xd6527ffadf0feaae +701, 0x3b900172045e25d +702, 0xb7dd594cdded6a46 +703, 0x6602aee7ec1599fc +704, 0x7fbf12f23747546a +705, 0x32e63f662bd2de0d +706, 0xedf47770b67ed641 +707, 0x331bef83481c5c2a +708, 0x8fc4256fdf05158c +709, 0x98eba48dabccf5e0 +710, 0xdbc2f2cdb7b1c154 +711, 0x7777755616517ad3 +712, 0xd473c147d2628ac1 +713, 0x861e15d1d760b5a7 +714, 0xf4d25926405ecb07 +715, 0xb7739c69effff86e +716, 0xe97fbafa6f96830c +717, 0xf13e8a334e8bede1 +718, 0xcd60010cba4ee4f9 +719, 0x1f537ac2b82e6008 +720, 0x1fda8d781a89140a +721, 0x9dc204f3f4a463f0 +722, 0x456dcd18eb56a1ab +723, 0x629957bc87bd16a1 +724, 0x2c8000ddb8c75253 +725, 0xc31dae9ec8449284 +726, 0xdac05c8baa2b691a +727, 0x21ff7be9ffa3e7ac +728, 0x844f4b5ed4ee08d0 +729, 0x651f913fd636c994 +730, 0xca3e71a2110b2d49 +731, 0x7709bc42253ed09d +732, 0xbb164d45b6569d43 +733, 0x90ec2f040c20a112 +734, 0xfa6e77e9166f5be4 +735, 0x6b6d12c1842d587d +736, 0xfcd7ff8466e25e2a +737, 0x6a5a2ed8bd971297 +738, 0x2ec35f6bba5adcbc +739, 0xc83676e16651249a +740, 0x458f6064cefe10ba +741, 0x90d54d527e6cd028 +742, 0xa5613e88db27c388 +743, 0x331e0c7d85aa1abc +744, 0x8cee4977e210358 +745, 0xfcae379aa6cbff8e +746, 0xd1407afc97a57e86 +747, 0x1fab25c864f094ae +748, 0xd914864a63004552 +749, 0x4214d226a20f1384 +750, 0x3f4e0d80c488b715 +751, 0xc5ca2f654024b7c8 +752, 0xc1e27a124e7c821c +753, 0xd890a915ffc7918c +754, 0x22fba040ce51a9f8 +755, 0xbf61cebd8891617a +756, 0x7846609ee228e319 +757, 0x536d1854375509b8 +758, 0xbbfb45fc6e666f50 +759, 0xd85b4c0527f9d7d6 +760, 0x528cc9c7fa2a84c8 +761, 0x27a1baece647f2cb +762, 0xfddf0cb92fe09dc3 +763, 0xeb5008fe965d8d96 +764, 0x4a3307937eb2e5c8 +765, 0xd07d74c240c6c363 +766, 0x16f62290179d1bbf +767, 0xe99c9bcc9cb1ece7 +768, 0xc64f9be03c8a93be +769, 0x32659effaf666c1f +770, 0x4bb228cfb30b6672 +771, 0x98764870842068a5 +772, 0x5b12ef2d2cd8bdcc +773, 0xbc79d1c1b41f28b8 +774, 0x97a517cf3279fc9a +775, 0x34ffd46c1d4d6025 +776, 0x9c302307ee25c8f0 +777, 0x399604eed1f18a8 +778, 0x1c9b813c2043142a +779, 0x2944ea5e55267fe9 +780, 0x5a8a9f5e728ea667 +781, 0x30c8440adb804a0 +782, 0xee0e6b627099a937 +783, 0x3d50757ada3c52da +784, 0x4548916b32c813ab +785, 0x602a186fe5bf109b +786, 0xf0d440a2227ba304 +787, 0x5a10d4e0ca9ea32b +788, 0x6e5eb90da13ba64c +789, 0x4c6af8fd04241ab2 +790, 0xf9eb31d26e093006 +791, 0x5d674878839fe3ea +792, 0x1562b55b2484e47c +793, 0xa87188c099c1cb61 +794, 0xb7736b8aa02a3392 +795, 0x5f4b301125abb20f +796, 0x361d566984637f44 +797, 0x68c4b3feac8bd0c3 +798, 0x7066c634dd2503c1 +799, 0xfecbf7c9441eb6ea +800, 0xdbc26ae0fc81436b +801, 0x9ef3e2b48252e7a4 +802, 0x31a49b4c339b37c7 +803, 0xb01b2a83cf346cf4 +804, 0xc24dc2347f82fbe3 +805, 0x134cad272dcd410f +806, 0x61260742823ba59c +807, 0x53ac4c193a97c730 +808, 0x9207c9833af34b52 +809, 0xa72e7ee77078d1f5 +810, 0x2e6f6e1b05936885 +811, 0x783b99ce5dbf9464 +812, 0xfdfeb6f0d027bb44 +813, 0x40eeb27096f92b0 +814, 0x5ef96ff5d4a4521f +815, 0x5595806ae873718a +816, 0x67d449eecf4ca1c3 +817, 0xde837ab611364f3f +818, 0x7034c24d2b139be9 +819, 0xe21166603e0a9c86 +820, 0x935694435c1f0d51 +821, 0x6cb3bec90c126088 +822, 0x4096ef662b7a9f89 +823, 0xd2d85b8d238d8c15 +824, 0xa4ea533ce3ec59b2 +825, 0x3654729d80a2db29 +826, 0x214c4cc3906d29d4 +827, 0x201c447e7588e373 +828, 0xe8b8f0ae25f683eb +829, 0x6744aaf5754e38af +830, 0xd1ffb10d6f27a061 +831, 0xe536733a7b3a6c30 +832, 0x39f0f66e47cbf2c9 +833, 0x856a9593526fde2 +834, 0x2e2a817a0098ea4b +835, 0xc5e1eeb551a0e3d3 +836, 0x3f21e2f5e2d50b2 +837, 0x906af56c66dd9f8c +838, 0x30f6dbd70329fac8 +839, 0xc443dfddf3c01a60 +840, 0x7ab85d9aa9675470 +841, 0x8c9080bd39717bfc +842, 0x4b1ccdb3c3597f6f +843, 0x74e2542d70ab5d67 +844, 0xbb3d236aad00f74 +845, 0xcf3cadf9a2804774 +846, 0xe851d9750e42bd07 +847, 0xc0ad82029b1c371f +848, 0x7ee119eb552d6c07 +849, 0xd8024049bd1d784a +850, 0xfa67a899760363 +851, 0xaa7c2f438b178197 +852, 0xc473674a47ffe064 +853, 0x539fbe3fc674c270 +854, 0xdb48484748a76f3b +855, 0xc73b2b092060d +856, 0xa1d2a15345016f5d +857, 0x4d0fe8599f9bba47 +858, 0xa0edc275e6f8f1d1 +859, 0x40590a8655bc8d72 +860, 0x35b4223161f05f75 +861, 0xa04c0c0f616752dc +862, 0x7f371ed2ca45432d +863, 0x2ff1a08f75ac6438 +864, 0xe2dc5c3682282f48 +865, 0xe1e4179fa98d9013 +866, 0x8cb083d6843a73d5 +867, 0xb4c2b5921b706854 +868, 0x738e14c0e7352445 +869, 0xcd2b646f91afd8c7 +870, 0xd5779a5b57a264fd +871, 0xc39ff855586c7d07 +872, 0x3e3f0098c631a859 +873, 0x644e02fae032110 +874, 0xa8834613c0a45278 +875, 0x69482f2c08e10657 +876, 0xe4ee475bdb87e69a +877, 0xdc1ef7b25c0d0019 +878, 0x88a3fa2be18d8744 +879, 0x60a02e0b21c5bec7 +880, 0xb6867b88aa19bc1a +881, 0xb599409affcf10eb +882, 0xaeaa1778a5e59daa +883, 0xd7a91a52c16663e3 +884, 0x93cb269affe07b1c +885, 0x841b6ced3a4ba815 +886, 0x84541768e1540a5c +887, 0xe3943c84f83b3020 +888, 0x5de366fbd7b45258 +889, 0xd787cc3bde91a661 +890, 0x814071446edecb57 +891, 0x15d8c602a1141514 +892, 0x72f07bc8002d1d0d +893, 0x4a8bd8dc9a1f0f3e +894, 0x8723796ae0f20d35 +895, 0xda7283c2051f73b2 +896, 0x2df0cc247f90bd3b +897, 0x79a8522b968f990a +898, 0x951ede190c8b9d02 +899, 0xc512f1a5b14b018a +900, 0xf0e3ddc03b9a4259 +901, 0x8cf4a35ad312e15f +902, 0xebef28926b11094b +903, 0x5628ba687325921c +904, 0xc3aa75e57edc49c3 +905, 0xc38382fa98e762ba +906, 0x8d209e896285848e +907, 0x2c7d6adf592b4a3e +908, 0x62de48e36f8338f3 +909, 0x4a752741e00de30e +910, 0xf7855b70f1f6ec2b +911, 0xa505fa4428199e43 +912, 0xe8b6b423b826bbac +913, 0x4bd1206cf8786d05 +914, 0x6dcf040391fe3bf4 +915, 0x913f500f87e1bba3 +916, 0x5acf775aa180a5d5 +917, 0x74dd28d9432ce739 +918, 0x996c2ff2f0dc2495 +919, 0x73dbfe6c56effe4 +920, 0x56fddd25196f5e40 +921, 0xe87810158f5b7 +922, 0x7b8795e996383f1f +923, 0x9ba5ee7c777c4c82 +924, 0x17ce3908d270fe1c +925, 0x3df9e613c1aedfae +926, 0xcdd26871b32fc8e1 +927, 0xd71cb13afc633979 +928, 0x63427c8ea9b1c79e +929, 0xd070f7664d3b405d +930, 0x46f2a9e32d9fb769 +931, 0xb4c3822a45e9fe9b +932, 0x8ba30b97fe6f5ec7 +933, 0x70aa554ee2fc11f9 +934, 0xa80c99dbe0cfcfaf +935, 0x36d9250cb2d68ed +936, 0x2995e4b9e1cd1db4 +937, 0x4b3803ba57fc570f +938, 0xae3959e7d740eaa5 +939, 0xb4cbd6662adbae08 +940, 0xae46576446e8dbc4 +941, 0xc4828e008a9a8a54 +942, 0x145d7db8e6554b2f +943, 0x1b1b8916a730c371 +944, 0xdaf84b2bebe31963 +945, 0x5b59b80ef23a2403 +946, 0x9180c7e89cab6fd3 +947, 0x80e58f5411babf34 +948, 0xa06cf55185b9b005 +949, 0x13b2c798424173ad +950, 0xc510f8e706311d49 +951, 0x1f974b83b6046d3a +952, 0xae6e8e85e822d1c3 +953, 0x66f2c8dc3274a31a +954, 0x7e04dbcbf65bd377 +955, 0xabf41ede01ec20a4 +956, 0x5efa0948f6bbb2ea +957, 0xbc91c99d8592255 +958, 0xf6d6917911d86d75 +959, 0x85ce273d54e9097a +960, 0xbdfd30f2420fff92 +961, 0x8802f02f610b537c +962, 0xd1d70037ed543229 +963, 0x908aaf97f9693a46 +964, 0x1f6cfeaa0834d53a +965, 0xa453fd1648ce04d2 +966, 0x2c38bb85ebc64af9 +967, 0xd2daff551c90c4f8 +968, 0xae5a0d949797d784 +969, 0xf0974c8552ac9593 +970, 0xa10b70499f65c693 +971, 0x39a449ebd594ddff +972, 0x8ea090f2b17b9b49 +973, 0xc592de318090fd83 +974, 0xb63e4fbc467b6912 +975, 0x57a0c1c5ce0e4dcc +976, 0xa7c517cf3d436b35 +977, 0xef6dcb0f3fad038b +978, 0xaf4fb60315b91287 +979, 0x5e0776f67304f331 +980, 0xe927753b8e6f7932 +981, 0xd3df2dd92559e304 +982, 0xdaed52aa6af44413 +983, 0x1b59f4dac1e181f8 +984, 0x4a73c2293877ef39 +985, 0xca45d0d015fe44de +986, 0x4659c8b7853735a8 +987, 0x12de6466bdf8adeb +988, 0xaeea857a09bfec15 +989, 0xcc9cf4b3c0b88a23 +990, 0xa44ae52396a5e1bf +991, 0x5847a724305d137f +992, 0x8f4d4de223956182 +993, 0x58254dfada867a8 +994, 0x900a98222c2f339e +995, 0xdb575260935d51d5 +996, 0x13fb4bfbbc0d7b53 +997, 0x62213850186bb92b +998, 0x2a34823312c00388 +999, 0x6148329042f743b0 diff --git a/venv/Lib/site-packages/numpy/random/tests/data/philox-testset-1.csv b/venv/Lib/site-packages/numpy/random/tests/data/philox-testset-1.csv new file mode 100644 index 0000000..e448cbf --- /dev/null +++ b/venv/Lib/site-packages/numpy/random/tests/data/philox-testset-1.csv @@ -0,0 +1,1001 @@ +seed, 0xdeadbeaf +0, 0xedc95200e2bd66a5 +1, 0x581d4e43b7682352 +2, 0x4be7278f5e373eab +3, 0xee47f17991a9e7ea +4, 0x38a7d2ae422f2e2c +5, 0xe2a6730a3b4a8a15 +6, 0x1588b7a841486442 +7, 0x13ad777246700504 +8, 0x14d157e0f5e18204 +9, 0xd87c22a7ee8c13f1 +10, 0x30cc389ce3542ba1 +11, 0xb8a53348955bb2e9 +12, 0xc08802e3c454f74f +13, 0xb444f627671a5780 +14, 0x4b6dd42b29cbf567 +15, 0x6109c7dc0bc5f7d5 +16, 0x85c954715d6b5b1e +17, 0x646178d3d9a3a5d5 +18, 0xebbde42b1cd83465 +19, 0x3d015102f6bc9c1a +20, 0x720fe2ec3798d5fd +21, 0x93120961289ceb2e +22, 0xc9207e960a56fae2 +23, 0xa7f042f31d991b98 +24, 0x5fac117415fae74b +25, 0xd0a970ba8dddc287 +26, 0x84b4e7e51b43106 +27, 0x6ad02bf525ea265f +28, 0xcdc7e5992b36ef8f +29, 0x44d4985209261d60 +30, 0x628c02d50f4b902e +31, 0xc7b1914922d1e76d +32, 0xfde99ff895cba51d +33, 0x175a0be050fa985f +34, 0x47297d3699e03228 +35, 0xccf1e9aeaa3339cd +36, 0x9fdd18ebeeaf15b1 +37, 0x7c94c9ab68747011 +38, 0x612d8ef22c1fa80f +39, 0x13f52b860de89ab5 +40, 0x81f264b8c139c43b +41, 0x8d017ba4ef1e85ba +42, 0x6d0556f46219951e +43, 0x8ee7b85663cf67b6 +44, 0x2432fc707645fe67 +45, 0xaf814046051e5941 +46, 0x4d432a83739ac76f +47, 0x59e5060d0983ccdd +48, 0xdd20e828b83d9b53 +49, 0x1b891800d7385f4c +50, 0x10e86a026c52ff5e +51, 0xb932f11723f7b90c +52, 0xb2413d0a1f3582d0 +53, 0xe7cd4edda65fc6b5 +54, 0x6d3808848d56593b +55, 0x192a727c3c7f47d9 +56, 0x9659d8aea5db8c16 +57, 0x4242c79fe2c77c16 +58, 0x605f90c913827cea +59, 0x53e153c8bfc2138a +60, 0xed2158fbdef5910e +61, 0xae9e6e29d4cb5060 +62, 0x7dd51afaad3b11ce +63, 0x2b9ba533d01a5453 +64, 0x7e0e9cf2b6c72c8 +65, 0x1cc8b3c7747ed147 +66, 0x9b102651e2e11b48 +67, 0x30b0b53cbaac33ea +68, 0x70c28aec39b99b85 +69, 0x5f1417ff536fdb75 +70, 0x3a1d91abd53acf58 +71, 0xba116a1772168259 +72, 0xf5369bc9bd284151 +73, 0x67bf11373bf183ca +74, 0xef0b2d44dbd33dc7 +75, 0xbfd567ee1a2953ed +76, 0x7d373f2579b5e5c6 +77, 0x756eeae7bcdd99be +78, 0x75f16eb9faa56f3b +79, 0x96d55ded2b54b9a5 +80, 0x94495191db692c24 +81, 0x32358bdd56bab38c +82, 0x3f6b64078576579 +83, 0x7177e7948bc064c9 +84, 0x2cbf23f09ba9bc91 +85, 0x9b97cc31c26645f5 +86, 0x5af2d239ff9028b1 +87, 0x316fa920e0332abe +88, 0x46535b7d1cae10a0 +89, 0x21f0a6869298022c +90, 0xf395c623b12deb14 +91, 0x8573995180675aa7 +92, 0xc3076509f4dc42d5 +93, 0x15e11e49760c6066 +94, 0xe8a6d311e67a021d +95, 0x7482f389c883339b +96, 0xda6f881573cba403 +97, 0xb110ffb847e42f07 +98, 0x2c3393140605ccf9 +99, 0xba1c8ba37d8bdc33 +100, 0x59adf43db7a86fe0 +101, 0xb4fcbf6aa585ca85 +102, 0xd794a93c18033fa6 +103, 0x6e839c01985f9d4 +104, 0x64065bf28222b2c7 +105, 0x6a6359b293fa0640 +106, 0x5ff610969e383e44 +107, 0xa8172c263f05c7f7 +108, 0x62a0172e8bd75d07 +109, 0x7be66e3c453b65ac +110, 0x6a3b8d5a14014292 +111, 0xa2583e6087450020 +112, 0xd5d3ecc480c627d2 +113, 0xa24e83f1eec8a27c +114, 0xa23febd2a99ee75a +115, 0x9a5fbf91c7310366 +116, 0x5b63156932e039b +117, 0x942af3c569908505 +118, 0x89a850f71ab6a912 +119, 0xfeadc803ac132fe9 +120, 0x67bf60e758250f3 +121, 0x533c25103466a697 +122, 0xb7deede3482f9769 +123, 0x325e043b53bba915 +124, 0x9e8d9e7fde132006 +125, 0x6bacc6860bbc436e +126, 0xb3ea0534c42b1c53 +127, 0xb2389334db583172 +128, 0xa74b1bfbf5242ee4 +129, 0x53a487e2dc51d15c +130, 0xe5a3b538d2c7a82e +131, 0x7b6c70bb0c4cadaf +132, 0xae20791b2081df1 +133, 0xc685c12e3c61d32c +134, 0x60110e6b0286e882 +135, 0x49682119c774045c +136, 0x53dc11a3bbd072e +137, 0xbdc87c6e732d9c2d +138, 0xcc4620861ebac8fd +139, 0x7e9c3558759350cc +140, 0x157408dee34891ba +141, 0x9bcad1855b80651b +142, 0xd81b29141d636908 +143, 0x1ed041a9f319c69d +144, 0x805b2f541208b490 +145, 0x484ef3bba2eb7c66 +146, 0xb6b5e37d50a99691 +147, 0xabc26a7d9e97e85f +148, 0xcba2a3cce0417c2f +149, 0xa030dfffd701993c +150, 0x2bf2dc50582ebf33 +151, 0xd9df13dd3eb9993e +152, 0x31ca28b757232ae5 +153, 0x614562a0ccf37263 +154, 0x44d635b01725afbb +155, 0x5ae230bc9ca9cd +156, 0xb23a124eb98705c6 +157, 0x6395675444981b11 +158, 0xd97314c34119f9ca +159, 0x9de61048327dd980 +160, 0x16bac6bded819707 +161, 0xcea3700e3e84b8c7 +162, 0xaa96955e2ee9c408 +163, 0x95361dcc93b5bc99 +164, 0x306921aed3713287 +165, 0x4df87f3130cd302a +166, 0x37c451daeb6a4af5 +167, 0x8dbbe35f911d5cc1 +168, 0x518157ce61cb10f9 +169, 0x669f577aebc7b35b +170, 0x4b0a5824a8786040 +171, 0x519bc3528de379f5 +172, 0x6128012516b54e02 +173, 0x98e4f165e5e6a6dd +174, 0x6404d03618a9b882 +175, 0x15b6aeb3d9cd8dc5 +176, 0x87ed2c1bae83c35b +177, 0x8377fc0252d41278 +178, 0x843f89d257a9ba02 +179, 0xcdda696ea95d0180 +180, 0xcfc4b23a50a89def +181, 0xf37fd270d5e29902 +182, 0xafe14418f76b7efa +183, 0xf984b81577076842 +184, 0xe8c60649ccb5458d +185, 0x3b7be8e50f8ff27b +186, 0xaa7506f25cef1464 +187, 0x5e513da59f106688 +188, 0x3c585e1f21a90d91 +189, 0x1df0e2075af292a +190, 0x29fdd36d4f72795f +191, 0xb162fe6c24cb4741 +192, 0x45073a8c02bd12c4 +193, 0xcbaaa395c2106f34 +194, 0x5db3c4c6011bc21c +195, 0x1b02aac4f752e377 +196, 0xa2dfb583eb7bec5 +197, 0xfe1d728805d34bb1 +198, 0xf647fb78bb4601ec +199, 0xd17be06f0d1f51ef +200, 0x39ec97c26e3d18a0 +201, 0xb7117c6037e142c8 +202, 0xe3a6ce6e6c71a028 +203, 0xe70a265e5db90bb2 +204, 0x24da4480530def1e +205, 0xfd82b28ce11d9a90 +206, 0x5bf61ead55074a1d +207, 0xbe9899c61dec480d +208, 0xae7d66d21e51ec9e +209, 0x384ee62c26a08419 +210, 0x6648dccb7c2f4abf +211, 0xc72aa0c2c708bdc9 +212, 0x205c5946b2b5ba71 +213, 0xd4d8d0b01890a812 +214, 0x56f185493625378d +215, 0x92f8072c81d39bd0 +216, 0xa60b3ceecb3e4979 +217, 0xfcf41d88b63b5896 +218, 0xf5a49aa845c14003 +219, 0xffcc7e99eee1e705 +220, 0xdd98312a7a43b32d +221, 0xa6339bd7730b004 +222, 0xdac7874ba7e30386 +223, 0xadf6f0b0d321c8 +224, 0x126a173ae4ffa39f +225, 0x5c854b137385c1e7 +226, 0x8173d471b1e69c00 +227, 0x23fa34de43581e27 +228, 0x343b373aef4507b1 +229, 0xa482d262b4ea919c +230, 0xf7fbef1b6f7fbba +231, 0xd8ce559487976613 +232, 0xbf3c8dd1e6ebc654 +233, 0xda41ed375451e988 +234, 0xf54906371fd4b9b3 +235, 0x5b6bb41231a04230 +236, 0x866d816482b29c17 +237, 0x11315b96941f27dc +238, 0xff95c79205c47d50 +239, 0x19c4fff96fbdac98 +240, 0xbfb1ae6e4131d0f4 +241, 0x9d20923f3cdb82c9 +242, 0x282175507c865dff +243, 0xdfd5e58a40fe29be +244, 0xedbd906ff40c8e4f +245, 0x11b04fc82614ccb3 +246, 0xeceb8afda76ae49f +247, 0xa4856913847c2cdf +248, 0x6f1425f15a627f2a +249, 0xdf144ffedf60349e +250, 0x392d7ecfd77cc65f +251, 0x72b8e2531049b2c6 +252, 0x5a7eb2bdb0ec9529 +253, 0xdcfd4306443e78c1 +254, 0x89ad67ed86cd7583 +255, 0x276b06c0779a6c8f +256, 0xb2dbb723196a0ac3 +257, 0x66c86a3b65906016 +258, 0x938348768a730b47 +259, 0x5f5282de938d1a96 +260, 0xa4d4588c4b473b1f +261, 0x8daed5962be4796f +262, 0x9dde8d796985a56e +263, 0x46be06dbd9ed9543 +264, 0xdf98286ceb9c5955 +265, 0xa1da1f52d7a7ca2b +266, 0x5a7f1449f24bbd62 +267, 0x3aedc4e324e525fd +268, 0xced62464cd0154e1 +269, 0x148fc035e7d88ce3 +270, 0x82f8878948f40d4c +271, 0x4c04d9cdd6135c17 +272, 0xdf046948d86b3b93 +273, 0x2f0dec84f403fe40 +274, 0xa61954fb71e63c0d +275, 0x616d8496f00382e8 +276, 0x162c622472746e27 +277, 0x43bcfe48731d2ceb +278, 0xff22432f9ff16d85 +279, 0xc033ed32bb0ad5a4 +280, 0x5d3717cc91c0ce09 +281, 0x7a39a4852d251075 +282, 0x61cd73d71d6e6a6 +283, 0xe37e2ea4783ab1a5 +284, 0x60e1882162579ea8 +285, 0x9258ec33f1a88e00 +286, 0x24b32acf029f0407 +287, 0x1410fc9aea6d3fac +288, 0x6054cf2a3c71d8f7 +289, 0x82f7605157a66183 +290, 0x3b34c1c0dff9eac5 +291, 0xfebe01b6d5c61819 +292, 0x7372187c68b777f2 +293, 0xc6923812cda479f0 +294, 0x386613be41b45156 +295, 0x92cfebe8cc4014b +296, 0x8e13c4595849828b +297, 0x90e47390d412291f +298, 0x6b21a1d93d285138 +299, 0xbf5b1f5922f04b12 +300, 0x21e65d1643b3cb69 +301, 0xf7683b131948ac3c +302, 0xe5d99fc926196ed2 +303, 0x7b138debbec90116 +304, 0x8a2650a75c2c2a5c +305, 0x20689a768f9b347b +306, 0xdfa2900cfb72dc6e +307, 0x98959c3855611cc2 +308, 0x5fdb71b89596cc7c +309, 0x1c14ac5c49568c7b +310, 0x958c4293016091fe +311, 0x7484522eb0087243 +312, 0xc4018dfb34fc190f +313, 0xca638567e9888860 +314, 0x102cd4805f0c0e89 +315, 0xcc3bc438e04548f8 +316, 0xb808944bb56ea5be +317, 0xffd4778dbf945c57 +318, 0xfe42617784c0233b +319, 0x3eccbfeae9b42d3c +320, 0xd9f1b585fd0bfa60 +321, 0x5c063d1b2705d5dd +322, 0x8e8bec3519941b64 +323, 0x9e94c36cbec2a42 +324, 0x1cd19f5b64ffd3ad +325, 0x9632e3aebfc68e66 +326, 0x98960c2d9da4ae45 +327, 0xb76994b1f2bbfc1f +328, 0xca184a737d3971cc +329, 0x964d31b07183adfb +330, 0xe9e0ff351cd276d4 +331, 0xb5747c860b05bbe4 +332, 0x5549ddc3bd3862e2 +333, 0x495496677b27873b +334, 0x53910baa26e3ea18 +335, 0xaa07a07ad0a688d3 +336, 0xbb43bd1f09ecdb1e +337, 0xe2ebc105699dd84 +338, 0x6e815a2729584035 +339, 0x2caab1713b17948a +340, 0x43d39d209fa41c90 +341, 0xfe3e71089d5d1c3a +342, 0xa778646c32f81177 +343, 0x8d42bfb86e6e92d5 +344, 0x175571f70b4fcfbe +345, 0x2a66a6fe10dc3b5b +346, 0xd9545e85235ca709 +347, 0x5642781c77ced48a +348, 0x24facc40b72ccd09 +349, 0xa800fbacce33f6f8 +350, 0x675f58a0ff19fba +351, 0x35aedf57bb5cde1b +352, 0xe5535a6b63f6d068 +353, 0x84dffd0102aaa85d +354, 0x621faad65467aaa7 +355, 0x596ad85b556b112f +356, 0x837545fff8894c7a +357, 0x3d9a4ae1356bc6a6 +358, 0xcd8b7153205d4ad0 +359, 0x98afdd40f1ed09a6 +360, 0xa38b2dc55a5cf87f +361, 0x484aecce2b6838bc +362, 0x6af05c26bdab18d9 +363, 0xf418b7399dcf2e4b +364, 0x1cfa38789b0d2445 +365, 0xfbed23c34166ee67 +366, 0x38e6820039e4912a +367, 0x1fe94911e963591e +368, 0x1291c79aee29ad70 +369, 0x65eccfc89506f963 +370, 0x7d14de3b2f55b1f6 +371, 0x82eb79c36cd2a739 +372, 0x41ffe3b75ea0def5 +373, 0x9eba9156470a51d9 +374, 0xd17c00b981db37d1 +375, 0xf688769a75601aa7 +376, 0xbcf738e9e03d571e +377, 0x14712e56df8f919b +378, 0xab14e227d156e310 +379, 0xf53d193e993e351e +380, 0x857fae46bd312141 +381, 0xc2dd71e41b639966 +382, 0x74f8b987a3d00ad1 +383, 0x5bce8526dc527981 +384, 0x94910926c172a379 +385, 0x503c45557688a9d5 +386, 0x244d03834e05807f +387, 0x6e014cbab9c7a31f +388, 0xae544c638530facf +389, 0x9b853aaaf9cbc22d +390, 0xfb42ab7024d060ed +391, 0x74cc3fba0dfd7ff2 +392, 0x24ec9e8f62144ad5 +393, 0x72f082954307bbe7 +394, 0x36feda21bbf67577 +395, 0x3222191611b832f1 +396, 0xd0584e81bcac8b0b +397, 0xdce8d793ef75e771 +398, 0x978824c6c2578fc +399, 0x6e8f77503b3c2ee4 +400, 0xc85d2d86fecf5d03 +401, 0x3d35b4a5d4d723c4 +402, 0xd3987dfd4727fff3 +403, 0xd3cde63fb6a31add +404, 0xf6699e86165bdaeb +405, 0x9d60ba158ec364c4 +406, 0x920c3c18b346bfc9 +407, 0x770fd1fdfbc236ca +408, 0x45998cfc5fc12ddd +409, 0xd74a3454e888834b +410, 0xbf2aa68081a4a28f +411, 0xea41b26a6f1da1b3 +412, 0x5560a2d24b9d5903 +413, 0xe3791f652a228d8b +414, 0x365116d3b5a8520c +415, 0xb1b2bd46528f8969 +416, 0xfcfe14943ef16ae7 +417, 0xf4d43425e8a535dc +418, 0xe6cf10a78782a7e0 +419, 0x9c7ac0de46556e3e +420, 0xc667ae0856eed9ef +421, 0x47dbb532e16f9c7e +422, 0xdf4785a5d89ee82e +423, 0xbd014925ce79dbcf +424, 0xea0d663fb58fa5be +425, 0x51af07d5cc3821fb +426, 0x27a1bdcdc4159a9d +427, 0x520c986c59b1e140 +428, 0x50b73fd9bacd5b39 +429, 0xae5240641f51e4f3 +430, 0x71faecc164ed9681 +431, 0xda95aa35529a7ee +432, 0xe25ba29b853c1c6d +433, 0x9871a925cda53735 +434, 0xde481ad8540e114d +435, 0xa2997f540e8abca0 +436, 0xc9683c5035e28185 +437, 0x1082471b57182bac +438, 0xbd3ecf0f0b788988 +439, 0xf479760776fbb342 +440, 0x3730929200d91f44 +441, 0xc1762d79ae72809c +442, 0xfaa0a4c7b1686cb3 +443, 0xd581e6d55afdafcd +444, 0x6cf57bdfba2dcf6d +445, 0xdef79d9fe6a5bcef +446, 0x13ed376e18132bd3 +447, 0xbe67efd72defa2a +448, 0x5acc176c468966ea +449, 0x8b35b626af139187 +450, 0x446de3fac0d973ac +451, 0xe1d49e06dc890317 +452, 0x817bc3fd21fc09b7 +453, 0xb71c3958a13d5579 +454, 0x8746e010f73d7148 +455, 0x1b61c06009922e83 +456, 0xba17e62e6b092316 +457, 0x1375fa23c4db8290 +458, 0x3f071230f51245a6 +459, 0x51c99a086a61cd13 +460, 0x5f0f2ae78589e1fd +461, 0x604834e114bbbc27 +462, 0x5eb2a7a34814e9a9 +463, 0x77a6907f386bf11e +464, 0x99525de2bd407eeb +465, 0xb818348c57b3b98f +466, 0x25f5f9e702fbe78d +467, 0x8f66669e6f884473 +468, 0x1e47d46e2af4f919 +469, 0xf6a19df846476833 +470, 0xff00c67bcd06621f +471, 0xe3dfe069795d72d8 +472, 0x8affc88b2fea4d73 +473, 0x66df747e5f827168 +474, 0xf368ec338d898a0e +475, 0x9e1f1a739c5984a2 +476, 0x46a1c90e1ca32cbc +477, 0xc261bc305ed8d762 +478, 0x754d7949f7da9e72 +479, 0x4c8fbbb14ef47b17 +480, 0xccbdc67a3848d80d +481, 0x3c25e6f58bae751d +482, 0x7078b163b936d9b6 +483, 0x440e27463c134ecf +484, 0x6c83ee39f324db0f +485, 0x27cf901b22aea535 +486, 0x57262dec79a3f366 +487, 0x91db09f1dbb524fb +488, 0xd7436eefba865df2 +489, 0x16c86b0a275a3f43 +490, 0x689493e6681deaa9 +491, 0x7e1dc536c1a9ac42 +492, 0x1145beac3ac7f5cc +493, 0x3d05e211a104b2b0 +494, 0x4f9e77ced3c52f44 +495, 0x53de1369354add72 +496, 0x1fb60f835f47cdeb +497, 0x6ab36f089e40c106 +498, 0xaabffcb0d3d04c7 +499, 0xaa399686d921bd25 +500, 0x2bf8dd8b6d6fa7f0 +501, 0x1ddbf4e124329613 +502, 0x466a740241466a72 +503, 0x98d7381eb68a761 +504, 0x817691510bc4857a +505, 0x8837622c0171fe33 +506, 0xcba078873179ee16 +507, 0x13adad1ab7b75af4 +508, 0x3bac3f502428840c +509, 0xbeb3cce138de9a91 +510, 0x30ef556e40b5f0b4 +511, 0x19c22abdf3bbb108 +512, 0x977e66ea4ddc7cf +513, 0x9f4a505f223d3bf3 +514, 0x6bc3f42ac79ec87b +515, 0x31e77712158d6c23 +516, 0x6d8de4295a28af0d +517, 0xee1807dbda72adb7 +518, 0xda54140179cd038f +519, 0x715aa5cdac38e062 +520, 0x5a7e55e99a22fa16 +521, 0xf190c36aa8edbe4f +522, 0xccadd93a82c1d044 +523, 0x7070e6d5012c3f15 +524, 0x50a83341a26c1ba5 +525, 0x11bca7cc634142e5 +526, 0x623a0d27867d8b04 +527, 0x75c18acff54fbf6e +528, 0x455ae7d933497a6f +529, 0xf624cf27d030c3d3 +530, 0x7a852716f8758bac +531, 0xe7a497ac1fa2b5b4 +532, 0xf84f097498f57562 +533, 0xc4bb392f87f65943 +534, 0x618e79a5d499fbfb +535, 0xb3c0b61d82b48b8 +536, 0x4750a10815c78ea7 +537, 0x9cf09cca3ddece69 +538, 0x2a69f1c94cc901a2 +539, 0x347a0e446e1ce86d +540, 0xb06f3a5a5ab37bb1 +541, 0x8035bd0713d591db +542, 0x539c9637042c3a1f +543, 0xd7ba4dc6b273cbd7 +544, 0x12f3f99933444f85 +545, 0x4a9517b9783fb9a4 +546, 0x6422b2ea95093bc5 +547, 0x3a5ecff0f996c2a6 +548, 0x31de504efc76a723 +549, 0x7ccb7c5233c21a9f +550, 0xc687d9e6ce4186e8 +551, 0x6e40769d6940376a +552, 0xf51207314f1f7528 +553, 0x67ee3acb190865e3 +554, 0xe08d586270588761 +555, 0xe387fa489af1a75c +556, 0x73414a52d29d8375 +557, 0x671a38191cf2a357 +558, 0xe00fb25b1aa54008 +559, 0x11a0610e22cf549b +560, 0xc90cc865d57c75be +561, 0x90d0863cc15f2b79 +562, 0x8b3e60d32ebcb856 +563, 0xb28cc55af621e04a +564, 0xcf60bd3cb2a5ab1d +565, 0x212cb5d421948f86 +566, 0xee297b96e0a3363f +567, 0x4e9392ff998760d1 +568, 0x61940c8d0105ba3e +569, 0x14ebcbae72a59a16 +570, 0xdf0f39a3d10c02af +571, 0xfc047b2b3c1c549d +572, 0x91718b5b98e3b286 +573, 0x9ea9539b1547d326 +574, 0x7a5a624a89a165e6 +575, 0x145b37dcaa8c4166 +576, 0x63814bbb90e5616c +577, 0xc4bc3ca6c38bb739 +578, 0x853c3a61ddc6626c +579, 0xa7ce8481c433829a +580, 0x8aff426941cc07b +581, 0x2dc3347ca68d8b95 +582, 0xce69f44f349e9917 +583, 0x2fa5cb8aca009b11 +584, 0xf26bb012115d9aca +585, 0xafa01c2f2d27235a +586, 0xabcba21f1b40305e +587, 0xfec20c896c0c1128 +588, 0xc5f7a71ebacadfa0 +589, 0xc8479ad14bab4eef +590, 0xad86ec9a3e7d3dc +591, 0xbbecd65292b915c5 +592, 0xb1f9e28149e67446 +593, 0x708d081c03dad352 +594, 0xaa8a84dbd1de916c +595, 0x9aa3efb29ba9480b +596, 0xd3c63969ff11443e +597, 0x1e9e9ac861315919 +598, 0x4fe227f91e66b41d +599, 0xefc0212d43d253ab +600, 0x98341437727c42d1 +601, 0x5ea85c0fe9008adc +602, 0x7891b15faa808613 +603, 0x32db2d63989aacfd +604, 0xc92f7f28e88fd7bc +605, 0x3513545eb6549475 +606, 0x49abe0082906fbf8 +607, 0xcee1e1a6551e729c +608, 0x38556672b592a28e +609, 0xc3e61409c4ec2d45 +610, 0x96c67ce2995a0fd4 +611, 0x9b9b0cada870293 +612, 0x82d6dd5dada48037 +613, 0xeea4f415299f1706 +614, 0x371107895f152ab3 +615, 0x2f6686159f4396bb +616, 0x61005a2ff3680089 +617, 0x9d2f2cafb595e6b6 +618, 0x4a812a920f011672 +619, 0x317554d3a77385d7 +620, 0x24c01086727eb74b +621, 0xa15ff76d618a3a9e +622, 0x2121bfd983859940 +623, 0x384d11577eea8114 +624, 0xab0f4299f3c44d88 +625, 0x136fd4b07cfa14d9 +626, 0x665fe45cbfaa972a +627, 0x76c5a23398a314e9 +628, 0x5507036357ccda98 +629, 0xd9b8c5ac9dce632b +630, 0x366bc71781da6e27 +631, 0xdd2b2ba1d6be6d15 +632, 0xf33ed0d50ea6f1a6 +633, 0xf05a9b1900174c18 +634, 0x3947e1419e2787cf +635, 0x6c742b1e029637d0 +636, 0x32aba12196a0d2e8 +637, 0x1b94aab2e82e7df +638, 0x68b617db19229d6 +639, 0x6c88a95ac0a33f98 +640, 0xdc9b95fd60c2d23e +641, 0x999e6971d3afc8b3 +642, 0x7071fc6ad8b60129 +643, 0x41a8184ef62485f6 +644, 0xb68e0605c7d5e713 +645, 0x272b961a1d1bbee +646, 0x23f04e76446187b0 +647, 0x999a7a8f6d33f260 +648, 0xdbd6318df4f168d +649, 0x8f5e74c84c40711e +650, 0x8ccc6b04393a19d6 +651, 0xadcd24b782dd8d3d +652, 0x1a966b4f80ef9499 +653, 0xcb6d4f9ff5a280f0 +654, 0x8095ff2b8484018a +655, 0xbfd3389611b8e771 +656, 0x278eb670b7d12d51 +657, 0x31df54ca8d65c20f +658, 0x121c7fb38af6985e +659, 0x84fb94f38fe1d0a +660, 0x15ae8af1a6d48f02 +661, 0x8d51e4a62cba1a28 +662, 0x58e6b6b3ae0f9e42 +663, 0x9365a0a85669cc99 +664, 0xe56e92f65a2106df +665, 0x68fa299c66b428fc +666, 0x55e51bb0b0a832c6 +667, 0x48b565293f9bc494 +668, 0x73d8132b1cbabb57 +669, 0x9178ac3926c36cbc +670, 0xe2f22c7b28ea5e0f +671, 0x6af45322a99afb12 +672, 0x59072fcb486a46f4 +673, 0x166b717b08d3d8e +674, 0xd4e627a2dfacc4ab +675, 0x33dad6f2921dedaa +676, 0x4b13b806834a6704 +677, 0xe5f7971b398ed54d +678, 0x20bfae65e3e6899b +679, 0x881dab45d2b4fc98 +680, 0x6f248126b5b885be +681, 0x7aeb39e986f9deee +682, 0xf819f9574b8c3a03 +683, 0xff3d93ed6bd9781a +684, 0x3a31e2e24a2f6385 +685, 0x7888a88f8944a5e +686, 0x4faee12f5de95537 +687, 0x7f3e4efccdb2ed67 +688, 0x91e0f2fc12593af5 +689, 0xb5be8a4b886a40d3 +690, 0x998e8288ac3a9b1b +691, 0x85c48fc8b1349e7b +692, 0xf03af25222d8fae5 +693, 0x45467e805b242c2e +694, 0xa2350db793dbebdc +695, 0xfebe5b61d2174553 +696, 0xa9a331f02c54ad0b +697, 0xe94e49a0f905aef3 +698, 0xe54b4c812b55e3da +699, 0xdc454114c6bc0278 +700, 0x99c7765ab476baa2 +701, 0xccd9590e47fdff7c +702, 0xfa2bcae7afd6cb71 +703, 0x2c1bf1a433a6f0f7 +704, 0x53882c62ff0aab28 +705, 0x80ac900f844dacc +706, 0x27ba8eb5c4a44d54 +707, 0x78f3dfb072a46004 +708, 0x34e00e6ec629edce +709, 0x5b88d19b552d1fbd +710, 0xe4df375dc79df432 +711, 0x37446312ff79c3b4 +712, 0xb72256900a95fa6d +713, 0x89f3171fbdff0bfc +714, 0xd37885b048687eba +715, 0xbb033213b283b60e +716, 0xcf10b523ee769030 +717, 0xbf8070b6cfd7bafb +718, 0xb7194da81fd1763b +719, 0xbfc303de88e68d24 +720, 0xb949c7a5aea8a072 +721, 0x844216e7bae90455 +722, 0xf1e7f20840049a33 +723, 0x96e3263ad0cae794 +724, 0x10772d51f6e9ba49 +725, 0xcea24fccae9d23b3 +726, 0xefd378add9dde040 +727, 0xba0c7c5275805976 +728, 0x2e2a04608f64fa8c +729, 0xafb42ec43aa0fa7 +730, 0x30444b84241ac465 +731, 0x19ef384bac4493ab +732, 0xfd1ac615d3ba5ab9 +733, 0x6cc781ba38643aff +734, 0x30ff27ebed875cfd +735, 0xee1a261aca97ae62 +736, 0xc5a92715202bc940 +737, 0x9e6ec76f93c657ff +738, 0x9b9fd55f55191ca5 +739, 0x654b13af008d8f03 +740, 0x1b7f030d9bd0719f +741, 0x6d622e277550cb7f +742, 0x3f8ee6b8830d0538 +743, 0x475462bcd0de190f +744, 0x21380e8a513bdbcd +745, 0x629bf3771b1bd7a4 +746, 0x3b5fd0b62c353709 +747, 0xf95634006ec3867e +748, 0x1be8bb584a6653c2 +749, 0x2e2d3cfa85320ce8 +750, 0x5b904b692252d11d +751, 0x4bfd76631d527990 +752, 0xc019571ca2bec4a0 +753, 0xf2eb730cea4cd751 +754, 0xd4571d709530191a +755, 0x3b5bd947061f5a7d +756, 0x56e2322cd2d1d1c0 +757, 0xa8830a5f62019f83 +758, 0x901d130c1b873cf3 +759, 0xb5dd29b363c61299 +760, 0xbb710bec3a17b26d +761, 0xc0c464daca0f2328 +762, 0x4dc8055df02650f5 +763, 0x3d3cd9bbe8b957af +764, 0xdb79612c2635b828 +765, 0xe25b3a8ad8fa3040 +766, 0xd5875c563cbf236b +767, 0x46861c1c3849c9bc +768, 0xf84bf1a2814dff43 +769, 0x6d8103902e0ad5e6 +770, 0x99f51c9be8af79e5 +771, 0xb0bfa8540ff94a96 +772, 0xaf45109a4e06f7d0 +773, 0x281df3e55aea9bfc +774, 0x6a1155ca8aa40e60 +775, 0x754d32c5de1f5da +776, 0xce1eafb1c6ca916f +777, 0xc4f2185fa8577bd1 +778, 0x4a188e9bdb5501d9 +779, 0xbb14107e99bd5550 +780, 0xf0381d8425ec2962 +781, 0x213dbfffc16ec4f6 +782, 0x7a999c5a28ea65bc +783, 0x23758c2aba7709ff +784, 0xea7e4bb205e93b44 +785, 0x9c5a31e53911c658 +786, 0x7f04d0bbdc689ddc +787, 0xe3ed89ab8d78dcb3 +788, 0x73c38bfb43986210 +789, 0x740c7d787eb8e158 +790, 0x5284fafdfb3fb9ec +791, 0x2e91a58ac1fb1409 +792, 0xb94a600bf0a09af3 +793, 0x533ea4dbe07d81dd +794, 0x48c3f1a736b3c5fd +795, 0x56ae3499fa8720ce +796, 0x526f2def663ca818 +797, 0x2f085759c65665c4 +798, 0xf715f042c69e0db4 +799, 0x110889c399231e60 +800, 0x64584a244866f3a0 +801, 0xf02ec101a39405d3 +802, 0xe73cd5e9a7f17283 +803, 0xfea64869e7028234 +804, 0x97559974ad877891 +805, 0xc8695aba1dc9f2e5 +806, 0x7b62b76ffc2264ec +807, 0xf5e1df172ec5ccd +808, 0xafaeb68765e443bd +809, 0xd3870eb2e8337623 +810, 0x4f944d684138fb39 +811, 0x6977c575038916ad +812, 0x8ada1a225df95a56 +813, 0xe4044c6c58d15e54 +814, 0x4e5121366681cf2 +815, 0xcf8640b079357b0d +816, 0xcd5b157d44106fa3 +817, 0x9d7a5481279e25a1 +818, 0xe10e9db41fb4b34f +819, 0x1052607be1eadff9 +820, 0x3403d67232fe2265 +821, 0xac9358f498c34afc +822, 0x820172da0dc39c9 +823, 0xe186e91a3b826b6a +824, 0x1a838e2a40284445 +825, 0x1870b617ebd7bce6 +826, 0xcb7cba4424be1ed7 +827, 0x6a2e56e40fdf9041 +828, 0xace93bbe108f97ee +829, 0xfeb9bc74ac41ca08 +830, 0x8cb2d05b0f6a1f51 +831, 0x73792309f3fac0a9 +832, 0x2507343d431308ca +833, 0xd0ea1197be615412 +834, 0xb1870812f1d2fa94 +835, 0x6d067b6935dcd23e +836, 0xaf161014e5492c31 +837, 0xd4be0dce97064be4 +838, 0xf8edfe3fc75c20f1 +839, 0x894751dc442d2d9c +840, 0xb4a95f6a6663456c +841, 0x74e93162e2d805db +842, 0x784bc5f3a7a2f645 +843, 0xd234d7c5b0582ea9 +844, 0x491f28d0ab6cb97c +845, 0xa79419e5cf4336c3 +846, 0x66b00141978c849 +847, 0xa7ddbd64698d563f +848, 0xefc33a4a5d97d4b2 +849, 0x95075514a65aebdc +850, 0x40eca5b3e28cd25e +851, 0x90ec7d00e9c9e35d +852, 0x63e84104d5af417a +853, 0xdaca0ea32df5744 +854, 0x7ed54f2587795881 +855, 0x5a73931760af4ee0 +856, 0x857d1a185a3081ec +857, 0x6eac2aabe67fb463 +858, 0xd1f86155d8bfc55f +859, 0x6d56398f3e7877ef +860, 0x7642f61dfc62bc17 +861, 0x1d76b12843246ffa +862, 0xde7817809b8a31d0 +863, 0xbcca9cd091198f9d +864, 0xf71ca566dddcdfd4 +865, 0xea4386ee8b61d082 +866, 0xe351729d6010bac4 +867, 0xfd685d8a49910dd6 +868, 0xa7a20ea6c686bd3 +869, 0x1cdaf82f4dbd5536 +870, 0xa3da1d1e77dda3e0 +871, 0x4f723b3818ff8b2a +872, 0x1290669eca152469 +873, 0xb54158b52d30651b +874, 0xc06b74f2c7f0fee +875, 0x7d5840bcbf702379 +876, 0x19fa4c1254a82ed +877, 0xcf5ce090ad0b38ea +878, 0xd4edd6ac9437e16d +879, 0xc6ebf25eb623b426 +880, 0xd2b6dbdf00d8fea2 +881, 0x949cf98391cc59e1 +882, 0x380a0c7d0356f7b3 +883, 0x8ffefe32465473bf +884, 0x637b6542d27c861e +885, 0x347d12ffc664ecd9 +886, 0xea66e3a0c75a6b37 +887, 0xc3aff6f34fb537a1 +888, 0x67bdf3579959bf49 +889, 0xa17a348e3a74b723 +890, 0x93c9ef26ddadd569 +891, 0x483909059a5ac0b2 +892, 0x26ec9074b56d5a0d +893, 0x6216000d9a48403a +894, 0x79b43909eab1ec05 +895, 0xe4a8e8d03649e0de +896, 0x1435d666f3ccdc08 +897, 0xb9e22ba902650a0e +898, 0x44dffcccc68b41f8 +899, 0x23e60dcc7a559a17 +900, 0x6fd1735eacd81266 +901, 0xf6bda0745ea20c8e +902, 0x85efcaefe271e07c +903, 0x9be996ee931cef42 +904, 0xe78b41c158611d64 +905, 0xd6201df605839830 +906, 0x702e8e47d2769fd3 +907, 0xb8dcf70e18cf14c +908, 0xac2690bab1bf5c17 +909, 0x92b166b71205d696 +910, 0xb0e73c795fc6df28 +911, 0x4bf2322c8b6b6f0d +912, 0xa842fbe67918cea0 +913, 0xb01a8675d9294e54 +914, 0xfbe3c94f03ca5af2 +915, 0x51a5c089600c441f +916, 0x60f0fd7512d85ded +917, 0xef3113d3bc2cadb0 +918, 0xe1ea128ade300d60 +919, 0xde413b7f8d92d746 +920, 0xfc32c6d43f47c5d8 +921, 0x69d551d8c2b54c68 +922, 0xb9bc68c175777943 +923, 0xb9c79c687f0dae90 +924, 0xd799421ef883c06e +925, 0xbff553ca95a29a3e +926, 0xfc9ffac46bd0aca1 +927, 0x4f6c3a30c80c3e5a +928, 0x8b7245bc6dc4a0a +929, 0xaf4e191a4575ff60 +930, 0x41218c4a76b90f0b +931, 0x986052aa51b8e89b +932, 0x284b464ed5622f9 +933, 0xba6bded912626b40 +934, 0x43cad3ed7443cb5c +935, 0x21641fa95725f328 +936, 0x6d99d6d09d755822 +937, 0x8246dfa2d4838492 +938, 0xd2ee70b9056f4726 +939, 0x87db515a786fbb8b +940, 0x7c63e4c1d7786e7d +941, 0xd1a9d548f10b3e88 +942, 0xa00856475f3b74c9 +943, 0x7f1964ce67148bf4 +944, 0x446650ec71e6018c +945, 0xb1805ca07d1b6345 +946, 0x869c0a1625b7271b +947, 0x79d6da06ce2ecfe2 +948, 0xec7b3cafc5e3c85f +949, 0x1745ce21e39f2c3d +950, 0xd9a0a7af6ee97825 +951, 0x680e0e52a6e11d5c +952, 0xd86b3f344ff7f4cd +953, 0xab56af117c840b9c +954, 0x5c5404c7e333a10e +955, 0x4f1eb462f35d990d +956, 0xf857605a5644458e +957, 0x3bb87cdf09262f86 +958, 0xd57295baf6da64b +959, 0xb5993f48472f2894 +960, 0x7d1a501608c060b2 +961, 0x45fabe2d0e54adf0 +962, 0xbb41c3806afb4efe +963, 0xbfbc506049424c8 +964, 0xb7dd6b67f2203344 +965, 0x389ce52eff883b81 +966, 0xe259c55c0cf6d000 +967, 0x70fb3e3824f7d213 +968, 0x9f36d5599ed55f4b +969, 0xd14cf6f12f83c4f7 +970, 0x570a09d56aaa0b66 +971, 0x8accafd527f4598 +972, 0xa42d64c62175adfd +973, 0xddb9c6a87b6e1558 +974, 0xd80b6c69fa1cde2a +975, 0x44ebaac10082207b +976, 0xf99be8889552fa1a +977, 0x38253cd4b38b5dc5 +978, 0x85356c8b02675791 +979, 0xbf91677b2ecdcf55 +980, 0x2316cb85e93f366e +981, 0x9abf35954db6b053 +982, 0xf49f7425e086b45a +983, 0x8f5b625e074afde2 +984, 0xe0d614559791b080 +985, 0xbf7b866afab2a525 +986, 0xde89d7e1641a6412 +987, 0x1d10687d8ae5b86f +988, 0x1f034caa0e904cbd +989, 0x2086357aec8a7a2c +990, 0x22dc476b80c56e1e +991, 0xbef5a73cc0e3a493 +992, 0xddfa3829b26ed797 +993, 0x8917a87ec3d4dc78 +994, 0xfeabe390628c365e +995, 0x581b0c4f6fb2d642 +996, 0x1ef8c590adbf5b9a +997, 0x4d8e13aac0cce879 +998, 0xfe38f71e5977fad0 +999, 0x1f83a32d4adfd2ed diff --git a/venv/Lib/site-packages/numpy/random/tests/data/philox-testset-2.csv b/venv/Lib/site-packages/numpy/random/tests/data/philox-testset-2.csv new file mode 100644 index 0000000..69d24c3 --- /dev/null +++ b/venv/Lib/site-packages/numpy/random/tests/data/philox-testset-2.csv @@ -0,0 +1,1001 @@ +seed, 0x0 +0, 0x399e5b222b82fa9 +1, 0x41fd08c1f00f3bc5 +2, 0x78b8824162ee4d04 +3, 0x176747919e02739d +4, 0xfaa88f002a8d3596 +5, 0x418eb6f592e6c227 +6, 0xef83020b8344dd45 +7, 0x30a74a1a6eaa064b +8, 0x93d43bf97a490c3 +9, 0xe4ba28b442194cc +10, 0xc829083a168a8656 +11, 0x73f45d50f8e22849 +12, 0xf912db57352824cc +13, 0xf524216927b12ada +14, 0x22b7697473b1dfda +15, 0x311e2a936414b39f +16, 0xb905abfdcc425be6 +17, 0x4b14630d031eac9c +18, 0x1cf0c4ae01222bc8 +19, 0xa6c33efc6e82ef3 +20, 0x43b3576937ba0948 +21, 0x1e483d17cdde108a +22, 0x6722784cac11ac88 +23, 0xee87569a48fc45d7 +24, 0xb821dcbe74d18661 +25, 0xa5d1876ef3da1a81 +26, 0xe4121c2af72a483 +27, 0x2d747e355a52cf43 +28, 0x609059957bd03725 +29, 0xc3327244b49e16c5 +30, 0xb5ae6cb000dde769 +31, 0x774315003209017 +32, 0xa2013397ba8db605 +33, 0x73b228945dbcd957 +34, 0x801af7190375d3c0 +35, 0xae6dca29f24c9c67 +36, 0xd1cc0bcb1ca26249 +37, 0x1defa62a5bd853be +38, 0x67c2f5557fa89462 +39, 0xf1729b58122fab02 +40, 0xb67eb71949ec6c42 +41, 0x5456366ec1f8f7d7 +42, 0x44492b32eb7966f5 +43, 0xa801804159f175f1 +44, 0x5a416f23cac70d84 +45, 0x186f55293302303d +46, 0x7339d5d7b6a43639 +47, 0xfc6df38d6a566121 +48, 0xed2fe018f150b39e +49, 0x508e0b04a781fa1b +50, 0x8bee9d50f32eaf50 +51, 0x9870015d37e63cc +52, 0x93c6b12309c14f2d +53, 0xb571cf798abe93ff +54, 0x85c35a297a88ae6e +55, 0x9b1b79afe497a2ae +56, 0x1ca02e5b95d96b8d +57, 0x5bb695a666c0a94a +58, 0x4e3caf9bbab0b208 +59, 0x44a44be1a89f2dc1 +60, 0x4ff37c33445758d1 +61, 0xd0e02875322f35da +62, 0xfd449a91fb92646b +63, 0xbe0b49096b95db4d +64, 0xffa3647cad13ef5d +65, 0x75c127a61acd10c8 +66, 0xd65f697756f5f98e +67, 0x3ced84be93d94434 +68, 0x4da3095c2fc46d68 +69, 0x67564e2a771ee9ac +70, 0x36944775180644a9 +71, 0xf458db1c177cdb60 +72, 0x5b58406dcd034c8 +73, 0x793301a3fdab2a73 +74, 0x1c2a1a16d6db6128 +75, 0xc2dacd4ddddbe56c +76, 0x2e7d15be2301a111 +77, 0xd4f4a6341b3bcd18 +78, 0x3622996bbe6a9e3b +79, 0xaf29aa9a7d6d47da +80, 0x6d7dbb74a4cd68ae +81, 0xc260a17e0f39f841 +82, 0xdee0170f2af66f0d +83, 0xf84ae780d7b5a06e +84, 0x8326247b73f43c3a +85, 0xd44eef44b4f98b84 +86, 0x3d10aee62ec895e3 +87, 0x4f23fef01bf703b3 +88, 0xf8e50aa57d888df6 +89, 0x7da67411e3bef261 +90, 0x1d00f2769b2f96d7 +91, 0x7ef9a15b7444b84e +92, 0xcfa16436cc2b7e21 +93, 0x29ab8cfac00460ff +94, 0x23613de8608b0e70 +95, 0xb1aa0980625798a8 +96, 0xb9256fd29db7df99 +97, 0xdacf311bf3e7fa18 +98, 0xa013c8f9fada20d8 +99, 0xaf5fd4fe8230fe3e +100, 0xd3d59ca55102bc5c +101, 0x9d08e2aa5242767f +102, 0x40278fe131e83b53 +103, 0x56397d03c7c14c98 +104, 0xe874b77b119359b3 +105, 0x926a1ba4304ab19f +106, 0x1e115d5aa695a91d +107, 0xc6a459df441f2fe3 +108, 0x2ca842bc1b0b3c6a +109, 0x24c804cf8e5eed16 +110, 0x7ca00fc4a4c3ebd3 +111, 0x546af7cecc4a4ba6 +112, 0x8faae1fa18fd6e3 +113, 0x40420b0089641a6a +114, 0x88175a35d9abcb83 +115, 0xf7d746d1b8b1357c +116, 0x7dae771a651be970 +117, 0x2f6485247ee4df84 +118, 0x6883702fab2d8ec5 +119, 0xeb7eea829a67f9a6 +120, 0x60d5880b485562ed +121, 0x7d4ca3d7e41a4e7e +122, 0xbb7fef961ab8de18 +123, 0x3b92452fb810c164 +124, 0x5f4b4755348b338 +125, 0xca45a715a7539806 +126, 0xc33efd9da5399dd +127, 0x593d665a51d4aedd +128, 0x75d6b8636563036b +129, 0x7b57caa55e262082 +130, 0x4ede7427969e0dd5 +131, 0xc3f19b6f78ea00b +132, 0xeea7bab9be2181ea +133, 0x652c45fe9c420c04 +134, 0x14ba9e3d175670ee +135, 0xd2ad156ba6490474 +136, 0x4d65ae41065f614 +137, 0x6ff911c8afa28eb1 +138, 0xedc2b33588f3cb68 +139, 0x437c8bc324666a2f +140, 0x828cee25457a3f0 +141, 0x530c986091f31b9b +142, 0x2f34671e8326ade7 +143, 0x4f686a8f4d77f6da +144, 0xa4c1987083498895 +145, 0xbce5a88b672b0fb1 +146, 0x8476115a9e6a00cc +147, 0x16de18a55dd2c238 +148, 0xdf38cf4c416232bc +149, 0x2cb837924e7559f3 +150, 0xfad4727484e982ed +151, 0x32a55d4b7801e4f +152, 0x8b9ef96804bd10a5 +153, 0xa1fd422c9b5cf2a9 +154, 0xf46ddb122eb7e442 +155, 0x6e3842547afa3b33 +156, 0x863dee1c34afe5c4 +157, 0x6a43a1935b6db171 +158, 0x1060a5c2f8145821 +159, 0xf783ec9ed34c4607 +160, 0x1da4a86bf5f8c0b0 +161, 0x4c7714041ba12af8 +162, 0x580da7010be2f192 +163, 0xad682fe795a7ea7a +164, 0x6687b6cb88a9ed2c +165, 0x3c8d4b175517cd18 +166, 0xe9247c3a524a6b6b +167, 0x337ca9cfaa02658 +168, 0xed95399481c6feec +169, 0x58726a088e606062 +170, 0xfe7588a5b4ee342a +171, 0xee434c7ed146fdee +172, 0xe2ade8b60fdc4ba5 +173, 0xd57e4c155de4eaab +174, 0xdefeae12de1137cb +175, 0xb7a276a241316ac1 +176, 0xeb838b1b1df4ca15 +177, 0x6f78965edea32f6f +178, 0x18bebd264d7a5d53 +179, 0x3641c691d77005ec +180, 0xbe70ed7efea8c24c +181, 0x33047fa8d03ca560 +182, 0x3bed0d2221ff0f87 +183, 0x23083a6ffbcf38a2 +184, 0xc23eb827073d3fa5 +185, 0xc873bb3415e9fb9b +186, 0xa4645179e54147fe +187, 0x2c72fb443f66e207 +188, 0x98084915dd89d8f4 +189, 0x88baa2de12c99037 +190, 0x85c74ab238cb795f +191, 0xe122186469ea3a26 +192, 0x4c3bba99b3249292 +193, 0x85d6845d9a015234 +194, 0x147ddd69c13e6a31 +195, 0x255f4d678c9a570b +196, 0x2d7c0c410bf962b4 +197, 0x58eb7649e0aa16ca +198, 0x9d240bf662fe0783 +199, 0x5f74f6fa32d293cc +200, 0x4928e52f0f79d9b9 +201, 0xe61c2b87146b706d +202, 0xcfcd90d100cf5431 +203, 0xf15ea8138e6aa178 +204, 0x6ab8287024f9a819 +205, 0xed8942593db74e01 +206, 0xefc00e4ec2ae36dd +207, 0xc21429fb9387f334 +208, 0xf9a3389e285a9bce +209, 0xacdee8c43aae49b3 +210, 0xefc382f02ad55c25 +211, 0x1153b50e8d406b72 +212, 0xb00d39ebcc2f89d8 +213, 0xde62f0b9831c8850 +214, 0xc076994662eef6c7 +215, 0x66f08f4752f1e3ef +216, 0x283b90619796249a +217, 0x4e4869bc4227499e +218, 0xb45ad78a49efd7ed +219, 0xffe19aa77abf5f4b +220, 0xfce11a0daf913aef +221, 0x7e4e64450d5cdceb +222, 0xe9621997cfd62762 +223, 0x4d2c9e156868081 +224, 0x4e2d96eb7cc9a08 +225, 0xda74849bba6e3bd3 +226, 0x6f4621da935e7fde +227, 0xb94b914aa0497259 +228, 0xd50d03e8b8db1563 +229, 0x1a45c1ce5dca422e +230, 0xc8d30d33276f843f +231, 0xb57245774e4176b4 +232, 0x8d36342c05abbbb1 +233, 0x3591ad893ecf9e78 +234, 0x62f4717239ee0ac8 +235, 0x9b71148a1a1d4200 +236, 0x65f8e0f56dd94463 +237, 0x453b1fcfd4fac8c2 +238, 0x4c25e48e54a55865 +239, 0xa866baa05112ace2 +240, 0x7741d3c69c6e79c5 +241, 0x7deb375e8f4f7a8a +242, 0xc242087ede42abd8 +243, 0x2fa9d1d488750c4b +244, 0xe8940137a935d3d3 +245, 0x1dab4918ca24b2f2 +246, 0xe2368c782168fe3e +247, 0x6e8b2d1d73695909 +248, 0x70455ebea268b33e +249, 0x656a919202e28da1 +250, 0x5a5a8935647da999 +251, 0x428c6f77e118c13c +252, 0xa87aee2b675bb083 +253, 0x3873a6412b239969 +254, 0x5f72c1e91cb8a2ee +255, 0xa25af80a1beb5679 +256, 0x1af65d27c7b4abc3 +257, 0x133437060670e067 +258, 0xb1990fa39a97d32e +259, 0x724adc89ae10ed17 +260, 0x3f682a3f2363a240 +261, 0x29198f8dbd343499 +262, 0xdfaeeaa42bc51105 +263, 0x5baff3901b9480c2 +264, 0x3f760a67043e77f5 +265, 0x610fa7aa355a43ba +266, 0x394856ac09c4f7a7 +267, 0x1d9229d058aee82e +268, 0x19c674804c41aeec +269, 0x74cf12372012f4aa +270, 0xa5d89b353fa2f6ca +271, 0x697e4f672ac363dd +272, 0xde6f55ba73df5af9 +273, 0x679cf537510bd68f +274, 0x3dc916114ae9ef7e +275, 0xd7e31a66ec2ee7ba +276, 0xc21bebb968728495 +277, 0xc5e0781414e2adfd +278, 0x71147b5412ddd4bd +279, 0x3b864b410625cca9 +280, 0x433d67c0036cdc6 +281, 0x48083afa0ae20b1b +282, 0x2d80beecd64ac4e8 +283, 0x2a753c27c3a3ee3e +284, 0xb2c5e6afd1fe051a +285, 0xea677930cd66c46b +286, 0x4c3960932f92810a +287, 0xf1b367a9e527eaba +288, 0xb7d92a8a9a69a98e +289, 0x9f9ad3210bd6b453 +290, 0x817f2889db2dcbd8 +291, 0x4270a665ac15813c +292, 0x90b85353bd2be4dd +293, 0x10c0460f7b2d68d +294, 0x11cef32b94f947f5 +295, 0x3cf29ed8e7d477e8 +296, 0x793aaa9bd50599ef +297, 0xbac15d1190014aad +298, 0x987944ae80b5cb13 +299, 0x460aa51f8d57c484 +300, 0xc77df0385f97c2d3 +301, 0x92e743b7293a3822 +302, 0xbc3458bcfbcbb8c0 +303, 0xe277bcf3d04b4ed7 +304, 0xa537ae5cf1c9a31c +305, 0x95eb00d30bd8cfb2 +306, 0x6376361c24e4f2dd +307, 0x374477fe87b9ea8e +308, 0x8210f1a9a039902e +309, 0xe7628f7031321f68 +310, 0x8b8e9c0888fc1d3d +311, 0x306be461fdc9e0ed +312, 0x510009372f9b56f5 +313, 0xa6e6fa486b7a027a +314, 0x9d3f002025203b5a +315, 0x7a46e0e81ecbef86 +316, 0x41e280c611d04df0 +317, 0xedcec10418a99e8a +318, 0x5c27b6327e0b9dbd +319, 0xa81ed2035b509f07 +320, 0x3581e855983a4cc4 +321, 0x4744594b25e9809d +322, 0xc737ac7c27fbd0ed +323, 0x1b523a307045433a +324, 0x8b4ce9171076f1d9 +325, 0x2db02d817cd5eec0 +326, 0x24a1f1229af50288 +327, 0x5550c0dcf583ff16 +328, 0x3587baaa122ec422 +329, 0xf9d3dc894229e510 +330, 0xf3100430d5cf8e87 +331, 0xc31af79862f8e2fb +332, 0xd20582063b9f3537 +333, 0xac5e90ac95fcc7ad +334, 0x107c4c704d5109d4 +335, 0xebc8628906dbfd70 +336, 0x215242776da8c531 +337, 0xa98002f1dcf08b51 +338, 0xbc3bdc07f3b09718 +339, 0x238677062495b512 +340, 0x53b4796f2a3c49e8 +341, 0x6424286467e22f0e +342, 0x14d0952a11a71bac +343, 0x2f97098149b82514 +344, 0x3777f2fdc425ad2 +345, 0xa32f2382938876d4 +346, 0xda8a39a021f20ae3 +347, 0x364361ef0a6ac32c +348, 0x4413eede008ff05a +349, 0x8dda8ace851aa327 +350, 0x4303cabbdcecd1ee +351, 0x2e69f06d74aa549f +352, 0x4797079cd4d9275c +353, 0xc7b1890917e98307 +354, 0x34031b0e822a4b4c +355, 0xfc79f76b566303ea +356, 0x77014adbe255a930 +357, 0xab6c43dd162f3be5 +358, 0xa430041f3463f6b9 +359, 0x5c191a32ada3f84a +360, 0xe8674a0781645a31 +361, 0x3a11cb667b8d0916 +362, 0xaedc73e80c39fd8a +363, 0xfde12c1b42328765 +364, 0x97abb7dcccdc1a0b +365, 0x52475c14d2167bc8 +366, 0x540e8811196d5aff +367, 0xa867e4ccdb2b4b77 +368, 0x2be04af61e5bcfb9 +369, 0x81b645102bfc5dfd +370, 0x96a52c9a66c6450f +371, 0x632ec2d136889234 +372, 0x4ed530c0b36a6c25 +373, 0x6f4851225546b75 +374, 0x2c065d6ba46a1144 +375, 0xf8a3613ff416551d +376, 0xb5f0fd60e9c971a9 +377, 0x339011a03bb4be65 +378, 0x9439f72b6995ded6 +379, 0xc1b03f3ef3b2292d +380, 0xad12fd221daab3ae +381, 0xf615b770f2cf996f +382, 0x269d0fdcb764172 +383, 0x67837025e8039256 +384, 0x6402831fc823fafa +385, 0x22854146a4abb964 +386, 0x7b5ad9b5a1bad7a8 +387, 0x67170e7beb6ac935 +388, 0xfc2d1e8e24adfaaa +389, 0x7ded4395345ff40d +390, 0x418981760a80dd07 +391, 0xc03bef38022c1d2 +392, 0x3a11850b26eade29 +393, 0xaa56d02c7175c5f4 +394, 0xd83b7917b9bfbff5 +395, 0x3c1df2f8fa6fced3 +396, 0xf3d6e2999c0bb760 +397, 0xc66d683a59a950e3 +398, 0x8e3972a9d73ffabf +399, 0x97720a0443edffd9 +400, 0xa85f5d2fe198444a +401, 0xfc5f0458e1b0de5e +402, 0xe3973f03df632b87 +403, 0xe151073c84c594b3 +404, 0x68eb4e22e7ff8ecf +405, 0x274f36eaed7cae27 +406, 0x3b87b1eb60896b13 +407, 0xbe0b2f831442d70a +408, 0x2782ed7a48a1b328 +409, 0xb3619d890310f704 +410, 0xb03926b11b55921a +411, 0xdb46fc44aa6a0ce4 +412, 0x4b063e2ef2e9453a +413, 0xe1584f1aeec60fb5 +414, 0x7092bd6a879c5a49 +415, 0xb84e1e7c7d52b0e6 +416, 0x29d09ca48db64dfb +417, 0x8f6c4a402066e905 +418, 0x77390795eabc36b +419, 0xcc2dc2e4141cc69f +420, 0x2727f83beb9e3c7c +421, 0x1b29868619331de0 +422, 0xd38c571e192c246f +423, 0x535327479fe37b6f +424, 0xaff9ce5758617eb3 +425, 0x5658539e9288a4e4 +426, 0x8df91d87126c4c6d +427, 0xe931cf8fdba6e255 +428, 0x815dfdf25fbee9e8 +429, 0x5c61f4c7cba91697 +430, 0xdd5f5512fe2313a1 +431, 0x499dd918a92a53cd +432, 0xa7e969d007c97dfd +433, 0xb8d39c6fc81ac0bb +434, 0x1d646983def5746c +435, 0x44d4b3b17432a60c +436, 0x65664232a14db1e3 +437, 0xda8fae6433e7500b +438, 0xbe51b94ff2a3fe94 +439, 0xe9b1bd9a9098ef9f +440, 0xfe47d54176297ef5 +441, 0xb8ab99bc03bb7135 +442, 0xcfad97f608565b38 +443, 0xf05da71f6760d9c1 +444, 0xef8da40a7c70e7b +445, 0xe0465d58dbd5d138 +446, 0xb54a2d70eb1a938 +447, 0xfdd50c905958f2d8 +448, 0x3c41933c90a57d43 +449, 0x678f6d894c6ad0bb +450, 0x403e8f4582274e8 +451, 0x5cbbe975668df6b0 +452, 0x297e6520a7902f03 +453, 0x8f6dded33cd1efd7 +454, 0x8e903c97be8d783b +455, 0x10bd015577e30f77 +456, 0x3fcd69d1c36eab0c +457, 0xb45989f3ca198d3 +458, 0x507655ce02b491a9 +459, 0xa92cf99bb78602ce +460, 0xebfb82055fbc2f0f +461, 0x3334256279289b7a +462, 0xc19d2a0f740ee0ac +463, 0x8bb070dea3934905 +464, 0xa4ab57d3a8d1b3eb +465, 0xfee1b09bcacf7ff4 +466, 0xccc7fb41ceec41fa +467, 0xd4da49094eb5a74d +468, 0xed5c693770af02ed +469, 0x369dabc9bbfaa8e4 +470, 0x7eab9f360d054199 +471, 0xe36dbebf5ee94076 +472, 0xd30840e499b23d7 +473, 0x8678e6cb545015ff +474, 0x3a47932ca0b336e +475, 0xeb7c742b6e93d6fe +476, 0x1404ea51fe5a62a9 +477, 0xa72cd49db978e288 +478, 0xfd7bada020173dcf +479, 0xc9e74fc7abe50054 +480, 0x93197847bb66808d +481, 0x25fd5f053dce5698 +482, 0xe198a9b18cc21f4 +483, 0x5cc27b1689452d5d +484, 0x8b3657af955a98dc +485, 0xc17f7584f54aa1c0 +486, 0xe821b088246b1427 +487, 0x32b5a9f6b45b6fa0 +488, 0x2aef7c315c2bae0c +489, 0xe1af8129846b705a +490, 0x4123b4c091b34614 +491, 0x6999d61ec341c073 +492, 0x14b9a8fcf86831ea +493, 0xfd4cff6548f46c9f +494, 0x350c3b7e6cc8d7d6 +495, 0x202a5047fecafcd5 +496, 0xa82509fe496bb57d +497, 0x835e4b2608b575fe +498, 0xf3abe3da919f54ec +499, 0x8705a21e2c9b8796 +500, 0xfd02d1427005c314 +501, 0xa38458faa637f49b +502, 0x61622f2360e7622a +503, 0xe89335a773c2963b +504, 0x481264b659b0e0d0 +505, 0x1e82ae94ebf62f15 +506, 0x8ea7812de49209d4 +507, 0xff963d764680584 +508, 0x418a68bef717f4af +509, 0x581f0e7621a8ab91 +510, 0x840337e9a0ec4150 +511, 0x951ef61b344be505 +512, 0xc8b1b899feb61ec2 +513, 0x8b78ca13c56f6ed9 +514, 0x3d2fd793715a946f +515, 0xf1c04fabcd0f4084 +516, 0x92b602614a9a9fcc +517, 0x7991bd7a94a65be7 +518, 0x5dead10b06cad2d7 +519, 0xda7719b33f722f06 +520, 0x9d87a722b7bff71e +521, 0xb038e479071409e9 +522, 0xf4e8bbec48054775 +523, 0x4fec2cd7a28a88ea +524, 0x839e28526aad3e56 +525, 0xd37ec57852a98bf0 +526, 0xdef2cbbe00f3a02d +527, 0x1aecfe01a9e4d801 +528, 0x59018d3c8beaf067 +529, 0x892753e6ac8bf3cd +530, 0xefdd3437023d2d1c +531, 0x447bfbd148c8cb88 +532, 0x282380221bd442b8 +533, 0xfce8658d1347384a +534, 0x60b211a7ec6bfa8 +535, 0xd21729cfcc692974 +536, 0x162087ecd5038a47 +537, 0x2b17000c4bce39d2 +538, 0x3a1f75ff6adcdce0 +539, 0x721a411d312f1a2c +540, 0x9c13b6133f66934d +541, 0xaa975d14978980e5 +542, 0x9403dbd4754203fa +543, 0x588c15762fdd643 +544, 0xdd1290f8d0ada73a +545, 0xd9b77380936103f4 +546, 0xb2e2047a356eb829 +547, 0x7019e5e7f76f7a47 +548, 0x3c29a461f62b001d +549, 0xa07dc6cfab59c116 +550, 0x9b97e278433f8eb +551, 0x6affc714e7236588 +552, 0x36170aeb32911a73 +553, 0x4a665104d364a789 +554, 0x4be01464ec276c9c +555, 0x71bb10271a8b4ecf +556, 0xbf62e1d068bc018 +557, 0xc9ada5db2cbbb413 +558, 0x2bded75e726650e5 +559, 0x33d5a7af2f34385d +560, 0x8179c46661d85657 +561, 0x324ebcfd29267359 +562, 0xac4c9311dc9f9110 +563, 0xc14bb6a52f9f9c0 +564, 0xc430abe15e7fb9db +565, 0xf1cce5c14df91c38 +566, 0x651e3efa2c0750d3 +567, 0x38a33604a8be5c75 +568, 0x7aaf77fe7ff56a49 +569, 0xc0d1cc56bbf27706 +570, 0x887aa47324e156c6 +571, 0x12547c004b085e8d +572, 0xd86a8d6fbbbfd011 +573, 0x57c860188c92d7b4 +574, 0xcd5d3843d361b8ca +575, 0x8f586ef05a9cb3ef +576, 0x174456e1ba6267d5 +577, 0xf5dc302c62fe583c +578, 0xa349442fabcdb71 +579, 0xe5123c1a8b6fd08e +580, 0x80681552aa318593 +581, 0xb295396deaef1e31 +582, 0xabb626e0b900e32b +583, 0xf024db8d3f19c15e +584, 0x1d04bb9548e2fb6c +585, 0xd8ed2b2214936c2b +586, 0x618ca1e430a52bc9 +587, 0xccbca44a6088136b +588, 0xd0481855c8b9ccbe +589, 0x3c92a2fade28bdf7 +590, 0x855e9fefc38c0816 +591, 0x1269bbfe55a7b27c +592, 0x1d6c853d83726d43 +593, 0xc8655511cc7fcafc +594, 0x301503eb125a9b0e +595, 0xb3108e4532016b11 +596, 0xbb7ab6245da9cb3d +597, 0x18004c49116d85eb +598, 0x3480849c20f61129 +599, 0xe28f45157463937b +600, 0x8e85e61060f2ce1 +601, 0x1673da4ec589ba5e +602, 0x74b9a6bd1b194712 +603, 0xed39e147fa8b7601 +604, 0x28ce54019102ca77 +605, 0x42e0347f6d7a2f30 +606, 0xb6a908d1c4814731 +607, 0x16c3435e4e9a126d +608, 0x8880190514c1ad54 +609, 0xfffd86229a6f773c +610, 0x4f2420cdb0aa1a93 +611, 0xf8e1acb4120fc1fa +612, 0x63a8c553ab36a2f2 +613, 0x86b88cf3c0a6a190 +614, 0x44d8b2801622c792 +615, 0xf6eae14e93082ff1 +616, 0xd9ed4f5d1b8fac61 +617, 0x1808ce17f4e1f70 +618, 0x446e83ea336f262f +619, 0xc7c802b04c0917b7 +620, 0x626f45fd64968b73 +621, 0x9ffa540edc9b2c5c +622, 0xa96a1e219e486af8 +623, 0x2bb8963884e887a1 +624, 0xba7f68a5d029e3c4 +625, 0xefc45f44392d9ca0 +626, 0x98d77762503c5eab +627, 0xd89bcf62f2da627c +628, 0xa3cab8347f833151 +629, 0xa095b7595907d5c7 +630, 0x3b3041274286181 +631, 0xb518db8919eb71fa +632, 0x187036c14fdc9a36 +633, 0xd06e28301e696f5d +634, 0xdbc71184e0c56492 +635, 0xfe51e9cae6125bfd +636, 0x3b12d17cd014df24 +637, 0x3b95e4e2c986ac1a +638, 0x29c1cce59fb2dea2 +639, 0x58c05793182a49d6 +640, 0xc016477e330d8c00 +641, 0x79ef335133ada5d +642, 0x168e2cad941203f3 +643, 0xf99d0f219d702ef0 +644, 0x655628068f8f135b +645, 0xdcdea51910ae3f92 +646, 0x8e4505039c567892 +647, 0x91a9ec7e947c89ae +648, 0x8717172530f93949 +649, 0x1c80aba9a440171a +650, 0x9c8f83f6ebe7441e +651, 0x6c05e1efea4aa7f9 +652, 0x10af696b777c01b +653, 0x5892e9d9a92fc309 +654, 0xd2ba7da71e709432 +655, 0x46378c7c3269a466 +656, 0x942c63dfe18e772c +657, 0x6245cf02ef2476f +658, 0x6f265b2759ea2aea +659, 0x5aa757f17d17f4a6 +660, 0x1ad6a3c44fa09be6 +661, 0xe861af14e7015fb8 +662, 0x86be2e7db388c77 +663, 0x5c7bba32b519e9a0 +664, 0x3feb314850c4437b +665, 0x97955add60cfb45b +666, 0xfdb536230a540bdc +667, 0xdac9d7bf6e58512e +668, 0x4894c00e474e8120 +669, 0xa1918a37739da366 +670, 0xa8097f2096532807 +671, 0x592afe50e6c5e643 +672, 0xd69050ee6dcb33dc +673, 0xa6956b262dd3c561 +674, 0x1a55c815555e63f7 +675, 0x2ec7fd37516de2bb +676, 0x8ec251d9c70e76ba +677, 0x9b76e4abafd2689 +678, 0x9ce3f5c751a57df1 +679, 0x915c4818bf287bc7 +680, 0x2293a0d1fe07c735 +681, 0x7627dcd5d5a66d3d +682, 0xb5e4f92cc49c7138 +683, 0x6fc51298731d268c +684, 0xd19800aa95441f87 +685, 0x14f70f31162fa115 +686, 0x41a3da3752936f59 +687, 0xbec0652be95652ee +688, 0x7aa4bdb1020a290f +689, 0x4382d0d9bee899ef +690, 0xe6d988ae4277d6ff +691, 0xe618088ccb2a32d1 +692, 0x411669dfaa899e90 +693, 0x234e2bf4ba76d9f +694, 0xe109fe4cb7828687 +695, 0x1fb96b5022b0b360 +696, 0x6b24ad76c061a716 +697, 0x7e1781d4d7ecee15 +698, 0xf20c2dbe82ba38ba +699, 0xeda8e8ae1d943655 +700, 0xa58d196e2a77eaec +701, 0x44564765a5995a0b +702, 0x11902fe871ecae21 +703, 0x2ea60279900e675d +704, 0x38427227c18a9a96 +705, 0xe0af01490a1b1b48 +706, 0x826f91997e057824 +707, 0x1e57308e6e50451 +708, 0xb42d469bbbfdc350 +709, 0xb9734cff1109c49b +710, 0x98967559bb9d364f +711, 0xd6be360041907c12 +712, 0xa86a1279122a1e21 +713, 0x26f99a8527bfc698 +714, 0xfa8b85758f28f5d6 +715, 0xe3057429940806ae +716, 0x4bee2d7e84f93b2b +717, 0x948350a76ea506f4 +718, 0xa139154488045e74 +719, 0x8893579ba5e78085 +720, 0x5f21c215c6a9e397 +721, 0x456134f3a59641dc +722, 0x92c0273f8e97a9c6 +723, 0xd2936c9c3f0c6936 +724, 0xcfa4221e752c4735 +725, 0x28cd5a7457355dca +726, 0xecdfdde23d90999f +727, 0x60631b2d494d032b +728, 0xf67289df269a827f +729, 0xcbe8011ef0f5b7ef +730, 0x20eea973c70a84f5 +731, 0xbe1fd200398557ce +732, 0xd2279ee030191bba +733, 0xf2bd4291dedaf819 +734, 0xfc6d167dbe8c402 +735, 0x39ac298da5d0044b +736, 0xceac026f5f561ce +737, 0x10a5b0bdd8ad60e6 +738, 0xdeb3c626df6d4bcb +739, 0x3c128962e77ff6ca +740, 0xc786262e9c67a0e5 +741, 0x4332855b3febcdc0 +742, 0x7bda9724d1c0e020 +743, 0x6a8c93399bc4df22 +744, 0xa9b20100ac707396 +745, 0xa11a3458502c4eb5 +746, 0xb185461c60478941 +747, 0x13131d56195b7ff6 +748, 0x8d55875ddbd4aa1c +749, 0xc09b67425f469aa5 +750, 0x39e33786cc7594c4 +751, 0x75e96db8e4b08b93 +752, 0xda01cd12a3275d1e +753, 0x2c49e7822344fab5 +754, 0x9bd5f10612514ca7 +755, 0x1c801a5c828e7332 +756, 0x29797d3f4f6c7b4c +757, 0xac992715e21e4e53 +758, 0xe40e89ee887ddb37 +759, 0x15189a2b265a783b +760, 0xa854159a52af5c5 +761, 0xb9d8a5a81c12bead +762, 0x3240cdc9d59e2a58 +763, 0x1d0b872234cf8e23 +764, 0xc01224cf6ce12cff +765, 0x2601e9f3905c8663 +766, 0xd4ecf9890168d6b4 +767, 0xa45db796d89bfdd5 +768, 0x9f389406dad64ab4 +769, 0xa5a851adce43ffe3 +770, 0xd0962c41c26e5aa9 +771, 0x8a671679e48510a4 +772, 0xc196dc0924a6bfeb +773, 0x3ead661043b549cb +774, 0x51af4ca737d405ac +775, 0xf4425b5c62275fb6 +776, 0x71e69d1f818c10f5 +777, 0xacaf4af2d3c70162 +778, 0x2e1f1d4fd7524244 +779, 0xe54fdd8f388890e8 +780, 0xfda0d33e84eb2b83 +781, 0x53965c5e392b81da +782, 0x5c92288267263097 +783, 0xcac1b431c878c66c +784, 0x36c0e1cf417241c6 +785, 0x5cc4d9cd1a36bf2c +786, 0x32e4257bb5d3e470 +787, 0x4aecff904adb44fb +788, 0x4d91a8e0d1d60cac +789, 0xa3b478388385b038 +790, 0x48d955f24eba70be +791, 0x310e4deb07f24f68 +792, 0x8853e73b1f30a5a +793, 0x278aee45c2a65c5 +794, 0xf6932eedbd62fb0b +795, 0xafb95958c82fafad +796, 0x78e807c18616c16c +797, 0xd7abadda7488ed9f +798, 0x2dd72e2572aa2ae6 +799, 0x6ec3791982c2be09 +800, 0x6865bb314fac478f +801, 0xa14dc0ce09000d1a +802, 0xb8081ad134da10f2 +803, 0xc4ac1534aa825ef5 +804, 0xd83aeb48ae2d538f +805, 0x38052027e3074be4 +806, 0xa9833e06ef136582 +807, 0x4f02d790ec9fd78 +808, 0xec2f60bc711c5bdc +809, 0x9253b0d12268e561 +810, 0xa8ac607fdd62c206 +811, 0x895e28ebc920289f +812, 0xe2fd42b154243ac7 +813, 0xc69cac2f776eee19 +814, 0xf4d4ac11db56d0dc +815, 0xa8d37049b9f39833 +816, 0x75abbf8a196c337c +817, 0xb115bb76750d27b8 +818, 0x39426d187839154 +819, 0xd488423e7f38bf83 +820, 0xbb92e0c76ecb6a62 +821, 0x3055a018ce39f4e3 +822, 0xc93fe0e907729bfb +823, 0x65985d17c5863340 +824, 0x2088ae081b2028e1 +825, 0x6e628de873314057 +826, 0x864377cccf573f0e +827, 0xae03f4c9aa63d132 +828, 0xb1db766d6404c66d +829, 0xdce5a22414a374b +830, 0x622155b777819997 +831, 0x69fe96e620371f3c +832, 0xa9c67dbc326d94fc +833, 0x932a84ae5dd43bab +834, 0xe2301a20f6c48c3f +835, 0x795d2e79c6477300 +836, 0xd8e3e631289521e7 +837, 0xae2684979002dfd6 +838, 0xc9c2392377550f89 +839, 0xa1b0c99d508ef7ec +840, 0x593aef3c5a5272ec +841, 0xe32e511a4b7162cd +842, 0xab3b81655f5a2857 +843, 0x1b535e1a0aaf053e +844, 0x5b33f56c1b6a07e2 +845, 0x782dc8cfcac4ef36 +846, 0xb3d4f256eecfd202 +847, 0xf73a6598f58c4f7e +848, 0xd5722189524870ae +849, 0x707878de6b995fc0 +850, 0xc3eb6ba73e3d7e8a +851, 0xca75c017655b75a7 +852, 0x1b29369ea3541e5f +853, 0x352e98858bdb58a3 +854, 0x1e4412d184b6b27d +855, 0x2d375ba0304b2d17 +856, 0x56c30fce69a5d08e +857, 0x6b8c2b0c06584bda +858, 0xde4dfff228c8c91f +859, 0xb7c9edd574e6287f +860, 0xf6078281c9fca2b2 +861, 0xb9b9a51de02a2f1e +862, 0xa411bef31c0103b0 +863, 0xc5facd8fc5e1d7a3 +864, 0x54e631c05ddf7359 +865, 0x815b42b3fd06c474 +866, 0xc9ac07566fda18ec +867, 0xd84ea62957bd8e15 +868, 0x5575f74b5cfd8803 +869, 0x5779a8d460c2e304 +870, 0xfd6e87e264a85587 +871, 0xa1d674daa320b26d +872, 0x2c3c3ec64b35afc4 +873, 0x393a274ff03e6935 +874, 0x1f40ecbac52c50ea +875, 0xc3de64fa324ffc0c +876, 0x56ae828b7f9deb04 +877, 0xe7c1a77b5c1f2cb3 +878, 0xa4c4aab19ea921cc +879, 0xec164c238825822c +880, 0xa6a3304770c03b03 +881, 0x3a63641d5b1e8123 +882, 0x42677be3a54617ef +883, 0xa2680423e3a200c0 +884, 0x8b17cf75f3f37277 +885, 0xe7ce65a49242be3d +886, 0x7f85934271323e4b +887, 0xcfb0f431f79a4fab +888, 0x392e4041a8505b65 +889, 0xd3e5daf0d8b25ea6 +890, 0x9447eff675d80f53 +891, 0xea27a9d53cfaeea8 +892, 0xe3f2335945a83ba +893, 0x8875a43ce216413b +894, 0xe49941f9eabce33e +895, 0x9357c1296683a5b1 +896, 0xf0f16439e81ee701 +897, 0x3181515295ffd79a +898, 0x9d7150fffd169ed8 +899, 0x2d6a1d281e255a72 +900, 0x81bf1286fb3a92b6 +901, 0x566d3079b499e279 +902, 0xc7939ca8f047341 +903, 0xb1f8050e7c2d59f6 +904, 0x605701045e7be192 +905, 0x51b73360e8e31a1c +906, 0x9f4ad54483ba9fe0 +907, 0xd3085b8fcf69d1c8 +908, 0xc3e7475026dc5f0b +909, 0x5800f8554b157354 +910, 0x37dfdf858cfcd963 +911, 0x3a1fce05ce385072 +912, 0xf495c062645c20c3 +913, 0xdcbeec2c3492c773 +914, 0xc38f427589d1d0b4 +915, 0x681ead60216a8184 +916, 0x4bd569c40cc88c41 +917, 0x49b0d442e130b7a2 +918, 0xee349156b7d1fa3f +919, 0x2bde2d2db055135b +920, 0xc6a460d2fbcb2378 +921, 0xd0f170494ff3dbb +922, 0xb294422492528a23 +923, 0xfc95873c854e7b86 +924, 0x6c9c3ad1797bb19c +925, 0xe0c06f2aab65062d +926, 0x58e32ce0f11e3a81 +927, 0xa745fcd729ff5036 +928, 0x599b249b2fc2cdb2 +929, 0x78f23b5b0dd5b082 +930, 0x6de3e957f549ecfc +931, 0x9d0712fa6d878756 +932, 0x9076e8554e4a413a +933, 0xf3185818c0294de8 +934, 0x5de7cdf4b455b9b6 +935, 0xb15f6908ed703f7d +936, 0x98c654dfedc6818 +937, 0x120502ab0e93ae42 +938, 0x67966a98a58dc120 +939, 0x1caa0fc628989482 +940, 0xd8b2c3cd480a8625 +941, 0x85c70071b3aed671 +942, 0xff385f8473714662 +943, 0xe2868e4bf3773b63 +944, 0x96cf8019b279298e +945, 0x8511cc930bd74800 +946, 0x5312e48fdd55f5ab +947, 0xfcdae564b52df78d +948, 0x9eee48373e652176 +949, 0x953788f6bcbc56b0 +950, 0xd1a3855dbd2f6b37 +951, 0x3ad32acf77f4d1e9 +952, 0x917c7be81b003e30 +953, 0x9ce817da1e2e9dfb +954, 0x2968983db162d44d +955, 0x1e005decef5828ad +956, 0xc38fe59d1aa4f3d5 +957, 0xf357f1710dc02f1d +958, 0x2613912a4c83ec67 +959, 0x832a11470b9a17cb +960, 0x5e85508a611f0dad +961, 0x2781131677f59d56 +962, 0xa82358d7d4b0237f +963, 0xfbf8b3cc030c3af6 +964, 0x68b2f68ac8a55adb +965, 0x3b6fcf353add0ada +966, 0xd1956049bcd15bd5 +967, 0x95b76f31c7f98b6d +968, 0x814b6690df971a84 +969, 0xdcf7959cddd819e4 +970, 0xcf8c72c5d804fc88 +971, 0x56883769c8945a22 +972, 0x1f034652f658cf46 +973, 0x41df1324cda235a1 +974, 0xeccd32524504a054 +975, 0x974e0910a04ec02c +976, 0x72104507b821f6db +977, 0x791f8d089f273044 +978, 0xe0f79a4f567f73c3 +979, 0x52fe5bea3997f024 +980, 0x5f8b9b446494f78 +981, 0xfd9f511947059190 +982, 0x3aea9dac6063bce3 +983, 0xbfdae4dfc24aee60 +984, 0xa82cdbbf0a280318 +985, 0xf460aae18d70aa9d +986, 0x997367cb204a57c4 +987, 0x616e21ab95ba05ef +988, 0x9bfc93bec116769f +989, 0x2b2ee27c37a3fa5b +990, 0xb25c6ed54006ee38 +991, 0xab04d4a5c69e69a5 +992, 0x6d2f6b45f2d8438f +993, 0x4ad2f32afc82f092 +994, 0x513d718908f709c0 +995, 0x5272aadc4fffca51 +996, 0xeb3f87e66156ef5d +997, 0xf8a3d5a46a86ba85 +998, 0xdb4548a86f27abfd +999, 0x57c05f47ff62380d diff --git a/venv/Lib/site-packages/numpy/random/tests/data/sfc64-testset-1.csv b/venv/Lib/site-packages/numpy/random/tests/data/sfc64-testset-1.csv new file mode 100644 index 0000000..4fffe69 --- /dev/null +++ b/venv/Lib/site-packages/numpy/random/tests/data/sfc64-testset-1.csv @@ -0,0 +1,1001 @@ +seed, 0xdeadbeaf +0, 0xa475f55fbb6bc638 +1, 0xb2d594b6c29d971c +2, 0x275bc4ece4484fb1 +3, 0x569be72d9b3492fb +4, 0x89a5bb9b206a670c +5, 0xd951bfa06afdc3f9 +6, 0x7ee2e1029d52a265 +7, 0x12ef1d4de0cb4d4c +8, 0x41658ba8f0ef0280 +9, 0x5b650c82e4fe09c5 +10, 0x638a9f3e30ec4e94 +11, 0x147487fb2ba9233e +12, 0x89ef035603d2d1fb +13, 0xe66ca57a190e6cbe +14, 0x330f673740dd61fc +15, 0xc71d3dce2f8bb34e +16, 0x3c07c39ff150b185 +17, 0x5df952b6cae8f099 +18, 0x9f09f2b1f0ceac80 +19, 0x19598eee2d0c4c67 +20, 0x64e06483702e0ebd +21, 0xda04d1fdb545f7fa +22, 0xf2cf53b61a0c4f9b +23, 0xf0bb724ce196f66e +24, 0x71cefde55d9cf0f +25, 0x6323f62824a20048 +26, 0x1e93604680f14b4e +27, 0xd9d8fad1d4654025 +28, 0xf4ee25af2e76ca08 +29, 0x6af3325896befa98 +30, 0xad9e43abf5e04053 +31, 0xbf930e318ce09de3 +32, 0x61f9583b4f9ffe76 +33, 0x9b69d0b3d5ec8958 +34, 0xa608f250f9b2ca41 +35, 0x6fdba7073dc2bb5d +36, 0xa9d57601efea6d26 +37, 0xc24a88a994954105 +38, 0xc728b1f78d88fe5b +39, 0x88da88c2b083b3b2 +40, 0xa9e27f7303c76cfd +41, 0xc4c24608c29176eb +42, 0x5420b58466b972fd +43, 0xd2018a661b6756c8 +44, 0x7caed83d9573fc7 +45, 0x562a3d81b849a06a +46, 0x16588af120c21f2c +47, 0x658109a7e0eb4837 +48, 0x877aabb14d3822e1 +49, 0x95704c342c3745fe +50, 0xeeb8a0dc81603616 +51, 0x431bf94889290419 +52, 0xe4a9410ab92a5863 +53, 0xbc6be64ea60f12ba +54, 0x328a2da920015063 +55, 0x40f6b3bf8271ae07 +56, 0x4068ff00a0e854f8 +57, 0x1b287572ca13fa78 +58, 0xa11624a600490b99 +59, 0x4a04ef29eb7150fa +60, 0xcc9469ab5ffb739 +61, 0x99a6a9f8d95e782 +62, 0x8e90356573e7a070 +63, 0xa740b8fb415c81c4 +64, 0x47eccef67447f3da +65, 0x2c720afe3a62a49b +66, 0xe2a747f0a43eacf4 +67, 0xba063a87ab165576 +68, 0xbc1c78ed27feb5a3 +69, 0x285a19fa3974f9d +70, 0x489c61e704f5f0e3 +71, 0xf5ab04f6b03f238b +72, 0x7e25f88138a110dd +73, 0xc3d1cef3d7c1f1d1 +74, 0xc3de6ec64d0d8e00 +75, 0x73682a15b6cc5088 +76, 0x6fecbeb319163dc5 +77, 0x7e100d5defe570a1 +78, 0xad2af9af076dce57 +79, 0x3c65100e23cd3a9a +80, 0x4b442cc6cfe521bb +81, 0xe89dc50f8ab1ef75 +82, 0x8b3c6fdc2496566 +83, 0xdfc50042bc2c308c +84, 0xe39c5f158b33d2b2 +85, 0x92f6adefdfeb0ac +86, 0xdf5808a949c85b3e +87, 0x437384021c9dace9 +88, 0xa7b5ed0d3d67d8f +89, 0xe1408f8b21da3c34 +90, 0xa1bba125c1e80522 +91, 0x7611dc4710385264 +92, 0xb00a46ea84082917 +93, 0x51bf8002ffa87cef +94, 0x9bb81013e9810adc +95, 0xd28f6600013541cd +96, 0xc2ca3b1fa7791c1f +97, 0x47f9ad58f099c82c +98, 0x4d1bb9458469caf9 +99, 0xca0b165b2844257 +100, 0xc3b2e667d075dc66 +101, 0xde22f71136a3dbb1 +102, 0x23b4e3b6f219e4c3 +103, 0x327e0db4c9782f66 +104, 0x9365506a6c7a1807 +105, 0x3e868382dedd3be7 +106, 0xff04fa6534bcaa99 +107, 0x96621a8862995305 +108, 0x81bf39cb5f8e1df7 +109, 0x79b684bb8c37af7a +110, 0xae3bc073c3cde33c +111, 0x7805674112c899ac +112, 0xd95a27995abb20f2 +113, 0x71a503c57b105c40 +114, 0x5ff00d6a73ec8acc +115, 0x12f96391d91e47c2 +116, 0xd55ca097b3bd4947 +117, 0x794d79d20468b04 +118, 0x35d814efb0d7a07d +119, 0xfa9ac9bd0aae76d3 +120, 0xa77b8a3711e175cd +121, 0xe6694fbf421f9489 +122, 0xd8f1756525a1a0aa +123, 0xe38dfa8426277433 +124, 0x16b640c269bbcd44 +125, 0x2a7a5a67ca24cfeb +126, 0x669039c28d5344b4 +127, 0x2a445ee81fd596bb +128, 0x600df94cf25607e0 +129, 0x9358561a7579abff +130, 0xee1d52ea179fc274 +131, 0x21a8b325e89d31be +132, 0x36fc0917486eec0a +133, 0x3d99f40717a6be9f +134, 0x39ac140051ca55ff +135, 0xcef7447c26711575 +136, 0xf22666870eff441d +137, 0x4a53c6134e1c7268 +138, 0xd26de518ad6bdb1b +139, 0x1a736bf75b8b0e55 +140, 0xef1523f4e6bd0219 +141, 0xb287b32fd615ad92 +142, 0x2583d6af5e841dd5 +143, 0x4b9294aae7ca670c +144, 0xf5aa4a84174f3ca9 +145, 0x886300f9e0dc6376 +146, 0x3611401e475ef130 +147, 0x69b56432b367e1ac +148, 0x30c330e9ab36b7c4 +149, 0x1e0e73079a85b8d5 +150, 0x40fdfc7a5bfaecf +151, 0xd7760f3e8e75a085 +152, 0x1cc1891f7f625313 +153, 0xeece1fe6165b4272 +154, 0xe61111b0c166a3c1 +155, 0x2f1201563312f185 +156, 0xfd10e8ecdd2a57cb +157, 0x51cdc8c9dd3a89bf +158, 0xed13cc93938b5496 +159, 0x843816129750526b +160, 0xd09995cd6819ada +161, 0x4601e778d40607df +162, 0xef9df06bd66c2ea0 +163, 0xae0bdecd3db65d69 +164, 0xbb921a3c65a4ae9a +165, 0xd66698ce8e9361be +166, 0xacdc91647b6068f4 +167, 0xe505ef68f2a5c1c0 +168, 0xd6e62fd27c6ab137 +169, 0x6a2ba2c6a4641d86 +170, 0x9c89143715c3b81 +171, 0xe408c4e00362601a +172, 0x986155cbf5d4bd9d +173, 0xb9e6831728c893a7 +174, 0xb985497c3bf88d8c +175, 0xd0d729214b727bec +176, 0x4e557f75fece38a +177, 0x6572067fdfd623ca +178, 0x178d49bb4d5cd794 +179, 0xe6baf59f60445d82 +180, 0x5607d53518e3a8d2 +181, 0xba7931adb6ebbd61 +182, 0xe853576172611329 +183, 0xe945daff96000c44 +184, 0x565b9ba3d952a176 +185, 0xcdb54d4f88c584c8 +186, 0x482a7499bee9b5e5 +187, 0x76560dd0affe825b +188, 0x2a56221faa5ca22c +189, 0x7729be5b361f5a25 +190, 0xd6f2195795764876 +191, 0x59ef7f8f423f18c5 +192, 0x7ebefed6d02adde1 +193, 0xcfec7265329c73e5 +194, 0x4fd8606a5e59881c +195, 0x95860982ae370b73 +196, 0xdecfa33b1f902acc +197, 0xf9b8a57400b7c0a6 +198, 0xd20b822672ec857b +199, 0x4eb81084096c7364 +200, 0xe535c29a44d9b6ad +201, 0xdef8b48ebacb2e29 +202, 0x1063bc2b8ba0e915 +203, 0xe4e837fb53d76d02 +204, 0x4df935db53579fb8 +205, 0xa30a0c8053869a89 +206, 0xe891ee58a388a7b5 +207, 0x17931a0c64b8a985 +208, 0xaf2d350b494ce1b3 +209, 0x2ab9345ffbcfed82 +210, 0x7de3fe628a2592f0 +211, 0x85cf54fab8b7e79d +212, 0x42d221520edab71b +213, 0x17b695b3af36c233 +214, 0xa4ffe50fe53eb485 +215, 0x1102d242db800e4d +216, 0xc8dc01f0233b3b6 +217, 0x984a030321053d36 +218, 0x27fa8dc7b7112c0e +219, 0xba634dd8294e177f +220, 0xe67ce34b36332eb +221, 0x8f1351e1894fb41a +222, 0xb522a3048761fd30 +223, 0xc350ad9bc6729edc +224, 0xe0ed105bd3c805e1 +225, 0xa14043d2b0825aa7 +226, 0xee7779ce7fc11fdf +227, 0xc0fa8ba23a60ab25 +228, 0xb596d1ce259afbad +229, 0xaa9b8445537fdf62 +230, 0x770ab2c700762e13 +231, 0xe812f1183e40cc1 +232, 0x44bc898e57aefbbd +233, 0xdd8a871df785c996 +234, 0x88836a5e371eb36b +235, 0xb6081c9152623f27 +236, 0x895acbcd6528ca96 +237, 0xfb67e33ddfbed435 +238, 0xaf7af47d323ce26 +239, 0xe354a510c3c39b2d +240, 0x5cacdedda0672ba3 +241, 0xa440d9a2c6c22b09 +242, 0x6395099f48d64304 +243, 0xc11cf04c75f655b5 +244, 0x1c4e054d144ddb30 +245, 0x3e0c2db89d336636 +246, 0x127ecf18a5b0b9a7 +247, 0x3b50551a88ea7a73 +248, 0xbd27003e47f1f684 +249, 0xf32d657782baac9b +250, 0x727f5cabf020bc9 +251, 0x39c1c1c226197dc7 +252, 0x5552c87b35deeb69 +253, 0x64d54067b5ce493f +254, 0x3494b091fe28dda0 +255, 0xdf0278bc85ee2965 +256, 0xdef16fec25efbd66 +257, 0xe2be09f578c4ce28 +258, 0xd27a9271979d3019 +259, 0x427f6fcd71845e3 +260, 0x26b52c5f81ec142b +261, 0x98267efc3986ad46 +262, 0x7bf4165ddb7e4374 +263, 0xd05f7996d7941010 +264, 0x3b3991de97b45f14 +265, 0x9068217fb4f27a30 +266, 0xd8fe295160afc7f3 +267, 0x8a159fab4c3bc06f +268, 0x57855506d19080b6 +269, 0x7636df6b3f2367a4 +270, 0x2844ee3abd1d5ec9 +271, 0xe5788de061f51c16 +272, 0x69e78cc9132a164 +273, 0xacd53cde6d8cd421 +274, 0xb23f3100068e91da +275, 0x4140070a47f53891 +276, 0xe4a422225a96e53a +277, 0xb82a8925a272a2ac +278, 0x7c2f9573590fe3b7 +279, 0xbaf80764db170575 +280, 0x955abffa54358368 +281, 0x355ce7460614a869 +282, 0x3700ede779a4afbf +283, 0x10a6ec01d92d68cd +284, 0x3308f5a0a4c0afef +285, 0x97b892d7601136c9 +286, 0x4955c3b941b8552e +287, 0xca85aa67e941961d +288, 0xb1859ae5db28e9d2 +289, 0x305d072ac1521fbd +290, 0xed52a868996085bb +291, 0x723bfa6a76358852 +292, 0x78d946ecd97c5fb3 +293, 0x39205b30a8e23e79 +294, 0xb927e3d086baadbe +295, 0xa18d6946136e1ff5 +296, 0xdab6f0b51c1eb5ff +297, 0xf0a640bf7a1af60c +298, 0xf0e81db09004d0d4 +299, 0xfe76cebdbe5a4dde +300, 0x2dafe9cc3decc376 +301, 0x4c871fdf1af34205 +302, 0xe79617d0c8fa893b +303, 0xee658aaad3a141f7 +304, 0xfd91aa74863e19f1 +305, 0x841b8f55c103cc22 +306, 0x22766ed65444ad5d +307, 0x56d03d1beca6c17a +308, 0x5fd4c112c92036ae +309, 0x75466ae58a5616dc +310, 0xfbf98b1081e802a9 +311, 0xdc325e957bf6d8f5 +312, 0xb08da7015ebd19b7 +313, 0xf25a9c0944f0c073 +314, 0xf4625bafa0ced718 +315, 0x4349c9e093a9e692 +316, 0x75a9ccd4dd8935cb +317, 0x7e6cf9e539361e91 +318, 0x20fdd22fb6edd475 +319, 0x5973021b57c2311f +320, 0x75392403667edc15 +321, 0xed9b2156ea70d9f1 +322, 0xf40c114db50b64a0 +323, 0xe26bb2c9eef20c62 +324, 0x409c1e3037869f03 +325, 0xcdfd71fdda3b7f91 +326, 0xa0dfae46816777d6 +327, 0xde060a8f61a8deb8 +328, 0x890e082a8b0ca4fc +329, 0xb9f2958eddf2d0db +330, 0xd17c148020d20e30 +331, 0xffdc9cc176fe7201 +332, 0xffb83d925b764c1 +333, 0x817ea639e313da8d +334, 0xa4dd335dd891ca91 +335, 0x1342d25a5e81f488 +336, 0xfa7eb9c3cf466b03 +337, 0xfe0a423d44b185d0 +338, 0x101cfd430ab96049 +339, 0x7b5d3eda9c4504b +340, 0xe20ccc006e0193f1 +341, 0xf54ccddedebc5df0 +342, 0xc0edd142bd58f1db +343, 0x3831f40d378d2430 +344, 0x80132353f0a88289 +345, 0x688f23c419d03ef8 +346, 0x4c6837e697884066 +347, 0x699387bb2e9a3a8f +348, 0x8996f860342448d8 +349, 0xb0f80dff99bfa5cc +350, 0x3e927a7f9ea12c8e +351, 0xd7e498d1e5f9dff3 +352, 0x78ecb97bb3f864cc +353, 0x3c4ffd069a014d38 +354, 0xf8d5073a1e09b4d4 +355, 0x8717e854f9faef23 +356, 0xfbcc5478d8d0ad7 +357, 0xd3cd8b233ca274ff +358, 0x8bd8f11f79beb265 +359, 0xf64498a832d8fd0e +360, 0xb01bba75112131ec +361, 0x55572445a7869781 +362, 0x7b56622f18cb3d7a +363, 0x7f192c9e075bdb83 +364, 0xd9a112f836b83ff3 +365, 0x68673b37269653dc +366, 0xe46a9433fb6a0879 +367, 0x127d756ca4779001 +368, 0xc1378e8b1e8eab94 +369, 0x1006edb0f51d078c +370, 0xc6dd53961232d926 +371, 0x9a4aeef44038256d +372, 0xd357f4fa652d4f5f +373, 0x59f3d2cc3378598 +374, 0xe76e6207a824a7fc +375, 0x5fc5e33712ceffef +376, 0x77d24aeb0ccb1adc +377, 0x5be4b2826805659e +378, 0x257c69d787e64634 +379, 0x58dd52ca6bc727b1 +380, 0x3ab997767235ea33 +381, 0x986a2a7a966fad14 +382, 0xc900f8b27761dcc4 +383, 0x44991bdb13795700 +384, 0xe5c145a4fe733b2 +385, 0x56f041b56bffe0d3 +386, 0x5779c4fef8067996 +387, 0xa0fe8748e829532d +388, 0x840c1277d78d9dd4 +389, 0x37ebcb315432acbc +390, 0xf4bc8738433ba3be +391, 0x8b122993f2e10062 +392, 0xe1fe8481f2681ed5 +393, 0x8e23f1630d9f494a +394, 0xda24661a01b7d0b3 +395, 0x7a02942a179cee36 +396, 0xf1e08a3c09b71ac +397, 0x3dec2cc7ee0bd8fd +398, 0x1f3e480113d805d4 +399, 0xc061b973ad4e3f2c +400, 0x6bea750f17a66836 +401, 0xbc2add72eac84c25 +402, 0xcff058d3f97934ca +403, 0x54ccc30987778ec2 +404, 0x93449ec1e1469558 +405, 0xe2ff369eb0c6836 +406, 0x41c2df2d63bf8e55 +407, 0xf9302629b6c71be2 +408, 0xdd30376b8e5ab29a +409, 0x12db9e04f911d754 +410, 0x8d03d6cd359f1b97 +411, 0xe15956511abf1cee +412, 0x9b68e10e2c2fd940 +413, 0x2e28de6491c1ce53 +414, 0x52b329b72d0c109d +415, 0xc2c0b115f9da2a60 +416, 0x6ca084105271bbff +417, 0x49b92b8676058c1e +418, 0x767fc92a70f7e5a3 +419, 0x87ba4ed4b65a6aa0 +420, 0xf70b052e0a3975e9 +421, 0x3e925c3306db9eec +422, 0x43253f1d96ac9513 +423, 0xe3e04f1a1ea454c4 +424, 0x763e3f4cc81ba0c8 +425, 0x2a2721ac69265705 +426, 0xdf3b0ac6416ea214 +427, 0xa6a6b57450f3e000 +428, 0xc3d3b1ac7dbfe6ac +429, 0xb66e5e6f7d2e4ec0 +430, 0x43c65296f98f0f04 +431, 0xdb0f6e3ff974d842 +432, 0x3d6b48e02ebb203b +433, 0xd74674ebf09d8f27 +434, 0xbe65243c58fc1200 +435, 0x55eb210a68d42625 +436, 0x87badab097dbe883 +437, 0xada3fda85a53824f +438, 0xef2791e8f48cd37a +439, 0x3fe7fceb927a641a +440, 0xd3bffd3ff031ac78 +441, 0xb94efe03da4d18fb +442, 0x162a0ad8da65ea68 +443, 0x300f234ef5b7e4a6 +444, 0xa2a8b4c77024e4fb +445, 0x5950f095ddd7b109 +446, 0xded66dd2b1bb02ba +447, 0x8ec24b7fa509bcb6 +448, 0x9bede53d924bdad6 +449, 0xa9c3f46423be1930 +450, 0x6dfc90597f8de8b4 +451, 0xb7419ebc65b434f0 +452, 0xa6596949238f58b9 +453, 0x966cbade640829b8 +454, 0x58c74877bdcbf65e +455, 0xaa103b8f89b0c453 +456, 0x219f0a86e41179a4 +457, 0x90f534fc06ddc57f +458, 0x8db7cdd644f1affa +459, 0x38f91de0167127ac +460, 0xdcd2a65e4df43daa +461, 0x3e04f34a7e01f834 +462, 0x5b237eea68007768 +463, 0x7ff4d2b015921768 +464, 0xf786b286549d3d51 +465, 0xaefa053fc2c3884c +466, 0x8e6a8ff381515d36 +467, 0x35b94f3d0a1fce3c +468, 0x165266d19e9abb64 +469, 0x1deb5caa5f9d8076 +470, 0x13ab91290c7cfe9d +471, 0x3651ca9856be3e05 +472, 0xe7b705f6e9cccc19 +473, 0xd6e7f79668c127ed +474, 0xa9faf37154896f92 +475, 0x89fbf190603e0ab1 +476, 0xb34d155a86f942d0 +477, 0xb2d4400a78bfdd76 +478, 0x7c0946aca8cfb3f0 +479, 0x7492771591c9d0e8 +480, 0xd084d95c5ca2eb28 +481, 0xb18d12bd3a6023e +482, 0xea217ed7b864d80b +483, 0xe52f69a755dd5c6f +484, 0x127133993d81c4aa +485, 0xe07188fcf1670bfb +486, 0x178fbfe668e4661d +487, 0x1c9ee14bb0cda154 +488, 0x8d043b96b6668f98 +489, 0xbc858986ec96ca2b +490, 0x7660f779d528b6b7 +491, 0xd448c6a1f74ae1d3 +492, 0x178e122cfc2a6862 +493, 0x236f000abaf2d23b +494, 0x171b27f3f0921915 +495, 0x4c3ff07652f50a70 +496, 0x18663e5e7d3a66ca +497, 0xb38c97946c750cc9 +498, 0xc5031aae6f78f909 +499, 0x4d1514e2925e95c1 +500, 0x4c2184a741dabfbb +501, 0xfd410364edf77182 +502, 0xc228157f863ee873 +503, 0x9856fdc735cc09fc +504, 0x660496cd1e41d60e +505, 0x2edf1d7e01954c32 +506, 0xd32e94639bdd98cf +507, 0x8e153f48709a77d +508, 0x89357f332d2d6561 +509, 0x1840d512c97085e6 +510, 0x2f18d035c9e26a85 +511, 0x77b88b1448b26d5b +512, 0xc1ca6ef4cdae0799 +513, 0xcc203f9e4508165f +514, 0xeaf762fbc9e0cbbe +515, 0xc070c687f3c4a290 +516, 0xd49ed321068d5c15 +517, 0x84a55eec17ee64ee +518, 0x4d8ee685298a8871 +519, 0x9ff5f17d7e029793 +520, 0x791d7d0d62e46302 +521, 0xab218b9114e22bc6 +522, 0x4902b7ab3f7119a7 +523, 0x694930f2e29b049e +524, 0x1a3c90650848999f +525, 0x79f1b9d8499c932b +526, 0xfacb6d3d55e3c92f +527, 0x8fd8b4f25a5da9f5 +528, 0xd037dcc3a7e62ae7 +529, 0xfecf57300d8f84f4 +530, 0x32079b1e1dc12d48 +531, 0xe5f8f1e62b288f54 +532, 0x97feba3a9c108894 +533, 0xd279a51e1899a9a0 +534, 0xd68eea8e8e363fa8 +535, 0x7394cf2deeca9386 +536, 0x5f70b0c80f1dbf10 +537, 0x8d646916ed40462 +538, 0xd253bb1c8a12bbb6 +539, 0x38f399a821fbd73e +540, 0x947523a26333ac90 +541, 0xb52e90affbc52a37 +542, 0xcf899cd964654da4 +543, 0xdf66ae9cca8d99e7 +544, 0x6051478e57c21b6a +545, 0xffa7dc975af3c1da +546, 0x195c7bff2d1a8f5 +547, 0x64f12b6575cf984d +548, 0x536034cb842cf9e1 +549, 0x180f247ce5bbfad +550, 0x8ced45081b134867 +551, 0x532bbfdf426710f3 +552, 0x4747933e74c4f54d +553, 0x197a890dc4793401 +554, 0x76c7cc2bd42fae2 +555, 0xdabfd67f69675dd0 +556, 0x85c690a68cdb3197 +557, 0xe482cec89ce8f92 +558, 0x20bc9fb7797011b1 +559, 0x76dc85a2185782ad +560, 0x3df37c164422117a +561, 0x99211f5d231e0ab0 +562, 0xef7fd794a0a91f4 +563, 0x419577151915f5fe +564, 0x3ce14a0a7135dae3 +565, 0x389b57598a075d6a +566, 0x8cc2a9d51b5af9aa +567, 0xe80a9beffbd13f13 +568, 0x65e96b22ea8a54d8 +569, 0x79f38c4164138ede +570, 0xd1955846cba03d81 +571, 0x60359fe58e4f26d6 +572, 0x4ea724f585f8d13e +573, 0x316dfdbadc801a3c +574, 0x20aa29b7c6dd66fe +575, 0x65eaf83a6a008caa +576, 0x407000aff1b9e8cb +577, 0xb4d49bfb2b268c40 +578, 0xd4e6fe8a7a0f14a9 +579, 0xe34afef924e8f58e +580, 0xe377b0c891844824 +581, 0x29c2e20c112d30c8 +582, 0x906aad1fe0c18a95 +583, 0x308385f0efbb6474 +584, 0xf23900481bf70445 +585, 0xfdfe3ade7f937a55 +586, 0xf37aae71c33c4f97 +587, 0x1c81e3775a8bed85 +588, 0x7eb5013882ce35ea +589, 0x37a1c1692495818d +590, 0x3f90ae118622a0ba +591, 0x58e4fe6fea29b037 +592, 0xd10ff1d269808825 +593, 0xbce30edb60c21bba +594, 0x123732329afd6fee +595, 0x429b4059f797d840 +596, 0x421166568a8c4be1 +597, 0x88f895c424c1bd7f +598, 0x2adaf7a7b9f781cb +599, 0xa425644b26cb698 +600, 0x8cc44d2486cc5743 +601, 0xdb9f357a33abf6ba +602, 0x1a57c4ea77a4d70c +603, 0x1dea29be75239e44 +604, 0x463141a137121a06 +605, 0x8fecfbbe0b8a9517 +606, 0x92c83984b3566123 +607, 0x3b1c69180ed28665 +608, 0x14a6073425ea8717 +609, 0x71f4c2b3283238d7 +610, 0xb3d491e3152f19f +611, 0x3a0ba3a11ebac5d2 +612, 0xddb4d1dd4c0f54ac +613, 0xdb8f36fe02414035 +614, 0x1cf5df5031b1902c +615, 0x23a20ed12ef95870 +616, 0xf113e573b2dedcbb +617, 0x308e2395cde0a9fa +618, 0xd377a22581c3a7da +619, 0xe0ced97a947a66fb +620, 0xe44f4de9cd754b00 +621, 0x2344943337d9d1bf +622, 0x4b5ae5e2ea6e749c +623, 0x9b8d2e3ef41d1c01 +624, 0x59a5a53ebbd24c6b +625, 0x4f7611bf9e8a06fb +626, 0xea38c7b61361cd06 +627, 0xf125a2bfdd2c0c7 +628, 0x2df8dcb5926b9ebb +629, 0x233e18720cc56988 +630, 0x974c61379b4aa95e +631, 0xc7fe24c1c868910b +632, 0x818fd1affc82a842 +633, 0xcee92a952a26d38e +634, 0x8962f575ebcbf43 +635, 0x7770687e3678c460 +636, 0xdfb1db4ed1298117 +637, 0xb9db54cb03d434d3 +638, 0x34aebbf2244257ad +639, 0xd836db0cb210c490 +640, 0x935daed7138957cd +641, 0x3cd914b14e7948fd +642, 0xd0472e9ed0a0f7f0 +643, 0xa9df33dca697f75e +644, 0x15e9ea259398721a +645, 0x23eeba0f970abd60 +646, 0x2217fdf8bbe99a12 +647, 0x5ea490a95717b198 +648, 0xf4e2bfc28280b639 +649, 0x9d19916072d6f05c +650, 0x5e0387cab1734c6a +651, 0x93c2c8ac26e5f01e +652, 0xb0d934354d957eb1 +653, 0xee5099a1eef3188c +654, 0x8be0abca8edc1115 +655, 0x989a60845dbf5aa3 +656, 0x181c7ed964eee892 +657, 0x49838ea07481288d +658, 0x17dbc75d66116b2e +659, 0xa4cafb7a87c0117e +660, 0xab2d0ae44cdc2e6e +661, 0xdf802f2457e7da6 +662, 0x4b966c4b9187e124 +663, 0x62de9db6f4811e1a +664, 0x1e20485968bc62 +665, 0xe9ac288265caca94 +666, 0xc5c694d349aa8c1a +667, 0x3d67f2083d9bdf10 +668, 0x9a2468e503085486 +669, 0x9d6acd3dc152d1a3 +670, 0xca951e2aeee8df77 +671, 0x2707371af9cdd7b0 +672, 0x2347ae6a4eb5ecbd +673, 0x16abe5582cb426f +674, 0x523af4ff980bbccb +675, 0xb07a0f043e3694aa +676, 0x14d7c3da81b2de7 +677, 0xf471f1b8ac22305b +678, 0xdb087ffff9e18520 +679, 0x1a352db3574359e8 +680, 0x48d5431502cc7476 +681, 0x7c9b7e7003dfd1bf +682, 0x4f43a48aae987169 +683, 0x9a5d3eb66dedb3e9 +684, 0xa7b331af76a9f817 +685, 0xba440154b118ab2d +686, 0x64d22344ce24c9c6 +687, 0xa22377bd52bd043 +688, 0x9dfa1bb18ca6c5f7 +689, 0xdccf44a92f644c8b +690, 0xf623d0a49fd18145 +691, 0x556d5c37978e28b3 +692, 0xad96e32ce9d2bb8b +693, 0x2e479c120be52798 +694, 0x7501cf871af7b2f7 +695, 0xd02536a5d026a5b8 +696, 0x4b37ff53e76ab5a4 +697, 0xdb3a4039caaeab13 +698, 0x6cbd65e3b700c7be +699, 0x7367abd98761a147 +700, 0xf4f9ba216a35aa77 +701, 0xf88ca25ce921eb86 +702, 0xb211de082ec2cbf2 +703, 0xdd94aa46ec57e12e +704, 0xa967d74ad8210240 +705, 0xdaa1fada8cfa887 +706, 0x85901d081c4488ee +707, 0xcf67f79a699ef06 +708, 0x7f2f1f0de921ee14 +709, 0x28bc61e9d3f2328b +710, 0x3332f2963faf18e5 +711, 0x4167ac71fcf43a6 +712, 0x843c1746b0160b74 +713, 0xd9be80070c578a5e +714, 0xbd7250c9af1473e7 +715, 0x43f78afaa3647899 +716, 0x91c6b5dd715a75a5 +717, 0x29cc66c8a07bfef3 +718, 0x3f5c667311dc22be +719, 0x4f49cd47958260cd +720, 0xbef8be43d920b64e +721, 0x7a892a5f13061d8b +722, 0x9532f40125c819b1 +723, 0x924fca3045f8a564 +724, 0x9b2c6442453b0c20 +725, 0x7e21009085b8e793 +726, 0x9b98c17e17af59d2 +727, 0xba61acb73e3ae89a +728, 0xb9d61a710555c138 +729, 0xc2a425d80978974b +730, 0xa275e13592da7d67 +731, 0xe962103202d9ad0f +732, 0xbdf8367a4d6f33fd +733, 0xe59beb2f8648bdc8 +734, 0xb4c387d8fbc4ac1c +735, 0x5e3f276b63054b75 +736, 0xf27e616aa54d8464 +737, 0x3f271661d1cd7426 +738, 0x43a69dbee7502c78 +739, 0x8066fcea6df059a1 +740, 0x3c10f19409bdc993 +741, 0x6ba6f43fb21f23e0 +742, 0x9e182d70a5bccf09 +743, 0x1520783d2a63a199 +744, 0xba1dcc0c70b9cace +745, 0x1009e1e9b1032d8 +746, 0xf632f6a95fb0315 +747, 0x48e711c7114cbfff +748, 0xef281dcec67debf7 +749, 0x33789894d6abf59b +750, 0x6c8e541fffbe7f9c +751, 0x85417f13b08e0a88 +752, 0x9a581e36d589608f +753, 0x461dca50b1befd35 +754, 0x5a3231680dde6462 +755, 0xcc57acf729780b97 +756, 0x50301efef62e1054 +757, 0x675d042cd4f6bbc9 +758, 0x1652fdd3794384c9 +759, 0x1c93bbeeb763cd4d +760, 0x44b7240c4b105242 +761, 0x4c6af2a1b606ccfb +762, 0x18fc43ece2ec1a40 +763, 0x859a5511aeae8acb +764, 0x2f56826f1996ad2f +765, 0xa8e95ce8bb363bdf +766, 0xf4da396054e50e4b +767, 0x5493865e9895883c +768, 0x768e4c8b332ac0e3 +769, 0x32195d2aa583fca5 +770, 0xf2f353f21266bc15 +771, 0x43cddf1d021307d +772, 0x6031e3aa30300e4a +773, 0x4f1298469ac6088f +774, 0x4b4d450bafac574e +775, 0x23e1cf9c0582a22b +776, 0x2e9036980db49cd0 +777, 0xe4e228b113c411b2 +778, 0x8bddcdb82b51706 +779, 0xd2a7ea8288593629 +780, 0x67fe90e98fdda61 +781, 0x7b63494dba95717b +782, 0x105625904510d782 +783, 0xdf4aa2242454e50a +784, 0x32541d6cd7d6c7e3 +785, 0x5661fb432591cf3b +786, 0xce920a5ed047bce7 +787, 0xed4178a3c96eea8f +788, 0xe378cd996e39863b +789, 0x169e1fdc8e2b05e1 +790, 0xaee1812ef7149a96 +791, 0x648571c7453d12c5 +792, 0xb7b6bc9328573c43 +793, 0xe7fb969078e270d7 +794, 0xdfc2b1b8985f6e6f +795, 0x862b6527ee39a1aa +796, 0x1ee329aea91d7882 +797, 0x20d25324f2fe704 +798, 0xbfcc47401fc3bbfd +799, 0x1515cdc8d48b2904 +800, 0xbd6eefe86284261c +801, 0x9b1f28e3b35f22ee +802, 0x842a29d35e5aecda +803, 0xf2346109ad370765 +804, 0x24d68add5a71afd9 +805, 0x4a691421613d91e2 +806, 0x60e3058b3c244051 +807, 0x79194905cdaa5de8 +808, 0xe0e2df35c01e8987 +809, 0xe29b78beffbb5e4a +810, 0xcdcdbc020218c19e +811, 0x5ae0af8c16feae43 +812, 0x8109292feeaf14fa +813, 0x34113f7508dfa521 +814, 0xc062ac163f56730a +815, 0xf1660e66ec6d4c4c +816, 0x5966c55f60151c80 +817, 0x3865ae8ec934b17 +818, 0x472a7314afb055ec +819, 0x7a24277309a44a44 +820, 0x556e02dd35d38baa +821, 0x9849611a1bc96ec1 +822, 0xd176f5d5a8eb0843 +823, 0x44db12ec60510030 +824, 0x272e3a06a0030078 +825, 0x7c4764dbefc075ea +826, 0x910712f3735c1183 +827, 0xd49a2da74ae7aff6 +828, 0xcf9b3e6e8f776d71 +829, 0x27789fe3ec481a02 +830, 0x86659f82c6b5912b +831, 0xe044b3dbf339158c +832, 0x99d81f6bb62a37b0 +833, 0x5f5830c246fada9a +834, 0xe68abab1eeb432cb +835, 0x49c5c5ace04e104 +836, 0x1ac3871b3fc6771b +837, 0x773b39f32d070652 +838, 0x9c4138c2ae58b1f3 +839, 0xac41c63d7452ac60 +840, 0x9248826b245359e1 +841, 0x99bba1c7a64f1670 +842, 0xe0dc99ff4ebb92f2 +843, 0x113638652740f87c +844, 0xebf51e94da88cfc +845, 0x5441c344b81b2585 +846, 0xe1e69e0bc2de652a +847, 0xe9ab6d64ae42ed1e +848, 0x879af8730e305f31 +849, 0x36b9ad912c7e00d6 +850, 0x83ef5e9fca853886 +851, 0xda54d48bb20ea974 +852, 0x32c6d93aefa92aa2 +853, 0x4e887b2c3391847d +854, 0x50966e815f42b1b8 +855, 0x53411ac087832837 +856, 0x46f64fef79df4f29 +857, 0xb34aae3924cd272c +858, 0xf5ad455869a0adbe +859, 0x8351ded7144edac8 +860, 0xeb558af089677494 +861, 0x36ed71d69293a8d6 +862, 0x659f90bf5431b254 +863, 0x53349102b7519949 +864, 0x3db83e20b1713610 +865, 0x6d63f96090556254 +866, 0x4cc0467e8f45c645 +867, 0xb8840c4bd5cd4091 +868, 0xbd381463cc93d584 +869, 0x203410d878c2066d +870, 0x2ebea06213cf71c8 +871, 0x598e8fb75e3fceb4 +872, 0xdcca41ceba0fce02 +873, 0x61bf69212b56aae5 +874, 0x97eed7f70c9114fa +875, 0xf46f37a8b7a063f9 +876, 0x66c8f4ffe5bd6efa +877, 0xe43fd6efda2d4e32 +878, 0x12d6c799e5ad01de +879, 0x9ac83e7f8b709360 +880, 0xbbb7bb3c1957513d +881, 0x7f87c08d4b3796b0 +882, 0x9a7d1d74b6aa4a5c +883, 0xa4314530ff741b6f +884, 0x99a80c6b6f15fca8 +885, 0xd2fec81d6d5fc3ce +886, 0x15a98be1cc40cea +887, 0x98693eb7719366f3 +888, 0x36ccdc2a9e9d4de8 +889, 0x3c8208f63d77df25 +890, 0xca2e376e2343df6 +891, 0xcc9b17cbb54420c6 +892, 0x8724c44a64d7dcb8 +893, 0x9d00c6949ff33869 +894, 0xf4f8e584d2699372 +895, 0x88f4748cdd5a2d53 +896, 0xe215072a1205bc6d +897, 0x190934fe6d740442 +898, 0x7fac5c0ab2af106d +899, 0x1b86633a0bd84fa1 +900, 0x1293e54318492dfb +901, 0x433324fd390f34b9 +902, 0x4c5eb2c67a44643b +903, 0x59a6e281c388b0dd +904, 0xe78e03f9c44623b7 +905, 0x91307a93c768fc3d +906, 0xde8867b004d8e3ff +907, 0xdf52c3f57b7c5862 +908, 0x993f3e1d10358a92 +909, 0x9ccb10bc3e18662d +910, 0x45093ce48a114c73 +911, 0xd59d05979d26330a +912, 0x417c0e03300119a9 +913, 0x1c336500f90cde81 +914, 0x1c8ccd29ead9b85b +915, 0xb76baf3e55d4d950 +916, 0x133ad6196c75fd7e +917, 0x34200b0cde7ed560 +918, 0x9c7c3dacb213c8d9 +919, 0xd97563c4fd9bf1b6 +920, 0x5d910e871835b6cb +921, 0x7d46c4733a16bdf9 +922, 0xe41d73194ddc87b2 +923, 0x7d3d8a0855a465a9 +924, 0x70c2a8b5d3f90c0f +925, 0x9e7565ca5dccfe12 +926, 0x2c0acb4577aa51b1 +927, 0x3d2cd211145b79c7 +928, 0x15a7b17aa6da7732 +929, 0xab44a3730c27d780 +930, 0xf008bd6c802bde3a +931, 0x82ed86ddf3619f77 +932, 0xaabe982ab15c49f9 +933, 0x9bcad8fa6d8e58a4 +934, 0x8f39ed8243718aa1 +935, 0xe9489340e03e3cb6 +936, 0xc722314f5eefb8d0 +937, 0x870e8869a436df59 +938, 0x4dae75b8087a8204 +939, 0xe1d790f6ec6e425b +940, 0xafd39ea1b1d0ed09 +941, 0xdf2c99e464ddf08f +942, 0x74936d859ab9644d +943, 0x3871302164250e73 +944, 0x764b68921e911886 +945, 0x2a1d024b26bb9d66 +946, 0x797fba43918e75b4 +947, 0x62ec6d24ccca335b +948, 0xf4bd8b951762b520 +949, 0x9d450dede9119397 +950, 0x5393a26d10f8c124 +951, 0x6b74769392896b57 +952, 0x7f61dbcc0e328581 +953, 0x64e1df3884d0d94 +954, 0xba77dcdf23738c37 +955, 0xf8e288bc0a177475 +956, 0x4a8abfd1702ecb7d +957, 0x53f22886694736a7 +958, 0x8fc982597ced3e3 +959, 0x1bc46090f820fff7 +960, 0x8bd31f965d02229f +961, 0x65cd0cb29996ee53 +962, 0x702e0f4fcf8c2e9f +963, 0x293b77bff307a9a0 +964, 0x125a986b8b305788 +965, 0x416b0eea428ebf3c +966, 0xeac85421ab0e8469 +967, 0x7f5496095019aa68 +968, 0x1a96d7afbc708e0 +969, 0xb91262e6766e01e1 +970, 0xd0a549cc4ccc6954 +971, 0x75a9a073f50c8a0d +972, 0xae275d2c1c6cd23c +973, 0xcf159b5ec5d28fd4 +974, 0x75d0838ce9b92b +975, 0xd4eddcee6dc4677f +976, 0x6a0a8ad5df6b75b8 +977, 0x6f3fd0ef0f13ecc4 +978, 0xb75a5826c1a8f8a8 +979, 0xd47098bbc7943766 +980, 0x3d4ddd62d5f23dd1 +981, 0x760a904e4583841c +982, 0x2afeb5022b4cf1f +983, 0x66d5f653729f0a13 +984, 0x9a6a5ab62980d30f +985, 0xc332f5643bbf8d5b +986, 0x848fb702e4056a90 +987, 0xa057beaf3f9e8c5f +988, 0x6cc603e4560a6c6a +989, 0xec761811a7b23211 +990, 0xb14aa4090a82aaa5 +991, 0xe29d9d028a5b2dbb +992, 0x5564e53738d68f97 +993, 0xfabca36542eaaf3b +994, 0xb9912fcb782020a2 +995, 0xe865e01b349284fd +996, 0x540b5ff11c5f9274 +997, 0x3463f64e1e7451dc +998, 0xe15d3e2f33b735f8 +999, 0xf5433336eadef6e diff --git a/venv/Lib/site-packages/numpy/random/tests/data/sfc64-testset-2.csv b/venv/Lib/site-packages/numpy/random/tests/data/sfc64-testset-2.csv new file mode 100644 index 0000000..70aebd5 --- /dev/null +++ b/venv/Lib/site-packages/numpy/random/tests/data/sfc64-testset-2.csv @@ -0,0 +1,1001 @@ +seed, 0x0 +0, 0x91959e5fb96a6332 +1, 0x3c1dd8a25a7e9f21 +2, 0x657bdffc99798d9e +3, 0x1a04de320b19e022 +4, 0x65b92af0e5f3c61c +5, 0x9c84070ce8f743c0 +6, 0xbb10e573693cdb25 +7, 0xd65ea9e76b37fb6b +8, 0x503efd0e76c8ae66 +9, 0xd711dcd04c26d0f +10, 0x12f53f435814ac8c +11, 0xb392cd402cfc82bd +12, 0x461764550e06c889 +13, 0x716a48b3514e6979 +14, 0xdd0a322213c18ad7 +15, 0x6673a8ca0a05c4d7 +16, 0x2992ef333437f844 +17, 0xc4aaf7e8240b2aad +18, 0x6ab0a1af1f41474f +19, 0xb0bae400c226941d +20, 0xe5f80c2eeeab48c6 +21, 0x3832c6a93a4024bf +22, 0x280bd824fabe8368 +23, 0x66b626228321e5ff +24, 0xe0bdfba5325a307e +25, 0x3a5f65c6ef254e05 +26, 0x99ea12503cb02f94 +27, 0x5d01fd2db77d420b +28, 0x6959bf5f36b2368d +29, 0xd856e30c62b5f5be +30, 0xe33233e1d8140e66 +31, 0xb78be619d415fa8d +32, 0x4f943bb2cc63d3b +33, 0x9b1460b290952d81 +34, 0x19205d794826740e +35, 0x64617bd9d7a6a1ff +36, 0x30442124b55ea76a +37, 0xebbbc3b29d0333fc +38, 0x39235a0fe359751c +39, 0xf9629768891121aa +40, 0x32052f53f366e05a +41, 0x60cc5b412c925bc8 +42, 0xf8b7ecda1c0e5a9 +43, 0x195f036e170a2568 +44, 0xfe06d0381a9ca782 +45, 0x919d89e8b88eebbf +46, 0xa47fb30148cf0d43 +47, 0x5c983e99d5f9fd56 +48, 0xe7492cdb6a1d42cd +49, 0xf9cfe5c865b0cfd8 +50, 0x35b653367bbc3b99 +51, 0xb1d92f6f4d4e440b +52, 0x737e1d5bd87ed9c0 +53, 0x7a880ca1498f8e17 +54, 0x687dae8494f9a3f7 +55, 0x6bae1989f441d5d7 +56, 0x71ad3fa5a9195c2e +57, 0x16b3969779f5d03 +58, 0xd1bce2ac973f15b3 +59, 0xa114b1ee2ce0dcdd +60, 0x270d75c11eb1b8d5 +61, 0xc48ffa087c0a7bc +62, 0xaaf9dc48cda9848d +63, 0x8111cf10ef6e584d +64, 0x6736df6af40ee6f4 +65, 0x1a1a111682fbf98d +66, 0xeb217658e1cb3b5d +67, 0xcaf58a8b79de9dec +68, 0x25d0ffd63c88d7a1 +69, 0x4c498cd871b7f176 +70, 0x4069a6156eb0cf3c +71, 0xdf012f12edcdd867 +72, 0x7734c0ac8edb1689 +73, 0xed6960ac53dbc245 +74, 0x305e20da8868c661 +75, 0x5f0c7a3719956f95 +76, 0x66842bbe3b28895 +77, 0xb608bc9a31eac410 +78, 0xfcb17d5529503abd +79, 0x829ae5cbc29b92ee +80, 0x17f2f0027bc24f3a +81, 0x435926c33d8f44cc +82, 0x3ab899327098dbec +83, 0xaf78573b27f8ead8 +84, 0xa8b334fabcf8dc60 +85, 0xcdf3b366a6a303db +86, 0x8da9379dd62b34c8 +87, 0xb0ba511955f264a7 +88, 0x9d72e21a644f961d +89, 0xfac28382e2e7e710 +90, 0xd457065f048410aa +91, 0x1cae57d952563969 +92, 0x5a160a6223253e03 +93, 0x2c45df736d73c8bd +94, 0x7f651ebc6ad9cec5 +95, 0x77a6be96c7d2e7e7 +96, 0x1721fb1dbfd6546a +97, 0xf73f433ecff3c997 +98, 0xed1e80f680965bfe +99, 0x6705ad67a3003b30 +100, 0xac21134efcadb9f7 +101, 0x4d2ba0a91d456ac +102, 0x59da7b59434eb52b +103, 0x26c1d070fd414b5f +104, 0xed7079ddfce83d9a +105, 0x9277d21f88e0fb7a +106, 0xfae16b9a8d53d282 +107, 0xb08a0e2e405fdf7d +108, 0x2ea20df44229d6ec +109, 0x80e4634cd3612825 +110, 0xbe62e8aeba8f8a1a +111, 0x4981209769c190fb +112, 0xcec96ef14c7e1f65 +113, 0x73fe4457b47e7b53 +114, 0x1d66300677315c31 +115, 0xe26821290498c4cc +116, 0xf6110248fd8fb1c5 +117, 0x30fd7fe32dbd8be3 +118, 0x534ec9b910a2bd72 +119, 0x8f9bfe878bbf7382 +120, 0x4f4eb5295c0c2193 +121, 0xdeb22f03a913be9e +122, 0x40f716f8e2a8886c +123, 0xc65007d0e386cdb1 +124, 0x9bdd26d92b143a14 +125, 0xf644b0b77ea44625 +126, 0x75f5a53f6b01993a +127, 0xfe803e347bf41010 +128, 0x594bff5fa17bc360 +129, 0x3551edfb450373c7 +130, 0x898f9dad433615db +131, 0x923d2406daa26d49 +132, 0x99e07faccbc33426 +133, 0x7389f9ff4470f807 +134, 0xdc2a25957c6df90b +135, 0x33c6d8965ef3053f +136, 0x51a8f07e838f1ab +137, 0x91c5db369380274f +138, 0xc37de65ac56b207e +139, 0xfcc6d2375dde7f14 +140, 0xa4e6418bff505958 +141, 0x4b8b9f78e46953c4 +142, 0x255ab2e0f93cf278 +143, 0xdf650717af3d96ef +144, 0x2caa21cba3aae2b2 +145, 0xce7e46c6f393daa4 +146, 0x1d5b3573f9997ac7 +147, 0x5280c556e850847d +148, 0x32edc31bef920ad7 +149, 0xefaa6b0b08cf2c6 +150, 0x5151c99d97b111c5 +151, 0x35ccf4bf53d17590 +152, 0xa210d7bd8697b385 +153, 0xa9419f95738fbe61 +154, 0xdeccf93a1a4fdc90 +155, 0xd0ea3365b18e7a05 +156, 0x84122df6dcd31b9a +157, 0x33040a2125cea5f5 +158, 0xfe18306a862f6d86 +159, 0xdb97c8392e5c4457 +160, 0xc3e0fa735e80e422 +161, 0x7d106ff36467a0c1 +162, 0xb9825eecc720a76d +163, 0x7fefc6f771647081 +164, 0xf5df3f5b3977bf13 +165, 0x18fb22736d36f1e0 +166, 0xadc4637b4953abfc +167, 0x174e66d3e17974bd +168, 0xf1614c51df4db5db +169, 0x6664ecde5717b293 +170, 0xd5bc5b6839265c26 +171, 0xf6ca9ce1af3f1832 +172, 0xca696789a9d506ea +173, 0x7399c246c8f9d53 +174, 0xadf49049626417e2 +175, 0xbcd84af37d09ab91 +176, 0xbb41c177f3a3fa45 +177, 0x592becc814d55302 +178, 0xa88b4e65f6cfe5f7 +179, 0xa0a55e34ff879426 +180, 0x3c2ea6aa725b42b7 +181, 0x65ac4a407b1f9521 +182, 0xde63d53f7e88b556 +183, 0x18bc76696d015f40 +184, 0xd1363f2cd4c116a8 +185, 0x2fe859be19a48e4a +186, 0x83d6099b1415e656 +187, 0x43f2cbc1a4ee6410 +188, 0xb2eca3d3421c533d +189, 0xc52b98ea3f031f5d +190, 0xfe57eb01da07e9d1 +191, 0xf9377883537a6031 +192, 0x364030c05dac7add +193, 0x6815cb06b35d4404 +194, 0xceae2d4ce31894be +195, 0xc602bcdf6062bf6a +196, 0xc8e4bd8dcc6062e3 +197, 0x9c29e87b92a1a791 +198, 0x41e626b871ca9651 +199, 0x325c3d1fb8efbcd8 +200, 0x7dbbacf8e3419fb3 +201, 0x3602e72516bb7319 +202, 0x537a008ebd94d24b +203, 0xda7714fc9d4d161d +204, 0x1c8c73700e1b621b +205, 0x2749b80937d6c939 +206, 0x76ee6abac5b14d33 +207, 0xf18d1e92cb6a8b5c +208, 0x6ce9579d9291c721 +209, 0x60523c745a40e58 +210, 0x637f837fcc901757 +211, 0x2ff71b19661dc5b3 +212, 0x393ab586326ad16f +213, 0xa0970ea30fe742b7 +214, 0x570222d7f27fe5ae +215, 0x3b5806d43fd38629 +216, 0x129a0ad7420180c5 +217, 0x1c4726355778d52c +218, 0x7c1459cf77656499 +219, 0xfe038a0932132069 +220, 0x4c4cc317a937483a +221, 0xa333d24067e926ba +222, 0x401d9b6ab37f6ef2 +223, 0x87ad0e491ebe4a2a +224, 0xfc02f312e72d121d +225, 0xfde715b3b99767b2 +226, 0xd111c342ba521c92 +227, 0x83b221b10879c617 +228, 0x6a1bf5c01fdf4277 +229, 0x166bfc0c3f5892ee +230, 0x4608d556d7c57856 +231, 0x8d786857c95ece49 +232, 0x2d357445a1aca4ac +233, 0x79620dae28ecd796 +234, 0x90e715dc0f2201c4 +235, 0x173b68b4c9f4b665 +236, 0x4e14d040ebac4eef +237, 0xbd25960b4b892e +238, 0x911a199db6f1989d +239, 0xfe822d7c601fd2e0 +240, 0x9b4c1d58d8223a69 +241, 0x907c1891283843b0 +242, 0xf4868bf54061c4b2 +243, 0x17f8cd1fc24efd85 +244, 0xd44253f9af14c3aa +245, 0x16d0da0cb911d43c +246, 0x3c6a46615828e79a +247, 0x498591c1138e11a5 +248, 0xcc0f26336d0d6141 +249, 0x4d3ebc873212309a +250, 0x16bad7792d5c2c6a +251, 0x474215a80b2bbd11 +252, 0x7159848abd8492fc +253, 0x359341c50973685f +254, 0x27512ee7bf784a4a +255, 0x45228ea080f70447 +256, 0x880cab616500d50e +257, 0x12fae93f9830d56e +258, 0x6744ee64348d9acd +259, 0x484dada28cd2a828 +260, 0x98491d0729e41863 +261, 0x2f15aac43c2863b0 +262, 0x5727a34d77a1da0f +263, 0xa435cebef6a62eed +264, 0xd211697d57b053b0 +265, 0x65aa757b68bd557 +266, 0xe3a1b7a2d8a3e06a +267, 0x2adf64e67252a7a9 +268, 0xadadcb75cadee276 +269, 0x7934bc57ac8d97bf +270, 0xccff0d0f412e0606 +271, 0x101a82aa3e8f3db9 +272, 0xb0f2498094b4575c +273, 0xba2561d9ef26ed8a +274, 0xfbcd1268fc3febe1 +275, 0x9aa10bb19eb152e0 +276, 0xf496217a601a6d72 +277, 0xe4be1e4f2fa91363 +278, 0x473a602bf3dd68eb +279, 0xfe8ed2a48c26f4b5 +280, 0x20e94b1a00159476 +281, 0x93e1cb1c6af86ec7 +282, 0x4fcba3898f7442ba +283, 0x5150c3a3d94891df +284, 0x91cfce6c85b033ea +285, 0x625e8a832a806491 +286, 0x28c97ba72e3ec0b2 +287, 0x8e172de217c71ea1 +288, 0x926b80216c732639 +289, 0x28b19431a649ae3d +290, 0x57c039a6e95a3795 +291, 0xfbc354182fe52718 +292, 0x819dfd7c7d534cef +293, 0xabb4093a619ed44f +294, 0xe785b7ac6f656745 +295, 0xb647b4588b2f942f +296, 0x64cf870a14c72d27 +297, 0x6d4a4a2a0ba9b37e +298, 0x78bfb0427d7ce6b0 +299, 0x8dcc72b8bfc79ac6 +300, 0x1c14d915d5e76c99 +301, 0xaf48ddea6f096d79 +302, 0x51b39b67aa130d8 +303, 0x1aeeb39d4def06de +304, 0xd678092ffedfdd27 +305, 0x8f54787f325111d3 +306, 0xf2ca2e827beaa6bc +307, 0x339d134099e98545 +308, 0x1f6a8a7b33942e43 +309, 0x952c8065dbef669a +310, 0xe066aeb6690147f7 +311, 0xed25aa92cf58ebb6 +312, 0x7601edce215ef521 +313, 0xed1c5b396abd9434 +314, 0x4fd1e407535de9d5 +315, 0xccc8315a0d4d1441 +316, 0x85753e250bb86976 +317, 0xf232e469378761c3 +318, 0x81d691b8e9aef3c6 +319, 0x224a2f9cab0ad0e +320, 0x978f3d3e50007f4e +321, 0xd3713e6a6c0cbe60 +322, 0xcce8f1eadd41f80d +323, 0x34bda028a97d469 +324, 0x90e242fdf0f59183 +325, 0x4d749754fbc5f092 +326, 0x4399f5b7851cc87b +327, 0xcb921a5f25f6c5d7 +328, 0x120bf5d0162101 +329, 0x1304cc2aa352735a +330, 0xf7236c5d0d5d417b +331, 0xc31b320fc1654306 +332, 0xb468c6b23f3fb4e7 +333, 0xb5985b5bfaca4166 +334, 0x898285a1cd2f8375 +335, 0xa13493da372aa7c9 +336, 0x15c80c09c12634e7 +337, 0x9b765c5cc9d438bd +338, 0xee7da816a9201dcb +339, 0x92e269f73b5a248e +340, 0xa8086c5de81400ce +341, 0xe0053901853d42be +342, 0x821df32c012f433e +343, 0x17a6d69ca37387c7 +344, 0x2b10044bfba3501f +345, 0x8dfd262afc2e8515 +346, 0xd68c2c7b60226371 +347, 0xe81ac114e4416774 +348, 0x5896d60061ebc471 +349, 0xa996e3147811dbd1 +350, 0xa819c7b80ecb3661 +351, 0x982ad71b38afbc01 +352, 0xab152b65aa17b7fe +353, 0x4582bc282ef187ef +354, 0xab5a17fe8d9bc669 +355, 0x83664fa9cb0284b7 +356, 0x234c4b0091968f52 +357, 0x8ab5f51805688d37 +358, 0xe9e11186e0c53eda +359, 0x10df37ef1de2eccf +360, 0x780f1b0d52db968f +361, 0x50bd4ff292872cd5 +362, 0x51e681c265f5ad0 +363, 0x842c49660a527566 +364, 0x6e56ee026e9eda87 +365, 0x4cf39e40d8c80393 +366, 0x13e466df371f7e1f +367, 0xf2ce1799f38e028e +368, 0x833c8db7adc6ff0e +369, 0xc6e189abc2ec98f +370, 0xafebb3721283fec5 +371, 0xb49bc1eb5cc17bdc +372, 0xf1d02e818f5e4488 +373, 0xe5e9d5b41a1dd815 +374, 0xce8aca6573b1bfe5 +375, 0x9b0a5d70e268b1d5 +376, 0xf3c0503a8358f4de +377, 0x2681605dd755669d +378, 0xea265ca7601efc70 +379, 0xa93747f0a159439f +380, 0x62a86ede78a23e50 +381, 0xac8a18935c3d063c +382, 0x729c0a298f5059f5 +383, 0xbbf195e5b54399f4 +384, 0x38aa9d551f968900 +385, 0x3b3e700c58778caa +386, 0x68e6e33c4443957a +387, 0x7c56fc13eb269815 +388, 0xaf7daca39711804a +389, 0x50fde6d10f9544b3 +390, 0xf3d37159f6f6c03d +391, 0x82d298f5c1a71685 +392, 0x478661ac54c5002c +393, 0x6053768e1a324ae0 +394, 0xde8fb4a7e56707ea +395, 0xaa2809301faa8cf4 +396, 0x690a8d49fedd0722 +397, 0xe17c481b9c217de9 +398, 0x60d1d8a2b57288e3 +399, 0x149adfaadc6b0886 +400, 0xa3c18b6eb79cd5fa +401, 0x5774e3a091af5f58 +402, 0x2acca57ff30e5712 +403, 0x94454d67367c4b0c +404, 0x581b2985ac2df5ca +405, 0x71618e50744f3e70 +406, 0x270a7f3bd9a94ae6 +407, 0x3ef81af9bb36cd7b +408, 0x8a4a2592875254aa +409, 0x704ac6086fbb414a +410, 0xda774d5d3f57414d +411, 0xe20d3358b918ae9e +412, 0x934a6b9f7b91e247 +413, 0xf91649cde87ec42c +414, 0x248cec5f9b6ced30 +415, 0x56791809fd8d64ba +416, 0xf502b2765c1395f +417, 0x6b04ec973d75aa7f +418, 0xb0339f2794bb26f +419, 0x4c524636efbaea49 +420, 0x6bbf3876e9738748 +421, 0xf686524e754e9e24 +422, 0x8dafa05a42d19cd3 +423, 0xc5f069ab2434008e +424, 0x4fd64cc713cba76 +425, 0xdbf93450c881ed5f +426, 0x492e278ebabb59a2 +427, 0x993fddfde4542642 +428, 0xecde68a72c8d4e52 +429, 0xe0760b3074c311fd +430, 0x68dc0e7e06528707 +431, 0x52b50edf49c0fdc7 +432, 0xb2bd4185c138f412 +433, 0x431496d7e1d86f3 +434, 0xa4e605b037e26c44 +435, 0x58236ae1f0aca2b5 +436, 0x26c72c420fc314d8 +437, 0x20134e982ab99a2b +438, 0x544b59b8b211374b +439, 0x1301c42f3a14d993 +440, 0x52a6ea740f763b0f +441, 0xf209d70c2bebf119 +442, 0xac66a4ebc2aa1be +443, 0x683713ed35878788 +444, 0x2b5578acec06b80c +445, 0x86428efa11c45b36 +446, 0xb49010adb17d291e +447, 0x73b686bd8664b6be +448, 0x6d28ebf57b6884cc +449, 0x9712091230ff58d9 +450, 0xc9c91f74c38b286 +451, 0x776310ac41dc008e +452, 0x2f3739df0bf6a88e +453, 0x5792dc62b94db675 +454, 0x5715910d024b06af +455, 0xeb1dd745458da08 +456, 0xfce7b07ccfa851a7 +457, 0xc305f1e983ac368 +458, 0x485aa9519ac00bb0 +459, 0xa5354f6589fb0ea0 +460, 0x32fee02dfdbf4454 +461, 0x4d1ddc304bbefaaa +462, 0x789a270a1737e57e +463, 0x9f3072f4b1ed8156 +464, 0x4de3c00e89058120 +465, 0xb00a02529e0a86fa +466, 0x539f6f0edd845d9a +467, 0x85e578fe15a8c001 +468, 0xa12c8e1a72cce7d8 +469, 0xc6908abbc2b1828 +470, 0xcf70090774cbb38c +471, 0x3b636a6977b45d4a +472, 0xf0a731b220680b57 +473, 0x18973929f51443a8 +474, 0xe93e1fbe7eadabe +475, 0x8233730f0a6dfa02 +476, 0x66e50b6919b0ab74 +477, 0xb1aba87c97fd08a2 +478, 0xd4dffc1fbc117ad6 +479, 0x6f7fa65724b96e6a +480, 0x4bd5800dee92e0fa +481, 0xe18a959db6256da +482, 0xe53a291bc66df487 +483, 0xb7ec306a08651806 +484, 0x1847a6b80d2821e1 +485, 0xda50391283b14d39 +486, 0xacc4d3cd7cceb97a +487, 0x57f70185165b7bc6 +488, 0x302b6d597c3aaba7 +489, 0xa47f32d037eab51e +490, 0xe1509b4408abc559 +491, 0x4f30a1d7c2934157 +492, 0x2ad03e6c60b650b2 +493, 0x334d9c337b0a9064 +494, 0xc7f442821e7aac12 +495, 0xbcdeb09298694cdd +496, 0xe42402389f8f0fb4 +497, 0xe5de56af539df727 +498, 0x7017f9b2101ee240 +499, 0x1ee5e68d5b10001d +500, 0x436229051836387a +501, 0xcd532d6d6ec38fb7 +502, 0x30a66606fdf38272 +503, 0xfdaa2ab9cf798496 +504, 0x4277b4adec70e7df +505, 0x72cfc30256e0eaef +506, 0x3c3359fd9bd34917 +507, 0xb7aa89598856efb0 +508, 0xf72226f8bf299ef5 +509, 0x258c499275a4356f +510, 0x999a56bfc7f20d76 +511, 0x2b3e7432e20c18b +512, 0x2d1251332f760cb5 +513, 0x7420e0eea62157c5 +514, 0xe85c895aa27cec3d +515, 0x27a0545c7020d57c +516, 0xc68638a65b4fff0d +517, 0xfda473983a4ea747 +518, 0xd19fe65fb4c06062 +519, 0x6b1374e050ee15e4 +520, 0x80065ecd49bc4bef +521, 0x4ee655954bc838de +522, 0xe8fb777504a72299 +523, 0x86b652ea70f4bdde +524, 0xcdc9e0fbde7e4f33 +525, 0x352c0a50cd3ac56 +526, 0x4b8605d368be75dc +527, 0x1ac9ea8129efbc37 +528, 0x470325faa99f39c5 +529, 0x25dd7ef9adccf7a1 +530, 0x5ae2c7a03e965816 +531, 0xf733d2df59dacc7d +532, 0xa05bbf0a8a1a7a70 +533, 0xe8aa3f102846ef5f +534, 0xc9b85ec49ae71789 +535, 0xb904c14ed1cb1936 +536, 0x5ae618230b5f0444 +537, 0x97987fe47b5d7467 +538, 0xabb3aca8865ca761 +539, 0x38bfdf29d4508228 +540, 0x353654f408353330 +541, 0xeb7e92930ae4ef0d +542, 0xec50f1a7ca526b96 +543, 0xd5e2dc08b5697544 +544, 0x24c7fd69d5ec32df +545, 0x6f7e1095568b8620 +546, 0x6ed9c16ca13b3c8 +547, 0xe676ef460002130f +548, 0xa3a01a3992c4b430 +549, 0xe2130406c3b1f202 +550, 0xa8f7263e2aedcd20 +551, 0xc45d71ef2e35f507 +552, 0x37155594021da7ba +553, 0x22dc94f19de73159 +554, 0x7969fc6bffc5443f +555, 0x97def7e44faa6bfe +556, 0x8b940f5e8931d71f +557, 0xd95b1dd3f1a3fdd5 +558, 0x1c83bfdca615701a +559, 0xb7fcb56279ceca6b +560, 0xd84f8950f20dcd0 +561, 0xb03343698de3cbe0 +562, 0xf64565d448d71f71 +563, 0xda52b4676e0ae662 +564, 0xda39c2c05b4ffb91 +565, 0xb35e2560421f6a85 +566, 0x1a7b108d48ac3646 +567, 0xc4e264dc390d79ed +568, 0xa10727dfd9813256 +569, 0x40d23154e720e4f7 +570, 0xd9fa7cd7e313e119 +571, 0xcbf29107859e6013 +572, 0xc357338553d940b7 +573, 0x2641b7ab0bdfcbaa +574, 0xd12f2b6060533ae7 +575, 0xd0435aa626411c56 +576, 0x44af4a488a9cec72 +577, 0xb934232ea8fa5696 +578, 0x760a8b12072b572d +579, 0xfab18f9942cfa9b3 +580, 0x5676834c1fe84d16 +581, 0x9c54e4fddb353236 +582, 0xab49edfc9551f293 +583, 0x567f1fb45a871d +584, 0x32a967c873998834 +585, 0x99240aad380ef8d1 +586, 0x7f66cbd432859a64 +587, 0x4cdc8a4658166822 +588, 0x984e3984a5766492 +589, 0xa3b2d0a3d64d3d94 +590, 0x177f667172f2affc +591, 0xb1a90607a73a303f +592, 0xe600b6c36427f878 +593, 0xf758f9834cb7f466 +594, 0x8ee9fce4a3f36449 +595, 0xcb8f11533e7da347 +596, 0xe7cf647794dabd7c +597, 0xc9d92cfe6110806 +598, 0xea1335fa9145a1ec +599, 0xbc6c29821d094552 +600, 0x37b9d6a858cc8bc3 +601, 0xf24e4c694929893e +602, 0x55d025ce2d7d0004 +603, 0xccdc69acccf4267b +604, 0xc491c04340c222eb +605, 0xba50f75ecec9befb +606, 0x1ec7bd85b8fe3bb9 +607, 0xe4de66498c59ae8a +608, 0x38aa9e912712c889 +609, 0xcee0e43c5cc31566 +610, 0x72b69aa708fc7ed +611, 0xdff70b7f6fa96679 +612, 0xd6d71d82112aadc3 +613, 0x365177892cb78531 +614, 0xa54852b39de4f72c +615, 0x11dd5832bf16dd59 +616, 0x248a0f3369c97097 +617, 0xa14cec0260e26792 +618, 0x3517616ff142bed1 +619, 0x9b693ad39dab7636 +620, 0x739dff825e994434 +621, 0x67711e7356098c9 +622, 0xa81f8515d2fdf458 +623, 0xdac2908113fe568e +624, 0xe99944ebc6e2806a +625, 0x671728ca5b030975 +626, 0xfdad20edb2b4a789 +627, 0xedc6e466bd0369d2 +628, 0x88b5d469821f7e1b +629, 0x2eabf94049a522a5 +630, 0x247794b7a2f5a8e3 +631, 0x278942bdbe02c649 +632, 0xbe5a9a9196ab99c1 +633, 0x75955060866da1b5 +634, 0xdedcfa149273c0b5 +635, 0xdbeb7a57758f3867 +636, 0x7b9053347a2c8d5a +637, 0xa059b3f2eed338a5 +638, 0x59401a46ded3b79f +639, 0x38044ba56a6d19fb +640, 0x72c7221b4e77e779 +641, 0x526df3491a3a34da +642, 0xc3b31184ba16c0c2 +643, 0xd94c7144488624af +644, 0xcf966ee4dc373f91 +645, 0x62049e65dd416266 +646, 0x7c2adccb925bf8f +647, 0xd5fa5c22ed4ef8e1 +648, 0xd00134ebd11f2cd1 +649, 0xfbdf81767bed3634 +650, 0x62e8cc8ff66b6e26 +651, 0x3a72d6bcd4f2dcf7 +652, 0xf1cd45b1b46a86ed +653, 0x1271f98e0938bb9a +654, 0x82e6927e83dc31fa +655, 0x7b9b0e0acb67b92d +656, 0x6df503e397b2e701 +657, 0x93888f6fb561e0c3 +658, 0x393fb6069a40291 +659, 0x967a7d894cc0754d +660, 0x6e298996ad866333 +661, 0x5ff3cf5559d6ab46 +662, 0xd0d70508c40349f5 +663, 0xc64c66c0dd426b33 +664, 0x8fea340ee35c64dd +665, 0xf9cd381eb3060005 +666, 0xfcc37c2799fc0b11 +667, 0x6a37c91d65b489fa +668, 0x57231000fa0a0c9d +669, 0x55f6e292c6703f9a +670, 0xd0508ffbfa55a7a6 +671, 0x885db543276bdac8 +672, 0xc26dbe6a26b0e704 +673, 0x21f884874ebd709e +674, 0x711f0b6c8f732220 +675, 0x354d0a361eaee195 +676, 0x721344d8d30b006a +677, 0xa0e090a0d3a56f07 +678, 0x16b3d5d823a4952b +679, 0x59d7874bc9eae7b6 +680, 0x9bbb32710076455f +681, 0xd4fb22242ffabafd +682, 0xe1d4ac6770be1d89 +683, 0xb259cedebc73dc8a +684, 0x35faaa3b4246ab69 +685, 0x5d26addefdaee89 +686, 0x8e7ec350da0f3545 +687, 0xd0f316eed9f8fc79 +688, 0x98b2a52c9bf291b2 +689, 0xe4d294a8aca6a314 +690, 0x25bd554e6aa7673c +691, 0xcfde5dcba5be2a6c +692, 0xb5e01fb48d2d2107 +693, 0xe1caf28948028536 +694, 0xd434aa0a26f3ee9b +695, 0xd17723381641b8f6 +696, 0xfe73bd1f3f3768a2 +697, 0x1cc6b1abd08d67e9 +698, 0x247e328371a28de0 +699, 0x502e7942e5a9104a +700, 0x6a030fd242eb4502 +701, 0xa2ffe02744014ce8 +702, 0x59290763b18fe04e +703, 0xcf14241564271436 +704, 0xb0fb73c3c1503aff +705, 0x94e27c622f82137a +706, 0x747a5b406ac3e1f0 +707, 0x9a914e96a732031d +708, 0x59f68c6c8f078835 +709, 0x809d012c73eb4724 +710, 0x5b3c3b73e1b37d74 +711, 0xdde60ef3ba49cdf7 +712, 0x87a14e1f9c761986 +713, 0x4109b960604522af +714, 0x122d0e1ed0eb6bb9 +715, 0xadc0d29e80bfe33 +716, 0xa25b1b44f5fc8e4e +717, 0xbab85d8a9b793f20 +718, 0x825f4cbced0e7d1e +719, 0x2d6ae8807acb37ea +720, 0x8234420adce2e39 +721, 0x4a8ad4da6b804807 +722, 0x1e19f9bc215e5245 +723, 0x1d6f4848a916dd5e +724, 0x9ac40dfcdc2d39cc +725, 0x9f3524e3086155ec +726, 0x861fffc43124b2ef +727, 0xe640e3b756396372 +728, 0x41cb0f0c5e149669 +729, 0xe0bd37e1192e4205 +730, 0x62917d3858f4ce47 +731, 0xa36e7eb4d855820a +732, 0x204b90255a3bf724 +733, 0x66ee83a0175535bc +734, 0x2c14ce7c6b0c1423 +735, 0x85d9495fa514f70d +736, 0x5a4fe45ead874dbc +737, 0xe72248dcb8cfc863 +738, 0xfc21ff2932ed98cd +739, 0xcbba1edd735b5cad +740, 0x91ddc32809679bf5 +741, 0x192cdf2c7631ea1f +742, 0xbbc451ddf2ea286f +743, 0xad9e80cae2397a64 +744, 0x6918f0119b95d0e5 +745, 0xa40379017a27d70a +746, 0x1aaeddb600e61e1 +747, 0x15afd93cbd7adda9 +748, 0x156719bc2b757ff4 +749, 0x13d9a59e2b2df49d +750, 0x9a490986eaddf0a +751, 0xef9a350f0b3eb6b4 +752, 0x5de7f6295ba4fa4d +753, 0x7f37fd087c3fdb49 +754, 0xa9fe3749d6f3f209 +755, 0x50912ac036d9bfb +756, 0x982cb4d726a441f8 +757, 0x8ca8d8af59b872d0 +758, 0x7f8adfb0ceeade8a +759, 0xdad390ec742be44 +760, 0xa637944d0045be5b +761, 0x3569a3b3af807061 +762, 0x9599da8eae14511d +763, 0xc333e8d19589b01a +764, 0xfb9b524a20b571e1 +765, 0xbd9dc8b37ce5c3e1 +766, 0x142333005fa389ac +767, 0x1368bc37cd5bcce1 +768, 0x16094907ad6ecf73 +769, 0xb32c90dbba4c1130 +770, 0x82761d97c1747dd0 +771, 0x599f9f267ae3444d +772, 0x79ad3382994852e1 +773, 0x2511f06d9ef06e54 +774, 0xb35e6ab7d5bbddae +775, 0xfca9fa83a2988732 +776, 0x7d4350f0394ac3ba +777, 0xa52a9527bb176ea3 +778, 0xb49fa0ceb2aa8353 +779, 0x1f62e504d1468cc0 +780, 0xe1a77bfccce6efc3 +781, 0x776cdff4dc0d6797 +782, 0x56612e39b652c1f2 +783, 0x5f096a29294eda04 +784, 0x7978abc3aabd8b23 +785, 0x79dd875e0485b979 +786, 0x8a98aa4d5735d778 +787, 0xcca43940f69d2388 +788, 0xb2d4b156f144f93a +789, 0xbd528a676e9a862 +790, 0x2a394939c8e7ec5e +791, 0xb1da900c6efe4abc +792, 0x9869af479de4c034 +793, 0x78dbdfb88ac7c1db +794, 0x18cb169143088041 +795, 0xe69e5461c51a3e13 +796, 0x5389fa16ea98183c +797, 0xed7c80d1be1ea520 +798, 0x87246fc359758ced +799, 0xab323eba95fae4ed +800, 0xbc4c0dde7f8a1828 +801, 0xdb739f7955610b1a +802, 0xecd8c68c3434cc +803, 0x138c2eb88c477f44 +804, 0x28a65f96727aae41 +805, 0xdee879f2cf5629d +806, 0x684f0c90ef20070f +807, 0xa24a819ef5621800 +808, 0x8d0054f870e4fdcb +809, 0x99e8c6e695b600b +810, 0x50b705245891f7c3 +811, 0xc02eed3a6e58e51a +812, 0x443d64e95443606c +813, 0xca24959cfbd2d120 +814, 0xe072609ea48815bc +815, 0xbcc715026590315b +816, 0x3e76df24d7aa5938 +817, 0xd8ff04940d9b79ae +818, 0x54474ce790059bcd +819, 0x278390dd6aa70e81 +820, 0xf4df619fe35414e4 +821, 0x757d71270264e615 +822, 0x1e8a373699c11b23 +823, 0xef68c82046e67dd6 +824, 0xe280006599972620 +825, 0x234e095183b0f4d6 +826, 0xe3b7560ed9839749 +827, 0xcd5ec4086572332e +828, 0xc41c0d4aaa279108 +829, 0x4b9cd6126bc16a6d +830, 0x4a7252734f3e3dd0 +831, 0xb3132df156cc103a +832, 0xf9e4abbf7b64464a +833, 0xf936df27fb3c47b7 +834, 0x9142960873f6d71a +835, 0x4ba6aa3235cdb10d +836, 0x3237a2e765ba7766 +837, 0xd62f0b94c8e99e54 +838, 0x26b682f90a3ae41b +839, 0x40ad5e82072b6f81 +840, 0xd0198101f5484000 +841, 0xe4fac60ba11c332 +842, 0x472d0b0a95ef9d38 +843, 0x8512557aec5a3d8f +844, 0xef83169d3efd4de9 +845, 0x53fe89283e7a7676 +846, 0x2f50933053d69fc4 +847, 0x76f5e4362e2e53a2 +848, 0x8676fdccce28874a +849, 0x2737764c1fb1f821 +850, 0x4a6f70afc066ab55 +851, 0x27f8e151e310fca4 +852, 0xd606960ccbe85161 +853, 0xcce51d7ddd270a32 +854, 0xb4235999794875c2 +855, 0x580084e358e884 +856, 0x2159d5e6dc8586d7 +857, 0x87bd54d8599b3ba4 +858, 0x3e9ade6a2181664 +859, 0x5e6e140406d97623 +860, 0x511545d5aa0080a2 +861, 0xf49d78ed219aac57 +862, 0xbece1f9c90b8ea87 +863, 0x1c741cac36a2c514 +864, 0x7453c141047db967 +865, 0xd751832a5037eba2 +866, 0x71370a3f30ada1f7 +867, 0x7c01cf2dcb408631 +868, 0x1052a4fbdccc0fa1 +869, 0x13d525c9df3fb6c +870, 0xa3aa8dbfee760c55 +871, 0xc0288d200f5155cf +872, 0x79f4bcd12af567c3 +873, 0x8160d163bb548755 +874, 0x5cf2995fb69fd2df +875, 0xcc98ed01396639df +876, 0xad95f1d9cfc8256e +877, 0xa3df27d9fbdbfb9d +878, 0x83e5f5dda4d52929 +879, 0x9adc05043009f55b +880, 0xdfe8329dfde1c001 +881, 0x9980ccdd5298e6a2 +882, 0x636a7bd134f6ef56 +883, 0xef5ff780c4be6ba4 +884, 0x290d71dc77a56d16 +885, 0x6d65db9ff58de1e6 +886, 0x944b063b3805a696 +887, 0xce468ca2cce33008 +888, 0x5ba1ccb840f80f48 +889, 0x28ddce36fc9ad268 +890, 0x4f77ef254d507a21 +891, 0xce9b4057fadf3ab +892, 0xb518bc68298730e6 +893, 0xd2eb5b8e2ec665b0 +894, 0xe1583303a4f87344 +895, 0x9d5a0df4fbe1bed5 +896, 0x2ba9bc03ec8cfd07 +897, 0x479ed880a96ca669 +898, 0xcedf96338324771a +899, 0x312f4fc2da41ffaa +900, 0xa0eb9cf23b5e1ed8 +901, 0xf8f88f975dc3f539 +902, 0x4a37e185d0e96e0f +903, 0xf829654a5c0b46f9 +904, 0x3909cca7a7f8c7fb +905, 0x4c2e1d66ceb45105 +906, 0xaffaa19e1db8af87 +907, 0x9ec498246bd18c76 +908, 0x21d51558edc089da +909, 0xe8984112cd1b1561 +910, 0x7de1d2cf54b0c0e1 +911, 0xa06729aed50bfb9d +912, 0xcf19f733e5db19e1 +913, 0x70edf2624ab777cd +914, 0x46685becad10e078 +915, 0x825e0f6add46785 +916, 0x66d4af3b15f70de4 +917, 0xc676614b0666b21 +918, 0x282a916c864f5cb7 +919, 0x2707283a3f512167 +920, 0x37ff3afda7461623 +921, 0xc767eb1205e4ca86 +922, 0x46b359aecc4ea25b +923, 0x67fbbb797a16dbb1 +924, 0x64fd4ba57122290e +925, 0x8acc2a8ae59d8fac +926, 0x64a49298599acc67 +927, 0xedf00de67177ce30 +928, 0x1ea9d8d7e76d2d2c +929, 0x363fcac323f70eb2 +930, 0x19e6e3ec8a9712eb +931, 0xca541e96b0961f09 +932, 0x4d8fd34c2822ec46 +933, 0x2fdd56a50b32f705 +934, 0xaac2fcf251e3fd3 +935, 0xb0c600299e57045c +936, 0xd951ec589e909e38 +937, 0x4dc8414390cae508 +938, 0x537ef9d5e2321344 +939, 0xa57bc21fd31aa2dc +940, 0xa3a60df564183750 +941, 0xbe69a5ce2e369fb6 +942, 0x7744601f4c053ec8 +943, 0x3838452af42f2612 +944, 0xd4f0dad7115a54e9 +945, 0x629cf68d8009a624 +946, 0x2211c8fa34cb98cb +947, 0x8040b19e2213db83 +948, 0xb2a86d3ba2384fd +949, 0x4b85cec4f93f0dab +950, 0xc8d212d21ea6845d +951, 0x5b271a03a4fe2be0 +952, 0xff4f671319ad8434 +953, 0x8e615a919d5afa96 +954, 0xea7f47c53161160a +955, 0x33273930b13c6efc +956, 0x98eedda27fb59c3c +957, 0x188dc5e92e939677 +958, 0x9dbd0fa0911430f1 +959, 0x5b3dcf3fa75dfd2b +960, 0x3f03846febdb275d +961, 0x20cc24faea9e9cf6 +962, 0x854f3ac66199ff5d +963, 0x31169ac99d341e6f +964, 0xa85daed3c0bc1bbe +965, 0x64633711e71ba5dd +966, 0x530e79978dc73334 +967, 0x636f2ee6e20aef13 +968, 0xf6220f8b6d9a58fb +969, 0x425db8fa32141a7b +970, 0xac7c210f4b02be95 +971, 0x5fe8cfbe197a7754 +972, 0xfff7d40c79420ea +973, 0x5f8bab9ef4697b77 +974, 0xaf6fe54e45b23fe8 +975, 0xce79456ccc70bbce +976, 0x645ef680f48f1c00 +977, 0xa4dfac46e2028595 +978, 0x6bece4c41effc5df +979, 0xd316df886442641f +980, 0xa4f6ff994edd2a6 +981, 0x30281ae3cc49abe4 +982, 0x39acb7b663dea974 +983, 0x5e8829b01a7c06fb +984, 0x87bdb08cf027f13e +985, 0xdfa5ede784e802f6 +986, 0x46d03d55711c38cc +987, 0xa55a961fc9788306 +988, 0xbf09ded495a2e57a +989, 0xcd601b29a639cc16 +990, 0x2193ce026bfd1085 +991, 0x25ba27f3f225be13 +992, 0x6f685be82f64f2fe +993, 0xec8454108229c450 +994, 0x6e79d8d205447a44 +995, 0x9ed7b6a96b9ccd68 +996, 0xae7134b3b7f8ee37 +997, 0x66963de0e5ebcc02 +998, 0x29c8dcd0d17c423f +999, 0xfb8482c827eb90bc diff --git a/venv/Lib/site-packages/numpy/random/tests/test_direct.py b/venv/Lib/site-packages/numpy/random/tests/test_direct.py new file mode 100644 index 0000000..d602b36 --- /dev/null +++ b/venv/Lib/site-packages/numpy/random/tests/test_direct.py @@ -0,0 +1,425 @@ +import os +from os.path import join +import sys + +import numpy as np +from numpy.testing import (assert_equal, assert_allclose, assert_array_equal, + assert_raises) +import pytest + +from numpy.random import ( + Generator, MT19937, PCG64, Philox, RandomState, SeedSequence, SFC64, + default_rng +) +from numpy.random._common import interface + +try: + import cffi # noqa: F401 + + MISSING_CFFI = False +except ImportError: + MISSING_CFFI = True + +try: + import ctypes # noqa: F401 + + MISSING_CTYPES = False +except ImportError: + MISSING_CTYPES = False + +if sys.flags.optimize > 1: + # no docstrings present to inspect when PYTHONOPTIMIZE/Py_OptimizeFlag > 1 + # cffi cannot succeed + MISSING_CFFI = True + + +pwd = os.path.dirname(os.path.abspath(__file__)) + + +def assert_state_equal(actual, target): + for key in actual: + if isinstance(actual[key], dict): + assert_state_equal(actual[key], target[key]) + elif isinstance(actual[key], np.ndarray): + assert_array_equal(actual[key], target[key]) + else: + assert actual[key] == target[key] + + +def uniform32_from_uint64(x): + x = np.uint64(x) + upper = np.array(x >> np.uint64(32), dtype=np.uint32) + lower = np.uint64(0xffffffff) + lower = np.array(x & lower, dtype=np.uint32) + joined = np.column_stack([lower, upper]).ravel() + out = (joined >> np.uint32(9)) * (1.0 / 2 ** 23) + return out.astype(np.float32) + + +def uniform32_from_uint53(x): + x = np.uint64(x) >> np.uint64(16) + x = np.uint32(x & np.uint64(0xffffffff)) + out = (x >> np.uint32(9)) * (1.0 / 2 ** 23) + return out.astype(np.float32) + + +def uniform32_from_uint32(x): + return (x >> np.uint32(9)) * (1.0 / 2 ** 23) + + +def uniform32_from_uint(x, bits): + if bits == 64: + return uniform32_from_uint64(x) + elif bits == 53: + return uniform32_from_uint53(x) + elif bits == 32: + return uniform32_from_uint32(x) + else: + raise NotImplementedError + + +def uniform_from_uint(x, bits): + if bits in (64, 63, 53): + return uniform_from_uint64(x) + elif bits == 32: + return uniform_from_uint32(x) + + +def uniform_from_uint64(x): + return (x >> np.uint64(11)) * (1.0 / 9007199254740992.0) + + +def uniform_from_uint32(x): + out = np.empty(len(x) // 2) + for i in range(0, len(x), 2): + a = x[i] >> 5 + b = x[i + 1] >> 6 + out[i // 2] = (a * 67108864.0 + b) / 9007199254740992.0 + return out + + +def uniform_from_dsfmt(x): + return x.view(np.double) - 1.0 + + +def gauss_from_uint(x, n, bits): + if bits in (64, 63): + doubles = uniform_from_uint64(x) + elif bits == 32: + doubles = uniform_from_uint32(x) + else: # bits == 'dsfmt' + doubles = uniform_from_dsfmt(x) + gauss = [] + loc = 0 + x1 = x2 = 0.0 + while len(gauss) < n: + r2 = 2 + while r2 >= 1.0 or r2 == 0.0: + x1 = 2.0 * doubles[loc] - 1.0 + x2 = 2.0 * doubles[loc + 1] - 1.0 + r2 = x1 * x1 + x2 * x2 + loc += 2 + + f = np.sqrt(-2.0 * np.log(r2) / r2) + gauss.append(f * x2) + gauss.append(f * x1) + + return gauss[:n] + +def test_seedsequence(): + from numpy.random.bit_generator import (ISeedSequence, + ISpawnableSeedSequence, + SeedlessSeedSequence) + + s1 = SeedSequence(range(10), spawn_key=(1, 2), pool_size=6) + s1.spawn(10) + s2 = SeedSequence(**s1.state) + assert_equal(s1.state, s2.state) + assert_equal(s1.n_children_spawned, s2.n_children_spawned) + + # The interfaces cannot be instantiated themselves. + assert_raises(TypeError, ISeedSequence) + assert_raises(TypeError, ISpawnableSeedSequence) + dummy = SeedlessSeedSequence() + assert_raises(NotImplementedError, dummy.generate_state, 10) + assert len(dummy.spawn(10)) == 10 + + +class Base: + dtype = np.uint64 + data2 = data1 = {} + + @classmethod + def setup_class(cls): + cls.bit_generator = PCG64 + cls.bits = 64 + cls.dtype = np.uint64 + cls.seed_error_type = TypeError + cls.invalid_init_types = [] + cls.invalid_init_values = [] + + @classmethod + def _read_csv(cls, filename): + with open(filename) as csv: + seed = csv.readline() + seed = seed.split(',') + seed = [int(s.strip(), 0) for s in seed[1:]] + data = [] + for line in csv: + data.append(int(line.split(',')[-1].strip(), 0)) + return {'seed': seed, 'data': np.array(data, dtype=cls.dtype)} + + def test_raw(self): + bit_generator = self.bit_generator(*self.data1['seed']) + uints = bit_generator.random_raw(1000) + assert_equal(uints, self.data1['data']) + + bit_generator = self.bit_generator(*self.data1['seed']) + uints = bit_generator.random_raw() + assert_equal(uints, self.data1['data'][0]) + + bit_generator = self.bit_generator(*self.data2['seed']) + uints = bit_generator.random_raw(1000) + assert_equal(uints, self.data2['data']) + + def test_random_raw(self): + bit_generator = self.bit_generator(*self.data1['seed']) + uints = bit_generator.random_raw(output=False) + assert uints is None + uints = bit_generator.random_raw(1000, output=False) + assert uints is None + + def test_gauss_inv(self): + n = 25 + rs = RandomState(self.bit_generator(*self.data1['seed'])) + gauss = rs.standard_normal(n) + assert_allclose(gauss, + gauss_from_uint(self.data1['data'], n, self.bits)) + + rs = RandomState(self.bit_generator(*self.data2['seed'])) + gauss = rs.standard_normal(25) + assert_allclose(gauss, + gauss_from_uint(self.data2['data'], n, self.bits)) + + def test_uniform_double(self): + rs = Generator(self.bit_generator(*self.data1['seed'])) + vals = uniform_from_uint(self.data1['data'], self.bits) + uniforms = rs.random(len(vals)) + assert_allclose(uniforms, vals) + assert_equal(uniforms.dtype, np.float64) + + rs = Generator(self.bit_generator(*self.data2['seed'])) + vals = uniform_from_uint(self.data2['data'], self.bits) + uniforms = rs.random(len(vals)) + assert_allclose(uniforms, vals) + assert_equal(uniforms.dtype, np.float64) + + def test_uniform_float(self): + rs = Generator(self.bit_generator(*self.data1['seed'])) + vals = uniform32_from_uint(self.data1['data'], self.bits) + uniforms = rs.random(len(vals), dtype=np.float32) + assert_allclose(uniforms, vals) + assert_equal(uniforms.dtype, np.float32) + + rs = Generator(self.bit_generator(*self.data2['seed'])) + vals = uniform32_from_uint(self.data2['data'], self.bits) + uniforms = rs.random(len(vals), dtype=np.float32) + assert_allclose(uniforms, vals) + assert_equal(uniforms.dtype, np.float32) + + def test_repr(self): + rs = Generator(self.bit_generator(*self.data1['seed'])) + assert 'Generator' in repr(rs) + assert f'{id(rs):#x}'.upper().replace('X', 'x') in repr(rs) + + def test_str(self): + rs = Generator(self.bit_generator(*self.data1['seed'])) + assert 'Generator' in str(rs) + assert str(self.bit_generator.__name__) in str(rs) + assert f'{id(rs):#x}'.upper().replace('X', 'x') not in str(rs) + + def test_pickle(self): + import pickle + + bit_generator = self.bit_generator(*self.data1['seed']) + state = bit_generator.state + bitgen_pkl = pickle.dumps(bit_generator) + reloaded = pickle.loads(bitgen_pkl) + reloaded_state = reloaded.state + assert_array_equal(Generator(bit_generator).standard_normal(1000), + Generator(reloaded).standard_normal(1000)) + assert bit_generator is not reloaded + assert_state_equal(reloaded_state, state) + + ss = SeedSequence(100) + aa = pickle.loads(pickle.dumps(ss)) + assert_equal(ss.state, aa.state) + + def test_invalid_state_type(self): + bit_generator = self.bit_generator(*self.data1['seed']) + with pytest.raises(TypeError): + bit_generator.state = {'1'} + + def test_invalid_state_value(self): + bit_generator = self.bit_generator(*self.data1['seed']) + state = bit_generator.state + state['bit_generator'] = 'otherBitGenerator' + with pytest.raises(ValueError): + bit_generator.state = state + + def test_invalid_init_type(self): + bit_generator = self.bit_generator + for st in self.invalid_init_types: + with pytest.raises(TypeError): + bit_generator(*st) + + def test_invalid_init_values(self): + bit_generator = self.bit_generator + for st in self.invalid_init_values: + with pytest.raises((ValueError, OverflowError)): + bit_generator(*st) + + def test_benchmark(self): + bit_generator = self.bit_generator(*self.data1['seed']) + bit_generator._benchmark(1) + bit_generator._benchmark(1, 'double') + with pytest.raises(ValueError): + bit_generator._benchmark(1, 'int32') + + @pytest.mark.skipif(MISSING_CFFI, reason='cffi not available') + def test_cffi(self): + bit_generator = self.bit_generator(*self.data1['seed']) + cffi_interface = bit_generator.cffi + assert isinstance(cffi_interface, interface) + other_cffi_interface = bit_generator.cffi + assert other_cffi_interface is cffi_interface + + @pytest.mark.skipif(MISSING_CTYPES, reason='ctypes not available') + def test_ctypes(self): + bit_generator = self.bit_generator(*self.data1['seed']) + ctypes_interface = bit_generator.ctypes + assert isinstance(ctypes_interface, interface) + other_ctypes_interface = bit_generator.ctypes + assert other_ctypes_interface is ctypes_interface + + def test_getstate(self): + bit_generator = self.bit_generator(*self.data1['seed']) + state = bit_generator.state + alt_state = bit_generator.__getstate__() + assert_state_equal(state, alt_state) + + +class TestPhilox(Base): + @classmethod + def setup_class(cls): + cls.bit_generator = Philox + cls.bits = 64 + cls.dtype = np.uint64 + cls.data1 = cls._read_csv( + join(pwd, './data/philox-testset-1.csv')) + cls.data2 = cls._read_csv( + join(pwd, './data/philox-testset-2.csv')) + cls.seed_error_type = TypeError + cls.invalid_init_types = [] + cls.invalid_init_values = [(1, None, 1), (-1,), (None, None, 2 ** 257 + 1)] + + def test_set_key(self): + bit_generator = self.bit_generator(*self.data1['seed']) + state = bit_generator.state + keyed = self.bit_generator(counter=state['state']['counter'], + key=state['state']['key']) + assert_state_equal(bit_generator.state, keyed.state) + + +class TestPCG64(Base): + @classmethod + def setup_class(cls): + cls.bit_generator = PCG64 + cls.bits = 64 + cls.dtype = np.uint64 + cls.data1 = cls._read_csv(join(pwd, './data/pcg64-testset-1.csv')) + cls.data2 = cls._read_csv(join(pwd, './data/pcg64-testset-2.csv')) + cls.seed_error_type = (ValueError, TypeError) + cls.invalid_init_types = [(3.2,), ([None],), (1, None)] + cls.invalid_init_values = [(-1,)] + + def test_advance_symmetry(self): + rs = Generator(self.bit_generator(*self.data1['seed'])) + state = rs.bit_generator.state + step = -0x9e3779b97f4a7c150000000000000000 + rs.bit_generator.advance(step) + val_neg = rs.integers(10) + rs.bit_generator.state = state + rs.bit_generator.advance(2**128 + step) + val_pos = rs.integers(10) + rs.bit_generator.state = state + rs.bit_generator.advance(10 * 2**128 + step) + val_big = rs.integers(10) + assert val_neg == val_pos + assert val_big == val_pos + + +class TestMT19937(Base): + @classmethod + def setup_class(cls): + cls.bit_generator = MT19937 + cls.bits = 32 + cls.dtype = np.uint32 + cls.data1 = cls._read_csv(join(pwd, './data/mt19937-testset-1.csv')) + cls.data2 = cls._read_csv(join(pwd, './data/mt19937-testset-2.csv')) + cls.seed_error_type = ValueError + cls.invalid_init_types = [] + cls.invalid_init_values = [(-1,)] + + def test_seed_float_array(self): + assert_raises(TypeError, self.bit_generator, np.array([np.pi])) + assert_raises(TypeError, self.bit_generator, np.array([-np.pi])) + assert_raises(TypeError, self.bit_generator, np.array([np.pi, -np.pi])) + assert_raises(TypeError, self.bit_generator, np.array([0, np.pi])) + assert_raises(TypeError, self.bit_generator, [np.pi]) + assert_raises(TypeError, self.bit_generator, [0, np.pi]) + + def test_state_tuple(self): + rs = Generator(self.bit_generator(*self.data1['seed'])) + bit_generator = rs.bit_generator + state = bit_generator.state + desired = rs.integers(2 ** 16) + tup = (state['bit_generator'], state['state']['key'], + state['state']['pos']) + bit_generator.state = tup + actual = rs.integers(2 ** 16) + assert_equal(actual, desired) + tup = tup + (0, 0.0) + bit_generator.state = tup + actual = rs.integers(2 ** 16) + assert_equal(actual, desired) + + +class TestSFC64(Base): + @classmethod + def setup_class(cls): + cls.bit_generator = SFC64 + cls.bits = 64 + cls.dtype = np.uint64 + cls.data1 = cls._read_csv( + join(pwd, './data/sfc64-testset-1.csv')) + cls.data2 = cls._read_csv( + join(pwd, './data/sfc64-testset-2.csv')) + cls.seed_error_type = (ValueError, TypeError) + cls.invalid_init_types = [(3.2,), ([None],), (1, None)] + cls.invalid_init_values = [(-1,)] + + +class TestDefaultRNG: + def test_seed(self): + for args in [(), (None,), (1234,), ([1234, 5678],)]: + rg = default_rng(*args) + assert isinstance(rg.bit_generator, PCG64) + + def test_passthrough(self): + bg = Philox() + rg = default_rng(bg) + assert rg.bit_generator is bg + rg2 = default_rng(rg) + assert rg2 is rg + assert rg2.bit_generator is bg diff --git a/venv/Lib/site-packages/numpy/random/tests/test_extending.py b/venv/Lib/site-packages/numpy/random/tests/test_extending.py new file mode 100644 index 0000000..99a819e --- /dev/null +++ b/venv/Lib/site-packages/numpy/random/tests/test_extending.py @@ -0,0 +1,95 @@ +import os +import pytest +import shutil +import subprocess +import sys +import warnings +import numpy as np + +try: + import cffi +except ImportError: + cffi = None + +if sys.flags.optimize > 1: + # no docstrings present to inspect when PYTHONOPTIMIZE/Py_OptimizeFlag > 1 + # cffi cannot succeed + cffi = None + +try: + with warnings.catch_warnings(record=True) as w: + # numba issue gh-4733 + warnings.filterwarnings('always', '', DeprecationWarning) + import numba +except ImportError: + numba = None + +try: + import cython + from Cython.Compiler.Version import version as cython_version +except ImportError: + cython = None +else: + from distutils.version import LooseVersion + # Cython 0.29.21 is required for Python 3.9 and there are + # other fixes in the 0.29 series that are needed even for earlier + # Python versions. + # Note: keep in sync with the one in pyproject.toml + required_version = LooseVersion('0.29.21') + if LooseVersion(cython_version) < required_version: + # too old or wrong cython, skip the test + cython = None + +@pytest.mark.skipif(cython is None, reason="requires cython") +@pytest.mark.slow +def test_cython(tmp_path): + srcdir = os.path.join(os.path.dirname(__file__), '..') + shutil.copytree(srcdir, tmp_path / 'random') + # build the examples and "install" them into a temporary directory + build_dir = tmp_path / 'random' / '_examples' / 'cython' + subprocess.check_call([sys.executable, 'setup.py', 'build', 'install', + '--prefix', str(tmp_path / 'installdir'), + '--single-version-externally-managed', + '--record', str(tmp_path/ 'tmp_install_log.txt'), + ], + cwd=str(build_dir), + ) + # gh-16162: make sure numpy's __init__.pxd was used for cython + # not really part of this test, but it is a convenient place to check + with open(build_dir / 'extending.c') as fid: + txt_to_find = 'NumPy API declarations from "numpy/__init__.pxd"' + for i, line in enumerate(fid): + if txt_to_find in line: + break + else: + assert False, ("Could not find '{}' in C file, " + "wrong pxd used".format(txt_to_find)) + # get the path to the so's + so1 = so2 = None + with open(tmp_path /'tmp_install_log.txt') as fid: + for line in fid: + if 'extending.' in line: + so1 = line.strip() + if 'extending_distributions' in line: + so2 = line.strip() + assert so1 is not None + assert so2 is not None + # import the so's without adding the directory to sys.path + from importlib.machinery import ExtensionFileLoader + extending = ExtensionFileLoader('extending', so1).load_module() + extending_distributions = ExtensionFileLoader('extending_distributions', so2).load_module() + + # actually test the cython c-extension + from numpy.random import PCG64 + values = extending_distributions.uniforms_ex(PCG64(0), 10, 'd') + assert values.shape == (10,) + assert values.dtype == np.float64 + +@pytest.mark.skipif(numba is None or cffi is None, + reason="requires numba and cffi") +def test_numba(): + from numpy.random._examples.numba import extending # noqa: F401 + +@pytest.mark.skipif(cffi is None, reason="requires cffi") +def test_cffi(): + from numpy.random._examples.cffi import extending # noqa: F401 diff --git a/venv/Lib/site-packages/numpy/random/tests/test_generator_mt19937.py b/venv/Lib/site-packages/numpy/random/tests/test_generator_mt19937.py new file mode 100644 index 0000000..88b5c75 --- /dev/null +++ b/venv/Lib/site-packages/numpy/random/tests/test_generator_mt19937.py @@ -0,0 +1,2513 @@ +import sys +import hashlib + +import pytest + +import numpy as np +from numpy.linalg import LinAlgError +from numpy.testing import ( + assert_, assert_raises, assert_equal, assert_allclose, + assert_warns, assert_no_warnings, assert_array_equal, + assert_array_almost_equal, suppress_warnings) + +from numpy.random import Generator, MT19937, SeedSequence + +random = Generator(MT19937()) + +JUMP_TEST_DATA = [ + { + "seed": 0, + "steps": 10, + "initial": {"key_sha256": "bb1636883c2707b51c5b7fc26c6927af4430f2e0785a8c7bc886337f919f9edf", "pos": 9}, + "jumped": {"key_sha256": "ff682ac12bb140f2d72fba8d3506cf4e46817a0db27aae1683867629031d8d55", "pos": 598}, + }, + { + "seed":384908324, + "steps":312, + "initial": {"key_sha256": "16b791a1e04886ccbbb4d448d6ff791267dc458ae599475d08d5cced29d11614", "pos": 311}, + "jumped": {"key_sha256": "a0110a2cf23b56be0feaed8f787a7fc84bef0cb5623003d75b26bdfa1c18002c", "pos": 276}, + }, + { + "seed": [839438204, 980239840, 859048019, 821], + "steps": 511, + "initial": {"key_sha256": "d306cf01314d51bd37892d874308200951a35265ede54d200f1e065004c3e9ea", "pos": 510}, + "jumped": {"key_sha256": "0e00ab449f01a5195a83b4aee0dfbc2ce8d46466a640b92e33977d2e42f777f8", "pos": 475}, + }, +] + +@pytest.fixture(scope='module', params=[True, False]) +def endpoint(request): + return request.param + + +class TestSeed: + def test_scalar(self): + s = Generator(MT19937(0)) + assert_equal(s.integers(1000), 479) + s = Generator(MT19937(4294967295)) + assert_equal(s.integers(1000), 324) + + def test_array(self): + s = Generator(MT19937(range(10))) + assert_equal(s.integers(1000), 465) + s = Generator(MT19937(np.arange(10))) + assert_equal(s.integers(1000), 465) + s = Generator(MT19937([0])) + assert_equal(s.integers(1000), 479) + s = Generator(MT19937([4294967295])) + assert_equal(s.integers(1000), 324) + + def test_seedsequence(self): + s = MT19937(SeedSequence(0)) + assert_equal(s.random_raw(1), 2058676884) + + def test_invalid_scalar(self): + # seed must be an unsigned 32 bit integer + assert_raises(TypeError, MT19937, -0.5) + assert_raises(ValueError, MT19937, -1) + + def test_invalid_array(self): + # seed must be an unsigned integer + assert_raises(TypeError, MT19937, [-0.5]) + assert_raises(ValueError, MT19937, [-1]) + assert_raises(ValueError, MT19937, [1, -2, 4294967296]) + + def test_noninstantized_bitgen(self): + assert_raises(ValueError, Generator, MT19937) + + +class TestBinomial: + def test_n_zero(self): + # Tests the corner case of n == 0 for the binomial distribution. + # binomial(0, p) should be zero for any p in [0, 1]. + # This test addresses issue #3480. + zeros = np.zeros(2, dtype='int') + for p in [0, .5, 1]: + assert_(random.binomial(0, p) == 0) + assert_array_equal(random.binomial(zeros, p), zeros) + + def test_p_is_nan(self): + # Issue #4571. + assert_raises(ValueError, random.binomial, 1, np.nan) + + +class TestMultinomial: + def test_basic(self): + random.multinomial(100, [0.2, 0.8]) + + def test_zero_probability(self): + random.multinomial(100, [0.2, 0.8, 0.0, 0.0, 0.0]) + + def test_int_negative_interval(self): + assert_(-5 <= random.integers(-5, -1) < -1) + x = random.integers(-5, -1, 5) + assert_(np.all(-5 <= x)) + assert_(np.all(x < -1)) + + def test_size(self): + # gh-3173 + p = [0.5, 0.5] + assert_equal(random.multinomial(1, p, np.uint32(1)).shape, (1, 2)) + assert_equal(random.multinomial(1, p, np.uint32(1)).shape, (1, 2)) + assert_equal(random.multinomial(1, p, np.uint32(1)).shape, (1, 2)) + assert_equal(random.multinomial(1, p, [2, 2]).shape, (2, 2, 2)) + assert_equal(random.multinomial(1, p, (2, 2)).shape, (2, 2, 2)) + assert_equal(random.multinomial(1, p, np.array((2, 2))).shape, + (2, 2, 2)) + + assert_raises(TypeError, random.multinomial, 1, p, + float(1)) + + def test_invalid_prob(self): + assert_raises(ValueError, random.multinomial, 100, [1.1, 0.2]) + assert_raises(ValueError, random.multinomial, 100, [-.1, 0.9]) + + def test_invalid_n(self): + assert_raises(ValueError, random.multinomial, -1, [0.8, 0.2]) + assert_raises(ValueError, random.multinomial, [-1] * 10, [0.8, 0.2]) + + def test_p_non_contiguous(self): + p = np.arange(15.) + p /= np.sum(p[1::3]) + pvals = p[1::3] + random = Generator(MT19937(1432985819)) + non_contig = random.multinomial(100, pvals=pvals) + random = Generator(MT19937(1432985819)) + contig = random.multinomial(100, pvals=np.ascontiguousarray(pvals)) + assert_array_equal(non_contig, contig) + + def test_multidimensional_pvals(self): + assert_raises(ValueError, random.multinomial, 10, [[0, 1]]) + assert_raises(ValueError, random.multinomial, 10, [[0], [1]]) + assert_raises(ValueError, random.multinomial, 10, [[[0], [1]], [[1], [0]]]) + assert_raises(ValueError, random.multinomial, 10, np.array([[0, 1], [1, 0]])) + + +class TestMultivariateHypergeometric: + + def setup(self): + self.seed = 8675309 + + def test_argument_validation(self): + # Error cases... + + # `colors` must be a 1-d sequence + assert_raises(ValueError, random.multivariate_hypergeometric, + 10, 4) + + # Negative nsample + assert_raises(ValueError, random.multivariate_hypergeometric, + [2, 3, 4], -1) + + # Negative color + assert_raises(ValueError, random.multivariate_hypergeometric, + [-1, 2, 3], 2) + + # nsample exceeds sum(colors) + assert_raises(ValueError, random.multivariate_hypergeometric, + [2, 3, 4], 10) + + # nsample exceeds sum(colors) (edge case of empty colors) + assert_raises(ValueError, random.multivariate_hypergeometric, + [], 1) + + # Validation errors associated with very large values in colors. + assert_raises(ValueError, random.multivariate_hypergeometric, + [999999999, 101], 5, 1, 'marginals') + + int64_info = np.iinfo(np.int64) + max_int64 = int64_info.max + max_int64_index = max_int64 // int64_info.dtype.itemsize + assert_raises(ValueError, random.multivariate_hypergeometric, + [max_int64_index - 100, 101], 5, 1, 'count') + + @pytest.mark.parametrize('method', ['count', 'marginals']) + def test_edge_cases(self, method): + # Set the seed, but in fact, all the results in this test are + # deterministic, so we don't really need this. + random = Generator(MT19937(self.seed)) + + x = random.multivariate_hypergeometric([0, 0, 0], 0, method=method) + assert_array_equal(x, [0, 0, 0]) + + x = random.multivariate_hypergeometric([], 0, method=method) + assert_array_equal(x, []) + + x = random.multivariate_hypergeometric([], 0, size=1, method=method) + assert_array_equal(x, np.empty((1, 0), dtype=np.int64)) + + x = random.multivariate_hypergeometric([1, 2, 3], 0, method=method) + assert_array_equal(x, [0, 0, 0]) + + x = random.multivariate_hypergeometric([9, 0, 0], 3, method=method) + assert_array_equal(x, [3, 0, 0]) + + colors = [1, 1, 0, 1, 1] + x = random.multivariate_hypergeometric(colors, sum(colors), + method=method) + assert_array_equal(x, colors) + + x = random.multivariate_hypergeometric([3, 4, 5], 12, size=3, + method=method) + assert_array_equal(x, [[3, 4, 5]]*3) + + # Cases for nsample: + # nsample < 10 + # 10 <= nsample < colors.sum()/2 + # colors.sum()/2 < nsample < colors.sum() - 10 + # colors.sum() - 10 < nsample < colors.sum() + @pytest.mark.parametrize('nsample', [8, 25, 45, 55]) + @pytest.mark.parametrize('method', ['count', 'marginals']) + @pytest.mark.parametrize('size', [5, (2, 3), 150000]) + def test_typical_cases(self, nsample, method, size): + random = Generator(MT19937(self.seed)) + + colors = np.array([10, 5, 20, 25]) + sample = random.multivariate_hypergeometric(colors, nsample, size, + method=method) + if isinstance(size, int): + expected_shape = (size,) + colors.shape + else: + expected_shape = size + colors.shape + assert_equal(sample.shape, expected_shape) + assert_((sample >= 0).all()) + assert_((sample <= colors).all()) + assert_array_equal(sample.sum(axis=-1), + np.full(size, fill_value=nsample, dtype=int)) + if isinstance(size, int) and size >= 100000: + # This sample is large enough to compare its mean to + # the expected values. + assert_allclose(sample.mean(axis=0), + nsample * colors / colors.sum(), + rtol=1e-3, atol=0.005) + + def test_repeatability1(self): + random = Generator(MT19937(self.seed)) + sample = random.multivariate_hypergeometric([3, 4, 5], 5, size=5, + method='count') + expected = np.array([[2, 1, 2], + [2, 1, 2], + [1, 1, 3], + [2, 0, 3], + [2, 1, 2]]) + assert_array_equal(sample, expected) + + def test_repeatability2(self): + random = Generator(MT19937(self.seed)) + sample = random.multivariate_hypergeometric([20, 30, 50], 50, + size=5, + method='marginals') + expected = np.array([[ 9, 17, 24], + [ 7, 13, 30], + [ 9, 15, 26], + [ 9, 17, 24], + [12, 14, 24]]) + assert_array_equal(sample, expected) + + def test_repeatability3(self): + random = Generator(MT19937(self.seed)) + sample = random.multivariate_hypergeometric([20, 30, 50], 12, + size=5, + method='marginals') + expected = np.array([[2, 3, 7], + [5, 3, 4], + [2, 5, 5], + [5, 3, 4], + [1, 5, 6]]) + assert_array_equal(sample, expected) + + +class TestSetState: + def setup(self): + self.seed = 1234567890 + self.rg = Generator(MT19937(self.seed)) + self.bit_generator = self.rg.bit_generator + self.state = self.bit_generator.state + self.legacy_state = (self.state['bit_generator'], + self.state['state']['key'], + self.state['state']['pos']) + + def test_gaussian_reset(self): + # Make sure the cached every-other-Gaussian is reset. + old = self.rg.standard_normal(size=3) + self.bit_generator.state = self.state + new = self.rg.standard_normal(size=3) + assert_(np.all(old == new)) + + def test_gaussian_reset_in_media_res(self): + # When the state is saved with a cached Gaussian, make sure the + # cached Gaussian is restored. + + self.rg.standard_normal() + state = self.bit_generator.state + old = self.rg.standard_normal(size=3) + self.bit_generator.state = state + new = self.rg.standard_normal(size=3) + assert_(np.all(old == new)) + + def test_negative_binomial(self): + # Ensure that the negative binomial results take floating point + # arguments without truncation. + self.rg.negative_binomial(0.5, 0.5) + + +class TestIntegers: + rfunc = random.integers + + # valid integer/boolean types + itype = [bool, np.int8, np.uint8, np.int16, np.uint16, + np.int32, np.uint32, np.int64, np.uint64] + + def test_unsupported_type(self, endpoint): + assert_raises(TypeError, self.rfunc, 1, endpoint=endpoint, dtype=float) + + def test_bounds_checking(self, endpoint): + for dt in self.itype: + lbnd = 0 if dt is bool else np.iinfo(dt).min + ubnd = 2 if dt is bool else np.iinfo(dt).max + 1 + ubnd = ubnd - 1 if endpoint else ubnd + assert_raises(ValueError, self.rfunc, lbnd - 1, ubnd, + endpoint=endpoint, dtype=dt) + assert_raises(ValueError, self.rfunc, lbnd, ubnd + 1, + endpoint=endpoint, dtype=dt) + assert_raises(ValueError, self.rfunc, ubnd, lbnd, + endpoint=endpoint, dtype=dt) + assert_raises(ValueError, self.rfunc, 1, 0, endpoint=endpoint, + dtype=dt) + + assert_raises(ValueError, self.rfunc, [lbnd - 1], ubnd, + endpoint=endpoint, dtype=dt) + assert_raises(ValueError, self.rfunc, [lbnd], [ubnd + 1], + endpoint=endpoint, dtype=dt) + assert_raises(ValueError, self.rfunc, [ubnd], [lbnd], + endpoint=endpoint, dtype=dt) + assert_raises(ValueError, self.rfunc, 1, [0], + endpoint=endpoint, dtype=dt) + + def test_bounds_checking_array(self, endpoint): + for dt in self.itype: + lbnd = 0 if dt is bool else np.iinfo(dt).min + ubnd = 2 if dt is bool else np.iinfo(dt).max + (not endpoint) + + assert_raises(ValueError, self.rfunc, [lbnd - 1] * 2, [ubnd] * 2, + endpoint=endpoint, dtype=dt) + assert_raises(ValueError, self.rfunc, [lbnd] * 2, + [ubnd + 1] * 2, endpoint=endpoint, dtype=dt) + assert_raises(ValueError, self.rfunc, ubnd, [lbnd] * 2, + endpoint=endpoint, dtype=dt) + assert_raises(ValueError, self.rfunc, [1] * 2, 0, + endpoint=endpoint, dtype=dt) + + def test_rng_zero_and_extremes(self, endpoint): + for dt in self.itype: + lbnd = 0 if dt is bool else np.iinfo(dt).min + ubnd = 2 if dt is bool else np.iinfo(dt).max + 1 + ubnd = ubnd - 1 if endpoint else ubnd + is_open = not endpoint + + tgt = ubnd - 1 + assert_equal(self.rfunc(tgt, tgt + is_open, size=1000, + endpoint=endpoint, dtype=dt), tgt) + assert_equal(self.rfunc([tgt], tgt + is_open, size=1000, + endpoint=endpoint, dtype=dt), tgt) + + tgt = lbnd + assert_equal(self.rfunc(tgt, tgt + is_open, size=1000, + endpoint=endpoint, dtype=dt), tgt) + assert_equal(self.rfunc(tgt, [tgt + is_open], size=1000, + endpoint=endpoint, dtype=dt), tgt) + + tgt = (lbnd + ubnd) // 2 + assert_equal(self.rfunc(tgt, tgt + is_open, size=1000, + endpoint=endpoint, dtype=dt), tgt) + assert_equal(self.rfunc([tgt], [tgt + is_open], + size=1000, endpoint=endpoint, dtype=dt), + tgt) + + def test_rng_zero_and_extremes_array(self, endpoint): + size = 1000 + for dt in self.itype: + lbnd = 0 if dt is bool else np.iinfo(dt).min + ubnd = 2 if dt is bool else np.iinfo(dt).max + 1 + ubnd = ubnd - 1 if endpoint else ubnd + + tgt = ubnd - 1 + assert_equal(self.rfunc([tgt], [tgt + 1], + size=size, dtype=dt), tgt) + assert_equal(self.rfunc( + [tgt] * size, [tgt + 1] * size, dtype=dt), tgt) + assert_equal(self.rfunc( + [tgt] * size, [tgt + 1] * size, size=size, dtype=dt), tgt) + + tgt = lbnd + assert_equal(self.rfunc([tgt], [tgt + 1], + size=size, dtype=dt), tgt) + assert_equal(self.rfunc( + [tgt] * size, [tgt + 1] * size, dtype=dt), tgt) + assert_equal(self.rfunc( + [tgt] * size, [tgt + 1] * size, size=size, dtype=dt), tgt) + + tgt = (lbnd + ubnd) // 2 + assert_equal(self.rfunc([tgt], [tgt + 1], + size=size, dtype=dt), tgt) + assert_equal(self.rfunc( + [tgt] * size, [tgt + 1] * size, dtype=dt), tgt) + assert_equal(self.rfunc( + [tgt] * size, [tgt + 1] * size, size=size, dtype=dt), tgt) + + def test_full_range(self, endpoint): + # Test for ticket #1690 + + for dt in self.itype: + lbnd = 0 if dt is bool else np.iinfo(dt).min + ubnd = 2 if dt is bool else np.iinfo(dt).max + 1 + ubnd = ubnd - 1 if endpoint else ubnd + + try: + self.rfunc(lbnd, ubnd, endpoint=endpoint, dtype=dt) + except Exception as e: + raise AssertionError("No error should have been raised, " + "but one was with the following " + "message:\n\n%s" % str(e)) + + def test_full_range_array(self, endpoint): + # Test for ticket #1690 + + for dt in self.itype: + lbnd = 0 if dt is bool else np.iinfo(dt).min + ubnd = 2 if dt is bool else np.iinfo(dt).max + 1 + ubnd = ubnd - 1 if endpoint else ubnd + + try: + self.rfunc([lbnd] * 2, [ubnd], endpoint=endpoint, dtype=dt) + except Exception as e: + raise AssertionError("No error should have been raised, " + "but one was with the following " + "message:\n\n%s" % str(e)) + + def test_in_bounds_fuzz(self, endpoint): + # Don't use fixed seed + random = Generator(MT19937()) + + for dt in self.itype[1:]: + for ubnd in [4, 8, 16]: + vals = self.rfunc(2, ubnd - endpoint, size=2 ** 16, + endpoint=endpoint, dtype=dt) + assert_(vals.max() < ubnd) + assert_(vals.min() >= 2) + + vals = self.rfunc(0, 2 - endpoint, size=2 ** 16, endpoint=endpoint, + dtype=bool) + assert_(vals.max() < 2) + assert_(vals.min() >= 0) + + def test_scalar_array_equiv(self, endpoint): + for dt in self.itype: + lbnd = 0 if dt is bool else np.iinfo(dt).min + ubnd = 2 if dt is bool else np.iinfo(dt).max + 1 + ubnd = ubnd - 1 if endpoint else ubnd + + size = 1000 + random = Generator(MT19937(1234)) + scalar = random.integers(lbnd, ubnd, size=size, endpoint=endpoint, + dtype=dt) + + random = Generator(MT19937(1234)) + scalar_array = random.integers([lbnd], [ubnd], size=size, + endpoint=endpoint, dtype=dt) + + random = Generator(MT19937(1234)) + array = random.integers([lbnd] * size, [ubnd] * + size, size=size, endpoint=endpoint, dtype=dt) + assert_array_equal(scalar, scalar_array) + assert_array_equal(scalar, array) + + def test_repeatability(self, endpoint): + # We use a sha256 hash of generated sequences of 1000 samples + # in the range [0, 6) for all but bool, where the range + # is [0, 2). Hashes are for little endian numbers. + tgt = {'bool': '053594a9b82d656f967c54869bc6970aa0358cf94ad469c81478459c6a90eee3', + 'int16': '54de9072b6ee9ff7f20b58329556a46a447a8a29d67db51201bf88baa6e4e5d4', + 'int32': 'd3a0d5efb04542b25ac712e50d21f39ac30f312a5052e9bbb1ad3baa791ac84b', + 'int64': '14e224389ac4580bfbdccb5697d6190b496f91227cf67df60989de3d546389b1', + 'int8': '0e203226ff3fbbd1580f15da4621e5f7164d0d8d6b51696dd42d004ece2cbec1', + 'uint16': '54de9072b6ee9ff7f20b58329556a46a447a8a29d67db51201bf88baa6e4e5d4', + 'uint32': 'd3a0d5efb04542b25ac712e50d21f39ac30f312a5052e9bbb1ad3baa791ac84b', + 'uint64': '14e224389ac4580bfbdccb5697d6190b496f91227cf67df60989de3d546389b1', + 'uint8': '0e203226ff3fbbd1580f15da4621e5f7164d0d8d6b51696dd42d004ece2cbec1'} + + for dt in self.itype[1:]: + random = Generator(MT19937(1234)) + + # view as little endian for hash + if sys.byteorder == 'little': + val = random.integers(0, 6 - endpoint, size=1000, endpoint=endpoint, + dtype=dt) + else: + val = random.integers(0, 6 - endpoint, size=1000, endpoint=endpoint, + dtype=dt).byteswap() + + res = hashlib.sha256(val).hexdigest() + assert_(tgt[np.dtype(dt).name] == res) + + # bools do not depend on endianness + random = Generator(MT19937(1234)) + val = random.integers(0, 2 - endpoint, size=1000, endpoint=endpoint, + dtype=bool).view(np.int8) + res = hashlib.sha256(val).hexdigest() + assert_(tgt[np.dtype(bool).name] == res) + + def test_repeatability_broadcasting(self, endpoint): + for dt in self.itype: + lbnd = 0 if dt in (bool, np.bool_) else np.iinfo(dt).min + ubnd = 2 if dt in (bool, np.bool_) else np.iinfo(dt).max + 1 + ubnd = ubnd - 1 if endpoint else ubnd + + # view as little endian for hash + random = Generator(MT19937(1234)) + val = random.integers(lbnd, ubnd, size=1000, endpoint=endpoint, + dtype=dt) + + random = Generator(MT19937(1234)) + val_bc = random.integers([lbnd] * 1000, ubnd, endpoint=endpoint, + dtype=dt) + + assert_array_equal(val, val_bc) + + random = Generator(MT19937(1234)) + val_bc = random.integers([lbnd] * 1000, [ubnd] * 1000, + endpoint=endpoint, dtype=dt) + + assert_array_equal(val, val_bc) + + @pytest.mark.parametrize( + 'bound, expected', + [(2**32 - 1, np.array([517043486, 1364798665, 1733884389, 1353720612, + 3769704066, 1170797179, 4108474671])), + (2**32, np.array([517043487, 1364798666, 1733884390, 1353720613, + 3769704067, 1170797180, 4108474672])), + (2**32 + 1, np.array([517043487, 1733884390, 3769704068, 4108474673, + 1831631863, 1215661561, 3869512430]))] + ) + def test_repeatability_32bit_boundary(self, bound, expected): + for size in [None, len(expected)]: + random = Generator(MT19937(1234)) + x = random.integers(bound, size=size) + assert_equal(x, expected if size is not None else expected[0]) + + def test_repeatability_32bit_boundary_broadcasting(self): + desired = np.array([[[1622936284, 3620788691, 1659384060], + [1417365545, 760222891, 1909653332], + [3788118662, 660249498, 4092002593]], + [[3625610153, 2979601262, 3844162757], + [ 685800658, 120261497, 2694012896], + [1207779440, 1586594375, 3854335050]], + [[3004074748, 2310761796, 3012642217], + [2067714190, 2786677879, 1363865881], + [ 791663441, 1867303284, 2169727960]], + [[1939603804, 1250951100, 298950036], + [1040128489, 3791912209, 3317053765], + [3155528714, 61360675, 2305155588]], + [[ 817688762, 1335621943, 3288952434], + [1770890872, 1102951817, 1957607470], + [3099996017, 798043451, 48334215]]]) + for size in [None, (5, 3, 3)]: + random = Generator(MT19937(12345)) + x = random.integers([[-1], [0], [1]], + [2**32 - 1, 2**32, 2**32 + 1], + size=size) + assert_array_equal(x, desired if size is not None else desired[0]) + + def test_int64_uint64_broadcast_exceptions(self, endpoint): + configs = {np.uint64: ((0, 2**65), (-1, 2**62), (10, 9), (0, 0)), + np.int64: ((0, 2**64), (-(2**64), 2**62), (10, 9), (0, 0), + (-2**63-1, -2**63-1))} + for dtype in configs: + for config in configs[dtype]: + low, high = config + high = high - endpoint + low_a = np.array([[low]*10]) + high_a = np.array([high] * 10) + assert_raises(ValueError, random.integers, low, high, + endpoint=endpoint, dtype=dtype) + assert_raises(ValueError, random.integers, low_a, high, + endpoint=endpoint, dtype=dtype) + assert_raises(ValueError, random.integers, low, high_a, + endpoint=endpoint, dtype=dtype) + assert_raises(ValueError, random.integers, low_a, high_a, + endpoint=endpoint, dtype=dtype) + + low_o = np.array([[low]*10], dtype=object) + high_o = np.array([high] * 10, dtype=object) + assert_raises(ValueError, random.integers, low_o, high, + endpoint=endpoint, dtype=dtype) + assert_raises(ValueError, random.integers, low, high_o, + endpoint=endpoint, dtype=dtype) + assert_raises(ValueError, random.integers, low_o, high_o, + endpoint=endpoint, dtype=dtype) + + def test_int64_uint64_corner_case(self, endpoint): + # When stored in Numpy arrays, `lbnd` is casted + # as np.int64, and `ubnd` is casted as np.uint64. + # Checking whether `lbnd` >= `ubnd` used to be + # done solely via direct comparison, which is incorrect + # because when Numpy tries to compare both numbers, + # it casts both to np.float64 because there is + # no integer superset of np.int64 and np.uint64. However, + # `ubnd` is too large to be represented in np.float64, + # causing it be round down to np.iinfo(np.int64).max, + # leading to a ValueError because `lbnd` now equals + # the new `ubnd`. + + dt = np.int64 + tgt = np.iinfo(np.int64).max + lbnd = np.int64(np.iinfo(np.int64).max) + ubnd = np.uint64(np.iinfo(np.int64).max + 1 - endpoint) + + # None of these function calls should + # generate a ValueError now. + actual = random.integers(lbnd, ubnd, endpoint=endpoint, dtype=dt) + assert_equal(actual, tgt) + + def test_respect_dtype_singleton(self, endpoint): + # See gh-7203 + for dt in self.itype: + lbnd = 0 if dt is bool else np.iinfo(dt).min + ubnd = 2 if dt is bool else np.iinfo(dt).max + 1 + ubnd = ubnd - 1 if endpoint else ubnd + dt = np.bool_ if dt is bool else dt + + sample = self.rfunc(lbnd, ubnd, endpoint=endpoint, dtype=dt) + assert_equal(sample.dtype, dt) + + for dt in (bool, int, np.compat.long): + lbnd = 0 if dt is bool else np.iinfo(dt).min + ubnd = 2 if dt is bool else np.iinfo(dt).max + 1 + ubnd = ubnd - 1 if endpoint else ubnd + + # gh-7284: Ensure that we get Python data types + sample = self.rfunc(lbnd, ubnd, endpoint=endpoint, dtype=dt) + assert not hasattr(sample, 'dtype') + assert_equal(type(sample), dt) + + def test_respect_dtype_array(self, endpoint): + # See gh-7203 + for dt in self.itype: + lbnd = 0 if dt is bool else np.iinfo(dt).min + ubnd = 2 if dt is bool else np.iinfo(dt).max + 1 + ubnd = ubnd - 1 if endpoint else ubnd + dt = np.bool_ if dt is bool else dt + + sample = self.rfunc([lbnd], [ubnd], endpoint=endpoint, dtype=dt) + assert_equal(sample.dtype, dt) + sample = self.rfunc([lbnd] * 2, [ubnd] * 2, endpoint=endpoint, + dtype=dt) + assert_equal(sample.dtype, dt) + + def test_zero_size(self, endpoint): + # See gh-7203 + for dt in self.itype: + sample = self.rfunc(0, 0, (3, 0, 4), endpoint=endpoint, dtype=dt) + assert sample.shape == (3, 0, 4) + assert sample.dtype == dt + assert self.rfunc(0, -10, 0, endpoint=endpoint, + dtype=dt).shape == (0,) + assert_equal(random.integers(0, 0, size=(3, 0, 4)).shape, + (3, 0, 4)) + assert_equal(random.integers(0, -10, size=0).shape, (0,)) + assert_equal(random.integers(10, 10, size=0).shape, (0,)) + + def test_error_byteorder(self): + other_byteord_dt = 'i4' + with pytest.raises(ValueError): + random.integers(0, 200, size=10, dtype=other_byteord_dt) + + # chi2max is the maximum acceptable chi-squared value. + @pytest.mark.slow + @pytest.mark.parametrize('sample_size,high,dtype,chi2max', + [(5000000, 5, np.int8, 125.0), # p-value ~4.6e-25 + (5000000, 7, np.uint8, 150.0), # p-value ~7.7e-30 + (10000000, 2500, np.int16, 3300.0), # p-value ~3.0e-25 + (50000000, 5000, np.uint16, 6500.0), # p-value ~3.5e-25 + ]) + def test_integers_small_dtype_chisquared(self, sample_size, high, + dtype, chi2max): + # Regression test for gh-14774. + samples = random.integers(high, size=sample_size, dtype=dtype) + + values, counts = np.unique(samples, return_counts=True) + expected = sample_size / high + chi2 = ((counts - expected)**2 / expected).sum() + assert chi2 < chi2max + + +class TestRandomDist: + # Make sure the random distribution returns the correct value for a + # given seed + + def setup(self): + self.seed = 1234567890 + + def test_integers(self): + random = Generator(MT19937(self.seed)) + actual = random.integers(-99, 99, size=(3, 2)) + desired = np.array([[-80, -56], [41, 37], [-83, -16]]) + assert_array_equal(actual, desired) + + def test_integers_masked(self): + # Test masked rejection sampling algorithm to generate array of + # uint32 in an interval. + random = Generator(MT19937(self.seed)) + actual = random.integers(0, 99, size=(3, 2), dtype=np.uint32) + desired = np.array([[9, 21], [70, 68], [8, 41]], dtype=np.uint32) + assert_array_equal(actual, desired) + + def test_integers_closed(self): + random = Generator(MT19937(self.seed)) + actual = random.integers(-99, 99, size=(3, 2), endpoint=True) + desired = np.array([[-80, -56], [ 41, 38], [-83, -15]]) + assert_array_equal(actual, desired) + + def test_integers_max_int(self): + # Tests whether integers with closed=True can generate the + # maximum allowed Python int that can be converted + # into a C long. Previous implementations of this + # method have thrown an OverflowError when attempting + # to generate this integer. + actual = random.integers(np.iinfo('l').max, np.iinfo('l').max, + endpoint=True) + + desired = np.iinfo('l').max + assert_equal(actual, desired) + + def test_random(self): + random = Generator(MT19937(self.seed)) + actual = random.random((3, 2)) + desired = np.array([[0.096999199829214, 0.707517457682192], + [0.084364834598269, 0.767731206553125], + [0.665069021359413, 0.715487190596693]]) + assert_array_almost_equal(actual, desired, decimal=15) + + random = Generator(MT19937(self.seed)) + actual = random.random() + assert_array_almost_equal(actual, desired[0, 0], decimal=15) + + def test_random_float(self): + random = Generator(MT19937(self.seed)) + actual = random.random((3, 2)) + desired = np.array([[0.0969992 , 0.70751746], + [0.08436483, 0.76773121], + [0.66506902, 0.71548719]]) + assert_array_almost_equal(actual, desired, decimal=7) + + def test_random_float_scalar(self): + random = Generator(MT19937(self.seed)) + actual = random.random(dtype=np.float32) + desired = 0.0969992 + assert_array_almost_equal(actual, desired, decimal=7) + + def test_random_unsupported_type(self): + assert_raises(TypeError, random.random, dtype='int32') + + def test_choice_uniform_replace(self): + random = Generator(MT19937(self.seed)) + actual = random.choice(4, 4) + desired = np.array([0, 0, 2, 2], dtype=np.int64) + assert_array_equal(actual, desired) + + def test_choice_nonuniform_replace(self): + random = Generator(MT19937(self.seed)) + actual = random.choice(4, 4, p=[0.4, 0.4, 0.1, 0.1]) + desired = np.array([0, 1, 0, 1], dtype=np.int64) + assert_array_equal(actual, desired) + + def test_choice_uniform_noreplace(self): + random = Generator(MT19937(self.seed)) + actual = random.choice(4, 3, replace=False) + desired = np.array([2, 0, 3], dtype=np.int64) + assert_array_equal(actual, desired) + actual = random.choice(4, 4, replace=False, shuffle=False) + desired = np.arange(4, dtype=np.int64) + assert_array_equal(actual, desired) + + def test_choice_nonuniform_noreplace(self): + random = Generator(MT19937(self.seed)) + actual = random.choice(4, 3, replace=False, p=[0.1, 0.3, 0.5, 0.1]) + desired = np.array([0, 2, 3], dtype=np.int64) + assert_array_equal(actual, desired) + + def test_choice_noninteger(self): + random = Generator(MT19937(self.seed)) + actual = random.choice(['a', 'b', 'c', 'd'], 4) + desired = np.array(['a', 'a', 'c', 'c']) + assert_array_equal(actual, desired) + + def test_choice_multidimensional_default_axis(self): + random = Generator(MT19937(self.seed)) + actual = random.choice([[0, 1], [2, 3], [4, 5], [6, 7]], 3) + desired = np.array([[0, 1], [0, 1], [4, 5]]) + assert_array_equal(actual, desired) + + def test_choice_multidimensional_custom_axis(self): + random = Generator(MT19937(self.seed)) + actual = random.choice([[0, 1], [2, 3], [4, 5], [6, 7]], 1, axis=1) + desired = np.array([[0], [2], [4], [6]]) + assert_array_equal(actual, desired) + + def test_choice_exceptions(self): + sample = random.choice + assert_raises(ValueError, sample, -1, 3) + assert_raises(ValueError, sample, 3., 3) + assert_raises(ValueError, sample, [], 3) + assert_raises(ValueError, sample, [1, 2, 3, 4], 3, + p=[[0.25, 0.25], [0.25, 0.25]]) + assert_raises(ValueError, sample, [1, 2], 3, p=[0.4, 0.4, 0.2]) + assert_raises(ValueError, sample, [1, 2], 3, p=[1.1, -0.1]) + assert_raises(ValueError, sample, [1, 2], 3, p=[0.4, 0.4]) + assert_raises(ValueError, sample, [1, 2, 3], 4, replace=False) + # gh-13087 + assert_raises(ValueError, sample, [1, 2, 3], -2, replace=False) + assert_raises(ValueError, sample, [1, 2, 3], (-1,), replace=False) + assert_raises(ValueError, sample, [1, 2, 3], (-1, 1), replace=False) + assert_raises(ValueError, sample, [1, 2, 3], 2, + replace=False, p=[1, 0, 0]) + + def test_choice_return_shape(self): + p = [0.1, 0.9] + # Check scalar + assert_(np.isscalar(random.choice(2, replace=True))) + assert_(np.isscalar(random.choice(2, replace=False))) + assert_(np.isscalar(random.choice(2, replace=True, p=p))) + assert_(np.isscalar(random.choice(2, replace=False, p=p))) + assert_(np.isscalar(random.choice([1, 2], replace=True))) + assert_(random.choice([None], replace=True) is None) + a = np.array([1, 2]) + arr = np.empty(1, dtype=object) + arr[0] = a + assert_(random.choice(arr, replace=True) is a) + + # Check 0-d array + s = tuple() + assert_(not np.isscalar(random.choice(2, s, replace=True))) + assert_(not np.isscalar(random.choice(2, s, replace=False))) + assert_(not np.isscalar(random.choice(2, s, replace=True, p=p))) + assert_(not np.isscalar(random.choice(2, s, replace=False, p=p))) + assert_(not np.isscalar(random.choice([1, 2], s, replace=True))) + assert_(random.choice([None], s, replace=True).ndim == 0) + a = np.array([1, 2]) + arr = np.empty(1, dtype=object) + arr[0] = a + assert_(random.choice(arr, s, replace=True).item() is a) + + # Check multi dimensional array + s = (2, 3) + p = [0.1, 0.1, 0.1, 0.1, 0.4, 0.2] + assert_equal(random.choice(6, s, replace=True).shape, s) + assert_equal(random.choice(6, s, replace=False).shape, s) + assert_equal(random.choice(6, s, replace=True, p=p).shape, s) + assert_equal(random.choice(6, s, replace=False, p=p).shape, s) + assert_equal(random.choice(np.arange(6), s, replace=True).shape, s) + + # Check zero-size + assert_equal(random.integers(0, 0, size=(3, 0, 4)).shape, (3, 0, 4)) + assert_equal(random.integers(0, -10, size=0).shape, (0,)) + assert_equal(random.integers(10, 10, size=0).shape, (0,)) + assert_equal(random.choice(0, size=0).shape, (0,)) + assert_equal(random.choice([], size=(0,)).shape, (0,)) + assert_equal(random.choice(['a', 'b'], size=(3, 0, 4)).shape, + (3, 0, 4)) + assert_raises(ValueError, random.choice, [], 10) + + def test_choice_nan_probabilities(self): + a = np.array([42, 1, 2]) + p = [None, None, None] + assert_raises(ValueError, random.choice, a, p=p) + + def test_choice_p_non_contiguous(self): + p = np.ones(10) / 5 + p[1::2] = 3.0 + random = Generator(MT19937(self.seed)) + non_contig = random.choice(5, 3, p=p[::2]) + random = Generator(MT19937(self.seed)) + contig = random.choice(5, 3, p=np.ascontiguousarray(p[::2])) + assert_array_equal(non_contig, contig) + + def test_choice_return_type(self): + # gh 9867 + p = np.ones(4) / 4. + actual = random.choice(4, 2) + assert actual.dtype == np.int64 + actual = random.choice(4, 2, replace=False) + assert actual.dtype == np.int64 + actual = random.choice(4, 2, p=p) + assert actual.dtype == np.int64 + actual = random.choice(4, 2, p=p, replace=False) + assert actual.dtype == np.int64 + + def test_choice_large_sample(self): + choice_hash = '4266599d12bfcfb815213303432341c06b4349f5455890446578877bb322e222' + random = Generator(MT19937(self.seed)) + actual = random.choice(10000, 5000, replace=False) + if sys.byteorder != 'little': + actual = actual.byteswap() + res = hashlib.sha256(actual.view(np.int8)).hexdigest() + assert_(choice_hash == res) + + def test_bytes(self): + random = Generator(MT19937(self.seed)) + actual = random.bytes(10) + desired = b'\x86\xf0\xd4\x18\xe1\x81\t8%\xdd' + assert_equal(actual, desired) + + def test_shuffle(self): + # Test lists, arrays (of various dtypes), and multidimensional versions + # of both, c-contiguous or not: + for conv in [lambda x: np.array([]), + lambda x: x, + lambda x: np.asarray(x).astype(np.int8), + lambda x: np.asarray(x).astype(np.float32), + lambda x: np.asarray(x).astype(np.complex64), + lambda x: np.asarray(x).astype(object), + lambda x: [(i, i) for i in x], + lambda x: np.asarray([[i, i] for i in x]), + lambda x: np.vstack([x, x]).T, + # gh-11442 + lambda x: (np.asarray([(i, i) for i in x], + [("a", int), ("b", int)]) + .view(np.recarray)), + # gh-4270 + lambda x: np.asarray([(i, i) for i in x], + [("a", object, (1,)), + ("b", np.int32, (1,))])]: + random = Generator(MT19937(self.seed)) + alist = conv([1, 2, 3, 4, 5, 6, 7, 8, 9, 0]) + random.shuffle(alist) + actual = alist + desired = conv([4, 1, 9, 8, 0, 5, 3, 6, 2, 7]) + assert_array_equal(actual, desired) + + def test_shuffle_custom_axis(self): + random = Generator(MT19937(self.seed)) + actual = np.arange(16).reshape((4, 4)) + random.shuffle(actual, axis=1) + desired = np.array([[ 0, 3, 1, 2], + [ 4, 7, 5, 6], + [ 8, 11, 9, 10], + [12, 15, 13, 14]]) + assert_array_equal(actual, desired) + random = Generator(MT19937(self.seed)) + actual = np.arange(16).reshape((4, 4)) + random.shuffle(actual, axis=-1) + assert_array_equal(actual, desired) + + def test_shuffle_custom_axis_empty(self): + random = Generator(MT19937(self.seed)) + desired = np.array([]).reshape((0, 6)) + for axis in (0, 1): + actual = np.array([]).reshape((0, 6)) + random.shuffle(actual, axis=axis) + assert_array_equal(actual, desired) + + def test_shuffle_axis_nonsquare(self): + y1 = np.arange(20).reshape(2, 10) + y2 = y1.copy() + random = Generator(MT19937(self.seed)) + random.shuffle(y1, axis=1) + random = Generator(MT19937(self.seed)) + random.shuffle(y2.T) + assert_array_equal(y1, y2) + + def test_shuffle_masked(self): + # gh-3263 + a = np.ma.masked_values(np.reshape(range(20), (5, 4)) % 3 - 1, -1) + b = np.ma.masked_values(np.arange(20) % 3 - 1, -1) + a_orig = a.copy() + b_orig = b.copy() + for i in range(50): + random.shuffle(a) + assert_equal( + sorted(a.data[~a.mask]), sorted(a_orig.data[~a_orig.mask])) + random.shuffle(b) + assert_equal( + sorted(b.data[~b.mask]), sorted(b_orig.data[~b_orig.mask])) + + def test_shuffle_exceptions(self): + random = Generator(MT19937(self.seed)) + arr = np.arange(10) + assert_raises(np.AxisError, random.shuffle, arr, 1) + arr = np.arange(9).reshape((3, 3)) + assert_raises(np.AxisError, random.shuffle, arr, 3) + assert_raises(TypeError, random.shuffle, arr, slice(1, 2, None)) + arr = [[1, 2, 3], [4, 5, 6]] + assert_raises(NotImplementedError, random.shuffle, arr, 1) + + arr = np.array(3) + assert_raises(TypeError, random.shuffle, arr) + arr = np.ones((3, 2)) + assert_raises(np.AxisError, random.shuffle, arr, 2) + + def test_permutation(self): + random = Generator(MT19937(self.seed)) + alist = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0] + actual = random.permutation(alist) + desired = [4, 1, 9, 8, 0, 5, 3, 6, 2, 7] + assert_array_equal(actual, desired) + + random = Generator(MT19937(self.seed)) + arr_2d = np.atleast_2d([1, 2, 3, 4, 5, 6, 7, 8, 9, 0]).T + actual = random.permutation(arr_2d) + assert_array_equal(actual, np.atleast_2d(desired).T) + + bad_x_str = "abcd" + assert_raises(np.AxisError, random.permutation, bad_x_str) + + bad_x_float = 1.2 + assert_raises(np.AxisError, random.permutation, bad_x_float) + + random = Generator(MT19937(self.seed)) + integer_val = 10 + desired = [3, 0, 8, 7, 9, 4, 2, 5, 1, 6] + + actual = random.permutation(integer_val) + assert_array_equal(actual, desired) + + def test_permutation_custom_axis(self): + a = np.arange(16).reshape((4, 4)) + desired = np.array([[ 0, 3, 1, 2], + [ 4, 7, 5, 6], + [ 8, 11, 9, 10], + [12, 15, 13, 14]]) + random = Generator(MT19937(self.seed)) + actual = random.permutation(a, axis=1) + assert_array_equal(actual, desired) + random = Generator(MT19937(self.seed)) + actual = random.permutation(a, axis=-1) + assert_array_equal(actual, desired) + + def test_permutation_exceptions(self): + random = Generator(MT19937(self.seed)) + arr = np.arange(10) + assert_raises(np.AxisError, random.permutation, arr, 1) + arr = np.arange(9).reshape((3, 3)) + assert_raises(np.AxisError, random.permutation, arr, 3) + assert_raises(TypeError, random.permutation, arr, slice(1, 2, None)) + + @pytest.mark.parametrize("dtype", [int, object]) + @pytest.mark.parametrize("axis, expected", + [(None, np.array([[3, 7, 0, 9, 10, 11], + [8, 4, 2, 5, 1, 6]])), + (0, np.array([[6, 1, 2, 9, 10, 11], + [0, 7, 8, 3, 4, 5]])), + (1, np.array([[ 5, 3, 4, 0, 2, 1], + [11, 9, 10, 6, 8, 7]]))]) + def test_permuted(self, dtype, axis, expected): + random = Generator(MT19937(self.seed)) + x = np.arange(12).reshape(2, 6).astype(dtype) + random.permuted(x, axis=axis, out=x) + assert_array_equal(x, expected) + + random = Generator(MT19937(self.seed)) + x = np.arange(12).reshape(2, 6).astype(dtype) + y = random.permuted(x, axis=axis) + assert y.dtype == dtype + assert_array_equal(y, expected) + + def test_permuted_with_strides(self): + random = Generator(MT19937(self.seed)) + x0 = np.arange(22).reshape(2, 11) + x1 = x0.copy() + x = x0[:, ::3] + y = random.permuted(x, axis=1, out=x) + expected = np.array([[0, 9, 3, 6], + [14, 20, 11, 17]]) + assert_array_equal(y, expected) + x1[:, ::3] = expected + # Verify that the original x0 was modified in-place as expected. + assert_array_equal(x1, x0) + + def test_permuted_empty(self): + y = random.permuted([]) + assert_array_equal(y, []) + + @pytest.mark.parametrize('outshape', [(2, 3), 5]) + def test_permuted_out_with_wrong_shape(self, outshape): + a = np.array([1, 2, 3]) + out = np.zeros(outshape, dtype=a.dtype) + with pytest.raises(ValueError, match='same shape'): + random.permuted(a, out=out) + + def test_permuted_out_with_wrong_type(self): + out = np.zeros((3, 5), dtype=np.int32) + x = np.ones((3, 5)) + with pytest.raises(TypeError, match='Cannot cast'): + random.permuted(x, axis=1, out=out) + + def test_beta(self): + random = Generator(MT19937(self.seed)) + actual = random.beta(.1, .9, size=(3, 2)) + desired = np.array( + [[1.083029353267698e-10, 2.449965303168024e-11], + [2.397085162969853e-02, 3.590779671820755e-08], + [2.830254190078299e-04, 1.744709918330393e-01]]) + assert_array_almost_equal(actual, desired, decimal=15) + + def test_binomial(self): + random = Generator(MT19937(self.seed)) + actual = random.binomial(100.123, .456, size=(3, 2)) + desired = np.array([[42, 41], + [42, 48], + [44, 50]]) + assert_array_equal(actual, desired) + + random = Generator(MT19937(self.seed)) + actual = random.binomial(100.123, .456) + desired = 42 + assert_array_equal(actual, desired) + + def test_chisquare(self): + random = Generator(MT19937(self.seed)) + actual = random.chisquare(50, size=(3, 2)) + desired = np.array([[32.9850547060149, 39.0219480493301], + [56.2006134779419, 57.3474165711485], + [55.4243733880198, 55.4209797925213]]) + assert_array_almost_equal(actual, desired, decimal=13) + + def test_dirichlet(self): + random = Generator(MT19937(self.seed)) + alpha = np.array([51.72840233779265162, 39.74494232180943953]) + actual = random.dirichlet(alpha, size=(3, 2)) + desired = np.array([[[0.5439892869558927, 0.45601071304410745], + [0.5588917345860708, 0.4411082654139292 ]], + [[0.5632074165063435, 0.43679258349365657], + [0.54862581112627, 0.45137418887373015]], + [[0.49961831357047226, 0.5003816864295278 ], + [0.52374806183482, 0.47625193816517997]]]) + assert_array_almost_equal(actual, desired, decimal=15) + bad_alpha = np.array([5.4e-01, -1.0e-16]) + assert_raises(ValueError, random.dirichlet, bad_alpha) + + random = Generator(MT19937(self.seed)) + alpha = np.array([51.72840233779265162, 39.74494232180943953]) + actual = random.dirichlet(alpha) + assert_array_almost_equal(actual, desired[0, 0], decimal=15) + + def test_dirichlet_size(self): + # gh-3173 + p = np.array([51.72840233779265162, 39.74494232180943953]) + assert_equal(random.dirichlet(p, np.uint32(1)).shape, (1, 2)) + assert_equal(random.dirichlet(p, np.uint32(1)).shape, (1, 2)) + assert_equal(random.dirichlet(p, np.uint32(1)).shape, (1, 2)) + assert_equal(random.dirichlet(p, [2, 2]).shape, (2, 2, 2)) + assert_equal(random.dirichlet(p, (2, 2)).shape, (2, 2, 2)) + assert_equal(random.dirichlet(p, np.array((2, 2))).shape, (2, 2, 2)) + + assert_raises(TypeError, random.dirichlet, p, float(1)) + + def test_dirichlet_bad_alpha(self): + # gh-2089 + alpha = np.array([5.4e-01, -1.0e-16]) + assert_raises(ValueError, random.dirichlet, alpha) + + # gh-15876 + assert_raises(ValueError, random.dirichlet, [[5, 1]]) + assert_raises(ValueError, random.dirichlet, [[5], [1]]) + assert_raises(ValueError, random.dirichlet, [[[5], [1]], [[1], [5]]]) + assert_raises(ValueError, random.dirichlet, np.array([[5, 1], [1, 5]])) + + def test_dirichlet_alpha_non_contiguous(self): + a = np.array([51.72840233779265162, -1.0, 39.74494232180943953]) + alpha = a[::2] + random = Generator(MT19937(self.seed)) + non_contig = random.dirichlet(alpha, size=(3, 2)) + random = Generator(MT19937(self.seed)) + contig = random.dirichlet(np.ascontiguousarray(alpha), + size=(3, 2)) + assert_array_almost_equal(non_contig, contig) + + def test_dirichlet_small_alpha(self): + eps = 1.0e-9 # 1.0e-10 -> runtime x 10; 1e-11 -> runtime x 200, etc. + alpha = eps * np.array([1., 1.0e-3]) + random = Generator(MT19937(self.seed)) + actual = random.dirichlet(alpha, size=(3, 2)) + expected = np.array([ + [[1., 0.], + [1., 0.]], + [[1., 0.], + [1., 0.]], + [[1., 0.], + [1., 0.]] + ]) + assert_array_almost_equal(actual, expected, decimal=15) + + @pytest.mark.slow + def test_dirichlet_moderately_small_alpha(self): + # Use alpha.max() < 0.1 to trigger stick breaking code path + alpha = np.array([0.02, 0.04, 0.03]) + exact_mean = alpha / alpha.sum() + random = Generator(MT19937(self.seed)) + sample = random.dirichlet(alpha, size=20000000) + sample_mean = sample.mean(axis=0) + assert_allclose(sample_mean, exact_mean, rtol=1e-3) + + def test_exponential(self): + random = Generator(MT19937(self.seed)) + actual = random.exponential(1.1234, size=(3, 2)) + desired = np.array([[0.098845481066258, 1.560752510746964], + [0.075730916041636, 1.769098974710777], + [1.488602544592235, 2.49684815275751 ]]) + assert_array_almost_equal(actual, desired, decimal=15) + + def test_exponential_0(self): + assert_equal(random.exponential(scale=0), 0) + assert_raises(ValueError, random.exponential, scale=-0.) + + def test_f(self): + random = Generator(MT19937(self.seed)) + actual = random.f(12, 77, size=(3, 2)) + desired = np.array([[0.461720027077085, 1.100441958872451], + [1.100337455217484, 0.91421736740018 ], + [0.500811891303113, 0.826802454552058]]) + assert_array_almost_equal(actual, desired, decimal=15) + + def test_gamma(self): + random = Generator(MT19937(self.seed)) + actual = random.gamma(5, 3, size=(3, 2)) + desired = np.array([[ 5.03850858902096, 7.9228656732049 ], + [18.73983605132985, 19.57961681699238], + [18.17897755150825, 18.17653912505234]]) + assert_array_almost_equal(actual, desired, decimal=14) + + def test_gamma_0(self): + assert_equal(random.gamma(shape=0, scale=0), 0) + assert_raises(ValueError, random.gamma, shape=-0., scale=-0.) + + def test_geometric(self): + random = Generator(MT19937(self.seed)) + actual = random.geometric(.123456789, size=(3, 2)) + desired = np.array([[ 1, 10], + [ 1, 12], + [ 9, 10]]) + assert_array_equal(actual, desired) + + def test_geometric_exceptions(self): + assert_raises(ValueError, random.geometric, 1.1) + assert_raises(ValueError, random.geometric, [1.1] * 10) + assert_raises(ValueError, random.geometric, -0.1) + assert_raises(ValueError, random.geometric, [-0.1] * 10) + with np.errstate(invalid='ignore'): + assert_raises(ValueError, random.geometric, np.nan) + assert_raises(ValueError, random.geometric, [np.nan] * 10) + + def test_gumbel(self): + random = Generator(MT19937(self.seed)) + actual = random.gumbel(loc=.123456789, scale=2.0, size=(3, 2)) + desired = np.array([[ 4.688397515056245, -0.289514845417841], + [ 4.981176042584683, -0.633224272589149], + [-0.055915275687488, -0.333962478257953]]) + assert_array_almost_equal(actual, desired, decimal=15) + + def test_gumbel_0(self): + assert_equal(random.gumbel(scale=0), 0) + assert_raises(ValueError, random.gumbel, scale=-0.) + + def test_hypergeometric(self): + random = Generator(MT19937(self.seed)) + actual = random.hypergeometric(10.1, 5.5, 14, size=(3, 2)) + desired = np.array([[ 9, 9], + [ 9, 9], + [10, 9]]) + assert_array_equal(actual, desired) + + # Test nbad = 0 + actual = random.hypergeometric(5, 0, 3, size=4) + desired = np.array([3, 3, 3, 3]) + assert_array_equal(actual, desired) + + actual = random.hypergeometric(15, 0, 12, size=4) + desired = np.array([12, 12, 12, 12]) + assert_array_equal(actual, desired) + + # Test ngood = 0 + actual = random.hypergeometric(0, 5, 3, size=4) + desired = np.array([0, 0, 0, 0]) + assert_array_equal(actual, desired) + + actual = random.hypergeometric(0, 15, 12, size=4) + desired = np.array([0, 0, 0, 0]) + assert_array_equal(actual, desired) + + def test_laplace(self): + random = Generator(MT19937(self.seed)) + actual = random.laplace(loc=.123456789, scale=2.0, size=(3, 2)) + desired = np.array([[-3.156353949272393, 1.195863024830054], + [-3.435458081645966, 1.656882398925444], + [ 0.924824032467446, 1.251116432209336]]) + assert_array_almost_equal(actual, desired, decimal=15) + + def test_laplace_0(self): + assert_equal(random.laplace(scale=0), 0) + assert_raises(ValueError, random.laplace, scale=-0.) + + def test_logistic(self): + random = Generator(MT19937(self.seed)) + actual = random.logistic(loc=.123456789, scale=2.0, size=(3, 2)) + desired = np.array([[-4.338584631510999, 1.890171436749954], + [-4.64547787337966 , 2.514545562919217], + [ 1.495389489198666, 1.967827627577474]]) + assert_array_almost_equal(actual, desired, decimal=15) + + def test_lognormal(self): + random = Generator(MT19937(self.seed)) + actual = random.lognormal(mean=.123456789, sigma=2.0, size=(3, 2)) + desired = np.array([[ 0.0268252166335, 13.9534486483053], + [ 0.1204014788936, 2.2422077497792], + [ 4.2484199496128, 12.0093343977523]]) + assert_array_almost_equal(actual, desired, decimal=13) + + def test_lognormal_0(self): + assert_equal(random.lognormal(sigma=0), 1) + assert_raises(ValueError, random.lognormal, sigma=-0.) + + def test_logseries(self): + random = Generator(MT19937(self.seed)) + actual = random.logseries(p=.923456789, size=(3, 2)) + desired = np.array([[14, 17], + [3, 18], + [5, 1]]) + assert_array_equal(actual, desired) + + def test_logseries_exceptions(self): + with np.errstate(invalid='ignore'): + assert_raises(ValueError, random.logseries, np.nan) + assert_raises(ValueError, random.logseries, [np.nan] * 10) + + def test_multinomial(self): + random = Generator(MT19937(self.seed)) + actual = random.multinomial(20, [1 / 6.] * 6, size=(3, 2)) + desired = np.array([[[1, 5, 1, 6, 4, 3], + [4, 2, 6, 2, 4, 2]], + [[5, 3, 2, 6, 3, 1], + [4, 4, 0, 2, 3, 7]], + [[6, 3, 1, 5, 3, 2], + [5, 5, 3, 1, 2, 4]]]) + assert_array_equal(actual, desired) + + @pytest.mark.parametrize("method", ["svd", "eigh", "cholesky"]) + def test_multivariate_normal(self, method): + random = Generator(MT19937(self.seed)) + mean = (.123456789, 10) + cov = [[1, 0], [0, 1]] + size = (3, 2) + actual = random.multivariate_normal(mean, cov, size, method=method) + desired = np.array([[[-1.747478062846581, 11.25613495182354 ], + [-0.9967333370066214, 10.342002097029821 ]], + [[ 0.7850019631242964, 11.181113712443013 ], + [ 0.8901349653255224, 8.873825399642492 ]], + [[ 0.7130260107430003, 9.551628690083056 ], + [ 0.7127098726541128, 11.991709234143173 ]]]) + + assert_array_almost_equal(actual, desired, decimal=15) + + # Check for default size, was raising deprecation warning + actual = random.multivariate_normal(mean, cov, method=method) + desired = np.array([0.233278563284287, 9.424140804347195]) + assert_array_almost_equal(actual, desired, decimal=15) + # Check that non symmetric covariance input raises exception when + # check_valid='raises' if using default svd method. + mean = [0, 0] + cov = [[1, 2], [1, 2]] + assert_raises(ValueError, random.multivariate_normal, mean, cov, + check_valid='raise') + + # Check that non positive-semidefinite covariance warns with + # RuntimeWarning + cov = [[1, 2], [2, 1]] + assert_warns(RuntimeWarning, random.multivariate_normal, mean, cov) + assert_warns(RuntimeWarning, random.multivariate_normal, mean, cov, + method='eigh') + assert_raises(LinAlgError, random.multivariate_normal, mean, cov, + method='cholesky') + + # and that it doesn't warn with RuntimeWarning check_valid='ignore' + assert_no_warnings(random.multivariate_normal, mean, cov, + check_valid='ignore') + + # and that it raises with RuntimeWarning check_valid='raises' + assert_raises(ValueError, random.multivariate_normal, mean, cov, + check_valid='raise') + assert_raises(ValueError, random.multivariate_normal, mean, cov, + check_valid='raise', method='eigh') + + # check degenerate samples from singular covariance matrix + cov = [[1, 1], [1, 1]] + if method in ('svd', 'eigh'): + samples = random.multivariate_normal(mean, cov, size=(3, 2), + method=method) + assert_array_almost_equal(samples[..., 0], samples[..., 1], + decimal=6) + else: + assert_raises(LinAlgError, random.multivariate_normal, mean, cov, + method='cholesky') + + cov = np.array([[1, 0.1], [0.1, 1]], dtype=np.float32) + with suppress_warnings() as sup: + random.multivariate_normal(mean, cov, method=method) + w = sup.record(RuntimeWarning) + assert len(w) == 0 + + mu = np.zeros(2) + cov = np.eye(2) + assert_raises(ValueError, random.multivariate_normal, mean, cov, + check_valid='other') + assert_raises(ValueError, random.multivariate_normal, + np.zeros((2, 1, 1)), cov) + assert_raises(ValueError, random.multivariate_normal, + mu, np.empty((3, 2))) + assert_raises(ValueError, random.multivariate_normal, + mu, np.eye(3)) + + @pytest.mark.parametrize("method", ["svd", "eigh", "cholesky"]) + def test_multivariate_normal_basic_stats(self, method): + random = Generator(MT19937(self.seed)) + n_s = 1000 + mean = np.array([1, 2]) + cov = np.array([[2, 1], [1, 2]]) + s = random.multivariate_normal(mean, cov, size=(n_s,), method=method) + s_center = s - mean + cov_emp = (s_center.T @ s_center) / (n_s - 1) + # these are pretty loose and are only designed to detect major errors + assert np.all(np.abs(s_center.mean(-2)) < 0.1) + assert np.all(np.abs(cov_emp - cov) < 0.2) + + def test_negative_binomial(self): + random = Generator(MT19937(self.seed)) + actual = random.negative_binomial(n=100, p=.12345, size=(3, 2)) + desired = np.array([[543, 727], + [775, 760], + [600, 674]]) + assert_array_equal(actual, desired) + + def test_negative_binomial_exceptions(self): + with np.errstate(invalid='ignore'): + assert_raises(ValueError, random.negative_binomial, 100, np.nan) + assert_raises(ValueError, random.negative_binomial, 100, + [np.nan] * 10) + + def test_negative_binomial_p0_exception(self): + # Verify that p=0 raises an exception. + with assert_raises(ValueError): + x = random.negative_binomial(1, 0) + + def test_noncentral_chisquare(self): + random = Generator(MT19937(self.seed)) + actual = random.noncentral_chisquare(df=5, nonc=5, size=(3, 2)) + desired = np.array([[ 1.70561552362133, 15.97378184942111], + [13.71483425173724, 20.17859633310629], + [11.3615477156643 , 3.67891108738029]]) + assert_array_almost_equal(actual, desired, decimal=14) + + actual = random.noncentral_chisquare(df=.5, nonc=.2, size=(3, 2)) + desired = np.array([[9.41427665607629e-04, 1.70473157518850e-04], + [1.14554372041263e+00, 1.38187755933435e-03], + [1.90659181905387e+00, 1.21772577941822e+00]]) + assert_array_almost_equal(actual, desired, decimal=14) + + random = Generator(MT19937(self.seed)) + actual = random.noncentral_chisquare(df=5, nonc=0, size=(3, 2)) + desired = np.array([[0.82947954590419, 1.80139670767078], + [6.58720057417794, 7.00491463609814], + [6.31101879073157, 6.30982307753005]]) + assert_array_almost_equal(actual, desired, decimal=14) + + def test_noncentral_f(self): + random = Generator(MT19937(self.seed)) + actual = random.noncentral_f(dfnum=5, dfden=2, nonc=1, + size=(3, 2)) + desired = np.array([[0.060310671139 , 0.23866058175939], + [0.86860246709073, 0.2668510459738 ], + [0.23375780078364, 1.88922102885943]]) + assert_array_almost_equal(actual, desired, decimal=14) + + def test_noncentral_f_nan(self): + random = Generator(MT19937(self.seed)) + actual = random.noncentral_f(dfnum=5, dfden=2, nonc=np.nan) + assert np.isnan(actual) + + def test_normal(self): + random = Generator(MT19937(self.seed)) + actual = random.normal(loc=.123456789, scale=2.0, size=(3, 2)) + desired = np.array([[-3.618412914693162, 2.635726692647081], + [-2.116923463013243, 0.807460983059643], + [ 1.446547137248593, 2.485684213886024]]) + assert_array_almost_equal(actual, desired, decimal=15) + + def test_normal_0(self): + assert_equal(random.normal(scale=0), 0) + assert_raises(ValueError, random.normal, scale=-0.) + + def test_pareto(self): + random = Generator(MT19937(self.seed)) + actual = random.pareto(a=.123456789, size=(3, 2)) + desired = np.array([[1.0394926776069018e+00, 7.7142534343505773e+04], + [7.2640150889064703e-01, 3.4650454783825594e+05], + [4.5852344481994740e+04, 6.5851383009539105e+07]]) + # For some reason on 32-bit x86 Ubuntu 12.10 the [1, 0] entry in this + # matrix differs by 24 nulps. Discussion: + # https://mail.python.org/pipermail/numpy-discussion/2012-September/063801.html + # Consensus is that this is probably some gcc quirk that affects + # rounding but not in any important way, so we just use a looser + # tolerance on this test: + np.testing.assert_array_almost_equal_nulp(actual, desired, nulp=30) + + def test_poisson(self): + random = Generator(MT19937(self.seed)) + actual = random.poisson(lam=.123456789, size=(3, 2)) + desired = np.array([[0, 0], + [0, 0], + [0, 0]]) + assert_array_equal(actual, desired) + + def test_poisson_exceptions(self): + lambig = np.iinfo('int64').max + lamneg = -1 + assert_raises(ValueError, random.poisson, lamneg) + assert_raises(ValueError, random.poisson, [lamneg] * 10) + assert_raises(ValueError, random.poisson, lambig) + assert_raises(ValueError, random.poisson, [lambig] * 10) + with np.errstate(invalid='ignore'): + assert_raises(ValueError, random.poisson, np.nan) + assert_raises(ValueError, random.poisson, [np.nan] * 10) + + def test_power(self): + random = Generator(MT19937(self.seed)) + actual = random.power(a=.123456789, size=(3, 2)) + desired = np.array([[1.977857368842754e-09, 9.806792196620341e-02], + [2.482442984543471e-10, 1.527108843266079e-01], + [8.188283434244285e-02, 3.950547209346948e-01]]) + assert_array_almost_equal(actual, desired, decimal=15) + + def test_rayleigh(self): + random = Generator(MT19937(self.seed)) + actual = random.rayleigh(scale=10, size=(3, 2)) + desired = np.array([[ 4.51734079831581, 15.6802442485758 ], + [ 4.19850651287094, 17.08718809823704], + [14.7907457708776 , 15.85545333419775]]) + assert_array_almost_equal(actual, desired, decimal=14) + + def test_rayleigh_0(self): + assert_equal(random.rayleigh(scale=0), 0) + assert_raises(ValueError, random.rayleigh, scale=-0.) + + def test_standard_cauchy(self): + random = Generator(MT19937(self.seed)) + actual = random.standard_cauchy(size=(3, 2)) + desired = np.array([[-1.489437778266206, -3.275389641569784], + [ 0.560102864910406, -0.680780916282552], + [-1.314912905226277, 0.295852965660225]]) + assert_array_almost_equal(actual, desired, decimal=15) + + def test_standard_exponential(self): + random = Generator(MT19937(self.seed)) + actual = random.standard_exponential(size=(3, 2), method='inv') + desired = np.array([[0.102031839440643, 1.229350298474972], + [0.088137284693098, 1.459859985522667], + [1.093830802293668, 1.256977002164613]]) + assert_array_almost_equal(actual, desired, decimal=15) + + def test_standard_expoential_type_error(self): + assert_raises(TypeError, random.standard_exponential, dtype=np.int32) + + def test_standard_gamma(self): + random = Generator(MT19937(self.seed)) + actual = random.standard_gamma(shape=3, size=(3, 2)) + desired = np.array([[0.62970724056362, 1.22379851271008], + [3.899412530884 , 4.12479964250139], + [3.74994102464584, 3.74929307690815]]) + assert_array_almost_equal(actual, desired, decimal=14) + + def test_standard_gammma_scalar_float(self): + random = Generator(MT19937(self.seed)) + actual = random.standard_gamma(3, dtype=np.float32) + desired = 2.9242148399353027 + assert_array_almost_equal(actual, desired, decimal=6) + + def test_standard_gamma_float(self): + random = Generator(MT19937(self.seed)) + actual = random.standard_gamma(shape=3, size=(3, 2)) + desired = np.array([[0.62971, 1.2238 ], + [3.89941, 4.1248 ], + [3.74994, 3.74929]]) + assert_array_almost_equal(actual, desired, decimal=5) + + def test_standard_gammma_float_out(self): + actual = np.zeros((3, 2), dtype=np.float32) + random = Generator(MT19937(self.seed)) + random.standard_gamma(10.0, out=actual, dtype=np.float32) + desired = np.array([[10.14987, 7.87012], + [ 9.46284, 12.56832], + [13.82495, 7.81533]], dtype=np.float32) + assert_array_almost_equal(actual, desired, decimal=5) + + random = Generator(MT19937(self.seed)) + random.standard_gamma(10.0, out=actual, size=(3, 2), dtype=np.float32) + assert_array_almost_equal(actual, desired, decimal=5) + + def test_standard_gamma_unknown_type(self): + assert_raises(TypeError, random.standard_gamma, 1., + dtype='int32') + + def test_out_size_mismatch(self): + out = np.zeros(10) + assert_raises(ValueError, random.standard_gamma, 10.0, size=20, + out=out) + assert_raises(ValueError, random.standard_gamma, 10.0, size=(10, 1), + out=out) + + def test_standard_gamma_0(self): + assert_equal(random.standard_gamma(shape=0), 0) + assert_raises(ValueError, random.standard_gamma, shape=-0.) + + def test_standard_normal(self): + random = Generator(MT19937(self.seed)) + actual = random.standard_normal(size=(3, 2)) + desired = np.array([[-1.870934851846581, 1.25613495182354 ], + [-1.120190126006621, 0.342002097029821], + [ 0.661545174124296, 1.181113712443012]]) + assert_array_almost_equal(actual, desired, decimal=15) + + def test_standard_normal_unsupported_type(self): + assert_raises(TypeError, random.standard_normal, dtype=np.int32) + + def test_standard_t(self): + random = Generator(MT19937(self.seed)) + actual = random.standard_t(df=10, size=(3, 2)) + desired = np.array([[-1.484666193042647, 0.30597891831161 ], + [ 1.056684299648085, -0.407312602088507], + [ 0.130704414281157, -2.038053410490321]]) + assert_array_almost_equal(actual, desired, decimal=15) + + def test_triangular(self): + random = Generator(MT19937(self.seed)) + actual = random.triangular(left=5.12, mode=10.23, right=20.34, + size=(3, 2)) + desired = np.array([[ 7.86664070590917, 13.6313848513185 ], + [ 7.68152445215983, 14.36169131136546], + [13.16105603911429, 13.72341621856971]]) + assert_array_almost_equal(actual, desired, decimal=14) + + def test_uniform(self): + random = Generator(MT19937(self.seed)) + actual = random.uniform(low=1.23, high=10.54, size=(3, 2)) + desired = np.array([[2.13306255040998 , 7.816987531021207], + [2.015436610109887, 8.377577533009589], + [7.421792588856135, 7.891185744455209]]) + assert_array_almost_equal(actual, desired, decimal=15) + + def test_uniform_range_bounds(self): + fmin = np.finfo('float').min + fmax = np.finfo('float').max + + func = random.uniform + assert_raises(OverflowError, func, -np.inf, 0) + assert_raises(OverflowError, func, 0, np.inf) + assert_raises(OverflowError, func, fmin, fmax) + assert_raises(OverflowError, func, [-np.inf], [0]) + assert_raises(OverflowError, func, [0], [np.inf]) + + # (fmax / 1e17) - fmin is within range, so this should not throw + # account for i386 extended precision DBL_MAX / 1e17 + DBL_MAX > + # DBL_MAX by increasing fmin a bit + random.uniform(low=np.nextafter(fmin, 1), high=fmax / 1e17) + + def test_scalar_exception_propagation(self): + # Tests that exceptions are correctly propagated in distributions + # when called with objects that throw exceptions when converted to + # scalars. + # + # Regression test for gh: 8865 + + class ThrowingFloat(np.ndarray): + def __float__(self): + raise TypeError + + throwing_float = np.array(1.0).view(ThrowingFloat) + assert_raises(TypeError, random.uniform, throwing_float, + throwing_float) + + class ThrowingInteger(np.ndarray): + def __int__(self): + raise TypeError + + throwing_int = np.array(1).view(ThrowingInteger) + assert_raises(TypeError, random.hypergeometric, throwing_int, 1, 1) + + def test_vonmises(self): + random = Generator(MT19937(self.seed)) + actual = random.vonmises(mu=1.23, kappa=1.54, size=(3, 2)) + desired = np.array([[ 1.107972248690106, 2.841536476232361], + [ 1.832602376042457, 1.945511926976032], + [-0.260147475776542, 2.058047492231698]]) + assert_array_almost_equal(actual, desired, decimal=15) + + def test_vonmises_small(self): + # check infinite loop, gh-4720 + random = Generator(MT19937(self.seed)) + r = random.vonmises(mu=0., kappa=1.1e-8, size=10**6) + assert_(np.isfinite(r).all()) + + def test_vonmises_nan(self): + random = Generator(MT19937(self.seed)) + r = random.vonmises(mu=0., kappa=np.nan) + assert_(np.isnan(r)) + + def test_wald(self): + random = Generator(MT19937(self.seed)) + actual = random.wald(mean=1.23, scale=1.54, size=(3, 2)) + desired = np.array([[0.26871721804551, 3.2233942732115 ], + [2.20328374987066, 2.40958405189353], + [2.07093587449261, 0.73073890064369]]) + assert_array_almost_equal(actual, desired, decimal=14) + + def test_weibull(self): + random = Generator(MT19937(self.seed)) + actual = random.weibull(a=1.23, size=(3, 2)) + desired = np.array([[0.138613914769468, 1.306463419753191], + [0.111623365934763, 1.446570494646721], + [1.257145775276011, 1.914247725027957]]) + assert_array_almost_equal(actual, desired, decimal=15) + + def test_weibull_0(self): + random = Generator(MT19937(self.seed)) + assert_equal(random.weibull(a=0, size=12), np.zeros(12)) + assert_raises(ValueError, random.weibull, a=-0.) + + def test_zipf(self): + random = Generator(MT19937(self.seed)) + actual = random.zipf(a=1.23, size=(3, 2)) + desired = np.array([[ 1, 1], + [ 10, 867], + [354, 2]]) + assert_array_equal(actual, desired) + + +class TestBroadcast: + # tests that functions that broadcast behave + # correctly when presented with non-scalar arguments + def setup(self): + self.seed = 123456789 + + + def test_uniform(self): + random = Generator(MT19937(self.seed)) + low = [0] + high = [1] + uniform = random.uniform + desired = np.array([0.16693771389729, 0.19635129550675, 0.75563050964095]) + + random = Generator(MT19937(self.seed)) + actual = random.uniform(low * 3, high) + assert_array_almost_equal(actual, desired, decimal=14) + + random = Generator(MT19937(self.seed)) + actual = random.uniform(low, high * 3) + assert_array_almost_equal(actual, desired, decimal=14) + + def test_normal(self): + loc = [0] + scale = [1] + bad_scale = [-1] + random = Generator(MT19937(self.seed)) + desired = np.array([-0.38736406738527, 0.79594375042255, 0.0197076236097]) + + random = Generator(MT19937(self.seed)) + actual = random.normal(loc * 3, scale) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, random.normal, loc * 3, bad_scale) + + random = Generator(MT19937(self.seed)) + normal = random.normal + actual = normal(loc, scale * 3) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, normal, loc, bad_scale * 3) + + def test_beta(self): + a = [1] + b = [2] + bad_a = [-1] + bad_b = [-2] + desired = np.array([0.18719338682602, 0.73234824491364, 0.17928615186455]) + + random = Generator(MT19937(self.seed)) + beta = random.beta + actual = beta(a * 3, b) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, beta, bad_a * 3, b) + assert_raises(ValueError, beta, a * 3, bad_b) + + random = Generator(MT19937(self.seed)) + actual = random.beta(a, b * 3) + assert_array_almost_equal(actual, desired, decimal=14) + + def test_exponential(self): + scale = [1] + bad_scale = [-1] + desired = np.array([0.67245993212806, 0.21380495318094, 0.7177848928629]) + + random = Generator(MT19937(self.seed)) + actual = random.exponential(scale * 3) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, random.exponential, bad_scale * 3) + + def test_standard_gamma(self): + shape = [1] + bad_shape = [-1] + desired = np.array([0.67245993212806, 0.21380495318094, 0.7177848928629]) + + random = Generator(MT19937(self.seed)) + std_gamma = random.standard_gamma + actual = std_gamma(shape * 3) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, std_gamma, bad_shape * 3) + + def test_gamma(self): + shape = [1] + scale = [2] + bad_shape = [-1] + bad_scale = [-2] + desired = np.array([1.34491986425611, 0.42760990636187, 1.4355697857258]) + + random = Generator(MT19937(self.seed)) + gamma = random.gamma + actual = gamma(shape * 3, scale) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, gamma, bad_shape * 3, scale) + assert_raises(ValueError, gamma, shape * 3, bad_scale) + + random = Generator(MT19937(self.seed)) + gamma = random.gamma + actual = gamma(shape, scale * 3) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, gamma, bad_shape, scale * 3) + assert_raises(ValueError, gamma, shape, bad_scale * 3) + + def test_f(self): + dfnum = [1] + dfden = [2] + bad_dfnum = [-1] + bad_dfden = [-2] + desired = np.array([0.07765056244107, 7.72951397913186, 0.05786093891763]) + + random = Generator(MT19937(self.seed)) + f = random.f + actual = f(dfnum * 3, dfden) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, f, bad_dfnum * 3, dfden) + assert_raises(ValueError, f, dfnum * 3, bad_dfden) + + random = Generator(MT19937(self.seed)) + f = random.f + actual = f(dfnum, dfden * 3) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, f, bad_dfnum, dfden * 3) + assert_raises(ValueError, f, dfnum, bad_dfden * 3) + + def test_noncentral_f(self): + dfnum = [2] + dfden = [3] + nonc = [4] + bad_dfnum = [0] + bad_dfden = [-1] + bad_nonc = [-2] + desired = np.array([2.02434240411421, 12.91838601070124, 1.24395160354629]) + + random = Generator(MT19937(self.seed)) + nonc_f = random.noncentral_f + actual = nonc_f(dfnum * 3, dfden, nonc) + assert_array_almost_equal(actual, desired, decimal=14) + assert np.all(np.isnan(nonc_f(dfnum, dfden, [np.nan] * 3))) + + assert_raises(ValueError, nonc_f, bad_dfnum * 3, dfden, nonc) + assert_raises(ValueError, nonc_f, dfnum * 3, bad_dfden, nonc) + assert_raises(ValueError, nonc_f, dfnum * 3, dfden, bad_nonc) + + random = Generator(MT19937(self.seed)) + nonc_f = random.noncentral_f + actual = nonc_f(dfnum, dfden * 3, nonc) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, nonc_f, bad_dfnum, dfden * 3, nonc) + assert_raises(ValueError, nonc_f, dfnum, bad_dfden * 3, nonc) + assert_raises(ValueError, nonc_f, dfnum, dfden * 3, bad_nonc) + + random = Generator(MT19937(self.seed)) + nonc_f = random.noncentral_f + actual = nonc_f(dfnum, dfden, nonc * 3) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, nonc_f, bad_dfnum, dfden, nonc * 3) + assert_raises(ValueError, nonc_f, dfnum, bad_dfden, nonc * 3) + assert_raises(ValueError, nonc_f, dfnum, dfden, bad_nonc * 3) + + def test_noncentral_f_small_df(self): + random = Generator(MT19937(self.seed)) + desired = np.array([0.04714867120827, 0.1239390327694]) + actual = random.noncentral_f(0.9, 0.9, 2, size=2) + assert_array_almost_equal(actual, desired, decimal=14) + + def test_chisquare(self): + df = [1] + bad_df = [-1] + desired = np.array([0.05573640064251, 1.47220224353539, 2.9469379318589]) + + random = Generator(MT19937(self.seed)) + actual = random.chisquare(df * 3) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, random.chisquare, bad_df * 3) + + def test_noncentral_chisquare(self): + df = [1] + nonc = [2] + bad_df = [-1] + bad_nonc = [-2] + desired = np.array([0.07710766249436, 5.27829115110304, 0.630732147399]) + + random = Generator(MT19937(self.seed)) + nonc_chi = random.noncentral_chisquare + actual = nonc_chi(df * 3, nonc) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, nonc_chi, bad_df * 3, nonc) + assert_raises(ValueError, nonc_chi, df * 3, bad_nonc) + + random = Generator(MT19937(self.seed)) + nonc_chi = random.noncentral_chisquare + actual = nonc_chi(df, nonc * 3) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, nonc_chi, bad_df, nonc * 3) + assert_raises(ValueError, nonc_chi, df, bad_nonc * 3) + + def test_standard_t(self): + df = [1] + bad_df = [-1] + desired = np.array([-1.39498829447098, -1.23058658835223, 0.17207021065983]) + + random = Generator(MT19937(self.seed)) + actual = random.standard_t(df * 3) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, random.standard_t, bad_df * 3) + + def test_vonmises(self): + mu = [2] + kappa = [1] + bad_kappa = [-1] + desired = np.array([2.25935584988528, 2.23326261461399, -2.84152146503326]) + + random = Generator(MT19937(self.seed)) + actual = random.vonmises(mu * 3, kappa) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, random.vonmises, mu * 3, bad_kappa) + + random = Generator(MT19937(self.seed)) + actual = random.vonmises(mu, kappa * 3) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, random.vonmises, mu, bad_kappa * 3) + + def test_pareto(self): + a = [1] + bad_a = [-1] + desired = np.array([0.95905052946317, 0.2383810889437 , 1.04988745750013]) + + random = Generator(MT19937(self.seed)) + actual = random.pareto(a * 3) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, random.pareto, bad_a * 3) + + def test_weibull(self): + a = [1] + bad_a = [-1] + desired = np.array([0.67245993212806, 0.21380495318094, 0.7177848928629]) + + random = Generator(MT19937(self.seed)) + actual = random.weibull(a * 3) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, random.weibull, bad_a * 3) + + def test_power(self): + a = [1] + bad_a = [-1] + desired = np.array([0.48954864361052, 0.19249412888486, 0.51216834058807]) + + random = Generator(MT19937(self.seed)) + actual = random.power(a * 3) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, random.power, bad_a * 3) + + def test_laplace(self): + loc = [0] + scale = [1] + bad_scale = [-1] + desired = np.array([-1.09698732625119, -0.93470271947368, 0.71592671378202]) + + random = Generator(MT19937(self.seed)) + laplace = random.laplace + actual = laplace(loc * 3, scale) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, laplace, loc * 3, bad_scale) + + random = Generator(MT19937(self.seed)) + laplace = random.laplace + actual = laplace(loc, scale * 3) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, laplace, loc, bad_scale * 3) + + def test_gumbel(self): + loc = [0] + scale = [1] + bad_scale = [-1] + desired = np.array([1.70020068231762, 1.52054354273631, -0.34293267607081]) + + random = Generator(MT19937(self.seed)) + gumbel = random.gumbel + actual = gumbel(loc * 3, scale) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, gumbel, loc * 3, bad_scale) + + random = Generator(MT19937(self.seed)) + gumbel = random.gumbel + actual = gumbel(loc, scale * 3) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, gumbel, loc, bad_scale * 3) + + def test_logistic(self): + loc = [0] + scale = [1] + bad_scale = [-1] + desired = np.array([-1.607487640433, -1.40925686003678, 1.12887112820397]) + + random = Generator(MT19937(self.seed)) + actual = random.logistic(loc * 3, scale) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, random.logistic, loc * 3, bad_scale) + + random = Generator(MT19937(self.seed)) + actual = random.logistic(loc, scale * 3) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, random.logistic, loc, bad_scale * 3) + assert_equal(random.logistic(1.0, 0.0), 1.0) + + def test_lognormal(self): + mean = [0] + sigma = [1] + bad_sigma = [-1] + desired = np.array([0.67884390500697, 2.21653186290321, 1.01990310084276]) + + random = Generator(MT19937(self.seed)) + lognormal = random.lognormal + actual = lognormal(mean * 3, sigma) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, lognormal, mean * 3, bad_sigma) + + random = Generator(MT19937(self.seed)) + actual = random.lognormal(mean, sigma * 3) + assert_raises(ValueError, random.lognormal, mean, bad_sigma * 3) + + def test_rayleigh(self): + scale = [1] + bad_scale = [-1] + desired = np.array([0.60439534475066, 0.66120048396359, 1.67873398389499]) + + random = Generator(MT19937(self.seed)) + actual = random.rayleigh(scale * 3) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, random.rayleigh, bad_scale * 3) + + def test_wald(self): + mean = [0.5] + scale = [1] + bad_mean = [0] + bad_scale = [-2] + desired = np.array([0.38052407392905, 0.50701641508592, 0.484935249864]) + + random = Generator(MT19937(self.seed)) + actual = random.wald(mean * 3, scale) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, random.wald, bad_mean * 3, scale) + assert_raises(ValueError, random.wald, mean * 3, bad_scale) + + random = Generator(MT19937(self.seed)) + actual = random.wald(mean, scale * 3) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, random.wald, bad_mean, scale * 3) + assert_raises(ValueError, random.wald, mean, bad_scale * 3) + + def test_triangular(self): + left = [1] + right = [3] + mode = [2] + bad_left_one = [3] + bad_mode_one = [4] + bad_left_two, bad_mode_two = right * 2 + desired = np.array([1.57781954604754, 1.62665986867957, 2.30090130831326]) + + random = Generator(MT19937(self.seed)) + triangular = random.triangular + actual = triangular(left * 3, mode, right) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, triangular, bad_left_one * 3, mode, right) + assert_raises(ValueError, triangular, left * 3, bad_mode_one, right) + assert_raises(ValueError, triangular, bad_left_two * 3, bad_mode_two, + right) + + random = Generator(MT19937(self.seed)) + triangular = random.triangular + actual = triangular(left, mode * 3, right) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, triangular, bad_left_one, mode * 3, right) + assert_raises(ValueError, triangular, left, bad_mode_one * 3, right) + assert_raises(ValueError, triangular, bad_left_two, bad_mode_two * 3, + right) + + random = Generator(MT19937(self.seed)) + triangular = random.triangular + actual = triangular(left, mode, right * 3) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, triangular, bad_left_one, mode, right * 3) + assert_raises(ValueError, triangular, left, bad_mode_one, right * 3) + assert_raises(ValueError, triangular, bad_left_two, bad_mode_two, + right * 3) + + assert_raises(ValueError, triangular, 10., 0., 20.) + assert_raises(ValueError, triangular, 10., 25., 20.) + assert_raises(ValueError, triangular, 10., 10., 10.) + + def test_binomial(self): + n = [1] + p = [0.5] + bad_n = [-1] + bad_p_one = [-1] + bad_p_two = [1.5] + desired = np.array([0, 0, 1]) + + random = Generator(MT19937(self.seed)) + binom = random.binomial + actual = binom(n * 3, p) + assert_array_equal(actual, desired) + assert_raises(ValueError, binom, bad_n * 3, p) + assert_raises(ValueError, binom, n * 3, bad_p_one) + assert_raises(ValueError, binom, n * 3, bad_p_two) + + random = Generator(MT19937(self.seed)) + actual = random.binomial(n, p * 3) + assert_array_equal(actual, desired) + assert_raises(ValueError, binom, bad_n, p * 3) + assert_raises(ValueError, binom, n, bad_p_one * 3) + assert_raises(ValueError, binom, n, bad_p_two * 3) + + def test_negative_binomial(self): + n = [1] + p = [0.5] + bad_n = [-1] + bad_p_one = [-1] + bad_p_two = [1.5] + desired = np.array([0, 2, 1], dtype=np.int64) + + random = Generator(MT19937(self.seed)) + neg_binom = random.negative_binomial + actual = neg_binom(n * 3, p) + assert_array_equal(actual, desired) + assert_raises(ValueError, neg_binom, bad_n * 3, p) + assert_raises(ValueError, neg_binom, n * 3, bad_p_one) + assert_raises(ValueError, neg_binom, n * 3, bad_p_two) + + random = Generator(MT19937(self.seed)) + neg_binom = random.negative_binomial + actual = neg_binom(n, p * 3) + assert_array_equal(actual, desired) + assert_raises(ValueError, neg_binom, bad_n, p * 3) + assert_raises(ValueError, neg_binom, n, bad_p_one * 3) + assert_raises(ValueError, neg_binom, n, bad_p_two * 3) + + def test_poisson(self): + + lam = [1] + bad_lam_one = [-1] + desired = np.array([0, 0, 3]) + + random = Generator(MT19937(self.seed)) + max_lam = random._poisson_lam_max + bad_lam_two = [max_lam * 2] + poisson = random.poisson + actual = poisson(lam * 3) + assert_array_equal(actual, desired) + assert_raises(ValueError, poisson, bad_lam_one * 3) + assert_raises(ValueError, poisson, bad_lam_two * 3) + + def test_zipf(self): + a = [2] + bad_a = [0] + desired = np.array([1, 8, 1]) + + random = Generator(MT19937(self.seed)) + zipf = random.zipf + actual = zipf(a * 3) + assert_array_equal(actual, desired) + assert_raises(ValueError, zipf, bad_a * 3) + with np.errstate(invalid='ignore'): + assert_raises(ValueError, zipf, np.nan) + assert_raises(ValueError, zipf, [0, 0, np.nan]) + + def test_geometric(self): + p = [0.5] + bad_p_one = [-1] + bad_p_two = [1.5] + desired = np.array([1, 1, 3]) + + random = Generator(MT19937(self.seed)) + geometric = random.geometric + actual = geometric(p * 3) + assert_array_equal(actual, desired) + assert_raises(ValueError, geometric, bad_p_one * 3) + assert_raises(ValueError, geometric, bad_p_two * 3) + + def test_hypergeometric(self): + ngood = [1] + nbad = [2] + nsample = [2] + bad_ngood = [-1] + bad_nbad = [-2] + bad_nsample_one = [-1] + bad_nsample_two = [4] + desired = np.array([0, 0, 1]) + + random = Generator(MT19937(self.seed)) + actual = random.hypergeometric(ngood * 3, nbad, nsample) + assert_array_equal(actual, desired) + assert_raises(ValueError, random.hypergeometric, bad_ngood * 3, nbad, nsample) + assert_raises(ValueError, random.hypergeometric, ngood * 3, bad_nbad, nsample) + assert_raises(ValueError, random.hypergeometric, ngood * 3, nbad, bad_nsample_one) + assert_raises(ValueError, random.hypergeometric, ngood * 3, nbad, bad_nsample_two) + + random = Generator(MT19937(self.seed)) + actual = random.hypergeometric(ngood, nbad * 3, nsample) + assert_array_equal(actual, desired) + assert_raises(ValueError, random.hypergeometric, bad_ngood, nbad * 3, nsample) + assert_raises(ValueError, random.hypergeometric, ngood, bad_nbad * 3, nsample) + assert_raises(ValueError, random.hypergeometric, ngood, nbad * 3, bad_nsample_one) + assert_raises(ValueError, random.hypergeometric, ngood, nbad * 3, bad_nsample_two) + + random = Generator(MT19937(self.seed)) + hypergeom = random.hypergeometric + actual = hypergeom(ngood, nbad, nsample * 3) + assert_array_equal(actual, desired) + assert_raises(ValueError, hypergeom, bad_ngood, nbad, nsample * 3) + assert_raises(ValueError, hypergeom, ngood, bad_nbad, nsample * 3) + assert_raises(ValueError, hypergeom, ngood, nbad, bad_nsample_one * 3) + assert_raises(ValueError, hypergeom, ngood, nbad, bad_nsample_two * 3) + + assert_raises(ValueError, hypergeom, -1, 10, 20) + assert_raises(ValueError, hypergeom, 10, -1, 20) + assert_raises(ValueError, hypergeom, 10, 10, -1) + assert_raises(ValueError, hypergeom, 10, 10, 25) + + # ValueError for arguments that are too big. + assert_raises(ValueError, hypergeom, 2**30, 10, 20) + assert_raises(ValueError, hypergeom, 999, 2**31, 50) + assert_raises(ValueError, hypergeom, 999, [2**29, 2**30], 1000) + + def test_logseries(self): + p = [0.5] + bad_p_one = [2] + bad_p_two = [-1] + desired = np.array([1, 1, 1]) + + random = Generator(MT19937(self.seed)) + logseries = random.logseries + actual = logseries(p * 3) + assert_array_equal(actual, desired) + assert_raises(ValueError, logseries, bad_p_one * 3) + assert_raises(ValueError, logseries, bad_p_two * 3) + + def test_multinomial(self): + random = Generator(MT19937(self.seed)) + actual = random.multinomial([5, 20], [1 / 6.] * 6, size=(3, 2)) + desired = np.array([[[0, 0, 2, 1, 2, 0], + [2, 3, 6, 4, 2, 3]], + [[1, 0, 1, 0, 2, 1], + [7, 2, 2, 1, 4, 4]], + [[0, 2, 0, 1, 2, 0], + [3, 2, 3, 3, 4, 5]]], dtype=np.int64) + assert_array_equal(actual, desired) + + random = Generator(MT19937(self.seed)) + actual = random.multinomial([5, 20], [1 / 6.] * 6) + desired = np.array([[0, 0, 2, 1, 2, 0], + [2, 3, 6, 4, 2, 3]], dtype=np.int64) + assert_array_equal(actual, desired) + + +class TestThread: + # make sure each state produces the same sequence even in threads + def setup(self): + self.seeds = range(4) + + def check_function(self, function, sz): + from threading import Thread + + out1 = np.empty((len(self.seeds),) + sz) + out2 = np.empty((len(self.seeds),) + sz) + + # threaded generation + t = [Thread(target=function, args=(Generator(MT19937(s)), o)) + for s, o in zip(self.seeds, out1)] + [x.start() for x in t] + [x.join() for x in t] + + # the same serial + for s, o in zip(self.seeds, out2): + function(Generator(MT19937(s)), o) + + # these platforms change x87 fpu precision mode in threads + if np.intp().dtype.itemsize == 4 and sys.platform == "win32": + assert_array_almost_equal(out1, out2) + else: + assert_array_equal(out1, out2) + + def test_normal(self): + def gen_random(state, out): + out[...] = state.normal(size=10000) + + self.check_function(gen_random, sz=(10000,)) + + def test_exp(self): + def gen_random(state, out): + out[...] = state.exponential(scale=np.ones((100, 1000))) + + self.check_function(gen_random, sz=(100, 1000)) + + def test_multinomial(self): + def gen_random(state, out): + out[...] = state.multinomial(10, [1 / 6.] * 6, size=10000) + + self.check_function(gen_random, sz=(10000, 6)) + + +# See Issue #4263 +class TestSingleEltArrayInput: + def setup(self): + self.argOne = np.array([2]) + self.argTwo = np.array([3]) + self.argThree = np.array([4]) + self.tgtShape = (1,) + + def test_one_arg_funcs(self): + funcs = (random.exponential, random.standard_gamma, + random.chisquare, random.standard_t, + random.pareto, random.weibull, + random.power, random.rayleigh, + random.poisson, random.zipf, + random.geometric, random.logseries) + + probfuncs = (random.geometric, random.logseries) + + for func in funcs: + if func in probfuncs: # p < 1.0 + out = func(np.array([0.5])) + + else: + out = func(self.argOne) + + assert_equal(out.shape, self.tgtShape) + + def test_two_arg_funcs(self): + funcs = (random.uniform, random.normal, + random.beta, random.gamma, + random.f, random.noncentral_chisquare, + random.vonmises, random.laplace, + random.gumbel, random.logistic, + random.lognormal, random.wald, + random.binomial, random.negative_binomial) + + probfuncs = (random.binomial, random.negative_binomial) + + for func in funcs: + if func in probfuncs: # p <= 1 + argTwo = np.array([0.5]) + + else: + argTwo = self.argTwo + + out = func(self.argOne, argTwo) + assert_equal(out.shape, self.tgtShape) + + out = func(self.argOne[0], argTwo) + assert_equal(out.shape, self.tgtShape) + + out = func(self.argOne, argTwo[0]) + assert_equal(out.shape, self.tgtShape) + + def test_integers(self, endpoint): + itype = [np.bool_, np.int8, np.uint8, np.int16, np.uint16, + np.int32, np.uint32, np.int64, np.uint64] + func = random.integers + high = np.array([1]) + low = np.array([0]) + + for dt in itype: + out = func(low, high, endpoint=endpoint, dtype=dt) + assert_equal(out.shape, self.tgtShape) + + out = func(low[0], high, endpoint=endpoint, dtype=dt) + assert_equal(out.shape, self.tgtShape) + + out = func(low, high[0], endpoint=endpoint, dtype=dt) + assert_equal(out.shape, self.tgtShape) + + def test_three_arg_funcs(self): + funcs = [random.noncentral_f, random.triangular, + random.hypergeometric] + + for func in funcs: + out = func(self.argOne, self.argTwo, self.argThree) + assert_equal(out.shape, self.tgtShape) + + out = func(self.argOne[0], self.argTwo, self.argThree) + assert_equal(out.shape, self.tgtShape) + + out = func(self.argOne, self.argTwo[0], self.argThree) + assert_equal(out.shape, self.tgtShape) + + +@pytest.mark.parametrize("config", JUMP_TEST_DATA) +def test_jumped(config): + # Each config contains the initial seed, a number of raw steps + # the sha256 hashes of the initial and the final states' keys and + # the position of of the initial and the final state. + # These were produced using the original C implementation. + seed = config["seed"] + steps = config["steps"] + + mt19937 = MT19937(seed) + # Burn step + mt19937.random_raw(steps) + key = mt19937.state["state"]["key"] + if sys.byteorder == 'big': + key = key.byteswap() + sha256 = hashlib.sha256(key) + assert mt19937.state["state"]["pos"] == config["initial"]["pos"] + assert sha256.hexdigest() == config["initial"]["key_sha256"] + + jumped = mt19937.jumped() + key = jumped.state["state"]["key"] + if sys.byteorder == 'big': + key = key.byteswap() + sha256 = hashlib.sha256(key) + assert jumped.state["state"]["pos"] == config["jumped"]["pos"] + assert sha256.hexdigest() == config["jumped"]["key_sha256"] + + +def test_broadcast_size_error(): + mu = np.ones(3) + sigma = np.ones((4, 3)) + size = (10, 4, 2) + assert random.normal(mu, sigma, size=(5, 4, 3)).shape == (5, 4, 3) + with pytest.raises(ValueError): + random.normal(mu, sigma, size=size) + with pytest.raises(ValueError): + random.normal(mu, sigma, size=(1, 3)) + with pytest.raises(ValueError): + random.normal(mu, sigma, size=(4, 1, 1)) + # 1 arg + shape = np.ones((4, 3)) + with pytest.raises(ValueError): + random.standard_gamma(shape, size=size) + with pytest.raises(ValueError): + random.standard_gamma(shape, size=(3,)) + with pytest.raises(ValueError): + random.standard_gamma(shape, size=3) + # Check out + out = np.empty(size) + with pytest.raises(ValueError): + random.standard_gamma(shape, out=out) + + # 2 arg + with pytest.raises(ValueError): + random.binomial(1, [0.3, 0.7], size=(2, 1)) + with pytest.raises(ValueError): + random.binomial([1, 2], 0.3, size=(2, 1)) + with pytest.raises(ValueError): + random.binomial([1, 2], [0.3, 0.7], size=(2, 1)) + with pytest.raises(ValueError): + random.multinomial([2, 2], [.3, .7], size=(2, 1)) + + # 3 arg + a = random.chisquare(5, size=3) + b = random.chisquare(5, size=(4, 3)) + c = random.chisquare(5, size=(5, 4, 3)) + assert random.noncentral_f(a, b, c).shape == (5, 4, 3) + with pytest.raises(ValueError, match=r"Output size \(6, 5, 1, 1\) is"): + random.noncentral_f(a, b, c, size=(6, 5, 1, 1)) + + +def test_broadcast_size_scalar(): + mu = np.ones(3) + sigma = np.ones(3) + random.normal(mu, sigma, size=3) + with pytest.raises(ValueError): + random.normal(mu, sigma, size=2) diff --git a/venv/Lib/site-packages/numpy/random/tests/test_generator_mt19937_regressions.py b/venv/Lib/site-packages/numpy/random/tests/test_generator_mt19937_regressions.py new file mode 100644 index 0000000..2ef6b06 --- /dev/null +++ b/venv/Lib/site-packages/numpy/random/tests/test_generator_mt19937_regressions.py @@ -0,0 +1,150 @@ +from numpy.testing import (assert_, assert_array_equal) +import numpy as np +import pytest +from numpy.random import Generator, MT19937 + +mt19937 = Generator(MT19937()) + + +class TestRegression: + + def test_VonMises_range(self): + # Make sure generated random variables are in [-pi, pi]. + # Regression test for ticket #986. + for mu in np.linspace(-7., 7., 5): + r = mt19937.vonmises(mu, 1, 50) + assert_(np.all(r > -np.pi) and np.all(r <= np.pi)) + + def test_hypergeometric_range(self): + # Test for ticket #921 + assert_(np.all(mt19937.hypergeometric(3, 18, 11, size=10) < 4)) + assert_(np.all(mt19937.hypergeometric(18, 3, 11, size=10) > 0)) + + # Test for ticket #5623 + args = (2**20 - 2, 2**20 - 2, 2**20 - 2) # Check for 32-bit systems + assert_(mt19937.hypergeometric(*args) > 0) + + def test_logseries_convergence(self): + # Test for ticket #923 + N = 1000 + mt19937 = Generator(MT19937(0)) + rvsn = mt19937.logseries(0.8, size=N) + # these two frequency counts should be close to theoretical + # numbers with this large sample + # theoretical large N result is 0.49706795 + freq = np.sum(rvsn == 1) / float(N) + msg = f'Frequency was {freq:f}, should be > 0.45' + assert_(freq > 0.45, msg) + # theoretical large N result is 0.19882718 + freq = np.sum(rvsn == 2) / float(N) + msg = f'Frequency was {freq:f}, should be < 0.23' + assert_(freq < 0.23, msg) + + def test_shuffle_mixed_dimension(self): + # Test for trac ticket #2074 + for t in [[1, 2, 3, None], + [(1, 1), (2, 2), (3, 3), None], + [1, (2, 2), (3, 3), None], + [(1, 1), 2, 3, None]]: + mt19937 = Generator(MT19937(12345)) + shuffled = np.array(t, dtype=object) + mt19937.shuffle(shuffled) + expected = np.array([t[2], t[0], t[3], t[1]], dtype=object) + assert_array_equal(np.array(shuffled, dtype=object), expected) + + def test_call_within_randomstate(self): + # Check that custom BitGenerator does not call into global state + res = np.array([1, 8, 0, 1, 5, 3, 3, 8, 1, 4]) + for i in range(3): + mt19937 = Generator(MT19937(i)) + m = Generator(MT19937(4321)) + # If m.state is not honored, the result will change + assert_array_equal(m.choice(10, size=10, p=np.ones(10)/10.), res) + + def test_multivariate_normal_size_types(self): + # Test for multivariate_normal issue with 'size' argument. + # Check that the multivariate_normal size argument can be a + # numpy integer. + mt19937.multivariate_normal([0], [[0]], size=1) + mt19937.multivariate_normal([0], [[0]], size=np.int_(1)) + mt19937.multivariate_normal([0], [[0]], size=np.int64(1)) + + def test_beta_small_parameters(self): + # Test that beta with small a and b parameters does not produce + # NaNs due to roundoff errors causing 0 / 0, gh-5851 + mt19937 = Generator(MT19937(1234567890)) + x = mt19937.beta(0.0001, 0.0001, size=100) + assert_(not np.any(np.isnan(x)), 'Nans in mt19937.beta') + + def test_choice_sum_of_probs_tolerance(self): + # The sum of probs should be 1.0 with some tolerance. + # For low precision dtypes the tolerance was too tight. + # See numpy github issue 6123. + mt19937 = Generator(MT19937(1234)) + a = [1, 2, 3] + counts = [4, 4, 2] + for dt in np.float16, np.float32, np.float64: + probs = np.array(counts, dtype=dt) / sum(counts) + c = mt19937.choice(a, p=probs) + assert_(c in a) + with pytest.raises(ValueError): + mt19937.choice(a, p=probs*0.9) + + def test_shuffle_of_array_of_different_length_strings(self): + # Test that permuting an array of different length strings + # will not cause a segfault on garbage collection + # Tests gh-7710 + mt19937 = Generator(MT19937(1234)) + + a = np.array(['a', 'a' * 1000]) + + for _ in range(100): + mt19937.shuffle(a) + + # Force Garbage Collection - should not segfault. + import gc + gc.collect() + + def test_shuffle_of_array_of_objects(self): + # Test that permuting an array of objects will not cause + # a segfault on garbage collection. + # See gh-7719 + mt19937 = Generator(MT19937(1234)) + a = np.array([np.arange(1), np.arange(4)], dtype=object) + + for _ in range(1000): + mt19937.shuffle(a) + + # Force Garbage Collection - should not segfault. + import gc + gc.collect() + + def test_permutation_subclass(self): + class N(np.ndarray): + pass + + mt19937 = Generator(MT19937(1)) + orig = np.arange(3).view(N) + perm = mt19937.permutation(orig) + assert_array_equal(perm, np.array([2, 0, 1])) + assert_array_equal(orig, np.arange(3).view(N)) + + class M: + a = np.arange(5) + + def __array__(self): + return self.a + + mt19937 = Generator(MT19937(1)) + m = M() + perm = mt19937.permutation(m) + assert_array_equal(perm, np.array([4, 1, 3, 0, 2])) + assert_array_equal(m.__array__(), np.arange(5)) + + def test_gamma_0(self): + assert mt19937.standard_gamma(0.0) == 0.0 + assert_array_equal(mt19937.standard_gamma([0.0]), 0.0) + + actual = mt19937.standard_gamma([0.0], dtype='float') + expected = np.array([0.], dtype=np.float32) + assert_array_equal(actual, expected) diff --git a/venv/Lib/site-packages/numpy/random/tests/test_random.py b/venv/Lib/site-packages/numpy/random/tests/test_random.py new file mode 100644 index 0000000..5f8b39e --- /dev/null +++ b/venv/Lib/site-packages/numpy/random/tests/test_random.py @@ -0,0 +1,1700 @@ +import warnings + +import numpy as np +from numpy.testing import ( + assert_, assert_raises, assert_equal, assert_warns, + assert_no_warnings, assert_array_equal, assert_array_almost_equal, + suppress_warnings + ) +from numpy import random +import sys + + +class TestSeed: + def test_scalar(self): + s = np.random.RandomState(0) + assert_equal(s.randint(1000), 684) + s = np.random.RandomState(4294967295) + assert_equal(s.randint(1000), 419) + + def test_array(self): + s = np.random.RandomState(range(10)) + assert_equal(s.randint(1000), 468) + s = np.random.RandomState(np.arange(10)) + assert_equal(s.randint(1000), 468) + s = np.random.RandomState([0]) + assert_equal(s.randint(1000), 973) + s = np.random.RandomState([4294967295]) + assert_equal(s.randint(1000), 265) + + def test_invalid_scalar(self): + # seed must be an unsigned 32 bit integer + assert_raises(TypeError, np.random.RandomState, -0.5) + assert_raises(ValueError, np.random.RandomState, -1) + + def test_invalid_array(self): + # seed must be an unsigned 32 bit integer + assert_raises(TypeError, np.random.RandomState, [-0.5]) + assert_raises(ValueError, np.random.RandomState, [-1]) + assert_raises(ValueError, np.random.RandomState, [4294967296]) + assert_raises(ValueError, np.random.RandomState, [1, 2, 4294967296]) + assert_raises(ValueError, np.random.RandomState, [1, -2, 4294967296]) + + def test_invalid_array_shape(self): + # gh-9832 + assert_raises(ValueError, np.random.RandomState, + np.array([], dtype=np.int64)) + assert_raises(ValueError, np.random.RandomState, [[1, 2, 3]]) + assert_raises(ValueError, np.random.RandomState, [[1, 2, 3], + [4, 5, 6]]) + + +class TestBinomial: + def test_n_zero(self): + # Tests the corner case of n == 0 for the binomial distribution. + # binomial(0, p) should be zero for any p in [0, 1]. + # This test addresses issue #3480. + zeros = np.zeros(2, dtype='int') + for p in [0, .5, 1]: + assert_(random.binomial(0, p) == 0) + assert_array_equal(random.binomial(zeros, p), zeros) + + def test_p_is_nan(self): + # Issue #4571. + assert_raises(ValueError, random.binomial, 1, np.nan) + + +class TestMultinomial: + def test_basic(self): + random.multinomial(100, [0.2, 0.8]) + + def test_zero_probability(self): + random.multinomial(100, [0.2, 0.8, 0.0, 0.0, 0.0]) + + def test_int_negative_interval(self): + assert_(-5 <= random.randint(-5, -1) < -1) + x = random.randint(-5, -1, 5) + assert_(np.all(-5 <= x)) + assert_(np.all(x < -1)) + + def test_size(self): + # gh-3173 + p = [0.5, 0.5] + assert_equal(np.random.multinomial(1, p, np.uint32(1)).shape, (1, 2)) + assert_equal(np.random.multinomial(1, p, np.uint32(1)).shape, (1, 2)) + assert_equal(np.random.multinomial(1, p, np.uint32(1)).shape, (1, 2)) + assert_equal(np.random.multinomial(1, p, [2, 2]).shape, (2, 2, 2)) + assert_equal(np.random.multinomial(1, p, (2, 2)).shape, (2, 2, 2)) + assert_equal(np.random.multinomial(1, p, np.array((2, 2))).shape, + (2, 2, 2)) + + assert_raises(TypeError, np.random.multinomial, 1, p, + float(1)) + + def test_multidimensional_pvals(self): + assert_raises(ValueError, np.random.multinomial, 10, [[0, 1]]) + assert_raises(ValueError, np.random.multinomial, 10, [[0], [1]]) + assert_raises(ValueError, np.random.multinomial, 10, [[[0], [1]], [[1], [0]]]) + assert_raises(ValueError, np.random.multinomial, 10, np.array([[0, 1], [1, 0]])) + + +class TestSetState: + def setup(self): + self.seed = 1234567890 + self.prng = random.RandomState(self.seed) + self.state = self.prng.get_state() + + def test_basic(self): + old = self.prng.tomaxint(16) + self.prng.set_state(self.state) + new = self.prng.tomaxint(16) + assert_(np.all(old == new)) + + def test_gaussian_reset(self): + # Make sure the cached every-other-Gaussian is reset. + old = self.prng.standard_normal(size=3) + self.prng.set_state(self.state) + new = self.prng.standard_normal(size=3) + assert_(np.all(old == new)) + + def test_gaussian_reset_in_media_res(self): + # When the state is saved with a cached Gaussian, make sure the + # cached Gaussian is restored. + + self.prng.standard_normal() + state = self.prng.get_state() + old = self.prng.standard_normal(size=3) + self.prng.set_state(state) + new = self.prng.standard_normal(size=3) + assert_(np.all(old == new)) + + def test_backwards_compatibility(self): + # Make sure we can accept old state tuples that do not have the + # cached Gaussian value. + old_state = self.state[:-2] + x1 = self.prng.standard_normal(size=16) + self.prng.set_state(old_state) + x2 = self.prng.standard_normal(size=16) + self.prng.set_state(self.state) + x3 = self.prng.standard_normal(size=16) + assert_(np.all(x1 == x2)) + assert_(np.all(x1 == x3)) + + def test_negative_binomial(self): + # Ensure that the negative binomial results take floating point + # arguments without truncation. + self.prng.negative_binomial(0.5, 0.5) + + +class TestRandint: + + rfunc = np.random.randint + + # valid integer/boolean types + itype = [np.bool_, np.int8, np.uint8, np.int16, np.uint16, + np.int32, np.uint32, np.int64, np.uint64] + + def test_unsupported_type(self): + assert_raises(TypeError, self.rfunc, 1, dtype=float) + + def test_bounds_checking(self): + for dt in self.itype: + lbnd = 0 if dt is np.bool_ else np.iinfo(dt).min + ubnd = 2 if dt is np.bool_ else np.iinfo(dt).max + 1 + assert_raises(ValueError, self.rfunc, lbnd - 1, ubnd, dtype=dt) + assert_raises(ValueError, self.rfunc, lbnd, ubnd + 1, dtype=dt) + assert_raises(ValueError, self.rfunc, ubnd, lbnd, dtype=dt) + assert_raises(ValueError, self.rfunc, 1, 0, dtype=dt) + + def test_rng_zero_and_extremes(self): + for dt in self.itype: + lbnd = 0 if dt is np.bool_ else np.iinfo(dt).min + ubnd = 2 if dt is np.bool_ else np.iinfo(dt).max + 1 + + tgt = ubnd - 1 + assert_equal(self.rfunc(tgt, tgt + 1, size=1000, dtype=dt), tgt) + + tgt = lbnd + assert_equal(self.rfunc(tgt, tgt + 1, size=1000, dtype=dt), tgt) + + tgt = (lbnd + ubnd)//2 + assert_equal(self.rfunc(tgt, tgt + 1, size=1000, dtype=dt), tgt) + + def test_full_range(self): + # Test for ticket #1690 + + for dt in self.itype: + lbnd = 0 if dt is np.bool_ else np.iinfo(dt).min + ubnd = 2 if dt is np.bool_ else np.iinfo(dt).max + 1 + + try: + self.rfunc(lbnd, ubnd, dtype=dt) + except Exception as e: + raise AssertionError("No error should have been raised, " + "but one was with the following " + "message:\n\n%s" % str(e)) + + def test_in_bounds_fuzz(self): + # Don't use fixed seed + np.random.seed() + + for dt in self.itype[1:]: + for ubnd in [4, 8, 16]: + vals = self.rfunc(2, ubnd, size=2**16, dtype=dt) + assert_(vals.max() < ubnd) + assert_(vals.min() >= 2) + + vals = self.rfunc(0, 2, size=2**16, dtype=np.bool_) + + assert_(vals.max() < 2) + assert_(vals.min() >= 0) + + def test_repeatability(self): + import hashlib + # We use a sha256 hash of generated sequences of 1000 samples + # in the range [0, 6) for all but bool, where the range + # is [0, 2). Hashes are for little endian numbers. + tgt = {'bool': '509aea74d792fb931784c4b0135392c65aec64beee12b0cc167548a2c3d31e71', + 'int16': '7b07f1a920e46f6d0fe02314155a2330bcfd7635e708da50e536c5ebb631a7d4', + 'int32': 'e577bfed6c935de944424667e3da285012e741892dcb7051a8f1ce68ab05c92f', + 'int64': '0fbead0b06759df2cfb55e43148822d4a1ff953c7eb19a5b08445a63bb64fa9e', + 'int8': '001aac3a5acb935a9b186cbe14a1ca064b8bb2dd0b045d48abeacf74d0203404', + 'uint16': '7b07f1a920e46f6d0fe02314155a2330bcfd7635e708da50e536c5ebb631a7d4', + 'uint32': 'e577bfed6c935de944424667e3da285012e741892dcb7051a8f1ce68ab05c92f', + 'uint64': '0fbead0b06759df2cfb55e43148822d4a1ff953c7eb19a5b08445a63bb64fa9e', + 'uint8': '001aac3a5acb935a9b186cbe14a1ca064b8bb2dd0b045d48abeacf74d0203404'} + + for dt in self.itype[1:]: + np.random.seed(1234) + + # view as little endian for hash + if sys.byteorder == 'little': + val = self.rfunc(0, 6, size=1000, dtype=dt) + else: + val = self.rfunc(0, 6, size=1000, dtype=dt).byteswap() + + res = hashlib.sha256(val.view(np.int8)).hexdigest() + assert_(tgt[np.dtype(dt).name] == res) + + # bools do not depend on endianness + np.random.seed(1234) + val = self.rfunc(0, 2, size=1000, dtype=bool).view(np.int8) + res = hashlib.sha256(val).hexdigest() + assert_(tgt[np.dtype(bool).name] == res) + + def test_int64_uint64_corner_case(self): + # When stored in Numpy arrays, `lbnd` is casted + # as np.int64, and `ubnd` is casted as np.uint64. + # Checking whether `lbnd` >= `ubnd` used to be + # done solely via direct comparison, which is incorrect + # because when Numpy tries to compare both numbers, + # it casts both to np.float64 because there is + # no integer superset of np.int64 and np.uint64. However, + # `ubnd` is too large to be represented in np.float64, + # causing it be round down to np.iinfo(np.int64).max, + # leading to a ValueError because `lbnd` now equals + # the new `ubnd`. + + dt = np.int64 + tgt = np.iinfo(np.int64).max + lbnd = np.int64(np.iinfo(np.int64).max) + ubnd = np.uint64(np.iinfo(np.int64).max + 1) + + # None of these function calls should + # generate a ValueError now. + actual = np.random.randint(lbnd, ubnd, dtype=dt) + assert_equal(actual, tgt) + + def test_respect_dtype_singleton(self): + # See gh-7203 + for dt in self.itype: + lbnd = 0 if dt is np.bool_ else np.iinfo(dt).min + ubnd = 2 if dt is np.bool_ else np.iinfo(dt).max + 1 + + sample = self.rfunc(lbnd, ubnd, dtype=dt) + assert_equal(sample.dtype, np.dtype(dt)) + + for dt in (bool, int, np.compat.long): + lbnd = 0 if dt is bool else np.iinfo(dt).min + ubnd = 2 if dt is bool else np.iinfo(dt).max + 1 + + # gh-7284: Ensure that we get Python data types + sample = self.rfunc(lbnd, ubnd, dtype=dt) + assert_(not hasattr(sample, 'dtype')) + assert_equal(type(sample), dt) + + +class TestRandomDist: + # Make sure the random distribution returns the correct value for a + # given seed + + def setup(self): + self.seed = 1234567890 + + def test_rand(self): + np.random.seed(self.seed) + actual = np.random.rand(3, 2) + desired = np.array([[0.61879477158567997, 0.59162362775974664], + [0.88868358904449662, 0.89165480011560816], + [0.4575674820298663, 0.7781880808593471]]) + assert_array_almost_equal(actual, desired, decimal=15) + + def test_randn(self): + np.random.seed(self.seed) + actual = np.random.randn(3, 2) + desired = np.array([[1.34016345771863121, 1.73759122771936081], + [1.498988344300628, -0.2286433324536169], + [2.031033998682787, 2.17032494605655257]]) + assert_array_almost_equal(actual, desired, decimal=15) + + def test_randint(self): + np.random.seed(self.seed) + actual = np.random.randint(-99, 99, size=(3, 2)) + desired = np.array([[31, 3], + [-52, 41], + [-48, -66]]) + assert_array_equal(actual, desired) + + def test_random_integers(self): + np.random.seed(self.seed) + with suppress_warnings() as sup: + w = sup.record(DeprecationWarning) + actual = np.random.random_integers(-99, 99, size=(3, 2)) + assert_(len(w) == 1) + desired = np.array([[31, 3], + [-52, 41], + [-48, -66]]) + assert_array_equal(actual, desired) + + def test_random_integers_max_int(self): + # Tests whether random_integers can generate the + # maximum allowed Python int that can be converted + # into a C long. Previous implementations of this + # method have thrown an OverflowError when attempting + # to generate this integer. + with suppress_warnings() as sup: + w = sup.record(DeprecationWarning) + actual = np.random.random_integers(np.iinfo('l').max, + np.iinfo('l').max) + assert_(len(w) == 1) + + desired = np.iinfo('l').max + assert_equal(actual, desired) + + def test_random_integers_deprecated(self): + with warnings.catch_warnings(): + warnings.simplefilter("error", DeprecationWarning) + + # DeprecationWarning raised with high == None + assert_raises(DeprecationWarning, + np.random.random_integers, + np.iinfo('l').max) + + # DeprecationWarning raised with high != None + assert_raises(DeprecationWarning, + np.random.random_integers, + np.iinfo('l').max, np.iinfo('l').max) + + def test_random(self): + np.random.seed(self.seed) + actual = np.random.random((3, 2)) + desired = np.array([[0.61879477158567997, 0.59162362775974664], + [0.88868358904449662, 0.89165480011560816], + [0.4575674820298663, 0.7781880808593471]]) + assert_array_almost_equal(actual, desired, decimal=15) + + def test_choice_uniform_replace(self): + np.random.seed(self.seed) + actual = np.random.choice(4, 4) + desired = np.array([2, 3, 2, 3]) + assert_array_equal(actual, desired) + + def test_choice_nonuniform_replace(self): + np.random.seed(self.seed) + actual = np.random.choice(4, 4, p=[0.4, 0.4, 0.1, 0.1]) + desired = np.array([1, 1, 2, 2]) + assert_array_equal(actual, desired) + + def test_choice_uniform_noreplace(self): + np.random.seed(self.seed) + actual = np.random.choice(4, 3, replace=False) + desired = np.array([0, 1, 3]) + assert_array_equal(actual, desired) + + def test_choice_nonuniform_noreplace(self): + np.random.seed(self.seed) + actual = np.random.choice(4, 3, replace=False, + p=[0.1, 0.3, 0.5, 0.1]) + desired = np.array([2, 3, 1]) + assert_array_equal(actual, desired) + + def test_choice_noninteger(self): + np.random.seed(self.seed) + actual = np.random.choice(['a', 'b', 'c', 'd'], 4) + desired = np.array(['c', 'd', 'c', 'd']) + assert_array_equal(actual, desired) + + def test_choice_exceptions(self): + sample = np.random.choice + assert_raises(ValueError, sample, -1, 3) + assert_raises(ValueError, sample, 3., 3) + assert_raises(ValueError, sample, [[1, 2], [3, 4]], 3) + assert_raises(ValueError, sample, [], 3) + assert_raises(ValueError, sample, [1, 2, 3, 4], 3, + p=[[0.25, 0.25], [0.25, 0.25]]) + assert_raises(ValueError, sample, [1, 2], 3, p=[0.4, 0.4, 0.2]) + assert_raises(ValueError, sample, [1, 2], 3, p=[1.1, -0.1]) + assert_raises(ValueError, sample, [1, 2], 3, p=[0.4, 0.4]) + assert_raises(ValueError, sample, [1, 2, 3], 4, replace=False) + # gh-13087 + assert_raises(ValueError, sample, [1, 2, 3], -2, replace=False) + assert_raises(ValueError, sample, [1, 2, 3], (-1,), replace=False) + assert_raises(ValueError, sample, [1, 2, 3], (-1, 1), replace=False) + assert_raises(ValueError, sample, [1, 2, 3], 2, + replace=False, p=[1, 0, 0]) + + def test_choice_return_shape(self): + p = [0.1, 0.9] + # Check scalar + assert_(np.isscalar(np.random.choice(2, replace=True))) + assert_(np.isscalar(np.random.choice(2, replace=False))) + assert_(np.isscalar(np.random.choice(2, replace=True, p=p))) + assert_(np.isscalar(np.random.choice(2, replace=False, p=p))) + assert_(np.isscalar(np.random.choice([1, 2], replace=True))) + assert_(np.random.choice([None], replace=True) is None) + a = np.array([1, 2]) + arr = np.empty(1, dtype=object) + arr[0] = a + assert_(np.random.choice(arr, replace=True) is a) + + # Check 0-d array + s = tuple() + assert_(not np.isscalar(np.random.choice(2, s, replace=True))) + assert_(not np.isscalar(np.random.choice(2, s, replace=False))) + assert_(not np.isscalar(np.random.choice(2, s, replace=True, p=p))) + assert_(not np.isscalar(np.random.choice(2, s, replace=False, p=p))) + assert_(not np.isscalar(np.random.choice([1, 2], s, replace=True))) + assert_(np.random.choice([None], s, replace=True).ndim == 0) + a = np.array([1, 2]) + arr = np.empty(1, dtype=object) + arr[0] = a + assert_(np.random.choice(arr, s, replace=True).item() is a) + + # Check multi dimensional array + s = (2, 3) + p = [0.1, 0.1, 0.1, 0.1, 0.4, 0.2] + assert_equal(np.random.choice(6, s, replace=True).shape, s) + assert_equal(np.random.choice(6, s, replace=False).shape, s) + assert_equal(np.random.choice(6, s, replace=True, p=p).shape, s) + assert_equal(np.random.choice(6, s, replace=False, p=p).shape, s) + assert_equal(np.random.choice(np.arange(6), s, replace=True).shape, s) + + # Check zero-size + assert_equal(np.random.randint(0, 0, size=(3, 0, 4)).shape, (3, 0, 4)) + assert_equal(np.random.randint(0, -10, size=0).shape, (0,)) + assert_equal(np.random.randint(10, 10, size=0).shape, (0,)) + assert_equal(np.random.choice(0, size=0).shape, (0,)) + assert_equal(np.random.choice([], size=(0,)).shape, (0,)) + assert_equal(np.random.choice(['a', 'b'], size=(3, 0, 4)).shape, + (3, 0, 4)) + assert_raises(ValueError, np.random.choice, [], 10) + + def test_choice_nan_probabilities(self): + a = np.array([42, 1, 2]) + p = [None, None, None] + assert_raises(ValueError, np.random.choice, a, p=p) + + def test_bytes(self): + np.random.seed(self.seed) + actual = np.random.bytes(10) + desired = b'\x82Ui\x9e\xff\x97+Wf\xa5' + assert_equal(actual, desired) + + def test_shuffle(self): + # Test lists, arrays (of various dtypes), and multidimensional versions + # of both, c-contiguous or not: + for conv in [lambda x: np.array([]), + lambda x: x, + lambda x: np.asarray(x).astype(np.int8), + lambda x: np.asarray(x).astype(np.float32), + lambda x: np.asarray(x).astype(np.complex64), + lambda x: np.asarray(x).astype(object), + lambda x: [(i, i) for i in x], + lambda x: np.asarray([[i, i] for i in x]), + lambda x: np.vstack([x, x]).T, + # gh-11442 + lambda x: (np.asarray([(i, i) for i in x], + [("a", int), ("b", int)]) + .view(np.recarray)), + # gh-4270 + lambda x: np.asarray([(i, i) for i in x], + [("a", object), ("b", np.int32)])]: + np.random.seed(self.seed) + alist = conv([1, 2, 3, 4, 5, 6, 7, 8, 9, 0]) + np.random.shuffle(alist) + actual = alist + desired = conv([0, 1, 9, 6, 2, 4, 5, 8, 7, 3]) + assert_array_equal(actual, desired) + + def test_shuffle_masked(self): + # gh-3263 + a = np.ma.masked_values(np.reshape(range(20), (5, 4)) % 3 - 1, -1) + b = np.ma.masked_values(np.arange(20) % 3 - 1, -1) + a_orig = a.copy() + b_orig = b.copy() + for i in range(50): + np.random.shuffle(a) + assert_equal( + sorted(a.data[~a.mask]), sorted(a_orig.data[~a_orig.mask])) + np.random.shuffle(b) + assert_equal( + sorted(b.data[~b.mask]), sorted(b_orig.data[~b_orig.mask])) + + def test_shuffle_memoryview(self): + # gh-18273 + # allow graceful handling of memoryviews + # (treat the same as arrays) + np.random.seed(self.seed) + a = np.arange(5).data + np.random.shuffle(a) + assert_equal(np.asarray(a), [0, 1, 4, 3, 2]) + rng = np.random.RandomState(self.seed) + rng.shuffle(a) + assert_equal(np.asarray(a), [0, 1, 2, 3, 4]) + rng = np.random.default_rng(self.seed) + rng.shuffle(a) + assert_equal(np.asarray(a), [4, 1, 0, 3, 2]) + + def test_beta(self): + np.random.seed(self.seed) + actual = np.random.beta(.1, .9, size=(3, 2)) + desired = np.array( + [[1.45341850513746058e-02, 5.31297615662868145e-04], + [1.85366619058432324e-06, 4.19214516800110563e-03], + [1.58405155108498093e-04, 1.26252891949397652e-04]]) + assert_array_almost_equal(actual, desired, decimal=15) + + def test_binomial(self): + np.random.seed(self.seed) + actual = np.random.binomial(100, .456, size=(3, 2)) + desired = np.array([[37, 43], + [42, 48], + [46, 45]]) + assert_array_equal(actual, desired) + + def test_chisquare(self): + np.random.seed(self.seed) + actual = np.random.chisquare(50, size=(3, 2)) + desired = np.array([[63.87858175501090585, 68.68407748911370447], + [65.77116116901505904, 47.09686762438974483], + [72.3828403199695174, 74.18408615260374006]]) + assert_array_almost_equal(actual, desired, decimal=13) + + def test_dirichlet(self): + np.random.seed(self.seed) + alpha = np.array([51.72840233779265162, 39.74494232180943953]) + actual = np.random.mtrand.dirichlet(alpha, size=(3, 2)) + desired = np.array([[[0.54539444573611562, 0.45460555426388438], + [0.62345816822039413, 0.37654183177960598]], + [[0.55206000085785778, 0.44793999914214233], + [0.58964023305154301, 0.41035976694845688]], + [[0.59266909280647828, 0.40733090719352177], + [0.56974431743975207, 0.43025568256024799]]]) + assert_array_almost_equal(actual, desired, decimal=15) + + def test_dirichlet_size(self): + # gh-3173 + p = np.array([51.72840233779265162, 39.74494232180943953]) + assert_equal(np.random.dirichlet(p, np.uint32(1)).shape, (1, 2)) + assert_equal(np.random.dirichlet(p, np.uint32(1)).shape, (1, 2)) + assert_equal(np.random.dirichlet(p, np.uint32(1)).shape, (1, 2)) + assert_equal(np.random.dirichlet(p, [2, 2]).shape, (2, 2, 2)) + assert_equal(np.random.dirichlet(p, (2, 2)).shape, (2, 2, 2)) + assert_equal(np.random.dirichlet(p, np.array((2, 2))).shape, (2, 2, 2)) + + assert_raises(TypeError, np.random.dirichlet, p, float(1)) + + def test_dirichlet_bad_alpha(self): + # gh-2089 + alpha = np.array([5.4e-01, -1.0e-16]) + assert_raises(ValueError, np.random.mtrand.dirichlet, alpha) + + # gh-15876 + assert_raises(ValueError, random.dirichlet, [[5, 1]]) + assert_raises(ValueError, random.dirichlet, [[5], [1]]) + assert_raises(ValueError, random.dirichlet, [[[5], [1]], [[1], [5]]]) + assert_raises(ValueError, random.dirichlet, np.array([[5, 1], [1, 5]])) + + def test_exponential(self): + np.random.seed(self.seed) + actual = np.random.exponential(1.1234, size=(3, 2)) + desired = np.array([[1.08342649775011624, 1.00607889924557314], + [2.46628830085216721, 2.49668106809923884], + [0.68717433461363442, 1.69175666993575979]]) + assert_array_almost_equal(actual, desired, decimal=15) + + def test_exponential_0(self): + assert_equal(np.random.exponential(scale=0), 0) + assert_raises(ValueError, np.random.exponential, scale=-0.) + + def test_f(self): + np.random.seed(self.seed) + actual = np.random.f(12, 77, size=(3, 2)) + desired = np.array([[1.21975394418575878, 1.75135759791559775], + [1.44803115017146489, 1.22108959480396262], + [1.02176975757740629, 1.34431827623300415]]) + assert_array_almost_equal(actual, desired, decimal=15) + + def test_gamma(self): + np.random.seed(self.seed) + actual = np.random.gamma(5, 3, size=(3, 2)) + desired = np.array([[24.60509188649287182, 28.54993563207210627], + [26.13476110204064184, 12.56988482927716078], + [31.71863275789960568, 33.30143302795922011]]) + assert_array_almost_equal(actual, desired, decimal=14) + + def test_gamma_0(self): + assert_equal(np.random.gamma(shape=0, scale=0), 0) + assert_raises(ValueError, np.random.gamma, shape=-0., scale=-0.) + + def test_geometric(self): + np.random.seed(self.seed) + actual = np.random.geometric(.123456789, size=(3, 2)) + desired = np.array([[8, 7], + [17, 17], + [5, 12]]) + assert_array_equal(actual, desired) + + def test_gumbel(self): + np.random.seed(self.seed) + actual = np.random.gumbel(loc=.123456789, scale=2.0, size=(3, 2)) + desired = np.array([[0.19591898743416816, 0.34405539668096674], + [-1.4492522252274278, -1.47374816298446865], + [1.10651090478803416, -0.69535848626236174]]) + assert_array_almost_equal(actual, desired, decimal=15) + + def test_gumbel_0(self): + assert_equal(np.random.gumbel(scale=0), 0) + assert_raises(ValueError, np.random.gumbel, scale=-0.) + + def test_hypergeometric(self): + np.random.seed(self.seed) + actual = np.random.hypergeometric(10, 5, 14, size=(3, 2)) + desired = np.array([[10, 10], + [10, 10], + [9, 9]]) + assert_array_equal(actual, desired) + + # Test nbad = 0 + actual = np.random.hypergeometric(5, 0, 3, size=4) + desired = np.array([3, 3, 3, 3]) + assert_array_equal(actual, desired) + + actual = np.random.hypergeometric(15, 0, 12, size=4) + desired = np.array([12, 12, 12, 12]) + assert_array_equal(actual, desired) + + # Test ngood = 0 + actual = np.random.hypergeometric(0, 5, 3, size=4) + desired = np.array([0, 0, 0, 0]) + assert_array_equal(actual, desired) + + actual = np.random.hypergeometric(0, 15, 12, size=4) + desired = np.array([0, 0, 0, 0]) + assert_array_equal(actual, desired) + + def test_laplace(self): + np.random.seed(self.seed) + actual = np.random.laplace(loc=.123456789, scale=2.0, size=(3, 2)) + desired = np.array([[0.66599721112760157, 0.52829452552221945], + [3.12791959514407125, 3.18202813572992005], + [-0.05391065675859356, 1.74901336242837324]]) + assert_array_almost_equal(actual, desired, decimal=15) + + def test_laplace_0(self): + assert_equal(np.random.laplace(scale=0), 0) + assert_raises(ValueError, np.random.laplace, scale=-0.) + + def test_logistic(self): + np.random.seed(self.seed) + actual = np.random.logistic(loc=.123456789, scale=2.0, size=(3, 2)) + desired = np.array([[1.09232835305011444, 0.8648196662399954], + [4.27818590694950185, 4.33897006346929714], + [-0.21682183359214885, 2.63373365386060332]]) + assert_array_almost_equal(actual, desired, decimal=15) + + def test_lognormal(self): + np.random.seed(self.seed) + actual = np.random.lognormal(mean=.123456789, sigma=2.0, size=(3, 2)) + desired = np.array([[16.50698631688883822, 36.54846706092654784], + [22.67886599981281748, 0.71617561058995771], + [65.72798501792723869, 86.84341601437161273]]) + assert_array_almost_equal(actual, desired, decimal=13) + + def test_lognormal_0(self): + assert_equal(np.random.lognormal(sigma=0), 1) + assert_raises(ValueError, np.random.lognormal, sigma=-0.) + + def test_logseries(self): + np.random.seed(self.seed) + actual = np.random.logseries(p=.923456789, size=(3, 2)) + desired = np.array([[2, 2], + [6, 17], + [3, 6]]) + assert_array_equal(actual, desired) + + def test_multinomial(self): + np.random.seed(self.seed) + actual = np.random.multinomial(20, [1/6.]*6, size=(3, 2)) + desired = np.array([[[4, 3, 5, 4, 2, 2], + [5, 2, 8, 2, 2, 1]], + [[3, 4, 3, 6, 0, 4], + [2, 1, 4, 3, 6, 4]], + [[4, 4, 2, 5, 2, 3], + [4, 3, 4, 2, 3, 4]]]) + assert_array_equal(actual, desired) + + def test_multivariate_normal(self): + np.random.seed(self.seed) + mean = (.123456789, 10) + cov = [[1, 0], [0, 1]] + size = (3, 2) + actual = np.random.multivariate_normal(mean, cov, size) + desired = np.array([[[1.463620246718631, 11.73759122771936], + [1.622445133300628, 9.771356667546383]], + [[2.154490787682787, 12.170324946056553], + [1.719909438201865, 9.230548443648306]], + [[0.689515026297799, 9.880729819607714], + [-0.023054015651998, 9.201096623542879]]]) + + assert_array_almost_equal(actual, desired, decimal=15) + + # Check for default size, was raising deprecation warning + actual = np.random.multivariate_normal(mean, cov) + desired = np.array([0.895289569463708, 9.17180864067987]) + assert_array_almost_equal(actual, desired, decimal=15) + + # Check that non positive-semidefinite covariance warns with + # RuntimeWarning + mean = [0, 0] + cov = [[1, 2], [2, 1]] + assert_warns(RuntimeWarning, np.random.multivariate_normal, mean, cov) + + # and that it doesn't warn with RuntimeWarning check_valid='ignore' + assert_no_warnings(np.random.multivariate_normal, mean, cov, + check_valid='ignore') + + # and that it raises with RuntimeWarning check_valid='raises' + assert_raises(ValueError, np.random.multivariate_normal, mean, cov, + check_valid='raise') + + cov = np.array([[1, 0.1], [0.1, 1]], dtype=np.float32) + with suppress_warnings() as sup: + np.random.multivariate_normal(mean, cov) + w = sup.record(RuntimeWarning) + assert len(w) == 0 + + def test_negative_binomial(self): + np.random.seed(self.seed) + actual = np.random.negative_binomial(n=100, p=.12345, size=(3, 2)) + desired = np.array([[848, 841], + [892, 611], + [779, 647]]) + assert_array_equal(actual, desired) + + def test_noncentral_chisquare(self): + np.random.seed(self.seed) + actual = np.random.noncentral_chisquare(df=5, nonc=5, size=(3, 2)) + desired = np.array([[23.91905354498517511, 13.35324692733826346], + [31.22452661329736401, 16.60047399466177254], + [5.03461598262724586, 17.94973089023519464]]) + assert_array_almost_equal(actual, desired, decimal=14) + + actual = np.random.noncentral_chisquare(df=.5, nonc=.2, size=(3, 2)) + desired = np.array([[1.47145377828516666, 0.15052899268012659], + [0.00943803056963588, 1.02647251615666169], + [0.332334982684171, 0.15451287602753125]]) + assert_array_almost_equal(actual, desired, decimal=14) + + np.random.seed(self.seed) + actual = np.random.noncentral_chisquare(df=5, nonc=0, size=(3, 2)) + desired = np.array([[9.597154162763948, 11.725484450296079], + [10.413711048138335, 3.694475922923986], + [13.484222138963087, 14.377255424602957]]) + assert_array_almost_equal(actual, desired, decimal=14) + + def test_noncentral_f(self): + np.random.seed(self.seed) + actual = np.random.noncentral_f(dfnum=5, dfden=2, nonc=1, + size=(3, 2)) + desired = np.array([[1.40598099674926669, 0.34207973179285761], + [3.57715069265772545, 7.92632662577829805], + [0.43741599463544162, 1.1774208752428319]]) + assert_array_almost_equal(actual, desired, decimal=14) + + def test_normal(self): + np.random.seed(self.seed) + actual = np.random.normal(loc=.123456789, scale=2.0, size=(3, 2)) + desired = np.array([[2.80378370443726244, 3.59863924443872163], + [3.121433477601256, -0.33382987590723379], + [4.18552478636557357, 4.46410668111310471]]) + assert_array_almost_equal(actual, desired, decimal=15) + + def test_normal_0(self): + assert_equal(np.random.normal(scale=0), 0) + assert_raises(ValueError, np.random.normal, scale=-0.) + + def test_pareto(self): + np.random.seed(self.seed) + actual = np.random.pareto(a=.123456789, size=(3, 2)) + desired = np.array( + [[2.46852460439034849e+03, 1.41286880810518346e+03], + [5.28287797029485181e+07, 6.57720981047328785e+07], + [1.40840323350391515e+02, 1.98390255135251704e+05]]) + # For some reason on 32-bit x86 Ubuntu 12.10 the [1, 0] entry in this + # matrix differs by 24 nulps. Discussion: + # https://mail.python.org/pipermail/numpy-discussion/2012-September/063801.html + # Consensus is that this is probably some gcc quirk that affects + # rounding but not in any important way, so we just use a looser + # tolerance on this test: + np.testing.assert_array_almost_equal_nulp(actual, desired, nulp=30) + + def test_poisson(self): + np.random.seed(self.seed) + actual = np.random.poisson(lam=.123456789, size=(3, 2)) + desired = np.array([[0, 0], + [1, 0], + [0, 0]]) + assert_array_equal(actual, desired) + + def test_poisson_exceptions(self): + lambig = np.iinfo('l').max + lamneg = -1 + assert_raises(ValueError, np.random.poisson, lamneg) + assert_raises(ValueError, np.random.poisson, [lamneg]*10) + assert_raises(ValueError, np.random.poisson, lambig) + assert_raises(ValueError, np.random.poisson, [lambig]*10) + + def test_power(self): + np.random.seed(self.seed) + actual = np.random.power(a=.123456789, size=(3, 2)) + desired = np.array([[0.02048932883240791, 0.01424192241128213], + [0.38446073748535298, 0.39499689943484395], + [0.00177699707563439, 0.13115505880863756]]) + assert_array_almost_equal(actual, desired, decimal=15) + + def test_rayleigh(self): + np.random.seed(self.seed) + actual = np.random.rayleigh(scale=10, size=(3, 2)) + desired = np.array([[13.8882496494248393, 13.383318339044731], + [20.95413364294492098, 21.08285015800712614], + [11.06066537006854311, 17.35468505778271009]]) + assert_array_almost_equal(actual, desired, decimal=14) + + def test_rayleigh_0(self): + assert_equal(np.random.rayleigh(scale=0), 0) + assert_raises(ValueError, np.random.rayleigh, scale=-0.) + + def test_standard_cauchy(self): + np.random.seed(self.seed) + actual = np.random.standard_cauchy(size=(3, 2)) + desired = np.array([[0.77127660196445336, -6.55601161955910605], + [0.93582023391158309, -2.07479293013759447], + [-4.74601644297011926, 0.18338989290760804]]) + assert_array_almost_equal(actual, desired, decimal=15) + + def test_standard_exponential(self): + np.random.seed(self.seed) + actual = np.random.standard_exponential(size=(3, 2)) + desired = np.array([[0.96441739162374596, 0.89556604882105506], + [2.1953785836319808, 2.22243285392490542], + [0.6116915921431676, 1.50592546727413201]]) + assert_array_almost_equal(actual, desired, decimal=15) + + def test_standard_gamma(self): + np.random.seed(self.seed) + actual = np.random.standard_gamma(shape=3, size=(3, 2)) + desired = np.array([[5.50841531318455058, 6.62953470301903103], + [5.93988484943779227, 2.31044849402133989], + [7.54838614231317084, 8.012756093271868]]) + assert_array_almost_equal(actual, desired, decimal=14) + + def test_standard_gamma_0(self): + assert_equal(np.random.standard_gamma(shape=0), 0) + assert_raises(ValueError, np.random.standard_gamma, shape=-0.) + + def test_standard_normal(self): + np.random.seed(self.seed) + actual = np.random.standard_normal(size=(3, 2)) + desired = np.array([[1.34016345771863121, 1.73759122771936081], + [1.498988344300628, -0.2286433324536169], + [2.031033998682787, 2.17032494605655257]]) + assert_array_almost_equal(actual, desired, decimal=15) + + def test_standard_t(self): + np.random.seed(self.seed) + actual = np.random.standard_t(df=10, size=(3, 2)) + desired = np.array([[0.97140611862659965, -0.08830486548450577], + [1.36311143689505321, -0.55317463909867071], + [-0.18473749069684214, 0.61181537341755321]]) + assert_array_almost_equal(actual, desired, decimal=15) + + def test_triangular(self): + np.random.seed(self.seed) + actual = np.random.triangular(left=5.12, mode=10.23, right=20.34, + size=(3, 2)) + desired = np.array([[12.68117178949215784, 12.4129206149193152], + [16.20131377335158263, 16.25692138747600524], + [11.20400690911820263, 14.4978144835829923]]) + assert_array_almost_equal(actual, desired, decimal=14) + + def test_uniform(self): + np.random.seed(self.seed) + actual = np.random.uniform(low=1.23, high=10.54, size=(3, 2)) + desired = np.array([[6.99097932346268003, 6.73801597444323974], + [9.50364421400426274, 9.53130618907631089], + [5.48995325769805476, 8.47493103280052118]]) + assert_array_almost_equal(actual, desired, decimal=15) + + def test_uniform_range_bounds(self): + fmin = np.finfo('float').min + fmax = np.finfo('float').max + + func = np.random.uniform + assert_raises(OverflowError, func, -np.inf, 0) + assert_raises(OverflowError, func, 0, np.inf) + assert_raises(OverflowError, func, fmin, fmax) + assert_raises(OverflowError, func, [-np.inf], [0]) + assert_raises(OverflowError, func, [0], [np.inf]) + + # (fmax / 1e17) - fmin is within range, so this should not throw + # account for i386 extended precision DBL_MAX / 1e17 + DBL_MAX > + # DBL_MAX by increasing fmin a bit + np.random.uniform(low=np.nextafter(fmin, 1), high=fmax / 1e17) + + def test_scalar_exception_propagation(self): + # Tests that exceptions are correctly propagated in distributions + # when called with objects that throw exceptions when converted to + # scalars. + # + # Regression test for gh: 8865 + + class ThrowingFloat(np.ndarray): + def __float__(self): + raise TypeError + + throwing_float = np.array(1.0).view(ThrowingFloat) + assert_raises(TypeError, np.random.uniform, throwing_float, + throwing_float) + + class ThrowingInteger(np.ndarray): + def __int__(self): + raise TypeError + + __index__ = __int__ + + throwing_int = np.array(1).view(ThrowingInteger) + assert_raises(TypeError, np.random.hypergeometric, throwing_int, 1, 1) + + def test_vonmises(self): + np.random.seed(self.seed) + actual = np.random.vonmises(mu=1.23, kappa=1.54, size=(3, 2)) + desired = np.array([[2.28567572673902042, 2.89163838442285037], + [0.38198375564286025, 2.57638023113890746], + [1.19153771588353052, 1.83509849681825354]]) + assert_array_almost_equal(actual, desired, decimal=15) + + def test_vonmises_small(self): + # check infinite loop, gh-4720 + np.random.seed(self.seed) + r = np.random.vonmises(mu=0., kappa=1.1e-8, size=10**6) + np.testing.assert_(np.isfinite(r).all()) + + def test_wald(self): + np.random.seed(self.seed) + actual = np.random.wald(mean=1.23, scale=1.54, size=(3, 2)) + desired = np.array([[3.82935265715889983, 5.13125249184285526], + [0.35045403618358717, 1.50832396872003538], + [0.24124319895843183, 0.22031101461955038]]) + assert_array_almost_equal(actual, desired, decimal=14) + + def test_weibull(self): + np.random.seed(self.seed) + actual = np.random.weibull(a=1.23, size=(3, 2)) + desired = np.array([[0.97097342648766727, 0.91422896443565516], + [1.89517770034962929, 1.91414357960479564], + [0.67057783752390987, 1.39494046635066793]]) + assert_array_almost_equal(actual, desired, decimal=15) + + def test_weibull_0(self): + np.random.seed(self.seed) + assert_equal(np.random.weibull(a=0, size=12), np.zeros(12)) + assert_raises(ValueError, np.random.weibull, a=-0.) + + def test_zipf(self): + np.random.seed(self.seed) + actual = np.random.zipf(a=1.23, size=(3, 2)) + desired = np.array([[66, 29], + [1, 1], + [3, 13]]) + assert_array_equal(actual, desired) + + +class TestBroadcast: + # tests that functions that broadcast behave + # correctly when presented with non-scalar arguments + def setup(self): + self.seed = 123456789 + + def setSeed(self): + np.random.seed(self.seed) + + # TODO: Include test for randint once it can broadcast + # Can steal the test written in PR #6938 + + def test_uniform(self): + low = [0] + high = [1] + uniform = np.random.uniform + desired = np.array([0.53283302478975902, + 0.53413660089041659, + 0.50955303552646702]) + + self.setSeed() + actual = uniform(low * 3, high) + assert_array_almost_equal(actual, desired, decimal=14) + + self.setSeed() + actual = uniform(low, high * 3) + assert_array_almost_equal(actual, desired, decimal=14) + + def test_normal(self): + loc = [0] + scale = [1] + bad_scale = [-1] + normal = np.random.normal + desired = np.array([2.2129019979039612, + 2.1283977976520019, + 1.8417114045748335]) + + self.setSeed() + actual = normal(loc * 3, scale) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, normal, loc * 3, bad_scale) + + self.setSeed() + actual = normal(loc, scale * 3) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, normal, loc, bad_scale * 3) + + def test_beta(self): + a = [1] + b = [2] + bad_a = [-1] + bad_b = [-2] + beta = np.random.beta + desired = np.array([0.19843558305989056, + 0.075230336409423643, + 0.24976865978980844]) + + self.setSeed() + actual = beta(a * 3, b) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, beta, bad_a * 3, b) + assert_raises(ValueError, beta, a * 3, bad_b) + + self.setSeed() + actual = beta(a, b * 3) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, beta, bad_a, b * 3) + assert_raises(ValueError, beta, a, bad_b * 3) + + def test_exponential(self): + scale = [1] + bad_scale = [-1] + exponential = np.random.exponential + desired = np.array([0.76106853658845242, + 0.76386282278691653, + 0.71243813125891797]) + + self.setSeed() + actual = exponential(scale * 3) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, exponential, bad_scale * 3) + + def test_standard_gamma(self): + shape = [1] + bad_shape = [-1] + std_gamma = np.random.standard_gamma + desired = np.array([0.76106853658845242, + 0.76386282278691653, + 0.71243813125891797]) + + self.setSeed() + actual = std_gamma(shape * 3) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, std_gamma, bad_shape * 3) + + def test_gamma(self): + shape = [1] + scale = [2] + bad_shape = [-1] + bad_scale = [-2] + gamma = np.random.gamma + desired = np.array([1.5221370731769048, + 1.5277256455738331, + 1.4248762625178359]) + + self.setSeed() + actual = gamma(shape * 3, scale) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, gamma, bad_shape * 3, scale) + assert_raises(ValueError, gamma, shape * 3, bad_scale) + + self.setSeed() + actual = gamma(shape, scale * 3) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, gamma, bad_shape, scale * 3) + assert_raises(ValueError, gamma, shape, bad_scale * 3) + + def test_f(self): + dfnum = [1] + dfden = [2] + bad_dfnum = [-1] + bad_dfden = [-2] + f = np.random.f + desired = np.array([0.80038951638264799, + 0.86768719635363512, + 2.7251095168386801]) + + self.setSeed() + actual = f(dfnum * 3, dfden) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, f, bad_dfnum * 3, dfden) + assert_raises(ValueError, f, dfnum * 3, bad_dfden) + + self.setSeed() + actual = f(dfnum, dfden * 3) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, f, bad_dfnum, dfden * 3) + assert_raises(ValueError, f, dfnum, bad_dfden * 3) + + def test_noncentral_f(self): + dfnum = [2] + dfden = [3] + nonc = [4] + bad_dfnum = [0] + bad_dfden = [-1] + bad_nonc = [-2] + nonc_f = np.random.noncentral_f + desired = np.array([9.1393943263705211, + 13.025456344595602, + 8.8018098359100545]) + + self.setSeed() + actual = nonc_f(dfnum * 3, dfden, nonc) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, nonc_f, bad_dfnum * 3, dfden, nonc) + assert_raises(ValueError, nonc_f, dfnum * 3, bad_dfden, nonc) + assert_raises(ValueError, nonc_f, dfnum * 3, dfden, bad_nonc) + + self.setSeed() + actual = nonc_f(dfnum, dfden * 3, nonc) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, nonc_f, bad_dfnum, dfden * 3, nonc) + assert_raises(ValueError, nonc_f, dfnum, bad_dfden * 3, nonc) + assert_raises(ValueError, nonc_f, dfnum, dfden * 3, bad_nonc) + + self.setSeed() + actual = nonc_f(dfnum, dfden, nonc * 3) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, nonc_f, bad_dfnum, dfden, nonc * 3) + assert_raises(ValueError, nonc_f, dfnum, bad_dfden, nonc * 3) + assert_raises(ValueError, nonc_f, dfnum, dfden, bad_nonc * 3) + + def test_noncentral_f_small_df(self): + self.setSeed() + desired = np.array([6.869638627492048, 0.785880199263955]) + actual = np.random.noncentral_f(0.9, 0.9, 2, size=2) + assert_array_almost_equal(actual, desired, decimal=14) + + def test_chisquare(self): + df = [1] + bad_df = [-1] + chisquare = np.random.chisquare + desired = np.array([0.57022801133088286, + 0.51947702108840776, + 0.1320969254923558]) + + self.setSeed() + actual = chisquare(df * 3) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, chisquare, bad_df * 3) + + def test_noncentral_chisquare(self): + df = [1] + nonc = [2] + bad_df = [-1] + bad_nonc = [-2] + nonc_chi = np.random.noncentral_chisquare + desired = np.array([9.0015599467913763, + 4.5804135049718742, + 6.0872302432834564]) + + self.setSeed() + actual = nonc_chi(df * 3, nonc) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, nonc_chi, bad_df * 3, nonc) + assert_raises(ValueError, nonc_chi, df * 3, bad_nonc) + + self.setSeed() + actual = nonc_chi(df, nonc * 3) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, nonc_chi, bad_df, nonc * 3) + assert_raises(ValueError, nonc_chi, df, bad_nonc * 3) + + def test_standard_t(self): + df = [1] + bad_df = [-1] + t = np.random.standard_t + desired = np.array([3.0702872575217643, + 5.8560725167361607, + 1.0274791436474273]) + + self.setSeed() + actual = t(df * 3) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, t, bad_df * 3) + + def test_vonmises(self): + mu = [2] + kappa = [1] + bad_kappa = [-1] + vonmises = np.random.vonmises + desired = np.array([2.9883443664201312, + -2.7064099483995943, + -1.8672476700665914]) + + self.setSeed() + actual = vonmises(mu * 3, kappa) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, vonmises, mu * 3, bad_kappa) + + self.setSeed() + actual = vonmises(mu, kappa * 3) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, vonmises, mu, bad_kappa * 3) + + def test_pareto(self): + a = [1] + bad_a = [-1] + pareto = np.random.pareto + desired = np.array([1.1405622680198362, + 1.1465519762044529, + 1.0389564467453547]) + + self.setSeed() + actual = pareto(a * 3) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, pareto, bad_a * 3) + + def test_weibull(self): + a = [1] + bad_a = [-1] + weibull = np.random.weibull + desired = np.array([0.76106853658845242, + 0.76386282278691653, + 0.71243813125891797]) + + self.setSeed() + actual = weibull(a * 3) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, weibull, bad_a * 3) + + def test_power(self): + a = [1] + bad_a = [-1] + power = np.random.power + desired = np.array([0.53283302478975902, + 0.53413660089041659, + 0.50955303552646702]) + + self.setSeed() + actual = power(a * 3) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, power, bad_a * 3) + + def test_laplace(self): + loc = [0] + scale = [1] + bad_scale = [-1] + laplace = np.random.laplace + desired = np.array([0.067921356028507157, + 0.070715642226971326, + 0.019290950698972624]) + + self.setSeed() + actual = laplace(loc * 3, scale) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, laplace, loc * 3, bad_scale) + + self.setSeed() + actual = laplace(loc, scale * 3) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, laplace, loc, bad_scale * 3) + + def test_gumbel(self): + loc = [0] + scale = [1] + bad_scale = [-1] + gumbel = np.random.gumbel + desired = np.array([0.2730318639556768, + 0.26936705726291116, + 0.33906220393037939]) + + self.setSeed() + actual = gumbel(loc * 3, scale) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, gumbel, loc * 3, bad_scale) + + self.setSeed() + actual = gumbel(loc, scale * 3) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, gumbel, loc, bad_scale * 3) + + def test_logistic(self): + loc = [0] + scale = [1] + bad_scale = [-1] + logistic = np.random.logistic + desired = np.array([0.13152135837586171, + 0.13675915696285773, + 0.038216792802833396]) + + self.setSeed() + actual = logistic(loc * 3, scale) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, logistic, loc * 3, bad_scale) + + self.setSeed() + actual = logistic(loc, scale * 3) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, logistic, loc, bad_scale * 3) + + def test_lognormal(self): + mean = [0] + sigma = [1] + bad_sigma = [-1] + lognormal = np.random.lognormal + desired = np.array([9.1422086044848427, + 8.4013952870126261, + 6.3073234116578671]) + + self.setSeed() + actual = lognormal(mean * 3, sigma) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, lognormal, mean * 3, bad_sigma) + + self.setSeed() + actual = lognormal(mean, sigma * 3) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, lognormal, mean, bad_sigma * 3) + + def test_rayleigh(self): + scale = [1] + bad_scale = [-1] + rayleigh = np.random.rayleigh + desired = np.array([1.2337491937897689, + 1.2360119924878694, + 1.1936818095781789]) + + self.setSeed() + actual = rayleigh(scale * 3) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, rayleigh, bad_scale * 3) + + def test_wald(self): + mean = [0.5] + scale = [1] + bad_mean = [0] + bad_scale = [-2] + wald = np.random.wald + desired = np.array([0.11873681120271318, + 0.12450084820795027, + 0.9096122728408238]) + + self.setSeed() + actual = wald(mean * 3, scale) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, wald, bad_mean * 3, scale) + assert_raises(ValueError, wald, mean * 3, bad_scale) + + self.setSeed() + actual = wald(mean, scale * 3) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, wald, bad_mean, scale * 3) + assert_raises(ValueError, wald, mean, bad_scale * 3) + assert_raises(ValueError, wald, 0.0, 1) + assert_raises(ValueError, wald, 0.5, 0.0) + + def test_triangular(self): + left = [1] + right = [3] + mode = [2] + bad_left_one = [3] + bad_mode_one = [4] + bad_left_two, bad_mode_two = right * 2 + triangular = np.random.triangular + desired = np.array([2.03339048710429, + 2.0347400359389356, + 2.0095991069536208]) + + self.setSeed() + actual = triangular(left * 3, mode, right) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, triangular, bad_left_one * 3, mode, right) + assert_raises(ValueError, triangular, left * 3, bad_mode_one, right) + assert_raises(ValueError, triangular, bad_left_two * 3, bad_mode_two, + right) + + self.setSeed() + actual = triangular(left, mode * 3, right) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, triangular, bad_left_one, mode * 3, right) + assert_raises(ValueError, triangular, left, bad_mode_one * 3, right) + assert_raises(ValueError, triangular, bad_left_two, bad_mode_two * 3, + right) + + self.setSeed() + actual = triangular(left, mode, right * 3) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, triangular, bad_left_one, mode, right * 3) + assert_raises(ValueError, triangular, left, bad_mode_one, right * 3) + assert_raises(ValueError, triangular, bad_left_two, bad_mode_two, + right * 3) + + def test_binomial(self): + n = [1] + p = [0.5] + bad_n = [-1] + bad_p_one = [-1] + bad_p_two = [1.5] + binom = np.random.binomial + desired = np.array([1, 1, 1]) + + self.setSeed() + actual = binom(n * 3, p) + assert_array_equal(actual, desired) + assert_raises(ValueError, binom, bad_n * 3, p) + assert_raises(ValueError, binom, n * 3, bad_p_one) + assert_raises(ValueError, binom, n * 3, bad_p_two) + + self.setSeed() + actual = binom(n, p * 3) + assert_array_equal(actual, desired) + assert_raises(ValueError, binom, bad_n, p * 3) + assert_raises(ValueError, binom, n, bad_p_one * 3) + assert_raises(ValueError, binom, n, bad_p_two * 3) + + def test_negative_binomial(self): + n = [1] + p = [0.5] + bad_n = [-1] + bad_p_one = [-1] + bad_p_two = [1.5] + neg_binom = np.random.negative_binomial + desired = np.array([1, 0, 1]) + + self.setSeed() + actual = neg_binom(n * 3, p) + assert_array_equal(actual, desired) + assert_raises(ValueError, neg_binom, bad_n * 3, p) + assert_raises(ValueError, neg_binom, n * 3, bad_p_one) + assert_raises(ValueError, neg_binom, n * 3, bad_p_two) + + self.setSeed() + actual = neg_binom(n, p * 3) + assert_array_equal(actual, desired) + assert_raises(ValueError, neg_binom, bad_n, p * 3) + assert_raises(ValueError, neg_binom, n, bad_p_one * 3) + assert_raises(ValueError, neg_binom, n, bad_p_two * 3) + + def test_poisson(self): + max_lam = np.random.RandomState()._poisson_lam_max + + lam = [1] + bad_lam_one = [-1] + bad_lam_two = [max_lam * 2] + poisson = np.random.poisson + desired = np.array([1, 1, 0]) + + self.setSeed() + actual = poisson(lam * 3) + assert_array_equal(actual, desired) + assert_raises(ValueError, poisson, bad_lam_one * 3) + assert_raises(ValueError, poisson, bad_lam_two * 3) + + def test_zipf(self): + a = [2] + bad_a = [0] + zipf = np.random.zipf + desired = np.array([2, 2, 1]) + + self.setSeed() + actual = zipf(a * 3) + assert_array_equal(actual, desired) + assert_raises(ValueError, zipf, bad_a * 3) + with np.errstate(invalid='ignore'): + assert_raises(ValueError, zipf, np.nan) + assert_raises(ValueError, zipf, [0, 0, np.nan]) + + def test_geometric(self): + p = [0.5] + bad_p_one = [-1] + bad_p_two = [1.5] + geom = np.random.geometric + desired = np.array([2, 2, 2]) + + self.setSeed() + actual = geom(p * 3) + assert_array_equal(actual, desired) + assert_raises(ValueError, geom, bad_p_one * 3) + assert_raises(ValueError, geom, bad_p_two * 3) + + def test_hypergeometric(self): + ngood = [1] + nbad = [2] + nsample = [2] + bad_ngood = [-1] + bad_nbad = [-2] + bad_nsample_one = [0] + bad_nsample_two = [4] + hypergeom = np.random.hypergeometric + desired = np.array([1, 1, 1]) + + self.setSeed() + actual = hypergeom(ngood * 3, nbad, nsample) + assert_array_equal(actual, desired) + assert_raises(ValueError, hypergeom, bad_ngood * 3, nbad, nsample) + assert_raises(ValueError, hypergeom, ngood * 3, bad_nbad, nsample) + assert_raises(ValueError, hypergeom, ngood * 3, nbad, bad_nsample_one) + assert_raises(ValueError, hypergeom, ngood * 3, nbad, bad_nsample_two) + + self.setSeed() + actual = hypergeom(ngood, nbad * 3, nsample) + assert_array_equal(actual, desired) + assert_raises(ValueError, hypergeom, bad_ngood, nbad * 3, nsample) + assert_raises(ValueError, hypergeom, ngood, bad_nbad * 3, nsample) + assert_raises(ValueError, hypergeom, ngood, nbad * 3, bad_nsample_one) + assert_raises(ValueError, hypergeom, ngood, nbad * 3, bad_nsample_two) + + self.setSeed() + actual = hypergeom(ngood, nbad, nsample * 3) + assert_array_equal(actual, desired) + assert_raises(ValueError, hypergeom, bad_ngood, nbad, nsample * 3) + assert_raises(ValueError, hypergeom, ngood, bad_nbad, nsample * 3) + assert_raises(ValueError, hypergeom, ngood, nbad, bad_nsample_one * 3) + assert_raises(ValueError, hypergeom, ngood, nbad, bad_nsample_two * 3) + + def test_logseries(self): + p = [0.5] + bad_p_one = [2] + bad_p_two = [-1] + logseries = np.random.logseries + desired = np.array([1, 1, 1]) + + self.setSeed() + actual = logseries(p * 3) + assert_array_equal(actual, desired) + assert_raises(ValueError, logseries, bad_p_one * 3) + assert_raises(ValueError, logseries, bad_p_two * 3) + + +class TestThread: + # make sure each state produces the same sequence even in threads + def setup(self): + self.seeds = range(4) + + def check_function(self, function, sz): + from threading import Thread + + out1 = np.empty((len(self.seeds),) + sz) + out2 = np.empty((len(self.seeds),) + sz) + + # threaded generation + t = [Thread(target=function, args=(np.random.RandomState(s), o)) + for s, o in zip(self.seeds, out1)] + [x.start() for x in t] + [x.join() for x in t] + + # the same serial + for s, o in zip(self.seeds, out2): + function(np.random.RandomState(s), o) + + # these platforms change x87 fpu precision mode in threads + if np.intp().dtype.itemsize == 4 and sys.platform == "win32": + assert_array_almost_equal(out1, out2) + else: + assert_array_equal(out1, out2) + + def test_normal(self): + def gen_random(state, out): + out[...] = state.normal(size=10000) + self.check_function(gen_random, sz=(10000,)) + + def test_exp(self): + def gen_random(state, out): + out[...] = state.exponential(scale=np.ones((100, 1000))) + self.check_function(gen_random, sz=(100, 1000)) + + def test_multinomial(self): + def gen_random(state, out): + out[...] = state.multinomial(10, [1/6.]*6, size=10000) + self.check_function(gen_random, sz=(10000, 6)) + + +# See Issue #4263 +class TestSingleEltArrayInput: + def setup(self): + self.argOne = np.array([2]) + self.argTwo = np.array([3]) + self.argThree = np.array([4]) + self.tgtShape = (1,) + + def test_one_arg_funcs(self): + funcs = (np.random.exponential, np.random.standard_gamma, + np.random.chisquare, np.random.standard_t, + np.random.pareto, np.random.weibull, + np.random.power, np.random.rayleigh, + np.random.poisson, np.random.zipf, + np.random.geometric, np.random.logseries) + + probfuncs = (np.random.geometric, np.random.logseries) + + for func in funcs: + if func in probfuncs: # p < 1.0 + out = func(np.array([0.5])) + + else: + out = func(self.argOne) + + assert_equal(out.shape, self.tgtShape) + + def test_two_arg_funcs(self): + funcs = (np.random.uniform, np.random.normal, + np.random.beta, np.random.gamma, + np.random.f, np.random.noncentral_chisquare, + np.random.vonmises, np.random.laplace, + np.random.gumbel, np.random.logistic, + np.random.lognormal, np.random.wald, + np.random.binomial, np.random.negative_binomial) + + probfuncs = (np.random.binomial, np.random.negative_binomial) + + for func in funcs: + if func in probfuncs: # p <= 1 + argTwo = np.array([0.5]) + + else: + argTwo = self.argTwo + + out = func(self.argOne, argTwo) + assert_equal(out.shape, self.tgtShape) + + out = func(self.argOne[0], argTwo) + assert_equal(out.shape, self.tgtShape) + + out = func(self.argOne, argTwo[0]) + assert_equal(out.shape, self.tgtShape) + +# TODO: Uncomment once randint can broadcast arguments +# def test_randint(self): +# itype = [bool, np.int8, np.uint8, np.int16, np.uint16, +# np.int32, np.uint32, np.int64, np.uint64] +# func = np.random.randint +# high = np.array([1]) +# low = np.array([0]) +# +# for dt in itype: +# out = func(low, high, dtype=dt) +# self.assert_equal(out.shape, self.tgtShape) +# +# out = func(low[0], high, dtype=dt) +# self.assert_equal(out.shape, self.tgtShape) +# +# out = func(low, high[0], dtype=dt) +# self.assert_equal(out.shape, self.tgtShape) + + def test_three_arg_funcs(self): + funcs = [np.random.noncentral_f, np.random.triangular, + np.random.hypergeometric] + + for func in funcs: + out = func(self.argOne, self.argTwo, self.argThree) + assert_equal(out.shape, self.tgtShape) + + out = func(self.argOne[0], self.argTwo, self.argThree) + assert_equal(out.shape, self.tgtShape) + + out = func(self.argOne, self.argTwo[0], self.argThree) + assert_equal(out.shape, self.tgtShape) diff --git a/venv/Lib/site-packages/numpy/random/tests/test_randomstate.py b/venv/Lib/site-packages/numpy/random/tests/test_randomstate.py new file mode 100644 index 0000000..7f5f080 --- /dev/null +++ b/venv/Lib/site-packages/numpy/random/tests/test_randomstate.py @@ -0,0 +1,2005 @@ +import hashlib +import pickle +import sys +import warnings + +import numpy as np +import pytest +from numpy.testing import ( + assert_, assert_raises, assert_equal, assert_warns, + assert_no_warnings, assert_array_equal, assert_array_almost_equal, + suppress_warnings + ) + +from numpy.random import MT19937, PCG64 +from numpy import random + +INT_FUNCS = {'binomial': (100.0, 0.6), + 'geometric': (.5,), + 'hypergeometric': (20, 20, 10), + 'logseries': (.5,), + 'multinomial': (20, np.ones(6) / 6.0), + 'negative_binomial': (100, .5), + 'poisson': (10.0,), + 'zipf': (2,), + } + +if np.iinfo(int).max < 2**32: + # Windows and some 32-bit platforms, e.g., ARM + INT_FUNC_HASHES = {'binomial': '2fbead005fc63942decb5326d36a1f32fe2c9d32c904ee61e46866b88447c263', + 'logseries': '23ead5dcde35d4cfd4ef2c105e4c3d43304b45dc1b1444b7823b9ee4fa144ebb', + 'geometric': '0d764db64f5c3bad48c8c33551c13b4d07a1e7b470f77629bef6c985cac76fcf', + 'hypergeometric': '7b59bf2f1691626c5815cdcd9a49e1dd68697251d4521575219e4d2a1b8b2c67', + 'multinomial': 'd754fa5b92943a38ec07630de92362dd2e02c43577fc147417dc5b9db94ccdd3', + 'negative_binomial': '8eb216f7cb2a63cf55605422845caaff002fddc64a7dc8b2d45acd477a49e824', + 'poisson': '70c891d76104013ebd6f6bcf30d403a9074b886ff62e4e6b8eb605bf1a4673b7', + 'zipf': '01f074f97517cd5d21747148ac6ca4074dde7fcb7acbaec0a936606fecacd93f', + } +else: + INT_FUNC_HASHES = {'binomial': '8626dd9d052cb608e93d8868de0a7b347258b199493871a1dc56e2a26cacb112', + 'geometric': '8edd53d272e49c4fc8fbbe6c7d08d563d62e482921f3131d0a0e068af30f0db9', + 'hypergeometric': '83496cc4281c77b786c9b7ad88b74d42e01603a55c60577ebab81c3ba8d45657', + 'logseries': '65878a38747c176bc00e930ebafebb69d4e1e16cd3a704e264ea8f5e24f548db', + 'multinomial': '7a984ae6dca26fd25374479e118b22f55db0aedccd5a0f2584ceada33db98605', + 'negative_binomial': 'd636d968e6a24ae92ab52fe11c46ac45b0897e98714426764e820a7d77602a61', + 'poisson': '956552176f77e7c9cb20d0118fc9cf690be488d790ed4b4c4747b965e61b0bb4', + 'zipf': 'f84ba7feffda41e606e20b28dfc0f1ea9964a74574513d4a4cbc98433a8bfa45', + } + + +@pytest.fixture(scope='module', params=INT_FUNCS) +def int_func(request): + return (request.param, INT_FUNCS[request.param], + INT_FUNC_HASHES[request.param]) + + +def assert_mt19937_state_equal(a, b): + assert_equal(a['bit_generator'], b['bit_generator']) + assert_array_equal(a['state']['key'], b['state']['key']) + assert_array_equal(a['state']['pos'], b['state']['pos']) + assert_equal(a['has_gauss'], b['has_gauss']) + assert_equal(a['gauss'], b['gauss']) + + +class TestSeed: + def test_scalar(self): + s = random.RandomState(0) + assert_equal(s.randint(1000), 684) + s = random.RandomState(4294967295) + assert_equal(s.randint(1000), 419) + + def test_array(self): + s = random.RandomState(range(10)) + assert_equal(s.randint(1000), 468) + s = random.RandomState(np.arange(10)) + assert_equal(s.randint(1000), 468) + s = random.RandomState([0]) + assert_equal(s.randint(1000), 973) + s = random.RandomState([4294967295]) + assert_equal(s.randint(1000), 265) + + def test_invalid_scalar(self): + # seed must be an unsigned 32 bit integer + assert_raises(TypeError, random.RandomState, -0.5) + assert_raises(ValueError, random.RandomState, -1) + + def test_invalid_array(self): + # seed must be an unsigned 32 bit integer + assert_raises(TypeError, random.RandomState, [-0.5]) + assert_raises(ValueError, random.RandomState, [-1]) + assert_raises(ValueError, random.RandomState, [4294967296]) + assert_raises(ValueError, random.RandomState, [1, 2, 4294967296]) + assert_raises(ValueError, random.RandomState, [1, -2, 4294967296]) + + def test_invalid_array_shape(self): + # gh-9832 + assert_raises(ValueError, random.RandomState, np.array([], + dtype=np.int64)) + assert_raises(ValueError, random.RandomState, [[1, 2, 3]]) + assert_raises(ValueError, random.RandomState, [[1, 2, 3], + [4, 5, 6]]) + + def test_cannot_seed(self): + rs = random.RandomState(PCG64(0)) + with assert_raises(TypeError): + rs.seed(1234) + + def test_invalid_initialization(self): + assert_raises(ValueError, random.RandomState, MT19937) + + +class TestBinomial: + def test_n_zero(self): + # Tests the corner case of n == 0 for the binomial distribution. + # binomial(0, p) should be zero for any p in [0, 1]. + # This test addresses issue #3480. + zeros = np.zeros(2, dtype='int') + for p in [0, .5, 1]: + assert_(random.binomial(0, p) == 0) + assert_array_equal(random.binomial(zeros, p), zeros) + + def test_p_is_nan(self): + # Issue #4571. + assert_raises(ValueError, random.binomial, 1, np.nan) + + +class TestMultinomial: + def test_basic(self): + random.multinomial(100, [0.2, 0.8]) + + def test_zero_probability(self): + random.multinomial(100, [0.2, 0.8, 0.0, 0.0, 0.0]) + + def test_int_negative_interval(self): + assert_(-5 <= random.randint(-5, -1) < -1) + x = random.randint(-5, -1, 5) + assert_(np.all(-5 <= x)) + assert_(np.all(x < -1)) + + def test_size(self): + # gh-3173 + p = [0.5, 0.5] + assert_equal(random.multinomial(1, p, np.uint32(1)).shape, (1, 2)) + assert_equal(random.multinomial(1, p, np.uint32(1)).shape, (1, 2)) + assert_equal(random.multinomial(1, p, np.uint32(1)).shape, (1, 2)) + assert_equal(random.multinomial(1, p, [2, 2]).shape, (2, 2, 2)) + assert_equal(random.multinomial(1, p, (2, 2)).shape, (2, 2, 2)) + assert_equal(random.multinomial(1, p, np.array((2, 2))).shape, + (2, 2, 2)) + + assert_raises(TypeError, random.multinomial, 1, p, + float(1)) + + def test_invalid_prob(self): + assert_raises(ValueError, random.multinomial, 100, [1.1, 0.2]) + assert_raises(ValueError, random.multinomial, 100, [-.1, 0.9]) + + def test_invalid_n(self): + assert_raises(ValueError, random.multinomial, -1, [0.8, 0.2]) + + def test_p_non_contiguous(self): + p = np.arange(15.) + p /= np.sum(p[1::3]) + pvals = p[1::3] + random.seed(1432985819) + non_contig = random.multinomial(100, pvals=pvals) + random.seed(1432985819) + contig = random.multinomial(100, pvals=np.ascontiguousarray(pvals)) + assert_array_equal(non_contig, contig) + + +class TestSetState: + def setup(self): + self.seed = 1234567890 + self.random_state = random.RandomState(self.seed) + self.state = self.random_state.get_state() + + def test_basic(self): + old = self.random_state.tomaxint(16) + self.random_state.set_state(self.state) + new = self.random_state.tomaxint(16) + assert_(np.all(old == new)) + + def test_gaussian_reset(self): + # Make sure the cached every-other-Gaussian is reset. + old = self.random_state.standard_normal(size=3) + self.random_state.set_state(self.state) + new = self.random_state.standard_normal(size=3) + assert_(np.all(old == new)) + + def test_gaussian_reset_in_media_res(self): + # When the state is saved with a cached Gaussian, make sure the + # cached Gaussian is restored. + + self.random_state.standard_normal() + state = self.random_state.get_state() + old = self.random_state.standard_normal(size=3) + self.random_state.set_state(state) + new = self.random_state.standard_normal(size=3) + assert_(np.all(old == new)) + + def test_backwards_compatibility(self): + # Make sure we can accept old state tuples that do not have the + # cached Gaussian value. + old_state = self.state[:-2] + x1 = self.random_state.standard_normal(size=16) + self.random_state.set_state(old_state) + x2 = self.random_state.standard_normal(size=16) + self.random_state.set_state(self.state) + x3 = self.random_state.standard_normal(size=16) + assert_(np.all(x1 == x2)) + assert_(np.all(x1 == x3)) + + def test_negative_binomial(self): + # Ensure that the negative binomial results take floating point + # arguments without truncation. + self.random_state.negative_binomial(0.5, 0.5) + + def test_get_state_warning(self): + rs = random.RandomState(PCG64()) + with suppress_warnings() as sup: + w = sup.record(RuntimeWarning) + state = rs.get_state() + assert_(len(w) == 1) + assert isinstance(state, dict) + assert state['bit_generator'] == 'PCG64' + + def test_invalid_legacy_state_setting(self): + state = self.random_state.get_state() + new_state = ('Unknown', ) + state[1:] + assert_raises(ValueError, self.random_state.set_state, new_state) + assert_raises(TypeError, self.random_state.set_state, + np.array(new_state, dtype=object)) + state = self.random_state.get_state(legacy=False) + del state['bit_generator'] + assert_raises(ValueError, self.random_state.set_state, state) + + def test_pickle(self): + self.random_state.seed(0) + self.random_state.random_sample(100) + self.random_state.standard_normal() + pickled = self.random_state.get_state(legacy=False) + assert_equal(pickled['has_gauss'], 1) + rs_unpick = pickle.loads(pickle.dumps(self.random_state)) + unpickled = rs_unpick.get_state(legacy=False) + assert_mt19937_state_equal(pickled, unpickled) + + def test_state_setting(self): + attr_state = self.random_state.__getstate__() + self.random_state.standard_normal() + self.random_state.__setstate__(attr_state) + state = self.random_state.get_state(legacy=False) + assert_mt19937_state_equal(attr_state, state) + + def test_repr(self): + assert repr(self.random_state).startswith('RandomState(MT19937)') + + +class TestRandint: + + rfunc = random.randint + + # valid integer/boolean types + itype = [np.bool_, np.int8, np.uint8, np.int16, np.uint16, + np.int32, np.uint32, np.int64, np.uint64] + + def test_unsupported_type(self): + assert_raises(TypeError, self.rfunc, 1, dtype=float) + + def test_bounds_checking(self): + for dt in self.itype: + lbnd = 0 if dt is np.bool_ else np.iinfo(dt).min + ubnd = 2 if dt is np.bool_ else np.iinfo(dt).max + 1 + assert_raises(ValueError, self.rfunc, lbnd - 1, ubnd, dtype=dt) + assert_raises(ValueError, self.rfunc, lbnd, ubnd + 1, dtype=dt) + assert_raises(ValueError, self.rfunc, ubnd, lbnd, dtype=dt) + assert_raises(ValueError, self.rfunc, 1, 0, dtype=dt) + + def test_rng_zero_and_extremes(self): + for dt in self.itype: + lbnd = 0 if dt is np.bool_ else np.iinfo(dt).min + ubnd = 2 if dt is np.bool_ else np.iinfo(dt).max + 1 + + tgt = ubnd - 1 + assert_equal(self.rfunc(tgt, tgt + 1, size=1000, dtype=dt), tgt) + + tgt = lbnd + assert_equal(self.rfunc(tgt, tgt + 1, size=1000, dtype=dt), tgt) + + tgt = (lbnd + ubnd)//2 + assert_equal(self.rfunc(tgt, tgt + 1, size=1000, dtype=dt), tgt) + + def test_full_range(self): + # Test for ticket #1690 + + for dt in self.itype: + lbnd = 0 if dt is np.bool_ else np.iinfo(dt).min + ubnd = 2 if dt is np.bool_ else np.iinfo(dt).max + 1 + + try: + self.rfunc(lbnd, ubnd, dtype=dt) + except Exception as e: + raise AssertionError("No error should have been raised, " + "but one was with the following " + "message:\n\n%s" % str(e)) + + def test_in_bounds_fuzz(self): + # Don't use fixed seed + random.seed() + + for dt in self.itype[1:]: + for ubnd in [4, 8, 16]: + vals = self.rfunc(2, ubnd, size=2**16, dtype=dt) + assert_(vals.max() < ubnd) + assert_(vals.min() >= 2) + + vals = self.rfunc(0, 2, size=2**16, dtype=np.bool_) + + assert_(vals.max() < 2) + assert_(vals.min() >= 0) + + def test_repeatability(self): + # We use a sha256 hash of generated sequences of 1000 samples + # in the range [0, 6) for all but bool, where the range + # is [0, 2). Hashes are for little endian numbers. + tgt = {'bool': '509aea74d792fb931784c4b0135392c65aec64beee12b0cc167548a2c3d31e71', + 'int16': '7b07f1a920e46f6d0fe02314155a2330bcfd7635e708da50e536c5ebb631a7d4', + 'int32': 'e577bfed6c935de944424667e3da285012e741892dcb7051a8f1ce68ab05c92f', + 'int64': '0fbead0b06759df2cfb55e43148822d4a1ff953c7eb19a5b08445a63bb64fa9e', + 'int8': '001aac3a5acb935a9b186cbe14a1ca064b8bb2dd0b045d48abeacf74d0203404', + 'uint16': '7b07f1a920e46f6d0fe02314155a2330bcfd7635e708da50e536c5ebb631a7d4', + 'uint32': 'e577bfed6c935de944424667e3da285012e741892dcb7051a8f1ce68ab05c92f', + 'uint64': '0fbead0b06759df2cfb55e43148822d4a1ff953c7eb19a5b08445a63bb64fa9e', + 'uint8': '001aac3a5acb935a9b186cbe14a1ca064b8bb2dd0b045d48abeacf74d0203404'} + + for dt in self.itype[1:]: + random.seed(1234) + + # view as little endian for hash + if sys.byteorder == 'little': + val = self.rfunc(0, 6, size=1000, dtype=dt) + else: + val = self.rfunc(0, 6, size=1000, dtype=dt).byteswap() + + res = hashlib.sha256(val.view(np.int8)).hexdigest() + assert_(tgt[np.dtype(dt).name] == res) + + # bools do not depend on endianness + random.seed(1234) + val = self.rfunc(0, 2, size=1000, dtype=bool).view(np.int8) + res = hashlib.sha256(val).hexdigest() + assert_(tgt[np.dtype(bool).name] == res) + + @pytest.mark.skipif(np.iinfo('l').max < 2**32, + reason='Cannot test with 32-bit C long') + def test_repeatability_32bit_boundary_broadcasting(self): + desired = np.array([[[3992670689, 2438360420, 2557845020], + [4107320065, 4142558326, 3216529513], + [1605979228, 2807061240, 665605495]], + [[3211410639, 4128781000, 457175120], + [1712592594, 1282922662, 3081439808], + [3997822960, 2008322436, 1563495165]], + [[1398375547, 4269260146, 115316740], + [3414372578, 3437564012, 2112038651], + [3572980305, 2260248732, 3908238631]], + [[2561372503, 223155946, 3127879445], + [ 441282060, 3514786552, 2148440361], + [1629275283, 3479737011, 3003195987]], + [[ 412181688, 940383289, 3047321305], + [2978368172, 764731833, 2282559898], + [ 105711276, 720447391, 3596512484]]]) + for size in [None, (5, 3, 3)]: + random.seed(12345) + x = self.rfunc([[-1], [0], [1]], [2**32 - 1, 2**32, 2**32 + 1], + size=size) + assert_array_equal(x, desired if size is not None else desired[0]) + + def test_int64_uint64_corner_case(self): + # When stored in Numpy arrays, `lbnd` is casted + # as np.int64, and `ubnd` is casted as np.uint64. + # Checking whether `lbnd` >= `ubnd` used to be + # done solely via direct comparison, which is incorrect + # because when Numpy tries to compare both numbers, + # it casts both to np.float64 because there is + # no integer superset of np.int64 and np.uint64. However, + # `ubnd` is too large to be represented in np.float64, + # causing it be round down to np.iinfo(np.int64).max, + # leading to a ValueError because `lbnd` now equals + # the new `ubnd`. + + dt = np.int64 + tgt = np.iinfo(np.int64).max + lbnd = np.int64(np.iinfo(np.int64).max) + ubnd = np.uint64(np.iinfo(np.int64).max + 1) + + # None of these function calls should + # generate a ValueError now. + actual = random.randint(lbnd, ubnd, dtype=dt) + assert_equal(actual, tgt) + + def test_respect_dtype_singleton(self): + # See gh-7203 + for dt in self.itype: + lbnd = 0 if dt is np.bool_ else np.iinfo(dt).min + ubnd = 2 if dt is np.bool_ else np.iinfo(dt).max + 1 + + sample = self.rfunc(lbnd, ubnd, dtype=dt) + assert_equal(sample.dtype, np.dtype(dt)) + + for dt in (bool, int, np.compat.long): + lbnd = 0 if dt is bool else np.iinfo(dt).min + ubnd = 2 if dt is bool else np.iinfo(dt).max + 1 + + # gh-7284: Ensure that we get Python data types + sample = self.rfunc(lbnd, ubnd, dtype=dt) + assert_(not hasattr(sample, 'dtype')) + assert_equal(type(sample), dt) + + +class TestRandomDist: + # Make sure the random distribution returns the correct value for a + # given seed + + def setup(self): + self.seed = 1234567890 + + def test_rand(self): + random.seed(self.seed) + actual = random.rand(3, 2) + desired = np.array([[0.61879477158567997, 0.59162362775974664], + [0.88868358904449662, 0.89165480011560816], + [0.4575674820298663, 0.7781880808593471]]) + assert_array_almost_equal(actual, desired, decimal=15) + + def test_rand_singleton(self): + random.seed(self.seed) + actual = random.rand() + desired = 0.61879477158567997 + assert_array_almost_equal(actual, desired, decimal=15) + + def test_randn(self): + random.seed(self.seed) + actual = random.randn(3, 2) + desired = np.array([[1.34016345771863121, 1.73759122771936081], + [1.498988344300628, -0.2286433324536169], + [2.031033998682787, 2.17032494605655257]]) + assert_array_almost_equal(actual, desired, decimal=15) + + random.seed(self.seed) + actual = random.randn() + assert_array_almost_equal(actual, desired[0, 0], decimal=15) + + def test_randint(self): + random.seed(self.seed) + actual = random.randint(-99, 99, size=(3, 2)) + desired = np.array([[31, 3], + [-52, 41], + [-48, -66]]) + assert_array_equal(actual, desired) + + def test_random_integers(self): + random.seed(self.seed) + with suppress_warnings() as sup: + w = sup.record(DeprecationWarning) + actual = random.random_integers(-99, 99, size=(3, 2)) + assert_(len(w) == 1) + desired = np.array([[31, 3], + [-52, 41], + [-48, -66]]) + assert_array_equal(actual, desired) + + random.seed(self.seed) + with suppress_warnings() as sup: + w = sup.record(DeprecationWarning) + actual = random.random_integers(198, size=(3, 2)) + assert_(len(w) == 1) + assert_array_equal(actual, desired + 100) + + def test_tomaxint(self): + random.seed(self.seed) + rs = random.RandomState(self.seed) + actual = rs.tomaxint(size=(3, 2)) + if np.iinfo(int).max == 2147483647: + desired = np.array([[1328851649, 731237375], + [1270502067, 320041495], + [1908433478, 499156889]], dtype=np.int64) + else: + desired = np.array([[5707374374421908479, 5456764827585442327], + [8196659375100692377, 8224063923314595285], + [4220315081820346526, 7177518203184491332]], + dtype=np.int64) + + assert_equal(actual, desired) + + rs.seed(self.seed) + actual = rs.tomaxint() + assert_equal(actual, desired[0, 0]) + + def test_random_integers_max_int(self): + # Tests whether random_integers can generate the + # maximum allowed Python int that can be converted + # into a C long. Previous implementations of this + # method have thrown an OverflowError when attempting + # to generate this integer. + with suppress_warnings() as sup: + w = sup.record(DeprecationWarning) + actual = random.random_integers(np.iinfo('l').max, + np.iinfo('l').max) + assert_(len(w) == 1) + + desired = np.iinfo('l').max + assert_equal(actual, desired) + with suppress_warnings() as sup: + w = sup.record(DeprecationWarning) + typer = np.dtype('l').type + actual = random.random_integers(typer(np.iinfo('l').max), + typer(np.iinfo('l').max)) + assert_(len(w) == 1) + assert_equal(actual, desired) + + def test_random_integers_deprecated(self): + with warnings.catch_warnings(): + warnings.simplefilter("error", DeprecationWarning) + + # DeprecationWarning raised with high == None + assert_raises(DeprecationWarning, + random.random_integers, + np.iinfo('l').max) + + # DeprecationWarning raised with high != None + assert_raises(DeprecationWarning, + random.random_integers, + np.iinfo('l').max, np.iinfo('l').max) + + def test_random_sample(self): + random.seed(self.seed) + actual = random.random_sample((3, 2)) + desired = np.array([[0.61879477158567997, 0.59162362775974664], + [0.88868358904449662, 0.89165480011560816], + [0.4575674820298663, 0.7781880808593471]]) + assert_array_almost_equal(actual, desired, decimal=15) + + random.seed(self.seed) + actual = random.random_sample() + assert_array_almost_equal(actual, desired[0, 0], decimal=15) + + def test_choice_uniform_replace(self): + random.seed(self.seed) + actual = random.choice(4, 4) + desired = np.array([2, 3, 2, 3]) + assert_array_equal(actual, desired) + + def test_choice_nonuniform_replace(self): + random.seed(self.seed) + actual = random.choice(4, 4, p=[0.4, 0.4, 0.1, 0.1]) + desired = np.array([1, 1, 2, 2]) + assert_array_equal(actual, desired) + + def test_choice_uniform_noreplace(self): + random.seed(self.seed) + actual = random.choice(4, 3, replace=False) + desired = np.array([0, 1, 3]) + assert_array_equal(actual, desired) + + def test_choice_nonuniform_noreplace(self): + random.seed(self.seed) + actual = random.choice(4, 3, replace=False, p=[0.1, 0.3, 0.5, 0.1]) + desired = np.array([2, 3, 1]) + assert_array_equal(actual, desired) + + def test_choice_noninteger(self): + random.seed(self.seed) + actual = random.choice(['a', 'b', 'c', 'd'], 4) + desired = np.array(['c', 'd', 'c', 'd']) + assert_array_equal(actual, desired) + + def test_choice_exceptions(self): + sample = random.choice + assert_raises(ValueError, sample, -1, 3) + assert_raises(ValueError, sample, 3., 3) + assert_raises(ValueError, sample, [[1, 2], [3, 4]], 3) + assert_raises(ValueError, sample, [], 3) + assert_raises(ValueError, sample, [1, 2, 3, 4], 3, + p=[[0.25, 0.25], [0.25, 0.25]]) + assert_raises(ValueError, sample, [1, 2], 3, p=[0.4, 0.4, 0.2]) + assert_raises(ValueError, sample, [1, 2], 3, p=[1.1, -0.1]) + assert_raises(ValueError, sample, [1, 2], 3, p=[0.4, 0.4]) + assert_raises(ValueError, sample, [1, 2, 3], 4, replace=False) + # gh-13087 + assert_raises(ValueError, sample, [1, 2, 3], -2, replace=False) + assert_raises(ValueError, sample, [1, 2, 3], (-1,), replace=False) + assert_raises(ValueError, sample, [1, 2, 3], (-1, 1), replace=False) + assert_raises(ValueError, sample, [1, 2, 3], 2, + replace=False, p=[1, 0, 0]) + + def test_choice_return_shape(self): + p = [0.1, 0.9] + # Check scalar + assert_(np.isscalar(random.choice(2, replace=True))) + assert_(np.isscalar(random.choice(2, replace=False))) + assert_(np.isscalar(random.choice(2, replace=True, p=p))) + assert_(np.isscalar(random.choice(2, replace=False, p=p))) + assert_(np.isscalar(random.choice([1, 2], replace=True))) + assert_(random.choice([None], replace=True) is None) + a = np.array([1, 2]) + arr = np.empty(1, dtype=object) + arr[0] = a + assert_(random.choice(arr, replace=True) is a) + + # Check 0-d array + s = tuple() + assert_(not np.isscalar(random.choice(2, s, replace=True))) + assert_(not np.isscalar(random.choice(2, s, replace=False))) + assert_(not np.isscalar(random.choice(2, s, replace=True, p=p))) + assert_(not np.isscalar(random.choice(2, s, replace=False, p=p))) + assert_(not np.isscalar(random.choice([1, 2], s, replace=True))) + assert_(random.choice([None], s, replace=True).ndim == 0) + a = np.array([1, 2]) + arr = np.empty(1, dtype=object) + arr[0] = a + assert_(random.choice(arr, s, replace=True).item() is a) + + # Check multi dimensional array + s = (2, 3) + p = [0.1, 0.1, 0.1, 0.1, 0.4, 0.2] + assert_equal(random.choice(6, s, replace=True).shape, s) + assert_equal(random.choice(6, s, replace=False).shape, s) + assert_equal(random.choice(6, s, replace=True, p=p).shape, s) + assert_equal(random.choice(6, s, replace=False, p=p).shape, s) + assert_equal(random.choice(np.arange(6), s, replace=True).shape, s) + + # Check zero-size + assert_equal(random.randint(0, 0, size=(3, 0, 4)).shape, (3, 0, 4)) + assert_equal(random.randint(0, -10, size=0).shape, (0,)) + assert_equal(random.randint(10, 10, size=0).shape, (0,)) + assert_equal(random.choice(0, size=0).shape, (0,)) + assert_equal(random.choice([], size=(0,)).shape, (0,)) + assert_equal(random.choice(['a', 'b'], size=(3, 0, 4)).shape, + (3, 0, 4)) + assert_raises(ValueError, random.choice, [], 10) + + def test_choice_nan_probabilities(self): + a = np.array([42, 1, 2]) + p = [None, None, None] + assert_raises(ValueError, random.choice, a, p=p) + + def test_choice_p_non_contiguous(self): + p = np.ones(10) / 5 + p[1::2] = 3.0 + random.seed(self.seed) + non_contig = random.choice(5, 3, p=p[::2]) + random.seed(self.seed) + contig = random.choice(5, 3, p=np.ascontiguousarray(p[::2])) + assert_array_equal(non_contig, contig) + + def test_bytes(self): + random.seed(self.seed) + actual = random.bytes(10) + desired = b'\x82Ui\x9e\xff\x97+Wf\xa5' + assert_equal(actual, desired) + + def test_shuffle(self): + # Test lists, arrays (of various dtypes), and multidimensional versions + # of both, c-contiguous or not: + for conv in [lambda x: np.array([]), + lambda x: x, + lambda x: np.asarray(x).astype(np.int8), + lambda x: np.asarray(x).astype(np.float32), + lambda x: np.asarray(x).astype(np.complex64), + lambda x: np.asarray(x).astype(object), + lambda x: [(i, i) for i in x], + lambda x: np.asarray([[i, i] for i in x]), + lambda x: np.vstack([x, x]).T, + # gh-11442 + lambda x: (np.asarray([(i, i) for i in x], + [("a", int), ("b", int)]) + .view(np.recarray)), + # gh-4270 + lambda x: np.asarray([(i, i) for i in x], + [("a", object, (1,)), + ("b", np.int32, (1,))])]: + random.seed(self.seed) + alist = conv([1, 2, 3, 4, 5, 6, 7, 8, 9, 0]) + random.shuffle(alist) + actual = alist + desired = conv([0, 1, 9, 6, 2, 4, 5, 8, 7, 3]) + assert_array_equal(actual, desired) + + def test_shuffle_masked(self): + # gh-3263 + a = np.ma.masked_values(np.reshape(range(20), (5, 4)) % 3 - 1, -1) + b = np.ma.masked_values(np.arange(20) % 3 - 1, -1) + a_orig = a.copy() + b_orig = b.copy() + for i in range(50): + random.shuffle(a) + assert_equal( + sorted(a.data[~a.mask]), sorted(a_orig.data[~a_orig.mask])) + random.shuffle(b) + assert_equal( + sorted(b.data[~b.mask]), sorted(b_orig.data[~b_orig.mask])) + + def test_shuffle_invalid_objects(self): + x = np.array(3) + assert_raises(TypeError, random.shuffle, x) + + def test_permutation(self): + random.seed(self.seed) + alist = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0] + actual = random.permutation(alist) + desired = [0, 1, 9, 6, 2, 4, 5, 8, 7, 3] + assert_array_equal(actual, desired) + + random.seed(self.seed) + arr_2d = np.atleast_2d([1, 2, 3, 4, 5, 6, 7, 8, 9, 0]).T + actual = random.permutation(arr_2d) + assert_array_equal(actual, np.atleast_2d(desired).T) + + random.seed(self.seed) + bad_x_str = "abcd" + assert_raises(IndexError, random.permutation, bad_x_str) + + random.seed(self.seed) + bad_x_float = 1.2 + assert_raises(IndexError, random.permutation, bad_x_float) + + integer_val = 10 + desired = [9, 0, 8, 5, 1, 3, 4, 7, 6, 2] + + random.seed(self.seed) + actual = random.permutation(integer_val) + assert_array_equal(actual, desired) + + def test_beta(self): + random.seed(self.seed) + actual = random.beta(.1, .9, size=(3, 2)) + desired = np.array( + [[1.45341850513746058e-02, 5.31297615662868145e-04], + [1.85366619058432324e-06, 4.19214516800110563e-03], + [1.58405155108498093e-04, 1.26252891949397652e-04]]) + assert_array_almost_equal(actual, desired, decimal=15) + + def test_binomial(self): + random.seed(self.seed) + actual = random.binomial(100.123, .456, size=(3, 2)) + desired = np.array([[37, 43], + [42, 48], + [46, 45]]) + assert_array_equal(actual, desired) + + random.seed(self.seed) + actual = random.binomial(100.123, .456) + desired = 37 + assert_array_equal(actual, desired) + + def test_chisquare(self): + random.seed(self.seed) + actual = random.chisquare(50, size=(3, 2)) + desired = np.array([[63.87858175501090585, 68.68407748911370447], + [65.77116116901505904, 47.09686762438974483], + [72.3828403199695174, 74.18408615260374006]]) + assert_array_almost_equal(actual, desired, decimal=13) + + def test_dirichlet(self): + random.seed(self.seed) + alpha = np.array([51.72840233779265162, 39.74494232180943953]) + actual = random.dirichlet(alpha, size=(3, 2)) + desired = np.array([[[0.54539444573611562, 0.45460555426388438], + [0.62345816822039413, 0.37654183177960598]], + [[0.55206000085785778, 0.44793999914214233], + [0.58964023305154301, 0.41035976694845688]], + [[0.59266909280647828, 0.40733090719352177], + [0.56974431743975207, 0.43025568256024799]]]) + assert_array_almost_equal(actual, desired, decimal=15) + bad_alpha = np.array([5.4e-01, -1.0e-16]) + assert_raises(ValueError, random.dirichlet, bad_alpha) + + random.seed(self.seed) + alpha = np.array([51.72840233779265162, 39.74494232180943953]) + actual = random.dirichlet(alpha) + assert_array_almost_equal(actual, desired[0, 0], decimal=15) + + def test_dirichlet_size(self): + # gh-3173 + p = np.array([51.72840233779265162, 39.74494232180943953]) + assert_equal(random.dirichlet(p, np.uint32(1)).shape, (1, 2)) + assert_equal(random.dirichlet(p, np.uint32(1)).shape, (1, 2)) + assert_equal(random.dirichlet(p, np.uint32(1)).shape, (1, 2)) + assert_equal(random.dirichlet(p, [2, 2]).shape, (2, 2, 2)) + assert_equal(random.dirichlet(p, (2, 2)).shape, (2, 2, 2)) + assert_equal(random.dirichlet(p, np.array((2, 2))).shape, (2, 2, 2)) + + assert_raises(TypeError, random.dirichlet, p, float(1)) + + def test_dirichlet_bad_alpha(self): + # gh-2089 + alpha = np.array([5.4e-01, -1.0e-16]) + assert_raises(ValueError, random.dirichlet, alpha) + + def test_dirichlet_alpha_non_contiguous(self): + a = np.array([51.72840233779265162, -1.0, 39.74494232180943953]) + alpha = a[::2] + random.seed(self.seed) + non_contig = random.dirichlet(alpha, size=(3, 2)) + random.seed(self.seed) + contig = random.dirichlet(np.ascontiguousarray(alpha), + size=(3, 2)) + assert_array_almost_equal(non_contig, contig) + + def test_exponential(self): + random.seed(self.seed) + actual = random.exponential(1.1234, size=(3, 2)) + desired = np.array([[1.08342649775011624, 1.00607889924557314], + [2.46628830085216721, 2.49668106809923884], + [0.68717433461363442, 1.69175666993575979]]) + assert_array_almost_equal(actual, desired, decimal=15) + + def test_exponential_0(self): + assert_equal(random.exponential(scale=0), 0) + assert_raises(ValueError, random.exponential, scale=-0.) + + def test_f(self): + random.seed(self.seed) + actual = random.f(12, 77, size=(3, 2)) + desired = np.array([[1.21975394418575878, 1.75135759791559775], + [1.44803115017146489, 1.22108959480396262], + [1.02176975757740629, 1.34431827623300415]]) + assert_array_almost_equal(actual, desired, decimal=15) + + def test_gamma(self): + random.seed(self.seed) + actual = random.gamma(5, 3, size=(3, 2)) + desired = np.array([[24.60509188649287182, 28.54993563207210627], + [26.13476110204064184, 12.56988482927716078], + [31.71863275789960568, 33.30143302795922011]]) + assert_array_almost_equal(actual, desired, decimal=14) + + def test_gamma_0(self): + assert_equal(random.gamma(shape=0, scale=0), 0) + assert_raises(ValueError, random.gamma, shape=-0., scale=-0.) + + def test_geometric(self): + random.seed(self.seed) + actual = random.geometric(.123456789, size=(3, 2)) + desired = np.array([[8, 7], + [17, 17], + [5, 12]]) + assert_array_equal(actual, desired) + + def test_geometric_exceptions(self): + assert_raises(ValueError, random.geometric, 1.1) + assert_raises(ValueError, random.geometric, [1.1] * 10) + assert_raises(ValueError, random.geometric, -0.1) + assert_raises(ValueError, random.geometric, [-0.1] * 10) + with suppress_warnings() as sup: + sup.record(RuntimeWarning) + assert_raises(ValueError, random.geometric, np.nan) + assert_raises(ValueError, random.geometric, [np.nan] * 10) + + def test_gumbel(self): + random.seed(self.seed) + actual = random.gumbel(loc=.123456789, scale=2.0, size=(3, 2)) + desired = np.array([[0.19591898743416816, 0.34405539668096674], + [-1.4492522252274278, -1.47374816298446865], + [1.10651090478803416, -0.69535848626236174]]) + assert_array_almost_equal(actual, desired, decimal=15) + + def test_gumbel_0(self): + assert_equal(random.gumbel(scale=0), 0) + assert_raises(ValueError, random.gumbel, scale=-0.) + + def test_hypergeometric(self): + random.seed(self.seed) + actual = random.hypergeometric(10.1, 5.5, 14, size=(3, 2)) + desired = np.array([[10, 10], + [10, 10], + [9, 9]]) + assert_array_equal(actual, desired) + + # Test nbad = 0 + actual = random.hypergeometric(5, 0, 3, size=4) + desired = np.array([3, 3, 3, 3]) + assert_array_equal(actual, desired) + + actual = random.hypergeometric(15, 0, 12, size=4) + desired = np.array([12, 12, 12, 12]) + assert_array_equal(actual, desired) + + # Test ngood = 0 + actual = random.hypergeometric(0, 5, 3, size=4) + desired = np.array([0, 0, 0, 0]) + assert_array_equal(actual, desired) + + actual = random.hypergeometric(0, 15, 12, size=4) + desired = np.array([0, 0, 0, 0]) + assert_array_equal(actual, desired) + + def test_laplace(self): + random.seed(self.seed) + actual = random.laplace(loc=.123456789, scale=2.0, size=(3, 2)) + desired = np.array([[0.66599721112760157, 0.52829452552221945], + [3.12791959514407125, 3.18202813572992005], + [-0.05391065675859356, 1.74901336242837324]]) + assert_array_almost_equal(actual, desired, decimal=15) + + def test_laplace_0(self): + assert_equal(random.laplace(scale=0), 0) + assert_raises(ValueError, random.laplace, scale=-0.) + + def test_logistic(self): + random.seed(self.seed) + actual = random.logistic(loc=.123456789, scale=2.0, size=(3, 2)) + desired = np.array([[1.09232835305011444, 0.8648196662399954], + [4.27818590694950185, 4.33897006346929714], + [-0.21682183359214885, 2.63373365386060332]]) + assert_array_almost_equal(actual, desired, decimal=15) + + def test_lognormal(self): + random.seed(self.seed) + actual = random.lognormal(mean=.123456789, sigma=2.0, size=(3, 2)) + desired = np.array([[16.50698631688883822, 36.54846706092654784], + [22.67886599981281748, 0.71617561058995771], + [65.72798501792723869, 86.84341601437161273]]) + assert_array_almost_equal(actual, desired, decimal=13) + + def test_lognormal_0(self): + assert_equal(random.lognormal(sigma=0), 1) + assert_raises(ValueError, random.lognormal, sigma=-0.) + + def test_logseries(self): + random.seed(self.seed) + actual = random.logseries(p=.923456789, size=(3, 2)) + desired = np.array([[2, 2], + [6, 17], + [3, 6]]) + assert_array_equal(actual, desired) + + def test_logseries_exceptions(self): + with suppress_warnings() as sup: + sup.record(RuntimeWarning) + assert_raises(ValueError, random.logseries, np.nan) + assert_raises(ValueError, random.logseries, [np.nan] * 10) + + def test_multinomial(self): + random.seed(self.seed) + actual = random.multinomial(20, [1 / 6.] * 6, size=(3, 2)) + desired = np.array([[[4, 3, 5, 4, 2, 2], + [5, 2, 8, 2, 2, 1]], + [[3, 4, 3, 6, 0, 4], + [2, 1, 4, 3, 6, 4]], + [[4, 4, 2, 5, 2, 3], + [4, 3, 4, 2, 3, 4]]]) + assert_array_equal(actual, desired) + + def test_multivariate_normal(self): + random.seed(self.seed) + mean = (.123456789, 10) + cov = [[1, 0], [0, 1]] + size = (3, 2) + actual = random.multivariate_normal(mean, cov, size) + desired = np.array([[[1.463620246718631, 11.73759122771936], + [1.622445133300628, 9.771356667546383]], + [[2.154490787682787, 12.170324946056553], + [1.719909438201865, 9.230548443648306]], + [[0.689515026297799, 9.880729819607714], + [-0.023054015651998, 9.201096623542879]]]) + + assert_array_almost_equal(actual, desired, decimal=15) + + # Check for default size, was raising deprecation warning + actual = random.multivariate_normal(mean, cov) + desired = np.array([0.895289569463708, 9.17180864067987]) + assert_array_almost_equal(actual, desired, decimal=15) + + # Check that non positive-semidefinite covariance warns with + # RuntimeWarning + mean = [0, 0] + cov = [[1, 2], [2, 1]] + assert_warns(RuntimeWarning, random.multivariate_normal, mean, cov) + + # and that it doesn't warn with RuntimeWarning check_valid='ignore' + assert_no_warnings(random.multivariate_normal, mean, cov, + check_valid='ignore') + + # and that it raises with RuntimeWarning check_valid='raises' + assert_raises(ValueError, random.multivariate_normal, mean, cov, + check_valid='raise') + + cov = np.array([[1, 0.1], [0.1, 1]], dtype=np.float32) + with suppress_warnings() as sup: + random.multivariate_normal(mean, cov) + w = sup.record(RuntimeWarning) + assert len(w) == 0 + + mu = np.zeros(2) + cov = np.eye(2) + assert_raises(ValueError, random.multivariate_normal, mean, cov, + check_valid='other') + assert_raises(ValueError, random.multivariate_normal, + np.zeros((2, 1, 1)), cov) + assert_raises(ValueError, random.multivariate_normal, + mu, np.empty((3, 2))) + assert_raises(ValueError, random.multivariate_normal, + mu, np.eye(3)) + + def test_negative_binomial(self): + random.seed(self.seed) + actual = random.negative_binomial(n=100, p=.12345, size=(3, 2)) + desired = np.array([[848, 841], + [892, 611], + [779, 647]]) + assert_array_equal(actual, desired) + + def test_negative_binomial_exceptions(self): + with suppress_warnings() as sup: + sup.record(RuntimeWarning) + assert_raises(ValueError, random.negative_binomial, 100, np.nan) + assert_raises(ValueError, random.negative_binomial, 100, + [np.nan] * 10) + + def test_noncentral_chisquare(self): + random.seed(self.seed) + actual = random.noncentral_chisquare(df=5, nonc=5, size=(3, 2)) + desired = np.array([[23.91905354498517511, 13.35324692733826346], + [31.22452661329736401, 16.60047399466177254], + [5.03461598262724586, 17.94973089023519464]]) + assert_array_almost_equal(actual, desired, decimal=14) + + actual = random.noncentral_chisquare(df=.5, nonc=.2, size=(3, 2)) + desired = np.array([[1.47145377828516666, 0.15052899268012659], + [0.00943803056963588, 1.02647251615666169], + [0.332334982684171, 0.15451287602753125]]) + assert_array_almost_equal(actual, desired, decimal=14) + + random.seed(self.seed) + actual = random.noncentral_chisquare(df=5, nonc=0, size=(3, 2)) + desired = np.array([[9.597154162763948, 11.725484450296079], + [10.413711048138335, 3.694475922923986], + [13.484222138963087, 14.377255424602957]]) + assert_array_almost_equal(actual, desired, decimal=14) + + def test_noncentral_f(self): + random.seed(self.seed) + actual = random.noncentral_f(dfnum=5, dfden=2, nonc=1, + size=(3, 2)) + desired = np.array([[1.40598099674926669, 0.34207973179285761], + [3.57715069265772545, 7.92632662577829805], + [0.43741599463544162, 1.1774208752428319]]) + assert_array_almost_equal(actual, desired, decimal=14) + + def test_noncentral_f_nan(self): + random.seed(self.seed) + actual = random.noncentral_f(dfnum=5, dfden=2, nonc=np.nan) + assert np.isnan(actual) + + def test_normal(self): + random.seed(self.seed) + actual = random.normal(loc=.123456789, scale=2.0, size=(3, 2)) + desired = np.array([[2.80378370443726244, 3.59863924443872163], + [3.121433477601256, -0.33382987590723379], + [4.18552478636557357, 4.46410668111310471]]) + assert_array_almost_equal(actual, desired, decimal=15) + + def test_normal_0(self): + assert_equal(random.normal(scale=0), 0) + assert_raises(ValueError, random.normal, scale=-0.) + + def test_pareto(self): + random.seed(self.seed) + actual = random.pareto(a=.123456789, size=(3, 2)) + desired = np.array( + [[2.46852460439034849e+03, 1.41286880810518346e+03], + [5.28287797029485181e+07, 6.57720981047328785e+07], + [1.40840323350391515e+02, 1.98390255135251704e+05]]) + # For some reason on 32-bit x86 Ubuntu 12.10 the [1, 0] entry in this + # matrix differs by 24 nulps. Discussion: + # https://mail.python.org/pipermail/numpy-discussion/2012-September/063801.html + # Consensus is that this is probably some gcc quirk that affects + # rounding but not in any important way, so we just use a looser + # tolerance on this test: + np.testing.assert_array_almost_equal_nulp(actual, desired, nulp=30) + + def test_poisson(self): + random.seed(self.seed) + actual = random.poisson(lam=.123456789, size=(3, 2)) + desired = np.array([[0, 0], + [1, 0], + [0, 0]]) + assert_array_equal(actual, desired) + + def test_poisson_exceptions(self): + lambig = np.iinfo('l').max + lamneg = -1 + assert_raises(ValueError, random.poisson, lamneg) + assert_raises(ValueError, random.poisson, [lamneg] * 10) + assert_raises(ValueError, random.poisson, lambig) + assert_raises(ValueError, random.poisson, [lambig] * 10) + with suppress_warnings() as sup: + sup.record(RuntimeWarning) + assert_raises(ValueError, random.poisson, np.nan) + assert_raises(ValueError, random.poisson, [np.nan] * 10) + + def test_power(self): + random.seed(self.seed) + actual = random.power(a=.123456789, size=(3, 2)) + desired = np.array([[0.02048932883240791, 0.01424192241128213], + [0.38446073748535298, 0.39499689943484395], + [0.00177699707563439, 0.13115505880863756]]) + assert_array_almost_equal(actual, desired, decimal=15) + + def test_rayleigh(self): + random.seed(self.seed) + actual = random.rayleigh(scale=10, size=(3, 2)) + desired = np.array([[13.8882496494248393, 13.383318339044731], + [20.95413364294492098, 21.08285015800712614], + [11.06066537006854311, 17.35468505778271009]]) + assert_array_almost_equal(actual, desired, decimal=14) + + def test_rayleigh_0(self): + assert_equal(random.rayleigh(scale=0), 0) + assert_raises(ValueError, random.rayleigh, scale=-0.) + + def test_standard_cauchy(self): + random.seed(self.seed) + actual = random.standard_cauchy(size=(3, 2)) + desired = np.array([[0.77127660196445336, -6.55601161955910605], + [0.93582023391158309, -2.07479293013759447], + [-4.74601644297011926, 0.18338989290760804]]) + assert_array_almost_equal(actual, desired, decimal=15) + + def test_standard_exponential(self): + random.seed(self.seed) + actual = random.standard_exponential(size=(3, 2)) + desired = np.array([[0.96441739162374596, 0.89556604882105506], + [2.1953785836319808, 2.22243285392490542], + [0.6116915921431676, 1.50592546727413201]]) + assert_array_almost_equal(actual, desired, decimal=15) + + def test_standard_gamma(self): + random.seed(self.seed) + actual = random.standard_gamma(shape=3, size=(3, 2)) + desired = np.array([[5.50841531318455058, 6.62953470301903103], + [5.93988484943779227, 2.31044849402133989], + [7.54838614231317084, 8.012756093271868]]) + assert_array_almost_equal(actual, desired, decimal=14) + + def test_standard_gamma_0(self): + assert_equal(random.standard_gamma(shape=0), 0) + assert_raises(ValueError, random.standard_gamma, shape=-0.) + + def test_standard_normal(self): + random.seed(self.seed) + actual = random.standard_normal(size=(3, 2)) + desired = np.array([[1.34016345771863121, 1.73759122771936081], + [1.498988344300628, -0.2286433324536169], + [2.031033998682787, 2.17032494605655257]]) + assert_array_almost_equal(actual, desired, decimal=15) + + def test_randn_singleton(self): + random.seed(self.seed) + actual = random.randn() + desired = np.array(1.34016345771863121) + assert_array_almost_equal(actual, desired, decimal=15) + + def test_standard_t(self): + random.seed(self.seed) + actual = random.standard_t(df=10, size=(3, 2)) + desired = np.array([[0.97140611862659965, -0.08830486548450577], + [1.36311143689505321, -0.55317463909867071], + [-0.18473749069684214, 0.61181537341755321]]) + assert_array_almost_equal(actual, desired, decimal=15) + + def test_triangular(self): + random.seed(self.seed) + actual = random.triangular(left=5.12, mode=10.23, right=20.34, + size=(3, 2)) + desired = np.array([[12.68117178949215784, 12.4129206149193152], + [16.20131377335158263, 16.25692138747600524], + [11.20400690911820263, 14.4978144835829923]]) + assert_array_almost_equal(actual, desired, decimal=14) + + def test_uniform(self): + random.seed(self.seed) + actual = random.uniform(low=1.23, high=10.54, size=(3, 2)) + desired = np.array([[6.99097932346268003, 6.73801597444323974], + [9.50364421400426274, 9.53130618907631089], + [5.48995325769805476, 8.47493103280052118]]) + assert_array_almost_equal(actual, desired, decimal=15) + + def test_uniform_range_bounds(self): + fmin = np.finfo('float').min + fmax = np.finfo('float').max + + func = random.uniform + assert_raises(OverflowError, func, -np.inf, 0) + assert_raises(OverflowError, func, 0, np.inf) + assert_raises(OverflowError, func, fmin, fmax) + assert_raises(OverflowError, func, [-np.inf], [0]) + assert_raises(OverflowError, func, [0], [np.inf]) + + # (fmax / 1e17) - fmin is within range, so this should not throw + # account for i386 extended precision DBL_MAX / 1e17 + DBL_MAX > + # DBL_MAX by increasing fmin a bit + random.uniform(low=np.nextafter(fmin, 1), high=fmax / 1e17) + + def test_scalar_exception_propagation(self): + # Tests that exceptions are correctly propagated in distributions + # when called with objects that throw exceptions when converted to + # scalars. + # + # Regression test for gh: 8865 + + class ThrowingFloat(np.ndarray): + def __float__(self): + raise TypeError + + throwing_float = np.array(1.0).view(ThrowingFloat) + assert_raises(TypeError, random.uniform, throwing_float, + throwing_float) + + class ThrowingInteger(np.ndarray): + def __int__(self): + raise TypeError + + throwing_int = np.array(1).view(ThrowingInteger) + assert_raises(TypeError, random.hypergeometric, throwing_int, 1, 1) + + def test_vonmises(self): + random.seed(self.seed) + actual = random.vonmises(mu=1.23, kappa=1.54, size=(3, 2)) + desired = np.array([[2.28567572673902042, 2.89163838442285037], + [0.38198375564286025, 2.57638023113890746], + [1.19153771588353052, 1.83509849681825354]]) + assert_array_almost_equal(actual, desired, decimal=15) + + def test_vonmises_small(self): + # check infinite loop, gh-4720 + random.seed(self.seed) + r = random.vonmises(mu=0., kappa=1.1e-8, size=10**6) + assert_(np.isfinite(r).all()) + + def test_vonmises_nan(self): + random.seed(self.seed) + r = random.vonmises(mu=0., kappa=np.nan) + assert_(np.isnan(r)) + + def test_wald(self): + random.seed(self.seed) + actual = random.wald(mean=1.23, scale=1.54, size=(3, 2)) + desired = np.array([[3.82935265715889983, 5.13125249184285526], + [0.35045403618358717, 1.50832396872003538], + [0.24124319895843183, 0.22031101461955038]]) + assert_array_almost_equal(actual, desired, decimal=14) + + def test_weibull(self): + random.seed(self.seed) + actual = random.weibull(a=1.23, size=(3, 2)) + desired = np.array([[0.97097342648766727, 0.91422896443565516], + [1.89517770034962929, 1.91414357960479564], + [0.67057783752390987, 1.39494046635066793]]) + assert_array_almost_equal(actual, desired, decimal=15) + + def test_weibull_0(self): + random.seed(self.seed) + assert_equal(random.weibull(a=0, size=12), np.zeros(12)) + assert_raises(ValueError, random.weibull, a=-0.) + + def test_zipf(self): + random.seed(self.seed) + actual = random.zipf(a=1.23, size=(3, 2)) + desired = np.array([[66, 29], + [1, 1], + [3, 13]]) + assert_array_equal(actual, desired) + + +class TestBroadcast: + # tests that functions that broadcast behave + # correctly when presented with non-scalar arguments + def setup(self): + self.seed = 123456789 + + def set_seed(self): + random.seed(self.seed) + + def test_uniform(self): + low = [0] + high = [1] + uniform = random.uniform + desired = np.array([0.53283302478975902, + 0.53413660089041659, + 0.50955303552646702]) + + self.set_seed() + actual = uniform(low * 3, high) + assert_array_almost_equal(actual, desired, decimal=14) + + self.set_seed() + actual = uniform(low, high * 3) + assert_array_almost_equal(actual, desired, decimal=14) + + def test_normal(self): + loc = [0] + scale = [1] + bad_scale = [-1] + normal = random.normal + desired = np.array([2.2129019979039612, + 2.1283977976520019, + 1.8417114045748335]) + + self.set_seed() + actual = normal(loc * 3, scale) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, normal, loc * 3, bad_scale) + + self.set_seed() + actual = normal(loc, scale * 3) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, normal, loc, bad_scale * 3) + + def test_beta(self): + a = [1] + b = [2] + bad_a = [-1] + bad_b = [-2] + beta = random.beta + desired = np.array([0.19843558305989056, + 0.075230336409423643, + 0.24976865978980844]) + + self.set_seed() + actual = beta(a * 3, b) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, beta, bad_a * 3, b) + assert_raises(ValueError, beta, a * 3, bad_b) + + self.set_seed() + actual = beta(a, b * 3) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, beta, bad_a, b * 3) + assert_raises(ValueError, beta, a, bad_b * 3) + + def test_exponential(self): + scale = [1] + bad_scale = [-1] + exponential = random.exponential + desired = np.array([0.76106853658845242, + 0.76386282278691653, + 0.71243813125891797]) + + self.set_seed() + actual = exponential(scale * 3) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, exponential, bad_scale * 3) + + def test_standard_gamma(self): + shape = [1] + bad_shape = [-1] + std_gamma = random.standard_gamma + desired = np.array([0.76106853658845242, + 0.76386282278691653, + 0.71243813125891797]) + + self.set_seed() + actual = std_gamma(shape * 3) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, std_gamma, bad_shape * 3) + + def test_gamma(self): + shape = [1] + scale = [2] + bad_shape = [-1] + bad_scale = [-2] + gamma = random.gamma + desired = np.array([1.5221370731769048, + 1.5277256455738331, + 1.4248762625178359]) + + self.set_seed() + actual = gamma(shape * 3, scale) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, gamma, bad_shape * 3, scale) + assert_raises(ValueError, gamma, shape * 3, bad_scale) + + self.set_seed() + actual = gamma(shape, scale * 3) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, gamma, bad_shape, scale * 3) + assert_raises(ValueError, gamma, shape, bad_scale * 3) + + def test_f(self): + dfnum = [1] + dfden = [2] + bad_dfnum = [-1] + bad_dfden = [-2] + f = random.f + desired = np.array([0.80038951638264799, + 0.86768719635363512, + 2.7251095168386801]) + + self.set_seed() + actual = f(dfnum * 3, dfden) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, f, bad_dfnum * 3, dfden) + assert_raises(ValueError, f, dfnum * 3, bad_dfden) + + self.set_seed() + actual = f(dfnum, dfden * 3) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, f, bad_dfnum, dfden * 3) + assert_raises(ValueError, f, dfnum, bad_dfden * 3) + + def test_noncentral_f(self): + dfnum = [2] + dfden = [3] + nonc = [4] + bad_dfnum = [0] + bad_dfden = [-1] + bad_nonc = [-2] + nonc_f = random.noncentral_f + desired = np.array([9.1393943263705211, + 13.025456344595602, + 8.8018098359100545]) + + self.set_seed() + actual = nonc_f(dfnum * 3, dfden, nonc) + assert_array_almost_equal(actual, desired, decimal=14) + assert np.all(np.isnan(nonc_f(dfnum, dfden, [np.nan] * 3))) + + assert_raises(ValueError, nonc_f, bad_dfnum * 3, dfden, nonc) + assert_raises(ValueError, nonc_f, dfnum * 3, bad_dfden, nonc) + assert_raises(ValueError, nonc_f, dfnum * 3, dfden, bad_nonc) + + self.set_seed() + actual = nonc_f(dfnum, dfden * 3, nonc) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, nonc_f, bad_dfnum, dfden * 3, nonc) + assert_raises(ValueError, nonc_f, dfnum, bad_dfden * 3, nonc) + assert_raises(ValueError, nonc_f, dfnum, dfden * 3, bad_nonc) + + self.set_seed() + actual = nonc_f(dfnum, dfden, nonc * 3) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, nonc_f, bad_dfnum, dfden, nonc * 3) + assert_raises(ValueError, nonc_f, dfnum, bad_dfden, nonc * 3) + assert_raises(ValueError, nonc_f, dfnum, dfden, bad_nonc * 3) + + def test_noncentral_f_small_df(self): + self.set_seed() + desired = np.array([6.869638627492048, 0.785880199263955]) + actual = random.noncentral_f(0.9, 0.9, 2, size=2) + assert_array_almost_equal(actual, desired, decimal=14) + + def test_chisquare(self): + df = [1] + bad_df = [-1] + chisquare = random.chisquare + desired = np.array([0.57022801133088286, + 0.51947702108840776, + 0.1320969254923558]) + + self.set_seed() + actual = chisquare(df * 3) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, chisquare, bad_df * 3) + + def test_noncentral_chisquare(self): + df = [1] + nonc = [2] + bad_df = [-1] + bad_nonc = [-2] + nonc_chi = random.noncentral_chisquare + desired = np.array([9.0015599467913763, + 4.5804135049718742, + 6.0872302432834564]) + + self.set_seed() + actual = nonc_chi(df * 3, nonc) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, nonc_chi, bad_df * 3, nonc) + assert_raises(ValueError, nonc_chi, df * 3, bad_nonc) + + self.set_seed() + actual = nonc_chi(df, nonc * 3) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, nonc_chi, bad_df, nonc * 3) + assert_raises(ValueError, nonc_chi, df, bad_nonc * 3) + + def test_standard_t(self): + df = [1] + bad_df = [-1] + t = random.standard_t + desired = np.array([3.0702872575217643, + 5.8560725167361607, + 1.0274791436474273]) + + self.set_seed() + actual = t(df * 3) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, t, bad_df * 3) + assert_raises(ValueError, random.standard_t, bad_df * 3) + + def test_vonmises(self): + mu = [2] + kappa = [1] + bad_kappa = [-1] + vonmises = random.vonmises + desired = np.array([2.9883443664201312, + -2.7064099483995943, + -1.8672476700665914]) + + self.set_seed() + actual = vonmises(mu * 3, kappa) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, vonmises, mu * 3, bad_kappa) + + self.set_seed() + actual = vonmises(mu, kappa * 3) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, vonmises, mu, bad_kappa * 3) + + def test_pareto(self): + a = [1] + bad_a = [-1] + pareto = random.pareto + desired = np.array([1.1405622680198362, + 1.1465519762044529, + 1.0389564467453547]) + + self.set_seed() + actual = pareto(a * 3) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, pareto, bad_a * 3) + assert_raises(ValueError, random.pareto, bad_a * 3) + + def test_weibull(self): + a = [1] + bad_a = [-1] + weibull = random.weibull + desired = np.array([0.76106853658845242, + 0.76386282278691653, + 0.71243813125891797]) + + self.set_seed() + actual = weibull(a * 3) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, weibull, bad_a * 3) + assert_raises(ValueError, random.weibull, bad_a * 3) + + def test_power(self): + a = [1] + bad_a = [-1] + power = random.power + desired = np.array([0.53283302478975902, + 0.53413660089041659, + 0.50955303552646702]) + + self.set_seed() + actual = power(a * 3) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, power, bad_a * 3) + assert_raises(ValueError, random.power, bad_a * 3) + + def test_laplace(self): + loc = [0] + scale = [1] + bad_scale = [-1] + laplace = random.laplace + desired = np.array([0.067921356028507157, + 0.070715642226971326, + 0.019290950698972624]) + + self.set_seed() + actual = laplace(loc * 3, scale) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, laplace, loc * 3, bad_scale) + + self.set_seed() + actual = laplace(loc, scale * 3) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, laplace, loc, bad_scale * 3) + + def test_gumbel(self): + loc = [0] + scale = [1] + bad_scale = [-1] + gumbel = random.gumbel + desired = np.array([0.2730318639556768, + 0.26936705726291116, + 0.33906220393037939]) + + self.set_seed() + actual = gumbel(loc * 3, scale) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, gumbel, loc * 3, bad_scale) + + self.set_seed() + actual = gumbel(loc, scale * 3) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, gumbel, loc, bad_scale * 3) + + def test_logistic(self): + loc = [0] + scale = [1] + bad_scale = [-1] + logistic = random.logistic + desired = np.array([0.13152135837586171, + 0.13675915696285773, + 0.038216792802833396]) + + self.set_seed() + actual = logistic(loc * 3, scale) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, logistic, loc * 3, bad_scale) + + self.set_seed() + actual = logistic(loc, scale * 3) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, logistic, loc, bad_scale * 3) + assert_equal(random.logistic(1.0, 0.0), 1.0) + + def test_lognormal(self): + mean = [0] + sigma = [1] + bad_sigma = [-1] + lognormal = random.lognormal + desired = np.array([9.1422086044848427, + 8.4013952870126261, + 6.3073234116578671]) + + self.set_seed() + actual = lognormal(mean * 3, sigma) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, lognormal, mean * 3, bad_sigma) + assert_raises(ValueError, random.lognormal, mean * 3, bad_sigma) + + self.set_seed() + actual = lognormal(mean, sigma * 3) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, lognormal, mean, bad_sigma * 3) + assert_raises(ValueError, random.lognormal, mean, bad_sigma * 3) + + def test_rayleigh(self): + scale = [1] + bad_scale = [-1] + rayleigh = random.rayleigh + desired = np.array([1.2337491937897689, + 1.2360119924878694, + 1.1936818095781789]) + + self.set_seed() + actual = rayleigh(scale * 3) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, rayleigh, bad_scale * 3) + + def test_wald(self): + mean = [0.5] + scale = [1] + bad_mean = [0] + bad_scale = [-2] + wald = random.wald + desired = np.array([0.11873681120271318, + 0.12450084820795027, + 0.9096122728408238]) + + self.set_seed() + actual = wald(mean * 3, scale) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, wald, bad_mean * 3, scale) + assert_raises(ValueError, wald, mean * 3, bad_scale) + assert_raises(ValueError, random.wald, bad_mean * 3, scale) + assert_raises(ValueError, random.wald, mean * 3, bad_scale) + + self.set_seed() + actual = wald(mean, scale * 3) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, wald, bad_mean, scale * 3) + assert_raises(ValueError, wald, mean, bad_scale * 3) + assert_raises(ValueError, wald, 0.0, 1) + assert_raises(ValueError, wald, 0.5, 0.0) + + def test_triangular(self): + left = [1] + right = [3] + mode = [2] + bad_left_one = [3] + bad_mode_one = [4] + bad_left_two, bad_mode_two = right * 2 + triangular = random.triangular + desired = np.array([2.03339048710429, + 2.0347400359389356, + 2.0095991069536208]) + + self.set_seed() + actual = triangular(left * 3, mode, right) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, triangular, bad_left_one * 3, mode, right) + assert_raises(ValueError, triangular, left * 3, bad_mode_one, right) + assert_raises(ValueError, triangular, bad_left_two * 3, bad_mode_two, + right) + + self.set_seed() + actual = triangular(left, mode * 3, right) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, triangular, bad_left_one, mode * 3, right) + assert_raises(ValueError, triangular, left, bad_mode_one * 3, right) + assert_raises(ValueError, triangular, bad_left_two, bad_mode_two * 3, + right) + + self.set_seed() + actual = triangular(left, mode, right * 3) + assert_array_almost_equal(actual, desired, decimal=14) + assert_raises(ValueError, triangular, bad_left_one, mode, right * 3) + assert_raises(ValueError, triangular, left, bad_mode_one, right * 3) + assert_raises(ValueError, triangular, bad_left_two, bad_mode_two, + right * 3) + + assert_raises(ValueError, triangular, 10., 0., 20.) + assert_raises(ValueError, triangular, 10., 25., 20.) + assert_raises(ValueError, triangular, 10., 10., 10.) + + def test_binomial(self): + n = [1] + p = [0.5] + bad_n = [-1] + bad_p_one = [-1] + bad_p_two = [1.5] + binom = random.binomial + desired = np.array([1, 1, 1]) + + self.set_seed() + actual = binom(n * 3, p) + assert_array_equal(actual, desired) + assert_raises(ValueError, binom, bad_n * 3, p) + assert_raises(ValueError, binom, n * 3, bad_p_one) + assert_raises(ValueError, binom, n * 3, bad_p_two) + + self.set_seed() + actual = binom(n, p * 3) + assert_array_equal(actual, desired) + assert_raises(ValueError, binom, bad_n, p * 3) + assert_raises(ValueError, binom, n, bad_p_one * 3) + assert_raises(ValueError, binom, n, bad_p_two * 3) + + def test_negative_binomial(self): + n = [1] + p = [0.5] + bad_n = [-1] + bad_p_one = [-1] + bad_p_two = [1.5] + neg_binom = random.negative_binomial + desired = np.array([1, 0, 1]) + + self.set_seed() + actual = neg_binom(n * 3, p) + assert_array_equal(actual, desired) + assert_raises(ValueError, neg_binom, bad_n * 3, p) + assert_raises(ValueError, neg_binom, n * 3, bad_p_one) + assert_raises(ValueError, neg_binom, n * 3, bad_p_two) + + self.set_seed() + actual = neg_binom(n, p * 3) + assert_array_equal(actual, desired) + assert_raises(ValueError, neg_binom, bad_n, p * 3) + assert_raises(ValueError, neg_binom, n, bad_p_one * 3) + assert_raises(ValueError, neg_binom, n, bad_p_two * 3) + + def test_poisson(self): + max_lam = random.RandomState()._poisson_lam_max + + lam = [1] + bad_lam_one = [-1] + bad_lam_two = [max_lam * 2] + poisson = random.poisson + desired = np.array([1, 1, 0]) + + self.set_seed() + actual = poisson(lam * 3) + assert_array_equal(actual, desired) + assert_raises(ValueError, poisson, bad_lam_one * 3) + assert_raises(ValueError, poisson, bad_lam_two * 3) + + def test_zipf(self): + a = [2] + bad_a = [0] + zipf = random.zipf + desired = np.array([2, 2, 1]) + + self.set_seed() + actual = zipf(a * 3) + assert_array_equal(actual, desired) + assert_raises(ValueError, zipf, bad_a * 3) + with np.errstate(invalid='ignore'): + assert_raises(ValueError, zipf, np.nan) + assert_raises(ValueError, zipf, [0, 0, np.nan]) + + def test_geometric(self): + p = [0.5] + bad_p_one = [-1] + bad_p_two = [1.5] + geom = random.geometric + desired = np.array([2, 2, 2]) + + self.set_seed() + actual = geom(p * 3) + assert_array_equal(actual, desired) + assert_raises(ValueError, geom, bad_p_one * 3) + assert_raises(ValueError, geom, bad_p_two * 3) + + def test_hypergeometric(self): + ngood = [1] + nbad = [2] + nsample = [2] + bad_ngood = [-1] + bad_nbad = [-2] + bad_nsample_one = [0] + bad_nsample_two = [4] + hypergeom = random.hypergeometric + desired = np.array([1, 1, 1]) + + self.set_seed() + actual = hypergeom(ngood * 3, nbad, nsample) + assert_array_equal(actual, desired) + assert_raises(ValueError, hypergeom, bad_ngood * 3, nbad, nsample) + assert_raises(ValueError, hypergeom, ngood * 3, bad_nbad, nsample) + assert_raises(ValueError, hypergeom, ngood * 3, nbad, bad_nsample_one) + assert_raises(ValueError, hypergeom, ngood * 3, nbad, bad_nsample_two) + + self.set_seed() + actual = hypergeom(ngood, nbad * 3, nsample) + assert_array_equal(actual, desired) + assert_raises(ValueError, hypergeom, bad_ngood, nbad * 3, nsample) + assert_raises(ValueError, hypergeom, ngood, bad_nbad * 3, nsample) + assert_raises(ValueError, hypergeom, ngood, nbad * 3, bad_nsample_one) + assert_raises(ValueError, hypergeom, ngood, nbad * 3, bad_nsample_two) + + self.set_seed() + actual = hypergeom(ngood, nbad, nsample * 3) + assert_array_equal(actual, desired) + assert_raises(ValueError, hypergeom, bad_ngood, nbad, nsample * 3) + assert_raises(ValueError, hypergeom, ngood, bad_nbad, nsample * 3) + assert_raises(ValueError, hypergeom, ngood, nbad, bad_nsample_one * 3) + assert_raises(ValueError, hypergeom, ngood, nbad, bad_nsample_two * 3) + + assert_raises(ValueError, hypergeom, -1, 10, 20) + assert_raises(ValueError, hypergeom, 10, -1, 20) + assert_raises(ValueError, hypergeom, 10, 10, 0) + assert_raises(ValueError, hypergeom, 10, 10, 25) + + def test_logseries(self): + p = [0.5] + bad_p_one = [2] + bad_p_two = [-1] + logseries = random.logseries + desired = np.array([1, 1, 1]) + + self.set_seed() + actual = logseries(p * 3) + assert_array_equal(actual, desired) + assert_raises(ValueError, logseries, bad_p_one * 3) + assert_raises(ValueError, logseries, bad_p_two * 3) + + +class TestThread: + # make sure each state produces the same sequence even in threads + def setup(self): + self.seeds = range(4) + + def check_function(self, function, sz): + from threading import Thread + + out1 = np.empty((len(self.seeds),) + sz) + out2 = np.empty((len(self.seeds),) + sz) + + # threaded generation + t = [Thread(target=function, args=(random.RandomState(s), o)) + for s, o in zip(self.seeds, out1)] + [x.start() for x in t] + [x.join() for x in t] + + # the same serial + for s, o in zip(self.seeds, out2): + function(random.RandomState(s), o) + + # these platforms change x87 fpu precision mode in threads + if np.intp().dtype.itemsize == 4 and sys.platform == "win32": + assert_array_almost_equal(out1, out2) + else: + assert_array_equal(out1, out2) + + def test_normal(self): + def gen_random(state, out): + out[...] = state.normal(size=10000) + + self.check_function(gen_random, sz=(10000,)) + + def test_exp(self): + def gen_random(state, out): + out[...] = state.exponential(scale=np.ones((100, 1000))) + + self.check_function(gen_random, sz=(100, 1000)) + + def test_multinomial(self): + def gen_random(state, out): + out[...] = state.multinomial(10, [1 / 6.] * 6, size=10000) + + self.check_function(gen_random, sz=(10000, 6)) + + +# See Issue #4263 +class TestSingleEltArrayInput: + def setup(self): + self.argOne = np.array([2]) + self.argTwo = np.array([3]) + self.argThree = np.array([4]) + self.tgtShape = (1,) + + def test_one_arg_funcs(self): + funcs = (random.exponential, random.standard_gamma, + random.chisquare, random.standard_t, + random.pareto, random.weibull, + random.power, random.rayleigh, + random.poisson, random.zipf, + random.geometric, random.logseries) + + probfuncs = (random.geometric, random.logseries) + + for func in funcs: + if func in probfuncs: # p < 1.0 + out = func(np.array([0.5])) + + else: + out = func(self.argOne) + + assert_equal(out.shape, self.tgtShape) + + def test_two_arg_funcs(self): + funcs = (random.uniform, random.normal, + random.beta, random.gamma, + random.f, random.noncentral_chisquare, + random.vonmises, random.laplace, + random.gumbel, random.logistic, + random.lognormal, random.wald, + random.binomial, random.negative_binomial) + + probfuncs = (random.binomial, random.negative_binomial) + + for func in funcs: + if func in probfuncs: # p <= 1 + argTwo = np.array([0.5]) + + else: + argTwo = self.argTwo + + out = func(self.argOne, argTwo) + assert_equal(out.shape, self.tgtShape) + + out = func(self.argOne[0], argTwo) + assert_equal(out.shape, self.tgtShape) + + out = func(self.argOne, argTwo[0]) + assert_equal(out.shape, self.tgtShape) + + def test_three_arg_funcs(self): + funcs = [random.noncentral_f, random.triangular, + random.hypergeometric] + + for func in funcs: + out = func(self.argOne, self.argTwo, self.argThree) + assert_equal(out.shape, self.tgtShape) + + out = func(self.argOne[0], self.argTwo, self.argThree) + assert_equal(out.shape, self.tgtShape) + + out = func(self.argOne, self.argTwo[0], self.argThree) + assert_equal(out.shape, self.tgtShape) + + +# Ensure returned array dtype is correct for platform +def test_integer_dtype(int_func): + random.seed(123456789) + fname, args, sha256 = int_func + f = getattr(random, fname) + actual = f(*args, size=2) + assert_(actual.dtype == np.dtype('l')) + + +def test_integer_repeat(int_func): + random.seed(123456789) + fname, args, sha256 = int_func + f = getattr(random, fname) + val = f(*args, size=1000000) + if sys.byteorder != 'little': + val = val.byteswap() + res = hashlib.sha256(val.view(np.int8)).hexdigest() + assert_(res == sha256) + + +def test_broadcast_size_error(): + # GH-16833 + with pytest.raises(ValueError): + random.binomial(1, [0.3, 0.7], size=(2, 1)) + with pytest.raises(ValueError): + random.binomial([1, 2], 0.3, size=(2, 1)) + with pytest.raises(ValueError): + random.binomial([1, 2], [0.3, 0.7], size=(2, 1)) diff --git a/venv/Lib/site-packages/numpy/random/tests/test_randomstate_regression.py b/venv/Lib/site-packages/numpy/random/tests/test_randomstate_regression.py new file mode 100644 index 0000000..0bf361e --- /dev/null +++ b/venv/Lib/site-packages/numpy/random/tests/test_randomstate_regression.py @@ -0,0 +1,203 @@ +import sys + +import pytest + +from numpy.testing import ( + assert_, assert_array_equal, assert_raises, + ) +import numpy as np + +from numpy import random + + +class TestRegression: + + def test_VonMises_range(self): + # Make sure generated random variables are in [-pi, pi]. + # Regression test for ticket #986. + for mu in np.linspace(-7., 7., 5): + r = random.vonmises(mu, 1, 50) + assert_(np.all(r > -np.pi) and np.all(r <= np.pi)) + + def test_hypergeometric_range(self): + # Test for ticket #921 + assert_(np.all(random.hypergeometric(3, 18, 11, size=10) < 4)) + assert_(np.all(random.hypergeometric(18, 3, 11, size=10) > 0)) + + # Test for ticket #5623 + args = [ + (2**20 - 2, 2**20 - 2, 2**20 - 2), # Check for 32-bit systems + ] + is_64bits = sys.maxsize > 2**32 + if is_64bits and sys.platform != 'win32': + # Check for 64-bit systems + args.append((2**40 - 2, 2**40 - 2, 2**40 - 2)) + for arg in args: + assert_(random.hypergeometric(*arg) > 0) + + def test_logseries_convergence(self): + # Test for ticket #923 + N = 1000 + random.seed(0) + rvsn = random.logseries(0.8, size=N) + # these two frequency counts should be close to theoretical + # numbers with this large sample + # theoretical large N result is 0.49706795 + freq = np.sum(rvsn == 1) / float(N) + msg = f'Frequency was {freq:f}, should be > 0.45' + assert_(freq > 0.45, msg) + # theoretical large N result is 0.19882718 + freq = np.sum(rvsn == 2) / float(N) + msg = f'Frequency was {freq:f}, should be < 0.23' + assert_(freq < 0.23, msg) + + def test_shuffle_mixed_dimension(self): + # Test for trac ticket #2074 + for t in [[1, 2, 3, None], + [(1, 1), (2, 2), (3, 3), None], + [1, (2, 2), (3, 3), None], + [(1, 1), 2, 3, None]]: + random.seed(12345) + shuffled = list(t) + random.shuffle(shuffled) + expected = np.array([t[0], t[3], t[1], t[2]], dtype=object) + assert_array_equal(np.array(shuffled, dtype=object), expected) + + def test_call_within_randomstate(self): + # Check that custom RandomState does not call into global state + m = random.RandomState() + res = np.array([0, 8, 7, 2, 1, 9, 4, 7, 0, 3]) + for i in range(3): + random.seed(i) + m.seed(4321) + # If m.state is not honored, the result will change + assert_array_equal(m.choice(10, size=10, p=np.ones(10)/10.), res) + + def test_multivariate_normal_size_types(self): + # Test for multivariate_normal issue with 'size' argument. + # Check that the multivariate_normal size argument can be a + # numpy integer. + random.multivariate_normal([0], [[0]], size=1) + random.multivariate_normal([0], [[0]], size=np.int_(1)) + random.multivariate_normal([0], [[0]], size=np.int64(1)) + + def test_beta_small_parameters(self): + # Test that beta with small a and b parameters does not produce + # NaNs due to roundoff errors causing 0 / 0, gh-5851 + random.seed(1234567890) + x = random.beta(0.0001, 0.0001, size=100) + assert_(not np.any(np.isnan(x)), 'Nans in random.beta') + + def test_choice_sum_of_probs_tolerance(self): + # The sum of probs should be 1.0 with some tolerance. + # For low precision dtypes the tolerance was too tight. + # See numpy github issue 6123. + random.seed(1234) + a = [1, 2, 3] + counts = [4, 4, 2] + for dt in np.float16, np.float32, np.float64: + probs = np.array(counts, dtype=dt) / sum(counts) + c = random.choice(a, p=probs) + assert_(c in a) + assert_raises(ValueError, random.choice, a, p=probs*0.9) + + def test_shuffle_of_array_of_different_length_strings(self): + # Test that permuting an array of different length strings + # will not cause a segfault on garbage collection + # Tests gh-7710 + random.seed(1234) + + a = np.array(['a', 'a' * 1000]) + + for _ in range(100): + random.shuffle(a) + + # Force Garbage Collection - should not segfault. + import gc + gc.collect() + + def test_shuffle_of_array_of_objects(self): + # Test that permuting an array of objects will not cause + # a segfault on garbage collection. + # See gh-7719 + random.seed(1234) + a = np.array([np.arange(1), np.arange(4)], dtype=object) + + for _ in range(1000): + random.shuffle(a) + + # Force Garbage Collection - should not segfault. + import gc + gc.collect() + + def test_permutation_subclass(self): + class N(np.ndarray): + pass + + random.seed(1) + orig = np.arange(3).view(N) + perm = random.permutation(orig) + assert_array_equal(perm, np.array([0, 2, 1])) + assert_array_equal(orig, np.arange(3).view(N)) + + class M: + a = np.arange(5) + + def __array__(self): + return self.a + + random.seed(1) + m = M() + perm = random.permutation(m) + assert_array_equal(perm, np.array([2, 1, 4, 0, 3])) + assert_array_equal(m.__array__(), np.arange(5)) + + def test_warns_byteorder(self): + # GH 13159 + other_byteord_dt = 'i4' + with pytest.deprecated_call(match='non-native byteorder is not'): + random.randint(0, 200, size=10, dtype=other_byteord_dt) + + def test_named_argument_initialization(self): + # GH 13669 + rs1 = np.random.RandomState(123456789) + rs2 = np.random.RandomState(seed=123456789) + assert rs1.randint(0, 100) == rs2.randint(0, 100) + + def test_choice_retun_dtype(self): + # GH 9867 + c = np.random.choice(10, p=[.1]*10, size=2) + assert c.dtype == np.dtype(int) + c = np.random.choice(10, p=[.1]*10, replace=False, size=2) + assert c.dtype == np.dtype(int) + c = np.random.choice(10, size=2) + assert c.dtype == np.dtype(int) + c = np.random.choice(10, replace=False, size=2) + assert c.dtype == np.dtype(int) + + @pytest.mark.skipif(np.iinfo('l').max < 2**32, + reason='Cannot test with 32-bit C long') + def test_randint_117(self): + # GH 14189 + random.seed(0) + expected = np.array([2357136044, 2546248239, 3071714933, 3626093760, + 2588848963, 3684848379, 2340255427, 3638918503, + 1819583497, 2678185683], dtype='int64') + actual = random.randint(2**32, size=10) + assert_array_equal(actual, expected) + + def test_p_zero_stream(self): + # Regression test for gh-14522. Ensure that future versions + # generate the same variates as version 1.16. + np.random.seed(12345) + assert_array_equal(random.binomial(1, [0, 0.25, 0.5, 0.75, 1]), + [0, 0, 0, 1, 1]) + + def test_n_zero_stream(self): + # Regression test for gh-14522. Ensure that future versions + # generate the same variates as version 1.16. + np.random.seed(8675309) + expected = np.array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [3, 4, 2, 3, 3, 1, 5, 3, 1, 3]]) + assert_array_equal(random.binomial([[0], [10]], 0.25, size=(2, 10)), + expected) diff --git a/venv/Lib/site-packages/numpy/random/tests/test_regression.py b/venv/Lib/site-packages/numpy/random/tests/test_regression.py new file mode 100644 index 0000000..54d5a3e --- /dev/null +++ b/venv/Lib/site-packages/numpy/random/tests/test_regression.py @@ -0,0 +1,149 @@ +import sys +from numpy.testing import ( + assert_, assert_array_equal, assert_raises, + ) +from numpy import random +import numpy as np + + +class TestRegression: + + def test_VonMises_range(self): + # Make sure generated random variables are in [-pi, pi]. + # Regression test for ticket #986. + for mu in np.linspace(-7., 7., 5): + r = random.mtrand.vonmises(mu, 1, 50) + assert_(np.all(r > -np.pi) and np.all(r <= np.pi)) + + def test_hypergeometric_range(self): + # Test for ticket #921 + assert_(np.all(np.random.hypergeometric(3, 18, 11, size=10) < 4)) + assert_(np.all(np.random.hypergeometric(18, 3, 11, size=10) > 0)) + + # Test for ticket #5623 + args = [ + (2**20 - 2, 2**20 - 2, 2**20 - 2), # Check for 32-bit systems + ] + is_64bits = sys.maxsize > 2**32 + if is_64bits and sys.platform != 'win32': + # Check for 64-bit systems + args.append((2**40 - 2, 2**40 - 2, 2**40 - 2)) + for arg in args: + assert_(np.random.hypergeometric(*arg) > 0) + + def test_logseries_convergence(self): + # Test for ticket #923 + N = 1000 + np.random.seed(0) + rvsn = np.random.logseries(0.8, size=N) + # these two frequency counts should be close to theoretical + # numbers with this large sample + # theoretical large N result is 0.49706795 + freq = np.sum(rvsn == 1) / float(N) + msg = f'Frequency was {freq:f}, should be > 0.45' + assert_(freq > 0.45, msg) + # theoretical large N result is 0.19882718 + freq = np.sum(rvsn == 2) / float(N) + msg = f'Frequency was {freq:f}, should be < 0.23' + assert_(freq < 0.23, msg) + + def test_shuffle_mixed_dimension(self): + # Test for trac ticket #2074 + for t in [[1, 2, 3, None], + [(1, 1), (2, 2), (3, 3), None], + [1, (2, 2), (3, 3), None], + [(1, 1), 2, 3, None]]: + np.random.seed(12345) + shuffled = list(t) + random.shuffle(shuffled) + expected = np.array([t[0], t[3], t[1], t[2]], dtype=object) + assert_array_equal(np.array(shuffled, dtype=object), expected) + + def test_call_within_randomstate(self): + # Check that custom RandomState does not call into global state + m = np.random.RandomState() + res = np.array([0, 8, 7, 2, 1, 9, 4, 7, 0, 3]) + for i in range(3): + np.random.seed(i) + m.seed(4321) + # If m.state is not honored, the result will change + assert_array_equal(m.choice(10, size=10, p=np.ones(10)/10.), res) + + def test_multivariate_normal_size_types(self): + # Test for multivariate_normal issue with 'size' argument. + # Check that the multivariate_normal size argument can be a + # numpy integer. + np.random.multivariate_normal([0], [[0]], size=1) + np.random.multivariate_normal([0], [[0]], size=np.int_(1)) + np.random.multivariate_normal([0], [[0]], size=np.int64(1)) + + def test_beta_small_parameters(self): + # Test that beta with small a and b parameters does not produce + # NaNs due to roundoff errors causing 0 / 0, gh-5851 + np.random.seed(1234567890) + x = np.random.beta(0.0001, 0.0001, size=100) + assert_(not np.any(np.isnan(x)), 'Nans in np.random.beta') + + def test_choice_sum_of_probs_tolerance(self): + # The sum of probs should be 1.0 with some tolerance. + # For low precision dtypes the tolerance was too tight. + # See numpy github issue 6123. + np.random.seed(1234) + a = [1, 2, 3] + counts = [4, 4, 2] + for dt in np.float16, np.float32, np.float64: + probs = np.array(counts, dtype=dt) / sum(counts) + c = np.random.choice(a, p=probs) + assert_(c in a) + assert_raises(ValueError, np.random.choice, a, p=probs*0.9) + + def test_shuffle_of_array_of_different_length_strings(self): + # Test that permuting an array of different length strings + # will not cause a segfault on garbage collection + # Tests gh-7710 + np.random.seed(1234) + + a = np.array(['a', 'a' * 1000]) + + for _ in range(100): + np.random.shuffle(a) + + # Force Garbage Collection - should not segfault. + import gc + gc.collect() + + def test_shuffle_of_array_of_objects(self): + # Test that permuting an array of objects will not cause + # a segfault on garbage collection. + # See gh-7719 + np.random.seed(1234) + a = np.array([np.arange(1), np.arange(4)], dtype=object) + + for _ in range(1000): + np.random.shuffle(a) + + # Force Garbage Collection - should not segfault. + import gc + gc.collect() + + def test_permutation_subclass(self): + class N(np.ndarray): + pass + + np.random.seed(1) + orig = np.arange(3).view(N) + perm = np.random.permutation(orig) + assert_array_equal(perm, np.array([0, 2, 1])) + assert_array_equal(orig, np.arange(3).view(N)) + + class M: + a = np.arange(5) + + def __array__(self): + return self.a + + np.random.seed(1) + m = M() + perm = np.random.permutation(m) + assert_array_equal(perm, np.array([2, 1, 4, 0, 3])) + assert_array_equal(m.__array__(), np.arange(5)) diff --git a/venv/Lib/site-packages/numpy/random/tests/test_seed_sequence.py b/venv/Lib/site-packages/numpy/random/tests/test_seed_sequence.py new file mode 100644 index 0000000..f08cf80 --- /dev/null +++ b/venv/Lib/site-packages/numpy/random/tests/test_seed_sequence.py @@ -0,0 +1,80 @@ +import numpy as np +from numpy.testing import assert_array_equal, assert_array_compare + +from numpy.random import SeedSequence + + +def test_reference_data(): + """ Check that SeedSequence generates data the same as the C++ reference. + + https://gist.github.com/imneme/540829265469e673d045 + """ + inputs = [ + [3735928559, 195939070, 229505742, 305419896], + [3668361503, 4165561550, 1661411377, 3634257570], + [164546577, 4166754639, 1765190214, 1303880213], + [446610472, 3941463886, 522937693, 1882353782], + [1864922766, 1719732118, 3882010307, 1776744564], + [4141682960, 3310988675, 553637289, 902896340], + [1134851934, 2352871630, 3699409824, 2648159817], + [1240956131, 3107113773, 1283198141, 1924506131], + [2669565031, 579818610, 3042504477, 2774880435], + [2766103236, 2883057919, 4029656435, 862374500], + ] + outputs = [ + [3914649087, 576849849, 3593928901, 2229911004], + [2240804226, 3691353228, 1365957195, 2654016646], + [3562296087, 3191708229, 1147942216, 3726991905], + [1403443605, 3591372999, 1291086759, 441919183], + [1086200464, 2191331643, 560336446, 3658716651], + [3249937430, 2346751812, 847844327, 2996632307], + [2584285912, 4034195531, 3523502488, 169742686], + [959045797, 3875435559, 1886309314, 359682705], + [3978441347, 432478529, 3223635119, 138903045], + [296367413, 4262059219, 13109864, 3283683422], + ] + outputs64 = [ + [2477551240072187391, 9577394838764454085], + [15854241394484835714, 11398914698975566411], + [13708282465491374871, 16007308345579681096], + [15424829579845884309, 1898028439751125927], + [9411697742461147792, 15714068361935982142], + [10079222287618677782, 12870437757549876199], + [17326737873898640088, 729039288628699544], + [16644868984619524261, 1544825456798124994], + [1857481142255628931, 596584038813451439], + [18305404959516669237, 14103312907920476776], + ] + for seed, expected, expected64 in zip(inputs, outputs, outputs64): + expected = np.array(expected, dtype=np.uint32) + ss = SeedSequence(seed) + state = ss.generate_state(len(expected)) + assert_array_equal(state, expected) + state64 = ss.generate_state(len(expected64), dtype=np.uint64) + assert_array_equal(state64, expected64) + + +def test_zero_padding(): + """ Ensure that the implicit zero-padding does not cause problems. + """ + # Ensure that large integers are inserted in little-endian fashion to avoid + # trailing 0s. + ss0 = SeedSequence(42) + ss1 = SeedSequence(42 << 32) + assert_array_compare( + np.not_equal, + ss0.generate_state(4), + ss1.generate_state(4)) + + # Ensure backwards compatibility with the original 0.17 release for small + # integers and no spawn key. + expected42 = np.array([3444837047, 2669555309, 2046530742, 3581440988], + dtype=np.uint32) + assert_array_equal(SeedSequence(42).generate_state(4), expected42) + + # Regression test for gh-16539 to ensure that the implicit 0s don't + # conflict with spawn keys. + assert_array_compare( + np.not_equal, + SeedSequence(42, spawn_key=(0,)).generate_state(4), + expected42) diff --git a/venv/Lib/site-packages/numpy/random/tests/test_smoke.py b/venv/Lib/site-packages/numpy/random/tests/test_smoke.py new file mode 100644 index 0000000..909bfaa --- /dev/null +++ b/venv/Lib/site-packages/numpy/random/tests/test_smoke.py @@ -0,0 +1,806 @@ +import pickle +from functools import partial + +import numpy as np +import pytest +from numpy.testing import assert_equal, assert_, assert_array_equal +from numpy.random import (Generator, MT19937, PCG64, Philox, SFC64) + +@pytest.fixture(scope='module', + params=(np.bool_, np.int8, np.int16, np.int32, np.int64, + np.uint8, np.uint16, np.uint32, np.uint64)) +def dtype(request): + return request.param + + +def params_0(f): + val = f() + assert_(np.isscalar(val)) + val = f(10) + assert_(val.shape == (10,)) + val = f((10, 10)) + assert_(val.shape == (10, 10)) + val = f((10, 10, 10)) + assert_(val.shape == (10, 10, 10)) + val = f(size=(5, 5)) + assert_(val.shape == (5, 5)) + + +def params_1(f, bounded=False): + a = 5.0 + b = np.arange(2.0, 12.0) + c = np.arange(2.0, 102.0).reshape((10, 10)) + d = np.arange(2.0, 1002.0).reshape((10, 10, 10)) + e = np.array([2.0, 3.0]) + g = np.arange(2.0, 12.0).reshape((1, 10, 1)) + if bounded: + a = 0.5 + b = b / (1.5 * b.max()) + c = c / (1.5 * c.max()) + d = d / (1.5 * d.max()) + e = e / (1.5 * e.max()) + g = g / (1.5 * g.max()) + + # Scalar + f(a) + # Scalar - size + f(a, size=(10, 10)) + # 1d + f(b) + # 2d + f(c) + # 3d + f(d) + # 1d size + f(b, size=10) + # 2d - size - broadcast + f(e, size=(10, 2)) + # 3d - size + f(g, size=(10, 10, 10)) + + +def comp_state(state1, state2): + identical = True + if isinstance(state1, dict): + for key in state1: + identical &= comp_state(state1[key], state2[key]) + elif type(state1) != type(state2): + identical &= type(state1) == type(state2) + else: + if (isinstance(state1, (list, tuple, np.ndarray)) and isinstance( + state2, (list, tuple, np.ndarray))): + for s1, s2 in zip(state1, state2): + identical &= comp_state(s1, s2) + else: + identical &= state1 == state2 + return identical + + +def warmup(rg, n=None): + if n is None: + n = 11 + np.random.randint(0, 20) + rg.standard_normal(n) + rg.standard_normal(n) + rg.standard_normal(n, dtype=np.float32) + rg.standard_normal(n, dtype=np.float32) + rg.integers(0, 2 ** 24, n, dtype=np.uint64) + rg.integers(0, 2 ** 48, n, dtype=np.uint64) + rg.standard_gamma(11.0, n) + rg.standard_gamma(11.0, n, dtype=np.float32) + rg.random(n, dtype=np.float64) + rg.random(n, dtype=np.float32) + + +class RNG: + @classmethod + def setup_class(cls): + # Overridden in test classes. Place holder to silence IDE noise + cls.bit_generator = PCG64 + cls.advance = None + cls.seed = [12345] + cls.rg = Generator(cls.bit_generator(*cls.seed)) + cls.initial_state = cls.rg.bit_generator.state + cls.seed_vector_bits = 64 + cls._extra_setup() + + @classmethod + def _extra_setup(cls): + cls.vec_1d = np.arange(2.0, 102.0) + cls.vec_2d = np.arange(2.0, 102.0)[None, :] + cls.mat = np.arange(2.0, 102.0, 0.01).reshape((100, 100)) + cls.seed_error = TypeError + + def _reset_state(self): + self.rg.bit_generator.state = self.initial_state + + def test_init(self): + rg = Generator(self.bit_generator()) + state = rg.bit_generator.state + rg.standard_normal(1) + rg.standard_normal(1) + rg.bit_generator.state = state + new_state = rg.bit_generator.state + assert_(comp_state(state, new_state)) + + def test_advance(self): + state = self.rg.bit_generator.state + if hasattr(self.rg.bit_generator, 'advance'): + self.rg.bit_generator.advance(self.advance) + assert_(not comp_state(state, self.rg.bit_generator.state)) + else: + bitgen_name = self.rg.bit_generator.__class__.__name__ + pytest.skip(f'Advance is not supported by {bitgen_name}') + + def test_jump(self): + state = self.rg.bit_generator.state + if hasattr(self.rg.bit_generator, 'jumped'): + bit_gen2 = self.rg.bit_generator.jumped() + jumped_state = bit_gen2.state + assert_(not comp_state(state, jumped_state)) + self.rg.random(2 * 3 * 5 * 7 * 11 * 13 * 17) + self.rg.bit_generator.state = state + bit_gen3 = self.rg.bit_generator.jumped() + rejumped_state = bit_gen3.state + assert_(comp_state(jumped_state, rejumped_state)) + else: + bitgen_name = self.rg.bit_generator.__class__.__name__ + if bitgen_name not in ('SFC64',): + raise AttributeError(f'no "jumped" in {bitgen_name}') + pytest.skip(f'Jump is not supported by {bitgen_name}') + + def test_uniform(self): + r = self.rg.uniform(-1.0, 0.0, size=10) + assert_(len(r) == 10) + assert_((r > -1).all()) + assert_((r <= 0).all()) + + def test_uniform_array(self): + r = self.rg.uniform(np.array([-1.0] * 10), 0.0, size=10) + assert_(len(r) == 10) + assert_((r > -1).all()) + assert_((r <= 0).all()) + r = self.rg.uniform(np.array([-1.0] * 10), + np.array([0.0] * 10), size=10) + assert_(len(r) == 10) + assert_((r > -1).all()) + assert_((r <= 0).all()) + r = self.rg.uniform(-1.0, np.array([0.0] * 10), size=10) + assert_(len(r) == 10) + assert_((r > -1).all()) + assert_((r <= 0).all()) + + def test_random(self): + assert_(len(self.rg.random(10)) == 10) + params_0(self.rg.random) + + def test_standard_normal_zig(self): + assert_(len(self.rg.standard_normal(10)) == 10) + + def test_standard_normal(self): + assert_(len(self.rg.standard_normal(10)) == 10) + params_0(self.rg.standard_normal) + + def test_standard_gamma(self): + assert_(len(self.rg.standard_gamma(10, 10)) == 10) + assert_(len(self.rg.standard_gamma(np.array([10] * 10), 10)) == 10) + params_1(self.rg.standard_gamma) + + def test_standard_exponential(self): + assert_(len(self.rg.standard_exponential(10)) == 10) + params_0(self.rg.standard_exponential) + + def test_standard_exponential_float(self): + randoms = self.rg.standard_exponential(10, dtype='float32') + assert_(len(randoms) == 10) + assert randoms.dtype == np.float32 + params_0(partial(self.rg.standard_exponential, dtype='float32')) + + def test_standard_exponential_float_log(self): + randoms = self.rg.standard_exponential(10, dtype='float32', + method='inv') + assert_(len(randoms) == 10) + assert randoms.dtype == np.float32 + params_0(partial(self.rg.standard_exponential, dtype='float32', + method='inv')) + + def test_standard_cauchy(self): + assert_(len(self.rg.standard_cauchy(10)) == 10) + params_0(self.rg.standard_cauchy) + + def test_standard_t(self): + assert_(len(self.rg.standard_t(10, 10)) == 10) + params_1(self.rg.standard_t) + + def test_binomial(self): + assert_(self.rg.binomial(10, .5) >= 0) + assert_(self.rg.binomial(1000, .5) >= 0) + + def test_reset_state(self): + state = self.rg.bit_generator.state + int_1 = self.rg.integers(2**31) + self.rg.bit_generator.state = state + int_2 = self.rg.integers(2**31) + assert_(int_1 == int_2) + + def test_entropy_init(self): + rg = Generator(self.bit_generator()) + rg2 = Generator(self.bit_generator()) + assert_(not comp_state(rg.bit_generator.state, + rg2.bit_generator.state)) + + def test_seed(self): + rg = Generator(self.bit_generator(*self.seed)) + rg2 = Generator(self.bit_generator(*self.seed)) + rg.random() + rg2.random() + assert_(comp_state(rg.bit_generator.state, rg2.bit_generator.state)) + + def test_reset_state_gauss(self): + rg = Generator(self.bit_generator(*self.seed)) + rg.standard_normal() + state = rg.bit_generator.state + n1 = rg.standard_normal(size=10) + rg2 = Generator(self.bit_generator()) + rg2.bit_generator.state = state + n2 = rg2.standard_normal(size=10) + assert_array_equal(n1, n2) + + def test_reset_state_uint32(self): + rg = Generator(self.bit_generator(*self.seed)) + rg.integers(0, 2 ** 24, 120, dtype=np.uint32) + state = rg.bit_generator.state + n1 = rg.integers(0, 2 ** 24, 10, dtype=np.uint32) + rg2 = Generator(self.bit_generator()) + rg2.bit_generator.state = state + n2 = rg2.integers(0, 2 ** 24, 10, dtype=np.uint32) + assert_array_equal(n1, n2) + + def test_reset_state_float(self): + rg = Generator(self.bit_generator(*self.seed)) + rg.random(dtype='float32') + state = rg.bit_generator.state + n1 = rg.random(size=10, dtype='float32') + rg2 = Generator(self.bit_generator()) + rg2.bit_generator.state = state + n2 = rg2.random(size=10, dtype='float32') + assert_((n1 == n2).all()) + + def test_shuffle(self): + original = np.arange(200, 0, -1) + permuted = self.rg.permutation(original) + assert_((original != permuted).any()) + + def test_permutation(self): + original = np.arange(200, 0, -1) + permuted = self.rg.permutation(original) + assert_((original != permuted).any()) + + def test_beta(self): + vals = self.rg.beta(2.0, 2.0, 10) + assert_(len(vals) == 10) + vals = self.rg.beta(np.array([2.0] * 10), 2.0) + assert_(len(vals) == 10) + vals = self.rg.beta(2.0, np.array([2.0] * 10)) + assert_(len(vals) == 10) + vals = self.rg.beta(np.array([2.0] * 10), np.array([2.0] * 10)) + assert_(len(vals) == 10) + vals = self.rg.beta(np.array([2.0] * 10), np.array([[2.0]] * 10)) + assert_(vals.shape == (10, 10)) + + def test_bytes(self): + vals = self.rg.bytes(10) + assert_(len(vals) == 10) + + def test_chisquare(self): + vals = self.rg.chisquare(2.0, 10) + assert_(len(vals) == 10) + params_1(self.rg.chisquare) + + def test_exponential(self): + vals = self.rg.exponential(2.0, 10) + assert_(len(vals) == 10) + params_1(self.rg.exponential) + + def test_f(self): + vals = self.rg.f(3, 1000, 10) + assert_(len(vals) == 10) + + def test_gamma(self): + vals = self.rg.gamma(3, 2, 10) + assert_(len(vals) == 10) + + def test_geometric(self): + vals = self.rg.geometric(0.5, 10) + assert_(len(vals) == 10) + params_1(self.rg.exponential, bounded=True) + + def test_gumbel(self): + vals = self.rg.gumbel(2.0, 2.0, 10) + assert_(len(vals) == 10) + + def test_laplace(self): + vals = self.rg.laplace(2.0, 2.0, 10) + assert_(len(vals) == 10) + + def test_logitic(self): + vals = self.rg.logistic(2.0, 2.0, 10) + assert_(len(vals) == 10) + + def test_logseries(self): + vals = self.rg.logseries(0.5, 10) + assert_(len(vals) == 10) + + def test_negative_binomial(self): + vals = self.rg.negative_binomial(10, 0.2, 10) + assert_(len(vals) == 10) + + def test_noncentral_chisquare(self): + vals = self.rg.noncentral_chisquare(10, 2, 10) + assert_(len(vals) == 10) + + def test_noncentral_f(self): + vals = self.rg.noncentral_f(3, 1000, 2, 10) + assert_(len(vals) == 10) + vals = self.rg.noncentral_f(np.array([3] * 10), 1000, 2) + assert_(len(vals) == 10) + vals = self.rg.noncentral_f(3, np.array([1000] * 10), 2) + assert_(len(vals) == 10) + vals = self.rg.noncentral_f(3, 1000, np.array([2] * 10)) + assert_(len(vals) == 10) + + def test_normal(self): + vals = self.rg.normal(10, 0.2, 10) + assert_(len(vals) == 10) + + def test_pareto(self): + vals = self.rg.pareto(3.0, 10) + assert_(len(vals) == 10) + + def test_poisson(self): + vals = self.rg.poisson(10, 10) + assert_(len(vals) == 10) + vals = self.rg.poisson(np.array([10] * 10)) + assert_(len(vals) == 10) + params_1(self.rg.poisson) + + def test_power(self): + vals = self.rg.power(0.2, 10) + assert_(len(vals) == 10) + + def test_integers(self): + vals = self.rg.integers(10, 20, 10) + assert_(len(vals) == 10) + + def test_rayleigh(self): + vals = self.rg.rayleigh(0.2, 10) + assert_(len(vals) == 10) + params_1(self.rg.rayleigh, bounded=True) + + def test_vonmises(self): + vals = self.rg.vonmises(10, 0.2, 10) + assert_(len(vals) == 10) + + def test_wald(self): + vals = self.rg.wald(1.0, 1.0, 10) + assert_(len(vals) == 10) + + def test_weibull(self): + vals = self.rg.weibull(1.0, 10) + assert_(len(vals) == 10) + + def test_zipf(self): + vals = self.rg.zipf(10, 10) + assert_(len(vals) == 10) + vals = self.rg.zipf(self.vec_1d) + assert_(len(vals) == 100) + vals = self.rg.zipf(self.vec_2d) + assert_(vals.shape == (1, 100)) + vals = self.rg.zipf(self.mat) + assert_(vals.shape == (100, 100)) + + def test_hypergeometric(self): + vals = self.rg.hypergeometric(25, 25, 20) + assert_(np.isscalar(vals)) + vals = self.rg.hypergeometric(np.array([25] * 10), 25, 20) + assert_(vals.shape == (10,)) + + def test_triangular(self): + vals = self.rg.triangular(-5, 0, 5) + assert_(np.isscalar(vals)) + vals = self.rg.triangular(-5, np.array([0] * 10), 5) + assert_(vals.shape == (10,)) + + def test_multivariate_normal(self): + mean = [0, 0] + cov = [[1, 0], [0, 100]] # diagonal covariance + x = self.rg.multivariate_normal(mean, cov, 5000) + assert_(x.shape == (5000, 2)) + x_zig = self.rg.multivariate_normal(mean, cov, 5000) + assert_(x.shape == (5000, 2)) + x_inv = self.rg.multivariate_normal(mean, cov, 5000) + assert_(x.shape == (5000, 2)) + assert_((x_zig != x_inv).any()) + + def test_multinomial(self): + vals = self.rg.multinomial(100, [1.0 / 3, 2.0 / 3]) + assert_(vals.shape == (2,)) + vals = self.rg.multinomial(100, [1.0 / 3, 2.0 / 3], size=10) + assert_(vals.shape == (10, 2)) + + def test_dirichlet(self): + s = self.rg.dirichlet((10, 5, 3), 20) + assert_(s.shape == (20, 3)) + + def test_pickle(self): + pick = pickle.dumps(self.rg) + unpick = pickle.loads(pick) + assert_((type(self.rg) == type(unpick))) + assert_(comp_state(self.rg.bit_generator.state, + unpick.bit_generator.state)) + + pick = pickle.dumps(self.rg) + unpick = pickle.loads(pick) + assert_((type(self.rg) == type(unpick))) + assert_(comp_state(self.rg.bit_generator.state, + unpick.bit_generator.state)) + + def test_seed_array(self): + if self.seed_vector_bits is None: + bitgen_name = self.bit_generator.__name__ + pytest.skip(f'Vector seeding is not supported by {bitgen_name}') + + if self.seed_vector_bits == 32: + dtype = np.uint32 + else: + dtype = np.uint64 + seed = np.array([1], dtype=dtype) + bg = self.bit_generator(seed) + state1 = bg.state + bg = self.bit_generator(1) + state2 = bg.state + assert_(comp_state(state1, state2)) + + seed = np.arange(4, dtype=dtype) + bg = self.bit_generator(seed) + state1 = bg.state + bg = self.bit_generator(seed[0]) + state2 = bg.state + assert_(not comp_state(state1, state2)) + + seed = np.arange(1500, dtype=dtype) + bg = self.bit_generator(seed) + state1 = bg.state + bg = self.bit_generator(seed[0]) + state2 = bg.state + assert_(not comp_state(state1, state2)) + + seed = 2 ** np.mod(np.arange(1500, dtype=dtype), + self.seed_vector_bits - 1) + 1 + bg = self.bit_generator(seed) + state1 = bg.state + bg = self.bit_generator(seed[0]) + state2 = bg.state + assert_(not comp_state(state1, state2)) + + def test_uniform_float(self): + rg = Generator(self.bit_generator(12345)) + warmup(rg) + state = rg.bit_generator.state + r1 = rg.random(11, dtype=np.float32) + rg2 = Generator(self.bit_generator()) + warmup(rg2) + rg2.bit_generator.state = state + r2 = rg2.random(11, dtype=np.float32) + assert_array_equal(r1, r2) + assert_equal(r1.dtype, np.float32) + assert_(comp_state(rg.bit_generator.state, rg2.bit_generator.state)) + + def test_gamma_floats(self): + rg = Generator(self.bit_generator()) + warmup(rg) + state = rg.bit_generator.state + r1 = rg.standard_gamma(4.0, 11, dtype=np.float32) + rg2 = Generator(self.bit_generator()) + warmup(rg2) + rg2.bit_generator.state = state + r2 = rg2.standard_gamma(4.0, 11, dtype=np.float32) + assert_array_equal(r1, r2) + assert_equal(r1.dtype, np.float32) + assert_(comp_state(rg.bit_generator.state, rg2.bit_generator.state)) + + def test_normal_floats(self): + rg = Generator(self.bit_generator()) + warmup(rg) + state = rg.bit_generator.state + r1 = rg.standard_normal(11, dtype=np.float32) + rg2 = Generator(self.bit_generator()) + warmup(rg2) + rg2.bit_generator.state = state + r2 = rg2.standard_normal(11, dtype=np.float32) + assert_array_equal(r1, r2) + assert_equal(r1.dtype, np.float32) + assert_(comp_state(rg.bit_generator.state, rg2.bit_generator.state)) + + def test_normal_zig_floats(self): + rg = Generator(self.bit_generator()) + warmup(rg) + state = rg.bit_generator.state + r1 = rg.standard_normal(11, dtype=np.float32) + rg2 = Generator(self.bit_generator()) + warmup(rg2) + rg2.bit_generator.state = state + r2 = rg2.standard_normal(11, dtype=np.float32) + assert_array_equal(r1, r2) + assert_equal(r1.dtype, np.float32) + assert_(comp_state(rg.bit_generator.state, rg2.bit_generator.state)) + + def test_output_fill(self): + rg = self.rg + state = rg.bit_generator.state + size = (31, 7, 97) + existing = np.empty(size) + rg.bit_generator.state = state + rg.standard_normal(out=existing) + rg.bit_generator.state = state + direct = rg.standard_normal(size=size) + assert_equal(direct, existing) + + sized = np.empty(size) + rg.bit_generator.state = state + rg.standard_normal(out=sized, size=sized.shape) + + existing = np.empty(size, dtype=np.float32) + rg.bit_generator.state = state + rg.standard_normal(out=existing, dtype=np.float32) + rg.bit_generator.state = state + direct = rg.standard_normal(size=size, dtype=np.float32) + assert_equal(direct, existing) + + def test_output_filling_uniform(self): + rg = self.rg + state = rg.bit_generator.state + size = (31, 7, 97) + existing = np.empty(size) + rg.bit_generator.state = state + rg.random(out=existing) + rg.bit_generator.state = state + direct = rg.random(size=size) + assert_equal(direct, existing) + + existing = np.empty(size, dtype=np.float32) + rg.bit_generator.state = state + rg.random(out=existing, dtype=np.float32) + rg.bit_generator.state = state + direct = rg.random(size=size, dtype=np.float32) + assert_equal(direct, existing) + + def test_output_filling_exponential(self): + rg = self.rg + state = rg.bit_generator.state + size = (31, 7, 97) + existing = np.empty(size) + rg.bit_generator.state = state + rg.standard_exponential(out=existing) + rg.bit_generator.state = state + direct = rg.standard_exponential(size=size) + assert_equal(direct, existing) + + existing = np.empty(size, dtype=np.float32) + rg.bit_generator.state = state + rg.standard_exponential(out=existing, dtype=np.float32) + rg.bit_generator.state = state + direct = rg.standard_exponential(size=size, dtype=np.float32) + assert_equal(direct, existing) + + def test_output_filling_gamma(self): + rg = self.rg + state = rg.bit_generator.state + size = (31, 7, 97) + existing = np.zeros(size) + rg.bit_generator.state = state + rg.standard_gamma(1.0, out=existing) + rg.bit_generator.state = state + direct = rg.standard_gamma(1.0, size=size) + assert_equal(direct, existing) + + existing = np.zeros(size, dtype=np.float32) + rg.bit_generator.state = state + rg.standard_gamma(1.0, out=existing, dtype=np.float32) + rg.bit_generator.state = state + direct = rg.standard_gamma(1.0, size=size, dtype=np.float32) + assert_equal(direct, existing) + + def test_output_filling_gamma_broadcast(self): + rg = self.rg + state = rg.bit_generator.state + size = (31, 7, 97) + mu = np.arange(97.0) + 1.0 + existing = np.zeros(size) + rg.bit_generator.state = state + rg.standard_gamma(mu, out=existing) + rg.bit_generator.state = state + direct = rg.standard_gamma(mu, size=size) + assert_equal(direct, existing) + + existing = np.zeros(size, dtype=np.float32) + rg.bit_generator.state = state + rg.standard_gamma(mu, out=existing, dtype=np.float32) + rg.bit_generator.state = state + direct = rg.standard_gamma(mu, size=size, dtype=np.float32) + assert_equal(direct, existing) + + def test_output_fill_error(self): + rg = self.rg + size = (31, 7, 97) + existing = np.empty(size) + with pytest.raises(TypeError): + rg.standard_normal(out=existing, dtype=np.float32) + with pytest.raises(ValueError): + rg.standard_normal(out=existing[::3]) + existing = np.empty(size, dtype=np.float32) + with pytest.raises(TypeError): + rg.standard_normal(out=existing, dtype=np.float64) + + existing = np.zeros(size, dtype=np.float32) + with pytest.raises(TypeError): + rg.standard_gamma(1.0, out=existing, dtype=np.float64) + with pytest.raises(ValueError): + rg.standard_gamma(1.0, out=existing[::3], dtype=np.float32) + existing = np.zeros(size, dtype=np.float64) + with pytest.raises(TypeError): + rg.standard_gamma(1.0, out=existing, dtype=np.float32) + with pytest.raises(ValueError): + rg.standard_gamma(1.0, out=existing[::3]) + + def test_integers_broadcast(self, dtype): + if dtype == np.bool_: + upper = 2 + lower = 0 + else: + info = np.iinfo(dtype) + upper = int(info.max) + 1 + lower = info.min + self._reset_state() + a = self.rg.integers(lower, [upper] * 10, dtype=dtype) + self._reset_state() + b = self.rg.integers([lower] * 10, upper, dtype=dtype) + assert_equal(a, b) + self._reset_state() + c = self.rg.integers(lower, upper, size=10, dtype=dtype) + assert_equal(a, c) + self._reset_state() + d = self.rg.integers(np.array( + [lower] * 10), np.array([upper], dtype=object), size=10, + dtype=dtype) + assert_equal(a, d) + self._reset_state() + e = self.rg.integers( + np.array([lower] * 10), np.array([upper] * 10), size=10, + dtype=dtype) + assert_equal(a, e) + + self._reset_state() + a = self.rg.integers(0, upper, size=10, dtype=dtype) + self._reset_state() + b = self.rg.integers([upper] * 10, dtype=dtype) + assert_equal(a, b) + + def test_integers_numpy(self, dtype): + high = np.array([1]) + low = np.array([0]) + + out = self.rg.integers(low, high, dtype=dtype) + assert out.shape == (1,) + + out = self.rg.integers(low[0], high, dtype=dtype) + assert out.shape == (1,) + + out = self.rg.integers(low, high[0], dtype=dtype) + assert out.shape == (1,) + + def test_integers_broadcast_errors(self, dtype): + if dtype == np.bool_: + upper = 2 + lower = 0 + else: + info = np.iinfo(dtype) + upper = int(info.max) + 1 + lower = info.min + with pytest.raises(ValueError): + self.rg.integers(lower, [upper + 1] * 10, dtype=dtype) + with pytest.raises(ValueError): + self.rg.integers(lower - 1, [upper] * 10, dtype=dtype) + with pytest.raises(ValueError): + self.rg.integers([lower - 1], [upper] * 10, dtype=dtype) + with pytest.raises(ValueError): + self.rg.integers([0], [0], dtype=dtype) + + +class TestMT19937(RNG): + @classmethod + def setup_class(cls): + cls.bit_generator = MT19937 + cls.advance = None + cls.seed = [2 ** 21 + 2 ** 16 + 2 ** 5 + 1] + cls.rg = Generator(cls.bit_generator(*cls.seed)) + cls.initial_state = cls.rg.bit_generator.state + cls.seed_vector_bits = 32 + cls._extra_setup() + cls.seed_error = ValueError + + def test_numpy_state(self): + nprg = np.random.RandomState() + nprg.standard_normal(99) + state = nprg.get_state() + self.rg.bit_generator.state = state + state2 = self.rg.bit_generator.state + assert_((state[1] == state2['state']['key']).all()) + assert_((state[2] == state2['state']['pos'])) + + +class TestPhilox(RNG): + @classmethod + def setup_class(cls): + cls.bit_generator = Philox + cls.advance = 2**63 + 2**31 + 2**15 + 1 + cls.seed = [12345] + cls.rg = Generator(cls.bit_generator(*cls.seed)) + cls.initial_state = cls.rg.bit_generator.state + cls.seed_vector_bits = 64 + cls._extra_setup() + + +class TestSFC64(RNG): + @classmethod + def setup_class(cls): + cls.bit_generator = SFC64 + cls.advance = None + cls.seed = [12345] + cls.rg = Generator(cls.bit_generator(*cls.seed)) + cls.initial_state = cls.rg.bit_generator.state + cls.seed_vector_bits = 192 + cls._extra_setup() + + +class TestPCG64(RNG): + @classmethod + def setup_class(cls): + cls.bit_generator = PCG64 + cls.advance = 2**63 + 2**31 + 2**15 + 1 + cls.seed = [12345] + cls.rg = Generator(cls.bit_generator(*cls.seed)) + cls.initial_state = cls.rg.bit_generator.state + cls.seed_vector_bits = 64 + cls._extra_setup() + + +class TestDefaultRNG(RNG): + @classmethod + def setup_class(cls): + # This will duplicate some tests that directly instantiate a fresh + # Generator(), but that's okay. + cls.bit_generator = PCG64 + cls.advance = 2**63 + 2**31 + 2**15 + 1 + cls.seed = [12345] + cls.rg = np.random.default_rng(*cls.seed) + cls.initial_state = cls.rg.bit_generator.state + cls.seed_vector_bits = 64 + cls._extra_setup() + + def test_default_is_pcg64(self): + # In order to change the default BitGenerator, we'll go through + # a deprecation cycle to move to a different function. + assert_(isinstance(self.rg.bit_generator, PCG64)) + + def test_seed(self): + np.random.default_rng() + np.random.default_rng(None) + np.random.default_rng(12345) + np.random.default_rng(0) + np.random.default_rng(43660444402423911716352051725018508569) + np.random.default_rng([43660444402423911716352051725018508569, + 279705150948142787361475340226491943209]) + with pytest.raises(ValueError): + np.random.default_rng(-1) + with pytest.raises(ValueError): + np.random.default_rng([12345, -1]) diff --git a/venv/Lib/site-packages/numpy/rec.pyi b/venv/Lib/site-packages/numpy/rec.pyi new file mode 100644 index 0000000..883e2dd --- /dev/null +++ b/venv/Lib/site-packages/numpy/rec.pyi @@ -0,0 +1,12 @@ +from typing import Any, List + +__all__: List[str] + +record: Any +recarray: Any +format_parser: Any +fromarrays: Any +fromrecords: Any +fromstring: Any +fromfile: Any +array: Any diff --git a/venv/Lib/site-packages/numpy/setup.py b/venv/Lib/site-packages/numpy/setup.py new file mode 100644 index 0000000..cbf6335 --- /dev/null +++ b/venv/Lib/site-packages/numpy/setup.py @@ -0,0 +1,29 @@ +#!/usr/bin/env python3 + +def configuration(parent_package='',top_path=None): + from numpy.distutils.misc_util import Configuration + config = Configuration('numpy', parent_package, top_path) + + config.add_subpackage('compat') + config.add_subpackage('core') + config.add_subpackage('distutils') + config.add_subpackage('doc') + config.add_subpackage('f2py') + config.add_subpackage('fft') + config.add_subpackage('lib') + config.add_subpackage('linalg') + config.add_subpackage('ma') + config.add_subpackage('matrixlib') + config.add_subpackage('polynomial') + config.add_subpackage('random') + config.add_subpackage('testing') + config.add_subpackage('typing') + config.add_data_dir('doc') + config.add_data_files('py.typed') + config.add_data_files('*.pyi') + config.add_subpackage('tests') + config.make_config_py() # installs __config__.py + return config + +if __name__ == '__main__': + print('This is the wrong setup.py file to run') diff --git a/venv/Lib/site-packages/numpy/testing/__init__.py b/venv/Lib/site-packages/numpy/testing/__init__.py new file mode 100644 index 0000000..e1f8762 --- /dev/null +++ b/venv/Lib/site-packages/numpy/testing/__init__.py @@ -0,0 +1,20 @@ +"""Common test support for all numpy test scripts. + +This single module should provide all the common functionality for numpy tests +in a single location, so that test scripts can just import it and work right +away. + +""" +from unittest import TestCase + +from ._private.utils import * +from ._private import decorators as dec +from ._private.nosetester import ( + run_module_suite, NoseTester as Tester + ) + +__all__ = _private.utils.__all__ + ['TestCase', 'run_module_suite'] + +from numpy._pytesttester import PytestTester +test = PytestTester(__name__) +del PytestTester diff --git a/venv/Lib/site-packages/numpy/testing/__init__.pyi b/venv/Lib/site-packages/numpy/testing/__init__.pyi new file mode 100644 index 0000000..7dad2c9 --- /dev/null +++ b/venv/Lib/site-packages/numpy/testing/__init__.pyi @@ -0,0 +1,46 @@ +from typing import Any, List + +__all__: List[str] + +assert_equal: Any +assert_almost_equal: Any +assert_approx_equal: Any +assert_array_equal: Any +assert_array_less: Any +assert_string_equal: Any +assert_array_almost_equal: Any +assert_raises: Any +build_err_msg: Any +decorate_methods: Any +jiffies: Any +memusage: Any +print_assert_equal: Any +raises: Any +rundocs: Any +runstring: Any +verbose: Any +measure: Any +assert_: Any +assert_array_almost_equal_nulp: Any +assert_raises_regex: Any +assert_array_max_ulp: Any +assert_warns: Any +assert_no_warnings: Any +assert_allclose: Any +IgnoreException: Any +clear_and_catch_warnings: Any +SkipTest: Any +KnownFailureException: Any +temppath: Any +tempdir: Any +IS_PYPY: Any +HAS_REFCOUNT: Any +suppress_warnings: Any +assert_array_compare: Any +_assert_valid_refcount: Any +_gen_alignment_data: Any +assert_no_gc_cycles: Any +break_cycles: Any +HAS_LAPACK64: Any +TestCase: Any +run_module_suite: Any diff --git a/venv/Lib/site-packages/numpy/testing/_private/__init__.py b/venv/Lib/site-packages/numpy/testing/_private/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/venv/Lib/site-packages/numpy/testing/_private/decorators.py b/venv/Lib/site-packages/numpy/testing/_private/decorators.py new file mode 100644 index 0000000..4c87d1a --- /dev/null +++ b/venv/Lib/site-packages/numpy/testing/_private/decorators.py @@ -0,0 +1,284 @@ +""" +Decorators for labeling and modifying behavior of test objects. + +Decorators that merely return a modified version of the original +function object are straightforward. Decorators that return a new +function object need to use +:: + + nose.tools.make_decorator(original_function)(decorator) + +in returning the decorator, in order to preserve meta-data such as +function name, setup and teardown functions and so on - see +``nose.tools`` for more information. + +""" +import collections.abc + +from .utils import SkipTest, assert_warns, HAS_REFCOUNT + +__all__ = ['slow', 'setastest', 'skipif', 'knownfailureif', 'deprecated', + 'parametrize', '_needs_refcount',] + + +def slow(t): + """ + Label a test as 'slow'. + + The exact definition of a slow test is obviously both subjective and + hardware-dependent, but in general any individual test that requires more + than a second or two should be labeled as slow (the whole suite consists of + thousands of tests, so even a second is significant). + + Parameters + ---------- + t : callable + The test to label as slow. + + Returns + ------- + t : callable + The decorated test `t`. + + Examples + -------- + The `numpy.testing` module includes ``import decorators as dec``. + A test can be decorated as slow like this:: + + from numpy.testing import * + + @dec.slow + def test_big(self): + print('Big, slow test') + + """ + + t.slow = True + return t + +def setastest(tf=True): + """ + Signals to nose that this function is or is not a test. + + Parameters + ---------- + tf : bool + If True, specifies that the decorated callable is a test. + If False, specifies that the decorated callable is not a test. + Default is True. + + Notes + ----- + This decorator can't use the nose namespace, because it can be + called from a non-test module. See also ``istest`` and ``nottest`` in + ``nose.tools``. + + Examples + -------- + `setastest` can be used in the following way:: + + from numpy.testing import dec + + @dec.setastest(False) + def func_with_test_in_name(arg1, arg2): + pass + + """ + def set_test(t): + t.__test__ = tf + return t + return set_test + +def skipif(skip_condition, msg=None): + """ + Make function raise SkipTest exception if a given condition is true. + + If the condition is a callable, it is used at runtime to dynamically + make the decision. This is useful for tests that may require costly + imports, to delay the cost until the test suite is actually executed. + + Parameters + ---------- + skip_condition : bool or callable + Flag to determine whether to skip the decorated test. + msg : str, optional + Message to give on raising a SkipTest exception. Default is None. + + Returns + ------- + decorator : function + Decorator which, when applied to a function, causes SkipTest + to be raised when `skip_condition` is True, and the function + to be called normally otherwise. + + Notes + ----- + The decorator itself is decorated with the ``nose.tools.make_decorator`` + function in order to transmit function name, and various other metadata. + + """ + + def skip_decorator(f): + # Local import to avoid a hard nose dependency and only incur the + # import time overhead at actual test-time. + import nose + + # Allow for both boolean or callable skip conditions. + if isinstance(skip_condition, collections.abc.Callable): + skip_val = lambda: skip_condition() + else: + skip_val = lambda: skip_condition + + def get_msg(func,msg=None): + """Skip message with information about function being skipped.""" + if msg is None: + out = 'Test skipped due to test condition' + else: + out = msg + + return f'Skipping test: {func.__name__}: {out}' + + # We need to define *two* skippers because Python doesn't allow both + # return with value and yield inside the same function. + def skipper_func(*args, **kwargs): + """Skipper for normal test functions.""" + if skip_val(): + raise SkipTest(get_msg(f, msg)) + else: + return f(*args, **kwargs) + + def skipper_gen(*args, **kwargs): + """Skipper for test generators.""" + if skip_val(): + raise SkipTest(get_msg(f, msg)) + else: + yield from f(*args, **kwargs) + + # Choose the right skipper to use when building the actual decorator. + if nose.util.isgenerator(f): + skipper = skipper_gen + else: + skipper = skipper_func + + return nose.tools.make_decorator(f)(skipper) + + return skip_decorator + + +def knownfailureif(fail_condition, msg=None): + """ + Make function raise KnownFailureException exception if given condition is true. + + If the condition is a callable, it is used at runtime to dynamically + make the decision. This is useful for tests that may require costly + imports, to delay the cost until the test suite is actually executed. + + Parameters + ---------- + fail_condition : bool or callable + Flag to determine whether to mark the decorated test as a known + failure (if True) or not (if False). + msg : str, optional + Message to give on raising a KnownFailureException exception. + Default is None. + + Returns + ------- + decorator : function + Decorator, which, when applied to a function, causes + KnownFailureException to be raised when `fail_condition` is True, + and the function to be called normally otherwise. + + Notes + ----- + The decorator itself is decorated with the ``nose.tools.make_decorator`` + function in order to transmit function name, and various other metadata. + + """ + if msg is None: + msg = 'Test skipped due to known failure' + + # Allow for both boolean or callable known failure conditions. + if isinstance(fail_condition, collections.abc.Callable): + fail_val = lambda: fail_condition() + else: + fail_val = lambda: fail_condition + + def knownfail_decorator(f): + # Local import to avoid a hard nose dependency and only incur the + # import time overhead at actual test-time. + import nose + from .noseclasses import KnownFailureException + + def knownfailer(*args, **kwargs): + if fail_val(): + raise KnownFailureException(msg) + else: + return f(*args, **kwargs) + return nose.tools.make_decorator(f)(knownfailer) + + return knownfail_decorator + +def deprecated(conditional=True): + """ + Filter deprecation warnings while running the test suite. + + This decorator can be used to filter DeprecationWarning's, to avoid + printing them during the test suite run, while checking that the test + actually raises a DeprecationWarning. + + Parameters + ---------- + conditional : bool or callable, optional + Flag to determine whether to mark test as deprecated or not. If the + condition is a callable, it is used at runtime to dynamically make the + decision. Default is True. + + Returns + ------- + decorator : function + The `deprecated` decorator itself. + + Notes + ----- + .. versionadded:: 1.4.0 + + """ + def deprecate_decorator(f): + # Local import to avoid a hard nose dependency and only incur the + # import time overhead at actual test-time. + import nose + + def _deprecated_imp(*args, **kwargs): + # Poor man's replacement for the with statement + with assert_warns(DeprecationWarning): + f(*args, **kwargs) + + if isinstance(conditional, collections.abc.Callable): + cond = conditional() + else: + cond = conditional + if cond: + return nose.tools.make_decorator(f)(_deprecated_imp) + else: + return f + return deprecate_decorator + + +def parametrize(vars, input): + """ + Pytest compatibility class. This implements the simplest level of + pytest.mark.parametrize for use in nose as an aid in making the transition + to pytest. It achieves that by adding a dummy var parameter and ignoring + the doc_func parameter of the base class. It does not support variable + substitution by name, nor does it support nesting or classes. See the + pytest documentation for usage. + + .. versionadded:: 1.14.0 + + """ + from .parameterized import parameterized + + return parameterized(input) + +_needs_refcount = skipif(not HAS_REFCOUNT, "python has no sys.getrefcount") diff --git a/venv/Lib/site-packages/numpy/testing/_private/noseclasses.py b/venv/Lib/site-packages/numpy/testing/_private/noseclasses.py new file mode 100644 index 0000000..48fa4dc --- /dev/null +++ b/venv/Lib/site-packages/numpy/testing/_private/noseclasses.py @@ -0,0 +1,364 @@ +# These classes implement a doctest runner plugin for nose, a "known failure" +# error class, and a customized TestProgram for NumPy. + +# Because this module imports nose directly, it should not +# be used except by nosetester.py to avoid a general NumPy +# dependency on nose. +import os +import sys +import doctest +import inspect + +import numpy +import nose +from nose.plugins import doctests as npd +from nose.plugins.errorclass import ErrorClass, ErrorClassPlugin +from nose.plugins.base import Plugin +from nose.util import src +from .nosetester import get_package_name +from .utils import KnownFailureException, KnownFailureTest + + +# Some of the classes in this module begin with 'Numpy' to clearly distinguish +# them from the plethora of very similar names from nose/unittest/doctest + +#----------------------------------------------------------------------------- +# Modified version of the one in the stdlib, that fixes a python bug (doctests +# not found in extension modules, https://bugs.python.org/issue3158) +class NumpyDocTestFinder(doctest.DocTestFinder): + + def _from_module(self, module, object): + """ + Return true if the given object is defined in the given + module. + """ + if module is None: + return True + elif inspect.isfunction(object): + return module.__dict__ is object.__globals__ + elif inspect.isbuiltin(object): + return module.__name__ == object.__module__ + elif inspect.isclass(object): + return module.__name__ == object.__module__ + elif inspect.ismethod(object): + # This one may be a bug in cython that fails to correctly set the + # __module__ attribute of methods, but since the same error is easy + # to make by extension code writers, having this safety in place + # isn't such a bad idea + return module.__name__ == object.__self__.__class__.__module__ + elif inspect.getmodule(object) is not None: + return module is inspect.getmodule(object) + elif hasattr(object, '__module__'): + return module.__name__ == object.__module__ + elif isinstance(object, property): + return True # [XX] no way not be sure. + else: + raise ValueError("object must be a class or function") + + def _find(self, tests, obj, name, module, source_lines, globs, seen): + """ + Find tests for the given object and any contained objects, and + add them to `tests`. + """ + + doctest.DocTestFinder._find(self, tests, obj, name, module, + source_lines, globs, seen) + + # Below we re-run pieces of the above method with manual modifications, + # because the original code is buggy and fails to correctly identify + # doctests in extension modules. + + # Local shorthands + from inspect import ( + isroutine, isclass, ismodule, isfunction, ismethod + ) + + # Look for tests in a module's contained objects. + if ismodule(obj) and self._recurse: + for valname, val in obj.__dict__.items(): + valname1 = f'{name}.{valname}' + if ( (isroutine(val) or isclass(val)) + and self._from_module(module, val)): + + self._find(tests, val, valname1, module, source_lines, + globs, seen) + + # Look for tests in a class's contained objects. + if isclass(obj) and self._recurse: + for valname, val in obj.__dict__.items(): + # Special handling for staticmethod/classmethod. + if isinstance(val, staticmethod): + val = getattr(obj, valname) + if isinstance(val, classmethod): + val = getattr(obj, valname).__func__ + + # Recurse to methods, properties, and nested classes. + if ((isfunction(val) or isclass(val) or + ismethod(val) or isinstance(val, property)) and + self._from_module(module, val)): + valname = f'{name}.{valname}' + self._find(tests, val, valname, module, source_lines, + globs, seen) + + +# second-chance checker; if the default comparison doesn't +# pass, then see if the expected output string contains flags that +# tell us to ignore the output +class NumpyOutputChecker(doctest.OutputChecker): + def check_output(self, want, got, optionflags): + ret = doctest.OutputChecker.check_output(self, want, got, + optionflags) + if not ret: + if "#random" in want: + return True + + # it would be useful to normalize endianness so that + # bigendian machines don't fail all the tests (and there are + # actually some bigendian examples in the doctests). Let's try + # making them all little endian + got = got.replace("'>", "'<") + want = want.replace("'>", "'<") + + # try to normalize out 32 and 64 bit default int sizes + for sz in [4, 8]: + got = got.replace("'>> np.testing.nosetester.get_package_name('nonsense') + 'numpy' + + """ + + fullpath = filepath[:] + pkg_name = [] + while 'site-packages' in filepath or 'dist-packages' in filepath: + filepath, p2 = os.path.split(filepath) + if p2 in ('site-packages', 'dist-packages'): + break + pkg_name.append(p2) + + # if package name determination failed, just default to numpy/scipy + if not pkg_name: + if 'scipy' in fullpath: + return 'scipy' + else: + return 'numpy' + + # otherwise, reverse to get correct order and return + pkg_name.reverse() + + # don't include the outer egg directory + if pkg_name[0].endswith('.egg'): + pkg_name.pop(0) + + return '.'.join(pkg_name) + + +def run_module_suite(file_to_run=None, argv=None): + """ + Run a test module. + + Equivalent to calling ``$ nosetests `` from + the command line + + Parameters + ---------- + file_to_run : str, optional + Path to test module, or None. + By default, run the module from which this function is called. + argv : list of strings + Arguments to be passed to the nose test runner. ``argv[0]`` is + ignored. All command line arguments accepted by ``nosetests`` + will work. If it is the default value None, sys.argv is used. + + .. versionadded:: 1.9.0 + + Examples + -------- + Adding the following:: + + if __name__ == "__main__" : + run_module_suite(argv=sys.argv) + + at the end of a test module will run the tests when that module is + called in the python interpreter. + + Alternatively, calling:: + + >>> run_module_suite(file_to_run="numpy/tests/test_matlib.py") # doctest: +SKIP + + from an interpreter will run all the test routine in 'test_matlib.py'. + """ + if file_to_run is None: + f = sys._getframe(1) + file_to_run = f.f_locals.get('__file__', None) + if file_to_run is None: + raise AssertionError + + if argv is None: + argv = sys.argv + [file_to_run] + else: + argv = argv + [file_to_run] + + nose = import_nose() + from .noseclasses import KnownFailurePlugin + nose.run(argv=argv, addplugins=[KnownFailurePlugin()]) + + +class NoseTester: + """ + Nose test runner. + + This class is made available as numpy.testing.Tester, and a test function + is typically added to a package's __init__.py like so:: + + from numpy.testing import Tester + test = Tester().test + + Calling this test function finds and runs all tests associated with the + package and all its sub-packages. + + Attributes + ---------- + package_path : str + Full path to the package to test. + package_name : str + Name of the package to test. + + Parameters + ---------- + package : module, str or None, optional + The package to test. If a string, this should be the full path to + the package. If None (default), `package` is set to the module from + which `NoseTester` is initialized. + raise_warnings : None, str or sequence of warnings, optional + This specifies which warnings to configure as 'raise' instead + of being shown once during the test execution. Valid strings are: + + - "develop" : equals ``(Warning,)`` + - "release" : equals ``()``, don't raise on any warnings. + + Default is "release". + depth : int, optional + If `package` is None, then this can be used to initialize from the + module of the caller of (the caller of (...)) the code that + initializes `NoseTester`. Default of 0 means the module of the + immediate caller; higher values are useful for utility routines that + want to initialize `NoseTester` objects on behalf of other code. + + """ + def __init__(self, package=None, raise_warnings="release", depth=0, + check_fpu_mode=False): + # Back-compat: 'None' used to mean either "release" or "develop" + # depending on whether this was a release or develop version of + # numpy. Those semantics were fine for testing numpy, but not so + # helpful for downstream projects like scipy that use + # numpy.testing. (They want to set this based on whether *they* are a + # release or develop version, not whether numpy is.) So we continue to + # accept 'None' for back-compat, but it's now just an alias for the + # default "release". + if raise_warnings is None: + raise_warnings = "release" + + package_name = None + if package is None: + f = sys._getframe(1 + depth) + package_path = f.f_locals.get('__file__', None) + if package_path is None: + raise AssertionError + package_path = os.path.dirname(package_path) + package_name = f.f_locals.get('__name__', None) + elif isinstance(package, type(os)): + package_path = os.path.dirname(package.__file__) + package_name = getattr(package, '__name__', None) + else: + package_path = str(package) + + self.package_path = package_path + + # Find the package name under test; this name is used to limit coverage + # reporting (if enabled). + if package_name is None: + package_name = get_package_name(package_path) + self.package_name = package_name + + # Set to "release" in constructor in maintenance branches. + self.raise_warnings = raise_warnings + + # Whether to check for FPU mode changes + self.check_fpu_mode = check_fpu_mode + + def _test_argv(self, label, verbose, extra_argv): + ''' Generate argv for nosetest command + + Parameters + ---------- + label : {'fast', 'full', '', attribute identifier}, optional + see ``test`` docstring + verbose : int, optional + Verbosity value for test outputs, in the range 1-10. Default is 1. + extra_argv : list, optional + List with any extra arguments to pass to nosetests. + + Returns + ------- + argv : list + command line arguments that will be passed to nose + ''' + argv = [__file__, self.package_path, '-s'] + if label and label != 'full': + if not isinstance(label, str): + raise TypeError('Selection label should be a string') + if label == 'fast': + label = 'not slow' + argv += ['-A', label] + argv += ['--verbosity', str(verbose)] + + # When installing with setuptools, and also in some other cases, the + # test_*.py files end up marked +x executable. Nose, by default, does + # not run files marked with +x as they might be scripts. However, in + # our case nose only looks for test_*.py files under the package + # directory, which should be safe. + argv += ['--exe'] + + if extra_argv: + argv += extra_argv + return argv + + def _show_system_info(self): + nose = import_nose() + + import numpy + print(f'NumPy version {numpy.__version__}') + relaxed_strides = numpy.ones((10, 1), order="C").flags.f_contiguous + print("NumPy relaxed strides checking option:", relaxed_strides) + npdir = os.path.dirname(numpy.__file__) + print(f'NumPy is installed in {npdir}') + + if 'scipy' in self.package_name: + import scipy + print(f'SciPy version {scipy.__version__}') + spdir = os.path.dirname(scipy.__file__) + print(f'SciPy is installed in {spdir}') + + pyversion = sys.version.replace('\n', '') + print(f'Python version {pyversion}') + print("nose version %d.%d.%d" % nose.__versioninfo__) + + def _get_custom_doctester(self): + """ Return instantiated plugin for doctests + + Allows subclassing of this class to override doctester + + A return value of None means use the nose builtin doctest plugin + """ + from .noseclasses import NumpyDoctest + return NumpyDoctest() + + def prepare_test_args(self, label='fast', verbose=1, extra_argv=None, + doctests=False, coverage=False, timer=False): + """ + Run tests for module using nose. + + This method does the heavy lifting for the `test` method. It takes all + the same arguments, for details see `test`. + + See Also + -------- + test + + """ + # fail with nice error message if nose is not present + import_nose() + # compile argv + argv = self._test_argv(label, verbose, extra_argv) + # our way of doing coverage + if coverage: + argv += [f'--cover-package={self.package_name}', '--with-coverage', + '--cover-tests', '--cover-erase'] + + if timer: + if timer is True: + argv += ['--with-timer'] + elif isinstance(timer, int): + argv += ['--with-timer', '--timer-top-n', str(timer)] + + # construct list of plugins + import nose.plugins.builtin + from nose.plugins import EntryPointPluginManager + from .noseclasses import (KnownFailurePlugin, Unplugger, + FPUModeCheckPlugin) + plugins = [KnownFailurePlugin()] + plugins += [p() for p in nose.plugins.builtin.plugins] + if self.check_fpu_mode: + plugins += [FPUModeCheckPlugin()] + argv += ["--with-fpumodecheckplugin"] + try: + # External plugins (like nose-timer) + entrypoint_manager = EntryPointPluginManager() + entrypoint_manager.loadPlugins() + plugins += [p for p in entrypoint_manager.plugins] + except ImportError: + # Relies on pkg_resources, not a hard dependency + pass + + # add doctesting if required + doctest_argv = '--with-doctest' in argv + if doctests == False and doctest_argv: + doctests = True + plug = self._get_custom_doctester() + if plug is None: + # use standard doctesting + if doctests and not doctest_argv: + argv += ['--with-doctest'] + else: # custom doctesting + if doctest_argv: # in fact the unplugger would take care of this + argv.remove('--with-doctest') + plugins += [Unplugger('doctest'), plug] + if doctests: + argv += ['--with-' + plug.name] + return argv, plugins + + def test(self, label='fast', verbose=1, extra_argv=None, + doctests=False, coverage=False, raise_warnings=None, + timer=False): + """ + Run tests for module using nose. + + Parameters + ---------- + label : {'fast', 'full', '', attribute identifier}, optional + Identifies the tests to run. This can be a string to pass to + the nosetests executable with the '-A' option, or one of several + special values. Special values are: + + * 'fast' - the default - which corresponds to the ``nosetests -A`` + option of 'not slow'. + * 'full' - fast (as above) and slow tests as in the + 'no -A' option to nosetests - this is the same as ''. + * None or '' - run all tests. + * attribute_identifier - string passed directly to nosetests as '-A'. + + verbose : int, optional + Verbosity value for test outputs, in the range 1-10. Default is 1. + extra_argv : list, optional + List with any extra arguments to pass to nosetests. + doctests : bool, optional + If True, run doctests in module. Default is False. + coverage : bool, optional + If True, report coverage of NumPy code. Default is False. + (This requires the + `coverage module `_). + raise_warnings : None, str or sequence of warnings, optional + This specifies which warnings to configure as 'raise' instead + of being shown once during the test execution. Valid strings are: + + * "develop" : equals ``(Warning,)`` + * "release" : equals ``()``, do not raise on any warnings. + timer : bool or int, optional + Timing of individual tests with ``nose-timer`` (which needs to be + installed). If True, time tests and report on all of them. + If an integer (say ``N``), report timing results for ``N`` slowest + tests. + + Returns + ------- + result : object + Returns the result of running the tests as a + ``nose.result.TextTestResult`` object. + + Notes + ----- + Each NumPy module exposes `test` in its namespace to run all tests for it. + For example, to run all tests for numpy.lib: + + >>> np.lib.test() #doctest: +SKIP + + Examples + -------- + >>> result = np.lib.test() #doctest: +SKIP + Running unit tests for numpy.lib + ... + Ran 976 tests in 3.933s + + OK + + >>> result.errors #doctest: +SKIP + [] + >>> result.knownfail #doctest: +SKIP + [] + """ + + # cap verbosity at 3 because nose becomes *very* verbose beyond that + verbose = min(verbose, 3) + + from . import utils + utils.verbose = verbose + + argv, plugins = self.prepare_test_args( + label, verbose, extra_argv, doctests, coverage, timer) + + if doctests: + print(f'Running unit tests and doctests for {self.package_name}') + else: + print(f'Running unit tests for {self.package_name}') + + self._show_system_info() + + # reset doctest state on every run + import doctest + doctest.master = None + + if raise_warnings is None: + raise_warnings = self.raise_warnings + + _warn_opts = dict(develop=(Warning,), + release=()) + if isinstance(raise_warnings, str): + raise_warnings = _warn_opts[raise_warnings] + + with suppress_warnings("location") as sup: + # Reset the warning filters to the default state, + # so that running the tests is more repeatable. + warnings.resetwarnings() + # Set all warnings to 'warn', this is because the default 'once' + # has the bad property of possibly shadowing later warnings. + warnings.filterwarnings('always') + # Force the requested warnings to raise + for warningtype in raise_warnings: + warnings.filterwarnings('error', category=warningtype) + # Filter out annoying import messages. + sup.filter(message='Not importing directory') + sup.filter(message="numpy.dtype size changed") + sup.filter(message="numpy.ufunc size changed") + sup.filter(category=np.ModuleDeprecationWarning) + # Filter out boolean '-' deprecation messages. This allows + # older versions of scipy to test without a flood of messages. + sup.filter(message=".*boolean negative.*") + sup.filter(message=".*boolean subtract.*") + # Filter out distutils cpu warnings (could be localized to + # distutils tests). ASV has problems with top level import, + # so fetch module for suppression here. + with warnings.catch_warnings(): + warnings.simplefilter("always") + from ...distutils import cpuinfo + sup.filter(category=UserWarning, module=cpuinfo) + # Filter out some deprecation warnings inside nose 1.3.7 when run + # on python 3.5b2. See + # https://github.com/nose-devs/nose/issues/929 + # Note: it is hard to filter based on module for sup (lineno could + # be implemented). + warnings.filterwarnings("ignore", message=".*getargspec.*", + category=DeprecationWarning, + module=r"nose\.") + + from .noseclasses import NumpyTestProgram + + t = NumpyTestProgram(argv=argv, exit=False, plugins=plugins) + + return t.result + + def bench(self, label='fast', verbose=1, extra_argv=None): + """ + Run benchmarks for module using nose. + + Parameters + ---------- + label : {'fast', 'full', '', attribute identifier}, optional + Identifies the benchmarks to run. This can be a string to pass to + the nosetests executable with the '-A' option, or one of several + special values. Special values are: + + * 'fast' - the default - which corresponds to the ``nosetests -A`` + option of 'not slow'. + * 'full' - fast (as above) and slow benchmarks as in the + 'no -A' option to nosetests - this is the same as ''. + * None or '' - run all tests. + * attribute_identifier - string passed directly to nosetests as '-A'. + + verbose : int, optional + Verbosity value for benchmark outputs, in the range 1-10. Default is 1. + extra_argv : list, optional + List with any extra arguments to pass to nosetests. + + Returns + ------- + success : bool + Returns True if running the benchmarks works, False if an error + occurred. + + Notes + ----- + Benchmarks are like tests, but have names starting with "bench" instead + of "test", and can be found under the "benchmarks" sub-directory of the + module. + + Each NumPy module exposes `bench` in its namespace to run all benchmarks + for it. + + Examples + -------- + >>> success = np.lib.bench() #doctest: +SKIP + Running benchmarks for numpy.lib + ... + using 562341 items: + unique: + 0.11 + unique1d: + 0.11 + ratio: 1.0 + nUnique: 56230 == 56230 + ... + OK + + >>> success #doctest: +SKIP + True + + """ + + print(f'Running benchmarks for {self.package_name}') + self._show_system_info() + + argv = self._test_argv(label, verbose, extra_argv) + argv += ['--match', r'(?:^|[\\b_\\.%s-])[Bb]ench' % os.sep] + + # import nose or make informative error + nose = import_nose() + + # get plugin to disable doctests + from .noseclasses import Unplugger + add_plugins = [Unplugger('doctest')] + + return nose.run(argv=argv, addplugins=add_plugins) + + +def _numpy_tester(): + if hasattr(np, "__version__") and ".dev0" in np.__version__: + mode = "develop" + else: + mode = "release" + return NoseTester(raise_warnings=mode, depth=1, + check_fpu_mode=True) diff --git a/venv/Lib/site-packages/numpy/testing/_private/parameterized.py b/venv/Lib/site-packages/numpy/testing/_private/parameterized.py new file mode 100644 index 0000000..ac7db6c --- /dev/null +++ b/venv/Lib/site-packages/numpy/testing/_private/parameterized.py @@ -0,0 +1,444 @@ +""" +tl;dr: all code code is licensed under simplified BSD, unless stated otherwise. + +Unless stated otherwise in the source files, all code is copyright 2010 David +Wolever . All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +EVENT SHALL OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE +OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of David Wolever. + +""" +import re +import inspect +import warnings +from functools import wraps +from types import MethodType +from collections import namedtuple + +try: + from collections import OrderedDict as MaybeOrderedDict +except ImportError: + MaybeOrderedDict = dict + +from unittest import TestCase + +_param = namedtuple("param", "args kwargs") + +class param(_param): + """ Represents a single parameter to a test case. + + For example:: + + >>> p = param("foo", bar=16) + >>> p + param("foo", bar=16) + >>> p.args + ('foo', ) + >>> p.kwargs + {'bar': 16} + + Intended to be used as an argument to ``@parameterized``:: + + @parameterized([ + param("foo", bar=16), + ]) + def test_stuff(foo, bar=16): + pass + """ + + def __new__(cls, *args , **kwargs): + return _param.__new__(cls, args, kwargs) + + @classmethod + def explicit(cls, args=None, kwargs=None): + """ Creates a ``param`` by explicitly specifying ``args`` and + ``kwargs``:: + + >>> param.explicit([1,2,3]) + param(*(1, 2, 3)) + >>> param.explicit(kwargs={"foo": 42}) + param(*(), **{"foo": "42"}) + """ + args = args or () + kwargs = kwargs or {} + return cls(*args, **kwargs) + + @classmethod + def from_decorator(cls, args): + """ Returns an instance of ``param()`` for ``@parameterized`` argument + ``args``:: + + >>> param.from_decorator((42, )) + param(args=(42, ), kwargs={}) + >>> param.from_decorator("foo") + param(args=("foo", ), kwargs={}) + """ + if isinstance(args, param): + return args + elif isinstance(args, (str,)): + args = (args, ) + try: + return cls(*args) + except TypeError as e: + if "after * must be" not in str(e): + raise + raise TypeError( + "Parameters must be tuples, but %r is not (hint: use '(%r, )')" + %(args, args), + ) + + def __repr__(self): + return "param(*%r, **%r)" %self + + +class QuietOrderedDict(MaybeOrderedDict): + """ When OrderedDict is available, use it to make sure that the kwargs in + doc strings are consistently ordered. """ + __str__ = dict.__str__ + __repr__ = dict.__repr__ + + +def parameterized_argument_value_pairs(func, p): + """Return tuples of parameterized arguments and their values. + + This is useful if you are writing your own doc_func + function and need to know the values for each parameter name:: + + >>> def func(a, foo=None, bar=42, **kwargs): pass + >>> p = param(1, foo=7, extra=99) + >>> parameterized_argument_value_pairs(func, p) + [("a", 1), ("foo", 7), ("bar", 42), ("**kwargs", {"extra": 99})] + + If the function's first argument is named ``self`` then it will be + ignored:: + + >>> def func(self, a): pass + >>> p = param(1) + >>> parameterized_argument_value_pairs(func, p) + [("a", 1)] + + Additionally, empty ``*args`` or ``**kwargs`` will be ignored:: + + >>> def func(foo, *args): pass + >>> p = param(1) + >>> parameterized_argument_value_pairs(func, p) + [("foo", 1)] + >>> p = param(1, 16) + >>> parameterized_argument_value_pairs(func, p) + [("foo", 1), ("*args", (16, ))] + """ + argspec = inspect.getargspec(func) + arg_offset = 1 if argspec.args[:1] == ["self"] else 0 + + named_args = argspec.args[arg_offset:] + + result = list(zip(named_args, p.args)) + named_args = argspec.args[len(result) + arg_offset:] + varargs = p.args[len(result):] + + result.extend([ + (name, p.kwargs.get(name, default)) + for (name, default) + in zip(named_args, argspec.defaults or []) + ]) + + seen_arg_names = {n for (n, _) in result} + keywords = QuietOrderedDict(sorted([ + (name, p.kwargs[name]) + for name in p.kwargs + if name not in seen_arg_names + ])) + + if varargs: + result.append(("*%s" %(argspec.varargs, ), tuple(varargs))) + + if keywords: + result.append(("**%s" %(argspec.keywords, ), keywords)) + + return result + +def short_repr(x, n=64): + """ A shortened repr of ``x`` which is guaranteed to be ``unicode``:: + + >>> short_repr("foo") + u"foo" + >>> short_repr("123456789", n=4) + u"12...89" + """ + + x_repr = repr(x) + if isinstance(x_repr, bytes): + try: + x_repr = str(x_repr, "utf-8") + except UnicodeDecodeError: + x_repr = str(x_repr, "latin1") + if len(x_repr) > n: + x_repr = x_repr[:n//2] + "..." + x_repr[len(x_repr) - n//2:] + return x_repr + +def default_doc_func(func, num, p): + if func.__doc__ is None: + return None + + all_args_with_values = parameterized_argument_value_pairs(func, p) + + # Assumes that the function passed is a bound method. + descs = [f'{n}={short_repr(v)}' for n, v in all_args_with_values] + + # The documentation might be a multiline string, so split it + # and just work with the first string, ignoring the period + # at the end if there is one. + first, nl, rest = func.__doc__.lstrip().partition("\n") + suffix = "" + if first.endswith("."): + suffix = "." + first = first[:-1] + args = "%s[with %s]" %(len(first) and " " or "", ", ".join(descs)) + return "".join([first.rstrip(), args, suffix, nl, rest]) + +def default_name_func(func, num, p): + base_name = func.__name__ + name_suffix = "_%s" %(num, ) + if len(p.args) > 0 and isinstance(p.args[0], (str,)): + name_suffix += "_" + parameterized.to_safe_name(p.args[0]) + return base_name + name_suffix + + +# force nose for numpy purposes. +_test_runner_override = 'nose' +_test_runner_guess = False +_test_runners = set(["unittest", "unittest2", "nose", "nose2", "pytest"]) +_test_runner_aliases = { + "_pytest": "pytest", +} + +def set_test_runner(name): + global _test_runner_override + if name not in _test_runners: + raise TypeError( + "Invalid test runner: %r (must be one of: %s)" + %(name, ", ".join(_test_runners)), + ) + _test_runner_override = name + +def detect_runner(): + """ Guess which test runner we're using by traversing the stack and looking + for the first matching module. This *should* be reasonably safe, as + it's done during test discovery where the test runner should be the + stack frame immediately outside. """ + if _test_runner_override is not None: + return _test_runner_override + global _test_runner_guess + if _test_runner_guess is False: + stack = inspect.stack() + for record in reversed(stack): + frame = record[0] + module = frame.f_globals.get("__name__").partition(".")[0] + if module in _test_runner_aliases: + module = _test_runner_aliases[module] + if module in _test_runners: + _test_runner_guess = module + break + else: + _test_runner_guess = None + return _test_runner_guess + +class parameterized: + """ Parameterize a test case:: + + class TestInt: + @parameterized([ + ("A", 10), + ("F", 15), + param("10", 42, base=42) + ]) + def test_int(self, input, expected, base=16): + actual = int(input, base=base) + assert_equal(actual, expected) + + @parameterized([ + (2, 3, 5) + (3, 5, 8), + ]) + def test_add(a, b, expected): + assert_equal(a + b, expected) + """ + + def __init__(self, input, doc_func=None): + self.get_input = self.input_as_callable(input) + self.doc_func = doc_func or default_doc_func + + def __call__(self, test_func): + self.assert_not_in_testcase_subclass() + + @wraps(test_func) + def wrapper(test_self=None): + test_cls = test_self and type(test_self) + + original_doc = wrapper.__doc__ + for num, args in enumerate(wrapper.parameterized_input): + p = param.from_decorator(args) + unbound_func, nose_tuple = self.param_as_nose_tuple(test_self, test_func, num, p) + try: + wrapper.__doc__ = nose_tuple[0].__doc__ + # Nose uses `getattr(instance, test_func.__name__)` to get + # a method bound to the test instance (as opposed to a + # method bound to the instance of the class created when + # tests were being enumerated). Set a value here to make + # sure nose can get the correct test method. + if test_self is not None: + setattr(test_cls, test_func.__name__, unbound_func) + yield nose_tuple + finally: + if test_self is not None: + delattr(test_cls, test_func.__name__) + wrapper.__doc__ = original_doc + wrapper.parameterized_input = self.get_input() + wrapper.parameterized_func = test_func + test_func.__name__ = "_parameterized_original_%s" %(test_func.__name__, ) + return wrapper + + def param_as_nose_tuple(self, test_self, func, num, p): + nose_func = wraps(func)(lambda *args: func(*args[:-1], **args[-1])) + nose_func.__doc__ = self.doc_func(func, num, p) + # Track the unbound function because we need to setattr the unbound + # function onto the class for nose to work (see comments above), and + # Python 3 doesn't let us pull the function out of a bound method. + unbound_func = nose_func + if test_self is not None: + nose_func = MethodType(nose_func, test_self) + return unbound_func, (nose_func, ) + p.args + (p.kwargs or {}, ) + + def assert_not_in_testcase_subclass(self): + parent_classes = self._terrible_magic_get_defining_classes() + if any(issubclass(cls, TestCase) for cls in parent_classes): + raise Exception("Warning: '@parameterized' tests won't work " + "inside subclasses of 'TestCase' - use " + "'@parameterized.expand' instead.") + + def _terrible_magic_get_defining_classes(self): + """ Returns the set of parent classes of the class currently being defined. + Will likely only work if called from the ``parameterized`` decorator. + This function is entirely @brandon_rhodes's fault, as he suggested + the implementation: http://stackoverflow.com/a/8793684/71522 + """ + stack = inspect.stack() + if len(stack) <= 4: + return [] + frame = stack[4] + code_context = frame[4] and frame[4][0].strip() + if not (code_context and code_context.startswith("class ")): + return [] + _, _, parents = code_context.partition("(") + parents, _, _ = parents.partition(")") + return eval("[" + parents + "]", frame[0].f_globals, frame[0].f_locals) + + @classmethod + def input_as_callable(cls, input): + if callable(input): + return lambda: cls.check_input_values(input()) + input_values = cls.check_input_values(input) + return lambda: input_values + + @classmethod + def check_input_values(cls, input_values): + # Explicitly convert non-list inputs to a list so that: + # 1. A helpful exception will be raised if they aren't iterable, and + # 2. Generators are unwrapped exactly once (otherwise `nosetests + # --processes=n` has issues; see: + # https://github.com/wolever/nose-parameterized/pull/31) + if not isinstance(input_values, list): + input_values = list(input_values) + return [ param.from_decorator(p) for p in input_values ] + + @classmethod + def expand(cls, input, name_func=None, doc_func=None, **legacy): + """ A "brute force" method of parameterizing test cases. Creates new + test cases and injects them into the namespace that the wrapped + function is being defined in. Useful for parameterizing tests in + subclasses of 'UnitTest', where Nose test generators don't work. + + >>> @parameterized.expand([("foo", 1, 2)]) + ... def test_add1(name, input, expected): + ... actual = add1(input) + ... assert_equal(actual, expected) + ... + >>> locals() + ... 'test_add1_foo_0': ... + >>> + """ + + if "testcase_func_name" in legacy: + warnings.warn("testcase_func_name= is deprecated; use name_func=", + DeprecationWarning, stacklevel=2) + if not name_func: + name_func = legacy["testcase_func_name"] + + if "testcase_func_doc" in legacy: + warnings.warn("testcase_func_doc= is deprecated; use doc_func=", + DeprecationWarning, stacklevel=2) + if not doc_func: + doc_func = legacy["testcase_func_doc"] + + doc_func = doc_func or default_doc_func + name_func = name_func or default_name_func + + def parameterized_expand_wrapper(f, instance=None): + stack = inspect.stack() + frame = stack[1] + frame_locals = frame[0].f_locals + + parameters = cls.input_as_callable(input)() + for num, p in enumerate(parameters): + name = name_func(f, num, p) + frame_locals[name] = cls.param_as_standalone_func(p, f, name) + frame_locals[name].__doc__ = doc_func(f, num, p) + + f.__test__ = False + return parameterized_expand_wrapper + + @classmethod + def param_as_standalone_func(cls, p, func, name): + @wraps(func) + def standalone_func(*a): + return func(*(a + p.args), **p.kwargs) + standalone_func.__name__ = name + + # place_as is used by py.test to determine what source file should be + # used for this test. + standalone_func.place_as = func + + # Remove __wrapped__ because py.test will try to look at __wrapped__ + # to determine which parameters should be used with this test case, + # and obviously we don't need it to do any parameterization. + try: + del standalone_func.__wrapped__ + except AttributeError: + pass + return standalone_func + + @classmethod + def to_safe_name(cls, s): + return str(re.sub("[^a-zA-Z0-9_]+", "_", s)) diff --git a/venv/Lib/site-packages/numpy/testing/_private/utils.py b/venv/Lib/site-packages/numpy/testing/_private/utils.py new file mode 100644 index 0000000..e974bbd --- /dev/null +++ b/venv/Lib/site-packages/numpy/testing/_private/utils.py @@ -0,0 +1,2519 @@ +""" +Utility function to facilitate testing. + +""" +import os +import sys +import platform +import re +import gc +import operator +import warnings +from functools import partial, wraps +import shutil +import contextlib +from tempfile import mkdtemp, mkstemp +from unittest.case import SkipTest +from warnings import WarningMessage +import pprint + +from numpy.core import( + intp, float32, empty, arange, array_repr, ndarray, isnat, array) +import numpy.linalg.lapack_lite + +from io import StringIO + +__all__ = [ + 'assert_equal', 'assert_almost_equal', 'assert_approx_equal', + 'assert_array_equal', 'assert_array_less', 'assert_string_equal', + 'assert_array_almost_equal', 'assert_raises', 'build_err_msg', + 'decorate_methods', 'jiffies', 'memusage', 'print_assert_equal', + 'raises', 'rundocs', 'runstring', 'verbose', 'measure', + 'assert_', 'assert_array_almost_equal_nulp', 'assert_raises_regex', + 'assert_array_max_ulp', 'assert_warns', 'assert_no_warnings', + 'assert_allclose', 'IgnoreException', 'clear_and_catch_warnings', + 'SkipTest', 'KnownFailureException', 'temppath', 'tempdir', 'IS_PYPY', + 'HAS_REFCOUNT', 'suppress_warnings', 'assert_array_compare', + '_assert_valid_refcount', '_gen_alignment_data', 'assert_no_gc_cycles', + 'break_cycles', 'HAS_LAPACK64' + ] + + +class KnownFailureException(Exception): + '''Raise this exception to mark a test as a known failing test.''' + pass + + +KnownFailureTest = KnownFailureException # backwards compat +verbose = 0 + +IS_PYPY = platform.python_implementation() == 'PyPy' +HAS_REFCOUNT = getattr(sys, 'getrefcount', None) is not None +HAS_LAPACK64 = numpy.linalg.lapack_lite._ilp64 + + +def import_nose(): + """ Import nose only when needed. + """ + nose_is_good = True + minimum_nose_version = (1, 0, 0) + try: + import nose + except ImportError: + nose_is_good = False + else: + if nose.__versioninfo__ < minimum_nose_version: + nose_is_good = False + + if not nose_is_good: + msg = ('Need nose >= %d.%d.%d for tests - see ' + 'https://nose.readthedocs.io' % + minimum_nose_version) + raise ImportError(msg) + + return nose + + +def assert_(val, msg=''): + """ + Assert that works in release mode. + Accepts callable msg to allow deferring evaluation until failure. + + The Python built-in ``assert`` does not work when executing code in + optimized mode (the ``-O`` flag) - no byte-code is generated for it. + + For documentation on usage, refer to the Python documentation. + + """ + __tracebackhide__ = True # Hide traceback for py.test + if not val: + try: + smsg = msg() + except TypeError: + smsg = msg + raise AssertionError(smsg) + + +def gisnan(x): + """like isnan, but always raise an error if type not supported instead of + returning a TypeError object. + + Notes + ----- + isnan and other ufunc sometimes return a NotImplementedType object instead + of raising any exception. This function is a wrapper to make sure an + exception is always raised. + + This should be removed once this problem is solved at the Ufunc level.""" + from numpy.core import isnan + st = isnan(x) + if isinstance(st, type(NotImplemented)): + raise TypeError("isnan not supported for this type") + return st + + +def gisfinite(x): + """like isfinite, but always raise an error if type not supported instead + of returning a TypeError object. + + Notes + ----- + isfinite and other ufunc sometimes return a NotImplementedType object + instead of raising any exception. This function is a wrapper to make sure + an exception is always raised. + + This should be removed once this problem is solved at the Ufunc level.""" + from numpy.core import isfinite, errstate + with errstate(invalid='ignore'): + st = isfinite(x) + if isinstance(st, type(NotImplemented)): + raise TypeError("isfinite not supported for this type") + return st + + +def gisinf(x): + """like isinf, but always raise an error if type not supported instead of + returning a TypeError object. + + Notes + ----- + isinf and other ufunc sometimes return a NotImplementedType object instead + of raising any exception. This function is a wrapper to make sure an + exception is always raised. + + This should be removed once this problem is solved at the Ufunc level.""" + from numpy.core import isinf, errstate + with errstate(invalid='ignore'): + st = isinf(x) + if isinstance(st, type(NotImplemented)): + raise TypeError("isinf not supported for this type") + return st + + +if os.name == 'nt': + # Code "stolen" from enthought/debug/memusage.py + def GetPerformanceAttributes(object, counter, instance=None, + inum=-1, format=None, machine=None): + # NOTE: Many counters require 2 samples to give accurate results, + # including "% Processor Time" (as by definition, at any instant, a + # thread's CPU usage is either 0 or 100). To read counters like this, + # you should copy this function, but keep the counter open, and call + # CollectQueryData() each time you need to know. + # See http://msdn.microsoft.com/library/en-us/dnperfmo/html/perfmonpt2.asp (dead link) + # My older explanation for this was that the "AddCounter" process + # forced the CPU to 100%, but the above makes more sense :) + import win32pdh + if format is None: + format = win32pdh.PDH_FMT_LONG + path = win32pdh.MakeCounterPath( (machine, object, instance, None, + inum, counter)) + hq = win32pdh.OpenQuery() + try: + hc = win32pdh.AddCounter(hq, path) + try: + win32pdh.CollectQueryData(hq) + type, val = win32pdh.GetFormattedCounterValue(hc, format) + return val + finally: + win32pdh.RemoveCounter(hc) + finally: + win32pdh.CloseQuery(hq) + + def memusage(processName="python", instance=0): + # from win32pdhutil, part of the win32all package + import win32pdh + return GetPerformanceAttributes("Process", "Virtual Bytes", + processName, instance, + win32pdh.PDH_FMT_LONG, None) +elif sys.platform[:5] == 'linux': + + def memusage(_proc_pid_stat=f'/proc/{os.getpid()}/stat'): + """ + Return virtual memory size in bytes of the running python. + + """ + try: + with open(_proc_pid_stat, 'r') as f: + l = f.readline().split(' ') + return int(l[22]) + except Exception: + return +else: + def memusage(): + """ + Return memory usage of running python. [Not implemented] + + """ + raise NotImplementedError + + +if sys.platform[:5] == 'linux': + def jiffies(_proc_pid_stat=f'/proc/{os.getpid()}/stat', _load_time=[]): + """ + Return number of jiffies elapsed. + + Return number of jiffies (1/100ths of a second) that this + process has been scheduled in user mode. See man 5 proc. + + """ + import time + if not _load_time: + _load_time.append(time.time()) + try: + with open(_proc_pid_stat, 'r') as f: + l = f.readline().split(' ') + return int(l[13]) + except Exception: + return int(100*(time.time()-_load_time[0])) +else: + # os.getpid is not in all platforms available. + # Using time is safe but inaccurate, especially when process + # was suspended or sleeping. + def jiffies(_load_time=[]): + """ + Return number of jiffies elapsed. + + Return number of jiffies (1/100ths of a second) that this + process has been scheduled in user mode. See man 5 proc. + + """ + import time + if not _load_time: + _load_time.append(time.time()) + return int(100*(time.time()-_load_time[0])) + + +def build_err_msg(arrays, err_msg, header='Items are not equal:', + verbose=True, names=('ACTUAL', 'DESIRED'), precision=8): + msg = ['\n' + header] + if err_msg: + if err_msg.find('\n') == -1 and len(err_msg) < 79-len(header): + msg = [msg[0] + ' ' + err_msg] + else: + msg.append(err_msg) + if verbose: + for i, a in enumerate(arrays): + + if isinstance(a, ndarray): + # precision argument is only needed if the objects are ndarrays + r_func = partial(array_repr, precision=precision) + else: + r_func = repr + + try: + r = r_func(a) + except Exception as exc: + r = f'[repr failed for <{type(a).__name__}>: {exc}]' + if r.count('\n') > 3: + r = '\n'.join(r.splitlines()[:3]) + r += '...' + msg.append(f' {names[i]}: {r}') + return '\n'.join(msg) + + +def assert_equal(actual, desired, err_msg='', verbose=True): + """ + Raises an AssertionError if two objects are not equal. + + Given two objects (scalars, lists, tuples, dictionaries or numpy arrays), + check that all elements of these objects are equal. An exception is raised + at the first conflicting values. + + When one of `actual` and `desired` is a scalar and the other is array_like, + the function checks that each element of the array_like object is equal to + the scalar. + + This function handles NaN comparisons as if NaN was a "normal" number. + That is, AssertionError is not raised if both objects have NaNs in the same + positions. This is in contrast to the IEEE standard on NaNs, which says + that NaN compared to anything must return False. + + Parameters + ---------- + actual : array_like + The object to check. + desired : array_like + The expected object. + err_msg : str, optional + The error message to be printed in case of failure. + verbose : bool, optional + If True, the conflicting values are appended to the error message. + + Raises + ------ + AssertionError + If actual and desired are not equal. + + Examples + -------- + >>> np.testing.assert_equal([4,5], [4,6]) + Traceback (most recent call last): + ... + AssertionError: + Items are not equal: + item=1 + ACTUAL: 5 + DESIRED: 6 + + The following comparison does not raise an exception. There are NaNs + in the inputs, but they are in the same positions. + + >>> np.testing.assert_equal(np.array([1.0, 2.0, np.nan]), [1, 2, np.nan]) + + """ + __tracebackhide__ = True # Hide traceback for py.test + if isinstance(desired, dict): + if not isinstance(actual, dict): + raise AssertionError(repr(type(actual))) + assert_equal(len(actual), len(desired), err_msg, verbose) + for k, i in desired.items(): + if k not in actual: + raise AssertionError(repr(k)) + assert_equal(actual[k], desired[k], f'key={k!r}\n{err_msg}', + verbose) + return + if isinstance(desired, (list, tuple)) and isinstance(actual, (list, tuple)): + assert_equal(len(actual), len(desired), err_msg, verbose) + for k in range(len(desired)): + assert_equal(actual[k], desired[k], f'item={k!r}\n{err_msg}', + verbose) + return + from numpy.core import ndarray, isscalar, signbit + from numpy.lib import iscomplexobj, real, imag + if isinstance(actual, ndarray) or isinstance(desired, ndarray): + return assert_array_equal(actual, desired, err_msg, verbose) + msg = build_err_msg([actual, desired], err_msg, verbose=verbose) + + # Handle complex numbers: separate into real/imag to handle + # nan/inf/negative zero correctly + # XXX: catch ValueError for subclasses of ndarray where iscomplex fail + try: + usecomplex = iscomplexobj(actual) or iscomplexobj(desired) + except (ValueError, TypeError): + usecomplex = False + + if usecomplex: + if iscomplexobj(actual): + actualr = real(actual) + actuali = imag(actual) + else: + actualr = actual + actuali = 0 + if iscomplexobj(desired): + desiredr = real(desired) + desiredi = imag(desired) + else: + desiredr = desired + desiredi = 0 + try: + assert_equal(actualr, desiredr) + assert_equal(actuali, desiredi) + except AssertionError: + raise AssertionError(msg) + + # isscalar test to check cases such as [np.nan] != np.nan + if isscalar(desired) != isscalar(actual): + raise AssertionError(msg) + + try: + isdesnat = isnat(desired) + isactnat = isnat(actual) + dtypes_match = array(desired).dtype.type == array(actual).dtype.type + if isdesnat and isactnat: + # If both are NaT (and have the same dtype -- datetime or + # timedelta) they are considered equal. + if dtypes_match: + return + else: + raise AssertionError(msg) + + except (TypeError, ValueError, NotImplementedError): + pass + + # Inf/nan/negative zero handling + try: + isdesnan = gisnan(desired) + isactnan = gisnan(actual) + if isdesnan and isactnan: + return # both nan, so equal + + # handle signed zero specially for floats + array_actual = array(actual) + array_desired = array(desired) + if (array_actual.dtype.char in 'Mm' or + array_desired.dtype.char in 'Mm'): + # version 1.18 + # until this version, gisnan failed for datetime64 and timedelta64. + # Now it succeeds but comparison to scalar with a different type + # emits a DeprecationWarning. + # Avoid that by skipping the next check + raise NotImplementedError('cannot compare to a scalar ' + 'with a different type') + + if desired == 0 and actual == 0: + if not signbit(desired) == signbit(actual): + raise AssertionError(msg) + + except (TypeError, ValueError, NotImplementedError): + pass + + try: + # Explicitly use __eq__ for comparison, gh-2552 + if not (desired == actual): + raise AssertionError(msg) + + except (DeprecationWarning, FutureWarning) as e: + # this handles the case when the two types are not even comparable + if 'elementwise == comparison' in e.args[0]: + raise AssertionError(msg) + else: + raise + + +def print_assert_equal(test_string, actual, desired): + """ + Test if two objects are equal, and print an error message if test fails. + + The test is performed with ``actual == desired``. + + Parameters + ---------- + test_string : str + The message supplied to AssertionError. + actual : object + The object to test for equality against `desired`. + desired : object + The expected result. + + Examples + -------- + >>> np.testing.print_assert_equal('Test XYZ of func xyz', [0, 1], [0, 1]) + >>> np.testing.print_assert_equal('Test XYZ of func xyz', [0, 1], [0, 2]) + Traceback (most recent call last): + ... + AssertionError: Test XYZ of func xyz failed + ACTUAL: + [0, 1] + DESIRED: + [0, 2] + + """ + __tracebackhide__ = True # Hide traceback for py.test + import pprint + + if not (actual == desired): + msg = StringIO() + msg.write(test_string) + msg.write(' failed\nACTUAL: \n') + pprint.pprint(actual, msg) + msg.write('DESIRED: \n') + pprint.pprint(desired, msg) + raise AssertionError(msg.getvalue()) + + +def assert_almost_equal(actual,desired,decimal=7,err_msg='',verbose=True): + """ + Raises an AssertionError if two items are not equal up to desired + precision. + + .. note:: It is recommended to use one of `assert_allclose`, + `assert_array_almost_equal_nulp` or `assert_array_max_ulp` + instead of this function for more consistent floating point + comparisons. + + The test verifies that the elements of ``actual`` and ``desired`` satisfy. + + ``abs(desired-actual) < 1.5 * 10**(-decimal)`` + + That is a looser test than originally documented, but agrees with what the + actual implementation in `assert_array_almost_equal` did up to rounding + vagaries. An exception is raised at conflicting values. For ndarrays this + delegates to assert_array_almost_equal + + Parameters + ---------- + actual : array_like + The object to check. + desired : array_like + The expected object. + decimal : int, optional + Desired precision, default is 7. + err_msg : str, optional + The error message to be printed in case of failure. + verbose : bool, optional + If True, the conflicting values are appended to the error message. + + Raises + ------ + AssertionError + If actual and desired are not equal up to specified precision. + + See Also + -------- + assert_allclose: Compare two array_like objects for equality with desired + relative and/or absolute precision. + assert_array_almost_equal_nulp, assert_array_max_ulp, assert_equal + + Examples + -------- + >>> import numpy.testing as npt + >>> npt.assert_almost_equal(2.3333333333333, 2.33333334) + >>> npt.assert_almost_equal(2.3333333333333, 2.33333334, decimal=10) + Traceback (most recent call last): + ... + AssertionError: + Arrays are not almost equal to 10 decimals + ACTUAL: 2.3333333333333 + DESIRED: 2.33333334 + + >>> npt.assert_almost_equal(np.array([1.0,2.3333333333333]), + ... np.array([1.0,2.33333334]), decimal=9) + Traceback (most recent call last): + ... + AssertionError: + Arrays are not almost equal to 9 decimals + + Mismatched elements: 1 / 2 (50%) + Max absolute difference: 6.66669964e-09 + Max relative difference: 2.85715698e-09 + x: array([1. , 2.333333333]) + y: array([1. , 2.33333334]) + + """ + __tracebackhide__ = True # Hide traceback for py.test + from numpy.core import ndarray + from numpy.lib import iscomplexobj, real, imag + + # Handle complex numbers: separate into real/imag to handle + # nan/inf/negative zero correctly + # XXX: catch ValueError for subclasses of ndarray where iscomplex fail + try: + usecomplex = iscomplexobj(actual) or iscomplexobj(desired) + except ValueError: + usecomplex = False + + def _build_err_msg(): + header = ('Arrays are not almost equal to %d decimals' % decimal) + return build_err_msg([actual, desired], err_msg, verbose=verbose, + header=header) + + if usecomplex: + if iscomplexobj(actual): + actualr = real(actual) + actuali = imag(actual) + else: + actualr = actual + actuali = 0 + if iscomplexobj(desired): + desiredr = real(desired) + desiredi = imag(desired) + else: + desiredr = desired + desiredi = 0 + try: + assert_almost_equal(actualr, desiredr, decimal=decimal) + assert_almost_equal(actuali, desiredi, decimal=decimal) + except AssertionError: + raise AssertionError(_build_err_msg()) + + if isinstance(actual, (ndarray, tuple, list)) \ + or isinstance(desired, (ndarray, tuple, list)): + return assert_array_almost_equal(actual, desired, decimal, err_msg) + try: + # If one of desired/actual is not finite, handle it specially here: + # check that both are nan if any is a nan, and test for equality + # otherwise + if not (gisfinite(desired) and gisfinite(actual)): + if gisnan(desired) or gisnan(actual): + if not (gisnan(desired) and gisnan(actual)): + raise AssertionError(_build_err_msg()) + else: + if not desired == actual: + raise AssertionError(_build_err_msg()) + return + except (NotImplementedError, TypeError): + pass + if abs(desired - actual) >= 1.5 * 10.0**(-decimal): + raise AssertionError(_build_err_msg()) + + +def assert_approx_equal(actual,desired,significant=7,err_msg='',verbose=True): + """ + Raises an AssertionError if two items are not equal up to significant + digits. + + .. note:: It is recommended to use one of `assert_allclose`, + `assert_array_almost_equal_nulp` or `assert_array_max_ulp` + instead of this function for more consistent floating point + comparisons. + + Given two numbers, check that they are approximately equal. + Approximately equal is defined as the number of significant digits + that agree. + + Parameters + ---------- + actual : scalar + The object to check. + desired : scalar + The expected object. + significant : int, optional + Desired precision, default is 7. + err_msg : str, optional + The error message to be printed in case of failure. + verbose : bool, optional + If True, the conflicting values are appended to the error message. + + Raises + ------ + AssertionError + If actual and desired are not equal up to specified precision. + + See Also + -------- + assert_allclose: Compare two array_like objects for equality with desired + relative and/or absolute precision. + assert_array_almost_equal_nulp, assert_array_max_ulp, assert_equal + + Examples + -------- + >>> np.testing.assert_approx_equal(0.12345677777777e-20, 0.1234567e-20) + >>> np.testing.assert_approx_equal(0.12345670e-20, 0.12345671e-20, + ... significant=8) + >>> np.testing.assert_approx_equal(0.12345670e-20, 0.12345672e-20, + ... significant=8) + Traceback (most recent call last): + ... + AssertionError: + Items are not equal to 8 significant digits: + ACTUAL: 1.234567e-21 + DESIRED: 1.2345672e-21 + + the evaluated condition that raises the exception is + + >>> abs(0.12345670e-20/1e-21 - 0.12345672e-20/1e-21) >= 10**-(8-1) + True + + """ + __tracebackhide__ = True # Hide traceback for py.test + import numpy as np + + (actual, desired) = map(float, (actual, desired)) + if desired == actual: + return + # Normalized the numbers to be in range (-10.0,10.0) + # scale = float(pow(10,math.floor(math.log10(0.5*(abs(desired)+abs(actual)))))) + with np.errstate(invalid='ignore'): + scale = 0.5*(np.abs(desired) + np.abs(actual)) + scale = np.power(10, np.floor(np.log10(scale))) + try: + sc_desired = desired/scale + except ZeroDivisionError: + sc_desired = 0.0 + try: + sc_actual = actual/scale + except ZeroDivisionError: + sc_actual = 0.0 + msg = build_err_msg( + [actual, desired], err_msg, + header='Items are not equal to %d significant digits:' % significant, + verbose=verbose) + try: + # If one of desired/actual is not finite, handle it specially here: + # check that both are nan if any is a nan, and test for equality + # otherwise + if not (gisfinite(desired) and gisfinite(actual)): + if gisnan(desired) or gisnan(actual): + if not (gisnan(desired) and gisnan(actual)): + raise AssertionError(msg) + else: + if not desired == actual: + raise AssertionError(msg) + return + except (TypeError, NotImplementedError): + pass + if np.abs(sc_desired - sc_actual) >= np.power(10., -(significant-1)): + raise AssertionError(msg) + + +def assert_array_compare(comparison, x, y, err_msg='', verbose=True, header='', + precision=6, equal_nan=True, equal_inf=True): + __tracebackhide__ = True # Hide traceback for py.test + from numpy.core import array, array2string, isnan, inf, bool_, errstate, all, max, object_ + + x = array(x, copy=False, subok=True) + y = array(y, copy=False, subok=True) + + # original array for output formatting + ox, oy = x, y + + def isnumber(x): + return x.dtype.char in '?bhilqpBHILQPefdgFDG' + + def istime(x): + return x.dtype.char in "Mm" + + def func_assert_same_pos(x, y, func=isnan, hasval='nan'): + """Handling nan/inf. + + Combine results of running func on x and y, checking that they are True + at the same locations. + + """ + __tracebackhide__ = True # Hide traceback for py.test + + x_id = func(x) + y_id = func(y) + # We include work-arounds here to handle three types of slightly + # pathological ndarray subclasses: + # (1) all() on `masked` array scalars can return masked arrays, so we + # use != True + # (2) __eq__ on some ndarray subclasses returns Python booleans + # instead of element-wise comparisons, so we cast to bool_() and + # use isinstance(..., bool) checks + # (3) subclasses with bare-bones __array_function__ implementations may + # not implement np.all(), so favor using the .all() method + # We are not committed to supporting such subclasses, but it's nice to + # support them if possible. + if bool_(x_id == y_id).all() != True: + msg = build_err_msg([x, y], + err_msg + '\nx and y %s location mismatch:' + % (hasval), verbose=verbose, header=header, + names=('x', 'y'), precision=precision) + raise AssertionError(msg) + # If there is a scalar, then here we know the array has the same + # flag as it everywhere, so we should return the scalar flag. + if isinstance(x_id, bool) or x_id.ndim == 0: + return bool_(x_id) + elif isinstance(y_id, bool) or y_id.ndim == 0: + return bool_(y_id) + else: + return y_id + + try: + cond = (x.shape == () or y.shape == ()) or x.shape == y.shape + if not cond: + msg = build_err_msg([x, y], + err_msg + + f'\n(shapes {x.shape}, {y.shape} mismatch)', + verbose=verbose, header=header, + names=('x', 'y'), precision=precision) + raise AssertionError(msg) + + flagged = bool_(False) + if isnumber(x) and isnumber(y): + if equal_nan: + flagged = func_assert_same_pos(x, y, func=isnan, hasval='nan') + + if equal_inf: + flagged |= func_assert_same_pos(x, y, + func=lambda xy: xy == +inf, + hasval='+inf') + flagged |= func_assert_same_pos(x, y, + func=lambda xy: xy == -inf, + hasval='-inf') + + elif istime(x) and istime(y): + # If one is datetime64 and the other timedelta64 there is no point + if equal_nan and x.dtype.type == y.dtype.type: + flagged = func_assert_same_pos(x, y, func=isnat, hasval="NaT") + + if flagged.ndim > 0: + x, y = x[~flagged], y[~flagged] + # Only do the comparison if actual values are left + if x.size == 0: + return + elif flagged: + # no sense doing comparison if everything is flagged. + return + + val = comparison(x, y) + + if isinstance(val, bool): + cond = val + reduced = array([val]) + else: + reduced = val.ravel() + cond = reduced.all() + + # The below comparison is a hack to ensure that fully masked + # results, for which val.ravel().all() returns np.ma.masked, + # do not trigger a failure (np.ma.masked != True evaluates as + # np.ma.masked, which is falsy). + if cond != True: + n_mismatch = reduced.size - reduced.sum(dtype=intp) + n_elements = flagged.size if flagged.ndim != 0 else reduced.size + percent_mismatch = 100 * n_mismatch / n_elements + remarks = [ + 'Mismatched elements: {} / {} ({:.3g}%)'.format( + n_mismatch, n_elements, percent_mismatch)] + + with errstate(invalid='ignore', divide='ignore'): + # ignore errors for non-numeric types + with contextlib.suppress(TypeError): + error = abs(x - y) + max_abs_error = max(error) + if getattr(error, 'dtype', object_) == object_: + remarks.append('Max absolute difference: ' + + str(max_abs_error)) + else: + remarks.append('Max absolute difference: ' + + array2string(max_abs_error)) + + # note: this definition of relative error matches that one + # used by assert_allclose (found in np.isclose) + # Filter values where the divisor would be zero + nonzero = bool_(y != 0) + if all(~nonzero): + max_rel_error = array(inf) + else: + max_rel_error = max(error[nonzero] / abs(y[nonzero])) + if getattr(error, 'dtype', object_) == object_: + remarks.append('Max relative difference: ' + + str(max_rel_error)) + else: + remarks.append('Max relative difference: ' + + array2string(max_rel_error)) + + err_msg += '\n' + '\n'.join(remarks) + msg = build_err_msg([ox, oy], err_msg, + verbose=verbose, header=header, + names=('x', 'y'), precision=precision) + raise AssertionError(msg) + except ValueError: + import traceback + efmt = traceback.format_exc() + header = f'error during assertion:\n\n{efmt}\n\n{header}' + + msg = build_err_msg([x, y], err_msg, verbose=verbose, header=header, + names=('x', 'y'), precision=precision) + raise ValueError(msg) + + +def assert_array_equal(x, y, err_msg='', verbose=True): + """ + Raises an AssertionError if two array_like objects are not equal. + + Given two array_like objects, check that the shape is equal and all + elements of these objects are equal (but see the Notes for the special + handling of a scalar). An exception is raised at shape mismatch or + conflicting values. In contrast to the standard usage in numpy, NaNs + are compared like numbers, no assertion is raised if both objects have + NaNs in the same positions. + + The usual caution for verifying equality with floating point numbers is + advised. + + Parameters + ---------- + x : array_like + The actual object to check. + y : array_like + The desired, expected object. + err_msg : str, optional + The error message to be printed in case of failure. + verbose : bool, optional + If True, the conflicting values are appended to the error message. + + Raises + ------ + AssertionError + If actual and desired objects are not equal. + + See Also + -------- + assert_allclose: Compare two array_like objects for equality with desired + relative and/or absolute precision. + assert_array_almost_equal_nulp, assert_array_max_ulp, assert_equal + + Notes + ----- + When one of `x` and `y` is a scalar and the other is array_like, the + function checks that each element of the array_like object is equal to + the scalar. + + Examples + -------- + The first assert does not raise an exception: + + >>> np.testing.assert_array_equal([1.0,2.33333,np.nan], + ... [np.exp(0),2.33333, np.nan]) + + Assert fails with numerical imprecision with floats: + + >>> np.testing.assert_array_equal([1.0,np.pi,np.nan], + ... [1, np.sqrt(np.pi)**2, np.nan]) + Traceback (most recent call last): + ... + AssertionError: + Arrays are not equal + + Mismatched elements: 1 / 3 (33.3%) + Max absolute difference: 4.4408921e-16 + Max relative difference: 1.41357986e-16 + x: array([1. , 3.141593, nan]) + y: array([1. , 3.141593, nan]) + + Use `assert_allclose` or one of the nulp (number of floating point values) + functions for these cases instead: + + >>> np.testing.assert_allclose([1.0,np.pi,np.nan], + ... [1, np.sqrt(np.pi)**2, np.nan], + ... rtol=1e-10, atol=0) + + As mentioned in the Notes section, `assert_array_equal` has special + handling for scalars. Here the test checks that each value in `x` is 3: + + >>> x = np.full((2, 5), fill_value=3) + >>> np.testing.assert_array_equal(x, 3) + + """ + __tracebackhide__ = True # Hide traceback for py.test + assert_array_compare(operator.__eq__, x, y, err_msg=err_msg, + verbose=verbose, header='Arrays are not equal') + + +def assert_array_almost_equal(x, y, decimal=6, err_msg='', verbose=True): + """ + Raises an AssertionError if two objects are not equal up to desired + precision. + + .. note:: It is recommended to use one of `assert_allclose`, + `assert_array_almost_equal_nulp` or `assert_array_max_ulp` + instead of this function for more consistent floating point + comparisons. + + The test verifies identical shapes and that the elements of ``actual`` and + ``desired`` satisfy. + + ``abs(desired-actual) < 1.5 * 10**(-decimal)`` + + That is a looser test than originally documented, but agrees with what the + actual implementation did up to rounding vagaries. An exception is raised + at shape mismatch or conflicting values. In contrast to the standard usage + in numpy, NaNs are compared like numbers, no assertion is raised if both + objects have NaNs in the same positions. + + Parameters + ---------- + x : array_like + The actual object to check. + y : array_like + The desired, expected object. + decimal : int, optional + Desired precision, default is 6. + err_msg : str, optional + The error message to be printed in case of failure. + verbose : bool, optional + If True, the conflicting values are appended to the error message. + + Raises + ------ + AssertionError + If actual and desired are not equal up to specified precision. + + See Also + -------- + assert_allclose: Compare two array_like objects for equality with desired + relative and/or absolute precision. + assert_array_almost_equal_nulp, assert_array_max_ulp, assert_equal + + Examples + -------- + the first assert does not raise an exception + + >>> np.testing.assert_array_almost_equal([1.0,2.333,np.nan], + ... [1.0,2.333,np.nan]) + + >>> np.testing.assert_array_almost_equal([1.0,2.33333,np.nan], + ... [1.0,2.33339,np.nan], decimal=5) + Traceback (most recent call last): + ... + AssertionError: + Arrays are not almost equal to 5 decimals + + Mismatched elements: 1 / 3 (33.3%) + Max absolute difference: 6.e-05 + Max relative difference: 2.57136612e-05 + x: array([1. , 2.33333, nan]) + y: array([1. , 2.33339, nan]) + + >>> np.testing.assert_array_almost_equal([1.0,2.33333,np.nan], + ... [1.0,2.33333, 5], decimal=5) + Traceback (most recent call last): + ... + AssertionError: + Arrays are not almost equal to 5 decimals + + x and y nan location mismatch: + x: array([1. , 2.33333, nan]) + y: array([1. , 2.33333, 5. ]) + + """ + __tracebackhide__ = True # Hide traceback for py.test + from numpy.core import number, float_, result_type, array + from numpy.core.numerictypes import issubdtype + from numpy.core.fromnumeric import any as npany + + def compare(x, y): + try: + if npany(gisinf(x)) or npany( gisinf(y)): + xinfid = gisinf(x) + yinfid = gisinf(y) + if not (xinfid == yinfid).all(): + return False + # if one item, x and y is +- inf + if x.size == y.size == 1: + return x == y + x = x[~xinfid] + y = y[~yinfid] + except (TypeError, NotImplementedError): + pass + + # make sure y is an inexact type to avoid abs(MIN_INT); will cause + # casting of x later. + dtype = result_type(y, 1.) + y = array(y, dtype=dtype, copy=False, subok=True) + z = abs(x - y) + + if not issubdtype(z.dtype, number): + z = z.astype(float_) # handle object arrays + + return z < 1.5 * 10.0**(-decimal) + + assert_array_compare(compare, x, y, err_msg=err_msg, verbose=verbose, + header=('Arrays are not almost equal to %d decimals' % decimal), + precision=decimal) + + +def assert_array_less(x, y, err_msg='', verbose=True): + """ + Raises an AssertionError if two array_like objects are not ordered by less + than. + + Given two array_like objects, check that the shape is equal and all + elements of the first object are strictly smaller than those of the + second object. An exception is raised at shape mismatch or incorrectly + ordered values. Shape mismatch does not raise if an object has zero + dimension. In contrast to the standard usage in numpy, NaNs are + compared, no assertion is raised if both objects have NaNs in the same + positions. + + + + Parameters + ---------- + x : array_like + The smaller object to check. + y : array_like + The larger object to compare. + err_msg : string + The error message to be printed in case of failure. + verbose : bool + If True, the conflicting values are appended to the error message. + + Raises + ------ + AssertionError + If actual and desired objects are not equal. + + See Also + -------- + assert_array_equal: tests objects for equality + assert_array_almost_equal: test objects for equality up to precision + + + + Examples + -------- + >>> np.testing.assert_array_less([1.0, 1.0, np.nan], [1.1, 2.0, np.nan]) + >>> np.testing.assert_array_less([1.0, 1.0, np.nan], [1, 2.0, np.nan]) + Traceback (most recent call last): + ... + AssertionError: + Arrays are not less-ordered + + Mismatched elements: 1 / 3 (33.3%) + Max absolute difference: 1. + Max relative difference: 0.5 + x: array([ 1., 1., nan]) + y: array([ 1., 2., nan]) + + >>> np.testing.assert_array_less([1.0, 4.0], 3) + Traceback (most recent call last): + ... + AssertionError: + Arrays are not less-ordered + + Mismatched elements: 1 / 2 (50%) + Max absolute difference: 2. + Max relative difference: 0.66666667 + x: array([1., 4.]) + y: array(3) + + >>> np.testing.assert_array_less([1.0, 2.0, 3.0], [4]) + Traceback (most recent call last): + ... + AssertionError: + Arrays are not less-ordered + + (shapes (3,), (1,) mismatch) + x: array([1., 2., 3.]) + y: array([4]) + + """ + __tracebackhide__ = True # Hide traceback for py.test + assert_array_compare(operator.__lt__, x, y, err_msg=err_msg, + verbose=verbose, + header='Arrays are not less-ordered', + equal_inf=False) + + +def runstring(astr, dict): + exec(astr, dict) + + +def assert_string_equal(actual, desired): + """ + Test if two strings are equal. + + If the given strings are equal, `assert_string_equal` does nothing. + If they are not equal, an AssertionError is raised, and the diff + between the strings is shown. + + Parameters + ---------- + actual : str + The string to test for equality against the expected string. + desired : str + The expected string. + + Examples + -------- + >>> np.testing.assert_string_equal('abc', 'abc') + >>> np.testing.assert_string_equal('abc', 'abcd') + Traceback (most recent call last): + File "", line 1, in + ... + AssertionError: Differences in strings: + - abc+ abcd? + + + """ + # delay import of difflib to reduce startup time + __tracebackhide__ = True # Hide traceback for py.test + import difflib + + if not isinstance(actual, str): + raise AssertionError(repr(type(actual))) + if not isinstance(desired, str): + raise AssertionError(repr(type(desired))) + if desired == actual: + return + + diff = list(difflib.Differ().compare(actual.splitlines(True), + desired.splitlines(True))) + diff_list = [] + while diff: + d1 = diff.pop(0) + if d1.startswith(' '): + continue + if d1.startswith('- '): + l = [d1] + d2 = diff.pop(0) + if d2.startswith('? '): + l.append(d2) + d2 = diff.pop(0) + if not d2.startswith('+ '): + raise AssertionError(repr(d2)) + l.append(d2) + if diff: + d3 = diff.pop(0) + if d3.startswith('? '): + l.append(d3) + else: + diff.insert(0, d3) + if d2[2:] == d1[2:]: + continue + diff_list.extend(l) + continue + raise AssertionError(repr(d1)) + if not diff_list: + return + msg = f"Differences in strings:\n{''.join(diff_list).rstrip()}" + if actual != desired: + raise AssertionError(msg) + + +def rundocs(filename=None, raise_on_error=True): + """ + Run doctests found in the given file. + + By default `rundocs` raises an AssertionError on failure. + + Parameters + ---------- + filename : str + The path to the file for which the doctests are run. + raise_on_error : bool + Whether to raise an AssertionError when a doctest fails. Default is + True. + + Notes + ----- + The doctests can be run by the user/developer by adding the ``doctests`` + argument to the ``test()`` call. For example, to run all tests (including + doctests) for `numpy.lib`: + + >>> np.lib.test(doctests=True) # doctest: +SKIP + """ + from numpy.compat import npy_load_module + import doctest + if filename is None: + f = sys._getframe(1) + filename = f.f_globals['__file__'] + name = os.path.splitext(os.path.basename(filename))[0] + m = npy_load_module(name, filename) + + tests = doctest.DocTestFinder().find(m) + runner = doctest.DocTestRunner(verbose=False) + + msg = [] + if raise_on_error: + out = lambda s: msg.append(s) + else: + out = None + + for test in tests: + runner.run(test, out=out) + + if runner.failures > 0 and raise_on_error: + raise AssertionError("Some doctests failed:\n%s" % "\n".join(msg)) + + +def raises(*args): + """Decorator to check for raised exceptions. + + The decorated test function must raise one of the passed exceptions to + pass. If you want to test many assertions about exceptions in a single + test, you may want to use `assert_raises` instead. + + .. warning:: + This decorator is nose specific, do not use it if you are using a + different test framework. + + Parameters + ---------- + args : exceptions + The test passes if any of the passed exceptions is raised. + + Raises + ------ + AssertionError + + Examples + -------- + + Usage:: + + @raises(TypeError, ValueError) + def test_raises_type_error(): + raise TypeError("This test passes") + + @raises(Exception) + def test_that_fails_by_passing(): + pass + + """ + nose = import_nose() + return nose.tools.raises(*args) + +# +# assert_raises and assert_raises_regex are taken from unittest. +# +import unittest + + +class _Dummy(unittest.TestCase): + def nop(self): + pass + +_d = _Dummy('nop') + +def assert_raises(*args, **kwargs): + """ + assert_raises(exception_class, callable, *args, **kwargs) + assert_raises(exception_class) + + Fail unless an exception of class exception_class is thrown + by callable when invoked with arguments args and keyword + arguments kwargs. If a different type of exception is + thrown, it will not be caught, and the test case will be + deemed to have suffered an error, exactly as for an + unexpected exception. + + Alternatively, `assert_raises` can be used as a context manager: + + >>> from numpy.testing import assert_raises + >>> with assert_raises(ZeroDivisionError): + ... 1 / 0 + + is equivalent to + + >>> def div(x, y): + ... return x / y + >>> assert_raises(ZeroDivisionError, div, 1, 0) + + """ + __tracebackhide__ = True # Hide traceback for py.test + return _d.assertRaises(*args,**kwargs) + + +def assert_raises_regex(exception_class, expected_regexp, *args, **kwargs): + """ + assert_raises_regex(exception_class, expected_regexp, callable, *args, + **kwargs) + assert_raises_regex(exception_class, expected_regexp) + + Fail unless an exception of class exception_class and with message that + matches expected_regexp is thrown by callable when invoked with arguments + args and keyword arguments kwargs. + + Alternatively, can be used as a context manager like `assert_raises`. + + Name of this function adheres to Python 3.2+ reference, but should work in + all versions down to 2.6. + + Notes + ----- + .. versionadded:: 1.9.0 + + """ + __tracebackhide__ = True # Hide traceback for py.test + return _d.assertRaisesRegex(exception_class, expected_regexp, *args, **kwargs) + + +def decorate_methods(cls, decorator, testmatch=None): + """ + Apply a decorator to all methods in a class matching a regular expression. + + The given decorator is applied to all public methods of `cls` that are + matched by the regular expression `testmatch` + (``testmatch.search(methodname)``). Methods that are private, i.e. start + with an underscore, are ignored. + + Parameters + ---------- + cls : class + Class whose methods to decorate. + decorator : function + Decorator to apply to methods + testmatch : compiled regexp or str, optional + The regular expression. Default value is None, in which case the + nose default (``re.compile(r'(?:^|[\\b_\\.%s-])[Tt]est' % os.sep)``) + is used. + If `testmatch` is a string, it is compiled to a regular expression + first. + + """ + if testmatch is None: + testmatch = re.compile(r'(?:^|[\\b_\\.%s-])[Tt]est' % os.sep) + else: + testmatch = re.compile(testmatch) + cls_attr = cls.__dict__ + + # delayed import to reduce startup time + from inspect import isfunction + + methods = [_m for _m in cls_attr.values() if isfunction(_m)] + for function in methods: + try: + if hasattr(function, 'compat_func_name'): + funcname = function.compat_func_name + else: + funcname = function.__name__ + except AttributeError: + # not a function + continue + if testmatch.search(funcname) and not funcname.startswith('_'): + setattr(cls, funcname, decorator(function)) + return + + +def measure(code_str, times=1, label=None): + """ + Return elapsed time for executing code in the namespace of the caller. + + The supplied code string is compiled with the Python builtin ``compile``. + The precision of the timing is 10 milli-seconds. If the code will execute + fast on this timescale, it can be executed many times to get reasonable + timing accuracy. + + Parameters + ---------- + code_str : str + The code to be timed. + times : int, optional + The number of times the code is executed. Default is 1. The code is + only compiled once. + label : str, optional + A label to identify `code_str` with. This is passed into ``compile`` + as the second argument (for run-time error messages). + + Returns + ------- + elapsed : float + Total elapsed time in seconds for executing `code_str` `times` times. + + Examples + -------- + >>> times = 10 + >>> etime = np.testing.measure('for i in range(1000): np.sqrt(i**2)', times=times) + >>> print("Time for a single execution : ", etime / times, "s") # doctest: +SKIP + Time for a single execution : 0.005 s + + """ + frame = sys._getframe(1) + locs, globs = frame.f_locals, frame.f_globals + + code = compile(code_str, f'Test name: {label} ', 'exec') + i = 0 + elapsed = jiffies() + while i < times: + i += 1 + exec(code, globs, locs) + elapsed = jiffies() - elapsed + return 0.01*elapsed + + +def _assert_valid_refcount(op): + """ + Check that ufuncs don't mishandle refcount of object `1`. + Used in a few regression tests. + """ + if not HAS_REFCOUNT: + return True + + import gc + import numpy as np + + b = np.arange(100*100).reshape(100, 100) + c = b + i = 1 + + gc.disable() + try: + rc = sys.getrefcount(i) + for j in range(15): + d = op(b, c) + assert_(sys.getrefcount(i) >= rc) + finally: + gc.enable() + del d # for pyflakes + + +def assert_allclose(actual, desired, rtol=1e-7, atol=0, equal_nan=True, + err_msg='', verbose=True): + """ + Raises an AssertionError if two objects are not equal up to desired + tolerance. + + The test is equivalent to ``allclose(actual, desired, rtol, atol)`` (note + that ``allclose`` has different default values). It compares the difference + between `actual` and `desired` to ``atol + rtol * abs(desired)``. + + .. versionadded:: 1.5.0 + + Parameters + ---------- + actual : array_like + Array obtained. + desired : array_like + Array desired. + rtol : float, optional + Relative tolerance. + atol : float, optional + Absolute tolerance. + equal_nan : bool, optional. + If True, NaNs will compare equal. + err_msg : str, optional + The error message to be printed in case of failure. + verbose : bool, optional + If True, the conflicting values are appended to the error message. + + Raises + ------ + AssertionError + If actual and desired are not equal up to specified precision. + + See Also + -------- + assert_array_almost_equal_nulp, assert_array_max_ulp + + Examples + -------- + >>> x = [1e-5, 1e-3, 1e-1] + >>> y = np.arccos(np.cos(x)) + >>> np.testing.assert_allclose(x, y, rtol=1e-5, atol=0) + + """ + __tracebackhide__ = True # Hide traceback for py.test + import numpy as np + + def compare(x, y): + return np.core.numeric.isclose(x, y, rtol=rtol, atol=atol, + equal_nan=equal_nan) + + actual, desired = np.asanyarray(actual), np.asanyarray(desired) + header = f'Not equal to tolerance rtol={rtol:g}, atol={atol:g}' + assert_array_compare(compare, actual, desired, err_msg=str(err_msg), + verbose=verbose, header=header, equal_nan=equal_nan) + + +def assert_array_almost_equal_nulp(x, y, nulp=1): + """ + Compare two arrays relatively to their spacing. + + This is a relatively robust method to compare two arrays whose amplitude + is variable. + + Parameters + ---------- + x, y : array_like + Input arrays. + nulp : int, optional + The maximum number of unit in the last place for tolerance (see Notes). + Default is 1. + + Returns + ------- + None + + Raises + ------ + AssertionError + If the spacing between `x` and `y` for one or more elements is larger + than `nulp`. + + See Also + -------- + assert_array_max_ulp : Check that all items of arrays differ in at most + N Units in the Last Place. + spacing : Return the distance between x and the nearest adjacent number. + + Notes + ----- + An assertion is raised if the following condition is not met:: + + abs(x - y) <= nulps * spacing(maximum(abs(x), abs(y))) + + Examples + -------- + >>> x = np.array([1., 1e-10, 1e-20]) + >>> eps = np.finfo(x.dtype).eps + >>> np.testing.assert_array_almost_equal_nulp(x, x*eps/2 + x) + + >>> np.testing.assert_array_almost_equal_nulp(x, x*eps + x) + Traceback (most recent call last): + ... + AssertionError: X and Y are not equal to 1 ULP (max is 2) + + """ + __tracebackhide__ = True # Hide traceback for py.test + import numpy as np + ax = np.abs(x) + ay = np.abs(y) + ref = nulp * np.spacing(np.where(ax > ay, ax, ay)) + if not np.all(np.abs(x-y) <= ref): + if np.iscomplexobj(x) or np.iscomplexobj(y): + msg = "X and Y are not equal to %d ULP" % nulp + else: + max_nulp = np.max(nulp_diff(x, y)) + msg = "X and Y are not equal to %d ULP (max is %g)" % (nulp, max_nulp) + raise AssertionError(msg) + + +def assert_array_max_ulp(a, b, maxulp=1, dtype=None): + """ + Check that all items of arrays differ in at most N Units in the Last Place. + + Parameters + ---------- + a, b : array_like + Input arrays to be compared. + maxulp : int, optional + The maximum number of units in the last place that elements of `a` and + `b` can differ. Default is 1. + dtype : dtype, optional + Data-type to convert `a` and `b` to if given. Default is None. + + Returns + ------- + ret : ndarray + Array containing number of representable floating point numbers between + items in `a` and `b`. + + Raises + ------ + AssertionError + If one or more elements differ by more than `maxulp`. + + Notes + ----- + For computing the ULP difference, this API does not differentiate between + various representations of NAN (ULP difference between 0x7fc00000 and 0xffc00000 + is zero). + + See Also + -------- + assert_array_almost_equal_nulp : Compare two arrays relatively to their + spacing. + + Examples + -------- + >>> a = np.linspace(0., 1., 100) + >>> res = np.testing.assert_array_max_ulp(a, np.arcsin(np.sin(a))) + + """ + __tracebackhide__ = True # Hide traceback for py.test + import numpy as np + ret = nulp_diff(a, b, dtype) + if not np.all(ret <= maxulp): + raise AssertionError("Arrays are not almost equal up to %g " + "ULP (max difference is %g ULP)" % + (maxulp, np.max(ret))) + return ret + + +def nulp_diff(x, y, dtype=None): + """For each item in x and y, return the number of representable floating + points between them. + + Parameters + ---------- + x : array_like + first input array + y : array_like + second input array + dtype : dtype, optional + Data-type to convert `x` and `y` to if given. Default is None. + + Returns + ------- + nulp : array_like + number of representable floating point numbers between each item in x + and y. + + Notes + ----- + For computing the ULP difference, this API does not differentiate between + various representations of NAN (ULP difference between 0x7fc00000 and 0xffc00000 + is zero). + + Examples + -------- + # By definition, epsilon is the smallest number such as 1 + eps != 1, so + # there should be exactly one ULP between 1 and 1 + eps + >>> nulp_diff(1, 1 + np.finfo(x.dtype).eps) + 1.0 + """ + import numpy as np + if dtype: + x = np.array(x, dtype=dtype) + y = np.array(y, dtype=dtype) + else: + x = np.array(x) + y = np.array(y) + + t = np.common_type(x, y) + if np.iscomplexobj(x) or np.iscomplexobj(y): + raise NotImplementedError("_nulp not implemented for complex array") + + x = np.array([x], dtype=t) + y = np.array([y], dtype=t) + + x[np.isnan(x)] = np.nan + y[np.isnan(y)] = np.nan + + if not x.shape == y.shape: + raise ValueError("x and y do not have the same shape: %s - %s" % + (x.shape, y.shape)) + + def _diff(rx, ry, vdt): + diff = np.array(rx-ry, dtype=vdt) + return np.abs(diff) + + rx = integer_repr(x) + ry = integer_repr(y) + return _diff(rx, ry, t) + + +def _integer_repr(x, vdt, comp): + # Reinterpret binary representation of the float as sign-magnitude: + # take into account two-complement representation + # See also + # https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/ + rx = x.view(vdt) + if not (rx.size == 1): + rx[rx < 0] = comp - rx[rx < 0] + else: + if rx < 0: + rx = comp - rx + + return rx + + +def integer_repr(x): + """Return the signed-magnitude interpretation of the binary representation + of x.""" + import numpy as np + if x.dtype == np.float16: + return _integer_repr(x, np.int16, np.int16(-2**15)) + elif x.dtype == np.float32: + return _integer_repr(x, np.int32, np.int32(-2**31)) + elif x.dtype == np.float64: + return _integer_repr(x, np.int64, np.int64(-2**63)) + else: + raise ValueError(f'Unsupported dtype {x.dtype}') + + +@contextlib.contextmanager +def _assert_warns_context(warning_class, name=None): + __tracebackhide__ = True # Hide traceback for py.test + with suppress_warnings() as sup: + l = sup.record(warning_class) + yield + if not len(l) > 0: + name_str = f' when calling {name}' if name is not None else '' + raise AssertionError("No warning raised" + name_str) + + +def assert_warns(warning_class, *args, **kwargs): + """ + Fail unless the given callable throws the specified warning. + + A warning of class warning_class should be thrown by the callable when + invoked with arguments args and keyword arguments kwargs. + If a different type of warning is thrown, it will not be caught. + + If called with all arguments other than the warning class omitted, may be + used as a context manager: + + with assert_warns(SomeWarning): + do_something() + + The ability to be used as a context manager is new in NumPy v1.11.0. + + .. versionadded:: 1.4.0 + + Parameters + ---------- + warning_class : class + The class defining the warning that `func` is expected to throw. + func : callable, optional + Callable to test + *args : Arguments + Arguments for `func`. + **kwargs : Kwargs + Keyword arguments for `func`. + + Returns + ------- + The value returned by `func`. + + Examples + -------- + >>> import warnings + >>> def deprecated_func(num): + ... warnings.warn("Please upgrade", DeprecationWarning) + ... return num*num + >>> with np.testing.assert_warns(DeprecationWarning): + ... assert deprecated_func(4) == 16 + >>> # or passing a func + >>> ret = np.testing.assert_warns(DeprecationWarning, deprecated_func, 4) + >>> assert ret == 16 + """ + if not args: + return _assert_warns_context(warning_class) + + func = args[0] + args = args[1:] + with _assert_warns_context(warning_class, name=func.__name__): + return func(*args, **kwargs) + + +@contextlib.contextmanager +def _assert_no_warnings_context(name=None): + __tracebackhide__ = True # Hide traceback for py.test + with warnings.catch_warnings(record=True) as l: + warnings.simplefilter('always') + yield + if len(l) > 0: + name_str = f' when calling {name}' if name is not None else '' + raise AssertionError(f'Got warnings{name_str}: {l}') + + +def assert_no_warnings(*args, **kwargs): + """ + Fail if the given callable produces any warnings. + + If called with all arguments omitted, may be used as a context manager: + + with assert_no_warnings(): + do_something() + + The ability to be used as a context manager is new in NumPy v1.11.0. + + .. versionadded:: 1.7.0 + + Parameters + ---------- + func : callable + The callable to test. + \\*args : Arguments + Arguments passed to `func`. + \\*\\*kwargs : Kwargs + Keyword arguments passed to `func`. + + Returns + ------- + The value returned by `func`. + + """ + if not args: + return _assert_no_warnings_context() + + func = args[0] + args = args[1:] + with _assert_no_warnings_context(name=func.__name__): + return func(*args, **kwargs) + + +def _gen_alignment_data(dtype=float32, type='binary', max_size=24): + """ + generator producing data with different alignment and offsets + to test simd vectorization + + Parameters + ---------- + dtype : dtype + data type to produce + type : string + 'unary': create data for unary operations, creates one input + and output array + 'binary': create data for unary operations, creates two input + and output array + max_size : integer + maximum size of data to produce + + Returns + ------- + if type is 'unary' yields one output, one input array and a message + containing information on the data + if type is 'binary' yields one output array, two input array and a message + containing information on the data + + """ + ufmt = 'unary offset=(%d, %d), size=%d, dtype=%r, %s' + bfmt = 'binary offset=(%d, %d, %d), size=%d, dtype=%r, %s' + for o in range(3): + for s in range(o + 2, max(o + 3, max_size)): + if type == 'unary': + inp = lambda: arange(s, dtype=dtype)[o:] + out = empty((s,), dtype=dtype)[o:] + yield out, inp(), ufmt % (o, o, s, dtype, 'out of place') + d = inp() + yield d, d, ufmt % (o, o, s, dtype, 'in place') + yield out[1:], inp()[:-1], ufmt % \ + (o + 1, o, s - 1, dtype, 'out of place') + yield out[:-1], inp()[1:], ufmt % \ + (o, o + 1, s - 1, dtype, 'out of place') + yield inp()[:-1], inp()[1:], ufmt % \ + (o, o + 1, s - 1, dtype, 'aliased') + yield inp()[1:], inp()[:-1], ufmt % \ + (o + 1, o, s - 1, dtype, 'aliased') + if type == 'binary': + inp1 = lambda: arange(s, dtype=dtype)[o:] + inp2 = lambda: arange(s, dtype=dtype)[o:] + out = empty((s,), dtype=dtype)[o:] + yield out, inp1(), inp2(), bfmt % \ + (o, o, o, s, dtype, 'out of place') + d = inp1() + yield d, d, inp2(), bfmt % \ + (o, o, o, s, dtype, 'in place1') + d = inp2() + yield d, inp1(), d, bfmt % \ + (o, o, o, s, dtype, 'in place2') + yield out[1:], inp1()[:-1], inp2()[:-1], bfmt % \ + (o + 1, o, o, s - 1, dtype, 'out of place') + yield out[:-1], inp1()[1:], inp2()[:-1], bfmt % \ + (o, o + 1, o, s - 1, dtype, 'out of place') + yield out[:-1], inp1()[:-1], inp2()[1:], bfmt % \ + (o, o, o + 1, s - 1, dtype, 'out of place') + yield inp1()[1:], inp1()[:-1], inp2()[:-1], bfmt % \ + (o + 1, o, o, s - 1, dtype, 'aliased') + yield inp1()[:-1], inp1()[1:], inp2()[:-1], bfmt % \ + (o, o + 1, o, s - 1, dtype, 'aliased') + yield inp1()[:-1], inp1()[:-1], inp2()[1:], bfmt % \ + (o, o, o + 1, s - 1, dtype, 'aliased') + + +class IgnoreException(Exception): + "Ignoring this exception due to disabled feature" + pass + + +@contextlib.contextmanager +def tempdir(*args, **kwargs): + """Context manager to provide a temporary test folder. + + All arguments are passed as this to the underlying tempfile.mkdtemp + function. + + """ + tmpdir = mkdtemp(*args, **kwargs) + try: + yield tmpdir + finally: + shutil.rmtree(tmpdir) + + +@contextlib.contextmanager +def temppath(*args, **kwargs): + """Context manager for temporary files. + + Context manager that returns the path to a closed temporary file. Its + parameters are the same as for tempfile.mkstemp and are passed directly + to that function. The underlying file is removed when the context is + exited, so it should be closed at that time. + + Windows does not allow a temporary file to be opened if it is already + open, so the underlying file must be closed after opening before it + can be opened again. + + """ + fd, path = mkstemp(*args, **kwargs) + os.close(fd) + try: + yield path + finally: + os.remove(path) + + +class clear_and_catch_warnings(warnings.catch_warnings): + """ Context manager that resets warning registry for catching warnings + + Warnings can be slippery, because, whenever a warning is triggered, Python + adds a ``__warningregistry__`` member to the *calling* module. This makes + it impossible to retrigger the warning in this module, whatever you put in + the warnings filters. This context manager accepts a sequence of `modules` + as a keyword argument to its constructor and: + + * stores and removes any ``__warningregistry__`` entries in given `modules` + on entry; + * resets ``__warningregistry__`` to its previous state on exit. + + This makes it possible to trigger any warning afresh inside the context + manager without disturbing the state of warnings outside. + + For compatibility with Python 3.0, please consider all arguments to be + keyword-only. + + Parameters + ---------- + record : bool, optional + Specifies whether warnings should be captured by a custom + implementation of ``warnings.showwarning()`` and be appended to a list + returned by the context manager. Otherwise None is returned by the + context manager. The objects appended to the list are arguments whose + attributes mirror the arguments to ``showwarning()``. + modules : sequence, optional + Sequence of modules for which to reset warnings registry on entry and + restore on exit. To work correctly, all 'ignore' filters should + filter by one of these modules. + + Examples + -------- + >>> import warnings + >>> with np.testing.clear_and_catch_warnings( + ... modules=[np.core.fromnumeric]): + ... warnings.simplefilter('always') + ... warnings.filterwarnings('ignore', module='np.core.fromnumeric') + ... # do something that raises a warning but ignore those in + ... # np.core.fromnumeric + """ + class_modules = () + + def __init__(self, record=False, modules=()): + self.modules = set(modules).union(self.class_modules) + self._warnreg_copies = {} + super(clear_and_catch_warnings, self).__init__(record=record) + + def __enter__(self): + for mod in self.modules: + if hasattr(mod, '__warningregistry__'): + mod_reg = mod.__warningregistry__ + self._warnreg_copies[mod] = mod_reg.copy() + mod_reg.clear() + return super(clear_and_catch_warnings, self).__enter__() + + def __exit__(self, *exc_info): + super(clear_and_catch_warnings, self).__exit__(*exc_info) + for mod in self.modules: + if hasattr(mod, '__warningregistry__'): + mod.__warningregistry__.clear() + if mod in self._warnreg_copies: + mod.__warningregistry__.update(self._warnreg_copies[mod]) + + +class suppress_warnings: + """ + Context manager and decorator doing much the same as + ``warnings.catch_warnings``. + + However, it also provides a filter mechanism to work around + https://bugs.python.org/issue4180. + + This bug causes Python before 3.4 to not reliably show warnings again + after they have been ignored once (even within catch_warnings). It + means that no "ignore" filter can be used easily, since following + tests might need to see the warning. Additionally it allows easier + specificity for testing warnings and can be nested. + + Parameters + ---------- + forwarding_rule : str, optional + One of "always", "once", "module", or "location". Analogous to + the usual warnings module filter mode, it is useful to reduce + noise mostly on the outmost level. Unsuppressed and unrecorded + warnings will be forwarded based on this rule. Defaults to "always". + "location" is equivalent to the warnings "default", match by exact + location the warning warning originated from. + + Notes + ----- + Filters added inside the context manager will be discarded again + when leaving it. Upon entering all filters defined outside a + context will be applied automatically. + + When a recording filter is added, matching warnings are stored in the + ``log`` attribute as well as in the list returned by ``record``. + + If filters are added and the ``module`` keyword is given, the + warning registry of this module will additionally be cleared when + applying it, entering the context, or exiting it. This could cause + warnings to appear a second time after leaving the context if they + were configured to be printed once (default) and were already + printed before the context was entered. + + Nesting this context manager will work as expected when the + forwarding rule is "always" (default). Unfiltered and unrecorded + warnings will be passed out and be matched by the outer level. + On the outmost level they will be printed (or caught by another + warnings context). The forwarding rule argument can modify this + behaviour. + + Like ``catch_warnings`` this context manager is not threadsafe. + + Examples + -------- + + With a context manager:: + + with np.testing.suppress_warnings() as sup: + sup.filter(DeprecationWarning, "Some text") + sup.filter(module=np.ma.core) + log = sup.record(FutureWarning, "Does this occur?") + command_giving_warnings() + # The FutureWarning was given once, the filtered warnings were + # ignored. All other warnings abide outside settings (may be + # printed/error) + assert_(len(log) == 1) + assert_(len(sup.log) == 1) # also stored in log attribute + + Or as a decorator:: + + sup = np.testing.suppress_warnings() + sup.filter(module=np.ma.core) # module must match exactly + @sup + def some_function(): + # do something which causes a warning in np.ma.core + pass + """ + def __init__(self, forwarding_rule="always"): + self._entered = False + + # Suppressions are either instance or defined inside one with block: + self._suppressions = [] + + if forwarding_rule not in {"always", "module", "once", "location"}: + raise ValueError("unsupported forwarding rule.") + self._forwarding_rule = forwarding_rule + + def _clear_registries(self): + if hasattr(warnings, "_filters_mutated"): + # clearing the registry should not be necessary on new pythons, + # instead the filters should be mutated. + warnings._filters_mutated() + return + # Simply clear the registry, this should normally be harmless, + # note that on new pythons it would be invalidated anyway. + for module in self._tmp_modules: + if hasattr(module, "__warningregistry__"): + module.__warningregistry__.clear() + + def _filter(self, category=Warning, message="", module=None, record=False): + if record: + record = [] # The log where to store warnings + else: + record = None + if self._entered: + if module is None: + warnings.filterwarnings( + "always", category=category, message=message) + else: + module_regex = module.__name__.replace('.', r'\.') + '$' + warnings.filterwarnings( + "always", category=category, message=message, + module=module_regex) + self._tmp_modules.add(module) + self._clear_registries() + + self._tmp_suppressions.append( + (category, message, re.compile(message, re.I), module, record)) + else: + self._suppressions.append( + (category, message, re.compile(message, re.I), module, record)) + + return record + + def filter(self, category=Warning, message="", module=None): + """ + Add a new suppressing filter or apply it if the state is entered. + + Parameters + ---------- + category : class, optional + Warning class to filter + message : string, optional + Regular expression matching the warning message. + module : module, optional + Module to filter for. Note that the module (and its file) + must match exactly and cannot be a submodule. This may make + it unreliable for external modules. + + Notes + ----- + When added within a context, filters are only added inside + the context and will be forgotten when the context is exited. + """ + self._filter(category=category, message=message, module=module, + record=False) + + def record(self, category=Warning, message="", module=None): + """ + Append a new recording filter or apply it if the state is entered. + + All warnings matching will be appended to the ``log`` attribute. + + Parameters + ---------- + category : class, optional + Warning class to filter + message : string, optional + Regular expression matching the warning message. + module : module, optional + Module to filter for. Note that the module (and its file) + must match exactly and cannot be a submodule. This may make + it unreliable for external modules. + + Returns + ------- + log : list + A list which will be filled with all matched warnings. + + Notes + ----- + When added within a context, filters are only added inside + the context and will be forgotten when the context is exited. + """ + return self._filter(category=category, message=message, module=module, + record=True) + + def __enter__(self): + if self._entered: + raise RuntimeError("cannot enter suppress_warnings twice.") + + self._orig_show = warnings.showwarning + self._filters = warnings.filters + warnings.filters = self._filters[:] + + self._entered = True + self._tmp_suppressions = [] + self._tmp_modules = set() + self._forwarded = set() + + self.log = [] # reset global log (no need to keep same list) + + for cat, mess, _, mod, log in self._suppressions: + if log is not None: + del log[:] # clear the log + if mod is None: + warnings.filterwarnings( + "always", category=cat, message=mess) + else: + module_regex = mod.__name__.replace('.', r'\.') + '$' + warnings.filterwarnings( + "always", category=cat, message=mess, + module=module_regex) + self._tmp_modules.add(mod) + warnings.showwarning = self._showwarning + self._clear_registries() + + return self + + def __exit__(self, *exc_info): + warnings.showwarning = self._orig_show + warnings.filters = self._filters + self._clear_registries() + self._entered = False + del self._orig_show + del self._filters + + def _showwarning(self, message, category, filename, lineno, + *args, use_warnmsg=None, **kwargs): + for cat, _, pattern, mod, rec in ( + self._suppressions + self._tmp_suppressions)[::-1]: + if (issubclass(category, cat) and + pattern.match(message.args[0]) is not None): + if mod is None: + # Message and category match, either recorded or ignored + if rec is not None: + msg = WarningMessage(message, category, filename, + lineno, **kwargs) + self.log.append(msg) + rec.append(msg) + return + # Use startswith, because warnings strips the c or o from + # .pyc/.pyo files. + elif mod.__file__.startswith(filename): + # The message and module (filename) match + if rec is not None: + msg = WarningMessage(message, category, filename, + lineno, **kwargs) + self.log.append(msg) + rec.append(msg) + return + + # There is no filter in place, so pass to the outside handler + # unless we should only pass it once + if self._forwarding_rule == "always": + if use_warnmsg is None: + self._orig_show(message, category, filename, lineno, + *args, **kwargs) + else: + self._orig_showmsg(use_warnmsg) + return + + if self._forwarding_rule == "once": + signature = (message.args, category) + elif self._forwarding_rule == "module": + signature = (message.args, category, filename) + elif self._forwarding_rule == "location": + signature = (message.args, category, filename, lineno) + + if signature in self._forwarded: + return + self._forwarded.add(signature) + if use_warnmsg is None: + self._orig_show(message, category, filename, lineno, *args, + **kwargs) + else: + self._orig_showmsg(use_warnmsg) + + def __call__(self, func): + """ + Function decorator to apply certain suppressions to a whole + function. + """ + @wraps(func) + def new_func(*args, **kwargs): + with self: + return func(*args, **kwargs) + + return new_func + + +@contextlib.contextmanager +def _assert_no_gc_cycles_context(name=None): + __tracebackhide__ = True # Hide traceback for py.test + + # not meaningful to test if there is no refcounting + if not HAS_REFCOUNT: + yield + return + + assert_(gc.isenabled()) + gc.disable() + gc_debug = gc.get_debug() + try: + for i in range(100): + if gc.collect() == 0: + break + else: + raise RuntimeError( + "Unable to fully collect garbage - perhaps a __del__ method " + "is creating more reference cycles?") + + gc.set_debug(gc.DEBUG_SAVEALL) + yield + # gc.collect returns the number of unreachable objects in cycles that + # were found -- we are checking that no cycles were created in the context + n_objects_in_cycles = gc.collect() + objects_in_cycles = gc.garbage[:] + finally: + del gc.garbage[:] + gc.set_debug(gc_debug) + gc.enable() + + if n_objects_in_cycles: + name_str = f' when calling {name}' if name is not None else '' + raise AssertionError( + "Reference cycles were found{}: {} objects were collected, " + "of which {} are shown below:{}" + .format( + name_str, + n_objects_in_cycles, + len(objects_in_cycles), + ''.join( + "\n {} object with id={}:\n {}".format( + type(o).__name__, + id(o), + pprint.pformat(o).replace('\n', '\n ') + ) for o in objects_in_cycles + ) + ) + ) + + +def assert_no_gc_cycles(*args, **kwargs): + """ + Fail if the given callable produces any reference cycles. + + If called with all arguments omitted, may be used as a context manager: + + with assert_no_gc_cycles(): + do_something() + + .. versionadded:: 1.15.0 + + Parameters + ---------- + func : callable + The callable to test. + \\*args : Arguments + Arguments passed to `func`. + \\*\\*kwargs : Kwargs + Keyword arguments passed to `func`. + + Returns + ------- + Nothing. The result is deliberately discarded to ensure that all cycles + are found. + + """ + if not args: + return _assert_no_gc_cycles_context() + + func = args[0] + args = args[1:] + with _assert_no_gc_cycles_context(name=func.__name__): + func(*args, **kwargs) + +def break_cycles(): + """ + Break reference cycles by calling gc.collect + Objects can call other objects' methods (for instance, another object's + __del__) inside their own __del__. On PyPy, the interpreter only runs + between calls to gc.collect, so multiple calls are needed to completely + release all cycles. + """ + + gc.collect() + if IS_PYPY: + # interpreter runs now, to call deleted objects' __del__ methods + gc.collect() + # two more, just to make sure + gc.collect() + gc.collect() + + +def requires_memory(free_bytes): + """Decorator to skip a test if not enough memory is available""" + import pytest + + def decorator(func): + @wraps(func) + def wrapper(*a, **kw): + msg = check_free_memory(free_bytes) + if msg is not None: + pytest.skip(msg) + + try: + return func(*a, **kw) + except MemoryError: + # Probably ran out of memory regardless: don't regard as failure + pytest.xfail("MemoryError raised") + + return wrapper + + return decorator + + +def check_free_memory(free_bytes): + """ + Check whether `free_bytes` amount of memory is currently free. + Returns: None if enough memory available, otherwise error message + """ + env_var = 'NPY_AVAILABLE_MEM' + env_value = os.environ.get(env_var) + if env_value is not None: + try: + mem_free = _parse_size(env_value) + except ValueError as exc: + raise ValueError(f'Invalid environment variable {env_var}: {exc}') + + msg = (f'{free_bytes/1e9} GB memory required, but environment variable ' + f'NPY_AVAILABLE_MEM={env_value} set') + else: + mem_free = _get_mem_available() + + if mem_free is None: + msg = ("Could not determine available memory; set NPY_AVAILABLE_MEM " + "environment variable (e.g. NPY_AVAILABLE_MEM=16GB) to run " + "the test.") + mem_free = -1 + else: + msg = f'{free_bytes/1e9} GB memory required, but {mem_free/1e9} GB available' + + return msg if mem_free < free_bytes else None + + +def _parse_size(size_str): + """Convert memory size strings ('12 GB' etc.) to float""" + suffixes = {'': 1, 'b': 1, + 'k': 1000, 'm': 1000**2, 'g': 1000**3, 't': 1000**4, + 'kb': 1000, 'mb': 1000**2, 'gb': 1000**3, 'tb': 1000**4, + 'kib': 1024, 'mib': 1024**2, 'gib': 1024**3, 'tib': 1024**4} + + size_re = re.compile(r'^\s*(\d+|\d+\.\d+)\s*({0})\s*$'.format( + '|'.join(suffixes.keys())), re.I) + + m = size_re.match(size_str.lower()) + if not m or m.group(2) not in suffixes: + raise ValueError(f'value {size_str!r} not a valid size') + return int(float(m.group(1)) * suffixes[m.group(2)]) + + +def _get_mem_available(): + """Return available memory in bytes, or None if unknown.""" + try: + import psutil + return psutil.virtual_memory().available + except (ImportError, AttributeError): + pass + + if sys.platform.startswith('linux'): + info = {} + with open('/proc/meminfo', 'r') as f: + for line in f: + p = line.split() + info[p[0].strip(':').lower()] = int(p[1]) * 1024 + + if 'memavailable' in info: + # Linux >= 3.14 + return info['memavailable'] + else: + return info['memfree'] + info['cached'] + + return None + + +def _no_tracing(func): + """ + Decorator to temporarily turn off tracing for the duration of a test. + Needed in tests that check refcounting, otherwise the tracing itself + influences the refcounts + """ + if not hasattr(sys, 'gettrace'): + return func + else: + @wraps(func) + def wrapper(*args, **kwargs): + original_trace = sys.gettrace() + try: + sys.settrace(None) + return func(*args, **kwargs) + finally: + sys.settrace(original_trace) + return wrapper + diff --git a/venv/Lib/site-packages/numpy/testing/print_coercion_tables.py b/venv/Lib/site-packages/numpy/testing/print_coercion_tables.py new file mode 100644 index 0000000..3a447cd --- /dev/null +++ b/venv/Lib/site-packages/numpy/testing/print_coercion_tables.py @@ -0,0 +1,199 @@ +#!/usr/bin/env python3 +"""Prints type-coercion tables for the built-in NumPy types + +""" +import numpy as np +from collections import namedtuple + +# Generic object that can be added, but doesn't do anything else +class GenericObject: + def __init__(self, v): + self.v = v + + def __add__(self, other): + return self + + def __radd__(self, other): + return self + + dtype = np.dtype('O') + +def print_cancast_table(ntypes): + print('X', end=' ') + for char in ntypes: + print(char, end=' ') + print() + for row in ntypes: + print(row, end=' ') + for col in ntypes: + if np.can_cast(row, col, "equiv"): + cast = "#" + elif np.can_cast(row, col, "safe"): + cast = "=" + elif np.can_cast(row, col, "same_kind"): + cast = "~" + elif np.can_cast(row, col, "unsafe"): + cast = "." + else: + cast = " " + print(cast, end=' ') + print() + +def print_coercion_table(ntypes, inputfirstvalue, inputsecondvalue, firstarray, use_promote_types=False): + print('+', end=' ') + for char in ntypes: + print(char, end=' ') + print() + for row in ntypes: + if row == 'O': + rowtype = GenericObject + else: + rowtype = np.obj2sctype(row) + + print(row, end=' ') + for col in ntypes: + if col == 'O': + coltype = GenericObject + else: + coltype = np.obj2sctype(col) + try: + if firstarray: + rowvalue = np.array([rowtype(inputfirstvalue)], dtype=rowtype) + else: + rowvalue = rowtype(inputfirstvalue) + colvalue = coltype(inputsecondvalue) + if use_promote_types: + char = np.promote_types(rowvalue.dtype, colvalue.dtype).char + else: + value = np.add(rowvalue, colvalue) + if isinstance(value, np.ndarray): + char = value.dtype.char + else: + char = np.dtype(type(value)).char + except ValueError: + char = '!' + except OverflowError: + char = '@' + except TypeError: + char = '#' + print(char, end=' ') + print() + + +def print_new_cast_table(*, can_cast=True, legacy=False, flags=False): + """Prints new casts, the values given are default "can-cast" values, not + actual ones. + """ + from numpy.core._multiarray_tests import get_all_cast_information + + cast_table = { + 0 : "#", # No cast (classify as equivalent here) + 1 : "#", # equivalent casting + 2 : "=", # safe casting + 3 : "~", # same-kind casting + 4 : ".", # unsafe casting + } + flags_table = { + 0 : "â–—", 7: "â–ˆ", + 1: "â–š", 2: "â–", 4: "â–„", + 3: "â–œ", 5: "â–™", + 6: "â–Ÿ", + } + + cast_info = namedtuple("cast_info", ["can_cast", "legacy", "flags"]) + no_cast_info = cast_info(" ", " ", " ") + + casts = get_all_cast_information() + table = {} + dtypes = set() + for cast in casts: + dtypes.add(cast["from"]) + dtypes.add(cast["to"]) + + if cast["from"] not in table: + table[cast["from"]] = {} + to_dict = table[cast["from"]] + + can_cast = cast_table[cast["casting"]] + legacy = "L" if cast["legacy"] else "." + flags = 0 + if cast["requires_pyapi"]: + flags |= 1 + if cast["supports_unaligned"]: + flags |= 2 + if cast["no_floatingpoint_errors"]: + flags |= 4 + + flags = flags_table[flags] + to_dict[cast["to"]] = cast_info(can_cast=can_cast, legacy=legacy, flags=flags) + + # The np.dtype(x.type) is a bit strange, because dtype classes do + # not expose much yet. + types = np.typecodes["All"] + def sorter(x): + # This is a bit weird hack, to get a table as close as possible to + # the one printing all typecodes (but expecting user-dtypes). + dtype = np.dtype(x.type) + try: + indx = types.index(dtype.char) + except ValueError: + indx = np.inf + return (indx, dtype.char) + + dtypes = sorted(dtypes, key=sorter) + + def print_table(field="can_cast"): + print('X', end=' ') + for dt in dtypes: + print(np.dtype(dt.type).char, end=' ') + print() + for from_dt in dtypes: + print(np.dtype(from_dt.type).char, end=' ') + row = table.get(from_dt, {}) + for to_dt in dtypes: + print(getattr(row.get(to_dt, no_cast_info), field), end=' ') + print() + + if can_cast: + # Print the actual table: + print() + print("Casting: # is equivalent, = is safe, ~ is same-kind, and . is unsafe") + print() + print_table("can_cast") + + if legacy: + print() + print("L denotes a legacy cast . a non-legacy one.") + print() + print_table("legacy") + + if flags: + print() + print(f"{flags_table[0]}: no flags, {flags_table[1]}: PyAPI, " + f"{flags_table[2]}: supports unaligned, {flags_table[4]}: no-float-errors") + print() + print_table("flags") + + +if __name__ == '__main__': + print("can cast") + print_cancast_table(np.typecodes['All']) + print() + print("In these tables, ValueError is '!', OverflowError is '@', TypeError is '#'") + print() + print("scalar + scalar") + print_coercion_table(np.typecodes['All'], 0, 0, False) + print() + print("scalar + neg scalar") + print_coercion_table(np.typecodes['All'], 0, -1, False) + print() + print("array + scalar") + print_coercion_table(np.typecodes['All'], 0, 0, True) + print() + print("array + neg scalar") + print_coercion_table(np.typecodes['All'], 0, -1, True) + print() + print("promote_types") + print_coercion_table(np.typecodes['All'], 0, 0, False, True) + print("New casting type promotion:") + print_new_cast_table(can_cast=True, legacy=True, flags=True) diff --git a/venv/Lib/site-packages/numpy/testing/setup.py b/venv/Lib/site-packages/numpy/testing/setup.py new file mode 100644 index 0000000..7652a94 --- /dev/null +++ b/venv/Lib/site-packages/numpy/testing/setup.py @@ -0,0 +1,20 @@ +#!/usr/bin/env python3 + +def configuration(parent_package='',top_path=None): + from numpy.distutils.misc_util import Configuration + config = Configuration('testing', parent_package, top_path) + + config.add_subpackage('_private') + config.add_subpackage('tests') + config.add_data_files('*.pyi') + return config + +if __name__ == '__main__': + from numpy.distutils.core import setup + setup(maintainer="NumPy Developers", + maintainer_email="numpy-dev@numpy.org", + description="NumPy test module", + url="https://www.numpy.org", + license="NumPy License (BSD Style)", + configuration=configuration, + ) diff --git a/venv/Lib/site-packages/numpy/testing/tests/__init__.py b/venv/Lib/site-packages/numpy/testing/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/venv/Lib/site-packages/numpy/testing/tests/test_decorators.py b/venv/Lib/site-packages/numpy/testing/tests/test_decorators.py new file mode 100644 index 0000000..b60d6df --- /dev/null +++ b/venv/Lib/site-packages/numpy/testing/tests/test_decorators.py @@ -0,0 +1,210 @@ +""" +Test the decorators from ``testing.decorators``. + +""" +import warnings +import pytest + +from numpy.testing import ( + assert_, assert_raises, dec, SkipTest, KnownFailureException, + ) + + +try: + with warnings.catch_warnings(): + warnings.simplefilter("always") + import nose # noqa: F401 +except ImportError: + HAVE_NOSE = False +else: + HAVE_NOSE = True + + +@pytest.mark.skipif(not HAVE_NOSE, reason="Needs nose") +class TestNoseDecorators: + # These tests are run in a class for simplicity while still + # getting a report on each, skipped or success. + + class DidntSkipException(Exception): + pass + + def test_slow(self): + @dec.slow + def slow_func(x, y, z): + pass + + assert_(slow_func.slow) + + def test_setastest(self): + @dec.setastest() + def f_default(a): + pass + + @dec.setastest(True) + def f_istest(a): + pass + + @dec.setastest(False) + def f_isnottest(a): + pass + + assert_(f_default.__test__) + assert_(f_istest.__test__) + assert_(not f_isnottest.__test__) + + def test_skip_functions_hardcoded(self): + @dec.skipif(True) + def f1(x): + raise self.DidntSkipException + + try: + f1('a') + except self.DidntSkipException: + raise Exception('Failed to skip') + except SkipTest().__class__: + pass + + @dec.skipif(False) + def f2(x): + raise self.DidntSkipException + + try: + f2('a') + except self.DidntSkipException: + pass + except SkipTest().__class__: + raise Exception('Skipped when not expected to') + + def test_skip_functions_callable(self): + def skip_tester(): + return skip_flag == 'skip me!' + + @dec.skipif(skip_tester) + def f1(x): + raise self.DidntSkipException + + try: + skip_flag = 'skip me!' + f1('a') + except self.DidntSkipException: + raise Exception('Failed to skip') + except SkipTest().__class__: + pass + + @dec.skipif(skip_tester) + def f2(x): + raise self.DidntSkipException + + try: + skip_flag = 'five is right out!' + f2('a') + except self.DidntSkipException: + pass + except SkipTest().__class__: + raise Exception('Skipped when not expected to') + + def test_skip_generators_hardcoded(self): + @dec.knownfailureif(True, "This test is known to fail") + def g1(x): + yield from range(x) + + try: + for j in g1(10): + pass + except KnownFailureException().__class__: + pass + else: + raise Exception('Failed to mark as known failure') + + @dec.knownfailureif(False, "This test is NOT known to fail") + def g2(x): + yield from range(x) + raise self.DidntSkipException('FAIL') + + try: + for j in g2(10): + pass + except KnownFailureException().__class__: + raise Exception('Marked incorrectly as known failure') + except self.DidntSkipException: + pass + + def test_skip_generators_callable(self): + def skip_tester(): + return skip_flag == 'skip me!' + + @dec.knownfailureif(skip_tester, "This test is known to fail") + def g1(x): + yield from range(x) + + try: + skip_flag = 'skip me!' + for j in g1(10): + pass + except KnownFailureException().__class__: + pass + else: + raise Exception('Failed to mark as known failure') + + @dec.knownfailureif(skip_tester, "This test is NOT known to fail") + def g2(x): + yield from range(x) + raise self.DidntSkipException('FAIL') + + try: + skip_flag = 'do not skip' + for j in g2(10): + pass + except KnownFailureException().__class__: + raise Exception('Marked incorrectly as known failure') + except self.DidntSkipException: + pass + + def test_deprecated(self): + @dec.deprecated(True) + def non_deprecated_func(): + pass + + @dec.deprecated() + def deprecated_func(): + import warnings + warnings.warn("TEST: deprecated func", DeprecationWarning) + + @dec.deprecated() + def deprecated_func2(): + import warnings + warnings.warn("AHHHH") + raise ValueError + + @dec.deprecated() + def deprecated_func3(): + import warnings + warnings.warn("AHHHH") + + # marked as deprecated, but does not raise DeprecationWarning + assert_raises(AssertionError, non_deprecated_func) + # should be silent + deprecated_func() + with warnings.catch_warnings(record=True): + warnings.simplefilter("always") # do not propagate unrelated warnings + # fails if deprecated decorator just disables test. See #1453. + assert_raises(ValueError, deprecated_func2) + # warning is not a DeprecationWarning + assert_raises(AssertionError, deprecated_func3) + + def test_parametrize(self): + # dec.parametrize assumes that it is being run by nose. Because + # we are running under pytest, we need to explicitly check the + # results. + @dec.parametrize('base, power, expected', + [(1, 1, 1), + (2, 1, 2), + (2, 2, 4)]) + def check_parametrize(base, power, expected): + assert_(base**power == expected) + + count = 0 + for test in check_parametrize(): + test[0](*test[1:]) + count += 1 + assert_(count == 3) diff --git a/venv/Lib/site-packages/numpy/testing/tests/test_doctesting.py b/venv/Lib/site-packages/numpy/testing/tests/test_doctesting.py new file mode 100644 index 0000000..92c2156 --- /dev/null +++ b/venv/Lib/site-packages/numpy/testing/tests/test_doctesting.py @@ -0,0 +1,57 @@ +""" Doctests for NumPy-specific nose/doctest modifications + +""" +#FIXME: None of these tests is run, because 'check' is not a recognized +# testing prefix. + +# try the #random directive on the output line +def check_random_directive(): + ''' + >>> 2+2 + #random: may vary on your system + ''' + +# check the implicit "import numpy as np" +def check_implicit_np(): + ''' + >>> np.array([1,2,3]) + array([1, 2, 3]) + ''' + +# there's some extraneous whitespace around the correct responses +def check_whitespace_enabled(): + ''' + # whitespace after the 3 + >>> 1+2 + 3 + + # whitespace before the 7 + >>> 3+4 + 7 + ''' + +def check_empty_output(): + """ Check that no output does not cause an error. + + This is related to nose bug 445; the numpy plugin changed the + doctest-result-variable default and therefore hit this bug: + http://code.google.com/p/python-nose/issues/detail?id=445 + + >>> a = 10 + """ + +def check_skip(): + """ Check skip directive + + The test below should not run + + >>> 1/0 #doctest: +SKIP + """ + + +if __name__ == '__main__': + # Run tests outside numpy test rig + import nose + from numpy.testing.noseclasses import NumpyDoctest + argv = ['', __file__, '--with-numpydoctest'] + nose.core.TestProgram(argv=argv, addplugins=[NumpyDoctest()]) diff --git a/venv/Lib/site-packages/numpy/testing/tests/test_utils.py b/venv/Lib/site-packages/numpy/testing/tests/test_utils.py new file mode 100644 index 0000000..261ed97 --- /dev/null +++ b/venv/Lib/site-packages/numpy/testing/tests/test_utils.py @@ -0,0 +1,1614 @@ +import warnings +import sys +import os +import itertools +import pytest +import weakref + +import numpy as np +from numpy.testing import ( + assert_equal, assert_array_equal, assert_almost_equal, + assert_array_almost_equal, assert_array_less, build_err_msg, raises, + assert_raises, assert_warns, assert_no_warnings, assert_allclose, + assert_approx_equal, assert_array_almost_equal_nulp, assert_array_max_ulp, + clear_and_catch_warnings, suppress_warnings, assert_string_equal, assert_, + tempdir, temppath, assert_no_gc_cycles, HAS_REFCOUNT + ) +from numpy.core.overrides import ARRAY_FUNCTION_ENABLED + + +class _GenericTest: + + def _test_equal(self, a, b): + self._assert_func(a, b) + + def _test_not_equal(self, a, b): + with assert_raises(AssertionError): + self._assert_func(a, b) + + def test_array_rank1_eq(self): + """Test two equal array of rank 1 are found equal.""" + a = np.array([1, 2]) + b = np.array([1, 2]) + + self._test_equal(a, b) + + def test_array_rank1_noteq(self): + """Test two different array of rank 1 are found not equal.""" + a = np.array([1, 2]) + b = np.array([2, 2]) + + self._test_not_equal(a, b) + + def test_array_rank2_eq(self): + """Test two equal array of rank 2 are found equal.""" + a = np.array([[1, 2], [3, 4]]) + b = np.array([[1, 2], [3, 4]]) + + self._test_equal(a, b) + + def test_array_diffshape(self): + """Test two arrays with different shapes are found not equal.""" + a = np.array([1, 2]) + b = np.array([[1, 2], [1, 2]]) + + self._test_not_equal(a, b) + + def test_objarray(self): + """Test object arrays.""" + a = np.array([1, 1], dtype=object) + self._test_equal(a, 1) + + def test_array_likes(self): + self._test_equal([1, 2, 3], (1, 2, 3)) + + +class TestArrayEqual(_GenericTest): + + def setup(self): + self._assert_func = assert_array_equal + + def test_generic_rank1(self): + """Test rank 1 array for all dtypes.""" + def foo(t): + a = np.empty(2, t) + a.fill(1) + b = a.copy() + c = a.copy() + c.fill(0) + self._test_equal(a, b) + self._test_not_equal(c, b) + + # Test numeric types and object + for t in '?bhilqpBHILQPfdgFDG': + foo(t) + + # Test strings + for t in ['S1', 'U1']: + foo(t) + + def test_0_ndim_array(self): + x = np.array(473963742225900817127911193656584771) + y = np.array(18535119325151578301457182298393896) + assert_raises(AssertionError, self._assert_func, x, y) + + y = x + self._assert_func(x, y) + + x = np.array(43) + y = np.array(10) + assert_raises(AssertionError, self._assert_func, x, y) + + y = x + self._assert_func(x, y) + + def test_generic_rank3(self): + """Test rank 3 array for all dtypes.""" + def foo(t): + a = np.empty((4, 2, 3), t) + a.fill(1) + b = a.copy() + c = a.copy() + c.fill(0) + self._test_equal(a, b) + self._test_not_equal(c, b) + + # Test numeric types and object + for t in '?bhilqpBHILQPfdgFDG': + foo(t) + + # Test strings + for t in ['S1', 'U1']: + foo(t) + + def test_nan_array(self): + """Test arrays with nan values in them.""" + a = np.array([1, 2, np.nan]) + b = np.array([1, 2, np.nan]) + + self._test_equal(a, b) + + c = np.array([1, 2, 3]) + self._test_not_equal(c, b) + + def test_string_arrays(self): + """Test two arrays with different shapes are found not equal.""" + a = np.array(['floupi', 'floupa']) + b = np.array(['floupi', 'floupa']) + + self._test_equal(a, b) + + c = np.array(['floupipi', 'floupa']) + + self._test_not_equal(c, b) + + def test_recarrays(self): + """Test record arrays.""" + a = np.empty(2, [('floupi', float), ('floupa', float)]) + a['floupi'] = [1, 2] + a['floupa'] = [1, 2] + b = a.copy() + + self._test_equal(a, b) + + c = np.empty(2, [('floupipi', float), ('floupa', float)]) + c['floupipi'] = a['floupi'].copy() + c['floupa'] = a['floupa'].copy() + + with suppress_warnings() as sup: + l = sup.record(FutureWarning, message="elementwise == ") + self._test_not_equal(c, b) + assert_equal(len(l), 1) + + def test_masked_nan_inf(self): + # Regression test for gh-11121 + a = np.ma.MaskedArray([3., 4., 6.5], mask=[False, True, False]) + b = np.array([3., np.nan, 6.5]) + self._test_equal(a, b) + self._test_equal(b, a) + a = np.ma.MaskedArray([3., 4., 6.5], mask=[True, False, False]) + b = np.array([np.inf, 4., 6.5]) + self._test_equal(a, b) + self._test_equal(b, a) + + def test_subclass_that_overrides_eq(self): + # While we cannot guarantee testing functions will always work for + # subclasses, the tests should ideally rely only on subclasses having + # comparison operators, not on them being able to store booleans + # (which, e.g., astropy Quantity cannot usefully do). See gh-8452. + class MyArray(np.ndarray): + def __eq__(self, other): + return bool(np.equal(self, other).all()) + + def __ne__(self, other): + return not self == other + + a = np.array([1., 2.]).view(MyArray) + b = np.array([2., 3.]).view(MyArray) + assert_(type(a == a), bool) + assert_(a == a) + assert_(a != b) + self._test_equal(a, a) + self._test_not_equal(a, b) + self._test_not_equal(b, a) + + @pytest.mark.skipif( + not ARRAY_FUNCTION_ENABLED, reason='requires __array_function__') + def test_subclass_that_does_not_implement_npall(self): + class MyArray(np.ndarray): + def __array_function__(self, *args, **kwargs): + return NotImplemented + + a = np.array([1., 2.]).view(MyArray) + b = np.array([2., 3.]).view(MyArray) + with assert_raises(TypeError): + np.all(a) + self._test_equal(a, a) + self._test_not_equal(a, b) + self._test_not_equal(b, a) + + +class TestBuildErrorMessage: + + def test_build_err_msg_defaults(self): + x = np.array([1.00001, 2.00002, 3.00003]) + y = np.array([1.00002, 2.00003, 3.00004]) + err_msg = 'There is a mismatch' + + a = build_err_msg([x, y], err_msg) + b = ('\nItems are not equal: There is a mismatch\n ACTUAL: array([' + '1.00001, 2.00002, 3.00003])\n DESIRED: array([1.00002, ' + '2.00003, 3.00004])') + assert_equal(a, b) + + def test_build_err_msg_no_verbose(self): + x = np.array([1.00001, 2.00002, 3.00003]) + y = np.array([1.00002, 2.00003, 3.00004]) + err_msg = 'There is a mismatch' + + a = build_err_msg([x, y], err_msg, verbose=False) + b = '\nItems are not equal: There is a mismatch' + assert_equal(a, b) + + def test_build_err_msg_custom_names(self): + x = np.array([1.00001, 2.00002, 3.00003]) + y = np.array([1.00002, 2.00003, 3.00004]) + err_msg = 'There is a mismatch' + + a = build_err_msg([x, y], err_msg, names=('FOO', 'BAR')) + b = ('\nItems are not equal: There is a mismatch\n FOO: array([' + '1.00001, 2.00002, 3.00003])\n BAR: array([1.00002, 2.00003, ' + '3.00004])') + assert_equal(a, b) + + def test_build_err_msg_custom_precision(self): + x = np.array([1.000000001, 2.00002, 3.00003]) + y = np.array([1.000000002, 2.00003, 3.00004]) + err_msg = 'There is a mismatch' + + a = build_err_msg([x, y], err_msg, precision=10) + b = ('\nItems are not equal: There is a mismatch\n ACTUAL: array([' + '1.000000001, 2.00002 , 3.00003 ])\n DESIRED: array([' + '1.000000002, 2.00003 , 3.00004 ])') + assert_equal(a, b) + + +class TestEqual(TestArrayEqual): + + def setup(self): + self._assert_func = assert_equal + + def test_nan_items(self): + self._assert_func(np.nan, np.nan) + self._assert_func([np.nan], [np.nan]) + self._test_not_equal(np.nan, [np.nan]) + self._test_not_equal(np.nan, 1) + + def test_inf_items(self): + self._assert_func(np.inf, np.inf) + self._assert_func([np.inf], [np.inf]) + self._test_not_equal(np.inf, [np.inf]) + + def test_datetime(self): + self._test_equal( + np.datetime64("2017-01-01", "s"), + np.datetime64("2017-01-01", "s") + ) + self._test_equal( + np.datetime64("2017-01-01", "s"), + np.datetime64("2017-01-01", "m") + ) + + # gh-10081 + self._test_not_equal( + np.datetime64("2017-01-01", "s"), + np.datetime64("2017-01-02", "s") + ) + self._test_not_equal( + np.datetime64("2017-01-01", "s"), + np.datetime64("2017-01-02", "m") + ) + + def test_nat_items(self): + # not a datetime + nadt_no_unit = np.datetime64("NaT") + nadt_s = np.datetime64("NaT", "s") + nadt_d = np.datetime64("NaT", "ns") + # not a timedelta + natd_no_unit = np.timedelta64("NaT") + natd_s = np.timedelta64("NaT", "s") + natd_d = np.timedelta64("NaT", "ns") + + dts = [nadt_no_unit, nadt_s, nadt_d] + tds = [natd_no_unit, natd_s, natd_d] + for a, b in itertools.product(dts, dts): + self._assert_func(a, b) + self._assert_func([a], [b]) + self._test_not_equal([a], b) + + for a, b in itertools.product(tds, tds): + self._assert_func(a, b) + self._assert_func([a], [b]) + self._test_not_equal([a], b) + + for a, b in itertools.product(tds, dts): + self._test_not_equal(a, b) + self._test_not_equal(a, [b]) + self._test_not_equal([a], [b]) + self._test_not_equal([a], np.datetime64("2017-01-01", "s")) + self._test_not_equal([b], np.datetime64("2017-01-01", "s")) + self._test_not_equal([a], np.timedelta64(123, "s")) + self._test_not_equal([b], np.timedelta64(123, "s")) + + def test_non_numeric(self): + self._assert_func('ab', 'ab') + self._test_not_equal('ab', 'abb') + + def test_complex_item(self): + self._assert_func(complex(1, 2), complex(1, 2)) + self._assert_func(complex(1, np.nan), complex(1, np.nan)) + self._test_not_equal(complex(1, np.nan), complex(1, 2)) + self._test_not_equal(complex(np.nan, 1), complex(1, np.nan)) + self._test_not_equal(complex(np.nan, np.inf), complex(np.nan, 2)) + + def test_negative_zero(self): + self._test_not_equal(np.PZERO, np.NZERO) + + def test_complex(self): + x = np.array([complex(1, 2), complex(1, np.nan)]) + y = np.array([complex(1, 2), complex(1, 2)]) + self._assert_func(x, x) + self._test_not_equal(x, y) + + def test_object(self): + #gh-12942 + import datetime + a = np.array([datetime.datetime(2000, 1, 1), + datetime.datetime(2000, 1, 2)]) + self._test_not_equal(a, a[::-1]) + + +class TestArrayAlmostEqual(_GenericTest): + + def setup(self): + self._assert_func = assert_array_almost_equal + + def test_closeness(self): + # Note that in the course of time we ended up with + # `abs(x - y) < 1.5 * 10**(-decimal)` + # instead of the previously documented + # `abs(x - y) < 0.5 * 10**(-decimal)` + # so this check serves to preserve the wrongness. + + # test scalars + self._assert_func(1.499999, 0.0, decimal=0) + assert_raises(AssertionError, + lambda: self._assert_func(1.5, 0.0, decimal=0)) + + # test arrays + self._assert_func([1.499999], [0.0], decimal=0) + assert_raises(AssertionError, + lambda: self._assert_func([1.5], [0.0], decimal=0)) + + def test_simple(self): + x = np.array([1234.2222]) + y = np.array([1234.2223]) + + self._assert_func(x, y, decimal=3) + self._assert_func(x, y, decimal=4) + assert_raises(AssertionError, + lambda: self._assert_func(x, y, decimal=5)) + + def test_nan(self): + anan = np.array([np.nan]) + aone = np.array([1]) + ainf = np.array([np.inf]) + self._assert_func(anan, anan) + assert_raises(AssertionError, + lambda: self._assert_func(anan, aone)) + assert_raises(AssertionError, + lambda: self._assert_func(anan, ainf)) + assert_raises(AssertionError, + lambda: self._assert_func(ainf, anan)) + + def test_inf(self): + a = np.array([[1., 2.], [3., 4.]]) + b = a.copy() + a[0, 0] = np.inf + assert_raises(AssertionError, + lambda: self._assert_func(a, b)) + b[0, 0] = -np.inf + assert_raises(AssertionError, + lambda: self._assert_func(a, b)) + + def test_subclass(self): + a = np.array([[1., 2.], [3., 4.]]) + b = np.ma.masked_array([[1., 2.], [0., 4.]], + [[False, False], [True, False]]) + self._assert_func(a, b) + self._assert_func(b, a) + self._assert_func(b, b) + + # Test fully masked as well (see gh-11123). + a = np.ma.MaskedArray(3.5, mask=True) + b = np.array([3., 4., 6.5]) + self._test_equal(a, b) + self._test_equal(b, a) + a = np.ma.masked + b = np.array([3., 4., 6.5]) + self._test_equal(a, b) + self._test_equal(b, a) + a = np.ma.MaskedArray([3., 4., 6.5], mask=[True, True, True]) + b = np.array([1., 2., 3.]) + self._test_equal(a, b) + self._test_equal(b, a) + a = np.ma.MaskedArray([3., 4., 6.5], mask=[True, True, True]) + b = np.array(1.) + self._test_equal(a, b) + self._test_equal(b, a) + + def test_subclass_that_cannot_be_bool(self): + # While we cannot guarantee testing functions will always work for + # subclasses, the tests should ideally rely only on subclasses having + # comparison operators, not on them being able to store booleans + # (which, e.g., astropy Quantity cannot usefully do). See gh-8452. + class MyArray(np.ndarray): + def __eq__(self, other): + return super(MyArray, self).__eq__(other).view(np.ndarray) + + def __lt__(self, other): + return super(MyArray, self).__lt__(other).view(np.ndarray) + + def all(self, *args, **kwargs): + raise NotImplementedError + + a = np.array([1., 2.]).view(MyArray) + self._assert_func(a, a) + + +class TestAlmostEqual(_GenericTest): + + def setup(self): + self._assert_func = assert_almost_equal + + def test_closeness(self): + # Note that in the course of time we ended up with + # `abs(x - y) < 1.5 * 10**(-decimal)` + # instead of the previously documented + # `abs(x - y) < 0.5 * 10**(-decimal)` + # so this check serves to preserve the wrongness. + + # test scalars + self._assert_func(1.499999, 0.0, decimal=0) + assert_raises(AssertionError, + lambda: self._assert_func(1.5, 0.0, decimal=0)) + + # test arrays + self._assert_func([1.499999], [0.0], decimal=0) + assert_raises(AssertionError, + lambda: self._assert_func([1.5], [0.0], decimal=0)) + + def test_nan_item(self): + self._assert_func(np.nan, np.nan) + assert_raises(AssertionError, + lambda: self._assert_func(np.nan, 1)) + assert_raises(AssertionError, + lambda: self._assert_func(np.nan, np.inf)) + assert_raises(AssertionError, + lambda: self._assert_func(np.inf, np.nan)) + + def test_inf_item(self): + self._assert_func(np.inf, np.inf) + self._assert_func(-np.inf, -np.inf) + assert_raises(AssertionError, + lambda: self._assert_func(np.inf, 1)) + assert_raises(AssertionError, + lambda: self._assert_func(-np.inf, np.inf)) + + def test_simple_item(self): + self._test_not_equal(1, 2) + + def test_complex_item(self): + self._assert_func(complex(1, 2), complex(1, 2)) + self._assert_func(complex(1, np.nan), complex(1, np.nan)) + self._assert_func(complex(np.inf, np.nan), complex(np.inf, np.nan)) + self._test_not_equal(complex(1, np.nan), complex(1, 2)) + self._test_not_equal(complex(np.nan, 1), complex(1, np.nan)) + self._test_not_equal(complex(np.nan, np.inf), complex(np.nan, 2)) + + def test_complex(self): + x = np.array([complex(1, 2), complex(1, np.nan)]) + z = np.array([complex(1, 2), complex(np.nan, 1)]) + y = np.array([complex(1, 2), complex(1, 2)]) + self._assert_func(x, x) + self._test_not_equal(x, y) + self._test_not_equal(x, z) + + def test_error_message(self): + """Check the message is formatted correctly for the decimal value. + Also check the message when input includes inf or nan (gh12200)""" + x = np.array([1.00000000001, 2.00000000002, 3.00003]) + y = np.array([1.00000000002, 2.00000000003, 3.00004]) + + # Test with a different amount of decimal digits + with pytest.raises(AssertionError) as exc_info: + self._assert_func(x, y, decimal=12) + msgs = str(exc_info.value).split('\n') + assert_equal(msgs[3], 'Mismatched elements: 3 / 3 (100%)') + assert_equal(msgs[4], 'Max absolute difference: 1.e-05') + assert_equal(msgs[5], 'Max relative difference: 3.33328889e-06') + assert_equal( + msgs[6], + ' x: array([1.00000000001, 2.00000000002, 3.00003 ])') + assert_equal( + msgs[7], + ' y: array([1.00000000002, 2.00000000003, 3.00004 ])') + + # With the default value of decimal digits, only the 3rd element + # differs. Note that we only check for the formatting of the arrays + # themselves. + with pytest.raises(AssertionError) as exc_info: + self._assert_func(x, y) + msgs = str(exc_info.value).split('\n') + assert_equal(msgs[3], 'Mismatched elements: 1 / 3 (33.3%)') + assert_equal(msgs[4], 'Max absolute difference: 1.e-05') + assert_equal(msgs[5], 'Max relative difference: 3.33328889e-06') + assert_equal(msgs[6], ' x: array([1. , 2. , 3.00003])') + assert_equal(msgs[7], ' y: array([1. , 2. , 3.00004])') + + # Check the error message when input includes inf + x = np.array([np.inf, 0]) + y = np.array([np.inf, 1]) + with pytest.raises(AssertionError) as exc_info: + self._assert_func(x, y) + msgs = str(exc_info.value).split('\n') + assert_equal(msgs[3], 'Mismatched elements: 1 / 2 (50%)') + assert_equal(msgs[4], 'Max absolute difference: 1.') + assert_equal(msgs[5], 'Max relative difference: 1.') + assert_equal(msgs[6], ' x: array([inf, 0.])') + assert_equal(msgs[7], ' y: array([inf, 1.])') + + # Check the error message when dividing by zero + x = np.array([1, 2]) + y = np.array([0, 0]) + with pytest.raises(AssertionError) as exc_info: + self._assert_func(x, y) + msgs = str(exc_info.value).split('\n') + assert_equal(msgs[3], 'Mismatched elements: 2 / 2 (100%)') + assert_equal(msgs[4], 'Max absolute difference: 2') + assert_equal(msgs[5], 'Max relative difference: inf') + + def test_error_message_2(self): + """Check the message is formatted correctly when either x or y is a scalar.""" + x = 2 + y = np.ones(20) + with pytest.raises(AssertionError) as exc_info: + self._assert_func(x, y) + msgs = str(exc_info.value).split('\n') + assert_equal(msgs[3], 'Mismatched elements: 20 / 20 (100%)') + assert_equal(msgs[4], 'Max absolute difference: 1.') + assert_equal(msgs[5], 'Max relative difference: 1.') + + y = 2 + x = np.ones(20) + with pytest.raises(AssertionError) as exc_info: + self._assert_func(x, y) + msgs = str(exc_info.value).split('\n') + assert_equal(msgs[3], 'Mismatched elements: 20 / 20 (100%)') + assert_equal(msgs[4], 'Max absolute difference: 1.') + assert_equal(msgs[5], 'Max relative difference: 0.5') + + def test_subclass_that_cannot_be_bool(self): + # While we cannot guarantee testing functions will always work for + # subclasses, the tests should ideally rely only on subclasses having + # comparison operators, not on them being able to store booleans + # (which, e.g., astropy Quantity cannot usefully do). See gh-8452. + class MyArray(np.ndarray): + def __eq__(self, other): + return super(MyArray, self).__eq__(other).view(np.ndarray) + + def __lt__(self, other): + return super(MyArray, self).__lt__(other).view(np.ndarray) + + def all(self, *args, **kwargs): + raise NotImplementedError + + a = np.array([1., 2.]).view(MyArray) + self._assert_func(a, a) + + +class TestApproxEqual: + + def setup(self): + self._assert_func = assert_approx_equal + + def test_simple_0d_arrays(self): + x = np.array(1234.22) + y = np.array(1234.23) + + self._assert_func(x, y, significant=5) + self._assert_func(x, y, significant=6) + assert_raises(AssertionError, + lambda: self._assert_func(x, y, significant=7)) + + def test_simple_items(self): + x = 1234.22 + y = 1234.23 + + self._assert_func(x, y, significant=4) + self._assert_func(x, y, significant=5) + self._assert_func(x, y, significant=6) + assert_raises(AssertionError, + lambda: self._assert_func(x, y, significant=7)) + + def test_nan_array(self): + anan = np.array(np.nan) + aone = np.array(1) + ainf = np.array(np.inf) + self._assert_func(anan, anan) + assert_raises(AssertionError, lambda: self._assert_func(anan, aone)) + assert_raises(AssertionError, lambda: self._assert_func(anan, ainf)) + assert_raises(AssertionError, lambda: self._assert_func(ainf, anan)) + + def test_nan_items(self): + anan = np.array(np.nan) + aone = np.array(1) + ainf = np.array(np.inf) + self._assert_func(anan, anan) + assert_raises(AssertionError, lambda: self._assert_func(anan, aone)) + assert_raises(AssertionError, lambda: self._assert_func(anan, ainf)) + assert_raises(AssertionError, lambda: self._assert_func(ainf, anan)) + + +class TestArrayAssertLess: + + def setup(self): + self._assert_func = assert_array_less + + def test_simple_arrays(self): + x = np.array([1.1, 2.2]) + y = np.array([1.2, 2.3]) + + self._assert_func(x, y) + assert_raises(AssertionError, lambda: self._assert_func(y, x)) + + y = np.array([1.0, 2.3]) + + assert_raises(AssertionError, lambda: self._assert_func(x, y)) + assert_raises(AssertionError, lambda: self._assert_func(y, x)) + + def test_rank2(self): + x = np.array([[1.1, 2.2], [3.3, 4.4]]) + y = np.array([[1.2, 2.3], [3.4, 4.5]]) + + self._assert_func(x, y) + assert_raises(AssertionError, lambda: self._assert_func(y, x)) + + y = np.array([[1.0, 2.3], [3.4, 4.5]]) + + assert_raises(AssertionError, lambda: self._assert_func(x, y)) + assert_raises(AssertionError, lambda: self._assert_func(y, x)) + + def test_rank3(self): + x = np.ones(shape=(2, 2, 2)) + y = np.ones(shape=(2, 2, 2))+1 + + self._assert_func(x, y) + assert_raises(AssertionError, lambda: self._assert_func(y, x)) + + y[0, 0, 0] = 0 + + assert_raises(AssertionError, lambda: self._assert_func(x, y)) + assert_raises(AssertionError, lambda: self._assert_func(y, x)) + + def test_simple_items(self): + x = 1.1 + y = 2.2 + + self._assert_func(x, y) + assert_raises(AssertionError, lambda: self._assert_func(y, x)) + + y = np.array([2.2, 3.3]) + + self._assert_func(x, y) + assert_raises(AssertionError, lambda: self._assert_func(y, x)) + + y = np.array([1.0, 3.3]) + + assert_raises(AssertionError, lambda: self._assert_func(x, y)) + + def test_nan_noncompare(self): + anan = np.array(np.nan) + aone = np.array(1) + ainf = np.array(np.inf) + self._assert_func(anan, anan) + assert_raises(AssertionError, lambda: self._assert_func(aone, anan)) + assert_raises(AssertionError, lambda: self._assert_func(anan, aone)) + assert_raises(AssertionError, lambda: self._assert_func(anan, ainf)) + assert_raises(AssertionError, lambda: self._assert_func(ainf, anan)) + + def test_nan_noncompare_array(self): + x = np.array([1.1, 2.2, 3.3]) + anan = np.array(np.nan) + + assert_raises(AssertionError, lambda: self._assert_func(x, anan)) + assert_raises(AssertionError, lambda: self._assert_func(anan, x)) + + x = np.array([1.1, 2.2, np.nan]) + + assert_raises(AssertionError, lambda: self._assert_func(x, anan)) + assert_raises(AssertionError, lambda: self._assert_func(anan, x)) + + y = np.array([1.0, 2.0, np.nan]) + + self._assert_func(y, x) + assert_raises(AssertionError, lambda: self._assert_func(x, y)) + + def test_inf_compare(self): + aone = np.array(1) + ainf = np.array(np.inf) + + self._assert_func(aone, ainf) + self._assert_func(-ainf, aone) + self._assert_func(-ainf, ainf) + assert_raises(AssertionError, lambda: self._assert_func(ainf, aone)) + assert_raises(AssertionError, lambda: self._assert_func(aone, -ainf)) + assert_raises(AssertionError, lambda: self._assert_func(ainf, ainf)) + assert_raises(AssertionError, lambda: self._assert_func(ainf, -ainf)) + assert_raises(AssertionError, lambda: self._assert_func(-ainf, -ainf)) + + def test_inf_compare_array(self): + x = np.array([1.1, 2.2, np.inf]) + ainf = np.array(np.inf) + + assert_raises(AssertionError, lambda: self._assert_func(x, ainf)) + assert_raises(AssertionError, lambda: self._assert_func(ainf, x)) + assert_raises(AssertionError, lambda: self._assert_func(x, -ainf)) + assert_raises(AssertionError, lambda: self._assert_func(-x, -ainf)) + assert_raises(AssertionError, lambda: self._assert_func(-ainf, -x)) + self._assert_func(-ainf, x) + + +@pytest.mark.skip(reason="The raises decorator depends on Nose") +class TestRaises: + + def setup(self): + class MyException(Exception): + pass + + self.e = MyException + + def raises_exception(self, e): + raise e + + def does_not_raise_exception(self): + pass + + def test_correct_catch(self): + raises(self.e)(self.raises_exception)(self.e) # raises? + + def test_wrong_exception(self): + try: + raises(self.e)(self.raises_exception)(RuntimeError) # raises? + except RuntimeError: + return + else: + raise AssertionError("should have caught RuntimeError") + + def test_catch_no_raise(self): + try: + raises(self.e)(self.does_not_raise_exception)() # raises? + except AssertionError: + return + else: + raise AssertionError("should have raised an AssertionError") + + +class TestWarns: + + def test_warn(self): + def f(): + warnings.warn("yo") + return 3 + + before_filters = sys.modules['warnings'].filters[:] + assert_equal(assert_warns(UserWarning, f), 3) + after_filters = sys.modules['warnings'].filters + + assert_raises(AssertionError, assert_no_warnings, f) + assert_equal(assert_no_warnings(lambda x: x, 1), 1) + + # Check that the warnings state is unchanged + assert_equal(before_filters, after_filters, + "assert_warns does not preserver warnings state") + + def test_context_manager(self): + + before_filters = sys.modules['warnings'].filters[:] + with assert_warns(UserWarning): + warnings.warn("yo") + after_filters = sys.modules['warnings'].filters + + def no_warnings(): + with assert_no_warnings(): + warnings.warn("yo") + + assert_raises(AssertionError, no_warnings) + assert_equal(before_filters, after_filters, + "assert_warns does not preserver warnings state") + + def test_warn_wrong_warning(self): + def f(): + warnings.warn("yo", DeprecationWarning) + + failed = False + with warnings.catch_warnings(): + warnings.simplefilter("error", DeprecationWarning) + try: + # Should raise a DeprecationWarning + assert_warns(UserWarning, f) + failed = True + except DeprecationWarning: + pass + + if failed: + raise AssertionError("wrong warning caught by assert_warn") + + +class TestAssertAllclose: + + def test_simple(self): + x = 1e-3 + y = 1e-9 + + assert_allclose(x, y, atol=1) + assert_raises(AssertionError, assert_allclose, x, y) + + a = np.array([x, y, x, y]) + b = np.array([x, y, x, x]) + + assert_allclose(a, b, atol=1) + assert_raises(AssertionError, assert_allclose, a, b) + + b[-1] = y * (1 + 1e-8) + assert_allclose(a, b) + assert_raises(AssertionError, assert_allclose, a, b, rtol=1e-9) + + assert_allclose(6, 10, rtol=0.5) + assert_raises(AssertionError, assert_allclose, 10, 6, rtol=0.5) + + def test_min_int(self): + a = np.array([np.iinfo(np.int_).min], dtype=np.int_) + # Should not raise: + assert_allclose(a, a) + + def test_report_fail_percentage(self): + a = np.array([1, 1, 1, 1]) + b = np.array([1, 1, 1, 2]) + + with pytest.raises(AssertionError) as exc_info: + assert_allclose(a, b) + msg = str(exc_info.value) + assert_('Mismatched elements: 1 / 4 (25%)\n' + 'Max absolute difference: 1\n' + 'Max relative difference: 0.5' in msg) + + def test_equal_nan(self): + a = np.array([np.nan]) + b = np.array([np.nan]) + # Should not raise: + assert_allclose(a, b, equal_nan=True) + + def test_not_equal_nan(self): + a = np.array([np.nan]) + b = np.array([np.nan]) + assert_raises(AssertionError, assert_allclose, a, b, equal_nan=False) + + def test_equal_nan_default(self): + # Make sure equal_nan default behavior remains unchanged. (All + # of these functions use assert_array_compare under the hood.) + # None of these should raise. + a = np.array([np.nan]) + b = np.array([np.nan]) + assert_array_equal(a, b) + assert_array_almost_equal(a, b) + assert_array_less(a, b) + assert_allclose(a, b) + + def test_report_max_relative_error(self): + a = np.array([0, 1]) + b = np.array([0, 2]) + + with pytest.raises(AssertionError) as exc_info: + assert_allclose(a, b) + msg = str(exc_info.value) + assert_('Max relative difference: 0.5' in msg) + + def test_timedelta(self): + # see gh-18286 + a = np.array([[1, 2, 3, "NaT"]], dtype="m8[ns]") + assert_allclose(a, a) + + +class TestArrayAlmostEqualNulp: + + def test_float64_pass(self): + # The number of units of least precision + # In this case, use a few places above the lowest level (ie nulp=1) + nulp = 5 + x = np.linspace(-20, 20, 50, dtype=np.float64) + x = 10**x + x = np.r_[-x, x] + + # Addition + eps = np.finfo(x.dtype).eps + y = x + x*eps*nulp/2. + assert_array_almost_equal_nulp(x, y, nulp) + + # Subtraction + epsneg = np.finfo(x.dtype).epsneg + y = x - x*epsneg*nulp/2. + assert_array_almost_equal_nulp(x, y, nulp) + + def test_float64_fail(self): + nulp = 5 + x = np.linspace(-20, 20, 50, dtype=np.float64) + x = 10**x + x = np.r_[-x, x] + + eps = np.finfo(x.dtype).eps + y = x + x*eps*nulp*2. + assert_raises(AssertionError, assert_array_almost_equal_nulp, + x, y, nulp) + + epsneg = np.finfo(x.dtype).epsneg + y = x - x*epsneg*nulp*2. + assert_raises(AssertionError, assert_array_almost_equal_nulp, + x, y, nulp) + + def test_float64_ignore_nan(self): + # Ignore ULP differences between various NAN's + # Note that MIPS may reverse quiet and signaling nans + # so we use the builtin version as a base. + offset = np.uint64(0xffffffff) + nan1_i64 = np.array(np.nan, dtype=np.float64).view(np.uint64) + nan2_i64 = nan1_i64 ^ offset # nan payload on MIPS is all ones. + nan1_f64 = nan1_i64.view(np.float64) + nan2_f64 = nan2_i64.view(np.float64) + assert_array_max_ulp(nan1_f64, nan2_f64, 0) + + def test_float32_pass(self): + nulp = 5 + x = np.linspace(-20, 20, 50, dtype=np.float32) + x = 10**x + x = np.r_[-x, x] + + eps = np.finfo(x.dtype).eps + y = x + x*eps*nulp/2. + assert_array_almost_equal_nulp(x, y, nulp) + + epsneg = np.finfo(x.dtype).epsneg + y = x - x*epsneg*nulp/2. + assert_array_almost_equal_nulp(x, y, nulp) + + def test_float32_fail(self): + nulp = 5 + x = np.linspace(-20, 20, 50, dtype=np.float32) + x = 10**x + x = np.r_[-x, x] + + eps = np.finfo(x.dtype).eps + y = x + x*eps*nulp*2. + assert_raises(AssertionError, assert_array_almost_equal_nulp, + x, y, nulp) + + epsneg = np.finfo(x.dtype).epsneg + y = x - x*epsneg*nulp*2. + assert_raises(AssertionError, assert_array_almost_equal_nulp, + x, y, nulp) + + def test_float32_ignore_nan(self): + # Ignore ULP differences between various NAN's + # Note that MIPS may reverse quiet and signaling nans + # so we use the builtin version as a base. + offset = np.uint32(0xffff) + nan1_i32 = np.array(np.nan, dtype=np.float32).view(np.uint32) + nan2_i32 = nan1_i32 ^ offset # nan payload on MIPS is all ones. + nan1_f32 = nan1_i32.view(np.float32) + nan2_f32 = nan2_i32.view(np.float32) + assert_array_max_ulp(nan1_f32, nan2_f32, 0) + + def test_float16_pass(self): + nulp = 5 + x = np.linspace(-4, 4, 10, dtype=np.float16) + x = 10**x + x = np.r_[-x, x] + + eps = np.finfo(x.dtype).eps + y = x + x*eps*nulp/2. + assert_array_almost_equal_nulp(x, y, nulp) + + epsneg = np.finfo(x.dtype).epsneg + y = x - x*epsneg*nulp/2. + assert_array_almost_equal_nulp(x, y, nulp) + + def test_float16_fail(self): + nulp = 5 + x = np.linspace(-4, 4, 10, dtype=np.float16) + x = 10**x + x = np.r_[-x, x] + + eps = np.finfo(x.dtype).eps + y = x + x*eps*nulp*2. + assert_raises(AssertionError, assert_array_almost_equal_nulp, + x, y, nulp) + + epsneg = np.finfo(x.dtype).epsneg + y = x - x*epsneg*nulp*2. + assert_raises(AssertionError, assert_array_almost_equal_nulp, + x, y, nulp) + + def test_float16_ignore_nan(self): + # Ignore ULP differences between various NAN's + # Note that MIPS may reverse quiet and signaling nans + # so we use the builtin version as a base. + offset = np.uint16(0xff) + nan1_i16 = np.array(np.nan, dtype=np.float16).view(np.uint16) + nan2_i16 = nan1_i16 ^ offset # nan payload on MIPS is all ones. + nan1_f16 = nan1_i16.view(np.float16) + nan2_f16 = nan2_i16.view(np.float16) + assert_array_max_ulp(nan1_f16, nan2_f16, 0) + + def test_complex128_pass(self): + nulp = 5 + x = np.linspace(-20, 20, 50, dtype=np.float64) + x = 10**x + x = np.r_[-x, x] + xi = x + x*1j + + eps = np.finfo(x.dtype).eps + y = x + x*eps*nulp/2. + assert_array_almost_equal_nulp(xi, x + y*1j, nulp) + assert_array_almost_equal_nulp(xi, y + x*1j, nulp) + # The test condition needs to be at least a factor of sqrt(2) smaller + # because the real and imaginary parts both change + y = x + x*eps*nulp/4. + assert_array_almost_equal_nulp(xi, y + y*1j, nulp) + + epsneg = np.finfo(x.dtype).epsneg + y = x - x*epsneg*nulp/2. + assert_array_almost_equal_nulp(xi, x + y*1j, nulp) + assert_array_almost_equal_nulp(xi, y + x*1j, nulp) + y = x - x*epsneg*nulp/4. + assert_array_almost_equal_nulp(xi, y + y*1j, nulp) + + def test_complex128_fail(self): + nulp = 5 + x = np.linspace(-20, 20, 50, dtype=np.float64) + x = 10**x + x = np.r_[-x, x] + xi = x + x*1j + + eps = np.finfo(x.dtype).eps + y = x + x*eps*nulp*2. + assert_raises(AssertionError, assert_array_almost_equal_nulp, + xi, x + y*1j, nulp) + assert_raises(AssertionError, assert_array_almost_equal_nulp, + xi, y + x*1j, nulp) + # The test condition needs to be at least a factor of sqrt(2) smaller + # because the real and imaginary parts both change + y = x + x*eps*nulp + assert_raises(AssertionError, assert_array_almost_equal_nulp, + xi, y + y*1j, nulp) + + epsneg = np.finfo(x.dtype).epsneg + y = x - x*epsneg*nulp*2. + assert_raises(AssertionError, assert_array_almost_equal_nulp, + xi, x + y*1j, nulp) + assert_raises(AssertionError, assert_array_almost_equal_nulp, + xi, y + x*1j, nulp) + y = x - x*epsneg*nulp + assert_raises(AssertionError, assert_array_almost_equal_nulp, + xi, y + y*1j, nulp) + + def test_complex64_pass(self): + nulp = 5 + x = np.linspace(-20, 20, 50, dtype=np.float32) + x = 10**x + x = np.r_[-x, x] + xi = x + x*1j + + eps = np.finfo(x.dtype).eps + y = x + x*eps*nulp/2. + assert_array_almost_equal_nulp(xi, x + y*1j, nulp) + assert_array_almost_equal_nulp(xi, y + x*1j, nulp) + y = x + x*eps*nulp/4. + assert_array_almost_equal_nulp(xi, y + y*1j, nulp) + + epsneg = np.finfo(x.dtype).epsneg + y = x - x*epsneg*nulp/2. + assert_array_almost_equal_nulp(xi, x + y*1j, nulp) + assert_array_almost_equal_nulp(xi, y + x*1j, nulp) + y = x - x*epsneg*nulp/4. + assert_array_almost_equal_nulp(xi, y + y*1j, nulp) + + def test_complex64_fail(self): + nulp = 5 + x = np.linspace(-20, 20, 50, dtype=np.float32) + x = 10**x + x = np.r_[-x, x] + xi = x + x*1j + + eps = np.finfo(x.dtype).eps + y = x + x*eps*nulp*2. + assert_raises(AssertionError, assert_array_almost_equal_nulp, + xi, x + y*1j, nulp) + assert_raises(AssertionError, assert_array_almost_equal_nulp, + xi, y + x*1j, nulp) + y = x + x*eps*nulp + assert_raises(AssertionError, assert_array_almost_equal_nulp, + xi, y + y*1j, nulp) + + epsneg = np.finfo(x.dtype).epsneg + y = x - x*epsneg*nulp*2. + assert_raises(AssertionError, assert_array_almost_equal_nulp, + xi, x + y*1j, nulp) + assert_raises(AssertionError, assert_array_almost_equal_nulp, + xi, y + x*1j, nulp) + y = x - x*epsneg*nulp + assert_raises(AssertionError, assert_array_almost_equal_nulp, + xi, y + y*1j, nulp) + + +class TestULP: + + def test_equal(self): + x = np.random.randn(10) + assert_array_max_ulp(x, x, maxulp=0) + + def test_single(self): + # Generate 1 + small deviation, check that adding eps gives a few UNL + x = np.ones(10).astype(np.float32) + x += 0.01 * np.random.randn(10).astype(np.float32) + eps = np.finfo(np.float32).eps + assert_array_max_ulp(x, x+eps, maxulp=20) + + def test_double(self): + # Generate 1 + small deviation, check that adding eps gives a few UNL + x = np.ones(10).astype(np.float64) + x += 0.01 * np.random.randn(10).astype(np.float64) + eps = np.finfo(np.float64).eps + assert_array_max_ulp(x, x+eps, maxulp=200) + + def test_inf(self): + for dt in [np.float32, np.float64]: + inf = np.array([np.inf]).astype(dt) + big = np.array([np.finfo(dt).max]) + assert_array_max_ulp(inf, big, maxulp=200) + + def test_nan(self): + # Test that nan is 'far' from small, tiny, inf, max and min + for dt in [np.float32, np.float64]: + if dt == np.float32: + maxulp = 1e6 + else: + maxulp = 1e12 + inf = np.array([np.inf]).astype(dt) + nan = np.array([np.nan]).astype(dt) + big = np.array([np.finfo(dt).max]) + tiny = np.array([np.finfo(dt).tiny]) + zero = np.array([np.PZERO]).astype(dt) + nzero = np.array([np.NZERO]).astype(dt) + assert_raises(AssertionError, + lambda: assert_array_max_ulp(nan, inf, + maxulp=maxulp)) + assert_raises(AssertionError, + lambda: assert_array_max_ulp(nan, big, + maxulp=maxulp)) + assert_raises(AssertionError, + lambda: assert_array_max_ulp(nan, tiny, + maxulp=maxulp)) + assert_raises(AssertionError, + lambda: assert_array_max_ulp(nan, zero, + maxulp=maxulp)) + assert_raises(AssertionError, + lambda: assert_array_max_ulp(nan, nzero, + maxulp=maxulp)) + + +class TestStringEqual: + def test_simple(self): + assert_string_equal("hello", "hello") + assert_string_equal("hello\nmultiline", "hello\nmultiline") + + with pytest.raises(AssertionError) as exc_info: + assert_string_equal("foo\nbar", "hello\nbar") + msg = str(exc_info.value) + assert_equal(msg, "Differences in strings:\n- foo\n+ hello") + + assert_raises(AssertionError, + lambda: assert_string_equal("foo", "hello")) + + def test_regex(self): + assert_string_equal("a+*b", "a+*b") + + assert_raises(AssertionError, + lambda: assert_string_equal("aaa", "a+b")) + + +def assert_warn_len_equal(mod, n_in_context, py34=None, py37=None): + try: + mod_warns = mod.__warningregistry__ + except AttributeError: + # the lack of a __warningregistry__ + # attribute means that no warning has + # occurred; this can be triggered in + # a parallel test scenario, while in + # a serial test scenario an initial + # warning (and therefore the attribute) + # are always created first + mod_warns = {} + + num_warns = len(mod_warns) + # Python 3.4 appears to clear any pre-existing warnings of the same type, + # when raising warnings inside a catch_warnings block. So, there is a + # warning generated by the tests within the context manager, but no + # previous warnings. + if 'version' in mod_warns: + # Python 3 adds a 'version' entry to the registry, + # do not count it. + num_warns -= 1 + + # Behavior of warnings is Python version dependent. Adjust the + # expected result to compensate. In particular, Python 3.7 does + # not make an entry for ignored warnings. + if sys.version_info[:2] >= (3, 7): + if py37 is not None: + n_in_context = py37 + else: + if py34 is not None: + n_in_context = py34 + assert_equal(num_warns, n_in_context) + +def test_warn_len_equal_call_scenarios(): + # assert_warn_len_equal is called under + # varying circumstances depending on serial + # vs. parallel test scenarios; this test + # simply aims to probe both code paths and + # check that no assertion is uncaught + + # parallel scenario -- no warning issued yet + class mod: + pass + + mod_inst = mod() + + assert_warn_len_equal(mod=mod_inst, + n_in_context=0) + + # serial test scenario -- the __warningregistry__ + # attribute should be present + class mod: + def __init__(self): + self.__warningregistry__ = {'warning1':1, + 'warning2':2} + + mod_inst = mod() + assert_warn_len_equal(mod=mod_inst, + n_in_context=2) + + +def _get_fresh_mod(): + # Get this module, with warning registry empty + my_mod = sys.modules[__name__] + try: + my_mod.__warningregistry__.clear() + except AttributeError: + # will not have a __warningregistry__ unless warning has been + # raised in the module at some point + pass + return my_mod + + +def test_clear_and_catch_warnings(): + # Initial state of module, no warnings + my_mod = _get_fresh_mod() + assert_equal(getattr(my_mod, '__warningregistry__', {}), {}) + with clear_and_catch_warnings(modules=[my_mod]): + warnings.simplefilter('ignore') + warnings.warn('Some warning') + assert_equal(my_mod.__warningregistry__, {}) + # Without specified modules, don't clear warnings during context + # Python 3.7 catch_warnings doesn't make an entry for 'ignore'. + with clear_and_catch_warnings(): + warnings.simplefilter('ignore') + warnings.warn('Some warning') + assert_warn_len_equal(my_mod, 1, py37=0) + # Confirm that specifying module keeps old warning, does not add new + with clear_and_catch_warnings(modules=[my_mod]): + warnings.simplefilter('ignore') + warnings.warn('Another warning') + assert_warn_len_equal(my_mod, 1, py37=0) + # Another warning, no module spec does add to warnings dict, except on + # Python 3.4 (see comments in `assert_warn_len_equal`) + # Python 3.7 catch_warnings doesn't make an entry for 'ignore'. + with clear_and_catch_warnings(): + warnings.simplefilter('ignore') + warnings.warn('Another warning') + assert_warn_len_equal(my_mod, 2, py34=1, py37=0) + + +def test_suppress_warnings_module(): + # Initial state of module, no warnings + my_mod = _get_fresh_mod() + assert_equal(getattr(my_mod, '__warningregistry__', {}), {}) + + def warn_other_module(): + # Apply along axis is implemented in python; stacklevel=2 means + # we end up inside its module, not ours. + def warn(arr): + warnings.warn("Some warning 2", stacklevel=2) + return arr + np.apply_along_axis(warn, 0, [0]) + + # Test module based warning suppression: + assert_warn_len_equal(my_mod, 0) + with suppress_warnings() as sup: + sup.record(UserWarning) + # suppress warning from other module (may have .pyc ending), + # if apply_along_axis is moved, had to be changed. + sup.filter(module=np.lib.shape_base) + warnings.warn("Some warning") + warn_other_module() + # Check that the suppression did test the file correctly (this module + # got filtered) + assert_equal(len(sup.log), 1) + assert_equal(sup.log[0].message.args[0], "Some warning") + assert_warn_len_equal(my_mod, 0, py37=0) + sup = suppress_warnings() + # Will have to be changed if apply_along_axis is moved: + sup.filter(module=my_mod) + with sup: + warnings.warn('Some warning') + assert_warn_len_equal(my_mod, 0) + # And test repeat works: + sup.filter(module=my_mod) + with sup: + warnings.warn('Some warning') + assert_warn_len_equal(my_mod, 0) + + # Without specified modules, don't clear warnings during context + # Python 3.7 does not add ignored warnings. + with suppress_warnings(): + warnings.simplefilter('ignore') + warnings.warn('Some warning') + assert_warn_len_equal(my_mod, 1, py37=0) + +def test_suppress_warnings_type(): + # Initial state of module, no warnings + my_mod = _get_fresh_mod() + assert_equal(getattr(my_mod, '__warningregistry__', {}), {}) + + # Test module based warning suppression: + with suppress_warnings() as sup: + sup.filter(UserWarning) + warnings.warn('Some warning') + assert_warn_len_equal(my_mod, 0) + sup = suppress_warnings() + sup.filter(UserWarning) + with sup: + warnings.warn('Some warning') + assert_warn_len_equal(my_mod, 0) + # And test repeat works: + sup.filter(module=my_mod) + with sup: + warnings.warn('Some warning') + assert_warn_len_equal(my_mod, 0) + + # Without specified modules, don't clear warnings during context + # Python 3.7 does not add ignored warnings. + with suppress_warnings(): + warnings.simplefilter('ignore') + warnings.warn('Some warning') + assert_warn_len_equal(my_mod, 1, py37=0) + + +def test_suppress_warnings_decorate_no_record(): + sup = suppress_warnings() + sup.filter(UserWarning) + + @sup + def warn(category): + warnings.warn('Some warning', category) + + with warnings.catch_warnings(record=True) as w: + warnings.simplefilter("always") + warn(UserWarning) # should be supppressed + warn(RuntimeWarning) + assert_equal(len(w), 1) + + +def test_suppress_warnings_record(): + sup = suppress_warnings() + log1 = sup.record() + + with sup: + log2 = sup.record(message='Some other warning 2') + sup.filter(message='Some warning') + warnings.warn('Some warning') + warnings.warn('Some other warning') + warnings.warn('Some other warning 2') + + assert_equal(len(sup.log), 2) + assert_equal(len(log1), 1) + assert_equal(len(log2),1) + assert_equal(log2[0].message.args[0], 'Some other warning 2') + + # Do it again, with the same context to see if some warnings survived: + with sup: + log2 = sup.record(message='Some other warning 2') + sup.filter(message='Some warning') + warnings.warn('Some warning') + warnings.warn('Some other warning') + warnings.warn('Some other warning 2') + + assert_equal(len(sup.log), 2) + assert_equal(len(log1), 1) + assert_equal(len(log2), 1) + assert_equal(log2[0].message.args[0], 'Some other warning 2') + + # Test nested: + with suppress_warnings() as sup: + sup.record() + with suppress_warnings() as sup2: + sup2.record(message='Some warning') + warnings.warn('Some warning') + warnings.warn('Some other warning') + assert_equal(len(sup2.log), 1) + assert_equal(len(sup.log), 1) + + +def test_suppress_warnings_forwarding(): + def warn_other_module(): + # Apply along axis is implemented in python; stacklevel=2 means + # we end up inside its module, not ours. + def warn(arr): + warnings.warn("Some warning", stacklevel=2) + return arr + np.apply_along_axis(warn, 0, [0]) + + with suppress_warnings() as sup: + sup.record() + with suppress_warnings("always"): + for i in range(2): + warnings.warn("Some warning") + + assert_equal(len(sup.log), 2) + + with suppress_warnings() as sup: + sup.record() + with suppress_warnings("location"): + for i in range(2): + warnings.warn("Some warning") + warnings.warn("Some warning") + + assert_equal(len(sup.log), 2) + + with suppress_warnings() as sup: + sup.record() + with suppress_warnings("module"): + for i in range(2): + warnings.warn("Some warning") + warnings.warn("Some warning") + warn_other_module() + + assert_equal(len(sup.log), 2) + + with suppress_warnings() as sup: + sup.record() + with suppress_warnings("once"): + for i in range(2): + warnings.warn("Some warning") + warnings.warn("Some other warning") + warn_other_module() + + assert_equal(len(sup.log), 2) + + +def test_tempdir(): + with tempdir() as tdir: + fpath = os.path.join(tdir, 'tmp') + with open(fpath, 'w'): + pass + assert_(not os.path.isdir(tdir)) + + raised = False + try: + with tempdir() as tdir: + raise ValueError() + except ValueError: + raised = True + assert_(raised) + assert_(not os.path.isdir(tdir)) + + +def test_temppath(): + with temppath() as fpath: + with open(fpath, 'w'): + pass + assert_(not os.path.isfile(fpath)) + + raised = False + try: + with temppath() as fpath: + raise ValueError() + except ValueError: + raised = True + assert_(raised) + assert_(not os.path.isfile(fpath)) + + +class my_cacw(clear_and_catch_warnings): + + class_modules = (sys.modules[__name__],) + + +def test_clear_and_catch_warnings_inherit(): + # Test can subclass and add default modules + my_mod = _get_fresh_mod() + with my_cacw(): + warnings.simplefilter('ignore') + warnings.warn('Some warning') + assert_equal(my_mod.__warningregistry__, {}) + + +@pytest.mark.skipif(not HAS_REFCOUNT, reason="Python lacks refcounts") +class TestAssertNoGcCycles: + """ Test assert_no_gc_cycles """ + def test_passes(self): + def no_cycle(): + b = [] + b.append([]) + return b + + with assert_no_gc_cycles(): + no_cycle() + + assert_no_gc_cycles(no_cycle) + + def test_asserts(self): + def make_cycle(): + a = [] + a.append(a) + a.append(a) + return a + + with assert_raises(AssertionError): + with assert_no_gc_cycles(): + make_cycle() + + with assert_raises(AssertionError): + assert_no_gc_cycles(make_cycle) + + @pytest.mark.slow + def test_fails(self): + """ + Test that in cases where the garbage cannot be collected, we raise an + error, instead of hanging forever trying to clear it. + """ + + class ReferenceCycleInDel: + """ + An object that not only contains a reference cycle, but creates new + cycles whenever it's garbage-collected and its __del__ runs + """ + make_cycle = True + + def __init__(self): + self.cycle = self + + def __del__(self): + # break the current cycle so that `self` can be freed + self.cycle = None + + if ReferenceCycleInDel.make_cycle: + # but create a new one so that the garbage collector has more + # work to do. + ReferenceCycleInDel() + + try: + w = weakref.ref(ReferenceCycleInDel()) + try: + with assert_raises(RuntimeError): + # this will be unable to get a baseline empty garbage + assert_no_gc_cycles(lambda: None) + except AssertionError: + # the above test is only necessary if the GC actually tried to free + # our object anyway, which python 2.7 does not. + if w() is not None: + pytest.skip("GC does not call __del__ on cyclic objects") + raise + + finally: + # make sure that we stop creating reference cycles + ReferenceCycleInDel.make_cycle = False diff --git a/venv/Lib/site-packages/numpy/testing/utils.py b/venv/Lib/site-packages/numpy/testing/utils.py new file mode 100644 index 0000000..753258c --- /dev/null +++ b/venv/Lib/site-packages/numpy/testing/utils.py @@ -0,0 +1,28 @@ +""" +Back compatibility utils module. It will import the appropriate +set of tools + +""" +import warnings + +# 2018-04-04, numpy 1.15.0 ImportWarning +# 2019-09-18, numpy 1.18.0 DeprecatonWarning (changed) +warnings.warn("Importing from numpy.testing.utils is deprecated " + "since 1.15.0, import from numpy.testing instead.", + DeprecationWarning, stacklevel=2) + +from ._private.utils import * + +__all__ = [ + 'assert_equal', 'assert_almost_equal', 'assert_approx_equal', + 'assert_array_equal', 'assert_array_less', 'assert_string_equal', + 'assert_array_almost_equal', 'assert_raises', 'build_err_msg', + 'decorate_methods', 'jiffies', 'memusage', 'print_assert_equal', + 'raises', 'rundocs', 'runstring', 'verbose', 'measure', + 'assert_', 'assert_array_almost_equal_nulp', 'assert_raises_regex', + 'assert_array_max_ulp', 'assert_warns', 'assert_no_warnings', + 'assert_allclose', 'IgnoreException', 'clear_and_catch_warnings', + 'SkipTest', 'KnownFailureException', 'temppath', 'tempdir', 'IS_PYPY', + 'HAS_REFCOUNT', 'suppress_warnings', 'assert_array_compare', + '_assert_valid_refcount', '_gen_alignment_data', 'assert_no_gc_cycles' + ] diff --git a/venv/Lib/site-packages/numpy/tests/__init__.py b/venv/Lib/site-packages/numpy/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/venv/Lib/site-packages/numpy/tests/test_ctypeslib.py b/venv/Lib/site-packages/numpy/tests/test_ctypeslib.py new file mode 100644 index 0000000..af3730d --- /dev/null +++ b/venv/Lib/site-packages/numpy/tests/test_ctypeslib.py @@ -0,0 +1,365 @@ +import sys +import pytest +import weakref + +import numpy as np +from numpy.ctypeslib import ndpointer, load_library, as_array +from numpy.distutils.misc_util import get_shared_lib_extension +from numpy.testing import assert_, assert_array_equal, assert_raises, assert_equal + +try: + import ctypes +except ImportError: + ctypes = None +else: + cdll = None + test_cdll = None + if hasattr(sys, 'gettotalrefcount'): + try: + cdll = load_library('_multiarray_umath_d', np.core._multiarray_umath.__file__) + except OSError: + pass + try: + test_cdll = load_library('_multiarray_tests', np.core._multiarray_tests.__file__) + except OSError: + pass + if cdll is None: + cdll = load_library('_multiarray_umath', np.core._multiarray_umath.__file__) + if test_cdll is None: + test_cdll = load_library('_multiarray_tests', np.core._multiarray_tests.__file__) + + c_forward_pointer = test_cdll.forward_pointer + + +@pytest.mark.skipif(ctypes is None, + reason="ctypes not available in this python") +@pytest.mark.skipif(sys.platform == 'cygwin', + reason="Known to fail on cygwin") +class TestLoadLibrary: + def test_basic(self): + try: + # Should succeed + load_library('_multiarray_umath', np.core._multiarray_umath.__file__) + except ImportError as e: + msg = ("ctypes is not available on this python: skipping the test" + " (import error was: %s)" % str(e)) + print(msg) + + def test_basic2(self): + # Regression for #801: load_library with a full library name + # (including extension) does not work. + try: + try: + so = get_shared_lib_extension(is_python_ext=True) + # Should succeed + load_library('_multiarray_umath%s' % so, np.core._multiarray_umath.__file__) + except ImportError: + print("No distutils available, skipping test.") + except ImportError as e: + msg = ("ctypes is not available on this python: skipping the test" + " (import error was: %s)" % str(e)) + print(msg) + + +class TestNdpointer: + def test_dtype(self): + dt = np.intc + p = ndpointer(dtype=dt) + assert_(p.from_param(np.array([1], dt))) + dt = 'i4') + p = ndpointer(dtype=dt) + p.from_param(np.array([1], dt)) + assert_raises(TypeError, p.from_param, + np.array([1], dt.newbyteorder('swap'))) + dtnames = ['x', 'y'] + dtformats = [np.intc, np.float64] + dtdescr = {'names': dtnames, 'formats': dtformats} + dt = np.dtype(dtdescr) + p = ndpointer(dtype=dt) + assert_(p.from_param(np.zeros((10,), dt))) + samedt = np.dtype(dtdescr) + p = ndpointer(dtype=samedt) + assert_(p.from_param(np.zeros((10,), dt))) + dt2 = np.dtype(dtdescr, align=True) + if dt.itemsize != dt2.itemsize: + assert_raises(TypeError, p.from_param, np.zeros((10,), dt2)) + else: + assert_(p.from_param(np.zeros((10,), dt2))) + + def test_ndim(self): + p = ndpointer(ndim=0) + assert_(p.from_param(np.array(1))) + assert_raises(TypeError, p.from_param, np.array([1])) + p = ndpointer(ndim=1) + assert_raises(TypeError, p.from_param, np.array(1)) + assert_(p.from_param(np.array([1]))) + p = ndpointer(ndim=2) + assert_(p.from_param(np.array([[1]]))) + + def test_shape(self): + p = ndpointer(shape=(1, 2)) + assert_(p.from_param(np.array([[1, 2]]))) + assert_raises(TypeError, p.from_param, np.array([[1], [2]])) + p = ndpointer(shape=()) + assert_(p.from_param(np.array(1))) + + def test_flags(self): + x = np.array([[1, 2], [3, 4]], order='F') + p = ndpointer(flags='FORTRAN') + assert_(p.from_param(x)) + p = ndpointer(flags='CONTIGUOUS') + assert_raises(TypeError, p.from_param, x) + p = ndpointer(flags=x.flags.num) + assert_(p.from_param(x)) + assert_raises(TypeError, p.from_param, np.array([[1, 2], [3, 4]])) + + def test_cache(self): + assert_(ndpointer(dtype=np.float64) is ndpointer(dtype=np.float64)) + + # shapes are normalized + assert_(ndpointer(shape=2) is ndpointer(shape=(2,))) + + # 1.12 <= v < 1.16 had a bug that made these fail + assert_(ndpointer(shape=2) is not ndpointer(ndim=2)) + assert_(ndpointer(ndim=2) is not ndpointer(shape=2)) + +@pytest.mark.skipif(ctypes is None, + reason="ctypes not available on this python installation") +class TestNdpointerCFunc: + def test_arguments(self): + """ Test that arguments are coerced from arrays """ + c_forward_pointer.restype = ctypes.c_void_p + c_forward_pointer.argtypes = (ndpointer(ndim=2),) + + c_forward_pointer(np.zeros((2, 3))) + # too many dimensions + assert_raises( + ctypes.ArgumentError, c_forward_pointer, np.zeros((2, 3, 4))) + + @pytest.mark.parametrize( + 'dt', [ + float, + np.dtype(dict( + formats=['u2') + ct = np.ctypeslib.as_ctypes_type(dt) + assert_equal(ct, ctypes.c_uint16.__ctype_be__) + + dt = np.dtype('u2') + ct = np.ctypeslib.as_ctypes_type(dt) + assert_equal(ct, ctypes.c_uint16) + + def test_subarray(self): + dt = np.dtype((np.int32, (2, 3))) + ct = np.ctypeslib.as_ctypes_type(dt) + assert_equal(ct, 2 * (3 * ctypes.c_int32)) + + def test_structure(self): + dt = np.dtype([ + ('a', np.uint16), + ('b', np.uint32), + ]) + + ct = np.ctypeslib.as_ctypes_type(dt) + assert_(issubclass(ct, ctypes.Structure)) + assert_equal(ctypes.sizeof(ct), dt.itemsize) + assert_equal(ct._fields_, [ + ('a', ctypes.c_uint16), + ('b', ctypes.c_uint32), + ]) + + def test_structure_aligned(self): + dt = np.dtype([ + ('a', np.uint16), + ('b', np.uint32), + ], align=True) + + ct = np.ctypeslib.as_ctypes_type(dt) + assert_(issubclass(ct, ctypes.Structure)) + assert_equal(ctypes.sizeof(ct), dt.itemsize) + assert_equal(ct._fields_, [ + ('a', ctypes.c_uint16), + ('', ctypes.c_char * 2), # padding + ('b', ctypes.c_uint32), + ]) + + def test_union(self): + dt = np.dtype(dict( + names=['a', 'b'], + offsets=[0, 0], + formats=[np.uint16, np.uint32] + )) + + ct = np.ctypeslib.as_ctypes_type(dt) + assert_(issubclass(ct, ctypes.Union)) + assert_equal(ctypes.sizeof(ct), dt.itemsize) + assert_equal(ct._fields_, [ + ('a', ctypes.c_uint16), + ('b', ctypes.c_uint32), + ]) + + def test_padded_union(self): + dt = np.dtype(dict( + names=['a', 'b'], + offsets=[0, 0], + formats=[np.uint16, np.uint32], + itemsize=5, + )) + + ct = np.ctypeslib.as_ctypes_type(dt) + assert_(issubclass(ct, ctypes.Union)) + assert_equal(ctypes.sizeof(ct), dt.itemsize) + assert_equal(ct._fields_, [ + ('a', ctypes.c_uint16), + ('b', ctypes.c_uint32), + ('', ctypes.c_char * 5), # padding + ]) + + def test_overlapping(self): + dt = np.dtype(dict( + names=['a', 'b'], + offsets=[0, 2], + formats=[np.uint32, np.uint32] + )) + assert_raises(NotImplementedError, np.ctypeslib.as_ctypes_type, dt) diff --git a/venv/Lib/site-packages/numpy/tests/test_matlib.py b/venv/Lib/site-packages/numpy/tests/test_matlib.py new file mode 100644 index 0000000..0e93c48 --- /dev/null +++ b/venv/Lib/site-packages/numpy/tests/test_matlib.py @@ -0,0 +1,58 @@ +import numpy as np +import numpy.matlib +from numpy.testing import assert_array_equal, assert_ + +def test_empty(): + x = numpy.matlib.empty((2,)) + assert_(isinstance(x, np.matrix)) + assert_(x.shape, (1, 2)) + +def test_ones(): + assert_array_equal(numpy.matlib.ones((2, 3)), + np.matrix([[ 1., 1., 1.], + [ 1., 1., 1.]])) + + assert_array_equal(numpy.matlib.ones(2), np.matrix([[ 1., 1.]])) + +def test_zeros(): + assert_array_equal(numpy.matlib.zeros((2, 3)), + np.matrix([[ 0., 0., 0.], + [ 0., 0., 0.]])) + + assert_array_equal(numpy.matlib.zeros(2), np.matrix([[ 0., 0.]])) + +def test_identity(): + x = numpy.matlib.identity(2, dtype=int) + assert_array_equal(x, np.matrix([[1, 0], [0, 1]])) + +def test_eye(): + xc = numpy.matlib.eye(3, k=1, dtype=int) + assert_array_equal(xc, np.matrix([[ 0, 1, 0], + [ 0, 0, 1], + [ 0, 0, 0]])) + assert xc.flags.c_contiguous + assert not xc.flags.f_contiguous + + xf = numpy.matlib.eye(3, 4, dtype=int, order='F') + assert_array_equal(xf, np.matrix([[ 1, 0, 0, 0], + [ 0, 1, 0, 0], + [ 0, 0, 1, 0]])) + assert not xf.flags.c_contiguous + assert xf.flags.f_contiguous + +def test_rand(): + x = numpy.matlib.rand(3) + # check matrix type, array would have shape (3,) + assert_(x.ndim == 2) + +def test_randn(): + x = np.matlib.randn(3) + # check matrix type, array would have shape (3,) + assert_(x.ndim == 2) + +def test_repmat(): + a1 = np.arange(4) + x = numpy.matlib.repmat(a1, 2, 2) + y = np.array([[0, 1, 2, 3, 0, 1, 2, 3], + [0, 1, 2, 3, 0, 1, 2, 3]]) + assert_array_equal(x, y) diff --git a/venv/Lib/site-packages/numpy/tests/test_numpy_version.py b/venv/Lib/site-packages/numpy/tests/test_numpy_version.py new file mode 100644 index 0000000..916ab93 --- /dev/null +++ b/venv/Lib/site-packages/numpy/tests/test_numpy_version.py @@ -0,0 +1,17 @@ +import re + +import numpy as np +from numpy.testing import assert_ + + +def test_valid_numpy_version(): + # Verify that the numpy version is a valid one (no .post suffix or other + # nonsense). See gh-6431 for an issue caused by an invalid version. + version_pattern = r"^[0-9]+\.[0-9]+\.[0-9]+(|a[0-9]|b[0-9]|rc[0-9])" + dev_suffix = r"(\.dev0\+([0-9a-f]{7}|Unknown))" + if np.version.release: + res = re.match(version_pattern, np.__version__) + else: + res = re.match(version_pattern + dev_suffix, np.__version__) + + assert_(res is not None, np.__version__) diff --git a/venv/Lib/site-packages/numpy/tests/test_public_api.py b/venv/Lib/site-packages/numpy/tests/test_public_api.py new file mode 100644 index 0000000..4df57ce --- /dev/null +++ b/venv/Lib/site-packages/numpy/tests/test_public_api.py @@ -0,0 +1,474 @@ +import sys +import subprocess +import pkgutil +import types +import importlib +import warnings + +import numpy as np +import numpy +import pytest + +try: + import ctypes +except ImportError: + ctypes = None + + +def check_dir(module, module_name=None): + """Returns a mapping of all objects with the wrong __module__ attribute.""" + if module_name is None: + module_name = module.__name__ + results = {} + for name in dir(module): + item = getattr(module, name) + if (hasattr(item, '__module__') and hasattr(item, '__name__') + and item.__module__ != module_name): + results[name] = item.__module__ + '.' + item.__name__ + return results + + +def test_numpy_namespace(): + # None of these objects are publicly documented to be part of the main + # NumPy namespace (some are useful though, others need to be cleaned up) + undocumented = { + 'Tester': 'numpy.testing._private.nosetester.NoseTester', + '_add_newdoc_ufunc': 'numpy.core._multiarray_umath._add_newdoc_ufunc', + 'add_docstring': 'numpy.core._multiarray_umath.add_docstring', + 'add_newdoc': 'numpy.core.function_base.add_newdoc', + 'add_newdoc_ufunc': 'numpy.core._multiarray_umath._add_newdoc_ufunc', + 'byte_bounds': 'numpy.lib.utils.byte_bounds', + 'compare_chararrays': 'numpy.core._multiarray_umath.compare_chararrays', + 'deprecate': 'numpy.lib.utils.deprecate', + 'deprecate_with_doc': 'numpy.lib.utils.', + 'disp': 'numpy.lib.function_base.disp', + 'fastCopyAndTranspose': 'numpy.core._multiarray_umath._fastCopyAndTranspose', + 'get_array_wrap': 'numpy.lib.shape_base.get_array_wrap', + 'get_include': 'numpy.lib.utils.get_include', + 'mafromtxt': 'numpy.lib.npyio.mafromtxt', + 'ndfromtxt': 'numpy.lib.npyio.ndfromtxt', + 'recfromcsv': 'numpy.lib.npyio.recfromcsv', + 'recfromtxt': 'numpy.lib.npyio.recfromtxt', + 'safe_eval': 'numpy.lib.utils.safe_eval', + 'set_string_function': 'numpy.core.arrayprint.set_string_function', + 'show_config': 'numpy.__config__.show', + 'who': 'numpy.lib.utils.who', + } + if sys.version_info < (3, 7): + # These built-in types are re-exported by numpy. + builtins = { + 'bool': 'builtins.bool', + 'complex': 'builtins.complex', + 'float': 'builtins.float', + 'int': 'builtins.int', + 'long': 'builtins.int', + 'object': 'builtins.object', + 'str': 'builtins.str', + 'unicode': 'builtins.str', + } + allowlist = dict(undocumented, **builtins) + else: + # after 3.7, we override dir to not show these members + allowlist = undocumented + bad_results = check_dir(np) + # pytest gives better error messages with the builtin assert than with + # assert_equal + assert bad_results == allowlist + + +@pytest.mark.parametrize('name', ['testing', 'Tester']) +def test_import_lazy_import(name): + """Make sure we can actually use the modules we lazy load. + + While not exported as part of the public API, it was accessible. With the + use of __getattr__ and __dir__, this isn't always true It can happen that + an infinite recursion may happen. + + This is the only way I found that would force the failure to appear on the + badly implemented code. + + We also test for the presence of the lazily imported modules in dir + + """ + exe = (sys.executable, '-c', "import numpy; numpy." + name) + result = subprocess.check_output(exe) + assert not result + + # Make sure they are still in the __dir__ + assert name in dir(np) + + +def test_dir_testing(): + """Assert that output of dir has only one "testing/tester" + attribute without duplicate""" + assert len(dir(np)) == len(set(dir(np))) + + +def test_numpy_linalg(): + bad_results = check_dir(np.linalg) + assert bad_results == {} + + +def test_numpy_fft(): + bad_results = check_dir(np.fft) + assert bad_results == {} + + +@pytest.mark.skipif(ctypes is None, + reason="ctypes not available in this python") +def test_NPY_NO_EXPORT(): + cdll = ctypes.CDLL(np.core._multiarray_tests.__file__) + # Make sure an arbitrary NPY_NO_EXPORT function is actually hidden + f = getattr(cdll, 'test_not_exported', None) + assert f is None, ("'test_not_exported' is mistakenly exported, " + "NPY_NO_EXPORT does not work") + + +# Historically NumPy has not used leading underscores for private submodules +# much. This has resulted in lots of things that look like public modules +# (i.e. things that can be imported as `import numpy.somesubmodule.somefile`), +# but were never intended to be public. The PUBLIC_MODULES list contains +# modules that are either public because they were meant to be, or because they +# contain public functions/objects that aren't present in any other namespace +# for whatever reason and therefore should be treated as public. +# +# The PRIVATE_BUT_PRESENT_MODULES list contains modules that look public (lack +# of underscores) but should not be used. For many of those modules the +# current status is fine. For others it may make sense to work on making them +# private, to clean up our public API and avoid confusion. +PUBLIC_MODULES = ['numpy.' + s for s in [ + "ctypeslib", + "distutils", + "distutils.cpuinfo", + "distutils.exec_command", + "distutils.misc_util", + "distutils.log", + "distutils.system_info", + "doc", + "doc.constants", + "doc.ufuncs", + "f2py", + "fft", + "lib", + "lib.format", # was this meant to be public? + "lib.mixins", + "lib.recfunctions", + "lib.scimath", + "lib.stride_tricks", + "linalg", + "ma", + "ma.extras", + "ma.mrecords", + "matlib", + "polynomial", + "polynomial.chebyshev", + "polynomial.hermite", + "polynomial.hermite_e", + "polynomial.laguerre", + "polynomial.legendre", + "polynomial.polynomial", + "random", + "testing", + "typing", + "version", +]] + + +PUBLIC_ALIASED_MODULES = [ + "numpy.char", + "numpy.emath", + "numpy.rec", +] + + +PRIVATE_BUT_PRESENT_MODULES = ['numpy.' + s for s in [ + "compat", + "compat.py3k", + "conftest", + "core", + "core.arrayprint", + "core.defchararray", + "core.einsumfunc", + "core.fromnumeric", + "core.function_base", + "core.getlimits", + "core.machar", + "core.memmap", + "core.multiarray", + "core.numeric", + "core.numerictypes", + "core.overrides", + "core.records", + "core.shape_base", + "core.umath", + "core.umath_tests", + "distutils.ccompiler", + 'distutils.ccompiler_opt', + "distutils.command", + "distutils.command.autodist", + "distutils.command.bdist_rpm", + "distutils.command.build", + "distutils.command.build_clib", + "distutils.command.build_ext", + "distutils.command.build_py", + "distutils.command.build_scripts", + "distutils.command.build_src", + "distutils.command.config", + "distutils.command.config_compiler", + "distutils.command.develop", + "distutils.command.egg_info", + "distutils.command.install", + "distutils.command.install_clib", + "distutils.command.install_data", + "distutils.command.install_headers", + "distutils.command.sdist", + "distutils.conv_template", + "distutils.core", + "distutils.extension", + "distutils.fcompiler", + "distutils.fcompiler.absoft", + "distutils.fcompiler.compaq", + "distutils.fcompiler.environment", + "distutils.fcompiler.g95", + "distutils.fcompiler.gnu", + "distutils.fcompiler.hpux", + "distutils.fcompiler.ibm", + "distutils.fcompiler.intel", + "distutils.fcompiler.lahey", + "distutils.fcompiler.mips", + "distutils.fcompiler.nag", + "distutils.fcompiler.none", + "distutils.fcompiler.pathf95", + "distutils.fcompiler.pg", + "distutils.fcompiler.nv", + "distutils.fcompiler.sun", + "distutils.fcompiler.vast", + "distutils.fcompiler.fujitsu", + "distutils.from_template", + "distutils.intelccompiler", + "distutils.lib2def", + "distutils.line_endings", + "distutils.mingw32ccompiler", + "distutils.msvccompiler", + "distutils.npy_pkg_config", + "distutils.numpy_distribution", + "distutils.pathccompiler", + "distutils.unixccompiler", + "dual", + "f2py.auxfuncs", + "f2py.capi_maps", + "f2py.cb_rules", + "f2py.cfuncs", + "f2py.common_rules", + "f2py.crackfortran", + "f2py.diagnose", + "f2py.f2py2e", + "f2py.f2py_testing", + "f2py.f90mod_rules", + "f2py.func2subr", + "f2py.rules", + "f2py.use_rules", + "fft.helper", + "lib.arraypad", + "lib.arraysetops", + "lib.arrayterator", + "lib.function_base", + "lib.histograms", + "lib.index_tricks", + "lib.nanfunctions", + "lib.npyio", + "lib.polynomial", + "lib.shape_base", + "lib.twodim_base", + "lib.type_check", + "lib.ufunclike", + "lib.user_array", # note: not in np.lib, but probably should just be deleted + "lib.utils", + "linalg.lapack_lite", + "linalg.linalg", + "ma.bench", + "ma.core", + "ma.testutils", + "ma.timer_comparison", + "matrixlib", + "matrixlib.defmatrix", + "polynomial.polyutils", + "random.mtrand", + "random.bit_generator", + "testing.print_coercion_tables", + "testing.utils", +]] + + +def is_unexpected(name): + """Check if this needs to be considered.""" + if '._' in name or '.tests' in name or '.setup' in name: + return False + + if name in PUBLIC_MODULES: + return False + + if name in PUBLIC_ALIASED_MODULES: + return False + + if name in PRIVATE_BUT_PRESENT_MODULES: + return False + + return True + + +# These are present in a directory with an __init__.py but cannot be imported +# code_generators/ isn't installed, but present for an inplace build +SKIP_LIST = [ + "numpy.core.code_generators", + "numpy.core.code_generators.genapi", + "numpy.core.code_generators.generate_umath", + "numpy.core.code_generators.ufunc_docstrings", + "numpy.core.code_generators.generate_numpy_api", + "numpy.core.code_generators.generate_ufunc_api", + "numpy.core.code_generators.numpy_api", + "numpy.core.cversions", + "numpy.core.generate_numpy_api", + "numpy.distutils.msvc9compiler", +] + + +def test_all_modules_are_expected(): + """ + Test that we don't add anything that looks like a new public module by + accident. Check is based on filenames. + """ + + modnames = [] + for _, modname, ispkg in pkgutil.walk_packages(path=np.__path__, + prefix=np.__name__ + '.', + onerror=None): + if is_unexpected(modname) and modname not in SKIP_LIST: + # We have a name that is new. If that's on purpose, add it to + # PUBLIC_MODULES. We don't expect to have to add anything to + # PRIVATE_BUT_PRESENT_MODULES. Use an underscore in the name! + modnames.append(modname) + + if modnames: + raise AssertionError(f'Found unexpected modules: {modnames}') + + +# Stuff that clearly shouldn't be in the API and is detected by the next test +# below +SKIP_LIST_2 = [ + 'numpy.math', + 'numpy.distutils.log.sys', + 'numpy.doc.constants.re', + 'numpy.doc.constants.textwrap', + 'numpy.lib.emath', + 'numpy.lib.math', + 'numpy.matlib.char', + 'numpy.matlib.rec', + 'numpy.matlib.emath', + 'numpy.matlib.math', + 'numpy.matlib.linalg', + 'numpy.matlib.fft', + 'numpy.matlib.random', + 'numpy.matlib.ctypeslib', + 'numpy.matlib.ma', +] + + +def test_all_modules_are_expected_2(): + """ + Method checking all objects. The pkgutil-based method in + `test_all_modules_are_expected` does not catch imports into a namespace, + only filenames. So this test is more thorough, and checks this like: + + import .lib.scimath as emath + + To check if something in a module is (effectively) public, one can check if + there's anything in that namespace that's a public function/object but is + not exposed in a higher-level namespace. For example for a `numpy.lib` + submodule:: + + mod = np.lib.mixins + for obj in mod.__all__: + if obj in np.__all__: + continue + elif obj in np.lib.__all__: + continue + + else: + print(obj) + + """ + + def find_unexpected_members(mod_name): + members = [] + module = importlib.import_module(mod_name) + if hasattr(module, '__all__'): + objnames = module.__all__ + else: + objnames = dir(module) + + for objname in objnames: + if not objname.startswith('_'): + fullobjname = mod_name + '.' + objname + if isinstance(getattr(module, objname), types.ModuleType): + if is_unexpected(fullobjname): + if fullobjname not in SKIP_LIST_2: + members.append(fullobjname) + + return members + + unexpected_members = find_unexpected_members("numpy") + for modname in PUBLIC_MODULES: + unexpected_members.extend(find_unexpected_members(modname)) + + if unexpected_members: + raise AssertionError("Found unexpected object(s) that look like " + "modules: {}".format(unexpected_members)) + + +def test_api_importable(): + """ + Check that all submodules listed higher up in this file can be imported + + Note that if a PRIVATE_BUT_PRESENT_MODULES entry goes missing, it may + simply need to be removed from the list (deprecation may or may not be + needed - apply common sense). + """ + def check_importable(module_name): + try: + importlib.import_module(module_name) + except (ImportError, AttributeError): + return False + + return True + + module_names = [] + for module_name in PUBLIC_MODULES: + if not check_importable(module_name): + module_names.append(module_name) + + if module_names: + raise AssertionError("Modules in the public API that cannot be " + "imported: {}".format(module_names)) + + for module_name in PUBLIC_ALIASED_MODULES: + try: + eval(module_name) + except AttributeError: + module_names.append(module_name) + + if module_names: + raise AssertionError("Modules in the public API that were not " + "found: {}".format(module_names)) + + with warnings.catch_warnings(record=True) as w: + warnings.filterwarnings('always', category=DeprecationWarning) + warnings.filterwarnings('always', category=ImportWarning) + for module_name in PRIVATE_BUT_PRESENT_MODULES: + if not check_importable(module_name): + module_names.append(module_name) + + if module_names: + raise AssertionError("Modules that are not really public but looked " + "public and can not be imported: " + "{}".format(module_names)) diff --git a/venv/Lib/site-packages/numpy/tests/test_reloading.py b/venv/Lib/site-packages/numpy/tests/test_reloading.py new file mode 100644 index 0000000..61ae91b --- /dev/null +++ b/venv/Lib/site-packages/numpy/tests/test_reloading.py @@ -0,0 +1,57 @@ +from numpy.testing import assert_raises, assert_, assert_equal +from numpy.compat import pickle + +import sys +import subprocess +import textwrap +from importlib import reload + + +def test_numpy_reloading(): + # gh-7844. Also check that relevant globals retain their identity. + import numpy as np + import numpy._globals + + _NoValue = np._NoValue + VisibleDeprecationWarning = np.VisibleDeprecationWarning + ModuleDeprecationWarning = np.ModuleDeprecationWarning + + reload(np) + assert_(_NoValue is np._NoValue) + assert_(ModuleDeprecationWarning is np.ModuleDeprecationWarning) + assert_(VisibleDeprecationWarning is np.VisibleDeprecationWarning) + + assert_raises(RuntimeError, reload, numpy._globals) + reload(np) + assert_(_NoValue is np._NoValue) + assert_(ModuleDeprecationWarning is np.ModuleDeprecationWarning) + assert_(VisibleDeprecationWarning is np.VisibleDeprecationWarning) + +def test_novalue(): + import numpy as np + for proto in range(2, pickle.HIGHEST_PROTOCOL + 1): + assert_equal(repr(np._NoValue), '') + assert_(pickle.loads(pickle.dumps(np._NoValue, + protocol=proto)) is np._NoValue) + + +def test_full_reimport(): + """At the time of writing this, it is *not* truly supported, but + apparently enough users rely on it, for it to be an annoying change + when it started failing previously. + """ + # Test within a new process, to ensure that we do not mess with the + # global state during the test run (could lead to cryptic test failures). + # This is generally unsafe, especially, since we also reload the C-modules. + code = textwrap.dedent(r""" + import sys + import numpy as np + + for k in list(sys.modules.keys()): + if "numpy" in k: + del sys.modules[k] + + import numpy as np + """) + p = subprocess.run([sys.executable, '-c', code]) + assert p.returncode == 0 diff --git a/venv/Lib/site-packages/numpy/tests/test_scripts.py b/venv/Lib/site-packages/numpy/tests/test_scripts.py new file mode 100644 index 0000000..e67a829 --- /dev/null +++ b/venv/Lib/site-packages/numpy/tests/test_scripts.py @@ -0,0 +1,46 @@ +""" Test scripts + +Test that we can run executable scripts that have been installed with numpy. +""" +import sys +import os +import pytest +from os.path import join as pathjoin, isfile, dirname +import subprocess + +import numpy as np +from numpy.testing import assert_equal + +is_inplace = isfile(pathjoin(dirname(np.__file__), '..', 'setup.py')) + + +def find_f2py_commands(): + if sys.platform == 'win32': + exe_dir = dirname(sys.executable) + if exe_dir.endswith('Scripts'): # virtualenv + return [os.path.join(exe_dir, 'f2py')] + else: + return [os.path.join(exe_dir, "Scripts", 'f2py')] + else: + # Three scripts are installed in Unix-like systems: + # 'f2py', 'f2py{major}', and 'f2py{major.minor}'. For example, + # if installed with python3.7 the scripts would be named + # 'f2py', 'f2py3', and 'f2py3.7'. + version = sys.version_info + major = str(version.major) + minor = str(version.minor) + return ['f2py', 'f2py' + major, 'f2py' + major + '.' + minor] + + +@pytest.mark.skipif(is_inplace, reason="Cannot test f2py command inplace") +@pytest.mark.xfail(reason="Test is unreliable") +@pytest.mark.parametrize('f2py_cmd', find_f2py_commands()) +def test_f2py(f2py_cmd): + # test that we can run f2py script + stdout = subprocess.check_output([f2py_cmd, '-v']) + assert_equal(stdout.strip(), np.__version__.encode('ascii')) + + +def test_pep338(): + stdout = subprocess.check_output([sys.executable, '-mnumpy.f2py', '-v']) + assert_equal(stdout.strip(), np.__version__.encode('ascii')) diff --git a/venv/Lib/site-packages/numpy/tests/test_warnings.py b/venv/Lib/site-packages/numpy/tests/test_warnings.py new file mode 100644 index 0000000..d7a6d88 --- /dev/null +++ b/venv/Lib/site-packages/numpy/tests/test_warnings.py @@ -0,0 +1,74 @@ +""" +Tests which scan for certain occurrences in the code, they may not find +all of these occurrences but should catch almost all. +""" +import pytest + +from pathlib import Path +import ast +import tokenize +import numpy + +class ParseCall(ast.NodeVisitor): + def __init__(self): + self.ls = [] + + def visit_Attribute(self, node): + ast.NodeVisitor.generic_visit(self, node) + self.ls.append(node.attr) + + def visit_Name(self, node): + self.ls.append(node.id) + + +class FindFuncs(ast.NodeVisitor): + def __init__(self, filename): + super().__init__() + self.__filename = filename + + def visit_Call(self, node): + p = ParseCall() + p.visit(node.func) + ast.NodeVisitor.generic_visit(self, node) + + if p.ls[-1] == 'simplefilter' or p.ls[-1] == 'filterwarnings': + if node.args[0].s == "ignore": + raise AssertionError( + "warnings should have an appropriate stacklevel; found in " + "{} on line {}".format(self.__filename, node.lineno)) + + if p.ls[-1] == 'warn' and ( + len(p.ls) == 1 or p.ls[-2] == 'warnings'): + + if "testing/tests/test_warnings.py" == self.__filename: + # This file + return + + # See if stacklevel exists: + if len(node.args) == 3: + return + args = {kw.arg for kw in node.keywords} + if "stacklevel" in args: + return + raise AssertionError( + "warnings should have an appropriate stacklevel; found in " + "{} on line {}".format(self.__filename, node.lineno)) + + +@pytest.mark.slow +def test_warning_calls(): + # combined "ignore" and stacklevel error + base = Path(numpy.__file__).parent + + for path in base.rglob("*.py"): + if base / "testing" in path.parents: + continue + if path == base / "__init__.py": + continue + if path == base / "random" / "__init__.py": + continue + # use tokenize to auto-detect encoding on systems where no + # default encoding is defined (e.g. LANG='C') + with tokenize.open(str(path)) as file: + tree = ast.parse(file.read()) + FindFuncs(path).visit(tree) diff --git a/venv/Lib/site-packages/numpy/typing/__init__.py b/venv/Lib/site-packages/numpy/typing/__init__.py new file mode 100644 index 0000000..87235a4 --- /dev/null +++ b/venv/Lib/site-packages/numpy/typing/__init__.py @@ -0,0 +1,232 @@ +""" +============================ +Typing (:mod:`numpy.typing`) +============================ + +.. warning:: + + Some of the types in this module rely on features only present in + the standard library in Python 3.8 and greater. If you want to use + these types in earlier versions of Python, you should install the + typing-extensions_ package. + +Large parts of the NumPy API have PEP-484-style type annotations. In +addition a number of type aliases are available to users, most prominently +the two below: + +- `ArrayLike`: objects that can be converted to arrays +- `DTypeLike`: objects that can be converted to dtypes + +.. _typing-extensions: https://pypi.org/project/typing-extensions/ + +Differences from the runtime NumPy API +-------------------------------------- + +NumPy is very flexible. Trying to describe the full range of +possibilities statically would result in types that are not very +helpful. For that reason, the typed NumPy API is often stricter than +the runtime NumPy API. This section describes some notable +differences. + +ArrayLike +~~~~~~~~~ + +The `ArrayLike` type tries to avoid creating object arrays. For +example, + +.. code-block:: python + + >>> np.array(x**2 for x in range(10)) + array( at ...>, dtype=object) + +is valid NumPy code which will create a 0-dimensional object +array. Type checkers will complain about the above example when using +the NumPy types however. If you really intended to do the above, then +you can either use a ``# type: ignore`` comment: + +.. code-block:: python + + >>> np.array(x**2 for x in range(10)) # type: ignore + +or explicitly type the array like object as `~typing.Any`: + +.. code-block:: python + + >>> from typing import Any + >>> array_like: Any = (x**2 for x in range(10)) + >>> np.array(array_like) + array( at ...>, dtype=object) + +ndarray +~~~~~~~ + +It's possible to mutate the dtype of an array at runtime. For example, +the following code is valid: + +.. code-block:: python + + >>> x = np.array([1, 2]) + >>> x.dtype = np.bool_ + +This sort of mutation is not allowed by the types. Users who want to +write statically typed code should insted use the `numpy.ndarray.view` +method to create a view of the array with a different dtype. + +DTypeLike +~~~~~~~~~ + +The `DTypeLike` type tries to avoid creation of dtype objects using +dictionary of fields like below: + +.. code-block:: python + + >>> x = np.dtype({"field1": (float, 1), "field2": (int, 3)}) + +Although this is valid Numpy code, the type checker will complain about it, +since its usage is discouraged. +Please see : :ref:`Data type objects ` + +Number Precision +~~~~~~~~~~~~~~~~ + +The precision of `numpy.number` subclasses is treated as a covariant generic +parameter (see :class:`~NBitBase`), simplifying the annoting of proccesses +involving precision-based casting. + +.. code-block:: python + + >>> from typing import TypeVar + >>> import numpy as np + >>> import numpy.typing as npt + + >>> T = TypeVar("T", bound=npt.NBitBase) + >>> def func(a: "np.floating[T]", b: "np.floating[T]") -> "np.floating[T]": + ... ... + +Consequently, the likes of `~numpy.float16`, `~numpy.float32` and +`~numpy.float64` are still sub-types of `~numpy.floating`, but, contrary to +runtime, they're not necessarily considered as sub-classes. + +Timedelta64 +~~~~~~~~~~~ + +The `~numpy.timedelta64` class is not considered a subclass of `~numpy.signedinteger`, +the former only inheriting from `~numpy.generic` while static type checking. + +API +--- + +""" +# NOTE: The API section will be appended with additional entries +# further down in this file + +from typing import TYPE_CHECKING, List + +if TYPE_CHECKING: + import sys + if sys.version_info >= (3, 8): + from typing import final + else: + from typing_extensions import final +else: + def final(f): return f + +if not TYPE_CHECKING: + __all__ = ["ArrayLike", "DTypeLike", "NBitBase"] +else: + # Ensure that all objects within this module are accessible while + # static type checking. This includes private ones, as we need them + # for internal use. + # + # Declare to mypy that `__all__` is a list of strings without assigning + # an explicit value + __all__: List[str] + + +@final # Dissallow the creation of arbitrary `NBitBase` subclasses +class NBitBase: + """ + An object representing `numpy.number` precision during static type checking. + + Used exclusively for the purpose static type checking, `NBitBase` + represents the base of a hierachieral set of subclasses. + Each subsequent subclass is herein used for representing a lower level + of precision, *e.g.* ``64Bit > 32Bit > 16Bit``. + + Examples + -------- + Below is a typical usage example: `NBitBase` is herein used for annotating a + function that takes a float and integer of arbitrary precision as arguments + and returns a new float of whichever precision is largest + (*e.g.* ``np.float16 + np.int64 -> np.float64``). + + .. code-block:: python + + >>> from typing import TypeVar, TYPE_CHECKING + >>> import numpy as np + >>> import numpy.typing as npt + + >>> T = TypeVar("T", bound=npt.NBitBase) + + >>> def add(a: "np.floating[T]", b: "np.integer[T]") -> "np.floating[T]": + ... return a + b + + >>> a = np.float16() + >>> b = np.int64() + >>> out = add(a, b) + + >>> if TYPE_CHECKING: + ... reveal_locals() + ... # note: Revealed local types are: + ... # note: a: numpy.floating[numpy.typing._16Bit*] + ... # note: b: numpy.signedinteger[numpy.typing._64Bit*] + ... # note: out: numpy.floating[numpy.typing._64Bit*] + + """ + + def __init_subclass__(cls) -> None: + allowed_names = { + "NBitBase", "_256Bit", "_128Bit", "_96Bit", "_80Bit", + "_64Bit", "_32Bit", "_16Bit", "_8Bit", + } + if cls.__name__ not in allowed_names: + raise TypeError('cannot inherit from final class "NBitBase"') + super().__init_subclass__() + + +# Silence errors about subclassing a `@final`-decorated class +class _256Bit(NBitBase): ... # type: ignore[misc] +class _128Bit(_256Bit): ... # type: ignore[misc] +class _96Bit(_128Bit): ... # type: ignore[misc] +class _80Bit(_96Bit): ... # type: ignore[misc] +class _64Bit(_80Bit): ... # type: ignore[misc] +class _32Bit(_64Bit): ... # type: ignore[misc] +class _16Bit(_32Bit): ... # type: ignore[misc] +class _8Bit(_16Bit): ... # type: ignore[misc] + +# Clean up the namespace +del TYPE_CHECKING, final, List + +from ._scalars import ( + _CharLike, + _BoolLike, + _IntLike, + _FloatLike, + _ComplexLike, + _NumberLike, + _ScalarLike, + _VoidLike, +) +from ._array_like import _SupportsArray, ArrayLike as ArrayLike +from ._shape import _Shape, _ShapeLike +from ._dtype_like import _SupportsDType, _VoidDTypeLike, DTypeLike as DTypeLike + +if __doc__ is not None: + from ._add_docstring import _docstrings + __doc__ += _docstrings + __doc__ += '\n.. autoclass:: numpy.typing.NBitBase\n' + del _docstrings + +from numpy._pytesttester import PytestTester +test = PytestTester(__name__) +del PytestTester diff --git a/venv/Lib/site-packages/numpy/typing/_add_docstring.py b/venv/Lib/site-packages/numpy/typing/_add_docstring.py new file mode 100644 index 0000000..8e39fe2 --- /dev/null +++ b/venv/Lib/site-packages/numpy/typing/_add_docstring.py @@ -0,0 +1,96 @@ +"""A module for creating docstrings for sphinx ``data`` domains.""" + +import re +import textwrap + +_docstrings_list = [] + + +def add_newdoc(name, value, doc): + _docstrings_list.append((name, value, doc)) + + +def _parse_docstrings(): + type_list_ret = [] + for name, value, doc in _docstrings_list: + s = textwrap.dedent(doc).replace("\n", "\n ") + + # Replace sections by rubrics + lines = s.split("\n") + new_lines = [] + indent = "" + for line in lines: + m = re.match(r'^(\s+)[-=]+\s*$', line) + if m and new_lines: + prev = textwrap.dedent(new_lines.pop()) + if prev == "Examples": + indent = "" + new_lines.append(f'{m.group(1)}.. rubric:: {prev}') + else: + indent = 4 * " " + new_lines.append(f'{m.group(1)}.. admonition:: {prev}') + new_lines.append("") + else: + new_lines.append(f"{indent}{line}") + s = "\n".join(new_lines) + + # Done. + type_list_ret.append(f""".. data:: {name}\n :value: {value}\n {s}""") + return "\n".join(type_list_ret) + + +add_newdoc('ArrayLike', 'typing.Union[...]', + """ + A `~typing.Union` representing objects that can be coerced into an `~numpy.ndarray`. + + Among others this includes the likes of: + + * Scalars. + * (Nested) sequences. + * Objects implementing the `~class.__array__` protocol. + + See Also + -------- + :term:`array_like`: + Any scalar or sequence that can be interpreted as an ndarray. + + Examples + -------- + .. code-block:: python + + >>> import numpy as np + >>> import numpy.typing as npt + + >>> def as_array(a: npt.ArrayLike) -> np.ndarray: + ... return np.array(a) + + """) + +add_newdoc('DTypeLike', 'typing.Union[...]', + """ + A `~typing.Union` representing objects that can be coerced into a `~numpy.dtype`. + + Among others this includes the likes of: + + * :class:`type` objects. + * Character codes or the names of :class:`type` objects. + * Objects with the ``.dtype`` attribute. + + See Also + -------- + :ref:`Specifying and constructing data types ` + A comprehensive overview of all objects that can be coerced into data types. + + Examples + -------- + .. code-block:: python + + >>> import numpy as np + >>> import numpy.typing as npt + + >>> def as_dtype(d: npt.DTypeLike) -> np.dtype: + ... return np.dtype(d) + + """) + +_docstrings = _parse_docstrings() diff --git a/venv/Lib/site-packages/numpy/typing/_array_like.py b/venv/Lib/site-packages/numpy/typing/_array_like.py new file mode 100644 index 0000000..a1a6042 --- /dev/null +++ b/venv/Lib/site-packages/numpy/typing/_array_like.py @@ -0,0 +1,40 @@ +import sys +from typing import Any, overload, Sequence, TYPE_CHECKING, Union + +from numpy import ndarray +from ._scalars import _ScalarLike +from ._dtype_like import DTypeLike + +if sys.version_info >= (3, 8): + from typing import Protocol + HAVE_PROTOCOL = True +else: + try: + from typing_extensions import Protocol + except ImportError: + HAVE_PROTOCOL = False + else: + HAVE_PROTOCOL = True + +if TYPE_CHECKING or HAVE_PROTOCOL: + class _SupportsArray(Protocol): + @overload + def __array__(self, __dtype: DTypeLike = ...) -> ndarray: ... + @overload + def __array__(self, dtype: DTypeLike = ...) -> ndarray: ... +else: + _SupportsArray = Any + +# TODO: support buffer protocols once +# +# https://bugs.python.org/issue27501 +# +# is resolved. See also the mypy issue: +# +# https://github.com/python/typing/issues/593 +ArrayLike = Union[ + _ScalarLike, + Sequence[_ScalarLike], + Sequence[Sequence[Any]], # TODO: Wait for support for recursive types + _SupportsArray, +] diff --git a/venv/Lib/site-packages/numpy/typing/_callable.py b/venv/Lib/site-packages/numpy/typing/_callable.py new file mode 100644 index 0000000..91b7a4e --- /dev/null +++ b/venv/Lib/site-packages/numpy/typing/_callable.py @@ -0,0 +1,336 @@ +""" +A module with various ``typing.Protocol`` subclasses that implement +the ``__call__`` magic method. + +See the `Mypy documentation`_ on protocols for more details. + +.. _`Mypy documentation`: https://mypy.readthedocs.io/en/stable/protocols.html#callback-protocols + +""" + +import sys +from typing import ( + Union, + TypeVar, + overload, + Any, + Tuple, + NoReturn, + TYPE_CHECKING, +) + +from numpy import ( + generic, + bool_, + timedelta64, + number, + integer, + unsignedinteger, + signedinteger, + int8, + floating, + float64, + complexfloating, + complex128, +) +from ._scalars import ( + _BoolLike, + _IntLike, + _FloatLike, + _ComplexLike, + _NumberLike, +) +from . import NBitBase + +if sys.version_info >= (3, 8): + from typing import Protocol + HAVE_PROTOCOL = True +else: + try: + from typing_extensions import Protocol + except ImportError: + HAVE_PROTOCOL = False + else: + HAVE_PROTOCOL = True + +if TYPE_CHECKING or HAVE_PROTOCOL: + _T = TypeVar("_T") + _2Tuple = Tuple[_T, _T] + + _NBit_co = TypeVar("_NBit_co", covariant=True, bound=NBitBase) + _NBit = TypeVar("_NBit", bound=NBitBase) + + _IntType = TypeVar("_IntType", bound=integer) + _FloatType = TypeVar("_FloatType", bound=floating) + _NumberType = TypeVar("_NumberType", bound=number) + _NumberType_co = TypeVar("_NumberType_co", covariant=True, bound=number) + _GenericType_co = TypeVar("_GenericType_co", covariant=True, bound=generic) + + class _BoolOp(Protocol[_GenericType_co]): + @overload + def __call__(self, __other: _BoolLike) -> _GenericType_co: ... + @overload # platform dependent + def __call__(self, __other: int) -> signedinteger[Any]: ... + @overload + def __call__(self, __other: float) -> float64: ... + @overload + def __call__(self, __other: complex) -> complex128: ... + @overload + def __call__(self, __other: _NumberType) -> _NumberType: ... + + class _BoolBitOp(Protocol[_GenericType_co]): + @overload + def __call__(self, __other: _BoolLike) -> _GenericType_co: ... + @overload # platform dependent + def __call__(self, __other: int) -> signedinteger[Any]: ... + @overload + def __call__(self, __other: _IntType) -> _IntType: ... + + class _BoolSub(Protocol): + # Note that `__other: bool_` is absent here + @overload + def __call__(self, __other: bool) -> NoReturn: ... + @overload # platform dependent + def __call__(self, __other: int) -> signedinteger[Any]: ... + @overload + def __call__(self, __other: float) -> float64: ... + @overload + def __call__(self, __other: complex) -> complex128: ... + @overload + def __call__(self, __other: _NumberType) -> _NumberType: ... + + class _BoolTrueDiv(Protocol): + @overload + def __call__(self, __other: Union[float, _IntLike, _BoolLike]) -> float64: ... + @overload + def __call__(self, __other: complex) -> complex128: ... + @overload + def __call__(self, __other: _NumberType) -> _NumberType: ... + + class _BoolMod(Protocol): + @overload + def __call__(self, __other: _BoolLike) -> int8: ... + @overload # platform dependent + def __call__(self, __other: int) -> signedinteger[Any]: ... + @overload + def __call__(self, __other: float) -> float64: ... + @overload + def __call__(self, __other: _IntType) -> _IntType: ... + @overload + def __call__(self, __other: _FloatType) -> _FloatType: ... + + class _BoolDivMod(Protocol): + @overload + def __call__(self, __other: _BoolLike) -> _2Tuple[int8]: ... + @overload # platform dependent + def __call__(self, __other: int) -> _2Tuple[signedinteger[Any]]: ... + @overload + def __call__(self, __other: float) -> _2Tuple[float64]: ... + @overload + def __call__(self, __other: _IntType) -> _2Tuple[_IntType]: ... + @overload + def __call__(self, __other: _FloatType) -> _2Tuple[_FloatType]: ... + + class _TD64Div(Protocol[_NumberType_co]): + @overload + def __call__(self, __other: timedelta64) -> _NumberType_co: ... + @overload + def __call__(self, __other: _FloatLike) -> timedelta64: ... + + class _IntTrueDiv(Protocol[_NBit_co]): + @overload + def __call__(self, __other: bool) -> floating[_NBit_co]: ... + @overload + def __call__(self, __other: int) -> floating[Any]: ... + @overload + def __call__(self, __other: float) -> float64: ... + @overload + def __call__(self, __other: complex) -> complex128: ... + @overload + def __call__(self, __other: integer[_NBit]) -> floating[Union[_NBit_co, _NBit]]: ... + + class _UnsignedIntOp(Protocol[_NBit_co]): + # NOTE: `uint64 + signedinteger -> float64` + @overload + def __call__(self, __other: bool) -> unsignedinteger[_NBit_co]: ... + @overload + def __call__( + self, __other: Union[int, signedinteger[Any]] + ) -> Union[signedinteger[Any], float64]: ... + @overload + def __call__(self, __other: float) -> float64: ... + @overload + def __call__(self, __other: complex) -> complex128: ... + @overload + def __call__( + self, __other: unsignedinteger[_NBit] + ) -> unsignedinteger[Union[_NBit_co, _NBit]]: ... + + class _UnsignedIntBitOp(Protocol[_NBit_co]): + @overload + def __call__(self, __other: bool) -> unsignedinteger[_NBit_co]: ... + @overload + def __call__(self, __other: int) -> signedinteger[Any]: ... + @overload + def __call__(self, __other: signedinteger[Any]) -> signedinteger[Any]: ... + @overload + def __call__( + self, __other: unsignedinteger[_NBit] + ) -> unsignedinteger[Union[_NBit_co, _NBit]]: ... + + class _UnsignedIntMod(Protocol[_NBit_co]): + @overload + def __call__(self, __other: bool) -> unsignedinteger[_NBit_co]: ... + @overload + def __call__( + self, __other: Union[int, signedinteger[Any]] + ) -> Union[signedinteger[Any], float64]: ... + @overload + def __call__(self, __other: float) -> float64: ... + @overload + def __call__( + self, __other: unsignedinteger[_NBit] + ) -> unsignedinteger[Union[_NBit_co, _NBit]]: ... + + class _UnsignedIntDivMod(Protocol[_NBit_co]): + @overload + def __call__(self, __other: bool) -> _2Tuple[signedinteger[_NBit_co]]: ... + @overload + def __call__( + self, __other: Union[int, signedinteger[Any]] + ) -> Union[_2Tuple[signedinteger[Any]], _2Tuple[float64]]: ... + @overload + def __call__(self, __other: float) -> _2Tuple[float64]: ... + @overload + def __call__( + self, __other: unsignedinteger[_NBit] + ) -> _2Tuple[unsignedinteger[Union[_NBit_co, _NBit]]]: ... + + class _SignedIntOp(Protocol[_NBit_co]): + @overload + def __call__(self, __other: bool) -> signedinteger[_NBit_co]: ... + @overload + def __call__(self, __other: int) -> signedinteger[Any]: ... + @overload + def __call__(self, __other: float) -> float64: ... + @overload + def __call__(self, __other: complex) -> complex128: ... + @overload + def __call__( + self, __other: signedinteger[_NBit] + ) -> signedinteger[Union[_NBit_co, _NBit]]: ... + + class _SignedIntBitOp(Protocol[_NBit_co]): + @overload + def __call__(self, __other: bool) -> signedinteger[_NBit_co]: ... + @overload + def __call__(self, __other: int) -> signedinteger[Any]: ... + @overload + def __call__( + self, __other: signedinteger[_NBit] + ) -> signedinteger[Union[_NBit_co, _NBit]]: ... + + class _SignedIntMod(Protocol[_NBit_co]): + @overload + def __call__(self, __other: bool) -> signedinteger[_NBit_co]: ... + @overload + def __call__(self, __other: int) -> signedinteger[Any]: ... + @overload + def __call__(self, __other: float) -> float64: ... + @overload + def __call__( + self, __other: signedinteger[_NBit] + ) -> signedinteger[Union[_NBit_co, _NBit]]: ... + + class _SignedIntDivMod(Protocol[_NBit_co]): + @overload + def __call__(self, __other: bool) -> _2Tuple[signedinteger[_NBit_co]]: ... + @overload + def __call__(self, __other: int) -> _2Tuple[signedinteger[Any]]: ... + @overload + def __call__(self, __other: float) -> _2Tuple[float64]: ... + @overload + def __call__( + self, __other: signedinteger[_NBit] + ) -> _2Tuple[signedinteger[Union[_NBit_co, _NBit]]]: ... + + class _FloatOp(Protocol[_NBit_co]): + @overload + def __call__(self, __other: bool) -> floating[_NBit_co]: ... + @overload + def __call__(self, __other: int) -> floating[Any]: ... + @overload + def __call__(self, __other: float) -> float64: ... + @overload + def __call__(self, __other: complex) -> complex128: ... + @overload + def __call__( + self, __other: Union[integer[_NBit], floating[_NBit]] + ) -> floating[Union[_NBit_co, _NBit]]: ... + + class _FloatMod(Protocol[_NBit_co]): + @overload + def __call__(self, __other: bool) -> floating[_NBit_co]: ... + @overload + def __call__(self, __other: int) -> floating[Any]: ... + @overload + def __call__(self, __other: float) -> float64: ... + @overload + def __call__( + self, __other: Union[integer[_NBit], floating[_NBit]] + ) -> floating[Union[_NBit_co, _NBit]]: ... + + class _FloatDivMod(Protocol[_NBit_co]): + @overload + def __call__(self, __other: bool) -> _2Tuple[floating[_NBit_co]]: ... + @overload + def __call__(self, __other: int) -> _2Tuple[floating[Any]]: ... + @overload + def __call__(self, __other: float) -> _2Tuple[float64]: ... + @overload + def __call__( + self, __other: Union[integer[_NBit], floating[_NBit]] + ) -> _2Tuple[floating[Union[_NBit_co, _NBit]]]: ... + + class _ComplexOp(Protocol[_NBit_co]): + @overload + def __call__(self, __other: bool) -> complexfloating[_NBit_co, _NBit_co]: ... + @overload + def __call__(self, __other: int) -> complexfloating[Any, Any]: ... + @overload + def __call__(self, __other: Union[float, complex]) -> complex128: ... + @overload + def __call__( + self, + __other: Union[ + integer[_NBit], + floating[_NBit], + complexfloating[_NBit, _NBit], + ] + ) -> complexfloating[Union[_NBit_co, _NBit], Union[_NBit_co, _NBit]]: ... + + class _NumberOp(Protocol): + def __call__(self, __other: _NumberLike) -> number: ... + +else: + _BoolOp = Any + _BoolBitOp = Any + _BoolSub = Any + _BoolTrueDiv = Any + _BoolMod = Any + _BoolDivMod = Any + _TD64Div = Any + _IntTrueDiv = Any + _UnsignedIntOp = Any + _UnsignedIntBitOp = Any + _UnsignedIntMod = Any + _UnsignedIntDivMod = Any + _SignedIntOp = Any + _SignedIntBitOp = Any + _SignedIntMod = Any + _SignedIntDivMod = Any + _FloatOp = Any + _FloatMod = Any + _FloatDivMod = Any + _ComplexOp = Any + _NumberOp = Any diff --git a/venv/Lib/site-packages/numpy/typing/_dtype_like.py b/venv/Lib/site-packages/numpy/typing/_dtype_like.py new file mode 100644 index 0000000..1953bd5 --- /dev/null +++ b/venv/Lib/site-packages/numpy/typing/_dtype_like.py @@ -0,0 +1,81 @@ +import sys +from typing import Any, List, Sequence, Tuple, Union, TYPE_CHECKING + +from numpy import dtype +from ._shape import _ShapeLike + +if sys.version_info >= (3, 8): + from typing import Protocol, TypedDict + HAVE_PROTOCOL = True +else: + try: + from typing_extensions import Protocol, TypedDict + except ImportError: + HAVE_PROTOCOL = False + else: + HAVE_PROTOCOL = True + +_DTypeLikeNested = Any # TODO: wait for support for recursive types + +if TYPE_CHECKING or HAVE_PROTOCOL: + # Mandatory keys + class _DTypeDictBase(TypedDict): + names: Sequence[str] + formats: Sequence[_DTypeLikeNested] + + # Mandatory + optional keys + class _DTypeDict(_DTypeDictBase, total=False): + offsets: Sequence[int] + titles: Sequence[Any] # Only `str` elements are usable as indexing aliases, but all objects are legal + itemsize: int + aligned: bool + + # A protocol for anything with the dtype attribute + class _SupportsDType(Protocol): + dtype: _DTypeLikeNested + +else: + _DTypeDict = Any + _SupportsDType = Any + + +# Would create a dtype[np.void] +_VoidDTypeLike = Union[ + # (flexible_dtype, itemsize) + Tuple[_DTypeLikeNested, int], + # (fixed_dtype, shape) + Tuple[_DTypeLikeNested, _ShapeLike], + # [(field_name, field_dtype, field_shape), ...] + # + # The type here is quite broad because NumPy accepts quite a wide + # range of inputs inside the list; see the tests for some + # examples. + List[Any], + # {'names': ..., 'formats': ..., 'offsets': ..., 'titles': ..., + # 'itemsize': ...} + _DTypeDict, + # (base_dtype, new_dtype) + Tuple[_DTypeLikeNested, _DTypeLikeNested], +] + +# Anything that can be coerced into numpy.dtype. +# Reference: https://docs.scipy.org/doc/numpy/reference/arrays.dtypes.html +DTypeLike = Union[ + dtype, + # default data type (float64) + None, + # array-scalar types and generic types + type, # TODO: enumerate these when we add type hints for numpy scalars + # anything with a dtype attribute + _SupportsDType, + # character codes, type strings or comma-separated fields, e.g., 'float64' + str, + _VoidDTypeLike, +] + +# NOTE: while it is possible to provide the dtype as a dict of +# dtype-like objects (e.g. `{'field1': ..., 'field2': ..., ...}`), +# this syntax is officially discourged and +# therefore not included in the Union defining `DTypeLike`. +# +# See https://github.com/numpy/numpy/issues/16891 for more details. diff --git a/venv/Lib/site-packages/numpy/typing/_scalars.py b/venv/Lib/site-packages/numpy/typing/_scalars.py new file mode 100644 index 0000000..e4fc28b --- /dev/null +++ b/venv/Lib/site-packages/numpy/typing/_scalars.py @@ -0,0 +1,26 @@ +from typing import Union, Tuple, Any + +import numpy as np + +# NOTE: `_StrLike` and `_BytesLike` are pointless, as `np.str_` and `np.bytes_` +# are already subclasses of their builtin counterpart + +_CharLike = Union[str, bytes] + +_BoolLike = Union[bool, np.bool_] +_IntLike = Union[int, np.integer] +_FloatLike = Union[_IntLike, float, np.floating] +_ComplexLike = Union[_FloatLike, complex, np.complexfloating] +_NumberLike = Union[int, float, complex, np.number, np.bool_] + +_ScalarLike = Union[ + int, + float, + complex, + str, + bytes, + np.generic, +] + +# `_VoidLike` is technically not a scalar, but it's close enough +_VoidLike = Union[Tuple[Any, ...], np.void] diff --git a/venv/Lib/site-packages/numpy/typing/_shape.py b/venv/Lib/site-packages/numpy/typing/_shape.py new file mode 100644 index 0000000..4629046 --- /dev/null +++ b/venv/Lib/site-packages/numpy/typing/_shape.py @@ -0,0 +1,6 @@ +from typing import Sequence, Tuple, Union + +_Shape = Tuple[int, ...] + +# Anything that can be coerced to a shape tuple +_ShapeLike = Union[int, Sequence[int]] diff --git a/venv/Lib/site-packages/numpy/typing/setup.py b/venv/Lib/site-packages/numpy/typing/setup.py new file mode 100644 index 0000000..c444e76 --- /dev/null +++ b/venv/Lib/site-packages/numpy/typing/setup.py @@ -0,0 +1,11 @@ +def configuration(parent_package='', top_path=None): + from numpy.distutils.misc_util import Configuration + config = Configuration('typing', parent_package, top_path) + config.add_subpackage('tests') + config.add_data_dir('tests/data') + return config + + +if __name__ == '__main__': + from numpy.distutils.core import setup + setup(configuration=configuration) diff --git a/venv/Lib/site-packages/numpy/typing/tests/__init__.py b/venv/Lib/site-packages/numpy/typing/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/venv/Lib/site-packages/numpy/typing/tests/data/fail/arithmetic.py b/venv/Lib/site-packages/numpy/typing/tests/data/fail/arithmetic.py new file mode 100644 index 0000000..f32eddc --- /dev/null +++ b/venv/Lib/site-packages/numpy/typing/tests/data/fail/arithmetic.py @@ -0,0 +1,16 @@ +import numpy as np + +b_ = np.bool_() +dt = np.datetime64(0, "D") +td = np.timedelta64(0, "D") + +b_ - b_ # E: No overload variant + +dt + dt # E: Unsupported operand types +td - dt # E: Unsupported operand types +td % 1 # E: Unsupported operand types +td / dt # E: No overload +td % dt # E: Unsupported operand types + +-b_ # E: Unsupported operand type ++b_ # E: Unsupported operand type diff --git a/venv/Lib/site-packages/numpy/typing/tests/data/fail/array_constructors.py b/venv/Lib/site-packages/numpy/typing/tests/data/fail/array_constructors.py new file mode 100644 index 0000000..9cb59fe --- /dev/null +++ b/venv/Lib/site-packages/numpy/typing/tests/data/fail/array_constructors.py @@ -0,0 +1,31 @@ +import numpy as np + +a: np.ndarray +generator = (i for i in range(10)) + +np.require(a, requirements=1) # E: No overload variant +np.require(a, requirements="TEST") # E: incompatible type + +np.zeros("test") # E: incompatible type +np.zeros() # E: Too few arguments + +np.ones("test") # E: incompatible type +np.ones() # E: Too few arguments + +np.array(0, float, True) # E: Too many positional + +np.linspace(None, 'bob') # E: No overload variant +np.linspace(0, 2, num=10.0) # E: No overload variant +np.linspace(0, 2, endpoint='True') # E: No overload variant +np.linspace(0, 2, retstep=b'False') # E: No overload variant +np.linspace(0, 2, dtype=0) # E: No overload variant +np.linspace(0, 2, axis=None) # E: No overload variant + +np.logspace(None, 'bob') # E: Argument 1 +np.logspace(0, 2, base=None) # E: Argument "base" + +np.geomspace(None, 'bob') # E: Argument 1 + +np.stack(generator) # E: No overload variant +np.hstack({1, 2}) # E: incompatible type +np.vstack(1) # E: incompatible type diff --git a/venv/Lib/site-packages/numpy/typing/tests/data/fail/array_like.py b/venv/Lib/site-packages/numpy/typing/tests/data/fail/array_like.py new file mode 100644 index 0000000..a97e72d --- /dev/null +++ b/venv/Lib/site-packages/numpy/typing/tests/data/fail/array_like.py @@ -0,0 +1,16 @@ +import numpy as np +from numpy.typing import ArrayLike + + +class A: + pass + + +x1: ArrayLike = (i for i in range(10)) # E: Incompatible types in assignment +x2: ArrayLike = A() # E: Incompatible types in assignment +x3: ArrayLike = {1: "foo", 2: "bar"} # E: Incompatible types in assignment + +scalar = np.int64(1) +scalar.__array__(dtype=np.float64) # E: Unexpected keyword argument +array = np.array([1]) +array.__array__(dtype=np.float64) # E: Unexpected keyword argument diff --git a/venv/Lib/site-packages/numpy/typing/tests/data/fail/bitwise_ops.py b/venv/Lib/site-packages/numpy/typing/tests/data/fail/bitwise_ops.py new file mode 100644 index 0000000..8a8f897 --- /dev/null +++ b/venv/Lib/site-packages/numpy/typing/tests/data/fail/bitwise_ops.py @@ -0,0 +1,20 @@ +import numpy as np + +i8 = np.int64() +i4 = np.int32() +u8 = np.uint64() +b_ = np.bool_() +i = int() + +f8 = np.float64() + +b_ >> f8 # E: No overload variant +i8 << f8 # E: No overload variant +i | f8 # E: Unsupported operand types +i8 ^ f8 # E: No overload variant +u8 & f8 # E: No overload variant +~f8 # E: Unsupported operand type + +# mypys' error message for `NoReturn` is unfortunately pretty bad +# TODO: Reenable this once we add support for numerical precision for `number`s +# a = u8 | 0 # E: Need type annotation diff --git a/venv/Lib/site-packages/numpy/typing/tests/data/fail/constants.py b/venv/Lib/site-packages/numpy/typing/tests/data/fail/constants.py new file mode 100644 index 0000000..67ee0e0 --- /dev/null +++ b/venv/Lib/site-packages/numpy/typing/tests/data/fail/constants.py @@ -0,0 +1,6 @@ +import numpy as np + +np.Inf = np.Inf # E: Cannot assign to final +np.ALLOW_THREADS = np.ALLOW_THREADS # E: Cannot assign to final +np.little_endian = np.little_endian # E: Cannot assign to final +np.UFUNC_PYVALS_NAME = np.UFUNC_PYVALS_NAME # E: Cannot assign to final diff --git a/venv/Lib/site-packages/numpy/typing/tests/data/fail/dtype.py b/venv/Lib/site-packages/numpy/typing/tests/data/fail/dtype.py new file mode 100644 index 0000000..7d4783d --- /dev/null +++ b/venv/Lib/site-packages/numpy/typing/tests/data/fail/dtype.py @@ -0,0 +1,16 @@ +import numpy as np + +class Test: + not_dtype = float + + +np.dtype(Test()) # E: No overload variant of "dtype" matches + +np.dtype( # E: No overload variant of "dtype" matches + { + "field1": (float, 1), + "field2": (int, 3), + } +) + +np.dtype[np.float64](np.int64) # E: Argument 1 to "dtype" has incompatible type diff --git a/venv/Lib/site-packages/numpy/typing/tests/data/fail/flatiter.py b/venv/Lib/site-packages/numpy/typing/tests/data/fail/flatiter.py new file mode 100644 index 0000000..544ffbe --- /dev/null +++ b/venv/Lib/site-packages/numpy/typing/tests/data/fail/flatiter.py @@ -0,0 +1,25 @@ +from typing import Any + +import numpy as np +from numpy.typing import _SupportsArray + + +class Index: + def __index__(self) -> int: + ... + + +a: "np.flatiter[np.ndarray]" +supports_array: _SupportsArray + +a.base = Any # E: Property "base" defined in "flatiter" is read-only +a.coords = Any # E: Property "coords" defined in "flatiter" is read-only +a.index = Any # E: Property "index" defined in "flatiter" is read-only +a.copy(order='C') # E: Unexpected keyword argument + +# NOTE: Contrary to `ndarray.__getitem__` its counterpart in `flatiter` +# does not accept objects with the `__array__` or `__index__` protocols; +# boolean indexing is just plain broken (gh-17175) +a[np.bool_()] # E: No overload variant of "__getitem__" +a[Index()] # E: No overload variant of "__getitem__" +a[supports_array] # E: No overload variant of "__getitem__" diff --git a/venv/Lib/site-packages/numpy/typing/tests/data/fail/fromnumeric.py b/venv/Lib/site-packages/numpy/typing/tests/data/fail/fromnumeric.py new file mode 100644 index 0000000..c915689 --- /dev/null +++ b/venv/Lib/site-packages/numpy/typing/tests/data/fail/fromnumeric.py @@ -0,0 +1,154 @@ +"""Tests for :mod:`numpy.core.fromnumeric`.""" + +import numpy as np + +A = np.array(True, ndmin=2, dtype=bool) +A.setflags(write=False) + +a = np.bool_(True) + +np.take(a, None) # E: No overload variant of "take" matches argument type +np.take(a, axis=1.0) # E: No overload variant of "take" matches argument type +np.take(A, out=1) # E: No overload variant of "take" matches argument type +np.take(A, mode="bob") # E: No overload variant of "take" matches argument type + +np.reshape(a, None) # E: Argument 2 to "reshape" has incompatible type +np.reshape(A, 1, order="bob") # E: Argument "order" to "reshape" has incompatible type + +np.choose(a, None) # E: No overload variant of "choose" matches argument type +np.choose(a, out=1.0) # E: No overload variant of "choose" matches argument type +np.choose(A, mode="bob") # E: No overload variant of "choose" matches argument type + +np.repeat(a, None) # E: Argument 2 to "repeat" has incompatible type +np.repeat(A, 1, axis=1.0) # E: Argument "axis" to "repeat" has incompatible type + +np.swapaxes(A, None, 1) # E: Argument 2 to "swapaxes" has incompatible type +np.swapaxes(A, 1, [0]) # E: Argument 3 to "swapaxes" has incompatible type + +np.transpose(A, axes=1.0) # E: Argument "axes" to "transpose" has incompatible type + +np.partition(a, None) # E: Argument 2 to "partition" has incompatible type +np.partition( + a, 0, axis="bob" # E: Argument "axis" to "partition" has incompatible type +) +np.partition( + A, 0, kind="bob" # E: Argument "kind" to "partition" has incompatible type +) +np.partition( + A, 0, order=range(5) # E: Argument "order" to "partition" has incompatible type +) + +np.argpartition( # E: No overload variant of "argpartition" matches argument type + a, None +) +np.argpartition( # E: No overload variant of "argpartition" matches argument type + a, 0, axis="bob" +) +np.argpartition( # E: No overload variant of "argpartition" matches argument type + A, 0, kind="bob" +) +np.argpartition( + A, 0, order=range(5) # E: Argument "order" to "argpartition" has incompatible type +) + +np.sort(A, axis="bob") # E: Argument "axis" to "sort" has incompatible type +np.sort(A, kind="bob") # E: Argument "kind" to "sort" has incompatible type +np.sort(A, order=range(5)) # E: Argument "order" to "sort" has incompatible type + +np.argsort(A, axis="bob") # E: Argument "axis" to "argsort" has incompatible type +np.argsort(A, kind="bob") # E: Argument "kind" to "argsort" has incompatible type +np.argsort(A, order=range(5)) # E: Argument "order" to "argsort" has incompatible type + +np.argmax(A, axis="bob") # E: No overload variant of "argmax" matches argument type +np.argmax(A, kind="bob") # E: No overload variant of "argmax" matches argument type + +np.argmin(A, axis="bob") # E: No overload variant of "argmin" matches argument type +np.argmin(A, kind="bob") # E: No overload variant of "argmin" matches argument type + +np.searchsorted( # E: No overload variant of "searchsorted" matches argument type + A[0], 0, side="bob" +) +np.searchsorted( # E: No overload variant of "searchsorted" matches argument type + A[0], 0, sorter=1.0 +) + +np.resize(A, 1.0) # E: Argument 2 to "resize" has incompatible type + +np.squeeze(A, 1.0) # E: No overload variant of "squeeze" matches argument type + +np.diagonal(A, offset=None) # E: Argument "offset" to "diagonal" has incompatible type +np.diagonal(A, axis1="bob") # E: Argument "axis1" to "diagonal" has incompatible type +np.diagonal(A, axis2=[]) # E: Argument "axis2" to "diagonal" has incompatible type + +np.trace(A, offset=None) # E: Argument "offset" to "trace" has incompatible type +np.trace(A, axis1="bob") # E: Argument "axis1" to "trace" has incompatible type +np.trace(A, axis2=[]) # E: Argument "axis2" to "trace" has incompatible type + +np.ravel(a, order="bob") # E: Argument "order" to "ravel" has incompatible type + +np.compress( + [True], A, axis=1.0 # E: Argument "axis" to "compress" has incompatible type +) + +np.clip(a, 1, 2, out=1) # E: No overload variant of "clip" matches argument type +np.clip(1, None, None) # E: No overload variant of "clip" matches argument type + +np.sum(a, axis=1.0) # E: No overload variant of "sum" matches argument type +np.sum(a, keepdims=1.0) # E: No overload variant of "sum" matches argument type +np.sum(a, initial=[1]) # E: No overload variant of "sum" matches argument type + +np.all(a, axis=1.0) # E: No overload variant of "all" matches argument type +np.all(a, keepdims=1.0) # E: No overload variant of "all" matches argument type +np.all(a, out=1.0) # E: No overload variant of "all" matches argument type + +np.any(a, axis=1.0) # E: No overload variant of "any" matches argument type +np.any(a, keepdims=1.0) # E: No overload variant of "any" matches argument type +np.any(a, out=1.0) # E: No overload variant of "any" matches argument type + +np.cumsum(a, axis=1.0) # E: Argument "axis" to "cumsum" has incompatible type +np.cumsum(a, dtype=1.0) # E: Argument "dtype" to "cumsum" has incompatible type +np.cumsum(a, out=1.0) # E: Argument "out" to "cumsum" has incompatible type + +np.ptp(a, axis=1.0) # E: No overload variant of "ptp" matches argument type +np.ptp(a, keepdims=1.0) # E: No overload variant of "ptp" matches argument type +np.ptp(a, out=1.0) # E: No overload variant of "ptp" matches argument type + +np.amax(a, axis=1.0) # E: No overload variant of "amax" matches argument type +np.amax(a, keepdims=1.0) # E: No overload variant of "amax" matches argument type +np.amax(a, out=1.0) # E: No overload variant of "amax" matches argument type +np.amax(a, initial=[1.0]) # E: No overload variant of "amax" matches argument type +np.amax(a, where=[1.0]) # E: List item 0 has incompatible type + +np.amin(a, axis=1.0) # E: No overload variant of "amin" matches argument type +np.amin(a, keepdims=1.0) # E: No overload variant of "amin" matches argument type +np.amin(a, out=1.0) # E: No overload variant of "amin" matches argument type +np.amin(a, initial=[1.0]) # E: No overload variant of "amin" matches argument type +np.amin(a, where=[1.0]) # E: List item 0 has incompatible type + +np.prod(a, axis=1.0) # E: No overload variant of "prod" matches argument type +np.prod(a, out=False) # E: No overload variant of "prod" matches argument type +np.prod(a, keepdims=1.0) # E: No overload variant of "prod" matches argument type +np.prod(a, initial=int) # E: No overload variant of "prod" matches argument type +np.prod(a, where=1.0) # E: No overload variant of "prod" matches argument type + +np.cumprod(a, axis=1.0) # E: Argument "axis" to "cumprod" has incompatible type +np.cumprod(a, out=False) # E: Argument "out" to "cumprod" has incompatible type + +np.size(a, axis=1.0) # E: Argument "axis" to "size" has incompatible type + +np.around(a, decimals=1.0) # E: No overload variant of "around" matches argument type +np.around(a, out=type) # E: No overload variant of "around" matches argument type + +np.mean(a, axis=1.0) # E: No overload variant of "mean" matches argument type +np.mean(a, out=False) # E: No overload variant of "mean" matches argument type +np.mean(a, keepdims=1.0) # E: No overload variant of "mean" matches argument type + +np.std(a, axis=1.0) # E: No overload variant of "std" matches argument type +np.std(a, out=False) # E: No overload variant of "std" matches argument type +np.std(a, ddof='test') # E: No overload variant of "std" matches argument type +np.std(a, keepdims=1.0) # E: No overload variant of "std" matches argument type + +np.var(a, axis=1.0) # E: No overload variant of "var" matches argument type +np.var(a, out=False) # E: No overload variant of "var" matches argument type +np.var(a, ddof='test') # E: No overload variant of "var" matches argument type +np.var(a, keepdims=1.0) # E: No overload variant of "var" matches argument type diff --git a/venv/Lib/site-packages/numpy/typing/tests/data/fail/modules.py b/venv/Lib/site-packages/numpy/typing/tests/data/fail/modules.py new file mode 100644 index 0000000..5770666 --- /dev/null +++ b/venv/Lib/site-packages/numpy/typing/tests/data/fail/modules.py @@ -0,0 +1,15 @@ +import numpy as np + +np.testing.bob # E: Module has no attribute +np.bob # E: Module has no attribute + +# Stdlib modules in the namespace by accident +np.warnings # E: Module has no attribute +np.sys # E: Module has no attribute +np.os # E: Module has no attribute +np.math # E: Module has no attribute + +# Public sub-modules that are not imported to their parent module by default; +# e.g. one must first execute `import numpy.lib.recfunctions` +np.lib.recfunctions # E: Module has no attribute +np.ma.mrecords # E: Module has no attribute diff --git a/venv/Lib/site-packages/numpy/typing/tests/data/fail/ndarray.py b/venv/Lib/site-packages/numpy/typing/tests/data/fail/ndarray.py new file mode 100644 index 0000000..5a5130d --- /dev/null +++ b/venv/Lib/site-packages/numpy/typing/tests/data/fail/ndarray.py @@ -0,0 +1,11 @@ +import numpy as np + +# Ban setting dtype since mutating the type of the array in place +# makes having ndarray be generic over dtype impossible. Generally +# users should use `ndarray.view` in this situation anyway. See +# +# https://github.com/numpy/numpy-stubs/issues/7 +# +# for more context. +float_array = np.array([1.0]) +float_array.dtype = np.bool_ # E: Property "dtype" defined in "ndarray" is read-only diff --git a/venv/Lib/site-packages/numpy/typing/tests/data/fail/ndarray_misc.py b/venv/Lib/site-packages/numpy/typing/tests/data/fail/ndarray_misc.py new file mode 100644 index 0000000..1e1496b --- /dev/null +++ b/venv/Lib/site-packages/numpy/typing/tests/data/fail/ndarray_misc.py @@ -0,0 +1,21 @@ +""" +Tests for miscellaneous (non-magic) ``np.ndarray``/``np.generic`` methods. + +More extensive tests are performed for the methods' +function-based counterpart in `../from_numeric.py`. + +""" + +import numpy as np + +f8: np.float64 + +f8.argpartition(0) # E: has no attribute +f8.diagonal() # E: has no attribute +f8.dot(1) # E: has no attribute +f8.nonzero() # E: has no attribute +f8.partition(0) # E: has no attribute +f8.put(0, 2) # E: has no attribute +f8.setfield(2, np.float64) # E: has no attribute +f8.sort() # E: has no attribute +f8.trace() # E: has no attribute diff --git a/venv/Lib/site-packages/numpy/typing/tests/data/fail/numerictypes.py b/venv/Lib/site-packages/numpy/typing/tests/data/fail/numerictypes.py new file mode 100644 index 0000000..94537a2 --- /dev/null +++ b/venv/Lib/site-packages/numpy/typing/tests/data/fail/numerictypes.py @@ -0,0 +1,13 @@ +import numpy as np + +# Techincally this works, but probably shouldn't. See +# +# https://github.com/numpy/numpy/issues/16366 +# +np.maximum_sctype(1) # E: incompatible type "int" + +np.issubsctype(1, np.int64) # E: incompatible type "int" + +np.issubdtype(1, np.int64) # E: incompatible type "int" + +np.find_common_type(np.int64, np.int64) # E: incompatible type "Type[signedinteger[Any]]" diff --git a/venv/Lib/site-packages/numpy/typing/tests/data/fail/scalars.py b/venv/Lib/site-packages/numpy/typing/tests/data/fail/scalars.py new file mode 100644 index 0000000..f097408 --- /dev/null +++ b/venv/Lib/site-packages/numpy/typing/tests/data/fail/scalars.py @@ -0,0 +1,76 @@ +import numpy as np + +f8: np.float64 + +# Construction + +np.float32(3j) # E: incompatible type + +# Technically the following examples are valid NumPy code. But they +# are not considered a best practice, and people who wish to use the +# stubs should instead do +# +# np.array([1.0, 0.0, 0.0], dtype=np.float32) +# np.array([], dtype=np.complex64) +# +# See e.g. the discussion on the mailing list +# +# https://mail.python.org/pipermail/numpy-discussion/2020-April/080566.html +# +# and the issue +# +# https://github.com/numpy/numpy-stubs/issues/41 +# +# for more context. +np.float32([1.0, 0.0, 0.0]) # E: incompatible type +np.complex64([]) # E: incompatible type + +np.complex64(1, 2) # E: Too many arguments +# TODO: protocols (can't check for non-existent protocols w/ __getattr__) + +np.datetime64(0) # E: non-matching overload + +class A: + def __float__(self): + return 1.0 + + +np.int8(A()) # E: incompatible type +np.int16(A()) # E: incompatible type +np.int32(A()) # E: incompatible type +np.int64(A()) # E: incompatible type +np.uint8(A()) # E: incompatible type +np.uint16(A()) # E: incompatible type +np.uint32(A()) # E: incompatible type +np.uint64(A()) # E: incompatible type + +np.void("test") # E: incompatible type + +np.generic(1) # E: Cannot instantiate abstract class +np.number(1) # E: Cannot instantiate abstract class +np.integer(1) # E: Cannot instantiate abstract class +np.inexact(1) # E: Cannot instantiate abstract class +np.character("test") # E: Cannot instantiate abstract class +np.flexible(b"test") # E: Cannot instantiate abstract class + +np.float64(value=0.0) # E: Unexpected keyword argument +np.int64(value=0) # E: Unexpected keyword argument +np.uint64(value=0) # E: Unexpected keyword argument +np.complex128(value=0.0j) # E: Unexpected keyword argument +np.str_(value='bob') # E: No overload variant +np.bytes_(value=b'test') # E: No overload variant +np.void(value=b'test') # E: Unexpected keyword argument +np.bool_(value=True) # E: Unexpected keyword argument +np.datetime64(value="2019") # E: No overload variant +np.timedelta64(value=0) # E: Unexpected keyword argument + +np.bytes_(b"hello", encoding='utf-8') # E: No overload variant +np.str_("hello", encoding='utf-8') # E: No overload variant + +complex(np.bytes_("1")) # E: No overload variant + +f8.item(1) # E: incompatible type +f8.item((0, 1)) # E: incompatible type +f8.squeeze(axis=1) # E: incompatible type +f8.squeeze(axis=(0, 1)) # E: incompatible type +f8.transpose(1) # E: incompatible type diff --git a/venv/Lib/site-packages/numpy/typing/tests/data/fail/ufunc_config.py b/venv/Lib/site-packages/numpy/typing/tests/data/fail/ufunc_config.py new file mode 100644 index 0000000..f547fbb --- /dev/null +++ b/venv/Lib/site-packages/numpy/typing/tests/data/fail/ufunc_config.py @@ -0,0 +1,21 @@ +"""Typing tests for `numpy.core._ufunc_config`.""" + +import numpy as np + +def func1(a: str, b: int, c: float) -> None: ... +def func2(a: str, *, b: int) -> None: ... + +class Write1: + def write1(self, a: str) -> None: ... + +class Write2: + def write(self, a: str, b: str) -> None: ... + +class Write3: + def write(self, *, a: str) -> None: ... + +np.seterrcall(func1) # E: Argument 1 to "seterrcall" has incompatible type +np.seterrcall(func2) # E: Argument 1 to "seterrcall" has incompatible type +np.seterrcall(Write1()) # E: Argument 1 to "seterrcall" has incompatible type +np.seterrcall(Write2()) # E: Argument 1 to "seterrcall" has incompatible type +np.seterrcall(Write3()) # E: Argument 1 to "seterrcall" has incompatible type diff --git a/venv/Lib/site-packages/numpy/typing/tests/data/fail/ufuncs.py b/venv/Lib/site-packages/numpy/typing/tests/data/fail/ufuncs.py new file mode 100644 index 0000000..4da9d08 --- /dev/null +++ b/venv/Lib/site-packages/numpy/typing/tests/data/fail/ufuncs.py @@ -0,0 +1,7 @@ +import numpy as np + +np.sin.nin + "foo" # E: Unsupported operand types +np.sin(1, foo="bar") # E: Unexpected keyword argument +np.sin(1, extobj=["foo", "foo", "foo"]) # E: incompatible type + +np.abs(None) # E: incompatible type diff --git a/venv/Lib/site-packages/numpy/typing/tests/data/fail/warnings_and_errors.py b/venv/Lib/site-packages/numpy/typing/tests/data/fail/warnings_and_errors.py new file mode 100644 index 0000000..7390cc4 --- /dev/null +++ b/venv/Lib/site-packages/numpy/typing/tests/data/fail/warnings_and_errors.py @@ -0,0 +1,7 @@ +import numpy as np + +np.AxisError(1.0) # E: Argument 1 to "AxisError" has incompatible type +np.AxisError(1, ndim=2.0) # E: Argument "ndim" to "AxisError" has incompatible type +np.AxisError( + 2, msg_prefix=404 # E: Argument "msg_prefix" to "AxisError" has incompatible type +) diff --git a/venv/Lib/site-packages/numpy/typing/tests/data/mypy.ini b/venv/Lib/site-packages/numpy/typing/tests/data/mypy.ini new file mode 100644 index 0000000..91d9358 --- /dev/null +++ b/venv/Lib/site-packages/numpy/typing/tests/data/mypy.ini @@ -0,0 +1,8 @@ +[mypy] +mypy_path = ../../.. + +[mypy-numpy] +ignore_errors = True + +[mypy-numpy.*] +ignore_errors = True diff --git a/venv/Lib/site-packages/numpy/typing/tests/data/pass/arithmetic.py b/venv/Lib/site-packages/numpy/typing/tests/data/pass/arithmetic.py new file mode 100644 index 0000000..ffbaf29 --- /dev/null +++ b/venv/Lib/site-packages/numpy/typing/tests/data/pass/arithmetic.py @@ -0,0 +1,293 @@ +import numpy as np + +c16 = np.complex128(1) +f8 = np.float64(1) +i8 = np.int64(1) +u8 = np.uint64(1) + +c8 = np.complex64(1) +f4 = np.float32(1) +i4 = np.int32(1) +u4 = np.uint32(1) + +dt = np.datetime64(1, "D") +td = np.timedelta64(1, "D") + +b_ = np.bool_(1) + +b = bool(1) +c = complex(1) +f = float(1) +i = int(1) + +AR = np.ones(1, dtype=np.float64) +AR.setflags(write=False) + +# unary ops + +-c16 +-c8 +-f8 +-f4 +-i8 +-i4 +-u8 +-u4 +-td +-AR + ++c16 ++c8 ++f8 ++f4 ++i8 ++i4 ++u8 ++u4 ++td ++AR + +abs(c16) +abs(c8) +abs(f8) +abs(f4) +abs(i8) +abs(i4) +abs(u8) +abs(u4) +abs(td) +abs(b_) +abs(AR) + +# Time structures + +dt + td +dt + i +dt + i4 +dt + i8 +dt - dt +dt - i +dt - i4 +dt - i8 + +td + td +td + i +td + i4 +td + i8 +td - td +td - i +td - i4 +td - i8 +td / f +td / f4 +td / f8 +td / td +td // td +td % td + + +# boolean + +b_ / b +b_ / b_ +b_ / i +b_ / i8 +b_ / i4 +b_ / u8 +b_ / u4 +b_ / f +b_ / f8 +b_ / f4 +b_ / c +b_ / c16 +b_ / c8 + +b / b_ +b_ / b_ +i / b_ +i8 / b_ +i4 / b_ +u8 / b_ +u4 / b_ +f / b_ +f8 / b_ +f4 / b_ +c / b_ +c16 / b_ +c8 / b_ + +# Complex + +c16 + c16 +c16 + f8 +c16 + i8 +c16 + c8 +c16 + f4 +c16 + i4 +c16 + b_ +c16 + b +c16 + c +c16 + f +c16 + i +c16 + AR + +c16 + c16 +f8 + c16 +i8 + c16 +c8 + c16 +f4 + c16 +i4 + c16 +b_ + c16 +b + c16 +c + c16 +f + c16 +i + c16 +AR + c16 + +c8 + c16 +c8 + f8 +c8 + i8 +c8 + c8 +c8 + f4 +c8 + i4 +c8 + b_ +c8 + b +c8 + c +c8 + f +c8 + i +c8 + AR + +c16 + c8 +f8 + c8 +i8 + c8 +c8 + c8 +f4 + c8 +i4 + c8 +b_ + c8 +b + c8 +c + c8 +f + c8 +i + c8 +AR + c8 + +# Float + +f8 + f8 +f8 + i8 +f8 + f4 +f8 + i4 +f8 + b_ +f8 + b +f8 + c +f8 + f +f8 + i +f8 + AR + +f8 + f8 +i8 + f8 +f4 + f8 +i4 + f8 +b_ + f8 +b + f8 +c + f8 +f + f8 +i + f8 +AR + f8 + +f4 + f8 +f4 + i8 +f4 + f4 +f4 + i4 +f4 + b_ +f4 + b +f4 + c +f4 + f +f4 + i +f4 + AR + +f8 + f4 +i8 + f4 +f4 + f4 +i4 + f4 +b_ + f4 +b + f4 +c + f4 +f + f4 +i + f4 +AR + f4 + +# Int + +i8 + i8 +i8 + u8 +i8 + i4 +i8 + u4 +i8 + b_ +i8 + b +i8 + c +i8 + f +i8 + i +i8 + AR + +u8 + u8 +u8 + i4 +u8 + u4 +u8 + b_ +u8 + b +u8 + c +u8 + f +u8 + i +u8 + AR + +i8 + i8 +u8 + i8 +i4 + i8 +u4 + i8 +b_ + i8 +b + i8 +c + i8 +f + i8 +i + i8 +AR + i8 + +u8 + u8 +i4 + u8 +u4 + u8 +b_ + u8 +b + u8 +c + u8 +f + u8 +i + u8 +AR + u8 + +i4 + i8 +i4 + i4 +i4 + i +i4 + b_ +i4 + b +i4 + AR + +u4 + i8 +u4 + i4 +u4 + u8 +u4 + u4 +u4 + i +u4 + b_ +u4 + b +u4 + AR + +i8 + i4 +i4 + i4 +i + i4 +b_ + i4 +b + i4 +AR + i4 + +i8 + u4 +i4 + u4 +u8 + u4 +u4 + u4 +b_ + u4 +b + u4 +i + u4 +AR + u4 diff --git a/venv/Lib/site-packages/numpy/typing/tests/data/pass/array_constructors.py b/venv/Lib/site-packages/numpy/typing/tests/data/pass/array_constructors.py new file mode 100644 index 0000000..63208f1 --- /dev/null +++ b/venv/Lib/site-packages/numpy/typing/tests/data/pass/array_constructors.py @@ -0,0 +1,128 @@ +from typing import List, Any +import numpy as np + +class Index: + def __index__(self) -> int: + return 0 + +class SubClass(np.ndarray): ... + +i8 = np.int64(1) + +A = np.array([1]) +B = A.view(SubClass).copy() +B_stack = np.array([[1], [1]]).view(SubClass) +C = [1] + +def func(i: int, j: int, **kwargs: Any) -> SubClass: + return B + +np.array(1, dtype=float) +np.array(1, copy=False) +np.array(1, order='F') +np.array(1, order=None) +np.array(1, subok=True) +np.array(1, ndmin=3) +np.array(1, str, copy=True, order='C', subok=False, ndmin=2) + +np.asarray(A) +np.asarray(B) +np.asarray(C) + +np.asanyarray(A) +np.asanyarray(B) +np.asanyarray(B, dtype=int) +np.asanyarray(C) + +np.ascontiguousarray(A) +np.ascontiguousarray(B) +np.ascontiguousarray(C) + +np.asfortranarray(A) +np.asfortranarray(B) +np.asfortranarray(C) + +np.require(A) +np.require(B) +np.require(B, dtype=int) +np.require(B, requirements=None) +np.require(B, requirements="E") +np.require(B, requirements=["ENSUREARRAY"]) +np.require(B, requirements={"F", "E"}) +np.require(B, requirements=["C", "OWNDATA"]) +np.require(B, requirements="W") +np.require(B, requirements="A") +np.require(C) + +np.linspace(0, 2) +np.linspace(0.5, [0, 1, 2]) +np.linspace([0, 1, 2], 3) +np.linspace(0j, 2) +np.linspace(0, 2, num=10) +np.linspace(0, 2, endpoint=True) +np.linspace(0, 2, retstep=True) +np.linspace(0j, 2j, retstep=True) +np.linspace(0, 2, dtype=bool) +np.linspace([0, 1], [2, 3], axis=Index()) + +np.logspace(0, 2, base=2) +np.logspace(0, 2, base=2) +np.logspace(0, 2, base=[1j, 2j], num=2) + +np.geomspace(1, 2) + +np.zeros_like(A) +np.zeros_like(C) +np.zeros_like(B) +np.zeros_like(B, dtype=np.int64) + +np.ones_like(A) +np.ones_like(C) +np.ones_like(B) +np.ones_like(B, dtype=np.int64) + +np.empty_like(A) +np.empty_like(C) +np.empty_like(B) +np.empty_like(B, dtype=np.int64) + +np.full_like(A, i8) +np.full_like(C, i8) +np.full_like(B, i8) +np.full_like(B, i8, dtype=np.int64) + +np.ones(1) +np.ones([1, 1, 1]) + +np.full(1, i8) +np.full([1, 1, 1], i8) + +np.indices([1, 2, 3]) +np.indices([1, 2, 3], sparse=True) + +np.fromfunction(func, (3, 5)) + +np.identity(10) + +np.atleast_1d(C) +np.atleast_1d(A) +np.atleast_1d(C, C) +np.atleast_1d(C, A) +np.atleast_1d(A, A) + +np.atleast_2d(C) + +np.atleast_3d(C) + +np.vstack([C, C]) +np.vstack([C, A]) +np.vstack([A, A]) + +np.hstack([C, C]) + +np.stack([C, C]) +np.stack([C, C], axis=0) +np.stack([C, C], out=B_stack) + +np.block([[C, C], [C, C]]) +np.block(A) diff --git a/venv/Lib/site-packages/numpy/typing/tests/data/pass/array_like.py b/venv/Lib/site-packages/numpy/typing/tests/data/pass/array_like.py new file mode 100644 index 0000000..f857242 --- /dev/null +++ b/venv/Lib/site-packages/numpy/typing/tests/data/pass/array_like.py @@ -0,0 +1,39 @@ +from typing import Any, List, Optional + +import numpy as np +from numpy.typing import ArrayLike, DTypeLike, _SupportsArray + +x1: ArrayLike = True +x2: ArrayLike = 5 +x3: ArrayLike = 1.0 +x4: ArrayLike = 1 + 1j +x5: ArrayLike = np.int8(1) +x6: ArrayLike = np.float64(1) +x7: ArrayLike = np.complex128(1) +x8: ArrayLike = np.array([1, 2, 3]) +x9: ArrayLike = [1, 2, 3] +x10: ArrayLike = (1, 2, 3) +x11: ArrayLike = "foo" +x12: ArrayLike = memoryview(b'foo') + + +class A: + def __array__(self, dtype: DTypeLike = None) -> np.ndarray: + return np.array([1, 2, 3]) + + +x13: ArrayLike = A() + +scalar: _SupportsArray = np.int64(1) +scalar.__array__(np.float64) +array: _SupportsArray = np.array(1) +array.__array__(np.float64) + +a: _SupportsArray = A() +a.__array__(np.int64) +a.__array__(dtype=np.int64) + +# Escape hatch for when you mean to make something like an object +# array. +object_array_scalar: Any = (i for i in range(10)) +np.array(object_array_scalar) diff --git a/venv/Lib/site-packages/numpy/typing/tests/data/pass/bitwise_ops.py b/venv/Lib/site-packages/numpy/typing/tests/data/pass/bitwise_ops.py new file mode 100644 index 0000000..67449e2 --- /dev/null +++ b/venv/Lib/site-packages/numpy/typing/tests/data/pass/bitwise_ops.py @@ -0,0 +1,131 @@ +import numpy as np + +i8 = np.int64(1) +u8 = np.uint64(1) + +i4 = np.int32(1) +u4 = np.uint32(1) + +b_ = np.bool_(1) + +b = bool(1) +i = int(1) + +AR = np.array([0, 1, 2], dtype=np.int32) +AR.setflags(write=False) + + +i8 << i8 +i8 >> i8 +i8 | i8 +i8 ^ i8 +i8 & i8 + +i8 << AR +i8 >> AR +i8 | AR +i8 ^ AR +i8 & AR + +i4 << i4 +i4 >> i4 +i4 | i4 +i4 ^ i4 +i4 & i4 + +i8 << i4 +i8 >> i4 +i8 | i4 +i8 ^ i4 +i8 & i4 + +i8 << i +i8 >> i +i8 | i +i8 ^ i +i8 & i + +i8 << b_ +i8 >> b_ +i8 | b_ +i8 ^ b_ +i8 & b_ + +i8 << b +i8 >> b +i8 | b +i8 ^ b +i8 & b + +u8 << u8 +u8 >> u8 +u8 | u8 +u8 ^ u8 +u8 & u8 + +u8 << AR +u8 >> AR +u8 | AR +u8 ^ AR +u8 & AR + +u4 << u4 +u4 >> u4 +u4 | u4 +u4 ^ u4 +u4 & u4 + +u4 << i4 +u4 >> i4 +u4 | i4 +u4 ^ i4 +u4 & i4 + +u4 << i +u4 >> i +u4 | i +u4 ^ i +u4 & i + +u8 << b_ +u8 >> b_ +u8 | b_ +u8 ^ b_ +u8 & b_ + +u8 << b +u8 >> b +u8 | b +u8 ^ b +u8 & b + +b_ << b_ +b_ >> b_ +b_ | b_ +b_ ^ b_ +b_ & b_ + +b_ << AR +b_ >> AR +b_ | AR +b_ ^ AR +b_ & AR + +b_ << b +b_ >> b +b_ | b +b_ ^ b +b_ & b + +b_ << i +b_ >> i +b_ | i +b_ ^ i +b_ & i + +~i8 +~i4 +~u8 +~u4 +~b_ +~AR diff --git a/venv/Lib/site-packages/numpy/typing/tests/data/pass/dtype.py b/venv/Lib/site-packages/numpy/typing/tests/data/pass/dtype.py new file mode 100644 index 0000000..9071520 --- /dev/null +++ b/venv/Lib/site-packages/numpy/typing/tests/data/pass/dtype.py @@ -0,0 +1,51 @@ +import numpy as np + +dtype_obj = np.dtype(np.str_) +void_dtype_obj = np.dtype([("f0", np.float64), ("f1", np.float32)]) + +np.dtype(dtype=np.int64) +np.dtype(int) +np.dtype("int") +np.dtype(None) + +np.dtype((int, 2)) +np.dtype((int, (1,))) + +np.dtype({"names": ["a", "b"], "formats": [int, float]}) +np.dtype({"names": ["a"], "formats": [int], "titles": [object]}) +np.dtype({"names": ["a"], "formats": [int], "titles": [object()]}) + +np.dtype([("name", np.unicode_, 16), ("grades", np.float64, (2,)), ("age", "int32")]) + +np.dtype( + { + "names": ["a", "b"], + "formats": [int, float], + "itemsize": 9, + "aligned": False, + "titles": ["x", "y"], + "offsets": [0, 1], + } +) + +np.dtype((np.float_, float)) + + +class Test: + dtype = float + + +np.dtype(Test()) + +dtype_obj.names + +dtype_obj * 0 +dtype_obj * 2 + +0 * dtype_obj +2 * dtype_obj + +void_dtype_obj["f0"] +void_dtype_obj[0] +void_dtype_obj[["f0", "f1"]] +void_dtype_obj[["f0"]] diff --git a/venv/Lib/site-packages/numpy/typing/tests/data/pass/flatiter.py b/venv/Lib/site-packages/numpy/typing/tests/data/pass/flatiter.py new file mode 100644 index 0000000..c0219eb --- /dev/null +++ b/venv/Lib/site-packages/numpy/typing/tests/data/pass/flatiter.py @@ -0,0 +1,14 @@ +import numpy as np + +a = np.empty((2, 2)).flat + +a.base +a.copy() +a.coords +a.index +iter(a) +next(a) +a[0] +a[[0, 1, 2]] +a[...] +a[:] diff --git a/venv/Lib/site-packages/numpy/typing/tests/data/pass/fromnumeric.py b/venv/Lib/site-packages/numpy/typing/tests/data/pass/fromnumeric.py new file mode 100644 index 0000000..9e936e6 --- /dev/null +++ b/venv/Lib/site-packages/numpy/typing/tests/data/pass/fromnumeric.py @@ -0,0 +1,260 @@ +"""Tests for :mod:`numpy.core.fromnumeric`.""" + +import numpy as np + +A = np.array(True, ndmin=2, dtype=bool) +B = np.array(1.0, ndmin=2, dtype=np.float32) +A.setflags(write=False) +B.setflags(write=False) + +a = np.bool_(True) +b = np.float32(1.0) +c = 1.0 +d = np.array(1.0, dtype=np.float32) # writeable + +np.take(a, 0) +np.take(b, 0) +np.take(c, 0) +np.take(A, 0) +np.take(B, 0) +np.take(A, [0]) +np.take(B, [0]) + +np.reshape(a, 1) +np.reshape(b, 1) +np.reshape(c, 1) +np.reshape(A, 1) +np.reshape(B, 1) + +np.choose(a, [True, True]) +np.choose(A, [1.0, 1.0]) + +np.repeat(a, 1) +np.repeat(b, 1) +np.repeat(c, 1) +np.repeat(A, 1) +np.repeat(B, 1) + +np.swapaxes(A, 0, 0) +np.swapaxes(B, 0, 0) + +np.transpose(a) +np.transpose(b) +np.transpose(c) +np.transpose(A) +np.transpose(B) + +np.partition(a, 0, axis=None) +np.partition(b, 0, axis=None) +np.partition(c, 0, axis=None) +np.partition(A, 0) +np.partition(B, 0) + +np.argpartition(a, 0) +np.argpartition(b, 0) +np.argpartition(c, 0) +np.argpartition(A, 0) +np.argpartition(B, 0) + +np.sort(A, 0) +np.sort(B, 0) + +np.argsort(A, 0) +np.argsort(B, 0) + +np.argmax(A) +np.argmax(B) +np.argmax(A, axis=0) +np.argmax(B, axis=0) + +np.argmin(A) +np.argmin(B) +np.argmin(A, axis=0) +np.argmin(B, axis=0) + +np.searchsorted(A[0], 0) +np.searchsorted(B[0], 0) +np.searchsorted(A[0], [0]) +np.searchsorted(B[0], [0]) + +np.resize(a, (5, 5)) +np.resize(b, (5, 5)) +np.resize(c, (5, 5)) +np.resize(A, (5, 5)) +np.resize(B, (5, 5)) + +np.squeeze(a) +np.squeeze(b) +np.squeeze(c) +np.squeeze(A) +np.squeeze(B) + +np.diagonal(A) +np.diagonal(B) + +np.trace(A) +np.trace(B) + +np.ravel(a) +np.ravel(b) +np.ravel(c) +np.ravel(A) +np.ravel(B) + +np.nonzero(A) +np.nonzero(B) + +np.shape(a) +np.shape(b) +np.shape(c) +np.shape(A) +np.shape(B) + +np.compress([True], a) +np.compress([True], b) +np.compress([True], c) +np.compress([True], A) +np.compress([True], B) + +np.clip(a, 0, 1.0) +np.clip(b, -1, 1) +np.clip(a, 0, None) +np.clip(b, None, 1) +np.clip(c, 0, 1) +np.clip(A, 0, 1) +np.clip(B, 0, 1) +np.clip(B, [0, 1], [1, 2]) + +np.sum(a) +np.sum(b) +np.sum(c) +np.sum(A) +np.sum(B) +np.sum(A, axis=0) +np.sum(B, axis=0) + +np.all(a) +np.all(b) +np.all(c) +np.all(A) +np.all(B) +np.all(A, axis=0) +np.all(B, axis=0) +np.all(A, keepdims=True) +np.all(B, keepdims=True) + +np.any(a) +np.any(b) +np.any(c) +np.any(A) +np.any(B) +np.any(A, axis=0) +np.any(B, axis=0) +np.any(A, keepdims=True) +np.any(B, keepdims=True) + +np.cumsum(a) +np.cumsum(b) +np.cumsum(c) +np.cumsum(A) +np.cumsum(B) + +np.ptp(b) +np.ptp(c) +np.ptp(B) +np.ptp(B, axis=0) +np.ptp(B, keepdims=True) + +np.amax(a) +np.amax(b) +np.amax(c) +np.amax(A) +np.amax(B) +np.amax(A, axis=0) +np.amax(B, axis=0) +np.amax(A, keepdims=True) +np.amax(B, keepdims=True) + +np.amin(a) +np.amin(b) +np.amin(c) +np.amin(A) +np.amin(B) +np.amin(A, axis=0) +np.amin(B, axis=0) +np.amin(A, keepdims=True) +np.amin(B, keepdims=True) + +np.prod(a) +np.prod(b) +np.prod(c) +np.prod(A) +np.prod(B) +np.prod(a, dtype=None) +np.prod(A, dtype=None) +np.prod(A, axis=0) +np.prod(B, axis=0) +np.prod(A, keepdims=True) +np.prod(B, keepdims=True) +np.prod(b, out=d) +np.prod(B, out=d) + +np.cumprod(a) +np.cumprod(b) +np.cumprod(c) +np.cumprod(A) +np.cumprod(B) + +np.ndim(a) +np.ndim(b) +np.ndim(c) +np.ndim(A) +np.ndim(B) + +np.size(a) +np.size(b) +np.size(c) +np.size(A) +np.size(B) + +np.around(a) +np.around(b) +np.around(c) +np.around(A) +np.around(B) + +np.mean(a) +np.mean(b) +np.mean(c) +np.mean(A) +np.mean(B) +np.mean(A, axis=0) +np.mean(B, axis=0) +np.mean(A, keepdims=True) +np.mean(B, keepdims=True) +np.mean(b, out=d) +np.mean(B, out=d) + +np.std(a) +np.std(b) +np.std(c) +np.std(A) +np.std(B) +np.std(A, axis=0) +np.std(B, axis=0) +np.std(A, keepdims=True) +np.std(B, keepdims=True) +np.std(b, out=d) +np.std(B, out=d) + +np.var(a) +np.var(b) +np.var(c) +np.var(A) +np.var(B) +np.var(A, axis=0) +np.var(B, axis=0) +np.var(A, keepdims=True) +np.var(B, keepdims=True) +np.var(b, out=d) +np.var(B, out=d) diff --git a/venv/Lib/site-packages/numpy/typing/tests/data/pass/literal.py b/venv/Lib/site-packages/numpy/typing/tests/data/pass/literal.py new file mode 100644 index 0000000..8eaeb6a --- /dev/null +++ b/venv/Lib/site-packages/numpy/typing/tests/data/pass/literal.py @@ -0,0 +1,45 @@ +from functools import partial +from typing import Callable, List, Tuple + +import pytest # type: ignore +import numpy as np + +AR = np.array(0) +AR.setflags(write=False) + +KACF = frozenset({None, "K", "A", "C", "F"}) +ACF = frozenset({None, "A", "C", "F"}) +CF = frozenset({None, "C", "F"}) + +order_list: List[Tuple[frozenset, Callable]] = [ + (KACF, partial(np.ndarray, 1)), + (KACF, AR.tobytes), + (KACF, partial(AR.astype, int)), + (KACF, AR.copy), + (ACF, partial(AR.reshape, 1)), + (KACF, AR.flatten), + (KACF, AR.ravel), + (KACF, partial(np.array, 1)), + (CF, partial(np.zeros, 1)), + (CF, partial(np.ones, 1)), + (CF, partial(np.empty, 1)), + (CF, partial(np.full, 1, 1)), + (KACF, partial(np.zeros_like, AR)), + (KACF, partial(np.ones_like, AR)), + (KACF, partial(np.empty_like, AR)), + (KACF, partial(np.full_like, AR, 1)), + (KACF, partial(np.add, 1, 1)), # i.e. np.ufunc.__call__ + (ACF, partial(np.reshape, AR, 1)), + (KACF, partial(np.ravel, AR)), + (KACF, partial(np.asarray, 1)), + (KACF, partial(np.asanyarray, 1)), +] + +for order_set, func in order_list: + for order in order_set: + func(order=order) + + invalid_orders = KACF - order_set + for order in invalid_orders: + with pytest.raises(ValueError): + func(order=order) diff --git a/venv/Lib/site-packages/numpy/typing/tests/data/pass/mod.py b/venv/Lib/site-packages/numpy/typing/tests/data/pass/mod.py new file mode 100644 index 0000000..b5b9afb --- /dev/null +++ b/venv/Lib/site-packages/numpy/typing/tests/data/pass/mod.py @@ -0,0 +1,149 @@ +import numpy as np + +f8 = np.float64(1) +i8 = np.int64(1) +u8 = np.uint64(1) + +f4 = np.float32(1) +i4 = np.int32(1) +u4 = np.uint32(1) + +td = np.timedelta64(1, "D") +b_ = np.bool_(1) + +b = bool(1) +f = float(1) +i = int(1) + +AR = np.array([1], dtype=np.bool_) +AR.setflags(write=False) + +AR2 = np.array([1], dtype=np.timedelta64) +AR2.setflags(write=False) + +# Time structures + +td % td +td % AR2 +AR2 % td + +divmod(td, td) +divmod(td, AR2) +divmod(AR2, td) + +# Bool + +b_ % b +b_ % i +b_ % f +b_ % b_ +b_ % i8 +b_ % u8 +b_ % f8 +b_ % AR + +divmod(b_, b) +divmod(b_, i) +divmod(b_, f) +divmod(b_, b_) +divmod(b_, i8) +divmod(b_, u8) +divmod(b_, f8) +divmod(b_, AR) + +b % b_ +i % b_ +f % b_ +b_ % b_ +i8 % b_ +u8 % b_ +f8 % b_ +AR % b_ + +divmod(b, b_) +divmod(i, b_) +divmod(f, b_) +divmod(b_, b_) +divmod(i8, b_) +divmod(u8, b_) +divmod(f8, b_) +divmod(AR, b_) + +# int + +i8 % b +i8 % i +i8 % f +i8 % i8 +i8 % f8 +i4 % i8 +i4 % f8 +i4 % i4 +i4 % f4 +i8 % AR + +divmod(i8, b) +divmod(i8, i) +divmod(i8, f) +divmod(i8, i8) +divmod(i8, f8) +divmod(i8, i4) +divmod(i8, f4) +divmod(i4, i4) +divmod(i4, f4) +divmod(i8, AR) + +b % i8 +i % i8 +f % i8 +i8 % i8 +f8 % i8 +i8 % i4 +f8 % i4 +i4 % i4 +f4 % i4 +AR % i8 + +divmod(b, i8) +divmod(i, i8) +divmod(f, i8) +divmod(i8, i8) +divmod(f8, i8) +divmod(i4, i8) +divmod(f4, i8) +divmod(i4, i4) +divmod(f4, i4) +divmod(AR, i8) + +# float + +f8 % b +f8 % i +f8 % f +i8 % f4 +f4 % f4 +f8 % AR + +divmod(f8, b) +divmod(f8, i) +divmod(f8, f) +divmod(f8, f8) +divmod(f8, f4) +divmod(f4, f4) +divmod(f8, AR) + +b % f8 +i % f8 +f % f8 +f8 % f8 +f8 % f8 +f4 % f4 +AR % f8 + +divmod(b, f8) +divmod(i, f8) +divmod(f, f8) +divmod(f8, f8) +divmod(f4, f8) +divmod(f4, f4) +divmod(AR, f8) diff --git a/venv/Lib/site-packages/numpy/typing/tests/data/pass/modules.py b/venv/Lib/site-packages/numpy/typing/tests/data/pass/modules.py new file mode 100644 index 0000000..f2d779e --- /dev/null +++ b/venv/Lib/site-packages/numpy/typing/tests/data/pass/modules.py @@ -0,0 +1,42 @@ +import numpy as np +from numpy import f2py + +np.char +np.ctypeslib +np.emath +np.fft +np.lib +np.linalg +np.ma +np.matrixlib +np.polynomial +np.random +np.rec +np.testing +np.version + +np.lib.format +np.lib.mixins +np.lib.scimath +np.lib.stride_tricks +np.ma.extras +np.polynomial.chebyshev +np.polynomial.hermite +np.polynomial.hermite_e +np.polynomial.laguerre +np.polynomial.legendre +np.polynomial.polynomial + +np.__path__ +np.__version__ + +np.__all__ +np.char.__all__ +np.ctypeslib.__all__ +np.emath.__all__ +np.lib.__all__ +np.ma.__all__ +np.random.__all__ +np.rec.__all__ +np.testing.__all__ +f2py.__all__ diff --git a/venv/Lib/site-packages/numpy/typing/tests/data/pass/ndarray_conversion.py b/venv/Lib/site-packages/numpy/typing/tests/data/pass/ndarray_conversion.py new file mode 100644 index 0000000..303cf53 --- /dev/null +++ b/venv/Lib/site-packages/numpy/typing/tests/data/pass/ndarray_conversion.py @@ -0,0 +1,94 @@ +import os +import tempfile + +import numpy as np + +nd = np.array([[1, 2], [3, 4]]) +scalar_array = np.array(1) + +# item +scalar_array.item() +nd.item(1) +nd.item(0, 1) +nd.item((0, 1)) + +# tolist is pretty simple + +# itemset +scalar_array.itemset(3) +nd.itemset(3, 0) +nd.itemset((0, 0), 3) + +# tobytes +nd.tobytes() +nd.tobytes("C") +nd.tobytes(None) + +# tofile +if os.name != "nt": + with tempfile.NamedTemporaryFile(suffix=".txt") as tmp: + nd.tofile(tmp.name) + nd.tofile(tmp.name, "") + nd.tofile(tmp.name, sep="") + + nd.tofile(tmp.name, "", "%s") + nd.tofile(tmp.name, format="%s") + + nd.tofile(tmp) + +# dump is pretty simple +# dumps is pretty simple + +# astype +nd.astype("float") +nd.astype(float) + +nd.astype(float, "K") +nd.astype(float, order="K") + +nd.astype(float, "K", "unsafe") +nd.astype(float, casting="unsafe") + +nd.astype(float, "K", "unsafe", True) +nd.astype(float, subok=True) + +nd.astype(float, "K", "unsafe", True, True) +nd.astype(float, copy=True) + +# byteswap +nd.byteswap() +nd.byteswap(True) + +# copy +nd.copy() +nd.copy("C") + +# view +nd.view() +nd.view(np.int64) +nd.view(dtype=np.int64) +nd.view(np.int64, np.matrix) +nd.view(type=np.matrix) + +# getfield +complex_array = np.array([[1 + 1j, 0], [0, 1 - 1j]], dtype=np.complex128) + +complex_array.getfield("float") +complex_array.getfield(float) + +complex_array.getfield("float", 8) +complex_array.getfield(float, offset=8) + +# setflags +nd.setflags() + +nd.setflags(True) +nd.setflags(write=True) + +nd.setflags(True, True) +nd.setflags(write=True, align=True) + +nd.setflags(True, True, False) +nd.setflags(write=True, align=True, uic=False) + +# fill is pretty simple diff --git a/venv/Lib/site-packages/numpy/typing/tests/data/pass/ndarray_misc.py b/venv/Lib/site-packages/numpy/typing/tests/data/pass/ndarray_misc.py new file mode 100644 index 0000000..6c6f5d5 --- /dev/null +++ b/venv/Lib/site-packages/numpy/typing/tests/data/pass/ndarray_misc.py @@ -0,0 +1,159 @@ +""" +Tests for miscellaneous (non-magic) ``np.ndarray``/``np.generic`` methods. + +More extensive tests are performed for the methods' +function-based counterpart in `../from_numeric.py`. + +""" + +from typing import cast +import numpy as np + +class SubClass(np.ndarray): ... + +i4 = np.int32(1) +A = np.array([[1]], dtype=np.int32) +B0 = np.empty((), dtype=np.int32).view(SubClass) +B1 = np.empty((1,), dtype=np.int32).view(SubClass) +B2 = np.empty((1, 1), dtype=np.int32).view(SubClass) +C = np.array([0, 1, 2], dtype=np.int32) +D = np.empty(3).view(SubClass) + +i4.all() +A.all() +A.all(axis=0) +A.all(keepdims=True) +A.all(out=B0) + +i4.any() +A.any() +A.any(axis=0) +A.any(keepdims=True) +A.any(out=B0) + +i4.argmax() +A.argmax() +A.argmax(axis=0) +A.argmax(out=B0) + +i4.argmin() +A.argmin() +A.argmin(axis=0) +A.argmin(out=B0) + +i4.argsort() +A.argsort() + +i4.choose([()]) +_choices = np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]], dtype=np.int32) +C.choose(_choices) +C.choose(_choices, out=D) + +i4.clip(1) +A.clip(1) +A.clip(None, 1) +A.clip(1, out=B2) +A.clip(None, 1, out=B2) + +i4.compress([1]) +A.compress([1]) +A.compress([1], out=B1) + +i4.conj() +A.conj() +B0.conj() + +i4.conjugate() +A.conjugate() +B0.conjugate() + +i4.cumprod() +A.cumprod() +A.cumprod(out=B1) + +i4.cumsum() +A.cumsum() +A.cumsum(out=B1) + +i4.max() +A.max() +A.max(axis=0) +A.max(keepdims=True) +A.max(out=B0) + +i4.mean() +A.mean() +A.mean(axis=0) +A.mean(keepdims=True) +A.mean(out=B0) + +i4.min() +A.min() +A.min(axis=0) +A.min(keepdims=True) +A.min(out=B0) + +i4.newbyteorder() +A.newbyteorder() +B0.newbyteorder('|') + +i4.prod() +A.prod() +A.prod(axis=0) +A.prod(keepdims=True) +A.prod(out=B0) + +i4.ptp() +A.ptp() +A.ptp(axis=0) +A.ptp(keepdims=True) +A.astype(int).ptp(out=B0) + +i4.round() +A.round() +A.round(out=B2) + +i4.repeat(1) +A.repeat(1) +B0.repeat(1) + +i4.std() +A.std() +A.std(axis=0) +A.std(keepdims=True) +A.std(out=B0.astype(np.float64)) + +i4.sum() +A.sum() +A.sum(axis=0) +A.sum(keepdims=True) +A.sum(out=B0) + +i4.take(0) +A.take(0) +A.take([0]) +A.take(0, out=B0) +A.take([0], out=B1) + +i4.var() +A.var() +A.var(axis=0) +A.var(keepdims=True) +A.var(out=B0) + +A.argpartition([0]) + +A.diagonal() + +A.dot(1) +A.dot(1, out=B0) + +A.nonzero() + +C.searchsorted(1) + +A.trace() +A.trace(out=B0) + +void = cast(np.void, np.array(1, dtype=[("f", np.float64)]).take(0)) +void.setfield(10, np.float64) diff --git a/venv/Lib/site-packages/numpy/typing/tests/data/pass/ndarray_shape_manipulation.py b/venv/Lib/site-packages/numpy/typing/tests/data/pass/ndarray_shape_manipulation.py new file mode 100644 index 0000000..0ca3dff --- /dev/null +++ b/venv/Lib/site-packages/numpy/typing/tests/data/pass/ndarray_shape_manipulation.py @@ -0,0 +1,47 @@ +import numpy as np + +nd1 = np.array([[1, 2], [3, 4]]) + +# reshape +nd1.reshape(4) +nd1.reshape(2, 2) +nd1.reshape((2, 2)) + +nd1.reshape((2, 2), order="C") +nd1.reshape(4, order="C") + +# resize +nd1.resize() +nd1.resize(4) +nd1.resize(2, 2) +nd1.resize((2, 2)) + +nd1.resize((2, 2), refcheck=True) +nd1.resize(4, refcheck=True) + +nd2 = np.array([[1, 2], [3, 4]]) + +# transpose +nd2.transpose() +nd2.transpose(1, 0) +nd2.transpose((1, 0)) + +# swapaxes +nd2.swapaxes(0, 1) + +# flatten +nd2.flatten() +nd2.flatten("C") + +# ravel +nd2.ravel() +nd2.ravel("C") + +# squeeze +nd2.squeeze() + +nd3 = np.array([[1, 2]]) +nd3.squeeze(0) + +nd4 = np.array([[[1, 2]]]) +nd4.squeeze((0, 1)) diff --git a/venv/Lib/site-packages/numpy/typing/tests/data/pass/numeric.py b/venv/Lib/site-packages/numpy/typing/tests/data/pass/numeric.py new file mode 100644 index 0000000..34fef72 --- /dev/null +++ b/venv/Lib/site-packages/numpy/typing/tests/data/pass/numeric.py @@ -0,0 +1,89 @@ +""" +Tests for :mod:`numpy.core.numeric`. + +Does not include tests which fall under ``array_constructors``. + +""" + +from typing import List +import numpy as np + +class SubClass(np.ndarray): + ... + +i8 = np.int64(1) + +A = np.arange(27).reshape(3, 3, 3) +B: List[List[List[int]]] = A.tolist() +C = np.empty((27, 27)).view(SubClass) + +np.count_nonzero(i8) +np.count_nonzero(A) +np.count_nonzero(B) +np.count_nonzero(A, keepdims=True) +np.count_nonzero(A, axis=0) + +np.isfortran(i8) +np.isfortran(A) + +np.argwhere(i8) +np.argwhere(A) + +np.flatnonzero(i8) +np.flatnonzero(A) + +np.correlate(B[0][0], A.ravel(), mode="valid") +np.correlate(A.ravel(), A.ravel(), mode="same") + +np.convolve(B[0][0], A.ravel(), mode="valid") +np.convolve(A.ravel(), A.ravel(), mode="same") + +np.outer(i8, A) +np.outer(B, A) +np.outer(A, A) +np.outer(A, A, out=C) + +np.tensordot(B, A) +np.tensordot(A, A) +np.tensordot(A, A, axes=0) +np.tensordot(A, A, axes=(0, 1)) + +np.isscalar(i8) +np.isscalar(A) +np.isscalar(B) + +np.roll(A, 1) +np.roll(A, (1, 2)) +np.roll(B, 1) + +np.rollaxis(A, 0, 1) + +np.moveaxis(A, 0, 1) +np.moveaxis(A, (0, 1), (1, 2)) + +np.cross(B, A) +np.cross(A, A) + +np.indices([0, 1, 2]) +np.indices([0, 1, 2], sparse=False) +np.indices([0, 1, 2], sparse=True) + +np.binary_repr(1) + +np.base_repr(1) + +np.allclose(i8, A) +np.allclose(B, A) +np.allclose(A, A) + +np.isclose(i8, A) +np.isclose(B, A) +np.isclose(A, A) + +np.array_equal(i8, A) +np.array_equal(B, A) +np.array_equal(A, A) + +np.array_equiv(i8, A) +np.array_equiv(B, A) +np.array_equiv(A, A) diff --git a/venv/Lib/site-packages/numpy/typing/tests/data/pass/numerictypes.py b/venv/Lib/site-packages/numpy/typing/tests/data/pass/numerictypes.py new file mode 100644 index 0000000..4f205ca --- /dev/null +++ b/venv/Lib/site-packages/numpy/typing/tests/data/pass/numerictypes.py @@ -0,0 +1,29 @@ +import numpy as np + +np.maximum_sctype("S8") +np.maximum_sctype(object) + +np.issctype(object) +np.issctype("S8") + +np.obj2sctype(list) +np.obj2sctype(list, default=None) +np.obj2sctype(list, default=np.string_) + +np.issubclass_(np.int32, int) +np.issubclass_(np.float64, float) +np.issubclass_(np.float64, (int, float)) + +np.issubsctype("int64", int) +np.issubsctype(np.array([1]), np.array([1])) + +np.issubdtype("S1", np.string_) +np.issubdtype(np.float64, np.float32) + +np.sctype2char("S1") +np.sctype2char(list) + +np.find_common_type([], [np.int64, np.float32, complex]) +np.find_common_type((), (np.int64, np.float32, complex)) +np.find_common_type([np.int64, np.float32], []) +np.find_common_type([np.float32], [np.int64, np.float64]) diff --git a/venv/Lib/site-packages/numpy/typing/tests/data/pass/scalars.py b/venv/Lib/site-packages/numpy/typing/tests/data/pass/scalars.py new file mode 100644 index 0000000..b7f7880 --- /dev/null +++ b/venv/Lib/site-packages/numpy/typing/tests/data/pass/scalars.py @@ -0,0 +1,165 @@ +import sys +import datetime as dt + +import pytest +import numpy as np + + +# Construction +class D: + def __index__(self) -> int: + return 0 + + +class C: + def __complex__(self) -> complex: + return 3j + + +class B: + def __int__(self) -> int: + return 4 + + +class A: + def __float__(self) -> float: + return 4.0 + + +np.complex64(3j) +np.complex64(A()) +np.complex64(C()) +np.complex128(3j) +np.complex128(C()) +np.complex128(None) +np.complex64("1.2") +np.complex128(b"2j") + +np.int8(4) +np.int16(3.4) +np.int32(4) +np.int64(-1) +np.uint8(B()) +np.uint32() +np.int32("1") +np.int64(b"2") + +np.float16(A()) +np.float32(16) +np.float64(3.0) +np.float64(None) +np.float32("1") +np.float16(b"2.5") + +if sys.version_info >= (3, 8): + np.uint64(D()) + np.float32(D()) + np.complex64(D()) + +np.bytes_(b"hello") +np.bytes_("hello", 'utf-8') +np.bytes_("hello", encoding='utf-8') +np.str_("hello") +np.str_(b"hello", 'utf-8') +np.str_(b"hello", encoding='utf-8') + +# Array-ish semantics +np.int8().real +np.int16().imag +np.int32().data +np.int64().flags + +np.uint8().itemsize * 2 +np.uint16().ndim + 1 +np.uint32().strides +np.uint64().shape + +# Time structures +np.datetime64() +np.datetime64(0, "D") +np.datetime64(0, b"D") +np.datetime64(0, ('ms', 3)) +np.datetime64("2019") +np.datetime64(b"2019") +np.datetime64("2019", "D") +np.datetime64(np.datetime64()) +np.datetime64(dt.datetime(2000, 5, 3)) +np.datetime64(None) +np.datetime64(None, "D") + +np.timedelta64() +np.timedelta64(0) +np.timedelta64(0, "D") +np.timedelta64(0, ('ms', 3)) +np.timedelta64(0, b"D") +np.timedelta64("3") +np.timedelta64(b"5") +np.timedelta64(np.timedelta64(2)) +np.timedelta64(dt.timedelta(2)) +np.timedelta64(None) +np.timedelta64(None, "D") + +np.void(1) +np.void(np.int64(1)) +np.void(True) +np.void(np.bool_(True)) +np.void(b"test") +np.void(np.bytes_("test")) + +# Protocols +i8 = np.int64() +u8 = np.uint64() +f8 = np.float64() +c16 = np.complex128() +b_ = np.bool_() +td = np.timedelta64() +U = np.str_("1") +S = np.bytes_("1") +AR = np.array(1, dtype=np.float64) + +int(i8) +int(u8) +int(f8) +int(b_) +int(td) +int(U) +int(S) +int(AR) +with pytest.warns(np.ComplexWarning): + int(c16) + +float(i8) +float(u8) +float(f8) +float(b_) +float(td) +float(U) +float(S) +float(AR) +with pytest.warns(np.ComplexWarning): + float(c16) + +complex(i8) +complex(u8) +complex(f8) +complex(c16) +complex(b_) +complex(td) +complex(U) +complex(AR) + + +# Misc +c16.dtype +c16.real +c16.imag +c16.real.real +c16.real.imag +c16.ndim +c16.size +c16.itemsize +c16.shape +c16.strides +c16.squeeze() +c16.byteswap() +c16.transpose() diff --git a/venv/Lib/site-packages/numpy/typing/tests/data/pass/simple.py b/venv/Lib/site-packages/numpy/typing/tests/data/pass/simple.py new file mode 100644 index 0000000..243caf2 --- /dev/null +++ b/venv/Lib/site-packages/numpy/typing/tests/data/pass/simple.py @@ -0,0 +1,165 @@ +"""Simple expression that should pass with mypy.""" +import operator + +import numpy as np +from typing import Iterable # noqa: F401 + +# Basic checks +array = np.array([1, 2]) + + +def ndarray_func(x): + # type: (np.ndarray) -> np.ndarray + return x + + +ndarray_func(np.array([1, 2])) +array == 1 +array.dtype == float + +# Dtype construction +np.dtype(float) +np.dtype(np.float64) +np.dtype(None) +np.dtype("float64") +np.dtype(np.dtype(float)) +np.dtype(("U", 10)) +np.dtype((np.int32, (2, 2))) +# Define the arguments on the previous line to prevent bidirectional +# type inference in mypy from broadening the types. +two_tuples_dtype = [("R", "u1"), ("G", "u1"), ("B", "u1")] +np.dtype(two_tuples_dtype) + +three_tuples_dtype = [("R", "u1", 2)] +np.dtype(three_tuples_dtype) + +mixed_tuples_dtype = [("R", "u1"), ("G", np.unicode_, 1)] +np.dtype(mixed_tuples_dtype) + +shape_tuple_dtype = [("R", "u1", (2, 2))] +np.dtype(shape_tuple_dtype) + +shape_like_dtype = [("R", "u1", (2, 2)), ("G", np.unicode_, 1)] +np.dtype(shape_like_dtype) + +object_dtype = [("field1", object)] +np.dtype(object_dtype) + +np.dtype((np.int32, (np.int8, 4))) + +# Dtype comparision +np.dtype(float) == float +np.dtype(float) != np.float64 +np.dtype(float) < None +np.dtype(float) <= "float64" +np.dtype(float) > np.dtype(float) +np.dtype(float) >= np.dtype(("U", 10)) + +# Iteration and indexing +def iterable_func(x): + # type: (Iterable) -> Iterable + return x + + +iterable_func(array) +[element for element in array] +iter(array) +zip(array, array) +array[1] +array[:] +array[...] +array[:] = 0 + +array_2d = np.ones((3, 3)) +array_2d[:2, :2] +array_2d[..., 0] +array_2d[:2, :2] = 0 + +# Other special methods +len(array) +str(array) +array_scalar = np.array(1) +int(array_scalar) +float(array_scalar) +# currently does not work due to https://github.com/python/typeshed/issues/1904 +# complex(array_scalar) +bytes(array_scalar) +operator.index(array_scalar) +bool(array_scalar) + +# comparisons +array < 1 +array <= 1 +array == 1 +array != 1 +array > 1 +array >= 1 +1 < array +1 <= array +1 == array +1 != array +1 > array +1 >= array + +# binary arithmetic +array + 1 +1 + array +array += 1 + +array - 1 +1 - array +array -= 1 + +array * 1 +1 * array +array *= 1 + +nonzero_array = np.array([1, 2]) +array / 1 +1 / nonzero_array +float_array = np.array([1.0, 2.0]) +float_array /= 1 + +array // 1 +1 // nonzero_array +array //= 1 + +array % 1 +1 % nonzero_array +array %= 1 + +divmod(array, 1) +divmod(1, nonzero_array) + +array ** 1 +1 ** array +array **= 1 + +array << 1 +1 << array +array <<= 1 + +array >> 1 +1 >> array +array >>= 1 + +array & 1 +1 & array +array &= 1 + +array ^ 1 +1 ^ array +array ^= 1 + +array | 1 +1 | array +array |= 1 + +# unary arithmetic +-array ++array +abs(array) +~array + +# Other methods +np.array([1, 2]).transpose() diff --git a/venv/Lib/site-packages/numpy/typing/tests/data/pass/simple_py3.py b/venv/Lib/site-packages/numpy/typing/tests/data/pass/simple_py3.py new file mode 100644 index 0000000..c05a1ce --- /dev/null +++ b/venv/Lib/site-packages/numpy/typing/tests/data/pass/simple_py3.py @@ -0,0 +1,6 @@ +import numpy as np + +array = np.array([1, 2]) + +# The @ operator is not in python 2 +array @ array diff --git a/venv/Lib/site-packages/numpy/typing/tests/data/pass/ufunc_config.py b/venv/Lib/site-packages/numpy/typing/tests/data/pass/ufunc_config.py new file mode 100644 index 0000000..2d13142 --- /dev/null +++ b/venv/Lib/site-packages/numpy/typing/tests/data/pass/ufunc_config.py @@ -0,0 +1,50 @@ +"""Typing tests for `numpy.core._ufunc_config`.""" + +import numpy as np + +def func1(a: str, b: int) -> None: ... +def func2(a: str, b: int, c: float = ...) -> None: ... +def func3(a: str, b: int) -> int: ... + +class Write1: + def write(self, a: str) -> None: ... + +class Write2: + def write(self, a: str, b: int = ...) -> None: ... + +class Write3: + def write(self, a: str) -> int: ... + + +_err_default = np.geterr() +_bufsize_default = np.getbufsize() +_errcall_default = np.geterrcall() + +try: + np.seterr(all=None) + np.seterr(divide="ignore") + np.seterr(over="warn") + np.seterr(under="call") + np.seterr(invalid="raise") + np.geterr() + + np.setbufsize(4096) + np.getbufsize() + + np.seterrcall(func1) + np.seterrcall(func2) + np.seterrcall(func3) + np.seterrcall(Write1()) + np.seterrcall(Write2()) + np.seterrcall(Write3()) + np.geterrcall() + + with np.errstate(call=func1, all="call"): + pass + with np.errstate(call=Write1(), divide="log", over="log"): + pass + +finally: + np.seterr(**_err_default) + np.setbufsize(_bufsize_default) + np.seterrcall(_errcall_default) diff --git a/venv/Lib/site-packages/numpy/typing/tests/data/pass/ufuncs.py b/venv/Lib/site-packages/numpy/typing/tests/data/pass/ufuncs.py new file mode 100644 index 0000000..ad4d483 --- /dev/null +++ b/venv/Lib/site-packages/numpy/typing/tests/data/pass/ufuncs.py @@ -0,0 +1,16 @@ +import numpy as np + +np.sin(1) +np.sin([1, 2, 3]) +np.sin(1, out=np.empty(1)) +np.matmul(np.ones((2, 2, 2)), np.ones((2, 2, 2)), axes=[(0, 1), (0, 1), (0, 1)]) +np.sin(1, signature="D") +np.sin(1, extobj=[16, 1, lambda: None]) +# NOTE: `np.generic` subclasses are not guaranteed to support addition; +# re-enable this we can infer the exact return type of `np.sin(...)`. +# +# np.sin(1) + np.sin(1) +np.sin.types[0] +np.sin.__name__ + +np.abs(np.array([1])) diff --git a/venv/Lib/site-packages/numpy/typing/tests/data/pass/warnings_and_errors.py b/venv/Lib/site-packages/numpy/typing/tests/data/pass/warnings_and_errors.py new file mode 100644 index 0000000..5b6ec26 --- /dev/null +++ b/venv/Lib/site-packages/numpy/typing/tests/data/pass/warnings_and_errors.py @@ -0,0 +1,7 @@ +import numpy as np + +np.AxisError(1) +np.AxisError(1, ndim=2) +np.AxisError(1, ndim=None) +np.AxisError(1, ndim=2, msg_prefix="error") +np.AxisError(1, ndim=2, msg_prefix=None) diff --git a/venv/Lib/site-packages/numpy/typing/tests/data/reveal/arithmetic.py b/venv/Lib/site-packages/numpy/typing/tests/data/reveal/arithmetic.py new file mode 100644 index 0000000..20310e6 --- /dev/null +++ b/venv/Lib/site-packages/numpy/typing/tests/data/reveal/arithmetic.py @@ -0,0 +1,291 @@ +import numpy as np + +c16 = np.complex128() +f8 = np.float64() +i8 = np.int64() +u8 = np.uint64() + +c8 = np.complex64() +f4 = np.float32() +i4 = np.int32() +u4 = np.uint32() + +dt = np.datetime64(0, "D") +td = np.timedelta64(0, "D") + +b_ = np.bool_() + +b = bool() +c = complex() +f = float() +i = int() + +AR = np.array([0], dtype=np.float64) +AR.setflags(write=False) + +# unary ops + +reveal_type(-c16) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit] +reveal_type(-c8) # E: numpy.complexfloating[numpy.typing._32Bit, numpy.typing._32Bit] +reveal_type(-f8) # E: numpy.floating[numpy.typing._64Bit] +reveal_type(-f4) # E: numpy.floating[numpy.typing._32Bit] +reveal_type(-i8) # E: numpy.signedinteger[numpy.typing._64Bit] +reveal_type(-i4) # E: numpy.signedinteger[numpy.typing._32Bit] +reveal_type(-u8) # E: numpy.unsignedinteger[numpy.typing._64Bit] +reveal_type(-u4) # E: numpy.unsignedinteger[numpy.typing._32Bit] +reveal_type(-td) # E: numpy.timedelta64 +reveal_type(-AR) # E: Any + +reveal_type(+c16) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit] +reveal_type(+c8) # E: numpy.complexfloating[numpy.typing._32Bit, numpy.typing._32Bit] +reveal_type(+f8) # E: numpy.floating[numpy.typing._64Bit] +reveal_type(+f4) # E: numpy.floating[numpy.typing._32Bit] +reveal_type(+i8) # E: numpy.signedinteger[numpy.typing._64Bit] +reveal_type(+i4) # E: numpy.signedinteger[numpy.typing._32Bit] +reveal_type(+u8) # E: numpy.unsignedinteger[numpy.typing._64Bit] +reveal_type(+u4) # E: numpy.unsignedinteger[numpy.typing._32Bit] +reveal_type(+td) # E: numpy.timedelta64 +reveal_type(+AR) # E: Any + +reveal_type(abs(c16)) # E: numpy.floating[numpy.typing._64Bit] +reveal_type(abs(c8)) # E: numpy.floating[numpy.typing._32Bit] +reveal_type(abs(f8)) # E: numpy.floating[numpy.typing._64Bit] +reveal_type(abs(f4)) # E: numpy.floating[numpy.typing._32Bit] +reveal_type(abs(i8)) # E: numpy.signedinteger[numpy.typing._64Bit] +reveal_type(abs(i4)) # E: numpy.signedinteger[numpy.typing._32Bit] +reveal_type(abs(u8)) # E: numpy.unsignedinteger[numpy.typing._64Bit] +reveal_type(abs(u4)) # E: numpy.unsignedinteger[numpy.typing._32Bit] +reveal_type(abs(td)) # E: numpy.timedelta64 +reveal_type(abs(b_)) # E: numpy.bool_ +reveal_type(abs(AR)) # E: Any + +# Time structures + +reveal_type(dt + td) # E: numpy.datetime64 +reveal_type(dt + i) # E: numpy.datetime64 +reveal_type(dt + i4) # E: numpy.datetime64 +reveal_type(dt + i8) # E: numpy.datetime64 +reveal_type(dt - dt) # E: numpy.timedelta64 +reveal_type(dt - i) # E: numpy.datetime64 +reveal_type(dt - i4) # E: numpy.datetime64 +reveal_type(dt - i8) # E: numpy.datetime64 + +reveal_type(td + td) # E: numpy.timedelta64 +reveal_type(td + i) # E: numpy.timedelta64 +reveal_type(td + i4) # E: numpy.timedelta64 +reveal_type(td + i8) # E: numpy.timedelta64 +reveal_type(td - td) # E: numpy.timedelta64 +reveal_type(td - i) # E: numpy.timedelta64 +reveal_type(td - i4) # E: numpy.timedelta64 +reveal_type(td - i8) # E: numpy.timedelta64 +reveal_type(td / f) # E: numpy.timedelta64 +reveal_type(td / f4) # E: numpy.timedelta64 +reveal_type(td / f8) # E: numpy.timedelta64 +reveal_type(td / td) # E: numpy.floating[numpy.typing._64Bit] +reveal_type(td // td) # E: numpy.signedinteger[numpy.typing._64Bit] + +# boolean + +reveal_type(b_ / b) # E: numpy.floating[numpy.typing._64Bit] +reveal_type(b_ / b_) # E: numpy.floating[numpy.typing._64Bit] +reveal_type(b_ / i) # E: numpy.floating[numpy.typing._64Bit] +reveal_type(b_ / i8) # E: numpy.floating[numpy.typing._64Bit] +reveal_type(b_ / i4) # E: numpy.floating[numpy.typing._64Bit] +reveal_type(b_ / u8) # E: numpy.floating[numpy.typing._64Bit] +reveal_type(b_ / u4) # E: numpy.floating[numpy.typing._64Bit] +reveal_type(b_ / f) # E: numpy.floating[numpy.typing._64Bit] +reveal_type(b_ / f8) # E: numpy.floating[numpy.typing._64Bit] +reveal_type(b_ / f4) # E: numpy.floating[numpy.typing._32Bit] +reveal_type(b_ / c) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit] +reveal_type(b_ / c16) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit] +reveal_type(b_ / c8) # E: numpy.complexfloating[numpy.typing._32Bit, numpy.typing._32Bit] + +reveal_type(b / b_) # E: numpy.floating[numpy.typing._64Bit] +reveal_type(b_ / b_) # E: numpy.floating[numpy.typing._64Bit] +reveal_type(i / b_) # E: numpy.floating[numpy.typing._64Bit] +reveal_type(i8 / b_) # E: numpy.floating[numpy.typing._64Bit] +reveal_type(i4 / b_) # E: numpy.floating[numpy.typing._64Bit] +reveal_type(u8 / b_) # E: numpy.floating[numpy.typing._64Bit] +reveal_type(u4 / b_) # E: numpy.floating[numpy.typing._64Bit] +reveal_type(f / b_) # E: numpy.floating[numpy.typing._64Bit] +reveal_type(f8 / b_) # E: numpy.floating[numpy.typing._64Bit] +reveal_type(f4 / b_) # E: numpy.floating[numpy.typing._32Bit] +reveal_type(c / b_) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit] +reveal_type(c16 / b_) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit] +reveal_type(c8 / b_) # E: numpy.complexfloating[numpy.typing._32Bit, numpy.typing._32Bit] + +# Complex + +reveal_type(c16 + c16) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit] +reveal_type(c16 + f8) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit] +reveal_type(c16 + i8) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit] +reveal_type(c16 + c8) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit] +reveal_type(c16 + f4) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit] +reveal_type(c16 + i4) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit] +reveal_type(c16 + b_) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit] +reveal_type(c16 + b) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit] +reveal_type(c16 + c) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit] +reveal_type(c16 + f) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit] +reveal_type(c16 + i) # E: numpy.complexfloating[Any, Any] +reveal_type(c16 + AR) # E: Any + +reveal_type(c16 + c16) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit] +reveal_type(f8 + c16) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit] +reveal_type(i8 + c16) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit] +reveal_type(c8 + c16) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit] +reveal_type(f4 + c16) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit] +reveal_type(i4 + c16) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit] +reveal_type(b_ + c16) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit] +reveal_type(b + c16) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit] +reveal_type(c + c16) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit] +reveal_type(f + c16) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit] +reveal_type(i + c16) # E: numpy.complexfloating[Any, Any] +reveal_type(AR + c16) # E: Any + +reveal_type(c8 + c16) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit] +reveal_type(c8 + f8) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit] +reveal_type(c8 + i8) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit] +reveal_type(c8 + c8) # E: numpy.complexfloating[numpy.typing._32Bit, numpy.typing._32Bit] +reveal_type(c8 + f4) # E: numpy.complexfloating[numpy.typing._32Bit, numpy.typing._32Bit] +reveal_type(c8 + i4) # E: numpy.complexfloating[numpy.typing._32Bit, numpy.typing._32Bit] +reveal_type(c8 + b_) # E: numpy.complexfloating[numpy.typing._32Bit, numpy.typing._32Bit] +reveal_type(c8 + b) # E: numpy.complexfloating[numpy.typing._32Bit, numpy.typing._32Bit] +reveal_type(c8 + c) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit] +reveal_type(c8 + f) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit] +reveal_type(c8 + i) # E: numpy.complexfloating[Any, Any] +reveal_type(c8 + AR) # E: Any + +reveal_type(c16 + c8) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit] +reveal_type(f8 + c8) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit] +reveal_type(i8 + c8) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit] +reveal_type(c8 + c8) # E: numpy.complexfloating[numpy.typing._32Bit, numpy.typing._32Bit] +reveal_type(f4 + c8) # E: numpy.complexfloating[numpy.typing._32Bit, numpy.typing._32Bit] +reveal_type(i4 + c8) # E: numpy.complexfloating[numpy.typing._32Bit, numpy.typing._32Bit] +reveal_type(b_ + c8) # E: numpy.complexfloating[numpy.typing._32Bit, numpy.typing._32Bit] +reveal_type(b + c8) # E: numpy.complexfloating[numpy.typing._32Bit, numpy.typing._32Bit] +reveal_type(c + c8) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit] +reveal_type(f + c8) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit] +reveal_type(i + c8) # E: numpy.complexfloating[Any, Any] +reveal_type(AR + c8) # E: Any + +# Float + +reveal_type(f8 + f8) # E: numpy.floating[numpy.typing._64Bit] +reveal_type(f8 + i8) # E: numpy.floating[numpy.typing._64Bit] +reveal_type(f8 + f4) # E: numpy.floating[numpy.typing._64Bit] +reveal_type(f8 + i4) # E: numpy.floating[numpy.typing._64Bit] +reveal_type(f8 + b_) # E: numpy.floating[numpy.typing._64Bit] +reveal_type(f8 + b) # E: numpy.floating[numpy.typing._64Bit] +reveal_type(f8 + c) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit] +reveal_type(f8 + f) # E: numpy.floating[numpy.typing._64Bit] +reveal_type(f8 + i) # E: numpy.floating[Any] +reveal_type(f8 + AR) # E: Any + +reveal_type(f8 + f8) # E: numpy.floating[numpy.typing._64Bit] +reveal_type(i8 + f8) # E: numpy.floating[numpy.typing._64Bit] +reveal_type(f4 + f8) # E: numpy.floating[numpy.typing._64Bit] +reveal_type(i4 + f8) # E: numpy.floating[numpy.typing._64Bit] +reveal_type(b_ + f8) # E: numpy.floating[numpy.typing._64Bit] +reveal_type(b + f8) # E: numpy.floating[numpy.typing._64Bit] +reveal_type(c + f8) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit] +reveal_type(f + f8) # E: numpy.floating[numpy.typing._64Bit] +reveal_type(i + f8) # E: numpy.floating[Any] +reveal_type(AR + f8) # E: Any + +reveal_type(f4 + f8) # E: numpy.floating[numpy.typing._64Bit] +reveal_type(f4 + i8) # E: numpy.floating[numpy.typing._64Bit] +reveal_type(f4 + f4) # E: numpy.floating[numpy.typing._32Bit] +reveal_type(f4 + i4) # E: numpy.floating[numpy.typing._32Bit] +reveal_type(f4 + b_) # E: numpy.floating[numpy.typing._32Bit] +reveal_type(f4 + b) # E: numpy.floating[numpy.typing._32Bit] +reveal_type(f4 + c) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit] +reveal_type(f4 + f) # E: numpy.floating[numpy.typing._64Bit] +reveal_type(f4 + i) # E: numpy.floating[Any] +reveal_type(f4 + AR) # E: Any + +reveal_type(f8 + f4) # E: numpy.floating[numpy.typing._64Bit] +reveal_type(i8 + f4) # E: numpy.floating[numpy.typing._64Bit] +reveal_type(f4 + f4) # E: umpy.floating[numpy.typing._32Bit] +reveal_type(i4 + f4) # E: umpy.floating[numpy.typing._32Bit] +reveal_type(b_ + f4) # E: umpy.floating[numpy.typing._32Bit] +reveal_type(b + f4) # E: umpy.floating[numpy.typing._32Bit] +reveal_type(c + f4) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit] +reveal_type(f + f4) # E: numpy.floating[numpy.typing._64Bit] +reveal_type(i + f4) # E: numpy.floating[Any] +reveal_type(AR + f4) # E: Any + +# Int + +reveal_type(i8 + i8) # E: numpy.signedinteger[numpy.typing._64Bit] +reveal_type(i8 + u8) # E: Union[numpy.signedinteger[Any], numpy.floating[numpy.typing._64Bit]] +reveal_type(i8 + i4) # E: numpy.signedinteger[numpy.typing._64Bit] +reveal_type(i8 + u4) # E: Union[numpy.signedinteger[Any], numpy.floating[numpy.typing._64Bit]] +reveal_type(i8 + b_) # E: numpy.signedinteger[numpy.typing._64Bit] +reveal_type(i8 + b) # E: numpy.signedinteger[numpy.typing._64Bit] +reveal_type(i8 + c) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit] +reveal_type(i8 + f) # E: numpy.floating[numpy.typing._64Bit] +reveal_type(i8 + i) # E: numpy.signedinteger[Any] +reveal_type(i8 + AR) # E: Any + +reveal_type(u8 + u8) # E: numpy.unsignedinteger[numpy.typing._64Bit] +reveal_type(u8 + i4) # E: Union[numpy.signedinteger[Any], numpy.floating[numpy.typing._64Bit]] +reveal_type(u8 + u4) # E: numpy.unsignedinteger[numpy.typing._64Bit] +reveal_type(u8 + b_) # E: numpy.unsignedinteger[numpy.typing._64Bit] +reveal_type(u8 + b) # E: numpy.unsignedinteger[numpy.typing._64Bit] +reveal_type(u8 + c) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit] +reveal_type(u8 + f) # E: numpy.floating[numpy.typing._64Bit] +reveal_type(u8 + i) # E: Union[numpy.signedinteger[Any], numpy.floating[numpy.typing._64Bit]] +reveal_type(u8 + AR) # E: Any + +reveal_type(i8 + i8) # E: numpy.signedinteger[numpy.typing._64Bit] +reveal_type(u8 + i8) # E: Union[numpy.signedinteger[Any], numpy.floating[numpy.typing._64Bit]] +reveal_type(i4 + i8) # E: numpy.signedinteger[numpy.typing._64Bit] +reveal_type(u4 + i8) # E: Union[numpy.signedinteger[Any], numpy.floating[numpy.typing._64Bit]] +reveal_type(b_ + i8) # E: numpy.signedinteger[numpy.typing._64Bit] +reveal_type(b + i8) # E: numpy.signedinteger[numpy.typing._64Bit] +reveal_type(c + i8) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit] +reveal_type(f + i8) # E: numpy.floating[numpy.typing._64Bit] +reveal_type(i + i8) # E: numpy.signedinteger[Any] +reveal_type(AR + i8) # E: Any + +reveal_type(u8 + u8) # E: numpy.unsignedinteger[numpy.typing._64Bit] +reveal_type(i4 + u8) # E: Union[numpy.signedinteger[Any], numpy.floating[numpy.typing._64Bit]] +reveal_type(u4 + u8) # E: numpy.unsignedinteger[numpy.typing._64Bit] +reveal_type(b_ + u8) # E: numpy.unsignedinteger[numpy.typing._64Bit] +reveal_type(b + u8) # E: numpy.unsignedinteger[numpy.typing._64Bit] +reveal_type(c + u8) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit] +reveal_type(f + u8) # E: numpy.floating[numpy.typing._64Bit] +reveal_type(i + u8) # E: Union[numpy.signedinteger[Any], numpy.floating[numpy.typing._64Bit]] +reveal_type(AR + u8) # E: Any + +reveal_type(i4 + i8) # E: numpy.signedinteger[numpy.typing._64Bit] +reveal_type(i4 + i4) # E: numpy.signedinteger[numpy.typing._32Bit] +reveal_type(i4 + i) # E: numpy.signedinteger[Any] +reveal_type(i4 + b_) # E: numpy.signedinteger[numpy.typing._32Bit] +reveal_type(i4 + b) # E: numpy.signedinteger[numpy.typing._32Bit] +reveal_type(i4 + AR) # E: Any + +reveal_type(u4 + i8) # E: Union[numpy.signedinteger[Any], numpy.floating[numpy.typing._64Bit]] +reveal_type(u4 + i4) # E: Union[numpy.signedinteger[Any], numpy.floating[numpy.typing._64Bit]] +reveal_type(u4 + u8) # E: numpy.unsignedinteger[numpy.typing._64Bit] +reveal_type(u4 + u4) # E: numpy.unsignedinteger[numpy.typing._32Bit] +reveal_type(u4 + i) # E: Union[numpy.signedinteger[Any], numpy.floating[numpy.typing._64Bit]] +reveal_type(u4 + b_) # E: numpy.unsignedinteger[numpy.typing._32Bit] +reveal_type(u4 + b) # E: numpy.unsignedinteger[numpy.typing._32Bit] +reveal_type(u4 + AR) # E: Any + +reveal_type(i8 + i4) # E: numpy.signedinteger[numpy.typing._64Bit] +reveal_type(i4 + i4) # E: numpy.signedinteger[numpy.typing._32Bit] +reveal_type(i + i4) # E: numpy.signedinteger[Any] +reveal_type(b_ + i4) # E: numpy.signedinteger[numpy.typing._32Bit] +reveal_type(b + i4) # E: numpy.signedinteger[numpy.typing._32Bit] +reveal_type(AR + i4) # E: Any + +reveal_type(i8 + u4) # E: Union[numpy.signedinteger[Any], numpy.floating[numpy.typing._64Bit]] +reveal_type(i4 + u4) # E: Union[numpy.signedinteger[Any], numpy.floating[numpy.typing._64Bit]] +reveal_type(u8 + u4) # E: numpy.unsignedinteger[numpy.typing._64Bit] +reveal_type(u4 + u4) # E: numpy.unsignedinteger[numpy.typing._32Bit] +reveal_type(b_ + u4) # E: numpy.unsignedinteger[numpy.typing._32Bit] +reveal_type(b + u4) # E: numpy.unsignedinteger[numpy.typing._32Bit] +reveal_type(i + u4) # E: Union[numpy.signedinteger[Any], numpy.floating[numpy.typing._64Bit]] +reveal_type(AR + u4) # E: Any diff --git a/venv/Lib/site-packages/numpy/typing/tests/data/reveal/array_constructors.py b/venv/Lib/site-packages/numpy/typing/tests/data/reveal/array_constructors.py new file mode 100644 index 0000000..1061747 --- /dev/null +++ b/venv/Lib/site-packages/numpy/typing/tests/data/reveal/array_constructors.py @@ -0,0 +1,102 @@ +from typing import List, Any +import numpy as np + +class SubClass(np.ndarray): ... + +i8: np.int64 + +A: np.ndarray +B: SubClass +C: List[int] + +def func(i: int, j: int, **kwargs: Any) -> SubClass: ... + +reveal_type(np.asarray(A)) # E: ndarray +reveal_type(np.asarray(B)) # E: ndarray +reveal_type(np.asarray(C)) # E: ndarray + +reveal_type(np.asanyarray(A)) # E: ndarray +reveal_type(np.asanyarray(B)) # E: SubClass +reveal_type(np.asanyarray(B, dtype=int)) # E: ndarray +reveal_type(np.asanyarray(C)) # E: ndarray + +reveal_type(np.ascontiguousarray(A)) # E: ndarray +reveal_type(np.ascontiguousarray(B)) # E: ndarray +reveal_type(np.ascontiguousarray(C)) # E: ndarray + +reveal_type(np.asfortranarray(A)) # E: ndarray +reveal_type(np.asfortranarray(B)) # E: ndarray +reveal_type(np.asfortranarray(C)) # E: ndarray + +reveal_type(np.require(A)) # E: ndarray +reveal_type(np.require(B)) # E: SubClass +reveal_type(np.require(B, requirements=None)) # E: SubClass +reveal_type(np.require(B, dtype=int)) # E: ndarray +reveal_type(np.require(B, requirements="E")) # E: ndarray +reveal_type(np.require(B, requirements=["ENSUREARRAY"])) # E: ndarray +reveal_type(np.require(B, requirements={"F", "E"})) # E: ndarray +reveal_type(np.require(B, requirements=["C", "OWNDATA"])) # E: SubClass +reveal_type(np.require(B, requirements="W")) # E: SubClass +reveal_type(np.require(B, requirements="A")) # E: SubClass +reveal_type(np.require(C)) # E: ndarray + +reveal_type(np.linspace(0, 10)) # E: numpy.ndarray +reveal_type(np.linspace(0, 10, retstep=True)) # E: Tuple[numpy.ndarray, numpy.inexact[Any]] +reveal_type(np.logspace(0, 10)) # E: numpy.ndarray +reveal_type(np.geomspace(1, 10)) # E: numpy.ndarray + +reveal_type(np.zeros_like(A)) # E: numpy.ndarray +reveal_type(np.zeros_like(C)) # E: numpy.ndarray +reveal_type(np.zeros_like(B)) # E: SubClass +reveal_type(np.zeros_like(B, dtype=np.int64)) # E: numpy.ndarray + +reveal_type(np.ones_like(A)) # E: numpy.ndarray +reveal_type(np.ones_like(C)) # E: numpy.ndarray +reveal_type(np.ones_like(B)) # E: SubClass +reveal_type(np.ones_like(B, dtype=np.int64)) # E: numpy.ndarray + +reveal_type(np.empty_like(A)) # E: numpy.ndarray +reveal_type(np.empty_like(C)) # E: numpy.ndarray +reveal_type(np.empty_like(B)) # E: SubClass +reveal_type(np.empty_like(B, dtype=np.int64)) # E: numpy.ndarray + +reveal_type(np.full_like(A, i8)) # E: numpy.ndarray +reveal_type(np.full_like(C, i8)) # E: numpy.ndarray +reveal_type(np.full_like(B, i8)) # E: SubClass +reveal_type(np.full_like(B, i8, dtype=np.int64)) # E: numpy.ndarray + +reveal_type(np.ones(1)) # E: numpy.ndarray +reveal_type(np.ones([1, 1, 1])) # E: numpy.ndarray + +reveal_type(np.full(1, i8)) # E: numpy.ndarray +reveal_type(np.full([1, 1, 1], i8)) # E: numpy.ndarray + +reveal_type(np.indices([1, 2, 3])) # E: numpy.ndarray +reveal_type(np.indices([1, 2, 3], sparse=True)) # E: tuple[numpy.ndarray] + +reveal_type(np.fromfunction(func, (3, 5))) # E: SubClass + +reveal_type(np.identity(10)) # E: numpy.ndarray + +reveal_type(np.atleast_1d(A)) # E: numpy.ndarray +reveal_type(np.atleast_1d(C)) # E: numpy.ndarray +reveal_type(np.atleast_1d(A, A)) # E: list[numpy.ndarray] +reveal_type(np.atleast_1d(A, C)) # E: list[numpy.ndarray] +reveal_type(np.atleast_1d(C, C)) # E: list[numpy.ndarray] + +reveal_type(np.atleast_2d(A)) # E: numpy.ndarray + +reveal_type(np.atleast_3d(A)) # E: numpy.ndarray + +reveal_type(np.vstack([A, A])) # E: numpy.ndarray +reveal_type(np.vstack([A, C])) # E: numpy.ndarray +reveal_type(np.vstack([C, C])) # E: numpy.ndarray + +reveal_type(np.hstack([A, A])) # E: numpy.ndarray + +reveal_type(np.stack([A, A])) # E: numpy.ndarray +reveal_type(np.stack([A, A], axis=0)) # E: numpy.ndarray +reveal_type(np.stack([A, A], out=B)) # E: SubClass + +reveal_type(np.block([[A, A], [A, A]])) # E: numpy.ndarray +reveal_type(np.block(C)) # E: numpy.ndarray diff --git a/venv/Lib/site-packages/numpy/typing/tests/data/reveal/bitwise_ops.py b/venv/Lib/site-packages/numpy/typing/tests/data/reveal/bitwise_ops.py new file mode 100644 index 0000000..cb9131a --- /dev/null +++ b/venv/Lib/site-packages/numpy/typing/tests/data/reveal/bitwise_ops.py @@ -0,0 +1,131 @@ +import numpy as np + +i8 = np.int64(1) +u8 = np.uint64(1) + +i4 = np.int32(1) +u4 = np.uint32(1) + +b_ = np.bool_(1) + +b = bool(1) +i = int(1) + +AR = np.array([0, 1, 2], dtype=np.int32) +AR.setflags(write=False) + + +reveal_type(i8 << i8) # E: numpy.signedinteger[numpy.typing._64Bit] +reveal_type(i8 >> i8) # E: numpy.signedinteger[numpy.typing._64Bit] +reveal_type(i8 | i8) # E: numpy.signedinteger[numpy.typing._64Bit] +reveal_type(i8 ^ i8) # E: numpy.signedinteger[numpy.typing._64Bit] +reveal_type(i8 & i8) # E: numpy.signedinteger[numpy.typing._64Bit] + +reveal_type(i8 << AR) # E: Any +reveal_type(i8 >> AR) # E: Any +reveal_type(i8 | AR) # E: Any +reveal_type(i8 ^ AR) # E: Any +reveal_type(i8 & AR) # E: Any + +reveal_type(i4 << i4) # E: numpy.signedinteger[numpy.typing._32Bit] +reveal_type(i4 >> i4) # E: numpy.signedinteger[numpy.typing._32Bit] +reveal_type(i4 | i4) # E: numpy.signedinteger[numpy.typing._32Bit] +reveal_type(i4 ^ i4) # E: numpy.signedinteger[numpy.typing._32Bit] +reveal_type(i4 & i4) # E: numpy.signedinteger[numpy.typing._32Bit] + +reveal_type(i8 << i4) # E: numpy.signedinteger[numpy.typing._64Bit] +reveal_type(i8 >> i4) # E: numpy.signedinteger[numpy.typing._64Bit] +reveal_type(i8 | i4) # E: numpy.signedinteger[numpy.typing._64Bit] +reveal_type(i8 ^ i4) # E: numpy.signedinteger[numpy.typing._64Bit] +reveal_type(i8 & i4) # E: numpy.signedinteger[numpy.typing._64Bit] + +reveal_type(i8 << i) # E: numpy.signedinteger[Any] +reveal_type(i8 >> i) # E: numpy.signedinteger[Any] +reveal_type(i8 | i) # E: numpy.signedinteger[Any] +reveal_type(i8 ^ i) # E: numpy.signedinteger[Any] +reveal_type(i8 & i) # E: numpy.signedinteger[Any] + +reveal_type(i8 << b_) # E: numpy.signedinteger[numpy.typing._64Bit] +reveal_type(i8 >> b_) # E: numpy.signedinteger[numpy.typing._64Bit] +reveal_type(i8 | b_) # E: numpy.signedinteger[numpy.typing._64Bit] +reveal_type(i8 ^ b_) # E: numpy.signedinteger[numpy.typing._64Bit] +reveal_type(i8 & b_) # E: numpy.signedinteger[numpy.typing._64Bit] + +reveal_type(i8 << b) # E: numpy.signedinteger[numpy.typing._64Bit] +reveal_type(i8 >> b) # E: numpy.signedinteger[numpy.typing._64Bit] +reveal_type(i8 | b) # E: numpy.signedinteger[numpy.typing._64Bit] +reveal_type(i8 ^ b) # E: numpy.signedinteger[numpy.typing._64Bit] +reveal_type(i8 & b) # E: numpy.signedinteger[numpy.typing._64Bit] + +reveal_type(u8 << u8) # E: numpy.unsignedinteger[numpy.typing._64Bit] +reveal_type(u8 >> u8) # E: numpy.unsignedinteger[numpy.typing._64Bit] +reveal_type(u8 | u8) # E: numpy.unsignedinteger[numpy.typing._64Bit] +reveal_type(u8 ^ u8) # E: numpy.unsignedinteger[numpy.typing._64Bit] +reveal_type(u8 & u8) # E: numpy.unsignedinteger[numpy.typing._64Bit] + +reveal_type(u8 << AR) # E: Any +reveal_type(u8 >> AR) # E: Any +reveal_type(u8 | AR) # E: Any +reveal_type(u8 ^ AR) # E: Any +reveal_type(u8 & AR) # E: Any + +reveal_type(u4 << u4) # E: numpy.unsignedinteger[numpy.typing._32Bit] +reveal_type(u4 >> u4) # E: numpy.unsignedinteger[numpy.typing._32Bit] +reveal_type(u4 | u4) # E: numpy.unsignedinteger[numpy.typing._32Bit] +reveal_type(u4 ^ u4) # E: numpy.unsignedinteger[numpy.typing._32Bit] +reveal_type(u4 & u4) # E: numpy.unsignedinteger[numpy.typing._32Bit] + +reveal_type(u4 << i4) # E: numpy.signedinteger[Any] +reveal_type(u4 >> i4) # E: numpy.signedinteger[Any] +reveal_type(u4 | i4) # E: numpy.signedinteger[Any] +reveal_type(u4 ^ i4) # E: numpy.signedinteger[Any] +reveal_type(u4 & i4) # E: numpy.signedinteger[Any] + +reveal_type(u4 << i) # E: numpy.signedinteger[Any] +reveal_type(u4 >> i) # E: numpy.signedinteger[Any] +reveal_type(u4 | i) # E: numpy.signedinteger[Any] +reveal_type(u4 ^ i) # E: numpy.signedinteger[Any] +reveal_type(u4 & i) # E: numpy.signedinteger[Any] + +reveal_type(u8 << b_) # E: numpy.unsignedinteger[numpy.typing._64Bit] +reveal_type(u8 >> b_) # E: numpy.unsignedinteger[numpy.typing._64Bit] +reveal_type(u8 | b_) # E: numpy.unsignedinteger[numpy.typing._64Bit] +reveal_type(u8 ^ b_) # E: numpy.unsignedinteger[numpy.typing._64Bit] +reveal_type(u8 & b_) # E: numpy.unsignedinteger[numpy.typing._64Bit] + +reveal_type(u8 << b) # E: numpy.unsignedinteger[numpy.typing._64Bit] +reveal_type(u8 >> b) # E: numpy.unsignedinteger[numpy.typing._64Bit] +reveal_type(u8 | b) # E: numpy.unsignedinteger[numpy.typing._64Bit] +reveal_type(u8 ^ b) # E: numpy.unsignedinteger[numpy.typing._64Bit] +reveal_type(u8 & b) # E: numpy.unsignedinteger[numpy.typing._64Bit] + +reveal_type(b_ << b_) # E: numpy.signedinteger[numpy.typing._8Bit] +reveal_type(b_ >> b_) # E: numpy.signedinteger[numpy.typing._8Bit] +reveal_type(b_ | b_) # E: numpy.bool_ +reveal_type(b_ ^ b_) # E: numpy.bool_ +reveal_type(b_ & b_) # E: numpy.bool_ + +reveal_type(b_ << AR) # E: Any +reveal_type(b_ >> AR) # E: Any +reveal_type(b_ | AR) # E: Any +reveal_type(b_ ^ AR) # E: Any +reveal_type(b_ & AR) # E: Any + +reveal_type(b_ << b) # E: numpy.signedinteger[numpy.typing._8Bit] +reveal_type(b_ >> b) # E: numpy.signedinteger[numpy.typing._8Bit] +reveal_type(b_ | b) # E: numpy.bool_ +reveal_type(b_ ^ b) # E: numpy.bool_ +reveal_type(b_ & b) # E: numpy.bool_ + +reveal_type(b_ << i) # E: numpy.signedinteger[Any] +reveal_type(b_ >> i) # E: numpy.signedinteger[Any] +reveal_type(b_ | i) # E: numpy.signedinteger[Any] +reveal_type(b_ ^ i) # E: numpy.signedinteger[Any] +reveal_type(b_ & i) # E: numpy.signedinteger[Any] + +reveal_type(~i8) # E: numpy.signedinteger[numpy.typing._64Bit] +reveal_type(~i4) # E: numpy.signedinteger[numpy.typing._32Bit] +reveal_type(~u8) # E: numpy.unsignedinteger[numpy.typing._64Bit] +reveal_type(~u4) # E: numpy.unsignedinteger[numpy.typing._32Bit] +reveal_type(~b_) # E: numpy.bool_ +reveal_type(~AR) # E: Any diff --git a/venv/Lib/site-packages/numpy/typing/tests/data/reveal/constants.py b/venv/Lib/site-packages/numpy/typing/tests/data/reveal/constants.py new file mode 100644 index 0000000..b2382e8 --- /dev/null +++ b/venv/Lib/site-packages/numpy/typing/tests/data/reveal/constants.py @@ -0,0 +1,52 @@ +import numpy as np + +reveal_type(np.Inf) # E: float +reveal_type(np.Infinity) # E: float +reveal_type(np.NAN) # E: float +reveal_type(np.NINF) # E: float +reveal_type(np.NZERO) # E: float +reveal_type(np.NaN) # E: float +reveal_type(np.PINF) # E: float +reveal_type(np.PZERO) # E: float +reveal_type(np.e) # E: float +reveal_type(np.euler_gamma) # E: float +reveal_type(np.inf) # E: float +reveal_type(np.infty) # E: float +reveal_type(np.nan) # E: float +reveal_type(np.pi) # E: float + +reveal_type(np.ALLOW_THREADS) # E: int +reveal_type(np.BUFSIZE) # E: int +reveal_type(np.CLIP) # E: int +reveal_type(np.ERR_CALL) # E: int +reveal_type(np.ERR_DEFAULT) # E: int +reveal_type(np.ERR_IGNORE) # E: int +reveal_type(np.ERR_LOG) # E: int +reveal_type(np.ERR_PRINT) # E: int +reveal_type(np.ERR_RAISE) # E: int +reveal_type(np.ERR_WARN) # E: int +reveal_type(np.FLOATING_POINT_SUPPORT) # E: int +reveal_type(np.FPE_DIVIDEBYZERO) # E: int +reveal_type(np.FPE_INVALID) # E: int +reveal_type(np.FPE_OVERFLOW) # E: int +reveal_type(np.FPE_UNDERFLOW) # E: int +reveal_type(np.MAXDIMS) # E: int +reveal_type(np.MAY_SHARE_BOUNDS) # E: int +reveal_type(np.MAY_SHARE_EXACT) # E: int +reveal_type(np.RAISE) # E: int +reveal_type(np.SHIFT_DIVIDEBYZERO) # E: int +reveal_type(np.SHIFT_INVALID) # E: int +reveal_type(np.SHIFT_OVERFLOW) # E: int +reveal_type(np.SHIFT_UNDERFLOW) # E: int +reveal_type(np.UFUNC_BUFSIZE_DEFAULT) # E: int +reveal_type(np.WRAP) # E: int +reveal_type(np.tracemalloc_domain) # E: int + +reveal_type(np.little_endian) # E: bool +reveal_type(np.True_) # E: numpy.bool_ +reveal_type(np.False_) # E: numpy.bool_ + +reveal_type(np.UFUNC_PYVALS_NAME) # E: str + +reveal_type(np.sctypeDict) # E: dict +reveal_type(np.sctypes) # E: TypedDict diff --git a/venv/Lib/site-packages/numpy/typing/tests/data/reveal/dtype.py b/venv/Lib/site-packages/numpy/typing/tests/data/reveal/dtype.py new file mode 100644 index 0000000..83a7695 --- /dev/null +++ b/venv/Lib/site-packages/numpy/typing/tests/data/reveal/dtype.py @@ -0,0 +1,52 @@ +import numpy as np + +dtype_obj: np.dtype[np.str_] +void_dtype_obj: np.dtype[np.void] + +reveal_type(np.dtype(np.float64)) # E: numpy.dtype[numpy.floating[numpy.typing._64Bit]] +reveal_type(np.dtype(np.int64)) # E: numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]] + +# String aliases +reveal_type(np.dtype("float64")) # E: numpy.dtype[numpy.floating[numpy.typing._64Bit]] +reveal_type(np.dtype("float32")) # E: numpy.dtype[numpy.floating[numpy.typing._32Bit]] +reveal_type(np.dtype("int64")) # E: numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]] +reveal_type(np.dtype("int32")) # E: numpy.dtype[numpy.signedinteger[numpy.typing._32Bit]] +reveal_type(np.dtype("bool")) # E: numpy.dtype[numpy.bool_] +reveal_type(np.dtype("bytes")) # E: numpy.dtype[numpy.bytes_] +reveal_type(np.dtype("str")) # E: numpy.dtype[numpy.str_] + +# Python types +reveal_type(np.dtype(complex)) # E: numpy.dtype[numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit]] +reveal_type(np.dtype(float)) # E: numpy.dtype[numpy.floating[numpy.typing._64Bit]] +reveal_type(np.dtype(int)) # E: numpy.dtype +reveal_type(np.dtype(bool)) # E: numpy.dtype[numpy.bool_] +reveal_type(np.dtype(str)) # E: numpy.dtype[numpy.str_] +reveal_type(np.dtype(bytes)) # E: numpy.dtype[numpy.bytes_] + +# Special case for None +reveal_type(np.dtype(None)) # E: numpy.dtype[numpy.floating[numpy.typing._64Bit]] + +# Dtypes of dtypes +reveal_type(np.dtype(np.dtype(np.float64))) # E: numpy.dtype[numpy.floating[numpy.typing._64Bit]] + +# Parameterized dtypes +reveal_type(np.dtype("S8")) # E: numpy.dtype + +# Void +reveal_type(np.dtype(("U", 10))) # E: numpy.dtype[numpy.void] + +reveal_type(dtype_obj.name) # E: str +reveal_type(dtype_obj.names) # E: Union[builtins.tuple[builtins.str], None] + +reveal_type(dtype_obj * 0) # E: None +reveal_type(dtype_obj * 1) # E: numpy.dtype[numpy.str_] +reveal_type(dtype_obj * 2) # E: numpy.dtype[numpy.void] + +reveal_type(0 * dtype_obj) # E: Any +reveal_type(1 * dtype_obj) # E: Any +reveal_type(2 * dtype_obj) # E: Any + +reveal_type(void_dtype_obj["f0"]) # E: numpy.dtype[Any] +reveal_type(void_dtype_obj[0]) # E: numpy.dtype[Any] +reveal_type(void_dtype_obj[["f0", "f1"]]) # E: numpy.dtype[numpy.void] +reveal_type(void_dtype_obj[["f0"]]) # E: numpy.dtype[numpy.void] diff --git a/venv/Lib/site-packages/numpy/typing/tests/data/reveal/flatiter.py b/venv/Lib/site-packages/numpy/typing/tests/data/reveal/flatiter.py new file mode 100644 index 0000000..56cdc7a --- /dev/null +++ b/venv/Lib/site-packages/numpy/typing/tests/data/reveal/flatiter.py @@ -0,0 +1,14 @@ +import numpy as np + +a: "np.flatiter[np.ndarray]" + +reveal_type(a.base) # E: numpy.ndarray* +reveal_type(a.copy()) # E: numpy.ndarray* +reveal_type(a.coords) # E: tuple[builtins.int] +reveal_type(a.index) # E: int +reveal_type(iter(a)) # E: Iterator[numpy.generic*] +reveal_type(next(a)) # E: numpy.generic +reveal_type(a[0]) # E: numpy.generic +reveal_type(a[[0, 1, 2]]) # E: numpy.ndarray* +reveal_type(a[...]) # E: numpy.ndarray* +reveal_type(a[:]) # E: numpy.ndarray* diff --git a/venv/Lib/site-packages/numpy/typing/tests/data/reveal/fromnumeric.py b/venv/Lib/site-packages/numpy/typing/tests/data/reveal/fromnumeric.py new file mode 100644 index 0000000..75865c2 --- /dev/null +++ b/venv/Lib/site-packages/numpy/typing/tests/data/reveal/fromnumeric.py @@ -0,0 +1,278 @@ +"""Tests for :mod:`numpy.core.fromnumeric`.""" + +import numpy as np + +A = np.array(True, ndmin=2, dtype=bool) +B = np.array(1.0, ndmin=2, dtype=np.float32) +A.setflags(write=False) +B.setflags(write=False) + +a = np.bool_(True) +b = np.float32(1.0) +c = 1.0 +d = np.array(1.0, dtype=np.float32) # writeable + +reveal_type(np.take(a, 0)) # E: numpy.bool_ +reveal_type(np.take(b, 0)) # E: numpy.floating[numpy.typing._32Bit] +reveal_type( + np.take(c, 0) # E: Union[numpy.generic, datetime.datetime, datetime.timedelta] +) +reveal_type( + np.take(A, 0) # E: Union[numpy.generic, datetime.datetime, datetime.timedelta] +) +reveal_type( + np.take(B, 0) # E: Union[numpy.generic, datetime.datetime, datetime.timedelta] +) +reveal_type( + np.take( # E: Union[Union[numpy.generic, datetime.datetime, datetime.timedelta], numpy.ndarray] + A, [0] + ) +) +reveal_type( + np.take( # E: Union[Union[numpy.generic, datetime.datetime, datetime.timedelta], numpy.ndarray] + B, [0] + ) +) + +reveal_type(np.reshape(a, 1)) # E: numpy.ndarray +reveal_type(np.reshape(b, 1)) # E: numpy.ndarray +reveal_type(np.reshape(c, 1)) # E: numpy.ndarray +reveal_type(np.reshape(A, 1)) # E: numpy.ndarray +reveal_type(np.reshape(B, 1)) # E: numpy.ndarray + +reveal_type(np.choose(a, [True, True])) # E: numpy.bool_ +reveal_type(np.choose(A, [True, True])) # E: numpy.ndarray + +reveal_type(np.repeat(a, 1)) # E: numpy.ndarray +reveal_type(np.repeat(b, 1)) # E: numpy.ndarray +reveal_type(np.repeat(c, 1)) # E: numpy.ndarray +reveal_type(np.repeat(A, 1)) # E: numpy.ndarray +reveal_type(np.repeat(B, 1)) # E: numpy.ndarray + +# TODO: Add tests for np.put() + +reveal_type(np.swapaxes(A, 0, 0)) # E: numpy.ndarray +reveal_type(np.swapaxes(B, 0, 0)) # E: numpy.ndarray + +reveal_type(np.transpose(a)) # E: numpy.ndarray +reveal_type(np.transpose(b)) # E: numpy.ndarray +reveal_type(np.transpose(c)) # E: numpy.ndarray +reveal_type(np.transpose(A)) # E: numpy.ndarray +reveal_type(np.transpose(B)) # E: numpy.ndarray + +reveal_type(np.partition(a, 0, axis=None)) # E: numpy.ndarray +reveal_type(np.partition(b, 0, axis=None)) # E: numpy.ndarray +reveal_type(np.partition(c, 0, axis=None)) # E: numpy.ndarray +reveal_type(np.partition(A, 0)) # E: numpy.ndarray +reveal_type(np.partition(B, 0)) # E: numpy.ndarray + +reveal_type(np.argpartition(a, 0)) # E: numpy.integer[Any] +reveal_type(np.argpartition(b, 0)) # E: numpy.integer[Any] +reveal_type(np.argpartition(c, 0)) # E: numpy.ndarray +reveal_type(np.argpartition(A, 0)) # E: numpy.ndarray +reveal_type(np.argpartition(B, 0)) # E: numpy.ndarray + +reveal_type(np.sort(A, 0)) # E: numpy.ndarray +reveal_type(np.sort(B, 0)) # E: numpy.ndarray + +reveal_type(np.argsort(A, 0)) # E: numpy.ndarray +reveal_type(np.argsort(B, 0)) # E: numpy.ndarray + +reveal_type(np.argmax(A)) # E: numpy.integer[Any] +reveal_type(np.argmax(B)) # E: numpy.integer[Any] +reveal_type(np.argmax(A, axis=0)) # E: Union[numpy.integer[Any], numpy.ndarray] +reveal_type(np.argmax(B, axis=0)) # E: Union[numpy.integer[Any], numpy.ndarray] + +reveal_type(np.argmin(A)) # E: numpy.integer[Any] +reveal_type(np.argmin(B)) # E: numpy.integer[Any] +reveal_type(np.argmin(A, axis=0)) # E: Union[numpy.integer[Any], numpy.ndarray] +reveal_type(np.argmin(B, axis=0)) # E: Union[numpy.integer[Any], numpy.ndarray] + +reveal_type(np.searchsorted(A[0], 0)) # E: numpy.integer[Any] +reveal_type(np.searchsorted(B[0], 0)) # E: numpy.integer[Any] +reveal_type(np.searchsorted(A[0], [0])) # E: numpy.ndarray +reveal_type(np.searchsorted(B[0], [0])) # E: numpy.ndarray + +reveal_type(np.resize(a, (5, 5))) # E: numpy.ndarray +reveal_type(np.resize(b, (5, 5))) # E: numpy.ndarray +reveal_type(np.resize(c, (5, 5))) # E: numpy.ndarray +reveal_type(np.resize(A, (5, 5))) # E: numpy.ndarray +reveal_type(np.resize(B, (5, 5))) # E: numpy.ndarray + +reveal_type(np.squeeze(a)) # E: numpy.bool_ +reveal_type(np.squeeze(b)) # E: numpy.floating[numpy.typing._32Bit] +reveal_type(np.squeeze(c)) # E: numpy.ndarray +reveal_type(np.squeeze(A)) # E: numpy.ndarray +reveal_type(np.squeeze(B)) # E: numpy.ndarray + +reveal_type(np.diagonal(A)) # E: numpy.ndarray +reveal_type(np.diagonal(B)) # E: numpy.ndarray + +reveal_type(np.trace(A)) # E: Union[numpy.number[Any], numpy.ndarray] +reveal_type(np.trace(B)) # E: Union[numpy.number[Any], numpy.ndarray] + +reveal_type(np.ravel(a)) # E: numpy.ndarray +reveal_type(np.ravel(b)) # E: numpy.ndarray +reveal_type(np.ravel(c)) # E: numpy.ndarray +reveal_type(np.ravel(A)) # E: numpy.ndarray +reveal_type(np.ravel(B)) # E: numpy.ndarray + +reveal_type(np.nonzero(a)) # E: tuple[numpy.ndarray] +reveal_type(np.nonzero(b)) # E: tuple[numpy.ndarray] +reveal_type(np.nonzero(c)) # E: tuple[numpy.ndarray] +reveal_type(np.nonzero(A)) # E: tuple[numpy.ndarray] +reveal_type(np.nonzero(B)) # E: tuple[numpy.ndarray] + +reveal_type(np.shape(a)) # E: tuple[builtins.int] +reveal_type(np.shape(b)) # E: tuple[builtins.int] +reveal_type(np.shape(c)) # E: tuple[builtins.int] +reveal_type(np.shape(A)) # E: tuple[builtins.int] +reveal_type(np.shape(B)) # E: tuple[builtins.int] + +reveal_type(np.compress([True], a)) # E: numpy.ndarray +reveal_type(np.compress([True], b)) # E: numpy.ndarray +reveal_type(np.compress([True], c)) # E: numpy.ndarray +reveal_type(np.compress([True], A)) # E: numpy.ndarray +reveal_type(np.compress([True], B)) # E: numpy.ndarray + +reveal_type(np.clip(a, 0, 1.0)) # E: numpy.number[Any] +reveal_type(np.clip(b, -1, 1)) # E: numpy.floating[numpy.typing._32Bit] +reveal_type(np.clip(c, 0, 1)) # E: numpy.number[Any] +reveal_type(np.clip(A, 0, 1)) # E: Union[numpy.number[Any], numpy.ndarray] +reveal_type(np.clip(B, 0, 1)) # E: Union[numpy.number[Any], numpy.ndarray] + +reveal_type(np.sum(a)) # E: numpy.number[Any] +reveal_type(np.sum(b)) # E: numpy.floating[numpy.typing._32Bit] +reveal_type(np.sum(c)) # E: numpy.number[Any] +reveal_type(np.sum(A)) # E: numpy.number[Any] +reveal_type(np.sum(B)) # E: numpy.number[Any] +reveal_type(np.sum(A, axis=0)) # E: Union[numpy.number[Any], numpy.ndarray] +reveal_type(np.sum(B, axis=0)) # E: Union[numpy.number[Any], numpy.ndarray] + +reveal_type(np.all(a)) # E: numpy.bool_ +reveal_type(np.all(b)) # E: numpy.bool_ +reveal_type(np.all(c)) # E: numpy.bool_ +reveal_type(np.all(A)) # E: numpy.bool_ +reveal_type(np.all(B)) # E: numpy.bool_ +reveal_type(np.all(A, axis=0)) # E: Union[numpy.bool_, numpy.ndarray] +reveal_type(np.all(B, axis=0)) # E: Union[numpy.bool_, numpy.ndarray] +reveal_type(np.all(A, keepdims=True)) # E: Union[numpy.bool_, numpy.ndarray] +reveal_type(np.all(B, keepdims=True)) # E: Union[numpy.bool_, numpy.ndarray] + +reveal_type(np.any(a)) # E: numpy.bool_ +reveal_type(np.any(b)) # E: numpy.bool_ +reveal_type(np.any(c)) # E: numpy.bool_ +reveal_type(np.any(A)) # E: numpy.bool_ +reveal_type(np.any(B)) # E: numpy.bool_ +reveal_type(np.any(A, axis=0)) # E: Union[numpy.bool_, numpy.ndarray] +reveal_type(np.any(B, axis=0)) # E: Union[numpy.bool_, numpy.ndarray] +reveal_type(np.any(A, keepdims=True)) # E: Union[numpy.bool_, numpy.ndarray] +reveal_type(np.any(B, keepdims=True)) # E: Union[numpy.bool_, numpy.ndarray] + +reveal_type(np.cumsum(a)) # E: numpy.ndarray +reveal_type(np.cumsum(b)) # E: numpy.ndarray +reveal_type(np.cumsum(c)) # E: numpy.ndarray +reveal_type(np.cumsum(A)) # E: numpy.ndarray +reveal_type(np.cumsum(B)) # E: numpy.ndarray + +reveal_type(np.ptp(a)) # E: numpy.number[Any] +reveal_type(np.ptp(b)) # E: numpy.floating[numpy.typing._32Bit] +reveal_type(np.ptp(c)) # E: numpy.number[Any] +reveal_type(np.ptp(A)) # E: numpy.number[Any] +reveal_type(np.ptp(B)) # E: numpy.number[Any] +reveal_type(np.ptp(A, axis=0)) # E: Union[numpy.number[Any], numpy.ndarray] +reveal_type(np.ptp(B, axis=0)) # E: Union[numpy.number[Any], numpy.ndarray] +reveal_type(np.ptp(A, keepdims=True)) # E: Union[numpy.number[Any], numpy.ndarray] +reveal_type(np.ptp(B, keepdims=True)) # E: Union[numpy.number[Any], numpy.ndarray] + +reveal_type(np.amax(a)) # E: numpy.number[Any] +reveal_type(np.amax(b)) # E: numpy.floating[numpy.typing._32Bit] +reveal_type(np.amax(c)) # E: numpy.number[Any] +reveal_type(np.amax(A)) # E: numpy.number[Any] +reveal_type(np.amax(B)) # E: numpy.number[Any] +reveal_type(np.amax(A, axis=0)) # E: Union[numpy.number[Any], numpy.ndarray] +reveal_type(np.amax(B, axis=0)) # E: Union[numpy.number[Any], numpy.ndarray] +reveal_type(np.amax(A, keepdims=True)) # E: Union[numpy.number[Any], numpy.ndarray] +reveal_type(np.amax(B, keepdims=True)) # E: Union[numpy.number[Any], numpy.ndarray] + +reveal_type(np.amin(a)) # E: numpy.number[Any] +reveal_type(np.amin(b)) # E: numpy.floating[numpy.typing._32Bit] +reveal_type(np.amin(c)) # E: numpy.number[Any] +reveal_type(np.amin(A)) # E: numpy.number[Any] +reveal_type(np.amin(B)) # E: numpy.number[Any] +reveal_type(np.amin(A, axis=0)) # E: Union[numpy.number[Any], numpy.ndarray] +reveal_type(np.amin(B, axis=0)) # E: Union[numpy.number[Any], numpy.ndarray] +reveal_type(np.amin(A, keepdims=True)) # E: Union[numpy.number[Any], numpy.ndarray] +reveal_type(np.amin(B, keepdims=True)) # E: Union[numpy.number[Any], numpy.ndarray] + +reveal_type(np.prod(a)) # E: numpy.number[Any] +reveal_type(np.prod(b)) # E: numpy.floating[numpy.typing._32Bit] +reveal_type(np.prod(c)) # E: numpy.number[Any] +reveal_type(np.prod(A)) # E: numpy.number[Any] +reveal_type(np.prod(B)) # E: numpy.number[Any] +reveal_type(np.prod(A, axis=0)) # E: Union[numpy.number[Any], numpy.ndarray] +reveal_type(np.prod(B, axis=0)) # E: Union[numpy.number[Any], numpy.ndarray] +reveal_type(np.prod(A, keepdims=True)) # E: Union[numpy.number[Any], numpy.ndarray] +reveal_type(np.prod(B, keepdims=True)) # E: Union[numpy.number[Any], numpy.ndarray] +reveal_type(np.prod(b, out=d)) # E: numpy.ndarray +reveal_type(np.prod(B, out=d)) # E: numpy.ndarray + +reveal_type(np.cumprod(a)) # E: numpy.ndarray +reveal_type(np.cumprod(b)) # E: numpy.ndarray +reveal_type(np.cumprod(c)) # E: numpy.ndarray +reveal_type(np.cumprod(A)) # E: numpy.ndarray +reveal_type(np.cumprod(B)) # E: numpy.ndarray + +reveal_type(np.ndim(a)) # E: int +reveal_type(np.ndim(b)) # E: int +reveal_type(np.ndim(c)) # E: int +reveal_type(np.ndim(A)) # E: int +reveal_type(np.ndim(B)) # E: int + +reveal_type(np.size(a)) # E: int +reveal_type(np.size(b)) # E: int +reveal_type(np.size(c)) # E: int +reveal_type(np.size(A)) # E: int +reveal_type(np.size(B)) # E: int + +reveal_type(np.around(a)) # E: numpy.number[Any] +reveal_type(np.around(b)) # E: numpy.floating[numpy.typing._32Bit] +reveal_type(np.around(c)) # E: numpy.number[Any] +reveal_type(np.around(A)) # E: numpy.ndarray +reveal_type(np.around(B)) # E: numpy.ndarray + +reveal_type(np.mean(a)) # E: numpy.number[Any] +reveal_type(np.mean(b)) # E: numpy.number[Any] +reveal_type(np.mean(c)) # E: numpy.number[Any] +reveal_type(np.mean(A)) # E: numpy.number[Any] +reveal_type(np.mean(B)) # E: numpy.number[Any] +reveal_type(np.mean(A, axis=0)) # E: Union[numpy.number[Any], numpy.ndarray] +reveal_type(np.mean(B, axis=0)) # E: Union[numpy.number[Any], numpy.ndarray] +reveal_type(np.mean(A, keepdims=True)) # E: Union[numpy.number[Any], numpy.ndarray] +reveal_type(np.mean(B, keepdims=True)) # E: Union[numpy.number[Any], numpy.ndarray] +reveal_type(np.mean(b, out=d)) # E: numpy.ndarray +reveal_type(np.mean(B, out=d)) # E: numpy.ndarray + +reveal_type(np.std(a)) # E: numpy.number[Any] +reveal_type(np.std(b)) # E: numpy.number[Any] +reveal_type(np.std(c)) # E: numpy.number[Any] +reveal_type(np.std(A)) # E: numpy.number[Any] +reveal_type(np.std(B)) # E: numpy.number[Any] +reveal_type(np.std(A, axis=0)) # E: Union[numpy.number[Any], numpy.ndarray] +reveal_type(np.std(B, axis=0)) # E: Union[numpy.number[Any], numpy.ndarray] +reveal_type(np.std(A, keepdims=True)) # E: Union[numpy.number[Any], numpy.ndarray] +reveal_type(np.std(B, keepdims=True)) # E: Union[numpy.number[Any], numpy.ndarray] +reveal_type(np.std(b, out=d)) # E: numpy.ndarray +reveal_type(np.std(B, out=d)) # E: numpy.ndarray + +reveal_type(np.var(a)) # E: numpy.number[Any] +reveal_type(np.var(b)) # E: numpy.number[Any] +reveal_type(np.var(c)) # E: numpy.number[Any] +reveal_type(np.var(A)) # E: numpy.number[Any] +reveal_type(np.var(B)) # E: numpy.number[Any] +reveal_type(np.var(A, axis=0)) # E: Union[numpy.number[Any], numpy.ndarray] +reveal_type(np.var(B, axis=0)) # E: Union[numpy.number[Any], numpy.ndarray] +reveal_type(np.var(A, keepdims=True)) # E: Union[numpy.number[Any], numpy.ndarray] +reveal_type(np.var(B, keepdims=True)) # E: Union[numpy.number[Any], numpy.ndarray] +reveal_type(np.var(b, out=d)) # E: numpy.ndarray +reveal_type(np.var(B, out=d)) # E: numpy.ndarray diff --git a/venv/Lib/site-packages/numpy/typing/tests/data/reveal/mod.py b/venv/Lib/site-packages/numpy/typing/tests/data/reveal/mod.py new file mode 100644 index 0000000..4292041 --- /dev/null +++ b/venv/Lib/site-packages/numpy/typing/tests/data/reveal/mod.py @@ -0,0 +1,149 @@ +import numpy as np + +f8 = np.float64() +i8 = np.int64() +u8 = np.uint64() + +f4 = np.float32() +i4 = np.int32() +u4 = np.uint32() + +td = np.timedelta64(0, "D") +b_ = np.bool_() + +b = bool() +f = float() +i = int() + +AR = np.array([1], dtype=np.bool_) +AR.setflags(write=False) + +AR2 = np.array([1], dtype=np.timedelta64) +AR2.setflags(write=False) + +# Time structures + +reveal_type(td % td) # E: numpy.timedelta64 +reveal_type(AR2 % td) # E: Any +reveal_type(td % AR2) # E: Any + +reveal_type(divmod(td, td)) # E: Tuple[numpy.signedinteger[numpy.typing._64Bit], numpy.timedelta64] +reveal_type(divmod(AR2, td)) # E: Tuple[Any, Any] +reveal_type(divmod(td, AR2)) # E: Tuple[Any, Any] + +# Bool + +reveal_type(b_ % b) # E: numpy.signedinteger[numpy.typing._8Bit] +reveal_type(b_ % i) # E: numpy.signedinteger[Any] +reveal_type(b_ % f) # E: numpy.floating[numpy.typing._64Bit] +reveal_type(b_ % b_) # E: numpy.signedinteger[numpy.typing._8Bit] +reveal_type(b_ % i8) # E: numpy.signedinteger[numpy.typing._64Bit] +reveal_type(b_ % u8) # E: numpy.unsignedinteger[numpy.typing._64Bit] +reveal_type(b_ % f8) # E: numpy.floating[numpy.typing._64Bit] +reveal_type(b_ % AR) # E: Any + +reveal_type(divmod(b_, b)) # E: Tuple[numpy.signedinteger[numpy.typing._8Bit], numpy.signedinteger[numpy.typing._8Bit]] +reveal_type(divmod(b_, i)) # E: Tuple[numpy.signedinteger[Any], numpy.signedinteger[Any]] +reveal_type(divmod(b_, f)) # E: Tuple[numpy.floating[numpy.typing._64Bit], numpy.floating[numpy.typing._64Bit]] +reveal_type(divmod(b_, b_)) # E: Tuple[numpy.signedinteger[numpy.typing._8Bit], numpy.signedinteger[numpy.typing._8Bit]] +reveal_type(divmod(b_, i8)) # E: Tuple[numpy.signedinteger[numpy.typing._64Bit], numpy.signedinteger[numpy.typing._64Bit]] +reveal_type(divmod(b_, u8)) # E: Tuple[numpy.unsignedinteger[numpy.typing._64Bit], numpy.unsignedinteger[numpy.typing._64Bit]] +reveal_type(divmod(b_, f8)) # E: Tuple[numpy.floating[numpy.typing._64Bit], numpy.floating[numpy.typing._64Bit]] +reveal_type(divmod(b_, AR)) # E: Tuple[Any, Any] + +reveal_type(b % b_) # E: numpy.signedinteger[numpy.typing._8Bit] +reveal_type(i % b_) # E: numpy.signedinteger[Any] +reveal_type(f % b_) # E: numpy.floating[numpy.typing._64Bit] +reveal_type(b_ % b_) # E: numpy.signedinteger[numpy.typing._8Bit] +reveal_type(i8 % b_) # E: numpy.signedinteger[numpy.typing._64Bit] +reveal_type(u8 % b_) # E: numpy.unsignedinteger[numpy.typing._64Bit] +reveal_type(f8 % b_) # E: numpy.floating[numpy.typing._64Bit] +reveal_type(AR % b_) # E: Any + +reveal_type(divmod(b, b_)) # E: Tuple[numpy.signedinteger[numpy.typing._8Bit], numpy.signedinteger[numpy.typing._8Bit]] +reveal_type(divmod(i, b_)) # E: Tuple[numpy.signedinteger[Any], numpy.signedinteger[Any]] +reveal_type(divmod(f, b_)) # E: Tuple[numpy.floating[numpy.typing._64Bit], numpy.floating[numpy.typing._64Bit]] +reveal_type(divmod(b_, b_)) # E: Tuple[numpy.signedinteger[numpy.typing._8Bit], numpy.signedinteger[numpy.typing._8Bit]] +reveal_type(divmod(i8, b_)) # E: Tuple[numpy.signedinteger[numpy.typing._64Bit], numpy.signedinteger[numpy.typing._64Bit]] +reveal_type(divmod(u8, b_)) # E: Tuple[numpy.unsignedinteger[numpy.typing._64Bit], numpy.unsignedinteger[numpy.typing._64Bit]] +reveal_type(divmod(f8, b_)) # E: Tuple[numpy.floating[numpy.typing._64Bit], numpy.floating[numpy.typing._64Bit]] +reveal_type(divmod(AR, b_)) # E: Tuple[Any, Any] + +# int + +reveal_type(i8 % b) # E: numpy.signedinteger[numpy.typing._64Bit] +reveal_type(i8 % i) # E: numpy.signedinteger[Any] +reveal_type(i8 % f) # E: numpy.floating[numpy.typing._64Bit] +reveal_type(i8 % i8) # E: numpy.signedinteger[numpy.typing._64Bit] +reveal_type(i8 % f8) # E: numpy.floating[numpy.typing._64Bit] +reveal_type(i4 % i8) # E: numpy.signedinteger[numpy.typing._64Bit] +reveal_type(i4 % f8) # E: numpy.floating[numpy.typing._64Bit] +reveal_type(i4 % i4) # E: numpy.signedinteger[numpy.typing._32Bit] +reveal_type(i4 % f4) # E: numpy.floating[numpy.typing._32Bit] +reveal_type(i8 % AR) # E: Any + +reveal_type(divmod(i8, b)) # E: Tuple[numpy.signedinteger[numpy.typing._64Bit], numpy.signedinteger[numpy.typing._64Bit]] +reveal_type(divmod(i8, i)) # E: Tuple[numpy.signedinteger[Any], numpy.signedinteger[Any]] +reveal_type(divmod(i8, f)) # E: Tuple[numpy.floating[numpy.typing._64Bit], numpy.floating[numpy.typing._64Bit]] +reveal_type(divmod(i8, i8)) # E: Tuple[numpy.signedinteger[numpy.typing._64Bit], numpy.signedinteger[numpy.typing._64Bit]] +reveal_type(divmod(i8, f8)) # E: Tuple[numpy.floating[numpy.typing._64Bit], numpy.floating[numpy.typing._64Bit]] +reveal_type(divmod(i8, i4)) # E: Tuple[numpy.signedinteger[numpy.typing._64Bit], numpy.signedinteger[numpy.typing._64Bit]] +reveal_type(divmod(i8, f4)) # E: Tuple[numpy.floating[numpy.typing._64Bit], numpy.floating[numpy.typing._64Bit]] +reveal_type(divmod(i4, i4)) # E: Tuple[numpy.signedinteger[numpy.typing._32Bit], numpy.signedinteger[numpy.typing._32Bit]] +reveal_type(divmod(i4, f4)) # E: Tuple[numpy.floating[numpy.typing._32Bit], numpy.floating[numpy.typing._32Bit]] +reveal_type(divmod(i8, AR)) # E: Tuple[Any, Any] + +reveal_type(b % i8) # E: numpy.signedinteger[numpy.typing._64Bit] +reveal_type(i % i8) # E: numpy.signedinteger[Any] +reveal_type(f % i8) # E: numpy.floating[numpy.typing._64Bit] +reveal_type(i8 % i8) # E: numpy.signedinteger[numpy.typing._64Bit] +reveal_type(f8 % i8) # E: numpy.floating[numpy.typing._64Bit] +reveal_type(i8 % i4) # E: numpy.signedinteger[numpy.typing._64Bit] +reveal_type(f8 % i4) # E: numpy.floating[numpy.typing._64Bit] +reveal_type(i4 % i4) # E: numpy.signedinteger[numpy.typing._32Bit] +reveal_type(f4 % i4) # E: numpy.floating[numpy.typing._32Bit] +reveal_type(AR % i8) # E: Any + +reveal_type(divmod(b, i8)) # E: Tuple[numpy.signedinteger[numpy.typing._64Bit], numpy.signedinteger[numpy.typing._64Bit]] +reveal_type(divmod(i, i8)) # E: Tuple[numpy.signedinteger[Any], numpy.signedinteger[Any]] +reveal_type(divmod(f, i8)) # E: Tuple[numpy.floating[numpy.typing._64Bit], numpy.floating[numpy.typing._64Bit]] +reveal_type(divmod(i8, i8)) # E: Tuple[numpy.signedinteger[numpy.typing._64Bit], numpy.signedinteger[numpy.typing._64Bit]] +reveal_type(divmod(f8, i8)) # E: Tuple[numpy.floating[numpy.typing._64Bit], numpy.floating[numpy.typing._64Bit]] +reveal_type(divmod(i4, i8)) # E: Tuple[numpy.signedinteger[numpy.typing._64Bit], numpy.signedinteger[numpy.typing._64Bit]] +reveal_type(divmod(f4, i8)) # E: Tuple[numpy.floating[numpy.typing._64Bit], numpy.floating[numpy.typing._64Bit]] +reveal_type(divmod(i4, i4)) # E: Tuple[numpy.signedinteger[numpy.typing._32Bit], numpy.signedinteger[numpy.typing._32Bit]] +reveal_type(divmod(f4, i4)) # E: Tuple[numpy.floating[numpy.typing._32Bit], numpy.floating[numpy.typing._32Bit]] +reveal_type(divmod(AR, i8)) # E: Tuple[Any, Any] + +# float + +reveal_type(f8 % b) # E: numpy.floating[numpy.typing._64Bit] +reveal_type(f8 % i) # E: numpy.floating[Any] +reveal_type(f8 % f) # E: numpy.floating[numpy.typing._64Bit] +reveal_type(i8 % f4) # E: numpy.floating[numpy.typing._64Bit] +reveal_type(f4 % f4) # E: numpy.floating[numpy.typing._32Bit] +reveal_type(f8 % AR) # E: Any + +reveal_type(divmod(f8, b)) # E: Tuple[numpy.floating[numpy.typing._64Bit], numpy.floating[numpy.typing._64Bit]] +reveal_type(divmod(f8, i)) # E: Tuple[numpy.floating[Any], numpy.floating[Any]] +reveal_type(divmod(f8, f)) # E: Tuple[numpy.floating[numpy.typing._64Bit], numpy.floating[numpy.typing._64Bit]] +reveal_type(divmod(f8, f8)) # E: Tuple[numpy.floating[numpy.typing._64Bit], numpy.floating[numpy.typing._64Bit]] +reveal_type(divmod(f8, f4)) # E: Tuple[numpy.floating[numpy.typing._64Bit], numpy.floating[numpy.typing._64Bit]] +reveal_type(divmod(f4, f4)) # E: Tuple[numpy.floating[numpy.typing._32Bit], numpy.floating[numpy.typing._32Bit]] +reveal_type(divmod(f8, AR)) # E: Tuple[Any, Any] + +reveal_type(b % f8) # E: numpy.floating[numpy.typing._64Bit] +reveal_type(i % f8) # E: numpy.floating[Any] +reveal_type(f % f8) # E: numpy.floating[numpy.typing._64Bit] +reveal_type(f8 % f8) # E: numpy.floating[numpy.typing._64Bit] +reveal_type(f8 % f8) # E: numpy.floating[numpy.typing._64Bit] +reveal_type(f4 % f4) # E: numpy.floating[numpy.typing._32Bit] +reveal_type(AR % f8) # E: Any + +reveal_type(divmod(b, f8)) # E: Tuple[numpy.floating[numpy.typing._64Bit], numpy.floating[numpy.typing._64Bit]] +reveal_type(divmod(i, f8)) # E: Tuple[numpy.floating[Any], numpy.floating[Any]] +reveal_type(divmod(f, f8)) # E: Tuple[numpy.floating[numpy.typing._64Bit], numpy.floating[numpy.typing._64Bit]] +reveal_type(divmod(f8, f8)) # E: Tuple[numpy.floating[numpy.typing._64Bit], numpy.floating[numpy.typing._64Bit]] +reveal_type(divmod(f4, f8)) # E: Tuple[numpy.floating[numpy.typing._64Bit], numpy.floating[numpy.typing._64Bit]] +reveal_type(divmod(f4, f4)) # E: Tuple[numpy.floating[numpy.typing._32Bit], numpy.floating[numpy.typing._32Bit]] +reveal_type(divmod(AR, f8)) # E: Tuple[Any, Any] diff --git a/venv/Lib/site-packages/numpy/typing/tests/data/reveal/modules.py b/venv/Lib/site-packages/numpy/typing/tests/data/reveal/modules.py new file mode 100644 index 0000000..00fca3e --- /dev/null +++ b/venv/Lib/site-packages/numpy/typing/tests/data/reveal/modules.py @@ -0,0 +1,47 @@ +import numpy as np +from numpy import f2py + +reveal_type(np) # E: ModuleType + +reveal_type(np.char) # E: ModuleType +reveal_type(np.ctypeslib) # E: ModuleType +reveal_type(np.emath) # E: ModuleType +reveal_type(np.fft) # E: ModuleType +reveal_type(np.lib) # E: ModuleType +reveal_type(np.linalg) # E: ModuleType +reveal_type(np.ma) # E: ModuleType +reveal_type(np.matrixlib) # E: ModuleType +reveal_type(np.polynomial) # E: ModuleType +reveal_type(np.random) # E: ModuleType +reveal_type(np.rec) # E: ModuleType +reveal_type(np.testing) # E: ModuleType +reveal_type(np.version) # E: ModuleType + +reveal_type(np.lib.format) # E: ModuleType +reveal_type(np.lib.mixins) # E: ModuleType +reveal_type(np.lib.scimath) # E: ModuleType +reveal_type(np.lib.stride_tricks) # E: ModuleType +reveal_type(np.ma.extras) # E: ModuleType +reveal_type(np.polynomial.chebyshev) # E: ModuleType +reveal_type(np.polynomial.hermite) # E: ModuleType +reveal_type(np.polynomial.hermite_e) # E: ModuleType +reveal_type(np.polynomial.laguerre) # E: ModuleType +reveal_type(np.polynomial.legendre) # E: ModuleType +reveal_type(np.polynomial.polynomial) # E: ModuleType + +# TODO: Remove when annotations have been added to `np.testing.assert_equal` +reveal_type(np.testing.assert_equal) # E: Any + +reveal_type(np.__path__) # E: list[builtins.str] +reveal_type(np.__version__) # E: str + +reveal_type(np.__all__) # E: list[builtins.str] +reveal_type(np.char.__all__) # E: list[builtins.str] +reveal_type(np.ctypeslib.__all__) # E: list[builtins.str] +reveal_type(np.emath.__all__) # E: list[builtins.str] +reveal_type(np.lib.__all__) # E: list[builtins.str] +reveal_type(np.ma.__all__) # E: list[builtins.str] +reveal_type(np.random.__all__) # E: list[builtins.str] +reveal_type(np.rec.__all__) # E: list[builtins.str] +reveal_type(np.testing.__all__) # E: list[builtins.str] +reveal_type(f2py.__all__) # E: list[builtins.str] diff --git a/venv/Lib/site-packages/numpy/typing/tests/data/reveal/nbit_base_example.py b/venv/Lib/site-packages/numpy/typing/tests/data/reveal/nbit_base_example.py new file mode 100644 index 0000000..0c4c53f --- /dev/null +++ b/venv/Lib/site-packages/numpy/typing/tests/data/reveal/nbit_base_example.py @@ -0,0 +1,18 @@ +from typing import TypeVar, Union +import numpy as np +import numpy.typing as npt + +T = TypeVar("T", bound=npt.NBitBase) + +def add(a: np.floating[T], b: np.integer[T]) -> np.floating[T]: + return a + b + +i8: np.int64 +i4: np.int32 +f8: np.float64 +f4: np.float32 + +reveal_type(add(f8, i8)) # E: numpy.floating[numpy.typing._64Bit] +reveal_type(add(f4, i8)) # E: numpy.floating[numpy.typing._64Bit] +reveal_type(add(f8, i4)) # E: numpy.floating[numpy.typing._64Bit] +reveal_type(add(f4, i4)) # E: numpy.floating[numpy.typing._32Bit] diff --git a/venv/Lib/site-packages/numpy/typing/tests/data/reveal/ndarray_conversion.py b/venv/Lib/site-packages/numpy/typing/tests/data/reveal/ndarray_conversion.py new file mode 100644 index 0000000..4ee637b --- /dev/null +++ b/venv/Lib/site-packages/numpy/typing/tests/data/reveal/ndarray_conversion.py @@ -0,0 +1,54 @@ +import numpy as np + +nd = np.array([[1, 2], [3, 4]]) + +# item +reveal_type(nd.item()) # E: Any +reveal_type(nd.item(1)) # E: Any +reveal_type(nd.item(0, 1)) # E: Any +reveal_type(nd.item((0, 1))) # E: Any + +# tolist +reveal_type(nd.tolist()) # E: Any + +# itemset does not return a value +# tostring is pretty simple +# tobytes is pretty simple +# tofile does not return a value +# dump does not return a value +# dumps is pretty simple + +# astype +reveal_type(nd.astype("float")) # E: numpy.ndarray +reveal_type(nd.astype(float)) # E: numpy.ndarray +reveal_type(nd.astype(float, "K")) # E: numpy.ndarray +reveal_type(nd.astype(float, "K", "unsafe")) # E: numpy.ndarray +reveal_type(nd.astype(float, "K", "unsafe", True)) # E: numpy.ndarray +reveal_type(nd.astype(float, "K", "unsafe", True, True)) # E: numpy.ndarray + +# byteswap +reveal_type(nd.byteswap()) # E: numpy.ndarray +reveal_type(nd.byteswap(True)) # E: numpy.ndarray + +# copy +reveal_type(nd.copy()) # E: numpy.ndarray +reveal_type(nd.copy("C")) # E: numpy.ndarray + +# view +class SubArray(np.ndarray): + pass + + +reveal_type(nd.view()) # E: numpy.ndarray +reveal_type(nd.view(np.int64)) # E: numpy.ndarray +# replace `Any` with `numpy.matrix` when `matrix` will be added to stubs +reveal_type(nd.view(np.int64, np.matrix)) # E: Any +reveal_type(nd.view(np.int64, SubArray)) # E: SubArray + +# getfield +reveal_type(nd.getfield("float")) # E: numpy.ndarray +reveal_type(nd.getfield(float)) # E: numpy.ndarray +reveal_type(nd.getfield(float, 8)) # E: numpy.ndarray + +# setflags does not return a value +# fill does not return a value diff --git a/venv/Lib/site-packages/numpy/typing/tests/data/reveal/ndarray_misc.py b/venv/Lib/site-packages/numpy/typing/tests/data/reveal/ndarray_misc.py new file mode 100644 index 0000000..826c8aa --- /dev/null +++ b/venv/Lib/site-packages/numpy/typing/tests/data/reveal/ndarray_misc.py @@ -0,0 +1,150 @@ +""" +Tests for miscellaneous (non-magic) ``np.ndarray``/``np.generic`` methods. + +More extensive tests are performed for the methods' +function-based counterpart in `../from_numeric.py`. + +""" + +import numpy as np + +class SubClass(np.ndarray): ... + +f8: np.float64 +A: np.ndarray +B: SubClass + +reveal_type(f8.all()) # E: numpy.bool_ +reveal_type(A.all()) # E: numpy.bool_ +reveal_type(A.all(axis=0)) # E: Union[numpy.bool_, numpy.ndarray] +reveal_type(A.all(keepdims=True)) # E: Union[numpy.bool_, numpy.ndarray] +reveal_type(A.all(out=B)) # E: SubClass + +reveal_type(f8.any()) # E: numpy.bool_ +reveal_type(A.any()) # E: numpy.bool_ +reveal_type(A.any(axis=0)) # E: Union[numpy.bool_, numpy.ndarray] +reveal_type(A.any(keepdims=True)) # E: Union[numpy.bool_, numpy.ndarray] +reveal_type(A.any(out=B)) # E: SubClass + +reveal_type(f8.argmax()) # E: numpy.signedinteger[Any] +reveal_type(A.argmax()) # E: numpy.signedinteger[Any] +reveal_type(A.argmax(axis=0)) # E: Union[numpy.signedinteger[Any], numpy.ndarray] +reveal_type(A.argmax(out=B)) # E: SubClass + +reveal_type(f8.argmin()) # E: numpy.signedinteger[Any] +reveal_type(A.argmin()) # E: numpy.signedinteger[Any] +reveal_type(A.argmin(axis=0)) # E: Union[numpy.signedinteger[Any], numpy.ndarray] +reveal_type(A.argmin(out=B)) # E: SubClass + +reveal_type(f8.argsort()) # E: numpy.ndarray +reveal_type(A.argsort()) # E: numpy.ndarray + +reveal_type(f8.astype(np.int64).choose([()])) # E: numpy.ndarray +reveal_type(A.choose([0])) # E: numpy.ndarray +reveal_type(A.choose([0], out=B)) # E: SubClass + +reveal_type(f8.clip(1)) # E: Union[numpy.number[Any], numpy.ndarray] +reveal_type(A.clip(1)) # E: Union[numpy.number[Any], numpy.ndarray] +reveal_type(A.clip(None, 1)) # E: Union[numpy.number[Any], numpy.ndarray] +reveal_type(A.clip(1, out=B)) # E: SubClass +reveal_type(A.clip(None, 1, out=B)) # E: SubClass + +reveal_type(f8.compress([0])) # E: numpy.ndarray +reveal_type(A.compress([0])) # E: numpy.ndarray +reveal_type(A.compress([0], out=B)) # E: SubClass + +reveal_type(f8.conj()) # E: numpy.floating[numpy.typing._64Bit] +reveal_type(A.conj()) # E: numpy.ndarray +reveal_type(B.conj()) # E: SubClass + +reveal_type(f8.conjugate()) # E: numpy.floating[numpy.typing._64Bit] +reveal_type(A.conjugate()) # E: numpy.ndarray +reveal_type(B.conjugate()) # E: SubClass + +reveal_type(f8.cumprod()) # E: numpy.ndarray +reveal_type(A.cumprod()) # E: numpy.ndarray +reveal_type(A.cumprod(out=B)) # E: SubClass + +reveal_type(f8.cumsum()) # E: numpy.ndarray +reveal_type(A.cumsum()) # E: numpy.ndarray +reveal_type(A.cumsum(out=B)) # E: SubClass + +reveal_type(f8.max()) # E: numpy.number[Any] +reveal_type(A.max()) # E: numpy.number[Any] +reveal_type(A.max(axis=0)) # E: Union[numpy.number[Any], numpy.ndarray] +reveal_type(A.max(keepdims=True)) # E: Union[numpy.number[Any], numpy.ndarray] +reveal_type(A.max(out=B)) # E: SubClass + +reveal_type(f8.mean()) # E: numpy.number[Any] +reveal_type(A.mean()) # E: numpy.number[Any] +reveal_type(A.mean(axis=0)) # E: Union[numpy.number[Any], numpy.ndarray] +reveal_type(A.mean(keepdims=True)) # E: Union[numpy.number[Any], numpy.ndarray] +reveal_type(A.mean(out=B)) # E: SubClass + +reveal_type(f8.min()) # E: numpy.number[Any] +reveal_type(A.min()) # E: numpy.number[Any] +reveal_type(A.min(axis=0)) # E: Union[numpy.number[Any], numpy.ndarray] +reveal_type(A.min(keepdims=True)) # E: Union[numpy.number[Any], numpy.ndarray] +reveal_type(A.min(out=B)) # E: SubClass + +reveal_type(f8.newbyteorder()) # E: numpy.floating[numpy.typing._64Bit] +reveal_type(A.newbyteorder()) # E: numpy.ndarray +reveal_type(B.newbyteorder('|')) # E: SubClass + +reveal_type(f8.prod()) # E: numpy.number[Any] +reveal_type(A.prod()) # E: numpy.number[Any] +reveal_type(A.prod(axis=0)) # E: Union[numpy.number[Any], numpy.ndarray] +reveal_type(A.prod(keepdims=True)) # E: Union[numpy.number[Any], numpy.ndarray] +reveal_type(A.prod(out=B)) # E: SubClass + +reveal_type(f8.ptp()) # E: numpy.number[Any] +reveal_type(A.ptp()) # E: numpy.number[Any] +reveal_type(A.ptp(axis=0)) # E: Union[numpy.number[Any], numpy.ndarray] +reveal_type(A.ptp(keepdims=True)) # E: Union[numpy.number[Any], numpy.ndarray] +reveal_type(A.ptp(out=B)) # E: SubClass + +reveal_type(f8.round()) # E: numpy.floating[numpy.typing._64Bit] +reveal_type(A.round()) # E: numpy.ndarray +reveal_type(A.round(out=B)) # E: SubClass + +reveal_type(f8.repeat(1)) # E: numpy.ndarray +reveal_type(A.repeat(1)) # E: numpy.ndarray +reveal_type(B.repeat(1)) # E: numpy.ndarray + +reveal_type(f8.std()) # E: numpy.number[Any] +reveal_type(A.std()) # E: numpy.number[Any] +reveal_type(A.std(axis=0)) # E: Union[numpy.number[Any], numpy.ndarray] +reveal_type(A.std(keepdims=True)) # E: Union[numpy.number[Any], numpy.ndarray] +reveal_type(A.std(out=B)) # E: SubClass + +reveal_type(f8.sum()) # E: numpy.number[Any] +reveal_type(A.sum()) # E: numpy.number[Any] +reveal_type(A.sum(axis=0)) # E: Union[numpy.number[Any], numpy.ndarray] +reveal_type(A.sum(keepdims=True)) # E: Union[numpy.number[Any], numpy.ndarray] +reveal_type(A.sum(out=B)) # E: SubClass + +reveal_type(f8.take(0)) # E: numpy.generic +reveal_type(A.take(0)) # E: numpy.generic +reveal_type(A.take([0])) # E: numpy.ndarray +reveal_type(A.take(0, out=B)) # E: SubClass +reveal_type(A.take([0], out=B)) # E: SubClass + +reveal_type(f8.var()) # E: numpy.number[Any] +reveal_type(A.var()) # E: numpy.number[Any] +reveal_type(A.var(axis=0)) # E: Union[numpy.number[Any], numpy.ndarray] +reveal_type(A.var(keepdims=True)) # E: Union[numpy.number[Any], numpy.ndarray] +reveal_type(A.var(out=B)) # E: SubClass + +reveal_type(A.argpartition([0])) # E: numpy.ndarray + +reveal_type(A.diagonal()) # E: numpy.ndarray + +reveal_type(A.dot(1)) # E: Union[numpy.number[Any], numpy.ndarray] +reveal_type(A.dot(1, out=B)) # E: SubClass + +reveal_type(A.nonzero()) # E: tuple[numpy.ndarray] + +reveal_type(A.searchsorted([1])) # E: numpy.ndarray + +reveal_type(A.trace()) # E: Union[numpy.number[Any], numpy.ndarray] +reveal_type(A.trace(out=B)) # E: SubClass diff --git a/venv/Lib/site-packages/numpy/typing/tests/data/reveal/ndarray_shape_manipulation.py b/venv/Lib/site-packages/numpy/typing/tests/data/reveal/ndarray_shape_manipulation.py new file mode 100644 index 0000000..a44e1cf --- /dev/null +++ b/venv/Lib/site-packages/numpy/typing/tests/data/reveal/ndarray_shape_manipulation.py @@ -0,0 +1,35 @@ +import numpy as np + +nd = np.array([[1, 2], [3, 4]]) + +# reshape +reveal_type(nd.reshape()) # E: numpy.ndarray +reveal_type(nd.reshape(4)) # E: numpy.ndarray +reveal_type(nd.reshape(2, 2)) # E: numpy.ndarray +reveal_type(nd.reshape((2, 2))) # E: numpy.ndarray + +reveal_type(nd.reshape((2, 2), order="C")) # E: numpy.ndarray +reveal_type(nd.reshape(4, order="C")) # E: numpy.ndarray + +# resize does not return a value + +# transpose +reveal_type(nd.transpose()) # E: numpy.ndarray +reveal_type(nd.transpose(1, 0)) # E: numpy.ndarray +reveal_type(nd.transpose((1, 0))) # E: numpy.ndarray + +# swapaxes +reveal_type(nd.swapaxes(0, 1)) # E: numpy.ndarray + +# flatten +reveal_type(nd.flatten()) # E: numpy.ndarray +reveal_type(nd.flatten("C")) # E: numpy.ndarray + +# ravel +reveal_type(nd.ravel()) # E: numpy.ndarray +reveal_type(nd.ravel("C")) # E: numpy.ndarray + +# squeeze +reveal_type(nd.squeeze()) # E: numpy.ndarray +reveal_type(nd.squeeze(0)) # E: numpy.ndarray +reveal_type(nd.squeeze((0, 2))) # E: numpy.ndarray diff --git a/venv/Lib/site-packages/numpy/typing/tests/data/reveal/numeric.py b/venv/Lib/site-packages/numpy/typing/tests/data/reveal/numeric.py new file mode 100644 index 0000000..5cbfa4a --- /dev/null +++ b/venv/Lib/site-packages/numpy/typing/tests/data/reveal/numeric.py @@ -0,0 +1,89 @@ +""" +Tests for :mod:`numpy.core.numeric`. + +Does not include tests which fall under ``array_constructors``. + +""" + +from typing import List +import numpy as np + +class SubClass(np.ndarray): + ... + +i8: np.int64 + +A: np.ndarray +B: List[int] +C: SubClass + +reveal_type(np.count_nonzero(i8)) # E: int +reveal_type(np.count_nonzero(A)) # E: int +reveal_type(np.count_nonzero(B)) # E: int +reveal_type(np.count_nonzero(A, keepdims=True)) # E: Union[numpy.signedinteger[Any], numpy.ndarray] +reveal_type(np.count_nonzero(A, axis=0)) # E: Union[numpy.signedinteger[Any], numpy.ndarray] + +reveal_type(np.isfortran(i8)) # E: bool +reveal_type(np.isfortran(A)) # E: bool + +reveal_type(np.argwhere(i8)) # E: numpy.ndarray +reveal_type(np.argwhere(A)) # E: numpy.ndarray + +reveal_type(np.flatnonzero(i8)) # E: numpy.ndarray +reveal_type(np.flatnonzero(A)) # E: numpy.ndarray + +reveal_type(np.correlate(B, A, mode="valid")) # E: numpy.ndarray +reveal_type(np.correlate(A, A, mode="same")) # E: numpy.ndarray + +reveal_type(np.convolve(B, A, mode="valid")) # E: numpy.ndarray +reveal_type(np.convolve(A, A, mode="same")) # E: numpy.ndarray + +reveal_type(np.outer(i8, A)) # E: numpy.ndarray +reveal_type(np.outer(B, A)) # E: numpy.ndarray +reveal_type(np.outer(A, A)) # E: numpy.ndarray +reveal_type(np.outer(A, A, out=C)) # E: SubClass + +reveal_type(np.tensordot(B, A)) # E: numpy.ndarray +reveal_type(np.tensordot(A, A)) # E: numpy.ndarray +reveal_type(np.tensordot(A, A, axes=0)) # E: numpy.ndarray +reveal_type(np.tensordot(A, A, axes=(0, 1))) # E: numpy.ndarray + +reveal_type(np.isscalar(i8)) # E: bool +reveal_type(np.isscalar(A)) # E: bool +reveal_type(np.isscalar(B)) # E: bool + +reveal_type(np.roll(A, 1)) # E: numpy.ndarray +reveal_type(np.roll(A, (1, 2))) # E: numpy.ndarray +reveal_type(np.roll(B, 1)) # E: numpy.ndarray + +reveal_type(np.rollaxis(A, 0, 1)) # E: numpy.ndarray + +reveal_type(np.moveaxis(A, 0, 1)) # E: numpy.ndarray +reveal_type(np.moveaxis(A, (0, 1), (1, 2))) # E: numpy.ndarray + +reveal_type(np.cross(B, A)) # E: numpy.ndarray +reveal_type(np.cross(A, A)) # E: numpy.ndarray + +reveal_type(np.indices([0, 1, 2])) # E: numpy.ndarray +reveal_type(np.indices([0, 1, 2], sparse=False)) # E: numpy.ndarray +reveal_type(np.indices([0, 1, 2], sparse=True)) # E: tuple[numpy.ndarray] + +reveal_type(np.binary_repr(1)) # E: str + +reveal_type(np.base_repr(1)) # E: str + +reveal_type(np.allclose(i8, A)) # E: bool +reveal_type(np.allclose(B, A)) # E: bool +reveal_type(np.allclose(A, A)) # E: bool + +reveal_type(np.isclose(i8, A)) # E: Union[numpy.bool_, numpy.ndarray] +reveal_type(np.isclose(B, A)) # E: Union[numpy.bool_, numpy.ndarray] +reveal_type(np.isclose(A, A)) # E: Union[numpy.bool_, numpy.ndarray] + +reveal_type(np.array_equal(i8, A)) # E: bool +reveal_type(np.array_equal(B, A)) # E: bool +reveal_type(np.array_equal(A, A)) # E: bool + +reveal_type(np.array_equiv(i8, A)) # E: bool +reveal_type(np.array_equiv(B, A)) # E: bool +reveal_type(np.array_equiv(A, A)) # E: bool diff --git a/venv/Lib/site-packages/numpy/typing/tests/data/reveal/numerictypes.py b/venv/Lib/site-packages/numpy/typing/tests/data/reveal/numerictypes.py new file mode 100644 index 0000000..e026158 --- /dev/null +++ b/venv/Lib/site-packages/numpy/typing/tests/data/reveal/numerictypes.py @@ -0,0 +1,18 @@ +import numpy as np + +reveal_type(np.issctype(np.generic)) # E: bool +reveal_type(np.issctype("foo")) # E: bool + +reveal_type(np.obj2sctype("S8")) # E: Union[numpy.generic, None] +reveal_type(np.obj2sctype("S8", default=None)) # E: Union[numpy.generic, None] +reveal_type( + np.obj2sctype("foo", default=int) # E: Union[numpy.generic, Type[builtins.int*]] +) + +reveal_type(np.issubclass_(np.float64, float)) # E: bool +reveal_type(np.issubclass_(np.float64, (int, float))) # E: bool + +reveal_type(np.sctype2char("S8")) # E: str +reveal_type(np.sctype2char(list)) # E: str + +reveal_type(np.find_common_type([np.int64], [np.int64])) # E: numpy.dtype diff --git a/venv/Lib/site-packages/numpy/typing/tests/data/reveal/scalars.py b/venv/Lib/site-packages/numpy/typing/tests/data/reveal/scalars.py new file mode 100644 index 0000000..e887e30 --- /dev/null +++ b/venv/Lib/site-packages/numpy/typing/tests/data/reveal/scalars.py @@ -0,0 +1,28 @@ +import numpy as np + +x = np.complex64(3 + 2j) + +reveal_type(x.real) # E: numpy.floating[numpy.typing._32Bit] +reveal_type(x.imag) # E: numpy.floating[numpy.typing._32Bit] + +reveal_type(x.real.real) # E: numpy.floating[numpy.typing._32Bit] +reveal_type(x.real.imag) # E: numpy.floating[numpy.typing._32Bit] + +reveal_type(x.itemsize) # E: int +reveal_type(x.shape) # E: Tuple[] +reveal_type(x.strides) # E: Tuple[] + +reveal_type(x.ndim) # E: Literal[0] +reveal_type(x.size) # E: Literal[1] + +reveal_type(x.squeeze()) # E: numpy.complexfloating[numpy.typing._32Bit, numpy.typing._32Bit] +reveal_type(x.byteswap()) # E: numpy.complexfloating[numpy.typing._32Bit, numpy.typing._32Bit] +reveal_type(x.transpose()) # E: numpy.complexfloating[numpy.typing._32Bit, numpy.typing._32Bit] + +reveal_type(x.dtype) # E: numpy.dtype[numpy.complexfloating[numpy.typing._32Bit, numpy.typing._32Bit]] + +reveal_type(np.complex64().real) # E: numpy.floating[numpy.typing._32Bit] +reveal_type(np.complex128().imag) # E: numpy.floating[numpy.typing._64Bit] + +reveal_type(np.unicode_('foo')) # E: numpy.str_ +reveal_type(np.str0('foo')) # E: numpy.str_ diff --git a/venv/Lib/site-packages/numpy/typing/tests/data/reveal/ufunc_config.py b/venv/Lib/site-packages/numpy/typing/tests/data/reveal/ufunc_config.py new file mode 100644 index 0000000..26be803 --- /dev/null +++ b/venv/Lib/site-packages/numpy/typing/tests/data/reveal/ufunc_config.py @@ -0,0 +1,25 @@ +"""Typing tests for `numpy.core._ufunc_config`.""" + +import numpy as np + +def func(a: str, b: int) -> None: ... + +class Write: + def write(self, value: str) -> None: ... + +reveal_type(np.seterr(all=None)) # E: TypedDict('numpy.core._ufunc_config._ErrDict' +reveal_type(np.seterr(divide="ignore")) # E: TypedDict('numpy.core._ufunc_config._ErrDict' +reveal_type(np.seterr(over="warn")) # E: TypedDict('numpy.core._ufunc_config._ErrDict' +reveal_type(np.seterr(under="call")) # E: TypedDict('numpy.core._ufunc_config._ErrDict' +reveal_type(np.seterr(invalid="raise")) # E: TypedDict('numpy.core._ufunc_config._ErrDict' +reveal_type(np.geterr()) # E: TypedDict('numpy.core._ufunc_config._ErrDict' + +reveal_type(np.setbufsize(4096)) # E: int +reveal_type(np.getbufsize()) # E: int + +reveal_type(np.seterrcall(func)) # E: Union[None, def (builtins.str, builtins.int) -> Any, numpy.core._ufunc_config._SupportsWrite] +reveal_type(np.seterrcall(Write())) # E: Union[None, def (builtins.str, builtins.int) -> Any, numpy.core._ufunc_config._SupportsWrite] +reveal_type(np.geterrcall()) # E: Union[None, def (builtins.str, builtins.int) -> Any, numpy.core._ufunc_config._SupportsWrite] + +reveal_type(np.errstate(call=func, all="call")) # E: numpy.errstate[def (a: builtins.str, b: builtins.int)] +reveal_type(np.errstate(call=Write(), divide="log", over="log")) # E: numpy.errstate[ufunc_config.Write] diff --git a/venv/Lib/site-packages/numpy/typing/tests/data/reveal/warnings_and_errors.py b/venv/Lib/site-packages/numpy/typing/tests/data/reveal/warnings_and_errors.py new file mode 100644 index 0000000..c428deb --- /dev/null +++ b/venv/Lib/site-packages/numpy/typing/tests/data/reveal/warnings_and_errors.py @@ -0,0 +1,10 @@ +from typing import Type + +import numpy as np + +reveal_type(np.ModuleDeprecationWarning()) # E: numpy.ModuleDeprecationWarning +reveal_type(np.VisibleDeprecationWarning()) # E: numpy.VisibleDeprecationWarning +reveal_type(np.ComplexWarning()) # E: numpy.ComplexWarning +reveal_type(np.RankWarning()) # E: numpy.RankWarning +reveal_type(np.TooHardError()) # E: numpy.TooHardError +reveal_type(np.AxisError(1)) # E: numpy.AxisError diff --git a/venv/Lib/site-packages/numpy/typing/tests/test_isfile.py b/venv/Lib/site-packages/numpy/typing/tests/test_isfile.py new file mode 100644 index 0000000..569f054 --- /dev/null +++ b/venv/Lib/site-packages/numpy/typing/tests/test_isfile.py @@ -0,0 +1,33 @@ +import os +from pathlib import Path + +import numpy as np +from numpy.testing import assert_ + +ROOT = Path(np.__file__).parents[0] +FILES = [ + ROOT / "py.typed", + ROOT / "__init__.pyi", + ROOT / "char.pyi", + ROOT / "ctypeslib.pyi", + ROOT / "emath.pyi", + ROOT / "rec.pyi", + ROOT / "core" / "__init__.pyi", + ROOT / "distutils" / "__init__.pyi", + ROOT / "f2py" / "__init__.pyi", + ROOT / "fft" / "__init__.pyi", + ROOT / "lib" / "__init__.pyi", + ROOT / "linalg" / "__init__.pyi", + ROOT / "ma" / "__init__.pyi", + ROOT / "matrixlib" / "__init__.pyi", + ROOT / "polynomial" / "__init__.pyi", + ROOT / "random" / "__init__.pyi", + ROOT / "testing" / "__init__.pyi", +] + + +class TestIsFile: + def test_isfile(self): + """Test if all ``.pyi`` files are properly installed.""" + for file in FILES: + assert_(os.path.isfile(file)) diff --git a/venv/Lib/site-packages/numpy/typing/tests/test_typing.py b/venv/Lib/site-packages/numpy/typing/tests/test_typing.py new file mode 100644 index 0000000..90de4fd --- /dev/null +++ b/venv/Lib/site-packages/numpy/typing/tests/test_typing.py @@ -0,0 +1,182 @@ +import importlib.util +import itertools +import os +import re +from collections import defaultdict +from typing import Optional + +import pytest +try: + from mypy import api +except ImportError: + NO_MYPY = True +else: + NO_MYPY = False + + +DATA_DIR = os.path.join(os.path.dirname(__file__), "data") +PASS_DIR = os.path.join(DATA_DIR, "pass") +FAIL_DIR = os.path.join(DATA_DIR, "fail") +REVEAL_DIR = os.path.join(DATA_DIR, "reveal") +MYPY_INI = os.path.join(DATA_DIR, "mypy.ini") +CACHE_DIR = os.path.join(DATA_DIR, ".mypy_cache") + + +def get_test_cases(directory): + for root, _, files in os.walk(directory): + for fname in files: + if os.path.splitext(fname)[-1] == ".py": + fullpath = os.path.join(root, fname) + # Use relative path for nice py.test name + relpath = os.path.relpath(fullpath, start=directory) + + yield pytest.param( + fullpath, + # Manually specify a name for the test + id=relpath, + ) + + +@pytest.mark.slow +@pytest.mark.skipif(NO_MYPY, reason="Mypy is not installed") +@pytest.mark.parametrize("path", get_test_cases(PASS_DIR)) +def test_success(path): + stdout, stderr, exitcode = api.run([ + "--config-file", + MYPY_INI, + "--cache-dir", + CACHE_DIR, + path, + ]) + assert exitcode == 0, stdout + assert re.match(r"Success: no issues found in \d+ source files?", stdout.strip()) + + +@pytest.mark.slow +@pytest.mark.skipif(NO_MYPY, reason="Mypy is not installed") +@pytest.mark.parametrize("path", get_test_cases(FAIL_DIR)) +def test_fail(path): + __tracebackhide__ = True + + stdout, stderr, exitcode = api.run([ + "--config-file", + MYPY_INI, + "--cache-dir", + CACHE_DIR, + path, + ]) + assert exitcode != 0 + + with open(path) as fin: + lines = fin.readlines() + + errors = defaultdict(lambda: "") + error_lines = stdout.rstrip("\n").split("\n") + assert re.match( + r"Found \d+ errors? in \d+ files? \(checked \d+ source files?\)", + error_lines[-1].strip(), + ) + for error_line in error_lines[:-1]: + error_line = error_line.strip() + if not error_line: + continue + + match = re.match( + r"^.+\.py:(?P\d+): (error|note): .+$", + error_line, + ) + if match is None: + raise ValueError(f"Unexpected error line format: {error_line}") + lineno = int(match.group('lineno')) + errors[lineno] += error_line + + for i, line in enumerate(lines): + lineno = i + 1 + if line.startswith('#') or (" E:" not in line and lineno not in errors): + continue + + target_line = lines[lineno - 1] + if "# E:" in target_line: + marker = target_line.split("# E:")[-1].strip() + expected_error = errors.get(lineno) + _test_fail(path, marker, expected_error, lineno) + else: + pytest.fail(f"Error {repr(errors[lineno])} not found") + + +_FAIL_MSG1 = """Extra error at line {} + +Extra error: {!r} +""" + +_FAIL_MSG2 = """Error mismatch at line {} + +Expected error: {!r} +Observed error: {!r} +""" + + +def _test_fail(path: str, error: str, expected_error: Optional[str], lineno: int) -> None: + if expected_error is None: + raise AssertionError(_FAIL_MSG1.format(lineno, error)) + elif error not in expected_error: + raise AssertionError(_FAIL_MSG2.format(lineno, expected_error, error)) + + +@pytest.mark.slow +@pytest.mark.skipif(NO_MYPY, reason="Mypy is not installed") +@pytest.mark.parametrize("path", get_test_cases(REVEAL_DIR)) +def test_reveal(path): + __tracebackhide__ = True + + stdout, stderr, exitcode = api.run([ + "--config-file", + MYPY_INI, + "--cache-dir", + CACHE_DIR, + path, + ]) + + with open(path) as fin: + lines = fin.read().replace('*', '').split("\n") + + stdout_list = stdout.replace('*', '').split("\n") + for error_line in stdout_list: + error_line = error_line.strip() + if not error_line: + continue + + match = re.match( + r"^.+\.py:(?P\d+): note: .+$", + error_line, + ) + if match is None: + raise ValueError(f"Unexpected reveal line format: {error_line}") + lineno = int(match.group('lineno')) - 1 + assert "Revealed type is" in error_line + + marker = lines[lineno].split("# E:")[-1].strip() + _test_reveal(path, marker, error_line, 1 + lineno) + + +_REVEAL_MSG = """Reveal mismatch at line {} + +Expected reveal: {!r} +Observed reveal: {!r} +""" + + +def _test_reveal(path: str, reveal: str, expected_reveal: str, lineno: int) -> None: + if reveal not in expected_reveal: + raise AssertionError(_REVEAL_MSG.format(lineno, expected_reveal, reveal)) + + +@pytest.mark.slow +@pytest.mark.skipif(NO_MYPY, reason="Mypy is not installed") +@pytest.mark.parametrize("path", get_test_cases(PASS_DIR)) +def test_code_runs(path): + path_without_extension, _ = os.path.splitext(path) + dirname, filename = path.split(os.sep)[-2:] + spec = importlib.util.spec_from_file_location(f"{dirname}.{filename}", path) + test_module = importlib.util.module_from_spec(spec) + spec.loader.exec_module(test_module) diff --git a/venv/Lib/site-packages/numpy/version.py b/venv/Lib/site-packages/numpy/version.py new file mode 100644 index 0000000..6cf3223 --- /dev/null +++ b/venv/Lib/site-packages/numpy/version.py @@ -0,0 +1,12 @@ + +# THIS FILE IS GENERATED FROM NUMPY SETUP.PY +# +# To compare versions robustly, use `numpy.lib.NumpyVersion` +short_version: str = '1.20.2' +version: str = '1.20.2' +full_version: str = '1.20.2' +git_revision: str = 'b19ad5bfa396a4600a52a598a30a65d4e993f831' +release: bool = True + +if not release: + version = full_version diff --git a/venv/Lib/site-packages/pgzero-1.2.1.dist-info/AUTHORS b/venv/Lib/site-packages/pgzero-1.2.1.dist-info/AUTHORS new file mode 100644 index 0000000..89d70f9 --- /dev/null +++ b/venv/Lib/site-packages/pgzero-1.2.1.dist-info/AUTHORS @@ -0,0 +1,2 @@ +Daniel Pope +Richard Jones diff --git a/venv/Lib/site-packages/pgzero-1.2.1.dist-info/COPYING b/venv/Lib/site-packages/pgzero-1.2.1.dist-info/COPYING new file mode 100644 index 0000000..65c5ca8 --- /dev/null +++ b/venv/Lib/site-packages/pgzero-1.2.1.dist-info/COPYING @@ -0,0 +1,165 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. diff --git a/venv/Lib/site-packages/pgzero-1.2.1.dist-info/INSTALLER b/venv/Lib/site-packages/pgzero-1.2.1.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/venv/Lib/site-packages/pgzero-1.2.1.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/venv/Lib/site-packages/pgzero-1.2.1.dist-info/METADATA b/venv/Lib/site-packages/pgzero-1.2.1.dist-info/METADATA new file mode 100644 index 0000000..31487f4 --- /dev/null +++ b/venv/Lib/site-packages/pgzero-1.2.1.dist-info/METADATA @@ -0,0 +1,90 @@ +Metadata-Version: 2.1 +Name: pgzero +Version: 1.2.1 +Summary: A zero-boilerplate 2D games framework +Home-page: http://pypi.python.org/pypi/pgzero +Author: Daniel Pope +Author-email: mauve@mauveweb.co.uk +License: UNKNOWN +Platform: UNKNOWN +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Education +Classifier: License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3) +Classifier: Programming Language :: Python :: 3 :: Only +Classifier: Topic :: Education +Classifier: Topic :: Games/Entertainment +Requires-Dist: pygame (~=2.0) +Requires-Dist: numpy +Requires-Dist: enum34 ; python_version < "3.4" + +Pygame Zero +=========== + +A zero-boilerplate games programming framework for Python 3, based on Pygame. + +Some examples +------------- + +Pygame Zero consists of a runner ``pgzrun`` that will run a Pygame Zero script +with a full game loop and a range of useful builtins. + +Here's some of the neat stuff you can do. Note that each of these is a +self-contained script. There's no need for any imports or anything else in the +file. + +Draw graphics (assuming there's a file like ``images/dog.png`` or +``images/dog.jpg``):: + + def draw(): + screen.clear() + screen.blit('dog', (10, 50)) + +Play the sound ``sounds/eep.wav`` when you click the mouse:: + + def on_mouse_down(): + sounds.eep.play() + +Draw an "actor" object (with the sprite ``images/alien.png``) that moves across +the screen:: + + alien = Actor('alien') + alien.pos = 10, 10 + + def draw(): + screen.clear() + alien.draw() + + def update(): + alien.x += 1 + if alien.left > WIDTH: + alien.right = 0 + +Installation +------------ + +See `installation instructions`__. + +.. __: http://pygame-zero.readthedocs.org/en/latest/installation.html + + +Documentation +------------- + +The full documentation is at http://pygame-zero.readthedocs.org/. + +Read the tutorial at http://pygame-zero.readthedocs.org/en/latest/introduction.html +for a taste of the other things that Pygame Zero can do. + +Contributing +------------ + +The project is hosted on Github: + +https://github.com/lordmauve/pgzero + +If you want to help out with the development of Pygame Zero, you can find some +instructions on setting up a development version in the docs: + +http://pygame-zero.readthedocs.org/en/latest/contributing.html + + diff --git a/venv/Lib/site-packages/pgzero-1.2.1.dist-info/RECORD b/venv/Lib/site-packages/pgzero-1.2.1.dist-info/RECORD new file mode 100644 index 0000000..7c057c7 --- /dev/null +++ b/venv/Lib/site-packages/pgzero-1.2.1.dist-info/RECORD @@ -0,0 +1,50 @@ +../../Scripts/pgzrun.exe,sha256=ZAm10tGvnDu0g1-7sy16AY3Yr-EbsDHmxG2G9qyKJP8,106349 +__pycache__/pgzrun.cpython-39.pyc,, +pgzero-1.2.1.dist-info/AUTHORS,sha256=GzMW4jTyfTFQepdM7Zmvj9Vbpn4W9GquX23pKWOlEdE,70 +pgzero-1.2.1.dist-info/COPYING,sha256=2n6rt7r999OuXp8iOqW9we7ORaxWncIbOwN1ILRGR2g,7651 +pgzero-1.2.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +pgzero-1.2.1.dist-info/METADATA,sha256=PY_hZHDryQlRzsFpxe9fpWDSJ7exNFfK09niDMydq80,2332 +pgzero-1.2.1.dist-info/RECORD,, +pgzero-1.2.1.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +pgzero-1.2.1.dist-info/WHEEL,sha256=OqRkF0eY5GHssMorFjlbTIq072vpHpF60fIQA6lS9xA,92 +pgzero-1.2.1.dist-info/entry_points.txt,sha256=r66fj5IThbEiS5e2jKtKveMmCLsRwn9QMuhiB8q0fjs,47 +pgzero-1.2.1.dist-info/top_level.txt,sha256=wWmWUHLHO9FO3mSrBtOIwzPsq1lA_vRnxCJqD5Z55cg,14 +pgzero/__init__.py,sha256=hXFuBdR_FvwprjG7rjRNiu41E-2n291EX5w9ekXxGcA,206 +pgzero/__main__.py,sha256=PeB5NzBB6KEW5rPmTHwltgn7Fi-L2pEVSPyTVIm2Qyw,39 +pgzero/__pycache__/__init__.cpython-39.pyc,, +pgzero/__pycache__/__main__.cpython-39.pyc,, +pgzero/__pycache__/actor.cpython-39.pyc,, +pgzero/__pycache__/animation.cpython-39.pyc,, +pgzero/__pycache__/builtins.cpython-39.pyc,, +pgzero/__pycache__/clock.cpython-39.pyc,, +pgzero/__pycache__/constants.cpython-39.pyc,, +pgzero/__pycache__/game.cpython-39.pyc,, +pgzero/__pycache__/keyboard.cpython-39.pyc,, +pgzero/__pycache__/loaders.cpython-39.pyc,, +pgzero/__pycache__/music.cpython-39.pyc,, +pgzero/__pycache__/ptext.cpython-39.pyc,, +pgzero/__pycache__/rect.cpython-39.pyc,, +pgzero/__pycache__/runner.cpython-39.pyc,, +pgzero/__pycache__/screen.cpython-39.pyc,, +pgzero/__pycache__/soundfmt.cpython-39.pyc,, +pgzero/__pycache__/spellcheck.cpython-39.pyc,, +pgzero/__pycache__/tone.cpython-39.pyc,, +pgzero/actor.py,sha256=65wq82poRiEJy13QZQP-yl2hTWPvEm3qRt3gN_iHIZQ,7168 +pgzero/animation.py,sha256=z7PbCXQAC3Nlhx3AIc317szSM1OsvOn5lQ69ApqyHYg,5749 +pgzero/builtins.py,sha256=IJh_BDG-P1Ev_CFRgoHB2_SxhF3RwpZBNzBEYs6riP4,314 +pgzero/clock.py,sha256=UXfX86D2mO5_F2nSGYKvJJ3OPqThvazKTN-Wo0zkT_4,5190 +pgzero/constants.py,sha256=Z61PDQnaacz2PcGTXmzUU7pTpH1O7TGLQY2GuI1hM8k,828 +pgzero/data/icon.png,sha256=aLgAnwMWrzOCxiCk_vxd9grEG-D0iLC_W1dN903PYVs,3646 +pgzero/data/joypad.png,sha256=tM4uix2UjoFqjD3KFzwom7DLwglPPl7wW0wW7x-NkAQ,30048 +pgzero/game.py,sha256=a_Z-ubpGVcMbdHzFD6-WfsImLFOM3gEL9VRqjXxcs3M,7624 +pgzero/keyboard.py,sha256=nxoE017iNvUWJ-I2IgABIrgH6tGqUsnyUG6iSTUXoaA,1595 +pgzero/loaders.py,sha256=HT5Emly9bIFo2PD8e2UO71DyJYENxUIeRTUebzD8Gas,6778 +pgzero/music.py,sha256=eNI1cTd67JdLWadrv4-1ACsUMRfPU9gwdZt73ikc_oY,2526 +pgzero/ptext.py,sha256=Ds-lcCqDsEvyAdT7aP-fVSU2godGlUdyY2kFRACCtIM,18387 +pgzero/rect.py,sha256=1SzUW7uA3AXH6K0KRvn-T4DLo7KXHiTfP_PAMZM0bVk,15799 +pgzero/runner.py,sha256=dZxhWid7VDhvfHmRDCfABpGlsqFQuIZ5M_V5Koxnyck,3486 +pgzero/screen.py,sha256=kAHrePf54GHRsAV7Ri1suDTzBLLEM1olU10Omn28wtY,3379 +pgzero/soundfmt.py,sha256=IDe8MSAcDvjfEw7VG7QezBhyAd3VQ9DrMf1u4LuRKZI,2988 +pgzero/spellcheck.py,sha256=Bl3ZUe1UrHAWSXIEie0uq3fgVCffdYD3wowBDaBmALM,4989 +pgzero/tone.py,sha256=pOzI-ZWQRVB1O2j3qzpMKvyI5xccAgoBv7SOI7-Gg_E,5279 +pgzrun.py,sha256=cag-cIifZ9JSjSESmm8VeOFJ8KchZ1nloEwW0GkYkUk,827 diff --git a/venv/Lib/site-packages/pgzero-1.2.1.dist-info/REQUESTED b/venv/Lib/site-packages/pgzero-1.2.1.dist-info/REQUESTED new file mode 100644 index 0000000..e69de29 diff --git a/venv/Lib/site-packages/pgzero-1.2.1.dist-info/WHEEL b/venv/Lib/site-packages/pgzero-1.2.1.dist-info/WHEEL new file mode 100644 index 0000000..385faab --- /dev/null +++ b/venv/Lib/site-packages/pgzero-1.2.1.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.36.2) +Root-Is-Purelib: true +Tag: py3-none-any + diff --git a/venv/Lib/site-packages/pgzero-1.2.1.dist-info/entry_points.txt b/venv/Lib/site-packages/pgzero-1.2.1.dist-info/entry_points.txt new file mode 100644 index 0000000..5ea5b31 --- /dev/null +++ b/venv/Lib/site-packages/pgzero-1.2.1.dist-info/entry_points.txt @@ -0,0 +1,3 @@ +[console_scripts] +pgzrun = pgzero.runner:main + diff --git a/venv/Lib/site-packages/pgzero-1.2.1.dist-info/top_level.txt b/venv/Lib/site-packages/pgzero-1.2.1.dist-info/top_level.txt new file mode 100644 index 0000000..8160511 --- /dev/null +++ b/venv/Lib/site-packages/pgzero-1.2.1.dist-info/top_level.txt @@ -0,0 +1,2 @@ +pgzero +pgzrun diff --git a/venv/Lib/site-packages/pgzero/__init__.py b/venv/Lib/site-packages/pgzero/__init__.py new file mode 100644 index 0000000..cd56aa3 --- /dev/null +++ b/venv/Lib/site-packages/pgzero/__init__.py @@ -0,0 +1,8 @@ +"""Pygame Zero, a zero-boilerplate game framework for education. + +You shouldn't need to import things from the 'pgzero' package directly; just +use 'pgzrun' to run the game file. + +""" + +__version__ = '1.2.1' diff --git a/venv/Lib/site-packages/pgzero/__main__.py b/venv/Lib/site-packages/pgzero/__main__.py new file mode 100644 index 0000000..11e0feb --- /dev/null +++ b/venv/Lib/site-packages/pgzero/__main__.py @@ -0,0 +1,3 @@ +from pgzero.runner import main + +main() diff --git a/venv/Lib/site-packages/pgzero/actor.py b/venv/Lib/site-packages/pgzero/actor.py new file mode 100644 index 0000000..26202cd --- /dev/null +++ b/venv/Lib/site-packages/pgzero/actor.py @@ -0,0 +1,250 @@ +import pygame +from math import radians, sin, cos, atan2, degrees, sqrt + +from . import game +from . import loaders +from . import rect +from . import spellcheck + + +ANCHORS = { + 'x': { + 'left': 0.0, + 'center': 0.5, + 'middle': 0.5, + 'right': 1.0, + }, + 'y': { + 'top': 0.0, + 'center': 0.5, + 'middle': 0.5, + 'bottom': 1.0, + } +} + + +def calculate_anchor(value, dim, total): + if isinstance(value, str): + try: + return total * ANCHORS[dim][value] + except KeyError: + raise ValueError( + '%r is not a valid %s-anchor name' % (value, dim) + ) + return float(value) + + +# These are methods (of the same name) on pygame.Rect +SYMBOLIC_POSITIONS = set(( + "topleft", "bottomleft", "topright", "bottomright", + "midtop", "midleft", "midbottom", "midright", + "center", +)) + +# Provides more meaningful default-arguments e.g. for display in IDEs etc. +POS_TOPLEFT = None +ANCHOR_CENTER = None + + +def transform_anchor(ax, ay, w, h, angle): + """Transform anchor based upon a rotation of a surface of size w x h.""" + theta = -radians(angle) + + sintheta = sin(theta) + costheta = cos(theta) + + # Dims of the transformed rect + tw = abs(w * costheta) + abs(h * sintheta) + th = abs(w * sintheta) + abs(h * costheta) + + # Offset of the anchor from the center + cax = ax - w * 0.5 + cay = ay - h * 0.5 + + # Rotated offset of the anchor from the center + rax = cax * costheta - cay * sintheta + ray = cax * sintheta + cay * costheta + + return ( + tw * 0.5 + rax, + th * 0.5 + ray + ) + + +class Actor: + EXPECTED_INIT_KWARGS = SYMBOLIC_POSITIONS + DELEGATED_ATTRIBUTES = [a for a in dir(rect.ZRect) if not a.startswith("_")] + + _anchor = _anchor_value = (0, 0) + _angle = 0.0 + + def __init__(self, image, pos=POS_TOPLEFT, anchor=ANCHOR_CENTER, **kwargs): + self._handle_unexpected_kwargs(kwargs) + + self.__dict__["_rect"] = rect.ZRect((0, 0), (0, 0)) + # Initialise it at (0, 0) for size (0, 0). + # We'll move it to the right place and resize it later + + self.image = image + self._init_position(pos, anchor, **kwargs) + + def __getattr__(self, attr): + if attr in self.__class__.DELEGATED_ATTRIBUTES: + return getattr(self._rect, attr) + else: + return object.__getattribute__(self, attr) + + def __setattr__(self, attr, value): + """Assign rect attributes to the underlying rect.""" + if attr in self.__class__.DELEGATED_ATTRIBUTES: + return setattr(self._rect, attr, value) + else: + # Ensure data descriptors are set normally + return object.__setattr__(self, attr, value) + + def __iter__(self): + return iter(self._rect) + + def _handle_unexpected_kwargs(self, kwargs): + unexpected_kwargs = set(kwargs.keys()) - self.EXPECTED_INIT_KWARGS + if not unexpected_kwargs: + return + + for found, suggested in spellcheck.compare( + unexpected_kwargs, self.EXPECTED_INIT_KWARGS): + raise TypeError( + "Unexpected keyword argument '{}' (did you mean '{}'?)".format( + found, suggested)) + + def _init_position(self, pos, anchor, **kwargs): + if anchor is None: + anchor = ("center", "center") + self.anchor = anchor + + symbolic_pos_args = { + k: kwargs[k] for k in kwargs if k in SYMBOLIC_POSITIONS} + + if not pos and not symbolic_pos_args: + # No positional information given, use sensible top-left default + self.topleft = (0, 0) + elif pos and symbolic_pos_args: + raise TypeError("'pos' argument cannot be mixed with 'topleft', 'topright' etc. argument.") + elif pos: + self.pos = pos + else: + self._set_symbolic_pos(symbolic_pos_args) + + def _set_symbolic_pos(self, symbolic_pos_dict): + if len(symbolic_pos_dict) == 0: + raise TypeError("No position-setting keyword arguments ('topleft', 'topright' etc) found.") + if len(symbolic_pos_dict) > 1: + raise TypeError("Only one 'topleft', 'topright' etc. argument is allowed.") + + setter_name, position = symbolic_pos_dict.popitem() + setattr(self, setter_name, position) + + @property + def anchor(self): + return self._anchor_value + + @anchor.setter + def anchor(self, val): + self._anchor_value = val + self._calc_anchor() + + def _calc_anchor(self): + ax, ay = self._anchor_value + ow, oh = self._orig_surf.get_size() + ax = calculate_anchor(ax, 'x', ow) + ay = calculate_anchor(ay, 'y', oh) + self._untransformed_anchor = ax, ay + if self._angle == 0.0: + self._anchor = self._untransformed_anchor + else: + self._anchor = transform_anchor(ax, ay, ow, oh, self._angle) + + @property + def angle(self): + return self._angle + + @angle.setter + def angle(self, angle): + self._angle = angle + self._surf = pygame.transform.rotate(self._orig_surf, angle) + p = self.pos + self.width, self.height = self._surf.get_size() + w, h = self._orig_surf.get_size() + ax, ay = self._untransformed_anchor + self._anchor = transform_anchor(ax, ay, w, h, angle) + self.pos = p + + @property + def pos(self): + px, py = self.topleft + ax, ay = self._anchor + return px + ax, py + ay + + @pos.setter + def pos(self, pos): + px, py = pos + ax, ay = self._anchor + self.topleft = px - ax, py - ay + + @property + def x(self): + ax = self._anchor[0] + return self.left + ax + + @x.setter + def x(self, px): + self.left = px - self._anchor[0] + + @property + def y(self): + ay = self._anchor[1] + return self.top + ay + + @y.setter + def y(self, py): + self.top = py - self._anchor[1] + + @property + def image(self): + return self._image_name + + @image.setter + def image(self, image): + self._image_name = image + self._orig_surf = self._surf = loaders.images.load(image) + self._update_pos() + + def _update_pos(self): + p = self.pos + self.width, self.height = self._surf.get_size() + self._calc_anchor() + self.pos = p + + def draw(self): + game.screen.blit(self._surf, self.topleft) + + def angle_to(self, target): + """Return the angle from this actors position to target, in degrees.""" + if isinstance(target, Actor): + tx, ty = target.pos + else: + tx, ty = target + myx, myy = self.pos + dx = tx - myx + dy = myy - ty # y axis is inverted from mathematical y in Pygame + return degrees(atan2(dy, dx)) + + def distance_to(self, target): + """Return the distance from this actor's pos to target, in pixels.""" + if isinstance(target, Actor): + tx, ty = target.pos + else: + tx, ty = target + myx, myy = self.pos + dx = tx - myx + dy = ty - myy + return sqrt(dx * dx + dy * dy) diff --git a/venv/Lib/site-packages/pgzero/animation.py b/venv/Lib/site-packages/pgzero/animation.py new file mode 100644 index 0000000..64da484 --- /dev/null +++ b/venv/Lib/site-packages/pgzero/animation.py @@ -0,0 +1,216 @@ +# Easing Functions ported from the Clutter Project via http://kivy.org/ +# http://www.clutter-project.org/docs/clutter/stable/ClutterAlpha.html + + +from math import sin, pow, pi + +from .clock import each_tick, unschedule + +TWEEN_FUNCTIONS = {} + + +def tweener(f): + TWEEN_FUNCTIONS[f.__name__] = f + return f + + +@tweener +def linear(n): + return n + + +@tweener +def accelerate(n): + return n * n + + +@tweener +def decelerate(n): + return -1.0 * n * (n - 2.0) + + +@tweener +def accel_decel(n): + p = n * 2 + if p < 1: + return 0.5 * p * p + p -= 1.0 + return -0.5 * (p * (p - 2.0) - 1.0) + + +@tweener +def in_elastic(n): + p = .3 + s = p / 4.0 + q = n + if q == 1: + return 1.0 + q -= 1.0 + return -(pow(2, 10 * q) * sin((q - s) * (2 * pi) / p)) + +@tweener +def out_elastic(n): + p = .3 + s = p / 4.0 + q = n + if q == 1: + return 1.0 + return pow(2, -10 * q) * sin((q - s) * (2 * pi) / p) + 1.0 + +@tweener +def in_out_elastic(n): + p = .3 * 1.5 + s = p / 4.0 + q = n * 2 + if q == 2: + return 1.0 + if q < 1: + q -= 1.0 + return -.5 * (pow(2, 10 * q) * sin((q - s) * (2.0 * pi) / p)) + else: + q -= 1.0 + return pow(2, -10 * q) * sin((q - s) * (2.0 * pi) / p) * .5 + 1.0 + + +def _out_bounce_internal(t, d): + p = t / d + if p < (1.0 / 2.75): + return 7.5625 * p * p + elif p < (2.0 / 2.75): + p -= (1.5 / 2.75) + return 7.5625 * p * p + .75 + elif p < (2.5 / 2.75): + p -= (2.25 / 2.75) + return 7.5625 * p * p + .9375 + else: + p -= (2.625 / 2.75) + return 7.5625 * p * p + .984375 + + +def _in_bounce_internal(t, d): + return 1.0 - _out_bounce_internal(d - t, d) + + +@tweener +def bounce_end(n): + return _out_bounce_internal(n, 1.) + + +@tweener +def bounce_start(n): + return _in_bounce_internal(n, 1.) + + +@tweener +def bounce_start_end(n): + p = n * 2. + if p < 1.: + return _in_bounce_internal(p, 1.) * .5 + return _out_bounce_internal(p - 1., 1.) * .5 + .5 + + +def tween(n, start, end): + return start + (end - start) * n + + +def tween_attr(n, start, end): + if isinstance(start, tuple): + return tuple(tween(n, a, b) for a,b in zip(start, end)) + elif isinstance(start, list): + return [tween(n, a, b) for a,b in zip(start, end)] + else: + return tween(n, start, end) + + +class Animation: + """An animation manager for object attribute animations. + + Each keyword argument given to the Animation on creation (except + "type" and "duration") will be *tweened* from their current value + on the object to the target value specified. + + If the value is a list or tuple, then each value inside that will + be tweened. + + The update() method is automatically scheduled with the clock for + the duration of the animation. + + """ + animations = [] + + # Animations are stored in _animation_dict under (object id, target + # attribute) keys. Objects may not be hashable, so the id, rather than + # the object itself, is needed. + # Animations with multiple targets will appear here multiple times. + # Newly scheduled animations will overwrite new ones. Once an animation + # ends, it is removed from this dict. + # Note that Animation keeps a reference to "its" object, so the id in the + # key will be valid as long as the animation lives. + _animation_dict = {} + + def __init__(self, object, tween='linear', duration=1, on_finished=None, + **targets): + self.targets = targets + self.function = TWEEN_FUNCTIONS[tween] + self.duration = duration + self.on_finished = on_finished + self.t = 0 + self.object = object + self.initial = {} + self.running = True + for k in self.targets: + try: + a = getattr(object, k) + except AttributeError: + raise ValueError('object %r has no attribute %s to animate' % (object, k)) + self.initial[k] = a + key = id(object), k + previous_animation = self._animation_dict.get(key) + if previous_animation is not None: + previous_animation._remove_target(k) + self._animation_dict[key] = self + each_tick(self.update) + self.animations.append(self) + + def update(self, dt): + self.t += dt + n = self.t / self.duration + if n > 1: + n = 1 + self.stop(complete=True) + if self.on_finished is not None: + self.on_finished() + return + n = self.function(n) + for k in self.targets: + v = tween_attr(n, self.initial[k], self.targets[k]) + setattr(self.object, k, v) + + def stop(self, complete=False): + """Stop the animation, optionally completing the transition to the final + property values. + + :param complete: If True, the object will have its targets + set to their final values for the animation. If not, the + targets will be set to some value between the start and + end values. + """ + self.running = False + if complete: + for k in self.targets: + setattr(self.object, k, self.targets[k]) + for k in list(self.targets): + self._remove_target(k, stop=False) + unschedule(self.update) + self.animations.remove(self) + + def _remove_target(self, target, stop=True): + del self.targets[target] + del self._animation_dict[id(self.object), target] + if not self.targets and stop: + self.stop() + + +def animate(object, tween='linear', duration=1, on_finished=None, **targets): + return Animation(object, tween, duration, on_finished=on_finished, + **targets) diff --git a/venv/Lib/site-packages/pgzero/builtins.py b/venv/Lib/site-packages/pgzero/builtins.py new file mode 100644 index 0000000..58bd21f --- /dev/null +++ b/venv/Lib/site-packages/pgzero/builtins.py @@ -0,0 +1,14 @@ +# Expose clock API as a builtin +from . import clock +from . import music +from . import tone +from .actor import Actor +from .keyboard import keyboard +from .animation import animate +from .rect import Rect, ZRect + +from .loaders import images, sounds + +from .constants import mouse, keys, keymods + +from .game import exit diff --git a/venv/Lib/site-packages/pgzero/clock.py b/venv/Lib/site-packages/pgzero/clock.py new file mode 100644 index 0000000..3a31531 --- /dev/null +++ b/venv/Lib/site-packages/pgzero/clock.py @@ -0,0 +1,182 @@ +"""Clock/event scheduler. + +This is a Pygame implementation of a scheduler inspired by the clock +classes in Pyglet. + +""" +import heapq +from weakref import ref +from functools import total_ordering +from types import MethodType + +__all__ = [ + 'Clock', 'schedule', 'schedule_interval', 'unschedule' +] + + +def weak_method(method): + """Quick weak method ref in case users aren't using Python 3.4""" + selfref = ref(method.__self__) + funcref = ref(method.__func__) + + def weakref(): + self = selfref() + func = funcref() + if self is None or func is None: + return None + return func.__get__(self) + return weakref + + +def mkref(o): + if isinstance(o, MethodType): + return weak_method(o) + else: + return ref(o) + + +@total_ordering +class Event: + """An event scheduled for a future time. + + Events are ordered by their scheduled execution time. + + """ + def __init__(self, time, cb, repeat=None): + self.time = time + self.repeat = repeat + self.cb = mkref(cb) + self.name = str(cb) + self.repeat = repeat + + def __lt__(self, ano): + return self.time < ano.time + + def __eq__(self, ano): + return self.time == ano.time + + @property + def callback(self): + return self.cb() + + +class Clock: + """A clock used for event scheduling. + + When tick() is called, all events scheduled for before now will be called + in order. + + tick() would typically be called from the game loop for the default clock. + + Additional clocks could be created - for example, a game clock that could + be suspended in pause screens. Your code must take care of calling tick() + or not. You could also run the clock at a different rate if desired, by + scaling dt before passing it to tick(). + + """ + def __init__(self): + self.t = 0 + self.fired = False + self.events = [] + self._each_tick = [] + + def schedule(self, callback, delay): + """Schedule callback to be called once, at `delay` seconds from now. + + :param callback: A parameterless callable to be called. + :param delay: The delay before the call (in clock time / seconds). + + """ + heapq.heappush(self.events, Event(self.t + delay, callback, None)) + + def schedule_unique(self, callback, delay): + """Schedule callback to be called once, at `delay` seconds from now. + + If it was already scheduled, postpone its firing. + + :param callback: A parameterless callable to be called. + :param delay: The delay before the call (in clock time / seconds). + + """ + self.unschedule(callback) + self.schedule(callback, delay) + + def schedule_interval(self, callback, delay): + """Schedule callback to be called every `delay` seconds. + + The first occurrence will be after `delay` seconds. + + :param callback: A parameterless callable to be called. + :param delay: The interval in seconds. + + """ + heapq.heappush(self.events, Event(self.t + delay, callback, delay)) + + def unschedule(self, callback): + """Unschedule the given callback. + + If scheduled multiple times all instances will be unscheduled. + + """ + self.events = [e for e in self.events if e.callback != callback and e.callback is not None] + heapq.heapify(self.events) + self._each_tick = [e for e in self._each_tick if e() != callback] + + def each_tick(self, callback): + """Schedule a callback to be called every tick. + + Unlike the standard scheduler functions, the callable is passed the + elapsed clock time since the last call (the same value passed to tick). + + """ + self._each_tick.append(mkref(callback)) + + def _fire_each_tick(self, dt): + dead = [None] + for r in self._each_tick: + cb = r() + if cb is not None: + self.fired = True + try: + cb(dt) + except Exception: + import traceback + traceback.print_exc() + dead.append(cb) + self._each_tick = [e for e in self._each_tick if e() not in dead] + + def tick(self, dt): + """Update the clock time and fire all scheduled events. + + :param dt: The elapsed time in seconds. + + """ + self.fired = False + self.t += float(dt) + self._fire_each_tick(dt) + while self.events and self.events[0].time <= self.t: + ev = heapq.heappop(self.events) + cb = ev.callback + if not cb: + continue + + if ev.repeat is not None: + self.schedule_interval(cb, ev.repeat) + + self.fired = True + try: + cb() + except Exception: + import traceback + traceback.print_exc() + self.unschedule(cb) + + +# One instance of a clock is available by default, to simplify the API +clock = Clock() +tick = clock.tick +schedule = clock.schedule +schedule_interval = clock.schedule_interval +schedule_unique = clock.schedule_unique +unschedule = clock.unschedule +each_tick = clock.each_tick diff --git a/venv/Lib/site-packages/pgzero/constants.py b/venv/Lib/site-packages/pgzero/constants.py new file mode 100644 index 0000000..ec26ac4 --- /dev/null +++ b/venv/Lib/site-packages/pgzero/constants.py @@ -0,0 +1,33 @@ +"""Names for constants returned by Pygame.""" +from enum import IntEnum +import pygame.locals + + +# Event type indicating the end of a music track +MUSIC_END = 99 + + +class mouse(IntEnum): + LEFT = 1 + MIDDLE = 2 + RIGHT = 3 + WHEEL_UP = 4 + WHEEL_DOWN = 5 + + +# Use a code generation approach to copy Pygame's key constants out into +# a Python 3.4 IntEnum, stripping prefixes where possible +srclines = ["class keys(IntEnum):"] +for k, v in vars(pygame.locals).items(): + if k.startswith('K_'): + if k[2].isalpha(): + k = k[2:] + srclines.append(" %s = %d" % (k.upper(), v)) + +srclines.append("class keymods(IntEnum):") +for k, v in vars(pygame.locals).items(): + if k.startswith('KMOD_'): + srclines.append(" %s = %d" % (k[5:].upper(), v)) + +exec('\n'.join(srclines), globals()) +del srclines diff --git a/venv/Lib/site-packages/pgzero/data/icon.png b/venv/Lib/site-packages/pgzero/data/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..765c6c8b88652051f23bb81629fb59195c487583 GIT binary patch literal 3646 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�cMQO*2Oy-N-TNaM% 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 literal 0 HcmV?d00001 diff --git a/venv/Lib/site-packages/pgzero/game.py b/venv/Lib/site-packages/pgzero/game.py new file mode 100644 index 0000000..d73b50c --- /dev/null +++ b/venv/Lib/site-packages/pgzero/game.py @@ -0,0 +1,258 @@ +import sys +import operator +import time + +import pygame +import pgzero.clock +import pgzero.keyboard +import pgzero.screen + +from . import constants + + +screen = None +DISPLAY_FLAGS = 0 + + +def exit(): + """Wait for up to a second for all sounds to play out + and then exit + """ + t0 = time.time() + while pygame.mixer.get_busy(): + time.sleep(0.1) + if time.time() - t0 > 1.0: + break + sys.exit() + + +def positional_parameters(handler): + """Get the positional parameters of the given function.""" + code = handler.__code__ + return code.co_varnames[:code.co_argcount] + + +class DEFAULTICON: + """Sentinel indicating that we want to use the default icon.""" + + +class PGZeroGame: + def __init__(self, mod): + self.mod = mod + self.screen = None + self.width = None + self.height = None + self.title = None + self.icon = None + self.keyboard = pgzero.keyboard.keyboard + self.handlers = {} + + def reinit_screen(self): + """Reinitialise the window. + + Return True if the dimensions of the screen changed. + + """ + global screen + changed = False + mod = self.mod + + icon = getattr(self.mod, 'ICON', DEFAULTICON) + if icon and icon != self.icon: + if icon is DEFAULTICON: + self.show_default_icon() + else: + pygame.display.set_icon(pygame.image.load(icon)) + self.icon = icon + + w = getattr(mod, 'WIDTH', 800) + h = getattr(mod, 'HEIGHT', 600) + if w != self.width or h != self.height: + self.screen = pygame.display.set_mode((w, h), DISPLAY_FLAGS) + if hasattr(self.mod, 'screen'): + self.mod.screen.surface = self.screen + else: + self.mod.screen = pgzero.screen.Screen(self.screen) + screen = self.screen # KILL ME + self.width = w + self.height = h + + title = getattr(self.mod, 'TITLE', 'Pygame Zero Game') + if title != self.title: + pygame.display.set_caption(title) + self.title = title + + return changed + + @staticmethod + def show_default_icon(): + """Show a default icon loaded from Pygame Zero resources.""" + from io import BytesIO + from pkgutil import get_data + buf = BytesIO(get_data(__name__, 'data/icon.png')) + pygame.display.set_icon(pygame.image.load(buf)) + + EVENT_HANDLERS = { + pygame.MOUSEBUTTONDOWN: 'on_mouse_down', + pygame.MOUSEBUTTONUP: 'on_mouse_up', + pygame.MOUSEMOTION: 'on_mouse_move', + pygame.KEYDOWN: 'on_key_down', + pygame.KEYUP: 'on_key_up', + constants.MUSIC_END: 'on_music_end' + } + + def map_buttons(val): + return {c for c, pressed in zip(constants.mouse, val) if pressed} + + EVENT_PARAM_MAPPERS = { + 'buttons': map_buttons, + 'button': constants.mouse, + 'key': constants.keys + } + + def load_handlers(self): + from .spellcheck import spellcheck + spellcheck(vars(self.mod)) + self.handlers = {} + for type, name in self.EVENT_HANDLERS.items(): + handler = getattr(self.mod, name, None) + if callable(handler): + self.handlers[type] = self.prepare_handler(handler) + + def prepare_handler(self, handler): + """Adapt a pgzero game's raw handler function to take a Pygame Event. + + Returns a one-argument function of the form ``handler(event)``. + This will ensure that the correct arguments are passed to the raw + handler based on its argument spec. + + The wrapped handler will also map certain parameter values using + callables from EVENT_PARAM_MAPPERS; this ensures that the value of + 'button' inside the handler is a real instance of constants.mouse, + which means (among other things) that it will print as a symbolic value + rather than a naive integer. + + """ + code = handler.__code__ + param_names = code.co_varnames[:code.co_argcount] + + def make_getter(mapper, getter): + if mapper: + return lambda event: mapper(getter(event)) + return getter + + param_handlers = [] + for name in param_names: + getter = operator.attrgetter(name) + mapper = self.EVENT_PARAM_MAPPERS.get(name) + param_handlers.append((name, make_getter(mapper, getter))) + + def prep_args(event): + return {name: get(event) for name, get in param_handlers} + + def new_handler(event): + try: + prepped = prep_args(event) + except ValueError: + # If we couldn't construct the keys/mouse objects representing + # the button that was pressed, then skip the event handler. + # + # This happens because Pygame can generate key codes that it + # does not have constants for. + return + else: + return handler(**prepped) + + return new_handler + + def dispatch_event(self, event): + handler = self.handlers.get(event.type) + if handler: + self.need_redraw = True + handler(event) + + def get_update_func(self): + """Get a one-argument update function. + + If the module defines a function matching :: + + update(dt) + + or :: + + update() + + then this will be called. Otherwise return a no-op function. + + """ + try: + update = self.mod.update + except AttributeError: + return None + else: + if update.__code__.co_argcount == 0: + return lambda dt: update() + return update + + def get_draw_func(self): + """Get a draw function. + + If no draw function is define, raise an exception. + + """ + try: + draw = self.mod.draw + except AttributeError: + return lambda: None + else: + if draw.__code__.co_argcount != 0: + raise TypeError( + "draw() must not take any arguments." + ) + return draw + + def run(self): + """Invoke the main loop, and then clean up.""" + try: + self.mainloop() + finally: + pygame.display.quit() + pygame.mixer.quit() + + def mainloop(self): + """Run the main loop of Pygame Zero.""" + clock = pygame.time.Clock() + self.reinit_screen() + + update = self.get_update_func() + draw = self.get_draw_func() + self.load_handlers() + + pgzclock = pgzero.clock.clock + + self.need_redraw = True + while True: + dt = clock.tick(60) / 1000.0 + + for event in pygame.event.get(): + if event.type == pygame.QUIT: + return + if event.type == pygame.KEYDOWN: + if event.key == pygame.K_q and \ + event.mod & (pygame.KMOD_CTRL | pygame.KMOD_META): + sys.exit(0) + self.keyboard._press(event.key) + elif event.type == pygame.KEYUP: + self.keyboard._release(event.key) + self.dispatch_event(event) + + pgzclock.tick(dt) + + if update: + update(dt) + + screen_change = self.reinit_screen() + if screen_change or update or pgzclock.fired or self.need_redraw: + draw() + pygame.display.flip() + self.need_redraw = False diff --git a/venv/Lib/site-packages/pgzero/keyboard.py b/venv/Lib/site-packages/pgzero/keyboard.py new file mode 100644 index 0000000..260be42 --- /dev/null +++ b/venv/Lib/site-packages/pgzero/keyboard.py @@ -0,0 +1,60 @@ +import re +from warnings import warn + +from .constants import keys + +DEPRECATED_KEY_RE = re.compile(r'[A-Z]') +PREFIX_RE = re.compile(r'^K_(?!\d$)') + + +class Keyboard: + """The current state of the keyboard. + + Each attribute represents a key. For example, :: + + keyboard.a + + is True if the 'A' key is depressed, and False otherwise. + + """ + # The current key state. This may as well be a class attribute - there's + # only one keyboard. + _pressed = set() + + def __getattr__(self, kname): + if DEPRECATED_KEY_RE.match(kname): + warn( + "Uppercase keyboard attributes (eg. keyboard.%s) are " + "deprecated." % kname, + DeprecationWarning, + 2 + ) + kname = PREFIX_RE.sub('', kname) + try: + key = keys[kname.upper()] + except AttributeError: + raise AttributeError('The key "%s" does not exist' % key) + return key.value in self._pressed + + def _press(self, key): + """Called by Game to mark the key as pressed.""" + self._pressed.add(key) + + def _release(self, key): + """Called by Game to mark the key as released.""" + self._pressed.discard(key) + + def __getitem__(self, k): + if isinstance(k, keys): + return k.value in self._pressed + else: + warn( + "String lookup in keyboard (eg. keyboard[%r]) is " + "deprecated." % k, + DeprecationWarning, + 2 + ) + return getattr(self, k) + + +keyboard = Keyboard() diff --git a/venv/Lib/site-packages/pgzero/loaders.py b/venv/Lib/site-packages/pgzero/loaders.py new file mode 100644 index 0000000..67aaa86 --- /dev/null +++ b/venv/Lib/site-packages/pgzero/loaders.py @@ -0,0 +1,256 @@ +import os.path +import sys + +from types import ModuleType +import pygame.image +import pygame.mixer + +from . import ptext + + +# Root directory for loaders +# This is modified by calling set_root(), which is called by the game runner. +root = '.' + + +def set_root(path): + """Configure all loaders to load from the given root. + + path may be a file (such as a Python source file), in which case the root + is set to its containing directory. + + """ + global root + path = os.path.abspath(path) + if os.path.isdir(path): + root = path + else: + root = os.path.dirname(path) + sys.path.insert(0, root) + + +class InvalidCase(Exception): + """Indicate case errors early so they don't bite cross-platform users.""" + +try: + import win32api +except ImportError: + def real_path(path): + return path +else: + def real_path(path): + """Get the real capitalisation of a path on Windows.""" + if not os.path.exists(path): + return path + return win32api.GetLongPathNameW(win32api.GetShortPathName(path)) + + +def validate_lowercase(relpath): + if relpath.lower() != relpath: + raise InvalidCase( + "%r is not lower case.\n" + "You must use lower case filenames. This is to avoid " + "portability problems when run on another operating system " + "(because filenames on some operating systems are case-" + "sensitive and others are not)." % relpath + + ) + + +def validate_compatible_path(path): + """Validate that the given path can be loaded cross-platform.""" + relpath = os.path.relpath(path, root) + validate_lowercase(relpath) + + real = real_path(os.path.join(root, relpath)) + real_rel = os.path.relpath(real, root) + + if real_rel != relpath: + raise InvalidCase( + "%s is mis-capitalised on disk as %r.\nYou should rename it to be " + "correctly lowercase, for cross-platform portability." % ( + relpath, real_rel + ) + ) + + +class ResourceLoader: + """Abstract resource loader. + + A resource loader is a singleton; resources are loaded from a named + subdirectory of the global 'root'. The `.load()` method actually loads + a resource. + + Additionally, attribute access can be used to access and cache resources. + Dotted paths can be used to traverse directories. + + """ + def __init__(self, subpath): + self.subpath = subpath + self.cache = {} + self.have_root = False + + def validate_root(self, name): + r = self._root() + self.have_root = os.path.exists(r) + if self.have_root: + validate_compatible_path(r) + else: + raise KeyError( + "No '{subpath}' directory found to load {type} " + "'{name}'.".format( + subpath=self.subpath, type=self.TYPE, name=name + ) + ) + + def _root(self): + return os.path.join(root, self.subpath) + + @staticmethod + def cache_key(name, args, kwargs): + kwpairs = sorted(kwargs.items()) + return (name, args, tuple(kwpairs)) + + def load(self, name, *args, **kwargs): + key = self.cache_key(name, args, kwargs) + if key in self.cache: + return self.cache[key] + + if not self.have_root: + self.validate_root(name) + p = os.path.join(self._root(), name) + + if not os.path.isfile(p): + for ext in self.EXTNS: + p = os.path.join(self._root(), name + '.' + ext) + if os.path.exists(p): + break + else: + raise KeyError( + "No {type} found like '{name}'. " + "Are you sure the {type} exists?".format( + type=self.TYPE, + name=name + ) + ) + + validate_compatible_path(p) + res = self.cache[key] = self._load(p, *args, **kwargs) + return res + + def __getattr__(self, name): + p = os.path.join(self._root(), name) + if os.path.isdir(p): + resource = self.__class__(os.path.join(self.subpath, name)) + else: + try: + resource = self.load(name) + except KeyError as e: + raise AttributeError(*e.args) from None + + setattr(self, name, resource) + return resource + + +class ImageLoader(ResourceLoader): + EXTNS = ['png', 'gif', 'jpg', 'jpeg', 'bmp'] + TYPE = 'image' + + def _load(self, path): + return pygame.image.load(path).convert_alpha() + + +class UnsupportedFormat(Exception): + """The resource was not in a supported format.""" + + +class SoundLoader(ResourceLoader): + EXTNS = ['wav', 'ogg', 'oga'] + TYPE = 'sound' + + def _load(self, path): + try: + return pygame.mixer.Sound(path) + except pygame.error: + from .soundfmt import identify + try: + fmt = identify(path) + except Exception: + pass + else: + raise UnsupportedFormat(""" +'{0}' is not in a supported audio format. + +It appears to be: + + {1} + +Pygame supports uncompressed WAV files (PCM or ADPCM), compressed Ogg Vorbis +files, or MP3s, depending on the codecs installed. Try re-encoding the sound +file, for example using Audacity: + + http://audacityteam.org/ +""".format(path, fmt).strip()) from None + raise + + +class FontLoader(ResourceLoader): + EXTNS = ['ttf'] + TYPE = 'font' + + def _load(self, path, fontsize=None): + return pygame.font.Font(path, fontsize or ptext.DEFAULT_FONT_SIZE) + + +images = ImageLoader('images') +sounds = SoundLoader('sounds') +fonts = FontLoader('fonts') + +def getfont( + fontname=None, + fontsize=None, + sysfontname=None, + bold=None, + italic=None, + underline=None): + """Monkey-patch for ptext.getfont(). + + This will use our loader and therefore obey our case validation, caching + and so on. + + """ + fontname = fontname or ptext.DEFAULT_FONT_NAME + fontsize = fontsize or ptext.DEFAULT_FONT_SIZE + + key = ( + fontname, + fontsize, + sysfontname, + bold, + italic, + underline + ) + + if key in ptext._font_cache: + return ptext._font_cache[key] + + if fontname is None: + font = ptext._font_cache.get(key) + if font: + return font + font = pygame.font.Font(fontname, fontsize) + else: + font = fonts.load(fontname, fontsize) + + if bold is not None: + font.set_bold(bold) + if italic is not None: + font.set_italic(italic) + if underline is not None: + font.set_underline(underline) + + ptext._font_cache[key] = font + return font + + +ptext.getfont = getfont diff --git a/venv/Lib/site-packages/pgzero/music.py b/venv/Lib/site-packages/pgzero/music.py new file mode 100644 index 0000000..c49efa2 --- /dev/null +++ b/venv/Lib/site-packages/pgzero/music.py @@ -0,0 +1,110 @@ +from pygame.mixer import music as _music +from .loaders import ResourceLoader +from . import constants + + +__all__ = [ + 'rewind', 'stop', 'fadeout', 'set_volume', 'get_volume', 'get_pos', + 'set_pos', 'play', 'queue', 'pause', 'unpause', +] + +_music.set_endevent(constants.MUSIC_END) + + +class _MusicLoader(ResourceLoader): + """Pygame's music API acts as a singleton with one 'current' track. + + No objects are returned that represent different tracks, so this loader + can't return anything useful. But it can perform all the path name + validations and return the validated path, so that's what we do. + + This loader should not be exposed to the user. + + """ + EXTNS = ['mp3', 'ogg', 'oga'] + TYPE = 'music' + + def _load(self, path): + return path + +_loader = _MusicLoader('music') + + +# State of whether we are paused or not +_paused = False + + +def _play(name, loop): + global _paused + path = _loader.load(name) + _music.load(path) + _music.play(loop) + _paused = False + + +def play(name): + """Play a music file from the music/ directory. + + The music will loop when it finishes playing. + + """ + _play(name, -1) + + +def play_once(name): + """Play a music file from the music/ directory.""" + _play(name, 0) + + +def queue(name): + """Queue a music file to follow the current track. + + This will load a music file and queue it. A queued music file will begin as + soon as the current music naturally ends. If the current music is ever + stopped or changed, the queued song will be lost. + + """ + path = _loader.load(name) + _music.queue(path) + + +def is_playing(name): + """Return True if the music is playing and not paused.""" + return _music.get_busy() and not _paused + + +def pause(): + """Temporarily stop playback of the music stream. + + Call `unpause()` to resume. + + """ + global _paused + _music.pause() + _paused = True + + +def unpause(): + """Resume playback of the music stream after it has been paused.""" + global _paused + _music.unpause() + _paused = False + + +def fadeout(seconds): + """Fade out and eventually stop the music playback. + + :param seconds: The duration in seconds over which the sound will be faded + out. For example, to fade out over half a second, call + ``music.fadeout(0.5)``. + + """ + _music.fadeout(int(seconds * 1000)) + + +rewind = _music.rewind +stop = _music.stop +get_volume = _music.get_volume +set_volume = _music.set_volume +get_pos = _music.get_pos +set_pos = _music.set_pos diff --git a/venv/Lib/site-packages/pgzero/ptext.py b/venv/Lib/site-packages/pgzero/ptext.py new file mode 100644 index 0000000..22180ea --- /dev/null +++ b/venv/Lib/site-packages/pgzero/ptext.py @@ -0,0 +1,495 @@ +"""pygame-text - high-level text rendering with Pygame. + +This module is directly copied from + + https://github.com/cosmologicon/pygame-text + +at revision c04e59b7382a832e117f0598cdcbc1bb3eb26db5 +and used under CC0. + +""" +# ptext module: place this in your import directory. + +# ptext.draw(text, pos=None, **options) + +# Please see README.md for explanation of options. +# https://github.com/cosmologicon/pygame-text + +from __future__ import division + +from math import ceil, sin, cos, radians +import pygame + +DEFAULT_FONT_SIZE = 24 +REFERENCE_FONT_SIZE = 100 +DEFAULT_LINE_HEIGHT = 1.0 +DEFAULT_FONT_NAME = None +FONT_NAME_TEMPLATE = "%s" +DEFAULT_COLOR = "white" +DEFAULT_BACKGROUND = None +DEFAULT_OUTLINE_COLOR = "black" +DEFAULT_SHADOW_COLOR = "black" +OUTLINE_UNIT = 1 / 24 +SHADOW_UNIT = 1 / 18 +DEFAULT_ALIGN = "left" # left, center, or right +DEFAULT_ANCHOR = 0, 0 # 0, 0 = top left ; 1, 1 = bottom right +DEFAULT_STRIP = True +ALPHA_RESOLUTION = 16 +ANGLE_RESOLUTION_DEGREES = 3 + +AUTO_CLEAN = True +MEMORY_LIMIT_MB = 64 +MEMORY_REDUCTION_FACTOR = 0.5 + +pygame.font.init() + +_font_cache = {} + + +def getfont(fontname=None, fontsize=None, sysfontname=None, + bold=None, italic=None, underline=None): + if fontname is not None and sysfontname is not None: + raise ValueError("Can't set both fontname and sysfontname") + if fontname is None and sysfontname is None: + fontname = DEFAULT_FONT_NAME + if fontsize is None: + fontsize = DEFAULT_FONT_SIZE + key = fontname, fontsize, sysfontname, bold, italic, underline + if key in _font_cache: + return _font_cache[key] + if sysfontname is not None: + font = pygame.font.SysFont( + sysfontname, fontsize, bold or False, italic or False) + else: + if fontname is not None: + fontname = FONT_NAME_TEMPLATE % fontname + try: + font = pygame.font.Font(fontname, fontsize) + except IOError: + raise IOError("unable to read font filename: %s" % fontname) + if bold is not None: + font.set_bold(bold) + if italic is not None: + font.set_italic(italic) + if underline is not None: + font.set_underline(underline) + _font_cache[key] = font + return font + + +def wrap(text, fontname=None, fontsize=None, sysfontname=None, + bold=None, italic=None, underline=None, width=None, widthem=None, strip=None): + if widthem is None: + font = getfont(fontname, fontsize, sysfontname, + bold, italic, underline) + elif width is not None: + raise ValueError("Can't set both width and widthem") + else: + font = getfont(fontname, REFERENCE_FONT_SIZE, + sysfontname, bold, italic, underline) + width = widthem * REFERENCE_FONT_SIZE + if strip is None: + strip = DEFAULT_STRIP + texts = text.replace("\t", " ").split("\n") + lines = [] + for text in texts: + if strip: + text = text.rstrip(" ") + if width is None: + lines.append(text) + continue + if not text: + lines.append("") + continue + # Preserve leading spaces in all cases. + a = len(text) - len(text.lstrip(" ")) + # At any time, a is the rightmost known index you can legally split a line. I.e. it's legal + # to add text[:a] to lines, and line is what will be added to lines if + # text is split at a. + a = text.index(" ", a) if " " in text else len(text) + line = text[:a] + while a + 1 < len(text): + # b is the next legal place to break the line, with bline the + # corresponding line to add. + if " " not in text[a + 1:]: + b = len(text) + bline = text + elif strip: + # Lines may be split at any space character that immediately follows a non-space + # character. + b = text.index(" ", a + 1) + while text[b - 1] == " ": + if " " in text[b + 1:]: + b = text.index(" ", b + 1) + else: + b = len(text) + break + bline = text[:b] + else: + # Lines may be split at any space character, or any character immediately following + # a space character. + b = a + 1 if text[a] == " " else text.index(" ", a + 1) + bline = text[:b] + if font.size(bline)[0] <= width: + a, line = b, bline + else: + lines.append(line) + text = text[a:].lstrip(" ") if strip else text[a:] + a = text.index(" ", 1) if " " in text[1:] else len(text) + line = text[:a] + if text: + lines.append(line) + return lines + +_fit_cache = {} + + +def _fitsize(text, fontname, sysfontname, bold, italic, underline, width, height, lineheight, strip): + key = text, fontname, sysfontname, bold, italic, underline, width, height, lineheight, strip + if key in _fit_cache: + return _fit_cache[key] + + def fits(fontsize): + texts = wrap(text, fontname, fontsize, sysfontname, + bold, italic, underline, width, strip) + font = getfont(fontname, fontsize, sysfontname, + bold, italic, underline) + w = max(font.size(line)[0] for line in texts) + linesize = font.get_linesize() * lineheight + h = int(round((len(texts) - 1) * linesize)) + font.get_height() + return w <= width and h <= height + a, b = 1, 256 + if not fits(a): + fontsize = a + elif fits(b): + fontsize = b + else: + while b - a > 1: + c = (a + b) // 2 + if fits(c): + a = c + else: + b = c + fontsize = a + _fit_cache[key] = fontsize + return fontsize + + +def _resolvecolor(color, default): + if color is None: + color = default + if color is None: + return None + try: + return tuple(pygame.Color(color)) + except ValueError: + return tuple(color) + + +def _resolvealpha(alpha): + if alpha >= 1: + return 1 + return max(int(round(alpha * ALPHA_RESOLUTION)) / ALPHA_RESOLUTION, 0) + + +def _resolveangle(angle): + if not angle: + return 0 + angle %= 360 + return int(round(angle / ANGLE_RESOLUTION_DEGREES)) * ANGLE_RESOLUTION_DEGREES + +# Return the set of points in the circle radius r, using Bresenham's +# circle algorithm +_circle_cache = {} + + +def _circlepoints(r): + r = int(round(r)) + if r in _circle_cache: + return _circle_cache[r] + x, y, e = r, 0, 1 - r + _circle_cache[r] = points = [] + while x >= y: + points.append((x, y)) + y += 1 + if e < 0: + e += 2 * y - 1 + else: + x -= 1 + e += 2 * (y - x) - 1 + points += [(y, x) for x, y in points if x > y] + points += [(-x, y) for x, y in points if x] + points += [(x, -y) for x, y in points if y] + points.sort() + return points + +_surf_cache = {} +_surf_tick_usage = {} +_surf_size_total = 0 +_unrotated_size = {} +_tick = 0 + + +def getsurf(text, fontname=None, fontsize=None, sysfontname=None, bold=None, italic=None, + underline=None, width=None, widthem=None, strip=None, color=None, + background=None, antialias=True, ocolor=None, owidth=None, scolor=None, shadow=None, + gcolor=None, alpha=1.0, align=None, lineheight=None, angle=0, cache=True): + global _tick, _surf_size_total + if fontname is None: + fontname = DEFAULT_FONT_NAME + if fontsize is None: + fontsize = DEFAULT_FONT_SIZE + fontsize = int(round(fontsize)) + if align is None: + align = DEFAULT_ALIGN + if align in ["left", "center", "right"]: + align = [0, 0.5, 1][["left", "center", "right"].index(align)] + if lineheight is None: + lineheight = DEFAULT_LINE_HEIGHT + color = _resolvecolor(color, DEFAULT_COLOR) + background = _resolvecolor(background, DEFAULT_BACKGROUND) + gcolor = _resolvecolor(gcolor, None) + ocolor = None if owidth is None else _resolvecolor( + ocolor, DEFAULT_OUTLINE_COLOR) + scolor = None if shadow is None else _resolvecolor( + scolor, DEFAULT_SHADOW_COLOR) + opx = None if owidth is None else ceil(owidth * fontsize * OUTLINE_UNIT) + spx = None if shadow is None else tuple( + ceil(s * fontsize * SHADOW_UNIT) for s in shadow) + alpha = _resolvealpha(alpha) + angle = _resolveangle(angle) + strip = DEFAULT_STRIP if strip is None else strip + key = (text, fontname, fontsize, sysfontname, bold, italic, underline, width, widthem, strip, + color, background, antialias, ocolor, opx, scolor, spx, gcolor, alpha, align, lineheight, angle) + if key in _surf_cache: + _surf_tick_usage[key] = _tick + _tick += 1 + return _surf_cache[key] + texts = wrap(text, fontname, fontsize, sysfontname, bold, italic, underline, + width=width, widthem=widthem, strip=strip) + if angle: + surf0 = getsurf(text, fontname, fontsize, sysfontname, bold, italic, underline, + width, widthem, strip, color, background, antialias, + ocolor, owidth, scolor, shadow, gcolor, alpha, align, lineheight, cache=cache) + if angle in (90, 180, 270): + surf = pygame.transform.rotate(surf0, angle) + else: + surf = pygame.transform.rotozoom(surf0, angle, 1.0) + _unrotated_size[(surf.get_size(), angle, text)] = surf0.get_size() + elif alpha < 1.0: + surf0 = getsurf(text, fontname, fontsize, sysfontname, bold, italic, underline, + width, widthem, strip, color, background, antialias, + ocolor, owidth, scolor, shadow, gcolor=gcolor, align=align, + lineheight=lineheight, cache=cache) + surf = surf0.copy() + array = pygame.surfarray.pixels_alpha(surf) + array[:, :] = (array[:, :] * alpha).astype(array.dtype) + del array + elif spx is not None: + surf0 = getsurf(text, fontname, fontsize, sysfontname, bold, italic, underline, + width, widthem, strip, color=color, background=(0, 0, 0, 0), antialias=antialias, + gcolor=gcolor, align=align, lineheight=lineheight, cache=cache) + ssurf = getsurf(text, fontname, fontsize, sysfontname, bold, italic, underline, + width, widthem, strip, color=scolor, background=(0, 0, 0, 0), antialias=antialias, + align=align, lineheight=lineheight, cache=cache) + w0, h0 = surf0.get_size() + sx, sy = spx + surf = pygame.Surface((w0 + abs(sx), h0 + abs(sy))).convert_alpha() + surf.fill(background or (0, 0, 0, 0)) + dx, dy = max(sx, 0), max(sy, 0) + surf.blit(ssurf, (dx, dy)) + x0, y0 = abs(sx) - dx, abs(sy) - dy + if len(color) > 3 and color[3] == 0: + array = pygame.surfarray.pixels_alpha(surf) + array0 = pygame.surfarray.pixels_alpha(surf0) + array[x0:x0 + w0, y0:y0 + + h0] -= array0.clip(max=array[x0:x0 + w0, y0:y0 + h0]) + del array, array0 + else: + surf.blit(surf0, (x0, y0)) + elif opx is not None: + surf0 = getsurf(text, fontname, fontsize, sysfontname, bold, italic, underline, + width, widthem, strip, color=color, background=(0, 0, 0, 0), antialias=antialias, + gcolor=gcolor, align=align, lineheight=lineheight, cache=cache) + osurf = getsurf(text, fontname, fontsize, sysfontname, bold, italic, underline, + width, widthem, strip, color=ocolor, background=(0, 0, 0, 0), antialias=antialias, + align=align, lineheight=lineheight, cache=cache) + w0, h0 = surf0.get_size() + surf = pygame.Surface((w0 + 2 * opx, h0 + 2 * opx)).convert_alpha() + surf.fill(background or (0, 0, 0, 0)) + for dx, dy in _circlepoints(opx): + surf.blit(osurf, (dx + opx, dy + opx)) + if len(color) > 3 and color[3] == 0: + array = pygame.surfarray.pixels_alpha(surf) + array0 = pygame.surfarray.pixels_alpha(surf0) + array[opx:-opx, opx:- + opx] -= array0.clip(max=array[opx:-opx, opx:-opx]) + del array, array0 + else: + surf.blit(surf0, (opx, opx)) + else: + font = getfont(fontname, fontsize, sysfontname, + bold, italic, underline) + # pygame.Font.render does not allow passing None as an argument value + # for background. + if background is None or (len(background) > 3 and background[3] == 0) or gcolor is not None: + lsurfs = [font.render(text, antialias, color).convert_alpha() + for text in texts] + else: + lsurfs = [font.render(text, antialias, color, + background).convert_alpha() for text in texts] + if gcolor is not None: + import numpy + m = numpy.clip(numpy.arange( + lsurfs[0].get_height()) * 2.0 / font.get_ascent() - 1.0, 0, 1) + for lsurf in lsurfs: + array = pygame.surfarray.pixels3d(lsurf) + for j in (0, 1, 2): + array[:, :, j] = ( + (1.0 - m) * array[:, :, j] + m * gcolor[j]).astype(array.dtype) + del array + + if len(lsurfs) == 1 and gcolor is None: + surf = lsurfs[0] + else: + w = max(lsurf.get_width() for lsurf in lsurfs) + linesize = font.get_linesize() * lineheight + ys = [int(round(k * linesize)) for k in range(len(lsurfs))] + h = ys[-1] + font.get_height() + surf = pygame.Surface((w, h)).convert_alpha() + surf.fill(background or (0, 0, 0, 0)) + for y, lsurf in zip(ys, lsurfs): + x = int(round(align * (w - lsurf.get_width()))) + surf.blit(lsurf, (x, y)) + if cache: + w, h = surf.get_size() + _surf_size_total += 4 * w * h + _surf_cache[key] = surf + _surf_tick_usage[key] = _tick + _tick += 1 + return surf + +_default_surf_sentinel = () + + +def draw(text, pos=None, + fontname=None, fontsize=None, sysfontname=None, + antialias=True, bold=None, italic=None, underline=None, + color=None, background=None, + top=None, left=None, bottom=None, right=None, + topleft=None, bottomleft=None, topright=None, bottomright=None, + midtop=None, midleft=None, midbottom=None, midright=None, + center=None, centerx=None, centery=None, + width=None, widthem=None, lineheight=None, strip=None, + align=None, + owidth=None, ocolor=None, + shadow=None, scolor=None, + gcolor=None, + alpha=1.0, + anchor=None, + angle=0, + surf=_default_surf_sentinel, + cache=True): + + if topleft: + left, top = topleft + if bottomleft: + left, bottom = bottomleft + if topright: + right, top = topright + if bottomright: + right, bottom = bottomright + if midtop: + centerx, top = midtop + if midleft: + left, centery = midleft + if midbottom: + centerx, bottom = midbottom + if midright: + right, centery = midright + if center: + centerx, centery = center + + x, y = pos or (None, None) + hanchor, vanchor = anchor or (None, None) + if left is not None: + x, hanchor = left, 0 + if centerx is not None: + x, hanchor = centerx, 0.5 + if right is not None: + x, hanchor = right, 1 + if top is not None: + y, vanchor = top, 0 + if centery is not None: + y, vanchor = centery, 0.5 + if bottom is not None: + y, vanchor = bottom, 1 + if x is None: + raise ValueError("Unable to determine horizontal position") + if y is None: + raise ValueError("Unable to determine vertical position") + + if align is None: + align = hanchor + if hanchor is None: + hanchor = DEFAULT_ANCHOR[0] + if vanchor is None: + vanchor = DEFAULT_ANCHOR[1] + + tsurf = getsurf(text, fontname, fontsize, sysfontname, bold, italic, underline, width, widthem, + strip, color, background, antialias, ocolor, owidth, scolor, shadow, gcolor, alpha, align, + lineheight, angle, cache) + angle = _resolveangle(angle) + if angle: + w0, h0 = _unrotated_size[(tsurf.get_size(), angle, text)] + S, C = sin(radians(angle)), cos(radians(angle)) + dx, dy = (0.5 - hanchor) * w0, (0.5 - vanchor) * h0 + x += dx * C + dy * S - 0.5 * tsurf.get_width() + y += -dx * S + dy * C - 0.5 * tsurf.get_height() + else: + x -= hanchor * tsurf.get_width() + y -= vanchor * tsurf.get_height() + x = int(round(x)) + y = int(round(y)) + + if surf is _default_surf_sentinel: + surf = pygame.display.get_surface() + if surf is not None: + surf.blit(tsurf, (x, y)) + + if AUTO_CLEAN: + clean() + + return tsurf, (x, y) + + +def drawbox(text, rect, fontname=None, sysfontname=None, lineheight=None, anchor=None, + bold=None, italic=None, underline=None, strip=None, **kwargs): + if fontname is None: + fontname = DEFAULT_FONT_NAME + if lineheight is None: + lineheight = DEFAULT_LINE_HEIGHT + hanchor, vanchor = anchor = anchor or (0.5, 0.5) + rect = pygame.Rect(rect) + x = rect.x + hanchor * rect.width + y = rect.y + vanchor * rect.height + fontsize = _fitsize(text, fontname, sysfontname, bold, italic, underline, + rect.width, rect.height, lineheight, strip) + return draw(text, (x, y), fontname=fontname, fontsize=fontsize, lineheight=lineheight, + width=rect.width, strip=strip, anchor=anchor, **kwargs) + + +def clean(): + global _surf_size_total + memory_limit = MEMORY_LIMIT_MB * (1 << 20) + if _surf_size_total < memory_limit: + return + memory_limit *= MEMORY_REDUCTION_FACTOR + keys = sorted(_surf_cache, key=_surf_tick_usage.get) + for key in keys: + w, h = _surf_cache[key].get_size() + del _surf_cache[key] + del _surf_tick_usage[key] + _surf_size_total -= 4 * w * h + if _surf_size_total < memory_limit: + break diff --git a/venv/Lib/site-packages/pgzero/rect.py b/venv/Lib/site-packages/pgzero/rect.py new file mode 100644 index 0000000..38adff6 --- /dev/null +++ b/venv/Lib/site-packages/pgzero/rect.py @@ -0,0 +1,498 @@ +# -*- coding: utf-8 -*- +import pygame.rect + + +class Rect(pygame.rect.Rect): + __slots__ = () + + # From Pygame docs + VALID_ATTRIBUTES = """ + x y + top left bottom right + topleft bottomleft topright bottomright + midtop midleft midbottom midright + center centerx centery + size width height + w h + """.split() + + def __setattr__(self, key, value): + try: + pygame.rect.Rect.__setattr__(self, key, value) + except AttributeError as e: + from .spellcheck import suggest + suggestions = suggest(key, self.VALID_ATTRIBUTES) + msg = e.args[0] + if suggestions: + msg += "; did you mean {!r}?".format(suggestions[0]) + raise AttributeError(msg) from None + +Rect.__doc__ = pygame.rect.Rect.__doc__ + + +class NoIntersect(Exception): + pass + + +class ZRect: + """ZRect + + This is a Python implementation of the pygame Rect class. Its raison + d'être is to allow the coordinates to be floating point. All pygame + functions which require a rect allow for an object with a "rect" + attribute and whose coordinates will be converted to integers implictly. + + All functions which require a dict will use the flexible constructor + to convert from: this (or a subclass); a Pygame Rect; a 4-tuple or a + pair of 2-tuples. In addition, they'll recognise any object which has + an (optionally callable) .rect attribute whose value will be used instead. + """ + + _item_mapping = dict(enumerate("xywh")) + + def __init__(self, *args): + + if len(args) == 1: + args = tuple(self._handle_one_arg(args[0])) + + # + # At this point we have one of: + # + # x, y, w, h + # (x, y), (w, h) + # (x, y, w, h), + # + if len(args) == 4: + self.x, self.y, self.w, self.h = args + elif len(args) == 2: + (self.x, self.y), (self.w, self.h) = args + elif len(args) == 1: + self.x, self.y, self.w, self.h = args[0] + else: + raise TypeError("%s should be called with one, two or four arguments" % (cls.__name__)) + + self.rect = self + + def _handle_one_arg(self, arg): + """Handle -- possibly recursively -- the case of one parameter + + Pygame -- and consequently pgzero -- is very accommodating when constructing + a rect. You can pass four integers, two pairs of 2-tuples, or one 4-tuple. + + Also, you can pass an existing Rect-like object, or an object with a .rect + attribute. The object named by the .rect attribute is either one of the above, + or it's a callable object which returns one of the above. + + This is evidently a recursive solution where an object with a .rect + attribute can yield an object with a .rect attribute, and so ad infinitum. + """ + # + # If the arg is an existing rect, return its elements + # + if isinstance(arg, RECT_CLASSES): + return arg.x, arg.y, arg.w, arg.h + + # + # If it's something with a .rect attribute, start again with + # that attribute, calling it first if it's callable + # + if hasattr(arg, "rect"): + rectobj = arg.rect + if callable(rectobj): + rectobj = rectobj() + return self._handle_one_arg(rectobj) + + # + # Otherwise, we assume it's an iterable of four elements + # + return arg + + def __repr__(self): + return "<%s (x: %s, y: %s, w: %s, h: %s)>" % (self.__class__.__name__, self.x, self.y, self.w, self.h) + + def __reduce__(self): + return self.__class__, (self.x, self.y, self.w, self.h) + + def copy(self): + return self.__class__(self.x, self.y, self.w, self.h) + __copy__ = copy + + def __len__(self): + return 4 + + def __getitem__(self, item): + try: + return getattr(self, self._item_mapping[item]) + except KeyError: + raise IndexError + + def __setitem__(self, item, value): + try: + attribute = self._item_mapping[item] + except KeyError: + raise IndexError + else: + setattr(attribute, value) + + def __bool__(self): + return self.w != 0 and self.h != 0 + + def __iter__(self): + yield self.x + yield self.y + yield self.w + yield self.h + + def __hash__(self): + raise TypeError("ZRect instances may not be used as dictionary keys") + + def __eq__(self, *other): + rect = self.__class__(*other) + return (self.x, self.y, self.w, self.h) == (rect.x, rect.y, rect.w, rect.h) + + def __ne__(self, *other): + rect = self.__class__(*other) + return (self.x, self.y, self.w, self.h) != (rect.x, rect.y, rect.w, rect.h) + + def __lt__(self, *other): + rect = self.__class__(*other) + return (self.x, self.y, self.w, self.h) < (rect.x, rect.y, rect.w, rect.h) + + def __gt__(self, *other): + rect = self.__class__(*other) + return (self.x, self.y, self.w, self.h) > (rect.x, rect.y, rect.w, rect.h) + + def __le__(self, *other): + rect = self.__class__(*other) + return (self.x, self.y, self.w, self.h) <= (rect.x, rect.y, rect.w, rect.h) + + def __ge__(self, *other): + rect = self.__class__(*other) + return (self.x, self.y, self.w, self.h) >= (rect.x, rect.y, rect.w, rect.h) + + def __contains__(self, other): + """Test whether a point (x, y) or another rectangle + (anything accepted by ZRect) is contained within this ZRect + """ + if len(other) == 2: + return self.collidepoint(*other) + else: + return self.contains(*other) + + def _get_width(self): + return self.w + def _set_width(self, width): + self.w = width + width = property(_get_width, _set_width) + + def _get_height(self): + return self.h + def _set_height(self, height): + self.h = height + height = property(_get_height, _set_height) + + def _get_top(self): + return self.y + def _set_top(self, top): + self.y = top + top = property(_get_top, _set_top) + + def _get_left(self): + return self.x + def _set_left(self, left): + self.x = left + left = property(_get_left, _set_left) + + def _get_right(self): + return self.x + self.w + def _set_right(self, right): + self.x = right - self.w + right = property(_get_right, _set_right) + + def _get_bottom(self): + return self.y + self.h + def _set_bottom(self, bottom): + self.y = bottom - self.h + bottom = property(_get_bottom, _set_bottom) + + def _get_centerx(self): + return self.x + (self.w / 2) + def _set_centerx(self, centerx): + self.x = centerx - (self.w / 2) + centerx = property(_get_centerx, _set_centerx) + + def _get_centery(self): + return self.y + (self.h / 2) + def _set_centery(self, centery): + self.y = centery - (self.h / 2) + centery = property(_get_centery, _set_centery) + + def _get_topleft(self): + return self.x, self.y + def _set_topleft(self, topleft): + self.x, self.y = topleft + topleft = property(_get_topleft, _set_topleft) + + def _get_topright(self): + return self.x + self.w, self.y + def _set_topright(self, topright): + x, y = topright + self.x = x - self.w + self.y = y + topright = property(_get_topright, _set_topright) + + def _get_bottomleft(self): + return self.x, self.y + self.h + def _set_bottomleft(self, bottomleft): + x, y = bottomleft + self.x = x + self.y = y - self.h + bottomleft = property(_get_bottomleft, _set_bottomleft) + + def _get_bottomright(self): + return self.x + self.w, self.y + self.h + def _set_bottomright(self, bottomright): + x, y = bottomright + self.x = x - self.w + self.y = y - self.h + bottomright = property(_get_bottomright, _set_bottomright) + + def _get_midtop(self): + return self.x + self.w / 2, self.y + def _set_midtop(self, midtop): + x, y = midtop + self.x = x - self.w / 2 + self.y = y + midtop = property(_get_midtop, _set_midtop) + + def _get_midleft(self): + return self.x, self.y + self.h / 2 + def _set_midleft(self, midleft): + x, y = midleft + self.x = x + self.y = y - self.h / 2 + midleft = property(_get_midleft, _set_midleft) + + def _get_midbottom(self): + return self.x + self.w / 2, self.y + self.h + def _set_midbottom(self, midbottom): + x, y = midbottom + self.x = x - self.w / 2 + self.y = y - self.h + midbottom = property(_get_midbottom, _set_midbottom) + + def _get_midright(self): + return self.x + self.w, self.y + self.h / 2 + def _set_midright(self, midright): + x, y = midright + self.x = x - self.w + self.y = y - self.h / 2 + midright = property(_get_midright, _set_midright) + + def _get_center(self): + return self.x + self.w / 2, self.y + self.h / 2 + def _set_center(self, center): + x, y = center + self.x = x - self.w / 2 + self.y = y - self.h / 2 + center = property(_get_center, _set_center) + + def _get_size(self): + return self.w, self.h + def _set_size(self, size): + self.w, self.h = size + size = property(_get_size, _set_size) + + def move(self, x, y): + return self.__class__(self.x + x, self.y + y, self.w, self.h) + + def move_ip(self, x, y): + self.x += x + self.y += y + + def _inflated(self, x, y): + return self.x - x / 2, self.y - y / 2, self.w + x, self.h + y + + def inflate(self, x, y): + return self.__class__(*self._inflated(x, y)) + + def inflate_ip(self, x, y): + self.x, self.y, self.w, self.h = self._inflated(x, y) + + def _clamped(self, *other): + rect = self.__class__(*other) + + if self.w >= rect.w: + x = rect.x + rect.w / 2 - self.w / 2 + elif self.x < rect.x: + x = rect.x + elif self.x + self.w > rect.x + rect.w: + x = rect.x + rect.w - self.w + else: + x = self.x + + if self.h >= rect.h: + y = rect.y + rect.h / 2 - self.h / 2 + elif self.y < rect.y: + y = rect.y + elif self.y + self.h > rect.y + rect.h: + y = rect.y + rect.h - self.h + else: + y = self.y + + return x, y + + def clamp(self, *other): + rect = self.__class__(*other) + x, y = self._clamped(rect) + return self.__class__(x, y, self.w, self.h) + + def clamp_ip(self, *other): + rect = self.__class__(*other) + self.x, self.y = self._clamped(rect) + + def _clipped(self, *other): + rect = self.__class__(*other) + + if self.x >= rect.x and self.x < (rect.x + rect.w): + x = self.x + elif rect.x >= self.x and rect.x < (self.x + self.w): + x = rect.x + else: + raise NoIntersect + + if (self.x + self.w) > rect.x and (self.x + self.w) <= (rect.x + rect.w): + w = self.x + self.w - x + elif (rect.x + rect.w) > self.x and (rect.x + rect.w) <= (self.x + self.w): + w = rect.x + rect.w - x + else: + raise NoIntersect + + if self.y >= rect.y and self.y < (rect.y + rect.h): + y = self.y + elif rect.y >= self.y and rect.y < (self.y + self.h): + y = rect.y + else: + raise NoIntersect + + if (self.y + self.h) > rect.y and (self.y + self.h) <= (rect.y + rect.h): + h = self.y + self.h - y + elif (rect.y + rect.h) > self.y and (rect.y + rect.h) <= (self.y + self.h): + h = rect.y + rect.h - y + else: + raise NoIntersect + + return x, y, w, h + + def clip(self, *other): + rect = self.__class__(*other) + try: + x, y, w, h = self._clipped(rect) + except NoIntersect: + x, y, w, h = self.x, self.y, 0, 0 + return self.__class__(x, y, w, h) + + def clip_ip(self, *other): + rect = self.__class__(*other) + try: + self.x, self.y, self.w, self.h = self._clipped(rect) + except NoIntersect: + self.x, self.y, self.w, self.h = self.x, self.y, 0, 0 + + def _unioned(self, *other): + rect = self.__class__(*other) + x = min(self.x, rect.x) + y = min(self.y, rect.y) + w = max(self.x + self.w, rect.x + rect.w) - x + h = max(self.y + self.h, rect.y + rect.h) - y + return x, y, w, h + + def union(self, *other): + rect = self.__class__(*other) + return self.__class__(*self._unioned(rect)) + + def union_ip(self, *other): + rect = self.__class__(*other) + self.x, self.y, self.w, self.h = self._unioned(rect) + + def _unionalled(self, others): + allrects = [self] + [self.__class__(other) for other in others] + x = min(r.x for r in allrects) + y = min(r.y for r in allrects) + w = max(r.x + r.w for r in allrects) - x + h = max(r.y + r.h for r in allrects) - y + return x, y, w, h + + def unionall(self, others): + return self.__class__(*self._unionalled(others)) + + def unionall_ip(self, others): + self.x, self.y, self.w, self.h = self._unionalled(others) + + def fit(self, *other): + rect = self.__class__(*other) + ratio = max(self.w / rect.w, self.h / rect.h) + w = self.w / ratio + h = self.h / ratio + x = rect.x + (rect.w - w) / 2 + y = rect.y + (rect.h - h) / 2 + return self.__class__(x, y, w, h) + + def normalize(self): + if self.w < 0: + self.x += self.w + self.w = abs(self.w) + if self.h < 0: + self.y += self.h + self.h = abs(self.h) + + def contains(self, *other): + rect = self.__class__(*other) + return ( + self.x <= rect.x and + self.y <= rect.y and + self.x + self.w >= rect.x + rect.w and + self.y + self.h >= rect.y + rect.h and + self.x + self.w > rect.x and + self.y + self.h > rect.y + ) + + def collidepoint(self, *args): + if len(args) == 1: + x, y = args[0] + else: + x, y = args + return ( + self.x <= x < (self.x + self.w) and + self.y <= y < (self.y + self.h) + ) + + def colliderect(self, *other): + rect = self.__class__(*other) + return ( + self.x < rect.x + rect.w and + self.y < rect.y + rect.h and + self.x + self.w > rect.x and + self.y + self.h > rect.y + ) + + def collidelist(self, others): + for n, other in enumerate(others): + if self.colliderect(other): + return n + else: + return -1 + + def collidelistall(self, others): + return [n for n, other in enumerate(others) if self.colliderect(other)] + + def collidedict(self, dict, use_values=True): + for k, v in dict.items(): + if self.colliderect(v if use_values else k): + return k, v + + def collidedictall(self, dict, use_values=True): + return [(k, v) for (k, v) in dict.items() if self.colliderect(v if use_values else k)] + + +RECT_CLASSES = (pygame.rect.Rect, ZRect) diff --git a/venv/Lib/site-packages/pgzero/runner.py b/venv/Lib/site-packages/pgzero/runner.py new file mode 100644 index 0000000..c2c8e9e --- /dev/null +++ b/venv/Lib/site-packages/pgzero/runner.py @@ -0,0 +1,113 @@ +import pygame +pygame.mixer.pre_init(frequency=22050, size=-16, channels=2) +pygame.init() + + +import os +import sys +import warnings +from optparse import OptionParser +from types import ModuleType + +from .game import PGZeroGame, DISPLAY_FLAGS +from . import loaders +from . import builtins + + +def _check_python_ok_for_pygame(): + """If we're on a Mac, is this a full Framework python? + + There is a problem with PyGame on Macs running in a virtual env. + If the Python used is from the venv, it will not allow full window and + keyboard interaction. Instead, we need the original framework Python + to get PyGame working properly. + + The problem doesn't occur on Linux and Windows. + """ + if sys.platform == 'darwin': # This is a Mac + return 'Library/Frameworks' in sys.executable + else: + return True + + +def _substitute_full_framework_python(): + """Need to change the OS/X Python executable to the full Mac version, + while maintaining the virtualenv environment, so things still run + in an encapsulated way. + + We do this by extract the paths that virtualenv has added to the system + path, and prefixing them to the current PYTHONPATH. + + Then we use os.execv() to start a replacement process that uses the + same environment as the previous one. + """ + PYVER = '{}.{}'.format(*sys.version_info[:2]) + base_fw = '/Library/Frameworks/Python.framework/Versions/' + framework_python = base_fw + '{pv}/bin/python{pv}'.format(pv=PYVER) + venv_base = os.environ.get('VIRTUAL_ENV') + if not venv_base or not os.path.exists(framework_python): + # Do nothing if virtual env hasn't been set up or if we can't + # find the framework Python interpreter + return + venv_paths = [p for p in sys.path if p.startswith(venv_base)] + # Need to allow for PYTHONPATH not already existing in environment + os.environ['PYTHONPATH'] = ':'.join(venv_paths + [ + os.environ.get('PYTHONPATH', '')]).rstrip(':') + # Pass command line args to the new process + os.execv(framework_python, ['python', '-m', 'pgzero'] + sys.argv[1:]) + + +def main(): + + # Pygame won't run from a normal virtualenv copy of Python on a Mac + if not _check_python_ok_for_pygame(): + _substitute_full_framework_python() + + parser = OptionParser() + options, args = parser.parse_args() + + if len(args) != 1: + parser.error("You must specify which module to run.") + + if __debug__: + warnings.simplefilter('default', DeprecationWarning) + path = args[0] + + with open(path) as f: + src = f.read() + + code = compile(src, os.path.basename(path), 'exec', dont_inherit=True) + + name, _ = os.path.splitext(os.path.basename(path)) + mod = ModuleType(name) + mod.__file__ = path + mod.__name__ = name + sys.modules[name] = mod + + # Indicate that we're running with the pgzrun runner + # This disables the 'import pgzrun' module + sys._pgzrun = True + + prepare_mod(mod) + exec(code, mod.__dict__) + run_mod(mod) + + +def prepare_mod(mod): + """Prepare a module to run as a Pygame Zero program. + + mod is a loaded module object. + + This sets up things like screen, loaders and builtins, which need to be + set before the module globals are run. + + """ + loaders.set_root(mod.__file__) + PGZeroGame.show_default_icon() + pygame.display.set_mode((100, 100), DISPLAY_FLAGS) + mod.__dict__.update(builtins.__dict__) + + +def run_mod(mod): + """Run the module.""" + PGZeroGame(mod).run() diff --git a/venv/Lib/site-packages/pgzero/screen.py b/venv/Lib/site-packages/pgzero/screen.py new file mode 100644 index 0000000..52abf8d --- /dev/null +++ b/venv/Lib/site-packages/pgzero/screen.py @@ -0,0 +1,105 @@ +import pygame +import pygame.draw +from . import ptext +from .rect import RECT_CLASSES +from . import loaders + + +def round_pos(pos): + """Round a tuple position so it can be used for drawing.""" + x, y = pos + return round(x), round(y) + + +def make_color(arg): + if isinstance(arg, tuple): + return arg + return tuple(pygame.Color(arg)) + + +class SurfacePainter: + """Interface to pygame.draw that is bound to a surface.""" + + def __init__(self, screen): + self._screen = screen + + @property + def _surf(self): + return self._screen.surface + + def line(self, start, end, color): + """Draw a line from start to end.""" + start = round_pos(start) + end = round_pos(end) + pygame.draw.line(self._surf, make_color(color), start, end, 1) + + def circle(self, pos, radius, color): + """Draw a circle.""" + pos = round_pos(pos) + pygame.draw.circle(self._surf, make_color(color), pos, radius, 1) + + def filled_circle(self, pos, radius, color): + """Draw a filled circle.""" + pos = round_pos(pos) + pygame.draw.circle(self._surf, make_color(color), pos, radius, 0) + + def rect(self, rect, color): + """Draw a rectangle.""" + if not isinstance(rect, RECT_CLASSES): + raise TypeError("screen.draw.rect() requires a rect to draw") + pygame.draw.rect(self._surf, make_color(color), rect, 1) + + def filled_rect(self, rect, color): + """Draw a filled rectangle.""" + if not isinstance(rect, RECT_CLASSES): + raise TypeError("screen.draw.filled_rect() requires a rect to draw") + pygame.draw.rect(self._surf, make_color(color), rect, 0) + + def text(self, *args, **kwargs): + """Draw text to the screen.""" + #FIXME: expose ptext parameters, for autocompletion and autodoc + ptext.draw(*args, surf=self._surf, **kwargs) + + def textbox(self, *args, **kwargs): + """Draw text to the screen, wrapped to fit a box""" + #FIXME: expose ptext parameters, for autocompletion and autodoc + ptext.drawbox(*args, surf=self._surf, **kwargs) + + +class Screen: + """Interface to the screen.""" + def __init__(self, surface): + self.surface = surface + self.width, self.height = surface.get_size() + + def clear(self): + """Clear the screen to black.""" + self.fill((0, 0, 0)) + + def fill(self, color): + """Fill the screen with a colour.""" + self.surface.fill(make_color(color)) + + def blit(self, image, pos): + """Draw a sprite onto the screen. + + "blit" is an archaic name for this operation, but one that is is still + frequently used, for example in Pygame. See the `Wikipedia article`__ + for more about the etymology of the term. + + .. __: http://en.wikipedia.org/wiki/Bit_blit + + :param image: A Surface or the name of an image object to load. + :param pos: The coordinates at which the top-left corner of the sprite + will be positioned. This may be given as a pair of + coordinates or as a Rect. If a Rect is given the sprite + will be drawn at ``rect.topleft``. + + """ + if isinstance(image, str): + image = loaders.images.load(image) + self.surface.blit(image, pos) + + @property + def draw(self): + return SurfacePainter(self) diff --git a/venv/Lib/site-packages/pgzero/soundfmt.py b/venv/Lib/site-packages/pgzero/soundfmt.py new file mode 100644 index 0000000..b1e6e33 --- /dev/null +++ b/venv/Lib/site-packages/pgzero/soundfmt.py @@ -0,0 +1,109 @@ +"""Identify WAV file formats. + +This is used only to give better error messages in the event that a sound +file is not loadable by Pygame. + +This is based on the 'magic' information for the 'file' command, at + +https://github.com/file/file/blob/86e34444a26860f2ad9895a2d77cb16d1ca4c48b/magic/Magdir/riff + +""" + +from struct import unpack_from + + +class MagicReader: + """Interface to reading the magic numbers in a file's header.""" + def __init__(self, path): + with open(path, 'rb') as f: + self.bytes = f.read(64 * 1024) + + def read_bytes(self, offset, length=4): + return self.bytes[offset:offset + length] + + def read_leshort(self, offset): + """Read an unsigned short at the given offset.""" + return unpack_from(' 1 and j > 1 and ca == b[j - 2] and a[i - 2] == cb: + d[i, j] = min( + d[i, j], + d[i - 2, j - 2] + cost # transposition + ) + + return d[la, lb] + + +def suggest(word, candidates): + """Suggest good candidates as corrections for the given word. + + Suggestions will be ordered from best to worst. + + """ + candidates_with_score = [(c, distance(word, c)) for c in candidates] + good_candidates = [(c, d) for c, d in candidates_with_score if d < 2.6] + good_candidates.sort(key=itemgetter(1)) + # print(word, good_candidates) + return [c for c, d in good_candidates] + + +def compare(have, want): + """Compare a set of names we have (from user input) to those we want. + + This is a greedy algorithm that will take the best answer for each word + in have in turn. + + """ + want = set(want) + have = set(have) + matched = want & have + want -= matched + have -= matched + for w in have: + suggestions = suggest(w, want) + if suggestions: + s = suggestions[0] + yield w, s + want.discard(s) + + +# The list of hooks we support +HOOKS = [ + 'draw', + 'update', +] + list(PGZeroGame.EVENT_HANDLERS.values()) + + +# The list of magic module-level constants +CONSTS = [ + 'TITLE', + 'WIDTH', + 'HEIGHT', + 'ICON' +] + +# Available parameters for each hook +# NB. update() takes one or zero positional parameter but we don't constrain +# the name. +# +# FIXME: These are from the documentation; there could be some missing here +VALID_PARAMS = { + 'on_mouse_down': ['pos', 'button'], + 'on_mouse_up': ['pos', 'button'], + 'on_mouse_move': ['pos', 'buttons', 'rel'], + 'on_key_up': ['key', 'mod'], + 'on_key_down': ['unicode', 'key', 'mod'], + 'draw': [], + 'on_music_end': [], +} + + +class InvalidParameter(Exception): + """A parameter to a hook was invalid.""" + + +class SpellCheckResult: + def warn(self, msg, found, suggestion): + print(msg.format( + found=found, + suggestion=suggestion + )) + + def error(self, msg, found, suggestion): + raise InvalidParameter(msg.format( + found=found, + suggestion=suggestion + )) + + +def spellcheck(namespace, result=SpellCheckResult()): + """Spell check the names in the given module. + + Where hooks are found, validate their positional parameters and offer + suggestions where mispelled. + + """ + funcs = {} + consts = [] + for name, val in namespace.items(): + if callable(val) and not isinstance(val, type): + funcs[name] = val + elif isinstance(val, (str, int)): + consts.append(name) + + for found, suggestion in compare(funcs, HOOKS): + result.warn( + "Warning: found function named {found}: " + "did you mean {suggestion}?", + found, suggestion + ) + + for found, suggestion in compare(consts, CONSTS): + result.warn( + "Warning: found constant named {found}: " + "did you mean {suggestion}?", + found, suggestion + ) + + for name, handler in funcs.items(): + try: + valid = VALID_PARAMS[name] + except KeyError: + continue + else: + param_names = positional_parameters(handler) + for param in param_names: + if param in valid: + continue + suggestions = suggest(param, valid) + if suggestions: + result.error( + "%s() hook accepts no parameter {found}; " + "did you mean {suggestion}?" % name, + param, + suggestions[0] + ) + else: + result.error( + "%s() hook accepts no parameter {found}" % name, + param, None + ) diff --git a/venv/Lib/site-packages/pgzero/tone.py b/venv/Lib/site-packages/pgzero/tone.py new file mode 100644 index 0000000..04d0b58 --- /dev/null +++ b/venv/Lib/site-packages/pgzero/tone.py @@ -0,0 +1,191 @@ +"""Tone generator for Pygame Zero. + +This tone generator uses numpy to generate sounds on demand at a given duration +and frequency. These are kept in a LRU cache which in typical applications +will reduce the number of times they need to be regenerated. + +Rather than generating plain sine waves, tones are shaped by a basic and +hard-coded `Attack Decay Sustain Release (ADSR) envelope`__, which gives them a +slightly more sonorous timbre: + +.. __: https://en.wikipedia.org/wiki/Synthesizer#ADSR_envelope + +The approach we use here, generating sound samples in memory, is memory hungry +and can introduce pauses when tones are generated. Currently tones generate in +under 1ms on a 2.4GHz i7. + +To minimise the extent that pauses affect gameplay, the ``play()`` function +offloads tone generation to a separate thread. Because tones are generated +with numpy operations this should allow at least part of this work to happen +on another CPU core, if present. + +""" + +from timeit import default_timer +import re +from functools import lru_cache + +import math +import pygame +try: + import numpy as np +except ImportError: + np = None +import pygame.sndarray +from threading import Thread, Lock +from queue import Queue + +__all__ = ( + 'play', + 'create', +) + +SAMPLE_RATE = 22050 + +NOTE_PATTERN = r'^([A-G])([b#]?)([0-8])$' + +A4 = 440.0 + +NOTE_VALUE = dict(C=-9, D=-7, E=-5, F=-4, G=-2, A=0, B=2) + +TWELTH_ROOT = math.pow(2, (1 / 12)) + +# Number of samples to decay for +DECAY = 2000 + +# Longest note to allow +MAX_DURATION = 4 + + +# lru_cache isn't threadsafe until Python 3.7, so protect it ourselves +# https://bugs.python.org/issue28969 +cache_lock = Lock() +note_queue = Queue() + + +def _play_thread(): + """Play any notes requested by the game thread. + + Multithreading is useful because numpy releases the GIL while performing + many C operations. + + """ + while True: + args = note_queue.get() + with cache_lock: + note = _create(*args) + note.play() + +player_thread = Thread(target=_play_thread) +player_thread.setDaemon(True) + + +def sine_array_onecycle(hz): + """Returns a single sin wave for a given frequency.""" + length = SAMPLE_RATE / hz + omega = np.pi * 2 / length + xvalues = np.arange(int(length)) * omega + return (np.sin(xvalues) * (2 ** 15)).astype(np.int16) + + +def create(pitch, duration): + """Create a tone of a given duration at the given pitch. + + Return a Sound which can be played later. + + """ + with cache_lock: + return _create(*_convert_args(pitch, duration)) + + +@lru_cache() +def _create(hz, samples): + """Actually create a tone.""" + end = samples + DECAY + + # Construct a mono tone of the right length + cycle = sine_array_onecycle(hz) + tone = np.resize(cycle, end) + + # Multiply it with an ADSR envelope + # See https://en.wikipedia.org/wiki/Synthesizer#ADSR_envelope + if samples < 1000: + volumes = [0, 1, 0.9, 0] + volume_times = [0, samples * 0.1, samples, end] + else: + volumes = [0, 1.0, 0.7, 0.7, 0] + volume_times = [0, 350, 1000, samples, end] + adsr = np.interp(np.arange(end), volume_times, volumes) + np.multiply(tone, adsr, out=tone, casting='unsafe') + + stereo = np.repeat(np.expand_dims(tone, axis=1), 2, axis=1) + return pygame.sndarray.make_sound(stereo) + + +class InvalidNote(Exception): + """The parameters passed were invalid.""" + + +@lru_cache() +def note_to_hertz(note): + note, accidental, octave = validate_note(note) + value = note_value(note, accidental, octave) + return A4 * math.pow(TWELTH_ROOT, value) + + +def note_value(note, accidental, octave): + value = NOTE_VALUE[note] + if accidental: + value += 1 if accidental == '#' else -1 + return (4 - octave) * -12 + value + + +def validate_note(note): + match = re.match(NOTE_PATTERN, note) + if match is None: + raise InvalidNote( + '%s is not a valid note. ' + 'notes are A-F, are either normal, flat (b) or sharp (#) ' + 'and of octave 0-8' % note + ) + note, accidental, octave = match.group(1, 2, 3) + return note, accidental, int(octave) + + +def _convert_args(hz, duration): + """Convert the given arguments to _create parameters.""" + if isinstance(hz, str): + hz = note_to_hertz(hz) + samples = int(duration * SAMPLE_RATE) + if not samples: + raise InvalidNote("Note has zero duration") + return hz, samples + + +def play(pitch, duration): + """Plays a tone of a certain length from a note or frequency in hertz. + + Tones have a maximum duration of 4 seconds. This limitation is imposed to + avoid accidentally creating sounds that take too long to generate and + require a lot of memory. + + To work around this, create the sounds you want to use up-front with + create() and hold onto them, perhaps in an array. + + """ + if duration > MAX_DURATION: + raise InvalidNote( + 'Note duration %ss is too long: notes may be at most %ss long' % + (duration, MAX_DURATION) + ) + args = _convert_args(pitch, duration) + if not player_thread.is_alive(): + player_thread.start() + note_queue.put(args) + + +if np is None: + def play(hz, length): + raise RuntimeError( + 'Tone generation depends on Numpy, which is not available' + ) diff --git a/venv/Lib/site-packages/pgzrun.py b/venv/Lib/site-packages/pgzrun.py new file mode 100644 index 0000000..4aca4b7 --- /dev/null +++ b/venv/Lib/site-packages/pgzrun.py @@ -0,0 +1,31 @@ +"""Runner system for Pygame Zero. + +By importing this module, the __main__ module is populated with the builtins +provided by Pygame Zero. + +When pgzrun.go() is called, the __main__ module is run as a Pygame Zero +script (we enter the game loop, calling draw() and update() etc as defined in +__main__). + +""" +import sys +import os +from pgzero.runner import prepare_mod, run_mod + + +mod = sys.modules['__main__'] +if not getattr(sys, '_pgzrun', None): + if not getattr(mod, '__file__', None): + raise ImportError( + "You are running from an interactive interpreter.\n" + "'import pgzrun' only works when you are running a Python file." + ) + prepare_mod(mod) + + +def go(): + """Run the __main__ module as a Pygame Zero script.""" + if getattr(sys, '_pgzrun', None): + return + + run_mod(mod) diff --git a/venv/Lib/site-packages/pip-21.0.1.dist-info/INSTALLER b/venv/Lib/site-packages/pip-21.0.1.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/venv/Lib/site-packages/pip-21.0.1.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/venv/Lib/site-packages/pip-21.0.1.dist-info/LICENSE.txt b/venv/Lib/site-packages/pip-21.0.1.dist-info/LICENSE.txt new file mode 100644 index 0000000..75eb0fd --- /dev/null +++ b/venv/Lib/site-packages/pip-21.0.1.dist-info/LICENSE.txt @@ -0,0 +1,20 @@ +Copyright (c) 2008-2020 The pip developers (see AUTHORS.txt file) + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/venv/Lib/site-packages/pip-21.0.1.dist-info/METADATA b/venv/Lib/site-packages/pip-21.0.1.dist-info/METADATA new file mode 100644 index 0000000..5b66e8e --- /dev/null +++ b/venv/Lib/site-packages/pip-21.0.1.dist-info/METADATA @@ -0,0 +1,92 @@ +Metadata-Version: 2.1 +Name: pip +Version: 21.0.1 +Summary: The PyPA recommended tool for installing Python packages. +Home-page: https://pip.pypa.io/ +Author: The pip developers +Author-email: distutils-sig@python.org +License: MIT +Project-URL: Documentation, https://pip.pypa.io +Project-URL: Source, https://github.com/pypa/pip +Project-URL: Changelog, https://pip.pypa.io/en/stable/news/ +Keywords: distutils easy_install egg setuptools wheel virtualenv +Platform: UNKNOWN +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: MIT License +Classifier: Topic :: Software Development :: Build Tools +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3 :: Only +Classifier: Programming Language :: Python :: 3.6 +Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: 3.8 +Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: Implementation :: CPython +Classifier: Programming Language :: Python :: Implementation :: PyPy +Requires-Python: >=3.6 + +pip - The Python Package Installer +================================== + +.. image:: https://img.shields.io/pypi/v/pip.svg + :target: https://pypi.org/project/pip/ + +.. image:: https://readthedocs.org/projects/pip/badge/?version=latest + :target: https://pip.pypa.io/en/latest + +pip is the `package installer`_ for Python. You can use pip to install packages from the `Python Package Index`_ and other indexes. + +Please take a look at our documentation for how to install and use pip: + +* `Installation`_ +* `Usage`_ + +We release updates regularly, with a new version every 3 months. Find more details in our documentation: + +* `Release notes`_ +* `Release process`_ + +In pip 20.3, we've `made a big improvement to the heart of pip`_; `learn more`_. We want your input, so `sign up for our user experience research studies`_ to help us do it right. + +**Note**: pip 21.0, in January 2021, removed Python 2 support, per pip's `Python 2 support policy`_. Please migrate to Python 3. + +If you find bugs, need help, or want to talk to the developers, please use our mailing lists or chat rooms: + +* `Issue tracking`_ +* `Discourse channel`_ +* `User IRC`_ + +If you want to get involved head over to GitHub to get the source code, look at our development documentation and feel free to jump on the developer mailing lists and chat rooms: + +* `GitHub page`_ +* `Development documentation`_ +* `Development mailing list`_ +* `Development IRC`_ + +Code of Conduct +--------------- + +Everyone interacting in the pip project's codebases, issue trackers, chat +rooms, and mailing lists is expected to follow the `PSF Code of Conduct`_. + +.. _package installer: https://packaging.python.org/guides/tool-recommendations/ +.. _Python Package Index: https://pypi.org +.. _Installation: https://pip.pypa.io/en/stable/installing.html +.. _Usage: https://pip.pypa.io/en/stable/ +.. _Release notes: https://pip.pypa.io/en/stable/news.html +.. _Release process: https://pip.pypa.io/en/latest/development/release-process/ +.. _GitHub page: https://github.com/pypa/pip +.. _Development documentation: https://pip.pypa.io/en/latest/development +.. _made a big improvement to the heart of pip: https://pyfound.blogspot.com/2020/11/pip-20-3-new-resolver.html +.. _learn more: https://pip.pypa.io/en/latest/user_guide/#changes-to-the-pip-dependency-resolver-in-20-3-2020 +.. _sign up for our user experience research studies: https://pyfound.blogspot.com/2020/03/new-pip-resolver-to-roll-out-this-year.html +.. _Python 2 support policy: https://pip.pypa.io/en/latest/development/release-process/#python-2-support +.. _Issue tracking: https://github.com/pypa/pip/issues +.. _Discourse channel: https://discuss.python.org/c/packaging +.. _Development mailing list: https://mail.python.org/mailman3/lists/distutils-sig.python.org/ +.. _User IRC: https://webchat.freenode.net/?channels=%23pypa +.. _Development IRC: https://webchat.freenode.net/?channels=%23pypa-dev +.. _PSF Code of Conduct: https://github.com/pypa/.github/blob/main/CODE_OF_CONDUCT.md + + diff --git a/venv/Lib/site-packages/pip-21.0.1.dist-info/RECORD b/venv/Lib/site-packages/pip-21.0.1.dist-info/RECORD new file mode 100644 index 0000000..9e8a697 --- /dev/null +++ b/venv/Lib/site-packages/pip-21.0.1.dist-info/RECORD @@ -0,0 +1,761 @@ +../../Scripts/pip.exe,sha256=OneOM_8yvgiF_Tbk5BavnWnyHGDeVATCXV1dLaU5Uho,106358 +../../Scripts/pip3.9.exe,sha256=OneOM_8yvgiF_Tbk5BavnWnyHGDeVATCXV1dLaU5Uho,106358 +../../Scripts/pip3.exe,sha256=OneOM_8yvgiF_Tbk5BavnWnyHGDeVATCXV1dLaU5Uho,106358 +pip-21.0.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +pip-21.0.1.dist-info/LICENSE.txt,sha256=ejlw8iXn2TntLdOpADqlISSc1qhJJgiYAKMZmq713Gk,1110 +pip-21.0.1.dist-info/METADATA,sha256=a6mCPyb1qd3cdVI5OorlrDhSN3HHYiN8feJrxmL4QgY,4168 +pip-21.0.1.dist-info/RECORD,, +pip-21.0.1.dist-info/WHEEL,sha256=OqRkF0eY5GHssMorFjlbTIq072vpHpF60fIQA6lS9xA,92 +pip-21.0.1.dist-info/entry_points.txt,sha256=5ExSa1s54zSPNA_1epJn5SX06786S8k5YHwskMvVYzw,125 +pip-21.0.1.dist-info/top_level.txt,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +pip/__init__.py,sha256=N22Wk52M-ZwIU8jx64XlNaLmHk_MyL1ErZ_71RG1Pzo,473 +pip/__main__.py,sha256=WGRSG7tdJrjefIHsZOk977H_rgkSt9z2liew-Cwm09U,874 +pip/__pycache__/__init__.cpython-39.pyc,, +pip/__pycache__/__main__.cpython-39.pyc,, +pip/_internal/__init__.py,sha256=fnY9L5BJfq79L8CXhLnj2nJMH8-JEpJkGQAMhM231AU,512 +pip/_internal/__pycache__/__init__.cpython-39.pyc,, +pip/_internal/__pycache__/build_env.cpython-39.pyc,, +pip/_internal/__pycache__/cache.cpython-39.pyc,, +pip/_internal/__pycache__/configuration.cpython-39.pyc,, +pip/_internal/__pycache__/exceptions.cpython-39.pyc,, +pip/_internal/__pycache__/locations.cpython-39.pyc,, +pip/_internal/__pycache__/main.cpython-39.pyc,, +pip/_internal/__pycache__/pyproject.cpython-39.pyc,, +pip/_internal/__pycache__/self_outdated_check.cpython-39.pyc,, +pip/_internal/__pycache__/wheel_builder.cpython-39.pyc,, +pip/_internal/build_env.py,sha256=mEgguVg9YnwbVVLtwUlDF5irYsweDksk67obP0KAjE8,8323 +pip/_internal/cache.py,sha256=j4UrFmwo2xC0e1QQUVAwPVuySmQttDUGJb-myD4t-Q8,10385 +pip/_internal/cli/__init__.py,sha256=9gMw_A_StJXzDh2Rhxil6bd8tFP-ZR719Q1pINHAw5I,136 +pip/_internal/cli/__pycache__/__init__.cpython-39.pyc,, +pip/_internal/cli/__pycache__/autocompletion.cpython-39.pyc,, +pip/_internal/cli/__pycache__/base_command.cpython-39.pyc,, +pip/_internal/cli/__pycache__/cmdoptions.cpython-39.pyc,, +pip/_internal/cli/__pycache__/command_context.cpython-39.pyc,, +pip/_internal/cli/__pycache__/main.cpython-39.pyc,, +pip/_internal/cli/__pycache__/main_parser.cpython-39.pyc,, +pip/_internal/cli/__pycache__/parser.cpython-39.pyc,, +pip/_internal/cli/__pycache__/progress_bars.cpython-39.pyc,, +pip/_internal/cli/__pycache__/req_command.cpython-39.pyc,, +pip/_internal/cli/__pycache__/spinners.cpython-39.pyc,, +pip/_internal/cli/__pycache__/status_codes.cpython-39.pyc,, +pip/_internal/cli/autocompletion.py,sha256=9iPihFS8MgmENqlAQOd80nPO3XWXNbl4yTFb-ZUIn1k,6711 +pip/_internal/cli/base_command.py,sha256=phmb0p-uI7fkc3yulvrjKvLwkoGwLXoejcvLJNX51s8,8127 +pip/_internal/cli/cmdoptions.py,sha256=WAXEdfKiz4dlEm4zGd_I9GY-jbpjBo83_2nDjPJCGos,29547 +pip/_internal/cli/command_context.py,sha256=edx8WCi04cZ-1jfMg3PnngxSwr2ZvlmSDdEAMsjfOvo,978 +pip/_internal/cli/main.py,sha256=elYNVqbCVwh1I2uKioP8YPCCoSEn_jOUXtS9zgb_ymE,2641 +pip/_internal/cli/main_parser.py,sha256=nWAmIGPraVBAV0lwg7prBPcTpqzZ8r0H7mm3d05QrfM,2894 +pip/_internal/cli/parser.py,sha256=_rp5QCCrsxFsBOKSt5CAMxSOqv0RjDgZBAnih6viO9k,10404 +pip/_internal/cli/progress_bars.py,sha256=3DmxcO5HuBVpXFGKGGi5p_seeUiI4X_XV3Tl4qMg0PU,9083 +pip/_internal/cli/req_command.py,sha256=oIwJ9DbEV4tCT8-bKOvKmGwdGeXXX4NkAgqmI70-NJc,16470 +pip/_internal/cli/spinners.py,sha256=JJKIdn76dBD6xGrBvXigjnzJtIHZeZfB5gzMOH_LHiw,5614 +pip/_internal/cli/status_codes.py,sha256=1xaB32lG8Nf1nMl_6e0yy5z2Iyvv81OTUpuHwXgGsfU,122 +pip/_internal/commands/__init__.py,sha256=FknHsVy_gYqpY6Y0zKae3kFyIqQHG32ptp09w8jzSoA,3866 +pip/_internal/commands/__pycache__/__init__.cpython-39.pyc,, +pip/_internal/commands/__pycache__/cache.cpython-39.pyc,, +pip/_internal/commands/__pycache__/check.cpython-39.pyc,, +pip/_internal/commands/__pycache__/completion.cpython-39.pyc,, +pip/_internal/commands/__pycache__/configuration.cpython-39.pyc,, +pip/_internal/commands/__pycache__/debug.cpython-39.pyc,, +pip/_internal/commands/__pycache__/download.cpython-39.pyc,, +pip/_internal/commands/__pycache__/freeze.cpython-39.pyc,, +pip/_internal/commands/__pycache__/hash.cpython-39.pyc,, +pip/_internal/commands/__pycache__/help.cpython-39.pyc,, +pip/_internal/commands/__pycache__/install.cpython-39.pyc,, +pip/_internal/commands/__pycache__/list.cpython-39.pyc,, +pip/_internal/commands/__pycache__/search.cpython-39.pyc,, +pip/_internal/commands/__pycache__/show.cpython-39.pyc,, +pip/_internal/commands/__pycache__/uninstall.cpython-39.pyc,, +pip/_internal/commands/__pycache__/wheel.cpython-39.pyc,, +pip/_internal/commands/cache.py,sha256=s-5zrlvMcgDCIT0pS7fsGm6gO51JZeU5nqRgTLS7r8g,7737 +pip/_internal/commands/check.py,sha256=3_wGQDSB_vNe6WLoN-oOwJJcSRov6vq5vP1wf0bUUfw,1728 +pip/_internal/commands/completion.py,sha256=9JoflBglg7tTYAHMU3RGQ9hpM632aWlp0UNXe7qADU4,3137 +pip/_internal/commands/configuration.py,sha256=YFrjdGREeyXerrhgWAgtEDfKxQ4Gwhl8GH9PyY1FkC4,9599 +pip/_internal/commands/debug.py,sha256=NiJHfTo3RpMubodWygd99vxgwZhA10JhfwKTRBccwt8,7150 +pip/_internal/commands/download.py,sha256=7QQ6MpSOBv0E1sXlD7m9OlxBD13PDsarJVrGYp3wKHk,5227 +pip/_internal/commands/freeze.py,sha256=mH5TWSL9eQ1dwcd87CapJvWLG0XRPcNzKeZiUyv326s,3628 +pip/_internal/commands/hash.py,sha256=6qN_SwOyWw93m44BBaq4nlRc2C7cJxFyXIMwRHZBc5c,1864 +pip/_internal/commands/help.py,sha256=bh7rxWxR3_ZUhk3QCqfkreSftcUY0ijPX1eeR0z6SfM,1282 +pip/_internal/commands/install.py,sha256=TNUBOFuF7oysQFG95k3aIE-5EIJNaYIShrVprDq6HyQ,28014 +pip/_internal/commands/list.py,sha256=o-vhJtkGZ5Y5X0UIa9FJFTa_aLkFCNof_U3ltzAksC4,11753 +pip/_internal/commands/search.py,sha256=F8Ab9LbsHLUGv79ZWa_vnCGN8DZ54iHX-yFRPU9gXak,6124 +pip/_internal/commands/show.py,sha256=iEAH0ehpOGM9rP9DpkYJNZqfd5a2yL82GF37tZ2S7Yc,7140 +pip/_internal/commands/uninstall.py,sha256=lOow-0Ja0CecV0kQjg7l019PAAa19P8M8alCUM4VoxQ,3364 +pip/_internal/commands/wheel.py,sha256=TVjbMZ7BMB1pRGeAZ8z3zGdk7ZnTL76x6iSg6GYI4Fc,6931 +pip/_internal/configuration.py,sha256=5ph7m7u6j3eNlVTJIFSLMaRPl2m8mesTmAEBLG0dCPY,14225 +pip/_internal/distributions/__init__.py,sha256=FFd96Mt1zxxzsFEzbR3yL1rDmQkDhWnnLhMR6LlzboU,983 +pip/_internal/distributions/__pycache__/__init__.cpython-39.pyc,, +pip/_internal/distributions/__pycache__/base.cpython-39.pyc,, +pip/_internal/distributions/__pycache__/installed.cpython-39.pyc,, +pip/_internal/distributions/__pycache__/sdist.cpython-39.pyc,, +pip/_internal/distributions/__pycache__/wheel.cpython-39.pyc,, +pip/_internal/distributions/base.py,sha256=Gb1nPCK39r1jmOcSbqMr-Tp5rDpB9p1BfpTqZDt4XpU,1385 +pip/_internal/distributions/installed.py,sha256=_FosTYlkY8U7BrJbyJlTLmKpVhHzIYBeaxWhn2THEbM,786 +pip/_internal/distributions/sdist.py,sha256=mbNJcb6oMuQLr4wJWKZTNldZQSQmKZJuPQk7FWPJYbg,4182 +pip/_internal/distributions/wheel.py,sha256=fu3BFBDAmhgYu2ce12TsvpcCBfuMMFwIkj9nNy0gskQ,1332 +pip/_internal/exceptions.py,sha256=hakQGwr-evbRl1NmTPqzD04fk3Lc22rtCm8EtN_JNXA,13158 +pip/_internal/index/__init__.py,sha256=x0ifDyFChwwQC4V_eHBFF1fvzLwbXRYG3nq15-Axy24,32 +pip/_internal/index/__pycache__/__init__.cpython-39.pyc,, +pip/_internal/index/__pycache__/collector.cpython-39.pyc,, +pip/_internal/index/__pycache__/package_finder.cpython-39.pyc,, +pip/_internal/index/collector.py,sha256=tkMhV8szxUKFewRB-WeJB2eZu5VciVuNWlq3jgDcwOI,22547 +pip/_internal/index/package_finder.py,sha256=5c1zFdAwfIZzEQFArPnoEbAYeLtNMGVJfKl8vydSOl4,37800 +pip/_internal/locations.py,sha256=VEtA-xzIiZifWmU8YrTGsovl9TPQfE0zrTRn_MGEcSA,6485 +pip/_internal/main.py,sha256=4U06fJfknPpyb5T_SBkohFNOAde0-qIcAD0EXsvACM4,453 +pip/_internal/models/__init__.py,sha256=j2kiRfNTH6h5JVP5yO_N2Yn0DqiNzJUtaPjHe2xMcgg,65 +pip/_internal/models/__pycache__/__init__.cpython-39.pyc,, +pip/_internal/models/__pycache__/candidate.cpython-39.pyc,, +pip/_internal/models/__pycache__/direct_url.cpython-39.pyc,, +pip/_internal/models/__pycache__/format_control.cpython-39.pyc,, +pip/_internal/models/__pycache__/index.cpython-39.pyc,, +pip/_internal/models/__pycache__/link.cpython-39.pyc,, +pip/_internal/models/__pycache__/scheme.cpython-39.pyc,, +pip/_internal/models/__pycache__/search_scope.cpython-39.pyc,, +pip/_internal/models/__pycache__/selection_prefs.cpython-39.pyc,, +pip/_internal/models/__pycache__/target_python.cpython-39.pyc,, +pip/_internal/models/__pycache__/wheel.cpython-39.pyc,, +pip/_internal/models/candidate.py,sha256=WMx9i7VnMtcraKXDWBSxR_WOECCEiopWy8LUcntUrvw,1208 +pip/_internal/models/direct_url.py,sha256=GGLCpPIGVKKYOR-0Lp55cGc0lPMoPWsUumWChA4BiDY,6913 +pip/_internal/models/format_control.py,sha256=YUBHSFsmBxmGDJytEJhCOA6YWaUcRq6ufvWlleehqKI,2802 +pip/_internal/models/index.py,sha256=idYm7uI8E8NQ9Sy3MqhnnRphnDmN4iTj5UbY5f7Llcg,1126 +pip/_internal/models/link.py,sha256=ZnNyXIo5Pn2YC_63q1CFOdrS_GdEMOjyolXk6_69adE,7639 +pip/_internal/models/scheme.py,sha256=sZ18s2TzMgmHZzwm8PMDX-hy4wxTQrSKUoNcCYS2F34,801 +pip/_internal/models/search_scope.py,sha256=GLnSaJKgMsSuCqCatTmDypSiKZI6Ny1CgRCX2GPTFoA,4835 +pip/_internal/models/selection_prefs.py,sha256=gY2ynXkzHLKBL1UZ2d5Pl6Q4m-Mp6CPg-ufZesUxyEY,2087 +pip/_internal/models/target_python.py,sha256=x57cmp9eb9zHZXncctwAdL4H1Rx_J27U5gaYrCQ2u7M,4169 +pip/_internal/models/wheel.py,sha256=KFKEmqRIScyHEfqovopluujgd1uRXZMTsWte5Eh9sPY,2834 +pip/_internal/network/__init__.py,sha256=IEtuAPVGqBTS0C7M0KJ95xqGcA76coOc2AsDcgIBP-8,52 +pip/_internal/network/__pycache__/__init__.cpython-39.pyc,, +pip/_internal/network/__pycache__/auth.cpython-39.pyc,, +pip/_internal/network/__pycache__/cache.cpython-39.pyc,, +pip/_internal/network/__pycache__/download.cpython-39.pyc,, +pip/_internal/network/__pycache__/lazy_wheel.cpython-39.pyc,, +pip/_internal/network/__pycache__/session.cpython-39.pyc,, +pip/_internal/network/__pycache__/utils.cpython-39.pyc,, +pip/_internal/network/__pycache__/xmlrpc.cpython-39.pyc,, +pip/_internal/network/auth.py,sha256=svvGxUsGxBmqNmX8T4kPi9PvZpe1eCBTZJk8rFkzkcw,11895 +pip/_internal/network/cache.py,sha256=zUu27h3fS78yIeSNuEB9sq_2GjFJ6S2RpRLCwQSFy64,2378 +pip/_internal/network/download.py,sha256=UONxxUxEwgNEfFN_lappdU_6NBa4RXqZ00LeHBOuL20,6587 +pip/_internal/network/lazy_wheel.py,sha256=Qgl8wi3_188W4nOjKi-L_J3OUqUKq0Ge0dDsxTSCFaY,8293 +pip/_internal/network/session.py,sha256=5N0_AdbQ_RnFLd2fg9ZMSuz22iaBSnM27LIoNotAtgQ,15643 +pip/_internal/network/utils.py,sha256=BpdHEUSN7ONrdradjr8BEe2mL5rlj8xFFtmYbMzhHz0,4266 +pip/_internal/network/xmlrpc.py,sha256=GgX5TAU3s50jlAmdwaUG7m_iV06rbPtaI5_NGd53AVo,1871 +pip/_internal/operations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +pip/_internal/operations/__pycache__/__init__.cpython-39.pyc,, +pip/_internal/operations/__pycache__/check.cpython-39.pyc,, +pip/_internal/operations/__pycache__/freeze.cpython-39.pyc,, +pip/_internal/operations/__pycache__/prepare.cpython-39.pyc,, +pip/_internal/operations/build/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +pip/_internal/operations/build/__pycache__/__init__.cpython-39.pyc,, +pip/_internal/operations/build/__pycache__/metadata.cpython-39.pyc,, +pip/_internal/operations/build/__pycache__/metadata_legacy.cpython-39.pyc,, +pip/_internal/operations/build/__pycache__/wheel.cpython-39.pyc,, +pip/_internal/operations/build/__pycache__/wheel_legacy.cpython-39.pyc,, +pip/_internal/operations/build/metadata.py,sha256=R1ir---xEH_Nx93KgH-tWYbkUYe64aQFLEO_b2NddEE,1293 +pip/_internal/operations/build/metadata_legacy.py,sha256=oqD7-jGQSHUxP90E2muEbwbjz5Bh1N1nUWWKxWOpwjI,2080 +pip/_internal/operations/build/wheel.py,sha256=9O1d7GiejX4V0d6jKNXc9TvuY0_CYg5a9L41UpFrB_o,1505 +pip/_internal/operations/build/wheel_legacy.py,sha256=hJ4tiC_fFzyIM2uoAFfd4Fk-CBD1AeJJyw_XZOFBlN4,3426 +pip/_internal/operations/check.py,sha256=WFd1l5wlpyOL7u8dZsSFDi9lzoZ-lRA7L1VLYiYH2kY,5371 +pip/_internal/operations/freeze.py,sha256=JNF8zG9BuqJ2fWJgQZV0H7eaiKdMNNLx5xc8gvlA9k0,10442 +pip/_internal/operations/install/__init__.py,sha256=Zug2xxRJjeI2LdVd45iwmeavUBYXA4ltbhFFwc4BEOg,53 +pip/_internal/operations/install/__pycache__/__init__.cpython-39.pyc,, +pip/_internal/operations/install/__pycache__/editable_legacy.cpython-39.pyc,, +pip/_internal/operations/install/__pycache__/legacy.cpython-39.pyc,, +pip/_internal/operations/install/__pycache__/wheel.cpython-39.pyc,, +pip/_internal/operations/install/editable_legacy.py,sha256=gEMhkmuxJ0wfqKspmhu_i41Ltq1_F-4IrTYPxsWVxEw,1540 +pip/_internal/operations/install/legacy.py,sha256=8aby3xQI90LPZOx7uDWvBV2cehOpGkj4Lb4js7bCrZA,4403 +pip/_internal/operations/install/wheel.py,sha256=dCig7D4jT4PMjtyLuhuMwDfD8kzXgN9ra8B9uyeMUYg,31158 +pip/_internal/operations/prepare.py,sha256=t5rXOX388PznqycvpLNGYRLpCcqsniKtmAzY9FSvXQg,22142 +pip/_internal/pyproject.py,sha256=yxwQz1Ib3r2dX6mp6qecZwiDThLK13eT2dkWW67swkA,7333 +pip/_internal/req/__init__.py,sha256=BUtbA3pab69f5WjMnLnkoXTEKSo8ZxEFsaYyf0Ql8m0,3170 +pip/_internal/req/__pycache__/__init__.cpython-39.pyc,, +pip/_internal/req/__pycache__/constructors.cpython-39.pyc,, +pip/_internal/req/__pycache__/req_file.cpython-39.pyc,, +pip/_internal/req/__pycache__/req_install.cpython-39.pyc,, +pip/_internal/req/__pycache__/req_set.cpython-39.pyc,, +pip/_internal/req/__pycache__/req_tracker.cpython-39.pyc,, +pip/_internal/req/__pycache__/req_uninstall.cpython-39.pyc,, +pip/_internal/req/constructors.py,sha256=-AhfcM1mO5Ng105XMcyA2k2ylp_rK513b4dPJZUbmRs,16035 +pip/_internal/req/req_file.py,sha256=Uaga43m7o24fKKwZEJmgFMmdSd-t-mV5Zvp8VwzDpiw,18552 +pip/_internal/req/req_install.py,sha256=PHz0mt8zWwRBxn8kcWPmt_eu1i3HHwUMjmFaQ-hl3TI,33145 +pip/_internal/req/req_set.py,sha256=CcW_X-n0cB81rmEixPOBmalXg7hOI4aOHMf19s1TVpA,8013 +pip/_internal/req/req_tracker.py,sha256=DcFBkSFp2ysr5x90NExMHlwus15mclFDj4_vNJrYcTk,4656 +pip/_internal/req/req_uninstall.py,sha256=TAfa5mYhhIYpnIITDz6hUy1z00ME_mybAhx0eekhp1s,24255 +pip/_internal/resolution/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +pip/_internal/resolution/__pycache__/__init__.cpython-39.pyc,, +pip/_internal/resolution/__pycache__/base.cpython-39.pyc,, +pip/_internal/resolution/base.py,sha256=df4S86qAB5UMkgzJ3ZNgxtkHusg9UywRF2J8ef91qPw,696 +pip/_internal/resolution/legacy/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +pip/_internal/resolution/legacy/__pycache__/__init__.cpython-39.pyc,, +pip/_internal/resolution/legacy/__pycache__/resolver.cpython-39.pyc,, +pip/_internal/resolution/legacy/resolver.py,sha256=mXfkbMGIUMYmdHkH7esyyLYKpuhIsvhKgPD_P884QXI,18692 +pip/_internal/resolution/resolvelib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +pip/_internal/resolution/resolvelib/__pycache__/__init__.cpython-39.pyc,, +pip/_internal/resolution/resolvelib/__pycache__/base.cpython-39.pyc,, +pip/_internal/resolution/resolvelib/__pycache__/candidates.cpython-39.pyc,, +pip/_internal/resolution/resolvelib/__pycache__/factory.cpython-39.pyc,, +pip/_internal/resolution/resolvelib/__pycache__/found_candidates.cpython-39.pyc,, +pip/_internal/resolution/resolvelib/__pycache__/provider.cpython-39.pyc,, +pip/_internal/resolution/resolvelib/__pycache__/reporter.cpython-39.pyc,, +pip/_internal/resolution/resolvelib/__pycache__/requirements.cpython-39.pyc,, +pip/_internal/resolution/resolvelib/__pycache__/resolver.cpython-39.pyc,, +pip/_internal/resolution/resolvelib/base.py,sha256=pCjC_evBGsbYZhseXluXMCKkyAS-LNkqRqSj-AHkXdw,5193 +pip/_internal/resolution/resolvelib/candidates.py,sha256=hOC1JSpzE0Yt-4J9l7G7tUIBSIyWBUVF6JaowJJ1a_8,20211 +pip/_internal/resolution/resolvelib/factory.py,sha256=avshtHNs5nrlExEbDcTLBMnlkNGXwQBUkSHX0Kk9Yxc,19228 +pip/_internal/resolution/resolvelib/found_candidates.py,sha256=P5C46Bj91edImB8tUNFkC5Zr75HhGgwrY6cjRbMf3fs,5479 +pip/_internal/resolution/resolvelib/provider.py,sha256=7_LjNcubdcjMEnehHiaN3iewSPu4m4coS2mTT7PQzp8,7513 +pip/_internal/resolution/resolvelib/reporter.py,sha256=-bdsWDecNezUPSWbSHEX-xNyVP8Tkd0zO96bhxFr1Vg,2941 +pip/_internal/resolution/resolvelib/requirements.py,sha256=mRJLY0Rc_muoYqZ7XDEYYmJN7Aw4L3sq4ywKimy_UZE,6162 +pip/_internal/resolution/resolvelib/resolver.py,sha256=MgZmX_N5J5xqwc-f0tvNyjnFCfWbrgtUlWmCHOh677g,11912 +pip/_internal/self_outdated_check.py,sha256=JsHoDtt7VjsGO7ADfj-SvUlU-Ul_B_RI9pTA0ma1ZLI,6858 +pip/_internal/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +pip/_internal/utils/__pycache__/__init__.cpython-39.pyc,, +pip/_internal/utils/__pycache__/appdirs.cpython-39.pyc,, +pip/_internal/utils/__pycache__/compat.cpython-39.pyc,, +pip/_internal/utils/__pycache__/compatibility_tags.cpython-39.pyc,, +pip/_internal/utils/__pycache__/datetime.cpython-39.pyc,, +pip/_internal/utils/__pycache__/deprecation.cpython-39.pyc,, +pip/_internal/utils/__pycache__/direct_url_helpers.cpython-39.pyc,, +pip/_internal/utils/__pycache__/distutils_args.cpython-39.pyc,, +pip/_internal/utils/__pycache__/encoding.cpython-39.pyc,, +pip/_internal/utils/__pycache__/entrypoints.cpython-39.pyc,, +pip/_internal/utils/__pycache__/filesystem.cpython-39.pyc,, +pip/_internal/utils/__pycache__/filetypes.cpython-39.pyc,, +pip/_internal/utils/__pycache__/glibc.cpython-39.pyc,, +pip/_internal/utils/__pycache__/hashes.cpython-39.pyc,, +pip/_internal/utils/__pycache__/inject_securetransport.cpython-39.pyc,, +pip/_internal/utils/__pycache__/logging.cpython-39.pyc,, +pip/_internal/utils/__pycache__/misc.cpython-39.pyc,, +pip/_internal/utils/__pycache__/models.cpython-39.pyc,, +pip/_internal/utils/__pycache__/packaging.cpython-39.pyc,, +pip/_internal/utils/__pycache__/parallel.cpython-39.pyc,, +pip/_internal/utils/__pycache__/pkg_resources.cpython-39.pyc,, +pip/_internal/utils/__pycache__/setuptools_build.cpython-39.pyc,, +pip/_internal/utils/__pycache__/subprocess.cpython-39.pyc,, +pip/_internal/utils/__pycache__/temp_dir.cpython-39.pyc,, +pip/_internal/utils/__pycache__/typing.cpython-39.pyc,, +pip/_internal/utils/__pycache__/unpacking.cpython-39.pyc,, +pip/_internal/utils/__pycache__/urls.cpython-39.pyc,, +pip/_internal/utils/__pycache__/virtualenv.cpython-39.pyc,, +pip/_internal/utils/__pycache__/wheel.cpython-39.pyc,, +pip/_internal/utils/appdirs.py,sha256=AyrjuIvYUfsCa7CncTTUOg1BxlERcwI42pSWZmsnNNM,1351 +pip/_internal/utils/compat.py,sha256=IQCUn_HI5WEB6UJrwQ19nmTKmrqTF_eQU7And3MbikM,5274 +pip/_internal/utils/compatibility_tags.py,sha256=Ef2fJYjWAqnFPMeR0FOlxTh47lu0SBrenQm0kxf-J2g,5816 +pip/_internal/utils/datetime.py,sha256=OLKI87v18hQDVOyRMuyPX15nbCUWO4rMc9bAm2KpkGc,267 +pip/_internal/utils/deprecation.py,sha256=jIp8XEEK76VrUV9LgEA_i9nhriAYWUvU5Oly1L9YyKw,3380 +pip/_internal/utils/direct_url_helpers.py,sha256=vnN-_foyl_4ooLdhmrudTxfWLaIBgstyxPENL2mS2H4,4152 +pip/_internal/utils/distutils_args.py,sha256=conKwlSsvwBEnIISbWnqEwZwch-kyq3hQ0nKOBWPIm4,1398 +pip/_internal/utils/encoding.py,sha256=QAG90ZRmRCTA80YHRwjdvLQVFCRmhkxebvhgDBawWyY,1317 +pip/_internal/utils/entrypoints.py,sha256=CwZKpoIbCxxCTV91Nkz6ReFZQnrSGBbruipbiGoaCLY,1183 +pip/_internal/utils/filesystem.py,sha256=OaK_UFxXDjXOvAPuNE-bb8eeuwbdZcHnVCN18yAK-98,6389 +pip/_internal/utils/filetypes.py,sha256=tvz0Rml52zC_GZfgQxhdR10vP0qAxED-3cDyPrdFajM,873 +pip/_internal/utils/glibc.py,sha256=VZsrQxHLTFxZWWKcEDi7x6jIE-qwF8reZC6_m8MyhMw,3353 +pip/_internal/utils/hashes.py,sha256=DB6Pd5fCdWq-lMRfEE2mMCTkjmPfMTfgmqMzMmk50WE,5203 +pip/_internal/utils/inject_securetransport.py,sha256=-ATb-4xYRxDqnAoJY5z6sflj1O0XF81Hk2tEroxrSo8,846 +pip/_internal/utils/logging.py,sha256=IZ2eLA6UyI9n3cK5nJED7Z4PBb4dv4Y5CopQHxUjwj4,11448 +pip/_internal/utils/misc.py,sha256=yxEkMv1xYRa_GLbb6qDuLWx5jwYksAnlrugbpx-30p0,27604 +pip/_internal/utils/models.py,sha256=CSUxzZEuh9va4KE5tUpOtjVW7a8Pd003XVI4eNMgXSE,1151 +pip/_internal/utils/packaging.py,sha256=UEZLCFmt-9BiRBfmLwWlt8D2nGkpLIReRq7gzGYLLMI,3089 +pip/_internal/utils/parallel.py,sha256=Hb_H-6sptwWCN4VGzEwbs8_rxh6B6q8FBkgIBM2Dz-M,3432 +pip/_internal/utils/pkg_resources.py,sha256=LD_Y6KCr0MEBbt4KDWe1r077l9qpeUUd61o18TEhE_Q,1282 +pip/_internal/utils/setuptools_build.py,sha256=OQO4vmlFjXWPFTdQwTnMzpUOi9OPtYdq6tbZ1rL8YCI,5239 +pip/_internal/utils/subprocess.py,sha256=UX9CHNORjhqVcedNG1Jjwsl0Kw40v63Dso7RmpwmvFc,11078 +pip/_internal/utils/temp_dir.py,sha256=G2qWEirX_8ablfvxKzkHFIh2jCBF4OfOCrzgBDFUuIY,8983 +pip/_internal/utils/typing.py,sha256=6T7qX9SYEJMUwgn2ZqdhM-SSmDwWTIzRHkeL49Q10-I,1439 +pip/_internal/utils/unpacking.py,sha256=4AvWThNDIpEA0GdO9GUSSN2VLnp9HPDOxTMhcm8_KO8,9464 +pip/_internal/utils/urls.py,sha256=Z3ClgEtfZIdrU-YLRA6uVVMvejy-EwdxzrnqjZj0eu8,1452 +pip/_internal/utils/virtualenv.py,sha256=Hm8fXwb_xWBt-HxD-0wEasli_BA6eB3RWVVkyzwS37s,3769 +pip/_internal/utils/wheel.py,sha256=WeowquCm4hd7REee-RX0Q-t6Yq11db9ze6bY4OFaWLs,7304 +pip/_internal/vcs/__init__.py,sha256=Ovj2REzS3fFosLAKw5lnd3CX76J2nN9b1FNY6KluBgE,632 +pip/_internal/vcs/__pycache__/__init__.cpython-39.pyc,, +pip/_internal/vcs/__pycache__/bazaar.cpython-39.pyc,, +pip/_internal/vcs/__pycache__/git.cpython-39.pyc,, +pip/_internal/vcs/__pycache__/mercurial.cpython-39.pyc,, +pip/_internal/vcs/__pycache__/subversion.cpython-39.pyc,, +pip/_internal/vcs/__pycache__/versioncontrol.cpython-39.pyc,, +pip/_internal/vcs/bazaar.py,sha256=9QxXZaQY4rCnfJ4rbHHqDQTdb248-fy3cS_wuF_A5YQ,3786 +pip/_internal/vcs/git.py,sha256=jwXPCDxSUq03H23c0dVg9x3nr8jAtEoZytFl_UTFFoI,15935 +pip/_internal/vcs/mercurial.py,sha256=_aONuC99EOc_UOP4rOp29dzcea7oefVu5fm6LY4y9IE,5705 +pip/_internal/vcs/subversion.py,sha256=cZpJVzGN11yxVLAYcm9PcrZ65C2gChDACL1cd952snk,13019 +pip/_internal/vcs/versioncontrol.py,sha256=WMBOrxHPzV3SE8tL8-slNM6d9M4HlOMd9xLehZZ6wmM,23848 +pip/_internal/wheel_builder.py,sha256=_ZomhgGv70RyqYe0FPyYkPFuQEwl3jJ-jOCJWBfaCSk,12202 +pip/_vendor/__init__.py,sha256=xsgffPuXJIsmc6cAP0jW-u7WUZ8TMF35kfixn9lmPMk,4902 +pip/_vendor/__pycache__/__init__.cpython-39.pyc,, +pip/_vendor/__pycache__/appdirs.cpython-39.pyc,, +pip/_vendor/__pycache__/contextlib2.cpython-39.pyc,, +pip/_vendor/__pycache__/distro.cpython-39.pyc,, +pip/_vendor/__pycache__/pyparsing.cpython-39.pyc,, +pip/_vendor/__pycache__/retrying.cpython-39.pyc,, +pip/_vendor/__pycache__/six.cpython-39.pyc,, +pip/_vendor/appdirs.py,sha256=Od1rs7d0yMmHLUc0FQn2DleIUbC--EEmM-UtXvFqAjM,26540 +pip/_vendor/cachecontrol/__init__.py,sha256=SR74BEsga7Z2I6-CH8doh2Oq_vH0GG7RCwjJg7TntdI,313 +pip/_vendor/cachecontrol/__pycache__/__init__.cpython-39.pyc,, +pip/_vendor/cachecontrol/__pycache__/_cmd.cpython-39.pyc,, +pip/_vendor/cachecontrol/__pycache__/adapter.cpython-39.pyc,, +pip/_vendor/cachecontrol/__pycache__/cache.cpython-39.pyc,, +pip/_vendor/cachecontrol/__pycache__/compat.cpython-39.pyc,, +pip/_vendor/cachecontrol/__pycache__/controller.cpython-39.pyc,, +pip/_vendor/cachecontrol/__pycache__/filewrapper.cpython-39.pyc,, +pip/_vendor/cachecontrol/__pycache__/heuristics.cpython-39.pyc,, +pip/_vendor/cachecontrol/__pycache__/serialize.cpython-39.pyc,, +pip/_vendor/cachecontrol/__pycache__/wrapper.cpython-39.pyc,, +pip/_vendor/cachecontrol/_cmd.py,sha256=KIO6PIJoXmNr5RGS2pZjDum1-40oR4fw5kE0LguxrY4,1352 +pip/_vendor/cachecontrol/adapter.py,sha256=FBRrYfpkXaH8hKogEgw6wYCScnL2SJFDZlHBNF0EvLE,5015 +pip/_vendor/cachecontrol/cache.py,sha256=gCo5R0D__iptJ49dUfxwWfu2Lc2OjpDs-MERy2hTpK8,844 +pip/_vendor/cachecontrol/caches/__init__.py,sha256=rN8Ox5dd2ucPtgkybgz77XfTTUL4HFTO2-n2ACK2q3E,88 +pip/_vendor/cachecontrol/caches/__pycache__/__init__.cpython-39.pyc,, +pip/_vendor/cachecontrol/caches/__pycache__/file_cache.cpython-39.pyc,, +pip/_vendor/cachecontrol/caches/__pycache__/redis_cache.cpython-39.pyc,, +pip/_vendor/cachecontrol/caches/file_cache.py,sha256=tw35e4ZnOsxqrlZ2fQ2VYz2FlUlCbFMerNu2tPwtRHY,4299 +pip/_vendor/cachecontrol/caches/redis_cache.py,sha256=hFJ_J9MCUTjblJCBT_cV_glP--2toqHDCKLRGUIHSOQ,889 +pip/_vendor/cachecontrol/compat.py,sha256=3BisP29GBHAo0QxUrbpBsMeXSp8YzKQcGHwEW7VYU2U,724 +pip/_vendor/cachecontrol/controller.py,sha256=fTDK1V7NjpnU1hwfMboX4Vyh73-uWgL6QkghtvvyTrY,14525 +pip/_vendor/cachecontrol/filewrapper.py,sha256=YsK9ISeZg26n-rS0z7MdEcMTyQ9gW_fLb6zIRJvE2rg,2613 +pip/_vendor/cachecontrol/heuristics.py,sha256=yndlfXHJZ5u_TC1ECrV4fVl68OuWiXnDS0HPyscK1MM,4205 +pip/_vendor/cachecontrol/serialize.py,sha256=7Jq5PcVBH6RVI-qkKkQsV5yAiZCFQa7yFhvITw_DYsc,7279 +pip/_vendor/cachecontrol/wrapper.py,sha256=tKJnzRvbl7uJRxOChwlNLdJf9NR0QlnknQxgNzQW2kM,719 +pip/_vendor/certifi/__init__.py,sha256=yNK-O9MHyQX1qYVnBuiU97REsFFEMimhp3MnaIh9Kbc,65 +pip/_vendor/certifi/__main__.py,sha256=4JJNpOgznsXzgISGReUBrJGB6Q4zJOlIV99WFE185fM,267 +pip/_vendor/certifi/__pycache__/__init__.cpython-39.pyc,, +pip/_vendor/certifi/__pycache__/__main__.cpython-39.pyc,, +pip/_vendor/certifi/__pycache__/core.cpython-39.pyc,, +pip/_vendor/certifi/cacert.pem,sha256=u3fxPT--yemLvyislQRrRBlsfY9Vq3cgBh6ZmRqCkZc,263774 +pip/_vendor/certifi/core.py,sha256=WCYiIkg5ozbypABAcRagDOa9DCO2qgnf66GZ1SRgmWA,2375 +pip/_vendor/chardet/__init__.py,sha256=yxky3TQpsr5YTFEf5XYv0O4wq2e1WSilELYZ9e2AEes,3354 +pip/_vendor/chardet/__pycache__/__init__.cpython-39.pyc,, +pip/_vendor/chardet/__pycache__/big5freq.cpython-39.pyc,, +pip/_vendor/chardet/__pycache__/big5prober.cpython-39.pyc,, +pip/_vendor/chardet/__pycache__/chardistribution.cpython-39.pyc,, +pip/_vendor/chardet/__pycache__/charsetgroupprober.cpython-39.pyc,, +pip/_vendor/chardet/__pycache__/charsetprober.cpython-39.pyc,, +pip/_vendor/chardet/__pycache__/codingstatemachine.cpython-39.pyc,, +pip/_vendor/chardet/__pycache__/compat.cpython-39.pyc,, +pip/_vendor/chardet/__pycache__/cp949prober.cpython-39.pyc,, +pip/_vendor/chardet/__pycache__/enums.cpython-39.pyc,, +pip/_vendor/chardet/__pycache__/escprober.cpython-39.pyc,, +pip/_vendor/chardet/__pycache__/escsm.cpython-39.pyc,, +pip/_vendor/chardet/__pycache__/eucjpprober.cpython-39.pyc,, +pip/_vendor/chardet/__pycache__/euckrfreq.cpython-39.pyc,, +pip/_vendor/chardet/__pycache__/euckrprober.cpython-39.pyc,, +pip/_vendor/chardet/__pycache__/euctwfreq.cpython-39.pyc,, +pip/_vendor/chardet/__pycache__/euctwprober.cpython-39.pyc,, +pip/_vendor/chardet/__pycache__/gb2312freq.cpython-39.pyc,, +pip/_vendor/chardet/__pycache__/gb2312prober.cpython-39.pyc,, +pip/_vendor/chardet/__pycache__/hebrewprober.cpython-39.pyc,, +pip/_vendor/chardet/__pycache__/jisfreq.cpython-39.pyc,, +pip/_vendor/chardet/__pycache__/jpcntx.cpython-39.pyc,, +pip/_vendor/chardet/__pycache__/langbulgarianmodel.cpython-39.pyc,, +pip/_vendor/chardet/__pycache__/langgreekmodel.cpython-39.pyc,, +pip/_vendor/chardet/__pycache__/langhebrewmodel.cpython-39.pyc,, +pip/_vendor/chardet/__pycache__/langhungarianmodel.cpython-39.pyc,, +pip/_vendor/chardet/__pycache__/langrussianmodel.cpython-39.pyc,, +pip/_vendor/chardet/__pycache__/langthaimodel.cpython-39.pyc,, +pip/_vendor/chardet/__pycache__/langturkishmodel.cpython-39.pyc,, +pip/_vendor/chardet/__pycache__/latin1prober.cpython-39.pyc,, +pip/_vendor/chardet/__pycache__/mbcharsetprober.cpython-39.pyc,, +pip/_vendor/chardet/__pycache__/mbcsgroupprober.cpython-39.pyc,, +pip/_vendor/chardet/__pycache__/mbcssm.cpython-39.pyc,, +pip/_vendor/chardet/__pycache__/sbcharsetprober.cpython-39.pyc,, +pip/_vendor/chardet/__pycache__/sbcsgroupprober.cpython-39.pyc,, +pip/_vendor/chardet/__pycache__/sjisprober.cpython-39.pyc,, +pip/_vendor/chardet/__pycache__/universaldetector.cpython-39.pyc,, +pip/_vendor/chardet/__pycache__/utf8prober.cpython-39.pyc,, +pip/_vendor/chardet/__pycache__/version.cpython-39.pyc,, +pip/_vendor/chardet/big5freq.py,sha256=dwRzRlsGp3Zgr1JQSSSwnxvyaZ7_q-5kuPfCVMuy4to,31640 +pip/_vendor/chardet/big5prober.py,sha256=TpmdoNfRtnQ7x9Q_p-a1CHaG-ok2mbisN5e9UHAtOiY,1804 +pip/_vendor/chardet/chardistribution.py,sha256=NzboAhfS6GODy_Tp6BkmUOL4NuxwTVfdVFcKA9bdUAo,9644 +pip/_vendor/chardet/charsetgroupprober.py,sha256=NPYh0Agp8UnrfqIls_qdbwszQ1mv9imGawGUCErFT6M,3946 +pip/_vendor/chardet/charsetprober.py,sha256=kk5-m0VdjqzbEhPRkBZ386R3fBQo3DxsBrdL-WFyk1o,5255 +pip/_vendor/chardet/cli/__init__.py,sha256=frcCV1k9oG9oKj3dpUqdJg1PxRT2RSN_XKdLCPjaYaY,2 +pip/_vendor/chardet/cli/__pycache__/__init__.cpython-39.pyc,, +pip/_vendor/chardet/cli/__pycache__/chardetect.cpython-39.pyc,, +pip/_vendor/chardet/cli/chardetect.py,sha256=535zsG4tA_x-_xPtEeDvn46QLib2nvF-5NT_nJdGgVs,2831 +pip/_vendor/chardet/codingstatemachine.py,sha256=qz9ZwK1q4mZ4s4zDRbyXu5KaGunYbk7g1Z7fqfb4mA4,3678 +pip/_vendor/chardet/compat.py,sha256=3j2eGvEAakISaIanHZ4wZutzfttNdRSdlo6RSjpyxsM,1236 +pip/_vendor/chardet/cp949prober.py,sha256=5NnMVUcel3jDY3w8ljD0cXyj2lcrvdagxOVE1jxl7xc,1904 +pip/_vendor/chardet/enums.py,sha256=3H_EIVP-VUYOdKqe2xmYdyooEDSLqS8sACMbn_3oejU,1737 +pip/_vendor/chardet/escprober.py,sha256=5MrTnVtZGEt3ssnY-lOXmOo3JY-CIqz9ruG3KjDpkbY,4051 +pip/_vendor/chardet/escsm.py,sha256=xQbwmM3Ieuskg-Aohyc6-bSfg3vsY0tx2TEKLDoVZGg,10756 +pip/_vendor/chardet/eucjpprober.py,sha256=PHumemJS19xMhDR4xPrsvxMfyBfsb297kVWmYz6zgy8,3841 +pip/_vendor/chardet/euckrfreq.py,sha256=MrLrIWMtlaDI0LYt-MM3MougBbLtSWHs6kvZx0VasIM,13741 +pip/_vendor/chardet/euckrprober.py,sha256=VbiOn7_id7mL9Q5GdeV0Ze3w5fG0nRCpUkEzeR-bnnY,1795 +pip/_vendor/chardet/euctwfreq.py,sha256=ZPBIHZDwNknGf7m6r4xGH8bX0W38qBpnTwVVv1QHw_M,32008 +pip/_vendor/chardet/euctwprober.py,sha256=hlUyGKUxzOPfBxCcyUcvRZSxgkLuvRoDU9wejp6YMiM,1793 +pip/_vendor/chardet/gb2312freq.py,sha256=aLHs-2GS8vmSM2ljyoWWgeVq_xRRcS_gN7ykpIiV43A,20998 +pip/_vendor/chardet/gb2312prober.py,sha256=msVbrDFcrJRE_XvsyETiqbTGfvdFhVIEZ2zBd-OENaE,1800 +pip/_vendor/chardet/hebrewprober.py,sha256=r81LqgKb24ZbvOmfi95MzItUxx7bkrjJR1ppkj5rvZw,14130 +pip/_vendor/chardet/jisfreq.py,sha256=vrqCR4CmwownBVXJ3Hh_gsfiDnIHOELbcNmTyC6Jx3w,26102 +pip/_vendor/chardet/jpcntx.py,sha256=Cn4cypo2y8CpqCan-zsdfYdEgXkRCnsqQoYaCu6FRjI,19876 +pip/_vendor/chardet/langbulgarianmodel.py,sha256=IuDOQ4uAe5spaYXt1F-2_496DFYd3J5lyLKKbVg-Nkw,110347 +pip/_vendor/chardet/langgreekmodel.py,sha256=cZRowhYjEUNYCevhuD5ZMHMiOIf3Pk1IpRixjTpRPB0,103969 +pip/_vendor/chardet/langhebrewmodel.py,sha256=p-xw_b2XvGVSIQFgQL91cVpS7u3vPpGJZ0udYxD07Do,103159 +pip/_vendor/chardet/langhungarianmodel.py,sha256=EKIZs5Z8Y-l6ORDcBzE9htOMMnAnr2j6Wb1PFRBMVxM,107148 +pip/_vendor/chardet/langrussianmodel.py,sha256=TFH-3rTFzbCBF15oasmoqf92FKBnwWY_HaN2ptl5WVo,136898 +pip/_vendor/chardet/langthaimodel.py,sha256=rTzLQ2x_RjQEzZfIksCR--SCFQyuP5eCtQpqxyl5-x8,107695 +pip/_vendor/chardet/langturkishmodel.py,sha256=fWI_tafe_UQ24gdOGqOWy1tnEY2jxKHoi4ueoT3rrrc,100329 +pip/_vendor/chardet/latin1prober.py,sha256=s1SFkEFY2NGe2_9bgX2MhOmyM_U_qSd_jVSdkdSgZxs,5515 +pip/_vendor/chardet/mbcharsetprober.py,sha256=hzFVD-brxTAVLnTAkDqa1ztd6RwGGwb5oAdvhj1-lE8,3504 +pip/_vendor/chardet/mbcsgroupprober.py,sha256=DlT-X7KRUl5y3SWJNqF1NXqvkjVc47jPKjJ2j4KVs3A,2066 +pip/_vendor/chardet/mbcssm.py,sha256=LGUDh1VB61rWsZB4QlJBzaCjI2PUEUgbBc91gPlX4DQ,26053 +pip/_vendor/chardet/metadata/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +pip/_vendor/chardet/metadata/__pycache__/__init__.cpython-39.pyc,, +pip/_vendor/chardet/metadata/__pycache__/languages.cpython-39.pyc,, +pip/_vendor/chardet/metadata/languages.py,sha256=pGf_EnapgynSUCViRjUcwEi7AWw_bYPJFHCqerAFSbQ,19784 +pip/_vendor/chardet/sbcharsetprober.py,sha256=VPAZ5z-o8ixIIfEGTScLVXeQxkd3Zqi1eceerr0rb78,6281 +pip/_vendor/chardet/sbcsgroupprober.py,sha256=p8XICsXYXOF78Anypfvdne8K_0p8qFC-SUF5nwD1fo4,4392 +pip/_vendor/chardet/sjisprober.py,sha256=1WGev_SSHpa7AVXmM0DIONl1OvyKc8mdydUNaKtGGNI,3866 +pip/_vendor/chardet/universaldetector.py,sha256=C3ryFrDZ9JuroNMdYwgDa2_zAYJlWuPHyHLX5WtCY-g,12789 +pip/_vendor/chardet/utf8prober.py,sha256=rGwn69WfIvmibp0sWvYuH_TPoXs7zzwKHTX79Ojbr9o,2848 +pip/_vendor/chardet/version.py,sha256=LCY3oiBIflXJGeBYm7ly2aw6P9n272rhp3t7qz3oOHo,251 +pip/_vendor/colorama/__init__.py,sha256=besK61Glmusp-wZ1wjjSlsPKEY_6zndaeulh1FkVStw,245 +pip/_vendor/colorama/__pycache__/__init__.cpython-39.pyc,, +pip/_vendor/colorama/__pycache__/ansi.cpython-39.pyc,, +pip/_vendor/colorama/__pycache__/ansitowin32.cpython-39.pyc,, +pip/_vendor/colorama/__pycache__/initialise.cpython-39.pyc,, +pip/_vendor/colorama/__pycache__/win32.cpython-39.pyc,, +pip/_vendor/colorama/__pycache__/winterm.cpython-39.pyc,, +pip/_vendor/colorama/ansi.py,sha256=121ZIWJSdXR76TcqKXusVZQRgyb0AIlRnf5EW6oSGlQ,2624 +pip/_vendor/colorama/ansitowin32.py,sha256=bZByVMjpiUp-LSAK21KNvCh63UN9CPkXdHFPUsq20kA,10775 +pip/_vendor/colorama/initialise.py,sha256=J92wwYPAAEgdlAyw-ady4JJxl1j9UmXPodi0HicWDwg,1995 +pip/_vendor/colorama/win32.py,sha256=fI0Ani_DO_cYDAbHz_a0BsMbDKHCA1-P3PGcj0eDCmA,5556 +pip/_vendor/colorama/winterm.py,sha256=Zurpa5AEwarU62JTuERX53gGelEWH5SBUiAXN4CxMtA,6607 +pip/_vendor/contextlib2.py,sha256=t6Fla8KtAzH4ERLcdAfXizvnpp4nOw9GCq4GYFwTHkg,17433 +pip/_vendor/distlib/__init__.py,sha256=VmyMfsxv7AYUwPUA52UN_a1GzhtKpSpF7zM7y0G6ocA,604 +pip/_vendor/distlib/__pycache__/__init__.cpython-39.pyc,, +pip/_vendor/distlib/__pycache__/compat.cpython-39.pyc,, +pip/_vendor/distlib/__pycache__/database.cpython-39.pyc,, +pip/_vendor/distlib/__pycache__/index.cpython-39.pyc,, +pip/_vendor/distlib/__pycache__/locators.cpython-39.pyc,, +pip/_vendor/distlib/__pycache__/manifest.cpython-39.pyc,, +pip/_vendor/distlib/__pycache__/markers.cpython-39.pyc,, +pip/_vendor/distlib/__pycache__/metadata.cpython-39.pyc,, +pip/_vendor/distlib/__pycache__/resources.cpython-39.pyc,, +pip/_vendor/distlib/__pycache__/scripts.cpython-39.pyc,, +pip/_vendor/distlib/__pycache__/util.cpython-39.pyc,, +pip/_vendor/distlib/__pycache__/version.cpython-39.pyc,, +pip/_vendor/distlib/__pycache__/wheel.cpython-39.pyc,, +pip/_vendor/distlib/_backport/__init__.py,sha256=XkACqtjaFfFn1QQBFDNxSqhMva0LqXeeh6H3fVwwLQ4,280 +pip/_vendor/distlib/_backport/__pycache__/__init__.cpython-39.pyc,, +pip/_vendor/distlib/_backport/__pycache__/misc.cpython-39.pyc,, +pip/_vendor/distlib/_backport/__pycache__/shutil.cpython-39.pyc,, +pip/_vendor/distlib/_backport/__pycache__/sysconfig.cpython-39.pyc,, +pip/_vendor/distlib/_backport/__pycache__/tarfile.cpython-39.pyc,, +pip/_vendor/distlib/_backport/misc.py,sha256=focjmI7975W3LgEtiNC99lvxohfZdsNSLTakOcPNShs,1012 +pip/_vendor/distlib/_backport/shutil.py,sha256=h-yIttFtLq-_LKn5lLn4beHXzRwcmo2wEg4UKU7hX6E,26471 +pip/_vendor/distlib/_backport/sysconfig.cfg,sha256=LoipPkR2PfCKC7JUQBGxp6OFVlWIiWBXT-rNuzv8acU,2701 +pip/_vendor/distlib/_backport/sysconfig.py,sha256=qV5ZK6YVkHS-gUFacIT2TpFBw7bZJFH3DYa8PbT6O54,27640 +pip/_vendor/distlib/_backport/tarfile.py,sha256=fzwGLsCdTmO8uzoHjyjSgu4-srrDQEAcw4jNKUfvQH0,95235 +pip/_vendor/distlib/compat.py,sha256=Z8PBQ-ZPCJuRvzs5rtHuzceFOB8iYV8HHjAGrW3SQ8s,42528 +pip/_vendor/distlib/database.py,sha256=m_LtL3siDUdcSvftoTnXcjhUJA-WZhDwTvHO7rg72SA,52398 +pip/_vendor/distlib/index.py,sha256=MYT9QkE79nX-D9fz1tBpl6YHHmq4uSO95Sp-Gq6dN7E,21582 +pip/_vendor/distlib/locators.py,sha256=DMRfq00jgdPDwelULclHE8qbjNVqGCBoTOXl2kfiwMY,53402 +pip/_vendor/distlib/manifest.py,sha256=0TlGw5ZyFp8wxr_GJz7tAAXGYwUJvceMIOsh9ydAXpM,15204 +pip/_vendor/distlib/markers.py,sha256=k4Fx6LHfaIaX1eOIoaWK_-o-zE8zoT5rXwb6mbnLoXk,4518 +pip/_vendor/distlib/metadata.py,sha256=E3b0ee3kUoNbawem10Mc6qGCBNCUxFvS4TkYKUX8z2Q,40018 +pip/_vendor/distlib/resources.py,sha256=5Xn4ehSMQKsu6kf4gxIsMvy668RRvtL0XwUPytyviPE,11121 +pip/_vendor/distlib/scripts.py,sha256=oGaqPfOX_wcLXbzW2xf8ojJQbU9aJ29QiUgslWNHncM,17599 +pip/_vendor/distlib/t32.exe,sha256=NS3xBCVAld35JVFNmb-1QRyVtThukMrwZVeXn4LhaEQ,96768 +pip/_vendor/distlib/t64.exe,sha256=oAqHes78rUWVM0OtVqIhUvequl_PKhAhXYQWnUf7zR0,105984 +pip/_vendor/distlib/util.py,sha256=vjN27blgrxQkPPiBbAhEbdiv_Xw0ogu4XAT9SgU3x-c,61606 +pip/_vendor/distlib/version.py,sha256=tFjbWEAxyeCDw0dWQDJsWsu9EzegUI5Yhm3IBu2x8hY,24127 +pip/_vendor/distlib/w32.exe,sha256=lJtnZdeUxTZWya_EW5DZos_K5rswRECGspIl8ZJCIXs,90112 +pip/_vendor/distlib/w64.exe,sha256=0aRzoN2BO9NWW4ENy4_4vHkHR4qZTFZNVSAJJYlODTI,99840 +pip/_vendor/distlib/wheel.py,sha256=u8_DwGV_j2-fxQRizS3V9OTioXV-IZ6EC-n6yOnjUfc,42162 +pip/_vendor/distro.py,sha256=ni3ahks9qSr3P1FMur9zTPEF_xcAdaHW8iWZWqwB5mU,44858 +pip/_vendor/html5lib/__init__.py,sha256=Bmlpvs5dN2GoaWRAvN2UZ1yF_p7xb2zROelA0QxBKis,1195 +pip/_vendor/html5lib/__pycache__/__init__.cpython-39.pyc,, +pip/_vendor/html5lib/__pycache__/_ihatexml.cpython-39.pyc,, +pip/_vendor/html5lib/__pycache__/_inputstream.cpython-39.pyc,, +pip/_vendor/html5lib/__pycache__/_tokenizer.cpython-39.pyc,, +pip/_vendor/html5lib/__pycache__/_utils.cpython-39.pyc,, +pip/_vendor/html5lib/__pycache__/constants.cpython-39.pyc,, +pip/_vendor/html5lib/__pycache__/html5parser.cpython-39.pyc,, +pip/_vendor/html5lib/__pycache__/serializer.cpython-39.pyc,, +pip/_vendor/html5lib/_ihatexml.py,sha256=IyMKE35pNPCYYGs290_oSUhWXF1BQZsbVcXBzGuFvl4,17017 +pip/_vendor/html5lib/_inputstream.py,sha256=EA6Wj46jxuK6544Vnk9YOjIpFwGbfJW0Ar2cMH1H0VU,33271 +pip/_vendor/html5lib/_tokenizer.py,sha256=BUDNWZENVB0oFBiKR49sZsqQU4rzLLa13-byISlYRfA,78775 +pip/_vendor/html5lib/_trie/__init__.py,sha256=kfSo27BaU64El8U7bg4ugLmI3Ksywu54xE6BlhVgggA,114 +pip/_vendor/html5lib/_trie/__pycache__/__init__.cpython-39.pyc,, +pip/_vendor/html5lib/_trie/__pycache__/_base.cpython-39.pyc,, +pip/_vendor/html5lib/_trie/__pycache__/py.cpython-39.pyc,, +pip/_vendor/html5lib/_trie/_base.py,sha256=LTpLNz1pn7LAcfn2TFvRp4moVPbFTkkbhzjPKUrvGes,1053 +pip/_vendor/html5lib/_trie/py.py,sha256=LmuYcbypKw-aMLcT0-IY6WewATGzg1QRkmyd8hTBQeY,1842 +pip/_vendor/html5lib/_utils.py,sha256=dLFxoZDTv5r38HOIHy45uxWwUY7VhLgbEFWNQw6Wppo,5090 +pip/_vendor/html5lib/constants.py,sha256=P9n6_ScDgAFkst0YfKaB-yaAlxVtUS9uMn5Lh8ywbQo,86410 +pip/_vendor/html5lib/filters/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +pip/_vendor/html5lib/filters/__pycache__/__init__.cpython-39.pyc,, +pip/_vendor/html5lib/filters/__pycache__/alphabeticalattributes.cpython-39.pyc,, +pip/_vendor/html5lib/filters/__pycache__/base.cpython-39.pyc,, +pip/_vendor/html5lib/filters/__pycache__/inject_meta_charset.cpython-39.pyc,, +pip/_vendor/html5lib/filters/__pycache__/lint.cpython-39.pyc,, +pip/_vendor/html5lib/filters/__pycache__/optionaltags.cpython-39.pyc,, +pip/_vendor/html5lib/filters/__pycache__/sanitizer.cpython-39.pyc,, +pip/_vendor/html5lib/filters/__pycache__/whitespace.cpython-39.pyc,, +pip/_vendor/html5lib/filters/alphabeticalattributes.py,sha256=0TV6VWJzhNkcLFiR7BNZUJsTJgAEEyZ02in6-PuL2gU,948 +pip/_vendor/html5lib/filters/base.py,sha256=6D2t423hbOLtjnvAAOrs1mWX1vsabMLBrWQF67ITPho,298 +pip/_vendor/html5lib/filters/inject_meta_charset.py,sha256=J-W5X3LyosH1sUipiHU1x-2ocd7g9JSudpIek_QlCUU,3018 +pip/_vendor/html5lib/filters/lint.py,sha256=O6sK29HXXW02Nv-EIEOfGvdQMuXxWvBePu2sQ2ecbJc,3736 +pip/_vendor/html5lib/filters/optionaltags.py,sha256=IVHcJ35kr6_MYBqahFMIK-Gel-ALLUk6Wk9X-or_yXk,10795 +pip/_vendor/html5lib/filters/sanitizer.py,sha256=uwT0HNJHjnw3Omf2LpmvfoVdIgAWb9_3VrMcWD1es_M,27813 +pip/_vendor/html5lib/filters/whitespace.py,sha256=bCC0mMQZicbq8HCg67pip_oScN5Fz_KkkvldfE137Kw,1252 +pip/_vendor/html5lib/html5parser.py,sha256=2xGZMaUvdkuuswAmpkazK1CXHT_y3-XTy4lS71PYUuU,119981 +pip/_vendor/html5lib/serializer.py,sha256=vMivcnRcQxjCSTrbMFdevLMhJ2HbF0cfv_CkroTODZM,16168 +pip/_vendor/html5lib/treeadapters/__init__.py,sha256=76InX2oJAx-C4rGAJziZsoE_CHI8_3thl6TeMgP-ypk,709 +pip/_vendor/html5lib/treeadapters/__pycache__/__init__.cpython-39.pyc,, +pip/_vendor/html5lib/treeadapters/__pycache__/genshi.cpython-39.pyc,, +pip/_vendor/html5lib/treeadapters/__pycache__/sax.cpython-39.pyc,, +pip/_vendor/html5lib/treeadapters/genshi.py,sha256=nQHNa4Hu0IMpu4bqHbJJS3_Cd1pKXgDO1pgMZ6gADDg,1769 +pip/_vendor/html5lib/treeadapters/sax.py,sha256=PAmV6NG9BSpfMHUY72bDbXwAe6Q2tPn1BC2yAD-K1G0,1826 +pip/_vendor/html5lib/treebuilders/__init__.py,sha256=zfrXDjeqDo2M7cJFax6hRJs70Az4pfHFiZbuLOZ9YE4,3680 +pip/_vendor/html5lib/treebuilders/__pycache__/__init__.cpython-39.pyc,, +pip/_vendor/html5lib/treebuilders/__pycache__/base.cpython-39.pyc,, +pip/_vendor/html5lib/treebuilders/__pycache__/dom.cpython-39.pyc,, +pip/_vendor/html5lib/treebuilders/__pycache__/etree.cpython-39.pyc,, +pip/_vendor/html5lib/treebuilders/__pycache__/etree_lxml.cpython-39.pyc,, +pip/_vendor/html5lib/treebuilders/base.py,sha256=Yao9LOJd-4KaLEx-3ysqRkAkhv1YaDqhTksvX6nuQyY,14982 +pip/_vendor/html5lib/treebuilders/dom.py,sha256=QWkBtUprtDosTiTFlIY6QpgKwk2-pD0AV84qVTNgiLo,9164 +pip/_vendor/html5lib/treebuilders/etree.py,sha256=k-LHrme562Hd5GmIi87r1_vfF25MtURGPurT3mAp8sY,13179 +pip/_vendor/html5lib/treebuilders/etree_lxml.py,sha256=CviyyGjvv2TwN-m47DC8DFWdx0Gt-atRw9jMTv4v8-Q,15158 +pip/_vendor/html5lib/treewalkers/__init__.py,sha256=buyxCJb9LFfJ_1ZIMdc-Do1zV93Uw-7L942o2H-Swy0,5873 +pip/_vendor/html5lib/treewalkers/__pycache__/__init__.cpython-39.pyc,, +pip/_vendor/html5lib/treewalkers/__pycache__/base.cpython-39.pyc,, +pip/_vendor/html5lib/treewalkers/__pycache__/dom.cpython-39.pyc,, +pip/_vendor/html5lib/treewalkers/__pycache__/etree.cpython-39.pyc,, +pip/_vendor/html5lib/treewalkers/__pycache__/etree_lxml.cpython-39.pyc,, +pip/_vendor/html5lib/treewalkers/__pycache__/genshi.cpython-39.pyc,, +pip/_vendor/html5lib/treewalkers/base.py,sha256=g-cLq7VStBtpZZZ1v_Tbwp3GhJjQ2oG5njgeHVhAaXE,7728 +pip/_vendor/html5lib/treewalkers/dom.py,sha256=fBJht3gn5a6y1WN2KE9gsUru158yTQ0KikT3vOM7Xc4,1456 +pip/_vendor/html5lib/treewalkers/etree.py,sha256=VtcKOS13qy9nv2PAaYoB1j9V1Z8n9o0AEA9KoGAgYOg,4682 +pip/_vendor/html5lib/treewalkers/etree_lxml.py,sha256=u9X06RqSrHanDb0qGI-v8I99-PqzOzmnpZOspHHz_Io,6572 +pip/_vendor/html5lib/treewalkers/genshi.py,sha256=P_2Tnc2GkbWJfuodXN9oYIg6kN9E26aWXXe9iL0_eX4,2378 +pip/_vendor/idna/__init__.py,sha256=_0n4R0OXufy1HIcXEOxgJCUCHGDqtazhMdYBVIXc320,60 +pip/_vendor/idna/__pycache__/__init__.cpython-39.pyc,, +pip/_vendor/idna/__pycache__/codec.cpython-39.pyc,, +pip/_vendor/idna/__pycache__/compat.cpython-39.pyc,, +pip/_vendor/idna/__pycache__/core.cpython-39.pyc,, +pip/_vendor/idna/__pycache__/idnadata.cpython-39.pyc,, +pip/_vendor/idna/__pycache__/intranges.cpython-39.pyc,, +pip/_vendor/idna/__pycache__/package_data.cpython-39.pyc,, +pip/_vendor/idna/__pycache__/uts46data.cpython-39.pyc,, +pip/_vendor/idna/codec.py,sha256=NDQdy95NUcd00WV5Qh0QOpZvYJzIpaMVb9ME0hKuQ80,3417 +pip/_vendor/idna/compat.py,sha256=QPaSi9bWqUO7OAXmC0brJFYc1zweHI3JnA7HiM2BlQA,244 +pip/_vendor/idna/core.py,sha256=9uPbfjxEP-fiU9QL8dtxNnaZHyZr7YUtUS1V0GaNB48,12351 +pip/_vendor/idna/idnadata.py,sha256=qUMdMMOBhxlR7CJpeXFUy97pBTZRwhWKa3zIhulao0k,44400 +pip/_vendor/idna/intranges.py,sha256=K5VTgP3Cn6UOQwinqj0O2stySFQoTb8xrLFKyg-hulg,1802 +pip/_vendor/idna/package_data.py,sha256=JS73h8bhkMB0AKLCXZ-Hbt660VMRAFBcP9drX0lX52s,24 +pip/_vendor/idna/uts46data.py,sha256=oxTG_Nku3jRCkXmSOL2yg_TCQHhH43uN2bDtuJ8xoCc,210441 +pip/_vendor/msgpack/__init__.py,sha256=OhoFouHD7wOYMP2PN-Hlyk9RAZw39V-iPTDRsmkoIns,1172 +pip/_vendor/msgpack/__pycache__/__init__.cpython-39.pyc,, +pip/_vendor/msgpack/__pycache__/_version.cpython-39.pyc,, +pip/_vendor/msgpack/__pycache__/exceptions.cpython-39.pyc,, +pip/_vendor/msgpack/__pycache__/ext.cpython-39.pyc,, +pip/_vendor/msgpack/__pycache__/fallback.cpython-39.pyc,, +pip/_vendor/msgpack/_version.py,sha256=qcv5IclQy1PSvtCYDvZyjaUSFWdHPIRzdGjv3YwkKCs,21 +pip/_vendor/msgpack/exceptions.py,sha256=2fCtczricqQgdT3NtW6cTqmZn3WA7GQtmlPuT-NhLyM,1129 +pip/_vendor/msgpack/ext.py,sha256=3Xznjz11nxxfQJe50uLzKDznWOvxOBxWSZ833DL_DDs,6281 +pip/_vendor/msgpack/fallback.py,sha256=ZaNwBMO2hh9WrqHnYqdHJaCv8zzPMnva9YhD5yInTpM,39113 +pip/_vendor/packaging/__about__.py,sha256=h9QOAlgXk51CVUXfD2djDO8X7z2DKjnIxkEcmCHalTc,753 +pip/_vendor/packaging/__init__.py,sha256=UcApkMPyWGcIGgYWGi5lL5uzPYpelyaOPRXhgdUhCiw,588 +pip/_vendor/packaging/__pycache__/__about__.cpython-39.pyc,, +pip/_vendor/packaging/__pycache__/__init__.cpython-39.pyc,, +pip/_vendor/packaging/__pycache__/_compat.cpython-39.pyc,, +pip/_vendor/packaging/__pycache__/_structures.cpython-39.pyc,, +pip/_vendor/packaging/__pycache__/_typing.cpython-39.pyc,, +pip/_vendor/packaging/__pycache__/markers.cpython-39.pyc,, +pip/_vendor/packaging/__pycache__/requirements.cpython-39.pyc,, +pip/_vendor/packaging/__pycache__/specifiers.cpython-39.pyc,, +pip/_vendor/packaging/__pycache__/tags.cpython-39.pyc,, +pip/_vendor/packaging/__pycache__/utils.cpython-39.pyc,, +pip/_vendor/packaging/__pycache__/version.cpython-39.pyc,, +pip/_vendor/packaging/_compat.py,sha256=wtTUbVAZPwwTy4_8aQjCedCpQVcy-CTvCZv1Ri3IvhY,1166 +pip/_vendor/packaging/_structures.py,sha256=0DUfMS4mYkvzf_89F1f5SRSbYtcxdikc3TvzgCnxeo0,2108 +pip/_vendor/packaging/_typing.py,sha256=n1Xr-giO86iFpEEEkYKWWGZetBwnyYbwhcr-EuId0G0,1872 +pip/_vendor/packaging/markers.py,sha256=1Fj8RWPWbNhnOsSZAYqs7JRI6-aOBzEau7u9UcnFKLk,9808 +pip/_vendor/packaging/requirements.py,sha256=Oxps2CfRKfaPNGWICAv5eUeUwddVOmOfHuLKlQ1k6MU,5270 +pip/_vendor/packaging/specifiers.py,sha256=BCbv9EegYKBiwB5qOLkAVK6sAVCrHdGIeVfzzGznn4c,33072 +pip/_vendor/packaging/tags.py,sha256=aOIFGI46FLvkJpDwy858fFdrHbydPRu1caLTkI8UTOo,30427 +pip/_vendor/packaging/utils.py,sha256=QSspLOaGAUqVnR8c1dHpIHIOQwJHydchP7HnnzMCHSY,4523 +pip/_vendor/packaging/version.py,sha256=QmDlgceXJ0sPNCc2Oe4yda6lShIItK7C1nZVmd-Sq5g,16530 +pip/_vendor/pep517/__init__.py,sha256=ure7CT2epH277sv3FqdoG-8BaydDdFnJnU1d4z15NQI,135 +pip/_vendor/pep517/__pycache__/__init__.cpython-39.pyc,, +pip/_vendor/pep517/__pycache__/_in_process.cpython-39.pyc,, +pip/_vendor/pep517/__pycache__/build.cpython-39.pyc,, +pip/_vendor/pep517/__pycache__/check.cpython-39.pyc,, +pip/_vendor/pep517/__pycache__/colorlog.cpython-39.pyc,, +pip/_vendor/pep517/__pycache__/compat.cpython-39.pyc,, +pip/_vendor/pep517/__pycache__/dirtools.cpython-39.pyc,, +pip/_vendor/pep517/__pycache__/envbuild.cpython-39.pyc,, +pip/_vendor/pep517/__pycache__/meta.cpython-39.pyc,, +pip/_vendor/pep517/__pycache__/wrappers.cpython-39.pyc,, +pip/_vendor/pep517/_in_process.py,sha256=R6B_Ol8FFxdRdbZ1R35CIL0glBjC-seixM2i0zasCTg,8718 +pip/_vendor/pep517/build.py,sha256=_LmMkH9mASElZ4lRRCwzmIrQedeguL5ocpSO0zPh6M0,3459 +pip/_vendor/pep517/check.py,sha256=qf0B_WXekszLi8IQb6Xv8raz5D5Ra-CdUmFjvnfbwdc,6164 +pip/_vendor/pep517/colorlog.py,sha256=uOdcoDYZ0ocKGRPPs5JgvpLYVDIfoEVvoMpc43ICQFU,4213 +pip/_vendor/pep517/compat.py,sha256=1jqYeQ-XtQzmaxIHxESnGU313ZBanlnusKD2gNBzRKQ,814 +pip/_vendor/pep517/dirtools.py,sha256=hrSzAJOGDo3tXdtCbgJ6LqoLhPVJn6JGmekz1ofLi6o,1173 +pip/_vendor/pep517/envbuild.py,sha256=Ji_P7ePNXexLOSqBlKyoyQqZQXNxF7-Xp3bF5XcsGgM,6208 +pip/_vendor/pep517/meta.py,sha256=ZkHYB0YHt4FDuSE5NdFuVsat3xfZ6LgW6VS6d4D6vIQ,2555 +pip/_vendor/pep517/wrappers.py,sha256=DLtY2zCWCyhWaVv8_AQcdUs0aou704Uos9vlCuiMLuc,11617 +pip/_vendor/pkg_resources/__init__.py,sha256=zeMvnKzGEcWISjTwy6YtFKWamTFJdwBwYjBAFUoyf7A,111573 +pip/_vendor/pkg_resources/__pycache__/__init__.cpython-39.pyc,, +pip/_vendor/pkg_resources/__pycache__/py31compat.cpython-39.pyc,, +pip/_vendor/pkg_resources/py31compat.py,sha256=tzQGe-w8g7GEXb6Ozw2-v8ZHaIygADmw0LAgriYzPAc,585 +pip/_vendor/progress/__init__.py,sha256=YTntFxK5CZDfVAa1b77EbNkWljGqvyM72YKRTHaHap8,5034 +pip/_vendor/progress/__pycache__/__init__.cpython-39.pyc,, +pip/_vendor/progress/__pycache__/bar.cpython-39.pyc,, +pip/_vendor/progress/__pycache__/counter.cpython-39.pyc,, +pip/_vendor/progress/__pycache__/spinner.cpython-39.pyc,, +pip/_vendor/progress/bar.py,sha256=evFQod41y2bMU60teK16uV-A5F4yVUehab8dtCiXj1E,2945 +pip/_vendor/progress/counter.py,sha256=c8AdstUGrFQvIQbvtHjjXxZx6LCflrY-a7DVM6IYTBs,1413 +pip/_vendor/progress/spinner.py,sha256=zLcx2RFinPfM6UwveJJrcJ8YABE3aLCAKqQFVD3pHow,1423 +pip/_vendor/pyparsing.py,sha256=lD3A8iEK1JYvnNDP00Cgve4vZjwEFonCvrpo7mEl3Q8,280501 +pip/_vendor/requests/__init__.py,sha256=ZPcnlAopNRpI2-4_FZKv1_SbCBwlwTxi-mKRwZhdPec,4600 +pip/_vendor/requests/__pycache__/__init__.cpython-39.pyc,, +pip/_vendor/requests/__pycache__/__version__.cpython-39.pyc,, +pip/_vendor/requests/__pycache__/_internal_utils.cpython-39.pyc,, +pip/_vendor/requests/__pycache__/adapters.cpython-39.pyc,, +pip/_vendor/requests/__pycache__/api.cpython-39.pyc,, +pip/_vendor/requests/__pycache__/auth.cpython-39.pyc,, +pip/_vendor/requests/__pycache__/certs.cpython-39.pyc,, +pip/_vendor/requests/__pycache__/compat.cpython-39.pyc,, +pip/_vendor/requests/__pycache__/cookies.cpython-39.pyc,, +pip/_vendor/requests/__pycache__/exceptions.cpython-39.pyc,, +pip/_vendor/requests/__pycache__/help.cpython-39.pyc,, +pip/_vendor/requests/__pycache__/hooks.cpython-39.pyc,, +pip/_vendor/requests/__pycache__/models.cpython-39.pyc,, +pip/_vendor/requests/__pycache__/packages.cpython-39.pyc,, +pip/_vendor/requests/__pycache__/sessions.cpython-39.pyc,, +pip/_vendor/requests/__pycache__/status_codes.cpython-39.pyc,, +pip/_vendor/requests/__pycache__/structures.cpython-39.pyc,, +pip/_vendor/requests/__pycache__/utils.cpython-39.pyc,, +pip/_vendor/requests/__version__.py,sha256=PYPw-iruqHi6_VTCebDNFpTbGld8EbCSw6EuZDH0c28,455 +pip/_vendor/requests/_internal_utils.py,sha256=zDALdxFfs4pAp4CME_TTw2rGyYR2EGBpSehYHgfn8o0,1138 +pip/_vendor/requests/adapters.py,sha256=v-nXh1zlxNzGQWQicaDrnsMmus75p2c99GPOtPl-6uw,22081 +pip/_vendor/requests/api.py,sha256=wQeIxib0gxc8KyQqF3oMwV2r7sszjJc2hbhGV_ZMzFQ,6657 +pip/_vendor/requests/auth.py,sha256=xe7s91xl3ENjQgRlZP3-2KsACnXYHAiLOuHLDw6nyyQ,10512 +pip/_vendor/requests/certs.py,sha256=fFBPJjnP90gWELetFYPbzrsfZgSZopej7XhlkrnVVec,483 +pip/_vendor/requests/compat.py,sha256=xfkhI1O0M1RPT9n92GEeoalPuBOYMsdApi7TONmwWD8,2121 +pip/_vendor/requests/cookies.py,sha256=PIxSKntoUn6l2irwR-CBMgm0scK8s-6yUZzwoCVIAdo,18979 +pip/_vendor/requests/exceptions.py,sha256=PIWWBbIjGPntNY_KDJMYzEqrBCmjh5d3rk7vZt2pXZI,3296 +pip/_vendor/requests/help.py,sha256=cU7c_l65QBsGALbTfqkHIeXpEKJ5cPih6N7Xcj9jjIQ,3697 +pip/_vendor/requests/hooks.py,sha256=LAWGUHI8SB52PkhFYbwyPcT6mWsjuVJeeZpM0RUTADc,791 +pip/_vendor/requests/models.py,sha256=JF52k_hco_uYxvg91Dhhc1c171lf7h6wVbBT0D7wxgA,35329 +pip/_vendor/requests/packages.py,sha256=ry2VlKGoCDdr8ZJyNCXxDcAF1HfENfmoylCK-_VzXh0,711 +pip/_vendor/requests/sessions.py,sha256=mpQg1Iz7Yg_IhfE87tkb2QwC3yS7JwiE3Ewe6mum_iY,30918 +pip/_vendor/requests/status_codes.py,sha256=ef_TQlJHa44J6_nrl_hTw6h7I-oZS8qg2MHCu9YyzYY,4311 +pip/_vendor/requests/structures.py,sha256=ssrNLrH8XELX89hk4yRQYEVeHnbopq1HAJBfgu38bi8,3110 +pip/_vendor/requests/utils.py,sha256=9CyTbt6eajb0LurVm10A9gSOYZ-PNSjEjz3XZ4U7Ywk,31521 +pip/_vendor/resolvelib/__init__.py,sha256=lzKfakTdPCSwU0ka5lroJTWCp5oHH50S35PI79aCufA,563 +pip/_vendor/resolvelib/__pycache__/__init__.cpython-39.pyc,, +pip/_vendor/resolvelib/__pycache__/providers.cpython-39.pyc,, +pip/_vendor/resolvelib/__pycache__/reporters.cpython-39.pyc,, +pip/_vendor/resolvelib/__pycache__/resolvers.cpython-39.pyc,, +pip/_vendor/resolvelib/__pycache__/structs.cpython-39.pyc,, +pip/_vendor/resolvelib/compat/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +pip/_vendor/resolvelib/compat/__pycache__/__init__.cpython-39.pyc,, +pip/_vendor/resolvelib/compat/__pycache__/collections_abc.cpython-39.pyc,, +pip/_vendor/resolvelib/compat/collections_abc.py,sha256=MheZFF7RxE2-89xgOpds4n99OEzq1RZTU5q4UVXNnQU,133 +pip/_vendor/resolvelib/providers.py,sha256=K5PbvYNuo9J_CgBDXknQpgNzQLuRucz8cSY-jMAry4o,5210 +pip/_vendor/resolvelib/reporters.py,sha256=Yi7l5VMEKyhL20KIEglPukQHWJHkweV4e4amcJs-4yk,1401 +pip/_vendor/resolvelib/resolvers.py,sha256=CEQp-FpwW9aKbkhrJoBoMp0i6aZx_LW-J_nENmdlU_w,16992 +pip/_vendor/resolvelib/structs.py,sha256=kbTC6heWXe96iLb0F7KdoxoTvmujcTsT5TX-ODuY2qg,4557 +pip/_vendor/retrying.py,sha256=LfbAQSee7r9F4SHbBcI1OBu7OLSDDr04Qsw9zkuC0Jw,10239 +pip/_vendor/six.py,sha256=PB_L4p2xXUH81qAYSIWp7iQRf-RU858yzM8bUfpyYBY,35141 +pip/_vendor/toml/__init__.py,sha256=mT8JBhpMcIoJeu-CrAAxPwe_d-xt-5pr9T_phq398TA,772 +pip/_vendor/toml/__pycache__/__init__.cpython-39.pyc,, +pip/_vendor/toml/__pycache__/decoder.cpython-39.pyc,, +pip/_vendor/toml/__pycache__/encoder.cpython-39.pyc,, +pip/_vendor/toml/__pycache__/ordered.cpython-39.pyc,, +pip/_vendor/toml/__pycache__/tz.cpython-39.pyc,, +pip/_vendor/toml/decoder.py,sha256=Uxh7DDx_iAkVMDWZsE4kFUZFFIklqOs_sRzFjJ0pwqY,40011 +pip/_vendor/toml/encoder.py,sha256=r7njY4Dgtsae5o5X-WS5LcQeIFguk1b3eqOioqqM1Ck,10268 +pip/_vendor/toml/ordered.py,sha256=byuDm6cI-nc2D37R4ae3soCb-k4pt48LpLh3e8LD2Fw,393 +pip/_vendor/toml/tz.py,sha256=gyy65HjpDD5I7ujKkL5iWLrUj3uFVpS08ls_btZ0uoY,725 +pip/_vendor/urllib3/__init__.py,sha256=FzLqycdKhCzSxjYOPTX50D3qf0lTCe6UgfZdwT-Li7o,2848 +pip/_vendor/urllib3/__pycache__/__init__.cpython-39.pyc,, +pip/_vendor/urllib3/__pycache__/_collections.cpython-39.pyc,, +pip/_vendor/urllib3/__pycache__/_version.cpython-39.pyc,, +pip/_vendor/urllib3/__pycache__/connection.cpython-39.pyc,, +pip/_vendor/urllib3/__pycache__/connectionpool.cpython-39.pyc,, +pip/_vendor/urllib3/__pycache__/exceptions.cpython-39.pyc,, +pip/_vendor/urllib3/__pycache__/fields.cpython-39.pyc,, +pip/_vendor/urllib3/__pycache__/filepost.cpython-39.pyc,, +pip/_vendor/urllib3/__pycache__/poolmanager.cpython-39.pyc,, +pip/_vendor/urllib3/__pycache__/request.cpython-39.pyc,, +pip/_vendor/urllib3/__pycache__/response.cpython-39.pyc,, +pip/_vendor/urllib3/_collections.py,sha256=RQtWWhudTDETvb2BCVqih1QTpXS2Q5HSf77UJY5ditA,11148 +pip/_vendor/urllib3/_version.py,sha256=y3H2R2qrG0QbjqKtuJNDmsD6z1luXDp-kD1fTjDzdGs,65 +pip/_vendor/urllib3/connection.py,sha256=lyJSLSrRVMHfktX6t9Vtvx4yBcAwOvdkSWjk3HhWfkA,19024 +pip/_vendor/urllib3/connectionpool.py,sha256=yFGc0n8ZWlHr7PaXlRGWiRydYOlJb5mVRNjXrgC7q28,38200 +pip/_vendor/urllib3/contrib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +pip/_vendor/urllib3/contrib/__pycache__/__init__.cpython-39.pyc,, +pip/_vendor/urllib3/contrib/__pycache__/_appengine_environ.cpython-39.pyc,, +pip/_vendor/urllib3/contrib/__pycache__/appengine.cpython-39.pyc,, +pip/_vendor/urllib3/contrib/__pycache__/ntlmpool.cpython-39.pyc,, +pip/_vendor/urllib3/contrib/__pycache__/pyopenssl.cpython-39.pyc,, +pip/_vendor/urllib3/contrib/__pycache__/securetransport.cpython-39.pyc,, +pip/_vendor/urllib3/contrib/__pycache__/socks.cpython-39.pyc,, +pip/_vendor/urllib3/contrib/_appengine_environ.py,sha256=POYJSeNWacJYwXQdv0If3v56lcoiHuL6MQE8pwG1Yoc,993 +pip/_vendor/urllib3/contrib/_securetransport/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +pip/_vendor/urllib3/contrib/_securetransport/__pycache__/__init__.cpython-39.pyc,, +pip/_vendor/urllib3/contrib/_securetransport/__pycache__/bindings.cpython-39.pyc,, +pip/_vendor/urllib3/contrib/_securetransport/__pycache__/low_level.cpython-39.pyc,, +pip/_vendor/urllib3/contrib/_securetransport/bindings.py,sha256=jreOmmwBW-Cio0m7I_OjmP028nqgrGuo_oB2f7Gir3s,18168 +pip/_vendor/urllib3/contrib/_securetransport/low_level.py,sha256=0KKeznz3h0z-SBDbCtGorDfgCgiZ30VQOqkX5ZgaPBY,14304 +pip/_vendor/urllib3/contrib/appengine.py,sha256=GObYFGhIv3PUW1-SRONBUac4kr2ja2dfyZhe1WJb0JY,11348 +pip/_vendor/urllib3/contrib/ntlmpool.py,sha256=xd-sWgSxZh-kNrUhzhcb7bRNiEvywF3GlRGv4xPpDI8,4281 +pip/_vendor/urllib3/contrib/pyopenssl.py,sha256=2EUnc5DS6QpjrnMMCxeT_nVuhP6Kzmw0rbo3aBCddEI,17304 +pip/_vendor/urllib3/contrib/securetransport.py,sha256=-Je5h1SDUr-8rX8dh8UZWsi90qoHkhT_oZhpsCLqwHw,35223 +pip/_vendor/urllib3/contrib/socks.py,sha256=NVZv5069T4TPXMtDnt8revc8Jgee0oxHX-zYeWrP36c,7313 +pip/_vendor/urllib3/exceptions.py,sha256=_ofwiuS3iKNqq2bodJzZ1CIXzm-hVwNJ0WMN5UoOnno,8123 +pip/_vendor/urllib3/fields.py,sha256=0KSfpuXxzXUMLkI2npM9siWOqCJO1H4wCiJN6neVmlA,8853 +pip/_vendor/urllib3/filepost.py,sha256=BVkEES0YAO9tFwXGBj1mD9yO92pRwk4pX5Q6cO5IRb8,2538 +pip/_vendor/urllib3/packages/__init__.py,sha256=FsOIVHqBFBlT3XxZnaD5y2yq0mvtVwmY4kut3GEfcBI,113 +pip/_vendor/urllib3/packages/__pycache__/__init__.cpython-39.pyc,, +pip/_vendor/urllib3/packages/__pycache__/six.cpython-39.pyc,, +pip/_vendor/urllib3/packages/backports/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +pip/_vendor/urllib3/packages/backports/__pycache__/__init__.cpython-39.pyc,, +pip/_vendor/urllib3/packages/backports/__pycache__/makefile.cpython-39.pyc,, +pip/_vendor/urllib3/packages/backports/makefile.py,sha256=DREmQjGcs2LoVH_Q3hrggClhTNdcI5Y3GJglsuihjAM,1468 +pip/_vendor/urllib3/packages/six.py,sha256=41omxbNReajvLUN-9qdHM6iAEisho1JDaZ1krmNu-jE,33557 +pip/_vendor/urllib3/packages/ssl_match_hostname/__init__.py,sha256=ceiD4ynQtrlnos1yI1RSqaETeLiNRzzAtxYsRGApR4s,779 +pip/_vendor/urllib3/packages/ssl_match_hostname/__pycache__/__init__.cpython-39.pyc,, +pip/_vendor/urllib3/packages/ssl_match_hostname/__pycache__/_implementation.cpython-39.pyc,, +pip/_vendor/urllib3/packages/ssl_match_hostname/_implementation.py,sha256=WXs1yNtk9PsYVmeTJQAcqeAm81zbzeabEWWf-xRJSAo,5839 +pip/_vendor/urllib3/poolmanager.py,sha256=blNTYqVqFg9zUGncVtyXk1HQsTxKO1Cy9hfGVLAGvhM,20299 +pip/_vendor/urllib3/request.py,sha256=Fe4bQCUhum8qh3t1dihpSsQwdyfd5nB44cNX8566DmM,6155 +pip/_vendor/urllib3/response.py,sha256=LjfUJBUhwPrJTrGgNI3WoySUizNEPd1Xiv71YxE2J7Y,29024 +pip/_vendor/urllib3/util/__init__.py,sha256=UV_J7p9b29cJXXQ6wTvBZppJDLUeKQ6mcv0v1ptl13c,1204 +pip/_vendor/urllib3/util/__pycache__/__init__.cpython-39.pyc,, +pip/_vendor/urllib3/util/__pycache__/connection.cpython-39.pyc,, +pip/_vendor/urllib3/util/__pycache__/proxy.cpython-39.pyc,, +pip/_vendor/urllib3/util/__pycache__/queue.cpython-39.pyc,, +pip/_vendor/urllib3/util/__pycache__/request.cpython-39.pyc,, +pip/_vendor/urllib3/util/__pycache__/response.cpython-39.pyc,, +pip/_vendor/urllib3/util/__pycache__/retry.cpython-39.pyc,, +pip/_vendor/urllib3/util/__pycache__/ssl_.cpython-39.pyc,, +pip/_vendor/urllib3/util/__pycache__/ssltransport.cpython-39.pyc,, +pip/_vendor/urllib3/util/__pycache__/timeout.cpython-39.pyc,, +pip/_vendor/urllib3/util/__pycache__/url.cpython-39.pyc,, +pip/_vendor/urllib3/util/__pycache__/wait.cpython-39.pyc,, +pip/_vendor/urllib3/util/connection.py,sha256=3mqDvgNGtru8tW3IFIckXj2y-6WsLFIabIRFdNMzoZs,5072 +pip/_vendor/urllib3/util/proxy.py,sha256=xMGYpCWlY1Obf1nod_fhOG3rk3NTUM2q_BJmj6B_NmU,1660 +pip/_vendor/urllib3/util/queue.py,sha256=mY2d0cfoJG51UEKZwk_sJMwYraofNfQWq7Larj9xh_o,520 +pip/_vendor/urllib3/util/request.py,sha256=O-NJTFysuN_wgY33pne8xA1P35qv3R7uh67ER9zwqYM,4266 +pip/_vendor/urllib3/util/response.py,sha256=685vBStgxTo8u3KoOilR6Kuh7IGPZr7TmzrP9awEtqU,3617 +pip/_vendor/urllib3/util/retry.py,sha256=v0qyO6YScY6KUoOmY2e_Q185IgioBJZP-_Ltthymc9Q,21967 +pip/_vendor/urllib3/util/ssl_.py,sha256=bvtqRNwp5hZBdDBhZZtKmie0r2VQZtYyPUKdq8iESGQ,16755 +pip/_vendor/urllib3/util/ssltransport.py,sha256=ALVjoGJbZJgWVjkepN82OR_YJu9-hPF49isTfDARzaM,7153 +pip/_vendor/urllib3/util/timeout.py,sha256=Ym2WjTspeYp4fzcCYGTQ5aSU1neVSMHXBAgDp1rcETw,10271 +pip/_vendor/urllib3/util/url.py,sha256=swNcZAmCREhcoLg-uk7ZhPrPRPGidDTPiAn8CpUG4h8,14411 +pip/_vendor/urllib3/util/wait.py,sha256=qk2qJQNb3FjhOm9lKJtpByhnsLWRVapWdhW_NLr7Eog,5557 +pip/_vendor/vendor.txt,sha256=vZicYA5EfWGG74RBvGLyAfH0dqIZ0KACbWfDJ9IIOZI,412 +pip/_vendor/webencodings/__init__.py,sha256=kG5cBDbIrAtrrdU-h1iSPVYq10ayTFldU1CTRcb1ym4,10921 +pip/_vendor/webencodings/__pycache__/__init__.cpython-39.pyc,, +pip/_vendor/webencodings/__pycache__/labels.cpython-39.pyc,, +pip/_vendor/webencodings/__pycache__/mklabels.cpython-39.pyc,, +pip/_vendor/webencodings/__pycache__/tests.cpython-39.pyc,, +pip/_vendor/webencodings/__pycache__/x_user_defined.cpython-39.pyc,, +pip/_vendor/webencodings/labels.py,sha256=e9gPVTA1XNYalJMVVX7lXvb52Kurc4UdnXFJDPcBXFE,9210 +pip/_vendor/webencodings/mklabels.py,sha256=tyhoDDc-TC6kjJY25Qn5TlsyMs2_IyPf_rfh4L6nSrg,1364 +pip/_vendor/webencodings/tests.py,sha256=7J6TdufKEml8sQSWcYEsl-e73QXtPmsIHF6pPT0sq08,6716 +pip/_vendor/webencodings/x_user_defined.py,sha256=CMn5bx2ccJ4y3Bsqf3xC24bYO4ONC3ZY_lv5vrqhKAY,4632 diff --git a/venv/Lib/site-packages/pip-21.0.1.dist-info/WHEEL b/venv/Lib/site-packages/pip-21.0.1.dist-info/WHEEL new file mode 100644 index 0000000..385faab --- /dev/null +++ b/venv/Lib/site-packages/pip-21.0.1.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.36.2) +Root-Is-Purelib: true +Tag: py3-none-any + diff --git a/venv/Lib/site-packages/pip-21.0.1.dist-info/entry_points.txt b/venv/Lib/site-packages/pip-21.0.1.dist-info/entry_points.txt new file mode 100644 index 0000000..9609f72 --- /dev/null +++ b/venv/Lib/site-packages/pip-21.0.1.dist-info/entry_points.txt @@ -0,0 +1,5 @@ +[console_scripts] +pip = pip._internal.cli.main:main +pip3 = pip._internal.cli.main:main +pip3.9 = pip._internal.cli.main:main + diff --git a/venv/Lib/site-packages/pip-21.0.1.dist-info/top_level.txt b/venv/Lib/site-packages/pip-21.0.1.dist-info/top_level.txt new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/venv/Lib/site-packages/pip-21.0.1.dist-info/top_level.txt @@ -0,0 +1 @@ +pip diff --git a/venv/Lib/site-packages/pip/__init__.py b/venv/Lib/site-packages/pip/__init__.py new file mode 100644 index 0000000..cb041b5 --- /dev/null +++ b/venv/Lib/site-packages/pip/__init__.py @@ -0,0 +1,18 @@ +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import List, Optional + + +__version__ = "21.0.1" + + +def main(args=None): + # type: (Optional[List[str]]) -> int + """This is an internal API only meant for use by pip's own console scripts. + + For additional details, see https://github.com/pypa/pip/issues/7498. + """ + from pip._internal.utils.entrypoints import _wrapper + + return _wrapper(args) diff --git a/venv/Lib/site-packages/pip/__main__.py b/venv/Lib/site-packages/pip/__main__.py new file mode 100644 index 0000000..1005489 --- /dev/null +++ b/venv/Lib/site-packages/pip/__main__.py @@ -0,0 +1,24 @@ +import os +import sys + +# Remove '' and current working directory from the first entry +# of sys.path, if present to avoid using current directory +# in pip commands check, freeze, install, list and show, +# when invoked as python -m pip +if sys.path[0] in ('', os.getcwd()): + sys.path.pop(0) + +# If we are running from a wheel, add the wheel to sys.path +# This allows the usage python pip-*.whl/pip install pip-*.whl +if __package__ == '': + # __file__ is pip-*.whl/pip/__main__.py + # first dirname call strips of '/__main__.py', second strips off '/pip' + # Resulting path is the name of the wheel itself + # Add that to sys.path so we can import pip + path = os.path.dirname(os.path.dirname(__file__)) + sys.path.insert(0, path) + +from pip._internal.cli.main import main as _main + +if __name__ == '__main__': + sys.exit(_main()) diff --git a/venv/Lib/site-packages/pip/_internal/__init__.py b/venv/Lib/site-packages/pip/_internal/__init__.py new file mode 100644 index 0000000..a778e99 --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/__init__.py @@ -0,0 +1,17 @@ +import pip._internal.utils.inject_securetransport # noqa +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import List, Optional + + +def main(args=None): + # type: (Optional[List[str]]) -> int + """This is preserved for old console scripts that may still be referencing + it. + + For additional details, see https://github.com/pypa/pip/issues/7498. + """ + from pip._internal.utils.entrypoints import _wrapper + + return _wrapper(args) diff --git a/venv/Lib/site-packages/pip/_internal/build_env.py b/venv/Lib/site-packages/pip/_internal/build_env.py new file mode 100644 index 0000000..a587d9f --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/build_env.py @@ -0,0 +1,242 @@ +"""Build Environment used for isolation during sdist building +""" + +import logging +import os +import sys +import textwrap +from collections import OrderedDict +from distutils.sysconfig import get_python_lib +from sysconfig import get_paths + +from pip._vendor.pkg_resources import Requirement, VersionConflict, WorkingSet + +from pip import __file__ as pip_location +from pip._internal.cli.spinners import open_spinner +from pip._internal.utils.subprocess import call_subprocess +from pip._internal.utils.temp_dir import TempDirectory, tempdir_kinds +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from types import TracebackType + from typing import Iterable, List, Optional, Set, Tuple, Type + + from pip._internal.index.package_finder import PackageFinder + +logger = logging.getLogger(__name__) + + +class _Prefix: + + def __init__(self, path): + # type: (str) -> None + self.path = path + self.setup = False + self.bin_dir = get_paths( + 'nt' if os.name == 'nt' else 'posix_prefix', + vars={'base': path, 'platbase': path} + )['scripts'] + # Note: prefer distutils' sysconfig to get the + # library paths so PyPy is correctly supported. + purelib = get_python_lib(plat_specific=False, prefix=path) + platlib = get_python_lib(plat_specific=True, prefix=path) + if purelib == platlib: + self.lib_dirs = [purelib] + else: + self.lib_dirs = [purelib, platlib] + + +class BuildEnvironment: + """Creates and manages an isolated environment to install build deps + """ + + def __init__(self): + # type: () -> None + temp_dir = TempDirectory( + kind=tempdir_kinds.BUILD_ENV, globally_managed=True + ) + + self._prefixes = OrderedDict(( + (name, _Prefix(os.path.join(temp_dir.path, name))) + for name in ('normal', 'overlay') + )) + + self._bin_dirs = [] # type: List[str] + self._lib_dirs = [] # type: List[str] + for prefix in reversed(list(self._prefixes.values())): + self._bin_dirs.append(prefix.bin_dir) + self._lib_dirs.extend(prefix.lib_dirs) + + # Customize site to: + # - ensure .pth files are honored + # - prevent access to system site packages + system_sites = { + os.path.normcase(site) for site in ( + get_python_lib(plat_specific=False), + get_python_lib(plat_specific=True), + ) + } + self._site_dir = os.path.join(temp_dir.path, 'site') + if not os.path.exists(self._site_dir): + os.mkdir(self._site_dir) + with open(os.path.join(self._site_dir, 'sitecustomize.py'), 'w') as fp: + fp.write(textwrap.dedent( + ''' + import os, site, sys + + # First, drop system-sites related paths. + original_sys_path = sys.path[:] + known_paths = set() + for path in {system_sites!r}: + site.addsitedir(path, known_paths=known_paths) + system_paths = set( + os.path.normcase(path) + for path in sys.path[len(original_sys_path):] + ) + original_sys_path = [ + path for path in original_sys_path + if os.path.normcase(path) not in system_paths + ] + sys.path = original_sys_path + + # Second, add lib directories. + # ensuring .pth file are processed. + for path in {lib_dirs!r}: + assert not path in sys.path + site.addsitedir(path) + ''' + ).format(system_sites=system_sites, lib_dirs=self._lib_dirs)) + + def __enter__(self): + # type: () -> None + self._save_env = { + name: os.environ.get(name, None) + for name in ('PATH', 'PYTHONNOUSERSITE', 'PYTHONPATH') + } + + path = self._bin_dirs[:] + old_path = self._save_env['PATH'] + if old_path: + path.extend(old_path.split(os.pathsep)) + + pythonpath = [self._site_dir] + + os.environ.update({ + 'PATH': os.pathsep.join(path), + 'PYTHONNOUSERSITE': '1', + 'PYTHONPATH': os.pathsep.join(pythonpath), + }) + + def __exit__( + self, + exc_type, # type: Optional[Type[BaseException]] + exc_val, # type: Optional[BaseException] + exc_tb # type: Optional[TracebackType] + ): + # type: (...) -> None + for varname, old_value in self._save_env.items(): + if old_value is None: + os.environ.pop(varname, None) + else: + os.environ[varname] = old_value + + def check_requirements(self, reqs): + # type: (Iterable[str]) -> Tuple[Set[Tuple[str, str]], Set[str]] + """Return 2 sets: + - conflicting requirements: set of (installed, wanted) reqs tuples + - missing requirements: set of reqs + """ + missing = set() + conflicting = set() + if reqs: + ws = WorkingSet(self._lib_dirs) + for req in reqs: + try: + if ws.find(Requirement.parse(req)) is None: + missing.add(req) + except VersionConflict as e: + conflicting.add((str(e.args[0].as_requirement()), + str(e.args[1]))) + return conflicting, missing + + def install_requirements( + self, + finder, # type: PackageFinder + requirements, # type: Iterable[str] + prefix_as_string, # type: str + message # type: str + ): + # type: (...) -> None + prefix = self._prefixes[prefix_as_string] + assert not prefix.setup + prefix.setup = True + if not requirements: + return + args = [ + sys.executable, os.path.dirname(pip_location), 'install', + '--ignore-installed', '--no-user', '--prefix', prefix.path, + '--no-warn-script-location', + ] # type: List[str] + if logger.getEffectiveLevel() <= logging.DEBUG: + args.append('-v') + for format_control in ('no_binary', 'only_binary'): + formats = getattr(finder.format_control, format_control) + args.extend(('--' + format_control.replace('_', '-'), + ','.join(sorted(formats or {':none:'})))) + + index_urls = finder.index_urls + if index_urls: + args.extend(['-i', index_urls[0]]) + for extra_index in index_urls[1:]: + args.extend(['--extra-index-url', extra_index]) + else: + args.append('--no-index') + for link in finder.find_links: + args.extend(['--find-links', link]) + + for host in finder.trusted_hosts: + args.extend(['--trusted-host', host]) + if finder.allow_all_prereleases: + args.append('--pre') + if finder.prefer_binary: + args.append('--prefer-binary') + args.append('--') + args.extend(requirements) + with open_spinner(message) as spinner: + call_subprocess(args, spinner=spinner) + + +class NoOpBuildEnvironment(BuildEnvironment): + """A no-op drop-in replacement for BuildEnvironment + """ + + def __init__(self): + # type: () -> None + pass + + def __enter__(self): + # type: () -> None + pass + + def __exit__( + self, + exc_type, # type: Optional[Type[BaseException]] + exc_val, # type: Optional[BaseException] + exc_tb # type: Optional[TracebackType] + ): + # type: (...) -> None + pass + + def cleanup(self): + # type: () -> None + pass + + def install_requirements( + self, + finder, # type: PackageFinder + requirements, # type: Iterable[str] + prefix_as_string, # type: str + message # type: str + ): + # type: (...) -> None + raise NotImplementedError() diff --git a/venv/Lib/site-packages/pip/_internal/cache.py b/venv/Lib/site-packages/pip/_internal/cache.py new file mode 100644 index 0000000..5e7db9c --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/cache.py @@ -0,0 +1,293 @@ +"""Cache Management +""" + +import hashlib +import json +import logging +import os + +from pip._vendor.packaging.tags import interpreter_name, interpreter_version +from pip._vendor.packaging.utils import canonicalize_name + +from pip._internal.exceptions import InvalidWheelFilename +from pip._internal.models.link import Link +from pip._internal.models.wheel import Wheel +from pip._internal.utils.temp_dir import TempDirectory, tempdir_kinds +from pip._internal.utils.typing import MYPY_CHECK_RUNNING +from pip._internal.utils.urls import path_to_url + +if MYPY_CHECK_RUNNING: + from typing import Any, Dict, List, Optional, Set + + from pip._vendor.packaging.tags import Tag + + from pip._internal.models.format_control import FormatControl + +logger = logging.getLogger(__name__) + + +def _hash_dict(d): + # type: (Dict[str, str]) -> str + """Return a stable sha224 of a dictionary.""" + s = json.dumps(d, sort_keys=True, separators=(",", ":"), ensure_ascii=True) + return hashlib.sha224(s.encode("ascii")).hexdigest() + + +class Cache: + """An abstract class - provides cache directories for data from links + + + :param cache_dir: The root of the cache. + :param format_control: An object of FormatControl class to limit + binaries being read from the cache. + :param allowed_formats: which formats of files the cache should store. + ('binary' and 'source' are the only allowed values) + """ + + def __init__(self, cache_dir, format_control, allowed_formats): + # type: (str, FormatControl, Set[str]) -> None + super().__init__() + assert not cache_dir or os.path.isabs(cache_dir) + self.cache_dir = cache_dir or None + self.format_control = format_control + self.allowed_formats = allowed_formats + + _valid_formats = {"source", "binary"} + assert self.allowed_formats.union(_valid_formats) == _valid_formats + + def _get_cache_path_parts(self, link): + # type: (Link) -> List[str] + """Get parts of part that must be os.path.joined with cache_dir + """ + + # We want to generate an url to use as our cache key, we don't want to + # just re-use the URL because it might have other items in the fragment + # and we don't care about those. + key_parts = {"url": link.url_without_fragment} + if link.hash_name is not None and link.hash is not None: + key_parts[link.hash_name] = link.hash + if link.subdirectory_fragment: + key_parts["subdirectory"] = link.subdirectory_fragment + + # Include interpreter name, major and minor version in cache key + # to cope with ill-behaved sdists that build a different wheel + # depending on the python version their setup.py is being run on, + # and don't encode the difference in compatibility tags. + # https://github.com/pypa/pip/issues/7296 + key_parts["interpreter_name"] = interpreter_name() + key_parts["interpreter_version"] = interpreter_version() + + # Encode our key url with sha224, we'll use this because it has similar + # security properties to sha256, but with a shorter total output (and + # thus less secure). However the differences don't make a lot of + # difference for our use case here. + hashed = _hash_dict(key_parts) + + # We want to nest the directories some to prevent having a ton of top + # level directories where we might run out of sub directories on some + # FS. + parts = [hashed[:2], hashed[2:4], hashed[4:6], hashed[6:]] + + return parts + + def _get_candidates(self, link, canonical_package_name): + # type: (Link, str) -> List[Any] + can_not_cache = ( + not self.cache_dir or + not canonical_package_name or + not link + ) + if can_not_cache: + return [] + + formats = self.format_control.get_allowed_formats( + canonical_package_name + ) + if not self.allowed_formats.intersection(formats): + return [] + + candidates = [] + path = self.get_path_for_link(link) + if os.path.isdir(path): + for candidate in os.listdir(path): + candidates.append((candidate, path)) + return candidates + + def get_path_for_link(self, link): + # type: (Link) -> str + """Return a directory to store cached items in for link. + """ + raise NotImplementedError() + + def get( + self, + link, # type: Link + package_name, # type: Optional[str] + supported_tags, # type: List[Tag] + ): + # type: (...) -> Link + """Returns a link to a cached item if it exists, otherwise returns the + passed link. + """ + raise NotImplementedError() + + +class SimpleWheelCache(Cache): + """A cache of wheels for future installs. + """ + + def __init__(self, cache_dir, format_control): + # type: (str, FormatControl) -> None + super().__init__(cache_dir, format_control, {"binary"}) + + def get_path_for_link(self, link): + # type: (Link) -> str + """Return a directory to store cached wheels for link + + Because there are M wheels for any one sdist, we provide a directory + to cache them in, and then consult that directory when looking up + cache hits. + + We only insert things into the cache if they have plausible version + numbers, so that we don't contaminate the cache with things that were + not unique. E.g. ./package might have dozens of installs done for it + and build a version of 0.0...and if we built and cached a wheel, we'd + end up using the same wheel even if the source has been edited. + + :param link: The link of the sdist for which this will cache wheels. + """ + parts = self._get_cache_path_parts(link) + assert self.cache_dir + # Store wheels within the root cache_dir + return os.path.join(self.cache_dir, "wheels", *parts) + + def get( + self, + link, # type: Link + package_name, # type: Optional[str] + supported_tags, # type: List[Tag] + ): + # type: (...) -> Link + candidates = [] + + if not package_name: + return link + + canonical_package_name = canonicalize_name(package_name) + for wheel_name, wheel_dir in self._get_candidates( + link, canonical_package_name + ): + try: + wheel = Wheel(wheel_name) + except InvalidWheelFilename: + continue + if canonicalize_name(wheel.name) != canonical_package_name: + logger.debug( + "Ignoring cached wheel %s for %s as it " + "does not match the expected distribution name %s.", + wheel_name, link, package_name, + ) + continue + if not wheel.supported(supported_tags): + # Built for a different python/arch/etc + continue + candidates.append( + ( + wheel.support_index_min(supported_tags), + wheel_name, + wheel_dir, + ) + ) + + if not candidates: + return link + + _, wheel_name, wheel_dir = min(candidates) + return Link(path_to_url(os.path.join(wheel_dir, wheel_name))) + + +class EphemWheelCache(SimpleWheelCache): + """A SimpleWheelCache that creates it's own temporary cache directory + """ + + def __init__(self, format_control): + # type: (FormatControl) -> None + self._temp_dir = TempDirectory( + kind=tempdir_kinds.EPHEM_WHEEL_CACHE, + globally_managed=True, + ) + + super().__init__(self._temp_dir.path, format_control) + + +class CacheEntry: + def __init__( + self, + link, # type: Link + persistent, # type: bool + ): + self.link = link + self.persistent = persistent + + +class WheelCache(Cache): + """Wraps EphemWheelCache and SimpleWheelCache into a single Cache + + This Cache allows for gracefully degradation, using the ephem wheel cache + when a certain link is not found in the simple wheel cache first. + """ + + def __init__(self, cache_dir, format_control): + # type: (str, FormatControl) -> None + super().__init__(cache_dir, format_control, {'binary'}) + self._wheel_cache = SimpleWheelCache(cache_dir, format_control) + self._ephem_cache = EphemWheelCache(format_control) + + def get_path_for_link(self, link): + # type: (Link) -> str + return self._wheel_cache.get_path_for_link(link) + + def get_ephem_path_for_link(self, link): + # type: (Link) -> str + return self._ephem_cache.get_path_for_link(link) + + def get( + self, + link, # type: Link + package_name, # type: Optional[str] + supported_tags, # type: List[Tag] + ): + # type: (...) -> Link + cache_entry = self.get_cache_entry(link, package_name, supported_tags) + if cache_entry is None: + return link + return cache_entry.link + + def get_cache_entry( + self, + link, # type: Link + package_name, # type: Optional[str] + supported_tags, # type: List[Tag] + ): + # type: (...) -> Optional[CacheEntry] + """Returns a CacheEntry with a link to a cached item if it exists or + None. The cache entry indicates if the item was found in the persistent + or ephemeral cache. + """ + retval = self._wheel_cache.get( + link=link, + package_name=package_name, + supported_tags=supported_tags, + ) + if retval is not link: + return CacheEntry(retval, persistent=True) + + retval = self._ephem_cache.get( + link=link, + package_name=package_name, + supported_tags=supported_tags, + ) + if retval is not link: + return CacheEntry(retval, persistent=False) + + return None diff --git a/venv/Lib/site-packages/pip/_internal/cli/__init__.py b/venv/Lib/site-packages/pip/_internal/cli/__init__.py new file mode 100644 index 0000000..e589bb9 --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/cli/__init__.py @@ -0,0 +1,4 @@ +"""Subpackage containing all of pip's command line interface related code +""" + +# This file intentionally does not import submodules diff --git a/venv/Lib/site-packages/pip/_internal/cli/autocompletion.py b/venv/Lib/site-packages/pip/_internal/cli/autocompletion.py new file mode 100644 index 0000000..329de60 --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/cli/autocompletion.py @@ -0,0 +1,164 @@ +"""Logic that powers autocompletion installed by ``pip completion``. +""" + +import optparse +import os +import sys +from itertools import chain + +from pip._internal.cli.main_parser import create_main_parser +from pip._internal.commands import commands_dict, create_command +from pip._internal.utils.misc import get_installed_distributions +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import Any, Iterable, List, Optional + + +def autocomplete(): + # type: () -> None + """Entry Point for completion of main and subcommand options. + """ + # Don't complete if user hasn't sourced bash_completion file. + if 'PIP_AUTO_COMPLETE' not in os.environ: + return + cwords = os.environ['COMP_WORDS'].split()[1:] + cword = int(os.environ['COMP_CWORD']) + try: + current = cwords[cword - 1] + except IndexError: + current = '' + + parser = create_main_parser() + subcommands = list(commands_dict) + options = [] + + # subcommand + subcommand_name = None # type: Optional[str] + for word in cwords: + if word in subcommands: + subcommand_name = word + break + # subcommand options + if subcommand_name is not None: + # special case: 'help' subcommand has no options + if subcommand_name == 'help': + sys.exit(1) + # special case: list locally installed dists for show and uninstall + should_list_installed = ( + subcommand_name in ['show', 'uninstall'] and + not current.startswith('-') + ) + if should_list_installed: + installed = [] + lc = current.lower() + for dist in get_installed_distributions(local_only=True): + if dist.key.startswith(lc) and dist.key not in cwords[1:]: + installed.append(dist.key) + # if there are no dists installed, fall back to option completion + if installed: + for dist in installed: + print(dist) + sys.exit(1) + + subcommand = create_command(subcommand_name) + + for opt in subcommand.parser.option_list_all: + if opt.help != optparse.SUPPRESS_HELP: + for opt_str in opt._long_opts + opt._short_opts: + options.append((opt_str, opt.nargs)) + + # filter out previously specified options from available options + prev_opts = [x.split('=')[0] for x in cwords[1:cword - 1]] + options = [(x, v) for (x, v) in options if x not in prev_opts] + # filter options by current input + options = [(k, v) for k, v in options if k.startswith(current)] + # get completion type given cwords and available subcommand options + completion_type = get_path_completion_type( + cwords, cword, subcommand.parser.option_list_all, + ) + # get completion files and directories if ``completion_type`` is + # ````, ```` or ```` + if completion_type: + paths = auto_complete_paths(current, completion_type) + options = [(path, 0) for path in paths] + for option in options: + opt_label = option[0] + # append '=' to options which require args + if option[1] and option[0][:2] == "--": + opt_label += '=' + print(opt_label) + else: + # show main parser options only when necessary + + opts = [i.option_list for i in parser.option_groups] + opts.append(parser.option_list) + flattened_opts = chain.from_iterable(opts) + if current.startswith('-'): + for opt in flattened_opts: + if opt.help != optparse.SUPPRESS_HELP: + subcommands += opt._long_opts + opt._short_opts + else: + # get completion type given cwords and all available options + completion_type = get_path_completion_type(cwords, cword, + flattened_opts) + if completion_type: + subcommands = list(auto_complete_paths(current, + completion_type)) + + print(' '.join([x for x in subcommands if x.startswith(current)])) + sys.exit(1) + + +def get_path_completion_type(cwords, cword, opts): + # type: (List[str], int, Iterable[Any]) -> Optional[str] + """Get the type of path completion (``file``, ``dir``, ``path`` or None) + + :param cwords: same as the environmental variable ``COMP_WORDS`` + :param cword: same as the environmental variable ``COMP_CWORD`` + :param opts: The available options to check + :return: path completion type (``file``, ``dir``, ``path`` or None) + """ + if cword < 2 or not cwords[cword - 2].startswith('-'): + return None + for opt in opts: + if opt.help == optparse.SUPPRESS_HELP: + continue + for o in str(opt).split('/'): + if cwords[cword - 2].split('=')[0] == o: + if not opt.metavar or any( + x in ('path', 'file', 'dir') + for x in opt.metavar.split('/')): + return opt.metavar + return None + + +def auto_complete_paths(current, completion_type): + # type: (str, str) -> Iterable[str] + """If ``completion_type`` is ``file`` or ``path``, list all regular files + and directories starting with ``current``; otherwise only list directories + starting with ``current``. + + :param current: The word to be completed + :param completion_type: path completion type(`file`, `path` or `dir`)i + :return: A generator of regular files and/or directories + """ + directory, filename = os.path.split(current) + current_path = os.path.abspath(directory) + # Don't complete paths if they can't be accessed + if not os.access(current_path, os.R_OK): + return + filename = os.path.normcase(filename) + # list all files that start with ``filename`` + file_list = (x for x in os.listdir(current_path) + if os.path.normcase(x).startswith(filename)) + for f in file_list: + opt = os.path.join(current_path, f) + comp_file = os.path.normcase(os.path.join(directory, f)) + # complete regular files when there is not ```` after option + # complete directories when there is ````, ```` or + # ````after option + if completion_type != 'dir' and os.path.isfile(opt): + yield comp_file + elif os.path.isdir(opt): + yield os.path.join(comp_file, '') diff --git a/venv/Lib/site-packages/pip/_internal/cli/base_command.py b/venv/Lib/site-packages/pip/_internal/cli/base_command.py new file mode 100644 index 0000000..fac76bb --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/cli/base_command.py @@ -0,0 +1,226 @@ +"""Base Command class, and related routines""" + +import logging +import logging.config +import optparse +import os +import sys +import traceback + +from pip._internal.cli import cmdoptions +from pip._internal.cli.command_context import CommandContextMixIn +from pip._internal.cli.parser import ConfigOptionParser, UpdatingDefaultsHelpFormatter +from pip._internal.cli.status_codes import ( + ERROR, + PREVIOUS_BUILD_DIR_ERROR, + UNKNOWN_ERROR, + VIRTUALENV_NOT_FOUND, +) +from pip._internal.exceptions import ( + BadCommand, + CommandError, + InstallationError, + NetworkConnectionError, + PreviousBuildDirError, + UninstallationError, +) +from pip._internal.utils.deprecation import deprecated +from pip._internal.utils.filesystem import check_path_owner +from pip._internal.utils.logging import BrokenStdoutLoggingError, setup_logging +from pip._internal.utils.misc import get_prog, normalize_path +from pip._internal.utils.temp_dir import global_tempdir_manager, tempdir_registry +from pip._internal.utils.typing import MYPY_CHECK_RUNNING +from pip._internal.utils.virtualenv import running_under_virtualenv + +if MYPY_CHECK_RUNNING: + from optparse import Values + from typing import Any, List, Optional, Tuple + + from pip._internal.utils.temp_dir import ( + TempDirectoryTypeRegistry as TempDirRegistry, + ) + +__all__ = ['Command'] + +logger = logging.getLogger(__name__) + + +class Command(CommandContextMixIn): + usage = None # type: str + ignore_require_venv = False # type: bool + + def __init__(self, name, summary, isolated=False): + # type: (str, str, bool) -> None + super().__init__() + parser_kw = { + 'usage': self.usage, + 'prog': f'{get_prog()} {name}', + 'formatter': UpdatingDefaultsHelpFormatter(), + 'add_help_option': False, + 'name': name, + 'description': self.__doc__, + 'isolated': isolated, + } + + self.name = name + self.summary = summary + self.parser = ConfigOptionParser(**parser_kw) + + self.tempdir_registry = None # type: Optional[TempDirRegistry] + + # Commands should add options to this option group + optgroup_name = f'{self.name.capitalize()} Options' + self.cmd_opts = optparse.OptionGroup(self.parser, optgroup_name) + + # Add the general options + gen_opts = cmdoptions.make_option_group( + cmdoptions.general_group, + self.parser, + ) + self.parser.add_option_group(gen_opts) + + self.add_options() + + def add_options(self): + # type: () -> None + pass + + def handle_pip_version_check(self, options): + # type: (Values) -> None + """ + This is a no-op so that commands by default do not do the pip version + check. + """ + # Make sure we do the pip version check if the index_group options + # are present. + assert not hasattr(options, 'no_index') + + def run(self, options, args): + # type: (Values, List[Any]) -> int + raise NotImplementedError + + def parse_args(self, args): + # type: (List[str]) -> Tuple[Any, Any] + # factored out for testability + return self.parser.parse_args(args) + + def main(self, args): + # type: (List[str]) -> int + try: + with self.main_context(): + return self._main(args) + finally: + logging.shutdown() + + def _main(self, args): + # type: (List[str]) -> int + # We must initialize this before the tempdir manager, otherwise the + # configuration would not be accessible by the time we clean up the + # tempdir manager. + self.tempdir_registry = self.enter_context(tempdir_registry()) + # Intentionally set as early as possible so globally-managed temporary + # directories are available to the rest of the code. + self.enter_context(global_tempdir_manager()) + + options, args = self.parse_args(args) + + # Set verbosity so that it can be used elsewhere. + self.verbosity = options.verbose - options.quiet + + level_number = setup_logging( + verbosity=self.verbosity, + no_color=options.no_color, + user_log_file=options.log, + ) + + # TODO: Try to get these passing down from the command? + # without resorting to os.environ to hold these. + # This also affects isolated builds and it should. + + if options.no_input: + os.environ['PIP_NO_INPUT'] = '1' + + if options.exists_action: + os.environ['PIP_EXISTS_ACTION'] = ' '.join(options.exists_action) + + if options.require_venv and not self.ignore_require_venv: + # If a venv is required check if it can really be found + if not running_under_virtualenv(): + logger.critical( + 'Could not find an activated virtualenv (required).' + ) + sys.exit(VIRTUALENV_NOT_FOUND) + + if options.cache_dir: + options.cache_dir = normalize_path(options.cache_dir) + if not check_path_owner(options.cache_dir): + logger.warning( + "The directory '%s' or its parent directory is not owned " + "or is not writable by the current user. The cache " + "has been disabled. Check the permissions and owner of " + "that directory. If executing pip with sudo, you may want " + "sudo's -H flag.", + options.cache_dir, + ) + options.cache_dir = None + + if getattr(options, "build_dir", None): + deprecated( + reason=( + "The -b/--build/--build-dir/--build-directory " + "option is deprecated and has no effect anymore." + ), + replacement=( + "use the TMPDIR/TEMP/TMP environment variable, " + "possibly combined with --no-clean" + ), + gone_in="21.1", + issue=8333, + ) + + if '2020-resolver' in options.features_enabled: + logger.warning( + "--use-feature=2020-resolver no longer has any effect, " + "since it is now the default dependency resolver in pip. " + "This will become an error in pip 21.0." + ) + + try: + status = self.run(options, args) + assert isinstance(status, int) + return status + except PreviousBuildDirError as exc: + logger.critical(str(exc)) + logger.debug('Exception information:', exc_info=True) + + return PREVIOUS_BUILD_DIR_ERROR + except (InstallationError, UninstallationError, BadCommand, + NetworkConnectionError) as exc: + logger.critical(str(exc)) + logger.debug('Exception information:', exc_info=True) + + return ERROR + except CommandError as exc: + logger.critical('%s', exc) + logger.debug('Exception information:', exc_info=True) + + return ERROR + except BrokenStdoutLoggingError: + # Bypass our logger and write any remaining messages to stderr + # because stdout no longer works. + print('ERROR: Pipe to stdout was broken', file=sys.stderr) + if level_number <= logging.DEBUG: + traceback.print_exc(file=sys.stderr) + + return ERROR + except KeyboardInterrupt: + logger.critical('Operation cancelled by user') + logger.debug('Exception information:', exc_info=True) + + return ERROR + except BaseException: + logger.critical('Exception:', exc_info=True) + + return UNKNOWN_ERROR + finally: + self.handle_pip_version_check(options) diff --git a/venv/Lib/site-packages/pip/_internal/cli/cmdoptions.py b/venv/Lib/site-packages/pip/_internal/cli/cmdoptions.py new file mode 100644 index 0000000..6631439 --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/cli/cmdoptions.py @@ -0,0 +1,969 @@ +""" +shared options and groups + +The principle here is to define options once, but *not* instantiate them +globally. One reason being that options with action='append' can carry state +between parses. pip parses general options twice internally, and shouldn't +pass on state. To be consistent, all options will follow this design. +""" + +# The following comment should be removed at some point in the future. +# mypy: strict-optional=False + +import os +import textwrap +import warnings +from functools import partial +from optparse import SUPPRESS_HELP, Option, OptionGroup +from textwrap import dedent + +from pip._vendor.packaging.utils import canonicalize_name + +from pip._internal.cli.progress_bars import BAR_TYPES +from pip._internal.exceptions import CommandError +from pip._internal.locations import USER_CACHE_DIR, get_src_prefix +from pip._internal.models.format_control import FormatControl +from pip._internal.models.index import PyPI +from pip._internal.models.target_python import TargetPython +from pip._internal.utils.hashes import STRONG_HASHES +from pip._internal.utils.misc import strtobool +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from optparse import OptionParser, Values + from typing import Any, Callable, Dict, Optional, Tuple + + from pip._internal.cli.parser import ConfigOptionParser + + +def raise_option_error(parser, option, msg): + # type: (OptionParser, Option, str) -> None + """ + Raise an option parsing error using parser.error(). + + Args: + parser: an OptionParser instance. + option: an Option instance. + msg: the error text. + """ + msg = f'{option} error: {msg}' + msg = textwrap.fill(' '.join(msg.split())) + parser.error(msg) + + +def make_option_group(group, parser): + # type: (Dict[str, Any], ConfigOptionParser) -> OptionGroup + """ + Return an OptionGroup object + group -- assumed to be dict with 'name' and 'options' keys + parser -- an optparse Parser + """ + option_group = OptionGroup(parser, group['name']) + for option in group['options']: + option_group.add_option(option()) + return option_group + + +def check_install_build_global(options, check_options=None): + # type: (Values, Optional[Values]) -> None + """Disable wheels if per-setup.py call options are set. + + :param options: The OptionParser options to update. + :param check_options: The options to check, if not supplied defaults to + options. + """ + if check_options is None: + check_options = options + + def getname(n): + # type: (str) -> Optional[Any] + return getattr(check_options, n, None) + names = ["build_options", "global_options", "install_options"] + if any(map(getname, names)): + control = options.format_control + control.disallow_binaries() + warnings.warn( + 'Disabling all use of wheels due to the use of --build-option ' + '/ --global-option / --install-option.', stacklevel=2, + ) + + +def check_dist_restriction(options, check_target=False): + # type: (Values, bool) -> None + """Function for determining if custom platform options are allowed. + + :param options: The OptionParser options. + :param check_target: Whether or not to check if --target is being used. + """ + dist_restriction_set = any([ + options.python_version, + options.platforms, + options.abis, + options.implementation, + ]) + + binary_only = FormatControl(set(), {':all:'}) + sdist_dependencies_allowed = ( + options.format_control != binary_only and + not options.ignore_dependencies + ) + + # Installations or downloads using dist restrictions must not combine + # source distributions and dist-specific wheels, as they are not + # guaranteed to be locally compatible. + if dist_restriction_set and sdist_dependencies_allowed: + raise CommandError( + "When restricting platform and interpreter constraints using " + "--python-version, --platform, --abi, or --implementation, " + "either --no-deps must be set, or --only-binary=:all: must be " + "set and --no-binary must not be set (or must be set to " + ":none:)." + ) + + if check_target: + if dist_restriction_set and not options.target_dir: + raise CommandError( + "Can not use any platform or abi specific options unless " + "installing via '--target'" + ) + + +def _path_option_check(option, opt, value): + # type: (Option, str, str) -> str + return os.path.expanduser(value) + + +def _package_name_option_check(option, opt, value): + # type: (Option, str, str) -> str + return canonicalize_name(value) + + +class PipOption(Option): + TYPES = Option.TYPES + ("path", "package_name") + TYPE_CHECKER = Option.TYPE_CHECKER.copy() + TYPE_CHECKER["package_name"] = _package_name_option_check + TYPE_CHECKER["path"] = _path_option_check + + +########### +# options # +########### + +help_ = partial( + Option, + '-h', '--help', + dest='help', + action='help', + help='Show help.', +) # type: Callable[..., Option] + +isolated_mode = partial( + Option, + "--isolated", + dest="isolated_mode", + action="store_true", + default=False, + help=( + "Run pip in an isolated mode, ignoring environment variables and user " + "configuration." + ), +) # type: Callable[..., Option] + +require_virtualenv = partial( + Option, + # Run only if inside a virtualenv, bail if not. + '--require-virtualenv', '--require-venv', + dest='require_venv', + action='store_true', + default=False, + help=SUPPRESS_HELP +) # type: Callable[..., Option] + +verbose = partial( + Option, + '-v', '--verbose', + dest='verbose', + action='count', + default=0, + help='Give more output. Option is additive, and can be used up to 3 times.' +) # type: Callable[..., Option] + +no_color = partial( + Option, + '--no-color', + dest='no_color', + action='store_true', + default=False, + help="Suppress colored output.", +) # type: Callable[..., Option] + +version = partial( + Option, + '-V', '--version', + dest='version', + action='store_true', + help='Show version and exit.', +) # type: Callable[..., Option] + +quiet = partial( + Option, + '-q', '--quiet', + dest='quiet', + action='count', + default=0, + help=( + 'Give less output. Option is additive, and can be used up to 3' + ' times (corresponding to WARNING, ERROR, and CRITICAL logging' + ' levels).' + ), +) # type: Callable[..., Option] + +progress_bar = partial( + Option, + '--progress-bar', + dest='progress_bar', + type='choice', + choices=list(BAR_TYPES.keys()), + default='on', + help=( + 'Specify type of progress to be displayed [' + + '|'.join(BAR_TYPES.keys()) + '] (default: %default)' + ), +) # type: Callable[..., Option] + +log = partial( + PipOption, + "--log", "--log-file", "--local-log", + dest="log", + metavar="path", + type="path", + help="Path to a verbose appending log." +) # type: Callable[..., Option] + +no_input = partial( + Option, + # Don't ask for input + '--no-input', + dest='no_input', + action='store_true', + default=False, + help="Disable prompting for input." +) # type: Callable[..., Option] + +proxy = partial( + Option, + '--proxy', + dest='proxy', + type='str', + default='', + help="Specify a proxy in the form [user:passwd@]proxy.server:port." +) # type: Callable[..., Option] + +retries = partial( + Option, + '--retries', + dest='retries', + type='int', + default=5, + help="Maximum number of retries each connection should attempt " + "(default %default times).", +) # type: Callable[..., Option] + +timeout = partial( + Option, + '--timeout', '--default-timeout', + metavar='sec', + dest='timeout', + type='float', + default=15, + help='Set the socket timeout (default %default seconds).', +) # type: Callable[..., Option] + + +def exists_action(): + # type: () -> Option + return Option( + # Option when path already exist + '--exists-action', + dest='exists_action', + type='choice', + choices=['s', 'i', 'w', 'b', 'a'], + default=[], + action='append', + metavar='action', + help="Default action when a path already exists: " + "(s)witch, (i)gnore, (w)ipe, (b)ackup, (a)bort.", + ) + + +cert = partial( + PipOption, + '--cert', + dest='cert', + type='path', + metavar='path', + help="Path to alternate CA bundle.", +) # type: Callable[..., Option] + +client_cert = partial( + PipOption, + '--client-cert', + dest='client_cert', + type='path', + default=None, + metavar='path', + help="Path to SSL client certificate, a single file containing the " + "private key and the certificate in PEM format.", +) # type: Callable[..., Option] + +index_url = partial( + Option, + '-i', '--index-url', '--pypi-url', + dest='index_url', + metavar='URL', + default=PyPI.simple_url, + help="Base URL of the Python Package Index (default %default). " + "This should point to a repository compliant with PEP 503 " + "(the simple repository API) or a local directory laid out " + "in the same format.", +) # type: Callable[..., Option] + + +def extra_index_url(): + # type: () -> Option + return Option( + '--extra-index-url', + dest='extra_index_urls', + metavar='URL', + action='append', + default=[], + help="Extra URLs of package indexes to use in addition to " + "--index-url. Should follow the same rules as " + "--index-url.", + ) + + +no_index = partial( + Option, + '--no-index', + dest='no_index', + action='store_true', + default=False, + help='Ignore package index (only looking at --find-links URLs instead).', +) # type: Callable[..., Option] + + +def find_links(): + # type: () -> Option + return Option( + '-f', '--find-links', + dest='find_links', + action='append', + default=[], + metavar='url', + help="If a URL or path to an html file, then parse for links to " + "archives such as sdist (.tar.gz) or wheel (.whl) files. " + "If a local path or file:// URL that's a directory, " + "then look for archives in the directory listing. " + "Links to VCS project URLs are not supported.", + ) + + +def trusted_host(): + # type: () -> Option + return Option( + "--trusted-host", + dest="trusted_hosts", + action="append", + metavar="HOSTNAME", + default=[], + help="Mark this host or host:port pair as trusted, even though it " + "does not have valid or any HTTPS.", + ) + + +def constraints(): + # type: () -> Option + return Option( + '-c', '--constraint', + dest='constraints', + action='append', + default=[], + metavar='file', + help='Constrain versions using the given constraints file. ' + 'This option can be used multiple times.' + ) + + +def requirements(): + # type: () -> Option + return Option( + '-r', '--requirement', + dest='requirements', + action='append', + default=[], + metavar='file', + help='Install from the given requirements file. ' + 'This option can be used multiple times.' + ) + + +def editable(): + # type: () -> Option + return Option( + '-e', '--editable', + dest='editables', + action='append', + default=[], + metavar='path/url', + help=('Install a project in editable mode (i.e. setuptools ' + '"develop mode") from a local project path or a VCS url.'), + ) + + +def _handle_src(option, opt_str, value, parser): + # type: (Option, str, str, OptionParser) -> None + value = os.path.abspath(value) + setattr(parser.values, option.dest, value) + + +src = partial( + PipOption, + '--src', '--source', '--source-dir', '--source-directory', + dest='src_dir', + type='path', + metavar='dir', + default=get_src_prefix(), + action='callback', + callback=_handle_src, + help='Directory to check out editable projects into. ' + 'The default in a virtualenv is "/src". ' + 'The default for global installs is "/src".' +) # type: Callable[..., Option] + + +def _get_format_control(values, option): + # type: (Values, Option) -> Any + """Get a format_control object.""" + return getattr(values, option.dest) + + +def _handle_no_binary(option, opt_str, value, parser): + # type: (Option, str, str, OptionParser) -> None + existing = _get_format_control(parser.values, option) + FormatControl.handle_mutual_excludes( + value, existing.no_binary, existing.only_binary, + ) + + +def _handle_only_binary(option, opt_str, value, parser): + # type: (Option, str, str, OptionParser) -> None + existing = _get_format_control(parser.values, option) + FormatControl.handle_mutual_excludes( + value, existing.only_binary, existing.no_binary, + ) + + +def no_binary(): + # type: () -> Option + format_control = FormatControl(set(), set()) + return Option( + "--no-binary", dest="format_control", action="callback", + callback=_handle_no_binary, type="str", + default=format_control, + help='Do not use binary packages. Can be supplied multiple times, and ' + 'each time adds to the existing value. Accepts either ":all:" to ' + 'disable all binary packages, ":none:" to empty the set (notice ' + 'the colons), or one or more package names with commas between ' + 'them (no colons). Note that some packages are tricky to compile ' + 'and may fail to install when this option is used on them.', + ) + + +def only_binary(): + # type: () -> Option + format_control = FormatControl(set(), set()) + return Option( + "--only-binary", dest="format_control", action="callback", + callback=_handle_only_binary, type="str", + default=format_control, + help='Do not use source packages. Can be supplied multiple times, and ' + 'each time adds to the existing value. Accepts either ":all:" to ' + 'disable all source packages, ":none:" to empty the set, or one ' + 'or more package names with commas between them. Packages ' + 'without binary distributions will fail to install when this ' + 'option is used on them.', + ) + + +platforms = partial( + Option, + '--platform', + dest='platforms', + metavar='platform', + action='append', + default=None, + help=("Only use wheels compatible with . Defaults to the " + "platform of the running system. Use this option multiple times to " + "specify multiple platforms supported by the target interpreter."), +) # type: Callable[..., Option] + + +# This was made a separate function for unit-testing purposes. +def _convert_python_version(value): + # type: (str) -> Tuple[Tuple[int, ...], Optional[str]] + """ + Convert a version string like "3", "37", or "3.7.3" into a tuple of ints. + + :return: A 2-tuple (version_info, error_msg), where `error_msg` is + non-None if and only if there was a parsing error. + """ + if not value: + # The empty string is the same as not providing a value. + return (None, None) + + parts = value.split('.') + if len(parts) > 3: + return ((), 'at most three version parts are allowed') + + if len(parts) == 1: + # Then we are in the case of "3" or "37". + value = parts[0] + if len(value) > 1: + parts = [value[0], value[1:]] + + try: + version_info = tuple(int(part) for part in parts) + except ValueError: + return ((), 'each version part must be an integer') + + return (version_info, None) + + +def _handle_python_version(option, opt_str, value, parser): + # type: (Option, str, str, OptionParser) -> None + """ + Handle a provided --python-version value. + """ + version_info, error_msg = _convert_python_version(value) + if error_msg is not None: + msg = ( + 'invalid --python-version value: {!r}: {}'.format( + value, error_msg, + ) + ) + raise_option_error(parser, option=option, msg=msg) + + parser.values.python_version = version_info + + +python_version = partial( + Option, + '--python-version', + dest='python_version', + metavar='python_version', + action='callback', + callback=_handle_python_version, type='str', + default=None, + help=dedent("""\ + The Python interpreter version to use for wheel and "Requires-Python" + compatibility checks. Defaults to a version derived from the running + interpreter. The version can be specified using up to three dot-separated + integers (e.g. "3" for 3.0.0, "3.7" for 3.7.0, or "3.7.3"). A major-minor + version can also be given as a string without dots (e.g. "37" for 3.7.0). + """), +) # type: Callable[..., Option] + + +implementation = partial( + Option, + '--implementation', + dest='implementation', + metavar='implementation', + default=None, + help=("Only use wheels compatible with Python " + "implementation , e.g. 'pp', 'jy', 'cp', " + " or 'ip'. If not specified, then the current " + "interpreter implementation is used. Use 'py' to force " + "implementation-agnostic wheels."), +) # type: Callable[..., Option] + + +abis = partial( + Option, + '--abi', + dest='abis', + metavar='abi', + action='append', + default=None, + help=("Only use wheels compatible with Python abi , e.g. 'pypy_41'. " + "If not specified, then the current interpreter abi tag is used. " + "Use this option multiple times to specify multiple abis supported " + "by the target interpreter. Generally you will need to specify " + "--implementation, --platform, and --python-version when using this " + "option."), +) # type: Callable[..., Option] + + +def add_target_python_options(cmd_opts): + # type: (OptionGroup) -> None + cmd_opts.add_option(platforms()) + cmd_opts.add_option(python_version()) + cmd_opts.add_option(implementation()) + cmd_opts.add_option(abis()) + + +def make_target_python(options): + # type: (Values) -> TargetPython + target_python = TargetPython( + platforms=options.platforms, + py_version_info=options.python_version, + abis=options.abis, + implementation=options.implementation, + ) + + return target_python + + +def prefer_binary(): + # type: () -> Option + return Option( + "--prefer-binary", + dest="prefer_binary", + action="store_true", + default=False, + help="Prefer older binary packages over newer source packages." + ) + + +cache_dir = partial( + PipOption, + "--cache-dir", + dest="cache_dir", + default=USER_CACHE_DIR, + metavar="dir", + type='path', + help="Store the cache data in ." +) # type: Callable[..., Option] + + +def _handle_no_cache_dir(option, opt, value, parser): + # type: (Option, str, str, OptionParser) -> None + """ + Process a value provided for the --no-cache-dir option. + + This is an optparse.Option callback for the --no-cache-dir option. + """ + # The value argument will be None if --no-cache-dir is passed via the + # command-line, since the option doesn't accept arguments. However, + # the value can be non-None if the option is triggered e.g. by an + # environment variable, like PIP_NO_CACHE_DIR=true. + if value is not None: + # Then parse the string value to get argument error-checking. + try: + strtobool(value) + except ValueError as exc: + raise_option_error(parser, option=option, msg=str(exc)) + + # Originally, setting PIP_NO_CACHE_DIR to a value that strtobool() + # converted to 0 (like "false" or "no") caused cache_dir to be disabled + # rather than enabled (logic would say the latter). Thus, we disable + # the cache directory not just on values that parse to True, but (for + # backwards compatibility reasons) also on values that parse to False. + # In other words, always set it to False if the option is provided in + # some (valid) form. + parser.values.cache_dir = False + + +no_cache = partial( + Option, + "--no-cache-dir", + dest="cache_dir", + action="callback", + callback=_handle_no_cache_dir, + help="Disable the cache.", +) # type: Callable[..., Option] + +no_deps = partial( + Option, + '--no-deps', '--no-dependencies', + dest='ignore_dependencies', + action='store_true', + default=False, + help="Don't install package dependencies.", +) # type: Callable[..., Option] + +build_dir = partial( + PipOption, + '-b', '--build', '--build-dir', '--build-directory', + dest='build_dir', + type='path', + metavar='dir', + help=SUPPRESS_HELP, +) # type: Callable[..., Option] + +ignore_requires_python = partial( + Option, + '--ignore-requires-python', + dest='ignore_requires_python', + action='store_true', + help='Ignore the Requires-Python information.' +) # type: Callable[..., Option] + +no_build_isolation = partial( + Option, + '--no-build-isolation', + dest='build_isolation', + action='store_false', + default=True, + help='Disable isolation when building a modern source distribution. ' + 'Build dependencies specified by PEP 518 must be already installed ' + 'if this option is used.' +) # type: Callable[..., Option] + + +def _handle_no_use_pep517(option, opt, value, parser): + # type: (Option, str, str, OptionParser) -> None + """ + Process a value provided for the --no-use-pep517 option. + + This is an optparse.Option callback for the no_use_pep517 option. + """ + # Since --no-use-pep517 doesn't accept arguments, the value argument + # will be None if --no-use-pep517 is passed via the command-line. + # However, the value can be non-None if the option is triggered e.g. + # by an environment variable, for example "PIP_NO_USE_PEP517=true". + if value is not None: + msg = """A value was passed for --no-use-pep517, + probably using either the PIP_NO_USE_PEP517 environment variable + or the "no-use-pep517" config file option. Use an appropriate value + of the PIP_USE_PEP517 environment variable or the "use-pep517" + config file option instead. + """ + raise_option_error(parser, option=option, msg=msg) + + # Otherwise, --no-use-pep517 was passed via the command-line. + parser.values.use_pep517 = False + + +use_pep517 = partial( + Option, + '--use-pep517', + dest='use_pep517', + action='store_true', + default=None, + help='Use PEP 517 for building source distributions ' + '(use --no-use-pep517 to force legacy behaviour).' +) # type: Any + +no_use_pep517 = partial( + Option, + '--no-use-pep517', + dest='use_pep517', + action='callback', + callback=_handle_no_use_pep517, + default=None, + help=SUPPRESS_HELP +) # type: Any + +install_options = partial( + Option, + '--install-option', + dest='install_options', + action='append', + metavar='options', + help="Extra arguments to be supplied to the setup.py install " + "command (use like --install-option=\"--install-scripts=/usr/local/" + "bin\"). Use multiple --install-option options to pass multiple " + "options to setup.py install. If you are using an option with a " + "directory path, be sure to use absolute path.", +) # type: Callable[..., Option] + +global_options = partial( + Option, + '--global-option', + dest='global_options', + action='append', + metavar='options', + help="Extra global options to be supplied to the setup.py " + "call before the install command.", +) # type: Callable[..., Option] + +no_clean = partial( + Option, + '--no-clean', + action='store_true', + default=False, + help="Don't clean up build directories." +) # type: Callable[..., Option] + +pre = partial( + Option, + '--pre', + action='store_true', + default=False, + help="Include pre-release and development versions. By default, " + "pip only finds stable versions.", +) # type: Callable[..., Option] + +disable_pip_version_check = partial( + Option, + "--disable-pip-version-check", + dest="disable_pip_version_check", + action="store_true", + default=False, + help="Don't periodically check PyPI to determine whether a new version " + "of pip is available for download. Implied with --no-index.", +) # type: Callable[..., Option] + + +def _handle_merge_hash(option, opt_str, value, parser): + # type: (Option, str, str, OptionParser) -> None + """Given a value spelled "algo:digest", append the digest to a list + pointed to in a dict by the algo name.""" + if not parser.values.hashes: + parser.values.hashes = {} + try: + algo, digest = value.split(':', 1) + except ValueError: + parser.error('Arguments to {} must be a hash name ' # noqa + 'followed by a value, like --hash=sha256:' + 'abcde...'.format(opt_str)) + if algo not in STRONG_HASHES: + parser.error('Allowed hash algorithms for {} are {}.'.format( # noqa + opt_str, ', '.join(STRONG_HASHES))) + parser.values.hashes.setdefault(algo, []).append(digest) + + +hash = partial( + Option, + '--hash', + # Hash values eventually end up in InstallRequirement.hashes due to + # __dict__ copying in process_line(). + dest='hashes', + action='callback', + callback=_handle_merge_hash, + type='string', + help="Verify that the package's archive matches this " + 'hash before installing. Example: --hash=sha256:abcdef...', +) # type: Callable[..., Option] + + +require_hashes = partial( + Option, + '--require-hashes', + dest='require_hashes', + action='store_true', + default=False, + help='Require a hash to check each requirement against, for ' + 'repeatable installs. This option is implied when any package in a ' + 'requirements file has a --hash option.', +) # type: Callable[..., Option] + + +list_path = partial( + PipOption, + '--path', + dest='path', + type='path', + action='append', + help='Restrict to the specified installation path for listing ' + 'packages (can be used multiple times).' +) # type: Callable[..., Option] + + +def check_list_path_option(options): + # type: (Values) -> None + if options.path and (options.user or options.local): + raise CommandError( + "Cannot combine '--path' with '--user' or '--local'" + ) + + +list_exclude = partial( + PipOption, + '--exclude', + dest='excludes', + action='append', + metavar='package', + type='package_name', + help="Exclude specified package from the output", +) # type: Callable[..., Option] + + +no_python_version_warning = partial( + Option, + '--no-python-version-warning', + dest='no_python_version_warning', + action='store_true', + default=False, + help='Silence deprecation warnings for upcoming unsupported Pythons.', +) # type: Callable[..., Option] + + +use_new_feature = partial( + Option, + '--use-feature', + dest='features_enabled', + metavar='feature', + action='append', + default=[], + choices=['2020-resolver', 'fast-deps'], + help='Enable new functionality, that may be backward incompatible.', +) # type: Callable[..., Option] + +use_deprecated_feature = partial( + Option, + '--use-deprecated', + dest='deprecated_features_enabled', + metavar='feature', + action='append', + default=[], + choices=['legacy-resolver'], + help=( + 'Enable deprecated functionality, that will be removed in the future.' + ), +) # type: Callable[..., Option] + + +########## +# groups # +########## + +general_group = { + 'name': 'General Options', + 'options': [ + help_, + isolated_mode, + require_virtualenv, + verbose, + version, + quiet, + log, + no_input, + proxy, + retries, + timeout, + exists_action, + trusted_host, + cert, + client_cert, + cache_dir, + no_cache, + disable_pip_version_check, + no_color, + no_python_version_warning, + use_new_feature, + use_deprecated_feature, + ] +} # type: Dict[str, Any] + +index_group = { + 'name': 'Package Index Options', + 'options': [ + index_url, + extra_index_url, + no_index, + find_links, + ] +} # type: Dict[str, Any] diff --git a/venv/Lib/site-packages/pip/_internal/cli/command_context.py b/venv/Lib/site-packages/pip/_internal/cli/command_context.py new file mode 100644 index 0000000..ade14f2 --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/cli/command_context.py @@ -0,0 +1,36 @@ +from contextlib import contextmanager + +from pip._vendor.contextlib2 import ExitStack + +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import ContextManager, Iterator, TypeVar + + _T = TypeVar('_T', covariant=True) + + +class CommandContextMixIn: + def __init__(self): + # type: () -> None + super().__init__() + self._in_main_context = False + self._main_context = ExitStack() + + @contextmanager + def main_context(self): + # type: () -> Iterator[None] + assert not self._in_main_context + + self._in_main_context = True + try: + with self._main_context: + yield + finally: + self._in_main_context = False + + def enter_context(self, context_provider): + # type: (ContextManager[_T]) -> _T + assert self._in_main_context + + return self._main_context.enter_context(context_provider) diff --git a/venv/Lib/site-packages/pip/_internal/cli/main.py b/venv/Lib/site-packages/pip/_internal/cli/main.py new file mode 100644 index 0000000..ed59073 --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/cli/main.py @@ -0,0 +1,73 @@ +"""Primary application entrypoint. +""" +import locale +import logging +import os +import sys + +from pip._internal.cli.autocompletion import autocomplete +from pip._internal.cli.main_parser import parse_command +from pip._internal.commands import create_command +from pip._internal.exceptions import PipError +from pip._internal.utils import deprecation +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import List, Optional + +logger = logging.getLogger(__name__) + + +# Do not import and use main() directly! Using it directly is actively +# discouraged by pip's maintainers. The name, location and behavior of +# this function is subject to change, so calling it directly is not +# portable across different pip versions. + +# In addition, running pip in-process is unsupported and unsafe. This is +# elaborated in detail at +# https://pip.pypa.io/en/stable/user_guide/#using-pip-from-your-program. +# That document also provides suggestions that should work for nearly +# all users that are considering importing and using main() directly. + +# However, we know that certain users will still want to invoke pip +# in-process. If you understand and accept the implications of using pip +# in an unsupported manner, the best approach is to use runpy to avoid +# depending on the exact location of this entry point. + +# The following example shows how to use runpy to invoke pip in that +# case: +# +# sys.argv = ["pip", your, args, here] +# runpy.run_module("pip", run_name="__main__") +# +# Note that this will exit the process after running, unlike a direct +# call to main. As it is not safe to do any processing after calling +# main, this should not be an issue in practice. + +def main(args=None): + # type: (Optional[List[str]]) -> int + if args is None: + args = sys.argv[1:] + + # Configure our deprecation warnings to be sent through loggers + deprecation.install_warning_logger() + + autocomplete() + + try: + cmd_name, cmd_args = parse_command(args) + except PipError as exc: + sys.stderr.write(f"ERROR: {exc}") + sys.stderr.write(os.linesep) + sys.exit(1) + + # Needed for locale.getpreferredencoding(False) to work + # in pip._internal.utils.encoding.auto_decode + try: + locale.setlocale(locale.LC_ALL, '') + except locale.Error as e: + # setlocale can apparently crash if locale are uninitialized + logger.debug("Ignoring error %s when setting locale", e) + command = create_command(cmd_name, isolated=("--isolated" in cmd_args)) + + return command.main(cmd_args) diff --git a/venv/Lib/site-packages/pip/_internal/cli/main_parser.py b/venv/Lib/site-packages/pip/_internal/cli/main_parser.py new file mode 100644 index 0000000..fcee6a2 --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/cli/main_parser.py @@ -0,0 +1,96 @@ +"""A single place for constructing and exposing the main parser +""" + +import os +import sys + +from pip._internal.cli import cmdoptions +from pip._internal.cli.parser import ConfigOptionParser, UpdatingDefaultsHelpFormatter +from pip._internal.commands import commands_dict, get_similar_commands +from pip._internal.exceptions import CommandError +from pip._internal.utils.misc import get_pip_version, get_prog +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import List, Tuple + + +__all__ = ["create_main_parser", "parse_command"] + + +def create_main_parser(): + # type: () -> ConfigOptionParser + """Creates and returns the main parser for pip's CLI + """ + + parser_kw = { + 'usage': '\n%prog [options]', + 'add_help_option': False, + 'formatter': UpdatingDefaultsHelpFormatter(), + 'name': 'global', + 'prog': get_prog(), + } + + parser = ConfigOptionParser(**parser_kw) + parser.disable_interspersed_args() + + parser.version = get_pip_version() + + # add the general options + gen_opts = cmdoptions.make_option_group(cmdoptions.general_group, parser) + parser.add_option_group(gen_opts) + + # so the help formatter knows + parser.main = True # type: ignore + + # create command listing for description + description = [''] + [ + '{name:27} {command_info.summary}'.format(**locals()) + for name, command_info in commands_dict.items() + ] + parser.description = '\n'.join(description) + + return parser + + +def parse_command(args): + # type: (List[str]) -> Tuple[str, List[str]] + parser = create_main_parser() + + # Note: parser calls disable_interspersed_args(), so the result of this + # call is to split the initial args into the general options before the + # subcommand and everything else. + # For example: + # args: ['--timeout=5', 'install', '--user', 'INITools'] + # general_options: ['--timeout==5'] + # args_else: ['install', '--user', 'INITools'] + general_options, args_else = parser.parse_args(args) + + # --version + if general_options.version: + sys.stdout.write(parser.version) + sys.stdout.write(os.linesep) + sys.exit() + + # pip || pip help -> print_help() + if not args_else or (args_else[0] == 'help' and len(args_else) == 1): + parser.print_help() + sys.exit() + + # the subcommand name + cmd_name = args_else[0] + + if cmd_name not in commands_dict: + guess = get_similar_commands(cmd_name) + + msg = [f'unknown command "{cmd_name}"'] + if guess: + msg.append(f'maybe you meant "{guess}"') + + raise CommandError(' - '.join(msg)) + + # all the args without the subcommand + cmd_args = args[:] + cmd_args.remove(cmd_name) + + return cmd_name, cmd_args diff --git a/venv/Lib/site-packages/pip/_internal/cli/parser.py b/venv/Lib/site-packages/pip/_internal/cli/parser.py new file mode 100644 index 0000000..60c61f3 --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/cli/parser.py @@ -0,0 +1,281 @@ +"""Base option parser setup""" + +# The following comment should be removed at some point in the future. +# mypy: disallow-untyped-defs=False + +import logging +import optparse +import shutil +import sys +import textwrap + +from pip._vendor.contextlib2 import suppress + +from pip._internal.cli.status_codes import UNKNOWN_ERROR +from pip._internal.configuration import Configuration, ConfigurationError +from pip._internal.utils.misc import redact_auth_from_url, strtobool + +logger = logging.getLogger(__name__) + + +class PrettyHelpFormatter(optparse.IndentedHelpFormatter): + """A prettier/less verbose help formatter for optparse.""" + + def __init__(self, *args, **kwargs): + # help position must be aligned with __init__.parseopts.description + kwargs['max_help_position'] = 30 + kwargs['indent_increment'] = 1 + kwargs['width'] = shutil.get_terminal_size()[0] - 2 + super().__init__(*args, **kwargs) + + def format_option_strings(self, option): + return self._format_option_strings(option) + + def _format_option_strings(self, option, mvarfmt=' <{}>', optsep=', '): + """ + Return a comma-separated list of option strings and metavars. + + :param option: tuple of (short opt, long opt), e.g: ('-f', '--format') + :param mvarfmt: metavar format string + :param optsep: separator + """ + opts = [] + + if option._short_opts: + opts.append(option._short_opts[0]) + if option._long_opts: + opts.append(option._long_opts[0]) + if len(opts) > 1: + opts.insert(1, optsep) + + if option.takes_value(): + metavar = option.metavar or option.dest.lower() + opts.append(mvarfmt.format(metavar.lower())) + + return ''.join(opts) + + def format_heading(self, heading): + if heading == 'Options': + return '' + return heading + ':\n' + + def format_usage(self, usage): + """ + Ensure there is only one newline between usage and the first heading + if there is no description. + """ + msg = '\nUsage: {}\n'.format( + self.indent_lines(textwrap.dedent(usage), " ")) + return msg + + def format_description(self, description): + # leave full control over description to us + if description: + if hasattr(self.parser, 'main'): + label = 'Commands' + else: + label = 'Description' + # some doc strings have initial newlines, some don't + description = description.lstrip('\n') + # some doc strings have final newlines and spaces, some don't + description = description.rstrip() + # dedent, then reindent + description = self.indent_lines(textwrap.dedent(description), " ") + description = f'{label}:\n{description}\n' + return description + else: + return '' + + def format_epilog(self, epilog): + # leave full control over epilog to us + if epilog: + return epilog + else: + return '' + + def indent_lines(self, text, indent): + new_lines = [indent + line for line in text.split('\n')] + return "\n".join(new_lines) + + +class UpdatingDefaultsHelpFormatter(PrettyHelpFormatter): + """Custom help formatter for use in ConfigOptionParser. + + This is updates the defaults before expanding them, allowing + them to show up correctly in the help listing. + + Also redact auth from url type options + """ + + def expand_default(self, option): + default_values = None + if self.parser is not None: + self.parser._update_defaults(self.parser.defaults) + default_values = self.parser.defaults.get(option.dest) + help_text = super().expand_default(option) + + if default_values and option.metavar == 'URL': + if isinstance(default_values, str): + default_values = [default_values] + + # If its not a list, we should abort and just return the help text + if not isinstance(default_values, list): + default_values = [] + + for val in default_values: + help_text = help_text.replace( + val, redact_auth_from_url(val)) + + return help_text + + +class CustomOptionParser(optparse.OptionParser): + + def insert_option_group(self, idx, *args, **kwargs): + """Insert an OptionGroup at a given position.""" + group = self.add_option_group(*args, **kwargs) + + self.option_groups.pop() + self.option_groups.insert(idx, group) + + return group + + @property + def option_list_all(self): + """Get a list of all options, including those in option groups.""" + res = self.option_list[:] + for i in self.option_groups: + res.extend(i.option_list) + + return res + + +class ConfigOptionParser(CustomOptionParser): + """Custom option parser which updates its defaults by checking the + configuration files and environmental variables""" + + def __init__(self, *args, **kwargs): + self.name = kwargs.pop('name') + + isolated = kwargs.pop("isolated", False) + self.config = Configuration(isolated) + + assert self.name + super().__init__(*args, **kwargs) + + def check_default(self, option, key, val): + try: + return option.check_value(key, val) + except optparse.OptionValueError as exc: + print(f"An error occurred during configuration: {exc}") + sys.exit(3) + + def _get_ordered_configuration_items(self): + # Configuration gives keys in an unordered manner. Order them. + override_order = ["global", self.name, ":env:"] + + # Pool the options into different groups + section_items = {name: [] for name in override_order} + for section_key, val in self.config.items(): + # ignore empty values + if not val: + logger.debug( + "Ignoring configuration key '%s' as it's value is empty.", + section_key + ) + continue + + section, key = section_key.split(".", 1) + if section in override_order: + section_items[section].append((key, val)) + + # Yield each group in their override order + for section in override_order: + for key, val in section_items[section]: + yield key, val + + def _update_defaults(self, defaults): + """Updates the given defaults with values from the config files and + the environ. Does a little special handling for certain types of + options (lists).""" + + # Accumulate complex default state. + self.values = optparse.Values(self.defaults) + late_eval = set() + # Then set the options with those values + for key, val in self._get_ordered_configuration_items(): + # '--' because configuration supports only long names + option = self.get_option('--' + key) + + # Ignore options not present in this parser. E.g. non-globals put + # in [global] by users that want them to apply to all applicable + # commands. + if option is None: + continue + + if option.action in ('store_true', 'store_false'): + try: + val = strtobool(val) + except ValueError: + self.error( + '{} is not a valid value for {} option, ' # noqa + 'please specify a boolean value like yes/no, ' + 'true/false or 1/0 instead.'.format(val, key) + ) + elif option.action == 'count': + with suppress(ValueError): + val = strtobool(val) + with suppress(ValueError): + val = int(val) + if not isinstance(val, int) or val < 0: + self.error( + '{} is not a valid value for {} option, ' # noqa + 'please instead specify either a non-negative integer ' + 'or a boolean value like yes/no or false/true ' + 'which is equivalent to 1/0.'.format(val, key) + ) + elif option.action == 'append': + val = val.split() + val = [self.check_default(option, key, v) for v in val] + elif option.action == 'callback': + late_eval.add(option.dest) + opt_str = option.get_opt_string() + val = option.convert_value(opt_str, val) + # From take_action + args = option.callback_args or () + kwargs = option.callback_kwargs or {} + option.callback(option, opt_str, val, self, *args, **kwargs) + else: + val = self.check_default(option, key, val) + + defaults[option.dest] = val + + for key in late_eval: + defaults[key] = getattr(self.values, key) + self.values = None + return defaults + + def get_default_values(self): + """Overriding to make updating the defaults after instantiation of + the option parser possible, _update_defaults() does the dirty work.""" + if not self.process_default_values: + # Old, pre-Optik 1.5 behaviour. + return optparse.Values(self.defaults) + + # Load the configuration, or error out in case of an error + try: + self.config.load() + except ConfigurationError as err: + self.exit(UNKNOWN_ERROR, str(err)) + + defaults = self._update_defaults(self.defaults.copy()) # ours + for option in self._get_all_options(): + default = defaults.get(option.dest) + if isinstance(default, str): + opt_str = option.get_opt_string() + defaults[option.dest] = option.check_value(opt_str, default) + return optparse.Values(defaults) + + def error(self, msg): + self.print_usage(sys.stderr) + self.exit(UNKNOWN_ERROR, f"{msg}\n") diff --git a/venv/Lib/site-packages/pip/_internal/cli/progress_bars.py b/venv/Lib/site-packages/pip/_internal/cli/progress_bars.py new file mode 100644 index 0000000..59b01a6 --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/cli/progress_bars.py @@ -0,0 +1,271 @@ +import itertools +import sys +from signal import SIGINT, default_int_handler, signal + +from pip._vendor.progress.bar import Bar, FillingCirclesBar, IncrementalBar +from pip._vendor.progress.spinner import Spinner + +from pip._internal.utils.compat import WINDOWS +from pip._internal.utils.logging import get_indentation +from pip._internal.utils.misc import format_size +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import Any, Dict, List + +try: + from pip._vendor import colorama +# Lots of different errors can come from this, including SystemError and +# ImportError. +except Exception: + colorama = None + + +def _select_progress_class(preferred, fallback): + # type: (Bar, Bar) -> Bar + encoding = getattr(preferred.file, "encoding", None) + + # If we don't know what encoding this file is in, then we'll just assume + # that it doesn't support unicode and use the ASCII bar. + if not encoding: + return fallback + + # Collect all of the possible characters we want to use with the preferred + # bar. + characters = [ + getattr(preferred, "empty_fill", ""), + getattr(preferred, "fill", ""), + ] + characters += list(getattr(preferred, "phases", [])) + + # Try to decode the characters we're using for the bar using the encoding + # of the given file, if this works then we'll assume that we can use the + # fancier bar and if not we'll fall back to the plaintext bar. + try: + "".join(characters).encode(encoding) + except UnicodeEncodeError: + return fallback + else: + return preferred + + +_BaseBar = _select_progress_class(IncrementalBar, Bar) # type: Any + + +class InterruptibleMixin: + """ + Helper to ensure that self.finish() gets called on keyboard interrupt. + + This allows downloads to be interrupted without leaving temporary state + (like hidden cursors) behind. + + This class is similar to the progress library's existing SigIntMixin + helper, but as of version 1.2, that helper has the following problems: + + 1. It calls sys.exit(). + 2. It discards the existing SIGINT handler completely. + 3. It leaves its own handler in place even after an uninterrupted finish, + which will have unexpected delayed effects if the user triggers an + unrelated keyboard interrupt some time after a progress-displaying + download has already completed, for example. + """ + + def __init__(self, *args, **kwargs): + # type: (List[Any], Dict[Any, Any]) -> None + """ + Save the original SIGINT handler for later. + """ + # https://github.com/python/mypy/issues/5887 + super().__init__(*args, **kwargs) # type: ignore + + self.original_handler = signal(SIGINT, self.handle_sigint) + + # If signal() returns None, the previous handler was not installed from + # Python, and we cannot restore it. This probably should not happen, + # but if it does, we must restore something sensible instead, at least. + # The least bad option should be Python's default SIGINT handler, which + # just raises KeyboardInterrupt. + if self.original_handler is None: + self.original_handler = default_int_handler + + def finish(self): + # type: () -> None + """ + Restore the original SIGINT handler after finishing. + + This should happen regardless of whether the progress display finishes + normally, or gets interrupted. + """ + super().finish() # type: ignore + signal(SIGINT, self.original_handler) + + def handle_sigint(self, signum, frame): # type: ignore + """ + Call self.finish() before delegating to the original SIGINT handler. + + This handler should only be in place while the progress display is + active. + """ + self.finish() + self.original_handler(signum, frame) + + +class SilentBar(Bar): + + def update(self): + # type: () -> None + pass + + +class BlueEmojiBar(IncrementalBar): + + suffix = "%(percent)d%%" + bar_prefix = " " + bar_suffix = " " + phases = ("\U0001F539", "\U0001F537", "\U0001F535") + + +class DownloadProgressMixin: + + def __init__(self, *args, **kwargs): + # type: (List[Any], Dict[Any, Any]) -> None + # https://github.com/python/mypy/issues/5887 + super().__init__(*args, **kwargs) # type: ignore + self.message = (" " * ( + get_indentation() + 2 + )) + self.message # type: str + + @property + def downloaded(self): + # type: () -> str + return format_size(self.index) # type: ignore + + @property + def download_speed(self): + # type: () -> str + # Avoid zero division errors... + if self.avg == 0.0: # type: ignore + return "..." + return format_size(1 / self.avg) + "/s" # type: ignore + + @property + def pretty_eta(self): + # type: () -> str + if self.eta: # type: ignore + return f"eta {self.eta_td}" # type: ignore + return "" + + def iter(self, it): # type: ignore + for x in it: + yield x + # B305 is incorrectly raised here + # https://github.com/PyCQA/flake8-bugbear/issues/59 + self.next(len(x)) # noqa: B305 + self.finish() + + +class WindowsMixin: + + def __init__(self, *args, **kwargs): + # type: (List[Any], Dict[Any, Any]) -> None + # The Windows terminal does not support the hide/show cursor ANSI codes + # even with colorama. So we'll ensure that hide_cursor is False on + # Windows. + # This call needs to go before the super() call, so that hide_cursor + # is set in time. The base progress bar class writes the "hide cursor" + # code to the terminal in its init, so if we don't set this soon + # enough, we get a "hide" with no corresponding "show"... + if WINDOWS and self.hide_cursor: # type: ignore + self.hide_cursor = False + + # https://github.com/python/mypy/issues/5887 + super().__init__(*args, **kwargs) # type: ignore + + # Check if we are running on Windows and we have the colorama module, + # if we do then wrap our file with it. + if WINDOWS and colorama: + self.file = colorama.AnsiToWin32(self.file) # type: ignore + # The progress code expects to be able to call self.file.isatty() + # but the colorama.AnsiToWin32() object doesn't have that, so we'll + # add it. + self.file.isatty = lambda: self.file.wrapped.isatty() + # The progress code expects to be able to call self.file.flush() + # but the colorama.AnsiToWin32() object doesn't have that, so we'll + # add it. + self.file.flush = lambda: self.file.wrapped.flush() + + +class BaseDownloadProgressBar(WindowsMixin, InterruptibleMixin, + DownloadProgressMixin): + + file = sys.stdout + message = "%(percent)d%%" + suffix = "%(downloaded)s %(download_speed)s %(pretty_eta)s" + + +class DefaultDownloadProgressBar(BaseDownloadProgressBar, + _BaseBar): + pass + + +class DownloadSilentBar(BaseDownloadProgressBar, SilentBar): + pass + + +class DownloadBar(BaseDownloadProgressBar, + Bar): + pass + + +class DownloadFillingCirclesBar(BaseDownloadProgressBar, + FillingCirclesBar): + pass + + +class DownloadBlueEmojiProgressBar(BaseDownloadProgressBar, + BlueEmojiBar): + pass + + +class DownloadProgressSpinner(WindowsMixin, InterruptibleMixin, + DownloadProgressMixin, Spinner): + + file = sys.stdout + suffix = "%(downloaded)s %(download_speed)s" + + def next_phase(self): + # type: () -> str + if not hasattr(self, "_phaser"): + self._phaser = itertools.cycle(self.phases) + return next(self._phaser) + + def update(self): + # type: () -> None + message = self.message % self + phase = self.next_phase() + suffix = self.suffix % self + line = ''.join([ + message, + " " if message else "", + phase, + " " if suffix else "", + suffix, + ]) + + self.writeln(line) + + +BAR_TYPES = { + "off": (DownloadSilentBar, DownloadSilentBar), + "on": (DefaultDownloadProgressBar, DownloadProgressSpinner), + "ascii": (DownloadBar, DownloadProgressSpinner), + "pretty": (DownloadFillingCirclesBar, DownloadProgressSpinner), + "emoji": (DownloadBlueEmojiProgressBar, DownloadProgressSpinner) +} + + +def DownloadProgressProvider(progress_bar, max=None): # type: ignore + if max is None or max == 0: + return BAR_TYPES[progress_bar][1]().iter + else: + return BAR_TYPES[progress_bar][0](max=max).iter diff --git a/venv/Lib/site-packages/pip/_internal/cli/req_command.py b/venv/Lib/site-packages/pip/_internal/cli/req_command.py new file mode 100644 index 0000000..468b3cc --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/cli/req_command.py @@ -0,0 +1,426 @@ +"""Contains the Command base classes that depend on PipSession. + +The classes in this module are in a separate module so the commands not +needing download / PackageFinder capability don't unnecessarily import the +PackageFinder machinery and all its vendored dependencies, etc. +""" + +import logging +import os +from functools import partial + +from pip._internal.cli import cmdoptions +from pip._internal.cli.base_command import Command +from pip._internal.cli.command_context import CommandContextMixIn +from pip._internal.exceptions import CommandError, PreviousBuildDirError +from pip._internal.index.collector import LinkCollector +from pip._internal.index.package_finder import PackageFinder +from pip._internal.models.selection_prefs import SelectionPreferences +from pip._internal.network.session import PipSession +from pip._internal.operations.prepare import RequirementPreparer +from pip._internal.req.constructors import ( + install_req_from_editable, + install_req_from_line, + install_req_from_parsed_requirement, + install_req_from_req_string, +) +from pip._internal.req.req_file import parse_requirements +from pip._internal.self_outdated_check import pip_self_version_check +from pip._internal.utils.temp_dir import tempdir_kinds +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from optparse import Values + from typing import Any, List, Optional, Tuple + + from pip._internal.cache import WheelCache + from pip._internal.models.target_python import TargetPython + from pip._internal.req.req_install import InstallRequirement + from pip._internal.req.req_tracker import RequirementTracker + from pip._internal.resolution.base import BaseResolver + from pip._internal.utils.temp_dir import TempDirectory, TempDirectoryTypeRegistry + + +logger = logging.getLogger(__name__) + + +class SessionCommandMixin(CommandContextMixIn): + + """ + A class mixin for command classes needing _build_session(). + """ + def __init__(self): + # type: () -> None + super().__init__() + self._session = None # Optional[PipSession] + + @classmethod + def _get_index_urls(cls, options): + # type: (Values) -> Optional[List[str]] + """Return a list of index urls from user-provided options.""" + index_urls = [] + if not getattr(options, "no_index", False): + url = getattr(options, "index_url", None) + if url: + index_urls.append(url) + urls = getattr(options, "extra_index_urls", None) + if urls: + index_urls.extend(urls) + # Return None rather than an empty list + return index_urls or None + + def get_default_session(self, options): + # type: (Values) -> PipSession + """Get a default-managed session.""" + if self._session is None: + self._session = self.enter_context(self._build_session(options)) + # there's no type annotation on requests.Session, so it's + # automatically ContextManager[Any] and self._session becomes Any, + # then https://github.com/python/mypy/issues/7696 kicks in + assert self._session is not None + return self._session + + def _build_session(self, options, retries=None, timeout=None): + # type: (Values, Optional[int], Optional[int]) -> PipSession + assert not options.cache_dir or os.path.isabs(options.cache_dir) + session = PipSession( + cache=( + os.path.join(options.cache_dir, "http") + if options.cache_dir else None + ), + retries=retries if retries is not None else options.retries, + trusted_hosts=options.trusted_hosts, + index_urls=self._get_index_urls(options), + ) + + # Handle custom ca-bundles from the user + if options.cert: + session.verify = options.cert + + # Handle SSL client certificate + if options.client_cert: + session.cert = options.client_cert + + # Handle timeouts + if options.timeout or timeout: + session.timeout = ( + timeout if timeout is not None else options.timeout + ) + + # Handle configured proxies + if options.proxy: + session.proxies = { + "http": options.proxy, + "https": options.proxy, + } + + # Determine if we can prompt the user for authentication or not + session.auth.prompting = not options.no_input + + return session + + +class IndexGroupCommand(Command, SessionCommandMixin): + + """ + Abstract base class for commands with the index_group options. + + This also corresponds to the commands that permit the pip version check. + """ + + def handle_pip_version_check(self, options): + # type: (Values) -> None + """ + Do the pip version check if not disabled. + + This overrides the default behavior of not doing the check. + """ + # Make sure the index_group options are present. + assert hasattr(options, 'no_index') + + if options.disable_pip_version_check or options.no_index: + return + + # Otherwise, check if we're using the latest version of pip available. + session = self._build_session( + options, + retries=0, + timeout=min(5, options.timeout) + ) + with session: + pip_self_version_check(session, options) + + +KEEPABLE_TEMPDIR_TYPES = [ + tempdir_kinds.BUILD_ENV, + tempdir_kinds.EPHEM_WHEEL_CACHE, + tempdir_kinds.REQ_BUILD, +] + + +def with_cleanup(func): + # type: (Any) -> Any + """Decorator for common logic related to managing temporary + directories. + """ + def configure_tempdir_registry(registry): + # type: (TempDirectoryTypeRegistry) -> None + for t in KEEPABLE_TEMPDIR_TYPES: + registry.set_delete(t, False) + + def wrapper(self, options, args): + # type: (RequirementCommand, Values, List[Any]) -> Optional[int] + assert self.tempdir_registry is not None + if options.no_clean: + configure_tempdir_registry(self.tempdir_registry) + + try: + return func(self, options, args) + except PreviousBuildDirError: + # This kind of conflict can occur when the user passes an explicit + # build directory with a pre-existing folder. In that case we do + # not want to accidentally remove it. + configure_tempdir_registry(self.tempdir_registry) + raise + + return wrapper + + +class RequirementCommand(IndexGroupCommand): + + def __init__(self, *args, **kw): + # type: (Any, Any) -> None + super().__init__(*args, **kw) + + self.cmd_opts.add_option(cmdoptions.no_clean()) + + @staticmethod + def determine_resolver_variant(options): + # type: (Values) -> str + """Determines which resolver should be used, based on the given options.""" + if "legacy-resolver" in options.deprecated_features_enabled: + return "legacy" + + return "2020-resolver" + + @classmethod + def make_requirement_preparer( + cls, + temp_build_dir, # type: TempDirectory + options, # type: Values + req_tracker, # type: RequirementTracker + session, # type: PipSession + finder, # type: PackageFinder + use_user_site, # type: bool + download_dir=None, # type: str + ): + # type: (...) -> RequirementPreparer + """ + Create a RequirementPreparer instance for the given parameters. + """ + temp_build_dir_path = temp_build_dir.path + assert temp_build_dir_path is not None + + resolver_variant = cls.determine_resolver_variant(options) + if resolver_variant == "2020-resolver": + lazy_wheel = 'fast-deps' in options.features_enabled + if lazy_wheel: + logger.warning( + 'pip is using lazily downloaded wheels using HTTP ' + 'range requests to obtain dependency information. ' + 'This experimental feature is enabled through ' + '--use-feature=fast-deps and it is not ready for ' + 'production.' + ) + else: + lazy_wheel = False + if 'fast-deps' in options.features_enabled: + logger.warning( + 'fast-deps has no effect when used with the legacy resolver.' + ) + + return RequirementPreparer( + build_dir=temp_build_dir_path, + src_dir=options.src_dir, + download_dir=download_dir, + build_isolation=options.build_isolation, + req_tracker=req_tracker, + session=session, + progress_bar=options.progress_bar, + finder=finder, + require_hashes=options.require_hashes, + use_user_site=use_user_site, + lazy_wheel=lazy_wheel, + ) + + @classmethod + def make_resolver( + cls, + preparer, # type: RequirementPreparer + finder, # type: PackageFinder + options, # type: Values + wheel_cache=None, # type: Optional[WheelCache] + use_user_site=False, # type: bool + ignore_installed=True, # type: bool + ignore_requires_python=False, # type: bool + force_reinstall=False, # type: bool + upgrade_strategy="to-satisfy-only", # type: str + use_pep517=None, # type: Optional[bool] + py_version_info=None, # type: Optional[Tuple[int, ...]] + ): + # type: (...) -> BaseResolver + """ + Create a Resolver instance for the given parameters. + """ + make_install_req = partial( + install_req_from_req_string, + isolated=options.isolated_mode, + use_pep517=use_pep517, + ) + resolver_variant = cls.determine_resolver_variant(options) + # The long import name and duplicated invocation is needed to convince + # Mypy into correctly typechecking. Otherwise it would complain the + # "Resolver" class being redefined. + if resolver_variant == "2020-resolver": + import pip._internal.resolution.resolvelib.resolver + + return pip._internal.resolution.resolvelib.resolver.Resolver( + preparer=preparer, + finder=finder, + wheel_cache=wheel_cache, + make_install_req=make_install_req, + use_user_site=use_user_site, + ignore_dependencies=options.ignore_dependencies, + ignore_installed=ignore_installed, + ignore_requires_python=ignore_requires_python, + force_reinstall=force_reinstall, + upgrade_strategy=upgrade_strategy, + py_version_info=py_version_info, + ) + import pip._internal.resolution.legacy.resolver + return pip._internal.resolution.legacy.resolver.Resolver( + preparer=preparer, + finder=finder, + wheel_cache=wheel_cache, + make_install_req=make_install_req, + use_user_site=use_user_site, + ignore_dependencies=options.ignore_dependencies, + ignore_installed=ignore_installed, + ignore_requires_python=ignore_requires_python, + force_reinstall=force_reinstall, + upgrade_strategy=upgrade_strategy, + py_version_info=py_version_info, + ) + + def get_requirements( + self, + args, # type: List[str] + options, # type: Values + finder, # type: PackageFinder + session, # type: PipSession + ): + # type: (...) -> List[InstallRequirement] + """ + Parse command-line arguments into the corresponding requirements. + """ + requirements = [] # type: List[InstallRequirement] + for filename in options.constraints: + for parsed_req in parse_requirements( + filename, + constraint=True, finder=finder, options=options, + session=session): + req_to_add = install_req_from_parsed_requirement( + parsed_req, + isolated=options.isolated_mode, + user_supplied=False, + ) + requirements.append(req_to_add) + + for req in args: + req_to_add = install_req_from_line( + req, None, isolated=options.isolated_mode, + use_pep517=options.use_pep517, + user_supplied=True, + ) + requirements.append(req_to_add) + + for req in options.editables: + req_to_add = install_req_from_editable( + req, + user_supplied=True, + isolated=options.isolated_mode, + use_pep517=options.use_pep517, + ) + requirements.append(req_to_add) + + # NOTE: options.require_hashes may be set if --require-hashes is True + for filename in options.requirements: + for parsed_req in parse_requirements( + filename, + finder=finder, options=options, session=session): + req_to_add = install_req_from_parsed_requirement( + parsed_req, + isolated=options.isolated_mode, + use_pep517=options.use_pep517, + user_supplied=True, + ) + requirements.append(req_to_add) + + # If any requirement has hash options, enable hash checking. + if any(req.has_hash_options for req in requirements): + options.require_hashes = True + + if not (args or options.editables or options.requirements): + opts = {'name': self.name} + if options.find_links: + raise CommandError( + 'You must give at least one requirement to {name} ' + '(maybe you meant "pip {name} {links}"?)'.format( + **dict(opts, links=' '.join(options.find_links)))) + else: + raise CommandError( + 'You must give at least one requirement to {name} ' + '(see "pip help {name}")'.format(**opts)) + + return requirements + + @staticmethod + def trace_basic_info(finder): + # type: (PackageFinder) -> None + """ + Trace basic information about the provided objects. + """ + # Display where finder is looking for packages + search_scope = finder.search_scope + locations = search_scope.get_formatted_locations() + if locations: + logger.info(locations) + + def _build_package_finder( + self, + options, # type: Values + session, # type: PipSession + target_python=None, # type: Optional[TargetPython] + ignore_requires_python=None, # type: Optional[bool] + ): + # type: (...) -> PackageFinder + """ + Create a package finder appropriate to this requirement command. + + :param ignore_requires_python: Whether to ignore incompatible + "Requires-Python" values in links. Defaults to False. + """ + link_collector = LinkCollector.create(session, options=options) + selection_prefs = SelectionPreferences( + allow_yanked=True, + format_control=options.format_control, + allow_all_prereleases=options.pre, + prefer_binary=options.prefer_binary, + ignore_requires_python=ignore_requires_python, + ) + + return PackageFinder.create( + link_collector=link_collector, + selection_prefs=selection_prefs, + target_python=target_python, + ) diff --git a/venv/Lib/site-packages/pip/_internal/cli/spinners.py b/venv/Lib/site-packages/pip/_internal/cli/spinners.py new file mode 100644 index 0000000..05ec2dc --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/cli/spinners.py @@ -0,0 +1,171 @@ +import contextlib +import itertools +import logging +import sys +import time + +from pip._vendor.progress import HIDE_CURSOR, SHOW_CURSOR + +from pip._internal.utils.compat import WINDOWS +from pip._internal.utils.logging import get_indentation +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import IO, Iterator + +logger = logging.getLogger(__name__) + + +class SpinnerInterface: + def spin(self): + # type: () -> None + raise NotImplementedError() + + def finish(self, final_status): + # type: (str) -> None + raise NotImplementedError() + + +class InteractiveSpinner(SpinnerInterface): + def __init__(self, message, file=None, spin_chars="-\\|/", + # Empirically, 8 updates/second looks nice + min_update_interval_seconds=0.125): + # type: (str, IO[str], str, float) -> None + self._message = message + if file is None: + file = sys.stdout + self._file = file + self._rate_limiter = RateLimiter(min_update_interval_seconds) + self._finished = False + + self._spin_cycle = itertools.cycle(spin_chars) + + self._file.write(" " * get_indentation() + self._message + " ... ") + self._width = 0 + + def _write(self, status): + # type: (str) -> None + assert not self._finished + # Erase what we wrote before by backspacing to the beginning, writing + # spaces to overwrite the old text, and then backspacing again + backup = "\b" * self._width + self._file.write(backup + " " * self._width + backup) + # Now we have a blank slate to add our status + self._file.write(status) + self._width = len(status) + self._file.flush() + self._rate_limiter.reset() + + def spin(self): + # type: () -> None + if self._finished: + return + if not self._rate_limiter.ready(): + return + self._write(next(self._spin_cycle)) + + def finish(self, final_status): + # type: (str) -> None + if self._finished: + return + self._write(final_status) + self._file.write("\n") + self._file.flush() + self._finished = True + + +# Used for dumb terminals, non-interactive installs (no tty), etc. +# We still print updates occasionally (once every 60 seconds by default) to +# act as a keep-alive for systems like Travis-CI that take lack-of-output as +# an indication that a task has frozen. +class NonInteractiveSpinner(SpinnerInterface): + def __init__(self, message, min_update_interval_seconds=60): + # type: (str, float) -> None + self._message = message + self._finished = False + self._rate_limiter = RateLimiter(min_update_interval_seconds) + self._update("started") + + def _update(self, status): + # type: (str) -> None + assert not self._finished + self._rate_limiter.reset() + logger.info("%s: %s", self._message, status) + + def spin(self): + # type: () -> None + if self._finished: + return + if not self._rate_limiter.ready(): + return + self._update("still running...") + + def finish(self, final_status): + # type: (str) -> None + if self._finished: + return + self._update( + "finished with status '{final_status}'".format(**locals())) + self._finished = True + + +class RateLimiter: + def __init__(self, min_update_interval_seconds): + # type: (float) -> None + self._min_update_interval_seconds = min_update_interval_seconds + self._last_update = 0 # type: float + + def ready(self): + # type: () -> bool + now = time.time() + delta = now - self._last_update + return delta >= self._min_update_interval_seconds + + def reset(self): + # type: () -> None + self._last_update = time.time() + + +@contextlib.contextmanager +def open_spinner(message): + # type: (str) -> Iterator[SpinnerInterface] + # Interactive spinner goes directly to sys.stdout rather than being routed + # through the logging system, but it acts like it has level INFO, + # i.e. it's only displayed if we're at level INFO or better. + # Non-interactive spinner goes through the logging system, so it is always + # in sync with logging configuration. + if sys.stdout.isatty() and logger.getEffectiveLevel() <= logging.INFO: + spinner = InteractiveSpinner(message) # type: SpinnerInterface + else: + spinner = NonInteractiveSpinner(message) + try: + with hidden_cursor(sys.stdout): + yield spinner + except KeyboardInterrupt: + spinner.finish("canceled") + raise + except Exception: + spinner.finish("error") + raise + else: + spinner.finish("done") + + +@contextlib.contextmanager +def hidden_cursor(file): + # type: (IO[str]) -> Iterator[None] + # The Windows terminal does not support the hide/show cursor ANSI codes, + # even via colorama. So don't even try. + if WINDOWS: + yield + # We don't want to clutter the output with control characters if we're + # writing to a file, or if the user is running with --quiet. + # See https://github.com/pypa/pip/issues/3418 + elif not file.isatty() or logger.getEffectiveLevel() > logging.INFO: + yield + else: + file.write(HIDE_CURSOR) + try: + yield + finally: + file.write(SHOW_CURSOR) diff --git a/venv/Lib/site-packages/pip/_internal/cli/status_codes.py b/venv/Lib/site-packages/pip/_internal/cli/status_codes.py new file mode 100644 index 0000000..5e29502 --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/cli/status_codes.py @@ -0,0 +1,6 @@ +SUCCESS = 0 +ERROR = 1 +UNKNOWN_ERROR = 2 +VIRTUALENV_NOT_FOUND = 3 +PREVIOUS_BUILD_DIR_ERROR = 4 +NO_MATCHES_FOUND = 23 diff --git a/venv/Lib/site-packages/pip/_internal/commands/__init__.py b/venv/Lib/site-packages/pip/_internal/commands/__init__.py new file mode 100644 index 0000000..f241120 --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/commands/__init__.py @@ -0,0 +1,115 @@ +""" +Package containing all pip commands +""" + +import importlib +from collections import OrderedDict, namedtuple + +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import Any, Optional + + from pip._internal.cli.base_command import Command + + +CommandInfo = namedtuple('CommandInfo', 'module_path, class_name, summary') + +# The ordering matters for help display. +# Also, even though the module path starts with the same +# "pip._internal.commands" prefix in each case, we include the full path +# because it makes testing easier (specifically when modifying commands_dict +# in test setup / teardown by adding info for a FakeCommand class defined +# in a test-related module). +# Finally, we need to pass an iterable of pairs here rather than a dict +# so that the ordering won't be lost when using Python 2.7. +commands_dict = OrderedDict([ + ('install', CommandInfo( + 'pip._internal.commands.install', 'InstallCommand', + 'Install packages.', + )), + ('download', CommandInfo( + 'pip._internal.commands.download', 'DownloadCommand', + 'Download packages.', + )), + ('uninstall', CommandInfo( + 'pip._internal.commands.uninstall', 'UninstallCommand', + 'Uninstall packages.', + )), + ('freeze', CommandInfo( + 'pip._internal.commands.freeze', 'FreezeCommand', + 'Output installed packages in requirements format.', + )), + ('list', CommandInfo( + 'pip._internal.commands.list', 'ListCommand', + 'List installed packages.', + )), + ('show', CommandInfo( + 'pip._internal.commands.show', 'ShowCommand', + 'Show information about installed packages.', + )), + ('check', CommandInfo( + 'pip._internal.commands.check', 'CheckCommand', + 'Verify installed packages have compatible dependencies.', + )), + ('config', CommandInfo( + 'pip._internal.commands.configuration', 'ConfigurationCommand', + 'Manage local and global configuration.', + )), + ('search', CommandInfo( + 'pip._internal.commands.search', 'SearchCommand', + 'Search PyPI for packages.', + )), + ('cache', CommandInfo( + 'pip._internal.commands.cache', 'CacheCommand', + "Inspect and manage pip's wheel cache.", + )), + ('wheel', CommandInfo( + 'pip._internal.commands.wheel', 'WheelCommand', + 'Build wheels from your requirements.', + )), + ('hash', CommandInfo( + 'pip._internal.commands.hash', 'HashCommand', + 'Compute hashes of package archives.', + )), + ('completion', CommandInfo( + 'pip._internal.commands.completion', 'CompletionCommand', + 'A helper command used for command completion.', + )), + ('debug', CommandInfo( + 'pip._internal.commands.debug', 'DebugCommand', + 'Show information useful for debugging.', + )), + ('help', CommandInfo( + 'pip._internal.commands.help', 'HelpCommand', + 'Show help for commands.', + )), +]) # type: OrderedDict[str, CommandInfo] + + +def create_command(name, **kwargs): + # type: (str, **Any) -> Command + """ + Create an instance of the Command class with the given name. + """ + module_path, class_name, summary = commands_dict[name] + module = importlib.import_module(module_path) + command_class = getattr(module, class_name) + command = command_class(name=name, summary=summary, **kwargs) + + return command + + +def get_similar_commands(name): + # type: (str) -> Optional[str] + """Command name auto-correct.""" + from difflib import get_close_matches + + name = name.lower() + + close_commands = get_close_matches(name, commands_dict.keys()) + + if close_commands: + return close_commands[0] + else: + return None diff --git a/venv/Lib/site-packages/pip/_internal/commands/cache.py b/venv/Lib/site-packages/pip/_internal/commands/cache.py new file mode 100644 index 0000000..d5ac45a --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/commands/cache.py @@ -0,0 +1,232 @@ +import logging +import os +import textwrap + +import pip._internal.utils.filesystem as filesystem +from pip._internal.cli.base_command import Command +from pip._internal.cli.status_codes import ERROR, SUCCESS +from pip._internal.exceptions import CommandError, PipError +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from optparse import Values + from typing import Any, List + + +logger = logging.getLogger(__name__) + + +class CacheCommand(Command): + """ + Inspect and manage pip's wheel cache. + + Subcommands: + + - dir: Show the cache directory. + - info: Show information about the cache. + - list: List filenames of packages stored in the cache. + - remove: Remove one or more package from the cache. + - purge: Remove all items from the cache. + + ```` can be a glob expression or a package name. + """ + + ignore_require_venv = True + usage = """ + %prog dir + %prog info + %prog list [] [--format=[human, abspath]] + %prog remove + %prog purge + """ + + def add_options(self): + # type: () -> None + + self.cmd_opts.add_option( + '--format', + action='store', + dest='list_format', + default="human", + choices=('human', 'abspath'), + help="Select the output format among: human (default) or abspath" + ) + + self.parser.insert_option_group(0, self.cmd_opts) + + def run(self, options, args): + # type: (Values, List[Any]) -> int + handlers = { + "dir": self.get_cache_dir, + "info": self.get_cache_info, + "list": self.list_cache_items, + "remove": self.remove_cache_items, + "purge": self.purge_cache, + } + + if not options.cache_dir: + logger.error("pip cache commands can not " + "function since cache is disabled.") + return ERROR + + # Determine action + if not args or args[0] not in handlers: + logger.error( + "Need an action (%s) to perform.", + ", ".join(sorted(handlers)), + ) + return ERROR + + action = args[0] + + # Error handling happens here, not in the action-handlers. + try: + handlers[action](options, args[1:]) + except PipError as e: + logger.error(e.args[0]) + return ERROR + + return SUCCESS + + def get_cache_dir(self, options, args): + # type: (Values, List[Any]) -> None + if args: + raise CommandError('Too many arguments') + + logger.info(options.cache_dir) + + def get_cache_info(self, options, args): + # type: (Values, List[Any]) -> None + if args: + raise CommandError('Too many arguments') + + num_http_files = len(self._find_http_files(options)) + num_packages = len(self._find_wheels(options, '*')) + + http_cache_location = self._cache_dir(options, 'http') + wheels_cache_location = self._cache_dir(options, 'wheels') + http_cache_size = filesystem.format_directory_size(http_cache_location) + wheels_cache_size = filesystem.format_directory_size( + wheels_cache_location + ) + + message = textwrap.dedent(""" + Package index page cache location: {http_cache_location} + Package index page cache size: {http_cache_size} + Number of HTTP files: {num_http_files} + Wheels location: {wheels_cache_location} + Wheels size: {wheels_cache_size} + Number of wheels: {package_count} + """).format( + http_cache_location=http_cache_location, + http_cache_size=http_cache_size, + num_http_files=num_http_files, + wheels_cache_location=wheels_cache_location, + package_count=num_packages, + wheels_cache_size=wheels_cache_size, + ).strip() + + logger.info(message) + + def list_cache_items(self, options, args): + # type: (Values, List[Any]) -> None + if len(args) > 1: + raise CommandError('Too many arguments') + + if args: + pattern = args[0] + else: + pattern = '*' + + files = self._find_wheels(options, pattern) + if options.list_format == 'human': + self.format_for_human(files) + else: + self.format_for_abspath(files) + + def format_for_human(self, files): + # type: (List[str]) -> None + if not files: + logger.info('Nothing cached.') + return + + results = [] + for filename in files: + wheel = os.path.basename(filename) + size = filesystem.format_file_size(filename) + results.append(f' - {wheel} ({size})') + logger.info('Cache contents:\n') + logger.info('\n'.join(sorted(results))) + + def format_for_abspath(self, files): + # type: (List[str]) -> None + if not files: + return + + results = [] + for filename in files: + results.append(filename) + + logger.info('\n'.join(sorted(results))) + + def remove_cache_items(self, options, args): + # type: (Values, List[Any]) -> None + if len(args) > 1: + raise CommandError('Too many arguments') + + if not args: + raise CommandError('Please provide a pattern') + + files = self._find_wheels(options, args[0]) + + # Only fetch http files if no specific pattern given + if args[0] == '*': + files += self._find_http_files(options) + + if not files: + raise CommandError('No matching packages') + + for filename in files: + os.unlink(filename) + logger.debug('Removed %s', filename) + logger.info('Files removed: %s', len(files)) + + def purge_cache(self, options, args): + # type: (Values, List[Any]) -> None + if args: + raise CommandError('Too many arguments') + + return self.remove_cache_items(options, ['*']) + + def _cache_dir(self, options, subdir): + # type: (Values, str) -> str + return os.path.join(options.cache_dir, subdir) + + def _find_http_files(self, options): + # type: (Values) -> List[str] + http_dir = self._cache_dir(options, 'http') + return filesystem.find_files(http_dir, '*') + + def _find_wheels(self, options, pattern): + # type: (Values, str) -> List[str] + wheel_dir = self._cache_dir(options, 'wheels') + + # The wheel filename format, as specified in PEP 427, is: + # {distribution}-{version}(-{build})?-{python}-{abi}-{platform}.whl + # + # Additionally, non-alphanumeric values in the distribution are + # normalized to underscores (_), meaning hyphens can never occur + # before `-{version}`. + # + # Given that information: + # - If the pattern we're given contains a hyphen (-), the user is + # providing at least the version. Thus, we can just append `*.whl` + # to match the rest of it. + # - If the pattern we're given doesn't contain a hyphen (-), the + # user is only providing the name. Thus, we append `-*.whl` to + # match the hyphen before the version, followed by anything else. + # + # PEP 427: https://www.python.org/dev/peps/pep-0427/ + pattern = pattern + ("*.whl" if "-" in pattern else "-*.whl") + + return filesystem.find_files(wheel_dir, pattern) diff --git a/venv/Lib/site-packages/pip/_internal/commands/check.py b/venv/Lib/site-packages/pip/_internal/commands/check.py new file mode 100644 index 0000000..e066bb6 --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/commands/check.py @@ -0,0 +1,51 @@ +import logging + +from pip._internal.cli.base_command import Command +from pip._internal.cli.status_codes import ERROR, SUCCESS +from pip._internal.operations.check import ( + check_package_set, + create_package_set_from_installed, +) +from pip._internal.utils.misc import write_output +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +logger = logging.getLogger(__name__) + +if MYPY_CHECK_RUNNING: + from optparse import Values + from typing import Any, List + + +class CheckCommand(Command): + """Verify installed packages have compatible dependencies.""" + + usage = """ + %prog [options]""" + + def run(self, options, args): + # type: (Values, List[Any]) -> int + + package_set, parsing_probs = create_package_set_from_installed() + missing, conflicting = check_package_set(package_set) + + for project_name in missing: + version = package_set[project_name].version + for dependency in missing[project_name]: + write_output( + "%s %s requires %s, which is not installed.", + project_name, version, dependency[0], + ) + + for project_name in conflicting: + version = package_set[project_name].version + for dep_name, dep_version, req in conflicting[project_name]: + write_output( + "%s %s has requirement %s, but you have %s %s.", + project_name, version, req, dep_name, dep_version, + ) + + if missing or conflicting or parsing_probs: + return ERROR + else: + write_output("No broken requirements found.") + return SUCCESS diff --git a/venv/Lib/site-packages/pip/_internal/commands/completion.py b/venv/Lib/site-packages/pip/_internal/commands/completion.py new file mode 100644 index 0000000..2c19d56 --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/commands/completion.py @@ -0,0 +1,96 @@ +import sys +import textwrap + +from pip._internal.cli.base_command import Command +from pip._internal.cli.status_codes import SUCCESS +from pip._internal.utils.misc import get_prog +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from optparse import Values + from typing import List + +BASE_COMPLETION = """ +# pip {shell} completion start{script}# pip {shell} completion end +""" + +COMPLETION_SCRIPTS = { + 'bash': """ + _pip_completion() + {{ + COMPREPLY=( $( COMP_WORDS="${{COMP_WORDS[*]}}" \\ + COMP_CWORD=$COMP_CWORD \\ + PIP_AUTO_COMPLETE=1 $1 2>/dev/null ) ) + }} + complete -o default -F _pip_completion {prog} + """, + 'zsh': """ + function _pip_completion {{ + local words cword + read -Ac words + read -cn cword + reply=( $( COMP_WORDS="$words[*]" \\ + COMP_CWORD=$(( cword-1 )) \\ + PIP_AUTO_COMPLETE=1 $words[1] 2>/dev/null )) + }} + compctl -K _pip_completion {prog} + """, + 'fish': """ + function __fish_complete_pip + set -lx COMP_WORDS (commandline -o) "" + set -lx COMP_CWORD ( \\ + math (contains -i -- (commandline -t) $COMP_WORDS)-1 \\ + ) + set -lx PIP_AUTO_COMPLETE 1 + string split \\ -- (eval $COMP_WORDS[1]) + end + complete -fa "(__fish_complete_pip)" -c {prog} + """, +} + + +class CompletionCommand(Command): + """A helper command to be used for command completion.""" + + ignore_require_venv = True + + def add_options(self): + # type: () -> None + self.cmd_opts.add_option( + '--bash', '-b', + action='store_const', + const='bash', + dest='shell', + help='Emit completion code for bash') + self.cmd_opts.add_option( + '--zsh', '-z', + action='store_const', + const='zsh', + dest='shell', + help='Emit completion code for zsh') + self.cmd_opts.add_option( + '--fish', '-f', + action='store_const', + const='fish', + dest='shell', + help='Emit completion code for fish') + + self.parser.insert_option_group(0, self.cmd_opts) + + def run(self, options, args): + # type: (Values, List[str]) -> int + """Prints the completion code of the given shell""" + shells = COMPLETION_SCRIPTS.keys() + shell_options = ['--' + shell for shell in sorted(shells)] + if options.shell in shells: + script = textwrap.dedent( + COMPLETION_SCRIPTS.get(options.shell, '').format( + prog=get_prog()) + ) + print(BASE_COMPLETION.format(script=script, shell=options.shell)) + return SUCCESS + else: + sys.stderr.write( + 'ERROR: You must pass {}\n' .format(' or '.join(shell_options)) + ) + return SUCCESS diff --git a/venv/Lib/site-packages/pip/_internal/commands/configuration.py b/venv/Lib/site-packages/pip/_internal/commands/configuration.py new file mode 100644 index 0000000..a440a2b --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/commands/configuration.py @@ -0,0 +1,280 @@ +import logging +import os +import subprocess + +from pip._internal.cli.base_command import Command +from pip._internal.cli.status_codes import ERROR, SUCCESS +from pip._internal.configuration import Configuration, get_configuration_files, kinds +from pip._internal.exceptions import PipError +from pip._internal.utils.logging import indent_log +from pip._internal.utils.misc import get_prog, write_output +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from optparse import Values + from typing import Any, List, Optional + + from pip._internal.configuration import Kind + +logger = logging.getLogger(__name__) + + +class ConfigurationCommand(Command): + """ + Manage local and global configuration. + + Subcommands: + + - list: List the active configuration (or from the file specified) + - edit: Edit the configuration file in an editor + - get: Get the value associated with name + - set: Set the name=value + - unset: Unset the value associated with name + - debug: List the configuration files and values defined under them + + If none of --user, --global and --site are passed, a virtual + environment configuration file is used if one is active and the file + exists. Otherwise, all modifications happen on the to the user file by + default. + """ + + ignore_require_venv = True + usage = """ + %prog [] list + %prog [] [--editor ] edit + + %prog [] get name + %prog [] set name value + %prog [] unset name + %prog [] debug + """ + + def add_options(self): + # type: () -> None + self.cmd_opts.add_option( + '--editor', + dest='editor', + action='store', + default=None, + help=( + 'Editor to use to edit the file. Uses VISUAL or EDITOR ' + 'environment variables if not provided.' + ) + ) + + self.cmd_opts.add_option( + '--global', + dest='global_file', + action='store_true', + default=False, + help='Use the system-wide configuration file only' + ) + + self.cmd_opts.add_option( + '--user', + dest='user_file', + action='store_true', + default=False, + help='Use the user configuration file only' + ) + + self.cmd_opts.add_option( + '--site', + dest='site_file', + action='store_true', + default=False, + help='Use the current environment configuration file only' + ) + + self.parser.insert_option_group(0, self.cmd_opts) + + def run(self, options, args): + # type: (Values, List[str]) -> int + handlers = { + "list": self.list_values, + "edit": self.open_in_editor, + "get": self.get_name, + "set": self.set_name_value, + "unset": self.unset_name, + "debug": self.list_config_values, + } + + # Determine action + if not args or args[0] not in handlers: + logger.error( + "Need an action (%s) to perform.", + ", ".join(sorted(handlers)), + ) + return ERROR + + action = args[0] + + # Determine which configuration files are to be loaded + # Depends on whether the command is modifying. + try: + load_only = self._determine_file( + options, need_value=(action in ["get", "set", "unset", "edit"]) + ) + except PipError as e: + logger.error(e.args[0]) + return ERROR + + # Load a new configuration + self.configuration = Configuration( + isolated=options.isolated_mode, load_only=load_only + ) + self.configuration.load() + + # Error handling happens here, not in the action-handlers. + try: + handlers[action](options, args[1:]) + except PipError as e: + logger.error(e.args[0]) + return ERROR + + return SUCCESS + + def _determine_file(self, options, need_value): + # type: (Values, bool) -> Optional[Kind] + file_options = [key for key, value in ( + (kinds.USER, options.user_file), + (kinds.GLOBAL, options.global_file), + (kinds.SITE, options.site_file), + ) if value] + + if not file_options: + if not need_value: + return None + # Default to user, unless there's a site file. + elif any( + os.path.exists(site_config_file) + for site_config_file in get_configuration_files()[kinds.SITE] + ): + return kinds.SITE + else: + return kinds.USER + elif len(file_options) == 1: + return file_options[0] + + raise PipError( + "Need exactly one file to operate upon " + "(--user, --site, --global) to perform." + ) + + def list_values(self, options, args): + # type: (Values, List[str]) -> None + self._get_n_args(args, "list", n=0) + + for key, value in sorted(self.configuration.items()): + write_output("%s=%r", key, value) + + def get_name(self, options, args): + # type: (Values, List[str]) -> None + key = self._get_n_args(args, "get [name]", n=1) + value = self.configuration.get_value(key) + + write_output("%s", value) + + def set_name_value(self, options, args): + # type: (Values, List[str]) -> None + key, value = self._get_n_args(args, "set [name] [value]", n=2) + self.configuration.set_value(key, value) + + self._save_configuration() + + def unset_name(self, options, args): + # type: (Values, List[str]) -> None + key = self._get_n_args(args, "unset [name]", n=1) + self.configuration.unset_value(key) + + self._save_configuration() + + def list_config_values(self, options, args): + # type: (Values, List[str]) -> None + """List config key-value pairs across different config files""" + self._get_n_args(args, "debug", n=0) + + self.print_env_var_values() + # Iterate over config files and print if they exist, and the + # key-value pairs present in them if they do + for variant, files in sorted(self.configuration.iter_config_files()): + write_output("%s:", variant) + for fname in files: + with indent_log(): + file_exists = os.path.exists(fname) + write_output("%s, exists: %r", + fname, file_exists) + if file_exists: + self.print_config_file_values(variant) + + def print_config_file_values(self, variant): + # type: (Kind) -> None + """Get key-value pairs from the file of a variant""" + for name, value in self.configuration.\ + get_values_in_config(variant).items(): + with indent_log(): + write_output("%s: %s", name, value) + + def print_env_var_values(self): + # type: () -> None + """Get key-values pairs present as environment variables""" + write_output("%s:", 'env_var') + with indent_log(): + for key, value in sorted(self.configuration.get_environ_vars()): + env_var = f'PIP_{key.upper()}' + write_output("%s=%r", env_var, value) + + def open_in_editor(self, options, args): + # type: (Values, List[str]) -> None + editor = self._determine_editor(options) + + fname = self.configuration.get_file_to_edit() + if fname is None: + raise PipError("Could not determine appropriate file.") + + try: + subprocess.check_call([editor, fname]) + except subprocess.CalledProcessError as e: + raise PipError( + "Editor Subprocess exited with exit code {}" + .format(e.returncode) + ) + + def _get_n_args(self, args, example, n): + # type: (List[str], str, int) -> Any + """Helper to make sure the command got the right number of arguments + """ + if len(args) != n: + msg = ( + 'Got unexpected number of arguments, expected {}. ' + '(example: "{} config {}")' + ).format(n, get_prog(), example) + raise PipError(msg) + + if n == 1: + return args[0] + else: + return args + + def _save_configuration(self): + # type: () -> None + # We successfully ran a modifying command. Need to save the + # configuration. + try: + self.configuration.save() + except Exception: + logger.exception( + "Unable to save configuration. Please report this as a bug." + ) + raise PipError("Internal Error.") + + def _determine_editor(self, options): + # type: (Values) -> str + if options.editor is not None: + return options.editor + elif "VISUAL" in os.environ: + return os.environ["VISUAL"] + elif "EDITOR" in os.environ: + return os.environ["EDITOR"] + else: + raise PipError("Could not determine editor to use.") diff --git a/venv/Lib/site-packages/pip/_internal/commands/debug.py b/venv/Lib/site-packages/pip/_internal/commands/debug.py new file mode 100644 index 0000000..be4f470 --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/commands/debug.py @@ -0,0 +1,218 @@ +import locale +import logging +import os +import sys + +import pip._vendor +from pip._vendor import pkg_resources +from pip._vendor.certifi import where +from pip._vendor.packaging.version import parse as parse_version + +from pip import __file__ as pip_location +from pip._internal.cli import cmdoptions +from pip._internal.cli.base_command import Command +from pip._internal.cli.cmdoptions import make_target_python +from pip._internal.cli.status_codes import SUCCESS +from pip._internal.utils.logging import indent_log +from pip._internal.utils.misc import get_pip_version +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from optparse import Values + from types import ModuleType + from typing import Dict, List, Optional + + from pip._internal.configuration import Configuration + +logger = logging.getLogger(__name__) + + +def show_value(name, value): + # type: (str, Optional[str]) -> None + logger.info('%s: %s', name, value) + + +def show_sys_implementation(): + # type: () -> None + logger.info('sys.implementation:') + implementation_name = sys.implementation.name + with indent_log(): + show_value('name', implementation_name) + + +def create_vendor_txt_map(): + # type: () -> Dict[str, str] + vendor_txt_path = os.path.join( + os.path.dirname(pip_location), + '_vendor', + 'vendor.txt' + ) + + with open(vendor_txt_path) as f: + # Purge non version specifying lines. + # Also, remove any space prefix or suffixes (including comments). + lines = [line.strip().split(' ', 1)[0] + for line in f.readlines() if '==' in line] + + # Transform into "module" -> version dict. + return dict(line.split('==', 1) for line in lines) # type: ignore + + +def get_module_from_module_name(module_name): + # type: (str) -> ModuleType + # Module name can be uppercase in vendor.txt for some reason... + module_name = module_name.lower() + # PATCH: setuptools is actually only pkg_resources. + if module_name == 'setuptools': + module_name = 'pkg_resources' + + __import__( + f'pip._vendor.{module_name}', + globals(), + locals(), + level=0 + ) + return getattr(pip._vendor, module_name) + + +def get_vendor_version_from_module(module_name): + # type: (str) -> Optional[str] + module = get_module_from_module_name(module_name) + version = getattr(module, '__version__', None) + + if not version: + # Try to find version in debundled module info + pkg_set = pkg_resources.WorkingSet([os.path.dirname(module.__file__)]) + package = pkg_set.find(pkg_resources.Requirement.parse(module_name)) + version = getattr(package, 'version', None) + + return version + + +def show_actual_vendor_versions(vendor_txt_versions): + # type: (Dict[str, str]) -> None + """Log the actual version and print extra info if there is + a conflict or if the actual version could not be imported. + """ + for module_name, expected_version in vendor_txt_versions.items(): + extra_message = '' + actual_version = get_vendor_version_from_module(module_name) + if not actual_version: + extra_message = ' (Unable to locate actual module version, using'\ + ' vendor.txt specified version)' + actual_version = expected_version + elif parse_version(actual_version) != parse_version(expected_version): + extra_message = ' (CONFLICT: vendor.txt suggests version should'\ + ' be {})'.format(expected_version) + logger.info('%s==%s%s', module_name, actual_version, extra_message) + + +def show_vendor_versions(): + # type: () -> None + logger.info('vendored library versions:') + + vendor_txt_versions = create_vendor_txt_map() + with indent_log(): + show_actual_vendor_versions(vendor_txt_versions) + + +def show_tags(options): + # type: (Values) -> None + tag_limit = 10 + + target_python = make_target_python(options) + tags = target_python.get_tags() + + # Display the target options that were explicitly provided. + formatted_target = target_python.format_given() + suffix = '' + if formatted_target: + suffix = f' (target: {formatted_target})' + + msg = 'Compatible tags: {}{}'.format(len(tags), suffix) + logger.info(msg) + + if options.verbose < 1 and len(tags) > tag_limit: + tags_limited = True + tags = tags[:tag_limit] + else: + tags_limited = False + + with indent_log(): + for tag in tags: + logger.info(str(tag)) + + if tags_limited: + msg = ( + '...\n' + '[First {tag_limit} tags shown. Pass --verbose to show all.]' + ).format(tag_limit=tag_limit) + logger.info(msg) + + +def ca_bundle_info(config): + # type: (Configuration) -> str + levels = set() + for key, _ in config.items(): + levels.add(key.split('.')[0]) + + if not levels: + return "Not specified" + + levels_that_override_global = ['install', 'wheel', 'download'] + global_overriding_level = [ + level for level in levels if level in levels_that_override_global + ] + if not global_overriding_level: + return 'global' + + if 'global' in levels: + levels.remove('global') + return ", ".join(levels) + + +class DebugCommand(Command): + """ + Display debug information. + """ + + usage = """ + %prog """ + ignore_require_venv = True + + def add_options(self): + # type: () -> None + cmdoptions.add_target_python_options(self.cmd_opts) + self.parser.insert_option_group(0, self.cmd_opts) + self.parser.config.load() + + def run(self, options, args): + # type: (Values, List[str]) -> int + logger.warning( + "This command is only meant for debugging. " + "Do not use this with automation for parsing and getting these " + "details, since the output and options of this command may " + "change without notice." + ) + show_value('pip version', get_pip_version()) + show_value('sys.version', sys.version) + show_value('sys.executable', sys.executable) + show_value('sys.getdefaultencoding', sys.getdefaultencoding()) + show_value('sys.getfilesystemencoding', sys.getfilesystemencoding()) + show_value( + 'locale.getpreferredencoding', locale.getpreferredencoding(), + ) + show_value('sys.platform', sys.platform) + show_sys_implementation() + + show_value("'cert' config value", ca_bundle_info(self.parser.config)) + show_value("REQUESTS_CA_BUNDLE", os.environ.get('REQUESTS_CA_BUNDLE')) + show_value("CURL_CA_BUNDLE", os.environ.get('CURL_CA_BUNDLE')) + show_value("pip._vendor.certifi.where()", where()) + show_value("pip._vendor.DEBUNDLED", pip._vendor.DEBUNDLED) + + show_vendor_versions() + + show_tags(options) + + return SUCCESS diff --git a/venv/Lib/site-packages/pip/_internal/commands/download.py b/venv/Lib/site-packages/pip/_internal/commands/download.py new file mode 100644 index 0000000..0f09fcc --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/commands/download.py @@ -0,0 +1,144 @@ +import logging +import os + +from pip._internal.cli import cmdoptions +from pip._internal.cli.cmdoptions import make_target_python +from pip._internal.cli.req_command import RequirementCommand, with_cleanup +from pip._internal.cli.status_codes import SUCCESS +from pip._internal.req.req_tracker import get_requirement_tracker +from pip._internal.utils.misc import ensure_dir, normalize_path, write_output +from pip._internal.utils.temp_dir import TempDirectory +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from optparse import Values + from typing import List + +logger = logging.getLogger(__name__) + + +class DownloadCommand(RequirementCommand): + """ + Download packages from: + + - PyPI (and other indexes) using requirement specifiers. + - VCS project urls. + - Local project directories. + - Local or remote source archives. + + pip also supports downloading from "requirements files", which provide + an easy way to specify a whole environment to be downloaded. + """ + + usage = """ + %prog [options] [package-index-options] ... + %prog [options] -r [package-index-options] ... + %prog [options] ... + %prog [options] ... + %prog [options] ...""" + + def add_options(self): + # type: () -> None + self.cmd_opts.add_option(cmdoptions.constraints()) + self.cmd_opts.add_option(cmdoptions.requirements()) + self.cmd_opts.add_option(cmdoptions.build_dir()) + self.cmd_opts.add_option(cmdoptions.no_deps()) + self.cmd_opts.add_option(cmdoptions.global_options()) + self.cmd_opts.add_option(cmdoptions.no_binary()) + self.cmd_opts.add_option(cmdoptions.only_binary()) + self.cmd_opts.add_option(cmdoptions.prefer_binary()) + self.cmd_opts.add_option(cmdoptions.src()) + self.cmd_opts.add_option(cmdoptions.pre()) + self.cmd_opts.add_option(cmdoptions.require_hashes()) + self.cmd_opts.add_option(cmdoptions.progress_bar()) + self.cmd_opts.add_option(cmdoptions.no_build_isolation()) + self.cmd_opts.add_option(cmdoptions.use_pep517()) + self.cmd_opts.add_option(cmdoptions.no_use_pep517()) + self.cmd_opts.add_option(cmdoptions.ignore_requires_python()) + + self.cmd_opts.add_option( + '-d', '--dest', '--destination-dir', '--destination-directory', + dest='download_dir', + metavar='dir', + default=os.curdir, + help=("Download packages into ."), + ) + + cmdoptions.add_target_python_options(self.cmd_opts) + + index_opts = cmdoptions.make_option_group( + cmdoptions.index_group, + self.parser, + ) + + self.parser.insert_option_group(0, index_opts) + self.parser.insert_option_group(0, self.cmd_opts) + + @with_cleanup + def run(self, options, args): + # type: (Values, List[str]) -> int + + options.ignore_installed = True + # editable doesn't really make sense for `pip download`, but the bowels + # of the RequirementSet code require that property. + options.editables = [] + + cmdoptions.check_dist_restriction(options) + + options.download_dir = normalize_path(options.download_dir) + ensure_dir(options.download_dir) + + session = self.get_default_session(options) + + target_python = make_target_python(options) + finder = self._build_package_finder( + options=options, + session=session, + target_python=target_python, + ignore_requires_python=options.ignore_requires_python, + ) + + req_tracker = self.enter_context(get_requirement_tracker()) + + directory = TempDirectory( + delete=not options.no_clean, + kind="download", + globally_managed=True, + ) + + reqs = self.get_requirements(args, options, finder, session) + + preparer = self.make_requirement_preparer( + temp_build_dir=directory, + options=options, + req_tracker=req_tracker, + session=session, + finder=finder, + download_dir=options.download_dir, + use_user_site=False, + ) + + resolver = self.make_resolver( + preparer=preparer, + finder=finder, + options=options, + ignore_requires_python=options.ignore_requires_python, + py_version_info=options.python_version, + ) + + self.trace_basic_info(finder) + + requirement_set = resolver.resolve( + reqs, check_supported_wheels=True + ) + + downloaded = [] # type: List[str] + for req in requirement_set.requirements.values(): + if req.satisfied_by is None: + assert req.name is not None + preparer.save_linked_requirement(req) + downloaded.append(req.name) + if downloaded: + write_output('Successfully downloaded %s', ' '.join(downloaded)) + + return SUCCESS diff --git a/venv/Lib/site-packages/pip/_internal/commands/freeze.py b/venv/Lib/site-packages/pip/_internal/commands/freeze.py new file mode 100644 index 0000000..bf20db6 --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/commands/freeze.py @@ -0,0 +1,107 @@ +import sys + +from pip._internal.cli import cmdoptions +from pip._internal.cli.base_command import Command +from pip._internal.cli.status_codes import SUCCESS +from pip._internal.operations.freeze import freeze +from pip._internal.utils.compat import stdlib_pkgs +from pip._internal.utils.deprecation import deprecated +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +DEV_PKGS = {'pip', 'setuptools', 'distribute', 'wheel'} + +if MYPY_CHECK_RUNNING: + from optparse import Values + from typing import List + + +class FreezeCommand(Command): + """ + Output installed packages in requirements format. + + packages are listed in a case-insensitive sorted order. + """ + + usage = """ + %prog [options]""" + log_streams = ("ext://sys.stderr", "ext://sys.stderr") + + def add_options(self): + # type: () -> None + self.cmd_opts.add_option( + '-r', '--requirement', + dest='requirements', + action='append', + default=[], + metavar='file', + help="Use the order in the given requirements file and its " + "comments when generating output. This option can be " + "used multiple times.") + self.cmd_opts.add_option( + '-f', '--find-links', + dest='find_links', + action='append', + default=[], + metavar='URL', + help='URL for finding packages, which will be added to the ' + 'output.') + self.cmd_opts.add_option( + '-l', '--local', + dest='local', + action='store_true', + default=False, + help='If in a virtualenv that has global access, do not output ' + 'globally-installed packages.') + self.cmd_opts.add_option( + '--user', + dest='user', + action='store_true', + default=False, + help='Only output packages installed in user-site.') + self.cmd_opts.add_option(cmdoptions.list_path()) + self.cmd_opts.add_option( + '--all', + dest='freeze_all', + action='store_true', + help='Do not skip these packages in the output:' + ' {}'.format(', '.join(DEV_PKGS))) + self.cmd_opts.add_option( + '--exclude-editable', + dest='exclude_editable', + action='store_true', + help='Exclude editable package from output.') + self.cmd_opts.add_option(cmdoptions.list_exclude()) + + self.parser.insert_option_group(0, self.cmd_opts) + + def run(self, options, args): + # type: (Values, List[str]) -> int + skip = set(stdlib_pkgs) + if not options.freeze_all: + skip.update(DEV_PKGS) + + if options.excludes: + skip.update(options.excludes) + + cmdoptions.check_list_path_option(options) + + if options.find_links: + deprecated( + "--find-links option in pip freeze is deprecated.", + replacement=None, + gone_in="21.2", + issue=9069, + ) + + for line in freeze( + requirement=options.requirements, + find_links=options.find_links, + local_only=options.local, + user_only=options.user, + paths=options.path, + isolated=options.isolated_mode, + skip=skip, + exclude_editable=options.exclude_editable, + ): + sys.stdout.write(line + '\n') + return SUCCESS diff --git a/venv/Lib/site-packages/pip/_internal/commands/hash.py b/venv/Lib/site-packages/pip/_internal/commands/hash.py new file mode 100644 index 0000000..db68f6c --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/commands/hash.py @@ -0,0 +1,61 @@ +import hashlib +import logging +import sys + +from pip._internal.cli.base_command import Command +from pip._internal.cli.status_codes import ERROR, SUCCESS +from pip._internal.utils.hashes import FAVORITE_HASH, STRONG_HASHES +from pip._internal.utils.misc import read_chunks, write_output +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from optparse import Values + from typing import List + +logger = logging.getLogger(__name__) + + +class HashCommand(Command): + """ + Compute a hash of a local package archive. + + These can be used with --hash in a requirements file to do repeatable + installs. + """ + + usage = '%prog [options] ...' + ignore_require_venv = True + + def add_options(self): + # type: () -> None + self.cmd_opts.add_option( + '-a', '--algorithm', + dest='algorithm', + choices=STRONG_HASHES, + action='store', + default=FAVORITE_HASH, + help='The hash algorithm to use: one of {}'.format( + ', '.join(STRONG_HASHES))) + self.parser.insert_option_group(0, self.cmd_opts) + + def run(self, options, args): + # type: (Values, List[str]) -> int + if not args: + self.parser.print_usage(sys.stderr) + return ERROR + + algorithm = options.algorithm + for path in args: + write_output('%s:\n--hash=%s:%s', + path, algorithm, _hash_of_file(path, algorithm)) + return SUCCESS + + +def _hash_of_file(path, algorithm): + # type: (str, str) -> str + """Return the hash digest of a file.""" + with open(path, 'rb') as archive: + hash = hashlib.new(algorithm) + for chunk in read_chunks(archive): + hash.update(chunk) + return hash.hexdigest() diff --git a/venv/Lib/site-packages/pip/_internal/commands/help.py b/venv/Lib/site-packages/pip/_internal/commands/help.py new file mode 100644 index 0000000..8372ac6 --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/commands/help.py @@ -0,0 +1,44 @@ +from pip._internal.cli.base_command import Command +from pip._internal.cli.status_codes import SUCCESS +from pip._internal.exceptions import CommandError +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from optparse import Values + from typing import List + + +class HelpCommand(Command): + """Show help for commands""" + + usage = """ + %prog """ + ignore_require_venv = True + + def run(self, options, args): + # type: (Values, List[str]) -> int + from pip._internal.commands import ( + commands_dict, + create_command, + get_similar_commands, + ) + + try: + # 'pip help' with no args is handled by pip.__init__.parseopt() + cmd_name = args[0] # the command we need help for + except IndexError: + return SUCCESS + + if cmd_name not in commands_dict: + guess = get_similar_commands(cmd_name) + + msg = [f'unknown command "{cmd_name}"'] + if guess: + msg.append(f'maybe you meant "{guess}"') + + raise CommandError(' - '.join(msg)) + + command = create_command(cmd_name) + command.parser.print_help() + + return SUCCESS diff --git a/venv/Lib/site-packages/pip/_internal/commands/install.py b/venv/Lib/site-packages/pip/_internal/commands/install.py new file mode 100644 index 0000000..e303adf --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/commands/install.py @@ -0,0 +1,733 @@ +import errno +import logging +import operator +import os +import shutil +import site +from optparse import SUPPRESS_HELP + +from pip._vendor import pkg_resources +from pip._vendor.packaging.utils import canonicalize_name + +from pip._internal.cache import WheelCache +from pip._internal.cli import cmdoptions +from pip._internal.cli.cmdoptions import make_target_python +from pip._internal.cli.req_command import RequirementCommand, with_cleanup +from pip._internal.cli.status_codes import ERROR, SUCCESS +from pip._internal.exceptions import CommandError, InstallationError +from pip._internal.locations import distutils_scheme +from pip._internal.operations.check import check_install_conflicts +from pip._internal.req import install_given_reqs +from pip._internal.req.req_tracker import get_requirement_tracker +from pip._internal.utils.distutils_args import parse_distutils_args +from pip._internal.utils.filesystem import test_writable_dir +from pip._internal.utils.misc import ( + ensure_dir, + get_installed_version, + get_pip_version, + protect_pip_from_modification_on_windows, + write_output, +) +from pip._internal.utils.temp_dir import TempDirectory +from pip._internal.utils.typing import MYPY_CHECK_RUNNING +from pip._internal.utils.virtualenv import virtualenv_no_global +from pip._internal.wheel_builder import build, should_build_for_install_command + +if MYPY_CHECK_RUNNING: + from optparse import Values + from typing import Iterable, List, Optional + + from pip._internal.models.format_control import FormatControl + from pip._internal.operations.check import ConflictDetails + from pip._internal.req.req_install import InstallRequirement + from pip._internal.wheel_builder import BinaryAllowedPredicate + + +logger = logging.getLogger(__name__) + + +def get_check_binary_allowed(format_control): + # type: (FormatControl) -> BinaryAllowedPredicate + def check_binary_allowed(req): + # type: (InstallRequirement) -> bool + canonical_name = canonicalize_name(req.name) + allowed_formats = format_control.get_allowed_formats(canonical_name) + return "binary" in allowed_formats + + return check_binary_allowed + + +class InstallCommand(RequirementCommand): + """ + Install packages from: + + - PyPI (and other indexes) using requirement specifiers. + - VCS project urls. + - Local project directories. + - Local or remote source archives. + + pip also supports installing from "requirements files", which provide + an easy way to specify a whole environment to be installed. + """ + + usage = """ + %prog [options] [package-index-options] ... + %prog [options] -r [package-index-options] ... + %prog [options] [-e] ... + %prog [options] [-e] ... + %prog [options] ...""" + + def add_options(self): + # type: () -> None + self.cmd_opts.add_option(cmdoptions.requirements()) + self.cmd_opts.add_option(cmdoptions.constraints()) + self.cmd_opts.add_option(cmdoptions.no_deps()) + self.cmd_opts.add_option(cmdoptions.pre()) + + self.cmd_opts.add_option(cmdoptions.editable()) + self.cmd_opts.add_option( + '-t', '--target', + dest='target_dir', + metavar='dir', + default=None, + help='Install packages into . ' + 'By default this will not replace existing files/folders in ' + '. Use --upgrade to replace existing packages in ' + 'with new versions.' + ) + cmdoptions.add_target_python_options(self.cmd_opts) + + self.cmd_opts.add_option( + '--user', + dest='use_user_site', + action='store_true', + help="Install to the Python user install directory for your " + "platform. Typically ~/.local/, or %APPDATA%\\Python on " + "Windows. (See the Python documentation for site.USER_BASE " + "for full details.)") + self.cmd_opts.add_option( + '--no-user', + dest='use_user_site', + action='store_false', + help=SUPPRESS_HELP) + self.cmd_opts.add_option( + '--root', + dest='root_path', + metavar='dir', + default=None, + help="Install everything relative to this alternate root " + "directory.") + self.cmd_opts.add_option( + '--prefix', + dest='prefix_path', + metavar='dir', + default=None, + help="Installation prefix where lib, bin and other top-level " + "folders are placed") + + self.cmd_opts.add_option(cmdoptions.build_dir()) + + self.cmd_opts.add_option(cmdoptions.src()) + + self.cmd_opts.add_option( + '-U', '--upgrade', + dest='upgrade', + action='store_true', + help='Upgrade all specified packages to the newest available ' + 'version. The handling of dependencies depends on the ' + 'upgrade-strategy used.' + ) + + self.cmd_opts.add_option( + '--upgrade-strategy', + dest='upgrade_strategy', + default='only-if-needed', + choices=['only-if-needed', 'eager'], + help='Determines how dependency upgrading should be handled ' + '[default: %default]. ' + '"eager" - dependencies are upgraded regardless of ' + 'whether the currently installed version satisfies the ' + 'requirements of the upgraded package(s). ' + '"only-if-needed" - are upgraded only when they do not ' + 'satisfy the requirements of the upgraded package(s).' + ) + + self.cmd_opts.add_option( + '--force-reinstall', + dest='force_reinstall', + action='store_true', + help='Reinstall all packages even if they are already ' + 'up-to-date.') + + self.cmd_opts.add_option( + '-I', '--ignore-installed', + dest='ignore_installed', + action='store_true', + help='Ignore the installed packages, overwriting them. ' + 'This can break your system if the existing package ' + 'is of a different version or was installed ' + 'with a different package manager!' + ) + + self.cmd_opts.add_option(cmdoptions.ignore_requires_python()) + self.cmd_opts.add_option(cmdoptions.no_build_isolation()) + self.cmd_opts.add_option(cmdoptions.use_pep517()) + self.cmd_opts.add_option(cmdoptions.no_use_pep517()) + + self.cmd_opts.add_option(cmdoptions.install_options()) + self.cmd_opts.add_option(cmdoptions.global_options()) + + self.cmd_opts.add_option( + "--compile", + action="store_true", + dest="compile", + default=True, + help="Compile Python source files to bytecode", + ) + + self.cmd_opts.add_option( + "--no-compile", + action="store_false", + dest="compile", + help="Do not compile Python source files to bytecode", + ) + + self.cmd_opts.add_option( + "--no-warn-script-location", + action="store_false", + dest="warn_script_location", + default=True, + help="Do not warn when installing scripts outside PATH", + ) + self.cmd_opts.add_option( + "--no-warn-conflicts", + action="store_false", + dest="warn_about_conflicts", + default=True, + help="Do not warn about broken dependencies", + ) + + self.cmd_opts.add_option(cmdoptions.no_binary()) + self.cmd_opts.add_option(cmdoptions.only_binary()) + self.cmd_opts.add_option(cmdoptions.prefer_binary()) + self.cmd_opts.add_option(cmdoptions.require_hashes()) + self.cmd_opts.add_option(cmdoptions.progress_bar()) + + index_opts = cmdoptions.make_option_group( + cmdoptions.index_group, + self.parser, + ) + + self.parser.insert_option_group(0, index_opts) + self.parser.insert_option_group(0, self.cmd_opts) + + @with_cleanup + def run(self, options, args): + # type: (Values, List[str]) -> int + if options.use_user_site and options.target_dir is not None: + raise CommandError("Can not combine '--user' and '--target'") + + cmdoptions.check_install_build_global(options) + upgrade_strategy = "to-satisfy-only" + if options.upgrade: + upgrade_strategy = options.upgrade_strategy + + cmdoptions.check_dist_restriction(options, check_target=True) + + install_options = options.install_options or [] + + logger.debug("Using %s", get_pip_version()) + options.use_user_site = decide_user_install( + options.use_user_site, + prefix_path=options.prefix_path, + target_dir=options.target_dir, + root_path=options.root_path, + isolated_mode=options.isolated_mode, + ) + + target_temp_dir = None # type: Optional[TempDirectory] + target_temp_dir_path = None # type: Optional[str] + if options.target_dir: + options.ignore_installed = True + options.target_dir = os.path.abspath(options.target_dir) + if (os.path.exists(options.target_dir) and not + os.path.isdir(options.target_dir)): + raise CommandError( + "Target path exists but is not a directory, will not " + "continue." + ) + + # Create a target directory for using with the target option + target_temp_dir = TempDirectory(kind="target") + target_temp_dir_path = target_temp_dir.path + self.enter_context(target_temp_dir) + + global_options = options.global_options or [] + + session = self.get_default_session(options) + + target_python = make_target_python(options) + finder = self._build_package_finder( + options=options, + session=session, + target_python=target_python, + ignore_requires_python=options.ignore_requires_python, + ) + wheel_cache = WheelCache(options.cache_dir, options.format_control) + + req_tracker = self.enter_context(get_requirement_tracker()) + + directory = TempDirectory( + delete=not options.no_clean, + kind="install", + globally_managed=True, + ) + + try: + reqs = self.get_requirements(args, options, finder, session) + + reject_location_related_install_options( + reqs, options.install_options + ) + + preparer = self.make_requirement_preparer( + temp_build_dir=directory, + options=options, + req_tracker=req_tracker, + session=session, + finder=finder, + use_user_site=options.use_user_site, + ) + resolver = self.make_resolver( + preparer=preparer, + finder=finder, + options=options, + wheel_cache=wheel_cache, + use_user_site=options.use_user_site, + ignore_installed=options.ignore_installed, + ignore_requires_python=options.ignore_requires_python, + force_reinstall=options.force_reinstall, + upgrade_strategy=upgrade_strategy, + use_pep517=options.use_pep517, + ) + + self.trace_basic_info(finder) + + requirement_set = resolver.resolve( + reqs, check_supported_wheels=not options.target_dir + ) + + try: + pip_req = requirement_set.get_requirement("pip") + except KeyError: + modifying_pip = False + else: + # If we're not replacing an already installed pip, + # we're not modifying it. + modifying_pip = pip_req.satisfied_by is None + protect_pip_from_modification_on_windows( + modifying_pip=modifying_pip + ) + + check_binary_allowed = get_check_binary_allowed( + finder.format_control + ) + + reqs_to_build = [ + r for r in requirement_set.requirements.values() + if should_build_for_install_command( + r, check_binary_allowed + ) + ] + + _, build_failures = build( + reqs_to_build, + wheel_cache=wheel_cache, + verify=True, + build_options=[], + global_options=[], + ) + + # If we're using PEP 517, we cannot do a direct install + # so we fail here. + pep517_build_failure_names = [ + r.name # type: ignore + for r in build_failures if r.use_pep517 + ] # type: List[str] + if pep517_build_failure_names: + raise InstallationError( + "Could not build wheels for {} which use" + " PEP 517 and cannot be installed directly".format( + ", ".join(pep517_build_failure_names) + ) + ) + + # For now, we just warn about failures building legacy + # requirements, as we'll fall through to a direct + # install for those. + for r in build_failures: + if not r.use_pep517: + r.legacy_install_reason = 8368 + + to_install = resolver.get_installation_order( + requirement_set + ) + + # Check for conflicts in the package set we're installing. + conflicts = None # type: Optional[ConflictDetails] + should_warn_about_conflicts = ( + not options.ignore_dependencies and + options.warn_about_conflicts + ) + if should_warn_about_conflicts: + conflicts = self._determine_conflicts(to_install) + + # Don't warn about script install locations if + # --target has been specified + warn_script_location = options.warn_script_location + if options.target_dir: + warn_script_location = False + + installed = install_given_reqs( + to_install, + install_options, + global_options, + root=options.root_path, + home=target_temp_dir_path, + prefix=options.prefix_path, + warn_script_location=warn_script_location, + use_user_site=options.use_user_site, + pycompile=options.compile, + ) + + lib_locations = get_lib_location_guesses( + user=options.use_user_site, + home=target_temp_dir_path, + root=options.root_path, + prefix=options.prefix_path, + isolated=options.isolated_mode, + ) + working_set = pkg_resources.WorkingSet(lib_locations) + + installed.sort(key=operator.attrgetter('name')) + items = [] + for result in installed: + item = result.name + try: + installed_version = get_installed_version( + result.name, working_set=working_set + ) + if installed_version: + item += '-' + installed_version + except Exception: + pass + items.append(item) + + if conflicts is not None: + self._warn_about_conflicts( + conflicts, + resolver_variant=self.determine_resolver_variant(options), + ) + + installed_desc = ' '.join(items) + if installed_desc: + write_output( + 'Successfully installed %s', installed_desc, + ) + except OSError as error: + show_traceback = (self.verbosity >= 1) + + message = create_os_error_message( + error, show_traceback, options.use_user_site, + ) + logger.error(message, exc_info=show_traceback) # noqa + + return ERROR + + if options.target_dir: + assert target_temp_dir + self._handle_target_dir( + options.target_dir, target_temp_dir, options.upgrade + ) + + return SUCCESS + + def _handle_target_dir(self, target_dir, target_temp_dir, upgrade): + # type: (str, TempDirectory, bool) -> None + ensure_dir(target_dir) + + # Checking both purelib and platlib directories for installed + # packages to be moved to target directory + lib_dir_list = [] + + # Checking both purelib and platlib directories for installed + # packages to be moved to target directory + scheme = distutils_scheme('', home=target_temp_dir.path) + purelib_dir = scheme['purelib'] + platlib_dir = scheme['platlib'] + data_dir = scheme['data'] + + if os.path.exists(purelib_dir): + lib_dir_list.append(purelib_dir) + if os.path.exists(platlib_dir) and platlib_dir != purelib_dir: + lib_dir_list.append(platlib_dir) + if os.path.exists(data_dir): + lib_dir_list.append(data_dir) + + for lib_dir in lib_dir_list: + for item in os.listdir(lib_dir): + if lib_dir == data_dir: + ddir = os.path.join(data_dir, item) + if any(s.startswith(ddir) for s in lib_dir_list[:-1]): + continue + target_item_dir = os.path.join(target_dir, item) + if os.path.exists(target_item_dir): + if not upgrade: + logger.warning( + 'Target directory %s already exists. Specify ' + '--upgrade to force replacement.', + target_item_dir + ) + continue + if os.path.islink(target_item_dir): + logger.warning( + 'Target directory %s already exists and is ' + 'a link. pip will not automatically replace ' + 'links, please remove if replacement is ' + 'desired.', + target_item_dir + ) + continue + if os.path.isdir(target_item_dir): + shutil.rmtree(target_item_dir) + else: + os.remove(target_item_dir) + + shutil.move( + os.path.join(lib_dir, item), + target_item_dir + ) + + def _determine_conflicts(self, to_install): + # type: (List[InstallRequirement]) -> Optional[ConflictDetails] + try: + return check_install_conflicts(to_install) + except Exception: + logger.exception( + "Error while checking for conflicts. Please file an issue on " + "pip's issue tracker: https://github.com/pypa/pip/issues/new" + ) + return None + + def _warn_about_conflicts(self, conflict_details, resolver_variant): + # type: (ConflictDetails, str) -> None + package_set, (missing, conflicting) = conflict_details + if not missing and not conflicting: + return + + parts = [] # type: List[str] + if resolver_variant == "legacy": + parts.append( + "pip's legacy dependency resolver does not consider dependency " + "conflicts when selecting packages. This behaviour is the " + "source of the following dependency conflicts." + ) + else: + assert resolver_variant == "2020-resolver" + parts.append( + "pip's dependency resolver does not currently take into account " + "all the packages that are installed. This behaviour is the " + "source of the following dependency conflicts." + ) + + # NOTE: There is some duplication here, with commands/check.py + for project_name in missing: + version = package_set[project_name][0] + for dependency in missing[project_name]: + message = ( + "{name} {version} requires {requirement}, " + "which is not installed." + ).format( + name=project_name, + version=version, + requirement=dependency[1], + ) + parts.append(message) + + for project_name in conflicting: + version = package_set[project_name][0] + for dep_name, dep_version, req in conflicting[project_name]: + message = ( + "{name} {version} requires {requirement}, but {you} have " + "{dep_name} {dep_version} which is incompatible." + ).format( + name=project_name, + version=version, + requirement=req, + dep_name=dep_name, + dep_version=dep_version, + you=("you" if resolver_variant == "2020-resolver" else "you'll") + ) + parts.append(message) + + logger.critical("\n".join(parts)) + + +def get_lib_location_guesses( + user=False, # type: bool + home=None, # type: Optional[str] + root=None, # type: Optional[str] + isolated=False, # type: bool + prefix=None # type: Optional[str] +): + # type:(...) -> List[str] + scheme = distutils_scheme('', user=user, home=home, root=root, + isolated=isolated, prefix=prefix) + return [scheme['purelib'], scheme['platlib']] + + +def site_packages_writable(root, isolated): + # type: (Optional[str], bool) -> bool + return all( + test_writable_dir(d) for d in set( + get_lib_location_guesses(root=root, isolated=isolated)) + ) + + +def decide_user_install( + use_user_site, # type: Optional[bool] + prefix_path=None, # type: Optional[str] + target_dir=None, # type: Optional[str] + root_path=None, # type: Optional[str] + isolated_mode=False, # type: bool +): + # type: (...) -> bool + """Determine whether to do a user install based on the input options. + + If use_user_site is False, no additional checks are done. + If use_user_site is True, it is checked for compatibility with other + options. + If use_user_site is None, the default behaviour depends on the environment, + which is provided by the other arguments. + """ + # In some cases (config from tox), use_user_site can be set to an integer + # rather than a bool, which 'use_user_site is False' wouldn't catch. + if (use_user_site is not None) and (not use_user_site): + logger.debug("Non-user install by explicit request") + return False + + if use_user_site: + if prefix_path: + raise CommandError( + "Can not combine '--user' and '--prefix' as they imply " + "different installation locations" + ) + if virtualenv_no_global(): + raise InstallationError( + "Can not perform a '--user' install. User site-packages " + "are not visible in this virtualenv." + ) + logger.debug("User install by explicit request") + return True + + # If we are here, user installs have not been explicitly requested/avoided + assert use_user_site is None + + # user install incompatible with --prefix/--target + if prefix_path or target_dir: + logger.debug("Non-user install due to --prefix or --target option") + return False + + # If user installs are not enabled, choose a non-user install + if not site.ENABLE_USER_SITE: + logger.debug("Non-user install because user site-packages disabled") + return False + + # If we have permission for a non-user install, do that, + # otherwise do a user install. + if site_packages_writable(root=root_path, isolated=isolated_mode): + logger.debug("Non-user install because site-packages writeable") + return False + + logger.info("Defaulting to user installation because normal site-packages " + "is not writeable") + return True + + +def reject_location_related_install_options(requirements, options): + # type: (List[InstallRequirement], Optional[List[str]]) -> None + """If any location-changing --install-option arguments were passed for + requirements or on the command-line, then show a deprecation warning. + """ + def format_options(option_names): + # type: (Iterable[str]) -> List[str] + return ["--{}".format(name.replace("_", "-")) for name in option_names] + + offenders = [] + + for requirement in requirements: + install_options = requirement.install_options + location_options = parse_distutils_args(install_options) + if location_options: + offenders.append( + "{!r} from {}".format( + format_options(location_options.keys()), requirement + ) + ) + + if options: + location_options = parse_distutils_args(options) + if location_options: + offenders.append( + "{!r} from command line".format( + format_options(location_options.keys()) + ) + ) + + if not offenders: + return + + raise CommandError( + "Location-changing options found in --install-option: {}." + " This is unsupported, use pip-level options like --user," + " --prefix, --root, and --target instead.".format( + "; ".join(offenders) + ) + ) + + +def create_os_error_message(error, show_traceback, using_user_site): + # type: (OSError, bool, bool) -> str + """Format an error message for an OSError + + It may occur anytime during the execution of the install command. + """ + parts = [] + + # Mention the error if we are not going to show a traceback + parts.append("Could not install packages due to an OSError") + if not show_traceback: + parts.append(": ") + parts.append(str(error)) + else: + parts.append(".") + + # Spilt the error indication from a helper message (if any) + parts[-1] += "\n" + + # Suggest useful actions to the user: + # (1) using user site-packages or (2) verifying the permissions + if error.errno == errno.EACCES: + user_option_part = "Consider using the `--user` option" + permissions_part = "Check the permissions" + + if not using_user_site: + parts.extend([ + user_option_part, " or ", + permissions_part.lower(), + ]) + else: + parts.append(permissions_part) + parts.append(".\n") + + return "".join(parts).strip() + "\n" diff --git a/venv/Lib/site-packages/pip/_internal/commands/list.py b/venv/Lib/site-packages/pip/_internal/commands/list.py new file mode 100644 index 0000000..89cfb62 --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/commands/list.py @@ -0,0 +1,323 @@ +import json +import logging + +from pip._internal.cli import cmdoptions +from pip._internal.cli.req_command import IndexGroupCommand +from pip._internal.cli.status_codes import SUCCESS +from pip._internal.exceptions import CommandError +from pip._internal.index.collector import LinkCollector +from pip._internal.index.package_finder import PackageFinder +from pip._internal.models.selection_prefs import SelectionPreferences +from pip._internal.utils.compat import stdlib_pkgs +from pip._internal.utils.misc import ( + dist_is_editable, + get_installed_distributions, + tabulate, + write_output, +) +from pip._internal.utils.packaging import get_installer +from pip._internal.utils.parallel import map_multithread +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from optparse import Values + from typing import Iterator, List, Set, Tuple + + from pip._vendor.pkg_resources import Distribution + + from pip._internal.network.session import PipSession + +logger = logging.getLogger(__name__) + + +class ListCommand(IndexGroupCommand): + """ + List installed packages, including editables. + + Packages are listed in a case-insensitive sorted order. + """ + + ignore_require_venv = True + usage = """ + %prog [options]""" + + def add_options(self): + # type: () -> None + self.cmd_opts.add_option( + '-o', '--outdated', + action='store_true', + default=False, + help='List outdated packages') + self.cmd_opts.add_option( + '-u', '--uptodate', + action='store_true', + default=False, + help='List uptodate packages') + self.cmd_opts.add_option( + '-e', '--editable', + action='store_true', + default=False, + help='List editable projects.') + self.cmd_opts.add_option( + '-l', '--local', + action='store_true', + default=False, + help=('If in a virtualenv that has global access, do not list ' + 'globally-installed packages.'), + ) + self.cmd_opts.add_option( + '--user', + dest='user', + action='store_true', + default=False, + help='Only output packages installed in user-site.') + self.cmd_opts.add_option(cmdoptions.list_path()) + self.cmd_opts.add_option( + '--pre', + action='store_true', + default=False, + help=("Include pre-release and development versions. By default, " + "pip only finds stable versions."), + ) + + self.cmd_opts.add_option( + '--format', + action='store', + dest='list_format', + default="columns", + choices=('columns', 'freeze', 'json'), + help="Select the output format among: columns (default), freeze, " + "or json", + ) + + self.cmd_opts.add_option( + '--not-required', + action='store_true', + dest='not_required', + help="List packages that are not dependencies of " + "installed packages.", + ) + + self.cmd_opts.add_option( + '--exclude-editable', + action='store_false', + dest='include_editable', + help='Exclude editable package from output.', + ) + self.cmd_opts.add_option( + '--include-editable', + action='store_true', + dest='include_editable', + help='Include editable package from output.', + default=True, + ) + self.cmd_opts.add_option(cmdoptions.list_exclude()) + index_opts = cmdoptions.make_option_group( + cmdoptions.index_group, self.parser + ) + + self.parser.insert_option_group(0, index_opts) + self.parser.insert_option_group(0, self.cmd_opts) + + def _build_package_finder(self, options, session): + # type: (Values, PipSession) -> PackageFinder + """ + Create a package finder appropriate to this list command. + """ + link_collector = LinkCollector.create(session, options=options) + + # Pass allow_yanked=False to ignore yanked versions. + selection_prefs = SelectionPreferences( + allow_yanked=False, + allow_all_prereleases=options.pre, + ) + + return PackageFinder.create( + link_collector=link_collector, + selection_prefs=selection_prefs, + ) + + def run(self, options, args): + # type: (Values, List[str]) -> int + if options.outdated and options.uptodate: + raise CommandError( + "Options --outdated and --uptodate cannot be combined.") + + cmdoptions.check_list_path_option(options) + + skip = set(stdlib_pkgs) + if options.excludes: + skip.update(options.excludes) + + packages = get_installed_distributions( + local_only=options.local, + user_only=options.user, + editables_only=options.editable, + include_editables=options.include_editable, + paths=options.path, + skip=skip, + ) + + # get_not_required must be called firstly in order to find and + # filter out all dependencies correctly. Otherwise a package + # can't be identified as requirement because some parent packages + # could be filtered out before. + if options.not_required: + packages = self.get_not_required(packages, options) + + if options.outdated: + packages = self.get_outdated(packages, options) + elif options.uptodate: + packages = self.get_uptodate(packages, options) + + self.output_package_listing(packages, options) + return SUCCESS + + def get_outdated(self, packages, options): + # type: (List[Distribution], Values) -> List[Distribution] + return [ + dist for dist in self.iter_packages_latest_infos(packages, options) + if dist.latest_version > dist.parsed_version + ] + + def get_uptodate(self, packages, options): + # type: (List[Distribution], Values) -> List[Distribution] + return [ + dist for dist in self.iter_packages_latest_infos(packages, options) + if dist.latest_version == dist.parsed_version + ] + + def get_not_required(self, packages, options): + # type: (List[Distribution], Values) -> List[Distribution] + dep_keys = set() # type: Set[Distribution] + for dist in packages: + dep_keys.update(requirement.key for requirement in dist.requires()) + + # Create a set to remove duplicate packages, and cast it to a list + # to keep the return type consistent with get_outdated and + # get_uptodate + return list({pkg for pkg in packages if pkg.key not in dep_keys}) + + def iter_packages_latest_infos(self, packages, options): + # type: (List[Distribution], Values) -> Iterator[Distribution] + with self._build_session(options) as session: + finder = self._build_package_finder(options, session) + + def latest_info(dist): + # type: (Distribution) -> Distribution + all_candidates = finder.find_all_candidates(dist.key) + if not options.pre: + # Remove prereleases + all_candidates = [candidate for candidate in all_candidates + if not candidate.version.is_prerelease] + + evaluator = finder.make_candidate_evaluator( + project_name=dist.project_name, + ) + best_candidate = evaluator.sort_best_candidate(all_candidates) + if best_candidate is None: + return None + + remote_version = best_candidate.version + if best_candidate.link.is_wheel: + typ = 'wheel' + else: + typ = 'sdist' + # This is dirty but makes the rest of the code much cleaner + dist.latest_version = remote_version + dist.latest_filetype = typ + return dist + + for dist in map_multithread(latest_info, packages): + if dist is not None: + yield dist + + def output_package_listing(self, packages, options): + # type: (List[Distribution], Values) -> None + packages = sorted( + packages, + key=lambda dist: dist.project_name.lower(), + ) + if options.list_format == 'columns' and packages: + data, header = format_for_columns(packages, options) + self.output_package_listing_columns(data, header) + elif options.list_format == 'freeze': + for dist in packages: + if options.verbose >= 1: + write_output("%s==%s (%s)", dist.project_name, + dist.version, dist.location) + else: + write_output("%s==%s", dist.project_name, dist.version) + elif options.list_format == 'json': + write_output(format_for_json(packages, options)) + + def output_package_listing_columns(self, data, header): + # type: (List[List[str]], List[str]) -> None + # insert the header first: we need to know the size of column names + if len(data) > 0: + data.insert(0, header) + + pkg_strings, sizes = tabulate(data) + + # Create and add a separator. + if len(data) > 0: + pkg_strings.insert(1, " ".join(map(lambda x: '-' * x, sizes))) + + for val in pkg_strings: + write_output(val) + + +def format_for_columns(pkgs, options): + # type: (List[Distribution], Values) -> Tuple[List[List[str]], List[str]] + """ + Convert the package data into something usable + by output_package_listing_columns. + """ + running_outdated = options.outdated + # Adjust the header for the `pip list --outdated` case. + if running_outdated: + header = ["Package", "Version", "Latest", "Type"] + else: + header = ["Package", "Version"] + + data = [] + if options.verbose >= 1 or any(dist_is_editable(x) for x in pkgs): + header.append("Location") + if options.verbose >= 1: + header.append("Installer") + + for proj in pkgs: + # if we're working on the 'outdated' list, separate out the + # latest_version and type + row = [proj.project_name, proj.version] + + if running_outdated: + row.append(proj.latest_version) + row.append(proj.latest_filetype) + + if options.verbose >= 1 or dist_is_editable(proj): + row.append(proj.location) + if options.verbose >= 1: + row.append(get_installer(proj)) + + data.append(row) + + return data, header + + +def format_for_json(packages, options): + # type: (List[Distribution], Values) -> str + data = [] + for dist in packages: + info = { + 'name': dist.project_name, + 'version': str(dist.version), + } + if options.verbose >= 1: + info['location'] = dist.location + info['installer'] = get_installer(dist) + if options.outdated: + info['latest_version'] = str(dist.latest_version) + info['latest_filetype'] = dist.latest_filetype + data.append(info) + return json.dumps(data) diff --git a/venv/Lib/site-packages/pip/_internal/commands/search.py b/venv/Lib/site-packages/pip/_internal/commands/search.py new file mode 100644 index 0000000..b3143b7 --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/commands/search.py @@ -0,0 +1,167 @@ +import logging +import shutil +import sys +import textwrap +from collections import OrderedDict + +from pip._vendor import pkg_resources +from pip._vendor.packaging.version import parse as parse_version + +# NOTE: XMLRPC Client is not annotated in typeshed as on 2017-07-17, which is +# why we ignore the type on this import +from pip._vendor.six.moves import xmlrpc_client # type: ignore + +from pip._internal.cli.base_command import Command +from pip._internal.cli.req_command import SessionCommandMixin +from pip._internal.cli.status_codes import NO_MATCHES_FOUND, SUCCESS +from pip._internal.exceptions import CommandError +from pip._internal.models.index import PyPI +from pip._internal.network.xmlrpc import PipXmlrpcTransport +from pip._internal.utils.logging import indent_log +from pip._internal.utils.misc import get_distribution, write_output +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from optparse import Values + from typing import Dict, List, Optional + + from typing_extensions import TypedDict + TransformedHit = TypedDict( + 'TransformedHit', + {'name': str, 'summary': str, 'versions': List[str]}, + ) + +logger = logging.getLogger(__name__) + + +class SearchCommand(Command, SessionCommandMixin): + """Search for PyPI packages whose name or summary contains .""" + + usage = """ + %prog [options] """ + ignore_require_venv = True + + def add_options(self): + # type: () -> None + self.cmd_opts.add_option( + '-i', '--index', + dest='index', + metavar='URL', + default=PyPI.pypi_url, + help='Base URL of Python Package Index (default %default)') + + self.parser.insert_option_group(0, self.cmd_opts) + + def run(self, options, args): + # type: (Values, List[str]) -> int + if not args: + raise CommandError('Missing required argument (search query).') + query = args + pypi_hits = self.search(query, options) + hits = transform_hits(pypi_hits) + + terminal_width = None + if sys.stdout.isatty(): + terminal_width = shutil.get_terminal_size()[0] + + print_results(hits, terminal_width=terminal_width) + if pypi_hits: + return SUCCESS + return NO_MATCHES_FOUND + + def search(self, query, options): + # type: (List[str], Values) -> List[Dict[str, str]] + index_url = options.index + + session = self.get_default_session(options) + + transport = PipXmlrpcTransport(index_url, session) + pypi = xmlrpc_client.ServerProxy(index_url, transport) + try: + hits = pypi.search({'name': query, 'summary': query}, 'or') + except xmlrpc_client.Fault as fault: + message = "XMLRPC request failed [code: {code}]\n{string}".format( + code=fault.faultCode, + string=fault.faultString, + ) + raise CommandError(message) + return hits + + +def transform_hits(hits): + # type: (List[Dict[str, str]]) -> List[TransformedHit] + """ + The list from pypi is really a list of versions. We want a list of + packages with the list of versions stored inline. This converts the + list from pypi into one we can use. + """ + packages = OrderedDict() # type: OrderedDict[str, TransformedHit] + for hit in hits: + name = hit['name'] + summary = hit['summary'] + version = hit['version'] + + if name not in packages.keys(): + packages[name] = { + 'name': name, + 'summary': summary, + 'versions': [version], + } + else: + packages[name]['versions'].append(version) + + # if this is the highest version, replace summary and score + if version == highest_version(packages[name]['versions']): + packages[name]['summary'] = summary + + return list(packages.values()) + + +def print_results(hits, name_column_width=None, terminal_width=None): + # type: (List[TransformedHit], Optional[int], Optional[int]) -> None + if not hits: + return + if name_column_width is None: + name_column_width = max([ + len(hit['name']) + len(highest_version(hit.get('versions', ['-']))) + for hit in hits + ]) + 4 + + installed_packages = [p.project_name for p in pkg_resources.working_set] + for hit in hits: + name = hit['name'] + summary = hit['summary'] or '' + latest = highest_version(hit.get('versions', ['-'])) + if terminal_width is not None: + target_width = terminal_width - name_column_width - 5 + if target_width > 10: + # wrap and indent summary to fit terminal + summary_lines = textwrap.wrap(summary, target_width) + summary = ('\n' + ' ' * (name_column_width + 3)).join( + summary_lines) + + line = '{name_latest:{name_column_width}} - {summary}'.format( + name_latest='{name} ({latest})'.format(**locals()), + **locals()) + try: + write_output(line) + if name in installed_packages: + dist = get_distribution(name) + assert dist is not None + with indent_log(): + if dist.version == latest: + write_output('INSTALLED: %s (latest)', dist.version) + else: + write_output('INSTALLED: %s', dist.version) + if parse_version(latest).pre: + write_output('LATEST: %s (pre-release; install' + ' with "pip install --pre")', latest) + else: + write_output('LATEST: %s', latest) + except UnicodeEncodeError: + pass + + +def highest_version(versions): + # type: (List[str]) -> str + return max(versions, key=parse_version) diff --git a/venv/Lib/site-packages/pip/_internal/commands/show.py b/venv/Lib/site-packages/pip/_internal/commands/show.py new file mode 100644 index 0000000..a6363cf --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/commands/show.py @@ -0,0 +1,184 @@ +import logging +import os +from email.parser import FeedParser + +from pip._vendor import pkg_resources +from pip._vendor.packaging.utils import canonicalize_name + +from pip._internal.cli.base_command import Command +from pip._internal.cli.status_codes import ERROR, SUCCESS +from pip._internal.utils.misc import write_output +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from optparse import Values + from typing import Dict, Iterator, List + +logger = logging.getLogger(__name__) + + +class ShowCommand(Command): + """ + Show information about one or more installed packages. + + The output is in RFC-compliant mail header format. + """ + + usage = """ + %prog [options] ...""" + ignore_require_venv = True + + def add_options(self): + # type: () -> None + self.cmd_opts.add_option( + '-f', '--files', + dest='files', + action='store_true', + default=False, + help='Show the full list of installed files for each package.') + + self.parser.insert_option_group(0, self.cmd_opts) + + def run(self, options, args): + # type: (Values, List[str]) -> int + if not args: + logger.warning('ERROR: Please provide a package name or names.') + return ERROR + query = args + + results = search_packages_info(query) + if not print_results( + results, list_files=options.files, verbose=options.verbose): + return ERROR + return SUCCESS + + +def search_packages_info(query): + # type: (List[str]) -> Iterator[Dict[str, str]] + """ + Gather details from installed distributions. Print distribution name, + version, location, and installed files. Installed files requires a + pip generated 'installed-files.txt' in the distributions '.egg-info' + directory. + """ + installed = {} + for p in pkg_resources.working_set: + installed[canonicalize_name(p.project_name)] = p + + query_names = [canonicalize_name(name) for name in query] + missing = sorted( + [name for name, pkg in zip(query, query_names) if pkg not in installed] + ) + if missing: + logger.warning('Package(s) not found: %s', ', '.join(missing)) + + def get_requiring_packages(package_name): + # type: (str) -> List[str] + canonical_name = canonicalize_name(package_name) + return [ + pkg.project_name for pkg in pkg_resources.working_set + if canonical_name in + [canonicalize_name(required.name) for required in + pkg.requires()] + ] + + for dist in [installed[pkg] for pkg in query_names if pkg in installed]: + package = { + 'name': dist.project_name, + 'version': dist.version, + 'location': dist.location, + 'requires': [dep.project_name for dep in dist.requires()], + 'required_by': get_requiring_packages(dist.project_name) + } + file_list = None + metadata = '' + if isinstance(dist, pkg_resources.DistInfoDistribution): + # RECORDs should be part of .dist-info metadatas + if dist.has_metadata('RECORD'): + lines = dist.get_metadata_lines('RECORD') + paths = [line.split(',')[0] for line in lines] + paths = [os.path.join(dist.location, p) for p in paths] + file_list = [os.path.relpath(p, dist.location) for p in paths] + + if dist.has_metadata('METADATA'): + metadata = dist.get_metadata('METADATA') + else: + # Otherwise use pip's log for .egg-info's + if dist.has_metadata('installed-files.txt'): + paths = dist.get_metadata_lines('installed-files.txt') + paths = [os.path.join(dist.egg_info, p) for p in paths] + file_list = [os.path.relpath(p, dist.location) for p in paths] + + if dist.has_metadata('PKG-INFO'): + metadata = dist.get_metadata('PKG-INFO') + + if dist.has_metadata('entry_points.txt'): + entry_points = dist.get_metadata_lines('entry_points.txt') + package['entry_points'] = entry_points + + if dist.has_metadata('INSTALLER'): + for line in dist.get_metadata_lines('INSTALLER'): + if line.strip(): + package['installer'] = line.strip() + break + + # @todo: Should pkg_resources.Distribution have a + # `get_pkg_info` method? + feed_parser = FeedParser() + feed_parser.feed(metadata) + pkg_info_dict = feed_parser.close() + for key in ('metadata-version', 'summary', + 'home-page', 'author', 'author-email', 'license'): + package[key] = pkg_info_dict.get(key) + + # It looks like FeedParser cannot deal with repeated headers + classifiers = [] + for line in metadata.splitlines(): + if line.startswith('Classifier: '): + classifiers.append(line[len('Classifier: '):]) + package['classifiers'] = classifiers + + if file_list: + package['files'] = sorted(file_list) + yield package + + +def print_results(distributions, list_files=False, verbose=False): + # type: (Iterator[Dict[str, str]], bool, bool) -> bool + """ + Print the information from installed distributions found. + """ + results_printed = False + for i, dist in enumerate(distributions): + results_printed = True + if i > 0: + write_output("---") + + write_output("Name: %s", dist.get('name', '')) + write_output("Version: %s", dist.get('version', '')) + write_output("Summary: %s", dist.get('summary', '')) + write_output("Home-page: %s", dist.get('home-page', '')) + write_output("Author: %s", dist.get('author', '')) + write_output("Author-email: %s", dist.get('author-email', '')) + write_output("License: %s", dist.get('license', '')) + write_output("Location: %s", dist.get('location', '')) + write_output("Requires: %s", ', '.join(dist.get('requires', []))) + write_output("Required-by: %s", ', '.join(dist.get('required_by', []))) + + if verbose: + write_output("Metadata-Version: %s", + dist.get('metadata-version', '')) + write_output("Installer: %s", dist.get('installer', '')) + write_output("Classifiers:") + for classifier in dist.get('classifiers', []): + write_output(" %s", classifier) + write_output("Entry-points:") + for entry in dist.get('entry_points', []): + write_output(" %s", entry.strip()) + if list_files: + write_output("Files:") + for line in dist.get('files', []): + write_output(" %s", line.strip()) + if "files" not in dist: + write_output("Cannot locate installed-files.txt") + return results_printed diff --git a/venv/Lib/site-packages/pip/_internal/commands/uninstall.py b/venv/Lib/site-packages/pip/_internal/commands/uninstall.py new file mode 100644 index 0000000..6dc96c3 --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/commands/uninstall.py @@ -0,0 +1,93 @@ +from pip._vendor.packaging.utils import canonicalize_name + +from pip._internal.cli.base_command import Command +from pip._internal.cli.req_command import SessionCommandMixin +from pip._internal.cli.status_codes import SUCCESS +from pip._internal.exceptions import InstallationError +from pip._internal.req import parse_requirements +from pip._internal.req.constructors import ( + install_req_from_line, + install_req_from_parsed_requirement, +) +from pip._internal.utils.misc import protect_pip_from_modification_on_windows +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from optparse import Values + from typing import List + + +class UninstallCommand(Command, SessionCommandMixin): + """ + Uninstall packages. + + pip is able to uninstall most installed packages. Known exceptions are: + + - Pure distutils packages installed with ``python setup.py install``, which + leave behind no metadata to determine what files were installed. + - Script wrappers installed by ``python setup.py develop``. + """ + + usage = """ + %prog [options] ... + %prog [options] -r ...""" + + def add_options(self): + # type: () -> None + self.cmd_opts.add_option( + '-r', '--requirement', + dest='requirements', + action='append', + default=[], + metavar='file', + help='Uninstall all the packages listed in the given requirements ' + 'file. This option can be used multiple times.', + ) + self.cmd_opts.add_option( + '-y', '--yes', + dest='yes', + action='store_true', + help="Don't ask for confirmation of uninstall deletions.") + + self.parser.insert_option_group(0, self.cmd_opts) + + def run(self, options, args): + # type: (Values, List[str]) -> int + session = self.get_default_session(options) + + reqs_to_uninstall = {} + for name in args: + req = install_req_from_line( + name, isolated=options.isolated_mode, + ) + if req.name: + reqs_to_uninstall[canonicalize_name(req.name)] = req + for filename in options.requirements: + for parsed_req in parse_requirements( + filename, + options=options, + session=session): + req = install_req_from_parsed_requirement( + parsed_req, + isolated=options.isolated_mode + ) + if req.name: + reqs_to_uninstall[canonicalize_name(req.name)] = req + if not reqs_to_uninstall: + raise InstallationError( + 'You must give at least one requirement to {self.name} (see ' + '"pip help {self.name}")'.format(**locals()) + ) + + protect_pip_from_modification_on_windows( + modifying_pip="pip" in reqs_to_uninstall + ) + + for req in reqs_to_uninstall.values(): + uninstall_pathset = req.uninstall( + auto_confirm=options.yes, verbose=self.verbosity > 0, + ) + if uninstall_pathset: + uninstall_pathset.commit() + + return SUCCESS diff --git a/venv/Lib/site-packages/pip/_internal/commands/wheel.py b/venv/Lib/site-packages/pip/_internal/commands/wheel.py new file mode 100644 index 0000000..28918fa --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/commands/wheel.py @@ -0,0 +1,194 @@ +import logging +import os +import shutil + +from pip._internal.cache import WheelCache +from pip._internal.cli import cmdoptions +from pip._internal.cli.req_command import RequirementCommand, with_cleanup +from pip._internal.cli.status_codes import SUCCESS +from pip._internal.exceptions import CommandError +from pip._internal.req.req_tracker import get_requirement_tracker +from pip._internal.utils.misc import ensure_dir, normalize_path +from pip._internal.utils.temp_dir import TempDirectory +from pip._internal.utils.typing import MYPY_CHECK_RUNNING +from pip._internal.wheel_builder import build, should_build_for_wheel_command + +if MYPY_CHECK_RUNNING: + from optparse import Values + from typing import List + + from pip._internal.req.req_install import InstallRequirement + +logger = logging.getLogger(__name__) + + +class WheelCommand(RequirementCommand): + """ + Build Wheel archives for your requirements and dependencies. + + Wheel is a built-package format, and offers the advantage of not + recompiling your software during every install. For more details, see the + wheel docs: https://wheel.readthedocs.io/en/latest/ + + Requirements: setuptools>=0.8, and wheel. + + 'pip wheel' uses the bdist_wheel setuptools extension from the wheel + package to build individual wheels. + + """ + + usage = """ + %prog [options] ... + %prog [options] -r ... + %prog [options] [-e] ... + %prog [options] [-e] ... + %prog [options] ...""" + + def add_options(self): + # type: () -> None + + self.cmd_opts.add_option( + '-w', '--wheel-dir', + dest='wheel_dir', + metavar='dir', + default=os.curdir, + help=("Build wheels into , where the default is the " + "current working directory."), + ) + self.cmd_opts.add_option(cmdoptions.no_binary()) + self.cmd_opts.add_option(cmdoptions.only_binary()) + self.cmd_opts.add_option(cmdoptions.prefer_binary()) + self.cmd_opts.add_option( + '--build-option', + dest='build_options', + metavar='options', + action='append', + help="Extra arguments to be supplied to 'setup.py bdist_wheel'.", + ) + self.cmd_opts.add_option(cmdoptions.no_build_isolation()) + self.cmd_opts.add_option(cmdoptions.use_pep517()) + self.cmd_opts.add_option(cmdoptions.no_use_pep517()) + self.cmd_opts.add_option(cmdoptions.constraints()) + self.cmd_opts.add_option(cmdoptions.editable()) + self.cmd_opts.add_option(cmdoptions.requirements()) + self.cmd_opts.add_option(cmdoptions.src()) + self.cmd_opts.add_option(cmdoptions.ignore_requires_python()) + self.cmd_opts.add_option(cmdoptions.no_deps()) + self.cmd_opts.add_option(cmdoptions.build_dir()) + self.cmd_opts.add_option(cmdoptions.progress_bar()) + + self.cmd_opts.add_option( + '--no-verify', + dest='no_verify', + action='store_true', + default=False, + help="Don't verify if built wheel is valid.", + ) + + self.cmd_opts.add_option( + '--global-option', + dest='global_options', + action='append', + metavar='options', + help="Extra global options to be supplied to the setup.py " + "call before the 'bdist_wheel' command.") + + self.cmd_opts.add_option( + '--pre', + action='store_true', + default=False, + help=("Include pre-release and development versions. By default, " + "pip only finds stable versions."), + ) + + self.cmd_opts.add_option(cmdoptions.require_hashes()) + + index_opts = cmdoptions.make_option_group( + cmdoptions.index_group, + self.parser, + ) + + self.parser.insert_option_group(0, index_opts) + self.parser.insert_option_group(0, self.cmd_opts) + + @with_cleanup + def run(self, options, args): + # type: (Values, List[str]) -> int + cmdoptions.check_install_build_global(options) + + session = self.get_default_session(options) + + finder = self._build_package_finder(options, session) + wheel_cache = WheelCache(options.cache_dir, options.format_control) + + options.wheel_dir = normalize_path(options.wheel_dir) + ensure_dir(options.wheel_dir) + + req_tracker = self.enter_context(get_requirement_tracker()) + + directory = TempDirectory( + delete=not options.no_clean, + kind="wheel", + globally_managed=True, + ) + + reqs = self.get_requirements(args, options, finder, session) + + preparer = self.make_requirement_preparer( + temp_build_dir=directory, + options=options, + req_tracker=req_tracker, + session=session, + finder=finder, + download_dir=options.wheel_dir, + use_user_site=False, + ) + + resolver = self.make_resolver( + preparer=preparer, + finder=finder, + options=options, + wheel_cache=wheel_cache, + ignore_requires_python=options.ignore_requires_python, + use_pep517=options.use_pep517, + ) + + self.trace_basic_info(finder) + + requirement_set = resolver.resolve( + reqs, check_supported_wheels=True + ) + + reqs_to_build = [] # type: List[InstallRequirement] + for req in requirement_set.requirements.values(): + if req.is_wheel: + preparer.save_linked_requirement(req) + elif should_build_for_wheel_command(req): + reqs_to_build.append(req) + + # build wheels + build_successes, build_failures = build( + reqs_to_build, + wheel_cache=wheel_cache, + verify=(not options.no_verify), + build_options=options.build_options or [], + global_options=options.global_options or [], + ) + for req in build_successes: + assert req.link and req.link.is_wheel + assert req.local_file_path + # copy from cache to target directory + try: + shutil.copy(req.local_file_path, options.wheel_dir) + except OSError as e: + logger.warning( + "Building wheel for %s failed: %s", + req.name, e, + ) + build_failures.append(req) + if len(build_failures) != 0: + raise CommandError( + "Failed to build one or more wheels" + ) + + return SUCCESS diff --git a/venv/Lib/site-packages/pip/_internal/configuration.py b/venv/Lib/site-packages/pip/_internal/configuration.py new file mode 100644 index 0000000..9d9a36e --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/configuration.py @@ -0,0 +1,406 @@ +"""Configuration management setup + +Some terminology: +- name + As written in config files. +- value + Value associated with a name +- key + Name combined with it's section (section.name) +- variant + A single word describing where the configuration key-value pair came from +""" + +import configparser +import locale +import logging +import os +import sys + +from pip._internal.exceptions import ( + ConfigurationError, + ConfigurationFileCouldNotBeLoaded, +) +from pip._internal.utils import appdirs +from pip._internal.utils.compat import WINDOWS +from pip._internal.utils.misc import ensure_dir, enum +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import Any, Dict, Iterable, List, NewType, Optional, Tuple + + RawConfigParser = configparser.RawConfigParser # Shorthand + Kind = NewType("Kind", str) + +CONFIG_BASENAME = 'pip.ini' if WINDOWS else 'pip.conf' +ENV_NAMES_IGNORED = "version", "help" + +# The kinds of configurations there are. +kinds = enum( + USER="user", # User Specific + GLOBAL="global", # System Wide + SITE="site", # [Virtual] Environment Specific + ENV="env", # from PIP_CONFIG_FILE + ENV_VAR="env-var", # from Environment Variables +) +OVERRIDE_ORDER = kinds.GLOBAL, kinds.USER, kinds.SITE, kinds.ENV, kinds.ENV_VAR +VALID_LOAD_ONLY = kinds.USER, kinds.GLOBAL, kinds.SITE + +logger = logging.getLogger(__name__) + + +# NOTE: Maybe use the optionx attribute to normalize keynames. +def _normalize_name(name): + # type: (str) -> str + """Make a name consistent regardless of source (environment or file) + """ + name = name.lower().replace('_', '-') + if name.startswith('--'): + name = name[2:] # only prefer long opts + return name + + +def _disassemble_key(name): + # type: (str) -> List[str] + if "." not in name: + error_message = ( + "Key does not contain dot separated section and key. " + "Perhaps you wanted to use 'global.{}' instead?" + ).format(name) + raise ConfigurationError(error_message) + return name.split(".", 1) + + +def get_configuration_files(): + # type: () -> Dict[Kind, List[str]] + global_config_files = [ + os.path.join(path, CONFIG_BASENAME) + for path in appdirs.site_config_dirs('pip') + ] + + site_config_file = os.path.join(sys.prefix, CONFIG_BASENAME) + legacy_config_file = os.path.join( + os.path.expanduser('~'), + 'pip' if WINDOWS else '.pip', + CONFIG_BASENAME, + ) + new_config_file = os.path.join( + appdirs.user_config_dir("pip"), CONFIG_BASENAME + ) + return { + kinds.GLOBAL: global_config_files, + kinds.SITE: [site_config_file], + kinds.USER: [legacy_config_file, new_config_file], + } + + +class Configuration: + """Handles management of configuration. + + Provides an interface to accessing and managing configuration files. + + This class converts provides an API that takes "section.key-name" style + keys and stores the value associated with it as "key-name" under the + section "section". + + This allows for a clean interface wherein the both the section and the + key-name are preserved in an easy to manage form in the configuration files + and the data stored is also nice. + """ + + def __init__(self, isolated, load_only=None): + # type: (bool, Optional[Kind]) -> None + super().__init__() + + if load_only is not None and load_only not in VALID_LOAD_ONLY: + raise ConfigurationError( + "Got invalid value for load_only - should be one of {}".format( + ", ".join(map(repr, VALID_LOAD_ONLY)) + ) + ) + self.isolated = isolated + self.load_only = load_only + + # Because we keep track of where we got the data from + self._parsers = { + variant: [] for variant in OVERRIDE_ORDER + } # type: Dict[Kind, List[Tuple[str, RawConfigParser]]] + self._config = { + variant: {} for variant in OVERRIDE_ORDER + } # type: Dict[Kind, Dict[str, Any]] + self._modified_parsers = [] # type: List[Tuple[str, RawConfigParser]] + + def load(self): + # type: () -> None + """Loads configuration from configuration files and environment + """ + self._load_config_files() + if not self.isolated: + self._load_environment_vars() + + def get_file_to_edit(self): + # type: () -> Optional[str] + """Returns the file with highest priority in configuration + """ + assert self.load_only is not None, \ + "Need to be specified a file to be editing" + + try: + return self._get_parser_to_modify()[0] + except IndexError: + return None + + def items(self): + # type: () -> Iterable[Tuple[str, Any]] + """Returns key-value pairs like dict.items() representing the loaded + configuration + """ + return self._dictionary.items() + + def get_value(self, key): + # type: (str) -> Any + """Get a value from the configuration. + """ + try: + return self._dictionary[key] + except KeyError: + raise ConfigurationError(f"No such key - {key}") + + def set_value(self, key, value): + # type: (str, Any) -> None + """Modify a value in the configuration. + """ + self._ensure_have_load_only() + + assert self.load_only + fname, parser = self._get_parser_to_modify() + + if parser is not None: + section, name = _disassemble_key(key) + + # Modify the parser and the configuration + if not parser.has_section(section): + parser.add_section(section) + parser.set(section, name, value) + + self._config[self.load_only][key] = value + self._mark_as_modified(fname, parser) + + def unset_value(self, key): + # type: (str) -> None + """Unset a value in the configuration.""" + self._ensure_have_load_only() + + assert self.load_only + if key not in self._config[self.load_only]: + raise ConfigurationError(f"No such key - {key}") + + fname, parser = self._get_parser_to_modify() + + if parser is not None: + section, name = _disassemble_key(key) + if not (parser.has_section(section) + and parser.remove_option(section, name)): + # The option was not removed. + raise ConfigurationError( + "Fatal Internal error [id=1]. Please report as a bug." + ) + + # The section may be empty after the option was removed. + if not parser.items(section): + parser.remove_section(section) + self._mark_as_modified(fname, parser) + + del self._config[self.load_only][key] + + def save(self): + # type: () -> None + """Save the current in-memory state. + """ + self._ensure_have_load_only() + + for fname, parser in self._modified_parsers: + logger.info("Writing to %s", fname) + + # Ensure directory exists. + ensure_dir(os.path.dirname(fname)) + + with open(fname, "w") as f: + parser.write(f) + + # + # Private routines + # + + def _ensure_have_load_only(self): + # type: () -> None + if self.load_only is None: + raise ConfigurationError("Needed a specific file to be modifying.") + logger.debug("Will be working with %s variant only", self.load_only) + + @property + def _dictionary(self): + # type: () -> Dict[str, Any] + """A dictionary representing the loaded configuration. + """ + # NOTE: Dictionaries are not populated if not loaded. So, conditionals + # are not needed here. + retval = {} + + for variant in OVERRIDE_ORDER: + retval.update(self._config[variant]) + + return retval + + def _load_config_files(self): + # type: () -> None + """Loads configuration from configuration files + """ + config_files = dict(self.iter_config_files()) + if config_files[kinds.ENV][0:1] == [os.devnull]: + logger.debug( + "Skipping loading configuration files due to " + "environment's PIP_CONFIG_FILE being os.devnull" + ) + return + + for variant, files in config_files.items(): + for fname in files: + # If there's specific variant set in `load_only`, load only + # that variant, not the others. + if self.load_only is not None and variant != self.load_only: + logger.debug( + "Skipping file '%s' (variant: %s)", fname, variant + ) + continue + + parser = self._load_file(variant, fname) + + # Keeping track of the parsers used + self._parsers[variant].append((fname, parser)) + + def _load_file(self, variant, fname): + # type: (Kind, str) -> RawConfigParser + logger.debug("For variant '%s', will try loading '%s'", variant, fname) + parser = self._construct_parser(fname) + + for section in parser.sections(): + items = parser.items(section) + self._config[variant].update(self._normalized_keys(section, items)) + + return parser + + def _construct_parser(self, fname): + # type: (str) -> RawConfigParser + parser = configparser.RawConfigParser() + # If there is no such file, don't bother reading it but create the + # parser anyway, to hold the data. + # Doing this is useful when modifying and saving files, where we don't + # need to construct a parser. + if os.path.exists(fname): + try: + parser.read(fname) + except UnicodeDecodeError: + # See https://github.com/pypa/pip/issues/4963 + raise ConfigurationFileCouldNotBeLoaded( + reason="contains invalid {} characters".format( + locale.getpreferredencoding(False) + ), + fname=fname, + ) + except configparser.Error as error: + # See https://github.com/pypa/pip/issues/4893 + raise ConfigurationFileCouldNotBeLoaded(error=error) + return parser + + def _load_environment_vars(self): + # type: () -> None + """Loads configuration from environment variables + """ + self._config[kinds.ENV_VAR].update( + self._normalized_keys(":env:", self.get_environ_vars()) + ) + + def _normalized_keys(self, section, items): + # type: (str, Iterable[Tuple[str, Any]]) -> Dict[str, Any] + """Normalizes items to construct a dictionary with normalized keys. + + This routine is where the names become keys and are made the same + regardless of source - configuration files or environment. + """ + normalized = {} + for name, val in items: + key = section + "." + _normalize_name(name) + normalized[key] = val + return normalized + + def get_environ_vars(self): + # type: () -> Iterable[Tuple[str, str]] + """Returns a generator with all environmental vars with prefix PIP_""" + for key, val in os.environ.items(): + if key.startswith("PIP_"): + name = key[4:].lower() + if name not in ENV_NAMES_IGNORED: + yield name, val + + # XXX: This is patched in the tests. + def iter_config_files(self): + # type: () -> Iterable[Tuple[Kind, List[str]]] + """Yields variant and configuration files associated with it. + + This should be treated like items of a dictionary. + """ + # SMELL: Move the conditions out of this function + + # environment variables have the lowest priority + config_file = os.environ.get('PIP_CONFIG_FILE', None) + if config_file is not None: + yield kinds.ENV, [config_file] + else: + yield kinds.ENV, [] + + config_files = get_configuration_files() + + # at the base we have any global configuration + yield kinds.GLOBAL, config_files[kinds.GLOBAL] + + # per-user configuration next + should_load_user_config = not self.isolated and not ( + config_file and os.path.exists(config_file) + ) + if should_load_user_config: + # The legacy config file is overridden by the new config file + yield kinds.USER, config_files[kinds.USER] + + # finally virtualenv configuration first trumping others + yield kinds.SITE, config_files[kinds.SITE] + + def get_values_in_config(self, variant): + # type: (Kind) -> Dict[str, Any] + """Get values present in a config file""" + return self._config[variant] + + def _get_parser_to_modify(self): + # type: () -> Tuple[str, RawConfigParser] + # Determine which parser to modify + assert self.load_only + parsers = self._parsers[self.load_only] + if not parsers: + # This should not happen if everything works correctly. + raise ConfigurationError( + "Fatal Internal error [id=2]. Please report as a bug." + ) + + # Use the highest priority parser. + return parsers[-1] + + # XXX: This is patched in the tests. + def _mark_as_modified(self, fname, parser): + # type: (str, RawConfigParser) -> None + file_parser_tuple = (fname, parser) + if file_parser_tuple not in self._modified_parsers: + self._modified_parsers.append(file_parser_tuple) + + def __repr__(self): + # type: () -> str + return f"{self.__class__.__name__}({self._dictionary!r})" diff --git a/venv/Lib/site-packages/pip/_internal/distributions/__init__.py b/venv/Lib/site-packages/pip/_internal/distributions/__init__.py new file mode 100644 index 0000000..d5c1afc --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/distributions/__init__.py @@ -0,0 +1,24 @@ +from pip._internal.distributions.sdist import SourceDistribution +from pip._internal.distributions.wheel import WheelDistribution +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from pip._internal.distributions.base import AbstractDistribution + from pip._internal.req.req_install import InstallRequirement + + +def make_distribution_for_install_requirement(install_req): + # type: (InstallRequirement) -> AbstractDistribution + """Returns a Distribution for the given InstallRequirement + """ + # Editable requirements will always be source distributions. They use the + # legacy logic until we create a modern standard for them. + if install_req.editable: + return SourceDistribution(install_req) + + # If it's a wheel, it's a WheelDistribution + if install_req.is_wheel: + return WheelDistribution(install_req) + + # Otherwise, a SourceDistribution + return SourceDistribution(install_req) diff --git a/venv/Lib/site-packages/pip/_internal/distributions/base.py b/venv/Lib/site-packages/pip/_internal/distributions/base.py new file mode 100644 index 0000000..37db810 --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/distributions/base.py @@ -0,0 +1,42 @@ +import abc + +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import Optional + + from pip._vendor.pkg_resources import Distribution + + from pip._internal.index.package_finder import PackageFinder + from pip._internal.req import InstallRequirement + + +class AbstractDistribution(metaclass=abc.ABCMeta): + """A base class for handling installable artifacts. + + The requirements for anything installable are as follows: + + - we must be able to determine the requirement name + (or we can't correctly handle the non-upgrade case). + + - for packages with setup requirements, we must also be able + to determine their requirements without installing additional + packages (for the same reason as run-time dependencies) + + - we must be able to create a Distribution object exposing the + above metadata. + """ + def __init__(self, req): + # type: (InstallRequirement) -> None + super().__init__() + self.req = req + + @abc.abstractmethod + def get_pkg_resources_distribution(self): + # type: () -> Optional[Distribution] + raise NotImplementedError() + + @abc.abstractmethod + def prepare_distribution_metadata(self, finder, build_isolation): + # type: (PackageFinder, bool) -> None + raise NotImplementedError() diff --git a/venv/Lib/site-packages/pip/_internal/distributions/installed.py b/venv/Lib/site-packages/pip/_internal/distributions/installed.py new file mode 100644 index 0000000..a813b21 --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/distributions/installed.py @@ -0,0 +1,25 @@ +from pip._internal.distributions.base import AbstractDistribution +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import Optional + + from pip._vendor.pkg_resources import Distribution + + from pip._internal.index.package_finder import PackageFinder + + +class InstalledDistribution(AbstractDistribution): + """Represents an installed package. + + This does not need any preparation as the required information has already + been computed. + """ + + def get_pkg_resources_distribution(self): + # type: () -> Optional[Distribution] + return self.req.satisfied_by + + def prepare_distribution_metadata(self, finder, build_isolation): + # type: (PackageFinder, bool) -> None + pass diff --git a/venv/Lib/site-packages/pip/_internal/distributions/sdist.py b/venv/Lib/site-packages/pip/_internal/distributions/sdist.py new file mode 100644 index 0000000..9b708fd --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/distributions/sdist.py @@ -0,0 +1,105 @@ +import logging + +from pip._internal.build_env import BuildEnvironment +from pip._internal.distributions.base import AbstractDistribution +from pip._internal.exceptions import InstallationError +from pip._internal.utils.subprocess import runner_with_spinner_message +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import Set, Tuple + + from pip._vendor.pkg_resources import Distribution + + from pip._internal.index.package_finder import PackageFinder + + +logger = logging.getLogger(__name__) + + +class SourceDistribution(AbstractDistribution): + """Represents a source distribution. + + The preparation step for these needs metadata for the packages to be + generated, either using PEP 517 or using the legacy `setup.py egg_info`. + """ + + def get_pkg_resources_distribution(self): + # type: () -> Distribution + return self.req.get_dist() + + def prepare_distribution_metadata(self, finder, build_isolation): + # type: (PackageFinder, bool) -> None + # Load pyproject.toml, to determine whether PEP 517 is to be used + self.req.load_pyproject_toml() + + # Set up the build isolation, if this requirement should be isolated + should_isolate = self.req.use_pep517 and build_isolation + if should_isolate: + self._setup_isolation(finder) + + self.req.prepare_metadata() + + def _setup_isolation(self, finder): + # type: (PackageFinder) -> None + def _raise_conflicts(conflicting_with, conflicting_reqs): + # type: (str, Set[Tuple[str, str]]) -> None + format_string = ( + "Some build dependencies for {requirement} " + "conflict with {conflicting_with}: {description}." + ) + error_message = format_string.format( + requirement=self.req, + conflicting_with=conflicting_with, + description=', '.join( + f'{installed} is incompatible with {wanted}' + for installed, wanted in sorted(conflicting) + ) + ) + raise InstallationError(error_message) + + # Isolate in a BuildEnvironment and install the build-time + # requirements. + pyproject_requires = self.req.pyproject_requires + assert pyproject_requires is not None + + self.req.build_env = BuildEnvironment() + self.req.build_env.install_requirements( + finder, pyproject_requires, 'overlay', + "Installing build dependencies" + ) + conflicting, missing = self.req.build_env.check_requirements( + self.req.requirements_to_check + ) + if conflicting: + _raise_conflicts("PEP 517/518 supported requirements", + conflicting) + if missing: + logger.warning( + "Missing build requirements in pyproject.toml for %s.", + self.req, + ) + logger.warning( + "The project does not specify a build backend, and " + "pip cannot fall back to setuptools without %s.", + " and ".join(map(repr, sorted(missing))) + ) + # Install any extra build dependencies that the backend requests. + # This must be done in a second pass, as the pyproject.toml + # dependencies must be installed before we can call the backend. + with self.req.build_env: + runner = runner_with_spinner_message( + "Getting requirements to build wheel" + ) + backend = self.req.pep517_backend + assert backend is not None + with backend.subprocess_runner(runner): + reqs = backend.get_requires_for_build_wheel() + + conflicting, missing = self.req.build_env.check_requirements(reqs) + if conflicting: + _raise_conflicts("the backend dependencies", conflicting) + self.req.build_env.install_requirements( + finder, missing, 'normal', + "Installing backend dependencies" + ) diff --git a/venv/Lib/site-packages/pip/_internal/distributions/wheel.py b/venv/Lib/site-packages/pip/_internal/distributions/wheel.py new file mode 100644 index 0000000..2adc228 --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/distributions/wheel.py @@ -0,0 +1,37 @@ +from zipfile import ZipFile + +from pip._internal.distributions.base import AbstractDistribution +from pip._internal.utils.typing import MYPY_CHECK_RUNNING +from pip._internal.utils.wheel import pkg_resources_distribution_for_wheel + +if MYPY_CHECK_RUNNING: + from pip._vendor.pkg_resources import Distribution + + from pip._internal.index.package_finder import PackageFinder + + +class WheelDistribution(AbstractDistribution): + """Represents a wheel distribution. + + This does not need any preparation as wheels can be directly unpacked. + """ + + def get_pkg_resources_distribution(self): + # type: () -> Distribution + """Loads the metadata from the wheel file into memory and returns a + Distribution that uses it, not relying on the wheel file or + requirement. + """ + # Set as part of preparation during download. + assert self.req.local_file_path + # Wheels are never unnamed. + assert self.req.name + + with ZipFile(self.req.local_file_path, allowZip64=True) as z: + return pkg_resources_distribution_for_wheel( + z, self.req.name, self.req.local_file_path + ) + + def prepare_distribution_metadata(self, finder, build_isolation): + # type: (PackageFinder, bool) -> None + pass diff --git a/venv/Lib/site-packages/pip/_internal/exceptions.py b/venv/Lib/site-packages/pip/_internal/exceptions.py new file mode 100644 index 0000000..891f8c3 --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/exceptions.py @@ -0,0 +1,384 @@ +"""Exceptions used throughout package""" + +from itertools import chain, groupby, repeat + +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + import configparser + from hashlib import _Hash + from typing import Dict, List, Optional + + from pip._vendor.pkg_resources import Distribution + from pip._vendor.requests.models import Request, Response + + from pip._internal.req.req_install import InstallRequirement + + +class PipError(Exception): + """Base pip exception""" + + +class ConfigurationError(PipError): + """General exception in configuration""" + + +class InstallationError(PipError): + """General exception during installation""" + + +class UninstallationError(PipError): + """General exception during uninstallation""" + + +class NoneMetadataError(PipError): + """ + Raised when accessing "METADATA" or "PKG-INFO" metadata for a + pip._vendor.pkg_resources.Distribution object and + `dist.has_metadata('METADATA')` returns True but + `dist.get_metadata('METADATA')` returns None (and similarly for + "PKG-INFO"). + """ + + def __init__(self, dist, metadata_name): + # type: (Distribution, str) -> None + """ + :param dist: A Distribution object. + :param metadata_name: The name of the metadata being accessed + (can be "METADATA" or "PKG-INFO"). + """ + self.dist = dist + self.metadata_name = metadata_name + + def __str__(self): + # type: () -> str + # Use `dist` in the error message because its stringification + # includes more information, like the version and location. + return ( + 'None {} metadata found for distribution: {}'.format( + self.metadata_name, self.dist, + ) + ) + + +class DistributionNotFound(InstallationError): + """Raised when a distribution cannot be found to satisfy a requirement""" + + +class RequirementsFileParseError(InstallationError): + """Raised when a general error occurs parsing a requirements file line.""" + + +class BestVersionAlreadyInstalled(PipError): + """Raised when the most up-to-date version of a package is already + installed.""" + + +class BadCommand(PipError): + """Raised when virtualenv or a command is not found""" + + +class CommandError(PipError): + """Raised when there is an error in command-line arguments""" + + +class PreviousBuildDirError(PipError): + """Raised when there's a previous conflicting build directory""" + + +class NetworkConnectionError(PipError): + """HTTP connection error""" + + def __init__(self, error_msg, response=None, request=None): + # type: (str, Response, Request) -> None + """ + Initialize NetworkConnectionError with `request` and `response` + objects. + """ + self.response = response + self.request = request + self.error_msg = error_msg + if (self.response is not None and not self.request and + hasattr(response, 'request')): + self.request = self.response.request + super().__init__(error_msg, response, request) + + def __str__(self): + # type: () -> str + return str(self.error_msg) + + +class InvalidWheelFilename(InstallationError): + """Invalid wheel filename.""" + + +class UnsupportedWheel(InstallationError): + """Unsupported wheel.""" + + +class MetadataInconsistent(InstallationError): + """Built metadata contains inconsistent information. + + This is raised when the metadata contains values (e.g. name and version) + that do not match the information previously obtained from sdist filename + or user-supplied ``#egg=`` value. + """ + def __init__(self, ireq, field, f_val, m_val): + # type: (InstallRequirement, str, str, str) -> None + self.ireq = ireq + self.field = field + self.f_val = f_val + self.m_val = m_val + + def __str__(self): + # type: () -> str + template = ( + "Requested {} has inconsistent {}: " + "filename has {!r}, but metadata has {!r}" + ) + return template.format(self.ireq, self.field, self.f_val, self.m_val) + + +class InstallationSubprocessError(InstallationError): + """A subprocess call failed during installation.""" + def __init__(self, returncode, description): + # type: (int, str) -> None + self.returncode = returncode + self.description = description + + def __str__(self): + # type: () -> str + return ( + "Command errored out with exit status {}: {} " + "Check the logs for full command output." + ).format(self.returncode, self.description) + + +class HashErrors(InstallationError): + """Multiple HashError instances rolled into one for reporting""" + + def __init__(self): + # type: () -> None + self.errors = [] # type: List[HashError] + + def append(self, error): + # type: (HashError) -> None + self.errors.append(error) + + def __str__(self): + # type: () -> str + lines = [] + self.errors.sort(key=lambda e: e.order) + for cls, errors_of_cls in groupby(self.errors, lambda e: e.__class__): + lines.append(cls.head) + lines.extend(e.body() for e in errors_of_cls) + if lines: + return '\n'.join(lines) + return '' + + def __nonzero__(self): + # type: () -> bool + return bool(self.errors) + + def __bool__(self): + # type: () -> bool + return self.__nonzero__() + + +class HashError(InstallationError): + """ + A failure to verify a package against known-good hashes + + :cvar order: An int sorting hash exception classes by difficulty of + recovery (lower being harder), so the user doesn't bother fretting + about unpinned packages when he has deeper issues, like VCS + dependencies, to deal with. Also keeps error reports in a + deterministic order. + :cvar head: A section heading for display above potentially many + exceptions of this kind + :ivar req: The InstallRequirement that triggered this error. This is + pasted on after the exception is instantiated, because it's not + typically available earlier. + + """ + req = None # type: Optional[InstallRequirement] + head = '' + order = -1 # type: int + + def body(self): + # type: () -> str + """Return a summary of me for display under the heading. + + This default implementation simply prints a description of the + triggering requirement. + + :param req: The InstallRequirement that provoked this error, with + its link already populated by the resolver's _populate_link(). + + """ + return f' {self._requirement_name()}' + + def __str__(self): + # type: () -> str + return f'{self.head}\n{self.body()}' + + def _requirement_name(self): + # type: () -> str + """Return a description of the requirement that triggered me. + + This default implementation returns long description of the req, with + line numbers + + """ + return str(self.req) if self.req else 'unknown package' + + +class VcsHashUnsupported(HashError): + """A hash was provided for a version-control-system-based requirement, but + we don't have a method for hashing those.""" + + order = 0 + head = ("Can't verify hashes for these requirements because we don't " + "have a way to hash version control repositories:") + + +class DirectoryUrlHashUnsupported(HashError): + """A hash was provided for a version-control-system-based requirement, but + we don't have a method for hashing those.""" + + order = 1 + head = ("Can't verify hashes for these file:// requirements because they " + "point to directories:") + + +class HashMissing(HashError): + """A hash was needed for a requirement but is absent.""" + + order = 2 + head = ('Hashes are required in --require-hashes mode, but they are ' + 'missing from some requirements. Here is a list of those ' + 'requirements along with the hashes their downloaded archives ' + 'actually had. Add lines like these to your requirements files to ' + 'prevent tampering. (If you did not enable --require-hashes ' + 'manually, note that it turns on automatically when any package ' + 'has a hash.)') + + def __init__(self, gotten_hash): + # type: (str) -> None + """ + :param gotten_hash: The hash of the (possibly malicious) archive we + just downloaded + """ + self.gotten_hash = gotten_hash + + def body(self): + # type: () -> str + # Dodge circular import. + from pip._internal.utils.hashes import FAVORITE_HASH + + package = None + if self.req: + # In the case of URL-based requirements, display the original URL + # seen in the requirements file rather than the package name, + # so the output can be directly copied into the requirements file. + package = (self.req.original_link if self.req.original_link + # In case someone feeds something downright stupid + # to InstallRequirement's constructor. + else getattr(self.req, 'req', None)) + return ' {} --hash={}:{}'.format(package or 'unknown package', + FAVORITE_HASH, + self.gotten_hash) + + +class HashUnpinned(HashError): + """A requirement had a hash specified but was not pinned to a specific + version.""" + + order = 3 + head = ('In --require-hashes mode, all requirements must have their ' + 'versions pinned with ==. These do not:') + + +class HashMismatch(HashError): + """ + Distribution file hash values don't match. + + :ivar package_name: The name of the package that triggered the hash + mismatch. Feel free to write to this after the exception is raise to + improve its error message. + + """ + order = 4 + head = ('THESE PACKAGES DO NOT MATCH THE HASHES FROM THE REQUIREMENTS ' + 'FILE. If you have updated the package versions, please update ' + 'the hashes. Otherwise, examine the package contents carefully; ' + 'someone may have tampered with them.') + + def __init__(self, allowed, gots): + # type: (Dict[str, List[str]], Dict[str, _Hash]) -> None + """ + :param allowed: A dict of algorithm names pointing to lists of allowed + hex digests + :param gots: A dict of algorithm names pointing to hashes we + actually got from the files under suspicion + """ + self.allowed = allowed + self.gots = gots + + def body(self): + # type: () -> str + return ' {}:\n{}'.format(self._requirement_name(), + self._hash_comparison()) + + def _hash_comparison(self): + # type: () -> str + """ + Return a comparison of actual and expected hash values. + + Example:: + + Expected sha256 abcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcde + or 123451234512345123451234512345123451234512345 + Got bcdefbcdefbcdefbcdefbcdefbcdefbcdefbcdefbcdef + + """ + def hash_then_or(hash_name): + # type: (str) -> chain[str] + # For now, all the decent hashes have 6-char names, so we can get + # away with hard-coding space literals. + return chain([hash_name], repeat(' or')) + + lines = [] # type: List[str] + for hash_name, expecteds in self.allowed.items(): + prefix = hash_then_or(hash_name) + lines.extend((' Expected {} {}'.format(next(prefix), e)) + for e in expecteds) + lines.append(' Got {}\n'.format( + self.gots[hash_name].hexdigest())) + return '\n'.join(lines) + + +class UnsupportedPythonVersion(InstallationError): + """Unsupported python version according to Requires-Python package + metadata.""" + + +class ConfigurationFileCouldNotBeLoaded(ConfigurationError): + """When there are errors while loading a configuration file + """ + + def __init__(self, reason="could not be loaded", fname=None, error=None): + # type: (str, Optional[str], Optional[configparser.Error]) -> None + super().__init__(error) + self.reason = reason + self.fname = fname + self.error = error + + def __str__(self): + # type: () -> str + if self.fname is not None: + message_part = f" in {self.fname}." + else: + assert self.error is not None + message_part = f".\n{self.error}\n" + return f"Configuration file {self.reason}{message_part}" diff --git a/venv/Lib/site-packages/pip/_internal/index/__init__.py b/venv/Lib/site-packages/pip/_internal/index/__init__.py new file mode 100644 index 0000000..7a17b7b --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/index/__init__.py @@ -0,0 +1,2 @@ +"""Index interaction code +""" diff --git a/venv/Lib/site-packages/pip/_internal/index/collector.py b/venv/Lib/site-packages/pip/_internal/index/collector.py new file mode 100644 index 0000000..ee4eb71 --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/index/collector.py @@ -0,0 +1,666 @@ +""" +The main purpose of this module is to expose LinkCollector.collect_links(). +""" + +import cgi +import functools +import itertools +import logging +import mimetypes +import os +import re +import urllib.parse +import urllib.request +from collections import OrderedDict + +from pip._vendor import html5lib, requests +from pip._vendor.distlib.compat import unescape +from pip._vendor.requests.exceptions import RetryError, SSLError + +from pip._internal.exceptions import NetworkConnectionError +from pip._internal.models.link import Link +from pip._internal.models.search_scope import SearchScope +from pip._internal.network.utils import raise_for_status +from pip._internal.utils.filetypes import is_archive_file +from pip._internal.utils.misc import pairwise, redact_auth_from_url +from pip._internal.utils.typing import MYPY_CHECK_RUNNING +from pip._internal.utils.urls import path_to_url, url_to_path +from pip._internal.vcs import is_url, vcs + +if MYPY_CHECK_RUNNING: + import xml.etree.ElementTree + from optparse import Values + from typing import ( + Callable, + Iterable, + List, + MutableMapping, + Optional, + Sequence, + Tuple, + Union, + ) + + from pip._vendor.requests import Response + + from pip._internal.network.session import PipSession + + HTMLElement = xml.etree.ElementTree.Element + ResponseHeaders = MutableMapping[str, str] + + +logger = logging.getLogger(__name__) + + +def _match_vcs_scheme(url): + # type: (str) -> Optional[str] + """Look for VCS schemes in the URL. + + Returns the matched VCS scheme, or None if there's no match. + """ + for scheme in vcs.schemes: + if url.lower().startswith(scheme) and url[len(scheme)] in '+:': + return scheme + return None + + +class _NotHTML(Exception): + def __init__(self, content_type, request_desc): + # type: (str, str) -> None + super().__init__(content_type, request_desc) + self.content_type = content_type + self.request_desc = request_desc + + +def _ensure_html_header(response): + # type: (Response) -> None + """Check the Content-Type header to ensure the response contains HTML. + + Raises `_NotHTML` if the content type is not text/html. + """ + content_type = response.headers.get("Content-Type", "") + if not content_type.lower().startswith("text/html"): + raise _NotHTML(content_type, response.request.method) + + +class _NotHTTP(Exception): + pass + + +def _ensure_html_response(url, session): + # type: (str, PipSession) -> None + """Send a HEAD request to the URL, and ensure the response contains HTML. + + Raises `_NotHTTP` if the URL is not available for a HEAD request, or + `_NotHTML` if the content type is not text/html. + """ + scheme, netloc, path, query, fragment = urllib.parse.urlsplit(url) + if scheme not in {'http', 'https'}: + raise _NotHTTP() + + resp = session.head(url, allow_redirects=True) + raise_for_status(resp) + + _ensure_html_header(resp) + + +def _get_html_response(url, session): + # type: (str, PipSession) -> Response + """Access an HTML page with GET, and return the response. + + This consists of three parts: + + 1. If the URL looks suspiciously like an archive, send a HEAD first to + check the Content-Type is HTML, to avoid downloading a large file. + Raise `_NotHTTP` if the content type cannot be determined, or + `_NotHTML` if it is not HTML. + 2. Actually perform the request. Raise HTTP exceptions on network failures. + 3. Check the Content-Type header to make sure we got HTML, and raise + `_NotHTML` otherwise. + """ + if is_archive_file(Link(url).filename): + _ensure_html_response(url, session=session) + + logger.debug('Getting page %s', redact_auth_from_url(url)) + + resp = session.get( + url, + headers={ + "Accept": "text/html", + # We don't want to blindly returned cached data for + # /simple/, because authors generally expecting that + # twine upload && pip install will function, but if + # they've done a pip install in the last ~10 minutes + # it won't. Thus by setting this to zero we will not + # blindly use any cached data, however the benefit of + # using max-age=0 instead of no-cache, is that we will + # still support conditional requests, so we will still + # minimize traffic sent in cases where the page hasn't + # changed at all, we will just always incur the round + # trip for the conditional GET now instead of only + # once per 10 minutes. + # For more information, please see pypa/pip#5670. + "Cache-Control": "max-age=0", + }, + ) + raise_for_status(resp) + + # The check for archives above only works if the url ends with + # something that looks like an archive. However that is not a + # requirement of an url. Unless we issue a HEAD request on every + # url we cannot know ahead of time for sure if something is HTML + # or not. However we can check after we've downloaded it. + _ensure_html_header(resp) + + return resp + + +def _get_encoding_from_headers(headers): + # type: (ResponseHeaders) -> Optional[str] + """Determine if we have any encoding information in our headers. + """ + if headers and "Content-Type" in headers: + content_type, params = cgi.parse_header(headers["Content-Type"]) + if "charset" in params: + return params['charset'] + return None + + +def _determine_base_url(document, page_url): + # type: (HTMLElement, str) -> str + """Determine the HTML document's base URL. + + This looks for a ```` tag in the HTML document. If present, its href + attribute denotes the base URL of anchor tags in the document. If there is + no such tag (or if it does not have a valid href attribute), the HTML + file's URL is used as the base URL. + + :param document: An HTML document representation. The current + implementation expects the result of ``html5lib.parse()``. + :param page_url: The URL of the HTML document. + """ + for base in document.findall(".//base"): + href = base.get("href") + if href is not None: + return href + return page_url + + +def _clean_url_path_part(part): + # type: (str) -> str + """ + Clean a "part" of a URL path (i.e. after splitting on "@" characters). + """ + # We unquote prior to quoting to make sure nothing is double quoted. + return urllib.parse.quote(urllib.parse.unquote(part)) + + +def _clean_file_url_path(part): + # type: (str) -> str + """ + Clean the first part of a URL path that corresponds to a local + filesystem path (i.e. the first part after splitting on "@" characters). + """ + # We unquote prior to quoting to make sure nothing is double quoted. + # Also, on Windows the path part might contain a drive letter which + # should not be quoted. On Linux where drive letters do not + # exist, the colon should be quoted. We rely on urllib.request + # to do the right thing here. + return urllib.request.pathname2url(urllib.request.url2pathname(part)) + + +# percent-encoded: / +_reserved_chars_re = re.compile('(@|%2F)', re.IGNORECASE) + + +def _clean_url_path(path, is_local_path): + # type: (str, bool) -> str + """ + Clean the path portion of a URL. + """ + if is_local_path: + clean_func = _clean_file_url_path + else: + clean_func = _clean_url_path_part + + # Split on the reserved characters prior to cleaning so that + # revision strings in VCS URLs are properly preserved. + parts = _reserved_chars_re.split(path) + + cleaned_parts = [] + for to_clean, reserved in pairwise(itertools.chain(parts, [''])): + cleaned_parts.append(clean_func(to_clean)) + # Normalize %xx escapes (e.g. %2f -> %2F) + cleaned_parts.append(reserved.upper()) + + return ''.join(cleaned_parts) + + +def _clean_link(url): + # type: (str) -> str + """ + Make sure a link is fully quoted. + For example, if ' ' occurs in the URL, it will be replaced with "%20", + and without double-quoting other characters. + """ + # Split the URL into parts according to the general structure + # `scheme://netloc/path;parameters?query#fragment`. + result = urllib.parse.urlparse(url) + # If the netloc is empty, then the URL refers to a local filesystem path. + is_local_path = not result.netloc + path = _clean_url_path(result.path, is_local_path=is_local_path) + return urllib.parse.urlunparse(result._replace(path=path)) + + +def _create_link_from_element( + anchor, # type: HTMLElement + page_url, # type: str + base_url, # type: str +): + # type: (...) -> Optional[Link] + """ + Convert an anchor element in a simple repository page to a Link. + """ + href = anchor.get("href") + if not href: + return None + + url = _clean_link(urllib.parse.urljoin(base_url, href)) + pyrequire = anchor.get('data-requires-python') + pyrequire = unescape(pyrequire) if pyrequire else None + + yanked_reason = anchor.get('data-yanked') + if yanked_reason: + # This is a unicode string in Python 2 (and 3). + yanked_reason = unescape(yanked_reason) + + link = Link( + url, + comes_from=page_url, + requires_python=pyrequire, + yanked_reason=yanked_reason, + ) + + return link + + +class CacheablePageContent: + def __init__(self, page): + # type: (HTMLPage) -> None + assert page.cache_link_parsing + self.page = page + + def __eq__(self, other): + # type: (object) -> bool + return (isinstance(other, type(self)) and + self.page.url == other.page.url) + + def __hash__(self): + # type: () -> int + return hash(self.page.url) + + +def with_cached_html_pages( + fn, # type: Callable[[HTMLPage], Iterable[Link]] +): + # type: (...) -> Callable[[HTMLPage], List[Link]] + """ + Given a function that parses an Iterable[Link] from an HTMLPage, cache the + function's result (keyed by CacheablePageContent), unless the HTMLPage + `page` has `page.cache_link_parsing == False`. + """ + + @functools.lru_cache(maxsize=None) + def wrapper(cacheable_page): + # type: (CacheablePageContent) -> List[Link] + return list(fn(cacheable_page.page)) + + @functools.wraps(fn) + def wrapper_wrapper(page): + # type: (HTMLPage) -> List[Link] + if page.cache_link_parsing: + return wrapper(CacheablePageContent(page)) + return list(fn(page)) + + return wrapper_wrapper + + +@with_cached_html_pages +def parse_links(page): + # type: (HTMLPage) -> Iterable[Link] + """ + Parse an HTML document, and yield its anchor elements as Link objects. + """ + document = html5lib.parse( + page.content, + transport_encoding=page.encoding, + namespaceHTMLElements=False, + ) + + url = page.url + base_url = _determine_base_url(document, url) + for anchor in document.findall(".//a"): + link = _create_link_from_element( + anchor, + page_url=url, + base_url=base_url, + ) + if link is None: + continue + yield link + + +class HTMLPage: + """Represents one page, along with its URL""" + + def __init__( + self, + content, # type: bytes + encoding, # type: Optional[str] + url, # type: str + cache_link_parsing=True, # type: bool + ): + # type: (...) -> None + """ + :param encoding: the encoding to decode the given content. + :param url: the URL from which the HTML was downloaded. + :param cache_link_parsing: whether links parsed from this page's url + should be cached. PyPI index urls should + have this set to False, for example. + """ + self.content = content + self.encoding = encoding + self.url = url + self.cache_link_parsing = cache_link_parsing + + def __str__(self): + # type: () -> str + return redact_auth_from_url(self.url) + + +def _handle_get_page_fail( + link, # type: Link + reason, # type: Union[str, Exception] + meth=None # type: Optional[Callable[..., None]] +): + # type: (...) -> None + if meth is None: + meth = logger.debug + meth("Could not fetch URL %s: %s - skipping", link, reason) + + +def _make_html_page(response, cache_link_parsing=True): + # type: (Response, bool) -> HTMLPage + encoding = _get_encoding_from_headers(response.headers) + return HTMLPage( + response.content, + encoding=encoding, + url=response.url, + cache_link_parsing=cache_link_parsing) + + +def _get_html_page(link, session=None): + # type: (Link, Optional[PipSession]) -> Optional[HTMLPage] + if session is None: + raise TypeError( + "_get_html_page() missing 1 required keyword argument: 'session'" + ) + + url = link.url.split('#', 1)[0] + + # Check for VCS schemes that do not support lookup as web pages. + vcs_scheme = _match_vcs_scheme(url) + if vcs_scheme: + logger.warning('Cannot look at %s URL %s because it does not support ' + 'lookup as web pages.', vcs_scheme, link) + return None + + # Tack index.html onto file:// URLs that point to directories + scheme, _, path, _, _, _ = urllib.parse.urlparse(url) + if (scheme == 'file' and os.path.isdir(urllib.request.url2pathname(path))): + # add trailing slash if not present so urljoin doesn't trim + # final segment + if not url.endswith('/'): + url += '/' + url = urllib.parse.urljoin(url, 'index.html') + logger.debug(' file: URL is directory, getting %s', url) + + try: + resp = _get_html_response(url, session=session) + except _NotHTTP: + logger.warning( + 'Skipping page %s because it looks like an archive, and cannot ' + 'be checked by a HTTP HEAD request.', link, + ) + except _NotHTML as exc: + logger.warning( + 'Skipping page %s because the %s request got Content-Type: %s.' + 'The only supported Content-Type is text/html', + link, exc.request_desc, exc.content_type, + ) + except NetworkConnectionError as exc: + _handle_get_page_fail(link, exc) + except RetryError as exc: + _handle_get_page_fail(link, exc) + except SSLError as exc: + reason = "There was a problem confirming the ssl certificate: " + reason += str(exc) + _handle_get_page_fail(link, reason, meth=logger.info) + except requests.ConnectionError as exc: + _handle_get_page_fail(link, f"connection error: {exc}") + except requests.Timeout: + _handle_get_page_fail(link, "timed out") + else: + return _make_html_page(resp, + cache_link_parsing=link.cache_link_parsing) + return None + + +def _remove_duplicate_links(links): + # type: (Iterable[Link]) -> List[Link] + """ + Return a list of links, with duplicates removed and ordering preserved. + """ + # We preserve the ordering when removing duplicates because we can. + return list(OrderedDict.fromkeys(links)) + + +def group_locations(locations, expand_dir=False): + # type: (Sequence[str], bool) -> Tuple[List[str], List[str]] + """ + Divide a list of locations into two groups: "files" (archives) and "urls." + + :return: A pair of lists (files, urls). + """ + files = [] + urls = [] + + # puts the url for the given file path into the appropriate list + def sort_path(path): + # type: (str) -> None + url = path_to_url(path) + if mimetypes.guess_type(url, strict=False)[0] == 'text/html': + urls.append(url) + else: + files.append(url) + + for url in locations: + + is_local_path = os.path.exists(url) + is_file_url = url.startswith('file:') + + if is_local_path or is_file_url: + if is_local_path: + path = url + else: + path = url_to_path(url) + if os.path.isdir(path): + if expand_dir: + path = os.path.realpath(path) + for item in os.listdir(path): + sort_path(os.path.join(path, item)) + elif is_file_url: + urls.append(url) + else: + logger.warning( + "Path '%s' is ignored: it is a directory.", path, + ) + elif os.path.isfile(path): + sort_path(path) + else: + logger.warning( + "Url '%s' is ignored: it is neither a file " + "nor a directory.", url, + ) + elif is_url(url): + # Only add url with clear scheme + urls.append(url) + else: + logger.warning( + "Url '%s' is ignored. It is either a non-existing " + "path or lacks a specific scheme.", url, + ) + + return files, urls + + +class CollectedLinks: + + """ + Encapsulates the return value of a call to LinkCollector.collect_links(). + + The return value includes both URLs to project pages containing package + links, as well as individual package Link objects collected from other + sources. + + This info is stored separately as: + + (1) links from the configured file locations, + (2) links from the configured find_links, and + (3) urls to HTML project pages, as described by the PEP 503 simple + repository API. + """ + + def __init__( + self, + files, # type: List[Link] + find_links, # type: List[Link] + project_urls, # type: List[Link] + ): + # type: (...) -> None + """ + :param files: Links from file locations. + :param find_links: Links from find_links. + :param project_urls: URLs to HTML project pages, as described by + the PEP 503 simple repository API. + """ + self.files = files + self.find_links = find_links + self.project_urls = project_urls + + +class LinkCollector: + + """ + Responsible for collecting Link objects from all configured locations, + making network requests as needed. + + The class's main method is its collect_links() method. + """ + + def __init__( + self, + session, # type: PipSession + search_scope, # type: SearchScope + ): + # type: (...) -> None + self.search_scope = search_scope + self.session = session + + @classmethod + def create(cls, session, options, suppress_no_index=False): + # type: (PipSession, Values, bool) -> LinkCollector + """ + :param session: The Session to use to make requests. + :param suppress_no_index: Whether to ignore the --no-index option + when constructing the SearchScope object. + """ + index_urls = [options.index_url] + options.extra_index_urls + if options.no_index and not suppress_no_index: + logger.debug( + 'Ignoring indexes: %s', + ','.join(redact_auth_from_url(url) for url in index_urls), + ) + index_urls = [] + + # Make sure find_links is a list before passing to create(). + find_links = options.find_links or [] + + search_scope = SearchScope.create( + find_links=find_links, index_urls=index_urls, + ) + link_collector = LinkCollector( + session=session, search_scope=search_scope, + ) + return link_collector + + @property + def find_links(self): + # type: () -> List[str] + return self.search_scope.find_links + + def fetch_page(self, location): + # type: (Link) -> Optional[HTMLPage] + """ + Fetch an HTML page containing package links. + """ + return _get_html_page(location, session=self.session) + + def collect_links(self, project_name): + # type: (str) -> CollectedLinks + """Find all available links for the given project name. + + :return: All the Link objects (unfiltered), as a CollectedLinks object. + """ + search_scope = self.search_scope + index_locations = search_scope.get_index_urls_locations(project_name) + index_file_loc, index_url_loc = group_locations(index_locations) + fl_file_loc, fl_url_loc = group_locations( + self.find_links, expand_dir=True, + ) + + file_links = [ + Link(url) for url in itertools.chain(index_file_loc, fl_file_loc) + ] + + # We trust every directly linked archive in find_links + find_link_links = [Link(url, '-f') for url in self.find_links] + + # We trust every url that the user has given us whether it was given + # via --index-url or --find-links. + # We want to filter out anything that does not have a secure origin. + url_locations = [ + link for link in itertools.chain( + # Mark PyPI indices as "cache_link_parsing == False" -- this + # will avoid caching the result of parsing the page for links. + (Link(url, cache_link_parsing=False) for url in index_url_loc), + (Link(url) for url in fl_url_loc), + ) + if self.session.is_secure_origin(link) + ] + + url_locations = _remove_duplicate_links(url_locations) + lines = [ + '{} location(s) to search for versions of {}:'.format( + len(url_locations), project_name, + ), + ] + for link in url_locations: + lines.append(f'* {link}') + logger.debug('\n'.join(lines)) + + return CollectedLinks( + files=file_links, + find_links=find_link_links, + project_urls=url_locations, + ) diff --git a/venv/Lib/site-packages/pip/_internal/index/package_finder.py b/venv/Lib/site-packages/pip/_internal/index/package_finder.py new file mode 100644 index 0000000..7311889 --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/index/package_finder.py @@ -0,0 +1,1005 @@ +"""Routines related to PyPI, indexes""" + +# The following comment should be removed at some point in the future. +# mypy: strict-optional=False + +import functools +import logging +import re + +from pip._vendor.packaging import specifiers +from pip._vendor.packaging.utils import canonicalize_name +from pip._vendor.packaging.version import parse as parse_version + +from pip._internal.exceptions import ( + BestVersionAlreadyInstalled, + DistributionNotFound, + InvalidWheelFilename, + UnsupportedWheel, +) +from pip._internal.index.collector import parse_links +from pip._internal.models.candidate import InstallationCandidate +from pip._internal.models.format_control import FormatControl +from pip._internal.models.link import Link +from pip._internal.models.selection_prefs import SelectionPreferences +from pip._internal.models.target_python import TargetPython +from pip._internal.models.wheel import Wheel +from pip._internal.utils.filetypes import WHEEL_EXTENSION +from pip._internal.utils.logging import indent_log +from pip._internal.utils.misc import build_netloc +from pip._internal.utils.packaging import check_requires_python +from pip._internal.utils.typing import MYPY_CHECK_RUNNING +from pip._internal.utils.unpacking import SUPPORTED_EXTENSIONS +from pip._internal.utils.urls import url_to_path + +if MYPY_CHECK_RUNNING: + from typing import FrozenSet, Iterable, List, Optional, Set, Tuple, Union + + from pip._vendor.packaging.tags import Tag + from pip._vendor.packaging.version import _BaseVersion + + from pip._internal.index.collector import LinkCollector + from pip._internal.models.search_scope import SearchScope + from pip._internal.req import InstallRequirement + from pip._internal.utils.hashes import Hashes + + BuildTag = Union[Tuple[()], Tuple[int, str]] + CandidateSortingKey = ( + Tuple[int, int, int, _BaseVersion, BuildTag, Optional[int]] + ) + + +__all__ = ['FormatControl', 'BestCandidateResult', 'PackageFinder'] + + +logger = logging.getLogger(__name__) + + +def _check_link_requires_python( + link, # type: Link + version_info, # type: Tuple[int, int, int] + ignore_requires_python=False, # type: bool +): + # type: (...) -> bool + """ + Return whether the given Python version is compatible with a link's + "Requires-Python" value. + + :param version_info: A 3-tuple of ints representing the Python + major-minor-micro version to check. + :param ignore_requires_python: Whether to ignore the "Requires-Python" + value if the given Python version isn't compatible. + """ + try: + is_compatible = check_requires_python( + link.requires_python, version_info=version_info, + ) + except specifiers.InvalidSpecifier: + logger.debug( + "Ignoring invalid Requires-Python (%r) for link: %s", + link.requires_python, link, + ) + else: + if not is_compatible: + version = '.'.join(map(str, version_info)) + if not ignore_requires_python: + logger.debug( + 'Link requires a different Python (%s not in: %r): %s', + version, link.requires_python, link, + ) + return False + + logger.debug( + 'Ignoring failed Requires-Python check (%s not in: %r) ' + 'for link: %s', + version, link.requires_python, link, + ) + + return True + + +class LinkEvaluator: + + """ + Responsible for evaluating links for a particular project. + """ + + _py_version_re = re.compile(r'-py([123]\.?[0-9]?)$') + + # Don't include an allow_yanked default value to make sure each call + # site considers whether yanked releases are allowed. This also causes + # that decision to be made explicit in the calling code, which helps + # people when reading the code. + def __init__( + self, + project_name, # type: str + canonical_name, # type: str + formats, # type: FrozenSet[str] + target_python, # type: TargetPython + allow_yanked, # type: bool + ignore_requires_python=None, # type: Optional[bool] + ): + # type: (...) -> None + """ + :param project_name: The user supplied package name. + :param canonical_name: The canonical package name. + :param formats: The formats allowed for this package. Should be a set + with 'binary' or 'source' or both in it. + :param target_python: The target Python interpreter to use when + evaluating link compatibility. This is used, for example, to + check wheel compatibility, as well as when checking the Python + version, e.g. the Python version embedded in a link filename + (or egg fragment) and against an HTML link's optional PEP 503 + "data-requires-python" attribute. + :param allow_yanked: Whether files marked as yanked (in the sense + of PEP 592) are permitted to be candidates for install. + :param ignore_requires_python: Whether to ignore incompatible + PEP 503 "data-requires-python" values in HTML links. Defaults + to False. + """ + if ignore_requires_python is None: + ignore_requires_python = False + + self._allow_yanked = allow_yanked + self._canonical_name = canonical_name + self._ignore_requires_python = ignore_requires_python + self._formats = formats + self._target_python = target_python + + self.project_name = project_name + + def evaluate_link(self, link): + # type: (Link) -> Tuple[bool, Optional[str]] + """ + Determine whether a link is a candidate for installation. + + :return: A tuple (is_candidate, result), where `result` is (1) a + version string if `is_candidate` is True, and (2) if + `is_candidate` is False, an optional string to log the reason + the link fails to qualify. + """ + version = None + if link.is_yanked and not self._allow_yanked: + reason = link.yanked_reason or '' + return (False, f'yanked for reason: {reason}') + + if link.egg_fragment: + egg_info = link.egg_fragment + ext = link.ext + else: + egg_info, ext = link.splitext() + if not ext: + return (False, 'not a file') + if ext not in SUPPORTED_EXTENSIONS: + return (False, f'unsupported archive format: {ext}') + if "binary" not in self._formats and ext == WHEEL_EXTENSION: + reason = 'No binaries permitted for {}'.format( + self.project_name) + return (False, reason) + if "macosx10" in link.path and ext == '.zip': + return (False, 'macosx10 one') + if ext == WHEEL_EXTENSION: + try: + wheel = Wheel(link.filename) + except InvalidWheelFilename: + return (False, 'invalid wheel filename') + if canonicalize_name(wheel.name) != self._canonical_name: + reason = 'wrong project name (not {})'.format( + self.project_name) + return (False, reason) + + supported_tags = self._target_python.get_tags() + if not wheel.supported(supported_tags): + # Include the wheel's tags in the reason string to + # simplify troubleshooting compatibility issues. + file_tags = wheel.get_formatted_file_tags() + reason = ( + "none of the wheel's tags match: {}".format( + ', '.join(file_tags) + ) + ) + return (False, reason) + + version = wheel.version + + # This should be up by the self.ok_binary check, but see issue 2700. + if "source" not in self._formats and ext != WHEEL_EXTENSION: + reason = f'No sources permitted for {self.project_name}' + return (False, reason) + + if not version: + version = _extract_version_from_fragment( + egg_info, self._canonical_name, + ) + if not version: + reason = f'Missing project version for {self.project_name}' + return (False, reason) + + match = self._py_version_re.search(version) + if match: + version = version[:match.start()] + py_version = match.group(1) + if py_version != self._target_python.py_version: + return (False, 'Python version is incorrect') + + supports_python = _check_link_requires_python( + link, version_info=self._target_python.py_version_info, + ignore_requires_python=self._ignore_requires_python, + ) + if not supports_python: + # Return None for the reason text to suppress calling + # _log_skipped_link(). + return (False, None) + + logger.debug('Found link %s, version: %s', link, version) + + return (True, version) + + +def filter_unallowed_hashes( + candidates, # type: List[InstallationCandidate] + hashes, # type: Hashes + project_name, # type: str +): + # type: (...) -> List[InstallationCandidate] + """ + Filter out candidates whose hashes aren't allowed, and return a new + list of candidates. + + If at least one candidate has an allowed hash, then all candidates with + either an allowed hash or no hash specified are returned. Otherwise, + the given candidates are returned. + + Including the candidates with no hash specified when there is a match + allows a warning to be logged if there is a more preferred candidate + with no hash specified. Returning all candidates in the case of no + matches lets pip report the hash of the candidate that would otherwise + have been installed (e.g. permitting the user to more easily update + their requirements file with the desired hash). + """ + if not hashes: + logger.debug( + 'Given no hashes to check %s links for project %r: ' + 'discarding no candidates', + len(candidates), + project_name, + ) + # Make sure we're not returning back the given value. + return list(candidates) + + matches_or_no_digest = [] + # Collect the non-matches for logging purposes. + non_matches = [] + match_count = 0 + for candidate in candidates: + link = candidate.link + if not link.has_hash: + pass + elif link.is_hash_allowed(hashes=hashes): + match_count += 1 + else: + non_matches.append(candidate) + continue + + matches_or_no_digest.append(candidate) + + if match_count: + filtered = matches_or_no_digest + else: + # Make sure we're not returning back the given value. + filtered = list(candidates) + + if len(filtered) == len(candidates): + discard_message = 'discarding no candidates' + else: + discard_message = 'discarding {} non-matches:\n {}'.format( + len(non_matches), + '\n '.join(str(candidate.link) for candidate in non_matches) + ) + + logger.debug( + 'Checked %s links for project %r against %s hashes ' + '(%s matches, %s no digest): %s', + len(candidates), + project_name, + hashes.digest_count, + match_count, + len(matches_or_no_digest) - match_count, + discard_message + ) + + return filtered + + +class CandidatePreferences: + + """ + Encapsulates some of the preferences for filtering and sorting + InstallationCandidate objects. + """ + + def __init__( + self, + prefer_binary=False, # type: bool + allow_all_prereleases=False, # type: bool + ): + # type: (...) -> None + """ + :param allow_all_prereleases: Whether to allow all pre-releases. + """ + self.allow_all_prereleases = allow_all_prereleases + self.prefer_binary = prefer_binary + + +class BestCandidateResult: + """A collection of candidates, returned by `PackageFinder.find_best_candidate`. + + This class is only intended to be instantiated by CandidateEvaluator's + `compute_best_candidate()` method. + """ + + def __init__( + self, + candidates, # type: List[InstallationCandidate] + applicable_candidates, # type: List[InstallationCandidate] + best_candidate, # type: Optional[InstallationCandidate] + ): + # type: (...) -> None + """ + :param candidates: A sequence of all available candidates found. + :param applicable_candidates: The applicable candidates. + :param best_candidate: The most preferred candidate found, or None + if no applicable candidates were found. + """ + assert set(applicable_candidates) <= set(candidates) + + if best_candidate is None: + assert not applicable_candidates + else: + assert best_candidate in applicable_candidates + + self._applicable_candidates = applicable_candidates + self._candidates = candidates + + self.best_candidate = best_candidate + + def iter_all(self): + # type: () -> Iterable[InstallationCandidate] + """Iterate through all candidates. + """ + return iter(self._candidates) + + def iter_applicable(self): + # type: () -> Iterable[InstallationCandidate] + """Iterate through the applicable candidates. + """ + return iter(self._applicable_candidates) + + +class CandidateEvaluator: + + """ + Responsible for filtering and sorting candidates for installation based + on what tags are valid. + """ + + @classmethod + def create( + cls, + project_name, # type: str + target_python=None, # type: Optional[TargetPython] + prefer_binary=False, # type: bool + allow_all_prereleases=False, # type: bool + specifier=None, # type: Optional[specifiers.BaseSpecifier] + hashes=None, # type: Optional[Hashes] + ): + # type: (...) -> CandidateEvaluator + """Create a CandidateEvaluator object. + + :param target_python: The target Python interpreter to use when + checking compatibility. If None (the default), a TargetPython + object will be constructed from the running Python. + :param specifier: An optional object implementing `filter` + (e.g. `packaging.specifiers.SpecifierSet`) to filter applicable + versions. + :param hashes: An optional collection of allowed hashes. + """ + if target_python is None: + target_python = TargetPython() + if specifier is None: + specifier = specifiers.SpecifierSet() + + supported_tags = target_python.get_tags() + + return cls( + project_name=project_name, + supported_tags=supported_tags, + specifier=specifier, + prefer_binary=prefer_binary, + allow_all_prereleases=allow_all_prereleases, + hashes=hashes, + ) + + def __init__( + self, + project_name, # type: str + supported_tags, # type: List[Tag] + specifier, # type: specifiers.BaseSpecifier + prefer_binary=False, # type: bool + allow_all_prereleases=False, # type: bool + hashes=None, # type: Optional[Hashes] + ): + # type: (...) -> None + """ + :param supported_tags: The PEP 425 tags supported by the target + Python in order of preference (most preferred first). + """ + self._allow_all_prereleases = allow_all_prereleases + self._hashes = hashes + self._prefer_binary = prefer_binary + self._project_name = project_name + self._specifier = specifier + self._supported_tags = supported_tags + + def get_applicable_candidates( + self, + candidates, # type: List[InstallationCandidate] + ): + # type: (...) -> List[InstallationCandidate] + """ + Return the applicable candidates from a list of candidates. + """ + # Using None infers from the specifier instead. + allow_prereleases = self._allow_all_prereleases or None + specifier = self._specifier + versions = { + str(v) for v in specifier.filter( + # We turn the version object into a str here because otherwise + # when we're debundled but setuptools isn't, Python will see + # packaging.version.Version and + # pkg_resources._vendor.packaging.version.Version as different + # types. This way we'll use a str as a common data interchange + # format. If we stop using the pkg_resources provided specifier + # and start using our own, we can drop the cast to str(). + (str(c.version) for c in candidates), + prereleases=allow_prereleases, + ) + } + + # Again, converting version to str to deal with debundling. + applicable_candidates = [ + c for c in candidates if str(c.version) in versions + ] + + filtered_applicable_candidates = filter_unallowed_hashes( + candidates=applicable_candidates, + hashes=self._hashes, + project_name=self._project_name, + ) + + return sorted(filtered_applicable_candidates, key=self._sort_key) + + def _sort_key(self, candidate): + # type: (InstallationCandidate) -> CandidateSortingKey + """ + Function to pass as the `key` argument to a call to sorted() to sort + InstallationCandidates by preference. + + Returns a tuple such that tuples sorting as greater using Python's + default comparison operator are more preferred. + + The preference is as follows: + + First and foremost, candidates with allowed (matching) hashes are + always preferred over candidates without matching hashes. This is + because e.g. if the only candidate with an allowed hash is yanked, + we still want to use that candidate. + + Second, excepting hash considerations, candidates that have been + yanked (in the sense of PEP 592) are always less preferred than + candidates that haven't been yanked. Then: + + If not finding wheels, they are sorted by version only. + If finding wheels, then the sort order is by version, then: + 1. existing installs + 2. wheels ordered via Wheel.support_index_min(self._supported_tags) + 3. source archives + If prefer_binary was set, then all wheels are sorted above sources. + + Note: it was considered to embed this logic into the Link + comparison operators, but then different sdist links + with the same version, would have to be considered equal + """ + valid_tags = self._supported_tags + support_num = len(valid_tags) + build_tag = () # type: BuildTag + binary_preference = 0 + link = candidate.link + if link.is_wheel: + # can raise InvalidWheelFilename + wheel = Wheel(link.filename) + if not wheel.supported(valid_tags): + raise UnsupportedWheel( + "{} is not a supported wheel for this platform. It " + "can't be sorted.".format(wheel.filename) + ) + if self._prefer_binary: + binary_preference = 1 + pri = -(wheel.support_index_min(valid_tags)) + if wheel.build_tag is not None: + match = re.match(r'^(\d+)(.*)$', wheel.build_tag) + build_tag_groups = match.groups() + build_tag = (int(build_tag_groups[0]), build_tag_groups[1]) + else: # sdist + pri = -(support_num) + has_allowed_hash = int(link.is_hash_allowed(self._hashes)) + yank_value = -1 * int(link.is_yanked) # -1 for yanked. + return ( + has_allowed_hash, yank_value, binary_preference, candidate.version, + build_tag, pri, + ) + + def sort_best_candidate( + self, + candidates, # type: List[InstallationCandidate] + ): + # type: (...) -> Optional[InstallationCandidate] + """ + Return the best candidate per the instance's sort order, or None if + no candidate is acceptable. + """ + if not candidates: + return None + best_candidate = max(candidates, key=self._sort_key) + return best_candidate + + def compute_best_candidate( + self, + candidates, # type: List[InstallationCandidate] + ): + # type: (...) -> BestCandidateResult + """ + Compute and return a `BestCandidateResult` instance. + """ + applicable_candidates = self.get_applicable_candidates(candidates) + + best_candidate = self.sort_best_candidate(applicable_candidates) + + return BestCandidateResult( + candidates, + applicable_candidates=applicable_candidates, + best_candidate=best_candidate, + ) + + +class PackageFinder: + """This finds packages. + + This is meant to match easy_install's technique for looking for + packages, by reading pages and looking for appropriate links. + """ + + def __init__( + self, + link_collector, # type: LinkCollector + target_python, # type: TargetPython + allow_yanked, # type: bool + format_control=None, # type: Optional[FormatControl] + candidate_prefs=None, # type: CandidatePreferences + ignore_requires_python=None, # type: Optional[bool] + ): + # type: (...) -> None + """ + This constructor is primarily meant to be used by the create() class + method and from tests. + + :param format_control: A FormatControl object, used to control + the selection of source packages / binary packages when consulting + the index and links. + :param candidate_prefs: Options to use when creating a + CandidateEvaluator object. + """ + if candidate_prefs is None: + candidate_prefs = CandidatePreferences() + + format_control = format_control or FormatControl(set(), set()) + + self._allow_yanked = allow_yanked + self._candidate_prefs = candidate_prefs + self._ignore_requires_python = ignore_requires_python + self._link_collector = link_collector + self._target_python = target_python + + self.format_control = format_control + + # These are boring links that have already been logged somehow. + self._logged_links = set() # type: Set[Link] + + # Don't include an allow_yanked default value to make sure each call + # site considers whether yanked releases are allowed. This also causes + # that decision to be made explicit in the calling code, which helps + # people when reading the code. + @classmethod + def create( + cls, + link_collector, # type: LinkCollector + selection_prefs, # type: SelectionPreferences + target_python=None, # type: Optional[TargetPython] + ): + # type: (...) -> PackageFinder + """Create a PackageFinder. + + :param selection_prefs: The candidate selection preferences, as a + SelectionPreferences object. + :param target_python: The target Python interpreter to use when + checking compatibility. If None (the default), a TargetPython + object will be constructed from the running Python. + """ + if target_python is None: + target_python = TargetPython() + + candidate_prefs = CandidatePreferences( + prefer_binary=selection_prefs.prefer_binary, + allow_all_prereleases=selection_prefs.allow_all_prereleases, + ) + + return cls( + candidate_prefs=candidate_prefs, + link_collector=link_collector, + target_python=target_python, + allow_yanked=selection_prefs.allow_yanked, + format_control=selection_prefs.format_control, + ignore_requires_python=selection_prefs.ignore_requires_python, + ) + + @property + def target_python(self): + # type: () -> TargetPython + return self._target_python + + @property + def search_scope(self): + # type: () -> SearchScope + return self._link_collector.search_scope + + @search_scope.setter + def search_scope(self, search_scope): + # type: (SearchScope) -> None + self._link_collector.search_scope = search_scope + + @property + def find_links(self): + # type: () -> List[str] + return self._link_collector.find_links + + @property + def index_urls(self): + # type: () -> List[str] + return self.search_scope.index_urls + + @property + def trusted_hosts(self): + # type: () -> Iterable[str] + for host_port in self._link_collector.session.pip_trusted_origins: + yield build_netloc(*host_port) + + @property + def allow_all_prereleases(self): + # type: () -> bool + return self._candidate_prefs.allow_all_prereleases + + def set_allow_all_prereleases(self): + # type: () -> None + self._candidate_prefs.allow_all_prereleases = True + + @property + def prefer_binary(self): + # type: () -> bool + return self._candidate_prefs.prefer_binary + + def set_prefer_binary(self): + # type: () -> None + self._candidate_prefs.prefer_binary = True + + def make_link_evaluator(self, project_name): + # type: (str) -> LinkEvaluator + canonical_name = canonicalize_name(project_name) + formats = self.format_control.get_allowed_formats(canonical_name) + + return LinkEvaluator( + project_name=project_name, + canonical_name=canonical_name, + formats=formats, + target_python=self._target_python, + allow_yanked=self._allow_yanked, + ignore_requires_python=self._ignore_requires_python, + ) + + def _sort_links(self, links): + # type: (Iterable[Link]) -> List[Link] + """ + Returns elements of links in order, non-egg links first, egg links + second, while eliminating duplicates + """ + eggs, no_eggs = [], [] + seen = set() # type: Set[Link] + for link in links: + if link not in seen: + seen.add(link) + if link.egg_fragment: + eggs.append(link) + else: + no_eggs.append(link) + return no_eggs + eggs + + def _log_skipped_link(self, link, reason): + # type: (Link, str) -> None + if link not in self._logged_links: + # Put the link at the end so the reason is more visible and because + # the link string is usually very long. + logger.debug('Skipping link: %s: %s', reason, link) + self._logged_links.add(link) + + def get_install_candidate(self, link_evaluator, link): + # type: (LinkEvaluator, Link) -> Optional[InstallationCandidate] + """ + If the link is a candidate for install, convert it to an + InstallationCandidate and return it. Otherwise, return None. + """ + is_candidate, result = link_evaluator.evaluate_link(link) + if not is_candidate: + if result: + self._log_skipped_link(link, reason=result) + return None + + return InstallationCandidate( + name=link_evaluator.project_name, + link=link, + version=result, + ) + + def evaluate_links(self, link_evaluator, links): + # type: (LinkEvaluator, Iterable[Link]) -> List[InstallationCandidate] + """ + Convert links that are candidates to InstallationCandidate objects. + """ + candidates = [] + for link in self._sort_links(links): + candidate = self.get_install_candidate(link_evaluator, link) + if candidate is not None: + candidates.append(candidate) + + return candidates + + def process_project_url(self, project_url, link_evaluator): + # type: (Link, LinkEvaluator) -> List[InstallationCandidate] + logger.debug( + 'Fetching project page and analyzing links: %s', project_url, + ) + html_page = self._link_collector.fetch_page(project_url) + if html_page is None: + return [] + + page_links = list(parse_links(html_page)) + + with indent_log(): + package_links = self.evaluate_links( + link_evaluator, + links=page_links, + ) + + return package_links + + @functools.lru_cache(maxsize=None) + def find_all_candidates(self, project_name): + # type: (str) -> List[InstallationCandidate] + """Find all available InstallationCandidate for project_name + + This checks index_urls and find_links. + All versions found are returned as an InstallationCandidate list. + + See LinkEvaluator.evaluate_link() for details on which files + are accepted. + """ + collected_links = self._link_collector.collect_links(project_name) + + link_evaluator = self.make_link_evaluator(project_name) + + find_links_versions = self.evaluate_links( + link_evaluator, + links=collected_links.find_links, + ) + + page_versions = [] + for project_url in collected_links.project_urls: + package_links = self.process_project_url( + project_url, link_evaluator=link_evaluator, + ) + page_versions.extend(package_links) + + file_versions = self.evaluate_links( + link_evaluator, + links=collected_links.files, + ) + if file_versions: + file_versions.sort(reverse=True) + logger.debug( + 'Local files found: %s', + ', '.join([ + url_to_path(candidate.link.url) + for candidate in file_versions + ]) + ) + + # This is an intentional priority ordering + return file_versions + find_links_versions + page_versions + + def make_candidate_evaluator( + self, + project_name, # type: str + specifier=None, # type: Optional[specifiers.BaseSpecifier] + hashes=None, # type: Optional[Hashes] + ): + # type: (...) -> CandidateEvaluator + """Create a CandidateEvaluator object to use. + """ + candidate_prefs = self._candidate_prefs + return CandidateEvaluator.create( + project_name=project_name, + target_python=self._target_python, + prefer_binary=candidate_prefs.prefer_binary, + allow_all_prereleases=candidate_prefs.allow_all_prereleases, + specifier=specifier, + hashes=hashes, + ) + + @functools.lru_cache(maxsize=None) + def find_best_candidate( + self, + project_name, # type: str + specifier=None, # type: Optional[specifiers.BaseSpecifier] + hashes=None, # type: Optional[Hashes] + ): + # type: (...) -> BestCandidateResult + """Find matches for the given project and specifier. + + :param specifier: An optional object implementing `filter` + (e.g. `packaging.specifiers.SpecifierSet`) to filter applicable + versions. + + :return: A `BestCandidateResult` instance. + """ + candidates = self.find_all_candidates(project_name) + candidate_evaluator = self.make_candidate_evaluator( + project_name=project_name, + specifier=specifier, + hashes=hashes, + ) + return candidate_evaluator.compute_best_candidate(candidates) + + def find_requirement(self, req, upgrade): + # type: (InstallRequirement, bool) -> Optional[InstallationCandidate] + """Try to find a Link matching req + + Expects req, an InstallRequirement and upgrade, a boolean + Returns a InstallationCandidate if found, + Raises DistributionNotFound or BestVersionAlreadyInstalled otherwise + """ + hashes = req.hashes(trust_internet=False) + best_candidate_result = self.find_best_candidate( + req.name, specifier=req.specifier, hashes=hashes, + ) + best_candidate = best_candidate_result.best_candidate + + installed_version = None # type: Optional[_BaseVersion] + if req.satisfied_by is not None: + installed_version = parse_version(req.satisfied_by.version) + + def _format_versions(cand_iter): + # type: (Iterable[InstallationCandidate]) -> str + # This repeated parse_version and str() conversion is needed to + # handle different vendoring sources from pip and pkg_resources. + # If we stop using the pkg_resources provided specifier and start + # using our own, we can drop the cast to str(). + return ", ".join(sorted( + {str(c.version) for c in cand_iter}, + key=parse_version, + )) or "none" + + if installed_version is None and best_candidate is None: + logger.critical( + 'Could not find a version that satisfies the requirement %s ' + '(from versions: %s)', + req, + _format_versions(best_candidate_result.iter_all()), + ) + + raise DistributionNotFound( + 'No matching distribution found for {}'.format( + req) + ) + + best_installed = False + if installed_version and ( + best_candidate is None or + best_candidate.version <= installed_version): + best_installed = True + + if not upgrade and installed_version is not None: + if best_installed: + logger.debug( + 'Existing installed version (%s) is most up-to-date and ' + 'satisfies requirement', + installed_version, + ) + else: + logger.debug( + 'Existing installed version (%s) satisfies requirement ' + '(most up-to-date version is %s)', + installed_version, + best_candidate.version, + ) + return None + + if best_installed: + # We have an existing version, and its the best version + logger.debug( + 'Installed version (%s) is most up-to-date (past versions: ' + '%s)', + installed_version, + _format_versions(best_candidate_result.iter_applicable()), + ) + raise BestVersionAlreadyInstalled + + logger.debug( + 'Using version %s (newest of versions: %s)', + best_candidate.version, + _format_versions(best_candidate_result.iter_applicable()), + ) + return best_candidate + + +def _find_name_version_sep(fragment, canonical_name): + # type: (str, str) -> int + """Find the separator's index based on the package's canonical name. + + :param fragment: A + filename "fragment" (stem) or + egg fragment. + :param canonical_name: The package's canonical name. + + This function is needed since the canonicalized name does not necessarily + have the same length as the egg info's name part. An example:: + + >>> fragment = 'foo__bar-1.0' + >>> canonical_name = 'foo-bar' + >>> _find_name_version_sep(fragment, canonical_name) + 8 + """ + # Project name and version must be separated by one single dash. Find all + # occurrences of dashes; if the string in front of it matches the canonical + # name, this is the one separating the name and version parts. + for i, c in enumerate(fragment): + if c != "-": + continue + if canonicalize_name(fragment[:i]) == canonical_name: + return i + raise ValueError(f"{fragment} does not match {canonical_name}") + + +def _extract_version_from_fragment(fragment, canonical_name): + # type: (str, str) -> Optional[str] + """Parse the version string from a + filename + "fragment" (stem) or egg fragment. + + :param fragment: The string to parse. E.g. foo-2.1 + :param canonical_name: The canonicalized name of the package this + belongs to. + """ + try: + version_start = _find_name_version_sep(fragment, canonical_name) + 1 + except ValueError: + return None + version = fragment[version_start:] + if not version: + return None + return version diff --git a/venv/Lib/site-packages/pip/_internal/locations.py b/venv/Lib/site-packages/pip/_internal/locations.py new file mode 100644 index 0000000..88b9e43 --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/locations.py @@ -0,0 +1,184 @@ +"""Locations where we look for configs, install stuff, etc""" + +# The following comment should be removed at some point in the future. +# mypy: strict-optional=False + +import os +import os.path +import site +import sys +import sysconfig +from distutils.command.install import SCHEME_KEYS +from distutils.command.install import install as distutils_install_command + +from pip._internal.models.scheme import Scheme +from pip._internal.utils import appdirs +from pip._internal.utils.compat import WINDOWS +from pip._internal.utils.typing import MYPY_CHECK_RUNNING, cast +from pip._internal.utils.virtualenv import running_under_virtualenv + +if MYPY_CHECK_RUNNING: + from distutils.cmd import Command as DistutilsCommand + from typing import Dict, List, Optional, Union + + +# Application Directories +USER_CACHE_DIR = appdirs.user_cache_dir("pip") + + +def get_major_minor_version(): + # type: () -> str + """ + Return the major-minor version of the current Python as a string, e.g. + "3.7" or "3.10". + """ + return '{}.{}'.format(*sys.version_info) + + +def get_src_prefix(): + # type: () -> str + if running_under_virtualenv(): + src_prefix = os.path.join(sys.prefix, 'src') + else: + # FIXME: keep src in cwd for now (it is not a temporary folder) + try: + src_prefix = os.path.join(os.getcwd(), 'src') + except OSError: + # In case the current working directory has been renamed or deleted + sys.exit( + "The folder you are executing pip from can no longer be found." + ) + + # under macOS + virtualenv sys.prefix is not properly resolved + # it is something like /path/to/python/bin/.. + return os.path.abspath(src_prefix) + + +# FIXME doesn't account for venv linked to global site-packages + +site_packages = sysconfig.get_path("purelib") # type: Optional[str] + +try: + # Use getusersitepackages if this is present, as it ensures that the + # value is initialised properly. + user_site = site.getusersitepackages() +except AttributeError: + user_site = site.USER_SITE + +if WINDOWS: + bin_py = os.path.join(sys.prefix, 'Scripts') + bin_user = os.path.join(user_site, 'Scripts') + # buildout uses 'bin' on Windows too? + if not os.path.exists(bin_py): + bin_py = os.path.join(sys.prefix, 'bin') + bin_user = os.path.join(user_site, 'bin') +else: + bin_py = os.path.join(sys.prefix, 'bin') + bin_user = os.path.join(user_site, 'bin') + + # Forcing to use /usr/local/bin for standard macOS framework installs + # Also log to ~/Library/Logs/ for use with the Console.app log viewer + if sys.platform[:6] == 'darwin' and sys.prefix[:16] == '/System/Library/': + bin_py = '/usr/local/bin' + + +def distutils_scheme( + dist_name, user=False, home=None, root=None, isolated=False, prefix=None +): + # type:(str, bool, str, str, bool, str) -> Dict[str, str] + """ + Return a distutils install scheme + """ + from distutils.dist import Distribution + + dist_args = {'name': dist_name} # type: Dict[str, Union[str, List[str]]] + if isolated: + dist_args["script_args"] = ["--no-user-cfg"] + + d = Distribution(dist_args) + d.parse_config_files() + obj = None # type: Optional[DistutilsCommand] + obj = d.get_command_obj('install', create=True) + assert obj is not None + i = cast(distutils_install_command, obj) + # NOTE: setting user or home has the side-effect of creating the home dir + # or user base for installations during finalize_options() + # ideally, we'd prefer a scheme class that has no side-effects. + assert not (user and prefix), f"user={user} prefix={prefix}" + assert not (home and prefix), f"home={home} prefix={prefix}" + i.user = user or i.user + if user or home: + i.prefix = "" + i.prefix = prefix or i.prefix + i.home = home or i.home + i.root = root or i.root + i.finalize_options() + + scheme = {} + for key in SCHEME_KEYS: + scheme[key] = getattr(i, 'install_' + key) + + # install_lib specified in setup.cfg should install *everything* + # into there (i.e. it takes precedence over both purelib and + # platlib). Note, i.install_lib is *always* set after + # finalize_options(); we only want to override here if the user + # has explicitly requested it hence going back to the config + if 'install_lib' in d.get_option_dict('install'): + scheme.update(dict(purelib=i.install_lib, platlib=i.install_lib)) + + if running_under_virtualenv(): + scheme['headers'] = os.path.join( + i.prefix, + 'include', + 'site', + f'python{get_major_minor_version()}', + dist_name, + ) + + if root is not None: + path_no_drive = os.path.splitdrive( + os.path.abspath(scheme["headers"]))[1] + scheme["headers"] = os.path.join( + root, + path_no_drive[1:], + ) + + return scheme + + +def get_scheme( + dist_name, # type: str + user=False, # type: bool + home=None, # type: Optional[str] + root=None, # type: Optional[str] + isolated=False, # type: bool + prefix=None, # type: Optional[str] +): + # type: (...) -> Scheme + """ + Get the "scheme" corresponding to the input parameters. The distutils + documentation provides the context for the available schemes: + https://docs.python.org/3/install/index.html#alternate-installation + + :param dist_name: the name of the package to retrieve the scheme for, used + in the headers scheme path + :param user: indicates to use the "user" scheme + :param home: indicates to use the "home" scheme and provides the base + directory for the same + :param root: root under which other directories are re-based + :param isolated: equivalent to --no-user-cfg, i.e. do not consider + ~/.pydistutils.cfg (posix) or ~/pydistutils.cfg (non-posix) for + scheme paths + :param prefix: indicates to use the "prefix" scheme and provides the + base directory for the same + """ + scheme = distutils_scheme( + dist_name, user, home, root, isolated, prefix + ) + return Scheme( + platlib=scheme["platlib"], + purelib=scheme["purelib"], + headers=scheme["headers"], + scripts=scheme["scripts"], + data=scheme["data"], + ) diff --git a/venv/Lib/site-packages/pip/_internal/main.py b/venv/Lib/site-packages/pip/_internal/main.py new file mode 100644 index 0000000..1c99c49 --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/main.py @@ -0,0 +1,16 @@ +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import List, Optional + + +def main(args=None): + # type: (Optional[List[str]]) -> int + """This is preserved for old console scripts that may still be referencing + it. + + For additional details, see https://github.com/pypa/pip/issues/7498. + """ + from pip._internal.utils.entrypoints import _wrapper + + return _wrapper(args) diff --git a/venv/Lib/site-packages/pip/_internal/models/__init__.py b/venv/Lib/site-packages/pip/_internal/models/__init__.py new file mode 100644 index 0000000..7855226 --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/models/__init__.py @@ -0,0 +1,2 @@ +"""A package that contains models that represent entities. +""" diff --git a/venv/Lib/site-packages/pip/_internal/models/candidate.py b/venv/Lib/site-packages/pip/_internal/models/candidate.py new file mode 100644 index 0000000..d8a8d42 --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/models/candidate.py @@ -0,0 +1,39 @@ +from pip._vendor.packaging.version import parse as parse_version + +from pip._internal.utils.models import KeyBasedCompareMixin +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from pip._vendor.packaging.version import _BaseVersion + + from pip._internal.models.link import Link + + +class InstallationCandidate(KeyBasedCompareMixin): + """Represents a potential "candidate" for installation. + """ + + __slots__ = ["name", "version", "link"] + + def __init__(self, name, version, link): + # type: (str, str, Link) -> None + self.name = name + self.version = parse_version(version) # type: _BaseVersion + self.link = link + + super().__init__( + key=(self.name, self.version, self.link), + defining_class=InstallationCandidate + ) + + def __repr__(self): + # type: () -> str + return "".format( + self.name, self.version, self.link, + ) + + def __str__(self): + # type: () -> str + return '{!r} candidate (version {} at {})'.format( + self.name, self.version, self.link, + ) diff --git a/venv/Lib/site-packages/pip/_internal/models/direct_url.py b/venv/Lib/site-packages/pip/_internal/models/direct_url.py new file mode 100644 index 0000000..a8869bd --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/models/direct_url.py @@ -0,0 +1,239 @@ +""" PEP 610 """ +import json +import re +import urllib.parse + +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import Any, Dict, Iterable, Optional, Type, TypeVar, Union + + T = TypeVar("T") + + +DIRECT_URL_METADATA_NAME = "direct_url.json" +ENV_VAR_RE = re.compile(r"^\$\{[A-Za-z0-9-_]+\}(:\$\{[A-Za-z0-9-_]+\})?$") + +__all__ = [ + "DirectUrl", + "DirectUrlValidationError", + "DirInfo", + "ArchiveInfo", + "VcsInfo", +] + + +class DirectUrlValidationError(Exception): + pass + + +def _get(d, expected_type, key, default=None): + # type: (Dict[str, Any], Type[T], str, Optional[T]) -> Optional[T] + """Get value from dictionary and verify expected type.""" + if key not in d: + return default + value = d[key] + if not isinstance(value, expected_type): + raise DirectUrlValidationError( + "{!r} has unexpected type for {} (expected {})".format( + value, key, expected_type + ) + ) + return value + + +def _get_required(d, expected_type, key, default=None): + # type: (Dict[str, Any], Type[T], str, Optional[T]) -> T + value = _get(d, expected_type, key, default) + if value is None: + raise DirectUrlValidationError(f"{key} must have a value") + return value + + +def _exactly_one_of(infos): + # type: (Iterable[Optional[InfoType]]) -> InfoType + infos = [info for info in infos if info is not None] + if not infos: + raise DirectUrlValidationError( + "missing one of archive_info, dir_info, vcs_info" + ) + if len(infos) > 1: + raise DirectUrlValidationError( + "more than one of archive_info, dir_info, vcs_info" + ) + assert infos[0] is not None + return infos[0] + + +def _filter_none(**kwargs): + # type: (Any) -> Dict[str, Any] + """Make dict excluding None values.""" + return {k: v for k, v in kwargs.items() if v is not None} + + +class VcsInfo: + name = "vcs_info" + + def __init__( + self, + vcs, # type: str + commit_id, # type: str + requested_revision=None, # type: Optional[str] + resolved_revision=None, # type: Optional[str] + resolved_revision_type=None, # type: Optional[str] + ): + self.vcs = vcs + self.requested_revision = requested_revision + self.commit_id = commit_id + self.resolved_revision = resolved_revision + self.resolved_revision_type = resolved_revision_type + + @classmethod + def _from_dict(cls, d): + # type: (Optional[Dict[str, Any]]) -> Optional[VcsInfo] + if d is None: + return None + return cls( + vcs=_get_required(d, str, "vcs"), + commit_id=_get_required(d, str, "commit_id"), + requested_revision=_get(d, str, "requested_revision"), + resolved_revision=_get(d, str, "resolved_revision"), + resolved_revision_type=_get(d, str, "resolved_revision_type"), + ) + + def _to_dict(self): + # type: () -> Dict[str, Any] + return _filter_none( + vcs=self.vcs, + requested_revision=self.requested_revision, + commit_id=self.commit_id, + resolved_revision=self.resolved_revision, + resolved_revision_type=self.resolved_revision_type, + ) + + +class ArchiveInfo: + name = "archive_info" + + def __init__( + self, + hash=None, # type: Optional[str] + ): + self.hash = hash + + @classmethod + def _from_dict(cls, d): + # type: (Optional[Dict[str, Any]]) -> Optional[ArchiveInfo] + if d is None: + return None + return cls(hash=_get(d, str, "hash")) + + def _to_dict(self): + # type: () -> Dict[str, Any] + return _filter_none(hash=self.hash) + + +class DirInfo: + name = "dir_info" + + def __init__( + self, + editable=False, # type: bool + ): + self.editable = editable + + @classmethod + def _from_dict(cls, d): + # type: (Optional[Dict[str, Any]]) -> Optional[DirInfo] + if d is None: + return None + return cls( + editable=_get_required(d, bool, "editable", default=False) + ) + + def _to_dict(self): + # type: () -> Dict[str, Any] + return _filter_none(editable=self.editable or None) + + +if MYPY_CHECK_RUNNING: + InfoType = Union[ArchiveInfo, DirInfo, VcsInfo] + + +class DirectUrl: + + def __init__( + self, + url, # type: str + info, # type: InfoType + subdirectory=None, # type: Optional[str] + ): + self.url = url + self.info = info + self.subdirectory = subdirectory + + def _remove_auth_from_netloc(self, netloc): + # type: (str) -> str + if "@" not in netloc: + return netloc + user_pass, netloc_no_user_pass = netloc.split("@", 1) + if ( + isinstance(self.info, VcsInfo) and + self.info.vcs == "git" and + user_pass == "git" + ): + return netloc + if ENV_VAR_RE.match(user_pass): + return netloc + return netloc_no_user_pass + + @property + def redacted_url(self): + # type: () -> str + """url with user:password part removed unless it is formed with + environment variables as specified in PEP 610, or it is ``git`` + in the case of a git URL. + """ + purl = urllib.parse.urlsplit(self.url) + netloc = self._remove_auth_from_netloc(purl.netloc) + surl = urllib.parse.urlunsplit( + (purl.scheme, netloc, purl.path, purl.query, purl.fragment) + ) + return surl + + def validate(self): + # type: () -> None + self.from_dict(self.to_dict()) + + @classmethod + def from_dict(cls, d): + # type: (Dict[str, Any]) -> DirectUrl + return DirectUrl( + url=_get_required(d, str, "url"), + subdirectory=_get(d, str, "subdirectory"), + info=_exactly_one_of( + [ + ArchiveInfo._from_dict(_get(d, dict, "archive_info")), + DirInfo._from_dict(_get(d, dict, "dir_info")), + VcsInfo._from_dict(_get(d, dict, "vcs_info")), + ] + ), + ) + + def to_dict(self): + # type: () -> Dict[str, Any] + res = _filter_none( + url=self.redacted_url, + subdirectory=self.subdirectory, + ) + res[self.info.name] = self.info._to_dict() + return res + + @classmethod + def from_json(cls, s): + # type: (str) -> DirectUrl + return cls.from_dict(json.loads(s)) + + def to_json(self): + # type: () -> str + return json.dumps(self.to_dict(), sort_keys=True) diff --git a/venv/Lib/site-packages/pip/_internal/models/format_control.py b/venv/Lib/site-packages/pip/_internal/models/format_control.py new file mode 100644 index 0000000..eb46f25 --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/models/format_control.py @@ -0,0 +1,88 @@ +from pip._vendor.packaging.utils import canonicalize_name + +from pip._internal.exceptions import CommandError +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import FrozenSet, Optional, Set + + +class FormatControl: + """Helper for managing formats from which a package can be installed. + """ + + __slots__ = ["no_binary", "only_binary"] + + def __init__(self, no_binary=None, only_binary=None): + # type: (Optional[Set[str]], Optional[Set[str]]) -> None + if no_binary is None: + no_binary = set() + if only_binary is None: + only_binary = set() + + self.no_binary = no_binary + self.only_binary = only_binary + + def __eq__(self, other): + # type: (object) -> bool + if not isinstance(other, self.__class__): + return NotImplemented + + if self.__slots__ != other.__slots__: + return False + + return all( + getattr(self, k) == getattr(other, k) + for k in self.__slots__ + ) + + def __repr__(self): + # type: () -> str + return "{}({}, {})".format( + self.__class__.__name__, + self.no_binary, + self.only_binary + ) + + @staticmethod + def handle_mutual_excludes(value, target, other): + # type: (str, Set[str], Set[str]) -> None + if value.startswith('-'): + raise CommandError( + "--no-binary / --only-binary option requires 1 argument." + ) + new = value.split(',') + while ':all:' in new: + other.clear() + target.clear() + target.add(':all:') + del new[:new.index(':all:') + 1] + # Without a none, we want to discard everything as :all: covers it + if ':none:' not in new: + return + for name in new: + if name == ':none:': + target.clear() + continue + name = canonicalize_name(name) + other.discard(name) + target.add(name) + + def get_allowed_formats(self, canonical_name): + # type: (str) -> FrozenSet[str] + result = {"binary", "source"} + if canonical_name in self.only_binary: + result.discard('source') + elif canonical_name in self.no_binary: + result.discard('binary') + elif ':all:' in self.only_binary: + result.discard('source') + elif ':all:' in self.no_binary: + result.discard('binary') + return frozenset(result) + + def disallow_binaries(self): + # type: () -> None + self.handle_mutual_excludes( + ':all:', self.no_binary, self.only_binary, + ) diff --git a/venv/Lib/site-packages/pip/_internal/models/index.py b/venv/Lib/site-packages/pip/_internal/models/index.py new file mode 100644 index 0000000..b148abb --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/models/index.py @@ -0,0 +1,34 @@ +import urllib.parse + + +class PackageIndex: + """Represents a Package Index and provides easier access to endpoints + """ + + __slots__ = ['url', 'netloc', 'simple_url', 'pypi_url', + 'file_storage_domain'] + + def __init__(self, url, file_storage_domain): + # type: (str, str) -> None + super().__init__() + self.url = url + self.netloc = urllib.parse.urlsplit(url).netloc + self.simple_url = self._url_for_path('simple') + self.pypi_url = self._url_for_path('pypi') + + # This is part of a temporary hack used to block installs of PyPI + # packages which depend on external urls only necessary until PyPI can + # block such packages themselves + self.file_storage_domain = file_storage_domain + + def _url_for_path(self, path): + # type: (str) -> str + return urllib.parse.urljoin(self.url, path) + + +PyPI = PackageIndex( + 'https://pypi.org/', file_storage_domain='files.pythonhosted.org' +) +TestPyPI = PackageIndex( + 'https://test.pypi.org/', file_storage_domain='test-files.pythonhosted.org' +) diff --git a/venv/Lib/site-packages/pip/_internal/models/link.py b/venv/Lib/site-packages/pip/_internal/models/link.py new file mode 100644 index 0000000..06a7ceb --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/models/link.py @@ -0,0 +1,245 @@ +import os +import posixpath +import re +import urllib.parse + +from pip._internal.utils.filetypes import WHEEL_EXTENSION +from pip._internal.utils.misc import ( + redact_auth_from_url, + split_auth_from_netloc, + splitext, +) +from pip._internal.utils.models import KeyBasedCompareMixin +from pip._internal.utils.typing import MYPY_CHECK_RUNNING +from pip._internal.utils.urls import path_to_url, url_to_path + +if MYPY_CHECK_RUNNING: + from typing import Optional, Tuple, Union + + from pip._internal.index.collector import HTMLPage + from pip._internal.utils.hashes import Hashes + + +class Link(KeyBasedCompareMixin): + """Represents a parsed link from a Package Index's simple URL + """ + + __slots__ = [ + "_parsed_url", + "_url", + "comes_from", + "requires_python", + "yanked_reason", + "cache_link_parsing", + ] + + def __init__( + self, + url, # type: str + comes_from=None, # type: Optional[Union[str, HTMLPage]] + requires_python=None, # type: Optional[str] + yanked_reason=None, # type: Optional[str] + cache_link_parsing=True, # type: bool + ): + # type: (...) -> None + """ + :param url: url of the resource pointed to (href of the link) + :param comes_from: instance of HTMLPage where the link was found, + or string. + :param requires_python: String containing the `Requires-Python` + metadata field, specified in PEP 345. This may be specified by + a data-requires-python attribute in the HTML link tag, as + described in PEP 503. + :param yanked_reason: the reason the file has been yanked, if the + file has been yanked, or None if the file hasn't been yanked. + This is the value of the "data-yanked" attribute, if present, in + a simple repository HTML link. If the file has been yanked but + no reason was provided, this should be the empty string. See + PEP 592 for more information and the specification. + :param cache_link_parsing: A flag that is used elsewhere to determine + whether resources retrieved from this link + should be cached. PyPI index urls should + generally have this set to False, for + example. + """ + + # url can be a UNC windows share + if url.startswith('\\\\'): + url = path_to_url(url) + + self._parsed_url = urllib.parse.urlsplit(url) + # Store the url as a private attribute to prevent accidentally + # trying to set a new value. + self._url = url + + self.comes_from = comes_from + self.requires_python = requires_python if requires_python else None + self.yanked_reason = yanked_reason + + super().__init__(key=url, defining_class=Link) + + self.cache_link_parsing = cache_link_parsing + + def __str__(self): + # type: () -> str + if self.requires_python: + rp = f' (requires-python:{self.requires_python})' + else: + rp = '' + if self.comes_from: + return '{} (from {}){}'.format( + redact_auth_from_url(self._url), self.comes_from, rp) + else: + return redact_auth_from_url(str(self._url)) + + def __repr__(self): + # type: () -> str + return f'' + + @property + def url(self): + # type: () -> str + return self._url + + @property + def filename(self): + # type: () -> str + path = self.path.rstrip('/') + name = posixpath.basename(path) + if not name: + # Make sure we don't leak auth information if the netloc + # includes a username and password. + netloc, user_pass = split_auth_from_netloc(self.netloc) + return netloc + + name = urllib.parse.unquote(name) + assert name, ( + 'URL {self._url!r} produced no filename'.format(**locals())) + return name + + @property + def file_path(self): + # type: () -> str + return url_to_path(self.url) + + @property + def scheme(self): + # type: () -> str + return self._parsed_url.scheme + + @property + def netloc(self): + # type: () -> str + """ + This can contain auth information. + """ + return self._parsed_url.netloc + + @property + def path(self): + # type: () -> str + return urllib.parse.unquote(self._parsed_url.path) + + def splitext(self): + # type: () -> Tuple[str, str] + return splitext(posixpath.basename(self.path.rstrip('/'))) + + @property + def ext(self): + # type: () -> str + return self.splitext()[1] + + @property + def url_without_fragment(self): + # type: () -> str + scheme, netloc, path, query, fragment = self._parsed_url + return urllib.parse.urlunsplit((scheme, netloc, path, query, None)) + + _egg_fragment_re = re.compile(r'[#&]egg=([^&]*)') + + @property + def egg_fragment(self): + # type: () -> Optional[str] + match = self._egg_fragment_re.search(self._url) + if not match: + return None + return match.group(1) + + _subdirectory_fragment_re = re.compile(r'[#&]subdirectory=([^&]*)') + + @property + def subdirectory_fragment(self): + # type: () -> Optional[str] + match = self._subdirectory_fragment_re.search(self._url) + if not match: + return None + return match.group(1) + + _hash_re = re.compile( + r'(sha1|sha224|sha384|sha256|sha512|md5)=([a-f0-9]+)' + ) + + @property + def hash(self): + # type: () -> Optional[str] + match = self._hash_re.search(self._url) + if match: + return match.group(2) + return None + + @property + def hash_name(self): + # type: () -> Optional[str] + match = self._hash_re.search(self._url) + if match: + return match.group(1) + return None + + @property + def show_url(self): + # type: () -> str + return posixpath.basename(self._url.split('#', 1)[0].split('?', 1)[0]) + + @property + def is_file(self): + # type: () -> bool + return self.scheme == 'file' + + def is_existing_dir(self): + # type: () -> bool + return self.is_file and os.path.isdir(self.file_path) + + @property + def is_wheel(self): + # type: () -> bool + return self.ext == WHEEL_EXTENSION + + @property + def is_vcs(self): + # type: () -> bool + from pip._internal.vcs import vcs + + return self.scheme in vcs.all_schemes + + @property + def is_yanked(self): + # type: () -> bool + return self.yanked_reason is not None + + @property + def has_hash(self): + # type: () -> bool + return self.hash_name is not None + + def is_hash_allowed(self, hashes): + # type: (Optional[Hashes]) -> bool + """ + Return True if the link has a hash and it is allowed. + """ + if hashes is None or not self.has_hash: + return False + # Assert non-None so mypy knows self.hash_name and self.hash are str. + assert self.hash_name is not None + assert self.hash is not None + + return hashes.is_hash_allowed(self.hash_name, hex_digest=self.hash) diff --git a/venv/Lib/site-packages/pip/_internal/models/scheme.py b/venv/Lib/site-packages/pip/_internal/models/scheme.py new file mode 100644 index 0000000..697cd19 --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/models/scheme.py @@ -0,0 +1,31 @@ +""" +For types associated with installation schemes. + +For a general overview of available schemes and their context, see +https://docs.python.org/3/install/index.html#alternate-installation. +""" + + +SCHEME_KEYS = ['platlib', 'purelib', 'headers', 'scripts', 'data'] + + +class Scheme: + """A Scheme holds paths which are used as the base directories for + artifacts associated with a Python package. + """ + + __slots__ = SCHEME_KEYS + + def __init__( + self, + platlib, # type: str + purelib, # type: str + headers, # type: str + scripts, # type: str + data, # type: str + ): + self.platlib = platlib + self.purelib = purelib + self.headers = headers + self.scripts = scripts + self.data = data diff --git a/venv/Lib/site-packages/pip/_internal/models/search_scope.py b/venv/Lib/site-packages/pip/_internal/models/search_scope.py new file mode 100644 index 0000000..c972f1d --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/models/search_scope.py @@ -0,0 +1,135 @@ +import itertools +import logging +import os +import posixpath +import urllib.parse + +from pip._vendor.packaging.utils import canonicalize_name + +from pip._internal.models.index import PyPI +from pip._internal.utils.compat import has_tls +from pip._internal.utils.misc import normalize_path, redact_auth_from_url +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import List + + +logger = logging.getLogger(__name__) + + +class SearchScope: + + """ + Encapsulates the locations that pip is configured to search. + """ + + __slots__ = ["find_links", "index_urls"] + + @classmethod + def create( + cls, + find_links, # type: List[str] + index_urls, # type: List[str] + ): + # type: (...) -> SearchScope + """ + Create a SearchScope object after normalizing the `find_links`. + """ + # Build find_links. If an argument starts with ~, it may be + # a local file relative to a home directory. So try normalizing + # it and if it exists, use the normalized version. + # This is deliberately conservative - it might be fine just to + # blindly normalize anything starting with a ~... + built_find_links = [] # type: List[str] + for link in find_links: + if link.startswith('~'): + new_link = normalize_path(link) + if os.path.exists(new_link): + link = new_link + built_find_links.append(link) + + # If we don't have TLS enabled, then WARN if anyplace we're looking + # relies on TLS. + if not has_tls(): + for link in itertools.chain(index_urls, built_find_links): + parsed = urllib.parse.urlparse(link) + if parsed.scheme == 'https': + logger.warning( + 'pip is configured with locations that require ' + 'TLS/SSL, however the ssl module in Python is not ' + 'available.' + ) + break + + return cls( + find_links=built_find_links, + index_urls=index_urls, + ) + + def __init__( + self, + find_links, # type: List[str] + index_urls, # type: List[str] + ): + # type: (...) -> None + self.find_links = find_links + self.index_urls = index_urls + + def get_formatted_locations(self): + # type: () -> str + lines = [] + redacted_index_urls = [] + if self.index_urls and self.index_urls != [PyPI.simple_url]: + for url in self.index_urls: + + redacted_index_url = redact_auth_from_url(url) + + # Parse the URL + purl = urllib.parse.urlsplit(redacted_index_url) + + # URL is generally invalid if scheme and netloc is missing + # there are issues with Python and URL parsing, so this test + # is a bit crude. See bpo-20271, bpo-23505. Python doesn't + # always parse invalid URLs correctly - it should raise + # exceptions for malformed URLs + if not purl.scheme and not purl.netloc: + logger.warning( + 'The index url "%s" seems invalid, ' + 'please provide a scheme.', redacted_index_url) + + redacted_index_urls.append(redacted_index_url) + + lines.append('Looking in indexes: {}'.format( + ', '.join(redacted_index_urls))) + + if self.find_links: + lines.append( + 'Looking in links: {}'.format(', '.join( + redact_auth_from_url(url) for url in self.find_links)) + ) + return '\n'.join(lines) + + def get_index_urls_locations(self, project_name): + # type: (str) -> List[str] + """Returns the locations found via self.index_urls + + Checks the url_name on the main (first in the list) index and + use this url_name to produce all locations + """ + + def mkurl_pypi_url(url): + # type: (str) -> str + loc = posixpath.join( + url, + urllib.parse.quote(canonicalize_name(project_name))) + # For maximum compatibility with easy_install, ensure the path + # ends in a trailing slash. Although this isn't in the spec + # (and PyPI can handle it without the slash) some other index + # implementations might break if they relied on easy_install's + # behavior. + if not loc.endswith('/'): + loc = loc + '/' + return loc + + return [mkurl_pypi_url(url) for url in self.index_urls] diff --git a/venv/Lib/site-packages/pip/_internal/models/selection_prefs.py b/venv/Lib/site-packages/pip/_internal/models/selection_prefs.py new file mode 100644 index 0000000..4d58222 --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/models/selection_prefs.py @@ -0,0 +1,50 @@ +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import Optional + + from pip._internal.models.format_control import FormatControl + + +class SelectionPreferences: + """ + Encapsulates the candidate selection preferences for downloading + and installing files. + """ + + __slots__ = ['allow_yanked', 'allow_all_prereleases', 'format_control', + 'prefer_binary', 'ignore_requires_python'] + + # Don't include an allow_yanked default value to make sure each call + # site considers whether yanked releases are allowed. This also causes + # that decision to be made explicit in the calling code, which helps + # people when reading the code. + def __init__( + self, + allow_yanked, # type: bool + allow_all_prereleases=False, # type: bool + format_control=None, # type: Optional[FormatControl] + prefer_binary=False, # type: bool + ignore_requires_python=None, # type: Optional[bool] + ): + # type: (...) -> None + """Create a SelectionPreferences object. + + :param allow_yanked: Whether files marked as yanked (in the sense + of PEP 592) are permitted to be candidates for install. + :param format_control: A FormatControl object or None. Used to control + the selection of source packages / binary packages when consulting + the index and links. + :param prefer_binary: Whether to prefer an old, but valid, binary + dist over a new source dist. + :param ignore_requires_python: Whether to ignore incompatible + "Requires-Python" values in links. Defaults to False. + """ + if ignore_requires_python is None: + ignore_requires_python = False + + self.allow_yanked = allow_yanked + self.allow_all_prereleases = allow_all_prereleases + self.format_control = format_control + self.prefer_binary = prefer_binary + self.ignore_requires_python = ignore_requires_python diff --git a/venv/Lib/site-packages/pip/_internal/models/target_python.py b/venv/Lib/site-packages/pip/_internal/models/target_python.py new file mode 100644 index 0000000..6e6e8b5 --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/models/target_python.py @@ -0,0 +1,117 @@ +import sys + +from pip._internal.utils.compatibility_tags import get_supported, version_info_to_nodot +from pip._internal.utils.misc import normalize_version_info +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import List, Optional, Tuple + + from pip._vendor.packaging.tags import Tag + + +class TargetPython: + + """ + Encapsulates the properties of a Python interpreter one is targeting + for a package install, download, etc. + """ + + __slots__ = [ + "_given_py_version_info", + "abis", + "implementation", + "platforms", + "py_version", + "py_version_info", + "_valid_tags", + ] + + def __init__( + self, + platforms=None, # type: Optional[List[str]] + py_version_info=None, # type: Optional[Tuple[int, ...]] + abis=None, # type: Optional[List[str]] + implementation=None, # type: Optional[str] + ): + # type: (...) -> None + """ + :param platforms: A list of strings or None. If None, searches for + packages that are supported by the current system. Otherwise, will + find packages that can be built on the platforms passed in. These + packages will only be downloaded for distribution: they will + not be built locally. + :param py_version_info: An optional tuple of ints representing the + Python version information to use (e.g. `sys.version_info[:3]`). + This can have length 1, 2, or 3 when provided. + :param abis: A list of strings or None. This is passed to + compatibility_tags.py's get_supported() function as is. + :param implementation: A string or None. This is passed to + compatibility_tags.py's get_supported() function as is. + """ + # Store the given py_version_info for when we call get_supported(). + self._given_py_version_info = py_version_info + + if py_version_info is None: + py_version_info = sys.version_info[:3] + else: + py_version_info = normalize_version_info(py_version_info) + + py_version = '.'.join(map(str, py_version_info[:2])) + + self.abis = abis + self.implementation = implementation + self.platforms = platforms + self.py_version = py_version + self.py_version_info = py_version_info + + # This is used to cache the return value of get_tags(). + self._valid_tags = None # type: Optional[List[Tag]] + + def format_given(self): + # type: () -> str + """ + Format the given, non-None attributes for display. + """ + display_version = None + if self._given_py_version_info is not None: + display_version = '.'.join( + str(part) for part in self._given_py_version_info + ) + + key_values = [ + ('platforms', self.platforms), + ('version_info', display_version), + ('abis', self.abis), + ('implementation', self.implementation), + ] + return ' '.join( + f'{key}={value!r}' for key, value in key_values + if value is not None + ) + + def get_tags(self): + # type: () -> List[Tag] + """ + Return the supported PEP 425 tags to check wheel candidates against. + + The tags are returned in order of preference (most preferred first). + """ + if self._valid_tags is None: + # Pass versions=None if no py_version_info was given since + # versions=None uses special default logic. + py_version_info = self._given_py_version_info + if py_version_info is None: + version = None + else: + version = version_info_to_nodot(py_version_info) + + tags = get_supported( + version=version, + platforms=self.platforms, + abis=self.abis, + impl=self.implementation, + ) + self._valid_tags = tags + + return self._valid_tags diff --git a/venv/Lib/site-packages/pip/_internal/models/wheel.py b/venv/Lib/site-packages/pip/_internal/models/wheel.py new file mode 100644 index 0000000..5e03f9f --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/models/wheel.py @@ -0,0 +1,78 @@ +"""Represents a wheel file and provides access to the various parts of the +name that have meaning. +""" +import re + +from pip._vendor.packaging.tags import Tag + +from pip._internal.exceptions import InvalidWheelFilename +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import List + + +class Wheel: + """A wheel file""" + + wheel_file_re = re.compile( + r"""^(?P(?P.+?)-(?P.*?)) + ((-(?P\d[^-]*?))?-(?P.+?)-(?P.+?)-(?P.+?) + \.whl|\.dist-info)$""", + re.VERBOSE + ) + + def __init__(self, filename): + # type: (str) -> None + """ + :raises InvalidWheelFilename: when the filename is invalid for a wheel + """ + wheel_info = self.wheel_file_re.match(filename) + if not wheel_info: + raise InvalidWheelFilename( + f"{filename} is not a valid wheel filename." + ) + self.filename = filename + self.name = wheel_info.group('name').replace('_', '-') + # we'll assume "_" means "-" due to wheel naming scheme + # (https://github.com/pypa/pip/issues/1150) + self.version = wheel_info.group('ver').replace('_', '-') + self.build_tag = wheel_info.group('build') + self.pyversions = wheel_info.group('pyver').split('.') + self.abis = wheel_info.group('abi').split('.') + self.plats = wheel_info.group('plat').split('.') + + # All the tag combinations from this file + self.file_tags = { + Tag(x, y, z) for x in self.pyversions + for y in self.abis for z in self.plats + } + + def get_formatted_file_tags(self): + # type: () -> List[str] + """Return the wheel's tags as a sorted list of strings.""" + return sorted(str(tag) for tag in self.file_tags) + + def support_index_min(self, tags): + # type: (List[Tag]) -> int + """Return the lowest index that one of the wheel's file_tag combinations + achieves in the given list of supported tags. + + For example, if there are 8 supported tags and one of the file tags + is first in the list, then return 0. + + :param tags: the PEP 425 tags to check the wheel against, in order + with most preferred first. + + :raises ValueError: If none of the wheel's file tags match one of + the supported tags. + """ + return min(tags.index(tag) for tag in self.file_tags if tag in tags) + + def supported(self, tags): + # type: (List[Tag]) -> bool + """Return whether the wheel is compatible with one of the given tags. + + :param tags: the PEP 425 tags to check the wheel against. + """ + return not self.file_tags.isdisjoint(tags) diff --git a/venv/Lib/site-packages/pip/_internal/network/__init__.py b/venv/Lib/site-packages/pip/_internal/network/__init__.py new file mode 100644 index 0000000..b51bde9 --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/network/__init__.py @@ -0,0 +1,2 @@ +"""Contains purely network-related utilities. +""" diff --git a/venv/Lib/site-packages/pip/_internal/network/auth.py b/venv/Lib/site-packages/pip/_internal/network/auth.py new file mode 100644 index 0000000..174eb83 --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/network/auth.py @@ -0,0 +1,310 @@ +"""Network Authentication Helpers + +Contains interface (MultiDomainBasicAuth) and associated glue code for +providing credentials in the context of network requests. +""" + +import logging +import urllib.parse + +from pip._vendor.requests.auth import AuthBase, HTTPBasicAuth +from pip._vendor.requests.utils import get_netrc_auth + +from pip._internal.utils.misc import ( + ask, + ask_input, + ask_password, + remove_auth_from_url, + split_auth_netloc_from_url, +) +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import Any, Dict, List, Optional, Tuple + + from pip._vendor.requests.models import Request, Response + + from pip._internal.vcs.versioncontrol import AuthInfo + + Credentials = Tuple[str, str, str] + +logger = logging.getLogger(__name__) + +try: + import keyring +except ImportError: + keyring = None +except Exception as exc: + logger.warning( + "Keyring is skipped due to an exception: %s", str(exc), + ) + keyring = None + + +def get_keyring_auth(url, username): + # type: (str, str) -> Optional[AuthInfo] + """Return the tuple auth for a given url from keyring.""" + global keyring + if not url or not keyring: + return None + + try: + try: + get_credential = keyring.get_credential + except AttributeError: + pass + else: + logger.debug("Getting credentials from keyring for %s", url) + cred = get_credential(url, username) + if cred is not None: + return cred.username, cred.password + return None + + if username: + logger.debug("Getting password from keyring for %s", url) + password = keyring.get_password(url, username) + if password: + return username, password + + except Exception as exc: + logger.warning( + "Keyring is skipped due to an exception: %s", str(exc), + ) + keyring = None + return None + + +class MultiDomainBasicAuth(AuthBase): + + def __init__(self, prompting=True, index_urls=None): + # type: (bool, Optional[List[str]]) -> None + self.prompting = prompting + self.index_urls = index_urls + self.passwords = {} # type: Dict[str, AuthInfo] + # When the user is prompted to enter credentials and keyring is + # available, we will offer to save them. If the user accepts, + # this value is set to the credentials they entered. After the + # request authenticates, the caller should call + # ``save_credentials`` to save these. + self._credentials_to_save = None # type: Optional[Credentials] + + def _get_index_url(self, url): + # type: (str) -> Optional[str] + """Return the original index URL matching the requested URL. + + Cached or dynamically generated credentials may work against + the original index URL rather than just the netloc. + + The provided url should have had its username and password + removed already. If the original index url had credentials then + they will be included in the return value. + + Returns None if no matching index was found, or if --no-index + was specified by the user. + """ + if not url or not self.index_urls: + return None + + for u in self.index_urls: + prefix = remove_auth_from_url(u).rstrip("/") + "/" + if url.startswith(prefix): + return u + return None + + def _get_new_credentials(self, original_url, allow_netrc=True, + allow_keyring=True): + # type: (str, bool, bool) -> AuthInfo + """Find and return credentials for the specified URL.""" + # Split the credentials and netloc from the url. + url, netloc, url_user_password = split_auth_netloc_from_url( + original_url, + ) + + # Start with the credentials embedded in the url + username, password = url_user_password + if username is not None and password is not None: + logger.debug("Found credentials in url for %s", netloc) + return url_user_password + + # Find a matching index url for this request + index_url = self._get_index_url(url) + if index_url: + # Split the credentials from the url. + index_info = split_auth_netloc_from_url(index_url) + if index_info: + index_url, _, index_url_user_password = index_info + logger.debug("Found index url %s", index_url) + + # If an index URL was found, try its embedded credentials + if index_url and index_url_user_password[0] is not None: + username, password = index_url_user_password + if username is not None and password is not None: + logger.debug("Found credentials in index url for %s", netloc) + return index_url_user_password + + # Get creds from netrc if we still don't have them + if allow_netrc: + netrc_auth = get_netrc_auth(original_url) + if netrc_auth: + logger.debug("Found credentials in netrc for %s", netloc) + return netrc_auth + + # If we don't have a password and keyring is available, use it. + if allow_keyring: + # The index url is more specific than the netloc, so try it first + kr_auth = ( + get_keyring_auth(index_url, username) or + get_keyring_auth(netloc, username) + ) + if kr_auth: + logger.debug("Found credentials in keyring for %s", netloc) + return kr_auth + + return username, password + + def _get_url_and_credentials(self, original_url): + # type: (str) -> Tuple[str, Optional[str], Optional[str]] + """Return the credentials to use for the provided URL. + + If allowed, netrc and keyring may be used to obtain the + correct credentials. + + Returns (url_without_credentials, username, password). Note + that even if the original URL contains credentials, this + function may return a different username and password. + """ + url, netloc, _ = split_auth_netloc_from_url(original_url) + + # Use any stored credentials that we have for this netloc + username, password = self.passwords.get(netloc, (None, None)) + + if username is None and password is None: + # No stored credentials. Acquire new credentials without prompting + # the user. (e.g. from netrc, keyring, or the URL itself) + username, password = self._get_new_credentials(original_url) + + if username is not None or password is not None: + # Convert the username and password if they're None, so that + # this netloc will show up as "cached" in the conditional above. + # Further, HTTPBasicAuth doesn't accept None, so it makes sense to + # cache the value that is going to be used. + username = username or "" + password = password or "" + + # Store any acquired credentials. + self.passwords[netloc] = (username, password) + + assert ( + # Credentials were found + (username is not None and password is not None) or + # Credentials were not found + (username is None and password is None) + ), f"Could not load credentials from url: {original_url}" + + return url, username, password + + def __call__(self, req): + # type: (Request) -> Request + # Get credentials for this request + url, username, password = self._get_url_and_credentials(req.url) + + # Set the url of the request to the url without any credentials + req.url = url + + if username is not None and password is not None: + # Send the basic auth with this request + req = HTTPBasicAuth(username, password)(req) + + # Attach a hook to handle 401 responses + req.register_hook("response", self.handle_401) + + return req + + # Factored out to allow for easy patching in tests + def _prompt_for_password(self, netloc): + # type: (str) -> Tuple[Optional[str], Optional[str], bool] + username = ask_input(f"User for {netloc}: ") + if not username: + return None, None, False + auth = get_keyring_auth(netloc, username) + if auth and auth[0] is not None and auth[1] is not None: + return auth[0], auth[1], False + password = ask_password("Password: ") + return username, password, True + + # Factored out to allow for easy patching in tests + def _should_save_password_to_keyring(self): + # type: () -> bool + if not keyring: + return False + return ask("Save credentials to keyring [y/N]: ", ["y", "n"]) == "y" + + def handle_401(self, resp, **kwargs): + # type: (Response, **Any) -> Response + # We only care about 401 responses, anything else we want to just + # pass through the actual response + if resp.status_code != 401: + return resp + + # We are not able to prompt the user so simply return the response + if not self.prompting: + return resp + + parsed = urllib.parse.urlparse(resp.url) + + # Prompt the user for a new username and password + username, password, save = self._prompt_for_password(parsed.netloc) + + # Store the new username and password to use for future requests + self._credentials_to_save = None + if username is not None and password is not None: + self.passwords[parsed.netloc] = (username, password) + + # Prompt to save the password to keyring + if save and self._should_save_password_to_keyring(): + self._credentials_to_save = (parsed.netloc, username, password) + + # Consume content and release the original connection to allow our new + # request to reuse the same one. + resp.content + resp.raw.release_conn() + + # Add our new username and password to the request + req = HTTPBasicAuth(username or "", password or "")(resp.request) + req.register_hook("response", self.warn_on_401) + + # On successful request, save the credentials that were used to + # keyring. (Note that if the user responded "no" above, this member + # is not set and nothing will be saved.) + if self._credentials_to_save: + req.register_hook("response", self.save_credentials) + + # Send our new request + new_resp = resp.connection.send(req, **kwargs) + new_resp.history.append(resp) + + return new_resp + + def warn_on_401(self, resp, **kwargs): + # type: (Response, **Any) -> None + """Response callback to warn about incorrect credentials.""" + if resp.status_code == 401: + logger.warning( + '401 Error, Credentials not correct for %s', resp.request.url, + ) + + def save_credentials(self, resp, **kwargs): + # type: (Response, **Any) -> None + """Response callback to save credentials on success.""" + assert keyring is not None, "should never reach here without keyring" + if not keyring: + return + + creds = self._credentials_to_save + self._credentials_to_save = None + if creds and resp.status_code < 400: + try: + logger.info('Saving credentials to keyring') + keyring.set_password(*creds) + except Exception: + logger.exception('Failed to save credentials') diff --git a/venv/Lib/site-packages/pip/_internal/network/cache.py b/venv/Lib/site-packages/pip/_internal/network/cache.py new file mode 100644 index 0000000..9253b20 --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/network/cache.py @@ -0,0 +1,79 @@ +"""HTTP cache implementation. +""" + +import os +from contextlib import contextmanager + +from pip._vendor.cachecontrol.cache import BaseCache +from pip._vendor.cachecontrol.caches import FileCache +from pip._vendor.requests.models import Response + +from pip._internal.utils.filesystem import adjacent_tmp_file, replace +from pip._internal.utils.misc import ensure_dir +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import Iterator, Optional + + +def is_from_cache(response): + # type: (Response) -> bool + return getattr(response, "from_cache", False) + + +@contextmanager +def suppressed_cache_errors(): + # type: () -> Iterator[None] + """If we can't access the cache then we can just skip caching and process + requests as if caching wasn't enabled. + """ + try: + yield + except OSError: + pass + + +class SafeFileCache(BaseCache): + """ + A file based cache which is safe to use even when the target directory may + not be accessible or writable. + """ + + def __init__(self, directory): + # type: (str) -> None + assert directory is not None, "Cache directory must not be None." + super().__init__() + self.directory = directory + + def _get_cache_path(self, name): + # type: (str) -> str + # From cachecontrol.caches.file_cache.FileCache._fn, brought into our + # class for backwards-compatibility and to avoid using a non-public + # method. + hashed = FileCache.encode(name) + parts = list(hashed[:5]) + [hashed] + return os.path.join(self.directory, *parts) + + def get(self, key): + # type: (str) -> Optional[bytes] + path = self._get_cache_path(key) + with suppressed_cache_errors(): + with open(path, 'rb') as f: + return f.read() + + def set(self, key, value): + # type: (str, bytes) -> None + path = self._get_cache_path(key) + with suppressed_cache_errors(): + ensure_dir(os.path.dirname(path)) + + with adjacent_tmp_file(path) as f: + f.write(value) + + replace(f.name, path) + + def delete(self, key): + # type: (str) -> None + path = self._get_cache_path(key) + with suppressed_cache_errors(): + os.remove(path) diff --git a/venv/Lib/site-packages/pip/_internal/network/download.py b/venv/Lib/site-packages/pip/_internal/network/download.py new file mode 100644 index 0000000..3239657 --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/network/download.py @@ -0,0 +1,202 @@ +"""Download files with progress indicators. +""" +import cgi +import logging +import mimetypes +import os + +from pip._vendor.requests.models import CONTENT_CHUNK_SIZE + +from pip._internal.cli.progress_bars import DownloadProgressProvider +from pip._internal.exceptions import NetworkConnectionError +from pip._internal.models.index import PyPI +from pip._internal.network.cache import is_from_cache +from pip._internal.network.utils import HEADERS, raise_for_status, response_chunks +from pip._internal.utils.misc import format_size, redact_auth_from_url, splitext +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import Iterable, Optional, Tuple + + from pip._vendor.requests.models import Response + + from pip._internal.models.link import Link + from pip._internal.network.session import PipSession + +logger = logging.getLogger(__name__) + + +def _get_http_response_size(resp): + # type: (Response) -> Optional[int] + try: + return int(resp.headers['content-length']) + except (ValueError, KeyError, TypeError): + return None + + +def _prepare_download( + resp, # type: Response + link, # type: Link + progress_bar # type: str +): + # type: (...) -> Iterable[bytes] + total_length = _get_http_response_size(resp) + + if link.netloc == PyPI.file_storage_domain: + url = link.show_url + else: + url = link.url_without_fragment + + logged_url = redact_auth_from_url(url) + + if total_length: + logged_url = '{} ({})'.format(logged_url, format_size(total_length)) + + if is_from_cache(resp): + logger.info("Using cached %s", logged_url) + else: + logger.info("Downloading %s", logged_url) + + if logger.getEffectiveLevel() > logging.INFO: + show_progress = False + elif is_from_cache(resp): + show_progress = False + elif not total_length: + show_progress = True + elif total_length > (40 * 1000): + show_progress = True + else: + show_progress = False + + chunks = response_chunks(resp, CONTENT_CHUNK_SIZE) + + if not show_progress: + return chunks + + return DownloadProgressProvider( + progress_bar, max=total_length + )(chunks) + + +def sanitize_content_filename(filename): + # type: (str) -> str + """ + Sanitize the "filename" value from a Content-Disposition header. + """ + return os.path.basename(filename) + + +def parse_content_disposition(content_disposition, default_filename): + # type: (str, str) -> str + """ + Parse the "filename" value from a Content-Disposition header, and + return the default filename if the result is empty. + """ + _type, params = cgi.parse_header(content_disposition) + filename = params.get('filename') + if filename: + # We need to sanitize the filename to prevent directory traversal + # in case the filename contains ".." path parts. + filename = sanitize_content_filename(filename) + return filename or default_filename + + +def _get_http_response_filename(resp, link): + # type: (Response, Link) -> str + """Get an ideal filename from the given HTTP response, falling back to + the link filename if not provided. + """ + filename = link.filename # fallback + # Have a look at the Content-Disposition header for a better guess + content_disposition = resp.headers.get('content-disposition') + if content_disposition: + filename = parse_content_disposition(content_disposition, filename) + ext = splitext(filename)[1] # type: Optional[str] + if not ext: + ext = mimetypes.guess_extension( + resp.headers.get('content-type', '') + ) + if ext: + filename += ext + if not ext and link.url != resp.url: + ext = os.path.splitext(resp.url)[1] + if ext: + filename += ext + return filename + + +def _http_get_download(session, link): + # type: (PipSession, Link) -> Response + target_url = link.url.split('#', 1)[0] + resp = session.get(target_url, headers=HEADERS, stream=True) + raise_for_status(resp) + return resp + + +class Downloader: + def __init__( + self, + session, # type: PipSession + progress_bar, # type: str + ): + # type: (...) -> None + self._session = session + self._progress_bar = progress_bar + + def __call__(self, link, location): + # type: (Link, str) -> Tuple[str, str] + """Download the file given by link into location.""" + try: + resp = _http_get_download(self._session, link) + except NetworkConnectionError as e: + assert e.response is not None + logger.critical( + "HTTP error %s while getting %s", e.response.status_code, link + ) + raise + + filename = _get_http_response_filename(resp, link) + filepath = os.path.join(location, filename) + + chunks = _prepare_download(resp, link, self._progress_bar) + with open(filepath, 'wb') as content_file: + for chunk in chunks: + content_file.write(chunk) + content_type = resp.headers.get('Content-Type', '') + return filepath, content_type + + +class BatchDownloader: + + def __init__( + self, + session, # type: PipSession + progress_bar, # type: str + ): + # type: (...) -> None + self._session = session + self._progress_bar = progress_bar + + def __call__(self, links, location): + # type: (Iterable[Link], str) -> Iterable[Tuple[str, Tuple[str, str]]] + """Download the files given by links into location.""" + for link in links: + try: + resp = _http_get_download(self._session, link) + except NetworkConnectionError as e: + assert e.response is not None + logger.critical( + "HTTP error %s while getting %s", + e.response.status_code, link, + ) + raise + + filename = _get_http_response_filename(resp, link) + filepath = os.path.join(location, filename) + + chunks = _prepare_download(resp, link, self._progress_bar) + with open(filepath, 'wb') as content_file: + for chunk in chunks: + content_file.write(chunk) + content_type = resp.headers.get('Content-Type', '') + yield link.url, (filepath, content_type) diff --git a/venv/Lib/site-packages/pip/_internal/network/lazy_wheel.py b/venv/Lib/site-packages/pip/_internal/network/lazy_wheel.py new file mode 100644 index 0000000..c5176a4 --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/network/lazy_wheel.py @@ -0,0 +1,230 @@ +"""Lazy ZIP over HTTP""" + +__all__ = ['HTTPRangeRequestUnsupported', 'dist_from_wheel_url'] + +from bisect import bisect_left, bisect_right +from contextlib import contextmanager +from tempfile import NamedTemporaryFile +from zipfile import BadZipfile, ZipFile + +from pip._vendor.requests.models import CONTENT_CHUNK_SIZE + +from pip._internal.network.utils import HEADERS, raise_for_status, response_chunks +from pip._internal.utils.typing import MYPY_CHECK_RUNNING +from pip._internal.utils.wheel import pkg_resources_distribution_for_wheel + +if MYPY_CHECK_RUNNING: + from typing import Any, Dict, Iterator, List, Optional, Tuple + + from pip._vendor.pkg_resources import Distribution + from pip._vendor.requests.models import Response + + from pip._internal.network.session import PipSession + + +class HTTPRangeRequestUnsupported(Exception): + pass + + +def dist_from_wheel_url(name, url, session): + # type: (str, str, PipSession) -> Distribution + """Return a pkg_resources.Distribution from the given wheel URL. + + This uses HTTP range requests to only fetch the potion of the wheel + containing metadata, just enough for the object to be constructed. + If such requests are not supported, HTTPRangeRequestUnsupported + is raised. + """ + with LazyZipOverHTTP(url, session) as wheel: + # For read-only ZIP files, ZipFile only needs methods read, + # seek, seekable and tell, not the whole IO protocol. + zip_file = ZipFile(wheel) # type: ignore + # After context manager exit, wheel.name + # is an invalid file by intention. + return pkg_resources_distribution_for_wheel(zip_file, name, wheel.name) + + +class LazyZipOverHTTP: + """File-like object mapped to a ZIP file over HTTP. + + This uses HTTP range requests to lazily fetch the file's content, + which is supposed to be fed to ZipFile. If such requests are not + supported by the server, raise HTTPRangeRequestUnsupported + during initialization. + """ + + def __init__(self, url, session, chunk_size=CONTENT_CHUNK_SIZE): + # type: (str, PipSession, int) -> None + head = session.head(url, headers=HEADERS) + raise_for_status(head) + assert head.status_code == 200 + self._session, self._url, self._chunk_size = session, url, chunk_size + self._length = int(head.headers['Content-Length']) + self._file = NamedTemporaryFile() + self.truncate(self._length) + self._left = [] # type: List[int] + self._right = [] # type: List[int] + if 'bytes' not in head.headers.get('Accept-Ranges', 'none'): + raise HTTPRangeRequestUnsupported('range request is not supported') + self._check_zip() + + @property + def mode(self): + # type: () -> str + """Opening mode, which is always rb.""" + return 'rb' + + @property + def name(self): + # type: () -> str + """Path to the underlying file.""" + return self._file.name + + def seekable(self): + # type: () -> bool + """Return whether random access is supported, which is True.""" + return True + + def close(self): + # type: () -> None + """Close the file.""" + self._file.close() + + @property + def closed(self): + # type: () -> bool + """Whether the file is closed.""" + return self._file.closed + + def read(self, size=-1): + # type: (int) -> bytes + """Read up to size bytes from the object and return them. + + As a convenience, if size is unspecified or -1, + all bytes until EOF are returned. Fewer than + size bytes may be returned if EOF is reached. + """ + download_size = max(size, self._chunk_size) + start, length = self.tell(), self._length + stop = length if size < 0 else min(start+download_size, length) + start = max(0, stop-download_size) + self._download(start, stop-1) + return self._file.read(size) + + def readable(self): + # type: () -> bool + """Return whether the file is readable, which is True.""" + return True + + def seek(self, offset, whence=0): + # type: (int, int) -> int + """Change stream position and return the new absolute position. + + Seek to offset relative position indicated by whence: + * 0: Start of stream (the default). pos should be >= 0; + * 1: Current position - pos may be negative; + * 2: End of stream - pos usually negative. + """ + return self._file.seek(offset, whence) + + def tell(self): + # type: () -> int + """Return the current possition.""" + return self._file.tell() + + def truncate(self, size=None): + # type: (Optional[int]) -> int + """Resize the stream to the given size in bytes. + + If size is unspecified resize to the current position. + The current stream position isn't changed. + + Return the new file size. + """ + return self._file.truncate(size) + + def writable(self): + # type: () -> bool + """Return False.""" + return False + + def __enter__(self): + # type: () -> LazyZipOverHTTP + self._file.__enter__() + return self + + def __exit__(self, *exc): + # type: (*Any) -> Optional[bool] + return self._file.__exit__(*exc) + + @contextmanager + def _stay(self): + # type: ()-> Iterator[None] + """Return a context manager keeping the position. + + At the end of the block, seek back to original position. + """ + pos = self.tell() + try: + yield + finally: + self.seek(pos) + + def _check_zip(self): + # type: () -> None + """Check and download until the file is a valid ZIP.""" + end = self._length - 1 + for start in reversed(range(0, end, self._chunk_size)): + self._download(start, end) + with self._stay(): + try: + # For read-only ZIP files, ZipFile only needs + # methods read, seek, seekable and tell. + ZipFile(self) # type: ignore + except BadZipfile: + pass + else: + break + + def _stream_response(self, start, end, base_headers=HEADERS): + # type: (int, int, Dict[str, str]) -> Response + """Return HTTP response to a range request from start to end.""" + headers = base_headers.copy() + headers['Range'] = f'bytes={start}-{end}' + # TODO: Get range requests to be correctly cached + headers['Cache-Control'] = 'no-cache' + return self._session.get(self._url, headers=headers, stream=True) + + def _merge(self, start, end, left, right): + # type: (int, int, int, int) -> Iterator[Tuple[int, int]] + """Return an iterator of intervals to be fetched. + + Args: + start (int): Start of needed interval + end (int): End of needed interval + left (int): Index of first overlapping downloaded data + right (int): Index after last overlapping downloaded data + """ + lslice, rslice = self._left[left:right], self._right[left:right] + i = start = min([start]+lslice[:1]) + end = max([end]+rslice[-1:]) + for j, k in zip(lslice, rslice): + if j > i: + yield i, j-1 + i = k + 1 + if i <= end: + yield i, end + self._left[left:right], self._right[left:right] = [start], [end] + + def _download(self, start, end): + # type: (int, int) -> None + """Download bytes from start to end inclusively.""" + with self._stay(): + left = bisect_left(self._right, start) + right = bisect_right(self._left, end) + for start, end in self._merge(start, end, left, right): + response = self._stream_response(start, end) + response.raise_for_status() + self.seek(start) + for chunk in response_chunks(response, self._chunk_size): + self._file.write(chunk) diff --git a/venv/Lib/site-packages/pip/_internal/network/session.py b/venv/Lib/site-packages/pip/_internal/network/session.py new file mode 100644 index 0000000..5021b8e --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/network/session.py @@ -0,0 +1,424 @@ +"""PipSession and supporting code, containing all pip-specific +network request configuration and behavior. +""" + +# The following comment should be removed at some point in the future. +# mypy: disallow-untyped-defs=False + +import email.utils +import ipaddress +import json +import logging +import mimetypes +import os +import platform +import sys +import urllib.parse +import warnings + +from pip._vendor import requests, six, urllib3 +from pip._vendor.cachecontrol import CacheControlAdapter +from pip._vendor.requests.adapters import BaseAdapter, HTTPAdapter +from pip._vendor.requests.models import Response +from pip._vendor.requests.structures import CaseInsensitiveDict +from pip._vendor.urllib3.exceptions import InsecureRequestWarning + +from pip import __version__ +from pip._internal.network.auth import MultiDomainBasicAuth +from pip._internal.network.cache import SafeFileCache + +# Import ssl from compat so the initial import occurs in only one place. +from pip._internal.utils.compat import has_tls +from pip._internal.utils.glibc import libc_ver +from pip._internal.utils.misc import ( + build_url_from_netloc, + get_installed_version, + parse_netloc, +) +from pip._internal.utils.typing import MYPY_CHECK_RUNNING +from pip._internal.utils.urls import url_to_path + +if MYPY_CHECK_RUNNING: + from typing import Iterator, List, Optional, Tuple, Union + + from pip._internal.models.link import Link + + SecureOrigin = Tuple[str, str, Optional[Union[int, str]]] + + +logger = logging.getLogger(__name__) + + +# Ignore warning raised when using --trusted-host. +warnings.filterwarnings("ignore", category=InsecureRequestWarning) + + +SECURE_ORIGINS = [ + # protocol, hostname, port + # Taken from Chrome's list of secure origins (See: http://bit.ly/1qrySKC) + ("https", "*", "*"), + ("*", "localhost", "*"), + ("*", "127.0.0.0/8", "*"), + ("*", "::1/128", "*"), + ("file", "*", None), + # ssh is always secure. + ("ssh", "*", "*"), +] # type: List[SecureOrigin] + + +# These are environment variables present when running under various +# CI systems. For each variable, some CI systems that use the variable +# are indicated. The collection was chosen so that for each of a number +# of popular systems, at least one of the environment variables is used. +# This list is used to provide some indication of and lower bound for +# CI traffic to PyPI. Thus, it is okay if the list is not comprehensive. +# For more background, see: https://github.com/pypa/pip/issues/5499 +CI_ENVIRONMENT_VARIABLES = ( + # Azure Pipelines + 'BUILD_BUILDID', + # Jenkins + 'BUILD_ID', + # AppVeyor, CircleCI, Codeship, Gitlab CI, Shippable, Travis CI + 'CI', + # Explicit environment variable. + 'PIP_IS_CI', +) + + +def looks_like_ci(): + # type: () -> bool + """ + Return whether it looks like pip is running under CI. + """ + # We don't use the method of checking for a tty (e.g. using isatty()) + # because some CI systems mimic a tty (e.g. Travis CI). Thus that + # method doesn't provide definitive information in either direction. + return any(name in os.environ for name in CI_ENVIRONMENT_VARIABLES) + + +def user_agent(): + """ + Return a string representing the user agent. + """ + data = { + "installer": {"name": "pip", "version": __version__}, + "python": platform.python_version(), + "implementation": { + "name": platform.python_implementation(), + }, + } + + if data["implementation"]["name"] == 'CPython': + data["implementation"]["version"] = platform.python_version() + elif data["implementation"]["name"] == 'PyPy': + if sys.pypy_version_info.releaselevel == 'final': + pypy_version_info = sys.pypy_version_info[:3] + else: + pypy_version_info = sys.pypy_version_info + data["implementation"]["version"] = ".".join( + [str(x) for x in pypy_version_info] + ) + elif data["implementation"]["name"] == 'Jython': + # Complete Guess + data["implementation"]["version"] = platform.python_version() + elif data["implementation"]["name"] == 'IronPython': + # Complete Guess + data["implementation"]["version"] = platform.python_version() + + if sys.platform.startswith("linux"): + from pip._vendor import distro + distro_infos = dict(filter( + lambda x: x[1], + zip(["name", "version", "id"], distro.linux_distribution()), + )) + libc = dict(filter( + lambda x: x[1], + zip(["lib", "version"], libc_ver()), + )) + if libc: + distro_infos["libc"] = libc + if distro_infos: + data["distro"] = distro_infos + + if sys.platform.startswith("darwin") and platform.mac_ver()[0]: + data["distro"] = {"name": "macOS", "version": platform.mac_ver()[0]} + + if platform.system(): + data.setdefault("system", {})["name"] = platform.system() + + if platform.release(): + data.setdefault("system", {})["release"] = platform.release() + + if platform.machine(): + data["cpu"] = platform.machine() + + if has_tls(): + import _ssl as ssl + data["openssl_version"] = ssl.OPENSSL_VERSION + + setuptools_version = get_installed_version("setuptools") + if setuptools_version is not None: + data["setuptools_version"] = setuptools_version + + # Use None rather than False so as not to give the impression that + # pip knows it is not being run under CI. Rather, it is a null or + # inconclusive result. Also, we include some value rather than no + # value to make it easier to know that the check has been run. + data["ci"] = True if looks_like_ci() else None + + user_data = os.environ.get("PIP_USER_AGENT_USER_DATA") + if user_data is not None: + data["user_data"] = user_data + + return "{data[installer][name]}/{data[installer][version]} {json}".format( + data=data, + json=json.dumps(data, separators=(",", ":"), sort_keys=True), + ) + + +class LocalFSAdapter(BaseAdapter): + + def send(self, request, stream=None, timeout=None, verify=None, cert=None, + proxies=None): + pathname = url_to_path(request.url) + + resp = Response() + resp.status_code = 200 + resp.url = request.url + + try: + stats = os.stat(pathname) + except OSError as exc: + resp.status_code = 404 + resp.raw = exc + else: + modified = email.utils.formatdate(stats.st_mtime, usegmt=True) + content_type = mimetypes.guess_type(pathname)[0] or "text/plain" + resp.headers = CaseInsensitiveDict({ + "Content-Type": content_type, + "Content-Length": stats.st_size, + "Last-Modified": modified, + }) + + resp.raw = open(pathname, "rb") + resp.close = resp.raw.close + + return resp + + def close(self): + pass + + +class InsecureHTTPAdapter(HTTPAdapter): + + def cert_verify(self, conn, url, verify, cert): + super().cert_verify(conn=conn, url=url, verify=False, cert=cert) + + +class InsecureCacheControlAdapter(CacheControlAdapter): + + def cert_verify(self, conn, url, verify, cert): + super().cert_verify(conn=conn, url=url, verify=False, cert=cert) + + +class PipSession(requests.Session): + + timeout = None # type: Optional[int] + + def __init__(self, *args, **kwargs): + """ + :param trusted_hosts: Domains not to emit warnings for when not using + HTTPS. + """ + retries = kwargs.pop("retries", 0) + cache = kwargs.pop("cache", None) + trusted_hosts = kwargs.pop("trusted_hosts", []) # type: List[str] + index_urls = kwargs.pop("index_urls", None) + + super().__init__(*args, **kwargs) + + # Namespace the attribute with "pip_" just in case to prevent + # possible conflicts with the base class. + self.pip_trusted_origins = [] # type: List[Tuple[str, Optional[int]]] + + # Attach our User Agent to the request + self.headers["User-Agent"] = user_agent() + + # Attach our Authentication handler to the session + self.auth = MultiDomainBasicAuth(index_urls=index_urls) + + # Create our urllib3.Retry instance which will allow us to customize + # how we handle retries. + retries = urllib3.Retry( + # Set the total number of retries that a particular request can + # have. + total=retries, + + # A 503 error from PyPI typically means that the Fastly -> Origin + # connection got interrupted in some way. A 503 error in general + # is typically considered a transient error so we'll go ahead and + # retry it. + # A 500 may indicate transient error in Amazon S3 + # A 520 or 527 - may indicate transient error in CloudFlare + status_forcelist=[500, 503, 520, 527], + + # Add a small amount of back off between failed requests in + # order to prevent hammering the service. + backoff_factor=0.25, + ) + + # Our Insecure HTTPAdapter disables HTTPS validation. It does not + # support caching so we'll use it for all http:// URLs. + # If caching is disabled, we will also use it for + # https:// hosts that we've marked as ignoring + # TLS errors for (trusted-hosts). + insecure_adapter = InsecureHTTPAdapter(max_retries=retries) + + # We want to _only_ cache responses on securely fetched origins or when + # the host is specified as trusted. We do this because + # we can't validate the response of an insecurely/untrusted fetched + # origin, and we don't want someone to be able to poison the cache and + # require manual eviction from the cache to fix it. + if cache: + secure_adapter = CacheControlAdapter( + cache=SafeFileCache(cache), + max_retries=retries, + ) + self._trusted_host_adapter = InsecureCacheControlAdapter( + cache=SafeFileCache(cache), + max_retries=retries, + ) + else: + secure_adapter = HTTPAdapter(max_retries=retries) + self._trusted_host_adapter = insecure_adapter + + self.mount("https://", secure_adapter) + self.mount("http://", insecure_adapter) + + # Enable file:// urls + self.mount("file://", LocalFSAdapter()) + + for host in trusted_hosts: + self.add_trusted_host(host, suppress_logging=True) + + def update_index_urls(self, new_index_urls): + # type: (List[str]) -> None + """ + :param new_index_urls: New index urls to update the authentication + handler with. + """ + self.auth.index_urls = new_index_urls + + def add_trusted_host(self, host, source=None, suppress_logging=False): + # type: (str, Optional[str], bool) -> None + """ + :param host: It is okay to provide a host that has previously been + added. + :param source: An optional source string, for logging where the host + string came from. + """ + if not suppress_logging: + msg = f'adding trusted host: {host!r}' + if source is not None: + msg += f' (from {source})' + logger.info(msg) + + host_port = parse_netloc(host) + if host_port not in self.pip_trusted_origins: + self.pip_trusted_origins.append(host_port) + + self.mount( + build_url_from_netloc(host) + '/', + self._trusted_host_adapter + ) + if not host_port[1]: + # Mount wildcard ports for the same host. + self.mount( + build_url_from_netloc(host) + ':', + self._trusted_host_adapter + ) + + def iter_secure_origins(self): + # type: () -> Iterator[SecureOrigin] + yield from SECURE_ORIGINS + for host, port in self.pip_trusted_origins: + yield ('*', host, '*' if port is None else port) + + def is_secure_origin(self, location): + # type: (Link) -> bool + # Determine if this url used a secure transport mechanism + parsed = urllib.parse.urlparse(str(location)) + origin_protocol, origin_host, origin_port = ( + parsed.scheme, parsed.hostname, parsed.port, + ) + + # The protocol to use to see if the protocol matches. + # Don't count the repository type as part of the protocol: in + # cases such as "git+ssh", only use "ssh". (I.e., Only verify against + # the last scheme.) + origin_protocol = origin_protocol.rsplit('+', 1)[-1] + + # Determine if our origin is a secure origin by looking through our + # hardcoded list of secure origins, as well as any additional ones + # configured on this PackageFinder instance. + for secure_origin in self.iter_secure_origins(): + secure_protocol, secure_host, secure_port = secure_origin + if origin_protocol != secure_protocol and secure_protocol != "*": + continue + + try: + addr = ipaddress.ip_address( + None + if origin_host is None + else six.ensure_text(origin_host) + ) + network = ipaddress.ip_network( + six.ensure_text(secure_host) + ) + except ValueError: + # We don't have both a valid address or a valid network, so + # we'll check this origin against hostnames. + if ( + origin_host and + origin_host.lower() != secure_host.lower() and + secure_host != "*" + ): + continue + else: + # We have a valid address and network, so see if the address + # is contained within the network. + if addr not in network: + continue + + # Check to see if the port matches. + if ( + origin_port != secure_port and + secure_port != "*" and + secure_port is not None + ): + continue + + # If we've gotten here, then this origin matches the current + # secure origin and we should return True + return True + + # If we've gotten to this point, then the origin isn't secure and we + # will not accept it as a valid location to search. We will however + # log a warning that we are ignoring it. + logger.warning( + "The repository located at %s is not a trusted or secure host and " + "is being ignored. If this repository is available via HTTPS we " + "recommend you use HTTPS instead, otherwise you may silence " + "this warning and allow it anyway with '--trusted-host %s'.", + origin_host, + origin_host, + ) + + return False + + def request(self, method, url, *args, **kwargs): + # Allow setting a default timeout on a session + kwargs.setdefault("timeout", self.timeout) + + # Dispatch the actual request + return super().request(method, url, *args, **kwargs) diff --git a/venv/Lib/site-packages/pip/_internal/network/utils.py b/venv/Lib/site-packages/pip/_internal/network/utils.py new file mode 100644 index 0000000..f4ff950 --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/network/utils.py @@ -0,0 +1,97 @@ +from pip._vendor.requests.models import CONTENT_CHUNK_SIZE, Response + +from pip._internal.exceptions import NetworkConnectionError +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import Dict, Iterator + +# The following comments and HTTP headers were originally added by +# Donald Stufft in git commit 22c562429a61bb77172039e480873fb239dd8c03. +# +# We use Accept-Encoding: identity here because requests defaults to +# accepting compressed responses. This breaks in a variety of ways +# depending on how the server is configured. +# - Some servers will notice that the file isn't a compressible file +# and will leave the file alone and with an empty Content-Encoding +# - Some servers will notice that the file is already compressed and +# will leave the file alone, adding a Content-Encoding: gzip header +# - Some servers won't notice anything at all and will take a file +# that's already been compressed and compress it again, and set +# the Content-Encoding: gzip header +# By setting this to request only the identity encoding we're hoping +# to eliminate the third case. Hopefully there does not exist a server +# which when given a file will notice it is already compressed and that +# you're not asking for a compressed file and will then decompress it +# before sending because if that's the case I don't think it'll ever be +# possible to make this work. +HEADERS = {'Accept-Encoding': 'identity'} # type: Dict[str, str] + + +def raise_for_status(resp): + # type: (Response) -> None + http_error_msg = '' + if isinstance(resp.reason, bytes): + # We attempt to decode utf-8 first because some servers + # choose to localize their reason strings. If the string + # isn't utf-8, we fall back to iso-8859-1 for all other + # encodings. + try: + reason = resp.reason.decode('utf-8') + except UnicodeDecodeError: + reason = resp.reason.decode('iso-8859-1') + else: + reason = resp.reason + + if 400 <= resp.status_code < 500: + http_error_msg = '%s Client Error: %s for url: %s' % ( + resp.status_code, reason, resp.url) + + elif 500 <= resp.status_code < 600: + http_error_msg = '%s Server Error: %s for url: %s' % ( + resp.status_code, reason, resp.url) + + if http_error_msg: + raise NetworkConnectionError(http_error_msg, response=resp) + + +def response_chunks(response, chunk_size=CONTENT_CHUNK_SIZE): + # type: (Response, int) -> Iterator[bytes] + """Given a requests Response, provide the data chunks. + """ + try: + # Special case for urllib3. + for chunk in response.raw.stream( + chunk_size, + # We use decode_content=False here because we don't + # want urllib3 to mess with the raw bytes we get + # from the server. If we decompress inside of + # urllib3 then we cannot verify the checksum + # because the checksum will be of the compressed + # file. This breakage will only occur if the + # server adds a Content-Encoding header, which + # depends on how the server was configured: + # - Some servers will notice that the file isn't a + # compressible file and will leave the file alone + # and with an empty Content-Encoding + # - Some servers will notice that the file is + # already compressed and will leave the file + # alone and will add a Content-Encoding: gzip + # header + # - Some servers won't notice anything at all and + # will take a file that's already been compressed + # and compress it again and set the + # Content-Encoding: gzip header + # + # By setting this not to decode automatically we + # hope to eliminate problems with the second case. + decode_content=False, + ): + yield chunk + except AttributeError: + # Standard file-like object. + while True: + chunk = response.raw.read(chunk_size) + if not chunk: + break + yield chunk diff --git a/venv/Lib/site-packages/pip/_internal/network/xmlrpc.py b/venv/Lib/site-packages/pip/_internal/network/xmlrpc.py new file mode 100644 index 0000000..8749045 --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/network/xmlrpc.py @@ -0,0 +1,53 @@ +"""xmlrpclib.Transport implementation +""" + +import logging +import urllib.parse + +# NOTE: XMLRPC Client is not annotated in typeshed as on 2017-07-17, which is +# why we ignore the type on this import +from pip._vendor.six.moves import xmlrpc_client # type: ignore + +from pip._internal.exceptions import NetworkConnectionError +from pip._internal.network.utils import raise_for_status +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import Dict + + from pip._internal.network.session import PipSession + + +logger = logging.getLogger(__name__) + + +class PipXmlrpcTransport(xmlrpc_client.Transport): + """Provide a `xmlrpclib.Transport` implementation via a `PipSession` + object. + """ + + def __init__(self, index_url, session, use_datetime=False): + # type: (str, PipSession, bool) -> None + super().__init__(use_datetime) + index_parts = urllib.parse.urlparse(index_url) + self._scheme = index_parts.scheme + self._session = session + + def request(self, host, handler, request_body, verbose=False): + # type: (str, str, Dict[str, str], bool) -> None + parts = (self._scheme, host, handler, None, None, None) + url = urllib.parse.urlunparse(parts) + try: + headers = {'Content-Type': 'text/xml'} + response = self._session.post(url, data=request_body, + headers=headers, stream=True) + raise_for_status(response) + self.verbose = verbose + return self.parse_response(response.raw) + except NetworkConnectionError as exc: + assert exc.response + logger.critical( + "HTTP error %s while getting %s", + exc.response.status_code, url, + ) + raise diff --git a/venv/Lib/site-packages/pip/_internal/operations/__init__.py b/venv/Lib/site-packages/pip/_internal/operations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/venv/Lib/site-packages/pip/_internal/operations/check.py b/venv/Lib/site-packages/pip/_internal/operations/check.py new file mode 100644 index 0000000..5dee6bc --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/operations/check.py @@ -0,0 +1,155 @@ +"""Validation of dependencies of packages +""" + +import logging +from collections import namedtuple + +from pip._vendor.packaging.utils import canonicalize_name +from pip._vendor.pkg_resources import RequirementParseError + +from pip._internal.distributions import make_distribution_for_install_requirement +from pip._internal.utils.misc import get_installed_distributions +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +logger = logging.getLogger(__name__) + +if MYPY_CHECK_RUNNING: + from typing import Any, Callable, Dict, List, Optional, Set, Tuple + + from pip._internal.req.req_install import InstallRequirement + + # Shorthands + PackageSet = Dict[str, 'PackageDetails'] + Missing = Tuple[str, Any] + Conflicting = Tuple[str, str, Any] + + MissingDict = Dict[str, List[Missing]] + ConflictingDict = Dict[str, List[Conflicting]] + CheckResult = Tuple[MissingDict, ConflictingDict] + ConflictDetails = Tuple[PackageSet, CheckResult] + +PackageDetails = namedtuple('PackageDetails', ['version', 'requires']) + + +def create_package_set_from_installed(**kwargs): + # type: (**Any) -> Tuple[PackageSet, bool] + """Converts a list of distributions into a PackageSet. + """ + # Default to using all packages installed on the system + if kwargs == {}: + kwargs = {"local_only": False, "skip": ()} + + package_set = {} + problems = False + for dist in get_installed_distributions(**kwargs): + name = canonicalize_name(dist.project_name) + try: + package_set[name] = PackageDetails(dist.version, dist.requires()) + except (OSError, RequirementParseError) as e: + # Don't crash on unreadable or broken metadata + logger.warning("Error parsing requirements for %s: %s", name, e) + problems = True + return package_set, problems + + +def check_package_set(package_set, should_ignore=None): + # type: (PackageSet, Optional[Callable[[str], bool]]) -> CheckResult + """Check if a package set is consistent + + If should_ignore is passed, it should be a callable that takes a + package name and returns a boolean. + """ + + missing = {} + conflicting = {} + + for package_name in package_set: + # Info about dependencies of package_name + missing_deps = set() # type: Set[Missing] + conflicting_deps = set() # type: Set[Conflicting] + + if should_ignore and should_ignore(package_name): + continue + + for req in package_set[package_name].requires: + name = canonicalize_name(req.project_name) # type: str + + # Check if it's missing + if name not in package_set: + missed = True + if req.marker is not None: + missed = req.marker.evaluate() + if missed: + missing_deps.add((name, req)) + continue + + # Check if there's a conflict + version = package_set[name].version # type: str + if not req.specifier.contains(version, prereleases=True): + conflicting_deps.add((name, version, req)) + + if missing_deps: + missing[package_name] = sorted(missing_deps, key=str) + if conflicting_deps: + conflicting[package_name] = sorted(conflicting_deps, key=str) + + return missing, conflicting + + +def check_install_conflicts(to_install): + # type: (List[InstallRequirement]) -> ConflictDetails + """For checking if the dependency graph would be consistent after \ + installing given requirements + """ + # Start from the current state + package_set, _ = create_package_set_from_installed() + # Install packages + would_be_installed = _simulate_installation_of(to_install, package_set) + + # Only warn about directly-dependent packages; create a whitelist of them + whitelist = _create_whitelist(would_be_installed, package_set) + + return ( + package_set, + check_package_set( + package_set, should_ignore=lambda name: name not in whitelist + ) + ) + + +def _simulate_installation_of(to_install, package_set): + # type: (List[InstallRequirement], PackageSet) -> Set[str] + """Computes the version of packages after installing to_install. + """ + + # Keep track of packages that were installed + installed = set() + + # Modify it as installing requirement_set would (assuming no errors) + for inst_req in to_install: + abstract_dist = make_distribution_for_install_requirement(inst_req) + dist = abstract_dist.get_pkg_resources_distribution() + + assert dist is not None + name = canonicalize_name(dist.key) + package_set[name] = PackageDetails(dist.version, dist.requires()) + + installed.add(name) + + return installed + + +def _create_whitelist(would_be_installed, package_set): + # type: (Set[str], PackageSet) -> Set[str] + packages_affected = set(would_be_installed) + + for package_name in package_set: + if package_name in packages_affected: + continue + + for req in package_set[package_name].requires: + if canonicalize_name(req.name) in packages_affected: + packages_affected.add(package_name) + break + + return packages_affected diff --git a/venv/Lib/site-packages/pip/_internal/operations/freeze.py b/venv/Lib/site-packages/pip/_internal/operations/freeze.py new file mode 100644 index 0000000..5d63c12 --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/operations/freeze.py @@ -0,0 +1,270 @@ +import collections +import logging +import os + +from pip._vendor.packaging.utils import canonicalize_name +from pip._vendor.pkg_resources import RequirementParseError + +from pip._internal.exceptions import BadCommand, InstallationError +from pip._internal.req.constructors import ( + install_req_from_editable, + install_req_from_line, +) +from pip._internal.req.req_file import COMMENT_RE +from pip._internal.utils.direct_url_helpers import ( + direct_url_as_pep440_direct_reference, + dist_get_direct_url, +) +from pip._internal.utils.misc import dist_is_editable, get_installed_distributions +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import ( + Container, + Dict, + Iterable, + Iterator, + List, + Optional, + Set, + Tuple, + Union, + ) + + from pip._vendor.pkg_resources import Distribution, Requirement + + RequirementInfo = Tuple[Optional[Union[str, Requirement]], bool, List[str]] + + +logger = logging.getLogger(__name__) + + +def freeze( + requirement=None, # type: Optional[List[str]] + find_links=None, # type: Optional[List[str]] + local_only=False, # type: bool + user_only=False, # type: bool + paths=None, # type: Optional[List[str]] + isolated=False, # type: bool + exclude_editable=False, # type: bool + skip=() # type: Container[str] +): + # type: (...) -> Iterator[str] + find_links = find_links or [] + + for link in find_links: + yield f'-f {link}' + installations = {} # type: Dict[str, FrozenRequirement] + + for dist in get_installed_distributions( + local_only=local_only, + skip=(), + user_only=user_only, + paths=paths + ): + try: + req = FrozenRequirement.from_dist(dist) + except RequirementParseError as exc: + # We include dist rather than dist.project_name because the + # dist string includes more information, like the version and + # location. We also include the exception message to aid + # troubleshooting. + logger.warning( + 'Could not generate requirement for distribution %r: %s', + dist, exc + ) + continue + if exclude_editable and req.editable: + continue + installations[req.canonical_name] = req + + if requirement: + # the options that don't get turned into an InstallRequirement + # should only be emitted once, even if the same option is in multiple + # requirements files, so we need to keep track of what has been emitted + # so that we don't emit it again if it's seen again + emitted_options = set() # type: Set[str] + # keep track of which files a requirement is in so that we can + # give an accurate warning if a requirement appears multiple times. + req_files = collections.defaultdict(list) # type: Dict[str, List[str]] + for req_file_path in requirement: + with open(req_file_path) as req_file: + for line in req_file: + if (not line.strip() or + line.strip().startswith('#') or + line.startswith(( + '-r', '--requirement', + '-f', '--find-links', + '-i', '--index-url', + '--pre', + '--trusted-host', + '--process-dependency-links', + '--extra-index-url', + '--use-feature'))): + line = line.rstrip() + if line not in emitted_options: + emitted_options.add(line) + yield line + continue + + if line.startswith('-e') or line.startswith('--editable'): + if line.startswith('-e'): + line = line[2:].strip() + else: + line = line[len('--editable'):].strip().lstrip('=') + line_req = install_req_from_editable( + line, + isolated=isolated, + ) + else: + line_req = install_req_from_line( + COMMENT_RE.sub('', line).strip(), + isolated=isolated, + ) + + if not line_req.name: + logger.info( + "Skipping line in requirement file [%s] because " + "it's not clear what it would install: %s", + req_file_path, line.strip(), + ) + logger.info( + " (add #egg=PackageName to the URL to avoid" + " this warning)" + ) + else: + line_req_canonical_name = canonicalize_name( + line_req.name) + if line_req_canonical_name not in installations: + # either it's not installed, or it is installed + # but has been processed already + if not req_files[line_req.name]: + logger.warning( + "Requirement file [%s] contains %s, but " + "package %r is not installed", + req_file_path, + COMMENT_RE.sub('', line).strip(), + line_req.name + ) + else: + req_files[line_req.name].append(req_file_path) + else: + yield str(installations[ + line_req_canonical_name]).rstrip() + del installations[line_req_canonical_name] + req_files[line_req.name].append(req_file_path) + + # Warn about requirements that were included multiple times (in a + # single requirements file or in different requirements files). + for name, files in req_files.items(): + if len(files) > 1: + logger.warning("Requirement %s included multiple times [%s]", + name, ', '.join(sorted(set(files)))) + + yield( + '## The following requirements were added by ' + 'pip freeze:' + ) + for installation in sorted( + installations.values(), key=lambda x: x.name.lower()): + if installation.canonical_name not in skip: + yield str(installation).rstrip() + + +def get_requirement_info(dist): + # type: (Distribution) -> RequirementInfo + """ + Compute and return values (req, editable, comments) for use in + FrozenRequirement.from_dist(). + """ + if not dist_is_editable(dist): + return (None, False, []) + + location = os.path.normcase(os.path.abspath(dist.location)) + + from pip._internal.vcs import RemoteNotFoundError, vcs + vcs_backend = vcs.get_backend_for_dir(location) + + if vcs_backend is None: + req = dist.as_requirement() + logger.debug( + 'No VCS found for editable requirement "%s" in: %r', req, + location, + ) + comments = [ + f'# Editable install with no version control ({req})' + ] + return (location, True, comments) + + try: + req = vcs_backend.get_src_requirement(location, dist.project_name) + except RemoteNotFoundError: + req = dist.as_requirement() + comments = [ + '# Editable {} install with no remote ({})'.format( + type(vcs_backend).__name__, req, + ) + ] + return (location, True, comments) + + except BadCommand: + logger.warning( + 'cannot determine version of editable source in %s ' + '(%s command not found in path)', + location, + vcs_backend.name, + ) + return (None, True, []) + + except InstallationError as exc: + logger.warning( + "Error when trying to get requirement for VCS system %s, " + "falling back to uneditable format", exc + ) + else: + return (req, True, []) + + logger.warning( + 'Could not determine repository location of %s', location + ) + comments = ['## !! Could not determine repository location'] + + return (None, False, comments) + + +class FrozenRequirement: + def __init__(self, name, req, editable, comments=()): + # type: (str, Union[str, Requirement], bool, Iterable[str]) -> None + self.name = name + self.canonical_name = canonicalize_name(name) + self.req = req + self.editable = editable + self.comments = comments + + @classmethod + def from_dist(cls, dist): + # type: (Distribution) -> FrozenRequirement + # TODO `get_requirement_info` is taking care of editable requirements. + # TODO This should be refactored when we will add detection of + # editable that provide .dist-info metadata. + req, editable, comments = get_requirement_info(dist) + if req is None and not editable: + # if PEP 610 metadata is present, attempt to use it + direct_url = dist_get_direct_url(dist) + if direct_url: + req = direct_url_as_pep440_direct_reference( + direct_url, dist.project_name + ) + comments = [] + if req is None: + # name==version requirement + req = dist.as_requirement() + + return cls(dist.project_name, req, editable, comments=comments) + + def __str__(self): + # type: () -> str + req = self.req + if self.editable: + req = f'-e {req}' + return '\n'.join(list(self.comments) + [str(req)]) + '\n' diff --git a/venv/Lib/site-packages/pip/_internal/operations/install/__init__.py b/venv/Lib/site-packages/pip/_internal/operations/install/__init__.py new file mode 100644 index 0000000..24d6a5d --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/operations/install/__init__.py @@ -0,0 +1,2 @@ +"""For modules related to installing packages. +""" diff --git a/venv/Lib/site-packages/pip/_internal/operations/install/editable_legacy.py b/venv/Lib/site-packages/pip/_internal/operations/install/editable_legacy.py new file mode 100644 index 0000000..a668a61 --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/operations/install/editable_legacy.py @@ -0,0 +1,52 @@ +"""Legacy editable installation process, i.e. `setup.py develop`. +""" +import logging + +from pip._internal.utils.logging import indent_log +from pip._internal.utils.setuptools_build import make_setuptools_develop_args +from pip._internal.utils.subprocess import call_subprocess +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import List, Optional, Sequence + + from pip._internal.build_env import BuildEnvironment + + +logger = logging.getLogger(__name__) + + +def install_editable( + install_options, # type: List[str] + global_options, # type: Sequence[str] + prefix, # type: Optional[str] + home, # type: Optional[str] + use_user_site, # type: bool + name, # type: str + setup_py_path, # type: str + isolated, # type: bool + build_env, # type: BuildEnvironment + unpacked_source_directory, # type: str +): + # type: (...) -> None + """Install a package in editable mode. Most arguments are pass-through + to setuptools. + """ + logger.info('Running setup.py develop for %s', name) + + args = make_setuptools_develop_args( + setup_py_path, + global_options=global_options, + install_options=install_options, + no_user_config=isolated, + prefix=prefix, + home=home, + use_user_site=use_user_site, + ) + + with indent_log(): + with build_env: + call_subprocess( + args, + cwd=unpacked_source_directory, + ) diff --git a/venv/Lib/site-packages/pip/_internal/operations/install/legacy.py b/venv/Lib/site-packages/pip/_internal/operations/install/legacy.py new file mode 100644 index 0000000..63a693a --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/operations/install/legacy.py @@ -0,0 +1,130 @@ +"""Legacy installation process, i.e. `setup.py install`. +""" + +import logging +import os +import sys +from distutils.util import change_root + +from pip._internal.exceptions import InstallationError +from pip._internal.utils.logging import indent_log +from pip._internal.utils.misc import ensure_dir +from pip._internal.utils.setuptools_build import make_setuptools_install_args +from pip._internal.utils.subprocess import runner_with_spinner_message +from pip._internal.utils.temp_dir import TempDirectory +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import List, Optional, Sequence + + from pip._internal.build_env import BuildEnvironment + from pip._internal.models.scheme import Scheme + + +logger = logging.getLogger(__name__) + + +class LegacyInstallFailure(Exception): + def __init__(self): + # type: () -> None + self.parent = sys.exc_info() + + +def install( + install_options, # type: List[str] + global_options, # type: Sequence[str] + root, # type: Optional[str] + home, # type: Optional[str] + prefix, # type: Optional[str] + use_user_site, # type: bool + pycompile, # type: bool + scheme, # type: Scheme + setup_py_path, # type: str + isolated, # type: bool + req_name, # type: str + build_env, # type: BuildEnvironment + unpacked_source_directory, # type: str + req_description, # type: str +): + # type: (...) -> bool + + header_dir = scheme.headers + + with TempDirectory(kind="record") as temp_dir: + try: + record_filename = os.path.join(temp_dir.path, 'install-record.txt') + install_args = make_setuptools_install_args( + setup_py_path, + global_options=global_options, + install_options=install_options, + record_filename=record_filename, + root=root, + prefix=prefix, + header_dir=header_dir, + home=home, + use_user_site=use_user_site, + no_user_config=isolated, + pycompile=pycompile, + ) + + runner = runner_with_spinner_message( + f"Running setup.py install for {req_name}" + ) + with indent_log(), build_env: + runner( + cmd=install_args, + cwd=unpacked_source_directory, + ) + + if not os.path.exists(record_filename): + logger.debug('Record file %s not found', record_filename) + # Signal to the caller that we didn't install the new package + return False + + except Exception: + # Signal to the caller that we didn't install the new package + raise LegacyInstallFailure + + # At this point, we have successfully installed the requirement. + + # We intentionally do not use any encoding to read the file because + # setuptools writes the file using distutils.file_util.write_file, + # which does not specify an encoding. + with open(record_filename) as f: + record_lines = f.read().splitlines() + + def prepend_root(path): + # type: (str) -> str + if root is None or not os.path.isabs(path): + return path + else: + return change_root(root, path) + + for line in record_lines: + directory = os.path.dirname(line) + if directory.endswith('.egg-info'): + egg_info_dir = prepend_root(directory) + break + else: + message = ( + "{} did not indicate that it installed an " + ".egg-info directory. Only setup.py projects " + "generating .egg-info directories are supported." + ).format(req_description) + raise InstallationError(message) + + new_lines = [] + for line in record_lines: + filename = line.strip() + if os.path.isdir(filename): + filename += os.path.sep + new_lines.append( + os.path.relpath(prepend_root(filename), egg_info_dir) + ) + new_lines.sort() + ensure_dir(egg_info_dir) + inst_files_path = os.path.join(egg_info_dir, 'installed-files.txt') + with open(inst_files_path, 'w') as f: + f.write('\n'.join(new_lines) + '\n') + + return True diff --git a/venv/Lib/site-packages/pip/_internal/operations/install/wheel.py b/venv/Lib/site-packages/pip/_internal/operations/install/wheel.py new file mode 100644 index 0000000..37dcb61 --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/operations/install/wheel.py @@ -0,0 +1,828 @@ +"""Support for installing and building the "wheel" binary package format. +""" + +import collections +import compileall +import contextlib +import csv +import importlib +import logging +import os.path +import re +import shutil +import sys +import warnings +from base64 import urlsafe_b64encode +from itertools import chain, filterfalse, starmap +from zipfile import ZipFile + +from pip._vendor import pkg_resources +from pip._vendor.distlib.scripts import ScriptMaker +from pip._vendor.distlib.util import get_export_entry +from pip._vendor.six import ensure_str, ensure_text, reraise + +from pip._internal.exceptions import InstallationError +from pip._internal.locations import get_major_minor_version +from pip._internal.models.direct_url import DIRECT_URL_METADATA_NAME, DirectUrl +from pip._internal.models.scheme import SCHEME_KEYS +from pip._internal.utils.filesystem import adjacent_tmp_file, replace +from pip._internal.utils.misc import captured_stdout, ensure_dir, hash_file, partition +from pip._internal.utils.typing import MYPY_CHECK_RUNNING +from pip._internal.utils.unpacking import ( + current_umask, + is_within_directory, + set_extracted_file_to_default_mode_plus_executable, + zip_item_is_executable, +) +from pip._internal.utils.wheel import parse_wheel, pkg_resources_distribution_for_wheel + +# Use the custom cast function at runtime to make cast work, +# and import typing.cast when performing pre-commit and type +# checks +if not MYPY_CHECK_RUNNING: + from pip._internal.utils.typing import cast +else: + from email.message import Message + from typing import ( + IO, + Any, + BinaryIO, + Callable, + Dict, + Iterable, + Iterator, + List, + NewType, + Optional, + Protocol, + Sequence, + Set, + Tuple, + Union, + cast, + ) + from zipfile import ZipInfo + + from pip._vendor.pkg_resources import Distribution + + from pip._internal.models.scheme import Scheme + + RecordPath = NewType('RecordPath', str) + InstalledCSVRow = Tuple[RecordPath, str, Union[int, str]] + + class File(Protocol): + src_record_path = None # type: RecordPath + dest_path = None # type: str + changed = None # type: bool + + def save(self): + # type: () -> None + pass + + +logger = logging.getLogger(__name__) + + +def rehash(path, blocksize=1 << 20): + # type: (str, int) -> Tuple[str, str] + """Return (encoded_digest, length) for path using hashlib.sha256()""" + h, length = hash_file(path, blocksize) + digest = 'sha256=' + urlsafe_b64encode( + h.digest() + ).decode('latin1').rstrip('=') + return (digest, str(length)) + + +def csv_io_kwargs(mode): + # type: (str) -> Dict[str, Any] + """Return keyword arguments to properly open a CSV file + in the given mode. + """ + return {'mode': mode, 'newline': '', 'encoding': 'utf-8'} + + +def fix_script(path): + # type: (str) -> bool + """Replace #!python with #!/path/to/python + Return True if file was changed. + """ + # XXX RECORD hashes will need to be updated + assert os.path.isfile(path) + + with open(path, 'rb') as script: + firstline = script.readline() + if not firstline.startswith(b'#!python'): + return False + exename = sys.executable.encode(sys.getfilesystemencoding()) + firstline = b'#!' + exename + os.linesep.encode("ascii") + rest = script.read() + with open(path, 'wb') as script: + script.write(firstline) + script.write(rest) + return True + + +def wheel_root_is_purelib(metadata): + # type: (Message) -> bool + return metadata.get("Root-Is-Purelib", "").lower() == "true" + + +def get_entrypoints(distribution): + # type: (Distribution) -> Tuple[Dict[str, str], Dict[str, str]] + # get the entry points and then the script names + try: + console = distribution.get_entry_map('console_scripts') + gui = distribution.get_entry_map('gui_scripts') + except KeyError: + # Our dict-based Distribution raises KeyError if entry_points.txt + # doesn't exist. + return {}, {} + + def _split_ep(s): + # type: (pkg_resources.EntryPoint) -> Tuple[str, str] + """get the string representation of EntryPoint, + remove space and split on '=' + """ + split_parts = str(s).replace(" ", "").split("=") + return split_parts[0], split_parts[1] + + # convert the EntryPoint objects into strings with module:function + console = dict(_split_ep(v) for v in console.values()) + gui = dict(_split_ep(v) for v in gui.values()) + return console, gui + + +def message_about_scripts_not_on_PATH(scripts): + # type: (Sequence[str]) -> Optional[str] + """Determine if any scripts are not on PATH and format a warning. + Returns a warning message if one or more scripts are not on PATH, + otherwise None. + """ + if not scripts: + return None + + # Group scripts by the path they were installed in + grouped_by_dir = collections.defaultdict(set) # type: Dict[str, Set[str]] + for destfile in scripts: + parent_dir = os.path.dirname(destfile) + script_name = os.path.basename(destfile) + grouped_by_dir[parent_dir].add(script_name) + + # We don't want to warn for directories that are on PATH. + not_warn_dirs = [ + os.path.normcase(i).rstrip(os.sep) for i in + os.environ.get("PATH", "").split(os.pathsep) + ] + # If an executable sits with sys.executable, we don't warn for it. + # This covers the case of venv invocations without activating the venv. + not_warn_dirs.append(os.path.normcase(os.path.dirname(sys.executable))) + warn_for = { + parent_dir: scripts for parent_dir, scripts in grouped_by_dir.items() + if os.path.normcase(parent_dir) not in not_warn_dirs + } # type: Dict[str, Set[str]] + if not warn_for: + return None + + # Format a message + msg_lines = [] + for parent_dir, dir_scripts in warn_for.items(): + sorted_scripts = sorted(dir_scripts) # type: List[str] + if len(sorted_scripts) == 1: + start_text = "script {} is".format(sorted_scripts[0]) + else: + start_text = "scripts {} are".format( + ", ".join(sorted_scripts[:-1]) + " and " + sorted_scripts[-1] + ) + + msg_lines.append( + "The {} installed in '{}' which is not on PATH." + .format(start_text, parent_dir) + ) + + last_line_fmt = ( + "Consider adding {} to PATH or, if you prefer " + "to suppress this warning, use --no-warn-script-location." + ) + if len(msg_lines) == 1: + msg_lines.append(last_line_fmt.format("this directory")) + else: + msg_lines.append(last_line_fmt.format("these directories")) + + # Add a note if any directory starts with ~ + warn_for_tilde = any( + i[0] == "~" for i in os.environ.get("PATH", "").split(os.pathsep) if i + ) + if warn_for_tilde: + tilde_warning_msg = ( + "NOTE: The current PATH contains path(s) starting with `~`, " + "which may not be expanded by all applications." + ) + msg_lines.append(tilde_warning_msg) + + # Returns the formatted multiline message + return "\n".join(msg_lines) + + +def _normalized_outrows(outrows): + # type: (Iterable[InstalledCSVRow]) -> List[Tuple[str, str, str]] + """Normalize the given rows of a RECORD file. + + Items in each row are converted into str. Rows are then sorted to make + the value more predictable for tests. + + Each row is a 3-tuple (path, hash, size) and corresponds to a record of + a RECORD file (see PEP 376 and PEP 427 for details). For the rows + passed to this function, the size can be an integer as an int or string, + or the empty string. + """ + # Normally, there should only be one row per path, in which case the + # second and third elements don't come into play when sorting. + # However, in cases in the wild where a path might happen to occur twice, + # we don't want the sort operation to trigger an error (but still want + # determinism). Since the third element can be an int or string, we + # coerce each element to a string to avoid a TypeError in this case. + # For additional background, see-- + # https://github.com/pypa/pip/issues/5868 + return sorted( + (ensure_str(record_path, encoding='utf-8'), hash_, str(size)) + for record_path, hash_, size in outrows + ) + + +def _record_to_fs_path(record_path): + # type: (RecordPath) -> str + return record_path + + +def _fs_to_record_path(path, relative_to=None): + # type: (str, Optional[str]) -> RecordPath + if relative_to is not None: + # On Windows, do not handle relative paths if they belong to different + # logical disks + if os.path.splitdrive(path)[0].lower() == \ + os.path.splitdrive(relative_to)[0].lower(): + path = os.path.relpath(path, relative_to) + path = path.replace(os.path.sep, '/') + return cast('RecordPath', path) + + +def _parse_record_path(record_column): + # type: (str) -> RecordPath + p = ensure_text(record_column, encoding='utf-8') + return cast('RecordPath', p) + + +def get_csv_rows_for_installed( + old_csv_rows, # type: List[List[str]] + installed, # type: Dict[RecordPath, RecordPath] + changed, # type: Set[RecordPath] + generated, # type: List[str] + lib_dir, # type: str +): + # type: (...) -> List[InstalledCSVRow] + """ + :param installed: A map from archive RECORD path to installation RECORD + path. + """ + installed_rows = [] # type: List[InstalledCSVRow] + for row in old_csv_rows: + if len(row) > 3: + logger.warning('RECORD line has more than three elements: %s', row) + old_record_path = _parse_record_path(row[0]) + new_record_path = installed.pop(old_record_path, old_record_path) + if new_record_path in changed: + digest, length = rehash(_record_to_fs_path(new_record_path)) + else: + digest = row[1] if len(row) > 1 else '' + length = row[2] if len(row) > 2 else '' + installed_rows.append((new_record_path, digest, length)) + for f in generated: + path = _fs_to_record_path(f, lib_dir) + digest, length = rehash(f) + installed_rows.append((path, digest, length)) + for installed_record_path in installed.values(): + installed_rows.append((installed_record_path, '', '')) + return installed_rows + + +def get_console_script_specs(console): + # type: (Dict[str, str]) -> List[str] + """ + Given the mapping from entrypoint name to callable, return the relevant + console script specs. + """ + # Don't mutate caller's version + console = console.copy() + + scripts_to_generate = [] + + # Special case pip and setuptools to generate versioned wrappers + # + # The issue is that some projects (specifically, pip and setuptools) use + # code in setup.py to create "versioned" entry points - pip2.7 on Python + # 2.7, pip3.3 on Python 3.3, etc. But these entry points are baked into + # the wheel metadata at build time, and so if the wheel is installed with + # a *different* version of Python the entry points will be wrong. The + # correct fix for this is to enhance the metadata to be able to describe + # such versioned entry points, but that won't happen till Metadata 2.0 is + # available. + # In the meantime, projects using versioned entry points will either have + # incorrect versioned entry points, or they will not be able to distribute + # "universal" wheels (i.e., they will need a wheel per Python version). + # + # Because setuptools and pip are bundled with _ensurepip and virtualenv, + # we need to use universal wheels. So, as a stopgap until Metadata 2.0, we + # override the versioned entry points in the wheel and generate the + # correct ones. This code is purely a short-term measure until Metadata 2.0 + # is available. + # + # To add the level of hack in this section of code, in order to support + # ensurepip this code will look for an ``ENSUREPIP_OPTIONS`` environment + # variable which will control which version scripts get installed. + # + # ENSUREPIP_OPTIONS=altinstall + # - Only pipX.Y and easy_install-X.Y will be generated and installed + # ENSUREPIP_OPTIONS=install + # - pipX.Y, pipX, easy_install-X.Y will be generated and installed. Note + # that this option is technically if ENSUREPIP_OPTIONS is set and is + # not altinstall + # DEFAULT + # - The default behavior is to install pip, pipX, pipX.Y, easy_install + # and easy_install-X.Y. + pip_script = console.pop('pip', None) + if pip_script: + if "ENSUREPIP_OPTIONS" not in os.environ: + scripts_to_generate.append('pip = ' + pip_script) + + if os.environ.get("ENSUREPIP_OPTIONS", "") != "altinstall": + scripts_to_generate.append( + 'pip{} = {}'.format(sys.version_info[0], pip_script) + ) + + scripts_to_generate.append( + f'pip{get_major_minor_version()} = {pip_script}' + ) + # Delete any other versioned pip entry points + pip_ep = [k for k in console if re.match(r'pip(\d(\.\d)?)?$', k)] + for k in pip_ep: + del console[k] + easy_install_script = console.pop('easy_install', None) + if easy_install_script: + if "ENSUREPIP_OPTIONS" not in os.environ: + scripts_to_generate.append( + 'easy_install = ' + easy_install_script + ) + + scripts_to_generate.append( + 'easy_install-{} = {}'.format( + get_major_minor_version(), easy_install_script + ) + ) + # Delete any other versioned easy_install entry points + easy_install_ep = [ + k for k in console if re.match(r'easy_install(-\d\.\d)?$', k) + ] + for k in easy_install_ep: + del console[k] + + # Generate the console entry points specified in the wheel + scripts_to_generate.extend(starmap('{} = {}'.format, console.items())) + + return scripts_to_generate + + +class ZipBackedFile: + def __init__(self, src_record_path, dest_path, zip_file): + # type: (RecordPath, str, ZipFile) -> None + self.src_record_path = src_record_path + self.dest_path = dest_path + self._zip_file = zip_file + self.changed = False + + def _getinfo(self): + # type: () -> ZipInfo + return self._zip_file.getinfo(self.src_record_path) + + def save(self): + # type: () -> None + # directory creation is lazy and after file filtering + # to ensure we don't install empty dirs; empty dirs can't be + # uninstalled. + parent_dir = os.path.dirname(self.dest_path) + ensure_dir(parent_dir) + + # When we open the output file below, any existing file is truncated + # before we start writing the new contents. This is fine in most + # cases, but can cause a segfault if pip has loaded a shared + # object (e.g. from pyopenssl through its vendored urllib3) + # Since the shared object is mmap'd an attempt to call a + # symbol in it will then cause a segfault. Unlinking the file + # allows writing of new contents while allowing the process to + # continue to use the old copy. + if os.path.exists(self.dest_path): + os.unlink(self.dest_path) + + zipinfo = self._getinfo() + + with self._zip_file.open(zipinfo) as f: + with open(self.dest_path, "wb") as dest: + shutil.copyfileobj(f, dest) + + if zip_item_is_executable(zipinfo): + set_extracted_file_to_default_mode_plus_executable(self.dest_path) + + +class ScriptFile: + def __init__(self, file): + # type: (File) -> None + self._file = file + self.src_record_path = self._file.src_record_path + self.dest_path = self._file.dest_path + self.changed = False + + def save(self): + # type: () -> None + self._file.save() + self.changed = fix_script(self.dest_path) + + +class MissingCallableSuffix(InstallationError): + def __init__(self, entry_point): + # type: (str) -> None + super().__init__( + "Invalid script entry point: {} - A callable " + "suffix is required. Cf https://packaging.python.org/" + "specifications/entry-points/#use-for-scripts for more " + "information.".format(entry_point) + ) + + +def _raise_for_invalid_entrypoint(specification): + # type: (str) -> None + entry = get_export_entry(specification) + if entry is not None and entry.suffix is None: + raise MissingCallableSuffix(str(entry)) + + +class PipScriptMaker(ScriptMaker): + def make(self, specification, options=None): + # type: (str, Dict[str, Any]) -> List[str] + _raise_for_invalid_entrypoint(specification) + return super().make(specification, options) + + +def _install_wheel( + name, # type: str + wheel_zip, # type: ZipFile + wheel_path, # type: str + scheme, # type: Scheme + pycompile=True, # type: bool + warn_script_location=True, # type: bool + direct_url=None, # type: Optional[DirectUrl] + requested=False, # type: bool +): + # type: (...) -> None + """Install a wheel. + + :param name: Name of the project to install + :param wheel_zip: open ZipFile for wheel being installed + :param scheme: Distutils scheme dictating the install directories + :param req_description: String used in place of the requirement, for + logging + :param pycompile: Whether to byte-compile installed Python files + :param warn_script_location: Whether to check that scripts are installed + into a directory on PATH + :raises UnsupportedWheel: + * when the directory holds an unpacked wheel with incompatible + Wheel-Version + * when the .dist-info dir does not match the wheel + """ + info_dir, metadata = parse_wheel(wheel_zip, name) + + if wheel_root_is_purelib(metadata): + lib_dir = scheme.purelib + else: + lib_dir = scheme.platlib + + # Record details of the files moved + # installed = files copied from the wheel to the destination + # changed = files changed while installing (scripts #! line typically) + # generated = files newly generated during the install (script wrappers) + installed = {} # type: Dict[RecordPath, RecordPath] + changed = set() # type: Set[RecordPath] + generated = [] # type: List[str] + + def record_installed(srcfile, destfile, modified=False): + # type: (RecordPath, str, bool) -> None + """Map archive RECORD paths to installation RECORD paths.""" + newpath = _fs_to_record_path(destfile, lib_dir) + installed[srcfile] = newpath + if modified: + changed.add(_fs_to_record_path(destfile)) + + def all_paths(): + # type: () -> Iterable[RecordPath] + names = wheel_zip.namelist() + # If a flag is set, names may be unicode in Python 2. We convert to + # text explicitly so these are valid for lookup in RECORD. + decoded_names = map(ensure_text, names) + for name in decoded_names: + yield cast("RecordPath", name) + + def is_dir_path(path): + # type: (RecordPath) -> bool + return path.endswith("/") + + def assert_no_path_traversal(dest_dir_path, target_path): + # type: (str, str) -> None + if not is_within_directory(dest_dir_path, target_path): + message = ( + "The wheel {!r} has a file {!r} trying to install" + " outside the target directory {!r}" + ) + raise InstallationError( + message.format(wheel_path, target_path, dest_dir_path) + ) + + def root_scheme_file_maker(zip_file, dest): + # type: (ZipFile, str) -> Callable[[RecordPath], File] + def make_root_scheme_file(record_path): + # type: (RecordPath) -> File + normed_path = os.path.normpath(record_path) + dest_path = os.path.join(dest, normed_path) + assert_no_path_traversal(dest, dest_path) + return ZipBackedFile(record_path, dest_path, zip_file) + + return make_root_scheme_file + + def data_scheme_file_maker(zip_file, scheme): + # type: (ZipFile, Scheme) -> Callable[[RecordPath], File] + scheme_paths = {} + for key in SCHEME_KEYS: + encoded_key = ensure_text(key) + scheme_paths[encoded_key] = ensure_text( + getattr(scheme, key), encoding=sys.getfilesystemencoding() + ) + + def make_data_scheme_file(record_path): + # type: (RecordPath) -> File + normed_path = os.path.normpath(record_path) + try: + _, scheme_key, dest_subpath = normed_path.split(os.path.sep, 2) + except ValueError: + message = ( + "Unexpected file in {}: {!r}. .data directory contents" + " should be named like: '/'." + ).format(wheel_path, record_path) + raise InstallationError(message) + + try: + scheme_path = scheme_paths[scheme_key] + except KeyError: + valid_scheme_keys = ", ".join(sorted(scheme_paths)) + message = ( + "Unknown scheme key used in {}: {} (for file {!r}). .data" + " directory contents should be in subdirectories named" + " with a valid scheme key ({})" + ).format( + wheel_path, scheme_key, record_path, valid_scheme_keys + ) + raise InstallationError(message) + + dest_path = os.path.join(scheme_path, dest_subpath) + assert_no_path_traversal(scheme_path, dest_path) + return ZipBackedFile(record_path, dest_path, zip_file) + + return make_data_scheme_file + + def is_data_scheme_path(path): + # type: (RecordPath) -> bool + return path.split("/", 1)[0].endswith(".data") + + paths = all_paths() + file_paths = filterfalse(is_dir_path, paths) + root_scheme_paths, data_scheme_paths = partition( + is_data_scheme_path, file_paths + ) + + make_root_scheme_file = root_scheme_file_maker( + wheel_zip, + ensure_text(lib_dir, encoding=sys.getfilesystemencoding()), + ) + files = map(make_root_scheme_file, root_scheme_paths) + + def is_script_scheme_path(path): + # type: (RecordPath) -> bool + parts = path.split("/", 2) + return ( + len(parts) > 2 and + parts[0].endswith(".data") and + parts[1] == "scripts" + ) + + other_scheme_paths, script_scheme_paths = partition( + is_script_scheme_path, data_scheme_paths + ) + + make_data_scheme_file = data_scheme_file_maker(wheel_zip, scheme) + other_scheme_files = map(make_data_scheme_file, other_scheme_paths) + files = chain(files, other_scheme_files) + + # Get the defined entry points + distribution = pkg_resources_distribution_for_wheel( + wheel_zip, name, wheel_path + ) + console, gui = get_entrypoints(distribution) + + def is_entrypoint_wrapper(file): + # type: (File) -> bool + # EP, EP.exe and EP-script.py are scripts generated for + # entry point EP by setuptools + path = file.dest_path + name = os.path.basename(path) + if name.lower().endswith('.exe'): + matchname = name[:-4] + elif name.lower().endswith('-script.py'): + matchname = name[:-10] + elif name.lower().endswith(".pya"): + matchname = name[:-4] + else: + matchname = name + # Ignore setuptools-generated scripts + return (matchname in console or matchname in gui) + + script_scheme_files = map(make_data_scheme_file, script_scheme_paths) + script_scheme_files = filterfalse( + is_entrypoint_wrapper, script_scheme_files + ) + script_scheme_files = map(ScriptFile, script_scheme_files) + files = chain(files, script_scheme_files) + + for file in files: + file.save() + record_installed(file.src_record_path, file.dest_path, file.changed) + + def pyc_source_file_paths(): + # type: () -> Iterator[str] + # We de-duplicate installation paths, since there can be overlap (e.g. + # file in .data maps to same location as file in wheel root). + # Sorting installation paths makes it easier to reproduce and debug + # issues related to permissions on existing files. + for installed_path in sorted(set(installed.values())): + full_installed_path = os.path.join(lib_dir, installed_path) + if not os.path.isfile(full_installed_path): + continue + if not full_installed_path.endswith('.py'): + continue + yield full_installed_path + + def pyc_output_path(path): + # type: (str) -> str + """Return the path the pyc file would have been written to. + """ + return importlib.util.cache_from_source(path) + + # Compile all of the pyc files for the installed files + if pycompile: + with captured_stdout() as stdout: + with warnings.catch_warnings(): + warnings.filterwarnings('ignore') + for path in pyc_source_file_paths(): + # Python 2's `compileall.compile_file` requires a str in + # error cases, so we must convert to the native type. + path_arg = ensure_str( + path, encoding=sys.getfilesystemencoding() + ) + success = compileall.compile_file( + path_arg, force=True, quiet=True + ) + if success: + pyc_path = pyc_output_path(path) + assert os.path.exists(pyc_path) + pyc_record_path = cast( + "RecordPath", pyc_path.replace(os.path.sep, "/") + ) + record_installed(pyc_record_path, pyc_path) + logger.debug(stdout.getvalue()) + + maker = PipScriptMaker(None, scheme.scripts) + + # Ensure old scripts are overwritten. + # See https://github.com/pypa/pip/issues/1800 + maker.clobber = True + + # Ensure we don't generate any variants for scripts because this is almost + # never what somebody wants. + # See https://bitbucket.org/pypa/distlib/issue/35/ + maker.variants = {''} + + # This is required because otherwise distlib creates scripts that are not + # executable. + # See https://bitbucket.org/pypa/distlib/issue/32/ + maker.set_mode = True + + # Generate the console and GUI entry points specified in the wheel + scripts_to_generate = get_console_script_specs(console) + + gui_scripts_to_generate = list(starmap('{} = {}'.format, gui.items())) + + generated_console_scripts = maker.make_multiple(scripts_to_generate) + generated.extend(generated_console_scripts) + + generated.extend( + maker.make_multiple(gui_scripts_to_generate, {'gui': True}) + ) + + if warn_script_location: + msg = message_about_scripts_not_on_PATH(generated_console_scripts) + if msg is not None: + logger.warning(msg) + + generated_file_mode = 0o666 & ~current_umask() + + @contextlib.contextmanager + def _generate_file(path, **kwargs): + # type: (str, **Any) -> Iterator[BinaryIO] + with adjacent_tmp_file(path, **kwargs) as f: + yield f + os.chmod(f.name, generated_file_mode) + replace(f.name, path) + + dest_info_dir = os.path.join(lib_dir, info_dir) + + # Record pip as the installer + installer_path = os.path.join(dest_info_dir, 'INSTALLER') + with _generate_file(installer_path) as installer_file: + installer_file.write(b'pip\n') + generated.append(installer_path) + + # Record the PEP 610 direct URL reference + if direct_url is not None: + direct_url_path = os.path.join(dest_info_dir, DIRECT_URL_METADATA_NAME) + with _generate_file(direct_url_path) as direct_url_file: + direct_url_file.write(direct_url.to_json().encode("utf-8")) + generated.append(direct_url_path) + + # Record the REQUESTED file + if requested: + requested_path = os.path.join(dest_info_dir, 'REQUESTED') + with open(requested_path, "w"): + pass + generated.append(requested_path) + + record_text = distribution.get_metadata('RECORD') + record_rows = list(csv.reader(record_text.splitlines())) + + rows = get_csv_rows_for_installed( + record_rows, + installed=installed, + changed=changed, + generated=generated, + lib_dir=lib_dir) + + # Record details of all files installed + record_path = os.path.join(dest_info_dir, 'RECORD') + + with _generate_file(record_path, **csv_io_kwargs('w')) as record_file: + # The type mypy infers for record_file is different for Python 3 + # (typing.IO[Any]) and Python 2 (typing.BinaryIO). We explicitly + # cast to typing.IO[str] as a workaround. + writer = csv.writer(cast('IO[str]', record_file)) + writer.writerows(_normalized_outrows(rows)) + + +@contextlib.contextmanager +def req_error_context(req_description): + # type: (str) -> Iterator[None] + try: + yield + except InstallationError as e: + message = "For req: {}. {}".format(req_description, e.args[0]) + reraise( + InstallationError, InstallationError(message), sys.exc_info()[2] + ) + + +def install_wheel( + name, # type: str + wheel_path, # type: str + scheme, # type: Scheme + req_description, # type: str + pycompile=True, # type: bool + warn_script_location=True, # type: bool + direct_url=None, # type: Optional[DirectUrl] + requested=False, # type: bool +): + # type: (...) -> None + with ZipFile(wheel_path, allowZip64=True) as z: + with req_error_context(req_description): + _install_wheel( + name=name, + wheel_zip=z, + wheel_path=wheel_path, + scheme=scheme, + pycompile=pycompile, + warn_script_location=warn_script_location, + direct_url=direct_url, + requested=requested, + ) diff --git a/venv/Lib/site-packages/pip/_internal/operations/prepare.py b/venv/Lib/site-packages/pip/_internal/operations/prepare.py new file mode 100644 index 0000000..dd66fc2 --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/operations/prepare.py @@ -0,0 +1,585 @@ +"""Prepares a distribution for installation +""" + +# The following comment should be removed at some point in the future. +# mypy: strict-optional=False + +import logging +import mimetypes +import os +import shutil + +from pip._vendor.packaging.utils import canonicalize_name + +from pip._internal.distributions import make_distribution_for_install_requirement +from pip._internal.distributions.installed import InstalledDistribution +from pip._internal.exceptions import ( + DirectoryUrlHashUnsupported, + HashMismatch, + HashUnpinned, + InstallationError, + NetworkConnectionError, + PreviousBuildDirError, + VcsHashUnsupported, +) +from pip._internal.models.wheel import Wheel +from pip._internal.network.download import BatchDownloader, Downloader +from pip._internal.network.lazy_wheel import ( + HTTPRangeRequestUnsupported, + dist_from_wheel_url, +) +from pip._internal.utils.filesystem import copy2_fixed +from pip._internal.utils.hashes import MissingHashes +from pip._internal.utils.logging import indent_log +from pip._internal.utils.misc import display_path, hide_url, path_to_display, rmtree +from pip._internal.utils.temp_dir import TempDirectory +from pip._internal.utils.typing import MYPY_CHECK_RUNNING +from pip._internal.utils.unpacking import unpack_file +from pip._internal.vcs import vcs + +if MYPY_CHECK_RUNNING: + from typing import Dict, Iterable, List, Optional, Tuple + + from pip._vendor.pkg_resources import Distribution + + from pip._internal.index.package_finder import PackageFinder + from pip._internal.models.link import Link + from pip._internal.network.session import PipSession + from pip._internal.req.req_install import InstallRequirement + from pip._internal.req.req_tracker import RequirementTracker + from pip._internal.utils.hashes import Hashes + + +logger = logging.getLogger(__name__) + + +def _get_prepared_distribution( + req, # type: InstallRequirement + req_tracker, # type: RequirementTracker + finder, # type: PackageFinder + build_isolation, # type: bool +): + # type: (...) -> Distribution + """Prepare a distribution for installation.""" + abstract_dist = make_distribution_for_install_requirement(req) + with req_tracker.track(req): + abstract_dist.prepare_distribution_metadata(finder, build_isolation) + return abstract_dist.get_pkg_resources_distribution() + + +def unpack_vcs_link(link, location): + # type: (Link, str) -> None + vcs_backend = vcs.get_backend_for_scheme(link.scheme) + assert vcs_backend is not None + vcs_backend.unpack(location, url=hide_url(link.url)) + + +class File: + + def __init__(self, path, content_type): + # type: (str, Optional[str]) -> None + self.path = path + if content_type is None: + self.content_type = mimetypes.guess_type(path)[0] + else: + self.content_type = content_type + + +def get_http_url( + link, # type: Link + download, # type: Downloader + download_dir=None, # type: Optional[str] + hashes=None, # type: Optional[Hashes] +): + # type: (...) -> File + temp_dir = TempDirectory(kind="unpack", globally_managed=True) + # If a download dir is specified, is the file already downloaded there? + already_downloaded_path = None + if download_dir: + already_downloaded_path = _check_download_dir( + link, download_dir, hashes + ) + + if already_downloaded_path: + from_path = already_downloaded_path + content_type = None + else: + # let's download to a tmp dir + from_path, content_type = download(link, temp_dir.path) + if hashes: + hashes.check_against_path(from_path) + + return File(from_path, content_type) + + +def _copy2_ignoring_special_files(src, dest): + # type: (str, str) -> None + """Copying special files is not supported, but as a convenience to users + we skip errors copying them. This supports tools that may create e.g. + socket files in the project source directory. + """ + try: + copy2_fixed(src, dest) + except shutil.SpecialFileError as e: + # SpecialFileError may be raised due to either the source or + # destination. If the destination was the cause then we would actually + # care, but since the destination directory is deleted prior to + # copy we ignore all of them assuming it is caused by the source. + logger.warning( + "Ignoring special file error '%s' encountered copying %s to %s.", + str(e), + path_to_display(src), + path_to_display(dest), + ) + + +def _copy_source_tree(source, target): + # type: (str, str) -> None + target_abspath = os.path.abspath(target) + target_basename = os.path.basename(target_abspath) + target_dirname = os.path.dirname(target_abspath) + + def ignore(d, names): + # type: (str, List[str]) -> List[str] + skipped = [] # type: List[str] + if d == source: + # Pulling in those directories can potentially be very slow, + # exclude the following directories if they appear in the top + # level dir (and only it). + # See discussion at https://github.com/pypa/pip/pull/6770 + skipped += ['.tox', '.nox'] + if os.path.abspath(d) == target_dirname: + # Prevent an infinite recursion if the target is in source. + # This can happen when TMPDIR is set to ${PWD}/... + # and we copy PWD to TMPDIR. + skipped += [target_basename] + return skipped + + shutil.copytree( + source, + target, + ignore=ignore, + symlinks=True, + copy_function=_copy2_ignoring_special_files, + ) + + +def get_file_url( + link, # type: Link + download_dir=None, # type: Optional[str] + hashes=None # type: Optional[Hashes] +): + # type: (...) -> File + """Get file and optionally check its hash. + """ + # If a download dir is specified, is the file already there and valid? + already_downloaded_path = None + if download_dir: + already_downloaded_path = _check_download_dir( + link, download_dir, hashes + ) + + if already_downloaded_path: + from_path = already_downloaded_path + else: + from_path = link.file_path + + # If --require-hashes is off, `hashes` is either empty, the + # link's embedded hash, or MissingHashes; it is required to + # match. If --require-hashes is on, we are satisfied by any + # hash in `hashes` matching: a URL-based or an option-based + # one; no internet-sourced hash will be in `hashes`. + if hashes: + hashes.check_against_path(from_path) + return File(from_path, None) + + +def unpack_url( + link, # type: Link + location, # type: str + download, # type: Downloader + download_dir=None, # type: Optional[str] + hashes=None, # type: Optional[Hashes] +): + # type: (...) -> Optional[File] + """Unpack link into location, downloading if required. + + :param hashes: A Hashes object, one of whose embedded hashes must match, + or HashMismatch will be raised. If the Hashes is empty, no matches are + required, and unhashable types of requirements (like VCS ones, which + would ordinarily raise HashUnsupported) are allowed. + """ + # non-editable vcs urls + if link.is_vcs: + unpack_vcs_link(link, location) + return None + + # If it's a url to a local directory + if link.is_existing_dir(): + if os.path.isdir(location): + rmtree(location) + _copy_source_tree(link.file_path, location) + return None + + # file urls + if link.is_file: + file = get_file_url(link, download_dir, hashes=hashes) + + # http urls + else: + file = get_http_url( + link, + download, + download_dir, + hashes=hashes, + ) + + # unpack the archive to the build dir location. even when only downloading + # archives, they have to be unpacked to parse dependencies, except wheels + if not link.is_wheel: + unpack_file(file.path, location, file.content_type) + + return file + + +def _check_download_dir(link, download_dir, hashes): + # type: (Link, str, Optional[Hashes]) -> Optional[str] + """ Check download_dir for previously downloaded file with correct hash + If a correct file is found return its path else None + """ + download_path = os.path.join(download_dir, link.filename) + + if not os.path.exists(download_path): + return None + + # If already downloaded, does its hash match? + logger.info('File was already downloaded %s', download_path) + if hashes: + try: + hashes.check_against_path(download_path) + except HashMismatch: + logger.warning( + 'Previously-downloaded file %s has bad hash. ' + 'Re-downloading.', + download_path + ) + os.unlink(download_path) + return None + return download_path + + +class RequirementPreparer: + """Prepares a Requirement + """ + + def __init__( + self, + build_dir, # type: str + download_dir, # type: Optional[str] + src_dir, # type: str + build_isolation, # type: bool + req_tracker, # type: RequirementTracker + session, # type: PipSession + progress_bar, # type: str + finder, # type: PackageFinder + require_hashes, # type: bool + use_user_site, # type: bool + lazy_wheel, # type: bool + ): + # type: (...) -> None + super().__init__() + + self.src_dir = src_dir + self.build_dir = build_dir + self.req_tracker = req_tracker + self._session = session + self._download = Downloader(session, progress_bar) + self._batch_download = BatchDownloader(session, progress_bar) + self.finder = finder + + # Where still-packed archives should be written to. If None, they are + # not saved, and are deleted immediately after unpacking. + self.download_dir = download_dir + + # Is build isolation allowed? + self.build_isolation = build_isolation + + # Should hash-checking be required? + self.require_hashes = require_hashes + + # Should install in user site-packages? + self.use_user_site = use_user_site + + # Should wheels be downloaded lazily? + self.use_lazy_wheel = lazy_wheel + + # Memoized downloaded files, as mapping of url: (path, mime type) + self._downloaded = {} # type: Dict[str, Tuple[str, str]] + + # Previous "header" printed for a link-based InstallRequirement + self._previous_requirement_header = ("", "") + + def _log_preparing_link(self, req): + # type: (InstallRequirement) -> None + """Provide context for the requirement being prepared.""" + if req.link.is_file and not req.original_link_is_in_wheel_cache: + message = "Processing %s" + information = str(display_path(req.link.file_path)) + else: + message = "Collecting %s" + information = str(req.req or req) + + if (message, information) != self._previous_requirement_header: + self._previous_requirement_header = (message, information) + logger.info(message, information) + + if req.original_link_is_in_wheel_cache: + with indent_log(): + logger.info("Using cached %s", req.link.filename) + + def _ensure_link_req_src_dir(self, req, parallel_builds): + # type: (InstallRequirement, bool) -> None + """Ensure source_dir of a linked InstallRequirement.""" + # Since source_dir is only set for editable requirements. + if req.link.is_wheel: + # We don't need to unpack wheels, so no need for a source + # directory. + return + assert req.source_dir is None + # We always delete unpacked sdists after pip runs. + req.ensure_has_source_dir( + self.build_dir, + autodelete=True, + parallel_builds=parallel_builds, + ) + + # If a checkout exists, it's unwise to keep going. version + # inconsistencies are logged later, but do not fail the + # installation. + # FIXME: this won't upgrade when there's an existing + # package unpacked in `req.source_dir` + if os.path.exists(os.path.join(req.source_dir, 'setup.py')): + raise PreviousBuildDirError( + "pip can't proceed with requirements '{}' due to a" + "pre-existing build directory ({}). This is likely " + "due to a previous installation that failed . pip is " + "being responsible and not assuming it can delete this. " + "Please delete it and try again.".format(req, req.source_dir) + ) + + def _get_linked_req_hashes(self, req): + # type: (InstallRequirement) -> Hashes + # By the time this is called, the requirement's link should have + # been checked so we can tell what kind of requirements req is + # and raise some more informative errors than otherwise. + # (For example, we can raise VcsHashUnsupported for a VCS URL + # rather than HashMissing.) + if not self.require_hashes: + return req.hashes(trust_internet=True) + + # We could check these first 2 conditions inside unpack_url + # and save repetition of conditions, but then we would + # report less-useful error messages for unhashable + # requirements, complaining that there's no hash provided. + if req.link.is_vcs: + raise VcsHashUnsupported() + if req.link.is_existing_dir(): + raise DirectoryUrlHashUnsupported() + + # Unpinned packages are asking for trouble when a new version + # is uploaded. This isn't a security check, but it saves users + # a surprising hash mismatch in the future. + # file:/// URLs aren't pinnable, so don't complain about them + # not being pinned. + if req.original_link is None and not req.is_pinned: + raise HashUnpinned() + + # If known-good hashes are missing for this requirement, + # shim it with a facade object that will provoke hash + # computation and then raise a HashMissing exception + # showing the user what the hash should be. + return req.hashes(trust_internet=False) or MissingHashes() + + def _fetch_metadata_using_lazy_wheel(self, link): + # type: (Link) -> Optional[Distribution] + """Fetch metadata using lazy wheel, if possible.""" + if not self.use_lazy_wheel: + return None + if self.require_hashes: + logger.debug('Lazy wheel is not used as hash checking is required') + return None + if link.is_file or not link.is_wheel: + logger.debug( + 'Lazy wheel is not used as ' + '%r does not points to a remote wheel', + link, + ) + return None + + wheel = Wheel(link.filename) + name = canonicalize_name(wheel.name) + logger.info( + 'Obtaining dependency information from %s %s', + name, wheel.version, + ) + url = link.url.split('#', 1)[0] + try: + return dist_from_wheel_url(name, url, self._session) + except HTTPRangeRequestUnsupported: + logger.debug('%s does not support range requests', url) + return None + + def prepare_linked_requirement(self, req, parallel_builds=False): + # type: (InstallRequirement, bool) -> Distribution + """Prepare a requirement to be obtained from req.link.""" + assert req.link + link = req.link + self._log_preparing_link(req) + with indent_log(): + # Check if the relevant file is already available + # in the download directory + file_path = None + if self.download_dir is not None and link.is_wheel: + hashes = self._get_linked_req_hashes(req) + file_path = _check_download_dir(req.link, self.download_dir, hashes) + + if file_path is not None: + # The file is already available, so mark it as downloaded + self._downloaded[req.link.url] = file_path, None + else: + # The file is not available, attempt to fetch only metadata + wheel_dist = self._fetch_metadata_using_lazy_wheel(link) + if wheel_dist is not None: + req.needs_more_preparation = True + return wheel_dist + + # None of the optimizations worked, fully prepare the requirement + return self._prepare_linked_requirement(req, parallel_builds) + + def prepare_linked_requirements_more(self, reqs, parallel_builds=False): + # type: (Iterable[InstallRequirement], bool) -> None + """Prepare a linked requirement more, if needed.""" + reqs = [req for req in reqs if req.needs_more_preparation] + links = [req.link for req in reqs] + + # Let's download to a temporary directory. + tmpdir = TempDirectory(kind="unpack", globally_managed=True).path + self._downloaded.update(self._batch_download(links, tmpdir)) + for req in reqs: + self._prepare_linked_requirement(req, parallel_builds) + + def _prepare_linked_requirement(self, req, parallel_builds): + # type: (InstallRequirement, bool) -> Distribution + assert req.link + link = req.link + + self._ensure_link_req_src_dir(req, parallel_builds) + hashes = self._get_linked_req_hashes(req) + if link.url not in self._downloaded: + try: + local_file = unpack_url( + link, req.source_dir, self._download, + self.download_dir, hashes, + ) + except NetworkConnectionError as exc: + raise InstallationError( + 'Could not install requirement {} because of HTTP ' + 'error {} for URL {}'.format(req, exc, link) + ) + else: + file_path, content_type = self._downloaded[link.url] + if hashes: + hashes.check_against_path(file_path) + local_file = File(file_path, content_type) + + # For use in later processing, + # preserve the file path on the requirement. + if local_file: + req.local_file_path = local_file.path + + dist = _get_prepared_distribution( + req, self.req_tracker, self.finder, self.build_isolation, + ) + return dist + + def save_linked_requirement(self, req): + # type: (InstallRequirement) -> None + assert self.download_dir is not None + assert req.link is not None + link = req.link + if link.is_vcs or (link.is_existing_dir() and req.editable): + # Make a .zip of the source_dir we already created. + req.archive(self.download_dir) + return + + if link.is_existing_dir(): + logger.debug( + 'Not copying link to destination directory ' + 'since it is a directory: %s', link, + ) + return + if req.local_file_path is None: + # No distribution was downloaded for this requirement. + return + + download_location = os.path.join(self.download_dir, link.filename) + if not os.path.exists(download_location): + shutil.copy(req.local_file_path, download_location) + download_path = display_path(download_location) + logger.info('Saved %s', download_path) + + def prepare_editable_requirement( + self, + req, # type: InstallRequirement + ): + # type: (...) -> Distribution + """Prepare an editable requirement + """ + assert req.editable, "cannot prepare a non-editable req as editable" + + logger.info('Obtaining %s', req) + + with indent_log(): + if self.require_hashes: + raise InstallationError( + 'The editable requirement {} cannot be installed when ' + 'requiring hashes, because there is no single file to ' + 'hash.'.format(req) + ) + req.ensure_has_source_dir(self.src_dir) + req.update_editable() + + dist = _get_prepared_distribution( + req, self.req_tracker, self.finder, self.build_isolation, + ) + + req.check_if_exists(self.use_user_site) + + return dist + + def prepare_installed_requirement( + self, + req, # type: InstallRequirement + skip_reason # type: str + ): + # type: (...) -> Distribution + """Prepare an already-installed requirement + """ + assert req.satisfied_by, "req should have been satisfied but isn't" + assert skip_reason is not None, ( + "did not get skip reason skipped but req.satisfied_by " + "is set to {}".format(req.satisfied_by) + ) + logger.info( + 'Requirement %s: %s (%s)', + skip_reason, req, req.satisfied_by.version + ) + with indent_log(): + if self.require_hashes: + logger.debug( + 'Since it is already installed, we are trusting this ' + 'package without checking its hash. To ensure a ' + 'completely repeatable environment, install into an ' + 'empty virtualenv.' + ) + return InstalledDistribution(req).get_pkg_resources_distribution() diff --git a/venv/Lib/site-packages/pip/_internal/pyproject.py b/venv/Lib/site-packages/pip/_internal/pyproject.py new file mode 100644 index 0000000..68ca53b --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/pyproject.py @@ -0,0 +1,186 @@ +import os +from collections import namedtuple + +from pip._vendor import toml +from pip._vendor.packaging.requirements import InvalidRequirement, Requirement + +from pip._internal.exceptions import InstallationError +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import Any, List, Optional + + +def _is_list_of_str(obj): + # type: (Any) -> bool + return ( + isinstance(obj, list) and + all(isinstance(item, str) for item in obj) + ) + + +def make_pyproject_path(unpacked_source_directory): + # type: (str) -> str + return os.path.join(unpacked_source_directory, 'pyproject.toml') + + +BuildSystemDetails = namedtuple('BuildSystemDetails', [ + 'requires', 'backend', 'check', 'backend_path' +]) + + +def load_pyproject_toml( + use_pep517, # type: Optional[bool] + pyproject_toml, # type: str + setup_py, # type: str + req_name # type: str +): + # type: (...) -> Optional[BuildSystemDetails] + """Load the pyproject.toml file. + + Parameters: + use_pep517 - Has the user requested PEP 517 processing? None + means the user hasn't explicitly specified. + pyproject_toml - Location of the project's pyproject.toml file + setup_py - Location of the project's setup.py file + req_name - The name of the requirement we're processing (for + error reporting) + + Returns: + None if we should use the legacy code path, otherwise a tuple + ( + requirements from pyproject.toml, + name of PEP 517 backend, + requirements we should check are installed after setting + up the build environment + directory paths to import the backend from (backend-path), + relative to the project root. + ) + """ + has_pyproject = os.path.isfile(pyproject_toml) + has_setup = os.path.isfile(setup_py) + + if has_pyproject: + with open(pyproject_toml, encoding="utf-8") as f: + pp_toml = toml.load(f) + build_system = pp_toml.get("build-system") + else: + build_system = None + + # The following cases must use PEP 517 + # We check for use_pep517 being non-None and falsey because that means + # the user explicitly requested --no-use-pep517. The value 0 as + # opposed to False can occur when the value is provided via an + # environment variable or config file option (due to the quirk of + # strtobool() returning an integer in pip's configuration code). + if has_pyproject and not has_setup: + if use_pep517 is not None and not use_pep517: + raise InstallationError( + "Disabling PEP 517 processing is invalid: " + "project does not have a setup.py" + ) + use_pep517 = True + elif build_system and "build-backend" in build_system: + if use_pep517 is not None and not use_pep517: + raise InstallationError( + "Disabling PEP 517 processing is invalid: " + "project specifies a build backend of {} " + "in pyproject.toml".format( + build_system["build-backend"] + ) + ) + use_pep517 = True + + # If we haven't worked out whether to use PEP 517 yet, + # and the user hasn't explicitly stated a preference, + # we do so if the project has a pyproject.toml file. + elif use_pep517 is None: + use_pep517 = has_pyproject + + # At this point, we know whether we're going to use PEP 517. + assert use_pep517 is not None + + # If we're using the legacy code path, there is nothing further + # for us to do here. + if not use_pep517: + return None + + if build_system is None: + # Either the user has a pyproject.toml with no build-system + # section, or the user has no pyproject.toml, but has opted in + # explicitly via --use-pep517. + # In the absence of any explicit backend specification, we + # assume the setuptools backend that most closely emulates the + # traditional direct setup.py execution, and require wheel and + # a version of setuptools that supports that backend. + + build_system = { + "requires": ["setuptools>=40.8.0", "wheel"], + "build-backend": "setuptools.build_meta:__legacy__", + } + + # If we're using PEP 517, we have build system information (either + # from pyproject.toml, or defaulted by the code above). + # Note that at this point, we do not know if the user has actually + # specified a backend, though. + assert build_system is not None + + # Ensure that the build-system section in pyproject.toml conforms + # to PEP 518. + error_template = ( + "{package} has a pyproject.toml file that does not comply " + "with PEP 518: {reason}" + ) + + # Specifying the build-system table but not the requires key is invalid + if "requires" not in build_system: + raise InstallationError( + error_template.format(package=req_name, reason=( + "it has a 'build-system' table but not " + "'build-system.requires' which is mandatory in the table" + )) + ) + + # Error out if requires is not a list of strings + requires = build_system["requires"] + if not _is_list_of_str(requires): + raise InstallationError(error_template.format( + package=req_name, + reason="'build-system.requires' is not a list of strings.", + )) + + # Each requirement must be valid as per PEP 508 + for requirement in requires: + try: + Requirement(requirement) + except InvalidRequirement: + raise InstallationError( + error_template.format( + package=req_name, + reason=( + "'build-system.requires' contains an invalid " + "requirement: {!r}".format(requirement) + ), + ) + ) + + backend = build_system.get("build-backend") + backend_path = build_system.get("backend-path", []) + check = [] # type: List[str] + if backend is None: + # If the user didn't specify a backend, we assume they want to use + # the setuptools backend. But we can't be sure they have included + # a version of setuptools which supplies the backend, or wheel + # (which is needed by the backend) in their requirements. So we + # make a note to check that those requirements are present once + # we have set up the environment. + # This is quite a lot of work to check for a very specific case. But + # the problem is, that case is potentially quite common - projects that + # adopted PEP 518 early for the ability to specify requirements to + # execute setup.py, but never considered needing to mention the build + # tools themselves. The original PEP 518 code had a similar check (but + # implemented in a different way). + backend = "setuptools.build_meta:__legacy__" + check = ["setuptools>=40.8.0", "wheel"] + + return BuildSystemDetails(requires, backend, check, backend_path) diff --git a/venv/Lib/site-packages/pip/_internal/req/__init__.py b/venv/Lib/site-packages/pip/_internal/req/__init__.py new file mode 100644 index 0000000..352d892 --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/req/__init__.py @@ -0,0 +1,101 @@ +import collections +import logging + +from pip._internal.utils.logging import indent_log +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +from .req_file import parse_requirements +from .req_install import InstallRequirement +from .req_set import RequirementSet + +if MYPY_CHECK_RUNNING: + from typing import Iterator, List, Optional, Sequence, Tuple + +__all__ = [ + "RequirementSet", "InstallRequirement", + "parse_requirements", "install_given_reqs", +] + +logger = logging.getLogger(__name__) + + +class InstallationResult: + def __init__(self, name): + # type: (str) -> None + self.name = name + + def __repr__(self): + # type: () -> str + return f"InstallationResult(name={self.name!r})" + + +def _validate_requirements( + requirements, # type: List[InstallRequirement] +): + # type: (...) -> Iterator[Tuple[str, InstallRequirement]] + for req in requirements: + assert req.name, f"invalid to-be-installed requirement: {req}" + yield req.name, req + + +def install_given_reqs( + requirements, # type: List[InstallRequirement] + install_options, # type: List[str] + global_options, # type: Sequence[str] + root, # type: Optional[str] + home, # type: Optional[str] + prefix, # type: Optional[str] + warn_script_location, # type: bool + use_user_site, # type: bool + pycompile, # type: bool +): + # type: (...) -> List[InstallationResult] + """ + Install everything in the given list. + + (to be called after having downloaded and unpacked the packages) + """ + to_install = collections.OrderedDict(_validate_requirements(requirements)) + + if to_install: + logger.info( + 'Installing collected packages: %s', + ', '.join(to_install.keys()), + ) + + installed = [] + + with indent_log(): + for req_name, requirement in to_install.items(): + if requirement.should_reinstall: + logger.info('Attempting uninstall: %s', req_name) + with indent_log(): + uninstalled_pathset = requirement.uninstall( + auto_confirm=True + ) + else: + uninstalled_pathset = None + + try: + requirement.install( + install_options, + global_options, + root=root, + home=home, + prefix=prefix, + warn_script_location=warn_script_location, + use_user_site=use_user_site, + pycompile=pycompile, + ) + except Exception: + # if install did not succeed, rollback previous uninstall + if uninstalled_pathset and not requirement.install_succeeded: + uninstalled_pathset.rollback() + raise + else: + if uninstalled_pathset and requirement.install_succeeded: + uninstalled_pathset.commit() + + installed.append(InstallationResult(req_name)) + + return installed diff --git a/venv/Lib/site-packages/pip/_internal/req/constructors.py b/venv/Lib/site-packages/pip/_internal/req/constructors.py new file mode 100644 index 0000000..cfb1951 --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/req/constructors.py @@ -0,0 +1,468 @@ +"""Backing implementation for InstallRequirement's various constructors + +The idea here is that these formed a major chunk of InstallRequirement's size +so, moving them and support code dedicated to them outside of that class +helps creates for better understandability for the rest of the code. + +These are meant to be used elsewhere within pip to create instances of +InstallRequirement. +""" + +import logging +import os +import re + +from pip._vendor.packaging.markers import Marker +from pip._vendor.packaging.requirements import InvalidRequirement, Requirement +from pip._vendor.packaging.specifiers import Specifier +from pip._vendor.pkg_resources import RequirementParseError, parse_requirements + +from pip._internal.exceptions import InstallationError +from pip._internal.models.index import PyPI, TestPyPI +from pip._internal.models.link import Link +from pip._internal.models.wheel import Wheel +from pip._internal.pyproject import make_pyproject_path +from pip._internal.req.req_install import InstallRequirement +from pip._internal.utils.filetypes import is_archive_file +from pip._internal.utils.misc import is_installable_dir +from pip._internal.utils.typing import MYPY_CHECK_RUNNING +from pip._internal.utils.urls import path_to_url +from pip._internal.vcs import is_url, vcs + +if MYPY_CHECK_RUNNING: + from typing import Any, Dict, Optional, Set, Tuple, Union + + from pip._internal.req.req_file import ParsedRequirement + + +__all__ = [ + "install_req_from_editable", "install_req_from_line", + "parse_editable" +] + +logger = logging.getLogger(__name__) +operators = Specifier._operators.keys() + + +def _strip_extras(path): + # type: (str) -> Tuple[str, Optional[str]] + m = re.match(r'^(.+)(\[[^\]]+\])$', path) + extras = None + if m: + path_no_extras = m.group(1) + extras = m.group(2) + else: + path_no_extras = path + + return path_no_extras, extras + + +def convert_extras(extras): + # type: (Optional[str]) -> Set[str] + if not extras: + return set() + return Requirement("placeholder" + extras.lower()).extras + + +def parse_editable(editable_req): + # type: (str) -> Tuple[Optional[str], str, Set[str]] + """Parses an editable requirement into: + - a requirement name + - an URL + - extras + - editable options + Accepted requirements: + svn+http://blahblah@rev#egg=Foobar[baz]&subdirectory=version_subdir + .[some_extra] + """ + + url = editable_req + + # If a file path is specified with extras, strip off the extras. + url_no_extras, extras = _strip_extras(url) + + if os.path.isdir(url_no_extras): + if not os.path.exists(os.path.join(url_no_extras, 'setup.py')): + msg = ( + 'File "setup.py" not found. Directory cannot be installed ' + 'in editable mode: {}'.format(os.path.abspath(url_no_extras)) + ) + pyproject_path = make_pyproject_path(url_no_extras) + if os.path.isfile(pyproject_path): + msg += ( + '\n(A "pyproject.toml" file was found, but editable ' + 'mode currently requires a setup.py based build.)' + ) + raise InstallationError(msg) + + # Treating it as code that has already been checked out + url_no_extras = path_to_url(url_no_extras) + + if url_no_extras.lower().startswith('file:'): + package_name = Link(url_no_extras).egg_fragment + if extras: + return ( + package_name, + url_no_extras, + Requirement("placeholder" + extras.lower()).extras, + ) + else: + return package_name, url_no_extras, set() + + for version_control in vcs: + if url.lower().startswith(f'{version_control}:'): + url = f'{version_control}+{url}' + break + + link = Link(url) + + if not link.is_vcs: + backends = ", ".join(vcs.all_schemes) + raise InstallationError( + f'{editable_req} is not a valid editable requirement. ' + f'It should either be a path to a local project or a VCS URL ' + f'(beginning with {backends}).' + ) + + package_name = link.egg_fragment + if not package_name: + raise InstallationError( + "Could not detect requirement name for '{}', please specify one " + "with #egg=your_package_name".format(editable_req) + ) + return package_name, url, set() + + +def deduce_helpful_msg(req): + # type: (str) -> str + """Returns helpful msg in case requirements file does not exist, + or cannot be parsed. + + :params req: Requirements file path + """ + msg = "" + if os.path.exists(req): + msg = " The path does exist. " + # Try to parse and check if it is a requirements file. + try: + with open(req, 'r') as fp: + # parse first line only + next(parse_requirements(fp.read())) + msg += ( + "The argument you provided " + "({}) appears to be a" + " requirements file. If that is the" + " case, use the '-r' flag to install" + " the packages specified within it." + ).format(req) + except RequirementParseError: + logger.debug( + "Cannot parse '%s' as requirements file", req, exc_info=True + ) + else: + msg += f" File '{req}' does not exist." + return msg + + +class RequirementParts: + def __init__( + self, + requirement, # type: Optional[Requirement] + link, # type: Optional[Link] + markers, # type: Optional[Marker] + extras, # type: Set[str] + ): + self.requirement = requirement + self.link = link + self.markers = markers + self.extras = extras + + +def parse_req_from_editable(editable_req): + # type: (str) -> RequirementParts + name, url, extras_override = parse_editable(editable_req) + + if name is not None: + try: + req = Requirement(name) + except InvalidRequirement: + raise InstallationError(f"Invalid requirement: '{name}'") + else: + req = None + + link = Link(url) + + return RequirementParts(req, link, None, extras_override) + + +# ---- The actual constructors follow ---- + + +def install_req_from_editable( + editable_req, # type: str + comes_from=None, # type: Optional[Union[InstallRequirement, str]] + use_pep517=None, # type: Optional[bool] + isolated=False, # type: bool + options=None, # type: Optional[Dict[str, Any]] + constraint=False, # type: bool + user_supplied=False, # type: bool +): + # type: (...) -> InstallRequirement + + parts = parse_req_from_editable(editable_req) + + return InstallRequirement( + parts.requirement, + comes_from=comes_from, + user_supplied=user_supplied, + editable=True, + link=parts.link, + constraint=constraint, + use_pep517=use_pep517, + isolated=isolated, + install_options=options.get("install_options", []) if options else [], + global_options=options.get("global_options", []) if options else [], + hash_options=options.get("hashes", {}) if options else {}, + extras=parts.extras, + ) + + +def _looks_like_path(name): + # type: (str) -> bool + """Checks whether the string "looks like" a path on the filesystem. + + This does not check whether the target actually exists, only judge from the + appearance. + + Returns true if any of the following conditions is true: + * a path separator is found (either os.path.sep or os.path.altsep); + * a dot is found (which represents the current directory). + """ + if os.path.sep in name: + return True + if os.path.altsep is not None and os.path.altsep in name: + return True + if name.startswith("."): + return True + return False + + +def _get_url_from_path(path, name): + # type: (str, str) -> Optional[str] + """ + First, it checks whether a provided path is an installable directory + (e.g. it has a setup.py). If it is, returns the path. + + If false, check if the path is an archive file (such as a .whl). + The function checks if the path is a file. If false, if the path has + an @, it will treat it as a PEP 440 URL requirement and return the path. + """ + if _looks_like_path(name) and os.path.isdir(path): + if is_installable_dir(path): + return path_to_url(path) + raise InstallationError( + "Directory {name!r} is not installable. Neither 'setup.py' " + "nor 'pyproject.toml' found.".format(**locals()) + ) + if not is_archive_file(path): + return None + if os.path.isfile(path): + return path_to_url(path) + urlreq_parts = name.split('@', 1) + if len(urlreq_parts) >= 2 and not _looks_like_path(urlreq_parts[0]): + # If the path contains '@' and the part before it does not look + # like a path, try to treat it as a PEP 440 URL req instead. + return None + logger.warning( + 'Requirement %r looks like a filename, but the ' + 'file does not exist', + name + ) + return path_to_url(path) + + +def parse_req_from_line(name, line_source): + # type: (str, Optional[str]) -> RequirementParts + if is_url(name): + marker_sep = '; ' + else: + marker_sep = ';' + if marker_sep in name: + name, markers_as_string = name.split(marker_sep, 1) + markers_as_string = markers_as_string.strip() + if not markers_as_string: + markers = None + else: + markers = Marker(markers_as_string) + else: + markers = None + name = name.strip() + req_as_string = None + path = os.path.normpath(os.path.abspath(name)) + link = None + extras_as_string = None + + if is_url(name): + link = Link(name) + else: + p, extras_as_string = _strip_extras(path) + url = _get_url_from_path(p, name) + if url is not None: + link = Link(url) + + # it's a local file, dir, or url + if link: + # Handle relative file URLs + if link.scheme == 'file' and re.search(r'\.\./', link.url): + link = Link( + path_to_url(os.path.normpath(os.path.abspath(link.path)))) + # wheel file + if link.is_wheel: + wheel = Wheel(link.filename) # can raise InvalidWheelFilename + req_as_string = "{wheel.name}=={wheel.version}".format(**locals()) + else: + # set the req to the egg fragment. when it's not there, this + # will become an 'unnamed' requirement + req_as_string = link.egg_fragment + + # a requirement specifier + else: + req_as_string = name + + extras = convert_extras(extras_as_string) + + def with_source(text): + # type: (str) -> str + if not line_source: + return text + return f'{text} (from {line_source})' + + if req_as_string is not None: + try: + req = Requirement(req_as_string) + except InvalidRequirement: + if os.path.sep in req_as_string: + add_msg = "It looks like a path." + add_msg += deduce_helpful_msg(req_as_string) + elif ('=' in req_as_string and + not any(op in req_as_string for op in operators)): + add_msg = "= is not a valid operator. Did you mean == ?" + else: + add_msg = '' + msg = with_source( + f'Invalid requirement: {req_as_string!r}' + ) + if add_msg: + msg += f'\nHint: {add_msg}' + raise InstallationError(msg) + else: + # Deprecate extras after specifiers: "name>=1.0[extras]" + # This currently works by accident because _strip_extras() parses + # any extras in the end of the string and those are saved in + # RequirementParts + for spec in req.specifier: + spec_str = str(spec) + if spec_str.endswith(']'): + msg = f"Extras after version '{spec_str}'." + raise InstallationError(msg) + else: + req = None + + return RequirementParts(req, link, markers, extras) + + +def install_req_from_line( + name, # type: str + comes_from=None, # type: Optional[Union[str, InstallRequirement]] + use_pep517=None, # type: Optional[bool] + isolated=False, # type: bool + options=None, # type: Optional[Dict[str, Any]] + constraint=False, # type: bool + line_source=None, # type: Optional[str] + user_supplied=False, # type: bool +): + # type: (...) -> InstallRequirement + """Creates an InstallRequirement from a name, which might be a + requirement, directory containing 'setup.py', filename, or URL. + + :param line_source: An optional string describing where the line is from, + for logging purposes in case of an error. + """ + parts = parse_req_from_line(name, line_source) + + return InstallRequirement( + parts.requirement, comes_from, link=parts.link, markers=parts.markers, + use_pep517=use_pep517, isolated=isolated, + install_options=options.get("install_options", []) if options else [], + global_options=options.get("global_options", []) if options else [], + hash_options=options.get("hashes", {}) if options else {}, + constraint=constraint, + extras=parts.extras, + user_supplied=user_supplied, + ) + + +def install_req_from_req_string( + req_string, # type: str + comes_from=None, # type: Optional[InstallRequirement] + isolated=False, # type: bool + use_pep517=None, # type: Optional[bool] + user_supplied=False, # type: bool +): + # type: (...) -> InstallRequirement + try: + req = Requirement(req_string) + except InvalidRequirement: + raise InstallationError(f"Invalid requirement: '{req_string}'") + + domains_not_allowed = [ + PyPI.file_storage_domain, + TestPyPI.file_storage_domain, + ] + if (req.url and comes_from and comes_from.link and + comes_from.link.netloc in domains_not_allowed): + # Explicitly disallow pypi packages that depend on external urls + raise InstallationError( + "Packages installed from PyPI cannot depend on packages " + "which are not also hosted on PyPI.\n" + "{} depends on {} ".format(comes_from.name, req) + ) + + return InstallRequirement( + req, + comes_from, + isolated=isolated, + use_pep517=use_pep517, + user_supplied=user_supplied, + ) + + +def install_req_from_parsed_requirement( + parsed_req, # type: ParsedRequirement + isolated=False, # type: bool + use_pep517=None, # type: Optional[bool] + user_supplied=False, # type: bool +): + # type: (...) -> InstallRequirement + if parsed_req.is_editable: + req = install_req_from_editable( + parsed_req.requirement, + comes_from=parsed_req.comes_from, + use_pep517=use_pep517, + constraint=parsed_req.constraint, + isolated=isolated, + user_supplied=user_supplied, + ) + + else: + req = install_req_from_line( + parsed_req.requirement, + comes_from=parsed_req.comes_from, + use_pep517=use_pep517, + isolated=isolated, + options=parsed_req.options, + constraint=parsed_req.constraint, + line_source=parsed_req.line_source, + user_supplied=user_supplied, + ) + return req diff --git a/venv/Lib/site-packages/pip/_internal/req/req_file.py b/venv/Lib/site-packages/pip/_internal/req/req_file.py new file mode 100644 index 0000000..716005d --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/req/req_file.py @@ -0,0 +1,560 @@ +""" +Requirements file parsing +""" + +import optparse +import os +import re +import shlex +import urllib.parse + +from pip._internal.cli import cmdoptions +from pip._internal.exceptions import InstallationError, RequirementsFileParseError +from pip._internal.models.search_scope import SearchScope +from pip._internal.network.utils import raise_for_status +from pip._internal.utils.encoding import auto_decode +from pip._internal.utils.typing import MYPY_CHECK_RUNNING +from pip._internal.utils.urls import get_url_scheme, url_to_path + +if MYPY_CHECK_RUNNING: + from optparse import Values + from typing import ( + Any, + Callable, + Dict, + Iterator, + List, + NoReturn, + Optional, + Text, + Tuple, + ) + + from pip._internal.index.package_finder import PackageFinder + from pip._internal.network.session import PipSession + + ReqFileLines = Iterator[Tuple[int, Text]] + + LineParser = Callable[[Text], Tuple[str, Values]] + + +__all__ = ['parse_requirements'] + +SCHEME_RE = re.compile(r'^(http|https|file):', re.I) +COMMENT_RE = re.compile(r'(^|\s+)#.*$') + +# Matches environment variable-style values in '${MY_VARIABLE_1}' with the +# variable name consisting of only uppercase letters, digits or the '_' +# (underscore). This follows the POSIX standard defined in IEEE Std 1003.1, +# 2013 Edition. +ENV_VAR_RE = re.compile(r'(?P\$\{(?P[A-Z0-9_]+)\})') + +SUPPORTED_OPTIONS = [ + cmdoptions.index_url, + cmdoptions.extra_index_url, + cmdoptions.no_index, + cmdoptions.constraints, + cmdoptions.requirements, + cmdoptions.editable, + cmdoptions.find_links, + cmdoptions.no_binary, + cmdoptions.only_binary, + cmdoptions.prefer_binary, + cmdoptions.require_hashes, + cmdoptions.pre, + cmdoptions.trusted_host, + cmdoptions.use_new_feature, +] # type: List[Callable[..., optparse.Option]] + +# options to be passed to requirements +SUPPORTED_OPTIONS_REQ = [ + cmdoptions.install_options, + cmdoptions.global_options, + cmdoptions.hash, +] # type: List[Callable[..., optparse.Option]] + +# the 'dest' string values +SUPPORTED_OPTIONS_REQ_DEST = [str(o().dest) for o in SUPPORTED_OPTIONS_REQ] + + +class ParsedRequirement: + def __init__( + self, + requirement, # type:str + is_editable, # type: bool + comes_from, # type: str + constraint, # type: bool + options=None, # type: Optional[Dict[str, Any]] + line_source=None, # type: Optional[str] + ): + # type: (...) -> None + self.requirement = requirement + self.is_editable = is_editable + self.comes_from = comes_from + self.options = options + self.constraint = constraint + self.line_source = line_source + + +class ParsedLine: + def __init__( + self, + filename, # type: str + lineno, # type: int + args, # type: str + opts, # type: Values + constraint, # type: bool + ): + # type: (...) -> None + self.filename = filename + self.lineno = lineno + self.opts = opts + self.constraint = constraint + + if args: + self.is_requirement = True + self.is_editable = False + self.requirement = args + elif opts.editables: + self.is_requirement = True + self.is_editable = True + # We don't support multiple -e on one line + self.requirement = opts.editables[0] + else: + self.is_requirement = False + + +def parse_requirements( + filename, # type: str + session, # type: PipSession + finder=None, # type: Optional[PackageFinder] + options=None, # type: Optional[optparse.Values] + constraint=False, # type: bool +): + # type: (...) -> Iterator[ParsedRequirement] + """Parse a requirements file and yield ParsedRequirement instances. + + :param filename: Path or url of requirements file. + :param session: PipSession instance. + :param finder: Instance of pip.index.PackageFinder. + :param options: cli options. + :param constraint: If true, parsing a constraint file rather than + requirements file. + """ + line_parser = get_line_parser(finder) + parser = RequirementsFileParser(session, line_parser) + + for parsed_line in parser.parse(filename, constraint): + parsed_req = handle_line( + parsed_line, + options=options, + finder=finder, + session=session + ) + if parsed_req is not None: + yield parsed_req + + +def preprocess(content): + # type: (str) -> ReqFileLines + """Split, filter, and join lines, and return a line iterator + + :param content: the content of the requirements file + """ + lines_enum = enumerate(content.splitlines(), start=1) # type: ReqFileLines + lines_enum = join_lines(lines_enum) + lines_enum = ignore_comments(lines_enum) + lines_enum = expand_env_variables(lines_enum) + return lines_enum + + +def handle_requirement_line( + line, # type: ParsedLine + options=None, # type: Optional[optparse.Values] +): + # type: (...) -> ParsedRequirement + + # preserve for the nested code path + line_comes_from = '{} {} (line {})'.format( + '-c' if line.constraint else '-r', line.filename, line.lineno, + ) + + assert line.is_requirement + + if line.is_editable: + # For editable requirements, we don't support per-requirement + # options, so just return the parsed requirement. + return ParsedRequirement( + requirement=line.requirement, + is_editable=line.is_editable, + comes_from=line_comes_from, + constraint=line.constraint, + ) + else: + if options: + # Disable wheels if the user has specified build options + cmdoptions.check_install_build_global(options, line.opts) + + # get the options that apply to requirements + req_options = {} + for dest in SUPPORTED_OPTIONS_REQ_DEST: + if dest in line.opts.__dict__ and line.opts.__dict__[dest]: + req_options[dest] = line.opts.__dict__[dest] + + line_source = f'line {line.lineno} of {line.filename}' + return ParsedRequirement( + requirement=line.requirement, + is_editable=line.is_editable, + comes_from=line_comes_from, + constraint=line.constraint, + options=req_options, + line_source=line_source, + ) + + +def handle_option_line( + opts, # type: Values + filename, # type: str + lineno, # type: int + finder=None, # type: Optional[PackageFinder] + options=None, # type: Optional[optparse.Values] + session=None, # type: Optional[PipSession] +): + # type: (...) -> None + + if options: + # percolate options upward + if opts.require_hashes: + options.require_hashes = opts.require_hashes + if opts.features_enabled: + options.features_enabled.extend( + f for f in opts.features_enabled + if f not in options.features_enabled + ) + + # set finder options + if finder: + find_links = finder.find_links + index_urls = finder.index_urls + if opts.index_url: + index_urls = [opts.index_url] + if opts.no_index is True: + index_urls = [] + if opts.extra_index_urls: + index_urls.extend(opts.extra_index_urls) + if opts.find_links: + # FIXME: it would be nice to keep track of the source + # of the find_links: support a find-links local path + # relative to a requirements file. + value = opts.find_links[0] + req_dir = os.path.dirname(os.path.abspath(filename)) + relative_to_reqs_file = os.path.join(req_dir, value) + if os.path.exists(relative_to_reqs_file): + value = relative_to_reqs_file + find_links.append(value) + + if session: + # We need to update the auth urls in session + session.update_index_urls(index_urls) + + search_scope = SearchScope( + find_links=find_links, + index_urls=index_urls, + ) + finder.search_scope = search_scope + + if opts.pre: + finder.set_allow_all_prereleases() + + if opts.prefer_binary: + finder.set_prefer_binary() + + if session: + for host in opts.trusted_hosts or []: + source = f'line {lineno} of {filename}' + session.add_trusted_host(host, source=source) + + +def handle_line( + line, # type: ParsedLine + options=None, # type: Optional[optparse.Values] + finder=None, # type: Optional[PackageFinder] + session=None, # type: Optional[PipSession] +): + # type: (...) -> Optional[ParsedRequirement] + """Handle a single parsed requirements line; This can result in + creating/yielding requirements, or updating the finder. + + :param line: The parsed line to be processed. + :param options: CLI options. + :param finder: The finder - updated by non-requirement lines. + :param session: The session - updated by non-requirement lines. + + Returns a ParsedRequirement object if the line is a requirement line, + otherwise returns None. + + For lines that contain requirements, the only options that have an effect + are from SUPPORTED_OPTIONS_REQ, and they are scoped to the + requirement. Other options from SUPPORTED_OPTIONS may be present, but are + ignored. + + For lines that do not contain requirements, the only options that have an + effect are from SUPPORTED_OPTIONS. Options from SUPPORTED_OPTIONS_REQ may + be present, but are ignored. These lines may contain multiple options + (although our docs imply only one is supported), and all our parsed and + affect the finder. + """ + + if line.is_requirement: + parsed_req = handle_requirement_line(line, options) + return parsed_req + else: + handle_option_line( + line.opts, + line.filename, + line.lineno, + finder, + options, + session, + ) + return None + + +class RequirementsFileParser: + def __init__( + self, + session, # type: PipSession + line_parser, # type: LineParser + ): + # type: (...) -> None + self._session = session + self._line_parser = line_parser + + def parse(self, filename, constraint): + # type: (str, bool) -> Iterator[ParsedLine] + """Parse a given file, yielding parsed lines. + """ + yield from self._parse_and_recurse(filename, constraint) + + def _parse_and_recurse(self, filename, constraint): + # type: (str, bool) -> Iterator[ParsedLine] + for line in self._parse_file(filename, constraint): + if ( + not line.is_requirement and + (line.opts.requirements or line.opts.constraints) + ): + # parse a nested requirements file + if line.opts.requirements: + req_path = line.opts.requirements[0] + nested_constraint = False + else: + req_path = line.opts.constraints[0] + nested_constraint = True + + # original file is over http + if SCHEME_RE.search(filename): + # do a url join so relative paths work + req_path = urllib.parse.urljoin(filename, req_path) + # original file and nested file are paths + elif not SCHEME_RE.search(req_path): + # do a join so relative paths work + req_path = os.path.join( + os.path.dirname(filename), req_path, + ) + + yield from self._parse_and_recurse(req_path, nested_constraint) + else: + yield line + + def _parse_file(self, filename, constraint): + # type: (str, bool) -> Iterator[ParsedLine] + _, content = get_file_content(filename, self._session) + + lines_enum = preprocess(content) + + for line_number, line in lines_enum: + try: + args_str, opts = self._line_parser(line) + except OptionParsingError as e: + # add offending line + msg = f'Invalid requirement: {line}\n{e.msg}' + raise RequirementsFileParseError(msg) + + yield ParsedLine( + filename, + line_number, + args_str, + opts, + constraint, + ) + + +def get_line_parser(finder): + # type: (Optional[PackageFinder]) -> LineParser + def parse_line(line): + # type: (str) -> Tuple[str, Values] + # Build new parser for each line since it accumulates appendable + # options. + parser = build_parser() + defaults = parser.get_default_values() + defaults.index_url = None + if finder: + defaults.format_control = finder.format_control + + args_str, options_str = break_args_options(line) + + opts, _ = parser.parse_args(shlex.split(options_str), defaults) + + return args_str, opts + + return parse_line + + +def break_args_options(line): + # type: (str) -> Tuple[str, str] + """Break up the line into an args and options string. We only want to shlex + (and then optparse) the options, not the args. args can contain markers + which are corrupted by shlex. + """ + tokens = line.split(' ') + args = [] + options = tokens[:] + for token in tokens: + if token.startswith('-') or token.startswith('--'): + break + else: + args.append(token) + options.pop(0) + return ' '.join(args), ' '.join(options) + + +class OptionParsingError(Exception): + def __init__(self, msg): + # type: (str) -> None + self.msg = msg + + +def build_parser(): + # type: () -> optparse.OptionParser + """ + Return a parser for parsing requirement lines + """ + parser = optparse.OptionParser(add_help_option=False) + + option_factories = SUPPORTED_OPTIONS + SUPPORTED_OPTIONS_REQ + for option_factory in option_factories: + option = option_factory() + parser.add_option(option) + + # By default optparse sys.exits on parsing errors. We want to wrap + # that in our own exception. + def parser_exit(self, msg): + # type: (Any, str) -> NoReturn + raise OptionParsingError(msg) + # NOTE: mypy disallows assigning to a method + # https://github.com/python/mypy/issues/2427 + parser.exit = parser_exit # type: ignore + + return parser + + +def join_lines(lines_enum): + # type: (ReqFileLines) -> ReqFileLines + """Joins a line ending in '\' with the previous line (except when following + comments). The joined line takes on the index of the first line. + """ + primary_line_number = None + new_line = [] # type: List[str] + for line_number, line in lines_enum: + if not line.endswith('\\') or COMMENT_RE.match(line): + if COMMENT_RE.match(line): + # this ensures comments are always matched later + line = ' ' + line + if new_line: + new_line.append(line) + assert primary_line_number is not None + yield primary_line_number, ''.join(new_line) + new_line = [] + else: + yield line_number, line + else: + if not new_line: + primary_line_number = line_number + new_line.append(line.strip('\\')) + + # last line contains \ + if new_line: + assert primary_line_number is not None + yield primary_line_number, ''.join(new_line) + + # TODO: handle space after '\'. + + +def ignore_comments(lines_enum): + # type: (ReqFileLines) -> ReqFileLines + """ + Strips comments and filter empty lines. + """ + for line_number, line in lines_enum: + line = COMMENT_RE.sub('', line) + line = line.strip() + if line: + yield line_number, line + + +def expand_env_variables(lines_enum): + # type: (ReqFileLines) -> ReqFileLines + """Replace all environment variables that can be retrieved via `os.getenv`. + + The only allowed format for environment variables defined in the + requirement file is `${MY_VARIABLE_1}` to ensure two things: + + 1. Strings that contain a `$` aren't accidentally (partially) expanded. + 2. Ensure consistency across platforms for requirement files. + + These points are the result of a discussion on the `github pull + request #3514 `_. + + Valid characters in variable names follow the `POSIX standard + `_ and are limited + to uppercase letter, digits and the `_` (underscore). + """ + for line_number, line in lines_enum: + for env_var, var_name in ENV_VAR_RE.findall(line): + value = os.getenv(var_name) + if not value: + continue + + line = line.replace(env_var, value) + + yield line_number, line + + +def get_file_content(url, session): + # type: (str, PipSession) -> Tuple[str, str] + """Gets the content of a file; it may be a filename, file: URL, or + http: URL. Returns (location, content). Content is unicode. + Respects # -*- coding: declarations on the retrieved files. + + :param url: File path or url. + :param session: PipSession instance. + """ + scheme = get_url_scheme(url) + + if scheme in ['http', 'https']: + # FIXME: catch some errors + resp = session.get(url) + raise_for_status(resp) + return resp.url, resp.text + + elif scheme == 'file': + url = url_to_path(url) + + try: + with open(url, 'rb') as f: + content = auto_decode(f.read()) + except OSError as exc: + raise InstallationError( + f'Could not open requirements file: {exc}' + ) + return url, content diff --git a/venv/Lib/site-packages/pip/_internal/req/req_install.py b/venv/Lib/site-packages/pip/_internal/req/req_install.py new file mode 100644 index 0000000..6d0aa30 --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/req/req_install.py @@ -0,0 +1,879 @@ +# The following comment should be removed at some point in the future. +# mypy: strict-optional=False + +import logging +import os +import shutil +import sys +import uuid +import zipfile + +from pip._vendor import pkg_resources, six +from pip._vendor.packaging.requirements import Requirement +from pip._vendor.packaging.utils import canonicalize_name +from pip._vendor.packaging.version import Version +from pip._vendor.packaging.version import parse as parse_version +from pip._vendor.pep517.wrappers import Pep517HookCaller + +from pip._internal.build_env import NoOpBuildEnvironment +from pip._internal.exceptions import InstallationError +from pip._internal.locations import get_scheme +from pip._internal.models.link import Link +from pip._internal.operations.build.metadata import generate_metadata +from pip._internal.operations.build.metadata_legacy import ( + generate_metadata as generate_metadata_legacy, +) +from pip._internal.operations.install.editable_legacy import ( + install_editable as install_editable_legacy, +) +from pip._internal.operations.install.legacy import LegacyInstallFailure +from pip._internal.operations.install.legacy import install as install_legacy +from pip._internal.operations.install.wheel import install_wheel +from pip._internal.pyproject import load_pyproject_toml, make_pyproject_path +from pip._internal.req.req_uninstall import UninstallPathSet +from pip._internal.utils.deprecation import deprecated +from pip._internal.utils.direct_url_helpers import direct_url_from_link +from pip._internal.utils.hashes import Hashes +from pip._internal.utils.logging import indent_log +from pip._internal.utils.misc import ( + ask_path_exists, + backup_dir, + display_path, + dist_in_site_packages, + dist_in_usersite, + get_distribution, + get_installed_version, + hide_url, + redact_auth_from_url, +) +from pip._internal.utils.packaging import get_metadata +from pip._internal.utils.temp_dir import TempDirectory, tempdir_kinds +from pip._internal.utils.typing import MYPY_CHECK_RUNNING +from pip._internal.utils.virtualenv import running_under_virtualenv +from pip._internal.vcs import vcs + +if MYPY_CHECK_RUNNING: + from typing import Any, Dict, Iterable, List, Optional, Sequence, Union + + from pip._vendor.packaging.markers import Marker + from pip._vendor.packaging.specifiers import SpecifierSet + from pip._vendor.pkg_resources import Distribution + + from pip._internal.build_env import BuildEnvironment + + +logger = logging.getLogger(__name__) + + +def _get_dist(metadata_directory): + # type: (str) -> Distribution + """Return a pkg_resources.Distribution for the provided + metadata directory. + """ + dist_dir = metadata_directory.rstrip(os.sep) + + # Build a PathMetadata object, from path to metadata. :wink: + base_dir, dist_dir_name = os.path.split(dist_dir) + metadata = pkg_resources.PathMetadata(base_dir, dist_dir) + + # Determine the correct Distribution object type. + if dist_dir.endswith(".egg-info"): + dist_cls = pkg_resources.Distribution + dist_name = os.path.splitext(dist_dir_name)[0] + else: + assert dist_dir.endswith(".dist-info") + dist_cls = pkg_resources.DistInfoDistribution + dist_name = os.path.splitext(dist_dir_name)[0].split("-")[0] + + return dist_cls( + base_dir, + project_name=dist_name, + metadata=metadata, + ) + + +class InstallRequirement: + """ + Represents something that may be installed later on, may have information + about where to fetch the relevant requirement and also contains logic for + installing the said requirement. + """ + + def __init__( + self, + req, # type: Optional[Requirement] + comes_from, # type: Optional[Union[str, InstallRequirement]] + editable=False, # type: bool + link=None, # type: Optional[Link] + markers=None, # type: Optional[Marker] + use_pep517=None, # type: Optional[bool] + isolated=False, # type: bool + install_options=None, # type: Optional[List[str]] + global_options=None, # type: Optional[List[str]] + hash_options=None, # type: Optional[Dict[str, List[str]]] + constraint=False, # type: bool + extras=(), # type: Iterable[str] + user_supplied=False, # type: bool + ): + # type: (...) -> None + assert req is None or isinstance(req, Requirement), req + self.req = req + self.comes_from = comes_from + self.constraint = constraint + self.editable = editable + self.legacy_install_reason = None # type: Optional[int] + + # source_dir is the local directory where the linked requirement is + # located, or unpacked. In case unpacking is needed, creating and + # populating source_dir is done by the RequirementPreparer. Note this + # is not necessarily the directory where pyproject.toml or setup.py is + # located - that one is obtained via unpacked_source_directory. + self.source_dir = None # type: Optional[str] + if self.editable: + assert link + if link.is_file: + self.source_dir = os.path.normpath( + os.path.abspath(link.file_path) + ) + + if link is None and req and req.url: + # PEP 508 URL requirement + link = Link(req.url) + self.link = self.original_link = link + self.original_link_is_in_wheel_cache = False + + # Path to any downloaded or already-existing package. + self.local_file_path = None # type: Optional[str] + if self.link and self.link.is_file: + self.local_file_path = self.link.file_path + + if extras: + self.extras = extras + elif req: + self.extras = { + pkg_resources.safe_extra(extra) for extra in req.extras + } + else: + self.extras = set() + if markers is None and req: + markers = req.marker + self.markers = markers + + # This holds the pkg_resources.Distribution object if this requirement + # is already available: + self.satisfied_by = None # type: Optional[Distribution] + # Whether the installation process should try to uninstall an existing + # distribution before installing this requirement. + self.should_reinstall = False + # Temporary build location + self._temp_build_dir = None # type: Optional[TempDirectory] + # Set to True after successful installation + self.install_succeeded = None # type: Optional[bool] + # Supplied options + self.install_options = install_options if install_options else [] + self.global_options = global_options if global_options else [] + self.hash_options = hash_options if hash_options else {} + # Set to True after successful preparation of this requirement + self.prepared = False + # User supplied requirement are explicitly requested for installation + # by the user via CLI arguments or requirements files, as opposed to, + # e.g. dependencies, extras or constraints. + self.user_supplied = user_supplied + + self.isolated = isolated + self.build_env = NoOpBuildEnvironment() # type: BuildEnvironment + + # For PEP 517, the directory where we request the project metadata + # gets stored. We need this to pass to build_wheel, so the backend + # can ensure that the wheel matches the metadata (see the PEP for + # details). + self.metadata_directory = None # type: Optional[str] + + # The static build requirements (from pyproject.toml) + self.pyproject_requires = None # type: Optional[List[str]] + + # Build requirements that we will check are available + self.requirements_to_check = [] # type: List[str] + + # The PEP 517 backend we should use to build the project + self.pep517_backend = None # type: Optional[Pep517HookCaller] + + # Are we using PEP 517 for this requirement? + # After pyproject.toml has been loaded, the only valid values are True + # and False. Before loading, None is valid (meaning "use the default"). + # Setting an explicit value before loading pyproject.toml is supported, + # but after loading this flag should be treated as read only. + self.use_pep517 = use_pep517 + + # This requirement needs more preparation before it can be built + self.needs_more_preparation = False + + def __str__(self): + # type: () -> str + if self.req: + s = str(self.req) + if self.link: + s += ' from {}'.format(redact_auth_from_url(self.link.url)) + elif self.link: + s = redact_auth_from_url(self.link.url) + else: + s = '' + if self.satisfied_by is not None: + s += ' in {}'.format(display_path(self.satisfied_by.location)) + if self.comes_from: + if isinstance(self.comes_from, str): + comes_from = self.comes_from # type: Optional[str] + else: + comes_from = self.comes_from.from_path() + if comes_from: + s += f' (from {comes_from})' + return s + + def __repr__(self): + # type: () -> str + return '<{} object: {} editable={!r}>'.format( + self.__class__.__name__, str(self), self.editable) + + def format_debug(self): + # type: () -> str + """An un-tested helper for getting state, for debugging. + """ + attributes = vars(self) + names = sorted(attributes) + + state = ( + "{}={!r}".format(attr, attributes[attr]) for attr in sorted(names) + ) + return '<{name} object: {{{state}}}>'.format( + name=self.__class__.__name__, + state=", ".join(state), + ) + + # Things that are valid for all kinds of requirements? + @property + def name(self): + # type: () -> Optional[str] + if self.req is None: + return None + return six.ensure_str(pkg_resources.safe_name(self.req.name)) + + @property + def specifier(self): + # type: () -> SpecifierSet + return self.req.specifier + + @property + def is_pinned(self): + # type: () -> bool + """Return whether I am pinned to an exact version. + + For example, some-package==1.2 is pinned; some-package>1.2 is not. + """ + specifiers = self.specifier + return (len(specifiers) == 1 and + next(iter(specifiers)).operator in {'==', '==='}) + + @property + def installed_version(self): + # type: () -> Optional[str] + return get_installed_version(self.name) + + def match_markers(self, extras_requested=None): + # type: (Optional[Iterable[str]]) -> bool + if not extras_requested: + # Provide an extra to safely evaluate the markers + # without matching any extra + extras_requested = ('',) + if self.markers is not None: + return any( + self.markers.evaluate({'extra': extra}) + for extra in extras_requested) + else: + return True + + @property + def has_hash_options(self): + # type: () -> bool + """Return whether any known-good hashes are specified as options. + + These activate --require-hashes mode; hashes specified as part of a + URL do not. + + """ + return bool(self.hash_options) + + def hashes(self, trust_internet=True): + # type: (bool) -> Hashes + """Return a hash-comparer that considers my option- and URL-based + hashes to be known-good. + + Hashes in URLs--ones embedded in the requirements file, not ones + downloaded from an index server--are almost peers with ones from + flags. They satisfy --require-hashes (whether it was implicitly or + explicitly activated) but do not activate it. md5 and sha224 are not + allowed in flags, which should nudge people toward good algos. We + always OR all hashes together, even ones from URLs. + + :param trust_internet: Whether to trust URL-based (#md5=...) hashes + downloaded from the internet, as by populate_link() + + """ + good_hashes = self.hash_options.copy() + link = self.link if trust_internet else self.original_link + if link and link.hash: + good_hashes.setdefault(link.hash_name, []).append(link.hash) + return Hashes(good_hashes) + + def from_path(self): + # type: () -> Optional[str] + """Format a nice indicator to show where this "comes from" + """ + if self.req is None: + return None + s = str(self.req) + if self.comes_from: + if isinstance(self.comes_from, str): + comes_from = self.comes_from + else: + comes_from = self.comes_from.from_path() + if comes_from: + s += '->' + comes_from + return s + + def ensure_build_location(self, build_dir, autodelete, parallel_builds): + # type: (str, bool, bool) -> str + assert build_dir is not None + if self._temp_build_dir is not None: + assert self._temp_build_dir.path + return self._temp_build_dir.path + if self.req is None: + # Some systems have /tmp as a symlink which confuses custom + # builds (such as numpy). Thus, we ensure that the real path + # is returned. + self._temp_build_dir = TempDirectory( + kind=tempdir_kinds.REQ_BUILD, globally_managed=True + ) + + return self._temp_build_dir.path + + # This is the only remaining place where we manually determine the path + # for the temporary directory. It is only needed for editables where + # it is the value of the --src option. + + # When parallel builds are enabled, add a UUID to the build directory + # name so multiple builds do not interfere with each other. + dir_name = canonicalize_name(self.name) + if parallel_builds: + dir_name = f"{dir_name}_{uuid.uuid4().hex}" + + # FIXME: Is there a better place to create the build_dir? (hg and bzr + # need this) + if not os.path.exists(build_dir): + logger.debug('Creating directory %s', build_dir) + os.makedirs(build_dir) + actual_build_dir = os.path.join(build_dir, dir_name) + # `None` indicates that we respect the globally-configured deletion + # settings, which is what we actually want when auto-deleting. + delete_arg = None if autodelete else False + return TempDirectory( + path=actual_build_dir, + delete=delete_arg, + kind=tempdir_kinds.REQ_BUILD, + globally_managed=True, + ).path + + def _set_requirement(self): + # type: () -> None + """Set requirement after generating metadata. + """ + assert self.req is None + assert self.metadata is not None + assert self.source_dir is not None + + # Construct a Requirement object from the generated metadata + if isinstance(parse_version(self.metadata["Version"]), Version): + op = "==" + else: + op = "===" + + self.req = Requirement( + "".join([ + self.metadata["Name"], + op, + self.metadata["Version"], + ]) + ) + + def warn_on_mismatching_name(self): + # type: () -> None + metadata_name = canonicalize_name(self.metadata["Name"]) + if canonicalize_name(self.req.name) == metadata_name: + # Everything is fine. + return + + # If we're here, there's a mismatch. Log a warning about it. + logger.warning( + 'Generating metadata for package %s ' + 'produced metadata for project name %s. Fix your ' + '#egg=%s fragments.', + self.name, metadata_name, self.name + ) + self.req = Requirement(metadata_name) + + def check_if_exists(self, use_user_site): + # type: (bool) -> None + """Find an installed distribution that satisfies or conflicts + with this requirement, and set self.satisfied_by or + self.should_reinstall appropriately. + """ + if self.req is None: + return + existing_dist = get_distribution(self.req.name) + if not existing_dist: + return + + existing_version = existing_dist.parsed_version + if not self.req.specifier.contains(existing_version, prereleases=True): + self.satisfied_by = None + if use_user_site: + if dist_in_usersite(existing_dist): + self.should_reinstall = True + elif (running_under_virtualenv() and + dist_in_site_packages(existing_dist)): + raise InstallationError( + "Will not install to the user site because it will " + "lack sys.path precedence to {} in {}".format( + existing_dist.project_name, existing_dist.location) + ) + else: + self.should_reinstall = True + else: + if self.editable: + self.should_reinstall = True + # when installing editables, nothing pre-existing should ever + # satisfy + self.satisfied_by = None + else: + self.satisfied_by = existing_dist + + # Things valid for wheels + @property + def is_wheel(self): + # type: () -> bool + if not self.link: + return False + return self.link.is_wheel + + # Things valid for sdists + @property + def unpacked_source_directory(self): + # type: () -> str + return os.path.join( + self.source_dir, + self.link and self.link.subdirectory_fragment or '') + + @property + def setup_py_path(self): + # type: () -> str + assert self.source_dir, f"No source dir for {self}" + setup_py = os.path.join(self.unpacked_source_directory, 'setup.py') + + return setup_py + + @property + def pyproject_toml_path(self): + # type: () -> str + assert self.source_dir, f"No source dir for {self}" + return make_pyproject_path(self.unpacked_source_directory) + + def load_pyproject_toml(self): + # type: () -> None + """Load the pyproject.toml file. + + After calling this routine, all of the attributes related to PEP 517 + processing for this requirement have been set. In particular, the + use_pep517 attribute can be used to determine whether we should + follow the PEP 517 or legacy (setup.py) code path. + """ + pyproject_toml_data = load_pyproject_toml( + self.use_pep517, + self.pyproject_toml_path, + self.setup_py_path, + str(self) + ) + + if pyproject_toml_data is None: + self.use_pep517 = False + return + + self.use_pep517 = True + requires, backend, check, backend_path = pyproject_toml_data + self.requirements_to_check = check + self.pyproject_requires = requires + self.pep517_backend = Pep517HookCaller( + self.unpacked_source_directory, backend, backend_path=backend_path, + ) + + def _generate_metadata(self): + # type: () -> str + """Invokes metadata generator functions, with the required arguments. + """ + if not self.use_pep517: + assert self.unpacked_source_directory + + return generate_metadata_legacy( + build_env=self.build_env, + setup_py_path=self.setup_py_path, + source_dir=self.unpacked_source_directory, + isolated=self.isolated, + details=self.name or f"from {self.link}" + ) + + assert self.pep517_backend is not None + + return generate_metadata( + build_env=self.build_env, + backend=self.pep517_backend, + ) + + def prepare_metadata(self): + # type: () -> None + """Ensure that project metadata is available. + + Under PEP 517, call the backend hook to prepare the metadata. + Under legacy processing, call setup.py egg-info. + """ + assert self.source_dir + + with indent_log(): + self.metadata_directory = self._generate_metadata() + + # Act on the newly generated metadata, based on the name and version. + if not self.name: + self._set_requirement() + else: + self.warn_on_mismatching_name() + + self.assert_source_matches_version() + + @property + def metadata(self): + # type: () -> Any + if not hasattr(self, '_metadata'): + self._metadata = get_metadata(self.get_dist()) + + return self._metadata + + def get_dist(self): + # type: () -> Distribution + return _get_dist(self.metadata_directory) + + def assert_source_matches_version(self): + # type: () -> None + assert self.source_dir + version = self.metadata['version'] + if self.req.specifier and version not in self.req.specifier: + logger.warning( + 'Requested %s, but installing version %s', + self, + version, + ) + else: + logger.debug( + 'Source in %s has version %s, which satisfies requirement %s', + display_path(self.source_dir), + version, + self, + ) + + # For both source distributions and editables + def ensure_has_source_dir( + self, + parent_dir, + autodelete=False, + parallel_builds=False, + ): + # type: (str, bool, bool) -> None + """Ensure that a source_dir is set. + + This will create a temporary build dir if the name of the requirement + isn't known yet. + + :param parent_dir: The ideal pip parent_dir for the source_dir. + Generally src_dir for editables and build_dir for sdists. + :return: self.source_dir + """ + if self.source_dir is None: + self.source_dir = self.ensure_build_location( + parent_dir, + autodelete=autodelete, + parallel_builds=parallel_builds, + ) + + # For editable installations + def update_editable(self): + # type: () -> None + if not self.link: + logger.debug( + "Cannot update repository at %s; repository location is " + "unknown", + self.source_dir, + ) + return + assert self.editable + assert self.source_dir + if self.link.scheme == 'file': + # Static paths don't get updated + return + vcs_backend = vcs.get_backend_for_scheme(self.link.scheme) + # Editable requirements are validated in Requirement constructors. + # So here, if it's neither a path nor a valid VCS URL, it's a bug. + assert vcs_backend, f"Unsupported VCS URL {self.link.url}" + hidden_url = hide_url(self.link.url) + vcs_backend.obtain(self.source_dir, url=hidden_url) + + # Top-level Actions + def uninstall(self, auto_confirm=False, verbose=False): + # type: (bool, bool) -> Optional[UninstallPathSet] + """ + Uninstall the distribution currently satisfying this requirement. + + Prompts before removing or modifying files unless + ``auto_confirm`` is True. + + Refuses to delete or modify files outside of ``sys.prefix`` - + thus uninstallation within a virtual environment can only + modify that virtual environment, even if the virtualenv is + linked to global site-packages. + + """ + assert self.req + dist = get_distribution(self.req.name) + if not dist: + logger.warning("Skipping %s as it is not installed.", self.name) + return None + logger.info('Found existing installation: %s', dist) + + uninstalled_pathset = UninstallPathSet.from_dist(dist) + uninstalled_pathset.remove(auto_confirm, verbose) + return uninstalled_pathset + + def _get_archive_name(self, path, parentdir, rootdir): + # type: (str, str, str) -> str + + def _clean_zip_name(name, prefix): + # type: (str, str) -> str + assert name.startswith(prefix + os.path.sep), ( + "name {name!r} doesn't start with prefix {prefix!r}" + .format(**locals()) + ) + name = name[len(prefix) + 1:] + name = name.replace(os.path.sep, '/') + return name + + path = os.path.join(parentdir, path) + name = _clean_zip_name(path, rootdir) + return self.name + '/' + name + + def archive(self, build_dir): + # type: (Optional[str]) -> None + """Saves archive to provided build_dir. + + Used for saving downloaded VCS requirements as part of `pip download`. + """ + assert self.source_dir + if build_dir is None: + return + + create_archive = True + archive_name = '{}-{}.zip'.format(self.name, self.metadata["version"]) + archive_path = os.path.join(build_dir, archive_name) + + if os.path.exists(archive_path): + response = ask_path_exists( + 'The file {} exists. (i)gnore, (w)ipe, ' + '(b)ackup, (a)bort '.format( + display_path(archive_path)), + ('i', 'w', 'b', 'a')) + if response == 'i': + create_archive = False + elif response == 'w': + logger.warning('Deleting %s', display_path(archive_path)) + os.remove(archive_path) + elif response == 'b': + dest_file = backup_dir(archive_path) + logger.warning( + 'Backing up %s to %s', + display_path(archive_path), + display_path(dest_file), + ) + shutil.move(archive_path, dest_file) + elif response == 'a': + sys.exit(-1) + + if not create_archive: + return + + zip_output = zipfile.ZipFile( + archive_path, 'w', zipfile.ZIP_DEFLATED, allowZip64=True, + ) + with zip_output: + dir = os.path.normcase( + os.path.abspath(self.unpacked_source_directory) + ) + for dirpath, dirnames, filenames in os.walk(dir): + for dirname in dirnames: + dir_arcname = self._get_archive_name( + dirname, parentdir=dirpath, rootdir=dir, + ) + zipdir = zipfile.ZipInfo(dir_arcname + '/') + zipdir.external_attr = 0x1ED << 16 # 0o755 + zip_output.writestr(zipdir, '') + for filename in filenames: + file_arcname = self._get_archive_name( + filename, parentdir=dirpath, rootdir=dir, + ) + filename = os.path.join(dirpath, filename) + zip_output.write(filename, file_arcname) + + logger.info('Saved %s', display_path(archive_path)) + + def install( + self, + install_options, # type: List[str] + global_options=None, # type: Optional[Sequence[str]] + root=None, # type: Optional[str] + home=None, # type: Optional[str] + prefix=None, # type: Optional[str] + warn_script_location=True, # type: bool + use_user_site=False, # type: bool + pycompile=True # type: bool + ): + # type: (...) -> None + scheme = get_scheme( + self.name, + user=use_user_site, + home=home, + root=root, + isolated=self.isolated, + prefix=prefix, + ) + + global_options = global_options if global_options is not None else [] + if self.editable: + install_editable_legacy( + install_options, + global_options, + prefix=prefix, + home=home, + use_user_site=use_user_site, + name=self.name, + setup_py_path=self.setup_py_path, + isolated=self.isolated, + build_env=self.build_env, + unpacked_source_directory=self.unpacked_source_directory, + ) + self.install_succeeded = True + return + + if self.is_wheel: + assert self.local_file_path + direct_url = None + if self.original_link: + direct_url = direct_url_from_link( + self.original_link, + self.source_dir, + self.original_link_is_in_wheel_cache, + ) + install_wheel( + self.name, + self.local_file_path, + scheme=scheme, + req_description=str(self.req), + pycompile=pycompile, + warn_script_location=warn_script_location, + direct_url=direct_url, + requested=self.user_supplied, + ) + self.install_succeeded = True + return + + # TODO: Why don't we do this for editable installs? + + # Extend the list of global and install options passed on to + # the setup.py call with the ones from the requirements file. + # Options specified in requirements file override those + # specified on the command line, since the last option given + # to setup.py is the one that is used. + global_options = list(global_options) + self.global_options + install_options = list(install_options) + self.install_options + + try: + success = install_legacy( + install_options=install_options, + global_options=global_options, + root=root, + home=home, + prefix=prefix, + use_user_site=use_user_site, + pycompile=pycompile, + scheme=scheme, + setup_py_path=self.setup_py_path, + isolated=self.isolated, + req_name=self.name, + build_env=self.build_env, + unpacked_source_directory=self.unpacked_source_directory, + req_description=str(self.req), + ) + except LegacyInstallFailure as exc: + self.install_succeeded = False + six.reraise(*exc.parent) + except Exception: + self.install_succeeded = True + raise + + self.install_succeeded = success + + if success and self.legacy_install_reason == 8368: + deprecated( + reason=( + "{} was installed using the legacy 'setup.py install' " + "method, because a wheel could not be built for it.". + format(self.name) + ), + replacement="to fix the wheel build issue reported above", + gone_in=None, + issue=8368, + ) + + +def check_invalid_constraint_type(req): + # type: (InstallRequirement) -> str + + # Check for unsupported forms + problem = "" + if not req.name: + problem = "Unnamed requirements are not allowed as constraints" + elif req.link: + problem = "Links are not allowed as constraints" + elif req.extras: + problem = "Constraints cannot have extras" + + if problem: + deprecated( + reason=( + "Constraints are only allowed to take the form of a package " + "name and a version specifier. Other forms were originally " + "permitted as an accident of the implementation, but were " + "undocumented. The new implementation of the resolver no " + "longer supports these forms." + ), + replacement=( + "replacing the constraint with a requirement." + ), + # No plan yet for when the new resolver becomes default + gone_in=None, + issue=8210 + ) + + return problem diff --git a/venv/Lib/site-packages/pip/_internal/req/req_set.py b/venv/Lib/site-packages/pip/_internal/req/req_set.py new file mode 100644 index 0000000..fa58be6 --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/req/req_set.py @@ -0,0 +1,202 @@ +import logging +from collections import OrderedDict + +from pip._vendor.packaging.utils import canonicalize_name + +from pip._internal.exceptions import InstallationError +from pip._internal.models.wheel import Wheel +from pip._internal.utils import compatibility_tags +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import Dict, Iterable, List, Optional, Tuple + + from pip._internal.req.req_install import InstallRequirement + + +logger = logging.getLogger(__name__) + + +class RequirementSet: + + def __init__(self, check_supported_wheels=True): + # type: (bool) -> None + """Create a RequirementSet. + """ + + self.requirements = OrderedDict() # type: Dict[str, InstallRequirement] + self.check_supported_wheels = check_supported_wheels + + self.unnamed_requirements = [] # type: List[InstallRequirement] + + def __str__(self): + # type: () -> str + requirements = sorted( + (req for req in self.requirements.values() if not req.comes_from), + key=lambda req: canonicalize_name(req.name), + ) + return ' '.join(str(req.req) for req in requirements) + + def __repr__(self): + # type: () -> str + requirements = sorted( + self.requirements.values(), + key=lambda req: canonicalize_name(req.name), + ) + + format_string = '<{classname} object; {count} requirement(s): {reqs}>' + return format_string.format( + classname=self.__class__.__name__, + count=len(requirements), + reqs=', '.join(str(req.req) for req in requirements), + ) + + def add_unnamed_requirement(self, install_req): + # type: (InstallRequirement) -> None + assert not install_req.name + self.unnamed_requirements.append(install_req) + + def add_named_requirement(self, install_req): + # type: (InstallRequirement) -> None + assert install_req.name + + project_name = canonicalize_name(install_req.name) + self.requirements[project_name] = install_req + + def add_requirement( + self, + install_req, # type: InstallRequirement + parent_req_name=None, # type: Optional[str] + extras_requested=None # type: Optional[Iterable[str]] + ): + # type: (...) -> Tuple[List[InstallRequirement], Optional[InstallRequirement]] + """Add install_req as a requirement to install. + + :param parent_req_name: The name of the requirement that needed this + added. The name is used because when multiple unnamed requirements + resolve to the same name, we could otherwise end up with dependency + links that point outside the Requirements set. parent_req must + already be added. Note that None implies that this is a user + supplied requirement, vs an inferred one. + :param extras_requested: an iterable of extras used to evaluate the + environment markers. + :return: Additional requirements to scan. That is either [] if + the requirement is not applicable, or [install_req] if the + requirement is applicable and has just been added. + """ + # If the markers do not match, ignore this requirement. + if not install_req.match_markers(extras_requested): + logger.info( + "Ignoring %s: markers '%s' don't match your environment", + install_req.name, install_req.markers, + ) + return [], None + + # If the wheel is not supported, raise an error. + # Should check this after filtering out based on environment markers to + # allow specifying different wheels based on the environment/OS, in a + # single requirements file. + if install_req.link and install_req.link.is_wheel: + wheel = Wheel(install_req.link.filename) + tags = compatibility_tags.get_supported() + if (self.check_supported_wheels and not wheel.supported(tags)): + raise InstallationError( + "{} is not a supported wheel on this platform.".format( + wheel.filename) + ) + + # This next bit is really a sanity check. + assert not install_req.user_supplied or parent_req_name is None, ( + "a user supplied req shouldn't have a parent" + ) + + # Unnamed requirements are scanned again and the requirement won't be + # added as a dependency until after scanning. + if not install_req.name: + self.add_unnamed_requirement(install_req) + return [install_req], None + + try: + existing_req = self.get_requirement( + install_req.name) # type: Optional[InstallRequirement] + except KeyError: + existing_req = None + + has_conflicting_requirement = ( + parent_req_name is None and + existing_req and + not existing_req.constraint and + existing_req.extras == install_req.extras and + existing_req.req.specifier != install_req.req.specifier + ) + if has_conflicting_requirement: + raise InstallationError( + "Double requirement given: {} (already in {}, name={!r})" + .format(install_req, existing_req, install_req.name) + ) + + # When no existing requirement exists, add the requirement as a + # dependency and it will be scanned again after. + if not existing_req: + self.add_named_requirement(install_req) + # We'd want to rescan this requirement later + return [install_req], install_req + + # Assume there's no need to scan, and that we've already + # encountered this for scanning. + if install_req.constraint or not existing_req.constraint: + return [], existing_req + + does_not_satisfy_constraint = ( + install_req.link and + not ( + existing_req.link and + install_req.link.path == existing_req.link.path + ) + ) + if does_not_satisfy_constraint: + raise InstallationError( + "Could not satisfy constraints for '{}': " + "installation from path or url cannot be " + "constrained to a version".format(install_req.name) + ) + # If we're now installing a constraint, mark the existing + # object for real installation. + existing_req.constraint = False + # If we're now installing a user supplied requirement, + # mark the existing object as such. + if install_req.user_supplied: + existing_req.user_supplied = True + existing_req.extras = tuple(sorted( + set(existing_req.extras) | set(install_req.extras) + )) + logger.debug( + "Setting %s extras to: %s", + existing_req, existing_req.extras, + ) + # Return the existing requirement for addition to the parent and + # scanning again. + return [existing_req], existing_req + + def has_requirement(self, name): + # type: (str) -> bool + project_name = canonicalize_name(name) + + return ( + project_name in self.requirements and + not self.requirements[project_name].constraint + ) + + def get_requirement(self, name): + # type: (str) -> InstallRequirement + project_name = canonicalize_name(name) + + if project_name in self.requirements: + return self.requirements[project_name] + + raise KeyError("No project with the name {name!r}".format(**locals())) + + @property + def all_requirements(self): + # type: () -> List[InstallRequirement] + return self.unnamed_requirements + list(self.requirements.values()) diff --git a/venv/Lib/site-packages/pip/_internal/req/req_tracker.py b/venv/Lib/site-packages/pip/_internal/req/req_tracker.py new file mode 100644 index 0000000..daa5b44 --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/req/req_tracker.py @@ -0,0 +1,146 @@ +import contextlib +import hashlib +import logging +import os + +from pip._vendor import contextlib2 + +from pip._internal.utils.temp_dir import TempDirectory +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from types import TracebackType + from typing import Dict, Iterator, Optional, Set, Type, Union + + from pip._internal.models.link import Link + from pip._internal.req.req_install import InstallRequirement + +logger = logging.getLogger(__name__) + + +@contextlib.contextmanager +def update_env_context_manager(**changes): + # type: (str) -> Iterator[None] + target = os.environ + + # Save values from the target and change them. + non_existent_marker = object() + saved_values = {} # type: Dict[str, Union[object, str]] + for name, new_value in changes.items(): + try: + saved_values[name] = target[name] + except KeyError: + saved_values[name] = non_existent_marker + target[name] = new_value + + try: + yield + finally: + # Restore original values in the target. + for name, original_value in saved_values.items(): + if original_value is non_existent_marker: + del target[name] + else: + assert isinstance(original_value, str) # for mypy + target[name] = original_value + + +@contextlib.contextmanager +def get_requirement_tracker(): + # type: () -> Iterator[RequirementTracker] + root = os.environ.get('PIP_REQ_TRACKER') + with contextlib2.ExitStack() as ctx: + if root is None: + root = ctx.enter_context( + TempDirectory(kind='req-tracker') + ).path + ctx.enter_context(update_env_context_manager(PIP_REQ_TRACKER=root)) + logger.debug("Initialized build tracking at %s", root) + + with RequirementTracker(root) as tracker: + yield tracker + + +class RequirementTracker: + + def __init__(self, root): + # type: (str) -> None + self._root = root + self._entries = set() # type: Set[InstallRequirement] + logger.debug("Created build tracker: %s", self._root) + + def __enter__(self): + # type: () -> RequirementTracker + logger.debug("Entered build tracker: %s", self._root) + return self + + def __exit__( + self, + exc_type, # type: Optional[Type[BaseException]] + exc_val, # type: Optional[BaseException] + exc_tb # type: Optional[TracebackType] + ): + # type: (...) -> None + self.cleanup() + + def _entry_path(self, link): + # type: (Link) -> str + hashed = hashlib.sha224(link.url_without_fragment.encode()).hexdigest() + return os.path.join(self._root, hashed) + + def add(self, req): + # type: (InstallRequirement) -> None + """Add an InstallRequirement to build tracking. + """ + + assert req.link + # Get the file to write information about this requirement. + entry_path = self._entry_path(req.link) + + # Try reading from the file. If it exists and can be read from, a build + # is already in progress, so a LookupError is raised. + try: + with open(entry_path) as fp: + contents = fp.read() + except FileNotFoundError: + pass + else: + message = '{} is already being built: {}'.format( + req.link, contents) + raise LookupError(message) + + # If we're here, req should really not be building already. + assert req not in self._entries + + # Start tracking this requirement. + with open(entry_path, 'w') as fp: + fp.write(str(req)) + self._entries.add(req) + + logger.debug('Added %s to build tracker %r', req, self._root) + + def remove(self, req): + # type: (InstallRequirement) -> None + """Remove an InstallRequirement from build tracking. + """ + + assert req.link + # Delete the created file and the corresponding entries. + os.unlink(self._entry_path(req.link)) + self._entries.remove(req) + + logger.debug('Removed %s from build tracker %r', req, self._root) + + def cleanup(self): + # type: () -> None + for req in set(self._entries): + self.remove(req) + + logger.debug("Removed build tracker: %r", self._root) + + @contextlib.contextmanager + def track(self, req): + # type: (InstallRequirement) -> Iterator[None] + self.add(req) + yield + self.remove(req) diff --git a/venv/Lib/site-packages/pip/_internal/req/req_uninstall.py b/venv/Lib/site-packages/pip/_internal/req/req_uninstall.py new file mode 100644 index 0000000..a37a378 --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/req/req_uninstall.py @@ -0,0 +1,654 @@ +import csv +import functools +import logging +import os +import sys +import sysconfig +from importlib.util import cache_from_source + +from pip._vendor import pkg_resources + +from pip._internal.exceptions import UninstallationError +from pip._internal.locations import bin_py, bin_user +from pip._internal.utils.compat import WINDOWS +from pip._internal.utils.logging import indent_log +from pip._internal.utils.misc import ( + ask, + dist_in_usersite, + dist_is_local, + egg_link_path, + is_local, + normalize_path, + renames, + rmtree, +) +from pip._internal.utils.temp_dir import AdjacentTempDirectory, TempDirectory +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import ( + Any, + Callable, + Dict, + Iterable, + Iterator, + List, + Optional, + Set, + Tuple, + ) + + from pip._vendor.pkg_resources import Distribution + +logger = logging.getLogger(__name__) + + +def _script_names(dist, script_name, is_gui): + # type: (Distribution, str, bool) -> List[str] + """Create the fully qualified name of the files created by + {console,gui}_scripts for the given ``dist``. + Returns the list of file names + """ + if dist_in_usersite(dist): + bin_dir = bin_user + else: + bin_dir = bin_py + exe_name = os.path.join(bin_dir, script_name) + paths_to_remove = [exe_name] + if WINDOWS: + paths_to_remove.append(exe_name + '.exe') + paths_to_remove.append(exe_name + '.exe.manifest') + if is_gui: + paths_to_remove.append(exe_name + '-script.pyw') + else: + paths_to_remove.append(exe_name + '-script.py') + return paths_to_remove + + +def _unique(fn): + # type: (Callable[..., Iterator[Any]]) -> Callable[..., Iterator[Any]] + @functools.wraps(fn) + def unique(*args, **kw): + # type: (Any, Any) -> Iterator[Any] + seen = set() # type: Set[Any] + for item in fn(*args, **kw): + if item not in seen: + seen.add(item) + yield item + return unique + + +@_unique +def uninstallation_paths(dist): + # type: (Distribution) -> Iterator[str] + """ + Yield all the uninstallation paths for dist based on RECORD-without-.py[co] + + Yield paths to all the files in RECORD. For each .py file in RECORD, add + the .pyc and .pyo in the same directory. + + UninstallPathSet.add() takes care of the __pycache__ .py[co]. + """ + r = csv.reader(dist.get_metadata_lines('RECORD')) + for row in r: + path = os.path.join(dist.location, row[0]) + yield path + if path.endswith('.py'): + dn, fn = os.path.split(path) + base = fn[:-3] + path = os.path.join(dn, base + '.pyc') + yield path + path = os.path.join(dn, base + '.pyo') + yield path + + +def compact(paths): + # type: (Iterable[str]) -> Set[str] + """Compact a path set to contain the minimal number of paths + necessary to contain all paths in the set. If /a/path/ and + /a/path/to/a/file.txt are both in the set, leave only the + shorter path.""" + + sep = os.path.sep + short_paths = set() # type: Set[str] + for path in sorted(paths, key=len): + should_skip = any( + path.startswith(shortpath.rstrip("*")) and + path[len(shortpath.rstrip("*").rstrip(sep))] == sep + for shortpath in short_paths + ) + if not should_skip: + short_paths.add(path) + return short_paths + + +def compress_for_rename(paths): + # type: (Iterable[str]) -> Set[str] + """Returns a set containing the paths that need to be renamed. + + This set may include directories when the original sequence of paths + included every file on disk. + """ + case_map = {os.path.normcase(p): p for p in paths} + remaining = set(case_map) + unchecked = sorted({os.path.split(p)[0] for p in case_map.values()}, key=len) + wildcards = set() # type: Set[str] + + def norm_join(*a): + # type: (str) -> str + return os.path.normcase(os.path.join(*a)) + + for root in unchecked: + if any(os.path.normcase(root).startswith(w) + for w in wildcards): + # This directory has already been handled. + continue + + all_files = set() # type: Set[str] + all_subdirs = set() # type: Set[str] + for dirname, subdirs, files in os.walk(root): + all_subdirs.update(norm_join(root, dirname, d) + for d in subdirs) + all_files.update(norm_join(root, dirname, f) + for f in files) + # If all the files we found are in our remaining set of files to + # remove, then remove them from the latter set and add a wildcard + # for the directory. + if not (all_files - remaining): + remaining.difference_update(all_files) + wildcards.add(root + os.sep) + + return set(map(case_map.__getitem__, remaining)) | wildcards + + +def compress_for_output_listing(paths): + # type: (Iterable[str]) -> Tuple[Set[str], Set[str]] + """Returns a tuple of 2 sets of which paths to display to user + + The first set contains paths that would be deleted. Files of a package + are not added and the top-level directory of the package has a '*' added + at the end - to signify that all it's contents are removed. + + The second set contains files that would have been skipped in the above + folders. + """ + + will_remove = set(paths) + will_skip = set() + + # Determine folders and files + folders = set() + files = set() + for path in will_remove: + if path.endswith(".pyc"): + continue + if path.endswith("__init__.py") or ".dist-info" in path: + folders.add(os.path.dirname(path)) + files.add(path) + + # probably this one https://github.com/python/mypy/issues/390 + _normcased_files = set(map(os.path.normcase, files)) # type: ignore + + folders = compact(folders) + + # This walks the tree using os.walk to not miss extra folders + # that might get added. + for folder in folders: + for dirpath, _, dirfiles in os.walk(folder): + for fname in dirfiles: + if fname.endswith(".pyc"): + continue + + file_ = os.path.join(dirpath, fname) + if (os.path.isfile(file_) and + os.path.normcase(file_) not in _normcased_files): + # We are skipping this file. Add it to the set. + will_skip.add(file_) + + will_remove = files | { + os.path.join(folder, "*") for folder in folders + } + + return will_remove, will_skip + + +class StashedUninstallPathSet: + """A set of file rename operations to stash files while + tentatively uninstalling them.""" + def __init__(self): + # type: () -> None + # Mapping from source file root to [Adjacent]TempDirectory + # for files under that directory. + self._save_dirs = {} # type: Dict[str, TempDirectory] + # (old path, new path) tuples for each move that may need + # to be undone. + self._moves = [] # type: List[Tuple[str, str]] + + def _get_directory_stash(self, path): + # type: (str) -> str + """Stashes a directory. + + Directories are stashed adjacent to their original location if + possible, or else moved/copied into the user's temp dir.""" + + try: + save_dir = AdjacentTempDirectory(path) # type: TempDirectory + except OSError: + save_dir = TempDirectory(kind="uninstall") + self._save_dirs[os.path.normcase(path)] = save_dir + + return save_dir.path + + def _get_file_stash(self, path): + # type: (str) -> str + """Stashes a file. + + If no root has been provided, one will be created for the directory + in the user's temp directory.""" + path = os.path.normcase(path) + head, old_head = os.path.dirname(path), None + save_dir = None + + while head != old_head: + try: + save_dir = self._save_dirs[head] + break + except KeyError: + pass + head, old_head = os.path.dirname(head), head + else: + # Did not find any suitable root + head = os.path.dirname(path) + save_dir = TempDirectory(kind='uninstall') + self._save_dirs[head] = save_dir + + relpath = os.path.relpath(path, head) + if relpath and relpath != os.path.curdir: + return os.path.join(save_dir.path, relpath) + return save_dir.path + + def stash(self, path): + # type: (str) -> str + """Stashes the directory or file and returns its new location. + Handle symlinks as files to avoid modifying the symlink targets. + """ + path_is_dir = os.path.isdir(path) and not os.path.islink(path) + if path_is_dir: + new_path = self._get_directory_stash(path) + else: + new_path = self._get_file_stash(path) + + self._moves.append((path, new_path)) + if (path_is_dir and os.path.isdir(new_path)): + # If we're moving a directory, we need to + # remove the destination first or else it will be + # moved to inside the existing directory. + # We just created new_path ourselves, so it will + # be removable. + os.rmdir(new_path) + renames(path, new_path) + return new_path + + def commit(self): + # type: () -> None + """Commits the uninstall by removing stashed files.""" + for _, save_dir in self._save_dirs.items(): + save_dir.cleanup() + self._moves = [] + self._save_dirs = {} + + def rollback(self): + # type: () -> None + """Undoes the uninstall by moving stashed files back.""" + for p in self._moves: + logger.info("Moving to %s\n from %s", *p) + + for new_path, path in self._moves: + try: + logger.debug('Replacing %s from %s', new_path, path) + if os.path.isfile(new_path) or os.path.islink(new_path): + os.unlink(new_path) + elif os.path.isdir(new_path): + rmtree(new_path) + renames(path, new_path) + except OSError as ex: + logger.error("Failed to restore %s", new_path) + logger.debug("Exception: %s", ex) + + self.commit() + + @property + def can_rollback(self): + # type: () -> bool + return bool(self._moves) + + +class UninstallPathSet: + """A set of file paths to be removed in the uninstallation of a + requirement.""" + def __init__(self, dist): + # type: (Distribution) -> None + self.paths = set() # type: Set[str] + self._refuse = set() # type: Set[str] + self.pth = {} # type: Dict[str, UninstallPthEntries] + self.dist = dist + self._moved_paths = StashedUninstallPathSet() + + def _permitted(self, path): + # type: (str) -> bool + """ + Return True if the given path is one we are permitted to + remove/modify, False otherwise. + + """ + return is_local(path) + + def add(self, path): + # type: (str) -> None + head, tail = os.path.split(path) + + # we normalize the head to resolve parent directory symlinks, but not + # the tail, since we only want to uninstall symlinks, not their targets + path = os.path.join(normalize_path(head), os.path.normcase(tail)) + + if not os.path.exists(path): + return + if self._permitted(path): + self.paths.add(path) + else: + self._refuse.add(path) + + # __pycache__ files can show up after 'installed-files.txt' is created, + # due to imports + if os.path.splitext(path)[1] == '.py': + self.add(cache_from_source(path)) + + def add_pth(self, pth_file, entry): + # type: (str, str) -> None + pth_file = normalize_path(pth_file) + if self._permitted(pth_file): + if pth_file not in self.pth: + self.pth[pth_file] = UninstallPthEntries(pth_file) + self.pth[pth_file].add(entry) + else: + self._refuse.add(pth_file) + + def remove(self, auto_confirm=False, verbose=False): + # type: (bool, bool) -> None + """Remove paths in ``self.paths`` with confirmation (unless + ``auto_confirm`` is True).""" + + if not self.paths: + logger.info( + "Can't uninstall '%s'. No files were found to uninstall.", + self.dist.project_name, + ) + return + + dist_name_version = ( + self.dist.project_name + "-" + self.dist.version + ) + logger.info('Uninstalling %s:', dist_name_version) + + with indent_log(): + if auto_confirm or self._allowed_to_proceed(verbose): + moved = self._moved_paths + + for_rename = compress_for_rename(self.paths) + + for path in sorted(compact(for_rename)): + moved.stash(path) + logger.debug('Removing file or directory %s', path) + + for pth in self.pth.values(): + pth.remove() + + logger.info('Successfully uninstalled %s', dist_name_version) + + def _allowed_to_proceed(self, verbose): + # type: (bool) -> bool + """Display which files would be deleted and prompt for confirmation + """ + + def _display(msg, paths): + # type: (str, Iterable[str]) -> None + if not paths: + return + + logger.info(msg) + with indent_log(): + for path in sorted(compact(paths)): + logger.info(path) + + if not verbose: + will_remove, will_skip = compress_for_output_listing(self.paths) + else: + # In verbose mode, display all the files that are going to be + # deleted. + will_remove = set(self.paths) + will_skip = set() + + _display('Would remove:', will_remove) + _display('Would not remove (might be manually added):', will_skip) + _display('Would not remove (outside of prefix):', self._refuse) + if verbose: + _display('Will actually move:', compress_for_rename(self.paths)) + + return ask('Proceed (y/n)? ', ('y', 'n')) == 'y' + + def rollback(self): + # type: () -> None + """Rollback the changes previously made by remove().""" + if not self._moved_paths.can_rollback: + logger.error( + "Can't roll back %s; was not uninstalled", + self.dist.project_name, + ) + return + logger.info('Rolling back uninstall of %s', self.dist.project_name) + self._moved_paths.rollback() + for pth in self.pth.values(): + pth.rollback() + + def commit(self): + # type: () -> None + """Remove temporary save dir: rollback will no longer be possible.""" + self._moved_paths.commit() + + @classmethod + def from_dist(cls, dist): + # type: (Distribution) -> UninstallPathSet + dist_path = normalize_path(dist.location) + if not dist_is_local(dist): + logger.info( + "Not uninstalling %s at %s, outside environment %s", + dist.key, + dist_path, + sys.prefix, + ) + return cls(dist) + + if dist_path in {p for p in {sysconfig.get_path("stdlib"), + sysconfig.get_path("platstdlib")} + if p}: + logger.info( + "Not uninstalling %s at %s, as it is in the standard library.", + dist.key, + dist_path, + ) + return cls(dist) + + paths_to_remove = cls(dist) + develop_egg_link = egg_link_path(dist) + develop_egg_link_egg_info = '{}.egg-info'.format( + pkg_resources.to_filename(dist.project_name)) + egg_info_exists = dist.egg_info and os.path.exists(dist.egg_info) + # Special case for distutils installed package + distutils_egg_info = getattr(dist._provider, 'path', None) + + # Uninstall cases order do matter as in the case of 2 installs of the + # same package, pip needs to uninstall the currently detected version + if (egg_info_exists and dist.egg_info.endswith('.egg-info') and + not dist.egg_info.endswith(develop_egg_link_egg_info)): + # if dist.egg_info.endswith(develop_egg_link_egg_info), we + # are in fact in the develop_egg_link case + paths_to_remove.add(dist.egg_info) + if dist.has_metadata('installed-files.txt'): + for installed_file in dist.get_metadata( + 'installed-files.txt').splitlines(): + path = os.path.normpath( + os.path.join(dist.egg_info, installed_file) + ) + paths_to_remove.add(path) + # FIXME: need a test for this elif block + # occurs with --single-version-externally-managed/--record outside + # of pip + elif dist.has_metadata('top_level.txt'): + if dist.has_metadata('namespace_packages.txt'): + namespaces = dist.get_metadata('namespace_packages.txt') + else: + namespaces = [] + for top_level_pkg in [ + p for p + in dist.get_metadata('top_level.txt').splitlines() + if p and p not in namespaces]: + path = os.path.join(dist.location, top_level_pkg) + paths_to_remove.add(path) + paths_to_remove.add(path + '.py') + paths_to_remove.add(path + '.pyc') + paths_to_remove.add(path + '.pyo') + + elif distutils_egg_info: + raise UninstallationError( + "Cannot uninstall {!r}. It is a distutils installed project " + "and thus we cannot accurately determine which files belong " + "to it which would lead to only a partial uninstall.".format( + dist.project_name, + ) + ) + + elif dist.location.endswith('.egg'): + # package installed by easy_install + # We cannot match on dist.egg_name because it can slightly vary + # i.e. setuptools-0.6c11-py2.6.egg vs setuptools-0.6rc11-py2.6.egg + paths_to_remove.add(dist.location) + easy_install_egg = os.path.split(dist.location)[1] + easy_install_pth = os.path.join(os.path.dirname(dist.location), + 'easy-install.pth') + paths_to_remove.add_pth(easy_install_pth, './' + easy_install_egg) + + elif egg_info_exists and dist.egg_info.endswith('.dist-info'): + for path in uninstallation_paths(dist): + paths_to_remove.add(path) + + elif develop_egg_link: + # develop egg + with open(develop_egg_link, 'r') as fh: + link_pointer = os.path.normcase(fh.readline().strip()) + assert (link_pointer == dist.location), ( + 'Egg-link {} does not match installed location of {} ' + '(at {})'.format( + link_pointer, dist.project_name, dist.location) + ) + paths_to_remove.add(develop_egg_link) + easy_install_pth = os.path.join(os.path.dirname(develop_egg_link), + 'easy-install.pth') + paths_to_remove.add_pth(easy_install_pth, dist.location) + + else: + logger.debug( + 'Not sure how to uninstall: %s - Check: %s', + dist, dist.location, + ) + + # find distutils scripts= scripts + if dist.has_metadata('scripts') and dist.metadata_isdir('scripts'): + for script in dist.metadata_listdir('scripts'): + if dist_in_usersite(dist): + bin_dir = bin_user + else: + bin_dir = bin_py + paths_to_remove.add(os.path.join(bin_dir, script)) + if WINDOWS: + paths_to_remove.add(os.path.join(bin_dir, script) + '.bat') + + # find console_scripts + _scripts_to_remove = [] + console_scripts = dist.get_entry_map(group='console_scripts') + for name in console_scripts.keys(): + _scripts_to_remove.extend(_script_names(dist, name, False)) + # find gui_scripts + gui_scripts = dist.get_entry_map(group='gui_scripts') + for name in gui_scripts.keys(): + _scripts_to_remove.extend(_script_names(dist, name, True)) + + for s in _scripts_to_remove: + paths_to_remove.add(s) + + return paths_to_remove + + +class UninstallPthEntries: + def __init__(self, pth_file): + # type: (str) -> None + self.file = pth_file + self.entries = set() # type: Set[str] + self._saved_lines = None # type: Optional[List[bytes]] + + def add(self, entry): + # type: (str) -> None + entry = os.path.normcase(entry) + # On Windows, os.path.normcase converts the entry to use + # backslashes. This is correct for entries that describe absolute + # paths outside of site-packages, but all the others use forward + # slashes. + # os.path.splitdrive is used instead of os.path.isabs because isabs + # treats non-absolute paths with drive letter markings like c:foo\bar + # as absolute paths. It also does not recognize UNC paths if they don't + # have more than "\\sever\share". Valid examples: "\\server\share\" or + # "\\server\share\folder". + if WINDOWS and not os.path.splitdrive(entry)[0]: + entry = entry.replace('\\', '/') + self.entries.add(entry) + + def remove(self): + # type: () -> None + logger.debug('Removing pth entries from %s:', self.file) + + # If the file doesn't exist, log a warning and return + if not os.path.isfile(self.file): + logger.warning( + "Cannot remove entries from nonexistent file %s", self.file + ) + return + with open(self.file, 'rb') as fh: + # windows uses '\r\n' with py3k, but uses '\n' with py2.x + lines = fh.readlines() + self._saved_lines = lines + if any(b'\r\n' in line for line in lines): + endline = '\r\n' + else: + endline = '\n' + # handle missing trailing newline + if lines and not lines[-1].endswith(endline.encode("utf-8")): + lines[-1] = lines[-1] + endline.encode("utf-8") + for entry in self.entries: + try: + logger.debug('Removing entry: %s', entry) + lines.remove((entry + endline).encode("utf-8")) + except ValueError: + pass + with open(self.file, 'wb') as fh: + fh.writelines(lines) + + def rollback(self): + # type: () -> bool + if self._saved_lines is None: + logger.error( + 'Cannot roll back changes to %s, none were made', self.file + ) + return False + logger.debug('Rolling %s back to previous state', self.file) + with open(self.file, 'wb') as fh: + fh.writelines(self._saved_lines) + return True diff --git a/venv/Lib/site-packages/pip/_internal/resolution/__init__.py b/venv/Lib/site-packages/pip/_internal/resolution/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/venv/Lib/site-packages/pip/_internal/resolution/base.py b/venv/Lib/site-packages/pip/_internal/resolution/base.py new file mode 100644 index 0000000..f2816ab --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/resolution/base.py @@ -0,0 +1,21 @@ +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import Callable, List + + from pip._internal.req.req_install import InstallRequirement + from pip._internal.req.req_set import RequirementSet + + InstallRequirementProvider = Callable[ + [str, InstallRequirement], InstallRequirement + ] + + +class BaseResolver: + def resolve(self, root_reqs, check_supported_wheels): + # type: (List[InstallRequirement], bool) -> RequirementSet + raise NotImplementedError() + + def get_installation_order(self, req_set): + # type: (RequirementSet) -> List[InstallRequirement] + raise NotImplementedError() diff --git a/venv/Lib/site-packages/pip/_internal/resolution/legacy/__init__.py b/venv/Lib/site-packages/pip/_internal/resolution/legacy/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/venv/Lib/site-packages/pip/_internal/resolution/legacy/resolver.py b/venv/Lib/site-packages/pip/_internal/resolution/legacy/resolver.py new file mode 100644 index 0000000..665dba1 --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/resolution/legacy/resolver.py @@ -0,0 +1,473 @@ +"""Dependency Resolution + +The dependency resolution in pip is performed as follows: + +for top-level requirements: + a. only one spec allowed per project, regardless of conflicts or not. + otherwise a "double requirement" exception is raised + b. they override sub-dependency requirements. +for sub-dependencies + a. "first found, wins" (where the order is breadth first) +""" + +# The following comment should be removed at some point in the future. +# mypy: strict-optional=False +# mypy: disallow-untyped-defs=False + +import logging +import sys +from collections import defaultdict +from itertools import chain + +from pip._vendor.packaging import specifiers + +from pip._internal.exceptions import ( + BestVersionAlreadyInstalled, + DistributionNotFound, + HashError, + HashErrors, + UnsupportedPythonVersion, +) +from pip._internal.req.req_install import check_invalid_constraint_type +from pip._internal.req.req_set import RequirementSet +from pip._internal.resolution.base import BaseResolver +from pip._internal.utils.compatibility_tags import get_supported +from pip._internal.utils.logging import indent_log +from pip._internal.utils.misc import dist_in_usersite, normalize_version_info +from pip._internal.utils.packaging import check_requires_python, get_requires_python +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import DefaultDict, List, Optional, Set, Tuple + + from pip._vendor.pkg_resources import Distribution + + from pip._internal.cache import WheelCache + from pip._internal.index.package_finder import PackageFinder + from pip._internal.models.link import Link + from pip._internal.operations.prepare import RequirementPreparer + from pip._internal.req.req_install import InstallRequirement + from pip._internal.resolution.base import InstallRequirementProvider + + DiscoveredDependencies = DefaultDict[str, List[InstallRequirement]] + +logger = logging.getLogger(__name__) + + +def _check_dist_requires_python( + dist, # type: Distribution + version_info, # type: Tuple[int, int, int] + ignore_requires_python=False, # type: bool +): + # type: (...) -> None + """ + Check whether the given Python version is compatible with a distribution's + "Requires-Python" value. + + :param version_info: A 3-tuple of ints representing the Python + major-minor-micro version to check. + :param ignore_requires_python: Whether to ignore the "Requires-Python" + value if the given Python version isn't compatible. + + :raises UnsupportedPythonVersion: When the given Python version isn't + compatible. + """ + requires_python = get_requires_python(dist) + try: + is_compatible = check_requires_python( + requires_python, version_info=version_info, + ) + except specifiers.InvalidSpecifier as exc: + logger.warning( + "Package %r has an invalid Requires-Python: %s", + dist.project_name, exc, + ) + return + + if is_compatible: + return + + version = '.'.join(map(str, version_info)) + if ignore_requires_python: + logger.debug( + 'Ignoring failed Requires-Python check for package %r: ' + '%s not in %r', + dist.project_name, version, requires_python, + ) + return + + raise UnsupportedPythonVersion( + 'Package {!r} requires a different Python: {} not in {!r}'.format( + dist.project_name, version, requires_python, + )) + + +class Resolver(BaseResolver): + """Resolves which packages need to be installed/uninstalled to perform \ + the requested operation without breaking the requirements of any package. + """ + + _allowed_strategies = {"eager", "only-if-needed", "to-satisfy-only"} + + def __init__( + self, + preparer, # type: RequirementPreparer + finder, # type: PackageFinder + wheel_cache, # type: Optional[WheelCache] + make_install_req, # type: InstallRequirementProvider + use_user_site, # type: bool + ignore_dependencies, # type: bool + ignore_installed, # type: bool + ignore_requires_python, # type: bool + force_reinstall, # type: bool + upgrade_strategy, # type: str + py_version_info=None, # type: Optional[Tuple[int, ...]] + ): + # type: (...) -> None + super().__init__() + assert upgrade_strategy in self._allowed_strategies + + if py_version_info is None: + py_version_info = sys.version_info[:3] + else: + py_version_info = normalize_version_info(py_version_info) + + self._py_version_info = py_version_info + + self.preparer = preparer + self.finder = finder + self.wheel_cache = wheel_cache + + self.upgrade_strategy = upgrade_strategy + self.force_reinstall = force_reinstall + self.ignore_dependencies = ignore_dependencies + self.ignore_installed = ignore_installed + self.ignore_requires_python = ignore_requires_python + self.use_user_site = use_user_site + self._make_install_req = make_install_req + + self._discovered_dependencies = \ + defaultdict(list) # type: DiscoveredDependencies + + def resolve(self, root_reqs, check_supported_wheels): + # type: (List[InstallRequirement], bool) -> RequirementSet + """Resolve what operations need to be done + + As a side-effect of this method, the packages (and their dependencies) + are downloaded, unpacked and prepared for installation. This + preparation is done by ``pip.operations.prepare``. + + Once PyPI has static dependency metadata available, it would be + possible to move the preparation to become a step separated from + dependency resolution. + """ + requirement_set = RequirementSet( + check_supported_wheels=check_supported_wheels + ) + for req in root_reqs: + if req.constraint: + check_invalid_constraint_type(req) + requirement_set.add_requirement(req) + + # Actually prepare the files, and collect any exceptions. Most hash + # exceptions cannot be checked ahead of time, because + # _populate_link() needs to be called before we can make decisions + # based on link type. + discovered_reqs = [] # type: List[InstallRequirement] + hash_errors = HashErrors() + for req in chain(requirement_set.all_requirements, discovered_reqs): + try: + discovered_reqs.extend(self._resolve_one(requirement_set, req)) + except HashError as exc: + exc.req = req + hash_errors.append(exc) + + if hash_errors: + raise hash_errors + + return requirement_set + + def _is_upgrade_allowed(self, req): + # type: (InstallRequirement) -> bool + if self.upgrade_strategy == "to-satisfy-only": + return False + elif self.upgrade_strategy == "eager": + return True + else: + assert self.upgrade_strategy == "only-if-needed" + return req.user_supplied or req.constraint + + def _set_req_to_reinstall(self, req): + # type: (InstallRequirement) -> None + """ + Set a requirement to be installed. + """ + # Don't uninstall the conflict if doing a user install and the + # conflict is not a user install. + if not self.use_user_site or dist_in_usersite(req.satisfied_by): + req.should_reinstall = True + req.satisfied_by = None + + def _check_skip_installed(self, req_to_install): + # type: (InstallRequirement) -> Optional[str] + """Check if req_to_install should be skipped. + + This will check if the req is installed, and whether we should upgrade + or reinstall it, taking into account all the relevant user options. + + After calling this req_to_install will only have satisfied_by set to + None if the req_to_install is to be upgraded/reinstalled etc. Any + other value will be a dist recording the current thing installed that + satisfies the requirement. + + Note that for vcs urls and the like we can't assess skipping in this + routine - we simply identify that we need to pull the thing down, + then later on it is pulled down and introspected to assess upgrade/ + reinstalls etc. + + :return: A text reason for why it was skipped, or None. + """ + if self.ignore_installed: + return None + + req_to_install.check_if_exists(self.use_user_site) + if not req_to_install.satisfied_by: + return None + + if self.force_reinstall: + self._set_req_to_reinstall(req_to_install) + return None + + if not self._is_upgrade_allowed(req_to_install): + if self.upgrade_strategy == "only-if-needed": + return 'already satisfied, skipping upgrade' + return 'already satisfied' + + # Check for the possibility of an upgrade. For link-based + # requirements we have to pull the tree down and inspect to assess + # the version #, so it's handled way down. + if not req_to_install.link: + try: + self.finder.find_requirement(req_to_install, upgrade=True) + except BestVersionAlreadyInstalled: + # Then the best version is installed. + return 'already up-to-date' + except DistributionNotFound: + # No distribution found, so we squash the error. It will + # be raised later when we re-try later to do the install. + # Why don't we just raise here? + pass + + self._set_req_to_reinstall(req_to_install) + return None + + def _find_requirement_link(self, req): + # type: (InstallRequirement) -> Optional[Link] + upgrade = self._is_upgrade_allowed(req) + best_candidate = self.finder.find_requirement(req, upgrade) + if not best_candidate: + return None + + # Log a warning per PEP 592 if necessary before returning. + link = best_candidate.link + if link.is_yanked: + reason = link.yanked_reason or '' + msg = ( + # Mark this as a unicode string to prevent + # "UnicodeEncodeError: 'ascii' codec can't encode character" + # in Python 2 when the reason contains non-ascii characters. + 'The candidate selected for download or install is a ' + 'yanked version: {candidate}\n' + 'Reason for being yanked: {reason}' + ).format(candidate=best_candidate, reason=reason) + logger.warning(msg) + + return link + + def _populate_link(self, req): + # type: (InstallRequirement) -> None + """Ensure that if a link can be found for this, that it is found. + + Note that req.link may still be None - if the requirement is already + installed and not needed to be upgraded based on the return value of + _is_upgrade_allowed(). + + If preparer.require_hashes is True, don't use the wheel cache, because + cached wheels, always built locally, have different hashes than the + files downloaded from the index server and thus throw false hash + mismatches. Furthermore, cached wheels at present have undeterministic + contents due to file modification times. + """ + if req.link is None: + req.link = self._find_requirement_link(req) + + if self.wheel_cache is None or self.preparer.require_hashes: + return + cache_entry = self.wheel_cache.get_cache_entry( + link=req.link, + package_name=req.name, + supported_tags=get_supported(), + ) + if cache_entry is not None: + logger.debug('Using cached wheel link: %s', cache_entry.link) + if req.link is req.original_link and cache_entry.persistent: + req.original_link_is_in_wheel_cache = True + req.link = cache_entry.link + + def _get_dist_for(self, req): + # type: (InstallRequirement) -> Distribution + """Takes a InstallRequirement and returns a single AbstractDist \ + representing a prepared variant of the same. + """ + if req.editable: + return self.preparer.prepare_editable_requirement(req) + + # satisfied_by is only evaluated by calling _check_skip_installed, + # so it must be None here. + assert req.satisfied_by is None + skip_reason = self._check_skip_installed(req) + + if req.satisfied_by: + return self.preparer.prepare_installed_requirement( + req, skip_reason + ) + + # We eagerly populate the link, since that's our "legacy" behavior. + self._populate_link(req) + dist = self.preparer.prepare_linked_requirement(req) + + # NOTE + # The following portion is for determining if a certain package is + # going to be re-installed/upgraded or not and reporting to the user. + # This should probably get cleaned up in a future refactor. + + # req.req is only avail after unpack for URL + # pkgs repeat check_if_exists to uninstall-on-upgrade + # (#14) + if not self.ignore_installed: + req.check_if_exists(self.use_user_site) + + if req.satisfied_by: + should_modify = ( + self.upgrade_strategy != "to-satisfy-only" or + self.force_reinstall or + self.ignore_installed or + req.link.scheme == 'file' + ) + if should_modify: + self._set_req_to_reinstall(req) + else: + logger.info( + 'Requirement already satisfied (use --upgrade to upgrade):' + ' %s', req, + ) + return dist + + def _resolve_one( + self, + requirement_set, # type: RequirementSet + req_to_install, # type: InstallRequirement + ): + # type: (...) -> List[InstallRequirement] + """Prepare a single requirements file. + + :return: A list of additional InstallRequirements to also install. + """ + # Tell user what we are doing for this requirement: + # obtain (editable), skipping, processing (local url), collecting + # (remote url or package name) + if req_to_install.constraint or req_to_install.prepared: + return [] + + req_to_install.prepared = True + + # Parse and return dependencies + dist = self._get_dist_for(req_to_install) + # This will raise UnsupportedPythonVersion if the given Python + # version isn't compatible with the distribution's Requires-Python. + _check_dist_requires_python( + dist, version_info=self._py_version_info, + ignore_requires_python=self.ignore_requires_python, + ) + + more_reqs = [] # type: List[InstallRequirement] + + def add_req(subreq, extras_requested): + sub_install_req = self._make_install_req( + str(subreq), + req_to_install, + ) + parent_req_name = req_to_install.name + to_scan_again, add_to_parent = requirement_set.add_requirement( + sub_install_req, + parent_req_name=parent_req_name, + extras_requested=extras_requested, + ) + if parent_req_name and add_to_parent: + self._discovered_dependencies[parent_req_name].append( + add_to_parent + ) + more_reqs.extend(to_scan_again) + + with indent_log(): + # We add req_to_install before its dependencies, so that we + # can refer to it when adding dependencies. + if not requirement_set.has_requirement(req_to_install.name): + # 'unnamed' requirements will get added here + # 'unnamed' requirements can only come from being directly + # provided by the user. + assert req_to_install.user_supplied + requirement_set.add_requirement( + req_to_install, parent_req_name=None, + ) + + if not self.ignore_dependencies: + if req_to_install.extras: + logger.debug( + "Installing extra requirements: %r", + ','.join(req_to_install.extras), + ) + missing_requested = sorted( + set(req_to_install.extras) - set(dist.extras) + ) + for missing in missing_requested: + logger.warning( + "%s does not provide the extra '%s'", + dist, missing + ) + + available_requested = sorted( + set(dist.extras) & set(req_to_install.extras) + ) + for subreq in dist.requires(available_requested): + add_req(subreq, extras_requested=available_requested) + + return more_reqs + + def get_installation_order(self, req_set): + # type: (RequirementSet) -> List[InstallRequirement] + """Create the installation order. + + The installation order is topological - requirements are installed + before the requiring thing. We break cycles at an arbitrary point, + and make no other guarantees. + """ + # The current implementation, which we may change at any point + # installs the user specified things in the order given, except when + # dependencies must come earlier to achieve topological order. + order = [] + ordered_reqs = set() # type: Set[InstallRequirement] + + def schedule(req): + if req.satisfied_by or req in ordered_reqs: + return + if req.constraint: + return + ordered_reqs.add(req) + for dep in self._discovered_dependencies[req.name]: + schedule(dep) + order.append(req) + + for install_req in req_set.requirements.values(): + schedule(install_req) + return order diff --git a/venv/Lib/site-packages/pip/_internal/resolution/resolvelib/__init__.py b/venv/Lib/site-packages/pip/_internal/resolution/resolvelib/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/venv/Lib/site-packages/pip/_internal/resolution/resolvelib/base.py b/venv/Lib/site-packages/pip/_internal/resolution/resolvelib/base.py new file mode 100644 index 0000000..82c5ec7 --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/resolution/resolvelib/base.py @@ -0,0 +1,156 @@ +from pip._vendor.packaging.specifiers import SpecifierSet +from pip._vendor.packaging.utils import canonicalize_name + +from pip._internal.req.req_install import InstallRequirement +from pip._internal.utils.hashes import Hashes +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import FrozenSet, Iterable, Optional, Tuple + + from pip._vendor.packaging.version import _BaseVersion + + from pip._internal.models.link import Link + + CandidateLookup = Tuple[ + Optional["Candidate"], + Optional[InstallRequirement], + ] + + +def format_name(project, extras): + # type: (str, FrozenSet[str]) -> str + if not extras: + return project + canonical_extras = sorted(canonicalize_name(e) for e in extras) + return "{}[{}]".format(project, ",".join(canonical_extras)) + + +class Constraint: + def __init__(self, specifier, hashes): + # type: (SpecifierSet, Hashes) -> None + self.specifier = specifier + self.hashes = hashes + + @classmethod + def empty(cls): + # type: () -> Constraint + return Constraint(SpecifierSet(), Hashes()) + + @classmethod + def from_ireq(cls, ireq): + # type: (InstallRequirement) -> Constraint + return Constraint(ireq.specifier, ireq.hashes(trust_internet=False)) + + def __nonzero__(self): + # type: () -> bool + return bool(self.specifier) or bool(self.hashes) + + def __bool__(self): + # type: () -> bool + return self.__nonzero__() + + def __and__(self, other): + # type: (InstallRequirement) -> Constraint + if not isinstance(other, InstallRequirement): + return NotImplemented + specifier = self.specifier & other.specifier + hashes = self.hashes & other.hashes(trust_internet=False) + return Constraint(specifier, hashes) + + def is_satisfied_by(self, candidate): + # type: (Candidate) -> bool + # We can safely always allow prereleases here since PackageFinder + # already implements the prerelease logic, and would have filtered out + # prerelease candidates if the user does not expect them. + return self.specifier.contains(candidate.version, prereleases=True) + + +class Requirement: + @property + def project_name(self): + # type: () -> str + """The "project name" of a requirement. + + This is different from ``name`` if this requirement contains extras, + in which case ``name`` would contain the ``[...]`` part, while this + refers to the name of the project. + """ + raise NotImplementedError("Subclass should override") + + @property + def name(self): + # type: () -> str + """The name identifying this requirement in the resolver. + + This is different from ``project_name`` if this requirement contains + extras, where ``project_name`` would not contain the ``[...]`` part. + """ + raise NotImplementedError("Subclass should override") + + def is_satisfied_by(self, candidate): + # type: (Candidate) -> bool + return False + + def get_candidate_lookup(self): + # type: () -> CandidateLookup + raise NotImplementedError("Subclass should override") + + def format_for_error(self): + # type: () -> str + raise NotImplementedError("Subclass should override") + + +class Candidate: + @property + def project_name(self): + # type: () -> str + """The "project name" of the candidate. + + This is different from ``name`` if this candidate contains extras, + in which case ``name`` would contain the ``[...]`` part, while this + refers to the name of the project. + """ + raise NotImplementedError("Override in subclass") + + @property + def name(self): + # type: () -> str + """The name identifying this candidate in the resolver. + + This is different from ``project_name`` if this candidate contains + extras, where ``project_name`` would not contain the ``[...]`` part. + """ + raise NotImplementedError("Override in subclass") + + @property + def version(self): + # type: () -> _BaseVersion + raise NotImplementedError("Override in subclass") + + @property + def is_installed(self): + # type: () -> bool + raise NotImplementedError("Override in subclass") + + @property + def is_editable(self): + # type: () -> bool + raise NotImplementedError("Override in subclass") + + @property + def source_link(self): + # type: () -> Optional[Link] + raise NotImplementedError("Override in subclass") + + def iter_dependencies(self, with_requires): + # type: (bool) -> Iterable[Optional[Requirement]] + raise NotImplementedError("Override in subclass") + + def get_install_requirement(self): + # type: () -> Optional[InstallRequirement] + raise NotImplementedError("Override in subclass") + + def format_for_error(self): + # type: () -> str + raise NotImplementedError("Subclass should override") diff --git a/venv/Lib/site-packages/pip/_internal/resolution/resolvelib/candidates.py b/venv/Lib/site-packages/pip/_internal/resolution/resolvelib/candidates.py new file mode 100644 index 0000000..91662b3 --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/resolution/resolvelib/candidates.py @@ -0,0 +1,598 @@ +import logging +import sys + +from pip._vendor.packaging.specifiers import InvalidSpecifier, SpecifierSet +from pip._vendor.packaging.utils import canonicalize_name +from pip._vendor.packaging.version import Version + +from pip._internal.exceptions import HashError, MetadataInconsistent +from pip._internal.models.wheel import Wheel +from pip._internal.req.constructors import ( + install_req_from_editable, + install_req_from_line, +) +from pip._internal.req.req_install import InstallRequirement +from pip._internal.utils.misc import dist_is_editable, normalize_version_info +from pip._internal.utils.packaging import get_requires_python +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +from .base import Candidate, format_name + +if MYPY_CHECK_RUNNING: + from typing import Any, FrozenSet, Iterable, Optional, Tuple, Union + + from pip._vendor.packaging.version import _BaseVersion + from pip._vendor.pkg_resources import Distribution + + from pip._internal.models.link import Link + + from .base import Requirement + from .factory import Factory + + BaseCandidate = Union[ + "AlreadyInstalledCandidate", + "EditableCandidate", + "LinkCandidate", + ] + + +logger = logging.getLogger(__name__) + + +def make_install_req_from_link(link, template): + # type: (Link, InstallRequirement) -> InstallRequirement + assert not template.editable, "template is editable" + if template.req: + line = str(template.req) + else: + line = link.url + ireq = install_req_from_line( + line, + user_supplied=template.user_supplied, + comes_from=template.comes_from, + use_pep517=template.use_pep517, + isolated=template.isolated, + constraint=template.constraint, + options=dict( + install_options=template.install_options, + global_options=template.global_options, + hashes=template.hash_options + ), + ) + ireq.original_link = template.original_link + ireq.link = link + return ireq + + +def make_install_req_from_editable(link, template): + # type: (Link, InstallRequirement) -> InstallRequirement + assert template.editable, "template not editable" + return install_req_from_editable( + link.url, + user_supplied=template.user_supplied, + comes_from=template.comes_from, + use_pep517=template.use_pep517, + isolated=template.isolated, + constraint=template.constraint, + options=dict( + install_options=template.install_options, + global_options=template.global_options, + hashes=template.hash_options + ), + ) + + +def make_install_req_from_dist(dist, template): + # type: (Distribution, InstallRequirement) -> InstallRequirement + project_name = canonicalize_name(dist.project_name) + if template.req: + line = str(template.req) + elif template.link: + line = f"{project_name} @ {template.link.url}" + else: + line = f"{project_name}=={dist.parsed_version}" + ireq = install_req_from_line( + line, + user_supplied=template.user_supplied, + comes_from=template.comes_from, + use_pep517=template.use_pep517, + isolated=template.isolated, + constraint=template.constraint, + options=dict( + install_options=template.install_options, + global_options=template.global_options, + hashes=template.hash_options + ), + ) + ireq.satisfied_by = dist + return ireq + + +class _InstallRequirementBackedCandidate(Candidate): + """A candidate backed by an ``InstallRequirement``. + + This represents a package request with the target not being already + in the environment, and needs to be fetched and installed. The backing + ``InstallRequirement`` is responsible for most of the leg work; this + class exposes appropriate information to the resolver. + + :param link: The link passed to the ``InstallRequirement``. The backing + ``InstallRequirement`` will use this link to fetch the distribution. + :param source_link: The link this candidate "originates" from. This is + different from ``link`` when the link is found in the wheel cache. + ``link`` would point to the wheel cache, while this points to the + found remote link (e.g. from pypi.org). + """ + is_installed = False + + def __init__( + self, + link, # type: Link + source_link, # type: Link + ireq, # type: InstallRequirement + factory, # type: Factory + name=None, # type: Optional[str] + version=None, # type: Optional[_BaseVersion] + ): + # type: (...) -> None + self._link = link + self._source_link = source_link + self._factory = factory + self._ireq = ireq + self._name = name + self._version = version + self.dist = self._prepare() + + def __str__(self): + # type: () -> str + return f"{self.name} {self.version}" + + def __repr__(self): + # type: () -> str + return "{class_name}({link!r})".format( + class_name=self.__class__.__name__, + link=str(self._link), + ) + + def __hash__(self): + # type: () -> int + return hash((self.__class__, self._link)) + + def __eq__(self, other): + # type: (Any) -> bool + if isinstance(other, self.__class__): + return self._link == other._link + return False + + @property + def source_link(self): + # type: () -> Optional[Link] + return self._source_link + + @property + def project_name(self): + # type: () -> str + """The normalised name of the project the candidate refers to""" + if self._name is None: + self._name = canonicalize_name(self.dist.project_name) + return self._name + + @property + def name(self): + # type: () -> str + return self.project_name + + @property + def version(self): + # type: () -> _BaseVersion + if self._version is None: + self._version = self.dist.parsed_version + return self._version + + def format_for_error(self): + # type: () -> str + return "{} {} (from {})".format( + self.name, + self.version, + self._link.file_path if self._link.is_file else self._link + ) + + def _prepare_distribution(self): + # type: () -> Distribution + raise NotImplementedError("Override in subclass") + + def _check_metadata_consistency(self, dist): + # type: (Distribution) -> None + """Check for consistency of project name and version of dist.""" + canonical_name = canonicalize_name(dist.project_name) + if self._name is not None and self._name != canonical_name: + raise MetadataInconsistent( + self._ireq, + "name", + self._name, + dist.project_name, + ) + if self._version is not None and self._version != dist.parsed_version: + raise MetadataInconsistent( + self._ireq, + "version", + str(self._version), + dist.version, + ) + + def _prepare(self): + # type: () -> Distribution + try: + dist = self._prepare_distribution() + except HashError as e: + # Provide HashError the underlying ireq that caused it. This + # provides context for the resulting error message to show the + # offending line to the user. + e.req = self._ireq + raise + self._check_metadata_consistency(dist) + return dist + + def _get_requires_python_dependency(self): + # type: () -> Optional[Requirement] + requires_python = get_requires_python(self.dist) + if requires_python is None: + return None + try: + spec = SpecifierSet(requires_python) + except InvalidSpecifier as e: + message = "Package %r has an invalid Requires-Python: %s" + logger.warning(message, self.name, e) + return None + return self._factory.make_requires_python_requirement(spec) + + def iter_dependencies(self, with_requires): + # type: (bool) -> Iterable[Optional[Requirement]] + requires = self.dist.requires() if with_requires else () + for r in requires: + yield self._factory.make_requirement_from_spec(str(r), self._ireq) + yield self._get_requires_python_dependency() + + def get_install_requirement(self): + # type: () -> Optional[InstallRequirement] + return self._ireq + + +class LinkCandidate(_InstallRequirementBackedCandidate): + is_editable = False + + def __init__( + self, + link, # type: Link + template, # type: InstallRequirement + factory, # type: Factory + name=None, # type: Optional[str] + version=None, # type: Optional[_BaseVersion] + ): + # type: (...) -> None + source_link = link + cache_entry = factory.get_wheel_cache_entry(link, name) + if cache_entry is not None: + logger.debug("Using cached wheel link: %s", cache_entry.link) + link = cache_entry.link + ireq = make_install_req_from_link(link, template) + assert ireq.link == link + if ireq.link.is_wheel and not ireq.link.is_file: + wheel = Wheel(ireq.link.filename) + wheel_name = canonicalize_name(wheel.name) + assert name == wheel_name, ( + f"{name!r} != {wheel_name!r} for wheel" + ) + # Version may not be present for PEP 508 direct URLs + if version is not None: + wheel_version = Version(wheel.version) + assert version == wheel_version, ( + "{!r} != {!r} for wheel {}".format( + version, wheel_version, name + ) + ) + + if (cache_entry is not None and + cache_entry.persistent and + template.link is template.original_link): + ireq.original_link_is_in_wheel_cache = True + + super().__init__( + link=link, + source_link=source_link, + ireq=ireq, + factory=factory, + name=name, + version=version, + ) + + def _prepare_distribution(self): + # type: () -> Distribution + return self._factory.preparer.prepare_linked_requirement( + self._ireq, parallel_builds=True, + ) + + +class EditableCandidate(_InstallRequirementBackedCandidate): + is_editable = True + + def __init__( + self, + link, # type: Link + template, # type: InstallRequirement + factory, # type: Factory + name=None, # type: Optional[str] + version=None, # type: Optional[_BaseVersion] + ): + # type: (...) -> None + super().__init__( + link=link, + source_link=link, + ireq=make_install_req_from_editable(link, template), + factory=factory, + name=name, + version=version, + ) + + def _prepare_distribution(self): + # type: () -> Distribution + return self._factory.preparer.prepare_editable_requirement(self._ireq) + + +class AlreadyInstalledCandidate(Candidate): + is_installed = True + source_link = None + + def __init__( + self, + dist, # type: Distribution + template, # type: InstallRequirement + factory, # type: Factory + ): + # type: (...) -> None + self.dist = dist + self._ireq = make_install_req_from_dist(dist, template) + self._factory = factory + + # This is just logging some messages, so we can do it eagerly. + # The returned dist would be exactly the same as self.dist because we + # set satisfied_by in make_install_req_from_dist. + # TODO: Supply reason based on force_reinstall and upgrade_strategy. + skip_reason = "already satisfied" + factory.preparer.prepare_installed_requirement(self._ireq, skip_reason) + + def __str__(self): + # type: () -> str + return str(self.dist) + + def __repr__(self): + # type: () -> str + return "{class_name}({distribution!r})".format( + class_name=self.__class__.__name__, + distribution=self.dist, + ) + + def __hash__(self): + # type: () -> int + return hash((self.__class__, self.name, self.version)) + + def __eq__(self, other): + # type: (Any) -> bool + if isinstance(other, self.__class__): + return self.name == other.name and self.version == other.version + return False + + @property + def project_name(self): + # type: () -> str + return canonicalize_name(self.dist.project_name) + + @property + def name(self): + # type: () -> str + return self.project_name + + @property + def version(self): + # type: () -> _BaseVersion + return self.dist.parsed_version + + @property + def is_editable(self): + # type: () -> bool + return dist_is_editable(self.dist) + + def format_for_error(self): + # type: () -> str + return f"{self.name} {self.version} (Installed)" + + def iter_dependencies(self, with_requires): + # type: (bool) -> Iterable[Optional[Requirement]] + if not with_requires: + return + for r in self.dist.requires(): + yield self._factory.make_requirement_from_spec(str(r), self._ireq) + + def get_install_requirement(self): + # type: () -> Optional[InstallRequirement] + return None + + +class ExtrasCandidate(Candidate): + """A candidate that has 'extras', indicating additional dependencies. + + Requirements can be for a project with dependencies, something like + foo[extra]. The extras don't affect the project/version being installed + directly, but indicate that we need additional dependencies. We model that + by having an artificial ExtrasCandidate that wraps the "base" candidate. + + The ExtrasCandidate differs from the base in the following ways: + + 1. It has a unique name, of the form foo[extra]. This causes the resolver + to treat it as a separate node in the dependency graph. + 2. When we're getting the candidate's dependencies, + a) We specify that we want the extra dependencies as well. + b) We add a dependency on the base candidate. + See below for why this is needed. + 3. We return None for the underlying InstallRequirement, as the base + candidate will provide it, and we don't want to end up with duplicates. + + The dependency on the base candidate is needed so that the resolver can't + decide that it should recommend foo[extra1] version 1.0 and foo[extra2] + version 2.0. Having those candidates depend on foo=1.0 and foo=2.0 + respectively forces the resolver to recognise that this is a conflict. + """ + def __init__( + self, + base, # type: BaseCandidate + extras, # type: FrozenSet[str] + ): + # type: (...) -> None + self.base = base + self.extras = extras + + def __str__(self): + # type: () -> str + name, rest = str(self.base).split(" ", 1) + return "{}[{}] {}".format(name, ",".join(self.extras), rest) + + def __repr__(self): + # type: () -> str + return "{class_name}(base={base!r}, extras={extras!r})".format( + class_name=self.__class__.__name__, + base=self.base, + extras=self.extras, + ) + + def __hash__(self): + # type: () -> int + return hash((self.base, self.extras)) + + def __eq__(self, other): + # type: (Any) -> bool + if isinstance(other, self.__class__): + return self.base == other.base and self.extras == other.extras + return False + + @property + def project_name(self): + # type: () -> str + return self.base.project_name + + @property + def name(self): + # type: () -> str + """The normalised name of the project the candidate refers to""" + return format_name(self.base.project_name, self.extras) + + @property + def version(self): + # type: () -> _BaseVersion + return self.base.version + + def format_for_error(self): + # type: () -> str + return "{} [{}]".format( + self.base.format_for_error(), + ", ".join(sorted(self.extras)) + ) + + @property + def is_installed(self): + # type: () -> bool + return self.base.is_installed + + @property + def is_editable(self): + # type: () -> bool + return self.base.is_editable + + @property + def source_link(self): + # type: () -> Optional[Link] + return self.base.source_link + + def iter_dependencies(self, with_requires): + # type: (bool) -> Iterable[Optional[Requirement]] + factory = self.base._factory + + # Add a dependency on the exact base + # (See note 2b in the class docstring) + yield factory.make_requirement_from_candidate(self.base) + if not with_requires: + return + + # The user may have specified extras that the candidate doesn't + # support. We ignore any unsupported extras here. + valid_extras = self.extras.intersection(self.base.dist.extras) + invalid_extras = self.extras.difference(self.base.dist.extras) + for extra in sorted(invalid_extras): + logger.warning( + "%s %s does not provide the extra '%s'", + self.base.name, + self.version, + extra + ) + + for r in self.base.dist.requires(valid_extras): + requirement = factory.make_requirement_from_spec( + str(r), self.base._ireq, valid_extras, + ) + if requirement: + yield requirement + + def get_install_requirement(self): + # type: () -> Optional[InstallRequirement] + # We don't return anything here, because we always + # depend on the base candidate, and we'll get the + # install requirement from that. + return None + + +class RequiresPythonCandidate(Candidate): + is_installed = False + source_link = None + + def __init__(self, py_version_info): + # type: (Optional[Tuple[int, ...]]) -> None + if py_version_info is not None: + version_info = normalize_version_info(py_version_info) + else: + version_info = sys.version_info[:3] + self._version = Version(".".join(str(c) for c in version_info)) + + # We don't need to implement __eq__() and __ne__() since there is always + # only one RequiresPythonCandidate in a resolution, i.e. the host Python. + # The built-in object.__eq__() and object.__ne__() do exactly what we want. + + def __str__(self): + # type: () -> str + return f"Python {self._version}" + + @property + def project_name(self): + # type: () -> str + # Avoid conflicting with the PyPI package "Python". + return "" + + @property + def name(self): + # type: () -> str + return self.project_name + + @property + def version(self): + # type: () -> _BaseVersion + return self._version + + def format_for_error(self): + # type: () -> str + return f"Python {self.version}" + + def iter_dependencies(self, with_requires): + # type: (bool) -> Iterable[Optional[Requirement]] + return () + + def get_install_requirement(self): + # type: () -> Optional[InstallRequirement] + return None diff --git a/venv/Lib/site-packages/pip/_internal/resolution/resolvelib/factory.py b/venv/Lib/site-packages/pip/_internal/resolution/resolvelib/factory.py new file mode 100644 index 0000000..be0729e --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/resolution/resolvelib/factory.py @@ -0,0 +1,499 @@ +import functools +import logging + +from pip._vendor.packaging.utils import canonicalize_name + +from pip._internal.exceptions import ( + DistributionNotFound, + InstallationError, + InstallationSubprocessError, + MetadataInconsistent, + UnsupportedPythonVersion, + UnsupportedWheel, +) +from pip._internal.models.wheel import Wheel +from pip._internal.req.req_install import InstallRequirement +from pip._internal.utils.compatibility_tags import get_supported +from pip._internal.utils.hashes import Hashes +from pip._internal.utils.misc import ( + dist_in_site_packages, + dist_in_usersite, + get_installed_distributions, +) +from pip._internal.utils.typing import MYPY_CHECK_RUNNING +from pip._internal.utils.virtualenv import running_under_virtualenv + +from .base import Constraint +from .candidates import ( + AlreadyInstalledCandidate, + EditableCandidate, + ExtrasCandidate, + LinkCandidate, + RequiresPythonCandidate, +) +from .found_candidates import FoundCandidates +from .requirements import ( + ExplicitRequirement, + RequiresPythonRequirement, + SpecifierRequirement, + UnsatisfiableRequirement, +) + +if MYPY_CHECK_RUNNING: + from typing import ( + Dict, + FrozenSet, + Iterable, + Iterator, + List, + Optional, + Sequence, + Set, + Tuple, + TypeVar, + ) + + from pip._vendor.packaging.specifiers import SpecifierSet + from pip._vendor.packaging.version import _BaseVersion + from pip._vendor.pkg_resources import Distribution + from pip._vendor.resolvelib import ResolutionImpossible + + from pip._internal.cache import CacheEntry, WheelCache + from pip._internal.index.package_finder import PackageFinder + from pip._internal.models.link import Link + from pip._internal.operations.prepare import RequirementPreparer + from pip._internal.resolution.base import InstallRequirementProvider + + from .base import Candidate, Requirement + from .candidates import BaseCandidate + from .found_candidates import IndexCandidateInfo + + C = TypeVar("C") + Cache = Dict[Link, C] + +logger = logging.getLogger(__name__) + + +class Factory: + def __init__( + self, + finder, # type: PackageFinder + preparer, # type: RequirementPreparer + make_install_req, # type: InstallRequirementProvider + wheel_cache, # type: Optional[WheelCache] + use_user_site, # type: bool + force_reinstall, # type: bool + ignore_installed, # type: bool + ignore_requires_python, # type: bool + py_version_info=None, # type: Optional[Tuple[int, ...]] + ): + # type: (...) -> None + self._finder = finder + self.preparer = preparer + self._wheel_cache = wheel_cache + self._python_candidate = RequiresPythonCandidate(py_version_info) + self._make_install_req_from_spec = make_install_req + self._use_user_site = use_user_site + self._force_reinstall = force_reinstall + self._ignore_requires_python = ignore_requires_python + + self._build_failures = {} # type: Cache[InstallationError] + self._link_candidate_cache = {} # type: Cache[LinkCandidate] + self._editable_candidate_cache = {} # type: Cache[EditableCandidate] + self._installed_candidate_cache = { + } # type: Dict[str, AlreadyInstalledCandidate] + + if not ignore_installed: + self._installed_dists = { + canonicalize_name(dist.project_name): dist + for dist in get_installed_distributions(local_only=False) + } + else: + self._installed_dists = {} + + @property + def force_reinstall(self): + # type: () -> bool + return self._force_reinstall + + def _make_candidate_from_dist( + self, + dist, # type: Distribution + extras, # type: FrozenSet[str] + template, # type: InstallRequirement + ): + # type: (...) -> Candidate + try: + base = self._installed_candidate_cache[dist.key] + except KeyError: + base = AlreadyInstalledCandidate(dist, template, factory=self) + self._installed_candidate_cache[dist.key] = base + if extras: + return ExtrasCandidate(base, extras) + return base + + def _make_candidate_from_link( + self, + link, # type: Link + extras, # type: FrozenSet[str] + template, # type: InstallRequirement + name, # type: Optional[str] + version, # type: Optional[_BaseVersion] + ): + # type: (...) -> Optional[Candidate] + # TODO: Check already installed candidate, and use it if the link and + # editable flag match. + + if link in self._build_failures: + # We already tried this candidate before, and it does not build. + # Don't bother trying again. + return None + + if template.editable: + if link not in self._editable_candidate_cache: + try: + self._editable_candidate_cache[link] = EditableCandidate( + link, template, factory=self, + name=name, version=version, + ) + except (InstallationSubprocessError, MetadataInconsistent) as e: + logger.warning("Discarding %s. %s", link, e) + self._build_failures[link] = e + return None + base = self._editable_candidate_cache[link] # type: BaseCandidate + else: + if link not in self._link_candidate_cache: + try: + self._link_candidate_cache[link] = LinkCandidate( + link, template, factory=self, + name=name, version=version, + ) + except (InstallationSubprocessError, MetadataInconsistent) as e: + logger.warning("Discarding %s. %s", link, e) + self._build_failures[link] = e + return None + base = self._link_candidate_cache[link] + + if extras: + return ExtrasCandidate(base, extras) + return base + + def _iter_found_candidates( + self, + ireqs, # type: Sequence[InstallRequirement] + specifier, # type: SpecifierSet + hashes, # type: Hashes + prefers_installed, # type: bool + ): + # type: (...) -> Iterable[Candidate] + if not ireqs: + return () + + # The InstallRequirement implementation requires us to give it a + # "template". Here we just choose the first requirement to represent + # all of them. + # Hopefully the Project model can correct this mismatch in the future. + template = ireqs[0] + name = canonicalize_name(template.req.name) + + extras = frozenset() # type: FrozenSet[str] + for ireq in ireqs: + specifier &= ireq.req.specifier + hashes &= ireq.hashes(trust_internet=False) + extras |= frozenset(ireq.extras) + + # Get the installed version, if it matches, unless the user + # specified `--force-reinstall`, when we want the version from + # the index instead. + installed_candidate = None + if not self._force_reinstall and name in self._installed_dists: + installed_dist = self._installed_dists[name] + if specifier.contains(installed_dist.version, prereleases=True): + installed_candidate = self._make_candidate_from_dist( + dist=installed_dist, + extras=extras, + template=template, + ) + + def iter_index_candidate_infos(): + # type: () -> Iterator[IndexCandidateInfo] + result = self._finder.find_best_candidate( + project_name=name, + specifier=specifier, + hashes=hashes, + ) + icans = list(result.iter_applicable()) + + # PEP 592: Yanked releases must be ignored unless only yanked + # releases can satisfy the version range. So if this is false, + # all yanked icans need to be skipped. + all_yanked = all(ican.link.is_yanked for ican in icans) + + # PackageFinder returns earlier versions first, so we reverse. + for ican in reversed(icans): + if not all_yanked and ican.link.is_yanked: + continue + func = functools.partial( + self._make_candidate_from_link, + link=ican.link, + extras=extras, + template=template, + name=name, + version=ican.version, + ) + yield ican.version, func + + return FoundCandidates( + iter_index_candidate_infos, + installed_candidate, + prefers_installed, + ) + + def find_candidates( + self, + requirements, # type: Sequence[Requirement] + constraint, # type: Constraint + prefers_installed, # type: bool + ): + # type: (...) -> Iterable[Candidate] + explicit_candidates = set() # type: Set[Candidate] + ireqs = [] # type: List[InstallRequirement] + for req in requirements: + cand, ireq = req.get_candidate_lookup() + if cand is not None: + explicit_candidates.add(cand) + if ireq is not None: + ireqs.append(ireq) + + # If none of the requirements want an explicit candidate, we can ask + # the finder for candidates. + if not explicit_candidates: + return self._iter_found_candidates( + ireqs, + constraint.specifier, + constraint.hashes, + prefers_installed, + ) + + return ( + c for c in explicit_candidates + if constraint.is_satisfied_by(c) + and all(req.is_satisfied_by(c) for req in requirements) + ) + + def make_requirement_from_install_req(self, ireq, requested_extras): + # type: (InstallRequirement, Iterable[str]) -> Optional[Requirement] + if not ireq.match_markers(requested_extras): + logger.info( + "Ignoring %s: markers '%s' don't match your environment", + ireq.name, ireq.markers, + ) + return None + if not ireq.link: + return SpecifierRequirement(ireq) + if ireq.link.is_wheel: + wheel = Wheel(ireq.link.filename) + if not wheel.supported(self._finder.target_python.get_tags()): + msg = "{} is not a supported wheel on this platform.".format( + wheel.filename, + ) + raise UnsupportedWheel(msg) + cand = self._make_candidate_from_link( + ireq.link, + extras=frozenset(ireq.extras), + template=ireq, + name=canonicalize_name(ireq.name) if ireq.name else None, + version=None, + ) + if cand is None: + # There's no way we can satisfy a URL requirement if the underlying + # candidate fails to build. An unnamed URL must be user-supplied, so + # we fail eagerly. If the URL is named, an unsatisfiable requirement + # can make the resolver do the right thing, either backtrack (and + # maybe find some other requirement that's buildable) or raise a + # ResolutionImpossible eventually. + if not ireq.name: + raise self._build_failures[ireq.link] + return UnsatisfiableRequirement(canonicalize_name(ireq.name)) + return self.make_requirement_from_candidate(cand) + + def make_requirement_from_candidate(self, candidate): + # type: (Candidate) -> ExplicitRequirement + return ExplicitRequirement(candidate) + + def make_requirement_from_spec( + self, + specifier, # type: str + comes_from, # type: InstallRequirement + requested_extras=(), # type: Iterable[str] + ): + # type: (...) -> Optional[Requirement] + ireq = self._make_install_req_from_spec(specifier, comes_from) + return self.make_requirement_from_install_req(ireq, requested_extras) + + def make_requires_python_requirement(self, specifier): + # type: (Optional[SpecifierSet]) -> Optional[Requirement] + if self._ignore_requires_python or specifier is None: + return None + return RequiresPythonRequirement(specifier, self._python_candidate) + + def get_wheel_cache_entry(self, link, name): + # type: (Link, Optional[str]) -> Optional[CacheEntry] + """Look up the link in the wheel cache. + + If ``preparer.require_hashes`` is True, don't use the wheel cache, + because cached wheels, always built locally, have different hashes + than the files downloaded from the index server and thus throw false + hash mismatches. Furthermore, cached wheels at present have + nondeterministic contents due to file modification times. + """ + if self._wheel_cache is None or self.preparer.require_hashes: + return None + return self._wheel_cache.get_cache_entry( + link=link, + package_name=name, + supported_tags=get_supported(), + ) + + def get_dist_to_uninstall(self, candidate): + # type: (Candidate) -> Optional[Distribution] + # TODO: Are there more cases this needs to return True? Editable? + dist = self._installed_dists.get(candidate.name) + if dist is None: # Not installed, no uninstallation required. + return None + + # We're installing into global site. The current installation must + # be uninstalled, no matter it's in global or user site, because the + # user site installation has precedence over global. + if not self._use_user_site: + return dist + + # We're installing into user site. Remove the user site installation. + if dist_in_usersite(dist): + return dist + + # We're installing into user site, but the installed incompatible + # package is in global site. We can't uninstall that, and would let + # the new user installation to "shadow" it. But shadowing won't work + # in virtual environments, so we error out. + if running_under_virtualenv() and dist_in_site_packages(dist): + raise InstallationError( + "Will not install to the user site because it will " + "lack sys.path precedence to {} in {}".format( + dist.project_name, dist.location, + ) + ) + return None + + def _report_requires_python_error( + self, + requirement, # type: RequiresPythonRequirement + template, # type: Candidate + ): + # type: (...) -> UnsupportedPythonVersion + message_format = ( + "Package {package!r} requires a different Python: " + "{version} not in {specifier!r}" + ) + message = message_format.format( + package=template.name, + version=self._python_candidate.version, + specifier=str(requirement.specifier), + ) + return UnsupportedPythonVersion(message) + + def get_installation_error(self, e): + # type: (ResolutionImpossible) -> InstallationError + + assert e.causes, "Installation error reported with no cause" + + # If one of the things we can't solve is "we need Python X.Y", + # that is what we report. + for cause in e.causes: + if isinstance(cause.requirement, RequiresPythonRequirement): + return self._report_requires_python_error( + cause.requirement, + cause.parent, + ) + + # Otherwise, we have a set of causes which can't all be satisfied + # at once. + + # The simplest case is when we have *one* cause that can't be + # satisfied. We just report that case. + if len(e.causes) == 1: + req, parent = e.causes[0] + if parent is None: + req_disp = str(req) + else: + req_disp = f'{req} (from {parent.name})' + logger.critical( + "Could not find a version that satisfies the requirement %s", + req_disp, + ) + return DistributionNotFound( + f'No matching distribution found for {req}' + ) + + # OK, we now have a list of requirements that can't all be + # satisfied at once. + + # A couple of formatting helpers + def text_join(parts): + # type: (List[str]) -> str + if len(parts) == 1: + return parts[0] + + return ", ".join(parts[:-1]) + " and " + parts[-1] + + def describe_trigger(parent): + # type: (Candidate) -> str + ireq = parent.get_install_requirement() + if not ireq or not ireq.comes_from: + return f"{parent.name}=={parent.version}" + if isinstance(ireq.comes_from, InstallRequirement): + return str(ireq.comes_from.name) + return str(ireq.comes_from) + + triggers = set() + for req, parent in e.causes: + if parent is None: + # This is a root requirement, so we can report it directly + trigger = req.format_for_error() + else: + trigger = describe_trigger(parent) + triggers.add(trigger) + + if triggers: + info = text_join(sorted(triggers)) + else: + info = "the requested packages" + + msg = "Cannot install {} because these package versions " \ + "have conflicting dependencies.".format(info) + logger.critical(msg) + msg = "\nThe conflict is caused by:" + for req, parent in e.causes: + msg = msg + "\n " + if parent: + msg = msg + "{} {} depends on ".format( + parent.name, + parent.version + ) + else: + msg = msg + "The user requested " + msg = msg + req.format_for_error() + + msg = msg + "\n\n" + \ + "To fix this you could try to:\n" + \ + "1. loosen the range of package versions you've specified\n" + \ + "2. remove package versions to allow pip attempt to solve " + \ + "the dependency conflict\n" + + logger.info(msg) + + return DistributionNotFound( + "ResolutionImpossible: for help visit " + "https://pip.pypa.io/en/latest/user_guide/" + "#fixing-conflicting-dependencies" + ) diff --git a/venv/Lib/site-packages/pip/_internal/resolution/resolvelib/found_candidates.py b/venv/Lib/site-packages/pip/_internal/resolution/resolvelib/found_candidates.py new file mode 100644 index 0000000..5d4b465 --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/resolution/resolvelib/found_candidates.py @@ -0,0 +1,145 @@ +"""Utilities to lazily create and visit candidates found. + +Creating and visiting a candidate is a *very* costly operation. It involves +fetching, extracting, potentially building modules from source, and verifying +distribution metadata. It is therefore crucial for performance to keep +everything here lazy all the way down, so we only touch candidates that we +absolutely need, and not "download the world" when we only need one version of +something. +""" + +import functools + +from pip._vendor.six.moves import collections_abc # type: ignore + +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import Callable, Iterator, Optional, Set, Tuple + + from pip._vendor.packaging.version import _BaseVersion + + from .base import Candidate + + IndexCandidateInfo = Tuple[_BaseVersion, Callable[[], Optional[Candidate]]] + + +def _iter_built(infos): + # type: (Iterator[IndexCandidateInfo]) -> Iterator[Candidate] + """Iterator for ``FoundCandidates``. + + This iterator is used the package is not already installed. Candidates + from index come later in their normal ordering. + """ + versions_found = set() # type: Set[_BaseVersion] + for version, func in infos: + if version in versions_found: + continue + candidate = func() + if candidate is None: + continue + yield candidate + versions_found.add(version) + + +def _iter_built_with_prepended(installed, infos): + # type: (Candidate, Iterator[IndexCandidateInfo]) -> Iterator[Candidate] + """Iterator for ``FoundCandidates``. + + This iterator is used when the resolver prefers the already-installed + candidate and NOT to upgrade. The installed candidate is therefore + always yielded first, and candidates from index come later in their + normal ordering, except skipped when the version is already installed. + """ + yield installed + versions_found = {installed.version} # type: Set[_BaseVersion] + for version, func in infos: + if version in versions_found: + continue + candidate = func() + if candidate is None: + continue + yield candidate + versions_found.add(version) + + +def _iter_built_with_inserted(installed, infos): + # type: (Candidate, Iterator[IndexCandidateInfo]) -> Iterator[Candidate] + """Iterator for ``FoundCandidates``. + + This iterator is used when the resolver prefers to upgrade an + already-installed package. Candidates from index are returned in their + normal ordering, except replaced when the version is already installed. + + The implementation iterates through and yields other candidates, inserting + the installed candidate exactly once before we start yielding older or + equivalent candidates, or after all other candidates if they are all newer. + """ + versions_found = set() # type: Set[_BaseVersion] + for version, func in infos: + if version in versions_found: + continue + # If the installed candidate is better, yield it first. + if installed.version >= version: + yield installed + versions_found.add(installed.version) + candidate = func() + if candidate is None: + continue + yield candidate + versions_found.add(version) + + # If the installed candidate is older than all other candidates. + if installed.version not in versions_found: + yield installed + + +class FoundCandidates(collections_abc.Sequence): + """A lazy sequence to provide candidates to the resolver. + + The intended usage is to return this from `find_matches()` so the resolver + can iterate through the sequence multiple times, but only access the index + page when remote packages are actually needed. This improve performances + when suitable candidates are already installed on disk. + """ + def __init__( + self, + get_infos, # type: Callable[[], Iterator[IndexCandidateInfo]] + installed, # type: Optional[Candidate] + prefers_installed, # type: bool + ): + self._get_infos = get_infos + self._installed = installed + self._prefers_installed = prefers_installed + + def __getitem__(self, index): + # type: (int) -> Candidate + # Implemented to satisfy the ABC check. This is not needed by the + # resolver, and should not be used by the provider either (for + # performance reasons). + raise NotImplementedError("don't do this") + + def __iter__(self): + # type: () -> Iterator[Candidate] + infos = self._get_infos() + if not self._installed: + return _iter_built(infos) + if self._prefers_installed: + return _iter_built_with_prepended(self._installed, infos) + return _iter_built_with_inserted(self._installed, infos) + + def __len__(self): + # type: () -> int + # Implemented to satisfy the ABC check. This is not needed by the + # resolver, and should not be used by the provider either (for + # performance reasons). + raise NotImplementedError("don't do this") + + @functools.lru_cache(maxsize=1) + def __bool__(self): + # type: () -> bool + if self._prefers_installed and self._installed: + return True + return any(self) + + __nonzero__ = __bool__ # XXX: Python 2. diff --git a/venv/Lib/site-packages/pip/_internal/resolution/resolvelib/provider.py b/venv/Lib/site-packages/pip/_internal/resolution/resolvelib/provider.py new file mode 100644 index 0000000..40a641a --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/resolution/resolvelib/provider.py @@ -0,0 +1,174 @@ +from pip._vendor.resolvelib.providers import AbstractProvider + +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +from .base import Constraint + +if MYPY_CHECK_RUNNING: + from typing import Any, Dict, Iterable, Optional, Sequence, Set, Tuple, Union + + from .base import Candidate, Requirement + from .factory import Factory + +# Notes on the relationship between the provider, the factory, and the +# candidate and requirement classes. +# +# The provider is a direct implementation of the resolvelib class. Its role +# is to deliver the API that resolvelib expects. +# +# Rather than work with completely abstract "requirement" and "candidate" +# concepts as resolvelib does, pip has concrete classes implementing these two +# ideas. The API of Requirement and Candidate objects are defined in the base +# classes, but essentially map fairly directly to the equivalent provider +# methods. In particular, `find_matches` and `is_satisfied_by` are +# requirement methods, and `get_dependencies` is a candidate method. +# +# The factory is the interface to pip's internal mechanisms. It is stateless, +# and is created by the resolver and held as a property of the provider. It is +# responsible for creating Requirement and Candidate objects, and provides +# services to those objects (access to pip's finder and preparer). + + +class PipProvider(AbstractProvider): + """Pip's provider implementation for resolvelib. + + :params constraints: A mapping of constraints specified by the user. Keys + are canonicalized project names. + :params ignore_dependencies: Whether the user specified ``--no-deps``. + :params upgrade_strategy: The user-specified upgrade strategy. + :params user_requested: A set of canonicalized package names that the user + supplied for pip to install/upgrade. + """ + + def __init__( + self, + factory, # type: Factory + constraints, # type: Dict[str, Constraint] + ignore_dependencies, # type: bool + upgrade_strategy, # type: str + user_requested, # type: Set[str] + ): + # type: (...) -> None + self._factory = factory + self._constraints = constraints + self._ignore_dependencies = ignore_dependencies + self._upgrade_strategy = upgrade_strategy + self._user_requested = user_requested + + def identify(self, dependency): + # type: (Union[Requirement, Candidate]) -> str + return dependency.name + + def get_preference( + self, + resolution, # type: Optional[Candidate] + candidates, # type: Sequence[Candidate] + information # type: Sequence[Tuple[Requirement, Candidate]] + ): + # type: (...) -> Any + """Produce a sort key for given requirement based on preference. + + The lower the return value is, the more preferred this group of + arguments is. + + Currently pip considers the followings in order: + + * Prefer if any of the known requirements points to an explicit URL. + * If equal, prefer if any requirements contain ``===`` and ``==``. + * If equal, prefer if requirements include version constraints, e.g. + ``>=`` and ``<``. + * If equal, prefer user-specified (non-transitive) requirements. + * If equal, order alphabetically for consistency (helps debuggability). + """ + + def _get_restrictive_rating(requirements): + # type: (Iterable[Requirement]) -> int + """Rate how restrictive a set of requirements are. + + ``Requirement.get_candidate_lookup()`` returns a 2-tuple for + lookup. The first element is ``Optional[Candidate]`` and the + second ``Optional[InstallRequirement]``. + + * If the requirement is an explicit one, the explicitly-required + candidate is returned as the first element. + * If the requirement is based on a PEP 508 specifier, the backing + ``InstallRequirement`` is returned as the second element. + + We use the first element to check whether there is an explicit + requirement, and the second for equality operator. + """ + lookups = (r.get_candidate_lookup() for r in requirements) + cands, ireqs = zip(*lookups) + if any(cand is not None for cand in cands): + return 0 + spec_sets = (ireq.specifier for ireq in ireqs if ireq) + operators = [ + specifier.operator + for spec_set in spec_sets + for specifier in spec_set + ] + if any(op in ("==", "===") for op in operators): + return 1 + if operators: + return 2 + # A "bare" requirement without any version requirements. + return 3 + + restrictive = _get_restrictive_rating(req for req, _ in information) + transitive = all(parent is not None for _, parent in information) + key = next(iter(candidates)).name if candidates else "" + + # HACK: Setuptools have a very long and solid backward compatibility + # track record, and extremely few projects would request a narrow, + # non-recent version range of it since that would break a lot things. + # (Most projects specify it only to request for an installer feature, + # which does not work, but that's another topic.) Intentionally + # delaying Setuptools helps reduce branches the resolver has to check. + # This serves as a temporary fix for issues like "apache-airlfow[all]" + # while we work on "proper" branch pruning techniques. + delay_this = (key == "setuptools") + + return (delay_this, restrictive, transitive, key) + + def find_matches(self, requirements): + # type: (Sequence[Requirement]) -> Iterable[Candidate] + if not requirements: + return [] + name = requirements[0].project_name + + def _eligible_for_upgrade(name): + # type: (str) -> bool + """Are upgrades allowed for this project? + + This checks the upgrade strategy, and whether the project was one + that the user specified in the command line, in order to decide + whether we should upgrade if there's a newer version available. + + (Note that we don't need access to the `--upgrade` flag, because + an upgrade strategy of "to-satisfy-only" means that `--upgrade` + was not specified). + """ + if self._upgrade_strategy == "eager": + return True + elif self._upgrade_strategy == "only-if-needed": + return (name in self._user_requested) + return False + + return self._factory.find_candidates( + requirements, + constraint=self._constraints.get(name, Constraint.empty()), + prefers_installed=(not _eligible_for_upgrade(name)), + ) + + def is_satisfied_by(self, requirement, candidate): + # type: (Requirement, Candidate) -> bool + return requirement.is_satisfied_by(candidate) + + def get_dependencies(self, candidate): + # type: (Candidate) -> Sequence[Requirement] + with_requires = not self._ignore_dependencies + return [ + r + for r in candidate.iter_dependencies(with_requires) + if r is not None + ] diff --git a/venv/Lib/site-packages/pip/_internal/resolution/resolvelib/reporter.py b/venv/Lib/site-packages/pip/_internal/resolution/resolvelib/reporter.py new file mode 100644 index 0000000..d0ef3fa --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/resolution/resolvelib/reporter.py @@ -0,0 +1,84 @@ +from collections import defaultdict +from logging import getLogger + +from pip._vendor.resolvelib.reporters import BaseReporter + +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import Any, DefaultDict + + from .base import Candidate, Requirement + + +logger = getLogger(__name__) + + +class PipReporter(BaseReporter): + + def __init__(self): + # type: () -> None + self.backtracks_by_package = defaultdict(int) # type: DefaultDict[str, int] + + self._messages_at_backtrack = { + 1: ( + "pip is looking at multiple versions of {package_name} to " + "determine which version is compatible with other " + "requirements. This could take a while." + ), + 8: ( + "pip is looking at multiple versions of {package_name} to " + "determine which version is compatible with other " + "requirements. This could take a while." + ), + 13: ( + "This is taking longer than usual. You might need to provide " + "the dependency resolver with stricter constraints to reduce " + "runtime. If you want to abort this run, you can press " + "Ctrl + C to do so. To improve how pip performs, tell us what " + "happened here: https://pip.pypa.io/surveys/backtracking" + ) + } + + def backtracking(self, candidate): + # type: (Candidate) -> None + self.backtracks_by_package[candidate.name] += 1 + + count = self.backtracks_by_package[candidate.name] + if count not in self._messages_at_backtrack: + return + + message = self._messages_at_backtrack[count] + logger.info("INFO: %s", message.format(package_name=candidate.name)) + + +class PipDebuggingReporter(BaseReporter): + """A reporter that does an info log for every event it sees.""" + + def starting(self): + # type: () -> None + logger.info("Reporter.starting()") + + def starting_round(self, index): + # type: (int) -> None + logger.info("Reporter.starting_round(%r)", index) + + def ending_round(self, index, state): + # type: (int, Any) -> None + logger.info("Reporter.ending_round(%r, state)", index) + + def ending(self, state): + # type: (Any) -> None + logger.info("Reporter.ending(%r)", state) + + def adding_requirement(self, requirement, parent): + # type: (Requirement, Candidate) -> None + logger.info("Reporter.adding_requirement(%r, %r)", requirement, parent) + + def backtracking(self, candidate): + # type: (Candidate) -> None + logger.info("Reporter.backtracking(%r)", candidate) + + def pinning(self, candidate): + # type: (Candidate) -> None + logger.info("Reporter.pinning(%r)", candidate) diff --git a/venv/Lib/site-packages/pip/_internal/resolution/resolvelib/requirements.py b/venv/Lib/site-packages/pip/_internal/resolution/resolvelib/requirements.py new file mode 100644 index 0000000..61c81e0 --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/resolution/resolvelib/requirements.py @@ -0,0 +1,201 @@ +from pip._vendor.packaging.utils import canonicalize_name + +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +from .base import Requirement, format_name + +if MYPY_CHECK_RUNNING: + from pip._vendor.packaging.specifiers import SpecifierSet + + from pip._internal.req.req_install import InstallRequirement + + from .base import Candidate, CandidateLookup + + +class ExplicitRequirement(Requirement): + def __init__(self, candidate): + # type: (Candidate) -> None + self.candidate = candidate + + def __str__(self): + # type: () -> str + return str(self.candidate) + + def __repr__(self): + # type: () -> str + return "{class_name}({candidate!r})".format( + class_name=self.__class__.__name__, + candidate=self.candidate, + ) + + @property + def project_name(self): + # type: () -> str + # No need to canonicalise - the candidate did this + return self.candidate.project_name + + @property + def name(self): + # type: () -> str + # No need to canonicalise - the candidate did this + return self.candidate.name + + def format_for_error(self): + # type: () -> str + return self.candidate.format_for_error() + + def get_candidate_lookup(self): + # type: () -> CandidateLookup + return self.candidate, None + + def is_satisfied_by(self, candidate): + # type: (Candidate) -> bool + return candidate == self.candidate + + +class SpecifierRequirement(Requirement): + def __init__(self, ireq): + # type: (InstallRequirement) -> None + assert ireq.link is None, "This is a link, not a specifier" + self._ireq = ireq + self._extras = frozenset(ireq.extras) + + def __str__(self): + # type: () -> str + return str(self._ireq.req) + + def __repr__(self): + # type: () -> str + return "{class_name}({requirement!r})".format( + class_name=self.__class__.__name__, + requirement=str(self._ireq.req), + ) + + @property + def project_name(self): + # type: () -> str + return canonicalize_name(self._ireq.req.name) + + @property + def name(self): + # type: () -> str + return format_name(self.project_name, self._extras) + + def format_for_error(self): + # type: () -> str + + # Convert comma-separated specifiers into "A, B, ..., F and G" + # This makes the specifier a bit more "human readable", without + # risking a change in meaning. (Hopefully! Not all edge cases have + # been checked) + parts = [s.strip() for s in str(self).split(",")] + if len(parts) == 0: + return "" + elif len(parts) == 1: + return parts[0] + + return ", ".join(parts[:-1]) + " and " + parts[-1] + + def get_candidate_lookup(self): + # type: () -> CandidateLookup + return None, self._ireq + + def is_satisfied_by(self, candidate): + # type: (Candidate) -> bool + assert candidate.name == self.name, \ + "Internal issue: Candidate is not for this requirement " \ + " {} vs {}".format(candidate.name, self.name) + # We can safely always allow prereleases here since PackageFinder + # already implements the prerelease logic, and would have filtered out + # prerelease candidates if the user does not expect them. + spec = self._ireq.req.specifier + return spec.contains(candidate.version, prereleases=True) + + +class RequiresPythonRequirement(Requirement): + """A requirement representing Requires-Python metadata. + """ + def __init__(self, specifier, match): + # type: (SpecifierSet, Candidate) -> None + self.specifier = specifier + self._candidate = match + + def __str__(self): + # type: () -> str + return f"Python {self.specifier}" + + def __repr__(self): + # type: () -> str + return "{class_name}({specifier!r})".format( + class_name=self.__class__.__name__, + specifier=str(self.specifier), + ) + + @property + def project_name(self): + # type: () -> str + return self._candidate.project_name + + @property + def name(self): + # type: () -> str + return self._candidate.name + + def format_for_error(self): + # type: () -> str + return str(self) + + def get_candidate_lookup(self): + # type: () -> CandidateLookup + if self.specifier.contains(self._candidate.version, prereleases=True): + return self._candidate, None + return None, None + + def is_satisfied_by(self, candidate): + # type: (Candidate) -> bool + assert candidate.name == self._candidate.name, "Not Python candidate" + # We can safely always allow prereleases here since PackageFinder + # already implements the prerelease logic, and would have filtered out + # prerelease candidates if the user does not expect them. + return self.specifier.contains(candidate.version, prereleases=True) + + +class UnsatisfiableRequirement(Requirement): + """A requirement that cannot be satisfied. + """ + def __init__(self, name): + # type: (str) -> None + self._name = name + + def __str__(self): + # type: () -> str + return "{} (unavailable)".format(self._name) + + def __repr__(self): + # type: () -> str + return "{class_name}({name!r})".format( + class_name=self.__class__.__name__, + name=str(self._name), + ) + + @property + def project_name(self): + # type: () -> str + return self._name + + @property + def name(self): + # type: () -> str + return self._name + + def format_for_error(self): + # type: () -> str + return str(self) + + def get_candidate_lookup(self): + # type: () -> CandidateLookup + return None, None + + def is_satisfied_by(self, candidate): + # type: (Candidate) -> bool + return False diff --git a/venv/Lib/site-packages/pip/_internal/resolution/resolvelib/resolver.py b/venv/Lib/site-packages/pip/_internal/resolution/resolvelib/resolver.py new file mode 100644 index 0000000..d30d696 --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/resolution/resolvelib/resolver.py @@ -0,0 +1,296 @@ +import functools +import logging +import os + +from pip._vendor import six +from pip._vendor.packaging.utils import canonicalize_name +from pip._vendor.resolvelib import ResolutionImpossible +from pip._vendor.resolvelib import Resolver as RLResolver + +from pip._internal.exceptions import InstallationError +from pip._internal.req.req_install import check_invalid_constraint_type +from pip._internal.req.req_set import RequirementSet +from pip._internal.resolution.base import BaseResolver +from pip._internal.resolution.resolvelib.provider import PipProvider +from pip._internal.resolution.resolvelib.reporter import ( + PipDebuggingReporter, + PipReporter, +) +from pip._internal.utils.deprecation import deprecated +from pip._internal.utils.filetypes import is_archive_file +from pip._internal.utils.misc import dist_is_editable +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +from .base import Constraint +from .factory import Factory + +if MYPY_CHECK_RUNNING: + from typing import Dict, List, Optional, Set, Tuple + + from pip._vendor.resolvelib.resolvers import Result + from pip._vendor.resolvelib.structs import Graph + + from pip._internal.cache import WheelCache + from pip._internal.index.package_finder import PackageFinder + from pip._internal.operations.prepare import RequirementPreparer + from pip._internal.req.req_install import InstallRequirement + from pip._internal.resolution.base import InstallRequirementProvider + + +logger = logging.getLogger(__name__) + + +class Resolver(BaseResolver): + _allowed_strategies = {"eager", "only-if-needed", "to-satisfy-only"} + + def __init__( + self, + preparer, # type: RequirementPreparer + finder, # type: PackageFinder + wheel_cache, # type: Optional[WheelCache] + make_install_req, # type: InstallRequirementProvider + use_user_site, # type: bool + ignore_dependencies, # type: bool + ignore_installed, # type: bool + ignore_requires_python, # type: bool + force_reinstall, # type: bool + upgrade_strategy, # type: str + py_version_info=None, # type: Optional[Tuple[int, ...]] + ): + super().__init__() + assert upgrade_strategy in self._allowed_strategies + + self.factory = Factory( + finder=finder, + preparer=preparer, + make_install_req=make_install_req, + wheel_cache=wheel_cache, + use_user_site=use_user_site, + force_reinstall=force_reinstall, + ignore_installed=ignore_installed, + ignore_requires_python=ignore_requires_python, + py_version_info=py_version_info, + ) + self.ignore_dependencies = ignore_dependencies + self.upgrade_strategy = upgrade_strategy + self._result = None # type: Optional[Result] + + def resolve(self, root_reqs, check_supported_wheels): + # type: (List[InstallRequirement], bool) -> RequirementSet + + constraints = {} # type: Dict[str, Constraint] + user_requested = set() # type: Set[str] + requirements = [] + for req in root_reqs: + if req.constraint: + # Ensure we only accept valid constraints + problem = check_invalid_constraint_type(req) + if problem: + raise InstallationError(problem) + if not req.match_markers(): + continue + name = canonicalize_name(req.name) + if name in constraints: + constraints[name] &= req + else: + constraints[name] = Constraint.from_ireq(req) + else: + if req.user_supplied and req.name: + user_requested.add(canonicalize_name(req.name)) + r = self.factory.make_requirement_from_install_req( + req, requested_extras=(), + ) + if r is not None: + requirements.append(r) + + provider = PipProvider( + factory=self.factory, + constraints=constraints, + ignore_dependencies=self.ignore_dependencies, + upgrade_strategy=self.upgrade_strategy, + user_requested=user_requested, + ) + if "PIP_RESOLVER_DEBUG" in os.environ: + reporter = PipDebuggingReporter() + else: + reporter = PipReporter() + resolver = RLResolver(provider, reporter) + + try: + try_to_avoid_resolution_too_deep = 2000000 + self._result = resolver.resolve( + requirements, max_rounds=try_to_avoid_resolution_too_deep, + ) + + except ResolutionImpossible as e: + error = self.factory.get_installation_error(e) + six.raise_from(error, e) + + req_set = RequirementSet(check_supported_wheels=check_supported_wheels) + for candidate in self._result.mapping.values(): + ireq = candidate.get_install_requirement() + if ireq is None: + continue + + # Check if there is already an installation under the same name, + # and set a flag for later stages to uninstall it, if needed. + installed_dist = self.factory.get_dist_to_uninstall(candidate) + if installed_dist is None: + # There is no existing installation -- nothing to uninstall. + ireq.should_reinstall = False + elif self.factory.force_reinstall: + # The --force-reinstall flag is set -- reinstall. + ireq.should_reinstall = True + elif installed_dist.parsed_version != candidate.version: + # The installation is different in version -- reinstall. + ireq.should_reinstall = True + elif candidate.is_editable or dist_is_editable(installed_dist): + # The incoming distribution is editable, or different in + # editable-ness to installation -- reinstall. + ireq.should_reinstall = True + elif candidate.source_link.is_file: + # The incoming distribution is under file:// + if candidate.source_link.is_wheel: + # is a local wheel -- do nothing. + logger.info( + "%s is already installed with the same version as the " + "provided wheel. Use --force-reinstall to force an " + "installation of the wheel.", + ireq.name, + ) + continue + + looks_like_sdist = ( + is_archive_file(candidate.source_link.file_path) + and candidate.source_link.ext != ".zip" + ) + if looks_like_sdist: + # is a local sdist -- show a deprecation warning! + reason = ( + "Source distribution is being reinstalled despite an " + "installed package having the same name and version as " + "the installed package." + ) + replacement = "use --force-reinstall" + deprecated( + reason=reason, + replacement=replacement, + gone_in="21.1", + issue=8711, + ) + + # is a local sdist or path -- reinstall + ireq.should_reinstall = True + else: + continue + + link = candidate.source_link + if link and link.is_yanked: + # The reason can contain non-ASCII characters, Unicode + # is required for Python 2. + msg = ( + 'The candidate selected for download or install is a ' + 'yanked version: {name!r} candidate (version {version} ' + 'at {link})\nReason for being yanked: {reason}' + ).format( + name=candidate.name, + version=candidate.version, + link=link, + reason=link.yanked_reason or '', + ) + logger.warning(msg) + + req_set.add_named_requirement(ireq) + + reqs = req_set.all_requirements + self.factory.preparer.prepare_linked_requirements_more(reqs) + return req_set + + def get_installation_order(self, req_set): + # type: (RequirementSet) -> List[InstallRequirement] + """Get order for installation of requirements in RequirementSet. + + The returned list contains a requirement before another that depends on + it. This helps ensure that the environment is kept consistent as they + get installed one-by-one. + + The current implementation creates a topological ordering of the + dependency graph, while breaking any cycles in the graph at arbitrary + points. We make no guarantees about where the cycle would be broken, + other than they would be broken. + """ + assert self._result is not None, "must call resolve() first" + + graph = self._result.graph + weights = get_topological_weights( + graph, + expected_node_count=len(self._result.mapping) + 1, + ) + + sorted_items = sorted( + req_set.requirements.items(), + key=functools.partial(_req_set_item_sorter, weights=weights), + reverse=True, + ) + return [ireq for _, ireq in sorted_items] + + +def get_topological_weights(graph, expected_node_count): + # type: (Graph, int) -> Dict[Optional[str], int] + """Assign weights to each node based on how "deep" they are. + + This implementation may change at any point in the future without prior + notice. + + We take the length for the longest path to any node from root, ignoring any + paths that contain a single node twice (i.e. cycles). This is done through + a depth-first search through the graph, while keeping track of the path to + the node. + + Cycles in the graph result would result in node being revisited while also + being it's own path. In this case, take no action. This helps ensure we + don't get stuck in a cycle. + + When assigning weight, the longer path (i.e. larger length) is preferred. + """ + path = set() # type: Set[Optional[str]] + weights = {} # type: Dict[Optional[str], int] + + def visit(node): + # type: (Optional[str]) -> None + if node in path: + # We hit a cycle, so we'll break it here. + return + + # Time to visit the children! + path.add(node) + for child in graph.iter_children(node): + visit(child) + path.remove(node) + + last_known_parent_count = weights.get(node, 0) + weights[node] = max(last_known_parent_count, len(path)) + + # `None` is guaranteed to be the root node by resolvelib. + visit(None) + + # Sanity checks + assert weights[None] == 0 + assert len(weights) == expected_node_count + + return weights + + +def _req_set_item_sorter( + item, # type: Tuple[str, InstallRequirement] + weights, # type: Dict[Optional[str], int] +): + # type: (...) -> Tuple[int, str] + """Key function used to sort install requirements for installation. + + Based on the "weight" mapping calculated in ``get_installation_order()``. + The canonical package name is returned as the second member as a tie- + breaker to ensure the result is predictable, which is useful in tests. + """ + name = canonicalize_name(item[0]) + return weights[name], name diff --git a/venv/Lib/site-packages/pip/_internal/self_outdated_check.py b/venv/Lib/site-packages/pip/_internal/self_outdated_check.py new file mode 100644 index 0000000..c22f06a --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/self_outdated_check.py @@ -0,0 +1,195 @@ +import datetime +import hashlib +import json +import logging +import os.path +import sys + +from pip._vendor.packaging import version as packaging_version +from pip._vendor.six import ensure_binary + +from pip._internal.index.collector import LinkCollector +from pip._internal.index.package_finder import PackageFinder +from pip._internal.models.selection_prefs import SelectionPreferences +from pip._internal.utils.filesystem import adjacent_tmp_file, check_path_owner, replace +from pip._internal.utils.misc import ensure_dir, get_distribution, get_installed_version +from pip._internal.utils.packaging import get_installer +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + import optparse + from typing import Any, Dict + + from pip._internal.network.session import PipSession + + +SELFCHECK_DATE_FMT = "%Y-%m-%dT%H:%M:%SZ" + + +logger = logging.getLogger(__name__) + + +def _get_statefile_name(key): + # type: (str) -> str + key_bytes = ensure_binary(key) + name = hashlib.sha224(key_bytes).hexdigest() + return name + + +class SelfCheckState: + def __init__(self, cache_dir): + # type: (str) -> None + self.state = {} # type: Dict[str, Any] + self.statefile_path = None + + # Try to load the existing state + if cache_dir: + self.statefile_path = os.path.join( + cache_dir, "selfcheck", _get_statefile_name(self.key) + ) + try: + with open(self.statefile_path) as statefile: + self.state = json.load(statefile) + except (OSError, ValueError, KeyError): + # Explicitly suppressing exceptions, since we don't want to + # error out if the cache file is invalid. + pass + + @property + def key(self): + # type: () -> str + return sys.prefix + + def save(self, pypi_version, current_time): + # type: (str, datetime.datetime) -> None + # If we do not have a path to cache in, don't bother saving. + if not self.statefile_path: + return + + # Check to make sure that we own the directory + if not check_path_owner(os.path.dirname(self.statefile_path)): + return + + # Now that we've ensured the directory is owned by this user, we'll go + # ahead and make sure that all our directories are created. + ensure_dir(os.path.dirname(self.statefile_path)) + + state = { + # Include the key so it's easy to tell which pip wrote the + # file. + "key": self.key, + "last_check": current_time.strftime(SELFCHECK_DATE_FMT), + "pypi_version": pypi_version, + } + + text = json.dumps(state, sort_keys=True, separators=(",", ":")) + + with adjacent_tmp_file(self.statefile_path) as f: + f.write(ensure_binary(text)) + + try: + # Since we have a prefix-specific state file, we can just + # overwrite whatever is there, no need to check. + replace(f.name, self.statefile_path) + except OSError: + # Best effort. + pass + + +def was_installed_by_pip(pkg): + # type: (str) -> bool + """Checks whether pkg was installed by pip + + This is used not to display the upgrade message when pip is in fact + installed by system package manager, such as dnf on Fedora. + """ + dist = get_distribution(pkg) + if not dist: + return False + return "pip" == get_installer(dist) + + +def pip_self_version_check(session, options): + # type: (PipSession, optparse.Values) -> None + """Check for an update for pip. + + Limit the frequency of checks to once per week. State is stored either in + the active virtualenv or in the user's USER_CACHE_DIR keyed off the prefix + of the pip script path. + """ + installed_version = get_installed_version("pip") + if not installed_version: + return + + pip_version = packaging_version.parse(installed_version) + pypi_version = None + + try: + state = SelfCheckState(cache_dir=options.cache_dir) + + current_time = datetime.datetime.utcnow() + # Determine if we need to refresh the state + if "last_check" in state.state and "pypi_version" in state.state: + last_check = datetime.datetime.strptime( + state.state["last_check"], + SELFCHECK_DATE_FMT + ) + if (current_time - last_check).total_seconds() < 7 * 24 * 60 * 60: + pypi_version = state.state["pypi_version"] + + # Refresh the version if we need to or just see if we need to warn + if pypi_version is None: + # Lets use PackageFinder to see what the latest pip version is + link_collector = LinkCollector.create( + session, + options=options, + suppress_no_index=True, + ) + + # Pass allow_yanked=False so we don't suggest upgrading to a + # yanked version. + selection_prefs = SelectionPreferences( + allow_yanked=False, + allow_all_prereleases=False, # Explicitly set to False + ) + + finder = PackageFinder.create( + link_collector=link_collector, + selection_prefs=selection_prefs, + ) + best_candidate = finder.find_best_candidate("pip").best_candidate + if best_candidate is None: + return + pypi_version = str(best_candidate.version) + + # save that we've performed a check + state.save(pypi_version, current_time) + + remote_version = packaging_version.parse(pypi_version) + + local_version_is_older = ( + pip_version < remote_version and + pip_version.base_version != remote_version.base_version and + was_installed_by_pip('pip') + ) + + # Determine if our pypi_version is older + if not local_version_is_older: + return + + # We cannot tell how the current pip is available in the current + # command context, so be pragmatic here and suggest the command + # that's always available. This does not accommodate spaces in + # `sys.executable`. + pip_cmd = f"{sys.executable} -m pip" + logger.warning( + "You are using pip version %s; however, version %s is " + "available.\nYou should consider upgrading via the " + "'%s install --upgrade pip' command.", + pip_version, pypi_version, pip_cmd + ) + except Exception: + logger.debug( + "There was an error checking the latest version of pip", + exc_info=True, + ) diff --git a/venv/Lib/site-packages/pip/_internal/utils/__init__.py b/venv/Lib/site-packages/pip/_internal/utils/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/venv/Lib/site-packages/pip/_internal/utils/appdirs.py b/venv/Lib/site-packages/pip/_internal/utils/appdirs.py new file mode 100644 index 0000000..a0a37be --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/utils/appdirs.py @@ -0,0 +1,42 @@ +""" +This code wraps the vendored appdirs module to so the return values are +compatible for the current pip code base. + +The intention is to rewrite current usages gradually, keeping the tests pass, +and eventually drop this after all usages are changed. +""" + +import os + +from pip._vendor import appdirs as _appdirs + +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import List + + +def user_cache_dir(appname): + # type: (str) -> str + return _appdirs.user_cache_dir(appname, appauthor=False) + + +def user_config_dir(appname, roaming=True): + # type: (str, bool) -> str + path = _appdirs.user_config_dir(appname, appauthor=False, roaming=roaming) + if _appdirs.system == "darwin" and not os.path.isdir(path): + path = os.path.expanduser('~/.config/') + if appname: + path = os.path.join(path, appname) + return path + + +# for the discussion regarding site_config_dir locations +# see +def site_config_dirs(appname): + # type: (str) -> List[str] + dirval = _appdirs.site_config_dir(appname, appauthor=False, multipath=True) + if _appdirs.system not in ["win32", "darwin"]: + # always look in /etc directly as well + return dirval.split(os.pathsep) + ['/etc'] + return [dirval] diff --git a/venv/Lib/site-packages/pip/_internal/utils/compat.py b/venv/Lib/site-packages/pip/_internal/utils/compat.py new file mode 100644 index 0000000..0ae0483 --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/utils/compat.py @@ -0,0 +1,152 @@ +"""Stuff that differs in different Python versions and platform +distributions.""" + +# The following comment should be removed at some point in the future. +# mypy: disallow-untyped-defs=False + +import codecs +import locale +import logging +import os +import sys + +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import Optional, Union + + +__all__ = ["console_to_str", "get_path_uid", "stdlib_pkgs", "WINDOWS"] + + +logger = logging.getLogger(__name__) + + +def has_tls(): + # type: () -> bool + try: + import _ssl # noqa: F401 # ignore unused + return True + except ImportError: + pass + + from pip._vendor.urllib3.util import IS_PYOPENSSL + return IS_PYOPENSSL + + +def str_to_display(data, desc=None): + # type: (Union[bytes, str], Optional[str]) -> str + """ + For display or logging purposes, convert a bytes object (or text) to + text (e.g. unicode in Python 2) safe for output. + + :param desc: An optional phrase describing the input data, for use in + the log message if a warning is logged. Defaults to "Bytes object". + + This function should never error out and so can take a best effort + approach. It is okay to be lossy if needed since the return value is + just for display. + + We assume the data is in the locale preferred encoding. If it won't + decode properly, we warn the user but decode as best we can. + + We also ensure that the output can be safely written to standard output + without encoding errors. + """ + if isinstance(data, str): + return data + + # Otherwise, data is a bytes object (str in Python 2). + # First, get the encoding we assume. This is the preferred + # encoding for the locale, unless that is not found, or + # it is ASCII, in which case assume UTF-8 + encoding = locale.getpreferredencoding() + if (not encoding) or codecs.lookup(encoding).name == "ascii": + encoding = "utf-8" + + # Now try to decode the data - if we fail, warn the user and + # decode with replacement. + try: + decoded_data = data.decode(encoding) + except UnicodeDecodeError: + logger.warning( + '%s does not appear to be encoded as %s', + desc or 'Bytes object', + encoding, + ) + decoded_data = data.decode(encoding, errors="backslashreplace") + + # Make sure we can print the output, by encoding it to the output + # encoding with replacement of unencodable characters, and then + # decoding again. + # We use stderr's encoding because it's less likely to be + # redirected and if we don't find an encoding we skip this + # step (on the assumption that output is wrapped by something + # that won't fail). + # The double getattr is to deal with the possibility that we're + # being called in a situation where sys.__stderr__ doesn't exist, + # or doesn't have an encoding attribute. Neither of these cases + # should occur in normal pip use, but there's no harm in checking + # in case people use pip in (unsupported) unusual situations. + output_encoding = getattr(getattr(sys, "__stderr__", None), + "encoding", None) + + if output_encoding: + output_encoded = decoded_data.encode( + output_encoding, + errors="backslashreplace" + ) + decoded_data = output_encoded.decode(output_encoding) + + return decoded_data + + +def console_to_str(data): + # type: (bytes) -> str + """Return a string, safe for output, of subprocess output. + """ + return str_to_display(data, desc='Subprocess output') + + +def get_path_uid(path): + # type: (str) -> int + """ + Return path's uid. + + Does not follow symlinks: + https://github.com/pypa/pip/pull/935#discussion_r5307003 + + Placed this function in compat due to differences on AIX and + Jython, that should eventually go away. + + :raises OSError: When path is a symlink or can't be read. + """ + if hasattr(os, 'O_NOFOLLOW'): + fd = os.open(path, os.O_RDONLY | os.O_NOFOLLOW) + file_uid = os.fstat(fd).st_uid + os.close(fd) + else: # AIX and Jython + # WARNING: time of check vulnerability, but best we can do w/o NOFOLLOW + if not os.path.islink(path): + # older versions of Jython don't have `os.fstat` + file_uid = os.stat(path).st_uid + else: + # raise OSError for parity with os.O_NOFOLLOW above + raise OSError( + "{} is a symlink; Will not return uid for symlinks".format( + path) + ) + return file_uid + + +# packages in the stdlib that may have installation metadata, but should not be +# considered 'installed'. this theoretically could be determined based on +# dist.location (py27:`sysconfig.get_paths()['stdlib']`, +# py26:sysconfig.get_config_vars('LIBDEST')), but fear platform variation may +# make this ineffective, so hard-coding +stdlib_pkgs = {"python", "wsgiref", "argparse"} + + +# windows detection, covers cpython and ironpython +WINDOWS = (sys.platform.startswith("win") or + (sys.platform == 'cli' and os.name == 'nt')) diff --git a/venv/Lib/site-packages/pip/_internal/utils/compatibility_tags.py b/venv/Lib/site-packages/pip/_internal/utils/compatibility_tags.py new file mode 100644 index 0000000..ac37c3a --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/utils/compatibility_tags.py @@ -0,0 +1,176 @@ +"""Generate and work with PEP 425 Compatibility Tags. +""" + +import re + +from pip._vendor.packaging.tags import ( + Tag, + compatible_tags, + cpython_tags, + generic_tags, + interpreter_name, + interpreter_version, + mac_platforms, +) + +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import List, Optional, Tuple + + from pip._vendor.packaging.tags import PythonVersion + +_osx_arch_pat = re.compile(r'(.+)_(\d+)_(\d+)_(.+)') + + +def version_info_to_nodot(version_info): + # type: (Tuple[int, ...]) -> str + # Only use up to the first two numbers. + return ''.join(map(str, version_info[:2])) + + +def _mac_platforms(arch): + # type: (str) -> List[str] + match = _osx_arch_pat.match(arch) + if match: + name, major, minor, actual_arch = match.groups() + mac_version = (int(major), int(minor)) + arches = [ + # Since we have always only checked that the platform starts + # with "macosx", for backwards-compatibility we extract the + # actual prefix provided by the user in case they provided + # something like "macosxcustom_". It may be good to remove + # this as undocumented or deprecate it in the future. + '{}_{}'.format(name, arch[len('macosx_'):]) + for arch in mac_platforms(mac_version, actual_arch) + ] + else: + # arch pattern didn't match (?!) + arches = [arch] + return arches + + +def _custom_manylinux_platforms(arch): + # type: (str) -> List[str] + arches = [arch] + arch_prefix, arch_sep, arch_suffix = arch.partition('_') + if arch_prefix == 'manylinux2014': + # manylinux1/manylinux2010 wheels run on most manylinux2014 systems + # with the exception of wheels depending on ncurses. PEP 599 states + # manylinux1/manylinux2010 wheels should be considered + # manylinux2014 wheels: + # https://www.python.org/dev/peps/pep-0599/#backwards-compatibility-with-manylinux2010-wheels + if arch_suffix in {'i686', 'x86_64'}: + arches.append('manylinux2010' + arch_sep + arch_suffix) + arches.append('manylinux1' + arch_sep + arch_suffix) + elif arch_prefix == 'manylinux2010': + # manylinux1 wheels run on most manylinux2010 systems with the + # exception of wheels depending on ncurses. PEP 571 states + # manylinux1 wheels should be considered manylinux2010 wheels: + # https://www.python.org/dev/peps/pep-0571/#backwards-compatibility-with-manylinux1-wheels + arches.append('manylinux1' + arch_sep + arch_suffix) + return arches + + +def _get_custom_platforms(arch): + # type: (str) -> List[str] + arch_prefix, arch_sep, arch_suffix = arch.partition('_') + if arch.startswith('macosx'): + arches = _mac_platforms(arch) + elif arch_prefix in ['manylinux2014', 'manylinux2010']: + arches = _custom_manylinux_platforms(arch) + else: + arches = [arch] + return arches + + +def _expand_allowed_platforms(platforms): + # type: (Optional[List[str]]) -> Optional[List[str]] + if not platforms: + return None + + seen = set() + result = [] + + for p in platforms: + if p in seen: + continue + additions = [c for c in _get_custom_platforms(p) if c not in seen] + seen.update(additions) + result.extend(additions) + + return result + + +def _get_python_version(version): + # type: (str) -> PythonVersion + if len(version) > 1: + return int(version[0]), int(version[1:]) + else: + return (int(version[0]),) + + +def _get_custom_interpreter(implementation=None, version=None): + # type: (Optional[str], Optional[str]) -> str + if implementation is None: + implementation = interpreter_name() + if version is None: + version = interpreter_version() + return f"{implementation}{version}" + + +def get_supported( + version=None, # type: Optional[str] + platforms=None, # type: Optional[List[str]] + impl=None, # type: Optional[str] + abis=None # type: Optional[List[str]] +): + # type: (...) -> List[Tag] + """Return a list of supported tags for each version specified in + `versions`. + + :param version: a string version, of the form "33" or "32", + or None. The version will be assumed to support our ABI. + :param platform: specify a list of platforms you want valid + tags for, or None. If None, use the local system platform. + :param impl: specify the exact implementation you want valid + tags for, or None. If None, use the local interpreter impl. + :param abis: specify a list of abis you want valid + tags for, or None. If None, use the local interpreter abi. + """ + supported = [] # type: List[Tag] + + python_version = None # type: Optional[PythonVersion] + if version is not None: + python_version = _get_python_version(version) + + interpreter = _get_custom_interpreter(impl, version) + + platforms = _expand_allowed_platforms(platforms) + + is_cpython = (impl or interpreter_name()) == "cp" + if is_cpython: + supported.extend( + cpython_tags( + python_version=python_version, + abis=abis, + platforms=platforms, + ) + ) + else: + supported.extend( + generic_tags( + interpreter=interpreter, + abis=abis, + platforms=platforms, + ) + ) + supported.extend( + compatible_tags( + python_version=python_version, + interpreter=interpreter, + platforms=platforms, + ) + ) + + return supported diff --git a/venv/Lib/site-packages/pip/_internal/utils/datetime.py b/venv/Lib/site-packages/pip/_internal/utils/datetime.py new file mode 100644 index 0000000..b638646 --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/utils/datetime.py @@ -0,0 +1,12 @@ +"""For when pip wants to check the date or time. +""" + +import datetime + + +def today_is_later_than(year, month, day): + # type: (int, int, int) -> bool + today = datetime.date.today() + given = datetime.date(year, month, day) + + return today > given diff --git a/venv/Lib/site-packages/pip/_internal/utils/deprecation.py b/venv/Lib/site-packages/pip/_internal/utils/deprecation.py new file mode 100644 index 0000000..534d3fd --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/utils/deprecation.py @@ -0,0 +1,102 @@ +""" +A module that implements tooling to enable easy warnings about deprecations. +""" + +# The following comment should be removed at some point in the future. +# mypy: disallow-untyped-defs=False + +import logging +import warnings + +from pip._vendor.packaging.version import parse + +from pip import __version__ as current_version +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import Any, Optional + + +DEPRECATION_MSG_PREFIX = "DEPRECATION: " + + +class PipDeprecationWarning(Warning): + pass + + +_original_showwarning = None # type: Any + + +# Warnings <-> Logging Integration +def _showwarning(message, category, filename, lineno, file=None, line=None): + if file is not None: + if _original_showwarning is not None: + _original_showwarning( + message, category, filename, lineno, file, line, + ) + elif issubclass(category, PipDeprecationWarning): + # We use a specially named logger which will handle all of the + # deprecation messages for pip. + logger = logging.getLogger("pip._internal.deprecations") + logger.warning(message) + else: + _original_showwarning( + message, category, filename, lineno, file, line, + ) + + +def install_warning_logger(): + # type: () -> None + # Enable our Deprecation Warnings + warnings.simplefilter("default", PipDeprecationWarning, append=True) + + global _original_showwarning + + if _original_showwarning is None: + _original_showwarning = warnings.showwarning + warnings.showwarning = _showwarning + + +def deprecated(reason, replacement, gone_in, issue=None): + # type: (str, Optional[str], Optional[str], Optional[int]) -> None + """Helper to deprecate existing functionality. + + reason: + Textual reason shown to the user about why this functionality has + been deprecated. + replacement: + Textual suggestion shown to the user about what alternative + functionality they can use. + gone_in: + The version of pip does this functionality should get removed in. + Raises errors if pip's current version is greater than or equal to + this. + issue: + Issue number on the tracker that would serve as a useful place for + users to find related discussion and provide feedback. + + Always pass replacement, gone_in and issue as keyword arguments for clarity + at the call site. + """ + + # Construct a nice message. + # This is eagerly formatted as we want it to get logged as if someone + # typed this entire message out. + sentences = [ + (reason, DEPRECATION_MSG_PREFIX + "{}"), + (gone_in, "pip {} will remove support for this functionality."), + (replacement, "A possible replacement is {}."), + (issue, ( + "You can find discussion regarding this at " + "https://github.com/pypa/pip/issues/{}." + )), + ] + message = " ".join( + template.format(val) for val, template in sentences if val is not None + ) + + # Raise as an error if it has to be removed. + if gone_in is not None and parse(current_version) >= parse(gone_in): + raise PipDeprecationWarning(message) + + warnings.warn(message, category=PipDeprecationWarning, stacklevel=2) diff --git a/venv/Lib/site-packages/pip/_internal/utils/direct_url_helpers.py b/venv/Lib/site-packages/pip/_internal/utils/direct_url_helpers.py new file mode 100644 index 0000000..9598137 --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/utils/direct_url_helpers.py @@ -0,0 +1,121 @@ +import json +import logging + +from pip._internal.models.direct_url import ( + DIRECT_URL_METADATA_NAME, + ArchiveInfo, + DirectUrl, + DirectUrlValidationError, + DirInfo, + VcsInfo, +) +from pip._internal.utils.typing import MYPY_CHECK_RUNNING +from pip._internal.vcs import vcs + +if MYPY_CHECK_RUNNING: + from typing import Optional + + from pip._vendor.pkg_resources import Distribution + + from pip._internal.models.link import Link + +logger = logging.getLogger(__name__) + + +def direct_url_as_pep440_direct_reference(direct_url, name): + # type: (DirectUrl, str) -> str + """Convert a DirectUrl to a pip requirement string.""" + direct_url.validate() # if invalid, this is a pip bug + requirement = name + " @ " + fragments = [] + if isinstance(direct_url.info, VcsInfo): + requirement += "{}+{}@{}".format( + direct_url.info.vcs, direct_url.url, direct_url.info.commit_id + ) + elif isinstance(direct_url.info, ArchiveInfo): + requirement += direct_url.url + if direct_url.info.hash: + fragments.append(direct_url.info.hash) + else: + assert isinstance(direct_url.info, DirInfo) + requirement += direct_url.url + if direct_url.subdirectory: + fragments.append("subdirectory=" + direct_url.subdirectory) + if fragments: + requirement += "#" + "&".join(fragments) + return requirement + + +def direct_url_from_link(link, source_dir=None, link_is_in_wheel_cache=False): + # type: (Link, Optional[str], bool) -> DirectUrl + if link.is_vcs: + vcs_backend = vcs.get_backend_for_scheme(link.scheme) + assert vcs_backend + url, requested_revision, _ = ( + vcs_backend.get_url_rev_and_auth(link.url_without_fragment) + ) + # For VCS links, we need to find out and add commit_id. + if link_is_in_wheel_cache: + # If the requested VCS link corresponds to a cached + # wheel, it means the requested revision was an + # immutable commit hash, otherwise it would not have + # been cached. In that case we don't have a source_dir + # with the VCS checkout. + assert requested_revision + commit_id = requested_revision + else: + # If the wheel was not in cache, it means we have + # had to checkout from VCS to build and we have a source_dir + # which we can inspect to find out the commit id. + assert source_dir + commit_id = vcs_backend.get_revision(source_dir) + return DirectUrl( + url=url, + info=VcsInfo( + vcs=vcs_backend.name, + commit_id=commit_id, + requested_revision=requested_revision, + ), + subdirectory=link.subdirectory_fragment, + ) + elif link.is_existing_dir(): + return DirectUrl( + url=link.url_without_fragment, + info=DirInfo(), + subdirectory=link.subdirectory_fragment, + ) + else: + hash = None + hash_name = link.hash_name + if hash_name: + hash = f"{hash_name}={link.hash}" + return DirectUrl( + url=link.url_without_fragment, + info=ArchiveInfo(hash=hash), + subdirectory=link.subdirectory_fragment, + ) + + +def dist_get_direct_url(dist): + # type: (Distribution) -> Optional[DirectUrl] + """Obtain a DirectUrl from a pkg_resource.Distribution. + + Returns None if the distribution has no `direct_url.json` metadata, + or if `direct_url.json` is invalid. + """ + if not dist.has_metadata(DIRECT_URL_METADATA_NAME): + return None + try: + return DirectUrl.from_json(dist.get_metadata(DIRECT_URL_METADATA_NAME)) + except ( + DirectUrlValidationError, + json.JSONDecodeError, + UnicodeDecodeError + ) as e: + logger.warning( + "Error parsing %s for %s: %s", + DIRECT_URL_METADATA_NAME, + dist.project_name, + e, + ) + return None diff --git a/venv/Lib/site-packages/pip/_internal/utils/distutils_args.py b/venv/Lib/site-packages/pip/_internal/utils/distutils_args.py new file mode 100644 index 0000000..e38e402 --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/utils/distutils_args.py @@ -0,0 +1,48 @@ +from distutils.errors import DistutilsArgError +from distutils.fancy_getopt import FancyGetopt + +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import Dict, List + + +_options = [ + ("exec-prefix=", None, ""), + ("home=", None, ""), + ("install-base=", None, ""), + ("install-data=", None, ""), + ("install-headers=", None, ""), + ("install-lib=", None, ""), + ("install-platlib=", None, ""), + ("install-purelib=", None, ""), + ("install-scripts=", None, ""), + ("prefix=", None, ""), + ("root=", None, ""), + ("user", None, ""), +] + + +# typeshed doesn't permit Tuple[str, None, str], see python/typeshed#3469. +_distutils_getopt = FancyGetopt(_options) # type: ignore + + +def parse_distutils_args(args): + # type: (List[str]) -> Dict[str, str] + """Parse provided arguments, returning an object that has the + matched arguments. + + Any unknown arguments are ignored. + """ + result = {} + for arg in args: + try: + _, match = _distutils_getopt.getopt(args=[arg]) + except DistutilsArgError: + # We don't care about any other options, which here may be + # considered unrecognized since our option list is not + # exhaustive. + pass + else: + result.update(match.__dict__) + return result diff --git a/venv/Lib/site-packages/pip/_internal/utils/encoding.py b/venv/Lib/site-packages/pip/_internal/utils/encoding.py new file mode 100644 index 0000000..7df6798 --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/utils/encoding.py @@ -0,0 +1,41 @@ +import codecs +import locale +import re +import sys + +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import List, Tuple + +BOMS = [ + (codecs.BOM_UTF8, 'utf-8'), + (codecs.BOM_UTF16, 'utf-16'), + (codecs.BOM_UTF16_BE, 'utf-16-be'), + (codecs.BOM_UTF16_LE, 'utf-16-le'), + (codecs.BOM_UTF32, 'utf-32'), + (codecs.BOM_UTF32_BE, 'utf-32-be'), + (codecs.BOM_UTF32_LE, 'utf-32-le'), +] # type: List[Tuple[bytes, str]] + +ENCODING_RE = re.compile(br'coding[:=]\s*([-\w.]+)') + + +def auto_decode(data): + # type: (bytes) -> str + """Check a bytes string for a BOM to correctly detect the encoding + + Fallback to locale.getpreferredencoding(False) like open() on Python3""" + for bom, encoding in BOMS: + if data.startswith(bom): + return data[len(bom):].decode(encoding) + # Lets check the first two lines as in PEP263 + for line in data.split(b'\n')[:2]: + if line[0:1] == b'#' and ENCODING_RE.search(line): + result = ENCODING_RE.search(line) + assert result is not None + encoding = result.groups()[0].decode('ascii') + return data.decode(encoding) + return data.decode( + locale.getpreferredencoding(False) or sys.getdefaultencoding(), + ) diff --git a/venv/Lib/site-packages/pip/_internal/utils/entrypoints.py b/venv/Lib/site-packages/pip/_internal/utils/entrypoints.py new file mode 100644 index 0000000..64d1cb2 --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/utils/entrypoints.py @@ -0,0 +1,31 @@ +import sys + +from pip._internal.cli.main import main +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import List, Optional + + +def _wrapper(args=None): + # type: (Optional[List[str]]) -> int + """Central wrapper for all old entrypoints. + + Historically pip has had several entrypoints defined. Because of issues + arising from PATH, sys.path, multiple Pythons, their interactions, and most + of them having a pip installed, users suffer every time an entrypoint gets + moved. + + To alleviate this pain, and provide a mechanism for warning users and + directing them to an appropriate place for help, we now define all of + our old entrypoints as wrappers for the current one. + """ + sys.stderr.write( + "WARNING: pip is being invoked by an old script wrapper. This will " + "fail in a future version of pip.\n" + "Please see https://github.com/pypa/pip/issues/5599 for advice on " + "fixing the underlying issue.\n" + "To avoid this problem you can invoke Python with '-m pip' instead of " + "running pip directly.\n" + ) + return main(args) diff --git a/venv/Lib/site-packages/pip/_internal/utils/filesystem.py b/venv/Lib/site-packages/pip/_internal/utils/filesystem.py new file mode 100644 index 0000000..1af8c10 --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/utils/filesystem.py @@ -0,0 +1,200 @@ +import fnmatch +import os +import os.path +import random +import shutil +import stat +import sys +from contextlib import contextmanager +from tempfile import NamedTemporaryFile + +# NOTE: retrying is not annotated in typeshed as on 2017-07-17, which is +# why we ignore the type on this import. +from pip._vendor.retrying import retry # type: ignore + +from pip._internal.utils.compat import get_path_uid +from pip._internal.utils.misc import format_size +from pip._internal.utils.typing import MYPY_CHECK_RUNNING, cast + +if MYPY_CHECK_RUNNING: + from typing import Any, BinaryIO, Iterator, List, Union + + +def check_path_owner(path): + # type: (str) -> bool + # If we don't have a way to check the effective uid of this process, then + # we'll just assume that we own the directory. + if sys.platform == "win32" or not hasattr(os, "geteuid"): + return True + + assert os.path.isabs(path) + + previous = None + while path != previous: + if os.path.lexists(path): + # Check if path is writable by current user. + if os.geteuid() == 0: + # Special handling for root user in order to handle properly + # cases where users use sudo without -H flag. + try: + path_uid = get_path_uid(path) + except OSError: + return False + return path_uid == 0 + else: + return os.access(path, os.W_OK) + else: + previous, path = path, os.path.dirname(path) + return False # assume we don't own the path + + +def copy2_fixed(src, dest): + # type: (str, str) -> None + """Wrap shutil.copy2() but map errors copying socket files to + SpecialFileError as expected. + + See also https://bugs.python.org/issue37700. + """ + try: + shutil.copy2(src, dest) + except OSError: + for f in [src, dest]: + try: + is_socket_file = is_socket(f) + except OSError: + # An error has already occurred. Another error here is not + # a problem and we can ignore it. + pass + else: + if is_socket_file: + raise shutil.SpecialFileError( + "`{f}` is a socket".format(**locals())) + + raise + + +def is_socket(path): + # type: (str) -> bool + return stat.S_ISSOCK(os.lstat(path).st_mode) + + +@contextmanager +def adjacent_tmp_file(path, **kwargs): + # type: (str, **Any) -> Iterator[BinaryIO] + """Return a file-like object pointing to a tmp file next to path. + + The file is created securely and is ensured to be written to disk + after the context reaches its end. + + kwargs will be passed to tempfile.NamedTemporaryFile to control + the way the temporary file will be opened. + """ + with NamedTemporaryFile( + delete=False, + dir=os.path.dirname(path), + prefix=os.path.basename(path), + suffix='.tmp', + **kwargs + ) as f: + result = cast('BinaryIO', f) + try: + yield result + finally: + result.flush() + os.fsync(result.fileno()) + + +_replace_retry = retry(stop_max_delay=1000, wait_fixed=250) + +replace = _replace_retry(os.replace) + + +# test_writable_dir and _test_writable_dir_win are copied from Flit, +# with the author's agreement to also place them under pip's license. +def test_writable_dir(path): + # type: (str) -> bool + """Check if a directory is writable. + + Uses os.access() on POSIX, tries creating files on Windows. + """ + # If the directory doesn't exist, find the closest parent that does. + while not os.path.isdir(path): + parent = os.path.dirname(path) + if parent == path: + break # Should never get here, but infinite loops are bad + path = parent + + if os.name == 'posix': + return os.access(path, os.W_OK) + + return _test_writable_dir_win(path) + + +def _test_writable_dir_win(path): + # type: (str) -> bool + # os.access doesn't work on Windows: http://bugs.python.org/issue2528 + # and we can't use tempfile: http://bugs.python.org/issue22107 + basename = 'accesstest_deleteme_fishfingers_custard_' + alphabet = 'abcdefghijklmnopqrstuvwxyz0123456789' + for _ in range(10): + name = basename + ''.join(random.choice(alphabet) for _ in range(6)) + file = os.path.join(path, name) + try: + fd = os.open(file, os.O_RDWR | os.O_CREAT | os.O_EXCL) + except FileExistsError: + pass + except PermissionError: + # This could be because there's a directory with the same name. + # But it's highly unlikely there's a directory called that, + # so we'll assume it's because the parent dir is not writable. + # This could as well be because the parent dir is not readable, + # due to non-privileged user access. + return False + else: + os.close(fd) + os.unlink(file) + return True + + # This should never be reached + raise OSError( + 'Unexpected condition testing for writable directory' + ) + + +def find_files(path, pattern): + # type: (str, str) -> List[str] + """Returns a list of absolute paths of files beneath path, recursively, + with filenames which match the UNIX-style shell glob pattern.""" + result = [] # type: List[str] + for root, _, files in os.walk(path): + matches = fnmatch.filter(files, pattern) + result.extend(os.path.join(root, f) for f in matches) + return result + + +def file_size(path): + # type: (str) -> Union[int, float] + # If it's a symlink, return 0. + if os.path.islink(path): + return 0 + return os.path.getsize(path) + + +def format_file_size(path): + # type: (str) -> str + return format_size(file_size(path)) + + +def directory_size(path): + # type: (str) -> Union[int, float] + size = 0.0 + for root, _dirs, files in os.walk(path): + for filename in files: + file_path = os.path.join(root, filename) + size += file_size(file_path) + return size + + +def format_directory_size(path): + # type: (str) -> str + return format_size(directory_size(path)) diff --git a/venv/Lib/site-packages/pip/_internal/utils/filetypes.py b/venv/Lib/site-packages/pip/_internal/utils/filetypes.py new file mode 100644 index 0000000..201c6eb --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/utils/filetypes.py @@ -0,0 +1,26 @@ +"""Filetype information. +""" +from pip._internal.utils.misc import splitext +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import Tuple + +WHEEL_EXTENSION = '.whl' +BZ2_EXTENSIONS = ('.tar.bz2', '.tbz') # type: Tuple[str, ...] +XZ_EXTENSIONS = ('.tar.xz', '.txz', '.tlz', + '.tar.lz', '.tar.lzma') # type: Tuple[str, ...] +ZIP_EXTENSIONS = ('.zip', WHEEL_EXTENSION) # type: Tuple[str, ...] +TAR_EXTENSIONS = ('.tar.gz', '.tgz', '.tar') # type: Tuple[str, ...] +ARCHIVE_EXTENSIONS = ( + ZIP_EXTENSIONS + BZ2_EXTENSIONS + TAR_EXTENSIONS + XZ_EXTENSIONS +) + + +def is_archive_file(name): + # type: (str) -> bool + """Return True if `name` is a considered as an archive file.""" + ext = splitext(name)[1].lower() + if ext in ARCHIVE_EXTENSIONS: + return True + return False diff --git a/venv/Lib/site-packages/pip/_internal/utils/glibc.py b/venv/Lib/site-packages/pip/_internal/utils/glibc.py new file mode 100644 index 0000000..819979d --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/utils/glibc.py @@ -0,0 +1,96 @@ +# The following comment should be removed at some point in the future. +# mypy: strict-optional=False + +import os +import sys + +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import Optional, Tuple + + +def glibc_version_string(): + # type: () -> Optional[str] + "Returns glibc version string, or None if not using glibc." + return glibc_version_string_confstr() or glibc_version_string_ctypes() + + +def glibc_version_string_confstr(): + # type: () -> Optional[str] + "Primary implementation of glibc_version_string using os.confstr." + # os.confstr is quite a bit faster than ctypes.DLL. It's also less likely + # to be broken or missing. This strategy is used in the standard library + # platform module: + # https://github.com/python/cpython/blob/fcf1d003bf4f0100c9d0921ff3d70e1127ca1b71/Lib/platform.py#L175-L183 + if sys.platform == "win32": + return None + try: + # os.confstr("CS_GNU_LIBC_VERSION") returns a string like "glibc 2.17": + _, version = os.confstr("CS_GNU_LIBC_VERSION").split() + except (AttributeError, OSError, ValueError): + # os.confstr() or CS_GNU_LIBC_VERSION not available (or a bad value)... + return None + return version + + +def glibc_version_string_ctypes(): + # type: () -> Optional[str] + "Fallback implementation of glibc_version_string using ctypes." + + try: + import ctypes + except ImportError: + return None + + # ctypes.CDLL(None) internally calls dlopen(NULL), and as the dlopen + # manpage says, "If filename is NULL, then the returned handle is for the + # main program". This way we can let the linker do the work to figure out + # which libc our process is actually using. + process_namespace = ctypes.CDLL(None) + try: + gnu_get_libc_version = process_namespace.gnu_get_libc_version + except AttributeError: + # Symbol doesn't exist -> therefore, we are not linked to + # glibc. + return None + + # Call gnu_get_libc_version, which returns a string like "2.5" + gnu_get_libc_version.restype = ctypes.c_char_p + version_str = gnu_get_libc_version() + # py2 / py3 compatibility: + if not isinstance(version_str, str): + version_str = version_str.decode("ascii") + + return version_str + + +# platform.libc_ver regularly returns completely nonsensical glibc +# versions. E.g. on my computer, platform says: +# +# ~$ python2.7 -c 'import platform; print(platform.libc_ver())' +# ('glibc', '2.7') +# ~$ python3.5 -c 'import platform; print(platform.libc_ver())' +# ('glibc', '2.9') +# +# But the truth is: +# +# ~$ ldd --version +# ldd (Debian GLIBC 2.22-11) 2.22 +# +# This is unfortunate, because it means that the linehaul data on libc +# versions that was generated by pip 8.1.2 and earlier is useless and +# misleading. Solution: instead of using platform, use our code that actually +# works. +def libc_ver(): + # type: () -> Tuple[str, str] + """Try to determine the glibc version + + Returns a tuple of strings (lib, version) which default to empty strings + in case the lookup fails. + """ + glibc_version = glibc_version_string() + if glibc_version is None: + return ("", "") + else: + return ("glibc", glibc_version) diff --git a/venv/Lib/site-packages/pip/_internal/utils/hashes.py b/venv/Lib/site-packages/pip/_internal/utils/hashes.py new file mode 100644 index 0000000..d5ff900 --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/utils/hashes.py @@ -0,0 +1,160 @@ +import hashlib + +from pip._internal.exceptions import HashMismatch, HashMissing, InstallationError +from pip._internal.utils.misc import read_chunks +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from hashlib import _Hash + from typing import BinaryIO, Dict, Iterator, List, NoReturn + + +# The recommended hash algo of the moment. Change this whenever the state of +# the art changes; it won't hurt backward compatibility. +FAVORITE_HASH = 'sha256' + + +# Names of hashlib algorithms allowed by the --hash option and ``pip hash`` +# Currently, those are the ones at least as collision-resistant as sha256. +STRONG_HASHES = ['sha256', 'sha384', 'sha512'] + + +class Hashes: + """A wrapper that builds multiple hashes at once and checks them against + known-good values + + """ + def __init__(self, hashes=None): + # type: (Dict[str, List[str]]) -> None + """ + :param hashes: A dict of algorithm names pointing to lists of allowed + hex digests + """ + allowed = {} + if hashes is not None: + for alg, keys in hashes.items(): + # Make sure values are always sorted (to ease equality checks) + allowed[alg] = sorted(keys) + self._allowed = allowed + + def __and__(self, other): + # type: (Hashes) -> Hashes + if not isinstance(other, Hashes): + return NotImplemented + + # If either of the Hashes object is entirely empty (i.e. no hash + # specified at all), all hashes from the other object are allowed. + if not other: + return self + if not self: + return other + + # Otherwise only hashes that present in both objects are allowed. + new = {} + for alg, values in other._allowed.items(): + if alg not in self._allowed: + continue + new[alg] = [v for v in values if v in self._allowed[alg]] + return Hashes(new) + + @property + def digest_count(self): + # type: () -> int + return sum(len(digests) for digests in self._allowed.values()) + + def is_hash_allowed( + self, + hash_name, # type: str + hex_digest, # type: str + ): + # type: (...) -> bool + """Return whether the given hex digest is allowed.""" + return hex_digest in self._allowed.get(hash_name, []) + + def check_against_chunks(self, chunks): + # type: (Iterator[bytes]) -> None + """Check good hashes against ones built from iterable of chunks of + data. + + Raise HashMismatch if none match. + + """ + gots = {} + for hash_name in self._allowed.keys(): + try: + gots[hash_name] = hashlib.new(hash_name) + except (ValueError, TypeError): + raise InstallationError( + f'Unknown hash name: {hash_name}' + ) + + for chunk in chunks: + for hash in gots.values(): + hash.update(chunk) + + for hash_name, got in gots.items(): + if got.hexdigest() in self._allowed[hash_name]: + return + self._raise(gots) + + def _raise(self, gots): + # type: (Dict[str, _Hash]) -> NoReturn + raise HashMismatch(self._allowed, gots) + + def check_against_file(self, file): + # type: (BinaryIO) -> None + """Check good hashes against a file-like object + + Raise HashMismatch if none match. + + """ + return self.check_against_chunks(read_chunks(file)) + + def check_against_path(self, path): + # type: (str) -> None + with open(path, 'rb') as file: + return self.check_against_file(file) + + def __nonzero__(self): + # type: () -> bool + """Return whether I know any known-good hashes.""" + return bool(self._allowed) + + def __bool__(self): + # type: () -> bool + return self.__nonzero__() + + def __eq__(self, other): + # type: (object) -> bool + if not isinstance(other, Hashes): + return NotImplemented + return self._allowed == other._allowed + + def __hash__(self): + # type: () -> int + return hash( + ",".join(sorted( + ":".join((alg, digest)) + for alg, digest_list in self._allowed.items() + for digest in digest_list + )) + ) + + +class MissingHashes(Hashes): + """A workalike for Hashes used when we're missing a hash for a requirement + + It computes the actual hash of the requirement and raises a HashMissing + exception showing it to the user. + + """ + def __init__(self): + # type: () -> None + """Don't offer the ``hashes`` kwarg.""" + # Pass our favorite hash in to generate a "gotten hash". With the + # empty list, it will never match, so an error will always raise. + super().__init__(hashes={FAVORITE_HASH: []}) + + def _raise(self, gots): + # type: (Dict[str, _Hash]) -> NoReturn + raise HashMissing(gots[FAVORITE_HASH].hexdigest()) diff --git a/venv/Lib/site-packages/pip/_internal/utils/inject_securetransport.py b/venv/Lib/site-packages/pip/_internal/utils/inject_securetransport.py new file mode 100644 index 0000000..5b93b1d --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/utils/inject_securetransport.py @@ -0,0 +1,36 @@ +"""A helper module that injects SecureTransport, on import. + +The import should be done as early as possible, to ensure all requests and +sessions (or whatever) are created after injecting SecureTransport. + +Note that we only do the injection on macOS, when the linked OpenSSL is too +old to handle TLSv1.2. +""" + +import sys + + +def inject_securetransport(): + # type: () -> None + # Only relevant on macOS + if sys.platform != "darwin": + return + + try: + import ssl + except ImportError: + return + + # Checks for OpenSSL 1.0.1 + if ssl.OPENSSL_VERSION_NUMBER >= 0x1000100f: + return + + try: + from pip._vendor.urllib3.contrib import securetransport + except (ImportError, OSError): + return + + securetransport.inject_into_urllib3() + + +inject_securetransport() diff --git a/venv/Lib/site-packages/pip/_internal/utils/logging.py b/venv/Lib/site-packages/pip/_internal/utils/logging.py new file mode 100644 index 0000000..87b91d2 --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/utils/logging.py @@ -0,0 +1,362 @@ +# The following comment should be removed at some point in the future. +# mypy: disallow-untyped-defs=False + +import contextlib +import errno +import logging +import logging.handlers +import os +import sys +from logging import Filter, getLogger + +from pip._internal.utils.compat import WINDOWS +from pip._internal.utils.deprecation import DEPRECATION_MSG_PREFIX +from pip._internal.utils.misc import ensure_dir + +try: + import threading +except ImportError: + import dummy_threading as threading # type: ignore + + +try: + from pip._vendor import colorama +# Lots of different errors can come from this, including SystemError and +# ImportError. +except Exception: + colorama = None + + +_log_state = threading.local() +subprocess_logger = getLogger('pip.subprocessor') + + +class BrokenStdoutLoggingError(Exception): + """ + Raised if BrokenPipeError occurs for the stdout stream while logging. + """ + pass + + +# BrokenPipeError manifests differently in Windows and non-Windows. +if WINDOWS: + # In Windows, a broken pipe can show up as EINVAL rather than EPIPE: + # https://bugs.python.org/issue19612 + # https://bugs.python.org/issue30418 + def _is_broken_pipe_error(exc_class, exc): + """See the docstring for non-Windows below.""" + return ((exc_class is BrokenPipeError) or + (exc_class is OSError and + exc.errno in (errno.EINVAL, errno.EPIPE))) +else: + # Then we are in the non-Windows case. + def _is_broken_pipe_error(exc_class, exc): + """ + Return whether an exception is a broken pipe error. + + Args: + exc_class: an exception class. + exc: an exception instance. + """ + return (exc_class is BrokenPipeError) + + +@contextlib.contextmanager +def indent_log(num=2): + """ + A context manager which will cause the log output to be indented for any + log messages emitted inside it. + """ + # For thread-safety + _log_state.indentation = get_indentation() + _log_state.indentation += num + try: + yield + finally: + _log_state.indentation -= num + + +def get_indentation(): + return getattr(_log_state, 'indentation', 0) + + +class IndentingFormatter(logging.Formatter): + default_time_format = "%Y-%m-%dT%H:%M:%S" + + def __init__(self, *args, **kwargs): + """ + A logging.Formatter that obeys the indent_log() context manager. + + :param add_timestamp: A bool indicating output lines should be prefixed + with their record's timestamp. + """ + self.add_timestamp = kwargs.pop("add_timestamp", False) + super().__init__(*args, **kwargs) + + def get_message_start(self, formatted, levelno): + """ + Return the start of the formatted log message (not counting the + prefix to add to each line). + """ + if levelno < logging.WARNING: + return '' + if formatted.startswith(DEPRECATION_MSG_PREFIX): + # Then the message already has a prefix. We don't want it to + # look like "WARNING: DEPRECATION: ...." + return '' + if levelno < logging.ERROR: + return 'WARNING: ' + + return 'ERROR: ' + + def format(self, record): + """ + Calls the standard formatter, but will indent all of the log message + lines by our current indentation level. + """ + formatted = super().format(record) + message_start = self.get_message_start(formatted, record.levelno) + formatted = message_start + formatted + + prefix = '' + if self.add_timestamp: + prefix = f"{self.formatTime(record)} " + prefix += " " * get_indentation() + formatted = "".join([ + prefix + line + for line in formatted.splitlines(True) + ]) + return formatted + + +def _color_wrap(*colors): + def wrapped(inp): + return "".join(list(colors) + [inp, colorama.Style.RESET_ALL]) + return wrapped + + +class ColorizedStreamHandler(logging.StreamHandler): + + # Don't build up a list of colors if we don't have colorama + if colorama: + COLORS = [ + # This needs to be in order from highest logging level to lowest. + (logging.ERROR, _color_wrap(colorama.Fore.RED)), + (logging.WARNING, _color_wrap(colorama.Fore.YELLOW)), + ] + else: + COLORS = [] + + def __init__(self, stream=None, no_color=None): + super().__init__(stream) + self._no_color = no_color + + if WINDOWS and colorama: + self.stream = colorama.AnsiToWin32(self.stream) + + def _using_stdout(self): + """ + Return whether the handler is using sys.stdout. + """ + if WINDOWS and colorama: + # Then self.stream is an AnsiToWin32 object. + return self.stream.wrapped is sys.stdout + + return self.stream is sys.stdout + + def should_color(self): + # Don't colorize things if we do not have colorama or if told not to + if not colorama or self._no_color: + return False + + real_stream = ( + self.stream if not isinstance(self.stream, colorama.AnsiToWin32) + else self.stream.wrapped + ) + + # If the stream is a tty we should color it + if hasattr(real_stream, "isatty") and real_stream.isatty(): + return True + + # If we have an ANSI term we should color it + if os.environ.get("TERM") == "ANSI": + return True + + # If anything else we should not color it + return False + + def format(self, record): + msg = logging.StreamHandler.format(self, record) + + if self.should_color(): + for level, color in self.COLORS: + if record.levelno >= level: + msg = color(msg) + break + + return msg + + # The logging module says handleError() can be customized. + def handleError(self, record): + exc_class, exc = sys.exc_info()[:2] + # If a broken pipe occurred while calling write() or flush() on the + # stdout stream in logging's Handler.emit(), then raise our special + # exception so we can handle it in main() instead of logging the + # broken pipe error and continuing. + if (exc_class and self._using_stdout() and + _is_broken_pipe_error(exc_class, exc)): + raise BrokenStdoutLoggingError() + + return super().handleError(record) + + +class BetterRotatingFileHandler(logging.handlers.RotatingFileHandler): + + def _open(self): + ensure_dir(os.path.dirname(self.baseFilename)) + return logging.handlers.RotatingFileHandler._open(self) + + +class MaxLevelFilter(Filter): + + def __init__(self, level): + self.level = level + + def filter(self, record): + return record.levelno < self.level + + +class ExcludeLoggerFilter(Filter): + + """ + A logging Filter that excludes records from a logger (or its children). + """ + + def filter(self, record): + # The base Filter class allows only records from a logger (or its + # children). + return not super().filter(record) + + +def setup_logging(verbosity, no_color, user_log_file): + """Configures and sets up all of the logging + + Returns the requested logging level, as its integer value. + """ + + # Determine the level to be logging at. + if verbosity >= 1: + level = "DEBUG" + elif verbosity == -1: + level = "WARNING" + elif verbosity == -2: + level = "ERROR" + elif verbosity <= -3: + level = "CRITICAL" + else: + level = "INFO" + + level_number = getattr(logging, level) + + # The "root" logger should match the "console" level *unless* we also need + # to log to a user log file. + include_user_log = user_log_file is not None + if include_user_log: + additional_log_file = user_log_file + root_level = "DEBUG" + else: + additional_log_file = "/dev/null" + root_level = level + + # Disable any logging besides WARNING unless we have DEBUG level logging + # enabled for vendored libraries. + vendored_log_level = "WARNING" if level in ["INFO", "ERROR"] else "DEBUG" + + # Shorthands for clarity + log_streams = { + "stdout": "ext://sys.stdout", + "stderr": "ext://sys.stderr", + } + handler_classes = { + "stream": "pip._internal.utils.logging.ColorizedStreamHandler", + "file": "pip._internal.utils.logging.BetterRotatingFileHandler", + } + handlers = ["console", "console_errors", "console_subprocess"] + ( + ["user_log"] if include_user_log else [] + ) + + logging.config.dictConfig({ + "version": 1, + "disable_existing_loggers": False, + "filters": { + "exclude_warnings": { + "()": "pip._internal.utils.logging.MaxLevelFilter", + "level": logging.WARNING, + }, + "restrict_to_subprocess": { + "()": "logging.Filter", + "name": subprocess_logger.name, + }, + "exclude_subprocess": { + "()": "pip._internal.utils.logging.ExcludeLoggerFilter", + "name": subprocess_logger.name, + }, + }, + "formatters": { + "indent": { + "()": IndentingFormatter, + "format": "%(message)s", + }, + "indent_with_timestamp": { + "()": IndentingFormatter, + "format": "%(message)s", + "add_timestamp": True, + }, + }, + "handlers": { + "console": { + "level": level, + "class": handler_classes["stream"], + "no_color": no_color, + "stream": log_streams["stdout"], + "filters": ["exclude_subprocess", "exclude_warnings"], + "formatter": "indent", + }, + "console_errors": { + "level": "WARNING", + "class": handler_classes["stream"], + "no_color": no_color, + "stream": log_streams["stderr"], + "filters": ["exclude_subprocess"], + "formatter": "indent", + }, + # A handler responsible for logging to the console messages + # from the "subprocessor" logger. + "console_subprocess": { + "level": level, + "class": handler_classes["stream"], + "no_color": no_color, + "stream": log_streams["stderr"], + "filters": ["restrict_to_subprocess"], + "formatter": "indent", + }, + "user_log": { + "level": "DEBUG", + "class": handler_classes["file"], + "filename": additional_log_file, + "delay": True, + "formatter": "indent_with_timestamp", + }, + }, + "root": { + "level": root_level, + "handlers": handlers, + }, + "loggers": { + "pip._vendor": { + "level": vendored_log_level + } + }, + }) + + return level_number diff --git a/venv/Lib/site-packages/pip/_internal/utils/misc.py b/venv/Lib/site-packages/pip/_internal/utils/misc.py new file mode 100644 index 0000000..6dd94e2 --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/utils/misc.py @@ -0,0 +1,927 @@ +# The following comment should be removed at some point in the future. +# mypy: strict-optional=False +# mypy: disallow-untyped-defs=False + +import contextlib +import errno +import getpass +import hashlib +import io +import logging +import os +import posixpath +import shutil +import stat +import sys +import urllib.parse +from io import StringIO +from itertools import filterfalse, tee, zip_longest + +from pip._vendor import pkg_resources +from pip._vendor.packaging.utils import canonicalize_name + +# NOTE: retrying is not annotated in typeshed as on 2017-07-17, which is +# why we ignore the type on this import. +from pip._vendor.retrying import retry # type: ignore + +from pip import __version__ +from pip._internal.exceptions import CommandError +from pip._internal.locations import get_major_minor_version, site_packages, user_site +from pip._internal.utils.compat import WINDOWS, stdlib_pkgs +from pip._internal.utils.typing import MYPY_CHECK_RUNNING, cast +from pip._internal.utils.virtualenv import ( + running_under_virtualenv, + virtualenv_no_global, +) + +if MYPY_CHECK_RUNNING: + from typing import ( + Any, + AnyStr, + Callable, + Container, + Iterable, + Iterator, + List, + Optional, + Tuple, + TypeVar, + ) + + from pip._vendor.pkg_resources import Distribution + + VersionInfo = Tuple[int, int, int] + T = TypeVar("T") + + +__all__ = ['rmtree', 'display_path', 'backup_dir', + 'ask', 'splitext', + 'format_size', 'is_installable_dir', + 'normalize_path', + 'renames', 'get_prog', + 'captured_stdout', 'ensure_dir', + 'get_installed_version', 'remove_auth_from_url'] + + +logger = logging.getLogger(__name__) + + +def get_pip_version(): + # type: () -> str + pip_pkg_dir = os.path.join(os.path.dirname(__file__), "..", "..") + pip_pkg_dir = os.path.abspath(pip_pkg_dir) + + return ( + 'pip {} from {} (python {})'.format( + __version__, pip_pkg_dir, get_major_minor_version(), + ) + ) + + +def normalize_version_info(py_version_info): + # type: (Tuple[int, ...]) -> Tuple[int, int, int] + """ + Convert a tuple of ints representing a Python version to one of length + three. + + :param py_version_info: a tuple of ints representing a Python version, + or None to specify no version. The tuple can have any length. + + :return: a tuple of length three if `py_version_info` is non-None. + Otherwise, return `py_version_info` unchanged (i.e. None). + """ + if len(py_version_info) < 3: + py_version_info += (3 - len(py_version_info)) * (0,) + elif len(py_version_info) > 3: + py_version_info = py_version_info[:3] + + return cast('VersionInfo', py_version_info) + + +def ensure_dir(path): + # type: (AnyStr) -> None + """os.path.makedirs without EEXIST.""" + try: + os.makedirs(path) + except OSError as e: + # Windows can raise spurious ENOTEMPTY errors. See #6426. + if e.errno != errno.EEXIST and e.errno != errno.ENOTEMPTY: + raise + + +def get_prog(): + # type: () -> str + try: + prog = os.path.basename(sys.argv[0]) + if prog in ('__main__.py', '-c'): + return f"{sys.executable} -m pip" + else: + return prog + except (AttributeError, TypeError, IndexError): + pass + return 'pip' + + +# Retry every half second for up to 3 seconds +@retry(stop_max_delay=3000, wait_fixed=500) +def rmtree(dir, ignore_errors=False): + # type: (AnyStr, bool) -> None + shutil.rmtree(dir, ignore_errors=ignore_errors, + onerror=rmtree_errorhandler) + + +def rmtree_errorhandler(func, path, exc_info): + """On Windows, the files in .svn are read-only, so when rmtree() tries to + remove them, an exception is thrown. We catch that here, remove the + read-only attribute, and hopefully continue without problems.""" + try: + has_attr_readonly = not (os.stat(path).st_mode & stat.S_IWRITE) + except OSError: + # it's equivalent to os.path.exists + return + + if has_attr_readonly: + # convert to read/write + os.chmod(path, stat.S_IWRITE) + # use the original function to repeat the operation + func(path) + return + else: + raise + + +def path_to_display(path): + # type: (Optional[str]) -> Optional[str] + """ + Convert a bytes (or text) path to text (unicode in Python 2) for display + and logging purposes. + + This function should never error out. Also, this function is mainly needed + for Python 2 since in Python 3 str paths are already text. + """ + if path is None: + return None + if isinstance(path, str): + return path + # Otherwise, path is a bytes object (str in Python 2). + try: + display_path = path.decode(sys.getfilesystemencoding(), 'strict') + except UnicodeDecodeError: + # Include the full bytes to make troubleshooting easier, even though + # it may not be very human readable. + display_path = ascii(path) + + return display_path + + +def display_path(path): + # type: (str) -> str + """Gives the display value for a given path, making it relative to cwd + if possible.""" + path = os.path.normcase(os.path.abspath(path)) + if path.startswith(os.getcwd() + os.path.sep): + path = '.' + path[len(os.getcwd()):] + return path + + +def backup_dir(dir, ext='.bak'): + # type: (str, str) -> str + """Figure out the name of a directory to back up the given dir to + (adding .bak, .bak2, etc)""" + n = 1 + extension = ext + while os.path.exists(dir + extension): + n += 1 + extension = ext + str(n) + return dir + extension + + +def ask_path_exists(message, options): + # type: (str, Iterable[str]) -> str + for action in os.environ.get('PIP_EXISTS_ACTION', '').split(): + if action in options: + return action + return ask(message, options) + + +def _check_no_input(message): + # type: (str) -> None + """Raise an error if no input is allowed.""" + if os.environ.get('PIP_NO_INPUT'): + raise Exception( + 'No input was expected ($PIP_NO_INPUT set); question: {}'.format( + message) + ) + + +def ask(message, options): + # type: (str, Iterable[str]) -> str + """Ask the message interactively, with the given possible responses""" + while 1: + _check_no_input(message) + response = input(message) + response = response.strip().lower() + if response not in options: + print( + 'Your response ({!r}) was not one of the expected responses: ' + '{}'.format(response, ', '.join(options)) + ) + else: + return response + + +def ask_input(message): + # type: (str) -> str + """Ask for input interactively.""" + _check_no_input(message) + return input(message) + + +def ask_password(message): + # type: (str) -> str + """Ask for a password interactively.""" + _check_no_input(message) + return getpass.getpass(message) + + +def strtobool(val): + # type: (str) -> int + """Convert a string representation of truth to true (1) or false (0). + + True values are 'y', 'yes', 't', 'true', 'on', and '1'; false values + are 'n', 'no', 'f', 'false', 'off', and '0'. Raises ValueError if + 'val' is anything else. + """ + val = val.lower() + if val in ('y', 'yes', 't', 'true', 'on', '1'): + return 1 + elif val in ('n', 'no', 'f', 'false', 'off', '0'): + return 0 + else: + raise ValueError("invalid truth value %r" % (val,)) + + +def format_size(bytes): + # type: (float) -> str + if bytes > 1000 * 1000: + return '{:.1f} MB'.format(bytes / 1000.0 / 1000) + elif bytes > 10 * 1000: + return '{} kB'.format(int(bytes / 1000)) + elif bytes > 1000: + return '{:.1f} kB'.format(bytes / 1000.0) + else: + return '{} bytes'.format(int(bytes)) + + +def tabulate(rows): + # type: (Iterable[Iterable[Any]]) -> Tuple[List[str], List[int]] + """Return a list of formatted rows and a list of column sizes. + + For example:: + + >>> tabulate([['foobar', 2000], [0xdeadbeef]]) + (['foobar 2000', '3735928559'], [10, 4]) + """ + rows = [tuple(map(str, row)) for row in rows] + sizes = [max(map(len, col)) for col in zip_longest(*rows, fillvalue='')] + table = [" ".join(map(str.ljust, row, sizes)).rstrip() for row in rows] + return table, sizes + + +def is_installable_dir(path): + # type: (str) -> bool + """Is path is a directory containing setup.py or pyproject.toml? + """ + if not os.path.isdir(path): + return False + setup_py = os.path.join(path, 'setup.py') + if os.path.isfile(setup_py): + return True + pyproject_toml = os.path.join(path, 'pyproject.toml') + if os.path.isfile(pyproject_toml): + return True + return False + + +def read_chunks(file, size=io.DEFAULT_BUFFER_SIZE): + """Yield pieces of data from a file-like object until EOF.""" + while True: + chunk = file.read(size) + if not chunk: + break + yield chunk + + +def normalize_path(path, resolve_symlinks=True): + # type: (str, bool) -> str + """ + Convert a path to its canonical, case-normalized, absolute version. + + """ + path = os.path.expanduser(path) + if resolve_symlinks: + path = os.path.realpath(path) + else: + path = os.path.abspath(path) + return os.path.normcase(path) + + +def splitext(path): + # type: (str) -> Tuple[str, str] + """Like os.path.splitext, but take off .tar too""" + base, ext = posixpath.splitext(path) + if base.lower().endswith('.tar'): + ext = base[-4:] + ext + base = base[:-4] + return base, ext + + +def renames(old, new): + # type: (str, str) -> None + """Like os.renames(), but handles renaming across devices.""" + # Implementation borrowed from os.renames(). + head, tail = os.path.split(new) + if head and tail and not os.path.exists(head): + os.makedirs(head) + + shutil.move(old, new) + + head, tail = os.path.split(old) + if head and tail: + try: + os.removedirs(head) + except OSError: + pass + + +def is_local(path): + # type: (str) -> bool + """ + Return True if path is within sys.prefix, if we're running in a virtualenv. + + If we're not in a virtualenv, all paths are considered "local." + + Caution: this function assumes the head of path has been normalized + with normalize_path. + """ + if not running_under_virtualenv(): + return True + return path.startswith(normalize_path(sys.prefix)) + + +def dist_is_local(dist): + # type: (Distribution) -> bool + """ + Return True if given Distribution object is installed locally + (i.e. within current virtualenv). + + Always True if we're not in a virtualenv. + + """ + return is_local(dist_location(dist)) + + +def dist_in_usersite(dist): + # type: (Distribution) -> bool + """ + Return True if given Distribution is installed in user site. + """ + return dist_location(dist).startswith(normalize_path(user_site)) + + +def dist_in_site_packages(dist): + # type: (Distribution) -> bool + """ + Return True if given Distribution is installed in + sysconfig.get_python_lib(). + """ + return dist_location(dist).startswith(normalize_path(site_packages)) + + +def dist_is_editable(dist): + # type: (Distribution) -> bool + """ + Return True if given Distribution is an editable install. + """ + for path_item in sys.path: + egg_link = os.path.join(path_item, dist.project_name + '.egg-link') + if os.path.isfile(egg_link): + return True + return False + + +def get_installed_distributions( + local_only=True, # type: bool + skip=stdlib_pkgs, # type: Container[str] + include_editables=True, # type: bool + editables_only=False, # type: bool + user_only=False, # type: bool + paths=None # type: Optional[List[str]] +): + # type: (...) -> List[Distribution] + """ + Return a list of installed Distribution objects. + + If ``local_only`` is True (default), only return installations + local to the current virtualenv, if in a virtualenv. + + ``skip`` argument is an iterable of lower-case project names to + ignore; defaults to stdlib_pkgs + + If ``include_editables`` is False, don't report editables. + + If ``editables_only`` is True , only report editables. + + If ``user_only`` is True , only report installations in the user + site directory. + + If ``paths`` is set, only report the distributions present at the + specified list of locations. + """ + if paths: + working_set = pkg_resources.WorkingSet(paths) + else: + working_set = pkg_resources.working_set + + if local_only: + local_test = dist_is_local + else: + def local_test(d): + return True + + if include_editables: + def editable_test(d): + return True + else: + def editable_test(d): + return not dist_is_editable(d) + + if editables_only: + def editables_only_test(d): + return dist_is_editable(d) + else: + def editables_only_test(d): + return True + + if user_only: + user_test = dist_in_usersite + else: + def user_test(d): + return True + + return [d for d in working_set + if local_test(d) and + d.key not in skip and + editable_test(d) and + editables_only_test(d) and + user_test(d) + ] + + +def _search_distribution(req_name): + # type: (str) -> Optional[Distribution] + """Find a distribution matching the ``req_name`` in the environment. + + This searches from *all* distributions available in the environment, to + match the behavior of ``pkg_resources.get_distribution()``. + """ + # Canonicalize the name before searching in the list of + # installed distributions and also while creating the package + # dictionary to get the Distribution object + req_name = canonicalize_name(req_name) + packages = get_installed_distributions( + local_only=False, + skip=(), + include_editables=True, + editables_only=False, + user_only=False, + paths=None, + ) + pkg_dict = {canonicalize_name(p.key): p for p in packages} + return pkg_dict.get(req_name) + + +def get_distribution(req_name): + # type: (str) -> Optional[Distribution] + """Given a requirement name, return the installed Distribution object. + + This searches from *all* distributions available in the environment, to + match the behavior of ``pkg_resources.get_distribution()``. + """ + + # Search the distribution by looking through the working set + dist = _search_distribution(req_name) + + # If distribution could not be found, call working_set.require + # to update the working set, and try to find the distribution + # again. + # This might happen for e.g. when you install a package + # twice, once using setup.py develop and again using setup.py install. + # Now when run pip uninstall twice, the package gets removed + # from the working set in the first uninstall, so we have to populate + # the working set again so that pip knows about it and the packages + # gets picked up and is successfully uninstalled the second time too. + if not dist: + try: + pkg_resources.working_set.require(req_name) + except pkg_resources.DistributionNotFound: + return None + return _search_distribution(req_name) + + +def egg_link_path(dist): + # type: (Distribution) -> Optional[str] + """ + Return the path for the .egg-link file if it exists, otherwise, None. + + There's 3 scenarios: + 1) not in a virtualenv + try to find in site.USER_SITE, then site_packages + 2) in a no-global virtualenv + try to find in site_packages + 3) in a yes-global virtualenv + try to find in site_packages, then site.USER_SITE + (don't look in global location) + + For #1 and #3, there could be odd cases, where there's an egg-link in 2 + locations. + + This method will just return the first one found. + """ + sites = [] + if running_under_virtualenv(): + sites.append(site_packages) + if not virtualenv_no_global() and user_site: + sites.append(user_site) + else: + if user_site: + sites.append(user_site) + sites.append(site_packages) + + for site in sites: + egglink = os.path.join(site, dist.project_name) + '.egg-link' + if os.path.isfile(egglink): + return egglink + return None + + +def dist_location(dist): + # type: (Distribution) -> str + """ + Get the site-packages location of this distribution. Generally + this is dist.location, except in the case of develop-installed + packages, where dist.location is the source code location, and we + want to know where the egg-link file is. + + The returned location is normalized (in particular, with symlinks removed). + """ + egg_link = egg_link_path(dist) + if egg_link: + return normalize_path(egg_link) + return normalize_path(dist.location) + + +def write_output(msg, *args): + # type: (Any, Any) -> None + logger.info(msg, *args) + + +class StreamWrapper(StringIO): + + @classmethod + def from_stream(cls, orig_stream): + cls.orig_stream = orig_stream + return cls() + + # compileall.compile_dir() needs stdout.encoding to print to stdout + @property + def encoding(self): + return self.orig_stream.encoding + + +@contextlib.contextmanager +def captured_output(stream_name): + """Return a context manager used by captured_stdout/stdin/stderr + that temporarily replaces the sys stream *stream_name* with a StringIO. + + Taken from Lib/support/__init__.py in the CPython repo. + """ + orig_stdout = getattr(sys, stream_name) + setattr(sys, stream_name, StreamWrapper.from_stream(orig_stdout)) + try: + yield getattr(sys, stream_name) + finally: + setattr(sys, stream_name, orig_stdout) + + +def captured_stdout(): + """Capture the output of sys.stdout: + + with captured_stdout() as stdout: + print('hello') + self.assertEqual(stdout.getvalue(), 'hello\n') + + Taken from Lib/support/__init__.py in the CPython repo. + """ + return captured_output('stdout') + + +def captured_stderr(): + """ + See captured_stdout(). + """ + return captured_output('stderr') + + +def get_installed_version(dist_name, working_set=None): + """Get the installed version of dist_name avoiding pkg_resources cache""" + # Create a requirement that we'll look for inside of setuptools. + req = pkg_resources.Requirement.parse(dist_name) + + if working_set is None: + # We want to avoid having this cached, so we need to construct a new + # working set each time. + working_set = pkg_resources.WorkingSet() + + # Get the installed distribution from our working set + dist = working_set.find(req) + + # Check to see if we got an installed distribution or not, if we did + # we want to return it's version. + return dist.version if dist else None + + +# Simulates an enum +def enum(*sequential, **named): + enums = dict(zip(sequential, range(len(sequential))), **named) + reverse = {value: key for key, value in enums.items()} + enums['reverse_mapping'] = reverse + return type('Enum', (), enums) + + +def build_netloc(host, port): + # type: (str, Optional[int]) -> str + """ + Build a netloc from a host-port pair + """ + if port is None: + return host + if ':' in host: + # Only wrap host with square brackets when it is IPv6 + host = f'[{host}]' + return f'{host}:{port}' + + +def build_url_from_netloc(netloc, scheme='https'): + # type: (str, str) -> str + """ + Build a full URL from a netloc. + """ + if netloc.count(':') >= 2 and '@' not in netloc and '[' not in netloc: + # It must be a bare IPv6 address, so wrap it with brackets. + netloc = f'[{netloc}]' + return f'{scheme}://{netloc}' + + +def parse_netloc(netloc): + # type: (str) -> Tuple[str, Optional[int]] + """ + Return the host-port pair from a netloc. + """ + url = build_url_from_netloc(netloc) + parsed = urllib.parse.urlparse(url) + return parsed.hostname, parsed.port + + +def split_auth_from_netloc(netloc): + """ + Parse out and remove the auth information from a netloc. + + Returns: (netloc, (username, password)). + """ + if '@' not in netloc: + return netloc, (None, None) + + # Split from the right because that's how urllib.parse.urlsplit() + # behaves if more than one @ is present (which can be checked using + # the password attribute of urlsplit()'s return value). + auth, netloc = netloc.rsplit('@', 1) + if ':' in auth: + # Split from the left because that's how urllib.parse.urlsplit() + # behaves if more than one : is present (which again can be checked + # using the password attribute of the return value) + user_pass = auth.split(':', 1) + else: + user_pass = auth, None + + user_pass = tuple( + None if x is None else urllib.parse.unquote(x) for x in user_pass + ) + + return netloc, user_pass + + +def redact_netloc(netloc): + # type: (str) -> str + """ + Replace the sensitive data in a netloc with "****", if it exists. + + For example: + - "user:pass@example.com" returns "user:****@example.com" + - "accesstoken@example.com" returns "****@example.com" + """ + netloc, (user, password) = split_auth_from_netloc(netloc) + if user is None: + return netloc + if password is None: + user = '****' + password = '' + else: + user = urllib.parse.quote(user) + password = ':****' + return '{user}{password}@{netloc}'.format(user=user, + password=password, + netloc=netloc) + + +def _transform_url(url, transform_netloc): + """Transform and replace netloc in a url. + + transform_netloc is a function taking the netloc and returning a + tuple. The first element of this tuple is the new netloc. The + entire tuple is returned. + + Returns a tuple containing the transformed url as item 0 and the + original tuple returned by transform_netloc as item 1. + """ + purl = urllib.parse.urlsplit(url) + netloc_tuple = transform_netloc(purl.netloc) + # stripped url + url_pieces = ( + purl.scheme, netloc_tuple[0], purl.path, purl.query, purl.fragment + ) + surl = urllib.parse.urlunsplit(url_pieces) + return surl, netloc_tuple + + +def _get_netloc(netloc): + return split_auth_from_netloc(netloc) + + +def _redact_netloc(netloc): + return (redact_netloc(netloc),) + + +def split_auth_netloc_from_url(url): + # type: (str) -> Tuple[str, str, Tuple[str, str]] + """ + Parse a url into separate netloc, auth, and url with no auth. + + Returns: (url_without_auth, netloc, (username, password)) + """ + url_without_auth, (netloc, auth) = _transform_url(url, _get_netloc) + return url_without_auth, netloc, auth + + +def remove_auth_from_url(url): + # type: (str) -> str + """Return a copy of url with 'username:password@' removed.""" + # username/pass params are passed to subversion through flags + # and are not recognized in the url. + return _transform_url(url, _get_netloc)[0] + + +def redact_auth_from_url(url): + # type: (str) -> str + """Replace the password in a given url with ****.""" + return _transform_url(url, _redact_netloc)[0] + + +class HiddenText: + def __init__( + self, + secret, # type: str + redacted, # type: str + ): + # type: (...) -> None + self.secret = secret + self.redacted = redacted + + def __repr__(self): + # type: (...) -> str + return ''.format(str(self)) + + def __str__(self): + # type: (...) -> str + return self.redacted + + # This is useful for testing. + def __eq__(self, other): + # type: (Any) -> bool + if type(self) != type(other): + return False + + # The string being used for redaction doesn't also have to match, + # just the raw, original string. + return (self.secret == other.secret) + + +def hide_value(value): + # type: (str) -> HiddenText + return HiddenText(value, redacted='****') + + +def hide_url(url): + # type: (str) -> HiddenText + redacted = redact_auth_from_url(url) + return HiddenText(url, redacted=redacted) + + +def protect_pip_from_modification_on_windows(modifying_pip): + # type: (bool) -> None + """Protection of pip.exe from modification on Windows + + On Windows, any operation modifying pip should be run as: + python -m pip ... + """ + pip_names = [ + "pip.exe", + "pip{}.exe".format(sys.version_info[0]), + "pip{}.{}.exe".format(*sys.version_info[:2]) + ] + + # See https://github.com/pypa/pip/issues/1299 for more discussion + should_show_use_python_msg = ( + modifying_pip and + WINDOWS and + os.path.basename(sys.argv[0]) in pip_names + ) + + if should_show_use_python_msg: + new_command = [ + sys.executable, "-m", "pip" + ] + sys.argv[1:] + raise CommandError( + 'To modify pip, please run the following command:\n{}' + .format(" ".join(new_command)) + ) + + +def is_console_interactive(): + # type: () -> bool + """Is this console interactive? + """ + return sys.stdin is not None and sys.stdin.isatty() + + +def hash_file(path, blocksize=1 << 20): + # type: (str, int) -> Tuple[Any, int] + """Return (hash, length) for path using hashlib.sha256() + """ + + h = hashlib.sha256() + length = 0 + with open(path, 'rb') as f: + for block in read_chunks(f, size=blocksize): + length += len(block) + h.update(block) + return h, length + + +def is_wheel_installed(): + """ + Return whether the wheel package is installed. + """ + try: + import wheel # noqa: F401 + except ImportError: + return False + + return True + + +def pairwise(iterable): + # type: (Iterable[Any]) -> Iterator[Tuple[Any, Any]] + """ + Return paired elements. + + For example: + s -> (s0, s1), (s2, s3), (s4, s5), ... + """ + iterable = iter(iterable) + return zip_longest(iterable, iterable) + + +def partition( + pred, # type: Callable[[T], bool] + iterable, # type: Iterable[T] +): + # type: (...) -> Tuple[Iterable[T], Iterable[T]] + """ + Use a predicate to partition entries into false entries and true entries, + like + + partition(is_odd, range(10)) --> 0 2 4 6 8 and 1 3 5 7 9 + """ + t1, t2 = tee(iterable) + return filterfalse(pred, t1), filter(pred, t2) diff --git a/venv/Lib/site-packages/pip/_internal/utils/models.py b/venv/Lib/site-packages/pip/_internal/utils/models.py new file mode 100644 index 0000000..c14e9ff --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/utils/models.py @@ -0,0 +1,41 @@ +"""Utilities for defining models +""" +# The following comment should be removed at some point in the future. +# mypy: disallow-untyped-defs=False + +import operator + + +class KeyBasedCompareMixin: + """Provides comparison capabilities that is based on a key + """ + + __slots__ = ['_compare_key', '_defining_class'] + + def __init__(self, key, defining_class): + self._compare_key = key + self._defining_class = defining_class + + def __hash__(self): + return hash(self._compare_key) + + def __lt__(self, other): + return self._compare(other, operator.__lt__) + + def __le__(self, other): + return self._compare(other, operator.__le__) + + def __gt__(self, other): + return self._compare(other, operator.__gt__) + + def __ge__(self, other): + return self._compare(other, operator.__ge__) + + def __eq__(self, other): + return self._compare(other, operator.__eq__) + + def _compare(self, other, method): + if not isinstance(other, self._defining_class): + return NotImplemented + + return method(self._compare_key, other._compare_key) diff --git a/venv/Lib/site-packages/pip/_internal/utils/packaging.py b/venv/Lib/site-packages/pip/_internal/utils/packaging.py new file mode 100644 index 0000000..fae0607 --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/utils/packaging.py @@ -0,0 +1,93 @@ +import logging +from email.parser import FeedParser + +from pip._vendor import pkg_resources +from pip._vendor.packaging import specifiers, version + +from pip._internal.exceptions import NoneMetadataError +from pip._internal.utils.misc import display_path +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from email.message import Message + from typing import Optional, Tuple + + from pip._vendor.pkg_resources import Distribution + + +logger = logging.getLogger(__name__) + + +def check_requires_python(requires_python, version_info): + # type: (Optional[str], Tuple[int, ...]) -> bool + """ + Check if the given Python version matches a "Requires-Python" specifier. + + :param version_info: A 3-tuple of ints representing a Python + major-minor-micro version to check (e.g. `sys.version_info[:3]`). + + :return: `True` if the given Python version satisfies the requirement. + Otherwise, return `False`. + + :raises InvalidSpecifier: If `requires_python` has an invalid format. + """ + if requires_python is None: + # The package provides no information + return True + requires_python_specifier = specifiers.SpecifierSet(requires_python) + + python_version = version.parse('.'.join(map(str, version_info))) + return python_version in requires_python_specifier + + +def get_metadata(dist): + # type: (Distribution) -> Message + """ + :raises NoneMetadataError: if the distribution reports `has_metadata()` + True but `get_metadata()` returns None. + """ + metadata_name = 'METADATA' + if (isinstance(dist, pkg_resources.DistInfoDistribution) and + dist.has_metadata(metadata_name)): + metadata = dist.get_metadata(metadata_name) + elif dist.has_metadata('PKG-INFO'): + metadata_name = 'PKG-INFO' + metadata = dist.get_metadata(metadata_name) + else: + logger.warning("No metadata found in %s", display_path(dist.location)) + metadata = '' + + if metadata is None: + raise NoneMetadataError(dist, metadata_name) + + feed_parser = FeedParser() + # The following line errors out if with a "NoneType" TypeError if + # passed metadata=None. + feed_parser.feed(metadata) + return feed_parser.close() + + +def get_requires_python(dist): + # type: (pkg_resources.Distribution) -> Optional[str] + """ + Return the "Requires-Python" metadata for a distribution, or None + if not present. + """ + pkg_info_dict = get_metadata(dist) + requires_python = pkg_info_dict.get('Requires-Python') + + if requires_python is not None: + # Convert to a str to satisfy the type checker, since requires_python + # can be a Header object. + requires_python = str(requires_python) + + return requires_python + + +def get_installer(dist): + # type: (Distribution) -> str + if dist.has_metadata('INSTALLER'): + for line in dist.get_metadata_lines('INSTALLER'): + if line.strip(): + return line.strip() + return '' diff --git a/venv/Lib/site-packages/pip/_internal/utils/parallel.py b/venv/Lib/site-packages/pip/_internal/utils/parallel.py new file mode 100644 index 0000000..5708236 --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/utils/parallel.py @@ -0,0 +1,105 @@ +"""Convenient parallelization of higher order functions. + +This module provides two helper functions, with appropriate fallbacks on +Python 2 and on systems lacking support for synchronization mechanisms: + +- map_multiprocess +- map_multithread + +These helpers work like Python 3's map, with two differences: + +- They don't guarantee the order of processing of + the elements of the iterable. +- The underlying process/thread pools chop the iterable into + a number of chunks, so that for very long iterables using + a large value for chunksize can make the job complete much faster + than using the default value of 1. +""" + +__all__ = ['map_multiprocess', 'map_multithread'] + +from contextlib import contextmanager +from multiprocessing import Pool as ProcessPool +from multiprocessing.dummy import Pool as ThreadPool + +from pip._vendor.requests.adapters import DEFAULT_POOLSIZE + +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from multiprocessing import pool + from typing import Callable, Iterable, Iterator, TypeVar, Union + + Pool = Union[pool.Pool, pool.ThreadPool] + S = TypeVar('S') + T = TypeVar('T') + +# On platforms without sem_open, multiprocessing[.dummy] Pool +# cannot be created. +try: + import multiprocessing.synchronize # noqa +except ImportError: + LACK_SEM_OPEN = True +else: + LACK_SEM_OPEN = False + +# Incredibly large timeout to work around bpo-8296 on Python 2. +TIMEOUT = 2000000 + + +@contextmanager +def closing(pool): + # type: (Pool) -> Iterator[Pool] + """Return a context manager making sure the pool closes properly.""" + try: + yield pool + finally: + # For Pool.imap*, close and join are needed + # for the returned iterator to begin yielding. + pool.close() + pool.join() + pool.terminate() + + +def _map_fallback(func, iterable, chunksize=1): + # type: (Callable[[S], T], Iterable[S], int) -> Iterator[T] + """Make an iterator applying func to each element in iterable. + + This function is the sequential fallback either on Python 2 + where Pool.imap* doesn't react to KeyboardInterrupt + or when sem_open is unavailable. + """ + return map(func, iterable) + + +def _map_multiprocess(func, iterable, chunksize=1): + # type: (Callable[[S], T], Iterable[S], int) -> Iterator[T] + """Chop iterable into chunks and submit them to a process pool. + + For very long iterables using a large value for chunksize can make + the job complete much faster than using the default value of 1. + + Return an unordered iterator of the results. + """ + with closing(ProcessPool()) as pool: + return pool.imap_unordered(func, iterable, chunksize) + + +def _map_multithread(func, iterable, chunksize=1): + # type: (Callable[[S], T], Iterable[S], int) -> Iterator[T] + """Chop iterable into chunks and submit them to a thread pool. + + For very long iterables using a large value for chunksize can make + the job complete much faster than using the default value of 1. + + Return an unordered iterator of the results. + """ + with closing(ThreadPool(DEFAULT_POOLSIZE)) as pool: + return pool.imap_unordered(func, iterable, chunksize) + + +if LACK_SEM_OPEN: + map_multiprocess = map_multithread = _map_fallback +else: + map_multiprocess = _map_multiprocess + map_multithread = _map_multithread diff --git a/venv/Lib/site-packages/pip/_internal/utils/pkg_resources.py b/venv/Lib/site-packages/pip/_internal/utils/pkg_resources.py new file mode 100644 index 0000000..d5b26f5 --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/utils/pkg_resources.py @@ -0,0 +1,44 @@ +from pip._vendor.pkg_resources import yield_lines +from pip._vendor.six import ensure_str + +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import Dict, Iterable, List + + +class DictMetadata: + """IMetadataProvider that reads metadata files from a dictionary. + """ + def __init__(self, metadata): + # type: (Dict[str, bytes]) -> None + self._metadata = metadata + + def has_metadata(self, name): + # type: (str) -> bool + return name in self._metadata + + def get_metadata(self, name): + # type: (str) -> str + try: + return ensure_str(self._metadata[name]) + except UnicodeDecodeError as e: + # Mirrors handling done in pkg_resources.NullProvider. + e.reason += f" in {name} file" + raise + + def get_metadata_lines(self, name): + # type: (str) -> Iterable[str] + return yield_lines(self.get_metadata(name)) + + def metadata_isdir(self, name): + # type: (str) -> bool + return False + + def metadata_listdir(self, name): + # type: (str) -> List[str] + return [] + + def run_script(self, script_name, namespace): + # type: (str, str) -> None + pass diff --git a/venv/Lib/site-packages/pip/_internal/utils/setuptools_build.py b/venv/Lib/site-packages/pip/_internal/utils/setuptools_build.py new file mode 100644 index 0000000..2a664b0 --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/utils/setuptools_build.py @@ -0,0 +1,181 @@ +import sys + +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import List, Optional, Sequence + +# Shim to wrap setup.py invocation with setuptools +# +# We set sys.argv[0] to the path to the underlying setup.py file so +# setuptools / distutils don't take the path to the setup.py to be "-c" when +# invoking via the shim. This avoids e.g. the following manifest_maker +# warning: "warning: manifest_maker: standard file '-c' not found". +_SETUPTOOLS_SHIM = ( + "import sys, setuptools, tokenize; sys.argv[0] = {0!r}; __file__={0!r};" + "f=getattr(tokenize, 'open', open)(__file__);" + "code=f.read().replace('\\r\\n', '\\n');" + "f.close();" + "exec(compile(code, __file__, 'exec'))" +) + + +def make_setuptools_shim_args( + setup_py_path, # type: str + global_options=None, # type: Sequence[str] + no_user_config=False, # type: bool + unbuffered_output=False # type: bool +): + # type: (...) -> List[str] + """ + Get setuptools command arguments with shim wrapped setup file invocation. + + :param setup_py_path: The path to setup.py to be wrapped. + :param global_options: Additional global options. + :param no_user_config: If True, disables personal user configuration. + :param unbuffered_output: If True, adds the unbuffered switch to the + argument list. + """ + args = [sys.executable] + if unbuffered_output: + args += ["-u"] + args += ["-c", _SETUPTOOLS_SHIM.format(setup_py_path)] + if global_options: + args += global_options + if no_user_config: + args += ["--no-user-cfg"] + return args + + +def make_setuptools_bdist_wheel_args( + setup_py_path, # type: str + global_options, # type: Sequence[str] + build_options, # type: Sequence[str] + destination_dir, # type: str +): + # type: (...) -> List[str] + # NOTE: Eventually, we'd want to also -S to the flags here, when we're + # isolating. Currently, it breaks Python in virtualenvs, because it + # relies on site.py to find parts of the standard library outside the + # virtualenv. + args = make_setuptools_shim_args( + setup_py_path, + global_options=global_options, + unbuffered_output=True + ) + args += ["bdist_wheel", "-d", destination_dir] + args += build_options + return args + + +def make_setuptools_clean_args( + setup_py_path, # type: str + global_options, # type: Sequence[str] +): + # type: (...) -> List[str] + args = make_setuptools_shim_args( + setup_py_path, + global_options=global_options, + unbuffered_output=True + ) + args += ["clean", "--all"] + return args + + +def make_setuptools_develop_args( + setup_py_path, # type: str + global_options, # type: Sequence[str] + install_options, # type: Sequence[str] + no_user_config, # type: bool + prefix, # type: Optional[str] + home, # type: Optional[str] + use_user_site, # type: bool +): + # type: (...) -> List[str] + assert not (use_user_site and prefix) + + args = make_setuptools_shim_args( + setup_py_path, + global_options=global_options, + no_user_config=no_user_config, + ) + + args += ["develop", "--no-deps"] + + args += install_options + + if prefix: + args += ["--prefix", prefix] + if home is not None: + args += ["--home", home] + + if use_user_site: + args += ["--user", "--prefix="] + + return args + + +def make_setuptools_egg_info_args( + setup_py_path, # type: str + egg_info_dir, # type: Optional[str] + no_user_config, # type: bool +): + # type: (...) -> List[str] + args = make_setuptools_shim_args( + setup_py_path, no_user_config=no_user_config + ) + + args += ["egg_info"] + + if egg_info_dir: + args += ["--egg-base", egg_info_dir] + + return args + + +def make_setuptools_install_args( + setup_py_path, # type: str + global_options, # type: Sequence[str] + install_options, # type: Sequence[str] + record_filename, # type: str + root, # type: Optional[str] + prefix, # type: Optional[str] + header_dir, # type: Optional[str] + home, # type: Optional[str] + use_user_site, # type: bool + no_user_config, # type: bool + pycompile # type: bool +): + # type: (...) -> List[str] + assert not (use_user_site and prefix) + assert not (use_user_site and root) + + args = make_setuptools_shim_args( + setup_py_path, + global_options=global_options, + no_user_config=no_user_config, + unbuffered_output=True + ) + args += ["install", "--record", record_filename] + args += ["--single-version-externally-managed"] + + if root is not None: + args += ["--root", root] + if prefix is not None: + args += ["--prefix", prefix] + if home is not None: + args += ["--home", home] + if use_user_site: + args += ["--user", "--prefix="] + + if pycompile: + args += ["--compile"] + else: + args += ["--no-compile"] + + if header_dir: + args += ["--install-headers", header_dir] + + args += install_options + + return args diff --git a/venv/Lib/site-packages/pip/_internal/utils/subprocess.py b/venv/Lib/site-packages/pip/_internal/utils/subprocess.py new file mode 100644 index 0000000..f685b03 --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/utils/subprocess.py @@ -0,0 +1,296 @@ +import logging +import os +import shlex +import subprocess + +from pip._internal.cli.spinners import SpinnerInterface, open_spinner +from pip._internal.exceptions import InstallationSubprocessError +from pip._internal.utils.compat import console_to_str, str_to_display +from pip._internal.utils.logging import subprocess_logger +from pip._internal.utils.misc import HiddenText, path_to_display +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import Any, Callable, Iterable, List, Mapping, Optional, Union + + CommandArgs = List[Union[str, HiddenText]] + + +LOG_DIVIDER = '----------------------------------------' + + +def make_command(*args): + # type: (Union[str, HiddenText, CommandArgs]) -> CommandArgs + """ + Create a CommandArgs object. + """ + command_args = [] # type: CommandArgs + for arg in args: + # Check for list instead of CommandArgs since CommandArgs is + # only known during type-checking. + if isinstance(arg, list): + command_args.extend(arg) + else: + # Otherwise, arg is str or HiddenText. + command_args.append(arg) + + return command_args + + +def format_command_args(args): + # type: (Union[List[str], CommandArgs]) -> str + """ + Format command arguments for display. + """ + # For HiddenText arguments, display the redacted form by calling str(). + # Also, we don't apply str() to arguments that aren't HiddenText since + # this can trigger a UnicodeDecodeError in Python 2 if the argument + # has type unicode and includes a non-ascii character. (The type + # checker doesn't ensure the annotations are correct in all cases.) + return ' '.join( + shlex.quote(str(arg)) if isinstance(arg, HiddenText) + else shlex.quote(arg) for arg in args + ) + + +def reveal_command_args(args): + # type: (Union[List[str], CommandArgs]) -> List[str] + """ + Return the arguments in their raw, unredacted form. + """ + return [ + arg.secret if isinstance(arg, HiddenText) else arg for arg in args + ] + + +def make_subprocess_output_error( + cmd_args, # type: Union[List[str], CommandArgs] + cwd, # type: Optional[str] + lines, # type: List[str] + exit_status, # type: int +): + # type: (...) -> str + """ + Create and return the error message to use to log a subprocess error + with command output. + + :param lines: A list of lines, each ending with a newline. + """ + command = format_command_args(cmd_args) + # Convert `command` and `cwd` to text (unicode in Python 2) so we can use + # them as arguments in the unicode format string below. This avoids + # "UnicodeDecodeError: 'ascii' codec can't decode byte ..." in Python 2 + # if either contains a non-ascii character. + command_display = str_to_display(command, desc='command bytes') + cwd_display = path_to_display(cwd) + + # We know the joined output value ends in a newline. + output = ''.join(lines) + msg = ( + # Use a unicode string to avoid "UnicodeEncodeError: 'ascii' + # codec can't encode character ..." in Python 2 when a format + # argument (e.g. `output`) has a non-ascii character. + 'Command errored out with exit status {exit_status}:\n' + ' command: {command_display}\n' + ' cwd: {cwd_display}\n' + 'Complete output ({line_count} lines):\n{output}{divider}' + ).format( + exit_status=exit_status, + command_display=command_display, + cwd_display=cwd_display, + line_count=len(lines), + output=output, + divider=LOG_DIVIDER, + ) + return msg + + +def call_subprocess( + cmd, # type: Union[List[str], CommandArgs] + show_stdout=False, # type: bool + cwd=None, # type: Optional[str] + on_returncode='raise', # type: str + extra_ok_returncodes=None, # type: Optional[Iterable[int]] + command_desc=None, # type: Optional[str] + extra_environ=None, # type: Optional[Mapping[str, Any]] + unset_environ=None, # type: Optional[Iterable[str]] + spinner=None, # type: Optional[SpinnerInterface] + log_failed_cmd=True, # type: Optional[bool] + stdout_only=False, # type: Optional[bool] +): + # type: (...) -> str + """ + Args: + show_stdout: if true, use INFO to log the subprocess's stderr and + stdout streams. Otherwise, use DEBUG. Defaults to False. + extra_ok_returncodes: an iterable of integer return codes that are + acceptable, in addition to 0. Defaults to None, which means []. + unset_environ: an iterable of environment variable names to unset + prior to calling subprocess.Popen(). + log_failed_cmd: if false, failed commands are not logged, only raised. + stdout_only: if true, return only stdout, else return both. When true, + logging of both stdout and stderr occurs when the subprocess has + terminated, else logging occurs as subprocess output is produced. + """ + if extra_ok_returncodes is None: + extra_ok_returncodes = [] + if unset_environ is None: + unset_environ = [] + # Most places in pip use show_stdout=False. What this means is-- + # + # - We connect the child's output (combined stderr and stdout) to a + # single pipe, which we read. + # - We log this output to stderr at DEBUG level as it is received. + # - If DEBUG logging isn't enabled (e.g. if --verbose logging wasn't + # requested), then we show a spinner so the user can still see the + # subprocess is in progress. + # - If the subprocess exits with an error, we log the output to stderr + # at ERROR level if it hasn't already been displayed to the console + # (e.g. if --verbose logging wasn't enabled). This way we don't log + # the output to the console twice. + # + # If show_stdout=True, then the above is still done, but with DEBUG + # replaced by INFO. + if show_stdout: + # Then log the subprocess output at INFO level. + log_subprocess = subprocess_logger.info + used_level = logging.INFO + else: + # Then log the subprocess output using DEBUG. This also ensures + # it will be logged to the log file (aka user_log), if enabled. + log_subprocess = subprocess_logger.debug + used_level = logging.DEBUG + + # Whether the subprocess will be visible in the console. + showing_subprocess = subprocess_logger.getEffectiveLevel() <= used_level + + # Only use the spinner if we're not showing the subprocess output + # and we have a spinner. + use_spinner = not showing_subprocess and spinner is not None + + if command_desc is None: + command_desc = format_command_args(cmd) + + log_subprocess("Running command %s", command_desc) + env = os.environ.copy() + if extra_environ: + env.update(extra_environ) + for name in unset_environ: + env.pop(name, None) + try: + proc = subprocess.Popen( + # Convert HiddenText objects to the underlying str. + reveal_command_args(cmd), + stdin=subprocess.PIPE, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT if not stdout_only else subprocess.PIPE, + cwd=cwd, + env=env, + ) + except Exception as exc: + if log_failed_cmd: + subprocess_logger.critical( + "Error %s while executing command %s", exc, command_desc, + ) + raise + all_output = [] + if not stdout_only: + assert proc.stdout + assert proc.stdin + proc.stdin.close() + # In this mode, stdout and stderr are in the same pipe. + while True: + # The "line" value is a unicode string in Python 2. + line = console_to_str(proc.stdout.readline()) + if not line: + break + line = line.rstrip() + all_output.append(line + '\n') + + # Show the line immediately. + log_subprocess(line) + # Update the spinner. + if use_spinner: + assert spinner + spinner.spin() + try: + proc.wait() + finally: + if proc.stdout: + proc.stdout.close() + output = ''.join(all_output) + else: + # In this mode, stdout and stderr are in different pipes. + # We must use communicate() which is the only safe way to read both. + out_bytes, err_bytes = proc.communicate() + # log line by line to preserve pip log indenting + out = console_to_str(out_bytes) + for out_line in out.splitlines(): + log_subprocess(out_line) + all_output.append(out) + err = console_to_str(err_bytes) + for err_line in err.splitlines(): + log_subprocess(err_line) + all_output.append(err) + output = out + + proc_had_error = ( + proc.returncode and proc.returncode not in extra_ok_returncodes + ) + if use_spinner: + assert spinner + if proc_had_error: + spinner.finish("error") + else: + spinner.finish("done") + if proc_had_error: + if on_returncode == 'raise': + if not showing_subprocess and log_failed_cmd: + # Then the subprocess streams haven't been logged to the + # console yet. + msg = make_subprocess_output_error( + cmd_args=cmd, + cwd=cwd, + lines=all_output, + exit_status=proc.returncode, + ) + subprocess_logger.error(msg) + raise InstallationSubprocessError(proc.returncode, command_desc) + elif on_returncode == 'warn': + subprocess_logger.warning( + 'Command "%s" had error code %s in %s', + command_desc, + proc.returncode, + cwd, + ) + elif on_returncode == 'ignore': + pass + else: + raise ValueError('Invalid value: on_returncode={!r}'.format( + on_returncode)) + return output + + +def runner_with_spinner_message(message): + # type: (str) -> Callable[..., None] + """Provide a subprocess_runner that shows a spinner message. + + Intended for use with for pep517's Pep517HookCaller. Thus, the runner has + an API that matches what's expected by Pep517HookCaller.subprocess_runner. + """ + + def runner( + cmd, # type: List[str] + cwd=None, # type: Optional[str] + extra_environ=None # type: Optional[Mapping[str, Any]] + ): + # type: (...) -> None + with open_spinner(message) as spinner: + call_subprocess( + cmd, + cwd=cwd, + extra_environ=extra_environ, + spinner=spinner, + ) + + return runner diff --git a/venv/Lib/site-packages/pip/_internal/utils/temp_dir.py b/venv/Lib/site-packages/pip/_internal/utils/temp_dir.py new file mode 100644 index 0000000..91b277d --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/utils/temp_dir.py @@ -0,0 +1,282 @@ +import errno +import itertools +import logging +import os.path +import tempfile +from contextlib import contextmanager + +from pip._vendor.contextlib2 import ExitStack +from pip._vendor.six import ensure_text + +from pip._internal.utils.compat import WINDOWS +from pip._internal.utils.misc import enum, rmtree +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import Any, Dict, Iterator, Optional, TypeVar, Union + + _T = TypeVar('_T', bound='TempDirectory') + + +logger = logging.getLogger(__name__) + + +# Kinds of temporary directories. Only needed for ones that are +# globally-managed. +tempdir_kinds = enum( + BUILD_ENV="build-env", + EPHEM_WHEEL_CACHE="ephem-wheel-cache", + REQ_BUILD="req-build", +) + + +_tempdir_manager = None # type: Optional[ExitStack] + + +@contextmanager +def global_tempdir_manager(): + # type: () -> Iterator[None] + global _tempdir_manager + with ExitStack() as stack: + old_tempdir_manager, _tempdir_manager = _tempdir_manager, stack + try: + yield + finally: + _tempdir_manager = old_tempdir_manager + + +class TempDirectoryTypeRegistry: + """Manages temp directory behavior + """ + + def __init__(self): + # type: () -> None + self._should_delete = {} # type: Dict[str, bool] + + def set_delete(self, kind, value): + # type: (str, bool) -> None + """Indicate whether a TempDirectory of the given kind should be + auto-deleted. + """ + self._should_delete[kind] = value + + def get_delete(self, kind): + # type: (str) -> bool + """Get configured auto-delete flag for a given TempDirectory type, + default True. + """ + return self._should_delete.get(kind, True) + + +_tempdir_registry = None # type: Optional[TempDirectoryTypeRegistry] + + +@contextmanager +def tempdir_registry(): + # type: () -> Iterator[TempDirectoryTypeRegistry] + """Provides a scoped global tempdir registry that can be used to dictate + whether directories should be deleted. + """ + global _tempdir_registry + old_tempdir_registry = _tempdir_registry + _tempdir_registry = TempDirectoryTypeRegistry() + try: + yield _tempdir_registry + finally: + _tempdir_registry = old_tempdir_registry + + +class _Default: + pass + + +_default = _Default() + + +class TempDirectory: + """Helper class that owns and cleans up a temporary directory. + + This class can be used as a context manager or as an OO representation of a + temporary directory. + + Attributes: + path + Location to the created temporary directory + delete + Whether the directory should be deleted when exiting + (when used as a contextmanager) + + Methods: + cleanup() + Deletes the temporary directory + + When used as a context manager, if the delete attribute is True, on + exiting the context the temporary directory is deleted. + """ + + def __init__( + self, + path=None, # type: Optional[str] + delete=_default, # type: Union[bool, None, _Default] + kind="temp", # type: str + globally_managed=False, # type: bool + ): + super().__init__() + + if delete is _default: + if path is not None: + # If we were given an explicit directory, resolve delete option + # now. + delete = False + else: + # Otherwise, we wait until cleanup and see what + # tempdir_registry says. + delete = None + + # The only time we specify path is in for editables where it + # is the value of the --src option. + if path is None: + path = self._create(kind) + + self._path = path + self._deleted = False + self.delete = delete + self.kind = kind + + if globally_managed: + assert _tempdir_manager is not None + _tempdir_manager.enter_context(self) + + @property + def path(self): + # type: () -> str + assert not self._deleted, ( + f"Attempted to access deleted path: {self._path}" + ) + return self._path + + def __repr__(self): + # type: () -> str + return f"<{self.__class__.__name__} {self.path!r}>" + + def __enter__(self): + # type: (_T) -> _T + return self + + def __exit__(self, exc, value, tb): + # type: (Any, Any, Any) -> None + if self.delete is not None: + delete = self.delete + elif _tempdir_registry: + delete = _tempdir_registry.get_delete(self.kind) + else: + delete = True + + if delete: + self.cleanup() + + def _create(self, kind): + # type: (str) -> str + """Create a temporary directory and store its path in self.path + """ + # We realpath here because some systems have their default tmpdir + # symlinked to another directory. This tends to confuse build + # scripts, so we canonicalize the path by traversing potential + # symlinks here. + path = os.path.realpath( + tempfile.mkdtemp(prefix=f"pip-{kind}-") + ) + logger.debug("Created temporary directory: %s", path) + return path + + def cleanup(self): + # type: () -> None + """Remove the temporary directory created and reset state + """ + self._deleted = True + if not os.path.exists(self._path): + return + # Make sure to pass unicode on Python 2 to make the contents also + # use unicode, ensuring non-ASCII names and can be represented. + # This is only done on Windows because POSIX platforms use bytes + # natively for paths, and the bytes-text conversion omission avoids + # errors caused by the environment configuring encodings incorrectly. + if WINDOWS: + rmtree(ensure_text(self._path)) + else: + rmtree(self._path) + + +class AdjacentTempDirectory(TempDirectory): + """Helper class that creates a temporary directory adjacent to a real one. + + Attributes: + original + The original directory to create a temp directory for. + path + After calling create() or entering, contains the full + path to the temporary directory. + delete + Whether the directory should be deleted when exiting + (when used as a contextmanager) + + """ + # The characters that may be used to name the temp directory + # We always prepend a ~ and then rotate through these until + # a usable name is found. + # pkg_resources raises a different error for .dist-info folder + # with leading '-' and invalid metadata + LEADING_CHARS = "-~.=%0123456789" + + def __init__(self, original, delete=None): + # type: (str, Optional[bool]) -> None + self.original = original.rstrip('/\\') + super().__init__(delete=delete) + + @classmethod + def _generate_names(cls, name): + # type: (str) -> Iterator[str] + """Generates a series of temporary names. + + The algorithm replaces the leading characters in the name + with ones that are valid filesystem characters, but are not + valid package names (for both Python and pip definitions of + package). + """ + for i in range(1, len(name)): + for candidate in itertools.combinations_with_replacement( + cls.LEADING_CHARS, i - 1): + new_name = '~' + ''.join(candidate) + name[i:] + if new_name != name: + yield new_name + + # If we make it this far, we will have to make a longer name + for i in range(len(cls.LEADING_CHARS)): + for candidate in itertools.combinations_with_replacement( + cls.LEADING_CHARS, i): + new_name = '~' + ''.join(candidate) + name + if new_name != name: + yield new_name + + def _create(self, kind): + # type: (str) -> str + root, name = os.path.split(self.original) + for candidate in self._generate_names(name): + path = os.path.join(root, candidate) + try: + os.mkdir(path) + except OSError as ex: + # Continue if the name exists already + if ex.errno != errno.EEXIST: + raise + else: + path = os.path.realpath(path) + break + else: + # Final fallback on the default behavior. + path = os.path.realpath( + tempfile.mkdtemp(prefix=f"pip-{kind}-") + ) + + logger.debug("Created temporary directory: %s", path) + return path diff --git a/venv/Lib/site-packages/pip/_internal/utils/typing.py b/venv/Lib/site-packages/pip/_internal/utils/typing.py new file mode 100644 index 0000000..8505a29 --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/utils/typing.py @@ -0,0 +1,38 @@ +"""For neatly implementing static typing in pip. + +`mypy` - the static type analysis tool we use - uses the `typing` module, which +provides core functionality fundamental to mypy's functioning. + +Generally, `typing` would be imported at runtime and used in that fashion - +it acts as a no-op at runtime and does not have any run-time overhead by +design. + +As it turns out, `typing` is not vendorable - it uses separate sources for +Python 2/Python 3. Thus, this codebase can not expect it to be present. +To work around this, mypy allows the typing import to be behind a False-y +optional to prevent it from running at runtime and type-comments can be used +to remove the need for the types to be accessible directly during runtime. + +This module provides the False-y guard in a nicely named fashion so that a +curious maintainer can reach here to read this. + +In pip, all static-typing related imports should be guarded as follows: + + from pip._internal.utils.typing import MYPY_CHECK_RUNNING + + if MYPY_CHECK_RUNNING: + from typing import ... + +Ref: https://github.com/python/mypy/issues/3216 +""" + +MYPY_CHECK_RUNNING = False + + +if MYPY_CHECK_RUNNING: + from typing import cast +else: + # typing's cast() is needed at runtime, but we don't want to import typing. + # Thus, we use a dummy no-op version, which we tell mypy to ignore. + def cast(type_, value): # type: ignore + return value diff --git a/venv/Lib/site-packages/pip/_internal/utils/unpacking.py b/venv/Lib/site-packages/pip/_internal/utils/unpacking.py new file mode 100644 index 0000000..a24d7e5 --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/utils/unpacking.py @@ -0,0 +1,277 @@ +"""Utilities related archives. +""" + +import logging +import os +import shutil +import stat +import tarfile +import zipfile + +from pip._internal.exceptions import InstallationError +from pip._internal.utils.filetypes import ( + BZ2_EXTENSIONS, + TAR_EXTENSIONS, + XZ_EXTENSIONS, + ZIP_EXTENSIONS, +) +from pip._internal.utils.misc import ensure_dir +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import Iterable, List, Optional + from zipfile import ZipInfo + + +logger = logging.getLogger(__name__) + + +SUPPORTED_EXTENSIONS = ZIP_EXTENSIONS + TAR_EXTENSIONS + +try: + import bz2 # noqa + SUPPORTED_EXTENSIONS += BZ2_EXTENSIONS +except ImportError: + logger.debug('bz2 module is not available') + +try: + # Only for Python 3.3+ + import lzma # noqa + SUPPORTED_EXTENSIONS += XZ_EXTENSIONS +except ImportError: + logger.debug('lzma module is not available') + + +def current_umask(): + # type: () -> int + """Get the current umask which involves having to set it temporarily.""" + mask = os.umask(0) + os.umask(mask) + return mask + + +def split_leading_dir(path): + # type: (str) -> List[str] + path = path.lstrip('/').lstrip('\\') + if ( + '/' in path and ( + ('\\' in path and path.find('/') < path.find('\\')) or + '\\' not in path + ) + ): + return path.split('/', 1) + elif '\\' in path: + return path.split('\\', 1) + else: + return [path, ''] + + +def has_leading_dir(paths): + # type: (Iterable[str]) -> bool + """Returns true if all the paths have the same leading path name + (i.e., everything is in one subdirectory in an archive)""" + common_prefix = None + for path in paths: + prefix, rest = split_leading_dir(path) + if not prefix: + return False + elif common_prefix is None: + common_prefix = prefix + elif prefix != common_prefix: + return False + return True + + +def is_within_directory(directory, target): + # type: (str, str) -> bool + """ + Return true if the absolute path of target is within the directory + """ + abs_directory = os.path.abspath(directory) + abs_target = os.path.abspath(target) + + prefix = os.path.commonprefix([abs_directory, abs_target]) + return prefix == abs_directory + + +def set_extracted_file_to_default_mode_plus_executable(path): + # type: (str) -> None + """ + Make file present at path have execute for user/group/world + (chmod +x) is no-op on windows per python docs + """ + os.chmod(path, (0o777 & ~current_umask() | 0o111)) + + +def zip_item_is_executable(info): + # type: (ZipInfo) -> bool + mode = info.external_attr >> 16 + # if mode and regular file and any execute permissions for + # user/group/world? + return bool(mode and stat.S_ISREG(mode) and mode & 0o111) + + +def unzip_file(filename, location, flatten=True): + # type: (str, str, bool) -> None + """ + Unzip the file (with path `filename`) to the destination `location`. All + files are written based on system defaults and umask (i.e. permissions are + not preserved), except that regular file members with any execute + permissions (user, group, or world) have "chmod +x" applied after being + written. Note that for windows, any execute changes using os.chmod are + no-ops per the python docs. + """ + ensure_dir(location) + zipfp = open(filename, 'rb') + try: + zip = zipfile.ZipFile(zipfp, allowZip64=True) + leading = has_leading_dir(zip.namelist()) and flatten + for info in zip.infolist(): + name = info.filename + fn = name + if leading: + fn = split_leading_dir(name)[1] + fn = os.path.join(location, fn) + dir = os.path.dirname(fn) + if not is_within_directory(location, fn): + message = ( + 'The zip file ({}) has a file ({}) trying to install ' + 'outside target directory ({})' + ) + raise InstallationError(message.format(filename, fn, location)) + if fn.endswith('/') or fn.endswith('\\'): + # A directory + ensure_dir(fn) + else: + ensure_dir(dir) + # Don't use read() to avoid allocating an arbitrarily large + # chunk of memory for the file's content + fp = zip.open(name) + try: + with open(fn, 'wb') as destfp: + shutil.copyfileobj(fp, destfp) + finally: + fp.close() + if zip_item_is_executable(info): + set_extracted_file_to_default_mode_plus_executable(fn) + finally: + zipfp.close() + + +def untar_file(filename, location): + # type: (str, str) -> None + """ + Untar the file (with path `filename`) to the destination `location`. + All files are written based on system defaults and umask (i.e. permissions + are not preserved), except that regular file members with any execute + permissions (user, group, or world) have "chmod +x" applied after being + written. Note that for windows, any execute changes using os.chmod are + no-ops per the python docs. + """ + ensure_dir(location) + if filename.lower().endswith('.gz') or filename.lower().endswith('.tgz'): + mode = 'r:gz' + elif filename.lower().endswith(BZ2_EXTENSIONS): + mode = 'r:bz2' + elif filename.lower().endswith(XZ_EXTENSIONS): + mode = 'r:xz' + elif filename.lower().endswith('.tar'): + mode = 'r' + else: + logger.warning( + 'Cannot determine compression type for file %s', filename, + ) + mode = 'r:*' + tar = tarfile.open(filename, mode) + try: + leading = has_leading_dir([ + member.name for member in tar.getmembers() + ]) + for member in tar.getmembers(): + fn = member.name + if leading: + fn = split_leading_dir(fn)[1] + path = os.path.join(location, fn) + if not is_within_directory(location, path): + message = ( + 'The tar file ({}) has a file ({}) trying to install ' + 'outside target directory ({})' + ) + raise InstallationError( + message.format(filename, path, location) + ) + if member.isdir(): + ensure_dir(path) + elif member.issym(): + try: + # https://github.com/python/typeshed/issues/2673 + tar._extract_member(member, path) # type: ignore + except Exception as exc: + # Some corrupt tar files seem to produce this + # (specifically bad symlinks) + logger.warning( + 'In the tar file %s the member %s is invalid: %s', + filename, member.name, exc, + ) + continue + else: + try: + fp = tar.extractfile(member) + except (KeyError, AttributeError) as exc: + # Some corrupt tar files seem to produce this + # (specifically bad symlinks) + logger.warning( + 'In the tar file %s the member %s is invalid: %s', + filename, member.name, exc, + ) + continue + ensure_dir(os.path.dirname(path)) + assert fp is not None + with open(path, 'wb') as destfp: + shutil.copyfileobj(fp, destfp) + fp.close() + # Update the timestamp (useful for cython compiled files) + tar.utime(member, path) + # member have any execute permissions for user/group/world? + if member.mode & 0o111: + set_extracted_file_to_default_mode_plus_executable(path) + finally: + tar.close() + + +def unpack_file( + filename, # type: str + location, # type: str + content_type=None, # type: Optional[str] +): + # type: (...) -> None + filename = os.path.realpath(filename) + if ( + content_type == 'application/zip' or + filename.lower().endswith(ZIP_EXTENSIONS) or + zipfile.is_zipfile(filename) + ): + unzip_file( + filename, + location, + flatten=not filename.endswith('.whl') + ) + elif ( + content_type == 'application/x-gzip' or + tarfile.is_tarfile(filename) or + filename.lower().endswith( + TAR_EXTENSIONS + BZ2_EXTENSIONS + XZ_EXTENSIONS + ) + ): + untar_file(filename, location) + else: + # FIXME: handle? + # FIXME: magic signatures? + logger.critical( + 'Cannot unpack file %s (downloaded from %s, content-type: %s); ' + 'cannot detect archive format', + filename, location, content_type, + ) + raise InstallationError( + f'Cannot determine archive format of {location}' + ) diff --git a/venv/Lib/site-packages/pip/_internal/utils/urls.py b/venv/Lib/site-packages/pip/_internal/utils/urls.py new file mode 100644 index 0000000..0ef063c --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/utils/urls.py @@ -0,0 +1,54 @@ +import os +import sys +import urllib.parse +import urllib.request + +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import Optional + + +def get_url_scheme(url): + # type: (str) -> Optional[str] + if ':' not in url: + return None + return url.split(':', 1)[0].lower() + + +def path_to_url(path): + # type: (str) -> str + """ + Convert a path to a file: URL. The path will be made absolute and have + quoted path parts. + """ + path = os.path.normpath(os.path.abspath(path)) + url = urllib.parse.urljoin('file:', urllib.request.pathname2url(path)) + return url + + +def url_to_path(url): + # type: (str) -> str + """ + Convert a file: URL to a path. + """ + assert url.startswith('file:'), ( + "You can only turn file: urls into filenames (not {url!r})" + .format(**locals())) + + _, netloc, path, _, _ = urllib.parse.urlsplit(url) + + if not netloc or netloc == 'localhost': + # According to RFC 8089, same as empty authority. + netloc = '' + elif sys.platform == 'win32': + # If we have a UNC path, prepend UNC share notation. + netloc = '\\\\' + netloc + else: + raise ValueError( + 'non-local file URIs are not supported on this platform: {url!r}' + .format(**locals()) + ) + + path = urllib.request.url2pathname(netloc + path) + return path diff --git a/venv/Lib/site-packages/pip/_internal/utils/virtualenv.py b/venv/Lib/site-packages/pip/_internal/utils/virtualenv.py new file mode 100644 index 0000000..3086bf2 --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/utils/virtualenv.py @@ -0,0 +1,116 @@ +import logging +import os +import re +import site +import sys + +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import List, Optional + +logger = logging.getLogger(__name__) +_INCLUDE_SYSTEM_SITE_PACKAGES_REGEX = re.compile( + r"include-system-site-packages\s*=\s*(?Ptrue|false)" +) + + +def _running_under_venv(): + # type: () -> bool + """Checks if sys.base_prefix and sys.prefix match. + + This handles PEP 405 compliant virtual environments. + """ + return sys.prefix != getattr(sys, "base_prefix", sys.prefix) + + +def _running_under_regular_virtualenv(): + # type: () -> bool + """Checks if sys.real_prefix is set. + + This handles virtual environments created with pypa's virtualenv. + """ + # pypa/virtualenv case + return hasattr(sys, 'real_prefix') + + +def running_under_virtualenv(): + # type: () -> bool + """Return True if we're running inside a virtualenv, False otherwise. + """ + return _running_under_venv() or _running_under_regular_virtualenv() + + +def _get_pyvenv_cfg_lines(): + # type: () -> Optional[List[str]] + """Reads {sys.prefix}/pyvenv.cfg and returns its contents as list of lines + + Returns None, if it could not read/access the file. + """ + pyvenv_cfg_file = os.path.join(sys.prefix, 'pyvenv.cfg') + try: + # Although PEP 405 does not specify, the built-in venv module always + # writes with UTF-8. (pypa/pip#8717) + with open(pyvenv_cfg_file, encoding='utf-8') as f: + return f.read().splitlines() # avoids trailing newlines + except OSError: + return None + + +def _no_global_under_venv(): + # type: () -> bool + """Check `{sys.prefix}/pyvenv.cfg` for system site-packages inclusion + + PEP 405 specifies that when system site-packages are not supposed to be + visible from a virtual environment, `pyvenv.cfg` must contain the following + line: + + include-system-site-packages = false + + Additionally, log a warning if accessing the file fails. + """ + cfg_lines = _get_pyvenv_cfg_lines() + if cfg_lines is None: + # We're not in a "sane" venv, so assume there is no system + # site-packages access (since that's PEP 405's default state). + logger.warning( + "Could not access 'pyvenv.cfg' despite a virtual environment " + "being active. Assuming global site-packages is not accessible " + "in this environment." + ) + return True + + for line in cfg_lines: + match = _INCLUDE_SYSTEM_SITE_PACKAGES_REGEX.match(line) + if match is not None and match.group('value') == 'false': + return True + return False + + +def _no_global_under_regular_virtualenv(): + # type: () -> bool + """Check if "no-global-site-packages.txt" exists beside site.py + + This mirrors logic in pypa/virtualenv for determining whether system + site-packages are visible in the virtual environment. + """ + site_mod_dir = os.path.dirname(os.path.abspath(site.__file__)) + no_global_site_packages_file = os.path.join( + site_mod_dir, 'no-global-site-packages.txt', + ) + return os.path.exists(no_global_site_packages_file) + + +def virtualenv_no_global(): + # type: () -> bool + """Returns a boolean, whether running in venv with no system site-packages. + """ + # PEP 405 compliance needs to be checked first since virtualenv >=20 would + # return True for both checks, but is only able to use the PEP 405 config. + if _running_under_venv(): + return _no_global_under_venv() + + if _running_under_regular_virtualenv(): + return _no_global_under_regular_virtualenv() + + return False diff --git a/venv/Lib/site-packages/pip/_internal/utils/wheel.py b/venv/Lib/site-packages/pip/_internal/utils/wheel.py new file mode 100644 index 0000000..e8d9c4b --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/utils/wheel.py @@ -0,0 +1,218 @@ +"""Support functions for working with wheel files. +""" + +import logging +from email.parser import Parser +from zipfile import BadZipFile, ZipFile + +from pip._vendor.packaging.utils import canonicalize_name +from pip._vendor.pkg_resources import DistInfoDistribution +from pip._vendor.six import ensure_str + +from pip._internal.exceptions import UnsupportedWheel +from pip._internal.utils.pkg_resources import DictMetadata +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from email.message import Message + from typing import Dict, Tuple + + from pip._vendor.pkg_resources import Distribution + + +VERSION_COMPATIBLE = (1, 0) + + +logger = logging.getLogger(__name__) + + +class WheelMetadata(DictMetadata): + """Metadata provider that maps metadata decoding exceptions to our + internal exception type. + """ + def __init__(self, metadata, wheel_name): + # type: (Dict[str, bytes], str) -> None + super().__init__(metadata) + self._wheel_name = wheel_name + + def get_metadata(self, name): + # type: (str) -> str + try: + return super().get_metadata(name) + except UnicodeDecodeError as e: + # Augment the default error with the origin of the file. + raise UnsupportedWheel( + "Error decoding metadata for {}: {}".format( + self._wheel_name, e + ) + ) + + +def pkg_resources_distribution_for_wheel(wheel_zip, name, location): + # type: (ZipFile, str, str) -> Distribution + """Get a pkg_resources distribution given a wheel. + + :raises UnsupportedWheel: on any errors + """ + info_dir, _ = parse_wheel(wheel_zip, name) + + metadata_files = [ + p for p in wheel_zip.namelist() if p.startswith(f"{info_dir}/") + ] + + metadata_text = {} # type: Dict[str, bytes] + for path in metadata_files: + # If a flag is set, namelist entries may be unicode in Python 2. + # We coerce them to native str type to match the types used in the rest + # of the code. This cannot fail because unicode can always be encoded + # with UTF-8. + full_path = ensure_str(path) + _, metadata_name = full_path.split("/", 1) + + try: + metadata_text[metadata_name] = read_wheel_metadata_file( + wheel_zip, full_path + ) + except UnsupportedWheel as e: + raise UnsupportedWheel( + "{} has an invalid wheel, {}".format(name, str(e)) + ) + + metadata = WheelMetadata(metadata_text, location) + + return DistInfoDistribution( + location=location, metadata=metadata, project_name=name + ) + + +def parse_wheel(wheel_zip, name): + # type: (ZipFile, str) -> Tuple[str, Message] + """Extract information from the provided wheel, ensuring it meets basic + standards. + + Returns the name of the .dist-info directory and the parsed WHEEL metadata. + """ + try: + info_dir = wheel_dist_info_dir(wheel_zip, name) + metadata = wheel_metadata(wheel_zip, info_dir) + version = wheel_version(metadata) + except UnsupportedWheel as e: + raise UnsupportedWheel( + "{} has an invalid wheel, {}".format(name, str(e)) + ) + + check_compatibility(version, name) + + return info_dir, metadata + + +def wheel_dist_info_dir(source, name): + # type: (ZipFile, str) -> str + """Returns the name of the contained .dist-info directory. + + Raises AssertionError or UnsupportedWheel if not found, >1 found, or + it doesn't match the provided name. + """ + # Zip file path separators must be / + subdirs = {p.split("/", 1)[0] for p in source.namelist()} + + info_dirs = [s for s in subdirs if s.endswith('.dist-info')] + + if not info_dirs: + raise UnsupportedWheel(".dist-info directory not found") + + if len(info_dirs) > 1: + raise UnsupportedWheel( + "multiple .dist-info directories found: {}".format( + ", ".join(info_dirs) + ) + ) + + info_dir = info_dirs[0] + + info_dir_name = canonicalize_name(info_dir) + canonical_name = canonicalize_name(name) + if not info_dir_name.startswith(canonical_name): + raise UnsupportedWheel( + ".dist-info directory {!r} does not start with {!r}".format( + info_dir, canonical_name + ) + ) + + # Zip file paths can be unicode or str depending on the zip entry flags, + # so normalize it. + return ensure_str(info_dir) + + +def read_wheel_metadata_file(source, path): + # type: (ZipFile, str) -> bytes + try: + return source.read(path) + # BadZipFile for general corruption, KeyError for missing entry, + # and RuntimeError for password-protected files + except (BadZipFile, KeyError, RuntimeError) as e: + raise UnsupportedWheel( + f"could not read {path!r} file: {e!r}" + ) + + +def wheel_metadata(source, dist_info_dir): + # type: (ZipFile, str) -> Message + """Return the WHEEL metadata of an extracted wheel, if possible. + Otherwise, raise UnsupportedWheel. + """ + path = f"{dist_info_dir}/WHEEL" + # Zip file path separators must be / + wheel_contents = read_wheel_metadata_file(source, path) + + try: + wheel_text = ensure_str(wheel_contents) + except UnicodeDecodeError as e: + raise UnsupportedWheel(f"error decoding {path!r}: {e!r}") + + # FeedParser (used by Parser) does not raise any exceptions. The returned + # message may have .defects populated, but for backwards-compatibility we + # currently ignore them. + return Parser().parsestr(wheel_text) + + +def wheel_version(wheel_data): + # type: (Message) -> Tuple[int, ...] + """Given WHEEL metadata, return the parsed Wheel-Version. + Otherwise, raise UnsupportedWheel. + """ + version_text = wheel_data["Wheel-Version"] + if version_text is None: + raise UnsupportedWheel("WHEEL is missing Wheel-Version") + + version = version_text.strip() + + try: + return tuple(map(int, version.split('.'))) + except ValueError: + raise UnsupportedWheel(f"invalid Wheel-Version: {version!r}") + + +def check_compatibility(version, name): + # type: (Tuple[int, ...], str) -> None + """Raises errors or warns if called with an incompatible Wheel-Version. + + pip should refuse to install a Wheel-Version that's a major series + ahead of what it's compatible with (e.g 2.0 > 1.1); and warn when + installing a version only minor version ahead (e.g 1.2 > 1.1). + + version: a 2-tuple representing a Wheel-Version (Major, Minor) + name: name of wheel or package to raise exception about + + :raises UnsupportedWheel: when an incompatible Wheel-Version is given + """ + if version[0] > VERSION_COMPATIBLE[0]: + raise UnsupportedWheel( + "{}'s Wheel-Version ({}) is not compatible with this version " + "of pip".format(name, '.'.join(map(str, version))) + ) + elif version > VERSION_COMPATIBLE: + logger.warning( + 'Installing from a newer Wheel-Version (%s)', + '.'.join(map(str, version)), + ) diff --git a/venv/Lib/site-packages/pip/_internal/vcs/__init__.py b/venv/Lib/site-packages/pip/_internal/vcs/__init__.py new file mode 100644 index 0000000..2a4eb13 --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/vcs/__init__.py @@ -0,0 +1,15 @@ +# Expose a limited set of classes and functions so callers outside of +# the vcs package don't need to import deeper than `pip._internal.vcs`. +# (The test directory and imports protected by MYPY_CHECK_RUNNING may +# still need to import from a vcs sub-package.) +# Import all vcs modules to register each VCS in the VcsSupport object. +import pip._internal.vcs.bazaar +import pip._internal.vcs.git +import pip._internal.vcs.mercurial +import pip._internal.vcs.subversion # noqa: F401 +from pip._internal.vcs.versioncontrol import ( # noqa: F401 + RemoteNotFoundError, + is_url, + make_vcs_requirement_url, + vcs, +) diff --git a/venv/Lib/site-packages/pip/_internal/vcs/bazaar.py b/venv/Lib/site-packages/pip/_internal/vcs/bazaar.py new file mode 100644 index 0000000..383f73a --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/vcs/bazaar.py @@ -0,0 +1,114 @@ +# The following comment should be removed at some point in the future. +# mypy: disallow-untyped-defs=False + +import logging +import os + +from pip._internal.utils.misc import display_path, rmtree +from pip._internal.utils.subprocess import make_command +from pip._internal.utils.typing import MYPY_CHECK_RUNNING +from pip._internal.utils.urls import path_to_url +from pip._internal.vcs.versioncontrol import RemoteNotFoundError, VersionControl, vcs + +if MYPY_CHECK_RUNNING: + from typing import Optional, Tuple + + from pip._internal.utils.misc import HiddenText + from pip._internal.vcs.versioncontrol import AuthInfo, RevOptions + + +logger = logging.getLogger(__name__) + + +class Bazaar(VersionControl): + name = 'bzr' + dirname = '.bzr' + repo_name = 'branch' + schemes = ( + 'bzr+http', 'bzr+https', 'bzr+ssh', 'bzr+sftp', 'bzr+ftp', + 'bzr+lp', 'bzr+file' + ) + + @staticmethod + def get_base_rev_args(rev): + return ['-r', rev] + + def export(self, location, url): + # type: (str, HiddenText) -> None + """ + Export the Bazaar repository at the url to the destination location + """ + # Remove the location to make sure Bazaar can export it correctly + if os.path.exists(location): + rmtree(location) + + url, rev_options = self.get_url_rev_options(url) + self.run_command( + make_command('export', location, url, rev_options.to_args()), + show_stdout=False, + ) + + def fetch_new(self, dest, url, rev_options): + # type: (str, HiddenText, RevOptions) -> None + rev_display = rev_options.to_display() + logger.info( + 'Checking out %s%s to %s', + url, + rev_display, + display_path(dest), + ) + cmd_args = ( + make_command('branch', '-q', rev_options.to_args(), url, dest) + ) + self.run_command(cmd_args) + + def switch(self, dest, url, rev_options): + # type: (str, HiddenText, RevOptions) -> None + self.run_command(make_command('switch', url), cwd=dest) + + def update(self, dest, url, rev_options): + # type: (str, HiddenText, RevOptions) -> None + cmd_args = make_command('pull', '-q', rev_options.to_args()) + self.run_command(cmd_args, cwd=dest) + + @classmethod + def get_url_rev_and_auth(cls, url): + # type: (str) -> Tuple[str, Optional[str], AuthInfo] + # hotfix the URL scheme after removing bzr+ from bzr+ssh:// readd it + url, rev, user_pass = super().get_url_rev_and_auth(url) + if url.startswith('ssh://'): + url = 'bzr+' + url + return url, rev, user_pass + + @classmethod + def get_remote_url(cls, location): + # type: (str) -> str + urls = cls.run_command( + ['info'], show_stdout=False, stdout_only=True, cwd=location + ) + for line in urls.splitlines(): + line = line.strip() + for x in ('checkout of branch: ', + 'parent branch: '): + if line.startswith(x): + repo = line.split(x)[1] + if cls._is_local_repository(repo): + return path_to_url(repo) + return repo + raise RemoteNotFoundError + + @classmethod + def get_revision(cls, location): + # type: (str) -> str + revision = cls.run_command( + ['revno'], show_stdout=False, stdout_only=True, cwd=location, + ) + return revision.splitlines()[-1] + + @classmethod + def is_commit_id_equal(cls, dest, name): + """Always assume the versions don't match""" + return False + + +vcs.register(Bazaar) diff --git a/venv/Lib/site-packages/pip/_internal/vcs/git.py b/venv/Lib/site-packages/pip/_internal/vcs/git.py new file mode 100644 index 0000000..cc22cd7 --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/vcs/git.py @@ -0,0 +1,454 @@ +# The following comment should be removed at some point in the future. +# mypy: disallow-untyped-defs=False + +import logging +import os.path +import re +import urllib.parse +import urllib.request + +from pip._vendor.packaging.version import parse as parse_version + +from pip._internal.exceptions import BadCommand, InstallationError +from pip._internal.utils.misc import display_path, hide_url +from pip._internal.utils.subprocess import make_command +from pip._internal.utils.temp_dir import TempDirectory +from pip._internal.utils.typing import MYPY_CHECK_RUNNING +from pip._internal.vcs.versioncontrol import ( + RemoteNotFoundError, + VersionControl, + find_path_to_setup_from_repo_root, + vcs, +) + +if MYPY_CHECK_RUNNING: + from typing import Optional, Tuple + + from pip._internal.utils.misc import HiddenText + from pip._internal.vcs.versioncontrol import AuthInfo, RevOptions + + +urlsplit = urllib.parse.urlsplit +urlunsplit = urllib.parse.urlunsplit + + +logger = logging.getLogger(__name__) + + +HASH_REGEX = re.compile('^[a-fA-F0-9]{40}$') + + +def looks_like_hash(sha): + return bool(HASH_REGEX.match(sha)) + + +class Git(VersionControl): + name = 'git' + dirname = '.git' + repo_name = 'clone' + schemes = ( + 'git+http', 'git+https', 'git+ssh', 'git+git', 'git+file', + ) + # Prevent the user's environment variables from interfering with pip: + # https://github.com/pypa/pip/issues/1130 + unset_environ = ('GIT_DIR', 'GIT_WORK_TREE') + default_arg_rev = 'HEAD' + + @staticmethod + def get_base_rev_args(rev): + return [rev] + + def is_immutable_rev_checkout(self, url, dest): + # type: (str, str) -> bool + _, rev_options = self.get_url_rev_options(hide_url(url)) + if not rev_options.rev: + return False + if not self.is_commit_id_equal(dest, rev_options.rev): + # the current commit is different from rev, + # which means rev was something else than a commit hash + return False + # return False in the rare case rev is both a commit hash + # and a tag or a branch; we don't want to cache in that case + # because that branch/tag could point to something else in the future + is_tag_or_branch = bool( + self.get_revision_sha(dest, rev_options.rev)[0] + ) + return not is_tag_or_branch + + def get_git_version(self): + VERSION_PFX = 'git version ' + version = self.run_command( + ['version'], show_stdout=False, stdout_only=True + ) + if version.startswith(VERSION_PFX): + version = version[len(VERSION_PFX):].split()[0] + else: + version = '' + # get first 3 positions of the git version because + # on windows it is x.y.z.windows.t, and this parses as + # LegacyVersion which always smaller than a Version. + version = '.'.join(version.split('.')[:3]) + return parse_version(version) + + @classmethod + def get_current_branch(cls, location): + """ + Return the current branch, or None if HEAD isn't at a branch + (e.g. detached HEAD). + """ + # git-symbolic-ref exits with empty stdout if "HEAD" is a detached + # HEAD rather than a symbolic ref. In addition, the -q causes the + # command to exit with status code 1 instead of 128 in this case + # and to suppress the message to stderr. + args = ['symbolic-ref', '-q', 'HEAD'] + output = cls.run_command( + args, + extra_ok_returncodes=(1, ), + show_stdout=False, + stdout_only=True, + cwd=location, + ) + ref = output.strip() + + if ref.startswith('refs/heads/'): + return ref[len('refs/heads/'):] + + return None + + def export(self, location, url): + # type: (str, HiddenText) -> None + """Export the Git repository at the url to the destination location""" + if not location.endswith('/'): + location = location + '/' + + with TempDirectory(kind="export") as temp_dir: + self.unpack(temp_dir.path, url=url) + self.run_command( + ['checkout-index', '-a', '-f', '--prefix', location], + show_stdout=False, cwd=temp_dir.path + ) + + @classmethod + def get_revision_sha(cls, dest, rev): + """ + Return (sha_or_none, is_branch), where sha_or_none is a commit hash + if the revision names a remote branch or tag, otherwise None. + + Args: + dest: the repository directory. + rev: the revision name. + """ + # Pass rev to pre-filter the list. + output = cls.run_command( + ['show-ref', rev], + cwd=dest, + show_stdout=False, + stdout_only=True, + on_returncode='ignore', + ) + refs = {} + for line in output.strip().splitlines(): + try: + sha, ref = line.split() + except ValueError: + # Include the offending line to simplify troubleshooting if + # this error ever occurs. + raise ValueError(f'unexpected show-ref line: {line!r}') + + refs[ref] = sha + + branch_ref = f'refs/remotes/origin/{rev}' + tag_ref = f'refs/tags/{rev}' + + sha = refs.get(branch_ref) + if sha is not None: + return (sha, True) + + sha = refs.get(tag_ref) + + return (sha, False) + + @classmethod + def _should_fetch(cls, dest, rev): + """ + Return true if rev is a ref or is a commit that we don't have locally. + + Branches and tags are not considered in this method because they are + assumed to be always available locally (which is a normal outcome of + ``git clone`` and ``git fetch --tags``). + """ + if rev.startswith("refs/"): + # Always fetch remote refs. + return True + + if not looks_like_hash(rev): + # Git fetch would fail with abbreviated commits. + return False + + if cls.has_commit(dest, rev): + # Don't fetch if we have the commit locally. + return False + + return True + + @classmethod + def resolve_revision(cls, dest, url, rev_options): + # type: (str, HiddenText, RevOptions) -> RevOptions + """ + Resolve a revision to a new RevOptions object with the SHA1 of the + branch, tag, or ref if found. + + Args: + rev_options: a RevOptions object. + """ + rev = rev_options.arg_rev + # The arg_rev property's implementation for Git ensures that the + # rev return value is always non-None. + assert rev is not None + + sha, is_branch = cls.get_revision_sha(dest, rev) + + if sha is not None: + rev_options = rev_options.make_new(sha) + rev_options.branch_name = rev if is_branch else None + + return rev_options + + # Do not show a warning for the common case of something that has + # the form of a Git commit hash. + if not looks_like_hash(rev): + logger.warning( + "Did not find branch or tag '%s', assuming revision or ref.", + rev, + ) + + if not cls._should_fetch(dest, rev): + return rev_options + + # fetch the requested revision + cls.run_command( + make_command('fetch', '-q', url, rev_options.to_args()), + cwd=dest, + ) + # Change the revision to the SHA of the ref we fetched + sha = cls.get_revision(dest, rev='FETCH_HEAD') + rev_options = rev_options.make_new(sha) + + return rev_options + + @classmethod + def is_commit_id_equal(cls, dest, name): + """ + Return whether the current commit hash equals the given name. + + Args: + dest: the repository directory. + name: a string name. + """ + if not name: + # Then avoid an unnecessary subprocess call. + return False + + return cls.get_revision(dest) == name + + def fetch_new(self, dest, url, rev_options): + # type: (str, HiddenText, RevOptions) -> None + rev_display = rev_options.to_display() + logger.info('Cloning %s%s to %s', url, rev_display, display_path(dest)) + self.run_command(make_command('clone', '-q', url, dest)) + + if rev_options.rev: + # Then a specific revision was requested. + rev_options = self.resolve_revision(dest, url, rev_options) + branch_name = getattr(rev_options, 'branch_name', None) + if branch_name is None: + # Only do a checkout if the current commit id doesn't match + # the requested revision. + if not self.is_commit_id_equal(dest, rev_options.rev): + cmd_args = make_command( + 'checkout', '-q', rev_options.to_args(), + ) + self.run_command(cmd_args, cwd=dest) + elif self.get_current_branch(dest) != branch_name: + # Then a specific branch was requested, and that branch + # is not yet checked out. + track_branch = f'origin/{branch_name}' + cmd_args = [ + 'checkout', '-b', branch_name, '--track', track_branch, + ] + self.run_command(cmd_args, cwd=dest) + + #: repo may contain submodules + self.update_submodules(dest) + + def switch(self, dest, url, rev_options): + # type: (str, HiddenText, RevOptions) -> None + self.run_command( + make_command('config', 'remote.origin.url', url), + cwd=dest, + ) + cmd_args = make_command('checkout', '-q', rev_options.to_args()) + self.run_command(cmd_args, cwd=dest) + + self.update_submodules(dest) + + def update(self, dest, url, rev_options): + # type: (str, HiddenText, RevOptions) -> None + # First fetch changes from the default remote + if self.get_git_version() >= parse_version('1.9.0'): + # fetch tags in addition to everything else + self.run_command(['fetch', '-q', '--tags'], cwd=dest) + else: + self.run_command(['fetch', '-q'], cwd=dest) + # Then reset to wanted revision (maybe even origin/master) + rev_options = self.resolve_revision(dest, url, rev_options) + cmd_args = make_command('reset', '--hard', '-q', rev_options.to_args()) + self.run_command(cmd_args, cwd=dest) + #: update submodules + self.update_submodules(dest) + + @classmethod + def get_remote_url(cls, location): + # type: (str) -> str + """ + Return URL of the first remote encountered. + + Raises RemoteNotFoundError if the repository does not have a remote + url configured. + """ + # We need to pass 1 for extra_ok_returncodes since the command + # exits with return code 1 if there are no matching lines. + stdout = cls.run_command( + ['config', '--get-regexp', r'remote\..*\.url'], + extra_ok_returncodes=(1, ), + show_stdout=False, + stdout_only=True, + cwd=location, + ) + remotes = stdout.splitlines() + try: + found_remote = remotes[0] + except IndexError: + raise RemoteNotFoundError + + for remote in remotes: + if remote.startswith('remote.origin.url '): + found_remote = remote + break + url = found_remote.split(' ')[1] + return url.strip() + + @classmethod + def has_commit(cls, location, rev): + """ + Check if rev is a commit that is available in the local repository. + """ + try: + cls.run_command( + ['rev-parse', '-q', '--verify', "sha^" + rev], + cwd=location, + log_failed_cmd=False, + ) + except InstallationError: + return False + else: + return True + + @classmethod + def get_revision(cls, location, rev=None): + # type: (str, Optional[str]) -> str + if rev is None: + rev = 'HEAD' + current_rev = cls.run_command( + ['rev-parse', rev], + show_stdout=False, + stdout_only=True, + cwd=location, + ) + return current_rev.strip() + + @classmethod + def get_subdirectory(cls, location): + """ + Return the path to setup.py, relative to the repo root. + Return None if setup.py is in the repo root. + """ + # find the repo root + git_dir = cls.run_command( + ['rev-parse', '--git-dir'], + show_stdout=False, + stdout_only=True, + cwd=location, + ).strip() + if not os.path.isabs(git_dir): + git_dir = os.path.join(location, git_dir) + repo_root = os.path.abspath(os.path.join(git_dir, '..')) + return find_path_to_setup_from_repo_root(location, repo_root) + + @classmethod + def get_url_rev_and_auth(cls, url): + # type: (str) -> Tuple[str, Optional[str], AuthInfo] + """ + Prefixes stub URLs like 'user@hostname:user/repo.git' with 'ssh://'. + That's required because although they use SSH they sometimes don't + work with a ssh:// scheme (e.g. GitHub). But we need a scheme for + parsing. Hence we remove it again afterwards and return it as a stub. + """ + # Works around an apparent Git bug + # (see https://article.gmane.org/gmane.comp.version-control.git/146500) + scheme, netloc, path, query, fragment = urlsplit(url) + if scheme.endswith('file'): + initial_slashes = path[:-len(path.lstrip('/'))] + newpath = ( + initial_slashes + + urllib.request.url2pathname(path) + .replace('\\', '/').lstrip('/') + ) + after_plus = scheme.find('+') + 1 + url = scheme[:after_plus] + urlunsplit( + (scheme[after_plus:], netloc, newpath, query, fragment), + ) + + if '://' not in url: + assert 'file:' not in url + url = url.replace('git+', 'git+ssh://') + url, rev, user_pass = super().get_url_rev_and_auth(url) + url = url.replace('ssh://', '') + else: + url, rev, user_pass = super().get_url_rev_and_auth(url) + + return url, rev, user_pass + + @classmethod + def update_submodules(cls, location): + if not os.path.exists(os.path.join(location, '.gitmodules')): + return + cls.run_command( + ['submodule', 'update', '--init', '--recursive', '-q'], + cwd=location, + ) + + @classmethod + def get_repository_root(cls, location): + loc = super().get_repository_root(location) + if loc: + return loc + try: + r = cls.run_command( + ['rev-parse', '--show-toplevel'], + cwd=location, + show_stdout=False, + stdout_only=True, + on_returncode='raise', + log_failed_cmd=False, + ) + except BadCommand: + logger.debug("could not determine if %s is under git control " + "because git is not available", location) + return None + except InstallationError: + return None + return os.path.normpath(r.rstrip('\r\n')) + + +vcs.register(Git) diff --git a/venv/Lib/site-packages/pip/_internal/vcs/mercurial.py b/venv/Lib/site-packages/pip/_internal/vcs/mercurial.py new file mode 100644 index 0000000..ae7dd7b --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/vcs/mercurial.py @@ -0,0 +1,171 @@ +# The following comment should be removed at some point in the future. +# mypy: disallow-untyped-defs=False + +import configparser +import logging +import os + +from pip._internal.exceptions import BadCommand, InstallationError +from pip._internal.utils.misc import display_path +from pip._internal.utils.subprocess import make_command +from pip._internal.utils.temp_dir import TempDirectory +from pip._internal.utils.typing import MYPY_CHECK_RUNNING +from pip._internal.utils.urls import path_to_url +from pip._internal.vcs.versioncontrol import ( + VersionControl, + find_path_to_setup_from_repo_root, + vcs, +) + +if MYPY_CHECK_RUNNING: + from pip._internal.utils.misc import HiddenText + from pip._internal.vcs.versioncontrol import RevOptions + + +logger = logging.getLogger(__name__) + + +class Mercurial(VersionControl): + name = 'hg' + dirname = '.hg' + repo_name = 'clone' + schemes = ( + 'hg+file', 'hg+http', 'hg+https', 'hg+ssh', 'hg+static-http', + ) + + @staticmethod + def get_base_rev_args(rev): + return [rev] + + def export(self, location, url): + # type: (str, HiddenText) -> None + """Export the Hg repository at the url to the destination location""" + with TempDirectory(kind="export") as temp_dir: + self.unpack(temp_dir.path, url=url) + + self.run_command( + ['archive', location], show_stdout=False, cwd=temp_dir.path + ) + + def fetch_new(self, dest, url, rev_options): + # type: (str, HiddenText, RevOptions) -> None + rev_display = rev_options.to_display() + logger.info( + 'Cloning hg %s%s to %s', + url, + rev_display, + display_path(dest), + ) + self.run_command(make_command('clone', '--noupdate', '-q', url, dest)) + self.run_command( + make_command('update', '-q', rev_options.to_args()), + cwd=dest, + ) + + def switch(self, dest, url, rev_options): + # type: (str, HiddenText, RevOptions) -> None + repo_config = os.path.join(dest, self.dirname, 'hgrc') + config = configparser.RawConfigParser() + try: + config.read(repo_config) + config.set('paths', 'default', url.secret) + with open(repo_config, 'w') as config_file: + config.write(config_file) + except (OSError, configparser.NoSectionError) as exc: + logger.warning( + 'Could not switch Mercurial repository to %s: %s', url, exc, + ) + else: + cmd_args = make_command('update', '-q', rev_options.to_args()) + self.run_command(cmd_args, cwd=dest) + + def update(self, dest, url, rev_options): + # type: (str, HiddenText, RevOptions) -> None + self.run_command(['pull', '-q'], cwd=dest) + cmd_args = make_command('update', '-q', rev_options.to_args()) + self.run_command(cmd_args, cwd=dest) + + @classmethod + def get_remote_url(cls, location): + # type: (str) -> str + url = cls.run_command( + ['showconfig', 'paths.default'], + show_stdout=False, + stdout_only=True, + cwd=location, + ).strip() + if cls._is_local_repository(url): + url = path_to_url(url) + return url.strip() + + @classmethod + def get_revision(cls, location): + # type: (str) -> str + """ + Return the repository-local changeset revision number, as an integer. + """ + current_revision = cls.run_command( + ['parents', '--template={rev}'], + show_stdout=False, + stdout_only=True, + cwd=location, + ).strip() + return current_revision + + @classmethod + def get_requirement_revision(cls, location): + """ + Return the changeset identification hash, as a 40-character + hexadecimal string + """ + current_rev_hash = cls.run_command( + ['parents', '--template={node}'], + show_stdout=False, + stdout_only=True, + cwd=location, + ).strip() + return current_rev_hash + + @classmethod + def is_commit_id_equal(cls, dest, name): + """Always assume the versions don't match""" + return False + + @classmethod + def get_subdirectory(cls, location): + """ + Return the path to setup.py, relative to the repo root. + Return None if setup.py is in the repo root. + """ + # find the repo root + repo_root = cls.run_command( + ['root'], show_stdout=False, stdout_only=True, cwd=location + ).strip() + if not os.path.isabs(repo_root): + repo_root = os.path.abspath(os.path.join(location, repo_root)) + return find_path_to_setup_from_repo_root(location, repo_root) + + @classmethod + def get_repository_root(cls, location): + loc = super().get_repository_root(location) + if loc: + return loc + try: + r = cls.run_command( + ['root'], + cwd=location, + show_stdout=False, + stdout_only=True, + on_returncode='raise', + log_failed_cmd=False, + ) + except BadCommand: + logger.debug("could not determine if %s is under hg control " + "because hg is not available", location) + return None + except InstallationError: + return None + return os.path.normpath(r.rstrip('\r\n')) + + +vcs.register(Mercurial) diff --git a/venv/Lib/site-packages/pip/_internal/vcs/subversion.py b/venv/Lib/site-packages/pip/_internal/vcs/subversion.py new file mode 100644 index 0000000..56e8d4b --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/vcs/subversion.py @@ -0,0 +1,346 @@ +# The following comment should be removed at some point in the future. +# mypy: disallow-untyped-defs=False + +import logging +import os +import re + +from pip._internal.utils.logging import indent_log +from pip._internal.utils.misc import ( + display_path, + is_console_interactive, + rmtree, + split_auth_from_netloc, +) +from pip._internal.utils.subprocess import make_command +from pip._internal.utils.typing import MYPY_CHECK_RUNNING +from pip._internal.vcs.versioncontrol import RemoteNotFoundError, VersionControl, vcs + +_svn_xml_url_re = re.compile('url="([^"]+)"') +_svn_rev_re = re.compile(r'committed-rev="(\d+)"') +_svn_info_xml_rev_re = re.compile(r'\s*revision="(\d+)"') +_svn_info_xml_url_re = re.compile(r'(.*)') + + +if MYPY_CHECK_RUNNING: + from typing import Optional, Tuple + + from pip._internal.utils.misc import HiddenText + from pip._internal.utils.subprocess import CommandArgs + from pip._internal.vcs.versioncontrol import AuthInfo, RevOptions + + +logger = logging.getLogger(__name__) + + +class Subversion(VersionControl): + name = 'svn' + dirname = '.svn' + repo_name = 'checkout' + schemes = ( + 'svn+ssh', 'svn+http', 'svn+https', 'svn+svn', 'svn+file' + ) + + @classmethod + def should_add_vcs_url_prefix(cls, remote_url): + return True + + @staticmethod + def get_base_rev_args(rev): + return ['-r', rev] + + @classmethod + def get_revision(cls, location): + # type: (str) -> str + """ + Return the maximum revision for all files under a given location + """ + # Note: taken from setuptools.command.egg_info + revision = 0 + + for base, dirs, _ in os.walk(location): + if cls.dirname not in dirs: + dirs[:] = [] + continue # no sense walking uncontrolled subdirs + dirs.remove(cls.dirname) + entries_fn = os.path.join(base, cls.dirname, 'entries') + if not os.path.exists(entries_fn): + # FIXME: should we warn? + continue + + dirurl, localrev = cls._get_svn_url_rev(base) + + if base == location: + base = dirurl + '/' # save the root url + elif not dirurl or not dirurl.startswith(base): + dirs[:] = [] + continue # not part of the same svn tree, skip it + revision = max(revision, localrev) + return str(revision) + + @classmethod + def get_netloc_and_auth(cls, netloc, scheme): + """ + This override allows the auth information to be passed to svn via the + --username and --password options instead of via the URL. + """ + if scheme == 'ssh': + # The --username and --password options can't be used for + # svn+ssh URLs, so keep the auth information in the URL. + return super().get_netloc_and_auth(netloc, scheme) + + return split_auth_from_netloc(netloc) + + @classmethod + def get_url_rev_and_auth(cls, url): + # type: (str) -> Tuple[str, Optional[str], AuthInfo] + # hotfix the URL scheme after removing svn+ from svn+ssh:// readd it + url, rev, user_pass = super().get_url_rev_and_auth(url) + if url.startswith('ssh://'): + url = 'svn+' + url + return url, rev, user_pass + + @staticmethod + def make_rev_args(username, password): + # type: (Optional[str], Optional[HiddenText]) -> CommandArgs + extra_args = [] # type: CommandArgs + if username: + extra_args += ['--username', username] + if password: + extra_args += ['--password', password] + + return extra_args + + @classmethod + def get_remote_url(cls, location): + # type: (str) -> str + # In cases where the source is in a subdirectory, not alongside + # setup.py we have to look up in the location until we find a real + # setup.py + orig_location = location + while not os.path.exists(os.path.join(location, 'setup.py')): + last_location = location + location = os.path.dirname(location) + if location == last_location: + # We've traversed up to the root of the filesystem without + # finding setup.py + logger.warning( + "Could not find setup.py for directory %s (tried all " + "parent directories)", + orig_location, + ) + raise RemoteNotFoundError + + url, _rev = cls._get_svn_url_rev(location) + if url is None: + raise RemoteNotFoundError + + return url + + @classmethod + def _get_svn_url_rev(cls, location): + from pip._internal.exceptions import InstallationError + + entries_path = os.path.join(location, cls.dirname, 'entries') + if os.path.exists(entries_path): + with open(entries_path) as f: + data = f.read() + else: # subversion >= 1.7 does not have the 'entries' file + data = '' + + if (data.startswith('8') or + data.startswith('9') or + data.startswith('10')): + data = list(map(str.splitlines, data.split('\n\x0c\n'))) + del data[0][0] # get rid of the '8' + url = data[0][3] + revs = [int(d[9]) for d in data if len(d) > 9 and d[9]] + [0] + elif data.startswith('= 1.7 + # Note that using get_remote_call_options is not necessary here + # because `svn info` is being run against a local directory. + # We don't need to worry about making sure interactive mode + # is being used to prompt for passwords, because passwords + # are only potentially needed for remote server requests. + xml = cls.run_command( + ['info', '--xml', location], + show_stdout=False, + stdout_only=True, + ) + url = _svn_info_xml_url_re.search(xml).group(1) + revs = [ + int(m.group(1)) for m in _svn_info_xml_rev_re.finditer(xml) + ] + except InstallationError: + url, revs = None, [] + + if revs: + rev = max(revs) + else: + rev = 0 + + return url, rev + + @classmethod + def is_commit_id_equal(cls, dest, name): + """Always assume the versions don't match""" + return False + + def __init__(self, use_interactive=None): + # type: (bool) -> None + if use_interactive is None: + use_interactive = is_console_interactive() + self.use_interactive = use_interactive + + # This member is used to cache the fetched version of the current + # ``svn`` client. + # Special value definitions: + # None: Not evaluated yet. + # Empty tuple: Could not parse version. + self._vcs_version = None # type: Optional[Tuple[int, ...]] + + super().__init__() + + def call_vcs_version(self): + # type: () -> Tuple[int, ...] + """Query the version of the currently installed Subversion client. + + :return: A tuple containing the parts of the version information or + ``()`` if the version returned from ``svn`` could not be parsed. + :raises: BadCommand: If ``svn`` is not installed. + """ + # Example versions: + # svn, version 1.10.3 (r1842928) + # compiled Feb 25 2019, 14:20:39 on x86_64-apple-darwin17.0.0 + # svn, version 1.7.14 (r1542130) + # compiled Mar 28 2018, 08:49:13 on x86_64-pc-linux-gnu + # svn, version 1.12.0-SlikSvn (SlikSvn/1.12.0) + # compiled May 28 2019, 13:44:56 on x86_64-microsoft-windows6.2 + version_prefix = 'svn, version ' + version = self.run_command( + ['--version'], show_stdout=False, stdout_only=True + ) + if not version.startswith(version_prefix): + return () + + version = version[len(version_prefix):].split()[0] + version_list = version.partition('-')[0].split('.') + try: + parsed_version = tuple(map(int, version_list)) + except ValueError: + return () + + return parsed_version + + def get_vcs_version(self): + # type: () -> Tuple[int, ...] + """Return the version of the currently installed Subversion client. + + If the version of the Subversion client has already been queried, + a cached value will be used. + + :return: A tuple containing the parts of the version information or + ``()`` if the version returned from ``svn`` could not be parsed. + :raises: BadCommand: If ``svn`` is not installed. + """ + if self._vcs_version is not None: + # Use cached version, if available. + # If parsing the version failed previously (empty tuple), + # do not attempt to parse it again. + return self._vcs_version + + vcs_version = self.call_vcs_version() + self._vcs_version = vcs_version + return vcs_version + + def get_remote_call_options(self): + # type: () -> CommandArgs + """Return options to be used on calls to Subversion that contact the server. + + These options are applicable for the following ``svn`` subcommands used + in this class. + + - checkout + - export + - switch + - update + + :return: A list of command line arguments to pass to ``svn``. + """ + if not self.use_interactive: + # --non-interactive switch is available since Subversion 0.14.4. + # Subversion < 1.8 runs in interactive mode by default. + return ['--non-interactive'] + + svn_version = self.get_vcs_version() + # By default, Subversion >= 1.8 runs in non-interactive mode if + # stdin is not a TTY. Since that is how pip invokes SVN, in + # call_subprocess(), pip must pass --force-interactive to ensure + # the user can be prompted for a password, if required. + # SVN added the --force-interactive option in SVN 1.8. Since + # e.g. RHEL/CentOS 7, which is supported until 2024, ships with + # SVN 1.7, pip should continue to support SVN 1.7. Therefore, pip + # can't safely add the option if the SVN version is < 1.8 (or unknown). + if svn_version >= (1, 8): + return ['--force-interactive'] + + return [] + + def export(self, location, url): + # type: (str, HiddenText) -> None + """Export the svn repository at the url to the destination location""" + url, rev_options = self.get_url_rev_options(url) + + logger.info('Exporting svn repository %s to %s', url, location) + with indent_log(): + if os.path.exists(location): + # Subversion doesn't like to check out over an existing + # directory --force fixes this, but was only added in svn 1.5 + rmtree(location) + cmd_args = make_command( + 'export', self.get_remote_call_options(), + rev_options.to_args(), url, location, + ) + self.run_command(cmd_args, show_stdout=False) + + def fetch_new(self, dest, url, rev_options): + # type: (str, HiddenText, RevOptions) -> None + rev_display = rev_options.to_display() + logger.info( + 'Checking out %s%s to %s', + url, + rev_display, + display_path(dest), + ) + cmd_args = make_command( + 'checkout', '-q', self.get_remote_call_options(), + rev_options.to_args(), url, dest, + ) + self.run_command(cmd_args) + + def switch(self, dest, url, rev_options): + # type: (str, HiddenText, RevOptions) -> None + cmd_args = make_command( + 'switch', self.get_remote_call_options(), rev_options.to_args(), + url, dest, + ) + self.run_command(cmd_args) + + def update(self, dest, url, rev_options): + # type: (str, HiddenText, RevOptions) -> None + cmd_args = make_command( + 'update', self.get_remote_call_options(), rev_options.to_args(), + dest, + ) + self.run_command(cmd_args) + + +vcs.register(Subversion) diff --git a/venv/Lib/site-packages/pip/_internal/vcs/versioncontrol.py b/venv/Lib/site-packages/pip/_internal/vcs/versioncontrol.py new file mode 100644 index 0000000..218de58 --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/vcs/versioncontrol.py @@ -0,0 +1,722 @@ +"""Handles all VCS (version control) support""" + +import logging +import os +import shutil +import sys +import urllib.parse + +from pip._vendor import pkg_resources + +from pip._internal.exceptions import BadCommand, InstallationError +from pip._internal.utils.misc import ( + ask_path_exists, + backup_dir, + display_path, + hide_url, + hide_value, + rmtree, +) +from pip._internal.utils.subprocess import call_subprocess, make_command +from pip._internal.utils.typing import MYPY_CHECK_RUNNING +from pip._internal.utils.urls import get_url_scheme + +if MYPY_CHECK_RUNNING: + from typing import ( + Any, + Dict, + Iterable, + Iterator, + List, + Mapping, + Optional, + Tuple, + Type, + Union, + ) + + from pip._internal.cli.spinners import SpinnerInterface + from pip._internal.utils.misc import HiddenText + from pip._internal.utils.subprocess import CommandArgs + + AuthInfo = Tuple[Optional[str], Optional[str]] + + +__all__ = ['vcs'] + + +logger = logging.getLogger(__name__) + + +def is_url(name): + # type: (str) -> bool + """ + Return true if the name looks like a URL. + """ + scheme = get_url_scheme(name) + if scheme is None: + return False + return scheme in ['http', 'https', 'file', 'ftp'] + vcs.all_schemes + + +def make_vcs_requirement_url(repo_url, rev, project_name, subdir=None): + # type: (str, str, str, Optional[str]) -> str + """ + Return the URL for a VCS requirement. + + Args: + repo_url: the remote VCS url, with any needed VCS prefix (e.g. "git+"). + project_name: the (unescaped) project name. + """ + egg_project_name = pkg_resources.to_filename(project_name) + req = f'{repo_url}@{rev}#egg={egg_project_name}' + if subdir: + req += f'&subdirectory={subdir}' + + return req + + +def find_path_to_setup_from_repo_root(location, repo_root): + # type: (str, str) -> Optional[str] + """ + Find the path to `setup.py` by searching up the filesystem from `location`. + Return the path to `setup.py` relative to `repo_root`. + Return None if `setup.py` is in `repo_root` or cannot be found. + """ + # find setup.py + orig_location = location + while not os.path.exists(os.path.join(location, 'setup.py')): + last_location = location + location = os.path.dirname(location) + if location == last_location: + # We've traversed up to the root of the filesystem without + # finding setup.py + logger.warning( + "Could not find setup.py for directory %s (tried all " + "parent directories)", + orig_location, + ) + return None + + if os.path.samefile(repo_root, location): + return None + + return os.path.relpath(location, repo_root) + + +class RemoteNotFoundError(Exception): + pass + + +class RevOptions: + + """ + Encapsulates a VCS-specific revision to install, along with any VCS + install options. + + Instances of this class should be treated as if immutable. + """ + + def __init__( + self, + vc_class, # type: Type[VersionControl] + rev=None, # type: Optional[str] + extra_args=None, # type: Optional[CommandArgs] + ): + # type: (...) -> None + """ + Args: + vc_class: a VersionControl subclass. + rev: the name of the revision to install. + extra_args: a list of extra options. + """ + if extra_args is None: + extra_args = [] + + self.extra_args = extra_args + self.rev = rev + self.vc_class = vc_class + self.branch_name = None # type: Optional[str] + + def __repr__(self): + # type: () -> str + return f'' + + @property + def arg_rev(self): + # type: () -> Optional[str] + if self.rev is None: + return self.vc_class.default_arg_rev + + return self.rev + + def to_args(self): + # type: () -> CommandArgs + """ + Return the VCS-specific command arguments. + """ + args = [] # type: CommandArgs + rev = self.arg_rev + if rev is not None: + args += self.vc_class.get_base_rev_args(rev) + args += self.extra_args + + return args + + def to_display(self): + # type: () -> str + if not self.rev: + return '' + + return f' (to revision {self.rev})' + + def make_new(self, rev): + # type: (str) -> RevOptions + """ + Make a copy of the current instance, but with a new rev. + + Args: + rev: the name of the revision for the new object. + """ + return self.vc_class.make_rev_options(rev, extra_args=self.extra_args) + + +class VcsSupport: + _registry = {} # type: Dict[str, VersionControl] + schemes = ['ssh', 'git', 'hg', 'bzr', 'sftp', 'svn'] + + def __init__(self): + # type: () -> None + # Register more schemes with urlparse for various version control + # systems + urllib.parse.uses_netloc.extend(self.schemes) + super().__init__() + + def __iter__(self): + # type: () -> Iterator[str] + return self._registry.__iter__() + + @property + def backends(self): + # type: () -> List[VersionControl] + return list(self._registry.values()) + + @property + def dirnames(self): + # type: () -> List[str] + return [backend.dirname for backend in self.backends] + + @property + def all_schemes(self): + # type: () -> List[str] + schemes = [] # type: List[str] + for backend in self.backends: + schemes.extend(backend.schemes) + return schemes + + def register(self, cls): + # type: (Type[VersionControl]) -> None + if not hasattr(cls, 'name'): + logger.warning('Cannot register VCS %s', cls.__name__) + return + if cls.name not in self._registry: + self._registry[cls.name] = cls() + logger.debug('Registered VCS backend: %s', cls.name) + + def unregister(self, name): + # type: (str) -> None + if name in self._registry: + del self._registry[name] + + def get_backend_for_dir(self, location): + # type: (str) -> Optional[VersionControl] + """ + Return a VersionControl object if a repository of that type is found + at the given directory. + """ + vcs_backends = {} + for vcs_backend in self._registry.values(): + repo_path = vcs_backend.get_repository_root(location) + if not repo_path: + continue + logger.debug('Determine that %s uses VCS: %s', + location, vcs_backend.name) + vcs_backends[repo_path] = vcs_backend + + if not vcs_backends: + return None + + # Choose the VCS in the inner-most directory. Since all repository + # roots found here would be either `location` or one of its + # parents, the longest path should have the most path components, + # i.e. the backend representing the inner-most repository. + inner_most_repo_path = max(vcs_backends, key=len) + return vcs_backends[inner_most_repo_path] + + def get_backend_for_scheme(self, scheme): + # type: (str) -> Optional[VersionControl] + """ + Return a VersionControl object or None. + """ + for vcs_backend in self._registry.values(): + if scheme in vcs_backend.schemes: + return vcs_backend + return None + + def get_backend(self, name): + # type: (str) -> Optional[VersionControl] + """ + Return a VersionControl object or None. + """ + name = name.lower() + return self._registry.get(name) + + +vcs = VcsSupport() + + +class VersionControl: + name = '' + dirname = '' + repo_name = '' + # List of supported schemes for this Version Control + schemes = () # type: Tuple[str, ...] + # Iterable of environment variable names to pass to call_subprocess(). + unset_environ = () # type: Tuple[str, ...] + default_arg_rev = None # type: Optional[str] + + @classmethod + def should_add_vcs_url_prefix(cls, remote_url): + # type: (str) -> bool + """ + Return whether the vcs prefix (e.g. "git+") should be added to a + repository's remote url when used in a requirement. + """ + return not remote_url.lower().startswith(f'{cls.name}:') + + @classmethod + def get_subdirectory(cls, location): + # type: (str) -> Optional[str] + """ + Return the path to setup.py, relative to the repo root. + Return None if setup.py is in the repo root. + """ + return None + + @classmethod + def get_requirement_revision(cls, repo_dir): + # type: (str) -> str + """ + Return the revision string that should be used in a requirement. + """ + return cls.get_revision(repo_dir) + + @classmethod + def get_src_requirement(cls, repo_dir, project_name): + # type: (str, str) -> str + """ + Return the requirement string to use to redownload the files + currently at the given repository directory. + + Args: + project_name: the (unescaped) project name. + + The return value has a form similar to the following: + + {repository_url}@{revision}#egg={project_name} + """ + repo_url = cls.get_remote_url(repo_dir) + + if cls.should_add_vcs_url_prefix(repo_url): + repo_url = f'{cls.name}+{repo_url}' + + revision = cls.get_requirement_revision(repo_dir) + subdir = cls.get_subdirectory(repo_dir) + req = make_vcs_requirement_url(repo_url, revision, project_name, + subdir=subdir) + + return req + + @staticmethod + def get_base_rev_args(rev): + # type: (str) -> List[str] + """ + Return the base revision arguments for a vcs command. + + Args: + rev: the name of a revision to install. Cannot be None. + """ + raise NotImplementedError + + def is_immutable_rev_checkout(self, url, dest): + # type: (str, str) -> bool + """ + Return true if the commit hash checked out at dest matches + the revision in url. + + Always return False, if the VCS does not support immutable commit + hashes. + + This method does not check if there are local uncommitted changes + in dest after checkout, as pip currently has no use case for that. + """ + return False + + @classmethod + def make_rev_options(cls, rev=None, extra_args=None): + # type: (Optional[str], Optional[CommandArgs]) -> RevOptions + """ + Return a RevOptions object. + + Args: + rev: the name of a revision to install. + extra_args: a list of extra options. + """ + return RevOptions(cls, rev, extra_args=extra_args) + + @classmethod + def _is_local_repository(cls, repo): + # type: (str) -> bool + """ + posix absolute paths start with os.path.sep, + win32 ones start with drive (like c:\\folder) + """ + drive, tail = os.path.splitdrive(repo) + return repo.startswith(os.path.sep) or bool(drive) + + def export(self, location, url): + # type: (str, HiddenText) -> None + """ + Export the repository at the url to the destination location + i.e. only download the files, without vcs informations + + :param url: the repository URL starting with a vcs prefix. + """ + raise NotImplementedError + + @classmethod + def get_netloc_and_auth(cls, netloc, scheme): + # type: (str, str) -> Tuple[str, Tuple[Optional[str], Optional[str]]] + """ + Parse the repository URL's netloc, and return the new netloc to use + along with auth information. + + Args: + netloc: the original repository URL netloc. + scheme: the repository URL's scheme without the vcs prefix. + + This is mainly for the Subversion class to override, so that auth + information can be provided via the --username and --password options + instead of through the URL. For other subclasses like Git without + such an option, auth information must stay in the URL. + + Returns: (netloc, (username, password)). + """ + return netloc, (None, None) + + @classmethod + def get_url_rev_and_auth(cls, url): + # type: (str) -> Tuple[str, Optional[str], AuthInfo] + """ + Parse the repository URL to use, and return the URL, revision, + and auth info to use. + + Returns: (url, rev, (username, password)). + """ + scheme, netloc, path, query, frag = urllib.parse.urlsplit(url) + if '+' not in scheme: + raise ValueError( + "Sorry, {!r} is a malformed VCS url. " + "The format is +://, " + "e.g. svn+http://myrepo/svn/MyApp#egg=MyApp".format(url) + ) + # Remove the vcs prefix. + scheme = scheme.split('+', 1)[1] + netloc, user_pass = cls.get_netloc_and_auth(netloc, scheme) + rev = None + if '@' in path: + path, rev = path.rsplit('@', 1) + if not rev: + raise InstallationError( + "The URL {!r} has an empty revision (after @) " + "which is not supported. Include a revision after @ " + "or remove @ from the URL.".format(url) + ) + url = urllib.parse.urlunsplit((scheme, netloc, path, query, '')) + return url, rev, user_pass + + @staticmethod + def make_rev_args(username, password): + # type: (Optional[str], Optional[HiddenText]) -> CommandArgs + """ + Return the RevOptions "extra arguments" to use in obtain(). + """ + return [] + + def get_url_rev_options(self, url): + # type: (HiddenText) -> Tuple[HiddenText, RevOptions] + """ + Return the URL and RevOptions object to use in obtain() and in + some cases export(), as a tuple (url, rev_options). + """ + secret_url, rev, user_pass = self.get_url_rev_and_auth(url.secret) + username, secret_password = user_pass + password = None # type: Optional[HiddenText] + if secret_password is not None: + password = hide_value(secret_password) + extra_args = self.make_rev_args(username, password) + rev_options = self.make_rev_options(rev, extra_args=extra_args) + + return hide_url(secret_url), rev_options + + @staticmethod + def normalize_url(url): + # type: (str) -> str + """ + Normalize a URL for comparison by unquoting it and removing any + trailing slash. + """ + return urllib.parse.unquote(url).rstrip('/') + + @classmethod + def compare_urls(cls, url1, url2): + # type: (str, str) -> bool + """ + Compare two repo URLs for identity, ignoring incidental differences. + """ + return (cls.normalize_url(url1) == cls.normalize_url(url2)) + + def fetch_new(self, dest, url, rev_options): + # type: (str, HiddenText, RevOptions) -> None + """ + Fetch a revision from a repository, in the case that this is the + first fetch from the repository. + + Args: + dest: the directory to fetch the repository to. + rev_options: a RevOptions object. + """ + raise NotImplementedError + + def switch(self, dest, url, rev_options): + # type: (str, HiddenText, RevOptions) -> None + """ + Switch the repo at ``dest`` to point to ``URL``. + + Args: + rev_options: a RevOptions object. + """ + raise NotImplementedError + + def update(self, dest, url, rev_options): + # type: (str, HiddenText, RevOptions) -> None + """ + Update an already-existing repo to the given ``rev_options``. + + Args: + rev_options: a RevOptions object. + """ + raise NotImplementedError + + @classmethod + def is_commit_id_equal(cls, dest, name): + # type: (str, Optional[str]) -> bool + """ + Return whether the id of the current commit equals the given name. + + Args: + dest: the repository directory. + name: a string name. + """ + raise NotImplementedError + + def obtain(self, dest, url): + # type: (str, HiddenText) -> None + """ + Install or update in editable mode the package represented by this + VersionControl object. + + :param dest: the repository directory in which to install or update. + :param url: the repository URL starting with a vcs prefix. + """ + url, rev_options = self.get_url_rev_options(url) + + if not os.path.exists(dest): + self.fetch_new(dest, url, rev_options) + return + + rev_display = rev_options.to_display() + if self.is_repository_directory(dest): + existing_url = self.get_remote_url(dest) + if self.compare_urls(existing_url, url.secret): + logger.debug( + '%s in %s exists, and has correct URL (%s)', + self.repo_name.title(), + display_path(dest), + url, + ) + if not self.is_commit_id_equal(dest, rev_options.rev): + logger.info( + 'Updating %s %s%s', + display_path(dest), + self.repo_name, + rev_display, + ) + self.update(dest, url, rev_options) + else: + logger.info('Skipping because already up-to-date.') + return + + logger.warning( + '%s %s in %s exists with URL %s', + self.name, + self.repo_name, + display_path(dest), + existing_url, + ) + prompt = ('(s)witch, (i)gnore, (w)ipe, (b)ackup ', + ('s', 'i', 'w', 'b')) + else: + logger.warning( + 'Directory %s already exists, and is not a %s %s.', + dest, + self.name, + self.repo_name, + ) + # https://github.com/python/mypy/issues/1174 + prompt = ('(i)gnore, (w)ipe, (b)ackup ', # type: ignore + ('i', 'w', 'b')) + + logger.warning( + 'The plan is to install the %s repository %s', + self.name, + url, + ) + response = ask_path_exists('What to do? {}'.format( + prompt[0]), prompt[1]) + + if response == 'a': + sys.exit(-1) + + if response == 'w': + logger.warning('Deleting %s', display_path(dest)) + rmtree(dest) + self.fetch_new(dest, url, rev_options) + return + + if response == 'b': + dest_dir = backup_dir(dest) + logger.warning( + 'Backing up %s to %s', display_path(dest), dest_dir, + ) + shutil.move(dest, dest_dir) + self.fetch_new(dest, url, rev_options) + return + + # Do nothing if the response is "i". + if response == 's': + logger.info( + 'Switching %s %s to %s%s', + self.repo_name, + display_path(dest), + url, + rev_display, + ) + self.switch(dest, url, rev_options) + + def unpack(self, location, url): + # type: (str, HiddenText) -> None + """ + Clean up current location and download the url repository + (and vcs infos) into location + + :param url: the repository URL starting with a vcs prefix. + """ + if os.path.exists(location): + rmtree(location) + self.obtain(location, url=url) + + @classmethod + def get_remote_url(cls, location): + # type: (str) -> str + """ + Return the url used at location + + Raises RemoteNotFoundError if the repository does not have a remote + url configured. + """ + raise NotImplementedError + + @classmethod + def get_revision(cls, location): + # type: (str) -> str + """ + Return the current commit id of the files at the given location. + """ + raise NotImplementedError + + @classmethod + def run_command( + cls, + cmd, # type: Union[List[str], CommandArgs] + show_stdout=True, # type: bool + cwd=None, # type: Optional[str] + on_returncode='raise', # type: str + extra_ok_returncodes=None, # type: Optional[Iterable[int]] + command_desc=None, # type: Optional[str] + extra_environ=None, # type: Optional[Mapping[str, Any]] + spinner=None, # type: Optional[SpinnerInterface] + log_failed_cmd=True, # type: bool + stdout_only=False, # type: bool + ): + # type: (...) -> str + """ + Run a VCS subcommand + This is simply a wrapper around call_subprocess that adds the VCS + command name, and checks that the VCS is available + """ + cmd = make_command(cls.name, *cmd) + try: + return call_subprocess(cmd, show_stdout, cwd, + on_returncode=on_returncode, + extra_ok_returncodes=extra_ok_returncodes, + command_desc=command_desc, + extra_environ=extra_environ, + unset_environ=cls.unset_environ, + spinner=spinner, + log_failed_cmd=log_failed_cmd, + stdout_only=stdout_only) + except FileNotFoundError: + # errno.ENOENT = no such file or directory + # In other words, the VCS executable isn't available + raise BadCommand( + 'Cannot find command {cls.name!r} - do you have ' + '{cls.name!r} installed and in your ' + 'PATH?'.format(**locals())) + + @classmethod + def is_repository_directory(cls, path): + # type: (str) -> bool + """ + Return whether a directory path is a repository directory. + """ + logger.debug('Checking in %s for %s (%s)...', + path, cls.dirname, cls.name) + return os.path.exists(os.path.join(path, cls.dirname)) + + @classmethod + def get_repository_root(cls, location): + # type: (str) -> Optional[str] + """ + Return the "root" (top-level) directory controlled by the vcs, + or `None` if the directory is not in any. + + It is meant to be overridden to implement smarter detection + mechanisms for specific vcs. + + This can do more than is_repository_directory() alone. For + example, the Git override checks that Git is actually available. + """ + if cls.is_repository_directory(location): + return location + return None diff --git a/venv/Lib/site-packages/pip/_internal/wheel_builder.py b/venv/Lib/site-packages/pip/_internal/wheel_builder.py new file mode 100644 index 0000000..c23ee1b --- /dev/null +++ b/venv/Lib/site-packages/pip/_internal/wheel_builder.py @@ -0,0 +1,365 @@ +"""Orchestrator for building wheels from InstallRequirements. +""" + +import logging +import os.path +import re +import shutil +import zipfile + +from pip._vendor.packaging.utils import canonicalize_name, canonicalize_version +from pip._vendor.packaging.version import InvalidVersion, Version +from pip._vendor.pkg_resources import Distribution + +from pip._internal.exceptions import InvalidWheelFilename, UnsupportedWheel +from pip._internal.models.link import Link +from pip._internal.models.wheel import Wheel +from pip._internal.operations.build.wheel import build_wheel_pep517 +from pip._internal.operations.build.wheel_legacy import build_wheel_legacy +from pip._internal.utils.logging import indent_log +from pip._internal.utils.misc import ensure_dir, hash_file, is_wheel_installed +from pip._internal.utils.setuptools_build import make_setuptools_clean_args +from pip._internal.utils.subprocess import call_subprocess +from pip._internal.utils.temp_dir import TempDirectory +from pip._internal.utils.typing import MYPY_CHECK_RUNNING +from pip._internal.utils.urls import path_to_url +from pip._internal.utils.wheel import pkg_resources_distribution_for_wheel +from pip._internal.vcs import vcs + +if MYPY_CHECK_RUNNING: + from typing import Any, Callable, Iterable, List, Optional, Tuple + + from pip._internal.cache import WheelCache + from pip._internal.req.req_install import InstallRequirement + + BinaryAllowedPredicate = Callable[[InstallRequirement], bool] + BuildResult = Tuple[List[InstallRequirement], List[InstallRequirement]] + +logger = logging.getLogger(__name__) + +_egg_info_re = re.compile(r'([a-z0-9_.]+)-([a-z0-9_.!+-]+)', re.IGNORECASE) + + +def _contains_egg_info(s): + # type: (str) -> bool + """Determine whether the string looks like an egg_info. + + :param s: The string to parse. E.g. foo-2.1 + """ + return bool(_egg_info_re.search(s)) + + +def _should_build( + req, # type: InstallRequirement + need_wheel, # type: bool + check_binary_allowed, # type: BinaryAllowedPredicate +): + # type: (...) -> bool + """Return whether an InstallRequirement should be built into a wheel.""" + if req.constraint: + # never build requirements that are merely constraints + return False + if req.is_wheel: + if need_wheel: + logger.info( + 'Skipping %s, due to already being wheel.', req.name, + ) + return False + + if need_wheel: + # i.e. pip wheel, not pip install + return True + + # From this point, this concerns the pip install command only + # (need_wheel=False). + + if req.editable or not req.source_dir: + return False + + if req.use_pep517: + return True + + if not check_binary_allowed(req): + logger.info( + "Skipping wheel build for %s, due to binaries " + "being disabled for it.", req.name, + ) + return False + + if not is_wheel_installed(): + # we don't build legacy requirements if wheel is not installed + logger.info( + "Using legacy 'setup.py install' for %s, " + "since package 'wheel' is not installed.", req.name, + ) + return False + + return True + + +def should_build_for_wheel_command( + req, # type: InstallRequirement +): + # type: (...) -> bool + return _should_build( + req, need_wheel=True, check_binary_allowed=_always_true + ) + + +def should_build_for_install_command( + req, # type: InstallRequirement + check_binary_allowed, # type: BinaryAllowedPredicate +): + # type: (...) -> bool + return _should_build( + req, need_wheel=False, check_binary_allowed=check_binary_allowed + ) + + +def _should_cache( + req, # type: InstallRequirement +): + # type: (...) -> Optional[bool] + """ + Return whether a built InstallRequirement can be stored in the persistent + wheel cache, assuming the wheel cache is available, and _should_build() + has determined a wheel needs to be built. + """ + if req.editable or not req.source_dir: + # never cache editable requirements + return False + + if req.link and req.link.is_vcs: + # VCS checkout. Do not cache + # unless it points to an immutable commit hash. + assert not req.editable + assert req.source_dir + vcs_backend = vcs.get_backend_for_scheme(req.link.scheme) + assert vcs_backend + if vcs_backend.is_immutable_rev_checkout(req.link.url, req.source_dir): + return True + return False + + assert req.link + base, ext = req.link.splitext() + if _contains_egg_info(base): + return True + + # Otherwise, do not cache. + return False + + +def _get_cache_dir( + req, # type: InstallRequirement + wheel_cache, # type: WheelCache +): + # type: (...) -> str + """Return the persistent or temporary cache directory where the built + wheel need to be stored. + """ + cache_available = bool(wheel_cache.cache_dir) + assert req.link + if cache_available and _should_cache(req): + cache_dir = wheel_cache.get_path_for_link(req.link) + else: + cache_dir = wheel_cache.get_ephem_path_for_link(req.link) + return cache_dir + + +def _always_true(_): + # type: (Any) -> bool + return True + + +def _get_metadata_version(dist): + # type: (Distribution) -> Optional[Version] + for line in dist.get_metadata_lines(dist.PKG_INFO): + if line.lower().startswith("metadata-version:"): + value = line.split(":", 1)[-1].strip() + try: + return Version(value) + except InvalidVersion: + msg = "Invalid Metadata-Version: {}".format(value) + raise UnsupportedWheel(msg) + raise UnsupportedWheel("Missing Metadata-Version") + + +def _verify_one(req, wheel_path): + # type: (InstallRequirement, str) -> None + canonical_name = canonicalize_name(req.name) + w = Wheel(os.path.basename(wheel_path)) + if canonicalize_name(w.name) != canonical_name: + raise InvalidWheelFilename( + "Wheel has unexpected file name: expected {!r}, " + "got {!r}".format(canonical_name, w.name), + ) + with zipfile.ZipFile(wheel_path, allowZip64=True) as zf: + dist = pkg_resources_distribution_for_wheel( + zf, canonical_name, wheel_path, + ) + if canonicalize_version(dist.version) != canonicalize_version(w.version): + raise InvalidWheelFilename( + "Wheel has unexpected file name: expected {!r}, " + "got {!r}".format(dist.version, w.version), + ) + if (_get_metadata_version(dist) >= Version("1.2") + and not isinstance(dist.parsed_version, Version)): + raise UnsupportedWheel( + "Metadata 1.2 mandates PEP 440 version, " + "but {!r} is not".format(dist.version) + ) + + +def _build_one( + req, # type: InstallRequirement + output_dir, # type: str + verify, # type: bool + build_options, # type: List[str] + global_options, # type: List[str] +): + # type: (...) -> Optional[str] + """Build one wheel. + + :return: The filename of the built wheel, or None if the build failed. + """ + try: + ensure_dir(output_dir) + except OSError as e: + logger.warning( + "Building wheel for %s failed: %s", + req.name, e, + ) + return None + + # Install build deps into temporary directory (PEP 518) + with req.build_env: + wheel_path = _build_one_inside_env( + req, output_dir, build_options, global_options + ) + if wheel_path and verify: + try: + _verify_one(req, wheel_path) + except (InvalidWheelFilename, UnsupportedWheel) as e: + logger.warning("Built wheel for %s is invalid: %s", req.name, e) + return None + return wheel_path + + +def _build_one_inside_env( + req, # type: InstallRequirement + output_dir, # type: str + build_options, # type: List[str] + global_options, # type: List[str] +): + # type: (...) -> Optional[str] + with TempDirectory(kind="wheel") as temp_dir: + assert req.name + if req.use_pep517: + assert req.metadata_directory + wheel_path = build_wheel_pep517( + name=req.name, + backend=req.pep517_backend, + metadata_directory=req.metadata_directory, + build_options=build_options, + tempd=temp_dir.path, + ) + else: + wheel_path = build_wheel_legacy( + name=req.name, + setup_py_path=req.setup_py_path, + source_dir=req.unpacked_source_directory, + global_options=global_options, + build_options=build_options, + tempd=temp_dir.path, + ) + + if wheel_path is not None: + wheel_name = os.path.basename(wheel_path) + dest_path = os.path.join(output_dir, wheel_name) + try: + wheel_hash, length = hash_file(wheel_path) + shutil.move(wheel_path, dest_path) + logger.info('Created wheel for %s: ' + 'filename=%s size=%d sha256=%s', + req.name, wheel_name, length, + wheel_hash.hexdigest()) + logger.info('Stored in directory: %s', output_dir) + return dest_path + except Exception as e: + logger.warning( + "Building wheel for %s failed: %s", + req.name, e, + ) + # Ignore return, we can't do anything else useful. + if not req.use_pep517: + _clean_one_legacy(req, global_options) + return None + + +def _clean_one_legacy(req, global_options): + # type: (InstallRequirement, List[str]) -> bool + clean_args = make_setuptools_clean_args( + req.setup_py_path, + global_options=global_options, + ) + + logger.info('Running setup.py clean for %s', req.name) + try: + call_subprocess(clean_args, cwd=req.source_dir) + return True + except Exception: + logger.error('Failed cleaning build dir for %s', req.name) + return False + + +def build( + requirements, # type: Iterable[InstallRequirement] + wheel_cache, # type: WheelCache + verify, # type: bool + build_options, # type: List[str] + global_options, # type: List[str] +): + # type: (...) -> BuildResult + """Build wheels. + + :return: The list of InstallRequirement that succeeded to build and + the list of InstallRequirement that failed to build. + """ + if not requirements: + return [], [] + + # Build the wheels. + logger.info( + 'Building wheels for collected packages: %s', + ', '.join(req.name for req in requirements), # type: ignore + ) + + with indent_log(): + build_successes, build_failures = [], [] + for req in requirements: + cache_dir = _get_cache_dir(req, wheel_cache) + wheel_file = _build_one( + req, cache_dir, verify, build_options, global_options + ) + if wheel_file: + # Update the link for this. + req.link = Link(path_to_url(wheel_file)) + req.local_file_path = req.link.file_path + assert req.link.is_wheel + build_successes.append(req) + else: + build_failures.append(req) + + # notify success/failure + if build_successes: + logger.info( + 'Successfully built %s', + ' '.join([req.name for req in build_successes]), # type: ignore + ) + if build_failures: + logger.info( + 'Failed to build %s', + ' '.join([req.name for req in build_failures]), # type: ignore + ) + # Return a list of requirements that failed to build + return build_successes, build_failures diff --git a/venv/Lib/site-packages/pip/_vendor/__init__.py b/venv/Lib/site-packages/pip/_vendor/__init__.py new file mode 100644 index 0000000..c3db83f --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/__init__.py @@ -0,0 +1,114 @@ +""" +pip._vendor is for vendoring dependencies of pip to prevent needing pip to +depend on something external. + +Files inside of pip._vendor should be considered immutable and should only be +updated to versions from upstream. +""" +from __future__ import absolute_import + +import glob +import os.path +import sys + +# Downstream redistributors which have debundled our dependencies should also +# patch this value to be true. This will trigger the additional patching +# to cause things like "six" to be available as pip. +DEBUNDLED = False + +# By default, look in this directory for a bunch of .whl files which we will +# add to the beginning of sys.path before attempting to import anything. This +# is done to support downstream re-distributors like Debian and Fedora who +# wish to create their own Wheels for our dependencies to aid in debundling. +WHEEL_DIR = os.path.abspath(os.path.dirname(__file__)) + + +# Define a small helper function to alias our vendored modules to the real ones +# if the vendored ones do not exist. This idea of this was taken from +# https://github.com/kennethreitz/requests/pull/2567. +def vendored(modulename): + vendored_name = "{0}.{1}".format(__name__, modulename) + + try: + __import__(modulename, globals(), locals(), level=0) + except ImportError: + # We can just silently allow import failures to pass here. If we + # got to this point it means that ``import pip._vendor.whatever`` + # failed and so did ``import whatever``. Since we're importing this + # upfront in an attempt to alias imports, not erroring here will + # just mean we get a regular import error whenever pip *actually* + # tries to import one of these modules to use it, which actually + # gives us a better error message than we would have otherwise + # gotten. + pass + else: + sys.modules[vendored_name] = sys.modules[modulename] + base, head = vendored_name.rsplit(".", 1) + setattr(sys.modules[base], head, sys.modules[modulename]) + + +# If we're operating in a debundled setup, then we want to go ahead and trigger +# the aliasing of our vendored libraries as well as looking for wheels to add +# to our sys.path. This will cause all of this code to be a no-op typically +# however downstream redistributors can enable it in a consistent way across +# all platforms. +if DEBUNDLED: + # Actually look inside of WHEEL_DIR to find .whl files and add them to the + # front of our sys.path. + sys.path[:] = glob.glob(os.path.join(WHEEL_DIR, "*.whl")) + sys.path + + # Actually alias all of our vendored dependencies. + vendored("appdirs") + vendored("cachecontrol") + vendored("certifi") + vendored("colorama") + vendored("contextlib2") + vendored("distlib") + vendored("distro") + vendored("html5lib") + vendored("six") + vendored("six.moves") + vendored("six.moves.urllib") + vendored("six.moves.urllib.parse") + vendored("packaging") + vendored("packaging.version") + vendored("packaging.specifiers") + vendored("pep517") + vendored("pkg_resources") + vendored("progress") + vendored("retrying") + vendored("requests") + vendored("requests.exceptions") + vendored("requests.packages") + vendored("requests.packages.urllib3") + vendored("requests.packages.urllib3._collections") + vendored("requests.packages.urllib3.connection") + vendored("requests.packages.urllib3.connectionpool") + vendored("requests.packages.urllib3.contrib") + vendored("requests.packages.urllib3.contrib.ntlmpool") + vendored("requests.packages.urllib3.contrib.pyopenssl") + vendored("requests.packages.urllib3.exceptions") + vendored("requests.packages.urllib3.fields") + vendored("requests.packages.urllib3.filepost") + vendored("requests.packages.urllib3.packages") + vendored("requests.packages.urllib3.packages.ordered_dict") + vendored("requests.packages.urllib3.packages.six") + vendored("requests.packages.urllib3.packages.ssl_match_hostname") + vendored("requests.packages.urllib3.packages.ssl_match_hostname." + "_implementation") + vendored("requests.packages.urllib3.poolmanager") + vendored("requests.packages.urllib3.request") + vendored("requests.packages.urllib3.response") + vendored("requests.packages.urllib3.util") + vendored("requests.packages.urllib3.util.connection") + vendored("requests.packages.urllib3.util.request") + vendored("requests.packages.urllib3.util.response") + vendored("requests.packages.urllib3.util.retry") + vendored("requests.packages.urllib3.util.ssl_") + vendored("requests.packages.urllib3.util.timeout") + vendored("requests.packages.urllib3.util.url") + vendored("resolvelib") + vendored("toml") + vendored("toml.encoder") + vendored("toml.decoder") + vendored("urllib3") diff --git a/venv/Lib/site-packages/pip/_vendor/appdirs.py b/venv/Lib/site-packages/pip/_vendor/appdirs.py new file mode 100644 index 0000000..33a3b77 --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/appdirs.py @@ -0,0 +1,633 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Copyright (c) 2005-2010 ActiveState Software Inc. +# Copyright (c) 2013 Eddy PetriÈ™or + +"""Utilities for determining application-specific dirs. + +See for details and usage. +""" +# Dev Notes: +# - MSDN on where to store app data files: +# http://support.microsoft.com/default.aspx?scid=kb;en-us;310294#XSLTH3194121123120121120120 +# - Mac OS X: http://developer.apple.com/documentation/MacOSX/Conceptual/BPFileSystem/index.html +# - XDG spec for Un*x: http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html + +__version__ = "1.4.4" +__version_info__ = tuple(int(segment) for segment in __version__.split(".")) + + +import sys +import os + +PY3 = sys.version_info[0] == 3 + +if PY3: + unicode = str + +if sys.platform.startswith('java'): + import platform + os_name = platform.java_ver()[3][0] + if os_name.startswith('Windows'): # "Windows XP", "Windows 7", etc. + system = 'win32' + elif os_name.startswith('Mac'): # "Mac OS X", etc. + system = 'darwin' + else: # "Linux", "SunOS", "FreeBSD", etc. + # Setting this to "linux2" is not ideal, but only Windows or Mac + # are actually checked for and the rest of the module expects + # *sys.platform* style strings. + system = 'linux2' +elif sys.platform == 'cli' and os.name == 'nt': + # Detect Windows in IronPython to match pip._internal.utils.compat.WINDOWS + # Discussion: + system = 'win32' +else: + system = sys.platform + + + +def user_data_dir(appname=None, appauthor=None, version=None, roaming=False): + r"""Return full path to the user-specific data dir for this application. + + "appname" is the name of application. + If None, just the system directory is returned. + "appauthor" (only used on Windows) is the name of the + appauthor or distributing body for this application. Typically + it is the owning company name. This falls back to appname. You may + pass False to disable it. + "version" is an optional version path element to append to the + path. You might want to use this if you want multiple versions + of your app to be able to run independently. If used, this + would typically be ".". + Only applied when appname is present. + "roaming" (boolean, default False) can be set True to use the Windows + roaming appdata directory. That means that for users on a Windows + network setup for roaming profiles, this user data will be + sync'd on login. See + + for a discussion of issues. + + Typical user data directories are: + Mac OS X: ~/Library/Application Support/ # or ~/.config/, if the other does not exist + Unix: ~/.local/share/ # or in $XDG_DATA_HOME, if defined + Win XP (not roaming): C:\Documents and Settings\\Application Data\\ + Win XP (roaming): C:\Documents and Settings\\Local Settings\Application Data\\ + Win 7 (not roaming): C:\Users\\AppData\Local\\ + Win 7 (roaming): C:\Users\\AppData\Roaming\\ + + For Unix, we follow the XDG spec and support $XDG_DATA_HOME. + That means, by default "~/.local/share/". + """ + if system == "win32": + if appauthor is None: + appauthor = appname + const = roaming and "CSIDL_APPDATA" or "CSIDL_LOCAL_APPDATA" + path = os.path.normpath(_get_win_folder(const)) + if appname: + if appauthor is not False: + path = os.path.join(path, appauthor, appname) + else: + path = os.path.join(path, appname) + elif system == 'darwin': + path = os.path.expanduser('~/Library/Application Support/') + if appname: + path = os.path.join(path, appname) + else: + path = os.getenv('XDG_DATA_HOME', os.path.expanduser("~/.local/share")) + if appname: + path = os.path.join(path, appname) + if appname and version: + path = os.path.join(path, version) + return path + + +def site_data_dir(appname=None, appauthor=None, version=None, multipath=False): + r"""Return full path to the user-shared data dir for this application. + + "appname" is the name of application. + If None, just the system directory is returned. + "appauthor" (only used on Windows) is the name of the + appauthor or distributing body for this application. Typically + it is the owning company name. This falls back to appname. You may + pass False to disable it. + "version" is an optional version path element to append to the + path. You might want to use this if you want multiple versions + of your app to be able to run independently. If used, this + would typically be ".". + Only applied when appname is present. + "multipath" is an optional parameter only applicable to *nix + which indicates that the entire list of data dirs should be + returned. By default, the first item from XDG_DATA_DIRS is + returned, or '/usr/local/share/', + if XDG_DATA_DIRS is not set + + Typical site data directories are: + Mac OS X: /Library/Application Support/ + Unix: /usr/local/share/ or /usr/share/ + Win XP: C:\Documents and Settings\All Users\Application Data\\ + Vista: (Fail! "C:\ProgramData" is a hidden *system* directory on Vista.) + Win 7: C:\ProgramData\\ # Hidden, but writeable on Win 7. + + For Unix, this is using the $XDG_DATA_DIRS[0] default. + + WARNING: Do not use this on Windows. See the Vista-Fail note above for why. + """ + if system == "win32": + if appauthor is None: + appauthor = appname + path = os.path.normpath(_get_win_folder("CSIDL_COMMON_APPDATA")) + if appname: + if appauthor is not False: + path = os.path.join(path, appauthor, appname) + else: + path = os.path.join(path, appname) + elif system == 'darwin': + path = os.path.expanduser('/Library/Application Support') + if appname: + path = os.path.join(path, appname) + else: + # XDG default for $XDG_DATA_DIRS + # only first, if multipath is False + path = os.getenv('XDG_DATA_DIRS', + os.pathsep.join(['/usr/local/share', '/usr/share'])) + pathlist = [os.path.expanduser(x.rstrip(os.sep)) for x in path.split(os.pathsep)] + if appname: + if version: + appname = os.path.join(appname, version) + pathlist = [os.path.join(x, appname) for x in pathlist] + + if multipath: + path = os.pathsep.join(pathlist) + else: + path = pathlist[0] + return path + + if appname and version: + path = os.path.join(path, version) + return path + + +def user_config_dir(appname=None, appauthor=None, version=None, roaming=False): + r"""Return full path to the user-specific config dir for this application. + + "appname" is the name of application. + If None, just the system directory is returned. + "appauthor" (only used on Windows) is the name of the + appauthor or distributing body for this application. Typically + it is the owning company name. This falls back to appname. You may + pass False to disable it. + "version" is an optional version path element to append to the + path. You might want to use this if you want multiple versions + of your app to be able to run independently. If used, this + would typically be ".". + Only applied when appname is present. + "roaming" (boolean, default False) can be set True to use the Windows + roaming appdata directory. That means that for users on a Windows + network setup for roaming profiles, this user data will be + sync'd on login. See + + for a discussion of issues. + + Typical user config directories are: + Mac OS X: same as user_data_dir + Unix: ~/.config/ # or in $XDG_CONFIG_HOME, if defined + Win *: same as user_data_dir + + For Unix, we follow the XDG spec and support $XDG_CONFIG_HOME. + That means, by default "~/.config/". + """ + if system in ["win32", "darwin"]: + path = user_data_dir(appname, appauthor, None, roaming) + else: + path = os.getenv('XDG_CONFIG_HOME', os.path.expanduser("~/.config")) + if appname: + path = os.path.join(path, appname) + if appname and version: + path = os.path.join(path, version) + return path + + +# for the discussion regarding site_config_dir locations +# see +def site_config_dir(appname=None, appauthor=None, version=None, multipath=False): + r"""Return full path to the user-shared data dir for this application. + + "appname" is the name of application. + If None, just the system directory is returned. + "appauthor" (only used on Windows) is the name of the + appauthor or distributing body for this application. Typically + it is the owning company name. This falls back to appname. You may + pass False to disable it. + "version" is an optional version path element to append to the + path. You might want to use this if you want multiple versions + of your app to be able to run independently. If used, this + would typically be ".". + Only applied when appname is present. + "multipath" is an optional parameter only applicable to *nix + which indicates that the entire list of config dirs should be + returned. By default, the first item from XDG_CONFIG_DIRS is + returned, or '/etc/xdg/', if XDG_CONFIG_DIRS is not set + + Typical site config directories are: + Mac OS X: same as site_data_dir + Unix: /etc/xdg/ or $XDG_CONFIG_DIRS[i]/ for each value in + $XDG_CONFIG_DIRS + Win *: same as site_data_dir + Vista: (Fail! "C:\ProgramData" is a hidden *system* directory on Vista.) + + For Unix, this is using the $XDG_CONFIG_DIRS[0] default, if multipath=False + + WARNING: Do not use this on Windows. See the Vista-Fail note above for why. + """ + if system in ["win32", "darwin"]: + path = site_data_dir(appname, appauthor) + if appname and version: + path = os.path.join(path, version) + else: + # XDG default for $XDG_CONFIG_DIRS (missing or empty) + # see + # only first, if multipath is False + path = os.getenv('XDG_CONFIG_DIRS') or '/etc/xdg' + pathlist = [os.path.expanduser(x.rstrip(os.sep)) for x in path.split(os.pathsep) if x] + if appname: + if version: + appname = os.path.join(appname, version) + pathlist = [os.path.join(x, appname) for x in pathlist] + + if multipath: + path = os.pathsep.join(pathlist) + else: + path = pathlist[0] + return path + + +def user_cache_dir(appname=None, appauthor=None, version=None, opinion=True): + r"""Return full path to the user-specific cache dir for this application. + + "appname" is the name of application. + If None, just the system directory is returned. + "appauthor" (only used on Windows) is the name of the + appauthor or distributing body for this application. Typically + it is the owning company name. This falls back to appname. You may + pass False to disable it. + "version" is an optional version path element to append to the + path. You might want to use this if you want multiple versions + of your app to be able to run independently. If used, this + would typically be ".". + Only applied when appname is present. + "opinion" (boolean) can be False to disable the appending of + "Cache" to the base app data dir for Windows. See + discussion below. + + Typical user cache directories are: + Mac OS X: ~/Library/Caches/ + Unix: ~/.cache/ (XDG default) + Win XP: C:\Documents and Settings\\Local Settings\Application Data\\\Cache + Vista: C:\Users\\AppData\Local\\\Cache + + On Windows the only suggestion in the MSDN docs is that local settings go in + the `CSIDL_LOCAL_APPDATA` directory. This is identical to the non-roaming + app data dir (the default returned by `user_data_dir` above). Apps typically + put cache data somewhere *under* the given dir here. Some examples: + ...\Mozilla\Firefox\Profiles\\Cache + ...\Acme\SuperApp\Cache\1.0 + OPINION: This function appends "Cache" to the `CSIDL_LOCAL_APPDATA` value. + This can be disabled with the `opinion=False` option. + """ + if system == "win32": + if appauthor is None: + appauthor = appname + path = os.path.normpath(_get_win_folder("CSIDL_LOCAL_APPDATA")) + # When using Python 2, return paths as bytes on Windows like we do on + # other operating systems. See helper function docs for more details. + if not PY3 and isinstance(path, unicode): + path = _win_path_to_bytes(path) + if appname: + if appauthor is not False: + path = os.path.join(path, appauthor, appname) + else: + path = os.path.join(path, appname) + if opinion: + path = os.path.join(path, "Cache") + elif system == 'darwin': + path = os.path.expanduser('~/Library/Caches') + if appname: + path = os.path.join(path, appname) + else: + path = os.getenv('XDG_CACHE_HOME', os.path.expanduser('~/.cache')) + if appname: + path = os.path.join(path, appname) + if appname and version: + path = os.path.join(path, version) + return path + + +def user_state_dir(appname=None, appauthor=None, version=None, roaming=False): + r"""Return full path to the user-specific state dir for this application. + + "appname" is the name of application. + If None, just the system directory is returned. + "appauthor" (only used on Windows) is the name of the + appauthor or distributing body for this application. Typically + it is the owning company name. This falls back to appname. You may + pass False to disable it. + "version" is an optional version path element to append to the + path. You might want to use this if you want multiple versions + of your app to be able to run independently. If used, this + would typically be ".". + Only applied when appname is present. + "roaming" (boolean, default False) can be set True to use the Windows + roaming appdata directory. That means that for users on a Windows + network setup for roaming profiles, this user data will be + sync'd on login. See + + for a discussion of issues. + + Typical user state directories are: + Mac OS X: same as user_data_dir + Unix: ~/.local/state/ # or in $XDG_STATE_HOME, if defined + Win *: same as user_data_dir + + For Unix, we follow this Debian proposal + to extend the XDG spec and support $XDG_STATE_HOME. + + That means, by default "~/.local/state/". + """ + if system in ["win32", "darwin"]: + path = user_data_dir(appname, appauthor, None, roaming) + else: + path = os.getenv('XDG_STATE_HOME', os.path.expanduser("~/.local/state")) + if appname: + path = os.path.join(path, appname) + if appname and version: + path = os.path.join(path, version) + return path + + +def user_log_dir(appname=None, appauthor=None, version=None, opinion=True): + r"""Return full path to the user-specific log dir for this application. + + "appname" is the name of application. + If None, just the system directory is returned. + "appauthor" (only used on Windows) is the name of the + appauthor or distributing body for this application. Typically + it is the owning company name. This falls back to appname. You may + pass False to disable it. + "version" is an optional version path element to append to the + path. You might want to use this if you want multiple versions + of your app to be able to run independently. If used, this + would typically be ".". + Only applied when appname is present. + "opinion" (boolean) can be False to disable the appending of + "Logs" to the base app data dir for Windows, and "log" to the + base cache dir for Unix. See discussion below. + + Typical user log directories are: + Mac OS X: ~/Library/Logs/ + Unix: ~/.cache//log # or under $XDG_CACHE_HOME if defined + Win XP: C:\Documents and Settings\\Local Settings\Application Data\\\Logs + Vista: C:\Users\\AppData\Local\\\Logs + + On Windows the only suggestion in the MSDN docs is that local settings + go in the `CSIDL_LOCAL_APPDATA` directory. (Note: I'm interested in + examples of what some windows apps use for a logs dir.) + + OPINION: This function appends "Logs" to the `CSIDL_LOCAL_APPDATA` + value for Windows and appends "log" to the user cache dir for Unix. + This can be disabled with the `opinion=False` option. + """ + if system == "darwin": + path = os.path.join( + os.path.expanduser('~/Library/Logs'), + appname) + elif system == "win32": + path = user_data_dir(appname, appauthor, version) + version = False + if opinion: + path = os.path.join(path, "Logs") + else: + path = user_cache_dir(appname, appauthor, version) + version = False + if opinion: + path = os.path.join(path, "log") + if appname and version: + path = os.path.join(path, version) + return path + + +class AppDirs(object): + """Convenience wrapper for getting application dirs.""" + def __init__(self, appname=None, appauthor=None, version=None, + roaming=False, multipath=False): + self.appname = appname + self.appauthor = appauthor + self.version = version + self.roaming = roaming + self.multipath = multipath + + @property + def user_data_dir(self): + return user_data_dir(self.appname, self.appauthor, + version=self.version, roaming=self.roaming) + + @property + def site_data_dir(self): + return site_data_dir(self.appname, self.appauthor, + version=self.version, multipath=self.multipath) + + @property + def user_config_dir(self): + return user_config_dir(self.appname, self.appauthor, + version=self.version, roaming=self.roaming) + + @property + def site_config_dir(self): + return site_config_dir(self.appname, self.appauthor, + version=self.version, multipath=self.multipath) + + @property + def user_cache_dir(self): + return user_cache_dir(self.appname, self.appauthor, + version=self.version) + + @property + def user_state_dir(self): + return user_state_dir(self.appname, self.appauthor, + version=self.version) + + @property + def user_log_dir(self): + return user_log_dir(self.appname, self.appauthor, + version=self.version) + + +#---- internal support stuff + +def _get_win_folder_from_registry(csidl_name): + """This is a fallback technique at best. I'm not sure if using the + registry for this guarantees us the correct answer for all CSIDL_* + names. + """ + if PY3: + import winreg as _winreg + else: + import _winreg + + shell_folder_name = { + "CSIDL_APPDATA": "AppData", + "CSIDL_COMMON_APPDATA": "Common AppData", + "CSIDL_LOCAL_APPDATA": "Local AppData", + }[csidl_name] + + key = _winreg.OpenKey( + _winreg.HKEY_CURRENT_USER, + r"Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders" + ) + dir, type = _winreg.QueryValueEx(key, shell_folder_name) + return dir + + +def _get_win_folder_with_pywin32(csidl_name): + from win32com.shell import shellcon, shell + dir = shell.SHGetFolderPath(0, getattr(shellcon, csidl_name), 0, 0) + # Try to make this a unicode path because SHGetFolderPath does + # not return unicode strings when there is unicode data in the + # path. + try: + dir = unicode(dir) + + # Downgrade to short path name if have highbit chars. See + # . + has_high_char = False + for c in dir: + if ord(c) > 255: + has_high_char = True + break + if has_high_char: + try: + import win32api + dir = win32api.GetShortPathName(dir) + except ImportError: + pass + except UnicodeError: + pass + return dir + + +def _get_win_folder_with_ctypes(csidl_name): + import ctypes + + csidl_const = { + "CSIDL_APPDATA": 26, + "CSIDL_COMMON_APPDATA": 35, + "CSIDL_LOCAL_APPDATA": 28, + }[csidl_name] + + buf = ctypes.create_unicode_buffer(1024) + ctypes.windll.shell32.SHGetFolderPathW(None, csidl_const, None, 0, buf) + + # Downgrade to short path name if have highbit chars. See + # . + has_high_char = False + for c in buf: + if ord(c) > 255: + has_high_char = True + break + if has_high_char: + buf2 = ctypes.create_unicode_buffer(1024) + if ctypes.windll.kernel32.GetShortPathNameW(buf.value, buf2, 1024): + buf = buf2 + + return buf.value + +def _get_win_folder_with_jna(csidl_name): + import array + from com.sun import jna + from com.sun.jna.platform import win32 + + buf_size = win32.WinDef.MAX_PATH * 2 + buf = array.zeros('c', buf_size) + shell = win32.Shell32.INSTANCE + shell.SHGetFolderPath(None, getattr(win32.ShlObj, csidl_name), None, win32.ShlObj.SHGFP_TYPE_CURRENT, buf) + dir = jna.Native.toString(buf.tostring()).rstrip("\0") + + # Downgrade to short path name if have highbit chars. See + # . + has_high_char = False + for c in dir: + if ord(c) > 255: + has_high_char = True + break + if has_high_char: + buf = array.zeros('c', buf_size) + kernel = win32.Kernel32.INSTANCE + if kernel.GetShortPathName(dir, buf, buf_size): + dir = jna.Native.toString(buf.tostring()).rstrip("\0") + + return dir + +if system == "win32": + try: + from ctypes import windll + _get_win_folder = _get_win_folder_with_ctypes + except ImportError: + try: + import com.sun.jna + _get_win_folder = _get_win_folder_with_jna + except ImportError: + _get_win_folder = _get_win_folder_from_registry + + +def _win_path_to_bytes(path): + """Encode Windows paths to bytes. Only used on Python 2. + + Motivation is to be consistent with other operating systems where paths + are also returned as bytes. This avoids problems mixing bytes and Unicode + elsewhere in the codebase. For more details and discussion see + . + + If encoding using ASCII and MBCS fails, return the original Unicode path. + """ + for encoding in ('ASCII', 'MBCS'): + try: + return path.encode(encoding) + except (UnicodeEncodeError, LookupError): + pass + return path + + +#---- self test code + +if __name__ == "__main__": + appname = "MyApp" + appauthor = "MyCompany" + + props = ("user_data_dir", + "user_config_dir", + "user_cache_dir", + "user_state_dir", + "user_log_dir", + "site_data_dir", + "site_config_dir") + + print("-- app dirs %s --" % __version__) + + print("-- app dirs (with optional 'version')") + dirs = AppDirs(appname, appauthor, version="1.0") + for prop in props: + print("%s: %s" % (prop, getattr(dirs, prop))) + + print("\n-- app dirs (without optional 'version')") + dirs = AppDirs(appname, appauthor) + for prop in props: + print("%s: %s" % (prop, getattr(dirs, prop))) + + print("\n-- app dirs (without optional 'appauthor')") + dirs = AppDirs(appname) + for prop in props: + print("%s: %s" % (prop, getattr(dirs, prop))) + + print("\n-- app dirs (with disabled 'appauthor')") + dirs = AppDirs(appname, appauthor=False) + for prop in props: + print("%s: %s" % (prop, getattr(dirs, prop))) diff --git a/venv/Lib/site-packages/pip/_vendor/cachecontrol/__init__.py b/venv/Lib/site-packages/pip/_vendor/cachecontrol/__init__.py new file mode 100644 index 0000000..a1bbbbe --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/cachecontrol/__init__.py @@ -0,0 +1,11 @@ +"""CacheControl import Interface. + +Make it easy to import from cachecontrol without long namespaces. +""" +__author__ = "Eric Larson" +__email__ = "eric@ionrock.org" +__version__ = "0.12.6" + +from .wrapper import CacheControl +from .adapter import CacheControlAdapter +from .controller import CacheController diff --git a/venv/Lib/site-packages/pip/_vendor/cachecontrol/_cmd.py b/venv/Lib/site-packages/pip/_vendor/cachecontrol/_cmd.py new file mode 100644 index 0000000..f1e0ad9 --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/cachecontrol/_cmd.py @@ -0,0 +1,57 @@ +import logging + +from pip._vendor import requests + +from pip._vendor.cachecontrol.adapter import CacheControlAdapter +from pip._vendor.cachecontrol.cache import DictCache +from pip._vendor.cachecontrol.controller import logger + +from argparse import ArgumentParser + + +def setup_logging(): + logger.setLevel(logging.DEBUG) + handler = logging.StreamHandler() + logger.addHandler(handler) + + +def get_session(): + adapter = CacheControlAdapter( + DictCache(), cache_etags=True, serializer=None, heuristic=None + ) + sess = requests.Session() + sess.mount("http://", adapter) + sess.mount("https://", adapter) + + sess.cache_controller = adapter.controller + return sess + + +def get_args(): + parser = ArgumentParser() + parser.add_argument("url", help="The URL to try and cache") + return parser.parse_args() + + +def main(args=None): + args = get_args() + sess = get_session() + + # Make a request to get a response + resp = sess.get(args.url) + + # Turn on logging + setup_logging() + + # try setting the cache + sess.cache_controller.cache_response(resp.request, resp.raw) + + # Now try to get it + if sess.cache_controller.cached_request(resp.request): + print("Cached!") + else: + print("Not cached :(") + + +if __name__ == "__main__": + main() diff --git a/venv/Lib/site-packages/pip/_vendor/cachecontrol/adapter.py b/venv/Lib/site-packages/pip/_vendor/cachecontrol/adapter.py new file mode 100644 index 0000000..815650e --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/cachecontrol/adapter.py @@ -0,0 +1,133 @@ +import types +import functools +import zlib + +from pip._vendor.requests.adapters import HTTPAdapter + +from .controller import CacheController +from .cache import DictCache +from .filewrapper import CallbackFileWrapper + + +class CacheControlAdapter(HTTPAdapter): + invalidating_methods = {"PUT", "DELETE"} + + def __init__( + self, + cache=None, + cache_etags=True, + controller_class=None, + serializer=None, + heuristic=None, + cacheable_methods=None, + *args, + **kw + ): + super(CacheControlAdapter, self).__init__(*args, **kw) + self.cache = DictCache() if cache is None else cache + self.heuristic = heuristic + self.cacheable_methods = cacheable_methods or ("GET",) + + controller_factory = controller_class or CacheController + self.controller = controller_factory( + self.cache, cache_etags=cache_etags, serializer=serializer + ) + + def send(self, request, cacheable_methods=None, **kw): + """ + Send a request. Use the request information to see if it + exists in the cache and cache the response if we need to and can. + """ + cacheable = cacheable_methods or self.cacheable_methods + if request.method in cacheable: + try: + cached_response = self.controller.cached_request(request) + except zlib.error: + cached_response = None + if cached_response: + return self.build_response(request, cached_response, from_cache=True) + + # check for etags and add headers if appropriate + request.headers.update(self.controller.conditional_headers(request)) + + resp = super(CacheControlAdapter, self).send(request, **kw) + + return resp + + def build_response( + self, request, response, from_cache=False, cacheable_methods=None + ): + """ + Build a response by making a request or using the cache. + + This will end up calling send and returning a potentially + cached response + """ + cacheable = cacheable_methods or self.cacheable_methods + if not from_cache and request.method in cacheable: + # Check for any heuristics that might update headers + # before trying to cache. + if self.heuristic: + response = self.heuristic.apply(response) + + # apply any expiration heuristics + if response.status == 304: + # We must have sent an ETag request. This could mean + # that we've been expired already or that we simply + # have an etag. In either case, we want to try and + # update the cache if that is the case. + cached_response = self.controller.update_cached_response( + request, response + ) + + if cached_response is not response: + from_cache = True + + # We are done with the server response, read a + # possible response body (compliant servers will + # not return one, but we cannot be 100% sure) and + # release the connection back to the pool. + response.read(decode_content=False) + response.release_conn() + + response = cached_response + + # We always cache the 301 responses + elif response.status == 301: + self.controller.cache_response(request, response) + else: + # Wrap the response file with a wrapper that will cache the + # response when the stream has been consumed. + response._fp = CallbackFileWrapper( + response._fp, + functools.partial( + self.controller.cache_response, request, response + ), + ) + if response.chunked: + super_update_chunk_length = response._update_chunk_length + + def _update_chunk_length(self): + super_update_chunk_length() + if self.chunk_left == 0: + self._fp._close() + + response._update_chunk_length = types.MethodType( + _update_chunk_length, response + ) + + resp = super(CacheControlAdapter, self).build_response(request, response) + + # See if we should invalidate the cache. + if request.method in self.invalidating_methods and resp.ok: + cache_url = self.controller.cache_url(request.url) + self.cache.delete(cache_url) + + # Give the request a from_cache attr to let people use it + resp.from_cache = from_cache + + return resp + + def close(self): + self.cache.close() + super(CacheControlAdapter, self).close() diff --git a/venv/Lib/site-packages/pip/_vendor/cachecontrol/cache.py b/venv/Lib/site-packages/pip/_vendor/cachecontrol/cache.py new file mode 100644 index 0000000..94e0773 --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/cachecontrol/cache.py @@ -0,0 +1,39 @@ +""" +The cache object API for implementing caches. The default is a thread +safe in-memory dictionary. +""" +from threading import Lock + + +class BaseCache(object): + + def get(self, key): + raise NotImplementedError() + + def set(self, key, value): + raise NotImplementedError() + + def delete(self, key): + raise NotImplementedError() + + def close(self): + pass + + +class DictCache(BaseCache): + + def __init__(self, init_dict=None): + self.lock = Lock() + self.data = init_dict or {} + + def get(self, key): + return self.data.get(key, None) + + def set(self, key, value): + with self.lock: + self.data.update({key: value}) + + def delete(self, key): + with self.lock: + if key in self.data: + self.data.pop(key) diff --git a/venv/Lib/site-packages/pip/_vendor/cachecontrol/caches/__init__.py b/venv/Lib/site-packages/pip/_vendor/cachecontrol/caches/__init__.py new file mode 100644 index 0000000..0e1658f --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/cachecontrol/caches/__init__.py @@ -0,0 +1,2 @@ +from .file_cache import FileCache # noqa +from .redis_cache import RedisCache # noqa diff --git a/venv/Lib/site-packages/pip/_vendor/cachecontrol/caches/file_cache.py b/venv/Lib/site-packages/pip/_vendor/cachecontrol/caches/file_cache.py new file mode 100644 index 0000000..607b945 --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/cachecontrol/caches/file_cache.py @@ -0,0 +1,146 @@ +import hashlib +import os +from textwrap import dedent + +from ..cache import BaseCache +from ..controller import CacheController + +try: + FileNotFoundError +except NameError: + # py2.X + FileNotFoundError = (IOError, OSError) + + +def _secure_open_write(filename, fmode): + # We only want to write to this file, so open it in write only mode + flags = os.O_WRONLY + + # os.O_CREAT | os.O_EXCL will fail if the file already exists, so we only + # will open *new* files. + # We specify this because we want to ensure that the mode we pass is the + # mode of the file. + flags |= os.O_CREAT | os.O_EXCL + + # Do not follow symlinks to prevent someone from making a symlink that + # we follow and insecurely open a cache file. + if hasattr(os, "O_NOFOLLOW"): + flags |= os.O_NOFOLLOW + + # On Windows we'll mark this file as binary + if hasattr(os, "O_BINARY"): + flags |= os.O_BINARY + + # Before we open our file, we want to delete any existing file that is + # there + try: + os.remove(filename) + except (IOError, OSError): + # The file must not exist already, so we can just skip ahead to opening + pass + + # Open our file, the use of os.O_CREAT | os.O_EXCL will ensure that if a + # race condition happens between the os.remove and this line, that an + # error will be raised. Because we utilize a lockfile this should only + # happen if someone is attempting to attack us. + fd = os.open(filename, flags, fmode) + try: + return os.fdopen(fd, "wb") + + except: + # An error occurred wrapping our FD in a file object + os.close(fd) + raise + + +class FileCache(BaseCache): + + def __init__( + self, + directory, + forever=False, + filemode=0o0600, + dirmode=0o0700, + use_dir_lock=None, + lock_class=None, + ): + + if use_dir_lock is not None and lock_class is not None: + raise ValueError("Cannot use use_dir_lock and lock_class together") + + try: + from lockfile import LockFile + from lockfile.mkdirlockfile import MkdirLockFile + except ImportError: + notice = dedent( + """ + NOTE: In order to use the FileCache you must have + lockfile installed. You can install it via pip: + pip install lockfile + """ + ) + raise ImportError(notice) + + else: + if use_dir_lock: + lock_class = MkdirLockFile + + elif lock_class is None: + lock_class = LockFile + + self.directory = directory + self.forever = forever + self.filemode = filemode + self.dirmode = dirmode + self.lock_class = lock_class + + @staticmethod + def encode(x): + return hashlib.sha224(x.encode()).hexdigest() + + def _fn(self, name): + # NOTE: This method should not change as some may depend on it. + # See: https://github.com/ionrock/cachecontrol/issues/63 + hashed = self.encode(name) + parts = list(hashed[:5]) + [hashed] + return os.path.join(self.directory, *parts) + + def get(self, key): + name = self._fn(key) + try: + with open(name, "rb") as fh: + return fh.read() + + except FileNotFoundError: + return None + + def set(self, key, value): + name = self._fn(key) + + # Make sure the directory exists + try: + os.makedirs(os.path.dirname(name), self.dirmode) + except (IOError, OSError): + pass + + with self.lock_class(name) as lock: + # Write our actual file + with _secure_open_write(lock.path, self.filemode) as fh: + fh.write(value) + + def delete(self, key): + name = self._fn(key) + if not self.forever: + try: + os.remove(name) + except FileNotFoundError: + pass + + +def url_to_file_path(url, filecache): + """Return the file cache path based on the URL. + + This does not ensure the file exists! + """ + key = CacheController.cache_url(url) + return filecache._fn(key) diff --git a/venv/Lib/site-packages/pip/_vendor/cachecontrol/caches/redis_cache.py b/venv/Lib/site-packages/pip/_vendor/cachecontrol/caches/redis_cache.py new file mode 100644 index 0000000..ed705ce --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/cachecontrol/caches/redis_cache.py @@ -0,0 +1,33 @@ +from __future__ import division + +from datetime import datetime +from pip._vendor.cachecontrol.cache import BaseCache + + +class RedisCache(BaseCache): + + def __init__(self, conn): + self.conn = conn + + def get(self, key): + return self.conn.get(key) + + def set(self, key, value, expires=None): + if not expires: + self.conn.set(key, value) + else: + expires = expires - datetime.utcnow() + self.conn.setex(key, int(expires.total_seconds()), value) + + def delete(self, key): + self.conn.delete(key) + + def clear(self): + """Helper for clearing all the keys in a database. Use with + caution!""" + for key in self.conn.keys(): + self.conn.delete(key) + + def close(self): + """Redis uses connection pooling, no need to close the connection.""" + pass diff --git a/venv/Lib/site-packages/pip/_vendor/cachecontrol/compat.py b/venv/Lib/site-packages/pip/_vendor/cachecontrol/compat.py new file mode 100644 index 0000000..33b5aed --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/cachecontrol/compat.py @@ -0,0 +1,29 @@ +try: + from urllib.parse import urljoin +except ImportError: + from urlparse import urljoin + + +try: + import cPickle as pickle +except ImportError: + import pickle + + +# Handle the case where the requests module has been patched to not have +# urllib3 bundled as part of its source. +try: + from pip._vendor.requests.packages.urllib3.response import HTTPResponse +except ImportError: + from pip._vendor.urllib3.response import HTTPResponse + +try: + from pip._vendor.requests.packages.urllib3.util import is_fp_closed +except ImportError: + from pip._vendor.urllib3.util import is_fp_closed + +# Replicate some six behaviour +try: + text_type = unicode +except NameError: + text_type = str diff --git a/venv/Lib/site-packages/pip/_vendor/cachecontrol/controller.py b/venv/Lib/site-packages/pip/_vendor/cachecontrol/controller.py new file mode 100644 index 0000000..dafe55c --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/cachecontrol/controller.py @@ -0,0 +1,376 @@ +""" +The httplib2 algorithms ported for use with requests. +""" +import logging +import re +import calendar +import time +from email.utils import parsedate_tz + +from pip._vendor.requests.structures import CaseInsensitiveDict + +from .cache import DictCache +from .serialize import Serializer + + +logger = logging.getLogger(__name__) + +URI = re.compile(r"^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?") + + +def parse_uri(uri): + """Parses a URI using the regex given in Appendix B of RFC 3986. + + (scheme, authority, path, query, fragment) = parse_uri(uri) + """ + groups = URI.match(uri).groups() + return (groups[1], groups[3], groups[4], groups[6], groups[8]) + + +class CacheController(object): + """An interface to see if request should cached or not. + """ + + def __init__( + self, cache=None, cache_etags=True, serializer=None, status_codes=None + ): + self.cache = DictCache() if cache is None else cache + self.cache_etags = cache_etags + self.serializer = serializer or Serializer() + self.cacheable_status_codes = status_codes or (200, 203, 300, 301) + + @classmethod + def _urlnorm(cls, uri): + """Normalize the URL to create a safe key for the cache""" + (scheme, authority, path, query, fragment) = parse_uri(uri) + if not scheme or not authority: + raise Exception("Only absolute URIs are allowed. uri = %s" % uri) + + scheme = scheme.lower() + authority = authority.lower() + + if not path: + path = "/" + + # Could do syntax based normalization of the URI before + # computing the digest. See Section 6.2.2 of Std 66. + request_uri = query and "?".join([path, query]) or path + defrag_uri = scheme + "://" + authority + request_uri + + return defrag_uri + + @classmethod + def cache_url(cls, uri): + return cls._urlnorm(uri) + + def parse_cache_control(self, headers): + known_directives = { + # https://tools.ietf.org/html/rfc7234#section-5.2 + "max-age": (int, True), + "max-stale": (int, False), + "min-fresh": (int, True), + "no-cache": (None, False), + "no-store": (None, False), + "no-transform": (None, False), + "only-if-cached": (None, False), + "must-revalidate": (None, False), + "public": (None, False), + "private": (None, False), + "proxy-revalidate": (None, False), + "s-maxage": (int, True), + } + + cc_headers = headers.get("cache-control", headers.get("Cache-Control", "")) + + retval = {} + + for cc_directive in cc_headers.split(","): + if not cc_directive.strip(): + continue + + parts = cc_directive.split("=", 1) + directive = parts[0].strip() + + try: + typ, required = known_directives[directive] + except KeyError: + logger.debug("Ignoring unknown cache-control directive: %s", directive) + continue + + if not typ or not required: + retval[directive] = None + if typ: + try: + retval[directive] = typ(parts[1].strip()) + except IndexError: + if required: + logger.debug( + "Missing value for cache-control " "directive: %s", + directive, + ) + except ValueError: + logger.debug( + "Invalid value for cache-control directive " "%s, must be %s", + directive, + typ.__name__, + ) + + return retval + + def cached_request(self, request): + """ + Return a cached response if it exists in the cache, otherwise + return False. + """ + cache_url = self.cache_url(request.url) + logger.debug('Looking up "%s" in the cache', cache_url) + cc = self.parse_cache_control(request.headers) + + # Bail out if the request insists on fresh data + if "no-cache" in cc: + logger.debug('Request header has "no-cache", cache bypassed') + return False + + if "max-age" in cc and cc["max-age"] == 0: + logger.debug('Request header has "max_age" as 0, cache bypassed') + return False + + # Request allows serving from the cache, let's see if we find something + cache_data = self.cache.get(cache_url) + if cache_data is None: + logger.debug("No cache entry available") + return False + + # Check whether it can be deserialized + resp = self.serializer.loads(request, cache_data) + if not resp: + logger.warning("Cache entry deserialization failed, entry ignored") + return False + + # If we have a cached 301, return it immediately. We don't + # need to test our response for other headers b/c it is + # intrinsically "cacheable" as it is Permanent. + # See: + # https://tools.ietf.org/html/rfc7231#section-6.4.2 + # + # Client can try to refresh the value by repeating the request + # with cache busting headers as usual (ie no-cache). + if resp.status == 301: + msg = ( + 'Returning cached "301 Moved Permanently" response ' + "(ignoring date and etag information)" + ) + logger.debug(msg) + return resp + + headers = CaseInsensitiveDict(resp.headers) + if not headers or "date" not in headers: + if "etag" not in headers: + # Without date or etag, the cached response can never be used + # and should be deleted. + logger.debug("Purging cached response: no date or etag") + self.cache.delete(cache_url) + logger.debug("Ignoring cached response: no date") + return False + + now = time.time() + date = calendar.timegm(parsedate_tz(headers["date"])) + current_age = max(0, now - date) + logger.debug("Current age based on date: %i", current_age) + + # TODO: There is an assumption that the result will be a + # urllib3 response object. This may not be best since we + # could probably avoid instantiating or constructing the + # response until we know we need it. + resp_cc = self.parse_cache_control(headers) + + # determine freshness + freshness_lifetime = 0 + + # Check the max-age pragma in the cache control header + if "max-age" in resp_cc: + freshness_lifetime = resp_cc["max-age"] + logger.debug("Freshness lifetime from max-age: %i", freshness_lifetime) + + # If there isn't a max-age, check for an expires header + elif "expires" in headers: + expires = parsedate_tz(headers["expires"]) + if expires is not None: + expire_time = calendar.timegm(expires) - date + freshness_lifetime = max(0, expire_time) + logger.debug("Freshness lifetime from expires: %i", freshness_lifetime) + + # Determine if we are setting freshness limit in the + # request. Note, this overrides what was in the response. + if "max-age" in cc: + freshness_lifetime = cc["max-age"] + logger.debug( + "Freshness lifetime from request max-age: %i", freshness_lifetime + ) + + if "min-fresh" in cc: + min_fresh = cc["min-fresh"] + # adjust our current age by our min fresh + current_age += min_fresh + logger.debug("Adjusted current age from min-fresh: %i", current_age) + + # Return entry if it is fresh enough + if freshness_lifetime > current_age: + logger.debug('The response is "fresh", returning cached response') + logger.debug("%i > %i", freshness_lifetime, current_age) + return resp + + # we're not fresh. If we don't have an Etag, clear it out + if "etag" not in headers: + logger.debug('The cached response is "stale" with no etag, purging') + self.cache.delete(cache_url) + + # return the original handler + return False + + def conditional_headers(self, request): + cache_url = self.cache_url(request.url) + resp = self.serializer.loads(request, self.cache.get(cache_url)) + new_headers = {} + + if resp: + headers = CaseInsensitiveDict(resp.headers) + + if "etag" in headers: + new_headers["If-None-Match"] = headers["ETag"] + + if "last-modified" in headers: + new_headers["If-Modified-Since"] = headers["Last-Modified"] + + return new_headers + + def cache_response(self, request, response, body=None, status_codes=None): + """ + Algorithm for caching requests. + + This assumes a requests Response object. + """ + # From httplib2: Don't cache 206's since we aren't going to + # handle byte range requests + cacheable_status_codes = status_codes or self.cacheable_status_codes + if response.status not in cacheable_status_codes: + logger.debug( + "Status code %s not in %s", response.status, cacheable_status_codes + ) + return + + response_headers = CaseInsensitiveDict(response.headers) + + # If we've been given a body, our response has a Content-Length, that + # Content-Length is valid then we can check to see if the body we've + # been given matches the expected size, and if it doesn't we'll just + # skip trying to cache it. + if ( + body is not None + and "content-length" in response_headers + and response_headers["content-length"].isdigit() + and int(response_headers["content-length"]) != len(body) + ): + return + + cc_req = self.parse_cache_control(request.headers) + cc = self.parse_cache_control(response_headers) + + cache_url = self.cache_url(request.url) + logger.debug('Updating cache with response from "%s"', cache_url) + + # Delete it from the cache if we happen to have it stored there + no_store = False + if "no-store" in cc: + no_store = True + logger.debug('Response header has "no-store"') + if "no-store" in cc_req: + no_store = True + logger.debug('Request header has "no-store"') + if no_store and self.cache.get(cache_url): + logger.debug('Purging existing cache entry to honor "no-store"') + self.cache.delete(cache_url) + if no_store: + return + + # https://tools.ietf.org/html/rfc7234#section-4.1: + # A Vary header field-value of "*" always fails to match. + # Storing such a response leads to a deserialization warning + # during cache lookup and is not allowed to ever be served, + # so storing it can be avoided. + if "*" in response_headers.get("vary", ""): + logger.debug('Response header has "Vary: *"') + return + + # If we've been given an etag, then keep the response + if self.cache_etags and "etag" in response_headers: + logger.debug("Caching due to etag") + self.cache.set( + cache_url, self.serializer.dumps(request, response, body=body) + ) + + # Add to the cache any 301s. We do this before looking that + # the Date headers. + elif response.status == 301: + logger.debug("Caching permanant redirect") + self.cache.set(cache_url, self.serializer.dumps(request, response)) + + # Add to the cache if the response headers demand it. If there + # is no date header then we can't do anything about expiring + # the cache. + elif "date" in response_headers: + # cache when there is a max-age > 0 + if "max-age" in cc and cc["max-age"] > 0: + logger.debug("Caching b/c date exists and max-age > 0") + self.cache.set( + cache_url, self.serializer.dumps(request, response, body=body) + ) + + # If the request can expire, it means we should cache it + # in the meantime. + elif "expires" in response_headers: + if response_headers["expires"]: + logger.debug("Caching b/c of expires header") + self.cache.set( + cache_url, self.serializer.dumps(request, response, body=body) + ) + + def update_cached_response(self, request, response): + """On a 304 we will get a new set of headers that we want to + update our cached value with, assuming we have one. + + This should only ever be called when we've sent an ETag and + gotten a 304 as the response. + """ + cache_url = self.cache_url(request.url) + + cached_response = self.serializer.loads(request, self.cache.get(cache_url)) + + if not cached_response: + # we didn't have a cached response + return response + + # Lets update our headers with the headers from the new request: + # http://tools.ietf.org/html/draft-ietf-httpbis-p4-conditional-26#section-4.1 + # + # The server isn't supposed to send headers that would make + # the cached body invalid. But... just in case, we'll be sure + # to strip out ones we know that might be problmatic due to + # typical assumptions. + excluded_headers = ["content-length"] + + cached_response.headers.update( + dict( + (k, v) + for k, v in response.headers.items() + if k.lower() not in excluded_headers + ) + ) + + # we want a 200 b/c we have content via the cache + cached_response.status = 200 + + # update our cache + self.cache.set(cache_url, self.serializer.dumps(request, cached_response)) + + return cached_response diff --git a/venv/Lib/site-packages/pip/_vendor/cachecontrol/filewrapper.py b/venv/Lib/site-packages/pip/_vendor/cachecontrol/filewrapper.py new file mode 100644 index 0000000..30ed4c5 --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/cachecontrol/filewrapper.py @@ -0,0 +1,80 @@ +from io import BytesIO + + +class CallbackFileWrapper(object): + """ + Small wrapper around a fp object which will tee everything read into a + buffer, and when that file is closed it will execute a callback with the + contents of that buffer. + + All attributes are proxied to the underlying file object. + + This class uses members with a double underscore (__) leading prefix so as + not to accidentally shadow an attribute. + """ + + def __init__(self, fp, callback): + self.__buf = BytesIO() + self.__fp = fp + self.__callback = callback + + def __getattr__(self, name): + # The vaguaries of garbage collection means that self.__fp is + # not always set. By using __getattribute__ and the private + # name[0] allows looking up the attribute value and raising an + # AttributeError when it doesn't exist. This stop thigns from + # infinitely recursing calls to getattr in the case where + # self.__fp hasn't been set. + # + # [0] https://docs.python.org/2/reference/expressions.html#atom-identifiers + fp = self.__getattribute__("_CallbackFileWrapper__fp") + return getattr(fp, name) + + def __is_fp_closed(self): + try: + return self.__fp.fp is None + + except AttributeError: + pass + + try: + return self.__fp.closed + + except AttributeError: + pass + + # We just don't cache it then. + # TODO: Add some logging here... + return False + + def _close(self): + if self.__callback: + self.__callback(self.__buf.getvalue()) + + # We assign this to None here, because otherwise we can get into + # really tricky problems where the CPython interpreter dead locks + # because the callback is holding a reference to something which + # has a __del__ method. Setting this to None breaks the cycle + # and allows the garbage collector to do it's thing normally. + self.__callback = None + + def read(self, amt=None): + data = self.__fp.read(amt) + self.__buf.write(data) + if self.__is_fp_closed(): + self._close() + + return data + + def _safe_read(self, amt): + data = self.__fp._safe_read(amt) + if amt == 2 and data == b"\r\n": + # urllib executes this read to toss the CRLF at the end + # of the chunk. + return data + + self.__buf.write(data) + if self.__is_fp_closed(): + self._close() + + return data diff --git a/venv/Lib/site-packages/pip/_vendor/cachecontrol/heuristics.py b/venv/Lib/site-packages/pip/_vendor/cachecontrol/heuristics.py new file mode 100644 index 0000000..6c0e979 --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/cachecontrol/heuristics.py @@ -0,0 +1,135 @@ +import calendar +import time + +from email.utils import formatdate, parsedate, parsedate_tz + +from datetime import datetime, timedelta + +TIME_FMT = "%a, %d %b %Y %H:%M:%S GMT" + + +def expire_after(delta, date=None): + date = date or datetime.utcnow() + return date + delta + + +def datetime_to_header(dt): + return formatdate(calendar.timegm(dt.timetuple())) + + +class BaseHeuristic(object): + + def warning(self, response): + """ + Return a valid 1xx warning header value describing the cache + adjustments. + + The response is provided too allow warnings like 113 + http://tools.ietf.org/html/rfc7234#section-5.5.4 where we need + to explicitly say response is over 24 hours old. + """ + return '110 - "Response is Stale"' + + def update_headers(self, response): + """Update the response headers with any new headers. + + NOTE: This SHOULD always include some Warning header to + signify that the response was cached by the client, not + by way of the provided headers. + """ + return {} + + def apply(self, response): + updated_headers = self.update_headers(response) + + if updated_headers: + response.headers.update(updated_headers) + warning_header_value = self.warning(response) + if warning_header_value is not None: + response.headers.update({"Warning": warning_header_value}) + + return response + + +class OneDayCache(BaseHeuristic): + """ + Cache the response by providing an expires 1 day in the + future. + """ + + def update_headers(self, response): + headers = {} + + if "expires" not in response.headers: + date = parsedate(response.headers["date"]) + expires = expire_after(timedelta(days=1), date=datetime(*date[:6])) + headers["expires"] = datetime_to_header(expires) + headers["cache-control"] = "public" + return headers + + +class ExpiresAfter(BaseHeuristic): + """ + Cache **all** requests for a defined time period. + """ + + def __init__(self, **kw): + self.delta = timedelta(**kw) + + def update_headers(self, response): + expires = expire_after(self.delta) + return {"expires": datetime_to_header(expires), "cache-control": "public"} + + def warning(self, response): + tmpl = "110 - Automatically cached for %s. Response might be stale" + return tmpl % self.delta + + +class LastModified(BaseHeuristic): + """ + If there is no Expires header already, fall back on Last-Modified + using the heuristic from + http://tools.ietf.org/html/rfc7234#section-4.2.2 + to calculate a reasonable value. + + Firefox also does something like this per + https://developer.mozilla.org/en-US/docs/Web/HTTP/Caching_FAQ + http://lxr.mozilla.org/mozilla-release/source/netwerk/protocol/http/nsHttpResponseHead.cpp#397 + Unlike mozilla we limit this to 24-hr. + """ + cacheable_by_default_statuses = { + 200, 203, 204, 206, 300, 301, 404, 405, 410, 414, 501 + } + + def update_headers(self, resp): + headers = resp.headers + + if "expires" in headers: + return {} + + if "cache-control" in headers and headers["cache-control"] != "public": + return {} + + if resp.status not in self.cacheable_by_default_statuses: + return {} + + if "date" not in headers or "last-modified" not in headers: + return {} + + date = calendar.timegm(parsedate_tz(headers["date"])) + last_modified = parsedate(headers["last-modified"]) + if date is None or last_modified is None: + return {} + + now = time.time() + current_age = max(0, now - date) + delta = date - calendar.timegm(last_modified) + freshness_lifetime = max(0, min(delta / 10, 24 * 3600)) + if freshness_lifetime <= current_age: + return {} + + expires = date + freshness_lifetime + return {"expires": time.strftime(TIME_FMT, time.gmtime(expires))} + + def warning(self, resp): + return None diff --git a/venv/Lib/site-packages/pip/_vendor/cachecontrol/serialize.py b/venv/Lib/site-packages/pip/_vendor/cachecontrol/serialize.py new file mode 100644 index 0000000..3b6ec2d --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/cachecontrol/serialize.py @@ -0,0 +1,188 @@ +import base64 +import io +import json +import zlib + +from pip._vendor import msgpack +from pip._vendor.requests.structures import CaseInsensitiveDict + +from .compat import HTTPResponse, pickle, text_type + + +def _b64_decode_bytes(b): + return base64.b64decode(b.encode("ascii")) + + +def _b64_decode_str(s): + return _b64_decode_bytes(s).decode("utf8") + + +class Serializer(object): + + def dumps(self, request, response, body=None): + response_headers = CaseInsensitiveDict(response.headers) + + if body is None: + body = response.read(decode_content=False) + + # NOTE: 99% sure this is dead code. I'm only leaving it + # here b/c I don't have a test yet to prove + # it. Basically, before using + # `cachecontrol.filewrapper.CallbackFileWrapper`, + # this made an effort to reset the file handle. The + # `CallbackFileWrapper` short circuits this code by + # setting the body as the content is consumed, the + # result being a `body` argument is *always* passed + # into cache_response, and in turn, + # `Serializer.dump`. + response._fp = io.BytesIO(body) + + # NOTE: This is all a bit weird, but it's really important that on + # Python 2.x these objects are unicode and not str, even when + # they contain only ascii. The problem here is that msgpack + # understands the difference between unicode and bytes and we + # have it set to differentiate between them, however Python 2 + # doesn't know the difference. Forcing these to unicode will be + # enough to have msgpack know the difference. + data = { + u"response": { + u"body": body, + u"headers": dict( + (text_type(k), text_type(v)) for k, v in response.headers.items() + ), + u"status": response.status, + u"version": response.version, + u"reason": text_type(response.reason), + u"strict": response.strict, + u"decode_content": response.decode_content, + } + } + + # Construct our vary headers + data[u"vary"] = {} + if u"vary" in response_headers: + varied_headers = response_headers[u"vary"].split(",") + for header in varied_headers: + header = text_type(header).strip() + header_value = request.headers.get(header, None) + if header_value is not None: + header_value = text_type(header_value) + data[u"vary"][header] = header_value + + return b",".join([b"cc=4", msgpack.dumps(data, use_bin_type=True)]) + + def loads(self, request, data): + # Short circuit if we've been given an empty set of data + if not data: + return + + # Determine what version of the serializer the data was serialized + # with + try: + ver, data = data.split(b",", 1) + except ValueError: + ver = b"cc=0" + + # Make sure that our "ver" is actually a version and isn't a false + # positive from a , being in the data stream. + if ver[:3] != b"cc=": + data = ver + data + ver = b"cc=0" + + # Get the version number out of the cc=N + ver = ver.split(b"=", 1)[-1].decode("ascii") + + # Dispatch to the actual load method for the given version + try: + return getattr(self, "_loads_v{}".format(ver))(request, data) + + except AttributeError: + # This is a version we don't have a loads function for, so we'll + # just treat it as a miss and return None + return + + def prepare_response(self, request, cached): + """Verify our vary headers match and construct a real urllib3 + HTTPResponse object. + """ + # Special case the '*' Vary value as it means we cannot actually + # determine if the cached response is suitable for this request. + # This case is also handled in the controller code when creating + # a cache entry, but is left here for backwards compatibility. + if "*" in cached.get("vary", {}): + return + + # Ensure that the Vary headers for the cached response match our + # request + for header, value in cached.get("vary", {}).items(): + if request.headers.get(header, None) != value: + return + + body_raw = cached["response"].pop("body") + + headers = CaseInsensitiveDict(data=cached["response"]["headers"]) + if headers.get("transfer-encoding", "") == "chunked": + headers.pop("transfer-encoding") + + cached["response"]["headers"] = headers + + try: + body = io.BytesIO(body_raw) + except TypeError: + # This can happen if cachecontrol serialized to v1 format (pickle) + # using Python 2. A Python 2 str(byte string) will be unpickled as + # a Python 3 str (unicode string), which will cause the above to + # fail with: + # + # TypeError: 'str' does not support the buffer interface + body = io.BytesIO(body_raw.encode("utf8")) + + return HTTPResponse(body=body, preload_content=False, **cached["response"]) + + def _loads_v0(self, request, data): + # The original legacy cache data. This doesn't contain enough + # information to construct everything we need, so we'll treat this as + # a miss. + return + + def _loads_v1(self, request, data): + try: + cached = pickle.loads(data) + except ValueError: + return + + return self.prepare_response(request, cached) + + def _loads_v2(self, request, data): + try: + cached = json.loads(zlib.decompress(data).decode("utf8")) + except (ValueError, zlib.error): + return + + # We need to decode the items that we've base64 encoded + cached["response"]["body"] = _b64_decode_bytes(cached["response"]["body"]) + cached["response"]["headers"] = dict( + (_b64_decode_str(k), _b64_decode_str(v)) + for k, v in cached["response"]["headers"].items() + ) + cached["response"]["reason"] = _b64_decode_str(cached["response"]["reason"]) + cached["vary"] = dict( + (_b64_decode_str(k), _b64_decode_str(v) if v is not None else v) + for k, v in cached["vary"].items() + ) + + return self.prepare_response(request, cached) + + def _loads_v3(self, request, data): + # Due to Python 2 encoding issues, it's impossible to know for sure + # exactly how to load v3 entries, thus we'll treat these as a miss so + # that they get rewritten out as v4 entries. + return + + def _loads_v4(self, request, data): + try: + cached = msgpack.loads(data, raw=False) + except ValueError: + return + + return self.prepare_response(request, cached) diff --git a/venv/Lib/site-packages/pip/_vendor/cachecontrol/wrapper.py b/venv/Lib/site-packages/pip/_vendor/cachecontrol/wrapper.py new file mode 100644 index 0000000..d8e6fc6 --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/cachecontrol/wrapper.py @@ -0,0 +1,29 @@ +from .adapter import CacheControlAdapter +from .cache import DictCache + + +def CacheControl( + sess, + cache=None, + cache_etags=True, + serializer=None, + heuristic=None, + controller_class=None, + adapter_class=None, + cacheable_methods=None, +): + + cache = DictCache() if cache is None else cache + adapter_class = adapter_class or CacheControlAdapter + adapter = adapter_class( + cache, + cache_etags=cache_etags, + serializer=serializer, + heuristic=heuristic, + controller_class=controller_class, + cacheable_methods=cacheable_methods, + ) + sess.mount("http://", adapter) + sess.mount("https://", adapter) + + return sess diff --git a/venv/Lib/site-packages/pip/_vendor/certifi/__init__.py b/venv/Lib/site-packages/pip/_vendor/certifi/__init__.py new file mode 100644 index 0000000..17aaf90 --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/certifi/__init__.py @@ -0,0 +1,3 @@ +from .core import contents, where + +__version__ = "2020.12.05" diff --git a/venv/Lib/site-packages/pip/_vendor/certifi/__main__.py b/venv/Lib/site-packages/pip/_vendor/certifi/__main__.py new file mode 100644 index 0000000..0037634 --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/certifi/__main__.py @@ -0,0 +1,12 @@ +import argparse + +from pip._vendor.certifi import contents, where + +parser = argparse.ArgumentParser() +parser.add_argument("-c", "--contents", action="store_true") +args = parser.parse_args() + +if args.contents: + print(contents()) +else: + print(where()) diff --git a/venv/Lib/site-packages/pip/_vendor/certifi/cacert.pem b/venv/Lib/site-packages/pip/_vendor/certifi/cacert.pem new file mode 100644 index 0000000..c9459dc --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/certifi/cacert.pem @@ -0,0 +1,4325 @@ + +# Issuer: CN=GlobalSign Root CA O=GlobalSign nv-sa OU=Root CA +# Subject: CN=GlobalSign Root CA O=GlobalSign nv-sa OU=Root CA +# Label: "GlobalSign Root CA" +# Serial: 4835703278459707669005204 +# MD5 Fingerprint: 3e:45:52:15:09:51:92:e1:b7:5d:37:9f:b1:87:29:8a +# SHA1 Fingerprint: b1:bc:96:8b:d4:f4:9d:62:2a:a8:9a:81:f2:15:01:52:a4:1d:82:9c +# SHA256 Fingerprint: eb:d4:10:40:e4:bb:3e:c7:42:c9:e3:81:d3:1e:f2:a4:1a:48:b6:68:5c:96:e7:ce:f3:c1:df:6c:d4:33:1c:99 +-----BEGIN CERTIFICATE----- +MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkG +A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv +b3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAw +MDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9i +YWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJHbG9iYWxT +aWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDaDuaZ +jc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavp +xy0Sy6scTHAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp +1Wrjsok6Vjk4bwY8iGlbKk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdG +snUOhugZitVtbNV4FpWi6cgKOOvyJBNPc1STE4U6G7weNLWLBYy5d4ux2x8gkasJ +U26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrXgzT/LCrBbBlDSgeF59N8 +9iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8E +BTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0B +AQUFAAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOz +yj1hTdNGCbM+w6DjY1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE +38NflNUVyRRBnMRddWQVDf9VMOyGj/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymP +AbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhHhm4qxFYxldBniYUr+WymXUad +DKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveCX4XSQRjbgbME +HMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A== +-----END CERTIFICATE----- + +# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R2 +# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R2 +# Label: "GlobalSign Root CA - R2" +# Serial: 4835703278459682885658125 +# MD5 Fingerprint: 94:14:77:7e:3e:5e:fd:8f:30:bd:41:b0:cf:e7:d0:30 +# SHA1 Fingerprint: 75:e0:ab:b6:13:85:12:27:1c:04:f8:5f:dd:de:38:e4:b7:24:2e:fe +# SHA256 Fingerprint: ca:42:dd:41:74:5f:d0:b8:1e:b9:02:36:2c:f9:d8:bf:71:9d:a1:bd:1b:1e:fc:94:6f:5b:4c:99:f4:2c:1b:9e +-----BEGIN CERTIFICATE----- +MIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4G +A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNp +Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDYxMjE1MDgwMDAwWhcNMjExMjE1 +MDgwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMjETMBEG +A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAKbPJA6+Lm8omUVCxKs+IVSbC9N/hHD6ErPL +v4dfxn+G07IwXNb9rfF73OX4YJYJkhD10FPe+3t+c4isUoh7SqbKSaZeqKeMWhG8 +eoLrvozps6yWJQeXSpkqBy+0Hne/ig+1AnwblrjFuTosvNYSuetZfeLQBoZfXklq +tTleiDTsvHgMCJiEbKjNS7SgfQx5TfC4LcshytVsW33hoCmEofnTlEnLJGKRILzd +C9XZzPnqJworc5HGnRusyMvo4KD0L5CLTfuwNhv2GXqF4G3yYROIXJ/gkwpRl4pa +zq+r1feqCapgvdzZX99yqWATXgAByUr6P6TqBwMhAo6CygPCm48CAwEAAaOBnDCB +mTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUm+IH +V2ccHsBqBt5ZtJot39wZhi4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5n +bG9iYWxzaWduLm5ldC9yb290LXIyLmNybDAfBgNVHSMEGDAWgBSb4gdXZxwewGoG +3lm0mi3f3BmGLjANBgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4Gs +J0/WwbgcQ3izDJr86iw8bmEbTUsp9Z8FHSbBuOmDAGJFtqkIk7mpM0sYmsL4h4hO +291xNBrBVNpGP+DTKqttVCL1OmLNIG+6KYnX3ZHu01yiPqFbQfXf5WRDLenVOavS +ot+3i9DAgBkcRcAtjOj4LaR0VknFBbVPFd5uRHg5h6h+u/N5GJG79G+dwfCMNYxd +AfvDbbnvRG15RjF+Cv6pgsH/76tuIMRQyV+dTZsXjAzlAcmgQWpzU/qlULRuJQ/7 +TBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg== +-----END CERTIFICATE----- + +# Issuer: CN=Entrust.net Certification Authority (2048) O=Entrust.net OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.)/(c) 1999 Entrust.net Limited +# Subject: CN=Entrust.net Certification Authority (2048) O=Entrust.net OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.)/(c) 1999 Entrust.net Limited +# Label: "Entrust.net Premium 2048 Secure Server CA" +# Serial: 946069240 +# MD5 Fingerprint: ee:29:31:bc:32:7e:9a:e6:e8:b5:f7:51:b4:34:71:90 +# SHA1 Fingerprint: 50:30:06:09:1d:97:d4:f5:ae:39:f7:cb:e7:92:7d:7d:65:2d:34:31 +# SHA256 Fingerprint: 6d:c4:71:72:e0:1c:bc:b0:bf:62:58:0d:89:5f:e2:b8:ac:9a:d4:f8:73:80:1e:0c:10:b9:c8:37:d2:1e:b1:77 +-----BEGIN CERTIFICATE----- +MIIEKjCCAxKgAwIBAgIEOGPe+DANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChML +RW50cnVzdC5uZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBp +bmNvcnAuIGJ5IHJlZi4gKGxpbWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5 +IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNVBAMTKkVudHJ1c3QubmV0IENlcnRp +ZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw05OTEyMjQxNzUwNTFaFw0yOTA3 +MjQxNDE1MTJaMIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3d3d3 +LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxp +YWIuKTElMCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEG +A1UEAxMqRW50cnVzdC5uZXQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgp +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArU1LqRKGsuqjIAcVFmQq +K0vRvwtKTY7tgHalZ7d4QMBzQshowNtTK91euHaYNZOLGp18EzoOH1u3Hs/lJBQe +sYGpjX24zGtLA/ECDNyrpUAkAH90lKGdCCmziAv1h3edVc3kw37XamSrhRSGlVuX +MlBvPci6Zgzj/L24ScF2iUkZ/cCovYmjZy/Gn7xxGWC4LeksyZB2ZnuU4q941mVT +XTzWnLLPKQP5L6RQstRIzgUyVYr9smRMDuSYB3Xbf9+5CFVghTAp+XtIpGmG4zU/ +HoZdenoVve8AjhUiVBcAkCaTvA5JaJG/+EfTnZVCwQ5N328mz8MYIWJmQ3DW1cAH +4QIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV +HQ4EFgQUVeSB0RGAvtiJuQijMfmhJAkWuXAwDQYJKoZIhvcNAQEFBQADggEBADub +j1abMOdTmXx6eadNl9cZlZD7Bh/KM3xGY4+WZiT6QBshJ8rmcnPyT/4xmf3IDExo +U8aAghOY+rat2l098c5u9hURlIIM7j+VrxGrD9cv3h8Dj1csHsm7mhpElesYT6Yf +zX1XEC+bBAlahLVu2B064dae0Wx5XnkcFMXj0EyTO2U87d89vqbllRrDtRnDvV5b +u/8j72gZyxKTJ1wDLW8w0B62GqzeWvfRqqgnpv55gcR5mTNXuhKwqeBCbJPKVt7+ +bYQLCIt+jerXmCHG8+c8eS9enNFMFY3h7CI3zJpDC5fcgJCNs2ebb0gIFVbPv/Er +fF6adulZkMV8gzURZVE= +-----END CERTIFICATE----- + +# Issuer: CN=Baltimore CyberTrust Root O=Baltimore OU=CyberTrust +# Subject: CN=Baltimore CyberTrust Root O=Baltimore OU=CyberTrust +# Label: "Baltimore CyberTrust Root" +# Serial: 33554617 +# MD5 Fingerprint: ac:b6:94:a5:9c:17:e0:d7:91:52:9b:b1:97:06:a6:e4 +# SHA1 Fingerprint: d4:de:20:d0:5e:66:fc:53:fe:1a:50:88:2c:78:db:28:52:ca:e4:74 +# SHA256 Fingerprint: 16:af:57:a9:f6:76:b0:ab:12:60:95:aa:5e:ba:de:f2:2a:b3:11:19:d6:44:ac:95:cd:4b:93:db:f3:f2:6a:eb +-----BEGIN CERTIFICATE----- +MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJ +RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD +VQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoX +DTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMCSUUxEjAQBgNVBAoTCUJhbHRpbW9y +ZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFsdGltb3JlIEN5YmVy +VHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKMEuyKr +mD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjr +IZ3AQSsBUnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeK +mpYcqWe4PwzV9/lSEy/CG9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSu +XmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9XbIGevOF6uvUA65ehD5f/xXtabz5OTZy +dc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjprl3RjM71oGDHweI12v/ye +jl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoIVDaGezq1 +BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3 +DQEBBQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT92 +9hkTI7gQCvlYpNRhcL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3Wgx +jkzSswF07r51XgdIGn9w/xZchMB5hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0 +Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsaY71k5h+3zvDyny67G7fyUIhz +ksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9HRCwBXbsdtTLS +R9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp +-----END CERTIFICATE----- + +# Issuer: CN=Entrust Root Certification Authority O=Entrust, Inc. OU=www.entrust.net/CPS is incorporated by reference/(c) 2006 Entrust, Inc. +# Subject: CN=Entrust Root Certification Authority O=Entrust, Inc. OU=www.entrust.net/CPS is incorporated by reference/(c) 2006 Entrust, Inc. +# Label: "Entrust Root Certification Authority" +# Serial: 1164660820 +# MD5 Fingerprint: d6:a5:c3:ed:5d:dd:3e:00:c1:3d:87:92:1f:1d:3f:e4 +# SHA1 Fingerprint: b3:1e:b1:b7:40:e3:6c:84:02:da:dc:37:d4:4d:f5:d4:67:49:52:f9 +# SHA256 Fingerprint: 73:c1:76:43:4f:1b:c6:d5:ad:f4:5b:0e:76:e7:27:28:7c:8d:e5:76:16:c1:e6:e6:14:1a:2b:2c:bc:7d:8e:4c +-----BEGIN CERTIFICATE----- +MIIEkTCCA3mgAwIBAgIERWtQVDANBgkqhkiG9w0BAQUFADCBsDELMAkGA1UEBhMC +VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xOTA3BgNVBAsTMHd3dy5lbnRydXN0 +Lm5ldC9DUFMgaXMgaW5jb3Jwb3JhdGVkIGJ5IHJlZmVyZW5jZTEfMB0GA1UECxMW +KGMpIDIwMDYgRW50cnVzdCwgSW5jLjEtMCsGA1UEAxMkRW50cnVzdCBSb290IENl +cnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA2MTEyNzIwMjM0MloXDTI2MTEyNzIw +NTM0MlowgbAxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMTkw +NwYDVQQLEzB3d3cuZW50cnVzdC5uZXQvQ1BTIGlzIGluY29ycG9yYXRlZCBieSBy +ZWZlcmVuY2UxHzAdBgNVBAsTFihjKSAyMDA2IEVudHJ1c3QsIEluYy4xLTArBgNV +BAMTJEVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASIwDQYJ +KoZIhvcNAQEBBQADggEPADCCAQoCggEBALaVtkNC+sZtKm9I35RMOVcF7sN5EUFo +Nu3s/poBj6E4KPz3EEZmLk0eGrEaTsbRwJWIsMn/MYszA9u3g3s+IIRe7bJWKKf4 +4LlAcTfFy0cOlypowCKVYhXbR9n10Cv/gkvJrT7eTNuQgFA/CYqEAOwwCj0Yzfv9 +KlmaI5UXLEWeH25DeW0MXJj+SKfFI0dcXv1u5x609mhF0YaDW6KKjbHjKYD+JXGI +rb68j6xSlkuqUY3kEzEZ6E5Nn9uss2rVvDlUccp6en+Q3X0dgNmBu1kmwhH+5pPi +94DkZfs0Nw4pgHBNrziGLp5/V6+eF67rHMsoIV+2HNjnogQi+dPa2MsCAwEAAaOB +sDCBrTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zArBgNVHRAEJDAi +gA8yMDA2MTEyNzIwMjM0MlqBDzIwMjYxMTI3MjA1MzQyWjAfBgNVHSMEGDAWgBRo +kORnpKZTgMeGZqTx90tD+4S9bTAdBgNVHQ4EFgQUaJDkZ6SmU4DHhmak8fdLQ/uE +vW0wHQYJKoZIhvZ9B0EABBAwDhsIVjcuMTo0LjADAgSQMA0GCSqGSIb3DQEBBQUA +A4IBAQCT1DCw1wMgKtD5Y+iRDAUgqV8ZyntyTtSx29CW+1RaGSwMCPeyvIWonX9t +O1KzKtvn1ISMY/YPyyYBkVBs9F8U4pN0wBOeMDpQ47RgxRzwIkSNcUesyBrJ6Zua +AGAT/3B+XxFNSRuzFVJ7yVTav52Vr2ua2J7p8eRDjeIRRDq/r72DQnNSi6q7pynP +9WQcCk3RvKqsnyrQ/39/2n3qse0wJcGE2jTSW3iDVuycNsMm4hH2Z0kdkquM++v/ +eu6FSqdQgPCnXEqULl8FmTxSQeDNtGPPAUO6nIPcj2A781q0tHuu2guQOHXvgR1m +0vdXcDazv/wor3ElhVsT/h5/WrQ8 +-----END CERTIFICATE----- + +# Issuer: CN=AAA Certificate Services O=Comodo CA Limited +# Subject: CN=AAA Certificate Services O=Comodo CA Limited +# Label: "Comodo AAA Services root" +# Serial: 1 +# MD5 Fingerprint: 49:79:04:b0:eb:87:19:ac:47:b0:bc:11:51:9b:74:d0 +# SHA1 Fingerprint: d1:eb:23:a4:6d:17:d6:8f:d9:25:64:c2:f1:f1:60:17:64:d8:e3:49 +# SHA256 Fingerprint: d7:a7:a0:fb:5d:7e:27:31:d7:71:e9:48:4e:bc:de:f7:1d:5f:0c:3e:0a:29:48:78:2b:c8:3e:e0:ea:69:9e:f4 +-----BEGIN CERTIFICATE----- +MIIEMjCCAxqgAwIBAgIBATANBgkqhkiG9w0BAQUFADB7MQswCQYDVQQGEwJHQjEb +MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow +GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEhMB8GA1UEAwwYQUFBIENlcnRpZmlj +YXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAwMFoXDTI4MTIzMTIzNTk1OVowezEL +MAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE +BwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNVBAMM +GEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBAL5AnfRu4ep2hxxNRUSOvkbIgwadwSr+GB+O5AL686tdUIoWMQua +BtDFcCLNSS1UY8y2bmhGC1Pqy0wkwLxyTurxFa70VJoSCsN6sjNg4tqJVfMiWPPe +3M/vg4aijJRPn2jymJBGhCfHdr/jzDUsi14HZGWCwEiwqJH5YZ92IFCokcdmtet4 +YgNW8IoaE+oxox6gmf049vYnMlhvB/VruPsUK6+3qszWY19zjNoFmag4qMsXeDZR +rOme9Hg6jc8P2ULimAyrL58OAd7vn5lJ8S3frHRNG5i1R8XlKdH5kBjHYpy+g8cm +ez6KJcfA3Z3mNWgQIJ2P2N7Sw4ScDV7oL8kCAwEAAaOBwDCBvTAdBgNVHQ4EFgQU +oBEKIz6W8Qfs4q8p74Klf9AwpLQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF +MAMBAf8wewYDVR0fBHQwcjA4oDagNIYyaHR0cDovL2NybC5jb21vZG9jYS5jb20v +QUFBQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmwwNqA0oDKGMGh0dHA6Ly9jcmwuY29t +b2RvLm5ldC9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2VzLmNybDANBgkqhkiG9w0BAQUF +AAOCAQEACFb8AvCb6P+k+tZ7xkSAzk/ExfYAWMymtrwUSWgEdujm7l3sAg9g1o1Q +GE8mTgHj5rCl7r+8dFRBv/38ErjHT1r0iWAFf2C3BUrz9vHCv8S5dIa2LX1rzNLz +Rt0vxuBqw8M0Ayx9lt1awg6nCpnBBYurDC/zXDrPbDdVCYfeU0BsWO/8tqtlbgT2 +G9w84FoVxp7Z8VlIMCFlA2zs6SFz7JsDoeA3raAVGI/6ugLOpyypEBMs1OUIJqsi +l2D4kF501KKaU73yqWjgom7C12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3tPxq3 +smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg== +-----END CERTIFICATE----- + +# Issuer: CN=QuoVadis Root Certification Authority O=QuoVadis Limited OU=Root Certification Authority +# Subject: CN=QuoVadis Root Certification Authority O=QuoVadis Limited OU=Root Certification Authority +# Label: "QuoVadis Root CA" +# Serial: 985026699 +# MD5 Fingerprint: 27:de:36:fe:72:b7:00:03:00:9d:f4:f0:1e:6c:04:24 +# SHA1 Fingerprint: de:3f:40:bd:50:93:d3:9b:6c:60:f6:da:bc:07:62:01:00:89:76:c9 +# SHA256 Fingerprint: a4:5e:de:3b:bb:f0:9c:8a:e1:5c:72:ef:c0:72:68:d6:93:a2:1c:99:6f:d5:1e:67:ca:07:94:60:fd:6d:88:73 +-----BEGIN CERTIFICATE----- +MIIF0DCCBLigAwIBAgIEOrZQizANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJC +TTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDElMCMGA1UECxMcUm9vdCBDZXJ0 +aWZpY2F0aW9uIEF1dGhvcml0eTEuMCwGA1UEAxMlUXVvVmFkaXMgUm9vdCBDZXJ0 +aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wMTAzMTkxODMzMzNaFw0yMTAzMTcxODMz +MzNaMH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMSUw +IwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYDVQQDEyVR +dW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv2G1lVO6V/z68mcLOhrfEYBklbTRvM16z/Yp +li4kVEAkOPcahdxYTMukJ0KX0J+DisPkBgNbAKVRHnAEdOLB1Dqr1607BxgFjv2D +rOpm2RgbaIr1VxqYuvXtdj182d6UajtLF8HVj71lODqV0D1VNk7feVcxKh7YWWVJ +WCCYfqtffp/p1k3sg3Spx2zY7ilKhSoGFPlU5tPaZQeLYzcS19Dsw3sgQUSj7cug +F+FxZc4dZjH3dgEZyH0DWLaVSR2mEiboxgx24ONmy+pdpibu5cxfvWenAScOospU +xbF6lR1xHkopigPcakXBpBlebzbNw6Kwt/5cOOJSvPhEQ+aQuwIDAQABo4ICUjCC +Ak4wPQYIKwYBBQUHAQEEMTAvMC0GCCsGAQUFBzABhiFodHRwczovL29jc3AucXVv +dmFkaXNvZmZzaG9yZS5jb20wDwYDVR0TAQH/BAUwAwEB/zCCARoGA1UdIASCAREw +ggENMIIBCQYJKwYBBAG+WAABMIH7MIHUBggrBgEFBQcCAjCBxxqBxFJlbGlhbmNl +IG9uIHRoZSBRdW9WYWRpcyBSb290IENlcnRpZmljYXRlIGJ5IGFueSBwYXJ0eSBh +c3N1bWVzIGFjY2VwdGFuY2Ugb2YgdGhlIHRoZW4gYXBwbGljYWJsZSBzdGFuZGFy +ZCB0ZXJtcyBhbmQgY29uZGl0aW9ucyBvZiB1c2UsIGNlcnRpZmljYXRpb24gcHJh +Y3RpY2VzLCBhbmQgdGhlIFF1b1ZhZGlzIENlcnRpZmljYXRlIFBvbGljeS4wIgYI +KwYBBQUHAgEWFmh0dHA6Ly93d3cucXVvdmFkaXMuYm0wHQYDVR0OBBYEFItLbe3T +KbkGGew5Oanwl4Rqy+/fMIGuBgNVHSMEgaYwgaOAFItLbe3TKbkGGew5Oanwl4Rq +y+/foYGEpIGBMH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1p +dGVkMSUwIwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYD +VQQDEyVRdW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggQ6tlCL +MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAitQUtf70mpKnGdSk +fnIYj9lofFIk3WdvOXrEql494liwTXCYhGHoG+NpGA7O+0dQoE7/8CQfvbLO9Sf8 +7C9TqnN7Az10buYWnuulLsS/VidQK2K6vkscPFVcQR0kvoIgR13VRH56FmjffU1R +cHhXHTMe/QKZnAzNCgVPx7uOpHX6Sm2xgI4JVrmcGmD+XcHXetwReNDWXcG31a0y +mQM6isxUJTkxgXsTIlG6Rmyhu576BGxJJnSP0nPrzDCi5upZIof4l/UO/erMkqQW +xFIY6iHOsfHmhIHluqmGKPJDWl0Snawe2ajlCmqnf6CHKc/yiU3U7MXi5nrQNiOK +SnQ2+Q== +-----END CERTIFICATE----- + +# Issuer: CN=QuoVadis Root CA 2 O=QuoVadis Limited +# Subject: CN=QuoVadis Root CA 2 O=QuoVadis Limited +# Label: "QuoVadis Root CA 2" +# Serial: 1289 +# MD5 Fingerprint: 5e:39:7b:dd:f8:ba:ec:82:e9:ac:62:ba:0c:54:00:2b +# SHA1 Fingerprint: ca:3a:fb:cf:12:40:36:4b:44:b2:16:20:88:80:48:39:19:93:7c:f7 +# SHA256 Fingerprint: 85:a0:dd:7d:d7:20:ad:b7:ff:05:f8:3d:54:2b:20:9d:c7:ff:45:28:f7:d6:77:b1:83:89:fe:a5:e5:c4:9e:86 +-----BEGIN CERTIFICATE----- +MIIFtzCCA5+gAwIBAgICBQkwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0x +GTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJv +b3QgQ0EgMjAeFw0wNjExMjQxODI3MDBaFw0zMTExMjQxODIzMzNaMEUxCzAJBgNV +BAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9W +YWRpcyBSb290IENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCa +GMpLlA0ALa8DKYrwD4HIrkwZhR0In6spRIXzL4GtMh6QRr+jhiYaHv5+HBg6XJxg +Fyo6dIMzMH1hVBHL7avg5tKifvVrbxi3Cgst/ek+7wrGsxDp3MJGF/hd/aTa/55J +WpzmM+Yklvc/ulsrHHo1wtZn/qtmUIttKGAr79dgw8eTvI02kfN/+NsRE8Scd3bB +rrcCaoF6qUWD4gXmuVbBlDePSHFjIuwXZQeVikvfj8ZaCuWw419eaxGrDPmF60Tp ++ARz8un+XJiM9XOva7R+zdRcAitMOeGylZUtQofX1bOQQ7dsE/He3fbE+Ik/0XX1 +ksOR1YqI0JDs3G3eicJlcZaLDQP9nL9bFqyS2+r+eXyt66/3FsvbzSUr5R/7mp/i +Ucw6UwxI5g69ybR2BlLmEROFcmMDBOAENisgGQLodKcftslWZvB1JdxnwQ5hYIiz +PtGo/KPaHbDRsSNU30R2be1B2MGyIrZTHN81Hdyhdyox5C315eXbyOD/5YDXC2Og +/zOhD7osFRXql7PSorW+8oyWHhqPHWykYTe5hnMz15eWniN9gqRMgeKh0bpnX5UH +oycR7hYQe7xFSkyyBNKr79X9DFHOUGoIMfmR2gyPZFwDwzqLID9ujWc9Otb+fVuI +yV77zGHcizN300QyNQliBJIWENieJ0f7OyHj+OsdWwIDAQABo4GwMIGtMA8GA1Ud +EwEB/wQFMAMBAf8wCwYDVR0PBAQDAgEGMB0GA1UdDgQWBBQahGK8SEwzJQTU7tD2 +A8QZRtGUazBuBgNVHSMEZzBlgBQahGK8SEwzJQTU7tD2A8QZRtGUa6FJpEcwRTEL +MAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMT +ElF1b1ZhZGlzIFJvb3QgQ0EgMoICBQkwDQYJKoZIhvcNAQEFBQADggIBAD4KFk2f +BluornFdLwUvZ+YTRYPENvbzwCYMDbVHZF34tHLJRqUDGCdViXh9duqWNIAXINzn +g/iN/Ae42l9NLmeyhP3ZRPx3UIHmfLTJDQtyU/h2BwdBR5YM++CCJpNVjP4iH2Bl +fF/nJrP3MpCYUNQ3cVX2kiF495V5+vgtJodmVjB3pjd4M1IQWK4/YY7yarHvGH5K +WWPKjaJW1acvvFYfzznB4vsKqBUsfU16Y8Zsl0Q80m/DShcK+JDSV6IZUaUtl0Ha +B0+pUNqQjZRG4T7wlP0QADj1O+hA4bRuVhogzG9Yje0uRY/W6ZM/57Es3zrWIozc +hLsib9D45MY56QSIPMO661V6bYCZJPVsAfv4l7CUW+v90m/xd2gNNWQjrLhVoQPR +TUIZ3Ph1WVaj+ahJefivDrkRoHy3au000LYmYjgahwz46P0u05B/B5EqHdZ+XIWD +mbA4CD/pXvk1B+TJYm5Xf6dQlfe6yJvmjqIBxdZmv3lh8zwc4bmCXF2gw+nYSL0Z +ohEUGW6yhhtoPkg3Goi3XZZenMfvJ2II4pEZXNLxId26F0KCl3GBUzGpn/Z9Yr9y +4aOTHcyKJloJONDO1w2AFrR4pTqHTI2KpdVGl/IsELm8VCLAAVBpQ570su9t+Oza +8eOx79+Rj1QqCyXBJhnEUhAFZdWCEOrCMc0u +-----END CERTIFICATE----- + +# Issuer: CN=QuoVadis Root CA 3 O=QuoVadis Limited +# Subject: CN=QuoVadis Root CA 3 O=QuoVadis Limited +# Label: "QuoVadis Root CA 3" +# Serial: 1478 +# MD5 Fingerprint: 31:85:3c:62:94:97:63:b9:aa:fd:89:4e:af:6f:e0:cf +# SHA1 Fingerprint: 1f:49:14:f7:d8:74:95:1d:dd:ae:02:c0:be:fd:3a:2d:82:75:51:85 +# SHA256 Fingerprint: 18:f1:fc:7f:20:5d:f8:ad:dd:eb:7f:e0:07:dd:57:e3:af:37:5a:9c:4d:8d:73:54:6b:f4:f1:fe:d1:e1:8d:35 +-----BEGIN CERTIFICATE----- +MIIGnTCCBIWgAwIBAgICBcYwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0x +GTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJv +b3QgQ0EgMzAeFw0wNjExMjQxOTExMjNaFw0zMTExMjQxOTA2NDRaMEUxCzAJBgNV +BAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9W +YWRpcyBSb290IENBIDMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDM +V0IWVJzmmNPTTe7+7cefQzlKZbPoFog02w1ZkXTPkrgEQK0CSzGrvI2RaNggDhoB +4hp7Thdd4oq3P5kazethq8Jlph+3t723j/z9cI8LoGe+AaJZz3HmDyl2/7FWeUUr +H556VOijKTVopAFPD6QuN+8bv+OPEKhyq1hX51SGyMnzW9os2l2ObjyjPtr7guXd +8lyyBTNvijbO0BNO/79KDDRMpsMhvVAEVeuxu537RR5kFd5VAYwCdrXLoT9Cabwv +vWhDFlaJKjdhkf2mrk7AyxRllDdLkgbvBNDInIjbC3uBr7E9KsRlOni27tyAsdLT +mZw67mtaa7ONt9XOnMK+pUsvFrGeaDsGb659n/je7Mwpp5ijJUMv7/FfJuGITfhe +btfZFG4ZM2mnO4SJk8RTVROhUXhA+LjJou57ulJCg54U7QVSWllWp5f8nT8KKdjc +T5EOE7zelaTfi5m+rJsziO+1ga8bxiJTyPbH7pcUsMV8eFLI8M5ud2CEpukqdiDt +WAEXMJPpGovgc2PZapKUSU60rUqFxKMiMPwJ7Wgic6aIDFUhWMXhOp8q3crhkODZ +c6tsgLjoC2SToJyMGf+z0gzskSaHirOi4XCPLArlzW1oUevaPwV/izLmE1xr/l9A +4iLItLRkT9a6fUg+qGkM17uGcclzuD87nSVL2v9A6wIDAQABo4IBlTCCAZEwDwYD +VR0TAQH/BAUwAwEB/zCB4QYDVR0gBIHZMIHWMIHTBgkrBgEEAb5YAAMwgcUwgZMG +CCsGAQUFBwICMIGGGoGDQW55IHVzZSBvZiB0aGlzIENlcnRpZmljYXRlIGNvbnN0 +aXR1dGVzIGFjY2VwdGFuY2Ugb2YgdGhlIFF1b1ZhZGlzIFJvb3QgQ0EgMyBDZXJ0 +aWZpY2F0ZSBQb2xpY3kgLyBDZXJ0aWZpY2F0aW9uIFByYWN0aWNlIFN0YXRlbWVu +dC4wLQYIKwYBBQUHAgEWIWh0dHA6Ly93d3cucXVvdmFkaXNnbG9iYWwuY29tL2Nw +czALBgNVHQ8EBAMCAQYwHQYDVR0OBBYEFPLAE+CCQz777i9nMpY1XNu4ywLQMG4G +A1UdIwRnMGWAFPLAE+CCQz777i9nMpY1XNu4ywLQoUmkRzBFMQswCQYDVQQGEwJC +TTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDEbMBkGA1UEAxMSUXVvVmFkaXMg +Um9vdCBDQSAzggIFxjANBgkqhkiG9w0BAQUFAAOCAgEAT62gLEz6wPJv92ZVqyM0 +7ucp2sNbtrCD2dDQ4iH782CnO11gUyeim/YIIirnv6By5ZwkajGxkHon24QRiSem +d1o417+shvzuXYO8BsbRd2sPbSQvS3pspweWyuOEn62Iix2rFo1bZhfZFvSLgNLd ++LJ2w/w4E6oM3kJpK27zPOuAJ9v1pkQNn1pVWQvVDVJIxa6f8i+AxeoyUDUSly7B +4f/xI4hROJ/yZlZ25w9Rl6VSDE1JUZU2Pb+iSwwQHYaZTKrzchGT5Or2m9qoXadN +t54CrnMAyNojA+j56hl0YgCUyyIgvpSnWbWCar6ZeXqp8kokUvd0/bpO5qgdAm6x +DYBEwa7TIzdfu4V8K5Iu6H6li92Z4b8nby1dqnuH/grdS/yO9SbkbnBCbjPsMZ57 +k8HkyWkaPcBrTiJt7qtYTcbQQcEr6k8Sh17rRdhs9ZgC06DYVYoGmRmioHfRMJ6s +zHXug/WwYjnPbFfiTNKRCw51KBuav/0aQ/HKd/s7j2G4aSgWQgRecCocIdiP4b0j +Wy10QJLZYxkNc91pvGJHvOB0K7Lrfb5BG7XARsWhIstfTsEokt4YutUqKLsRixeT +mJlglFwjz1onl14LBQaTNx47aTbrqZ5hHY8y2o4M1nQ+ewkk2gF3R8Q7zTSMmfXK +4SVhM7JZG+Ju1zdXtg2pEto= +-----END CERTIFICATE----- + +# Issuer: O=SECOM Trust.net OU=Security Communication RootCA1 +# Subject: O=SECOM Trust.net OU=Security Communication RootCA1 +# Label: "Security Communication Root CA" +# Serial: 0 +# MD5 Fingerprint: f1:bc:63:6a:54:e0:b5:27:f5:cd:e7:1a:e3:4d:6e:4a +# SHA1 Fingerprint: 36:b1:2b:49:f9:81:9e:d7:4c:9e:bc:38:0f:c6:56:8f:5d:ac:b2:f7 +# SHA256 Fingerprint: e7:5e:72:ed:9f:56:0e:ec:6e:b4:80:00:73:a4:3f:c3:ad:19:19:5a:39:22:82:01:78:95:97:4a:99:02:6b:6c +-----BEGIN CERTIFICATE----- +MIIDWjCCAkKgAwIBAgIBADANBgkqhkiG9w0BAQUFADBQMQswCQYDVQQGEwJKUDEY +MBYGA1UEChMPU0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21t +dW5pY2F0aW9uIFJvb3RDQTEwHhcNMDMwOTMwMDQyMDQ5WhcNMjMwOTMwMDQyMDQ5 +WjBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMPU0VDT00gVHJ1c3QubmV0MScwJQYD +VQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQCzs/5/022x7xZ8V6UMbXaKL0u/ZPtM7orw8yl8 +9f/uKuDp6bpbZCKamm8sOiZpUQWZJtzVHGpxxpp9Hp3dfGzGjGdnSj74cbAZJ6kJ +DKaVv0uMDPpVmDvY6CKhS3E4eayXkmmziX7qIWgGmBSWh9JhNrxtJ1aeV+7AwFb9 +Ms+k2Y7CI9eNqPPYJayX5HA49LY6tJ07lyZDo6G8SVlyTCMwhwFY9k6+HGhWZq/N +QV3Is00qVUarH9oe4kA92819uZKAnDfdDJZkndwi92SL32HeFZRSFaB9UslLqCHJ +xrHty8OVYNEP8Ktw+N/LTX7s1vqr2b1/VPKl6Xn62dZ2JChzAgMBAAGjPzA9MB0G +A1UdDgQWBBSgc0mZaNyFW2XjmygvV5+9M7wHSDALBgNVHQ8EBAMCAQYwDwYDVR0T +AQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAaECpqLvkT115swW1F7NgE+vG +kl3g0dNq/vu+m22/xwVtWSDEHPC32oRYAmP6SBbvT6UL90qY8j+eG61Ha2POCEfr +Uj94nK9NrvjVT8+amCoQQTlSxN3Zmw7vkwGusi7KaEIkQmywszo+zenaSMQVy+n5 +Bw+SUEmK3TGXX8npN6o7WWWXlDLJs58+OmJYxUmtYg5xpTKqL8aJdkNAExNnPaJU +JRDL8Try2frbSVa7pv6nQTXD4IhhyYjH3zYQIphZ6rBK+1YWc26sTfcioU+tHXot +RSflMMFe8toTyyVCUZVHA4xsIcx0Qu1T/zOLjw9XARYvz6buyXAiFL39vmwLAw== +-----END CERTIFICATE----- + +# Issuer: CN=Sonera Class2 CA O=Sonera +# Subject: CN=Sonera Class2 CA O=Sonera +# Label: "Sonera Class 2 Root CA" +# Serial: 29 +# MD5 Fingerprint: a3:ec:75:0f:2e:88:df:fa:48:01:4e:0b:5c:48:6f:fb +# SHA1 Fingerprint: 37:f7:6d:e6:07:7c:90:c5:b1:3e:93:1a:b7:41:10:b4:f2:e4:9a:27 +# SHA256 Fingerprint: 79:08:b4:03:14:c1:38:10:0b:51:8d:07:35:80:7f:fb:fc:f8:51:8a:00:95:33:71:05:ba:38:6b:15:3d:d9:27 +-----BEGIN CERTIFICATE----- +MIIDIDCCAgigAwIBAgIBHTANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJGSTEP +MA0GA1UEChMGU29uZXJhMRkwFwYDVQQDExBTb25lcmEgQ2xhc3MyIENBMB4XDTAx +MDQwNjA3Mjk0MFoXDTIxMDQwNjA3Mjk0MFowOTELMAkGA1UEBhMCRkkxDzANBgNV +BAoTBlNvbmVyYTEZMBcGA1UEAxMQU29uZXJhIENsYXNzMiBDQTCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAJAXSjWdyvANlsdE+hY3/Ei9vX+ALTU74W+o +Z6m/AxxNjG8yR9VBaKQTBME1DJqEQ/xcHf+Js+gXGM2RX/uJ4+q/Tl18GybTdXnt +5oTjV+WtKcT0OijnpXuENmmz/V52vaMtmdOQTiMofRhj8VQ7Jp12W5dCsv+u8E7s +3TmVToMGf+dJQMjFAbJUWmYdPfz56TwKnoG4cPABi+QjVHzIrviQHgCWctRUz2Ej +vOr7nQKV0ba5cTppCD8PtOFCx4j1P5iop7oc4HFx71hXgVB6XGt0Rg6DA5jDjqhu +8nYybieDwnPz3BjotJPqdURrBGAgcVeHnfO+oJAjPYok4doh28MCAwEAAaMzMDEw +DwYDVR0TAQH/BAUwAwEB/zARBgNVHQ4ECgQISqCqWITTXjwwCwYDVR0PBAQDAgEG +MA0GCSqGSIb3DQEBBQUAA4IBAQBazof5FnIVV0sd2ZvnoiYw7JNn39Yt0jSv9zil +zqsWuasvfDXLrNAPtEwr/IDva4yRXzZ299uzGxnq9LIR/WFxRL8oszodv7ND6J+/ +3DEIcbCdjdY0RzKQxmUk96BKfARzjzlvF4xytb1LyHr4e4PDKE6cCepnP7JnBBvD +FNr450kkkdAdavphOe9r5yF1BgfYErQhIHBCcYHaPJo2vqZbDWpsmh+Re/n570K6 +Tk6ezAyNlNzZRZxe7EJQY670XcSxEtzKO6gunRRaBXW37Ndj4ro1tgQIkejanZz2 +ZrUYrAqmVCY0M9IbwdR/GjqOC6oybtv8TyWf2TLHllpwrN9M +-----END CERTIFICATE----- + +# Issuer: CN=XRamp Global Certification Authority O=XRamp Security Services Inc OU=www.xrampsecurity.com +# Subject: CN=XRamp Global Certification Authority O=XRamp Security Services Inc OU=www.xrampsecurity.com +# Label: "XRamp Global CA Root" +# Serial: 107108908803651509692980124233745014957 +# MD5 Fingerprint: a1:0b:44:b3:ca:10:d8:00:6e:9d:0f:d8:0f:92:0a:d1 +# SHA1 Fingerprint: b8:01:86:d1:eb:9c:86:a5:41:04:cf:30:54:f3:4c:52:b7:e5:58:c6 +# SHA256 Fingerprint: ce:cd:dc:90:50:99:d8:da:df:c5:b1:d2:09:b7:37:cb:e2:c1:8c:fb:2c:10:c0:ff:0b:cf:0d:32:86:fc:1a:a2 +-----BEGIN CERTIFICATE----- +MIIEMDCCAxigAwIBAgIQUJRs7Bjq1ZxN1ZfvdY+grTANBgkqhkiG9w0BAQUFADCB +gjELMAkGA1UEBhMCVVMxHjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEk +MCIGA1UEChMbWFJhbXAgU2VjdXJpdHkgU2VydmljZXMgSW5jMS0wKwYDVQQDEyRY +UmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQxMTAxMTcx +NDA0WhcNMzUwMTAxMDUzNzE5WjCBgjELMAkGA1UEBhMCVVMxHjAcBgNVBAsTFXd3 +dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2VjdXJpdHkgU2Vy +dmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBB +dXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCYJB69FbS6 +38eMpSe2OAtp87ZOqCwuIR1cRN8hXX4jdP5efrRKt6atH67gBhbim1vZZ3RrXYCP +KZ2GG9mcDZhtdhAoWORlsH9KmHmf4MMxfoArtYzAQDsRhtDLooY2YKTVMIJt2W7Q +DxIEM5dfT2Fa8OT5kavnHTu86M/0ay00fOJIYRyO82FEzG+gSqmUsE3a56k0enI4 +qEHMPJQRfevIpoy3hsvKMzvZPTeL+3o+hiznc9cKV6xkmxnr9A8ECIqsAxcZZPRa +JSKNNCyy9mgdEm3Tih4U2sSPpuIjhdV6Db1q4Ons7Be7QhtnqiXtRYMh/MHJfNVi +PvryxS3T/dRlAgMBAAGjgZ8wgZwwEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0P +BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFMZPoj0GY4QJnM5i5ASs +jVy16bYbMDYGA1UdHwQvMC0wK6ApoCeGJWh0dHA6Ly9jcmwueHJhbXBzZWN1cml0 +eS5jb20vWEdDQS5jcmwwEAYJKwYBBAGCNxUBBAMCAQEwDQYJKoZIhvcNAQEFBQAD +ggEBAJEVOQMBG2f7Shz5CmBbodpNl2L5JFMn14JkTpAuw0kbK5rc/Kh4ZzXxHfAR +vbdI4xD2Dd8/0sm2qlWkSLoC295ZLhVbO50WfUfXN+pfTXYSNrsf16GBBEYgoyxt +qZ4Bfj8pzgCT3/3JknOJiWSe5yvkHJEs0rnOfc5vMZnT5r7SHpDwCRR5XCOrTdLa +IR9NmXmd4c8nnxCbHIgNsIpkQTG4DmyQJKSbXHGPurt+HBvbaoAPIbzp26a3QPSy +i6mx5O+aGtA9aZnuqCij4Tyz8LIRnM98QObd50N9otg6tamN8jSZxNQQ4Qb9CYQQ +O+7ETPTsJ3xCwnR8gooJybQDJbw= +-----END CERTIFICATE----- + +# Issuer: O=The Go Daddy Group, Inc. OU=Go Daddy Class 2 Certification Authority +# Subject: O=The Go Daddy Group, Inc. OU=Go Daddy Class 2 Certification Authority +# Label: "Go Daddy Class 2 CA" +# Serial: 0 +# MD5 Fingerprint: 91:de:06:25:ab:da:fd:32:17:0c:bb:25:17:2a:84:67 +# SHA1 Fingerprint: 27:96:ba:e6:3f:18:01:e2:77:26:1b:a0:d7:77:70:02:8f:20:ee:e4 +# SHA256 Fingerprint: c3:84:6b:f2:4b:9e:93:ca:64:27:4c:0e:c6:7c:1e:cc:5e:02:4f:fc:ac:d2:d7:40:19:35:0e:81:fe:54:6a:e4 +-----BEGIN CERTIFICATE----- +MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEh +MB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBE +YWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3 +MDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkGA1UEBhMCVVMxITAfBgNVBAoTGFRo +ZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28gRGFkZHkgQ2xhc3Mg +MiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQADggEN +ADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCA +PVYYYwhv2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6w +wdhFJ2+qN1j3hybX2C32qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXi +EqITLdiOr18SPaAIBQi2XKVlOARFmR6jYGB0xUGlcmIbYsUfb18aQr4CUWWoriMY +avx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmYvLEHZ6IVDd2gWMZEewo+ +YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0OBBYEFNLE +sNKR1EwRcbNhyz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h +/t2oatTjoWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5 +IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmlj +YXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQAD +ggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wimPQoZ+YeAEW5p5JYXMP80kWNy +OO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKtI3lpjbi2Tc7P +TMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ +HmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mER +dEr/VxqHD3VILs9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5Cuf +ReYNnyicsbkqWletNw+vHX/bvZ8= +-----END CERTIFICATE----- + +# Issuer: O=Starfield Technologies, Inc. OU=Starfield Class 2 Certification Authority +# Subject: O=Starfield Technologies, Inc. OU=Starfield Class 2 Certification Authority +# Label: "Starfield Class 2 CA" +# Serial: 0 +# MD5 Fingerprint: 32:4a:4b:bb:c8:63:69:9b:be:74:9a:c6:dd:1d:46:24 +# SHA1 Fingerprint: ad:7e:1c:28:b0:64:ef:8f:60:03:40:20:14:c3:d0:e3:37:0e:b5:8a +# SHA256 Fingerprint: 14:65:fa:20:53:97:b8:76:fa:a6:f0:a9:95:8e:55:90:e4:0f:cc:7f:aa:4f:b7:c2:c8:67:75:21:fb:5f:b6:58 +-----BEGIN CERTIFICATE----- +MIIEDzCCAvegAwIBAgIBADANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJVUzEl +MCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMp +U3RhcmZpZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQw +NjI5MTczOTE2WhcNMzQwNjI5MTczOTE2WjBoMQswCQYDVQQGEwJVUzElMCMGA1UE +ChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMpU3RhcmZp +ZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEgMA0GCSqGSIb3 +DQEBAQUAA4IBDQAwggEIAoIBAQC3Msj+6XGmBIWtDBFk385N78gDGIc/oav7PKaf +8MOh2tTYbitTkPskpD6E8J7oX+zlJ0T1KKY/e97gKvDIr1MvnsoFAZMej2YcOadN ++lq2cwQlZut3f+dZxkqZJRRU6ybH838Z1TBwj6+wRir/resp7defqgSHo9T5iaU0 +X9tDkYI22WY8sbi5gv2cOj4QyDvvBmVmepsZGD3/cVE8MC5fvj13c7JdBmzDI1aa +K4UmkhynArPkPw2vCHmCuDY96pzTNbO8acr1zJ3o/WSNF4Azbl5KXZnJHoe0nRrA +1W4TNSNe35tfPe/W93bC6j67eA0cQmdrBNj41tpvi/JEoAGrAgEDo4HFMIHCMB0G +A1UdDgQWBBS/X7fRzt0fhvRbVazc1xDCDqmI5zCBkgYDVR0jBIGKMIGHgBS/X7fR +zt0fhvRbVazc1xDCDqmI56FspGowaDELMAkGA1UEBhMCVVMxJTAjBgNVBAoTHFN0 +YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAsTKVN0YXJmaWVsZCBD +bGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8w +DQYJKoZIhvcNAQEFBQADggEBAAWdP4id0ckaVaGsafPzWdqbAYcaT1epoXkJKtv3 +L7IezMdeatiDh6GX70k1PncGQVhiv45YuApnP+yz3SFmH8lU+nLMPUxA2IGvd56D +eruix/U0F47ZEUD0/CwqTRV/p2JdLiXTAAsgGh1o+Re49L2L7ShZ3U0WixeDyLJl +xy16paq8U4Zt3VekyvggQQto8PT7dL5WXXp59fkdheMtlb71cZBDzI0fmgAKhynp +VSJYACPq4xJDKVtHCN2MQWplBqjlIapBtJUhlbl90TSrE9atvNziPTnNvT51cKEY +WQPJIrSPnNVeKtelttQKbfi3QBFGmh95DmK/D5fs4C8fF5Q= +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert Assured ID Root CA O=DigiCert Inc OU=www.digicert.com +# Subject: CN=DigiCert Assured ID Root CA O=DigiCert Inc OU=www.digicert.com +# Label: "DigiCert Assured ID Root CA" +# Serial: 17154717934120587862167794914071425081 +# MD5 Fingerprint: 87:ce:0b:7b:2a:0e:49:00:e1:58:71:9b:37:a8:93:72 +# SHA1 Fingerprint: 05:63:b8:63:0d:62:d7:5a:bb:c8:ab:1e:4b:df:b5:a8:99:b2:4d:43 +# SHA256 Fingerprint: 3e:90:99:b5:01:5e:8f:48:6c:00:bc:ea:9d:11:1e:e7:21:fa:ba:35:5a:89:bc:f1:df:69:56:1e:3d:c6:32:5c +-----BEGIN CERTIFICATE----- +MIIDtzCCAp+gAwIBAgIQDOfg5RfYRv6P5WD8G/AwOTANBgkqhkiG9w0BAQUFADBl +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv +b3QgQ0EwHhcNMDYxMTEwMDAwMDAwWhcNMzExMTEwMDAwMDAwWjBlMQswCQYDVQQG +EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl +cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0EwggEi +MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtDhXO5EOAXLGH87dg+XESpa7c +JpSIqvTO9SA5KFhgDPiA2qkVlTJhPLWxKISKityfCgyDF3qPkKyK53lTXDGEKvYP +mDI2dsze3Tyoou9q+yHyUmHfnyDXH+Kx2f4YZNISW1/5WBg1vEfNoTb5a3/UsDg+ +wRvDjDPZ2C8Y/igPs6eD1sNuRMBhNZYW/lmci3Zt1/GiSw0r/wty2p5g0I6QNcZ4 +VYcgoc/lbQrISXwxmDNsIumH0DJaoroTghHtORedmTpyoeb6pNnVFzF1roV9Iq4/ +AUaG9ih5yLHa5FcXxH4cDrC0kqZWs72yl+2qp/C3xag/lRbQ/6GW6whfGHdPAgMB +AAGjYzBhMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW +BBRF66Kv9JLLgjEtUYunpyGd823IDzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYun +pyGd823IDzANBgkqhkiG9w0BAQUFAAOCAQEAog683+Lt8ONyc3pklL/3cmbYMuRC +dWKuh+vy1dneVrOfzM4UKLkNl2BcEkxY5NM9g0lFWJc1aRqoR+pWxnmrEthngYTf +fwk8lOa4JiwgvT2zKIn3X/8i4peEH+ll74fg38FnSbNd67IJKusm7Xi+fT8r87cm +NW1fiQG2SVufAQWbqz0lwcy2f8Lxb4bG+mRo64EtlOtCt/qMHt1i8b5QZ7dsvfPx +H2sMNgcWfzd8qVttevESRmCD1ycEvkvOl77DZypoEd+A5wwzZr8TDRRu838fYxAe ++o0bJW1sj6W3YQGx0qMmoRBxna3iw/nDmVG3KwcIzi7mULKn+gpFL6Lw8g== +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert Global Root CA O=DigiCert Inc OU=www.digicert.com +# Subject: CN=DigiCert Global Root CA O=DigiCert Inc OU=www.digicert.com +# Label: "DigiCert Global Root CA" +# Serial: 10944719598952040374951832963794454346 +# MD5 Fingerprint: 79:e4:a9:84:0d:7d:3a:96:d7:c0:4f:e2:43:4c:89:2e +# SHA1 Fingerprint: a8:98:5d:3a:65:e5:e5:c4:b2:d7:d6:6d:40:c6:dd:2f:b1:9c:54:36 +# SHA256 Fingerprint: 43:48:a0:e9:44:4c:78:cb:26:5e:05:8d:5e:89:44:b4:d8:4f:96:62:bd:26:db:25:7f:89:34:a4:43:c7:01:61 +-----BEGIN CERTIFICATE----- +MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD +QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT +MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j +b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB +CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97 +nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt +43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P +T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4 +gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO +BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR +TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw +DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr +hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg +06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF +PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls +YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk +CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4= +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert High Assurance EV Root CA O=DigiCert Inc OU=www.digicert.com +# Subject: CN=DigiCert High Assurance EV Root CA O=DigiCert Inc OU=www.digicert.com +# Label: "DigiCert High Assurance EV Root CA" +# Serial: 3553400076410547919724730734378100087 +# MD5 Fingerprint: d4:74:de:57:5c:39:b2:d3:9c:85:83:c5:c0:65:49:8a +# SHA1 Fingerprint: 5f:b7:ee:06:33:e2:59:db:ad:0c:4c:9a:e6:d3:8f:1a:61:c7:dc:25 +# SHA256 Fingerprint: 74:31:e5:f4:c3:c1:ce:46:90:77:4f:0b:61:e0:54:40:88:3b:a9:a0:1e:d0:0b:a6:ab:d7:80:6e:d3:b1:18:cf +-----BEGIN CERTIFICATE----- +MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j +ZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL +MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3 +LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug +RVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm ++9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW +PNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM +xChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB +Ik5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3 +hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg +EsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF +MAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA +FLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec +nzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z +eM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF +hS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2 +Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe +vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep ++OkuE6N36B9K +-----END CERTIFICATE----- + +# Issuer: CN=DST Root CA X3 O=Digital Signature Trust Co. +# Subject: CN=DST Root CA X3 O=Digital Signature Trust Co. +# Label: "DST Root CA X3" +# Serial: 91299735575339953335919266965803778155 +# MD5 Fingerprint: 41:03:52:dc:0f:f7:50:1b:16:f0:02:8e:ba:6f:45:c5 +# SHA1 Fingerprint: da:c9:02:4f:54:d8:f6:df:94:93:5f:b1:73:26:38:ca:6a:d7:7c:13 +# SHA256 Fingerprint: 06:87:26:03:31:a7:24:03:d9:09:f1:05:e6:9b:cf:0d:32:e1:bd:24:93:ff:c6:d9:20:6d:11:bc:d6:77:07:39 +-----BEGIN CERTIFICATE----- +MIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/ +MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT +DkRTVCBSb290IENBIFgzMB4XDTAwMDkzMDIxMTIxOVoXDTIxMDkzMDE0MDExNVow +PzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMRcwFQYDVQQD +Ew5EU1QgUm9vdCBDQSBYMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB +AN+v6ZdQCINXtMxiZfaQguzH0yxrMMpb7NnDfcdAwRgUi+DoM3ZJKuM/IUmTrE4O +rz5Iy2Xu/NMhD2XSKtkyj4zl93ewEnu1lcCJo6m67XMuegwGMoOifooUMM0RoOEq +OLl5CjH9UL2AZd+3UWODyOKIYepLYYHsUmu5ouJLGiifSKOeDNoJjj4XLh7dIN9b +xiqKqy69cK3FCxolkHRyxXtqqzTWMIn/5WgTe1QLyNau7Fqckh49ZLOMxt+/yUFw +7BZy1SbsOFU5Q9D8/RhcQPGX69Wam40dutolucbY38EVAjqr2m7xPi71XAicPNaD +aeQQmxkqtilX4+U9m5/wAl0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNV +HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMSnsaR7LHH62+FLkHX/xBVghYkQMA0GCSqG +SIb3DQEBBQUAA4IBAQCjGiybFwBcqR7uKGY3Or+Dxz9LwwmglSBd49lZRNI+DT69 +ikugdB/OEIKcdBodfpga3csTS7MgROSR6cz8faXbauX+5v3gTt23ADq1cEmv8uXr +AvHRAosZy5Q6XkjEGB5YGV8eAlrwDPGxrancWYaLbumR9YbK+rlmM6pZW87ipxZz +R8srzJmwN0jP41ZL9c8PDHIyh8bwRLtTcm1D9SZImlJnt1ir/md2cXjbDaJWFBM5 +JDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubSfZGL+T0yjWW06XyxV3bqxbYo +Ob8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ +-----END CERTIFICATE----- + +# Issuer: CN=SwissSign Gold CA - G2 O=SwissSign AG +# Subject: CN=SwissSign Gold CA - G2 O=SwissSign AG +# Label: "SwissSign Gold CA - G2" +# Serial: 13492815561806991280 +# MD5 Fingerprint: 24:77:d9:a8:91:d1:3b:fa:88:2d:c2:ff:f8:cd:33:93 +# SHA1 Fingerprint: d8:c5:38:8a:b7:30:1b:1b:6e:d4:7a:e6:45:25:3a:6f:9f:1a:27:61 +# SHA256 Fingerprint: 62:dd:0b:e9:b9:f5:0a:16:3e:a0:f8:e7:5c:05:3b:1e:ca:57:ea:55:c8:68:8f:64:7c:68:81:f2:c8:35:7b:95 +-----BEGIN CERTIFICATE----- +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 +-----END CERTIFICATE----- + +# Issuer: CN=SwissSign Silver CA - G2 O=SwissSign AG +# Subject: CN=SwissSign Silver CA - G2 O=SwissSign AG +# Label: "SwissSign Silver CA - G2" +# Serial: 5700383053117599563 +# MD5 Fingerprint: e0:06:a1:c9:7d:cf:c9:fc:0d:c0:56:75:96:d8:62:13 +# SHA1 Fingerprint: 9b:aa:e5:9f:56:ee:21:cb:43:5a:be:25:93:df:a7:f0:40:d1:1d:cb +# SHA256 Fingerprint: be:6c:4d:a2:bb:b9:ba:59:b6:f3:93:97:68:37:42:46:c3:c0:05:99:3f:a9:8f:02:0d:1d:ed:be:d4:8a:81:d5 +-----BEGIN CERTIFICATE----- +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 +-----END CERTIFICATE----- + +# Issuer: CN=SecureTrust CA O=SecureTrust Corporation +# Subject: CN=SecureTrust CA O=SecureTrust Corporation +# Label: "SecureTrust CA" +# Serial: 17199774589125277788362757014266862032 +# MD5 Fingerprint: dc:32:c3:a7:6d:25:57:c7:68:09:9d:ea:2d:a9:a2:d1 +# SHA1 Fingerprint: 87:82:c6:c3:04:35:3b:cf:d2:96:92:d2:59:3e:7d:44:d9:34:ff:11 +# SHA256 Fingerprint: f1:c1:b5:0a:e5:a2:0d:d8:03:0e:c9:f6:bc:24:82:3d:d3:67:b5:25:57:59:b4:e7:1b:61:fc:e9:f7:37:5d:73 +-----BEGIN CERTIFICATE----- +MIIDuDCCAqCgAwIBAgIQDPCOXAgWpa1Cf/DrJxhZ0DANBgkqhkiG9w0BAQUFADBI +MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24x +FzAVBgNVBAMTDlNlY3VyZVRydXN0IENBMB4XDTA2MTEwNzE5MzExOFoXDTI5MTIz +MTE5NDA1NVowSDELMAkGA1UEBhMCVVMxIDAeBgNVBAoTF1NlY3VyZVRydXN0IENv +cnBvcmF0aW9uMRcwFQYDVQQDEw5TZWN1cmVUcnVzdCBDQTCCASIwDQYJKoZIhvcN +AQEBBQADggEPADCCAQoCggEBAKukgeWVzfX2FI7CT8rU4niVWJxB4Q2ZQCQXOZEz +Zum+4YOvYlyJ0fwkW2Gz4BERQRwdbvC4u/jep4G6pkjGnx29vo6pQT64lO0pGtSO +0gMdA+9tDWccV9cGrcrI9f4Or2YlSASWC12juhbDCE/RRvgUXPLIXgGZbf2IzIao +wW8xQmxSPmjL8xk037uHGFaAJsTQ3MBv396gwpEWoGQRS0S8Hvbn+mPeZqx2pHGj +7DaUaHp3pLHnDi+BeuK1cobvomuL8A/b01k/unK8RCSc43Oz969XL0Imnal0ugBS +8kvNU3xHCzaFDmapCJcWNFfBZveA4+1wVMeT4C4oFVmHursCAwEAAaOBnTCBmjAT +BgkrBgEEAYI3FAIEBh4EAEMAQTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB +/zAdBgNVHQ4EFgQUQjK2FvoE/f5dS3rD/fdMQB1aQ68wNAYDVR0fBC0wKzApoCeg +JYYjaHR0cDovL2NybC5zZWN1cmV0cnVzdC5jb20vU1RDQS5jcmwwEAYJKwYBBAGC +NxUBBAMCAQAwDQYJKoZIhvcNAQEFBQADggEBADDtT0rhWDpSclu1pqNlGKa7UTt3 +6Z3q059c4EVlew3KW+JwULKUBRSuSceNQQcSc5R+DCMh/bwQf2AQWnL1mA6s7Ll/ +3XpvXdMc9P+IBWlCqQVxyLesJugutIxq/3HcuLHfmbx8IVQr5Fiiu1cprp6poxkm +D5kuCLDv/WnPmRoJjeOnnyvJNjR7JLN4TJUXpAYmHrZkUjZfYGfZnMUFdAvnZyPS +CPyI6a6Lf+Ew9Dd+/cYy2i2eRDAwbO4H3tI0/NL/QPZL9GZGBlSm8jIKYyYwa5vR +3ItHuuG51WLQoqD0ZwV4KWMabwTW+MZMo5qxN7SN5ShLHZ4swrhovO0C7jE= +-----END CERTIFICATE----- + +# Issuer: CN=Secure Global CA O=SecureTrust Corporation +# Subject: CN=Secure Global CA O=SecureTrust Corporation +# Label: "Secure Global CA" +# Serial: 9751836167731051554232119481456978597 +# MD5 Fingerprint: cf:f4:27:0d:d4:ed:dc:65:16:49:6d:3d:da:bf:6e:de +# SHA1 Fingerprint: 3a:44:73:5a:e5:81:90:1f:24:86:61:46:1e:3b:9c:c4:5f:f5:3a:1b +# SHA256 Fingerprint: 42:00:f5:04:3a:c8:59:0e:bb:52:7d:20:9e:d1:50:30:29:fb:cb:d4:1c:a1:b5:06:ec:27:f1:5a:de:7d:ac:69 +-----BEGIN CERTIFICATE----- +MIIDvDCCAqSgAwIBAgIQB1YipOjUiolN9BPI8PjqpTANBgkqhkiG9w0BAQUFADBK +MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24x +GTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwgQ0EwHhcNMDYxMTA3MTk0MjI4WhcNMjkx +MjMxMTk1MjA2WjBKMQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3Qg +Q29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwgQ0EwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvNS7YrGxVaQZx5RNoJLNP2MwhR/jxYDiJ +iQPpvepeRlMJ3Fz1Wuj3RSoC6zFh1ykzTM7HfAo3fg+6MpjhHZevj8fcyTiW89sa +/FHtaMbQbqR8JNGuQsiWUGMu4P51/pinX0kuleM5M2SOHqRfkNJnPLLZ/kG5VacJ +jnIFHovdRIWCQtBJwB1g8NEXLJXr9qXBkqPFwqcIYA1gBBCWeZ4WNOaptvolRTnI +HmX5k/Wq8VLcmZg9pYYaDDUz+kulBAYVHDGA76oYa8J719rO+TMg1fW9ajMtgQT7 +sFzUnKPiXB3jqUJ1XnvUd+85VLrJChgbEplJL4hL/VBi0XPnj3pDAgMBAAGjgZ0w +gZowEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1UdEwEB/wQF +MAMBAf8wHQYDVR0OBBYEFK9EBMJBfkiD2045AuzshHrmzsmkMDQGA1UdHwQtMCsw +KaAnoCWGI2h0dHA6Ly9jcmwuc2VjdXJldHJ1c3QuY29tL1NHQ0EuY3JsMBAGCSsG +AQQBgjcVAQQDAgEAMA0GCSqGSIb3DQEBBQUAA4IBAQBjGghAfaReUw132HquHw0L +URYD7xh8yOOvaliTFGCRsoTciE6+OYo68+aCiV0BN7OrJKQVDpI1WkpEXk5X+nXO +H0jOZvQ8QCaSmGwb7iRGDBezUqXbpZGRzzfTb+cnCDpOGR86p1hcF895P4vkp9Mm +I50mD1hp/Ed+stCNi5O/KU9DaXR2Z0vPB4zmAve14bRDtUstFJ/53CYNv6ZHdAbY +iNE6KTCEztI5gGIbqMdXSbxqVVFnFUq+NQfk1XWYN3kwFNspnWzFacxHVaIw98xc +f8LDmBxrThaA63p4ZUWiABqvDA1VZDRIuJK58bRQKfJPIx/abKwfROHdI3hRW8cW +-----END CERTIFICATE----- + +# Issuer: CN=COMODO Certification Authority O=COMODO CA Limited +# Subject: CN=COMODO Certification Authority O=COMODO CA Limited +# Label: "COMODO Certification Authority" +# Serial: 104350513648249232941998508985834464573 +# MD5 Fingerprint: 5c:48:dc:f7:42:72:ec:56:94:6d:1c:cc:71:35:80:75 +# SHA1 Fingerprint: 66:31:bf:9e:f7:4f:9e:b6:c9:d5:a6:0c:ba:6a:be:d1:f7:bd:ef:7b +# SHA256 Fingerprint: 0c:2c:d6:3d:f7:80:6f:a3:99:ed:e8:09:11:6b:57:5b:f8:79:89:f0:65:18:f9:80:8c:86:05:03:17:8b:af:66 +-----BEGIN CERTIFICATE----- +MIIEHTCCAwWgAwIBAgIQToEtioJl4AsC7j41AkblPTANBgkqhkiG9w0BAQUFADCB +gTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G +A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxJzAlBgNV +BAMTHkNPTU9ETyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjEyMDEwMDAw +MDBaFw0yOTEyMzEyMzU5NTlaMIGBMQswCQYDVQQGEwJHQjEbMBkGA1UECBMSR3Jl +YXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFDT01P +RE8gQ0EgTGltaXRlZDEnMCUGA1UEAxMeQ09NT0RPIENlcnRpZmljYXRpb24gQXV0 +aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ECLi3LjkRv3 +UcEbVASY06m/weaKXTuH+7uIzg3jLz8GlvCiKVCZrts7oVewdFFxze1CkU1B/qnI +2GqGd0S7WWaXUF601CxwRM/aN5VCaTwwxHGzUvAhTaHYujl8HJ6jJJ3ygxaYqhZ8 +Q5sVW7euNJH+1GImGEaaP+vB+fGQV+useg2L23IwambV4EajcNxo2f8ESIl33rXp ++2dtQem8Ob0y2WIC8bGoPW43nOIv4tOiJovGuFVDiOEjPqXSJDlqR6sA1KGzqSX+ +DT+nHbrTUcELpNqsOO9VUCQFZUaTNE8tja3G1CEZ0o7KBWFxB3NH5YoZEr0ETc5O +nKVIrLsm9wIDAQABo4GOMIGLMB0GA1UdDgQWBBQLWOWLxkwVN6RAqTCpIb5HNlpW +/zAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zBJBgNVHR8EQjBAMD6g +PKA6hjhodHRwOi8vY3JsLmNvbW9kb2NhLmNvbS9DT01PRE9DZXJ0aWZpY2F0aW9u +QXV0aG9yaXR5LmNybDANBgkqhkiG9w0BAQUFAAOCAQEAPpiem/Yb6dc5t3iuHXIY +SdOH5EOC6z/JqvWote9VfCFSZfnVDeFs9D6Mk3ORLgLETgdxb8CPOGEIqB6BCsAv +IC9Bi5HcSEW88cbeunZrM8gALTFGTO3nnc+IlP8zwFboJIYmuNg4ON8qa90SzMc/ +RxdMosIGlgnW2/4/PEZB31jiVg88O8EckzXZOFKs7sjsLjBOlDW0JB9LeGna8gI4 +zJVSk/BwJVmcIGfE7vmLV2H0knZ9P4SNVbfo5azV8fUZVqZa+5Acr5Pr5RzUZ5dd +BA6+C4OmF4O5MBKgxTMVBbkN+8cFduPYSo38NBejxiEovjBFMR7HeL5YYTisO+IB +ZQ== +-----END CERTIFICATE----- + +# Issuer: CN=Network Solutions Certificate Authority O=Network Solutions L.L.C. +# Subject: CN=Network Solutions Certificate Authority O=Network Solutions L.L.C. +# Label: "Network Solutions Certificate Authority" +# Serial: 116697915152937497490437556386812487904 +# MD5 Fingerprint: d3:f3:a6:16:c0:fa:6b:1d:59:b1:2d:96:4d:0e:11:2e +# SHA1 Fingerprint: 74:f8:a3:c3:ef:e7:b3:90:06:4b:83:90:3c:21:64:60:20:e5:df:ce +# SHA256 Fingerprint: 15:f0:ba:00:a3:ac:7a:f3:ac:88:4c:07:2b:10:11:a0:77:bd:77:c0:97:f4:01:64:b2:f8:59:8a:bd:83:86:0c +-----BEGIN CERTIFICATE----- +MIID5jCCAs6gAwIBAgIQV8szb8JcFuZHFhfjkDFo4DANBgkqhkiG9w0BAQUFADBi +MQswCQYDVQQGEwJVUzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMu +MTAwLgYDVQQDEydOZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3Jp +dHkwHhcNMDYxMjAxMDAwMDAwWhcNMjkxMjMxMjM1OTU5WjBiMQswCQYDVQQGEwJV +UzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMuMTAwLgYDVQQDEydO +ZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDkvH6SMG3G2I4rC7xGzuAnlt7e+foS0zwz +c7MEL7xxjOWftiJgPl9dzgn/ggwbmlFQGiaJ3dVhXRncEg8tCqJDXRfQNJIg6nPP +OCwGJgl6cvf6UDL4wpPTaaIjzkGxzOTVHzbRijr4jGPiFFlp7Q3Tf2vouAPlT2rl +mGNpSAW+Lv8ztumXWWn4Zxmuk2GWRBXTcrA/vGp97Eh/jcOrqnErU2lBUzS1sLnF +BgrEsEX1QV1uiUV7PTsmjHTC5dLRfbIR1PtYMiKagMnc/Qzpf14Dl847ABSHJ3A4 +qY5usyd2mFHgBeMhqxrVhSI8KbWaFsWAqPS7azCPL0YCorEMIuDTAgMBAAGjgZcw +gZQwHQYDVR0OBBYEFCEwyfsA106Y2oeqKtCnLrFAMadMMA4GA1UdDwEB/wQEAwIB +BjAPBgNVHRMBAf8EBTADAQH/MFIGA1UdHwRLMEkwR6BFoEOGQWh0dHA6Ly9jcmwu +bmV0c29sc3NsLmNvbS9OZXR3b3JrU29sdXRpb25zQ2VydGlmaWNhdGVBdXRob3Jp +dHkuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQC7rkvnt1frf6ott3NHhWrB5KUd5Oc8 +6fRZZXe1eltajSU24HqXLjjAV2CDmAaDn7l2em5Q4LqILPxFzBiwmZVRDuwduIj/ +h1AcgsLj4DKAv6ALR8jDMe+ZZzKATxcheQxpXN5eNK4CtSbqUN9/GGUsyfJj4akH +/nxxH2szJGoeBfcFaMBqEssuXmHLrijTfsK0ZpEmXzwuJF/LWA/rKOyvEZbz3Htv +wKeI8lN3s2Berq4o2jUsbzRF0ybh3uxbTydrFny9RAQYgrOJeRcQcT16ohZO9QHN +pGxlaKFJdlxDydi8NmdspZS11My5vWo1ViHe2MPr+8ukYEywVaCge1ey +-----END CERTIFICATE----- + +# Issuer: CN=COMODO ECC Certification Authority O=COMODO CA Limited +# Subject: CN=COMODO ECC Certification Authority O=COMODO CA Limited +# Label: "COMODO ECC Certification Authority" +# Serial: 41578283867086692638256921589707938090 +# MD5 Fingerprint: 7c:62:ff:74:9d:31:53:5e:68:4a:d5:78:aa:1e:bf:23 +# SHA1 Fingerprint: 9f:74:4e:9f:2b:4d:ba:ec:0f:31:2c:50:b6:56:3b:8e:2d:93:c3:11 +# SHA256 Fingerprint: 17:93:92:7a:06:14:54:97:89:ad:ce:2f:8f:34:f7:f0:b6:6d:0f:3a:e3:a3:b8:4d:21:ec:15:db:ba:4f:ad:c7 +-----BEGIN CERTIFICATE----- +MIICiTCCAg+gAwIBAgIQH0evqmIAcFBUTAGem2OZKjAKBggqhkjOPQQDAzCBhTEL +MAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE +BxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMT +IkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwMzA2MDAw +MDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdy +ZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09N +T0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlv +biBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQDR3svdcmCFYX7deSR +FtSrYpn1PlILBs5BAH+X4QokPB0BBO490o0JlwzgdeT6+3eKKvUDYEs2ixYjFq0J +cfRK9ChQtP6IHG4/bC8vCVlbpVsLM5niwz2J+Wos77LTBumjQjBAMB0GA1UdDgQW +BBR1cacZSBm8nZ3qQUfflMRId5nTeTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/ +BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjEA7wNbeqy3eApyt4jf/7VGFAkK+qDm +fQjGGoe9GKhzvSbKYAydzpmfz1wPMOG+FDHqAjAU9JM8SaczepBGR7NjfRObTrdv +GDeAU/7dIOA1mjbRxwG55tzd8/8dLDoWV9mSOdY= +-----END CERTIFICATE----- + +# Issuer: CN=Certigna O=Dhimyotis +# Subject: CN=Certigna O=Dhimyotis +# Label: "Certigna" +# Serial: 18364802974209362175 +# MD5 Fingerprint: ab:57:a6:5b:7d:42:82:19:b5:d8:58:26:28:5e:fd:ff +# SHA1 Fingerprint: b1:2e:13:63:45:86:a4:6f:1a:b2:60:68:37:58:2d:c4:ac:fd:94:97 +# SHA256 Fingerprint: e3:b6:a2:db:2e:d7:ce:48:84:2f:7a:c5:32:41:c7:b7:1d:54:14:4b:fb:40:c1:1f:3f:1d:0b:42:f5:ee:a1:2d +-----BEGIN CERTIFICATE----- +MIIDqDCCApCgAwIBAgIJAP7c4wEPyUj/MA0GCSqGSIb3DQEBBQUAMDQxCzAJBgNV +BAYTAkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hMB4X +DTA3MDYyOTE1MTMwNVoXDTI3MDYyOTE1MTMwNVowNDELMAkGA1UEBhMCRlIxEjAQ +BgNVBAoMCURoaW15b3RpczERMA8GA1UEAwwIQ2VydGlnbmEwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQDIaPHJ1tazNHUmgh7stL7qXOEm7RFHYeGifBZ4 +QCHkYJ5ayGPhxLGWkv8YbWkj4Sti993iNi+RB7lIzw7sebYs5zRLcAglozyHGxny +gQcPOJAZ0xH+hrTy0V4eHpbNgGzOOzGTtvKg0KmVEn2lmsxryIRWijOp5yIVUxbw +zBfsV1/pogqYCd7jX5xv3EjjhQsVWqa6n6xI4wmy9/Qy3l40vhx4XUJbzg4ij02Q +130yGLMLLGq/jj8UEYkgDncUtT2UCIf3JR7VsmAA7G8qKCVuKj4YYxclPz5EIBb2 +JsglrgVKtOdjLPOMFlN+XPsRGgjBRmKfIrjxwo1p3Po6WAbfAgMBAAGjgbwwgbkw +DwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUGu3+QTmQtCRZvgHyUtVF9lo53BEw +ZAYDVR0jBF0wW4AUGu3+QTmQtCRZvgHyUtVF9lo53BGhOKQ2MDQxCzAJBgNVBAYT +AkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hggkA/tzj +AQ/JSP8wDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIABzANBgkqhkiG +9w0BAQUFAAOCAQEAhQMeknH2Qq/ho2Ge6/PAD/Kl1NqV5ta+aDY9fm4fTIrv0Q8h +bV6lUmPOEvjvKtpv6zf+EwLHyzs+ImvaYS5/1HI93TDhHkxAGYwP15zRgzB7mFnc +fca5DClMoTOi62c6ZYTTluLtdkVwj7Ur3vkj1kluPBS1xp81HlDQwY9qcEQCYsuu +HWhBp6pX6FOqB9IG9tUUBguRA3UsbHK1YZWaDYu5Def131TN3ubY1gkIl2PlwS6w +t0QmwCbAr1UwnjvVNioZBPRcHv/PLLf/0P2HQBHVESO7SMAhqaQoLf0V+LBOK/Qw +WyH8EZE0vkHve52Xdf+XlcCWWC/qu0bXu+TZLg== +-----END CERTIFICATE----- + +# Issuer: CN=Cybertrust Global Root O=Cybertrust, Inc +# Subject: CN=Cybertrust Global Root O=Cybertrust, Inc +# Label: "Cybertrust Global Root" +# Serial: 4835703278459682877484360 +# MD5 Fingerprint: 72:e4:4a:87:e3:69:40:80:77:ea:bc:e3:f4:ff:f0:e1 +# SHA1 Fingerprint: 5f:43:e5:b1:bf:f8:78:8c:ac:1c:c7:ca:4a:9a:c6:22:2b:cc:34:c6 +# SHA256 Fingerprint: 96:0a:df:00:63:e9:63:56:75:0c:29:65:dd:0a:08:67:da:0b:9c:bd:6e:77:71:4a:ea:fb:23:49:ab:39:3d:a3 +-----BEGIN CERTIFICATE----- +MIIDoTCCAomgAwIBAgILBAAAAAABD4WqLUgwDQYJKoZIhvcNAQEFBQAwOzEYMBYG +A1UEChMPQ3liZXJ0cnVzdCwgSW5jMR8wHQYDVQQDExZDeWJlcnRydXN0IEdsb2Jh +bCBSb290MB4XDTA2MTIxNTA4MDAwMFoXDTIxMTIxNTA4MDAwMFowOzEYMBYGA1UE +ChMPQ3liZXJ0cnVzdCwgSW5jMR8wHQYDVQQDExZDeWJlcnRydXN0IEdsb2JhbCBS +b290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA+Mi8vRRQZhP/8NN5 +7CPytxrHjoXxEnOmGaoQ25yiZXRadz5RfVb23CO21O1fWLE3TdVJDm71aofW0ozS +J8bi/zafmGWgE07GKmSb1ZASzxQG9Dvj1Ci+6A74q05IlG2OlTEQXO2iLb3VOm2y +HLtgwEZLAfVJrn5GitB0jaEMAs7u/OePuGtm839EAL9mJRQr3RAwHQeWP032a7iP +t3sMpTjr3kfb1V05/Iin89cqdPHoWqI7n1C6poxFNcJQZZXcY4Lv3b93TZxiyWNz +FtApD0mpSPCzqrdsxacwOUBdrsTiXSZT8M4cIwhhqJQZugRiQOwfOHB3EgZxpzAY +XSUnpQIDAQABo4GlMIGiMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/ +MB0GA1UdDgQWBBS2CHsNesysIEyGVjJez6tuhS1wVzA/BgNVHR8EODA2MDSgMqAw +hi5odHRwOi8vd3d3Mi5wdWJsaWMtdHJ1c3QuY29tL2NybC9jdC9jdHJvb3QuY3Js +MB8GA1UdIwQYMBaAFLYIew16zKwgTIZWMl7Pq26FLXBXMA0GCSqGSIb3DQEBBQUA +A4IBAQBW7wojoFROlZfJ+InaRcHUowAl9B8Tq7ejhVhpwjCt2BWKLePJzYFa+HMj +Wqd8BfP9IjsO0QbE2zZMcwSO5bAi5MXzLqXZI+O4Tkogp24CJJ8iYGd7ix1yCcUx +XOl5n4BHPa2hCwcUPUf/A2kaDAtE52Mlp3+yybh2hO0j9n0Hq0V+09+zv+mKts2o +omcrUtW3ZfA5TGOgkXmTUg9U3YO7n9GPp1Nzw8v/MOx8BLjYRB+TX3EJIrduPuoc +A06dGiBh+4E37F78CkWr1+cXVdCg6mCbpvbjjFspwgZgFJ0tl0ypkxWdYcQBX0jW +WL1WMRJOEcgh4LMRkWXbtKaIOM5V +-----END CERTIFICATE----- + +# Issuer: O=Chunghwa Telecom Co., Ltd. OU=ePKI Root Certification Authority +# Subject: O=Chunghwa Telecom Co., Ltd. OU=ePKI Root Certification Authority +# Label: "ePKI Root Certification Authority" +# Serial: 28956088682735189655030529057352760477 +# MD5 Fingerprint: 1b:2e:00:ca:26:06:90:3d:ad:fe:6f:15:68:d3:6b:b3 +# SHA1 Fingerprint: 67:65:0d:f1:7e:8e:7e:5b:82:40:a4:f4:56:4b:cf:e2:3d:69:c6:f0 +# SHA256 Fingerprint: c0:a6:f4:dc:63:a2:4b:fd:cf:54:ef:2a:6a:08:2a:0a:72:de:35:80:3e:2f:f5:ff:52:7a:e5:d8:72:06:df:d5 +-----BEGIN CERTIFICATE----- +MIIFsDCCA5igAwIBAgIQFci9ZUdcr7iXAF7kBtK8nTANBgkqhkiG9w0BAQUFADBe +MQswCQYDVQQGEwJUVzEjMCEGA1UECgwaQ2h1bmdod2EgVGVsZWNvbSBDby4sIEx0 +ZC4xKjAoBgNVBAsMIWVQS0kgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAe +Fw0wNDEyMjAwMjMxMjdaFw0zNDEyMjAwMjMxMjdaMF4xCzAJBgNVBAYTAlRXMSMw +IQYDVQQKDBpDaHVuZ2h3YSBUZWxlY29tIENvLiwgTHRkLjEqMCgGA1UECwwhZVBL +SSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkqhkiG9w0BAQEF +AAOCAg8AMIICCgKCAgEA4SUP7o3biDN1Z82tH306Tm2d0y8U82N0ywEhajfqhFAH +SyZbCUNsIZ5qyNUD9WBpj8zwIuQf5/dqIjG3LBXy4P4AakP/h2XGtRrBp0xtInAh +ijHyl3SJCRImHJ7K2RKilTza6We/CKBk49ZCt0Xvl/T29de1ShUCWH2YWEtgvM3X +DZoTM1PRYfl61dd4s5oz9wCGzh1NlDivqOx4UXCKXBCDUSH3ET00hl7lSM2XgYI1 +TBnsZfZrxQWh7kcT1rMhJ5QQCtkkO7q+RBNGMD+XPNjX12ruOzjjK9SXDrkb5wdJ +fzcq+Xd4z1TtW0ado4AOkUPB1ltfFLqfpo0kR0BZv3I4sjZsN/+Z0V0OWQqraffA +sgRFelQArr5T9rXn4fg8ozHSqf4hUmTFpmfwdQcGlBSBVcYn5AGPF8Fqcde+S/uU +WH1+ETOxQvdibBjWzwloPn9s9h6PYq2lY9sJpx8iQkEeb5mKPtf5P0B6ebClAZLS +nT0IFaUQAS2zMnaolQ2zepr7BxB4EW/hj8e6DyUadCrlHJhBmd8hh+iVBmoKs2pH +dmX2Os+PYhcZewoozRrSgx4hxyy/vv9haLdnG7t4TY3OZ+XkwY63I2binZB1NJip +NiuKmpS5nezMirH4JYlcWrYvjB9teSSnUmjDhDXiZo1jDiVN1Rmy5nk3pyKdVDEC +AwEAAaNqMGgwHQYDVR0OBBYEFB4M97Zn8uGSJglFwFU5Lnc/QkqiMAwGA1UdEwQF +MAMBAf8wOQYEZyoHAAQxMC8wLQIBADAJBgUrDgMCGgUAMAcGBWcqAwAABBRFsMLH +ClZ87lt4DJX5GFPBphzYEDANBgkqhkiG9w0BAQUFAAOCAgEACbODU1kBPpVJufGB +uvl2ICO1J2B01GqZNF5sAFPZn/KmsSQHRGoqxqWOeBLoR9lYGxMqXnmbnwoqZ6Yl +PwZpVnPDimZI+ymBV3QGypzqKOg4ZyYr8dW1P2WT+DZdjo2NQCCHGervJ8A9tDkP +JXtoUHRVnAxZfVo9QZQlUgjgRywVMRnVvwdVxrsStZf0X4OFunHB2WyBEXYKCrC/ +gpf36j36+uwtqSiUO1bd0lEursC9CBWMd1I0ltabrNMdjmEPNXubrjlpC2JgQCA2 +j6/7Nu4tCEoduL+bXPjqpRugc6bY+G7gMwRfaKonh+3ZwZCc7b3jajWvY9+rGNm6 +5ulK6lCKD2GTHuItGeIwlDWSXQ62B68ZgI9HkFFLLk3dheLSClIKF5r8GrBQAuUB +o2M3IUxExJtRmREOc5wGj1QupyheRDmHVi03vYVElOEMSyycw5KFNGHLD7ibSkNS +/jQ6fbjpKdx2qcgw+BRxgMYeNkh0IkFch4LoGHGLQYlE535YW6i4jRPpp2zDR+2z +Gp1iro2C6pSe3VkQw63d4k3jMdXH7OjysP6SHhYKGvzZ8/gntsm+HbRsZJB/9OTE +W9c3rkIO3aQab3yIVMUWbuF6aC74Or8NpDyJO3inTmODBCEIZ43ygknQW/2xzQ+D +hNQ+IIX3Sj0rnP0qCglN6oH4EZw= +-----END CERTIFICATE----- + +# Issuer: O=certSIGN OU=certSIGN ROOT CA +# Subject: O=certSIGN OU=certSIGN ROOT CA +# Label: "certSIGN ROOT CA" +# Serial: 35210227249154 +# MD5 Fingerprint: 18:98:c0:d6:e9:3a:fc:f9:b0:f5:0c:f7:4b:01:44:17 +# SHA1 Fingerprint: fa:b7:ee:36:97:26:62:fb:2d:b0:2a:f6:bf:03:fd:e8:7c:4b:2f:9b +# SHA256 Fingerprint: ea:a9:62:c4:fa:4a:6b:af:eb:e4:15:19:6d:35:1c:cd:88:8d:4f:53:f3:fa:8a:e6:d7:c4:66:a9:4e:60:42:bb +-----BEGIN CERTIFICATE----- +MIIDODCCAiCgAwIBAgIGIAYFFnACMA0GCSqGSIb3DQEBBQUAMDsxCzAJBgNVBAYT +AlJPMREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBD +QTAeFw0wNjA3MDQxNzIwMDRaFw0zMTA3MDQxNzIwMDRaMDsxCzAJBgNVBAYTAlJP +MREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBDQTCC +ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALczuX7IJUqOtdu0KBuqV5Do +0SLTZLrTk+jUrIZhQGpgV2hUhE28alQCBf/fm5oqrl0Hj0rDKH/v+yv6efHHrfAQ +UySQi2bJqIirr1qjAOm+ukbuW3N7LBeCgV5iLKECZbO9xSsAfsT8AzNXDe3i+s5d +RdY4zTW2ssHQnIFKquSyAVwdj1+ZxLGt24gh65AIgoDzMKND5pCCrlUoSe1b16kQ +OA7+j0xbm0bqQfWwCHTD0IgztnzXdN/chNFDDnU5oSVAKOp4yw4sLjmdjItuFhwv +JoIQ4uNllAoEwF73XVv4EOLQunpL+943AAAaWyjj0pxzPjKHmKHJUS/X3qwzs08C +AwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAcYwHQYDVR0O +BBYEFOCMm9slSbPxfIbWskKHC9BroNnkMA0GCSqGSIb3DQEBBQUAA4IBAQA+0hyJ +LjX8+HXd5n9liPRyTMks1zJO890ZeUe9jjtbkw9QSSQTaxQGcu8J06Gh40CEyecY +MnQ8SG4Pn0vU9x7Tk4ZkVJdjclDVVc/6IJMCopvDI5NOFlV2oHB5bc0hH88vLbwZ +44gx+FkagQnIl6Z0x2DEW8xXjrJ1/RsCCdtZb3KTafcxQdaIOL+Hsr0Wefmq5L6I +Jd1hJyMctTEHBDa0GpC9oHRxUIltvBTjD4au8as+x6AJzKNI0eDbZOeStc+vckNw +i/nDhDwTqn6Sm1dTk/pwwpEOMfmbZ13pljheX7NzTogVZ96edhBiIL5VaZVDADlN +9u6wWk5JRFRYX0KD +-----END CERTIFICATE----- + +# Issuer: CN=GeoTrust Primary Certification Authority - G2 O=GeoTrust Inc. OU=(c) 2007 GeoTrust Inc. - For authorized use only +# Subject: CN=GeoTrust Primary Certification Authority - G2 O=GeoTrust Inc. OU=(c) 2007 GeoTrust Inc. - For authorized use only +# Label: "GeoTrust Primary Certification Authority - G2" +# Serial: 80682863203381065782177908751794619243 +# MD5 Fingerprint: 01:5e:d8:6b:bd:6f:3d:8e:a1:31:f8:12:e0:98:73:6a +# SHA1 Fingerprint: 8d:17:84:d5:37:f3:03:7d:ec:70:fe:57:8b:51:9a:99:e6:10:d7:b0 +# SHA256 Fingerprint: 5e:db:7a:c4:3b:82:a0:6a:87:61:e8:d7:be:49:79:eb:f2:61:1f:7d:d7:9b:f9:1c:1c:6b:56:6a:21:9e:d7:66 +-----BEGIN CERTIFICATE----- +MIICrjCCAjWgAwIBAgIQPLL0SAoA4v7rJDteYD7DazAKBggqhkjOPQQDAzCBmDEL +MAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsTMChj +KSAyMDA3IEdlb1RydXN0IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTE2 +MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0 +eSAtIEcyMB4XDTA3MTEwNTAwMDAwMFoXDTM4MDExODIzNTk1OVowgZgxCzAJBgNV +BAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAoYykgMjAw +NyBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0BgNV +BAMTLUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBH +MjB2MBAGByqGSM49AgEGBSuBBAAiA2IABBWx6P0DFUPlrOuHNxFi79KDNlJ9RVcL +So17VDs6bl8VAsBQps8lL33KSLjHUGMcKiEIfJo22Av+0SbFWDEwKCXzXV2juLal +tJLtbCyf691DiaI8S0iRHVDsJt/WYC69IaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO +BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBVfNVdRVfslsq0DafwBo/q+EVXVMAoG +CCqGSM49BAMDA2cAMGQCMGSWWaboCd6LuvpaiIjwH5HTRqjySkwCY/tsXzjbLkGT +qQ7mndwxHLKgpxgceeHHNgIwOlavmnRs9vuD4DPTCF+hnMJbn0bWtsuRBmOiBucz +rD6ogRLQy7rQkgu2npaqBA+K +-----END CERTIFICATE----- + +# Issuer: CN=VeriSign Universal Root Certification Authority O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2008 VeriSign, Inc. - For authorized use only +# Subject: CN=VeriSign Universal Root Certification Authority O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2008 VeriSign, Inc. - For authorized use only +# Label: "VeriSign Universal Root Certification Authority" +# Serial: 85209574734084581917763752644031726877 +# MD5 Fingerprint: 8e:ad:b5:01:aa:4d:81:e4:8c:1d:d1:e1:14:00:95:19 +# SHA1 Fingerprint: 36:79:ca:35:66:87:72:30:4d:30:a5:fb:87:3b:0f:a7:7b:b7:0d:54 +# SHA256 Fingerprint: 23:99:56:11:27:a5:71:25:de:8c:ef:ea:61:0d:df:2f:a0:78:b5:c8:06:7f:4e:82:82:90:bf:b8:60:e8:4b:3c +-----BEGIN CERTIFICATE----- +MIIEuTCCA6GgAwIBAgIQQBrEZCGzEyEDDrvkEhrFHTANBgkqhkiG9w0BAQsFADCB +vTELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL +ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwOCBWZXJp +U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MTgwNgYDVQQDEy9W +ZXJpU2lnbiBVbml2ZXJzYWwgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAe +Fw0wODA0MDIwMDAwMDBaFw0zNzEyMDEyMzU5NTlaMIG9MQswCQYDVQQGEwJVUzEX +MBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0 +IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAyMDA4IFZlcmlTaWduLCBJbmMuIC0gRm9y +IGF1dGhvcml6ZWQgdXNlIG9ubHkxODA2BgNVBAMTL1ZlcmlTaWduIFVuaXZlcnNh +bCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAx2E3XrEBNNti1xWb/1hajCMj1mCOkdeQmIN65lgZOIzF +9uVkhbSicfvtvbnazU0AtMgtc6XHaXGVHzk8skQHnOgO+k1KxCHfKWGPMiJhgsWH +H26MfF8WIFFE0XBPV+rjHOPMee5Y2A7Cs0WTwCznmhcrewA3ekEzeOEz4vMQGn+H +LL729fdC4uW/h2KJXwBL38Xd5HVEMkE6HnFuacsLdUYI0crSK5XQz/u5QGtkjFdN +/BMReYTtXlT2NJ8IAfMQJQYXStrxHXpma5hgZqTZ79IugvHw7wnqRMkVauIDbjPT +rJ9VAMf2CGqUuV/c4DPxhGD5WycRtPwW8rtWaoAljQIDAQABo4GyMIGvMA8GA1Ud +EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMG0GCCsGAQUFBwEMBGEwX6FdoFsw +WTBXMFUWCWltYWdlL2dpZjAhMB8wBwYFKw4DAhoEFI/l0xqGrI2Oa8PPgGrUSBgs +exkuMCUWI2h0dHA6Ly9sb2dvLnZlcmlzaWduLmNvbS92c2xvZ28uZ2lmMB0GA1Ud +DgQWBBS2d/ppSEefUxLVwuoHMnYH0ZcHGTANBgkqhkiG9w0BAQsFAAOCAQEASvj4 +sAPmLGd75JR3Y8xuTPl9Dg3cyLk1uXBPY/ok+myDjEedO2Pzmvl2MpWRsXe8rJq+ +seQxIcaBlVZaDrHC1LGmWazxY8u4TB1ZkErvkBYoH1quEPuBUDgMbMzxPcP1Y+Oz +4yHJJDnp/RVmRvQbEdBNc6N9Rvk97ahfYtTxP/jgdFcrGJ2BtMQo2pSXpXDrrB2+ +BxHw1dvd5Yzw1TKwg+ZX4o+/vqGqvz0dtdQ46tewXDpPaj+PwGZsY6rp2aQW9IHR +lRQOfc2VNNnSj3BzgXucfr2YYdhFh5iQxeuGMMY1v/D/w1WIg0vvBZIGcfK4mJO3 +7M2CYfE45k+XmCpajQ== +-----END CERTIFICATE----- + +# Issuer: CN=NetLock Arany (Class Gold) F\u0151tan\xfas\xedtv\xe1ny O=NetLock Kft. OU=Tan\xfas\xedtv\xe1nykiad\xf3k (Certification Services) +# Subject: CN=NetLock Arany (Class Gold) F\u0151tan\xfas\xedtv\xe1ny O=NetLock Kft. OU=Tan\xfas\xedtv\xe1nykiad\xf3k (Certification Services) +# Label: "NetLock Arany (Class Gold) F\u0151tan\xfas\xedtv\xe1ny" +# Serial: 80544274841616 +# MD5 Fingerprint: c5:a1:b7:ff:73:dd:d6:d7:34:32:18:df:fc:3c:ad:88 +# SHA1 Fingerprint: 06:08:3f:59:3f:15:a1:04:a0:69:a4:6b:a9:03:d0:06:b7:97:09:91 +# SHA256 Fingerprint: 6c:61:da:c3:a2:de:f0:31:50:6b:e0:36:d2:a6:fe:40:19:94:fb:d1:3d:f9:c8:d4:66:59:92:74:c4:46:ec:98 +-----BEGIN CERTIFICATE----- +MIIEFTCCAv2gAwIBAgIGSUEs5AAQMA0GCSqGSIb3DQEBCwUAMIGnMQswCQYDVQQG +EwJIVTERMA8GA1UEBwwIQnVkYXBlc3QxFTATBgNVBAoMDE5ldExvY2sgS2Z0LjE3 +MDUGA1UECwwuVGFuw7pzw610dsOhbnlraWFkw7NrIChDZXJ0aWZpY2F0aW9uIFNl +cnZpY2VzKTE1MDMGA1UEAwwsTmV0TG9jayBBcmFueSAoQ2xhc3MgR29sZCkgRsWR +dGFuw7pzw610dsOhbnkwHhcNMDgxMjExMTUwODIxWhcNMjgxMjA2MTUwODIxWjCB +pzELMAkGA1UEBhMCSFUxETAPBgNVBAcMCEJ1ZGFwZXN0MRUwEwYDVQQKDAxOZXRM +b2NrIEtmdC4xNzA1BgNVBAsMLlRhbsO6c8OtdHbDoW55a2lhZMOzayAoQ2VydGlm +aWNhdGlvbiBTZXJ2aWNlcykxNTAzBgNVBAMMLE5ldExvY2sgQXJhbnkgKENsYXNz +IEdvbGQpIEbFkXRhbsO6c8OtdHbDoW55MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAxCRec75LbRTDofTjl5Bu0jBFHjzuZ9lk4BqKf8owyoPjIMHj9DrT +lF8afFttvzBPhCf2nx9JvMaZCpDyD/V/Q4Q3Y1GLeqVw/HpYzY6b7cNGbIRwXdrz +AZAj/E4wqX7hJ2Pn7WQ8oLjJM2P+FpD/sLj916jAwJRDC7bVWaaeVtAkH3B5r9s5 +VA1lddkVQZQBr17s9o3x/61k/iCa11zr/qYfCGSji3ZVrR47KGAuhyXoqq8fxmRG +ILdwfzzeSNuWU7c5d+Qa4scWhHaXWy+7GRWF+GmF9ZmnqfI0p6m2pgP8b4Y9VHx2 +BJtr+UBdADTHLpl1neWIA6pN+APSQnbAGwIDAKiLo0UwQzASBgNVHRMBAf8ECDAG +AQH/AgEEMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUzPpnk/C2uNClwB7zU/2M +U9+D15YwDQYJKoZIhvcNAQELBQADggEBAKt/7hwWqZw8UQCgwBEIBaeZ5m8BiFRh +bvG5GK1Krf6BQCOUL/t1fC8oS2IkgYIL9WHxHG64YTjrgfpioTtaYtOUZcTh5m2C ++C8lcLIhJsFyUR+MLMOEkMNaj7rP9KdlpeuY0fsFskZ1FSNqb4VjMIDw1Z4fKRzC +bLBQWV2QWzuoDTDPv31/zvGdg73JRm4gpvlhUbohL3u+pRVjodSVh/GeufOJ8z2F +uLjbvrW5KfnaNwUASZQDhETnv0Mxz3WLJdH0pmT1kvarBes96aULNmLazAZfNou2 +XjG4Kvte9nHfRCaexOYNkbQudZWAUWpLMKawYqGT8ZvYzsRjdT9ZR7E= +-----END CERTIFICATE----- + +# Issuer: CN=Hongkong Post Root CA 1 O=Hongkong Post +# Subject: CN=Hongkong Post Root CA 1 O=Hongkong Post +# Label: "Hongkong Post Root CA 1" +# Serial: 1000 +# MD5 Fingerprint: a8:0d:6f:39:78:b9:43:6d:77:42:6d:98:5a:cc:23:ca +# SHA1 Fingerprint: d6:da:a8:20:8d:09:d2:15:4d:24:b5:2f:cb:34:6e:b2:58:b2:8a:58 +# SHA256 Fingerprint: f9:e6:7d:33:6c:51:00:2a:c0:54:c6:32:02:2d:66:dd:a2:e7:e3:ff:f1:0a:d0:61:ed:31:d8:bb:b4:10:cf:b2 +-----BEGIN CERTIFICATE----- +MIIDMDCCAhigAwIBAgICA+gwDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCSEsx +FjAUBgNVBAoTDUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3Qg +Um9vdCBDQSAxMB4XDTAzMDUxNTA1MTMxNFoXDTIzMDUxNTA0NTIyOVowRzELMAkG +A1UEBhMCSEsxFjAUBgNVBAoTDUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdr +b25nIFBvc3QgUm9vdCBDQSAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEArP84tulmAknjorThkPlAj3n54r15/gK97iSSHSL22oVyaf7XPwnU3ZG1ApzQ +jVrhVcNQhrkpJsLj2aDxaQMoIIBFIi1WpztUlVYiWR8o3x8gPW2iNr4joLFutbEn +PzlTCeqrauh0ssJlXI6/fMN4hM2eFvz1Lk8gKgifd/PFHsSaUmYeSF7jEAaPIpjh +ZY4bXSNmO7ilMlHIhqqhqZ5/dpTCpmy3QfDVyAY45tQM4vM7TG1QjMSDJ8EThFk9 +nnV0ttgCXjqQesBCNnLsak3c78QA3xMYV18meMjWCnl3v/evt3a5pQuEF10Q6m/h +q5URX208o1xNg1vysxmKgIsLhwIDAQABoyYwJDASBgNVHRMBAf8ECDAGAQH/AgED +MA4GA1UdDwEB/wQEAwIBxjANBgkqhkiG9w0BAQUFAAOCAQEADkbVPK7ih9legYsC +mEEIjEy82tvuJxuC52pF7BaLT4Wg87JwvVqWuspube5Gi27nKi6Wsxkz67SfqLI3 +7piol7Yutmcn1KZJ/RyTZXaeQi/cImyaT/JaFTmxcdcrUehtHJjA2Sr0oYJ71clB +oiMBdDhViw+5LmeiIAQ32pwL0xch4I+XeTRvhEgCIDMb5jREn5Fw9IBehEPCKdJs +EhTkYY2sEJCehFC78JZvRZ+K88psT/oROhUVRsPNH4NbLUES7VBnQRM9IauUiqpO +fMGx+6fWtScvl6tu4B3i0RwsH0Ti/L6RoZz71ilTc4afU9hDDl3WY4JxHYB0yvbi +AmvZWg== +-----END CERTIFICATE----- + +# Issuer: CN=SecureSign RootCA11 O=Japan Certification Services, Inc. +# Subject: CN=SecureSign RootCA11 O=Japan Certification Services, Inc. +# Label: "SecureSign RootCA11" +# Serial: 1 +# MD5 Fingerprint: b7:52:74:e2:92:b4:80:93:f2:75:e4:cc:d7:f2:ea:26 +# SHA1 Fingerprint: 3b:c4:9f:48:f8:f3:73:a0:9c:1e:bd:f8:5b:b1:c3:65:c7:d8:11:b3 +# SHA256 Fingerprint: bf:0f:ee:fb:9e:3a:58:1a:d5:f9:e9:db:75:89:98:57:43:d2:61:08:5c:4d:31:4f:6f:5d:72:59:aa:42:16:12 +-----BEGIN CERTIFICATE----- +MIIDbTCCAlWgAwIBAgIBATANBgkqhkiG9w0BAQUFADBYMQswCQYDVQQGEwJKUDEr +MCkGA1UEChMiSmFwYW4gQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcywgSW5jLjEcMBoG +A1UEAxMTU2VjdXJlU2lnbiBSb290Q0ExMTAeFw0wOTA0MDgwNDU2NDdaFw0yOTA0 +MDgwNDU2NDdaMFgxCzAJBgNVBAYTAkpQMSswKQYDVQQKEyJKYXBhbiBDZXJ0aWZp +Y2F0aW9uIFNlcnZpY2VzLCBJbmMuMRwwGgYDVQQDExNTZWN1cmVTaWduIFJvb3RD +QTExMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA/XeqpRyQBTvLTJsz +i1oURaTnkBbR31fSIRCkF/3frNYfp+TbfPfs37gD2pRY/V1yfIw/XwFndBWW4wI8 +h9uuywGOwvNmxoVF9ALGOrVisq/6nL+k5tSAMJjzDbaTj6nU2DbysPyKyiyhFTOV +MdrAG/LuYpmGYz+/3ZMqg6h2uRMft85OQoWPIucuGvKVCbIFtUROd6EgvanyTgp9 +UK31BQ1FT0Zx/Sg+U/sE2C3XZR1KG/rPO7AxmjVuyIsG0wCR8pQIZUyxNAYAeoni +8McDWc/V1uinMrPmmECGxc0nEovMe863ETxiYAcjPitAbpSACW22s293bzUIUPsC +h8U+iQIDAQABo0IwQDAdBgNVHQ4EFgQUW/hNT7KlhtQ60vFjmqC+CfZXt94wDgYD +VR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEB +AKChOBZmLqdWHyGcBvod7bkixTgm2E5P7KN/ed5GIaGHd48HCJqypMWvDzKYC3xm +KbabfSVSSUOrTC4rbnpwrxYO4wJs+0LmGJ1F2FXI6Dvd5+H0LgscNFxsWEr7jIhQ +X5Ucv+2rIrVls4W6ng+4reV6G4pQOh29Dbx7VFALuUKvVaAYga1lme++5Jy/xIWr +QbJUb9wlze144o4MjQlJ3WN7WmmWAiGovVJZ6X01y8hSyn+B/tlr0/cR7SXf+Of5 +pPpyl4RTDaXQMhhRdlkUbA/r7F+AjHVDg8OFmP9Mni0N5HeDk061lgeLKBObjBmN +QSdJQO7e5iNEOdyhIta6A/I= +-----END CERTIFICATE----- + +# Issuer: CN=Microsec e-Szigno Root CA 2009 O=Microsec Ltd. +# Subject: CN=Microsec e-Szigno Root CA 2009 O=Microsec Ltd. +# Label: "Microsec e-Szigno Root CA 2009" +# Serial: 14014712776195784473 +# MD5 Fingerprint: f8:49:f4:03:bc:44:2d:83:be:48:69:7d:29:64:fc:b1 +# SHA1 Fingerprint: 89:df:74:fe:5c:f4:0f:4a:80:f9:e3:37:7d:54:da:91:e1:01:31:8e +# SHA256 Fingerprint: 3c:5f:81:fe:a5:fa:b8:2c:64:bf:a2:ea:ec:af:cd:e8:e0:77:fc:86:20:a7:ca:e5:37:16:3d:f3:6e:db:f3:78 +-----BEGIN CERTIFICATE----- +MIIECjCCAvKgAwIBAgIJAMJ+QwRORz8ZMA0GCSqGSIb3DQEBCwUAMIGCMQswCQYD +VQQGEwJIVTERMA8GA1UEBwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0 +ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUtU3ppZ25vIFJvb3QgQ0EgMjAwOTEfMB0G +CSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5odTAeFw0wOTA2MTYxMTMwMThaFw0y +OTEyMzAxMTMwMThaMIGCMQswCQYDVQQGEwJIVTERMA8GA1UEBwwIQnVkYXBlc3Qx +FjAUBgNVBAoMDU1pY3Jvc2VjIEx0ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUtU3pp +Z25vIFJvb3QgQ0EgMjAwOTEfMB0GCSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5o +dTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOn4j/NjrdqG2KfgQvvP +kd6mJviZpWNwrZuuyjNAfW2WbqEORO7hE52UQlKavXWFdCyoDh2Tthi3jCyoz/tc +cbna7P7ofo/kLx2yqHWH2Leh5TvPmUpG0IMZfcChEhyVbUr02MelTTMuhTlAdX4U +fIASmFDHQWe4oIBhVKZsTh/gnQ4H6cm6M+f+wFUoLAKApxn1ntxVUwOXewdI/5n7 +N4okxFnMUBBjjqqpGrCEGob5X7uxUG6k0QrM1XF+H6cbfPVTbiJfyyvm1HxdrtbC +xkzlBQHZ7Vf8wSN5/PrIJIOV87VqUQHQd9bpEqH5GoP7ghu5sJf0dgYzQ0mg/wu1 ++rUCAwEAAaOBgDB+MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0G +A1UdDgQWBBTLD8bfQkPMPcu1SCOhGnqmKrs0aDAfBgNVHSMEGDAWgBTLD8bfQkPM +Pcu1SCOhGnqmKrs0aDAbBgNVHREEFDASgRBpbmZvQGUtc3ppZ25vLmh1MA0GCSqG +SIb3DQEBCwUAA4IBAQDJ0Q5eLtXMs3w+y/w9/w0olZMEyL/azXm4Q5DwpL7v8u8h +mLzU1F0G9u5C7DBsoKqpyvGvivo/C3NqPuouQH4frlRheesuCDfXI/OMn74dseGk +ddug4lQUsbocKaQY9hK6ohQU4zE1yED/t+AFdlfBHFny+L/k7SViXITwfn4fs775 +tyERzAMBVnCnEJIeGzSBHq2cGsMEPO0CYdYeBvNfOofyK/FFh+U9rNHHV4S9a67c +2Pm2G2JwCz02yULyMtd6YebS2z3PyKnJm9zbWETXbzivf3jTo60adbocwTZ8jx5t +HMN1Rq41Bab2XD0h7lbwyYIiLXpUq3DDfSJlgnCW +-----END CERTIFICATE----- + +# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R3 +# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R3 +# Label: "GlobalSign Root CA - R3" +# Serial: 4835703278459759426209954 +# MD5 Fingerprint: c5:df:b8:49:ca:05:13:55:ee:2d:ba:1a:c3:3e:b0:28 +# SHA1 Fingerprint: d6:9b:56:11:48:f0:1c:77:c5:45:78:c1:09:26:df:5b:85:69:76:ad +# SHA256 Fingerprint: cb:b5:22:d7:b7:f1:27:ad:6a:01:13:86:5b:df:1c:d4:10:2e:7d:07:59:af:63:5a:7c:f4:72:0d:c9:63:c5:3b +-----BEGIN CERTIFICATE----- +MIIDXzCCAkegAwIBAgILBAAAAAABIVhTCKIwDQYJKoZIhvcNAQELBQAwTDEgMB4G +A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNp +Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDkwMzE4MTAwMDAwWhcNMjkwMzE4 +MTAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMzETMBEG +A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAMwldpB5BngiFvXAg7aEyiie/QV2EcWtiHL8 +RgJDx7KKnQRfJMsuS+FggkbhUqsMgUdwbN1k0ev1LKMPgj0MK66X17YUhhB5uzsT +gHeMCOFJ0mpiLx9e+pZo34knlTifBtc+ycsmWQ1z3rDI6SYOgxXG71uL0gRgykmm +KPZpO/bLyCiR5Z2KYVc3rHQU3HTgOu5yLy6c+9C7v/U9AOEGM+iCK65TpjoWc4zd +QQ4gOsC0p6Hpsk+QLjJg6VfLuQSSaGjlOCZgdbKfd/+RFO+uIEn8rUAVSNECMWEZ +XriX7613t2Saer9fwRPvm2L7DWzgVGkWqQPabumDk3F2xmmFghcCAwEAAaNCMEAw +DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFI/wS3+o +LkUkrk1Q+mOai97i3Ru8MA0GCSqGSIb3DQEBCwUAA4IBAQBLQNvAUKr+yAzv95ZU +RUm7lgAJQayzE4aGKAczymvmdLm6AC2upArT9fHxD4q/c2dKg8dEe3jgr25sbwMp +jjM5RcOO5LlXbKr8EpbsU8Yt5CRsuZRj+9xTaGdWPoO4zzUhw8lo/s7awlOqzJCK +6fBdRoyV3XpYKBovHd7NADdBj+1EbddTKJd+82cEHhXXipa0095MJ6RMG3NzdvQX +mcIfeg7jLQitChws/zyrVQ4PkX4268NXSb7hLi18YIvDQVETI53O9zJrlAGomecs +Mx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7rkpeDMdmztcpH +WD9f +-----END CERTIFICATE----- + +# Issuer: CN=Autoridad de Certificacion Firmaprofesional CIF A62634068 +# Subject: CN=Autoridad de Certificacion Firmaprofesional CIF A62634068 +# Label: "Autoridad de Certificacion Firmaprofesional CIF A62634068" +# Serial: 6047274297262753887 +# MD5 Fingerprint: 73:3a:74:7a:ec:bb:a3:96:a6:c2:e4:e2:c8:9b:c0:c3 +# SHA1 Fingerprint: ae:c5:fb:3f:c8:e1:bf:c4:e5:4f:03:07:5a:9a:e8:00:b7:f7:b6:fa +# SHA256 Fingerprint: 04:04:80:28:bf:1f:28:64:d4:8f:9a:d4:d8:32:94:36:6a:82:88:56:55:3f:3b:14:30:3f:90:14:7f:5d:40:ef +-----BEGIN CERTIFICATE----- +MIIGFDCCA/ygAwIBAgIIU+w77vuySF8wDQYJKoZIhvcNAQEFBQAwUTELMAkGA1UE +BhMCRVMxQjBABgNVBAMMOUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1h +cHJvZmVzaW9uYWwgQ0lGIEE2MjYzNDA2ODAeFw0wOTA1MjAwODM4MTVaFw0zMDEy +MzEwODM4MTVaMFExCzAJBgNVBAYTAkVTMUIwQAYDVQQDDDlBdXRvcmlkYWQgZGUg +Q2VydGlmaWNhY2lvbiBGaXJtYXByb2Zlc2lvbmFsIENJRiBBNjI2MzQwNjgwggIi +MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKlmuO6vj78aI14H9M2uDDUtd9 +thDIAl6zQyrET2qyyhxdKJp4ERppWVevtSBC5IsP5t9bpgOSL/UR5GLXMnE42QQM +cas9UX4PB99jBVzpv5RvwSmCwLTaUbDBPLutN0pcyvFLNg4kq7/DhHf9qFD0sefG +L9ItWY16Ck6WaVICqjaY7Pz6FIMMNx/Jkjd/14Et5cS54D40/mf0PmbR0/RAz15i +NA9wBj4gGFrO93IbJWyTdBSTo3OxDqqHECNZXyAFGUftaI6SEspd/NYrspI8IM/h +X68gvqB2f3bl7BqGYTM+53u0P6APjqK5am+5hyZvQWyIplD9amML9ZMWGxmPsu2b +m8mQ9QEM3xk9Dz44I8kvjwzRAv4bVdZO0I08r0+k8/6vKtMFnXkIoctXMbScyJCy +Z/QYFpM6/EfY0XiWMR+6KwxfXZmtY4laJCB22N/9q06mIqqdXuYnin1oKaPnirja +EbsXLZmdEyRG98Xi2J+Of8ePdG1asuhy9azuJBCtLxTa/y2aRnFHvkLfuwHb9H/T +KI8xWVvTyQKmtFLKbpf7Q8UIJm+K9Lv9nyiqDdVF8xM6HdjAeI9BZzwelGSuewvF +6NkBiDkal4ZkQdU7hwxu+g/GvUgUvzlN1J5Bto+WHWOWk9mVBngxaJ43BjuAiUVh +OSPHG0SjFeUc+JIwuwIDAQABo4HvMIHsMBIGA1UdEwEB/wQIMAYBAf8CAQEwDgYD +VR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRlzeurNR4APn7VdMActHNHDhpkLzCBpgYD +VR0gBIGeMIGbMIGYBgRVHSAAMIGPMC8GCCsGAQUFBwIBFiNodHRwOi8vd3d3LmZp +cm1hcHJvZmVzaW9uYWwuY29tL2NwczBcBggrBgEFBQcCAjBQHk4AUABhAHMAZQBv +ACAAZABlACAAbABhACAAQgBvAG4AYQBuAG8AdgBhACAANAA3ACAAQgBhAHIAYwBl +AGwAbwBuAGEAIAAwADgAMAAxADcwDQYJKoZIhvcNAQEFBQADggIBABd9oPm03cXF +661LJLWhAqvdpYhKsg9VSytXjDvlMd3+xDLx51tkljYyGOylMnfX40S2wBEqgLk9 +am58m9Ot/MPWo+ZkKXzR4Tgegiv/J2Wv+xYVxC5xhOW1//qkR71kMrv2JYSiJ0L1 +ILDCExARzRAVukKQKtJE4ZYm6zFIEv0q2skGz3QeqUvVhyj5eTSSPi5E6PaPT481 +PyWzOdxjKpBrIF/EUhJOlywqrJ2X3kjyo2bbwtKDlaZmp54lD+kLM5FlClrD2VQS +3a/DTg4fJl4N3LON7NWBcN7STyQF82xO9UxJZo3R/9ILJUFI/lGExkKvgATP0H5k +SeTy36LssUzAKh3ntLFlosS88Zj0qnAHY7S42jtM+kAiMFsRpvAFDsYCA0irhpuF +3dvd6qJ2gHN99ZwExEWN57kci57q13XRcrHedUTnQn3iV2t93Jm8PYMo6oCTjcVM +ZcFwgbg4/EMxsvYDNEeyrPsiBsse3RdHHF9mudMaotoRsaS8I8nkvof/uZS2+F0g +StRf571oe2XyFR7SOqkt6dhrJKyXWERHrVkY8SFlcN7ONGCoQPHzPKTDKCOM/icz +Q0CgFzzr6juwcqajuUpLXhZI9LK8yIySxZ2frHI2vDSANGupi5LAuBft7HZT9SQB +jLMi6Et8Vcad+qMUu2WFbm5PEn4KPJ2V +-----END CERTIFICATE----- + +# Issuer: CN=Izenpe.com O=IZENPE S.A. +# Subject: CN=Izenpe.com O=IZENPE S.A. +# Label: "Izenpe.com" +# Serial: 917563065490389241595536686991402621 +# MD5 Fingerprint: a6:b0:cd:85:80:da:5c:50:34:a3:39:90:2f:55:67:73 +# SHA1 Fingerprint: 2f:78:3d:25:52:18:a7:4a:65:39:71:b5:2c:a2:9c:45:15:6f:e9:19 +# SHA256 Fingerprint: 25:30:cc:8e:98:32:15:02:ba:d9:6f:9b:1f:ba:1b:09:9e:2d:29:9e:0f:45:48:bb:91:4f:36:3b:c0:d4:53:1f +-----BEGIN CERTIFICATE----- +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 +-----END CERTIFICATE----- + +# Issuer: CN=Chambers of Commerce Root - 2008 O=AC Camerfirma S.A. +# Subject: CN=Chambers of Commerce Root - 2008 O=AC Camerfirma S.A. +# Label: "Chambers of Commerce Root - 2008" +# Serial: 11806822484801597146 +# MD5 Fingerprint: 5e:80:9e:84:5a:0e:65:0b:17:02:f3:55:18:2a:3e:d7 +# SHA1 Fingerprint: 78:6a:74:ac:76:ab:14:7f:9c:6a:30:50:ba:9e:a8:7e:fe:9a:ce:3c +# SHA256 Fingerprint: 06:3e:4a:fa:c4:91:df:d3:32:f3:08:9b:85:42:e9:46:17:d8:93:d7:fe:94:4e:10:a7:93:7e:e2:9d:96:93:c0 +-----BEGIN CERTIFICATE----- +MIIHTzCCBTegAwIBAgIJAKPaQn6ksa7aMA0GCSqGSIb3DQEBBQUAMIGuMQswCQYD +VQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0 +IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3 +MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xKTAnBgNVBAMTIENoYW1iZXJz +IG9mIENvbW1lcmNlIFJvb3QgLSAyMDA4MB4XDTA4MDgwMTEyMjk1MFoXDTM4MDcz +MTEyMjk1MFowga4xCzAJBgNVBAYTAkVVMUMwQQYDVQQHEzpNYWRyaWQgKHNlZSBj +dXJyZW50IGFkZHJlc3MgYXQgd3d3LmNhbWVyZmlybWEuY29tL2FkZHJlc3MpMRIw +EAYDVQQFEwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENhbWVyZmlybWEgUy5BLjEp +MCcGA1UEAxMgQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdCAtIDIwMDgwggIiMA0G +CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCvAMtwNyuAWko6bHiUfaN/Gh/2NdW9 +28sNRHI+JrKQUrpjOyhYb6WzbZSm891kDFX29ufyIiKAXuFixrYp4YFs8r/lfTJq +VKAyGVn+H4vXPWCGhSRv4xGzdz4gljUha7MI2XAuZPeEklPWDrCQiorjh40G072Q +DuKZoRuGDtqaCrsLYVAGUvGef3bsyw/QHg3PmTA9HMRFEFis1tPo1+XqxQEHd9ZR +5gN/ikilTWh1uem8nk4ZcfUyS5xtYBkL+8ydddy/Js2Pk3g5eXNeJQ7KXOt3EgfL +ZEFHcpOrUMPrCXZkNNI5t3YRCQ12RcSprj1qr7V9ZS+UWBDsXHyvfuK2GNnQm05a +Sd+pZgvMPMZ4fKecHePOjlO+Bd5gD2vlGts/4+EhySnB8esHnFIbAURRPHsl18Tl +UlRdJQfKFiC4reRB7noI/plvg6aRArBsNlVq5331lubKgdaX8ZSD6e2wsWsSaR6s ++12pxZjptFtYer49okQ6Y1nUCyXeG0+95QGezdIp1Z8XGQpvvwyQ0wlf2eOKNcx5 +Wk0ZN5K3xMGtr/R5JJqyAQuxr1yW84Ay+1w9mPGgP0revq+ULtlVmhduYJ1jbLhj +ya6BXBg14JC7vjxPNyK5fuvPnnchpj04gftI2jE9K+OJ9dC1vX7gUMQSibMjmhAx +hduub+84Mxh2EQIDAQABo4IBbDCCAWgwEgYDVR0TAQH/BAgwBgEB/wIBDDAdBgNV +HQ4EFgQU+SSsD7K1+HnA+mCIG8TZTQKeFxkwgeMGA1UdIwSB2zCB2IAU+SSsD7K1 ++HnA+mCIG8TZTQKeFxmhgbSkgbEwga4xCzAJBgNVBAYTAkVVMUMwQQYDVQQHEzpN +YWRyaWQgKHNlZSBjdXJyZW50IGFkZHJlc3MgYXQgd3d3LmNhbWVyZmlybWEuY29t +L2FkZHJlc3MpMRIwEAYDVQQFEwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENhbWVy +ZmlybWEgUy5BLjEpMCcGA1UEAxMgQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdCAt +IDIwMDiCCQCj2kJ+pLGu2jAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRV +HSAAMCowKAYIKwYBBQUHAgEWHGh0dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20w +DQYJKoZIhvcNAQEFBQADggIBAJASryI1wqM58C7e6bXpeHxIvj99RZJe6dqxGfwW +PJ+0W2aeaufDuV2I6A+tzyMP3iU6XsxPpcG1Lawk0lgH3qLPaYRgM+gQDROpI9CF +5Y57pp49chNyM/WqfcZjHwj0/gF/JM8rLFQJ3uIrbZLGOU8W6jx+ekbURWpGqOt1 +glanq6B8aBMz9p0w8G8nOSQjKpD9kCk18pPfNKXG9/jvjA9iSnyu0/VU+I22mlaH +FoI6M6taIgj3grrqLuBHmrS1RaMFO9ncLkVAO+rcf+g769HsJtg1pDDFOqxXnrN2 +pSB7+R5KBWIBpih1YJeSDW4+TTdDDZIVnBgizVGZoCkaPF+KMjNbMMeJL0eYD6MD +xvbxrN8y8NmBGuScvfaAFPDRLLmF9dijscilIeUcE5fuDr3fKanvNFNb0+RqE4QG +tjICxFKuItLcsiFCGtpA8CnJ7AoMXOLQusxI0zcKzBIKinmwPQN/aUv0NCB9szTq +jktk9T79syNnFQ0EuPAtwQlRPLJsFfClI9eDdOTlLsn+mCdCxqvGnrDQWzilm1De +fhiYtUU79nm06PcaewaD+9CL2rvHvRirCG88gGtAPxkZumWK5r7VXNM21+9AUiRg +OGcEMeyP84LG3rlV8zsxkVrctQgVrXYlCg17LofiDKYGvCYQbTed7N14jHyAxfDZ +d0jQ +-----END CERTIFICATE----- + +# Issuer: CN=Global Chambersign Root - 2008 O=AC Camerfirma S.A. +# Subject: CN=Global Chambersign Root - 2008 O=AC Camerfirma S.A. +# Label: "Global Chambersign Root - 2008" +# Serial: 14541511773111788494 +# MD5 Fingerprint: 9e:80:ff:78:01:0c:2e:c1:36:bd:fe:96:90:6e:08:f3 +# SHA1 Fingerprint: 4a:bd:ee:ec:95:0d:35:9c:89:ae:c7:52:a1:2c:5b:29:f6:d6:aa:0c +# SHA256 Fingerprint: 13:63:35:43:93:34:a7:69:80:16:a0:d3:24:de:72:28:4e:07:9d:7b:52:20:bb:8f:bd:74:78:16:ee:be:ba:ca +-----BEGIN CERTIFICATE----- +MIIHSTCCBTGgAwIBAgIJAMnN0+nVfSPOMA0GCSqGSIb3DQEBBQUAMIGsMQswCQYD +VQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0 +IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3 +MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xJzAlBgNVBAMTHkdsb2JhbCBD +aGFtYmVyc2lnbiBSb290IC0gMjAwODAeFw0wODA4MDExMjMxNDBaFw0zODA3MzEx +MjMxNDBaMIGsMQswCQYDVQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUgY3Vy +cmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAG +A1UEBRMJQTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xJzAl +BgNVBAMTHkdsb2JhbCBDaGFtYmVyc2lnbiBSb290IC0gMjAwODCCAiIwDQYJKoZI +hvcNAQEBBQADggIPADCCAgoCggIBAMDfVtPkOpt2RbQT2//BthmLN0EYlVJH6xed +KYiONWwGMi5HYvNJBL99RDaxccy9Wglz1dmFRP+RVyXfXjaOcNFccUMd2drvXNL7 +G706tcuto8xEpw2uIRU/uXpbknXYpBI4iRmKt4DS4jJvVpyR1ogQC7N0ZJJ0YPP2 +zxhPYLIj0Mc7zmFLmY/CDNBAspjcDahOo7kKrmCgrUVSY7pmvWjg+b4aqIG7HkF4 +ddPB/gBVsIdU6CeQNR1MM62X/JcumIS/LMmjv9GYERTtY/jKmIhYF5ntRQOXfjyG +HoiMvvKRhI9lNNgATH23MRdaKXoKGCQwoze1eqkBfSbW+Q6OWfH9GzO1KTsXO0G2 +Id3UwD2ln58fQ1DJu7xsepeY7s2MH/ucUa6LcL0nn3HAa6x9kGbo1106DbDVwo3V +yJ2dwW3Q0L9R5OP4wzg2rtandeavhENdk5IMagfeOx2YItaswTXbo6Al/3K1dh3e +beksZixShNBFks4c5eUzHdwHU1SjqoI7mjcv3N2gZOnm3b2u/GSFHTynyQbehP9r +6GsaPMWis0L7iwk+XwhSx2LE1AVxv8Rk5Pihg+g+EpuoHtQ2TS9x9o0o9oOpE9Jh +wZG7SMA0j0GMS0zbaRL/UJScIINZc+18ofLx/d33SdNDWKBWY8o9PeU1VlnpDsog +zCtLkykPAgMBAAGjggFqMIIBZjASBgNVHRMBAf8ECDAGAQH/AgEMMB0GA1UdDgQW +BBS5CcqcHtvTbDprru1U8VuTBjUuXjCB4QYDVR0jBIHZMIHWgBS5CcqcHtvTbDpr +ru1U8VuTBjUuXqGBsqSBrzCBrDELMAkGA1UEBhMCRVUxQzBBBgNVBAcTOk1hZHJp +ZCAoc2VlIGN1cnJlbnQgYWRkcmVzcyBhdCB3d3cuY2FtZXJmaXJtYS5jb20vYWRk +cmVzcykxEjAQBgNVBAUTCUE4Mjc0MzI4NzEbMBkGA1UEChMSQUMgQ2FtZXJmaXJt +YSBTLkEuMScwJQYDVQQDEx5HbG9iYWwgQ2hhbWJlcnNpZ24gUm9vdCAtIDIwMDiC +CQDJzdPp1X0jzjAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRVHSAAMCow +KAYIKwYBBQUHAgEWHGh0dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20wDQYJKoZI +hvcNAQEFBQADggIBAICIf3DekijZBZRG/5BXqfEv3xoNa/p8DhxJJHkn2EaqbylZ +UohwEurdPfWbU1Rv4WCiqAm57OtZfMY18dwY6fFn5a+6ReAJ3spED8IXDneRRXoz +X1+WLGiLwUePmJs9wOzL9dWCkoQ10b42OFZyMVtHLaoXpGNR6woBrX/sdZ7LoR/x +fxKxueRkf2fWIyr0uDldmOghp+G9PUIadJpwr2hsUF1Jz//7Dl3mLEfXgTpZALVz +a2Mg9jFFCDkO9HB+QHBaP9BrQql0PSgvAm11cpUJjUhjxsYjV5KTXjXBjfkK9yyd +Yhz2rXzdpjEetrHHfoUm+qRqtdpjMNHvkzeyZi99Bffnt0uYlDXA2TopwZ2yUDMd +SqlapskD7+3056huirRXhOukP9DuqqqHW2Pok+JrqNS4cnhrG+055F3Lm6qH1U9O +AP7Zap88MQ8oAgF9mOinsKJknnn4SPIVqczmyETrP3iZ8ntxPjzxmKfFGBI/5rso +M0LpRQp8bfKGeS/Fghl9CYl8slR2iK7ewfPM4W7bMdaTrpmg7yVqc5iJWzouE4ge +v8CSlDQb4ye3ix5vQv/n6TebUB0tovkC7stYWDpxvGjjqsGvHCgfotwjZT+B6q6Z +09gwzxMNTxXJhLynSC34MCN32EZLeW32jO06f2ARePTpm67VVMB0gNELQp/B +-----END CERTIFICATE----- + +# Issuer: CN=Go Daddy Root Certificate Authority - G2 O=GoDaddy.com, Inc. +# Subject: CN=Go Daddy Root Certificate Authority - G2 O=GoDaddy.com, Inc. +# Label: "Go Daddy Root Certificate Authority - G2" +# Serial: 0 +# MD5 Fingerprint: 80:3a:bc:22:c1:e6:fb:8d:9b:3b:27:4a:32:1b:9a:01 +# SHA1 Fingerprint: 47:be:ab:c9:22:ea:e8:0e:78:78:34:62:a7:9f:45:c2:54:fd:e6:8b +# SHA256 Fingerprint: 45:14:0b:32:47:eb:9c:c8:c5:b4:f0:d7:b5:30:91:f7:32:92:08:9e:6e:5a:63:e2:74:9d:d3:ac:a9:19:8e:da +-----BEGIN CERTIFICATE----- +MIIDxTCCAq2gAwIBAgIBADANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMx +EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoT +EUdvRGFkZHkuY29tLCBJbmMuMTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRp +ZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIz +NTk1OVowgYMxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQH +EwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjExMC8GA1UE +AxMoR28gRGFkZHkgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIw +DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL9xYgjx+lk09xvJGKP3gElY6SKD +E6bFIEMBO4Tx5oVJnyfq9oQbTqC023CYxzIBsQU+B07u9PpPL1kwIuerGVZr4oAH +/PMWdYA5UXvl+TW2dE6pjYIT5LY/qQOD+qK+ihVqf94Lw7YZFAXK6sOoBJQ7Rnwy +DfMAZiLIjWltNowRGLfTshxgtDj6AozO091GB94KPutdfMh8+7ArU6SSYmlRJQVh +GkSBjCypQ5Yj36w6gZoOKcUcqeldHraenjAKOc7xiID7S13MMuyFYkMlNAJWJwGR +tDtwKj9useiciAF9n9T521NtYJ2/LOdYq7hfRvzOxBsDPAnrSTFcaUaz4EcCAwEA +AaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE +FDqahQcQZyi27/a9BUFuIMGU2g/eMA0GCSqGSIb3DQEBCwUAA4IBAQCZ21151fmX +WWcDYfF+OwYxdS2hII5PZYe096acvNjpL9DbWu7PdIxztDhC2gV7+AJ1uP2lsdeu +9tfeE8tTEH6KRtGX+rcuKxGrkLAngPnon1rpN5+r5N9ss4UXnT3ZJE95kTXWXwTr +gIOrmgIttRD02JDHBHNA7XIloKmf7J6raBKZV8aPEjoJpL1E/QYVN8Gb5DKj7Tjo +2GTzLH4U/ALqn83/B2gX2yKQOC16jdFU8WnjXzPKej17CuPKf1855eJ1usV2GDPO +LPAvTK33sefOT6jEm0pUBsV/fdUID+Ic/n4XuKxe9tQWskMJDE32p2u0mYRlynqI +4uJEvlz36hz1 +-----END CERTIFICATE----- + +# Issuer: CN=Starfield Root Certificate Authority - G2 O=Starfield Technologies, Inc. +# Subject: CN=Starfield Root Certificate Authority - G2 O=Starfield Technologies, Inc. +# Label: "Starfield Root Certificate Authority - G2" +# Serial: 0 +# MD5 Fingerprint: d6:39:81:c6:52:7e:96:69:fc:fc:ca:66:ed:05:f2:96 +# SHA1 Fingerprint: b5:1c:06:7c:ee:2b:0c:3d:f8:55:ab:2d:92:f4:fe:39:d4:e7:0f:0e +# SHA256 Fingerprint: 2c:e1:cb:0b:f9:d2:f9:e1:02:99:3f:be:21:51:52:c3:b2:dd:0c:ab:de:1c:68:e5:31:9b:83:91:54:db:b7:f5 +-----BEGIN CERTIFICATE----- +MIID3TCCAsWgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMx +EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT +HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVs +ZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAw +MFoXDTM3MTIzMTIzNTk1OVowgY8xCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6 +b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQgVGVj +aG5vbG9naWVzLCBJbmMuMTIwMAYDVQQDEylTdGFyZmllbGQgUm9vdCBDZXJ0aWZp +Y2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBAL3twQP89o/8ArFvW59I2Z154qK3A2FWGMNHttfKPTUuiUP3oWmb3ooa/RMg +nLRJdzIpVv257IzdIvpy3Cdhl+72WoTsbhm5iSzchFvVdPtrX8WJpRBSiUZV9Lh1 +HOZ/5FSuS/hVclcCGfgXcVnrHigHdMWdSL5stPSksPNkN3mSwOxGXn/hbVNMYq/N +Hwtjuzqd+/x5AJhhdM8mgkBj87JyahkNmcrUDnXMN/uLicFZ8WJ/X7NfZTD4p7dN +dloedl40wOiWVpmKs/B/pM293DIxfJHP4F8R+GuqSVzRmZTRouNjWwl2tVZi4Ut0 +HZbUJtQIBFnQmA4O5t78w+wfkPECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO +BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFHwMMh+n2TB/xH1oo2Kooc6rB1snMA0G +CSqGSIb3DQEBCwUAA4IBAQARWfolTwNvlJk7mh+ChTnUdgWUXuEok21iXQnCoKjU +sHU48TRqneSfioYmUeYs0cYtbpUgSpIB7LiKZ3sx4mcujJUDJi5DnUox9g61DLu3 +4jd/IroAow57UvtruzvE03lRTs2Q9GcHGcg8RnoNAX3FWOdt5oUwF5okxBDgBPfg +8n/Uqgr/Qh037ZTlZFkSIHc40zI+OIF1lnP6aI+xy84fxez6nH7PfrHxBy22/L/K +pL/QlwVKvOoYKAKQvVR4CSFx09F9HdkWsKlhPdAKACL8x3vLCWRFCztAgfd9fDL1 +mMpYjn0q7pBZc2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0 +-----END CERTIFICATE----- + +# Issuer: CN=Starfield Services Root Certificate Authority - G2 O=Starfield Technologies, Inc. +# Subject: CN=Starfield Services Root Certificate Authority - G2 O=Starfield Technologies, Inc. +# Label: "Starfield Services Root Certificate Authority - G2" +# Serial: 0 +# MD5 Fingerprint: 17:35:74:af:7b:61:1c:eb:f4:f9:3c:e2:ee:40:f9:a2 +# SHA1 Fingerprint: 92:5a:8f:8d:2c:6d:04:e0:66:5f:59:6a:ff:22:d8:63:e8:25:6f:3f +# SHA256 Fingerprint: 56:8d:69:05:a2:c8:87:08:a4:b3:02:51:90:ed:cf:ed:b1:97:4a:60:6a:13:c6:e5:29:0f:cb:2a:e6:3e:da:b5 +-----BEGIN CERTIFICATE----- +MIID7zCCAtegAwIBAgIBADANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMCVVMx +EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT +HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xOzA5BgNVBAMTMlN0YXJmaWVs +ZCBTZXJ2aWNlcyBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5 +MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgZgxCzAJBgNVBAYTAlVTMRAwDgYD +VQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFy +ZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTswOQYDVQQDEzJTdGFyZmllbGQgU2Vy +dmljZXMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBANUMOsQq+U7i9b4Zl1+OiFOxHz/Lz58gE20p +OsgPfTz3a3Y4Y9k2YKibXlwAgLIvWX/2h/klQ4bnaRtSmpDhcePYLQ1Ob/bISdm2 +8xpWriu2dBTrz/sm4xq6HZYuajtYlIlHVv8loJNwU4PahHQUw2eeBGg6345AWh1K +Ts9DkTvnVtYAcMtS7nt9rjrnvDH5RfbCYM8TWQIrgMw0R9+53pBlbQLPLJGmpufe +hRhJfGZOozptqbXuNC66DQO4M99H67FrjSXZm86B0UVGMpZwh94CDklDhbZsc7tk +6mFBrMnUVN+HL8cisibMn1lUaJ/8viovxFUcdUBgF4UCVTmLfwUCAwEAAaNCMEAw +DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJxfAN+q +AdcwKziIorhtSpzyEZGDMA0GCSqGSIb3DQEBCwUAA4IBAQBLNqaEd2ndOxmfZyMI +bw5hyf2E3F/YNoHN2BtBLZ9g3ccaaNnRbobhiCPPE95Dz+I0swSdHynVv/heyNXB +ve6SbzJ08pGCL72CQnqtKrcgfU28elUSwhXqvfdqlS5sdJ/PHLTyxQGjhdByPq1z +qwubdQxtRbeOlKyWN7Wg0I8VRw7j6IPdj/3vQQF3zCepYoUz8jcI73HPdwbeyBkd +iEDPfUYd/x7H4c7/I9vG+o1VTqkC50cRRj70/b17KSa7qWFiNyi2LSr2EIZkyXCn +0q23KXB56jzaYyWf/Wi3MOxw+3WKt21gZ7IeyLnp2KhvAotnDU0mV3HaIPzBSlCN +sSi6 +-----END CERTIFICATE----- + +# Issuer: CN=AffirmTrust Commercial O=AffirmTrust +# Subject: CN=AffirmTrust Commercial O=AffirmTrust +# Label: "AffirmTrust Commercial" +# Serial: 8608355977964138876 +# MD5 Fingerprint: 82:92:ba:5b:ef:cd:8a:6f:a6:3d:55:f9:84:f6:d6:b7 +# SHA1 Fingerprint: f9:b5:b6:32:45:5f:9c:be:ec:57:5f:80:dc:e9:6e:2c:c7:b2:78:b7 +# SHA256 Fingerprint: 03:76:ab:1d:54:c5:f9:80:3c:e4:b2:e2:01:a0:ee:7e:ef:7b:57:b6:36:e8:a9:3c:9b:8d:48:60:c9:6f:5f:a7 +-----BEGIN CERTIFICATE----- +MIIDTDCCAjSgAwIBAgIId3cGJyapsXwwDQYJKoZIhvcNAQELBQAwRDELMAkGA1UE +BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVz +dCBDb21tZXJjaWFsMB4XDTEwMDEyOTE0MDYwNloXDTMwMTIzMTE0MDYwNlowRDEL +MAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZp +cm1UcnVzdCBDb21tZXJjaWFsMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEA9htPZwcroRX1BiLLHwGy43NFBkRJLLtJJRTWzsO3qyxPxkEylFf6EqdbDuKP +Hx6GGaeqtS25Xw2Kwq+FNXkyLbscYjfysVtKPcrNcV/pQr6U6Mje+SJIZMblq8Yr +ba0F8PrVC8+a5fBQpIs7R6UjW3p6+DM/uO+Zl+MgwdYoic+U+7lF7eNAFxHUdPAL +MeIrJmqbTFeurCA+ukV6BfO9m2kVrn1OIGPENXY6BwLJN/3HR+7o8XYdcxXyl6S1 +yHp52UKqK39c/s4mT6NmgTWvRLpUHhwwMmWd5jyTXlBOeuM61G7MGvv50jeuJCqr +VwMiKA1JdX+3KNp1v47j3A55MQIDAQABo0IwQDAdBgNVHQ4EFgQUnZPGU4teyq8/ +nx4P5ZmVvCT2lI8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJ +KoZIhvcNAQELBQADggEBAFis9AQOzcAN/wr91LoWXym9e2iZWEnStB03TX8nfUYG +XUPGhi4+c7ImfU+TqbbEKpqrIZcUsd6M06uJFdhrJNTxFq7YpFzUf1GO7RgBsZNj +vbz4YYCanrHOQnDiqX0GJX0nof5v7LMeJNrjS1UaADs1tDvZ110w/YETifLCBivt +Z8SOyUOyXGsViQK8YvxO8rUzqrJv0wqiUOP2O+guRMLbZjipM1ZI8W0bM40NjD9g +N53Tym1+NH4Nn3J2ixufcv1SNUFFApYvHLKac0khsUlHRUe072o0EclNmsxZt9YC +nlpOZbWUrhvfKbAW8b8Angc6F2S1BLUjIZkKlTuXfO8= +-----END CERTIFICATE----- + +# Issuer: CN=AffirmTrust Networking O=AffirmTrust +# Subject: CN=AffirmTrust Networking O=AffirmTrust +# Label: "AffirmTrust Networking" +# Serial: 8957382827206547757 +# MD5 Fingerprint: 42:65:ca:be:01:9a:9a:4c:a9:8c:41:49:cd:c0:d5:7f +# SHA1 Fingerprint: 29:36:21:02:8b:20:ed:02:f5:66:c5:32:d1:d6:ed:90:9f:45:00:2f +# SHA256 Fingerprint: 0a:81:ec:5a:92:97:77:f1:45:90:4a:f3:8d:5d:50:9f:66:b5:e2:c5:8f:cd:b5:31:05:8b:0e:17:f3:f0:b4:1b +-----BEGIN CERTIFICATE----- +MIIDTDCCAjSgAwIBAgIIfE8EORzUmS0wDQYJKoZIhvcNAQEFBQAwRDELMAkGA1UE +BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVz +dCBOZXR3b3JraW5nMB4XDTEwMDEyOTE0MDgyNFoXDTMwMTIzMTE0MDgyNFowRDEL +MAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZp +cm1UcnVzdCBOZXR3b3JraW5nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEAtITMMxcua5Rsa2FSoOujz3mUTOWUgJnLVWREZY9nZOIG41w3SfYvm4SEHi3y +YJ0wTsyEheIszx6e/jarM3c1RNg1lho9Nuh6DtjVR6FqaYvZ/Ls6rnla1fTWcbua +kCNrmreIdIcMHl+5ni36q1Mr3Lt2PpNMCAiMHqIjHNRqrSK6mQEubWXLviRmVSRL +QESxG9fhwoXA3hA/Pe24/PHxI1Pcv2WXb9n5QHGNfb2V1M6+oF4nI979ptAmDgAp +6zxG8D1gvz9Q0twmQVGeFDdCBKNwV6gbh+0t+nvujArjqWaJGctB+d1ENmHP4ndG +yH329JKBNv3bNPFyfvMMFr20FQIDAQABo0IwQDAdBgNVHQ4EFgQUBx/S55zawm6i +QLSwelAQUHTEyL0wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJ +KoZIhvcNAQEFBQADggEBAIlXshZ6qML91tmbmzTCnLQyFE2npN/svqe++EPbkTfO +tDIuUFUaNU52Q3Eg75N3ThVwLofDwR1t3Mu1J9QsVtFSUzpE0nPIxBsFZVpikpzu +QY0x2+c06lkh1QF612S4ZDnNye2v7UsDSKegmQGA3GWjNq5lWUhPgkvIZfFXHeVZ +Lgo/bNjR9eUJtGxUAArgFU2HdW23WJZa3W3SAKD0m0i+wzekujbgfIeFlxoVot4u +olu9rxj5kFDNcFn4J2dHy8egBzp90SxdbBk6ZrV9/ZFvgrG+CJPbFEfxojfHRZ48 +x3evZKiT3/Zpg4Jg8klCNO1aAFSFHBY2kgxc+qatv9s= +-----END CERTIFICATE----- + +# Issuer: CN=AffirmTrust Premium O=AffirmTrust +# Subject: CN=AffirmTrust Premium O=AffirmTrust +# Label: "AffirmTrust Premium" +# Serial: 7893706540734352110 +# MD5 Fingerprint: c4:5d:0e:48:b6:ac:28:30:4e:0a:bc:f9:38:16:87:57 +# SHA1 Fingerprint: d8:a6:33:2c:e0:03:6f:b1:85:f6:63:4f:7d:6a:06:65:26:32:28:27 +# SHA256 Fingerprint: 70:a7:3f:7f:37:6b:60:07:42:48:90:45:34:b1:14:82:d5:bf:0e:69:8e:cc:49:8d:f5:25:77:eb:f2:e9:3b:9a +-----BEGIN CERTIFICATE----- +MIIFRjCCAy6gAwIBAgIIbYwURrGmCu4wDQYJKoZIhvcNAQEMBQAwQTELMAkGA1UE +BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1UcnVz +dCBQcmVtaXVtMB4XDTEwMDEyOTE0MTAzNloXDTQwMTIzMTE0MTAzNlowQTELMAkG +A1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1U +cnVzdCBQcmVtaXVtMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxBLf +qV/+Qd3d9Z+K4/as4Tx4mrzY8H96oDMq3I0gW64tb+eT2TZwamjPjlGjhVtnBKAQ +JG9dKILBl1fYSCkTtuG+kU3fhQxTGJoeJKJPj/CihQvL9Cl/0qRY7iZNyaqoe5rZ ++jjeRFcV5fiMyNlI4g0WJx0eyIOFJbe6qlVBzAMiSy2RjYvmia9mx+n/K+k8rNrS +s8PhaJyJ+HoAVt70VZVs+7pk3WKL3wt3MutizCaam7uqYoNMtAZ6MMgpv+0GTZe5 +HMQxK9VfvFMSF5yZVylmd2EhMQcuJUmdGPLu8ytxjLW6OQdJd/zvLpKQBY0tL3d7 +70O/Nbua2Plzpyzy0FfuKE4mX4+QaAkvuPjcBukumj5Rp9EixAqnOEhss/n/fauG +V+O61oV4d7pD6kh/9ti+I20ev9E2bFhc8e6kGVQa9QPSdubhjL08s9NIS+LI+H+S +qHZGnEJlPqQewQcDWkYtuJfzt9WyVSHvutxMAJf7FJUnM7/oQ0dG0giZFmA7mn7S +5u046uwBHjxIVkkJx0w3AJ6IDsBz4W9m6XJHMD4Q5QsDyZpCAGzFlH5hxIrff4Ia +C1nEWTJ3s7xgaVY5/bQGeyzWZDbZvUjthB9+pSKPKrhC9IK31FOQeE4tGv2Bb0TX +OwF0lkLgAOIua+rF7nKsu7/+6qqo+Nz2snmKtmcCAwEAAaNCMEAwHQYDVR0OBBYE +FJ3AZ6YMItkm9UWrpmVSESfYRaxjMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/ +BAQDAgEGMA0GCSqGSIb3DQEBDAUAA4ICAQCzV00QYk465KzquByvMiPIs0laUZx2 +KI15qldGF9X1Uva3ROgIRL8YhNILgM3FEv0AVQVhh0HctSSePMTYyPtwni94loMg +Nt58D2kTiKV1NpgIpsbfrM7jWNa3Pt668+s0QNiigfV4Py/VpfzZotReBA4Xrf5B +8OWycvpEgjNC6C1Y91aMYj+6QrCcDFx+LmUmXFNPALJ4fqENmS2NuB2OosSw/WDQ +MKSOyARiqcTtNd56l+0OOF6SL5Nwpamcb6d9Ex1+xghIsV5n61EIJenmJWtSKZGc +0jlzCFfemQa0W50QBuHCAKi4HEoCChTQwUHK+4w1IX2COPKpVJEZNZOUbWo6xbLQ +u4mGk+ibyQ86p3q4ofB4Rvr8Ny/lioTz3/4E2aFooC8k4gmVBtWVyuEklut89pMF +u+1z6S3RdTnX5yTb2E5fQ4+e0BQ5v1VwSJlXMbSc7kqYA5YwH2AG7hsj/oFgIxpH +YoWlzBk0gG+zrBrjn/B7SK3VAdlntqlyk+otZrWyuOQ9PLLvTIzq6we/qzWaVYa8 +GKa1qF60g2xraUDTn9zxw2lrueFtCfTxqlB2Cnp9ehehVZZCmTEJ3WARjQUwfuaO +RtGdFNrHF+QFlozEJLUbzxQHskD4o55BhrwE0GuWyCqANP2/7waj3VjFhT0+j/6e +KeC2uAloGRwYQw== +-----END CERTIFICATE----- + +# Issuer: CN=AffirmTrust Premium ECC O=AffirmTrust +# Subject: CN=AffirmTrust Premium ECC O=AffirmTrust +# Label: "AffirmTrust Premium ECC" +# Serial: 8401224907861490260 +# MD5 Fingerprint: 64:b0:09:55:cf:b1:d5:99:e2:be:13:ab:a6:5d:ea:4d +# SHA1 Fingerprint: b8:23:6b:00:2f:1d:16:86:53:01:55:6c:11:a4:37:ca:eb:ff:c3:bb +# SHA256 Fingerprint: bd:71:fd:f6:da:97:e4:cf:62:d1:64:7a:dd:25:81:b0:7d:79:ad:f8:39:7e:b4:ec:ba:9c:5e:84:88:82:14:23 +-----BEGIN CERTIFICATE----- +MIIB/jCCAYWgAwIBAgIIdJclisc/elQwCgYIKoZIzj0EAwMwRTELMAkGA1UEBhMC +VVMxFDASBgNVBAoMC0FmZmlybVRydXN0MSAwHgYDVQQDDBdBZmZpcm1UcnVzdCBQ +cmVtaXVtIEVDQzAeFw0xMDAxMjkxNDIwMjRaFw00MDEyMzExNDIwMjRaMEUxCzAJ +BgNVBAYTAlVTMRQwEgYDVQQKDAtBZmZpcm1UcnVzdDEgMB4GA1UEAwwXQWZmaXJt +VHJ1c3QgUHJlbWl1bSBFQ0MwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQNMF4bFZ0D +0KF5Nbc6PJJ6yhUczWLznCZcBz3lVPqj1swS6vQUX+iOGasvLkjmrBhDeKzQN8O9 +ss0s5kfiGuZjuD0uL3jET9v0D6RoTFVya5UdThhClXjMNzyR4ptlKymjQjBAMB0G +A1UdDgQWBBSaryl6wBE1NSZRMADDav5A1a7WPDAPBgNVHRMBAf8EBTADAQH/MA4G +A1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAwNnADBkAjAXCfOHiFBar8jAQr9HX/Vs +aobgxCd05DhT1wV/GzTjxi+zygk8N53X57hG8f2h4nECMEJZh0PUUd+60wkyWs6I +flc9nF9Ca/UHLbXwgpP5WW+uZPpY5Yse42O+tYHNbwKMeQ== +-----END CERTIFICATE----- + +# Issuer: CN=Certum Trusted Network CA O=Unizeto Technologies S.A. OU=Certum Certification Authority +# Subject: CN=Certum Trusted Network CA O=Unizeto Technologies S.A. OU=Certum Certification Authority +# Label: "Certum Trusted Network CA" +# Serial: 279744 +# MD5 Fingerprint: d5:e9:81:40:c5:18:69:fc:46:2c:89:75:62:0f:aa:78 +# SHA1 Fingerprint: 07:e0:32:e0:20:b7:2c:3f:19:2f:06:28:a2:59:3a:19:a7:0f:06:9e +# SHA256 Fingerprint: 5c:58:46:8d:55:f5:8e:49:7e:74:39:82:d2:b5:00:10:b6:d1:65:37:4a:cf:83:a7:d4:a3:2d:b7:68:c4:40:8e +-----BEGIN CERTIFICATE----- +MIIDuzCCAqOgAwIBAgIDBETAMA0GCSqGSIb3DQEBBQUAMH4xCzAJBgNVBAYTAlBM +MSIwIAYDVQQKExlVbml6ZXRvIFRlY2hub2xvZ2llcyBTLkEuMScwJQYDVQQLEx5D +ZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxIjAgBgNVBAMTGUNlcnR1bSBU +cnVzdGVkIE5ldHdvcmsgQ0EwHhcNMDgxMDIyMTIwNzM3WhcNMjkxMjMxMTIwNzM3 +WjB+MQswCQYDVQQGEwJQTDEiMCAGA1UEChMZVW5pemV0byBUZWNobm9sb2dpZXMg +Uy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MSIw +IAYDVQQDExlDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENBMIIBIjANBgkqhkiG9w0B +AQEFAAOCAQ8AMIIBCgKCAQEA4/t9o3K6wvDJFIf1awFO4W5AB7ptJ11/91sts1rH +UV+rpDKmYYe2bg+G0jACl/jXaVehGDldamR5xgFZrDwxSjh80gTSSyjoIF87B6LM +TXPb865Px1bVWqeWifrzq2jUI4ZZJ88JJ7ysbnKDHDBy3+Ci6dLhdHUZvSqeexVU +BBvXQzmtVSjF4hq79MDkrjhJM8x2hZ85RdKknvISjFH4fOQtf/WsX+sWn7Et0brM +kUJ3TCXJkDhv2/DM+44el1k+1WBO5gUo7Ul5E0u6SNsv+XLTOcr+H9g0cvW0QM8x +AcPs3hEtF10fuFDRXhmnad4HMyjKUJX5p1TLVIZQRan5SQIDAQABo0IwQDAPBgNV +HRMBAf8EBTADAQH/MB0GA1UdDgQWBBQIds3LB/8k9sXN7buQvOKEN0Z19zAOBgNV +HQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEFBQADggEBAKaorSLOAT2mo/9i0Eidi15y +sHhE49wcrwn9I0j6vSrEuVUEtRCjjSfeC4Jj0O7eDDd5QVsisrCaQVymcODU0HfL +I9MA4GxWL+FpDQ3Zqr8hgVDZBqWo/5U30Kr+4rP1mS1FhIrlQgnXdAIv94nYmem8 +J9RHjboNRhx3zxSkHLmkMcScKHQDNP8zGSal6Q10tz6XxnboJ5ajZt3hrvJBW8qY +VoNzcOSGGtIxQbovvi0TWnZvTuhOgQ4/WwMioBK+ZlgRSssDxLQqKi2WF+A5VLxI +03YnnZotBqbJ7DnSq9ufmgsnAjUpsUCV5/nonFWIGUbWtzT1fs45mtk48VH3Tyw= +-----END CERTIFICATE----- + +# Issuer: CN=TWCA Root Certification Authority O=TAIWAN-CA OU=Root CA +# Subject: CN=TWCA Root Certification Authority O=TAIWAN-CA OU=Root CA +# Label: "TWCA Root Certification Authority" +# Serial: 1 +# MD5 Fingerprint: aa:08:8f:f6:f9:7b:b7:f2:b1:a7:1e:9b:ea:ea:bd:79 +# SHA1 Fingerprint: cf:9e:87:6d:d3:eb:fc:42:26:97:a3:b5:a3:7a:a0:76:a9:06:23:48 +# SHA256 Fingerprint: bf:d8:8f:e1:10:1c:41:ae:3e:80:1b:f8:be:56:35:0e:e9:ba:d1:a6:b9:bd:51:5e:dc:5c:6d:5b:87:11:ac:44 +-----BEGIN CERTIFICATE----- +MIIDezCCAmOgAwIBAgIBATANBgkqhkiG9w0BAQUFADBfMQswCQYDVQQGEwJUVzES +MBAGA1UECgwJVEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFU +V0NBIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwODI4MDcyNDMz +WhcNMzAxMjMxMTU1OTU5WjBfMQswCQYDVQQGEwJUVzESMBAGA1UECgwJVEFJV0FO +LUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NBIFJvb3QgQ2VydGlm +aWNhdGlvbiBBdXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB +AQCwfnK4pAOU5qfeCTiRShFAh6d8WWQUe7UREN3+v9XAu1bihSX0NXIP+FPQQeFE +AcK0HMMxQhZHhTMidrIKbw/lJVBPhYa+v5guEGcevhEFhgWQxFnQfHgQsIBct+HH +K3XLfJ+utdGdIzdjp9xCoi2SBBtQwXu4PhvJVgSLL1KbralW6cH/ralYhzC2gfeX +RfwZVzsrb+RH9JlF/h3x+JejiB03HFyP4HYlmlD4oFT/RJB2I9IyxsOrBr/8+7/z +rX2SYgJbKdM1o5OaQ2RgXbL6Mv87BK9NQGr5x+PvI/1ry+UPizgN7gr8/g+YnzAx +3WxSZfmLgb4i4RxYA7qRG4kHAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV +HRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqOFsmjd6LWvJPelSDGRjjCDWmujANBgkq +hkiG9w0BAQUFAAOCAQEAPNV3PdrfibqHDAhUaiBQkr6wQT25JmSDCi/oQMCXKCeC +MErJk/9q56YAf4lCmtYR5VPOL8zy2gXE/uJQxDqGfczafhAJO5I1KlOy/usrBdls +XebQ79NqZp4VKIV66IIArB6nCWlWQtNoURi+VJq/REG6Sb4gumlc7rh3zc5sH62D +lhh9DrUUOYTxKOkto557HnpyWoOzeW/vtPzQCqVYT0bf+215WfKEIlKuD8z7fDvn +aspHYcN6+NOSBB+4IIThNlQWx0DeO4pz3N/GCUzf7Nr/1FNCocnyYh0igzyXxfkZ +YiesZSLX0zzG5Y6yU8xJzrww/nsOM5D77dIUkR8Hrw== +-----END CERTIFICATE----- + +# Issuer: O=SECOM Trust Systems CO.,LTD. OU=Security Communication RootCA2 +# Subject: O=SECOM Trust Systems CO.,LTD. OU=Security Communication RootCA2 +# Label: "Security Communication RootCA2" +# Serial: 0 +# MD5 Fingerprint: 6c:39:7d:a4:0e:55:59:b2:3f:d6:41:b1:12:50:de:43 +# SHA1 Fingerprint: 5f:3b:8c:f2:f8:10:b3:7d:78:b4:ce:ec:19:19:c3:73:34:b9:c7:74 +# SHA256 Fingerprint: 51:3b:2c:ec:b8:10:d4:cd:e5:dd:85:39:1a:df:c6:c2:dd:60:d8:7b:b7:36:d2:b5:21:48:4a:a4:7a:0e:be:f6 +-----BEGIN CERTIFICATE----- +MIIDdzCCAl+gAwIBAgIBADANBgkqhkiG9w0BAQsFADBdMQswCQYDVQQGEwJKUDEl +MCMGA1UEChMcU0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEnMCUGA1UECxMe +U2VjdXJpdHkgQ29tbXVuaWNhdGlvbiBSb290Q0EyMB4XDTA5MDUyOTA1MDAzOVoX +DTI5MDUyOTA1MDAzOVowXTELMAkGA1UEBhMCSlAxJTAjBgNVBAoTHFNFQ09NIFRy +dXN0IFN5c3RlbXMgQ08uLExURC4xJzAlBgNVBAsTHlNlY3VyaXR5IENvbW11bmlj +YXRpb24gUm9vdENBMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANAV +OVKxUrO6xVmCxF1SrjpDZYBLx/KWvNs2l9amZIyoXvDjChz335c9S672XewhtUGr +zbl+dp+++T42NKA7wfYxEUV0kz1XgMX5iZnK5atq1LXaQZAQwdbWQonCv/Q4EpVM +VAX3NuRFg3sUZdbcDE3R3n4MqzvEFb46VqZab3ZpUql6ucjrappdUtAtCms1FgkQ +hNBqyjoGADdH5H5XTz+L62e4iKrFvlNVspHEfbmwhRkGeC7bYRr6hfVKkaHnFtWO +ojnflLhwHyg/i/xAXmODPIMqGplrz95Zajv8bxbXH/1KEOtOghY6rCcMU/Gt1SSw +awNQwS08Ft1ENCcadfsCAwEAAaNCMEAwHQYDVR0OBBYEFAqFqXdlBZh8QIH4D5cs +OPEK7DzPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3 +DQEBCwUAA4IBAQBMOqNErLlFsceTfsgLCkLfZOoc7llsCLqJX2rKSpWeeo8HxdpF +coJxDjrSzG+ntKEju/Ykn8sX/oymzsLS28yN/HH8AynBbF0zX2S2ZTuJbxh2ePXc +okgfGT+Ok+vx+hfuzU7jBBJV1uXk3fs+BXziHV7Gp7yXT2g69ekuCkO2r1dcYmh8 +t/2jioSgrGK+KwmHNPBqAbubKVY8/gA3zyNs8U6qtnRGEmyR7jTV7JqR50S+kDFy +1UkC9gLl9B/rfNmWVan/7Ir5mUf/NVoCqgTLiluHcSmRvaS0eg29mvVXIwAHIRc/ +SjnRBUkLp7Y3gaVdjKozXoEofKd9J+sAro03 +-----END CERTIFICATE----- + +# Issuer: CN=EC-ACC O=Agencia Catalana de Certificacio (NIF Q-0801176-I) OU=Serveis Publics de Certificacio/Vegeu https://www.catcert.net/verarrel (c)03/Jerarquia Entitats de Certificacio Catalanes +# Subject: CN=EC-ACC O=Agencia Catalana de Certificacio (NIF Q-0801176-I) OU=Serveis Publics de Certificacio/Vegeu https://www.catcert.net/verarrel (c)03/Jerarquia Entitats de Certificacio Catalanes +# Label: "EC-ACC" +# Serial: -23701579247955709139626555126524820479 +# MD5 Fingerprint: eb:f5:9d:29:0d:61:f9:42:1f:7c:c2:ba:6d:e3:15:09 +# SHA1 Fingerprint: 28:90:3a:63:5b:52:80:fa:e6:77:4c:0b:6d:a7:d6:ba:a6:4a:f2:e8 +# SHA256 Fingerprint: 88:49:7f:01:60:2f:31:54:24:6a:e2:8c:4d:5a:ef:10:f1:d8:7e:bb:76:62:6f:4a:e0:b7:f9:5b:a7:96:87:99 +-----BEGIN CERTIFICATE----- +MIIFVjCCBD6gAwIBAgIQ7is969Qh3hSoYqwE893EATANBgkqhkiG9w0BAQUFADCB +8zELMAkGA1UEBhMCRVMxOzA5BgNVBAoTMkFnZW5jaWEgQ2F0YWxhbmEgZGUgQ2Vy +dGlmaWNhY2lvIChOSUYgUS0wODAxMTc2LUkpMSgwJgYDVQQLEx9TZXJ2ZWlzIFB1 +YmxpY3MgZGUgQ2VydGlmaWNhY2lvMTUwMwYDVQQLEyxWZWdldSBodHRwczovL3d3 +dy5jYXRjZXJ0Lm5ldC92ZXJhcnJlbCAoYykwMzE1MDMGA1UECxMsSmVyYXJxdWlh +IEVudGl0YXRzIGRlIENlcnRpZmljYWNpbyBDYXRhbGFuZXMxDzANBgNVBAMTBkVD +LUFDQzAeFw0wMzAxMDcyMzAwMDBaFw0zMTAxMDcyMjU5NTlaMIHzMQswCQYDVQQG +EwJFUzE7MDkGA1UEChMyQWdlbmNpYSBDYXRhbGFuYSBkZSBDZXJ0aWZpY2FjaW8g +KE5JRiBRLTA4MDExNzYtSSkxKDAmBgNVBAsTH1NlcnZlaXMgUHVibGljcyBkZSBD +ZXJ0aWZpY2FjaW8xNTAzBgNVBAsTLFZlZ2V1IGh0dHBzOi8vd3d3LmNhdGNlcnQu +bmV0L3ZlcmFycmVsIChjKTAzMTUwMwYDVQQLEyxKZXJhcnF1aWEgRW50aXRhdHMg +ZGUgQ2VydGlmaWNhY2lvIENhdGFsYW5lczEPMA0GA1UEAxMGRUMtQUNDMIIBIjAN +BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsyLHT+KXQpWIR4NA9h0X84NzJB5R +85iKw5K4/0CQBXCHYMkAqbWUZRkiFRfCQ2xmRJoNBD45b6VLeqpjt4pEndljkYRm +4CgPukLjbo73FCeTae6RDqNfDrHrZqJyTxIThmV6PttPB/SnCWDaOkKZx7J/sxaV +HMf5NLWUhdWZXqBIoH7nF2W4onW4HvPlQn2v7fOKSGRdghST2MDk/7NQcvJ29rNd +QlB50JQ+awwAvthrDk4q7D7SzIKiGGUzE3eeml0aE9jD2z3Il3rucO2n5nzbcc8t +lGLfbdb1OL4/pYUKGbio2Al1QnDE6u/LDsg0qBIimAy4E5S2S+zw0JDnJwIDAQAB +o4HjMIHgMB0GA1UdEQQWMBSBEmVjX2FjY0BjYXRjZXJ0Lm5ldDAPBgNVHRMBAf8E +BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUoMOLRKo3pUW/l4Ba0fF4 +opvpXY0wfwYDVR0gBHgwdjB0BgsrBgEEAfV4AQMBCjBlMCwGCCsGAQUFBwIBFiBo +dHRwczovL3d3dy5jYXRjZXJ0Lm5ldC92ZXJhcnJlbDA1BggrBgEFBQcCAjApGidW +ZWdldSBodHRwczovL3d3dy5jYXRjZXJ0Lm5ldC92ZXJhcnJlbCAwDQYJKoZIhvcN +AQEFBQADggEBAKBIW4IB9k1IuDlVNZyAelOZ1Vr/sXE7zDkJlF7W2u++AVtd0x7Y +/X1PzaBB4DSTv8vihpw3kpBWHNzrKQXlxJ7HNd+KDM3FIUPpqojlNcAZQmNaAl6k +SBg6hW/cnbw/nZzBh7h6YQjpdwt/cKt63dmXLGQehb+8dJahw3oS7AwaboMMPOhy +Rp/7SNVel+axofjk70YllJyJ22k4vuxcDlbHZVHlUIiIv0LVKz3l+bqeLrPK9HOS +Agu+TGbrIP65y7WZf+a2E/rKS03Z7lNGBjvGTq2TWoF+bCpLagVFjPIhpDGQh2xl +nJ2lYJU6Un/10asIbvPuW/mIPX64b24D5EI= +-----END CERTIFICATE----- + +# Issuer: CN=Hellenic Academic and Research Institutions RootCA 2011 O=Hellenic Academic and Research Institutions Cert. Authority +# Subject: CN=Hellenic Academic and Research Institutions RootCA 2011 O=Hellenic Academic and Research Institutions Cert. Authority +# Label: "Hellenic Academic and Research Institutions RootCA 2011" +# Serial: 0 +# MD5 Fingerprint: 73:9f:4c:4b:73:5b:79:e9:fa:ba:1c:ef:6e:cb:d5:c9 +# SHA1 Fingerprint: fe:45:65:9b:79:03:5b:98:a1:61:b5:51:2e:ac:da:58:09:48:22:4d +# SHA256 Fingerprint: bc:10:4f:15:a4:8b:e7:09:dc:a5:42:a7:e1:d4:b9:df:6f:05:45:27:e8:02:ea:a9:2d:59:54:44:25:8a:fe:71 +-----BEGIN CERTIFICATE----- +MIIEMTCCAxmgAwIBAgIBADANBgkqhkiG9w0BAQUFADCBlTELMAkGA1UEBhMCR1Ix +RDBCBgNVBAoTO0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1 +dGlvbnMgQ2VydC4gQXV0aG9yaXR5MUAwPgYDVQQDEzdIZWxsZW5pYyBBY2FkZW1p +YyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25zIFJvb3RDQSAyMDExMB4XDTExMTIw +NjEzNDk1MloXDTMxMTIwMTEzNDk1MlowgZUxCzAJBgNVBAYTAkdSMUQwQgYDVQQK +EztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25zIENl +cnQuIEF1dGhvcml0eTFAMD4GA1UEAxM3SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJl +c2VhcmNoIEluc3RpdHV0aW9ucyBSb290Q0EgMjAxMTCCASIwDQYJKoZIhvcNAQEB +BQADggEPADCCAQoCggEBAKlTAOMupvaO+mDYLZU++CwqVE7NuYRhlFhPjz2L5EPz +dYmNUeTDN9KKiE15HrcS3UN4SoqS5tdI1Q+kOilENbgH9mgdVc04UfCMJDGFr4PJ +fel3r+0ae50X+bOdOFAPplp5kYCvN66m0zH7tSYJnTxa71HFK9+WXesyHgLacEns +bgzImjeN9/E2YEsmLIKe0HjzDQ9jpFEw4fkrJxIH2Oq9GGKYsFk3fb7u8yBRQlqD +75O6aRXxYp2fmTmCobd0LovUxQt7L/DICto9eQqakxylKHJzkUOap9FNhYS5qXSP +FEDH3N6sQWRstBmbAmNtJGSPRLIl6s5ddAxjMlyNh+UCAwEAAaOBiTCBhjAPBgNV +HRMBAf8EBTADAQH/MAsGA1UdDwQEAwIBBjAdBgNVHQ4EFgQUppFC/RNhSiOeCKQp +5dgTBCPuQSUwRwYDVR0eBEAwPqA8MAWCAy5ncjAFggMuZXUwBoIELmVkdTAGggQu +b3JnMAWBAy5ncjAFgQMuZXUwBoEELmVkdTAGgQQub3JnMA0GCSqGSIb3DQEBBQUA +A4IBAQAf73lB4XtuP7KMhjdCSk4cNx6NZrokgclPEg8hwAOXhiVtXdMiKahsog2p +6z0GW5k6x8zDmjR/qw7IThzh+uTczQ2+vyT+bOdrwg3IBp5OjWEopmr95fZi6hg8 +TqBTnbI6nOulnJEWtk2C4AwFSKls9cz4y51JtPACpf1wA+2KIaWuE4ZJwzNzvoc7 +dIsXRSZMFpGD/md9zU1jZ/rzAxKWeAaNsWftjj++n08C9bMJL/NMh98qy5V8Acys +Nnq/onN694/BtZqhFLKPM58N7yLcZnuEvUUXBj08yrl3NI/K6s8/MT7jiOOASSXI +l7WdmplNsDz4SgCbZN2fOUvRJ9e4 +-----END CERTIFICATE----- + +# Issuer: CN=Actalis Authentication Root CA O=Actalis S.p.A./03358520967 +# Subject: CN=Actalis Authentication Root CA O=Actalis S.p.A./03358520967 +# Label: "Actalis Authentication Root CA" +# Serial: 6271844772424770508 +# MD5 Fingerprint: 69:c1:0d:4f:07:a3:1b:c3:fe:56:3d:04:bc:11:f6:a6 +# SHA1 Fingerprint: f3:73:b3:87:06:5a:28:84:8a:f2:f3:4a:ce:19:2b:dd:c7:8e:9c:ac +# SHA256 Fingerprint: 55:92:60:84:ec:96:3a:64:b9:6e:2a:be:01:ce:0b:a8:6a:64:fb:fe:bc:c7:aa:b5:af:c1:55:b3:7f:d7:60:66 +-----BEGIN CERTIFICATE----- +MIIFuzCCA6OgAwIBAgIIVwoRl0LE48wwDQYJKoZIhvcNAQELBQAwazELMAkGA1UE +BhMCSVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8w +MzM1ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290 +IENBMB4XDTExMDkyMjExMjIwMloXDTMwMDkyMjExMjIwMlowazELMAkGA1UEBhMC +SVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8wMzM1 +ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290IENB +MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAp8bEpSmkLO/lGMWwUKNv +UTufClrJwkg4CsIcoBh/kbWHuUA/3R1oHwiD1S0eiKD4j1aPbZkCkpAW1V8IbInX +4ay8IMKx4INRimlNAJZaby/ARH6jDuSRzVju3PvHHkVH3Se5CAGfpiEd9UEtL0z9 +KK3giq0itFZljoZUj5NDKd45RnijMCO6zfB9E1fAXdKDa0hMxKufgFpbOr3JpyI/ +gCczWw63igxdBzcIy2zSekciRDXFzMwujt0q7bd9Zg1fYVEiVRvjRuPjPdA1Yprb +rxTIW6HMiRvhMCb8oJsfgadHHwTrozmSBp+Z07/T6k9QnBn+locePGX2oxgkg4YQ +51Q+qDp2JE+BIcXjDwL4k5RHILv+1A7TaLndxHqEguNTVHnd25zS8gebLra8Pu2F +be8lEfKXGkJh90qX6IuxEAf6ZYGyojnP9zz/GPvG8VqLWeICrHuS0E4UT1lF9gxe +KF+w6D9Fz8+vm2/7hNN3WpVvrJSEnu68wEqPSpP4RCHiMUVhUE4Q2OM1fEwZtN4F +v6MGn8i1zeQf1xcGDXqVdFUNaBr8EBtiZJ1t4JWgw5QHVw0U5r0F+7if5t+L4sbn +fpb2U8WANFAoWPASUHEXMLrmeGO89LKtmyuy/uE5jF66CyCU3nuDuP/jVo23Eek7 +jPKxwV2dpAtMK9myGPW1n0sCAwEAAaNjMGEwHQYDVR0OBBYEFFLYiDrIn3hm7Ynz +ezhwlMkCAjbQMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUUtiIOsifeGbt +ifN7OHCUyQICNtAwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQAL +e3KHwGCmSUyIWOYdiPcUZEim2FgKDk8TNd81HdTtBjHIgT5q1d07GjLukD0R0i70 +jsNjLiNmsGe+b7bAEzlgqqI0JZN1Ut6nna0Oh4lScWoWPBkdg/iaKWW+9D+a2fDz +WochcYBNy+A4mz+7+uAwTc+G02UQGRjRlwKxK3JCaKygvU5a2hi/a5iB0P2avl4V +SM0RFbnAKVy06Ij3Pjaut2L9HmLecHgQHEhb2rykOLpn7VU+Xlff1ANATIGk0k9j +pwlCCRT8AKnCgHNPLsBA2RF7SOp6AsDT6ygBJlh0wcBzIm2Tlf05fbsq4/aC4yyX +X04fkZT6/iyj2HYauE2yOE+b+h1IYHkm4vP9qdCa6HCPSXrW5b0KDtst842/6+Ok +fcvHlXHo2qN8xcL4dJIEG4aspCJTQLas/kx2z/uUMsA1n3Y/buWQbqCmJqK4LL7R +K4X9p2jIugErsWx0Hbhzlefut8cl8ABMALJ+tguLHPPAUJ4lueAI3jZm/zel0btU +ZCzJJ7VLkn5l/9Mt4blOvH+kQSGQQXemOR/qnuOf0GZvBeyqdn6/axag67XH/JJU +LysRJyU3eExRarDzzFhdFPFqSBX/wge2sY0PjlxQRrM9vwGYT7JZVEc+NHt4bVaT +LnPqZih4zR0Uv6CPLy64Lo7yFIrM6bV8+2ydDKXhlg== +-----END CERTIFICATE----- + +# Issuer: O=Trustis Limited OU=Trustis FPS Root CA +# Subject: O=Trustis Limited OU=Trustis FPS Root CA +# Label: "Trustis FPS Root CA" +# Serial: 36053640375399034304724988975563710553 +# MD5 Fingerprint: 30:c9:e7:1e:6b:e6:14:eb:65:b2:16:69:20:31:67:4d +# SHA1 Fingerprint: 3b:c0:38:0b:33:c3:f6:a6:0c:86:15:22:93:d9:df:f5:4b:81:c0:04 +# SHA256 Fingerprint: c1:b4:82:99:ab:a5:20:8f:e9:63:0a:ce:55:ca:68:a0:3e:da:5a:51:9c:88:02:a0:d3:a6:73:be:8f:8e:55:7d +-----BEGIN CERTIFICATE----- +MIIDZzCCAk+gAwIBAgIQGx+ttiD5JNM2a/fH8YygWTANBgkqhkiG9w0BAQUFADBF +MQswCQYDVQQGEwJHQjEYMBYGA1UEChMPVHJ1c3RpcyBMaW1pdGVkMRwwGgYDVQQL +ExNUcnVzdGlzIEZQUyBSb290IENBMB4XDTAzMTIyMzEyMTQwNloXDTI0MDEyMTEx +MzY1NFowRTELMAkGA1UEBhMCR0IxGDAWBgNVBAoTD1RydXN0aXMgTGltaXRlZDEc +MBoGA1UECxMTVHJ1c3RpcyBGUFMgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBAMVQe547NdDfxIzNjpvto8A2mfRC6qc+gIMPpqdZh8mQRUN+ +AOqGeSoDvT03mYlmt+WKVoaTnGhLaASMk5MCPjDSNzoiYYkchU59j9WvezX2fihH +iTHcDnlkH5nSW7r+f2C/revnPDgpai/lkQtV/+xvWNUtyd5MZnGPDNcE2gfmHhjj +vSkCqPoc4Vu5g6hBSLwacY3nYuUtsuvffM/bq1rKMfFMIvMFE/eC+XN5DL7XSxzA +0RU8k0Fk0ea+IxciAIleH2ulrG6nS4zto3Lmr2NNL4XSFDWaLk6M6jKYKIahkQlB +OrTh4/L68MkKokHdqeMDx4gVOxzUGpTXn2RZEm0CAwEAAaNTMFEwDwYDVR0TAQH/ +BAUwAwEB/zAfBgNVHSMEGDAWgBS6+nEleYtXQSUhhgtx67JkDoshZzAdBgNVHQ4E +FgQUuvpxJXmLV0ElIYYLceuyZA6LIWcwDQYJKoZIhvcNAQEFBQADggEBAH5Y//01 +GX2cGE+esCu8jowU/yyg2kdbw++BLa8F6nRIW/M+TgfHbcWzk88iNVy2P3UnXwmW +zaD+vkAMXBJV+JOCyinpXj9WV4s4NvdFGkwozZ5BuO1WTISkQMi4sKUraXAEasP4 +1BIy+Q7DsdwyhEQsb8tGD+pmQQ9P8Vilpg0ND2HepZ5dfWWhPBfnqFVO76DH7cZE +f1T1o+CP8HxVIo8ptoGj4W1OLBuAZ+ytIJ8MYmHVl/9D7S3B2l0pKoU/rGXuhg8F +jZBf3+6f9L/uHfuY5H+QK4R4EA5sSVPvFVtlRkpdr7r7OnIdzfYliB6XzCGcKQEN +ZetX2fNXlrtIzYE= +-----END CERTIFICATE----- + +# Issuer: CN=Buypass Class 2 Root CA O=Buypass AS-983163327 +# Subject: CN=Buypass Class 2 Root CA O=Buypass AS-983163327 +# Label: "Buypass Class 2 Root CA" +# Serial: 2 +# MD5 Fingerprint: 46:a7:d2:fe:45:fb:64:5a:a8:59:90:9b:78:44:9b:29 +# SHA1 Fingerprint: 49:0a:75:74:de:87:0a:47:fe:58:ee:f6:c7:6b:eb:c6:0b:12:40:99 +# SHA256 Fingerprint: 9a:11:40:25:19:7c:5b:b9:5d:94:e6:3d:55:cd:43:79:08:47:b6:46:b2:3c:df:11:ad:a4:a0:0e:ff:15:fb:48 +-----BEGIN CERTIFICATE----- +MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEd +MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3Mg +Q2xhc3MgMiBSb290IENBMB4XDTEwMTAyNjA4MzgwM1oXDTQwMTAyNjA4MzgwM1ow +TjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MSAw +HgYDVQQDDBdCdXlwYXNzIENsYXNzIDIgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEB +BQADggIPADCCAgoCggIBANfHXvfBB9R3+0Mh9PT1aeTuMgHbo4Yf5FkNuud1g1Lr +6hxhFUi7HQfKjK6w3Jad6sNgkoaCKHOcVgb/S2TwDCo3SbXlzwx87vFKu3MwZfPV +L4O2fuPn9Z6rYPnT8Z2SdIrkHJasW4DptfQxh6NR/Md+oW+OU3fUl8FVM5I+GC91 +1K2GScuVr1QGbNgGE41b/+EmGVnAJLqBcXmQRFBoJJRfuLMR8SlBYaNByyM21cHx +MlAQTn/0hpPshNOOvEu/XAFOBz3cFIqUCqTqc/sLUegTBxj6DvEr0VQVfTzh97QZ +QmdiXnfgolXsttlpF9U6r0TtSsWe5HonfOV116rLJeffawrbD02TTqigzXsu8lkB +arcNuAeBfos4GzjmCleZPe4h6KP1DBbdi+w0jpwqHAAVF41og9JwnxgIzRFo1clr +Us3ERo/ctfPYV3Me6ZQ5BL/T3jjetFPsaRyifsSP5BtwrfKi+fv3FmRmaZ9JUaLi +FRhnBkp/1Wy1TbMz4GHrXb7pmA8y1x1LPC5aAVKRCfLf6o3YBkBjqhHk/sM3nhRS +P/TizPJhk9H9Z2vXUq6/aKtAQ6BXNVN48FP4YUIHZMbXb5tMOA1jrGKvNouicwoN +9SG9dKpN6nIDSdvHXx1iY8f93ZHsM+71bbRuMGjeyNYmsHVee7QHIJihdjK4TWxP +AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFMmAd+BikoL1Rpzz +uvdMw964o605MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAU18h +9bqwOlI5LJKwbADJ784g7wbylp7ppHR/ehb8t/W2+xUbP6umwHJdELFx7rxP462s +A20ucS6vxOOto70MEae0/0qyexAQH6dXQbLArvQsWdZHEIjzIVEpMMpghq9Gqx3t +OluwlN5E40EIosHsHdb9T7bWR9AUC8rmyrV7d35BH16Dx7aMOZawP5aBQW9gkOLo ++fsicdl9sz1Gv7SEr5AcD48Saq/v7h56rgJKihcrdv6sVIkkLE8/trKnToyokZf7 +KcZ7XC25y2a2t6hbElGFtQl+Ynhw/qlqYLYdDnkM/crqJIByw5c/8nerQyIKx+u2 +DISCLIBrQYoIwOula9+ZEsuK1V6ADJHgJgg2SMX6OBE1/yWDLfJ6v9r9jv6ly0Us +H8SIU653DtmadsWOLB2jutXsMq7Aqqz30XpN69QH4kj3Io6wpJ9qzo6ysmD0oyLQ +I+uUWnpp3Q+/QFesa1lQ2aOZ4W7+jQF5JyMV3pKdewlNWudLSDBaGOYKbeaP4NK7 +5t98biGCwWg5TbSYWGZizEqQXsP6JwSxeRV0mcy+rSDeJmAc61ZRpqPq5KM/p/9h +3PFaTWwyI0PurKju7koSCTxdccK+efrCh2gdC/1cacwG0Jp9VJkqyTkaGa9LKkPz +Y11aWOIv4x3kqdbQCtCev9eBCfHJxyYNrJgWVqA= +-----END CERTIFICATE----- + +# Issuer: CN=Buypass Class 3 Root CA O=Buypass AS-983163327 +# Subject: CN=Buypass Class 3 Root CA O=Buypass AS-983163327 +# Label: "Buypass Class 3 Root CA" +# Serial: 2 +# MD5 Fingerprint: 3d:3b:18:9e:2c:64:5a:e8:d5:88:ce:0e:f9:37:c2:ec +# SHA1 Fingerprint: da:fa:f7:fa:66:84:ec:06:8f:14:50:bd:c7:c2:81:a5:bc:a9:64:57 +# SHA256 Fingerprint: ed:f7:eb:bc:a2:7a:2a:38:4d:38:7b:7d:40:10:c6:66:e2:ed:b4:84:3e:4c:29:b4:ae:1d:5b:93:32:e6:b2:4d +-----BEGIN CERTIFICATE----- +MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEd +MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3Mg +Q2xhc3MgMyBSb290IENBMB4XDTEwMTAyNjA4Mjg1OFoXDTQwMTAyNjA4Mjg1OFow +TjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MSAw +HgYDVQQDDBdCdXlwYXNzIENsYXNzIDMgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEB +BQADggIPADCCAgoCggIBAKXaCpUWUOOV8l6ddjEGMnqb8RB2uACatVI2zSRHsJ8Y +ZLya9vrVediQYkwiL944PdbgqOkcLNt4EemOaFEVcsfzM4fkoF0LXOBXByow9c3E +N3coTRiR5r/VUv1xLXA+58bEiuPwKAv0dpihi4dVsjoT/Lc+JzeOIuOoTyrvYLs9 +tznDDgFHmV0ST9tD+leh7fmdvhFHJlsTmKtdFoqwNxxXnUX/iJY2v7vKB3tvh2PX +0DJq1l1sDPGzbjniazEuOQAnFN44wOwZZoYS6J1yFhNkUsepNxz9gjDthBgd9K5c +/3ATAOux9TN6S9ZV+AWNS2mw9bMoNlwUxFFzTWsL8TQH2xc519woe2v1n/MuwU8X +KhDzzMro6/1rqy6any2CbgTUUgGTLT2G/H783+9CHaZr77kgxve9oKeV/afmiSTY +zIw0bOIjL9kSGiG5VZFvC5F5GQytQIgLcOJ60g7YaEi7ghM5EFjp2CoHxhLbWNvS +O1UQRwUVZ2J+GGOmRj8JDlQyXr8NYnon74Do29lLBlo3WiXQCBJ31G8JUJc9yB3D +34xFMFbG02SrZvPAXpacw8Tvw3xrizp5f7NJzz3iiZ+gMEuFuZyUJHmPfWupRWgP +K9Dx2hzLabjKSWJtyNBjYt1gD1iqj6G8BaVmos8bdrKEZLFMOVLAMLrwjEsCsLa3 +AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFEe4zf/lb+74suwv +Tg75JbCOPGvDMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAACAj +QTUEkMJAYmDv4jVM1z+s4jSQuKFvdvoWFqRINyzpkMLyPPgKn9iB5btb2iUspKdV +cSQy9sgL8rxq+JOssgfCX5/bzMiKqr5qb+FJEMwx14C7u8jYog5kV+qi9cKpMRXS +IGrs/CIBKM+GuIAeqcwRpTzyFrNHnfzSgCHEy9BHcEGhyoMZCCxt8l13nIoUE9Q2 +HJLw5QY33KbmkJs4j1xrG0aGQ0JfPgEHU1RdZX33inOhmlRaHylDFCfChQ+1iHsa +O5S3HWCntZznKWlXWpuTekMwGwPXYshApqr8ZORK15FTAaggiG6cX0S5y2CBNOxv +033aSF/rtJC8LakcC6wc1aJoIIAE1vyxjy+7SjENSoYc6+I2KSb12tjE8nVhz36u +dmNKekBlk4f4HoCMhuWG1o8O/FMsYOgWYRqiPkN7zTlgVGr18okmAWiDSKIz6MkE +kbIRNBE+6tBDGR8Dk5AM/1E9V/RBbuHLoL7ryWPNbczk+DaqaJ3tvV2XcEQNtg41 +3OEMXbugUZTLfhbrES+jkkXITHHZvMmZUldGL1DPvTVp9D0VzgalLA8+9oG6lLvD +u79leNKGef9JOxqDDPDeeOzI8k1MGt6CKfjBWtrt7uYnXuhF0J0cUahoq0Tj0Itq +4/g7u9xN12TyUb7mqqta6THuBrxzvxNiCp/HuZc= +-----END CERTIFICATE----- + +# Issuer: CN=T-TeleSec GlobalRoot Class 3 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center +# Subject: CN=T-TeleSec GlobalRoot Class 3 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center +# Label: "T-TeleSec GlobalRoot Class 3" +# Serial: 1 +# MD5 Fingerprint: ca:fb:40:a8:4e:39:92:8a:1d:fe:8e:2f:c4:27:ea:ef +# SHA1 Fingerprint: 55:a6:72:3e:cb:f2:ec:cd:c3:23:74:70:19:9d:2a:be:11:e3:81:d1 +# SHA256 Fingerprint: fd:73:da:d3:1c:64:4f:f1:b4:3b:ef:0c:cd:da:96:71:0b:9c:d9:87:5e:ca:7e:31:70:7a:f3:e9:6d:52:2b:bd +-----BEGIN CERTIFICATE----- +MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUx +KzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAd +BgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNl +YyBHbG9iYWxSb290IENsYXNzIDMwHhcNMDgxMDAxMTAyOTU2WhcNMzMxMDAxMjM1 +OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnBy +aXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50 +ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDMwggEiMA0G +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC9dZPwYiJvJK7genasfb3ZJNW4t/zN +8ELg63iIVl6bmlQdTQyK9tPPcPRStdiTBONGhnFBSivwKixVA9ZIw+A5OO3yXDw/ +RLyTPWGrTs0NvvAgJ1gORH8EGoel15YUNpDQSXuhdfsaa3Ox+M6pCSzyU9XDFES4 +hqX2iys52qMzVNn6chr3IhUciJFrf2blw2qAsCTz34ZFiP0Zf3WHHx+xGwpzJFu5 +ZeAsVMhg02YXP+HMVDNzkQI6pn97djmiH5a2OK61yJN0HZ65tOVgnS9W0eDrXltM +EnAMbEQgqxHY9Bn20pxSN+f6tsIxO0rUFJmtxxr1XV/6B7h8DR/Wgx6zAgMBAAGj +QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS1 +A/d2O2GCahKqGFPrAyGUv/7OyjANBgkqhkiG9w0BAQsFAAOCAQEAVj3vlNW92nOy +WL6ukK2YJ5f+AbGwUgC4TeQbIXQbfsDuXmkqJa9c1h3a0nnJ85cp4IaH3gRZD/FZ +1GSFS5mvJQQeyUapl96Cshtwn5z2r3Ex3XsFpSzTucpH9sry9uetuUg/vBa3wW30 +6gmv7PO15wWeph6KU1HWk4HMdJP2udqmJQV0eVp+QD6CSyYRMG7hP0HHRwA11fXT +91Q+gT3aSWqas+8QPebrb9HIIkfLzM8BMZLZGOMivgkeGj5asuRrDFR6fUNOuIml +e9eiPZaGzPImNC1qkp2aGtAw4l1OBLBfiyB+d8E9lYLRRpo7PHi4b6HQDWSieB4p +TpPDpFQUWw== +-----END CERTIFICATE----- + +# Issuer: CN=D-TRUST Root Class 3 CA 2 2009 O=D-Trust GmbH +# Subject: CN=D-TRUST Root Class 3 CA 2 2009 O=D-Trust GmbH +# Label: "D-TRUST Root Class 3 CA 2 2009" +# Serial: 623603 +# MD5 Fingerprint: cd:e0:25:69:8d:47:ac:9c:89:35:90:f7:fd:51:3d:2f +# SHA1 Fingerprint: 58:e8:ab:b0:36:15:33:fb:80:f7:9b:1b:6d:29:d3:ff:8d:5f:00:f0 +# SHA256 Fingerprint: 49:e7:a4:42:ac:f0:ea:62:87:05:00:54:b5:25:64:b6:50:e4:f4:9e:42:e3:48:d6:aa:38:e0:39:e9:57:b1:c1 +-----BEGIN CERTIFICATE----- +MIIEMzCCAxugAwIBAgIDCYPzMA0GCSqGSIb3DQEBCwUAME0xCzAJBgNVBAYTAkRF +MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMMHkQtVFJVU1QgUm9vdCBD +bGFzcyAzIENBIDIgMjAwOTAeFw0wOTExMDUwODM1NThaFw0yOTExMDUwODM1NTha +ME0xCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMM +HkQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgMjAwOTCCASIwDQYJKoZIhvcNAQEB +BQADggEPADCCAQoCggEBANOySs96R+91myP6Oi/WUEWJNTrGa9v+2wBoqOADER03 +UAifTUpolDWzU9GUY6cgVq/eUXjsKj3zSEhQPgrfRlWLJ23DEE0NkVJD2IfgXU42 +tSHKXzlABF9bfsyjxiupQB7ZNoTWSPOSHjRGICTBpFGOShrvUD9pXRl/RcPHAY9R +ySPocq60vFYJfxLLHLGvKZAKyVXMD9O0Gu1HNVpK7ZxzBCHQqr0ME7UAyiZsxGsM +lFqVlNpQmvH/pStmMaTJOKDfHR+4CS7zp+hnUquVH+BGPtikw8paxTGA6Eian5Rp +/hnd2HN8gcqW3o7tszIFZYQ05ub9VxC1X3a/L7AQDcUCAwEAAaOCARowggEWMA8G +A1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFP3aFMSfMN4hvR5COfyrYyNJ4PGEMA4G +A1UdDwEB/wQEAwIBBjCB0wYDVR0fBIHLMIHIMIGAoH6gfIZ6bGRhcDovL2RpcmVj +dG9yeS5kLXRydXN0Lm5ldC9DTj1ELVRSVVNUJTIwUm9vdCUyMENsYXNzJTIwMyUy +MENBJTIwMiUyMDIwMDksTz1ELVRydXN0JTIwR21iSCxDPURFP2NlcnRpZmljYXRl +cmV2b2NhdGlvbmxpc3QwQ6BBoD+GPWh0dHA6Ly93d3cuZC10cnVzdC5uZXQvY3Js +L2QtdHJ1c3Rfcm9vdF9jbGFzc18zX2NhXzJfMjAwOS5jcmwwDQYJKoZIhvcNAQEL +BQADggEBAH+X2zDI36ScfSF6gHDOFBJpiBSVYEQBrLLpME+bUMJm2H6NMLVwMeni +acfzcNsgFYbQDfC+rAF1hM5+n02/t2A7nPPKHeJeaNijnZflQGDSNiH+0LS4F9p0 +o3/U37CYAqxva2ssJSRyoWXuJVrl5jLn8t+rSfrzkGkj2wTZ51xY/GXUl77M/C4K +zCUqNQT4YJEVdT1B/yMfGchs64JTBKbkTCJNjYy6zltz7GRUUG3RnFX7acM2w4y8 +PIWmawomDeCTmGCufsYkl4phX5GOZpIJhzbNi5stPvZR1FDUWSi9g/LMKHtThm3Y +Johw1+qRzT65ysCQblrGXnRl11z+o+I= +-----END CERTIFICATE----- + +# Issuer: CN=D-TRUST Root Class 3 CA 2 EV 2009 O=D-Trust GmbH +# Subject: CN=D-TRUST Root Class 3 CA 2 EV 2009 O=D-Trust GmbH +# Label: "D-TRUST Root Class 3 CA 2 EV 2009" +# Serial: 623604 +# MD5 Fingerprint: aa:c6:43:2c:5e:2d:cd:c4:34:c0:50:4f:11:02:4f:b6 +# SHA1 Fingerprint: 96:c9:1b:0b:95:b4:10:98:42:fa:d0:d8:22:79:fe:60:fa:b9:16:83 +# SHA256 Fingerprint: ee:c5:49:6b:98:8c:e9:86:25:b9:34:09:2e:ec:29:08:be:d0:b0:f3:16:c2:d4:73:0c:84:ea:f1:f3:d3:48:81 +-----BEGIN CERTIFICATE----- +MIIEQzCCAyugAwIBAgIDCYP0MA0GCSqGSIb3DQEBCwUAMFAxCzAJBgNVBAYTAkRF +MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxKjAoBgNVBAMMIUQtVFJVU1QgUm9vdCBD +bGFzcyAzIENBIDIgRVYgMjAwOTAeFw0wOTExMDUwODUwNDZaFw0yOTExMDUwODUw +NDZaMFAxCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxELVRydXN0IEdtYkgxKjAoBgNV +BAMMIUQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgRVYgMjAwOTCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAJnxhDRwui+3MKCOvXwEz75ivJn9gpfSegpn +ljgJ9hBOlSJzmY3aFS3nBfwZcyK3jpgAvDw9rKFs+9Z5JUut8Mxk2og+KbgPCdM0 +3TP1YtHhzRnp7hhPTFiu4h7WDFsVWtg6uMQYZB7jM7K1iXdODL/ZlGsTl28So/6Z +qQTMFexgaDbtCHu39b+T7WYxg4zGcTSHThfqr4uRjRxWQa4iN1438h3Z0S0NL2lR +p75mpoo6Kr3HGrHhFPC+Oh25z1uxav60sUYgovseO3Dvk5h9jHOW8sXvhXCtKSb8 +HgQ+HKDYD8tSg2J87otTlZCpV6LqYQXY+U3EJ/pure3511H3a6UCAwEAAaOCASQw +ggEgMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNOUikxiEyoZLsyvcop9Ntea +HNxnMA4GA1UdDwEB/wQEAwIBBjCB3QYDVR0fBIHVMIHSMIGHoIGEoIGBhn9sZGFw +Oi8vZGlyZWN0b3J5LmQtdHJ1c3QubmV0L0NOPUQtVFJVU1QlMjBSb290JTIwQ2xh +c3MlMjAzJTIwQ0ElMjAyJTIwRVYlMjAyMDA5LE89RC1UcnVzdCUyMEdtYkgsQz1E +RT9jZXJ0aWZpY2F0ZXJldm9jYXRpb25saXN0MEagRKBChkBodHRwOi8vd3d3LmQt +dHJ1c3QubmV0L2NybC9kLXRydXN0X3Jvb3RfY2xhc3NfM19jYV8yX2V2XzIwMDku +Y3JsMA0GCSqGSIb3DQEBCwUAA4IBAQA07XtaPKSUiO8aEXUHL7P+PPoeUSbrh/Yp +3uDx1MYkCenBz1UbtDDZzhr+BlGmFaQt77JLvyAoJUnRpjZ3NOhk31KxEcdzes05 +nsKtjHEh8lprr988TlWvsoRlFIm5d8sqMb7Po23Pb0iUMkZv53GMoKaEGTcH8gNF +CSuGdXzfX2lXANtu2KZyIktQ1HWYVt+3GP9DQ1CuekR78HlR10M9p9OB0/DJT7na +xpeG0ILD5EJt/rDiZE4OJudANCa1CInXCGNjOCd1HjPqbqjdn5lPdE2BiYBL3ZqX +KVwvvoFBuYz/6n1gBp7N1z3TLqMVvKjmJuVvw9y4AyHqnxbxLFS1 +-----END CERTIFICATE----- + +# Issuer: CN=CA Disig Root R2 O=Disig a.s. +# Subject: CN=CA Disig Root R2 O=Disig a.s. +# Label: "CA Disig Root R2" +# Serial: 10572350602393338211 +# MD5 Fingerprint: 26:01:fb:d8:27:a7:17:9a:45:54:38:1a:43:01:3b:03 +# SHA1 Fingerprint: b5:61:eb:ea:a4:de:e4:25:4b:69:1a:98:a5:57:47:c2:34:c7:d9:71 +# SHA256 Fingerprint: e2:3d:4a:03:6d:7b:70:e9:f5:95:b1:42:20:79:d2:b9:1e:df:bb:1f:b6:51:a0:63:3e:aa:8a:9d:c5:f8:07:03 +-----BEGIN CERTIFICATE----- +MIIFaTCCA1GgAwIBAgIJAJK4iNuwisFjMA0GCSqGSIb3DQEBCwUAMFIxCzAJBgNV +BAYTAlNLMRMwEQYDVQQHEwpCcmF0aXNsYXZhMRMwEQYDVQQKEwpEaXNpZyBhLnMu +MRkwFwYDVQQDExBDQSBEaXNpZyBSb290IFIyMB4XDTEyMDcxOTA5MTUzMFoXDTQy +MDcxOTA5MTUzMFowUjELMAkGA1UEBhMCU0sxEzARBgNVBAcTCkJyYXRpc2xhdmEx +EzARBgNVBAoTCkRpc2lnIGEucy4xGTAXBgNVBAMTEENBIERpc2lnIFJvb3QgUjIw +ggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCio8QACdaFXS1tFPbCw3Oe +NcJxVX6B+6tGUODBfEl45qt5WDza/3wcn9iXAng+a0EE6UG9vgMsRfYvZNSrXaNH +PWSb6WiaxswbP7q+sos0Ai6YVRn8jG+qX9pMzk0DIaPY0jSTVpbLTAwAFjxfGs3I +x2ymrdMxp7zo5eFm1tL7A7RBZckQrg4FY8aAamkw/dLukO8NJ9+flXP04SXabBbe +QTg06ov80egEFGEtQX6sx3dOy1FU+16SGBsEWmjGycT6txOgmLcRK7fWV8x8nhfR +yyX+hk4kLlYMeE2eARKmK6cBZW58Yh2EhN/qwGu1pSqVg8NTEQxzHQuyRpDRQjrO +QG6Vrf/GlK1ul4SOfW+eioANSW1z4nuSHsPzwfPrLgVv2RvPN3YEyLRa5Beny912 +H9AZdugsBbPWnDTYltxhh5EF5EQIM8HauQhl1K6yNg3ruji6DOWbnuuNZt2Zz9aJ +QfYEkoopKW1rOhzndX0CcQ7zwOe9yxndnWCywmZgtrEE7snmhrmaZkCo5xHtgUUD +i/ZnWejBBhG93c+AAk9lQHhcR1DIm+YfgXvkRKhbhZri3lrVx/k6RGZL5DJUfORs +nLMOPReisjQS1n6yqEm70XooQL6iFh/f5DcfEXP7kAplQ6INfPgGAVUzfbANuPT1 +rqVCV3w2EYx7XsQDnYx5nQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1Ud +DwEB/wQEAwIBBjAdBgNVHQ4EFgQUtZn4r7CU9eMg1gqtzk5WpC5uQu0wDQYJKoZI +hvcNAQELBQADggIBACYGXnDnZTPIgm7ZnBc6G3pmsgH2eDtpXi/q/075KMOYKmFM +tCQSin1tERT3nLXK5ryeJ45MGcipvXrA1zYObYVybqjGom32+nNjf7xueQgcnYqf +GopTpti72TVVsRHFqQOzVju5hJMiXn7B9hJSi+osZ7z+Nkz1uM/Rs0mSO9MpDpkb +lvdhuDvEK7Z4bLQjb/D907JedR+Zlais9trhxTF7+9FGs9K8Z7RiVLoJ92Owk6Ka ++elSLotgEqv89WBW7xBci8QaQtyDW2QOy7W81k/BfDxujRNt+3vrMNDcTa/F1bal +TFtxyegxvug4BkihGuLq0t4SOVga/4AOgnXmt8kHbA7v/zjxmHHEt38OFdAlab0i +nSvtBfZGR6ztwPDUO+Ls7pZbkBNOHlY667DvlruWIxG68kOGdGSVyCh13x01utI3 +gzhTODY7z2zp+WsO0PsE6E9312UBeIYMej4hYvF/Y3EMyZ9E26gnonW+boE+18Dr +G5gPcFw0sorMwIUY6256s/daoQe/qUKS82Ail+QUoQebTnbAjn39pCXHR+3/H3Os +zMOl6W8KjptlwlCFtaOgUxLMVYdh84GuEEZhvUQhuMI9dM9+JDX6HAcOmz0iyu8x +L4ysEr3vQCj8KWefshNPZiTEUxnpHikV7+ZtsH8tZ/3zbBt1RqPlShfppNcL +-----END CERTIFICATE----- + +# Issuer: CN=ACCVRAIZ1 O=ACCV OU=PKIACCV +# Subject: CN=ACCVRAIZ1 O=ACCV OU=PKIACCV +# Label: "ACCVRAIZ1" +# Serial: 6828503384748696800 +# MD5 Fingerprint: d0:a0:5a:ee:05:b6:09:94:21:a1:7d:f1:b2:29:82:02 +# SHA1 Fingerprint: 93:05:7a:88:15:c6:4f:ce:88:2f:fa:91:16:52:28:78:bc:53:64:17 +# SHA256 Fingerprint: 9a:6e:c0:12:e1:a7:da:9d:be:34:19:4d:47:8a:d7:c0:db:18:22:fb:07:1d:f1:29:81:49:6e:d1:04:38:41:13 +-----BEGIN CERTIFICATE----- +MIIH0zCCBbugAwIBAgIIXsO3pkN/pOAwDQYJKoZIhvcNAQEFBQAwQjESMBAGA1UE +AwwJQUNDVlJBSVoxMRAwDgYDVQQLDAdQS0lBQ0NWMQ0wCwYDVQQKDARBQ0NWMQsw +CQYDVQQGEwJFUzAeFw0xMTA1MDUwOTM3MzdaFw0zMDEyMzEwOTM3MzdaMEIxEjAQ +BgNVBAMMCUFDQ1ZSQUlaMTEQMA4GA1UECwwHUEtJQUNDVjENMAsGA1UECgwEQUND +VjELMAkGA1UEBhMCRVMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCb +qau/YUqXry+XZpp0X9DZlv3P4uRm7x8fRzPCRKPfmt4ftVTdFXxpNRFvu8gMjmoY +HtiP2Ra8EEg2XPBjs5BaXCQ316PWywlxufEBcoSwfdtNgM3802/J+Nq2DoLSRYWo +G2ioPej0RGy9ocLLA76MPhMAhN9KSMDjIgro6TenGEyxCQ0jVn8ETdkXhBilyNpA +lHPrzg5XPAOBOp0KoVdDaaxXbXmQeOW1tDvYvEyNKKGno6e6Ak4l0Squ7a4DIrhr +IA8wKFSVf+DuzgpmndFALW4ir50awQUZ0m/A8p/4e7MCQvtQqR0tkw8jq8bBD5L/ +0KIV9VMJcRz/RROE5iZe+OCIHAr8Fraocwa48GOEAqDGWuzndN9wrqODJerWx5eH +k6fGioozl2A3ED6XPm4pFdahD9GILBKfb6qkxkLrQaLjlUPTAYVtjrs78yM2x/47 +4KElB0iryYl0/wiPgL/AlmXz7uxLaL2diMMxs0Dx6M/2OLuc5NF/1OVYm3z61PMO +m3WR5LpSLhl+0fXNWhn8ugb2+1KoS5kE3fj5tItQo05iifCHJPqDQsGH+tUtKSpa +cXpkatcnYGMN285J9Y0fkIkyF/hzQ7jSWpOGYdbhdQrqeWZ2iE9x6wQl1gpaepPl +uUsXQA+xtrn13k/c4LOsOxFwYIRKQ26ZIMApcQrAZQIDAQABo4ICyzCCAscwfQYI +KwYBBQUHAQEEcTBvMEwGCCsGAQUFBzAChkBodHRwOi8vd3d3LmFjY3YuZXMvZmls +ZWFkbWluL0FyY2hpdm9zL2NlcnRpZmljYWRvcy9yYWl6YWNjdjEuY3J0MB8GCCsG +AQUFBzABhhNodHRwOi8vb2NzcC5hY2N2LmVzMB0GA1UdDgQWBBTSh7Tj3zcnk1X2 +VuqB5TbMjB4/vTAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFNKHtOPfNyeT +VfZW6oHlNsyMHj+9MIIBcwYDVR0gBIIBajCCAWYwggFiBgRVHSAAMIIBWDCCASIG +CCsGAQUFBwICMIIBFB6CARAAQQB1AHQAbwByAGkAZABhAGQAIABkAGUAIABDAGUA +cgB0AGkAZgBpAGMAYQBjAGkA8wBuACAAUgBhAO0AegAgAGQAZQAgAGwAYQAgAEEA +QwBDAFYAIAAoAEEAZwBlAG4AYwBpAGEAIABkAGUAIABUAGUAYwBuAG8AbABvAGcA +7QBhACAAeQAgAEMAZQByAHQAaQBmAGkAYwBhAGMAaQDzAG4AIABFAGwAZQBjAHQA +cgDzAG4AaQBjAGEALAAgAEMASQBGACAAUQA0ADYAMAAxADEANQA2AEUAKQAuACAA +QwBQAFMAIABlAG4AIABoAHQAdABwADoALwAvAHcAdwB3AC4AYQBjAGMAdgAuAGUA +czAwBggrBgEFBQcCARYkaHR0cDovL3d3dy5hY2N2LmVzL2xlZ2lzbGFjaW9uX2Mu +aHRtMFUGA1UdHwROMEwwSqBIoEaGRGh0dHA6Ly93d3cuYWNjdi5lcy9maWxlYWRt +aW4vQXJjaGl2b3MvY2VydGlmaWNhZG9zL3JhaXphY2N2MV9kZXIuY3JsMA4GA1Ud +DwEB/wQEAwIBBjAXBgNVHREEEDAOgQxhY2N2QGFjY3YuZXMwDQYJKoZIhvcNAQEF +BQADggIBAJcxAp/n/UNnSEQU5CmH7UwoZtCPNdpNYbdKl02125DgBS4OxnnQ8pdp +D70ER9m+27Up2pvZrqmZ1dM8MJP1jaGo/AaNRPTKFpV8M9xii6g3+CfYCS0b78gU +JyCpZET/LtZ1qmxNYEAZSUNUY9rizLpm5U9EelvZaoErQNV/+QEnWCzI7UiRfD+m +AM/EKXMRNt6GGT6d7hmKG9Ww7Y49nCrADdg9ZuM8Db3VlFzi4qc1GwQA9j9ajepD +vV+JHanBsMyZ4k0ACtrJJ1vnE5Bc5PUzolVt3OAJTS+xJlsndQAJxGJ3KQhfnlms +tn6tn1QwIgPBHnFk/vk4CpYY3QIUrCPLBhwepH2NDd4nQeit2hW3sCPdK6jT2iWH +7ehVRE2I9DZ+hJp4rPcOVkkO1jMl1oRQQmwgEh0q1b688nCBpHBgvgW1m54ERL5h +I6zppSSMEYCUWqKiuUnSwdzRp+0xESyeGabu4VXhwOrPDYTkF7eifKXeVSUG7szA +h1xA2syVP1XgNce4hL60Xc16gwFy7ofmXx2utYXGJt/mwZrpHgJHnyqobalbz+xF +d3+YJ5oyXSrjhO7FmGYvliAd3djDJ9ew+f7Zfc3Qn48LFFhRny+Lwzgt3uiP1o2H +pPVWQxaZLPSkVrQ0uGE3ycJYgBugl6H8WY3pEfbRD0tVNEYqi4Y7 +-----END CERTIFICATE----- + +# Issuer: CN=TWCA Global Root CA O=TAIWAN-CA OU=Root CA +# Subject: CN=TWCA Global Root CA O=TAIWAN-CA OU=Root CA +# Label: "TWCA Global Root CA" +# Serial: 3262 +# MD5 Fingerprint: f9:03:7e:cf:e6:9e:3c:73:7a:2a:90:07:69:ff:2b:96 +# SHA1 Fingerprint: 9c:bb:48:53:f6:a4:f6:d3:52:a4:e8:32:52:55:60:13:f5:ad:af:65 +# SHA256 Fingerprint: 59:76:90:07:f7:68:5d:0f:cd:50:87:2f:9f:95:d5:75:5a:5b:2b:45:7d:81:f3:69:2b:61:0a:98:67:2f:0e:1b +-----BEGIN CERTIFICATE----- +MIIFQTCCAymgAwIBAgICDL4wDQYJKoZIhvcNAQELBQAwUTELMAkGA1UEBhMCVFcx +EjAQBgNVBAoTCVRBSVdBTi1DQTEQMA4GA1UECxMHUm9vdCBDQTEcMBoGA1UEAxMT +VFdDQSBHbG9iYWwgUm9vdCBDQTAeFw0xMjA2MjcwNjI4MzNaFw0zMDEyMzExNTU5 +NTlaMFExCzAJBgNVBAYTAlRXMRIwEAYDVQQKEwlUQUlXQU4tQ0ExEDAOBgNVBAsT +B1Jvb3QgQ0ExHDAaBgNVBAMTE1RXQ0EgR2xvYmFsIFJvb3QgQ0EwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQCwBdvI64zEbooh745NnHEKH1Jw7W2CnJfF +10xORUnLQEK1EjRsGcJ0pDFfhQKX7EMzClPSnIyOt7h52yvVavKOZsTuKwEHktSz +0ALfUPZVr2YOy+BHYC8rMjk1Ujoog/h7FsYYuGLWRyWRzvAZEk2tY/XTP3VfKfCh +MBwqoJimFb3u/Rk28OKRQ4/6ytYQJ0lM793B8YVwm8rqqFpD/G2Gb3PpN0Wp8DbH +zIh1HrtsBv+baz4X7GGqcXzGHaL3SekVtTzWoWH1EfcFbx39Eb7QMAfCKbAJTibc +46KokWofwpFFiFzlmLhxpRUZyXx1EcxwdE8tmx2RRP1WKKD+u4ZqyPpcC1jcxkt2 +yKsi2XMPpfRaAok/T54igu6idFMqPVMnaR1sjjIsZAAmY2E2TqNGtz99sy2sbZCi +laLOz9qC5wc0GZbpuCGqKX6mOL6OKUohZnkfs8O1CWfe1tQHRvMq2uYiN2DLgbYP +oA/pyJV/v1WRBXrPPRXAb94JlAGD1zQbzECl8LibZ9WYkTunhHiVJqRaCPgrdLQA +BDzfuBSO6N+pjWxnkjMdwLfS7JLIvgm/LCkFbwJrnu+8vyq8W8BQj0FwcYeyTbcE +qYSjMq+u7msXi7Kx/mzhkIyIqJdIzshNy/MGz19qCkKxHh53L46g5pIOBvwFItIm +4TFRfTLcDwIDAQABoyMwITAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB +/zANBgkqhkiG9w0BAQsFAAOCAgEAXzSBdu+WHdXltdkCY4QWwa6gcFGn90xHNcgL +1yg9iXHZqjNB6hQbbCEAwGxCGX6faVsgQt+i0trEfJdLjbDorMjupWkEmQqSpqsn +LhpNgb+E1HAerUf+/UqdM+DyucRFCCEK2mlpc3INvjT+lIutwx4116KD7+U4x6WF +H6vPNOw/KP4M8VeGTslV9xzU2KV9Bnpv1d8Q34FOIWWxtuEXeZVFBs5fzNxGiWNo +RI2T9GRwoD2dKAXDOXC4Ynsg/eTb6QihuJ49CcdP+yz4k3ZB3lLg4VfSnQO8d57+ +nile98FRYB/e2guyLXW3Q0iT5/Z5xoRdgFlglPx4mI88k1HtQJAH32RjJMtOcQWh +15QaiDLxInQirqWm2BJpTGCjAu4r7NRjkgtevi92a6O2JryPA9gK8kxkRr05YuWW +6zRjESjMlfGt7+/cgFhI6Uu46mWs6fyAtbXIRfmswZ/ZuepiiI7E8UuDEq3mi4TW +nsLrgxifarsbJGAzcMzs9zLzXNl5fe+epP7JI8Mk7hWSsT2RTyaGvWZzJBPqpK5j +wa19hAM8EHiGG3njxPPyBJUgriOCxLM6AGK/5jYk4Ve6xx6QddVfP5VhK8E7zeWz +aGHQRiapIVJpLesux+t3zqY6tQMzT3bR51xUAV3LePTJDL/PEo4XLSNolOer/qmy +KwbQBM0= +-----END CERTIFICATE----- + +# Issuer: CN=TeliaSonera Root CA v1 O=TeliaSonera +# Subject: CN=TeliaSonera Root CA v1 O=TeliaSonera +# Label: "TeliaSonera Root CA v1" +# Serial: 199041966741090107964904287217786801558 +# MD5 Fingerprint: 37:41:49:1b:18:56:9a:26:f5:ad:c2:66:fb:40:a5:4c +# SHA1 Fingerprint: 43:13:bb:96:f1:d5:86:9b:c1:4e:6a:92:f6:cf:f6:34:69:87:82:37 +# SHA256 Fingerprint: dd:69:36:fe:21:f8:f0:77:c1:23:a1:a5:21:c1:22:24:f7:22:55:b7:3e:03:a7:26:06:93:e8:a2:4b:0f:a3:89 +-----BEGIN CERTIFICATE----- +MIIFODCCAyCgAwIBAgIRAJW+FqD3LkbxezmCcvqLzZYwDQYJKoZIhvcNAQEFBQAw +NzEUMBIGA1UECgwLVGVsaWFTb25lcmExHzAdBgNVBAMMFlRlbGlhU29uZXJhIFJv +b3QgQ0EgdjEwHhcNMDcxMDE4MTIwMDUwWhcNMzIxMDE4MTIwMDUwWjA3MRQwEgYD +VQQKDAtUZWxpYVNvbmVyYTEfMB0GA1UEAwwWVGVsaWFTb25lcmEgUm9vdCBDQSB2 +MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMK+6yfwIaPzaSZVfp3F +VRaRXP3vIb9TgHot0pGMYzHw7CTww6XScnwQbfQ3t+XmfHnqjLWCi65ItqwA3GV1 +7CpNX8GH9SBlK4GoRz6JI5UwFpB/6FcHSOcZrr9FZ7E3GwYq/t75rH2D+1665I+X +Z75Ljo1kB1c4VWk0Nj0TSO9P4tNmHqTPGrdeNjPUtAa9GAH9d4RQAEX1jF3oI7x+ +/jXh7VB7qTCNGdMJjmhnXb88lxhTuylixcpecsHHltTbLaC0H2kD7OriUPEMPPCs +81Mt8Bz17Ww5OXOAFshSsCPN4D7c3TxHoLs1iuKYaIu+5b9y7tL6pe0S7fyYGKkm +dtwoSxAgHNN/Fnct7W+A90m7UwW7XWjH1Mh1Fj+JWov3F0fUTPHSiXk+TT2YqGHe +Oh7S+F4D4MHJHIzTjU3TlTazN19jY5szFPAtJmtTfImMMsJu7D0hADnJoWjiUIMu +sDor8zagrC/kb2HCUQk5PotTubtn2txTuXZZNp1D5SDgPTJghSJRt8czu90VL6R4 +pgd7gUY2BIbdeTXHlSw7sKMXNeVzH7RcWe/a6hBle3rQf5+ztCo3O3CLm1u5K7fs +slESl1MpWtTwEhDcTwK7EpIvYtQ/aUN8Ddb8WHUBiJ1YFkveupD/RwGJBmr2X7KQ +arMCpgKIv7NHfirZ1fpoeDVNAgMBAAGjPzA9MA8GA1UdEwEB/wQFMAMBAf8wCwYD +VR0PBAQDAgEGMB0GA1UdDgQWBBTwj1k4ALP1j5qWDNXr+nuqF+gTEjANBgkqhkiG +9w0BAQUFAAOCAgEAvuRcYk4k9AwI//DTDGjkk0kiP0Qnb7tt3oNmzqjMDfz1mgbl +dxSR651Be5kqhOX//CHBXfDkH1e3damhXwIm/9fH907eT/j3HEbAek9ALCI18Bmx +0GtnLLCo4MBANzX2hFxc469CeP6nyQ1Q6g2EdvZR74NTxnr/DlZJLo961gzmJ1Tj +TQpgcmLNkQfWpb/ImWvtxBnmq0wROMVvMeJuScg/doAmAyYp4Db29iBT4xdwNBed +Y2gea+zDTYa4EzAvXUYNR0PVG6pZDrlcjQZIrXSHX8f8MVRBE+LHIQ6e4B4N4cB7 +Q4WQxYpYxmUKeFfyxiMPAdkgS94P+5KFdSpcc41teyWRyu5FrgZLAMzTsVlQ2jqI +OylDRl6XK1TOU2+NSueW+r9xDkKLfP0ooNBIytrEgUy7onOTJsjrDNYmiLbAJM+7 +vVvrdX3pCI6GMyx5dwlppYn8s3CQh3aP0yK7Qs69cwsgJirQmz1wHiRszYd2qReW +t88NkvuOGKmYSdGe/mBEciG5Ge3C9THxOUiIkCR1VBatzvT4aRRkOfujuLpwQMcn +HL/EVlP6Y2XQ8xwOFvVrhlhNGNTkDY6lnVuR3HYkUD/GKvvZt5y11ubQ2egZixVx +SK236thZiNSQvxaz2emsWWFUyBy6ysHK4bkgTI86k4mloMy/0/Z1pHWWbVY= +-----END CERTIFICATE----- + +# Issuer: CN=E-Tugra Certification Authority O=E-Tu\u011fra EBG Bili\u015fim Teknolojileri ve Hizmetleri A.\u015e. OU=E-Tugra Sertifikasyon Merkezi +# Subject: CN=E-Tugra Certification Authority O=E-Tu\u011fra EBG Bili\u015fim Teknolojileri ve Hizmetleri A.\u015e. OU=E-Tugra Sertifikasyon Merkezi +# Label: "E-Tugra Certification Authority" +# Serial: 7667447206703254355 +# MD5 Fingerprint: b8:a1:03:63:b0:bd:21:71:70:8a:6f:13:3a:bb:79:49 +# SHA1 Fingerprint: 51:c6:e7:08:49:06:6e:f3:92:d4:5c:a0:0d:6d:a3:62:8f:c3:52:39 +# SHA256 Fingerprint: b0:bf:d5:2b:b0:d7:d9:bd:92:bf:5d:4d:c1:3d:a2:55:c0:2c:54:2f:37:83:65:ea:89:39:11:f5:5e:55:f2:3c +-----BEGIN CERTIFICATE----- +MIIGSzCCBDOgAwIBAgIIamg+nFGby1MwDQYJKoZIhvcNAQELBQAwgbIxCzAJBgNV +BAYTAlRSMQ8wDQYDVQQHDAZBbmthcmExQDA+BgNVBAoMN0UtVHXEn3JhIEVCRyBC +aWxpxZ9pbSBUZWtub2xvamlsZXJpIHZlIEhpem1ldGxlcmkgQS7Fni4xJjAkBgNV +BAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBNZXJrZXppMSgwJgYDVQQDDB9FLVR1 +Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTEzMDMwNTEyMDk0OFoXDTIz +MDMwMzEyMDk0OFowgbIxCzAJBgNVBAYTAlRSMQ8wDQYDVQQHDAZBbmthcmExQDA+ +BgNVBAoMN0UtVHXEn3JhIEVCRyBCaWxpxZ9pbSBUZWtub2xvamlsZXJpIHZlIEhp +em1ldGxlcmkgQS7Fni4xJjAkBgNVBAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBN +ZXJrZXppMSgwJgYDVQQDDB9FLVR1Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5 +MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA4vU/kwVRHoViVF56C/UY +B4Oufq9899SKa6VjQzm5S/fDxmSJPZQuVIBSOTkHS0vdhQd2h8y/L5VMzH2nPbxH +D5hw+IyFHnSOkm0bQNGZDbt1bsipa5rAhDGvykPL6ys06I+XawGb1Q5KCKpbknSF +Q9OArqGIW66z6l7LFpp3RMih9lRozt6Plyu6W0ACDGQXwLWTzeHxE2bODHnv0ZEo +q1+gElIwcxmOj+GMB6LDu0rw6h8VqO4lzKRG+Bsi77MOQ7osJLjFLFzUHPhdZL3D +k14opz8n8Y4e0ypQBaNV2cvnOVPAmJ6MVGKLJrD3fY185MaeZkJVgkfnsliNZvcH +fC425lAcP9tDJMW/hkd5s3kc91r0E+xs+D/iWR+V7kI+ua2oMoVJl0b+SzGPWsut +dEcf6ZG33ygEIqDUD13ieU/qbIWGvaimzuT6w+Gzrt48Ue7LE3wBf4QOXVGUnhMM +ti6lTPk5cDZvlsouDERVxcr6XQKj39ZkjFqzAQqptQpHF//vkUAqjqFGOjGY5RH8 +zLtJVor8udBhmm9lbObDyz51Sf6Pp+KJxWfXnUYTTjF2OySznhFlhqt/7x3U+Lzn +rFpct1pHXFXOVbQicVtbC/DP3KBhZOqp12gKY6fgDT+gr9Oq0n7vUaDmUStVkhUX +U8u3Zg5mTPj5dUyQ5xJwx0UCAwEAAaNjMGEwHQYDVR0OBBYEFC7j27JJ0JxUeVz6 +Jyr+zE7S6E5UMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAULuPbsknQnFR5 +XPonKv7MTtLoTlQwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQAF +Nzr0TbdF4kV1JI+2d1LoHNgQk2Xz8lkGpD4eKexd0dCrfOAKkEh47U6YA5n+KGCR +HTAduGN8qOY1tfrTYXbm1gdLymmasoR6d5NFFxWfJNCYExL/u6Au/U5Mh/jOXKqY +GwXgAEZKgoClM4so3O0409/lPun++1ndYYRP0lSWE2ETPo+Aab6TR7U1Q9Jauz1c +77NCR807VRMGsAnb/WP2OogKmW9+4c4bU2pEZiNRCHu8W1Ki/QY3OEBhj0qWuJA3 ++GbHeJAAFS6LrVE1Uweoa2iu+U48BybNCAVwzDk/dr2l02cmAYamU9JgO3xDf1WK +vJUawSg5TB9D0pH0clmKuVb8P7Sd2nCcdlqMQ1DujjByTd//SffGqWfZbawCEeI6 +FiWnWAjLb1NBnEg4R2gz0dfHj9R0IdTDBZB6/86WiLEVKV0jq9BgoRJP3vQXzTLl +yb/IQ639Lo7xr+L0mPoSHyDYwKcMhcWQ9DstliaxLL5Mq+ux0orJ23gTDx4JnW2P +AJ8C2sH6H3p6CcRK5ogql5+Ji/03X186zjhZhkuvcQu02PJwT58yE+Owp1fl2tpD +y4Q08ijE6m30Ku/Ba3ba+367hTzSU8JNvnHhRdH9I2cNE3X7z2VnIp2usAnRCf8d +NL/+I5c30jn6PQ0GC7TbO6Orb1wdtn7os4I07QZcJA== +-----END CERTIFICATE----- + +# Issuer: CN=T-TeleSec GlobalRoot Class 2 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center +# Subject: CN=T-TeleSec GlobalRoot Class 2 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center +# Label: "T-TeleSec GlobalRoot Class 2" +# Serial: 1 +# MD5 Fingerprint: 2b:9b:9e:e4:7b:6c:1f:00:72:1a:cc:c1:77:79:df:6a +# SHA1 Fingerprint: 59:0d:2d:7d:88:4f:40:2e:61:7e:a5:62:32:17:65:cf:17:d8:94:e9 +# SHA256 Fingerprint: 91:e2:f5:78:8d:58:10:eb:a7:ba:58:73:7d:e1:54:8a:8e:ca:cd:01:45:98:bc:0b:14:3e:04:1b:17:05:25:52 +-----BEGIN CERTIFICATE----- +MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUx +KzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAd +BgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNl +YyBHbG9iYWxSb290IENsYXNzIDIwHhcNMDgxMDAxMTA0MDE0WhcNMzMxMDAxMjM1 +OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnBy +aXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50 +ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDIwggEiMA0G +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCqX9obX+hzkeXaXPSi5kfl82hVYAUd +AqSzm1nzHoqvNK38DcLZSBnuaY/JIPwhqgcZ7bBcrGXHX+0CfHt8LRvWurmAwhiC +FoT6ZrAIxlQjgeTNuUk/9k9uN0goOA/FvudocP05l03Sx5iRUKrERLMjfTlH6VJi +1hKTXrcxlkIF+3anHqP1wvzpesVsqXFP6st4vGCvx9702cu+fjOlbpSD8DT6Iavq +jnKgP6TeMFvvhk1qlVtDRKgQFRzlAVfFmPHmBiiRqiDFt1MmUUOyCxGVWOHAD3bZ +wI18gfNycJ5v/hqO2V81xrJvNHy+SE/iWjnX2J14np+GPgNeGYtEotXHAgMBAAGj +QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS/ +WSA2AHmgoCJrjNXyYdK4LMuCSjANBgkqhkiG9w0BAQsFAAOCAQEAMQOiYQsfdOhy +NsZt+U2e+iKo4YFWz827n+qrkRk4r6p8FU3ztqONpfSO9kSpp+ghla0+AGIWiPAC +uvxhI+YzmzB6azZie60EI4RYZeLbK4rnJVM3YlNfvNoBYimipidx5joifsFvHZVw +IEoHNN/q/xWA5brXethbdXwFeilHfkCoMRN3zUA7tFFHei4R40cR3p1m0IvVVGb6 +g1XqfMIpiRvpb7PO4gWEyS8+eIVibslfwXhjdFjASBgMmTnrpMwatXlajRWc2BQN +9noHV8cigwUtPJslJj0Ys6lDfMjIq2SPDqO/nBudMNva0Bkuqjzx+zOAduTNrRlP +BSeOE6Fuwg== +-----END CERTIFICATE----- + +# Issuer: CN=Atos TrustedRoot 2011 O=Atos +# Subject: CN=Atos TrustedRoot 2011 O=Atos +# Label: "Atos TrustedRoot 2011" +# Serial: 6643877497813316402 +# MD5 Fingerprint: ae:b9:c4:32:4b:ac:7f:5d:66:cc:77:94:bb:2a:77:56 +# SHA1 Fingerprint: 2b:b1:f5:3e:55:0c:1d:c5:f1:d4:e6:b7:6a:46:4b:55:06:02:ac:21 +# SHA256 Fingerprint: f3:56:be:a2:44:b7:a9:1e:b3:5d:53:ca:9a:d7:86:4a:ce:01:8e:2d:35:d5:f8:f9:6d:df:68:a6:f4:1a:a4:74 +-----BEGIN CERTIFICATE----- +MIIDdzCCAl+gAwIBAgIIXDPLYixfszIwDQYJKoZIhvcNAQELBQAwPDEeMBwGA1UE +AwwVQXRvcyBUcnVzdGVkUm9vdCAyMDExMQ0wCwYDVQQKDARBdG9zMQswCQYDVQQG +EwJERTAeFw0xMTA3MDcxNDU4MzBaFw0zMDEyMzEyMzU5NTlaMDwxHjAcBgNVBAMM +FUF0b3MgVHJ1c3RlZFJvb3QgMjAxMTENMAsGA1UECgwEQXRvczELMAkGA1UEBhMC +REUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCVhTuXbyo7LjvPpvMp +Nb7PGKw+qtn4TaA+Gke5vJrf8v7MPkfoepbCJI419KkM/IL9bcFyYie96mvr54rM +VD6QUM+A1JX76LWC1BTFtqlVJVfbsVD2sGBkWXppzwO3bw2+yj5vdHLqqjAqc2K+ +SZFhyBH+DgMq92og3AIVDV4VavzjgsG1xZ1kCWyjWZgHJ8cblithdHFsQ/H3NYkQ +4J7sVaE3IqKHBAUsR320HLliKWYoyrfhk/WklAOZuXCFteZI6o1Q/NnezG8HDt0L +cp2AMBYHlT8oDv3FdU9T1nSatCQujgKRz3bFmx5VdJx4IbHwLfELn8LVlhgf8FQi +eowHAgMBAAGjfTB7MB0GA1UdDgQWBBSnpQaxLKYJYO7Rl+lwrrw7GWzbITAPBgNV +HRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFKelBrEspglg7tGX6XCuvDsZbNshMBgG +A1UdIAQRMA8wDQYLKwYBBAGwLQMEAQEwDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3 +DQEBCwUAA4IBAQAmdzTblEiGKkGdLD4GkGDEjKwLVLgfuXvTBznk+j57sj1O7Z8j +vZfza1zv7v1Apt+hk6EKhqzvINB5Ab149xnYJDE0BAGmuhWawyfc2E8PzBhj/5kP +DpFrdRbhIfzYJsdHt6bPWHJxfrrhTZVHO8mvbaG0weyJ9rQPOLXiZNwlz6bb65pc +maHFCN795trV1lpFDMS3wrUU77QR/w4VtfX128a961qn8FYiqTxlVMYVqL2Gns2D +lmh6cYGJ4Qvh6hEbaAjMaZ7snkGeRDImeuKHCnE96+RapNLbxc3G3mB/ufNPRJLv +KrcYPqcZ2Qt9sTdBQrC6YB3y/gkRsPCHe6ed +-----END CERTIFICATE----- + +# Issuer: CN=QuoVadis Root CA 1 G3 O=QuoVadis Limited +# Subject: CN=QuoVadis Root CA 1 G3 O=QuoVadis Limited +# Label: "QuoVadis Root CA 1 G3" +# Serial: 687049649626669250736271037606554624078720034195 +# MD5 Fingerprint: a4:bc:5b:3f:fe:37:9a:fa:64:f0:e2:fa:05:3d:0b:ab +# SHA1 Fingerprint: 1b:8e:ea:57:96:29:1a:c9:39:ea:b8:0a:81:1a:73:73:c0:93:79:67 +# SHA256 Fingerprint: 8a:86:6f:d1:b2:76:b5:7e:57:8e:92:1c:65:82:8a:2b:ed:58:e9:f2:f2:88:05:41:34:b7:f1:f4:bf:c9:cc:74 +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIUeFhfLq0sGUvjNwc1NBMotZbUZZMwDQYJKoZIhvcNAQEL +BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc +BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMSBHMzAeFw0xMjAxMTIxNzI3NDRaFw00 +MjAxMTIxNzI3NDRaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM +aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDEgRzMwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQCgvlAQjunybEC0BJyFuTHK3C3kEakEPBtV +wedYMB0ktMPvhd6MLOHBPd+C5k+tR4ds7FtJwUrVu4/sh6x/gpqG7D0DmVIB0jWe +rNrwU8lmPNSsAgHaJNM7qAJGr6Qc4/hzWHa39g6QDbXwz8z6+cZM5cOGMAqNF341 +68Xfuw6cwI2H44g4hWf6Pser4BOcBRiYz5P1sZK0/CPTz9XEJ0ngnjybCKOLXSoh +4Pw5qlPafX7PGglTvF0FBM+hSo+LdoINofjSxxR3W5A2B4GbPgb6Ul5jxaYA/qXp +UhtStZI5cgMJYr2wYBZupt0lwgNm3fME0UDiTouG9G/lg6AnhF4EwfWQvTA9xO+o +abw4m6SkltFi2mnAAZauy8RRNOoMqv8hjlmPSlzkYZqn0ukqeI1RPToV7qJZjqlc +3sX5kCLliEVx3ZGZbHqfPT2YfF72vhZooF6uCyP8Wg+qInYtyaEQHeTTRCOQiJ/G +KubX9ZqzWB4vMIkIG1SitZgj7Ah3HJVdYdHLiZxfokqRmu8hqkkWCKi9YSgxyXSt +hfbZxbGL0eUQMk1fiyA6PEkfM4VZDdvLCXVDaXP7a3F98N/ETH3Goy7IlXnLc6KO +Tk0k+17kBL5yG6YnLUlamXrXXAkgt3+UuU/xDRxeiEIbEbfnkduebPRq34wGmAOt +zCjvpUfzUwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB +BjAdBgNVHQ4EFgQUo5fW816iEOGrRZ88F2Q87gFwnMwwDQYJKoZIhvcNAQELBQAD +ggIBABj6W3X8PnrHX3fHyt/PX8MSxEBd1DKquGrX1RUVRpgjpeaQWxiZTOOtQqOC +MTaIzen7xASWSIsBx40Bz1szBpZGZnQdT+3Btrm0DWHMY37XLneMlhwqI2hrhVd2 +cDMT/uFPpiN3GPoajOi9ZcnPP/TJF9zrx7zABC4tRi9pZsMbj/7sPtPKlL92CiUN +qXsCHKnQO18LwIE6PWThv6ctTr1NxNgpxiIY0MWscgKCP6o6ojoilzHdCGPDdRS5 +YCgtW2jgFqlmgiNR9etT2DGbe+m3nUvriBbP+V04ikkwj+3x6xn0dxoxGE1nVGwv +b2X52z3sIexe9PSLymBlVNFxZPT5pqOBMzYzcfCkeF9OrYMh3jRJjehZrJ3ydlo2 +8hP0r+AJx2EqbPfgna67hkooby7utHnNkDPDs3b69fBsnQGQ+p6Q9pxyz0fawx/k +NSBT8lTR32GDpgLiJTjehTItXnOQUl1CxM49S+H5GYQd1aJQzEH7QRTDvdbJWqNj +ZgKAvQU6O0ec7AAmTPWIUb+oI38YB7AL7YsmoWTTYUrrXJ/es69nA7Mf3W1daWhp +q1467HxpvMc7hU6eFbm0FU/DlXpY18ls6Wy58yljXrQs8C097Vpl4KlbQMJImYFt +nh8GKjwStIsPm6Ik8KaN1nrgS7ZklmOVhMJKzRwuJIczYOXD +-----END CERTIFICATE----- + +# Issuer: CN=QuoVadis Root CA 2 G3 O=QuoVadis Limited +# Subject: CN=QuoVadis Root CA 2 G3 O=QuoVadis Limited +# Label: "QuoVadis Root CA 2 G3" +# Serial: 390156079458959257446133169266079962026824725800 +# MD5 Fingerprint: af:0c:86:6e:bf:40:2d:7f:0b:3e:12:50:ba:12:3d:06 +# SHA1 Fingerprint: 09:3c:61:f3:8b:8b:dc:7d:55:df:75:38:02:05:00:e1:25:f5:c8:36 +# SHA256 Fingerprint: 8f:e4:fb:0a:f9:3a:4d:0d:67:db:0b:eb:b2:3e:37:c7:1b:f3:25:dc:bc:dd:24:0e:a0:4d:af:58:b4:7e:18:40 +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIURFc0JFuBiZs18s64KztbpybwdSgwDQYJKoZIhvcNAQEL +BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc +BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMiBHMzAeFw0xMjAxMTIxODU5MzJaFw00 +MjAxMTIxODU5MzJaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM +aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDIgRzMwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQChriWyARjcV4g/Ruv5r+LrI3HimtFhZiFf +qq8nUeVuGxbULX1QsFN3vXg6YOJkApt8hpvWGo6t/x8Vf9WVHhLL5hSEBMHfNrMW +n4rjyduYNM7YMxcoRvynyfDStNVNCXJJ+fKH46nafaF9a7I6JaltUkSs+L5u+9ym +c5GQYaYDFCDy54ejiK2toIz/pgslUiXnFgHVy7g1gQyjO/Dh4fxaXc6AcW34Sas+ +O7q414AB+6XrW7PFXmAqMaCvN+ggOp+oMiwMzAkd056OXbxMmO7FGmh77FOm6RQ1 +o9/NgJ8MSPsc9PG/Srj61YxxSscfrf5BmrODXfKEVu+lV0POKa2Mq1W/xPtbAd0j +IaFYAI7D0GoT7RPjEiuA3GfmlbLNHiJuKvhB1PLKFAeNilUSxmn1uIZoL1NesNKq +IcGY5jDjZ1XHm26sGahVpkUG0CM62+tlXSoREfA7T8pt9DTEceT/AFr2XK4jYIVz +8eQQsSWu1ZK7E8EM4DnatDlXtas1qnIhO4M15zHfeiFuuDIIfR0ykRVKYnLP43eh +vNURG3YBZwjgQQvD6xVu+KQZ2aKrr+InUlYrAoosFCT5v0ICvybIxo/gbjh9Uy3l +7ZizlWNof/k19N+IxWA1ksB8aRxhlRbQ694Lrz4EEEVlWFA4r0jyWbYW8jwNkALG +cC4BrTwV1wIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB +BjAdBgNVHQ4EFgQU7edvdlq/YOxJW8ald7tyFnGbxD0wDQYJKoZIhvcNAQELBQAD +ggIBAJHfgD9DCX5xwvfrs4iP4VGyvD11+ShdyLyZm3tdquXK4Qr36LLTn91nMX66 +AarHakE7kNQIXLJgapDwyM4DYvmL7ftuKtwGTTwpD4kWilhMSA/ohGHqPHKmd+RC +roijQ1h5fq7KpVMNqT1wvSAZYaRsOPxDMuHBR//47PERIjKWnML2W2mWeyAMQ0Ga +W/ZZGYjeVYg3UQt4XAoeo0L9x52ID8DyeAIkVJOviYeIyUqAHerQbj5hLja7NQ4n +lv1mNDthcnPxFlxHBlRJAHpYErAK74X9sbgzdWqTHBLmYF5vHX/JHyPLhGGfHoJE ++V+tYlUkmlKY7VHnoX6XOuYvHxHaU4AshZ6rNRDbIl9qxV6XU/IyAgkwo1jwDQHV +csaxfGl7w/U2Rcxhbl5MlMVerugOXou/983g7aEOGzPuVBj+D77vfoRrQ+NwmNtd +dbINWQeFFSM51vHfqSYP1kjHs6Yi9TM3WpVHn3u6GBVv/9YUZINJ0gpnIdsPNWNg +KCLjsZWDzYWm3S8P52dSbrsvhXz1SnPnxT7AvSESBT/8twNJAlvIJebiVDj1eYeM +HVOyToV7BjjHLPj4sHKNJeV3UvQDHEimUF+IIDBu8oJDqz2XhOdT+yHBTw8imoa4 +WSr2Rz0ZiC3oheGe7IUIarFsNMkd7EgrO3jtZsSOeWmD3n+M +-----END CERTIFICATE----- + +# Issuer: CN=QuoVadis Root CA 3 G3 O=QuoVadis Limited +# Subject: CN=QuoVadis Root CA 3 G3 O=QuoVadis Limited +# Label: "QuoVadis Root CA 3 G3" +# Serial: 268090761170461462463995952157327242137089239581 +# MD5 Fingerprint: df:7d:b9:ad:54:6f:68:a1:df:89:57:03:97:43:b0:d7 +# SHA1 Fingerprint: 48:12:bd:92:3c:a8:c4:39:06:e7:30:6d:27:96:e6:a4:cf:22:2e:7d +# SHA256 Fingerprint: 88:ef:81:de:20:2e:b0:18:45:2e:43:f8:64:72:5c:ea:5f:bd:1f:c2:d9:d2:05:73:07:09:c5:d8:b8:69:0f:46 +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIULvWbAiin23r/1aOp7r0DoM8Sah0wDQYJKoZIhvcNAQEL +BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc +BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMyBHMzAeFw0xMjAxMTIyMDI2MzJaFw00 +MjAxMTIyMDI2MzJaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM +aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDMgRzMwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQCzyw4QZ47qFJenMioKVjZ/aEzHs286IxSR +/xl/pcqs7rN2nXrpixurazHb+gtTTK/FpRp5PIpM/6zfJd5O2YIyC0TeytuMrKNu +FoM7pmRLMon7FhY4futD4tN0SsJiCnMK3UmzV9KwCoWdcTzeo8vAMvMBOSBDGzXR +U7Ox7sWTaYI+FrUoRqHe6okJ7UO4BUaKhvVZR74bbwEhELn9qdIoyhA5CcoTNs+c +ra1AdHkrAj80//ogaX3T7mH1urPnMNA3I4ZyYUUpSFlob3emLoG+B01vr87ERROR +FHAGjx+f+IdpsQ7vw4kZ6+ocYfx6bIrc1gMLnia6Et3UVDmrJqMz6nWB2i3ND0/k +A9HvFZcba5DFApCTZgIhsUfei5pKgLlVj7WiL8DWM2fafsSntARE60f75li59wzw +eyuxwHApw0BiLTtIadwjPEjrewl5qW3aqDCYz4ByA4imW0aucnl8CAMhZa634Ryl +sSqiMd5mBPfAdOhx3v89WcyWJhKLhZVXGqtrdQtEPREoPHtht+KPZ0/l7DxMYIBp +VzgeAVuNVejH38DMdyM0SXV89pgR6y3e7UEuFAUCf+D+IOs15xGsIs5XPd7JMG0Q +A4XN8f+MFrXBsj6IbGB/kE+V9/YtrQE5BwT6dYB9v0lQ7e/JxHwc64B+27bQ3RP+ +ydOc17KXqQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB +BjAdBgNVHQ4EFgQUxhfQvKjqAkPyGwaZXSuQILnXnOQwDQYJKoZIhvcNAQELBQAD +ggIBADRh2Va1EodVTd2jNTFGu6QHcrxfYWLopfsLN7E8trP6KZ1/AvWkyaiTt3px +KGmPc+FSkNrVvjrlt3ZqVoAh313m6Tqe5T72omnHKgqwGEfcIHB9UqM+WXzBusnI +FUBhynLWcKzSt/Ac5IYp8M7vaGPQtSCKFWGafoaYtMnCdvvMujAWzKNhxnQT5Wvv +oxXqA/4Ti2Tk08HS6IT7SdEQTXlm66r99I0xHnAUrdzeZxNMgRVhvLfZkXdxGYFg +u/BYpbWcC/ePIlUnwEsBbTuZDdQdm2NnL9DuDcpmvJRPpq3t/O5jrFc/ZSXPsoaP +0Aj/uHYUbt7lJ+yreLVTubY/6CD50qi+YUbKh4yE8/nxoGibIh6BJpsQBJFxwAYf +3KDTuVan45gtf4Od34wrnDKOMpTwATwiKp9Dwi7DmDkHOHv8XgBCH/MyJnmDhPbl +8MFREsALHgQjDFSlTC9JxUrRtm5gDWv8a4uFJGS3iQ6rJUdbPM9+Sb3H6QrG2vd+ +DhcI00iX0HGS8A85PjRqHH3Y8iKuu2n0M7SmSFXRDw4m6Oy2Cy2nhTXN/VnIn9HN +PlopNLk9hM6xZdRZkZFWdSHBd575euFgndOtBBj0fOtek49TSiIp+EgrPk2GrFt/ +ywaZWWDYWGWVjUTR939+J399roD1B0y2PpxxVJkES/1Y+Zj0 +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert Assured ID Root G2 O=DigiCert Inc OU=www.digicert.com +# Subject: CN=DigiCert Assured ID Root G2 O=DigiCert Inc OU=www.digicert.com +# Label: "DigiCert Assured ID Root G2" +# Serial: 15385348160840213938643033620894905419 +# MD5 Fingerprint: 92:38:b9:f8:63:24:82:65:2c:57:33:e6:fe:81:8f:9d +# SHA1 Fingerprint: a1:4b:48:d9:43:ee:0a:0e:40:90:4f:3c:e0:a4:c0:91:93:51:5d:3f +# SHA256 Fingerprint: 7d:05:eb:b6:82:33:9f:8c:94:51:ee:09:4e:eb:fe:fa:79:53:a1:14:ed:b2:f4:49:49:45:2f:ab:7d:2f:c1:85 +-----BEGIN CERTIFICATE----- +MIIDljCCAn6gAwIBAgIQC5McOtY5Z+pnI7/Dr5r0SzANBgkqhkiG9w0BAQsFADBl +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv +b3QgRzIwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBlMQswCQYDVQQG +EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl +cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzIwggEi +MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDZ5ygvUj82ckmIkzTz+GoeMVSA +n61UQbVH35ao1K+ALbkKz3X9iaV9JPrjIgwrvJUXCzO/GU1BBpAAvQxNEP4Htecc +biJVMWWXvdMX0h5i89vqbFCMP4QMls+3ywPgym2hFEwbid3tALBSfK+RbLE4E9Hp +EgjAALAcKxHad3A2m67OeYfcgnDmCXRwVWmvo2ifv922ebPynXApVfSr/5Vh88lA +bx3RvpO704gqu52/clpWcTs/1PPRCv4o76Pu2ZmvA9OPYLfykqGxvYmJHzDNw6Yu +YjOuFgJ3RFrngQo8p0Quebg/BLxcoIfhG69Rjs3sLPr4/m3wOnyqi+RnlTGNAgMB +AAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQW +BBTOw0q5mVXyuNtgv6l+vVa1lzan1jANBgkqhkiG9w0BAQsFAAOCAQEAyqVVjOPI +QW5pJ6d1Ee88hjZv0p3GeDgdaZaikmkuOGybfQTUiaWxMTeKySHMq2zNixya1r9I +0jJmwYrA8y8678Dj1JGG0VDjA9tzd29KOVPt3ibHtX2vK0LRdWLjSisCx1BL4Gni +lmwORGYQRI+tBev4eaymG+g3NJ1TyWGqolKvSnAWhsI6yLETcDbYz+70CjTVW0z9 +B5yiutkBclzzTcHdDrEcDcRjvq30FPuJ7KJBDkzMyFdA0G4Dqs0MjomZmWzwPDCv +ON9vvKO+KSAnq3T/EyJ43pdSVR6DtVQgA+6uwE9W3jfMw3+qBCe703e4YtsXfJwo +IhNzbM8m9Yop5w== +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert Assured ID Root G3 O=DigiCert Inc OU=www.digicert.com +# Subject: CN=DigiCert Assured ID Root G3 O=DigiCert Inc OU=www.digicert.com +# Label: "DigiCert Assured ID Root G3" +# Serial: 15459312981008553731928384953135426796 +# MD5 Fingerprint: 7c:7f:65:31:0c:81:df:8d:ba:3e:99:e2:5c:ad:6e:fb +# SHA1 Fingerprint: f5:17:a2:4f:9a:48:c6:c9:f8:a2:00:26:9f:dc:0f:48:2c:ab:30:89 +# SHA256 Fingerprint: 7e:37:cb:8b:4c:47:09:0c:ab:36:55:1b:a6:f4:5d:b8:40:68:0f:ba:16:6a:95:2d:b1:00:71:7f:43:05:3f:c2 +-----BEGIN CERTIFICATE----- +MIICRjCCAc2gAwIBAgIQC6Fa+h3foLVJRK/NJKBs7DAKBggqhkjOPQQDAzBlMQsw +CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu +ZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3Qg +RzMwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBlMQswCQYDVQQGEwJV +UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQu +Y29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzMwdjAQBgcq +hkjOPQIBBgUrgQQAIgNiAAQZ57ysRGXtzbg/WPuNsVepRC0FFfLvC/8QdJ+1YlJf +Zn4f5dwbRXkLzMZTCp2NXQLZqVneAlr2lSoOjThKiknGvMYDOAdfVdp+CW7if17Q +RSAPWXYQ1qAk8C3eNvJsKTmjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/ +BAQDAgGGMB0GA1UdDgQWBBTL0L2p4ZgFUaFNN6KDec6NHSrkhDAKBggqhkjOPQQD +AwNnADBkAjAlpIFFAmsSS3V0T8gj43DydXLefInwz5FyYZ5eEJJZVrmDxxDnOOlY +JjZ91eQ0hjkCMHw2U/Aw5WJjOpnitqM7mzT6HtoQknFekROn3aRukswy1vUhZscv +6pZjamVFkpUBtA== +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert Global Root G2 O=DigiCert Inc OU=www.digicert.com +# Subject: CN=DigiCert Global Root G2 O=DigiCert Inc OU=www.digicert.com +# Label: "DigiCert Global Root G2" +# Serial: 4293743540046975378534879503202253541 +# MD5 Fingerprint: e4:a6:8a:c8:54:ac:52:42:46:0a:fd:72:48:1b:2a:44 +# SHA1 Fingerprint: df:3c:24:f9:bf:d6:66:76:1b:26:80:73:fe:06:d1:cc:8d:4f:82:a4 +# SHA256 Fingerprint: cb:3c:cb:b7:60:31:e5:e0:13:8f:8d:d3:9a:23:f9:de:47:ff:c3:5e:43:c1:14:4c:ea:27:d4:6a:5a:b1:cb:5f +-----BEGIN CERTIFICATE----- +MIIDjjCCAnagAwIBAgIQAzrx5qcRqaC7KGSxHQn65TANBgkqhkiG9w0BAQsFADBh +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBH +MjAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVT +MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j +b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEcyMIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzfNNNx7a8myaJCtSnX/RrohCgiN9RlUyfuI +2/Ou8jqJkTx65qsGGmvPrC3oXgkkRLpimn7Wo6h+4FR1IAWsULecYxpsMNzaHxmx +1x7e/dfgy5SDN67sH0NO3Xss0r0upS/kqbitOtSZpLYl6ZtrAGCSYP9PIUkY92eQ +q2EGnI/yuum06ZIya7XzV+hdG82MHauVBJVJ8zUtluNJbd134/tJS7SsVQepj5Wz +tCO7TG1F8PapspUwtP1MVYwnSlcUfIKdzXOS0xZKBgyMUNGPHgm+F6HmIcr9g+UQ +vIOlCsRnKPZzFBQ9RnbDhxSJITRNrw9FDKZJobq7nMWxM4MphQIDAQABo0IwQDAP +BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUTiJUIBiV +5uNu5g/6+rkS7QYXjzkwDQYJKoZIhvcNAQELBQADggEBAGBnKJRvDkhj6zHd6mcY +1Yl9PMWLSn/pvtsrF9+wX3N3KjITOYFnQoQj8kVnNeyIv/iPsGEMNKSuIEyExtv4 +NeF22d+mQrvHRAiGfzZ0JFrabA0UWTW98kndth/Jsw1HKj2ZL7tcu7XUIOGZX1NG +Fdtom/DzMNU+MeKNhJ7jitralj41E6Vf8PlwUHBHQRFXGU7Aj64GxJUTFy8bJZ91 +8rGOmaFvE7FBcf6IKshPECBV1/MUReXgRPTqh5Uykw7+U0b6LJ3/iyK5S9kJRaTe +pLiaWN0bfVKfjllDiIGknibVb63dDcY3fe0Dkhvld1927jyNxF1WW6LZZm6zNTfl +MrY= +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert Global Root G3 O=DigiCert Inc OU=www.digicert.com +# Subject: CN=DigiCert Global Root G3 O=DigiCert Inc OU=www.digicert.com +# Label: "DigiCert Global Root G3" +# Serial: 7089244469030293291760083333884364146 +# MD5 Fingerprint: f5:5d:a4:50:a5:fb:28:7e:1e:0f:0d:cc:96:57:56:ca +# SHA1 Fingerprint: 7e:04:de:89:6a:3e:66:6d:00:e6:87:d3:3f:fa:d9:3b:e8:3d:34:9e +# SHA256 Fingerprint: 31:ad:66:48:f8:10:41:38:c7:38:f3:9e:a4:32:01:33:39:3e:3a:18:cc:02:29:6e:f9:7c:2a:c9:ef:67:31:d0 +-----BEGIN CERTIFICATE----- +MIICPzCCAcWgAwIBAgIQBVVWvPJepDU1w6QP1atFcjAKBggqhkjOPQQDAzBhMQsw +CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu +ZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBHMzAe +Fw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVTMRUw +EwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20x +IDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEczMHYwEAYHKoZIzj0CAQYF +K4EEACIDYgAE3afZu4q4C/sLfyHS8L6+c/MzXRq8NOrexpu80JX28MzQC7phW1FG +fp4tn+6OYwwX7Adw9c+ELkCDnOg/QW07rdOkFFk2eJ0DQ+4QE2xy3q6Ip6FrtUPO +Z9wj/wMco+I+o0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAd +BgNVHQ4EFgQUs9tIpPmhxdiuNkHMEWNpYim8S8YwCgYIKoZIzj0EAwMDaAAwZQIx +AK288mw/EkrRLTnDCgmXc/SINoyIJ7vmiI1Qhadj+Z4y3maTD/HMsQmP3Wyr+mt/ +oAIwOWZbwmSNuJ5Q3KjVSaLtx9zRSX8XAbjIho9OjIgrqJqpisXRAL34VOKa5Vt8 +sycX +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert Trusted Root G4 O=DigiCert Inc OU=www.digicert.com +# Subject: CN=DigiCert Trusted Root G4 O=DigiCert Inc OU=www.digicert.com +# Label: "DigiCert Trusted Root G4" +# Serial: 7451500558977370777930084869016614236 +# MD5 Fingerprint: 78:f2:fc:aa:60:1f:2f:b4:eb:c9:37:ba:53:2e:75:49 +# SHA1 Fingerprint: dd:fb:16:cd:49:31:c9:73:a2:03:7d:3f:c8:3a:4d:7d:77:5d:05:e4 +# SHA256 Fingerprint: 55:2f:7b:dc:f1:a7:af:9e:6c:e6:72:01:7f:4f:12:ab:f7:72:40:c7:8e:76:1a:c2:03:d1:d9:d2:0a:c8:99:88 +-----BEGIN CERTIFICATE----- +MIIFkDCCA3igAwIBAgIQBZsbV56OITLiOQe9p3d1XDANBgkqhkiG9w0BAQwFADBi +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3Qg +RzQwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBiMQswCQYDVQQGEwJV +UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQu +Y29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQC/5pBzaN675F1KPDAiMGkz7MKnJS7JIT3y +ithZwuEppz1Yq3aaza57G4QNxDAf8xukOBbrVsaXbR2rsnnyyhHS5F/WBTxSD1If +xp4VpX6+n6lXFllVcq9ok3DCsrp1mWpzMpTREEQQLt+C8weE5nQ7bXHiLQwb7iDV +ySAdYyktzuxeTsiT+CFhmzTrBcZe7FsavOvJz82sNEBfsXpm7nfISKhmV1efVFiO +DCu3T6cw2Vbuyntd463JT17lNecxy9qTXtyOj4DatpGYQJB5w3jHtrHEtWoYOAMQ +jdjUN6QuBX2I9YI+EJFwq1WCQTLX2wRzKm6RAXwhTNS8rhsDdV14Ztk6MUSaM0C/ +CNdaSaTC5qmgZ92kJ7yhTzm1EVgX9yRcRo9k98FpiHaYdj1ZXUJ2h4mXaXpI8OCi +EhtmmnTK3kse5w5jrubU75KSOp493ADkRSWJtppEGSt+wJS00mFt6zPZxd9LBADM +fRyVw4/3IbKyEbe7f/LVjHAsQWCqsWMYRJUadmJ+9oCw++hkpjPRiQfhvbfmQ6QY +uKZ3AeEPlAwhHbJUKSWJbOUOUlFHdL4mrLZBdd56rF+NP8m800ERElvlEFDrMcXK +chYiCd98THU/Y+whX8QgUWtvsauGi0/C1kVfnSD8oR7FwI+isX4KJpn15GkvmB0t +9dmpsh3lGwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB +hjAdBgNVHQ4EFgQU7NfjgtJxXWRM3y5nP+e6mK4cD08wDQYJKoZIhvcNAQEMBQAD +ggIBALth2X2pbL4XxJEbw6GiAI3jZGgPVs93rnD5/ZpKmbnJeFwMDF/k5hQpVgs2 +SV1EY+CtnJYYZhsjDT156W1r1lT40jzBQ0CuHVD1UvyQO7uYmWlrx8GnqGikJ9yd ++SeuMIW59mdNOj6PWTkiU0TryF0Dyu1Qen1iIQqAyHNm0aAFYF/opbSnr6j3bTWc +fFqK1qI4mfN4i/RN0iAL3gTujJtHgXINwBQy7zBZLq7gcfJW5GqXb5JQbZaNaHqa +sjYUegbyJLkJEVDXCLG4iXqEI2FCKeWjzaIgQdfRnGTZ6iahixTXTBmyUEFxPT9N +cCOGDErcgdLMMpSEDQgJlxxPwO5rIHQw0uA5NBCFIRUBCOhVMt5xSdkoF1BN5r5N +0XWs0Mr7QbhDparTwwVETyw2m+L64kW4I1NsBm9nVX9GtUw/bihaeSbSpKhil9Ie +4u1Ki7wb/UdKDd9nZn6yW0HQO+T0O/QEY+nvwlQAUaCKKsnOeMzV6ocEGLPOr0mI +r/OSmbaz5mEP0oUA51Aa5BuVnRmhuZyxm7EAHu/QD09CbMkKvO5D+jpxpchNJqU1 +/YldvIViHTLSoCtU7ZpXwdv6EM8Zt4tKG48BtieVU+i2iW1bvGjUI+iLUaJW+fCm +gKDWHrO8Dw9TdSmq6hN35N6MgSGtBxBHEa2HPQfRdbzP82Z+ +-----END CERTIFICATE----- + +# Issuer: CN=COMODO RSA Certification Authority O=COMODO CA Limited +# Subject: CN=COMODO RSA Certification Authority O=COMODO CA Limited +# Label: "COMODO RSA Certification Authority" +# Serial: 101909084537582093308941363524873193117 +# MD5 Fingerprint: 1b:31:b0:71:40:36:cc:14:36:91:ad:c4:3e:fd:ec:18 +# SHA1 Fingerprint: af:e5:d2:44:a8:d1:19:42:30:ff:47:9f:e2:f8:97:bb:cd:7a:8c:b4 +# SHA256 Fingerprint: 52:f0:e1:c4:e5:8e:c6:29:29:1b:60:31:7f:07:46:71:b8:5d:7e:a8:0d:5b:07:27:34:63:53:4b:32:b4:02:34 +-----BEGIN CERTIFICATE----- +MIIF2DCCA8CgAwIBAgIQTKr5yttjb+Af907YWwOGnTANBgkqhkiG9w0BAQwFADCB +hTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G +A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNV +BAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAwMTE5 +MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgT +EkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMR +Q09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNh +dGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCR +6FSS0gpWsawNJN3Fz0RndJkrN6N9I3AAcbxT38T6KhKPS38QVr2fcHK3YX/JSw8X +pz3jsARh7v8Rl8f0hj4K+j5c+ZPmNHrZFGvnnLOFoIJ6dq9xkNfs/Q36nGz637CC +9BR++b7Epi9Pf5l/tfxnQ3K9DADWietrLNPtj5gcFKt+5eNu/Nio5JIk2kNrYrhV +/erBvGy2i/MOjZrkm2xpmfh4SDBF1a3hDTxFYPwyllEnvGfDyi62a+pGx8cgoLEf +Zd5ICLqkTqnyg0Y3hOvozIFIQ2dOciqbXL1MGyiKXCJ7tKuY2e7gUYPDCUZObT6Z ++pUX2nwzV0E8jVHtC7ZcryxjGt9XyD+86V3Em69FmeKjWiS0uqlWPc9vqv9JWL7w +qP/0uK3pN/u6uPQLOvnoQ0IeidiEyxPx2bvhiWC4jChWrBQdnArncevPDt09qZah +SL0896+1DSJMwBGB7FY79tOi4lu3sgQiUpWAk2nojkxl8ZEDLXB0AuqLZxUpaVIC +u9ffUGpVRr+goyhhf3DQw6KqLCGqR84onAZFdr+CGCe01a60y1Dma/RMhnEw6abf +Fobg2P9A3fvQQoh/ozM6LlweQRGBY84YcWsr7KaKtzFcOmpH4MN5WdYgGq/yapiq +crxXStJLnbsQ/LBMQeXtHT1eKJ2czL+zUdqnR+WEUwIDAQABo0IwQDAdBgNVHQ4E +FgQUu69+Aj36pvE8hI6t7jiY7NkyMtQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB +/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAArx1UaEt65Ru2yyTUEUAJNMnMvl +wFTPoCWOAvn9sKIN9SCYPBMtrFaisNZ+EZLpLrqeLppysb0ZRGxhNaKatBYSaVqM +4dc+pBroLwP0rmEdEBsqpIt6xf4FpuHA1sj+nq6PK7o9mfjYcwlYRm6mnPTXJ9OV +2jeDchzTc+CiR5kDOF3VSXkAKRzH7JsgHAckaVd4sjn8OoSgtZx8jb8uk2Intzna +FxiuvTwJaP+EmzzV1gsD41eeFPfR60/IvYcjt7ZJQ3mFXLrrkguhxuhoqEwWsRqZ +CuhTLJK7oQkYdQxlqHvLI7cawiiFwxv/0Cti76R7CZGYZ4wUAc1oBmpjIXUDgIiK +boHGhfKppC3n9KUkEEeDys30jXlYsQab5xoq2Z0B15R97QNKyvDb6KkBPvVWmcke +jkk9u+UJueBPSZI9FoJAzMxZxuY67RIuaTxslbH9qh17f4a+Hg4yRvv7E491f0yL +S0Zj/gA0QHDBw7mh3aZw4gSzQbzpgJHqZJx64SIDqZxubw5lT2yHh17zbqD5daWb +QOhTsiedSrnAdyGN/4fy3ryM7xfft0kL0fJuMAsaDk527RH89elWsn2/x20Kk4yl +0MC2Hb46TpSi125sC8KKfPog88Tk5c0NqMuRkrF8hey1FGlmDoLnzc7ILaZRfyHB +NVOFBkpdn627G190 +-----END CERTIFICATE----- + +# Issuer: CN=USERTrust RSA Certification Authority O=The USERTRUST Network +# Subject: CN=USERTrust RSA Certification Authority O=The USERTRUST Network +# Label: "USERTrust RSA Certification Authority" +# Serial: 2645093764781058787591871645665788717 +# MD5 Fingerprint: 1b:fe:69:d1:91:b7:19:33:a3:72:a8:0f:e1:55:e5:b5 +# SHA1 Fingerprint: 2b:8f:1b:57:33:0d:bb:a2:d0:7a:6c:51:f7:0e:e9:0d:da:b9:ad:8e +# SHA256 Fingerprint: e7:93:c9:b0:2f:d8:aa:13:e2:1c:31:22:8a:cc:b0:81:19:64:3b:74:9c:89:89:64:b1:74:6d:46:c3:d4:cb:d2 +-----BEGIN CERTIFICATE----- +MIIF3jCCA8agAwIBAgIQAf1tMPyjylGoG7xkDjUDLTANBgkqhkiG9w0BAQwFADCB +iDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0pl +cnNleSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNV +BAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAw +MjAxMDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNV +BAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVU +aGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBSU0EgQ2Vy +dGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK +AoICAQCAEmUXNg7D2wiz0KxXDXbtzSfTTK1Qg2HiqiBNCS1kCdzOiZ/MPans9s/B +3PHTsdZ7NygRK0faOca8Ohm0X6a9fZ2jY0K2dvKpOyuR+OJv0OwWIJAJPuLodMkY +tJHUYmTbf6MG8YgYapAiPLz+E/CHFHv25B+O1ORRxhFnRghRy4YUVD+8M/5+bJz/ +Fp0YvVGONaanZshyZ9shZrHUm3gDwFA66Mzw3LyeTP6vBZY1H1dat//O+T23LLb2 +VN3I5xI6Ta5MirdcmrS3ID3KfyI0rn47aGYBROcBTkZTmzNg95S+UzeQc0PzMsNT +79uq/nROacdrjGCT3sTHDN/hMq7MkztReJVni+49Vv4M0GkPGw/zJSZrM233bkf6 +c0Plfg6lZrEpfDKEY1WJxA3Bk1QwGROs0303p+tdOmw1XNtB1xLaqUkL39iAigmT +Yo61Zs8liM2EuLE/pDkP2QKe6xJMlXzzawWpXhaDzLhn4ugTncxbgtNMs+1b/97l +c6wjOy0AvzVVdAlJ2ElYGn+SNuZRkg7zJn0cTRe8yexDJtC/QV9AqURE9JnnV4ee +UB9XVKg+/XRjL7FQZQnmWEIuQxpMtPAlR1n6BB6T1CZGSlCBst6+eLf8ZxXhyVeE +Hg9j1uliutZfVS7qXMYoCAQlObgOK6nyTJccBz8NUvXt7y+CDwIDAQABo0IwQDAd +BgNVHQ4EFgQUU3m/WqorSs9UgOHYm8Cd8rIDZsswDgYDVR0PAQH/BAQDAgEGMA8G +A1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAFzUfA3P9wF9QZllDHPF +Up/L+M+ZBn8b2kMVn54CVVeWFPFSPCeHlCjtHzoBN6J2/FNQwISbxmtOuowhT6KO +VWKR82kV2LyI48SqC/3vqOlLVSoGIG1VeCkZ7l8wXEskEVX/JJpuXior7gtNn3/3 +ATiUFJVDBwn7YKnuHKsSjKCaXqeYalltiz8I+8jRRa8YFWSQEg9zKC7F4iRO/Fjs +8PRF/iKz6y+O0tlFYQXBl2+odnKPi4w2r78NBc5xjeambx9spnFixdjQg3IM8WcR +iQycE0xyNN+81XHfqnHd4blsjDwSXWXavVcStkNr/+XeTWYRUc+ZruwXtuhxkYze +Sf7dNXGiFSeUHM9h4ya7b6NnJSFd5t0dCy5oGzuCr+yDZ4XUmFF0sbmZgIn/f3gZ +XHlKYC6SQK5MNyosycdiyA5d9zZbyuAlJQG03RoHnHcAP9Dc1ew91Pq7P8yF1m9/ +qS3fuQL39ZeatTXaw2ewh0qpKJ4jjv9cJ2vhsE/zB+4ALtRZh8tSQZXq9EfX7mRB +VXyNWQKV3WKdwrnuWih0hKWbt5DHDAff9Yk2dDLWKMGwsAvgnEzDHNb842m1R0aB +L6KCq9NjRHDEjf8tM7qtj3u1cIiuPhnPQCjY/MiQu12ZIvVS5ljFH4gxQ+6IHdfG +jjxDah2nGN59PRbxYvnKkKj9 +-----END CERTIFICATE----- + +# Issuer: CN=USERTrust ECC Certification Authority O=The USERTRUST Network +# Subject: CN=USERTrust ECC Certification Authority O=The USERTRUST Network +# Label: "USERTrust ECC Certification Authority" +# Serial: 123013823720199481456569720443997572134 +# MD5 Fingerprint: fa:68:bc:d9:b5:7f:ad:fd:c9:1d:06:83:28:cc:24:c1 +# SHA1 Fingerprint: d1:cb:ca:5d:b2:d5:2a:7f:69:3b:67:4d:e5:f0:5a:1d:0c:95:7d:f0 +# SHA256 Fingerprint: 4f:f4:60:d5:4b:9c:86:da:bf:bc:fc:57:12:e0:40:0d:2b:ed:3f:bc:4d:4f:bd:aa:86:e0:6a:dc:d2:a9:ad:7a +-----BEGIN CERTIFICATE----- +MIICjzCCAhWgAwIBAgIQXIuZxVqUxdJxVt7NiYDMJjAKBggqhkjOPQQDAzCBiDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNl +eSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMT +JVVTRVJUcnVzdCBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAwMjAx +MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNVBAgT +Ck5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVUaGUg +VVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBFQ0MgQ2VydGlm +aWNhdGlvbiBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQarFRaqflo +I+d61SRvU8Za2EurxtW20eZzca7dnNYMYf3boIkDuAUU7FfO7l0/4iGzzvfUinng +o4N+LZfQYcTxmdwlkWOrfzCjtHDix6EznPO/LlxTsV+zfTJ/ijTjeXmjQjBAMB0G +A1UdDgQWBBQ64QmG1M8ZwpZ2dEl23OA1xmNjmjAOBgNVHQ8BAf8EBAMCAQYwDwYD +VR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjA2Z6EWCNzklwBBHU6+4WMB +zzuqQhFkoJ2UOQIReVx7Hfpkue4WQrO/isIJxOzksU0CMQDpKmFHjFJKS04YcPbW +RNZu9YO6bVi9JNlWSOrvxKJGgYhqOkbRqZtNyWHa0V1Xahg= +-----END CERTIFICATE----- + +# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R4 +# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R4 +# Label: "GlobalSign ECC Root CA - R4" +# Serial: 14367148294922964480859022125800977897474 +# MD5 Fingerprint: 20:f0:27:68:d1:7e:a0:9d:0e:e6:2a:ca:df:5c:89:8e +# SHA1 Fingerprint: 69:69:56:2e:40:80:f4:24:a1:e7:19:9f:14:ba:f3:ee:58:ab:6a:bb +# SHA256 Fingerprint: be:c9:49:11:c2:95:56:76:db:6c:0a:55:09:86:d7:6e:3b:a0:05:66:7c:44:2c:97:62:b4:fb:b7:73:de:22:8c +-----BEGIN CERTIFICATE----- +MIIB4TCCAYegAwIBAgIRKjikHJYKBN5CsiilC+g0mAIwCgYIKoZIzj0EAwIwUDEk +MCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI0MRMwEQYDVQQKEwpH +bG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoX +DTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBD +QSAtIFI0MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu +MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEuMZ5049sJQ6fLjkZHAOkrprlOQcJ +FspjsbmG+IpXwVfOQvpzofdlQv8ewQCybnMO/8ch5RikqtlxP6jUuc6MHaNCMEAw +DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFFSwe61F +uOJAf/sKbvu+M8k8o4TVMAoGCCqGSM49BAMCA0gAMEUCIQDckqGgE6bPA7DmxCGX +kPoUVy0D7O48027KqGx2vKLeuwIgJ6iFJzWbVsaj8kfSt24bAgAXqmemFZHe+pTs +ewv4n4Q= +-----END CERTIFICATE----- + +# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R5 +# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R5 +# Label: "GlobalSign ECC Root CA - R5" +# Serial: 32785792099990507226680698011560947931244 +# MD5 Fingerprint: 9f:ad:3b:1c:02:1e:8a:ba:17:74:38:81:0c:a2:bc:08 +# SHA1 Fingerprint: 1f:24:c6:30:cd:a4:18:ef:20:69:ff:ad:4f:dd:5f:46:3a:1b:69:aa +# SHA256 Fingerprint: 17:9f:bc:14:8a:3d:d0:0f:d2:4e:a1:34:58:cc:43:bf:a7:f5:9c:81:82:d7:83:a5:13:f6:eb:ec:10:0c:89:24 +-----BEGIN CERTIFICATE----- +MIICHjCCAaSgAwIBAgIRYFlJ4CYuu1X5CneKcflK2GwwCgYIKoZIzj0EAwMwUDEk +MCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI1MRMwEQYDVQQKEwpH +bG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoX +DTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBD +QSAtIFI1MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu +MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAER0UOlvt9Xb/pOdEh+J8LttV7HpI6SFkc +8GIxLcB6KP4ap1yztsyX50XUWPrRd21DosCHZTQKH3rd6zwzocWdTaRvQZU4f8ke +hOvRnkmSh5SHDDqFSmafnVmTTZdhBoZKo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYD +VR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUPeYpSJvqB8ohREom3m7e0oPQn1kwCgYI +KoZIzj0EAwMDaAAwZQIxAOVpEslu28YxuglB4Zf4+/2a4n0Sye18ZNPLBSWLVtmg +515dTguDnFt2KaAJJiFqYgIwcdK1j1zqO+F4CYWodZI7yFz9SO8NdCKoCOJuxUnO +xwy8p2Fp8fc74SrL+SvzZpA3 +-----END CERTIFICATE----- + +# Issuer: CN=Staat der Nederlanden Root CA - G3 O=Staat der Nederlanden +# Subject: CN=Staat der Nederlanden Root CA - G3 O=Staat der Nederlanden +# Label: "Staat der Nederlanden Root CA - G3" +# Serial: 10003001 +# MD5 Fingerprint: 0b:46:67:07:db:10:2f:19:8c:35:50:60:d1:0b:f4:37 +# SHA1 Fingerprint: d8:eb:6b:41:51:92:59:e0:f3:e7:85:00:c0:3d:b6:88:97:c9:ee:fc +# SHA256 Fingerprint: 3c:4f:b0:b9:5a:b8:b3:00:32:f4:32:b8:6f:53:5f:e1:72:c1:85:d0:fd:39:86:58:37:cf:36:18:7f:a6:f4:28 +-----BEGIN CERTIFICATE----- +MIIFdDCCA1ygAwIBAgIEAJiiOTANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJO +TDEeMBwGA1UECgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSswKQYDVQQDDCJTdGFh +dCBkZXIgTmVkZXJsYW5kZW4gUm9vdCBDQSAtIEczMB4XDTEzMTExNDExMjg0MloX +DTI4MTExMzIzMDAwMFowWjELMAkGA1UEBhMCTkwxHjAcBgNVBAoMFVN0YWF0IGRl +ciBOZWRlcmxhbmRlbjErMCkGA1UEAwwiU3RhYXQgZGVyIE5lZGVybGFuZGVuIFJv +b3QgQ0EgLSBHMzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAL4yolQP +cPssXFnrbMSkUeiFKrPMSjTysF/zDsccPVMeiAho2G89rcKezIJnByeHaHE6n3WW +IkYFsO2tx1ueKt6c/DrGlaf1F2cY5y9JCAxcz+bMNO14+1Cx3Gsy8KL+tjzk7FqX +xz8ecAgwoNzFs21v0IJyEavSgWhZghe3eJJg+szeP4TrjTgzkApyI/o1zCZxMdFy +KJLZWyNtZrVtB0LrpjPOktvA9mxjeM3KTj215VKb8b475lRgsGYeCasH/lSJEULR +9yS6YHgamPfJEf0WwTUaVHXvQ9Plrk7O53vDxk5hUUurmkVLoR9BvUhTFXFkC4az +5S6+zqQbwSmEorXLCCN2QyIkHxcE1G6cxvx/K2Ya7Irl1s9N9WMJtxU51nus6+N8 +6U78dULI7ViVDAZCopz35HCz33JvWjdAidiFpNfxC95DGdRKWCyMijmev4SH8RY7 +Ngzp07TKbBlBUgmhHbBqv4LvcFEhMtwFdozL92TkA1CvjJFnq8Xy7ljY3r735zHP +bMk7ccHViLVlvMDoFxcHErVc0qsgk7TmgoNwNsXNo42ti+yjwUOH5kPiNL6VizXt +BznaqB16nzaeErAMZRKQFWDZJkBE41ZgpRDUajz9QdwOWke275dhdU/Z/seyHdTt +XUmzqWrLZoQT1Vyg3N9udwbRcXXIV2+vD3dbAgMBAAGjQjBAMA8GA1UdEwEB/wQF +MAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRUrfrHkleuyjWcLhL75Lpd +INyUVzANBgkqhkiG9w0BAQsFAAOCAgEAMJmdBTLIXg47mAE6iqTnB/d6+Oea31BD +U5cqPco8R5gu4RV78ZLzYdqQJRZlwJ9UXQ4DO1t3ApyEtg2YXzTdO2PCwyiBwpwp +LiniyMMB8jPqKqrMCQj3ZWfGzd/TtiunvczRDnBfuCPRy5FOCvTIeuXZYzbB1N/8 +Ipf3YF3qKS9Ysr1YvY2WTxB1v0h7PVGHoTx0IsL8B3+A3MSs/mrBcDCw6Y5p4ixp +gZQJut3+TcCDjJRYwEYgr5wfAvg1VUkvRtTA8KCWAg8zxXHzniN9lLf9OtMJgwYh +/WA9rjLA0u6NpvDntIJ8CsxwyXmA+P5M9zWEGYox+wrZ13+b8KKaa8MFSu1BYBQw +0aoRQm7TIwIEC8Zl3d1Sd9qBa7Ko+gE4uZbqKmxnl4mUnrzhVNXkanjvSr0rmj1A +fsbAddJu+2gw7OyLnflJNZoaLNmzlTnVHpL3prllL+U9bTpITAjc5CgSKL59NVzq +4BZ+Extq1z7XnvwtdbLBFNUjA9tbbws+eC8N3jONFrdI54OagQ97wUNNVQQXOEpR +1VmiiXTTn74eS9fGbbeIJG9gkaSChVtWQbzQRKtqE77RLFi3EjNYsjdj3BP1lB0/ +QFH1T/U67cjF68IeHRaVesd+QnGTbksVtzDfqu1XhUisHWrdOWnk4Xl4vs4Fv6EM +94B7IWcnMFk= +-----END CERTIFICATE----- + +# Issuer: CN=Staat der Nederlanden EV Root CA O=Staat der Nederlanden +# Subject: CN=Staat der Nederlanden EV Root CA O=Staat der Nederlanden +# Label: "Staat der Nederlanden EV Root CA" +# Serial: 10000013 +# MD5 Fingerprint: fc:06:af:7b:e8:1a:f1:9a:b4:e8:d2:70:1f:c0:f5:ba +# SHA1 Fingerprint: 76:e2:7e:c1:4f:db:82:c1:c0:a6:75:b5:05:be:3d:29:b4:ed:db:bb +# SHA256 Fingerprint: 4d:24:91:41:4c:fe:95:67:46:ec:4c:ef:a6:cf:6f:72:e2:8a:13:29:43:2f:9d:8a:90:7a:c4:cb:5d:ad:c1:5a +-----BEGIN CERTIFICATE----- +MIIFcDCCA1igAwIBAgIEAJiWjTANBgkqhkiG9w0BAQsFADBYMQswCQYDVQQGEwJO +TDEeMBwGA1UECgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSkwJwYDVQQDDCBTdGFh +dCBkZXIgTmVkZXJsYW5kZW4gRVYgUm9vdCBDQTAeFw0xMDEyMDgxMTE5MjlaFw0y +MjEyMDgxMTEwMjhaMFgxCzAJBgNVBAYTAk5MMR4wHAYDVQQKDBVTdGFhdCBkZXIg +TmVkZXJsYW5kZW4xKTAnBgNVBAMMIFN0YWF0IGRlciBOZWRlcmxhbmRlbiBFViBS +b290IENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA48d+ifkkSzrS +M4M1LGns3Amk41GoJSt5uAg94JG6hIXGhaTK5skuU6TJJB79VWZxXSzFYGgEt9nC +UiY4iKTWO0Cmws0/zZiTs1QUWJZV1VD+hq2kY39ch/aO5ieSZxeSAgMs3NZmdO3d +Z//BYY1jTw+bbRcwJu+r0h8QoPnFfxZpgQNH7R5ojXKhTbImxrpsX23Wr9GxE46p +rfNeaXUmGD5BKyF/7otdBwadQ8QpCiv8Kj6GyzyDOvnJDdrFmeK8eEEzduG/L13l +pJhQDBXd4Pqcfzho0LKmeqfRMb1+ilgnQ7O6M5HTp5gVXJrm0w912fxBmJc+qiXb +j5IusHsMX/FjqTf5m3VpTCgmJdrV8hJwRVXj33NeN/UhbJCONVrJ0yPr08C+eKxC +KFhmpUZtcALXEPlLVPxdhkqHz3/KRawRWrUgUY0viEeXOcDPusBCAUCZSCELa6fS +/ZbV0b5GnUngC6agIk440ME8MLxwjyx1zNDFjFE7PZQIZCZhfbnDZY8UnCHQqv0X +cgOPvZuM5l5Tnrmd74K74bzickFbIZTTRTeU0d8JOV3nI6qaHcptqAqGhYqCvkIH +1vI4gnPah1vlPNOePqc7nvQDs/nxfRN0Av+7oeX6AHkcpmZBiFxgV6YuCcS6/ZrP +px9Aw7vMWgpVSzs4dlG4Y4uElBbmVvMCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB +/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFP6rAJCYniT8qcwaivsnuL8wbqg7 +MA0GCSqGSIb3DQEBCwUAA4ICAQDPdyxuVr5Os7aEAJSrR8kN0nbHhp8dB9O2tLsI +eK9p0gtJ3jPFrK3CiAJ9Brc1AsFgyb/E6JTe1NOpEyVa/m6irn0F3H3zbPB+po3u +2dfOWBfoqSmuc0iH55vKbimhZF8ZE/euBhD/UcabTVUlT5OZEAFTdfETzsemQUHS +v4ilf0X8rLiltTMMgsT7B/Zq5SWEXwbKwYY5EdtYzXc7LMJMD16a4/CrPmEbUCTC +wPTxGfARKbalGAKb12NMcIxHowNDXLldRqANb/9Zjr7dn3LDWyvfjFvO5QxGbJKy +CqNMVEIYFRIYvdr8unRu/8G2oGTYqV9Vrp9canaW2HNnh/tNf1zuacpzEPuKqf2e +vTY4SUmH9A4U8OmHuD+nT3pajnnUk+S7aFKErGzp85hwVXIy+TSrK0m1zSBi5Dp6 +Z2Orltxtrpfs/J92VoguZs9btsmksNcFuuEnL5O7Jiqik7Ab846+HUCjuTaPPoIa +Gl6I6lD4WeKDRikL40Rc4ZW2aZCaFG+XroHPaO+Zmr615+F/+PoTRxZMzG0IQOeL +eG9QgkRQP2YGiqtDhFZKDyAthg710tvSeopLzaXoTvFeJiUBWSOgftL2fiFX1ye8 +FVdMpEbB4IMeDExNH08GGeL5qPQ6gqGyeUN51q1veieQA6TqJIc/2b3Z6fJfUEkc +7uzXLg== +-----END CERTIFICATE----- + +# Issuer: CN=IdenTrust Commercial Root CA 1 O=IdenTrust +# Subject: CN=IdenTrust Commercial Root CA 1 O=IdenTrust +# Label: "IdenTrust Commercial Root CA 1" +# Serial: 13298821034946342390520003877796839426 +# MD5 Fingerprint: b3:3e:77:73:75:ee:a0:d3:e3:7e:49:63:49:59:bb:c7 +# SHA1 Fingerprint: df:71:7e:aa:4a:d9:4e:c9:55:84:99:60:2d:48:de:5f:bc:f0:3a:25 +# SHA256 Fingerprint: 5d:56:49:9b:e4:d2:e0:8b:cf:ca:d0:8a:3e:38:72:3d:50:50:3b:de:70:69:48:e4:2f:55:60:30:19:e5:28:ae +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIQCgFCgAAAAUUjyES1AAAAAjANBgkqhkiG9w0BAQsFADBK +MQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MScwJQYDVQQDEx5JZGVu +VHJ1c3QgQ29tbWVyY2lhbCBSb290IENBIDEwHhcNMTQwMTE2MTgxMjIzWhcNMzQw +MTE2MTgxMjIzWjBKMQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MScw +JQYDVQQDEx5JZGVuVHJ1c3QgQ29tbWVyY2lhbCBSb290IENBIDEwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQCnUBneP5k91DNG8W9RYYKyqU+PZ4ldhNlT +3Qwo2dfw/66VQ3KZ+bVdfIrBQuExUHTRgQ18zZshq0PirK1ehm7zCYofWjK9ouuU ++ehcCuz/mNKvcbO0U59Oh++SvL3sTzIwiEsXXlfEU8L2ApeN2WIrvyQfYo3fw7gp +S0l4PJNgiCL8mdo2yMKi1CxUAGc1bnO/AljwpN3lsKImesrgNqUZFvX9t++uP0D1 +bVoE/c40yiTcdCMbXTMTEl3EASX2MN0CXZ/g1Ue9tOsbobtJSdifWwLziuQkkORi +T0/Br4sOdBeo0XKIanoBScy0RnnGF7HamB4HWfp1IYVl3ZBWzvurpWCdxJ35UrCL +vYf5jysjCiN2O/cz4ckA82n5S6LgTrx+kzmEB/dEcH7+B1rlsazRGMzyNeVJSQjK +Vsk9+w8YfYs7wRPCTY/JTw436R+hDmrfYi7LNQZReSzIJTj0+kuniVyc0uMNOYZK +dHzVWYfCP04MXFL0PfdSgvHqo6z9STQaKPNBiDoT7uje/5kdX7rL6B7yuVBgwDHT +c+XvvqDtMwt0viAgxGds8AgDelWAf0ZOlqf0Hj7h9tgJ4TNkK2PXMl6f+cB7D3hv +l7yTmvmcEpB4eoCHFddydJxVdHixuuFucAS6T6C6aMN7/zHwcz09lCqxC0EOoP5N +iGVreTO01wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB +/zAdBgNVHQ4EFgQU7UQZwNPwBovupHu+QucmVMiONnYwDQYJKoZIhvcNAQELBQAD +ggIBAA2ukDL2pkt8RHYZYR4nKM1eVO8lvOMIkPkp165oCOGUAFjvLi5+U1KMtlwH +6oi6mYtQlNeCgN9hCQCTrQ0U5s7B8jeUeLBfnLOic7iPBZM4zY0+sLj7wM+x8uwt +LRvM7Kqas6pgghstO8OEPVeKlh6cdbjTMM1gCIOQ045U8U1mwF10A0Cj7oV+wh93 +nAbowacYXVKV7cndJZ5t+qntozo00Fl72u1Q8zW/7esUTTHHYPTa8Yec4kjixsU3 ++wYQ+nVZZjFHKdp2mhzpgq7vmrlR94gjmmmVYjzlVYA211QC//G5Xc7UI2/YRYRK +W2XviQzdFKcgyxilJbQN+QHwotL0AMh0jqEqSI5l2xPE4iUXfeu+h1sXIFRRk0pT +AwvsXcoz7WL9RccvW9xYoIA55vrX/hMUpu09lEpCdNTDd1lzzY9GvlU47/rokTLq +l1gEIt44w8y8bckzOmoKaT+gyOpyj4xjhiO9bTyWnpXgSUyqorkqG5w2gXjtw+hG +4iZZRHUe2XWJUc0QhJ1hYMtd+ZciTY6Y5uN/9lu7rs3KSoFrXgvzUeF0K+l+J6fZ +mUlO+KWA2yUPHGNiiskzZ2s8EIPGrd6ozRaOjfAHN3Gf8qv8QfXBi+wAN10J5U6A +7/qxXDgGpRtK4dw4LTzcqx+QGtVKnO7RcGzM7vRX+Bi6hG6H +-----END CERTIFICATE----- + +# Issuer: CN=IdenTrust Public Sector Root CA 1 O=IdenTrust +# Subject: CN=IdenTrust Public Sector Root CA 1 O=IdenTrust +# Label: "IdenTrust Public Sector Root CA 1" +# Serial: 13298821034946342390521976156843933698 +# MD5 Fingerprint: 37:06:a5:b0:fc:89:9d:ba:f4:6b:8c:1a:64:cd:d5:ba +# SHA1 Fingerprint: ba:29:41:60:77:98:3f:f4:f3:ef:f2:31:05:3b:2e:ea:6d:4d:45:fd +# SHA256 Fingerprint: 30:d0:89:5a:9a:44:8a:26:20:91:63:55:22:d1:f5:20:10:b5:86:7a:ca:e1:2c:78:ef:95:8f:d4:f4:38:9f:2f +-----BEGIN CERTIFICATE----- +MIIFZjCCA06gAwIBAgIQCgFCgAAAAUUjz0Z8AAAAAjANBgkqhkiG9w0BAQsFADBN +MQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MSowKAYDVQQDEyFJZGVu +VHJ1c3QgUHVibGljIFNlY3RvciBSb290IENBIDEwHhcNMTQwMTE2MTc1MzMyWhcN +MzQwMTE2MTc1MzMyWjBNMQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0 +MSowKAYDVQQDEyFJZGVuVHJ1c3QgUHVibGljIFNlY3RvciBSb290IENBIDEwggIi +MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2IpT8pEiv6EdrCvsnduTyP4o7 +ekosMSqMjbCpwzFrqHd2hCa2rIFCDQjrVVi7evi8ZX3yoG2LqEfpYnYeEe4IFNGy +RBb06tD6Hi9e28tzQa68ALBKK0CyrOE7S8ItneShm+waOh7wCLPQ5CQ1B5+ctMlS +bdsHyo+1W/CD80/HLaXIrcuVIKQxKFdYWuSNG5qrng0M8gozOSI5Cpcu81N3uURF +/YTLNiCBWS2ab21ISGHKTN9T0a9SvESfqy9rg3LvdYDaBjMbXcjaY8ZNzaxmMc3R +3j6HEDbhuaR672BQssvKplbgN6+rNBM5Jeg5ZuSYeqoSmJxZZoY+rfGwyj4GD3vw +EUs3oERte8uojHH01bWRNszwFcYr3lEXsZdMUD2xlVl8BX0tIdUAvwFnol57plzy +9yLxkA2T26pEUWbMfXYD62qoKjgZl3YNa4ph+bz27nb9cCvdKTz4Ch5bQhyLVi9V +GxyhLrXHFub4qjySjmm2AcG1hp2JDws4lFTo6tyePSW8Uybt1as5qsVATFSrsrTZ +2fjXctscvG29ZV/viDUqZi/u9rNl8DONfJhBaUYPQxxp+pu10GFqzcpL2UyQRqsV +WaFHVCkugyhfHMKiq3IXAAaOReyL4jM9f9oZRORicsPfIsbyVtTdX5Vy7W1f90gD +W/3FKqD2cyOEEBsB5wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/ +BAUwAwEB/zAdBgNVHQ4EFgQU43HgntinQtnbcZFrlJPrw6PRFKMwDQYJKoZIhvcN +AQELBQADggIBAEf63QqwEZE4rU1d9+UOl1QZgkiHVIyqZJnYWv6IAcVYpZmxI1Qj +t2odIFflAWJBF9MJ23XLblSQdf4an4EKwt3X9wnQW3IV5B4Jaj0z8yGa5hV+rVHV +DRDtfULAj+7AmgjVQdZcDiFpboBhDhXAuM/FSRJSzL46zNQuOAXeNf0fb7iAaJg9 +TaDKQGXSc3z1i9kKlT/YPyNtGtEqJBnZhbMX73huqVjRI9PHE+1yJX9dsXNw0H8G +lwmEKYBhHfpe/3OsoOOJuBxxFcbeMX8S3OFtm6/n6J91eEyrRjuazr8FGF1NFTwW +mhlQBJqymm9li1JfPFgEKCXAZmExfrngdbkaqIHWchezxQMxNRF4eKLg6TCMf4Df +WN88uieW4oA0beOY02QnrEh+KHdcxiVhJfiFDGX6xDIvpZgF5PgLZxYWxoK4Mhn5 ++bl53B/N66+rDt0b20XkeucC4pVd/GnwU2lhlXV5C15V5jgclKlZM57IcXR5f1GJ +tshquDDIajjDbp7hNxbqBWJMWxJH7ae0s1hWx0nzfxJoCTFx8G34Tkf71oXuxVhA +GaQdp/lLQzfcaFpPz+vCZHTetBXZ9FRUGi8c15dxVJCO2SCdUyt/q4/i6jC8UDfv +8Ue1fXwsBOxonbRJRBD0ckscZOf85muQ3Wl9af0AVqW3rLatt8o+Ae+c +-----END CERTIFICATE----- + +# Issuer: CN=Entrust Root Certification Authority - G2 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2009 Entrust, Inc. - for authorized use only +# Subject: CN=Entrust Root Certification Authority - G2 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2009 Entrust, Inc. - for authorized use only +# Label: "Entrust Root Certification Authority - G2" +# Serial: 1246989352 +# MD5 Fingerprint: 4b:e2:c9:91:96:65:0c:f4:0e:5a:93:92:a0:0a:fe:b2 +# SHA1 Fingerprint: 8c:f4:27:fd:79:0c:3a:d1:66:06:8d:e8:1e:57:ef:bb:93:22:72:d4 +# SHA256 Fingerprint: 43:df:57:74:b0:3e:7f:ef:5f:e4:0d:93:1a:7b:ed:f1:bb:2e:6b:42:73:8c:4e:6d:38:41:10:3d:3a:a7:f3:39 +-----BEGIN CERTIFICATE----- +MIIEPjCCAyagAwIBAgIESlOMKDANBgkqhkiG9w0BAQsFADCBvjELMAkGA1UEBhMC +VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50 +cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3Qs +IEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEyMDAGA1UEAxMpRW50cnVz +dCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzIwHhcNMDkwNzA3MTcy +NTU0WhcNMzAxMjA3MTc1NTU0WjCBvjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUVu +dHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwt +dGVybXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0 +aG9yaXplZCB1c2Ugb25seTEyMDAGA1UEAxMpRW50cnVzdCBSb290IENlcnRpZmlj +YXRpb24gQXV0aG9yaXR5IC0gRzIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQC6hLZy254Ma+KZ6TABp3bqMriVQRrJ2mFOWHLP/vaCeb9zYQYKpSfYs1/T +RU4cctZOMvJyig/3gxnQaoCAAEUesMfnmr8SVycco2gvCoe9amsOXmXzHHfV1IWN +cCG0szLni6LVhjkCsbjSR87kyUnEO6fe+1R9V77w6G7CebI6C1XiUJgWMhNcL3hW +wcKUs/Ja5CeanyTXxuzQmyWC48zCxEXFjJd6BmsqEZ+pCm5IO2/b1BEZQvePB7/1 +U1+cPvQXLOZprE4yTGJ36rfo5bs0vBmLrpxR57d+tVOxMyLlbc9wPBr64ptntoP0 +jaWvYkxN4FisZDQSA/i2jZRjJKRxAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAP +BgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqciZ60B7vfec7aVHUbI2fkBJmqzAN +BgkqhkiG9w0BAQsFAAOCAQEAeZ8dlsa2eT8ijYfThwMEYGprmi5ZiXMRrEPR9RP/ +jTkrwPK9T3CMqS/qF8QLVJ7UG5aYMzyorWKiAHarWWluBh1+xLlEjZivEtRh2woZ +Rkfz6/djwUAFQKXSt/S1mja/qYh2iARVBCuch38aNzx+LaUa2NSJXsq9rD1s2G2v +1fN2D807iDginWyTmsQ9v4IbZT+mD12q/OWyFcq1rca8PdCE6OoGcrBNOTJ4vz4R +nAuknZoh8/CbCzB428Hch0P+vGOaysXCHMnHjf87ElgI5rY97HosTvuDls4MPGmH +VHOkc8KT/1EQrBVUAdj8BbGJoX90g5pJ19xOe4pIb4tF9g== +-----END CERTIFICATE----- + +# Issuer: CN=Entrust Root Certification Authority - EC1 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2012 Entrust, Inc. - for authorized use only +# Subject: CN=Entrust Root Certification Authority - EC1 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2012 Entrust, Inc. - for authorized use only +# Label: "Entrust Root Certification Authority - EC1" +# Serial: 51543124481930649114116133369 +# MD5 Fingerprint: b6:7e:1d:f0:58:c5:49:6c:24:3b:3d:ed:98:18:ed:bc +# SHA1 Fingerprint: 20:d8:06:40:df:9b:25:f5:12:25:3a:11:ea:f7:59:8a:eb:14:b5:47 +# SHA256 Fingerprint: 02:ed:0e:b2:8c:14:da:45:16:5c:56:67:91:70:0d:64:51:d7:fb:56:f0:b2:ab:1d:3b:8e:b0:70:e5:6e:df:f5 +-----BEGIN CERTIFICATE----- +MIIC+TCCAoCgAwIBAgINAKaLeSkAAAAAUNCR+TAKBggqhkjOPQQDAzCBvzELMAkG +A1UEBhMCVVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3 +d3cuZW50cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDEyIEVu +dHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEzMDEGA1UEAxMq +RW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRUMxMB4XDTEy +MTIxODE1MjUzNloXDTM3MTIxODE1NTUzNlowgb8xCzAJBgNVBAYTAlVTMRYwFAYD +VQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1c3QubmV0 +L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxMiBFbnRydXN0LCBJbmMuIC0g +Zm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxMzAxBgNVBAMTKkVudHJ1c3QgUm9vdCBD +ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEVDMTB2MBAGByqGSM49AgEGBSuBBAAi +A2IABIQTydC6bUF74mzQ61VfZgIaJPRbiWlH47jCffHyAsWfoPZb1YsGGYZPUxBt +ByQnoaD41UcZYUx9ypMn6nQM72+WCf5j7HBdNq1nd67JnXxVRDqiY1Ef9eNi1KlH +Bz7MIKNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0O +BBYEFLdj5xrdjekIplWDpOBqUEFlEUJJMAoGCCqGSM49BAMDA2cAMGQCMGF52OVC +R98crlOZF7ZvHH3hvxGU0QOIdeSNiaSKd0bebWHvAvX7td/M/k7//qnmpwIwW5nX +hTcGtXsI/esni0qU+eH6p44mCOh8kmhtc9hvJqwhAriZtyZBWyVgrtBIGu4G +-----END CERTIFICATE----- + +# Issuer: CN=CFCA EV ROOT O=China Financial Certification Authority +# Subject: CN=CFCA EV ROOT O=China Financial Certification Authority +# Label: "CFCA EV ROOT" +# Serial: 407555286 +# MD5 Fingerprint: 74:e1:b6:ed:26:7a:7a:44:30:33:94:ab:7b:27:81:30 +# SHA1 Fingerprint: e2:b8:29:4b:55:84:ab:6b:58:c2:90:46:6c:ac:3f:b8:39:8f:84:83 +# SHA256 Fingerprint: 5c:c3:d7:8e:4e:1d:5e:45:54:7a:04:e6:87:3e:64:f9:0c:f9:53:6d:1c:cc:2e:f8:00:f3:55:c4:c5:fd:70:fd +-----BEGIN CERTIFICATE----- +MIIFjTCCA3WgAwIBAgIEGErM1jANBgkqhkiG9w0BAQsFADBWMQswCQYDVQQGEwJD +TjEwMC4GA1UECgwnQ2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9y +aXR5MRUwEwYDVQQDDAxDRkNBIEVWIFJPT1QwHhcNMTIwODA4MDMwNzAxWhcNMjkx +MjMxMDMwNzAxWjBWMQswCQYDVQQGEwJDTjEwMC4GA1UECgwnQ2hpbmEgRmluYW5j +aWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRUwEwYDVQQDDAxDRkNBIEVWIFJP +T1QwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDXXWvNED8fBVnVBU03 +sQ7smCuOFR36k0sXgiFxEFLXUWRwFsJVaU2OFW2fvwwbwuCjZ9YMrM8irq93VCpL +TIpTUnrD7i7es3ElweldPe6hL6P3KjzJIx1qqx2hp/Hz7KDVRM8Vz3IvHWOX6Jn5 +/ZOkVIBMUtRSqy5J35DNuF++P96hyk0g1CXohClTt7GIH//62pCfCqktQT+x8Rgp +7hZZLDRJGqgG16iI0gNyejLi6mhNbiyWZXvKWfry4t3uMCz7zEasxGPrb382KzRz +EpR/38wmnvFyXVBlWY9ps4deMm/DGIq1lY+wejfeWkU7xzbh72fROdOXW3NiGUgt +hxwG+3SYIElz8AXSG7Ggo7cbcNOIabla1jj0Ytwli3i/+Oh+uFzJlU9fpy25IGvP +a931DfSCt/SyZi4QKPaXWnuWFo8BGS1sbn85WAZkgwGDg8NNkt0yxoekN+kWzqot +aK8KgWU6cMGbrU1tVMoqLUuFG7OA5nBFDWteNfB/O7ic5ARwiRIlk9oKmSJgamNg +TnYGmE69g60dWIolhdLHZR4tjsbftsbhf4oEIRUpdPA+nJCdDC7xij5aqgwJHsfV +PKPtl8MeNPo4+QgO48BdK4PRVmrJtqhUUy54Mmc9gn900PvhtgVguXDbjgv5E1hv +cWAQUhC5wUEJ73IfZzF4/5YFjQIDAQABo2MwYTAfBgNVHSMEGDAWgBTj/i39KNAL +tbq2osS/BqoFjJP7LzAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAd +BgNVHQ4EFgQU4/4t/SjQC7W6tqLEvwaqBYyT+y8wDQYJKoZIhvcNAQELBQADggIB +ACXGumvrh8vegjmWPfBEp2uEcwPenStPuiB/vHiyz5ewG5zz13ku9Ui20vsXiObT +ej/tUxPQ4i9qecsAIyjmHjdXNYmEwnZPNDatZ8POQQaIxffu2Bq41gt/UP+TqhdL +jOztUmCypAbqTuv0axn96/Ua4CUqmtzHQTb3yHQFhDmVOdYLO6Qn+gjYXB74BGBS +ESgoA//vU2YApUo0FmZ8/Qmkrp5nGm9BC2sGE5uPhnEFtC+NiWYzKXZUmhH4J/qy +P5Hgzg0b8zAarb8iXRvTvyUFTeGSGn+ZnzxEk8rUQElsgIfXBDrDMlI1Dlb4pd19 +xIsNER9Tyx6yF7Zod1rg1MvIB671Oi6ON7fQAUtDKXeMOZePglr4UeWJoBjnaH9d +Ci77o0cOPaYjesYBx4/IXr9tgFa+iiS6M+qf4TIRnvHST4D2G0CvOJ4RUHlzEhLN +5mydLIhyPDCBBpEi6lmt2hkuIsKNuYyH4Ga8cyNfIWRjgEj1oDwYPZTISEEdQLpe +/v5WOaHIz16eGWRGENoXkbcFgKyLmZJ956LYBws2J+dIeWCKw9cTXPhyQN9Ky8+Z +AAoACxGV2lZFA4gKn2fQ1XmxqI1AbQ3CekD6819kR5LLU7m7Wc5P/dAVUwHY3+vZ +5nbv0CO7O6l5s9UCKc2Jo5YPSjXnTkLAdc0Hz+Ys63su +-----END CERTIFICATE----- + +# Issuer: CN=OISTE WISeKey Global Root GB CA O=WISeKey OU=OISTE Foundation Endorsed +# Subject: CN=OISTE WISeKey Global Root GB CA O=WISeKey OU=OISTE Foundation Endorsed +# Label: "OISTE WISeKey Global Root GB CA" +# Serial: 157768595616588414422159278966750757568 +# MD5 Fingerprint: a4:eb:b9:61:28:2e:b7:2f:98:b0:35:26:90:99:51:1d +# SHA1 Fingerprint: 0f:f9:40:76:18:d3:d7:6a:4b:98:f0:a8:35:9e:0c:fd:27:ac:cc:ed +# SHA256 Fingerprint: 6b:9c:08:e8:6e:b0:f7:67:cf:ad:65:cd:98:b6:21:49:e5:49:4a:67:f5:84:5e:7b:d1:ed:01:9f:27:b8:6b:d6 +-----BEGIN CERTIFICATE----- +MIIDtTCCAp2gAwIBAgIQdrEgUnTwhYdGs/gjGvbCwDANBgkqhkiG9w0BAQsFADBt +MQswCQYDVQQGEwJDSDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUg +Rm91bmRhdGlvbiBFbmRvcnNlZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9i +YWwgUm9vdCBHQiBDQTAeFw0xNDEyMDExNTAwMzJaFw0zOTEyMDExNTEwMzFaMG0x +CzAJBgNVBAYTAkNIMRAwDgYDVQQKEwdXSVNlS2V5MSIwIAYDVQQLExlPSVNURSBG +b3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5IEdsb2Jh +bCBSb290IEdCIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2Be3 +HEokKtaXscriHvt9OO+Y9bI5mE4nuBFde9IllIiCFSZqGzG7qFshISvYD06fWvGx +WuR51jIjK+FTzJlFXHtPrby/h0oLS5daqPZI7H17Dc0hBt+eFf1Biki3IPShehtX +1F1Q/7pn2COZH8g/497/b1t3sWtuuMlk9+HKQUYOKXHQuSP8yYFfTvdv37+ErXNk +u7dCjmn21HYdfp2nuFeKUWdy19SouJVUQHMD9ur06/4oQnc/nSMbsrY9gBQHTC5P +99UKFg29ZkM3fiNDecNAhvVMKdqOmq0NpQSHiB6F4+lT1ZvIiwNjeOvgGUpuuy9r +M2RYk61pv48b74JIxwIDAQABo1EwTzALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUw +AwEB/zAdBgNVHQ4EFgQUNQ/INmNe4qPs+TtmFc5RUuORmj0wEAYJKwYBBAGCNxUB +BAMCAQAwDQYJKoZIhvcNAQELBQADggEBAEBM+4eymYGQfp3FsLAmzYh7KzKNbrgh +cViXfa43FK8+5/ea4n32cZiZBKpDdHij40lhPnOMTZTg+XHEthYOU3gf1qKHLwI5 +gSk8rxWYITD+KJAAjNHhy/peyP34EEY7onhCkRd0VQreUGdNZtGn//3ZwLWoo4rO +ZvUPQ82nK1d7Y0Zqqi5S2PTt4W2tKZB4SLrhI6qjiey1q5bAtEuiHZeeevJuQHHf +aPFlTc58Bd9TZaml8LGXBHAVRgOY1NK/VLSgWH1Sb9pWJmLU2NuJMW8c8CLC02Ic +Nc1MaRVUGpCY3useX8p3x8uOPUNpnJpY0CQ73xtAln41rYHHTnG6iBM= +-----END CERTIFICATE----- + +# Issuer: CN=SZAFIR ROOT CA2 O=Krajowa Izba Rozliczeniowa S.A. +# Subject: CN=SZAFIR ROOT CA2 O=Krajowa Izba Rozliczeniowa S.A. +# Label: "SZAFIR ROOT CA2" +# Serial: 357043034767186914217277344587386743377558296292 +# MD5 Fingerprint: 11:64:c1:89:b0:24:b1:8c:b1:07:7e:89:9e:51:9e:99 +# SHA1 Fingerprint: e2:52:fa:95:3f:ed:db:24:60:bd:6e:28:f3:9c:cc:cf:5e:b3:3f:de +# SHA256 Fingerprint: a1:33:9d:33:28:1a:0b:56:e5:57:d3:d3:2b:1c:e7:f9:36:7e:b0:94:bd:5f:a7:2a:7e:50:04:c8:de:d7:ca:fe +-----BEGIN CERTIFICATE----- +MIIDcjCCAlqgAwIBAgIUPopdB+xV0jLVt+O2XwHrLdzk1uQwDQYJKoZIhvcNAQEL +BQAwUTELMAkGA1UEBhMCUEwxKDAmBgNVBAoMH0tyYWpvd2EgSXpiYSBSb3psaWN6 +ZW5pb3dhIFMuQS4xGDAWBgNVBAMMD1NaQUZJUiBST09UIENBMjAeFw0xNTEwMTkw +NzQzMzBaFw0zNTEwMTkwNzQzMzBaMFExCzAJBgNVBAYTAlBMMSgwJgYDVQQKDB9L +cmFqb3dhIEl6YmEgUm96bGljemVuaW93YSBTLkEuMRgwFgYDVQQDDA9TWkFGSVIg +Uk9PVCBDQTIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC3vD5QqEvN +QLXOYeeWyrSh2gwisPq1e3YAd4wLz32ohswmUeQgPYUM1ljj5/QqGJ3a0a4m7utT +3PSQ1hNKDJA8w/Ta0o4NkjrcsbH/ON7Dui1fgLkCvUqdGw+0w8LBZwPd3BucPbOw +3gAeqDRHu5rr/gsUvTaE2g0gv/pby6kWIK05YO4vdbbnl5z5Pv1+TW9NL++IDWr6 +3fE9biCloBK0TXC5ztdyO4mTp4CEHCdJckm1/zuVnsHMyAHs6A6KCpbns6aH5db5 +BSsNl0BwPLqsdVqc1U2dAgrSS5tmS0YHF2Wtn2yIANwiieDhZNRnvDF5YTy7ykHN +XGoAyDw4jlivAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQD +AgEGMB0GA1UdDgQWBBQuFqlKGLXLzPVvUPMjX/hd56zwyDANBgkqhkiG9w0BAQsF +AAOCAQEAtXP4A9xZWx126aMqe5Aosk3AM0+qmrHUuOQn/6mWmc5G4G18TKI4pAZw +8PRBEew/R40/cof5O/2kbytTAOD/OblqBw7rHRz2onKQy4I9EYKL0rufKq8h5mOG +nXkZ7/e7DDWQw4rtTw/1zBLZpD67oPwglV9PJi8RI4NOdQcPv5vRtB3pEAT+ymCP +oky4rc/hkA/NrgrHXXu3UNLUYfrVFdvXn4dRVOul4+vJhaAlIDf7js4MNIThPIGy +d05DpYhfhmehPea0XGG2Ptv+tyjFogeutcrKjSoS75ftwjCkySp6+/NNIxuZMzSg +LvWpCz/UXeHPhJ/iGcJfitYgHuNztw== +-----END CERTIFICATE----- + +# Issuer: CN=Certum Trusted Network CA 2 O=Unizeto Technologies S.A. OU=Certum Certification Authority +# Subject: CN=Certum Trusted Network CA 2 O=Unizeto Technologies S.A. OU=Certum Certification Authority +# Label: "Certum Trusted Network CA 2" +# Serial: 44979900017204383099463764357512596969 +# MD5 Fingerprint: 6d:46:9e:d9:25:6d:08:23:5b:5e:74:7d:1e:27:db:f2 +# SHA1 Fingerprint: d3:dd:48:3e:2b:bf:4c:05:e8:af:10:f5:fa:76:26:cf:d3:dc:30:92 +# SHA256 Fingerprint: b6:76:f2:ed:da:e8:77:5c:d3:6c:b0:f6:3c:d1:d4:60:39:61:f4:9e:62:65:ba:01:3a:2f:03:07:b6:d0:b8:04 +-----BEGIN CERTIFICATE----- +MIIF0jCCA7qgAwIBAgIQIdbQSk8lD8kyN/yqXhKN6TANBgkqhkiG9w0BAQ0FADCB +gDELMAkGA1UEBhMCUEwxIjAgBgNVBAoTGVVuaXpldG8gVGVjaG5vbG9naWVzIFMu +QS4xJzAlBgNVBAsTHkNlcnR1bSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEkMCIG +A1UEAxMbQ2VydHVtIFRydXN0ZWQgTmV0d29yayBDQSAyMCIYDzIwMTExMDA2MDgz +OTU2WhgPMjA0NjEwMDYwODM5NTZaMIGAMQswCQYDVQQGEwJQTDEiMCAGA1UEChMZ +VW5pemV0byBUZWNobm9sb2dpZXMgUy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRp +ZmljYXRpb24gQXV0aG9yaXR5MSQwIgYDVQQDExtDZXJ0dW0gVHJ1c3RlZCBOZXR3 +b3JrIENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC9+Xj45tWA +DGSdhhuWZGc/IjoedQF97/tcZ4zJzFxrqZHmuULlIEub2pt7uZld2ZuAS9eEQCsn +0+i6MLs+CRqnSZXvK0AkwpfHp+6bJe+oCgCXhVqqndwpyeI1B+twTUrWwbNWuKFB +OJvR+zF/j+Bf4bE/D44WSWDXBo0Y+aomEKsq09DRZ40bRr5HMNUuctHFY9rnY3lE +fktjJImGLjQ/KUxSiyqnwOKRKIm5wFv5HdnnJ63/mgKXwcZQkpsCLL2puTRZCr+E +Sv/f/rOf69me4Jgj7KZrdxYq28ytOxykh9xGc14ZYmhFV+SQgkK7QtbwYeDBoz1m +o130GO6IyY0XRSmZMnUCMe4pJshrAua1YkV/NxVaI2iJ1D7eTiew8EAMvE0Xy02i +sx7QBlrd9pPPV3WZ9fqGGmd4s7+W/jTcvedSVuWz5XV710GRBdxdaeOVDUO5/IOW +OZV7bIBaTxNyxtd9KXpEulKkKtVBRgkg/iKgtlswjbyJDNXXcPiHUv3a76xRLgez +Tv7QCdpw75j6VuZt27VXS9zlLCUVyJ4ueE742pyehizKV/Ma5ciSixqClnrDvFAS +adgOWkaLOusm+iPJtrCBvkIApPjW/jAux9JG9uWOdf3yzLnQh1vMBhBgu4M1t15n +3kfsmUjxpKEV/q2MYo45VU85FrmxY53/twIDAQABo0IwQDAPBgNVHRMBAf8EBTAD +AQH/MB0GA1UdDgQWBBS2oVQ5AsOgP46KvPrU+Bym0ToO/TAOBgNVHQ8BAf8EBAMC +AQYwDQYJKoZIhvcNAQENBQADggIBAHGlDs7k6b8/ONWJWsQCYftMxRQXLYtPU2sQ +F/xlhMcQSZDe28cmk4gmb3DWAl45oPePq5a1pRNcgRRtDoGCERuKTsZPpd1iHkTf +CVn0W3cLN+mLIMb4Ck4uWBzrM9DPhmDJ2vuAL55MYIR4PSFk1vtBHxgP58l1cb29 +XN40hz5BsA72udY/CROWFC/emh1auVbONTqwX3BNXuMp8SMoclm2q8KMZiYcdywm +djWLKKdpoPk79SPdhRB0yZADVpHnr7pH1BKXESLjokmUbOe3lEu6LaTaM4tMpkT/ +WjzGHWTYtTHkpjx6qFcL2+1hGsvxznN3Y6SHb0xRONbkX8eftoEq5IVIeVheO/jb +AoJnwTnbw3RLPTYe+SmTiGhbqEQZIfCn6IENLOiTNrQ3ssqwGyZ6miUfmpqAnksq +P/ujmv5zMnHCnsZy4YpoJ/HkD7TETKVhk/iXEAcqMCWpuchxuO9ozC1+9eB+D4Ko +b7a6bINDd82Kkhehnlt4Fj1F4jNy3eFmypnTycUm/Q1oBEauttmbjL4ZvrHG8hnj +XALKLNhvSgfZyTXaQHXyxKcZb55CEJh15pWLYLztxRLXis7VmFxWlgPF7ncGNf/P +5O4/E2Hu29othfDNrp2yGAlFw5Khchf8R7agCyzxxN5DaAhqXzvwdmP7zAYspsbi +DrW5viSP +-----END CERTIFICATE----- + +# Issuer: CN=Hellenic Academic and Research Institutions RootCA 2015 O=Hellenic Academic and Research Institutions Cert. Authority +# Subject: CN=Hellenic Academic and Research Institutions RootCA 2015 O=Hellenic Academic and Research Institutions Cert. Authority +# Label: "Hellenic Academic and Research Institutions RootCA 2015" +# Serial: 0 +# MD5 Fingerprint: ca:ff:e2:db:03:d9:cb:4b:e9:0f:ad:84:fd:7b:18:ce +# SHA1 Fingerprint: 01:0c:06:95:a6:98:19:14:ff:bf:5f:c6:b0:b6:95:ea:29:e9:12:a6 +# SHA256 Fingerprint: a0:40:92:9a:02:ce:53:b4:ac:f4:f2:ff:c6:98:1c:e4:49:6f:75:5e:6d:45:fe:0b:2a:69:2b:cd:52:52:3f:36 +-----BEGIN CERTIFICATE----- +MIIGCzCCA/OgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBpjELMAkGA1UEBhMCR1Ix +DzANBgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5k +IFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNVBAMT +N0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgUm9v +dENBIDIwMTUwHhcNMTUwNzA3MTAxMTIxWhcNNDAwNjMwMTAxMTIxWjCBpjELMAkG +A1UEBhMCR1IxDzANBgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNh +ZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkx +QDA+BgNVBAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1 +dGlvbnMgUm9vdENBIDIwMTUwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC +AQDC+Kk/G4n8PDwEXT2QNrCROnk8ZlrvbTkBSRq0t89/TSNTt5AA4xMqKKYx8ZEA +4yjsriFBzh/a/X0SWwGDD7mwX5nh8hKDgE0GPt+sr+ehiGsxr/CL0BgzuNtFajT0 +AoAkKAoCFZVedioNmToUW/bLy1O8E00BiDeUJRtCvCLYjqOWXjrZMts+6PAQZe10 +4S+nfK8nNLspfZu2zwnI5dMK/IhlZXQK3HMcXM1AsRzUtoSMTFDPaI6oWa7CJ06C +ojXdFPQf/7J31Ycvqm59JCfnxssm5uX+Zwdj2EUN3TpZZTlYepKZcj2chF6IIbjV +9Cz82XBST3i4vTwri5WY9bPRaM8gFH5MXF/ni+X1NYEZN9cRCLdmvtNKzoNXADrD +gfgXy5I2XdGj2HUb4Ysn6npIQf1FGQatJ5lOwXBH3bWfgVMS5bGMSF0xQxfjjMZ6 +Y5ZLKTBOhE5iGV48zpeQpX8B653g+IuJ3SWYPZK2fu/Z8VFRfS0myGlZYeCsargq +NhEEelC9MoS+L9xy1dcdFkfkR2YgP/SWxa+OAXqlD3pk9Q0Yh9muiNX6hME6wGko +LfINaFGq46V3xqSQDqE3izEjR8EJCOtu93ib14L8hCCZSRm2Ekax+0VVFqmjZayc +Bw/qa9wfLgZy7IaIEuQt218FL+TwA9MmM+eAws1CoRc0CwIDAQABo0IwQDAPBgNV +HRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUcRVnyMjJvXVd +ctA4GGqd83EkVAswDQYJKoZIhvcNAQELBQADggIBAHW7bVRLqhBYRjTyYtcWNl0I +XtVsyIe9tC5G8jH4fOpCtZMWVdyhDBKg2mF+D1hYc2Ryx+hFjtyp8iY/xnmMsVMI +M4GwVhO+5lFc2JsKT0ucVlMC6U/2DWDqTUJV6HwbISHTGzrMd/K4kPFox/la/vot +9L/J9UUbzjgQKjeKeaO04wlshYaT/4mWJ3iBj2fjRnRUjtkNaeJK9E10A/+yd+2V +Z5fkscWrv2oj6NSU4kQoYsRL4vDY4ilrGnB+JGGTe08DMiUNRSQrlrRGar9KC/ea +j8GsGsVn82800vpzY4zvFrCopEYq+OsS7HK07/grfoxSwIuEVPkvPuNVqNxmsdnh +X9izjFk0WaSrT2y7HxjbdavYy5LNlDhhDgcGH0tGEPEVvo2FXDtKK4F5D7Rpn0lQ +l033DlZdwJVqwjbDG2jJ9SrcR5q+ss7FJej6A7na+RZukYT1HCjI/CbM1xyQVqdf +bzoEvM14iQuODy+jqk+iGxI9FghAD/FGTNeqewjBCvVtJ94Cj8rDtSvK6evIIVM4 +pcw72Hc3MKJP2W/R8kCtQXoXxdZKNYm3QdV8hn9VTYNKpXMgwDqvkPGaJI7ZjnHK +e7iG2rKPmT4dEw0SEe7Uq/DpFXYC5ODfqiAeW2GFZECpkJcNrVPSWh2HagCXZWK0 +vm9qp/UsQu0yrbYhnr68 +-----END CERTIFICATE----- + +# Issuer: CN=Hellenic Academic and Research Institutions ECC RootCA 2015 O=Hellenic Academic and Research Institutions Cert. Authority +# Subject: CN=Hellenic Academic and Research Institutions ECC RootCA 2015 O=Hellenic Academic and Research Institutions Cert. Authority +# Label: "Hellenic Academic and Research Institutions ECC RootCA 2015" +# Serial: 0 +# MD5 Fingerprint: 81:e5:b4:17:eb:c2:f5:e1:4b:0d:41:7b:49:92:fe:ef +# SHA1 Fingerprint: 9f:f1:71:8d:92:d5:9a:f3:7d:74:97:b4:bc:6f:84:68:0b:ba:b6:66 +# SHA256 Fingerprint: 44:b5:45:aa:8a:25:e6:5a:73:ca:15:dc:27:fc:36:d2:4c:1c:b9:95:3a:06:65:39:b1:15:82:dc:48:7b:48:33 +-----BEGIN CERTIFICATE----- +MIICwzCCAkqgAwIBAgIBADAKBggqhkjOPQQDAjCBqjELMAkGA1UEBhMCR1IxDzAN +BgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJl +c2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxRDBCBgNVBAMTO0hl +bGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgRUNDIFJv +b3RDQSAyMDE1MB4XDTE1MDcwNzEwMzcxMloXDTQwMDYzMDEwMzcxMlowgaoxCzAJ +BgNVBAYTAkdSMQ8wDQYDVQQHEwZBdGhlbnMxRDBCBgNVBAoTO0hlbGxlbmljIEFj +YWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgQ2VydC4gQXV0aG9yaXR5 +MUQwQgYDVQQDEztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0 +dXRpb25zIEVDQyBSb290Q0EgMjAxNTB2MBAGByqGSM49AgEGBSuBBAAiA2IABJKg +QehLgoRc4vgxEZmGZE4JJS+dQS8KrjVPdJWyUWRrjWvmP3CV8AVER6ZyOFB2lQJa +jq4onvktTpnvLEhvTCUp6NFxW98dwXU3tNf6e3pCnGoKVlp8aQuqgAkkbH7BRqNC +MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFLQi +C4KZJAEOnLvkDv2/+5cgk5kqMAoGCCqGSM49BAMCA2cAMGQCMGfOFmI4oqxiRaep +lSTAGiecMjvAwNW6qef4BENThe5SId6d9SWDPp5YSy/XZxMOIQIwBeF1Ad5o7Sof +TUwJCA3sS61kFyjndc5FZXIhF8siQQ6ME5g4mlRtm8rifOoCWCKR +-----END CERTIFICATE----- + +# Issuer: CN=ISRG Root X1 O=Internet Security Research Group +# Subject: CN=ISRG Root X1 O=Internet Security Research Group +# Label: "ISRG Root X1" +# Serial: 172886928669790476064670243504169061120 +# MD5 Fingerprint: 0c:d2:f9:e0:da:17:73:e9:ed:86:4d:a5:e3:70:e7:4e +# SHA1 Fingerprint: ca:bd:2a:79:a1:07:6a:31:f2:1d:25:36:35:cb:03:9d:43:29:a5:e8 +# SHA256 Fingerprint: 96:bc:ec:06:26:49:76:f3:74:60:77:9a:cf:28:c5:a7:cf:e8:a3:c0:aa:e1:1a:8f:fc:ee:05:c0:bd:df:08:c6 +-----BEGIN CERTIFICATE----- +MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw +TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh +cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4 +WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu +ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY +MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc +h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+ +0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U +A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW +T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH +B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC +B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv +KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn +OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn +jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw +qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI +rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV +HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq +hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL +ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ +3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK +NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5 +ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur +TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC +jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc +oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq +4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA +mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d +emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc= +-----END CERTIFICATE----- + +# Issuer: O=FNMT-RCM OU=AC RAIZ FNMT-RCM +# Subject: O=FNMT-RCM OU=AC RAIZ FNMT-RCM +# Label: "AC RAIZ FNMT-RCM" +# Serial: 485876308206448804701554682760554759 +# MD5 Fingerprint: e2:09:04:b4:d3:bd:d1:a0:14:fd:1a:d2:47:c4:57:1d +# SHA1 Fingerprint: ec:50:35:07:b2:15:c4:95:62:19:e2:a8:9a:5b:42:99:2c:4c:2c:20 +# SHA256 Fingerprint: eb:c5:57:0c:29:01:8c:4d:67:b1:aa:12:7b:af:12:f7:03:b4:61:1e:bc:17:b7:da:b5:57:38:94:17:9b:93:fa +-----BEGIN CERTIFICATE----- +MIIFgzCCA2ugAwIBAgIPXZONMGc2yAYdGsdUhGkHMA0GCSqGSIb3DQEBCwUAMDsx +CzAJBgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJ +WiBGTk1ULVJDTTAeFw0wODEwMjkxNTU5NTZaFw0zMDAxMDEwMDAwMDBaMDsxCzAJ +BgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJWiBG +Tk1ULVJDTTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALpxgHpMhm5/ +yBNtwMZ9HACXjywMI7sQmkCpGreHiPibVmr75nuOi5KOpyVdWRHbNi63URcfqQgf +BBckWKo3Shjf5TnUV/3XwSyRAZHiItQDwFj8d0fsjz50Q7qsNI1NOHZnjrDIbzAz +WHFctPVrbtQBULgTfmxKo0nRIBnuvMApGGWn3v7v3QqQIecaZ5JCEJhfTzC8PhxF +tBDXaEAUwED653cXeuYLj2VbPNmaUtu1vZ5Gzz3rkQUCwJaydkxNEJY7kvqcfw+Z +374jNUUeAlz+taibmSXaXvMiwzn15Cou08YfxGyqxRxqAQVKL9LFwag0Jl1mpdIC +IfkYtwb1TplvqKtMUejPUBjFd8g5CSxJkjKZqLsXF3mwWsXmo8RZZUc1g16p6DUL +mbvkzSDGm0oGObVo/CK67lWMK07q87Hj/LaZmtVC+nFNCM+HHmpxffnTtOmlcYF7 +wk5HlqX2doWjKI/pgG6BU6VtX7hI+cL5NqYuSf+4lsKMB7ObiFj86xsc3i1w4peS +MKGJ47xVqCfWS+2QrYv6YyVZLag13cqXM7zlzced0ezvXg5KkAYmY6252TUtB7p2 +ZSysV4999AeU14ECll2jB0nVetBX+RvnU0Z1qrB5QstocQjpYL05ac70r8NWQMet +UqIJ5G+GR4of6ygnXYMgrwTJbFaai0b1AgMBAAGjgYMwgYAwDwYDVR0TAQH/BAUw +AwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFPd9xf3E6Jobd2Sn9R2gzL+H +YJptMD4GA1UdIAQ3MDUwMwYEVR0gADArMCkGCCsGAQUFBwIBFh1odHRwOi8vd3d3 +LmNlcnQuZm5tdC5lcy9kcGNzLzANBgkqhkiG9w0BAQsFAAOCAgEAB5BK3/MjTvDD +nFFlm5wioooMhfNzKWtN/gHiqQxjAb8EZ6WdmF/9ARP67Jpi6Yb+tmLSbkyU+8B1 +RXxlDPiyN8+sD8+Nb/kZ94/sHvJwnvDKuO+3/3Y3dlv2bojzr2IyIpMNOmqOFGYM +LVN0V2Ue1bLdI4E7pWYjJ2cJj+F3qkPNZVEI7VFY/uY5+ctHhKQV8Xa7pO6kO8Rf +77IzlhEYt8llvhjho6Tc+hj507wTmzl6NLrTQfv6MooqtyuGC2mDOL7Nii4LcK2N +JpLuHvUBKwrZ1pebbuCoGRw6IYsMHkCtA+fdZn71uSANA+iW+YJF1DngoABd15jm +fZ5nc8OaKveri6E6FO80vFIOiZiaBECEHX5FaZNXzuvO+FB8TxxuBEOb+dY7Ixjp +6o7RTUaN8Tvkasq6+yO3m/qZASlaWFot4/nUbQ4mrcFuNLwy+AwF+mWj2zs3gyLp +1txyM/1d8iC9djwj2ij3+RvrWWTV3F9yfiD8zYm1kGdNYno/Tq0dwzn+evQoFt9B +9kiABdcPUXmsEKvU7ANm5mqwujGSQkBqvjrTcuFqN1W8rB2Vt2lh8kORdOag0wok +RqEIr9baRRmW1FMdW4R58MD3R++Lj8UGrp1MYp3/RgT408m2ECVAdf4WqslKYIYv +uu8wd+RU4riEmViAqhOLUTpPSPaLtrM= +-----END CERTIFICATE----- + +# Issuer: CN=Amazon Root CA 1 O=Amazon +# Subject: CN=Amazon Root CA 1 O=Amazon +# Label: "Amazon Root CA 1" +# Serial: 143266978916655856878034712317230054538369994 +# MD5 Fingerprint: 43:c6:bf:ae:ec:fe:ad:2f:18:c6:88:68:30:fc:c8:e6 +# SHA1 Fingerprint: 8d:a7:f9:65:ec:5e:fc:37:91:0f:1c:6e:59:fd:c1:cc:6a:6e:de:16 +# SHA256 Fingerprint: 8e:cd:e6:88:4f:3d:87:b1:12:5b:a3:1a:c3:fc:b1:3d:70:16:de:7f:57:cc:90:4f:e1:cb:97:c6:ae:98:19:6e +-----BEGIN CERTIFICATE----- +MIIDQTCCAimgAwIBAgITBmyfz5m/jAo54vB4ikPmljZbyjANBgkqhkiG9w0BAQsF +ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6 +b24gUm9vdCBDQSAxMB4XDTE1MDUyNjAwMDAwMFoXDTM4MDExNzAwMDAwMFowOTEL +MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv +b3QgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALJ4gHHKeNXj +ca9HgFB0fW7Y14h29Jlo91ghYPl0hAEvrAIthtOgQ3pOsqTQNroBvo3bSMgHFzZM +9O6II8c+6zf1tRn4SWiw3te5djgdYZ6k/oI2peVKVuRF4fn9tBb6dNqcmzU5L/qw +IFAGbHrQgLKm+a/sRxmPUDgH3KKHOVj4utWp+UhnMJbulHheb4mjUcAwhmahRWa6 +VOujw5H5SNz/0egwLX0tdHA114gk957EWW67c4cX8jJGKLhD+rcdqsq08p8kDi1L +93FcXmn/6pUCyziKrlA4b9v7LWIbxcceVOF34GfID5yHI9Y/QCB/IIDEgEw+OyQm +jgSubJrIqg0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC +AYYwHQYDVR0OBBYEFIQYzIU07LwMlJQuCFmcx7IQTgoIMA0GCSqGSIb3DQEBCwUA +A4IBAQCY8jdaQZChGsV2USggNiMOruYou6r4lK5IpDB/G/wkjUu0yKGX9rbxenDI +U5PMCCjjmCXPI6T53iHTfIUJrU6adTrCC2qJeHZERxhlbI1Bjjt/msv0tadQ1wUs +N+gDS63pYaACbvXy8MWy7Vu33PqUXHeeE6V/Uq2V8viTO96LXFvKWlJbYK8U90vv +o/ufQJVtMVT8QtPHRh8jrdkPSHCa2XV4cdFyQzR1bldZwgJcJmApzyMZFo6IQ6XU +5MsI+yMRQ+hDKXJioaldXgjUkK642M4UwtBV8ob2xJNDd2ZhwLnoQdeXeGADbkpy +rqXRfboQnoZsG4q5WTP468SQvvG5 +-----END CERTIFICATE----- + +# Issuer: CN=Amazon Root CA 2 O=Amazon +# Subject: CN=Amazon Root CA 2 O=Amazon +# Label: "Amazon Root CA 2" +# Serial: 143266982885963551818349160658925006970653239 +# MD5 Fingerprint: c8:e5:8d:ce:a8:42:e2:7a:c0:2a:5c:7c:9e:26:bf:66 +# SHA1 Fingerprint: 5a:8c:ef:45:d7:a6:98:59:76:7a:8c:8b:44:96:b5:78:cf:47:4b:1a +# SHA256 Fingerprint: 1b:a5:b2:aa:8c:65:40:1a:82:96:01:18:f8:0b:ec:4f:62:30:4d:83:ce:c4:71:3a:19:c3:9c:01:1e:a4:6d:b4 +-----BEGIN CERTIFICATE----- +MIIFQTCCAymgAwIBAgITBmyf0pY1hp8KD+WGePhbJruKNzANBgkqhkiG9w0BAQwF +ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6 +b24gUm9vdCBDQSAyMB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTEL +MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv +b3QgQ0EgMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK2Wny2cSkxK +gXlRmeyKy2tgURO8TW0G/LAIjd0ZEGrHJgw12MBvIITplLGbhQPDW9tK6Mj4kHbZ +W0/jTOgGNk3Mmqw9DJArktQGGWCsN0R5hYGCrVo34A3MnaZMUnbqQ523BNFQ9lXg +1dKmSYXpN+nKfq5clU1Imj+uIFptiJXZNLhSGkOQsL9sBbm2eLfq0OQ6PBJTYv9K +8nu+NQWpEjTj82R0Yiw9AElaKP4yRLuH3WUnAnE72kr3H9rN9yFVkE8P7K6C4Z9r +2UXTu/Bfh+08LDmG2j/e7HJV63mjrdvdfLC6HM783k81ds8P+HgfajZRRidhW+me +z/CiVX18JYpvL7TFz4QuK/0NURBs+18bvBt+xa47mAExkv8LV/SasrlX6avvDXbR +8O70zoan4G7ptGmh32n2M8ZpLpcTnqWHsFcQgTfJU7O7f/aS0ZzQGPSSbtqDT6Zj +mUyl+17vIWR6IF9sZIUVyzfpYgwLKhbcAS4y2j5L9Z469hdAlO+ekQiG+r5jqFoz +7Mt0Q5X5bGlSNscpb/xVA1wf+5+9R+vnSUeVC06JIglJ4PVhHvG/LopyboBZ/1c6 ++XUyo05f7O0oYtlNc/LMgRdg7c3r3NunysV+Ar3yVAhU/bQtCSwXVEqY0VThUWcI +0u1ufm8/0i2BWSlmy5A5lREedCf+3euvAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMB +Af8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSwDPBMMPQFWAJI/TPlUq9LhONm +UjANBgkqhkiG9w0BAQwFAAOCAgEAqqiAjw54o+Ci1M3m9Zh6O+oAA7CXDpO8Wqj2 +LIxyh6mx/H9z/WNxeKWHWc8w4Q0QshNabYL1auaAn6AFC2jkR2vHat+2/XcycuUY ++gn0oJMsXdKMdYV2ZZAMA3m3MSNjrXiDCYZohMr/+c8mmpJ5581LxedhpxfL86kS +k5Nrp+gvU5LEYFiwzAJRGFuFjWJZY7attN6a+yb3ACfAXVU3dJnJUH/jWS5E4ywl +7uxMMne0nxrpS10gxdr9HIcWxkPo1LsmmkVwXqkLN1PiRnsn/eBG8om3zEK2yygm +btmlyTrIQRNg91CMFa6ybRoVGld45pIq2WWQgj9sAq+uEjonljYE1x2igGOpm/Hl +urR8FLBOybEfdF849lHqm/osohHUqS0nGkWxr7JOcQ3AWEbWaQbLU8uz/mtBzUF+ +fUwPfHJ5elnNXkoOrJupmHN5fLT0zLm4BwyydFy4x2+IoZCn9Kr5v2c69BoVYh63 +n749sSmvZ6ES8lgQGVMDMBu4Gon2nL2XA46jCfMdiyHxtN/kHNGfZQIG6lzWE7OE +76KlXIx3KadowGuuQNKotOrN8I1LOJwZmhsoVLiJkO/KdYE+HvJkJMcYr07/R54H +9jVlpNMKVv/1F2Rs76giJUmTtt8AF9pYfl3uxRuw0dFfIRDH+fO6AgonB8Xx1sfT +4PsJYGw= +-----END CERTIFICATE----- + +# Issuer: CN=Amazon Root CA 3 O=Amazon +# Subject: CN=Amazon Root CA 3 O=Amazon +# Label: "Amazon Root CA 3" +# Serial: 143266986699090766294700635381230934788665930 +# MD5 Fingerprint: a0:d4:ef:0b:f7:b5:d8:49:95:2a:ec:f5:c4:fc:81:87 +# SHA1 Fingerprint: 0d:44:dd:8c:3c:8c:1a:1a:58:75:64:81:e9:0f:2e:2a:ff:b3:d2:6e +# SHA256 Fingerprint: 18:ce:6c:fe:7b:f1:4e:60:b2:e3:47:b8:df:e8:68:cb:31:d0:2e:bb:3a:da:27:15:69:f5:03:43:b4:6d:b3:a4 +-----BEGIN CERTIFICATE----- +MIIBtjCCAVugAwIBAgITBmyf1XSXNmY/Owua2eiedgPySjAKBggqhkjOPQQDAjA5 +MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g +Um9vdCBDQSAzMB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkG +A1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJvb3Qg +Q0EgMzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABCmXp8ZBf8ANm+gBG1bG8lKl +ui2yEujSLtf6ycXYqm0fc4E7O5hrOXwzpcVOho6AF2hiRVd9RFgdszflZwjrZt6j +QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSr +ttvXBp43rDCGB5Fwx5zEGbF4wDAKBggqhkjOPQQDAgNJADBGAiEA4IWSoxe3jfkr +BqWTrBqYaGFy+uGh0PsceGCmQ5nFuMQCIQCcAu/xlJyzlvnrxir4tiz+OpAUFteM +YyRIHN8wfdVoOw== +-----END CERTIFICATE----- + +# Issuer: CN=Amazon Root CA 4 O=Amazon +# Subject: CN=Amazon Root CA 4 O=Amazon +# Label: "Amazon Root CA 4" +# Serial: 143266989758080763974105200630763877849284878 +# MD5 Fingerprint: 89:bc:27:d5:eb:17:8d:06:6a:69:d5:fd:89:47:b4:cd +# SHA1 Fingerprint: f6:10:84:07:d6:f8:bb:67:98:0c:c2:e2:44:c2:eb:ae:1c:ef:63:be +# SHA256 Fingerprint: e3:5d:28:41:9e:d0:20:25:cf:a6:90:38:cd:62:39:62:45:8d:a5:c6:95:fb:de:a3:c2:2b:0b:fb:25:89:70:92 +-----BEGIN CERTIFICATE----- +MIIB8jCCAXigAwIBAgITBmyf18G7EEwpQ+Vxe3ssyBrBDjAKBggqhkjOPQQDAzA5 +MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g +Um9vdCBDQSA0MB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkG +A1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJvb3Qg +Q0EgNDB2MBAGByqGSM49AgEGBSuBBAAiA2IABNKrijdPo1MN/sGKe0uoe0ZLY7Bi +9i0b2whxIdIA6GO9mif78DluXeo9pcmBqqNbIJhFXRbb/egQbeOc4OO9X4Ri83Bk +M6DLJC9wuoihKqB1+IGuYgbEgds5bimwHvouXKNCMEAwDwYDVR0TAQH/BAUwAwEB +/zAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0OBBYEFNPsxzplbszh2naaVvuc84ZtV+WB +MAoGCCqGSM49BAMDA2gAMGUCMDqLIfG9fhGt0O9Yli/W651+kI0rz2ZVwyzjKKlw +CkcO8DdZEv8tmZQoTipPNU0zWgIxAOp1AE47xDqUEpHJWEadIRNyp4iciuRMStuW +1KyLa2tJElMzrdfkviT8tQp21KW8EA== +-----END CERTIFICATE----- + +# Issuer: CN=TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1 O=Turkiye Bilimsel ve Teknolojik Arastirma Kurumu - TUBITAK OU=Kamu Sertifikasyon Merkezi - Kamu SM +# Subject: CN=TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1 O=Turkiye Bilimsel ve Teknolojik Arastirma Kurumu - TUBITAK OU=Kamu Sertifikasyon Merkezi - Kamu SM +# Label: "TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1" +# Serial: 1 +# MD5 Fingerprint: dc:00:81:dc:69:2f:3e:2f:b0:3b:f6:3d:5a:91:8e:49 +# SHA1 Fingerprint: 31:43:64:9b:ec:ce:27:ec:ed:3a:3f:0b:8f:0d:e4:e8:91:dd:ee:ca +# SHA256 Fingerprint: 46:ed:c3:68:90:46:d5:3a:45:3f:b3:10:4a:b8:0d:ca:ec:65:8b:26:60:ea:16:29:dd:7e:86:79:90:64:87:16 +-----BEGIN CERTIFICATE----- +MIIEYzCCA0ugAwIBAgIBATANBgkqhkiG9w0BAQsFADCB0jELMAkGA1UEBhMCVFIx +GDAWBgNVBAcTD0dlYnplIC0gS29jYWVsaTFCMEAGA1UEChM5VHVya2l5ZSBCaWxp +bXNlbCB2ZSBUZWtub2xvamlrIEFyYXN0aXJtYSBLdXJ1bXUgLSBUVUJJVEFLMS0w +KwYDVQQLEyRLYW11IFNlcnRpZmlrYXN5b24gTWVya2V6aSAtIEthbXUgU00xNjA0 +BgNVBAMTLVRVQklUQUsgS2FtdSBTTSBTU0wgS29rIFNlcnRpZmlrYXNpIC0gU3Vy +dW0gMTAeFw0xMzExMjUwODI1NTVaFw00MzEwMjUwODI1NTVaMIHSMQswCQYDVQQG +EwJUUjEYMBYGA1UEBxMPR2ViemUgLSBLb2NhZWxpMUIwQAYDVQQKEzlUdXJraXll +IEJpbGltc2VsIHZlIFRla25vbG9qaWsgQXJhc3Rpcm1hIEt1cnVtdSAtIFRVQklU +QUsxLTArBgNVBAsTJEthbXUgU2VydGlmaWthc3lvbiBNZXJrZXppIC0gS2FtdSBT +TTE2MDQGA1UEAxMtVFVCSVRBSyBLYW11IFNNIFNTTCBLb2sgU2VydGlmaWthc2kg +LSBTdXJ1bSAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAr3UwM6q7 +a9OZLBI3hNmNe5eA027n/5tQlT6QlVZC1xl8JoSNkvoBHToP4mQ4t4y86Ij5iySr +LqP1N+RAjhgleYN1Hzv/bKjFxlb4tO2KRKOrbEz8HdDc72i9z+SqzvBV96I01INr +N3wcwv61A+xXzry0tcXtAA9TNypN9E8Mg/uGz8v+jE69h/mniyFXnHrfA2eJLJ2X +YacQuFWQfw4tJzh03+f92k4S400VIgLI4OD8D62K18lUUMw7D8oWgITQUVbDjlZ/ +iSIzL+aFCr2lqBs23tPcLG07xxO9WSMs5uWk99gL7eqQQESolbuT1dCANLZGeA4f +AJNG4e7p+exPFwIDAQABo0IwQDAdBgNVHQ4EFgQUZT/HiobGPN08VFw1+DrtUgxH +V8gwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEL +BQADggEBACo/4fEyjq7hmFxLXs9rHmoJ0iKpEsdeV31zVmSAhHqT5Am5EM2fKifh +AHe+SMg1qIGf5LgsyX8OsNJLN13qudULXjS99HMpw+0mFZx+CFOKWI3QSyjfwbPf +IPP54+M638yclNhOT8NrF7f3cuitZjO1JVOr4PhMqZ398g26rrnZqsZr+ZO7rqu4 +lzwDGrpDxpa5RXI4s6ehlj2Re37AIVNMh+3yC1SVUZPVIqUNivGTDj5UDrDYyU7c +8jEyVupk+eq1nRZmQnLzf9OxMUP8pI4X8W0jq5Rm+K37DwhuJi1/FwcJsoz7UMCf +lo3Ptv0AnVoUmr8CRPXBwp8iXqIPoeM= +-----END CERTIFICATE----- + +# Issuer: CN=GDCA TrustAUTH R5 ROOT O=GUANG DONG CERTIFICATE AUTHORITY CO.,LTD. +# Subject: CN=GDCA TrustAUTH R5 ROOT O=GUANG DONG CERTIFICATE AUTHORITY CO.,LTD. +# Label: "GDCA TrustAUTH R5 ROOT" +# Serial: 9009899650740120186 +# MD5 Fingerprint: 63:cc:d9:3d:34:35:5c:6f:53:a3:e2:08:70:48:1f:b4 +# SHA1 Fingerprint: 0f:36:38:5b:81:1a:25:c3:9b:31:4e:83:ca:e9:34:66:70:cc:74:b4 +# SHA256 Fingerprint: bf:ff:8f:d0:44:33:48:7d:6a:8a:a6:0c:1a:29:76:7a:9f:c2:bb:b0:5e:42:0f:71:3a:13:b9:92:89:1d:38:93 +-----BEGIN CERTIFICATE----- +MIIFiDCCA3CgAwIBAgIIfQmX/vBH6nowDQYJKoZIhvcNAQELBQAwYjELMAkGA1UE +BhMCQ04xMjAwBgNVBAoMKUdVQU5HIERPTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZ +IENPLixMVEQuMR8wHQYDVQQDDBZHRENBIFRydXN0QVVUSCBSNSBST09UMB4XDTE0 +MTEyNjA1MTMxNVoXDTQwMTIzMTE1NTk1OVowYjELMAkGA1UEBhMCQ04xMjAwBgNV +BAoMKUdVQU5HIERPTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZIENPLixMVEQuMR8w +HQYDVQQDDBZHRENBIFRydXN0QVVUSCBSNSBST09UMIICIjANBgkqhkiG9w0BAQEF +AAOCAg8AMIICCgKCAgEA2aMW8Mh0dHeb7zMNOwZ+Vfy1YI92hhJCfVZmPoiC7XJj +Dp6L3TQsAlFRwxn9WVSEyfFrs0yw6ehGXTjGoqcuEVe6ghWinI9tsJlKCvLriXBj +TnnEt1u9ol2x8kECK62pOqPseQrsXzrj/e+APK00mxqriCZ7VqKChh/rNYmDf1+u +KU49tm7srsHwJ5uu4/Ts765/94Y9cnrrpftZTqfrlYwiOXnhLQiPzLyRuEH3FMEj +qcOtmkVEs7LXLM3GKeJQEK5cy4KOFxg2fZfmiJqwTTQJ9Cy5WmYqsBebnh52nUpm +MUHfP/vFBu8btn4aRjb3ZGM74zkYI+dndRTVdVeSN72+ahsmUPI2JgaQxXABZG12 +ZuGR224HwGGALrIuL4xwp9E7PLOR5G62xDtw8mySlwnNR30YwPO7ng/Wi64HtloP +zgsMR6flPri9fcebNaBhlzpBdRfMK5Z3KpIhHtmVdiBnaM8Nvd/WHwlqmuLMc3Gk +L30SgLdTMEZeS1SZD2fJpcjyIMGC7J0R38IC+xo70e0gmu9lZJIQDSri3nDxGGeC +jGHeuLzRL5z7D9Ar7Rt2ueQ5Vfj4oR24qoAATILnsn8JuLwwoC8N9VKejveSswoA +HQBUlwbgsQfZxw9cZX08bVlX5O2ljelAU58VS6Bx9hoh49pwBiFYFIeFd3mqgnkC +AwEAAaNCMEAwHQYDVR0OBBYEFOLJQJ9NzuiaoXzPDj9lxSmIahlRMA8GA1UdEwEB +/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQDRSVfg +p8xoWLoBDysZzY2wYUWsEe1jUGn4H3++Fo/9nesLqjJHdtJnJO29fDMylyrHBYZm +DRd9FBUb1Ov9H5r2XpdptxolpAqzkT9fNqyL7FeoPueBihhXOYV0GkLH6VsTX4/5 +COmSdI31R9KrO9b7eGZONn356ZLpBN79SWP8bfsUcZNnL0dKt7n/HipzcEYwv1ry +L3ml4Y0M2fmyYzeMN2WFcGpcWwlyua1jPLHd+PwyvzeG5LuOmCd+uh8W4XAR8gPf +JWIyJyYYMoSf/wA6E7qaTfRPuBRwIrHKK5DOKcFw9C+df/KQHtZa37dG/OaG+svg +IHZ6uqbL9XzeYqWxi+7egmaKTjowHz+Ay60nugxe19CxVsp3cbK1daFQqUBDF8Io +2c9Si1vIY9RCPqAzekYu9wogRlR+ak8x8YF+QnQ4ZXMn7sZ8uI7XpTrXmKGcjBBV +09tL7ECQ8s1uV9JiDnxXk7Gnbc2dg7sq5+W2O3FYrf3RRbxake5TFW/TRQl1brqQ +XR4EzzffHqhmsYzmIGrv/EhOdJhCrylvLmrH+33RZjEizIYAfmaDDEL0vTSSwxrq +T8p+ck0LcIymSLumoRT2+1hEmRSuqguTaaApJUqlyyvdimYHFngVV3Eb7PVHhPOe +MTd61X8kreS8/f3MboPoDKi3QWwH3b08hpcv0g== +-----END CERTIFICATE----- + +# Issuer: CN=TrustCor RootCert CA-1 O=TrustCor Systems S. de R.L. OU=TrustCor Certificate Authority +# Subject: CN=TrustCor RootCert CA-1 O=TrustCor Systems S. de R.L. OU=TrustCor Certificate Authority +# Label: "TrustCor RootCert CA-1" +# Serial: 15752444095811006489 +# MD5 Fingerprint: 6e:85:f1:dc:1a:00:d3:22:d5:b2:b2:ac:6b:37:05:45 +# SHA1 Fingerprint: ff:bd:cd:e7:82:c8:43:5e:3c:6f:26:86:5c:ca:a8:3a:45:5b:c3:0a +# SHA256 Fingerprint: d4:0e:9c:86:cd:8f:e4:68:c1:77:69:59:f4:9e:a7:74:fa:54:86:84:b6:c4:06:f3:90:92:61:f4:dc:e2:57:5c +-----BEGIN CERTIFICATE----- +MIIEMDCCAxigAwIBAgIJANqb7HHzA7AZMA0GCSqGSIb3DQEBCwUAMIGkMQswCQYD +VQQGEwJQQTEPMA0GA1UECAwGUGFuYW1hMRQwEgYDVQQHDAtQYW5hbWEgQ2l0eTEk +MCIGA1UECgwbVHJ1c3RDb3IgU3lzdGVtcyBTLiBkZSBSLkwuMScwJQYDVQQLDB5U +cnVzdENvciBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxHzAdBgNVBAMMFlRydXN0Q29y +IFJvb3RDZXJ0IENBLTEwHhcNMTYwMjA0MTIzMjE2WhcNMjkxMjMxMTcyMzE2WjCB +pDELMAkGA1UEBhMCUEExDzANBgNVBAgMBlBhbmFtYTEUMBIGA1UEBwwLUGFuYW1h +IENpdHkxJDAiBgNVBAoMG1RydXN0Q29yIFN5c3RlbXMgUy4gZGUgUi5MLjEnMCUG +A1UECwweVHJ1c3RDb3IgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MR8wHQYDVQQDDBZU +cnVzdENvciBSb290Q2VydCBDQS0xMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB +CgKCAQEAv463leLCJhJrMxnHQFgKq1mqjQCj/IDHUHuO1CAmujIS2CNUSSUQIpid +RtLByZ5OGy4sDjjzGiVoHKZaBeYei0i/mJZ0PmnK6bV4pQa81QBeCQryJ3pS/C3V +seq0iWEk8xoT26nPUu0MJLq5nux+AHT6k61sKZKuUbS701e/s/OojZz0JEsq1pme +9J7+wH5COucLlVPat2gOkEz7cD+PSiyU8ybdY2mplNgQTsVHCJCZGxdNuWxu72CV +EY4hgLW9oHPY0LJ3xEXqWib7ZnZ2+AYfYW0PVcWDtxBWcgYHpfOxGgMFZA6dWorW +hnAbJN7+KIor0Gqw/Hqi3LJ5DotlDwIDAQABo2MwYTAdBgNVHQ4EFgQU7mtJPHo/ +DeOxCbeKyKsZn3MzUOcwHwYDVR0jBBgwFoAU7mtJPHo/DeOxCbeKyKsZn3MzUOcw +DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQELBQAD +ggEBACUY1JGPE+6PHh0RU9otRCkZoB5rMZ5NDp6tPVxBb5UrJKF5mDo4Nvu7Zp5I +/5CQ7z3UuJu0h3U/IJvOcs+hVcFNZKIZBqEHMwwLKeXx6quj7LUKdJDHfXLy11yf +ke+Ri7fc7Waiz45mO7yfOgLgJ90WmMCV1Aqk5IGadZQ1nJBfiDcGrVmVCrDRZ9MZ +yonnMlo2HD6CqFqTvsbQZJG2z9m2GM/bftJlo6bEjhcxwft+dtvTheNYsnd6djts +L1Ac59v2Z3kf9YKVmgenFK+P3CghZwnS1k1aHBkcjndcw5QkPTJrS37UeJSDvjdN +zl/HHk484IkzlQsPpTLWPFp5LBk= +-----END CERTIFICATE----- + +# Issuer: CN=TrustCor RootCert CA-2 O=TrustCor Systems S. de R.L. OU=TrustCor Certificate Authority +# Subject: CN=TrustCor RootCert CA-2 O=TrustCor Systems S. de R.L. OU=TrustCor Certificate Authority +# Label: "TrustCor RootCert CA-2" +# Serial: 2711694510199101698 +# MD5 Fingerprint: a2:e1:f8:18:0b:ba:45:d5:c7:41:2a:bb:37:52:45:64 +# SHA1 Fingerprint: b8:be:6d:cb:56:f1:55:b9:63:d4:12:ca:4e:06:34:c7:94:b2:1c:c0 +# SHA256 Fingerprint: 07:53:e9:40:37:8c:1b:d5:e3:83:6e:39:5d:ae:a5:cb:83:9e:50:46:f1:bd:0e:ae:19:51:cf:10:fe:c7:c9:65 +-----BEGIN CERTIFICATE----- +MIIGLzCCBBegAwIBAgIIJaHfyjPLWQIwDQYJKoZIhvcNAQELBQAwgaQxCzAJBgNV +BAYTAlBBMQ8wDQYDVQQIDAZQYW5hbWExFDASBgNVBAcMC1BhbmFtYSBDaXR5MSQw +IgYDVQQKDBtUcnVzdENvciBTeXN0ZW1zIFMuIGRlIFIuTC4xJzAlBgNVBAsMHlRy +dXN0Q29yIENlcnRpZmljYXRlIEF1dGhvcml0eTEfMB0GA1UEAwwWVHJ1c3RDb3Ig +Um9vdENlcnQgQ0EtMjAeFw0xNjAyMDQxMjMyMjNaFw0zNDEyMzExNzI2MzlaMIGk +MQswCQYDVQQGEwJQQTEPMA0GA1UECAwGUGFuYW1hMRQwEgYDVQQHDAtQYW5hbWEg +Q2l0eTEkMCIGA1UECgwbVHJ1c3RDb3IgU3lzdGVtcyBTLiBkZSBSLkwuMScwJQYD +VQQLDB5UcnVzdENvciBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxHzAdBgNVBAMMFlRy +dXN0Q29yIFJvb3RDZXJ0IENBLTIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK +AoICAQCnIG7CKqJiJJWQdsg4foDSq8GbZQWU9MEKENUCrO2fk8eHyLAnK0IMPQo+ +QVqedd2NyuCb7GgypGmSaIwLgQ5WoD4a3SwlFIIvl9NkRvRUqdw6VC0xK5mC8tkq +1+9xALgxpL56JAfDQiDyitSSBBtlVkxs1Pu2YVpHI7TYabS3OtB0PAx1oYxOdqHp +2yqlO/rOsP9+aij9JxzIsekp8VduZLTQwRVtDr4uDkbIXvRR/u8OYzo7cbrPb1nK +DOObXUm4TOJXsZiKQlecdu/vvdFoqNL0Cbt3Nb4lggjEFixEIFapRBF37120Hape +az6LMvYHL1cEksr1/p3C6eizjkxLAjHZ5DxIgif3GIJ2SDpxsROhOdUuxTTCHWKF +3wP+TfSvPd9cW436cOGlfifHhi5qjxLGhF5DUVCcGZt45vz27Ud+ez1m7xMTiF88 +oWP7+ayHNZ/zgp6kPwqcMWmLmaSISo5uZk3vFsQPeSghYA2FFn3XVDjxklb9tTNM +g9zXEJ9L/cb4Qr26fHMC4P99zVvh1Kxhe1fVSntb1IVYJ12/+CtgrKAmrhQhJ8Z3 +mjOAPF5GP/fDsaOGM8boXg25NSyqRsGFAnWAoOsk+xWq5Gd/bnc/9ASKL3x74xdh +8N0JqSDIvgmk0H5Ew7IwSjiqqewYmgeCK9u4nBit2uBGF6zPXQIDAQABo2MwYTAd +BgNVHQ4EFgQU2f4hQG6UnrybPZx9mCAZ5YwwYrIwHwYDVR0jBBgwFoAU2f4hQG6U +nrybPZx9mCAZ5YwwYrIwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYw +DQYJKoZIhvcNAQELBQADggIBAJ5Fngw7tu/hOsh80QA9z+LqBrWyOrsGS2h60COX +dKcs8AjYeVrXWoSK2BKaG9l9XE1wxaX5q+WjiYndAfrs3fnpkpfbsEZC89NiqpX+ +MWcUaViQCqoL7jcjx1BRtPV+nuN79+TMQjItSQzL/0kMmx40/W5ulop5A7Zv2wnL +/V9lFDfhOPXzYRZY5LVtDQsEGz9QLX+zx3oaFoBg+Iof6Rsqxvm6ARppv9JYx1RX +CI/hOWB3S6xZhBqI8d3LT3jX5+EzLfzuQfogsL7L9ziUwOHQhQ+77Sxzq+3+knYa +ZH9bDTMJBzN7Bj8RpFxwPIXAz+OQqIN3+tvmxYxoZxBnpVIt8MSZj3+/0WvitUfW +2dCFmU2Umw9Lje4AWkcdEQOsQRivh7dvDDqPys/cA8GiCcjl/YBeyGBCARsaU1q7 +N6a3vLqE6R5sGtRk2tRD/pOLS/IseRYQ1JMLiI+h2IYURpFHmygk71dSTlxCnKr3 +Sewn6EAes6aJInKc9Q0ztFijMDvd1GpUk74aTfOTlPf8hAs/hCBcNANExdqtvArB +As8e5ZTZ845b2EzwnexhF7sUMlQMAimTHpKG9n/v55IFDlndmQguLvqcAFLTxWYp +5KeXRKQOKIETNcX2b2TmQcTVL8w0RSXPQQCWPUouwpaYT05KnJe32x+SMsj/D1Fu +1uwJ +-----END CERTIFICATE----- + +# Issuer: CN=TrustCor ECA-1 O=TrustCor Systems S. de R.L. OU=TrustCor Certificate Authority +# Subject: CN=TrustCor ECA-1 O=TrustCor Systems S. de R.L. OU=TrustCor Certificate Authority +# Label: "TrustCor ECA-1" +# Serial: 9548242946988625984 +# MD5 Fingerprint: 27:92:23:1d:0a:f5:40:7c:e9:e6:6b:9d:d8:f5:e7:6c +# SHA1 Fingerprint: 58:d1:df:95:95:67:6b:63:c0:f0:5b:1c:17:4d:8b:84:0b:c8:78:bd +# SHA256 Fingerprint: 5a:88:5d:b1:9c:01:d9:12:c5:75:93:88:93:8c:af:bb:df:03:1a:b2:d4:8e:91:ee:15:58:9b:42:97:1d:03:9c +-----BEGIN CERTIFICATE----- +MIIEIDCCAwigAwIBAgIJAISCLF8cYtBAMA0GCSqGSIb3DQEBCwUAMIGcMQswCQYD +VQQGEwJQQTEPMA0GA1UECAwGUGFuYW1hMRQwEgYDVQQHDAtQYW5hbWEgQ2l0eTEk +MCIGA1UECgwbVHJ1c3RDb3IgU3lzdGVtcyBTLiBkZSBSLkwuMScwJQYDVQQLDB5U +cnVzdENvciBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxFzAVBgNVBAMMDlRydXN0Q29y +IEVDQS0xMB4XDTE2MDIwNDEyMzIzM1oXDTI5MTIzMTE3MjgwN1owgZwxCzAJBgNV +BAYTAlBBMQ8wDQYDVQQIDAZQYW5hbWExFDASBgNVBAcMC1BhbmFtYSBDaXR5MSQw +IgYDVQQKDBtUcnVzdENvciBTeXN0ZW1zIFMuIGRlIFIuTC4xJzAlBgNVBAsMHlRy +dXN0Q29yIENlcnRpZmljYXRlIEF1dGhvcml0eTEXMBUGA1UEAwwOVHJ1c3RDb3Ig +RUNBLTEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDPj+ARtZ+odnbb +3w9U73NjKYKtR8aja+3+XzP4Q1HpGjORMRegdMTUpwHmspI+ap3tDvl0mEDTPwOA +BoJA6LHip1GnHYMma6ve+heRK9jGrB6xnhkB1Zem6g23xFUfJ3zSCNV2HykVh0A5 +3ThFEXXQmqc04L/NyFIduUd+Dbi7xgz2c1cWWn5DkR9VOsZtRASqnKmcp0yJF4Ou +owReUoCLHhIlERnXDH19MURB6tuvsBzvgdAsxZohmz3tQjtQJvLsznFhBmIhVE5/ +wZ0+fyCMgMsq2JdiyIMzkX2woloPV+g7zPIlstR8L+xNxqE6FXrntl019fZISjZF +ZtS6mFjBAgMBAAGjYzBhMB0GA1UdDgQWBBREnkj1zG1I1KBLf/5ZJC+Dl5mahjAf +BgNVHSMEGDAWgBREnkj1zG1I1KBLf/5ZJC+Dl5mahjAPBgNVHRMBAf8EBTADAQH/ +MA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAQEABT41XBVwm8nHc2Fv +civUwo/yQ10CzsSUuZQRg2dd4mdsdXa/uwyqNsatR5Nj3B5+1t4u/ukZMjgDfxT2 +AHMsWbEhBuH7rBiVDKP/mZb3Kyeb1STMHd3BOuCYRLDE5D53sXOpZCz2HAF8P11F +hcCF5yWPldwX8zyfGm6wyuMdKulMY/okYWLW2n62HGz1Ah3UKt1VkOsqEUc8Ll50 +soIipX1TH0XsJ5F95yIW6MBoNtjG8U+ARDL54dHRHareqKucBK+tIA5kmE2la8BI +WJZpTdwHjFGTot+fDz2LYLSCjaoITmJF4PkL0uDgPFveXHEnJcLmA4GLEFPjx1Wi +tJ/X5g== +-----END CERTIFICATE----- + +# Issuer: CN=SSL.com Root Certification Authority RSA O=SSL Corporation +# Subject: CN=SSL.com Root Certification Authority RSA O=SSL Corporation +# Label: "SSL.com Root Certification Authority RSA" +# Serial: 8875640296558310041 +# MD5 Fingerprint: 86:69:12:c0:70:f1:ec:ac:ac:c2:d5:bc:a5:5b:a1:29 +# SHA1 Fingerprint: b7:ab:33:08:d1:ea:44:77:ba:14:80:12:5a:6f:bd:a9:36:49:0c:bb +# SHA256 Fingerprint: 85:66:6a:56:2e:e0:be:5c:e9:25:c1:d8:89:0a:6f:76:a8:7e:c1:6d:4d:7d:5f:29:ea:74:19:cf:20:12:3b:69 +-----BEGIN CERTIFICATE----- +MIIF3TCCA8WgAwIBAgIIeyyb0xaAMpkwDQYJKoZIhvcNAQELBQAwfDELMAkGA1UE +BhMCVVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQK +DA9TU0wgQ29ycG9yYXRpb24xMTAvBgNVBAMMKFNTTC5jb20gUm9vdCBDZXJ0aWZp +Y2F0aW9uIEF1dGhvcml0eSBSU0EwHhcNMTYwMjEyMTczOTM5WhcNNDEwMjEyMTcz +OTM5WjB8MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hv +dXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjExMC8GA1UEAwwoU1NMLmNv +bSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IFJTQTCCAiIwDQYJKoZIhvcN +AQEBBQADggIPADCCAgoCggIBAPkP3aMrfcvQKv7sZ4Wm5y4bunfh4/WvpOz6Sl2R +xFdHaxh3a3by/ZPkPQ/CFp4LZsNWlJ4Xg4XOVu/yFv0AYvUiCVToZRdOQbngT0aX +qhvIuG5iXmmxX9sqAn78bMrzQdjt0Oj8P2FI7bADFB0QDksZ4LtO7IZl/zbzXmcC +C52GVWH9ejjt/uIZALdvoVBidXQ8oPrIJZK0bnoix/geoeOy3ZExqysdBP+lSgQ3 +6YWkMyv94tZVNHwZpEpox7Ko07fKoZOI68GXvIz5HdkihCR0xwQ9aqkpk8zruFvh +/l8lqjRYyMEjVJ0bmBHDOJx+PYZspQ9AhnwC9FwCTyjLrnGfDzrIM/4RJTXq/LrF +YD3ZfBjVsqnTdXgDciLKOsMf7yzlLqn6niy2UUb9rwPW6mBo6oUWNmuF6R7As93E +JNyAKoFBbZQ+yODJgUEAnl6/f8UImKIYLEJAs/lvOCdLToD0PYFH4Ih86hzOtXVc +US4cK38acijnALXRdMbX5J+tB5O2UzU1/Dfkw/ZdFr4hc96SCvigY2q8lpJqPvi8 +ZVWb3vUNiSYE/CUapiVpy8JtynziWV+XrOvvLsi81xtZPCvM8hnIk2snYxnP/Okm ++Mpxm3+T/jRnhE6Z6/yzeAkzcLpmpnbtG3PrGqUNxCITIJRWCk4sbE6x/c+cCbqi +M+2HAgMBAAGjYzBhMB0GA1UdDgQWBBTdBAkHovV6fVJTEpKV7jiAJQ2mWTAPBgNV +HRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFN0ECQei9Xp9UlMSkpXuOIAlDaZZMA4G +A1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAIBgRlCn7Jp0cHh5wYfGV +cpNxJK1ok1iOMq8bs3AD/CUrdIWQPXhq9LmLpZc7tRiRux6n+UBbkflVma8eEdBc +Hadm47GUBwwyOabqG7B52B2ccETjit3E+ZUfijhDPwGFpUenPUayvOUiaPd7nNgs +PgohyC0zrL/FgZkxdMF1ccW+sfAjRfSda/wZY52jvATGGAslu1OJD7OAUN5F7kR/ +q5R4ZJjT9ijdh9hwZXT7DrkT66cPYakylszeu+1jTBi7qUD3oFRuIIhxdRjqerQ0 +cuAjJ3dctpDqhiVAq+8zD8ufgr6iIPv2tS0a5sKFsXQP+8hlAqRSAUfdSSLBv9jr +a6x+3uxjMxW3IwiPxg+NQVrdjsW5j+VFP3jbutIbQLH+cU0/4IGiul607BXgk90I +H37hVZkLId6Tngr75qNJvTYw/ud3sqB1l7UtgYgXZSD32pAAn8lSzDLKNXz1PQ/Y +K9f1JmzJBjSWFupwWRoyeXkLtoh/D1JIPb9s2KJELtFOt3JY04kTlf5Eq/jXixtu +nLwsoFvVagCvXzfh1foQC5ichucmj87w7G6KVwuA406ywKBjYZC6VWg3dGq2ktuf +oYYitmUnDuy2n0Jg5GfCtdpBC8TTi2EbvPofkSvXRAdeuims2cXp71NIWuuA8ShY +Ic2wBlX7Jz9TkHCpBB5XJ7k= +-----END CERTIFICATE----- + +# Issuer: CN=SSL.com Root Certification Authority ECC O=SSL Corporation +# Subject: CN=SSL.com Root Certification Authority ECC O=SSL Corporation +# Label: "SSL.com Root Certification Authority ECC" +# Serial: 8495723813297216424 +# MD5 Fingerprint: 2e:da:e4:39:7f:9c:8f:37:d1:70:9f:26:17:51:3a:8e +# SHA1 Fingerprint: c3:19:7c:39:24:e6:54:af:1b:c4:ab:20:95:7a:e2:c3:0e:13:02:6a +# SHA256 Fingerprint: 34:17:bb:06:cc:60:07:da:1b:96:1c:92:0b:8a:b4:ce:3f:ad:82:0e:4a:a3:0b:9a:cb:c4:a7:4e:bd:ce:bc:65 +-----BEGIN CERTIFICATE----- +MIICjTCCAhSgAwIBAgIIdebfy8FoW6gwCgYIKoZIzj0EAwIwfDELMAkGA1UEBhMC +VVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9T +U0wgQ29ycG9yYXRpb24xMTAvBgNVBAMMKFNTTC5jb20gUm9vdCBDZXJ0aWZpY2F0 +aW9uIEF1dGhvcml0eSBFQ0MwHhcNMTYwMjEyMTgxNDAzWhcNNDEwMjEyMTgxNDAz +WjB8MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hvdXN0 +b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjExMC8GA1UEAwwoU1NMLmNvbSBS +b290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQzB2MBAGByqGSM49AgEGBSuB +BAAiA2IABEVuqVDEpiM2nl8ojRfLliJkP9x6jh3MCLOicSS6jkm5BBtHllirLZXI +7Z4INcgn64mMU1jrYor+8FsPazFSY0E7ic3s7LaNGdM0B9y7xgZ/wkWV7Mt/qCPg +CemB+vNH06NjMGEwHQYDVR0OBBYEFILRhXMw5zUE044CkvvlpNHEIejNMA8GA1Ud +EwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUgtGFczDnNQTTjgKS++Wk0cQh6M0wDgYD +VR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2cAMGQCMG/n61kRpGDPYbCWe+0F+S8T +kdzt5fxQaxFGRrMcIQBiu77D5+jNB5n5DQtdcj7EqgIwH7y6C+IwJPt8bYBVCpk+ +gA0z5Wajs6O7pdWLjwkspl1+4vAHCGht0nxpbl/f5Wpl +-----END CERTIFICATE----- + +# Issuer: CN=SSL.com EV Root Certification Authority RSA R2 O=SSL Corporation +# Subject: CN=SSL.com EV Root Certification Authority RSA R2 O=SSL Corporation +# Label: "SSL.com EV Root Certification Authority RSA R2" +# Serial: 6248227494352943350 +# MD5 Fingerprint: e1:1e:31:58:1a:ae:54:53:02:f6:17:6a:11:7b:4d:95 +# SHA1 Fingerprint: 74:3a:f0:52:9b:d0:32:a0:f4:4a:83:cd:d4:ba:a9:7b:7c:2e:c4:9a +# SHA256 Fingerprint: 2e:7b:f1:6c:c2:24:85:a7:bb:e2:aa:86:96:75:07:61:b0:ae:39:be:3b:2f:e9:d0:cc:6d:4e:f7:34:91:42:5c +-----BEGIN CERTIFICATE----- +MIIF6zCCA9OgAwIBAgIIVrYpzTS8ePYwDQYJKoZIhvcNAQELBQAwgYIxCzAJBgNV +BAYTAlVTMQ4wDAYDVQQIDAVUZXhhczEQMA4GA1UEBwwHSG91c3RvbjEYMBYGA1UE +CgwPU1NMIENvcnBvcmF0aW9uMTcwNQYDVQQDDC5TU0wuY29tIEVWIFJvb3QgQ2Vy +dGlmaWNhdGlvbiBBdXRob3JpdHkgUlNBIFIyMB4XDTE3MDUzMTE4MTQzN1oXDTQy +MDUzMDE4MTQzN1owgYIxCzAJBgNVBAYTAlVTMQ4wDAYDVQQIDAVUZXhhczEQMA4G +A1UEBwwHSG91c3RvbjEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMTcwNQYDVQQD +DC5TU0wuY29tIEVWIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgUlNBIFIy +MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAjzZlQOHWTcDXtOlG2mvq +M0fNTPl9fb69LT3w23jhhqXZuglXaO1XPqDQCEGD5yhBJB/jchXQARr7XnAjssuf +OePPxU7Gkm0mxnu7s9onnQqG6YE3Bf7wcXHswxzpY6IXFJ3vG2fThVUCAtZJycxa +4bH3bzKfydQ7iEGonL3Lq9ttewkfokxykNorCPzPPFTOZw+oz12WGQvE43LrrdF9 +HSfvkusQv1vrO6/PgN3B0pYEW3p+pKk8OHakYo6gOV7qd89dAFmPZiw+B6KjBSYR +aZfqhbcPlgtLyEDhULouisv3D5oi53+aNxPN8k0TayHRwMwi8qFG9kRpnMphNQcA +b9ZhCBHqurj26bNg5U257J8UZslXWNvNh2n4ioYSA0e/ZhN2rHd9NCSFg83XqpyQ +Gp8hLH94t2S42Oim9HizVcuE0jLEeK6jj2HdzghTreyI/BXkmg3mnxp3zkyPuBQV +PWKchjgGAGYS5Fl2WlPAApiiECtoRHuOec4zSnaqW4EWG7WK2NAAe15itAnWhmMO +pgWVSbooi4iTsjQc2KRVbrcc0N6ZVTsj9CLg+SlmJuwgUHfbSguPvuUCYHBBXtSu +UDkiFCbLsjtzdFVHB3mBOagwE0TlBIqulhMlQg+5U8Sb/M3kHN48+qvWBkofZ6aY +MBzdLNvcGJVXZsb/XItW9XcCAwEAAaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAfBgNV +HSMEGDAWgBT5YLvU49U09rj1BoAlp3PbRmmonjAdBgNVHQ4EFgQU+WC71OPVNPa4 +9QaAJadz20ZpqJ4wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQBW +s47LCp1Jjr+kxJG7ZhcFUZh1++VQLHqe8RT6q9OKPv+RKY9ji9i0qVQBDb6Thi/5 +Sm3HXvVX+cpVHBK+Rw82xd9qt9t1wkclf7nxY/hoLVUE0fKNsKTPvDxeH3jnpaAg +cLAExbf3cqfeIg29MyVGjGSSJuM+LmOW2puMPfgYCdcDzH2GguDKBAdRUNf/ktUM +79qGn5nX67evaOI5JpS6aLe/g9Pqemc9YmeuJeVy6OLk7K4S9ksrPJ/psEDzOFSz +/bdoyNrGj1E8svuR3Bznm53htw1yj+KkxKl4+esUrMZDBcJlOSgYAsOCsp0FvmXt +ll9ldDz7CTUue5wT/RsPXcdtgTpWD8w74a8CLyKsRspGPKAcTNZEtF4uXBVmCeEm +Kf7GUmG6sXP/wwyc5WxqlD8UykAWlYTzWamsX0xhk23RO8yilQwipmdnRC652dKK +QbNmC1r7fSOl8hqw/96bg5Qu0T/fkreRrwU7ZcegbLHNYhLDkBvjJc40vG93drEQ +w/cFGsDWr3RiSBd3kmmQYRzelYB0VI8YHMPzA9C/pEN1hlMYegouCRw2n5H9gooi +S9EOUCXdywMMF8mDAAhONU2Ki+3wApRmLER/y5UnlhetCTCstnEXbosX9hwJ1C07 +mKVx01QT2WDz9UtmT/rx7iASjbSsV7FFY6GsdqnC+w== +-----END CERTIFICATE----- + +# Issuer: CN=SSL.com EV Root Certification Authority ECC O=SSL Corporation +# Subject: CN=SSL.com EV Root Certification Authority ECC O=SSL Corporation +# Label: "SSL.com EV Root Certification Authority ECC" +# Serial: 3182246526754555285 +# MD5 Fingerprint: 59:53:22:65:83:42:01:54:c0:ce:42:b9:5a:7c:f2:90 +# SHA1 Fingerprint: 4c:dd:51:a3:d1:f5:20:32:14:b0:c6:c5:32:23:03:91:c7:46:42:6d +# SHA256 Fingerprint: 22:a2:c1:f7:bd:ed:70:4c:c1:e7:01:b5:f4:08:c3:10:88:0f:e9:56:b5:de:2a:4a:44:f9:9c:87:3a:25:a7:c8 +-----BEGIN CERTIFICATE----- +MIIClDCCAhqgAwIBAgIILCmcWxbtBZUwCgYIKoZIzj0EAwIwfzELMAkGA1UEBhMC +VVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9T +U0wgQ29ycG9yYXRpb24xNDAyBgNVBAMMK1NTTC5jb20gRVYgUm9vdCBDZXJ0aWZp +Y2F0aW9uIEF1dGhvcml0eSBFQ0MwHhcNMTYwMjEyMTgxNTIzWhcNNDEwMjEyMTgx +NTIzWjB/MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hv +dXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjE0MDIGA1UEAwwrU1NMLmNv +bSBFViBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQzB2MBAGByqGSM49 +AgEGBSuBBAAiA2IABKoSR5CYG/vvw0AHgyBO8TCCogbR8pKGYfL2IWjKAMTH6kMA +VIbc/R/fALhBYlzccBYy3h+Z1MzFB8gIH2EWB1E9fVwHU+M1OIzfzZ/ZLg1Kthku +WnBaBu2+8KGwytAJKaNjMGEwHQYDVR0OBBYEFFvKXuXe0oGqzagtZFG22XKbl+ZP +MA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUW8pe5d7SgarNqC1kUbbZcpuX +5k8wDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2gAMGUCMQCK5kCJN+vp1RPZ +ytRrJPOwPYdGWBrssd9v+1a6cGvHOMzosYxPD/fxZ3YOg9AeUY8CMD32IygmTMZg +h5Mmm7I1HrrW9zzRHM76JTymGoEVW/MSD2zuZYrJh6j5B+BimoxcSg== +-----END CERTIFICATE----- + +# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R6 +# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R6 +# Label: "GlobalSign Root CA - R6" +# Serial: 1417766617973444989252670301619537 +# MD5 Fingerprint: 4f:dd:07:e4:d4:22:64:39:1e:0c:37:42:ea:d1:c6:ae +# SHA1 Fingerprint: 80:94:64:0e:b5:a7:a1:ca:11:9c:1f:dd:d5:9f:81:02:63:a7:fb:d1 +# SHA256 Fingerprint: 2c:ab:ea:fe:37:d0:6c:a2:2a:ba:73:91:c0:03:3d:25:98:29:52:c4:53:64:73:49:76:3a:3a:b5:ad:6c:cf:69 +-----BEGIN CERTIFICATE----- +MIIFgzCCA2ugAwIBAgIORea7A4Mzw4VlSOb/RVEwDQYJKoZIhvcNAQEMBQAwTDEg +MB4GA1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjYxEzARBgNVBAoTCkdsb2Jh +bFNpZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMTQxMjEwMDAwMDAwWhcNMzQx +MjEwMDAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSNjET +MBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCAiIwDQYJ +KoZIhvcNAQEBBQADggIPADCCAgoCggIBAJUH6HPKZvnsFMp7PPcNCPG0RQssgrRI +xutbPK6DuEGSMxSkb3/pKszGsIhrxbaJ0cay/xTOURQh7ErdG1rG1ofuTToVBu1k +ZguSgMpE3nOUTvOniX9PeGMIyBJQbUJmL025eShNUhqKGoC3GYEOfsSKvGRMIRxD +aNc9PIrFsmbVkJq3MQbFvuJtMgamHvm566qjuL++gmNQ0PAYid/kD3n16qIfKtJw +LnvnvJO7bVPiSHyMEAc4/2ayd2F+4OqMPKq0pPbzlUoSB239jLKJz9CgYXfIWHSw +1CM69106yqLbnQneXUQtkPGBzVeS+n68UARjNN9rkxi+azayOeSsJDa38O+2HBNX +k7besvjihbdzorg1qkXy4J02oW9UivFyVm4uiMVRQkQVlO6jxTiWm05OWgtH8wY2 +SXcwvHE35absIQh1/OZhFj931dmRl4QKbNQCTXTAFO39OfuD8l4UoQSwC+n+7o/h +bguyCLNhZglqsQY6ZZZZwPA1/cnaKI0aEYdwgQqomnUdnjqGBQCe24DWJfncBZ4n +WUx2OVvq+aWh2IMP0f/fMBH5hc8zSPXKbWQULHpYT9NLCEnFlWQaYw55PfWzjMpY +rZxCRXluDocZXFSxZba/jJvcE+kNb7gu3GduyYsRtYQUigAZcIN5kZeR1Bonvzce +MgfYFGM8KEyvAgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTAD +AQH/MB0GA1UdDgQWBBSubAWjkxPioufi1xzWx/B/yGdToDAfBgNVHSMEGDAWgBSu +bAWjkxPioufi1xzWx/B/yGdToDANBgkqhkiG9w0BAQwFAAOCAgEAgyXt6NH9lVLN +nsAEoJFp5lzQhN7craJP6Ed41mWYqVuoPId8AorRbrcWc+ZfwFSY1XS+wc3iEZGt +Ixg93eFyRJa0lV7Ae46ZeBZDE1ZXs6KzO7V33EByrKPrmzU+sQghoefEQzd5Mr61 +55wsTLxDKZmOMNOsIeDjHfrYBzN2VAAiKrlNIC5waNrlU/yDXNOd8v9EDERm8tLj +vUYAGm0CuiVdjaExUd1URhxN25mW7xocBFymFe944Hn+Xds+qkxV/ZoVqW/hpvvf +cDDpw+5CRu3CkwWJ+n1jez/QcYF8AOiYrg54NMMl+68KnyBr3TsTjxKM4kEaSHpz +oHdpx7Zcf4LIHv5YGygrqGytXm3ABdJ7t+uA/iU3/gKbaKxCXcPu9czc8FB10jZp +nOZ7BN9uBmm23goJSFmH63sUYHpkqmlD75HHTOwY3WzvUy2MmeFe8nI+z1TIvWfs +pA9MRf/TuTAjB0yPEL+GltmZWrSZVxykzLsViVO6LAUP5MSeGbEYNNVMnbrt9x+v +JJUEeKgDu+6B5dpffItKoZB0JaezPkvILFa9x8jvOOJckvB595yEunQtYQEgfn7R +8k8HWV+LLUNS60YMlOH1Zkd5d9VUWx+tJDfLRVpOoERIyNiwmcUVhAn21klJwGW4 +5hpxbqCo8YLoRT5s1gLXCmeDBVrJpBA= +-----END CERTIFICATE----- + +# Issuer: CN=OISTE WISeKey Global Root GC CA O=WISeKey OU=OISTE Foundation Endorsed +# Subject: CN=OISTE WISeKey Global Root GC CA O=WISeKey OU=OISTE Foundation Endorsed +# Label: "OISTE WISeKey Global Root GC CA" +# Serial: 44084345621038548146064804565436152554 +# MD5 Fingerprint: a9:d6:b9:2d:2f:93:64:f8:a5:69:ca:91:e9:68:07:23 +# SHA1 Fingerprint: e0:11:84:5e:34:de:be:88:81:b9:9c:f6:16:26:d1:96:1f:c3:b9:31 +# SHA256 Fingerprint: 85:60:f9:1c:36:24:da:ba:95:70:b5:fe:a0:db:e3:6f:f1:1a:83:23:be:94:86:85:4f:b3:f3:4a:55:71:19:8d +-----BEGIN CERTIFICATE----- +MIICaTCCAe+gAwIBAgIQISpWDK7aDKtARb8roi066jAKBggqhkjOPQQDAzBtMQsw +CQYDVQQGEwJDSDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUgRm91 +bmRhdGlvbiBFbmRvcnNlZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9iYWwg +Um9vdCBHQyBDQTAeFw0xNzA1MDkwOTQ4MzRaFw00MjA1MDkwOTU4MzNaMG0xCzAJ +BgNVBAYTAkNIMRAwDgYDVQQKEwdXSVNlS2V5MSIwIAYDVQQLExlPSVNURSBGb3Vu +ZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5IEdsb2JhbCBS +b290IEdDIENBMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAETOlQwMYPchi82PG6s4ni +eUqjFqdrVCTbUf/q9Akkwwsin8tqJ4KBDdLArzHkdIJuyiXZjHWd8dvQmqJLIX4W +p2OQ0jnUsYd4XxiWD1AbNTcPasbc2RNNpI6QN+a9WzGRo1QwUjAOBgNVHQ8BAf8E +BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUSIcUrOPDnpBgOtfKie7T +rYy0UGYwEAYJKwYBBAGCNxUBBAMCAQAwCgYIKoZIzj0EAwMDaAAwZQIwJsdpW9zV +57LnyAyMjMPdeYwbY9XJUpROTYJKcx6ygISpJcBMWm1JKWB4E+J+SOtkAjEA2zQg +Mgj/mkkCtojeFK9dbJlxjRo/i9fgojaGHAeCOnZT/cKi7e97sIBPWA9LUzm9 +-----END CERTIFICATE----- + +# Issuer: CN=GTS Root R1 O=Google Trust Services LLC +# Subject: CN=GTS Root R1 O=Google Trust Services LLC +# Label: "GTS Root R1" +# Serial: 146587175971765017618439757810265552097 +# MD5 Fingerprint: 82:1a:ef:d4:d2:4a:f2:9f:e2:3d:97:06:14:70:72:85 +# SHA1 Fingerprint: e1:c9:50:e6:ef:22:f8:4c:56:45:72:8b:92:20:60:d7:d5:a7:a3:e8 +# SHA256 Fingerprint: 2a:57:54:71:e3:13:40:bc:21:58:1c:bd:2c:f1:3e:15:84:63:20:3e:ce:94:bc:f9:d3:cc:19:6b:f0:9a:54:72 +-----BEGIN CERTIFICATE----- +MIIFWjCCA0KgAwIBAgIQbkepxUtHDA3sM9CJuRz04TANBgkqhkiG9w0BAQwFADBH +MQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExM +QzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIy +MDAwMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNl +cnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwggIiMA0GCSqGSIb3DQEB +AQUAA4ICDwAwggIKAoICAQC2EQKLHuOhd5s73L+UPreVp0A8of2C+X0yBoJx9vaM +f/vo27xqLpeXo4xL+Sv2sfnOhB2x+cWX3u+58qPpvBKJXqeqUqv4IyfLpLGcY9vX +mX7wCl7raKb0xlpHDU0QM+NOsROjyBhsS+z8CZDfnWQpJSMHobTSPS5g4M/SCYe7 +zUjwTcLCeoiKu7rPWRnWr4+wB7CeMfGCwcDfLqZtbBkOtdh+JhpFAz2weaSUKK0P +fyblqAj+lug8aJRT7oM6iCsVlgmy4HqMLnXWnOunVmSPlk9orj2XwoSPwLxAwAtc +vfaHszVsrBhQf4TgTM2S0yDpM7xSma8ytSmzJSq0SPly4cpk9+aCEI3oncKKiPo4 +Zor8Y/kB+Xj9e1x3+naH+uzfsQ55lVe0vSbv1gHR6xYKu44LtcXFilWr06zqkUsp +zBmkMiVOKvFlRNACzqrOSbTqn3yDsEB750Orp2yjj32JgfpMpf/VjsPOS+C12LOO +Rc92wO1AK/1TD7Cn1TsNsYqiA94xrcx36m97PtbfkSIS5r762DL8EGMUUXLeXdYW +k70paDPvOmbsB4om3xPXV2V4J95eSRQAogB/mqghtqmxlbCluQ0WEdrHbEg8QOB+ +DVrNVjzRlwW5y0vtOUucxD/SVRNuJLDWcfr0wbrM7Rv1/oFB2ACYPTrIrnqYNxgF +lQIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV +HQ4EFgQU5K8rJnEaK0gnhS9SZizv8IkTcT4wDQYJKoZIhvcNAQEMBQADggIBADiW +Cu49tJYeX++dnAsznyvgyv3SjgofQXSlfKqE1OXyHuY3UjKcC9FhHb8owbZEKTV1 +d5iyfNm9dKyKaOOpMQkpAWBz40d8U6iQSifvS9efk+eCNs6aaAyC58/UEBZvXw6Z +XPYfcX3v73svfuo21pdwCxXu11xWajOl40k4DLh9+42FpLFZXvRq4d2h9mREruZR +gyFmxhE+885H7pwoHyXa/6xmld01D1zvICxi/ZG6qcz8WpyTgYMpl0p8WnK0OdC3 +d8t5/Wk6kjftbjhlRn7pYL15iJdfOBL07q9bgsiG1eGZbYwE8na6SfZu6W0eX6Dv +J4J2QPim01hcDyxC2kLGe4g0x8HYRZvBPsVhHdljUEn2NIVq4BjFbkerQUIpm/Zg +DdIx02OYI5NaAIFItO/Nis3Jz5nu2Z6qNuFoS3FJFDYoOj0dzpqPJeaAcWErtXvM ++SUWgeExX6GjfhaknBZqlxi9dnKlC54dNuYvoS++cJEPqOba+MSSQGwlfnuzCdyy +F62ARPBopY+Udf90WuioAnwMCeKpSwughQtiue+hMZL77/ZRBIls6Kl0obsXs7X9 +SQ98POyDGCBDTtWTurQ0sR8WNh8M5mQ5Fkzc4P4dyKliPUDqysU0ArSuiYgzNdws +E3PYJ/HQcu51OyLemGhmW/HGY0dVHLqlCFF1pkgl +-----END CERTIFICATE----- + +# Issuer: CN=GTS Root R2 O=Google Trust Services LLC +# Subject: CN=GTS Root R2 O=Google Trust Services LLC +# Label: "GTS Root R2" +# Serial: 146587176055767053814479386953112547951 +# MD5 Fingerprint: 44:ed:9a:0e:a4:09:3b:00:f2:ae:4c:a3:c6:61:b0:8b +# SHA1 Fingerprint: d2:73:96:2a:2a:5e:39:9f:73:3f:e1:c7:1e:64:3f:03:38:34:fc:4d +# SHA256 Fingerprint: c4:5d:7b:b0:8e:6d:67:e6:2e:42:35:11:0b:56:4e:5f:78:fd:92:ef:05:8c:84:0a:ea:4e:64:55:d7:58:5c:60 +-----BEGIN CERTIFICATE----- +MIIFWjCCA0KgAwIBAgIQbkepxlqz5yDFMJo/aFLybzANBgkqhkiG9w0BAQwFADBH +MQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExM +QzEUMBIGA1UEAxMLR1RTIFJvb3QgUjIwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIy +MDAwMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNl +cnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjIwggIiMA0GCSqGSIb3DQEB +AQUAA4ICDwAwggIKAoICAQDO3v2m++zsFDQ8BwZabFn3GTXd98GdVarTzTukk3Lv +CvptnfbwhYBboUhSnznFt+4orO/LdmgUud+tAWyZH8QiHZ/+cnfgLFuv5AS/T3Kg +GjSY6Dlo7JUle3ah5mm5hRm9iYz+re026nO8/4Piy33B0s5Ks40FnotJk9/BW9Bu +XvAuMC6C/Pq8tBcKSOWIm8Wba96wyrQD8Nr0kLhlZPdcTK3ofmZemde4wj7I0BOd +re7kRXuJVfeKH2JShBKzwkCX44ofR5GmdFrS+LFjKBC4swm4VndAoiaYecb+3yXu +PuWgf9RhD1FLPD+M2uFwdNjCaKH5wQzpoeJ/u1U8dgbuak7MkogwTZq9TwtImoS1 +mKPV+3PBV2HdKFZ1E66HjucMUQkQdYhMvI35ezzUIkgfKtzra7tEscszcTJGr61K +8YzodDqs5xoic4DSMPclQsciOzsSrZYuxsN2B6ogtzVJV+mSSeh2FnIxZyuWfoqj +x5RWIr9qS34BIbIjMt/kmkRtWVtd9QCgHJvGeJeNkP+byKq0rxFROV7Z+2et1VsR +nTKaG73VululycslaVNVJ1zgyjbLiGH7HrfQy+4W+9OmTN6SpdTi3/UGVN4unUu0 +kzCqgc7dGtxRcw1PcOnlthYhGXmy5okLdWTK1au8CcEYof/UVKGFPP0UJAOyh9Ok +twIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV +HQ4EFgQUu//KjiOfT5nK2+JopqUVJxce2Q4wDQYJKoZIhvcNAQEMBQADggIBALZp +8KZ3/p7uC4Gt4cCpx/k1HUCCq+YEtN/L9x0Pg/B+E02NjO7jMyLDOfxA325BS0JT +vhaI8dI4XsRomRyYUpOM52jtG2pzegVATX9lO9ZY8c6DR2Dj/5epnGB3GFW1fgiT +z9D2PGcDFWEJ+YF59exTpJ/JjwGLc8R3dtyDovUMSRqodt6Sm2T4syzFJ9MHwAiA +pJiS4wGWAqoC7o87xdFtCjMwc3i5T1QWvwsHoaRc5svJXISPD+AVdyx+Jn7axEvb +pxZ3B7DNdehyQtaVhJ2Gg/LkkM0JR9SLA3DaWsYDQvTtN6LwG1BUSw7YhN4ZKJmB +R64JGz9I0cNv4rBgF/XuIwKl2gBbbZCr7qLpGzvpx0QnRY5rn/WkhLx3+WuXrD5R +RaIRpsyF7gpo8j5QOHokYh4XIDdtak23CZvJ/KRY9bb7nE4Yu5UC56GtmwfuNmsk +0jmGwZODUNKBRqhfYlcsu2xkiAhu7xNUX90txGdj08+JN7+dIPT7eoOboB6BAFDC +5AwiWVIQ7UNWhwD4FFKnHYuTjKJNRn8nxnGbJN7k2oaLDX5rIMHAnuFl2GqjpuiF +izoHCBy69Y9Vmhh1fuXsgWbRIXOhNUQLgD1bnF5vKheW0YMjiGZt5obicDIvUiLn +yOd/xCxgXS/Dr55FBcOEArf9LAhST4Ldo/DUhgkC +-----END CERTIFICATE----- + +# Issuer: CN=GTS Root R3 O=Google Trust Services LLC +# Subject: CN=GTS Root R3 O=Google Trust Services LLC +# Label: "GTS Root R3" +# Serial: 146587176140553309517047991083707763997 +# MD5 Fingerprint: 1a:79:5b:6b:04:52:9c:5d:c7:74:33:1b:25:9a:f9:25 +# SHA1 Fingerprint: 30:d4:24:6f:07:ff:db:91:89:8a:0b:e9:49:66:11:eb:8c:5e:46:e5 +# SHA256 Fingerprint: 15:d5:b8:77:46:19:ea:7d:54:ce:1c:a6:d0:b0:c4:03:e0:37:a9:17:f1:31:e8:a0:4e:1e:6b:7a:71:ba:bc:e5 +-----BEGIN CERTIFICATE----- +MIICDDCCAZGgAwIBAgIQbkepx2ypcyRAiQ8DVd2NHTAKBggqhkjOPQQDAzBHMQsw +CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU +MBIGA1UEAxMLR1RTIFJvb3QgUjMwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw +MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp +Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjMwdjAQBgcqhkjOPQIBBgUrgQQA +IgNiAAQfTzOHMymKoYTey8chWEGJ6ladK0uFxh1MJ7x/JlFyb+Kf1qPKzEUURout +736GjOyxfi//qXGdGIRFBEFVbivqJn+7kAHjSxm65FSWRQmx1WyRRK2EE46ajA2A +DDL24CejQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud +DgQWBBTB8Sa6oC2uhYHP0/EqEr24Cmf9vDAKBggqhkjOPQQDAwNpADBmAjEAgFuk +fCPAlaUs3L6JbyO5o91lAFJekazInXJ0glMLfalAvWhgxeG4VDvBNhcl2MG9AjEA +njWSdIUlUfUk7GRSJFClH9voy8l27OyCbvWFGFPouOOaKaqW04MjyaR7YbPMAuhd +-----END CERTIFICATE----- + +# Issuer: CN=GTS Root R4 O=Google Trust Services LLC +# Subject: CN=GTS Root R4 O=Google Trust Services LLC +# Label: "GTS Root R4" +# Serial: 146587176229350439916519468929765261721 +# MD5 Fingerprint: 5d:b6:6a:c4:60:17:24:6a:1a:99:a8:4b:ee:5e:b4:26 +# SHA1 Fingerprint: 2a:1d:60:27:d9:4a:b1:0a:1c:4d:91:5c:cd:33:a0:cb:3e:2d:54:cb +# SHA256 Fingerprint: 71:cc:a5:39:1f:9e:79:4b:04:80:25:30:b3:63:e1:21:da:8a:30:43:bb:26:66:2f:ea:4d:ca:7f:c9:51:a4:bd +-----BEGIN CERTIFICATE----- +MIICCjCCAZGgAwIBAgIQbkepyIuUtui7OyrYorLBmTAKBggqhkjOPQQDAzBHMQsw +CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU +MBIGA1UEAxMLR1RTIFJvb3QgUjQwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw +MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp +Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjQwdjAQBgcqhkjOPQIBBgUrgQQA +IgNiAATzdHOnaItgrkO4NcWBMHtLSZ37wWHO5t5GvWvVYRg1rkDdc/eJkTBa6zzu +hXyiQHY7qca4R9gq55KRanPpsXI5nymfopjTX15YhmUPoYRlBtHci8nHc8iMai/l +xKvRHYqjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud +DgQWBBSATNbrdP9JNqPV2Py1PsVq8JQdjDAKBggqhkjOPQQDAwNnADBkAjBqUFJ0 +CMRw3J5QdCHojXohw0+WbhXRIjVhLfoIN+4Zba3bssx9BzT1YBkstTTZbyACMANx +sbqjYAuG7ZoIapVon+Kz4ZNkfF6Tpt95LY2F45TPI11xzPKwTdb+mciUqXWi4w== +-----END CERTIFICATE----- + +# Issuer: CN=UCA Global G2 Root O=UniTrust +# Subject: CN=UCA Global G2 Root O=UniTrust +# Label: "UCA Global G2 Root" +# Serial: 124779693093741543919145257850076631279 +# MD5 Fingerprint: 80:fe:f0:c4:4a:f0:5c:62:32:9f:1c:ba:78:a9:50:f8 +# SHA1 Fingerprint: 28:f9:78:16:19:7a:ff:18:25:18:aa:44:fe:c1:a0:ce:5c:b6:4c:8a +# SHA256 Fingerprint: 9b:ea:11:c9:76:fe:01:47:64:c1:be:56:a6:f9:14:b5:a5:60:31:7a:bd:99:88:39:33:82:e5:16:1a:a0:49:3c +-----BEGIN CERTIFICATE----- +MIIFRjCCAy6gAwIBAgIQXd+x2lqj7V2+WmUgZQOQ7zANBgkqhkiG9w0BAQsFADA9 +MQswCQYDVQQGEwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxGzAZBgNVBAMMElVDQSBH +bG9iYWwgRzIgUm9vdDAeFw0xNjAzMTEwMDAwMDBaFw00MDEyMzEwMDAwMDBaMD0x +CzAJBgNVBAYTAkNOMREwDwYDVQQKDAhVbmlUcnVzdDEbMBkGA1UEAwwSVUNBIEds +b2JhbCBHMiBSb290MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxeYr +b3zvJgUno4Ek2m/LAfmZmqkywiKHYUGRO8vDaBsGxUypK8FnFyIdK+35KYmToni9 +kmugow2ifsqTs6bRjDXVdfkX9s9FxeV67HeToI8jrg4aA3++1NDtLnurRiNb/yzm +VHqUwCoV8MmNsHo7JOHXaOIxPAYzRrZUEaalLyJUKlgNAQLx+hVRZ2zA+te2G3/R +VogvGjqNO7uCEeBHANBSh6v7hn4PJGtAnTRnvI3HLYZveT6OqTwXS3+wmeOwcWDc +C/Vkw85DvG1xudLeJ1uK6NjGruFZfc8oLTW4lVYa8bJYS7cSN8h8s+1LgOGN+jIj +tm+3SJUIsUROhYw6AlQgL9+/V087OpAh18EmNVQg7Mc/R+zvWr9LesGtOxdQXGLY +D0tK3Cv6brxzks3sx1DoQZbXqX5t2Okdj4q1uViSukqSKwxW/YDrCPBeKW4bHAyv +j5OJrdu9o54hyokZ7N+1wxrrFv54NkzWbtA+FxyQF2smuvt6L78RHBgOLXMDj6Dl +NaBa4kx1HXHhOThTeEDMg5PXCp6dW4+K5OXgSORIskfNTip1KnvyIvbJvgmRlld6 +iIis7nCs+dwp4wwcOxJORNanTrAmyPPZGpeRaOrvjUYG0lZFWJo8DA+DuAUlwznP +O6Q0ibd5Ei9Hxeepl2n8pndntd978XplFeRhVmUCAwEAAaNCMEAwDgYDVR0PAQH/ +BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFIHEjMz15DD/pQwIX4wV +ZyF0Ad/fMA0GCSqGSIb3DQEBCwUAA4ICAQATZSL1jiutROTL/7lo5sOASD0Ee/oj +L3rtNtqyzm325p7lX1iPyzcyochltq44PTUbPrw7tgTQvPlJ9Zv3hcU2tsu8+Mg5 +1eRfB70VVJd0ysrtT7q6ZHafgbiERUlMjW+i67HM0cOU2kTC5uLqGOiiHycFutfl +1qnN3e92mI0ADs0b+gO3joBYDic/UvuUospeZcnWhNq5NXHzJsBPd+aBJ9J3O5oU +b3n09tDh05S60FdRvScFDcH9yBIw7m+NESsIndTUv4BFFJqIRNow6rSn4+7vW4LV +PtateJLbXDzz2K36uGt/xDYotgIVilQsnLAXc47QN6MUPJiVAAwpBVueSUmxX8fj +y88nZY41F7dXyDDZQVu5FLbowg+UMaeUmMxq67XhJ/UQqAHojhJi6IjMtX9Gl8Cb +EGY4GjZGXyJoPd/JxhMnq1MGrKI8hgZlb7F+sSlEmqO6SWkoaY/X5V+tBIZkbxqg +DMUIYs6Ao9Dz7GjevjPHF1t/gMRMTLGmhIrDO7gJzRSBuhjjVFc2/tsvfEehOjPI ++Vg7RE+xygKJBJYoaMVLuCaJu9YzL1DV/pqJuhgyklTGW+Cd+V7lDSKb9triyCGy +YiGqhkCyLmTTX8jjfhFnRR8F/uOi77Oos/N9j/gMHyIfLXC0uAE0djAA5SN4p1bX +UB+K+wb1whnw0A== +-----END CERTIFICATE----- + +# Issuer: CN=UCA Extended Validation Root O=UniTrust +# Subject: CN=UCA Extended Validation Root O=UniTrust +# Label: "UCA Extended Validation Root" +# Serial: 106100277556486529736699587978573607008 +# MD5 Fingerprint: a1:f3:5f:43:c6:34:9b:da:bf:8c:7e:05:53:ad:96:e2 +# SHA1 Fingerprint: a3:a1:b0:6f:24:61:23:4a:e3:36:a5:c2:37:fc:a6:ff:dd:f0:d7:3a +# SHA256 Fingerprint: d4:3a:f9:b3:54:73:75:5c:96:84:fc:06:d7:d8:cb:70:ee:5c:28:e7:73:fb:29:4e:b4:1e:e7:17:22:92:4d:24 +-----BEGIN CERTIFICATE----- +MIIFWjCCA0KgAwIBAgIQT9Irj/VkyDOeTzRYZiNwYDANBgkqhkiG9w0BAQsFADBH +MQswCQYDVQQGEwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxJTAjBgNVBAMMHFVDQSBF +eHRlbmRlZCBWYWxpZGF0aW9uIFJvb3QwHhcNMTUwMzEzMDAwMDAwWhcNMzgxMjMx +MDAwMDAwWjBHMQswCQYDVQQGEwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxJTAjBgNV +BAMMHFVDQSBFeHRlbmRlZCBWYWxpZGF0aW9uIFJvb3QwggIiMA0GCSqGSIb3DQEB +AQUAA4ICDwAwggIKAoICAQCpCQcoEwKwmeBkqh5DFnpzsZGgdT6o+uM4AHrsiWog +D4vFsJszA1qGxliG1cGFu0/GnEBNyr7uaZa4rYEwmnySBesFK5pI0Lh2PpbIILvS +sPGP2KxFRv+qZ2C0d35qHzwaUnoEPQc8hQ2E0B92CvdqFN9y4zR8V05WAT558aop +O2z6+I9tTcg1367r3CTueUWnhbYFiN6IXSV8l2RnCdm/WhUFhvMJHuxYMjMR83dk +sHYf5BA1FxvyDrFspCqjc/wJHx4yGVMR59mzLC52LqGj3n5qiAno8geK+LLNEOfi +c0CTuwjRP+H8C5SzJe98ptfRr5//lpr1kXuYC3fUfugH0mK1lTnj8/FtDw5lhIpj +VMWAtuCeS31HJqcBCF3RiJ7XwzJE+oJKCmhUfzhTA8ykADNkUVkLo4KRel7sFsLz +KuZi2irbWWIQJUoqgQtHB0MGcIfS+pMRKXpITeuUx3BNr2fVUbGAIAEBtHoIppB/ +TuDvB0GHr2qlXov7z1CymlSvw4m6WC31MJixNnI5fkkE/SmnTHnkBVfblLkWU41G +sx2VYVdWf6/wFlthWG82UBEL2KwrlRYaDh8IzTY0ZRBiZtWAXxQgXy0MoHgKaNYs +1+lvK9JKBZP8nm9rZ/+I8U6laUpSNwXqxhaN0sSZ0YIrO7o1dfdRUVjzyAfd5LQD +fwIDAQABo0IwQDAdBgNVHQ4EFgQU2XQ65DA9DfcS3H5aBZ8eNJr34RQwDwYDVR0T +AQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQELBQADggIBADaN +l8xCFWQpN5smLNb7rhVpLGsaGvdftvkHTFnq88nIua7Mui563MD1sC3AO6+fcAUR +ap8lTwEpcOPlDOHqWnzcSbvBHiqB9RZLcpHIojG5qtr8nR/zXUACE/xOHAbKsxSQ +VBcZEhrxH9cMaVr2cXj0lH2RC47skFSOvG+hTKv8dGT9cZr4QQehzZHkPJrgmzI5 +c6sq1WnIeJEmMX3ixzDx/BR4dxIOE/TdFpS/S2d7cFOFyrC78zhNLJA5wA3CXWvp +4uXViI3WLL+rG761KIcSF3Ru/H38j9CHJrAb+7lsq+KePRXBOy5nAliRn+/4Qh8s +t2j1da3Ptfb/EX3C8CSlrdP6oDyp+l3cpaDvRKS+1ujl5BOWF3sGPjLtx7dCvHaj +2GU4Kzg1USEODm8uNBNA4StnDG1KQTAYI1oyVZnJF+A83vbsea0rWBmirSwiGpWO +vpaQXUJXxPkUAzUrHC1RVwinOt4/5Mi0A3PCwSaAuwtCH60NryZy2sy+s6ODWA2C +xR9GUeOcGMyNm43sSet1UNWMKFnKdDTajAshqx7qG+XH/RU+wBeq+yNuJkbL+vmx +cmtpzyKEC2IPrNkZAJSidjzULZrtBJ4tBmIQN1IchXIbJ+XMxjHsN+xjWZsLHXbM +fjKaiJUINlK73nZfdklJrX+9ZSCyycErdhh2n1ax +-----END CERTIFICATE----- + +# Issuer: CN=Certigna Root CA O=Dhimyotis OU=0002 48146308100036 +# Subject: CN=Certigna Root CA O=Dhimyotis OU=0002 48146308100036 +# Label: "Certigna Root CA" +# Serial: 269714418870597844693661054334862075617 +# MD5 Fingerprint: 0e:5c:30:62:27:eb:5b:bc:d7:ae:62:ba:e9:d5:df:77 +# SHA1 Fingerprint: 2d:0d:52:14:ff:9e:ad:99:24:01:74:20:47:6e:6c:85:27:27:f5:43 +# SHA256 Fingerprint: d4:8d:3d:23:ee:db:50:a4:59:e5:51:97:60:1c:27:77:4b:9d:7b:18:c9:4d:5a:05:95:11:a1:02:50:b9:31:68 +-----BEGIN CERTIFICATE----- +MIIGWzCCBEOgAwIBAgIRAMrpG4nxVQMNo+ZBbcTjpuEwDQYJKoZIhvcNAQELBQAw +WjELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCURoaW15b3RpczEcMBoGA1UECwwTMDAw +MiA0ODE0NjMwODEwMDAzNjEZMBcGA1UEAwwQQ2VydGlnbmEgUm9vdCBDQTAeFw0x +MzEwMDEwODMyMjdaFw0zMzEwMDEwODMyMjdaMFoxCzAJBgNVBAYTAkZSMRIwEAYD +VQQKDAlEaGlteW90aXMxHDAaBgNVBAsMEzAwMDIgNDgxNDYzMDgxMDAwMzYxGTAX +BgNVBAMMEENlcnRpZ25hIFJvb3QgQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw +ggIKAoICAQDNGDllGlmx6mQWDoyUJJV8g9PFOSbcDO8WV43X2KyjQn+Cyu3NW9sO +ty3tRQgXstmzy9YXUnIo245Onoq2C/mehJpNdt4iKVzSs9IGPjA5qXSjklYcoW9M +CiBtnyN6tMbaLOQdLNyzKNAT8kxOAkmhVECe5uUFoC2EyP+YbNDrihqECB63aCPu +I9Vwzm1RaRDuoXrC0SIxwoKF0vJVdlB8JXrJhFwLrN1CTivngqIkicuQstDuI7pm +TLtipPlTWmR7fJj6o0ieD5Wupxj0auwuA0Wv8HT4Ks16XdG+RCYyKfHx9WzMfgIh +C59vpD++nVPiz32pLHxYGpfhPTc3GGYo0kDFUYqMwy3OU4gkWGQwFsWq4NYKpkDf +ePb1BHxpE4S80dGnBs8B92jAqFe7OmGtBIyT46388NtEbVncSVmurJqZNjBBe3Yz +IoejwpKGbvlw7q6Hh5UbxHq9MfPU0uWZ/75I7HX1eBYdpnDBfzwboZL7z8g81sWT +Co/1VTp2lc5ZmIoJlXcymoO6LAQ6l73UL77XbJuiyn1tJslV1c/DeVIICZkHJC1k +JWumIWmbat10TWuXekG9qxf5kBdIjzb5LdXF2+6qhUVB+s06RbFo5jZMm5BX7CO5 +hwjCxAnxl4YqKE3idMDaxIzb3+KhF1nOJFl0Mdp//TBt2dzhauH8XwIDAQABo4IB +GjCCARYwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE +FBiHVuBud+4kNTxOc5of1uHieX4rMB8GA1UdIwQYMBaAFBiHVuBud+4kNTxOc5of +1uHieX4rMEQGA1UdIAQ9MDswOQYEVR0gADAxMC8GCCsGAQUFBwIBFiNodHRwczov +L3d3d3cuY2VydGlnbmEuZnIvYXV0b3JpdGVzLzBtBgNVHR8EZjBkMC+gLaArhilo +dHRwOi8vY3JsLmNlcnRpZ25hLmZyL2NlcnRpZ25hcm9vdGNhLmNybDAxoC+gLYYr +aHR0cDovL2NybC5kaGlteW90aXMuY29tL2NlcnRpZ25hcm9vdGNhLmNybDANBgkq +hkiG9w0BAQsFAAOCAgEAlLieT/DjlQgi581oQfccVdV8AOItOoldaDgvUSILSo3L +6btdPrtcPbEo/uRTVRPPoZAbAh1fZkYJMyjhDSSXcNMQH+pkV5a7XdrnxIxPTGRG +HVyH41neQtGbqH6mid2PHMkwgu07nM3A6RngatgCdTer9zQoKJHyBApPNeNgJgH6 +0BGM+RFq7q89w1DTj18zeTyGqHNFkIwgtnJzFyO+B2XleJINugHA64wcZr+shncB +lA2c5uk5jR+mUYyZDDl34bSb+hxnV29qao6pK0xXeXpXIs/NX2NGjVxZOob4Mkdi +o2cNGJHc+6Zr9UhhcyNZjgKnvETq9Emd8VRY+WCv2hikLyhF3HqgiIZd8zvn/yk1 +gPxkQ5Tm4xxvvq0OKmOZK8l+hfZx6AYDlf7ej0gcWtSS6Cvu5zHbugRqh5jnxV/v +faci9wHYTfmJ0A6aBVmknpjZbyvKcL5kwlWj9Omvw5Ip3IgWJJk8jSaYtlu3zM63 +Nwf9JtmYhST/WSMDmu2dnajkXjjO11INb9I/bbEFa0nOipFGc/T2L/Coc3cOZayh +jWZSaX5LaAzHHjcng6WMxwLkFM1JAbBzs/3GkDpv0mztO+7skb6iQ12LAEpmJURw +3kAP+HwV96LOPNdeE4yBFxgX0b3xdxA61GU5wSesVywlVP+i2k+KYTlerj1KjL0= +-----END CERTIFICATE----- + +# Issuer: CN=emSign Root CA - G1 O=eMudhra Technologies Limited OU=emSign PKI +# Subject: CN=emSign Root CA - G1 O=eMudhra Technologies Limited OU=emSign PKI +# Label: "emSign Root CA - G1" +# Serial: 235931866688319308814040 +# MD5 Fingerprint: 9c:42:84:57:dd:cb:0b:a7:2e:95:ad:b6:f3:da:bc:ac +# SHA1 Fingerprint: 8a:c7:ad:8f:73:ac:4e:c1:b5:75:4d:a5:40:f4:fc:cf:7c:b5:8e:8c +# SHA256 Fingerprint: 40:f6:af:03:46:a9:9a:a1:cd:1d:55:5a:4e:9c:ce:62:c7:f9:63:46:03:ee:40:66:15:83:3d:c8:c8:d0:03:67 +-----BEGIN CERTIFICATE----- +MIIDlDCCAnygAwIBAgIKMfXkYgxsWO3W2DANBgkqhkiG9w0BAQsFADBnMQswCQYD +VQQGEwJJTjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBU +ZWNobm9sb2dpZXMgTGltaXRlZDEcMBoGA1UEAxMTZW1TaWduIFJvb3QgQ0EgLSBH +MTAeFw0xODAyMTgxODMwMDBaFw00MzAyMTgxODMwMDBaMGcxCzAJBgNVBAYTAklO +MRMwEQYDVQQLEwplbVNpZ24gUEtJMSUwIwYDVQQKExxlTXVkaHJhIFRlY2hub2xv +Z2llcyBMaW1pdGVkMRwwGgYDVQQDExNlbVNpZ24gUm9vdCBDQSAtIEcxMIIBIjAN +BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAk0u76WaK7p1b1TST0Bsew+eeuGQz +f2N4aLTNLnF115sgxk0pvLZoYIr3IZpWNVrzdr3YzZr/k1ZLpVkGoZM0Kd0WNHVO +8oG0x5ZOrRkVUkr+PHB1cM2vK6sVmjM8qrOLqs1D/fXqcP/tzxE7lM5OMhbTI0Aq +d7OvPAEsbO2ZLIvZTmmYsvePQbAyeGHWDV/D+qJAkh1cF+ZwPjXnorfCYuKrpDhM +tTk1b+oDafo6VGiFbdbyL0NVHpENDtjVaqSW0RM8LHhQ6DqS0hdW5TUaQBw+jSzt +Od9C4INBdN+jzcKGYEho42kLVACL5HZpIQ15TjQIXhTCzLG3rdd8cIrHhQIDAQAB +o0IwQDAdBgNVHQ4EFgQU++8Nhp6w492pufEhF38+/PB3KxowDgYDVR0PAQH/BAQD +AgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAFn/8oz1h31x +PaOfG1vR2vjTnGs2vZupYeveFix0PZ7mddrXuqe8QhfnPZHr5X3dPpzxz5KsbEjM +wiI/aTvFthUvozXGaCocV685743QNcMYDHsAVhzNixl03r4PEuDQqqE/AjSxcM6d +GNYIAwlG7mDgfrbESQRRfXBgvKqy/3lyeqYdPV8q+Mri/Tm3R7nrft8EI6/6nAYH +6ftjk4BAtcZsCjEozgyfz7MjNYBBjWzEN3uBL4ChQEKF6dk4jeihU80Bv2noWgby +RQuQ+q7hv53yrlc8pa6yVvSLZUDp/TGBLPQ5Cdjua6e0ph0VpZj3AYHYhX3zUVxx +iN66zB+Afko= +-----END CERTIFICATE----- + +# Issuer: CN=emSign ECC Root CA - G3 O=eMudhra Technologies Limited OU=emSign PKI +# Subject: CN=emSign ECC Root CA - G3 O=eMudhra Technologies Limited OU=emSign PKI +# Label: "emSign ECC Root CA - G3" +# Serial: 287880440101571086945156 +# MD5 Fingerprint: ce:0b:72:d1:9f:88:8e:d0:50:03:e8:e3:b8:8b:67:40 +# SHA1 Fingerprint: 30:43:fa:4f:f2:57:dc:a0:c3:80:ee:2e:58:ea:78:b2:3f:e6:bb:c1 +# SHA256 Fingerprint: 86:a1:ec:ba:08:9c:4a:8d:3b:be:27:34:c6:12:ba:34:1d:81:3e:04:3c:f9:e8:a8:62:cd:5c:57:a3:6b:be:6b +-----BEGIN CERTIFICATE----- +MIICTjCCAdOgAwIBAgIKPPYHqWhwDtqLhDAKBggqhkjOPQQDAzBrMQswCQYDVQQG +EwJJTjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBUZWNo +bm9sb2dpZXMgTGltaXRlZDEgMB4GA1UEAxMXZW1TaWduIEVDQyBSb290IENBIC0g +RzMwHhcNMTgwMjE4MTgzMDAwWhcNNDMwMjE4MTgzMDAwWjBrMQswCQYDVQQGEwJJ +TjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBUZWNobm9s +b2dpZXMgTGltaXRlZDEgMB4GA1UEAxMXZW1TaWduIEVDQyBSb290IENBIC0gRzMw +djAQBgcqhkjOPQIBBgUrgQQAIgNiAAQjpQy4LRL1KPOxst3iAhKAnjlfSU2fySU0 +WXTsuwYc58Byr+iuL+FBVIcUqEqy6HyC5ltqtdyzdc6LBtCGI79G1Y4PPwT01xyS +fvalY8L1X44uT6EYGQIrMgqCZH0Wk9GjQjBAMB0GA1UdDgQWBBR8XQKEE9TMipuB +zhccLikenEhjQjAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggq +hkjOPQQDAwNpADBmAjEAvvNhzwIQHWSVB7gYboiFBS+DCBeQyh+KTOgNG3qxrdWB +CUfvO6wIBHxcmbHtRwfSAjEAnbpV/KlK6O3t5nYBQnvI+GDZjVGLVTv7jHvrZQnD ++JbNR6iC8hZVdyR+EhCVBCyj +-----END CERTIFICATE----- + +# Issuer: CN=emSign Root CA - C1 O=eMudhra Inc OU=emSign PKI +# Subject: CN=emSign Root CA - C1 O=eMudhra Inc OU=emSign PKI +# Label: "emSign Root CA - C1" +# Serial: 825510296613316004955058 +# MD5 Fingerprint: d8:e3:5d:01:21:fa:78:5a:b0:df:ba:d2:ee:2a:5f:68 +# SHA1 Fingerprint: e7:2e:f1:df:fc:b2:09:28:cf:5d:d4:d5:67:37:b1:51:cb:86:4f:01 +# SHA256 Fingerprint: 12:56:09:aa:30:1d:a0:a2:49:b9:7a:82:39:cb:6a:34:21:6f:44:dc:ac:9f:39:54:b1:42:92:f2:e8:c8:60:8f +-----BEGIN CERTIFICATE----- +MIIDczCCAlugAwIBAgILAK7PALrEzzL4Q7IwDQYJKoZIhvcNAQELBQAwVjELMAkG +A1UEBhMCVVMxEzARBgNVBAsTCmVtU2lnbiBQS0kxFDASBgNVBAoTC2VNdWRocmEg +SW5jMRwwGgYDVQQDExNlbVNpZ24gUm9vdCBDQSAtIEMxMB4XDTE4MDIxODE4MzAw +MFoXDTQzMDIxODE4MzAwMFowVjELMAkGA1UEBhMCVVMxEzARBgNVBAsTCmVtU2ln +biBQS0kxFDASBgNVBAoTC2VNdWRocmEgSW5jMRwwGgYDVQQDExNlbVNpZ24gUm9v +dCBDQSAtIEMxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAz+upufGZ +BczYKCFK83M0UYRWEPWgTywS4/oTmifQz/l5GnRfHXk5/Fv4cI7gklL35CX5VIPZ +HdPIWoU/Xse2B+4+wM6ar6xWQio5JXDWv7V7Nq2s9nPczdcdioOl+yuQFTdrHCZH +3DspVpNqs8FqOp099cGXOFgFixwR4+S0uF2FHYP+eF8LRWgYSKVGczQ7/g/IdrvH +GPMF0Ybzhe3nudkyrVWIzqa2kbBPrH4VI5b2P/AgNBbeCsbEBEV5f6f9vtKppa+c +xSMq9zwhbL2vj07FOrLzNBL834AaSaTUqZX3noleoomslMuoaJuvimUnzYnu3Yy1 +aylwQ6BpC+S5DwIDAQABo0IwQDAdBgNVHQ4EFgQU/qHgcB4qAzlSWkK+XJGFehiq +TbUwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEL +BQADggEBAMJKVvoVIXsoounlHfv4LcQ5lkFMOycsxGwYFYDGrK9HWS8mC+M2sO87 +/kOXSTKZEhVb3xEp/6tT+LvBeA+snFOvV71ojD1pM/CjoCNjO2RnIkSt1XHLVip4 +kqNPEjE2NuLe/gDEo2APJ62gsIq1NnpSob0n9CAnYuhNlCQT5AoE6TyrLshDCUrG +YQTlSTR+08TI9Q/Aqum6VF7zYytPT1DU/rl7mYw9wC68AivTxEDkigcxHpvOJpkT ++xHqmiIMERnHXhuBUDDIlhJu58tBf5E7oke3VIAb3ADMmpDqw8NQBmIMMMAVSKeo +WXzhriKi4gp6D/piq1JM4fHfyr6DDUI= +-----END CERTIFICATE----- + +# Issuer: CN=emSign ECC Root CA - C3 O=eMudhra Inc OU=emSign PKI +# Subject: CN=emSign ECC Root CA - C3 O=eMudhra Inc OU=emSign PKI +# Label: "emSign ECC Root CA - C3" +# Serial: 582948710642506000014504 +# MD5 Fingerprint: 3e:53:b3:a3:81:ee:d7:10:f8:d3:b0:1d:17:92:f5:d5 +# SHA1 Fingerprint: b6:af:43:c2:9b:81:53:7d:f6:ef:6b:c3:1f:1f:60:15:0c:ee:48:66 +# SHA256 Fingerprint: bc:4d:80:9b:15:18:9d:78:db:3e:1d:8c:f4:f9:72:6a:79:5d:a1:64:3c:a5:f1:35:8e:1d:db:0e:dc:0d:7e:b3 +-----BEGIN CERTIFICATE----- +MIICKzCCAbGgAwIBAgIKe3G2gla4EnycqDAKBggqhkjOPQQDAzBaMQswCQYDVQQG +EwJVUzETMBEGA1UECxMKZW1TaWduIFBLSTEUMBIGA1UEChMLZU11ZGhyYSBJbmMx +IDAeBgNVBAMTF2VtU2lnbiBFQ0MgUm9vdCBDQSAtIEMzMB4XDTE4MDIxODE4MzAw +MFoXDTQzMDIxODE4MzAwMFowWjELMAkGA1UEBhMCVVMxEzARBgNVBAsTCmVtU2ln +biBQS0kxFDASBgNVBAoTC2VNdWRocmEgSW5jMSAwHgYDVQQDExdlbVNpZ24gRUND +IFJvb3QgQ0EgLSBDMzB2MBAGByqGSM49AgEGBSuBBAAiA2IABP2lYa57JhAd6bci +MK4G9IGzsUJxlTm801Ljr6/58pc1kjZGDoeVjbk5Wum739D+yAdBPLtVb4Ojavti +sIGJAnB9SMVK4+kiVCJNk7tCDK93nCOmfddhEc5lx/h//vXyqaNCMEAwHQYDVR0O +BBYEFPtaSNCAIEDyqOkAB2kZd6fmw/TPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMB +Af8EBTADAQH/MAoGCCqGSM49BAMDA2gAMGUCMQC02C8Cif22TGK6Q04ThHK1rt0c +3ta13FaPWEBaLd4gTCKDypOofu4SQMfWh0/434UCMBwUZOR8loMRnLDRWmFLpg9J +0wD8ofzkpf9/rdcw0Md3f76BB1UwUCAU9Vc4CqgxUQ== +-----END CERTIFICATE----- + +# Issuer: CN=Hongkong Post Root CA 3 O=Hongkong Post +# Subject: CN=Hongkong Post Root CA 3 O=Hongkong Post +# Label: "Hongkong Post Root CA 3" +# Serial: 46170865288971385588281144162979347873371282084 +# MD5 Fingerprint: 11:fc:9f:bd:73:30:02:8a:fd:3f:f3:58:b9:cb:20:f0 +# SHA1 Fingerprint: 58:a2:d0:ec:20:52:81:5b:c1:f3:f8:64:02:24:4e:c2:8e:02:4b:02 +# SHA256 Fingerprint: 5a:2f:c0:3f:0c:83:b0:90:bb:fa:40:60:4b:09:88:44:6c:76:36:18:3d:f9:84:6e:17:10:1a:44:7f:b8:ef:d6 +-----BEGIN CERTIFICATE----- +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 +mpv0 +-----END CERTIFICATE----- + +# Issuer: CN=Entrust Root Certification Authority - G4 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2015 Entrust, Inc. - for authorized use only +# Subject: CN=Entrust Root Certification Authority - G4 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2015 Entrust, Inc. - for authorized use only +# Label: "Entrust Root Certification Authority - G4" +# Serial: 289383649854506086828220374796556676440 +# MD5 Fingerprint: 89:53:f1:83:23:b7:7c:8e:05:f1:8c:71:38:4e:1f:88 +# SHA1 Fingerprint: 14:88:4e:86:26:37:b0:26:af:59:62:5c:40:77:ec:35:29:ba:96:01 +# SHA256 Fingerprint: db:35:17:d1:f6:73:2a:2d:5a:b9:7c:53:3e:c7:07:79:ee:32:70:a6:2f:b4:ac:42:38:37:24:60:e6:f0:1e:88 +-----BEGIN CERTIFICATE----- +MIIGSzCCBDOgAwIBAgIRANm1Q3+vqTkPAAAAAFVlrVgwDQYJKoZIhvcNAQELBQAw +gb4xCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQL +Ex9TZWUgd3d3LmVudHJ1c3QubmV0L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykg +MjAxNSBFbnRydXN0LCBJbmMuIC0gZm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxMjAw +BgNVBAMTKUVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEc0 +MB4XDTE1MDUyNzExMTExNloXDTM3MTIyNzExNDExNlowgb4xCzAJBgNVBAYTAlVT +MRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1 +c3QubmV0L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxNSBFbnRydXN0LCBJ +bmMuIC0gZm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxMjAwBgNVBAMTKUVudHJ1c3Qg +Um9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEc0MIICIjANBgkqhkiG9w0B +AQEFAAOCAg8AMIICCgKCAgEAsewsQu7i0TD/pZJH4i3DumSXbcr3DbVZwbPLqGgZ +2K+EbTBwXX7zLtJTmeH+H17ZSK9dE43b/2MzTdMAArzE+NEGCJR5WIoV3imz/f3E +T+iq4qA7ec2/a0My3dl0ELn39GjUu9CH1apLiipvKgS1sqbHoHrmSKvS0VnM1n4j +5pds8ELl3FFLFUHtSUrJ3hCX1nbB76W1NhSXNdh4IjVS70O92yfbYVaCNNzLiGAM +C1rlLAHGVK/XqsEQe9IFWrhAnoanw5CGAlZSCXqc0ieCU0plUmr1POeo8pyvi73T +DtTUXm6Hnmo9RR3RXRv06QqsYJn7ibT/mCzPfB3pAqoEmh643IhuJbNsZvc8kPNX +wbMv9W3y+8qh+CmdRouzavbmZwe+LGcKKh9asj5XxNMhIWNlUpEbsZmOeX7m640A +2Vqq6nPopIICR5b+W45UYaPrL0swsIsjdXJ8ITzI9vF01Bx7owVV7rtNOzK+mndm +nqxpkCIHH2E6lr7lmk/MBTwoWdPBDFSoWWG9yHJM6Nyfh3+9nEg2XpWjDrk4JFX8 +dWbrAuMINClKxuMrLzOg2qOGpRKX/YAr2hRC45K9PvJdXmd0LhyIRyk0X+IyqJwl +N4y6mACXi0mWHv0liqzc2thddG5msP9E36EYxr5ILzeUePiVSj9/E15dWf10hkNj +c0kCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYD +VR0OBBYEFJ84xFYjwznooHFs6FRM5Og6sb9nMA0GCSqGSIb3DQEBCwUAA4ICAQAS +5UKme4sPDORGpbZgQIeMJX6tuGguW8ZAdjwD+MlZ9POrYs4QjbRaZIxowLByQzTS +Gwv2LFPSypBLhmb8qoMi9IsabyZIrHZ3CL/FmFz0Jomee8O5ZDIBf9PD3Vht7LGr +hFV0d4QEJ1JrhkzO3bll/9bGXp+aEJlLdWr+aumXIOTkdnrG0CSqkM0gkLpHZPt/ +B7NTeLUKYvJzQ85BK4FqLoUWlFPUa19yIqtRLULVAJyZv967lDtX/Zr1hstWO1uI +AeV8KEsD+UmDfLJ/fOPtjqF/YFOOVZ1QNBIPt5d7bIdKROf1beyAN/BYGW5KaHbw +H5Lk6rWS02FREAutp9lfx1/cH6NcjKF+m7ee01ZvZl4HliDtC3T7Zk6LERXpgUl+ +b7DUUH8i119lAg2m9IUe2K4GS0qn0jFmwvjO5QimpAKWRGhXxNUzzxkvFMSUHHuk +2fCfDrGA4tGeEWSpiBE6doLlYsKA2KSD7ZPvfC+QsDJMlhVoSFLUmQjAJOgc47Ol +IQ6SwJAfzyBfyjs4x7dtOvPmRLgOMWuIjnDrnBdSqEGULoe256YSxXXfW8AKbnuk +5F6G+TaU33fD6Q3AOfF5u0aOq0NZJ7cguyPpVkAh7DE9ZapD8j3fcEThuk0mEDuY +n/PIjhs4ViFqUZPTkcpG2om3PVODLAgfi49T3f+sHw== +-----END CERTIFICATE----- + +# Issuer: CN=Microsoft ECC Root Certificate Authority 2017 O=Microsoft Corporation +# Subject: CN=Microsoft ECC Root Certificate Authority 2017 O=Microsoft Corporation +# Label: "Microsoft ECC Root Certificate Authority 2017" +# Serial: 136839042543790627607696632466672567020 +# MD5 Fingerprint: dd:a1:03:e6:4a:93:10:d1:bf:f0:19:42:cb:fe:ed:67 +# SHA1 Fingerprint: 99:9a:64:c3:7f:f4:7d:9f:ab:95:f1:47:69:89:14:60:ee:c4:c3:c5 +# SHA256 Fingerprint: 35:8d:f3:9d:76:4a:f9:e1:b7:66:e9:c9:72:df:35:2e:e1:5c:fa:c2:27:af:6a:d1:d7:0e:8e:4a:6e:dc:ba:02 +-----BEGIN CERTIFICATE----- +MIICWTCCAd+gAwIBAgIQZvI9r4fei7FK6gxXMQHC7DAKBggqhkjOPQQDAzBlMQsw +CQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYD +VQQDEy1NaWNyb3NvZnQgRUNDIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIw +MTcwHhcNMTkxMjE4MjMwNjQ1WhcNNDIwNzE4MjMxNjA0WjBlMQswCQYDVQQGEwJV +UzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYDVQQDEy1NaWNy +b3NvZnQgRUNDIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTcwdjAQBgcq +hkjOPQIBBgUrgQQAIgNiAATUvD0CQnVBEyPNgASGAlEvaqiBYgtlzPbKnR5vSmZR +ogPZnZH6thaxjG7efM3beaYvzrvOcS/lpaso7GMEZpn4+vKTEAXhgShC48Zo9OYb +hGBKia/teQ87zvH2RPUBeMCjVDBSMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8E +BTADAQH/MB0GA1UdDgQWBBTIy5lycFIM+Oa+sgRXKSrPQhDtNTAQBgkrBgEEAYI3 +FQEEAwIBADAKBggqhkjOPQQDAwNoADBlAjBY8k3qDPlfXu5gKcs68tvWMoQZP3zV +L8KxzJOuULsJMsbG7X7JNpQS5GiFBqIb0C8CMQCZ6Ra0DvpWSNSkMBaReNtUjGUB +iudQZsIxtzm6uBoiB078a1QWIP8rtedMDE2mT3M= +-----END CERTIFICATE----- + +# Issuer: CN=Microsoft RSA Root Certificate Authority 2017 O=Microsoft Corporation +# Subject: CN=Microsoft RSA Root Certificate Authority 2017 O=Microsoft Corporation +# Label: "Microsoft RSA Root Certificate Authority 2017" +# Serial: 40975477897264996090493496164228220339 +# MD5 Fingerprint: 10:ff:00:ff:cf:c9:f8:c7:7a:c0:ee:35:8e:c9:0f:47 +# SHA1 Fingerprint: 73:a5:e6:4a:3b:ff:83:16:ff:0e:dc:cc:61:8a:90:6e:4e:ae:4d:74 +# SHA256 Fingerprint: c7:41:f7:0f:4b:2a:8d:88:bf:2e:71:c1:41:22:ef:53:ef:10:eb:a0:cf:a5:e6:4c:fa:20:f4:18:85:30:73:e0 +-----BEGIN CERTIFICATE----- +MIIFqDCCA5CgAwIBAgIQHtOXCV/YtLNHcB6qvn9FszANBgkqhkiG9w0BAQwFADBl +MQswCQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYw +NAYDVQQDEy1NaWNyb3NvZnQgUlNBIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5 +IDIwMTcwHhcNMTkxMjE4MjI1MTIyWhcNNDIwNzE4MjMwMDIzWjBlMQswCQYDVQQG +EwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYDVQQDEy1N +aWNyb3NvZnQgUlNBIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTcwggIi +MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKW76UM4wplZEWCpW9R2LBifOZ +Nt9GkMml7Xhqb0eRaPgnZ1AzHaGm++DlQ6OEAlcBXZxIQIJTELy/xztokLaCLeX0 +ZdDMbRnMlfl7rEqUrQ7eS0MdhweSE5CAg2Q1OQT85elss7YfUJQ4ZVBcF0a5toW1 +HLUX6NZFndiyJrDKxHBKrmCk3bPZ7Pw71VdyvD/IybLeS2v4I2wDwAW9lcfNcztm +gGTjGqwu+UcF8ga2m3P1eDNbx6H7JyqhtJqRjJHTOoI+dkC0zVJhUXAoP8XFWvLJ +jEm7FFtNyP9nTUwSlq31/niol4fX/V4ggNyhSyL71Imtus5Hl0dVe49FyGcohJUc +aDDv70ngNXtk55iwlNpNhTs+VcQor1fznhPbRiefHqJeRIOkpcrVE7NLP8TjwuaG +YaRSMLl6IE9vDzhTyzMMEyuP1pq9KsgtsRx9S1HKR9FIJ3Jdh+vVReZIZZ2vUpC6 +W6IYZVcSn2i51BVrlMRpIpj0M+Dt+VGOQVDJNE92kKz8OMHY4Xu54+OU4UZpyw4K +UGsTuqwPN1q3ErWQgR5WrlcihtnJ0tHXUeOrO8ZV/R4O03QK0dqq6mm4lyiPSMQH ++FJDOvTKVTUssKZqwJz58oHhEmrARdlns87/I6KJClTUFLkqqNfs+avNJVgyeY+Q +W5g5xAgGwax/Dj0ApQIDAQABo1QwUjAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/ +BAUwAwEB/zAdBgNVHQ4EFgQUCctZf4aycI8awznjwNnpv7tNsiMwEAYJKwYBBAGC +NxUBBAMCAQAwDQYJKoZIhvcNAQEMBQADggIBAKyvPl3CEZaJjqPnktaXFbgToqZC +LgLNFgVZJ8og6Lq46BrsTaiXVq5lQ7GPAJtSzVXNUzltYkyLDVt8LkS/gxCP81OC +gMNPOsduET/m4xaRhPtthH80dK2Jp86519efhGSSvpWhrQlTM93uCupKUY5vVau6 +tZRGrox/2KJQJWVggEbbMwSubLWYdFQl3JPk+ONVFT24bcMKpBLBaYVu32TxU5nh +SnUgnZUP5NbcA/FZGOhHibJXWpS2qdgXKxdJ5XbLwVaZOjex/2kskZGT4d9Mozd2 +TaGf+G0eHdP67Pv0RR0Tbc/3WeUiJ3IrhvNXuzDtJE3cfVa7o7P4NHmJweDyAmH3 +pvwPuxwXC65B2Xy9J6P9LjrRk5Sxcx0ki69bIImtt2dmefU6xqaWM/5TkshGsRGR +xpl/j8nWZjEgQRCHLQzWwa80mMpkg/sTV9HB8Dx6jKXB/ZUhoHHBk2dxEuqPiApp +GWSZI1b7rCoucL5mxAyE7+WL85MB+GqQk2dLsmijtWKP6T+MejteD+eMuMZ87zf9 +dOLITzNy4ZQ5bb0Sr74MTnB8G2+NszKTc0QWbej09+CVgI+WXTik9KveCjCHk9hN +AHFiRSdLOkKEW39lt2c0Ui2cFmuqqNh7o0JMcccMyj6D5KbvtwEwXlGjefVwaaZB +RA+GsCyRxj3qrg+E +-----END CERTIFICATE----- + +# Issuer: CN=e-Szigno Root CA 2017 O=Microsec Ltd. +# Subject: CN=e-Szigno Root CA 2017 O=Microsec Ltd. +# Label: "e-Szigno Root CA 2017" +# Serial: 411379200276854331539784714 +# MD5 Fingerprint: de:1f:f6:9e:84:ae:a7:b4:21:ce:1e:58:7d:d1:84:98 +# SHA1 Fingerprint: 89:d4:83:03:4f:9e:9a:48:80:5f:72:37:d4:a9:a6:ef:cb:7c:1f:d1 +# SHA256 Fingerprint: be:b0:0b:30:83:9b:9b:c3:2c:32:e4:44:79:05:95:06:41:f2:64:21:b1:5e:d0:89:19:8b:51:8a:e2:ea:1b:99 +-----BEGIN CERTIFICATE----- +MIICQDCCAeWgAwIBAgIMAVRI7yH9l1kN9QQKMAoGCCqGSM49BAMCMHExCzAJBgNV +BAYTAkhVMREwDwYDVQQHDAhCdWRhcGVzdDEWMBQGA1UECgwNTWljcm9zZWMgTHRk +LjEXMBUGA1UEYQwOVkFUSFUtMjM1ODQ0OTcxHjAcBgNVBAMMFWUtU3ppZ25vIFJv +b3QgQ0EgMjAxNzAeFw0xNzA4MjIxMjA3MDZaFw00MjA4MjIxMjA3MDZaMHExCzAJ +BgNVBAYTAkhVMREwDwYDVQQHDAhCdWRhcGVzdDEWMBQGA1UECgwNTWljcm9zZWMg +THRkLjEXMBUGA1UEYQwOVkFUSFUtMjM1ODQ0OTcxHjAcBgNVBAMMFWUtU3ppZ25v +IFJvb3QgQ0EgMjAxNzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABJbcPYrYsHtv +xie+RJCxs1YVe45DJH0ahFnuY2iyxl6H0BVIHqiQrb1TotreOpCmYF9oMrWGQd+H +Wyx7xf58etqjYzBhMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0G +A1UdDgQWBBSHERUI0arBeAyxr87GyZDvvzAEwDAfBgNVHSMEGDAWgBSHERUI0arB +eAyxr87GyZDvvzAEwDAKBggqhkjOPQQDAgNJADBGAiEAtVfd14pVCzbhhkT61Nlo +jbjcI4qKDdQvfepz7L9NbKgCIQDLpbQS+ue16M9+k/zzNY9vTlp8tLxOsvxyqltZ ++efcMQ== +-----END CERTIFICATE----- + +# Issuer: O=CERTSIGN SA OU=certSIGN ROOT CA G2 +# Subject: O=CERTSIGN SA OU=certSIGN ROOT CA G2 +# Label: "certSIGN Root CA G2" +# Serial: 313609486401300475190 +# MD5 Fingerprint: 8c:f1:75:8a:c6:19:cf:94:b7:f7:65:20:87:c3:97:c7 +# SHA1 Fingerprint: 26:f9:93:b4:ed:3d:28:27:b0:b9:4b:a7:e9:15:1d:a3:8d:92:e5:32 +# SHA256 Fingerprint: 65:7c:fe:2f:a7:3f:aa:38:46:25:71:f3:32:a2:36:3a:46:fc:e7:02:09:51:71:07:02:cd:fb:b6:ee:da:33:05 +-----BEGIN CERTIFICATE----- +MIIFRzCCAy+gAwIBAgIJEQA0tk7GNi02MA0GCSqGSIb3DQEBCwUAMEExCzAJBgNV +BAYTAlJPMRQwEgYDVQQKEwtDRVJUU0lHTiBTQTEcMBoGA1UECxMTY2VydFNJR04g +Uk9PVCBDQSBHMjAeFw0xNzAyMDYwOTI3MzVaFw00MjAyMDYwOTI3MzVaMEExCzAJ +BgNVBAYTAlJPMRQwEgYDVQQKEwtDRVJUU0lHTiBTQTEcMBoGA1UECxMTY2VydFNJ +R04gUk9PVCBDQSBHMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMDF +dRmRfUR0dIf+DjuW3NgBFszuY5HnC2/OOwppGnzC46+CjobXXo9X69MhWf05N0Iw +vlDqtg+piNguLWkh59E3GE59kdUWX2tbAMI5Qw02hVK5U2UPHULlj88F0+7cDBrZ +uIt4ImfkabBoxTzkbFpG583H+u/E7Eu9aqSs/cwoUe+StCmrqzWaTOTECMYmzPhp +n+Sc8CnTXPnGFiWeI8MgwT0PPzhAsP6CRDiqWhqKa2NYOLQV07YRaXseVO6MGiKs +cpc/I1mbySKEwQdPzH/iV8oScLumZfNpdWO9lfsbl83kqK/20U6o2YpxJM02PbyW +xPFsqa7lzw1uKA2wDrXKUXt4FMMgL3/7FFXhEZn91QqhngLjYl/rNUssuHLoPj1P +rCy7Lobio3aP5ZMqz6WryFyNSwb/EkaseMsUBzXgqd+L6a8VTxaJW732jcZZroiF +DsGJ6x9nxUWO/203Nit4ZoORUSs9/1F3dmKh7Gc+PoGD4FapUB8fepmrY7+EF3fx +DTvf95xhszWYijqy7DwaNz9+j5LP2RIUZNoQAhVB/0/E6xyjyfqZ90bp4RjZsbgy +LcsUDFDYg2WD7rlcz8sFWkz6GZdr1l0T08JcVLwyc6B49fFtHsufpaafItzRUZ6C +eWRgKRM+o/1Pcmqr4tTluCRVLERLiohEnMqE0yo7AgMBAAGjQjBAMA8GA1UdEwEB +/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBSCIS1mxteg4BXrzkwJ +d8RgnlRuAzANBgkqhkiG9w0BAQsFAAOCAgEAYN4auOfyYILVAzOBywaK8SJJ6ejq +kX/GM15oGQOGO0MBzwdw5AgeZYWR5hEit/UCI46uuR59H35s5r0l1ZUa8gWmr4UC +b6741jH/JclKyMeKqdmfS0mbEVeZkkMR3rYzpMzXjWR91M08KCy0mpbqTfXERMQl +qiCA2ClV9+BB/AYm/7k29UMUA2Z44RGx2iBfRgB4ACGlHgAoYXhvqAEBj500mv/0 +OJD7uNGzcgbJceaBxXntC6Z58hMLnPddDnskk7RI24Zf3lCGeOdA5jGokHZwYa+c +NywRtYK3qq4kNFtyDGkNzVmf9nGvnAvRCjj5BiKDUyUM/FHE5r7iOZULJK2v0ZXk +ltd0ZGtxTgI8qoXzIKNDOXZbbFD+mpwUHmUUihW9o4JFWklWatKcsWMy5WHgUyIO +pwpJ6st+H6jiYoD2EEVSmAYY3qXNL3+q1Ok+CHLsIwMCPKaq2LxndD0UF/tUSxfj +03k9bWtJySgOLnRQvwzZRjoQhsmnP+mg7H/rpXdYaXHmgwo38oZJar55CJD2AhZk +PuXaTH4MNMn5X7azKFGnpyuqSfqNZSlO42sTp5SjLVFteAxEy9/eCG/Oo2Sr05WE +1LlSVHJ7liXMvGnjSG4N0MedJ5qq+BOS3R7fY581qRY27Iy4g/Q9iY/NtBde17MX +QRBdJ3NghVdJIgc= +-----END CERTIFICATE----- + +# Issuer: CN=Trustwave Global Certification Authority O=Trustwave Holdings, Inc. +# Subject: CN=Trustwave Global Certification Authority O=Trustwave Holdings, Inc. +# Label: "Trustwave Global Certification Authority" +# Serial: 1846098327275375458322922162 +# MD5 Fingerprint: f8:1c:18:2d:2f:ba:5f:6d:a1:6c:bc:c7:ab:91:c7:0e +# SHA1 Fingerprint: 2f:8f:36:4f:e1:58:97:44:21:59:87:a5:2a:9a:d0:69:95:26:7f:b5 +# SHA256 Fingerprint: 97:55:20:15:f5:dd:fc:3c:87:88:c0:06:94:45:55:40:88:94:45:00:84:f1:00:86:70:86:bc:1a:2b:b5:8d:c8 +-----BEGIN CERTIFICATE----- +MIIF2jCCA8KgAwIBAgIMBfcOhtpJ80Y1LrqyMA0GCSqGSIb3DQEBCwUAMIGIMQsw +CQYDVQQGEwJVUzERMA8GA1UECAwISWxsaW5vaXMxEDAOBgNVBAcMB0NoaWNhZ28x +ITAfBgNVBAoMGFRydXN0d2F2ZSBIb2xkaW5ncywgSW5jLjExMC8GA1UEAwwoVHJ1 +c3R3YXZlIEdsb2JhbCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0xNzA4MjMx +OTM0MTJaFw00MjA4MjMxOTM0MTJaMIGIMQswCQYDVQQGEwJVUzERMA8GA1UECAwI +SWxsaW5vaXMxEDAOBgNVBAcMB0NoaWNhZ28xITAfBgNVBAoMGFRydXN0d2F2ZSBI +b2xkaW5ncywgSW5jLjExMC8GA1UEAwwoVHJ1c3R3YXZlIEdsb2JhbCBDZXJ0aWZp +Y2F0aW9uIEF1dGhvcml0eTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB +ALldUShLPDeS0YLOvR29zd24q88KPuFd5dyqCblXAj7mY2Hf8g+CY66j96xz0Xzn +swuvCAAJWX/NKSqIk4cXGIDtiLK0thAfLdZfVaITXdHG6wZWiYj+rDKd/VzDBcdu +7oaJuogDnXIhhpCujwOl3J+IKMujkkkP7NAP4m1ET4BqstTnoApTAbqOl5F2brz8 +1Ws25kCI1nsvXwXoLG0R8+eyvpJETNKXpP7ScoFDB5zpET71ixpZfR9oWN0EACyW +80OzfpgZdNmcc9kYvkHHNHnZ9GLCQ7mzJ7Aiy/k9UscwR7PJPrhq4ufogXBeQotP +JqX+OsIgbrv4Fo7NDKm0G2x2EOFYeUY+VM6AqFcJNykbmROPDMjWLBz7BegIlT1l +RtzuzWniTY+HKE40Cz7PFNm73bZQmq131BnW2hqIyE4bJ3XYsgjxroMwuREOzYfw +hI0Vcnyh78zyiGG69Gm7DIwLdVcEuE4qFC49DxweMqZiNu5m4iK4BUBjECLzMx10 +coos9TkpoNPnG4CELcU9402x/RpvumUHO1jsQkUm+9jaJXLE9gCxInm943xZYkqc +BW89zubWR2OZxiRvchLIrH+QtAuRcOi35hYQcRfO3gZPSEF9NUqjifLJS3tBEW1n +twiYTOURGa5CgNz7kAXU+FDKvuStx8KU1xad5hePrzb7AgMBAAGjQjBAMA8GA1Ud +EwEB/wQFMAMBAf8wHQYDVR0OBBYEFJngGWcNYtt2s9o9uFvo/ULSMQ6HMA4GA1Ud +DwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAmHNw4rDT7TnsTGDZqRKGFx6W +0OhUKDtkLSGm+J1WE2pIPU/HPinbbViDVD2HfSMF1OQc3Og4ZYbFdada2zUFvXfe +uyk3QAUHw5RSn8pk3fEbK9xGChACMf1KaA0HZJDmHvUqoai7PF35owgLEQzxPy0Q +lG/+4jSHg9bP5Rs1bdID4bANqKCqRieCNqcVtgimQlRXtpla4gt5kNdXElE1GYhB +aCXUNxeEFfsBctyV3lImIJgm4nb1J2/6ADtKYdkNy1GTKv0WBpanI5ojSP5RvbbE +sLFUzt5sQa0WZ37b/TjNuThOssFgy50X31ieemKyJo90lZvkWx3SD92YHJtZuSPT +MaCm/zjdzyBP6VhWOmfD0faZmZ26NraAL4hHT4a/RDqA5Dccprrql5gR0IRiR2Qe +qu5AvzSxnI9O4fKSTx+O856X3vOmeWqJcU9LJxdI/uz0UA9PSX3MReO9ekDFQdxh +VicGaeVyQYHTtgGJoC86cnn+OjC/QezHYj6RS8fZMXZC+fc8Y+wmjHMMfRod6qh8 +h6jCJ3zhM0EPz8/8AKAigJ5Kp28AsEFFtyLKaEjFQqKu3R3y4G5OBVixwJAWKqQ9 +EEC+j2Jjg6mcgn0tAumDMHzLJ8n9HmYAsC7TIS+OMxZsmO0QqAfWzJPP29FpHOTK +yeC2nOnOcXHebD8WpHk= +-----END CERTIFICATE----- + +# Issuer: CN=Trustwave Global ECC P256 Certification Authority O=Trustwave Holdings, Inc. +# Subject: CN=Trustwave Global ECC P256 Certification Authority O=Trustwave Holdings, Inc. +# Label: "Trustwave Global ECC P256 Certification Authority" +# Serial: 4151900041497450638097112925 +# MD5 Fingerprint: 5b:44:e3:8d:5d:36:86:26:e8:0d:05:d2:59:a7:83:54 +# SHA1 Fingerprint: b4:90:82:dd:45:0c:be:8b:5b:b1:66:d3:e2:a4:08:26:cd:ed:42:cf +# SHA256 Fingerprint: 94:5b:bc:82:5e:a5:54:f4:89:d1:fd:51:a7:3d:df:2e:a6:24:ac:70:19:a0:52:05:22:5c:22:a7:8c:cf:a8:b4 +-----BEGIN CERTIFICATE----- +MIICYDCCAgegAwIBAgIMDWpfCD8oXD5Rld9dMAoGCCqGSM49BAMCMIGRMQswCQYD +VQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAf +BgNVBAoTGFRydXN0d2F2ZSBIb2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3 +YXZlIEdsb2JhbCBFQ0MgUDI1NiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0x +NzA4MjMxOTM1MTBaFw00MjA4MjMxOTM1MTBaMIGRMQswCQYDVQQGEwJVUzERMA8G +A1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAfBgNVBAoTGFRydXN0 +d2F2ZSBIb2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3YXZlIEdsb2JhbCBF +Q0MgUDI1NiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTBZMBMGByqGSM49AgEGCCqG +SM49AwEHA0IABH77bOYj43MyCMpg5lOcunSNGLB4kFKA3TjASh3RqMyTpJcGOMoN +FWLGjgEqZZ2q3zSRLoHB5DOSMcT9CTqmP62jQzBBMA8GA1UdEwEB/wQFMAMBAf8w +DwYDVR0PAQH/BAUDAwcGADAdBgNVHQ4EFgQUo0EGrJBt0UrrdaVKEJmzsaGLSvcw +CgYIKoZIzj0EAwIDRwAwRAIgB+ZU2g6gWrKuEZ+Hxbb/ad4lvvigtwjzRM4q3wgh +DDcCIC0mA6AFvWvR9lz4ZcyGbbOcNEhjhAnFjXca4syc4XR7 +-----END CERTIFICATE----- + +# Issuer: CN=Trustwave Global ECC P384 Certification Authority O=Trustwave Holdings, Inc. +# Subject: CN=Trustwave Global ECC P384 Certification Authority O=Trustwave Holdings, Inc. +# Label: "Trustwave Global ECC P384 Certification Authority" +# Serial: 2704997926503831671788816187 +# MD5 Fingerprint: ea:cf:60:c4:3b:b9:15:29:40:a1:97:ed:78:27:93:d6 +# SHA1 Fingerprint: e7:f3:a3:c8:cf:6f:c3:04:2e:6d:0e:67:32:c5:9e:68:95:0d:5e:d2 +# SHA256 Fingerprint: 55:90:38:59:c8:c0:c3:eb:b8:75:9e:ce:4e:25:57:22:5f:f5:75:8b:bd:38:eb:d4:82:76:60:1e:1b:d5:80:97 +-----BEGIN CERTIFICATE----- +MIICnTCCAiSgAwIBAgIMCL2Fl2yZJ6SAaEc7MAoGCCqGSM49BAMDMIGRMQswCQYD +VQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAf +BgNVBAoTGFRydXN0d2F2ZSBIb2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3 +YXZlIEdsb2JhbCBFQ0MgUDM4NCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0x +NzA4MjMxOTM2NDNaFw00MjA4MjMxOTM2NDNaMIGRMQswCQYDVQQGEwJVUzERMA8G +A1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAfBgNVBAoTGFRydXN0 +d2F2ZSBIb2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3YXZlIEdsb2JhbCBF +Q0MgUDM4NCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTB2MBAGByqGSM49AgEGBSuB +BAAiA2IABGvaDXU1CDFHBa5FmVXxERMuSvgQMSOjfoPTfygIOiYaOs+Xgh+AtycJ +j9GOMMQKmw6sWASr9zZ9lCOkmwqKi6vr/TklZvFe/oyujUF5nQlgziip04pt89ZF +1PKYhDhloKNDMEEwDwYDVR0TAQH/BAUwAwEB/zAPBgNVHQ8BAf8EBQMDBwYAMB0G +A1UdDgQWBBRVqYSJ0sEyvRjLbKYHTsjnnb6CkDAKBggqhkjOPQQDAwNnADBkAjA3 +AZKXRRJ+oPM+rRk6ct30UJMDEr5E0k9BpIycnR+j9sKS50gU/k6bpZFXrsY3crsC +MGclCrEMXu6pY5Jv5ZAL/mYiykf9ijH3g/56vxC+GCsej/YpHpRZ744hN8tRmKVu +Sw== +-----END CERTIFICATE----- + +# Issuer: CN=NAVER Global Root Certification Authority O=NAVER BUSINESS PLATFORM Corp. +# Subject: CN=NAVER Global Root Certification Authority O=NAVER BUSINESS PLATFORM Corp. +# Label: "NAVER Global Root Certification Authority" +# Serial: 9013692873798656336226253319739695165984492813 +# MD5 Fingerprint: c8:7e:41:f6:25:3b:f5:09:b3:17:e8:46:3d:bf:d0:9b +# SHA1 Fingerprint: 8f:6b:f2:a9:27:4a:da:14:a0:c4:f4:8e:61:27:f9:c0:1e:78:5d:d1 +# SHA256 Fingerprint: 88:f4:38:dc:f8:ff:d1:fa:8f:42:91:15:ff:e5:f8:2a:e1:e0:6e:0c:70:c3:75:fa:ad:71:7b:34:a4:9e:72:65 +-----BEGIN CERTIFICATE----- +MIIFojCCA4qgAwIBAgIUAZQwHqIL3fXFMyqxQ0Rx+NZQTQ0wDQYJKoZIhvcNAQEM +BQAwaTELMAkGA1UEBhMCS1IxJjAkBgNVBAoMHU5BVkVSIEJVU0lORVNTIFBMQVRG +T1JNIENvcnAuMTIwMAYDVQQDDClOQVZFUiBHbG9iYWwgUm9vdCBDZXJ0aWZpY2F0 +aW9uIEF1dGhvcml0eTAeFw0xNzA4MTgwODU4NDJaFw0zNzA4MTgyMzU5NTlaMGkx +CzAJBgNVBAYTAktSMSYwJAYDVQQKDB1OQVZFUiBCVVNJTkVTUyBQTEFURk9STSBD +b3JwLjEyMDAGA1UEAwwpTkFWRVIgR2xvYmFsIFJvb3QgQ2VydGlmaWNhdGlvbiBB +dXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC21PGTXLVA +iQqrDZBbUGOukJR0F0Vy1ntlWilLp1agS7gvQnXp2XskWjFlqxcX0TM62RHcQDaH +38dq6SZeWYp34+hInDEW+j6RscrJo+KfziFTowI2MMtSAuXaMl3Dxeb57hHHi8lE +HoSTGEq0n+USZGnQJoViAbbJAh2+g1G7XNr4rRVqmfeSVPc0W+m/6imBEtRTkZaz +kVrd/pBzKPswRrXKCAfHcXLJZtM0l/aM9BhK4dA9WkW2aacp+yPOiNgSnABIqKYP +szuSjXEOdMWLyEz59JuOuDxp7W87UC9Y7cSw0BwbagzivESq2M0UXZR4Yb8Obtoq +vC8MC3GmsxY/nOb5zJ9TNeIDoKAYv7vxvvTWjIcNQvcGufFt7QSUqP620wbGQGHf +nZ3zVHbOUzoBppJB7ASjjw2i1QnK1sua8e9DXcCrpUHPXFNwcMmIpi3Ua2FzUCaG +YQ5fG8Ir4ozVu53BA0K6lNpfqbDKzE0K70dpAy8i+/Eozr9dUGWokG2zdLAIx6yo +0es+nPxdGoMuK8u180SdOqcXYZaicdNwlhVNt0xz7hlcxVs+Qf6sdWA7G2POAN3a +CJBitOUt7kinaxeZVL6HSuOpXgRM6xBtVNbv8ejyYhbLgGvtPe31HzClrkvJE+2K +AQHJuFFYwGY6sWZLxNUxAmLpdIQM201GLQIDAQABo0IwQDAdBgNVHQ4EFgQU0p+I +36HNLL3s9TsBAZMzJ7LrYEswDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMB +Af8wDQYJKoZIhvcNAQEMBQADggIBADLKgLOdPVQG3dLSLvCkASELZ0jKbY7gyKoN +qo0hV4/GPnrK21HUUrPUloSlWGB/5QuOH/XcChWB5Tu2tyIvCZwTFrFsDDUIbatj +cu3cvuzHV+YwIHHW1xDBE1UBjCpD5EHxzzp6U5LOogMFDTjfArsQLtk70pt6wKGm ++LUx5vR1yblTmXVHIloUFcd4G7ad6Qz4G3bxhYTeodoS76TiEJd6eN4MUZeoIUCL +hr0N8F5OSza7OyAfikJW4Qsav3vQIkMsRIz75Sq0bBwcupTgE34h5prCy8VCZLQe +lHsIJchxzIdFV4XTnyliIoNRlwAYl3dqmJLJfGBs32x9SuRwTMKeuB330DTHD8z7 +p/8Dvq1wkNoL3chtl1+afwkyQf3NosxabUzyqkn+Zvjp2DXrDige7kgvOtB5CTh8 +piKCk5XQA76+AqAF3SAi428diDRgxuYKuQl1C/AH6GmWNcf7I4GOODm4RStDeKLR +LBT/DShycpWbXgnbiUSYqqFJu3FS8r/2/yehNq+4tneI3TqkbZs0kNwUXTC/t+sX +5Ie3cdCh13cV1ELX8vMxmV2b3RZtP+oGI/hGoiLtk/bdmuYqh7GYVPEi92tF4+KO +dh2ajcQGjTa3FPOdVGm3jjzVpG2Tgbet9r1ke8LJaDmgkpzNNIaRkPpkUZ3+/uul +9XXeifdy +-----END CERTIFICATE----- diff --git a/venv/Lib/site-packages/pip/_vendor/certifi/core.py b/venv/Lib/site-packages/pip/_vendor/certifi/core.py new file mode 100644 index 0000000..8987449 --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/certifi/core.py @@ -0,0 +1,60 @@ +# -*- coding: utf-8 -*- + +""" +certifi.py +~~~~~~~~~~ + +This module returns the installation location of cacert.pem or its contents. +""" +import os + +try: + from importlib.resources import path as get_path, read_text + + _CACERT_CTX = None + _CACERT_PATH = None + + def where(): + # This is slightly terrible, but we want to delay extracting the file + # in cases where we're inside of a zipimport situation until someone + # actually calls where(), but we don't want to re-extract the file + # on every call of where(), so we'll do it once then store it in a + # global variable. + global _CACERT_CTX + global _CACERT_PATH + if _CACERT_PATH is None: + # This is slightly janky, the importlib.resources API wants you to + # manage the cleanup of this file, so it doesn't actually return a + # path, it returns a context manager that will give you the path + # when you enter it and will do any cleanup when you leave it. In + # the common case of not needing a temporary file, it will just + # return the file system location and the __exit__() is a no-op. + # + # We also have to hold onto the actual context manager, because + # it will do the cleanup whenever it gets garbage collected, so + # we will also store that at the global level as well. + _CACERT_CTX = get_path("pip._vendor.certifi", "cacert.pem") + _CACERT_PATH = str(_CACERT_CTX.__enter__()) + + return _CACERT_PATH + + +except ImportError: + # This fallback will work for Python versions prior to 3.7 that lack the + # importlib.resources module but relies on the existing `where` function + # so won't address issues with environments like PyOxidizer that don't set + # __file__ on modules. + def read_text(_module, _path, encoding="ascii"): + with open(where(), "r", encoding=encoding) as data: + return data.read() + + # If we don't have importlib.resources, then we will just do the old logic + # of assuming we're on the filesystem and munge the path directly. + def where(): + f = os.path.dirname(__file__) + + return os.path.join(f, "cacert.pem") + + +def contents(): + return read_text("certifi", "cacert.pem", encoding="ascii") diff --git a/venv/Lib/site-packages/pip/_vendor/chardet/__init__.py b/venv/Lib/site-packages/pip/_vendor/chardet/__init__.py new file mode 100644 index 0000000..80ad254 --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/chardet/__init__.py @@ -0,0 +1,83 @@ +######################## BEGIN LICENSE BLOCK ######################## +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + + +from .universaldetector import UniversalDetector +from .enums import InputState +from .version import __version__, VERSION + + +__all__ = ['UniversalDetector', 'detect', 'detect_all', '__version__', 'VERSION'] + + +def detect(byte_str): + """ + Detect the encoding of the given byte string. + + :param byte_str: The byte sequence to examine. + :type byte_str: ``bytes`` or ``bytearray`` + """ + if not isinstance(byte_str, bytearray): + if not isinstance(byte_str, bytes): + raise TypeError('Expected object of type bytes or bytearray, got: ' + '{}'.format(type(byte_str))) + else: + byte_str = bytearray(byte_str) + detector = UniversalDetector() + detector.feed(byte_str) + return detector.close() + + +def detect_all(byte_str): + """ + Detect all the possible encodings of the given byte string. + + :param byte_str: The byte sequence to examine. + :type byte_str: ``bytes`` or ``bytearray`` + """ + if not isinstance(byte_str, bytearray): + if not isinstance(byte_str, bytes): + raise TypeError('Expected object of type bytes or bytearray, got: ' + '{}'.format(type(byte_str))) + else: + byte_str = bytearray(byte_str) + + detector = UniversalDetector() + detector.feed(byte_str) + detector.close() + + if detector._input_state == InputState.HIGH_BYTE: + results = [] + for prober in detector._charset_probers: + if prober.get_confidence() > detector.MINIMUM_THRESHOLD: + charset_name = prober.charset_name + lower_charset_name = prober.charset_name.lower() + # Use Windows encoding name instead of ISO-8859 if we saw any + # extra Windows-specific bytes + if lower_charset_name.startswith('iso-8859'): + if detector._has_win_bytes: + charset_name = detector.ISO_WIN_MAP.get(lower_charset_name, + charset_name) + results.append({ + 'encoding': charset_name, + 'confidence': prober.get_confidence(), + 'language': prober.language, + }) + if len(results) > 0: + return sorted(results, key=lambda result: -result['confidence']) + + return [detector.result] diff --git a/venv/Lib/site-packages/pip/_vendor/chardet/big5freq.py b/venv/Lib/site-packages/pip/_vendor/chardet/big5freq.py new file mode 100644 index 0000000..38f3251 --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/chardet/big5freq.py @@ -0,0 +1,386 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +# Big5 frequency table +# by Taiwan's Mandarin Promotion Council +# +# +# 128 --> 0.42261 +# 256 --> 0.57851 +# 512 --> 0.74851 +# 1024 --> 0.89384 +# 2048 --> 0.97583 +# +# Ideal Distribution Ratio = 0.74851/(1-0.74851) =2.98 +# Random Distribution Ration = 512/(5401-512)=0.105 +# +# Typical Distribution Ratio about 25% of Ideal one, still much higher than RDR + +BIG5_TYPICAL_DISTRIBUTION_RATIO = 0.75 + +#Char to FreqOrder table +BIG5_TABLE_SIZE = 5376 + +BIG5_CHAR_TO_FREQ_ORDER = ( + 1,1801,1506, 255,1431, 198, 9, 82, 6,5008, 177, 202,3681,1256,2821, 110, # 16 +3814, 33,3274, 261, 76, 44,2114, 16,2946,2187,1176, 659,3971, 26,3451,2653, # 32 +1198,3972,3350,4202, 410,2215, 302, 590, 361,1964, 8, 204, 58,4510,5009,1932, # 48 + 63,5010,5011, 317,1614, 75, 222, 159,4203,2417,1480,5012,3555,3091, 224,2822, # 64 +3682, 3, 10,3973,1471, 29,2787,1135,2866,1940, 873, 130,3275,1123, 312,5013, # 80 +4511,2052, 507, 252, 682,5014, 142,1915, 124, 206,2947, 34,3556,3204, 64, 604, # 96 +5015,2501,1977,1978, 155,1991, 645, 641,1606,5016,3452, 337, 72, 406,5017, 80, # 112 + 630, 238,3205,1509, 263, 939,1092,2654, 756,1440,1094,3453, 449, 69,2987, 591, # 128 + 179,2096, 471, 115,2035,1844, 60, 50,2988, 134, 806,1869, 734,2036,3454, 180, # 144 + 995,1607, 156, 537,2907, 688,5018, 319,1305, 779,2145, 514,2379, 298,4512, 359, # 160 +2502, 90,2716,1338, 663, 11, 906,1099,2553, 20,2441, 182, 532,1716,5019, 732, # 176 +1376,4204,1311,1420,3206, 25,2317,1056, 113, 399, 382,1950, 242,3455,2474, 529, # 192 +3276, 475,1447,3683,5020, 117, 21, 656, 810,1297,2300,2334,3557,5021, 126,4205, # 208 + 706, 456, 150, 613,4513, 71,1118,2037,4206, 145,3092, 85, 835, 486,2115,1246, # 224 +1426, 428, 727,1285,1015, 800, 106, 623, 303,1281,5022,2128,2359, 347,3815, 221, # 240 +3558,3135,5023,1956,1153,4207, 83, 296,1199,3093, 192, 624, 93,5024, 822,1898, # 256 +2823,3136, 795,2065, 991,1554,1542,1592, 27, 43,2867, 859, 139,1456, 860,4514, # 272 + 437, 712,3974, 164,2397,3137, 695, 211,3037,2097, 195,3975,1608,3559,3560,3684, # 288 +3976, 234, 811,2989,2098,3977,2233,1441,3561,1615,2380, 668,2077,1638, 305, 228, # 304 +1664,4515, 467, 415,5025, 262,2099,1593, 239, 108, 300, 200,1033, 512,1247,2078, # 320 +5026,5027,2176,3207,3685,2682, 593, 845,1062,3277, 88,1723,2038,3978,1951, 212, # 336 + 266, 152, 149, 468,1899,4208,4516, 77, 187,5028,3038, 37, 5,2990,5029,3979, # 352 +5030,5031, 39,2524,4517,2908,3208,2079, 55, 148, 74,4518, 545, 483,1474,1029, # 368 +1665, 217,1870,1531,3138,1104,2655,4209, 24, 172,3562, 900,3980,3563,3564,4519, # 384 + 32,1408,2824,1312, 329, 487,2360,2251,2717, 784,2683, 4,3039,3351,1427,1789, # 400 + 188, 109, 499,5032,3686,1717,1790, 888,1217,3040,4520,5033,3565,5034,3352,1520, # 416 +3687,3981, 196,1034, 775,5035,5036, 929,1816, 249, 439, 38,5037,1063,5038, 794, # 432 +3982,1435,2301, 46, 178,3278,2066,5039,2381,5040, 214,1709,4521, 804, 35, 707, # 448 + 324,3688,1601,2554, 140, 459,4210,5041,5042,1365, 839, 272, 978,2262,2580,3456, # 464 +2129,1363,3689,1423, 697, 100,3094, 48, 70,1231, 495,3139,2196,5043,1294,5044, # 480 +2080, 462, 586,1042,3279, 853, 256, 988, 185,2382,3457,1698, 434,1084,5045,3458, # 496 + 314,2625,2788,4522,2335,2336, 569,2285, 637,1817,2525, 757,1162,1879,1616,3459, # 512 + 287,1577,2116, 768,4523,1671,2868,3566,2526,1321,3816, 909,2418,5046,4211, 933, # 528 +3817,4212,2053,2361,1222,4524, 765,2419,1322, 786,4525,5047,1920,1462,1677,2909, # 544 +1699,5048,4526,1424,2442,3140,3690,2600,3353,1775,1941,3460,3983,4213, 309,1369, # 560 +1130,2825, 364,2234,1653,1299,3984,3567,3985,3986,2656, 525,1085,3041, 902,2001, # 576 +1475, 964,4527, 421,1845,1415,1057,2286, 940,1364,3141, 376,4528,4529,1381, 7, # 592 +2527, 983,2383, 336,1710,2684,1846, 321,3461, 559,1131,3042,2752,1809,1132,1313, # 608 + 265,1481,1858,5049, 352,1203,2826,3280, 167,1089, 420,2827, 776, 792,1724,3568, # 624 +4214,2443,3281,5050,4215,5051, 446, 229, 333,2753, 901,3818,1200,1557,4530,2657, # 640 +1921, 395,2754,2685,3819,4216,1836, 125, 916,3209,2626,4531,5052,5053,3820,5054, # 656 +5055,5056,4532,3142,3691,1133,2555,1757,3462,1510,2318,1409,3569,5057,2146, 438, # 672 +2601,2910,2384,3354,1068, 958,3043, 461, 311,2869,2686,4217,1916,3210,4218,1979, # 688 + 383, 750,2755,2627,4219, 274, 539, 385,1278,1442,5058,1154,1965, 384, 561, 210, # 704 + 98,1295,2556,3570,5059,1711,2420,1482,3463,3987,2911,1257, 129,5060,3821, 642, # 720 + 523,2789,2790,2658,5061, 141,2235,1333, 68, 176, 441, 876, 907,4220, 603,2602, # 736 + 710, 171,3464, 404, 549, 18,3143,2398,1410,3692,1666,5062,3571,4533,2912,4534, # 752 +5063,2991, 368,5064, 146, 366, 99, 871,3693,1543, 748, 807,1586,1185, 22,2263, # 768 + 379,3822,3211,5065,3212, 505,1942,2628,1992,1382,2319,5066, 380,2362, 218, 702, # 784 +1818,1248,3465,3044,3572,3355,3282,5067,2992,3694, 930,3283,3823,5068, 59,5069, # 800 + 585, 601,4221, 497,3466,1112,1314,4535,1802,5070,1223,1472,2177,5071, 749,1837, # 816 + 690,1900,3824,1773,3988,1476, 429,1043,1791,2236,2117, 917,4222, 447,1086,1629, # 832 +5072, 556,5073,5074,2021,1654, 844,1090, 105, 550, 966,1758,2828,1008,1783, 686, # 848 +1095,5075,2287, 793,1602,5076,3573,2603,4536,4223,2948,2302,4537,3825, 980,2503, # 864 + 544, 353, 527,4538, 908,2687,2913,5077, 381,2629,1943,1348,5078,1341,1252, 560, # 880 +3095,5079,3467,2870,5080,2054, 973, 886,2081, 143,4539,5081,5082, 157,3989, 496, # 896 +4224, 57, 840, 540,2039,4540,4541,3468,2118,1445, 970,2264,1748,1966,2082,4225, # 912 +3144,1234,1776,3284,2829,3695, 773,1206,2130,1066,2040,1326,3990,1738,1725,4226, # 928 + 279,3145, 51,1544,2604, 423,1578,2131,2067, 173,4542,1880,5083,5084,1583, 264, # 944 + 610,3696,4543,2444, 280, 154,5085,5086,5087,1739, 338,1282,3096, 693,2871,1411, # 960 +1074,3826,2445,5088,4544,5089,5090,1240, 952,2399,5091,2914,1538,2688, 685,1483, # 976 +4227,2475,1436, 953,4228,2055,4545, 671,2400, 79,4229,2446,3285, 608, 567,2689, # 992 +3469,4230,4231,1691, 393,1261,1792,2401,5092,4546,5093,5094,5095,5096,1383,1672, # 1008 +3827,3213,1464, 522,1119, 661,1150, 216, 675,4547,3991,1432,3574, 609,4548,2690, # 1024 +2402,5097,5098,5099,4232,3045, 0,5100,2476, 315, 231,2447, 301,3356,4549,2385, # 1040 +5101, 233,4233,3697,1819,4550,4551,5102, 96,1777,1315,2083,5103, 257,5104,1810, # 1056 +3698,2718,1139,1820,4234,2022,1124,2164,2791,1778,2659,5105,3097, 363,1655,3214, # 1072 +5106,2993,5107,5108,5109,3992,1567,3993, 718, 103,3215, 849,1443, 341,3357,2949, # 1088 +1484,5110,1712, 127, 67, 339,4235,2403, 679,1412, 821,5111,5112, 834, 738, 351, # 1104 +2994,2147, 846, 235,1497,1881, 418,1993,3828,2719, 186,1100,2148,2756,3575,1545, # 1120 +1355,2950,2872,1377, 583,3994,4236,2581,2995,5113,1298,3699,1078,2557,3700,2363, # 1136 + 78,3829,3830, 267,1289,2100,2002,1594,4237, 348, 369,1274,2197,2178,1838,4552, # 1152 +1821,2830,3701,2757,2288,2003,4553,2951,2758, 144,3358, 882,4554,3995,2759,3470, # 1168 +4555,2915,5114,4238,1726, 320,5115,3996,3046, 788,2996,5116,2831,1774,1327,2873, # 1184 +3997,2832,5117,1306,4556,2004,1700,3831,3576,2364,2660, 787,2023, 506, 824,3702, # 1200 + 534, 323,4557,1044,3359,2024,1901, 946,3471,5118,1779,1500,1678,5119,1882,4558, # 1216 + 165, 243,4559,3703,2528, 123, 683,4239, 764,4560, 36,3998,1793, 589,2916, 816, # 1232 + 626,1667,3047,2237,1639,1555,1622,3832,3999,5120,4000,2874,1370,1228,1933, 891, # 1248 +2084,2917, 304,4240,5121, 292,2997,2720,3577, 691,2101,4241,1115,4561, 118, 662, # 1264 +5122, 611,1156, 854,2386,1316,2875, 2, 386, 515,2918,5123,5124,3286, 868,2238, # 1280 +1486, 855,2661, 785,2216,3048,5125,1040,3216,3578,5126,3146, 448,5127,1525,5128, # 1296 +2165,4562,5129,3833,5130,4242,2833,3579,3147, 503, 818,4001,3148,1568, 814, 676, # 1312 +1444, 306,1749,5131,3834,1416,1030, 197,1428, 805,2834,1501,4563,5132,5133,5134, # 1328 +1994,5135,4564,5136,5137,2198, 13,2792,3704,2998,3149,1229,1917,5138,3835,2132, # 1344 +5139,4243,4565,2404,3580,5140,2217,1511,1727,1120,5141,5142, 646,3836,2448, 307, # 1360 +5143,5144,1595,3217,5145,5146,5147,3705,1113,1356,4002,1465,2529,2530,5148, 519, # 1376 +5149, 128,2133, 92,2289,1980,5150,4003,1512, 342,3150,2199,5151,2793,2218,1981, # 1392 +3360,4244, 290,1656,1317, 789, 827,2365,5152,3837,4566, 562, 581,4004,5153, 401, # 1408 +4567,2252, 94,4568,5154,1399,2794,5155,1463,2025,4569,3218,1944,5156, 828,1105, # 1424 +4245,1262,1394,5157,4246, 605,4570,5158,1784,2876,5159,2835, 819,2102, 578,2200, # 1440 +2952,5160,1502, 436,3287,4247,3288,2836,4005,2919,3472,3473,5161,2721,2320,5162, # 1456 +5163,2337,2068, 23,4571, 193, 826,3838,2103, 699,1630,4248,3098, 390,1794,1064, # 1472 +3581,5164,1579,3099,3100,1400,5165,4249,1839,1640,2877,5166,4572,4573, 137,4250, # 1488 + 598,3101,1967, 780, 104, 974,2953,5167, 278, 899, 253, 402, 572, 504, 493,1339, # 1504 +5168,4006,1275,4574,2582,2558,5169,3706,3049,3102,2253, 565,1334,2722, 863, 41, # 1520 +5170,5171,4575,5172,1657,2338, 19, 463,2760,4251, 606,5173,2999,3289,1087,2085, # 1536 +1323,2662,3000,5174,1631,1623,1750,4252,2691,5175,2878, 791,2723,2663,2339, 232, # 1552 +2421,5176,3001,1498,5177,2664,2630, 755,1366,3707,3290,3151,2026,1609, 119,1918, # 1568 +3474, 862,1026,4253,5178,4007,3839,4576,4008,4577,2265,1952,2477,5179,1125, 817, # 1584 +4254,4255,4009,1513,1766,2041,1487,4256,3050,3291,2837,3840,3152,5180,5181,1507, # 1600 +5182,2692, 733, 40,1632,1106,2879, 345,4257, 841,2531, 230,4578,3002,1847,3292, # 1616 +3475,5183,1263, 986,3476,5184, 735, 879, 254,1137, 857, 622,1300,1180,1388,1562, # 1632 +4010,4011,2954, 967,2761,2665,1349, 592,2134,1692,3361,3003,1995,4258,1679,4012, # 1648 +1902,2188,5185, 739,3708,2724,1296,1290,5186,4259,2201,2202,1922,1563,2605,2559, # 1664 +1871,2762,3004,5187, 435,5188, 343,1108, 596, 17,1751,4579,2239,3477,3709,5189, # 1680 +4580, 294,3582,2955,1693, 477, 979, 281,2042,3583, 643,2043,3710,2631,2795,2266, # 1696 +1031,2340,2135,2303,3584,4581, 367,1249,2560,5190,3585,5191,4582,1283,3362,2005, # 1712 + 240,1762,3363,4583,4584, 836,1069,3153, 474,5192,2149,2532, 268,3586,5193,3219, # 1728 +1521,1284,5194,1658,1546,4260,5195,3587,3588,5196,4261,3364,2693,1685,4262, 961, # 1744 +1673,2632, 190,2006,2203,3841,4585,4586,5197, 570,2504,3711,1490,5198,4587,2633, # 1760 +3293,1957,4588, 584,1514, 396,1045,1945,5199,4589,1968,2449,5200,5201,4590,4013, # 1776 + 619,5202,3154,3294, 215,2007,2796,2561,3220,4591,3221,4592, 763,4263,3842,4593, # 1792 +5203,5204,1958,1767,2956,3365,3712,1174, 452,1477,4594,3366,3155,5205,2838,1253, # 1808 +2387,2189,1091,2290,4264, 492,5206, 638,1169,1825,2136,1752,4014, 648, 926,1021, # 1824 +1324,4595, 520,4596, 997, 847,1007, 892,4597,3843,2267,1872,3713,2405,1785,4598, # 1840 +1953,2957,3103,3222,1728,4265,2044,3714,4599,2008,1701,3156,1551, 30,2268,4266, # 1856 +5207,2027,4600,3589,5208, 501,5209,4267, 594,3478,2166,1822,3590,3479,3591,3223, # 1872 + 829,2839,4268,5210,1680,3157,1225,4269,5211,3295,4601,4270,3158,2341,5212,4602, # 1888 +4271,5213,4015,4016,5214,1848,2388,2606,3367,5215,4603, 374,4017, 652,4272,4273, # 1904 + 375,1140, 798,5216,5217,5218,2366,4604,2269, 546,1659, 138,3051,2450,4605,5219, # 1920 +2254, 612,1849, 910, 796,3844,1740,1371, 825,3845,3846,5220,2920,2562,5221, 692, # 1936 + 444,3052,2634, 801,4606,4274,5222,1491, 244,1053,3053,4275,4276, 340,5223,4018, # 1952 +1041,3005, 293,1168, 87,1357,5224,1539, 959,5225,2240, 721, 694,4277,3847, 219, # 1968 +1478, 644,1417,3368,2666,1413,1401,1335,1389,4019,5226,5227,3006,2367,3159,1826, # 1984 + 730,1515, 184,2840, 66,4607,5228,1660,2958, 246,3369, 378,1457, 226,3480, 975, # 2000 +4020,2959,1264,3592, 674, 696,5229, 163,5230,1141,2422,2167, 713,3593,3370,4608, # 2016 +4021,5231,5232,1186, 15,5233,1079,1070,5234,1522,3224,3594, 276,1050,2725, 758, # 2032 +1126, 653,2960,3296,5235,2342, 889,3595,4022,3104,3007, 903,1250,4609,4023,3481, # 2048 +3596,1342,1681,1718, 766,3297, 286, 89,2961,3715,5236,1713,5237,2607,3371,3008, # 2064 +5238,2962,2219,3225,2880,5239,4610,2505,2533, 181, 387,1075,4024, 731,2190,3372, # 2080 +5240,3298, 310, 313,3482,2304, 770,4278, 54,3054, 189,4611,3105,3848,4025,5241, # 2096 +1230,1617,1850, 355,3597,4279,4612,3373, 111,4280,3716,1350,3160,3483,3055,4281, # 2112 +2150,3299,3598,5242,2797,4026,4027,3009, 722,2009,5243,1071, 247,1207,2343,2478, # 2128 +1378,4613,2010, 864,1437,1214,4614, 373,3849,1142,2220, 667,4615, 442,2763,2563, # 2144 +3850,4028,1969,4282,3300,1840, 837, 170,1107, 934,1336,1883,5244,5245,2119,4283, # 2160 +2841, 743,1569,5246,4616,4284, 582,2389,1418,3484,5247,1803,5248, 357,1395,1729, # 2176 +3717,3301,2423,1564,2241,5249,3106,3851,1633,4617,1114,2086,4285,1532,5250, 482, # 2192 +2451,4618,5251,5252,1492, 833,1466,5253,2726,3599,1641,2842,5254,1526,1272,3718, # 2208 +4286,1686,1795, 416,2564,1903,1954,1804,5255,3852,2798,3853,1159,2321,5256,2881, # 2224 +4619,1610,1584,3056,2424,2764, 443,3302,1163,3161,5257,5258,4029,5259,4287,2506, # 2240 +3057,4620,4030,3162,2104,1647,3600,2011,1873,4288,5260,4289, 431,3485,5261, 250, # 2256 + 97, 81,4290,5262,1648,1851,1558, 160, 848,5263, 866, 740,1694,5264,2204,2843, # 2272 +3226,4291,4621,3719,1687, 950,2479, 426, 469,3227,3720,3721,4031,5265,5266,1188, # 2288 + 424,1996, 861,3601,4292,3854,2205,2694, 168,1235,3602,4293,5267,2087,1674,4622, # 2304 +3374,3303, 220,2565,1009,5268,3855, 670,3010, 332,1208, 717,5269,5270,3603,2452, # 2320 +4032,3375,5271, 513,5272,1209,2882,3376,3163,4623,1080,5273,5274,5275,5276,2534, # 2336 +3722,3604, 815,1587,4033,4034,5277,3605,3486,3856,1254,4624,1328,3058,1390,4035, # 2352 +1741,4036,3857,4037,5278, 236,3858,2453,3304,5279,5280,3723,3859,1273,3860,4625, # 2368 +5281, 308,5282,4626, 245,4627,1852,2480,1307,2583, 430, 715,2137,2454,5283, 270, # 2384 + 199,2883,4038,5284,3606,2727,1753, 761,1754, 725,1661,1841,4628,3487,3724,5285, # 2400 +5286, 587, 14,3305, 227,2608, 326, 480,2270, 943,2765,3607, 291, 650,1884,5287, # 2416 +1702,1226, 102,1547, 62,3488, 904,4629,3489,1164,4294,5288,5289,1224,1548,2766, # 2432 + 391, 498,1493,5290,1386,1419,5291,2056,1177,4630, 813, 880,1081,2368, 566,1145, # 2448 +4631,2291,1001,1035,2566,2609,2242, 394,1286,5292,5293,2069,5294, 86,1494,1730, # 2464 +4039, 491,1588, 745, 897,2963, 843,3377,4040,2767,2884,3306,1768, 998,2221,2070, # 2480 + 397,1827,1195,1970,3725,3011,3378, 284,5295,3861,2507,2138,2120,1904,5296,4041, # 2496 +2151,4042,4295,1036,3490,1905, 114,2567,4296, 209,1527,5297,5298,2964,2844,2635, # 2512 +2390,2728,3164, 812,2568,5299,3307,5300,1559, 737,1885,3726,1210, 885, 28,2695, # 2528 +3608,3862,5301,4297,1004,1780,4632,5302, 346,1982,2222,2696,4633,3863,1742, 797, # 2544 +1642,4043,1934,1072,1384,2152, 896,4044,3308,3727,3228,2885,3609,5303,2569,1959, # 2560 +4634,2455,1786,5304,5305,5306,4045,4298,1005,1308,3728,4299,2729,4635,4636,1528, # 2576 +2610, 161,1178,4300,1983, 987,4637,1101,4301, 631,4046,1157,3229,2425,1343,1241, # 2592 +1016,2243,2570, 372, 877,2344,2508,1160, 555,1935, 911,4047,5307, 466,1170, 169, # 2608 +1051,2921,2697,3729,2481,3012,1182,2012,2571,1251,2636,5308, 992,2345,3491,1540, # 2624 +2730,1201,2071,2406,1997,2482,5309,4638, 528,1923,2191,1503,1874,1570,2369,3379, # 2640 +3309,5310, 557,1073,5311,1828,3492,2088,2271,3165,3059,3107, 767,3108,2799,4639, # 2656 +1006,4302,4640,2346,1267,2179,3730,3230, 778,4048,3231,2731,1597,2667,5312,4641, # 2672 +5313,3493,5314,5315,5316,3310,2698,1433,3311, 131, 95,1504,4049, 723,4303,3166, # 2688 +1842,3610,2768,2192,4050,2028,2105,3731,5317,3013,4051,1218,5318,3380,3232,4052, # 2704 +4304,2584, 248,1634,3864, 912,5319,2845,3732,3060,3865, 654, 53,5320,3014,5321, # 2720 +1688,4642, 777,3494,1032,4053,1425,5322, 191, 820,2121,2846, 971,4643, 931,3233, # 2736 + 135, 664, 783,3866,1998, 772,2922,1936,4054,3867,4644,2923,3234, 282,2732, 640, # 2752 +1372,3495,1127, 922, 325,3381,5323,5324, 711,2045,5325,5326,4055,2223,2800,1937, # 2768 +4056,3382,2224,2255,3868,2305,5327,4645,3869,1258,3312,4057,3235,2139,2965,4058, # 2784 +4059,5328,2225, 258,3236,4646, 101,1227,5329,3313,1755,5330,1391,3314,5331,2924, # 2800 +2057, 893,5332,5333,5334,1402,4305,2347,5335,5336,3237,3611,5337,5338, 878,1325, # 2816 +1781,2801,4647, 259,1385,2585, 744,1183,2272,4648,5339,4060,2509,5340, 684,1024, # 2832 +4306,5341, 472,3612,3496,1165,3315,4061,4062, 322,2153, 881, 455,1695,1152,1340, # 2848 + 660, 554,2154,4649,1058,4650,4307, 830,1065,3383,4063,4651,1924,5342,1703,1919, # 2864 +5343, 932,2273, 122,5344,4652, 947, 677,5345,3870,2637, 297,1906,1925,2274,4653, # 2880 +2322,3316,5346,5347,4308,5348,4309, 84,4310, 112, 989,5349, 547,1059,4064, 701, # 2896 +3613,1019,5350,4311,5351,3497, 942, 639, 457,2306,2456, 993,2966, 407, 851, 494, # 2912 +4654,3384, 927,5352,1237,5353,2426,3385, 573,4312, 680, 921,2925,1279,1875, 285, # 2928 + 790,1448,1984, 719,2168,5354,5355,4655,4065,4066,1649,5356,1541, 563,5357,1077, # 2944 +5358,3386,3061,3498, 511,3015,4067,4068,3733,4069,1268,2572,3387,3238,4656,4657, # 2960 +5359, 535,1048,1276,1189,2926,2029,3167,1438,1373,2847,2967,1134,2013,5360,4313, # 2976 +1238,2586,3109,1259,5361, 700,5362,2968,3168,3734,4314,5363,4315,1146,1876,1907, # 2992 +4658,2611,4070, 781,2427, 132,1589, 203, 147, 273,2802,2407, 898,1787,2155,4071, # 3008 +4072,5364,3871,2803,5365,5366,4659,4660,5367,3239,5368,1635,3872, 965,5369,1805, # 3024 +2699,1516,3614,1121,1082,1329,3317,4073,1449,3873, 65,1128,2848,2927,2769,1590, # 3040 +3874,5370,5371, 12,2668, 45, 976,2587,3169,4661, 517,2535,1013,1037,3240,5372, # 3056 +3875,2849,5373,3876,5374,3499,5375,2612, 614,1999,2323,3877,3110,2733,2638,5376, # 3072 +2588,4316, 599,1269,5377,1811,3735,5378,2700,3111, 759,1060, 489,1806,3388,3318, # 3088 +1358,5379,5380,2391,1387,1215,2639,2256, 490,5381,5382,4317,1759,2392,2348,5383, # 3104 +4662,3878,1908,4074,2640,1807,3241,4663,3500,3319,2770,2349, 874,5384,5385,3501, # 3120 +3736,1859, 91,2928,3737,3062,3879,4664,5386,3170,4075,2669,5387,3502,1202,1403, # 3136 +3880,2969,2536,1517,2510,4665,3503,2511,5388,4666,5389,2701,1886,1495,1731,4076, # 3152 +2370,4667,5390,2030,5391,5392,4077,2702,1216, 237,2589,4318,2324,4078,3881,4668, # 3168 +4669,2703,3615,3504, 445,4670,5393,5394,5395,5396,2771, 61,4079,3738,1823,4080, # 3184 +5397, 687,2046, 935, 925, 405,2670, 703,1096,1860,2734,4671,4081,1877,1367,2704, # 3200 +3389, 918,2106,1782,2483, 334,3320,1611,1093,4672, 564,3171,3505,3739,3390, 945, # 3216 +2641,2058,4673,5398,1926, 872,4319,5399,3506,2705,3112, 349,4320,3740,4082,4674, # 3232 +3882,4321,3741,2156,4083,4675,4676,4322,4677,2408,2047, 782,4084, 400, 251,4323, # 3248 +1624,5400,5401, 277,3742, 299,1265, 476,1191,3883,2122,4324,4325,1109, 205,5402, # 3264 +2590,1000,2157,3616,1861,5403,5404,5405,4678,5406,4679,2573, 107,2484,2158,4085, # 3280 +3507,3172,5407,1533, 541,1301, 158, 753,4326,2886,3617,5408,1696, 370,1088,4327, # 3296 +4680,3618, 579, 327, 440, 162,2244, 269,1938,1374,3508, 968,3063, 56,1396,3113, # 3312 +2107,3321,3391,5409,1927,2159,4681,3016,5410,3619,5411,5412,3743,4682,2485,5413, # 3328 +2804,5414,1650,4683,5415,2613,5416,5417,4086,2671,3392,1149,3393,4087,3884,4088, # 3344 +5418,1076, 49,5419, 951,3242,3322,3323, 450,2850, 920,5420,1812,2805,2371,4328, # 3360 +1909,1138,2372,3885,3509,5421,3243,4684,1910,1147,1518,2428,4685,3886,5422,4686, # 3376 +2393,2614, 260,1796,3244,5423,5424,3887,3324, 708,5425,3620,1704,5426,3621,1351, # 3392 +1618,3394,3017,1887, 944,4329,3395,4330,3064,3396,4331,5427,3744, 422, 413,1714, # 3408 +3325, 500,2059,2350,4332,2486,5428,1344,1911, 954,5429,1668,5430,5431,4089,2409, # 3424 +4333,3622,3888,4334,5432,2307,1318,2512,3114, 133,3115,2887,4687, 629, 31,2851, # 3440 +2706,3889,4688, 850, 949,4689,4090,2970,1732,2089,4335,1496,1853,5433,4091, 620, # 3456 +3245, 981,1242,3745,3397,1619,3746,1643,3326,2140,2457,1971,1719,3510,2169,5434, # 3472 +3246,5435,5436,3398,1829,5437,1277,4690,1565,2048,5438,1636,3623,3116,5439, 869, # 3488 +2852, 655,3890,3891,3117,4092,3018,3892,1310,3624,4691,5440,5441,5442,1733, 558, # 3504 +4692,3747, 335,1549,3065,1756,4336,3748,1946,3511,1830,1291,1192, 470,2735,2108, # 3520 +2806, 913,1054,4093,5443,1027,5444,3066,4094,4693, 982,2672,3399,3173,3512,3247, # 3536 +3248,1947,2807,5445, 571,4694,5446,1831,5447,3625,2591,1523,2429,5448,2090, 984, # 3552 +4695,3749,1960,5449,3750, 852, 923,2808,3513,3751, 969,1519, 999,2049,2325,1705, # 3568 +5450,3118, 615,1662, 151, 597,4095,2410,2326,1049, 275,4696,3752,4337, 568,3753, # 3584 +3626,2487,4338,3754,5451,2430,2275, 409,3249,5452,1566,2888,3514,1002, 769,2853, # 3600 + 194,2091,3174,3755,2226,3327,4339, 628,1505,5453,5454,1763,2180,3019,4096, 521, # 3616 +1161,2592,1788,2206,2411,4697,4097,1625,4340,4341, 412, 42,3119, 464,5455,2642, # 3632 +4698,3400,1760,1571,2889,3515,2537,1219,2207,3893,2643,2141,2373,4699,4700,3328, # 3648 +1651,3401,3627,5456,5457,3628,2488,3516,5458,3756,5459,5460,2276,2092, 460,5461, # 3664 +4701,5462,3020, 962, 588,3629, 289,3250,2644,1116, 52,5463,3067,1797,5464,5465, # 3680 +5466,1467,5467,1598,1143,3757,4342,1985,1734,1067,4702,1280,3402, 465,4703,1572, # 3696 + 510,5468,1928,2245,1813,1644,3630,5469,4704,3758,5470,5471,2673,1573,1534,5472, # 3712 +5473, 536,1808,1761,3517,3894,3175,2645,5474,5475,5476,4705,3518,2929,1912,2809, # 3728 +5477,3329,1122, 377,3251,5478, 360,5479,5480,4343,1529, 551,5481,2060,3759,1769, # 3744 +2431,5482,2930,4344,3330,3120,2327,2109,2031,4706,1404, 136,1468,1479, 672,1171, # 3760 +3252,2308, 271,3176,5483,2772,5484,2050, 678,2736, 865,1948,4707,5485,2014,4098, # 3776 +2971,5486,2737,2227,1397,3068,3760,4708,4709,1735,2931,3403,3631,5487,3895, 509, # 3792 +2854,2458,2890,3896,5488,5489,3177,3178,4710,4345,2538,4711,2309,1166,1010, 552, # 3808 + 681,1888,5490,5491,2972,2973,4099,1287,1596,1862,3179, 358, 453, 736, 175, 478, # 3824 +1117, 905,1167,1097,5492,1854,1530,5493,1706,5494,2181,3519,2292,3761,3520,3632, # 3840 +4346,2093,4347,5495,3404,1193,2489,4348,1458,2193,2208,1863,1889,1421,3331,2932, # 3856 +3069,2182,3521, 595,2123,5496,4100,5497,5498,4349,1707,2646, 223,3762,1359, 751, # 3872 +3121, 183,3522,5499,2810,3021, 419,2374, 633, 704,3897,2394, 241,5500,5501,5502, # 3888 + 838,3022,3763,2277,2773,2459,3898,1939,2051,4101,1309,3122,2246,1181,5503,1136, # 3904 +2209,3899,2375,1446,4350,2310,4712,5504,5505,4351,1055,2615, 484,3764,5506,4102, # 3920 + 625,4352,2278,3405,1499,4353,4103,5507,4104,4354,3253,2279,2280,3523,5508,5509, # 3936 +2774, 808,2616,3765,3406,4105,4355,3123,2539, 526,3407,3900,4356, 955,5510,1620, # 3952 +4357,2647,2432,5511,1429,3766,1669,1832, 994, 928,5512,3633,1260,5513,5514,5515, # 3968 +1949,2293, 741,2933,1626,4358,2738,2460, 867,1184, 362,3408,1392,5516,5517,4106, # 3984 +4359,1770,1736,3254,2934,4713,4714,1929,2707,1459,1158,5518,3070,3409,2891,1292, # 4000 +1930,2513,2855,3767,1986,1187,2072,2015,2617,4360,5519,2574,2514,2170,3768,2490, # 4016 +3332,5520,3769,4715,5521,5522, 666,1003,3023,1022,3634,4361,5523,4716,1814,2257, # 4032 + 574,3901,1603, 295,1535, 705,3902,4362, 283, 858, 417,5524,5525,3255,4717,4718, # 4048 +3071,1220,1890,1046,2281,2461,4107,1393,1599, 689,2575, 388,4363,5526,2491, 802, # 4064 +5527,2811,3903,2061,1405,2258,5528,4719,3904,2110,1052,1345,3256,1585,5529, 809, # 4080 +5530,5531,5532, 575,2739,3524, 956,1552,1469,1144,2328,5533,2329,1560,2462,3635, # 4096 +3257,4108, 616,2210,4364,3180,2183,2294,5534,1833,5535,3525,4720,5536,1319,3770, # 4112 +3771,1211,3636,1023,3258,1293,2812,5537,5538,5539,3905, 607,2311,3906, 762,2892, # 4128 +1439,4365,1360,4721,1485,3072,5540,4722,1038,4366,1450,2062,2648,4367,1379,4723, # 4144 +2593,5541,5542,4368,1352,1414,2330,2935,1172,5543,5544,3907,3908,4724,1798,1451, # 4160 +5545,5546,5547,5548,2936,4109,4110,2492,2351, 411,4111,4112,3637,3333,3124,4725, # 4176 +1561,2674,1452,4113,1375,5549,5550, 47,2974, 316,5551,1406,1591,2937,3181,5552, # 4192 +1025,2142,3125,3182, 354,2740, 884,2228,4369,2412, 508,3772, 726,3638, 996,2433, # 4208 +3639, 729,5553, 392,2194,1453,4114,4726,3773,5554,5555,2463,3640,2618,1675,2813, # 4224 + 919,2352,2975,2353,1270,4727,4115, 73,5556,5557, 647,5558,3259,2856,2259,1550, # 4240 +1346,3024,5559,1332, 883,3526,5560,5561,5562,5563,3334,2775,5564,1212, 831,1347, # 4256 +4370,4728,2331,3909,1864,3073, 720,3910,4729,4730,3911,5565,4371,5566,5567,4731, # 4272 +5568,5569,1799,4732,3774,2619,4733,3641,1645,2376,4734,5570,2938, 669,2211,2675, # 4288 +2434,5571,2893,5572,5573,1028,3260,5574,4372,2413,5575,2260,1353,5576,5577,4735, # 4304 +3183, 518,5578,4116,5579,4373,1961,5580,2143,4374,5581,5582,3025,2354,2355,3912, # 4320 + 516,1834,1454,4117,2708,4375,4736,2229,2620,1972,1129,3642,5583,2776,5584,2976, # 4336 +1422, 577,1470,3026,1524,3410,5585,5586, 432,4376,3074,3527,5587,2594,1455,2515, # 4352 +2230,1973,1175,5588,1020,2741,4118,3528,4737,5589,2742,5590,1743,1361,3075,3529, # 4368 +2649,4119,4377,4738,2295, 895, 924,4378,2171, 331,2247,3076, 166,1627,3077,1098, # 4384 +5591,1232,2894,2231,3411,4739, 657, 403,1196,2377, 542,3775,3412,1600,4379,3530, # 4400 +5592,4740,2777,3261, 576, 530,1362,4741,4742,2540,2676,3776,4120,5593, 842,3913, # 4416 +5594,2814,2032,1014,4121, 213,2709,3413, 665, 621,4380,5595,3777,2939,2435,5596, # 4432 +2436,3335,3643,3414,4743,4381,2541,4382,4744,3644,1682,4383,3531,1380,5597, 724, # 4448 +2282, 600,1670,5598,1337,1233,4745,3126,2248,5599,1621,4746,5600, 651,4384,5601, # 4464 +1612,4385,2621,5602,2857,5603,2743,2312,3078,5604, 716,2464,3079, 174,1255,2710, # 4480 +4122,3645, 548,1320,1398, 728,4123,1574,5605,1891,1197,3080,4124,5606,3081,3082, # 4496 +3778,3646,3779, 747,5607, 635,4386,4747,5608,5609,5610,4387,5611,5612,4748,5613, # 4512 +3415,4749,2437, 451,5614,3780,2542,2073,4388,2744,4389,4125,5615,1764,4750,5616, # 4528 +4390, 350,4751,2283,2395,2493,5617,4391,4126,2249,1434,4127, 488,4752, 458,4392, # 4544 +4128,3781, 771,1330,2396,3914,2576,3184,2160,2414,1553,2677,3185,4393,5618,2494, # 4560 +2895,2622,1720,2711,4394,3416,4753,5619,2543,4395,5620,3262,4396,2778,5621,2016, # 4576 +2745,5622,1155,1017,3782,3915,5623,3336,2313, 201,1865,4397,1430,5624,4129,5625, # 4592 +5626,5627,5628,5629,4398,1604,5630, 414,1866, 371,2595,4754,4755,3532,2017,3127, # 4608 +4756,1708, 960,4399, 887, 389,2172,1536,1663,1721,5631,2232,4130,2356,2940,1580, # 4624 +5632,5633,1744,4757,2544,4758,4759,5634,4760,5635,2074,5636,4761,3647,3417,2896, # 4640 +4400,5637,4401,2650,3418,2815, 673,2712,2465, 709,3533,4131,3648,4402,5638,1148, # 4656 + 502, 634,5639,5640,1204,4762,3649,1575,4763,2623,3783,5641,3784,3128, 948,3263, # 4672 + 121,1745,3916,1110,5642,4403,3083,2516,3027,4132,3785,1151,1771,3917,1488,4133, # 4688 +1987,5643,2438,3534,5644,5645,2094,5646,4404,3918,1213,1407,2816, 531,2746,2545, # 4704 +3264,1011,1537,4764,2779,4405,3129,1061,5647,3786,3787,1867,2897,5648,2018, 120, # 4720 +4406,4407,2063,3650,3265,2314,3919,2678,3419,1955,4765,4134,5649,3535,1047,2713, # 4736 +1266,5650,1368,4766,2858, 649,3420,3920,2546,2747,1102,2859,2679,5651,5652,2000, # 4752 +5653,1111,3651,2977,5654,2495,3921,3652,2817,1855,3421,3788,5655,5656,3422,2415, # 4768 +2898,3337,3266,3653,5657,2577,5658,3654,2818,4135,1460, 856,5659,3655,5660,2899, # 4784 +2978,5661,2900,3922,5662,4408, 632,2517, 875,3923,1697,3924,2296,5663,5664,4767, # 4800 +3028,1239, 580,4768,4409,5665, 914, 936,2075,1190,4136,1039,2124,5666,5667,5668, # 4816 +5669,3423,1473,5670,1354,4410,3925,4769,2173,3084,4137, 915,3338,4411,4412,3339, # 4832 +1605,1835,5671,2748, 398,3656,4413,3926,4138, 328,1913,2860,4139,3927,1331,4414, # 4848 +3029, 937,4415,5672,3657,4140,4141,3424,2161,4770,3425, 524, 742, 538,3085,1012, # 4864 +5673,5674,3928,2466,5675, 658,1103, 225,3929,5676,5677,4771,5678,4772,5679,3267, # 4880 +1243,5680,4142, 963,2250,4773,5681,2714,3658,3186,5682,5683,2596,2332,5684,4774, # 4896 +5685,5686,5687,3536, 957,3426,2547,2033,1931,2941,2467, 870,2019,3659,1746,2780, # 4912 +2781,2439,2468,5688,3930,5689,3789,3130,3790,3537,3427,3791,5690,1179,3086,5691, # 4928 +3187,2378,4416,3792,2548,3188,3131,2749,4143,5692,3428,1556,2549,2297, 977,2901, # 4944 +2034,4144,1205,3429,5693,1765,3430,3189,2125,1271, 714,1689,4775,3538,5694,2333, # 4960 +3931, 533,4417,3660,2184, 617,5695,2469,3340,3539,2315,5696,5697,3190,5698,5699, # 4976 +3932,1988, 618, 427,2651,3540,3431,5700,5701,1244,1690,5702,2819,4418,4776,5703, # 4992 +3541,4777,5704,2284,1576, 473,3661,4419,3432, 972,5705,3662,5706,3087,5707,5708, # 5008 +4778,4779,5709,3793,4145,4146,5710, 153,4780, 356,5711,1892,2902,4420,2144, 408, # 5024 + 803,2357,5712,3933,5713,4421,1646,2578,2518,4781,4782,3934,5714,3935,4422,5715, # 5040 +2416,3433, 752,5716,5717,1962,3341,2979,5718, 746,3030,2470,4783,4423,3794, 698, # 5056 +4784,1893,4424,3663,2550,4785,3664,3936,5719,3191,3434,5720,1824,1302,4147,2715, # 5072 +3937,1974,4425,5721,4426,3192, 823,1303,1288,1236,2861,3542,4148,3435, 774,3938, # 5088 +5722,1581,4786,1304,2862,3939,4787,5723,2440,2162,1083,3268,4427,4149,4428, 344, # 5104 +1173, 288,2316, 454,1683,5724,5725,1461,4788,4150,2597,5726,5727,4789, 985, 894, # 5120 +5728,3436,3193,5729,1914,2942,3795,1989,5730,2111,1975,5731,4151,5732,2579,1194, # 5136 + 425,5733,4790,3194,1245,3796,4429,5734,5735,2863,5736, 636,4791,1856,3940, 760, # 5152 +1800,5737,4430,2212,1508,4792,4152,1894,1684,2298,5738,5739,4793,4431,4432,2213, # 5168 + 479,5740,5741, 832,5742,4153,2496,5743,2980,2497,3797, 990,3132, 627,1815,2652, # 5184 +4433,1582,4434,2126,2112,3543,4794,5744, 799,4435,3195,5745,4795,2113,1737,3031, # 5200 +1018, 543, 754,4436,3342,1676,4796,4797,4154,4798,1489,5746,3544,5747,2624,2903, # 5216 +4155,5748,5749,2981,5750,5751,5752,5753,3196,4799,4800,2185,1722,5754,3269,3270, # 5232 +1843,3665,1715, 481, 365,1976,1857,5755,5756,1963,2498,4801,5757,2127,3666,3271, # 5248 + 433,1895,2064,2076,5758, 602,2750,5759,5760,5761,5762,5763,3032,1628,3437,5764, # 5264 +3197,4802,4156,2904,4803,2519,5765,2551,2782,5766,5767,5768,3343,4804,2905,5769, # 5280 +4805,5770,2864,4806,4807,1221,2982,4157,2520,5771,5772,5773,1868,1990,5774,5775, # 5296 +5776,1896,5777,5778,4808,1897,4158, 318,5779,2095,4159,4437,5780,5781, 485,5782, # 5312 + 938,3941, 553,2680, 116,5783,3942,3667,5784,3545,2681,2783,3438,3344,2820,5785, # 5328 +3668,2943,4160,1747,2944,2983,5786,5787, 207,5788,4809,5789,4810,2521,5790,3033, # 5344 + 890,3669,3943,5791,1878,3798,3439,5792,2186,2358,3440,1652,5793,5794,5795, 941, # 5360 +2299, 208,3546,4161,2020, 330,4438,3944,2906,2499,3799,4439,4811,5796,5797,5798, # 5376 +) + diff --git a/venv/Lib/site-packages/pip/_vendor/chardet/big5prober.py b/venv/Lib/site-packages/pip/_vendor/chardet/big5prober.py new file mode 100644 index 0000000..98f9970 --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/chardet/big5prober.py @@ -0,0 +1,47 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .mbcharsetprober import MultiByteCharSetProber +from .codingstatemachine import CodingStateMachine +from .chardistribution import Big5DistributionAnalysis +from .mbcssm import BIG5_SM_MODEL + + +class Big5Prober(MultiByteCharSetProber): + def __init__(self): + super(Big5Prober, self).__init__() + self.coding_sm = CodingStateMachine(BIG5_SM_MODEL) + self.distribution_analyzer = Big5DistributionAnalysis() + self.reset() + + @property + def charset_name(self): + return "Big5" + + @property + def language(self): + return "Chinese" diff --git a/venv/Lib/site-packages/pip/_vendor/chardet/chardistribution.py b/venv/Lib/site-packages/pip/_vendor/chardet/chardistribution.py new file mode 100644 index 0000000..c0395f4 --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/chardet/chardistribution.py @@ -0,0 +1,233 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .euctwfreq import (EUCTW_CHAR_TO_FREQ_ORDER, EUCTW_TABLE_SIZE, + EUCTW_TYPICAL_DISTRIBUTION_RATIO) +from .euckrfreq import (EUCKR_CHAR_TO_FREQ_ORDER, EUCKR_TABLE_SIZE, + EUCKR_TYPICAL_DISTRIBUTION_RATIO) +from .gb2312freq import (GB2312_CHAR_TO_FREQ_ORDER, GB2312_TABLE_SIZE, + GB2312_TYPICAL_DISTRIBUTION_RATIO) +from .big5freq import (BIG5_CHAR_TO_FREQ_ORDER, BIG5_TABLE_SIZE, + BIG5_TYPICAL_DISTRIBUTION_RATIO) +from .jisfreq import (JIS_CHAR_TO_FREQ_ORDER, JIS_TABLE_SIZE, + JIS_TYPICAL_DISTRIBUTION_RATIO) + + +class CharDistributionAnalysis(object): + ENOUGH_DATA_THRESHOLD = 1024 + SURE_YES = 0.99 + SURE_NO = 0.01 + MINIMUM_DATA_THRESHOLD = 3 + + def __init__(self): + # Mapping table to get frequency order from char order (get from + # GetOrder()) + self._char_to_freq_order = None + self._table_size = None # Size of above table + # This is a constant value which varies from language to language, + # used in calculating confidence. See + # http://www.mozilla.org/projects/intl/UniversalCharsetDetection.html + # for further detail. + self.typical_distribution_ratio = None + self._done = None + self._total_chars = None + self._freq_chars = None + self.reset() + + def reset(self): + """reset analyser, clear any state""" + # If this flag is set to True, detection is done and conclusion has + # been made + self._done = False + self._total_chars = 0 # Total characters encountered + # The number of characters whose frequency order is less than 512 + self._freq_chars = 0 + + def feed(self, char, char_len): + """feed a character with known length""" + if char_len == 2: + # we only care about 2-bytes character in our distribution analysis + order = self.get_order(char) + else: + order = -1 + if order >= 0: + self._total_chars += 1 + # order is valid + if order < self._table_size: + if 512 > self._char_to_freq_order[order]: + self._freq_chars += 1 + + def get_confidence(self): + """return confidence based on existing data""" + # if we didn't receive any character in our consideration range, + # return negative answer + if self._total_chars <= 0 or self._freq_chars <= self.MINIMUM_DATA_THRESHOLD: + return self.SURE_NO + + if self._total_chars != self._freq_chars: + r = (self._freq_chars / ((self._total_chars - self._freq_chars) + * self.typical_distribution_ratio)) + if r < self.SURE_YES: + return r + + # normalize confidence (we don't want to be 100% sure) + return self.SURE_YES + + def got_enough_data(self): + # It is not necessary to receive all data to draw conclusion. + # For charset detection, certain amount of data is enough + return self._total_chars > self.ENOUGH_DATA_THRESHOLD + + def get_order(self, byte_str): + # We do not handle characters based on the original encoding string, + # but convert this encoding string to a number, here called order. + # This allows multiple encodings of a language to share one frequency + # table. + return -1 + + +class EUCTWDistributionAnalysis(CharDistributionAnalysis): + def __init__(self): + super(EUCTWDistributionAnalysis, self).__init__() + self._char_to_freq_order = EUCTW_CHAR_TO_FREQ_ORDER + self._table_size = EUCTW_TABLE_SIZE + self.typical_distribution_ratio = EUCTW_TYPICAL_DISTRIBUTION_RATIO + + def get_order(self, byte_str): + # for euc-TW encoding, we are interested + # first byte range: 0xc4 -- 0xfe + # second byte range: 0xa1 -- 0xfe + # no validation needed here. State machine has done that + first_char = byte_str[0] + if first_char >= 0xC4: + return 94 * (first_char - 0xC4) + byte_str[1] - 0xA1 + else: + return -1 + + +class EUCKRDistributionAnalysis(CharDistributionAnalysis): + def __init__(self): + super(EUCKRDistributionAnalysis, self).__init__() + self._char_to_freq_order = EUCKR_CHAR_TO_FREQ_ORDER + self._table_size = EUCKR_TABLE_SIZE + self.typical_distribution_ratio = EUCKR_TYPICAL_DISTRIBUTION_RATIO + + def get_order(self, byte_str): + # for euc-KR encoding, we are interested + # first byte range: 0xb0 -- 0xfe + # second byte range: 0xa1 -- 0xfe + # no validation needed here. State machine has done that + first_char = byte_str[0] + if first_char >= 0xB0: + return 94 * (first_char - 0xB0) + byte_str[1] - 0xA1 + else: + return -1 + + +class GB2312DistributionAnalysis(CharDistributionAnalysis): + def __init__(self): + super(GB2312DistributionAnalysis, self).__init__() + self._char_to_freq_order = GB2312_CHAR_TO_FREQ_ORDER + self._table_size = GB2312_TABLE_SIZE + self.typical_distribution_ratio = GB2312_TYPICAL_DISTRIBUTION_RATIO + + def get_order(self, byte_str): + # for GB2312 encoding, we are interested + # first byte range: 0xb0 -- 0xfe + # second byte range: 0xa1 -- 0xfe + # no validation needed here. State machine has done that + first_char, second_char = byte_str[0], byte_str[1] + if (first_char >= 0xB0) and (second_char >= 0xA1): + return 94 * (first_char - 0xB0) + second_char - 0xA1 + else: + return -1 + + +class Big5DistributionAnalysis(CharDistributionAnalysis): + def __init__(self): + super(Big5DistributionAnalysis, self).__init__() + self._char_to_freq_order = BIG5_CHAR_TO_FREQ_ORDER + self._table_size = BIG5_TABLE_SIZE + self.typical_distribution_ratio = BIG5_TYPICAL_DISTRIBUTION_RATIO + + def get_order(self, byte_str): + # for big5 encoding, we are interested + # first byte range: 0xa4 -- 0xfe + # second byte range: 0x40 -- 0x7e , 0xa1 -- 0xfe + # no validation needed here. State machine has done that + first_char, second_char = byte_str[0], byte_str[1] + if first_char >= 0xA4: + if second_char >= 0xA1: + return 157 * (first_char - 0xA4) + second_char - 0xA1 + 63 + else: + return 157 * (first_char - 0xA4) + second_char - 0x40 + else: + return -1 + + +class SJISDistributionAnalysis(CharDistributionAnalysis): + def __init__(self): + super(SJISDistributionAnalysis, self).__init__() + self._char_to_freq_order = JIS_CHAR_TO_FREQ_ORDER + self._table_size = JIS_TABLE_SIZE + self.typical_distribution_ratio = JIS_TYPICAL_DISTRIBUTION_RATIO + + def get_order(self, byte_str): + # for sjis encoding, we are interested + # first byte range: 0x81 -- 0x9f , 0xe0 -- 0xfe + # second byte range: 0x40 -- 0x7e, 0x81 -- oxfe + # no validation needed here. State machine has done that + first_char, second_char = byte_str[0], byte_str[1] + if (first_char >= 0x81) and (first_char <= 0x9F): + order = 188 * (first_char - 0x81) + elif (first_char >= 0xE0) and (first_char <= 0xEF): + order = 188 * (first_char - 0xE0 + 31) + else: + return -1 + order = order + second_char - 0x40 + if second_char > 0x7F: + order = -1 + return order + + +class EUCJPDistributionAnalysis(CharDistributionAnalysis): + def __init__(self): + super(EUCJPDistributionAnalysis, self).__init__() + self._char_to_freq_order = JIS_CHAR_TO_FREQ_ORDER + self._table_size = JIS_TABLE_SIZE + self.typical_distribution_ratio = JIS_TYPICAL_DISTRIBUTION_RATIO + + def get_order(self, byte_str): + # for euc-JP encoding, we are interested + # first byte range: 0xa0 -- 0xfe + # second byte range: 0xa1 -- 0xfe + # no validation needed here. State machine has done that + char = byte_str[0] + if char >= 0xA0: + return 94 * (char - 0xA1) + byte_str[1] - 0xa1 + else: + return -1 diff --git a/venv/Lib/site-packages/pip/_vendor/chardet/charsetgroupprober.py b/venv/Lib/site-packages/pip/_vendor/chardet/charsetgroupprober.py new file mode 100644 index 0000000..5812cef --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/chardet/charsetgroupprober.py @@ -0,0 +1,107 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .enums import ProbingState +from .charsetprober import CharSetProber + + +class CharSetGroupProber(CharSetProber): + def __init__(self, lang_filter=None): + super(CharSetGroupProber, self).__init__(lang_filter=lang_filter) + self._active_num = 0 + self.probers = [] + self._best_guess_prober = None + + def reset(self): + super(CharSetGroupProber, self).reset() + self._active_num = 0 + for prober in self.probers: + if prober: + prober.reset() + prober.active = True + self._active_num += 1 + self._best_guess_prober = None + + @property + def charset_name(self): + if not self._best_guess_prober: + self.get_confidence() + if not self._best_guess_prober: + return None + return self._best_guess_prober.charset_name + + @property + def language(self): + if not self._best_guess_prober: + self.get_confidence() + if not self._best_guess_prober: + return None + return self._best_guess_prober.language + + def feed(self, byte_str): + for prober in self.probers: + if not prober: + continue + if not prober.active: + continue + state = prober.feed(byte_str) + if not state: + continue + if state == ProbingState.FOUND_IT: + self._best_guess_prober = prober + self._state = ProbingState.FOUND_IT + return self.state + elif state == ProbingState.NOT_ME: + prober.active = False + self._active_num -= 1 + if self._active_num <= 0: + self._state = ProbingState.NOT_ME + return self.state + return self.state + + def get_confidence(self): + state = self.state + if state == ProbingState.FOUND_IT: + return 0.99 + elif state == ProbingState.NOT_ME: + return 0.01 + best_conf = 0.0 + self._best_guess_prober = None + for prober in self.probers: + if not prober: + continue + if not prober.active: + self.logger.debug('%s not active', prober.charset_name) + continue + conf = prober.get_confidence() + self.logger.debug('%s %s confidence = %s', prober.charset_name, prober.language, conf) + if best_conf < conf: + best_conf = conf + self._best_guess_prober = prober + if not self._best_guess_prober: + return 0.0 + return best_conf diff --git a/venv/Lib/site-packages/pip/_vendor/chardet/charsetprober.py b/venv/Lib/site-packages/pip/_vendor/chardet/charsetprober.py new file mode 100644 index 0000000..eac4e59 --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/chardet/charsetprober.py @@ -0,0 +1,145 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Universal charset detector code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 2001 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# Shy Shalom - original C code +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +import logging +import re + +from .enums import ProbingState + + +class CharSetProber(object): + + SHORTCUT_THRESHOLD = 0.95 + + def __init__(self, lang_filter=None): + self._state = None + self.lang_filter = lang_filter + self.logger = logging.getLogger(__name__) + + def reset(self): + self._state = ProbingState.DETECTING + + @property + def charset_name(self): + return None + + def feed(self, buf): + pass + + @property + def state(self): + return self._state + + def get_confidence(self): + return 0.0 + + @staticmethod + def filter_high_byte_only(buf): + buf = re.sub(b'([\x00-\x7F])+', b' ', buf) + return buf + + @staticmethod + def filter_international_words(buf): + """ + We define three types of bytes: + alphabet: english alphabets [a-zA-Z] + international: international characters [\x80-\xFF] + marker: everything else [^a-zA-Z\x80-\xFF] + + The input buffer can be thought to contain a series of words delimited + by markers. This function works to filter all words that contain at + least one international character. All contiguous sequences of markers + are replaced by a single space ascii character. + + This filter applies to all scripts which do not use English characters. + """ + filtered = bytearray() + + # This regex expression filters out only words that have at-least one + # international character. The word may include one marker character at + # the end. + words = re.findall(b'[a-zA-Z]*[\x80-\xFF]+[a-zA-Z]*[^a-zA-Z\x80-\xFF]?', + buf) + + for word in words: + filtered.extend(word[:-1]) + + # If the last character in the word is a marker, replace it with a + # space as markers shouldn't affect our analysis (they are used + # similarly across all languages and may thus have similar + # frequencies). + last_char = word[-1:] + if not last_char.isalpha() and last_char < b'\x80': + last_char = b' ' + filtered.extend(last_char) + + return filtered + + @staticmethod + def filter_with_english_letters(buf): + """ + Returns a copy of ``buf`` that retains only the sequences of English + alphabet and high byte characters that are not between <> characters. + Also retains English alphabet and high byte characters immediately + before occurrences of >. + + This filter can be applied to all scripts which contain both English + characters and extended ASCII characters, but is currently only used by + ``Latin1Prober``. + """ + filtered = bytearray() + in_tag = False + prev = 0 + + for curr in range(len(buf)): + # Slice here to get bytes instead of an int with Python 3 + buf_char = buf[curr:curr + 1] + # Check if we're coming out of or entering an HTML tag + if buf_char == b'>': + in_tag = False + elif buf_char == b'<': + in_tag = True + + # If current character is not extended-ASCII and not alphabetic... + if buf_char < b'\x80' and not buf_char.isalpha(): + # ...and we're not in a tag + if curr > prev and not in_tag: + # Keep everything after last non-extended-ASCII, + # non-alphabetic character + filtered.extend(buf[prev:curr]) + # Output a space to delimit stretch we kept + filtered.extend(b' ') + prev = curr + 1 + + # If we're not in a tag... + if not in_tag: + # Keep everything after last non-extended-ASCII, non-alphabetic + # character + filtered.extend(buf[prev:]) + + return filtered diff --git a/venv/Lib/site-packages/pip/_vendor/chardet/cli/__init__.py b/venv/Lib/site-packages/pip/_vendor/chardet/cli/__init__.py new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/chardet/cli/__init__.py @@ -0,0 +1 @@ + diff --git a/venv/Lib/site-packages/pip/_vendor/chardet/cli/chardetect.py b/venv/Lib/site-packages/pip/_vendor/chardet/cli/chardetect.py new file mode 100644 index 0000000..6d6f93a --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/chardet/cli/chardetect.py @@ -0,0 +1,84 @@ +""" +Script which takes one or more file paths and reports on their detected +encodings + +Example:: + + % chardetect somefile someotherfile + somefile: windows-1252 with confidence 0.5 + someotherfile: ascii with confidence 1.0 + +If no paths are provided, it takes its input from stdin. + +""" + +from __future__ import absolute_import, print_function, unicode_literals + +import argparse +import sys + +from pip._vendor.chardet import __version__ +from pip._vendor.chardet.compat import PY2 +from pip._vendor.chardet.universaldetector import UniversalDetector + + +def description_of(lines, name='stdin'): + """ + Return a string describing the probable encoding of a file or + list of strings. + + :param lines: The lines to get the encoding of. + :type lines: Iterable of bytes + :param name: Name of file or collection of lines + :type name: str + """ + u = UniversalDetector() + for line in lines: + line = bytearray(line) + u.feed(line) + # shortcut out of the loop to save reading further - particularly useful if we read a BOM. + if u.done: + break + u.close() + result = u.result + if PY2: + name = name.decode(sys.getfilesystemencoding(), 'ignore') + if result['encoding']: + return '{}: {} with confidence {}'.format(name, result['encoding'], + result['confidence']) + else: + return '{}: no result'.format(name) + + +def main(argv=None): + """ + Handles command line arguments and gets things started. + + :param argv: List of arguments, as if specified on the command-line. + If None, ``sys.argv[1:]`` is used instead. + :type argv: list of str + """ + # Get command line arguments + parser = argparse.ArgumentParser( + description="Takes one or more file paths and reports their detected \ + encodings") + parser.add_argument('input', + help='File whose encoding we would like to determine. \ + (default: stdin)', + type=argparse.FileType('rb'), nargs='*', + default=[sys.stdin if PY2 else sys.stdin.buffer]) + parser.add_argument('--version', action='version', + version='%(prog)s {}'.format(__version__)) + args = parser.parse_args(argv) + + for f in args.input: + if f.isatty(): + print("You are running chardetect interactively. Press " + + "CTRL-D twice at the start of a blank line to signal the " + + "end of your input. If you want help, run chardetect " + + "--help\n", file=sys.stderr) + print(description_of(f, f.name)) + + +if __name__ == '__main__': + main() diff --git a/venv/Lib/site-packages/pip/_vendor/chardet/codingstatemachine.py b/venv/Lib/site-packages/pip/_vendor/chardet/codingstatemachine.py new file mode 100644 index 0000000..68fba44 --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/chardet/codingstatemachine.py @@ -0,0 +1,88 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +import logging + +from .enums import MachineState + + +class CodingStateMachine(object): + """ + A state machine to verify a byte sequence for a particular encoding. For + each byte the detector receives, it will feed that byte to every active + state machine available, one byte at a time. The state machine changes its + state based on its previous state and the byte it receives. There are 3 + states in a state machine that are of interest to an auto-detector: + + START state: This is the state to start with, or a legal byte sequence + (i.e. a valid code point) for character has been identified. + + ME state: This indicates that the state machine identified a byte sequence + that is specific to the charset it is designed for and that + there is no other possible encoding which can contain this byte + sequence. This will to lead to an immediate positive answer for + the detector. + + ERROR state: This indicates the state machine identified an illegal byte + sequence for that encoding. This will lead to an immediate + negative answer for this encoding. Detector will exclude this + encoding from consideration from here on. + """ + def __init__(self, sm): + self._model = sm + self._curr_byte_pos = 0 + self._curr_char_len = 0 + self._curr_state = None + self.logger = logging.getLogger(__name__) + self.reset() + + def reset(self): + self._curr_state = MachineState.START + + def next_state(self, c): + # for each byte we get its class + # if it is first byte, we also get byte length + byte_class = self._model['class_table'][c] + if self._curr_state == MachineState.START: + self._curr_byte_pos = 0 + self._curr_char_len = self._model['char_len_table'][byte_class] + # from byte's class and state_table, we get its next state + curr_state = (self._curr_state * self._model['class_factor'] + + byte_class) + self._curr_state = self._model['state_table'][curr_state] + self._curr_byte_pos += 1 + return self._curr_state + + def get_current_charlen(self): + return self._curr_char_len + + def get_coding_state_machine(self): + return self._model['name'] + + @property + def language(self): + return self._model['language'] diff --git a/venv/Lib/site-packages/pip/_vendor/chardet/compat.py b/venv/Lib/site-packages/pip/_vendor/chardet/compat.py new file mode 100644 index 0000000..8941572 --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/chardet/compat.py @@ -0,0 +1,36 @@ +######################## BEGIN LICENSE BLOCK ######################## +# Contributor(s): +# Dan Blanchard +# Ian Cordasco +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +import sys + + +if sys.version_info < (3, 0): + PY2 = True + PY3 = False + string_types = (str, unicode) + text_type = unicode + iteritems = dict.iteritems +else: + PY2 = False + PY3 = True + string_types = (bytes, str) + text_type = str + iteritems = dict.items diff --git a/venv/Lib/site-packages/pip/_vendor/chardet/cp949prober.py b/venv/Lib/site-packages/pip/_vendor/chardet/cp949prober.py new file mode 100644 index 0000000..efd793a --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/chardet/cp949prober.py @@ -0,0 +1,49 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .chardistribution import EUCKRDistributionAnalysis +from .codingstatemachine import CodingStateMachine +from .mbcharsetprober import MultiByteCharSetProber +from .mbcssm import CP949_SM_MODEL + + +class CP949Prober(MultiByteCharSetProber): + def __init__(self): + super(CP949Prober, self).__init__() + self.coding_sm = CodingStateMachine(CP949_SM_MODEL) + # NOTE: CP949 is a superset of EUC-KR, so the distribution should be + # not different. + self.distribution_analyzer = EUCKRDistributionAnalysis() + self.reset() + + @property + def charset_name(self): + return "CP949" + + @property + def language(self): + return "Korean" diff --git a/venv/Lib/site-packages/pip/_vendor/chardet/enums.py b/venv/Lib/site-packages/pip/_vendor/chardet/enums.py new file mode 100644 index 0000000..0451207 --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/chardet/enums.py @@ -0,0 +1,76 @@ +""" +All of the Enums that are used throughout the chardet package. + +:author: Dan Blanchard (dan.blanchard@gmail.com) +""" + + +class InputState(object): + """ + This enum represents the different states a universal detector can be in. + """ + PURE_ASCII = 0 + ESC_ASCII = 1 + HIGH_BYTE = 2 + + +class LanguageFilter(object): + """ + This enum represents the different language filters we can apply to a + ``UniversalDetector``. + """ + CHINESE_SIMPLIFIED = 0x01 + CHINESE_TRADITIONAL = 0x02 + JAPANESE = 0x04 + KOREAN = 0x08 + NON_CJK = 0x10 + ALL = 0x1F + CHINESE = CHINESE_SIMPLIFIED | CHINESE_TRADITIONAL + CJK = CHINESE | JAPANESE | KOREAN + + +class ProbingState(object): + """ + This enum represents the different states a prober can be in. + """ + DETECTING = 0 + FOUND_IT = 1 + NOT_ME = 2 + + +class MachineState(object): + """ + This enum represents the different states a state machine can be in. + """ + START = 0 + ERROR = 1 + ITS_ME = 2 + + +class SequenceLikelihood(object): + """ + This enum represents the likelihood of a character following the previous one. + """ + NEGATIVE = 0 + UNLIKELY = 1 + LIKELY = 2 + POSITIVE = 3 + + @classmethod + def get_num_categories(cls): + """:returns: The number of likelihood categories in the enum.""" + return 4 + + +class CharacterCategory(object): + """ + This enum represents the different categories language models for + ``SingleByteCharsetProber`` put characters into. + + Anything less than CONTROL is considered a letter. + """ + UNDEFINED = 255 + LINE_BREAK = 254 + SYMBOL = 253 + DIGIT = 252 + CONTROL = 251 diff --git a/venv/Lib/site-packages/pip/_vendor/chardet/escprober.py b/venv/Lib/site-packages/pip/_vendor/chardet/escprober.py new file mode 100644 index 0000000..c70493f --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/chardet/escprober.py @@ -0,0 +1,101 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .charsetprober import CharSetProber +from .codingstatemachine import CodingStateMachine +from .enums import LanguageFilter, ProbingState, MachineState +from .escsm import (HZ_SM_MODEL, ISO2022CN_SM_MODEL, ISO2022JP_SM_MODEL, + ISO2022KR_SM_MODEL) + + +class EscCharSetProber(CharSetProber): + """ + This CharSetProber uses a "code scheme" approach for detecting encodings, + whereby easily recognizable escape or shift sequences are relied on to + identify these encodings. + """ + + def __init__(self, lang_filter=None): + super(EscCharSetProber, self).__init__(lang_filter=lang_filter) + self.coding_sm = [] + if self.lang_filter & LanguageFilter.CHINESE_SIMPLIFIED: + self.coding_sm.append(CodingStateMachine(HZ_SM_MODEL)) + self.coding_sm.append(CodingStateMachine(ISO2022CN_SM_MODEL)) + if self.lang_filter & LanguageFilter.JAPANESE: + self.coding_sm.append(CodingStateMachine(ISO2022JP_SM_MODEL)) + if self.lang_filter & LanguageFilter.KOREAN: + self.coding_sm.append(CodingStateMachine(ISO2022KR_SM_MODEL)) + self.active_sm_count = None + self._detected_charset = None + self._detected_language = None + self._state = None + self.reset() + + def reset(self): + super(EscCharSetProber, self).reset() + for coding_sm in self.coding_sm: + if not coding_sm: + continue + coding_sm.active = True + coding_sm.reset() + self.active_sm_count = len(self.coding_sm) + self._detected_charset = None + self._detected_language = None + + @property + def charset_name(self): + return self._detected_charset + + @property + def language(self): + return self._detected_language + + def get_confidence(self): + if self._detected_charset: + return 0.99 + else: + return 0.00 + + def feed(self, byte_str): + for c in byte_str: + for coding_sm in self.coding_sm: + if not coding_sm or not coding_sm.active: + continue + coding_state = coding_sm.next_state(c) + if coding_state == MachineState.ERROR: + coding_sm.active = False + self.active_sm_count -= 1 + if self.active_sm_count <= 0: + self._state = ProbingState.NOT_ME + return self.state + elif coding_state == MachineState.ITS_ME: + self._state = ProbingState.FOUND_IT + self._detected_charset = coding_sm.get_coding_state_machine() + self._detected_language = coding_sm.language + return self.state + + return self.state diff --git a/venv/Lib/site-packages/pip/_vendor/chardet/escsm.py b/venv/Lib/site-packages/pip/_vendor/chardet/escsm.py new file mode 100644 index 0000000..0069523 --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/chardet/escsm.py @@ -0,0 +1,246 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .enums import MachineState + +HZ_CLS = ( +1,0,0,0,0,0,0,0, # 00 - 07 +0,0,0,0,0,0,0,0, # 08 - 0f +0,0,0,0,0,0,0,0, # 10 - 17 +0,0,0,1,0,0,0,0, # 18 - 1f +0,0,0,0,0,0,0,0, # 20 - 27 +0,0,0,0,0,0,0,0, # 28 - 2f +0,0,0,0,0,0,0,0, # 30 - 37 +0,0,0,0,0,0,0,0, # 38 - 3f +0,0,0,0,0,0,0,0, # 40 - 47 +0,0,0,0,0,0,0,0, # 48 - 4f +0,0,0,0,0,0,0,0, # 50 - 57 +0,0,0,0,0,0,0,0, # 58 - 5f +0,0,0,0,0,0,0,0, # 60 - 67 +0,0,0,0,0,0,0,0, # 68 - 6f +0,0,0,0,0,0,0,0, # 70 - 77 +0,0,0,4,0,5,2,0, # 78 - 7f +1,1,1,1,1,1,1,1, # 80 - 87 +1,1,1,1,1,1,1,1, # 88 - 8f +1,1,1,1,1,1,1,1, # 90 - 97 +1,1,1,1,1,1,1,1, # 98 - 9f +1,1,1,1,1,1,1,1, # a0 - a7 +1,1,1,1,1,1,1,1, # a8 - af +1,1,1,1,1,1,1,1, # b0 - b7 +1,1,1,1,1,1,1,1, # b8 - bf +1,1,1,1,1,1,1,1, # c0 - c7 +1,1,1,1,1,1,1,1, # c8 - cf +1,1,1,1,1,1,1,1, # d0 - d7 +1,1,1,1,1,1,1,1, # d8 - df +1,1,1,1,1,1,1,1, # e0 - e7 +1,1,1,1,1,1,1,1, # e8 - ef +1,1,1,1,1,1,1,1, # f0 - f7 +1,1,1,1,1,1,1,1, # f8 - ff +) + +HZ_ST = ( +MachineState.START,MachineState.ERROR, 3,MachineState.START,MachineState.START,MachineState.START,MachineState.ERROR,MachineState.ERROR,# 00-07 +MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,# 08-0f +MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START, 4,MachineState.ERROR,# 10-17 + 5,MachineState.ERROR, 6,MachineState.ERROR, 5, 5, 4,MachineState.ERROR,# 18-1f + 4,MachineState.ERROR, 4, 4, 4,MachineState.ERROR, 4,MachineState.ERROR,# 20-27 + 4,MachineState.ITS_ME,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,# 28-2f +) + +HZ_CHAR_LEN_TABLE = (0, 0, 0, 0, 0, 0) + +HZ_SM_MODEL = {'class_table': HZ_CLS, + 'class_factor': 6, + 'state_table': HZ_ST, + 'char_len_table': HZ_CHAR_LEN_TABLE, + 'name': "HZ-GB-2312", + 'language': 'Chinese'} + +ISO2022CN_CLS = ( +2,0,0,0,0,0,0,0, # 00 - 07 +0,0,0,0,0,0,0,0, # 08 - 0f +0,0,0,0,0,0,0,0, # 10 - 17 +0,0,0,1,0,0,0,0, # 18 - 1f +0,0,0,0,0,0,0,0, # 20 - 27 +0,3,0,0,0,0,0,0, # 28 - 2f +0,0,0,0,0,0,0,0, # 30 - 37 +0,0,0,0,0,0,0,0, # 38 - 3f +0,0,0,4,0,0,0,0, # 40 - 47 +0,0,0,0,0,0,0,0, # 48 - 4f +0,0,0,0,0,0,0,0, # 50 - 57 +0,0,0,0,0,0,0,0, # 58 - 5f +0,0,0,0,0,0,0,0, # 60 - 67 +0,0,0,0,0,0,0,0, # 68 - 6f +0,0,0,0,0,0,0,0, # 70 - 77 +0,0,0,0,0,0,0,0, # 78 - 7f +2,2,2,2,2,2,2,2, # 80 - 87 +2,2,2,2,2,2,2,2, # 88 - 8f +2,2,2,2,2,2,2,2, # 90 - 97 +2,2,2,2,2,2,2,2, # 98 - 9f +2,2,2,2,2,2,2,2, # a0 - a7 +2,2,2,2,2,2,2,2, # a8 - af +2,2,2,2,2,2,2,2, # b0 - b7 +2,2,2,2,2,2,2,2, # b8 - bf +2,2,2,2,2,2,2,2, # c0 - c7 +2,2,2,2,2,2,2,2, # c8 - cf +2,2,2,2,2,2,2,2, # d0 - d7 +2,2,2,2,2,2,2,2, # d8 - df +2,2,2,2,2,2,2,2, # e0 - e7 +2,2,2,2,2,2,2,2, # e8 - ef +2,2,2,2,2,2,2,2, # f0 - f7 +2,2,2,2,2,2,2,2, # f8 - ff +) + +ISO2022CN_ST = ( +MachineState.START, 3,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,# 00-07 +MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,# 08-0f +MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,# 10-17 +MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 4,MachineState.ERROR,# 18-1f +MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,# 20-27 + 5, 6,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,# 28-2f +MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,# 30-37 +MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ERROR,MachineState.START,# 38-3f +) + +ISO2022CN_CHAR_LEN_TABLE = (0, 0, 0, 0, 0, 0, 0, 0, 0) + +ISO2022CN_SM_MODEL = {'class_table': ISO2022CN_CLS, + 'class_factor': 9, + 'state_table': ISO2022CN_ST, + 'char_len_table': ISO2022CN_CHAR_LEN_TABLE, + 'name': "ISO-2022-CN", + 'language': 'Chinese'} + +ISO2022JP_CLS = ( +2,0,0,0,0,0,0,0, # 00 - 07 +0,0,0,0,0,0,2,2, # 08 - 0f +0,0,0,0,0,0,0,0, # 10 - 17 +0,0,0,1,0,0,0,0, # 18 - 1f +0,0,0,0,7,0,0,0, # 20 - 27 +3,0,0,0,0,0,0,0, # 28 - 2f +0,0,0,0,0,0,0,0, # 30 - 37 +0,0,0,0,0,0,0,0, # 38 - 3f +6,0,4,0,8,0,0,0, # 40 - 47 +0,9,5,0,0,0,0,0, # 48 - 4f +0,0,0,0,0,0,0,0, # 50 - 57 +0,0,0,0,0,0,0,0, # 58 - 5f +0,0,0,0,0,0,0,0, # 60 - 67 +0,0,0,0,0,0,0,0, # 68 - 6f +0,0,0,0,0,0,0,0, # 70 - 77 +0,0,0,0,0,0,0,0, # 78 - 7f +2,2,2,2,2,2,2,2, # 80 - 87 +2,2,2,2,2,2,2,2, # 88 - 8f +2,2,2,2,2,2,2,2, # 90 - 97 +2,2,2,2,2,2,2,2, # 98 - 9f +2,2,2,2,2,2,2,2, # a0 - a7 +2,2,2,2,2,2,2,2, # a8 - af +2,2,2,2,2,2,2,2, # b0 - b7 +2,2,2,2,2,2,2,2, # b8 - bf +2,2,2,2,2,2,2,2, # c0 - c7 +2,2,2,2,2,2,2,2, # c8 - cf +2,2,2,2,2,2,2,2, # d0 - d7 +2,2,2,2,2,2,2,2, # d8 - df +2,2,2,2,2,2,2,2, # e0 - e7 +2,2,2,2,2,2,2,2, # e8 - ef +2,2,2,2,2,2,2,2, # f0 - f7 +2,2,2,2,2,2,2,2, # f8 - ff +) + +ISO2022JP_ST = ( +MachineState.START, 3,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,# 00-07 +MachineState.START,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,# 08-0f +MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,# 10-17 +MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,# 18-1f +MachineState.ERROR, 5,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 4,MachineState.ERROR,MachineState.ERROR,# 20-27 +MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 6,MachineState.ITS_ME,MachineState.ERROR,MachineState.ITS_ME,MachineState.ERROR,# 28-2f +MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,# 30-37 +MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,# 38-3f +MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ERROR,MachineState.START,MachineState.START,# 40-47 +) + +ISO2022JP_CHAR_LEN_TABLE = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0) + +ISO2022JP_SM_MODEL = {'class_table': ISO2022JP_CLS, + 'class_factor': 10, + 'state_table': ISO2022JP_ST, + 'char_len_table': ISO2022JP_CHAR_LEN_TABLE, + 'name': "ISO-2022-JP", + 'language': 'Japanese'} + +ISO2022KR_CLS = ( +2,0,0,0,0,0,0,0, # 00 - 07 +0,0,0,0,0,0,0,0, # 08 - 0f +0,0,0,0,0,0,0,0, # 10 - 17 +0,0,0,1,0,0,0,0, # 18 - 1f +0,0,0,0,3,0,0,0, # 20 - 27 +0,4,0,0,0,0,0,0, # 28 - 2f +0,0,0,0,0,0,0,0, # 30 - 37 +0,0,0,0,0,0,0,0, # 38 - 3f +0,0,0,5,0,0,0,0, # 40 - 47 +0,0,0,0,0,0,0,0, # 48 - 4f +0,0,0,0,0,0,0,0, # 50 - 57 +0,0,0,0,0,0,0,0, # 58 - 5f +0,0,0,0,0,0,0,0, # 60 - 67 +0,0,0,0,0,0,0,0, # 68 - 6f +0,0,0,0,0,0,0,0, # 70 - 77 +0,0,0,0,0,0,0,0, # 78 - 7f +2,2,2,2,2,2,2,2, # 80 - 87 +2,2,2,2,2,2,2,2, # 88 - 8f +2,2,2,2,2,2,2,2, # 90 - 97 +2,2,2,2,2,2,2,2, # 98 - 9f +2,2,2,2,2,2,2,2, # a0 - a7 +2,2,2,2,2,2,2,2, # a8 - af +2,2,2,2,2,2,2,2, # b0 - b7 +2,2,2,2,2,2,2,2, # b8 - bf +2,2,2,2,2,2,2,2, # c0 - c7 +2,2,2,2,2,2,2,2, # c8 - cf +2,2,2,2,2,2,2,2, # d0 - d7 +2,2,2,2,2,2,2,2, # d8 - df +2,2,2,2,2,2,2,2, # e0 - e7 +2,2,2,2,2,2,2,2, # e8 - ef +2,2,2,2,2,2,2,2, # f0 - f7 +2,2,2,2,2,2,2,2, # f8 - ff +) + +ISO2022KR_ST = ( +MachineState.START, 3,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.ERROR,MachineState.ERROR,# 00-07 +MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,# 08-0f +MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 4,MachineState.ERROR,MachineState.ERROR,# 10-17 +MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 5,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,# 18-1f +MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.START,MachineState.START,MachineState.START,MachineState.START,# 20-27 +) + +ISO2022KR_CHAR_LEN_TABLE = (0, 0, 0, 0, 0, 0) + +ISO2022KR_SM_MODEL = {'class_table': ISO2022KR_CLS, + 'class_factor': 6, + 'state_table': ISO2022KR_ST, + 'char_len_table': ISO2022KR_CHAR_LEN_TABLE, + 'name': "ISO-2022-KR", + 'language': 'Korean'} + + diff --git a/venv/Lib/site-packages/pip/_vendor/chardet/eucjpprober.py b/venv/Lib/site-packages/pip/_vendor/chardet/eucjpprober.py new file mode 100644 index 0000000..20ce8f7 --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/chardet/eucjpprober.py @@ -0,0 +1,92 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .enums import ProbingState, MachineState +from .mbcharsetprober import MultiByteCharSetProber +from .codingstatemachine import CodingStateMachine +from .chardistribution import EUCJPDistributionAnalysis +from .jpcntx import EUCJPContextAnalysis +from .mbcssm import EUCJP_SM_MODEL + + +class EUCJPProber(MultiByteCharSetProber): + def __init__(self): + super(EUCJPProber, self).__init__() + self.coding_sm = CodingStateMachine(EUCJP_SM_MODEL) + self.distribution_analyzer = EUCJPDistributionAnalysis() + self.context_analyzer = EUCJPContextAnalysis() + self.reset() + + def reset(self): + super(EUCJPProber, self).reset() + self.context_analyzer.reset() + + @property + def charset_name(self): + return "EUC-JP" + + @property + def language(self): + return "Japanese" + + def feed(self, byte_str): + for i in range(len(byte_str)): + # PY3K: byte_str is a byte array, so byte_str[i] is an int, not a byte + coding_state = self.coding_sm.next_state(byte_str[i]) + if coding_state == MachineState.ERROR: + self.logger.debug('%s %s prober hit error at byte %s', + self.charset_name, self.language, i) + self._state = ProbingState.NOT_ME + break + elif coding_state == MachineState.ITS_ME: + self._state = ProbingState.FOUND_IT + break + elif coding_state == MachineState.START: + char_len = self.coding_sm.get_current_charlen() + if i == 0: + self._last_char[1] = byte_str[0] + self.context_analyzer.feed(self._last_char, char_len) + self.distribution_analyzer.feed(self._last_char, char_len) + else: + self.context_analyzer.feed(byte_str[i - 1:i + 1], + char_len) + self.distribution_analyzer.feed(byte_str[i - 1:i + 1], + char_len) + + self._last_char[0] = byte_str[-1] + + if self.state == ProbingState.DETECTING: + if (self.context_analyzer.got_enough_data() and + (self.get_confidence() > self.SHORTCUT_THRESHOLD)): + self._state = ProbingState.FOUND_IT + + return self.state + + def get_confidence(self): + context_conf = self.context_analyzer.get_confidence() + distrib_conf = self.distribution_analyzer.get_confidence() + return max(context_conf, distrib_conf) diff --git a/venv/Lib/site-packages/pip/_vendor/chardet/euckrfreq.py b/venv/Lib/site-packages/pip/_vendor/chardet/euckrfreq.py new file mode 100644 index 0000000..b68078c --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/chardet/euckrfreq.py @@ -0,0 +1,195 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +# Sampling from about 20M text materials include literature and computer technology + +# 128 --> 0.79 +# 256 --> 0.92 +# 512 --> 0.986 +# 1024 --> 0.99944 +# 2048 --> 0.99999 +# +# Idea Distribution Ratio = 0.98653 / (1-0.98653) = 73.24 +# Random Distribution Ration = 512 / (2350-512) = 0.279. +# +# Typical Distribution Ratio + +EUCKR_TYPICAL_DISTRIBUTION_RATIO = 6.0 + +EUCKR_TABLE_SIZE = 2352 + +# Char to FreqOrder table , +EUCKR_CHAR_TO_FREQ_ORDER = ( + 13, 130, 120,1396, 481,1719,1720, 328, 609, 212,1721, 707, 400, 299,1722, 87, +1397,1723, 104, 536,1117,1203,1724,1267, 685,1268, 508,1725,1726,1727,1728,1398, +1399,1729,1730,1731, 141, 621, 326,1057, 368,1732, 267, 488, 20,1733,1269,1734, + 945,1400,1735, 47, 904,1270,1736,1737, 773, 248,1738, 409, 313, 786, 429,1739, + 116, 987, 813,1401, 683, 75,1204, 145,1740,1741,1742,1743, 16, 847, 667, 622, + 708,1744,1745,1746, 966, 787, 304, 129,1747, 60, 820, 123, 676,1748,1749,1750, +1751, 617,1752, 626,1753,1754,1755,1756, 653,1757,1758,1759,1760,1761,1762, 856, + 344,1763,1764,1765,1766, 89, 401, 418, 806, 905, 848,1767,1768,1769, 946,1205, + 709,1770,1118,1771, 241,1772,1773,1774,1271,1775, 569,1776, 999,1777,1778,1779, +1780, 337, 751,1058, 28, 628, 254,1781, 177, 906, 270, 349, 891,1079,1782, 19, +1783, 379,1784, 315,1785, 629, 754,1402, 559,1786, 636, 203,1206,1787, 710, 567, +1788, 935, 814,1789,1790,1207, 766, 528,1791,1792,1208,1793,1794,1795,1796,1797, +1403,1798,1799, 533,1059,1404,1405,1156,1406, 936, 884,1080,1800, 351,1801,1802, +1803,1804,1805, 801,1806,1807,1808,1119,1809,1157, 714, 474,1407,1810, 298, 899, + 885,1811,1120, 802,1158,1812, 892,1813,1814,1408, 659,1815,1816,1121,1817,1818, +1819,1820,1821,1822, 319,1823, 594, 545,1824, 815, 937,1209,1825,1826, 573,1409, +1022,1827,1210,1828,1829,1830,1831,1832,1833, 556, 722, 807,1122,1060,1834, 697, +1835, 900, 557, 715,1836,1410, 540,1411, 752,1159, 294, 597,1211, 976, 803, 770, +1412,1837,1838, 39, 794,1413, 358,1839, 371, 925,1840, 453, 661, 788, 531, 723, + 544,1023,1081, 869, 91,1841, 392, 430, 790, 602,1414, 677,1082, 457,1415,1416, +1842,1843, 475, 327,1024,1417, 795, 121,1844, 733, 403,1418,1845,1846,1847, 300, + 119, 711,1212, 627,1848,1272, 207,1849,1850, 796,1213, 382,1851, 519,1852,1083, + 893,1853,1854,1855, 367, 809, 487, 671,1856, 663,1857,1858, 956, 471, 306, 857, +1859,1860,1160,1084,1861,1862,1863,1864,1865,1061,1866,1867,1868,1869,1870,1871, + 282, 96, 574,1872, 502,1085,1873,1214,1874, 907,1875,1876, 827, 977,1419,1420, +1421, 268,1877,1422,1878,1879,1880, 308,1881, 2, 537,1882,1883,1215,1884,1885, + 127, 791,1886,1273,1423,1887, 34, 336, 404, 643,1888, 571, 654, 894, 840,1889, + 0, 886,1274, 122, 575, 260, 908, 938,1890,1275, 410, 316,1891,1892, 100,1893, +1894,1123, 48,1161,1124,1025,1895, 633, 901,1276,1896,1897, 115, 816,1898, 317, +1899, 694,1900, 909, 734,1424, 572, 866,1425, 691, 85, 524,1010, 543, 394, 841, +1901,1902,1903,1026,1904,1905,1906,1907,1908,1909, 30, 451, 651, 988, 310,1910, +1911,1426, 810,1216, 93,1912,1913,1277,1217,1914, 858, 759, 45, 58, 181, 610, + 269,1915,1916, 131,1062, 551, 443,1000, 821,1427, 957, 895,1086,1917,1918, 375, +1919, 359,1920, 687,1921, 822,1922, 293,1923,1924, 40, 662, 118, 692, 29, 939, + 887, 640, 482, 174,1925, 69,1162, 728,1428, 910,1926,1278,1218,1279, 386, 870, + 217, 854,1163, 823,1927,1928,1929,1930, 834,1931, 78,1932, 859,1933,1063,1934, +1935,1936,1937, 438,1164, 208, 595,1938,1939,1940,1941,1219,1125,1942, 280, 888, +1429,1430,1220,1431,1943,1944,1945,1946,1947,1280, 150, 510,1432,1948,1949,1950, +1951,1952,1953,1954,1011,1087,1955,1433,1043,1956, 881,1957, 614, 958,1064,1065, +1221,1958, 638,1001, 860, 967, 896,1434, 989, 492, 553,1281,1165,1959,1282,1002, +1283,1222,1960,1961,1962,1963, 36, 383, 228, 753, 247, 454,1964, 876, 678,1965, +1966,1284, 126, 464, 490, 835, 136, 672, 529, 940,1088,1435, 473,1967,1968, 467, + 50, 390, 227, 587, 279, 378, 598, 792, 968, 240, 151, 160, 849, 882,1126,1285, + 639,1044, 133, 140, 288, 360, 811, 563,1027, 561, 142, 523,1969,1970,1971, 7, + 103, 296, 439, 407, 506, 634, 990,1972,1973,1974,1975, 645,1976,1977,1978,1979, +1980,1981, 236,1982,1436,1983,1984,1089, 192, 828, 618, 518,1166, 333,1127,1985, + 818,1223,1986,1987,1988,1989,1990,1991,1992,1993, 342,1128,1286, 746, 842,1994, +1995, 560, 223,1287, 98, 8, 189, 650, 978,1288,1996,1437,1997, 17, 345, 250, + 423, 277, 234, 512, 226, 97, 289, 42, 167,1998, 201,1999,2000, 843, 836, 824, + 532, 338, 783,1090, 182, 576, 436,1438,1439, 527, 500,2001, 947, 889,2002,2003, +2004,2005, 262, 600, 314, 447,2006, 547,2007, 693, 738,1129,2008, 71,1440, 745, + 619, 688,2009, 829,2010,2011, 147,2012, 33, 948,2013,2014, 74, 224,2015, 61, + 191, 918, 399, 637,2016,1028,1130, 257, 902,2017,2018,2019,2020,2021,2022,2023, +2024,2025,2026, 837,2027,2028,2029,2030, 179, 874, 591, 52, 724, 246,2031,2032, +2033,2034,1167, 969,2035,1289, 630, 605, 911,1091,1168,2036,2037,2038,1441, 912, +2039, 623,2040,2041, 253,1169,1290,2042,1442, 146, 620, 611, 577, 433,2043,1224, + 719,1170, 959, 440, 437, 534, 84, 388, 480,1131, 159, 220, 198, 679,2044,1012, + 819,1066,1443, 113,1225, 194, 318,1003,1029,2045,2046,2047,2048,1067,2049,2050, +2051,2052,2053, 59, 913, 112,2054, 632,2055, 455, 144, 739,1291,2056, 273, 681, + 499,2057, 448,2058,2059, 760,2060,2061, 970, 384, 169, 245,1132,2062,2063, 414, +1444,2064,2065, 41, 235,2066, 157, 252, 877, 568, 919, 789, 580,2067, 725,2068, +2069,1292,2070,2071,1445,2072,1446,2073,2074, 55, 588, 66,1447, 271,1092,2075, +1226,2076, 960,1013, 372,2077,2078,2079,2080,2081,1293,2082,2083,2084,2085, 850, +2086,2087,2088,2089,2090, 186,2091,1068, 180,2092,2093,2094, 109,1227, 522, 606, +2095, 867,1448,1093, 991,1171, 926, 353,1133,2096, 581,2097,2098,2099,1294,1449, +1450,2100, 596,1172,1014,1228,2101,1451,1295,1173,1229,2102,2103,1296,1134,1452, + 949,1135,2104,2105,1094,1453,1454,1455,2106,1095,2107,2108,2109,2110,2111,2112, +2113,2114,2115,2116,2117, 804,2118,2119,1230,1231, 805,1456, 405,1136,2120,2121, +2122,2123,2124, 720, 701,1297, 992,1457, 927,1004,2125,2126,2127,2128,2129,2130, + 22, 417,2131, 303,2132, 385,2133, 971, 520, 513,2134,1174, 73,1096, 231, 274, + 962,1458, 673,2135,1459,2136, 152,1137,2137,2138,2139,2140,1005,1138,1460,1139, +2141,2142,2143,2144, 11, 374, 844,2145, 154,1232, 46,1461,2146, 838, 830, 721, +1233, 106,2147, 90, 428, 462, 578, 566,1175, 352,2148,2149, 538,1234, 124,1298, +2150,1462, 761, 565,2151, 686,2152, 649,2153, 72, 173,2154, 460, 415,2155,1463, +2156,1235, 305,2157,2158,2159,2160,2161,2162, 579,2163,2164,2165,2166,2167, 747, +2168,2169,2170,2171,1464, 669,2172,2173,2174,2175,2176,1465,2177, 23, 530, 285, +2178, 335, 729,2179, 397,2180,2181,2182,1030,2183,2184, 698,2185,2186, 325,2187, +2188, 369,2189, 799,1097,1015, 348,2190,1069, 680,2191, 851,1466,2192,2193, 10, +2194, 613, 424,2195, 979, 108, 449, 589, 27, 172, 81,1031, 80, 774, 281, 350, +1032, 525, 301, 582,1176,2196, 674,1045,2197,2198,1467, 730, 762,2199,2200,2201, +2202,1468,2203, 993,2204,2205, 266,1070, 963,1140,2206,2207,2208, 664,1098, 972, +2209,2210,2211,1177,1469,1470, 871,2212,2213,2214,2215,2216,1471,2217,2218,2219, +2220,2221,2222,2223,2224,2225,2226,2227,1472,1236,2228,2229,2230,2231,2232,2233, +2234,2235,1299,2236,2237, 200,2238, 477, 373,2239,2240, 731, 825, 777,2241,2242, +2243, 521, 486, 548,2244,2245,2246,1473,1300, 53, 549, 137, 875, 76, 158,2247, +1301,1474, 469, 396,1016, 278, 712,2248, 321, 442, 503, 767, 744, 941,1237,1178, +1475,2249, 82, 178,1141,1179, 973,2250,1302,2251, 297,2252,2253, 570,2254,2255, +2256, 18, 450, 206,2257, 290, 292,1142,2258, 511, 162, 99, 346, 164, 735,2259, +1476,1477, 4, 554, 343, 798,1099,2260,1100,2261, 43, 171,1303, 139, 215,2262, +2263, 717, 775,2264,1033, 322, 216,2265, 831,2266, 149,2267,1304,2268,2269, 702, +1238, 135, 845, 347, 309,2270, 484,2271, 878, 655, 238,1006,1478,2272, 67,2273, + 295,2274,2275, 461,2276, 478, 942, 412,2277,1034,2278,2279,2280, 265,2281, 541, +2282,2283,2284,2285,2286, 70, 852,1071,2287,2288,2289,2290, 21, 56, 509, 117, + 432,2291,2292, 331, 980, 552,1101, 148, 284, 105, 393,1180,1239, 755,2293, 187, +2294,1046,1479,2295, 340,2296, 63,1047, 230,2297,2298,1305, 763,1306, 101, 800, + 808, 494,2299,2300,2301, 903,2302, 37,1072, 14, 5,2303, 79, 675,2304, 312, +2305,2306,2307,2308,2309,1480, 6,1307,2310,2311,2312, 1, 470, 35, 24, 229, +2313, 695, 210, 86, 778, 15, 784, 592, 779, 32, 77, 855, 964,2314, 259,2315, + 501, 380,2316,2317, 83, 981, 153, 689,1308,1481,1482,1483,2318,2319, 716,1484, +2320,2321,2322,2323,2324,2325,1485,2326,2327, 128, 57, 68, 261,1048, 211, 170, +1240, 31,2328, 51, 435, 742,2329,2330,2331, 635,2332, 264, 456,2333,2334,2335, + 425,2336,1486, 143, 507, 263, 943,2337, 363, 920,1487, 256,1488,1102, 243, 601, +1489,2338,2339,2340,2341,2342,2343,2344, 861,2345,2346,2347,2348,2349,2350, 395, +2351,1490,1491, 62, 535, 166, 225,2352,2353, 668, 419,1241, 138, 604, 928,2354, +1181,2355,1492,1493,2356,2357,2358,1143,2359, 696,2360, 387, 307,1309, 682, 476, +2361,2362, 332, 12, 222, 156,2363, 232,2364, 641, 276, 656, 517,1494,1495,1035, + 416, 736,1496,2365,1017, 586,2366,2367,2368,1497,2369, 242,2370,2371,2372,1498, +2373, 965, 713,2374,2375,2376,2377, 740, 982,1499, 944,1500,1007,2378,2379,1310, +1501,2380,2381,2382, 785, 329,2383,2384,1502,2385,2386,2387, 932,2388,1503,2389, +2390,2391,2392,1242,2393,2394,2395,2396,2397, 994, 950,2398,2399,2400,2401,1504, +1311,2402,2403,2404,2405,1049, 749,2406,2407, 853, 718,1144,1312,2408,1182,1505, +2409,2410, 255, 516, 479, 564, 550, 214,1506,1507,1313, 413, 239, 444, 339,1145, +1036,1508,1509,1314,1037,1510,1315,2411,1511,2412,2413,2414, 176, 703, 497, 624, + 593, 921, 302,2415, 341, 165,1103,1512,2416,1513,2417,2418,2419, 376,2420, 700, +2421,2422,2423, 258, 768,1316,2424,1183,2425, 995, 608,2426,2427,2428,2429, 221, +2430,2431,2432,2433,2434,2435,2436,2437, 195, 323, 726, 188, 897, 983,1317, 377, + 644,1050, 879,2438, 452,2439,2440,2441,2442,2443,2444, 914,2445,2446,2447,2448, + 915, 489,2449,1514,1184,2450,2451, 515, 64, 427, 495,2452, 583,2453, 483, 485, +1038, 562, 213,1515, 748, 666,2454,2455,2456,2457, 334,2458, 780, 996,1008, 705, +1243,2459,2460,2461,2462,2463, 114,2464, 493,1146, 366, 163,1516, 961,1104,2465, + 291,2466,1318,1105,2467,1517, 365,2468, 355, 951,1244,2469,1319,2470, 631,2471, +2472, 218,1320, 364, 320, 756,1518,1519,1321,1520,1322,2473,2474,2475,2476, 997, +2477,2478,2479,2480, 665,1185,2481, 916,1521,2482,2483,2484, 584, 684,2485,2486, + 797,2487,1051,1186,2488,2489,2490,1522,2491,2492, 370,2493,1039,1187, 65,2494, + 434, 205, 463,1188,2495, 125, 812, 391, 402, 826, 699, 286, 398, 155, 781, 771, + 585,2496, 590, 505,1073,2497, 599, 244, 219, 917,1018, 952, 646,1523,2498,1323, +2499,2500, 49, 984, 354, 741,2501, 625,2502,1324,2503,1019, 190, 357, 757, 491, + 95, 782, 868,2504,2505,2506,2507,2508,2509, 134,1524,1074, 422,1525, 898,2510, + 161,2511,2512,2513,2514, 769,2515,1526,2516,2517, 411,1325,2518, 472,1527,2519, +2520,2521,2522,2523,2524, 985,2525,2526,2527,2528,2529,2530, 764,2531,1245,2532, +2533, 25, 204, 311,2534, 496,2535,1052,2536,2537,2538,2539,2540,2541,2542, 199, + 704, 504, 468, 758, 657,1528, 196, 44, 839,1246, 272, 750,2543, 765, 862,2544, +2545,1326,2546, 132, 615, 933,2547, 732,2548,2549,2550,1189,1529,2551, 283,1247, +1053, 607, 929,2552,2553,2554, 930, 183, 872, 616,1040,1147,2555,1148,1020, 441, + 249,1075,2556,2557,2558, 466, 743,2559,2560,2561, 92, 514, 426, 420, 526,2562, +2563,2564,2565,2566,2567,2568, 185,2569,2570,2571,2572, 776,1530, 658,2573, 362, +2574, 361, 922,1076, 793,2575,2576,2577,2578,2579,2580,1531, 251,2581,2582,2583, +2584,1532, 54, 612, 237,1327,2585,2586, 275, 408, 647, 111,2587,1533,1106, 465, + 3, 458, 9, 38,2588, 107, 110, 890, 209, 26, 737, 498,2589,1534,2590, 431, + 202, 88,1535, 356, 287,1107, 660,1149,2591, 381,1536, 986,1150, 445,1248,1151, + 974,2592,2593, 846,2594, 446, 953, 184,1249,1250, 727,2595, 923, 193, 883,2596, +2597,2598, 102, 324, 539, 817,2599, 421,1041,2600, 832,2601, 94, 175, 197, 406, +2602, 459,2603,2604,2605,2606,2607, 330, 555,2608,2609,2610, 706,1108, 389,2611, +2612,2613,2614, 233,2615, 833, 558, 931, 954,1251,2616,2617,1537, 546,2618,2619, +1009,2620,2621,2622,1538, 690,1328,2623, 955,2624,1539,2625,2626, 772,2627,2628, +2629,2630,2631, 924, 648, 863, 603,2632,2633, 934,1540, 864, 865,2634, 642,1042, + 670,1190,2635,2636,2637,2638, 168,2639, 652, 873, 542,1054,1541,2640,2641,2642, # 512, 256 +) + diff --git a/venv/Lib/site-packages/pip/_vendor/chardet/euckrprober.py b/venv/Lib/site-packages/pip/_vendor/chardet/euckrprober.py new file mode 100644 index 0000000..345a060 --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/chardet/euckrprober.py @@ -0,0 +1,47 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .mbcharsetprober import MultiByteCharSetProber +from .codingstatemachine import CodingStateMachine +from .chardistribution import EUCKRDistributionAnalysis +from .mbcssm import EUCKR_SM_MODEL + + +class EUCKRProber(MultiByteCharSetProber): + def __init__(self): + super(EUCKRProber, self).__init__() + self.coding_sm = CodingStateMachine(EUCKR_SM_MODEL) + self.distribution_analyzer = EUCKRDistributionAnalysis() + self.reset() + + @property + def charset_name(self): + return "EUC-KR" + + @property + def language(self): + return "Korean" diff --git a/venv/Lib/site-packages/pip/_vendor/chardet/euctwfreq.py b/venv/Lib/site-packages/pip/_vendor/chardet/euctwfreq.py new file mode 100644 index 0000000..ed7a995 --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/chardet/euctwfreq.py @@ -0,0 +1,387 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +# EUCTW frequency table +# Converted from big5 work +# by Taiwan's Mandarin Promotion Council +# + +# 128 --> 0.42261 +# 256 --> 0.57851 +# 512 --> 0.74851 +# 1024 --> 0.89384 +# 2048 --> 0.97583 +# +# Idea Distribution Ratio = 0.74851/(1-0.74851) =2.98 +# Random Distribution Ration = 512/(5401-512)=0.105 +# +# Typical Distribution Ratio about 25% of Ideal one, still much higher than RDR + +EUCTW_TYPICAL_DISTRIBUTION_RATIO = 0.75 + +# Char to FreqOrder table , +EUCTW_TABLE_SIZE = 5376 + +EUCTW_CHAR_TO_FREQ_ORDER = ( + 1,1800,1506, 255,1431, 198, 9, 82, 6,7310, 177, 202,3615,1256,2808, 110, # 2742 +3735, 33,3241, 261, 76, 44,2113, 16,2931,2184,1176, 659,3868, 26,3404,2643, # 2758 +1198,3869,3313,4060, 410,2211, 302, 590, 361,1963, 8, 204, 58,4296,7311,1931, # 2774 + 63,7312,7313, 317,1614, 75, 222, 159,4061,2412,1480,7314,3500,3068, 224,2809, # 2790 +3616, 3, 10,3870,1471, 29,2774,1135,2852,1939, 873, 130,3242,1123, 312,7315, # 2806 +4297,2051, 507, 252, 682,7316, 142,1914, 124, 206,2932, 34,3501,3173, 64, 604, # 2822 +7317,2494,1976,1977, 155,1990, 645, 641,1606,7318,3405, 337, 72, 406,7319, 80, # 2838 + 630, 238,3174,1509, 263, 939,1092,2644, 756,1440,1094,3406, 449, 69,2969, 591, # 2854 + 179,2095, 471, 115,2034,1843, 60, 50,2970, 134, 806,1868, 734,2035,3407, 180, # 2870 + 995,1607, 156, 537,2893, 688,7320, 319,1305, 779,2144, 514,2374, 298,4298, 359, # 2886 +2495, 90,2707,1338, 663, 11, 906,1099,2545, 20,2436, 182, 532,1716,7321, 732, # 2902 +1376,4062,1311,1420,3175, 25,2312,1056, 113, 399, 382,1949, 242,3408,2467, 529, # 2918 +3243, 475,1447,3617,7322, 117, 21, 656, 810,1297,2295,2329,3502,7323, 126,4063, # 2934 + 706, 456, 150, 613,4299, 71,1118,2036,4064, 145,3069, 85, 835, 486,2114,1246, # 2950 +1426, 428, 727,1285,1015, 800, 106, 623, 303,1281,7324,2127,2354, 347,3736, 221, # 2966 +3503,3110,7325,1955,1153,4065, 83, 296,1199,3070, 192, 624, 93,7326, 822,1897, # 2982 +2810,3111, 795,2064, 991,1554,1542,1592, 27, 43,2853, 859, 139,1456, 860,4300, # 2998 + 437, 712,3871, 164,2392,3112, 695, 211,3017,2096, 195,3872,1608,3504,3505,3618, # 3014 +3873, 234, 811,2971,2097,3874,2229,1441,3506,1615,2375, 668,2076,1638, 305, 228, # 3030 +1664,4301, 467, 415,7327, 262,2098,1593, 239, 108, 300, 200,1033, 512,1247,2077, # 3046 +7328,7329,2173,3176,3619,2673, 593, 845,1062,3244, 88,1723,2037,3875,1950, 212, # 3062 + 266, 152, 149, 468,1898,4066,4302, 77, 187,7330,3018, 37, 5,2972,7331,3876, # 3078 +7332,7333, 39,2517,4303,2894,3177,2078, 55, 148, 74,4304, 545, 483,1474,1029, # 3094 +1665, 217,1869,1531,3113,1104,2645,4067, 24, 172,3507, 900,3877,3508,3509,4305, # 3110 + 32,1408,2811,1312, 329, 487,2355,2247,2708, 784,2674, 4,3019,3314,1427,1788, # 3126 + 188, 109, 499,7334,3620,1717,1789, 888,1217,3020,4306,7335,3510,7336,3315,1520, # 3142 +3621,3878, 196,1034, 775,7337,7338, 929,1815, 249, 439, 38,7339,1063,7340, 794, # 3158 +3879,1435,2296, 46, 178,3245,2065,7341,2376,7342, 214,1709,4307, 804, 35, 707, # 3174 + 324,3622,1601,2546, 140, 459,4068,7343,7344,1365, 839, 272, 978,2257,2572,3409, # 3190 +2128,1363,3623,1423, 697, 100,3071, 48, 70,1231, 495,3114,2193,7345,1294,7346, # 3206 +2079, 462, 586,1042,3246, 853, 256, 988, 185,2377,3410,1698, 434,1084,7347,3411, # 3222 + 314,2615,2775,4308,2330,2331, 569,2280, 637,1816,2518, 757,1162,1878,1616,3412, # 3238 + 287,1577,2115, 768,4309,1671,2854,3511,2519,1321,3737, 909,2413,7348,4069, 933, # 3254 +3738,7349,2052,2356,1222,4310, 765,2414,1322, 786,4311,7350,1919,1462,1677,2895, # 3270 +1699,7351,4312,1424,2437,3115,3624,2590,3316,1774,1940,3413,3880,4070, 309,1369, # 3286 +1130,2812, 364,2230,1653,1299,3881,3512,3882,3883,2646, 525,1085,3021, 902,2000, # 3302 +1475, 964,4313, 421,1844,1415,1057,2281, 940,1364,3116, 376,4314,4315,1381, 7, # 3318 +2520, 983,2378, 336,1710,2675,1845, 321,3414, 559,1131,3022,2742,1808,1132,1313, # 3334 + 265,1481,1857,7352, 352,1203,2813,3247, 167,1089, 420,2814, 776, 792,1724,3513, # 3350 +4071,2438,3248,7353,4072,7354, 446, 229, 333,2743, 901,3739,1200,1557,4316,2647, # 3366 +1920, 395,2744,2676,3740,4073,1835, 125, 916,3178,2616,4317,7355,7356,3741,7357, # 3382 +7358,7359,4318,3117,3625,1133,2547,1757,3415,1510,2313,1409,3514,7360,2145, 438, # 3398 +2591,2896,2379,3317,1068, 958,3023, 461, 311,2855,2677,4074,1915,3179,4075,1978, # 3414 + 383, 750,2745,2617,4076, 274, 539, 385,1278,1442,7361,1154,1964, 384, 561, 210, # 3430 + 98,1295,2548,3515,7362,1711,2415,1482,3416,3884,2897,1257, 129,7363,3742, 642, # 3446 + 523,2776,2777,2648,7364, 141,2231,1333, 68, 176, 441, 876, 907,4077, 603,2592, # 3462 + 710, 171,3417, 404, 549, 18,3118,2393,1410,3626,1666,7365,3516,4319,2898,4320, # 3478 +7366,2973, 368,7367, 146, 366, 99, 871,3627,1543, 748, 807,1586,1185, 22,2258, # 3494 + 379,3743,3180,7368,3181, 505,1941,2618,1991,1382,2314,7369, 380,2357, 218, 702, # 3510 +1817,1248,3418,3024,3517,3318,3249,7370,2974,3628, 930,3250,3744,7371, 59,7372, # 3526 + 585, 601,4078, 497,3419,1112,1314,4321,1801,7373,1223,1472,2174,7374, 749,1836, # 3542 + 690,1899,3745,1772,3885,1476, 429,1043,1790,2232,2116, 917,4079, 447,1086,1629, # 3558 +7375, 556,7376,7377,2020,1654, 844,1090, 105, 550, 966,1758,2815,1008,1782, 686, # 3574 +1095,7378,2282, 793,1602,7379,3518,2593,4322,4080,2933,2297,4323,3746, 980,2496, # 3590 + 544, 353, 527,4324, 908,2678,2899,7380, 381,2619,1942,1348,7381,1341,1252, 560, # 3606 +3072,7382,3420,2856,7383,2053, 973, 886,2080, 143,4325,7384,7385, 157,3886, 496, # 3622 +4081, 57, 840, 540,2038,4326,4327,3421,2117,1445, 970,2259,1748,1965,2081,4082, # 3638 +3119,1234,1775,3251,2816,3629, 773,1206,2129,1066,2039,1326,3887,1738,1725,4083, # 3654 + 279,3120, 51,1544,2594, 423,1578,2130,2066, 173,4328,1879,7386,7387,1583, 264, # 3670 + 610,3630,4329,2439, 280, 154,7388,7389,7390,1739, 338,1282,3073, 693,2857,1411, # 3686 +1074,3747,2440,7391,4330,7392,7393,1240, 952,2394,7394,2900,1538,2679, 685,1483, # 3702 +4084,2468,1436, 953,4085,2054,4331, 671,2395, 79,4086,2441,3252, 608, 567,2680, # 3718 +3422,4087,4088,1691, 393,1261,1791,2396,7395,4332,7396,7397,7398,7399,1383,1672, # 3734 +3748,3182,1464, 522,1119, 661,1150, 216, 675,4333,3888,1432,3519, 609,4334,2681, # 3750 +2397,7400,7401,7402,4089,3025, 0,7403,2469, 315, 231,2442, 301,3319,4335,2380, # 3766 +7404, 233,4090,3631,1818,4336,4337,7405, 96,1776,1315,2082,7406, 257,7407,1809, # 3782 +3632,2709,1139,1819,4091,2021,1124,2163,2778,1777,2649,7408,3074, 363,1655,3183, # 3798 +7409,2975,7410,7411,7412,3889,1567,3890, 718, 103,3184, 849,1443, 341,3320,2934, # 3814 +1484,7413,1712, 127, 67, 339,4092,2398, 679,1412, 821,7414,7415, 834, 738, 351, # 3830 +2976,2146, 846, 235,1497,1880, 418,1992,3749,2710, 186,1100,2147,2746,3520,1545, # 3846 +1355,2935,2858,1377, 583,3891,4093,2573,2977,7416,1298,3633,1078,2549,3634,2358, # 3862 + 78,3750,3751, 267,1289,2099,2001,1594,4094, 348, 369,1274,2194,2175,1837,4338, # 3878 +1820,2817,3635,2747,2283,2002,4339,2936,2748, 144,3321, 882,4340,3892,2749,3423, # 3894 +4341,2901,7417,4095,1726, 320,7418,3893,3026, 788,2978,7419,2818,1773,1327,2859, # 3910 +3894,2819,7420,1306,4342,2003,1700,3752,3521,2359,2650, 787,2022, 506, 824,3636, # 3926 + 534, 323,4343,1044,3322,2023,1900, 946,3424,7421,1778,1500,1678,7422,1881,4344, # 3942 + 165, 243,4345,3637,2521, 123, 683,4096, 764,4346, 36,3895,1792, 589,2902, 816, # 3958 + 626,1667,3027,2233,1639,1555,1622,3753,3896,7423,3897,2860,1370,1228,1932, 891, # 3974 +2083,2903, 304,4097,7424, 292,2979,2711,3522, 691,2100,4098,1115,4347, 118, 662, # 3990 +7425, 611,1156, 854,2381,1316,2861, 2, 386, 515,2904,7426,7427,3253, 868,2234, # 4006 +1486, 855,2651, 785,2212,3028,7428,1040,3185,3523,7429,3121, 448,7430,1525,7431, # 4022 +2164,4348,7432,3754,7433,4099,2820,3524,3122, 503, 818,3898,3123,1568, 814, 676, # 4038 +1444, 306,1749,7434,3755,1416,1030, 197,1428, 805,2821,1501,4349,7435,7436,7437, # 4054 +1993,7438,4350,7439,7440,2195, 13,2779,3638,2980,3124,1229,1916,7441,3756,2131, # 4070 +7442,4100,4351,2399,3525,7443,2213,1511,1727,1120,7444,7445, 646,3757,2443, 307, # 4086 +7446,7447,1595,3186,7448,7449,7450,3639,1113,1356,3899,1465,2522,2523,7451, 519, # 4102 +7452, 128,2132, 92,2284,1979,7453,3900,1512, 342,3125,2196,7454,2780,2214,1980, # 4118 +3323,7455, 290,1656,1317, 789, 827,2360,7456,3758,4352, 562, 581,3901,7457, 401, # 4134 +4353,2248, 94,4354,1399,2781,7458,1463,2024,4355,3187,1943,7459, 828,1105,4101, # 4150 +1262,1394,7460,4102, 605,4356,7461,1783,2862,7462,2822, 819,2101, 578,2197,2937, # 4166 +7463,1502, 436,3254,4103,3255,2823,3902,2905,3425,3426,7464,2712,2315,7465,7466, # 4182 +2332,2067, 23,4357, 193, 826,3759,2102, 699,1630,4104,3075, 390,1793,1064,3526, # 4198 +7467,1579,3076,3077,1400,7468,4105,1838,1640,2863,7469,4358,4359, 137,4106, 598, # 4214 +3078,1966, 780, 104, 974,2938,7470, 278, 899, 253, 402, 572, 504, 493,1339,7471, # 4230 +3903,1275,4360,2574,2550,7472,3640,3029,3079,2249, 565,1334,2713, 863, 41,7473, # 4246 +7474,4361,7475,1657,2333, 19, 463,2750,4107, 606,7476,2981,3256,1087,2084,1323, # 4262 +2652,2982,7477,1631,1623,1750,4108,2682,7478,2864, 791,2714,2653,2334, 232,2416, # 4278 +7479,2983,1498,7480,2654,2620, 755,1366,3641,3257,3126,2025,1609, 119,1917,3427, # 4294 + 862,1026,4109,7481,3904,3760,4362,3905,4363,2260,1951,2470,7482,1125, 817,4110, # 4310 +4111,3906,1513,1766,2040,1487,4112,3030,3258,2824,3761,3127,7483,7484,1507,7485, # 4326 +2683, 733, 40,1632,1106,2865, 345,4113, 841,2524, 230,4364,2984,1846,3259,3428, # 4342 +7486,1263, 986,3429,7487, 735, 879, 254,1137, 857, 622,1300,1180,1388,1562,3907, # 4358 +3908,2939, 967,2751,2655,1349, 592,2133,1692,3324,2985,1994,4114,1679,3909,1901, # 4374 +2185,7488, 739,3642,2715,1296,1290,7489,4115,2198,2199,1921,1563,2595,2551,1870, # 4390 +2752,2986,7490, 435,7491, 343,1108, 596, 17,1751,4365,2235,3430,3643,7492,4366, # 4406 + 294,3527,2940,1693, 477, 979, 281,2041,3528, 643,2042,3644,2621,2782,2261,1031, # 4422 +2335,2134,2298,3529,4367, 367,1249,2552,7493,3530,7494,4368,1283,3325,2004, 240, # 4438 +1762,3326,4369,4370, 836,1069,3128, 474,7495,2148,2525, 268,3531,7496,3188,1521, # 4454 +1284,7497,1658,1546,4116,7498,3532,3533,7499,4117,3327,2684,1685,4118, 961,1673, # 4470 +2622, 190,2005,2200,3762,4371,4372,7500, 570,2497,3645,1490,7501,4373,2623,3260, # 4486 +1956,4374, 584,1514, 396,1045,1944,7502,4375,1967,2444,7503,7504,4376,3910, 619, # 4502 +7505,3129,3261, 215,2006,2783,2553,3189,4377,3190,4378, 763,4119,3763,4379,7506, # 4518 +7507,1957,1767,2941,3328,3646,1174, 452,1477,4380,3329,3130,7508,2825,1253,2382, # 4534 +2186,1091,2285,4120, 492,7509, 638,1169,1824,2135,1752,3911, 648, 926,1021,1324, # 4550 +4381, 520,4382, 997, 847,1007, 892,4383,3764,2262,1871,3647,7510,2400,1784,4384, # 4566 +1952,2942,3080,3191,1728,4121,2043,3648,4385,2007,1701,3131,1551, 30,2263,4122, # 4582 +7511,2026,4386,3534,7512, 501,7513,4123, 594,3431,2165,1821,3535,3432,3536,3192, # 4598 + 829,2826,4124,7514,1680,3132,1225,4125,7515,3262,4387,4126,3133,2336,7516,4388, # 4614 +4127,7517,3912,3913,7518,1847,2383,2596,3330,7519,4389, 374,3914, 652,4128,4129, # 4630 + 375,1140, 798,7520,7521,7522,2361,4390,2264, 546,1659, 138,3031,2445,4391,7523, # 4646 +2250, 612,1848, 910, 796,3765,1740,1371, 825,3766,3767,7524,2906,2554,7525, 692, # 4662 + 444,3032,2624, 801,4392,4130,7526,1491, 244,1053,3033,4131,4132, 340,7527,3915, # 4678 +1041,2987, 293,1168, 87,1357,7528,1539, 959,7529,2236, 721, 694,4133,3768, 219, # 4694 +1478, 644,1417,3331,2656,1413,1401,1335,1389,3916,7530,7531,2988,2362,3134,1825, # 4710 + 730,1515, 184,2827, 66,4393,7532,1660,2943, 246,3332, 378,1457, 226,3433, 975, # 4726 +3917,2944,1264,3537, 674, 696,7533, 163,7534,1141,2417,2166, 713,3538,3333,4394, # 4742 +3918,7535,7536,1186, 15,7537,1079,1070,7538,1522,3193,3539, 276,1050,2716, 758, # 4758 +1126, 653,2945,3263,7539,2337, 889,3540,3919,3081,2989, 903,1250,4395,3920,3434, # 4774 +3541,1342,1681,1718, 766,3264, 286, 89,2946,3649,7540,1713,7541,2597,3334,2990, # 4790 +7542,2947,2215,3194,2866,7543,4396,2498,2526, 181, 387,1075,3921, 731,2187,3335, # 4806 +7544,3265, 310, 313,3435,2299, 770,4134, 54,3034, 189,4397,3082,3769,3922,7545, # 4822 +1230,1617,1849, 355,3542,4135,4398,3336, 111,4136,3650,1350,3135,3436,3035,4137, # 4838 +2149,3266,3543,7546,2784,3923,3924,2991, 722,2008,7547,1071, 247,1207,2338,2471, # 4854 +1378,4399,2009, 864,1437,1214,4400, 373,3770,1142,2216, 667,4401, 442,2753,2555, # 4870 +3771,3925,1968,4138,3267,1839, 837, 170,1107, 934,1336,1882,7548,7549,2118,4139, # 4886 +2828, 743,1569,7550,4402,4140, 582,2384,1418,3437,7551,1802,7552, 357,1395,1729, # 4902 +3651,3268,2418,1564,2237,7553,3083,3772,1633,4403,1114,2085,4141,1532,7554, 482, # 4918 +2446,4404,7555,7556,1492, 833,1466,7557,2717,3544,1641,2829,7558,1526,1272,3652, # 4934 +4142,1686,1794, 416,2556,1902,1953,1803,7559,3773,2785,3774,1159,2316,7560,2867, # 4950 +4405,1610,1584,3036,2419,2754, 443,3269,1163,3136,7561,7562,3926,7563,4143,2499, # 4966 +3037,4406,3927,3137,2103,1647,3545,2010,1872,4144,7564,4145, 431,3438,7565, 250, # 4982 + 97, 81,4146,7566,1648,1850,1558, 160, 848,7567, 866, 740,1694,7568,2201,2830, # 4998 +3195,4147,4407,3653,1687, 950,2472, 426, 469,3196,3654,3655,3928,7569,7570,1188, # 5014 + 424,1995, 861,3546,4148,3775,2202,2685, 168,1235,3547,4149,7571,2086,1674,4408, # 5030 +3337,3270, 220,2557,1009,7572,3776, 670,2992, 332,1208, 717,7573,7574,3548,2447, # 5046 +3929,3338,7575, 513,7576,1209,2868,3339,3138,4409,1080,7577,7578,7579,7580,2527, # 5062 +3656,3549, 815,1587,3930,3931,7581,3550,3439,3777,1254,4410,1328,3038,1390,3932, # 5078 +1741,3933,3778,3934,7582, 236,3779,2448,3271,7583,7584,3657,3780,1273,3781,4411, # 5094 +7585, 308,7586,4412, 245,4413,1851,2473,1307,2575, 430, 715,2136,2449,7587, 270, # 5110 + 199,2869,3935,7588,3551,2718,1753, 761,1754, 725,1661,1840,4414,3440,3658,7589, # 5126 +7590, 587, 14,3272, 227,2598, 326, 480,2265, 943,2755,3552, 291, 650,1883,7591, # 5142 +1702,1226, 102,1547, 62,3441, 904,4415,3442,1164,4150,7592,7593,1224,1548,2756, # 5158 + 391, 498,1493,7594,1386,1419,7595,2055,1177,4416, 813, 880,1081,2363, 566,1145, # 5174 +4417,2286,1001,1035,2558,2599,2238, 394,1286,7596,7597,2068,7598, 86,1494,1730, # 5190 +3936, 491,1588, 745, 897,2948, 843,3340,3937,2757,2870,3273,1768, 998,2217,2069, # 5206 + 397,1826,1195,1969,3659,2993,3341, 284,7599,3782,2500,2137,2119,1903,7600,3938, # 5222 +2150,3939,4151,1036,3443,1904, 114,2559,4152, 209,1527,7601,7602,2949,2831,2625, # 5238 +2385,2719,3139, 812,2560,7603,3274,7604,1559, 737,1884,3660,1210, 885, 28,2686, # 5254 +3553,3783,7605,4153,1004,1779,4418,7606, 346,1981,2218,2687,4419,3784,1742, 797, # 5270 +1642,3940,1933,1072,1384,2151, 896,3941,3275,3661,3197,2871,3554,7607,2561,1958, # 5286 +4420,2450,1785,7608,7609,7610,3942,4154,1005,1308,3662,4155,2720,4421,4422,1528, # 5302 +2600, 161,1178,4156,1982, 987,4423,1101,4157, 631,3943,1157,3198,2420,1343,1241, # 5318 +1016,2239,2562, 372, 877,2339,2501,1160, 555,1934, 911,3944,7611, 466,1170, 169, # 5334 +1051,2907,2688,3663,2474,2994,1182,2011,2563,1251,2626,7612, 992,2340,3444,1540, # 5350 +2721,1201,2070,2401,1996,2475,7613,4424, 528,1922,2188,1503,1873,1570,2364,3342, # 5366 +3276,7614, 557,1073,7615,1827,3445,2087,2266,3140,3039,3084, 767,3085,2786,4425, # 5382 +1006,4158,4426,2341,1267,2176,3664,3199, 778,3945,3200,2722,1597,2657,7616,4427, # 5398 +7617,3446,7618,7619,7620,3277,2689,1433,3278, 131, 95,1504,3946, 723,4159,3141, # 5414 +1841,3555,2758,2189,3947,2027,2104,3665,7621,2995,3948,1218,7622,3343,3201,3949, # 5430 +4160,2576, 248,1634,3785, 912,7623,2832,3666,3040,3786, 654, 53,7624,2996,7625, # 5446 +1688,4428, 777,3447,1032,3950,1425,7626, 191, 820,2120,2833, 971,4429, 931,3202, # 5462 + 135, 664, 783,3787,1997, 772,2908,1935,3951,3788,4430,2909,3203, 282,2723, 640, # 5478 +1372,3448,1127, 922, 325,3344,7627,7628, 711,2044,7629,7630,3952,2219,2787,1936, # 5494 +3953,3345,2220,2251,3789,2300,7631,4431,3790,1258,3279,3954,3204,2138,2950,3955, # 5510 +3956,7632,2221, 258,3205,4432, 101,1227,7633,3280,1755,7634,1391,3281,7635,2910, # 5526 +2056, 893,7636,7637,7638,1402,4161,2342,7639,7640,3206,3556,7641,7642, 878,1325, # 5542 +1780,2788,4433, 259,1385,2577, 744,1183,2267,4434,7643,3957,2502,7644, 684,1024, # 5558 +4162,7645, 472,3557,3449,1165,3282,3958,3959, 322,2152, 881, 455,1695,1152,1340, # 5574 + 660, 554,2153,4435,1058,4436,4163, 830,1065,3346,3960,4437,1923,7646,1703,1918, # 5590 +7647, 932,2268, 122,7648,4438, 947, 677,7649,3791,2627, 297,1905,1924,2269,4439, # 5606 +2317,3283,7650,7651,4164,7652,4165, 84,4166, 112, 989,7653, 547,1059,3961, 701, # 5622 +3558,1019,7654,4167,7655,3450, 942, 639, 457,2301,2451, 993,2951, 407, 851, 494, # 5638 +4440,3347, 927,7656,1237,7657,2421,3348, 573,4168, 680, 921,2911,1279,1874, 285, # 5654 + 790,1448,1983, 719,2167,7658,7659,4441,3962,3963,1649,7660,1541, 563,7661,1077, # 5670 +7662,3349,3041,3451, 511,2997,3964,3965,3667,3966,1268,2564,3350,3207,4442,4443, # 5686 +7663, 535,1048,1276,1189,2912,2028,3142,1438,1373,2834,2952,1134,2012,7664,4169, # 5702 +1238,2578,3086,1259,7665, 700,7666,2953,3143,3668,4170,7667,4171,1146,1875,1906, # 5718 +4444,2601,3967, 781,2422, 132,1589, 203, 147, 273,2789,2402, 898,1786,2154,3968, # 5734 +3969,7668,3792,2790,7669,7670,4445,4446,7671,3208,7672,1635,3793, 965,7673,1804, # 5750 +2690,1516,3559,1121,1082,1329,3284,3970,1449,3794, 65,1128,2835,2913,2759,1590, # 5766 +3795,7674,7675, 12,2658, 45, 976,2579,3144,4447, 517,2528,1013,1037,3209,7676, # 5782 +3796,2836,7677,3797,7678,3452,7679,2602, 614,1998,2318,3798,3087,2724,2628,7680, # 5798 +2580,4172, 599,1269,7681,1810,3669,7682,2691,3088, 759,1060, 489,1805,3351,3285, # 5814 +1358,7683,7684,2386,1387,1215,2629,2252, 490,7685,7686,4173,1759,2387,2343,7687, # 5830 +4448,3799,1907,3971,2630,1806,3210,4449,3453,3286,2760,2344, 874,7688,7689,3454, # 5846 +3670,1858, 91,2914,3671,3042,3800,4450,7690,3145,3972,2659,7691,3455,1202,1403, # 5862 +3801,2954,2529,1517,2503,4451,3456,2504,7692,4452,7693,2692,1885,1495,1731,3973, # 5878 +2365,4453,7694,2029,7695,7696,3974,2693,1216, 237,2581,4174,2319,3975,3802,4454, # 5894 +4455,2694,3560,3457, 445,4456,7697,7698,7699,7700,2761, 61,3976,3672,1822,3977, # 5910 +7701, 687,2045, 935, 925, 405,2660, 703,1096,1859,2725,4457,3978,1876,1367,2695, # 5926 +3352, 918,2105,1781,2476, 334,3287,1611,1093,4458, 564,3146,3458,3673,3353, 945, # 5942 +2631,2057,4459,7702,1925, 872,4175,7703,3459,2696,3089, 349,4176,3674,3979,4460, # 5958 +3803,4177,3675,2155,3980,4461,4462,4178,4463,2403,2046, 782,3981, 400, 251,4179, # 5974 +1624,7704,7705, 277,3676, 299,1265, 476,1191,3804,2121,4180,4181,1109, 205,7706, # 5990 +2582,1000,2156,3561,1860,7707,7708,7709,4464,7710,4465,2565, 107,2477,2157,3982, # 6006 +3460,3147,7711,1533, 541,1301, 158, 753,4182,2872,3562,7712,1696, 370,1088,4183, # 6022 +4466,3563, 579, 327, 440, 162,2240, 269,1937,1374,3461, 968,3043, 56,1396,3090, # 6038 +2106,3288,3354,7713,1926,2158,4467,2998,7714,3564,7715,7716,3677,4468,2478,7717, # 6054 +2791,7718,1650,4469,7719,2603,7720,7721,3983,2661,3355,1149,3356,3984,3805,3985, # 6070 +7722,1076, 49,7723, 951,3211,3289,3290, 450,2837, 920,7724,1811,2792,2366,4184, # 6086 +1908,1138,2367,3806,3462,7725,3212,4470,1909,1147,1518,2423,4471,3807,7726,4472, # 6102 +2388,2604, 260,1795,3213,7727,7728,3808,3291, 708,7729,3565,1704,7730,3566,1351, # 6118 +1618,3357,2999,1886, 944,4185,3358,4186,3044,3359,4187,7731,3678, 422, 413,1714, # 6134 +3292, 500,2058,2345,4188,2479,7732,1344,1910, 954,7733,1668,7734,7735,3986,2404, # 6150 +4189,3567,3809,4190,7736,2302,1318,2505,3091, 133,3092,2873,4473, 629, 31,2838, # 6166 +2697,3810,4474, 850, 949,4475,3987,2955,1732,2088,4191,1496,1852,7737,3988, 620, # 6182 +3214, 981,1242,3679,3360,1619,3680,1643,3293,2139,2452,1970,1719,3463,2168,7738, # 6198 +3215,7739,7740,3361,1828,7741,1277,4476,1565,2047,7742,1636,3568,3093,7743, 869, # 6214 +2839, 655,3811,3812,3094,3989,3000,3813,1310,3569,4477,7744,7745,7746,1733, 558, # 6230 +4478,3681, 335,1549,3045,1756,4192,3682,1945,3464,1829,1291,1192, 470,2726,2107, # 6246 +2793, 913,1054,3990,7747,1027,7748,3046,3991,4479, 982,2662,3362,3148,3465,3216, # 6262 +3217,1946,2794,7749, 571,4480,7750,1830,7751,3570,2583,1523,2424,7752,2089, 984, # 6278 +4481,3683,1959,7753,3684, 852, 923,2795,3466,3685, 969,1519, 999,2048,2320,1705, # 6294 +7754,3095, 615,1662, 151, 597,3992,2405,2321,1049, 275,4482,3686,4193, 568,3687, # 6310 +3571,2480,4194,3688,7755,2425,2270, 409,3218,7756,1566,2874,3467,1002, 769,2840, # 6326 + 194,2090,3149,3689,2222,3294,4195, 628,1505,7757,7758,1763,2177,3001,3993, 521, # 6342 +1161,2584,1787,2203,2406,4483,3994,1625,4196,4197, 412, 42,3096, 464,7759,2632, # 6358 +4484,3363,1760,1571,2875,3468,2530,1219,2204,3814,2633,2140,2368,4485,4486,3295, # 6374 +1651,3364,3572,7760,7761,3573,2481,3469,7762,3690,7763,7764,2271,2091, 460,7765, # 6390 +4487,7766,3002, 962, 588,3574, 289,3219,2634,1116, 52,7767,3047,1796,7768,7769, # 6406 +7770,1467,7771,1598,1143,3691,4198,1984,1734,1067,4488,1280,3365, 465,4489,1572, # 6422 + 510,7772,1927,2241,1812,1644,3575,7773,4490,3692,7774,7775,2663,1573,1534,7776, # 6438 +7777,4199, 536,1807,1761,3470,3815,3150,2635,7778,7779,7780,4491,3471,2915,1911, # 6454 +2796,7781,3296,1122, 377,3220,7782, 360,7783,7784,4200,1529, 551,7785,2059,3693, # 6470 +1769,2426,7786,2916,4201,3297,3097,2322,2108,2030,4492,1404, 136,1468,1479, 672, # 6486 +1171,3221,2303, 271,3151,7787,2762,7788,2049, 678,2727, 865,1947,4493,7789,2013, # 6502 +3995,2956,7790,2728,2223,1397,3048,3694,4494,4495,1735,2917,3366,3576,7791,3816, # 6518 + 509,2841,2453,2876,3817,7792,7793,3152,3153,4496,4202,2531,4497,2304,1166,1010, # 6534 + 552, 681,1887,7794,7795,2957,2958,3996,1287,1596,1861,3154, 358, 453, 736, 175, # 6550 + 478,1117, 905,1167,1097,7796,1853,1530,7797,1706,7798,2178,3472,2287,3695,3473, # 6566 +3577,4203,2092,4204,7799,3367,1193,2482,4205,1458,2190,2205,1862,1888,1421,3298, # 6582 +2918,3049,2179,3474, 595,2122,7800,3997,7801,7802,4206,1707,2636, 223,3696,1359, # 6598 + 751,3098, 183,3475,7803,2797,3003, 419,2369, 633, 704,3818,2389, 241,7804,7805, # 6614 +7806, 838,3004,3697,2272,2763,2454,3819,1938,2050,3998,1309,3099,2242,1181,7807, # 6630 +1136,2206,3820,2370,1446,4207,2305,4498,7808,7809,4208,1055,2605, 484,3698,7810, # 6646 +3999, 625,4209,2273,3368,1499,4210,4000,7811,4001,4211,3222,2274,2275,3476,7812, # 6662 +7813,2764, 808,2606,3699,3369,4002,4212,3100,2532, 526,3370,3821,4213, 955,7814, # 6678 +1620,4214,2637,2427,7815,1429,3700,1669,1831, 994, 928,7816,3578,1260,7817,7818, # 6694 +7819,1948,2288, 741,2919,1626,4215,2729,2455, 867,1184, 362,3371,1392,7820,7821, # 6710 +4003,4216,1770,1736,3223,2920,4499,4500,1928,2698,1459,1158,7822,3050,3372,2877, # 6726 +1292,1929,2506,2842,3701,1985,1187,2071,2014,2607,4217,7823,2566,2507,2169,3702, # 6742 +2483,3299,7824,3703,4501,7825,7826, 666,1003,3005,1022,3579,4218,7827,4502,1813, # 6758 +2253, 574,3822,1603, 295,1535, 705,3823,4219, 283, 858, 417,7828,7829,3224,4503, # 6774 +4504,3051,1220,1889,1046,2276,2456,4004,1393,1599, 689,2567, 388,4220,7830,2484, # 6790 + 802,7831,2798,3824,2060,1405,2254,7832,4505,3825,2109,1052,1345,3225,1585,7833, # 6806 + 809,7834,7835,7836, 575,2730,3477, 956,1552,1469,1144,2323,7837,2324,1560,2457, # 6822 +3580,3226,4005, 616,2207,3155,2180,2289,7838,1832,7839,3478,4506,7840,1319,3704, # 6838 +3705,1211,3581,1023,3227,1293,2799,7841,7842,7843,3826, 607,2306,3827, 762,2878, # 6854 +1439,4221,1360,7844,1485,3052,7845,4507,1038,4222,1450,2061,2638,4223,1379,4508, # 6870 +2585,7846,7847,4224,1352,1414,2325,2921,1172,7848,7849,3828,3829,7850,1797,1451, # 6886 +7851,7852,7853,7854,2922,4006,4007,2485,2346, 411,4008,4009,3582,3300,3101,4509, # 6902 +1561,2664,1452,4010,1375,7855,7856, 47,2959, 316,7857,1406,1591,2923,3156,7858, # 6918 +1025,2141,3102,3157, 354,2731, 884,2224,4225,2407, 508,3706, 726,3583, 996,2428, # 6934 +3584, 729,7859, 392,2191,1453,4011,4510,3707,7860,7861,2458,3585,2608,1675,2800, # 6950 + 919,2347,2960,2348,1270,4511,4012, 73,7862,7863, 647,7864,3228,2843,2255,1550, # 6966 +1346,3006,7865,1332, 883,3479,7866,7867,7868,7869,3301,2765,7870,1212, 831,1347, # 6982 +4226,4512,2326,3830,1863,3053, 720,3831,4513,4514,3832,7871,4227,7872,7873,4515, # 6998 +7874,7875,1798,4516,3708,2609,4517,3586,1645,2371,7876,7877,2924, 669,2208,2665, # 7014 +2429,7878,2879,7879,7880,1028,3229,7881,4228,2408,7882,2256,1353,7883,7884,4518, # 7030 +3158, 518,7885,4013,7886,4229,1960,7887,2142,4230,7888,7889,3007,2349,2350,3833, # 7046 + 516,1833,1454,4014,2699,4231,4519,2225,2610,1971,1129,3587,7890,2766,7891,2961, # 7062 +1422, 577,1470,3008,1524,3373,7892,7893, 432,4232,3054,3480,7894,2586,1455,2508, # 7078 +2226,1972,1175,7895,1020,2732,4015,3481,4520,7896,2733,7897,1743,1361,3055,3482, # 7094 +2639,4016,4233,4521,2290, 895, 924,4234,2170, 331,2243,3056, 166,1627,3057,1098, # 7110 +7898,1232,2880,2227,3374,4522, 657, 403,1196,2372, 542,3709,3375,1600,4235,3483, # 7126 +7899,4523,2767,3230, 576, 530,1362,7900,4524,2533,2666,3710,4017,7901, 842,3834, # 7142 +7902,2801,2031,1014,4018, 213,2700,3376, 665, 621,4236,7903,3711,2925,2430,7904, # 7158 +2431,3302,3588,3377,7905,4237,2534,4238,4525,3589,1682,4239,3484,1380,7906, 724, # 7174 +2277, 600,1670,7907,1337,1233,4526,3103,2244,7908,1621,4527,7909, 651,4240,7910, # 7190 +1612,4241,2611,7911,2844,7912,2734,2307,3058,7913, 716,2459,3059, 174,1255,2701, # 7206 +4019,3590, 548,1320,1398, 728,4020,1574,7914,1890,1197,3060,4021,7915,3061,3062, # 7222 +3712,3591,3713, 747,7916, 635,4242,4528,7917,7918,7919,4243,7920,7921,4529,7922, # 7238 +3378,4530,2432, 451,7923,3714,2535,2072,4244,2735,4245,4022,7924,1764,4531,7925, # 7254 +4246, 350,7926,2278,2390,2486,7927,4247,4023,2245,1434,4024, 488,4532, 458,4248, # 7270 +4025,3715, 771,1330,2391,3835,2568,3159,2159,2409,1553,2667,3160,4249,7928,2487, # 7286 +2881,2612,1720,2702,4250,3379,4533,7929,2536,4251,7930,3231,4252,2768,7931,2015, # 7302 +2736,7932,1155,1017,3716,3836,7933,3303,2308, 201,1864,4253,1430,7934,4026,7935, # 7318 +7936,7937,7938,7939,4254,1604,7940, 414,1865, 371,2587,4534,4535,3485,2016,3104, # 7334 +4536,1708, 960,4255, 887, 389,2171,1536,1663,1721,7941,2228,4027,2351,2926,1580, # 7350 +7942,7943,7944,1744,7945,2537,4537,4538,7946,4539,7947,2073,7948,7949,3592,3380, # 7366 +2882,4256,7950,4257,2640,3381,2802, 673,2703,2460, 709,3486,4028,3593,4258,7951, # 7382 +1148, 502, 634,7952,7953,1204,4540,3594,1575,4541,2613,3717,7954,3718,3105, 948, # 7398 +3232, 121,1745,3837,1110,7955,4259,3063,2509,3009,4029,3719,1151,1771,3838,1488, # 7414 +4030,1986,7956,2433,3487,7957,7958,2093,7959,4260,3839,1213,1407,2803, 531,2737, # 7430 +2538,3233,1011,1537,7960,2769,4261,3106,1061,7961,3720,3721,1866,2883,7962,2017, # 7446 + 120,4262,4263,2062,3595,3234,2309,3840,2668,3382,1954,4542,7963,7964,3488,1047, # 7462 +2704,1266,7965,1368,4543,2845, 649,3383,3841,2539,2738,1102,2846,2669,7966,7967, # 7478 +1999,7968,1111,3596,2962,7969,2488,3842,3597,2804,1854,3384,3722,7970,7971,3385, # 7494 +2410,2884,3304,3235,3598,7972,2569,7973,3599,2805,4031,1460, 856,7974,3600,7975, # 7510 +2885,2963,7976,2886,3843,7977,4264, 632,2510, 875,3844,1697,3845,2291,7978,7979, # 7526 +4544,3010,1239, 580,4545,4265,7980, 914, 936,2074,1190,4032,1039,2123,7981,7982, # 7542 +7983,3386,1473,7984,1354,4266,3846,7985,2172,3064,4033, 915,3305,4267,4268,3306, # 7558 +1605,1834,7986,2739, 398,3601,4269,3847,4034, 328,1912,2847,4035,3848,1331,4270, # 7574 +3011, 937,4271,7987,3602,4036,4037,3387,2160,4546,3388, 524, 742, 538,3065,1012, # 7590 +7988,7989,3849,2461,7990, 658,1103, 225,3850,7991,7992,4547,7993,4548,7994,3236, # 7606 +1243,7995,4038, 963,2246,4549,7996,2705,3603,3161,7997,7998,2588,2327,7999,4550, # 7622 +8000,8001,8002,3489,3307, 957,3389,2540,2032,1930,2927,2462, 870,2018,3604,1746, # 7638 +2770,2771,2434,2463,8003,3851,8004,3723,3107,3724,3490,3390,3725,8005,1179,3066, # 7654 +8006,3162,2373,4272,3726,2541,3163,3108,2740,4039,8007,3391,1556,2542,2292, 977, # 7670 +2887,2033,4040,1205,3392,8008,1765,3393,3164,2124,1271,1689, 714,4551,3491,8009, # 7686 +2328,3852, 533,4273,3605,2181, 617,8010,2464,3308,3492,2310,8011,8012,3165,8013, # 7702 +8014,3853,1987, 618, 427,2641,3493,3394,8015,8016,1244,1690,8017,2806,4274,4552, # 7718 +8018,3494,8019,8020,2279,1576, 473,3606,4275,3395, 972,8021,3607,8022,3067,8023, # 7734 +8024,4553,4554,8025,3727,4041,4042,8026, 153,4555, 356,8027,1891,2888,4276,2143, # 7750 + 408, 803,2352,8028,3854,8029,4277,1646,2570,2511,4556,4557,3855,8030,3856,4278, # 7766 +8031,2411,3396, 752,8032,8033,1961,2964,8034, 746,3012,2465,8035,4279,3728, 698, # 7782 +4558,1892,4280,3608,2543,4559,3609,3857,8036,3166,3397,8037,1823,1302,4043,2706, # 7798 +3858,1973,4281,8038,4282,3167, 823,1303,1288,1236,2848,3495,4044,3398, 774,3859, # 7814 +8039,1581,4560,1304,2849,3860,4561,8040,2435,2161,1083,3237,4283,4045,4284, 344, # 7830 +1173, 288,2311, 454,1683,8041,8042,1461,4562,4046,2589,8043,8044,4563, 985, 894, # 7846 +8045,3399,3168,8046,1913,2928,3729,1988,8047,2110,1974,8048,4047,8049,2571,1194, # 7862 + 425,8050,4564,3169,1245,3730,4285,8051,8052,2850,8053, 636,4565,1855,3861, 760, # 7878 +1799,8054,4286,2209,1508,4566,4048,1893,1684,2293,8055,8056,8057,4287,4288,2210, # 7894 + 479,8058,8059, 832,8060,4049,2489,8061,2965,2490,3731, 990,3109, 627,1814,2642, # 7910 +4289,1582,4290,2125,2111,3496,4567,8062, 799,4291,3170,8063,4568,2112,1737,3013, # 7926 +1018, 543, 754,4292,3309,1676,4569,4570,4050,8064,1489,8065,3497,8066,2614,2889, # 7942 +4051,8067,8068,2966,8069,8070,8071,8072,3171,4571,4572,2182,1722,8073,3238,3239, # 7958 +1842,3610,1715, 481, 365,1975,1856,8074,8075,1962,2491,4573,8076,2126,3611,3240, # 7974 + 433,1894,2063,2075,8077, 602,2741,8078,8079,8080,8081,8082,3014,1628,3400,8083, # 7990 +3172,4574,4052,2890,4575,2512,8084,2544,2772,8085,8086,8087,3310,4576,2891,8088, # 8006 +4577,8089,2851,4578,4579,1221,2967,4053,2513,8090,8091,8092,1867,1989,8093,8094, # 8022 +8095,1895,8096,8097,4580,1896,4054, 318,8098,2094,4055,4293,8099,8100, 485,8101, # 8038 + 938,3862, 553,2670, 116,8102,3863,3612,8103,3498,2671,2773,3401,3311,2807,8104, # 8054 +3613,2929,4056,1747,2930,2968,8105,8106, 207,8107,8108,2672,4581,2514,8109,3015, # 8070 + 890,3614,3864,8110,1877,3732,3402,8111,2183,2353,3403,1652,8112,8113,8114, 941, # 8086 +2294, 208,3499,4057,2019, 330,4294,3865,2892,2492,3733,4295,8115,8116,8117,8118, # 8102 +) + diff --git a/venv/Lib/site-packages/pip/_vendor/chardet/euctwprober.py b/venv/Lib/site-packages/pip/_vendor/chardet/euctwprober.py new file mode 100644 index 0000000..35669cc --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/chardet/euctwprober.py @@ -0,0 +1,46 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .mbcharsetprober import MultiByteCharSetProber +from .codingstatemachine import CodingStateMachine +from .chardistribution import EUCTWDistributionAnalysis +from .mbcssm import EUCTW_SM_MODEL + +class EUCTWProber(MultiByteCharSetProber): + def __init__(self): + super(EUCTWProber, self).__init__() + self.coding_sm = CodingStateMachine(EUCTW_SM_MODEL) + self.distribution_analyzer = EUCTWDistributionAnalysis() + self.reset() + + @property + def charset_name(self): + return "EUC-TW" + + @property + def language(self): + return "Taiwan" diff --git a/venv/Lib/site-packages/pip/_vendor/chardet/gb2312freq.py b/venv/Lib/site-packages/pip/_vendor/chardet/gb2312freq.py new file mode 100644 index 0000000..697837b --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/chardet/gb2312freq.py @@ -0,0 +1,283 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +# GB2312 most frequently used character table +# +# Char to FreqOrder table , from hz6763 + +# 512 --> 0.79 -- 0.79 +# 1024 --> 0.92 -- 0.13 +# 2048 --> 0.98 -- 0.06 +# 6768 --> 1.00 -- 0.02 +# +# Ideal Distribution Ratio = 0.79135/(1-0.79135) = 3.79 +# Random Distribution Ration = 512 / (3755 - 512) = 0.157 +# +# Typical Distribution Ratio about 25% of Ideal one, still much higher that RDR + +GB2312_TYPICAL_DISTRIBUTION_RATIO = 0.9 + +GB2312_TABLE_SIZE = 3760 + +GB2312_CHAR_TO_FREQ_ORDER = ( +1671, 749,1443,2364,3924,3807,2330,3921,1704,3463,2691,1511,1515, 572,3191,2205, +2361, 224,2558, 479,1711, 963,3162, 440,4060,1905,2966,2947,3580,2647,3961,3842, +2204, 869,4207, 970,2678,5626,2944,2956,1479,4048, 514,3595, 588,1346,2820,3409, + 249,4088,1746,1873,2047,1774, 581,1813, 358,1174,3590,1014,1561,4844,2245, 670, +1636,3112, 889,1286, 953, 556,2327,3060,1290,3141, 613, 185,3477,1367, 850,3820, +1715,2428,2642,2303,2732,3041,2562,2648,3566,3946,1349, 388,3098,2091,1360,3585, + 152,1687,1539, 738,1559, 59,1232,2925,2267,1388,1249,1741,1679,2960, 151,1566, +1125,1352,4271, 924,4296, 385,3166,4459, 310,1245,2850, 70,3285,2729,3534,3575, +2398,3298,3466,1960,2265, 217,3647, 864,1909,2084,4401,2773,1010,3269,5152, 853, +3051,3121,1244,4251,1895, 364,1499,1540,2313,1180,3655,2268, 562, 715,2417,3061, + 544, 336,3768,2380,1752,4075, 950, 280,2425,4382, 183,2759,3272, 333,4297,2155, +1688,2356,1444,1039,4540, 736,1177,3349,2443,2368,2144,2225, 565, 196,1482,3406, + 927,1335,4147, 692, 878,1311,1653,3911,3622,1378,4200,1840,2969,3149,2126,1816, +2534,1546,2393,2760, 737,2494, 13, 447, 245,2747, 38,2765,2129,2589,1079, 606, + 360, 471,3755,2890, 404, 848, 699,1785,1236, 370,2221,1023,3746,2074,2026,2023, +2388,1581,2119, 812,1141,3091,2536,1519, 804,2053, 406,1596,1090, 784, 548,4414, +1806,2264,2936,1100, 343,4114,5096, 622,3358, 743,3668,1510,1626,5020,3567,2513, +3195,4115,5627,2489,2991, 24,2065,2697,1087,2719, 48,1634, 315, 68, 985,2052, + 198,2239,1347,1107,1439, 597,2366,2172, 871,3307, 919,2487,2790,1867, 236,2570, +1413,3794, 906,3365,3381,1701,1982,1818,1524,2924,1205, 616,2586,2072,2004, 575, + 253,3099, 32,1365,1182, 197,1714,2454,1201, 554,3388,3224,2748, 756,2587, 250, +2567,1507,1517,3529,1922,2761,2337,3416,1961,1677,2452,2238,3153, 615, 911,1506, +1474,2495,1265,1906,2749,3756,3280,2161, 898,2714,1759,3450,2243,2444, 563, 26, +3286,2266,3769,3344,2707,3677, 611,1402, 531,1028,2871,4548,1375, 261,2948, 835, +1190,4134, 353, 840,2684,1900,3082,1435,2109,1207,1674, 329,1872,2781,4055,2686, +2104, 608,3318,2423,2957,2768,1108,3739,3512,3271,3985,2203,1771,3520,1418,2054, +1681,1153, 225,1627,2929, 162,2050,2511,3687,1954, 124,1859,2431,1684,3032,2894, + 585,4805,3969,2869,2704,2088,2032,2095,3656,2635,4362,2209, 256, 518,2042,2105, +3777,3657, 643,2298,1148,1779, 190, 989,3544, 414, 11,2135,2063,2979,1471, 403, +3678, 126, 770,1563, 671,2499,3216,2877, 600,1179, 307,2805,4937,1268,1297,2694, + 252,4032,1448,1494,1331,1394, 127,2256, 222,1647,1035,1481,3056,1915,1048, 873, +3651, 210, 33,1608,2516, 200,1520, 415, 102, 0,3389,1287, 817, 91,3299,2940, + 836,1814, 549,2197,1396,1669,2987,3582,2297,2848,4528,1070, 687, 20,1819, 121, +1552,1364,1461,1968,2617,3540,2824,2083, 177, 948,4938,2291, 110,4549,2066, 648, +3359,1755,2110,2114,4642,4845,1693,3937,3308,1257,1869,2123, 208,1804,3159,2992, +2531,2549,3361,2418,1350,2347,2800,2568,1291,2036,2680, 72, 842,1990, 212,1233, +1154,1586, 75,2027,3410,4900,1823,1337,2710,2676, 728,2810,1522,3026,4995, 157, + 755,1050,4022, 710, 785,1936,2194,2085,1406,2777,2400, 150,1250,4049,1206, 807, +1910, 534, 529,3309,1721,1660, 274, 39,2827, 661,2670,1578, 925,3248,3815,1094, +4278,4901,4252, 41,1150,3747,2572,2227,4501,3658,4902,3813,3357,3617,2884,2258, + 887, 538,4187,3199,1294,2439,3042,2329,2343,2497,1255, 107, 543,1527, 521,3478, +3568, 194,5062, 15, 961,3870,1241,1192,2664, 66,5215,3260,2111,1295,1127,2152, +3805,4135, 901,1164,1976, 398,1278, 530,1460, 748, 904,1054,1966,1426, 53,2909, + 509, 523,2279,1534, 536,1019, 239,1685, 460,2353, 673,1065,2401,3600,4298,2272, +1272,2363, 284,1753,3679,4064,1695, 81, 815,2677,2757,2731,1386, 859, 500,4221, +2190,2566, 757,1006,2519,2068,1166,1455, 337,2654,3203,1863,1682,1914,3025,1252, +1409,1366, 847, 714,2834,2038,3209, 964,2970,1901, 885,2553,1078,1756,3049, 301, +1572,3326, 688,2130,1996,2429,1805,1648,2930,3421,2750,3652,3088, 262,1158,1254, + 389,1641,1812, 526,1719, 923,2073,1073,1902, 468, 489,4625,1140, 857,2375,3070, +3319,2863, 380, 116,1328,2693,1161,2244, 273,1212,1884,2769,3011,1775,1142, 461, +3066,1200,2147,2212, 790, 702,2695,4222,1601,1058, 434,2338,5153,3640, 67,2360, +4099,2502, 618,3472,1329, 416,1132, 830,2782,1807,2653,3211,3510,1662, 192,2124, + 296,3979,1739,1611,3684, 23, 118, 324, 446,1239,1225, 293,2520,3814,3795,2535, +3116, 17,1074, 467,2692,2201, 387,2922, 45,1326,3055,1645,3659,2817, 958, 243, +1903,2320,1339,2825,1784,3289, 356, 576, 865,2315,2381,3377,3916,1088,3122,1713, +1655, 935, 628,4689,1034,1327, 441, 800, 720, 894,1979,2183,1528,5289,2702,1071, +4046,3572,2399,1571,3281, 79, 761,1103, 327, 134, 758,1899,1371,1615, 879, 442, + 215,2605,2579, 173,2048,2485,1057,2975,3317,1097,2253,3801,4263,1403,1650,2946, + 814,4968,3487,1548,2644,1567,1285, 2, 295,2636, 97, 946,3576, 832, 141,4257, +3273, 760,3821,3521,3156,2607, 949,1024,1733,1516,1803,1920,2125,2283,2665,3180, +1501,2064,3560,2171,1592, 803,3518,1416, 732,3897,4258,1363,1362,2458, 119,1427, + 602,1525,2608,1605,1639,3175, 694,3064, 10, 465, 76,2000,4846,4208, 444,3781, +1619,3353,2206,1273,3796, 740,2483, 320,1723,2377,3660,2619,1359,1137,1762,1724, +2345,2842,1850,1862, 912, 821,1866, 612,2625,1735,2573,3369,1093, 844, 89, 937, + 930,1424,3564,2413,2972,1004,3046,3019,2011, 711,3171,1452,4178, 428, 801,1943, + 432, 445,2811, 206,4136,1472, 730, 349, 73, 397,2802,2547, 998,1637,1167, 789, + 396,3217, 154,1218, 716,1120,1780,2819,4826,1931,3334,3762,2139,1215,2627, 552, +3664,3628,3232,1405,2383,3111,1356,2652,3577,3320,3101,1703, 640,1045,1370,1246, +4996, 371,1575,2436,1621,2210, 984,4033,1734,2638, 16,4529, 663,2755,3255,1451, +3917,2257,1253,1955,2234,1263,2951, 214,1229, 617, 485, 359,1831,1969, 473,2310, + 750,2058, 165, 80,2864,2419, 361,4344,2416,2479,1134, 796,3726,1266,2943, 860, +2715, 938, 390,2734,1313,1384, 248, 202, 877,1064,2854, 522,3907, 279,1602, 297, +2357, 395,3740, 137,2075, 944,4089,2584,1267,3802, 62,1533,2285, 178, 176, 780, +2440, 201,3707, 590, 478,1560,4354,2117,1075, 30, 74,4643,4004,1635,1441,2745, + 776,2596, 238,1077,1692,1912,2844, 605, 499,1742,3947, 241,3053, 980,1749, 936, +2640,4511,2582, 515,1543,2162,5322,2892,2993, 890,2148,1924, 665,1827,3581,1032, + 968,3163, 339,1044,1896, 270, 583,1791,1720,4367,1194,3488,3669, 43,2523,1657, + 163,2167, 290,1209,1622,3378, 550, 634,2508,2510, 695,2634,2384,2512,1476,1414, + 220,1469,2341,2138,2852,3183,2900,4939,2865,3502,1211,3680, 854,3227,1299,2976, +3172, 186,2998,1459, 443,1067,3251,1495, 321,1932,3054, 909, 753,1410,1828, 436, +2441,1119,1587,3164,2186,1258, 227, 231,1425,1890,3200,3942, 247, 959, 725,5254, +2741, 577,2158,2079, 929, 120, 174, 838,2813, 591,1115, 417,2024, 40,3240,1536, +1037, 291,4151,2354, 632,1298,2406,2500,3535,1825,1846,3451, 205,1171, 345,4238, + 18,1163, 811, 685,2208,1217, 425,1312,1508,1175,4308,2552,1033, 587,1381,3059, +2984,3482, 340,1316,4023,3972, 792,3176, 519, 777,4690, 918, 933,4130,2981,3741, + 90,3360,2911,2200,5184,4550, 609,3079,2030, 272,3379,2736, 363,3881,1130,1447, + 286, 779, 357,1169,3350,3137,1630,1220,2687,2391, 747,1277,3688,2618,2682,2601, +1156,3196,5290,4034,3102,1689,3596,3128, 874, 219,2783, 798, 508,1843,2461, 269, +1658,1776,1392,1913,2983,3287,2866,2159,2372, 829,4076, 46,4253,2873,1889,1894, + 915,1834,1631,2181,2318, 298, 664,2818,3555,2735, 954,3228,3117, 527,3511,2173, + 681,2712,3033,2247,2346,3467,1652, 155,2164,3382, 113,1994, 450, 899, 494, 994, +1237,2958,1875,2336,1926,3727, 545,1577,1550, 633,3473, 204,1305,3072,2410,1956, +2471, 707,2134, 841,2195,2196,2663,3843,1026,4940, 990,3252,4997, 368,1092, 437, +3212,3258,1933,1829, 675,2977,2893, 412, 943,3723,4644,3294,3283,2230,2373,5154, +2389,2241,2661,2323,1404,2524, 593, 787, 677,3008,1275,2059, 438,2709,2609,2240, +2269,2246,1446, 36,1568,1373,3892,1574,2301,1456,3962, 693,2276,5216,2035,1143, +2720,1919,1797,1811,2763,4137,2597,1830,1699,1488,1198,2090, 424,1694, 312,3634, +3390,4179,3335,2252,1214, 561,1059,3243,2295,2561, 975,5155,2321,2751,3772, 472, +1537,3282,3398,1047,2077,2348,2878,1323,3340,3076, 690,2906, 51, 369, 170,3541, +1060,2187,2688,3670,2541,1083,1683, 928,3918, 459, 109,4427, 599,3744,4286, 143, +2101,2730,2490, 82,1588,3036,2121, 281,1860, 477,4035,1238,2812,3020,2716,3312, +1530,2188,2055,1317, 843, 636,1808,1173,3495, 649, 181,1002, 147,3641,1159,2414, +3750,2289,2795, 813,3123,2610,1136,4368, 5,3391,4541,2174, 420, 429,1728, 754, +1228,2115,2219, 347,2223,2733, 735,1518,3003,2355,3134,1764,3948,3329,1888,2424, +1001,1234,1972,3321,3363,1672,1021,1450,1584, 226, 765, 655,2526,3404,3244,2302, +3665, 731, 594,2184, 319,1576, 621, 658,2656,4299,2099,3864,1279,2071,2598,2739, + 795,3086,3699,3908,1707,2352,2402,1382,3136,2475,1465,4847,3496,3865,1085,3004, +2591,1084, 213,2287,1963,3565,2250, 822, 793,4574,3187,1772,1789,3050, 595,1484, +1959,2770,1080,2650, 456, 422,2996, 940,3322,4328,4345,3092,2742, 965,2784, 739, +4124, 952,1358,2498,2949,2565, 332,2698,2378, 660,2260,2473,4194,3856,2919, 535, +1260,2651,1208,1428,1300,1949,1303,2942, 433,2455,2450,1251,1946, 614,1269, 641, +1306,1810,2737,3078,2912, 564,2365,1419,1415,1497,4460,2367,2185,1379,3005,1307, +3218,2175,1897,3063, 682,1157,4040,4005,1712,1160,1941,1399, 394, 402,2952,1573, +1151,2986,2404, 862, 299,2033,1489,3006, 346, 171,2886,3401,1726,2932, 168,2533, + 47,2507,1030,3735,1145,3370,1395,1318,1579,3609,4560,2857,4116,1457,2529,1965, + 504,1036,2690,2988,2405, 745,5871, 849,2397,2056,3081, 863,2359,3857,2096, 99, +1397,1769,2300,4428,1643,3455,1978,1757,3718,1440, 35,4879,3742,1296,4228,2280, + 160,5063,1599,2013, 166, 520,3479,1646,3345,3012, 490,1937,1545,1264,2182,2505, +1096,1188,1369,1436,2421,1667,2792,2460,1270,2122, 727,3167,2143, 806,1706,1012, +1800,3037, 960,2218,1882, 805, 139,2456,1139,1521, 851,1052,3093,3089, 342,2039, + 744,5097,1468,1502,1585,2087, 223, 939, 326,2140,2577, 892,2481,1623,4077, 982, +3708, 135,2131, 87,2503,3114,2326,1106, 876,1616, 547,2997,2831,2093,3441,4530, +4314, 9,3256,4229,4148, 659,1462,1986,1710,2046,2913,2231,4090,4880,5255,3392, +3274,1368,3689,4645,1477, 705,3384,3635,1068,1529,2941,1458,3782,1509, 100,1656, +2548, 718,2339, 408,1590,2780,3548,1838,4117,3719,1345,3530, 717,3442,2778,3220, +2898,1892,4590,3614,3371,2043,1998,1224,3483, 891, 635, 584,2559,3355, 733,1766, +1729,1172,3789,1891,2307, 781,2982,2271,1957,1580,5773,2633,2005,4195,3097,1535, +3213,1189,1934,5693,3262, 586,3118,1324,1598, 517,1564,2217,1868,1893,4445,3728, +2703,3139,1526,1787,1992,3882,2875,1549,1199,1056,2224,1904,2711,5098,4287, 338, +1993,3129,3489,2689,1809,2815,1997, 957,1855,3898,2550,3275,3057,1105,1319, 627, +1505,1911,1883,3526, 698,3629,3456,1833,1431, 746, 77,1261,2017,2296,1977,1885, + 125,1334,1600, 525,1798,1109,2222,1470,1945, 559,2236,1186,3443,2476,1929,1411, +2411,3135,1777,3372,2621,1841,1613,3229, 668,1430,1839,2643,2916, 195,1989,2671, +2358,1387, 629,3205,2293,5256,4439, 123,1310, 888,1879,4300,3021,3605,1003,1162, +3192,2910,2010, 140,2395,2859, 55,1082,2012,2901, 662, 419,2081,1438, 680,2774, +4654,3912,1620,1731,1625,5035,4065,2328, 512,1344, 802,5443,2163,2311,2537, 524, +3399, 98,1155,2103,1918,2606,3925,2816,1393,2465,1504,3773,2177,3963,1478,4346, + 180,1113,4655,3461,2028,1698, 833,2696,1235,1322,1594,4408,3623,3013,3225,2040, +3022, 541,2881, 607,3632,2029,1665,1219, 639,1385,1686,1099,2803,3231,1938,3188, +2858, 427, 676,2772,1168,2025, 454,3253,2486,3556, 230,1950, 580, 791,1991,1280, +1086,1974,2034, 630, 257,3338,2788,4903,1017, 86,4790, 966,2789,1995,1696,1131, + 259,3095,4188,1308, 179,1463,5257, 289,4107,1248, 42,3413,1725,2288, 896,1947, + 774,4474,4254, 604,3430,4264, 392,2514,2588, 452, 237,1408,3018, 988,4531,1970, +3034,3310, 540,2370,1562,1288,2990, 502,4765,1147, 4,1853,2708, 207, 294,2814, +4078,2902,2509, 684, 34,3105,3532,2551, 644, 709,2801,2344, 573,1727,3573,3557, +2021,1081,3100,4315,2100,3681, 199,2263,1837,2385, 146,3484,1195,2776,3949, 997, +1939,3973,1008,1091,1202,1962,1847,1149,4209,5444,1076, 493, 117,5400,2521, 972, +1490,2934,1796,4542,2374,1512,2933,2657, 413,2888,1135,2762,2314,2156,1355,2369, + 766,2007,2527,2170,3124,2491,2593,2632,4757,2437, 234,3125,3591,1898,1750,1376, +1942,3468,3138, 570,2127,2145,3276,4131, 962, 132,1445,4196, 19, 941,3624,3480, +3366,1973,1374,4461,3431,2629, 283,2415,2275, 808,2887,3620,2112,2563,1353,3610, + 955,1089,3103,1053, 96, 88,4097, 823,3808,1583, 399, 292,4091,3313, 421,1128, + 642,4006, 903,2539,1877,2082, 596, 29,4066,1790, 722,2157, 130, 995,1569, 769, +1485, 464, 513,2213, 288,1923,1101,2453,4316, 133, 486,2445, 50, 625, 487,2207, + 57, 423, 481,2962, 159,3729,1558, 491, 303, 482, 501, 240,2837, 112,3648,2392, +1783, 362, 8,3433,3422, 610,2793,3277,1390,1284,1654, 21,3823, 734, 367, 623, + 193, 287, 374,1009,1483, 816, 476, 313,2255,2340,1262,2150,2899,1146,2581, 782, +2116,1659,2018,1880, 255,3586,3314,1110,2867,2137,2564, 986,2767,5185,2006, 650, + 158, 926, 762, 881,3157,2717,2362,3587, 306,3690,3245,1542,3077,2427,1691,2478, +2118,2985,3490,2438, 539,2305, 983, 129,1754, 355,4201,2386, 827,2923, 104,1773, +2838,2771, 411,2905,3919, 376, 767, 122,1114, 828,2422,1817,3506, 266,3460,1007, +1609,4998, 945,2612,4429,2274, 726,1247,1964,2914,2199,2070,4002,4108, 657,3323, +1422, 579, 455,2764,4737,1222,2895,1670, 824,1223,1487,2525, 558, 861,3080, 598, +2659,2515,1967, 752,2583,2376,2214,4180, 977, 704,2464,4999,2622,4109,1210,2961, + 819,1541, 142,2284, 44, 418, 457,1126,3730,4347,4626,1644,1876,3671,1864, 302, +1063,5694, 624, 723,1984,3745,1314,1676,2488,1610,1449,3558,3569,2166,2098, 409, +1011,2325,3704,2306, 818,1732,1383,1824,1844,3757, 999,2705,3497,1216,1423,2683, +2426,2954,2501,2726,2229,1475,2554,5064,1971,1794,1666,2014,1343, 783, 724, 191, +2434,1354,2220,5065,1763,2752,2472,4152, 131, 175,2885,3434, 92,1466,4920,2616, +3871,3872,3866, 128,1551,1632, 669,1854,3682,4691,4125,1230, 188,2973,3290,1302, +1213, 560,3266, 917, 763,3909,3249,1760, 868,1958, 764,1782,2097, 145,2277,3774, +4462, 64,1491,3062, 971,2132,3606,2442, 221,1226,1617, 218, 323,1185,3207,3147, + 571, 619,1473,1005,1744,2281, 449,1887,2396,3685, 275, 375,3816,1743,3844,3731, + 845,1983,2350,4210,1377, 773, 967,3499,3052,3743,2725,4007,1697,1022,3943,1464, +3264,2855,2722,1952,1029,2839,2467, 84,4383,2215, 820,1391,2015,2448,3672, 377, +1948,2168, 797,2545,3536,2578,2645, 94,2874,1678, 405,1259,3071, 771, 546,1315, + 470,1243,3083, 895,2468, 981, 969,2037, 846,4181, 653,1276,2928, 14,2594, 557, +3007,2474, 156, 902,1338,1740,2574, 537,2518, 973,2282,2216,2433,1928, 138,2903, +1293,2631,1612, 646,3457, 839,2935, 111, 496,2191,2847, 589,3186, 149,3994,2060, +4031,2641,4067,3145,1870, 37,3597,2136,1025,2051,3009,3383,3549,1121,1016,3261, +1301, 251,2446,2599,2153, 872,3246, 637, 334,3705, 831, 884, 921,3065,3140,4092, +2198,1944, 246,2964, 108,2045,1152,1921,2308,1031, 203,3173,4170,1907,3890, 810, +1401,2003,1690, 506, 647,1242,2828,1761,1649,3208,2249,1589,3709,2931,5156,1708, + 498, 666,2613, 834,3817,1231, 184,2851,1124, 883,3197,2261,3710,1765,1553,2658, +1178,2639,2351, 93,1193, 942,2538,2141,4402, 235,1821, 870,1591,2192,1709,1871, +3341,1618,4126,2595,2334, 603, 651, 69, 701, 268,2662,3411,2555,1380,1606, 503, + 448, 254,2371,2646, 574,1187,2309,1770, 322,2235,1292,1801, 305, 566,1133, 229, +2067,2057, 706, 167, 483,2002,2672,3295,1820,3561,3067, 316, 378,2746,3452,1112, + 136,1981, 507,1651,2917,1117, 285,4591, 182,2580,3522,1304, 335,3303,1835,2504, +1795,1792,2248, 674,1018,2106,2449,1857,2292,2845, 976,3047,1781,2600,2727,1389, +1281, 52,3152, 153, 265,3950, 672,3485,3951,4463, 430,1183, 365, 278,2169, 27, +1407,1336,2304, 209,1340,1730,2202,1852,2403,2883, 979,1737,1062, 631,2829,2542, +3876,2592, 825,2086,2226,3048,3625, 352,1417,3724, 542, 991, 431,1351,3938,1861, +2294, 826,1361,2927,3142,3503,1738, 463,2462,2723, 582,1916,1595,2808, 400,3845, +3891,2868,3621,2254, 58,2492,1123, 910,2160,2614,1372,1603,1196,1072,3385,1700, +3267,1980, 696, 480,2430, 920, 799,1570,2920,1951,2041,4047,2540,1321,4223,2469, +3562,2228,1271,2602, 401,2833,3351,2575,5157, 907,2312,1256, 410, 263,3507,1582, + 996, 678,1849,2316,1480, 908,3545,2237, 703,2322, 667,1826,2849,1531,2604,2999, +2407,3146,2151,2630,1786,3711, 469,3542, 497,3899,2409, 858, 837,4446,3393,1274, + 786, 620,1845,2001,3311, 484, 308,3367,1204,1815,3691,2332,1532,2557,1842,2020, +2724,1927,2333,4440, 567, 22,1673,2728,4475,1987,1858,1144,1597, 101,1832,3601, + 12, 974,3783,4391, 951,1412, 1,3720, 453,4608,4041, 528,1041,1027,3230,2628, +1129, 875,1051,3291,1203,2262,1069,2860,2799,2149,2615,3278, 144,1758,3040, 31, + 475,1680, 366,2685,3184, 311,1642,4008,2466,5036,1593,1493,2809, 216,1420,1668, + 233, 304,2128,3284, 232,1429,1768,1040,2008,3407,2740,2967,2543, 242,2133, 778, +1565,2022,2620, 505,2189,2756,1098,2273, 372,1614, 708, 553,2846,2094,2278, 169, +3626,2835,4161, 228,2674,3165, 809,1454,1309, 466,1705,1095, 900,3423, 880,2667, +3751,5258,2317,3109,2571,4317,2766,1503,1342, 866,4447,1118, 63,2076, 314,1881, +1348,1061, 172, 978,3515,1747, 532, 511,3970, 6, 601, 905,2699,3300,1751, 276, +1467,3725,2668, 65,4239,2544,2779,2556,1604, 578,2451,1802, 992,2331,2624,1320, +3446, 713,1513,1013, 103,2786,2447,1661, 886,1702, 916, 654,3574,2031,1556, 751, +2178,2821,2179,1498,1538,2176, 271, 914,2251,2080,1325, 638,1953,2937,3877,2432, +2754, 95,3265,1716, 260,1227,4083, 775, 106,1357,3254, 426,1607, 555,2480, 772, +1985, 244,2546, 474, 495,1046,2611,1851,2061, 71,2089,1675,2590, 742,3758,2843, +3222,1433, 267,2180,2576,2826,2233,2092,3913,2435, 956,1745,3075, 856,2113,1116, + 451, 3,1988,2896,1398, 993,2463,1878,2049,1341,2718,2721,2870,2108, 712,2904, +4363,2753,2324, 277,2872,2349,2649, 384, 987, 435, 691,3000, 922, 164,3939, 652, +1500,1184,4153,2482,3373,2165,4848,2335,3775,3508,3154,2806,2830,1554,2102,1664, +2530,1434,2408, 893,1547,2623,3447,2832,2242,2532,3169,2856,3223,2078, 49,3770, +3469, 462, 318, 656,2259,3250,3069, 679,1629,2758, 344,1138,1104,3120,1836,1283, +3115,2154,1437,4448, 934, 759,1999, 794,2862,1038, 533,2560,1722,2342, 855,2626, +1197,1663,4476,3127, 85,4240,2528, 25,1111,1181,3673, 407,3470,4561,2679,2713, + 768,1925,2841,3986,1544,1165, 932, 373,1240,2146,1930,2673, 721,4766, 354,4333, + 391,2963, 187, 61,3364,1442,1102, 330,1940,1767, 341,3809,4118, 393,2496,2062, +2211, 105, 331, 300, 439, 913,1332, 626, 379,3304,1557, 328, 689,3952, 309,1555, + 931, 317,2517,3027, 325, 569, 686,2107,3084, 60,1042,1333,2794, 264,3177,4014, +1628, 258,3712, 7,4464,1176,1043,1778, 683, 114,1975, 78,1492, 383,1886, 510, + 386, 645,5291,2891,2069,3305,4138,3867,2939,2603,2493,1935,1066,1848,3588,1015, +1282,1289,4609, 697,1453,3044,2666,3611,1856,2412, 54, 719,1330, 568,3778,2459, +1748, 788, 492, 551,1191,1000, 488,3394,3763, 282,1799, 348,2016,1523,3155,2390, +1049, 382,2019,1788,1170, 729,2968,3523, 897,3926,2785,2938,3292, 350,2319,3238, +1718,1717,2655,3453,3143,4465, 161,2889,2980,2009,1421, 56,1908,1640,2387,2232, +1917,1874,2477,4921, 148, 83,3438, 592,4245,2882,1822,1055, 741, 115,1496,1624, + 381,1638,4592,1020, 516,3214, 458, 947,4575,1432, 211,1514,2926,1865,2142, 189, + 852,1221,1400,1486, 882,2299,4036, 351, 28,1122, 700,6479,6480,6481,6482,6483, #last 512 +) + diff --git a/venv/Lib/site-packages/pip/_vendor/chardet/gb2312prober.py b/venv/Lib/site-packages/pip/_vendor/chardet/gb2312prober.py new file mode 100644 index 0000000..8446d2d --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/chardet/gb2312prober.py @@ -0,0 +1,46 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .mbcharsetprober import MultiByteCharSetProber +from .codingstatemachine import CodingStateMachine +from .chardistribution import GB2312DistributionAnalysis +from .mbcssm import GB2312_SM_MODEL + +class GB2312Prober(MultiByteCharSetProber): + def __init__(self): + super(GB2312Prober, self).__init__() + self.coding_sm = CodingStateMachine(GB2312_SM_MODEL) + self.distribution_analyzer = GB2312DistributionAnalysis() + self.reset() + + @property + def charset_name(self): + return "GB2312" + + @property + def language(self): + return "Chinese" diff --git a/venv/Lib/site-packages/pip/_vendor/chardet/hebrewprober.py b/venv/Lib/site-packages/pip/_vendor/chardet/hebrewprober.py new file mode 100644 index 0000000..b0e1bf4 --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/chardet/hebrewprober.py @@ -0,0 +1,292 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Universal charset detector code. +# +# The Initial Developer of the Original Code is +# Shy Shalom +# Portions created by the Initial Developer are Copyright (C) 2005 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .charsetprober import CharSetProber +from .enums import ProbingState + +# This prober doesn't actually recognize a language or a charset. +# It is a helper prober for the use of the Hebrew model probers + +### General ideas of the Hebrew charset recognition ### +# +# Four main charsets exist in Hebrew: +# "ISO-8859-8" - Visual Hebrew +# "windows-1255" - Logical Hebrew +# "ISO-8859-8-I" - Logical Hebrew +# "x-mac-hebrew" - ?? Logical Hebrew ?? +# +# Both "ISO" charsets use a completely identical set of code points, whereas +# "windows-1255" and "x-mac-hebrew" are two different proper supersets of +# these code points. windows-1255 defines additional characters in the range +# 0x80-0x9F as some misc punctuation marks as well as some Hebrew-specific +# diacritics and additional 'Yiddish' ligature letters in the range 0xc0-0xd6. +# x-mac-hebrew defines similar additional code points but with a different +# mapping. +# +# As far as an average Hebrew text with no diacritics is concerned, all four +# charsets are identical with respect to code points. Meaning that for the +# main Hebrew alphabet, all four map the same values to all 27 Hebrew letters +# (including final letters). +# +# The dominant difference between these charsets is their directionality. +# "Visual" directionality means that the text is ordered as if the renderer is +# not aware of a BIDI rendering algorithm. The renderer sees the text and +# draws it from left to right. The text itself when ordered naturally is read +# backwards. A buffer of Visual Hebrew generally looks like so: +# "[last word of first line spelled backwards] [whole line ordered backwards +# and spelled backwards] [first word of first line spelled backwards] +# [end of line] [last word of second line] ... etc' " +# adding punctuation marks, numbers and English text to visual text is +# naturally also "visual" and from left to right. +# +# "Logical" directionality means the text is ordered "naturally" according to +# the order it is read. It is the responsibility of the renderer to display +# the text from right to left. A BIDI algorithm is used to place general +# punctuation marks, numbers and English text in the text. +# +# Texts in x-mac-hebrew are almost impossible to find on the Internet. From +# what little evidence I could find, it seems that its general directionality +# is Logical. +# +# To sum up all of the above, the Hebrew probing mechanism knows about two +# charsets: +# Visual Hebrew - "ISO-8859-8" - backwards text - Words and sentences are +# backwards while line order is natural. For charset recognition purposes +# the line order is unimportant (In fact, for this implementation, even +# word order is unimportant). +# Logical Hebrew - "windows-1255" - normal, naturally ordered text. +# +# "ISO-8859-8-I" is a subset of windows-1255 and doesn't need to be +# specifically identified. +# "x-mac-hebrew" is also identified as windows-1255. A text in x-mac-hebrew +# that contain special punctuation marks or diacritics is displayed with +# some unconverted characters showing as question marks. This problem might +# be corrected using another model prober for x-mac-hebrew. Due to the fact +# that x-mac-hebrew texts are so rare, writing another model prober isn't +# worth the effort and performance hit. +# +#### The Prober #### +# +# The prober is divided between two SBCharSetProbers and a HebrewProber, +# all of which are managed, created, fed data, inquired and deleted by the +# SBCSGroupProber. The two SBCharSetProbers identify that the text is in +# fact some kind of Hebrew, Logical or Visual. The final decision about which +# one is it is made by the HebrewProber by combining final-letter scores +# with the scores of the two SBCharSetProbers to produce a final answer. +# +# The SBCSGroupProber is responsible for stripping the original text of HTML +# tags, English characters, numbers, low-ASCII punctuation characters, spaces +# and new lines. It reduces any sequence of such characters to a single space. +# The buffer fed to each prober in the SBCS group prober is pure text in +# high-ASCII. +# The two SBCharSetProbers (model probers) share the same language model: +# Win1255Model. +# The first SBCharSetProber uses the model normally as any other +# SBCharSetProber does, to recognize windows-1255, upon which this model was +# built. The second SBCharSetProber is told to make the pair-of-letter +# lookup in the language model backwards. This in practice exactly simulates +# a visual Hebrew model using the windows-1255 logical Hebrew model. +# +# The HebrewProber is not using any language model. All it does is look for +# final-letter evidence suggesting the text is either logical Hebrew or visual +# Hebrew. Disjointed from the model probers, the results of the HebrewProber +# alone are meaningless. HebrewProber always returns 0.00 as confidence +# since it never identifies a charset by itself. Instead, the pointer to the +# HebrewProber is passed to the model probers as a helper "Name Prober". +# When the Group prober receives a positive identification from any prober, +# it asks for the name of the charset identified. If the prober queried is a +# Hebrew model prober, the model prober forwards the call to the +# HebrewProber to make the final decision. In the HebrewProber, the +# decision is made according to the final-letters scores maintained and Both +# model probers scores. The answer is returned in the form of the name of the +# charset identified, either "windows-1255" or "ISO-8859-8". + +class HebrewProber(CharSetProber): + # windows-1255 / ISO-8859-8 code points of interest + FINAL_KAF = 0xea + NORMAL_KAF = 0xeb + FINAL_MEM = 0xed + NORMAL_MEM = 0xee + FINAL_NUN = 0xef + NORMAL_NUN = 0xf0 + FINAL_PE = 0xf3 + NORMAL_PE = 0xf4 + FINAL_TSADI = 0xf5 + NORMAL_TSADI = 0xf6 + + # Minimum Visual vs Logical final letter score difference. + # If the difference is below this, don't rely solely on the final letter score + # distance. + MIN_FINAL_CHAR_DISTANCE = 5 + + # Minimum Visual vs Logical model score difference. + # If the difference is below this, don't rely at all on the model score + # distance. + MIN_MODEL_DISTANCE = 0.01 + + VISUAL_HEBREW_NAME = "ISO-8859-8" + LOGICAL_HEBREW_NAME = "windows-1255" + + def __init__(self): + super(HebrewProber, self).__init__() + self._final_char_logical_score = None + self._final_char_visual_score = None + self._prev = None + self._before_prev = None + self._logical_prober = None + self._visual_prober = None + self.reset() + + def reset(self): + self._final_char_logical_score = 0 + self._final_char_visual_score = 0 + # The two last characters seen in the previous buffer, + # mPrev and mBeforePrev are initialized to space in order to simulate + # a word delimiter at the beginning of the data + self._prev = ' ' + self._before_prev = ' ' + # These probers are owned by the group prober. + + def set_model_probers(self, logicalProber, visualProber): + self._logical_prober = logicalProber + self._visual_prober = visualProber + + def is_final(self, c): + return c in [self.FINAL_KAF, self.FINAL_MEM, self.FINAL_NUN, + self.FINAL_PE, self.FINAL_TSADI] + + def is_non_final(self, c): + # The normal Tsadi is not a good Non-Final letter due to words like + # 'lechotet' (to chat) containing an apostrophe after the tsadi. This + # apostrophe is converted to a space in FilterWithoutEnglishLetters + # causing the Non-Final tsadi to appear at an end of a word even + # though this is not the case in the original text. + # The letters Pe and Kaf rarely display a related behavior of not being + # a good Non-Final letter. Words like 'Pop', 'Winamp' and 'Mubarak' + # for example legally end with a Non-Final Pe or Kaf. However, the + # benefit of these letters as Non-Final letters outweighs the damage + # since these words are quite rare. + return c in [self.NORMAL_KAF, self.NORMAL_MEM, + self.NORMAL_NUN, self.NORMAL_PE] + + def feed(self, byte_str): + # Final letter analysis for logical-visual decision. + # Look for evidence that the received buffer is either logical Hebrew + # or visual Hebrew. + # The following cases are checked: + # 1) A word longer than 1 letter, ending with a final letter. This is + # an indication that the text is laid out "naturally" since the + # final letter really appears at the end. +1 for logical score. + # 2) A word longer than 1 letter, ending with a Non-Final letter. In + # normal Hebrew, words ending with Kaf, Mem, Nun, Pe or Tsadi, + # should not end with the Non-Final form of that letter. Exceptions + # to this rule are mentioned above in isNonFinal(). This is an + # indication that the text is laid out backwards. +1 for visual + # score + # 3) A word longer than 1 letter, starting with a final letter. Final + # letters should not appear at the beginning of a word. This is an + # indication that the text is laid out backwards. +1 for visual + # score. + # + # The visual score and logical score are accumulated throughout the + # text and are finally checked against each other in GetCharSetName(). + # No checking for final letters in the middle of words is done since + # that case is not an indication for either Logical or Visual text. + # + # We automatically filter out all 7-bit characters (replace them with + # spaces) so the word boundary detection works properly. [MAP] + + if self.state == ProbingState.NOT_ME: + # Both model probers say it's not them. No reason to continue. + return ProbingState.NOT_ME + + byte_str = self.filter_high_byte_only(byte_str) + + for cur in byte_str: + if cur == ' ': + # We stand on a space - a word just ended + if self._before_prev != ' ': + # next-to-last char was not a space so self._prev is not a + # 1 letter word + if self.is_final(self._prev): + # case (1) [-2:not space][-1:final letter][cur:space] + self._final_char_logical_score += 1 + elif self.is_non_final(self._prev): + # case (2) [-2:not space][-1:Non-Final letter][ + # cur:space] + self._final_char_visual_score += 1 + else: + # Not standing on a space + if ((self._before_prev == ' ') and + (self.is_final(self._prev)) and (cur != ' ')): + # case (3) [-2:space][-1:final letter][cur:not space] + self._final_char_visual_score += 1 + self._before_prev = self._prev + self._prev = cur + + # Forever detecting, till the end or until both model probers return + # ProbingState.NOT_ME (handled above) + return ProbingState.DETECTING + + @property + def charset_name(self): + # Make the decision: is it Logical or Visual? + # If the final letter score distance is dominant enough, rely on it. + finalsub = self._final_char_logical_score - self._final_char_visual_score + if finalsub >= self.MIN_FINAL_CHAR_DISTANCE: + return self.LOGICAL_HEBREW_NAME + if finalsub <= -self.MIN_FINAL_CHAR_DISTANCE: + return self.VISUAL_HEBREW_NAME + + # It's not dominant enough, try to rely on the model scores instead. + modelsub = (self._logical_prober.get_confidence() + - self._visual_prober.get_confidence()) + if modelsub > self.MIN_MODEL_DISTANCE: + return self.LOGICAL_HEBREW_NAME + if modelsub < -self.MIN_MODEL_DISTANCE: + return self.VISUAL_HEBREW_NAME + + # Still no good, back to final letter distance, maybe it'll save the + # day. + if finalsub < 0.0: + return self.VISUAL_HEBREW_NAME + + # (finalsub > 0 - Logical) or (don't know what to do) default to + # Logical. + return self.LOGICAL_HEBREW_NAME + + @property + def language(self): + return 'Hebrew' + + @property + def state(self): + # Remain active as long as any of the model probers are active. + if (self._logical_prober.state == ProbingState.NOT_ME) and \ + (self._visual_prober.state == ProbingState.NOT_ME): + return ProbingState.NOT_ME + return ProbingState.DETECTING diff --git a/venv/Lib/site-packages/pip/_vendor/chardet/jisfreq.py b/venv/Lib/site-packages/pip/_vendor/chardet/jisfreq.py new file mode 100644 index 0000000..83fc082 --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/chardet/jisfreq.py @@ -0,0 +1,325 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +# Sampling from about 20M text materials include literature and computer technology +# +# Japanese frequency table, applied to both S-JIS and EUC-JP +# They are sorted in order. + +# 128 --> 0.77094 +# 256 --> 0.85710 +# 512 --> 0.92635 +# 1024 --> 0.97130 +# 2048 --> 0.99431 +# +# Ideal Distribution Ratio = 0.92635 / (1-0.92635) = 12.58 +# Random Distribution Ration = 512 / (2965+62+83+86-512) = 0.191 +# +# Typical Distribution Ratio, 25% of IDR + +JIS_TYPICAL_DISTRIBUTION_RATIO = 3.0 + +# Char to FreqOrder table , +JIS_TABLE_SIZE = 4368 + +JIS_CHAR_TO_FREQ_ORDER = ( + 40, 1, 6, 182, 152, 180, 295,2127, 285, 381,3295,4304,3068,4606,3165,3510, # 16 +3511,1822,2785,4607,1193,2226,5070,4608, 171,2996,1247, 18, 179,5071, 856,1661, # 32 +1262,5072, 619, 127,3431,3512,3230,1899,1700, 232, 228,1294,1298, 284, 283,2041, # 48 +2042,1061,1062, 48, 49, 44, 45, 433, 434,1040,1041, 996, 787,2997,1255,4305, # 64 +2108,4609,1684,1648,5073,5074,5075,5076,5077,5078,3687,5079,4610,5080,3927,3928, # 80 +5081,3296,3432, 290,2285,1471,2187,5082,2580,2825,1303,2140,1739,1445,2691,3375, # 96 +1691,3297,4306,4307,4611, 452,3376,1182,2713,3688,3069,4308,5083,5084,5085,5086, # 112 +5087,5088,5089,5090,5091,5092,5093,5094,5095,5096,5097,5098,5099,5100,5101,5102, # 128 +5103,5104,5105,5106,5107,5108,5109,5110,5111,5112,4097,5113,5114,5115,5116,5117, # 144 +5118,5119,5120,5121,5122,5123,5124,5125,5126,5127,5128,5129,5130,5131,5132,5133, # 160 +5134,5135,5136,5137,5138,5139,5140,5141,5142,5143,5144,5145,5146,5147,5148,5149, # 176 +5150,5151,5152,4612,5153,5154,5155,5156,5157,5158,5159,5160,5161,5162,5163,5164, # 192 +5165,5166,5167,5168,5169,5170,5171,5172,5173,5174,5175,1472, 598, 618, 820,1205, # 208 +1309,1412,1858,1307,1692,5176,5177,5178,5179,5180,5181,5182,1142,1452,1234,1172, # 224 +1875,2043,2149,1793,1382,2973, 925,2404,1067,1241, 960,1377,2935,1491, 919,1217, # 240 +1865,2030,1406,1499,2749,4098,5183,5184,5185,5186,5187,5188,2561,4099,3117,1804, # 256 +2049,3689,4309,3513,1663,5189,3166,3118,3298,1587,1561,3433,5190,3119,1625,2998, # 272 +3299,4613,1766,3690,2786,4614,5191,5192,5193,5194,2161, 26,3377, 2,3929, 20, # 288 +3691, 47,4100, 50, 17, 16, 35, 268, 27, 243, 42, 155, 24, 154, 29, 184, # 304 + 4, 91, 14, 92, 53, 396, 33, 289, 9, 37, 64, 620, 21, 39, 321, 5, # 320 + 12, 11, 52, 13, 3, 208, 138, 0, 7, 60, 526, 141, 151,1069, 181, 275, # 336 +1591, 83, 132,1475, 126, 331, 829, 15, 69, 160, 59, 22, 157, 55,1079, 312, # 352 + 109, 38, 23, 25, 10, 19, 79,5195, 61, 382,1124, 8, 30,5196,5197,5198, # 368 +5199,5200,5201,5202,5203,5204,5205,5206, 89, 62, 74, 34,2416, 112, 139, 196, # 384 + 271, 149, 84, 607, 131, 765, 46, 88, 153, 683, 76, 874, 101, 258, 57, 80, # 400 + 32, 364, 121,1508, 169,1547, 68, 235, 145,2999, 41, 360,3027, 70, 63, 31, # 416 + 43, 259, 262,1383, 99, 533, 194, 66, 93, 846, 217, 192, 56, 106, 58, 565, # 432 + 280, 272, 311, 256, 146, 82, 308, 71, 100, 128, 214, 655, 110, 261, 104,1140, # 448 + 54, 51, 36, 87, 67,3070, 185,2618,2936,2020, 28,1066,2390,2059,5207,5208, # 464 +5209,5210,5211,5212,5213,5214,5215,5216,4615,5217,5218,5219,5220,5221,5222,5223, # 480 +5224,5225,5226,5227,5228,5229,5230,5231,5232,5233,5234,5235,5236,3514,5237,5238, # 496 +5239,5240,5241,5242,5243,5244,2297,2031,4616,4310,3692,5245,3071,5246,3598,5247, # 512 +4617,3231,3515,5248,4101,4311,4618,3808,4312,4102,5249,4103,4104,3599,5250,5251, # 528 +5252,5253,5254,5255,5256,5257,5258,5259,5260,5261,5262,5263,5264,5265,5266,5267, # 544 +5268,5269,5270,5271,5272,5273,5274,5275,5276,5277,5278,5279,5280,5281,5282,5283, # 560 +5284,5285,5286,5287,5288,5289,5290,5291,5292,5293,5294,5295,5296,5297,5298,5299, # 576 +5300,5301,5302,5303,5304,5305,5306,5307,5308,5309,5310,5311,5312,5313,5314,5315, # 592 +5316,5317,5318,5319,5320,5321,5322,5323,5324,5325,5326,5327,5328,5329,5330,5331, # 608 +5332,5333,5334,5335,5336,5337,5338,5339,5340,5341,5342,5343,5344,5345,5346,5347, # 624 +5348,5349,5350,5351,5352,5353,5354,5355,5356,5357,5358,5359,5360,5361,5362,5363, # 640 +5364,5365,5366,5367,5368,5369,5370,5371,5372,5373,5374,5375,5376,5377,5378,5379, # 656 +5380,5381, 363, 642,2787,2878,2788,2789,2316,3232,2317,3434,2011, 165,1942,3930, # 672 +3931,3932,3933,5382,4619,5383,4620,5384,5385,5386,5387,5388,5389,5390,5391,5392, # 688 +5393,5394,5395,5396,5397,5398,5399,5400,5401,5402,5403,5404,5405,5406,5407,5408, # 704 +5409,5410,5411,5412,5413,5414,5415,5416,5417,5418,5419,5420,5421,5422,5423,5424, # 720 +5425,5426,5427,5428,5429,5430,5431,5432,5433,5434,5435,5436,5437,5438,5439,5440, # 736 +5441,5442,5443,5444,5445,5446,5447,5448,5449,5450,5451,5452,5453,5454,5455,5456, # 752 +5457,5458,5459,5460,5461,5462,5463,5464,5465,5466,5467,5468,5469,5470,5471,5472, # 768 +5473,5474,5475,5476,5477,5478,5479,5480,5481,5482,5483,5484,5485,5486,5487,5488, # 784 +5489,5490,5491,5492,5493,5494,5495,5496,5497,5498,5499,5500,5501,5502,5503,5504, # 800 +5505,5506,5507,5508,5509,5510,5511,5512,5513,5514,5515,5516,5517,5518,5519,5520, # 816 +5521,5522,5523,5524,5525,5526,5527,5528,5529,5530,5531,5532,5533,5534,5535,5536, # 832 +5537,5538,5539,5540,5541,5542,5543,5544,5545,5546,5547,5548,5549,5550,5551,5552, # 848 +5553,5554,5555,5556,5557,5558,5559,5560,5561,5562,5563,5564,5565,5566,5567,5568, # 864 +5569,5570,5571,5572,5573,5574,5575,5576,5577,5578,5579,5580,5581,5582,5583,5584, # 880 +5585,5586,5587,5588,5589,5590,5591,5592,5593,5594,5595,5596,5597,5598,5599,5600, # 896 +5601,5602,5603,5604,5605,5606,5607,5608,5609,5610,5611,5612,5613,5614,5615,5616, # 912 +5617,5618,5619,5620,5621,5622,5623,5624,5625,5626,5627,5628,5629,5630,5631,5632, # 928 +5633,5634,5635,5636,5637,5638,5639,5640,5641,5642,5643,5644,5645,5646,5647,5648, # 944 +5649,5650,5651,5652,5653,5654,5655,5656,5657,5658,5659,5660,5661,5662,5663,5664, # 960 +5665,5666,5667,5668,5669,5670,5671,5672,5673,5674,5675,5676,5677,5678,5679,5680, # 976 +5681,5682,5683,5684,5685,5686,5687,5688,5689,5690,5691,5692,5693,5694,5695,5696, # 992 +5697,5698,5699,5700,5701,5702,5703,5704,5705,5706,5707,5708,5709,5710,5711,5712, # 1008 +5713,5714,5715,5716,5717,5718,5719,5720,5721,5722,5723,5724,5725,5726,5727,5728, # 1024 +5729,5730,5731,5732,5733,5734,5735,5736,5737,5738,5739,5740,5741,5742,5743,5744, # 1040 +5745,5746,5747,5748,5749,5750,5751,5752,5753,5754,5755,5756,5757,5758,5759,5760, # 1056 +5761,5762,5763,5764,5765,5766,5767,5768,5769,5770,5771,5772,5773,5774,5775,5776, # 1072 +5777,5778,5779,5780,5781,5782,5783,5784,5785,5786,5787,5788,5789,5790,5791,5792, # 1088 +5793,5794,5795,5796,5797,5798,5799,5800,5801,5802,5803,5804,5805,5806,5807,5808, # 1104 +5809,5810,5811,5812,5813,5814,5815,5816,5817,5818,5819,5820,5821,5822,5823,5824, # 1120 +5825,5826,5827,5828,5829,5830,5831,5832,5833,5834,5835,5836,5837,5838,5839,5840, # 1136 +5841,5842,5843,5844,5845,5846,5847,5848,5849,5850,5851,5852,5853,5854,5855,5856, # 1152 +5857,5858,5859,5860,5861,5862,5863,5864,5865,5866,5867,5868,5869,5870,5871,5872, # 1168 +5873,5874,5875,5876,5877,5878,5879,5880,5881,5882,5883,5884,5885,5886,5887,5888, # 1184 +5889,5890,5891,5892,5893,5894,5895,5896,5897,5898,5899,5900,5901,5902,5903,5904, # 1200 +5905,5906,5907,5908,5909,5910,5911,5912,5913,5914,5915,5916,5917,5918,5919,5920, # 1216 +5921,5922,5923,5924,5925,5926,5927,5928,5929,5930,5931,5932,5933,5934,5935,5936, # 1232 +5937,5938,5939,5940,5941,5942,5943,5944,5945,5946,5947,5948,5949,5950,5951,5952, # 1248 +5953,5954,5955,5956,5957,5958,5959,5960,5961,5962,5963,5964,5965,5966,5967,5968, # 1264 +5969,5970,5971,5972,5973,5974,5975,5976,5977,5978,5979,5980,5981,5982,5983,5984, # 1280 +5985,5986,5987,5988,5989,5990,5991,5992,5993,5994,5995,5996,5997,5998,5999,6000, # 1296 +6001,6002,6003,6004,6005,6006,6007,6008,6009,6010,6011,6012,6013,6014,6015,6016, # 1312 +6017,6018,6019,6020,6021,6022,6023,6024,6025,6026,6027,6028,6029,6030,6031,6032, # 1328 +6033,6034,6035,6036,6037,6038,6039,6040,6041,6042,6043,6044,6045,6046,6047,6048, # 1344 +6049,6050,6051,6052,6053,6054,6055,6056,6057,6058,6059,6060,6061,6062,6063,6064, # 1360 +6065,6066,6067,6068,6069,6070,6071,6072,6073,6074,6075,6076,6077,6078,6079,6080, # 1376 +6081,6082,6083,6084,6085,6086,6087,6088,6089,6090,6091,6092,6093,6094,6095,6096, # 1392 +6097,6098,6099,6100,6101,6102,6103,6104,6105,6106,6107,6108,6109,6110,6111,6112, # 1408 +6113,6114,2044,2060,4621, 997,1235, 473,1186,4622, 920,3378,6115,6116, 379,1108, # 1424 +4313,2657,2735,3934,6117,3809, 636,3233, 573,1026,3693,3435,2974,3300,2298,4105, # 1440 + 854,2937,2463, 393,2581,2417, 539, 752,1280,2750,2480, 140,1161, 440, 708,1569, # 1456 + 665,2497,1746,1291,1523,3000, 164,1603, 847,1331, 537,1997, 486, 508,1693,2418, # 1472 +1970,2227, 878,1220, 299,1030, 969, 652,2751, 624,1137,3301,2619, 65,3302,2045, # 1488 +1761,1859,3120,1930,3694,3516, 663,1767, 852, 835,3695, 269, 767,2826,2339,1305, # 1504 + 896,1150, 770,1616,6118, 506,1502,2075,1012,2519, 775,2520,2975,2340,2938,4314, # 1520 +3028,2086,1224,1943,2286,6119,3072,4315,2240,1273,1987,3935,1557, 175, 597, 985, # 1536 +3517,2419,2521,1416,3029, 585, 938,1931,1007,1052,1932,1685,6120,3379,4316,4623, # 1552 + 804, 599,3121,1333,2128,2539,1159,1554,2032,3810, 687,2033,2904, 952, 675,1467, # 1568 +3436,6121,2241,1096,1786,2440,1543,1924, 980,1813,2228, 781,2692,1879, 728,1918, # 1584 +3696,4624, 548,1950,4625,1809,1088,1356,3303,2522,1944, 502, 972, 373, 513,2827, # 1600 + 586,2377,2391,1003,1976,1631,6122,2464,1084, 648,1776,4626,2141, 324, 962,2012, # 1616 +2177,2076,1384, 742,2178,1448,1173,1810, 222, 102, 301, 445, 125,2420, 662,2498, # 1632 + 277, 200,1476,1165,1068, 224,2562,1378,1446, 450,1880, 659, 791, 582,4627,2939, # 1648 +3936,1516,1274, 555,2099,3697,1020,1389,1526,3380,1762,1723,1787,2229, 412,2114, # 1664 +1900,2392,3518, 512,2597, 427,1925,2341,3122,1653,1686,2465,2499, 697, 330, 273, # 1680 + 380,2162, 951, 832, 780, 991,1301,3073, 965,2270,3519, 668,2523,2636,1286, 535, # 1696 +1407, 518, 671, 957,2658,2378, 267, 611,2197,3030,6123, 248,2299, 967,1799,2356, # 1712 + 850,1418,3437,1876,1256,1480,2828,1718,6124,6125,1755,1664,2405,6126,4628,2879, # 1728 +2829, 499,2179, 676,4629, 557,2329,2214,2090, 325,3234, 464, 811,3001, 992,2342, # 1744 +2481,1232,1469, 303,2242, 466,1070,2163, 603,1777,2091,4630,2752,4631,2714, 322, # 1760 +2659,1964,1768, 481,2188,1463,2330,2857,3600,2092,3031,2421,4632,2318,2070,1849, # 1776 +2598,4633,1302,2254,1668,1701,2422,3811,2905,3032,3123,2046,4106,1763,1694,4634, # 1792 +1604, 943,1724,1454, 917, 868,2215,1169,2940, 552,1145,1800,1228,1823,1955, 316, # 1808 +1080,2510, 361,1807,2830,4107,2660,3381,1346,1423,1134,4108,6127, 541,1263,1229, # 1824 +1148,2540, 545, 465,1833,2880,3438,1901,3074,2482, 816,3937, 713,1788,2500, 122, # 1840 +1575, 195,1451,2501,1111,6128, 859, 374,1225,2243,2483,4317, 390,1033,3439,3075, # 1856 +2524,1687, 266, 793,1440,2599, 946, 779, 802, 507, 897,1081, 528,2189,1292, 711, # 1872 +1866,1725,1167,1640, 753, 398,2661,1053, 246, 348,4318, 137,1024,3440,1600,2077, # 1888 +2129, 825,4319, 698, 238, 521, 187,2300,1157,2423,1641,1605,1464,1610,1097,2541, # 1904 +1260,1436, 759,2255,1814,2150, 705,3235, 409,2563,3304, 561,3033,2005,2564, 726, # 1920 +1956,2343,3698,4109, 949,3812,3813,3520,1669, 653,1379,2525, 881,2198, 632,2256, # 1936 +1027, 778,1074, 733,1957, 514,1481,2466, 554,2180, 702,3938,1606,1017,1398,6129, # 1952 +1380,3521, 921, 993,1313, 594, 449,1489,1617,1166, 768,1426,1360, 495,1794,3601, # 1968 +1177,3602,1170,4320,2344, 476, 425,3167,4635,3168,1424, 401,2662,1171,3382,1998, # 1984 +1089,4110, 477,3169, 474,6130,1909, 596,2831,1842, 494, 693,1051,1028,1207,3076, # 2000 + 606,2115, 727,2790,1473,1115, 743,3522, 630, 805,1532,4321,2021, 366,1057, 838, # 2016 + 684,1114,2142,4322,2050,1492,1892,1808,2271,3814,2424,1971,1447,1373,3305,1090, # 2032 +1536,3939,3523,3306,1455,2199, 336, 369,2331,1035, 584,2393, 902, 718,2600,6131, # 2048 +2753, 463,2151,1149,1611,2467, 715,1308,3124,1268, 343,1413,3236,1517,1347,2663, # 2064 +2093,3940,2022,1131,1553,2100,2941,1427,3441,2942,1323,2484,6132,1980, 872,2368, # 2080 +2441,2943, 320,2369,2116,1082, 679,1933,3941,2791,3815, 625,1143,2023, 422,2200, # 2096 +3816,6133, 730,1695, 356,2257,1626,2301,2858,2637,1627,1778, 937, 883,2906,2693, # 2112 +3002,1769,1086, 400,1063,1325,3307,2792,4111,3077, 456,2345,1046, 747,6134,1524, # 2128 + 884,1094,3383,1474,2164,1059, 974,1688,2181,2258,1047, 345,1665,1187, 358, 875, # 2144 +3170, 305, 660,3524,2190,1334,1135,3171,1540,1649,2542,1527, 927, 968,2793, 885, # 2160 +1972,1850, 482, 500,2638,1218,1109,1085,2543,1654,2034, 876, 78,2287,1482,1277, # 2176 + 861,1675,1083,1779, 724,2754, 454, 397,1132,1612,2332, 893, 672,1237, 257,2259, # 2192 +2370, 135,3384, 337,2244, 547, 352, 340, 709,2485,1400, 788,1138,2511, 540, 772, # 2208 +1682,2260,2272,2544,2013,1843,1902,4636,1999,1562,2288,4637,2201,1403,1533, 407, # 2224 + 576,3308,1254,2071, 978,3385, 170, 136,1201,3125,2664,3172,2394, 213, 912, 873, # 2240 +3603,1713,2202, 699,3604,3699, 813,3442, 493, 531,1054, 468,2907,1483, 304, 281, # 2256 +4112,1726,1252,2094, 339,2319,2130,2639, 756,1563,2944, 748, 571,2976,1588,2425, # 2272 +2715,1851,1460,2426,1528,1392,1973,3237, 288,3309, 685,3386, 296, 892,2716,2216, # 2288 +1570,2245, 722,1747,2217, 905,3238,1103,6135,1893,1441,1965, 251,1805,2371,3700, # 2304 +2601,1919,1078, 75,2182,1509,1592,1270,2640,4638,2152,6136,3310,3817, 524, 706, # 2320 +1075, 292,3818,1756,2602, 317, 98,3173,3605,3525,1844,2218,3819,2502, 814, 567, # 2336 + 385,2908,1534,6137, 534,1642,3239, 797,6138,1670,1529, 953,4323, 188,1071, 538, # 2352 + 178, 729,3240,2109,1226,1374,2000,2357,2977, 731,2468,1116,2014,2051,6139,1261, # 2368 +1593, 803,2859,2736,3443, 556, 682, 823,1541,6140,1369,2289,1706,2794, 845, 462, # 2384 +2603,2665,1361, 387, 162,2358,1740, 739,1770,1720,1304,1401,3241,1049, 627,1571, # 2400 +2427,3526,1877,3942,1852,1500, 431,1910,1503, 677, 297,2795, 286,1433,1038,1198, # 2416 +2290,1133,1596,4113,4639,2469,1510,1484,3943,6141,2442, 108, 712,4640,2372, 866, # 2432 +3701,2755,3242,1348, 834,1945,1408,3527,2395,3243,1811, 824, 994,1179,2110,1548, # 2448 +1453, 790,3003, 690,4324,4325,2832,2909,3820,1860,3821, 225,1748, 310, 346,1780, # 2464 +2470, 821,1993,2717,2796, 828, 877,3528,2860,2471,1702,2165,2910,2486,1789, 453, # 2480 + 359,2291,1676, 73,1164,1461,1127,3311, 421, 604, 314,1037, 589, 116,2487, 737, # 2496 + 837,1180, 111, 244, 735,6142,2261,1861,1362, 986, 523, 418, 581,2666,3822, 103, # 2512 + 855, 503,1414,1867,2488,1091, 657,1597, 979, 605,1316,4641,1021,2443,2078,2001, # 2528 +1209, 96, 587,2166,1032, 260,1072,2153, 173, 94, 226,3244, 819,2006,4642,4114, # 2544 +2203, 231,1744, 782, 97,2667, 786,3387, 887, 391, 442,2219,4326,1425,6143,2694, # 2560 + 633,1544,1202, 483,2015, 592,2052,1958,2472,1655, 419, 129,4327,3444,3312,1714, # 2576 +1257,3078,4328,1518,1098, 865,1310,1019,1885,1512,1734, 469,2444, 148, 773, 436, # 2592 +1815,1868,1128,1055,4329,1245,2756,3445,2154,1934,1039,4643, 579,1238, 932,2320, # 2608 + 353, 205, 801, 115,2428, 944,2321,1881, 399,2565,1211, 678, 766,3944, 335,2101, # 2624 +1459,1781,1402,3945,2737,2131,1010, 844, 981,1326,1013, 550,1816,1545,2620,1335, # 2640 +1008, 371,2881, 936,1419,1613,3529,1456,1395,2273,1834,2604,1317,2738,2503, 416, # 2656 +1643,4330, 806,1126, 229, 591,3946,1314,1981,1576,1837,1666, 347,1790, 977,3313, # 2672 + 764,2861,1853, 688,2429,1920,1462, 77, 595, 415,2002,3034, 798,1192,4115,6144, # 2688 +2978,4331,3035,2695,2582,2072,2566, 430,2430,1727, 842,1396,3947,3702, 613, 377, # 2704 + 278, 236,1417,3388,3314,3174, 757,1869, 107,3530,6145,1194, 623,2262, 207,1253, # 2720 +2167,3446,3948, 492,1117,1935, 536,1838,2757,1246,4332, 696,2095,2406,1393,1572, # 2736 +3175,1782, 583, 190, 253,1390,2230, 830,3126,3389, 934,3245,1703,1749,2979,1870, # 2752 +2545,1656,2204, 869,2346,4116,3176,1817, 496,1764,4644, 942,1504, 404,1903,1122, # 2768 +1580,3606,2945,1022, 515, 372,1735, 955,2431,3036,6146,2797,1110,2302,2798, 617, # 2784 +6147, 441, 762,1771,3447,3607,3608,1904, 840,3037, 86, 939,1385, 572,1370,2445, # 2800 +1336, 114,3703, 898, 294, 203,3315, 703,1583,2274, 429, 961,4333,1854,1951,3390, # 2816 +2373,3704,4334,1318,1381, 966,1911,2322,1006,1155, 309, 989, 458,2718,1795,1372, # 2832 +1203, 252,1689,1363,3177, 517,1936, 168,1490, 562, 193,3823,1042,4117,1835, 551, # 2848 + 470,4645, 395, 489,3448,1871,1465,2583,2641, 417,1493, 279,1295, 511,1236,1119, # 2864 + 72,1231,1982,1812,3004, 871,1564, 984,3449,1667,2696,2096,4646,2347,2833,1673, # 2880 +3609, 695,3246,2668, 807,1183,4647, 890, 388,2333,1801,1457,2911,1765,1477,1031, # 2896 +3316,3317,1278,3391,2799,2292,2526, 163,3450,4335,2669,1404,1802,6148,2323,2407, # 2912 +1584,1728,1494,1824,1269, 298, 909,3318,1034,1632, 375, 776,1683,2061, 291, 210, # 2928 +1123, 809,1249,1002,2642,3038, 206,1011,2132, 144, 975, 882,1565, 342, 667, 754, # 2944 +1442,2143,1299,2303,2062, 447, 626,2205,1221,2739,2912,1144,1214,2206,2584, 760, # 2960 +1715, 614, 950,1281,2670,2621, 810, 577,1287,2546,4648, 242,2168, 250,2643, 691, # 2976 + 123,2644, 647, 313,1029, 689,1357,2946,1650, 216, 771,1339,1306, 808,2063, 549, # 2992 + 913,1371,2913,2914,6149,1466,1092,1174,1196,1311,2605,2396,1783,1796,3079, 406, # 3008 +2671,2117,3949,4649, 487,1825,2220,6150,2915, 448,2348,1073,6151,2397,1707, 130, # 3024 + 900,1598, 329, 176,1959,2527,1620,6152,2275,4336,3319,1983,2191,3705,3610,2155, # 3040 +3706,1912,1513,1614,6153,1988, 646, 392,2304,1589,3320,3039,1826,1239,1352,1340, # 3056 +2916, 505,2567,1709,1437,2408,2547, 906,6154,2672, 384,1458,1594,1100,1329, 710, # 3072 + 423,3531,2064,2231,2622,1989,2673,1087,1882, 333, 841,3005,1296,2882,2379, 580, # 3088 +1937,1827,1293,2585, 601, 574, 249,1772,4118,2079,1120, 645, 901,1176,1690, 795, # 3104 +2207, 478,1434, 516,1190,1530, 761,2080, 930,1264, 355, 435,1552, 644,1791, 987, # 3120 + 220,1364,1163,1121,1538, 306,2169,1327,1222, 546,2645, 218, 241, 610,1704,3321, # 3136 +1984,1839,1966,2528, 451,6155,2586,3707,2568, 907,3178, 254,2947, 186,1845,4650, # 3152 + 745, 432,1757, 428,1633, 888,2246,2221,2489,3611,2118,1258,1265, 956,3127,1784, # 3168 +4337,2490, 319, 510, 119, 457,3612, 274,2035,2007,4651,1409,3128, 970,2758, 590, # 3184 +2800, 661,2247,4652,2008,3950,1420,1549,3080,3322,3951,1651,1375,2111, 485,2491, # 3200 +1429,1156,6156,2548,2183,1495, 831,1840,2529,2446, 501,1657, 307,1894,3247,1341, # 3216 + 666, 899,2156,1539,2549,1559, 886, 349,2208,3081,2305,1736,3824,2170,2759,1014, # 3232 +1913,1386, 542,1397,2948, 490, 368, 716, 362, 159, 282,2569,1129,1658,1288,1750, # 3248 +2674, 276, 649,2016, 751,1496, 658,1818,1284,1862,2209,2087,2512,3451, 622,2834, # 3264 + 376, 117,1060,2053,1208,1721,1101,1443, 247,1250,3179,1792,3952,2760,2398,3953, # 3280 +6157,2144,3708, 446,2432,1151,2570,3452,2447,2761,2835,1210,2448,3082, 424,2222, # 3296 +1251,2449,2119,2836, 504,1581,4338, 602, 817, 857,3825,2349,2306, 357,3826,1470, # 3312 +1883,2883, 255, 958, 929,2917,3248, 302,4653,1050,1271,1751,2307,1952,1430,2697, # 3328 +2719,2359, 354,3180, 777, 158,2036,4339,1659,4340,4654,2308,2949,2248,1146,2232, # 3344 +3532,2720,1696,2623,3827,6158,3129,1550,2698,1485,1297,1428, 637, 931,2721,2145, # 3360 + 914,2550,2587, 81,2450, 612, 827,2646,1242,4655,1118,2884, 472,1855,3181,3533, # 3376 +3534, 569,1353,2699,1244,1758,2588,4119,2009,2762,2171,3709,1312,1531,6159,1152, # 3392 +1938, 134,1830, 471,3710,2276,1112,1535,3323,3453,3535, 982,1337,2950, 488, 826, # 3408 + 674,1058,1628,4120,2017, 522,2399, 211, 568,1367,3454, 350, 293,1872,1139,3249, # 3424 +1399,1946,3006,1300,2360,3324, 588, 736,6160,2606, 744, 669,3536,3828,6161,1358, # 3440 + 199, 723, 848, 933, 851,1939,1505,1514,1338,1618,1831,4656,1634,3613, 443,2740, # 3456 +3829, 717,1947, 491,1914,6162,2551,1542,4121,1025,6163,1099,1223, 198,3040,2722, # 3472 + 370, 410,1905,2589, 998,1248,3182,2380, 519,1449,4122,1710, 947, 928,1153,4341, # 3488 +2277, 344,2624,1511, 615, 105, 161,1212,1076,1960,3130,2054,1926,1175,1906,2473, # 3504 + 414,1873,2801,6164,2309, 315,1319,3325, 318,2018,2146,2157, 963, 631, 223,4342, # 3520 +4343,2675, 479,3711,1197,2625,3712,2676,2361,6165,4344,4123,6166,2451,3183,1886, # 3536 +2184,1674,1330,1711,1635,1506, 799, 219,3250,3083,3954,1677,3713,3326,2081,3614, # 3552 +1652,2073,4657,1147,3041,1752, 643,1961, 147,1974,3955,6167,1716,2037, 918,3007, # 3568 +1994, 120,1537, 118, 609,3184,4345, 740,3455,1219, 332,1615,3830,6168,1621,2980, # 3584 +1582, 783, 212, 553,2350,3714,1349,2433,2082,4124, 889,6169,2310,1275,1410, 973, # 3600 + 166,1320,3456,1797,1215,3185,2885,1846,2590,2763,4658, 629, 822,3008, 763, 940, # 3616 +1990,2862, 439,2409,1566,1240,1622, 926,1282,1907,2764, 654,2210,1607, 327,1130, # 3632 +3956,1678,1623,6170,2434,2192, 686, 608,3831,3715, 903,3957,3042,6171,2741,1522, # 3648 +1915,1105,1555,2552,1359, 323,3251,4346,3457, 738,1354,2553,2311,2334,1828,2003, # 3664 +3832,1753,2351,1227,6172,1887,4125,1478,6173,2410,1874,1712,1847, 520,1204,2607, # 3680 + 264,4659, 836,2677,2102, 600,4660,3833,2278,3084,6174,4347,3615,1342, 640, 532, # 3696 + 543,2608,1888,2400,2591,1009,4348,1497, 341,1737,3616,2723,1394, 529,3252,1321, # 3712 + 983,4661,1515,2120, 971,2592, 924, 287,1662,3186,4349,2700,4350,1519, 908,1948, # 3728 +2452, 156, 796,1629,1486,2223,2055, 694,4126,1259,1036,3392,1213,2249,2742,1889, # 3744 +1230,3958,1015, 910, 408, 559,3617,4662, 746, 725, 935,4663,3959,3009,1289, 563, # 3760 + 867,4664,3960,1567,2981,2038,2626, 988,2263,2381,4351, 143,2374, 704,1895,6175, # 3776 +1188,3716,2088, 673,3085,2362,4352, 484,1608,1921,2765,2918, 215, 904,3618,3537, # 3792 + 894, 509, 976,3043,2701,3961,4353,2837,2982, 498,6176,6177,1102,3538,1332,3393, # 3808 +1487,1636,1637, 233, 245,3962, 383, 650, 995,3044, 460,1520,1206,2352, 749,3327, # 3824 + 530, 700, 389,1438,1560,1773,3963,2264, 719,2951,2724,3834, 870,1832,1644,1000, # 3840 + 839,2474,3717, 197,1630,3394, 365,2886,3964,1285,2133, 734, 922, 818,1106, 732, # 3856 + 480,2083,1774,3458, 923,2279,1350, 221,3086, 85,2233,2234,3835,1585,3010,2147, # 3872 +1387,1705,2382,1619,2475, 133, 239,2802,1991,1016,2084,2383, 411,2838,1113, 651, # 3888 +1985,1160,3328, 990,1863,3087,1048,1276,2647, 265,2627,1599,3253,2056, 150, 638, # 3904 +2019, 656, 853, 326,1479, 680,1439,4354,1001,1759, 413,3459,3395,2492,1431, 459, # 3920 +4355,1125,3329,2265,1953,1450,2065,2863, 849, 351,2678,3131,3254,3255,1104,1577, # 3936 + 227,1351,1645,2453,2193,1421,2887, 812,2121, 634, 95,2435, 201,2312,4665,1646, # 3952 +1671,2743,1601,2554,2702,2648,2280,1315,1366,2089,3132,1573,3718,3965,1729,1189, # 3968 + 328,2679,1077,1940,1136, 558,1283, 964,1195, 621,2074,1199,1743,3460,3619,1896, # 3984 +1916,1890,3836,2952,1154,2112,1064, 862, 378,3011,2066,2113,2803,1568,2839,6178, # 4000 +3088,2919,1941,1660,2004,1992,2194, 142, 707,1590,1708,1624,1922,1023,1836,1233, # 4016 +1004,2313, 789, 741,3620,6179,1609,2411,1200,4127,3719,3720,4666,2057,3721, 593, # 4032 +2840, 367,2920,1878,6180,3461,1521, 628,1168, 692,2211,2649, 300, 720,2067,2571, # 4048 +2953,3396, 959,2504,3966,3539,3462,1977, 701,6181, 954,1043, 800, 681, 183,3722, # 4064 +1803,1730,3540,4128,2103, 815,2314, 174, 467, 230,2454,1093,2134, 755,3541,3397, # 4080 +1141,1162,6182,1738,2039, 270,3256,2513,1005,1647,2185,3837, 858,1679,1897,1719, # 4096 +2954,2324,1806, 402, 670, 167,4129,1498,2158,2104, 750,6183, 915, 189,1680,1551, # 4112 + 455,4356,1501,2455, 405,1095,2955, 338,1586,1266,1819, 570, 641,1324, 237,1556, # 4128 +2650,1388,3723,6184,1368,2384,1343,1978,3089,2436, 879,3724, 792,1191, 758,3012, # 4144 +1411,2135,1322,4357, 240,4667,1848,3725,1574,6185, 420,3045,1546,1391, 714,4358, # 4160 +1967, 941,1864, 863, 664, 426, 560,1731,2680,1785,2864,1949,2363, 403,3330,1415, # 4176 +1279,2136,1697,2335, 204, 721,2097,3838, 90,6186,2085,2505, 191,3967, 124,2148, # 4192 +1376,1798,1178,1107,1898,1405, 860,4359,1243,1272,2375,2983,1558,2456,1638, 113, # 4208 +3621, 578,1923,2609, 880, 386,4130, 784,2186,2266,1422,2956,2172,1722, 497, 263, # 4224 +2514,1267,2412,2610, 177,2703,3542, 774,1927,1344, 616,1432,1595,1018, 172,4360, # 4240 +2325, 911,4361, 438,1468,3622, 794,3968,2024,2173,1681,1829,2957, 945, 895,3090, # 4256 + 575,2212,2476, 475,2401,2681, 785,2744,1745,2293,2555,1975,3133,2865, 394,4668, # 4272 +3839, 635,4131, 639, 202,1507,2195,2766,1345,1435,2572,3726,1908,1184,1181,2457, # 4288 +3727,3134,4362, 843,2611, 437, 916,4669, 234, 769,1884,3046,3047,3623, 833,6187, # 4304 +1639,2250,2402,1355,1185,2010,2047, 999, 525,1732,1290,1488,2612, 948,1578,3728, # 4320 +2413,2477,1216,2725,2159, 334,3840,1328,3624,2921,1525,4132, 564,1056, 891,4363, # 4336 +1444,1698,2385,2251,3729,1365,2281,2235,1717,6188, 864,3841,2515, 444, 527,2767, # 4352 +2922,3625, 544, 461,6189, 566, 209,2437,3398,2098,1065,2068,3331,3626,3257,2137, # 4368 #last 512 +) + + diff --git a/venv/Lib/site-packages/pip/_vendor/chardet/jpcntx.py b/venv/Lib/site-packages/pip/_vendor/chardet/jpcntx.py new file mode 100644 index 0000000..20044e4 --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/chardet/jpcntx.py @@ -0,0 +1,233 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + + +# This is hiragana 2-char sequence table, the number in each cell represents its frequency category +jp2CharContext = ( +(0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1), +(2,4,0,4,0,3,0,4,0,3,4,4,4,2,4,3,3,4,3,2,3,3,4,2,3,3,3,2,4,1,4,3,3,1,5,4,3,4,3,4,3,5,3,0,3,5,4,2,0,3,1,0,3,3,0,3,3,0,1,1,0,4,3,0,3,3,0,4,0,2,0,3,5,5,5,5,4,0,4,1,0,3,4), +(0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2), +(0,4,0,5,0,5,0,4,0,4,5,4,4,3,5,3,5,1,5,3,4,3,4,4,3,4,3,3,4,3,5,4,4,3,5,5,3,5,5,5,3,5,5,3,4,5,5,3,1,3,2,0,3,4,0,4,2,0,4,2,1,5,3,2,3,5,0,4,0,2,0,5,4,4,5,4,5,0,4,0,0,4,4), +(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), +(0,3,0,4,0,3,0,3,0,4,5,4,3,3,3,3,4,3,5,4,4,3,5,4,4,3,4,3,4,4,4,4,5,3,4,4,3,4,5,5,4,5,5,1,4,5,4,3,0,3,3,1,3,3,0,4,4,0,3,3,1,5,3,3,3,5,0,4,0,3,0,4,4,3,4,3,3,0,4,1,1,3,4), +(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), +(0,4,0,3,0,3,0,4,0,3,4,4,3,2,2,1,2,1,3,1,3,3,3,3,3,4,3,1,3,3,5,3,3,0,4,3,0,5,4,3,3,5,4,4,3,4,4,5,0,1,2,0,1,2,0,2,2,0,1,0,0,5,2,2,1,4,0,3,0,1,0,4,4,3,5,4,3,0,2,1,0,4,3), +(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), +(0,3,0,5,0,4,0,2,1,4,4,2,4,1,4,2,4,2,4,3,3,3,4,3,3,3,3,1,4,2,3,3,3,1,4,4,1,1,1,4,3,3,2,0,2,4,3,2,0,3,3,0,3,1,1,0,0,0,3,3,0,4,2,2,3,4,0,4,0,3,0,4,4,5,3,4,4,0,3,0,0,1,4), +(1,4,0,4,0,4,0,4,0,3,5,4,4,3,4,3,5,4,3,3,4,3,5,4,4,4,4,3,4,2,4,3,3,1,5,4,3,2,4,5,4,5,5,4,4,5,4,4,0,3,2,2,3,3,0,4,3,1,3,2,1,4,3,3,4,5,0,3,0,2,0,4,5,5,4,5,4,0,4,0,0,5,4), +(0,5,0,5,0,4,0,3,0,4,4,3,4,3,3,3,4,0,4,4,4,3,4,3,4,3,3,1,4,2,4,3,4,0,5,4,1,4,5,4,4,5,3,2,4,3,4,3,2,4,1,3,3,3,2,3,2,0,4,3,3,4,3,3,3,4,0,4,0,3,0,4,5,4,4,4,3,0,4,1,0,1,3), +(0,3,1,4,0,3,0,2,0,3,4,4,3,1,4,2,3,3,4,3,4,3,4,3,4,4,3,2,3,1,5,4,4,1,4,4,3,5,4,4,3,5,5,4,3,4,4,3,1,2,3,1,2,2,0,3,2,0,3,1,0,5,3,3,3,4,3,3,3,3,4,4,4,4,5,4,2,0,3,3,2,4,3), +(0,2,0,3,0,1,0,1,0,0,3,2,0,0,2,0,1,0,2,1,3,3,3,1,2,3,1,0,1,0,4,2,1,1,3,3,0,4,3,3,1,4,3,3,0,3,3,2,0,0,0,0,1,0,0,2,0,0,0,0,0,4,1,0,2,3,2,2,2,1,3,3,3,4,4,3,2,0,3,1,0,3,3), +(0,4,0,4,0,3,0,3,0,4,4,4,3,3,3,3,3,3,4,3,4,2,4,3,4,3,3,2,4,3,4,5,4,1,4,5,3,5,4,5,3,5,4,0,3,5,5,3,1,3,3,2,2,3,0,3,4,1,3,3,2,4,3,3,3,4,0,4,0,3,0,4,5,4,4,5,3,0,4,1,0,3,4), +(0,2,0,3,0,3,0,0,0,2,2,2,1,0,1,0,0,0,3,0,3,0,3,0,1,3,1,0,3,1,3,3,3,1,3,3,3,0,1,3,1,3,4,0,0,3,1,1,0,3,2,0,0,0,0,1,3,0,1,0,0,3,3,2,0,3,0,0,0,0,0,3,4,3,4,3,3,0,3,0,0,2,3), +(2,3,0,3,0,2,0,1,0,3,3,4,3,1,3,1,1,1,3,1,4,3,4,3,3,3,0,0,3,1,5,4,3,1,4,3,2,5,5,4,4,4,4,3,3,4,4,4,0,2,1,1,3,2,0,1,2,0,0,1,0,4,1,3,3,3,0,3,0,1,0,4,4,4,5,5,3,0,2,0,0,4,4), +(0,2,0,1,0,3,1,3,0,2,3,3,3,0,3,1,0,0,3,0,3,2,3,1,3,2,1,1,0,0,4,2,1,0,2,3,1,4,3,2,0,4,4,3,1,3,1,3,0,1,0,0,1,0,0,0,1,0,0,0,0,4,1,1,1,2,0,3,0,0,0,3,4,2,4,3,2,0,1,0,0,3,3), +(0,1,0,4,0,5,0,4,0,2,4,4,2,3,3,2,3,3,5,3,3,3,4,3,4,2,3,0,4,3,3,3,4,1,4,3,2,1,5,5,3,4,5,1,3,5,4,2,0,3,3,0,1,3,0,4,2,0,1,3,1,4,3,3,3,3,0,3,0,1,0,3,4,4,4,5,5,0,3,0,1,4,5), +(0,2,0,3,0,3,0,0,0,2,3,1,3,0,4,0,1,1,3,0,3,4,3,2,3,1,0,3,3,2,3,1,3,0,2,3,0,2,1,4,1,2,2,0,0,3,3,0,0,2,0,0,0,1,0,0,0,0,2,2,0,3,2,1,3,3,0,2,0,2,0,0,3,3,1,2,4,0,3,0,2,2,3), +(2,4,0,5,0,4,0,4,0,2,4,4,4,3,4,3,3,3,1,2,4,3,4,3,4,4,5,0,3,3,3,3,2,0,4,3,1,4,3,4,1,4,4,3,3,4,4,3,1,2,3,0,4,2,0,4,1,0,3,3,0,4,3,3,3,4,0,4,0,2,0,3,5,3,4,5,2,0,3,0,0,4,5), +(0,3,0,4,0,1,0,1,0,1,3,2,2,1,3,0,3,0,2,0,2,0,3,0,2,0,0,0,1,0,1,1,0,0,3,1,0,0,0,4,0,3,1,0,2,1,3,0,0,0,0,0,0,3,0,0,0,0,0,0,0,4,2,2,3,1,0,3,0,0,0,1,4,4,4,3,0,0,4,0,0,1,4), +(1,4,1,5,0,3,0,3,0,4,5,4,4,3,5,3,3,4,4,3,4,1,3,3,3,3,2,1,4,1,5,4,3,1,4,4,3,5,4,4,3,5,4,3,3,4,4,4,0,3,3,1,2,3,0,3,1,0,3,3,0,5,4,4,4,4,4,4,3,3,5,4,4,3,3,5,4,0,3,2,0,4,4), +(0,2,0,3,0,1,0,0,0,1,3,3,3,2,4,1,3,0,3,1,3,0,2,2,1,1,0,0,2,0,4,3,1,0,4,3,0,4,4,4,1,4,3,1,1,3,3,1,0,2,0,0,1,3,0,0,0,0,2,0,0,4,3,2,4,3,5,4,3,3,3,4,3,3,4,3,3,0,2,1,0,3,3), +(0,2,0,4,0,3,0,2,0,2,5,5,3,4,4,4,4,1,4,3,3,0,4,3,4,3,1,3,3,2,4,3,0,3,4,3,0,3,4,4,2,4,4,0,4,5,3,3,2,2,1,1,1,2,0,1,5,0,3,3,2,4,3,3,3,4,0,3,0,2,0,4,4,3,5,5,0,0,3,0,2,3,3), +(0,3,0,4,0,3,0,1,0,3,4,3,3,1,3,3,3,0,3,1,3,0,4,3,3,1,1,0,3,0,3,3,0,0,4,4,0,1,5,4,3,3,5,0,3,3,4,3,0,2,0,1,1,1,0,1,3,0,1,2,1,3,3,2,3,3,0,3,0,1,0,1,3,3,4,4,1,0,1,2,2,1,3), +(0,1,0,4,0,4,0,3,0,1,3,3,3,2,3,1,1,0,3,0,3,3,4,3,2,4,2,0,1,0,4,3,2,0,4,3,0,5,3,3,2,4,4,4,3,3,3,4,0,1,3,0,0,1,0,0,1,0,0,0,0,4,2,3,3,3,0,3,0,0,0,4,4,4,5,3,2,0,3,3,0,3,5), +(0,2,0,3,0,0,0,3,0,1,3,0,2,0,0,0,1,0,3,1,1,3,3,0,0,3,0,0,3,0,2,3,1,0,3,1,0,3,3,2,0,4,2,2,0,2,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,2,1,2,0,1,0,1,0,0,0,1,3,1,2,0,0,0,1,0,0,1,4), +(0,3,0,3,0,5,0,1,0,2,4,3,1,3,3,2,1,1,5,2,1,0,5,1,2,0,0,0,3,3,2,2,3,2,4,3,0,0,3,3,1,3,3,0,2,5,3,4,0,3,3,0,1,2,0,2,2,0,3,2,0,2,2,3,3,3,0,2,0,1,0,3,4,4,2,5,4,0,3,0,0,3,5), +(0,3,0,3,0,3,0,1,0,3,3,3,3,0,3,0,2,0,2,1,1,0,2,0,1,0,0,0,2,1,0,0,1,0,3,2,0,0,3,3,1,2,3,1,0,3,3,0,0,1,0,0,0,0,0,2,0,0,0,0,0,2,3,1,2,3,0,3,0,1,0,3,2,1,0,4,3,0,1,1,0,3,3), +(0,4,0,5,0,3,0,3,0,4,5,5,4,3,5,3,4,3,5,3,3,2,5,3,4,4,4,3,4,3,4,5,5,3,4,4,3,4,4,5,4,4,4,3,4,5,5,4,2,3,4,2,3,4,0,3,3,1,4,3,2,4,3,3,5,5,0,3,0,3,0,5,5,5,5,4,4,0,4,0,1,4,4), +(0,4,0,4,0,3,0,3,0,3,5,4,4,2,3,2,5,1,3,2,5,1,4,2,3,2,3,3,4,3,3,3,3,2,5,4,1,3,3,5,3,4,4,0,4,4,3,1,1,3,1,0,2,3,0,2,3,0,3,0,0,4,3,1,3,4,0,3,0,2,0,4,4,4,3,4,5,0,4,0,0,3,4), +(0,3,0,3,0,3,1,2,0,3,4,4,3,3,3,0,2,2,4,3,3,1,3,3,3,1,1,0,3,1,4,3,2,3,4,4,2,4,4,4,3,4,4,3,2,4,4,3,1,3,3,1,3,3,0,4,1,0,2,2,1,4,3,2,3,3,5,4,3,3,5,4,4,3,3,0,4,0,3,2,2,4,4), +(0,2,0,1,0,0,0,0,0,1,2,1,3,0,0,0,0,0,2,0,1,2,1,0,0,1,0,0,0,0,3,0,0,1,0,1,1,3,1,0,0,0,1,1,0,1,1,0,0,0,0,0,2,0,0,0,0,0,0,0,0,1,1,2,2,0,3,4,0,0,0,1,1,0,0,1,0,0,0,0,0,1,1), +(0,1,0,0,0,1,0,0,0,0,4,0,4,1,4,0,3,0,4,0,3,0,4,0,3,0,3,0,4,1,5,1,4,0,0,3,0,5,0,5,2,0,1,0,0,0,2,1,4,0,1,3,0,0,3,0,0,3,1,1,4,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0), +(1,4,0,5,0,3,0,2,0,3,5,4,4,3,4,3,5,3,4,3,3,0,4,3,3,3,3,3,3,2,4,4,3,1,3,4,4,5,4,4,3,4,4,1,3,5,4,3,3,3,1,2,2,3,3,1,3,1,3,3,3,5,3,3,4,5,0,3,0,3,0,3,4,3,4,4,3,0,3,0,2,4,3), +(0,1,0,4,0,0,0,0,0,1,4,0,4,1,4,2,4,0,3,0,1,0,1,0,0,0,0,0,2,0,3,1,1,1,0,3,0,0,0,1,2,1,0,0,1,1,1,1,0,1,0,0,0,1,0,0,3,0,0,0,0,3,2,0,2,2,0,1,0,0,0,2,3,2,3,3,0,0,0,0,2,1,0), +(0,5,1,5,0,3,0,3,0,5,4,4,5,1,5,3,3,0,4,3,4,3,5,3,4,3,3,2,4,3,4,3,3,0,3,3,1,4,4,3,4,4,4,3,4,5,5,3,2,3,1,1,3,3,1,3,1,1,3,3,2,4,5,3,3,5,0,4,0,3,0,4,4,3,5,3,3,0,3,4,0,4,3), +(0,5,0,5,0,3,0,2,0,4,4,3,5,2,4,3,3,3,4,4,4,3,5,3,5,3,3,1,4,0,4,3,3,0,3,3,0,4,4,4,4,5,4,3,3,5,5,3,2,3,1,2,3,2,0,1,0,0,3,2,2,4,4,3,1,5,0,4,0,3,0,4,3,1,3,2,1,0,3,3,0,3,3), +(0,4,0,5,0,5,0,4,0,4,5,5,5,3,4,3,3,2,5,4,4,3,5,3,5,3,4,0,4,3,4,4,3,2,4,4,3,4,5,4,4,5,5,0,3,5,5,4,1,3,3,2,3,3,1,3,1,0,4,3,1,4,4,3,4,5,0,4,0,2,0,4,3,4,4,3,3,0,4,0,0,5,5), +(0,4,0,4,0,5,0,1,1,3,3,4,4,3,4,1,3,0,5,1,3,0,3,1,3,1,1,0,3,0,3,3,4,0,4,3,0,4,4,4,3,4,4,0,3,5,4,1,0,3,0,0,2,3,0,3,1,0,3,1,0,3,2,1,3,5,0,3,0,1,0,3,2,3,3,4,4,0,2,2,0,4,4), +(2,4,0,5,0,4,0,3,0,4,5,5,4,3,5,3,5,3,5,3,5,2,5,3,4,3,3,4,3,4,5,3,2,1,5,4,3,2,3,4,5,3,4,1,2,5,4,3,0,3,3,0,3,2,0,2,3,0,4,1,0,3,4,3,3,5,0,3,0,1,0,4,5,5,5,4,3,0,4,2,0,3,5), +(0,5,0,4,0,4,0,2,0,5,4,3,4,3,4,3,3,3,4,3,4,2,5,3,5,3,4,1,4,3,4,4,4,0,3,5,0,4,4,4,4,5,3,1,3,4,5,3,3,3,3,3,3,3,0,2,2,0,3,3,2,4,3,3,3,5,3,4,1,3,3,5,3,2,0,0,0,0,4,3,1,3,3), +(0,1,0,3,0,3,0,1,0,1,3,3,3,2,3,3,3,0,3,0,0,0,3,1,3,0,0,0,2,2,2,3,0,0,3,2,0,1,2,4,1,3,3,0,0,3,3,3,0,1,0,0,2,1,0,0,3,0,3,1,0,3,0,0,1,3,0,2,0,1,0,3,3,1,3,3,0,0,1,1,0,3,3), +(0,2,0,3,0,2,1,4,0,2,2,3,1,1,3,1,1,0,2,0,3,1,2,3,1,3,0,0,1,0,4,3,2,3,3,3,1,4,2,3,3,3,3,1,0,3,1,4,0,1,1,0,1,2,0,1,1,0,1,1,0,3,1,3,2,2,0,1,0,0,0,2,3,3,3,1,0,0,0,0,0,2,3), +(0,5,0,4,0,5,0,2,0,4,5,5,3,3,4,3,3,1,5,4,4,2,4,4,4,3,4,2,4,3,5,5,4,3,3,4,3,3,5,5,4,5,5,1,3,4,5,3,1,4,3,1,3,3,0,3,3,1,4,3,1,4,5,3,3,5,0,4,0,3,0,5,3,3,1,4,3,0,4,0,1,5,3), +(0,5,0,5,0,4,0,2,0,4,4,3,4,3,3,3,3,3,5,4,4,4,4,4,4,5,3,3,5,2,4,4,4,3,4,4,3,3,4,4,5,5,3,3,4,3,4,3,3,4,3,3,3,3,1,2,2,1,4,3,3,5,4,4,3,4,0,4,0,3,0,4,4,4,4,4,1,0,4,2,0,2,4), +(0,4,0,4,0,3,0,1,0,3,5,2,3,0,3,0,2,1,4,2,3,3,4,1,4,3,3,2,4,1,3,3,3,0,3,3,0,0,3,3,3,5,3,3,3,3,3,2,0,2,0,0,2,0,0,2,0,0,1,0,0,3,1,2,2,3,0,3,0,2,0,4,4,3,3,4,1,0,3,0,0,2,4), +(0,0,0,4,0,0,0,0,0,0,1,0,1,0,2,0,0,0,0,0,1,0,2,0,1,0,0,0,0,0,3,1,3,0,3,2,0,0,0,1,0,3,2,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,4,0,2,0,0,0,0,0,0,2), +(0,2,1,3,0,2,0,2,0,3,3,3,3,1,3,1,3,3,3,3,3,3,4,2,2,1,2,1,4,0,4,3,1,3,3,3,2,4,3,5,4,3,3,3,3,3,3,3,0,1,3,0,2,0,0,1,0,0,1,0,0,4,2,0,2,3,0,3,3,0,3,3,4,2,3,1,4,0,1,2,0,2,3), +(0,3,0,3,0,1,0,3,0,2,3,3,3,0,3,1,2,0,3,3,2,3,3,2,3,2,3,1,3,0,4,3,2,0,3,3,1,4,3,3,2,3,4,3,1,3,3,1,1,0,1,1,0,1,0,1,0,1,0,0,0,4,1,1,0,3,0,3,1,0,2,3,3,3,3,3,1,0,0,2,0,3,3), +(0,0,0,0,0,0,0,0,0,0,3,0,2,0,3,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,3,0,3,0,3,1,0,1,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,2,0,2,3,0,0,0,0,0,0,0,0,3), +(0,2,0,3,1,3,0,3,0,2,3,3,3,1,3,1,3,1,3,1,3,3,3,1,3,0,2,3,1,1,4,3,3,2,3,3,1,2,2,4,1,3,3,0,1,4,2,3,0,1,3,0,3,0,0,1,3,0,2,0,0,3,3,2,1,3,0,3,0,2,0,3,4,4,4,3,1,0,3,0,0,3,3), +(0,2,0,1,0,2,0,0,0,1,3,2,2,1,3,0,1,1,3,0,3,2,3,1,2,0,2,0,1,1,3,3,3,0,3,3,1,1,2,3,2,3,3,1,2,3,2,0,0,1,0,0,0,0,0,0,3,0,1,0,0,2,1,2,1,3,0,3,0,0,0,3,4,4,4,3,2,0,2,0,0,2,4), +(0,0,0,1,0,1,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,2,2,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,3,1,0,0,0,0,0,0,0,3), +(0,3,0,3,0,2,0,3,0,3,3,3,2,3,2,2,2,0,3,1,3,3,3,2,3,3,0,0,3,0,3,2,2,0,2,3,1,4,3,4,3,3,2,3,1,5,4,4,0,3,1,2,1,3,0,3,1,1,2,0,2,3,1,3,1,3,0,3,0,1,0,3,3,4,4,2,1,0,2,1,0,2,4), +(0,1,0,3,0,1,0,2,0,1,4,2,5,1,4,0,2,0,2,1,3,1,4,0,2,1,0,0,2,1,4,1,1,0,3,3,0,5,1,3,2,3,3,1,0,3,2,3,0,1,0,0,0,0,0,0,1,0,0,0,0,4,0,1,0,3,0,2,0,1,0,3,3,3,4,3,3,0,0,0,0,2,3), +(0,0,0,1,0,0,0,0,0,0,2,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,1,0,0,1,0,0,0,0,0,3), +(0,1,0,3,0,4,0,3,0,2,4,3,1,0,3,2,2,1,3,1,2,2,3,1,1,1,2,1,3,0,1,2,0,1,3,2,1,3,0,5,5,1,0,0,1,3,2,1,0,3,0,0,1,0,0,0,0,0,3,4,0,1,1,1,3,2,0,2,0,1,0,2,3,3,1,2,3,0,1,0,1,0,4), +(0,0,0,1,0,3,0,3,0,2,2,1,0,0,4,0,3,0,3,1,3,0,3,0,3,0,1,0,3,0,3,1,3,0,3,3,0,0,1,2,1,1,1,0,1,2,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,2,2,1,2,0,0,2,0,0,0,0,2,3,3,3,3,0,0,0,0,1,4), +(0,0,0,3,0,3,0,0,0,0,3,1,1,0,3,0,1,0,2,0,1,0,0,0,0,0,0,0,1,0,3,0,2,0,2,3,0,0,2,2,3,1,2,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,2,0,0,0,0,2,3), +(2,4,0,5,0,5,0,4,0,3,4,3,3,3,4,3,3,3,4,3,4,4,5,4,5,5,5,2,3,0,5,5,4,1,5,4,3,1,5,4,3,4,4,3,3,4,3,3,0,3,2,0,2,3,0,3,0,0,3,3,0,5,3,2,3,3,0,3,0,3,0,3,4,5,4,5,3,0,4,3,0,3,4), +(0,3,0,3,0,3,0,3,0,3,3,4,3,2,3,2,3,0,4,3,3,3,3,3,3,3,3,0,3,2,4,3,3,1,3,4,3,4,4,4,3,4,4,3,2,4,4,1,0,2,0,0,1,1,0,2,0,0,3,1,0,5,3,2,1,3,0,3,0,1,2,4,3,2,4,3,3,0,3,2,0,4,4), +(0,3,0,3,0,1,0,0,0,1,4,3,3,2,3,1,3,1,4,2,3,2,4,2,3,4,3,0,2,2,3,3,3,0,3,3,3,0,3,4,1,3,3,0,3,4,3,3,0,1,1,0,1,0,0,0,4,0,3,0,0,3,1,2,1,3,0,4,0,1,0,4,3,3,4,3,3,0,2,0,0,3,3), +(0,3,0,4,0,1,0,3,0,3,4,3,3,0,3,3,3,1,3,1,3,3,4,3,3,3,0,0,3,1,5,3,3,1,3,3,2,5,4,3,3,4,5,3,2,5,3,4,0,1,0,0,0,0,0,2,0,0,1,1,0,4,2,2,1,3,0,3,0,2,0,4,4,3,5,3,2,0,1,1,0,3,4), +(0,5,0,4,0,5,0,2,0,4,4,3,3,2,3,3,3,1,4,3,4,1,5,3,4,3,4,0,4,2,4,3,4,1,5,4,0,4,4,4,4,5,4,1,3,5,4,2,1,4,1,1,3,2,0,3,1,0,3,2,1,4,3,3,3,4,0,4,0,3,0,4,4,4,3,3,3,0,4,2,0,3,4), +(1,4,0,4,0,3,0,1,0,3,3,3,1,1,3,3,2,2,3,3,1,0,3,2,2,1,2,0,3,1,2,1,2,0,3,2,0,2,2,3,3,4,3,0,3,3,1,2,0,1,1,3,1,2,0,0,3,0,1,1,0,3,2,2,3,3,0,3,0,0,0,2,3,3,4,3,3,0,1,0,0,1,4), +(0,4,0,4,0,4,0,0,0,3,4,4,3,1,4,2,3,2,3,3,3,1,4,3,4,0,3,0,4,2,3,3,2,2,5,4,2,1,3,4,3,4,3,1,3,3,4,2,0,2,1,0,3,3,0,0,2,0,3,1,0,4,4,3,4,3,0,4,0,1,0,2,4,4,4,4,4,0,3,2,0,3,3), +(0,0,0,1,0,4,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,3,2,0,0,1,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,2), +(0,2,0,3,0,4,0,4,0,1,3,3,3,0,4,0,2,1,2,1,1,1,2,0,3,1,1,0,1,0,3,1,0,0,3,3,2,0,1,1,0,0,0,0,0,1,0,2,0,2,2,0,3,1,0,0,1,0,1,1,0,1,2,0,3,0,0,0,0,1,0,0,3,3,4,3,1,0,1,0,3,0,2), +(0,0,0,3,0,5,0,0,0,0,1,0,2,0,3,1,0,1,3,0,0,0,2,0,0,0,1,0,0,0,1,1,0,0,4,0,0,0,2,3,0,1,4,1,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,1,0,0,0,0,0,0,0,2,0,0,3,0,0,0,0,0,3), +(0,2,0,5,0,5,0,1,0,2,4,3,3,2,5,1,3,2,3,3,3,0,4,1,2,0,3,0,4,0,2,2,1,1,5,3,0,0,1,4,2,3,2,0,3,3,3,2,0,2,4,1,1,2,0,1,1,0,3,1,0,1,3,1,2,3,0,2,0,0,0,1,3,5,4,4,4,0,3,0,0,1,3), +(0,4,0,5,0,4,0,4,0,4,5,4,3,3,4,3,3,3,4,3,4,4,5,3,4,5,4,2,4,2,3,4,3,1,4,4,1,3,5,4,4,5,5,4,4,5,5,5,2,3,3,1,4,3,1,3,3,0,3,3,1,4,3,4,4,4,0,3,0,4,0,3,3,4,4,5,0,0,4,3,0,4,5), +(0,4,0,4,0,3,0,3,0,3,4,4,4,3,3,2,4,3,4,3,4,3,5,3,4,3,2,1,4,2,4,4,3,1,3,4,2,4,5,5,3,4,5,4,1,5,4,3,0,3,2,2,3,2,1,3,1,0,3,3,3,5,3,3,3,5,4,4,2,3,3,4,3,3,3,2,1,0,3,2,1,4,3), +(0,4,0,5,0,4,0,3,0,3,5,5,3,2,4,3,4,0,5,4,4,1,4,4,4,3,3,3,4,3,5,5,2,3,3,4,1,2,5,5,3,5,5,2,3,5,5,4,0,3,2,0,3,3,1,1,5,1,4,1,0,4,3,2,3,5,0,4,0,3,0,5,4,3,4,3,0,0,4,1,0,4,4), +(1,3,0,4,0,2,0,2,0,2,5,5,3,3,3,3,3,0,4,2,3,4,4,4,3,4,0,0,3,4,5,4,3,3,3,3,2,5,5,4,5,5,5,4,3,5,5,5,1,3,1,0,1,0,0,3,2,0,4,2,0,5,2,3,2,4,1,3,0,3,0,4,5,4,5,4,3,0,4,2,0,5,4), +(0,3,0,4,0,5,0,3,0,3,4,4,3,2,3,2,3,3,3,3,3,2,4,3,3,2,2,0,3,3,3,3,3,1,3,3,3,0,4,4,3,4,4,1,1,4,4,2,0,3,1,0,1,1,0,4,1,0,2,3,1,3,3,1,3,4,0,3,0,1,0,3,1,3,0,0,1,0,2,0,0,4,4), +(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), +(0,3,0,3,0,2,0,3,0,1,5,4,3,3,3,1,4,2,1,2,3,4,4,2,4,4,5,0,3,1,4,3,4,0,4,3,3,3,2,3,2,5,3,4,3,2,2,3,0,0,3,0,2,1,0,1,2,0,0,0,0,2,1,1,3,1,0,2,0,4,0,3,4,4,4,5,2,0,2,0,0,1,3), +(0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1,1,0,0,1,1,0,0,0,4,2,1,1,0,1,0,3,2,0,0,3,1,1,1,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,1,0,0,0,2,0,0,0,1,4,0,4,2,1,0,0,0,0,0,1), +(0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,1,0,0,0,0,0,0,1,0,1,0,0,0,0,3,1,0,0,0,2,0,2,1,0,0,1,2,1,0,1,1,0,0,3,0,0,0,0,0,0,0,0,0,0,0,1,3,1,0,0,0,0,0,1,0,0,2,1,0,0,0,0,0,0,0,0,2), +(0,4,0,4,0,4,0,3,0,4,4,3,4,2,4,3,2,0,4,4,4,3,5,3,5,3,3,2,4,2,4,3,4,3,1,4,0,2,3,4,4,4,3,3,3,4,4,4,3,4,1,3,4,3,2,1,2,1,3,3,3,4,4,3,3,5,0,4,0,3,0,4,3,3,3,2,1,0,3,0,0,3,3), +(0,4,0,3,0,3,0,3,0,3,5,5,3,3,3,3,4,3,4,3,3,3,4,4,4,3,3,3,3,4,3,5,3,3,1,3,2,4,5,5,5,5,4,3,4,5,5,3,2,2,3,3,3,3,2,3,3,1,2,3,2,4,3,3,3,4,0,4,0,2,0,4,3,2,2,1,2,0,3,0,0,4,1), +) + +class JapaneseContextAnalysis(object): + NUM_OF_CATEGORY = 6 + DONT_KNOW = -1 + ENOUGH_REL_THRESHOLD = 100 + MAX_REL_THRESHOLD = 1000 + MINIMUM_DATA_THRESHOLD = 4 + + def __init__(self): + self._total_rel = None + self._rel_sample = None + self._need_to_skip_char_num = None + self._last_char_order = None + self._done = None + self.reset() + + def reset(self): + self._total_rel = 0 # total sequence received + # category counters, each integer counts sequence in its category + self._rel_sample = [0] * self.NUM_OF_CATEGORY + # if last byte in current buffer is not the last byte of a character, + # we need to know how many bytes to skip in next buffer + self._need_to_skip_char_num = 0 + self._last_char_order = -1 # The order of previous char + # If this flag is set to True, detection is done and conclusion has + # been made + self._done = False + + def feed(self, byte_str, num_bytes): + if self._done: + return + + # The buffer we got is byte oriented, and a character may span in more than one + # buffers. In case the last one or two byte in last buffer is not + # complete, we record how many byte needed to complete that character + # and skip these bytes here. We can choose to record those bytes as + # well and analyse the character once it is complete, but since a + # character will not make much difference, by simply skipping + # this character will simply our logic and improve performance. + i = self._need_to_skip_char_num + while i < num_bytes: + order, char_len = self.get_order(byte_str[i:i + 2]) + i += char_len + if i > num_bytes: + self._need_to_skip_char_num = i - num_bytes + self._last_char_order = -1 + else: + if (order != -1) and (self._last_char_order != -1): + self._total_rel += 1 + if self._total_rel > self.MAX_REL_THRESHOLD: + self._done = True + break + self._rel_sample[jp2CharContext[self._last_char_order][order]] += 1 + self._last_char_order = order + + def got_enough_data(self): + return self._total_rel > self.ENOUGH_REL_THRESHOLD + + def get_confidence(self): + # This is just one way to calculate confidence. It works well for me. + if self._total_rel > self.MINIMUM_DATA_THRESHOLD: + return (self._total_rel - self._rel_sample[0]) / self._total_rel + else: + return self.DONT_KNOW + + def get_order(self, byte_str): + return -1, 1 + +class SJISContextAnalysis(JapaneseContextAnalysis): + def __init__(self): + super(SJISContextAnalysis, self).__init__() + self._charset_name = "SHIFT_JIS" + + @property + def charset_name(self): + return self._charset_name + + def get_order(self, byte_str): + if not byte_str: + return -1, 1 + # find out current char's byte length + first_char = byte_str[0] + if (0x81 <= first_char <= 0x9F) or (0xE0 <= first_char <= 0xFC): + char_len = 2 + if (first_char == 0x87) or (0xFA <= first_char <= 0xFC): + self._charset_name = "CP932" + else: + char_len = 1 + + # return its order if it is hiragana + if len(byte_str) > 1: + second_char = byte_str[1] + if (first_char == 202) and (0x9F <= second_char <= 0xF1): + return second_char - 0x9F, char_len + + return -1, char_len + +class EUCJPContextAnalysis(JapaneseContextAnalysis): + def get_order(self, byte_str): + if not byte_str: + return -1, 1 + # find out current char's byte length + first_char = byte_str[0] + if (first_char == 0x8E) or (0xA1 <= first_char <= 0xFE): + char_len = 2 + elif first_char == 0x8F: + char_len = 3 + else: + char_len = 1 + + # return its order if it is hiragana + if len(byte_str) > 1: + second_char = byte_str[1] + if (first_char == 0xA4) and (0xA1 <= second_char <= 0xF3): + return second_char - 0xA1, char_len + + return -1, char_len + + diff --git a/venv/Lib/site-packages/pip/_vendor/chardet/langbulgarianmodel.py b/venv/Lib/site-packages/pip/_vendor/chardet/langbulgarianmodel.py new file mode 100644 index 0000000..e963a50 --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/chardet/langbulgarianmodel.py @@ -0,0 +1,4650 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from pip._vendor.chardet.sbcharsetprober import SingleByteCharSetModel + + +# 3: Positive +# 2: Likely +# 1: Unlikely +# 0: Negative + +BULGARIAN_LANG_MODEL = { + 63: { # 'e' + 63: 1, # 'e' + 45: 0, # '\xad' + 31: 0, # 'Ð' + 32: 0, # 'Б' + 35: 0, # 'Ð’' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Ð' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Ð¥' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 0, # 'а' + 18: 1, # 'б' + 9: 1, # 'в' + 20: 1, # 'г' + 11: 1, # 'д' + 3: 1, # 'е' + 23: 1, # 'ж' + 15: 1, # 'з' + 2: 0, # 'и' + 26: 1, # 'й' + 12: 1, # 'к' + 10: 1, # 'л' + 14: 1, # 'м' + 6: 1, # 'н' + 4: 1, # 'о' + 13: 1, # 'п' + 7: 1, # 'Ñ€' + 8: 1, # 'Ñ' + 5: 1, # 'Ñ‚' + 19: 0, # 'у' + 29: 1, # 'Ñ„' + 25: 1, # 'Ñ…' + 22: 0, # 'ц' + 21: 1, # 'ч' + 27: 1, # 'ш' + 24: 1, # 'щ' + 17: 0, # 'ÑŠ' + 52: 0, # 'ÑŒ' + 42: 0, # 'ÑŽ' + 16: 1, # 'Ñ' + 58: 0, # 'Ñ”' + 62: 0, # 'â„–' + }, + 45: { # '\xad' + 63: 0, # 'e' + 45: 0, # '\xad' + 31: 0, # 'Ð' + 32: 1, # 'Б' + 35: 1, # 'Ð’' + 43: 0, # 'Г' + 37: 1, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 1, # 'И' + 59: 0, # 'Й' + 33: 1, # 'К' + 46: 0, # 'Л' + 38: 1, # 'М' + 36: 0, # 'Ð' + 41: 1, # 'О' + 30: 1, # 'П' + 39: 1, # 'Р' + 28: 1, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 1, # 'Ð¥' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 0, # 'а' + 18: 0, # 'б' + 9: 0, # 'в' + 20: 0, # 'г' + 11: 0, # 'д' + 3: 0, # 'е' + 23: 0, # 'ж' + 15: 0, # 'з' + 2: 0, # 'и' + 26: 0, # 'й' + 12: 0, # 'к' + 10: 0, # 'л' + 14: 0, # 'м' + 6: 0, # 'н' + 4: 0, # 'о' + 13: 0, # 'п' + 7: 0, # 'Ñ€' + 8: 0, # 'Ñ' + 5: 0, # 'Ñ‚' + 19: 0, # 'у' + 29: 0, # 'Ñ„' + 25: 0, # 'Ñ…' + 22: 0, # 'ц' + 21: 0, # 'ч' + 27: 0, # 'ш' + 24: 0, # 'щ' + 17: 0, # 'ÑŠ' + 52: 0, # 'ÑŒ' + 42: 0, # 'ÑŽ' + 16: 0, # 'Ñ' + 58: 0, # 'Ñ”' + 62: 0, # 'â„–' + }, + 31: { # 'Ð' + 63: 0, # 'e' + 45: 1, # '\xad' + 31: 1, # 'Ð' + 32: 1, # 'Б' + 35: 2, # 'Ð’' + 43: 1, # 'Г' + 37: 2, # 'Д' + 44: 2, # 'Е' + 55: 1, # 'Ж' + 47: 2, # 'З' + 40: 1, # 'И' + 59: 1, # 'Й' + 33: 1, # 'К' + 46: 2, # 'Л' + 38: 1, # 'М' + 36: 2, # 'Ð' + 41: 1, # 'О' + 30: 2, # 'П' + 39: 2, # 'Р' + 28: 2, # 'С' + 34: 2, # 'Т' + 51: 1, # 'У' + 48: 2, # 'Ф' + 49: 1, # 'Ð¥' + 53: 1, # 'Ц' + 50: 1, # 'Ч' + 54: 1, # 'Ш' + 57: 2, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 1, # 'Я' + 1: 1, # 'а' + 18: 2, # 'б' + 9: 2, # 'в' + 20: 2, # 'г' + 11: 2, # 'д' + 3: 1, # 'е' + 23: 1, # 'ж' + 15: 2, # 'з' + 2: 0, # 'и' + 26: 2, # 'й' + 12: 2, # 'к' + 10: 3, # 'л' + 14: 2, # 'м' + 6: 3, # 'н' + 4: 0, # 'о' + 13: 2, # 'п' + 7: 2, # 'Ñ€' + 8: 2, # 'Ñ' + 5: 2, # 'Ñ‚' + 19: 1, # 'у' + 29: 2, # 'Ñ„' + 25: 1, # 'Ñ…' + 22: 1, # 'ц' + 21: 1, # 'ч' + 27: 1, # 'ш' + 24: 0, # 'щ' + 17: 0, # 'ÑŠ' + 52: 0, # 'ÑŒ' + 42: 0, # 'ÑŽ' + 16: 1, # 'Ñ' + 58: 0, # 'Ñ”' + 62: 0, # 'â„–' + }, + 32: { # 'Б' + 63: 0, # 'e' + 45: 0, # '\xad' + 31: 2, # 'Ð' + 32: 2, # 'Б' + 35: 1, # 'Ð’' + 43: 1, # 'Г' + 37: 2, # 'Д' + 44: 1, # 'Е' + 55: 1, # 'Ж' + 47: 2, # 'З' + 40: 1, # 'И' + 59: 0, # 'Й' + 33: 1, # 'К' + 46: 1, # 'Л' + 38: 1, # 'М' + 36: 2, # 'Ð' + 41: 2, # 'О' + 30: 1, # 'П' + 39: 1, # 'Р' + 28: 2, # 'С' + 34: 2, # 'Т' + 51: 1, # 'У' + 48: 2, # 'Ф' + 49: 1, # 'Ð¥' + 53: 1, # 'Ц' + 50: 1, # 'Ч' + 54: 0, # 'Ш' + 57: 1, # 'Щ' + 61: 2, # 'Ъ' + 60: 1, # 'Ю' + 56: 1, # 'Я' + 1: 3, # 'а' + 18: 0, # 'б' + 9: 0, # 'в' + 20: 0, # 'г' + 11: 1, # 'д' + 3: 3, # 'е' + 23: 0, # 'ж' + 15: 0, # 'з' + 2: 2, # 'и' + 26: 0, # 'й' + 12: 0, # 'к' + 10: 2, # 'л' + 14: 0, # 'м' + 6: 0, # 'н' + 4: 3, # 'о' + 13: 0, # 'п' + 7: 2, # 'Ñ€' + 8: 1, # 'Ñ' + 5: 0, # 'Ñ‚' + 19: 2, # 'у' + 29: 0, # 'Ñ„' + 25: 1, # 'Ñ…' + 22: 0, # 'ц' + 21: 0, # 'ч' + 27: 0, # 'ш' + 24: 0, # 'щ' + 17: 3, # 'ÑŠ' + 52: 1, # 'ÑŒ' + 42: 1, # 'ÑŽ' + 16: 2, # 'Ñ' + 58: 0, # 'Ñ”' + 62: 0, # 'â„–' + }, + 35: { # 'Ð’' + 63: 0, # 'e' + 45: 0, # '\xad' + 31: 2, # 'Ð' + 32: 1, # 'Б' + 35: 1, # 'Ð’' + 43: 0, # 'Г' + 37: 1, # 'Д' + 44: 2, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 2, # 'И' + 59: 0, # 'Й' + 33: 1, # 'К' + 46: 1, # 'Л' + 38: 1, # 'М' + 36: 1, # 'Ð' + 41: 1, # 'О' + 30: 1, # 'П' + 39: 2, # 'Р' + 28: 2, # 'С' + 34: 1, # 'Т' + 51: 1, # 'У' + 48: 2, # 'Ф' + 49: 0, # 'Ð¥' + 53: 1, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 1, # 'Ъ' + 60: 1, # 'Ю' + 56: 2, # 'Я' + 1: 3, # 'а' + 18: 1, # 'б' + 9: 0, # 'в' + 20: 0, # 'г' + 11: 1, # 'д' + 3: 3, # 'е' + 23: 1, # 'ж' + 15: 2, # 'з' + 2: 3, # 'и' + 26: 0, # 'й' + 12: 1, # 'к' + 10: 2, # 'л' + 14: 1, # 'м' + 6: 2, # 'н' + 4: 2, # 'о' + 13: 1, # 'п' + 7: 2, # 'Ñ€' + 8: 2, # 'Ñ' + 5: 2, # 'Ñ‚' + 19: 1, # 'у' + 29: 0, # 'Ñ„' + 25: 1, # 'Ñ…' + 22: 0, # 'ц' + 21: 2, # 'ч' + 27: 0, # 'ш' + 24: 0, # 'щ' + 17: 2, # 'ÑŠ' + 52: 1, # 'ÑŒ' + 42: 1, # 'ÑŽ' + 16: 1, # 'Ñ' + 58: 0, # 'Ñ”' + 62: 0, # 'â„–' + }, + 43: { # 'Г' + 63: 0, # 'e' + 45: 0, # '\xad' + 31: 2, # 'Ð' + 32: 1, # 'Б' + 35: 0, # 'Ð’' + 43: 0, # 'Г' + 37: 1, # 'Д' + 44: 2, # 'Е' + 55: 0, # 'Ж' + 47: 1, # 'З' + 40: 1, # 'И' + 59: 0, # 'Й' + 33: 1, # 'К' + 46: 1, # 'Л' + 38: 0, # 'М' + 36: 1, # 'Ð' + 41: 1, # 'О' + 30: 0, # 'П' + 39: 1, # 'Р' + 28: 1, # 'С' + 34: 0, # 'Т' + 51: 1, # 'У' + 48: 1, # 'Ф' + 49: 0, # 'Ð¥' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 1, # 'Щ' + 61: 1, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 2, # 'а' + 18: 1, # 'б' + 9: 1, # 'в' + 20: 0, # 'г' + 11: 1, # 'д' + 3: 3, # 'е' + 23: 1, # 'ж' + 15: 0, # 'з' + 2: 2, # 'и' + 26: 0, # 'й' + 12: 1, # 'к' + 10: 2, # 'л' + 14: 1, # 'м' + 6: 1, # 'н' + 4: 2, # 'о' + 13: 0, # 'п' + 7: 2, # 'Ñ€' + 8: 0, # 'Ñ' + 5: 0, # 'Ñ‚' + 19: 2, # 'у' + 29: 0, # 'Ñ„' + 25: 0, # 'Ñ…' + 22: 0, # 'ц' + 21: 0, # 'ч' + 27: 0, # 'ш' + 24: 1, # 'щ' + 17: 2, # 'ÑŠ' + 52: 1, # 'ÑŒ' + 42: 1, # 'ÑŽ' + 16: 1, # 'Ñ' + 58: 0, # 'Ñ”' + 62: 0, # 'â„–' + }, + 37: { # 'Д' + 63: 0, # 'e' + 45: 0, # '\xad' + 31: 2, # 'Ð' + 32: 1, # 'Б' + 35: 2, # 'Ð’' + 43: 1, # 'Г' + 37: 2, # 'Д' + 44: 2, # 'Е' + 55: 2, # 'Ж' + 47: 1, # 'З' + 40: 2, # 'И' + 59: 0, # 'Й' + 33: 1, # 'К' + 46: 1, # 'Л' + 38: 1, # 'М' + 36: 1, # 'Ð' + 41: 2, # 'О' + 30: 2, # 'П' + 39: 1, # 'Р' + 28: 2, # 'С' + 34: 1, # 'Т' + 51: 1, # 'У' + 48: 1, # 'Ф' + 49: 0, # 'Ð¥' + 53: 1, # 'Ц' + 50: 1, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 1, # 'Ъ' + 60: 1, # 'Ю' + 56: 1, # 'Я' + 1: 3, # 'а' + 18: 0, # 'б' + 9: 2, # 'в' + 20: 0, # 'г' + 11: 0, # 'д' + 3: 3, # 'е' + 23: 3, # 'ж' + 15: 1, # 'з' + 2: 3, # 'и' + 26: 0, # 'й' + 12: 0, # 'к' + 10: 1, # 'л' + 14: 1, # 'м' + 6: 2, # 'н' + 4: 3, # 'о' + 13: 0, # 'п' + 7: 2, # 'Ñ€' + 8: 0, # 'Ñ' + 5: 0, # 'Ñ‚' + 19: 2, # 'у' + 29: 0, # 'Ñ„' + 25: 0, # 'Ñ…' + 22: 0, # 'ц' + 21: 0, # 'ч' + 27: 0, # 'ш' + 24: 0, # 'щ' + 17: 2, # 'ÑŠ' + 52: 1, # 'ÑŒ' + 42: 2, # 'ÑŽ' + 16: 1, # 'Ñ' + 58: 0, # 'Ñ”' + 62: 0, # 'â„–' + }, + 44: { # 'Е' + 63: 0, # 'e' + 45: 0, # '\xad' + 31: 1, # 'Ð' + 32: 1, # 'Б' + 35: 2, # 'Ð’' + 43: 1, # 'Г' + 37: 1, # 'Д' + 44: 1, # 'Е' + 55: 1, # 'Ж' + 47: 1, # 'З' + 40: 1, # 'И' + 59: 1, # 'Й' + 33: 2, # 'К' + 46: 2, # 'Л' + 38: 1, # 'М' + 36: 2, # 'Ð' + 41: 2, # 'О' + 30: 1, # 'П' + 39: 2, # 'Р' + 28: 2, # 'С' + 34: 2, # 'Т' + 51: 1, # 'У' + 48: 2, # 'Ф' + 49: 1, # 'Ð¥' + 53: 2, # 'Ц' + 50: 1, # 'Ч' + 54: 1, # 'Ш' + 57: 1, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 1, # 'Я' + 1: 0, # 'а' + 18: 1, # 'б' + 9: 2, # 'в' + 20: 1, # 'г' + 11: 2, # 'д' + 3: 0, # 'е' + 23: 1, # 'ж' + 15: 1, # 'з' + 2: 0, # 'и' + 26: 1, # 'й' + 12: 2, # 'к' + 10: 2, # 'л' + 14: 2, # 'м' + 6: 2, # 'н' + 4: 0, # 'о' + 13: 1, # 'п' + 7: 2, # 'Ñ€' + 8: 2, # 'Ñ' + 5: 1, # 'Ñ‚' + 19: 1, # 'у' + 29: 1, # 'Ñ„' + 25: 1, # 'Ñ…' + 22: 0, # 'ц' + 21: 1, # 'ч' + 27: 1, # 'ш' + 24: 1, # 'щ' + 17: 1, # 'ÑŠ' + 52: 0, # 'ÑŒ' + 42: 1, # 'ÑŽ' + 16: 1, # 'Ñ' + 58: 0, # 'Ñ”' + 62: 0, # 'â„–' + }, + 55: { # 'Ж' + 63: 0, # 'e' + 45: 0, # '\xad' + 31: 1, # 'Ð' + 32: 0, # 'Б' + 35: 1, # 'Ð’' + 43: 0, # 'Г' + 37: 1, # 'Д' + 44: 1, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 1, # 'И' + 59: 0, # 'Й' + 33: 1, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 1, # 'Ð' + 41: 1, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 1, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Ð¥' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 2, # 'а' + 18: 0, # 'б' + 9: 0, # 'в' + 20: 0, # 'г' + 11: 1, # 'д' + 3: 2, # 'е' + 23: 0, # 'ж' + 15: 0, # 'з' + 2: 2, # 'и' + 26: 0, # 'й' + 12: 0, # 'к' + 10: 0, # 'л' + 14: 0, # 'м' + 6: 0, # 'н' + 4: 2, # 'о' + 13: 1, # 'п' + 7: 1, # 'Ñ€' + 8: 0, # 'Ñ' + 5: 0, # 'Ñ‚' + 19: 1, # 'у' + 29: 0, # 'Ñ„' + 25: 0, # 'Ñ…' + 22: 0, # 'ц' + 21: 0, # 'ч' + 27: 0, # 'ш' + 24: 0, # 'щ' + 17: 1, # 'ÑŠ' + 52: 1, # 'ÑŒ' + 42: 1, # 'ÑŽ' + 16: 0, # 'Ñ' + 58: 0, # 'Ñ”' + 62: 0, # 'â„–' + }, + 47: { # 'З' + 63: 0, # 'e' + 45: 0, # '\xad' + 31: 2, # 'Ð' + 32: 1, # 'Б' + 35: 1, # 'Ð’' + 43: 1, # 'Г' + 37: 1, # 'Д' + 44: 1, # 'Е' + 55: 0, # 'Ж' + 47: 1, # 'З' + 40: 1, # 'И' + 59: 0, # 'Й' + 33: 1, # 'К' + 46: 1, # 'Л' + 38: 1, # 'М' + 36: 2, # 'Ð' + 41: 1, # 'О' + 30: 1, # 'П' + 39: 1, # 'Р' + 28: 1, # 'С' + 34: 1, # 'Т' + 51: 1, # 'У' + 48: 0, # 'Ф' + 49: 1, # 'Ð¥' + 53: 1, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 1, # 'Ъ' + 60: 0, # 'Ю' + 56: 1, # 'Я' + 1: 3, # 'а' + 18: 1, # 'б' + 9: 2, # 'в' + 20: 1, # 'г' + 11: 2, # 'д' + 3: 2, # 'е' + 23: 0, # 'ж' + 15: 0, # 'з' + 2: 1, # 'и' + 26: 0, # 'й' + 12: 0, # 'к' + 10: 2, # 'л' + 14: 1, # 'м' + 6: 1, # 'н' + 4: 1, # 'о' + 13: 0, # 'п' + 7: 1, # 'Ñ€' + 8: 0, # 'Ñ' + 5: 0, # 'Ñ‚' + 19: 1, # 'у' + 29: 0, # 'Ñ„' + 25: 0, # 'Ñ…' + 22: 0, # 'ц' + 21: 0, # 'ч' + 27: 0, # 'ш' + 24: 0, # 'щ' + 17: 1, # 'ÑŠ' + 52: 0, # 'ÑŒ' + 42: 1, # 'ÑŽ' + 16: 0, # 'Ñ' + 58: 0, # 'Ñ”' + 62: 0, # 'â„–' + }, + 40: { # 'И' + 63: 0, # 'e' + 45: 1, # '\xad' + 31: 1, # 'Ð' + 32: 1, # 'Б' + 35: 1, # 'Ð’' + 43: 1, # 'Г' + 37: 1, # 'Д' + 44: 2, # 'Е' + 55: 1, # 'Ж' + 47: 2, # 'З' + 40: 1, # 'И' + 59: 1, # 'Й' + 33: 2, # 'К' + 46: 2, # 'Л' + 38: 2, # 'М' + 36: 2, # 'Ð' + 41: 1, # 'О' + 30: 1, # 'П' + 39: 2, # 'Р' + 28: 2, # 'С' + 34: 2, # 'Т' + 51: 0, # 'У' + 48: 1, # 'Ф' + 49: 1, # 'Ð¥' + 53: 1, # 'Ц' + 50: 1, # 'Ч' + 54: 1, # 'Ш' + 57: 1, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 2, # 'Я' + 1: 1, # 'а' + 18: 1, # 'б' + 9: 3, # 'в' + 20: 2, # 'г' + 11: 1, # 'д' + 3: 1, # 'е' + 23: 0, # 'ж' + 15: 3, # 'з' + 2: 0, # 'и' + 26: 1, # 'й' + 12: 1, # 'к' + 10: 2, # 'л' + 14: 2, # 'м' + 6: 2, # 'н' + 4: 0, # 'о' + 13: 1, # 'п' + 7: 2, # 'Ñ€' + 8: 2, # 'Ñ' + 5: 2, # 'Ñ‚' + 19: 0, # 'у' + 29: 1, # 'Ñ„' + 25: 1, # 'Ñ…' + 22: 1, # 'ц' + 21: 1, # 'ч' + 27: 1, # 'ш' + 24: 1, # 'щ' + 17: 0, # 'ÑŠ' + 52: 0, # 'ÑŒ' + 42: 0, # 'ÑŽ' + 16: 0, # 'Ñ' + 58: 0, # 'Ñ”' + 62: 0, # 'â„–' + }, + 59: { # 'Й' + 63: 0, # 'e' + 45: 0, # '\xad' + 31: 0, # 'Ð' + 32: 0, # 'Б' + 35: 0, # 'Ð’' + 43: 0, # 'Г' + 37: 1, # 'Д' + 44: 1, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 1, # 'К' + 46: 1, # 'Л' + 38: 1, # 'М' + 36: 1, # 'Ð' + 41: 1, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 1, # 'С' + 34: 1, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Ð¥' + 53: 0, # 'Ц' + 50: 1, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 1, # 'Я' + 1: 0, # 'а' + 18: 0, # 'б' + 9: 0, # 'в' + 20: 0, # 'г' + 11: 0, # 'д' + 3: 1, # 'е' + 23: 0, # 'ж' + 15: 0, # 'з' + 2: 0, # 'и' + 26: 0, # 'й' + 12: 0, # 'к' + 10: 0, # 'л' + 14: 0, # 'м' + 6: 0, # 'н' + 4: 2, # 'о' + 13: 0, # 'п' + 7: 0, # 'Ñ€' + 8: 0, # 'Ñ' + 5: 0, # 'Ñ‚' + 19: 0, # 'у' + 29: 0, # 'Ñ„' + 25: 0, # 'Ñ…' + 22: 0, # 'ц' + 21: 0, # 'ч' + 27: 0, # 'ш' + 24: 0, # 'щ' + 17: 1, # 'ÑŠ' + 52: 0, # 'ÑŒ' + 42: 0, # 'ÑŽ' + 16: 0, # 'Ñ' + 58: 0, # 'Ñ”' + 62: 0, # 'â„–' + }, + 33: { # 'К' + 63: 0, # 'e' + 45: 1, # '\xad' + 31: 2, # 'Ð' + 32: 1, # 'Б' + 35: 1, # 'Ð’' + 43: 1, # 'Г' + 37: 1, # 'Д' + 44: 1, # 'Е' + 55: 0, # 'Ж' + 47: 1, # 'З' + 40: 2, # 'И' + 59: 0, # 'Й' + 33: 1, # 'К' + 46: 1, # 'Л' + 38: 0, # 'М' + 36: 2, # 'Ð' + 41: 2, # 'О' + 30: 2, # 'П' + 39: 1, # 'Р' + 28: 2, # 'С' + 34: 1, # 'Т' + 51: 1, # 'У' + 48: 1, # 'Ф' + 49: 1, # 'Ð¥' + 53: 1, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 1, # 'Ъ' + 60: 1, # 'Ю' + 56: 0, # 'Я' + 1: 3, # 'а' + 18: 0, # 'б' + 9: 1, # 'в' + 20: 0, # 'г' + 11: 0, # 'д' + 3: 2, # 'е' + 23: 1, # 'ж' + 15: 0, # 'з' + 2: 2, # 'и' + 26: 0, # 'й' + 12: 0, # 'к' + 10: 2, # 'л' + 14: 1, # 'м' + 6: 2, # 'н' + 4: 3, # 'о' + 13: 0, # 'п' + 7: 3, # 'Ñ€' + 8: 1, # 'Ñ' + 5: 0, # 'Ñ‚' + 19: 2, # 'у' + 29: 0, # 'Ñ„' + 25: 1, # 'Ñ…' + 22: 0, # 'ц' + 21: 0, # 'ч' + 27: 1, # 'ш' + 24: 0, # 'щ' + 17: 2, # 'ÑŠ' + 52: 1, # 'ÑŒ' + 42: 2, # 'ÑŽ' + 16: 0, # 'Ñ' + 58: 0, # 'Ñ”' + 62: 0, # 'â„–' + }, + 46: { # 'Л' + 63: 1, # 'e' + 45: 0, # '\xad' + 31: 2, # 'Ð' + 32: 1, # 'Б' + 35: 1, # 'Ð’' + 43: 2, # 'Г' + 37: 1, # 'Д' + 44: 2, # 'Е' + 55: 0, # 'Ж' + 47: 1, # 'З' + 40: 2, # 'И' + 59: 0, # 'Й' + 33: 1, # 'К' + 46: 1, # 'Л' + 38: 0, # 'М' + 36: 1, # 'Ð' + 41: 2, # 'О' + 30: 1, # 'П' + 39: 0, # 'Р' + 28: 1, # 'С' + 34: 1, # 'Т' + 51: 1, # 'У' + 48: 0, # 'Ф' + 49: 1, # 'Ð¥' + 53: 1, # 'Ц' + 50: 1, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 1, # 'Ъ' + 60: 1, # 'Ю' + 56: 1, # 'Я' + 1: 2, # 'а' + 18: 0, # 'б' + 9: 1, # 'в' + 20: 0, # 'г' + 11: 0, # 'д' + 3: 3, # 'е' + 23: 0, # 'ж' + 15: 0, # 'з' + 2: 2, # 'и' + 26: 0, # 'й' + 12: 0, # 'к' + 10: 0, # 'л' + 14: 0, # 'м' + 6: 0, # 'н' + 4: 2, # 'о' + 13: 0, # 'п' + 7: 0, # 'Ñ€' + 8: 0, # 'Ñ' + 5: 0, # 'Ñ‚' + 19: 2, # 'у' + 29: 0, # 'Ñ„' + 25: 0, # 'Ñ…' + 22: 0, # 'ц' + 21: 0, # 'ч' + 27: 0, # 'ш' + 24: 0, # 'щ' + 17: 1, # 'ÑŠ' + 52: 1, # 'ÑŒ' + 42: 2, # 'ÑŽ' + 16: 1, # 'Ñ' + 58: 0, # 'Ñ”' + 62: 0, # 'â„–' + }, + 38: { # 'М' + 63: 0, # 'e' + 45: 0, # '\xad' + 31: 2, # 'Ð' + 32: 1, # 'Б' + 35: 2, # 'Ð’' + 43: 0, # 'Г' + 37: 1, # 'Д' + 44: 1, # 'Е' + 55: 0, # 'Ж' + 47: 1, # 'З' + 40: 2, # 'И' + 59: 0, # 'Й' + 33: 1, # 'К' + 46: 1, # 'Л' + 38: 1, # 'М' + 36: 1, # 'Ð' + 41: 2, # 'О' + 30: 1, # 'П' + 39: 1, # 'Р' + 28: 2, # 'С' + 34: 1, # 'Т' + 51: 1, # 'У' + 48: 1, # 'Ф' + 49: 0, # 'Ð¥' + 53: 1, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 1, # 'Ъ' + 60: 0, # 'Ю' + 56: 1, # 'Я' + 1: 3, # 'а' + 18: 0, # 'б' + 9: 0, # 'в' + 20: 0, # 'г' + 11: 0, # 'д' + 3: 3, # 'е' + 23: 0, # 'ж' + 15: 0, # 'з' + 2: 3, # 'и' + 26: 0, # 'й' + 12: 0, # 'к' + 10: 2, # 'л' + 14: 0, # 'м' + 6: 2, # 'н' + 4: 3, # 'о' + 13: 0, # 'п' + 7: 1, # 'Ñ€' + 8: 0, # 'Ñ' + 5: 0, # 'Ñ‚' + 19: 2, # 'у' + 29: 0, # 'Ñ„' + 25: 0, # 'Ñ…' + 22: 0, # 'ц' + 21: 0, # 'ч' + 27: 0, # 'ш' + 24: 0, # 'щ' + 17: 2, # 'ÑŠ' + 52: 1, # 'ÑŒ' + 42: 2, # 'ÑŽ' + 16: 1, # 'Ñ' + 58: 0, # 'Ñ”' + 62: 0, # 'â„–' + }, + 36: { # 'Ð' + 63: 0, # 'e' + 45: 0, # '\xad' + 31: 2, # 'Ð' + 32: 2, # 'Б' + 35: 1, # 'Ð’' + 43: 1, # 'Г' + 37: 2, # 'Д' + 44: 2, # 'Е' + 55: 1, # 'Ж' + 47: 1, # 'З' + 40: 2, # 'И' + 59: 1, # 'Й' + 33: 2, # 'К' + 46: 1, # 'Л' + 38: 1, # 'М' + 36: 1, # 'Ð' + 41: 2, # 'О' + 30: 1, # 'П' + 39: 1, # 'Р' + 28: 2, # 'С' + 34: 2, # 'Т' + 51: 1, # 'У' + 48: 1, # 'Ф' + 49: 1, # 'Ð¥' + 53: 1, # 'Ц' + 50: 1, # 'Ч' + 54: 1, # 'Ш' + 57: 0, # 'Щ' + 61: 1, # 'Ъ' + 60: 1, # 'Ю' + 56: 1, # 'Я' + 1: 3, # 'а' + 18: 0, # 'б' + 9: 0, # 'в' + 20: 1, # 'г' + 11: 0, # 'д' + 3: 3, # 'е' + 23: 0, # 'ж' + 15: 0, # 'з' + 2: 3, # 'и' + 26: 0, # 'й' + 12: 0, # 'к' + 10: 0, # 'л' + 14: 0, # 'м' + 6: 0, # 'н' + 4: 3, # 'о' + 13: 0, # 'п' + 7: 0, # 'Ñ€' + 8: 0, # 'Ñ' + 5: 1, # 'Ñ‚' + 19: 1, # 'у' + 29: 0, # 'Ñ„' + 25: 0, # 'Ñ…' + 22: 0, # 'ц' + 21: 0, # 'ч' + 27: 1, # 'ш' + 24: 0, # 'щ' + 17: 0, # 'ÑŠ' + 52: 0, # 'ÑŒ' + 42: 2, # 'ÑŽ' + 16: 2, # 'Ñ' + 58: 0, # 'Ñ”' + 62: 0, # 'â„–' + }, + 41: { # 'О' + 63: 0, # 'e' + 45: 0, # '\xad' + 31: 1, # 'Ð' + 32: 1, # 'Б' + 35: 2, # 'Ð’' + 43: 1, # 'Г' + 37: 2, # 'Д' + 44: 1, # 'Е' + 55: 1, # 'Ж' + 47: 1, # 'З' + 40: 1, # 'И' + 59: 1, # 'Й' + 33: 2, # 'К' + 46: 2, # 'Л' + 38: 2, # 'М' + 36: 2, # 'Ð' + 41: 2, # 'О' + 30: 1, # 'П' + 39: 2, # 'Р' + 28: 2, # 'С' + 34: 2, # 'Т' + 51: 1, # 'У' + 48: 1, # 'Ф' + 49: 1, # 'Ð¥' + 53: 0, # 'Ц' + 50: 1, # 'Ч' + 54: 1, # 'Ш' + 57: 1, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 1, # 'Я' + 1: 1, # 'а' + 18: 2, # 'б' + 9: 2, # 'в' + 20: 2, # 'г' + 11: 1, # 'д' + 3: 1, # 'е' + 23: 1, # 'ж' + 15: 1, # 'з' + 2: 0, # 'и' + 26: 1, # 'й' + 12: 2, # 'к' + 10: 2, # 'л' + 14: 1, # 'м' + 6: 1, # 'н' + 4: 0, # 'о' + 13: 2, # 'п' + 7: 2, # 'Ñ€' + 8: 2, # 'Ñ' + 5: 3, # 'Ñ‚' + 19: 1, # 'у' + 29: 1, # 'Ñ„' + 25: 1, # 'Ñ…' + 22: 1, # 'ц' + 21: 2, # 'ч' + 27: 0, # 'ш' + 24: 2, # 'щ' + 17: 0, # 'ÑŠ' + 52: 0, # 'ÑŒ' + 42: 0, # 'ÑŽ' + 16: 1, # 'Ñ' + 58: 0, # 'Ñ”' + 62: 0, # 'â„–' + }, + 30: { # 'П' + 63: 0, # 'e' + 45: 1, # '\xad' + 31: 2, # 'Ð' + 32: 1, # 'Б' + 35: 1, # 'Ð’' + 43: 1, # 'Г' + 37: 1, # 'Д' + 44: 1, # 'Е' + 55: 0, # 'Ж' + 47: 1, # 'З' + 40: 2, # 'И' + 59: 0, # 'Й' + 33: 1, # 'К' + 46: 1, # 'Л' + 38: 1, # 'М' + 36: 1, # 'Ð' + 41: 2, # 'О' + 30: 2, # 'П' + 39: 2, # 'Р' + 28: 2, # 'С' + 34: 1, # 'Т' + 51: 2, # 'У' + 48: 1, # 'Ф' + 49: 0, # 'Ð¥' + 53: 1, # 'Ц' + 50: 1, # 'Ч' + 54: 1, # 'Ш' + 57: 0, # 'Щ' + 61: 1, # 'Ъ' + 60: 1, # 'Ю' + 56: 0, # 'Я' + 1: 3, # 'а' + 18: 0, # 'б' + 9: 0, # 'в' + 20: 0, # 'г' + 11: 2, # 'д' + 3: 3, # 'е' + 23: 0, # 'ж' + 15: 0, # 'з' + 2: 2, # 'и' + 26: 0, # 'й' + 12: 1, # 'к' + 10: 3, # 'л' + 14: 0, # 'м' + 6: 1, # 'н' + 4: 3, # 'о' + 13: 0, # 'п' + 7: 3, # 'Ñ€' + 8: 1, # 'Ñ' + 5: 1, # 'Ñ‚' + 19: 2, # 'у' + 29: 1, # 'Ñ„' + 25: 1, # 'Ñ…' + 22: 0, # 'ц' + 21: 1, # 'ч' + 27: 1, # 'ш' + 24: 0, # 'щ' + 17: 2, # 'ÑŠ' + 52: 1, # 'ÑŒ' + 42: 1, # 'ÑŽ' + 16: 1, # 'Ñ' + 58: 0, # 'Ñ”' + 62: 0, # 'â„–' + }, + 39: { # 'Р' + 63: 0, # 'e' + 45: 1, # '\xad' + 31: 2, # 'Ð' + 32: 1, # 'Б' + 35: 1, # 'Ð’' + 43: 2, # 'Г' + 37: 2, # 'Д' + 44: 2, # 'Е' + 55: 0, # 'Ж' + 47: 1, # 'З' + 40: 2, # 'И' + 59: 0, # 'Й' + 33: 1, # 'К' + 46: 0, # 'Л' + 38: 1, # 'М' + 36: 1, # 'Ð' + 41: 2, # 'О' + 30: 2, # 'П' + 39: 1, # 'Р' + 28: 1, # 'С' + 34: 1, # 'Т' + 51: 1, # 'У' + 48: 1, # 'Ф' + 49: 1, # 'Ð¥' + 53: 1, # 'Ц' + 50: 1, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 1, # 'Ъ' + 60: 1, # 'Ю' + 56: 1, # 'Я' + 1: 3, # 'а' + 18: 0, # 'б' + 9: 0, # 'в' + 20: 0, # 'г' + 11: 0, # 'д' + 3: 2, # 'е' + 23: 0, # 'ж' + 15: 0, # 'з' + 2: 2, # 'и' + 26: 0, # 'й' + 12: 0, # 'к' + 10: 0, # 'л' + 14: 0, # 'м' + 6: 1, # 'н' + 4: 3, # 'о' + 13: 0, # 'п' + 7: 0, # 'Ñ€' + 8: 1, # 'Ñ' + 5: 0, # 'Ñ‚' + 19: 3, # 'у' + 29: 0, # 'Ñ„' + 25: 0, # 'Ñ…' + 22: 0, # 'ц' + 21: 0, # 'ч' + 27: 0, # 'ш' + 24: 0, # 'щ' + 17: 1, # 'ÑŠ' + 52: 0, # 'ÑŒ' + 42: 1, # 'ÑŽ' + 16: 1, # 'Ñ' + 58: 0, # 'Ñ”' + 62: 0, # 'â„–' + }, + 28: { # 'С' + 63: 1, # 'e' + 45: 0, # '\xad' + 31: 3, # 'Ð' + 32: 2, # 'Б' + 35: 2, # 'Ð’' + 43: 1, # 'Г' + 37: 2, # 'Д' + 44: 2, # 'Е' + 55: 1, # 'Ж' + 47: 1, # 'З' + 40: 2, # 'И' + 59: 0, # 'Й' + 33: 2, # 'К' + 46: 1, # 'Л' + 38: 1, # 'М' + 36: 1, # 'Ð' + 41: 2, # 'О' + 30: 2, # 'П' + 39: 1, # 'Р' + 28: 2, # 'С' + 34: 2, # 'Т' + 51: 1, # 'У' + 48: 1, # 'Ф' + 49: 0, # 'Ð¥' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 1, # 'Ъ' + 60: 1, # 'Ю' + 56: 1, # 'Я' + 1: 3, # 'а' + 18: 1, # 'б' + 9: 2, # 'в' + 20: 1, # 'г' + 11: 1, # 'д' + 3: 3, # 'е' + 23: 0, # 'ж' + 15: 0, # 'з' + 2: 3, # 'и' + 26: 0, # 'й' + 12: 2, # 'к' + 10: 3, # 'л' + 14: 2, # 'м' + 6: 1, # 'н' + 4: 3, # 'о' + 13: 3, # 'п' + 7: 2, # 'Ñ€' + 8: 0, # 'Ñ' + 5: 3, # 'Ñ‚' + 19: 2, # 'у' + 29: 2, # 'Ñ„' + 25: 1, # 'Ñ…' + 22: 1, # 'ц' + 21: 1, # 'ч' + 27: 0, # 'ш' + 24: 0, # 'щ' + 17: 3, # 'ÑŠ' + 52: 1, # 'ÑŒ' + 42: 1, # 'ÑŽ' + 16: 1, # 'Ñ' + 58: 0, # 'Ñ”' + 62: 0, # 'â„–' + }, + 34: { # 'Т' + 63: 0, # 'e' + 45: 0, # '\xad' + 31: 2, # 'Ð' + 32: 2, # 'Б' + 35: 1, # 'Ð’' + 43: 0, # 'Г' + 37: 1, # 'Д' + 44: 2, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 2, # 'И' + 59: 0, # 'Й' + 33: 2, # 'К' + 46: 1, # 'Л' + 38: 1, # 'М' + 36: 1, # 'Ð' + 41: 2, # 'О' + 30: 1, # 'П' + 39: 2, # 'Р' + 28: 2, # 'С' + 34: 1, # 'Т' + 51: 1, # 'У' + 48: 1, # 'Ф' + 49: 0, # 'Ð¥' + 53: 1, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 1, # 'Ъ' + 60: 0, # 'Ю' + 56: 1, # 'Я' + 1: 3, # 'а' + 18: 1, # 'б' + 9: 1, # 'в' + 20: 0, # 'г' + 11: 0, # 'д' + 3: 3, # 'е' + 23: 0, # 'ж' + 15: 0, # 'з' + 2: 2, # 'и' + 26: 0, # 'й' + 12: 1, # 'к' + 10: 1, # 'л' + 14: 0, # 'м' + 6: 0, # 'н' + 4: 3, # 'о' + 13: 0, # 'п' + 7: 3, # 'Ñ€' + 8: 0, # 'Ñ' + 5: 0, # 'Ñ‚' + 19: 2, # 'у' + 29: 0, # 'Ñ„' + 25: 0, # 'Ñ…' + 22: 0, # 'ц' + 21: 0, # 'ч' + 27: 0, # 'ш' + 24: 0, # 'щ' + 17: 2, # 'ÑŠ' + 52: 0, # 'ÑŒ' + 42: 1, # 'ÑŽ' + 16: 2, # 'Ñ' + 58: 0, # 'Ñ”' + 62: 0, # 'â„–' + }, + 51: { # 'У' + 63: 0, # 'e' + 45: 1, # '\xad' + 31: 1, # 'Ð' + 32: 1, # 'Б' + 35: 1, # 'Ð’' + 43: 1, # 'Г' + 37: 1, # 'Д' + 44: 2, # 'Е' + 55: 1, # 'Ж' + 47: 1, # 'З' + 40: 1, # 'И' + 59: 0, # 'Й' + 33: 1, # 'К' + 46: 1, # 'Л' + 38: 1, # 'М' + 36: 1, # 'Ð' + 41: 0, # 'О' + 30: 1, # 'П' + 39: 1, # 'Р' + 28: 1, # 'С' + 34: 2, # 'Т' + 51: 0, # 'У' + 48: 1, # 'Ф' + 49: 1, # 'Ð¥' + 53: 1, # 'Ц' + 50: 1, # 'Ч' + 54: 1, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 1, # 'а' + 18: 1, # 'б' + 9: 2, # 'в' + 20: 1, # 'г' + 11: 1, # 'д' + 3: 2, # 'е' + 23: 1, # 'ж' + 15: 1, # 'з' + 2: 2, # 'и' + 26: 1, # 'й' + 12: 2, # 'к' + 10: 1, # 'л' + 14: 1, # 'м' + 6: 2, # 'н' + 4: 2, # 'о' + 13: 1, # 'п' + 7: 1, # 'Ñ€' + 8: 2, # 'Ñ' + 5: 1, # 'Ñ‚' + 19: 1, # 'у' + 29: 0, # 'Ñ„' + 25: 1, # 'Ñ…' + 22: 0, # 'ц' + 21: 2, # 'ч' + 27: 1, # 'ш' + 24: 0, # 'щ' + 17: 1, # 'ÑŠ' + 52: 0, # 'ÑŒ' + 42: 0, # 'ÑŽ' + 16: 0, # 'Ñ' + 58: 0, # 'Ñ”' + 62: 0, # 'â„–' + }, + 48: { # 'Ф' + 63: 0, # 'e' + 45: 0, # '\xad' + 31: 2, # 'Ð' + 32: 1, # 'Б' + 35: 1, # 'Ð’' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 1, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 2, # 'И' + 59: 0, # 'Й' + 33: 1, # 'К' + 46: 1, # 'Л' + 38: 0, # 'М' + 36: 1, # 'Ð' + 41: 1, # 'О' + 30: 2, # 'П' + 39: 1, # 'Р' + 28: 2, # 'С' + 34: 1, # 'Т' + 51: 1, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Ð¥' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 2, # 'а' + 18: 0, # 'б' + 9: 0, # 'в' + 20: 0, # 'г' + 11: 0, # 'д' + 3: 2, # 'е' + 23: 0, # 'ж' + 15: 0, # 'з' + 2: 2, # 'и' + 26: 0, # 'й' + 12: 0, # 'к' + 10: 2, # 'л' + 14: 0, # 'м' + 6: 0, # 'н' + 4: 2, # 'о' + 13: 0, # 'п' + 7: 2, # 'Ñ€' + 8: 0, # 'Ñ' + 5: 0, # 'Ñ‚' + 19: 1, # 'у' + 29: 0, # 'Ñ„' + 25: 0, # 'Ñ…' + 22: 0, # 'ц' + 21: 0, # 'ч' + 27: 0, # 'ш' + 24: 0, # 'щ' + 17: 1, # 'ÑŠ' + 52: 1, # 'ÑŒ' + 42: 1, # 'ÑŽ' + 16: 0, # 'Ñ' + 58: 0, # 'Ñ”' + 62: 0, # 'â„–' + }, + 49: { # 'Ð¥' + 63: 0, # 'e' + 45: 0, # '\xad' + 31: 1, # 'Ð' + 32: 0, # 'Б' + 35: 1, # 'Ð’' + 43: 1, # 'Г' + 37: 1, # 'Д' + 44: 1, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 1, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 1, # 'Л' + 38: 1, # 'М' + 36: 1, # 'Ð' + 41: 1, # 'О' + 30: 1, # 'П' + 39: 1, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 1, # 'Ð¥' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 2, # 'а' + 18: 0, # 'б' + 9: 1, # 'в' + 20: 0, # 'г' + 11: 0, # 'д' + 3: 2, # 'е' + 23: 0, # 'ж' + 15: 0, # 'з' + 2: 2, # 'и' + 26: 0, # 'й' + 12: 0, # 'к' + 10: 1, # 'л' + 14: 1, # 'м' + 6: 0, # 'н' + 4: 2, # 'о' + 13: 0, # 'п' + 7: 2, # 'Ñ€' + 8: 0, # 'Ñ' + 5: 0, # 'Ñ‚' + 19: 2, # 'у' + 29: 0, # 'Ñ„' + 25: 0, # 'Ñ…' + 22: 0, # 'ц' + 21: 0, # 'ч' + 27: 0, # 'ш' + 24: 0, # 'щ' + 17: 2, # 'ÑŠ' + 52: 1, # 'ÑŒ' + 42: 1, # 'ÑŽ' + 16: 0, # 'Ñ' + 58: 0, # 'Ñ”' + 62: 0, # 'â„–' + }, + 53: { # 'Ц' + 63: 0, # 'e' + 45: 0, # '\xad' + 31: 1, # 'Ð' + 32: 0, # 'Б' + 35: 1, # 'Ð’' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 1, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 2, # 'И' + 59: 0, # 'Й' + 33: 2, # 'К' + 46: 1, # 'Л' + 38: 1, # 'М' + 36: 0, # 'Ð' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 1, # 'Р' + 28: 2, # 'С' + 34: 0, # 'Т' + 51: 1, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Ð¥' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 2, # 'а' + 18: 0, # 'б' + 9: 2, # 'в' + 20: 0, # 'г' + 11: 0, # 'д' + 3: 2, # 'е' + 23: 0, # 'ж' + 15: 1, # 'з' + 2: 2, # 'и' + 26: 0, # 'й' + 12: 0, # 'к' + 10: 0, # 'л' + 14: 0, # 'м' + 6: 0, # 'н' + 4: 1, # 'о' + 13: 0, # 'п' + 7: 1, # 'Ñ€' + 8: 0, # 'Ñ' + 5: 0, # 'Ñ‚' + 19: 1, # 'у' + 29: 0, # 'Ñ„' + 25: 0, # 'Ñ…' + 22: 0, # 'ц' + 21: 0, # 'ч' + 27: 0, # 'ш' + 24: 0, # 'щ' + 17: 1, # 'ÑŠ' + 52: 0, # 'ÑŒ' + 42: 1, # 'ÑŽ' + 16: 1, # 'Ñ' + 58: 0, # 'Ñ”' + 62: 0, # 'â„–' + }, + 50: { # 'Ч' + 63: 0, # 'e' + 45: 0, # '\xad' + 31: 2, # 'Ð' + 32: 1, # 'Б' + 35: 0, # 'Ð’' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 1, # 'Е' + 55: 0, # 'Ж' + 47: 1, # 'З' + 40: 1, # 'И' + 59: 0, # 'Й' + 33: 1, # 'К' + 46: 1, # 'Л' + 38: 0, # 'М' + 36: 1, # 'Ð' + 41: 1, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 1, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Ð¥' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 2, # 'а' + 18: 0, # 'б' + 9: 0, # 'в' + 20: 0, # 'г' + 11: 0, # 'д' + 3: 3, # 'е' + 23: 1, # 'ж' + 15: 0, # 'з' + 2: 2, # 'и' + 26: 0, # 'й' + 12: 0, # 'к' + 10: 1, # 'л' + 14: 0, # 'м' + 6: 0, # 'н' + 4: 2, # 'о' + 13: 0, # 'п' + 7: 1, # 'Ñ€' + 8: 0, # 'Ñ' + 5: 0, # 'Ñ‚' + 19: 2, # 'у' + 29: 0, # 'Ñ„' + 25: 0, # 'Ñ…' + 22: 0, # 'ц' + 21: 0, # 'ч' + 27: 0, # 'ш' + 24: 0, # 'щ' + 17: 1, # 'ÑŠ' + 52: 1, # 'ÑŒ' + 42: 0, # 'ÑŽ' + 16: 0, # 'Ñ' + 58: 0, # 'Ñ”' + 62: 0, # 'â„–' + }, + 54: { # 'Ш' + 63: 0, # 'e' + 45: 0, # '\xad' + 31: 1, # 'Ð' + 32: 0, # 'Б' + 35: 0, # 'Ð’' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 1, # 'Е' + 55: 0, # 'Ж' + 47: 1, # 'З' + 40: 1, # 'И' + 59: 0, # 'Й' + 33: 1, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 1, # 'Ð' + 41: 1, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 1, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Ð¥' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 2, # 'а' + 18: 0, # 'б' + 9: 2, # 'в' + 20: 0, # 'г' + 11: 0, # 'д' + 3: 2, # 'е' + 23: 0, # 'ж' + 15: 0, # 'з' + 2: 2, # 'и' + 26: 0, # 'й' + 12: 1, # 'к' + 10: 1, # 'л' + 14: 1, # 'м' + 6: 1, # 'н' + 4: 2, # 'о' + 13: 1, # 'п' + 7: 1, # 'Ñ€' + 8: 0, # 'Ñ' + 5: 0, # 'Ñ‚' + 19: 2, # 'у' + 29: 0, # 'Ñ„' + 25: 0, # 'Ñ…' + 22: 0, # 'ц' + 21: 1, # 'ч' + 27: 0, # 'ш' + 24: 0, # 'щ' + 17: 1, # 'ÑŠ' + 52: 1, # 'ÑŒ' + 42: 0, # 'ÑŽ' + 16: 0, # 'Ñ' + 58: 0, # 'Ñ”' + 62: 0, # 'â„–' + }, + 57: { # 'Щ' + 63: 0, # 'e' + 45: 0, # '\xad' + 31: 1, # 'Ð' + 32: 0, # 'Б' + 35: 0, # 'Ð’' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 1, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 1, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Ð' + 41: 1, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Ð¥' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 2, # 'а' + 18: 0, # 'б' + 9: 0, # 'в' + 20: 0, # 'г' + 11: 0, # 'д' + 3: 2, # 'е' + 23: 0, # 'ж' + 15: 0, # 'з' + 2: 1, # 'и' + 26: 0, # 'й' + 12: 0, # 'к' + 10: 0, # 'л' + 14: 0, # 'м' + 6: 0, # 'н' + 4: 1, # 'о' + 13: 0, # 'п' + 7: 1, # 'Ñ€' + 8: 0, # 'Ñ' + 5: 0, # 'Ñ‚' + 19: 1, # 'у' + 29: 0, # 'Ñ„' + 25: 0, # 'Ñ…' + 22: 0, # 'ц' + 21: 0, # 'ч' + 27: 0, # 'ш' + 24: 0, # 'щ' + 17: 1, # 'ÑŠ' + 52: 0, # 'ÑŒ' + 42: 0, # 'ÑŽ' + 16: 1, # 'Ñ' + 58: 0, # 'Ñ”' + 62: 0, # 'â„–' + }, + 61: { # 'Ъ' + 63: 0, # 'e' + 45: 0, # '\xad' + 31: 0, # 'Ð' + 32: 1, # 'Б' + 35: 1, # 'Ð’' + 43: 0, # 'Г' + 37: 1, # 'Д' + 44: 0, # 'Е' + 55: 1, # 'Ж' + 47: 1, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 1, # 'К' + 46: 2, # 'Л' + 38: 1, # 'М' + 36: 1, # 'Ð' + 41: 0, # 'О' + 30: 1, # 'П' + 39: 2, # 'Р' + 28: 1, # 'С' + 34: 1, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 1, # 'Ð¥' + 53: 1, # 'Ц' + 50: 1, # 'Ч' + 54: 1, # 'Ш' + 57: 1, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 0, # 'а' + 18: 0, # 'б' + 9: 0, # 'в' + 20: 0, # 'г' + 11: 0, # 'д' + 3: 0, # 'е' + 23: 0, # 'ж' + 15: 0, # 'з' + 2: 0, # 'и' + 26: 0, # 'й' + 12: 0, # 'к' + 10: 1, # 'л' + 14: 0, # 'м' + 6: 1, # 'н' + 4: 0, # 'о' + 13: 0, # 'п' + 7: 1, # 'Ñ€' + 8: 0, # 'Ñ' + 5: 0, # 'Ñ‚' + 19: 0, # 'у' + 29: 0, # 'Ñ„' + 25: 0, # 'Ñ…' + 22: 0, # 'ц' + 21: 0, # 'ч' + 27: 0, # 'ш' + 24: 0, # 'щ' + 17: 0, # 'ÑŠ' + 52: 0, # 'ÑŒ' + 42: 0, # 'ÑŽ' + 16: 0, # 'Ñ' + 58: 0, # 'Ñ”' + 62: 0, # 'â„–' + }, + 60: { # 'Ю' + 63: 0, # 'e' + 45: 0, # '\xad' + 31: 1, # 'Ð' + 32: 1, # 'Б' + 35: 0, # 'Ð’' + 43: 1, # 'Г' + 37: 1, # 'Д' + 44: 0, # 'Е' + 55: 1, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 1, # 'К' + 46: 1, # 'Л' + 38: 0, # 'М' + 36: 1, # 'Ð' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 1, # 'Р' + 28: 1, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Ð¥' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 0, # 'а' + 18: 1, # 'б' + 9: 1, # 'в' + 20: 2, # 'г' + 11: 1, # 'д' + 3: 0, # 'е' + 23: 2, # 'ж' + 15: 1, # 'з' + 2: 1, # 'и' + 26: 0, # 'й' + 12: 1, # 'к' + 10: 1, # 'л' + 14: 1, # 'м' + 6: 1, # 'н' + 4: 0, # 'о' + 13: 1, # 'п' + 7: 1, # 'Ñ€' + 8: 1, # 'Ñ' + 5: 1, # 'Ñ‚' + 19: 0, # 'у' + 29: 0, # 'Ñ„' + 25: 1, # 'Ñ…' + 22: 0, # 'ц' + 21: 0, # 'ч' + 27: 0, # 'ш' + 24: 0, # 'щ' + 17: 0, # 'ÑŠ' + 52: 0, # 'ÑŒ' + 42: 0, # 'ÑŽ' + 16: 0, # 'Ñ' + 58: 0, # 'Ñ”' + 62: 0, # 'â„–' + }, + 56: { # 'Я' + 63: 0, # 'e' + 45: 0, # '\xad' + 31: 0, # 'Ð' + 32: 1, # 'Б' + 35: 1, # 'Ð’' + 43: 1, # 'Г' + 37: 1, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 1, # 'К' + 46: 1, # 'Л' + 38: 1, # 'М' + 36: 1, # 'Ð' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 1, # 'С' + 34: 2, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Ð¥' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 0, # 'а' + 18: 1, # 'б' + 9: 1, # 'в' + 20: 1, # 'г' + 11: 1, # 'д' + 3: 0, # 'е' + 23: 0, # 'ж' + 15: 1, # 'з' + 2: 1, # 'и' + 26: 1, # 'й' + 12: 1, # 'к' + 10: 1, # 'л' + 14: 2, # 'м' + 6: 2, # 'н' + 4: 0, # 'о' + 13: 2, # 'п' + 7: 1, # 'Ñ€' + 8: 1, # 'Ñ' + 5: 1, # 'Ñ‚' + 19: 0, # 'у' + 29: 0, # 'Ñ„' + 25: 1, # 'Ñ…' + 22: 0, # 'ц' + 21: 0, # 'ч' + 27: 1, # 'ш' + 24: 0, # 'щ' + 17: 0, # 'ÑŠ' + 52: 0, # 'ÑŒ' + 42: 1, # 'ÑŽ' + 16: 0, # 'Ñ' + 58: 0, # 'Ñ”' + 62: 0, # 'â„–' + }, + 1: { # 'а' + 63: 1, # 'e' + 45: 1, # '\xad' + 31: 1, # 'Ð' + 32: 0, # 'Б' + 35: 0, # 'Ð’' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 1, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Ð' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Ð¥' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 1, # 'а' + 18: 3, # 'б' + 9: 3, # 'в' + 20: 3, # 'г' + 11: 3, # 'д' + 3: 3, # 'е' + 23: 3, # 'ж' + 15: 3, # 'з' + 2: 3, # 'и' + 26: 3, # 'й' + 12: 3, # 'к' + 10: 3, # 'л' + 14: 3, # 'м' + 6: 3, # 'н' + 4: 2, # 'о' + 13: 3, # 'п' + 7: 3, # 'Ñ€' + 8: 3, # 'Ñ' + 5: 3, # 'Ñ‚' + 19: 3, # 'у' + 29: 3, # 'Ñ„' + 25: 3, # 'Ñ…' + 22: 3, # 'ц' + 21: 3, # 'ч' + 27: 3, # 'ш' + 24: 3, # 'щ' + 17: 0, # 'ÑŠ' + 52: 0, # 'ÑŒ' + 42: 1, # 'ÑŽ' + 16: 3, # 'Ñ' + 58: 0, # 'Ñ”' + 62: 0, # 'â„–' + }, + 18: { # 'б' + 63: 1, # 'e' + 45: 0, # '\xad' + 31: 0, # 'Ð' + 32: 0, # 'Б' + 35: 0, # 'Ð’' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Ð' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Ð¥' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 3, # 'а' + 18: 0, # 'б' + 9: 3, # 'в' + 20: 1, # 'г' + 11: 2, # 'д' + 3: 3, # 'е' + 23: 1, # 'ж' + 15: 1, # 'з' + 2: 3, # 'и' + 26: 0, # 'й' + 12: 1, # 'к' + 10: 3, # 'л' + 14: 2, # 'м' + 6: 3, # 'н' + 4: 3, # 'о' + 13: 1, # 'п' + 7: 3, # 'Ñ€' + 8: 3, # 'Ñ' + 5: 0, # 'Ñ‚' + 19: 3, # 'у' + 29: 0, # 'Ñ„' + 25: 2, # 'Ñ…' + 22: 1, # 'ц' + 21: 1, # 'ч' + 27: 1, # 'ш' + 24: 3, # 'щ' + 17: 3, # 'ÑŠ' + 52: 1, # 'ÑŒ' + 42: 2, # 'ÑŽ' + 16: 3, # 'Ñ' + 58: 0, # 'Ñ”' + 62: 0, # 'â„–' + }, + 9: { # 'в' + 63: 1, # 'e' + 45: 1, # '\xad' + 31: 0, # 'Ð' + 32: 1, # 'Б' + 35: 0, # 'Ð’' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Ð' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 1, # 'Ф' + 49: 0, # 'Ð¥' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 3, # 'а' + 18: 1, # 'б' + 9: 0, # 'в' + 20: 2, # 'г' + 11: 3, # 'д' + 3: 3, # 'е' + 23: 1, # 'ж' + 15: 3, # 'з' + 2: 3, # 'и' + 26: 0, # 'й' + 12: 3, # 'к' + 10: 3, # 'л' + 14: 2, # 'м' + 6: 3, # 'н' + 4: 3, # 'о' + 13: 2, # 'п' + 7: 3, # 'Ñ€' + 8: 3, # 'Ñ' + 5: 3, # 'Ñ‚' + 19: 2, # 'у' + 29: 0, # 'Ñ„' + 25: 2, # 'Ñ…' + 22: 2, # 'ц' + 21: 3, # 'ч' + 27: 2, # 'ш' + 24: 1, # 'щ' + 17: 3, # 'ÑŠ' + 52: 1, # 'ÑŒ' + 42: 2, # 'ÑŽ' + 16: 3, # 'Ñ' + 58: 0, # 'Ñ”' + 62: 0, # 'â„–' + }, + 20: { # 'г' + 63: 0, # 'e' + 45: 0, # '\xad' + 31: 0, # 'Ð' + 32: 0, # 'Б' + 35: 0, # 'Ð’' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Ð' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Ð¥' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 3, # 'а' + 18: 1, # 'б' + 9: 2, # 'в' + 20: 1, # 'г' + 11: 2, # 'д' + 3: 3, # 'е' + 23: 0, # 'ж' + 15: 1, # 'з' + 2: 3, # 'и' + 26: 0, # 'й' + 12: 1, # 'к' + 10: 3, # 'л' + 14: 1, # 'м' + 6: 3, # 'н' + 4: 3, # 'о' + 13: 1, # 'п' + 7: 3, # 'Ñ€' + 8: 2, # 'Ñ' + 5: 2, # 'Ñ‚' + 19: 3, # 'у' + 29: 1, # 'Ñ„' + 25: 1, # 'Ñ…' + 22: 0, # 'ц' + 21: 1, # 'ч' + 27: 0, # 'ш' + 24: 0, # 'щ' + 17: 3, # 'ÑŠ' + 52: 1, # 'ÑŒ' + 42: 1, # 'ÑŽ' + 16: 1, # 'Ñ' + 58: 0, # 'Ñ”' + 62: 0, # 'â„–' + }, + 11: { # 'д' + 63: 1, # 'e' + 45: 0, # '\xad' + 31: 0, # 'Ð' + 32: 0, # 'Б' + 35: 0, # 'Ð’' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Ð' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Ð¥' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 3, # 'а' + 18: 2, # 'б' + 9: 3, # 'в' + 20: 2, # 'г' + 11: 2, # 'д' + 3: 3, # 'е' + 23: 3, # 'ж' + 15: 2, # 'з' + 2: 3, # 'и' + 26: 0, # 'й' + 12: 3, # 'к' + 10: 3, # 'л' + 14: 3, # 'м' + 6: 3, # 'н' + 4: 3, # 'о' + 13: 3, # 'п' + 7: 3, # 'Ñ€' + 8: 3, # 'Ñ' + 5: 1, # 'Ñ‚' + 19: 3, # 'у' + 29: 1, # 'Ñ„' + 25: 2, # 'Ñ…' + 22: 2, # 'ц' + 21: 2, # 'ч' + 27: 1, # 'ш' + 24: 1, # 'щ' + 17: 3, # 'ÑŠ' + 52: 1, # 'ÑŒ' + 42: 1, # 'ÑŽ' + 16: 3, # 'Ñ' + 58: 0, # 'Ñ”' + 62: 0, # 'â„–' + }, + 3: { # 'е' + 63: 0, # 'e' + 45: 1, # '\xad' + 31: 0, # 'Ð' + 32: 0, # 'Б' + 35: 0, # 'Ð’' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Ð' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Ð¥' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 2, # 'а' + 18: 3, # 'б' + 9: 3, # 'в' + 20: 3, # 'г' + 11: 3, # 'д' + 3: 2, # 'е' + 23: 3, # 'ж' + 15: 3, # 'з' + 2: 2, # 'и' + 26: 3, # 'й' + 12: 3, # 'к' + 10: 3, # 'л' + 14: 3, # 'м' + 6: 3, # 'н' + 4: 3, # 'о' + 13: 3, # 'п' + 7: 3, # 'Ñ€' + 8: 3, # 'Ñ' + 5: 3, # 'Ñ‚' + 19: 2, # 'у' + 29: 3, # 'Ñ„' + 25: 3, # 'Ñ…' + 22: 3, # 'ц' + 21: 3, # 'ч' + 27: 3, # 'ш' + 24: 3, # 'щ' + 17: 1, # 'ÑŠ' + 52: 0, # 'ÑŒ' + 42: 1, # 'ÑŽ' + 16: 3, # 'Ñ' + 58: 0, # 'Ñ”' + 62: 0, # 'â„–' + }, + 23: { # 'ж' + 63: 0, # 'e' + 45: 0, # '\xad' + 31: 0, # 'Ð' + 32: 0, # 'Б' + 35: 0, # 'Ð’' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Ð' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Ð¥' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 3, # 'а' + 18: 3, # 'б' + 9: 2, # 'в' + 20: 1, # 'г' + 11: 3, # 'д' + 3: 3, # 'е' + 23: 0, # 'ж' + 15: 0, # 'з' + 2: 3, # 'и' + 26: 0, # 'й' + 12: 2, # 'к' + 10: 1, # 'л' + 14: 1, # 'м' + 6: 3, # 'н' + 4: 2, # 'о' + 13: 1, # 'п' + 7: 1, # 'Ñ€' + 8: 1, # 'Ñ' + 5: 1, # 'Ñ‚' + 19: 2, # 'у' + 29: 0, # 'Ñ„' + 25: 0, # 'Ñ…' + 22: 1, # 'ц' + 21: 1, # 'ч' + 27: 0, # 'ш' + 24: 0, # 'щ' + 17: 2, # 'ÑŠ' + 52: 0, # 'ÑŒ' + 42: 0, # 'ÑŽ' + 16: 1, # 'Ñ' + 58: 0, # 'Ñ”' + 62: 0, # 'â„–' + }, + 15: { # 'з' + 63: 1, # 'e' + 45: 0, # '\xad' + 31: 0, # 'Ð' + 32: 0, # 'Б' + 35: 0, # 'Ð’' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Ð' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Ð¥' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 3, # 'а' + 18: 3, # 'б' + 9: 3, # 'в' + 20: 3, # 'г' + 11: 3, # 'д' + 3: 3, # 'е' + 23: 1, # 'ж' + 15: 1, # 'з' + 2: 3, # 'и' + 26: 0, # 'й' + 12: 3, # 'к' + 10: 3, # 'л' + 14: 3, # 'м' + 6: 3, # 'н' + 4: 3, # 'о' + 13: 3, # 'п' + 7: 3, # 'Ñ€' + 8: 3, # 'Ñ' + 5: 3, # 'Ñ‚' + 19: 3, # 'у' + 29: 1, # 'Ñ„' + 25: 2, # 'Ñ…' + 22: 2, # 'ц' + 21: 2, # 'ч' + 27: 2, # 'ш' + 24: 1, # 'щ' + 17: 2, # 'ÑŠ' + 52: 1, # 'ÑŒ' + 42: 1, # 'ÑŽ' + 16: 2, # 'Ñ' + 58: 0, # 'Ñ”' + 62: 0, # 'â„–' + }, + 2: { # 'и' + 63: 1, # 'e' + 45: 1, # '\xad' + 31: 0, # 'Ð' + 32: 0, # 'Б' + 35: 0, # 'Ð’' + 43: 1, # 'Г' + 37: 0, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 1, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Ð' + 41: 0, # 'О' + 30: 1, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 1, # 'Ф' + 49: 0, # 'Ð¥' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 3, # 'а' + 18: 3, # 'б' + 9: 3, # 'в' + 20: 3, # 'г' + 11: 3, # 'д' + 3: 3, # 'е' + 23: 3, # 'ж' + 15: 3, # 'з' + 2: 3, # 'и' + 26: 3, # 'й' + 12: 3, # 'к' + 10: 3, # 'л' + 14: 3, # 'м' + 6: 3, # 'н' + 4: 3, # 'о' + 13: 3, # 'п' + 7: 3, # 'Ñ€' + 8: 3, # 'Ñ' + 5: 3, # 'Ñ‚' + 19: 2, # 'у' + 29: 3, # 'Ñ„' + 25: 3, # 'Ñ…' + 22: 3, # 'ц' + 21: 3, # 'ч' + 27: 3, # 'ш' + 24: 3, # 'щ' + 17: 2, # 'ÑŠ' + 52: 0, # 'ÑŒ' + 42: 1, # 'ÑŽ' + 16: 3, # 'Ñ' + 58: 0, # 'Ñ”' + 62: 0, # 'â„–' + }, + 26: { # 'й' + 63: 0, # 'e' + 45: 0, # '\xad' + 31: 0, # 'Ð' + 32: 0, # 'Б' + 35: 0, # 'Ð’' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Ð' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Ð¥' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 1, # 'а' + 18: 2, # 'б' + 9: 2, # 'в' + 20: 1, # 'г' + 11: 2, # 'д' + 3: 2, # 'е' + 23: 0, # 'ж' + 15: 2, # 'з' + 2: 1, # 'и' + 26: 0, # 'й' + 12: 3, # 'к' + 10: 2, # 'л' + 14: 2, # 'м' + 6: 3, # 'н' + 4: 2, # 'о' + 13: 1, # 'п' + 7: 2, # 'Ñ€' + 8: 3, # 'Ñ' + 5: 3, # 'Ñ‚' + 19: 1, # 'у' + 29: 2, # 'Ñ„' + 25: 1, # 'Ñ…' + 22: 2, # 'ц' + 21: 2, # 'ч' + 27: 1, # 'ш' + 24: 1, # 'щ' + 17: 1, # 'ÑŠ' + 52: 0, # 'ÑŒ' + 42: 0, # 'ÑŽ' + 16: 1, # 'Ñ' + 58: 0, # 'Ñ”' + 62: 0, # 'â„–' + }, + 12: { # 'к' + 63: 1, # 'e' + 45: 0, # '\xad' + 31: 0, # 'Ð' + 32: 0, # 'Б' + 35: 1, # 'Ð’' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 1, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Ð' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Ð¥' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 3, # 'а' + 18: 1, # 'б' + 9: 3, # 'в' + 20: 2, # 'г' + 11: 1, # 'д' + 3: 3, # 'е' + 23: 0, # 'ж' + 15: 2, # 'з' + 2: 3, # 'и' + 26: 0, # 'й' + 12: 1, # 'к' + 10: 3, # 'л' + 14: 2, # 'м' + 6: 3, # 'н' + 4: 3, # 'о' + 13: 1, # 'п' + 7: 3, # 'Ñ€' + 8: 3, # 'Ñ' + 5: 3, # 'Ñ‚' + 19: 3, # 'у' + 29: 1, # 'Ñ„' + 25: 1, # 'Ñ…' + 22: 3, # 'ц' + 21: 2, # 'ч' + 27: 1, # 'ш' + 24: 0, # 'щ' + 17: 3, # 'ÑŠ' + 52: 1, # 'ÑŒ' + 42: 2, # 'ÑŽ' + 16: 1, # 'Ñ' + 58: 0, # 'Ñ”' + 62: 0, # 'â„–' + }, + 10: { # 'л' + 63: 1, # 'e' + 45: 1, # '\xad' + 31: 0, # 'Ð' + 32: 0, # 'Б' + 35: 0, # 'Ð’' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Ð' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 1, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Ð¥' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 3, # 'а' + 18: 3, # 'б' + 9: 3, # 'в' + 20: 3, # 'г' + 11: 2, # 'д' + 3: 3, # 'е' + 23: 3, # 'ж' + 15: 2, # 'з' + 2: 3, # 'и' + 26: 0, # 'й' + 12: 3, # 'к' + 10: 1, # 'л' + 14: 2, # 'м' + 6: 3, # 'н' + 4: 3, # 'о' + 13: 2, # 'п' + 7: 2, # 'Ñ€' + 8: 3, # 'Ñ' + 5: 3, # 'Ñ‚' + 19: 3, # 'у' + 29: 2, # 'Ñ„' + 25: 2, # 'Ñ…' + 22: 2, # 'ц' + 21: 2, # 'ч' + 27: 2, # 'ш' + 24: 1, # 'щ' + 17: 3, # 'ÑŠ' + 52: 2, # 'ÑŒ' + 42: 3, # 'ÑŽ' + 16: 3, # 'Ñ' + 58: 0, # 'Ñ”' + 62: 0, # 'â„–' + }, + 14: { # 'м' + 63: 1, # 'e' + 45: 0, # '\xad' + 31: 1, # 'Ð' + 32: 0, # 'Б' + 35: 0, # 'Ð’' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Ð' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Ð¥' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 3, # 'а' + 18: 3, # 'б' + 9: 3, # 'в' + 20: 1, # 'г' + 11: 1, # 'д' + 3: 3, # 'е' + 23: 1, # 'ж' + 15: 1, # 'з' + 2: 3, # 'и' + 26: 0, # 'й' + 12: 2, # 'к' + 10: 3, # 'л' + 14: 1, # 'м' + 6: 3, # 'н' + 4: 3, # 'о' + 13: 3, # 'п' + 7: 2, # 'Ñ€' + 8: 2, # 'Ñ' + 5: 1, # 'Ñ‚' + 19: 3, # 'у' + 29: 2, # 'Ñ„' + 25: 1, # 'Ñ…' + 22: 2, # 'ц' + 21: 2, # 'ч' + 27: 2, # 'ш' + 24: 1, # 'щ' + 17: 3, # 'ÑŠ' + 52: 1, # 'ÑŒ' + 42: 2, # 'ÑŽ' + 16: 3, # 'Ñ' + 58: 0, # 'Ñ”' + 62: 0, # 'â„–' + }, + 6: { # 'н' + 63: 1, # 'e' + 45: 0, # '\xad' + 31: 0, # 'Ð' + 32: 0, # 'Б' + 35: 0, # 'Ð’' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Ð' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 1, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Ð¥' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 3, # 'а' + 18: 2, # 'б' + 9: 2, # 'в' + 20: 3, # 'г' + 11: 3, # 'д' + 3: 3, # 'е' + 23: 2, # 'ж' + 15: 2, # 'з' + 2: 3, # 'и' + 26: 0, # 'й' + 12: 3, # 'к' + 10: 2, # 'л' + 14: 1, # 'м' + 6: 3, # 'н' + 4: 3, # 'о' + 13: 1, # 'п' + 7: 2, # 'Ñ€' + 8: 3, # 'Ñ' + 5: 3, # 'Ñ‚' + 19: 3, # 'у' + 29: 3, # 'Ñ„' + 25: 2, # 'Ñ…' + 22: 3, # 'ц' + 21: 3, # 'ч' + 27: 2, # 'ш' + 24: 1, # 'щ' + 17: 3, # 'ÑŠ' + 52: 2, # 'ÑŒ' + 42: 2, # 'ÑŽ' + 16: 3, # 'Ñ' + 58: 0, # 'Ñ”' + 62: 0, # 'â„–' + }, + 4: { # 'о' + 63: 0, # 'e' + 45: 1, # '\xad' + 31: 0, # 'Ð' + 32: 0, # 'Б' + 35: 0, # 'Ð’' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Ð' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Ð¥' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 2, # 'а' + 18: 3, # 'б' + 9: 3, # 'в' + 20: 3, # 'г' + 11: 3, # 'д' + 3: 3, # 'е' + 23: 3, # 'ж' + 15: 3, # 'з' + 2: 3, # 'и' + 26: 3, # 'й' + 12: 3, # 'к' + 10: 3, # 'л' + 14: 3, # 'м' + 6: 3, # 'н' + 4: 2, # 'о' + 13: 3, # 'п' + 7: 3, # 'Ñ€' + 8: 3, # 'Ñ' + 5: 3, # 'Ñ‚' + 19: 2, # 'у' + 29: 3, # 'Ñ„' + 25: 3, # 'Ñ…' + 22: 3, # 'ц' + 21: 3, # 'ч' + 27: 3, # 'ш' + 24: 3, # 'щ' + 17: 1, # 'ÑŠ' + 52: 0, # 'ÑŒ' + 42: 1, # 'ÑŽ' + 16: 3, # 'Ñ' + 58: 0, # 'Ñ”' + 62: 0, # 'â„–' + }, + 13: { # 'п' + 63: 1, # 'e' + 45: 0, # '\xad' + 31: 0, # 'Ð' + 32: 0, # 'Б' + 35: 0, # 'Ð’' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Ð' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Ð¥' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 3, # 'а' + 18: 1, # 'б' + 9: 2, # 'в' + 20: 1, # 'г' + 11: 1, # 'д' + 3: 3, # 'е' + 23: 0, # 'ж' + 15: 1, # 'з' + 2: 3, # 'и' + 26: 1, # 'й' + 12: 2, # 'к' + 10: 3, # 'л' + 14: 1, # 'м' + 6: 2, # 'н' + 4: 3, # 'о' + 13: 1, # 'п' + 7: 3, # 'Ñ€' + 8: 2, # 'Ñ' + 5: 2, # 'Ñ‚' + 19: 3, # 'у' + 29: 1, # 'Ñ„' + 25: 1, # 'Ñ…' + 22: 2, # 'ц' + 21: 2, # 'ч' + 27: 1, # 'ш' + 24: 1, # 'щ' + 17: 3, # 'ÑŠ' + 52: 1, # 'ÑŒ' + 42: 2, # 'ÑŽ' + 16: 2, # 'Ñ' + 58: 0, # 'Ñ”' + 62: 0, # 'â„–' + }, + 7: { # 'Ñ€' + 63: 1, # 'e' + 45: 0, # '\xad' + 31: 0, # 'Ð' + 32: 0, # 'Б' + 35: 0, # 'Ð’' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Ð' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Ð¥' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 3, # 'а' + 18: 3, # 'б' + 9: 3, # 'в' + 20: 3, # 'г' + 11: 3, # 'д' + 3: 3, # 'е' + 23: 3, # 'ж' + 15: 2, # 'з' + 2: 3, # 'и' + 26: 0, # 'й' + 12: 3, # 'к' + 10: 3, # 'л' + 14: 3, # 'м' + 6: 3, # 'н' + 4: 3, # 'о' + 13: 2, # 'п' + 7: 1, # 'Ñ€' + 8: 3, # 'Ñ' + 5: 3, # 'Ñ‚' + 19: 3, # 'у' + 29: 2, # 'Ñ„' + 25: 3, # 'Ñ…' + 22: 3, # 'ц' + 21: 2, # 'ч' + 27: 3, # 'ш' + 24: 1, # 'щ' + 17: 3, # 'ÑŠ' + 52: 1, # 'ÑŒ' + 42: 2, # 'ÑŽ' + 16: 3, # 'Ñ' + 58: 0, # 'Ñ”' + 62: 0, # 'â„–' + }, + 8: { # 'Ñ' + 63: 1, # 'e' + 45: 0, # '\xad' + 31: 0, # 'Ð' + 32: 0, # 'Б' + 35: 0, # 'Ð’' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Ð' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Ð¥' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 3, # 'а' + 18: 2, # 'б' + 9: 3, # 'в' + 20: 2, # 'г' + 11: 2, # 'д' + 3: 3, # 'е' + 23: 0, # 'ж' + 15: 1, # 'з' + 2: 3, # 'и' + 26: 0, # 'й' + 12: 3, # 'к' + 10: 3, # 'л' + 14: 3, # 'м' + 6: 3, # 'н' + 4: 3, # 'о' + 13: 3, # 'п' + 7: 3, # 'Ñ€' + 8: 1, # 'Ñ' + 5: 3, # 'Ñ‚' + 19: 3, # 'у' + 29: 2, # 'Ñ„' + 25: 2, # 'Ñ…' + 22: 2, # 'ц' + 21: 2, # 'ч' + 27: 2, # 'ш' + 24: 0, # 'щ' + 17: 3, # 'ÑŠ' + 52: 2, # 'ÑŒ' + 42: 2, # 'ÑŽ' + 16: 3, # 'Ñ' + 58: 0, # 'Ñ”' + 62: 0, # 'â„–' + }, + 5: { # 'Ñ‚' + 63: 1, # 'e' + 45: 0, # '\xad' + 31: 0, # 'Ð' + 32: 0, # 'Б' + 35: 0, # 'Ð’' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Ð' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Ð¥' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 3, # 'а' + 18: 3, # 'б' + 9: 3, # 'в' + 20: 2, # 'г' + 11: 2, # 'д' + 3: 3, # 'е' + 23: 1, # 'ж' + 15: 1, # 'з' + 2: 3, # 'и' + 26: 0, # 'й' + 12: 3, # 'к' + 10: 3, # 'л' + 14: 2, # 'м' + 6: 3, # 'н' + 4: 3, # 'о' + 13: 2, # 'п' + 7: 3, # 'Ñ€' + 8: 3, # 'Ñ' + 5: 3, # 'Ñ‚' + 19: 3, # 'у' + 29: 1, # 'Ñ„' + 25: 2, # 'Ñ…' + 22: 2, # 'ц' + 21: 2, # 'ч' + 27: 1, # 'ш' + 24: 1, # 'щ' + 17: 3, # 'ÑŠ' + 52: 2, # 'ÑŒ' + 42: 2, # 'ÑŽ' + 16: 3, # 'Ñ' + 58: 0, # 'Ñ”' + 62: 0, # 'â„–' + }, + 19: { # 'у' + 63: 0, # 'e' + 45: 0, # '\xad' + 31: 0, # 'Ð' + 32: 0, # 'Б' + 35: 0, # 'Ð’' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Ð' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Ð¥' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 3, # 'а' + 18: 3, # 'б' + 9: 3, # 'в' + 20: 3, # 'г' + 11: 3, # 'д' + 3: 2, # 'е' + 23: 3, # 'ж' + 15: 3, # 'з' + 2: 2, # 'и' + 26: 2, # 'й' + 12: 3, # 'к' + 10: 3, # 'л' + 14: 3, # 'м' + 6: 3, # 'н' + 4: 2, # 'о' + 13: 3, # 'п' + 7: 3, # 'Ñ€' + 8: 3, # 'Ñ' + 5: 3, # 'Ñ‚' + 19: 1, # 'у' + 29: 2, # 'Ñ„' + 25: 2, # 'Ñ…' + 22: 2, # 'ц' + 21: 3, # 'ч' + 27: 3, # 'ш' + 24: 2, # 'щ' + 17: 1, # 'ÑŠ' + 52: 0, # 'ÑŒ' + 42: 1, # 'ÑŽ' + 16: 1, # 'Ñ' + 58: 0, # 'Ñ”' + 62: 0, # 'â„–' + }, + 29: { # 'Ñ„' + 63: 1, # 'e' + 45: 0, # '\xad' + 31: 0, # 'Ð' + 32: 0, # 'Б' + 35: 0, # 'Ð’' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Ð' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Ð¥' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 3, # 'а' + 18: 1, # 'б' + 9: 1, # 'в' + 20: 1, # 'г' + 11: 0, # 'д' + 3: 3, # 'е' + 23: 0, # 'ж' + 15: 0, # 'з' + 2: 3, # 'и' + 26: 0, # 'й' + 12: 2, # 'к' + 10: 2, # 'л' + 14: 1, # 'м' + 6: 1, # 'н' + 4: 3, # 'о' + 13: 0, # 'п' + 7: 2, # 'Ñ€' + 8: 2, # 'Ñ' + 5: 2, # 'Ñ‚' + 19: 2, # 'у' + 29: 0, # 'Ñ„' + 25: 1, # 'Ñ…' + 22: 0, # 'ц' + 21: 1, # 'ч' + 27: 1, # 'ш' + 24: 0, # 'щ' + 17: 2, # 'ÑŠ' + 52: 2, # 'ÑŒ' + 42: 1, # 'ÑŽ' + 16: 1, # 'Ñ' + 58: 0, # 'Ñ”' + 62: 0, # 'â„–' + }, + 25: { # 'Ñ…' + 63: 0, # 'e' + 45: 0, # '\xad' + 31: 0, # 'Ð' + 32: 0, # 'Б' + 35: 0, # 'Ð’' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Ð' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Ð¥' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 3, # 'а' + 18: 1, # 'б' + 9: 3, # 'в' + 20: 0, # 'г' + 11: 1, # 'д' + 3: 2, # 'е' + 23: 0, # 'ж' + 15: 1, # 'з' + 2: 3, # 'и' + 26: 0, # 'й' + 12: 1, # 'к' + 10: 2, # 'л' + 14: 2, # 'м' + 6: 3, # 'н' + 4: 3, # 'о' + 13: 1, # 'п' + 7: 3, # 'Ñ€' + 8: 1, # 'Ñ' + 5: 2, # 'Ñ‚' + 19: 3, # 'у' + 29: 0, # 'Ñ„' + 25: 1, # 'Ñ…' + 22: 0, # 'ц' + 21: 1, # 'ч' + 27: 0, # 'ш' + 24: 0, # 'щ' + 17: 2, # 'ÑŠ' + 52: 0, # 'ÑŒ' + 42: 1, # 'ÑŽ' + 16: 1, # 'Ñ' + 58: 0, # 'Ñ”' + 62: 0, # 'â„–' + }, + 22: { # 'ц' + 63: 1, # 'e' + 45: 0, # '\xad' + 31: 0, # 'Ð' + 32: 0, # 'Б' + 35: 0, # 'Ð’' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Ð' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Ð¥' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 3, # 'а' + 18: 1, # 'б' + 9: 2, # 'в' + 20: 1, # 'г' + 11: 1, # 'д' + 3: 3, # 'е' + 23: 0, # 'ж' + 15: 1, # 'з' + 2: 3, # 'и' + 26: 0, # 'й' + 12: 2, # 'к' + 10: 1, # 'л' + 14: 1, # 'м' + 6: 1, # 'н' + 4: 2, # 'о' + 13: 1, # 'п' + 7: 1, # 'Ñ€' + 8: 1, # 'Ñ' + 5: 1, # 'Ñ‚' + 19: 2, # 'у' + 29: 1, # 'Ñ„' + 25: 1, # 'Ñ…' + 22: 1, # 'ц' + 21: 1, # 'ч' + 27: 1, # 'ш' + 24: 1, # 'щ' + 17: 2, # 'ÑŠ' + 52: 1, # 'ÑŒ' + 42: 0, # 'ÑŽ' + 16: 2, # 'Ñ' + 58: 0, # 'Ñ”' + 62: 0, # 'â„–' + }, + 21: { # 'ч' + 63: 1, # 'e' + 45: 0, # '\xad' + 31: 0, # 'Ð' + 32: 0, # 'Б' + 35: 0, # 'Ð’' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Ð' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Ð¥' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 3, # 'а' + 18: 1, # 'б' + 9: 3, # 'в' + 20: 1, # 'г' + 11: 0, # 'д' + 3: 3, # 'е' + 23: 1, # 'ж' + 15: 0, # 'з' + 2: 3, # 'и' + 26: 0, # 'й' + 12: 3, # 'к' + 10: 2, # 'л' + 14: 2, # 'м' + 6: 3, # 'н' + 4: 3, # 'о' + 13: 0, # 'п' + 7: 2, # 'Ñ€' + 8: 0, # 'Ñ' + 5: 2, # 'Ñ‚' + 19: 3, # 'у' + 29: 0, # 'Ñ„' + 25: 0, # 'Ñ…' + 22: 0, # 'ц' + 21: 0, # 'ч' + 27: 1, # 'ш' + 24: 0, # 'щ' + 17: 2, # 'ÑŠ' + 52: 0, # 'ÑŒ' + 42: 1, # 'ÑŽ' + 16: 0, # 'Ñ' + 58: 0, # 'Ñ”' + 62: 0, # 'â„–' + }, + 27: { # 'ш' + 63: 1, # 'e' + 45: 0, # '\xad' + 31: 0, # 'Ð' + 32: 0, # 'Б' + 35: 0, # 'Ð’' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Ð' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Ð¥' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 3, # 'а' + 18: 0, # 'б' + 9: 2, # 'в' + 20: 0, # 'г' + 11: 1, # 'д' + 3: 3, # 'е' + 23: 0, # 'ж' + 15: 0, # 'з' + 2: 3, # 'и' + 26: 0, # 'й' + 12: 3, # 'к' + 10: 2, # 'л' + 14: 1, # 'м' + 6: 3, # 'н' + 4: 2, # 'о' + 13: 2, # 'п' + 7: 1, # 'Ñ€' + 8: 0, # 'Ñ' + 5: 1, # 'Ñ‚' + 19: 2, # 'у' + 29: 1, # 'Ñ„' + 25: 0, # 'Ñ…' + 22: 0, # 'ц' + 21: 1, # 'ч' + 27: 0, # 'ш' + 24: 0, # 'щ' + 17: 2, # 'ÑŠ' + 52: 1, # 'ÑŒ' + 42: 1, # 'ÑŽ' + 16: 0, # 'Ñ' + 58: 0, # 'Ñ”' + 62: 0, # 'â„–' + }, + 24: { # 'щ' + 63: 1, # 'e' + 45: 0, # '\xad' + 31: 0, # 'Ð' + 32: 0, # 'Б' + 35: 0, # 'Ð’' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Ð' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Ð¥' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 3, # 'а' + 18: 0, # 'б' + 9: 1, # 'в' + 20: 0, # 'г' + 11: 0, # 'д' + 3: 3, # 'е' + 23: 0, # 'ж' + 15: 0, # 'з' + 2: 3, # 'и' + 26: 0, # 'й' + 12: 1, # 'к' + 10: 0, # 'л' + 14: 0, # 'м' + 6: 2, # 'н' + 4: 3, # 'о' + 13: 0, # 'п' + 7: 1, # 'Ñ€' + 8: 0, # 'Ñ' + 5: 2, # 'Ñ‚' + 19: 3, # 'у' + 29: 0, # 'Ñ„' + 25: 0, # 'Ñ…' + 22: 1, # 'ц' + 21: 0, # 'ч' + 27: 0, # 'ш' + 24: 0, # 'щ' + 17: 1, # 'ÑŠ' + 52: 0, # 'ÑŒ' + 42: 0, # 'ÑŽ' + 16: 2, # 'Ñ' + 58: 0, # 'Ñ”' + 62: 0, # 'â„–' + }, + 17: { # 'ÑŠ' + 63: 0, # 'e' + 45: 0, # '\xad' + 31: 0, # 'Ð' + 32: 0, # 'Б' + 35: 0, # 'Ð’' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Ð' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Ð¥' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 1, # 'а' + 18: 3, # 'б' + 9: 3, # 'в' + 20: 3, # 'г' + 11: 3, # 'д' + 3: 2, # 'е' + 23: 3, # 'ж' + 15: 3, # 'з' + 2: 1, # 'и' + 26: 2, # 'й' + 12: 3, # 'к' + 10: 3, # 'л' + 14: 3, # 'м' + 6: 3, # 'н' + 4: 3, # 'о' + 13: 3, # 'п' + 7: 3, # 'Ñ€' + 8: 3, # 'Ñ' + 5: 3, # 'Ñ‚' + 19: 1, # 'у' + 29: 1, # 'Ñ„' + 25: 2, # 'Ñ…' + 22: 2, # 'ц' + 21: 3, # 'ч' + 27: 2, # 'ш' + 24: 3, # 'щ' + 17: 0, # 'ÑŠ' + 52: 0, # 'ÑŒ' + 42: 2, # 'ÑŽ' + 16: 0, # 'Ñ' + 58: 0, # 'Ñ”' + 62: 0, # 'â„–' + }, + 52: { # 'ÑŒ' + 63: 0, # 'e' + 45: 0, # '\xad' + 31: 0, # 'Ð' + 32: 0, # 'Б' + 35: 0, # 'Ð’' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Ð' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Ð¥' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 0, # 'а' + 18: 0, # 'б' + 9: 0, # 'в' + 20: 0, # 'г' + 11: 0, # 'д' + 3: 1, # 'е' + 23: 0, # 'ж' + 15: 0, # 'з' + 2: 0, # 'и' + 26: 0, # 'й' + 12: 1, # 'к' + 10: 0, # 'л' + 14: 0, # 'м' + 6: 1, # 'н' + 4: 3, # 'о' + 13: 0, # 'п' + 7: 0, # 'Ñ€' + 8: 0, # 'Ñ' + 5: 1, # 'Ñ‚' + 19: 0, # 'у' + 29: 0, # 'Ñ„' + 25: 0, # 'Ñ…' + 22: 1, # 'ц' + 21: 0, # 'ч' + 27: 0, # 'ш' + 24: 0, # 'щ' + 17: 0, # 'ÑŠ' + 52: 0, # 'ÑŒ' + 42: 1, # 'ÑŽ' + 16: 0, # 'Ñ' + 58: 0, # 'Ñ”' + 62: 0, # 'â„–' + }, + 42: { # 'ÑŽ' + 63: 0, # 'e' + 45: 0, # '\xad' + 31: 0, # 'Ð' + 32: 0, # 'Б' + 35: 0, # 'Ð’' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Ð' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Ð¥' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 1, # 'а' + 18: 2, # 'б' + 9: 1, # 'в' + 20: 2, # 'г' + 11: 2, # 'д' + 3: 1, # 'е' + 23: 2, # 'ж' + 15: 2, # 'з' + 2: 1, # 'и' + 26: 1, # 'й' + 12: 2, # 'к' + 10: 2, # 'л' + 14: 2, # 'м' + 6: 2, # 'н' + 4: 1, # 'о' + 13: 1, # 'п' + 7: 2, # 'Ñ€' + 8: 2, # 'Ñ' + 5: 2, # 'Ñ‚' + 19: 1, # 'у' + 29: 1, # 'Ñ„' + 25: 1, # 'Ñ…' + 22: 2, # 'ц' + 21: 3, # 'ч' + 27: 1, # 'ш' + 24: 1, # 'щ' + 17: 1, # 'ÑŠ' + 52: 0, # 'ÑŒ' + 42: 0, # 'ÑŽ' + 16: 1, # 'Ñ' + 58: 0, # 'Ñ”' + 62: 0, # 'â„–' + }, + 16: { # 'Ñ' + 63: 0, # 'e' + 45: 1, # '\xad' + 31: 0, # 'Ð' + 32: 0, # 'Б' + 35: 0, # 'Ð’' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Ð' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Ð¥' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 0, # 'а' + 18: 3, # 'б' + 9: 3, # 'в' + 20: 2, # 'г' + 11: 3, # 'д' + 3: 2, # 'е' + 23: 1, # 'ж' + 15: 2, # 'з' + 2: 1, # 'и' + 26: 2, # 'й' + 12: 3, # 'к' + 10: 3, # 'л' + 14: 3, # 'м' + 6: 3, # 'н' + 4: 1, # 'о' + 13: 2, # 'п' + 7: 2, # 'Ñ€' + 8: 3, # 'Ñ' + 5: 3, # 'Ñ‚' + 19: 1, # 'у' + 29: 1, # 'Ñ„' + 25: 3, # 'Ñ…' + 22: 2, # 'ц' + 21: 1, # 'ч' + 27: 1, # 'ш' + 24: 2, # 'щ' + 17: 0, # 'ÑŠ' + 52: 0, # 'ÑŒ' + 42: 0, # 'ÑŽ' + 16: 1, # 'Ñ' + 58: 0, # 'Ñ”' + 62: 0, # 'â„–' + }, + 58: { # 'Ñ”' + 63: 0, # 'e' + 45: 0, # '\xad' + 31: 0, # 'Ð' + 32: 0, # 'Б' + 35: 0, # 'Ð’' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Ð' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Ð¥' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 0, # 'а' + 18: 0, # 'б' + 9: 0, # 'в' + 20: 0, # 'г' + 11: 0, # 'д' + 3: 0, # 'е' + 23: 0, # 'ж' + 15: 0, # 'з' + 2: 0, # 'и' + 26: 0, # 'й' + 12: 0, # 'к' + 10: 0, # 'л' + 14: 0, # 'м' + 6: 0, # 'н' + 4: 0, # 'о' + 13: 0, # 'п' + 7: 0, # 'Ñ€' + 8: 0, # 'Ñ' + 5: 0, # 'Ñ‚' + 19: 0, # 'у' + 29: 0, # 'Ñ„' + 25: 0, # 'Ñ…' + 22: 0, # 'ц' + 21: 0, # 'ч' + 27: 0, # 'ш' + 24: 0, # 'щ' + 17: 0, # 'ÑŠ' + 52: 0, # 'ÑŒ' + 42: 0, # 'ÑŽ' + 16: 0, # 'Ñ' + 58: 0, # 'Ñ”' + 62: 0, # 'â„–' + }, + 62: { # 'â„–' + 63: 0, # 'e' + 45: 0, # '\xad' + 31: 0, # 'Ð' + 32: 0, # 'Б' + 35: 0, # 'Ð’' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Ð' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Ð¥' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 0, # 'а' + 18: 0, # 'б' + 9: 0, # 'в' + 20: 0, # 'г' + 11: 0, # 'д' + 3: 0, # 'е' + 23: 0, # 'ж' + 15: 0, # 'з' + 2: 0, # 'и' + 26: 0, # 'й' + 12: 0, # 'к' + 10: 0, # 'л' + 14: 0, # 'м' + 6: 0, # 'н' + 4: 0, # 'о' + 13: 0, # 'п' + 7: 0, # 'Ñ€' + 8: 0, # 'Ñ' + 5: 0, # 'Ñ‚' + 19: 0, # 'у' + 29: 0, # 'Ñ„' + 25: 0, # 'Ñ…' + 22: 0, # 'ц' + 21: 0, # 'ч' + 27: 0, # 'ш' + 24: 0, # 'щ' + 17: 0, # 'ÑŠ' + 52: 0, # 'ÑŒ' + 42: 0, # 'ÑŽ' + 16: 0, # 'Ñ' + 58: 0, # 'Ñ”' + 62: 0, # 'â„–' + }, +} + +# 255: Undefined characters that did not exist in training text +# 254: Carriage/Return +# 253: symbol (punctuation) that does not belong to word +# 252: 0 - 9 +# 251: Control characters + +# Character Mapping Table(s): +ISO_8859_5_BULGARIAN_CHAR_TO_ORDER = { + 0: 255, # '\x00' + 1: 255, # '\x01' + 2: 255, # '\x02' + 3: 255, # '\x03' + 4: 255, # '\x04' + 5: 255, # '\x05' + 6: 255, # '\x06' + 7: 255, # '\x07' + 8: 255, # '\x08' + 9: 255, # '\t' + 10: 254, # '\n' + 11: 255, # '\x0b' + 12: 255, # '\x0c' + 13: 254, # '\r' + 14: 255, # '\x0e' + 15: 255, # '\x0f' + 16: 255, # '\x10' + 17: 255, # '\x11' + 18: 255, # '\x12' + 19: 255, # '\x13' + 20: 255, # '\x14' + 21: 255, # '\x15' + 22: 255, # '\x16' + 23: 255, # '\x17' + 24: 255, # '\x18' + 25: 255, # '\x19' + 26: 255, # '\x1a' + 27: 255, # '\x1b' + 28: 255, # '\x1c' + 29: 255, # '\x1d' + 30: 255, # '\x1e' + 31: 255, # '\x1f' + 32: 253, # ' ' + 33: 253, # '!' + 34: 253, # '"' + 35: 253, # '#' + 36: 253, # '$' + 37: 253, # '%' + 38: 253, # '&' + 39: 253, # "'" + 40: 253, # '(' + 41: 253, # ')' + 42: 253, # '*' + 43: 253, # '+' + 44: 253, # ',' + 45: 253, # '-' + 46: 253, # '.' + 47: 253, # '/' + 48: 252, # '0' + 49: 252, # '1' + 50: 252, # '2' + 51: 252, # '3' + 52: 252, # '4' + 53: 252, # '5' + 54: 252, # '6' + 55: 252, # '7' + 56: 252, # '8' + 57: 252, # '9' + 58: 253, # ':' + 59: 253, # ';' + 60: 253, # '<' + 61: 253, # '=' + 62: 253, # '>' + 63: 253, # '?' + 64: 253, # '@' + 65: 77, # 'A' + 66: 90, # 'B' + 67: 99, # 'C' + 68: 100, # 'D' + 69: 72, # 'E' + 70: 109, # 'F' + 71: 107, # 'G' + 72: 101, # 'H' + 73: 79, # 'I' + 74: 185, # 'J' + 75: 81, # 'K' + 76: 102, # 'L' + 77: 76, # 'M' + 78: 94, # 'N' + 79: 82, # 'O' + 80: 110, # 'P' + 81: 186, # 'Q' + 82: 108, # 'R' + 83: 91, # 'S' + 84: 74, # 'T' + 85: 119, # 'U' + 86: 84, # 'V' + 87: 96, # 'W' + 88: 111, # 'X' + 89: 187, # 'Y' + 90: 115, # 'Z' + 91: 253, # '[' + 92: 253, # '\\' + 93: 253, # ']' + 94: 253, # '^' + 95: 253, # '_' + 96: 253, # '`' + 97: 65, # 'a' + 98: 69, # 'b' + 99: 70, # 'c' + 100: 66, # 'd' + 101: 63, # 'e' + 102: 68, # 'f' + 103: 112, # 'g' + 104: 103, # 'h' + 105: 92, # 'i' + 106: 194, # 'j' + 107: 104, # 'k' + 108: 95, # 'l' + 109: 86, # 'm' + 110: 87, # 'n' + 111: 71, # 'o' + 112: 116, # 'p' + 113: 195, # 'q' + 114: 85, # 'r' + 115: 93, # 's' + 116: 97, # 't' + 117: 113, # 'u' + 118: 196, # 'v' + 119: 197, # 'w' + 120: 198, # 'x' + 121: 199, # 'y' + 122: 200, # 'z' + 123: 253, # '{' + 124: 253, # '|' + 125: 253, # '}' + 126: 253, # '~' + 127: 253, # '\x7f' + 128: 194, # '\x80' + 129: 195, # '\x81' + 130: 196, # '\x82' + 131: 197, # '\x83' + 132: 198, # '\x84' + 133: 199, # '\x85' + 134: 200, # '\x86' + 135: 201, # '\x87' + 136: 202, # '\x88' + 137: 203, # '\x89' + 138: 204, # '\x8a' + 139: 205, # '\x8b' + 140: 206, # '\x8c' + 141: 207, # '\x8d' + 142: 208, # '\x8e' + 143: 209, # '\x8f' + 144: 210, # '\x90' + 145: 211, # '\x91' + 146: 212, # '\x92' + 147: 213, # '\x93' + 148: 214, # '\x94' + 149: 215, # '\x95' + 150: 216, # '\x96' + 151: 217, # '\x97' + 152: 218, # '\x98' + 153: 219, # '\x99' + 154: 220, # '\x9a' + 155: 221, # '\x9b' + 156: 222, # '\x9c' + 157: 223, # '\x9d' + 158: 224, # '\x9e' + 159: 225, # '\x9f' + 160: 81, # '\xa0' + 161: 226, # 'Ð' + 162: 227, # 'Ђ' + 163: 228, # 'Ѓ' + 164: 229, # 'Є' + 165: 230, # 'Ð…' + 166: 105, # 'І' + 167: 231, # 'Ї' + 168: 232, # 'Ј' + 169: 233, # 'Љ' + 170: 234, # 'Њ' + 171: 235, # 'Ћ' + 172: 236, # 'ÐŒ' + 173: 45, # '\xad' + 174: 237, # 'ÐŽ' + 175: 238, # 'Ð' + 176: 31, # 'Ð' + 177: 32, # 'Б' + 178: 35, # 'Ð’' + 179: 43, # 'Г' + 180: 37, # 'Д' + 181: 44, # 'Е' + 182: 55, # 'Ж' + 183: 47, # 'З' + 184: 40, # 'И' + 185: 59, # 'Й' + 186: 33, # 'К' + 187: 46, # 'Л' + 188: 38, # 'М' + 189: 36, # 'Ð' + 190: 41, # 'О' + 191: 30, # 'П' + 192: 39, # 'Р' + 193: 28, # 'С' + 194: 34, # 'Т' + 195: 51, # 'У' + 196: 48, # 'Ф' + 197: 49, # 'Ð¥' + 198: 53, # 'Ц' + 199: 50, # 'Ч' + 200: 54, # 'Ш' + 201: 57, # 'Щ' + 202: 61, # 'Ъ' + 203: 239, # 'Ы' + 204: 67, # 'Ь' + 205: 240, # 'Э' + 206: 60, # 'Ю' + 207: 56, # 'Я' + 208: 1, # 'а' + 209: 18, # 'б' + 210: 9, # 'в' + 211: 20, # 'г' + 212: 11, # 'д' + 213: 3, # 'е' + 214: 23, # 'ж' + 215: 15, # 'з' + 216: 2, # 'и' + 217: 26, # 'й' + 218: 12, # 'к' + 219: 10, # 'л' + 220: 14, # 'м' + 221: 6, # 'н' + 222: 4, # 'о' + 223: 13, # 'п' + 224: 7, # 'Ñ€' + 225: 8, # 'Ñ' + 226: 5, # 'Ñ‚' + 227: 19, # 'у' + 228: 29, # 'Ñ„' + 229: 25, # 'Ñ…' + 230: 22, # 'ц' + 231: 21, # 'ч' + 232: 27, # 'ш' + 233: 24, # 'щ' + 234: 17, # 'ÑŠ' + 235: 75, # 'Ñ‹' + 236: 52, # 'ÑŒ' + 237: 241, # 'Ñ' + 238: 42, # 'ÑŽ' + 239: 16, # 'Ñ' + 240: 62, # 'â„–' + 241: 242, # 'Ñ‘' + 242: 243, # 'Ñ’' + 243: 244, # 'Ñ“' + 244: 58, # 'Ñ”' + 245: 245, # 'Ñ•' + 246: 98, # 'Ñ–' + 247: 246, # 'Ñ—' + 248: 247, # 'ј' + 249: 248, # 'Ñ™' + 250: 249, # 'Ñš' + 251: 250, # 'Ñ›' + 252: 251, # 'Ñœ' + 253: 91, # '§' + 254: 252, # 'Ñž' + 255: 253, # 'ÑŸ' +} + +ISO_8859_5_BULGARIAN_MODEL = SingleByteCharSetModel(charset_name='ISO-8859-5', + language='Bulgarian', + char_to_order_map=ISO_8859_5_BULGARIAN_CHAR_TO_ORDER, + language_model=BULGARIAN_LANG_MODEL, + typical_positive_ratio=0.969392, + keep_ascii_letters=False, + alphabet='ÐБВГДЕЖЗИЙКЛМÐОПРСТУФХЦЧШЩЪЬЮЯабвгдежзийклмнопрÑтуфхцчшщъьюÑ') + +WINDOWS_1251_BULGARIAN_CHAR_TO_ORDER = { + 0: 255, # '\x00' + 1: 255, # '\x01' + 2: 255, # '\x02' + 3: 255, # '\x03' + 4: 255, # '\x04' + 5: 255, # '\x05' + 6: 255, # '\x06' + 7: 255, # '\x07' + 8: 255, # '\x08' + 9: 255, # '\t' + 10: 254, # '\n' + 11: 255, # '\x0b' + 12: 255, # '\x0c' + 13: 254, # '\r' + 14: 255, # '\x0e' + 15: 255, # '\x0f' + 16: 255, # '\x10' + 17: 255, # '\x11' + 18: 255, # '\x12' + 19: 255, # '\x13' + 20: 255, # '\x14' + 21: 255, # '\x15' + 22: 255, # '\x16' + 23: 255, # '\x17' + 24: 255, # '\x18' + 25: 255, # '\x19' + 26: 255, # '\x1a' + 27: 255, # '\x1b' + 28: 255, # '\x1c' + 29: 255, # '\x1d' + 30: 255, # '\x1e' + 31: 255, # '\x1f' + 32: 253, # ' ' + 33: 253, # '!' + 34: 253, # '"' + 35: 253, # '#' + 36: 253, # '$' + 37: 253, # '%' + 38: 253, # '&' + 39: 253, # "'" + 40: 253, # '(' + 41: 253, # ')' + 42: 253, # '*' + 43: 253, # '+' + 44: 253, # ',' + 45: 253, # '-' + 46: 253, # '.' + 47: 253, # '/' + 48: 252, # '0' + 49: 252, # '1' + 50: 252, # '2' + 51: 252, # '3' + 52: 252, # '4' + 53: 252, # '5' + 54: 252, # '6' + 55: 252, # '7' + 56: 252, # '8' + 57: 252, # '9' + 58: 253, # ':' + 59: 253, # ';' + 60: 253, # '<' + 61: 253, # '=' + 62: 253, # '>' + 63: 253, # '?' + 64: 253, # '@' + 65: 77, # 'A' + 66: 90, # 'B' + 67: 99, # 'C' + 68: 100, # 'D' + 69: 72, # 'E' + 70: 109, # 'F' + 71: 107, # 'G' + 72: 101, # 'H' + 73: 79, # 'I' + 74: 185, # 'J' + 75: 81, # 'K' + 76: 102, # 'L' + 77: 76, # 'M' + 78: 94, # 'N' + 79: 82, # 'O' + 80: 110, # 'P' + 81: 186, # 'Q' + 82: 108, # 'R' + 83: 91, # 'S' + 84: 74, # 'T' + 85: 119, # 'U' + 86: 84, # 'V' + 87: 96, # 'W' + 88: 111, # 'X' + 89: 187, # 'Y' + 90: 115, # 'Z' + 91: 253, # '[' + 92: 253, # '\\' + 93: 253, # ']' + 94: 253, # '^' + 95: 253, # '_' + 96: 253, # '`' + 97: 65, # 'a' + 98: 69, # 'b' + 99: 70, # 'c' + 100: 66, # 'd' + 101: 63, # 'e' + 102: 68, # 'f' + 103: 112, # 'g' + 104: 103, # 'h' + 105: 92, # 'i' + 106: 194, # 'j' + 107: 104, # 'k' + 108: 95, # 'l' + 109: 86, # 'm' + 110: 87, # 'n' + 111: 71, # 'o' + 112: 116, # 'p' + 113: 195, # 'q' + 114: 85, # 'r' + 115: 93, # 's' + 116: 97, # 't' + 117: 113, # 'u' + 118: 196, # 'v' + 119: 197, # 'w' + 120: 198, # 'x' + 121: 199, # 'y' + 122: 200, # 'z' + 123: 253, # '{' + 124: 253, # '|' + 125: 253, # '}' + 126: 253, # '~' + 127: 253, # '\x7f' + 128: 206, # 'Ђ' + 129: 207, # 'Ѓ' + 130: 208, # '‚' + 131: 209, # 'Ñ“' + 132: 210, # '„' + 133: 211, # '…' + 134: 212, # '†' + 135: 213, # '‡' + 136: 120, # '€' + 137: 214, # '‰' + 138: 215, # 'Љ' + 139: 216, # '‹' + 140: 217, # 'Њ' + 141: 218, # 'ÐŒ' + 142: 219, # 'Ћ' + 143: 220, # 'Ð' + 144: 221, # 'Ñ’' + 145: 78, # '‘' + 146: 64, # '’' + 147: 83, # '“' + 148: 121, # 'â€' + 149: 98, # '•' + 150: 117, # '–' + 151: 105, # '—' + 152: 222, # None + 153: 223, # 'â„¢' + 154: 224, # 'Ñ™' + 155: 225, # '›' + 156: 226, # 'Ñš' + 157: 227, # 'Ñœ' + 158: 228, # 'Ñ›' + 159: 229, # 'ÑŸ' + 160: 88, # '\xa0' + 161: 230, # 'ÐŽ' + 162: 231, # 'Ñž' + 163: 232, # 'Ј' + 164: 233, # '¤' + 165: 122, # 'Ò' + 166: 89, # '¦' + 167: 106, # '§' + 168: 234, # 'Ð' + 169: 235, # '©' + 170: 236, # 'Є' + 171: 237, # '«' + 172: 238, # '¬' + 173: 45, # '\xad' + 174: 239, # '®' + 175: 240, # 'Ї' + 176: 73, # '°' + 177: 80, # '±' + 178: 118, # 'І' + 179: 114, # 'Ñ–' + 180: 241, # 'Ò‘' + 181: 242, # 'µ' + 182: 243, # '¶' + 183: 244, # '·' + 184: 245, # 'Ñ‘' + 185: 62, # 'â„–' + 186: 58, # 'Ñ”' + 187: 246, # '»' + 188: 247, # 'ј' + 189: 248, # 'Ð…' + 190: 249, # 'Ñ•' + 191: 250, # 'Ñ—' + 192: 31, # 'Ð' + 193: 32, # 'Б' + 194: 35, # 'Ð’' + 195: 43, # 'Г' + 196: 37, # 'Д' + 197: 44, # 'Е' + 198: 55, # 'Ж' + 199: 47, # 'З' + 200: 40, # 'И' + 201: 59, # 'Й' + 202: 33, # 'К' + 203: 46, # 'Л' + 204: 38, # 'М' + 205: 36, # 'Ð' + 206: 41, # 'О' + 207: 30, # 'П' + 208: 39, # 'Р' + 209: 28, # 'С' + 210: 34, # 'Т' + 211: 51, # 'У' + 212: 48, # 'Ф' + 213: 49, # 'Ð¥' + 214: 53, # 'Ц' + 215: 50, # 'Ч' + 216: 54, # 'Ш' + 217: 57, # 'Щ' + 218: 61, # 'Ъ' + 219: 251, # 'Ы' + 220: 67, # 'Ь' + 221: 252, # 'Э' + 222: 60, # 'Ю' + 223: 56, # 'Я' + 224: 1, # 'а' + 225: 18, # 'б' + 226: 9, # 'в' + 227: 20, # 'г' + 228: 11, # 'д' + 229: 3, # 'е' + 230: 23, # 'ж' + 231: 15, # 'з' + 232: 2, # 'и' + 233: 26, # 'й' + 234: 12, # 'к' + 235: 10, # 'л' + 236: 14, # 'м' + 237: 6, # 'н' + 238: 4, # 'о' + 239: 13, # 'п' + 240: 7, # 'Ñ€' + 241: 8, # 'Ñ' + 242: 5, # 'Ñ‚' + 243: 19, # 'у' + 244: 29, # 'Ñ„' + 245: 25, # 'Ñ…' + 246: 22, # 'ц' + 247: 21, # 'ч' + 248: 27, # 'ш' + 249: 24, # 'щ' + 250: 17, # 'ÑŠ' + 251: 75, # 'Ñ‹' + 252: 52, # 'ÑŒ' + 253: 253, # 'Ñ' + 254: 42, # 'ÑŽ' + 255: 16, # 'Ñ' +} + +WINDOWS_1251_BULGARIAN_MODEL = SingleByteCharSetModel(charset_name='windows-1251', + language='Bulgarian', + char_to_order_map=WINDOWS_1251_BULGARIAN_CHAR_TO_ORDER, + language_model=BULGARIAN_LANG_MODEL, + typical_positive_ratio=0.969392, + keep_ascii_letters=False, + alphabet='ÐБВГДЕЖЗИЙКЛМÐОПРСТУФХЦЧШЩЪЬЮЯабвгдежзийклмнопрÑтуфхцчшщъьюÑ') + diff --git a/venv/Lib/site-packages/pip/_vendor/chardet/langgreekmodel.py b/venv/Lib/site-packages/pip/_vendor/chardet/langgreekmodel.py new file mode 100644 index 0000000..d99528e --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/chardet/langgreekmodel.py @@ -0,0 +1,4398 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from pip._vendor.chardet.sbcharsetprober import SingleByteCharSetModel + + +# 3: Positive +# 2: Likely +# 1: Unlikely +# 0: Negative + +GREEK_LANG_MODEL = { + 60: { # 'e' + 60: 2, # 'e' + 55: 1, # 'o' + 58: 2, # 't' + 36: 1, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'ÎŒ' + 31: 0, # 'Α' + 51: 0, # 'Î’' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Î' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Î¥' + 56: 0, # 'Φ' + 50: 1, # 'Χ' + 57: 0, # 'Ω' + 17: 0, # 'ά' + 18: 0, # 'έ' + 22: 0, # 'ή' + 15: 0, # 'ί' + 1: 0, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 0, # 'ε' + 32: 0, # 'ζ' + 13: 0, # 'η' + 25: 0, # 'θ' + 5: 0, # 'ι' + 11: 0, # 'κ' + 16: 0, # 'λ' + 10: 0, # 'μ' + 6: 0, # 'ν' + 30: 0, # 'ξ' + 4: 0, # 'ο' + 9: 0, # 'Ï€' + 8: 0, # 'Ï' + 14: 0, # 'Ï‚' + 7: 0, # 'σ' + 2: 0, # 'Ï„' + 12: 0, # 'Ï…' + 28: 0, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 0, # 'ω' + 19: 0, # 'ÏŒ' + 26: 0, # 'Ï' + 27: 0, # 'ÏŽ' + }, + 55: { # 'o' + 60: 0, # 'e' + 55: 2, # 'o' + 58: 2, # 't' + 36: 1, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'ÎŒ' + 31: 0, # 'Α' + 51: 0, # 'Î’' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Î' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Î¥' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 0, # 'ά' + 18: 0, # 'έ' + 22: 0, # 'ή' + 15: 0, # 'ί' + 1: 0, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 0, # 'ε' + 32: 0, # 'ζ' + 13: 0, # 'η' + 25: 0, # 'θ' + 5: 0, # 'ι' + 11: 0, # 'κ' + 16: 0, # 'λ' + 10: 0, # 'μ' + 6: 1, # 'ν' + 30: 0, # 'ξ' + 4: 0, # 'ο' + 9: 0, # 'Ï€' + 8: 0, # 'Ï' + 14: 0, # 'Ï‚' + 7: 0, # 'σ' + 2: 0, # 'Ï„' + 12: 1, # 'Ï…' + 28: 0, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 0, # 'ω' + 19: 0, # 'ÏŒ' + 26: 0, # 'Ï' + 27: 0, # 'ÏŽ' + }, + 58: { # 't' + 60: 2, # 'e' + 55: 1, # 'o' + 58: 1, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'ÎŒ' + 31: 0, # 'Α' + 51: 0, # 'Î’' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Î' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Î¥' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 2, # 'ά' + 18: 0, # 'έ' + 22: 0, # 'ή' + 15: 0, # 'ί' + 1: 0, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 0, # 'ε' + 32: 0, # 'ζ' + 13: 0, # 'η' + 25: 0, # 'θ' + 5: 0, # 'ι' + 11: 0, # 'κ' + 16: 0, # 'λ' + 10: 0, # 'μ' + 6: 0, # 'ν' + 30: 0, # 'ξ' + 4: 1, # 'ο' + 9: 0, # 'Ï€' + 8: 0, # 'Ï' + 14: 0, # 'Ï‚' + 7: 0, # 'σ' + 2: 0, # 'Ï„' + 12: 0, # 'Ï…' + 28: 0, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 0, # 'ω' + 19: 0, # 'ÏŒ' + 26: 0, # 'Ï' + 27: 0, # 'ÏŽ' + }, + 36: { # '·' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'ÎŒ' + 31: 0, # 'Α' + 51: 0, # 'Î’' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Î' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Î¥' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 0, # 'ά' + 18: 0, # 'έ' + 22: 0, # 'ή' + 15: 0, # 'ί' + 1: 0, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 0, # 'ε' + 32: 0, # 'ζ' + 13: 0, # 'η' + 25: 0, # 'θ' + 5: 0, # 'ι' + 11: 0, # 'κ' + 16: 0, # 'λ' + 10: 0, # 'μ' + 6: 0, # 'ν' + 30: 0, # 'ξ' + 4: 0, # 'ο' + 9: 0, # 'Ï€' + 8: 0, # 'Ï' + 14: 0, # 'Ï‚' + 7: 0, # 'σ' + 2: 0, # 'Ï„' + 12: 0, # 'Ï…' + 28: 0, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 0, # 'ω' + 19: 0, # 'ÏŒ' + 26: 0, # 'Ï' + 27: 0, # 'ÏŽ' + }, + 61: { # 'Ά' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'ÎŒ' + 31: 0, # 'Α' + 51: 0, # 'Î’' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Î' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Î¥' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 0, # 'ά' + 18: 0, # 'έ' + 22: 0, # 'ή' + 15: 0, # 'ί' + 1: 0, # 'α' + 29: 0, # 'β' + 20: 1, # 'γ' + 21: 2, # 'δ' + 3: 0, # 'ε' + 32: 0, # 'ζ' + 13: 0, # 'η' + 25: 0, # 'θ' + 5: 0, # 'ι' + 11: 0, # 'κ' + 16: 2, # 'λ' + 10: 0, # 'μ' + 6: 0, # 'ν' + 30: 0, # 'ξ' + 4: 0, # 'ο' + 9: 1, # 'Ï€' + 8: 2, # 'Ï' + 14: 0, # 'Ï‚' + 7: 0, # 'σ' + 2: 0, # 'Ï„' + 12: 0, # 'Ï…' + 28: 0, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 0, # 'ω' + 19: 0, # 'ÏŒ' + 26: 0, # 'Ï' + 27: 0, # 'ÏŽ' + }, + 46: { # 'Έ' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'ÎŒ' + 31: 0, # 'Α' + 51: 0, # 'Î’' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Î' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Î¥' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 0, # 'ά' + 18: 0, # 'έ' + 22: 0, # 'ή' + 15: 0, # 'ί' + 1: 0, # 'α' + 29: 2, # 'β' + 20: 2, # 'γ' + 21: 0, # 'δ' + 3: 0, # 'ε' + 32: 0, # 'ζ' + 13: 0, # 'η' + 25: 0, # 'θ' + 5: 0, # 'ι' + 11: 2, # 'κ' + 16: 2, # 'λ' + 10: 0, # 'μ' + 6: 3, # 'ν' + 30: 2, # 'ξ' + 4: 0, # 'ο' + 9: 2, # 'Ï€' + 8: 2, # 'Ï' + 14: 0, # 'Ï‚' + 7: 1, # 'σ' + 2: 2, # 'Ï„' + 12: 0, # 'Ï…' + 28: 2, # 'φ' + 23: 3, # 'χ' + 42: 0, # 'ψ' + 24: 0, # 'ω' + 19: 0, # 'ÏŒ' + 26: 0, # 'Ï' + 27: 0, # 'ÏŽ' + }, + 54: { # 'ÎŒ' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'ÎŒ' + 31: 0, # 'Α' + 51: 0, # 'Î’' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Î' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Î¥' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 0, # 'ά' + 18: 0, # 'έ' + 22: 0, # 'ή' + 15: 0, # 'ί' + 1: 0, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 0, # 'ε' + 32: 0, # 'ζ' + 13: 0, # 'η' + 25: 0, # 'θ' + 5: 0, # 'ι' + 11: 0, # 'κ' + 16: 2, # 'λ' + 10: 2, # 'μ' + 6: 2, # 'ν' + 30: 0, # 'ξ' + 4: 0, # 'ο' + 9: 2, # 'Ï€' + 8: 0, # 'Ï' + 14: 0, # 'Ï‚' + 7: 2, # 'σ' + 2: 3, # 'Ï„' + 12: 0, # 'Ï…' + 28: 0, # 'φ' + 23: 2, # 'χ' + 42: 0, # 'ψ' + 24: 0, # 'ω' + 19: 0, # 'ÏŒ' + 26: 0, # 'Ï' + 27: 0, # 'ÏŽ' + }, + 31: { # 'Α' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'ÎŒ' + 31: 0, # 'Α' + 51: 2, # 'Î’' + 43: 2, # 'Γ' + 41: 1, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 2, # 'Θ' + 47: 2, # 'Ι' + 44: 2, # 'Κ' + 53: 2, # 'Λ' + 38: 2, # 'Μ' + 49: 2, # 'Î' + 59: 1, # 'Ξ' + 39: 0, # 'Ο' + 35: 2, # 'Π' + 48: 2, # 'Ρ' + 37: 2, # 'Σ' + 33: 2, # 'Τ' + 45: 2, # 'Î¥' + 56: 2, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 0, # 'ά' + 18: 0, # 'έ' + 22: 0, # 'ή' + 15: 0, # 'ί' + 1: 0, # 'α' + 29: 0, # 'β' + 20: 2, # 'γ' + 21: 0, # 'δ' + 3: 0, # 'ε' + 32: 0, # 'ζ' + 13: 0, # 'η' + 25: 1, # 'θ' + 5: 0, # 'ι' + 11: 2, # 'κ' + 16: 3, # 'λ' + 10: 2, # 'μ' + 6: 3, # 'ν' + 30: 2, # 'ξ' + 4: 0, # 'ο' + 9: 3, # 'Ï€' + 8: 3, # 'Ï' + 14: 2, # 'Ï‚' + 7: 2, # 'σ' + 2: 0, # 'Ï„' + 12: 3, # 'Ï…' + 28: 2, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 0, # 'ω' + 19: 0, # 'ÏŒ' + 26: 2, # 'Ï' + 27: 0, # 'ÏŽ' + }, + 51: { # 'Î’' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'ÎŒ' + 31: 2, # 'Α' + 51: 0, # 'Î’' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 1, # 'Ε' + 40: 1, # 'Η' + 52: 0, # 'Θ' + 47: 1, # 'Ι' + 44: 0, # 'Κ' + 53: 1, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Î' + 59: 0, # 'Ξ' + 39: 2, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Î¥' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 2, # 'ά' + 18: 2, # 'έ' + 22: 2, # 'ή' + 15: 0, # 'ί' + 1: 2, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 2, # 'ε' + 32: 0, # 'ζ' + 13: 0, # 'η' + 25: 0, # 'θ' + 5: 2, # 'ι' + 11: 0, # 'κ' + 16: 2, # 'λ' + 10: 0, # 'μ' + 6: 0, # 'ν' + 30: 0, # 'ξ' + 4: 2, # 'ο' + 9: 0, # 'Ï€' + 8: 2, # 'Ï' + 14: 0, # 'Ï‚' + 7: 0, # 'σ' + 2: 0, # 'Ï„' + 12: 0, # 'Ï…' + 28: 0, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 0, # 'ω' + 19: 0, # 'ÏŒ' + 26: 0, # 'Ï' + 27: 0, # 'ÏŽ' + }, + 43: { # 'Γ' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'ÎŒ' + 31: 1, # 'Α' + 51: 0, # 'Î’' + 43: 2, # 'Γ' + 41: 0, # 'Δ' + 34: 2, # 'Ε' + 40: 1, # 'Η' + 52: 0, # 'Θ' + 47: 2, # 'Ι' + 44: 1, # 'Κ' + 53: 1, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Î' + 59: 0, # 'Ξ' + 39: 1, # 'Ο' + 35: 0, # 'Π' + 48: 2, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 2, # 'Î¥' + 56: 0, # 'Φ' + 50: 1, # 'Χ' + 57: 2, # 'Ω' + 17: 0, # 'ά' + 18: 0, # 'έ' + 22: 0, # 'ή' + 15: 2, # 'ί' + 1: 2, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 2, # 'ε' + 32: 0, # 'ζ' + 13: 0, # 'η' + 25: 0, # 'θ' + 5: 3, # 'ι' + 11: 0, # 'κ' + 16: 2, # 'λ' + 10: 0, # 'μ' + 6: 2, # 'ν' + 30: 0, # 'ξ' + 4: 0, # 'ο' + 9: 0, # 'Ï€' + 8: 2, # 'Ï' + 14: 0, # 'Ï‚' + 7: 0, # 'σ' + 2: 0, # 'Ï„' + 12: 0, # 'Ï…' + 28: 0, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 0, # 'ω' + 19: 0, # 'ÏŒ' + 26: 0, # 'Ï' + 27: 0, # 'ÏŽ' + }, + 41: { # 'Δ' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'ÎŒ' + 31: 0, # 'Α' + 51: 0, # 'Î’' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 2, # 'Ε' + 40: 2, # 'Η' + 52: 0, # 'Θ' + 47: 2, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Î' + 59: 0, # 'Ξ' + 39: 2, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Î¥' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 2, # 'Ω' + 17: 0, # 'ά' + 18: 0, # 'έ' + 22: 2, # 'ή' + 15: 2, # 'ί' + 1: 0, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 3, # 'ε' + 32: 0, # 'ζ' + 13: 2, # 'η' + 25: 0, # 'θ' + 5: 3, # 'ι' + 11: 0, # 'κ' + 16: 0, # 'λ' + 10: 0, # 'μ' + 6: 0, # 'ν' + 30: 0, # 'ξ' + 4: 2, # 'ο' + 9: 0, # 'Ï€' + 8: 2, # 'Ï' + 14: 0, # 'Ï‚' + 7: 0, # 'σ' + 2: 0, # 'Ï„' + 12: 2, # 'Ï…' + 28: 0, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 2, # 'ω' + 19: 1, # 'ÏŒ' + 26: 2, # 'Ï' + 27: 2, # 'ÏŽ' + }, + 34: { # 'Ε' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'ÎŒ' + 31: 2, # 'Α' + 51: 0, # 'Î’' + 43: 2, # 'Γ' + 41: 2, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 2, # 'Ι' + 44: 2, # 'Κ' + 53: 2, # 'Λ' + 38: 2, # 'Μ' + 49: 2, # 'Î' + 59: 1, # 'Ξ' + 39: 0, # 'Ο' + 35: 2, # 'Π' + 48: 2, # 'Ρ' + 37: 2, # 'Σ' + 33: 2, # 'Τ' + 45: 2, # 'Î¥' + 56: 0, # 'Φ' + 50: 2, # 'Χ' + 57: 2, # 'Ω' + 17: 3, # 'ά' + 18: 0, # 'έ' + 22: 0, # 'ή' + 15: 3, # 'ί' + 1: 0, # 'α' + 29: 0, # 'β' + 20: 3, # 'γ' + 21: 2, # 'δ' + 3: 1, # 'ε' + 32: 0, # 'ζ' + 13: 0, # 'η' + 25: 1, # 'θ' + 5: 2, # 'ι' + 11: 3, # 'κ' + 16: 3, # 'λ' + 10: 2, # 'μ' + 6: 3, # 'ν' + 30: 2, # 'ξ' + 4: 0, # 'ο' + 9: 3, # 'Ï€' + 8: 2, # 'Ï' + 14: 0, # 'Ï‚' + 7: 2, # 'σ' + 2: 2, # 'Ï„' + 12: 2, # 'Ï…' + 28: 2, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 0, # 'ω' + 19: 0, # 'ÏŒ' + 26: 1, # 'Ï' + 27: 0, # 'ÏŽ' + }, + 40: { # 'Η' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'ÎŒ' + 31: 0, # 'Α' + 51: 0, # 'Î’' + 43: 1, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 2, # 'Θ' + 47: 0, # 'Ι' + 44: 2, # 'Κ' + 53: 0, # 'Λ' + 38: 2, # 'Μ' + 49: 2, # 'Î' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 2, # 'Π' + 48: 2, # 'Ρ' + 37: 2, # 'Σ' + 33: 2, # 'Τ' + 45: 1, # 'Î¥' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 0, # 'ά' + 18: 0, # 'έ' + 22: 0, # 'ή' + 15: 0, # 'ί' + 1: 0, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 0, # 'ε' + 32: 0, # 'ζ' + 13: 0, # 'η' + 25: 0, # 'θ' + 5: 0, # 'ι' + 11: 0, # 'κ' + 16: 2, # 'λ' + 10: 0, # 'μ' + 6: 1, # 'ν' + 30: 0, # 'ξ' + 4: 0, # 'ο' + 9: 0, # 'Ï€' + 8: 0, # 'Ï' + 14: 0, # 'Ï‚' + 7: 0, # 'σ' + 2: 0, # 'Ï„' + 12: 0, # 'Ï…' + 28: 0, # 'φ' + 23: 1, # 'χ' + 42: 0, # 'ψ' + 24: 0, # 'ω' + 19: 0, # 'ÏŒ' + 26: 0, # 'Ï' + 27: 0, # 'ÏŽ' + }, + 52: { # 'Θ' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'ÎŒ' + 31: 2, # 'Α' + 51: 0, # 'Î’' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 2, # 'Ε' + 40: 2, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Î' + 59: 0, # 'Ξ' + 39: 2, # 'Ο' + 35: 0, # 'Π' + 48: 1, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 1, # 'Î¥' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 0, # 'ά' + 18: 2, # 'έ' + 22: 0, # 'ή' + 15: 0, # 'ί' + 1: 3, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 2, # 'ε' + 32: 0, # 'ζ' + 13: 0, # 'η' + 25: 0, # 'θ' + 5: 0, # 'ι' + 11: 0, # 'κ' + 16: 0, # 'λ' + 10: 0, # 'μ' + 6: 0, # 'ν' + 30: 0, # 'ξ' + 4: 0, # 'ο' + 9: 0, # 'Ï€' + 8: 0, # 'Ï' + 14: 0, # 'Ï‚' + 7: 0, # 'σ' + 2: 0, # 'Ï„' + 12: 2, # 'Ï…' + 28: 0, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 0, # 'ω' + 19: 0, # 'ÏŒ' + 26: 2, # 'Ï' + 27: 0, # 'ÏŽ' + }, + 47: { # 'Ι' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'ÎŒ' + 31: 2, # 'Α' + 51: 1, # 'Î’' + 43: 1, # 'Γ' + 41: 2, # 'Δ' + 34: 2, # 'Ε' + 40: 2, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 2, # 'Κ' + 53: 2, # 'Λ' + 38: 2, # 'Μ' + 49: 2, # 'Î' + 59: 0, # 'Ξ' + 39: 2, # 'Ο' + 35: 0, # 'Π' + 48: 2, # 'Ρ' + 37: 2, # 'Σ' + 33: 2, # 'Τ' + 45: 0, # 'Î¥' + 56: 2, # 'Φ' + 50: 0, # 'Χ' + 57: 2, # 'Ω' + 17: 0, # 'ά' + 18: 0, # 'έ' + 22: 0, # 'ή' + 15: 0, # 'ί' + 1: 2, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 2, # 'δ' + 3: 0, # 'ε' + 32: 0, # 'ζ' + 13: 0, # 'η' + 25: 0, # 'θ' + 5: 0, # 'ι' + 11: 0, # 'κ' + 16: 0, # 'λ' + 10: 0, # 'μ' + 6: 1, # 'ν' + 30: 0, # 'ξ' + 4: 2, # 'ο' + 9: 0, # 'Ï€' + 8: 0, # 'Ï' + 14: 0, # 'Ï‚' + 7: 2, # 'σ' + 2: 1, # 'Ï„' + 12: 0, # 'Ï…' + 28: 0, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 1, # 'ω' + 19: 0, # 'ÏŒ' + 26: 0, # 'Ï' + 27: 0, # 'ÏŽ' + }, + 44: { # 'Κ' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'ÎŒ' + 31: 2, # 'Α' + 51: 0, # 'Î’' + 43: 0, # 'Γ' + 41: 1, # 'Δ' + 34: 2, # 'Ε' + 40: 2, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 1, # 'Μ' + 49: 0, # 'Î' + 59: 0, # 'Ξ' + 39: 2, # 'Ο' + 35: 0, # 'Π' + 48: 2, # 'Ρ' + 37: 0, # 'Σ' + 33: 1, # 'Τ' + 45: 2, # 'Î¥' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 1, # 'Ω' + 17: 3, # 'ά' + 18: 0, # 'έ' + 22: 0, # 'ή' + 15: 0, # 'ί' + 1: 3, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 2, # 'ε' + 32: 0, # 'ζ' + 13: 0, # 'η' + 25: 0, # 'θ' + 5: 2, # 'ι' + 11: 0, # 'κ' + 16: 2, # 'λ' + 10: 0, # 'μ' + 6: 0, # 'ν' + 30: 0, # 'ξ' + 4: 2, # 'ο' + 9: 0, # 'Ï€' + 8: 2, # 'Ï' + 14: 0, # 'Ï‚' + 7: 0, # 'σ' + 2: 0, # 'Ï„' + 12: 2, # 'Ï…' + 28: 0, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 0, # 'ω' + 19: 2, # 'ÏŒ' + 26: 2, # 'Ï' + 27: 2, # 'ÏŽ' + }, + 53: { # 'Λ' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'ÎŒ' + 31: 2, # 'Α' + 51: 0, # 'Î’' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 2, # 'Ε' + 40: 2, # 'Η' + 52: 0, # 'Θ' + 47: 2, # 'Ι' + 44: 0, # 'Κ' + 53: 2, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Î' + 59: 0, # 'Ξ' + 39: 2, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 2, # 'Σ' + 33: 0, # 'Τ' + 45: 2, # 'Î¥' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 2, # 'Ω' + 17: 2, # 'ά' + 18: 2, # 'έ' + 22: 0, # 'ή' + 15: 2, # 'ί' + 1: 2, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 2, # 'ε' + 32: 0, # 'ζ' + 13: 0, # 'η' + 25: 0, # 'θ' + 5: 1, # 'ι' + 11: 0, # 'κ' + 16: 0, # 'λ' + 10: 0, # 'μ' + 6: 0, # 'ν' + 30: 0, # 'ξ' + 4: 2, # 'ο' + 9: 0, # 'Ï€' + 8: 0, # 'Ï' + 14: 0, # 'Ï‚' + 7: 0, # 'σ' + 2: 0, # 'Ï„' + 12: 2, # 'Ï…' + 28: 0, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 0, # 'ω' + 19: 2, # 'ÏŒ' + 26: 2, # 'Ï' + 27: 0, # 'ÏŽ' + }, + 38: { # 'Μ' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'ÎŒ' + 31: 2, # 'Α' + 51: 2, # 'Î’' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 2, # 'Ε' + 40: 2, # 'Η' + 52: 0, # 'Θ' + 47: 2, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 2, # 'Μ' + 49: 0, # 'Î' + 59: 0, # 'Ξ' + 39: 2, # 'Ο' + 35: 2, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Î¥' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 2, # 'ά' + 18: 2, # 'έ' + 22: 2, # 'ή' + 15: 2, # 'ί' + 1: 2, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 3, # 'ε' + 32: 0, # 'ζ' + 13: 2, # 'η' + 25: 0, # 'θ' + 5: 3, # 'ι' + 11: 0, # 'κ' + 16: 0, # 'λ' + 10: 0, # 'μ' + 6: 0, # 'ν' + 30: 0, # 'ξ' + 4: 2, # 'ο' + 9: 3, # 'Ï€' + 8: 0, # 'Ï' + 14: 0, # 'Ï‚' + 7: 0, # 'σ' + 2: 0, # 'Ï„' + 12: 2, # 'Ï…' + 28: 0, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 0, # 'ω' + 19: 2, # 'ÏŒ' + 26: 0, # 'Ï' + 27: 0, # 'ÏŽ' + }, + 49: { # 'Î' + 60: 2, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'ÎŒ' + 31: 2, # 'Α' + 51: 0, # 'Î’' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 2, # 'Ε' + 40: 2, # 'Η' + 52: 0, # 'Θ' + 47: 2, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Î' + 59: 0, # 'Ξ' + 39: 2, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 2, # 'Τ' + 45: 0, # 'Î¥' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 2, # 'Ω' + 17: 0, # 'ά' + 18: 2, # 'έ' + 22: 0, # 'ή' + 15: 2, # 'ί' + 1: 2, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 1, # 'ε' + 32: 0, # 'ζ' + 13: 0, # 'η' + 25: 0, # 'θ' + 5: 0, # 'ι' + 11: 0, # 'κ' + 16: 0, # 'λ' + 10: 0, # 'μ' + 6: 0, # 'ν' + 30: 0, # 'ξ' + 4: 2, # 'ο' + 9: 0, # 'Ï€' + 8: 0, # 'Ï' + 14: 0, # 'Ï‚' + 7: 0, # 'σ' + 2: 0, # 'Ï„' + 12: 0, # 'Ï…' + 28: 0, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 1, # 'ω' + 19: 2, # 'ÏŒ' + 26: 0, # 'Ï' + 27: 0, # 'ÏŽ' + }, + 59: { # 'Ξ' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'ÎŒ' + 31: 0, # 'Α' + 51: 0, # 'Î’' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 1, # 'Ε' + 40: 1, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Î' + 59: 0, # 'Ξ' + 39: 1, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Î¥' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 0, # 'ά' + 18: 2, # 'έ' + 22: 0, # 'ή' + 15: 0, # 'ί' + 1: 2, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 2, # 'ε' + 32: 0, # 'ζ' + 13: 0, # 'η' + 25: 0, # 'θ' + 5: 0, # 'ι' + 11: 0, # 'κ' + 16: 0, # 'λ' + 10: 0, # 'μ' + 6: 0, # 'ν' + 30: 0, # 'ξ' + 4: 0, # 'ο' + 9: 0, # 'Ï€' + 8: 0, # 'Ï' + 14: 0, # 'Ï‚' + 7: 0, # 'σ' + 2: 0, # 'Ï„' + 12: 0, # 'Ï…' + 28: 0, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 0, # 'ω' + 19: 0, # 'ÏŒ' + 26: 0, # 'Ï' + 27: 0, # 'ÏŽ' + }, + 39: { # 'Ο' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'ÎŒ' + 31: 0, # 'Α' + 51: 1, # 'Î’' + 43: 2, # 'Γ' + 41: 2, # 'Δ' + 34: 2, # 'Ε' + 40: 1, # 'Η' + 52: 2, # 'Θ' + 47: 2, # 'Ι' + 44: 2, # 'Κ' + 53: 2, # 'Λ' + 38: 2, # 'Μ' + 49: 2, # 'Î' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 2, # 'Π' + 48: 2, # 'Ρ' + 37: 2, # 'Σ' + 33: 2, # 'Τ' + 45: 2, # 'Î¥' + 56: 2, # 'Φ' + 50: 2, # 'Χ' + 57: 0, # 'Ω' + 17: 0, # 'ά' + 18: 0, # 'έ' + 22: 0, # 'ή' + 15: 0, # 'ί' + 1: 0, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 2, # 'δ' + 3: 0, # 'ε' + 32: 0, # 'ζ' + 13: 0, # 'η' + 25: 0, # 'θ' + 5: 3, # 'ι' + 11: 2, # 'κ' + 16: 2, # 'λ' + 10: 2, # 'μ' + 6: 2, # 'ν' + 30: 0, # 'ξ' + 4: 0, # 'ο' + 9: 2, # 'Ï€' + 8: 2, # 'Ï' + 14: 0, # 'Ï‚' + 7: 0, # 'σ' + 2: 2, # 'Ï„' + 12: 2, # 'Ï…' + 28: 1, # 'φ' + 23: 1, # 'χ' + 42: 0, # 'ψ' + 24: 0, # 'ω' + 19: 0, # 'ÏŒ' + 26: 2, # 'Ï' + 27: 0, # 'ÏŽ' + }, + 35: { # 'Π' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'ÎŒ' + 31: 2, # 'Α' + 51: 0, # 'Î’' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 2, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 2, # 'Ι' + 44: 0, # 'Κ' + 53: 2, # 'Λ' + 38: 1, # 'Μ' + 49: 0, # 'Î' + 59: 0, # 'Ξ' + 39: 2, # 'Ο' + 35: 0, # 'Π' + 48: 2, # 'Ρ' + 37: 0, # 'Σ' + 33: 1, # 'Τ' + 45: 0, # 'Î¥' + 56: 0, # 'Φ' + 50: 1, # 'Χ' + 57: 2, # 'Ω' + 17: 2, # 'ά' + 18: 1, # 'έ' + 22: 1, # 'ή' + 15: 2, # 'ί' + 1: 3, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 3, # 'ε' + 32: 0, # 'ζ' + 13: 2, # 'η' + 25: 0, # 'θ' + 5: 2, # 'ι' + 11: 0, # 'κ' + 16: 2, # 'λ' + 10: 0, # 'μ' + 6: 2, # 'ν' + 30: 0, # 'ξ' + 4: 3, # 'ο' + 9: 0, # 'Ï€' + 8: 3, # 'Ï' + 14: 0, # 'Ï‚' + 7: 0, # 'σ' + 2: 0, # 'Ï„' + 12: 2, # 'Ï…' + 28: 0, # 'φ' + 23: 2, # 'χ' + 42: 0, # 'ψ' + 24: 2, # 'ω' + 19: 2, # 'ÏŒ' + 26: 0, # 'Ï' + 27: 3, # 'ÏŽ' + }, + 48: { # 'Ρ' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'ÎŒ' + 31: 2, # 'Α' + 51: 0, # 'Î’' + 43: 1, # 'Γ' + 41: 1, # 'Δ' + 34: 2, # 'Ε' + 40: 2, # 'Η' + 52: 0, # 'Θ' + 47: 2, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 2, # 'Î' + 59: 0, # 'Ξ' + 39: 2, # 'Ο' + 35: 0, # 'Π' + 48: 2, # 'Ρ' + 37: 0, # 'Σ' + 33: 1, # 'Τ' + 45: 1, # 'Î¥' + 56: 0, # 'Φ' + 50: 1, # 'Χ' + 57: 1, # 'Ω' + 17: 0, # 'ά' + 18: 0, # 'έ' + 22: 0, # 'ή' + 15: 2, # 'ί' + 1: 0, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 0, # 'ε' + 32: 0, # 'ζ' + 13: 0, # 'η' + 25: 0, # 'θ' + 5: 0, # 'ι' + 11: 0, # 'κ' + 16: 0, # 'λ' + 10: 0, # 'μ' + 6: 0, # 'ν' + 30: 0, # 'ξ' + 4: 1, # 'ο' + 9: 0, # 'Ï€' + 8: 0, # 'Ï' + 14: 0, # 'Ï‚' + 7: 0, # 'σ' + 2: 0, # 'Ï„' + 12: 3, # 'Ï…' + 28: 0, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 2, # 'ω' + 19: 0, # 'ÏŒ' + 26: 2, # 'Ï' + 27: 0, # 'ÏŽ' + }, + 37: { # 'Σ' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'ÎŒ' + 31: 2, # 'Α' + 51: 0, # 'Î’' + 43: 0, # 'Γ' + 41: 1, # 'Δ' + 34: 2, # 'Ε' + 40: 2, # 'Η' + 52: 0, # 'Θ' + 47: 2, # 'Ι' + 44: 2, # 'Κ' + 53: 0, # 'Λ' + 38: 2, # 'Μ' + 49: 0, # 'Î' + 59: 0, # 'Ξ' + 39: 2, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 2, # 'Σ' + 33: 2, # 'Τ' + 45: 2, # 'Î¥' + 56: 0, # 'Φ' + 50: 2, # 'Χ' + 57: 2, # 'Ω' + 17: 0, # 'ά' + 18: 0, # 'έ' + 22: 2, # 'ή' + 15: 2, # 'ί' + 1: 2, # 'α' + 29: 2, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 3, # 'ε' + 32: 0, # 'ζ' + 13: 3, # 'η' + 25: 0, # 'θ' + 5: 2, # 'ι' + 11: 2, # 'κ' + 16: 0, # 'λ' + 10: 0, # 'μ' + 6: 0, # 'ν' + 30: 0, # 'ξ' + 4: 2, # 'ο' + 9: 2, # 'Ï€' + 8: 0, # 'Ï' + 14: 0, # 'Ï‚' + 7: 0, # 'σ' + 2: 3, # 'Ï„' + 12: 3, # 'Ï…' + 28: 0, # 'φ' + 23: 2, # 'χ' + 42: 0, # 'ψ' + 24: 2, # 'ω' + 19: 0, # 'ÏŒ' + 26: 2, # 'Ï' + 27: 2, # 'ÏŽ' + }, + 33: { # 'Τ' + 60: 0, # 'e' + 55: 1, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'ÎŒ' + 31: 2, # 'Α' + 51: 0, # 'Î’' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 2, # 'Ε' + 40: 2, # 'Η' + 52: 0, # 'Θ' + 47: 2, # 'Ι' + 44: 2, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Î' + 59: 0, # 'Ξ' + 39: 2, # 'Ο' + 35: 0, # 'Π' + 48: 2, # 'Ρ' + 37: 0, # 'Σ' + 33: 1, # 'Τ' + 45: 1, # 'Î¥' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 2, # 'Ω' + 17: 2, # 'ά' + 18: 2, # 'έ' + 22: 0, # 'ή' + 15: 2, # 'ί' + 1: 3, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 2, # 'ε' + 32: 0, # 'ζ' + 13: 2, # 'η' + 25: 0, # 'θ' + 5: 2, # 'ι' + 11: 0, # 'κ' + 16: 0, # 'λ' + 10: 2, # 'μ' + 6: 0, # 'ν' + 30: 0, # 'ξ' + 4: 3, # 'ο' + 9: 0, # 'Ï€' + 8: 2, # 'Ï' + 14: 0, # 'Ï‚' + 7: 2, # 'σ' + 2: 0, # 'Ï„' + 12: 2, # 'Ï…' + 28: 0, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 0, # 'ω' + 19: 2, # 'ÏŒ' + 26: 2, # 'Ï' + 27: 3, # 'ÏŽ' + }, + 45: { # 'Î¥' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'ÎŒ' + 31: 0, # 'Α' + 51: 0, # 'Î’' + 43: 2, # 'Γ' + 41: 0, # 'Δ' + 34: 1, # 'Ε' + 40: 2, # 'Η' + 52: 2, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 1, # 'Λ' + 38: 2, # 'Μ' + 49: 2, # 'Î' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 2, # 'Π' + 48: 1, # 'Ρ' + 37: 2, # 'Σ' + 33: 2, # 'Τ' + 45: 0, # 'Î¥' + 56: 0, # 'Φ' + 50: 1, # 'Χ' + 57: 0, # 'Ω' + 17: 0, # 'ά' + 18: 0, # 'έ' + 22: 0, # 'ή' + 15: 0, # 'ί' + 1: 0, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 0, # 'ε' + 32: 0, # 'ζ' + 13: 0, # 'η' + 25: 0, # 'θ' + 5: 0, # 'ι' + 11: 0, # 'κ' + 16: 2, # 'λ' + 10: 0, # 'μ' + 6: 0, # 'ν' + 30: 0, # 'ξ' + 4: 0, # 'ο' + 9: 3, # 'Ï€' + 8: 0, # 'Ï' + 14: 0, # 'Ï‚' + 7: 0, # 'σ' + 2: 0, # 'Ï„' + 12: 0, # 'Ï…' + 28: 0, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 0, # 'ω' + 19: 0, # 'ÏŒ' + 26: 0, # 'Ï' + 27: 0, # 'ÏŽ' + }, + 56: { # 'Φ' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'ÎŒ' + 31: 1, # 'Α' + 51: 0, # 'Î’' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 1, # 'Η' + 52: 0, # 'Θ' + 47: 2, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Î' + 59: 0, # 'Ξ' + 39: 2, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Î¥' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 0, # 'ά' + 18: 0, # 'έ' + 22: 0, # 'ή' + 15: 0, # 'ί' + 1: 2, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 2, # 'ε' + 32: 0, # 'ζ' + 13: 0, # 'η' + 25: 0, # 'θ' + 5: 2, # 'ι' + 11: 0, # 'κ' + 16: 0, # 'λ' + 10: 0, # 'μ' + 6: 0, # 'ν' + 30: 0, # 'ξ' + 4: 2, # 'ο' + 9: 0, # 'Ï€' + 8: 0, # 'Ï' + 14: 0, # 'Ï‚' + 7: 0, # 'σ' + 2: 2, # 'Ï„' + 12: 2, # 'Ï…' + 28: 0, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 0, # 'ω' + 19: 0, # 'ÏŒ' + 26: 1, # 'Ï' + 27: 1, # 'ÏŽ' + }, + 50: { # 'Χ' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'ÎŒ' + 31: 1, # 'Α' + 51: 0, # 'Î’' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 2, # 'Ε' + 40: 2, # 'Η' + 52: 0, # 'Θ' + 47: 2, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 1, # 'Î' + 59: 0, # 'Ξ' + 39: 1, # 'Ο' + 35: 0, # 'Π' + 48: 2, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Î¥' + 56: 0, # 'Φ' + 50: 1, # 'Χ' + 57: 1, # 'Ω' + 17: 2, # 'ά' + 18: 0, # 'έ' + 22: 0, # 'ή' + 15: 0, # 'ί' + 1: 2, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 2, # 'ε' + 32: 0, # 'ζ' + 13: 0, # 'η' + 25: 0, # 'θ' + 5: 0, # 'ι' + 11: 0, # 'κ' + 16: 0, # 'λ' + 10: 0, # 'μ' + 6: 0, # 'ν' + 30: 0, # 'ξ' + 4: 2, # 'ο' + 9: 0, # 'Ï€' + 8: 3, # 'Ï' + 14: 0, # 'Ï‚' + 7: 0, # 'σ' + 2: 2, # 'Ï„' + 12: 0, # 'Ï…' + 28: 0, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 2, # 'ω' + 19: 0, # 'ÏŒ' + 26: 0, # 'Ï' + 27: 0, # 'ÏŽ' + }, + 57: { # 'Ω' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'ÎŒ' + 31: 0, # 'Α' + 51: 0, # 'Î’' + 43: 1, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 1, # 'Λ' + 38: 0, # 'Μ' + 49: 2, # 'Î' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 2, # 'Ρ' + 37: 2, # 'Σ' + 33: 2, # 'Τ' + 45: 0, # 'Î¥' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 0, # 'ά' + 18: 0, # 'έ' + 22: 0, # 'ή' + 15: 0, # 'ί' + 1: 0, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 0, # 'ε' + 32: 0, # 'ζ' + 13: 0, # 'η' + 25: 0, # 'θ' + 5: 0, # 'ι' + 11: 0, # 'κ' + 16: 0, # 'λ' + 10: 0, # 'μ' + 6: 0, # 'ν' + 30: 0, # 'ξ' + 4: 0, # 'ο' + 9: 0, # 'Ï€' + 8: 2, # 'Ï' + 14: 2, # 'Ï‚' + 7: 2, # 'σ' + 2: 0, # 'Ï„' + 12: 0, # 'Ï…' + 28: 0, # 'φ' + 23: 1, # 'χ' + 42: 0, # 'ψ' + 24: 0, # 'ω' + 19: 0, # 'ÏŒ' + 26: 0, # 'Ï' + 27: 0, # 'ÏŽ' + }, + 17: { # 'ά' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 2, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'ÎŒ' + 31: 0, # 'Α' + 51: 0, # 'Î’' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Î' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Î¥' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 0, # 'ά' + 18: 0, # 'έ' + 22: 0, # 'ή' + 15: 0, # 'ί' + 1: 0, # 'α' + 29: 3, # 'β' + 20: 3, # 'γ' + 21: 3, # 'δ' + 3: 3, # 'ε' + 32: 3, # 'ζ' + 13: 0, # 'η' + 25: 3, # 'θ' + 5: 2, # 'ι' + 11: 3, # 'κ' + 16: 3, # 'λ' + 10: 3, # 'μ' + 6: 3, # 'ν' + 30: 3, # 'ξ' + 4: 0, # 'ο' + 9: 3, # 'Ï€' + 8: 3, # 'Ï' + 14: 3, # 'Ï‚' + 7: 3, # 'σ' + 2: 3, # 'Ï„' + 12: 0, # 'Ï…' + 28: 3, # 'φ' + 23: 3, # 'χ' + 42: 3, # 'ψ' + 24: 2, # 'ω' + 19: 0, # 'ÏŒ' + 26: 0, # 'Ï' + 27: 0, # 'ÏŽ' + }, + 18: { # 'έ' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'ÎŒ' + 31: 0, # 'Α' + 51: 0, # 'Î’' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Î' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Î¥' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 0, # 'ά' + 18: 0, # 'έ' + 22: 0, # 'ή' + 15: 0, # 'ί' + 1: 3, # 'α' + 29: 2, # 'β' + 20: 3, # 'γ' + 21: 2, # 'δ' + 3: 3, # 'ε' + 32: 2, # 'ζ' + 13: 0, # 'η' + 25: 3, # 'θ' + 5: 0, # 'ι' + 11: 3, # 'κ' + 16: 3, # 'λ' + 10: 3, # 'μ' + 6: 3, # 'ν' + 30: 3, # 'ξ' + 4: 3, # 'ο' + 9: 3, # 'Ï€' + 8: 3, # 'Ï' + 14: 3, # 'Ï‚' + 7: 3, # 'σ' + 2: 3, # 'Ï„' + 12: 0, # 'Ï…' + 28: 3, # 'φ' + 23: 3, # 'χ' + 42: 3, # 'ψ' + 24: 2, # 'ω' + 19: 0, # 'ÏŒ' + 26: 0, # 'Ï' + 27: 0, # 'ÏŽ' + }, + 22: { # 'ή' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 1, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'ÎŒ' + 31: 0, # 'Α' + 51: 0, # 'Î’' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Î' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Î¥' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 0, # 'ά' + 18: 0, # 'έ' + 22: 0, # 'ή' + 15: 0, # 'ί' + 1: 0, # 'α' + 29: 0, # 'β' + 20: 3, # 'γ' + 21: 3, # 'δ' + 3: 0, # 'ε' + 32: 0, # 'ζ' + 13: 0, # 'η' + 25: 3, # 'θ' + 5: 0, # 'ι' + 11: 3, # 'κ' + 16: 2, # 'λ' + 10: 3, # 'μ' + 6: 3, # 'ν' + 30: 2, # 'ξ' + 4: 0, # 'ο' + 9: 3, # 'Ï€' + 8: 3, # 'Ï' + 14: 3, # 'Ï‚' + 7: 3, # 'σ' + 2: 3, # 'Ï„' + 12: 0, # 'Ï…' + 28: 2, # 'φ' + 23: 3, # 'χ' + 42: 2, # 'ψ' + 24: 0, # 'ω' + 19: 0, # 'ÏŒ' + 26: 0, # 'Ï' + 27: 0, # 'ÏŽ' + }, + 15: { # 'ί' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'ÎŒ' + 31: 0, # 'Α' + 51: 0, # 'Î’' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Î' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Î¥' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 0, # 'ά' + 18: 0, # 'έ' + 22: 0, # 'ή' + 15: 0, # 'ί' + 1: 3, # 'α' + 29: 2, # 'β' + 20: 3, # 'γ' + 21: 3, # 'δ' + 3: 3, # 'ε' + 32: 3, # 'ζ' + 13: 3, # 'η' + 25: 3, # 'θ' + 5: 0, # 'ι' + 11: 3, # 'κ' + 16: 3, # 'λ' + 10: 3, # 'μ' + 6: 3, # 'ν' + 30: 3, # 'ξ' + 4: 3, # 'ο' + 9: 3, # 'Ï€' + 8: 3, # 'Ï' + 14: 3, # 'Ï‚' + 7: 3, # 'σ' + 2: 3, # 'Ï„' + 12: 0, # 'Ï…' + 28: 1, # 'φ' + 23: 3, # 'χ' + 42: 2, # 'ψ' + 24: 3, # 'ω' + 19: 0, # 'ÏŒ' + 26: 0, # 'Ï' + 27: 0, # 'ÏŽ' + }, + 1: { # 'α' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 2, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'ÎŒ' + 31: 0, # 'Α' + 51: 0, # 'Î’' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Î' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Î¥' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 0, # 'ά' + 18: 2, # 'έ' + 22: 0, # 'ή' + 15: 3, # 'ί' + 1: 0, # 'α' + 29: 3, # 'β' + 20: 3, # 'γ' + 21: 3, # 'δ' + 3: 2, # 'ε' + 32: 3, # 'ζ' + 13: 1, # 'η' + 25: 3, # 'θ' + 5: 3, # 'ι' + 11: 3, # 'κ' + 16: 3, # 'λ' + 10: 3, # 'μ' + 6: 3, # 'ν' + 30: 3, # 'ξ' + 4: 2, # 'ο' + 9: 3, # 'Ï€' + 8: 3, # 'Ï' + 14: 3, # 'Ï‚' + 7: 3, # 'σ' + 2: 3, # 'Ï„' + 12: 3, # 'Ï…' + 28: 3, # 'φ' + 23: 3, # 'χ' + 42: 2, # 'ψ' + 24: 0, # 'ω' + 19: 2, # 'ÏŒ' + 26: 2, # 'Ï' + 27: 0, # 'ÏŽ' + }, + 29: { # 'β' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'ÎŒ' + 31: 0, # 'Α' + 51: 0, # 'Î’' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Î' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Î¥' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 3, # 'ά' + 18: 2, # 'έ' + 22: 3, # 'ή' + 15: 2, # 'ί' + 1: 3, # 'α' + 29: 0, # 'β' + 20: 2, # 'γ' + 21: 2, # 'δ' + 3: 3, # 'ε' + 32: 0, # 'ζ' + 13: 2, # 'η' + 25: 0, # 'θ' + 5: 3, # 'ι' + 11: 0, # 'κ' + 16: 3, # 'λ' + 10: 0, # 'μ' + 6: 0, # 'ν' + 30: 0, # 'ξ' + 4: 3, # 'ο' + 9: 0, # 'Ï€' + 8: 3, # 'Ï' + 14: 0, # 'Ï‚' + 7: 0, # 'σ' + 2: 0, # 'Ï„' + 12: 0, # 'Ï…' + 28: 0, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 2, # 'ω' + 19: 2, # 'ÏŒ' + 26: 2, # 'Ï' + 27: 2, # 'ÏŽ' + }, + 20: { # 'γ' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'ÎŒ' + 31: 0, # 'Α' + 51: 0, # 'Î’' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Î' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Î¥' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 3, # 'ά' + 18: 3, # 'έ' + 22: 3, # 'ή' + 15: 3, # 'ί' + 1: 3, # 'α' + 29: 0, # 'β' + 20: 3, # 'γ' + 21: 0, # 'δ' + 3: 3, # 'ε' + 32: 0, # 'ζ' + 13: 3, # 'η' + 25: 0, # 'θ' + 5: 3, # 'ι' + 11: 3, # 'κ' + 16: 3, # 'λ' + 10: 3, # 'μ' + 6: 3, # 'ν' + 30: 3, # 'ξ' + 4: 3, # 'ο' + 9: 0, # 'Ï€' + 8: 3, # 'Ï' + 14: 0, # 'Ï‚' + 7: 0, # 'σ' + 2: 0, # 'Ï„' + 12: 2, # 'Ï…' + 28: 0, # 'φ' + 23: 3, # 'χ' + 42: 0, # 'ψ' + 24: 3, # 'ω' + 19: 3, # 'ÏŒ' + 26: 2, # 'Ï' + 27: 3, # 'ÏŽ' + }, + 21: { # 'δ' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'ÎŒ' + 31: 0, # 'Α' + 51: 0, # 'Î’' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Î' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Î¥' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 2, # 'ά' + 18: 3, # 'έ' + 22: 3, # 'ή' + 15: 3, # 'ί' + 1: 3, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 3, # 'ε' + 32: 0, # 'ζ' + 13: 3, # 'η' + 25: 0, # 'θ' + 5: 3, # 'ι' + 11: 0, # 'κ' + 16: 0, # 'λ' + 10: 0, # 'μ' + 6: 0, # 'ν' + 30: 0, # 'ξ' + 4: 3, # 'ο' + 9: 0, # 'Ï€' + 8: 3, # 'Ï' + 14: 0, # 'Ï‚' + 7: 0, # 'σ' + 2: 0, # 'Ï„' + 12: 3, # 'Ï…' + 28: 0, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 3, # 'ω' + 19: 3, # 'ÏŒ' + 26: 3, # 'Ï' + 27: 3, # 'ÏŽ' + }, + 3: { # 'ε' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 2, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'ÎŒ' + 31: 0, # 'Α' + 51: 0, # 'Î’' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Î' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Î¥' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 3, # 'ά' + 18: 0, # 'έ' + 22: 0, # 'ή' + 15: 3, # 'ί' + 1: 2, # 'α' + 29: 3, # 'β' + 20: 3, # 'γ' + 21: 3, # 'δ' + 3: 2, # 'ε' + 32: 2, # 'ζ' + 13: 0, # 'η' + 25: 3, # 'θ' + 5: 3, # 'ι' + 11: 3, # 'κ' + 16: 3, # 'λ' + 10: 3, # 'μ' + 6: 3, # 'ν' + 30: 3, # 'ξ' + 4: 2, # 'ο' + 9: 3, # 'Ï€' + 8: 3, # 'Ï' + 14: 3, # 'Ï‚' + 7: 3, # 'σ' + 2: 3, # 'Ï„' + 12: 3, # 'Ï…' + 28: 3, # 'φ' + 23: 3, # 'χ' + 42: 2, # 'ψ' + 24: 3, # 'ω' + 19: 2, # 'ÏŒ' + 26: 3, # 'Ï' + 27: 2, # 'ÏŽ' + }, + 32: { # 'ζ' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'ÎŒ' + 31: 0, # 'Α' + 51: 0, # 'Î’' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Î' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Î¥' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 2, # 'ά' + 18: 2, # 'έ' + 22: 2, # 'ή' + 15: 2, # 'ί' + 1: 2, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 3, # 'ε' + 32: 0, # 'ζ' + 13: 3, # 'η' + 25: 0, # 'θ' + 5: 2, # 'ι' + 11: 0, # 'κ' + 16: 0, # 'λ' + 10: 0, # 'μ' + 6: 0, # 'ν' + 30: 0, # 'ξ' + 4: 3, # 'ο' + 9: 0, # 'Ï€' + 8: 0, # 'Ï' + 14: 0, # 'Ï‚' + 7: 0, # 'σ' + 2: 0, # 'Ï„' + 12: 1, # 'Ï…' + 28: 0, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 3, # 'ω' + 19: 2, # 'ÏŒ' + 26: 0, # 'Ï' + 27: 2, # 'ÏŽ' + }, + 13: { # 'η' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 2, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'ÎŒ' + 31: 0, # 'Α' + 51: 0, # 'Î’' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Î' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Î¥' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 0, # 'ά' + 18: 0, # 'έ' + 22: 0, # 'ή' + 15: 0, # 'ί' + 1: 0, # 'α' + 29: 0, # 'β' + 20: 3, # 'γ' + 21: 2, # 'δ' + 3: 0, # 'ε' + 32: 0, # 'ζ' + 13: 0, # 'η' + 25: 3, # 'θ' + 5: 0, # 'ι' + 11: 3, # 'κ' + 16: 3, # 'λ' + 10: 3, # 'μ' + 6: 3, # 'ν' + 30: 2, # 'ξ' + 4: 0, # 'ο' + 9: 2, # 'Ï€' + 8: 3, # 'Ï' + 14: 3, # 'Ï‚' + 7: 3, # 'σ' + 2: 3, # 'Ï„' + 12: 0, # 'Ï…' + 28: 2, # 'φ' + 23: 3, # 'χ' + 42: 2, # 'ψ' + 24: 0, # 'ω' + 19: 0, # 'ÏŒ' + 26: 0, # 'Ï' + 27: 0, # 'ÏŽ' + }, + 25: { # 'θ' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'ÎŒ' + 31: 0, # 'Α' + 51: 0, # 'Î’' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Î' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Î¥' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 2, # 'ά' + 18: 3, # 'έ' + 22: 3, # 'ή' + 15: 2, # 'ί' + 1: 3, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 3, # 'ε' + 32: 0, # 'ζ' + 13: 3, # 'η' + 25: 0, # 'θ' + 5: 3, # 'ι' + 11: 0, # 'κ' + 16: 1, # 'λ' + 10: 3, # 'μ' + 6: 2, # 'ν' + 30: 0, # 'ξ' + 4: 3, # 'ο' + 9: 0, # 'Ï€' + 8: 3, # 'Ï' + 14: 0, # 'Ï‚' + 7: 0, # 'σ' + 2: 0, # 'Ï„' + 12: 3, # 'Ï…' + 28: 0, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 3, # 'ω' + 19: 3, # 'ÏŒ' + 26: 3, # 'Ï' + 27: 3, # 'ÏŽ' + }, + 5: { # 'ι' + 60: 0, # 'e' + 55: 1, # 'o' + 58: 0, # 't' + 36: 2, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'ÎŒ' + 31: 0, # 'Α' + 51: 0, # 'Î’' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 1, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Î' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Î¥' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 3, # 'ά' + 18: 3, # 'έ' + 22: 3, # 'ή' + 15: 0, # 'ί' + 1: 3, # 'α' + 29: 3, # 'β' + 20: 3, # 'γ' + 21: 3, # 'δ' + 3: 3, # 'ε' + 32: 2, # 'ζ' + 13: 3, # 'η' + 25: 3, # 'θ' + 5: 0, # 'ι' + 11: 3, # 'κ' + 16: 3, # 'λ' + 10: 3, # 'μ' + 6: 3, # 'ν' + 30: 3, # 'ξ' + 4: 3, # 'ο' + 9: 3, # 'Ï€' + 8: 3, # 'Ï' + 14: 3, # 'Ï‚' + 7: 3, # 'σ' + 2: 3, # 'Ï„' + 12: 0, # 'Ï…' + 28: 2, # 'φ' + 23: 3, # 'χ' + 42: 2, # 'ψ' + 24: 3, # 'ω' + 19: 3, # 'ÏŒ' + 26: 0, # 'Ï' + 27: 3, # 'ÏŽ' + }, + 11: { # 'κ' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'ÎŒ' + 31: 0, # 'Α' + 51: 0, # 'Î’' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Î' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Î¥' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 3, # 'ά' + 18: 3, # 'έ' + 22: 3, # 'ή' + 15: 3, # 'ί' + 1: 3, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 3, # 'δ' + 3: 3, # 'ε' + 32: 0, # 'ζ' + 13: 3, # 'η' + 25: 2, # 'θ' + 5: 3, # 'ι' + 11: 3, # 'κ' + 16: 3, # 'λ' + 10: 3, # 'μ' + 6: 2, # 'ν' + 30: 0, # 'ξ' + 4: 3, # 'ο' + 9: 2, # 'Ï€' + 8: 3, # 'Ï' + 14: 0, # 'Ï‚' + 7: 0, # 'σ' + 2: 3, # 'Ï„' + 12: 3, # 'Ï…' + 28: 2, # 'φ' + 23: 2, # 'χ' + 42: 0, # 'ψ' + 24: 3, # 'ω' + 19: 3, # 'ÏŒ' + 26: 3, # 'Ï' + 27: 3, # 'ÏŽ' + }, + 16: { # 'λ' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'ÎŒ' + 31: 0, # 'Α' + 51: 0, # 'Î’' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Î' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Î¥' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 3, # 'ά' + 18: 3, # 'έ' + 22: 3, # 'ή' + 15: 3, # 'ί' + 1: 3, # 'α' + 29: 1, # 'β' + 20: 2, # 'γ' + 21: 1, # 'δ' + 3: 3, # 'ε' + 32: 0, # 'ζ' + 13: 3, # 'η' + 25: 2, # 'θ' + 5: 3, # 'ι' + 11: 2, # 'κ' + 16: 3, # 'λ' + 10: 2, # 'μ' + 6: 2, # 'ν' + 30: 0, # 'ξ' + 4: 3, # 'ο' + 9: 3, # 'Ï€' + 8: 0, # 'Ï' + 14: 0, # 'Ï‚' + 7: 0, # 'σ' + 2: 3, # 'Ï„' + 12: 3, # 'Ï…' + 28: 2, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 3, # 'ω' + 19: 3, # 'ÏŒ' + 26: 3, # 'Ï' + 27: 3, # 'ÏŽ' + }, + 10: { # 'μ' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'ÎŒ' + 31: 0, # 'Α' + 51: 0, # 'Î’' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 1, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Î' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Î¥' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 3, # 'ά' + 18: 3, # 'έ' + 22: 3, # 'ή' + 15: 3, # 'ί' + 1: 3, # 'α' + 29: 3, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 3, # 'ε' + 32: 0, # 'ζ' + 13: 3, # 'η' + 25: 0, # 'θ' + 5: 3, # 'ι' + 11: 0, # 'κ' + 16: 0, # 'λ' + 10: 3, # 'μ' + 6: 3, # 'ν' + 30: 0, # 'ξ' + 4: 3, # 'ο' + 9: 3, # 'Ï€' + 8: 0, # 'Ï' + 14: 0, # 'Ï‚' + 7: 0, # 'σ' + 2: 0, # 'Ï„' + 12: 2, # 'Ï…' + 28: 3, # 'φ' + 23: 0, # 'χ' + 42: 2, # 'ψ' + 24: 3, # 'ω' + 19: 3, # 'ÏŒ' + 26: 2, # 'Ï' + 27: 2, # 'ÏŽ' + }, + 6: { # 'ν' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 2, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'ÎŒ' + 31: 0, # 'Α' + 51: 0, # 'Î’' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Î' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Î¥' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 3, # 'ά' + 18: 3, # 'έ' + 22: 3, # 'ή' + 15: 3, # 'ί' + 1: 3, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 3, # 'δ' + 3: 3, # 'ε' + 32: 2, # 'ζ' + 13: 3, # 'η' + 25: 3, # 'θ' + 5: 3, # 'ι' + 11: 0, # 'κ' + 16: 1, # 'λ' + 10: 0, # 'μ' + 6: 2, # 'ν' + 30: 0, # 'ξ' + 4: 3, # 'ο' + 9: 0, # 'Ï€' + 8: 0, # 'Ï' + 14: 0, # 'Ï‚' + 7: 3, # 'σ' + 2: 3, # 'Ï„' + 12: 3, # 'Ï…' + 28: 0, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 3, # 'ω' + 19: 3, # 'ÏŒ' + 26: 3, # 'Ï' + 27: 3, # 'ÏŽ' + }, + 30: { # 'ξ' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'ÎŒ' + 31: 0, # 'Α' + 51: 0, # 'Î’' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Î' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Î¥' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 2, # 'ά' + 18: 3, # 'έ' + 22: 3, # 'ή' + 15: 2, # 'ί' + 1: 3, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 3, # 'ε' + 32: 0, # 'ζ' + 13: 3, # 'η' + 25: 0, # 'θ' + 5: 2, # 'ι' + 11: 0, # 'κ' + 16: 0, # 'λ' + 10: 0, # 'μ' + 6: 0, # 'ν' + 30: 0, # 'ξ' + 4: 3, # 'ο' + 9: 0, # 'Ï€' + 8: 0, # 'Ï' + 14: 0, # 'Ï‚' + 7: 0, # 'σ' + 2: 3, # 'Ï„' + 12: 2, # 'Ï…' + 28: 0, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 3, # 'ω' + 19: 2, # 'ÏŒ' + 26: 3, # 'Ï' + 27: 1, # 'ÏŽ' + }, + 4: { # 'ο' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 2, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'ÎŒ' + 31: 0, # 'Α' + 51: 0, # 'Î’' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Î' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Î¥' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 0, # 'ά' + 18: 2, # 'έ' + 22: 3, # 'ή' + 15: 3, # 'ί' + 1: 2, # 'α' + 29: 3, # 'β' + 20: 3, # 'γ' + 21: 3, # 'δ' + 3: 3, # 'ε' + 32: 0, # 'ζ' + 13: 3, # 'η' + 25: 3, # 'θ' + 5: 3, # 'ι' + 11: 3, # 'κ' + 16: 3, # 'λ' + 10: 3, # 'μ' + 6: 3, # 'ν' + 30: 2, # 'ξ' + 4: 2, # 'ο' + 9: 3, # 'Ï€' + 8: 3, # 'Ï' + 14: 3, # 'Ï‚' + 7: 3, # 'σ' + 2: 3, # 'Ï„' + 12: 3, # 'Ï…' + 28: 3, # 'φ' + 23: 3, # 'χ' + 42: 2, # 'ψ' + 24: 2, # 'ω' + 19: 1, # 'ÏŒ' + 26: 3, # 'Ï' + 27: 2, # 'ÏŽ' + }, + 9: { # 'Ï€' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'ÎŒ' + 31: 0, # 'Α' + 51: 0, # 'Î’' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Î' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Î¥' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 3, # 'ά' + 18: 3, # 'έ' + 22: 3, # 'ή' + 15: 3, # 'ί' + 1: 3, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 3, # 'ε' + 32: 0, # 'ζ' + 13: 3, # 'η' + 25: 0, # 'θ' + 5: 3, # 'ι' + 11: 0, # 'κ' + 16: 3, # 'λ' + 10: 0, # 'μ' + 6: 2, # 'ν' + 30: 0, # 'ξ' + 4: 3, # 'ο' + 9: 0, # 'Ï€' + 8: 3, # 'Ï' + 14: 2, # 'Ï‚' + 7: 0, # 'σ' + 2: 3, # 'Ï„' + 12: 3, # 'Ï…' + 28: 0, # 'φ' + 23: 2, # 'χ' + 42: 0, # 'ψ' + 24: 3, # 'ω' + 19: 3, # 'ÏŒ' + 26: 2, # 'Ï' + 27: 3, # 'ÏŽ' + }, + 8: { # 'Ï' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'ÎŒ' + 31: 0, # 'Α' + 51: 0, # 'Î’' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Î' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Î¥' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 3, # 'ά' + 18: 3, # 'έ' + 22: 3, # 'ή' + 15: 3, # 'ί' + 1: 3, # 'α' + 29: 2, # 'β' + 20: 3, # 'γ' + 21: 2, # 'δ' + 3: 3, # 'ε' + 32: 0, # 'ζ' + 13: 3, # 'η' + 25: 3, # 'θ' + 5: 3, # 'ι' + 11: 3, # 'κ' + 16: 1, # 'λ' + 10: 3, # 'μ' + 6: 3, # 'ν' + 30: 2, # 'ξ' + 4: 3, # 'ο' + 9: 2, # 'Ï€' + 8: 2, # 'Ï' + 14: 0, # 'Ï‚' + 7: 2, # 'σ' + 2: 3, # 'Ï„' + 12: 3, # 'Ï…' + 28: 3, # 'φ' + 23: 3, # 'χ' + 42: 0, # 'ψ' + 24: 3, # 'ω' + 19: 3, # 'ÏŒ' + 26: 3, # 'Ï' + 27: 3, # 'ÏŽ' + }, + 14: { # 'Ï‚' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 2, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'ÎŒ' + 31: 0, # 'Α' + 51: 0, # 'Î’' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Î' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Î¥' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 0, # 'ά' + 18: 0, # 'έ' + 22: 0, # 'ή' + 15: 0, # 'ί' + 1: 0, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 0, # 'ε' + 32: 0, # 'ζ' + 13: 0, # 'η' + 25: 0, # 'θ' + 5: 0, # 'ι' + 11: 0, # 'κ' + 16: 0, # 'λ' + 10: 0, # 'μ' + 6: 0, # 'ν' + 30: 0, # 'ξ' + 4: 0, # 'ο' + 9: 0, # 'Ï€' + 8: 0, # 'Ï' + 14: 0, # 'Ï‚' + 7: 0, # 'σ' + 2: 0, # 'Ï„' + 12: 0, # 'Ï…' + 28: 0, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 0, # 'ω' + 19: 0, # 'ÏŒ' + 26: 0, # 'Ï' + 27: 0, # 'ÏŽ' + }, + 7: { # 'σ' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'ÎŒ' + 31: 0, # 'Α' + 51: 0, # 'Î’' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Î' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Î¥' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 2, # 'ά' + 18: 2, # 'έ' + 22: 3, # 'ή' + 15: 3, # 'ί' + 1: 3, # 'α' + 29: 3, # 'β' + 20: 0, # 'γ' + 21: 2, # 'δ' + 3: 3, # 'ε' + 32: 0, # 'ζ' + 13: 3, # 'η' + 25: 3, # 'θ' + 5: 3, # 'ι' + 11: 3, # 'κ' + 16: 2, # 'λ' + 10: 3, # 'μ' + 6: 0, # 'ν' + 30: 0, # 'ξ' + 4: 3, # 'ο' + 9: 3, # 'Ï€' + 8: 0, # 'Ï' + 14: 0, # 'Ï‚' + 7: 3, # 'σ' + 2: 3, # 'Ï„' + 12: 3, # 'Ï…' + 28: 3, # 'φ' + 23: 3, # 'χ' + 42: 0, # 'ψ' + 24: 3, # 'ω' + 19: 3, # 'ÏŒ' + 26: 3, # 'Ï' + 27: 2, # 'ÏŽ' + }, + 2: { # 'Ï„' + 60: 0, # 'e' + 55: 2, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'ÎŒ' + 31: 0, # 'Α' + 51: 0, # 'Î’' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Î' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Î¥' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 3, # 'ά' + 18: 3, # 'έ' + 22: 3, # 'ή' + 15: 3, # 'ί' + 1: 3, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 3, # 'ε' + 32: 2, # 'ζ' + 13: 3, # 'η' + 25: 0, # 'θ' + 5: 3, # 'ι' + 11: 2, # 'κ' + 16: 2, # 'λ' + 10: 3, # 'μ' + 6: 0, # 'ν' + 30: 0, # 'ξ' + 4: 3, # 'ο' + 9: 0, # 'Ï€' + 8: 3, # 'Ï' + 14: 0, # 'Ï‚' + 7: 3, # 'σ' + 2: 3, # 'Ï„' + 12: 3, # 'Ï…' + 28: 2, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 3, # 'ω' + 19: 3, # 'ÏŒ' + 26: 3, # 'Ï' + 27: 3, # 'ÏŽ' + }, + 12: { # 'Ï…' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'ÎŒ' + 31: 0, # 'Α' + 51: 0, # 'Î’' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Î' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Î¥' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 2, # 'ά' + 18: 2, # 'έ' + 22: 3, # 'ή' + 15: 2, # 'ί' + 1: 3, # 'α' + 29: 2, # 'β' + 20: 3, # 'γ' + 21: 2, # 'δ' + 3: 2, # 'ε' + 32: 2, # 'ζ' + 13: 2, # 'η' + 25: 3, # 'θ' + 5: 2, # 'ι' + 11: 3, # 'κ' + 16: 3, # 'λ' + 10: 3, # 'μ' + 6: 3, # 'ν' + 30: 3, # 'ξ' + 4: 3, # 'ο' + 9: 3, # 'Ï€' + 8: 3, # 'Ï' + 14: 3, # 'Ï‚' + 7: 3, # 'σ' + 2: 3, # 'Ï„' + 12: 0, # 'Ï…' + 28: 2, # 'φ' + 23: 3, # 'χ' + 42: 2, # 'ψ' + 24: 2, # 'ω' + 19: 2, # 'ÏŒ' + 26: 0, # 'Ï' + 27: 2, # 'ÏŽ' + }, + 28: { # 'φ' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'ÎŒ' + 31: 0, # 'Α' + 51: 0, # 'Î’' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Î' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Î¥' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 3, # 'ά' + 18: 3, # 'έ' + 22: 3, # 'ή' + 15: 3, # 'ί' + 1: 3, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 3, # 'ε' + 32: 0, # 'ζ' + 13: 2, # 'η' + 25: 2, # 'θ' + 5: 3, # 'ι' + 11: 0, # 'κ' + 16: 2, # 'λ' + 10: 0, # 'μ' + 6: 1, # 'ν' + 30: 0, # 'ξ' + 4: 3, # 'ο' + 9: 0, # 'Ï€' + 8: 3, # 'Ï' + 14: 0, # 'Ï‚' + 7: 0, # 'σ' + 2: 3, # 'Ï„' + 12: 3, # 'Ï…' + 28: 1, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 3, # 'ω' + 19: 3, # 'ÏŒ' + 26: 2, # 'Ï' + 27: 2, # 'ÏŽ' + }, + 23: { # 'χ' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'ÎŒ' + 31: 0, # 'Α' + 51: 0, # 'Î’' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Î' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Î¥' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 3, # 'ά' + 18: 2, # 'έ' + 22: 3, # 'ή' + 15: 3, # 'ί' + 1: 3, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 3, # 'ε' + 32: 0, # 'ζ' + 13: 2, # 'η' + 25: 2, # 'θ' + 5: 3, # 'ι' + 11: 0, # 'κ' + 16: 2, # 'λ' + 10: 2, # 'μ' + 6: 3, # 'ν' + 30: 0, # 'ξ' + 4: 3, # 'ο' + 9: 0, # 'Ï€' + 8: 3, # 'Ï' + 14: 0, # 'Ï‚' + 7: 0, # 'σ' + 2: 3, # 'Ï„' + 12: 3, # 'Ï…' + 28: 0, # 'φ' + 23: 2, # 'χ' + 42: 0, # 'ψ' + 24: 3, # 'ω' + 19: 3, # 'ÏŒ' + 26: 3, # 'Ï' + 27: 3, # 'ÏŽ' + }, + 42: { # 'ψ' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'ÎŒ' + 31: 0, # 'Α' + 51: 0, # 'Î’' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Î' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Î¥' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 2, # 'ά' + 18: 2, # 'έ' + 22: 1, # 'ή' + 15: 2, # 'ί' + 1: 2, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 3, # 'ε' + 32: 0, # 'ζ' + 13: 3, # 'η' + 25: 0, # 'θ' + 5: 2, # 'ι' + 11: 0, # 'κ' + 16: 0, # 'λ' + 10: 0, # 'μ' + 6: 0, # 'ν' + 30: 0, # 'ξ' + 4: 2, # 'ο' + 9: 0, # 'Ï€' + 8: 0, # 'Ï' + 14: 0, # 'Ï‚' + 7: 0, # 'σ' + 2: 2, # 'Ï„' + 12: 1, # 'Ï…' + 28: 0, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 2, # 'ω' + 19: 0, # 'ÏŒ' + 26: 0, # 'Ï' + 27: 0, # 'ÏŽ' + }, + 24: { # 'ω' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'ÎŒ' + 31: 0, # 'Α' + 51: 0, # 'Î’' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Î' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Î¥' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 1, # 'ά' + 18: 0, # 'έ' + 22: 2, # 'ή' + 15: 0, # 'ί' + 1: 0, # 'α' + 29: 2, # 'β' + 20: 3, # 'γ' + 21: 2, # 'δ' + 3: 0, # 'ε' + 32: 0, # 'ζ' + 13: 0, # 'η' + 25: 3, # 'θ' + 5: 2, # 'ι' + 11: 0, # 'κ' + 16: 2, # 'λ' + 10: 3, # 'μ' + 6: 3, # 'ν' + 30: 0, # 'ξ' + 4: 0, # 'ο' + 9: 3, # 'Ï€' + 8: 3, # 'Ï' + 14: 3, # 'Ï‚' + 7: 3, # 'σ' + 2: 3, # 'Ï„' + 12: 0, # 'Ï…' + 28: 2, # 'φ' + 23: 2, # 'χ' + 42: 0, # 'ψ' + 24: 0, # 'ω' + 19: 0, # 'ÏŒ' + 26: 0, # 'Ï' + 27: 0, # 'ÏŽ' + }, + 19: { # 'ÏŒ' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'ÎŒ' + 31: 0, # 'Α' + 51: 0, # 'Î’' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Î' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Î¥' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 0, # 'ά' + 18: 0, # 'έ' + 22: 0, # 'ή' + 15: 0, # 'ί' + 1: 0, # 'α' + 29: 3, # 'β' + 20: 3, # 'γ' + 21: 3, # 'δ' + 3: 1, # 'ε' + 32: 2, # 'ζ' + 13: 2, # 'η' + 25: 2, # 'θ' + 5: 2, # 'ι' + 11: 3, # 'κ' + 16: 3, # 'λ' + 10: 3, # 'μ' + 6: 3, # 'ν' + 30: 1, # 'ξ' + 4: 2, # 'ο' + 9: 3, # 'Ï€' + 8: 3, # 'Ï' + 14: 3, # 'Ï‚' + 7: 3, # 'σ' + 2: 3, # 'Ï„' + 12: 0, # 'Ï…' + 28: 2, # 'φ' + 23: 3, # 'χ' + 42: 2, # 'ψ' + 24: 0, # 'ω' + 19: 0, # 'ÏŒ' + 26: 0, # 'Ï' + 27: 0, # 'ÏŽ' + }, + 26: { # 'Ï' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'ÎŒ' + 31: 0, # 'Α' + 51: 0, # 'Î’' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Î' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Î¥' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 0, # 'ά' + 18: 0, # 'έ' + 22: 0, # 'ή' + 15: 0, # 'ί' + 1: 2, # 'α' + 29: 2, # 'β' + 20: 2, # 'γ' + 21: 1, # 'δ' + 3: 3, # 'ε' + 32: 0, # 'ζ' + 13: 2, # 'η' + 25: 3, # 'θ' + 5: 0, # 'ι' + 11: 3, # 'κ' + 16: 3, # 'λ' + 10: 3, # 'μ' + 6: 3, # 'ν' + 30: 2, # 'ξ' + 4: 3, # 'ο' + 9: 3, # 'Ï€' + 8: 3, # 'Ï' + 14: 3, # 'Ï‚' + 7: 3, # 'σ' + 2: 3, # 'Ï„' + 12: 0, # 'Ï…' + 28: 2, # 'φ' + 23: 2, # 'χ' + 42: 2, # 'ψ' + 24: 2, # 'ω' + 19: 0, # 'ÏŒ' + 26: 0, # 'Ï' + 27: 0, # 'ÏŽ' + }, + 27: { # 'ÏŽ' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'ÎŒ' + 31: 0, # 'Α' + 51: 0, # 'Î’' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Î' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Î¥' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 0, # 'ά' + 18: 0, # 'έ' + 22: 0, # 'ή' + 15: 0, # 'ί' + 1: 0, # 'α' + 29: 1, # 'β' + 20: 0, # 'γ' + 21: 3, # 'δ' + 3: 0, # 'ε' + 32: 0, # 'ζ' + 13: 1, # 'η' + 25: 2, # 'θ' + 5: 2, # 'ι' + 11: 0, # 'κ' + 16: 2, # 'λ' + 10: 3, # 'μ' + 6: 3, # 'ν' + 30: 1, # 'ξ' + 4: 0, # 'ο' + 9: 2, # 'Ï€' + 8: 3, # 'Ï' + 14: 3, # 'Ï‚' + 7: 3, # 'σ' + 2: 3, # 'Ï„' + 12: 0, # 'Ï…' + 28: 1, # 'φ' + 23: 1, # 'χ' + 42: 0, # 'ψ' + 24: 0, # 'ω' + 19: 0, # 'ÏŒ' + 26: 0, # 'Ï' + 27: 0, # 'ÏŽ' + }, +} + +# 255: Undefined characters that did not exist in training text +# 254: Carriage/Return +# 253: symbol (punctuation) that does not belong to word +# 252: 0 - 9 +# 251: Control characters + +# Character Mapping Table(s): +WINDOWS_1253_GREEK_CHAR_TO_ORDER = { + 0: 255, # '\x00' + 1: 255, # '\x01' + 2: 255, # '\x02' + 3: 255, # '\x03' + 4: 255, # '\x04' + 5: 255, # '\x05' + 6: 255, # '\x06' + 7: 255, # '\x07' + 8: 255, # '\x08' + 9: 255, # '\t' + 10: 254, # '\n' + 11: 255, # '\x0b' + 12: 255, # '\x0c' + 13: 254, # '\r' + 14: 255, # '\x0e' + 15: 255, # '\x0f' + 16: 255, # '\x10' + 17: 255, # '\x11' + 18: 255, # '\x12' + 19: 255, # '\x13' + 20: 255, # '\x14' + 21: 255, # '\x15' + 22: 255, # '\x16' + 23: 255, # '\x17' + 24: 255, # '\x18' + 25: 255, # '\x19' + 26: 255, # '\x1a' + 27: 255, # '\x1b' + 28: 255, # '\x1c' + 29: 255, # '\x1d' + 30: 255, # '\x1e' + 31: 255, # '\x1f' + 32: 253, # ' ' + 33: 253, # '!' + 34: 253, # '"' + 35: 253, # '#' + 36: 253, # '$' + 37: 253, # '%' + 38: 253, # '&' + 39: 253, # "'" + 40: 253, # '(' + 41: 253, # ')' + 42: 253, # '*' + 43: 253, # '+' + 44: 253, # ',' + 45: 253, # '-' + 46: 253, # '.' + 47: 253, # '/' + 48: 252, # '0' + 49: 252, # '1' + 50: 252, # '2' + 51: 252, # '3' + 52: 252, # '4' + 53: 252, # '5' + 54: 252, # '6' + 55: 252, # '7' + 56: 252, # '8' + 57: 252, # '9' + 58: 253, # ':' + 59: 253, # ';' + 60: 253, # '<' + 61: 253, # '=' + 62: 253, # '>' + 63: 253, # '?' + 64: 253, # '@' + 65: 82, # 'A' + 66: 100, # 'B' + 67: 104, # 'C' + 68: 94, # 'D' + 69: 98, # 'E' + 70: 101, # 'F' + 71: 116, # 'G' + 72: 102, # 'H' + 73: 111, # 'I' + 74: 187, # 'J' + 75: 117, # 'K' + 76: 92, # 'L' + 77: 88, # 'M' + 78: 113, # 'N' + 79: 85, # 'O' + 80: 79, # 'P' + 81: 118, # 'Q' + 82: 105, # 'R' + 83: 83, # 'S' + 84: 67, # 'T' + 85: 114, # 'U' + 86: 119, # 'V' + 87: 95, # 'W' + 88: 99, # 'X' + 89: 109, # 'Y' + 90: 188, # 'Z' + 91: 253, # '[' + 92: 253, # '\\' + 93: 253, # ']' + 94: 253, # '^' + 95: 253, # '_' + 96: 253, # '`' + 97: 72, # 'a' + 98: 70, # 'b' + 99: 80, # 'c' + 100: 81, # 'd' + 101: 60, # 'e' + 102: 96, # 'f' + 103: 93, # 'g' + 104: 89, # 'h' + 105: 68, # 'i' + 106: 120, # 'j' + 107: 97, # 'k' + 108: 77, # 'l' + 109: 86, # 'm' + 110: 69, # 'n' + 111: 55, # 'o' + 112: 78, # 'p' + 113: 115, # 'q' + 114: 65, # 'r' + 115: 66, # 's' + 116: 58, # 't' + 117: 76, # 'u' + 118: 106, # 'v' + 119: 103, # 'w' + 120: 87, # 'x' + 121: 107, # 'y' + 122: 112, # 'z' + 123: 253, # '{' + 124: 253, # '|' + 125: 253, # '}' + 126: 253, # '~' + 127: 253, # '\x7f' + 128: 255, # '€' + 129: 255, # None + 130: 255, # '‚' + 131: 255, # 'Æ’' + 132: 255, # '„' + 133: 255, # '…' + 134: 255, # '†' + 135: 255, # '‡' + 136: 255, # None + 137: 255, # '‰' + 138: 255, # None + 139: 255, # '‹' + 140: 255, # None + 141: 255, # None + 142: 255, # None + 143: 255, # None + 144: 255, # None + 145: 255, # '‘' + 146: 255, # '’' + 147: 255, # '“' + 148: 255, # 'â€' + 149: 255, # '•' + 150: 255, # '–' + 151: 255, # '—' + 152: 255, # None + 153: 255, # 'â„¢' + 154: 255, # None + 155: 255, # '›' + 156: 255, # None + 157: 255, # None + 158: 255, # None + 159: 255, # None + 160: 253, # '\xa0' + 161: 233, # 'Î…' + 162: 61, # 'Ά' + 163: 253, # '£' + 164: 253, # '¤' + 165: 253, # 'Â¥' + 166: 253, # '¦' + 167: 253, # '§' + 168: 253, # '¨' + 169: 253, # '©' + 170: 253, # None + 171: 253, # '«' + 172: 253, # '¬' + 173: 74, # '\xad' + 174: 253, # '®' + 175: 253, # '―' + 176: 253, # '°' + 177: 253, # '±' + 178: 253, # '²' + 179: 253, # '³' + 180: 247, # '΄' + 181: 253, # 'µ' + 182: 253, # '¶' + 183: 36, # '·' + 184: 46, # 'Έ' + 185: 71, # 'Ή' + 186: 73, # 'Ί' + 187: 253, # '»' + 188: 54, # 'ÎŒ' + 189: 253, # '½' + 190: 108, # 'ÎŽ' + 191: 123, # 'Î' + 192: 110, # 'Î' + 193: 31, # 'Α' + 194: 51, # 'Î’' + 195: 43, # 'Γ' + 196: 41, # 'Δ' + 197: 34, # 'Ε' + 198: 91, # 'Ζ' + 199: 40, # 'Η' + 200: 52, # 'Θ' + 201: 47, # 'Ι' + 202: 44, # 'Κ' + 203: 53, # 'Λ' + 204: 38, # 'Μ' + 205: 49, # 'Î' + 206: 59, # 'Ξ' + 207: 39, # 'Ο' + 208: 35, # 'Π' + 209: 48, # 'Ρ' + 210: 250, # None + 211: 37, # 'Σ' + 212: 33, # 'Τ' + 213: 45, # 'Î¥' + 214: 56, # 'Φ' + 215: 50, # 'Χ' + 216: 84, # 'Ψ' + 217: 57, # 'Ω' + 218: 120, # 'Ϊ' + 219: 121, # 'Ϋ' + 220: 17, # 'ά' + 221: 18, # 'έ' + 222: 22, # 'ή' + 223: 15, # 'ί' + 224: 124, # 'ΰ' + 225: 1, # 'α' + 226: 29, # 'β' + 227: 20, # 'γ' + 228: 21, # 'δ' + 229: 3, # 'ε' + 230: 32, # 'ζ' + 231: 13, # 'η' + 232: 25, # 'θ' + 233: 5, # 'ι' + 234: 11, # 'κ' + 235: 16, # 'λ' + 236: 10, # 'μ' + 237: 6, # 'ν' + 238: 30, # 'ξ' + 239: 4, # 'ο' + 240: 9, # 'Ï€' + 241: 8, # 'Ï' + 242: 14, # 'Ï‚' + 243: 7, # 'σ' + 244: 2, # 'Ï„' + 245: 12, # 'Ï…' + 246: 28, # 'φ' + 247: 23, # 'χ' + 248: 42, # 'ψ' + 249: 24, # 'ω' + 250: 64, # 'ÏŠ' + 251: 75, # 'Ï‹' + 252: 19, # 'ÏŒ' + 253: 26, # 'Ï' + 254: 27, # 'ÏŽ' + 255: 253, # None +} + +WINDOWS_1253_GREEK_MODEL = SingleByteCharSetModel(charset_name='windows-1253', + language='Greek', + char_to_order_map=WINDOWS_1253_GREEK_CHAR_TO_ORDER, + language_model=GREEK_LANG_MODEL, + typical_positive_ratio=0.982851, + keep_ascii_letters=False, + alphabet='ΆΈΉΊΌΎÎΑΒΓΔΕΖΗΘΙΚΛΜÎΞΟΠΡΣΤΥΦΧΨΩάέήίαβγδεζηθικλμνξοπÏςστυφχψωόÏÏŽ') + +ISO_8859_7_GREEK_CHAR_TO_ORDER = { + 0: 255, # '\x00' + 1: 255, # '\x01' + 2: 255, # '\x02' + 3: 255, # '\x03' + 4: 255, # '\x04' + 5: 255, # '\x05' + 6: 255, # '\x06' + 7: 255, # '\x07' + 8: 255, # '\x08' + 9: 255, # '\t' + 10: 254, # '\n' + 11: 255, # '\x0b' + 12: 255, # '\x0c' + 13: 254, # '\r' + 14: 255, # '\x0e' + 15: 255, # '\x0f' + 16: 255, # '\x10' + 17: 255, # '\x11' + 18: 255, # '\x12' + 19: 255, # '\x13' + 20: 255, # '\x14' + 21: 255, # '\x15' + 22: 255, # '\x16' + 23: 255, # '\x17' + 24: 255, # '\x18' + 25: 255, # '\x19' + 26: 255, # '\x1a' + 27: 255, # '\x1b' + 28: 255, # '\x1c' + 29: 255, # '\x1d' + 30: 255, # '\x1e' + 31: 255, # '\x1f' + 32: 253, # ' ' + 33: 253, # '!' + 34: 253, # '"' + 35: 253, # '#' + 36: 253, # '$' + 37: 253, # '%' + 38: 253, # '&' + 39: 253, # "'" + 40: 253, # '(' + 41: 253, # ')' + 42: 253, # '*' + 43: 253, # '+' + 44: 253, # ',' + 45: 253, # '-' + 46: 253, # '.' + 47: 253, # '/' + 48: 252, # '0' + 49: 252, # '1' + 50: 252, # '2' + 51: 252, # '3' + 52: 252, # '4' + 53: 252, # '5' + 54: 252, # '6' + 55: 252, # '7' + 56: 252, # '8' + 57: 252, # '9' + 58: 253, # ':' + 59: 253, # ';' + 60: 253, # '<' + 61: 253, # '=' + 62: 253, # '>' + 63: 253, # '?' + 64: 253, # '@' + 65: 82, # 'A' + 66: 100, # 'B' + 67: 104, # 'C' + 68: 94, # 'D' + 69: 98, # 'E' + 70: 101, # 'F' + 71: 116, # 'G' + 72: 102, # 'H' + 73: 111, # 'I' + 74: 187, # 'J' + 75: 117, # 'K' + 76: 92, # 'L' + 77: 88, # 'M' + 78: 113, # 'N' + 79: 85, # 'O' + 80: 79, # 'P' + 81: 118, # 'Q' + 82: 105, # 'R' + 83: 83, # 'S' + 84: 67, # 'T' + 85: 114, # 'U' + 86: 119, # 'V' + 87: 95, # 'W' + 88: 99, # 'X' + 89: 109, # 'Y' + 90: 188, # 'Z' + 91: 253, # '[' + 92: 253, # '\\' + 93: 253, # ']' + 94: 253, # '^' + 95: 253, # '_' + 96: 253, # '`' + 97: 72, # 'a' + 98: 70, # 'b' + 99: 80, # 'c' + 100: 81, # 'd' + 101: 60, # 'e' + 102: 96, # 'f' + 103: 93, # 'g' + 104: 89, # 'h' + 105: 68, # 'i' + 106: 120, # 'j' + 107: 97, # 'k' + 108: 77, # 'l' + 109: 86, # 'm' + 110: 69, # 'n' + 111: 55, # 'o' + 112: 78, # 'p' + 113: 115, # 'q' + 114: 65, # 'r' + 115: 66, # 's' + 116: 58, # 't' + 117: 76, # 'u' + 118: 106, # 'v' + 119: 103, # 'w' + 120: 87, # 'x' + 121: 107, # 'y' + 122: 112, # 'z' + 123: 253, # '{' + 124: 253, # '|' + 125: 253, # '}' + 126: 253, # '~' + 127: 253, # '\x7f' + 128: 255, # '\x80' + 129: 255, # '\x81' + 130: 255, # '\x82' + 131: 255, # '\x83' + 132: 255, # '\x84' + 133: 255, # '\x85' + 134: 255, # '\x86' + 135: 255, # '\x87' + 136: 255, # '\x88' + 137: 255, # '\x89' + 138: 255, # '\x8a' + 139: 255, # '\x8b' + 140: 255, # '\x8c' + 141: 255, # '\x8d' + 142: 255, # '\x8e' + 143: 255, # '\x8f' + 144: 255, # '\x90' + 145: 255, # '\x91' + 146: 255, # '\x92' + 147: 255, # '\x93' + 148: 255, # '\x94' + 149: 255, # '\x95' + 150: 255, # '\x96' + 151: 255, # '\x97' + 152: 255, # '\x98' + 153: 255, # '\x99' + 154: 255, # '\x9a' + 155: 255, # '\x9b' + 156: 255, # '\x9c' + 157: 255, # '\x9d' + 158: 255, # '\x9e' + 159: 255, # '\x9f' + 160: 253, # '\xa0' + 161: 233, # '‘' + 162: 90, # '’' + 163: 253, # '£' + 164: 253, # '€' + 165: 253, # '₯' + 166: 253, # '¦' + 167: 253, # '§' + 168: 253, # '¨' + 169: 253, # '©' + 170: 253, # 'ͺ' + 171: 253, # '«' + 172: 253, # '¬' + 173: 74, # '\xad' + 174: 253, # None + 175: 253, # '―' + 176: 253, # '°' + 177: 253, # '±' + 178: 253, # '²' + 179: 253, # '³' + 180: 247, # '΄' + 181: 248, # 'Î…' + 182: 61, # 'Ά' + 183: 36, # '·' + 184: 46, # 'Έ' + 185: 71, # 'Ή' + 186: 73, # 'Ί' + 187: 253, # '»' + 188: 54, # 'ÎŒ' + 189: 253, # '½' + 190: 108, # 'ÎŽ' + 191: 123, # 'Î' + 192: 110, # 'Î' + 193: 31, # 'Α' + 194: 51, # 'Î’' + 195: 43, # 'Γ' + 196: 41, # 'Δ' + 197: 34, # 'Ε' + 198: 91, # 'Ζ' + 199: 40, # 'Η' + 200: 52, # 'Θ' + 201: 47, # 'Ι' + 202: 44, # 'Κ' + 203: 53, # 'Λ' + 204: 38, # 'Μ' + 205: 49, # 'Î' + 206: 59, # 'Ξ' + 207: 39, # 'Ο' + 208: 35, # 'Π' + 209: 48, # 'Ρ' + 210: 250, # None + 211: 37, # 'Σ' + 212: 33, # 'Τ' + 213: 45, # 'Î¥' + 214: 56, # 'Φ' + 215: 50, # 'Χ' + 216: 84, # 'Ψ' + 217: 57, # 'Ω' + 218: 120, # 'Ϊ' + 219: 121, # 'Ϋ' + 220: 17, # 'ά' + 221: 18, # 'έ' + 222: 22, # 'ή' + 223: 15, # 'ί' + 224: 124, # 'ΰ' + 225: 1, # 'α' + 226: 29, # 'β' + 227: 20, # 'γ' + 228: 21, # 'δ' + 229: 3, # 'ε' + 230: 32, # 'ζ' + 231: 13, # 'η' + 232: 25, # 'θ' + 233: 5, # 'ι' + 234: 11, # 'κ' + 235: 16, # 'λ' + 236: 10, # 'μ' + 237: 6, # 'ν' + 238: 30, # 'ξ' + 239: 4, # 'ο' + 240: 9, # 'Ï€' + 241: 8, # 'Ï' + 242: 14, # 'Ï‚' + 243: 7, # 'σ' + 244: 2, # 'Ï„' + 245: 12, # 'Ï…' + 246: 28, # 'φ' + 247: 23, # 'χ' + 248: 42, # 'ψ' + 249: 24, # 'ω' + 250: 64, # 'ÏŠ' + 251: 75, # 'Ï‹' + 252: 19, # 'ÏŒ' + 253: 26, # 'Ï' + 254: 27, # 'ÏŽ' + 255: 253, # None +} + +ISO_8859_7_GREEK_MODEL = SingleByteCharSetModel(charset_name='ISO-8859-7', + language='Greek', + char_to_order_map=ISO_8859_7_GREEK_CHAR_TO_ORDER, + language_model=GREEK_LANG_MODEL, + typical_positive_ratio=0.982851, + keep_ascii_letters=False, + alphabet='ΆΈΉΊΌΎÎΑΒΓΔΕΖΗΘΙΚΛΜÎΞΟΠΡΣΤΥΦΧΨΩάέήίαβγδεζηθικλμνξοπÏςστυφχψωόÏÏŽ') + diff --git a/venv/Lib/site-packages/pip/_vendor/chardet/langhebrewmodel.py b/venv/Lib/site-packages/pip/_vendor/chardet/langhebrewmodel.py new file mode 100644 index 0000000..484c652 --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/chardet/langhebrewmodel.py @@ -0,0 +1,4383 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from pip._vendor.chardet.sbcharsetprober import SingleByteCharSetModel + + +# 3: Positive +# 2: Likely +# 1: Unlikely +# 0: Negative + +HEBREW_LANG_MODEL = { + 50: { # 'a' + 50: 0, # 'a' + 60: 1, # 'c' + 61: 1, # 'd' + 42: 1, # 'e' + 53: 1, # 'i' + 56: 2, # 'l' + 54: 2, # 'n' + 49: 0, # 'o' + 51: 2, # 'r' + 43: 1, # 's' + 44: 2, # 't' + 63: 1, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'Ö°' + 59: 0, # 'Ö±' + 41: 0, # 'Ö²' + 33: 0, # 'Ö´' + 37: 0, # 'Öµ' + 36: 0, # 'Ö¶' + 31: 0, # 'Ö·' + 29: 0, # 'Ö¸' + 35: 0, # 'Ö¹' + 62: 0, # 'Ö»' + 28: 0, # 'Ö¼' + 38: 0, # '×' + 45: 0, # 'ׂ' + 9: 0, # '×' + 8: 0, # 'ב' + 20: 0, # '×’' + 16: 0, # 'ד' + 3: 1, # '×”' + 2: 0, # 'ו' + 24: 0, # '×–' + 14: 0, # '×—' + 22: 0, # 'ט' + 1: 0, # '×™' + 25: 0, # 'ך' + 15: 0, # '×›' + 4: 0, # 'ל' + 11: 0, # '×' + 6: 1, # 'מ' + 23: 0, # 'ן' + 12: 0, # '× ' + 19: 0, # 'ס' + 13: 0, # '×¢' + 26: 0, # '×£' + 18: 0, # 'פ' + 27: 0, # '×¥' + 21: 0, # 'צ' + 17: 1, # '×§' + 7: 0, # 'ר' + 10: 1, # 'ש' + 5: 0, # 'ת' + 32: 0, # '–' + 52: 1, # '’' + 47: 0, # '“' + 46: 1, # 'â€' + 58: 0, # '†' + 40: 1, # '…' + }, + 60: { # 'c' + 50: 1, # 'a' + 60: 1, # 'c' + 61: 0, # 'd' + 42: 1, # 'e' + 53: 1, # 'i' + 56: 1, # 'l' + 54: 0, # 'n' + 49: 1, # 'o' + 51: 1, # 'r' + 43: 1, # 's' + 44: 2, # 't' + 63: 1, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'Ö°' + 59: 0, # 'Ö±' + 41: 0, # 'Ö²' + 33: 0, # 'Ö´' + 37: 0, # 'Öµ' + 36: 0, # 'Ö¶' + 31: 0, # 'Ö·' + 29: 0, # 'Ö¸' + 35: 0, # 'Ö¹' + 62: 0, # 'Ö»' + 28: 0, # 'Ö¼' + 38: 0, # '×' + 45: 0, # 'ׂ' + 9: 1, # '×' + 8: 0, # 'ב' + 20: 0, # '×’' + 16: 0, # 'ד' + 3: 1, # '×”' + 2: 0, # 'ו' + 24: 0, # '×–' + 14: 0, # '×—' + 22: 0, # 'ט' + 1: 0, # '×™' + 25: 0, # 'ך' + 15: 0, # '×›' + 4: 0, # 'ל' + 11: 0, # '×' + 6: 1, # 'מ' + 23: 0, # 'ן' + 12: 1, # '× ' + 19: 0, # 'ס' + 13: 0, # '×¢' + 26: 0, # '×£' + 18: 0, # 'פ' + 27: 0, # '×¥' + 21: 0, # 'צ' + 17: 0, # '×§' + 7: 0, # 'ר' + 10: 0, # 'ש' + 5: 0, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 1, # 'â€' + 58: 0, # '†' + 40: 1, # '…' + }, + 61: { # 'd' + 50: 1, # 'a' + 60: 0, # 'c' + 61: 1, # 'd' + 42: 1, # 'e' + 53: 1, # 'i' + 56: 1, # 'l' + 54: 1, # 'n' + 49: 2, # 'o' + 51: 1, # 'r' + 43: 1, # 's' + 44: 0, # 't' + 63: 1, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'Ö°' + 59: 0, # 'Ö±' + 41: 0, # 'Ö²' + 33: 0, # 'Ö´' + 37: 0, # 'Öµ' + 36: 0, # 'Ö¶' + 31: 0, # 'Ö·' + 29: 0, # 'Ö¸' + 35: 0, # 'Ö¹' + 62: 0, # 'Ö»' + 28: 0, # 'Ö¼' + 38: 0, # '×' + 45: 0, # 'ׂ' + 9: 0, # '×' + 8: 0, # 'ב' + 20: 0, # '×’' + 16: 0, # 'ד' + 3: 1, # '×”' + 2: 0, # 'ו' + 24: 0, # '×–' + 14: 0, # '×—' + 22: 0, # 'ט' + 1: 0, # '×™' + 25: 0, # 'ך' + 15: 0, # '×›' + 4: 0, # 'ל' + 11: 0, # '×' + 6: 0, # 'מ' + 23: 0, # 'ן' + 12: 0, # '× ' + 19: 0, # 'ס' + 13: 0, # '×¢' + 26: 0, # '×£' + 18: 0, # 'פ' + 27: 0, # '×¥' + 21: 0, # 'צ' + 17: 0, # '×§' + 7: 0, # 'ר' + 10: 0, # 'ש' + 5: 0, # 'ת' + 32: 1, # '–' + 52: 1, # '’' + 47: 0, # '“' + 46: 1, # 'â€' + 58: 0, # '†' + 40: 1, # '…' + }, + 42: { # 'e' + 50: 1, # 'a' + 60: 1, # 'c' + 61: 2, # 'd' + 42: 1, # 'e' + 53: 1, # 'i' + 56: 2, # 'l' + 54: 2, # 'n' + 49: 1, # 'o' + 51: 2, # 'r' + 43: 2, # 's' + 44: 2, # 't' + 63: 1, # 'u' + 34: 1, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'Ö°' + 59: 0, # 'Ö±' + 41: 0, # 'Ö²' + 33: 0, # 'Ö´' + 37: 0, # 'Öµ' + 36: 0, # 'Ö¶' + 31: 0, # 'Ö·' + 29: 0, # 'Ö¸' + 35: 0, # 'Ö¹' + 62: 0, # 'Ö»' + 28: 0, # 'Ö¼' + 38: 0, # '×' + 45: 0, # 'ׂ' + 9: 0, # '×' + 8: 0, # 'ב' + 20: 0, # '×’' + 16: 0, # 'ד' + 3: 0, # '×”' + 2: 0, # 'ו' + 24: 0, # '×–' + 14: 0, # '×—' + 22: 0, # 'ט' + 1: 0, # '×™' + 25: 0, # 'ך' + 15: 0, # '×›' + 4: 0, # 'ל' + 11: 0, # '×' + 6: 0, # 'מ' + 23: 0, # 'ן' + 12: 0, # '× ' + 19: 0, # 'ס' + 13: 0, # '×¢' + 26: 0, # '×£' + 18: 1, # 'פ' + 27: 0, # '×¥' + 21: 0, # 'צ' + 17: 0, # '×§' + 7: 0, # 'ר' + 10: 0, # 'ש' + 5: 0, # 'ת' + 32: 1, # '–' + 52: 2, # '’' + 47: 0, # '“' + 46: 1, # 'â€' + 58: 0, # '†' + 40: 1, # '…' + }, + 53: { # 'i' + 50: 1, # 'a' + 60: 2, # 'c' + 61: 1, # 'd' + 42: 1, # 'e' + 53: 0, # 'i' + 56: 1, # 'l' + 54: 2, # 'n' + 49: 2, # 'o' + 51: 1, # 'r' + 43: 2, # 's' + 44: 2, # 't' + 63: 1, # 'u' + 34: 0, # '\xa0' + 55: 1, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'Ö°' + 59: 0, # 'Ö±' + 41: 0, # 'Ö²' + 33: 0, # 'Ö´' + 37: 0, # 'Öµ' + 36: 0, # 'Ö¶' + 31: 0, # 'Ö·' + 29: 0, # 'Ö¸' + 35: 0, # 'Ö¹' + 62: 0, # 'Ö»' + 28: 0, # 'Ö¼' + 38: 0, # '×' + 45: 0, # 'ׂ' + 9: 0, # '×' + 8: 0, # 'ב' + 20: 0, # '×’' + 16: 0, # 'ד' + 3: 0, # '×”' + 2: 0, # 'ו' + 24: 0, # '×–' + 14: 0, # '×—' + 22: 0, # 'ט' + 1: 0, # '×™' + 25: 0, # 'ך' + 15: 0, # '×›' + 4: 0, # 'ל' + 11: 0, # '×' + 6: 0, # 'מ' + 23: 0, # 'ן' + 12: 0, # '× ' + 19: 0, # 'ס' + 13: 0, # '×¢' + 26: 0, # '×£' + 18: 0, # 'פ' + 27: 0, # '×¥' + 21: 0, # 'צ' + 17: 0, # '×§' + 7: 0, # 'ר' + 10: 0, # 'ש' + 5: 0, # 'ת' + 32: 0, # '–' + 52: 1, # '’' + 47: 0, # '“' + 46: 0, # 'â€' + 58: 0, # '†' + 40: 0, # '…' + }, + 56: { # 'l' + 50: 1, # 'a' + 60: 1, # 'c' + 61: 1, # 'd' + 42: 2, # 'e' + 53: 2, # 'i' + 56: 2, # 'l' + 54: 1, # 'n' + 49: 1, # 'o' + 51: 0, # 'r' + 43: 1, # 's' + 44: 1, # 't' + 63: 1, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'Ö°' + 59: 0, # 'Ö±' + 41: 0, # 'Ö²' + 33: 0, # 'Ö´' + 37: 0, # 'Öµ' + 36: 0, # 'Ö¶' + 31: 0, # 'Ö·' + 29: 0, # 'Ö¸' + 35: 0, # 'Ö¹' + 62: 0, # 'Ö»' + 28: 0, # 'Ö¼' + 38: 0, # '×' + 45: 0, # 'ׂ' + 9: 0, # '×' + 8: 0, # 'ב' + 20: 0, # '×’' + 16: 0, # 'ד' + 3: 0, # '×”' + 2: 0, # 'ו' + 24: 0, # '×–' + 14: 0, # '×—' + 22: 0, # 'ט' + 1: 0, # '×™' + 25: 0, # 'ך' + 15: 0, # '×›' + 4: 0, # 'ל' + 11: 0, # '×' + 6: 0, # 'מ' + 23: 0, # 'ן' + 12: 0, # '× ' + 19: 0, # 'ס' + 13: 0, # '×¢' + 26: 0, # '×£' + 18: 0, # 'פ' + 27: 0, # '×¥' + 21: 0, # 'צ' + 17: 0, # '×§' + 7: 0, # 'ר' + 10: 0, # 'ש' + 5: 0, # 'ת' + 32: 0, # '–' + 52: 1, # '’' + 47: 0, # '“' + 46: 1, # 'â€' + 58: 0, # '†' + 40: 1, # '…' + }, + 54: { # 'n' + 50: 1, # 'a' + 60: 1, # 'c' + 61: 1, # 'd' + 42: 1, # 'e' + 53: 1, # 'i' + 56: 1, # 'l' + 54: 1, # 'n' + 49: 1, # 'o' + 51: 0, # 'r' + 43: 1, # 's' + 44: 2, # 't' + 63: 1, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'Ö°' + 59: 0, # 'Ö±' + 41: 0, # 'Ö²' + 33: 0, # 'Ö´' + 37: 0, # 'Öµ' + 36: 0, # 'Ö¶' + 31: 0, # 'Ö·' + 29: 0, # 'Ö¸' + 35: 0, # 'Ö¹' + 62: 0, # 'Ö»' + 28: 0, # 'Ö¼' + 38: 0, # '×' + 45: 0, # 'ׂ' + 9: 0, # '×' + 8: 0, # 'ב' + 20: 0, # '×’' + 16: 0, # 'ד' + 3: 1, # '×”' + 2: 0, # 'ו' + 24: 0, # '×–' + 14: 0, # '×—' + 22: 0, # 'ט' + 1: 0, # '×™' + 25: 0, # 'ך' + 15: 0, # '×›' + 4: 0, # 'ל' + 11: 0, # '×' + 6: 0, # 'מ' + 23: 0, # 'ן' + 12: 0, # '× ' + 19: 0, # 'ס' + 13: 0, # '×¢' + 26: 0, # '×£' + 18: 0, # 'פ' + 27: 0, # '×¥' + 21: 0, # 'צ' + 17: 0, # '×§' + 7: 0, # 'ר' + 10: 0, # 'ש' + 5: 0, # 'ת' + 32: 0, # '–' + 52: 2, # '’' + 47: 0, # '“' + 46: 1, # 'â€' + 58: 0, # '†' + 40: 1, # '…' + }, + 49: { # 'o' + 50: 1, # 'a' + 60: 1, # 'c' + 61: 1, # 'd' + 42: 1, # 'e' + 53: 1, # 'i' + 56: 1, # 'l' + 54: 2, # 'n' + 49: 1, # 'o' + 51: 2, # 'r' + 43: 1, # 's' + 44: 1, # 't' + 63: 1, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'Ö°' + 59: 0, # 'Ö±' + 41: 0, # 'Ö²' + 33: 0, # 'Ö´' + 37: 0, # 'Öµ' + 36: 0, # 'Ö¶' + 31: 0, # 'Ö·' + 29: 0, # 'Ö¸' + 35: 0, # 'Ö¹' + 62: 0, # 'Ö»' + 28: 0, # 'Ö¼' + 38: 0, # '×' + 45: 0, # 'ׂ' + 9: 0, # '×' + 8: 0, # 'ב' + 20: 0, # '×’' + 16: 0, # 'ד' + 3: 0, # '×”' + 2: 0, # 'ו' + 24: 0, # '×–' + 14: 0, # '×—' + 22: 0, # 'ט' + 1: 0, # '×™' + 25: 0, # 'ך' + 15: 0, # '×›' + 4: 0, # 'ל' + 11: 0, # '×' + 6: 0, # 'מ' + 23: 0, # 'ן' + 12: 0, # '× ' + 19: 0, # 'ס' + 13: 0, # '×¢' + 26: 0, # '×£' + 18: 0, # 'פ' + 27: 0, # '×¥' + 21: 0, # 'צ' + 17: 0, # '×§' + 7: 0, # 'ר' + 10: 0, # 'ש' + 5: 0, # 'ת' + 32: 0, # '–' + 52: 1, # '’' + 47: 0, # '“' + 46: 1, # 'â€' + 58: 0, # '†' + 40: 1, # '…' + }, + 51: { # 'r' + 50: 2, # 'a' + 60: 1, # 'c' + 61: 1, # 'd' + 42: 2, # 'e' + 53: 1, # 'i' + 56: 1, # 'l' + 54: 1, # 'n' + 49: 2, # 'o' + 51: 1, # 'r' + 43: 1, # 's' + 44: 1, # 't' + 63: 1, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'Ö°' + 59: 0, # 'Ö±' + 41: 0, # 'Ö²' + 33: 0, # 'Ö´' + 37: 0, # 'Öµ' + 36: 0, # 'Ö¶' + 31: 0, # 'Ö·' + 29: 0, # 'Ö¸' + 35: 0, # 'Ö¹' + 62: 0, # 'Ö»' + 28: 0, # 'Ö¼' + 38: 0, # '×' + 45: 0, # 'ׂ' + 9: 0, # '×' + 8: 0, # 'ב' + 20: 0, # '×’' + 16: 0, # 'ד' + 3: 0, # '×”' + 2: 0, # 'ו' + 24: 0, # '×–' + 14: 0, # '×—' + 22: 0, # 'ט' + 1: 0, # '×™' + 25: 0, # 'ך' + 15: 0, # '×›' + 4: 0, # 'ל' + 11: 0, # '×' + 6: 0, # 'מ' + 23: 0, # 'ן' + 12: 0, # '× ' + 19: 0, # 'ס' + 13: 0, # '×¢' + 26: 0, # '×£' + 18: 0, # 'פ' + 27: 0, # '×¥' + 21: 0, # 'צ' + 17: 0, # '×§' + 7: 0, # 'ר' + 10: 0, # 'ש' + 5: 0, # 'ת' + 32: 0, # '–' + 52: 2, # '’' + 47: 0, # '“' + 46: 1, # 'â€' + 58: 0, # '†' + 40: 1, # '…' + }, + 43: { # 's' + 50: 1, # 'a' + 60: 1, # 'c' + 61: 0, # 'd' + 42: 2, # 'e' + 53: 1, # 'i' + 56: 1, # 'l' + 54: 1, # 'n' + 49: 1, # 'o' + 51: 1, # 'r' + 43: 1, # 's' + 44: 2, # 't' + 63: 1, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'Ö°' + 59: 0, # 'Ö±' + 41: 0, # 'Ö²' + 33: 0, # 'Ö´' + 37: 0, # 'Öµ' + 36: 0, # 'Ö¶' + 31: 0, # 'Ö·' + 29: 0, # 'Ö¸' + 35: 0, # 'Ö¹' + 62: 0, # 'Ö»' + 28: 0, # 'Ö¼' + 38: 0, # '×' + 45: 0, # 'ׂ' + 9: 0, # '×' + 8: 0, # 'ב' + 20: 0, # '×’' + 16: 0, # 'ד' + 3: 0, # '×”' + 2: 0, # 'ו' + 24: 0, # '×–' + 14: 0, # '×—' + 22: 0, # 'ט' + 1: 0, # '×™' + 25: 0, # 'ך' + 15: 0, # '×›' + 4: 0, # 'ל' + 11: 0, # '×' + 6: 0, # 'מ' + 23: 0, # 'ן' + 12: 0, # '× ' + 19: 0, # 'ס' + 13: 0, # '×¢' + 26: 0, # '×£' + 18: 0, # 'פ' + 27: 0, # '×¥' + 21: 0, # 'צ' + 17: 0, # '×§' + 7: 0, # 'ר' + 10: 0, # 'ש' + 5: 0, # 'ת' + 32: 0, # '–' + 52: 1, # '’' + 47: 0, # '“' + 46: 2, # 'â€' + 58: 0, # '†' + 40: 2, # '…' + }, + 44: { # 't' + 50: 1, # 'a' + 60: 1, # 'c' + 61: 0, # 'd' + 42: 2, # 'e' + 53: 2, # 'i' + 56: 1, # 'l' + 54: 0, # 'n' + 49: 1, # 'o' + 51: 1, # 'r' + 43: 1, # 's' + 44: 1, # 't' + 63: 1, # 'u' + 34: 1, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'Ö°' + 59: 0, # 'Ö±' + 41: 0, # 'Ö²' + 33: 0, # 'Ö´' + 37: 0, # 'Öµ' + 36: 0, # 'Ö¶' + 31: 0, # 'Ö·' + 29: 0, # 'Ö¸' + 35: 0, # 'Ö¹' + 62: 0, # 'Ö»' + 28: 0, # 'Ö¼' + 38: 0, # '×' + 45: 0, # 'ׂ' + 9: 0, # '×' + 8: 0, # 'ב' + 20: 0, # '×’' + 16: 0, # 'ד' + 3: 0, # '×”' + 2: 0, # 'ו' + 24: 0, # '×–' + 14: 0, # '×—' + 22: 0, # 'ט' + 1: 0, # '×™' + 25: 0, # 'ך' + 15: 0, # '×›' + 4: 0, # 'ל' + 11: 0, # '×' + 6: 0, # 'מ' + 23: 0, # 'ן' + 12: 0, # '× ' + 19: 0, # 'ס' + 13: 0, # '×¢' + 26: 0, # '×£' + 18: 0, # 'פ' + 27: 0, # '×¥' + 21: 0, # 'צ' + 17: 0, # '×§' + 7: 0, # 'ר' + 10: 0, # 'ש' + 5: 0, # 'ת' + 32: 0, # '–' + 52: 2, # '’' + 47: 0, # '“' + 46: 1, # 'â€' + 58: 0, # '†' + 40: 1, # '…' + }, + 63: { # 'u' + 50: 1, # 'a' + 60: 1, # 'c' + 61: 1, # 'd' + 42: 1, # 'e' + 53: 1, # 'i' + 56: 1, # 'l' + 54: 1, # 'n' + 49: 0, # 'o' + 51: 1, # 'r' + 43: 2, # 's' + 44: 1, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'Ö°' + 59: 0, # 'Ö±' + 41: 0, # 'Ö²' + 33: 0, # 'Ö´' + 37: 0, # 'Öµ' + 36: 0, # 'Ö¶' + 31: 0, # 'Ö·' + 29: 0, # 'Ö¸' + 35: 0, # 'Ö¹' + 62: 0, # 'Ö»' + 28: 0, # 'Ö¼' + 38: 0, # '×' + 45: 0, # 'ׂ' + 9: 0, # '×' + 8: 0, # 'ב' + 20: 0, # '×’' + 16: 0, # 'ד' + 3: 0, # '×”' + 2: 0, # 'ו' + 24: 0, # '×–' + 14: 0, # '×—' + 22: 0, # 'ט' + 1: 0, # '×™' + 25: 0, # 'ך' + 15: 0, # '×›' + 4: 0, # 'ל' + 11: 0, # '×' + 6: 0, # 'מ' + 23: 0, # 'ן' + 12: 0, # '× ' + 19: 0, # 'ס' + 13: 0, # '×¢' + 26: 0, # '×£' + 18: 0, # 'פ' + 27: 0, # '×¥' + 21: 0, # 'צ' + 17: 0, # '×§' + 7: 0, # 'ר' + 10: 0, # 'ש' + 5: 0, # 'ת' + 32: 0, # '–' + 52: 1, # '’' + 47: 0, # '“' + 46: 0, # 'â€' + 58: 0, # '†' + 40: 0, # '…' + }, + 34: { # '\xa0' + 50: 1, # 'a' + 60: 0, # 'c' + 61: 1, # 'd' + 42: 0, # 'e' + 53: 1, # 'i' + 56: 0, # 'l' + 54: 1, # 'n' + 49: 1, # 'o' + 51: 0, # 'r' + 43: 1, # 's' + 44: 1, # 't' + 63: 0, # 'u' + 34: 2, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'Ö°' + 59: 0, # 'Ö±' + 41: 0, # 'Ö²' + 33: 0, # 'Ö´' + 37: 0, # 'Öµ' + 36: 0, # 'Ö¶' + 31: 0, # 'Ö·' + 29: 0, # 'Ö¸' + 35: 0, # 'Ö¹' + 62: 0, # 'Ö»' + 28: 0, # 'Ö¼' + 38: 0, # '×' + 45: 0, # 'ׂ' + 9: 2, # '×' + 8: 1, # 'ב' + 20: 1, # '×’' + 16: 1, # 'ד' + 3: 1, # '×”' + 2: 1, # 'ו' + 24: 1, # '×–' + 14: 1, # '×—' + 22: 1, # 'ט' + 1: 2, # '×™' + 25: 0, # 'ך' + 15: 1, # '×›' + 4: 1, # 'ל' + 11: 0, # '×' + 6: 2, # 'מ' + 23: 0, # 'ן' + 12: 1, # '× ' + 19: 1, # 'ס' + 13: 1, # '×¢' + 26: 0, # '×£' + 18: 1, # 'פ' + 27: 0, # '×¥' + 21: 1, # 'צ' + 17: 1, # '×§' + 7: 1, # 'ר' + 10: 1, # 'ש' + 5: 1, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 0, # 'â€' + 58: 0, # '†' + 40: 0, # '…' + }, + 55: { # '´' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 1, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'Ö°' + 59: 0, # 'Ö±' + 41: 0, # 'Ö²' + 33: 0, # 'Ö´' + 37: 0, # 'Öµ' + 36: 0, # 'Ö¶' + 31: 0, # 'Ö·' + 29: 0, # 'Ö¸' + 35: 0, # 'Ö¹' + 62: 0, # 'Ö»' + 28: 0, # 'Ö¼' + 38: 0, # '×' + 45: 0, # 'ׂ' + 9: 1, # '×' + 8: 0, # 'ב' + 20: 0, # '×’' + 16: 0, # 'ד' + 3: 1, # '×”' + 2: 1, # 'ו' + 24: 0, # '×–' + 14: 0, # '×—' + 22: 0, # 'ט' + 1: 2, # '×™' + 25: 0, # 'ך' + 15: 0, # '×›' + 4: 1, # 'ל' + 11: 0, # '×' + 6: 1, # 'מ' + 23: 1, # 'ן' + 12: 1, # '× ' + 19: 1, # 'ס' + 13: 0, # '×¢' + 26: 0, # '×£' + 18: 0, # 'פ' + 27: 0, # '×¥' + 21: 0, # 'צ' + 17: 0, # '×§' + 7: 1, # 'ר' + 10: 1, # 'ש' + 5: 0, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 0, # 'â€' + 58: 0, # '†' + 40: 0, # '…' + }, + 48: { # '¼' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'Ö°' + 59: 0, # 'Ö±' + 41: 0, # 'Ö²' + 33: 0, # 'Ö´' + 37: 0, # 'Öµ' + 36: 0, # 'Ö¶' + 31: 0, # 'Ö·' + 29: 0, # 'Ö¸' + 35: 0, # 'Ö¹' + 62: 0, # 'Ö»' + 28: 0, # 'Ö¼' + 38: 0, # '×' + 45: 0, # 'ׂ' + 9: 1, # '×' + 8: 0, # 'ב' + 20: 0, # '×’' + 16: 0, # 'ד' + 3: 0, # '×”' + 2: 1, # 'ו' + 24: 0, # '×–' + 14: 0, # '×—' + 22: 0, # 'ט' + 1: 0, # '×™' + 25: 0, # 'ך' + 15: 1, # '×›' + 4: 1, # 'ל' + 11: 0, # '×' + 6: 1, # 'מ' + 23: 0, # 'ן' + 12: 0, # '× ' + 19: 0, # 'ס' + 13: 0, # '×¢' + 26: 0, # '×£' + 18: 0, # 'פ' + 27: 0, # '×¥' + 21: 0, # 'צ' + 17: 0, # '×§' + 7: 0, # 'ר' + 10: 0, # 'ש' + 5: 0, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 0, # 'â€' + 58: 0, # '†' + 40: 0, # '…' + }, + 39: { # '½' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'Ö°' + 59: 0, # 'Ö±' + 41: 0, # 'Ö²' + 33: 0, # 'Ö´' + 37: 0, # 'Öµ' + 36: 0, # 'Ö¶' + 31: 0, # 'Ö·' + 29: 0, # 'Ö¸' + 35: 0, # 'Ö¹' + 62: 0, # 'Ö»' + 28: 0, # 'Ö¼' + 38: 0, # '×' + 45: 0, # 'ׂ' + 9: 0, # '×' + 8: 0, # 'ב' + 20: 0, # '×’' + 16: 0, # 'ד' + 3: 0, # '×”' + 2: 0, # 'ו' + 24: 0, # '×–' + 14: 0, # '×—' + 22: 0, # 'ט' + 1: 0, # '×™' + 25: 0, # 'ך' + 15: 1, # '×›' + 4: 1, # 'ל' + 11: 0, # '×' + 6: 0, # 'מ' + 23: 0, # 'ן' + 12: 0, # '× ' + 19: 0, # 'ס' + 13: 0, # '×¢' + 26: 0, # '×£' + 18: 0, # 'פ' + 27: 0, # '×¥' + 21: 1, # 'צ' + 17: 1, # '×§' + 7: 0, # 'ר' + 10: 0, # 'ש' + 5: 0, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 0, # 'â€' + 58: 0, # '†' + 40: 0, # '…' + }, + 57: { # '¾' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'Ö°' + 59: 0, # 'Ö±' + 41: 0, # 'Ö²' + 33: 0, # 'Ö´' + 37: 0, # 'Öµ' + 36: 0, # 'Ö¶' + 31: 0, # 'Ö·' + 29: 0, # 'Ö¸' + 35: 0, # 'Ö¹' + 62: 0, # 'Ö»' + 28: 0, # 'Ö¼' + 38: 0, # '×' + 45: 0, # 'ׂ' + 9: 0, # '×' + 8: 0, # 'ב' + 20: 0, # '×’' + 16: 0, # 'ד' + 3: 0, # '×”' + 2: 0, # 'ו' + 24: 0, # '×–' + 14: 0, # '×—' + 22: 0, # 'ט' + 1: 0, # '×™' + 25: 0, # 'ך' + 15: 0, # '×›' + 4: 0, # 'ל' + 11: 0, # '×' + 6: 0, # 'מ' + 23: 0, # 'ן' + 12: 0, # '× ' + 19: 0, # 'ס' + 13: 0, # '×¢' + 26: 0, # '×£' + 18: 0, # 'פ' + 27: 0, # '×¥' + 21: 0, # 'צ' + 17: 0, # '×§' + 7: 0, # 'ר' + 10: 0, # 'ש' + 5: 0, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 0, # 'â€' + 58: 0, # '†' + 40: 0, # '…' + }, + 30: { # 'Ö°' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'Ö°' + 59: 0, # 'Ö±' + 41: 0, # 'Ö²' + 33: 0, # 'Ö´' + 37: 0, # 'Öµ' + 36: 1, # 'Ö¶' + 31: 0, # 'Ö·' + 29: 0, # 'Ö¸' + 35: 1, # 'Ö¹' + 62: 0, # 'Ö»' + 28: 0, # 'Ö¼' + 38: 0, # '×' + 45: 0, # 'ׂ' + 9: 2, # '×' + 8: 2, # 'ב' + 20: 2, # '×’' + 16: 2, # 'ד' + 3: 2, # '×”' + 2: 2, # 'ו' + 24: 2, # '×–' + 14: 2, # '×—' + 22: 2, # 'ט' + 1: 2, # '×™' + 25: 2, # 'ך' + 15: 2, # '×›' + 4: 2, # 'ל' + 11: 1, # '×' + 6: 2, # 'מ' + 23: 0, # 'ן' + 12: 2, # '× ' + 19: 2, # 'ס' + 13: 2, # '×¢' + 26: 0, # '×£' + 18: 2, # 'פ' + 27: 0, # '×¥' + 21: 2, # 'צ' + 17: 2, # '×§' + 7: 2, # 'ר' + 10: 2, # 'ש' + 5: 2, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 0, # 'â€' + 58: 0, # '†' + 40: 0, # '…' + }, + 59: { # 'Ö±' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 1, # 'Ö°' + 59: 0, # 'Ö±' + 41: 0, # 'Ö²' + 33: 0, # 'Ö´' + 37: 0, # 'Öµ' + 36: 0, # 'Ö¶' + 31: 0, # 'Ö·' + 29: 0, # 'Ö¸' + 35: 0, # 'Ö¹' + 62: 0, # 'Ö»' + 28: 0, # 'Ö¼' + 38: 0, # '×' + 45: 0, # 'ׂ' + 9: 0, # '×' + 8: 1, # 'ב' + 20: 1, # '×’' + 16: 0, # 'ד' + 3: 0, # '×”' + 2: 0, # 'ו' + 24: 1, # '×–' + 14: 0, # '×—' + 22: 0, # 'ט' + 1: 1, # '×™' + 25: 0, # 'ך' + 15: 1, # '×›' + 4: 2, # 'ל' + 11: 0, # '×' + 6: 2, # 'מ' + 23: 0, # 'ן' + 12: 1, # '× ' + 19: 0, # 'ס' + 13: 0, # '×¢' + 26: 0, # '×£' + 18: 0, # 'פ' + 27: 0, # '×¥' + 21: 0, # 'צ' + 17: 0, # '×§' + 7: 1, # 'ר' + 10: 1, # 'ש' + 5: 0, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 0, # 'â€' + 58: 0, # '†' + 40: 0, # '…' + }, + 41: { # 'Ö²' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'Ö°' + 59: 0, # 'Ö±' + 41: 0, # 'Ö²' + 33: 0, # 'Ö´' + 37: 0, # 'Öµ' + 36: 0, # 'Ö¶' + 31: 0, # 'Ö·' + 29: 0, # 'Ö¸' + 35: 0, # 'Ö¹' + 62: 0, # 'Ö»' + 28: 0, # 'Ö¼' + 38: 0, # '×' + 45: 0, # 'ׂ' + 9: 0, # '×' + 8: 2, # 'ב' + 20: 1, # '×’' + 16: 2, # 'ד' + 3: 1, # '×”' + 2: 1, # 'ו' + 24: 1, # '×–' + 14: 1, # '×—' + 22: 1, # 'ט' + 1: 1, # '×™' + 25: 1, # 'ך' + 15: 1, # '×›' + 4: 2, # 'ל' + 11: 0, # '×' + 6: 2, # 'מ' + 23: 0, # 'ן' + 12: 2, # '× ' + 19: 1, # 'ס' + 13: 0, # '×¢' + 26: 0, # '×£' + 18: 1, # 'פ' + 27: 0, # '×¥' + 21: 2, # 'צ' + 17: 1, # '×§' + 7: 2, # 'ר' + 10: 2, # 'ש' + 5: 1, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 0, # 'â€' + 58: 0, # '†' + 40: 0, # '…' + }, + 33: { # 'Ö´' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 1, # 'Ö°' + 59: 0, # 'Ö±' + 41: 0, # 'Ö²' + 33: 1, # 'Ö´' + 37: 0, # 'Öµ' + 36: 1, # 'Ö¶' + 31: 0, # 'Ö·' + 29: 1, # 'Ö¸' + 35: 0, # 'Ö¹' + 62: 0, # 'Ö»' + 28: 1, # 'Ö¼' + 38: 0, # '×' + 45: 0, # 'ׂ' + 9: 1, # '×' + 8: 2, # 'ב' + 20: 2, # '×’' + 16: 2, # 'ד' + 3: 1, # '×”' + 2: 1, # 'ו' + 24: 2, # '×–' + 14: 1, # '×—' + 22: 1, # 'ט' + 1: 3, # '×™' + 25: 1, # 'ך' + 15: 2, # '×›' + 4: 2, # 'ל' + 11: 2, # '×' + 6: 2, # 'מ' + 23: 2, # 'ן' + 12: 2, # '× ' + 19: 2, # 'ס' + 13: 1, # '×¢' + 26: 0, # '×£' + 18: 2, # 'פ' + 27: 1, # '×¥' + 21: 2, # 'צ' + 17: 2, # '×§' + 7: 2, # 'ר' + 10: 2, # 'ש' + 5: 2, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 0, # 'â€' + 58: 0, # '†' + 40: 0, # '…' + }, + 37: { # 'Öµ' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'Ö°' + 59: 0, # 'Ö±' + 41: 0, # 'Ö²' + 33: 0, # 'Ö´' + 37: 0, # 'Öµ' + 36: 1, # 'Ö¶' + 31: 1, # 'Ö·' + 29: 1, # 'Ö¸' + 35: 0, # 'Ö¹' + 62: 0, # 'Ö»' + 28: 0, # 'Ö¼' + 38: 0, # '×' + 45: 0, # 'ׂ' + 9: 2, # '×' + 8: 2, # 'ב' + 20: 1, # '×’' + 16: 2, # 'ד' + 3: 2, # '×”' + 2: 1, # 'ו' + 24: 1, # '×–' + 14: 2, # '×—' + 22: 1, # 'ט' + 1: 3, # '×™' + 25: 2, # 'ך' + 15: 1, # '×›' + 4: 2, # 'ל' + 11: 2, # '×' + 6: 1, # 'מ' + 23: 2, # 'ן' + 12: 2, # '× ' + 19: 1, # 'ס' + 13: 2, # '×¢' + 26: 1, # '×£' + 18: 1, # 'פ' + 27: 1, # '×¥' + 21: 1, # 'צ' + 17: 1, # '×§' + 7: 2, # 'ר' + 10: 2, # 'ש' + 5: 2, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 0, # 'â€' + 58: 0, # '†' + 40: 0, # '…' + }, + 36: { # 'Ö¶' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'Ö°' + 59: 0, # 'Ö±' + 41: 0, # 'Ö²' + 33: 0, # 'Ö´' + 37: 0, # 'Öµ' + 36: 1, # 'Ö¶' + 31: 1, # 'Ö·' + 29: 1, # 'Ö¸' + 35: 0, # 'Ö¹' + 62: 0, # 'Ö»' + 28: 0, # 'Ö¼' + 38: 0, # '×' + 45: 0, # 'ׂ' + 9: 2, # '×' + 8: 2, # 'ב' + 20: 1, # '×’' + 16: 2, # 'ד' + 3: 2, # '×”' + 2: 1, # 'ו' + 24: 1, # '×–' + 14: 2, # '×—' + 22: 1, # 'ט' + 1: 2, # '×™' + 25: 2, # 'ך' + 15: 1, # '×›' + 4: 2, # 'ל' + 11: 2, # '×' + 6: 2, # 'מ' + 23: 2, # 'ן' + 12: 2, # '× ' + 19: 2, # 'ס' + 13: 1, # '×¢' + 26: 1, # '×£' + 18: 1, # 'פ' + 27: 2, # '×¥' + 21: 1, # 'צ' + 17: 1, # '×§' + 7: 2, # 'ר' + 10: 2, # 'ש' + 5: 2, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 0, # 'â€' + 58: 0, # '†' + 40: 0, # '…' + }, + 31: { # 'Ö·' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 1, # 'Ö°' + 59: 0, # 'Ö±' + 41: 0, # 'Ö²' + 33: 0, # 'Ö´' + 37: 0, # 'Öµ' + 36: 1, # 'Ö¶' + 31: 0, # 'Ö·' + 29: 2, # 'Ö¸' + 35: 0, # 'Ö¹' + 62: 0, # 'Ö»' + 28: 0, # 'Ö¼' + 38: 0, # '×' + 45: 0, # 'ׂ' + 9: 2, # '×' + 8: 2, # 'ב' + 20: 2, # '×’' + 16: 2, # 'ד' + 3: 2, # '×”' + 2: 1, # 'ו' + 24: 2, # '×–' + 14: 2, # '×—' + 22: 2, # 'ט' + 1: 3, # '×™' + 25: 1, # 'ך' + 15: 2, # '×›' + 4: 2, # 'ל' + 11: 2, # '×' + 6: 2, # 'מ' + 23: 2, # 'ן' + 12: 2, # '× ' + 19: 2, # 'ס' + 13: 2, # '×¢' + 26: 2, # '×£' + 18: 2, # 'פ' + 27: 1, # '×¥' + 21: 2, # 'צ' + 17: 2, # '×§' + 7: 2, # 'ר' + 10: 2, # 'ש' + 5: 2, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 0, # 'â€' + 58: 0, # '†' + 40: 0, # '…' + }, + 29: { # 'Ö¸' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'Ö°' + 59: 0, # 'Ö±' + 41: 0, # 'Ö²' + 33: 0, # 'Ö´' + 37: 0, # 'Öµ' + 36: 0, # 'Ö¶' + 31: 1, # 'Ö·' + 29: 2, # 'Ö¸' + 35: 0, # 'Ö¹' + 62: 0, # 'Ö»' + 28: 1, # 'Ö¼' + 38: 0, # '×' + 45: 0, # 'ׂ' + 9: 2, # '×' + 8: 2, # 'ב' + 20: 2, # '×’' + 16: 2, # 'ד' + 3: 3, # '×”' + 2: 2, # 'ו' + 24: 2, # '×–' + 14: 2, # '×—' + 22: 1, # 'ט' + 1: 2, # '×™' + 25: 2, # 'ך' + 15: 2, # '×›' + 4: 2, # 'ל' + 11: 2, # '×' + 6: 2, # 'מ' + 23: 2, # 'ן' + 12: 2, # '× ' + 19: 1, # 'ס' + 13: 2, # '×¢' + 26: 1, # '×£' + 18: 2, # 'פ' + 27: 1, # '×¥' + 21: 2, # 'צ' + 17: 2, # '×§' + 7: 2, # 'ר' + 10: 2, # 'ש' + 5: 2, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 0, # 'â€' + 58: 0, # '†' + 40: 0, # '…' + }, + 35: { # 'Ö¹' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'Ö°' + 59: 0, # 'Ö±' + 41: 0, # 'Ö²' + 33: 0, # 'Ö´' + 37: 0, # 'Öµ' + 36: 0, # 'Ö¶' + 31: 0, # 'Ö·' + 29: 0, # 'Ö¸' + 35: 1, # 'Ö¹' + 62: 0, # 'Ö»' + 28: 0, # 'Ö¼' + 38: 0, # '×' + 45: 0, # 'ׂ' + 9: 2, # '×' + 8: 2, # 'ב' + 20: 1, # '×’' + 16: 2, # 'ד' + 3: 2, # '×”' + 2: 1, # 'ו' + 24: 1, # '×–' + 14: 1, # '×—' + 22: 1, # 'ט' + 1: 1, # '×™' + 25: 1, # 'ך' + 15: 2, # '×›' + 4: 2, # 'ל' + 11: 2, # '×' + 6: 2, # 'מ' + 23: 2, # 'ן' + 12: 2, # '× ' + 19: 2, # 'ס' + 13: 2, # '×¢' + 26: 1, # '×£' + 18: 2, # 'פ' + 27: 1, # '×¥' + 21: 2, # 'צ' + 17: 2, # '×§' + 7: 2, # 'ר' + 10: 2, # 'ש' + 5: 2, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 0, # 'â€' + 58: 0, # '†' + 40: 0, # '…' + }, + 62: { # 'Ö»' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'Ö°' + 59: 0, # 'Ö±' + 41: 0, # 'Ö²' + 33: 0, # 'Ö´' + 37: 0, # 'Öµ' + 36: 0, # 'Ö¶' + 31: 0, # 'Ö·' + 29: 0, # 'Ö¸' + 35: 0, # 'Ö¹' + 62: 0, # 'Ö»' + 28: 0, # 'Ö¼' + 38: 0, # '×' + 45: 0, # 'ׂ' + 9: 0, # '×' + 8: 1, # 'ב' + 20: 1, # '×’' + 16: 1, # 'ד' + 3: 1, # '×”' + 2: 1, # 'ו' + 24: 1, # '×–' + 14: 1, # '×—' + 22: 0, # 'ט' + 1: 1, # '×™' + 25: 0, # 'ך' + 15: 1, # '×›' + 4: 2, # 'ל' + 11: 1, # '×' + 6: 1, # 'מ' + 23: 1, # 'ן' + 12: 1, # '× ' + 19: 1, # 'ס' + 13: 1, # '×¢' + 26: 0, # '×£' + 18: 1, # 'פ' + 27: 0, # '×¥' + 21: 1, # 'צ' + 17: 1, # '×§' + 7: 1, # 'ר' + 10: 1, # 'ש' + 5: 1, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 0, # 'â€' + 58: 0, # '†' + 40: 0, # '…' + }, + 28: { # 'Ö¼' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 3, # 'Ö°' + 59: 0, # 'Ö±' + 41: 1, # 'Ö²' + 33: 3, # 'Ö´' + 37: 2, # 'Öµ' + 36: 2, # 'Ö¶' + 31: 3, # 'Ö·' + 29: 3, # 'Ö¸' + 35: 2, # 'Ö¹' + 62: 1, # 'Ö»' + 28: 0, # 'Ö¼' + 38: 2, # '×' + 45: 1, # 'ׂ' + 9: 2, # '×' + 8: 2, # 'ב' + 20: 1, # '×’' + 16: 2, # 'ד' + 3: 1, # '×”' + 2: 2, # 'ו' + 24: 1, # '×–' + 14: 1, # '×—' + 22: 1, # 'ט' + 1: 2, # '×™' + 25: 2, # 'ך' + 15: 2, # '×›' + 4: 2, # 'ל' + 11: 1, # '×' + 6: 2, # 'מ' + 23: 1, # 'ן' + 12: 2, # '× ' + 19: 1, # 'ס' + 13: 2, # '×¢' + 26: 1, # '×£' + 18: 1, # 'פ' + 27: 1, # '×¥' + 21: 1, # 'צ' + 17: 1, # '×§' + 7: 2, # 'ר' + 10: 2, # 'ש' + 5: 2, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 0, # 'â€' + 58: 0, # '†' + 40: 0, # '…' + }, + 38: { # '×' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 2, # 'Ö°' + 59: 0, # 'Ö±' + 41: 0, # 'Ö²' + 33: 2, # 'Ö´' + 37: 2, # 'Öµ' + 36: 2, # 'Ö¶' + 31: 2, # 'Ö·' + 29: 2, # 'Ö¸' + 35: 1, # 'Ö¹' + 62: 1, # 'Ö»' + 28: 0, # 'Ö¼' + 38: 0, # '×' + 45: 0, # 'ׂ' + 9: 0, # '×' + 8: 0, # 'ב' + 20: 0, # '×’' + 16: 0, # 'ד' + 3: 0, # '×”' + 2: 2, # 'ו' + 24: 0, # '×–' + 14: 0, # '×—' + 22: 0, # 'ט' + 1: 1, # '×™' + 25: 0, # 'ך' + 15: 0, # '×›' + 4: 0, # 'ל' + 11: 0, # '×' + 6: 0, # 'מ' + 23: 0, # 'ן' + 12: 0, # '× ' + 19: 0, # 'ס' + 13: 1, # '×¢' + 26: 0, # '×£' + 18: 0, # 'פ' + 27: 0, # '×¥' + 21: 0, # 'צ' + 17: 0, # '×§' + 7: 0, # 'ר' + 10: 0, # 'ש' + 5: 0, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 0, # 'â€' + 58: 0, # '†' + 40: 0, # '…' + }, + 45: { # 'ׂ' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 2, # 'Ö°' + 59: 0, # 'Ö±' + 41: 0, # 'Ö²' + 33: 2, # 'Ö´' + 37: 1, # 'Öµ' + 36: 2, # 'Ö¶' + 31: 1, # 'Ö·' + 29: 2, # 'Ö¸' + 35: 1, # 'Ö¹' + 62: 0, # 'Ö»' + 28: 0, # 'Ö¼' + 38: 0, # '×' + 45: 0, # 'ׂ' + 9: 1, # '×' + 8: 0, # 'ב' + 20: 1, # '×’' + 16: 0, # 'ד' + 3: 1, # '×”' + 2: 2, # 'ו' + 24: 0, # '×–' + 14: 1, # '×—' + 22: 0, # 'ט' + 1: 1, # '×™' + 25: 0, # 'ך' + 15: 0, # '×›' + 4: 0, # 'ל' + 11: 1, # '×' + 6: 1, # 'מ' + 23: 0, # 'ן' + 12: 1, # '× ' + 19: 0, # 'ס' + 13: 1, # '×¢' + 26: 0, # '×£' + 18: 1, # 'פ' + 27: 0, # '×¥' + 21: 0, # 'צ' + 17: 0, # '×§' + 7: 1, # 'ר' + 10: 0, # 'ש' + 5: 1, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 0, # 'â€' + 58: 0, # '†' + 40: 0, # '…' + }, + 9: { # '×' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 1, # '\xa0' + 55: 1, # '´' + 48: 1, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'Ö°' + 59: 2, # 'Ö±' + 41: 2, # 'Ö²' + 33: 2, # 'Ö´' + 37: 2, # 'Öµ' + 36: 2, # 'Ö¶' + 31: 2, # 'Ö·' + 29: 2, # 'Ö¸' + 35: 2, # 'Ö¹' + 62: 1, # 'Ö»' + 28: 0, # 'Ö¼' + 38: 0, # '×' + 45: 0, # 'ׂ' + 9: 2, # '×' + 8: 3, # 'ב' + 20: 3, # '×’' + 16: 3, # 'ד' + 3: 3, # '×”' + 2: 3, # 'ו' + 24: 3, # '×–' + 14: 3, # '×—' + 22: 3, # 'ט' + 1: 3, # '×™' + 25: 3, # 'ך' + 15: 3, # '×›' + 4: 3, # 'ל' + 11: 3, # '×' + 6: 3, # 'מ' + 23: 3, # 'ן' + 12: 3, # '× ' + 19: 3, # 'ס' + 13: 2, # '×¢' + 26: 3, # '×£' + 18: 3, # 'פ' + 27: 1, # '×¥' + 21: 3, # 'צ' + 17: 3, # '×§' + 7: 3, # 'ר' + 10: 3, # 'ש' + 5: 3, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 1, # 'â€' + 58: 0, # '†' + 40: 1, # '…' + }, + 8: { # 'ב' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 1, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 1, # '\xa0' + 55: 1, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 2, # 'Ö°' + 59: 0, # 'Ö±' + 41: 0, # 'Ö²' + 33: 2, # 'Ö´' + 37: 2, # 'Öµ' + 36: 2, # 'Ö¶' + 31: 2, # 'Ö·' + 29: 2, # 'Ö¸' + 35: 2, # 'Ö¹' + 62: 1, # 'Ö»' + 28: 3, # 'Ö¼' + 38: 0, # '×' + 45: 0, # 'ׂ' + 9: 3, # '×' + 8: 3, # 'ב' + 20: 3, # '×’' + 16: 3, # 'ד' + 3: 3, # '×”' + 2: 3, # 'ו' + 24: 3, # '×–' + 14: 3, # '×—' + 22: 3, # 'ט' + 1: 3, # '×™' + 25: 2, # 'ך' + 15: 3, # '×›' + 4: 3, # 'ל' + 11: 2, # '×' + 6: 3, # 'מ' + 23: 3, # 'ן' + 12: 3, # '× ' + 19: 3, # 'ס' + 13: 3, # '×¢' + 26: 1, # '×£' + 18: 3, # 'פ' + 27: 2, # '×¥' + 21: 3, # 'צ' + 17: 3, # '×§' + 7: 3, # 'ר' + 10: 3, # 'ש' + 5: 3, # 'ת' + 32: 1, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 1, # 'â€' + 58: 0, # '†' + 40: 1, # '…' + }, + 20: { # '×’' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 1, # '\xa0' + 55: 2, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 2, # 'Ö°' + 59: 0, # 'Ö±' + 41: 0, # 'Ö²' + 33: 1, # 'Ö´' + 37: 1, # 'Öµ' + 36: 1, # 'Ö¶' + 31: 2, # 'Ö·' + 29: 2, # 'Ö¸' + 35: 1, # 'Ö¹' + 62: 0, # 'Ö»' + 28: 2, # 'Ö¼' + 38: 0, # '×' + 45: 0, # 'ׂ' + 9: 2, # '×' + 8: 3, # 'ב' + 20: 2, # '×’' + 16: 3, # 'ד' + 3: 3, # '×”' + 2: 3, # 'ו' + 24: 3, # '×–' + 14: 2, # '×—' + 22: 2, # 'ט' + 1: 3, # '×™' + 25: 1, # 'ך' + 15: 1, # '×›' + 4: 3, # 'ל' + 11: 3, # '×' + 6: 3, # 'מ' + 23: 3, # 'ן' + 12: 3, # '× ' + 19: 2, # 'ס' + 13: 3, # '×¢' + 26: 2, # '×£' + 18: 2, # 'פ' + 27: 1, # '×¥' + 21: 1, # 'צ' + 17: 1, # '×§' + 7: 3, # 'ר' + 10: 3, # 'ש' + 5: 3, # 'ת' + 32: 0, # '–' + 52: 1, # '’' + 47: 0, # '“' + 46: 1, # 'â€' + 58: 0, # '†' + 40: 0, # '…' + }, + 16: { # 'ד' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 2, # 'Ö°' + 59: 0, # 'Ö±' + 41: 0, # 'Ö²' + 33: 2, # 'Ö´' + 37: 2, # 'Öµ' + 36: 2, # 'Ö¶' + 31: 2, # 'Ö·' + 29: 2, # 'Ö¸' + 35: 2, # 'Ö¹' + 62: 1, # 'Ö»' + 28: 2, # 'Ö¼' + 38: 0, # '×' + 45: 0, # 'ׂ' + 9: 3, # '×' + 8: 3, # 'ב' + 20: 3, # '×’' + 16: 3, # 'ד' + 3: 3, # '×”' + 2: 3, # 'ו' + 24: 1, # '×–' + 14: 2, # '×—' + 22: 2, # 'ט' + 1: 3, # '×™' + 25: 2, # 'ך' + 15: 2, # '×›' + 4: 3, # 'ל' + 11: 3, # '×' + 6: 3, # 'מ' + 23: 2, # 'ן' + 12: 3, # '× ' + 19: 2, # 'ס' + 13: 3, # '×¢' + 26: 2, # '×£' + 18: 3, # 'פ' + 27: 0, # '×¥' + 21: 2, # 'צ' + 17: 3, # '×§' + 7: 3, # 'ר' + 10: 3, # 'ש' + 5: 3, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 1, # 'â€' + 58: 0, # '†' + 40: 1, # '…' + }, + 3: { # '×”' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 1, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 1, # '\xa0' + 55: 0, # '´' + 48: 1, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 1, # 'Ö°' + 59: 1, # 'Ö±' + 41: 2, # 'Ö²' + 33: 2, # 'Ö´' + 37: 2, # 'Öµ' + 36: 2, # 'Ö¶' + 31: 3, # 'Ö·' + 29: 2, # 'Ö¸' + 35: 1, # 'Ö¹' + 62: 1, # 'Ö»' + 28: 2, # 'Ö¼' + 38: 0, # '×' + 45: 0, # 'ׂ' + 9: 3, # '×' + 8: 3, # 'ב' + 20: 3, # '×’' + 16: 3, # 'ד' + 3: 3, # '×”' + 2: 3, # 'ו' + 24: 3, # '×–' + 14: 3, # '×—' + 22: 3, # 'ט' + 1: 3, # '×™' + 25: 1, # 'ך' + 15: 3, # '×›' + 4: 3, # 'ל' + 11: 3, # '×' + 6: 3, # 'מ' + 23: 3, # 'ן' + 12: 3, # '× ' + 19: 3, # 'ס' + 13: 3, # '×¢' + 26: 0, # '×£' + 18: 3, # 'פ' + 27: 1, # '×¥' + 21: 3, # 'צ' + 17: 3, # '×§' + 7: 3, # 'ר' + 10: 3, # 'ש' + 5: 3, # 'ת' + 32: 1, # '–' + 52: 1, # '’' + 47: 0, # '“' + 46: 1, # 'â€' + 58: 0, # '†' + 40: 2, # '…' + }, + 2: { # 'ו' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 1, # 't' + 63: 0, # 'u' + 34: 1, # '\xa0' + 55: 1, # '´' + 48: 1, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 2, # 'Ö°' + 59: 0, # 'Ö±' + 41: 0, # 'Ö²' + 33: 2, # 'Ö´' + 37: 1, # 'Öµ' + 36: 1, # 'Ö¶' + 31: 2, # 'Ö·' + 29: 2, # 'Ö¸' + 35: 3, # 'Ö¹' + 62: 0, # 'Ö»' + 28: 3, # 'Ö¼' + 38: 0, # '×' + 45: 0, # 'ׂ' + 9: 3, # '×' + 8: 3, # 'ב' + 20: 3, # '×’' + 16: 3, # 'ד' + 3: 3, # '×”' + 2: 3, # 'ו' + 24: 3, # '×–' + 14: 3, # '×—' + 22: 3, # 'ט' + 1: 3, # '×™' + 25: 3, # 'ך' + 15: 3, # '×›' + 4: 3, # 'ל' + 11: 3, # '×' + 6: 3, # 'מ' + 23: 3, # 'ן' + 12: 3, # '× ' + 19: 3, # 'ס' + 13: 3, # '×¢' + 26: 3, # '×£' + 18: 3, # 'פ' + 27: 3, # '×¥' + 21: 3, # 'צ' + 17: 3, # '×§' + 7: 3, # 'ר' + 10: 3, # 'ש' + 5: 3, # 'ת' + 32: 1, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 1, # 'â€' + 58: 0, # '†' + 40: 2, # '…' + }, + 24: { # '×–' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 1, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 2, # 'Ö°' + 59: 0, # 'Ö±' + 41: 1, # 'Ö²' + 33: 1, # 'Ö´' + 37: 2, # 'Öµ' + 36: 2, # 'Ö¶' + 31: 2, # 'Ö·' + 29: 2, # 'Ö¸' + 35: 1, # 'Ö¹' + 62: 1, # 'Ö»' + 28: 2, # 'Ö¼' + 38: 0, # '×' + 45: 0, # 'ׂ' + 9: 3, # '×' + 8: 2, # 'ב' + 20: 2, # '×’' + 16: 2, # 'ד' + 3: 3, # '×”' + 2: 3, # 'ו' + 24: 2, # '×–' + 14: 2, # '×—' + 22: 1, # 'ט' + 1: 3, # '×™' + 25: 1, # 'ך' + 15: 3, # '×›' + 4: 3, # 'ל' + 11: 2, # '×' + 6: 3, # 'מ' + 23: 2, # 'ן' + 12: 2, # '× ' + 19: 1, # 'ס' + 13: 2, # '×¢' + 26: 1, # '×£' + 18: 1, # 'פ' + 27: 0, # '×¥' + 21: 2, # 'צ' + 17: 3, # '×§' + 7: 3, # 'ר' + 10: 1, # 'ש' + 5: 2, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 0, # 'â€' + 58: 0, # '†' + 40: 1, # '…' + }, + 14: { # '×—' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 1, # '\xa0' + 55: 1, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 2, # 'Ö°' + 59: 1, # 'Ö±' + 41: 2, # 'Ö²' + 33: 2, # 'Ö´' + 37: 2, # 'Öµ' + 36: 2, # 'Ö¶' + 31: 2, # 'Ö·' + 29: 2, # 'Ö¸' + 35: 2, # 'Ö¹' + 62: 1, # 'Ö»' + 28: 0, # 'Ö¼' + 38: 0, # '×' + 45: 0, # 'ׂ' + 9: 2, # '×' + 8: 3, # 'ב' + 20: 2, # '×’' + 16: 3, # 'ד' + 3: 3, # '×”' + 2: 3, # 'ו' + 24: 3, # '×–' + 14: 2, # '×—' + 22: 2, # 'ט' + 1: 3, # '×™' + 25: 1, # 'ך' + 15: 2, # '×›' + 4: 3, # 'ל' + 11: 3, # '×' + 6: 3, # 'מ' + 23: 2, # 'ן' + 12: 3, # '× ' + 19: 3, # 'ס' + 13: 1, # '×¢' + 26: 2, # '×£' + 18: 2, # 'פ' + 27: 2, # '×¥' + 21: 3, # 'צ' + 17: 3, # '×§' + 7: 3, # 'ר' + 10: 3, # 'ש' + 5: 3, # 'ת' + 32: 0, # '–' + 52: 1, # '’' + 47: 0, # '“' + 46: 1, # 'â€' + 58: 0, # '†' + 40: 1, # '…' + }, + 22: { # 'ט' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 1, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 2, # 'Ö°' + 59: 0, # 'Ö±' + 41: 0, # 'Ö²' + 33: 2, # 'Ö´' + 37: 1, # 'Öµ' + 36: 1, # 'Ö¶' + 31: 2, # 'Ö·' + 29: 1, # 'Ö¸' + 35: 1, # 'Ö¹' + 62: 1, # 'Ö»' + 28: 1, # 'Ö¼' + 38: 0, # '×' + 45: 0, # 'ׂ' + 9: 3, # '×' + 8: 3, # 'ב' + 20: 3, # '×’' + 16: 1, # 'ד' + 3: 3, # '×”' + 2: 3, # 'ו' + 24: 2, # '×–' + 14: 3, # '×—' + 22: 2, # 'ט' + 1: 3, # '×™' + 25: 1, # 'ך' + 15: 2, # '×›' + 4: 3, # 'ל' + 11: 2, # '×' + 6: 2, # 'מ' + 23: 2, # 'ן' + 12: 3, # '× ' + 19: 2, # 'ס' + 13: 3, # '×¢' + 26: 2, # '×£' + 18: 3, # 'פ' + 27: 1, # '×¥' + 21: 2, # 'צ' + 17: 2, # '×§' + 7: 3, # 'ר' + 10: 2, # 'ש' + 5: 3, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 0, # 'â€' + 58: 0, # '†' + 40: 1, # '…' + }, + 1: { # '×™' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 1, # '\xa0' + 55: 1, # '´' + 48: 1, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 2, # 'Ö°' + 59: 0, # 'Ö±' + 41: 0, # 'Ö²' + 33: 2, # 'Ö´' + 37: 2, # 'Öµ' + 36: 1, # 'Ö¶' + 31: 2, # 'Ö·' + 29: 2, # 'Ö¸' + 35: 2, # 'Ö¹' + 62: 1, # 'Ö»' + 28: 2, # 'Ö¼' + 38: 0, # '×' + 45: 0, # 'ׂ' + 9: 3, # '×' + 8: 3, # 'ב' + 20: 3, # '×’' + 16: 3, # 'ד' + 3: 3, # '×”' + 2: 3, # 'ו' + 24: 3, # '×–' + 14: 3, # '×—' + 22: 3, # 'ט' + 1: 3, # '×™' + 25: 3, # 'ך' + 15: 3, # '×›' + 4: 3, # 'ל' + 11: 3, # '×' + 6: 3, # 'מ' + 23: 3, # 'ן' + 12: 3, # '× ' + 19: 3, # 'ס' + 13: 3, # '×¢' + 26: 3, # '×£' + 18: 3, # 'פ' + 27: 3, # '×¥' + 21: 3, # 'צ' + 17: 3, # '×§' + 7: 3, # 'ר' + 10: 3, # 'ש' + 5: 3, # 'ת' + 32: 1, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 1, # 'â€' + 58: 0, # '†' + 40: 2, # '…' + }, + 25: { # 'ך' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 2, # 'Ö°' + 59: 0, # 'Ö±' + 41: 0, # 'Ö²' + 33: 0, # 'Ö´' + 37: 0, # 'Öµ' + 36: 0, # 'Ö¶' + 31: 0, # 'Ö·' + 29: 2, # 'Ö¸' + 35: 0, # 'Ö¹' + 62: 0, # 'Ö»' + 28: 1, # 'Ö¼' + 38: 0, # '×' + 45: 0, # 'ׂ' + 9: 1, # '×' + 8: 0, # 'ב' + 20: 0, # '×’' + 16: 0, # 'ד' + 3: 1, # '×”' + 2: 0, # 'ו' + 24: 0, # '×–' + 14: 1, # '×—' + 22: 0, # 'ט' + 1: 0, # '×™' + 25: 0, # 'ך' + 15: 0, # '×›' + 4: 1, # 'ל' + 11: 0, # '×' + 6: 1, # 'מ' + 23: 0, # 'ן' + 12: 0, # '× ' + 19: 0, # 'ס' + 13: 0, # '×¢' + 26: 0, # '×£' + 18: 0, # 'פ' + 27: 0, # '×¥' + 21: 0, # 'צ' + 17: 0, # '×§' + 7: 0, # 'ר' + 10: 1, # 'ש' + 5: 0, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 0, # 'â€' + 58: 0, # '†' + 40: 1, # '…' + }, + 15: { # '×›' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 2, # 'Ö°' + 59: 0, # 'Ö±' + 41: 0, # 'Ö²' + 33: 2, # 'Ö´' + 37: 2, # 'Öµ' + 36: 2, # 'Ö¶' + 31: 2, # 'Ö·' + 29: 2, # 'Ö¸' + 35: 1, # 'Ö¹' + 62: 1, # 'Ö»' + 28: 3, # 'Ö¼' + 38: 0, # '×' + 45: 0, # 'ׂ' + 9: 3, # '×' + 8: 3, # 'ב' + 20: 2, # '×’' + 16: 3, # 'ד' + 3: 3, # '×”' + 2: 3, # 'ו' + 24: 3, # '×–' + 14: 3, # '×—' + 22: 2, # 'ט' + 1: 3, # '×™' + 25: 3, # 'ך' + 15: 3, # '×›' + 4: 3, # 'ל' + 11: 3, # '×' + 6: 3, # 'מ' + 23: 3, # 'ן' + 12: 3, # '× ' + 19: 3, # 'ס' + 13: 2, # '×¢' + 26: 3, # '×£' + 18: 3, # 'פ' + 27: 1, # '×¥' + 21: 2, # 'צ' + 17: 2, # '×§' + 7: 3, # 'ר' + 10: 3, # 'ש' + 5: 3, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 0, # 'â€' + 58: 0, # '†' + 40: 0, # '…' + }, + 4: { # 'ל' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 1, # '\xa0' + 55: 1, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 3, # 'Ö°' + 59: 0, # 'Ö±' + 41: 0, # 'Ö²' + 33: 2, # 'Ö´' + 37: 2, # 'Öµ' + 36: 2, # 'Ö¶' + 31: 2, # 'Ö·' + 29: 2, # 'Ö¸' + 35: 2, # 'Ö¹' + 62: 1, # 'Ö»' + 28: 2, # 'Ö¼' + 38: 0, # '×' + 45: 0, # 'ׂ' + 9: 3, # '×' + 8: 3, # 'ב' + 20: 3, # '×’' + 16: 3, # 'ד' + 3: 3, # '×”' + 2: 3, # 'ו' + 24: 3, # '×–' + 14: 3, # '×—' + 22: 3, # 'ט' + 1: 3, # '×™' + 25: 3, # 'ך' + 15: 3, # '×›' + 4: 3, # 'ל' + 11: 3, # '×' + 6: 3, # 'מ' + 23: 2, # 'ן' + 12: 3, # '× ' + 19: 3, # 'ס' + 13: 3, # '×¢' + 26: 2, # '×£' + 18: 3, # 'פ' + 27: 2, # '×¥' + 21: 3, # 'צ' + 17: 3, # '×§' + 7: 3, # 'ר' + 10: 3, # 'ש' + 5: 3, # 'ת' + 32: 1, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 1, # 'â€' + 58: 0, # '†' + 40: 1, # '…' + }, + 11: { # '×' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 1, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'Ö°' + 59: 0, # 'Ö±' + 41: 0, # 'Ö²' + 33: 0, # 'Ö´' + 37: 0, # 'Öµ' + 36: 0, # 'Ö¶' + 31: 0, # 'Ö·' + 29: 0, # 'Ö¸' + 35: 0, # 'Ö¹' + 62: 0, # 'Ö»' + 28: 0, # 'Ö¼' + 38: 0, # '×' + 45: 0, # 'ׂ' + 9: 1, # '×' + 8: 1, # 'ב' + 20: 1, # '×’' + 16: 0, # 'ד' + 3: 1, # '×”' + 2: 1, # 'ו' + 24: 1, # '×–' + 14: 1, # '×—' + 22: 0, # 'ט' + 1: 1, # '×™' + 25: 0, # 'ך' + 15: 1, # '×›' + 4: 1, # 'ל' + 11: 1, # '×' + 6: 1, # 'מ' + 23: 0, # 'ן' + 12: 1, # '× ' + 19: 0, # 'ס' + 13: 1, # '×¢' + 26: 0, # '×£' + 18: 1, # 'פ' + 27: 1, # '×¥' + 21: 1, # 'צ' + 17: 1, # '×§' + 7: 1, # 'ר' + 10: 1, # 'ש' + 5: 1, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 1, # 'â€' + 58: 0, # '†' + 40: 2, # '…' + }, + 6: { # 'מ' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 1, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 2, # 'Ö°' + 59: 0, # 'Ö±' + 41: 0, # 'Ö²' + 33: 2, # 'Ö´' + 37: 2, # 'Öµ' + 36: 2, # 'Ö¶' + 31: 2, # 'Ö·' + 29: 2, # 'Ö¸' + 35: 2, # 'Ö¹' + 62: 1, # 'Ö»' + 28: 2, # 'Ö¼' + 38: 0, # '×' + 45: 0, # 'ׂ' + 9: 3, # '×' + 8: 3, # 'ב' + 20: 3, # '×’' + 16: 3, # 'ד' + 3: 3, # '×”' + 2: 3, # 'ו' + 24: 3, # '×–' + 14: 3, # '×—' + 22: 3, # 'ט' + 1: 3, # '×™' + 25: 2, # 'ך' + 15: 3, # '×›' + 4: 3, # 'ל' + 11: 3, # '×' + 6: 3, # 'מ' + 23: 3, # 'ן' + 12: 3, # '× ' + 19: 3, # 'ס' + 13: 3, # '×¢' + 26: 0, # '×£' + 18: 3, # 'פ' + 27: 2, # '×¥' + 21: 3, # 'צ' + 17: 3, # '×§' + 7: 3, # 'ר' + 10: 3, # 'ש' + 5: 3, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 0, # 'â€' + 58: 0, # '†' + 40: 1, # '…' + }, + 23: { # 'ן' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 1, # '\xa0' + 55: 0, # '´' + 48: 1, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'Ö°' + 59: 0, # 'Ö±' + 41: 0, # 'Ö²' + 33: 0, # 'Ö´' + 37: 0, # 'Öµ' + 36: 0, # 'Ö¶' + 31: 0, # 'Ö·' + 29: 0, # 'Ö¸' + 35: 0, # 'Ö¹' + 62: 0, # 'Ö»' + 28: 0, # 'Ö¼' + 38: 0, # '×' + 45: 0, # 'ׂ' + 9: 1, # '×' + 8: 1, # 'ב' + 20: 1, # '×’' + 16: 1, # 'ד' + 3: 1, # '×”' + 2: 1, # 'ו' + 24: 0, # '×–' + 14: 1, # '×—' + 22: 1, # 'ט' + 1: 1, # '×™' + 25: 0, # 'ך' + 15: 1, # '×›' + 4: 1, # 'ל' + 11: 1, # '×' + 6: 1, # 'מ' + 23: 0, # 'ן' + 12: 1, # '× ' + 19: 1, # 'ס' + 13: 1, # '×¢' + 26: 1, # '×£' + 18: 1, # 'פ' + 27: 0, # '×¥' + 21: 0, # 'צ' + 17: 1, # '×§' + 7: 1, # 'ר' + 10: 1, # 'ש' + 5: 1, # 'ת' + 32: 1, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 1, # 'â€' + 58: 0, # '†' + 40: 2, # '…' + }, + 12: { # '× ' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 2, # 'Ö°' + 59: 0, # 'Ö±' + 41: 0, # 'Ö²' + 33: 2, # 'Ö´' + 37: 2, # 'Öµ' + 36: 2, # 'Ö¶' + 31: 2, # 'Ö·' + 29: 2, # 'Ö¸' + 35: 1, # 'Ö¹' + 62: 1, # 'Ö»' + 28: 2, # 'Ö¼' + 38: 0, # '×' + 45: 0, # 'ׂ' + 9: 3, # '×' + 8: 3, # 'ב' + 20: 3, # '×’' + 16: 3, # 'ד' + 3: 3, # '×”' + 2: 3, # 'ו' + 24: 3, # '×–' + 14: 3, # '×—' + 22: 3, # 'ט' + 1: 3, # '×™' + 25: 2, # 'ך' + 15: 3, # '×›' + 4: 3, # 'ל' + 11: 3, # '×' + 6: 3, # 'מ' + 23: 3, # 'ן' + 12: 3, # '× ' + 19: 3, # 'ס' + 13: 3, # '×¢' + 26: 2, # '×£' + 18: 3, # 'פ' + 27: 2, # '×¥' + 21: 3, # 'צ' + 17: 3, # '×§' + 7: 3, # 'ר' + 10: 3, # 'ש' + 5: 3, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 0, # 'â€' + 58: 0, # '†' + 40: 0, # '…' + }, + 19: { # 'ס' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 1, # '\xa0' + 55: 1, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 2, # 'Ö°' + 59: 0, # 'Ö±' + 41: 0, # 'Ö²' + 33: 2, # 'Ö´' + 37: 1, # 'Öµ' + 36: 2, # 'Ö¶' + 31: 2, # 'Ö·' + 29: 1, # 'Ö¸' + 35: 1, # 'Ö¹' + 62: 2, # 'Ö»' + 28: 2, # 'Ö¼' + 38: 0, # '×' + 45: 0, # 'ׂ' + 9: 2, # '×' + 8: 3, # 'ב' + 20: 3, # '×’' + 16: 3, # 'ד' + 3: 3, # '×”' + 2: 3, # 'ו' + 24: 1, # '×–' + 14: 3, # '×—' + 22: 3, # 'ט' + 1: 3, # '×™' + 25: 2, # 'ך' + 15: 3, # '×›' + 4: 3, # 'ל' + 11: 2, # '×' + 6: 3, # 'מ' + 23: 2, # 'ן' + 12: 3, # '× ' + 19: 2, # 'ס' + 13: 3, # '×¢' + 26: 3, # '×£' + 18: 3, # 'פ' + 27: 0, # '×¥' + 21: 2, # 'צ' + 17: 3, # '×§' + 7: 3, # 'ר' + 10: 1, # 'ש' + 5: 3, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 1, # 'â€' + 58: 0, # '†' + 40: 1, # '…' + }, + 13: { # '×¢' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 1, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 1, # 'Ö°' + 59: 1, # 'Ö±' + 41: 2, # 'Ö²' + 33: 2, # 'Ö´' + 37: 2, # 'Öµ' + 36: 2, # 'Ö¶' + 31: 2, # 'Ö·' + 29: 2, # 'Ö¸' + 35: 2, # 'Ö¹' + 62: 1, # 'Ö»' + 28: 0, # 'Ö¼' + 38: 0, # '×' + 45: 0, # 'ׂ' + 9: 2, # '×' + 8: 3, # 'ב' + 20: 3, # '×’' + 16: 3, # 'ד' + 3: 3, # '×”' + 2: 3, # 'ו' + 24: 3, # '×–' + 14: 1, # '×—' + 22: 3, # 'ט' + 1: 3, # '×™' + 25: 2, # 'ך' + 15: 2, # '×›' + 4: 3, # 'ל' + 11: 3, # '×' + 6: 3, # 'מ' + 23: 2, # 'ן' + 12: 3, # '× ' + 19: 3, # 'ס' + 13: 2, # '×¢' + 26: 1, # '×£' + 18: 2, # 'פ' + 27: 2, # '×¥' + 21: 3, # 'צ' + 17: 3, # '×§' + 7: 3, # 'ר' + 10: 3, # 'ש' + 5: 3, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 1, # 'â€' + 58: 0, # '†' + 40: 1, # '…' + }, + 26: { # '×£' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'Ö°' + 59: 0, # 'Ö±' + 41: 0, # 'Ö²' + 33: 0, # 'Ö´' + 37: 0, # 'Öµ' + 36: 0, # 'Ö¶' + 31: 0, # 'Ö·' + 29: 0, # 'Ö¸' + 35: 0, # 'Ö¹' + 62: 0, # 'Ö»' + 28: 0, # 'Ö¼' + 38: 0, # '×' + 45: 0, # 'ׂ' + 9: 1, # '×' + 8: 0, # 'ב' + 20: 0, # '×’' + 16: 0, # 'ד' + 3: 0, # '×”' + 2: 1, # 'ו' + 24: 0, # '×–' + 14: 1, # '×—' + 22: 0, # 'ט' + 1: 0, # '×™' + 25: 0, # 'ך' + 15: 1, # '×›' + 4: 1, # 'ל' + 11: 0, # '×' + 6: 1, # 'מ' + 23: 0, # 'ן' + 12: 0, # '× ' + 19: 1, # 'ס' + 13: 0, # '×¢' + 26: 1, # '×£' + 18: 1, # 'פ' + 27: 0, # '×¥' + 21: 0, # 'צ' + 17: 1, # '×§' + 7: 1, # 'ר' + 10: 1, # 'ש' + 5: 0, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 0, # 'â€' + 58: 0, # '†' + 40: 1, # '…' + }, + 18: { # 'פ' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 1, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 2, # 'Ö°' + 59: 0, # 'Ö±' + 41: 0, # 'Ö²' + 33: 2, # 'Ö´' + 37: 1, # 'Öµ' + 36: 2, # 'Ö¶' + 31: 1, # 'Ö·' + 29: 2, # 'Ö¸' + 35: 1, # 'Ö¹' + 62: 1, # 'Ö»' + 28: 2, # 'Ö¼' + 38: 0, # '×' + 45: 0, # 'ׂ' + 9: 3, # '×' + 8: 2, # 'ב' + 20: 3, # '×’' + 16: 2, # 'ד' + 3: 3, # '×”' + 2: 3, # 'ו' + 24: 2, # '×–' + 14: 3, # '×—' + 22: 3, # 'ט' + 1: 3, # '×™' + 25: 2, # 'ך' + 15: 3, # '×›' + 4: 3, # 'ל' + 11: 2, # '×' + 6: 2, # 'מ' + 23: 3, # 'ן' + 12: 3, # '× ' + 19: 3, # 'ס' + 13: 3, # '×¢' + 26: 2, # '×£' + 18: 2, # 'פ' + 27: 2, # '×¥' + 21: 3, # 'צ' + 17: 3, # '×§' + 7: 3, # 'ר' + 10: 3, # 'ש' + 5: 3, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 1, # 'â€' + 58: 0, # '†' + 40: 0, # '…' + }, + 27: { # '×¥' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 1, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'Ö°' + 59: 0, # 'Ö±' + 41: 0, # 'Ö²' + 33: 0, # 'Ö´' + 37: 0, # 'Öµ' + 36: 0, # 'Ö¶' + 31: 0, # 'Ö·' + 29: 0, # 'Ö¸' + 35: 0, # 'Ö¹' + 62: 0, # 'Ö»' + 28: 0, # 'Ö¼' + 38: 0, # '×' + 45: 0, # 'ׂ' + 9: 1, # '×' + 8: 0, # 'ב' + 20: 0, # '×’' + 16: 0, # 'ד' + 3: 0, # '×”' + 2: 0, # 'ו' + 24: 0, # '×–' + 14: 0, # '×—' + 22: 0, # 'ט' + 1: 0, # '×™' + 25: 0, # 'ך' + 15: 0, # '×›' + 4: 1, # 'ל' + 11: 0, # '×' + 6: 0, # 'מ' + 23: 0, # 'ן' + 12: 0, # '× ' + 19: 1, # 'ס' + 13: 0, # '×¢' + 26: 0, # '×£' + 18: 0, # 'פ' + 27: 0, # '×¥' + 21: 0, # 'צ' + 17: 0, # '×§' + 7: 1, # 'ר' + 10: 0, # 'ש' + 5: 1, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 0, # 'â€' + 58: 0, # '†' + 40: 1, # '…' + }, + 21: { # 'צ' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 1, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 2, # 'Ö°' + 59: 0, # 'Ö±' + 41: 0, # 'Ö²' + 33: 2, # 'Ö´' + 37: 2, # 'Öµ' + 36: 1, # 'Ö¶' + 31: 2, # 'Ö·' + 29: 2, # 'Ö¸' + 35: 1, # 'Ö¹' + 62: 1, # 'Ö»' + 28: 2, # 'Ö¼' + 38: 0, # '×' + 45: 0, # 'ׂ' + 9: 3, # '×' + 8: 3, # 'ב' + 20: 2, # '×’' + 16: 3, # 'ד' + 3: 3, # '×”' + 2: 3, # 'ו' + 24: 1, # '×–' + 14: 3, # '×—' + 22: 2, # 'ט' + 1: 3, # '×™' + 25: 1, # 'ך' + 15: 1, # '×›' + 4: 3, # 'ל' + 11: 2, # '×' + 6: 3, # 'מ' + 23: 2, # 'ן' + 12: 3, # '× ' + 19: 1, # 'ס' + 13: 3, # '×¢' + 26: 2, # '×£' + 18: 3, # 'פ' + 27: 2, # '×¥' + 21: 2, # 'צ' + 17: 3, # '×§' + 7: 3, # 'ר' + 10: 0, # 'ש' + 5: 3, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 0, # 'â€' + 58: 0, # '†' + 40: 0, # '…' + }, + 17: { # '×§' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 1, # '\xa0' + 55: 1, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 2, # 'Ö°' + 59: 0, # 'Ö±' + 41: 0, # 'Ö²' + 33: 2, # 'Ö´' + 37: 2, # 'Öµ' + 36: 1, # 'Ö¶' + 31: 2, # 'Ö·' + 29: 2, # 'Ö¸' + 35: 2, # 'Ö¹' + 62: 1, # 'Ö»' + 28: 2, # 'Ö¼' + 38: 0, # '×' + 45: 0, # 'ׂ' + 9: 3, # '×' + 8: 3, # 'ב' + 20: 2, # '×’' + 16: 3, # 'ד' + 3: 3, # '×”' + 2: 3, # 'ו' + 24: 2, # '×–' + 14: 3, # '×—' + 22: 3, # 'ט' + 1: 3, # '×™' + 25: 1, # 'ך' + 15: 1, # '×›' + 4: 3, # 'ל' + 11: 2, # '×' + 6: 3, # 'מ' + 23: 2, # 'ן' + 12: 3, # '× ' + 19: 3, # 'ס' + 13: 3, # '×¢' + 26: 2, # '×£' + 18: 3, # 'פ' + 27: 2, # '×¥' + 21: 3, # 'צ' + 17: 2, # '×§' + 7: 3, # 'ר' + 10: 3, # 'ש' + 5: 3, # 'ת' + 32: 0, # '–' + 52: 1, # '’' + 47: 0, # '“' + 46: 1, # 'â€' + 58: 0, # '†' + 40: 1, # '…' + }, + 7: { # 'ר' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 1, # '\xa0' + 55: 2, # '´' + 48: 1, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 2, # 'Ö°' + 59: 0, # 'Ö±' + 41: 1, # 'Ö²' + 33: 2, # 'Ö´' + 37: 2, # 'Öµ' + 36: 2, # 'Ö¶' + 31: 2, # 'Ö·' + 29: 2, # 'Ö¸' + 35: 2, # 'Ö¹' + 62: 1, # 'Ö»' + 28: 0, # 'Ö¼' + 38: 0, # '×' + 45: 0, # 'ׂ' + 9: 3, # '×' + 8: 3, # 'ב' + 20: 3, # '×’' + 16: 3, # 'ד' + 3: 3, # '×”' + 2: 3, # 'ו' + 24: 3, # '×–' + 14: 3, # '×—' + 22: 3, # 'ט' + 1: 3, # '×™' + 25: 3, # 'ך' + 15: 3, # '×›' + 4: 3, # 'ל' + 11: 3, # '×' + 6: 3, # 'מ' + 23: 3, # 'ן' + 12: 3, # '× ' + 19: 3, # 'ס' + 13: 3, # '×¢' + 26: 2, # '×£' + 18: 3, # 'פ' + 27: 3, # '×¥' + 21: 3, # 'צ' + 17: 3, # '×§' + 7: 3, # 'ר' + 10: 3, # 'ש' + 5: 3, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 1, # 'â€' + 58: 0, # '†' + 40: 2, # '…' + }, + 10: { # 'ש' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 1, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 1, # 'Ö°' + 59: 0, # 'Ö±' + 41: 0, # 'Ö²' + 33: 1, # 'Ö´' + 37: 1, # 'Öµ' + 36: 1, # 'Ö¶' + 31: 1, # 'Ö·' + 29: 1, # 'Ö¸' + 35: 1, # 'Ö¹' + 62: 1, # 'Ö»' + 28: 2, # 'Ö¼' + 38: 3, # '×' + 45: 2, # 'ׂ' + 9: 3, # '×' + 8: 3, # 'ב' + 20: 3, # '×’' + 16: 3, # 'ד' + 3: 3, # '×”' + 2: 3, # 'ו' + 24: 2, # '×–' + 14: 3, # '×—' + 22: 3, # 'ט' + 1: 3, # '×™' + 25: 3, # 'ך' + 15: 3, # '×›' + 4: 3, # 'ל' + 11: 3, # '×' + 6: 3, # 'מ' + 23: 2, # 'ן' + 12: 3, # '× ' + 19: 2, # 'ס' + 13: 3, # '×¢' + 26: 2, # '×£' + 18: 3, # 'פ' + 27: 1, # '×¥' + 21: 2, # 'צ' + 17: 3, # '×§' + 7: 3, # 'ר' + 10: 3, # 'ש' + 5: 3, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 1, # 'â€' + 58: 0, # '†' + 40: 1, # '…' + }, + 5: { # 'ת' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 1, # '\xa0' + 55: 0, # '´' + 48: 1, # '¼' + 39: 1, # '½' + 57: 0, # '¾' + 30: 2, # 'Ö°' + 59: 0, # 'Ö±' + 41: 0, # 'Ö²' + 33: 2, # 'Ö´' + 37: 2, # 'Öµ' + 36: 2, # 'Ö¶' + 31: 2, # 'Ö·' + 29: 2, # 'Ö¸' + 35: 1, # 'Ö¹' + 62: 1, # 'Ö»' + 28: 2, # 'Ö¼' + 38: 0, # '×' + 45: 0, # 'ׂ' + 9: 3, # '×' + 8: 3, # 'ב' + 20: 3, # '×’' + 16: 2, # 'ד' + 3: 3, # '×”' + 2: 3, # 'ו' + 24: 2, # '×–' + 14: 3, # '×—' + 22: 2, # 'ט' + 1: 3, # '×™' + 25: 2, # 'ך' + 15: 3, # '×›' + 4: 3, # 'ל' + 11: 3, # '×' + 6: 3, # 'מ' + 23: 3, # 'ן' + 12: 3, # '× ' + 19: 2, # 'ס' + 13: 3, # '×¢' + 26: 2, # '×£' + 18: 3, # 'פ' + 27: 1, # '×¥' + 21: 2, # 'צ' + 17: 3, # '×§' + 7: 3, # 'ר' + 10: 3, # 'ש' + 5: 3, # 'ת' + 32: 1, # '–' + 52: 1, # '’' + 47: 0, # '“' + 46: 0, # 'â€' + 58: 0, # '†' + 40: 2, # '…' + }, + 32: { # '–' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 1, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'Ö°' + 59: 0, # 'Ö±' + 41: 0, # 'Ö²' + 33: 0, # 'Ö´' + 37: 0, # 'Öµ' + 36: 0, # 'Ö¶' + 31: 0, # 'Ö·' + 29: 0, # 'Ö¸' + 35: 0, # 'Ö¹' + 62: 0, # 'Ö»' + 28: 0, # 'Ö¼' + 38: 0, # '×' + 45: 0, # 'ׂ' + 9: 1, # '×' + 8: 1, # 'ב' + 20: 1, # '×’' + 16: 1, # 'ד' + 3: 1, # '×”' + 2: 1, # 'ו' + 24: 0, # '×–' + 14: 1, # '×—' + 22: 0, # 'ט' + 1: 1, # '×™' + 25: 0, # 'ך' + 15: 1, # '×›' + 4: 1, # 'ל' + 11: 0, # '×' + 6: 1, # 'מ' + 23: 0, # 'ן' + 12: 0, # '× ' + 19: 1, # 'ס' + 13: 1, # '×¢' + 26: 0, # '×£' + 18: 1, # 'פ' + 27: 0, # '×¥' + 21: 1, # 'צ' + 17: 0, # '×§' + 7: 1, # 'ר' + 10: 1, # 'ש' + 5: 1, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 0, # 'â€' + 58: 0, # '†' + 40: 0, # '…' + }, + 52: { # '’' + 50: 1, # 'a' + 60: 0, # 'c' + 61: 1, # 'd' + 42: 1, # 'e' + 53: 1, # 'i' + 56: 1, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 1, # 'r' + 43: 2, # 's' + 44: 2, # 't' + 63: 1, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'Ö°' + 59: 0, # 'Ö±' + 41: 0, # 'Ö²' + 33: 0, # 'Ö´' + 37: 0, # 'Öµ' + 36: 0, # 'Ö¶' + 31: 0, # 'Ö·' + 29: 0, # 'Ö¸' + 35: 0, # 'Ö¹' + 62: 0, # 'Ö»' + 28: 0, # 'Ö¼' + 38: 0, # '×' + 45: 0, # 'ׂ' + 9: 0, # '×' + 8: 0, # 'ב' + 20: 0, # '×’' + 16: 0, # 'ד' + 3: 0, # '×”' + 2: 1, # 'ו' + 24: 0, # '×–' + 14: 0, # '×—' + 22: 0, # 'ט' + 1: 0, # '×™' + 25: 0, # 'ך' + 15: 0, # '×›' + 4: 0, # 'ל' + 11: 0, # '×' + 6: 1, # 'מ' + 23: 0, # 'ן' + 12: 0, # '× ' + 19: 0, # 'ס' + 13: 0, # '×¢' + 26: 0, # '×£' + 18: 0, # 'פ' + 27: 0, # '×¥' + 21: 0, # 'צ' + 17: 0, # '×§' + 7: 0, # 'ר' + 10: 0, # 'ש' + 5: 1, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 0, # 'â€' + 58: 0, # '†' + 40: 0, # '…' + }, + 47: { # '“' + 50: 1, # 'a' + 60: 1, # 'c' + 61: 1, # 'd' + 42: 1, # 'e' + 53: 1, # 'i' + 56: 1, # 'l' + 54: 1, # 'n' + 49: 1, # 'o' + 51: 1, # 'r' + 43: 1, # 's' + 44: 1, # 't' + 63: 1, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'Ö°' + 59: 0, # 'Ö±' + 41: 0, # 'Ö²' + 33: 0, # 'Ö´' + 37: 0, # 'Öµ' + 36: 0, # 'Ö¶' + 31: 0, # 'Ö·' + 29: 0, # 'Ö¸' + 35: 0, # 'Ö¹' + 62: 0, # 'Ö»' + 28: 0, # 'Ö¼' + 38: 0, # '×' + 45: 0, # 'ׂ' + 9: 2, # '×' + 8: 1, # 'ב' + 20: 1, # '×’' + 16: 1, # 'ד' + 3: 1, # '×”' + 2: 1, # 'ו' + 24: 1, # '×–' + 14: 1, # '×—' + 22: 1, # 'ט' + 1: 1, # '×™' + 25: 0, # 'ך' + 15: 1, # '×›' + 4: 1, # 'ל' + 11: 0, # '×' + 6: 1, # 'מ' + 23: 0, # 'ן' + 12: 1, # '× ' + 19: 1, # 'ס' + 13: 1, # '×¢' + 26: 0, # '×£' + 18: 1, # 'פ' + 27: 0, # '×¥' + 21: 1, # 'צ' + 17: 1, # '×§' + 7: 1, # 'ר' + 10: 1, # 'ש' + 5: 1, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 0, # 'â€' + 58: 0, # '†' + 40: 0, # '…' + }, + 46: { # 'â€' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 1, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'Ö°' + 59: 0, # 'Ö±' + 41: 0, # 'Ö²' + 33: 0, # 'Ö´' + 37: 0, # 'Öµ' + 36: 0, # 'Ö¶' + 31: 0, # 'Ö·' + 29: 0, # 'Ö¸' + 35: 0, # 'Ö¹' + 62: 0, # 'Ö»' + 28: 0, # 'Ö¼' + 38: 0, # '×' + 45: 0, # 'ׂ' + 9: 1, # '×' + 8: 1, # 'ב' + 20: 1, # '×’' + 16: 0, # 'ד' + 3: 0, # '×”' + 2: 0, # 'ו' + 24: 0, # '×–' + 14: 0, # '×—' + 22: 0, # 'ט' + 1: 1, # '×™' + 25: 0, # 'ך' + 15: 1, # '×›' + 4: 1, # 'ל' + 11: 0, # '×' + 6: 1, # 'מ' + 23: 0, # 'ן' + 12: 0, # '× ' + 19: 0, # 'ס' + 13: 0, # '×¢' + 26: 0, # '×£' + 18: 0, # 'פ' + 27: 0, # '×¥' + 21: 1, # 'צ' + 17: 0, # '×§' + 7: 1, # 'ר' + 10: 0, # 'ש' + 5: 0, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 0, # 'â€' + 58: 0, # '†' + 40: 0, # '…' + }, + 58: { # '†' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'Ö°' + 59: 0, # 'Ö±' + 41: 0, # 'Ö²' + 33: 0, # 'Ö´' + 37: 0, # 'Öµ' + 36: 0, # 'Ö¶' + 31: 0, # 'Ö·' + 29: 0, # 'Ö¸' + 35: 0, # 'Ö¹' + 62: 0, # 'Ö»' + 28: 0, # 'Ö¼' + 38: 0, # '×' + 45: 0, # 'ׂ' + 9: 0, # '×' + 8: 0, # 'ב' + 20: 0, # '×’' + 16: 0, # 'ד' + 3: 0, # '×”' + 2: 0, # 'ו' + 24: 0, # '×–' + 14: 0, # '×—' + 22: 0, # 'ט' + 1: 0, # '×™' + 25: 0, # 'ך' + 15: 0, # '×›' + 4: 0, # 'ל' + 11: 0, # '×' + 6: 0, # 'מ' + 23: 0, # 'ן' + 12: 0, # '× ' + 19: 0, # 'ס' + 13: 0, # '×¢' + 26: 0, # '×£' + 18: 0, # 'פ' + 27: 0, # '×¥' + 21: 0, # 'צ' + 17: 0, # '×§' + 7: 0, # 'ר' + 10: 0, # 'ש' + 5: 0, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 0, # 'â€' + 58: 2, # '†' + 40: 0, # '…' + }, + 40: { # '…' + 50: 1, # 'a' + 60: 1, # 'c' + 61: 1, # 'd' + 42: 1, # 'e' + 53: 1, # 'i' + 56: 0, # 'l' + 54: 1, # 'n' + 49: 0, # 'o' + 51: 1, # 'r' + 43: 1, # 's' + 44: 1, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'Ö°' + 59: 0, # 'Ö±' + 41: 0, # 'Ö²' + 33: 0, # 'Ö´' + 37: 0, # 'Öµ' + 36: 0, # 'Ö¶' + 31: 0, # 'Ö·' + 29: 0, # 'Ö¸' + 35: 0, # 'Ö¹' + 62: 0, # 'Ö»' + 28: 0, # 'Ö¼' + 38: 0, # '×' + 45: 0, # 'ׂ' + 9: 1, # '×' + 8: 0, # 'ב' + 20: 0, # '×’' + 16: 0, # 'ד' + 3: 1, # '×”' + 2: 1, # 'ו' + 24: 1, # '×–' + 14: 0, # '×—' + 22: 0, # 'ט' + 1: 1, # '×™' + 25: 0, # 'ך' + 15: 1, # '×›' + 4: 1, # 'ל' + 11: 0, # '×' + 6: 1, # 'מ' + 23: 0, # 'ן' + 12: 1, # '× ' + 19: 0, # 'ס' + 13: 0, # '×¢' + 26: 0, # '×£' + 18: 1, # 'פ' + 27: 0, # '×¥' + 21: 0, # 'צ' + 17: 0, # '×§' + 7: 1, # 'ר' + 10: 1, # 'ש' + 5: 1, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 1, # 'â€' + 58: 0, # '†' + 40: 2, # '…' + }, +} + +# 255: Undefined characters that did not exist in training text +# 254: Carriage/Return +# 253: symbol (punctuation) that does not belong to word +# 252: 0 - 9 +# 251: Control characters + +# Character Mapping Table(s): +WINDOWS_1255_HEBREW_CHAR_TO_ORDER = { + 0: 255, # '\x00' + 1: 255, # '\x01' + 2: 255, # '\x02' + 3: 255, # '\x03' + 4: 255, # '\x04' + 5: 255, # '\x05' + 6: 255, # '\x06' + 7: 255, # '\x07' + 8: 255, # '\x08' + 9: 255, # '\t' + 10: 254, # '\n' + 11: 255, # '\x0b' + 12: 255, # '\x0c' + 13: 254, # '\r' + 14: 255, # '\x0e' + 15: 255, # '\x0f' + 16: 255, # '\x10' + 17: 255, # '\x11' + 18: 255, # '\x12' + 19: 255, # '\x13' + 20: 255, # '\x14' + 21: 255, # '\x15' + 22: 255, # '\x16' + 23: 255, # '\x17' + 24: 255, # '\x18' + 25: 255, # '\x19' + 26: 255, # '\x1a' + 27: 255, # '\x1b' + 28: 255, # '\x1c' + 29: 255, # '\x1d' + 30: 255, # '\x1e' + 31: 255, # '\x1f' + 32: 253, # ' ' + 33: 253, # '!' + 34: 253, # '"' + 35: 253, # '#' + 36: 253, # '$' + 37: 253, # '%' + 38: 253, # '&' + 39: 253, # "'" + 40: 253, # '(' + 41: 253, # ')' + 42: 253, # '*' + 43: 253, # '+' + 44: 253, # ',' + 45: 253, # '-' + 46: 253, # '.' + 47: 253, # '/' + 48: 252, # '0' + 49: 252, # '1' + 50: 252, # '2' + 51: 252, # '3' + 52: 252, # '4' + 53: 252, # '5' + 54: 252, # '6' + 55: 252, # '7' + 56: 252, # '8' + 57: 252, # '9' + 58: 253, # ':' + 59: 253, # ';' + 60: 253, # '<' + 61: 253, # '=' + 62: 253, # '>' + 63: 253, # '?' + 64: 253, # '@' + 65: 69, # 'A' + 66: 91, # 'B' + 67: 79, # 'C' + 68: 80, # 'D' + 69: 92, # 'E' + 70: 89, # 'F' + 71: 97, # 'G' + 72: 90, # 'H' + 73: 68, # 'I' + 74: 111, # 'J' + 75: 112, # 'K' + 76: 82, # 'L' + 77: 73, # 'M' + 78: 95, # 'N' + 79: 85, # 'O' + 80: 78, # 'P' + 81: 121, # 'Q' + 82: 86, # 'R' + 83: 71, # 'S' + 84: 67, # 'T' + 85: 102, # 'U' + 86: 107, # 'V' + 87: 84, # 'W' + 88: 114, # 'X' + 89: 103, # 'Y' + 90: 115, # 'Z' + 91: 253, # '[' + 92: 253, # '\\' + 93: 253, # ']' + 94: 253, # '^' + 95: 253, # '_' + 96: 253, # '`' + 97: 50, # 'a' + 98: 74, # 'b' + 99: 60, # 'c' + 100: 61, # 'd' + 101: 42, # 'e' + 102: 76, # 'f' + 103: 70, # 'g' + 104: 64, # 'h' + 105: 53, # 'i' + 106: 105, # 'j' + 107: 93, # 'k' + 108: 56, # 'l' + 109: 65, # 'm' + 110: 54, # 'n' + 111: 49, # 'o' + 112: 66, # 'p' + 113: 110, # 'q' + 114: 51, # 'r' + 115: 43, # 's' + 116: 44, # 't' + 117: 63, # 'u' + 118: 81, # 'v' + 119: 77, # 'w' + 120: 98, # 'x' + 121: 75, # 'y' + 122: 108, # 'z' + 123: 253, # '{' + 124: 253, # '|' + 125: 253, # '}' + 126: 253, # '~' + 127: 253, # '\x7f' + 128: 124, # '€' + 129: 202, # None + 130: 203, # '‚' + 131: 204, # 'Æ’' + 132: 205, # '„' + 133: 40, # '…' + 134: 58, # '†' + 135: 206, # '‡' + 136: 207, # 'ˆ' + 137: 208, # '‰' + 138: 209, # None + 139: 210, # '‹' + 140: 211, # None + 141: 212, # None + 142: 213, # None + 143: 214, # None + 144: 215, # None + 145: 83, # '‘' + 146: 52, # '’' + 147: 47, # '“' + 148: 46, # 'â€' + 149: 72, # '•' + 150: 32, # '–' + 151: 94, # '—' + 152: 216, # 'Ëœ' + 153: 113, # 'â„¢' + 154: 217, # None + 155: 109, # '›' + 156: 218, # None + 157: 219, # None + 158: 220, # None + 159: 221, # None + 160: 34, # '\xa0' + 161: 116, # '¡' + 162: 222, # '¢' + 163: 118, # '£' + 164: 100, # '₪' + 165: 223, # 'Â¥' + 166: 224, # '¦' + 167: 117, # '§' + 168: 119, # '¨' + 169: 104, # '©' + 170: 125, # '×' + 171: 225, # '«' + 172: 226, # '¬' + 173: 87, # '\xad' + 174: 99, # '®' + 175: 227, # '¯' + 176: 106, # '°' + 177: 122, # '±' + 178: 123, # '²' + 179: 228, # '³' + 180: 55, # '´' + 181: 229, # 'µ' + 182: 230, # '¶' + 183: 101, # '·' + 184: 231, # '¸' + 185: 232, # '¹' + 186: 120, # '÷' + 187: 233, # '»' + 188: 48, # '¼' + 189: 39, # '½' + 190: 57, # '¾' + 191: 234, # '¿' + 192: 30, # 'Ö°' + 193: 59, # 'Ö±' + 194: 41, # 'Ö²' + 195: 88, # 'Ö³' + 196: 33, # 'Ö´' + 197: 37, # 'Öµ' + 198: 36, # 'Ö¶' + 199: 31, # 'Ö·' + 200: 29, # 'Ö¸' + 201: 35, # 'Ö¹' + 202: 235, # None + 203: 62, # 'Ö»' + 204: 28, # 'Ö¼' + 205: 236, # 'Ö½' + 206: 126, # 'Ö¾' + 207: 237, # 'Ö¿' + 208: 238, # '×€' + 209: 38, # '×' + 210: 45, # 'ׂ' + 211: 239, # '׃' + 212: 240, # '×°' + 213: 241, # '×±' + 214: 242, # 'ײ' + 215: 243, # '׳' + 216: 127, # '×´' + 217: 244, # None + 218: 245, # None + 219: 246, # None + 220: 247, # None + 221: 248, # None + 222: 249, # None + 223: 250, # None + 224: 9, # '×' + 225: 8, # 'ב' + 226: 20, # '×’' + 227: 16, # 'ד' + 228: 3, # '×”' + 229: 2, # 'ו' + 230: 24, # '×–' + 231: 14, # '×—' + 232: 22, # 'ט' + 233: 1, # '×™' + 234: 25, # 'ך' + 235: 15, # '×›' + 236: 4, # 'ל' + 237: 11, # '×' + 238: 6, # 'מ' + 239: 23, # 'ן' + 240: 12, # '× ' + 241: 19, # 'ס' + 242: 13, # '×¢' + 243: 26, # '×£' + 244: 18, # 'פ' + 245: 27, # '×¥' + 246: 21, # 'צ' + 247: 17, # '×§' + 248: 7, # 'ר' + 249: 10, # 'ש' + 250: 5, # 'ת' + 251: 251, # None + 252: 252, # None + 253: 128, # '\u200e' + 254: 96, # '\u200f' + 255: 253, # None +} + +WINDOWS_1255_HEBREW_MODEL = SingleByteCharSetModel(charset_name='windows-1255', + language='Hebrew', + char_to_order_map=WINDOWS_1255_HEBREW_CHAR_TO_ORDER, + language_model=HEBREW_LANG_MODEL, + typical_positive_ratio=0.984004, + keep_ascii_letters=False, + alphabet='×בגדהוזחטיךכל×מןנסעףפץצקרשתװױײ') + diff --git a/venv/Lib/site-packages/pip/_vendor/chardet/langhungarianmodel.py b/venv/Lib/site-packages/pip/_vendor/chardet/langhungarianmodel.py new file mode 100644 index 0000000..bbc5cda --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/chardet/langhungarianmodel.py @@ -0,0 +1,4650 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from pip._vendor.chardet.sbcharsetprober import SingleByteCharSetModel + + +# 3: Positive +# 2: Likely +# 1: Unlikely +# 0: Negative + +HUNGARIAN_LANG_MODEL = { + 28: { # 'A' + 28: 0, # 'A' + 40: 1, # 'B' + 54: 1, # 'C' + 45: 2, # 'D' + 32: 1, # 'E' + 50: 1, # 'F' + 49: 2, # 'G' + 38: 1, # 'H' + 39: 2, # 'I' + 53: 1, # 'J' + 36: 2, # 'K' + 41: 2, # 'L' + 34: 1, # 'M' + 35: 2, # 'N' + 47: 1, # 'O' + 46: 2, # 'P' + 43: 2, # 'R' + 33: 2, # 'S' + 37: 2, # 'T' + 57: 1, # 'U' + 48: 1, # 'V' + 55: 1, # 'Y' + 52: 2, # 'Z' + 2: 0, # 'a' + 18: 1, # 'b' + 26: 1, # 'c' + 17: 2, # 'd' + 1: 1, # 'e' + 27: 1, # 'f' + 12: 1, # 'g' + 20: 1, # 'h' + 9: 1, # 'i' + 22: 1, # 'j' + 7: 2, # 'k' + 6: 2, # 'l' + 13: 2, # 'm' + 4: 2, # 'n' + 8: 0, # 'o' + 23: 2, # 'p' + 10: 2, # 'r' + 5: 1, # 's' + 3: 1, # 't' + 21: 1, # 'u' + 19: 1, # 'v' + 62: 1, # 'x' + 16: 0, # 'y' + 11: 3, # 'z' + 51: 1, # 'Ã' + 44: 0, # 'É' + 61: 1, # 'Ã' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 0, # 'á' + 15: 0, # 'é' + 30: 0, # 'í' + 25: 0, # 'ó' + 24: 0, # 'ö' + 31: 0, # 'ú' + 29: 0, # 'ü' + 42: 0, # 'Å‘' + 56: 0, # 'ű' + }, + 40: { # 'B' + 28: 2, # 'A' + 40: 1, # 'B' + 54: 1, # 'C' + 45: 1, # 'D' + 32: 2, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 1, # 'I' + 53: 1, # 'J' + 36: 1, # 'K' + 41: 1, # 'L' + 34: 0, # 'M' + 35: 1, # 'N' + 47: 2, # 'O' + 46: 0, # 'P' + 43: 1, # 'R' + 33: 1, # 'S' + 37: 1, # 'T' + 57: 1, # 'U' + 48: 1, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 2, # 'a' + 18: 0, # 'b' + 26: 0, # 'c' + 17: 0, # 'd' + 1: 3, # 'e' + 27: 0, # 'f' + 12: 0, # 'g' + 20: 0, # 'h' + 9: 2, # 'i' + 22: 1, # 'j' + 7: 0, # 'k' + 6: 1, # 'l' + 13: 0, # 'm' + 4: 0, # 'n' + 8: 2, # 'o' + 23: 1, # 'p' + 10: 2, # 'r' + 5: 0, # 's' + 3: 0, # 't' + 21: 3, # 'u' + 19: 0, # 'v' + 62: 0, # 'x' + 16: 1, # 'y' + 11: 0, # 'z' + 51: 1, # 'Ã' + 44: 1, # 'É' + 61: 1, # 'Ã' + 58: 1, # 'Ó' + 59: 1, # 'Ö' + 60: 1, # 'Ú' + 63: 1, # 'Ü' + 14: 2, # 'á' + 15: 2, # 'é' + 30: 1, # 'í' + 25: 1, # 'ó' + 24: 1, # 'ö' + 31: 1, # 'ú' + 29: 1, # 'ü' + 42: 1, # 'Å‘' + 56: 1, # 'ű' + }, + 54: { # 'C' + 28: 1, # 'A' + 40: 1, # 'B' + 54: 1, # 'C' + 45: 1, # 'D' + 32: 1, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 1, # 'H' + 39: 2, # 'I' + 53: 1, # 'J' + 36: 1, # 'K' + 41: 1, # 'L' + 34: 1, # 'M' + 35: 0, # 'N' + 47: 1, # 'O' + 46: 1, # 'P' + 43: 1, # 'R' + 33: 2, # 'S' + 37: 1, # 'T' + 57: 1, # 'U' + 48: 0, # 'V' + 55: 1, # 'Y' + 52: 1, # 'Z' + 2: 2, # 'a' + 18: 0, # 'b' + 26: 0, # 'c' + 17: 0, # 'd' + 1: 1, # 'e' + 27: 0, # 'f' + 12: 0, # 'g' + 20: 1, # 'h' + 9: 1, # 'i' + 22: 0, # 'j' + 7: 0, # 'k' + 6: 1, # 'l' + 13: 0, # 'm' + 4: 0, # 'n' + 8: 2, # 'o' + 23: 0, # 'p' + 10: 1, # 'r' + 5: 3, # 's' + 3: 0, # 't' + 21: 1, # 'u' + 19: 0, # 'v' + 62: 0, # 'x' + 16: 1, # 'y' + 11: 1, # 'z' + 51: 1, # 'Ã' + 44: 1, # 'É' + 61: 1, # 'Ã' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 1, # 'á' + 15: 1, # 'é' + 30: 1, # 'í' + 25: 1, # 'ó' + 24: 0, # 'ö' + 31: 0, # 'ú' + 29: 0, # 'ü' + 42: 0, # 'Å‘' + 56: 0, # 'ű' + }, + 45: { # 'D' + 28: 2, # 'A' + 40: 1, # 'B' + 54: 0, # 'C' + 45: 1, # 'D' + 32: 2, # 'E' + 50: 1, # 'F' + 49: 1, # 'G' + 38: 1, # 'H' + 39: 2, # 'I' + 53: 1, # 'J' + 36: 1, # 'K' + 41: 0, # 'L' + 34: 1, # 'M' + 35: 1, # 'N' + 47: 2, # 'O' + 46: 0, # 'P' + 43: 1, # 'R' + 33: 1, # 'S' + 37: 1, # 'T' + 57: 1, # 'U' + 48: 1, # 'V' + 55: 1, # 'Y' + 52: 1, # 'Z' + 2: 2, # 'a' + 18: 0, # 'b' + 26: 0, # 'c' + 17: 0, # 'd' + 1: 3, # 'e' + 27: 0, # 'f' + 12: 0, # 'g' + 20: 0, # 'h' + 9: 1, # 'i' + 22: 0, # 'j' + 7: 0, # 'k' + 6: 0, # 'l' + 13: 0, # 'm' + 4: 0, # 'n' + 8: 1, # 'o' + 23: 0, # 'p' + 10: 2, # 'r' + 5: 0, # 's' + 3: 0, # 't' + 21: 2, # 'u' + 19: 0, # 'v' + 62: 0, # 'x' + 16: 1, # 'y' + 11: 1, # 'z' + 51: 1, # 'Ã' + 44: 1, # 'É' + 61: 1, # 'Ã' + 58: 1, # 'Ó' + 59: 1, # 'Ö' + 60: 1, # 'Ú' + 63: 1, # 'Ü' + 14: 1, # 'á' + 15: 1, # 'é' + 30: 1, # 'í' + 25: 1, # 'ó' + 24: 1, # 'ö' + 31: 1, # 'ú' + 29: 1, # 'ü' + 42: 1, # 'Å‘' + 56: 0, # 'ű' + }, + 32: { # 'E' + 28: 1, # 'A' + 40: 1, # 'B' + 54: 1, # 'C' + 45: 1, # 'D' + 32: 1, # 'E' + 50: 1, # 'F' + 49: 2, # 'G' + 38: 1, # 'H' + 39: 1, # 'I' + 53: 1, # 'J' + 36: 2, # 'K' + 41: 2, # 'L' + 34: 2, # 'M' + 35: 2, # 'N' + 47: 1, # 'O' + 46: 1, # 'P' + 43: 2, # 'R' + 33: 2, # 'S' + 37: 2, # 'T' + 57: 1, # 'U' + 48: 1, # 'V' + 55: 1, # 'Y' + 52: 1, # 'Z' + 2: 1, # 'a' + 18: 1, # 'b' + 26: 1, # 'c' + 17: 2, # 'd' + 1: 1, # 'e' + 27: 1, # 'f' + 12: 3, # 'g' + 20: 1, # 'h' + 9: 1, # 'i' + 22: 1, # 'j' + 7: 1, # 'k' + 6: 2, # 'l' + 13: 2, # 'm' + 4: 2, # 'n' + 8: 0, # 'o' + 23: 1, # 'p' + 10: 2, # 'r' + 5: 2, # 's' + 3: 1, # 't' + 21: 2, # 'u' + 19: 1, # 'v' + 62: 1, # 'x' + 16: 0, # 'y' + 11: 3, # 'z' + 51: 1, # 'Ã' + 44: 1, # 'É' + 61: 0, # 'Ã' + 58: 1, # 'Ó' + 59: 1, # 'Ö' + 60: 0, # 'Ú' + 63: 1, # 'Ü' + 14: 0, # 'á' + 15: 0, # 'é' + 30: 0, # 'í' + 25: 0, # 'ó' + 24: 1, # 'ö' + 31: 0, # 'ú' + 29: 0, # 'ü' + 42: 0, # 'Å‘' + 56: 0, # 'ű' + }, + 50: { # 'F' + 28: 1, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 1, # 'E' + 50: 1, # 'F' + 49: 0, # 'G' + 38: 1, # 'H' + 39: 1, # 'I' + 53: 1, # 'J' + 36: 1, # 'K' + 41: 1, # 'L' + 34: 1, # 'M' + 35: 1, # 'N' + 47: 1, # 'O' + 46: 0, # 'P' + 43: 1, # 'R' + 33: 0, # 'S' + 37: 1, # 'T' + 57: 1, # 'U' + 48: 0, # 'V' + 55: 1, # 'Y' + 52: 0, # 'Z' + 2: 2, # 'a' + 18: 0, # 'b' + 26: 0, # 'c' + 17: 0, # 'd' + 1: 2, # 'e' + 27: 1, # 'f' + 12: 0, # 'g' + 20: 0, # 'h' + 9: 2, # 'i' + 22: 1, # 'j' + 7: 0, # 'k' + 6: 1, # 'l' + 13: 0, # 'm' + 4: 0, # 'n' + 8: 2, # 'o' + 23: 0, # 'p' + 10: 2, # 'r' + 5: 0, # 's' + 3: 0, # 't' + 21: 1, # 'u' + 19: 0, # 'v' + 62: 0, # 'x' + 16: 0, # 'y' + 11: 0, # 'z' + 51: 1, # 'Ã' + 44: 1, # 'É' + 61: 0, # 'Ã' + 58: 1, # 'Ó' + 59: 1, # 'Ö' + 60: 0, # 'Ú' + 63: 1, # 'Ü' + 14: 1, # 'á' + 15: 1, # 'é' + 30: 0, # 'í' + 25: 0, # 'ó' + 24: 2, # 'ö' + 31: 1, # 'ú' + 29: 1, # 'ü' + 42: 1, # 'Å‘' + 56: 1, # 'ű' + }, + 49: { # 'G' + 28: 2, # 'A' + 40: 1, # 'B' + 54: 1, # 'C' + 45: 1, # 'D' + 32: 2, # 'E' + 50: 1, # 'F' + 49: 1, # 'G' + 38: 1, # 'H' + 39: 1, # 'I' + 53: 1, # 'J' + 36: 1, # 'K' + 41: 1, # 'L' + 34: 1, # 'M' + 35: 1, # 'N' + 47: 1, # 'O' + 46: 1, # 'P' + 43: 1, # 'R' + 33: 1, # 'S' + 37: 1, # 'T' + 57: 1, # 'U' + 48: 1, # 'V' + 55: 2, # 'Y' + 52: 1, # 'Z' + 2: 2, # 'a' + 18: 0, # 'b' + 26: 0, # 'c' + 17: 0, # 'd' + 1: 2, # 'e' + 27: 0, # 'f' + 12: 0, # 'g' + 20: 0, # 'h' + 9: 1, # 'i' + 22: 0, # 'j' + 7: 0, # 'k' + 6: 1, # 'l' + 13: 0, # 'm' + 4: 0, # 'n' + 8: 2, # 'o' + 23: 0, # 'p' + 10: 2, # 'r' + 5: 0, # 's' + 3: 0, # 't' + 21: 1, # 'u' + 19: 0, # 'v' + 62: 0, # 'x' + 16: 2, # 'y' + 11: 0, # 'z' + 51: 1, # 'Ã' + 44: 1, # 'É' + 61: 1, # 'Ã' + 58: 1, # 'Ó' + 59: 1, # 'Ö' + 60: 1, # 'Ú' + 63: 1, # 'Ü' + 14: 1, # 'á' + 15: 1, # 'é' + 30: 0, # 'í' + 25: 1, # 'ó' + 24: 1, # 'ö' + 31: 1, # 'ú' + 29: 1, # 'ü' + 42: 1, # 'Å‘' + 56: 0, # 'ű' + }, + 38: { # 'H' + 28: 2, # 'A' + 40: 1, # 'B' + 54: 1, # 'C' + 45: 0, # 'D' + 32: 1, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 1, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 1, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 1, # 'O' + 46: 0, # 'P' + 43: 1, # 'R' + 33: 1, # 'S' + 37: 1, # 'T' + 57: 1, # 'U' + 48: 0, # 'V' + 55: 1, # 'Y' + 52: 0, # 'Z' + 2: 3, # 'a' + 18: 0, # 'b' + 26: 0, # 'c' + 17: 0, # 'd' + 1: 2, # 'e' + 27: 0, # 'f' + 12: 0, # 'g' + 20: 0, # 'h' + 9: 2, # 'i' + 22: 1, # 'j' + 7: 0, # 'k' + 6: 1, # 'l' + 13: 1, # 'm' + 4: 0, # 'n' + 8: 3, # 'o' + 23: 0, # 'p' + 10: 1, # 'r' + 5: 0, # 's' + 3: 0, # 't' + 21: 2, # 'u' + 19: 0, # 'v' + 62: 0, # 'x' + 16: 1, # 'y' + 11: 0, # 'z' + 51: 2, # 'Ã' + 44: 2, # 'É' + 61: 1, # 'Ã' + 58: 1, # 'Ó' + 59: 1, # 'Ö' + 60: 1, # 'Ú' + 63: 1, # 'Ü' + 14: 2, # 'á' + 15: 1, # 'é' + 30: 2, # 'í' + 25: 1, # 'ó' + 24: 1, # 'ö' + 31: 1, # 'ú' + 29: 1, # 'ü' + 42: 1, # 'Å‘' + 56: 1, # 'ű' + }, + 39: { # 'I' + 28: 2, # 'A' + 40: 1, # 'B' + 54: 1, # 'C' + 45: 1, # 'D' + 32: 1, # 'E' + 50: 1, # 'F' + 49: 1, # 'G' + 38: 1, # 'H' + 39: 2, # 'I' + 53: 1, # 'J' + 36: 2, # 'K' + 41: 2, # 'L' + 34: 1, # 'M' + 35: 2, # 'N' + 47: 1, # 'O' + 46: 1, # 'P' + 43: 1, # 'R' + 33: 2, # 'S' + 37: 1, # 'T' + 57: 1, # 'U' + 48: 1, # 'V' + 55: 0, # 'Y' + 52: 2, # 'Z' + 2: 0, # 'a' + 18: 1, # 'b' + 26: 1, # 'c' + 17: 2, # 'd' + 1: 0, # 'e' + 27: 1, # 'f' + 12: 2, # 'g' + 20: 1, # 'h' + 9: 0, # 'i' + 22: 1, # 'j' + 7: 1, # 'k' + 6: 2, # 'l' + 13: 2, # 'm' + 4: 1, # 'n' + 8: 0, # 'o' + 23: 1, # 'p' + 10: 2, # 'r' + 5: 2, # 's' + 3: 2, # 't' + 21: 0, # 'u' + 19: 1, # 'v' + 62: 0, # 'x' + 16: 0, # 'y' + 11: 1, # 'z' + 51: 1, # 'Ã' + 44: 1, # 'É' + 61: 0, # 'Ã' + 58: 1, # 'Ó' + 59: 1, # 'Ö' + 60: 1, # 'Ú' + 63: 1, # 'Ü' + 14: 0, # 'á' + 15: 0, # 'é' + 30: 0, # 'í' + 25: 0, # 'ó' + 24: 0, # 'ö' + 31: 0, # 'ú' + 29: 0, # 'ü' + 42: 0, # 'Å‘' + 56: 0, # 'ű' + }, + 53: { # 'J' + 28: 2, # 'A' + 40: 0, # 'B' + 54: 1, # 'C' + 45: 1, # 'D' + 32: 2, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 1, # 'H' + 39: 1, # 'I' + 53: 1, # 'J' + 36: 1, # 'K' + 41: 1, # 'L' + 34: 1, # 'M' + 35: 1, # 'N' + 47: 1, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 1, # 'S' + 37: 1, # 'T' + 57: 1, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 1, # 'Z' + 2: 2, # 'a' + 18: 0, # 'b' + 26: 0, # 'c' + 17: 0, # 'd' + 1: 2, # 'e' + 27: 0, # 'f' + 12: 0, # 'g' + 20: 0, # 'h' + 9: 1, # 'i' + 22: 0, # 'j' + 7: 0, # 'k' + 6: 0, # 'l' + 13: 0, # 'm' + 4: 0, # 'n' + 8: 1, # 'o' + 23: 0, # 'p' + 10: 0, # 'r' + 5: 0, # 's' + 3: 0, # 't' + 21: 2, # 'u' + 19: 0, # 'v' + 62: 0, # 'x' + 16: 0, # 'y' + 11: 0, # 'z' + 51: 1, # 'Ã' + 44: 1, # 'É' + 61: 0, # 'Ã' + 58: 1, # 'Ó' + 59: 1, # 'Ö' + 60: 1, # 'Ú' + 63: 1, # 'Ü' + 14: 2, # 'á' + 15: 1, # 'é' + 30: 0, # 'í' + 25: 2, # 'ó' + 24: 2, # 'ö' + 31: 1, # 'ú' + 29: 0, # 'ü' + 42: 1, # 'Å‘' + 56: 0, # 'ű' + }, + 36: { # 'K' + 28: 2, # 'A' + 40: 1, # 'B' + 54: 1, # 'C' + 45: 1, # 'D' + 32: 2, # 'E' + 50: 1, # 'F' + 49: 0, # 'G' + 38: 1, # 'H' + 39: 2, # 'I' + 53: 1, # 'J' + 36: 1, # 'K' + 41: 1, # 'L' + 34: 1, # 'M' + 35: 1, # 'N' + 47: 2, # 'O' + 46: 0, # 'P' + 43: 1, # 'R' + 33: 1, # 'S' + 37: 1, # 'T' + 57: 1, # 'U' + 48: 1, # 'V' + 55: 1, # 'Y' + 52: 0, # 'Z' + 2: 2, # 'a' + 18: 0, # 'b' + 26: 0, # 'c' + 17: 0, # 'd' + 1: 2, # 'e' + 27: 1, # 'f' + 12: 0, # 'g' + 20: 1, # 'h' + 9: 3, # 'i' + 22: 0, # 'j' + 7: 0, # 'k' + 6: 1, # 'l' + 13: 1, # 'm' + 4: 1, # 'n' + 8: 2, # 'o' + 23: 0, # 'p' + 10: 2, # 'r' + 5: 0, # 's' + 3: 0, # 't' + 21: 1, # 'u' + 19: 1, # 'v' + 62: 0, # 'x' + 16: 1, # 'y' + 11: 0, # 'z' + 51: 1, # 'Ã' + 44: 1, # 'É' + 61: 1, # 'Ã' + 58: 1, # 'Ó' + 59: 2, # 'Ö' + 60: 1, # 'Ú' + 63: 1, # 'Ü' + 14: 2, # 'á' + 15: 2, # 'é' + 30: 1, # 'í' + 25: 1, # 'ó' + 24: 2, # 'ö' + 31: 1, # 'ú' + 29: 2, # 'ü' + 42: 1, # 'Å‘' + 56: 0, # 'ű' + }, + 41: { # 'L' + 28: 2, # 'A' + 40: 1, # 'B' + 54: 1, # 'C' + 45: 1, # 'D' + 32: 2, # 'E' + 50: 1, # 'F' + 49: 1, # 'G' + 38: 1, # 'H' + 39: 2, # 'I' + 53: 1, # 'J' + 36: 1, # 'K' + 41: 2, # 'L' + 34: 1, # 'M' + 35: 1, # 'N' + 47: 2, # 'O' + 46: 0, # 'P' + 43: 1, # 'R' + 33: 1, # 'S' + 37: 2, # 'T' + 57: 1, # 'U' + 48: 1, # 'V' + 55: 1, # 'Y' + 52: 1, # 'Z' + 2: 2, # 'a' + 18: 0, # 'b' + 26: 0, # 'c' + 17: 0, # 'd' + 1: 3, # 'e' + 27: 0, # 'f' + 12: 0, # 'g' + 20: 0, # 'h' + 9: 2, # 'i' + 22: 1, # 'j' + 7: 0, # 'k' + 6: 1, # 'l' + 13: 0, # 'm' + 4: 0, # 'n' + 8: 2, # 'o' + 23: 0, # 'p' + 10: 0, # 'r' + 5: 0, # 's' + 3: 0, # 't' + 21: 2, # 'u' + 19: 0, # 'v' + 62: 0, # 'x' + 16: 1, # 'y' + 11: 0, # 'z' + 51: 2, # 'Ã' + 44: 1, # 'É' + 61: 1, # 'Ã' + 58: 1, # 'Ó' + 59: 1, # 'Ö' + 60: 1, # 'Ú' + 63: 1, # 'Ü' + 14: 2, # 'á' + 15: 1, # 'é' + 30: 1, # 'í' + 25: 1, # 'ó' + 24: 1, # 'ö' + 31: 0, # 'ú' + 29: 1, # 'ü' + 42: 0, # 'Å‘' + 56: 0, # 'ű' + }, + 34: { # 'M' + 28: 2, # 'A' + 40: 1, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 2, # 'E' + 50: 1, # 'F' + 49: 0, # 'G' + 38: 1, # 'H' + 39: 2, # 'I' + 53: 1, # 'J' + 36: 1, # 'K' + 41: 1, # 'L' + 34: 1, # 'M' + 35: 1, # 'N' + 47: 1, # 'O' + 46: 1, # 'P' + 43: 1, # 'R' + 33: 1, # 'S' + 37: 1, # 'T' + 57: 1, # 'U' + 48: 1, # 'V' + 55: 1, # 'Y' + 52: 1, # 'Z' + 2: 3, # 'a' + 18: 0, # 'b' + 26: 1, # 'c' + 17: 0, # 'd' + 1: 3, # 'e' + 27: 0, # 'f' + 12: 0, # 'g' + 20: 0, # 'h' + 9: 3, # 'i' + 22: 0, # 'j' + 7: 0, # 'k' + 6: 0, # 'l' + 13: 1, # 'm' + 4: 1, # 'n' + 8: 3, # 'o' + 23: 0, # 'p' + 10: 1, # 'r' + 5: 0, # 's' + 3: 0, # 't' + 21: 2, # 'u' + 19: 0, # 'v' + 62: 0, # 'x' + 16: 1, # 'y' + 11: 0, # 'z' + 51: 2, # 'Ã' + 44: 1, # 'É' + 61: 1, # 'Ã' + 58: 1, # 'Ó' + 59: 1, # 'Ö' + 60: 1, # 'Ú' + 63: 1, # 'Ü' + 14: 2, # 'á' + 15: 2, # 'é' + 30: 1, # 'í' + 25: 1, # 'ó' + 24: 1, # 'ö' + 31: 1, # 'ú' + 29: 1, # 'ü' + 42: 0, # 'Å‘' + 56: 1, # 'ű' + }, + 35: { # 'N' + 28: 2, # 'A' + 40: 1, # 'B' + 54: 1, # 'C' + 45: 2, # 'D' + 32: 2, # 'E' + 50: 1, # 'F' + 49: 1, # 'G' + 38: 1, # 'H' + 39: 1, # 'I' + 53: 1, # 'J' + 36: 1, # 'K' + 41: 1, # 'L' + 34: 1, # 'M' + 35: 1, # 'N' + 47: 1, # 'O' + 46: 1, # 'P' + 43: 1, # 'R' + 33: 1, # 'S' + 37: 2, # 'T' + 57: 1, # 'U' + 48: 1, # 'V' + 55: 2, # 'Y' + 52: 1, # 'Z' + 2: 3, # 'a' + 18: 0, # 'b' + 26: 0, # 'c' + 17: 0, # 'd' + 1: 3, # 'e' + 27: 0, # 'f' + 12: 0, # 'g' + 20: 0, # 'h' + 9: 2, # 'i' + 22: 0, # 'j' + 7: 0, # 'k' + 6: 0, # 'l' + 13: 0, # 'm' + 4: 1, # 'n' + 8: 2, # 'o' + 23: 0, # 'p' + 10: 0, # 'r' + 5: 0, # 's' + 3: 0, # 't' + 21: 1, # 'u' + 19: 0, # 'v' + 62: 0, # 'x' + 16: 2, # 'y' + 11: 0, # 'z' + 51: 1, # 'Ã' + 44: 1, # 'É' + 61: 1, # 'Ã' + 58: 1, # 'Ó' + 59: 1, # 'Ö' + 60: 1, # 'Ú' + 63: 1, # 'Ü' + 14: 1, # 'á' + 15: 2, # 'é' + 30: 1, # 'í' + 25: 1, # 'ó' + 24: 1, # 'ö' + 31: 0, # 'ú' + 29: 0, # 'ü' + 42: 1, # 'Å‘' + 56: 0, # 'ű' + }, + 47: { # 'O' + 28: 1, # 'A' + 40: 1, # 'B' + 54: 1, # 'C' + 45: 1, # 'D' + 32: 1, # 'E' + 50: 1, # 'F' + 49: 1, # 'G' + 38: 1, # 'H' + 39: 1, # 'I' + 53: 1, # 'J' + 36: 2, # 'K' + 41: 2, # 'L' + 34: 2, # 'M' + 35: 2, # 'N' + 47: 1, # 'O' + 46: 1, # 'P' + 43: 2, # 'R' + 33: 2, # 'S' + 37: 2, # 'T' + 57: 1, # 'U' + 48: 1, # 'V' + 55: 1, # 'Y' + 52: 1, # 'Z' + 2: 0, # 'a' + 18: 1, # 'b' + 26: 1, # 'c' + 17: 1, # 'd' + 1: 1, # 'e' + 27: 1, # 'f' + 12: 1, # 'g' + 20: 1, # 'h' + 9: 1, # 'i' + 22: 1, # 'j' + 7: 2, # 'k' + 6: 2, # 'l' + 13: 1, # 'm' + 4: 1, # 'n' + 8: 1, # 'o' + 23: 1, # 'p' + 10: 2, # 'r' + 5: 1, # 's' + 3: 2, # 't' + 21: 1, # 'u' + 19: 0, # 'v' + 62: 1, # 'x' + 16: 0, # 'y' + 11: 1, # 'z' + 51: 1, # 'Ã' + 44: 1, # 'É' + 61: 0, # 'Ã' + 58: 1, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 0, # 'á' + 15: 0, # 'é' + 30: 0, # 'í' + 25: 0, # 'ó' + 24: 0, # 'ö' + 31: 0, # 'ú' + 29: 0, # 'ü' + 42: 0, # 'Å‘' + 56: 0, # 'ű' + }, + 46: { # 'P' + 28: 1, # 'A' + 40: 1, # 'B' + 54: 1, # 'C' + 45: 1, # 'D' + 32: 1, # 'E' + 50: 1, # 'F' + 49: 1, # 'G' + 38: 1, # 'H' + 39: 1, # 'I' + 53: 1, # 'J' + 36: 1, # 'K' + 41: 1, # 'L' + 34: 0, # 'M' + 35: 1, # 'N' + 47: 1, # 'O' + 46: 1, # 'P' + 43: 2, # 'R' + 33: 1, # 'S' + 37: 1, # 'T' + 57: 1, # 'U' + 48: 1, # 'V' + 55: 0, # 'Y' + 52: 1, # 'Z' + 2: 2, # 'a' + 18: 0, # 'b' + 26: 0, # 'c' + 17: 0, # 'd' + 1: 2, # 'e' + 27: 1, # 'f' + 12: 0, # 'g' + 20: 1, # 'h' + 9: 2, # 'i' + 22: 0, # 'j' + 7: 0, # 'k' + 6: 1, # 'l' + 13: 0, # 'm' + 4: 1, # 'n' + 8: 2, # 'o' + 23: 0, # 'p' + 10: 2, # 'r' + 5: 1, # 's' + 3: 0, # 't' + 21: 1, # 'u' + 19: 0, # 'v' + 62: 0, # 'x' + 16: 1, # 'y' + 11: 0, # 'z' + 51: 2, # 'Ã' + 44: 1, # 'É' + 61: 1, # 'Ã' + 58: 1, # 'Ó' + 59: 1, # 'Ö' + 60: 0, # 'Ú' + 63: 1, # 'Ü' + 14: 3, # 'á' + 15: 2, # 'é' + 30: 0, # 'í' + 25: 1, # 'ó' + 24: 1, # 'ö' + 31: 0, # 'ú' + 29: 1, # 'ü' + 42: 1, # 'Å‘' + 56: 0, # 'ű' + }, + 43: { # 'R' + 28: 2, # 'A' + 40: 1, # 'B' + 54: 1, # 'C' + 45: 1, # 'D' + 32: 2, # 'E' + 50: 1, # 'F' + 49: 1, # 'G' + 38: 1, # 'H' + 39: 2, # 'I' + 53: 1, # 'J' + 36: 1, # 'K' + 41: 1, # 'L' + 34: 1, # 'M' + 35: 1, # 'N' + 47: 2, # 'O' + 46: 1, # 'P' + 43: 1, # 'R' + 33: 2, # 'S' + 37: 2, # 'T' + 57: 1, # 'U' + 48: 1, # 'V' + 55: 1, # 'Y' + 52: 1, # 'Z' + 2: 2, # 'a' + 18: 0, # 'b' + 26: 0, # 'c' + 17: 0, # 'd' + 1: 2, # 'e' + 27: 0, # 'f' + 12: 0, # 'g' + 20: 1, # 'h' + 9: 2, # 'i' + 22: 0, # 'j' + 7: 0, # 'k' + 6: 0, # 'l' + 13: 0, # 'm' + 4: 0, # 'n' + 8: 2, # 'o' + 23: 0, # 'p' + 10: 0, # 'r' + 5: 0, # 's' + 3: 0, # 't' + 21: 1, # 'u' + 19: 0, # 'v' + 62: 0, # 'x' + 16: 1, # 'y' + 11: 0, # 'z' + 51: 2, # 'Ã' + 44: 1, # 'É' + 61: 1, # 'Ã' + 58: 2, # 'Ó' + 59: 1, # 'Ö' + 60: 1, # 'Ú' + 63: 1, # 'Ü' + 14: 2, # 'á' + 15: 2, # 'é' + 30: 1, # 'í' + 25: 2, # 'ó' + 24: 1, # 'ö' + 31: 1, # 'ú' + 29: 1, # 'ü' + 42: 0, # 'Å‘' + 56: 0, # 'ű' + }, + 33: { # 'S' + 28: 2, # 'A' + 40: 1, # 'B' + 54: 1, # 'C' + 45: 1, # 'D' + 32: 2, # 'E' + 50: 1, # 'F' + 49: 1, # 'G' + 38: 1, # 'H' + 39: 2, # 'I' + 53: 1, # 'J' + 36: 1, # 'K' + 41: 1, # 'L' + 34: 1, # 'M' + 35: 1, # 'N' + 47: 2, # 'O' + 46: 1, # 'P' + 43: 1, # 'R' + 33: 2, # 'S' + 37: 2, # 'T' + 57: 1, # 'U' + 48: 1, # 'V' + 55: 1, # 'Y' + 52: 3, # 'Z' + 2: 2, # 'a' + 18: 0, # 'b' + 26: 1, # 'c' + 17: 0, # 'd' + 1: 2, # 'e' + 27: 0, # 'f' + 12: 0, # 'g' + 20: 1, # 'h' + 9: 2, # 'i' + 22: 0, # 'j' + 7: 1, # 'k' + 6: 1, # 'l' + 13: 1, # 'm' + 4: 0, # 'n' + 8: 2, # 'o' + 23: 1, # 'p' + 10: 0, # 'r' + 5: 0, # 's' + 3: 1, # 't' + 21: 1, # 'u' + 19: 1, # 'v' + 62: 0, # 'x' + 16: 1, # 'y' + 11: 3, # 'z' + 51: 2, # 'Ã' + 44: 1, # 'É' + 61: 1, # 'Ã' + 58: 1, # 'Ó' + 59: 1, # 'Ö' + 60: 1, # 'Ú' + 63: 1, # 'Ü' + 14: 2, # 'á' + 15: 1, # 'é' + 30: 1, # 'í' + 25: 1, # 'ó' + 24: 1, # 'ö' + 31: 1, # 'ú' + 29: 1, # 'ü' + 42: 1, # 'Å‘' + 56: 1, # 'ű' + }, + 37: { # 'T' + 28: 2, # 'A' + 40: 1, # 'B' + 54: 1, # 'C' + 45: 1, # 'D' + 32: 2, # 'E' + 50: 1, # 'F' + 49: 1, # 'G' + 38: 1, # 'H' + 39: 2, # 'I' + 53: 1, # 'J' + 36: 1, # 'K' + 41: 1, # 'L' + 34: 1, # 'M' + 35: 1, # 'N' + 47: 2, # 'O' + 46: 1, # 'P' + 43: 2, # 'R' + 33: 1, # 'S' + 37: 2, # 'T' + 57: 1, # 'U' + 48: 1, # 'V' + 55: 1, # 'Y' + 52: 1, # 'Z' + 2: 2, # 'a' + 18: 0, # 'b' + 26: 0, # 'c' + 17: 0, # 'd' + 1: 2, # 'e' + 27: 0, # 'f' + 12: 0, # 'g' + 20: 1, # 'h' + 9: 2, # 'i' + 22: 0, # 'j' + 7: 0, # 'k' + 6: 0, # 'l' + 13: 0, # 'm' + 4: 0, # 'n' + 8: 2, # 'o' + 23: 0, # 'p' + 10: 1, # 'r' + 5: 1, # 's' + 3: 0, # 't' + 21: 2, # 'u' + 19: 0, # 'v' + 62: 0, # 'x' + 16: 1, # 'y' + 11: 1, # 'z' + 51: 2, # 'Ã' + 44: 2, # 'É' + 61: 1, # 'Ã' + 58: 1, # 'Ó' + 59: 1, # 'Ö' + 60: 1, # 'Ú' + 63: 1, # 'Ü' + 14: 2, # 'á' + 15: 1, # 'é' + 30: 1, # 'í' + 25: 1, # 'ó' + 24: 2, # 'ö' + 31: 1, # 'ú' + 29: 1, # 'ü' + 42: 1, # 'Å‘' + 56: 1, # 'ű' + }, + 57: { # 'U' + 28: 1, # 'A' + 40: 1, # 'B' + 54: 1, # 'C' + 45: 1, # 'D' + 32: 1, # 'E' + 50: 1, # 'F' + 49: 1, # 'G' + 38: 1, # 'H' + 39: 1, # 'I' + 53: 1, # 'J' + 36: 1, # 'K' + 41: 1, # 'L' + 34: 1, # 'M' + 35: 1, # 'N' + 47: 1, # 'O' + 46: 1, # 'P' + 43: 1, # 'R' + 33: 2, # 'S' + 37: 1, # 'T' + 57: 0, # 'U' + 48: 1, # 'V' + 55: 0, # 'Y' + 52: 1, # 'Z' + 2: 0, # 'a' + 18: 1, # 'b' + 26: 1, # 'c' + 17: 1, # 'd' + 1: 1, # 'e' + 27: 0, # 'f' + 12: 2, # 'g' + 20: 0, # 'h' + 9: 0, # 'i' + 22: 1, # 'j' + 7: 1, # 'k' + 6: 1, # 'l' + 13: 1, # 'm' + 4: 1, # 'n' + 8: 0, # 'o' + 23: 1, # 'p' + 10: 1, # 'r' + 5: 1, # 's' + 3: 1, # 't' + 21: 0, # 'u' + 19: 0, # 'v' + 62: 0, # 'x' + 16: 0, # 'y' + 11: 1, # 'z' + 51: 0, # 'Ã' + 44: 0, # 'É' + 61: 1, # 'Ã' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 0, # 'á' + 15: 0, # 'é' + 30: 0, # 'í' + 25: 0, # 'ó' + 24: 0, # 'ö' + 31: 0, # 'ú' + 29: 0, # 'ü' + 42: 0, # 'Å‘' + 56: 0, # 'ű' + }, + 48: { # 'V' + 28: 2, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 1, # 'D' + 32: 2, # 'E' + 50: 1, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 2, # 'I' + 53: 1, # 'J' + 36: 1, # 'K' + 41: 0, # 'L' + 34: 1, # 'M' + 35: 1, # 'N' + 47: 1, # 'O' + 46: 1, # 'P' + 43: 1, # 'R' + 33: 1, # 'S' + 37: 1, # 'T' + 57: 1, # 'U' + 48: 1, # 'V' + 55: 1, # 'Y' + 52: 0, # 'Z' + 2: 3, # 'a' + 18: 0, # 'b' + 26: 0, # 'c' + 17: 0, # 'd' + 1: 2, # 'e' + 27: 0, # 'f' + 12: 0, # 'g' + 20: 0, # 'h' + 9: 2, # 'i' + 22: 0, # 'j' + 7: 0, # 'k' + 6: 1, # 'l' + 13: 0, # 'm' + 4: 0, # 'n' + 8: 2, # 'o' + 23: 0, # 'p' + 10: 0, # 'r' + 5: 0, # 's' + 3: 0, # 't' + 21: 1, # 'u' + 19: 0, # 'v' + 62: 0, # 'x' + 16: 0, # 'y' + 11: 0, # 'z' + 51: 2, # 'Ã' + 44: 2, # 'É' + 61: 1, # 'Ã' + 58: 1, # 'Ó' + 59: 1, # 'Ö' + 60: 0, # 'Ú' + 63: 1, # 'Ü' + 14: 2, # 'á' + 15: 2, # 'é' + 30: 1, # 'í' + 25: 0, # 'ó' + 24: 1, # 'ö' + 31: 0, # 'ú' + 29: 0, # 'ü' + 42: 0, # 'Å‘' + 56: 0, # 'ű' + }, + 55: { # 'Y' + 28: 2, # 'A' + 40: 1, # 'B' + 54: 1, # 'C' + 45: 1, # 'D' + 32: 2, # 'E' + 50: 1, # 'F' + 49: 1, # 'G' + 38: 1, # 'H' + 39: 1, # 'I' + 53: 1, # 'J' + 36: 1, # 'K' + 41: 1, # 'L' + 34: 1, # 'M' + 35: 1, # 'N' + 47: 1, # 'O' + 46: 1, # 'P' + 43: 1, # 'R' + 33: 1, # 'S' + 37: 1, # 'T' + 57: 1, # 'U' + 48: 1, # 'V' + 55: 0, # 'Y' + 52: 2, # 'Z' + 2: 1, # 'a' + 18: 0, # 'b' + 26: 0, # 'c' + 17: 1, # 'd' + 1: 1, # 'e' + 27: 0, # 'f' + 12: 0, # 'g' + 20: 0, # 'h' + 9: 0, # 'i' + 22: 0, # 'j' + 7: 0, # 'k' + 6: 0, # 'l' + 13: 0, # 'm' + 4: 0, # 'n' + 8: 1, # 'o' + 23: 1, # 'p' + 10: 0, # 'r' + 5: 0, # 's' + 3: 0, # 't' + 21: 0, # 'u' + 19: 1, # 'v' + 62: 0, # 'x' + 16: 0, # 'y' + 11: 0, # 'z' + 51: 1, # 'Ã' + 44: 1, # 'É' + 61: 1, # 'Ã' + 58: 1, # 'Ó' + 59: 1, # 'Ö' + 60: 1, # 'Ú' + 63: 1, # 'Ü' + 14: 0, # 'á' + 15: 0, # 'é' + 30: 0, # 'í' + 25: 0, # 'ó' + 24: 0, # 'ö' + 31: 0, # 'ú' + 29: 0, # 'ü' + 42: 0, # 'Å‘' + 56: 0, # 'ű' + }, + 52: { # 'Z' + 28: 2, # 'A' + 40: 1, # 'B' + 54: 0, # 'C' + 45: 1, # 'D' + 32: 2, # 'E' + 50: 1, # 'F' + 49: 1, # 'G' + 38: 1, # 'H' + 39: 2, # 'I' + 53: 1, # 'J' + 36: 1, # 'K' + 41: 1, # 'L' + 34: 1, # 'M' + 35: 1, # 'N' + 47: 2, # 'O' + 46: 1, # 'P' + 43: 1, # 'R' + 33: 2, # 'S' + 37: 1, # 'T' + 57: 1, # 'U' + 48: 1, # 'V' + 55: 1, # 'Y' + 52: 1, # 'Z' + 2: 1, # 'a' + 18: 0, # 'b' + 26: 0, # 'c' + 17: 0, # 'd' + 1: 1, # 'e' + 27: 0, # 'f' + 12: 0, # 'g' + 20: 0, # 'h' + 9: 1, # 'i' + 22: 0, # 'j' + 7: 0, # 'k' + 6: 0, # 'l' + 13: 0, # 'm' + 4: 1, # 'n' + 8: 1, # 'o' + 23: 0, # 'p' + 10: 1, # 'r' + 5: 2, # 's' + 3: 0, # 't' + 21: 1, # 'u' + 19: 0, # 'v' + 62: 0, # 'x' + 16: 0, # 'y' + 11: 0, # 'z' + 51: 2, # 'Ã' + 44: 1, # 'É' + 61: 1, # 'Ã' + 58: 1, # 'Ó' + 59: 1, # 'Ö' + 60: 1, # 'Ú' + 63: 1, # 'Ü' + 14: 1, # 'á' + 15: 1, # 'é' + 30: 0, # 'í' + 25: 0, # 'ó' + 24: 1, # 'ö' + 31: 1, # 'ú' + 29: 1, # 'ü' + 42: 0, # 'Å‘' + 56: 0, # 'ű' + }, + 2: { # 'a' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 1, # 'a' + 18: 3, # 'b' + 26: 3, # 'c' + 17: 3, # 'd' + 1: 2, # 'e' + 27: 2, # 'f' + 12: 3, # 'g' + 20: 3, # 'h' + 9: 3, # 'i' + 22: 3, # 'j' + 7: 3, # 'k' + 6: 3, # 'l' + 13: 3, # 'm' + 4: 3, # 'n' + 8: 2, # 'o' + 23: 3, # 'p' + 10: 3, # 'r' + 5: 3, # 's' + 3: 3, # 't' + 21: 3, # 'u' + 19: 3, # 'v' + 62: 1, # 'x' + 16: 2, # 'y' + 11: 3, # 'z' + 51: 0, # 'Ã' + 44: 0, # 'É' + 61: 0, # 'Ã' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 1, # 'á' + 15: 1, # 'é' + 30: 1, # 'í' + 25: 1, # 'ó' + 24: 1, # 'ö' + 31: 1, # 'ú' + 29: 1, # 'ü' + 42: 0, # 'Å‘' + 56: 0, # 'ű' + }, + 18: { # 'b' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 3, # 'a' + 18: 3, # 'b' + 26: 1, # 'c' + 17: 1, # 'd' + 1: 3, # 'e' + 27: 1, # 'f' + 12: 1, # 'g' + 20: 1, # 'h' + 9: 3, # 'i' + 22: 2, # 'j' + 7: 2, # 'k' + 6: 2, # 'l' + 13: 1, # 'm' + 4: 2, # 'n' + 8: 3, # 'o' + 23: 1, # 'p' + 10: 3, # 'r' + 5: 2, # 's' + 3: 1, # 't' + 21: 3, # 'u' + 19: 1, # 'v' + 62: 0, # 'x' + 16: 1, # 'y' + 11: 1, # 'z' + 51: 0, # 'Ã' + 44: 0, # 'É' + 61: 0, # 'Ã' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 3, # 'á' + 15: 3, # 'é' + 30: 2, # 'í' + 25: 3, # 'ó' + 24: 2, # 'ö' + 31: 2, # 'ú' + 29: 2, # 'ü' + 42: 2, # 'Å‘' + 56: 1, # 'ű' + }, + 26: { # 'c' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 1, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 1, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 2, # 'a' + 18: 1, # 'b' + 26: 2, # 'c' + 17: 1, # 'd' + 1: 3, # 'e' + 27: 1, # 'f' + 12: 1, # 'g' + 20: 3, # 'h' + 9: 3, # 'i' + 22: 1, # 'j' + 7: 2, # 'k' + 6: 1, # 'l' + 13: 1, # 'm' + 4: 1, # 'n' + 8: 3, # 'o' + 23: 1, # 'p' + 10: 2, # 'r' + 5: 3, # 's' + 3: 2, # 't' + 21: 2, # 'u' + 19: 1, # 'v' + 62: 0, # 'x' + 16: 1, # 'y' + 11: 2, # 'z' + 51: 0, # 'Ã' + 44: 0, # 'É' + 61: 0, # 'Ã' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 2, # 'á' + 15: 2, # 'é' + 30: 2, # 'í' + 25: 1, # 'ó' + 24: 1, # 'ö' + 31: 1, # 'ú' + 29: 1, # 'ü' + 42: 0, # 'Å‘' + 56: 0, # 'ű' + }, + 17: { # 'd' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 3, # 'a' + 18: 2, # 'b' + 26: 1, # 'c' + 17: 2, # 'd' + 1: 3, # 'e' + 27: 1, # 'f' + 12: 1, # 'g' + 20: 2, # 'h' + 9: 3, # 'i' + 22: 3, # 'j' + 7: 2, # 'k' + 6: 1, # 'l' + 13: 2, # 'm' + 4: 3, # 'n' + 8: 3, # 'o' + 23: 1, # 'p' + 10: 3, # 'r' + 5: 3, # 's' + 3: 3, # 't' + 21: 3, # 'u' + 19: 3, # 'v' + 62: 0, # 'x' + 16: 2, # 'y' + 11: 2, # 'z' + 51: 0, # 'Ã' + 44: 0, # 'É' + 61: 0, # 'Ã' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 3, # 'á' + 15: 3, # 'é' + 30: 3, # 'í' + 25: 3, # 'ó' + 24: 3, # 'ö' + 31: 2, # 'ú' + 29: 2, # 'ü' + 42: 2, # 'Å‘' + 56: 1, # 'ű' + }, + 1: { # 'e' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 2, # 'a' + 18: 3, # 'b' + 26: 3, # 'c' + 17: 3, # 'd' + 1: 2, # 'e' + 27: 3, # 'f' + 12: 3, # 'g' + 20: 3, # 'h' + 9: 3, # 'i' + 22: 3, # 'j' + 7: 3, # 'k' + 6: 3, # 'l' + 13: 3, # 'm' + 4: 3, # 'n' + 8: 2, # 'o' + 23: 3, # 'p' + 10: 3, # 'r' + 5: 3, # 's' + 3: 3, # 't' + 21: 2, # 'u' + 19: 3, # 'v' + 62: 2, # 'x' + 16: 2, # 'y' + 11: 3, # 'z' + 51: 0, # 'Ã' + 44: 0, # 'É' + 61: 0, # 'Ã' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 3, # 'á' + 15: 1, # 'é' + 30: 1, # 'í' + 25: 1, # 'ó' + 24: 1, # 'ö' + 31: 1, # 'ú' + 29: 1, # 'ü' + 42: 0, # 'Å‘' + 56: 0, # 'ű' + }, + 27: { # 'f' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 3, # 'a' + 18: 1, # 'b' + 26: 1, # 'c' + 17: 1, # 'd' + 1: 3, # 'e' + 27: 2, # 'f' + 12: 1, # 'g' + 20: 1, # 'h' + 9: 3, # 'i' + 22: 2, # 'j' + 7: 1, # 'k' + 6: 1, # 'l' + 13: 1, # 'm' + 4: 1, # 'n' + 8: 3, # 'o' + 23: 0, # 'p' + 10: 3, # 'r' + 5: 1, # 's' + 3: 1, # 't' + 21: 2, # 'u' + 19: 1, # 'v' + 62: 0, # 'x' + 16: 1, # 'y' + 11: 0, # 'z' + 51: 0, # 'Ã' + 44: 0, # 'É' + 61: 0, # 'Ã' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 3, # 'á' + 15: 3, # 'é' + 30: 1, # 'í' + 25: 1, # 'ó' + 24: 3, # 'ö' + 31: 1, # 'ú' + 29: 2, # 'ü' + 42: 1, # 'Å‘' + 56: 1, # 'ű' + }, + 12: { # 'g' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 3, # 'a' + 18: 3, # 'b' + 26: 2, # 'c' + 17: 2, # 'd' + 1: 3, # 'e' + 27: 2, # 'f' + 12: 3, # 'g' + 20: 3, # 'h' + 9: 3, # 'i' + 22: 3, # 'j' + 7: 2, # 'k' + 6: 3, # 'l' + 13: 2, # 'm' + 4: 3, # 'n' + 8: 3, # 'o' + 23: 1, # 'p' + 10: 3, # 'r' + 5: 3, # 's' + 3: 3, # 't' + 21: 3, # 'u' + 19: 3, # 'v' + 62: 0, # 'x' + 16: 3, # 'y' + 11: 2, # 'z' + 51: 0, # 'Ã' + 44: 0, # 'É' + 61: 0, # 'Ã' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 3, # 'á' + 15: 3, # 'é' + 30: 2, # 'í' + 25: 3, # 'ó' + 24: 2, # 'ö' + 31: 2, # 'ú' + 29: 2, # 'ü' + 42: 2, # 'Å‘' + 56: 1, # 'ű' + }, + 20: { # 'h' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 3, # 'a' + 18: 1, # 'b' + 26: 1, # 'c' + 17: 0, # 'd' + 1: 3, # 'e' + 27: 0, # 'f' + 12: 1, # 'g' + 20: 2, # 'h' + 9: 3, # 'i' + 22: 1, # 'j' + 7: 1, # 'k' + 6: 1, # 'l' + 13: 1, # 'm' + 4: 1, # 'n' + 8: 3, # 'o' + 23: 0, # 'p' + 10: 1, # 'r' + 5: 2, # 's' + 3: 1, # 't' + 21: 3, # 'u' + 19: 1, # 'v' + 62: 0, # 'x' + 16: 2, # 'y' + 11: 0, # 'z' + 51: 0, # 'Ã' + 44: 0, # 'É' + 61: 0, # 'Ã' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 3, # 'á' + 15: 3, # 'é' + 30: 3, # 'í' + 25: 2, # 'ó' + 24: 2, # 'ö' + 31: 2, # 'ú' + 29: 1, # 'ü' + 42: 1, # 'Å‘' + 56: 1, # 'ű' + }, + 9: { # 'i' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 3, # 'a' + 18: 3, # 'b' + 26: 3, # 'c' + 17: 3, # 'd' + 1: 3, # 'e' + 27: 3, # 'f' + 12: 3, # 'g' + 20: 3, # 'h' + 9: 2, # 'i' + 22: 2, # 'j' + 7: 3, # 'k' + 6: 3, # 'l' + 13: 3, # 'm' + 4: 3, # 'n' + 8: 2, # 'o' + 23: 2, # 'p' + 10: 3, # 'r' + 5: 3, # 's' + 3: 3, # 't' + 21: 3, # 'u' + 19: 3, # 'v' + 62: 1, # 'x' + 16: 1, # 'y' + 11: 3, # 'z' + 51: 0, # 'Ã' + 44: 0, # 'É' + 61: 0, # 'Ã' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 3, # 'á' + 15: 2, # 'é' + 30: 1, # 'í' + 25: 3, # 'ó' + 24: 1, # 'ö' + 31: 2, # 'ú' + 29: 1, # 'ü' + 42: 0, # 'Å‘' + 56: 1, # 'ű' + }, + 22: { # 'j' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 3, # 'a' + 18: 2, # 'b' + 26: 1, # 'c' + 17: 3, # 'd' + 1: 3, # 'e' + 27: 1, # 'f' + 12: 1, # 'g' + 20: 2, # 'h' + 9: 1, # 'i' + 22: 2, # 'j' + 7: 2, # 'k' + 6: 2, # 'l' + 13: 1, # 'm' + 4: 2, # 'n' + 8: 3, # 'o' + 23: 1, # 'p' + 10: 2, # 'r' + 5: 2, # 's' + 3: 3, # 't' + 21: 3, # 'u' + 19: 1, # 'v' + 62: 0, # 'x' + 16: 0, # 'y' + 11: 2, # 'z' + 51: 0, # 'Ã' + 44: 0, # 'É' + 61: 0, # 'Ã' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 3, # 'á' + 15: 3, # 'é' + 30: 1, # 'í' + 25: 3, # 'ó' + 24: 3, # 'ö' + 31: 3, # 'ú' + 29: 2, # 'ü' + 42: 1, # 'Å‘' + 56: 1, # 'ű' + }, + 7: { # 'k' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 3, # 'a' + 18: 3, # 'b' + 26: 2, # 'c' + 17: 1, # 'd' + 1: 3, # 'e' + 27: 1, # 'f' + 12: 1, # 'g' + 20: 2, # 'h' + 9: 3, # 'i' + 22: 2, # 'j' + 7: 3, # 'k' + 6: 3, # 'l' + 13: 1, # 'm' + 4: 3, # 'n' + 8: 3, # 'o' + 23: 1, # 'p' + 10: 3, # 'r' + 5: 3, # 's' + 3: 3, # 't' + 21: 3, # 'u' + 19: 2, # 'v' + 62: 0, # 'x' + 16: 2, # 'y' + 11: 1, # 'z' + 51: 0, # 'Ã' + 44: 0, # 'É' + 61: 0, # 'Ã' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 3, # 'á' + 15: 3, # 'é' + 30: 3, # 'í' + 25: 2, # 'ó' + 24: 3, # 'ö' + 31: 1, # 'ú' + 29: 3, # 'ü' + 42: 1, # 'Å‘' + 56: 1, # 'ű' + }, + 6: { # 'l' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 1, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 1, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 3, # 'a' + 18: 2, # 'b' + 26: 3, # 'c' + 17: 3, # 'd' + 1: 3, # 'e' + 27: 3, # 'f' + 12: 3, # 'g' + 20: 3, # 'h' + 9: 3, # 'i' + 22: 3, # 'j' + 7: 3, # 'k' + 6: 3, # 'l' + 13: 3, # 'm' + 4: 3, # 'n' + 8: 3, # 'o' + 23: 2, # 'p' + 10: 2, # 'r' + 5: 3, # 's' + 3: 3, # 't' + 21: 3, # 'u' + 19: 3, # 'v' + 62: 0, # 'x' + 16: 3, # 'y' + 11: 2, # 'z' + 51: 0, # 'Ã' + 44: 0, # 'É' + 61: 0, # 'Ã' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 3, # 'á' + 15: 3, # 'é' + 30: 3, # 'í' + 25: 3, # 'ó' + 24: 3, # 'ö' + 31: 2, # 'ú' + 29: 2, # 'ü' + 42: 3, # 'Å‘' + 56: 1, # 'ű' + }, + 13: { # 'm' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 3, # 'a' + 18: 3, # 'b' + 26: 2, # 'c' + 17: 1, # 'd' + 1: 3, # 'e' + 27: 1, # 'f' + 12: 1, # 'g' + 20: 2, # 'h' + 9: 3, # 'i' + 22: 2, # 'j' + 7: 1, # 'k' + 6: 3, # 'l' + 13: 3, # 'm' + 4: 2, # 'n' + 8: 3, # 'o' + 23: 3, # 'p' + 10: 2, # 'r' + 5: 2, # 's' + 3: 2, # 't' + 21: 3, # 'u' + 19: 1, # 'v' + 62: 0, # 'x' + 16: 1, # 'y' + 11: 2, # 'z' + 51: 0, # 'Ã' + 44: 0, # 'É' + 61: 0, # 'Ã' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 3, # 'á' + 15: 3, # 'é' + 30: 2, # 'í' + 25: 2, # 'ó' + 24: 2, # 'ö' + 31: 2, # 'ú' + 29: 2, # 'ü' + 42: 1, # 'Å‘' + 56: 2, # 'ű' + }, + 4: { # 'n' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 3, # 'a' + 18: 3, # 'b' + 26: 3, # 'c' + 17: 3, # 'd' + 1: 3, # 'e' + 27: 2, # 'f' + 12: 3, # 'g' + 20: 3, # 'h' + 9: 3, # 'i' + 22: 2, # 'j' + 7: 3, # 'k' + 6: 2, # 'l' + 13: 2, # 'm' + 4: 3, # 'n' + 8: 3, # 'o' + 23: 2, # 'p' + 10: 2, # 'r' + 5: 3, # 's' + 3: 3, # 't' + 21: 3, # 'u' + 19: 2, # 'v' + 62: 1, # 'x' + 16: 3, # 'y' + 11: 3, # 'z' + 51: 0, # 'Ã' + 44: 0, # 'É' + 61: 0, # 'Ã' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 3, # 'á' + 15: 3, # 'é' + 30: 2, # 'í' + 25: 2, # 'ó' + 24: 3, # 'ö' + 31: 2, # 'ú' + 29: 3, # 'ü' + 42: 2, # 'Å‘' + 56: 1, # 'ű' + }, + 8: { # 'o' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 1, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 2, # 'a' + 18: 3, # 'b' + 26: 3, # 'c' + 17: 3, # 'd' + 1: 2, # 'e' + 27: 2, # 'f' + 12: 3, # 'g' + 20: 3, # 'h' + 9: 2, # 'i' + 22: 2, # 'j' + 7: 3, # 'k' + 6: 3, # 'l' + 13: 3, # 'm' + 4: 3, # 'n' + 8: 1, # 'o' + 23: 3, # 'p' + 10: 3, # 'r' + 5: 3, # 's' + 3: 3, # 't' + 21: 2, # 'u' + 19: 3, # 'v' + 62: 1, # 'x' + 16: 1, # 'y' + 11: 3, # 'z' + 51: 0, # 'Ã' + 44: 0, # 'É' + 61: 0, # 'Ã' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 1, # 'á' + 15: 2, # 'é' + 30: 1, # 'í' + 25: 1, # 'ó' + 24: 1, # 'ö' + 31: 1, # 'ú' + 29: 1, # 'ü' + 42: 0, # 'Å‘' + 56: 0, # 'ű' + }, + 23: { # 'p' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 3, # 'a' + 18: 1, # 'b' + 26: 2, # 'c' + 17: 1, # 'd' + 1: 3, # 'e' + 27: 1, # 'f' + 12: 1, # 'g' + 20: 2, # 'h' + 9: 3, # 'i' + 22: 2, # 'j' + 7: 2, # 'k' + 6: 3, # 'l' + 13: 1, # 'm' + 4: 2, # 'n' + 8: 3, # 'o' + 23: 3, # 'p' + 10: 3, # 'r' + 5: 2, # 's' + 3: 2, # 't' + 21: 3, # 'u' + 19: 2, # 'v' + 62: 0, # 'x' + 16: 1, # 'y' + 11: 2, # 'z' + 51: 0, # 'Ã' + 44: 0, # 'É' + 61: 0, # 'Ã' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 3, # 'á' + 15: 3, # 'é' + 30: 2, # 'í' + 25: 2, # 'ó' + 24: 2, # 'ö' + 31: 1, # 'ú' + 29: 2, # 'ü' + 42: 1, # 'Å‘' + 56: 1, # 'ű' + }, + 10: { # 'r' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 3, # 'a' + 18: 3, # 'b' + 26: 3, # 'c' + 17: 3, # 'd' + 1: 3, # 'e' + 27: 2, # 'f' + 12: 3, # 'g' + 20: 2, # 'h' + 9: 3, # 'i' + 22: 3, # 'j' + 7: 3, # 'k' + 6: 3, # 'l' + 13: 3, # 'm' + 4: 3, # 'n' + 8: 3, # 'o' + 23: 2, # 'p' + 10: 3, # 'r' + 5: 3, # 's' + 3: 3, # 't' + 21: 3, # 'u' + 19: 3, # 'v' + 62: 1, # 'x' + 16: 2, # 'y' + 11: 3, # 'z' + 51: 0, # 'Ã' + 44: 0, # 'É' + 61: 0, # 'Ã' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 3, # 'á' + 15: 3, # 'é' + 30: 2, # 'í' + 25: 3, # 'ó' + 24: 3, # 'ö' + 31: 3, # 'ú' + 29: 3, # 'ü' + 42: 2, # 'Å‘' + 56: 2, # 'ű' + }, + 5: { # 's' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 3, # 'a' + 18: 3, # 'b' + 26: 2, # 'c' + 17: 2, # 'd' + 1: 3, # 'e' + 27: 2, # 'f' + 12: 2, # 'g' + 20: 2, # 'h' + 9: 3, # 'i' + 22: 1, # 'j' + 7: 3, # 'k' + 6: 2, # 'l' + 13: 3, # 'm' + 4: 3, # 'n' + 8: 3, # 'o' + 23: 2, # 'p' + 10: 3, # 'r' + 5: 3, # 's' + 3: 3, # 't' + 21: 3, # 'u' + 19: 2, # 'v' + 62: 0, # 'x' + 16: 1, # 'y' + 11: 3, # 'z' + 51: 0, # 'Ã' + 44: 0, # 'É' + 61: 0, # 'Ã' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 3, # 'á' + 15: 3, # 'é' + 30: 3, # 'í' + 25: 3, # 'ó' + 24: 3, # 'ö' + 31: 3, # 'ú' + 29: 3, # 'ü' + 42: 2, # 'Å‘' + 56: 1, # 'ű' + }, + 3: { # 't' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 3, # 'a' + 18: 3, # 'b' + 26: 2, # 'c' + 17: 1, # 'd' + 1: 3, # 'e' + 27: 2, # 'f' + 12: 1, # 'g' + 20: 3, # 'h' + 9: 3, # 'i' + 22: 3, # 'j' + 7: 3, # 'k' + 6: 3, # 'l' + 13: 2, # 'm' + 4: 3, # 'n' + 8: 3, # 'o' + 23: 1, # 'p' + 10: 3, # 'r' + 5: 3, # 's' + 3: 3, # 't' + 21: 3, # 'u' + 19: 3, # 'v' + 62: 0, # 'x' + 16: 3, # 'y' + 11: 1, # 'z' + 51: 0, # 'Ã' + 44: 0, # 'É' + 61: 0, # 'Ã' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 3, # 'á' + 15: 3, # 'é' + 30: 2, # 'í' + 25: 3, # 'ó' + 24: 3, # 'ö' + 31: 3, # 'ú' + 29: 3, # 'ü' + 42: 3, # 'Å‘' + 56: 2, # 'ű' + }, + 21: { # 'u' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 1, # 'a' + 18: 2, # 'b' + 26: 2, # 'c' + 17: 3, # 'd' + 1: 2, # 'e' + 27: 1, # 'f' + 12: 3, # 'g' + 20: 2, # 'h' + 9: 2, # 'i' + 22: 2, # 'j' + 7: 3, # 'k' + 6: 3, # 'l' + 13: 3, # 'm' + 4: 3, # 'n' + 8: 1, # 'o' + 23: 2, # 'p' + 10: 3, # 'r' + 5: 3, # 's' + 3: 3, # 't' + 21: 1, # 'u' + 19: 3, # 'v' + 62: 1, # 'x' + 16: 1, # 'y' + 11: 2, # 'z' + 51: 0, # 'Ã' + 44: 0, # 'É' + 61: 0, # 'Ã' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 2, # 'á' + 15: 1, # 'é' + 30: 1, # 'í' + 25: 1, # 'ó' + 24: 0, # 'ö' + 31: 1, # 'ú' + 29: 0, # 'ü' + 42: 0, # 'Å‘' + 56: 0, # 'ű' + }, + 19: { # 'v' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 3, # 'a' + 18: 2, # 'b' + 26: 1, # 'c' + 17: 1, # 'd' + 1: 3, # 'e' + 27: 1, # 'f' + 12: 1, # 'g' + 20: 1, # 'h' + 9: 3, # 'i' + 22: 1, # 'j' + 7: 1, # 'k' + 6: 1, # 'l' + 13: 1, # 'm' + 4: 1, # 'n' + 8: 3, # 'o' + 23: 1, # 'p' + 10: 1, # 'r' + 5: 2, # 's' + 3: 2, # 't' + 21: 2, # 'u' + 19: 2, # 'v' + 62: 0, # 'x' + 16: 1, # 'y' + 11: 1, # 'z' + 51: 0, # 'Ã' + 44: 0, # 'É' + 61: 0, # 'Ã' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 3, # 'á' + 15: 3, # 'é' + 30: 2, # 'í' + 25: 2, # 'ó' + 24: 2, # 'ö' + 31: 1, # 'ú' + 29: 2, # 'ü' + 42: 1, # 'Å‘' + 56: 1, # 'ű' + }, + 62: { # 'x' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 1, # 'a' + 18: 1, # 'b' + 26: 1, # 'c' + 17: 0, # 'd' + 1: 1, # 'e' + 27: 1, # 'f' + 12: 0, # 'g' + 20: 0, # 'h' + 9: 1, # 'i' + 22: 0, # 'j' + 7: 1, # 'k' + 6: 1, # 'l' + 13: 1, # 'm' + 4: 1, # 'n' + 8: 1, # 'o' + 23: 1, # 'p' + 10: 1, # 'r' + 5: 1, # 's' + 3: 1, # 't' + 21: 1, # 'u' + 19: 0, # 'v' + 62: 0, # 'x' + 16: 0, # 'y' + 11: 0, # 'z' + 51: 0, # 'Ã' + 44: 0, # 'É' + 61: 0, # 'Ã' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 1, # 'á' + 15: 1, # 'é' + 30: 1, # 'í' + 25: 1, # 'ó' + 24: 0, # 'ö' + 31: 0, # 'ú' + 29: 0, # 'ü' + 42: 0, # 'Å‘' + 56: 0, # 'ű' + }, + 16: { # 'y' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 3, # 'a' + 18: 2, # 'b' + 26: 1, # 'c' + 17: 1, # 'd' + 1: 3, # 'e' + 27: 2, # 'f' + 12: 2, # 'g' + 20: 2, # 'h' + 9: 3, # 'i' + 22: 2, # 'j' + 7: 2, # 'k' + 6: 2, # 'l' + 13: 2, # 'm' + 4: 3, # 'n' + 8: 3, # 'o' + 23: 2, # 'p' + 10: 2, # 'r' + 5: 3, # 's' + 3: 3, # 't' + 21: 3, # 'u' + 19: 3, # 'v' + 62: 0, # 'x' + 16: 0, # 'y' + 11: 2, # 'z' + 51: 0, # 'Ã' + 44: 0, # 'É' + 61: 0, # 'Ã' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 3, # 'á' + 15: 3, # 'é' + 30: 2, # 'í' + 25: 2, # 'ó' + 24: 3, # 'ö' + 31: 2, # 'ú' + 29: 2, # 'ü' + 42: 1, # 'Å‘' + 56: 2, # 'ű' + }, + 11: { # 'z' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 3, # 'a' + 18: 2, # 'b' + 26: 1, # 'c' + 17: 3, # 'd' + 1: 3, # 'e' + 27: 1, # 'f' + 12: 2, # 'g' + 20: 2, # 'h' + 9: 3, # 'i' + 22: 1, # 'j' + 7: 3, # 'k' + 6: 2, # 'l' + 13: 3, # 'm' + 4: 3, # 'n' + 8: 3, # 'o' + 23: 1, # 'p' + 10: 2, # 'r' + 5: 3, # 's' + 3: 3, # 't' + 21: 3, # 'u' + 19: 2, # 'v' + 62: 0, # 'x' + 16: 1, # 'y' + 11: 3, # 'z' + 51: 0, # 'Ã' + 44: 0, # 'É' + 61: 0, # 'Ã' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 3, # 'á' + 15: 3, # 'é' + 30: 3, # 'í' + 25: 3, # 'ó' + 24: 3, # 'ö' + 31: 2, # 'ú' + 29: 3, # 'ü' + 42: 2, # 'Å‘' + 56: 1, # 'ű' + }, + 51: { # 'Ã' + 28: 0, # 'A' + 40: 1, # 'B' + 54: 1, # 'C' + 45: 1, # 'D' + 32: 0, # 'E' + 50: 1, # 'F' + 49: 2, # 'G' + 38: 1, # 'H' + 39: 1, # 'I' + 53: 1, # 'J' + 36: 1, # 'K' + 41: 2, # 'L' + 34: 1, # 'M' + 35: 2, # 'N' + 47: 0, # 'O' + 46: 1, # 'P' + 43: 2, # 'R' + 33: 2, # 'S' + 37: 1, # 'T' + 57: 0, # 'U' + 48: 1, # 'V' + 55: 0, # 'Y' + 52: 1, # 'Z' + 2: 0, # 'a' + 18: 1, # 'b' + 26: 1, # 'c' + 17: 1, # 'd' + 1: 0, # 'e' + 27: 0, # 'f' + 12: 1, # 'g' + 20: 1, # 'h' + 9: 0, # 'i' + 22: 1, # 'j' + 7: 1, # 'k' + 6: 2, # 'l' + 13: 2, # 'm' + 4: 0, # 'n' + 8: 0, # 'o' + 23: 1, # 'p' + 10: 1, # 'r' + 5: 1, # 's' + 3: 1, # 't' + 21: 0, # 'u' + 19: 0, # 'v' + 62: 0, # 'x' + 16: 0, # 'y' + 11: 1, # 'z' + 51: 0, # 'Ã' + 44: 0, # 'É' + 61: 1, # 'Ã' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 0, # 'á' + 15: 0, # 'é' + 30: 0, # 'í' + 25: 0, # 'ó' + 24: 0, # 'ö' + 31: 0, # 'ú' + 29: 0, # 'ü' + 42: 0, # 'Å‘' + 56: 0, # 'ű' + }, + 44: { # 'É' + 28: 0, # 'A' + 40: 1, # 'B' + 54: 1, # 'C' + 45: 1, # 'D' + 32: 1, # 'E' + 50: 0, # 'F' + 49: 2, # 'G' + 38: 1, # 'H' + 39: 1, # 'I' + 53: 1, # 'J' + 36: 1, # 'K' + 41: 2, # 'L' + 34: 1, # 'M' + 35: 2, # 'N' + 47: 0, # 'O' + 46: 1, # 'P' + 43: 2, # 'R' + 33: 2, # 'S' + 37: 2, # 'T' + 57: 0, # 'U' + 48: 1, # 'V' + 55: 0, # 'Y' + 52: 1, # 'Z' + 2: 0, # 'a' + 18: 1, # 'b' + 26: 1, # 'c' + 17: 1, # 'd' + 1: 0, # 'e' + 27: 0, # 'f' + 12: 1, # 'g' + 20: 1, # 'h' + 9: 0, # 'i' + 22: 1, # 'j' + 7: 1, # 'k' + 6: 2, # 'l' + 13: 1, # 'm' + 4: 2, # 'n' + 8: 0, # 'o' + 23: 1, # 'p' + 10: 2, # 'r' + 5: 3, # 's' + 3: 1, # 't' + 21: 0, # 'u' + 19: 1, # 'v' + 62: 0, # 'x' + 16: 0, # 'y' + 11: 0, # 'z' + 51: 0, # 'Ã' + 44: 1, # 'É' + 61: 0, # 'Ã' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 0, # 'á' + 15: 0, # 'é' + 30: 0, # 'í' + 25: 0, # 'ó' + 24: 0, # 'ö' + 31: 0, # 'ú' + 29: 0, # 'ü' + 42: 0, # 'Å‘' + 56: 0, # 'ű' + }, + 61: { # 'Ã' + 28: 0, # 'A' + 40: 1, # 'B' + 54: 1, # 'C' + 45: 1, # 'D' + 32: 0, # 'E' + 50: 1, # 'F' + 49: 1, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 1, # 'J' + 36: 0, # 'K' + 41: 1, # 'L' + 34: 1, # 'M' + 35: 1, # 'N' + 47: 0, # 'O' + 46: 1, # 'P' + 43: 1, # 'R' + 33: 1, # 'S' + 37: 1, # 'T' + 57: 0, # 'U' + 48: 1, # 'V' + 55: 0, # 'Y' + 52: 1, # 'Z' + 2: 0, # 'a' + 18: 0, # 'b' + 26: 0, # 'c' + 17: 0, # 'd' + 1: 0, # 'e' + 27: 0, # 'f' + 12: 2, # 'g' + 20: 0, # 'h' + 9: 0, # 'i' + 22: 0, # 'j' + 7: 0, # 'k' + 6: 0, # 'l' + 13: 1, # 'm' + 4: 0, # 'n' + 8: 0, # 'o' + 23: 0, # 'p' + 10: 1, # 'r' + 5: 0, # 's' + 3: 1, # 't' + 21: 0, # 'u' + 19: 0, # 'v' + 62: 0, # 'x' + 16: 0, # 'y' + 11: 1, # 'z' + 51: 0, # 'Ã' + 44: 0, # 'É' + 61: 0, # 'Ã' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 0, # 'á' + 15: 0, # 'é' + 30: 0, # 'í' + 25: 0, # 'ó' + 24: 0, # 'ö' + 31: 0, # 'ú' + 29: 0, # 'ü' + 42: 0, # 'Å‘' + 56: 0, # 'ű' + }, + 58: { # 'Ó' + 28: 1, # 'A' + 40: 1, # 'B' + 54: 1, # 'C' + 45: 1, # 'D' + 32: 0, # 'E' + 50: 1, # 'F' + 49: 1, # 'G' + 38: 1, # 'H' + 39: 1, # 'I' + 53: 1, # 'J' + 36: 1, # 'K' + 41: 2, # 'L' + 34: 1, # 'M' + 35: 1, # 'N' + 47: 0, # 'O' + 46: 1, # 'P' + 43: 1, # 'R' + 33: 1, # 'S' + 37: 1, # 'T' + 57: 0, # 'U' + 48: 1, # 'V' + 55: 0, # 'Y' + 52: 1, # 'Z' + 2: 0, # 'a' + 18: 1, # 'b' + 26: 1, # 'c' + 17: 1, # 'd' + 1: 0, # 'e' + 27: 0, # 'f' + 12: 0, # 'g' + 20: 2, # 'h' + 9: 0, # 'i' + 22: 0, # 'j' + 7: 1, # 'k' + 6: 1, # 'l' + 13: 0, # 'm' + 4: 1, # 'n' + 8: 0, # 'o' + 23: 1, # 'p' + 10: 1, # 'r' + 5: 1, # 's' + 3: 0, # 't' + 21: 0, # 'u' + 19: 1, # 'v' + 62: 0, # 'x' + 16: 0, # 'y' + 11: 1, # 'z' + 51: 0, # 'Ã' + 44: 1, # 'É' + 61: 0, # 'Ã' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 0, # 'á' + 15: 0, # 'é' + 30: 0, # 'í' + 25: 0, # 'ó' + 24: 0, # 'ö' + 31: 0, # 'ú' + 29: 0, # 'ü' + 42: 0, # 'Å‘' + 56: 0, # 'ű' + }, + 59: { # 'Ö' + 28: 0, # 'A' + 40: 1, # 'B' + 54: 1, # 'C' + 45: 1, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 1, # 'G' + 38: 1, # 'H' + 39: 0, # 'I' + 53: 1, # 'J' + 36: 1, # 'K' + 41: 1, # 'L' + 34: 1, # 'M' + 35: 1, # 'N' + 47: 0, # 'O' + 46: 1, # 'P' + 43: 1, # 'R' + 33: 1, # 'S' + 37: 1, # 'T' + 57: 0, # 'U' + 48: 1, # 'V' + 55: 0, # 'Y' + 52: 1, # 'Z' + 2: 0, # 'a' + 18: 0, # 'b' + 26: 1, # 'c' + 17: 1, # 'd' + 1: 0, # 'e' + 27: 0, # 'f' + 12: 0, # 'g' + 20: 0, # 'h' + 9: 0, # 'i' + 22: 0, # 'j' + 7: 1, # 'k' + 6: 1, # 'l' + 13: 1, # 'm' + 4: 1, # 'n' + 8: 0, # 'o' + 23: 0, # 'p' + 10: 2, # 'r' + 5: 1, # 's' + 3: 1, # 't' + 21: 0, # 'u' + 19: 1, # 'v' + 62: 0, # 'x' + 16: 0, # 'y' + 11: 1, # 'z' + 51: 0, # 'Ã' + 44: 0, # 'É' + 61: 0, # 'Ã' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 0, # 'á' + 15: 0, # 'é' + 30: 0, # 'í' + 25: 0, # 'ó' + 24: 0, # 'ö' + 31: 0, # 'ú' + 29: 0, # 'ü' + 42: 0, # 'Å‘' + 56: 0, # 'ű' + }, + 60: { # 'Ú' + 28: 0, # 'A' + 40: 1, # 'B' + 54: 1, # 'C' + 45: 1, # 'D' + 32: 0, # 'E' + 50: 1, # 'F' + 49: 1, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 1, # 'J' + 36: 1, # 'K' + 41: 1, # 'L' + 34: 1, # 'M' + 35: 1, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 1, # 'R' + 33: 1, # 'S' + 37: 1, # 'T' + 57: 0, # 'U' + 48: 1, # 'V' + 55: 0, # 'Y' + 52: 1, # 'Z' + 2: 0, # 'a' + 18: 0, # 'b' + 26: 0, # 'c' + 17: 0, # 'd' + 1: 0, # 'e' + 27: 0, # 'f' + 12: 2, # 'g' + 20: 0, # 'h' + 9: 0, # 'i' + 22: 2, # 'j' + 7: 0, # 'k' + 6: 0, # 'l' + 13: 0, # 'm' + 4: 1, # 'n' + 8: 0, # 'o' + 23: 0, # 'p' + 10: 1, # 'r' + 5: 1, # 's' + 3: 1, # 't' + 21: 0, # 'u' + 19: 0, # 'v' + 62: 0, # 'x' + 16: 0, # 'y' + 11: 0, # 'z' + 51: 0, # 'Ã' + 44: 0, # 'É' + 61: 0, # 'Ã' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 0, # 'á' + 15: 0, # 'é' + 30: 0, # 'í' + 25: 0, # 'ó' + 24: 0, # 'ö' + 31: 0, # 'ú' + 29: 0, # 'ü' + 42: 0, # 'Å‘' + 56: 0, # 'ű' + }, + 63: { # 'Ü' + 28: 0, # 'A' + 40: 1, # 'B' + 54: 0, # 'C' + 45: 1, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 1, # 'G' + 38: 1, # 'H' + 39: 0, # 'I' + 53: 1, # 'J' + 36: 1, # 'K' + 41: 1, # 'L' + 34: 1, # 'M' + 35: 1, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 1, # 'R' + 33: 1, # 'S' + 37: 1, # 'T' + 57: 0, # 'U' + 48: 1, # 'V' + 55: 0, # 'Y' + 52: 1, # 'Z' + 2: 0, # 'a' + 18: 1, # 'b' + 26: 0, # 'c' + 17: 1, # 'd' + 1: 0, # 'e' + 27: 0, # 'f' + 12: 1, # 'g' + 20: 0, # 'h' + 9: 0, # 'i' + 22: 0, # 'j' + 7: 0, # 'k' + 6: 1, # 'l' + 13: 0, # 'm' + 4: 1, # 'n' + 8: 0, # 'o' + 23: 0, # 'p' + 10: 1, # 'r' + 5: 1, # 's' + 3: 1, # 't' + 21: 0, # 'u' + 19: 1, # 'v' + 62: 0, # 'x' + 16: 0, # 'y' + 11: 1, # 'z' + 51: 0, # 'Ã' + 44: 0, # 'É' + 61: 0, # 'Ã' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 0, # 'á' + 15: 0, # 'é' + 30: 0, # 'í' + 25: 0, # 'ó' + 24: 0, # 'ö' + 31: 0, # 'ú' + 29: 0, # 'ü' + 42: 0, # 'Å‘' + 56: 0, # 'ű' + }, + 14: { # 'á' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 1, # 'a' + 18: 3, # 'b' + 26: 3, # 'c' + 17: 3, # 'd' + 1: 1, # 'e' + 27: 2, # 'f' + 12: 3, # 'g' + 20: 2, # 'h' + 9: 2, # 'i' + 22: 3, # 'j' + 7: 3, # 'k' + 6: 3, # 'l' + 13: 3, # 'm' + 4: 3, # 'n' + 8: 1, # 'o' + 23: 2, # 'p' + 10: 3, # 'r' + 5: 3, # 's' + 3: 3, # 't' + 21: 2, # 'u' + 19: 3, # 'v' + 62: 0, # 'x' + 16: 1, # 'y' + 11: 3, # 'z' + 51: 0, # 'Ã' + 44: 0, # 'É' + 61: 0, # 'Ã' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 1, # 'á' + 15: 2, # 'é' + 30: 1, # 'í' + 25: 0, # 'ó' + 24: 1, # 'ö' + 31: 0, # 'ú' + 29: 1, # 'ü' + 42: 0, # 'Å‘' + 56: 0, # 'ű' + }, + 15: { # 'é' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 1, # 'a' + 18: 3, # 'b' + 26: 2, # 'c' + 17: 3, # 'd' + 1: 1, # 'e' + 27: 1, # 'f' + 12: 3, # 'g' + 20: 3, # 'h' + 9: 2, # 'i' + 22: 2, # 'j' + 7: 3, # 'k' + 6: 3, # 'l' + 13: 3, # 'm' + 4: 3, # 'n' + 8: 1, # 'o' + 23: 3, # 'p' + 10: 3, # 'r' + 5: 3, # 's' + 3: 3, # 't' + 21: 0, # 'u' + 19: 3, # 'v' + 62: 0, # 'x' + 16: 0, # 'y' + 11: 3, # 'z' + 51: 0, # 'Ã' + 44: 0, # 'É' + 61: 0, # 'Ã' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 1, # 'á' + 15: 1, # 'é' + 30: 0, # 'í' + 25: 0, # 'ó' + 24: 0, # 'ö' + 31: 0, # 'ú' + 29: 1, # 'ü' + 42: 0, # 'Å‘' + 56: 0, # 'ű' + }, + 30: { # 'í' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 0, # 'a' + 18: 1, # 'b' + 26: 2, # 'c' + 17: 1, # 'd' + 1: 0, # 'e' + 27: 1, # 'f' + 12: 3, # 'g' + 20: 0, # 'h' + 9: 0, # 'i' + 22: 1, # 'j' + 7: 1, # 'k' + 6: 2, # 'l' + 13: 2, # 'm' + 4: 3, # 'n' + 8: 0, # 'o' + 23: 1, # 'p' + 10: 3, # 'r' + 5: 2, # 's' + 3: 3, # 't' + 21: 0, # 'u' + 19: 3, # 'v' + 62: 0, # 'x' + 16: 0, # 'y' + 11: 2, # 'z' + 51: 0, # 'Ã' + 44: 0, # 'É' + 61: 0, # 'Ã' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 0, # 'á' + 15: 0, # 'é' + 30: 0, # 'í' + 25: 0, # 'ó' + 24: 0, # 'ö' + 31: 0, # 'ú' + 29: 0, # 'ü' + 42: 0, # 'Å‘' + 56: 0, # 'ű' + }, + 25: { # 'ó' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 2, # 'a' + 18: 3, # 'b' + 26: 2, # 'c' + 17: 3, # 'd' + 1: 1, # 'e' + 27: 2, # 'f' + 12: 2, # 'g' + 20: 2, # 'h' + 9: 2, # 'i' + 22: 2, # 'j' + 7: 3, # 'k' + 6: 3, # 'l' + 13: 2, # 'm' + 4: 3, # 'n' + 8: 1, # 'o' + 23: 2, # 'p' + 10: 3, # 'r' + 5: 3, # 's' + 3: 3, # 't' + 21: 1, # 'u' + 19: 2, # 'v' + 62: 0, # 'x' + 16: 0, # 'y' + 11: 3, # 'z' + 51: 0, # 'Ã' + 44: 0, # 'É' + 61: 0, # 'Ã' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 1, # 'á' + 15: 1, # 'é' + 30: 1, # 'í' + 25: 0, # 'ó' + 24: 1, # 'ö' + 31: 1, # 'ú' + 29: 1, # 'ü' + 42: 0, # 'Å‘' + 56: 0, # 'ű' + }, + 24: { # 'ö' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 0, # 'a' + 18: 3, # 'b' + 26: 1, # 'c' + 17: 2, # 'd' + 1: 0, # 'e' + 27: 1, # 'f' + 12: 2, # 'g' + 20: 1, # 'h' + 9: 0, # 'i' + 22: 1, # 'j' + 7: 3, # 'k' + 6: 3, # 'l' + 13: 3, # 'm' + 4: 3, # 'n' + 8: 0, # 'o' + 23: 2, # 'p' + 10: 3, # 'r' + 5: 3, # 's' + 3: 3, # 't' + 21: 0, # 'u' + 19: 3, # 'v' + 62: 0, # 'x' + 16: 0, # 'y' + 11: 3, # 'z' + 51: 0, # 'Ã' + 44: 0, # 'É' + 61: 0, # 'Ã' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 0, # 'á' + 15: 0, # 'é' + 30: 0, # 'í' + 25: 0, # 'ó' + 24: 0, # 'ö' + 31: 0, # 'ú' + 29: 0, # 'ü' + 42: 0, # 'Å‘' + 56: 0, # 'ű' + }, + 31: { # 'ú' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 1, # 'a' + 18: 1, # 'b' + 26: 2, # 'c' + 17: 1, # 'd' + 1: 1, # 'e' + 27: 2, # 'f' + 12: 3, # 'g' + 20: 1, # 'h' + 9: 1, # 'i' + 22: 3, # 'j' + 7: 1, # 'k' + 6: 3, # 'l' + 13: 1, # 'm' + 4: 2, # 'n' + 8: 0, # 'o' + 23: 1, # 'p' + 10: 3, # 'r' + 5: 3, # 's' + 3: 2, # 't' + 21: 1, # 'u' + 19: 1, # 'v' + 62: 0, # 'x' + 16: 0, # 'y' + 11: 2, # 'z' + 51: 0, # 'Ã' + 44: 0, # 'É' + 61: 0, # 'Ã' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 1, # 'á' + 15: 1, # 'é' + 30: 0, # 'í' + 25: 0, # 'ó' + 24: 0, # 'ö' + 31: 0, # 'ú' + 29: 0, # 'ü' + 42: 0, # 'Å‘' + 56: 0, # 'ű' + }, + 29: { # 'ü' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 1, # 'a' + 18: 1, # 'b' + 26: 1, # 'c' + 17: 2, # 'd' + 1: 1, # 'e' + 27: 1, # 'f' + 12: 3, # 'g' + 20: 2, # 'h' + 9: 1, # 'i' + 22: 1, # 'j' + 7: 3, # 'k' + 6: 3, # 'l' + 13: 1, # 'm' + 4: 3, # 'n' + 8: 0, # 'o' + 23: 1, # 'p' + 10: 2, # 'r' + 5: 2, # 's' + 3: 2, # 't' + 21: 0, # 'u' + 19: 2, # 'v' + 62: 0, # 'x' + 16: 0, # 'y' + 11: 2, # 'z' + 51: 0, # 'Ã' + 44: 0, # 'É' + 61: 0, # 'Ã' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 0, # 'á' + 15: 1, # 'é' + 30: 0, # 'í' + 25: 0, # 'ó' + 24: 0, # 'ö' + 31: 0, # 'ú' + 29: 0, # 'ü' + 42: 0, # 'Å‘' + 56: 0, # 'ű' + }, + 42: { # 'Å‘' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 1, # 'a' + 18: 2, # 'b' + 26: 1, # 'c' + 17: 2, # 'd' + 1: 1, # 'e' + 27: 1, # 'f' + 12: 1, # 'g' + 20: 1, # 'h' + 9: 1, # 'i' + 22: 1, # 'j' + 7: 2, # 'k' + 6: 3, # 'l' + 13: 1, # 'm' + 4: 2, # 'n' + 8: 1, # 'o' + 23: 1, # 'p' + 10: 2, # 'r' + 5: 2, # 's' + 3: 2, # 't' + 21: 1, # 'u' + 19: 1, # 'v' + 62: 0, # 'x' + 16: 0, # 'y' + 11: 2, # 'z' + 51: 0, # 'Ã' + 44: 0, # 'É' + 61: 0, # 'Ã' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 0, # 'á' + 15: 1, # 'é' + 30: 1, # 'í' + 25: 0, # 'ó' + 24: 0, # 'ö' + 31: 0, # 'ú' + 29: 1, # 'ü' + 42: 0, # 'Å‘' + 56: 0, # 'ű' + }, + 56: { # 'ű' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 1, # 'a' + 18: 1, # 'b' + 26: 0, # 'c' + 17: 1, # 'd' + 1: 1, # 'e' + 27: 1, # 'f' + 12: 1, # 'g' + 20: 1, # 'h' + 9: 1, # 'i' + 22: 1, # 'j' + 7: 1, # 'k' + 6: 1, # 'l' + 13: 0, # 'm' + 4: 2, # 'n' + 8: 0, # 'o' + 23: 0, # 'p' + 10: 1, # 'r' + 5: 1, # 's' + 3: 1, # 't' + 21: 0, # 'u' + 19: 1, # 'v' + 62: 0, # 'x' + 16: 0, # 'y' + 11: 2, # 'z' + 51: 0, # 'Ã' + 44: 0, # 'É' + 61: 0, # 'Ã' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 0, # 'á' + 15: 0, # 'é' + 30: 0, # 'í' + 25: 0, # 'ó' + 24: 0, # 'ö' + 31: 0, # 'ú' + 29: 0, # 'ü' + 42: 0, # 'Å‘' + 56: 0, # 'ű' + }, +} + +# 255: Undefined characters that did not exist in training text +# 254: Carriage/Return +# 253: symbol (punctuation) that does not belong to word +# 252: 0 - 9 +# 251: Control characters + +# Character Mapping Table(s): +WINDOWS_1250_HUNGARIAN_CHAR_TO_ORDER = { + 0: 255, # '\x00' + 1: 255, # '\x01' + 2: 255, # '\x02' + 3: 255, # '\x03' + 4: 255, # '\x04' + 5: 255, # '\x05' + 6: 255, # '\x06' + 7: 255, # '\x07' + 8: 255, # '\x08' + 9: 255, # '\t' + 10: 254, # '\n' + 11: 255, # '\x0b' + 12: 255, # '\x0c' + 13: 254, # '\r' + 14: 255, # '\x0e' + 15: 255, # '\x0f' + 16: 255, # '\x10' + 17: 255, # '\x11' + 18: 255, # '\x12' + 19: 255, # '\x13' + 20: 255, # '\x14' + 21: 255, # '\x15' + 22: 255, # '\x16' + 23: 255, # '\x17' + 24: 255, # '\x18' + 25: 255, # '\x19' + 26: 255, # '\x1a' + 27: 255, # '\x1b' + 28: 255, # '\x1c' + 29: 255, # '\x1d' + 30: 255, # '\x1e' + 31: 255, # '\x1f' + 32: 253, # ' ' + 33: 253, # '!' + 34: 253, # '"' + 35: 253, # '#' + 36: 253, # '$' + 37: 253, # '%' + 38: 253, # '&' + 39: 253, # "'" + 40: 253, # '(' + 41: 253, # ')' + 42: 253, # '*' + 43: 253, # '+' + 44: 253, # ',' + 45: 253, # '-' + 46: 253, # '.' + 47: 253, # '/' + 48: 252, # '0' + 49: 252, # '1' + 50: 252, # '2' + 51: 252, # '3' + 52: 252, # '4' + 53: 252, # '5' + 54: 252, # '6' + 55: 252, # '7' + 56: 252, # '8' + 57: 252, # '9' + 58: 253, # ':' + 59: 253, # ';' + 60: 253, # '<' + 61: 253, # '=' + 62: 253, # '>' + 63: 253, # '?' + 64: 253, # '@' + 65: 28, # 'A' + 66: 40, # 'B' + 67: 54, # 'C' + 68: 45, # 'D' + 69: 32, # 'E' + 70: 50, # 'F' + 71: 49, # 'G' + 72: 38, # 'H' + 73: 39, # 'I' + 74: 53, # 'J' + 75: 36, # 'K' + 76: 41, # 'L' + 77: 34, # 'M' + 78: 35, # 'N' + 79: 47, # 'O' + 80: 46, # 'P' + 81: 72, # 'Q' + 82: 43, # 'R' + 83: 33, # 'S' + 84: 37, # 'T' + 85: 57, # 'U' + 86: 48, # 'V' + 87: 64, # 'W' + 88: 68, # 'X' + 89: 55, # 'Y' + 90: 52, # 'Z' + 91: 253, # '[' + 92: 253, # '\\' + 93: 253, # ']' + 94: 253, # '^' + 95: 253, # '_' + 96: 253, # '`' + 97: 2, # 'a' + 98: 18, # 'b' + 99: 26, # 'c' + 100: 17, # 'd' + 101: 1, # 'e' + 102: 27, # 'f' + 103: 12, # 'g' + 104: 20, # 'h' + 105: 9, # 'i' + 106: 22, # 'j' + 107: 7, # 'k' + 108: 6, # 'l' + 109: 13, # 'm' + 110: 4, # 'n' + 111: 8, # 'o' + 112: 23, # 'p' + 113: 67, # 'q' + 114: 10, # 'r' + 115: 5, # 's' + 116: 3, # 't' + 117: 21, # 'u' + 118: 19, # 'v' + 119: 65, # 'w' + 120: 62, # 'x' + 121: 16, # 'y' + 122: 11, # 'z' + 123: 253, # '{' + 124: 253, # '|' + 125: 253, # '}' + 126: 253, # '~' + 127: 253, # '\x7f' + 128: 161, # '€' + 129: 162, # None + 130: 163, # '‚' + 131: 164, # None + 132: 165, # '„' + 133: 166, # '…' + 134: 167, # '†' + 135: 168, # '‡' + 136: 169, # None + 137: 170, # '‰' + 138: 171, # 'Å ' + 139: 172, # '‹' + 140: 173, # 'Åš' + 141: 174, # 'Ť' + 142: 175, # 'Ž' + 143: 176, # 'Ź' + 144: 177, # None + 145: 178, # '‘' + 146: 179, # '’' + 147: 180, # '“' + 148: 78, # 'â€' + 149: 181, # '•' + 150: 69, # '–' + 151: 182, # '—' + 152: 183, # None + 153: 184, # 'â„¢' + 154: 185, # 'Å¡' + 155: 186, # '›' + 156: 187, # 'Å›' + 157: 188, # 'Å¥' + 158: 189, # 'ž' + 159: 190, # 'ź' + 160: 191, # '\xa0' + 161: 192, # 'ˇ' + 162: 193, # '˘' + 163: 194, # 'Å' + 164: 195, # '¤' + 165: 196, # 'Ä„' + 166: 197, # '¦' + 167: 76, # '§' + 168: 198, # '¨' + 169: 199, # '©' + 170: 200, # 'Åž' + 171: 201, # '«' + 172: 202, # '¬' + 173: 203, # '\xad' + 174: 204, # '®' + 175: 205, # 'Å»' + 176: 81, # '°' + 177: 206, # '±' + 178: 207, # 'Ë›' + 179: 208, # 'Å‚' + 180: 209, # '´' + 181: 210, # 'µ' + 182: 211, # '¶' + 183: 212, # '·' + 184: 213, # '¸' + 185: 214, # 'Ä…' + 186: 215, # 'ÅŸ' + 187: 216, # '»' + 188: 217, # 'Ľ' + 189: 218, # 'Ë' + 190: 219, # 'ľ' + 191: 220, # 'ż' + 192: 221, # 'Å”' + 193: 51, # 'Ã' + 194: 83, # 'Â' + 195: 222, # 'Ä‚' + 196: 80, # 'Ä' + 197: 223, # 'Ĺ' + 198: 224, # 'Ć' + 199: 225, # 'Ç' + 200: 226, # 'ÄŒ' + 201: 44, # 'É' + 202: 227, # 'Ę' + 203: 228, # 'Ë' + 204: 229, # 'Äš' + 205: 61, # 'Ã' + 206: 230, # 'ÃŽ' + 207: 231, # 'ÄŽ' + 208: 232, # 'Ä' + 209: 233, # 'Ń' + 210: 234, # 'Ň' + 211: 58, # 'Ó' + 212: 235, # 'Ô' + 213: 66, # 'Å' + 214: 59, # 'Ö' + 215: 236, # '×' + 216: 237, # 'Ř' + 217: 238, # 'Å®' + 218: 60, # 'Ú' + 219: 70, # 'Ű' + 220: 63, # 'Ü' + 221: 239, # 'Ã' + 222: 240, # 'Å¢' + 223: 241, # 'ß' + 224: 84, # 'Å•' + 225: 14, # 'á' + 226: 75, # 'â' + 227: 242, # 'ă' + 228: 71, # 'ä' + 229: 82, # 'ĺ' + 230: 243, # 'ć' + 231: 73, # 'ç' + 232: 244, # 'Ä' + 233: 15, # 'é' + 234: 85, # 'Ä™' + 235: 79, # 'ë' + 236: 86, # 'Ä›' + 237: 30, # 'í' + 238: 77, # 'î' + 239: 87, # 'Ä' + 240: 245, # 'Ä‘' + 241: 246, # 'Å„' + 242: 247, # 'ň' + 243: 25, # 'ó' + 244: 74, # 'ô' + 245: 42, # 'Å‘' + 246: 24, # 'ö' + 247: 248, # '÷' + 248: 249, # 'Å™' + 249: 250, # 'ů' + 250: 31, # 'ú' + 251: 56, # 'ű' + 252: 29, # 'ü' + 253: 251, # 'ý' + 254: 252, # 'Å£' + 255: 253, # 'Ë™' +} + +WINDOWS_1250_HUNGARIAN_MODEL = SingleByteCharSetModel(charset_name='windows-1250', + language='Hungarian', + char_to_order_map=WINDOWS_1250_HUNGARIAN_CHAR_TO_ORDER, + language_model=HUNGARIAN_LANG_MODEL, + typical_positive_ratio=0.947368, + keep_ascii_letters=True, + alphabet='ABCDEFGHIJKLMNOPRSTUVZabcdefghijklmnoprstuvzÃÉÃÓÖÚÜáéíóöúüÅőŰű') + +ISO_8859_2_HUNGARIAN_CHAR_TO_ORDER = { + 0: 255, # '\x00' + 1: 255, # '\x01' + 2: 255, # '\x02' + 3: 255, # '\x03' + 4: 255, # '\x04' + 5: 255, # '\x05' + 6: 255, # '\x06' + 7: 255, # '\x07' + 8: 255, # '\x08' + 9: 255, # '\t' + 10: 254, # '\n' + 11: 255, # '\x0b' + 12: 255, # '\x0c' + 13: 254, # '\r' + 14: 255, # '\x0e' + 15: 255, # '\x0f' + 16: 255, # '\x10' + 17: 255, # '\x11' + 18: 255, # '\x12' + 19: 255, # '\x13' + 20: 255, # '\x14' + 21: 255, # '\x15' + 22: 255, # '\x16' + 23: 255, # '\x17' + 24: 255, # '\x18' + 25: 255, # '\x19' + 26: 255, # '\x1a' + 27: 255, # '\x1b' + 28: 255, # '\x1c' + 29: 255, # '\x1d' + 30: 255, # '\x1e' + 31: 255, # '\x1f' + 32: 253, # ' ' + 33: 253, # '!' + 34: 253, # '"' + 35: 253, # '#' + 36: 253, # '$' + 37: 253, # '%' + 38: 253, # '&' + 39: 253, # "'" + 40: 253, # '(' + 41: 253, # ')' + 42: 253, # '*' + 43: 253, # '+' + 44: 253, # ',' + 45: 253, # '-' + 46: 253, # '.' + 47: 253, # '/' + 48: 252, # '0' + 49: 252, # '1' + 50: 252, # '2' + 51: 252, # '3' + 52: 252, # '4' + 53: 252, # '5' + 54: 252, # '6' + 55: 252, # '7' + 56: 252, # '8' + 57: 252, # '9' + 58: 253, # ':' + 59: 253, # ';' + 60: 253, # '<' + 61: 253, # '=' + 62: 253, # '>' + 63: 253, # '?' + 64: 253, # '@' + 65: 28, # 'A' + 66: 40, # 'B' + 67: 54, # 'C' + 68: 45, # 'D' + 69: 32, # 'E' + 70: 50, # 'F' + 71: 49, # 'G' + 72: 38, # 'H' + 73: 39, # 'I' + 74: 53, # 'J' + 75: 36, # 'K' + 76: 41, # 'L' + 77: 34, # 'M' + 78: 35, # 'N' + 79: 47, # 'O' + 80: 46, # 'P' + 81: 71, # 'Q' + 82: 43, # 'R' + 83: 33, # 'S' + 84: 37, # 'T' + 85: 57, # 'U' + 86: 48, # 'V' + 87: 64, # 'W' + 88: 68, # 'X' + 89: 55, # 'Y' + 90: 52, # 'Z' + 91: 253, # '[' + 92: 253, # '\\' + 93: 253, # ']' + 94: 253, # '^' + 95: 253, # '_' + 96: 253, # '`' + 97: 2, # 'a' + 98: 18, # 'b' + 99: 26, # 'c' + 100: 17, # 'd' + 101: 1, # 'e' + 102: 27, # 'f' + 103: 12, # 'g' + 104: 20, # 'h' + 105: 9, # 'i' + 106: 22, # 'j' + 107: 7, # 'k' + 108: 6, # 'l' + 109: 13, # 'm' + 110: 4, # 'n' + 111: 8, # 'o' + 112: 23, # 'p' + 113: 67, # 'q' + 114: 10, # 'r' + 115: 5, # 's' + 116: 3, # 't' + 117: 21, # 'u' + 118: 19, # 'v' + 119: 65, # 'w' + 120: 62, # 'x' + 121: 16, # 'y' + 122: 11, # 'z' + 123: 253, # '{' + 124: 253, # '|' + 125: 253, # '}' + 126: 253, # '~' + 127: 253, # '\x7f' + 128: 159, # '\x80' + 129: 160, # '\x81' + 130: 161, # '\x82' + 131: 162, # '\x83' + 132: 163, # '\x84' + 133: 164, # '\x85' + 134: 165, # '\x86' + 135: 166, # '\x87' + 136: 167, # '\x88' + 137: 168, # '\x89' + 138: 169, # '\x8a' + 139: 170, # '\x8b' + 140: 171, # '\x8c' + 141: 172, # '\x8d' + 142: 173, # '\x8e' + 143: 174, # '\x8f' + 144: 175, # '\x90' + 145: 176, # '\x91' + 146: 177, # '\x92' + 147: 178, # '\x93' + 148: 179, # '\x94' + 149: 180, # '\x95' + 150: 181, # '\x96' + 151: 182, # '\x97' + 152: 183, # '\x98' + 153: 184, # '\x99' + 154: 185, # '\x9a' + 155: 186, # '\x9b' + 156: 187, # '\x9c' + 157: 188, # '\x9d' + 158: 189, # '\x9e' + 159: 190, # '\x9f' + 160: 191, # '\xa0' + 161: 192, # 'Ä„' + 162: 193, # '˘' + 163: 194, # 'Å' + 164: 195, # '¤' + 165: 196, # 'Ľ' + 166: 197, # 'Åš' + 167: 75, # '§' + 168: 198, # '¨' + 169: 199, # 'Å ' + 170: 200, # 'Åž' + 171: 201, # 'Ť' + 172: 202, # 'Ź' + 173: 203, # '\xad' + 174: 204, # 'Ž' + 175: 205, # 'Å»' + 176: 79, # '°' + 177: 206, # 'Ä…' + 178: 207, # 'Ë›' + 179: 208, # 'Å‚' + 180: 209, # '´' + 181: 210, # 'ľ' + 182: 211, # 'Å›' + 183: 212, # 'ˇ' + 184: 213, # '¸' + 185: 214, # 'Å¡' + 186: 215, # 'ÅŸ' + 187: 216, # 'Å¥' + 188: 217, # 'ź' + 189: 218, # 'Ë' + 190: 219, # 'ž' + 191: 220, # 'ż' + 192: 221, # 'Å”' + 193: 51, # 'Ã' + 194: 81, # 'Â' + 195: 222, # 'Ä‚' + 196: 78, # 'Ä' + 197: 223, # 'Ĺ' + 198: 224, # 'Ć' + 199: 225, # 'Ç' + 200: 226, # 'ÄŒ' + 201: 44, # 'É' + 202: 227, # 'Ę' + 203: 228, # 'Ë' + 204: 229, # 'Äš' + 205: 61, # 'Ã' + 206: 230, # 'ÃŽ' + 207: 231, # 'ÄŽ' + 208: 232, # 'Ä' + 209: 233, # 'Ń' + 210: 234, # 'Ň' + 211: 58, # 'Ó' + 212: 235, # 'Ô' + 213: 66, # 'Å' + 214: 59, # 'Ö' + 215: 236, # '×' + 216: 237, # 'Ř' + 217: 238, # 'Å®' + 218: 60, # 'Ú' + 219: 69, # 'Ű' + 220: 63, # 'Ü' + 221: 239, # 'Ã' + 222: 240, # 'Å¢' + 223: 241, # 'ß' + 224: 82, # 'Å•' + 225: 14, # 'á' + 226: 74, # 'â' + 227: 242, # 'ă' + 228: 70, # 'ä' + 229: 80, # 'ĺ' + 230: 243, # 'ć' + 231: 72, # 'ç' + 232: 244, # 'Ä' + 233: 15, # 'é' + 234: 83, # 'Ä™' + 235: 77, # 'ë' + 236: 84, # 'Ä›' + 237: 30, # 'í' + 238: 76, # 'î' + 239: 85, # 'Ä' + 240: 245, # 'Ä‘' + 241: 246, # 'Å„' + 242: 247, # 'ň' + 243: 25, # 'ó' + 244: 73, # 'ô' + 245: 42, # 'Å‘' + 246: 24, # 'ö' + 247: 248, # '÷' + 248: 249, # 'Å™' + 249: 250, # 'ů' + 250: 31, # 'ú' + 251: 56, # 'ű' + 252: 29, # 'ü' + 253: 251, # 'ý' + 254: 252, # 'Å£' + 255: 253, # 'Ë™' +} + +ISO_8859_2_HUNGARIAN_MODEL = SingleByteCharSetModel(charset_name='ISO-8859-2', + language='Hungarian', + char_to_order_map=ISO_8859_2_HUNGARIAN_CHAR_TO_ORDER, + language_model=HUNGARIAN_LANG_MODEL, + typical_positive_ratio=0.947368, + keep_ascii_letters=True, + alphabet='ABCDEFGHIJKLMNOPRSTUVZabcdefghijklmnoprstuvzÃÉÃÓÖÚÜáéíóöúüÅőŰű') + diff --git a/venv/Lib/site-packages/pip/_vendor/chardet/langrussianmodel.py b/venv/Lib/site-packages/pip/_vendor/chardet/langrussianmodel.py new file mode 100644 index 0000000..5594452 --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/chardet/langrussianmodel.py @@ -0,0 +1,5718 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from pip._vendor.chardet.sbcharsetprober import SingleByteCharSetModel + + +# 3: Positive +# 2: Likely +# 1: Unlikely +# 0: Negative + +RUSSIAN_LANG_MODEL = { + 37: { # 'Ð' + 37: 0, # 'Ð' + 44: 1, # 'Б' + 33: 1, # 'Ð’' + 46: 1, # 'Г' + 41: 1, # 'Д' + 48: 1, # 'Е' + 56: 1, # 'Ж' + 51: 1, # 'З' + 42: 1, # 'И' + 60: 1, # 'Й' + 36: 1, # 'К' + 49: 1, # 'Л' + 38: 1, # 'М' + 31: 2, # 'Ð' + 34: 1, # 'О' + 35: 1, # 'П' + 45: 1, # 'Р' + 32: 1, # 'С' + 40: 1, # 'Т' + 52: 1, # 'У' + 53: 1, # 'Ф' + 55: 1, # 'Ð¥' + 58: 1, # 'Ц' + 50: 1, # 'Ч' + 57: 1, # 'Ш' + 63: 1, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 1, # 'Ю' + 43: 1, # 'Я' + 3: 1, # 'а' + 21: 2, # 'б' + 10: 2, # 'в' + 19: 2, # 'г' + 13: 2, # 'д' + 2: 0, # 'е' + 24: 1, # 'ж' + 20: 1, # 'з' + 4: 0, # 'и' + 23: 1, # 'й' + 11: 2, # 'к' + 8: 3, # 'л' + 12: 2, # 'м' + 5: 2, # 'н' + 1: 0, # 'о' + 15: 2, # 'п' + 9: 2, # 'Ñ€' + 7: 2, # 'Ñ' + 6: 2, # 'Ñ‚' + 14: 2, # 'у' + 39: 2, # 'Ñ„' + 26: 2, # 'Ñ…' + 28: 0, # 'ц' + 22: 1, # 'ч' + 25: 2, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ÑŠ' + 18: 0, # 'Ñ‹' + 17: 0, # 'ÑŒ' + 30: 1, # 'Ñ' + 27: 0, # 'ÑŽ' + 16: 0, # 'Ñ' + }, + 44: { # 'Б' + 37: 1, # 'Ð' + 44: 0, # 'Б' + 33: 1, # 'Ð’' + 46: 1, # 'Г' + 41: 0, # 'Д' + 48: 1, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 1, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 1, # 'Л' + 38: 1, # 'М' + 31: 1, # 'Ð' + 34: 1, # 'О' + 35: 0, # 'П' + 45: 1, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 1, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Ð¥' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 1, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 1, # 'Я' + 3: 2, # 'а' + 21: 0, # 'б' + 10: 0, # 'в' + 19: 0, # 'г' + 13: 1, # 'д' + 2: 3, # 'е' + 24: 0, # 'ж' + 20: 0, # 'з' + 4: 2, # 'и' + 23: 0, # 'й' + 11: 0, # 'к' + 8: 2, # 'л' + 12: 0, # 'м' + 5: 0, # 'н' + 1: 3, # 'о' + 15: 0, # 'п' + 9: 2, # 'Ñ€' + 7: 0, # 'Ñ' + 6: 0, # 'Ñ‚' + 14: 2, # 'у' + 39: 0, # 'Ñ„' + 26: 0, # 'Ñ…' + 28: 0, # 'ц' + 22: 0, # 'ч' + 25: 0, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ÑŠ' + 18: 2, # 'Ñ‹' + 17: 1, # 'ÑŒ' + 30: 2, # 'Ñ' + 27: 1, # 'ÑŽ' + 16: 1, # 'Ñ' + }, + 33: { # 'Ð’' + 37: 2, # 'Ð' + 44: 0, # 'Б' + 33: 1, # 'Ð’' + 46: 0, # 'Г' + 41: 1, # 'Д' + 48: 1, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 1, # 'И' + 60: 0, # 'Й' + 36: 1, # 'К' + 49: 1, # 'Л' + 38: 1, # 'М' + 31: 1, # 'Ð' + 34: 1, # 'О' + 35: 1, # 'П' + 45: 1, # 'Р' + 32: 1, # 'С' + 40: 1, # 'Т' + 52: 1, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Ð¥' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 1, # 'Ш' + 63: 0, # 'Щ' + 62: 1, # 'Ы' + 61: 1, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 1, # 'Я' + 3: 2, # 'а' + 21: 1, # 'б' + 10: 1, # 'в' + 19: 1, # 'г' + 13: 2, # 'д' + 2: 3, # 'е' + 24: 0, # 'ж' + 20: 2, # 'з' + 4: 2, # 'и' + 23: 0, # 'й' + 11: 1, # 'к' + 8: 2, # 'л' + 12: 2, # 'м' + 5: 2, # 'н' + 1: 3, # 'о' + 15: 2, # 'п' + 9: 2, # 'Ñ€' + 7: 3, # 'Ñ' + 6: 2, # 'Ñ‚' + 14: 2, # 'у' + 39: 0, # 'Ñ„' + 26: 1, # 'Ñ…' + 28: 1, # 'ц' + 22: 2, # 'ч' + 25: 1, # 'ш' + 29: 0, # 'щ' + 54: 1, # 'ÑŠ' + 18: 3, # 'Ñ‹' + 17: 1, # 'ÑŒ' + 30: 2, # 'Ñ' + 27: 0, # 'ÑŽ' + 16: 1, # 'Ñ' + }, + 46: { # 'Г' + 37: 1, # 'Ð' + 44: 1, # 'Б' + 33: 0, # 'Ð’' + 46: 0, # 'Г' + 41: 1, # 'Д' + 48: 1, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 1, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 1, # 'Л' + 38: 1, # 'М' + 31: 1, # 'Ð' + 34: 1, # 'О' + 35: 1, # 'П' + 45: 1, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 1, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Ð¥' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 2, # 'а' + 21: 0, # 'б' + 10: 1, # 'в' + 19: 0, # 'г' + 13: 2, # 'д' + 2: 2, # 'е' + 24: 0, # 'ж' + 20: 0, # 'з' + 4: 2, # 'и' + 23: 0, # 'й' + 11: 0, # 'к' + 8: 2, # 'л' + 12: 1, # 'м' + 5: 1, # 'н' + 1: 3, # 'о' + 15: 0, # 'п' + 9: 2, # 'Ñ€' + 7: 0, # 'Ñ' + 6: 0, # 'Ñ‚' + 14: 2, # 'у' + 39: 0, # 'Ñ„' + 26: 0, # 'Ñ…' + 28: 0, # 'ц' + 22: 0, # 'ч' + 25: 0, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ÑŠ' + 18: 0, # 'Ñ‹' + 17: 1, # 'ÑŒ' + 30: 1, # 'Ñ' + 27: 1, # 'ÑŽ' + 16: 0, # 'Ñ' + }, + 41: { # 'Д' + 37: 1, # 'Ð' + 44: 0, # 'Б' + 33: 1, # 'Ð’' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 2, # 'Е' + 56: 1, # 'Ж' + 51: 0, # 'З' + 42: 1, # 'И' + 60: 0, # 'Й' + 36: 1, # 'К' + 49: 1, # 'Л' + 38: 0, # 'М' + 31: 1, # 'Ð' + 34: 1, # 'О' + 35: 0, # 'П' + 45: 1, # 'Р' + 32: 1, # 'С' + 40: 0, # 'Т' + 52: 1, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Ð¥' + 58: 1, # 'Ц' + 50: 1, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 1, # 'Ы' + 61: 1, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 1, # 'Я' + 3: 3, # 'а' + 21: 0, # 'б' + 10: 2, # 'в' + 19: 0, # 'г' + 13: 0, # 'д' + 2: 2, # 'е' + 24: 3, # 'ж' + 20: 1, # 'з' + 4: 2, # 'и' + 23: 0, # 'й' + 11: 0, # 'к' + 8: 2, # 'л' + 12: 1, # 'м' + 5: 1, # 'н' + 1: 3, # 'о' + 15: 0, # 'п' + 9: 2, # 'Ñ€' + 7: 0, # 'Ñ' + 6: 0, # 'Ñ‚' + 14: 2, # 'у' + 39: 0, # 'Ñ„' + 26: 1, # 'Ñ…' + 28: 0, # 'ц' + 22: 0, # 'ч' + 25: 0, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ÑŠ' + 18: 1, # 'Ñ‹' + 17: 1, # 'ÑŒ' + 30: 2, # 'Ñ' + 27: 1, # 'ÑŽ' + 16: 1, # 'Ñ' + }, + 48: { # 'Е' + 37: 1, # 'Ð' + 44: 1, # 'Б' + 33: 1, # 'Ð’' + 46: 1, # 'Г' + 41: 1, # 'Д' + 48: 1, # 'Е' + 56: 1, # 'Ж' + 51: 1, # 'З' + 42: 1, # 'И' + 60: 1, # 'Й' + 36: 1, # 'К' + 49: 1, # 'Л' + 38: 1, # 'М' + 31: 2, # 'Ð' + 34: 1, # 'О' + 35: 1, # 'П' + 45: 2, # 'Р' + 32: 2, # 'С' + 40: 1, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 1, # 'Ð¥' + 58: 1, # 'Ц' + 50: 1, # 'Ч' + 57: 1, # 'Ш' + 63: 1, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 1, # 'Я' + 3: 0, # 'а' + 21: 0, # 'б' + 10: 2, # 'в' + 19: 2, # 'г' + 13: 2, # 'д' + 2: 2, # 'е' + 24: 1, # 'ж' + 20: 1, # 'з' + 4: 0, # 'и' + 23: 2, # 'й' + 11: 1, # 'к' + 8: 2, # 'л' + 12: 2, # 'м' + 5: 1, # 'н' + 1: 0, # 'о' + 15: 1, # 'п' + 9: 1, # 'Ñ€' + 7: 3, # 'Ñ' + 6: 0, # 'Ñ‚' + 14: 0, # 'у' + 39: 1, # 'Ñ„' + 26: 1, # 'Ñ…' + 28: 0, # 'ц' + 22: 0, # 'ч' + 25: 1, # 'ш' + 29: 2, # 'щ' + 54: 0, # 'ÑŠ' + 18: 0, # 'Ñ‹' + 17: 0, # 'ÑŒ' + 30: 0, # 'Ñ' + 27: 1, # 'ÑŽ' + 16: 0, # 'Ñ' + }, + 56: { # 'Ж' + 37: 1, # 'Ð' + 44: 0, # 'Б' + 33: 0, # 'Ð’' + 46: 0, # 'Г' + 41: 1, # 'Д' + 48: 1, # 'Е' + 56: 0, # 'Ж' + 51: 1, # 'З' + 42: 1, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 1, # 'Ð' + 34: 1, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 1, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Ð¥' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 2, # 'а' + 21: 1, # 'б' + 10: 0, # 'в' + 19: 1, # 'г' + 13: 1, # 'д' + 2: 2, # 'е' + 24: 1, # 'ж' + 20: 0, # 'з' + 4: 2, # 'и' + 23: 0, # 'й' + 11: 0, # 'к' + 8: 0, # 'л' + 12: 1, # 'м' + 5: 0, # 'н' + 1: 2, # 'о' + 15: 0, # 'п' + 9: 1, # 'Ñ€' + 7: 0, # 'Ñ' + 6: 0, # 'Ñ‚' + 14: 2, # 'у' + 39: 0, # 'Ñ„' + 26: 0, # 'Ñ…' + 28: 0, # 'ц' + 22: 0, # 'ч' + 25: 0, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ÑŠ' + 18: 0, # 'Ñ‹' + 17: 0, # 'ÑŒ' + 30: 0, # 'Ñ' + 27: 2, # 'ÑŽ' + 16: 0, # 'Ñ' + }, + 51: { # 'З' + 37: 1, # 'Ð' + 44: 0, # 'Б' + 33: 1, # 'Ð’' + 46: 1, # 'Г' + 41: 1, # 'Д' + 48: 1, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 1, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 1, # 'Л' + 38: 1, # 'М' + 31: 1, # 'Ð' + 34: 1, # 'О' + 35: 0, # 'П' + 45: 1, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 1, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Ð¥' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 1, # 'Ы' + 61: 1, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 3, # 'а' + 21: 1, # 'б' + 10: 2, # 'в' + 19: 0, # 'г' + 13: 2, # 'д' + 2: 2, # 'е' + 24: 0, # 'ж' + 20: 0, # 'з' + 4: 2, # 'и' + 23: 0, # 'й' + 11: 0, # 'к' + 8: 1, # 'л' + 12: 1, # 'м' + 5: 2, # 'н' + 1: 2, # 'о' + 15: 0, # 'п' + 9: 1, # 'Ñ€' + 7: 0, # 'Ñ' + 6: 0, # 'Ñ‚' + 14: 1, # 'у' + 39: 0, # 'Ñ„' + 26: 0, # 'Ñ…' + 28: 0, # 'ц' + 22: 0, # 'ч' + 25: 0, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ÑŠ' + 18: 1, # 'Ñ‹' + 17: 0, # 'ÑŒ' + 30: 0, # 'Ñ' + 27: 0, # 'ÑŽ' + 16: 1, # 'Ñ' + }, + 42: { # 'И' + 37: 1, # 'Ð' + 44: 1, # 'Б' + 33: 1, # 'Ð’' + 46: 1, # 'Г' + 41: 1, # 'Д' + 48: 2, # 'Е' + 56: 1, # 'Ж' + 51: 1, # 'З' + 42: 1, # 'И' + 60: 1, # 'Й' + 36: 1, # 'К' + 49: 1, # 'Л' + 38: 1, # 'М' + 31: 1, # 'Ð' + 34: 1, # 'О' + 35: 1, # 'П' + 45: 1, # 'Р' + 32: 2, # 'С' + 40: 1, # 'Т' + 52: 0, # 'У' + 53: 1, # 'Ф' + 55: 1, # 'Ð¥' + 58: 1, # 'Ц' + 50: 1, # 'Ч' + 57: 0, # 'Ш' + 63: 1, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 1, # 'Ю' + 43: 1, # 'Я' + 3: 1, # 'а' + 21: 2, # 'б' + 10: 2, # 'в' + 19: 2, # 'г' + 13: 2, # 'д' + 2: 2, # 'е' + 24: 0, # 'ж' + 20: 2, # 'з' + 4: 1, # 'и' + 23: 0, # 'й' + 11: 1, # 'к' + 8: 2, # 'л' + 12: 2, # 'м' + 5: 2, # 'н' + 1: 1, # 'о' + 15: 1, # 'п' + 9: 2, # 'Ñ€' + 7: 2, # 'Ñ' + 6: 2, # 'Ñ‚' + 14: 1, # 'у' + 39: 1, # 'Ñ„' + 26: 2, # 'Ñ…' + 28: 0, # 'ц' + 22: 0, # 'ч' + 25: 1, # 'ш' + 29: 1, # 'щ' + 54: 0, # 'ÑŠ' + 18: 0, # 'Ñ‹' + 17: 0, # 'ÑŒ' + 30: 0, # 'Ñ' + 27: 1, # 'ÑŽ' + 16: 0, # 'Ñ' + }, + 60: { # 'Й' + 37: 0, # 'Ð' + 44: 0, # 'Б' + 33: 0, # 'Ð’' + 46: 0, # 'Г' + 41: 1, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 1, # 'К' + 49: 1, # 'Л' + 38: 0, # 'М' + 31: 1, # 'Ð' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 1, # 'С' + 40: 1, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 1, # 'Ð¥' + 58: 1, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 0, # 'а' + 21: 0, # 'б' + 10: 0, # 'в' + 19: 0, # 'г' + 13: 0, # 'д' + 2: 1, # 'е' + 24: 0, # 'ж' + 20: 0, # 'з' + 4: 0, # 'и' + 23: 0, # 'й' + 11: 0, # 'к' + 8: 0, # 'л' + 12: 0, # 'м' + 5: 0, # 'н' + 1: 2, # 'о' + 15: 0, # 'п' + 9: 0, # 'Ñ€' + 7: 0, # 'Ñ' + 6: 0, # 'Ñ‚' + 14: 0, # 'у' + 39: 0, # 'Ñ„' + 26: 0, # 'Ñ…' + 28: 0, # 'ц' + 22: 0, # 'ч' + 25: 0, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ÑŠ' + 18: 0, # 'Ñ‹' + 17: 0, # 'ÑŒ' + 30: 0, # 'Ñ' + 27: 0, # 'ÑŽ' + 16: 0, # 'Ñ' + }, + 36: { # 'К' + 37: 2, # 'Ð' + 44: 0, # 'Б' + 33: 1, # 'Ð’' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 1, # 'Е' + 56: 0, # 'Ж' + 51: 1, # 'З' + 42: 1, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 1, # 'Л' + 38: 0, # 'М' + 31: 1, # 'Ð' + 34: 2, # 'О' + 35: 1, # 'П' + 45: 1, # 'Р' + 32: 1, # 'С' + 40: 1, # 'Т' + 52: 1, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Ð¥' + 58: 1, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 3, # 'а' + 21: 0, # 'б' + 10: 1, # 'в' + 19: 0, # 'г' + 13: 0, # 'д' + 2: 2, # 'е' + 24: 0, # 'ж' + 20: 0, # 'з' + 4: 2, # 'и' + 23: 0, # 'й' + 11: 0, # 'к' + 8: 2, # 'л' + 12: 0, # 'м' + 5: 1, # 'н' + 1: 3, # 'о' + 15: 0, # 'п' + 9: 2, # 'Ñ€' + 7: 2, # 'Ñ' + 6: 2, # 'Ñ‚' + 14: 2, # 'у' + 39: 0, # 'Ñ„' + 26: 1, # 'Ñ…' + 28: 0, # 'ц' + 22: 0, # 'ч' + 25: 0, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ÑŠ' + 18: 1, # 'Ñ‹' + 17: 1, # 'ÑŒ' + 30: 2, # 'Ñ' + 27: 1, # 'ÑŽ' + 16: 0, # 'Ñ' + }, + 49: { # 'Л' + 37: 2, # 'Ð' + 44: 0, # 'Б' + 33: 0, # 'Ð’' + 46: 1, # 'Г' + 41: 0, # 'Д' + 48: 1, # 'Е' + 56: 1, # 'Ж' + 51: 0, # 'З' + 42: 1, # 'И' + 60: 0, # 'Й' + 36: 1, # 'К' + 49: 1, # 'Л' + 38: 1, # 'М' + 31: 0, # 'Ð' + 34: 1, # 'О' + 35: 1, # 'П' + 45: 0, # 'Р' + 32: 1, # 'С' + 40: 1, # 'Т' + 52: 1, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Ð¥' + 58: 0, # 'Ц' + 50: 1, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 1, # 'Ы' + 61: 1, # 'Ь' + 47: 0, # 'Э' + 59: 1, # 'Ю' + 43: 1, # 'Я' + 3: 2, # 'а' + 21: 0, # 'б' + 10: 0, # 'в' + 19: 1, # 'г' + 13: 0, # 'д' + 2: 2, # 'е' + 24: 1, # 'ж' + 20: 0, # 'з' + 4: 2, # 'и' + 23: 0, # 'й' + 11: 0, # 'к' + 8: 1, # 'л' + 12: 0, # 'м' + 5: 1, # 'н' + 1: 2, # 'о' + 15: 0, # 'п' + 9: 0, # 'Ñ€' + 7: 0, # 'Ñ' + 6: 0, # 'Ñ‚' + 14: 2, # 'у' + 39: 0, # 'Ñ„' + 26: 1, # 'Ñ…' + 28: 0, # 'ц' + 22: 0, # 'ч' + 25: 0, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ÑŠ' + 18: 1, # 'Ñ‹' + 17: 1, # 'ÑŒ' + 30: 2, # 'Ñ' + 27: 2, # 'ÑŽ' + 16: 1, # 'Ñ' + }, + 38: { # 'М' + 37: 1, # 'Ð' + 44: 1, # 'Б' + 33: 1, # 'Ð’' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 1, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 1, # 'И' + 60: 0, # 'Й' + 36: 1, # 'К' + 49: 1, # 'Л' + 38: 1, # 'М' + 31: 1, # 'Ð' + 34: 1, # 'О' + 35: 1, # 'П' + 45: 1, # 'Р' + 32: 1, # 'С' + 40: 1, # 'Т' + 52: 1, # 'У' + 53: 1, # 'Ф' + 55: 1, # 'Ð¥' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 1, # 'Ы' + 61: 0, # 'Ь' + 47: 1, # 'Э' + 59: 0, # 'Ю' + 43: 1, # 'Я' + 3: 3, # 'а' + 21: 0, # 'б' + 10: 0, # 'в' + 19: 1, # 'г' + 13: 0, # 'д' + 2: 2, # 'е' + 24: 0, # 'ж' + 20: 0, # 'з' + 4: 3, # 'и' + 23: 0, # 'й' + 11: 0, # 'к' + 8: 1, # 'л' + 12: 1, # 'м' + 5: 2, # 'н' + 1: 3, # 'о' + 15: 0, # 'п' + 9: 1, # 'Ñ€' + 7: 1, # 'Ñ' + 6: 0, # 'Ñ‚' + 14: 2, # 'у' + 39: 0, # 'Ñ„' + 26: 0, # 'Ñ…' + 28: 0, # 'ц' + 22: 0, # 'ч' + 25: 0, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ÑŠ' + 18: 3, # 'Ñ‹' + 17: 1, # 'ÑŒ' + 30: 2, # 'Ñ' + 27: 1, # 'ÑŽ' + 16: 1, # 'Ñ' + }, + 31: { # 'Ð' + 37: 2, # 'Ð' + 44: 0, # 'Б' + 33: 0, # 'Ð’' + 46: 1, # 'Г' + 41: 1, # 'Д' + 48: 1, # 'Е' + 56: 0, # 'Ж' + 51: 1, # 'З' + 42: 2, # 'И' + 60: 0, # 'Й' + 36: 1, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 1, # 'Ð' + 34: 1, # 'О' + 35: 0, # 'П' + 45: 1, # 'Р' + 32: 1, # 'С' + 40: 1, # 'Т' + 52: 1, # 'У' + 53: 1, # 'Ф' + 55: 1, # 'Ð¥' + 58: 1, # 'Ц' + 50: 1, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 1, # 'Ы' + 61: 1, # 'Ь' + 47: 1, # 'Э' + 59: 0, # 'Ю' + 43: 1, # 'Я' + 3: 3, # 'а' + 21: 0, # 'б' + 10: 0, # 'в' + 19: 0, # 'г' + 13: 0, # 'д' + 2: 3, # 'е' + 24: 0, # 'ж' + 20: 0, # 'з' + 4: 3, # 'и' + 23: 0, # 'й' + 11: 0, # 'к' + 8: 0, # 'л' + 12: 0, # 'м' + 5: 0, # 'н' + 1: 3, # 'о' + 15: 0, # 'п' + 9: 1, # 'Ñ€' + 7: 0, # 'Ñ' + 6: 0, # 'Ñ‚' + 14: 3, # 'у' + 39: 0, # 'Ñ„' + 26: 1, # 'Ñ…' + 28: 0, # 'ц' + 22: 0, # 'ч' + 25: 0, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ÑŠ' + 18: 1, # 'Ñ‹' + 17: 2, # 'ÑŒ' + 30: 1, # 'Ñ' + 27: 1, # 'ÑŽ' + 16: 1, # 'Ñ' + }, + 34: { # 'О' + 37: 0, # 'Ð' + 44: 1, # 'Б' + 33: 1, # 'Ð’' + 46: 1, # 'Г' + 41: 2, # 'Д' + 48: 1, # 'Е' + 56: 1, # 'Ж' + 51: 1, # 'З' + 42: 1, # 'И' + 60: 1, # 'Й' + 36: 1, # 'К' + 49: 2, # 'Л' + 38: 1, # 'М' + 31: 2, # 'Ð' + 34: 1, # 'О' + 35: 1, # 'П' + 45: 2, # 'Р' + 32: 1, # 'С' + 40: 1, # 'Т' + 52: 1, # 'У' + 53: 1, # 'Ф' + 55: 1, # 'Ð¥' + 58: 0, # 'Ц' + 50: 1, # 'Ч' + 57: 1, # 'Ш' + 63: 1, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 1, # 'Я' + 3: 1, # 'а' + 21: 2, # 'б' + 10: 1, # 'в' + 19: 2, # 'г' + 13: 2, # 'д' + 2: 0, # 'е' + 24: 1, # 'ж' + 20: 1, # 'з' + 4: 0, # 'и' + 23: 1, # 'й' + 11: 2, # 'к' + 8: 2, # 'л' + 12: 1, # 'м' + 5: 3, # 'н' + 1: 0, # 'о' + 15: 2, # 'п' + 9: 2, # 'Ñ€' + 7: 2, # 'Ñ' + 6: 2, # 'Ñ‚' + 14: 1, # 'у' + 39: 1, # 'Ñ„' + 26: 2, # 'Ñ…' + 28: 1, # 'ц' + 22: 2, # 'ч' + 25: 2, # 'ш' + 29: 1, # 'щ' + 54: 0, # 'ÑŠ' + 18: 0, # 'Ñ‹' + 17: 0, # 'ÑŒ' + 30: 0, # 'Ñ' + 27: 0, # 'ÑŽ' + 16: 0, # 'Ñ' + }, + 35: { # 'П' + 37: 1, # 'Ð' + 44: 0, # 'Б' + 33: 0, # 'Ð’' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 1, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 1, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 1, # 'Л' + 38: 0, # 'М' + 31: 1, # 'Ð' + 34: 1, # 'О' + 35: 1, # 'П' + 45: 2, # 'Р' + 32: 1, # 'С' + 40: 1, # 'Т' + 52: 1, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Ð¥' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 1, # 'Ы' + 61: 1, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 1, # 'Я' + 3: 2, # 'а' + 21: 0, # 'б' + 10: 0, # 'в' + 19: 0, # 'г' + 13: 0, # 'д' + 2: 2, # 'е' + 24: 0, # 'ж' + 20: 0, # 'з' + 4: 2, # 'и' + 23: 0, # 'й' + 11: 0, # 'к' + 8: 2, # 'л' + 12: 0, # 'м' + 5: 1, # 'н' + 1: 3, # 'о' + 15: 0, # 'п' + 9: 3, # 'Ñ€' + 7: 1, # 'Ñ' + 6: 1, # 'Ñ‚' + 14: 2, # 'у' + 39: 1, # 'Ñ„' + 26: 0, # 'Ñ…' + 28: 0, # 'ц' + 22: 0, # 'ч' + 25: 1, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ÑŠ' + 18: 1, # 'Ñ‹' + 17: 2, # 'ÑŒ' + 30: 1, # 'Ñ' + 27: 0, # 'ÑŽ' + 16: 2, # 'Ñ' + }, + 45: { # 'Р' + 37: 2, # 'Ð' + 44: 1, # 'Б' + 33: 1, # 'Ð’' + 46: 1, # 'Г' + 41: 1, # 'Д' + 48: 2, # 'Е' + 56: 1, # 'Ж' + 51: 0, # 'З' + 42: 2, # 'И' + 60: 0, # 'Й' + 36: 1, # 'К' + 49: 1, # 'Л' + 38: 1, # 'М' + 31: 1, # 'Ð' + 34: 2, # 'О' + 35: 0, # 'П' + 45: 1, # 'Р' + 32: 1, # 'С' + 40: 1, # 'Т' + 52: 1, # 'У' + 53: 0, # 'Ф' + 55: 1, # 'Ð¥' + 58: 1, # 'Ц' + 50: 1, # 'Ч' + 57: 1, # 'Ш' + 63: 0, # 'Щ' + 62: 1, # 'Ы' + 61: 1, # 'Ь' + 47: 1, # 'Э' + 59: 1, # 'Ю' + 43: 1, # 'Я' + 3: 3, # 'а' + 21: 0, # 'б' + 10: 1, # 'в' + 19: 0, # 'г' + 13: 0, # 'д' + 2: 2, # 'е' + 24: 1, # 'ж' + 20: 0, # 'з' + 4: 2, # 'и' + 23: 0, # 'й' + 11: 0, # 'к' + 8: 0, # 'л' + 12: 0, # 'м' + 5: 0, # 'н' + 1: 3, # 'о' + 15: 0, # 'п' + 9: 1, # 'Ñ€' + 7: 0, # 'Ñ' + 6: 0, # 'Ñ‚' + 14: 2, # 'у' + 39: 0, # 'Ñ„' + 26: 0, # 'Ñ…' + 28: 0, # 'ц' + 22: 0, # 'ч' + 25: 0, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ÑŠ' + 18: 2, # 'Ñ‹' + 17: 0, # 'ÑŒ' + 30: 1, # 'Ñ' + 27: 1, # 'ÑŽ' + 16: 2, # 'Ñ' + }, + 32: { # 'С' + 37: 1, # 'Ð' + 44: 1, # 'Б' + 33: 1, # 'Ð’' + 46: 1, # 'Г' + 41: 1, # 'Д' + 48: 1, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 1, # 'И' + 60: 0, # 'Й' + 36: 1, # 'К' + 49: 1, # 'Л' + 38: 1, # 'М' + 31: 1, # 'Ð' + 34: 1, # 'О' + 35: 1, # 'П' + 45: 1, # 'Р' + 32: 1, # 'С' + 40: 2, # 'Т' + 52: 1, # 'У' + 53: 0, # 'Ф' + 55: 1, # 'Ð¥' + 58: 1, # 'Ц' + 50: 1, # 'Ч' + 57: 1, # 'Ш' + 63: 0, # 'Щ' + 62: 1, # 'Ы' + 61: 1, # 'Ь' + 47: 1, # 'Э' + 59: 1, # 'Ю' + 43: 1, # 'Я' + 3: 2, # 'а' + 21: 1, # 'б' + 10: 2, # 'в' + 19: 1, # 'г' + 13: 2, # 'д' + 2: 3, # 'е' + 24: 1, # 'ж' + 20: 1, # 'з' + 4: 2, # 'и' + 23: 0, # 'й' + 11: 2, # 'к' + 8: 2, # 'л' + 12: 2, # 'м' + 5: 2, # 'н' + 1: 2, # 'о' + 15: 2, # 'п' + 9: 2, # 'Ñ€' + 7: 1, # 'Ñ' + 6: 3, # 'Ñ‚' + 14: 2, # 'у' + 39: 1, # 'Ñ„' + 26: 1, # 'Ñ…' + 28: 1, # 'ц' + 22: 1, # 'ч' + 25: 0, # 'ш' + 29: 0, # 'щ' + 54: 1, # 'ÑŠ' + 18: 1, # 'Ñ‹' + 17: 1, # 'ÑŒ' + 30: 2, # 'Ñ' + 27: 1, # 'ÑŽ' + 16: 1, # 'Ñ' + }, + 40: { # 'Т' + 37: 1, # 'Ð' + 44: 0, # 'Б' + 33: 1, # 'Ð’' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 1, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 1, # 'И' + 60: 0, # 'Й' + 36: 1, # 'К' + 49: 1, # 'Л' + 38: 1, # 'М' + 31: 1, # 'Ð' + 34: 2, # 'О' + 35: 0, # 'П' + 45: 1, # 'Р' + 32: 1, # 'С' + 40: 1, # 'Т' + 52: 1, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Ð¥' + 58: 0, # 'Ц' + 50: 1, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 1, # 'Ы' + 61: 1, # 'Ь' + 47: 1, # 'Э' + 59: 1, # 'Ю' + 43: 1, # 'Я' + 3: 3, # 'а' + 21: 1, # 'б' + 10: 2, # 'в' + 19: 0, # 'г' + 13: 0, # 'д' + 2: 3, # 'е' + 24: 0, # 'ж' + 20: 0, # 'з' + 4: 2, # 'и' + 23: 0, # 'й' + 11: 1, # 'к' + 8: 1, # 'л' + 12: 0, # 'м' + 5: 0, # 'н' + 1: 3, # 'о' + 15: 0, # 'п' + 9: 2, # 'Ñ€' + 7: 1, # 'Ñ' + 6: 0, # 'Ñ‚' + 14: 2, # 'у' + 39: 0, # 'Ñ„' + 26: 0, # 'Ñ…' + 28: 0, # 'ц' + 22: 0, # 'ч' + 25: 0, # 'ш' + 29: 1, # 'щ' + 54: 0, # 'ÑŠ' + 18: 3, # 'Ñ‹' + 17: 1, # 'ÑŒ' + 30: 2, # 'Ñ' + 27: 1, # 'ÑŽ' + 16: 1, # 'Ñ' + }, + 52: { # 'У' + 37: 1, # 'Ð' + 44: 1, # 'Б' + 33: 1, # 'Ð’' + 46: 1, # 'Г' + 41: 1, # 'Д' + 48: 1, # 'Е' + 56: 1, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 1, # 'Й' + 36: 1, # 'К' + 49: 1, # 'Л' + 38: 1, # 'М' + 31: 1, # 'Ð' + 34: 1, # 'О' + 35: 1, # 'П' + 45: 1, # 'Р' + 32: 1, # 'С' + 40: 1, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 1, # 'Ð¥' + 58: 0, # 'Ц' + 50: 1, # 'Ч' + 57: 1, # 'Ш' + 63: 1, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 1, # 'Ю' + 43: 0, # 'Я' + 3: 1, # 'а' + 21: 2, # 'б' + 10: 2, # 'в' + 19: 1, # 'г' + 13: 2, # 'д' + 2: 1, # 'е' + 24: 2, # 'ж' + 20: 2, # 'з' + 4: 2, # 'и' + 23: 1, # 'й' + 11: 1, # 'к' + 8: 2, # 'л' + 12: 2, # 'м' + 5: 1, # 'н' + 1: 2, # 'о' + 15: 1, # 'п' + 9: 2, # 'Ñ€' + 7: 2, # 'Ñ' + 6: 2, # 'Ñ‚' + 14: 0, # 'у' + 39: 1, # 'Ñ„' + 26: 1, # 'Ñ…' + 28: 1, # 'ц' + 22: 2, # 'ч' + 25: 1, # 'ш' + 29: 1, # 'щ' + 54: 0, # 'ÑŠ' + 18: 0, # 'Ñ‹' + 17: 0, # 'ÑŒ' + 30: 2, # 'Ñ' + 27: 1, # 'ÑŽ' + 16: 0, # 'Ñ' + }, + 53: { # 'Ф' + 37: 1, # 'Ð' + 44: 1, # 'Б' + 33: 0, # 'Ð’' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 1, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 1, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 1, # 'Л' + 38: 0, # 'М' + 31: 0, # 'Ð' + 34: 1, # 'О' + 35: 0, # 'П' + 45: 1, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 1, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Ð¥' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 2, # 'а' + 21: 0, # 'б' + 10: 0, # 'в' + 19: 0, # 'г' + 13: 0, # 'д' + 2: 2, # 'е' + 24: 0, # 'ж' + 20: 0, # 'з' + 4: 2, # 'и' + 23: 0, # 'й' + 11: 0, # 'к' + 8: 2, # 'л' + 12: 0, # 'м' + 5: 0, # 'н' + 1: 2, # 'о' + 15: 0, # 'п' + 9: 2, # 'Ñ€' + 7: 0, # 'Ñ' + 6: 1, # 'Ñ‚' + 14: 2, # 'у' + 39: 0, # 'Ñ„' + 26: 0, # 'Ñ…' + 28: 0, # 'ц' + 22: 0, # 'ч' + 25: 0, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ÑŠ' + 18: 0, # 'Ñ‹' + 17: 1, # 'ÑŒ' + 30: 2, # 'Ñ' + 27: 0, # 'ÑŽ' + 16: 0, # 'Ñ' + }, + 55: { # 'Ð¥' + 37: 1, # 'Ð' + 44: 0, # 'Б' + 33: 1, # 'Ð’' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 1, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 1, # 'Л' + 38: 1, # 'М' + 31: 1, # 'Ð' + 34: 1, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Ð¥' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 2, # 'а' + 21: 0, # 'б' + 10: 2, # 'в' + 19: 0, # 'г' + 13: 0, # 'д' + 2: 2, # 'е' + 24: 0, # 'ж' + 20: 0, # 'з' + 4: 2, # 'и' + 23: 0, # 'й' + 11: 0, # 'к' + 8: 2, # 'л' + 12: 1, # 'м' + 5: 0, # 'н' + 1: 2, # 'о' + 15: 0, # 'п' + 9: 2, # 'Ñ€' + 7: 0, # 'Ñ' + 6: 0, # 'Ñ‚' + 14: 1, # 'у' + 39: 0, # 'Ñ„' + 26: 0, # 'Ñ…' + 28: 0, # 'ц' + 22: 0, # 'ч' + 25: 0, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ÑŠ' + 18: 0, # 'Ñ‹' + 17: 1, # 'ÑŒ' + 30: 1, # 'Ñ' + 27: 0, # 'ÑŽ' + 16: 0, # 'Ñ' + }, + 58: { # 'Ц' + 37: 1, # 'Ð' + 44: 0, # 'Б' + 33: 0, # 'Ð’' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 1, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 1, # 'И' + 60: 0, # 'Й' + 36: 1, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 0, # 'Ð' + 34: 1, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 1, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Ð¥' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 1, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 1, # 'а' + 21: 0, # 'б' + 10: 1, # 'в' + 19: 0, # 'г' + 13: 0, # 'д' + 2: 2, # 'е' + 24: 0, # 'ж' + 20: 0, # 'з' + 4: 2, # 'и' + 23: 0, # 'й' + 11: 0, # 'к' + 8: 0, # 'л' + 12: 0, # 'м' + 5: 0, # 'н' + 1: 0, # 'о' + 15: 0, # 'п' + 9: 0, # 'Ñ€' + 7: 0, # 'Ñ' + 6: 0, # 'Ñ‚' + 14: 1, # 'у' + 39: 0, # 'Ñ„' + 26: 0, # 'Ñ…' + 28: 0, # 'ц' + 22: 0, # 'ч' + 25: 0, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ÑŠ' + 18: 1, # 'Ñ‹' + 17: 0, # 'ÑŒ' + 30: 0, # 'Ñ' + 27: 1, # 'ÑŽ' + 16: 0, # 'Ñ' + }, + 50: { # 'Ч' + 37: 1, # 'Ð' + 44: 0, # 'Б' + 33: 0, # 'Ð’' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 1, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 1, # 'И' + 60: 0, # 'Й' + 36: 1, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 1, # 'Ð' + 34: 0, # 'О' + 35: 1, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 1, # 'Т' + 52: 1, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Ð¥' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 1, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 2, # 'а' + 21: 0, # 'б' + 10: 0, # 'в' + 19: 0, # 'г' + 13: 0, # 'д' + 2: 2, # 'е' + 24: 0, # 'ж' + 20: 0, # 'з' + 4: 2, # 'и' + 23: 0, # 'й' + 11: 0, # 'к' + 8: 1, # 'л' + 12: 0, # 'м' + 5: 0, # 'н' + 1: 1, # 'о' + 15: 0, # 'п' + 9: 1, # 'Ñ€' + 7: 0, # 'Ñ' + 6: 3, # 'Ñ‚' + 14: 2, # 'у' + 39: 0, # 'Ñ„' + 26: 0, # 'Ñ…' + 28: 0, # 'ц' + 22: 0, # 'ч' + 25: 0, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ÑŠ' + 18: 0, # 'Ñ‹' + 17: 1, # 'ÑŒ' + 30: 0, # 'Ñ' + 27: 0, # 'ÑŽ' + 16: 0, # 'Ñ' + }, + 57: { # 'Ш' + 37: 1, # 'Ð' + 44: 0, # 'Б' + 33: 0, # 'Ð’' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 1, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 1, # 'И' + 60: 0, # 'Й' + 36: 1, # 'К' + 49: 1, # 'Л' + 38: 0, # 'М' + 31: 1, # 'Ð' + 34: 1, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 1, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Ð¥' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 2, # 'а' + 21: 0, # 'б' + 10: 1, # 'в' + 19: 0, # 'г' + 13: 0, # 'д' + 2: 2, # 'е' + 24: 0, # 'ж' + 20: 0, # 'з' + 4: 1, # 'и' + 23: 0, # 'й' + 11: 1, # 'к' + 8: 2, # 'л' + 12: 1, # 'м' + 5: 1, # 'н' + 1: 2, # 'о' + 15: 2, # 'п' + 9: 1, # 'Ñ€' + 7: 0, # 'Ñ' + 6: 2, # 'Ñ‚' + 14: 2, # 'у' + 39: 0, # 'Ñ„' + 26: 1, # 'Ñ…' + 28: 0, # 'ц' + 22: 0, # 'ч' + 25: 1, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ÑŠ' + 18: 0, # 'Ñ‹' + 17: 0, # 'ÑŒ' + 30: 1, # 'Ñ' + 27: 0, # 'ÑŽ' + 16: 0, # 'Ñ' + }, + 63: { # 'Щ' + 37: 1, # 'Ð' + 44: 0, # 'Б' + 33: 0, # 'Ð’' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 1, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 1, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 0, # 'Ð' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Ð¥' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 1, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 1, # 'а' + 21: 0, # 'б' + 10: 0, # 'в' + 19: 0, # 'г' + 13: 0, # 'д' + 2: 1, # 'е' + 24: 0, # 'ж' + 20: 0, # 'з' + 4: 1, # 'и' + 23: 0, # 'й' + 11: 0, # 'к' + 8: 0, # 'л' + 12: 0, # 'м' + 5: 0, # 'н' + 1: 1, # 'о' + 15: 0, # 'п' + 9: 0, # 'Ñ€' + 7: 0, # 'Ñ' + 6: 0, # 'Ñ‚' + 14: 1, # 'у' + 39: 0, # 'Ñ„' + 26: 0, # 'Ñ…' + 28: 0, # 'ц' + 22: 0, # 'ч' + 25: 0, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ÑŠ' + 18: 0, # 'Ñ‹' + 17: 0, # 'ÑŒ' + 30: 0, # 'Ñ' + 27: 0, # 'ÑŽ' + 16: 0, # 'Ñ' + }, + 62: { # 'Ы' + 37: 0, # 'Ð' + 44: 0, # 'Б' + 33: 1, # 'Ð’' + 46: 1, # 'Г' + 41: 0, # 'Д' + 48: 1, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 1, # 'Й' + 36: 1, # 'К' + 49: 1, # 'Л' + 38: 1, # 'М' + 31: 1, # 'Ð' + 34: 0, # 'О' + 35: 1, # 'П' + 45: 1, # 'Р' + 32: 1, # 'С' + 40: 1, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 1, # 'Ð¥' + 58: 1, # 'Ц' + 50: 0, # 'Ч' + 57: 1, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 0, # 'а' + 21: 0, # 'б' + 10: 0, # 'в' + 19: 0, # 'г' + 13: 0, # 'д' + 2: 0, # 'е' + 24: 0, # 'ж' + 20: 0, # 'з' + 4: 0, # 'и' + 23: 0, # 'й' + 11: 0, # 'к' + 8: 0, # 'л' + 12: 0, # 'м' + 5: 0, # 'н' + 1: 0, # 'о' + 15: 0, # 'п' + 9: 0, # 'Ñ€' + 7: 0, # 'Ñ' + 6: 0, # 'Ñ‚' + 14: 0, # 'у' + 39: 0, # 'Ñ„' + 26: 0, # 'Ñ…' + 28: 0, # 'ц' + 22: 0, # 'ч' + 25: 0, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ÑŠ' + 18: 0, # 'Ñ‹' + 17: 0, # 'ÑŒ' + 30: 0, # 'Ñ' + 27: 0, # 'ÑŽ' + 16: 0, # 'Ñ' + }, + 61: { # 'Ь' + 37: 0, # 'Ð' + 44: 1, # 'Б' + 33: 1, # 'Ð’' + 46: 0, # 'Г' + 41: 1, # 'Д' + 48: 1, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 1, # 'И' + 60: 0, # 'Й' + 36: 1, # 'К' + 49: 0, # 'Л' + 38: 1, # 'М' + 31: 1, # 'Ð' + 34: 1, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 1, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 1, # 'Ф' + 55: 0, # 'Ð¥' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 1, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 1, # 'Ю' + 43: 1, # 'Я' + 3: 0, # 'а' + 21: 0, # 'б' + 10: 0, # 'в' + 19: 0, # 'г' + 13: 0, # 'д' + 2: 0, # 'е' + 24: 0, # 'ж' + 20: 0, # 'з' + 4: 0, # 'и' + 23: 0, # 'й' + 11: 0, # 'к' + 8: 0, # 'л' + 12: 0, # 'м' + 5: 0, # 'н' + 1: 0, # 'о' + 15: 0, # 'п' + 9: 0, # 'Ñ€' + 7: 0, # 'Ñ' + 6: 0, # 'Ñ‚' + 14: 0, # 'у' + 39: 0, # 'Ñ„' + 26: 0, # 'Ñ…' + 28: 0, # 'ц' + 22: 0, # 'ч' + 25: 0, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ÑŠ' + 18: 0, # 'Ñ‹' + 17: 0, # 'ÑŒ' + 30: 0, # 'Ñ' + 27: 0, # 'ÑŽ' + 16: 0, # 'Ñ' + }, + 47: { # 'Э' + 37: 0, # 'Ð' + 44: 0, # 'Б' + 33: 1, # 'Ð’' + 46: 0, # 'Г' + 41: 1, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 1, # 'Й' + 36: 1, # 'К' + 49: 1, # 'Л' + 38: 1, # 'М' + 31: 1, # 'Ð' + 34: 0, # 'О' + 35: 1, # 'П' + 45: 1, # 'Р' + 32: 1, # 'С' + 40: 1, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Ð¥' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 1, # 'а' + 21: 1, # 'б' + 10: 2, # 'в' + 19: 1, # 'г' + 13: 2, # 'д' + 2: 0, # 'е' + 24: 1, # 'ж' + 20: 0, # 'з' + 4: 0, # 'и' + 23: 2, # 'й' + 11: 2, # 'к' + 8: 2, # 'л' + 12: 2, # 'м' + 5: 2, # 'н' + 1: 0, # 'о' + 15: 1, # 'п' + 9: 2, # 'Ñ€' + 7: 1, # 'Ñ' + 6: 3, # 'Ñ‚' + 14: 1, # 'у' + 39: 1, # 'Ñ„' + 26: 1, # 'Ñ…' + 28: 0, # 'ц' + 22: 0, # 'ч' + 25: 1, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ÑŠ' + 18: 0, # 'Ñ‹' + 17: 0, # 'ÑŒ' + 30: 0, # 'Ñ' + 27: 0, # 'ÑŽ' + 16: 0, # 'Ñ' + }, + 59: { # 'Ю' + 37: 1, # 'Ð' + 44: 1, # 'Б' + 33: 0, # 'Ð’' + 46: 0, # 'Г' + 41: 1, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 1, # 'Ð' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 1, # 'Р' + 32: 0, # 'С' + 40: 1, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Ð¥' + 58: 0, # 'Ц' + 50: 1, # 'Ч' + 57: 0, # 'Ш' + 63: 1, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 0, # 'а' + 21: 1, # 'б' + 10: 0, # 'в' + 19: 1, # 'г' + 13: 1, # 'д' + 2: 0, # 'е' + 24: 1, # 'ж' + 20: 0, # 'з' + 4: 0, # 'и' + 23: 0, # 'й' + 11: 1, # 'к' + 8: 2, # 'л' + 12: 1, # 'м' + 5: 2, # 'н' + 1: 0, # 'о' + 15: 1, # 'п' + 9: 1, # 'Ñ€' + 7: 1, # 'Ñ' + 6: 0, # 'Ñ‚' + 14: 0, # 'у' + 39: 0, # 'Ñ„' + 26: 1, # 'Ñ…' + 28: 0, # 'ц' + 22: 0, # 'ч' + 25: 0, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ÑŠ' + 18: 0, # 'Ñ‹' + 17: 0, # 'ÑŒ' + 30: 0, # 'Ñ' + 27: 0, # 'ÑŽ' + 16: 0, # 'Ñ' + }, + 43: { # 'Я' + 37: 0, # 'Ð' + 44: 0, # 'Б' + 33: 1, # 'Ð’' + 46: 1, # 'Г' + 41: 0, # 'Д' + 48: 1, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 1, # 'И' + 60: 0, # 'Й' + 36: 1, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 1, # 'Ð' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 1, # 'С' + 40: 1, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 1, # 'Ð¥' + 58: 0, # 'Ц' + 50: 1, # 'Ч' + 57: 0, # 'Ш' + 63: 1, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 1, # 'Ю' + 43: 1, # 'Я' + 3: 0, # 'а' + 21: 1, # 'б' + 10: 1, # 'в' + 19: 1, # 'г' + 13: 1, # 'д' + 2: 0, # 'е' + 24: 0, # 'ж' + 20: 1, # 'з' + 4: 0, # 'и' + 23: 1, # 'й' + 11: 1, # 'к' + 8: 1, # 'л' + 12: 1, # 'м' + 5: 2, # 'н' + 1: 0, # 'о' + 15: 1, # 'п' + 9: 1, # 'Ñ€' + 7: 1, # 'Ñ' + 6: 0, # 'Ñ‚' + 14: 0, # 'у' + 39: 0, # 'Ñ„' + 26: 1, # 'Ñ…' + 28: 0, # 'ц' + 22: 0, # 'ч' + 25: 1, # 'ш' + 29: 1, # 'щ' + 54: 0, # 'ÑŠ' + 18: 0, # 'Ñ‹' + 17: 0, # 'ÑŒ' + 30: 0, # 'Ñ' + 27: 0, # 'ÑŽ' + 16: 0, # 'Ñ' + }, + 3: { # 'а' + 37: 0, # 'Ð' + 44: 0, # 'Б' + 33: 0, # 'Ð’' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 1, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 1, # 'Ð' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Ð¥' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 2, # 'а' + 21: 3, # 'б' + 10: 3, # 'в' + 19: 3, # 'г' + 13: 3, # 'д' + 2: 3, # 'е' + 24: 3, # 'ж' + 20: 3, # 'з' + 4: 3, # 'и' + 23: 3, # 'й' + 11: 3, # 'к' + 8: 3, # 'л' + 12: 3, # 'м' + 5: 3, # 'н' + 1: 2, # 'о' + 15: 3, # 'п' + 9: 3, # 'Ñ€' + 7: 3, # 'Ñ' + 6: 3, # 'Ñ‚' + 14: 3, # 'у' + 39: 2, # 'Ñ„' + 26: 3, # 'Ñ…' + 28: 3, # 'ц' + 22: 3, # 'ч' + 25: 3, # 'ш' + 29: 3, # 'щ' + 54: 0, # 'ÑŠ' + 18: 0, # 'Ñ‹' + 17: 0, # 'ÑŒ' + 30: 2, # 'Ñ' + 27: 3, # 'ÑŽ' + 16: 3, # 'Ñ' + }, + 21: { # 'б' + 37: 0, # 'Ð' + 44: 0, # 'Б' + 33: 0, # 'Ð’' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 1, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 0, # 'Ð' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Ð¥' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 3, # 'а' + 21: 2, # 'б' + 10: 2, # 'в' + 19: 1, # 'г' + 13: 2, # 'д' + 2: 3, # 'е' + 24: 2, # 'ж' + 20: 1, # 'з' + 4: 3, # 'и' + 23: 0, # 'й' + 11: 2, # 'к' + 8: 3, # 'л' + 12: 2, # 'м' + 5: 3, # 'н' + 1: 3, # 'о' + 15: 1, # 'п' + 9: 3, # 'Ñ€' + 7: 3, # 'Ñ' + 6: 2, # 'Ñ‚' + 14: 3, # 'у' + 39: 0, # 'Ñ„' + 26: 2, # 'Ñ…' + 28: 1, # 'ц' + 22: 1, # 'ч' + 25: 2, # 'ш' + 29: 3, # 'щ' + 54: 2, # 'ÑŠ' + 18: 3, # 'Ñ‹' + 17: 2, # 'ÑŒ' + 30: 1, # 'Ñ' + 27: 2, # 'ÑŽ' + 16: 3, # 'Ñ' + }, + 10: { # 'в' + 37: 0, # 'Ð' + 44: 0, # 'Б' + 33: 0, # 'Ð’' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 0, # 'Ð' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Ð¥' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 3, # 'а' + 21: 2, # 'б' + 10: 2, # 'в' + 19: 2, # 'г' + 13: 3, # 'д' + 2: 3, # 'е' + 24: 1, # 'ж' + 20: 3, # 'з' + 4: 3, # 'и' + 23: 0, # 'й' + 11: 3, # 'к' + 8: 3, # 'л' + 12: 2, # 'м' + 5: 3, # 'н' + 1: 3, # 'о' + 15: 3, # 'п' + 9: 3, # 'Ñ€' + 7: 3, # 'Ñ' + 6: 3, # 'Ñ‚' + 14: 3, # 'у' + 39: 1, # 'Ñ„' + 26: 2, # 'Ñ…' + 28: 2, # 'ц' + 22: 2, # 'ч' + 25: 3, # 'ш' + 29: 2, # 'щ' + 54: 2, # 'ÑŠ' + 18: 3, # 'Ñ‹' + 17: 3, # 'ÑŒ' + 30: 1, # 'Ñ' + 27: 1, # 'ÑŽ' + 16: 3, # 'Ñ' + }, + 19: { # 'г' + 37: 0, # 'Ð' + 44: 0, # 'Б' + 33: 0, # 'Ð’' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 0, # 'Ð' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Ð¥' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 3, # 'а' + 21: 1, # 'б' + 10: 2, # 'в' + 19: 1, # 'г' + 13: 3, # 'д' + 2: 3, # 'е' + 24: 0, # 'ж' + 20: 1, # 'з' + 4: 3, # 'и' + 23: 0, # 'й' + 11: 2, # 'к' + 8: 3, # 'л' + 12: 2, # 'м' + 5: 3, # 'н' + 1: 3, # 'о' + 15: 0, # 'п' + 9: 3, # 'Ñ€' + 7: 2, # 'Ñ' + 6: 2, # 'Ñ‚' + 14: 3, # 'у' + 39: 1, # 'Ñ„' + 26: 1, # 'Ñ…' + 28: 1, # 'ц' + 22: 2, # 'ч' + 25: 1, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ÑŠ' + 18: 1, # 'Ñ‹' + 17: 1, # 'ÑŒ' + 30: 1, # 'Ñ' + 27: 1, # 'ÑŽ' + 16: 0, # 'Ñ' + }, + 13: { # 'д' + 37: 0, # 'Ð' + 44: 0, # 'Б' + 33: 0, # 'Ð’' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 0, # 'Ð' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Ð¥' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 3, # 'а' + 21: 2, # 'б' + 10: 3, # 'в' + 19: 2, # 'г' + 13: 2, # 'д' + 2: 3, # 'е' + 24: 2, # 'ж' + 20: 2, # 'з' + 4: 3, # 'и' + 23: 0, # 'й' + 11: 3, # 'к' + 8: 3, # 'л' + 12: 2, # 'м' + 5: 3, # 'н' + 1: 3, # 'о' + 15: 2, # 'п' + 9: 3, # 'Ñ€' + 7: 3, # 'Ñ' + 6: 3, # 'Ñ‚' + 14: 3, # 'у' + 39: 1, # 'Ñ„' + 26: 2, # 'Ñ…' + 28: 3, # 'ц' + 22: 2, # 'ч' + 25: 2, # 'ш' + 29: 1, # 'щ' + 54: 2, # 'ÑŠ' + 18: 3, # 'Ñ‹' + 17: 3, # 'ÑŒ' + 30: 1, # 'Ñ' + 27: 2, # 'ÑŽ' + 16: 3, # 'Ñ' + }, + 2: { # 'е' + 37: 0, # 'Ð' + 44: 0, # 'Б' + 33: 0, # 'Ð’' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 0, # 'Ð' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Ð¥' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 2, # 'а' + 21: 3, # 'б' + 10: 3, # 'в' + 19: 3, # 'г' + 13: 3, # 'д' + 2: 3, # 'е' + 24: 3, # 'ж' + 20: 3, # 'з' + 4: 2, # 'и' + 23: 3, # 'й' + 11: 3, # 'к' + 8: 3, # 'л' + 12: 3, # 'м' + 5: 3, # 'н' + 1: 3, # 'о' + 15: 3, # 'п' + 9: 3, # 'Ñ€' + 7: 3, # 'Ñ' + 6: 3, # 'Ñ‚' + 14: 2, # 'у' + 39: 2, # 'Ñ„' + 26: 3, # 'Ñ…' + 28: 3, # 'ц' + 22: 3, # 'ч' + 25: 3, # 'ш' + 29: 3, # 'щ' + 54: 0, # 'ÑŠ' + 18: 0, # 'Ñ‹' + 17: 0, # 'ÑŒ' + 30: 1, # 'Ñ' + 27: 2, # 'ÑŽ' + 16: 3, # 'Ñ' + }, + 24: { # 'ж' + 37: 0, # 'Ð' + 44: 0, # 'Б' + 33: 0, # 'Ð’' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 0, # 'Ð' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Ð¥' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 3, # 'а' + 21: 2, # 'б' + 10: 1, # 'в' + 19: 2, # 'г' + 13: 3, # 'д' + 2: 3, # 'е' + 24: 2, # 'ж' + 20: 1, # 'з' + 4: 3, # 'и' + 23: 0, # 'й' + 11: 2, # 'к' + 8: 2, # 'л' + 12: 1, # 'м' + 5: 3, # 'н' + 1: 2, # 'о' + 15: 1, # 'п' + 9: 2, # 'Ñ€' + 7: 2, # 'Ñ' + 6: 1, # 'Ñ‚' + 14: 3, # 'у' + 39: 1, # 'Ñ„' + 26: 0, # 'Ñ…' + 28: 1, # 'ц' + 22: 2, # 'ч' + 25: 0, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ÑŠ' + 18: 1, # 'Ñ‹' + 17: 2, # 'ÑŒ' + 30: 1, # 'Ñ' + 27: 1, # 'ÑŽ' + 16: 1, # 'Ñ' + }, + 20: { # 'з' + 37: 0, # 'Ð' + 44: 0, # 'Б' + 33: 0, # 'Ð’' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 0, # 'Ð' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Ð¥' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 3, # 'а' + 21: 3, # 'б' + 10: 3, # 'в' + 19: 3, # 'г' + 13: 3, # 'д' + 2: 3, # 'е' + 24: 2, # 'ж' + 20: 2, # 'з' + 4: 3, # 'и' + 23: 0, # 'й' + 11: 3, # 'к' + 8: 3, # 'л' + 12: 3, # 'м' + 5: 3, # 'н' + 1: 3, # 'о' + 15: 0, # 'п' + 9: 3, # 'Ñ€' + 7: 2, # 'Ñ' + 6: 2, # 'Ñ‚' + 14: 3, # 'у' + 39: 0, # 'Ñ„' + 26: 0, # 'Ñ…' + 28: 1, # 'ц' + 22: 2, # 'ч' + 25: 1, # 'ш' + 29: 0, # 'щ' + 54: 2, # 'ÑŠ' + 18: 3, # 'Ñ‹' + 17: 2, # 'ÑŒ' + 30: 1, # 'Ñ' + 27: 1, # 'ÑŽ' + 16: 3, # 'Ñ' + }, + 4: { # 'и' + 37: 1, # 'Ð' + 44: 0, # 'Б' + 33: 0, # 'Ð’' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 1, # 'Ð' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Ð¥' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 3, # 'а' + 21: 3, # 'б' + 10: 3, # 'в' + 19: 3, # 'г' + 13: 3, # 'д' + 2: 3, # 'е' + 24: 3, # 'ж' + 20: 3, # 'з' + 4: 3, # 'и' + 23: 3, # 'й' + 11: 3, # 'к' + 8: 3, # 'л' + 12: 3, # 'м' + 5: 3, # 'н' + 1: 3, # 'о' + 15: 3, # 'п' + 9: 3, # 'Ñ€' + 7: 3, # 'Ñ' + 6: 3, # 'Ñ‚' + 14: 2, # 'у' + 39: 2, # 'Ñ„' + 26: 3, # 'Ñ…' + 28: 3, # 'ц' + 22: 3, # 'ч' + 25: 3, # 'ш' + 29: 3, # 'щ' + 54: 0, # 'ÑŠ' + 18: 0, # 'Ñ‹' + 17: 0, # 'ÑŒ' + 30: 2, # 'Ñ' + 27: 3, # 'ÑŽ' + 16: 3, # 'Ñ' + }, + 23: { # 'й' + 37: 0, # 'Ð' + 44: 0, # 'Б' + 33: 0, # 'Ð’' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 0, # 'Ð' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Ð¥' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 1, # 'а' + 21: 1, # 'б' + 10: 1, # 'в' + 19: 2, # 'г' + 13: 3, # 'д' + 2: 2, # 'е' + 24: 0, # 'ж' + 20: 2, # 'з' + 4: 1, # 'и' + 23: 0, # 'й' + 11: 2, # 'к' + 8: 2, # 'л' + 12: 2, # 'м' + 5: 3, # 'н' + 1: 2, # 'о' + 15: 1, # 'п' + 9: 2, # 'Ñ€' + 7: 3, # 'Ñ' + 6: 3, # 'Ñ‚' + 14: 1, # 'у' + 39: 2, # 'Ñ„' + 26: 1, # 'Ñ…' + 28: 2, # 'ц' + 22: 3, # 'ч' + 25: 2, # 'ш' + 29: 1, # 'щ' + 54: 0, # 'ÑŠ' + 18: 0, # 'Ñ‹' + 17: 0, # 'ÑŒ' + 30: 1, # 'Ñ' + 27: 1, # 'ÑŽ' + 16: 2, # 'Ñ' + }, + 11: { # 'к' + 37: 0, # 'Ð' + 44: 0, # 'Б' + 33: 0, # 'Ð’' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 0, # 'Ð' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Ð¥' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 3, # 'а' + 21: 1, # 'б' + 10: 3, # 'в' + 19: 1, # 'г' + 13: 1, # 'д' + 2: 3, # 'е' + 24: 2, # 'ж' + 20: 2, # 'з' + 4: 3, # 'и' + 23: 0, # 'й' + 11: 2, # 'к' + 8: 3, # 'л' + 12: 1, # 'м' + 5: 3, # 'н' + 1: 3, # 'о' + 15: 0, # 'п' + 9: 3, # 'Ñ€' + 7: 3, # 'Ñ' + 6: 3, # 'Ñ‚' + 14: 3, # 'у' + 39: 1, # 'Ñ„' + 26: 2, # 'Ñ…' + 28: 2, # 'ц' + 22: 1, # 'ч' + 25: 2, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ÑŠ' + 18: 1, # 'Ñ‹' + 17: 1, # 'ÑŒ' + 30: 1, # 'Ñ' + 27: 1, # 'ÑŽ' + 16: 1, # 'Ñ' + }, + 8: { # 'л' + 37: 0, # 'Ð' + 44: 0, # 'Б' + 33: 0, # 'Ð’' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 0, # 'Ð' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Ð¥' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 3, # 'а' + 21: 2, # 'б' + 10: 2, # 'в' + 19: 3, # 'г' + 13: 2, # 'д' + 2: 3, # 'е' + 24: 3, # 'ж' + 20: 2, # 'з' + 4: 3, # 'и' + 23: 0, # 'й' + 11: 3, # 'к' + 8: 3, # 'л' + 12: 2, # 'м' + 5: 3, # 'н' + 1: 3, # 'о' + 15: 2, # 'п' + 9: 1, # 'Ñ€' + 7: 3, # 'Ñ' + 6: 2, # 'Ñ‚' + 14: 3, # 'у' + 39: 2, # 'Ñ„' + 26: 2, # 'Ñ…' + 28: 1, # 'ц' + 22: 3, # 'ч' + 25: 2, # 'ш' + 29: 1, # 'щ' + 54: 0, # 'ÑŠ' + 18: 3, # 'Ñ‹' + 17: 3, # 'ÑŒ' + 30: 1, # 'Ñ' + 27: 3, # 'ÑŽ' + 16: 3, # 'Ñ' + }, + 12: { # 'м' + 37: 0, # 'Ð' + 44: 0, # 'Б' + 33: 0, # 'Ð’' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 0, # 'Ð' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Ð¥' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 3, # 'а' + 21: 2, # 'б' + 10: 2, # 'в' + 19: 2, # 'г' + 13: 1, # 'д' + 2: 3, # 'е' + 24: 1, # 'ж' + 20: 1, # 'з' + 4: 3, # 'и' + 23: 0, # 'й' + 11: 2, # 'к' + 8: 3, # 'л' + 12: 2, # 'м' + 5: 3, # 'н' + 1: 3, # 'о' + 15: 2, # 'п' + 9: 2, # 'Ñ€' + 7: 3, # 'Ñ' + 6: 2, # 'Ñ‚' + 14: 3, # 'у' + 39: 2, # 'Ñ„' + 26: 2, # 'Ñ…' + 28: 2, # 'ц' + 22: 2, # 'ч' + 25: 1, # 'ш' + 29: 1, # 'щ' + 54: 0, # 'ÑŠ' + 18: 3, # 'Ñ‹' + 17: 2, # 'ÑŒ' + 30: 2, # 'Ñ' + 27: 1, # 'ÑŽ' + 16: 3, # 'Ñ' + }, + 5: { # 'н' + 37: 0, # 'Ð' + 44: 0, # 'Б' + 33: 0, # 'Ð’' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 0, # 'Ð' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Ð¥' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 3, # 'а' + 21: 2, # 'б' + 10: 2, # 'в' + 19: 3, # 'г' + 13: 3, # 'д' + 2: 3, # 'е' + 24: 2, # 'ж' + 20: 2, # 'з' + 4: 3, # 'и' + 23: 0, # 'й' + 11: 3, # 'к' + 8: 2, # 'л' + 12: 1, # 'м' + 5: 3, # 'н' + 1: 3, # 'о' + 15: 1, # 'п' + 9: 2, # 'Ñ€' + 7: 3, # 'Ñ' + 6: 3, # 'Ñ‚' + 14: 3, # 'у' + 39: 2, # 'Ñ„' + 26: 2, # 'Ñ…' + 28: 3, # 'ц' + 22: 3, # 'ч' + 25: 2, # 'ш' + 29: 2, # 'щ' + 54: 1, # 'ÑŠ' + 18: 3, # 'Ñ‹' + 17: 3, # 'ÑŒ' + 30: 1, # 'Ñ' + 27: 3, # 'ÑŽ' + 16: 3, # 'Ñ' + }, + 1: { # 'о' + 37: 0, # 'Ð' + 44: 0, # 'Б' + 33: 0, # 'Ð’' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 0, # 'Ð' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Ð¥' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 2, # 'а' + 21: 3, # 'б' + 10: 3, # 'в' + 19: 3, # 'г' + 13: 3, # 'д' + 2: 3, # 'е' + 24: 3, # 'ж' + 20: 3, # 'з' + 4: 3, # 'и' + 23: 3, # 'й' + 11: 3, # 'к' + 8: 3, # 'л' + 12: 3, # 'м' + 5: 3, # 'н' + 1: 3, # 'о' + 15: 3, # 'п' + 9: 3, # 'Ñ€' + 7: 3, # 'Ñ' + 6: 3, # 'Ñ‚' + 14: 2, # 'у' + 39: 2, # 'Ñ„' + 26: 3, # 'Ñ…' + 28: 2, # 'ц' + 22: 3, # 'ч' + 25: 3, # 'ш' + 29: 3, # 'щ' + 54: 0, # 'ÑŠ' + 18: 0, # 'Ñ‹' + 17: 0, # 'ÑŒ' + 30: 2, # 'Ñ' + 27: 3, # 'ÑŽ' + 16: 3, # 'Ñ' + }, + 15: { # 'п' + 37: 0, # 'Ð' + 44: 0, # 'Б' + 33: 0, # 'Ð’' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 0, # 'Ð' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Ð¥' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 3, # 'а' + 21: 1, # 'б' + 10: 0, # 'в' + 19: 0, # 'г' + 13: 0, # 'д' + 2: 3, # 'е' + 24: 0, # 'ж' + 20: 0, # 'з' + 4: 3, # 'и' + 23: 0, # 'й' + 11: 2, # 'к' + 8: 3, # 'л' + 12: 1, # 'м' + 5: 3, # 'н' + 1: 3, # 'о' + 15: 2, # 'п' + 9: 3, # 'Ñ€' + 7: 2, # 'Ñ' + 6: 2, # 'Ñ‚' + 14: 3, # 'у' + 39: 1, # 'Ñ„' + 26: 0, # 'Ñ…' + 28: 2, # 'ц' + 22: 2, # 'ч' + 25: 1, # 'ш' + 29: 1, # 'щ' + 54: 0, # 'ÑŠ' + 18: 3, # 'Ñ‹' + 17: 2, # 'ÑŒ' + 30: 1, # 'Ñ' + 27: 1, # 'ÑŽ' + 16: 3, # 'Ñ' + }, + 9: { # 'Ñ€' + 37: 0, # 'Ð' + 44: 0, # 'Б' + 33: 0, # 'Ð’' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 0, # 'Ð' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Ð¥' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 3, # 'а' + 21: 2, # 'б' + 10: 3, # 'в' + 19: 3, # 'г' + 13: 3, # 'д' + 2: 3, # 'е' + 24: 3, # 'ж' + 20: 2, # 'з' + 4: 3, # 'и' + 23: 0, # 'й' + 11: 3, # 'к' + 8: 2, # 'л' + 12: 3, # 'м' + 5: 3, # 'н' + 1: 3, # 'о' + 15: 2, # 'п' + 9: 2, # 'Ñ€' + 7: 3, # 'Ñ' + 6: 3, # 'Ñ‚' + 14: 3, # 'у' + 39: 2, # 'Ñ„' + 26: 3, # 'Ñ…' + 28: 2, # 'ц' + 22: 2, # 'ч' + 25: 3, # 'ш' + 29: 2, # 'щ' + 54: 0, # 'ÑŠ' + 18: 3, # 'Ñ‹' + 17: 3, # 'ÑŒ' + 30: 2, # 'Ñ' + 27: 2, # 'ÑŽ' + 16: 3, # 'Ñ' + }, + 7: { # 'Ñ' + 37: 0, # 'Ð' + 44: 0, # 'Б' + 33: 0, # 'Ð’' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 1, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 0, # 'Ð' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Ð¥' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 3, # 'а' + 21: 2, # 'б' + 10: 3, # 'в' + 19: 2, # 'г' + 13: 3, # 'д' + 2: 3, # 'е' + 24: 2, # 'ж' + 20: 2, # 'з' + 4: 3, # 'и' + 23: 0, # 'й' + 11: 3, # 'к' + 8: 3, # 'л' + 12: 3, # 'м' + 5: 3, # 'н' + 1: 3, # 'о' + 15: 3, # 'п' + 9: 3, # 'Ñ€' + 7: 3, # 'Ñ' + 6: 3, # 'Ñ‚' + 14: 3, # 'у' + 39: 2, # 'Ñ„' + 26: 3, # 'Ñ…' + 28: 2, # 'ц' + 22: 3, # 'ч' + 25: 2, # 'ш' + 29: 1, # 'щ' + 54: 2, # 'ÑŠ' + 18: 3, # 'Ñ‹' + 17: 3, # 'ÑŒ' + 30: 2, # 'Ñ' + 27: 3, # 'ÑŽ' + 16: 3, # 'Ñ' + }, + 6: { # 'Ñ‚' + 37: 0, # 'Ð' + 44: 0, # 'Б' + 33: 0, # 'Ð’' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 0, # 'Ð' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Ð¥' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 3, # 'а' + 21: 2, # 'б' + 10: 3, # 'в' + 19: 2, # 'г' + 13: 2, # 'д' + 2: 3, # 'е' + 24: 1, # 'ж' + 20: 1, # 'з' + 4: 3, # 'и' + 23: 0, # 'й' + 11: 3, # 'к' + 8: 3, # 'л' + 12: 2, # 'м' + 5: 3, # 'н' + 1: 3, # 'о' + 15: 2, # 'п' + 9: 3, # 'Ñ€' + 7: 3, # 'Ñ' + 6: 2, # 'Ñ‚' + 14: 3, # 'у' + 39: 2, # 'Ñ„' + 26: 2, # 'Ñ…' + 28: 2, # 'ц' + 22: 2, # 'ч' + 25: 2, # 'ш' + 29: 2, # 'щ' + 54: 2, # 'ÑŠ' + 18: 3, # 'Ñ‹' + 17: 3, # 'ÑŒ' + 30: 2, # 'Ñ' + 27: 2, # 'ÑŽ' + 16: 3, # 'Ñ' + }, + 14: { # 'у' + 37: 0, # 'Ð' + 44: 0, # 'Б' + 33: 0, # 'Ð’' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 0, # 'Ð' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Ð¥' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 2, # 'а' + 21: 3, # 'б' + 10: 3, # 'в' + 19: 3, # 'г' + 13: 3, # 'д' + 2: 3, # 'е' + 24: 3, # 'ж' + 20: 3, # 'з' + 4: 2, # 'и' + 23: 2, # 'й' + 11: 3, # 'к' + 8: 3, # 'л' + 12: 3, # 'м' + 5: 3, # 'н' + 1: 2, # 'о' + 15: 3, # 'п' + 9: 3, # 'Ñ€' + 7: 3, # 'Ñ' + 6: 3, # 'Ñ‚' + 14: 1, # 'у' + 39: 2, # 'Ñ„' + 26: 3, # 'Ñ…' + 28: 2, # 'ц' + 22: 3, # 'ч' + 25: 3, # 'ш' + 29: 3, # 'щ' + 54: 0, # 'ÑŠ' + 18: 0, # 'Ñ‹' + 17: 0, # 'ÑŒ' + 30: 2, # 'Ñ' + 27: 3, # 'ÑŽ' + 16: 2, # 'Ñ' + }, + 39: { # 'Ñ„' + 37: 0, # 'Ð' + 44: 0, # 'Б' + 33: 0, # 'Ð’' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 0, # 'Ð' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Ð¥' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 3, # 'а' + 21: 1, # 'б' + 10: 0, # 'в' + 19: 1, # 'г' + 13: 0, # 'д' + 2: 3, # 'е' + 24: 0, # 'ж' + 20: 0, # 'з' + 4: 3, # 'и' + 23: 0, # 'й' + 11: 1, # 'к' + 8: 2, # 'л' + 12: 1, # 'м' + 5: 1, # 'н' + 1: 3, # 'о' + 15: 1, # 'п' + 9: 2, # 'Ñ€' + 7: 2, # 'Ñ' + 6: 2, # 'Ñ‚' + 14: 2, # 'у' + 39: 2, # 'Ñ„' + 26: 0, # 'Ñ…' + 28: 0, # 'ц' + 22: 1, # 'ч' + 25: 1, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ÑŠ' + 18: 2, # 'Ñ‹' + 17: 1, # 'ÑŒ' + 30: 2, # 'Ñ' + 27: 1, # 'ÑŽ' + 16: 1, # 'Ñ' + }, + 26: { # 'Ñ…' + 37: 0, # 'Ð' + 44: 0, # 'Б' + 33: 0, # 'Ð’' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 0, # 'Ð' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Ð¥' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 3, # 'а' + 21: 0, # 'б' + 10: 3, # 'в' + 19: 1, # 'г' + 13: 1, # 'д' + 2: 2, # 'е' + 24: 0, # 'ж' + 20: 1, # 'з' + 4: 3, # 'и' + 23: 0, # 'й' + 11: 1, # 'к' + 8: 2, # 'л' + 12: 2, # 'м' + 5: 3, # 'н' + 1: 3, # 'о' + 15: 1, # 'п' + 9: 3, # 'Ñ€' + 7: 2, # 'Ñ' + 6: 2, # 'Ñ‚' + 14: 2, # 'у' + 39: 1, # 'Ñ„' + 26: 1, # 'Ñ…' + 28: 1, # 'ц' + 22: 1, # 'ч' + 25: 2, # 'ш' + 29: 0, # 'щ' + 54: 1, # 'ÑŠ' + 18: 0, # 'Ñ‹' + 17: 1, # 'ÑŒ' + 30: 1, # 'Ñ' + 27: 1, # 'ÑŽ' + 16: 0, # 'Ñ' + }, + 28: { # 'ц' + 37: 0, # 'Ð' + 44: 0, # 'Б' + 33: 0, # 'Ð’' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 0, # 'Ð' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Ð¥' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 3, # 'а' + 21: 1, # 'б' + 10: 2, # 'в' + 19: 1, # 'г' + 13: 1, # 'д' + 2: 3, # 'е' + 24: 0, # 'ж' + 20: 1, # 'з' + 4: 3, # 'и' + 23: 0, # 'й' + 11: 2, # 'к' + 8: 1, # 'л' + 12: 1, # 'м' + 5: 1, # 'н' + 1: 3, # 'о' + 15: 0, # 'п' + 9: 1, # 'Ñ€' + 7: 0, # 'Ñ' + 6: 1, # 'Ñ‚' + 14: 3, # 'у' + 39: 0, # 'Ñ„' + 26: 0, # 'Ñ…' + 28: 1, # 'ц' + 22: 0, # 'ч' + 25: 1, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ÑŠ' + 18: 3, # 'Ñ‹' + 17: 1, # 'ÑŒ' + 30: 0, # 'Ñ' + 27: 1, # 'ÑŽ' + 16: 0, # 'Ñ' + }, + 22: { # 'ч' + 37: 0, # 'Ð' + 44: 0, # 'Б' + 33: 0, # 'Ð’' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 0, # 'Ð' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Ð¥' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 3, # 'а' + 21: 1, # 'б' + 10: 1, # 'в' + 19: 0, # 'г' + 13: 0, # 'д' + 2: 3, # 'е' + 24: 1, # 'ж' + 20: 0, # 'з' + 4: 3, # 'и' + 23: 0, # 'й' + 11: 3, # 'к' + 8: 2, # 'л' + 12: 1, # 'м' + 5: 3, # 'н' + 1: 2, # 'о' + 15: 0, # 'п' + 9: 2, # 'Ñ€' + 7: 1, # 'Ñ' + 6: 3, # 'Ñ‚' + 14: 3, # 'у' + 39: 1, # 'Ñ„' + 26: 1, # 'Ñ…' + 28: 0, # 'ц' + 22: 1, # 'ч' + 25: 2, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ÑŠ' + 18: 0, # 'Ñ‹' + 17: 3, # 'ÑŒ' + 30: 0, # 'Ñ' + 27: 0, # 'ÑŽ' + 16: 0, # 'Ñ' + }, + 25: { # 'ш' + 37: 0, # 'Ð' + 44: 0, # 'Б' + 33: 0, # 'Ð’' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 0, # 'Ð' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Ð¥' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 3, # 'а' + 21: 1, # 'б' + 10: 2, # 'в' + 19: 1, # 'г' + 13: 0, # 'д' + 2: 3, # 'е' + 24: 0, # 'ж' + 20: 0, # 'з' + 4: 3, # 'и' + 23: 0, # 'й' + 11: 3, # 'к' + 8: 3, # 'л' + 12: 2, # 'м' + 5: 3, # 'н' + 1: 3, # 'о' + 15: 2, # 'п' + 9: 2, # 'Ñ€' + 7: 1, # 'Ñ' + 6: 2, # 'Ñ‚' + 14: 3, # 'у' + 39: 2, # 'Ñ„' + 26: 1, # 'Ñ…' + 28: 1, # 'ц' + 22: 1, # 'ч' + 25: 1, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ÑŠ' + 18: 0, # 'Ñ‹' + 17: 3, # 'ÑŒ' + 30: 1, # 'Ñ' + 27: 1, # 'ÑŽ' + 16: 0, # 'Ñ' + }, + 29: { # 'щ' + 37: 0, # 'Ð' + 44: 0, # 'Б' + 33: 0, # 'Ð’' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 0, # 'Ð' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Ð¥' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 3, # 'а' + 21: 0, # 'б' + 10: 1, # 'в' + 19: 0, # 'г' + 13: 0, # 'д' + 2: 3, # 'е' + 24: 0, # 'ж' + 20: 0, # 'з' + 4: 3, # 'и' + 23: 0, # 'й' + 11: 0, # 'к' + 8: 0, # 'л' + 12: 1, # 'м' + 5: 2, # 'н' + 1: 1, # 'о' + 15: 0, # 'п' + 9: 2, # 'Ñ€' + 7: 0, # 'Ñ' + 6: 0, # 'Ñ‚' + 14: 2, # 'у' + 39: 0, # 'Ñ„' + 26: 0, # 'Ñ…' + 28: 0, # 'ц' + 22: 0, # 'ч' + 25: 0, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ÑŠ' + 18: 0, # 'Ñ‹' + 17: 2, # 'ÑŒ' + 30: 0, # 'Ñ' + 27: 0, # 'ÑŽ' + 16: 0, # 'Ñ' + }, + 54: { # 'ÑŠ' + 37: 0, # 'Ð' + 44: 0, # 'Б' + 33: 0, # 'Ð’' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 0, # 'Ð' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Ð¥' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 0, # 'а' + 21: 0, # 'б' + 10: 0, # 'в' + 19: 0, # 'г' + 13: 0, # 'д' + 2: 2, # 'е' + 24: 0, # 'ж' + 20: 0, # 'з' + 4: 0, # 'и' + 23: 0, # 'й' + 11: 0, # 'к' + 8: 0, # 'л' + 12: 0, # 'м' + 5: 0, # 'н' + 1: 0, # 'о' + 15: 0, # 'п' + 9: 0, # 'Ñ€' + 7: 0, # 'Ñ' + 6: 0, # 'Ñ‚' + 14: 0, # 'у' + 39: 0, # 'Ñ„' + 26: 0, # 'Ñ…' + 28: 0, # 'ц' + 22: 0, # 'ч' + 25: 0, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ÑŠ' + 18: 0, # 'Ñ‹' + 17: 0, # 'ÑŒ' + 30: 0, # 'Ñ' + 27: 1, # 'ÑŽ' + 16: 2, # 'Ñ' + }, + 18: { # 'Ñ‹' + 37: 0, # 'Ð' + 44: 0, # 'Б' + 33: 0, # 'Ð’' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 0, # 'Ð' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Ð¥' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 0, # 'а' + 21: 3, # 'б' + 10: 3, # 'в' + 19: 2, # 'г' + 13: 2, # 'д' + 2: 3, # 'е' + 24: 2, # 'ж' + 20: 2, # 'з' + 4: 2, # 'и' + 23: 3, # 'й' + 11: 3, # 'к' + 8: 3, # 'л' + 12: 3, # 'м' + 5: 3, # 'н' + 1: 1, # 'о' + 15: 3, # 'п' + 9: 3, # 'Ñ€' + 7: 3, # 'Ñ' + 6: 3, # 'Ñ‚' + 14: 1, # 'у' + 39: 0, # 'Ñ„' + 26: 3, # 'Ñ…' + 28: 2, # 'ц' + 22: 3, # 'ч' + 25: 3, # 'ш' + 29: 2, # 'щ' + 54: 0, # 'ÑŠ' + 18: 0, # 'Ñ‹' + 17: 0, # 'ÑŒ' + 30: 0, # 'Ñ' + 27: 0, # 'ÑŽ' + 16: 2, # 'Ñ' + }, + 17: { # 'ÑŒ' + 37: 0, # 'Ð' + 44: 0, # 'Б' + 33: 0, # 'Ð’' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 0, # 'Ð' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Ð¥' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 0, # 'а' + 21: 2, # 'б' + 10: 2, # 'в' + 19: 2, # 'г' + 13: 2, # 'д' + 2: 3, # 'е' + 24: 1, # 'ж' + 20: 3, # 'з' + 4: 2, # 'и' + 23: 0, # 'й' + 11: 3, # 'к' + 8: 0, # 'л' + 12: 3, # 'м' + 5: 3, # 'н' + 1: 2, # 'о' + 15: 2, # 'п' + 9: 1, # 'Ñ€' + 7: 3, # 'Ñ' + 6: 2, # 'Ñ‚' + 14: 0, # 'у' + 39: 2, # 'Ñ„' + 26: 1, # 'Ñ…' + 28: 2, # 'ц' + 22: 2, # 'ч' + 25: 3, # 'ш' + 29: 2, # 'щ' + 54: 0, # 'ÑŠ' + 18: 0, # 'Ñ‹' + 17: 0, # 'ÑŒ' + 30: 1, # 'Ñ' + 27: 3, # 'ÑŽ' + 16: 3, # 'Ñ' + }, + 30: { # 'Ñ' + 37: 0, # 'Ð' + 44: 0, # 'Б' + 33: 0, # 'Ð’' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 1, # 'М' + 31: 1, # 'Ð' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 1, # 'Р' + 32: 1, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 1, # 'Ф' + 55: 0, # 'Ð¥' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 0, # 'а' + 21: 1, # 'б' + 10: 1, # 'в' + 19: 1, # 'г' + 13: 2, # 'д' + 2: 1, # 'е' + 24: 0, # 'ж' + 20: 1, # 'з' + 4: 0, # 'и' + 23: 2, # 'й' + 11: 2, # 'к' + 8: 2, # 'л' + 12: 2, # 'м' + 5: 2, # 'н' + 1: 0, # 'о' + 15: 2, # 'п' + 9: 2, # 'Ñ€' + 7: 2, # 'Ñ' + 6: 3, # 'Ñ‚' + 14: 1, # 'у' + 39: 2, # 'Ñ„' + 26: 1, # 'Ñ…' + 28: 0, # 'ц' + 22: 0, # 'ч' + 25: 1, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ÑŠ' + 18: 0, # 'Ñ‹' + 17: 0, # 'ÑŒ' + 30: 1, # 'Ñ' + 27: 1, # 'ÑŽ' + 16: 1, # 'Ñ' + }, + 27: { # 'ÑŽ' + 37: 0, # 'Ð' + 44: 0, # 'Б' + 33: 0, # 'Ð’' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 0, # 'Ð' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Ð¥' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 2, # 'а' + 21: 3, # 'б' + 10: 1, # 'в' + 19: 2, # 'г' + 13: 3, # 'д' + 2: 1, # 'е' + 24: 2, # 'ж' + 20: 2, # 'з' + 4: 1, # 'и' + 23: 1, # 'й' + 11: 2, # 'к' + 8: 2, # 'л' + 12: 2, # 'м' + 5: 2, # 'н' + 1: 1, # 'о' + 15: 2, # 'п' + 9: 2, # 'Ñ€' + 7: 3, # 'Ñ' + 6: 3, # 'Ñ‚' + 14: 0, # 'у' + 39: 1, # 'Ñ„' + 26: 2, # 'Ñ…' + 28: 2, # 'ц' + 22: 2, # 'ч' + 25: 2, # 'ш' + 29: 3, # 'щ' + 54: 0, # 'ÑŠ' + 18: 0, # 'Ñ‹' + 17: 0, # 'ÑŒ' + 30: 1, # 'Ñ' + 27: 2, # 'ÑŽ' + 16: 1, # 'Ñ' + }, + 16: { # 'Ñ' + 37: 0, # 'Ð' + 44: 0, # 'Б' + 33: 0, # 'Ð’' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 0, # 'Ð' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Ð¥' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 0, # 'а' + 21: 2, # 'б' + 10: 3, # 'в' + 19: 2, # 'г' + 13: 3, # 'д' + 2: 3, # 'е' + 24: 3, # 'ж' + 20: 3, # 'з' + 4: 2, # 'и' + 23: 2, # 'й' + 11: 3, # 'к' + 8: 3, # 'л' + 12: 3, # 'м' + 5: 3, # 'н' + 1: 0, # 'о' + 15: 2, # 'п' + 9: 2, # 'Ñ€' + 7: 3, # 'Ñ' + 6: 3, # 'Ñ‚' + 14: 1, # 'у' + 39: 1, # 'Ñ„' + 26: 3, # 'Ñ…' + 28: 2, # 'ц' + 22: 2, # 'ч' + 25: 2, # 'ш' + 29: 3, # 'щ' + 54: 0, # 'ÑŠ' + 18: 0, # 'Ñ‹' + 17: 0, # 'ÑŒ' + 30: 0, # 'Ñ' + 27: 2, # 'ÑŽ' + 16: 2, # 'Ñ' + }, +} + +# 255: Undefined characters that did not exist in training text +# 254: Carriage/Return +# 253: symbol (punctuation) that does not belong to word +# 252: 0 - 9 +# 251: Control characters + +# Character Mapping Table(s): +IBM866_RUSSIAN_CHAR_TO_ORDER = { + 0: 255, # '\x00' + 1: 255, # '\x01' + 2: 255, # '\x02' + 3: 255, # '\x03' + 4: 255, # '\x04' + 5: 255, # '\x05' + 6: 255, # '\x06' + 7: 255, # '\x07' + 8: 255, # '\x08' + 9: 255, # '\t' + 10: 254, # '\n' + 11: 255, # '\x0b' + 12: 255, # '\x0c' + 13: 254, # '\r' + 14: 255, # '\x0e' + 15: 255, # '\x0f' + 16: 255, # '\x10' + 17: 255, # '\x11' + 18: 255, # '\x12' + 19: 255, # '\x13' + 20: 255, # '\x14' + 21: 255, # '\x15' + 22: 255, # '\x16' + 23: 255, # '\x17' + 24: 255, # '\x18' + 25: 255, # '\x19' + 26: 255, # '\x1a' + 27: 255, # '\x1b' + 28: 255, # '\x1c' + 29: 255, # '\x1d' + 30: 255, # '\x1e' + 31: 255, # '\x1f' + 32: 253, # ' ' + 33: 253, # '!' + 34: 253, # '"' + 35: 253, # '#' + 36: 253, # '$' + 37: 253, # '%' + 38: 253, # '&' + 39: 253, # "'" + 40: 253, # '(' + 41: 253, # ')' + 42: 253, # '*' + 43: 253, # '+' + 44: 253, # ',' + 45: 253, # '-' + 46: 253, # '.' + 47: 253, # '/' + 48: 252, # '0' + 49: 252, # '1' + 50: 252, # '2' + 51: 252, # '3' + 52: 252, # '4' + 53: 252, # '5' + 54: 252, # '6' + 55: 252, # '7' + 56: 252, # '8' + 57: 252, # '9' + 58: 253, # ':' + 59: 253, # ';' + 60: 253, # '<' + 61: 253, # '=' + 62: 253, # '>' + 63: 253, # '?' + 64: 253, # '@' + 65: 142, # 'A' + 66: 143, # 'B' + 67: 144, # 'C' + 68: 145, # 'D' + 69: 146, # 'E' + 70: 147, # 'F' + 71: 148, # 'G' + 72: 149, # 'H' + 73: 150, # 'I' + 74: 151, # 'J' + 75: 152, # 'K' + 76: 74, # 'L' + 77: 153, # 'M' + 78: 75, # 'N' + 79: 154, # 'O' + 80: 155, # 'P' + 81: 156, # 'Q' + 82: 157, # 'R' + 83: 158, # 'S' + 84: 159, # 'T' + 85: 160, # 'U' + 86: 161, # 'V' + 87: 162, # 'W' + 88: 163, # 'X' + 89: 164, # 'Y' + 90: 165, # 'Z' + 91: 253, # '[' + 92: 253, # '\\' + 93: 253, # ']' + 94: 253, # '^' + 95: 253, # '_' + 96: 253, # '`' + 97: 71, # 'a' + 98: 172, # 'b' + 99: 66, # 'c' + 100: 173, # 'd' + 101: 65, # 'e' + 102: 174, # 'f' + 103: 76, # 'g' + 104: 175, # 'h' + 105: 64, # 'i' + 106: 176, # 'j' + 107: 177, # 'k' + 108: 77, # 'l' + 109: 72, # 'm' + 110: 178, # 'n' + 111: 69, # 'o' + 112: 67, # 'p' + 113: 179, # 'q' + 114: 78, # 'r' + 115: 73, # 's' + 116: 180, # 't' + 117: 181, # 'u' + 118: 79, # 'v' + 119: 182, # 'w' + 120: 183, # 'x' + 121: 184, # 'y' + 122: 185, # 'z' + 123: 253, # '{' + 124: 253, # '|' + 125: 253, # '}' + 126: 253, # '~' + 127: 253, # '\x7f' + 128: 37, # 'Ð' + 129: 44, # 'Б' + 130: 33, # 'Ð’' + 131: 46, # 'Г' + 132: 41, # 'Д' + 133: 48, # 'Е' + 134: 56, # 'Ж' + 135: 51, # 'З' + 136: 42, # 'И' + 137: 60, # 'Й' + 138: 36, # 'К' + 139: 49, # 'Л' + 140: 38, # 'М' + 141: 31, # 'Ð' + 142: 34, # 'О' + 143: 35, # 'П' + 144: 45, # 'Р' + 145: 32, # 'С' + 146: 40, # 'Т' + 147: 52, # 'У' + 148: 53, # 'Ф' + 149: 55, # 'Ð¥' + 150: 58, # 'Ц' + 151: 50, # 'Ч' + 152: 57, # 'Ш' + 153: 63, # 'Щ' + 154: 70, # 'Ъ' + 155: 62, # 'Ы' + 156: 61, # 'Ь' + 157: 47, # 'Э' + 158: 59, # 'Ю' + 159: 43, # 'Я' + 160: 3, # 'а' + 161: 21, # 'б' + 162: 10, # 'в' + 163: 19, # 'г' + 164: 13, # 'д' + 165: 2, # 'е' + 166: 24, # 'ж' + 167: 20, # 'з' + 168: 4, # 'и' + 169: 23, # 'й' + 170: 11, # 'к' + 171: 8, # 'л' + 172: 12, # 'м' + 173: 5, # 'н' + 174: 1, # 'о' + 175: 15, # 'п' + 176: 191, # 'â–‘' + 177: 192, # 'â–’' + 178: 193, # 'â–“' + 179: 194, # '│' + 180: 195, # '┤' + 181: 196, # 'â•¡' + 182: 197, # 'â•¢' + 183: 198, # 'â•–' + 184: 199, # 'â••' + 185: 200, # 'â•£' + 186: 201, # 'â•‘' + 187: 202, # 'â•—' + 188: 203, # 'â•' + 189: 204, # '╜' + 190: 205, # 'â•›' + 191: 206, # 'â”' + 192: 207, # 'â””' + 193: 208, # 'â”´' + 194: 209, # '┬' + 195: 210, # '├' + 196: 211, # '─' + 197: 212, # '┼' + 198: 213, # '╞' + 199: 214, # '╟' + 200: 215, # '╚' + 201: 216, # 'â•”' + 202: 217, # 'â•©' + 203: 218, # '╦' + 204: 219, # 'â• ' + 205: 220, # 'â•' + 206: 221, # '╬' + 207: 222, # 'â•§' + 208: 223, # '╨' + 209: 224, # '╤' + 210: 225, # 'â•¥' + 211: 226, # 'â•™' + 212: 227, # '╘' + 213: 228, # 'â•’' + 214: 229, # 'â•“' + 215: 230, # 'â•«' + 216: 231, # '╪' + 217: 232, # '┘' + 218: 233, # '┌' + 219: 234, # 'â–ˆ' + 220: 235, # 'â–„' + 221: 236, # 'â–Œ' + 222: 237, # 'â–' + 223: 238, # 'â–€' + 224: 9, # 'Ñ€' + 225: 7, # 'Ñ' + 226: 6, # 'Ñ‚' + 227: 14, # 'у' + 228: 39, # 'Ñ„' + 229: 26, # 'Ñ…' + 230: 28, # 'ц' + 231: 22, # 'ч' + 232: 25, # 'ш' + 233: 29, # 'щ' + 234: 54, # 'ÑŠ' + 235: 18, # 'Ñ‹' + 236: 17, # 'ÑŒ' + 237: 30, # 'Ñ' + 238: 27, # 'ÑŽ' + 239: 16, # 'Ñ' + 240: 239, # 'Ð' + 241: 68, # 'Ñ‘' + 242: 240, # 'Є' + 243: 241, # 'Ñ”' + 244: 242, # 'Ї' + 245: 243, # 'Ñ—' + 246: 244, # 'ÐŽ' + 247: 245, # 'Ñž' + 248: 246, # '°' + 249: 247, # '∙' + 250: 248, # '·' + 251: 249, # '√' + 252: 250, # 'â„–' + 253: 251, # '¤' + 254: 252, # 'â– ' + 255: 255, # '\xa0' +} + +IBM866_RUSSIAN_MODEL = SingleByteCharSetModel(charset_name='IBM866', + language='Russian', + char_to_order_map=IBM866_RUSSIAN_CHAR_TO_ORDER, + language_model=RUSSIAN_LANG_MODEL, + typical_positive_ratio=0.976601, + keep_ascii_letters=False, + alphabet='ÐÐБВГДЕЖЗИЙКЛМÐОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрÑтуфхцчшщъыьÑÑŽÑÑ‘') + +WINDOWS_1251_RUSSIAN_CHAR_TO_ORDER = { + 0: 255, # '\x00' + 1: 255, # '\x01' + 2: 255, # '\x02' + 3: 255, # '\x03' + 4: 255, # '\x04' + 5: 255, # '\x05' + 6: 255, # '\x06' + 7: 255, # '\x07' + 8: 255, # '\x08' + 9: 255, # '\t' + 10: 254, # '\n' + 11: 255, # '\x0b' + 12: 255, # '\x0c' + 13: 254, # '\r' + 14: 255, # '\x0e' + 15: 255, # '\x0f' + 16: 255, # '\x10' + 17: 255, # '\x11' + 18: 255, # '\x12' + 19: 255, # '\x13' + 20: 255, # '\x14' + 21: 255, # '\x15' + 22: 255, # '\x16' + 23: 255, # '\x17' + 24: 255, # '\x18' + 25: 255, # '\x19' + 26: 255, # '\x1a' + 27: 255, # '\x1b' + 28: 255, # '\x1c' + 29: 255, # '\x1d' + 30: 255, # '\x1e' + 31: 255, # '\x1f' + 32: 253, # ' ' + 33: 253, # '!' + 34: 253, # '"' + 35: 253, # '#' + 36: 253, # '$' + 37: 253, # '%' + 38: 253, # '&' + 39: 253, # "'" + 40: 253, # '(' + 41: 253, # ')' + 42: 253, # '*' + 43: 253, # '+' + 44: 253, # ',' + 45: 253, # '-' + 46: 253, # '.' + 47: 253, # '/' + 48: 252, # '0' + 49: 252, # '1' + 50: 252, # '2' + 51: 252, # '3' + 52: 252, # '4' + 53: 252, # '5' + 54: 252, # '6' + 55: 252, # '7' + 56: 252, # '8' + 57: 252, # '9' + 58: 253, # ':' + 59: 253, # ';' + 60: 253, # '<' + 61: 253, # '=' + 62: 253, # '>' + 63: 253, # '?' + 64: 253, # '@' + 65: 142, # 'A' + 66: 143, # 'B' + 67: 144, # 'C' + 68: 145, # 'D' + 69: 146, # 'E' + 70: 147, # 'F' + 71: 148, # 'G' + 72: 149, # 'H' + 73: 150, # 'I' + 74: 151, # 'J' + 75: 152, # 'K' + 76: 74, # 'L' + 77: 153, # 'M' + 78: 75, # 'N' + 79: 154, # 'O' + 80: 155, # 'P' + 81: 156, # 'Q' + 82: 157, # 'R' + 83: 158, # 'S' + 84: 159, # 'T' + 85: 160, # 'U' + 86: 161, # 'V' + 87: 162, # 'W' + 88: 163, # 'X' + 89: 164, # 'Y' + 90: 165, # 'Z' + 91: 253, # '[' + 92: 253, # '\\' + 93: 253, # ']' + 94: 253, # '^' + 95: 253, # '_' + 96: 253, # '`' + 97: 71, # 'a' + 98: 172, # 'b' + 99: 66, # 'c' + 100: 173, # 'd' + 101: 65, # 'e' + 102: 174, # 'f' + 103: 76, # 'g' + 104: 175, # 'h' + 105: 64, # 'i' + 106: 176, # 'j' + 107: 177, # 'k' + 108: 77, # 'l' + 109: 72, # 'm' + 110: 178, # 'n' + 111: 69, # 'o' + 112: 67, # 'p' + 113: 179, # 'q' + 114: 78, # 'r' + 115: 73, # 's' + 116: 180, # 't' + 117: 181, # 'u' + 118: 79, # 'v' + 119: 182, # 'w' + 120: 183, # 'x' + 121: 184, # 'y' + 122: 185, # 'z' + 123: 253, # '{' + 124: 253, # '|' + 125: 253, # '}' + 126: 253, # '~' + 127: 253, # '\x7f' + 128: 191, # 'Ђ' + 129: 192, # 'Ѓ' + 130: 193, # '‚' + 131: 194, # 'Ñ“' + 132: 195, # '„' + 133: 196, # '…' + 134: 197, # '†' + 135: 198, # '‡' + 136: 199, # '€' + 137: 200, # '‰' + 138: 201, # 'Љ' + 139: 202, # '‹' + 140: 203, # 'Њ' + 141: 204, # 'ÐŒ' + 142: 205, # 'Ћ' + 143: 206, # 'Ð' + 144: 207, # 'Ñ’' + 145: 208, # '‘' + 146: 209, # '’' + 147: 210, # '“' + 148: 211, # 'â€' + 149: 212, # '•' + 150: 213, # '–' + 151: 214, # '—' + 152: 215, # None + 153: 216, # 'â„¢' + 154: 217, # 'Ñ™' + 155: 218, # '›' + 156: 219, # 'Ñš' + 157: 220, # 'Ñœ' + 158: 221, # 'Ñ›' + 159: 222, # 'ÑŸ' + 160: 223, # '\xa0' + 161: 224, # 'ÐŽ' + 162: 225, # 'Ñž' + 163: 226, # 'Ј' + 164: 227, # '¤' + 165: 228, # 'Ò' + 166: 229, # '¦' + 167: 230, # '§' + 168: 231, # 'Ð' + 169: 232, # '©' + 170: 233, # 'Є' + 171: 234, # '«' + 172: 235, # '¬' + 173: 236, # '\xad' + 174: 237, # '®' + 175: 238, # 'Ї' + 176: 239, # '°' + 177: 240, # '±' + 178: 241, # 'І' + 179: 242, # 'Ñ–' + 180: 243, # 'Ò‘' + 181: 244, # 'µ' + 182: 245, # '¶' + 183: 246, # '·' + 184: 68, # 'Ñ‘' + 185: 247, # 'â„–' + 186: 248, # 'Ñ”' + 187: 249, # '»' + 188: 250, # 'ј' + 189: 251, # 'Ð…' + 190: 252, # 'Ñ•' + 191: 253, # 'Ñ—' + 192: 37, # 'Ð' + 193: 44, # 'Б' + 194: 33, # 'Ð’' + 195: 46, # 'Г' + 196: 41, # 'Д' + 197: 48, # 'Е' + 198: 56, # 'Ж' + 199: 51, # 'З' + 200: 42, # 'И' + 201: 60, # 'Й' + 202: 36, # 'К' + 203: 49, # 'Л' + 204: 38, # 'М' + 205: 31, # 'Ð' + 206: 34, # 'О' + 207: 35, # 'П' + 208: 45, # 'Р' + 209: 32, # 'С' + 210: 40, # 'Т' + 211: 52, # 'У' + 212: 53, # 'Ф' + 213: 55, # 'Ð¥' + 214: 58, # 'Ц' + 215: 50, # 'Ч' + 216: 57, # 'Ш' + 217: 63, # 'Щ' + 218: 70, # 'Ъ' + 219: 62, # 'Ы' + 220: 61, # 'Ь' + 221: 47, # 'Э' + 222: 59, # 'Ю' + 223: 43, # 'Я' + 224: 3, # 'а' + 225: 21, # 'б' + 226: 10, # 'в' + 227: 19, # 'г' + 228: 13, # 'д' + 229: 2, # 'е' + 230: 24, # 'ж' + 231: 20, # 'з' + 232: 4, # 'и' + 233: 23, # 'й' + 234: 11, # 'к' + 235: 8, # 'л' + 236: 12, # 'м' + 237: 5, # 'н' + 238: 1, # 'о' + 239: 15, # 'п' + 240: 9, # 'Ñ€' + 241: 7, # 'Ñ' + 242: 6, # 'Ñ‚' + 243: 14, # 'у' + 244: 39, # 'Ñ„' + 245: 26, # 'Ñ…' + 246: 28, # 'ц' + 247: 22, # 'ч' + 248: 25, # 'ш' + 249: 29, # 'щ' + 250: 54, # 'ÑŠ' + 251: 18, # 'Ñ‹' + 252: 17, # 'ÑŒ' + 253: 30, # 'Ñ' + 254: 27, # 'ÑŽ' + 255: 16, # 'Ñ' +} + +WINDOWS_1251_RUSSIAN_MODEL = SingleByteCharSetModel(charset_name='windows-1251', + language='Russian', + char_to_order_map=WINDOWS_1251_RUSSIAN_CHAR_TO_ORDER, + language_model=RUSSIAN_LANG_MODEL, + typical_positive_ratio=0.976601, + keep_ascii_letters=False, + alphabet='ÐÐБВГДЕЖЗИЙКЛМÐОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрÑтуфхцчшщъыьÑÑŽÑÑ‘') + +IBM855_RUSSIAN_CHAR_TO_ORDER = { + 0: 255, # '\x00' + 1: 255, # '\x01' + 2: 255, # '\x02' + 3: 255, # '\x03' + 4: 255, # '\x04' + 5: 255, # '\x05' + 6: 255, # '\x06' + 7: 255, # '\x07' + 8: 255, # '\x08' + 9: 255, # '\t' + 10: 254, # '\n' + 11: 255, # '\x0b' + 12: 255, # '\x0c' + 13: 254, # '\r' + 14: 255, # '\x0e' + 15: 255, # '\x0f' + 16: 255, # '\x10' + 17: 255, # '\x11' + 18: 255, # '\x12' + 19: 255, # '\x13' + 20: 255, # '\x14' + 21: 255, # '\x15' + 22: 255, # '\x16' + 23: 255, # '\x17' + 24: 255, # '\x18' + 25: 255, # '\x19' + 26: 255, # '\x1a' + 27: 255, # '\x1b' + 28: 255, # '\x1c' + 29: 255, # '\x1d' + 30: 255, # '\x1e' + 31: 255, # '\x1f' + 32: 253, # ' ' + 33: 253, # '!' + 34: 253, # '"' + 35: 253, # '#' + 36: 253, # '$' + 37: 253, # '%' + 38: 253, # '&' + 39: 253, # "'" + 40: 253, # '(' + 41: 253, # ')' + 42: 253, # '*' + 43: 253, # '+' + 44: 253, # ',' + 45: 253, # '-' + 46: 253, # '.' + 47: 253, # '/' + 48: 252, # '0' + 49: 252, # '1' + 50: 252, # '2' + 51: 252, # '3' + 52: 252, # '4' + 53: 252, # '5' + 54: 252, # '6' + 55: 252, # '7' + 56: 252, # '8' + 57: 252, # '9' + 58: 253, # ':' + 59: 253, # ';' + 60: 253, # '<' + 61: 253, # '=' + 62: 253, # '>' + 63: 253, # '?' + 64: 253, # '@' + 65: 142, # 'A' + 66: 143, # 'B' + 67: 144, # 'C' + 68: 145, # 'D' + 69: 146, # 'E' + 70: 147, # 'F' + 71: 148, # 'G' + 72: 149, # 'H' + 73: 150, # 'I' + 74: 151, # 'J' + 75: 152, # 'K' + 76: 74, # 'L' + 77: 153, # 'M' + 78: 75, # 'N' + 79: 154, # 'O' + 80: 155, # 'P' + 81: 156, # 'Q' + 82: 157, # 'R' + 83: 158, # 'S' + 84: 159, # 'T' + 85: 160, # 'U' + 86: 161, # 'V' + 87: 162, # 'W' + 88: 163, # 'X' + 89: 164, # 'Y' + 90: 165, # 'Z' + 91: 253, # '[' + 92: 253, # '\\' + 93: 253, # ']' + 94: 253, # '^' + 95: 253, # '_' + 96: 253, # '`' + 97: 71, # 'a' + 98: 172, # 'b' + 99: 66, # 'c' + 100: 173, # 'd' + 101: 65, # 'e' + 102: 174, # 'f' + 103: 76, # 'g' + 104: 175, # 'h' + 105: 64, # 'i' + 106: 176, # 'j' + 107: 177, # 'k' + 108: 77, # 'l' + 109: 72, # 'm' + 110: 178, # 'n' + 111: 69, # 'o' + 112: 67, # 'p' + 113: 179, # 'q' + 114: 78, # 'r' + 115: 73, # 's' + 116: 180, # 't' + 117: 181, # 'u' + 118: 79, # 'v' + 119: 182, # 'w' + 120: 183, # 'x' + 121: 184, # 'y' + 122: 185, # 'z' + 123: 253, # '{' + 124: 253, # '|' + 125: 253, # '}' + 126: 253, # '~' + 127: 253, # '\x7f' + 128: 191, # 'Ñ’' + 129: 192, # 'Ђ' + 130: 193, # 'Ñ“' + 131: 194, # 'Ѓ' + 132: 68, # 'Ñ‘' + 133: 195, # 'Ð' + 134: 196, # 'Ñ”' + 135: 197, # 'Є' + 136: 198, # 'Ñ•' + 137: 199, # 'Ð…' + 138: 200, # 'Ñ–' + 139: 201, # 'І' + 140: 202, # 'Ñ—' + 141: 203, # 'Ї' + 142: 204, # 'ј' + 143: 205, # 'Ј' + 144: 206, # 'Ñ™' + 145: 207, # 'Љ' + 146: 208, # 'Ñš' + 147: 209, # 'Њ' + 148: 210, # 'Ñ›' + 149: 211, # 'Ћ' + 150: 212, # 'Ñœ' + 151: 213, # 'ÐŒ' + 152: 214, # 'Ñž' + 153: 215, # 'ÐŽ' + 154: 216, # 'ÑŸ' + 155: 217, # 'Ð' + 156: 27, # 'ÑŽ' + 157: 59, # 'Ю' + 158: 54, # 'ÑŠ' + 159: 70, # 'Ъ' + 160: 3, # 'а' + 161: 37, # 'Ð' + 162: 21, # 'б' + 163: 44, # 'Б' + 164: 28, # 'ц' + 165: 58, # 'Ц' + 166: 13, # 'д' + 167: 41, # 'Д' + 168: 2, # 'е' + 169: 48, # 'Е' + 170: 39, # 'Ñ„' + 171: 53, # 'Ф' + 172: 19, # 'г' + 173: 46, # 'Г' + 174: 218, # '«' + 175: 219, # '»' + 176: 220, # 'â–‘' + 177: 221, # 'â–’' + 178: 222, # 'â–“' + 179: 223, # '│' + 180: 224, # '┤' + 181: 26, # 'Ñ…' + 182: 55, # 'Ð¥' + 183: 4, # 'и' + 184: 42, # 'И' + 185: 225, # 'â•£' + 186: 226, # 'â•‘' + 187: 227, # 'â•—' + 188: 228, # 'â•' + 189: 23, # 'й' + 190: 60, # 'Й' + 191: 229, # 'â”' + 192: 230, # 'â””' + 193: 231, # 'â”´' + 194: 232, # '┬' + 195: 233, # '├' + 196: 234, # '─' + 197: 235, # '┼' + 198: 11, # 'к' + 199: 36, # 'К' + 200: 236, # '╚' + 201: 237, # 'â•”' + 202: 238, # 'â•©' + 203: 239, # '╦' + 204: 240, # 'â• ' + 205: 241, # 'â•' + 206: 242, # '╬' + 207: 243, # '¤' + 208: 8, # 'л' + 209: 49, # 'Л' + 210: 12, # 'м' + 211: 38, # 'М' + 212: 5, # 'н' + 213: 31, # 'Ð' + 214: 1, # 'о' + 215: 34, # 'О' + 216: 15, # 'п' + 217: 244, # '┘' + 218: 245, # '┌' + 219: 246, # 'â–ˆ' + 220: 247, # 'â–„' + 221: 35, # 'П' + 222: 16, # 'Ñ' + 223: 248, # 'â–€' + 224: 43, # 'Я' + 225: 9, # 'Ñ€' + 226: 45, # 'Р' + 227: 7, # 'Ñ' + 228: 32, # 'С' + 229: 6, # 'Ñ‚' + 230: 40, # 'Т' + 231: 14, # 'у' + 232: 52, # 'У' + 233: 24, # 'ж' + 234: 56, # 'Ж' + 235: 10, # 'в' + 236: 33, # 'Ð’' + 237: 17, # 'ÑŒ' + 238: 61, # 'Ь' + 239: 249, # 'â„–' + 240: 250, # '\xad' + 241: 18, # 'Ñ‹' + 242: 62, # 'Ы' + 243: 20, # 'з' + 244: 51, # 'З' + 245: 25, # 'ш' + 246: 57, # 'Ш' + 247: 30, # 'Ñ' + 248: 47, # 'Э' + 249: 29, # 'щ' + 250: 63, # 'Щ' + 251: 22, # 'ч' + 252: 50, # 'Ч' + 253: 251, # '§' + 254: 252, # 'â– ' + 255: 255, # '\xa0' +} + +IBM855_RUSSIAN_MODEL = SingleByteCharSetModel(charset_name='IBM855', + language='Russian', + char_to_order_map=IBM855_RUSSIAN_CHAR_TO_ORDER, + language_model=RUSSIAN_LANG_MODEL, + typical_positive_ratio=0.976601, + keep_ascii_letters=False, + alphabet='ÐÐБВГДЕЖЗИЙКЛМÐОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрÑтуфхцчшщъыьÑÑŽÑÑ‘') + +KOI8_R_RUSSIAN_CHAR_TO_ORDER = { + 0: 255, # '\x00' + 1: 255, # '\x01' + 2: 255, # '\x02' + 3: 255, # '\x03' + 4: 255, # '\x04' + 5: 255, # '\x05' + 6: 255, # '\x06' + 7: 255, # '\x07' + 8: 255, # '\x08' + 9: 255, # '\t' + 10: 254, # '\n' + 11: 255, # '\x0b' + 12: 255, # '\x0c' + 13: 254, # '\r' + 14: 255, # '\x0e' + 15: 255, # '\x0f' + 16: 255, # '\x10' + 17: 255, # '\x11' + 18: 255, # '\x12' + 19: 255, # '\x13' + 20: 255, # '\x14' + 21: 255, # '\x15' + 22: 255, # '\x16' + 23: 255, # '\x17' + 24: 255, # '\x18' + 25: 255, # '\x19' + 26: 255, # '\x1a' + 27: 255, # '\x1b' + 28: 255, # '\x1c' + 29: 255, # '\x1d' + 30: 255, # '\x1e' + 31: 255, # '\x1f' + 32: 253, # ' ' + 33: 253, # '!' + 34: 253, # '"' + 35: 253, # '#' + 36: 253, # '$' + 37: 253, # '%' + 38: 253, # '&' + 39: 253, # "'" + 40: 253, # '(' + 41: 253, # ')' + 42: 253, # '*' + 43: 253, # '+' + 44: 253, # ',' + 45: 253, # '-' + 46: 253, # '.' + 47: 253, # '/' + 48: 252, # '0' + 49: 252, # '1' + 50: 252, # '2' + 51: 252, # '3' + 52: 252, # '4' + 53: 252, # '5' + 54: 252, # '6' + 55: 252, # '7' + 56: 252, # '8' + 57: 252, # '9' + 58: 253, # ':' + 59: 253, # ';' + 60: 253, # '<' + 61: 253, # '=' + 62: 253, # '>' + 63: 253, # '?' + 64: 253, # '@' + 65: 142, # 'A' + 66: 143, # 'B' + 67: 144, # 'C' + 68: 145, # 'D' + 69: 146, # 'E' + 70: 147, # 'F' + 71: 148, # 'G' + 72: 149, # 'H' + 73: 150, # 'I' + 74: 151, # 'J' + 75: 152, # 'K' + 76: 74, # 'L' + 77: 153, # 'M' + 78: 75, # 'N' + 79: 154, # 'O' + 80: 155, # 'P' + 81: 156, # 'Q' + 82: 157, # 'R' + 83: 158, # 'S' + 84: 159, # 'T' + 85: 160, # 'U' + 86: 161, # 'V' + 87: 162, # 'W' + 88: 163, # 'X' + 89: 164, # 'Y' + 90: 165, # 'Z' + 91: 253, # '[' + 92: 253, # '\\' + 93: 253, # ']' + 94: 253, # '^' + 95: 253, # '_' + 96: 253, # '`' + 97: 71, # 'a' + 98: 172, # 'b' + 99: 66, # 'c' + 100: 173, # 'd' + 101: 65, # 'e' + 102: 174, # 'f' + 103: 76, # 'g' + 104: 175, # 'h' + 105: 64, # 'i' + 106: 176, # 'j' + 107: 177, # 'k' + 108: 77, # 'l' + 109: 72, # 'm' + 110: 178, # 'n' + 111: 69, # 'o' + 112: 67, # 'p' + 113: 179, # 'q' + 114: 78, # 'r' + 115: 73, # 's' + 116: 180, # 't' + 117: 181, # 'u' + 118: 79, # 'v' + 119: 182, # 'w' + 120: 183, # 'x' + 121: 184, # 'y' + 122: 185, # 'z' + 123: 253, # '{' + 124: 253, # '|' + 125: 253, # '}' + 126: 253, # '~' + 127: 253, # '\x7f' + 128: 191, # '─' + 129: 192, # '│' + 130: 193, # '┌' + 131: 194, # 'â”' + 132: 195, # 'â””' + 133: 196, # '┘' + 134: 197, # '├' + 135: 198, # '┤' + 136: 199, # '┬' + 137: 200, # 'â”´' + 138: 201, # '┼' + 139: 202, # 'â–€' + 140: 203, # 'â–„' + 141: 204, # 'â–ˆ' + 142: 205, # 'â–Œ' + 143: 206, # 'â–' + 144: 207, # 'â–‘' + 145: 208, # 'â–’' + 146: 209, # 'â–“' + 147: 210, # '⌠' + 148: 211, # 'â– ' + 149: 212, # '∙' + 150: 213, # '√' + 151: 214, # '≈' + 152: 215, # '≤' + 153: 216, # '≥' + 154: 217, # '\xa0' + 155: 218, # '⌡' + 156: 219, # '°' + 157: 220, # '²' + 158: 221, # '·' + 159: 222, # '÷' + 160: 223, # 'â•' + 161: 224, # 'â•‘' + 162: 225, # 'â•’' + 163: 68, # 'Ñ‘' + 164: 226, # 'â•“' + 165: 227, # 'â•”' + 166: 228, # 'â••' + 167: 229, # 'â•–' + 168: 230, # 'â•—' + 169: 231, # '╘' + 170: 232, # 'â•™' + 171: 233, # '╚' + 172: 234, # 'â•›' + 173: 235, # '╜' + 174: 236, # 'â•' + 175: 237, # '╞' + 176: 238, # '╟' + 177: 239, # 'â• ' + 178: 240, # 'â•¡' + 179: 241, # 'Ð' + 180: 242, # 'â•¢' + 181: 243, # 'â•£' + 182: 244, # '╤' + 183: 245, # 'â•¥' + 184: 246, # '╦' + 185: 247, # 'â•§' + 186: 248, # '╨' + 187: 249, # 'â•©' + 188: 250, # '╪' + 189: 251, # 'â•«' + 190: 252, # '╬' + 191: 253, # '©' + 192: 27, # 'ÑŽ' + 193: 3, # 'а' + 194: 21, # 'б' + 195: 28, # 'ц' + 196: 13, # 'д' + 197: 2, # 'е' + 198: 39, # 'Ñ„' + 199: 19, # 'г' + 200: 26, # 'Ñ…' + 201: 4, # 'и' + 202: 23, # 'й' + 203: 11, # 'к' + 204: 8, # 'л' + 205: 12, # 'м' + 206: 5, # 'н' + 207: 1, # 'о' + 208: 15, # 'п' + 209: 16, # 'Ñ' + 210: 9, # 'Ñ€' + 211: 7, # 'Ñ' + 212: 6, # 'Ñ‚' + 213: 14, # 'у' + 214: 24, # 'ж' + 215: 10, # 'в' + 216: 17, # 'ÑŒ' + 217: 18, # 'Ñ‹' + 218: 20, # 'з' + 219: 25, # 'ш' + 220: 30, # 'Ñ' + 221: 29, # 'щ' + 222: 22, # 'ч' + 223: 54, # 'ÑŠ' + 224: 59, # 'Ю' + 225: 37, # 'Ð' + 226: 44, # 'Б' + 227: 58, # 'Ц' + 228: 41, # 'Д' + 229: 48, # 'Е' + 230: 53, # 'Ф' + 231: 46, # 'Г' + 232: 55, # 'Ð¥' + 233: 42, # 'И' + 234: 60, # 'Й' + 235: 36, # 'К' + 236: 49, # 'Л' + 237: 38, # 'М' + 238: 31, # 'Ð' + 239: 34, # 'О' + 240: 35, # 'П' + 241: 43, # 'Я' + 242: 45, # 'Р' + 243: 32, # 'С' + 244: 40, # 'Т' + 245: 52, # 'У' + 246: 56, # 'Ж' + 247: 33, # 'Ð’' + 248: 61, # 'Ь' + 249: 62, # 'Ы' + 250: 51, # 'З' + 251: 57, # 'Ш' + 252: 47, # 'Э' + 253: 63, # 'Щ' + 254: 50, # 'Ч' + 255: 70, # 'Ъ' +} + +KOI8_R_RUSSIAN_MODEL = SingleByteCharSetModel(charset_name='KOI8-R', + language='Russian', + char_to_order_map=KOI8_R_RUSSIAN_CHAR_TO_ORDER, + language_model=RUSSIAN_LANG_MODEL, + typical_positive_ratio=0.976601, + keep_ascii_letters=False, + alphabet='ÐÐБВГДЕЖЗИЙКЛМÐОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрÑтуфхцчшщъыьÑÑŽÑÑ‘') + +MACCYRILLIC_RUSSIAN_CHAR_TO_ORDER = { + 0: 255, # '\x00' + 1: 255, # '\x01' + 2: 255, # '\x02' + 3: 255, # '\x03' + 4: 255, # '\x04' + 5: 255, # '\x05' + 6: 255, # '\x06' + 7: 255, # '\x07' + 8: 255, # '\x08' + 9: 255, # '\t' + 10: 254, # '\n' + 11: 255, # '\x0b' + 12: 255, # '\x0c' + 13: 254, # '\r' + 14: 255, # '\x0e' + 15: 255, # '\x0f' + 16: 255, # '\x10' + 17: 255, # '\x11' + 18: 255, # '\x12' + 19: 255, # '\x13' + 20: 255, # '\x14' + 21: 255, # '\x15' + 22: 255, # '\x16' + 23: 255, # '\x17' + 24: 255, # '\x18' + 25: 255, # '\x19' + 26: 255, # '\x1a' + 27: 255, # '\x1b' + 28: 255, # '\x1c' + 29: 255, # '\x1d' + 30: 255, # '\x1e' + 31: 255, # '\x1f' + 32: 253, # ' ' + 33: 253, # '!' + 34: 253, # '"' + 35: 253, # '#' + 36: 253, # '$' + 37: 253, # '%' + 38: 253, # '&' + 39: 253, # "'" + 40: 253, # '(' + 41: 253, # ')' + 42: 253, # '*' + 43: 253, # '+' + 44: 253, # ',' + 45: 253, # '-' + 46: 253, # '.' + 47: 253, # '/' + 48: 252, # '0' + 49: 252, # '1' + 50: 252, # '2' + 51: 252, # '3' + 52: 252, # '4' + 53: 252, # '5' + 54: 252, # '6' + 55: 252, # '7' + 56: 252, # '8' + 57: 252, # '9' + 58: 253, # ':' + 59: 253, # ';' + 60: 253, # '<' + 61: 253, # '=' + 62: 253, # '>' + 63: 253, # '?' + 64: 253, # '@' + 65: 142, # 'A' + 66: 143, # 'B' + 67: 144, # 'C' + 68: 145, # 'D' + 69: 146, # 'E' + 70: 147, # 'F' + 71: 148, # 'G' + 72: 149, # 'H' + 73: 150, # 'I' + 74: 151, # 'J' + 75: 152, # 'K' + 76: 74, # 'L' + 77: 153, # 'M' + 78: 75, # 'N' + 79: 154, # 'O' + 80: 155, # 'P' + 81: 156, # 'Q' + 82: 157, # 'R' + 83: 158, # 'S' + 84: 159, # 'T' + 85: 160, # 'U' + 86: 161, # 'V' + 87: 162, # 'W' + 88: 163, # 'X' + 89: 164, # 'Y' + 90: 165, # 'Z' + 91: 253, # '[' + 92: 253, # '\\' + 93: 253, # ']' + 94: 253, # '^' + 95: 253, # '_' + 96: 253, # '`' + 97: 71, # 'a' + 98: 172, # 'b' + 99: 66, # 'c' + 100: 173, # 'd' + 101: 65, # 'e' + 102: 174, # 'f' + 103: 76, # 'g' + 104: 175, # 'h' + 105: 64, # 'i' + 106: 176, # 'j' + 107: 177, # 'k' + 108: 77, # 'l' + 109: 72, # 'm' + 110: 178, # 'n' + 111: 69, # 'o' + 112: 67, # 'p' + 113: 179, # 'q' + 114: 78, # 'r' + 115: 73, # 's' + 116: 180, # 't' + 117: 181, # 'u' + 118: 79, # 'v' + 119: 182, # 'w' + 120: 183, # 'x' + 121: 184, # 'y' + 122: 185, # 'z' + 123: 253, # '{' + 124: 253, # '|' + 125: 253, # '}' + 126: 253, # '~' + 127: 253, # '\x7f' + 128: 37, # 'Ð' + 129: 44, # 'Б' + 130: 33, # 'Ð’' + 131: 46, # 'Г' + 132: 41, # 'Д' + 133: 48, # 'Е' + 134: 56, # 'Ж' + 135: 51, # 'З' + 136: 42, # 'И' + 137: 60, # 'Й' + 138: 36, # 'К' + 139: 49, # 'Л' + 140: 38, # 'М' + 141: 31, # 'Ð' + 142: 34, # 'О' + 143: 35, # 'П' + 144: 45, # 'Р' + 145: 32, # 'С' + 146: 40, # 'Т' + 147: 52, # 'У' + 148: 53, # 'Ф' + 149: 55, # 'Ð¥' + 150: 58, # 'Ц' + 151: 50, # 'Ч' + 152: 57, # 'Ш' + 153: 63, # 'Щ' + 154: 70, # 'Ъ' + 155: 62, # 'Ы' + 156: 61, # 'Ь' + 157: 47, # 'Э' + 158: 59, # 'Ю' + 159: 43, # 'Я' + 160: 191, # '†' + 161: 192, # '°' + 162: 193, # 'Ò' + 163: 194, # '£' + 164: 195, # '§' + 165: 196, # '•' + 166: 197, # '¶' + 167: 198, # 'І' + 168: 199, # '®' + 169: 200, # '©' + 170: 201, # 'â„¢' + 171: 202, # 'Ђ' + 172: 203, # 'Ñ’' + 173: 204, # '≠' + 174: 205, # 'Ѓ' + 175: 206, # 'Ñ“' + 176: 207, # '∞' + 177: 208, # '±' + 178: 209, # '≤' + 179: 210, # '≥' + 180: 211, # 'Ñ–' + 181: 212, # 'µ' + 182: 213, # 'Ò‘' + 183: 214, # 'Ј' + 184: 215, # 'Є' + 185: 216, # 'Ñ”' + 186: 217, # 'Ї' + 187: 218, # 'Ñ—' + 188: 219, # 'Љ' + 189: 220, # 'Ñ™' + 190: 221, # 'Њ' + 191: 222, # 'Ñš' + 192: 223, # 'ј' + 193: 224, # 'Ð…' + 194: 225, # '¬' + 195: 226, # '√' + 196: 227, # 'Æ’' + 197: 228, # '≈' + 198: 229, # '∆' + 199: 230, # '«' + 200: 231, # '»' + 201: 232, # '…' + 202: 233, # '\xa0' + 203: 234, # 'Ћ' + 204: 235, # 'Ñ›' + 205: 236, # 'ÐŒ' + 206: 237, # 'Ñœ' + 207: 238, # 'Ñ•' + 208: 239, # '–' + 209: 240, # '—' + 210: 241, # '“' + 211: 242, # 'â€' + 212: 243, # '‘' + 213: 244, # '’' + 214: 245, # '÷' + 215: 246, # '„' + 216: 247, # 'ÐŽ' + 217: 248, # 'Ñž' + 218: 249, # 'Ð' + 219: 250, # 'ÑŸ' + 220: 251, # 'â„–' + 221: 252, # 'Ð' + 222: 68, # 'Ñ‘' + 223: 16, # 'Ñ' + 224: 3, # 'а' + 225: 21, # 'б' + 226: 10, # 'в' + 227: 19, # 'г' + 228: 13, # 'д' + 229: 2, # 'е' + 230: 24, # 'ж' + 231: 20, # 'з' + 232: 4, # 'и' + 233: 23, # 'й' + 234: 11, # 'к' + 235: 8, # 'л' + 236: 12, # 'м' + 237: 5, # 'н' + 238: 1, # 'о' + 239: 15, # 'п' + 240: 9, # 'Ñ€' + 241: 7, # 'Ñ' + 242: 6, # 'Ñ‚' + 243: 14, # 'у' + 244: 39, # 'Ñ„' + 245: 26, # 'Ñ…' + 246: 28, # 'ц' + 247: 22, # 'ч' + 248: 25, # 'ш' + 249: 29, # 'щ' + 250: 54, # 'ÑŠ' + 251: 18, # 'Ñ‹' + 252: 17, # 'ÑŒ' + 253: 30, # 'Ñ' + 254: 27, # 'ÑŽ' + 255: 255, # '€' +} + +MACCYRILLIC_RUSSIAN_MODEL = SingleByteCharSetModel(charset_name='MacCyrillic', + language='Russian', + char_to_order_map=MACCYRILLIC_RUSSIAN_CHAR_TO_ORDER, + language_model=RUSSIAN_LANG_MODEL, + typical_positive_ratio=0.976601, + keep_ascii_letters=False, + alphabet='ÐÐБВГДЕЖЗИЙКЛМÐОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрÑтуфхцчшщъыьÑÑŽÑÑ‘') + +ISO_8859_5_RUSSIAN_CHAR_TO_ORDER = { + 0: 255, # '\x00' + 1: 255, # '\x01' + 2: 255, # '\x02' + 3: 255, # '\x03' + 4: 255, # '\x04' + 5: 255, # '\x05' + 6: 255, # '\x06' + 7: 255, # '\x07' + 8: 255, # '\x08' + 9: 255, # '\t' + 10: 254, # '\n' + 11: 255, # '\x0b' + 12: 255, # '\x0c' + 13: 254, # '\r' + 14: 255, # '\x0e' + 15: 255, # '\x0f' + 16: 255, # '\x10' + 17: 255, # '\x11' + 18: 255, # '\x12' + 19: 255, # '\x13' + 20: 255, # '\x14' + 21: 255, # '\x15' + 22: 255, # '\x16' + 23: 255, # '\x17' + 24: 255, # '\x18' + 25: 255, # '\x19' + 26: 255, # '\x1a' + 27: 255, # '\x1b' + 28: 255, # '\x1c' + 29: 255, # '\x1d' + 30: 255, # '\x1e' + 31: 255, # '\x1f' + 32: 253, # ' ' + 33: 253, # '!' + 34: 253, # '"' + 35: 253, # '#' + 36: 253, # '$' + 37: 253, # '%' + 38: 253, # '&' + 39: 253, # "'" + 40: 253, # '(' + 41: 253, # ')' + 42: 253, # '*' + 43: 253, # '+' + 44: 253, # ',' + 45: 253, # '-' + 46: 253, # '.' + 47: 253, # '/' + 48: 252, # '0' + 49: 252, # '1' + 50: 252, # '2' + 51: 252, # '3' + 52: 252, # '4' + 53: 252, # '5' + 54: 252, # '6' + 55: 252, # '7' + 56: 252, # '8' + 57: 252, # '9' + 58: 253, # ':' + 59: 253, # ';' + 60: 253, # '<' + 61: 253, # '=' + 62: 253, # '>' + 63: 253, # '?' + 64: 253, # '@' + 65: 142, # 'A' + 66: 143, # 'B' + 67: 144, # 'C' + 68: 145, # 'D' + 69: 146, # 'E' + 70: 147, # 'F' + 71: 148, # 'G' + 72: 149, # 'H' + 73: 150, # 'I' + 74: 151, # 'J' + 75: 152, # 'K' + 76: 74, # 'L' + 77: 153, # 'M' + 78: 75, # 'N' + 79: 154, # 'O' + 80: 155, # 'P' + 81: 156, # 'Q' + 82: 157, # 'R' + 83: 158, # 'S' + 84: 159, # 'T' + 85: 160, # 'U' + 86: 161, # 'V' + 87: 162, # 'W' + 88: 163, # 'X' + 89: 164, # 'Y' + 90: 165, # 'Z' + 91: 253, # '[' + 92: 253, # '\\' + 93: 253, # ']' + 94: 253, # '^' + 95: 253, # '_' + 96: 253, # '`' + 97: 71, # 'a' + 98: 172, # 'b' + 99: 66, # 'c' + 100: 173, # 'd' + 101: 65, # 'e' + 102: 174, # 'f' + 103: 76, # 'g' + 104: 175, # 'h' + 105: 64, # 'i' + 106: 176, # 'j' + 107: 177, # 'k' + 108: 77, # 'l' + 109: 72, # 'm' + 110: 178, # 'n' + 111: 69, # 'o' + 112: 67, # 'p' + 113: 179, # 'q' + 114: 78, # 'r' + 115: 73, # 's' + 116: 180, # 't' + 117: 181, # 'u' + 118: 79, # 'v' + 119: 182, # 'w' + 120: 183, # 'x' + 121: 184, # 'y' + 122: 185, # 'z' + 123: 253, # '{' + 124: 253, # '|' + 125: 253, # '}' + 126: 253, # '~' + 127: 253, # '\x7f' + 128: 191, # '\x80' + 129: 192, # '\x81' + 130: 193, # '\x82' + 131: 194, # '\x83' + 132: 195, # '\x84' + 133: 196, # '\x85' + 134: 197, # '\x86' + 135: 198, # '\x87' + 136: 199, # '\x88' + 137: 200, # '\x89' + 138: 201, # '\x8a' + 139: 202, # '\x8b' + 140: 203, # '\x8c' + 141: 204, # '\x8d' + 142: 205, # '\x8e' + 143: 206, # '\x8f' + 144: 207, # '\x90' + 145: 208, # '\x91' + 146: 209, # '\x92' + 147: 210, # '\x93' + 148: 211, # '\x94' + 149: 212, # '\x95' + 150: 213, # '\x96' + 151: 214, # '\x97' + 152: 215, # '\x98' + 153: 216, # '\x99' + 154: 217, # '\x9a' + 155: 218, # '\x9b' + 156: 219, # '\x9c' + 157: 220, # '\x9d' + 158: 221, # '\x9e' + 159: 222, # '\x9f' + 160: 223, # '\xa0' + 161: 224, # 'Ð' + 162: 225, # 'Ђ' + 163: 226, # 'Ѓ' + 164: 227, # 'Є' + 165: 228, # 'Ð…' + 166: 229, # 'І' + 167: 230, # 'Ї' + 168: 231, # 'Ј' + 169: 232, # 'Љ' + 170: 233, # 'Њ' + 171: 234, # 'Ћ' + 172: 235, # 'ÐŒ' + 173: 236, # '\xad' + 174: 237, # 'ÐŽ' + 175: 238, # 'Ð' + 176: 37, # 'Ð' + 177: 44, # 'Б' + 178: 33, # 'Ð’' + 179: 46, # 'Г' + 180: 41, # 'Д' + 181: 48, # 'Е' + 182: 56, # 'Ж' + 183: 51, # 'З' + 184: 42, # 'И' + 185: 60, # 'Й' + 186: 36, # 'К' + 187: 49, # 'Л' + 188: 38, # 'М' + 189: 31, # 'Ð' + 190: 34, # 'О' + 191: 35, # 'П' + 192: 45, # 'Р' + 193: 32, # 'С' + 194: 40, # 'Т' + 195: 52, # 'У' + 196: 53, # 'Ф' + 197: 55, # 'Ð¥' + 198: 58, # 'Ц' + 199: 50, # 'Ч' + 200: 57, # 'Ш' + 201: 63, # 'Щ' + 202: 70, # 'Ъ' + 203: 62, # 'Ы' + 204: 61, # 'Ь' + 205: 47, # 'Э' + 206: 59, # 'Ю' + 207: 43, # 'Я' + 208: 3, # 'а' + 209: 21, # 'б' + 210: 10, # 'в' + 211: 19, # 'г' + 212: 13, # 'д' + 213: 2, # 'е' + 214: 24, # 'ж' + 215: 20, # 'з' + 216: 4, # 'и' + 217: 23, # 'й' + 218: 11, # 'к' + 219: 8, # 'л' + 220: 12, # 'м' + 221: 5, # 'н' + 222: 1, # 'о' + 223: 15, # 'п' + 224: 9, # 'Ñ€' + 225: 7, # 'Ñ' + 226: 6, # 'Ñ‚' + 227: 14, # 'у' + 228: 39, # 'Ñ„' + 229: 26, # 'Ñ…' + 230: 28, # 'ц' + 231: 22, # 'ч' + 232: 25, # 'ш' + 233: 29, # 'щ' + 234: 54, # 'ÑŠ' + 235: 18, # 'Ñ‹' + 236: 17, # 'ÑŒ' + 237: 30, # 'Ñ' + 238: 27, # 'ÑŽ' + 239: 16, # 'Ñ' + 240: 239, # 'â„–' + 241: 68, # 'Ñ‘' + 242: 240, # 'Ñ’' + 243: 241, # 'Ñ“' + 244: 242, # 'Ñ”' + 245: 243, # 'Ñ•' + 246: 244, # 'Ñ–' + 247: 245, # 'Ñ—' + 248: 246, # 'ј' + 249: 247, # 'Ñ™' + 250: 248, # 'Ñš' + 251: 249, # 'Ñ›' + 252: 250, # 'Ñœ' + 253: 251, # '§' + 254: 252, # 'Ñž' + 255: 255, # 'ÑŸ' +} + +ISO_8859_5_RUSSIAN_MODEL = SingleByteCharSetModel(charset_name='ISO-8859-5', + language='Russian', + char_to_order_map=ISO_8859_5_RUSSIAN_CHAR_TO_ORDER, + language_model=RUSSIAN_LANG_MODEL, + typical_positive_ratio=0.976601, + keep_ascii_letters=False, + alphabet='ÐÐБВГДЕЖЗИЙКЛМÐОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрÑтуфхцчшщъыьÑÑŽÑÑ‘') + diff --git a/venv/Lib/site-packages/pip/_vendor/chardet/langthaimodel.py b/venv/Lib/site-packages/pip/_vendor/chardet/langthaimodel.py new file mode 100644 index 0000000..9a37db5 --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/chardet/langthaimodel.py @@ -0,0 +1,4383 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from pip._vendor.chardet.sbcharsetprober import SingleByteCharSetModel + + +# 3: Positive +# 2: Likely +# 1: Unlikely +# 0: Negative + +THAI_LANG_MODEL = { + 5: { # 'à¸' + 5: 2, # 'à¸' + 30: 2, # 'ข' + 24: 2, # 'ค' + 8: 2, # 'ง' + 26: 2, # 'จ' + 52: 0, # 'ฉ' + 34: 1, # 'ช' + 51: 1, # 'ซ' + 47: 0, # 'à¸' + 58: 3, # 'ฎ' + 57: 2, # 'à¸' + 49: 0, # 'à¸' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 2, # 'ณ' + 20: 2, # 'ด' + 19: 3, # 'ต' + 44: 0, # 'ถ' + 14: 2, # 'ท' + 48: 0, # 'ธ' + 3: 2, # 'น' + 17: 1, # 'บ' + 25: 2, # 'ป' + 39: 1, # 'ผ' + 62: 1, # 'à¸' + 31: 1, # 'พ' + 54: 0, # 'ฟ' + 45: 1, # 'ภ' + 9: 2, # 'ม' + 16: 1, # 'ย' + 2: 3, # 'ร' + 61: 2, # 'ฤ' + 15: 3, # 'ล' + 12: 3, # 'ว' + 42: 2, # 'ศ' + 46: 3, # 'ษ' + 18: 2, # 'ส' + 21: 2, # 'ห' + 4: 3, # 'อ' + 63: 1, # 'ฯ' + 22: 2, # 'ะ' + 10: 3, # 'ั' + 1: 3, # 'า' + 36: 3, # 'ำ' + 23: 3, # 'ิ' + 13: 3, # 'ี' + 40: 0, # 'ึ' + 27: 2, # 'ื' + 32: 2, # 'ุ' + 35: 1, # 'ู' + 11: 2, # 'เ' + 28: 2, # 'à¹' + 41: 1, # 'โ' + 29: 1, # 'ใ' + 33: 2, # 'ไ' + 50: 1, # 'ๆ' + 37: 3, # '็' + 6: 3, # '่' + 7: 3, # '้' + 38: 2, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 30: { # 'ข' + 5: 1, # 'à¸' + 30: 0, # 'ข' + 24: 1, # 'ค' + 8: 1, # 'ง' + 26: 1, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'à¸' + 58: 0, # 'ฎ' + 57: 0, # 'à¸' + 49: 0, # 'à¸' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 2, # 'ณ' + 20: 0, # 'ด' + 19: 2, # 'ต' + 44: 0, # 'ถ' + 14: 1, # 'ท' + 48: 0, # 'ธ' + 3: 2, # 'น' + 17: 1, # 'บ' + 25: 1, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'à¸' + 31: 0, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 0, # 'ม' + 16: 2, # 'ย' + 2: 1, # 'ร' + 61: 0, # 'ฤ' + 15: 0, # 'ล' + 12: 2, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 1, # 'ส' + 21: 1, # 'ห' + 4: 3, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 3, # 'ั' + 1: 3, # 'า' + 36: 0, # 'ำ' + 23: 0, # 'ิ' + 13: 2, # 'ี' + 40: 3, # 'ึ' + 27: 1, # 'ื' + 32: 1, # 'ุ' + 35: 0, # 'ู' + 11: 0, # 'เ' + 28: 0, # 'à¹' + 41: 0, # 'โ' + 29: 1, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 1, # '็' + 6: 2, # '่' + 7: 3, # '้' + 38: 1, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 24: { # 'ค' + 5: 0, # 'à¸' + 30: 0, # 'ข' + 24: 2, # 'ค' + 8: 2, # 'ง' + 26: 0, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'à¸' + 58: 0, # 'ฎ' + 57: 0, # 'à¸' + 49: 0, # 'à¸' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 2, # 'ณ' + 20: 2, # 'ด' + 19: 2, # 'ต' + 44: 0, # 'ถ' + 14: 1, # 'ท' + 48: 0, # 'ธ' + 3: 3, # 'น' + 17: 0, # 'บ' + 25: 1, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'à¸' + 31: 0, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 2, # 'ม' + 16: 2, # 'ย' + 2: 3, # 'ร' + 61: 0, # 'ฤ' + 15: 3, # 'ล' + 12: 3, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 1, # 'ส' + 21: 0, # 'ห' + 4: 2, # 'อ' + 63: 0, # 'ฯ' + 22: 2, # 'ะ' + 10: 3, # 'ั' + 1: 2, # 'า' + 36: 3, # 'ำ' + 23: 3, # 'ิ' + 13: 2, # 'ี' + 40: 0, # 'ึ' + 27: 3, # 'ื' + 32: 3, # 'ุ' + 35: 2, # 'ู' + 11: 1, # 'เ' + 28: 0, # 'à¹' + 41: 3, # 'โ' + 29: 0, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 1, # '็' + 6: 3, # '่' + 7: 3, # '้' + 38: 3, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 8: { # 'ง' + 5: 3, # 'à¸' + 30: 2, # 'ข' + 24: 3, # 'ค' + 8: 2, # 'ง' + 26: 2, # 'จ' + 52: 1, # 'ฉ' + 34: 2, # 'ช' + 51: 1, # 'ซ' + 47: 0, # 'à¸' + 58: 0, # 'ฎ' + 57: 0, # 'à¸' + 49: 0, # 'à¸' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 2, # 'ด' + 19: 2, # 'ต' + 44: 1, # 'ถ' + 14: 3, # 'ท' + 48: 1, # 'ธ' + 3: 3, # 'น' + 17: 2, # 'บ' + 25: 2, # 'ป' + 39: 2, # 'ผ' + 62: 1, # 'à¸' + 31: 2, # 'พ' + 54: 0, # 'ฟ' + 45: 1, # 'ภ' + 9: 2, # 'ม' + 16: 1, # 'ย' + 2: 2, # 'ร' + 61: 0, # 'ฤ' + 15: 2, # 'ล' + 12: 2, # 'ว' + 42: 2, # 'ศ' + 46: 1, # 'ษ' + 18: 3, # 'ส' + 21: 3, # 'ห' + 4: 2, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 1, # 'ั' + 1: 3, # 'า' + 36: 0, # 'ำ' + 23: 2, # 'ิ' + 13: 1, # 'ี' + 40: 0, # 'ึ' + 27: 1, # 'ื' + 32: 1, # 'ุ' + 35: 0, # 'ู' + 11: 3, # 'เ' + 28: 2, # 'à¹' + 41: 1, # 'โ' + 29: 2, # 'ใ' + 33: 2, # 'ไ' + 50: 3, # 'ๆ' + 37: 0, # '็' + 6: 2, # '่' + 7: 0, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 26: { # 'จ' + 5: 2, # 'à¸' + 30: 1, # 'ข' + 24: 0, # 'ค' + 8: 2, # 'ง' + 26: 3, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'à¸' + 58: 0, # 'ฎ' + 57: 0, # 'à¸' + 49: 0, # 'à¸' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 2, # 'ด' + 19: 1, # 'ต' + 44: 1, # 'ถ' + 14: 2, # 'ท' + 48: 0, # 'ธ' + 3: 3, # 'น' + 17: 1, # 'บ' + 25: 0, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'à¸' + 31: 1, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 1, # 'ม' + 16: 1, # 'ย' + 2: 3, # 'ร' + 61: 0, # 'ฤ' + 15: 0, # 'ล' + 12: 1, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 2, # 'ส' + 21: 1, # 'ห' + 4: 2, # 'อ' + 63: 0, # 'ฯ' + 22: 3, # 'ะ' + 10: 3, # 'ั' + 1: 3, # 'า' + 36: 3, # 'ำ' + 23: 2, # 'ิ' + 13: 1, # 'ี' + 40: 3, # 'ึ' + 27: 1, # 'ื' + 32: 3, # 'ุ' + 35: 2, # 'ู' + 11: 1, # 'เ' + 28: 1, # 'à¹' + 41: 0, # 'โ' + 29: 1, # 'ใ' + 33: 1, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 2, # '่' + 7: 2, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 52: { # 'ฉ' + 5: 0, # 'à¸' + 30: 0, # 'ข' + 24: 0, # 'ค' + 8: 0, # 'ง' + 26: 0, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'à¸' + 58: 0, # 'ฎ' + 57: 0, # 'à¸' + 49: 0, # 'à¸' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 0, # 'ด' + 19: 0, # 'ต' + 44: 0, # 'ถ' + 14: 0, # 'ท' + 48: 0, # 'ธ' + 3: 0, # 'น' + 17: 3, # 'บ' + 25: 0, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'à¸' + 31: 3, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 1, # 'ม' + 16: 1, # 'ย' + 2: 0, # 'ร' + 61: 0, # 'ฤ' + 15: 2, # 'ล' + 12: 1, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 0, # 'ส' + 21: 0, # 'ห' + 4: 0, # 'อ' + 63: 0, # 'ฯ' + 22: 1, # 'ะ' + 10: 1, # 'ั' + 1: 1, # 'า' + 36: 0, # 'ำ' + 23: 1, # 'ิ' + 13: 1, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 1, # 'ุ' + 35: 0, # 'ู' + 11: 0, # 'เ' + 28: 0, # 'à¹' + 41: 0, # 'โ' + 29: 0, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 0, # '่' + 7: 0, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 34: { # 'ช' + 5: 1, # 'à¸' + 30: 0, # 'ข' + 24: 0, # 'ค' + 8: 1, # 'ง' + 26: 0, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 1, # 'à¸' + 58: 0, # 'ฎ' + 57: 0, # 'à¸' + 49: 0, # 'à¸' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 0, # 'ด' + 19: 0, # 'ต' + 44: 0, # 'ถ' + 14: 1, # 'ท' + 48: 0, # 'ธ' + 3: 3, # 'น' + 17: 2, # 'บ' + 25: 0, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'à¸' + 31: 0, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 2, # 'ม' + 16: 1, # 'ย' + 2: 1, # 'ร' + 61: 0, # 'ฤ' + 15: 0, # 'ล' + 12: 1, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 0, # 'ส' + 21: 0, # 'ห' + 4: 2, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 2, # 'ั' + 1: 3, # 'า' + 36: 1, # 'ำ' + 23: 3, # 'ิ' + 13: 2, # 'ี' + 40: 0, # 'ึ' + 27: 3, # 'ื' + 32: 3, # 'ุ' + 35: 1, # 'ู' + 11: 0, # 'เ' + 28: 0, # 'à¹' + 41: 0, # 'โ' + 29: 0, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 1, # '็' + 6: 3, # '่' + 7: 3, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 51: { # 'ซ' + 5: 0, # 'à¸' + 30: 0, # 'ข' + 24: 0, # 'ค' + 8: 0, # 'ง' + 26: 0, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'à¸' + 58: 0, # 'ฎ' + 57: 0, # 'à¸' + 49: 0, # 'à¸' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 0, # 'ด' + 19: 0, # 'ต' + 44: 0, # 'ถ' + 14: 0, # 'ท' + 48: 0, # 'ธ' + 3: 1, # 'น' + 17: 0, # 'บ' + 25: 0, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'à¸' + 31: 0, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 0, # 'ม' + 16: 0, # 'ย' + 2: 0, # 'ร' + 61: 0, # 'ฤ' + 15: 1, # 'ล' + 12: 0, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 1, # 'ส' + 21: 0, # 'ห' + 4: 2, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 1, # 'ั' + 1: 1, # 'า' + 36: 0, # 'ำ' + 23: 1, # 'ิ' + 13: 2, # 'ี' + 40: 3, # 'ึ' + 27: 2, # 'ื' + 32: 1, # 'ุ' + 35: 1, # 'ู' + 11: 1, # 'เ' + 28: 0, # 'à¹' + 41: 0, # 'โ' + 29: 0, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 1, # '็' + 6: 1, # '่' + 7: 2, # '้' + 38: 1, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 47: { # 'à¸' + 5: 1, # 'à¸' + 30: 1, # 'ข' + 24: 0, # 'ค' + 8: 0, # 'ง' + 26: 0, # 'จ' + 52: 0, # 'ฉ' + 34: 1, # 'ช' + 51: 0, # 'ซ' + 47: 3, # 'à¸' + 58: 0, # 'ฎ' + 57: 0, # 'à¸' + 49: 0, # 'à¸' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 0, # 'ด' + 19: 0, # 'ต' + 44: 0, # 'ถ' + 14: 1, # 'ท' + 48: 0, # 'ธ' + 3: 0, # 'น' + 17: 1, # 'บ' + 25: 1, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'à¸' + 31: 0, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 1, # 'ม' + 16: 0, # 'ย' + 2: 0, # 'ร' + 61: 0, # 'ฤ' + 15: 1, # 'ล' + 12: 0, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 1, # 'ส' + 21: 2, # 'ห' + 4: 1, # 'อ' + 63: 0, # 'ฯ' + 22: 1, # 'ะ' + 10: 2, # 'ั' + 1: 3, # 'า' + 36: 0, # 'ำ' + 23: 1, # 'ิ' + 13: 1, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 1, # 'เ' + 28: 1, # 'à¹' + 41: 0, # 'โ' + 29: 1, # 'ใ' + 33: 0, # 'ไ' + 50: 1, # 'ๆ' + 37: 0, # '็' + 6: 2, # '่' + 7: 0, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 58: { # 'ฎ' + 5: 2, # 'à¸' + 30: 0, # 'ข' + 24: 0, # 'ค' + 8: 0, # 'ง' + 26: 0, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'à¸' + 58: 0, # 'ฎ' + 57: 0, # 'à¸' + 49: 0, # 'à¸' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 0, # 'ด' + 19: 0, # 'ต' + 44: 0, # 'ถ' + 14: 0, # 'ท' + 48: 0, # 'ธ' + 3: 0, # 'น' + 17: 0, # 'บ' + 25: 0, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'à¸' + 31: 0, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 0, # 'ม' + 16: 0, # 'ย' + 2: 0, # 'ร' + 61: 0, # 'ฤ' + 15: 0, # 'ล' + 12: 0, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 0, # 'ส' + 21: 1, # 'ห' + 4: 0, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 0, # 'ั' + 1: 0, # 'า' + 36: 0, # 'ำ' + 23: 1, # 'ิ' + 13: 2, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 0, # 'เ' + 28: 0, # 'à¹' + 41: 0, # 'โ' + 29: 0, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 0, # '่' + 7: 0, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 57: { # 'à¸' + 5: 0, # 'à¸' + 30: 0, # 'ข' + 24: 0, # 'ค' + 8: 0, # 'ง' + 26: 0, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'à¸' + 58: 0, # 'ฎ' + 57: 0, # 'à¸' + 49: 0, # 'à¸' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 0, # 'ด' + 19: 0, # 'ต' + 44: 0, # 'ถ' + 14: 0, # 'ท' + 48: 0, # 'ธ' + 3: 0, # 'น' + 17: 0, # 'บ' + 25: 0, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'à¸' + 31: 0, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 0, # 'ม' + 16: 0, # 'ย' + 2: 0, # 'ร' + 61: 0, # 'ฤ' + 15: 0, # 'ล' + 12: 0, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 0, # 'ส' + 21: 0, # 'ห' + 4: 0, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 0, # 'ั' + 1: 0, # 'า' + 36: 0, # 'ำ' + 23: 3, # 'ิ' + 13: 1, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 0, # 'เ' + 28: 0, # 'à¹' + 41: 0, # 'โ' + 29: 0, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 0, # '่' + 7: 0, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 49: { # 'à¸' + 5: 1, # 'à¸' + 30: 0, # 'ข' + 24: 0, # 'ค' + 8: 0, # 'ง' + 26: 0, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'à¸' + 58: 0, # 'ฎ' + 57: 0, # 'à¸' + 49: 0, # 'à¸' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 0, # 'ด' + 19: 0, # 'ต' + 44: 0, # 'ถ' + 14: 0, # 'ท' + 48: 0, # 'ธ' + 3: 0, # 'น' + 17: 2, # 'บ' + 25: 0, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'à¸' + 31: 0, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 2, # 'ม' + 16: 0, # 'ย' + 2: 0, # 'ร' + 61: 0, # 'ฤ' + 15: 0, # 'ล' + 12: 0, # 'ว' + 42: 1, # 'ศ' + 46: 0, # 'ษ' + 18: 0, # 'ส' + 21: 0, # 'ห' + 4: 1, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 0, # 'ั' + 1: 3, # 'า' + 36: 0, # 'ำ' + 23: 0, # 'ิ' + 13: 0, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 0, # 'เ' + 28: 0, # 'à¹' + 41: 0, # 'โ' + 29: 0, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 0, # '่' + 7: 0, # '้' + 38: 1, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 53: { # 'ฑ' + 5: 0, # 'à¸' + 30: 0, # 'ข' + 24: 0, # 'ค' + 8: 0, # 'ง' + 26: 0, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'à¸' + 58: 0, # 'ฎ' + 57: 0, # 'à¸' + 49: 0, # 'à¸' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 0, # 'ด' + 19: 0, # 'ต' + 44: 0, # 'ถ' + 14: 0, # 'ท' + 48: 0, # 'ธ' + 3: 0, # 'น' + 17: 0, # 'บ' + 25: 0, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'à¸' + 31: 0, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 0, # 'ม' + 16: 0, # 'ย' + 2: 0, # 'ร' + 61: 0, # 'ฤ' + 15: 0, # 'ล' + 12: 0, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 0, # 'ส' + 21: 0, # 'ห' + 4: 0, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 0, # 'ั' + 1: 0, # 'า' + 36: 0, # 'ำ' + 23: 2, # 'ิ' + 13: 0, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 0, # 'เ' + 28: 0, # 'à¹' + 41: 0, # 'โ' + 29: 0, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 0, # '่' + 7: 0, # '้' + 38: 3, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 55: { # 'ฒ' + 5: 0, # 'à¸' + 30: 0, # 'ข' + 24: 0, # 'ค' + 8: 0, # 'ง' + 26: 0, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'à¸' + 58: 0, # 'ฎ' + 57: 0, # 'à¸' + 49: 0, # 'à¸' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 0, # 'ด' + 19: 0, # 'ต' + 44: 0, # 'ถ' + 14: 0, # 'ท' + 48: 0, # 'ธ' + 3: 3, # 'น' + 17: 0, # 'บ' + 25: 0, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'à¸' + 31: 1, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 0, # 'ม' + 16: 0, # 'ย' + 2: 0, # 'ร' + 61: 0, # 'ฤ' + 15: 0, # 'ล' + 12: 0, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 0, # 'ส' + 21: 0, # 'ห' + 4: 0, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 0, # 'ั' + 1: 0, # 'า' + 36: 0, # 'ำ' + 23: 1, # 'ิ' + 13: 0, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 0, # 'เ' + 28: 0, # 'à¹' + 41: 0, # 'โ' + 29: 0, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 0, # '่' + 7: 0, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 43: { # 'ณ' + 5: 1, # 'à¸' + 30: 0, # 'ข' + 24: 0, # 'ค' + 8: 0, # 'ง' + 26: 0, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'à¸' + 58: 0, # 'ฎ' + 57: 0, # 'à¸' + 49: 0, # 'à¸' + 53: 3, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 0, # 'ด' + 19: 0, # 'ต' + 44: 0, # 'ถ' + 14: 0, # 'ท' + 48: 0, # 'ธ' + 3: 0, # 'น' + 17: 0, # 'บ' + 25: 0, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'à¸' + 31: 0, # 'พ' + 54: 0, # 'ฟ' + 45: 3, # 'ภ' + 9: 0, # 'ม' + 16: 0, # 'ย' + 2: 1, # 'ร' + 61: 0, # 'ฤ' + 15: 0, # 'ล' + 12: 1, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 1, # 'ส' + 21: 1, # 'ห' + 4: 0, # 'อ' + 63: 0, # 'ฯ' + 22: 3, # 'ะ' + 10: 0, # 'ั' + 1: 3, # 'า' + 36: 0, # 'ำ' + 23: 1, # 'ิ' + 13: 2, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 1, # 'เ' + 28: 1, # 'à¹' + 41: 0, # 'โ' + 29: 1, # 'ใ' + 33: 1, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 0, # '่' + 7: 0, # '้' + 38: 3, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 20: { # 'ด' + 5: 2, # 'à¸' + 30: 2, # 'ข' + 24: 2, # 'ค' + 8: 3, # 'ง' + 26: 2, # 'จ' + 52: 0, # 'ฉ' + 34: 1, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'à¸' + 58: 0, # 'ฎ' + 57: 0, # 'à¸' + 49: 0, # 'à¸' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 1, # 'ด' + 19: 2, # 'ต' + 44: 1, # 'ถ' + 14: 2, # 'ท' + 48: 0, # 'ธ' + 3: 1, # 'น' + 17: 1, # 'บ' + 25: 1, # 'ป' + 39: 1, # 'ผ' + 62: 0, # 'à¸' + 31: 1, # 'พ' + 54: 0, # 'ฟ' + 45: 1, # 'ภ' + 9: 2, # 'ม' + 16: 3, # 'ย' + 2: 2, # 'ร' + 61: 0, # 'ฤ' + 15: 2, # 'ล' + 12: 2, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 2, # 'ส' + 21: 2, # 'ห' + 4: 1, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 3, # 'ั' + 1: 2, # 'า' + 36: 2, # 'ำ' + 23: 3, # 'ิ' + 13: 3, # 'ี' + 40: 1, # 'ึ' + 27: 2, # 'ื' + 32: 3, # 'ุ' + 35: 2, # 'ู' + 11: 2, # 'เ' + 28: 2, # 'à¹' + 41: 1, # 'โ' + 29: 2, # 'ใ' + 33: 2, # 'ไ' + 50: 2, # 'ๆ' + 37: 2, # '็' + 6: 1, # '่' + 7: 3, # '้' + 38: 1, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 19: { # 'ต' + 5: 2, # 'à¸' + 30: 1, # 'ข' + 24: 1, # 'ค' + 8: 0, # 'ง' + 26: 1, # 'จ' + 52: 0, # 'ฉ' + 34: 1, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'à¸' + 58: 0, # 'ฎ' + 57: 0, # 'à¸' + 49: 0, # 'à¸' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 1, # 'ด' + 19: 1, # 'ต' + 44: 2, # 'ถ' + 14: 1, # 'ท' + 48: 0, # 'ธ' + 3: 2, # 'น' + 17: 1, # 'บ' + 25: 1, # 'ป' + 39: 1, # 'ผ' + 62: 0, # 'à¸' + 31: 1, # 'พ' + 54: 0, # 'ฟ' + 45: 2, # 'ภ' + 9: 1, # 'ม' + 16: 1, # 'ย' + 2: 3, # 'ร' + 61: 0, # 'ฤ' + 15: 2, # 'ล' + 12: 1, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 3, # 'ส' + 21: 0, # 'ห' + 4: 3, # 'อ' + 63: 1, # 'ฯ' + 22: 2, # 'ะ' + 10: 3, # 'ั' + 1: 3, # 'า' + 36: 2, # 'ำ' + 23: 3, # 'ิ' + 13: 2, # 'ี' + 40: 1, # 'ึ' + 27: 1, # 'ื' + 32: 3, # 'ุ' + 35: 2, # 'ู' + 11: 1, # 'เ' + 28: 1, # 'à¹' + 41: 1, # 'โ' + 29: 1, # 'ใ' + 33: 1, # 'ไ' + 50: 0, # 'ๆ' + 37: 2, # '็' + 6: 3, # '่' + 7: 3, # '้' + 38: 2, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 44: { # 'ถ' + 5: 1, # 'à¸' + 30: 0, # 'ข' + 24: 1, # 'ค' + 8: 0, # 'ง' + 26: 1, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'à¸' + 58: 0, # 'ฎ' + 57: 0, # 'à¸' + 49: 0, # 'à¸' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 0, # 'ด' + 19: 1, # 'ต' + 44: 0, # 'ถ' + 14: 1, # 'ท' + 48: 0, # 'ธ' + 3: 1, # 'น' + 17: 2, # 'บ' + 25: 0, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'à¸' + 31: 1, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 0, # 'ม' + 16: 0, # 'ย' + 2: 1, # 'ร' + 61: 0, # 'ฤ' + 15: 1, # 'ล' + 12: 1, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 1, # 'ส' + 21: 0, # 'ห' + 4: 1, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 2, # 'ั' + 1: 3, # 'า' + 36: 0, # 'ำ' + 23: 2, # 'ิ' + 13: 1, # 'ี' + 40: 3, # 'ึ' + 27: 2, # 'ื' + 32: 2, # 'ุ' + 35: 3, # 'ู' + 11: 1, # 'เ' + 28: 1, # 'à¹' + 41: 0, # 'โ' + 29: 1, # 'ใ' + 33: 1, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 2, # '่' + 7: 3, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 14: { # 'ท' + 5: 1, # 'à¸' + 30: 1, # 'ข' + 24: 3, # 'ค' + 8: 1, # 'ง' + 26: 1, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'à¸' + 58: 0, # 'ฎ' + 57: 0, # 'à¸' + 49: 0, # 'à¸' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 2, # 'ด' + 19: 1, # 'ต' + 44: 0, # 'ถ' + 14: 1, # 'ท' + 48: 3, # 'ธ' + 3: 3, # 'น' + 17: 2, # 'บ' + 25: 2, # 'ป' + 39: 1, # 'ผ' + 62: 0, # 'à¸' + 31: 2, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 1, # 'ม' + 16: 3, # 'ย' + 2: 3, # 'ร' + 61: 1, # 'ฤ' + 15: 1, # 'ล' + 12: 2, # 'ว' + 42: 3, # 'ศ' + 46: 1, # 'ษ' + 18: 1, # 'ส' + 21: 0, # 'ห' + 4: 2, # 'อ' + 63: 0, # 'ฯ' + 22: 2, # 'ะ' + 10: 3, # 'ั' + 1: 3, # 'า' + 36: 3, # 'ำ' + 23: 2, # 'ิ' + 13: 3, # 'ี' + 40: 2, # 'ึ' + 27: 1, # 'ื' + 32: 3, # 'ุ' + 35: 1, # 'ู' + 11: 0, # 'เ' + 28: 1, # 'à¹' + 41: 0, # 'โ' + 29: 1, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 1, # '็' + 6: 3, # '่' + 7: 3, # '้' + 38: 2, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 48: { # 'ธ' + 5: 0, # 'à¸' + 30: 0, # 'ข' + 24: 0, # 'ค' + 8: 1, # 'ง' + 26: 0, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'à¸' + 58: 0, # 'ฎ' + 57: 0, # 'à¸' + 49: 0, # 'à¸' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 0, # 'ด' + 19: 0, # 'ต' + 44: 0, # 'ถ' + 14: 0, # 'ท' + 48: 0, # 'ธ' + 3: 1, # 'น' + 17: 0, # 'บ' + 25: 0, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'à¸' + 31: 0, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 0, # 'ม' + 16: 0, # 'ย' + 2: 2, # 'ร' + 61: 0, # 'ฤ' + 15: 0, # 'ล' + 12: 0, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 0, # 'ส' + 21: 0, # 'ห' + 4: 0, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 0, # 'ั' + 1: 2, # 'า' + 36: 0, # 'ำ' + 23: 3, # 'ิ' + 13: 3, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 2, # 'ุ' + 35: 0, # 'ู' + 11: 0, # 'เ' + 28: 0, # 'à¹' + 41: 0, # 'โ' + 29: 0, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 0, # '่' + 7: 0, # '้' + 38: 3, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 3: { # 'น' + 5: 3, # 'à¸' + 30: 2, # 'ข' + 24: 3, # 'ค' + 8: 1, # 'ง' + 26: 2, # 'จ' + 52: 0, # 'ฉ' + 34: 1, # 'ช' + 51: 1, # 'ซ' + 47: 0, # 'à¸' + 58: 0, # 'ฎ' + 57: 0, # 'à¸' + 49: 1, # 'à¸' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 3, # 'ด' + 19: 3, # 'ต' + 44: 2, # 'ถ' + 14: 3, # 'ท' + 48: 3, # 'ธ' + 3: 2, # 'น' + 17: 2, # 'บ' + 25: 2, # 'ป' + 39: 2, # 'ผ' + 62: 0, # 'à¸' + 31: 2, # 'พ' + 54: 1, # 'ฟ' + 45: 1, # 'ภ' + 9: 2, # 'ม' + 16: 2, # 'ย' + 2: 2, # 'ร' + 61: 1, # 'ฤ' + 15: 2, # 'ล' + 12: 3, # 'ว' + 42: 1, # 'ศ' + 46: 0, # 'ษ' + 18: 2, # 'ส' + 21: 2, # 'ห' + 4: 3, # 'อ' + 63: 1, # 'ฯ' + 22: 2, # 'ะ' + 10: 3, # 'ั' + 1: 3, # 'า' + 36: 3, # 'ำ' + 23: 3, # 'ิ' + 13: 3, # 'ี' + 40: 3, # 'ึ' + 27: 3, # 'ื' + 32: 3, # 'ุ' + 35: 2, # 'ู' + 11: 3, # 'เ' + 28: 2, # 'à¹' + 41: 3, # 'โ' + 29: 3, # 'ใ' + 33: 3, # 'ไ' + 50: 2, # 'ๆ' + 37: 1, # '็' + 6: 3, # '่' + 7: 3, # '้' + 38: 2, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 17: { # 'บ' + 5: 3, # 'à¸' + 30: 2, # 'ข' + 24: 2, # 'ค' + 8: 1, # 'ง' + 26: 1, # 'จ' + 52: 1, # 'ฉ' + 34: 1, # 'ช' + 51: 1, # 'ซ' + 47: 0, # 'à¸' + 58: 0, # 'ฎ' + 57: 0, # 'à¸' + 49: 0, # 'à¸' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 1, # 'ด' + 19: 2, # 'ต' + 44: 1, # 'ถ' + 14: 3, # 'ท' + 48: 0, # 'ธ' + 3: 3, # 'น' + 17: 3, # 'บ' + 25: 2, # 'ป' + 39: 2, # 'ผ' + 62: 0, # 'à¸' + 31: 1, # 'พ' + 54: 1, # 'ฟ' + 45: 1, # 'ภ' + 9: 1, # 'ม' + 16: 0, # 'ย' + 2: 3, # 'ร' + 61: 0, # 'ฤ' + 15: 2, # 'ล' + 12: 3, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 2, # 'ส' + 21: 2, # 'ห' + 4: 2, # 'อ' + 63: 1, # 'ฯ' + 22: 0, # 'ะ' + 10: 3, # 'ั' + 1: 3, # 'า' + 36: 2, # 'ำ' + 23: 2, # 'ิ' + 13: 2, # 'ี' + 40: 0, # 'ึ' + 27: 2, # 'ื' + 32: 3, # 'ุ' + 35: 2, # 'ู' + 11: 2, # 'เ' + 28: 2, # 'à¹' + 41: 1, # 'โ' + 29: 2, # 'ใ' + 33: 2, # 'ไ' + 50: 0, # 'ๆ' + 37: 1, # '็' + 6: 2, # '่' + 7: 2, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 25: { # 'ป' + 5: 2, # 'à¸' + 30: 0, # 'ข' + 24: 1, # 'ค' + 8: 0, # 'ง' + 26: 1, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 1, # 'ซ' + 47: 0, # 'à¸' + 58: 1, # 'ฎ' + 57: 3, # 'à¸' + 49: 1, # 'à¸' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 1, # 'ด' + 19: 1, # 'ต' + 44: 1, # 'ถ' + 14: 1, # 'ท' + 48: 0, # 'ธ' + 3: 2, # 'น' + 17: 0, # 'บ' + 25: 1, # 'ป' + 39: 1, # 'ผ' + 62: 1, # 'à¸' + 31: 1, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 1, # 'ม' + 16: 0, # 'ย' + 2: 3, # 'ร' + 61: 0, # 'ฤ' + 15: 3, # 'ล' + 12: 1, # 'ว' + 42: 0, # 'ศ' + 46: 1, # 'ษ' + 18: 2, # 'ส' + 21: 1, # 'ห' + 4: 2, # 'อ' + 63: 0, # 'ฯ' + 22: 1, # 'ะ' + 10: 3, # 'ั' + 1: 1, # 'า' + 36: 0, # 'ำ' + 23: 2, # 'ิ' + 13: 3, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 1, # 'ุ' + 35: 0, # 'ู' + 11: 1, # 'เ' + 28: 2, # 'à¹' + 41: 0, # 'โ' + 29: 1, # 'ใ' + 33: 2, # 'ไ' + 50: 0, # 'ๆ' + 37: 3, # '็' + 6: 1, # '่' + 7: 2, # '้' + 38: 1, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 39: { # 'ผ' + 5: 1, # 'à¸' + 30: 0, # 'ข' + 24: 0, # 'ค' + 8: 1, # 'ง' + 26: 0, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'à¸' + 58: 0, # 'ฎ' + 57: 0, # 'à¸' + 49: 0, # 'à¸' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 0, # 'ด' + 19: 0, # 'ต' + 44: 0, # 'ถ' + 14: 0, # 'ท' + 48: 0, # 'ธ' + 3: 2, # 'น' + 17: 0, # 'บ' + 25: 0, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'à¸' + 31: 0, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 1, # 'ม' + 16: 2, # 'ย' + 2: 0, # 'ร' + 61: 0, # 'ฤ' + 15: 3, # 'ล' + 12: 0, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 1, # 'ส' + 21: 0, # 'ห' + 4: 0, # 'อ' + 63: 0, # 'ฯ' + 22: 1, # 'ะ' + 10: 1, # 'ั' + 1: 0, # 'า' + 36: 0, # 'ำ' + 23: 2, # 'ิ' + 13: 0, # 'ี' + 40: 0, # 'ึ' + 27: 1, # 'ื' + 32: 0, # 'ุ' + 35: 3, # 'ู' + 11: 0, # 'เ' + 28: 0, # 'à¹' + 41: 0, # 'โ' + 29: 0, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 3, # '่' + 7: 1, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 62: { # 'à¸' + 5: 0, # 'à¸' + 30: 0, # 'ข' + 24: 0, # 'ค' + 8: 0, # 'ง' + 26: 0, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'à¸' + 58: 0, # 'ฎ' + 57: 0, # 'à¸' + 49: 0, # 'à¸' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 0, # 'ด' + 19: 0, # 'ต' + 44: 0, # 'ถ' + 14: 0, # 'ท' + 48: 0, # 'ธ' + 3: 1, # 'น' + 17: 0, # 'บ' + 25: 0, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'à¸' + 31: 0, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 0, # 'ม' + 16: 0, # 'ย' + 2: 1, # 'ร' + 61: 0, # 'ฤ' + 15: 0, # 'ล' + 12: 0, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 0, # 'ส' + 21: 0, # 'ห' + 4: 0, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 1, # 'ั' + 1: 0, # 'า' + 36: 0, # 'ำ' + 23: 0, # 'ิ' + 13: 1, # 'ี' + 40: 2, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 0, # 'เ' + 28: 0, # 'à¹' + 41: 0, # 'โ' + 29: 0, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 2, # '่' + 7: 1, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 31: { # 'พ' + 5: 1, # 'à¸' + 30: 1, # 'ข' + 24: 1, # 'ค' + 8: 1, # 'ง' + 26: 1, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'à¸' + 58: 0, # 'ฎ' + 57: 0, # 'à¸' + 49: 0, # 'à¸' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 1, # 'ณ' + 20: 1, # 'ด' + 19: 1, # 'ต' + 44: 0, # 'ถ' + 14: 2, # 'ท' + 48: 1, # 'ธ' + 3: 3, # 'น' + 17: 2, # 'บ' + 25: 0, # 'ป' + 39: 1, # 'ผ' + 62: 0, # 'à¸' + 31: 1, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 1, # 'ม' + 16: 2, # 'ย' + 2: 3, # 'ร' + 61: 2, # 'ฤ' + 15: 2, # 'ล' + 12: 2, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 1, # 'ส' + 21: 1, # 'ห' + 4: 2, # 'อ' + 63: 1, # 'ฯ' + 22: 0, # 'ะ' + 10: 3, # 'ั' + 1: 3, # 'า' + 36: 0, # 'ำ' + 23: 3, # 'ิ' + 13: 2, # 'ี' + 40: 1, # 'ึ' + 27: 3, # 'ื' + 32: 1, # 'ุ' + 35: 2, # 'ู' + 11: 1, # 'เ' + 28: 1, # 'à¹' + 41: 0, # 'โ' + 29: 1, # 'ใ' + 33: 1, # 'ไ' + 50: 0, # 'ๆ' + 37: 1, # '็' + 6: 0, # '่' + 7: 1, # '้' + 38: 3, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 54: { # 'ฟ' + 5: 0, # 'à¸' + 30: 0, # 'ข' + 24: 0, # 'ค' + 8: 0, # 'ง' + 26: 0, # 'จ' + 52: 0, # 'ฉ' + 34: 1, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'à¸' + 58: 0, # 'ฎ' + 57: 0, # 'à¸' + 49: 0, # 'à¸' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 0, # 'ด' + 19: 1, # 'ต' + 44: 0, # 'ถ' + 14: 1, # 'ท' + 48: 0, # 'ธ' + 3: 0, # 'น' + 17: 0, # 'บ' + 25: 0, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'à¸' + 31: 0, # 'พ' + 54: 2, # 'ฟ' + 45: 0, # 'ภ' + 9: 0, # 'ม' + 16: 0, # 'ย' + 2: 1, # 'ร' + 61: 0, # 'ฤ' + 15: 2, # 'ล' + 12: 0, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 1, # 'ส' + 21: 0, # 'ห' + 4: 1, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 2, # 'ั' + 1: 0, # 'า' + 36: 0, # 'ำ' + 23: 1, # 'ิ' + 13: 1, # 'ี' + 40: 0, # 'ึ' + 27: 1, # 'ื' + 32: 1, # 'ุ' + 35: 0, # 'ู' + 11: 0, # 'เ' + 28: 1, # 'à¹' + 41: 0, # 'โ' + 29: 0, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 0, # '่' + 7: 2, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 45: { # 'ภ' + 5: 0, # 'à¸' + 30: 0, # 'ข' + 24: 1, # 'ค' + 8: 0, # 'ง' + 26: 0, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'à¸' + 58: 0, # 'ฎ' + 57: 0, # 'à¸' + 49: 0, # 'à¸' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 0, # 'ด' + 19: 0, # 'ต' + 44: 0, # 'ถ' + 14: 3, # 'ท' + 48: 0, # 'ธ' + 3: 0, # 'น' + 17: 0, # 'บ' + 25: 0, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'à¸' + 31: 1, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 0, # 'ม' + 16: 0, # 'ย' + 2: 1, # 'ร' + 61: 0, # 'ฤ' + 15: 0, # 'ล' + 12: 0, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 0, # 'ส' + 21: 0, # 'ห' + 4: 0, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 3, # 'ั' + 1: 3, # 'า' + 36: 0, # 'ำ' + 23: 1, # 'ิ' + 13: 0, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 2, # 'ู' + 11: 0, # 'เ' + 28: 0, # 'à¹' + 41: 0, # 'โ' + 29: 0, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 0, # '่' + 7: 0, # '้' + 38: 1, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 9: { # 'ม' + 5: 2, # 'à¸' + 30: 2, # 'ข' + 24: 2, # 'ค' + 8: 2, # 'ง' + 26: 2, # 'จ' + 52: 0, # 'ฉ' + 34: 1, # 'ช' + 51: 1, # 'ซ' + 47: 0, # 'à¸' + 58: 0, # 'ฎ' + 57: 0, # 'à¸' + 49: 0, # 'à¸' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 1, # 'ณ' + 20: 2, # 'ด' + 19: 2, # 'ต' + 44: 1, # 'ถ' + 14: 2, # 'ท' + 48: 1, # 'ธ' + 3: 3, # 'น' + 17: 2, # 'บ' + 25: 2, # 'ป' + 39: 1, # 'ผ' + 62: 0, # 'à¸' + 31: 3, # 'พ' + 54: 0, # 'ฟ' + 45: 1, # 'ภ' + 9: 2, # 'ม' + 16: 1, # 'ย' + 2: 2, # 'ร' + 61: 2, # 'ฤ' + 15: 2, # 'ล' + 12: 2, # 'ว' + 42: 1, # 'ศ' + 46: 1, # 'ษ' + 18: 3, # 'ส' + 21: 3, # 'ห' + 4: 3, # 'อ' + 63: 0, # 'ฯ' + 22: 1, # 'ะ' + 10: 3, # 'ั' + 1: 3, # 'า' + 36: 0, # 'ำ' + 23: 3, # 'ิ' + 13: 3, # 'ี' + 40: 0, # 'ึ' + 27: 3, # 'ื' + 32: 3, # 'ุ' + 35: 3, # 'ู' + 11: 2, # 'เ' + 28: 2, # 'à¹' + 41: 2, # 'โ' + 29: 2, # 'ใ' + 33: 2, # 'ไ' + 50: 1, # 'ๆ' + 37: 1, # '็' + 6: 3, # '่' + 7: 2, # '้' + 38: 1, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 16: { # 'ย' + 5: 3, # 'à¸' + 30: 1, # 'ข' + 24: 2, # 'ค' + 8: 3, # 'ง' + 26: 2, # 'จ' + 52: 0, # 'ฉ' + 34: 2, # 'ช' + 51: 0, # 'ซ' + 47: 2, # 'à¸' + 58: 0, # 'ฎ' + 57: 0, # 'à¸' + 49: 0, # 'à¸' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 2, # 'ด' + 19: 2, # 'ต' + 44: 1, # 'ถ' + 14: 2, # 'ท' + 48: 1, # 'ธ' + 3: 3, # 'น' + 17: 3, # 'บ' + 25: 1, # 'ป' + 39: 1, # 'ผ' + 62: 0, # 'à¸' + 31: 1, # 'พ' + 54: 0, # 'ฟ' + 45: 1, # 'ภ' + 9: 2, # 'ม' + 16: 0, # 'ย' + 2: 2, # 'ร' + 61: 0, # 'ฤ' + 15: 1, # 'ล' + 12: 3, # 'ว' + 42: 1, # 'ศ' + 46: 0, # 'ษ' + 18: 2, # 'ส' + 21: 1, # 'ห' + 4: 2, # 'อ' + 63: 0, # 'ฯ' + 22: 2, # 'ะ' + 10: 3, # 'ั' + 1: 3, # 'า' + 36: 0, # 'ำ' + 23: 2, # 'ิ' + 13: 3, # 'ี' + 40: 1, # 'ึ' + 27: 2, # 'ื' + 32: 2, # 'ุ' + 35: 3, # 'ู' + 11: 2, # 'เ' + 28: 1, # 'à¹' + 41: 1, # 'โ' + 29: 2, # 'ใ' + 33: 2, # 'ไ' + 50: 2, # 'ๆ' + 37: 1, # '็' + 6: 3, # '่' + 7: 2, # '้' + 38: 3, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 2: { # 'ร' + 5: 3, # 'à¸' + 30: 2, # 'ข' + 24: 2, # 'ค' + 8: 3, # 'ง' + 26: 2, # 'จ' + 52: 0, # 'ฉ' + 34: 2, # 'ช' + 51: 1, # 'ซ' + 47: 0, # 'à¸' + 58: 0, # 'ฎ' + 57: 0, # 'à¸' + 49: 3, # 'à¸' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 3, # 'ณ' + 20: 2, # 'ด' + 19: 2, # 'ต' + 44: 3, # 'ถ' + 14: 3, # 'ท' + 48: 1, # 'ธ' + 3: 2, # 'น' + 17: 2, # 'บ' + 25: 3, # 'ป' + 39: 2, # 'ผ' + 62: 1, # 'à¸' + 31: 2, # 'พ' + 54: 1, # 'ฟ' + 45: 1, # 'ภ' + 9: 3, # 'ม' + 16: 2, # 'ย' + 2: 3, # 'ร' + 61: 0, # 'ฤ' + 15: 2, # 'ล' + 12: 3, # 'ว' + 42: 2, # 'ศ' + 46: 2, # 'ษ' + 18: 2, # 'ส' + 21: 2, # 'ห' + 4: 3, # 'อ' + 63: 1, # 'ฯ' + 22: 3, # 'ะ' + 10: 3, # 'ั' + 1: 3, # 'า' + 36: 0, # 'ำ' + 23: 3, # 'ิ' + 13: 3, # 'ี' + 40: 2, # 'ึ' + 27: 3, # 'ื' + 32: 3, # 'ุ' + 35: 3, # 'ู' + 11: 3, # 'เ' + 28: 3, # 'à¹' + 41: 1, # 'โ' + 29: 2, # 'ใ' + 33: 1, # 'ไ' + 50: 0, # 'ๆ' + 37: 3, # '็' + 6: 3, # '่' + 7: 3, # '้' + 38: 3, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 61: { # 'ฤ' + 5: 0, # 'à¸' + 30: 0, # 'ข' + 24: 0, # 'ค' + 8: 0, # 'ง' + 26: 0, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'à¸' + 58: 0, # 'ฎ' + 57: 0, # 'à¸' + 49: 0, # 'à¸' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 0, # 'ด' + 19: 2, # 'ต' + 44: 0, # 'ถ' + 14: 2, # 'ท' + 48: 0, # 'ธ' + 3: 0, # 'น' + 17: 0, # 'บ' + 25: 0, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'à¸' + 31: 0, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 1, # 'ม' + 16: 0, # 'ย' + 2: 0, # 'ร' + 61: 0, # 'ฤ' + 15: 0, # 'ล' + 12: 0, # 'ว' + 42: 0, # 'ศ' + 46: 2, # 'ษ' + 18: 0, # 'ส' + 21: 0, # 'ห' + 4: 0, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 0, # 'ั' + 1: 0, # 'า' + 36: 0, # 'ำ' + 23: 0, # 'ิ' + 13: 0, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 0, # 'เ' + 28: 0, # 'à¹' + 41: 0, # 'โ' + 29: 0, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 0, # '่' + 7: 0, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 15: { # 'ล' + 5: 2, # 'à¸' + 30: 3, # 'ข' + 24: 1, # 'ค' + 8: 3, # 'ง' + 26: 1, # 'จ' + 52: 0, # 'ฉ' + 34: 1, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'à¸' + 58: 0, # 'ฎ' + 57: 0, # 'à¸' + 49: 0, # 'à¸' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 2, # 'ด' + 19: 2, # 'ต' + 44: 1, # 'ถ' + 14: 2, # 'ท' + 48: 0, # 'ธ' + 3: 1, # 'น' + 17: 2, # 'บ' + 25: 2, # 'ป' + 39: 1, # 'ผ' + 62: 0, # 'à¸' + 31: 0, # 'พ' + 54: 0, # 'ฟ' + 45: 1, # 'ภ' + 9: 1, # 'ม' + 16: 3, # 'ย' + 2: 1, # 'ร' + 61: 0, # 'ฤ' + 15: 1, # 'ล' + 12: 1, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 2, # 'ส' + 21: 1, # 'ห' + 4: 3, # 'อ' + 63: 2, # 'ฯ' + 22: 3, # 'ะ' + 10: 3, # 'ั' + 1: 3, # 'า' + 36: 2, # 'ำ' + 23: 3, # 'ิ' + 13: 3, # 'ี' + 40: 2, # 'ึ' + 27: 3, # 'ื' + 32: 2, # 'ุ' + 35: 3, # 'ู' + 11: 2, # 'เ' + 28: 1, # 'à¹' + 41: 1, # 'โ' + 29: 2, # 'ใ' + 33: 1, # 'ไ' + 50: 0, # 'ๆ' + 37: 2, # '็' + 6: 3, # '่' + 7: 3, # '้' + 38: 2, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 12: { # 'ว' + 5: 3, # 'à¸' + 30: 2, # 'ข' + 24: 1, # 'ค' + 8: 3, # 'ง' + 26: 2, # 'จ' + 52: 0, # 'ฉ' + 34: 1, # 'ช' + 51: 1, # 'ซ' + 47: 0, # 'à¸' + 58: 0, # 'ฎ' + 57: 0, # 'à¸' + 49: 0, # 'à¸' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 1, # 'ณ' + 20: 2, # 'ด' + 19: 1, # 'ต' + 44: 1, # 'ถ' + 14: 1, # 'ท' + 48: 0, # 'ธ' + 3: 3, # 'น' + 17: 2, # 'บ' + 25: 1, # 'ป' + 39: 1, # 'ผ' + 62: 0, # 'à¸' + 31: 1, # 'พ' + 54: 1, # 'ฟ' + 45: 0, # 'ภ' + 9: 3, # 'ม' + 16: 3, # 'ย' + 2: 3, # 'ร' + 61: 0, # 'ฤ' + 15: 3, # 'ล' + 12: 1, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 2, # 'ส' + 21: 2, # 'ห' + 4: 2, # 'อ' + 63: 0, # 'ฯ' + 22: 2, # 'ะ' + 10: 3, # 'ั' + 1: 3, # 'า' + 36: 0, # 'ำ' + 23: 3, # 'ิ' + 13: 2, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 2, # 'ุ' + 35: 0, # 'ู' + 11: 3, # 'เ' + 28: 2, # 'à¹' + 41: 1, # 'โ' + 29: 1, # 'ใ' + 33: 2, # 'ไ' + 50: 1, # 'ๆ' + 37: 0, # '็' + 6: 3, # '่' + 7: 3, # '้' + 38: 1, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 42: { # 'ศ' + 5: 1, # 'à¸' + 30: 0, # 'ข' + 24: 1, # 'ค' + 8: 0, # 'ง' + 26: 1, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 1, # 'à¸' + 58: 0, # 'ฎ' + 57: 0, # 'à¸' + 49: 0, # 'à¸' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 0, # 'ด' + 19: 1, # 'ต' + 44: 0, # 'ถ' + 14: 1, # 'ท' + 48: 0, # 'ธ' + 3: 2, # 'น' + 17: 0, # 'บ' + 25: 0, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'à¸' + 31: 0, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 0, # 'ม' + 16: 0, # 'ย' + 2: 2, # 'ร' + 61: 0, # 'ฤ' + 15: 0, # 'ล' + 12: 2, # 'ว' + 42: 1, # 'ศ' + 46: 2, # 'ษ' + 18: 1, # 'ส' + 21: 0, # 'ห' + 4: 0, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 2, # 'ั' + 1: 3, # 'า' + 36: 0, # 'ำ' + 23: 2, # 'ิ' + 13: 0, # 'ี' + 40: 3, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 2, # 'ู' + 11: 0, # 'เ' + 28: 1, # 'à¹' + 41: 0, # 'โ' + 29: 1, # 'ใ' + 33: 1, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 0, # '่' + 7: 0, # '้' + 38: 1, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 46: { # 'ษ' + 5: 0, # 'à¸' + 30: 0, # 'ข' + 24: 0, # 'ค' + 8: 0, # 'ง' + 26: 0, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'à¸' + 58: 2, # 'ฎ' + 57: 1, # 'à¸' + 49: 2, # 'à¸' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 3, # 'ณ' + 20: 0, # 'ด' + 19: 1, # 'ต' + 44: 0, # 'ถ' + 14: 1, # 'ท' + 48: 0, # 'ธ' + 3: 0, # 'น' + 17: 0, # 'บ' + 25: 0, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'à¸' + 31: 0, # 'พ' + 54: 0, # 'ฟ' + 45: 1, # 'ภ' + 9: 1, # 'ม' + 16: 2, # 'ย' + 2: 2, # 'ร' + 61: 0, # 'ฤ' + 15: 0, # 'ล' + 12: 0, # 'ว' + 42: 1, # 'ศ' + 46: 0, # 'ษ' + 18: 0, # 'ส' + 21: 0, # 'ห' + 4: 0, # 'อ' + 63: 0, # 'ฯ' + 22: 2, # 'ะ' + 10: 2, # 'ั' + 1: 3, # 'า' + 36: 0, # 'ำ' + 23: 0, # 'ิ' + 13: 1, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 1, # 'เ' + 28: 0, # 'à¹' + 41: 0, # 'โ' + 29: 0, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 0, # '่' + 7: 0, # '้' + 38: 2, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 18: { # 'ส' + 5: 2, # 'à¸' + 30: 0, # 'ข' + 24: 0, # 'ค' + 8: 2, # 'ง' + 26: 1, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'à¸' + 58: 0, # 'ฎ' + 57: 0, # 'à¸' + 49: 0, # 'à¸' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 3, # 'ด' + 19: 3, # 'ต' + 44: 3, # 'ถ' + 14: 0, # 'ท' + 48: 0, # 'ธ' + 3: 3, # 'น' + 17: 2, # 'บ' + 25: 1, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'à¸' + 31: 0, # 'พ' + 54: 0, # 'ฟ' + 45: 2, # 'ภ' + 9: 3, # 'ม' + 16: 1, # 'ย' + 2: 3, # 'ร' + 61: 0, # 'ฤ' + 15: 1, # 'ล' + 12: 2, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 0, # 'ส' + 21: 2, # 'ห' + 4: 3, # 'อ' + 63: 0, # 'ฯ' + 22: 2, # 'ะ' + 10: 3, # 'ั' + 1: 3, # 'า' + 36: 3, # 'ำ' + 23: 3, # 'ิ' + 13: 3, # 'ี' + 40: 2, # 'ึ' + 27: 3, # 'ื' + 32: 3, # 'ุ' + 35: 3, # 'ู' + 11: 2, # 'เ' + 28: 0, # 'à¹' + 41: 1, # 'โ' + 29: 0, # 'ใ' + 33: 1, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 3, # '่' + 7: 1, # '้' + 38: 2, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 21: { # 'ห' + 5: 3, # 'à¸' + 30: 0, # 'ข' + 24: 0, # 'ค' + 8: 1, # 'ง' + 26: 0, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 2, # 'à¸' + 58: 0, # 'ฎ' + 57: 0, # 'à¸' + 49: 0, # 'à¸' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 1, # 'ด' + 19: 3, # 'ต' + 44: 0, # 'ถ' + 14: 0, # 'ท' + 48: 0, # 'ธ' + 3: 3, # 'น' + 17: 0, # 'บ' + 25: 1, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'à¸' + 31: 1, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 3, # 'ม' + 16: 2, # 'ย' + 2: 3, # 'ร' + 61: 0, # 'ฤ' + 15: 3, # 'ล' + 12: 2, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 0, # 'ส' + 21: 0, # 'ห' + 4: 3, # 'อ' + 63: 0, # 'ฯ' + 22: 1, # 'ะ' + 10: 3, # 'ั' + 1: 3, # 'า' + 36: 0, # 'ำ' + 23: 1, # 'ิ' + 13: 1, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 1, # 'ุ' + 35: 1, # 'ู' + 11: 0, # 'เ' + 28: 0, # 'à¹' + 41: 0, # 'โ' + 29: 0, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 3, # '็' + 6: 3, # '่' + 7: 3, # '้' + 38: 2, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 4: { # 'อ' + 5: 3, # 'à¸' + 30: 1, # 'ข' + 24: 2, # 'ค' + 8: 3, # 'ง' + 26: 1, # 'จ' + 52: 0, # 'ฉ' + 34: 1, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'à¸' + 58: 0, # 'ฎ' + 57: 0, # 'à¸' + 49: 0, # 'à¸' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 3, # 'ด' + 19: 2, # 'ต' + 44: 1, # 'ถ' + 14: 2, # 'ท' + 48: 1, # 'ธ' + 3: 3, # 'น' + 17: 3, # 'บ' + 25: 1, # 'ป' + 39: 1, # 'ผ' + 62: 0, # 'à¸' + 31: 1, # 'พ' + 54: 1, # 'ฟ' + 45: 1, # 'ภ' + 9: 3, # 'ม' + 16: 3, # 'ย' + 2: 3, # 'ร' + 61: 0, # 'ฤ' + 15: 2, # 'ล' + 12: 2, # 'ว' + 42: 1, # 'ศ' + 46: 0, # 'ษ' + 18: 2, # 'ส' + 21: 2, # 'ห' + 4: 3, # 'อ' + 63: 0, # 'ฯ' + 22: 2, # 'ะ' + 10: 3, # 'ั' + 1: 3, # 'า' + 36: 2, # 'ำ' + 23: 2, # 'ิ' + 13: 3, # 'ี' + 40: 0, # 'ึ' + 27: 3, # 'ื' + 32: 3, # 'ุ' + 35: 0, # 'ู' + 11: 3, # 'เ' + 28: 1, # 'à¹' + 41: 1, # 'โ' + 29: 2, # 'ใ' + 33: 2, # 'ไ' + 50: 1, # 'ๆ' + 37: 1, # '็' + 6: 2, # '่' + 7: 2, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 63: { # 'ฯ' + 5: 0, # 'à¸' + 30: 0, # 'ข' + 24: 0, # 'ค' + 8: 0, # 'ง' + 26: 0, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'à¸' + 58: 0, # 'ฎ' + 57: 0, # 'à¸' + 49: 0, # 'à¸' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 0, # 'ด' + 19: 0, # 'ต' + 44: 0, # 'ถ' + 14: 0, # 'ท' + 48: 0, # 'ธ' + 3: 0, # 'น' + 17: 0, # 'บ' + 25: 0, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'à¸' + 31: 0, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 0, # 'ม' + 16: 0, # 'ย' + 2: 0, # 'ร' + 61: 0, # 'ฤ' + 15: 2, # 'ล' + 12: 0, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 0, # 'ส' + 21: 0, # 'ห' + 4: 0, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 0, # 'ั' + 1: 0, # 'า' + 36: 0, # 'ำ' + 23: 0, # 'ิ' + 13: 0, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 0, # 'เ' + 28: 0, # 'à¹' + 41: 0, # 'โ' + 29: 0, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 0, # '่' + 7: 0, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 22: { # 'ะ' + 5: 3, # 'à¸' + 30: 1, # 'ข' + 24: 2, # 'ค' + 8: 1, # 'ง' + 26: 2, # 'จ' + 52: 0, # 'ฉ' + 34: 3, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'à¸' + 58: 0, # 'ฎ' + 57: 0, # 'à¸' + 49: 0, # 'à¸' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 3, # 'ด' + 19: 3, # 'ต' + 44: 1, # 'ถ' + 14: 3, # 'ท' + 48: 1, # 'ธ' + 3: 2, # 'น' + 17: 3, # 'บ' + 25: 2, # 'ป' + 39: 1, # 'ผ' + 62: 0, # 'à¸' + 31: 2, # 'พ' + 54: 0, # 'ฟ' + 45: 1, # 'ภ' + 9: 3, # 'ม' + 16: 2, # 'ย' + 2: 2, # 'ร' + 61: 0, # 'ฤ' + 15: 2, # 'ล' + 12: 2, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 3, # 'ส' + 21: 3, # 'ห' + 4: 2, # 'อ' + 63: 1, # 'ฯ' + 22: 1, # 'ะ' + 10: 0, # 'ั' + 1: 0, # 'า' + 36: 0, # 'ำ' + 23: 0, # 'ิ' + 13: 0, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 3, # 'เ' + 28: 2, # 'à¹' + 41: 1, # 'โ' + 29: 2, # 'ใ' + 33: 2, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 0, # '่' + 7: 0, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 10: { # 'ั' + 5: 3, # 'à¸' + 30: 0, # 'ข' + 24: 1, # 'ค' + 8: 3, # 'ง' + 26: 3, # 'จ' + 52: 0, # 'ฉ' + 34: 1, # 'ช' + 51: 0, # 'ซ' + 47: 3, # 'à¸' + 58: 0, # 'ฎ' + 57: 0, # 'à¸' + 49: 2, # 'à¸' + 53: 0, # 'ฑ' + 55: 3, # 'ฒ' + 43: 3, # 'ณ' + 20: 3, # 'ด' + 19: 3, # 'ต' + 44: 0, # 'ถ' + 14: 2, # 'ท' + 48: 0, # 'ธ' + 3: 3, # 'น' + 17: 3, # 'บ' + 25: 1, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'à¸' + 31: 2, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 3, # 'ม' + 16: 3, # 'ย' + 2: 0, # 'ร' + 61: 0, # 'ฤ' + 15: 2, # 'ล' + 12: 3, # 'ว' + 42: 2, # 'ศ' + 46: 0, # 'ษ' + 18: 3, # 'ส' + 21: 0, # 'ห' + 4: 0, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 0, # 'ั' + 1: 0, # 'า' + 36: 0, # 'ำ' + 23: 0, # 'ิ' + 13: 0, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 0, # 'เ' + 28: 0, # 'à¹' + 41: 0, # 'โ' + 29: 0, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 3, # '่' + 7: 3, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 1: { # 'า' + 5: 3, # 'à¸' + 30: 2, # 'ข' + 24: 3, # 'ค' + 8: 3, # 'ง' + 26: 3, # 'จ' + 52: 0, # 'ฉ' + 34: 3, # 'ช' + 51: 1, # 'ซ' + 47: 2, # 'à¸' + 58: 0, # 'ฎ' + 57: 0, # 'à¸' + 49: 0, # 'à¸' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 3, # 'ณ' + 20: 3, # 'ด' + 19: 3, # 'ต' + 44: 1, # 'ถ' + 14: 3, # 'ท' + 48: 2, # 'ธ' + 3: 3, # 'น' + 17: 3, # 'บ' + 25: 2, # 'ป' + 39: 1, # 'ผ' + 62: 1, # 'à¸' + 31: 3, # 'พ' + 54: 1, # 'ฟ' + 45: 1, # 'ภ' + 9: 3, # 'ม' + 16: 3, # 'ย' + 2: 3, # 'ร' + 61: 0, # 'ฤ' + 15: 3, # 'ล' + 12: 3, # 'ว' + 42: 2, # 'ศ' + 46: 3, # 'ษ' + 18: 3, # 'ส' + 21: 3, # 'ห' + 4: 2, # 'อ' + 63: 1, # 'ฯ' + 22: 3, # 'ะ' + 10: 0, # 'ั' + 1: 0, # 'า' + 36: 0, # 'ำ' + 23: 0, # 'ิ' + 13: 0, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 3, # 'เ' + 28: 2, # 'à¹' + 41: 1, # 'โ' + 29: 2, # 'ใ' + 33: 2, # 'ไ' + 50: 1, # 'ๆ' + 37: 0, # '็' + 6: 0, # '่' + 7: 0, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 36: { # 'ำ' + 5: 2, # 'à¸' + 30: 1, # 'ข' + 24: 3, # 'ค' + 8: 2, # 'ง' + 26: 1, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'à¸' + 58: 0, # 'ฎ' + 57: 0, # 'à¸' + 49: 1, # 'à¸' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 1, # 'ด' + 19: 1, # 'ต' + 44: 1, # 'ถ' + 14: 1, # 'ท' + 48: 0, # 'ธ' + 3: 3, # 'น' + 17: 1, # 'บ' + 25: 1, # 'ป' + 39: 1, # 'ผ' + 62: 0, # 'à¸' + 31: 1, # 'พ' + 54: 0, # 'ฟ' + 45: 1, # 'ภ' + 9: 1, # 'ม' + 16: 0, # 'ย' + 2: 2, # 'ร' + 61: 0, # 'ฤ' + 15: 2, # 'ล' + 12: 1, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 1, # 'ส' + 21: 3, # 'ห' + 4: 1, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 0, # 'ั' + 1: 0, # 'า' + 36: 0, # 'ำ' + 23: 0, # 'ิ' + 13: 0, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 3, # 'เ' + 28: 2, # 'à¹' + 41: 1, # 'โ' + 29: 2, # 'ใ' + 33: 2, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 0, # '่' + 7: 0, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 23: { # 'ิ' + 5: 3, # 'à¸' + 30: 1, # 'ข' + 24: 2, # 'ค' + 8: 3, # 'ง' + 26: 3, # 'จ' + 52: 0, # 'ฉ' + 34: 3, # 'ช' + 51: 0, # 'ซ' + 47: 2, # 'à¸' + 58: 0, # 'ฎ' + 57: 0, # 'à¸' + 49: 0, # 'à¸' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 3, # 'ด' + 19: 3, # 'ต' + 44: 1, # 'ถ' + 14: 3, # 'ท' + 48: 3, # 'ธ' + 3: 3, # 'น' + 17: 3, # 'บ' + 25: 2, # 'ป' + 39: 2, # 'ผ' + 62: 0, # 'à¸' + 31: 3, # 'พ' + 54: 1, # 'ฟ' + 45: 2, # 'ภ' + 9: 3, # 'ม' + 16: 2, # 'ย' + 2: 2, # 'ร' + 61: 0, # 'ฤ' + 15: 2, # 'ล' + 12: 3, # 'ว' + 42: 3, # 'ศ' + 46: 2, # 'ษ' + 18: 2, # 'ส' + 21: 3, # 'ห' + 4: 1, # 'อ' + 63: 1, # 'ฯ' + 22: 0, # 'ะ' + 10: 0, # 'ั' + 1: 0, # 'า' + 36: 0, # 'ำ' + 23: 0, # 'ิ' + 13: 0, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 3, # 'เ' + 28: 1, # 'à¹' + 41: 1, # 'โ' + 29: 1, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 3, # '่' + 7: 2, # '้' + 38: 2, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 13: { # 'ี' + 5: 3, # 'à¸' + 30: 2, # 'ข' + 24: 2, # 'ค' + 8: 0, # 'ง' + 26: 1, # 'จ' + 52: 0, # 'ฉ' + 34: 1, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'à¸' + 58: 0, # 'ฎ' + 57: 0, # 'à¸' + 49: 0, # 'à¸' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 2, # 'ด' + 19: 1, # 'ต' + 44: 0, # 'ถ' + 14: 2, # 'ท' + 48: 0, # 'ธ' + 3: 1, # 'น' + 17: 2, # 'บ' + 25: 2, # 'ป' + 39: 1, # 'ผ' + 62: 0, # 'à¸' + 31: 2, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 2, # 'ม' + 16: 3, # 'ย' + 2: 2, # 'ร' + 61: 0, # 'ฤ' + 15: 1, # 'ล' + 12: 2, # 'ว' + 42: 1, # 'ศ' + 46: 0, # 'ษ' + 18: 2, # 'ส' + 21: 1, # 'ห' + 4: 2, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 0, # 'ั' + 1: 0, # 'า' + 36: 0, # 'ำ' + 23: 0, # 'ิ' + 13: 0, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 2, # 'เ' + 28: 2, # 'à¹' + 41: 1, # 'โ' + 29: 1, # 'ใ' + 33: 1, # 'ไ' + 50: 1, # 'ๆ' + 37: 0, # '็' + 6: 3, # '่' + 7: 3, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 40: { # 'ึ' + 5: 3, # 'à¸' + 30: 0, # 'ข' + 24: 0, # 'ค' + 8: 3, # 'ง' + 26: 0, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'à¸' + 58: 0, # 'ฎ' + 57: 0, # 'à¸' + 49: 0, # 'à¸' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 1, # 'ด' + 19: 0, # 'ต' + 44: 0, # 'ถ' + 14: 0, # 'ท' + 48: 0, # 'ธ' + 3: 0, # 'น' + 17: 0, # 'บ' + 25: 0, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'à¸' + 31: 0, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 1, # 'ม' + 16: 0, # 'ย' + 2: 0, # 'ร' + 61: 0, # 'ฤ' + 15: 0, # 'ล' + 12: 0, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 0, # 'ส' + 21: 0, # 'ห' + 4: 0, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 0, # 'ั' + 1: 0, # 'า' + 36: 0, # 'ำ' + 23: 0, # 'ิ' + 13: 0, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 0, # 'เ' + 28: 0, # 'à¹' + 41: 0, # 'โ' + 29: 0, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 3, # '่' + 7: 3, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 27: { # 'ื' + 5: 0, # 'à¸' + 30: 0, # 'ข' + 24: 0, # 'ค' + 8: 0, # 'ง' + 26: 0, # 'จ' + 52: 0, # 'ฉ' + 34: 1, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'à¸' + 58: 0, # 'ฎ' + 57: 0, # 'à¸' + 49: 0, # 'à¸' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 1, # 'ด' + 19: 0, # 'ต' + 44: 0, # 'ถ' + 14: 0, # 'ท' + 48: 0, # 'ธ' + 3: 2, # 'น' + 17: 3, # 'บ' + 25: 0, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'à¸' + 31: 0, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 2, # 'ม' + 16: 0, # 'ย' + 2: 0, # 'ร' + 61: 0, # 'ฤ' + 15: 0, # 'ล' + 12: 0, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 0, # 'ส' + 21: 0, # 'ห' + 4: 3, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 0, # 'ั' + 1: 0, # 'า' + 36: 0, # 'ำ' + 23: 0, # 'ิ' + 13: 0, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 0, # 'เ' + 28: 0, # 'à¹' + 41: 0, # 'โ' + 29: 0, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 3, # '่' + 7: 3, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 32: { # 'ุ' + 5: 3, # 'à¸' + 30: 2, # 'ข' + 24: 3, # 'ค' + 8: 3, # 'ง' + 26: 0, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 2, # 'à¸' + 58: 0, # 'ฎ' + 57: 0, # 'à¸' + 49: 0, # 'à¸' + 53: 0, # 'ฑ' + 55: 1, # 'ฒ' + 43: 3, # 'ณ' + 20: 3, # 'ด' + 19: 3, # 'ต' + 44: 1, # 'ถ' + 14: 2, # 'ท' + 48: 1, # 'ธ' + 3: 2, # 'น' + 17: 2, # 'บ' + 25: 2, # 'ป' + 39: 2, # 'ผ' + 62: 0, # 'à¸' + 31: 1, # 'พ' + 54: 0, # 'ฟ' + 45: 1, # 'ภ' + 9: 3, # 'ม' + 16: 1, # 'ย' + 2: 2, # 'ร' + 61: 0, # 'ฤ' + 15: 2, # 'ล' + 12: 1, # 'ว' + 42: 1, # 'ศ' + 46: 2, # 'ษ' + 18: 1, # 'ส' + 21: 1, # 'ห' + 4: 1, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 0, # 'ั' + 1: 0, # 'า' + 36: 0, # 'ำ' + 23: 0, # 'ิ' + 13: 0, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 1, # 'เ' + 28: 0, # 'à¹' + 41: 1, # 'โ' + 29: 0, # 'ใ' + 33: 1, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 3, # '่' + 7: 2, # '้' + 38: 1, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 35: { # 'ู' + 5: 3, # 'à¸' + 30: 0, # 'ข' + 24: 0, # 'ค' + 8: 2, # 'ง' + 26: 1, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 2, # 'à¸' + 58: 0, # 'ฎ' + 57: 0, # 'à¸' + 49: 0, # 'à¸' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 1, # 'ณ' + 20: 2, # 'ด' + 19: 2, # 'ต' + 44: 0, # 'ถ' + 14: 1, # 'ท' + 48: 0, # 'ธ' + 3: 2, # 'น' + 17: 0, # 'บ' + 25: 3, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'à¸' + 31: 0, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 2, # 'ม' + 16: 0, # 'ย' + 2: 1, # 'ร' + 61: 0, # 'ฤ' + 15: 3, # 'ล' + 12: 1, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 0, # 'ส' + 21: 0, # 'ห' + 4: 0, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 0, # 'ั' + 1: 0, # 'า' + 36: 0, # 'ำ' + 23: 0, # 'ิ' + 13: 0, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 1, # 'เ' + 28: 1, # 'à¹' + 41: 1, # 'โ' + 29: 0, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 3, # '่' + 7: 3, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 11: { # 'เ' + 5: 3, # 'à¸' + 30: 3, # 'ข' + 24: 3, # 'ค' + 8: 2, # 'ง' + 26: 3, # 'จ' + 52: 3, # 'ฉ' + 34: 3, # 'ช' + 51: 2, # 'ซ' + 47: 0, # 'à¸' + 58: 0, # 'ฎ' + 57: 0, # 'à¸' + 49: 0, # 'à¸' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 1, # 'ณ' + 20: 3, # 'ด' + 19: 3, # 'ต' + 44: 1, # 'ถ' + 14: 3, # 'ท' + 48: 1, # 'ธ' + 3: 3, # 'น' + 17: 3, # 'บ' + 25: 3, # 'ป' + 39: 2, # 'ผ' + 62: 1, # 'à¸' + 31: 3, # 'พ' + 54: 1, # 'ฟ' + 45: 3, # 'ภ' + 9: 3, # 'ม' + 16: 2, # 'ย' + 2: 3, # 'ร' + 61: 0, # 'ฤ' + 15: 3, # 'ล' + 12: 3, # 'ว' + 42: 2, # 'ศ' + 46: 0, # 'ษ' + 18: 3, # 'ส' + 21: 3, # 'ห' + 4: 3, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 0, # 'ั' + 1: 0, # 'า' + 36: 0, # 'ำ' + 23: 0, # 'ิ' + 13: 0, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 0, # 'เ' + 28: 0, # 'à¹' + 41: 0, # 'โ' + 29: 0, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 0, # '่' + 7: 0, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 28: { # 'à¹' + 5: 3, # 'à¸' + 30: 2, # 'ข' + 24: 2, # 'ค' + 8: 1, # 'ง' + 26: 2, # 'จ' + 52: 0, # 'ฉ' + 34: 1, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'à¸' + 58: 0, # 'ฎ' + 57: 0, # 'à¸' + 49: 0, # 'à¸' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 2, # 'ด' + 19: 3, # 'ต' + 44: 2, # 'ถ' + 14: 3, # 'ท' + 48: 0, # 'ธ' + 3: 3, # 'น' + 17: 3, # 'บ' + 25: 2, # 'ป' + 39: 3, # 'ผ' + 62: 0, # 'à¸' + 31: 2, # 'พ' + 54: 2, # 'ฟ' + 45: 0, # 'ภ' + 9: 2, # 'ม' + 16: 2, # 'ย' + 2: 2, # 'ร' + 61: 0, # 'ฤ' + 15: 3, # 'ล' + 12: 2, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 3, # 'ส' + 21: 3, # 'ห' + 4: 1, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 0, # 'ั' + 1: 0, # 'า' + 36: 0, # 'ำ' + 23: 0, # 'ิ' + 13: 0, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 0, # 'เ' + 28: 0, # 'à¹' + 41: 0, # 'โ' + 29: 0, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 0, # '่' + 7: 0, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 41: { # 'โ' + 5: 2, # 'à¸' + 30: 1, # 'ข' + 24: 2, # 'ค' + 8: 0, # 'ง' + 26: 1, # 'จ' + 52: 1, # 'ฉ' + 34: 1, # 'ช' + 51: 1, # 'ซ' + 47: 0, # 'à¸' + 58: 0, # 'ฎ' + 57: 0, # 'à¸' + 49: 0, # 'à¸' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 3, # 'ด' + 19: 2, # 'ต' + 44: 0, # 'ถ' + 14: 2, # 'ท' + 48: 0, # 'ธ' + 3: 3, # 'น' + 17: 1, # 'บ' + 25: 3, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'à¸' + 31: 1, # 'พ' + 54: 1, # 'ฟ' + 45: 1, # 'ภ' + 9: 1, # 'ม' + 16: 2, # 'ย' + 2: 2, # 'ร' + 61: 0, # 'ฤ' + 15: 3, # 'ล' + 12: 0, # 'ว' + 42: 1, # 'ศ' + 46: 0, # 'ษ' + 18: 2, # 'ส' + 21: 0, # 'ห' + 4: 2, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 0, # 'ั' + 1: 0, # 'า' + 36: 0, # 'ำ' + 23: 0, # 'ิ' + 13: 0, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 0, # 'เ' + 28: 0, # 'à¹' + 41: 0, # 'โ' + 29: 0, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 0, # '่' + 7: 0, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 29: { # 'ใ' + 5: 2, # 'à¸' + 30: 0, # 'ข' + 24: 1, # 'ค' + 8: 0, # 'ง' + 26: 3, # 'จ' + 52: 0, # 'ฉ' + 34: 3, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'à¸' + 58: 0, # 'ฎ' + 57: 0, # 'à¸' + 49: 0, # 'à¸' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 3, # 'ด' + 19: 1, # 'ต' + 44: 0, # 'ถ' + 14: 0, # 'ท' + 48: 0, # 'ธ' + 3: 3, # 'น' + 17: 2, # 'บ' + 25: 0, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'à¸' + 31: 0, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 0, # 'ม' + 16: 1, # 'ย' + 2: 0, # 'ร' + 61: 0, # 'ฤ' + 15: 0, # 'ล' + 12: 0, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 3, # 'ส' + 21: 3, # 'ห' + 4: 0, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 0, # 'ั' + 1: 0, # 'า' + 36: 0, # 'ำ' + 23: 0, # 'ิ' + 13: 0, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 0, # 'เ' + 28: 0, # 'à¹' + 41: 0, # 'โ' + 29: 0, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 0, # '่' + 7: 0, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 33: { # 'ไ' + 5: 1, # 'à¸' + 30: 2, # 'ข' + 24: 0, # 'ค' + 8: 0, # 'ง' + 26: 0, # 'จ' + 52: 0, # 'ฉ' + 34: 1, # 'ช' + 51: 1, # 'ซ' + 47: 0, # 'à¸' + 58: 0, # 'ฎ' + 57: 0, # 'à¸' + 49: 0, # 'à¸' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 3, # 'ด' + 19: 1, # 'ต' + 44: 0, # 'ถ' + 14: 3, # 'ท' + 48: 0, # 'ธ' + 3: 0, # 'น' + 17: 1, # 'บ' + 25: 3, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'à¸' + 31: 0, # 'พ' + 54: 2, # 'ฟ' + 45: 0, # 'ภ' + 9: 3, # 'ม' + 16: 0, # 'ย' + 2: 3, # 'ร' + 61: 0, # 'ฤ' + 15: 1, # 'ล' + 12: 3, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 1, # 'ส' + 21: 2, # 'ห' + 4: 0, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 0, # 'ั' + 1: 0, # 'า' + 36: 0, # 'ำ' + 23: 0, # 'ิ' + 13: 0, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 0, # 'เ' + 28: 0, # 'à¹' + 41: 0, # 'โ' + 29: 0, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 0, # '่' + 7: 0, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 50: { # 'ๆ' + 5: 0, # 'à¸' + 30: 0, # 'ข' + 24: 0, # 'ค' + 8: 0, # 'ง' + 26: 0, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'à¸' + 58: 0, # 'ฎ' + 57: 0, # 'à¸' + 49: 0, # 'à¸' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 0, # 'ด' + 19: 0, # 'ต' + 44: 0, # 'ถ' + 14: 0, # 'ท' + 48: 0, # 'ธ' + 3: 0, # 'น' + 17: 0, # 'บ' + 25: 0, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'à¸' + 31: 0, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 0, # 'ม' + 16: 0, # 'ย' + 2: 0, # 'ร' + 61: 0, # 'ฤ' + 15: 0, # 'ล' + 12: 0, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 0, # 'ส' + 21: 0, # 'ห' + 4: 0, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 0, # 'ั' + 1: 0, # 'า' + 36: 0, # 'ำ' + 23: 0, # 'ิ' + 13: 0, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 0, # 'เ' + 28: 0, # 'à¹' + 41: 0, # 'โ' + 29: 0, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 0, # '่' + 7: 0, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 37: { # '็' + 5: 2, # 'à¸' + 30: 1, # 'ข' + 24: 2, # 'ค' + 8: 2, # 'ง' + 26: 3, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 1, # 'à¸' + 58: 0, # 'ฎ' + 57: 0, # 'à¸' + 49: 0, # 'à¸' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 1, # 'ด' + 19: 2, # 'ต' + 44: 0, # 'ถ' + 14: 1, # 'ท' + 48: 0, # 'ธ' + 3: 3, # 'น' + 17: 3, # 'บ' + 25: 0, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'à¸' + 31: 0, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 2, # 'ม' + 16: 1, # 'ย' + 2: 0, # 'ร' + 61: 0, # 'ฤ' + 15: 0, # 'ล' + 12: 2, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 1, # 'ส' + 21: 0, # 'ห' + 4: 1, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 0, # 'ั' + 1: 0, # 'า' + 36: 0, # 'ำ' + 23: 0, # 'ิ' + 13: 0, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 1, # 'เ' + 28: 0, # 'à¹' + 41: 0, # 'โ' + 29: 0, # 'ใ' + 33: 1, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 0, # '่' + 7: 0, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 6: { # '่' + 5: 2, # 'à¸' + 30: 1, # 'ข' + 24: 2, # 'ค' + 8: 3, # 'ง' + 26: 2, # 'จ' + 52: 0, # 'ฉ' + 34: 1, # 'ช' + 51: 1, # 'ซ' + 47: 0, # 'à¸' + 58: 0, # 'ฎ' + 57: 0, # 'à¸' + 49: 1, # 'à¸' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 1, # 'ด' + 19: 2, # 'ต' + 44: 1, # 'ถ' + 14: 2, # 'ท' + 48: 1, # 'ธ' + 3: 3, # 'น' + 17: 1, # 'บ' + 25: 2, # 'ป' + 39: 2, # 'ผ' + 62: 1, # 'à¸' + 31: 1, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 3, # 'ม' + 16: 3, # 'ย' + 2: 2, # 'ร' + 61: 0, # 'ฤ' + 15: 2, # 'ล' + 12: 3, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 2, # 'ส' + 21: 1, # 'ห' + 4: 3, # 'อ' + 63: 0, # 'ฯ' + 22: 1, # 'ะ' + 10: 0, # 'ั' + 1: 3, # 'า' + 36: 2, # 'ำ' + 23: 0, # 'ิ' + 13: 0, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 3, # 'เ' + 28: 2, # 'à¹' + 41: 1, # 'โ' + 29: 2, # 'ใ' + 33: 2, # 'ไ' + 50: 1, # 'ๆ' + 37: 0, # '็' + 6: 0, # '่' + 7: 0, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 7: { # '้' + 5: 2, # 'à¸' + 30: 1, # 'ข' + 24: 2, # 'ค' + 8: 3, # 'ง' + 26: 2, # 'จ' + 52: 0, # 'ฉ' + 34: 1, # 'ช' + 51: 1, # 'ซ' + 47: 0, # 'à¸' + 58: 0, # 'ฎ' + 57: 0, # 'à¸' + 49: 0, # 'à¸' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 1, # 'ด' + 19: 2, # 'ต' + 44: 1, # 'ถ' + 14: 2, # 'ท' + 48: 0, # 'ธ' + 3: 3, # 'น' + 17: 2, # 'บ' + 25: 2, # 'ป' + 39: 2, # 'ผ' + 62: 0, # 'à¸' + 31: 1, # 'พ' + 54: 1, # 'ฟ' + 45: 0, # 'ภ' + 9: 3, # 'ม' + 16: 2, # 'ย' + 2: 2, # 'ร' + 61: 0, # 'ฤ' + 15: 1, # 'ล' + 12: 3, # 'ว' + 42: 1, # 'ศ' + 46: 0, # 'ษ' + 18: 2, # 'ส' + 21: 2, # 'ห' + 4: 3, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 0, # 'ั' + 1: 3, # 'า' + 36: 2, # 'ำ' + 23: 0, # 'ิ' + 13: 0, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 2, # 'เ' + 28: 2, # 'à¹' + 41: 1, # 'โ' + 29: 2, # 'ใ' + 33: 2, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 0, # '่' + 7: 0, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 38: { # '์' + 5: 2, # 'à¸' + 30: 1, # 'ข' + 24: 1, # 'ค' + 8: 0, # 'ง' + 26: 1, # 'จ' + 52: 0, # 'ฉ' + 34: 1, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'à¸' + 58: 0, # 'ฎ' + 57: 0, # 'à¸' + 49: 0, # 'à¸' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 2, # 'ด' + 19: 1, # 'ต' + 44: 1, # 'ถ' + 14: 1, # 'ท' + 48: 0, # 'ธ' + 3: 1, # 'น' + 17: 1, # 'บ' + 25: 1, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'à¸' + 31: 1, # 'พ' + 54: 1, # 'ฟ' + 45: 0, # 'ภ' + 9: 2, # 'ม' + 16: 0, # 'ย' + 2: 1, # 'ร' + 61: 1, # 'ฤ' + 15: 1, # 'ล' + 12: 1, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 1, # 'ส' + 21: 1, # 'ห' + 4: 2, # 'อ' + 63: 1, # 'ฯ' + 22: 0, # 'ะ' + 10: 0, # 'ั' + 1: 0, # 'า' + 36: 0, # 'ำ' + 23: 0, # 'ิ' + 13: 0, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 2, # 'เ' + 28: 2, # 'à¹' + 41: 1, # 'โ' + 29: 1, # 'ใ' + 33: 1, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 0, # '่' + 7: 0, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 56: { # '๑' + 5: 0, # 'à¸' + 30: 0, # 'ข' + 24: 0, # 'ค' + 8: 0, # 'ง' + 26: 0, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'à¸' + 58: 0, # 'ฎ' + 57: 0, # 'à¸' + 49: 0, # 'à¸' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 0, # 'ด' + 19: 0, # 'ต' + 44: 0, # 'ถ' + 14: 0, # 'ท' + 48: 0, # 'ธ' + 3: 0, # 'น' + 17: 0, # 'บ' + 25: 0, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'à¸' + 31: 0, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 0, # 'ม' + 16: 0, # 'ย' + 2: 0, # 'ร' + 61: 0, # 'ฤ' + 15: 0, # 'ล' + 12: 0, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 0, # 'ส' + 21: 0, # 'ห' + 4: 0, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 0, # 'ั' + 1: 0, # 'า' + 36: 0, # 'ำ' + 23: 0, # 'ิ' + 13: 0, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 0, # 'เ' + 28: 0, # 'à¹' + 41: 0, # 'โ' + 29: 0, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 0, # '่' + 7: 0, # '้' + 38: 0, # '์' + 56: 2, # '๑' + 59: 1, # '๒' + 60: 1, # '๕' + }, + 59: { # '๒' + 5: 0, # 'à¸' + 30: 0, # 'ข' + 24: 0, # 'ค' + 8: 0, # 'ง' + 26: 0, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'à¸' + 58: 0, # 'ฎ' + 57: 0, # 'à¸' + 49: 0, # 'à¸' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 0, # 'ด' + 19: 0, # 'ต' + 44: 0, # 'ถ' + 14: 0, # 'ท' + 48: 0, # 'ธ' + 3: 0, # 'น' + 17: 0, # 'บ' + 25: 0, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'à¸' + 31: 0, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 0, # 'ม' + 16: 0, # 'ย' + 2: 0, # 'ร' + 61: 0, # 'ฤ' + 15: 0, # 'ล' + 12: 0, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 0, # 'ส' + 21: 0, # 'ห' + 4: 0, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 0, # 'ั' + 1: 0, # 'า' + 36: 0, # 'ำ' + 23: 0, # 'ิ' + 13: 0, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 0, # 'เ' + 28: 0, # 'à¹' + 41: 0, # 'โ' + 29: 0, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 0, # '่' + 7: 0, # '้' + 38: 0, # '์' + 56: 1, # '๑' + 59: 1, # '๒' + 60: 3, # '๕' + }, + 60: { # '๕' + 5: 0, # 'à¸' + 30: 0, # 'ข' + 24: 0, # 'ค' + 8: 0, # 'ง' + 26: 0, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'à¸' + 58: 0, # 'ฎ' + 57: 0, # 'à¸' + 49: 0, # 'à¸' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 0, # 'ด' + 19: 0, # 'ต' + 44: 0, # 'ถ' + 14: 0, # 'ท' + 48: 0, # 'ธ' + 3: 0, # 'น' + 17: 0, # 'บ' + 25: 0, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'à¸' + 31: 0, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 0, # 'ม' + 16: 0, # 'ย' + 2: 0, # 'ร' + 61: 0, # 'ฤ' + 15: 0, # 'ล' + 12: 0, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 0, # 'ส' + 21: 0, # 'ห' + 4: 0, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 0, # 'ั' + 1: 0, # 'า' + 36: 0, # 'ำ' + 23: 0, # 'ิ' + 13: 0, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 0, # 'เ' + 28: 0, # 'à¹' + 41: 0, # 'โ' + 29: 0, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 0, # '่' + 7: 0, # '้' + 38: 0, # '์' + 56: 2, # '๑' + 59: 1, # '๒' + 60: 0, # '๕' + }, +} + +# 255: Undefined characters that did not exist in training text +# 254: Carriage/Return +# 253: symbol (punctuation) that does not belong to word +# 252: 0 - 9 +# 251: Control characters + +# Character Mapping Table(s): +TIS_620_THAI_CHAR_TO_ORDER = { + 0: 255, # '\x00' + 1: 255, # '\x01' + 2: 255, # '\x02' + 3: 255, # '\x03' + 4: 255, # '\x04' + 5: 255, # '\x05' + 6: 255, # '\x06' + 7: 255, # '\x07' + 8: 255, # '\x08' + 9: 255, # '\t' + 10: 254, # '\n' + 11: 255, # '\x0b' + 12: 255, # '\x0c' + 13: 254, # '\r' + 14: 255, # '\x0e' + 15: 255, # '\x0f' + 16: 255, # '\x10' + 17: 255, # '\x11' + 18: 255, # '\x12' + 19: 255, # '\x13' + 20: 255, # '\x14' + 21: 255, # '\x15' + 22: 255, # '\x16' + 23: 255, # '\x17' + 24: 255, # '\x18' + 25: 255, # '\x19' + 26: 255, # '\x1a' + 27: 255, # '\x1b' + 28: 255, # '\x1c' + 29: 255, # '\x1d' + 30: 255, # '\x1e' + 31: 255, # '\x1f' + 32: 253, # ' ' + 33: 253, # '!' + 34: 253, # '"' + 35: 253, # '#' + 36: 253, # '$' + 37: 253, # '%' + 38: 253, # '&' + 39: 253, # "'" + 40: 253, # '(' + 41: 253, # ')' + 42: 253, # '*' + 43: 253, # '+' + 44: 253, # ',' + 45: 253, # '-' + 46: 253, # '.' + 47: 253, # '/' + 48: 252, # '0' + 49: 252, # '1' + 50: 252, # '2' + 51: 252, # '3' + 52: 252, # '4' + 53: 252, # '5' + 54: 252, # '6' + 55: 252, # '7' + 56: 252, # '8' + 57: 252, # '9' + 58: 253, # ':' + 59: 253, # ';' + 60: 253, # '<' + 61: 253, # '=' + 62: 253, # '>' + 63: 253, # '?' + 64: 253, # '@' + 65: 182, # 'A' + 66: 106, # 'B' + 67: 107, # 'C' + 68: 100, # 'D' + 69: 183, # 'E' + 70: 184, # 'F' + 71: 185, # 'G' + 72: 101, # 'H' + 73: 94, # 'I' + 74: 186, # 'J' + 75: 187, # 'K' + 76: 108, # 'L' + 77: 109, # 'M' + 78: 110, # 'N' + 79: 111, # 'O' + 80: 188, # 'P' + 81: 189, # 'Q' + 82: 190, # 'R' + 83: 89, # 'S' + 84: 95, # 'T' + 85: 112, # 'U' + 86: 113, # 'V' + 87: 191, # 'W' + 88: 192, # 'X' + 89: 193, # 'Y' + 90: 194, # 'Z' + 91: 253, # '[' + 92: 253, # '\\' + 93: 253, # ']' + 94: 253, # '^' + 95: 253, # '_' + 96: 253, # '`' + 97: 64, # 'a' + 98: 72, # 'b' + 99: 73, # 'c' + 100: 114, # 'd' + 101: 74, # 'e' + 102: 115, # 'f' + 103: 116, # 'g' + 104: 102, # 'h' + 105: 81, # 'i' + 106: 201, # 'j' + 107: 117, # 'k' + 108: 90, # 'l' + 109: 103, # 'm' + 110: 78, # 'n' + 111: 82, # 'o' + 112: 96, # 'p' + 113: 202, # 'q' + 114: 91, # 'r' + 115: 79, # 's' + 116: 84, # 't' + 117: 104, # 'u' + 118: 105, # 'v' + 119: 97, # 'w' + 120: 98, # 'x' + 121: 92, # 'y' + 122: 203, # 'z' + 123: 253, # '{' + 124: 253, # '|' + 125: 253, # '}' + 126: 253, # '~' + 127: 253, # '\x7f' + 128: 209, # '\x80' + 129: 210, # '\x81' + 130: 211, # '\x82' + 131: 212, # '\x83' + 132: 213, # '\x84' + 133: 88, # '\x85' + 134: 214, # '\x86' + 135: 215, # '\x87' + 136: 216, # '\x88' + 137: 217, # '\x89' + 138: 218, # '\x8a' + 139: 219, # '\x8b' + 140: 220, # '\x8c' + 141: 118, # '\x8d' + 142: 221, # '\x8e' + 143: 222, # '\x8f' + 144: 223, # '\x90' + 145: 224, # '\x91' + 146: 99, # '\x92' + 147: 85, # '\x93' + 148: 83, # '\x94' + 149: 225, # '\x95' + 150: 226, # '\x96' + 151: 227, # '\x97' + 152: 228, # '\x98' + 153: 229, # '\x99' + 154: 230, # '\x9a' + 155: 231, # '\x9b' + 156: 232, # '\x9c' + 157: 233, # '\x9d' + 158: 234, # '\x9e' + 159: 235, # '\x9f' + 160: 236, # None + 161: 5, # 'à¸' + 162: 30, # 'ข' + 163: 237, # 'ฃ' + 164: 24, # 'ค' + 165: 238, # 'ฅ' + 166: 75, # 'ฆ' + 167: 8, # 'ง' + 168: 26, # 'จ' + 169: 52, # 'ฉ' + 170: 34, # 'ช' + 171: 51, # 'ซ' + 172: 119, # 'ฌ' + 173: 47, # 'à¸' + 174: 58, # 'ฎ' + 175: 57, # 'à¸' + 176: 49, # 'à¸' + 177: 53, # 'ฑ' + 178: 55, # 'ฒ' + 179: 43, # 'ณ' + 180: 20, # 'ด' + 181: 19, # 'ต' + 182: 44, # 'ถ' + 183: 14, # 'ท' + 184: 48, # 'ธ' + 185: 3, # 'น' + 186: 17, # 'บ' + 187: 25, # 'ป' + 188: 39, # 'ผ' + 189: 62, # 'à¸' + 190: 31, # 'พ' + 191: 54, # 'ฟ' + 192: 45, # 'ภ' + 193: 9, # 'ม' + 194: 16, # 'ย' + 195: 2, # 'ร' + 196: 61, # 'ฤ' + 197: 15, # 'ล' + 198: 239, # 'ฦ' + 199: 12, # 'ว' + 200: 42, # 'ศ' + 201: 46, # 'ษ' + 202: 18, # 'ส' + 203: 21, # 'ห' + 204: 76, # 'ฬ' + 205: 4, # 'อ' + 206: 66, # 'ฮ' + 207: 63, # 'ฯ' + 208: 22, # 'ะ' + 209: 10, # 'ั' + 210: 1, # 'า' + 211: 36, # 'ำ' + 212: 23, # 'ิ' + 213: 13, # 'ี' + 214: 40, # 'ึ' + 215: 27, # 'ื' + 216: 32, # 'ุ' + 217: 35, # 'ู' + 218: 86, # 'ฺ' + 219: 240, # None + 220: 241, # None + 221: 242, # None + 222: 243, # None + 223: 244, # '฿' + 224: 11, # 'เ' + 225: 28, # 'à¹' + 226: 41, # 'โ' + 227: 29, # 'ใ' + 228: 33, # 'ไ' + 229: 245, # 'ๅ' + 230: 50, # 'ๆ' + 231: 37, # '็' + 232: 6, # '่' + 233: 7, # '้' + 234: 67, # '๊' + 235: 77, # '๋' + 236: 38, # '์' + 237: 93, # 'à¹' + 238: 246, # '๎' + 239: 247, # 'à¹' + 240: 68, # 'à¹' + 241: 56, # '๑' + 242: 59, # '๒' + 243: 65, # '๓' + 244: 69, # '๔' + 245: 60, # '๕' + 246: 70, # '๖' + 247: 80, # '๗' + 248: 71, # '๘' + 249: 87, # '๙' + 250: 248, # '๚' + 251: 249, # '๛' + 252: 250, # None + 253: 251, # None + 254: 252, # None + 255: 253, # None +} + +TIS_620_THAI_MODEL = SingleByteCharSetModel(charset_name='TIS-620', + language='Thai', + char_to_order_map=TIS_620_THAI_CHAR_TO_ORDER, + language_model=THAI_LANG_MODEL, + typical_positive_ratio=0.926386, + keep_ascii_letters=False, + alphabet='à¸à¸‚ฃคฅฆงจฉชซฌà¸à¸Žà¸à¸à¸‘ฒณดตถทธนบปผà¸à¸žà¸Ÿà¸ à¸¡à¸¢à¸£à¸¤à¸¥à¸¦à¸§à¸¨à¸©à¸ªà¸«à¸¬à¸­à¸®à¸¯à¸°à¸±à¸²à¸³à¸´à¸µà¸¶à¸·à¸¸à¸¹à¸ºà¸¿à¹€à¹à¹‚ใไๅๆ็่้๊๋์à¹à¹Žà¹à¹à¹‘๒๓๔๕๖๗๘๙๚๛') + diff --git a/venv/Lib/site-packages/pip/_vendor/chardet/langturkishmodel.py b/venv/Lib/site-packages/pip/_vendor/chardet/langturkishmodel.py new file mode 100644 index 0000000..43f4230 --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/chardet/langturkishmodel.py @@ -0,0 +1,4383 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from pip._vendor.chardet.sbcharsetprober import SingleByteCharSetModel + + +# 3: Positive +# 2: Likely +# 1: Unlikely +# 0: Negative + +TURKISH_LANG_MODEL = { + 23: { # 'A' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 0, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 0, # 'K' + 49: 0, # 'L' + 20: 0, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 0, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 0, # 'Z' + 1: 3, # 'a' + 21: 0, # 'b' + 28: 0, # 'c' + 12: 2, # 'd' + 2: 3, # 'e' + 18: 0, # 'f' + 27: 1, # 'g' + 25: 1, # 'h' + 3: 1, # 'i' + 24: 0, # 'j' + 10: 2, # 'k' + 5: 1, # 'l' + 13: 1, # 'm' + 4: 1, # 'n' + 15: 0, # 'o' + 26: 0, # 'p' + 7: 1, # 'r' + 8: 1, # 's' + 9: 1, # 't' + 14: 1, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 3, # 'y' + 22: 0, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 1, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 0, # 'ü' + 30: 0, # 'ÄŸ' + 41: 0, # 'İ' + 6: 0, # 'ı' + 40: 0, # 'Åž' + 19: 0, # 'ÅŸ' + }, + 37: { # 'B' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 2, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 2, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 1, # 'K' + 49: 0, # 'L' + 20: 0, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 1, # 'P' + 44: 0, # 'R' + 35: 1, # 'S' + 31: 0, # 'T' + 51: 0, # 'U' + 38: 1, # 'V' + 62: 0, # 'W' + 43: 1, # 'Y' + 56: 0, # 'Z' + 1: 2, # 'a' + 21: 0, # 'b' + 28: 2, # 'c' + 12: 0, # 'd' + 2: 3, # 'e' + 18: 0, # 'f' + 27: 0, # 'g' + 25: 0, # 'h' + 3: 0, # 'i' + 24: 0, # 'j' + 10: 0, # 'k' + 5: 0, # 'l' + 13: 1, # 'm' + 4: 1, # 'n' + 15: 0, # 'o' + 26: 0, # 'p' + 7: 0, # 'r' + 8: 0, # 's' + 9: 0, # 't' + 14: 2, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 0, # 'y' + 22: 1, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 1, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 0, # 'ç' + 61: 0, # 'î' + 34: 1, # 'ö' + 17: 0, # 'ü' + 30: 0, # 'ÄŸ' + 41: 0, # 'İ' + 6: 0, # 'ı' + 40: 1, # 'Åž' + 19: 1, # 'ÅŸ' + }, + 47: { # 'C' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 1, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 0, # 'K' + 49: 1, # 'L' + 20: 0, # 'M' + 46: 1, # 'N' + 42: 0, # 'O' + 48: 1, # 'P' + 44: 1, # 'R' + 35: 0, # 'S' + 31: 0, # 'T' + 51: 0, # 'U' + 38: 1, # 'V' + 62: 0, # 'W' + 43: 1, # 'Y' + 56: 0, # 'Z' + 1: 3, # 'a' + 21: 0, # 'b' + 28: 2, # 'c' + 12: 0, # 'd' + 2: 3, # 'e' + 18: 0, # 'f' + 27: 0, # 'g' + 25: 0, # 'h' + 3: 0, # 'i' + 24: 2, # 'j' + 10: 1, # 'k' + 5: 2, # 'l' + 13: 2, # 'm' + 4: 2, # 'n' + 15: 1, # 'o' + 26: 0, # 'p' + 7: 2, # 'r' + 8: 0, # 's' + 9: 0, # 't' + 14: 3, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 0, # 'y' + 22: 2, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 1, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 1, # 'ç' + 61: 0, # 'î' + 34: 1, # 'ö' + 17: 0, # 'ü' + 30: 0, # 'ÄŸ' + 41: 1, # 'İ' + 6: 3, # 'ı' + 40: 0, # 'Åž' + 19: 0, # 'ÅŸ' + }, + 39: { # 'D' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 1, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 1, # 'K' + 49: 0, # 'L' + 20: 0, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 1, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 0, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 0, # 'Z' + 1: 2, # 'a' + 21: 0, # 'b' + 28: 2, # 'c' + 12: 0, # 'd' + 2: 2, # 'e' + 18: 0, # 'f' + 27: 0, # 'g' + 25: 0, # 'h' + 3: 0, # 'i' + 24: 0, # 'j' + 10: 0, # 'k' + 5: 1, # 'l' + 13: 3, # 'm' + 4: 0, # 'n' + 15: 1, # 'o' + 26: 0, # 'p' + 7: 0, # 'r' + 8: 0, # 's' + 9: 0, # 't' + 14: 1, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 0, # 'y' + 22: 1, # 'z' + 63: 0, # '·' + 54: 1, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 1, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 0, # 'ü' + 30: 1, # 'ÄŸ' + 41: 0, # 'İ' + 6: 1, # 'ı' + 40: 1, # 'Åž' + 19: 0, # 'ÅŸ' + }, + 29: { # 'E' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 1, # 'E' + 52: 0, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 3, # 'K' + 49: 0, # 'L' + 20: 1, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 0, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 0, # 'Z' + 1: 3, # 'a' + 21: 0, # 'b' + 28: 0, # 'c' + 12: 2, # 'd' + 2: 3, # 'e' + 18: 0, # 'f' + 27: 1, # 'g' + 25: 0, # 'h' + 3: 1, # 'i' + 24: 1, # 'j' + 10: 0, # 'k' + 5: 3, # 'l' + 13: 3, # 'm' + 4: 3, # 'n' + 15: 0, # 'o' + 26: 0, # 'p' + 7: 0, # 'r' + 8: 1, # 's' + 9: 1, # 't' + 14: 1, # 'u' + 32: 1, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 2, # 'y' + 22: 0, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 0, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 0, # 'ü' + 30: 0, # 'ÄŸ' + 41: 0, # 'İ' + 6: 3, # 'ı' + 40: 0, # 'Åž' + 19: 0, # 'ÅŸ' + }, + 52: { # 'F' + 23: 0, # 'A' + 37: 1, # 'B' + 47: 1, # 'C' + 39: 1, # 'D' + 29: 1, # 'E' + 52: 2, # 'F' + 36: 0, # 'G' + 45: 2, # 'H' + 53: 1, # 'I' + 60: 0, # 'J' + 16: 0, # 'K' + 49: 0, # 'L' + 20: 1, # 'M' + 46: 1, # 'N' + 42: 1, # 'O' + 48: 2, # 'P' + 44: 1, # 'R' + 35: 1, # 'S' + 31: 1, # 'T' + 51: 1, # 'U' + 38: 1, # 'V' + 62: 0, # 'W' + 43: 2, # 'Y' + 56: 0, # 'Z' + 1: 0, # 'a' + 21: 1, # 'b' + 28: 1, # 'c' + 12: 1, # 'd' + 2: 0, # 'e' + 18: 1, # 'f' + 27: 0, # 'g' + 25: 0, # 'h' + 3: 2, # 'i' + 24: 1, # 'j' + 10: 0, # 'k' + 5: 0, # 'l' + 13: 1, # 'm' + 4: 2, # 'n' + 15: 1, # 'o' + 26: 0, # 'p' + 7: 2, # 'r' + 8: 1, # 's' + 9: 1, # 't' + 14: 1, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 1, # 'y' + 22: 1, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 1, # 'Ö' + 55: 2, # 'Ü' + 59: 0, # 'â' + 33: 0, # 'ç' + 61: 0, # 'î' + 34: 2, # 'ö' + 17: 0, # 'ü' + 30: 1, # 'ÄŸ' + 41: 1, # 'İ' + 6: 2, # 'ı' + 40: 0, # 'Åž' + 19: 2, # 'ÅŸ' + }, + 36: { # 'G' + 23: 1, # 'A' + 37: 0, # 'B' + 47: 1, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 1, # 'F' + 36: 2, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 2, # 'K' + 49: 0, # 'L' + 20: 0, # 'M' + 46: 2, # 'N' + 42: 1, # 'O' + 48: 1, # 'P' + 44: 1, # 'R' + 35: 1, # 'S' + 31: 0, # 'T' + 51: 1, # 'U' + 38: 2, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 0, # 'Z' + 1: 3, # 'a' + 21: 0, # 'b' + 28: 1, # 'c' + 12: 0, # 'd' + 2: 3, # 'e' + 18: 0, # 'f' + 27: 0, # 'g' + 25: 0, # 'h' + 3: 0, # 'i' + 24: 1, # 'j' + 10: 1, # 'k' + 5: 0, # 'l' + 13: 3, # 'm' + 4: 2, # 'n' + 15: 0, # 'o' + 26: 1, # 'p' + 7: 0, # 'r' + 8: 1, # 's' + 9: 1, # 't' + 14: 3, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 1, # 'x' + 11: 0, # 'y' + 22: 2, # 'z' + 63: 0, # '·' + 54: 1, # 'Ç' + 50: 2, # 'Ö' + 55: 0, # 'Ü' + 59: 1, # 'â' + 33: 2, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 0, # 'ü' + 30: 1, # 'ÄŸ' + 41: 1, # 'İ' + 6: 2, # 'ı' + 40: 2, # 'Åž' + 19: 1, # 'ÅŸ' + }, + 45: { # 'H' + 23: 0, # 'A' + 37: 1, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 2, # 'F' + 36: 2, # 'G' + 45: 1, # 'H' + 53: 1, # 'I' + 60: 0, # 'J' + 16: 2, # 'K' + 49: 1, # 'L' + 20: 0, # 'M' + 46: 1, # 'N' + 42: 1, # 'O' + 48: 1, # 'P' + 44: 0, # 'R' + 35: 2, # 'S' + 31: 0, # 'T' + 51: 1, # 'U' + 38: 2, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 0, # 'Z' + 1: 3, # 'a' + 21: 0, # 'b' + 28: 2, # 'c' + 12: 0, # 'd' + 2: 3, # 'e' + 18: 0, # 'f' + 27: 0, # 'g' + 25: 0, # 'h' + 3: 2, # 'i' + 24: 0, # 'j' + 10: 1, # 'k' + 5: 0, # 'l' + 13: 2, # 'm' + 4: 0, # 'n' + 15: 1, # 'o' + 26: 1, # 'p' + 7: 1, # 'r' + 8: 0, # 's' + 9: 0, # 't' + 14: 3, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 0, # 'y' + 22: 2, # 'z' + 63: 0, # '·' + 54: 1, # 'Ç' + 50: 1, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 1, # 'ç' + 61: 0, # 'î' + 34: 1, # 'ö' + 17: 0, # 'ü' + 30: 2, # 'ÄŸ' + 41: 1, # 'İ' + 6: 0, # 'ı' + 40: 2, # 'Åž' + 19: 1, # 'ÅŸ' + }, + 53: { # 'I' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 1, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 2, # 'K' + 49: 0, # 'L' + 20: 0, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 1, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 0, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 0, # 'Z' + 1: 2, # 'a' + 21: 0, # 'b' + 28: 2, # 'c' + 12: 0, # 'd' + 2: 2, # 'e' + 18: 0, # 'f' + 27: 0, # 'g' + 25: 0, # 'h' + 3: 0, # 'i' + 24: 0, # 'j' + 10: 0, # 'k' + 5: 2, # 'l' + 13: 2, # 'm' + 4: 0, # 'n' + 15: 0, # 'o' + 26: 0, # 'p' + 7: 0, # 'r' + 8: 0, # 's' + 9: 0, # 't' + 14: 2, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 0, # 'y' + 22: 2, # 'z' + 63: 0, # '·' + 54: 1, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 2, # 'ç' + 61: 0, # 'î' + 34: 1, # 'ö' + 17: 0, # 'ü' + 30: 0, # 'ÄŸ' + 41: 0, # 'İ' + 6: 0, # 'ı' + 40: 1, # 'Åž' + 19: 1, # 'ÅŸ' + }, + 60: { # 'J' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 0, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 0, # 'K' + 49: 0, # 'L' + 20: 1, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 0, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 0, # 'Z' + 1: 0, # 'a' + 21: 1, # 'b' + 28: 0, # 'c' + 12: 1, # 'd' + 2: 0, # 'e' + 18: 0, # 'f' + 27: 0, # 'g' + 25: 0, # 'h' + 3: 1, # 'i' + 24: 0, # 'j' + 10: 0, # 'k' + 5: 0, # 'l' + 13: 0, # 'm' + 4: 1, # 'n' + 15: 0, # 'o' + 26: 0, # 'p' + 7: 0, # 'r' + 8: 1, # 's' + 9: 0, # 't' + 14: 0, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 0, # 'y' + 22: 0, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 0, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 0, # 'ü' + 30: 0, # 'ÄŸ' + 41: 0, # 'İ' + 6: 0, # 'ı' + 40: 0, # 'Åž' + 19: 0, # 'ÅŸ' + }, + 16: { # 'K' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 3, # 'E' + 52: 0, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 0, # 'K' + 49: 0, # 'L' + 20: 2, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 2, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 0, # 'Z' + 1: 2, # 'a' + 21: 3, # 'b' + 28: 0, # 'c' + 12: 3, # 'd' + 2: 1, # 'e' + 18: 3, # 'f' + 27: 3, # 'g' + 25: 3, # 'h' + 3: 3, # 'i' + 24: 2, # 'j' + 10: 3, # 'k' + 5: 0, # 'l' + 13: 0, # 'm' + 4: 3, # 'n' + 15: 0, # 'o' + 26: 1, # 'p' + 7: 3, # 'r' + 8: 3, # 's' + 9: 3, # 't' + 14: 0, # 'u' + 32: 3, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 2, # 'y' + 22: 1, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 0, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 2, # 'ü' + 30: 0, # 'ÄŸ' + 41: 1, # 'İ' + 6: 3, # 'ı' + 40: 0, # 'Åž' + 19: 0, # 'ÅŸ' + }, + 49: { # 'L' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 2, # 'E' + 52: 0, # 'F' + 36: 1, # 'G' + 45: 1, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 0, # 'K' + 49: 0, # 'L' + 20: 1, # 'M' + 46: 0, # 'N' + 42: 2, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 0, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 1, # 'Y' + 56: 0, # 'Z' + 1: 0, # 'a' + 21: 3, # 'b' + 28: 0, # 'c' + 12: 2, # 'd' + 2: 0, # 'e' + 18: 0, # 'f' + 27: 0, # 'g' + 25: 0, # 'h' + 3: 2, # 'i' + 24: 0, # 'j' + 10: 1, # 'k' + 5: 0, # 'l' + 13: 0, # 'm' + 4: 2, # 'n' + 15: 1, # 'o' + 26: 1, # 'p' + 7: 1, # 'r' + 8: 1, # 's' + 9: 1, # 't' + 14: 0, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 2, # 'y' + 22: 0, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 2, # 'Ü' + 59: 0, # 'â' + 33: 0, # 'ç' + 61: 0, # 'î' + 34: 1, # 'ö' + 17: 1, # 'ü' + 30: 1, # 'ÄŸ' + 41: 0, # 'İ' + 6: 2, # 'ı' + 40: 0, # 'Åž' + 19: 0, # 'ÅŸ' + }, + 20: { # 'M' + 23: 1, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 0, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 1, # 'J' + 16: 3, # 'K' + 49: 0, # 'L' + 20: 2, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 1, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 0, # 'Z' + 1: 3, # 'a' + 21: 2, # 'b' + 28: 0, # 'c' + 12: 3, # 'd' + 2: 3, # 'e' + 18: 0, # 'f' + 27: 1, # 'g' + 25: 1, # 'h' + 3: 2, # 'i' + 24: 2, # 'j' + 10: 2, # 'k' + 5: 2, # 'l' + 13: 3, # 'm' + 4: 3, # 'n' + 15: 0, # 'o' + 26: 1, # 'p' + 7: 3, # 'r' + 8: 0, # 's' + 9: 2, # 't' + 14: 3, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 2, # 'y' + 22: 0, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 3, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 0, # 'ü' + 30: 0, # 'ÄŸ' + 41: 0, # 'İ' + 6: 3, # 'ı' + 40: 0, # 'Åž' + 19: 0, # 'ÅŸ' + }, + 46: { # 'N' + 23: 0, # 'A' + 37: 1, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 1, # 'F' + 36: 1, # 'G' + 45: 1, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 2, # 'K' + 49: 0, # 'L' + 20: 0, # 'M' + 46: 1, # 'N' + 42: 0, # 'O' + 48: 0, # 'P' + 44: 1, # 'R' + 35: 1, # 'S' + 31: 0, # 'T' + 51: 1, # 'U' + 38: 2, # 'V' + 62: 0, # 'W' + 43: 1, # 'Y' + 56: 0, # 'Z' + 1: 3, # 'a' + 21: 0, # 'b' + 28: 2, # 'c' + 12: 0, # 'd' + 2: 3, # 'e' + 18: 0, # 'f' + 27: 1, # 'g' + 25: 0, # 'h' + 3: 0, # 'i' + 24: 2, # 'j' + 10: 1, # 'k' + 5: 1, # 'l' + 13: 3, # 'm' + 4: 2, # 'n' + 15: 1, # 'o' + 26: 1, # 'p' + 7: 1, # 'r' + 8: 0, # 's' + 9: 0, # 't' + 14: 3, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 1, # 'x' + 11: 1, # 'y' + 22: 2, # 'z' + 63: 0, # '·' + 54: 1, # 'Ç' + 50: 1, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 0, # 'ç' + 61: 0, # 'î' + 34: 1, # 'ö' + 17: 0, # 'ü' + 30: 0, # 'ÄŸ' + 41: 1, # 'İ' + 6: 2, # 'ı' + 40: 1, # 'Åž' + 19: 1, # 'ÅŸ' + }, + 42: { # 'O' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 1, # 'F' + 36: 0, # 'G' + 45: 1, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 2, # 'K' + 49: 1, # 'L' + 20: 0, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 2, # 'P' + 44: 1, # 'R' + 35: 1, # 'S' + 31: 0, # 'T' + 51: 1, # 'U' + 38: 1, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 0, # 'Z' + 1: 3, # 'a' + 21: 0, # 'b' + 28: 2, # 'c' + 12: 0, # 'd' + 2: 2, # 'e' + 18: 0, # 'f' + 27: 0, # 'g' + 25: 0, # 'h' + 3: 0, # 'i' + 24: 0, # 'j' + 10: 0, # 'k' + 5: 3, # 'l' + 13: 3, # 'm' + 4: 0, # 'n' + 15: 1, # 'o' + 26: 0, # 'p' + 7: 0, # 'r' + 8: 0, # 's' + 9: 0, # 't' + 14: 2, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 0, # 'y' + 22: 2, # 'z' + 63: 0, # '·' + 54: 2, # 'Ç' + 50: 1, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 2, # 'ç' + 61: 0, # 'î' + 34: 1, # 'ö' + 17: 0, # 'ü' + 30: 1, # 'ÄŸ' + 41: 2, # 'İ' + 6: 1, # 'ı' + 40: 1, # 'Åž' + 19: 1, # 'ÅŸ' + }, + 48: { # 'P' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 2, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 2, # 'F' + 36: 1, # 'G' + 45: 1, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 2, # 'K' + 49: 0, # 'L' + 20: 0, # 'M' + 46: 1, # 'N' + 42: 1, # 'O' + 48: 1, # 'P' + 44: 0, # 'R' + 35: 1, # 'S' + 31: 0, # 'T' + 51: 0, # 'U' + 38: 1, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 0, # 'Z' + 1: 2, # 'a' + 21: 0, # 'b' + 28: 2, # 'c' + 12: 0, # 'd' + 2: 3, # 'e' + 18: 0, # 'f' + 27: 0, # 'g' + 25: 0, # 'h' + 3: 0, # 'i' + 24: 0, # 'j' + 10: 1, # 'k' + 5: 0, # 'l' + 13: 2, # 'm' + 4: 0, # 'n' + 15: 2, # 'o' + 26: 0, # 'p' + 7: 0, # 'r' + 8: 0, # 's' + 9: 0, # 't' + 14: 2, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 2, # 'x' + 11: 0, # 'y' + 22: 2, # 'z' + 63: 0, # '·' + 54: 1, # 'Ç' + 50: 2, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 0, # 'ç' + 61: 0, # 'î' + 34: 2, # 'ö' + 17: 0, # 'ü' + 30: 1, # 'ÄŸ' + 41: 1, # 'İ' + 6: 0, # 'ı' + 40: 2, # 'Åž' + 19: 1, # 'ÅŸ' + }, + 44: { # 'R' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 1, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 1, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 3, # 'K' + 49: 0, # 'L' + 20: 0, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 1, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 0, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 1, # 'Y' + 56: 0, # 'Z' + 1: 3, # 'a' + 21: 1, # 'b' + 28: 1, # 'c' + 12: 0, # 'd' + 2: 2, # 'e' + 18: 0, # 'f' + 27: 0, # 'g' + 25: 0, # 'h' + 3: 0, # 'i' + 24: 0, # 'j' + 10: 1, # 'k' + 5: 2, # 'l' + 13: 2, # 'm' + 4: 0, # 'n' + 15: 1, # 'o' + 26: 0, # 'p' + 7: 0, # 'r' + 8: 0, # 's' + 9: 0, # 't' + 14: 2, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 1, # 'y' + 22: 2, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 1, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 1, # 'ç' + 61: 0, # 'î' + 34: 1, # 'ö' + 17: 1, # 'ü' + 30: 1, # 'ÄŸ' + 41: 0, # 'İ' + 6: 2, # 'ı' + 40: 1, # 'Åž' + 19: 1, # 'ÅŸ' + }, + 35: { # 'S' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 1, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 1, # 'F' + 36: 1, # 'G' + 45: 1, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 3, # 'K' + 49: 1, # 'L' + 20: 1, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 1, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 0, # 'T' + 51: 1, # 'U' + 38: 1, # 'V' + 62: 0, # 'W' + 43: 1, # 'Y' + 56: 0, # 'Z' + 1: 3, # 'a' + 21: 0, # 'b' + 28: 2, # 'c' + 12: 0, # 'd' + 2: 3, # 'e' + 18: 0, # 'f' + 27: 0, # 'g' + 25: 0, # 'h' + 3: 0, # 'i' + 24: 0, # 'j' + 10: 1, # 'k' + 5: 1, # 'l' + 13: 2, # 'm' + 4: 1, # 'n' + 15: 0, # 'o' + 26: 0, # 'p' + 7: 0, # 'r' + 8: 0, # 's' + 9: 1, # 't' + 14: 2, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 0, # 'y' + 22: 1, # 'z' + 63: 0, # '·' + 54: 2, # 'Ç' + 50: 2, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 3, # 'ç' + 61: 0, # 'î' + 34: 1, # 'ö' + 17: 0, # 'ü' + 30: 0, # 'ÄŸ' + 41: 0, # 'İ' + 6: 3, # 'ı' + 40: 2, # 'Åž' + 19: 1, # 'ÅŸ' + }, + 31: { # 'T' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 0, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 1, # 'J' + 16: 2, # 'K' + 49: 0, # 'L' + 20: 1, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 2, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 0, # 'Z' + 1: 3, # 'a' + 21: 2, # 'b' + 28: 0, # 'c' + 12: 1, # 'd' + 2: 3, # 'e' + 18: 2, # 'f' + 27: 2, # 'g' + 25: 0, # 'h' + 3: 1, # 'i' + 24: 1, # 'j' + 10: 2, # 'k' + 5: 2, # 'l' + 13: 3, # 'm' + 4: 3, # 'n' + 15: 0, # 'o' + 26: 2, # 'p' + 7: 2, # 'r' + 8: 0, # 's' + 9: 2, # 't' + 14: 2, # 'u' + 32: 1, # 'v' + 57: 1, # 'w' + 58: 1, # 'x' + 11: 2, # 'y' + 22: 0, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 0, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 1, # 'ü' + 30: 0, # 'ÄŸ' + 41: 0, # 'İ' + 6: 3, # 'ı' + 40: 0, # 'Åž' + 19: 0, # 'ÅŸ' + }, + 51: { # 'U' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 1, # 'F' + 36: 1, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 1, # 'K' + 49: 0, # 'L' + 20: 0, # 'M' + 46: 1, # 'N' + 42: 0, # 'O' + 48: 1, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 0, # 'T' + 51: 1, # 'U' + 38: 1, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 0, # 'Z' + 1: 3, # 'a' + 21: 0, # 'b' + 28: 1, # 'c' + 12: 0, # 'd' + 2: 3, # 'e' + 18: 0, # 'f' + 27: 2, # 'g' + 25: 0, # 'h' + 3: 0, # 'i' + 24: 0, # 'j' + 10: 1, # 'k' + 5: 1, # 'l' + 13: 3, # 'm' + 4: 2, # 'n' + 15: 0, # 'o' + 26: 1, # 'p' + 7: 0, # 'r' + 8: 0, # 's' + 9: 0, # 't' + 14: 2, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 0, # 'y' + 22: 2, # 'z' + 63: 0, # '·' + 54: 1, # 'Ç' + 50: 1, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 0, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 0, # 'ü' + 30: 1, # 'ÄŸ' + 41: 1, # 'İ' + 6: 2, # 'ı' + 40: 0, # 'Åž' + 19: 1, # 'ÅŸ' + }, + 38: { # 'V' + 23: 1, # 'A' + 37: 1, # 'B' + 47: 1, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 2, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 3, # 'K' + 49: 0, # 'L' + 20: 3, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 1, # 'P' + 44: 1, # 'R' + 35: 0, # 'S' + 31: 0, # 'T' + 51: 1, # 'U' + 38: 1, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 0, # 'Z' + 1: 3, # 'a' + 21: 0, # 'b' + 28: 2, # 'c' + 12: 0, # 'd' + 2: 3, # 'e' + 18: 0, # 'f' + 27: 0, # 'g' + 25: 0, # 'h' + 3: 0, # 'i' + 24: 0, # 'j' + 10: 0, # 'k' + 5: 2, # 'l' + 13: 2, # 'm' + 4: 0, # 'n' + 15: 2, # 'o' + 26: 0, # 'p' + 7: 0, # 'r' + 8: 0, # 's' + 9: 1, # 't' + 14: 3, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 1, # 'y' + 22: 2, # 'z' + 63: 0, # '·' + 54: 1, # 'Ç' + 50: 1, # 'Ö' + 55: 0, # 'Ü' + 59: 1, # 'â' + 33: 2, # 'ç' + 61: 0, # 'î' + 34: 1, # 'ö' + 17: 0, # 'ü' + 30: 1, # 'ÄŸ' + 41: 1, # 'İ' + 6: 3, # 'ı' + 40: 2, # 'Åž' + 19: 1, # 'ÅŸ' + }, + 62: { # 'W' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 0, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 0, # 'K' + 49: 0, # 'L' + 20: 0, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 0, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 0, # 'Z' + 1: 0, # 'a' + 21: 0, # 'b' + 28: 0, # 'c' + 12: 0, # 'd' + 2: 0, # 'e' + 18: 0, # 'f' + 27: 0, # 'g' + 25: 0, # 'h' + 3: 0, # 'i' + 24: 0, # 'j' + 10: 0, # 'k' + 5: 0, # 'l' + 13: 0, # 'm' + 4: 0, # 'n' + 15: 0, # 'o' + 26: 0, # 'p' + 7: 0, # 'r' + 8: 0, # 's' + 9: 0, # 't' + 14: 0, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 0, # 'y' + 22: 0, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 0, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 0, # 'ü' + 30: 0, # 'ÄŸ' + 41: 0, # 'İ' + 6: 0, # 'ı' + 40: 0, # 'Åž' + 19: 0, # 'ÅŸ' + }, + 43: { # 'Y' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 1, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 2, # 'F' + 36: 0, # 'G' + 45: 1, # 'H' + 53: 1, # 'I' + 60: 0, # 'J' + 16: 2, # 'K' + 49: 0, # 'L' + 20: 0, # 'M' + 46: 2, # 'N' + 42: 0, # 'O' + 48: 2, # 'P' + 44: 1, # 'R' + 35: 1, # 'S' + 31: 0, # 'T' + 51: 1, # 'U' + 38: 2, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 0, # 'Z' + 1: 3, # 'a' + 21: 0, # 'b' + 28: 2, # 'c' + 12: 0, # 'd' + 2: 2, # 'e' + 18: 0, # 'f' + 27: 0, # 'g' + 25: 0, # 'h' + 3: 0, # 'i' + 24: 1, # 'j' + 10: 1, # 'k' + 5: 1, # 'l' + 13: 3, # 'm' + 4: 0, # 'n' + 15: 2, # 'o' + 26: 0, # 'p' + 7: 0, # 'r' + 8: 0, # 's' + 9: 0, # 't' + 14: 3, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 1, # 'x' + 11: 0, # 'y' + 22: 2, # 'z' + 63: 0, # '·' + 54: 1, # 'Ç' + 50: 2, # 'Ö' + 55: 1, # 'Ü' + 59: 1, # 'â' + 33: 0, # 'ç' + 61: 0, # 'î' + 34: 1, # 'ö' + 17: 0, # 'ü' + 30: 1, # 'ÄŸ' + 41: 1, # 'İ' + 6: 0, # 'ı' + 40: 2, # 'Åž' + 19: 1, # 'ÅŸ' + }, + 56: { # 'Z' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 0, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 0, # 'K' + 49: 0, # 'L' + 20: 0, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 0, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 2, # 'Z' + 1: 2, # 'a' + 21: 1, # 'b' + 28: 0, # 'c' + 12: 0, # 'd' + 2: 2, # 'e' + 18: 0, # 'f' + 27: 0, # 'g' + 25: 0, # 'h' + 3: 2, # 'i' + 24: 1, # 'j' + 10: 0, # 'k' + 5: 0, # 'l' + 13: 1, # 'm' + 4: 1, # 'n' + 15: 0, # 'o' + 26: 0, # 'p' + 7: 1, # 'r' + 8: 1, # 's' + 9: 0, # 't' + 14: 2, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 0, # 'y' + 22: 0, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 0, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 1, # 'ü' + 30: 0, # 'ÄŸ' + 41: 0, # 'İ' + 6: 1, # 'ı' + 40: 0, # 'Åž' + 19: 0, # 'ÅŸ' + }, + 1: { # 'a' + 23: 3, # 'A' + 37: 0, # 'B' + 47: 1, # 'C' + 39: 0, # 'D' + 29: 3, # 'E' + 52: 0, # 'F' + 36: 1, # 'G' + 45: 1, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 0, # 'K' + 49: 0, # 'L' + 20: 3, # 'M' + 46: 1, # 'N' + 42: 0, # 'O' + 48: 1, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 3, # 'T' + 51: 0, # 'U' + 38: 1, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 2, # 'Z' + 1: 2, # 'a' + 21: 3, # 'b' + 28: 0, # 'c' + 12: 3, # 'd' + 2: 2, # 'e' + 18: 3, # 'f' + 27: 3, # 'g' + 25: 3, # 'h' + 3: 3, # 'i' + 24: 3, # 'j' + 10: 3, # 'k' + 5: 0, # 'l' + 13: 2, # 'm' + 4: 3, # 'n' + 15: 1, # 'o' + 26: 3, # 'p' + 7: 3, # 'r' + 8: 3, # 's' + 9: 3, # 't' + 14: 3, # 'u' + 32: 3, # 'v' + 57: 2, # 'w' + 58: 0, # 'x' + 11: 3, # 'y' + 22: 0, # 'z' + 63: 1, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 1, # 'ç' + 61: 1, # 'î' + 34: 1, # 'ö' + 17: 3, # 'ü' + 30: 0, # 'ÄŸ' + 41: 0, # 'İ' + 6: 3, # 'ı' + 40: 0, # 'Åž' + 19: 1, # 'ÅŸ' + }, + 21: { # 'b' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 0, # 'F' + 36: 1, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 1, # 'J' + 16: 2, # 'K' + 49: 0, # 'L' + 20: 2, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 1, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 1, # 'Y' + 56: 0, # 'Z' + 1: 3, # 'a' + 21: 2, # 'b' + 28: 0, # 'c' + 12: 3, # 'd' + 2: 3, # 'e' + 18: 0, # 'f' + 27: 3, # 'g' + 25: 1, # 'h' + 3: 3, # 'i' + 24: 2, # 'j' + 10: 3, # 'k' + 5: 3, # 'l' + 13: 3, # 'm' + 4: 3, # 'n' + 15: 0, # 'o' + 26: 3, # 'p' + 7: 1, # 'r' + 8: 2, # 's' + 9: 2, # 't' + 14: 2, # 'u' + 32: 1, # 'v' + 57: 0, # 'w' + 58: 1, # 'x' + 11: 3, # 'y' + 22: 0, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 1, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 0, # 'ü' + 30: 1, # 'ÄŸ' + 41: 0, # 'İ' + 6: 2, # 'ı' + 40: 0, # 'Åž' + 19: 0, # 'ÅŸ' + }, + 28: { # 'c' + 23: 0, # 'A' + 37: 1, # 'B' + 47: 1, # 'C' + 39: 1, # 'D' + 29: 2, # 'E' + 52: 0, # 'F' + 36: 2, # 'G' + 45: 2, # 'H' + 53: 1, # 'I' + 60: 0, # 'J' + 16: 0, # 'K' + 49: 0, # 'L' + 20: 2, # 'M' + 46: 1, # 'N' + 42: 1, # 'O' + 48: 2, # 'P' + 44: 1, # 'R' + 35: 1, # 'S' + 31: 2, # 'T' + 51: 2, # 'U' + 38: 2, # 'V' + 62: 0, # 'W' + 43: 3, # 'Y' + 56: 0, # 'Z' + 1: 1, # 'a' + 21: 1, # 'b' + 28: 2, # 'c' + 12: 2, # 'd' + 2: 1, # 'e' + 18: 1, # 'f' + 27: 2, # 'g' + 25: 2, # 'h' + 3: 3, # 'i' + 24: 1, # 'j' + 10: 3, # 'k' + 5: 0, # 'l' + 13: 2, # 'm' + 4: 3, # 'n' + 15: 2, # 'o' + 26: 2, # 'p' + 7: 3, # 'r' + 8: 3, # 's' + 9: 3, # 't' + 14: 1, # 'u' + 32: 0, # 'v' + 57: 1, # 'w' + 58: 0, # 'x' + 11: 2, # 'y' + 22: 1, # 'z' + 63: 1, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 1, # 'Ü' + 59: 0, # 'â' + 33: 0, # 'ç' + 61: 1, # 'î' + 34: 2, # 'ö' + 17: 2, # 'ü' + 30: 2, # 'ÄŸ' + 41: 1, # 'İ' + 6: 3, # 'ı' + 40: 0, # 'Åž' + 19: 2, # 'ÅŸ' + }, + 12: { # 'd' + 23: 1, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 0, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 2, # 'J' + 16: 3, # 'K' + 49: 0, # 'L' + 20: 3, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 1, # 'S' + 31: 1, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 0, # 'Z' + 1: 3, # 'a' + 21: 2, # 'b' + 28: 1, # 'c' + 12: 3, # 'd' + 2: 3, # 'e' + 18: 1, # 'f' + 27: 3, # 'g' + 25: 3, # 'h' + 3: 2, # 'i' + 24: 3, # 'j' + 10: 2, # 'k' + 5: 3, # 'l' + 13: 3, # 'm' + 4: 3, # 'n' + 15: 1, # 'o' + 26: 2, # 'p' + 7: 3, # 'r' + 8: 2, # 's' + 9: 2, # 't' + 14: 3, # 'u' + 32: 1, # 'v' + 57: 0, # 'w' + 58: 1, # 'x' + 11: 3, # 'y' + 22: 1, # 'z' + 63: 1, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 0, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 1, # 'ü' + 30: 0, # 'ÄŸ' + 41: 0, # 'İ' + 6: 2, # 'ı' + 40: 0, # 'Åž' + 19: 0, # 'ÅŸ' + }, + 2: { # 'e' + 23: 2, # 'A' + 37: 0, # 'B' + 47: 2, # 'C' + 39: 0, # 'D' + 29: 3, # 'E' + 52: 1, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 1, # 'K' + 49: 0, # 'L' + 20: 3, # 'M' + 46: 1, # 'N' + 42: 0, # 'O' + 48: 1, # 'P' + 44: 1, # 'R' + 35: 0, # 'S' + 31: 3, # 'T' + 51: 0, # 'U' + 38: 1, # 'V' + 62: 0, # 'W' + 43: 1, # 'Y' + 56: 0, # 'Z' + 1: 3, # 'a' + 21: 3, # 'b' + 28: 0, # 'c' + 12: 3, # 'd' + 2: 2, # 'e' + 18: 3, # 'f' + 27: 3, # 'g' + 25: 3, # 'h' + 3: 3, # 'i' + 24: 3, # 'j' + 10: 3, # 'k' + 5: 0, # 'l' + 13: 2, # 'm' + 4: 3, # 'n' + 15: 1, # 'o' + 26: 3, # 'p' + 7: 3, # 'r' + 8: 3, # 's' + 9: 3, # 't' + 14: 3, # 'u' + 32: 3, # 'v' + 57: 2, # 'w' + 58: 0, # 'x' + 11: 3, # 'y' + 22: 1, # 'z' + 63: 1, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 1, # 'ç' + 61: 0, # 'î' + 34: 1, # 'ö' + 17: 3, # 'ü' + 30: 0, # 'ÄŸ' + 41: 0, # 'İ' + 6: 3, # 'ı' + 40: 0, # 'Åž' + 19: 0, # 'ÅŸ' + }, + 18: { # 'f' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 0, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 2, # 'K' + 49: 0, # 'L' + 20: 2, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 2, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 0, # 'Z' + 1: 3, # 'a' + 21: 1, # 'b' + 28: 0, # 'c' + 12: 3, # 'd' + 2: 3, # 'e' + 18: 2, # 'f' + 27: 1, # 'g' + 25: 1, # 'h' + 3: 1, # 'i' + 24: 1, # 'j' + 10: 1, # 'k' + 5: 3, # 'l' + 13: 3, # 'm' + 4: 3, # 'n' + 15: 0, # 'o' + 26: 2, # 'p' + 7: 1, # 'r' + 8: 3, # 's' + 9: 3, # 't' + 14: 1, # 'u' + 32: 2, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 1, # 'y' + 22: 0, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 1, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 1, # 'ü' + 30: 0, # 'ÄŸ' + 41: 0, # 'İ' + 6: 1, # 'ı' + 40: 0, # 'Åž' + 19: 0, # 'ÅŸ' + }, + 27: { # 'g' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 0, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 3, # 'K' + 49: 0, # 'L' + 20: 0, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 1, # 'S' + 31: 1, # 'T' + 51: 0, # 'U' + 38: 2, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 0, # 'Z' + 1: 3, # 'a' + 21: 1, # 'b' + 28: 0, # 'c' + 12: 1, # 'd' + 2: 3, # 'e' + 18: 0, # 'f' + 27: 2, # 'g' + 25: 1, # 'h' + 3: 2, # 'i' + 24: 3, # 'j' + 10: 2, # 'k' + 5: 3, # 'l' + 13: 3, # 'm' + 4: 2, # 'n' + 15: 0, # 'o' + 26: 1, # 'p' + 7: 2, # 'r' + 8: 2, # 's' + 9: 3, # 't' + 14: 3, # 'u' + 32: 1, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 1, # 'y' + 22: 0, # 'z' + 63: 1, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 0, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 0, # 'ü' + 30: 0, # 'ÄŸ' + 41: 0, # 'İ' + 6: 2, # 'ı' + 40: 0, # 'Åž' + 19: 0, # 'ÅŸ' + }, + 25: { # 'h' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 0, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 2, # 'K' + 49: 0, # 'L' + 20: 0, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 0, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 0, # 'Z' + 1: 3, # 'a' + 21: 0, # 'b' + 28: 0, # 'c' + 12: 2, # 'd' + 2: 3, # 'e' + 18: 0, # 'f' + 27: 1, # 'g' + 25: 2, # 'h' + 3: 2, # 'i' + 24: 3, # 'j' + 10: 3, # 'k' + 5: 3, # 'l' + 13: 3, # 'm' + 4: 3, # 'n' + 15: 1, # 'o' + 26: 1, # 'p' + 7: 3, # 'r' + 8: 3, # 's' + 9: 2, # 't' + 14: 3, # 'u' + 32: 2, # 'v' + 57: 1, # 'w' + 58: 0, # 'x' + 11: 1, # 'y' + 22: 0, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 0, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 0, # 'ü' + 30: 0, # 'ÄŸ' + 41: 0, # 'İ' + 6: 3, # 'ı' + 40: 0, # 'Åž' + 19: 0, # 'ÅŸ' + }, + 3: { # 'i' + 23: 2, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 0, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 1, # 'J' + 16: 3, # 'K' + 49: 0, # 'L' + 20: 3, # 'M' + 46: 0, # 'N' + 42: 1, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 1, # 'S' + 31: 2, # 'T' + 51: 0, # 'U' + 38: 1, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 0, # 'Z' + 1: 3, # 'a' + 21: 2, # 'b' + 28: 0, # 'c' + 12: 3, # 'd' + 2: 3, # 'e' + 18: 2, # 'f' + 27: 3, # 'g' + 25: 1, # 'h' + 3: 3, # 'i' + 24: 2, # 'j' + 10: 3, # 'k' + 5: 3, # 'l' + 13: 3, # 'm' + 4: 3, # 'n' + 15: 1, # 'o' + 26: 3, # 'p' + 7: 3, # 'r' + 8: 3, # 's' + 9: 3, # 't' + 14: 3, # 'u' + 32: 2, # 'v' + 57: 1, # 'w' + 58: 1, # 'x' + 11: 3, # 'y' + 22: 1, # 'z' + 63: 1, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 1, # 'Ü' + 59: 0, # 'â' + 33: 2, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 3, # 'ü' + 30: 0, # 'ÄŸ' + 41: 1, # 'İ' + 6: 2, # 'ı' + 40: 0, # 'Åž' + 19: 0, # 'ÅŸ' + }, + 24: { # 'j' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 0, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 1, # 'J' + 16: 2, # 'K' + 49: 0, # 'L' + 20: 2, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 1, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 1, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 1, # 'Z' + 1: 3, # 'a' + 21: 1, # 'b' + 28: 1, # 'c' + 12: 3, # 'd' + 2: 3, # 'e' + 18: 2, # 'f' + 27: 1, # 'g' + 25: 1, # 'h' + 3: 2, # 'i' + 24: 1, # 'j' + 10: 2, # 'k' + 5: 2, # 'l' + 13: 3, # 'm' + 4: 2, # 'n' + 15: 0, # 'o' + 26: 1, # 'p' + 7: 2, # 'r' + 8: 3, # 's' + 9: 2, # 't' + 14: 3, # 'u' + 32: 2, # 'v' + 57: 0, # 'w' + 58: 2, # 'x' + 11: 1, # 'y' + 22: 0, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 1, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 1, # 'ü' + 30: 0, # 'ÄŸ' + 41: 0, # 'İ' + 6: 3, # 'ı' + 40: 0, # 'Åž' + 19: 0, # 'ÅŸ' + }, + 10: { # 'k' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 0, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 3, # 'K' + 49: 0, # 'L' + 20: 2, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 3, # 'T' + 51: 0, # 'U' + 38: 1, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 1, # 'Z' + 1: 3, # 'a' + 21: 2, # 'b' + 28: 0, # 'c' + 12: 2, # 'd' + 2: 3, # 'e' + 18: 1, # 'f' + 27: 2, # 'g' + 25: 2, # 'h' + 3: 3, # 'i' + 24: 2, # 'j' + 10: 2, # 'k' + 5: 3, # 'l' + 13: 3, # 'm' + 4: 3, # 'n' + 15: 0, # 'o' + 26: 3, # 'p' + 7: 2, # 'r' + 8: 2, # 's' + 9: 2, # 't' + 14: 3, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 1, # 'x' + 11: 3, # 'y' + 22: 0, # 'z' + 63: 1, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 3, # 'ç' + 61: 0, # 'î' + 34: 1, # 'ö' + 17: 3, # 'ü' + 30: 1, # 'ÄŸ' + 41: 0, # 'İ' + 6: 3, # 'ı' + 40: 0, # 'Åž' + 19: 1, # 'ÅŸ' + }, + 5: { # 'l' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 3, # 'E' + 52: 0, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 0, # 'K' + 49: 0, # 'L' + 20: 2, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 1, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 0, # 'Z' + 1: 0, # 'a' + 21: 3, # 'b' + 28: 0, # 'c' + 12: 3, # 'd' + 2: 1, # 'e' + 18: 3, # 'f' + 27: 3, # 'g' + 25: 2, # 'h' + 3: 3, # 'i' + 24: 2, # 'j' + 10: 3, # 'k' + 5: 1, # 'l' + 13: 1, # 'm' + 4: 3, # 'n' + 15: 0, # 'o' + 26: 2, # 'p' + 7: 3, # 'r' + 8: 3, # 's' + 9: 3, # 't' + 14: 2, # 'u' + 32: 2, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 3, # 'y' + 22: 0, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 1, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 2, # 'ü' + 30: 0, # 'ÄŸ' + 41: 0, # 'İ' + 6: 3, # 'ı' + 40: 0, # 'Åž' + 19: 0, # 'ÅŸ' + }, + 13: { # 'm' + 23: 1, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 3, # 'E' + 52: 0, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 0, # 'K' + 49: 0, # 'L' + 20: 3, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 3, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 1, # 'Y' + 56: 0, # 'Z' + 1: 2, # 'a' + 21: 3, # 'b' + 28: 0, # 'c' + 12: 3, # 'd' + 2: 2, # 'e' + 18: 3, # 'f' + 27: 3, # 'g' + 25: 3, # 'h' + 3: 3, # 'i' + 24: 3, # 'j' + 10: 3, # 'k' + 5: 0, # 'l' + 13: 2, # 'm' + 4: 3, # 'n' + 15: 1, # 'o' + 26: 2, # 'p' + 7: 3, # 'r' + 8: 3, # 's' + 9: 3, # 't' + 14: 2, # 'u' + 32: 2, # 'v' + 57: 1, # 'w' + 58: 0, # 'x' + 11: 3, # 'y' + 22: 0, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 0, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 3, # 'ü' + 30: 0, # 'ÄŸ' + 41: 0, # 'İ' + 6: 3, # 'ı' + 40: 0, # 'Åž' + 19: 1, # 'ÅŸ' + }, + 4: { # 'n' + 23: 1, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 0, # 'F' + 36: 0, # 'G' + 45: 1, # 'H' + 53: 0, # 'I' + 60: 2, # 'J' + 16: 3, # 'K' + 49: 0, # 'L' + 20: 3, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 2, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 0, # 'Z' + 1: 3, # 'a' + 21: 2, # 'b' + 28: 1, # 'c' + 12: 3, # 'd' + 2: 3, # 'e' + 18: 1, # 'f' + 27: 2, # 'g' + 25: 3, # 'h' + 3: 2, # 'i' + 24: 2, # 'j' + 10: 3, # 'k' + 5: 3, # 'l' + 13: 3, # 'm' + 4: 3, # 'n' + 15: 1, # 'o' + 26: 3, # 'p' + 7: 2, # 'r' + 8: 3, # 's' + 9: 3, # 't' + 14: 3, # 'u' + 32: 2, # 'v' + 57: 0, # 'w' + 58: 2, # 'x' + 11: 3, # 'y' + 22: 0, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 1, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 2, # 'ü' + 30: 0, # 'ÄŸ' + 41: 0, # 'İ' + 6: 1, # 'ı' + 40: 0, # 'Åž' + 19: 0, # 'ÅŸ' + }, + 15: { # 'o' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 1, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 2, # 'F' + 36: 1, # 'G' + 45: 1, # 'H' + 53: 1, # 'I' + 60: 0, # 'J' + 16: 3, # 'K' + 49: 2, # 'L' + 20: 0, # 'M' + 46: 2, # 'N' + 42: 1, # 'O' + 48: 2, # 'P' + 44: 1, # 'R' + 35: 0, # 'S' + 31: 0, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 0, # 'Z' + 1: 3, # 'a' + 21: 0, # 'b' + 28: 2, # 'c' + 12: 0, # 'd' + 2: 3, # 'e' + 18: 0, # 'f' + 27: 0, # 'g' + 25: 0, # 'h' + 3: 1, # 'i' + 24: 2, # 'j' + 10: 1, # 'k' + 5: 3, # 'l' + 13: 3, # 'm' + 4: 2, # 'n' + 15: 2, # 'o' + 26: 0, # 'p' + 7: 1, # 'r' + 8: 0, # 's' + 9: 0, # 't' + 14: 3, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 2, # 'x' + 11: 0, # 'y' + 22: 2, # 'z' + 63: 0, # '·' + 54: 1, # 'Ç' + 50: 2, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 3, # 'ç' + 61: 0, # 'î' + 34: 1, # 'ö' + 17: 0, # 'ü' + 30: 2, # 'ÄŸ' + 41: 2, # 'İ' + 6: 3, # 'ı' + 40: 2, # 'Åž' + 19: 2, # 'ÅŸ' + }, + 26: { # 'p' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 0, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 3, # 'K' + 49: 0, # 'L' + 20: 1, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 0, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 0, # 'Z' + 1: 3, # 'a' + 21: 1, # 'b' + 28: 0, # 'c' + 12: 1, # 'd' + 2: 3, # 'e' + 18: 0, # 'f' + 27: 1, # 'g' + 25: 1, # 'h' + 3: 2, # 'i' + 24: 3, # 'j' + 10: 1, # 'k' + 5: 3, # 'l' + 13: 3, # 'm' + 4: 2, # 'n' + 15: 0, # 'o' + 26: 2, # 'p' + 7: 2, # 'r' + 8: 1, # 's' + 9: 1, # 't' + 14: 3, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 1, # 'x' + 11: 1, # 'y' + 22: 0, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 3, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 1, # 'ü' + 30: 0, # 'ÄŸ' + 41: 0, # 'İ' + 6: 3, # 'ı' + 40: 0, # 'Åž' + 19: 0, # 'ÅŸ' + }, + 7: { # 'r' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 1, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 2, # 'J' + 16: 3, # 'K' + 49: 0, # 'L' + 20: 2, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 2, # 'T' + 51: 1, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 1, # 'Z' + 1: 3, # 'a' + 21: 1, # 'b' + 28: 0, # 'c' + 12: 3, # 'd' + 2: 3, # 'e' + 18: 0, # 'f' + 27: 2, # 'g' + 25: 3, # 'h' + 3: 2, # 'i' + 24: 2, # 'j' + 10: 3, # 'k' + 5: 3, # 'l' + 13: 3, # 'm' + 4: 3, # 'n' + 15: 0, # 'o' + 26: 2, # 'p' + 7: 3, # 'r' + 8: 3, # 's' + 9: 3, # 't' + 14: 3, # 'u' + 32: 2, # 'v' + 57: 0, # 'w' + 58: 1, # 'x' + 11: 2, # 'y' + 22: 0, # 'z' + 63: 1, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 2, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 3, # 'ü' + 30: 0, # 'ÄŸ' + 41: 0, # 'İ' + 6: 2, # 'ı' + 40: 0, # 'Åž' + 19: 0, # 'ÅŸ' + }, + 8: { # 's' + 23: 1, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 0, # 'F' + 36: 1, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 3, # 'K' + 49: 0, # 'L' + 20: 3, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 2, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 1, # 'Z' + 1: 3, # 'a' + 21: 2, # 'b' + 28: 1, # 'c' + 12: 3, # 'd' + 2: 3, # 'e' + 18: 0, # 'f' + 27: 2, # 'g' + 25: 2, # 'h' + 3: 2, # 'i' + 24: 3, # 'j' + 10: 3, # 'k' + 5: 3, # 'l' + 13: 3, # 'm' + 4: 3, # 'n' + 15: 0, # 'o' + 26: 3, # 'p' + 7: 3, # 'r' + 8: 3, # 's' + 9: 3, # 't' + 14: 3, # 'u' + 32: 2, # 'v' + 57: 0, # 'w' + 58: 1, # 'x' + 11: 2, # 'y' + 22: 1, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 2, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 2, # 'ü' + 30: 0, # 'ÄŸ' + 41: 0, # 'İ' + 6: 3, # 'ı' + 40: 0, # 'Åž' + 19: 1, # 'ÅŸ' + }, + 9: { # 't' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 0, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 1, # 'J' + 16: 3, # 'K' + 49: 0, # 'L' + 20: 2, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 2, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 1, # 'Z' + 1: 3, # 'a' + 21: 3, # 'b' + 28: 0, # 'c' + 12: 3, # 'd' + 2: 3, # 'e' + 18: 2, # 'f' + 27: 2, # 'g' + 25: 2, # 'h' + 3: 2, # 'i' + 24: 2, # 'j' + 10: 3, # 'k' + 5: 3, # 'l' + 13: 3, # 'm' + 4: 3, # 'n' + 15: 0, # 'o' + 26: 2, # 'p' + 7: 3, # 'r' + 8: 3, # 's' + 9: 3, # 't' + 14: 3, # 'u' + 32: 3, # 'v' + 57: 0, # 'w' + 58: 2, # 'x' + 11: 2, # 'y' + 22: 0, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 3, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 2, # 'ü' + 30: 0, # 'ÄŸ' + 41: 0, # 'İ' + 6: 3, # 'ı' + 40: 0, # 'Åž' + 19: 0, # 'ÅŸ' + }, + 14: { # 'u' + 23: 3, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 3, # 'E' + 52: 0, # 'F' + 36: 0, # 'G' + 45: 1, # 'H' + 53: 0, # 'I' + 60: 1, # 'J' + 16: 0, # 'K' + 49: 0, # 'L' + 20: 3, # 'M' + 46: 2, # 'N' + 42: 0, # 'O' + 48: 1, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 3, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 1, # 'Y' + 56: 2, # 'Z' + 1: 2, # 'a' + 21: 3, # 'b' + 28: 0, # 'c' + 12: 3, # 'd' + 2: 2, # 'e' + 18: 2, # 'f' + 27: 3, # 'g' + 25: 3, # 'h' + 3: 3, # 'i' + 24: 2, # 'j' + 10: 3, # 'k' + 5: 0, # 'l' + 13: 3, # 'm' + 4: 3, # 'n' + 15: 0, # 'o' + 26: 3, # 'p' + 7: 3, # 'r' + 8: 3, # 's' + 9: 3, # 't' + 14: 3, # 'u' + 32: 2, # 'v' + 57: 2, # 'w' + 58: 0, # 'x' + 11: 3, # 'y' + 22: 0, # 'z' + 63: 1, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 0, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 3, # 'ü' + 30: 1, # 'ÄŸ' + 41: 0, # 'İ' + 6: 3, # 'ı' + 40: 0, # 'Åž' + 19: 0, # 'ÅŸ' + }, + 32: { # 'v' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 0, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 3, # 'K' + 49: 0, # 'L' + 20: 1, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 0, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 0, # 'Z' + 1: 3, # 'a' + 21: 0, # 'b' + 28: 0, # 'c' + 12: 3, # 'd' + 2: 3, # 'e' + 18: 0, # 'f' + 27: 0, # 'g' + 25: 0, # 'h' + 3: 0, # 'i' + 24: 1, # 'j' + 10: 1, # 'k' + 5: 3, # 'l' + 13: 2, # 'm' + 4: 3, # 'n' + 15: 0, # 'o' + 26: 1, # 'p' + 7: 1, # 'r' + 8: 2, # 's' + 9: 3, # 't' + 14: 3, # 'u' + 32: 1, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 0, # 'y' + 22: 0, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 2, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 0, # 'ü' + 30: 0, # 'ÄŸ' + 41: 0, # 'İ' + 6: 1, # 'ı' + 40: 0, # 'Åž' + 19: 0, # 'ÅŸ' + }, + 57: { # 'w' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 0, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 0, # 'K' + 49: 0, # 'L' + 20: 0, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 0, # 'T' + 51: 1, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 0, # 'Z' + 1: 1, # 'a' + 21: 0, # 'b' + 28: 0, # 'c' + 12: 0, # 'd' + 2: 2, # 'e' + 18: 0, # 'f' + 27: 0, # 'g' + 25: 1, # 'h' + 3: 0, # 'i' + 24: 0, # 'j' + 10: 1, # 'k' + 5: 0, # 'l' + 13: 0, # 'm' + 4: 1, # 'n' + 15: 0, # 'o' + 26: 0, # 'p' + 7: 0, # 'r' + 8: 1, # 's' + 9: 0, # 't' + 14: 1, # 'u' + 32: 0, # 'v' + 57: 2, # 'w' + 58: 0, # 'x' + 11: 0, # 'y' + 22: 0, # 'z' + 63: 1, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 0, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 1, # 'ü' + 30: 0, # 'ÄŸ' + 41: 0, # 'İ' + 6: 0, # 'ı' + 40: 0, # 'Åž' + 19: 0, # 'ÅŸ' + }, + 58: { # 'x' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 1, # 'E' + 52: 0, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 1, # 'J' + 16: 0, # 'K' + 49: 0, # 'L' + 20: 1, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 0, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 0, # 'Z' + 1: 0, # 'a' + 21: 1, # 'b' + 28: 0, # 'c' + 12: 2, # 'd' + 2: 1, # 'e' + 18: 0, # 'f' + 27: 0, # 'g' + 25: 0, # 'h' + 3: 2, # 'i' + 24: 2, # 'j' + 10: 1, # 'k' + 5: 0, # 'l' + 13: 0, # 'm' + 4: 2, # 'n' + 15: 0, # 'o' + 26: 0, # 'p' + 7: 1, # 'r' + 8: 2, # 's' + 9: 1, # 't' + 14: 0, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 2, # 'y' + 22: 0, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 0, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 1, # 'ü' + 30: 0, # 'ÄŸ' + 41: 0, # 'İ' + 6: 2, # 'ı' + 40: 0, # 'Åž' + 19: 0, # 'ÅŸ' + }, + 11: { # 'y' + 23: 1, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 0, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 1, # 'J' + 16: 3, # 'K' + 49: 0, # 'L' + 20: 1, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 1, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 1, # 'Y' + 56: 1, # 'Z' + 1: 3, # 'a' + 21: 1, # 'b' + 28: 0, # 'c' + 12: 2, # 'd' + 2: 3, # 'e' + 18: 0, # 'f' + 27: 2, # 'g' + 25: 2, # 'h' + 3: 2, # 'i' + 24: 1, # 'j' + 10: 2, # 'k' + 5: 3, # 'l' + 13: 3, # 'm' + 4: 3, # 'n' + 15: 0, # 'o' + 26: 1, # 'p' + 7: 2, # 'r' + 8: 1, # 's' + 9: 2, # 't' + 14: 3, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 1, # 'x' + 11: 3, # 'y' + 22: 0, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 3, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 2, # 'ü' + 30: 0, # 'ÄŸ' + 41: 0, # 'İ' + 6: 3, # 'ı' + 40: 0, # 'Åž' + 19: 0, # 'ÅŸ' + }, + 22: { # 'z' + 23: 2, # 'A' + 37: 2, # 'B' + 47: 1, # 'C' + 39: 2, # 'D' + 29: 3, # 'E' + 52: 1, # 'F' + 36: 2, # 'G' + 45: 2, # 'H' + 53: 1, # 'I' + 60: 0, # 'J' + 16: 0, # 'K' + 49: 0, # 'L' + 20: 3, # 'M' + 46: 2, # 'N' + 42: 2, # 'O' + 48: 2, # 'P' + 44: 1, # 'R' + 35: 1, # 'S' + 31: 3, # 'T' + 51: 2, # 'U' + 38: 2, # 'V' + 62: 0, # 'W' + 43: 2, # 'Y' + 56: 1, # 'Z' + 1: 1, # 'a' + 21: 2, # 'b' + 28: 1, # 'c' + 12: 2, # 'd' + 2: 2, # 'e' + 18: 3, # 'f' + 27: 2, # 'g' + 25: 2, # 'h' + 3: 3, # 'i' + 24: 2, # 'j' + 10: 3, # 'k' + 5: 0, # 'l' + 13: 2, # 'm' + 4: 3, # 'n' + 15: 2, # 'o' + 26: 2, # 'p' + 7: 3, # 'r' + 8: 3, # 's' + 9: 3, # 't' + 14: 0, # 'u' + 32: 2, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 3, # 'y' + 22: 2, # 'z' + 63: 1, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 2, # 'Ü' + 59: 1, # 'â' + 33: 0, # 'ç' + 61: 0, # 'î' + 34: 2, # 'ö' + 17: 2, # 'ü' + 30: 2, # 'ÄŸ' + 41: 1, # 'İ' + 6: 3, # 'ı' + 40: 1, # 'Åž' + 19: 2, # 'ÅŸ' + }, + 63: { # '·' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 0, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 0, # 'K' + 49: 0, # 'L' + 20: 0, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 0, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 0, # 'Z' + 1: 0, # 'a' + 21: 0, # 'b' + 28: 0, # 'c' + 12: 0, # 'd' + 2: 1, # 'e' + 18: 0, # 'f' + 27: 0, # 'g' + 25: 0, # 'h' + 3: 0, # 'i' + 24: 0, # 'j' + 10: 0, # 'k' + 5: 0, # 'l' + 13: 2, # 'm' + 4: 0, # 'n' + 15: 0, # 'o' + 26: 0, # 'p' + 7: 0, # 'r' + 8: 0, # 's' + 9: 0, # 't' + 14: 2, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 0, # 'y' + 22: 0, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 0, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 0, # 'ü' + 30: 0, # 'ÄŸ' + 41: 0, # 'İ' + 6: 0, # 'ı' + 40: 0, # 'Åž' + 19: 0, # 'ÅŸ' + }, + 54: { # 'Ç' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 1, # 'C' + 39: 1, # 'D' + 29: 0, # 'E' + 52: 0, # 'F' + 36: 1, # 'G' + 45: 1, # 'H' + 53: 1, # 'I' + 60: 0, # 'J' + 16: 0, # 'K' + 49: 0, # 'L' + 20: 0, # 'M' + 46: 0, # 'N' + 42: 1, # 'O' + 48: 1, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 0, # 'T' + 51: 1, # 'U' + 38: 1, # 'V' + 62: 0, # 'W' + 43: 2, # 'Y' + 56: 0, # 'Z' + 1: 0, # 'a' + 21: 1, # 'b' + 28: 0, # 'c' + 12: 1, # 'd' + 2: 0, # 'e' + 18: 0, # 'f' + 27: 1, # 'g' + 25: 0, # 'h' + 3: 3, # 'i' + 24: 0, # 'j' + 10: 1, # 'k' + 5: 0, # 'l' + 13: 0, # 'm' + 4: 2, # 'n' + 15: 1, # 'o' + 26: 0, # 'p' + 7: 2, # 'r' + 8: 0, # 's' + 9: 1, # 't' + 14: 0, # 'u' + 32: 2, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 0, # 'y' + 22: 0, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 2, # 'Ü' + 59: 0, # 'â' + 33: 0, # 'ç' + 61: 0, # 'î' + 34: 1, # 'ö' + 17: 0, # 'ü' + 30: 0, # 'ÄŸ' + 41: 0, # 'İ' + 6: 2, # 'ı' + 40: 0, # 'Åž' + 19: 1, # 'ÅŸ' + }, + 50: { # 'Ö' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 1, # 'C' + 39: 1, # 'D' + 29: 2, # 'E' + 52: 0, # 'F' + 36: 1, # 'G' + 45: 2, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 0, # 'K' + 49: 0, # 'L' + 20: 1, # 'M' + 46: 1, # 'N' + 42: 2, # 'O' + 48: 2, # 'P' + 44: 1, # 'R' + 35: 0, # 'S' + 31: 0, # 'T' + 51: 1, # 'U' + 38: 1, # 'V' + 62: 0, # 'W' + 43: 2, # 'Y' + 56: 0, # 'Z' + 1: 0, # 'a' + 21: 2, # 'b' + 28: 1, # 'c' + 12: 2, # 'd' + 2: 0, # 'e' + 18: 1, # 'f' + 27: 1, # 'g' + 25: 1, # 'h' + 3: 2, # 'i' + 24: 0, # 'j' + 10: 2, # 'k' + 5: 0, # 'l' + 13: 0, # 'm' + 4: 3, # 'n' + 15: 2, # 'o' + 26: 2, # 'p' + 7: 3, # 'r' + 8: 1, # 's' + 9: 2, # 't' + 14: 0, # 'u' + 32: 1, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 0, # 'y' + 22: 1, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 0, # 'ç' + 61: 0, # 'î' + 34: 2, # 'ö' + 17: 2, # 'ü' + 30: 1, # 'ÄŸ' + 41: 0, # 'İ' + 6: 2, # 'ı' + 40: 0, # 'Åž' + 19: 1, # 'ÅŸ' + }, + 55: { # 'Ü' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 2, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 1, # 'K' + 49: 0, # 'L' + 20: 0, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 1, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 0, # 'T' + 51: 0, # 'U' + 38: 1, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 0, # 'Z' + 1: 2, # 'a' + 21: 0, # 'b' + 28: 2, # 'c' + 12: 0, # 'd' + 2: 2, # 'e' + 18: 0, # 'f' + 27: 1, # 'g' + 25: 0, # 'h' + 3: 0, # 'i' + 24: 0, # 'j' + 10: 0, # 'k' + 5: 1, # 'l' + 13: 1, # 'm' + 4: 1, # 'n' + 15: 0, # 'o' + 26: 0, # 'p' + 7: 0, # 'r' + 8: 0, # 's' + 9: 1, # 't' + 14: 2, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 0, # 'y' + 22: 1, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 1, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 0, # 'ç' + 61: 0, # 'î' + 34: 1, # 'ö' + 17: 0, # 'ü' + 30: 1, # 'ÄŸ' + 41: 1, # 'İ' + 6: 0, # 'ı' + 40: 0, # 'Åž' + 19: 1, # 'ÅŸ' + }, + 59: { # 'â' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 0, # 'F' + 36: 1, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 1, # 'K' + 49: 0, # 'L' + 20: 0, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 0, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 0, # 'Z' + 1: 2, # 'a' + 21: 0, # 'b' + 28: 0, # 'c' + 12: 0, # 'd' + 2: 2, # 'e' + 18: 0, # 'f' + 27: 0, # 'g' + 25: 0, # 'h' + 3: 0, # 'i' + 24: 0, # 'j' + 10: 0, # 'k' + 5: 0, # 'l' + 13: 2, # 'm' + 4: 0, # 'n' + 15: 1, # 'o' + 26: 0, # 'p' + 7: 0, # 'r' + 8: 0, # 's' + 9: 0, # 't' + 14: 2, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 0, # 'y' + 22: 1, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 0, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 0, # 'ü' + 30: 0, # 'ÄŸ' + 41: 0, # 'İ' + 6: 1, # 'ı' + 40: 1, # 'Åž' + 19: 0, # 'ÅŸ' + }, + 33: { # 'ç' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 3, # 'E' + 52: 0, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 0, # 'K' + 49: 0, # 'L' + 20: 1, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 2, # 'T' + 51: 0, # 'U' + 38: 1, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 0, # 'Z' + 1: 0, # 'a' + 21: 3, # 'b' + 28: 0, # 'c' + 12: 2, # 'd' + 2: 0, # 'e' + 18: 2, # 'f' + 27: 1, # 'g' + 25: 3, # 'h' + 3: 3, # 'i' + 24: 0, # 'j' + 10: 3, # 'k' + 5: 0, # 'l' + 13: 0, # 'm' + 4: 3, # 'n' + 15: 0, # 'o' + 26: 1, # 'p' + 7: 3, # 'r' + 8: 2, # 's' + 9: 3, # 't' + 14: 0, # 'u' + 32: 2, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 2, # 'y' + 22: 0, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 0, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 1, # 'ü' + 30: 0, # 'ÄŸ' + 41: 0, # 'İ' + 6: 3, # 'ı' + 40: 0, # 'Åž' + 19: 0, # 'ÅŸ' + }, + 61: { # 'î' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 0, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 0, # 'K' + 49: 0, # 'L' + 20: 0, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 0, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 1, # 'Z' + 1: 2, # 'a' + 21: 0, # 'b' + 28: 0, # 'c' + 12: 0, # 'd' + 2: 2, # 'e' + 18: 0, # 'f' + 27: 0, # 'g' + 25: 0, # 'h' + 3: 0, # 'i' + 24: 1, # 'j' + 10: 0, # 'k' + 5: 0, # 'l' + 13: 1, # 'm' + 4: 1, # 'n' + 15: 0, # 'o' + 26: 0, # 'p' + 7: 0, # 'r' + 8: 0, # 's' + 9: 0, # 't' + 14: 1, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 0, # 'y' + 22: 1, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 0, # 'ç' + 61: 1, # 'î' + 34: 0, # 'ö' + 17: 0, # 'ü' + 30: 0, # 'ÄŸ' + 41: 0, # 'İ' + 6: 1, # 'ı' + 40: 0, # 'Åž' + 19: 0, # 'ÅŸ' + }, + 34: { # 'ö' + 23: 0, # 'A' + 37: 1, # 'B' + 47: 1, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 2, # 'F' + 36: 1, # 'G' + 45: 1, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 3, # 'K' + 49: 1, # 'L' + 20: 0, # 'M' + 46: 1, # 'N' + 42: 1, # 'O' + 48: 2, # 'P' + 44: 1, # 'R' + 35: 1, # 'S' + 31: 1, # 'T' + 51: 1, # 'U' + 38: 1, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 1, # 'Z' + 1: 3, # 'a' + 21: 1, # 'b' + 28: 2, # 'c' + 12: 1, # 'd' + 2: 3, # 'e' + 18: 0, # 'f' + 27: 2, # 'g' + 25: 2, # 'h' + 3: 1, # 'i' + 24: 2, # 'j' + 10: 1, # 'k' + 5: 2, # 'l' + 13: 3, # 'm' + 4: 2, # 'n' + 15: 2, # 'o' + 26: 0, # 'p' + 7: 0, # 'r' + 8: 3, # 's' + 9: 1, # 't' + 14: 3, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 1, # 'y' + 22: 2, # 'z' + 63: 0, # '·' + 54: 1, # 'Ç' + 50: 2, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 2, # 'ç' + 61: 0, # 'î' + 34: 2, # 'ö' + 17: 0, # 'ü' + 30: 2, # 'ÄŸ' + 41: 1, # 'İ' + 6: 1, # 'ı' + 40: 2, # 'Åž' + 19: 1, # 'ÅŸ' + }, + 17: { # 'ü' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 1, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 0, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 1, # 'J' + 16: 1, # 'K' + 49: 0, # 'L' + 20: 1, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 1, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 1, # 'Z' + 1: 3, # 'a' + 21: 0, # 'b' + 28: 0, # 'c' + 12: 1, # 'd' + 2: 3, # 'e' + 18: 1, # 'f' + 27: 2, # 'g' + 25: 0, # 'h' + 3: 1, # 'i' + 24: 1, # 'j' + 10: 2, # 'k' + 5: 3, # 'l' + 13: 2, # 'm' + 4: 3, # 'n' + 15: 0, # 'o' + 26: 2, # 'p' + 7: 2, # 'r' + 8: 3, # 's' + 9: 2, # 't' + 14: 3, # 'u' + 32: 1, # 'v' + 57: 1, # 'w' + 58: 0, # 'x' + 11: 0, # 'y' + 22: 0, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 1, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 2, # 'ü' + 30: 0, # 'ÄŸ' + 41: 0, # 'İ' + 6: 2, # 'ı' + 40: 0, # 'Åž' + 19: 0, # 'ÅŸ' + }, + 30: { # 'ÄŸ' + 23: 0, # 'A' + 37: 2, # 'B' + 47: 1, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 2, # 'F' + 36: 1, # 'G' + 45: 0, # 'H' + 53: 1, # 'I' + 60: 0, # 'J' + 16: 3, # 'K' + 49: 0, # 'L' + 20: 1, # 'M' + 46: 2, # 'N' + 42: 2, # 'O' + 48: 1, # 'P' + 44: 1, # 'R' + 35: 0, # 'S' + 31: 1, # 'T' + 51: 0, # 'U' + 38: 2, # 'V' + 62: 0, # 'W' + 43: 2, # 'Y' + 56: 0, # 'Z' + 1: 3, # 'a' + 21: 0, # 'b' + 28: 2, # 'c' + 12: 0, # 'd' + 2: 2, # 'e' + 18: 0, # 'f' + 27: 0, # 'g' + 25: 0, # 'h' + 3: 0, # 'i' + 24: 3, # 'j' + 10: 1, # 'k' + 5: 2, # 'l' + 13: 3, # 'm' + 4: 0, # 'n' + 15: 1, # 'o' + 26: 0, # 'p' + 7: 1, # 'r' + 8: 0, # 's' + 9: 0, # 't' + 14: 3, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 0, # 'y' + 22: 2, # 'z' + 63: 0, # '·' + 54: 2, # 'Ç' + 50: 2, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 1, # 'ç' + 61: 0, # 'î' + 34: 2, # 'ö' + 17: 0, # 'ü' + 30: 1, # 'ÄŸ' + 41: 2, # 'İ' + 6: 2, # 'ı' + 40: 2, # 'Åž' + 19: 1, # 'ÅŸ' + }, + 41: { # 'İ' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 1, # 'C' + 39: 1, # 'D' + 29: 1, # 'E' + 52: 0, # 'F' + 36: 2, # 'G' + 45: 2, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 0, # 'K' + 49: 0, # 'L' + 20: 2, # 'M' + 46: 1, # 'N' + 42: 1, # 'O' + 48: 2, # 'P' + 44: 0, # 'R' + 35: 1, # 'S' + 31: 1, # 'T' + 51: 1, # 'U' + 38: 1, # 'V' + 62: 0, # 'W' + 43: 2, # 'Y' + 56: 0, # 'Z' + 1: 1, # 'a' + 21: 2, # 'b' + 28: 1, # 'c' + 12: 2, # 'd' + 2: 1, # 'e' + 18: 0, # 'f' + 27: 3, # 'g' + 25: 2, # 'h' + 3: 2, # 'i' + 24: 2, # 'j' + 10: 2, # 'k' + 5: 0, # 'l' + 13: 1, # 'm' + 4: 3, # 'n' + 15: 1, # 'o' + 26: 1, # 'p' + 7: 3, # 'r' + 8: 3, # 's' + 9: 2, # 't' + 14: 0, # 'u' + 32: 0, # 'v' + 57: 1, # 'w' + 58: 0, # 'x' + 11: 2, # 'y' + 22: 0, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 1, # 'Ü' + 59: 1, # 'â' + 33: 0, # 'ç' + 61: 0, # 'î' + 34: 1, # 'ö' + 17: 1, # 'ü' + 30: 2, # 'ÄŸ' + 41: 0, # 'İ' + 6: 3, # 'ı' + 40: 0, # 'Åž' + 19: 1, # 'ÅŸ' + }, + 6: { # 'ı' + 23: 2, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 0, # 'F' + 36: 1, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 2, # 'J' + 16: 3, # 'K' + 49: 0, # 'L' + 20: 3, # 'M' + 46: 1, # 'N' + 42: 0, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 2, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 2, # 'Y' + 56: 1, # 'Z' + 1: 3, # 'a' + 21: 2, # 'b' + 28: 1, # 'c' + 12: 3, # 'd' + 2: 3, # 'e' + 18: 3, # 'f' + 27: 3, # 'g' + 25: 2, # 'h' + 3: 3, # 'i' + 24: 3, # 'j' + 10: 3, # 'k' + 5: 3, # 'l' + 13: 3, # 'm' + 4: 3, # 'n' + 15: 0, # 'o' + 26: 3, # 'p' + 7: 3, # 'r' + 8: 3, # 's' + 9: 3, # 't' + 14: 3, # 'u' + 32: 3, # 'v' + 57: 1, # 'w' + 58: 1, # 'x' + 11: 3, # 'y' + 22: 0, # 'z' + 63: 1, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 2, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 3, # 'ü' + 30: 0, # 'ÄŸ' + 41: 0, # 'İ' + 6: 3, # 'ı' + 40: 0, # 'Åž' + 19: 0, # 'ÅŸ' + }, + 40: { # 'Åž' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 1, # 'C' + 39: 1, # 'D' + 29: 1, # 'E' + 52: 0, # 'F' + 36: 1, # 'G' + 45: 2, # 'H' + 53: 1, # 'I' + 60: 0, # 'J' + 16: 0, # 'K' + 49: 0, # 'L' + 20: 2, # 'M' + 46: 1, # 'N' + 42: 1, # 'O' + 48: 2, # 'P' + 44: 2, # 'R' + 35: 1, # 'S' + 31: 1, # 'T' + 51: 0, # 'U' + 38: 1, # 'V' + 62: 0, # 'W' + 43: 2, # 'Y' + 56: 1, # 'Z' + 1: 0, # 'a' + 21: 2, # 'b' + 28: 0, # 'c' + 12: 2, # 'd' + 2: 0, # 'e' + 18: 3, # 'f' + 27: 0, # 'g' + 25: 2, # 'h' + 3: 3, # 'i' + 24: 2, # 'j' + 10: 1, # 'k' + 5: 0, # 'l' + 13: 1, # 'm' + 4: 3, # 'n' + 15: 2, # 'o' + 26: 0, # 'p' + 7: 3, # 'r' + 8: 2, # 's' + 9: 2, # 't' + 14: 1, # 'u' + 32: 3, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 2, # 'y' + 22: 0, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 1, # 'Ü' + 59: 0, # 'â' + 33: 0, # 'ç' + 61: 0, # 'î' + 34: 2, # 'ö' + 17: 1, # 'ü' + 30: 2, # 'ÄŸ' + 41: 0, # 'İ' + 6: 2, # 'ı' + 40: 1, # 'Åž' + 19: 2, # 'ÅŸ' + }, + 19: { # 'ÅŸ' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 1, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 2, # 'F' + 36: 1, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 3, # 'K' + 49: 2, # 'L' + 20: 0, # 'M' + 46: 1, # 'N' + 42: 1, # 'O' + 48: 1, # 'P' + 44: 1, # 'R' + 35: 1, # 'S' + 31: 0, # 'T' + 51: 1, # 'U' + 38: 1, # 'V' + 62: 0, # 'W' + 43: 1, # 'Y' + 56: 0, # 'Z' + 1: 3, # 'a' + 21: 1, # 'b' + 28: 2, # 'c' + 12: 0, # 'd' + 2: 3, # 'e' + 18: 0, # 'f' + 27: 2, # 'g' + 25: 1, # 'h' + 3: 1, # 'i' + 24: 0, # 'j' + 10: 2, # 'k' + 5: 2, # 'l' + 13: 3, # 'm' + 4: 0, # 'n' + 15: 0, # 'o' + 26: 1, # 'p' + 7: 3, # 'r' + 8: 0, # 's' + 9: 0, # 't' + 14: 3, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 0, # 'y' + 22: 2, # 'z' + 63: 0, # '·' + 54: 1, # 'Ç' + 50: 2, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 1, # 'ç' + 61: 1, # 'î' + 34: 2, # 'ö' + 17: 0, # 'ü' + 30: 1, # 'ÄŸ' + 41: 1, # 'İ' + 6: 1, # 'ı' + 40: 1, # 'Åž' + 19: 1, # 'ÅŸ' + }, +} + +# 255: Undefined characters that did not exist in training text +# 254: Carriage/Return +# 253: symbol (punctuation) that does not belong to word +# 252: 0 - 9 +# 251: Control characters + +# Character Mapping Table(s): +ISO_8859_9_TURKISH_CHAR_TO_ORDER = { + 0: 255, # '\x00' + 1: 255, # '\x01' + 2: 255, # '\x02' + 3: 255, # '\x03' + 4: 255, # '\x04' + 5: 255, # '\x05' + 6: 255, # '\x06' + 7: 255, # '\x07' + 8: 255, # '\x08' + 9: 255, # '\t' + 10: 255, # '\n' + 11: 255, # '\x0b' + 12: 255, # '\x0c' + 13: 255, # '\r' + 14: 255, # '\x0e' + 15: 255, # '\x0f' + 16: 255, # '\x10' + 17: 255, # '\x11' + 18: 255, # '\x12' + 19: 255, # '\x13' + 20: 255, # '\x14' + 21: 255, # '\x15' + 22: 255, # '\x16' + 23: 255, # '\x17' + 24: 255, # '\x18' + 25: 255, # '\x19' + 26: 255, # '\x1a' + 27: 255, # '\x1b' + 28: 255, # '\x1c' + 29: 255, # '\x1d' + 30: 255, # '\x1e' + 31: 255, # '\x1f' + 32: 255, # ' ' + 33: 255, # '!' + 34: 255, # '"' + 35: 255, # '#' + 36: 255, # '$' + 37: 255, # '%' + 38: 255, # '&' + 39: 255, # "'" + 40: 255, # '(' + 41: 255, # ')' + 42: 255, # '*' + 43: 255, # '+' + 44: 255, # ',' + 45: 255, # '-' + 46: 255, # '.' + 47: 255, # '/' + 48: 255, # '0' + 49: 255, # '1' + 50: 255, # '2' + 51: 255, # '3' + 52: 255, # '4' + 53: 255, # '5' + 54: 255, # '6' + 55: 255, # '7' + 56: 255, # '8' + 57: 255, # '9' + 58: 255, # ':' + 59: 255, # ';' + 60: 255, # '<' + 61: 255, # '=' + 62: 255, # '>' + 63: 255, # '?' + 64: 255, # '@' + 65: 23, # 'A' + 66: 37, # 'B' + 67: 47, # 'C' + 68: 39, # 'D' + 69: 29, # 'E' + 70: 52, # 'F' + 71: 36, # 'G' + 72: 45, # 'H' + 73: 53, # 'I' + 74: 60, # 'J' + 75: 16, # 'K' + 76: 49, # 'L' + 77: 20, # 'M' + 78: 46, # 'N' + 79: 42, # 'O' + 80: 48, # 'P' + 81: 69, # 'Q' + 82: 44, # 'R' + 83: 35, # 'S' + 84: 31, # 'T' + 85: 51, # 'U' + 86: 38, # 'V' + 87: 62, # 'W' + 88: 65, # 'X' + 89: 43, # 'Y' + 90: 56, # 'Z' + 91: 255, # '[' + 92: 255, # '\\' + 93: 255, # ']' + 94: 255, # '^' + 95: 255, # '_' + 96: 255, # '`' + 97: 1, # 'a' + 98: 21, # 'b' + 99: 28, # 'c' + 100: 12, # 'd' + 101: 2, # 'e' + 102: 18, # 'f' + 103: 27, # 'g' + 104: 25, # 'h' + 105: 3, # 'i' + 106: 24, # 'j' + 107: 10, # 'k' + 108: 5, # 'l' + 109: 13, # 'm' + 110: 4, # 'n' + 111: 15, # 'o' + 112: 26, # 'p' + 113: 64, # 'q' + 114: 7, # 'r' + 115: 8, # 's' + 116: 9, # 't' + 117: 14, # 'u' + 118: 32, # 'v' + 119: 57, # 'w' + 120: 58, # 'x' + 121: 11, # 'y' + 122: 22, # 'z' + 123: 255, # '{' + 124: 255, # '|' + 125: 255, # '}' + 126: 255, # '~' + 127: 255, # '\x7f' + 128: 180, # '\x80' + 129: 179, # '\x81' + 130: 178, # '\x82' + 131: 177, # '\x83' + 132: 176, # '\x84' + 133: 175, # '\x85' + 134: 174, # '\x86' + 135: 173, # '\x87' + 136: 172, # '\x88' + 137: 171, # '\x89' + 138: 170, # '\x8a' + 139: 169, # '\x8b' + 140: 168, # '\x8c' + 141: 167, # '\x8d' + 142: 166, # '\x8e' + 143: 165, # '\x8f' + 144: 164, # '\x90' + 145: 163, # '\x91' + 146: 162, # '\x92' + 147: 161, # '\x93' + 148: 160, # '\x94' + 149: 159, # '\x95' + 150: 101, # '\x96' + 151: 158, # '\x97' + 152: 157, # '\x98' + 153: 156, # '\x99' + 154: 155, # '\x9a' + 155: 154, # '\x9b' + 156: 153, # '\x9c' + 157: 152, # '\x9d' + 158: 151, # '\x9e' + 159: 106, # '\x9f' + 160: 150, # '\xa0' + 161: 149, # '¡' + 162: 148, # '¢' + 163: 147, # '£' + 164: 146, # '¤' + 165: 145, # 'Â¥' + 166: 144, # '¦' + 167: 100, # '§' + 168: 143, # '¨' + 169: 142, # '©' + 170: 141, # 'ª' + 171: 140, # '«' + 172: 139, # '¬' + 173: 138, # '\xad' + 174: 137, # '®' + 175: 136, # '¯' + 176: 94, # '°' + 177: 80, # '±' + 178: 93, # '²' + 179: 135, # '³' + 180: 105, # '´' + 181: 134, # 'µ' + 182: 133, # '¶' + 183: 63, # '·' + 184: 132, # '¸' + 185: 131, # '¹' + 186: 130, # 'º' + 187: 129, # '»' + 188: 128, # '¼' + 189: 127, # '½' + 190: 126, # '¾' + 191: 125, # '¿' + 192: 124, # 'À' + 193: 104, # 'Ã' + 194: 73, # 'Â' + 195: 99, # 'Ã' + 196: 79, # 'Ä' + 197: 85, # 'Ã…' + 198: 123, # 'Æ' + 199: 54, # 'Ç' + 200: 122, # 'È' + 201: 98, # 'É' + 202: 92, # 'Ê' + 203: 121, # 'Ë' + 204: 120, # 'ÃŒ' + 205: 91, # 'Ã' + 206: 103, # 'ÃŽ' + 207: 119, # 'Ã' + 208: 68, # 'Äž' + 209: 118, # 'Ñ' + 210: 117, # 'Ã’' + 211: 97, # 'Ó' + 212: 116, # 'Ô' + 213: 115, # 'Õ' + 214: 50, # 'Ö' + 215: 90, # '×' + 216: 114, # 'Ø' + 217: 113, # 'Ù' + 218: 112, # 'Ú' + 219: 111, # 'Û' + 220: 55, # 'Ü' + 221: 41, # 'İ' + 222: 40, # 'Åž' + 223: 86, # 'ß' + 224: 89, # 'à' + 225: 70, # 'á' + 226: 59, # 'â' + 227: 78, # 'ã' + 228: 71, # 'ä' + 229: 82, # 'Ã¥' + 230: 88, # 'æ' + 231: 33, # 'ç' + 232: 77, # 'è' + 233: 66, # 'é' + 234: 84, # 'ê' + 235: 83, # 'ë' + 236: 110, # 'ì' + 237: 75, # 'í' + 238: 61, # 'î' + 239: 96, # 'ï' + 240: 30, # 'ÄŸ' + 241: 67, # 'ñ' + 242: 109, # 'ò' + 243: 74, # 'ó' + 244: 87, # 'ô' + 245: 102, # 'õ' + 246: 34, # 'ö' + 247: 95, # '÷' + 248: 81, # 'ø' + 249: 108, # 'ù' + 250: 76, # 'ú' + 251: 72, # 'û' + 252: 17, # 'ü' + 253: 6, # 'ı' + 254: 19, # 'ÅŸ' + 255: 107, # 'ÿ' +} + +ISO_8859_9_TURKISH_MODEL = SingleByteCharSetModel(charset_name='ISO-8859-9', + language='Turkish', + char_to_order_map=ISO_8859_9_TURKISH_CHAR_TO_ORDER, + language_model=TURKISH_LANG_MODEL, + typical_positive_ratio=0.97029, + keep_ascii_letters=True, + alphabet='ABCDEFGHIJKLMNOPRSTUVYZabcdefghijklmnoprstuvyzÂÇÎÖÛÜâçîöûüĞğİıŞş') + diff --git a/venv/Lib/site-packages/pip/_vendor/chardet/latin1prober.py b/venv/Lib/site-packages/pip/_vendor/chardet/latin1prober.py new file mode 100644 index 0000000..7d1e8c2 --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/chardet/latin1prober.py @@ -0,0 +1,145 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Universal charset detector code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 2001 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# Shy Shalom - original C code +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .charsetprober import CharSetProber +from .enums import ProbingState + +FREQ_CAT_NUM = 4 + +UDF = 0 # undefined +OTH = 1 # other +ASC = 2 # ascii capital letter +ASS = 3 # ascii small letter +ACV = 4 # accent capital vowel +ACO = 5 # accent capital other +ASV = 6 # accent small vowel +ASO = 7 # accent small other +CLASS_NUM = 8 # total classes + +Latin1_CharToClass = ( + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 00 - 07 + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 08 - 0F + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 10 - 17 + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 18 - 1F + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 20 - 27 + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 28 - 2F + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 30 - 37 + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 38 - 3F + OTH, ASC, ASC, ASC, ASC, ASC, ASC, ASC, # 40 - 47 + ASC, ASC, ASC, ASC, ASC, ASC, ASC, ASC, # 48 - 4F + ASC, ASC, ASC, ASC, ASC, ASC, ASC, ASC, # 50 - 57 + ASC, ASC, ASC, OTH, OTH, OTH, OTH, OTH, # 58 - 5F + OTH, ASS, ASS, ASS, ASS, ASS, ASS, ASS, # 60 - 67 + ASS, ASS, ASS, ASS, ASS, ASS, ASS, ASS, # 68 - 6F + ASS, ASS, ASS, ASS, ASS, ASS, ASS, ASS, # 70 - 77 + ASS, ASS, ASS, OTH, OTH, OTH, OTH, OTH, # 78 - 7F + OTH, UDF, OTH, ASO, OTH, OTH, OTH, OTH, # 80 - 87 + OTH, OTH, ACO, OTH, ACO, UDF, ACO, UDF, # 88 - 8F + UDF, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 90 - 97 + OTH, OTH, ASO, OTH, ASO, UDF, ASO, ACO, # 98 - 9F + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # A0 - A7 + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # A8 - AF + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # B0 - B7 + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # B8 - BF + ACV, ACV, ACV, ACV, ACV, ACV, ACO, ACO, # C0 - C7 + ACV, ACV, ACV, ACV, ACV, ACV, ACV, ACV, # C8 - CF + ACO, ACO, ACV, ACV, ACV, ACV, ACV, OTH, # D0 - D7 + ACV, ACV, ACV, ACV, ACV, ACO, ACO, ACO, # D8 - DF + ASV, ASV, ASV, ASV, ASV, ASV, ASO, ASO, # E0 - E7 + ASV, ASV, ASV, ASV, ASV, ASV, ASV, ASV, # E8 - EF + ASO, ASO, ASV, ASV, ASV, ASV, ASV, OTH, # F0 - F7 + ASV, ASV, ASV, ASV, ASV, ASO, ASO, ASO, # F8 - FF +) + +# 0 : illegal +# 1 : very unlikely +# 2 : normal +# 3 : very likely +Latin1ClassModel = ( +# UDF OTH ASC ASS ACV ACO ASV ASO + 0, 0, 0, 0, 0, 0, 0, 0, # UDF + 0, 3, 3, 3, 3, 3, 3, 3, # OTH + 0, 3, 3, 3, 3, 3, 3, 3, # ASC + 0, 3, 3, 3, 1, 1, 3, 3, # ASS + 0, 3, 3, 3, 1, 2, 1, 2, # ACV + 0, 3, 3, 3, 3, 3, 3, 3, # ACO + 0, 3, 1, 3, 1, 1, 1, 3, # ASV + 0, 3, 1, 3, 1, 1, 3, 3, # ASO +) + + +class Latin1Prober(CharSetProber): + def __init__(self): + super(Latin1Prober, self).__init__() + self._last_char_class = None + self._freq_counter = None + self.reset() + + def reset(self): + self._last_char_class = OTH + self._freq_counter = [0] * FREQ_CAT_NUM + CharSetProber.reset(self) + + @property + def charset_name(self): + return "ISO-8859-1" + + @property + def language(self): + return "" + + def feed(self, byte_str): + byte_str = self.filter_with_english_letters(byte_str) + for c in byte_str: + char_class = Latin1_CharToClass[c] + freq = Latin1ClassModel[(self._last_char_class * CLASS_NUM) + + char_class] + if freq == 0: + self._state = ProbingState.NOT_ME + break + self._freq_counter[freq] += 1 + self._last_char_class = char_class + + return self.state + + def get_confidence(self): + if self.state == ProbingState.NOT_ME: + return 0.01 + + total = sum(self._freq_counter) + if total < 0.01: + confidence = 0.0 + else: + confidence = ((self._freq_counter[3] - self._freq_counter[1] * 20.0) + / total) + if confidence < 0.0: + confidence = 0.0 + # lower the confidence of latin1 so that other more accurate + # detector can take priority. + confidence = confidence * 0.73 + return confidence diff --git a/venv/Lib/site-packages/pip/_vendor/chardet/mbcharsetprober.py b/venv/Lib/site-packages/pip/_vendor/chardet/mbcharsetprober.py new file mode 100644 index 0000000..6256ecf --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/chardet/mbcharsetprober.py @@ -0,0 +1,91 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Universal charset detector code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 2001 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# Shy Shalom - original C code +# Proofpoint, Inc. +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .charsetprober import CharSetProber +from .enums import ProbingState, MachineState + + +class MultiByteCharSetProber(CharSetProber): + """ + MultiByteCharSetProber + """ + + def __init__(self, lang_filter=None): + super(MultiByteCharSetProber, self).__init__(lang_filter=lang_filter) + self.distribution_analyzer = None + self.coding_sm = None + self._last_char = [0, 0] + + def reset(self): + super(MultiByteCharSetProber, self).reset() + if self.coding_sm: + self.coding_sm.reset() + if self.distribution_analyzer: + self.distribution_analyzer.reset() + self._last_char = [0, 0] + + @property + def charset_name(self): + raise NotImplementedError + + @property + def language(self): + raise NotImplementedError + + def feed(self, byte_str): + for i in range(len(byte_str)): + coding_state = self.coding_sm.next_state(byte_str[i]) + if coding_state == MachineState.ERROR: + self.logger.debug('%s %s prober hit error at byte %s', + self.charset_name, self.language, i) + self._state = ProbingState.NOT_ME + break + elif coding_state == MachineState.ITS_ME: + self._state = ProbingState.FOUND_IT + break + elif coding_state == MachineState.START: + char_len = self.coding_sm.get_current_charlen() + if i == 0: + self._last_char[1] = byte_str[0] + self.distribution_analyzer.feed(self._last_char, char_len) + else: + self.distribution_analyzer.feed(byte_str[i - 1:i + 1], + char_len) + + self._last_char[0] = byte_str[-1] + + if self.state == ProbingState.DETECTING: + if (self.distribution_analyzer.got_enough_data() and + (self.get_confidence() > self.SHORTCUT_THRESHOLD)): + self._state = ProbingState.FOUND_IT + + return self.state + + def get_confidence(self): + return self.distribution_analyzer.get_confidence() diff --git a/venv/Lib/site-packages/pip/_vendor/chardet/mbcsgroupprober.py b/venv/Lib/site-packages/pip/_vendor/chardet/mbcsgroupprober.py new file mode 100644 index 0000000..530abe7 --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/chardet/mbcsgroupprober.py @@ -0,0 +1,54 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Universal charset detector code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 2001 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# Shy Shalom - original C code +# Proofpoint, Inc. +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .charsetgroupprober import CharSetGroupProber +from .utf8prober import UTF8Prober +from .sjisprober import SJISProber +from .eucjpprober import EUCJPProber +from .gb2312prober import GB2312Prober +from .euckrprober import EUCKRProber +from .cp949prober import CP949Prober +from .big5prober import Big5Prober +from .euctwprober import EUCTWProber + + +class MBCSGroupProber(CharSetGroupProber): + def __init__(self, lang_filter=None): + super(MBCSGroupProber, self).__init__(lang_filter=lang_filter) + self.probers = [ + UTF8Prober(), + SJISProber(), + EUCJPProber(), + GB2312Prober(), + EUCKRProber(), + CP949Prober(), + Big5Prober(), + EUCTWProber() + ] + self.reset() diff --git a/venv/Lib/site-packages/pip/_vendor/chardet/mbcssm.py b/venv/Lib/site-packages/pip/_vendor/chardet/mbcssm.py new file mode 100644 index 0000000..8360d0f --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/chardet/mbcssm.py @@ -0,0 +1,572 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .enums import MachineState + +# BIG5 + +BIG5_CLS = ( + 1,1,1,1,1,1,1,1, # 00 - 07 #allow 0x00 as legal value + 1,1,1,1,1,1,0,0, # 08 - 0f + 1,1,1,1,1,1,1,1, # 10 - 17 + 1,1,1,0,1,1,1,1, # 18 - 1f + 1,1,1,1,1,1,1,1, # 20 - 27 + 1,1,1,1,1,1,1,1, # 28 - 2f + 1,1,1,1,1,1,1,1, # 30 - 37 + 1,1,1,1,1,1,1,1, # 38 - 3f + 2,2,2,2,2,2,2,2, # 40 - 47 + 2,2,2,2,2,2,2,2, # 48 - 4f + 2,2,2,2,2,2,2,2, # 50 - 57 + 2,2,2,2,2,2,2,2, # 58 - 5f + 2,2,2,2,2,2,2,2, # 60 - 67 + 2,2,2,2,2,2,2,2, # 68 - 6f + 2,2,2,2,2,2,2,2, # 70 - 77 + 2,2,2,2,2,2,2,1, # 78 - 7f + 4,4,4,4,4,4,4,4, # 80 - 87 + 4,4,4,4,4,4,4,4, # 88 - 8f + 4,4,4,4,4,4,4,4, # 90 - 97 + 4,4,4,4,4,4,4,4, # 98 - 9f + 4,3,3,3,3,3,3,3, # a0 - a7 + 3,3,3,3,3,3,3,3, # a8 - af + 3,3,3,3,3,3,3,3, # b0 - b7 + 3,3,3,3,3,3,3,3, # b8 - bf + 3,3,3,3,3,3,3,3, # c0 - c7 + 3,3,3,3,3,3,3,3, # c8 - cf + 3,3,3,3,3,3,3,3, # d0 - d7 + 3,3,3,3,3,3,3,3, # d8 - df + 3,3,3,3,3,3,3,3, # e0 - e7 + 3,3,3,3,3,3,3,3, # e8 - ef + 3,3,3,3,3,3,3,3, # f0 - f7 + 3,3,3,3,3,3,3,0 # f8 - ff +) + +BIG5_ST = ( + MachineState.ERROR,MachineState.START,MachineState.START, 3,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#00-07 + MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,#08-0f + MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START#10-17 +) + +BIG5_CHAR_LEN_TABLE = (0, 1, 1, 2, 0) + +BIG5_SM_MODEL = {'class_table': BIG5_CLS, + 'class_factor': 5, + 'state_table': BIG5_ST, + 'char_len_table': BIG5_CHAR_LEN_TABLE, + 'name': 'Big5'} + +# CP949 + +CP949_CLS = ( + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,0,0, # 00 - 0f + 1,1,1,1,1,1,1,1, 1,1,1,0,1,1,1,1, # 10 - 1f + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, # 20 - 2f + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, # 30 - 3f + 1,4,4,4,4,4,4,4, 4,4,4,4,4,4,4,4, # 40 - 4f + 4,4,5,5,5,5,5,5, 5,5,5,1,1,1,1,1, # 50 - 5f + 1,5,5,5,5,5,5,5, 5,5,5,5,5,5,5,5, # 60 - 6f + 5,5,5,5,5,5,5,5, 5,5,5,1,1,1,1,1, # 70 - 7f + 0,6,6,6,6,6,6,6, 6,6,6,6,6,6,6,6, # 80 - 8f + 6,6,6,6,6,6,6,6, 6,6,6,6,6,6,6,6, # 90 - 9f + 6,7,7,7,7,7,7,7, 7,7,7,7,7,8,8,8, # a0 - af + 7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7, # b0 - bf + 7,7,7,7,7,7,9,2, 2,3,2,2,2,2,2,2, # c0 - cf + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, # d0 - df + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, # e0 - ef + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,0, # f0 - ff +) + +CP949_ST = ( +#cls= 0 1 2 3 4 5 6 7 8 9 # previous state = + MachineState.ERROR,MachineState.START, 3,MachineState.ERROR,MachineState.START,MachineState.START, 4, 5,MachineState.ERROR, 6, # MachineState.START + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, # MachineState.ERROR + MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME, # MachineState.ITS_ME + MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START, # 3 + MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START, # 4 + MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START, # 5 + MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START, # 6 +) + +CP949_CHAR_LEN_TABLE = (0, 1, 2, 0, 1, 1, 2, 2, 0, 2) + +CP949_SM_MODEL = {'class_table': CP949_CLS, + 'class_factor': 10, + 'state_table': CP949_ST, + 'char_len_table': CP949_CHAR_LEN_TABLE, + 'name': 'CP949'} + +# EUC-JP + +EUCJP_CLS = ( + 4,4,4,4,4,4,4,4, # 00 - 07 + 4,4,4,4,4,4,5,5, # 08 - 0f + 4,4,4,4,4,4,4,4, # 10 - 17 + 4,4,4,5,4,4,4,4, # 18 - 1f + 4,4,4,4,4,4,4,4, # 20 - 27 + 4,4,4,4,4,4,4,4, # 28 - 2f + 4,4,4,4,4,4,4,4, # 30 - 37 + 4,4,4,4,4,4,4,4, # 38 - 3f + 4,4,4,4,4,4,4,4, # 40 - 47 + 4,4,4,4,4,4,4,4, # 48 - 4f + 4,4,4,4,4,4,4,4, # 50 - 57 + 4,4,4,4,4,4,4,4, # 58 - 5f + 4,4,4,4,4,4,4,4, # 60 - 67 + 4,4,4,4,4,4,4,4, # 68 - 6f + 4,4,4,4,4,4,4,4, # 70 - 77 + 4,4,4,4,4,4,4,4, # 78 - 7f + 5,5,5,5,5,5,5,5, # 80 - 87 + 5,5,5,5,5,5,1,3, # 88 - 8f + 5,5,5,5,5,5,5,5, # 90 - 97 + 5,5,5,5,5,5,5,5, # 98 - 9f + 5,2,2,2,2,2,2,2, # a0 - a7 + 2,2,2,2,2,2,2,2, # a8 - af + 2,2,2,2,2,2,2,2, # b0 - b7 + 2,2,2,2,2,2,2,2, # b8 - bf + 2,2,2,2,2,2,2,2, # c0 - c7 + 2,2,2,2,2,2,2,2, # c8 - cf + 2,2,2,2,2,2,2,2, # d0 - d7 + 2,2,2,2,2,2,2,2, # d8 - df + 0,0,0,0,0,0,0,0, # e0 - e7 + 0,0,0,0,0,0,0,0, # e8 - ef + 0,0,0,0,0,0,0,0, # f0 - f7 + 0,0,0,0,0,0,0,5 # f8 - ff +) + +EUCJP_ST = ( + 3, 4, 3, 5,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#00-07 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,#08-0f + MachineState.ITS_ME,MachineState.ITS_ME,MachineState.START,MachineState.ERROR,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#10-17 + MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 3,MachineState.ERROR,#18-1f + 3,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START#20-27 +) + +EUCJP_CHAR_LEN_TABLE = (2, 2, 2, 3, 1, 0) + +EUCJP_SM_MODEL = {'class_table': EUCJP_CLS, + 'class_factor': 6, + 'state_table': EUCJP_ST, + 'char_len_table': EUCJP_CHAR_LEN_TABLE, + 'name': 'EUC-JP'} + +# EUC-KR + +EUCKR_CLS = ( + 1,1,1,1,1,1,1,1, # 00 - 07 + 1,1,1,1,1,1,0,0, # 08 - 0f + 1,1,1,1,1,1,1,1, # 10 - 17 + 1,1,1,0,1,1,1,1, # 18 - 1f + 1,1,1,1,1,1,1,1, # 20 - 27 + 1,1,1,1,1,1,1,1, # 28 - 2f + 1,1,1,1,1,1,1,1, # 30 - 37 + 1,1,1,1,1,1,1,1, # 38 - 3f + 1,1,1,1,1,1,1,1, # 40 - 47 + 1,1,1,1,1,1,1,1, # 48 - 4f + 1,1,1,1,1,1,1,1, # 50 - 57 + 1,1,1,1,1,1,1,1, # 58 - 5f + 1,1,1,1,1,1,1,1, # 60 - 67 + 1,1,1,1,1,1,1,1, # 68 - 6f + 1,1,1,1,1,1,1,1, # 70 - 77 + 1,1,1,1,1,1,1,1, # 78 - 7f + 0,0,0,0,0,0,0,0, # 80 - 87 + 0,0,0,0,0,0,0,0, # 88 - 8f + 0,0,0,0,0,0,0,0, # 90 - 97 + 0,0,0,0,0,0,0,0, # 98 - 9f + 0,2,2,2,2,2,2,2, # a0 - a7 + 2,2,2,2,2,3,3,3, # a8 - af + 2,2,2,2,2,2,2,2, # b0 - b7 + 2,2,2,2,2,2,2,2, # b8 - bf + 2,2,2,2,2,2,2,2, # c0 - c7 + 2,3,2,2,2,2,2,2, # c8 - cf + 2,2,2,2,2,2,2,2, # d0 - d7 + 2,2,2,2,2,2,2,2, # d8 - df + 2,2,2,2,2,2,2,2, # e0 - e7 + 2,2,2,2,2,2,2,2, # e8 - ef + 2,2,2,2,2,2,2,2, # f0 - f7 + 2,2,2,2,2,2,2,0 # f8 - ff +) + +EUCKR_ST = ( + MachineState.ERROR,MachineState.START, 3,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#00-07 + MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START #08-0f +) + +EUCKR_CHAR_LEN_TABLE = (0, 1, 2, 0) + +EUCKR_SM_MODEL = {'class_table': EUCKR_CLS, + 'class_factor': 4, + 'state_table': EUCKR_ST, + 'char_len_table': EUCKR_CHAR_LEN_TABLE, + 'name': 'EUC-KR'} + +# EUC-TW + +EUCTW_CLS = ( + 2,2,2,2,2,2,2,2, # 00 - 07 + 2,2,2,2,2,2,0,0, # 08 - 0f + 2,2,2,2,2,2,2,2, # 10 - 17 + 2,2,2,0,2,2,2,2, # 18 - 1f + 2,2,2,2,2,2,2,2, # 20 - 27 + 2,2,2,2,2,2,2,2, # 28 - 2f + 2,2,2,2,2,2,2,2, # 30 - 37 + 2,2,2,2,2,2,2,2, # 38 - 3f + 2,2,2,2,2,2,2,2, # 40 - 47 + 2,2,2,2,2,2,2,2, # 48 - 4f + 2,2,2,2,2,2,2,2, # 50 - 57 + 2,2,2,2,2,2,2,2, # 58 - 5f + 2,2,2,2,2,2,2,2, # 60 - 67 + 2,2,2,2,2,2,2,2, # 68 - 6f + 2,2,2,2,2,2,2,2, # 70 - 77 + 2,2,2,2,2,2,2,2, # 78 - 7f + 0,0,0,0,0,0,0,0, # 80 - 87 + 0,0,0,0,0,0,6,0, # 88 - 8f + 0,0,0,0,0,0,0,0, # 90 - 97 + 0,0,0,0,0,0,0,0, # 98 - 9f + 0,3,4,4,4,4,4,4, # a0 - a7 + 5,5,1,1,1,1,1,1, # a8 - af + 1,1,1,1,1,1,1,1, # b0 - b7 + 1,1,1,1,1,1,1,1, # b8 - bf + 1,1,3,1,3,3,3,3, # c0 - c7 + 3,3,3,3,3,3,3,3, # c8 - cf + 3,3,3,3,3,3,3,3, # d0 - d7 + 3,3,3,3,3,3,3,3, # d8 - df + 3,3,3,3,3,3,3,3, # e0 - e7 + 3,3,3,3,3,3,3,3, # e8 - ef + 3,3,3,3,3,3,3,3, # f0 - f7 + 3,3,3,3,3,3,3,0 # f8 - ff +) + +EUCTW_ST = ( + MachineState.ERROR,MachineState.ERROR,MachineState.START, 3, 3, 3, 4,MachineState.ERROR,#00-07 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,#08-0f + MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,MachineState.START,MachineState.ERROR,#10-17 + MachineState.START,MachineState.START,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#18-1f + 5,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.ERROR,MachineState.START,MachineState.START,#20-27 + MachineState.START,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START #28-2f +) + +EUCTW_CHAR_LEN_TABLE = (0, 0, 1, 2, 2, 2, 3) + +EUCTW_SM_MODEL = {'class_table': EUCTW_CLS, + 'class_factor': 7, + 'state_table': EUCTW_ST, + 'char_len_table': EUCTW_CHAR_LEN_TABLE, + 'name': 'x-euc-tw'} + +# GB2312 + +GB2312_CLS = ( + 1,1,1,1,1,1,1,1, # 00 - 07 + 1,1,1,1,1,1,0,0, # 08 - 0f + 1,1,1,1,1,1,1,1, # 10 - 17 + 1,1,1,0,1,1,1,1, # 18 - 1f + 1,1,1,1,1,1,1,1, # 20 - 27 + 1,1,1,1,1,1,1,1, # 28 - 2f + 3,3,3,3,3,3,3,3, # 30 - 37 + 3,3,1,1,1,1,1,1, # 38 - 3f + 2,2,2,2,2,2,2,2, # 40 - 47 + 2,2,2,2,2,2,2,2, # 48 - 4f + 2,2,2,2,2,2,2,2, # 50 - 57 + 2,2,2,2,2,2,2,2, # 58 - 5f + 2,2,2,2,2,2,2,2, # 60 - 67 + 2,2,2,2,2,2,2,2, # 68 - 6f + 2,2,2,2,2,2,2,2, # 70 - 77 + 2,2,2,2,2,2,2,4, # 78 - 7f + 5,6,6,6,6,6,6,6, # 80 - 87 + 6,6,6,6,6,6,6,6, # 88 - 8f + 6,6,6,6,6,6,6,6, # 90 - 97 + 6,6,6,6,6,6,6,6, # 98 - 9f + 6,6,6,6,6,6,6,6, # a0 - a7 + 6,6,6,6,6,6,6,6, # a8 - af + 6,6,6,6,6,6,6,6, # b0 - b7 + 6,6,6,6,6,6,6,6, # b8 - bf + 6,6,6,6,6,6,6,6, # c0 - c7 + 6,6,6,6,6,6,6,6, # c8 - cf + 6,6,6,6,6,6,6,6, # d0 - d7 + 6,6,6,6,6,6,6,6, # d8 - df + 6,6,6,6,6,6,6,6, # e0 - e7 + 6,6,6,6,6,6,6,6, # e8 - ef + 6,6,6,6,6,6,6,6, # f0 - f7 + 6,6,6,6,6,6,6,0 # f8 - ff +) + +GB2312_ST = ( + MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START, 3,MachineState.ERROR,#00-07 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,#08-0f + MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.START,#10-17 + 4,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#18-1f + MachineState.ERROR,MachineState.ERROR, 5,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ERROR,#20-27 + MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START #28-2f +) + +# To be accurate, the length of class 6 can be either 2 or 4. +# But it is not necessary to discriminate between the two since +# it is used for frequency analysis only, and we are validating +# each code range there as well. So it is safe to set it to be +# 2 here. +GB2312_CHAR_LEN_TABLE = (0, 1, 1, 1, 1, 1, 2) + +GB2312_SM_MODEL = {'class_table': GB2312_CLS, + 'class_factor': 7, + 'state_table': GB2312_ST, + 'char_len_table': GB2312_CHAR_LEN_TABLE, + 'name': 'GB2312'} + +# Shift_JIS + +SJIS_CLS = ( + 1,1,1,1,1,1,1,1, # 00 - 07 + 1,1,1,1,1,1,0,0, # 08 - 0f + 1,1,1,1,1,1,1,1, # 10 - 17 + 1,1,1,0,1,1,1,1, # 18 - 1f + 1,1,1,1,1,1,1,1, # 20 - 27 + 1,1,1,1,1,1,1,1, # 28 - 2f + 1,1,1,1,1,1,1,1, # 30 - 37 + 1,1,1,1,1,1,1,1, # 38 - 3f + 2,2,2,2,2,2,2,2, # 40 - 47 + 2,2,2,2,2,2,2,2, # 48 - 4f + 2,2,2,2,2,2,2,2, # 50 - 57 + 2,2,2,2,2,2,2,2, # 58 - 5f + 2,2,2,2,2,2,2,2, # 60 - 67 + 2,2,2,2,2,2,2,2, # 68 - 6f + 2,2,2,2,2,2,2,2, # 70 - 77 + 2,2,2,2,2,2,2,1, # 78 - 7f + 3,3,3,3,3,2,2,3, # 80 - 87 + 3,3,3,3,3,3,3,3, # 88 - 8f + 3,3,3,3,3,3,3,3, # 90 - 97 + 3,3,3,3,3,3,3,3, # 98 - 9f + #0xa0 is illegal in sjis encoding, but some pages does + #contain such byte. We need to be more error forgiven. + 2,2,2,2,2,2,2,2, # a0 - a7 + 2,2,2,2,2,2,2,2, # a8 - af + 2,2,2,2,2,2,2,2, # b0 - b7 + 2,2,2,2,2,2,2,2, # b8 - bf + 2,2,2,2,2,2,2,2, # c0 - c7 + 2,2,2,2,2,2,2,2, # c8 - cf + 2,2,2,2,2,2,2,2, # d0 - d7 + 2,2,2,2,2,2,2,2, # d8 - df + 3,3,3,3,3,3,3,3, # e0 - e7 + 3,3,3,3,3,4,4,4, # e8 - ef + 3,3,3,3,3,3,3,3, # f0 - f7 + 3,3,3,3,3,0,0,0) # f8 - ff + + +SJIS_ST = ( + MachineState.ERROR,MachineState.START,MachineState.START, 3,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#00-07 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,#08-0f + MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START #10-17 +) + +SJIS_CHAR_LEN_TABLE = (0, 1, 1, 2, 0, 0) + +SJIS_SM_MODEL = {'class_table': SJIS_CLS, + 'class_factor': 6, + 'state_table': SJIS_ST, + 'char_len_table': SJIS_CHAR_LEN_TABLE, + 'name': 'Shift_JIS'} + +# UCS2-BE + +UCS2BE_CLS = ( + 0,0,0,0,0,0,0,0, # 00 - 07 + 0,0,1,0,0,2,0,0, # 08 - 0f + 0,0,0,0,0,0,0,0, # 10 - 17 + 0,0,0,3,0,0,0,0, # 18 - 1f + 0,0,0,0,0,0,0,0, # 20 - 27 + 0,3,3,3,3,3,0,0, # 28 - 2f + 0,0,0,0,0,0,0,0, # 30 - 37 + 0,0,0,0,0,0,0,0, # 38 - 3f + 0,0,0,0,0,0,0,0, # 40 - 47 + 0,0,0,0,0,0,0,0, # 48 - 4f + 0,0,0,0,0,0,0,0, # 50 - 57 + 0,0,0,0,0,0,0,0, # 58 - 5f + 0,0,0,0,0,0,0,0, # 60 - 67 + 0,0,0,0,0,0,0,0, # 68 - 6f + 0,0,0,0,0,0,0,0, # 70 - 77 + 0,0,0,0,0,0,0,0, # 78 - 7f + 0,0,0,0,0,0,0,0, # 80 - 87 + 0,0,0,0,0,0,0,0, # 88 - 8f + 0,0,0,0,0,0,0,0, # 90 - 97 + 0,0,0,0,0,0,0,0, # 98 - 9f + 0,0,0,0,0,0,0,0, # a0 - a7 + 0,0,0,0,0,0,0,0, # a8 - af + 0,0,0,0,0,0,0,0, # b0 - b7 + 0,0,0,0,0,0,0,0, # b8 - bf + 0,0,0,0,0,0,0,0, # c0 - c7 + 0,0,0,0,0,0,0,0, # c8 - cf + 0,0,0,0,0,0,0,0, # d0 - d7 + 0,0,0,0,0,0,0,0, # d8 - df + 0,0,0,0,0,0,0,0, # e0 - e7 + 0,0,0,0,0,0,0,0, # e8 - ef + 0,0,0,0,0,0,0,0, # f0 - f7 + 0,0,0,0,0,0,4,5 # f8 - ff +) + +UCS2BE_ST = ( + 5, 7, 7,MachineState.ERROR, 4, 3,MachineState.ERROR,MachineState.ERROR,#00-07 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,#08-0f + MachineState.ITS_ME,MachineState.ITS_ME, 6, 6, 6, 6,MachineState.ERROR,MachineState.ERROR,#10-17 + 6, 6, 6, 6, 6,MachineState.ITS_ME, 6, 6,#18-1f + 6, 6, 6, 6, 5, 7, 7,MachineState.ERROR,#20-27 + 5, 8, 6, 6,MachineState.ERROR, 6, 6, 6,#28-2f + 6, 6, 6, 6,MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START #30-37 +) + +UCS2BE_CHAR_LEN_TABLE = (2, 2, 2, 0, 2, 2) + +UCS2BE_SM_MODEL = {'class_table': UCS2BE_CLS, + 'class_factor': 6, + 'state_table': UCS2BE_ST, + 'char_len_table': UCS2BE_CHAR_LEN_TABLE, + 'name': 'UTF-16BE'} + +# UCS2-LE + +UCS2LE_CLS = ( + 0,0,0,0,0,0,0,0, # 00 - 07 + 0,0,1,0,0,2,0,0, # 08 - 0f + 0,0,0,0,0,0,0,0, # 10 - 17 + 0,0,0,3,0,0,0,0, # 18 - 1f + 0,0,0,0,0,0,0,0, # 20 - 27 + 0,3,3,3,3,3,0,0, # 28 - 2f + 0,0,0,0,0,0,0,0, # 30 - 37 + 0,0,0,0,0,0,0,0, # 38 - 3f + 0,0,0,0,0,0,0,0, # 40 - 47 + 0,0,0,0,0,0,0,0, # 48 - 4f + 0,0,0,0,0,0,0,0, # 50 - 57 + 0,0,0,0,0,0,0,0, # 58 - 5f + 0,0,0,0,0,0,0,0, # 60 - 67 + 0,0,0,0,0,0,0,0, # 68 - 6f + 0,0,0,0,0,0,0,0, # 70 - 77 + 0,0,0,0,0,0,0,0, # 78 - 7f + 0,0,0,0,0,0,0,0, # 80 - 87 + 0,0,0,0,0,0,0,0, # 88 - 8f + 0,0,0,0,0,0,0,0, # 90 - 97 + 0,0,0,0,0,0,0,0, # 98 - 9f + 0,0,0,0,0,0,0,0, # a0 - a7 + 0,0,0,0,0,0,0,0, # a8 - af + 0,0,0,0,0,0,0,0, # b0 - b7 + 0,0,0,0,0,0,0,0, # b8 - bf + 0,0,0,0,0,0,0,0, # c0 - c7 + 0,0,0,0,0,0,0,0, # c8 - cf + 0,0,0,0,0,0,0,0, # d0 - d7 + 0,0,0,0,0,0,0,0, # d8 - df + 0,0,0,0,0,0,0,0, # e0 - e7 + 0,0,0,0,0,0,0,0, # e8 - ef + 0,0,0,0,0,0,0,0, # f0 - f7 + 0,0,0,0,0,0,4,5 # f8 - ff +) + +UCS2LE_ST = ( + 6, 6, 7, 6, 4, 3,MachineState.ERROR,MachineState.ERROR,#00-07 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,#08-0f + MachineState.ITS_ME,MachineState.ITS_ME, 5, 5, 5,MachineState.ERROR,MachineState.ITS_ME,MachineState.ERROR,#10-17 + 5, 5, 5,MachineState.ERROR, 5,MachineState.ERROR, 6, 6,#18-1f + 7, 6, 8, 8, 5, 5, 5,MachineState.ERROR,#20-27 + 5, 5, 5,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 5, 5,#28-2f + 5, 5, 5,MachineState.ERROR, 5,MachineState.ERROR,MachineState.START,MachineState.START #30-37 +) + +UCS2LE_CHAR_LEN_TABLE = (2, 2, 2, 2, 2, 2) + +UCS2LE_SM_MODEL = {'class_table': UCS2LE_CLS, + 'class_factor': 6, + 'state_table': UCS2LE_ST, + 'char_len_table': UCS2LE_CHAR_LEN_TABLE, + 'name': 'UTF-16LE'} + +# UTF-8 + +UTF8_CLS = ( + 1,1,1,1,1,1,1,1, # 00 - 07 #allow 0x00 as a legal value + 1,1,1,1,1,1,0,0, # 08 - 0f + 1,1,1,1,1,1,1,1, # 10 - 17 + 1,1,1,0,1,1,1,1, # 18 - 1f + 1,1,1,1,1,1,1,1, # 20 - 27 + 1,1,1,1,1,1,1,1, # 28 - 2f + 1,1,1,1,1,1,1,1, # 30 - 37 + 1,1,1,1,1,1,1,1, # 38 - 3f + 1,1,1,1,1,1,1,1, # 40 - 47 + 1,1,1,1,1,1,1,1, # 48 - 4f + 1,1,1,1,1,1,1,1, # 50 - 57 + 1,1,1,1,1,1,1,1, # 58 - 5f + 1,1,1,1,1,1,1,1, # 60 - 67 + 1,1,1,1,1,1,1,1, # 68 - 6f + 1,1,1,1,1,1,1,1, # 70 - 77 + 1,1,1,1,1,1,1,1, # 78 - 7f + 2,2,2,2,3,3,3,3, # 80 - 87 + 4,4,4,4,4,4,4,4, # 88 - 8f + 4,4,4,4,4,4,4,4, # 90 - 97 + 4,4,4,4,4,4,4,4, # 98 - 9f + 5,5,5,5,5,5,5,5, # a0 - a7 + 5,5,5,5,5,5,5,5, # a8 - af + 5,5,5,5,5,5,5,5, # b0 - b7 + 5,5,5,5,5,5,5,5, # b8 - bf + 0,0,6,6,6,6,6,6, # c0 - c7 + 6,6,6,6,6,6,6,6, # c8 - cf + 6,6,6,6,6,6,6,6, # d0 - d7 + 6,6,6,6,6,6,6,6, # d8 - df + 7,8,8,8,8,8,8,8, # e0 - e7 + 8,8,8,8,8,9,8,8, # e8 - ef + 10,11,11,11,11,11,11,11, # f0 - f7 + 12,13,13,13,14,15,0,0 # f8 - ff +) + +UTF8_ST = ( + MachineState.ERROR,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 12, 10,#00-07 + 9, 11, 8, 7, 6, 5, 4, 3,#08-0f + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#10-17 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#18-1f + MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,#20-27 + MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,#28-2f + MachineState.ERROR,MachineState.ERROR, 5, 5, 5, 5,MachineState.ERROR,MachineState.ERROR,#30-37 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#38-3f + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 5, 5, 5,MachineState.ERROR,MachineState.ERROR,#40-47 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#48-4f + MachineState.ERROR,MachineState.ERROR, 7, 7, 7, 7,MachineState.ERROR,MachineState.ERROR,#50-57 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#58-5f + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 7, 7,MachineState.ERROR,MachineState.ERROR,#60-67 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#68-6f + MachineState.ERROR,MachineState.ERROR, 9, 9, 9, 9,MachineState.ERROR,MachineState.ERROR,#70-77 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#78-7f + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 9,MachineState.ERROR,MachineState.ERROR,#80-87 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#88-8f + MachineState.ERROR,MachineState.ERROR, 12, 12, 12, 12,MachineState.ERROR,MachineState.ERROR,#90-97 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#98-9f + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 12,MachineState.ERROR,MachineState.ERROR,#a0-a7 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#a8-af + MachineState.ERROR,MachineState.ERROR, 12, 12, 12,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#b0-b7 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#b8-bf + MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.ERROR,MachineState.ERROR,#c0-c7 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR #c8-cf +) + +UTF8_CHAR_LEN_TABLE = (0, 1, 0, 0, 0, 0, 2, 3, 3, 3, 4, 4, 5, 5, 6, 6) + +UTF8_SM_MODEL = {'class_table': UTF8_CLS, + 'class_factor': 16, + 'state_table': UTF8_ST, + 'char_len_table': UTF8_CHAR_LEN_TABLE, + 'name': 'UTF-8'} diff --git a/venv/Lib/site-packages/pip/_vendor/chardet/metadata/__init__.py b/venv/Lib/site-packages/pip/_vendor/chardet/metadata/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/venv/Lib/site-packages/pip/_vendor/chardet/metadata/languages.py b/venv/Lib/site-packages/pip/_vendor/chardet/metadata/languages.py new file mode 100644 index 0000000..3237d5a --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/chardet/metadata/languages.py @@ -0,0 +1,310 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +""" +Metadata about languages used by our model training code for our +SingleByteCharSetProbers. Could be used for other things in the future. + +This code is based on the language metadata from the uchardet project. +""" +from __future__ import absolute_import, print_function + +from string import ascii_letters + + +# TODO: Add Ukranian (KOI8-U) + +class Language(object): + """Metadata about a language useful for training models + + :ivar name: The human name for the language, in English. + :type name: str + :ivar iso_code: 2-letter ISO 639-1 if possible, 3-letter ISO code otherwise, + or use another catalog as a last resort. + :type iso_code: str + :ivar use_ascii: Whether or not ASCII letters should be included in trained + models. + :type use_ascii: bool + :ivar charsets: The charsets we want to support and create data for. + :type charsets: list of str + :ivar alphabet: The characters in the language's alphabet. If `use_ascii` is + `True`, you only need to add those not in the ASCII set. + :type alphabet: str + :ivar wiki_start_pages: The Wikipedia pages to start from if we're crawling + Wikipedia for training data. + :type wiki_start_pages: list of str + """ + def __init__(self, name=None, iso_code=None, use_ascii=True, charsets=None, + alphabet=None, wiki_start_pages=None): + super(Language, self).__init__() + self.name = name + self.iso_code = iso_code + self.use_ascii = use_ascii + self.charsets = charsets + if self.use_ascii: + if alphabet: + alphabet += ascii_letters + else: + alphabet = ascii_letters + elif not alphabet: + raise ValueError('Must supply alphabet if use_ascii is False') + self.alphabet = ''.join(sorted(set(alphabet))) if alphabet else None + self.wiki_start_pages = wiki_start_pages + + def __repr__(self): + return '{}({})'.format(self.__class__.__name__, + ', '.join('{}={!r}'.format(k, v) + for k, v in self.__dict__.items() + if not k.startswith('_'))) + + +LANGUAGES = {'Arabic': Language(name='Arabic', + iso_code='ar', + use_ascii=False, + # We only support encodings that use isolated + # forms, because the current recommendation is + # that the rendering system handles presentation + # forms. This means we purposefully skip IBM864. + charsets=['ISO-8859-6', 'WINDOWS-1256', + 'CP720', 'CP864'], + alphabet=u'ءآأؤإئابةتثجحخدذرزسشصضطظعغػؼؽؾؿـÙقكلمنهوىيًٌÙÙŽÙÙÙ‘', + wiki_start_pages=[u'Ø§Ù„ØµÙØ­Ø©_الرئيسية']), + 'Belarusian': Language(name='Belarusian', + iso_code='be', + use_ascii=False, + charsets=['ISO-8859-5', 'WINDOWS-1251', + 'IBM866', 'MacCyrillic'], + alphabet=(u'ÐБВГДЕÐЖЗІЙКЛМÐОПРСТУЎФХЦЧШЫЬЭЮЯ' + u'абвгдеёжзійклмнопрÑтуўфхцчшыьÑÑŽÑʼ'), + wiki_start_pages=[u'ГалоўнаÑ_Ñтаронка']), + 'Bulgarian': Language(name='Bulgarian', + iso_code='bg', + use_ascii=False, + charsets=['ISO-8859-5', 'WINDOWS-1251', + 'IBM855'], + alphabet=(u'ÐБВГДЕЖЗИЙКЛМÐОПРСТУФХЦЧШЩЪЬЮЯ' + u'абвгдежзийклмнопрÑтуфхцчшщъьюÑ'), + wiki_start_pages=[u'Ðачална_Ñтраница']), + 'Czech': Language(name='Czech', + iso_code='cz', + use_ascii=True, + charsets=['ISO-8859-2', 'WINDOWS-1250'], + alphabet=u'áÄÄéěíňóřšťúůýžÃČĎÉĚÃŇÓŘŠŤÚŮÃŽ', + wiki_start_pages=[u'Hlavní_strana']), + 'Danish': Language(name='Danish', + iso_code='da', + use_ascii=True, + charsets=['ISO-8859-1', 'ISO-8859-15', + 'WINDOWS-1252'], + alphabet=u'æøåÆØÅ', + wiki_start_pages=[u'Forside']), + 'German': Language(name='German', + iso_code='de', + use_ascii=True, + charsets=['ISO-8859-1', 'WINDOWS-1252'], + alphabet=u'äöüßÄÖÜ', + wiki_start_pages=[u'Wikipedia:Hauptseite']), + 'Greek': Language(name='Greek', + iso_code='el', + use_ascii=False, + charsets=['ISO-8859-7', 'WINDOWS-1253'], + alphabet=(u'αβγδεζηθικλμνξοπÏσςτυφχψωάέήίόÏÏŽ' + u'ΑΒΓΔΕΖΗΘΙΚΛΜÎΞΟΠΡΣΣΤΥΦΧΨΩΆΈΉΊΌΎÎ'), + wiki_start_pages=[u'ΠÏλη:ΚÏÏια']), + 'English': Language(name='English', + iso_code='en', + use_ascii=True, + charsets=['ISO-8859-1', 'WINDOWS-1252'], + wiki_start_pages=[u'Main_Page']), + 'Esperanto': Language(name='Esperanto', + iso_code='eo', + # Q, W, X, and Y not used at all + use_ascii=False, + charsets=['ISO-8859-3'], + alphabet=(u'abcĉdefgÄhÄ¥ijĵklmnoprsÅtuÅ­vz' + u'ABCĈDEFGÄœHĤIJÄ´KLMNOPRSÅœTUŬVZ'), + wiki_start_pages=[u'Vikipedio:ĈefpaÄo']), + 'Spanish': Language(name='Spanish', + iso_code='es', + use_ascii=True, + charsets=['ISO-8859-1', 'ISO-8859-15', + 'WINDOWS-1252'], + alphabet=u'ñáéíóúüÑÃÉÃÓÚÜ', + wiki_start_pages=[u'Wikipedia:Portada']), + 'Estonian': Language(name='Estonian', + iso_code='et', + use_ascii=False, + charsets=['ISO-8859-4', 'ISO-8859-13', + 'WINDOWS-1257'], + # C, F, Å , Q, W, X, Y, Z, Ž are only for + # loanwords + alphabet=(u'ABDEGHIJKLMNOPRSTUVÕÄÖÜ' + u'abdeghijklmnoprstuvõäöü'), + wiki_start_pages=[u'Esileht']), + 'Finnish': Language(name='Finnish', + iso_code='fi', + use_ascii=True, + charsets=['ISO-8859-1', 'ISO-8859-15', + 'WINDOWS-1252'], + alphabet=u'ÅÄÖŠŽåäöšž', + wiki_start_pages=[u'Wikipedia:Etusivu']), + 'French': Language(name='French', + iso_code='fr', + use_ascii=True, + charsets=['ISO-8859-1', 'ISO-8859-15', + 'WINDOWS-1252'], + alphabet=u'œàâçèéîïùûêŒÀÂÇÈÉÎÃÙÛÊ', + wiki_start_pages=[u'Wikipédia:Accueil_principal', + u'BÅ“uf (animal)']), + 'Hebrew': Language(name='Hebrew', + iso_code='he', + use_ascii=False, + charsets=['ISO-8859-8', 'WINDOWS-1255'], + alphabet=u'×בגדהוזחטיךכל×מןנסעףפץצקרשתװױײ', + wiki_start_pages=[u'עמוד_ר×שי']), + 'Croatian': Language(name='Croatian', + iso_code='hr', + # Q, W, X, Y are only used for foreign words. + use_ascii=False, + charsets=['ISO-8859-2', 'WINDOWS-1250'], + alphabet=(u'abcÄćdÄ‘efghijklmnoprsÅ¡tuvzž' + u'ABCČĆDÄEFGHIJKLMNOPRSÅ TUVZŽ'), + wiki_start_pages=[u'Glavna_stranica']), + 'Hungarian': Language(name='Hungarian', + iso_code='hu', + # Q, W, X, Y are only used for foreign words. + use_ascii=False, + charsets=['ISO-8859-2', 'WINDOWS-1250'], + alphabet=(u'abcdefghijklmnoprstuvzáéíóöőúüű' + u'ABCDEFGHIJKLMNOPRSTUVZÃÉÃÓÖÅÚÜŰ'), + wiki_start_pages=[u'KezdÅ‘lap']), + 'Italian': Language(name='Italian', + iso_code='it', + use_ascii=True, + charsets=['ISO-8859-1', 'ISO-8859-15', + 'WINDOWS-1252'], + alphabet=u'ÀÈÉÌÒÓÙàèéìòóù', + wiki_start_pages=[u'Pagina_principale']), + 'Lithuanian': Language(name='Lithuanian', + iso_code='lt', + use_ascii=False, + charsets=['ISO-8859-13', 'WINDOWS-1257', + 'ISO-8859-4'], + # Q, W, and X not used at all + alphabet=(u'AÄ„BCÄŒDEĘĖFGHIÄ®YJKLMNOPRSÅ TUŲŪVZŽ' + u'aÄ…bcÄdeęėfghiįyjklmnoprsÅ¡tuųūvzž'), + wiki_start_pages=[u'Pagrindinis_puslapis']), + 'Latvian': Language(name='Latvian', + iso_code='lv', + use_ascii=False, + charsets=['ISO-8859-13', 'WINDOWS-1257', + 'ISO-8859-4'], + # Q, W, X, Y are only for loanwords + alphabet=(u'AÄ€BCÄŒDEÄ’FGÄ¢HIĪJKĶLÄ»MNÅ…OPRSÅ TUŪVZŽ' + u'aÄbcÄdeÄ“fgÄ£hiÄ«jkÄ·lļmnņoprsÅ¡tuÅ«vzž'), + wiki_start_pages=[u'SÄkumlapa']), + 'Macedonian': Language(name='Macedonian', + iso_code='mk', + use_ascii=False, + charsets=['ISO-8859-5', 'WINDOWS-1251', + 'MacCyrillic', 'IBM855'], + alphabet=(u'ÐБВГДЃЕЖЗЅИЈКЛЉМÐЊОПРСТЌУФХЦЧÐШ' + u'абвгдѓежзѕијклљмнњопрÑтќуфхцчџш'), + wiki_start_pages=[u'Главна_Ñтраница']), + 'Dutch': Language(name='Dutch', + iso_code='nl', + use_ascii=True, + charsets=['ISO-8859-1', 'WINDOWS-1252'], + wiki_start_pages=[u'Hoofdpagina']), + 'Polish': Language(name='Polish', + iso_code='pl', + # Q and X are only used for foreign words. + use_ascii=False, + charsets=['ISO-8859-2', 'WINDOWS-1250'], + alphabet=(u'AÄ„BCĆDEĘFGHIJKLÅMNŃOÓPRSÅšTUWYZŹŻ' + u'aÄ…bcćdeÄ™fghijklÅ‚mnÅ„oóprsÅ›tuwyzźż'), + wiki_start_pages=[u'Wikipedia:Strona_główna']), + 'Portuguese': Language(name='Portuguese', + iso_code='pt', + use_ascii=True, + charsets=['ISO-8859-1', 'ISO-8859-15', + 'WINDOWS-1252'], + alphabet=u'ÃÂÃÀÇÉÊÃÓÔÕÚáâãàçéêíóôõú', + wiki_start_pages=[u'Wikipédia:Página_principal']), + 'Romanian': Language(name='Romanian', + iso_code='ro', + use_ascii=True, + charsets=['ISO-8859-2', 'WINDOWS-1250'], + alphabet=u'ăâîșțĂÂÎȘȚ', + wiki_start_pages=[u'Pagina_principală']), + 'Russian': Language(name='Russian', + iso_code='ru', + use_ascii=False, + charsets=['ISO-8859-5', 'WINDOWS-1251', + 'KOI8-R', 'MacCyrillic', 'IBM866', + 'IBM855'], + alphabet=(u'абвгдеёжзийклмнопрÑтуфхцчшщъыьÑÑŽÑ' + u'ÐБВГДЕÐЖЗИЙКЛМÐОПРСТУФХЦЧШЩЪЫЬЭЮЯ'), + wiki_start_pages=[u'ЗаглавнаÑ_Ñтраница']), + 'Slovak': Language(name='Slovak', + iso_code='sk', + use_ascii=True, + charsets=['ISO-8859-2', 'WINDOWS-1250'], + alphabet=u'áäÄÄéíĺľňóôŕšťúýžÃÄČĎÉÃĹĽŇÓÔŔŠŤÚÃŽ', + wiki_start_pages=[u'Hlavná_stránka']), + 'Slovene': Language(name='Slovene', + iso_code='sl', + # Q, W, X, Y are only used for foreign words. + use_ascii=False, + charsets=['ISO-8859-2', 'WINDOWS-1250'], + alphabet=(u'abcÄdefghijklmnoprsÅ¡tuvzž' + u'ABCÄŒDEFGHIJKLMNOPRSÅ TUVZŽ'), + wiki_start_pages=[u'Glavna_stran']), + # Serbian can be written in both Latin and Cyrillic, but there's no + # simple way to get the Latin alphabet pages from Wikipedia through + # the API, so for now we just support Cyrillic. + 'Serbian': Language(name='Serbian', + iso_code='sr', + alphabet=(u'ÐБВГДЂЕЖЗИЈКЛЉМÐЊОПРСТЋУФХЦЧÐШ' + u'абвгдђежзијклљмнњопрÑтћуфхцчџш'), + charsets=['ISO-8859-5', 'WINDOWS-1251', + 'MacCyrillic', 'IBM855'], + wiki_start_pages=[u'Главна_Ñтрана']), + 'Thai': Language(name='Thai', + iso_code='th', + use_ascii=False, + charsets=['ISO-8859-11', 'TIS-620', 'CP874'], + alphabet=u'à¸à¸‚ฃคฅฆงจฉชซฌà¸à¸Žà¸à¸à¸‘ฒณดตถทธนบปผà¸à¸žà¸Ÿà¸ à¸¡à¸¢à¸£à¸¤à¸¥à¸¦à¸§à¸¨à¸©à¸ªà¸«à¸¬à¸­à¸®à¸¯à¸°à¸±à¸²à¸³à¸´à¸µà¸¶à¸·à¸ºà¸¸à¸¹à¸¿à¹€à¹à¹‚ใไๅๆ็่้๊๋์à¹à¹Žà¹à¹à¹‘๒๓๔๕๖๗๘๙๚๛', + wiki_start_pages=[u'หน้าหลัà¸']), + 'Turkish': Language(name='Turkish', + iso_code='tr', + # Q, W, and X are not used by Turkish + use_ascii=False, + charsets=['ISO-8859-3', 'ISO-8859-9', + 'WINDOWS-1254'], + alphabet=(u'abcçdefgÄŸhıijklmnoöprsÅŸtuüvyzâîû' + u'ABCÇDEFGÄžHIİJKLMNOÖPRSÅžTUÜVYZÂÎÛ'), + wiki_start_pages=[u'Ana_Sayfa']), + 'Vietnamese': Language(name='Vietnamese', + iso_code='vi', + use_ascii=False, + # Windows-1258 is the only common 8-bit + # Vietnamese encoding supported by Python. + # From Wikipedia: + # For systems that lack support for Unicode, + # dozens of 8-bit Vietnamese code pages are + # available.[1] The most common are VISCII + # (TCVN 5712:1993), VPS, and Windows-1258.[3] + # Where ASCII is required, such as when + # ensuring readability in plain text e-mail, + # Vietnamese letters are often encoded + # according to Vietnamese Quoted-Readable + # (VIQR) or VSCII Mnemonic (VSCII-MNEM),[4] + # though usage of either variable-width + # scheme has declined dramatically following + # the adoption of Unicode on the World Wide + # Web. + charsets=['WINDOWS-1258'], + alphabet=(u'aăâbcdÄ‘eêghiklmnoôơpqrstuưvxy' + u'AĂÂBCDÄEÊGHIKLMNOÔƠPQRSTUƯVXY'), + wiki_start_pages=[u'Chữ_Quốc_ngữ']), + } diff --git a/venv/Lib/site-packages/pip/_vendor/chardet/sbcharsetprober.py b/venv/Lib/site-packages/pip/_vendor/chardet/sbcharsetprober.py new file mode 100644 index 0000000..46ba835 --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/chardet/sbcharsetprober.py @@ -0,0 +1,145 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Universal charset detector code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 2001 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# Shy Shalom - original C code +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from collections import namedtuple + +from .charsetprober import CharSetProber +from .enums import CharacterCategory, ProbingState, SequenceLikelihood + + +SingleByteCharSetModel = namedtuple('SingleByteCharSetModel', + ['charset_name', + 'language', + 'char_to_order_map', + 'language_model', + 'typical_positive_ratio', + 'keep_ascii_letters', + 'alphabet']) + + +class SingleByteCharSetProber(CharSetProber): + SAMPLE_SIZE = 64 + SB_ENOUGH_REL_THRESHOLD = 1024 # 0.25 * SAMPLE_SIZE^2 + POSITIVE_SHORTCUT_THRESHOLD = 0.95 + NEGATIVE_SHORTCUT_THRESHOLD = 0.05 + + def __init__(self, model, reversed=False, name_prober=None): + super(SingleByteCharSetProber, self).__init__() + self._model = model + # TRUE if we need to reverse every pair in the model lookup + self._reversed = reversed + # Optional auxiliary prober for name decision + self._name_prober = name_prober + self._last_order = None + self._seq_counters = None + self._total_seqs = None + self._total_char = None + self._freq_char = None + self.reset() + + def reset(self): + super(SingleByteCharSetProber, self).reset() + # char order of last character + self._last_order = 255 + self._seq_counters = [0] * SequenceLikelihood.get_num_categories() + self._total_seqs = 0 + self._total_char = 0 + # characters that fall in our sampling range + self._freq_char = 0 + + @property + def charset_name(self): + if self._name_prober: + return self._name_prober.charset_name + else: + return self._model.charset_name + + @property + def language(self): + if self._name_prober: + return self._name_prober.language + else: + return self._model.language + + def feed(self, byte_str): + # TODO: Make filter_international_words keep things in self.alphabet + if not self._model.keep_ascii_letters: + byte_str = self.filter_international_words(byte_str) + if not byte_str: + return self.state + char_to_order_map = self._model.char_to_order_map + language_model = self._model.language_model + for char in byte_str: + order = char_to_order_map.get(char, CharacterCategory.UNDEFINED) + # XXX: This was SYMBOL_CAT_ORDER before, with a value of 250, but + # CharacterCategory.SYMBOL is actually 253, so we use CONTROL + # to make it closer to the original intent. The only difference + # is whether or not we count digits and control characters for + # _total_char purposes. + if order < CharacterCategory.CONTROL: + self._total_char += 1 + # TODO: Follow uchardet's lead and discount confidence for frequent + # control characters. + # See https://github.com/BYVoid/uchardet/commit/55b4f23971db61 + if order < self.SAMPLE_SIZE: + self._freq_char += 1 + if self._last_order < self.SAMPLE_SIZE: + self._total_seqs += 1 + if not self._reversed: + lm_cat = language_model[self._last_order][order] + else: + lm_cat = language_model[order][self._last_order] + self._seq_counters[lm_cat] += 1 + self._last_order = order + + charset_name = self._model.charset_name + if self.state == ProbingState.DETECTING: + if self._total_seqs > self.SB_ENOUGH_REL_THRESHOLD: + confidence = self.get_confidence() + if confidence > self.POSITIVE_SHORTCUT_THRESHOLD: + self.logger.debug('%s confidence = %s, we have a winner', + charset_name, confidence) + self._state = ProbingState.FOUND_IT + elif confidence < self.NEGATIVE_SHORTCUT_THRESHOLD: + self.logger.debug('%s confidence = %s, below negative ' + 'shortcut threshhold %s', charset_name, + confidence, + self.NEGATIVE_SHORTCUT_THRESHOLD) + self._state = ProbingState.NOT_ME + + return self.state + + def get_confidence(self): + r = 0.01 + if self._total_seqs > 0: + r = ((1.0 * self._seq_counters[SequenceLikelihood.POSITIVE]) / + self._total_seqs / self._model.typical_positive_ratio) + r = r * self._freq_char / self._total_char + if r >= 1.0: + r = 0.99 + return r diff --git a/venv/Lib/site-packages/pip/_vendor/chardet/sbcsgroupprober.py b/venv/Lib/site-packages/pip/_vendor/chardet/sbcsgroupprober.py new file mode 100644 index 0000000..bdeef4e --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/chardet/sbcsgroupprober.py @@ -0,0 +1,83 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Universal charset detector code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 2001 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# Shy Shalom - original C code +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .charsetgroupprober import CharSetGroupProber +from .hebrewprober import HebrewProber +from .langbulgarianmodel import (ISO_8859_5_BULGARIAN_MODEL, + WINDOWS_1251_BULGARIAN_MODEL) +from .langgreekmodel import ISO_8859_7_GREEK_MODEL, WINDOWS_1253_GREEK_MODEL +from .langhebrewmodel import WINDOWS_1255_HEBREW_MODEL +# from .langhungarianmodel import (ISO_8859_2_HUNGARIAN_MODEL, +# WINDOWS_1250_HUNGARIAN_MODEL) +from .langrussianmodel import (IBM855_RUSSIAN_MODEL, IBM866_RUSSIAN_MODEL, + ISO_8859_5_RUSSIAN_MODEL, KOI8_R_RUSSIAN_MODEL, + MACCYRILLIC_RUSSIAN_MODEL, + WINDOWS_1251_RUSSIAN_MODEL) +from .langthaimodel import TIS_620_THAI_MODEL +from .langturkishmodel import ISO_8859_9_TURKISH_MODEL +from .sbcharsetprober import SingleByteCharSetProber + + +class SBCSGroupProber(CharSetGroupProber): + def __init__(self): + super(SBCSGroupProber, self).__init__() + hebrew_prober = HebrewProber() + logical_hebrew_prober = SingleByteCharSetProber(WINDOWS_1255_HEBREW_MODEL, + False, hebrew_prober) + # TODO: See if using ISO-8859-8 Hebrew model works better here, since + # it's actually the visual one + visual_hebrew_prober = SingleByteCharSetProber(WINDOWS_1255_HEBREW_MODEL, + True, hebrew_prober) + hebrew_prober.set_model_probers(logical_hebrew_prober, + visual_hebrew_prober) + # TODO: ORDER MATTERS HERE. I changed the order vs what was in master + # and several tests failed that did not before. Some thought + # should be put into the ordering, and we should consider making + # order not matter here, because that is very counter-intuitive. + self.probers = [ + SingleByteCharSetProber(WINDOWS_1251_RUSSIAN_MODEL), + SingleByteCharSetProber(KOI8_R_RUSSIAN_MODEL), + SingleByteCharSetProber(ISO_8859_5_RUSSIAN_MODEL), + SingleByteCharSetProber(MACCYRILLIC_RUSSIAN_MODEL), + SingleByteCharSetProber(IBM866_RUSSIAN_MODEL), + SingleByteCharSetProber(IBM855_RUSSIAN_MODEL), + SingleByteCharSetProber(ISO_8859_7_GREEK_MODEL), + SingleByteCharSetProber(WINDOWS_1253_GREEK_MODEL), + SingleByteCharSetProber(ISO_8859_5_BULGARIAN_MODEL), + SingleByteCharSetProber(WINDOWS_1251_BULGARIAN_MODEL), + # TODO: Restore Hungarian encodings (iso-8859-2 and windows-1250) + # after we retrain model. + # SingleByteCharSetProber(ISO_8859_2_HUNGARIAN_MODEL), + # SingleByteCharSetProber(WINDOWS_1250_HUNGARIAN_MODEL), + SingleByteCharSetProber(TIS_620_THAI_MODEL), + SingleByteCharSetProber(ISO_8859_9_TURKISH_MODEL), + hebrew_prober, + logical_hebrew_prober, + visual_hebrew_prober, + ] + self.reset() diff --git a/venv/Lib/site-packages/pip/_vendor/chardet/sjisprober.py b/venv/Lib/site-packages/pip/_vendor/chardet/sjisprober.py new file mode 100644 index 0000000..9e29623 --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/chardet/sjisprober.py @@ -0,0 +1,92 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .mbcharsetprober import MultiByteCharSetProber +from .codingstatemachine import CodingStateMachine +from .chardistribution import SJISDistributionAnalysis +from .jpcntx import SJISContextAnalysis +from .mbcssm import SJIS_SM_MODEL +from .enums import ProbingState, MachineState + + +class SJISProber(MultiByteCharSetProber): + def __init__(self): + super(SJISProber, self).__init__() + self.coding_sm = CodingStateMachine(SJIS_SM_MODEL) + self.distribution_analyzer = SJISDistributionAnalysis() + self.context_analyzer = SJISContextAnalysis() + self.reset() + + def reset(self): + super(SJISProber, self).reset() + self.context_analyzer.reset() + + @property + def charset_name(self): + return self.context_analyzer.charset_name + + @property + def language(self): + return "Japanese" + + def feed(self, byte_str): + for i in range(len(byte_str)): + coding_state = self.coding_sm.next_state(byte_str[i]) + if coding_state == MachineState.ERROR: + self.logger.debug('%s %s prober hit error at byte %s', + self.charset_name, self.language, i) + self._state = ProbingState.NOT_ME + break + elif coding_state == MachineState.ITS_ME: + self._state = ProbingState.FOUND_IT + break + elif coding_state == MachineState.START: + char_len = self.coding_sm.get_current_charlen() + if i == 0: + self._last_char[1] = byte_str[0] + self.context_analyzer.feed(self._last_char[2 - char_len:], + char_len) + self.distribution_analyzer.feed(self._last_char, char_len) + else: + self.context_analyzer.feed(byte_str[i + 1 - char_len:i + 3 + - char_len], char_len) + self.distribution_analyzer.feed(byte_str[i - 1:i + 1], + char_len) + + self._last_char[0] = byte_str[-1] + + if self.state == ProbingState.DETECTING: + if (self.context_analyzer.got_enough_data() and + (self.get_confidence() > self.SHORTCUT_THRESHOLD)): + self._state = ProbingState.FOUND_IT + + return self.state + + def get_confidence(self): + context_conf = self.context_analyzer.get_confidence() + distrib_conf = self.distribution_analyzer.get_confidence() + return max(context_conf, distrib_conf) diff --git a/venv/Lib/site-packages/pip/_vendor/chardet/universaldetector.py b/venv/Lib/site-packages/pip/_vendor/chardet/universaldetector.py new file mode 100644 index 0000000..055a8ac --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/chardet/universaldetector.py @@ -0,0 +1,286 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Universal charset detector code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 2001 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# Shy Shalom - original C code +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### +""" +Module containing the UniversalDetector detector class, which is the primary +class a user of ``chardet`` should use. + +:author: Mark Pilgrim (initial port to Python) +:author: Shy Shalom (original C code) +:author: Dan Blanchard (major refactoring for 3.0) +:author: Ian Cordasco +""" + + +import codecs +import logging +import re + +from .charsetgroupprober import CharSetGroupProber +from .enums import InputState, LanguageFilter, ProbingState +from .escprober import EscCharSetProber +from .latin1prober import Latin1Prober +from .mbcsgroupprober import MBCSGroupProber +from .sbcsgroupprober import SBCSGroupProber + + +class UniversalDetector(object): + """ + The ``UniversalDetector`` class underlies the ``chardet.detect`` function + and coordinates all of the different charset probers. + + To get a ``dict`` containing an encoding and its confidence, you can simply + run: + + .. code:: + + u = UniversalDetector() + u.feed(some_bytes) + u.close() + detected = u.result + + """ + + MINIMUM_THRESHOLD = 0.20 + HIGH_BYTE_DETECTOR = re.compile(b'[\x80-\xFF]') + ESC_DETECTOR = re.compile(b'(\033|~{)') + WIN_BYTE_DETECTOR = re.compile(b'[\x80-\x9F]') + ISO_WIN_MAP = {'iso-8859-1': 'Windows-1252', + 'iso-8859-2': 'Windows-1250', + 'iso-8859-5': 'Windows-1251', + 'iso-8859-6': 'Windows-1256', + 'iso-8859-7': 'Windows-1253', + 'iso-8859-8': 'Windows-1255', + 'iso-8859-9': 'Windows-1254', + 'iso-8859-13': 'Windows-1257'} + + def __init__(self, lang_filter=LanguageFilter.ALL): + self._esc_charset_prober = None + self._charset_probers = [] + self.result = None + self.done = None + self._got_data = None + self._input_state = None + self._last_char = None + self.lang_filter = lang_filter + self.logger = logging.getLogger(__name__) + self._has_win_bytes = None + self.reset() + + def reset(self): + """ + Reset the UniversalDetector and all of its probers back to their + initial states. This is called by ``__init__``, so you only need to + call this directly in between analyses of different documents. + """ + self.result = {'encoding': None, 'confidence': 0.0, 'language': None} + self.done = False + self._got_data = False + self._has_win_bytes = False + self._input_state = InputState.PURE_ASCII + self._last_char = b'' + if self._esc_charset_prober: + self._esc_charset_prober.reset() + for prober in self._charset_probers: + prober.reset() + + def feed(self, byte_str): + """ + Takes a chunk of a document and feeds it through all of the relevant + charset probers. + + After calling ``feed``, you can check the value of the ``done`` + attribute to see if you need to continue feeding the + ``UniversalDetector`` more data, or if it has made a prediction + (in the ``result`` attribute). + + .. note:: + You should always call ``close`` when you're done feeding in your + document if ``done`` is not already ``True``. + """ + if self.done: + return + + if not len(byte_str): + return + + if not isinstance(byte_str, bytearray): + byte_str = bytearray(byte_str) + + # First check for known BOMs, since these are guaranteed to be correct + if not self._got_data: + # If the data starts with BOM, we know it is UTF + if byte_str.startswith(codecs.BOM_UTF8): + # EF BB BF UTF-8 with BOM + self.result = {'encoding': "UTF-8-SIG", + 'confidence': 1.0, + 'language': ''} + elif byte_str.startswith((codecs.BOM_UTF32_LE, + codecs.BOM_UTF32_BE)): + # FF FE 00 00 UTF-32, little-endian BOM + # 00 00 FE FF UTF-32, big-endian BOM + self.result = {'encoding': "UTF-32", + 'confidence': 1.0, + 'language': ''} + elif byte_str.startswith(b'\xFE\xFF\x00\x00'): + # FE FF 00 00 UCS-4, unusual octet order BOM (3412) + self.result = {'encoding': "X-ISO-10646-UCS-4-3412", + 'confidence': 1.0, + 'language': ''} + elif byte_str.startswith(b'\x00\x00\xFF\xFE'): + # 00 00 FF FE UCS-4, unusual octet order BOM (2143) + self.result = {'encoding': "X-ISO-10646-UCS-4-2143", + 'confidence': 1.0, + 'language': ''} + elif byte_str.startswith((codecs.BOM_LE, codecs.BOM_BE)): + # FF FE UTF-16, little endian BOM + # FE FF UTF-16, big endian BOM + self.result = {'encoding': "UTF-16", + 'confidence': 1.0, + 'language': ''} + + self._got_data = True + if self.result['encoding'] is not None: + self.done = True + return + + # If none of those matched and we've only see ASCII so far, check + # for high bytes and escape sequences + if self._input_state == InputState.PURE_ASCII: + if self.HIGH_BYTE_DETECTOR.search(byte_str): + self._input_state = InputState.HIGH_BYTE + elif self._input_state == InputState.PURE_ASCII and \ + self.ESC_DETECTOR.search(self._last_char + byte_str): + self._input_state = InputState.ESC_ASCII + + self._last_char = byte_str[-1:] + + # If we've seen escape sequences, use the EscCharSetProber, which + # uses a simple state machine to check for known escape sequences in + # HZ and ISO-2022 encodings, since those are the only encodings that + # use such sequences. + if self._input_state == InputState.ESC_ASCII: + if not self._esc_charset_prober: + self._esc_charset_prober = EscCharSetProber(self.lang_filter) + if self._esc_charset_prober.feed(byte_str) == ProbingState.FOUND_IT: + self.result = {'encoding': + self._esc_charset_prober.charset_name, + 'confidence': + self._esc_charset_prober.get_confidence(), + 'language': + self._esc_charset_prober.language} + self.done = True + # If we've seen high bytes (i.e., those with values greater than 127), + # we need to do more complicated checks using all our multi-byte and + # single-byte probers that are left. The single-byte probers + # use character bigram distributions to determine the encoding, whereas + # the multi-byte probers use a combination of character unigram and + # bigram distributions. + elif self._input_state == InputState.HIGH_BYTE: + if not self._charset_probers: + self._charset_probers = [MBCSGroupProber(self.lang_filter)] + # If we're checking non-CJK encodings, use single-byte prober + if self.lang_filter & LanguageFilter.NON_CJK: + self._charset_probers.append(SBCSGroupProber()) + self._charset_probers.append(Latin1Prober()) + for prober in self._charset_probers: + if prober.feed(byte_str) == ProbingState.FOUND_IT: + self.result = {'encoding': prober.charset_name, + 'confidence': prober.get_confidence(), + 'language': prober.language} + self.done = True + break + if self.WIN_BYTE_DETECTOR.search(byte_str): + self._has_win_bytes = True + + def close(self): + """ + Stop analyzing the current document and come up with a final + prediction. + + :returns: The ``result`` attribute, a ``dict`` with the keys + `encoding`, `confidence`, and `language`. + """ + # Don't bother with checks if we're already done + if self.done: + return self.result + self.done = True + + if not self._got_data: + self.logger.debug('no data received!') + + # Default to ASCII if it is all we've seen so far + elif self._input_state == InputState.PURE_ASCII: + self.result = {'encoding': 'ascii', + 'confidence': 1.0, + 'language': ''} + + # If we have seen non-ASCII, return the best that met MINIMUM_THRESHOLD + elif self._input_state == InputState.HIGH_BYTE: + prober_confidence = None + max_prober_confidence = 0.0 + max_prober = None + for prober in self._charset_probers: + if not prober: + continue + prober_confidence = prober.get_confidence() + if prober_confidence > max_prober_confidence: + max_prober_confidence = prober_confidence + max_prober = prober + if max_prober and (max_prober_confidence > self.MINIMUM_THRESHOLD): + charset_name = max_prober.charset_name + lower_charset_name = max_prober.charset_name.lower() + confidence = max_prober.get_confidence() + # Use Windows encoding name instead of ISO-8859 if we saw any + # extra Windows-specific bytes + if lower_charset_name.startswith('iso-8859'): + if self._has_win_bytes: + charset_name = self.ISO_WIN_MAP.get(lower_charset_name, + charset_name) + self.result = {'encoding': charset_name, + 'confidence': confidence, + 'language': max_prober.language} + + # Log all prober confidences if none met MINIMUM_THRESHOLD + if self.logger.getEffectiveLevel() <= logging.DEBUG: + if self.result['encoding'] is None: + self.logger.debug('no probers hit minimum threshold') + for group_prober in self._charset_probers: + if not group_prober: + continue + if isinstance(group_prober, CharSetGroupProber): + for prober in group_prober.probers: + self.logger.debug('%s %s confidence = %s', + prober.charset_name, + prober.language, + prober.get_confidence()) + else: + self.logger.debug('%s %s confidence = %s', + group_prober.charset_name, + group_prober.language, + group_prober.get_confidence()) + return self.result diff --git a/venv/Lib/site-packages/pip/_vendor/chardet/utf8prober.py b/venv/Lib/site-packages/pip/_vendor/chardet/utf8prober.py new file mode 100644 index 0000000..6c3196c --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/chardet/utf8prober.py @@ -0,0 +1,82 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .charsetprober import CharSetProber +from .enums import ProbingState, MachineState +from .codingstatemachine import CodingStateMachine +from .mbcssm import UTF8_SM_MODEL + + + +class UTF8Prober(CharSetProber): + ONE_CHAR_PROB = 0.5 + + def __init__(self): + super(UTF8Prober, self).__init__() + self.coding_sm = CodingStateMachine(UTF8_SM_MODEL) + self._num_mb_chars = None + self.reset() + + def reset(self): + super(UTF8Prober, self).reset() + self.coding_sm.reset() + self._num_mb_chars = 0 + + @property + def charset_name(self): + return "utf-8" + + @property + def language(self): + return "" + + def feed(self, byte_str): + for c in byte_str: + coding_state = self.coding_sm.next_state(c) + if coding_state == MachineState.ERROR: + self._state = ProbingState.NOT_ME + break + elif coding_state == MachineState.ITS_ME: + self._state = ProbingState.FOUND_IT + break + elif coding_state == MachineState.START: + if self.coding_sm.get_current_charlen() >= 2: + self._num_mb_chars += 1 + + if self.state == ProbingState.DETECTING: + if self.get_confidence() > self.SHORTCUT_THRESHOLD: + self._state = ProbingState.FOUND_IT + + return self.state + + def get_confidence(self): + unlike = 0.99 + if self._num_mb_chars < 6: + unlike *= self.ONE_CHAR_PROB ** self._num_mb_chars + return 1.0 - unlike + else: + return unlike diff --git a/venv/Lib/site-packages/pip/_vendor/chardet/version.py b/venv/Lib/site-packages/pip/_vendor/chardet/version.py new file mode 100644 index 0000000..70369b9 --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/chardet/version.py @@ -0,0 +1,9 @@ +""" +This module exists only to simplify retrieving the version number of chardet +from within setup.py and from chardet subpackages. + +:author: Dan Blanchard (dan.blanchard@gmail.com) +""" + +__version__ = "4.0.0" +VERSION = __version__.split('.') diff --git a/venv/Lib/site-packages/pip/_vendor/colorama/__init__.py b/venv/Lib/site-packages/pip/_vendor/colorama/__init__.py new file mode 100644 index 0000000..b149ed7 --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/colorama/__init__.py @@ -0,0 +1,6 @@ +# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. +from .initialise import init, deinit, reinit, colorama_text +from .ansi import Fore, Back, Style, Cursor +from .ansitowin32 import AnsiToWin32 + +__version__ = '0.4.4' diff --git a/venv/Lib/site-packages/pip/_vendor/colorama/ansi.py b/venv/Lib/site-packages/pip/_vendor/colorama/ansi.py new file mode 100644 index 0000000..11ec695 --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/colorama/ansi.py @@ -0,0 +1,102 @@ +# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. +''' +This module generates ANSI character codes to printing colors to terminals. +See: http://en.wikipedia.org/wiki/ANSI_escape_code +''' + +CSI = '\033[' +OSC = '\033]' +BEL = '\a' + + +def code_to_chars(code): + return CSI + str(code) + 'm' + +def set_title(title): + return OSC + '2;' + title + BEL + +def clear_screen(mode=2): + return CSI + str(mode) + 'J' + +def clear_line(mode=2): + return CSI + str(mode) + 'K' + + +class AnsiCodes(object): + def __init__(self): + # the subclasses declare class attributes which are numbers. + # Upon instantiation we define instance attributes, which are the same + # as the class attributes but wrapped with the ANSI escape sequence + for name in dir(self): + if not name.startswith('_'): + value = getattr(self, name) + setattr(self, name, code_to_chars(value)) + + +class AnsiCursor(object): + def UP(self, n=1): + return CSI + str(n) + 'A' + def DOWN(self, n=1): + return CSI + str(n) + 'B' + def FORWARD(self, n=1): + return CSI + str(n) + 'C' + def BACK(self, n=1): + return CSI + str(n) + 'D' + def POS(self, x=1, y=1): + return CSI + str(y) + ';' + str(x) + 'H' + + +class AnsiFore(AnsiCodes): + BLACK = 30 + RED = 31 + GREEN = 32 + YELLOW = 33 + BLUE = 34 + MAGENTA = 35 + CYAN = 36 + WHITE = 37 + RESET = 39 + + # These are fairly well supported, but not part of the standard. + LIGHTBLACK_EX = 90 + LIGHTRED_EX = 91 + LIGHTGREEN_EX = 92 + LIGHTYELLOW_EX = 93 + LIGHTBLUE_EX = 94 + LIGHTMAGENTA_EX = 95 + LIGHTCYAN_EX = 96 + LIGHTWHITE_EX = 97 + + +class AnsiBack(AnsiCodes): + BLACK = 40 + RED = 41 + GREEN = 42 + YELLOW = 43 + BLUE = 44 + MAGENTA = 45 + CYAN = 46 + WHITE = 47 + RESET = 49 + + # These are fairly well supported, but not part of the standard. + LIGHTBLACK_EX = 100 + LIGHTRED_EX = 101 + LIGHTGREEN_EX = 102 + LIGHTYELLOW_EX = 103 + LIGHTBLUE_EX = 104 + LIGHTMAGENTA_EX = 105 + LIGHTCYAN_EX = 106 + LIGHTWHITE_EX = 107 + + +class AnsiStyle(AnsiCodes): + BRIGHT = 1 + DIM = 2 + NORMAL = 22 + RESET_ALL = 0 + +Fore = AnsiFore() +Back = AnsiBack() +Style = AnsiStyle() +Cursor = AnsiCursor() diff --git a/venv/Lib/site-packages/pip/_vendor/colorama/ansitowin32.py b/venv/Lib/site-packages/pip/_vendor/colorama/ansitowin32.py new file mode 100644 index 0000000..6039a05 --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/colorama/ansitowin32.py @@ -0,0 +1,258 @@ +# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. +import re +import sys +import os + +from .ansi import AnsiFore, AnsiBack, AnsiStyle, Style, BEL +from .winterm import WinTerm, WinColor, WinStyle +from .win32 import windll, winapi_test + + +winterm = None +if windll is not None: + winterm = WinTerm() + + +class StreamWrapper(object): + ''' + Wraps a stream (such as stdout), acting as a transparent proxy for all + attribute access apart from method 'write()', which is delegated to our + Converter instance. + ''' + def __init__(self, wrapped, converter): + # double-underscore everything to prevent clashes with names of + # attributes on the wrapped stream object. + self.__wrapped = wrapped + self.__convertor = converter + + def __getattr__(self, name): + return getattr(self.__wrapped, name) + + def __enter__(self, *args, **kwargs): + # special method lookup bypasses __getattr__/__getattribute__, see + # https://stackoverflow.com/questions/12632894/why-doesnt-getattr-work-with-exit + # thus, contextlib magic methods are not proxied via __getattr__ + return self.__wrapped.__enter__(*args, **kwargs) + + def __exit__(self, *args, **kwargs): + return self.__wrapped.__exit__(*args, **kwargs) + + def write(self, text): + self.__convertor.write(text) + + def isatty(self): + stream = self.__wrapped + if 'PYCHARM_HOSTED' in os.environ: + if stream is not None and (stream is sys.__stdout__ or stream is sys.__stderr__): + return True + try: + stream_isatty = stream.isatty + except AttributeError: + return False + else: + return stream_isatty() + + @property + def closed(self): + stream = self.__wrapped + try: + return stream.closed + except AttributeError: + return True + + +class AnsiToWin32(object): + ''' + Implements a 'write()' method which, on Windows, will strip ANSI character + sequences from the text, and if outputting to a tty, will convert them into + win32 function calls. + ''' + ANSI_CSI_RE = re.compile('\001?\033\\[((?:\\d|;)*)([a-zA-Z])\002?') # Control Sequence Introducer + ANSI_OSC_RE = re.compile('\001?\033\\]([^\a]*)(\a)\002?') # Operating System Command + + def __init__(self, wrapped, convert=None, strip=None, autoreset=False): + # The wrapped stream (normally sys.stdout or sys.stderr) + self.wrapped = wrapped + + # should we reset colors to defaults after every .write() + self.autoreset = autoreset + + # create the proxy wrapping our output stream + self.stream = StreamWrapper(wrapped, self) + + on_windows = os.name == 'nt' + # We test if the WinAPI works, because even if we are on Windows + # we may be using a terminal that doesn't support the WinAPI + # (e.g. Cygwin Terminal). In this case it's up to the terminal + # to support the ANSI codes. + conversion_supported = on_windows and winapi_test() + + # should we strip ANSI sequences from our output? + if strip is None: + strip = conversion_supported or (not self.stream.closed and not self.stream.isatty()) + self.strip = strip + + # should we should convert ANSI sequences into win32 calls? + if convert is None: + convert = conversion_supported and not self.stream.closed and self.stream.isatty() + self.convert = convert + + # dict of ansi codes to win32 functions and parameters + self.win32_calls = self.get_win32_calls() + + # are we wrapping stderr? + self.on_stderr = self.wrapped is sys.stderr + + def should_wrap(self): + ''' + True if this class is actually needed. If false, then the output + stream will not be affected, nor will win32 calls be issued, so + wrapping stdout is not actually required. This will generally be + False on non-Windows platforms, unless optional functionality like + autoreset has been requested using kwargs to init() + ''' + return self.convert or self.strip or self.autoreset + + def get_win32_calls(self): + if self.convert and winterm: + return { + AnsiStyle.RESET_ALL: (winterm.reset_all, ), + AnsiStyle.BRIGHT: (winterm.style, WinStyle.BRIGHT), + AnsiStyle.DIM: (winterm.style, WinStyle.NORMAL), + AnsiStyle.NORMAL: (winterm.style, WinStyle.NORMAL), + AnsiFore.BLACK: (winterm.fore, WinColor.BLACK), + AnsiFore.RED: (winterm.fore, WinColor.RED), + AnsiFore.GREEN: (winterm.fore, WinColor.GREEN), + AnsiFore.YELLOW: (winterm.fore, WinColor.YELLOW), + AnsiFore.BLUE: (winterm.fore, WinColor.BLUE), + AnsiFore.MAGENTA: (winterm.fore, WinColor.MAGENTA), + AnsiFore.CYAN: (winterm.fore, WinColor.CYAN), + AnsiFore.WHITE: (winterm.fore, WinColor.GREY), + AnsiFore.RESET: (winterm.fore, ), + AnsiFore.LIGHTBLACK_EX: (winterm.fore, WinColor.BLACK, True), + AnsiFore.LIGHTRED_EX: (winterm.fore, WinColor.RED, True), + AnsiFore.LIGHTGREEN_EX: (winterm.fore, WinColor.GREEN, True), + AnsiFore.LIGHTYELLOW_EX: (winterm.fore, WinColor.YELLOW, True), + AnsiFore.LIGHTBLUE_EX: (winterm.fore, WinColor.BLUE, True), + AnsiFore.LIGHTMAGENTA_EX: (winterm.fore, WinColor.MAGENTA, True), + AnsiFore.LIGHTCYAN_EX: (winterm.fore, WinColor.CYAN, True), + AnsiFore.LIGHTWHITE_EX: (winterm.fore, WinColor.GREY, True), + AnsiBack.BLACK: (winterm.back, WinColor.BLACK), + AnsiBack.RED: (winterm.back, WinColor.RED), + AnsiBack.GREEN: (winterm.back, WinColor.GREEN), + AnsiBack.YELLOW: (winterm.back, WinColor.YELLOW), + AnsiBack.BLUE: (winterm.back, WinColor.BLUE), + AnsiBack.MAGENTA: (winterm.back, WinColor.MAGENTA), + AnsiBack.CYAN: (winterm.back, WinColor.CYAN), + AnsiBack.WHITE: (winterm.back, WinColor.GREY), + AnsiBack.RESET: (winterm.back, ), + AnsiBack.LIGHTBLACK_EX: (winterm.back, WinColor.BLACK, True), + AnsiBack.LIGHTRED_EX: (winterm.back, WinColor.RED, True), + AnsiBack.LIGHTGREEN_EX: (winterm.back, WinColor.GREEN, True), + AnsiBack.LIGHTYELLOW_EX: (winterm.back, WinColor.YELLOW, True), + AnsiBack.LIGHTBLUE_EX: (winterm.back, WinColor.BLUE, True), + AnsiBack.LIGHTMAGENTA_EX: (winterm.back, WinColor.MAGENTA, True), + AnsiBack.LIGHTCYAN_EX: (winterm.back, WinColor.CYAN, True), + AnsiBack.LIGHTWHITE_EX: (winterm.back, WinColor.GREY, True), + } + return dict() + + def write(self, text): + if self.strip or self.convert: + self.write_and_convert(text) + else: + self.wrapped.write(text) + self.wrapped.flush() + if self.autoreset: + self.reset_all() + + + def reset_all(self): + if self.convert: + self.call_win32('m', (0,)) + elif not self.strip and not self.stream.closed: + self.wrapped.write(Style.RESET_ALL) + + + def write_and_convert(self, text): + ''' + Write the given text to our wrapped stream, stripping any ANSI + sequences from the text, and optionally converting them into win32 + calls. + ''' + cursor = 0 + text = self.convert_osc(text) + for match in self.ANSI_CSI_RE.finditer(text): + start, end = match.span() + self.write_plain_text(text, cursor, start) + self.convert_ansi(*match.groups()) + cursor = end + self.write_plain_text(text, cursor, len(text)) + + + def write_plain_text(self, text, start, end): + if start < end: + self.wrapped.write(text[start:end]) + self.wrapped.flush() + + + def convert_ansi(self, paramstring, command): + if self.convert: + params = self.extract_params(command, paramstring) + self.call_win32(command, params) + + + def extract_params(self, command, paramstring): + if command in 'Hf': + params = tuple(int(p) if len(p) != 0 else 1 for p in paramstring.split(';')) + while len(params) < 2: + # defaults: + params = params + (1,) + else: + params = tuple(int(p) for p in paramstring.split(';') if len(p) != 0) + if len(params) == 0: + # defaults: + if command in 'JKm': + params = (0,) + elif command in 'ABCD': + params = (1,) + + return params + + + def call_win32(self, command, params): + if command == 'm': + for param in params: + if param in self.win32_calls: + func_args = self.win32_calls[param] + func = func_args[0] + args = func_args[1:] + kwargs = dict(on_stderr=self.on_stderr) + func(*args, **kwargs) + elif command in 'J': + winterm.erase_screen(params[0], on_stderr=self.on_stderr) + elif command in 'K': + winterm.erase_line(params[0], on_stderr=self.on_stderr) + elif command in 'Hf': # cursor position - absolute + winterm.set_cursor_position(params, on_stderr=self.on_stderr) + elif command in 'ABCD': # cursor position - relative + n = params[0] + # A - up, B - down, C - forward, D - back + x, y = {'A': (0, -n), 'B': (0, n), 'C': (n, 0), 'D': (-n, 0)}[command] + winterm.cursor_adjust(x, y, on_stderr=self.on_stderr) + + + def convert_osc(self, text): + for match in self.ANSI_OSC_RE.finditer(text): + start, end = match.span() + text = text[:start] + text[end:] + paramstring, command = match.groups() + if command == BEL: + if paramstring.count(";") == 1: + params = paramstring.split(";") + # 0 - change title and icon (we will only change title) + # 1 - change icon (we don't support this) + # 2 - change title + if params[0] in '02': + winterm.set_title(params[1]) + return text diff --git a/venv/Lib/site-packages/pip/_vendor/colorama/initialise.py b/venv/Lib/site-packages/pip/_vendor/colorama/initialise.py new file mode 100644 index 0000000..430d066 --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/colorama/initialise.py @@ -0,0 +1,80 @@ +# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. +import atexit +import contextlib +import sys + +from .ansitowin32 import AnsiToWin32 + + +orig_stdout = None +orig_stderr = None + +wrapped_stdout = None +wrapped_stderr = None + +atexit_done = False + + +def reset_all(): + if AnsiToWin32 is not None: # Issue #74: objects might become None at exit + AnsiToWin32(orig_stdout).reset_all() + + +def init(autoreset=False, convert=None, strip=None, wrap=True): + + if not wrap and any([autoreset, convert, strip]): + raise ValueError('wrap=False conflicts with any other arg=True') + + global wrapped_stdout, wrapped_stderr + global orig_stdout, orig_stderr + + orig_stdout = sys.stdout + orig_stderr = sys.stderr + + if sys.stdout is None: + wrapped_stdout = None + else: + sys.stdout = wrapped_stdout = \ + wrap_stream(orig_stdout, convert, strip, autoreset, wrap) + if sys.stderr is None: + wrapped_stderr = None + else: + sys.stderr = wrapped_stderr = \ + wrap_stream(orig_stderr, convert, strip, autoreset, wrap) + + global atexit_done + if not atexit_done: + atexit.register(reset_all) + atexit_done = True + + +def deinit(): + if orig_stdout is not None: + sys.stdout = orig_stdout + if orig_stderr is not None: + sys.stderr = orig_stderr + + +@contextlib.contextmanager +def colorama_text(*args, **kwargs): + init(*args, **kwargs) + try: + yield + finally: + deinit() + + +def reinit(): + if wrapped_stdout is not None: + sys.stdout = wrapped_stdout + if wrapped_stderr is not None: + sys.stderr = wrapped_stderr + + +def wrap_stream(stream, convert, strip, autoreset, wrap): + if wrap: + wrapper = AnsiToWin32(stream, + convert=convert, strip=strip, autoreset=autoreset) + if wrapper.should_wrap(): + stream = wrapper.stream + return stream diff --git a/venv/Lib/site-packages/pip/_vendor/colorama/win32.py b/venv/Lib/site-packages/pip/_vendor/colorama/win32.py new file mode 100644 index 0000000..c2d8360 --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/colorama/win32.py @@ -0,0 +1,152 @@ +# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. + +# from winbase.h +STDOUT = -11 +STDERR = -12 + +try: + import ctypes + from ctypes import LibraryLoader + windll = LibraryLoader(ctypes.WinDLL) + from ctypes import wintypes +except (AttributeError, ImportError): + windll = None + SetConsoleTextAttribute = lambda *_: None + winapi_test = lambda *_: None +else: + from ctypes import byref, Structure, c_char, POINTER + + COORD = wintypes._COORD + + class CONSOLE_SCREEN_BUFFER_INFO(Structure): + """struct in wincon.h.""" + _fields_ = [ + ("dwSize", COORD), + ("dwCursorPosition", COORD), + ("wAttributes", wintypes.WORD), + ("srWindow", wintypes.SMALL_RECT), + ("dwMaximumWindowSize", COORD), + ] + def __str__(self): + return '(%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d)' % ( + self.dwSize.Y, self.dwSize.X + , self.dwCursorPosition.Y, self.dwCursorPosition.X + , self.wAttributes + , self.srWindow.Top, self.srWindow.Left, self.srWindow.Bottom, self.srWindow.Right + , self.dwMaximumWindowSize.Y, self.dwMaximumWindowSize.X + ) + + _GetStdHandle = windll.kernel32.GetStdHandle + _GetStdHandle.argtypes = [ + wintypes.DWORD, + ] + _GetStdHandle.restype = wintypes.HANDLE + + _GetConsoleScreenBufferInfo = windll.kernel32.GetConsoleScreenBufferInfo + _GetConsoleScreenBufferInfo.argtypes = [ + wintypes.HANDLE, + POINTER(CONSOLE_SCREEN_BUFFER_INFO), + ] + _GetConsoleScreenBufferInfo.restype = wintypes.BOOL + + _SetConsoleTextAttribute = windll.kernel32.SetConsoleTextAttribute + _SetConsoleTextAttribute.argtypes = [ + wintypes.HANDLE, + wintypes.WORD, + ] + _SetConsoleTextAttribute.restype = wintypes.BOOL + + _SetConsoleCursorPosition = windll.kernel32.SetConsoleCursorPosition + _SetConsoleCursorPosition.argtypes = [ + wintypes.HANDLE, + COORD, + ] + _SetConsoleCursorPosition.restype = wintypes.BOOL + + _FillConsoleOutputCharacterA = windll.kernel32.FillConsoleOutputCharacterA + _FillConsoleOutputCharacterA.argtypes = [ + wintypes.HANDLE, + c_char, + wintypes.DWORD, + COORD, + POINTER(wintypes.DWORD), + ] + _FillConsoleOutputCharacterA.restype = wintypes.BOOL + + _FillConsoleOutputAttribute = windll.kernel32.FillConsoleOutputAttribute + _FillConsoleOutputAttribute.argtypes = [ + wintypes.HANDLE, + wintypes.WORD, + wintypes.DWORD, + COORD, + POINTER(wintypes.DWORD), + ] + _FillConsoleOutputAttribute.restype = wintypes.BOOL + + _SetConsoleTitleW = windll.kernel32.SetConsoleTitleW + _SetConsoleTitleW.argtypes = [ + wintypes.LPCWSTR + ] + _SetConsoleTitleW.restype = wintypes.BOOL + + def _winapi_test(handle): + csbi = CONSOLE_SCREEN_BUFFER_INFO() + success = _GetConsoleScreenBufferInfo( + handle, byref(csbi)) + return bool(success) + + def winapi_test(): + return any(_winapi_test(h) for h in + (_GetStdHandle(STDOUT), _GetStdHandle(STDERR))) + + def GetConsoleScreenBufferInfo(stream_id=STDOUT): + handle = _GetStdHandle(stream_id) + csbi = CONSOLE_SCREEN_BUFFER_INFO() + success = _GetConsoleScreenBufferInfo( + handle, byref(csbi)) + return csbi + + def SetConsoleTextAttribute(stream_id, attrs): + handle = _GetStdHandle(stream_id) + return _SetConsoleTextAttribute(handle, attrs) + + def SetConsoleCursorPosition(stream_id, position, adjust=True): + position = COORD(*position) + # If the position is out of range, do nothing. + if position.Y <= 0 or position.X <= 0: + return + # Adjust for Windows' SetConsoleCursorPosition: + # 1. being 0-based, while ANSI is 1-based. + # 2. expecting (x,y), while ANSI uses (y,x). + adjusted_position = COORD(position.Y - 1, position.X - 1) + if adjust: + # Adjust for viewport's scroll position + sr = GetConsoleScreenBufferInfo(STDOUT).srWindow + adjusted_position.Y += sr.Top + adjusted_position.X += sr.Left + # Resume normal processing + handle = _GetStdHandle(stream_id) + return _SetConsoleCursorPosition(handle, adjusted_position) + + def FillConsoleOutputCharacter(stream_id, char, length, start): + handle = _GetStdHandle(stream_id) + char = c_char(char.encode()) + length = wintypes.DWORD(length) + num_written = wintypes.DWORD(0) + # Note that this is hard-coded for ANSI (vs wide) bytes. + success = _FillConsoleOutputCharacterA( + handle, char, length, start, byref(num_written)) + return num_written.value + + def FillConsoleOutputAttribute(stream_id, attr, length, start): + ''' FillConsoleOutputAttribute( hConsole, csbi.wAttributes, dwConSize, coordScreen, &cCharsWritten )''' + handle = _GetStdHandle(stream_id) + attribute = wintypes.WORD(attr) + length = wintypes.DWORD(length) + num_written = wintypes.DWORD(0) + # Note that this is hard-coded for ANSI (vs wide) bytes. + return _FillConsoleOutputAttribute( + handle, attribute, length, start, byref(num_written)) + + def SetConsoleTitle(title): + return _SetConsoleTitleW(title) diff --git a/venv/Lib/site-packages/pip/_vendor/colorama/winterm.py b/venv/Lib/site-packages/pip/_vendor/colorama/winterm.py new file mode 100644 index 0000000..0fdb4ec --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/colorama/winterm.py @@ -0,0 +1,169 @@ +# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. +from . import win32 + + +# from wincon.h +class WinColor(object): + BLACK = 0 + BLUE = 1 + GREEN = 2 + CYAN = 3 + RED = 4 + MAGENTA = 5 + YELLOW = 6 + GREY = 7 + +# from wincon.h +class WinStyle(object): + NORMAL = 0x00 # dim text, dim background + BRIGHT = 0x08 # bright text, dim background + BRIGHT_BACKGROUND = 0x80 # dim text, bright background + +class WinTerm(object): + + def __init__(self): + self._default = win32.GetConsoleScreenBufferInfo(win32.STDOUT).wAttributes + self.set_attrs(self._default) + self._default_fore = self._fore + self._default_back = self._back + self._default_style = self._style + # In order to emulate LIGHT_EX in windows, we borrow the BRIGHT style. + # So that LIGHT_EX colors and BRIGHT style do not clobber each other, + # we track them separately, since LIGHT_EX is overwritten by Fore/Back + # and BRIGHT is overwritten by Style codes. + self._light = 0 + + def get_attrs(self): + return self._fore + self._back * 16 + (self._style | self._light) + + def set_attrs(self, value): + self._fore = value & 7 + self._back = (value >> 4) & 7 + self._style = value & (WinStyle.BRIGHT | WinStyle.BRIGHT_BACKGROUND) + + def reset_all(self, on_stderr=None): + self.set_attrs(self._default) + self.set_console(attrs=self._default) + self._light = 0 + + def fore(self, fore=None, light=False, on_stderr=False): + if fore is None: + fore = self._default_fore + self._fore = fore + # Emulate LIGHT_EX with BRIGHT Style + if light: + self._light |= WinStyle.BRIGHT + else: + self._light &= ~WinStyle.BRIGHT + self.set_console(on_stderr=on_stderr) + + def back(self, back=None, light=False, on_stderr=False): + if back is None: + back = self._default_back + self._back = back + # Emulate LIGHT_EX with BRIGHT_BACKGROUND Style + if light: + self._light |= WinStyle.BRIGHT_BACKGROUND + else: + self._light &= ~WinStyle.BRIGHT_BACKGROUND + self.set_console(on_stderr=on_stderr) + + def style(self, style=None, on_stderr=False): + if style is None: + style = self._default_style + self._style = style + self.set_console(on_stderr=on_stderr) + + def set_console(self, attrs=None, on_stderr=False): + if attrs is None: + attrs = self.get_attrs() + handle = win32.STDOUT + if on_stderr: + handle = win32.STDERR + win32.SetConsoleTextAttribute(handle, attrs) + + def get_position(self, handle): + position = win32.GetConsoleScreenBufferInfo(handle).dwCursorPosition + # Because Windows coordinates are 0-based, + # and win32.SetConsoleCursorPosition expects 1-based. + position.X += 1 + position.Y += 1 + return position + + def set_cursor_position(self, position=None, on_stderr=False): + if position is None: + # I'm not currently tracking the position, so there is no default. + # position = self.get_position() + return + handle = win32.STDOUT + if on_stderr: + handle = win32.STDERR + win32.SetConsoleCursorPosition(handle, position) + + def cursor_adjust(self, x, y, on_stderr=False): + handle = win32.STDOUT + if on_stderr: + handle = win32.STDERR + position = self.get_position(handle) + adjusted_position = (position.Y + y, position.X + x) + win32.SetConsoleCursorPosition(handle, adjusted_position, adjust=False) + + def erase_screen(self, mode=0, on_stderr=False): + # 0 should clear from the cursor to the end of the screen. + # 1 should clear from the cursor to the beginning of the screen. + # 2 should clear the entire screen, and move cursor to (1,1) + handle = win32.STDOUT + if on_stderr: + handle = win32.STDERR + csbi = win32.GetConsoleScreenBufferInfo(handle) + # get the number of character cells in the current buffer + cells_in_screen = csbi.dwSize.X * csbi.dwSize.Y + # get number of character cells before current cursor position + cells_before_cursor = csbi.dwSize.X * csbi.dwCursorPosition.Y + csbi.dwCursorPosition.X + if mode == 0: + from_coord = csbi.dwCursorPosition + cells_to_erase = cells_in_screen - cells_before_cursor + elif mode == 1: + from_coord = win32.COORD(0, 0) + cells_to_erase = cells_before_cursor + elif mode == 2: + from_coord = win32.COORD(0, 0) + cells_to_erase = cells_in_screen + else: + # invalid mode + return + # fill the entire screen with blanks + win32.FillConsoleOutputCharacter(handle, ' ', cells_to_erase, from_coord) + # now set the buffer's attributes accordingly + win32.FillConsoleOutputAttribute(handle, self.get_attrs(), cells_to_erase, from_coord) + if mode == 2: + # put the cursor where needed + win32.SetConsoleCursorPosition(handle, (1, 1)) + + def erase_line(self, mode=0, on_stderr=False): + # 0 should clear from the cursor to the end of the line. + # 1 should clear from the cursor to the beginning of the line. + # 2 should clear the entire line. + handle = win32.STDOUT + if on_stderr: + handle = win32.STDERR + csbi = win32.GetConsoleScreenBufferInfo(handle) + if mode == 0: + from_coord = csbi.dwCursorPosition + cells_to_erase = csbi.dwSize.X - csbi.dwCursorPosition.X + elif mode == 1: + from_coord = win32.COORD(0, csbi.dwCursorPosition.Y) + cells_to_erase = csbi.dwCursorPosition.X + elif mode == 2: + from_coord = win32.COORD(0, csbi.dwCursorPosition.Y) + cells_to_erase = csbi.dwSize.X + else: + # invalid mode + return + # fill the entire screen with blanks + win32.FillConsoleOutputCharacter(handle, ' ', cells_to_erase, from_coord) + # now set the buffer's attributes accordingly + win32.FillConsoleOutputAttribute(handle, self.get_attrs(), cells_to_erase, from_coord) + + def set_title(self, title): + win32.SetConsoleTitle(title) diff --git a/venv/Lib/site-packages/pip/_vendor/contextlib2.py b/venv/Lib/site-packages/pip/_vendor/contextlib2.py new file mode 100644 index 0000000..3aae8f4 --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/contextlib2.py @@ -0,0 +1,518 @@ +"""contextlib2 - backports and enhancements to the contextlib module""" + +import abc +import sys +import warnings +from collections import deque +from functools import wraps + +__all__ = ["contextmanager", "closing", "nullcontext", + "AbstractContextManager", + "ContextDecorator", "ExitStack", + "redirect_stdout", "redirect_stderr", "suppress"] + +# Backwards compatibility +__all__ += ["ContextStack"] + + +# Backport abc.ABC +if sys.version_info[:2] >= (3, 4): + _abc_ABC = abc.ABC +else: + _abc_ABC = abc.ABCMeta('ABC', (object,), {'__slots__': ()}) + + +# Backport classic class MRO +def _classic_mro(C, result): + if C in result: + return + result.append(C) + for B in C.__bases__: + _classic_mro(B, result) + return result + + +# Backport _collections_abc._check_methods +def _check_methods(C, *methods): + try: + mro = C.__mro__ + except AttributeError: + mro = tuple(_classic_mro(C, [])) + + for method in methods: + for B in mro: + if method in B.__dict__: + if B.__dict__[method] is None: + return NotImplemented + break + else: + return NotImplemented + return True + + +class AbstractContextManager(_abc_ABC): + """An abstract base class for context managers.""" + + def __enter__(self): + """Return `self` upon entering the runtime context.""" + return self + + @abc.abstractmethod + def __exit__(self, exc_type, exc_value, traceback): + """Raise any exception triggered within the runtime context.""" + return None + + @classmethod + def __subclasshook__(cls, C): + """Check whether subclass is considered a subclass of this ABC.""" + if cls is AbstractContextManager: + return _check_methods(C, "__enter__", "__exit__") + return NotImplemented + + +class ContextDecorator(object): + """A base class or mixin that enables context managers to work as decorators.""" + + def refresh_cm(self): + """Returns the context manager used to actually wrap the call to the + decorated function. + + The default implementation just returns *self*. + + Overriding this method allows otherwise one-shot context managers + like _GeneratorContextManager to support use as decorators via + implicit recreation. + + DEPRECATED: refresh_cm was never added to the standard library's + ContextDecorator API + """ + warnings.warn("refresh_cm was never added to the standard library", + DeprecationWarning) + return self._recreate_cm() + + def _recreate_cm(self): + """Return a recreated instance of self. + + Allows an otherwise one-shot context manager like + _GeneratorContextManager to support use as + a decorator via implicit recreation. + + This is a private interface just for _GeneratorContextManager. + See issue #11647 for details. + """ + return self + + def __call__(self, func): + @wraps(func) + def inner(*args, **kwds): + with self._recreate_cm(): + return func(*args, **kwds) + return inner + + +class _GeneratorContextManager(ContextDecorator): + """Helper for @contextmanager decorator.""" + + def __init__(self, func, args, kwds): + self.gen = func(*args, **kwds) + self.func, self.args, self.kwds = func, args, kwds + # Issue 19330: ensure context manager instances have good docstrings + doc = getattr(func, "__doc__", None) + if doc is None: + doc = type(self).__doc__ + self.__doc__ = doc + # Unfortunately, this still doesn't provide good help output when + # inspecting the created context manager instances, since pydoc + # currently bypasses the instance docstring and shows the docstring + # for the class instead. + # See http://bugs.python.org/issue19404 for more details. + + def _recreate_cm(self): + # _GCM instances are one-shot context managers, so the + # CM must be recreated each time a decorated function is + # called + return self.__class__(self.func, self.args, self.kwds) + + def __enter__(self): + try: + return next(self.gen) + except StopIteration: + raise RuntimeError("generator didn't yield") + + def __exit__(self, type, value, traceback): + if type is None: + try: + next(self.gen) + except StopIteration: + return + else: + raise RuntimeError("generator didn't stop") + else: + if value is None: + # Need to force instantiation so we can reliably + # tell if we get the same exception back + value = type() + try: + self.gen.throw(type, value, traceback) + raise RuntimeError("generator didn't stop after throw()") + except StopIteration as exc: + # Suppress StopIteration *unless* it's the same exception that + # was passed to throw(). This prevents a StopIteration + # raised inside the "with" statement from being suppressed. + return exc is not value + except RuntimeError as exc: + # Don't re-raise the passed in exception + if exc is value: + return False + # Likewise, avoid suppressing if a StopIteration exception + # was passed to throw() and later wrapped into a RuntimeError + # (see PEP 479). + if _HAVE_EXCEPTION_CHAINING and exc.__cause__ is value: + return False + raise + except: + # only re-raise if it's *not* the exception that was + # passed to throw(), because __exit__() must not raise + # an exception unless __exit__() itself failed. But throw() + # has to raise the exception to signal propagation, so this + # fixes the impedance mismatch between the throw() protocol + # and the __exit__() protocol. + # + if sys.exc_info()[1] is not value: + raise + + +def contextmanager(func): + """@contextmanager decorator. + + Typical usage: + + @contextmanager + def some_generator(): + + try: + yield + finally: + + + This makes this: + + with some_generator() as : + + + equivalent to this: + + + try: + = + + finally: + + + """ + @wraps(func) + def helper(*args, **kwds): + return _GeneratorContextManager(func, args, kwds) + return helper + + +class closing(object): + """Context to automatically close something at the end of a block. + + Code like this: + + with closing(.open()) as f: + + + is equivalent to this: + + f = .open() + try: + + finally: + f.close() + + """ + def __init__(self, thing): + self.thing = thing + + def __enter__(self): + return self.thing + + def __exit__(self, *exc_info): + self.thing.close() + + +class _RedirectStream(object): + + _stream = None + + def __init__(self, new_target): + self._new_target = new_target + # We use a list of old targets to make this CM re-entrant + self._old_targets = [] + + def __enter__(self): + self._old_targets.append(getattr(sys, self._stream)) + setattr(sys, self._stream, self._new_target) + return self._new_target + + def __exit__(self, exctype, excinst, exctb): + setattr(sys, self._stream, self._old_targets.pop()) + + +class redirect_stdout(_RedirectStream): + """Context manager for temporarily redirecting stdout to another file. + + # How to send help() to stderr + with redirect_stdout(sys.stderr): + help(dir) + + # How to write help() to a file + with open('help.txt', 'w') as f: + with redirect_stdout(f): + help(pow) + """ + + _stream = "stdout" + + +class redirect_stderr(_RedirectStream): + """Context manager for temporarily redirecting stderr to another file.""" + + _stream = "stderr" + + +class suppress(object): + """Context manager to suppress specified exceptions + + After the exception is suppressed, execution proceeds with the next + statement following the with statement. + + with suppress(FileNotFoundError): + os.remove(somefile) + # Execution still resumes here if the file was already removed + """ + + def __init__(self, *exceptions): + self._exceptions = exceptions + + def __enter__(self): + pass + + def __exit__(self, exctype, excinst, exctb): + # Unlike isinstance and issubclass, CPython exception handling + # currently only looks at the concrete type hierarchy (ignoring + # the instance and subclass checking hooks). While Guido considers + # that a bug rather than a feature, it's a fairly hard one to fix + # due to various internal implementation details. suppress provides + # the simpler issubclass based semantics, rather than trying to + # exactly reproduce the limitations of the CPython interpreter. + # + # See http://bugs.python.org/issue12029 for more details + return exctype is not None and issubclass(exctype, self._exceptions) + + +# Context manipulation is Python 3 only +_HAVE_EXCEPTION_CHAINING = sys.version_info[0] >= 3 +if _HAVE_EXCEPTION_CHAINING: + def _make_context_fixer(frame_exc): + def _fix_exception_context(new_exc, old_exc): + # Context may not be correct, so find the end of the chain + while 1: + exc_context = new_exc.__context__ + if exc_context is old_exc: + # Context is already set correctly (see issue 20317) + return + if exc_context is None or exc_context is frame_exc: + break + new_exc = exc_context + # Change the end of the chain to point to the exception + # we expect it to reference + new_exc.__context__ = old_exc + return _fix_exception_context + + def _reraise_with_existing_context(exc_details): + try: + # bare "raise exc_details[1]" replaces our carefully + # set-up context + fixed_ctx = exc_details[1].__context__ + raise exc_details[1] + except BaseException: + exc_details[1].__context__ = fixed_ctx + raise +else: + # No exception context in Python 2 + def _make_context_fixer(frame_exc): + return lambda new_exc, old_exc: None + + # Use 3 argument raise in Python 2, + # but use exec to avoid SyntaxError in Python 3 + def _reraise_with_existing_context(exc_details): + exc_type, exc_value, exc_tb = exc_details + exec("raise exc_type, exc_value, exc_tb") + +# Handle old-style classes if they exist +try: + from types import InstanceType +except ImportError: + # Python 3 doesn't have old-style classes + _get_type = type +else: + # Need to handle old-style context managers on Python 2 + def _get_type(obj): + obj_type = type(obj) + if obj_type is InstanceType: + return obj.__class__ # Old-style class + return obj_type # New-style class + + +# Inspired by discussions on http://bugs.python.org/issue13585 +class ExitStack(object): + """Context manager for dynamic management of a stack of exit callbacks + + For example: + + with ExitStack() as stack: + files = [stack.enter_context(open(fname)) for fname in filenames] + # All opened files will automatically be closed at the end of + # the with statement, even if attempts to open files later + # in the list raise an exception + + """ + def __init__(self): + self._exit_callbacks = deque() + + def pop_all(self): + """Preserve the context stack by transferring it to a new instance""" + new_stack = type(self)() + new_stack._exit_callbacks = self._exit_callbacks + self._exit_callbacks = deque() + return new_stack + + def _push_cm_exit(self, cm, cm_exit): + """Helper to correctly register callbacks to __exit__ methods""" + def _exit_wrapper(*exc_details): + return cm_exit(cm, *exc_details) + _exit_wrapper.__self__ = cm + self.push(_exit_wrapper) + + def push(self, exit): + """Registers a callback with the standard __exit__ method signature + + Can suppress exceptions the same way __exit__ methods can. + + Also accepts any object with an __exit__ method (registering a call + to the method instead of the object itself) + """ + # We use an unbound method rather than a bound method to follow + # the standard lookup behaviour for special methods + _cb_type = _get_type(exit) + try: + exit_method = _cb_type.__exit__ + except AttributeError: + # Not a context manager, so assume its a callable + self._exit_callbacks.append(exit) + else: + self._push_cm_exit(exit, exit_method) + return exit # Allow use as a decorator + + def callback(self, callback, *args, **kwds): + """Registers an arbitrary callback and arguments. + + Cannot suppress exceptions. + """ + def _exit_wrapper(exc_type, exc, tb): + callback(*args, **kwds) + # We changed the signature, so using @wraps is not appropriate, but + # setting __wrapped__ may still help with introspection + _exit_wrapper.__wrapped__ = callback + self.push(_exit_wrapper) + return callback # Allow use as a decorator + + def enter_context(self, cm): + """Enters the supplied context manager + + If successful, also pushes its __exit__ method as a callback and + returns the result of the __enter__ method. + """ + # We look up the special methods on the type to match the with statement + _cm_type = _get_type(cm) + _exit = _cm_type.__exit__ + result = _cm_type.__enter__(cm) + self._push_cm_exit(cm, _exit) + return result + + def close(self): + """Immediately unwind the context stack""" + self.__exit__(None, None, None) + + def __enter__(self): + return self + + def __exit__(self, *exc_details): + received_exc = exc_details[0] is not None + + # We manipulate the exception state so it behaves as though + # we were actually nesting multiple with statements + frame_exc = sys.exc_info()[1] + _fix_exception_context = _make_context_fixer(frame_exc) + + # Callbacks are invoked in LIFO order to match the behaviour of + # nested context managers + suppressed_exc = False + pending_raise = False + while self._exit_callbacks: + cb = self._exit_callbacks.pop() + try: + if cb(*exc_details): + suppressed_exc = True + pending_raise = False + exc_details = (None, None, None) + except: + new_exc_details = sys.exc_info() + # simulate the stack of exceptions by setting the context + _fix_exception_context(new_exc_details[1], exc_details[1]) + pending_raise = True + exc_details = new_exc_details + if pending_raise: + _reraise_with_existing_context(exc_details) + return received_exc and suppressed_exc + + +# Preserve backwards compatibility +class ContextStack(ExitStack): + """Backwards compatibility alias for ExitStack""" + + def __init__(self): + warnings.warn("ContextStack has been renamed to ExitStack", + DeprecationWarning) + super(ContextStack, self).__init__() + + def register_exit(self, callback): + return self.push(callback) + + def register(self, callback, *args, **kwds): + return self.callback(callback, *args, **kwds) + + def preserve(self): + return self.pop_all() + + +class nullcontext(AbstractContextManager): + """Context manager that does no additional processing. + Used as a stand-in for a normal context manager, when a particular + block of code is only sometimes used with a normal context manager: + cm = optional_cm if condition else nullcontext() + with cm: + # Perform operation, using optional_cm if condition is True + """ + + def __init__(self, enter_result=None): + self.enter_result = enter_result + + def __enter__(self): + return self.enter_result + + def __exit__(self, *excinfo): + pass diff --git a/venv/Lib/site-packages/pip/_vendor/distlib/__init__.py b/venv/Lib/site-packages/pip/_vendor/distlib/__init__.py new file mode 100644 index 0000000..63d916e --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/distlib/__init__.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2012-2019 Vinay Sajip. +# Licensed to the Python Software Foundation under a contributor agreement. +# See LICENSE.txt and CONTRIBUTORS.txt. +# +import logging + +__version__ = '0.3.1' + +class DistlibException(Exception): + pass + +try: + from logging import NullHandler +except ImportError: # pragma: no cover + class NullHandler(logging.Handler): + def handle(self, record): pass + def emit(self, record): pass + def createLock(self): self.lock = None + +logger = logging.getLogger(__name__) +logger.addHandler(NullHandler()) diff --git a/venv/Lib/site-packages/pip/_vendor/distlib/_backport/__init__.py b/venv/Lib/site-packages/pip/_vendor/distlib/_backport/__init__.py new file mode 100644 index 0000000..f7dbf4c --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/distlib/_backport/__init__.py @@ -0,0 +1,6 @@ +"""Modules copied from Python 3 standard libraries, for internal use only. + +Individual classes and functions are found in d2._backport.misc. Intended +usage is to always import things missing from 3.1 from that module: the +built-in/stdlib objects will be used if found. +""" diff --git a/venv/Lib/site-packages/pip/_vendor/distlib/_backport/misc.py b/venv/Lib/site-packages/pip/_vendor/distlib/_backport/misc.py new file mode 100644 index 0000000..cfb318d --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/distlib/_backport/misc.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2012 The Python Software Foundation. +# See LICENSE.txt and CONTRIBUTORS.txt. +# +"""Backports for individual classes and functions.""" + +import os +import sys + +__all__ = ['cache_from_source', 'callable', 'fsencode'] + + +try: + from imp import cache_from_source +except ImportError: + def cache_from_source(py_file, debug=__debug__): + ext = debug and 'c' or 'o' + return py_file + ext + + +try: + callable = callable +except NameError: + from collections import Callable + + def callable(obj): + return isinstance(obj, Callable) + + +try: + fsencode = os.fsencode +except AttributeError: + def fsencode(filename): + if isinstance(filename, bytes): + return filename + elif isinstance(filename, str): + return filename.encode(sys.getfilesystemencoding()) + else: + raise TypeError("expect bytes or str, not %s" % + type(filename).__name__) diff --git a/venv/Lib/site-packages/pip/_vendor/distlib/_backport/shutil.py b/venv/Lib/site-packages/pip/_vendor/distlib/_backport/shutil.py new file mode 100644 index 0000000..10ed362 --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/distlib/_backport/shutil.py @@ -0,0 +1,764 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2012 The Python Software Foundation. +# See LICENSE.txt and CONTRIBUTORS.txt. +# +"""Utility functions for copying and archiving files and directory trees. + +XXX The functions here don't copy the resource fork or other metadata on Mac. + +""" + +import os +import sys +import stat +from os.path import abspath +import fnmatch +try: + from collections.abc import Callable +except ImportError: + from collections import Callable +import errno +from . import tarfile + +try: + import bz2 + _BZ2_SUPPORTED = True +except ImportError: + _BZ2_SUPPORTED = False + +try: + from pwd import getpwnam +except ImportError: + getpwnam = None + +try: + from grp import getgrnam +except ImportError: + getgrnam = None + +__all__ = ["copyfileobj", "copyfile", "copymode", "copystat", "copy", "copy2", + "copytree", "move", "rmtree", "Error", "SpecialFileError", + "ExecError", "make_archive", "get_archive_formats", + "register_archive_format", "unregister_archive_format", + "get_unpack_formats", "register_unpack_format", + "unregister_unpack_format", "unpack_archive", "ignore_patterns"] + +class Error(EnvironmentError): + pass + +class SpecialFileError(EnvironmentError): + """Raised when trying to do a kind of operation (e.g. copying) which is + not supported on a special file (e.g. a named pipe)""" + +class ExecError(EnvironmentError): + """Raised when a command could not be executed""" + +class ReadError(EnvironmentError): + """Raised when an archive cannot be read""" + +class RegistryError(Exception): + """Raised when a registry operation with the archiving + and unpacking registries fails""" + + +try: + WindowsError +except NameError: + WindowsError = None + +def copyfileobj(fsrc, fdst, length=16*1024): + """copy data from file-like object fsrc to file-like object fdst""" + while 1: + buf = fsrc.read(length) + if not buf: + break + fdst.write(buf) + +def _samefile(src, dst): + # Macintosh, Unix. + if hasattr(os.path, 'samefile'): + try: + return os.path.samefile(src, dst) + except OSError: + return False + + # All other platforms: check for same pathname. + return (os.path.normcase(os.path.abspath(src)) == + os.path.normcase(os.path.abspath(dst))) + +def copyfile(src, dst): + """Copy data from src to dst""" + if _samefile(src, dst): + raise Error("`%s` and `%s` are the same file" % (src, dst)) + + for fn in [src, dst]: + try: + st = os.stat(fn) + except OSError: + # File most likely does not exist + pass + else: + # XXX What about other special files? (sockets, devices...) + if stat.S_ISFIFO(st.st_mode): + raise SpecialFileError("`%s` is a named pipe" % fn) + + with open(src, 'rb') as fsrc: + with open(dst, 'wb') as fdst: + copyfileobj(fsrc, fdst) + +def copymode(src, dst): + """Copy mode bits from src to dst""" + if hasattr(os, 'chmod'): + st = os.stat(src) + mode = stat.S_IMODE(st.st_mode) + os.chmod(dst, mode) + +def copystat(src, dst): + """Copy all stat info (mode bits, atime, mtime, flags) from src to dst""" + st = os.stat(src) + mode = stat.S_IMODE(st.st_mode) + if hasattr(os, 'utime'): + os.utime(dst, (st.st_atime, st.st_mtime)) + if hasattr(os, 'chmod'): + os.chmod(dst, mode) + if hasattr(os, 'chflags') and hasattr(st, 'st_flags'): + try: + os.chflags(dst, st.st_flags) + except OSError as why: + if (not hasattr(errno, 'EOPNOTSUPP') or + why.errno != errno.EOPNOTSUPP): + raise + +def copy(src, dst): + """Copy data and mode bits ("cp src dst"). + + The destination may be a directory. + + """ + if os.path.isdir(dst): + dst = os.path.join(dst, os.path.basename(src)) + copyfile(src, dst) + copymode(src, dst) + +def copy2(src, dst): + """Copy data and all stat info ("cp -p src dst"). + + The destination may be a directory. + + """ + if os.path.isdir(dst): + dst = os.path.join(dst, os.path.basename(src)) + copyfile(src, dst) + copystat(src, dst) + +def ignore_patterns(*patterns): + """Function that can be used as copytree() ignore parameter. + + Patterns is a sequence of glob-style patterns + that are used to exclude files""" + def _ignore_patterns(path, names): + ignored_names = [] + for pattern in patterns: + ignored_names.extend(fnmatch.filter(names, pattern)) + return set(ignored_names) + return _ignore_patterns + +def copytree(src, dst, symlinks=False, ignore=None, copy_function=copy2, + ignore_dangling_symlinks=False): + """Recursively copy a directory tree. + + The destination directory must not already exist. + If exception(s) occur, an Error is raised with a list of reasons. + + If the optional symlinks flag is true, symbolic links in the + source tree result in symbolic links in the destination tree; if + it is false, the contents of the files pointed to by symbolic + links are copied. If the file pointed by the symlink doesn't + exist, an exception will be added in the list of errors raised in + an Error exception at the end of the copy process. + + You can set the optional ignore_dangling_symlinks flag to true if you + want to silence this exception. Notice that this has no effect on + platforms that don't support os.symlink. + + The optional ignore argument is a callable. If given, it + is called with the `src` parameter, which is the directory + being visited by copytree(), and `names` which is the list of + `src` contents, as returned by os.listdir(): + + callable(src, names) -> ignored_names + + Since copytree() is called recursively, the callable will be + called once for each directory that is copied. It returns a + list of names relative to the `src` directory that should + not be copied. + + The optional copy_function argument is a callable that will be used + to copy each file. It will be called with the source path and the + destination path as arguments. By default, copy2() is used, but any + function that supports the same signature (like copy()) can be used. + + """ + names = os.listdir(src) + if ignore is not None: + ignored_names = ignore(src, names) + else: + ignored_names = set() + + os.makedirs(dst) + errors = [] + for name in names: + if name in ignored_names: + continue + srcname = os.path.join(src, name) + dstname = os.path.join(dst, name) + try: + if os.path.islink(srcname): + linkto = os.readlink(srcname) + if symlinks: + os.symlink(linkto, dstname) + else: + # ignore dangling symlink if the flag is on + if not os.path.exists(linkto) and ignore_dangling_symlinks: + continue + # otherwise let the copy occurs. copy2 will raise an error + copy_function(srcname, dstname) + elif os.path.isdir(srcname): + copytree(srcname, dstname, symlinks, ignore, copy_function) + else: + # Will raise a SpecialFileError for unsupported file types + copy_function(srcname, dstname) + # catch the Error from the recursive copytree so that we can + # continue with other files + except Error as err: + errors.extend(err.args[0]) + except EnvironmentError as why: + errors.append((srcname, dstname, str(why))) + try: + copystat(src, dst) + except OSError as why: + if WindowsError is not None and isinstance(why, WindowsError): + # Copying file access times may fail on Windows + pass + else: + errors.extend((src, dst, str(why))) + if errors: + raise Error(errors) + +def rmtree(path, ignore_errors=False, onerror=None): + """Recursively delete a directory tree. + + If ignore_errors is set, errors are ignored; otherwise, if onerror + is set, it is called to handle the error with arguments (func, + path, exc_info) where func is os.listdir, os.remove, or os.rmdir; + path is the argument to that function that caused it to fail; and + exc_info is a tuple returned by sys.exc_info(). If ignore_errors + is false and onerror is None, an exception is raised. + + """ + if ignore_errors: + def onerror(*args): + pass + elif onerror is None: + def onerror(*args): + raise + try: + if os.path.islink(path): + # symlinks to directories are forbidden, see bug #1669 + raise OSError("Cannot call rmtree on a symbolic link") + except OSError: + onerror(os.path.islink, path, sys.exc_info()) + # can't continue even if onerror hook returns + return + names = [] + try: + names = os.listdir(path) + except os.error: + onerror(os.listdir, path, sys.exc_info()) + for name in names: + fullname = os.path.join(path, name) + try: + mode = os.lstat(fullname).st_mode + except os.error: + mode = 0 + if stat.S_ISDIR(mode): + rmtree(fullname, ignore_errors, onerror) + else: + try: + os.remove(fullname) + except os.error: + onerror(os.remove, fullname, sys.exc_info()) + try: + os.rmdir(path) + except os.error: + onerror(os.rmdir, path, sys.exc_info()) + + +def _basename(path): + # A basename() variant which first strips the trailing slash, if present. + # Thus we always get the last component of the path, even for directories. + return os.path.basename(path.rstrip(os.path.sep)) + +def move(src, dst): + """Recursively move a file or directory to another location. This is + similar to the Unix "mv" command. + + If the destination is a directory or a symlink to a directory, the source + is moved inside the directory. The destination path must not already + exist. + + If the destination already exists but is not a directory, it may be + overwritten depending on os.rename() semantics. + + If the destination is on our current filesystem, then rename() is used. + Otherwise, src is copied to the destination and then removed. + A lot more could be done here... A look at a mv.c shows a lot of + the issues this implementation glosses over. + + """ + real_dst = dst + if os.path.isdir(dst): + if _samefile(src, dst): + # We might be on a case insensitive filesystem, + # perform the rename anyway. + os.rename(src, dst) + return + + real_dst = os.path.join(dst, _basename(src)) + if os.path.exists(real_dst): + raise Error("Destination path '%s' already exists" % real_dst) + try: + os.rename(src, real_dst) + except OSError: + if os.path.isdir(src): + if _destinsrc(src, dst): + raise Error("Cannot move a directory '%s' into itself '%s'." % (src, dst)) + copytree(src, real_dst, symlinks=True) + rmtree(src) + else: + copy2(src, real_dst) + os.unlink(src) + +def _destinsrc(src, dst): + src = abspath(src) + dst = abspath(dst) + if not src.endswith(os.path.sep): + src += os.path.sep + if not dst.endswith(os.path.sep): + dst += os.path.sep + return dst.startswith(src) + +def _get_gid(name): + """Returns a gid, given a group name.""" + if getgrnam is None or name is None: + return None + try: + result = getgrnam(name) + except KeyError: + result = None + if result is not None: + return result[2] + return None + +def _get_uid(name): + """Returns an uid, given a user name.""" + if getpwnam is None or name is None: + return None + try: + result = getpwnam(name) + except KeyError: + result = None + if result is not None: + return result[2] + return None + +def _make_tarball(base_name, base_dir, compress="gzip", verbose=0, dry_run=0, + owner=None, group=None, logger=None): + """Create a (possibly compressed) tar file from all the files under + 'base_dir'. + + 'compress' must be "gzip" (the default), "bzip2", or None. + + 'owner' and 'group' can be used to define an owner and a group for the + archive that is being built. If not provided, the current owner and group + will be used. + + The output tar file will be named 'base_name' + ".tar", possibly plus + the appropriate compression extension (".gz", or ".bz2"). + + Returns the output filename. + """ + tar_compression = {'gzip': 'gz', None: ''} + compress_ext = {'gzip': '.gz'} + + if _BZ2_SUPPORTED: + tar_compression['bzip2'] = 'bz2' + compress_ext['bzip2'] = '.bz2' + + # flags for compression program, each element of list will be an argument + if compress is not None and compress not in compress_ext: + raise ValueError("bad value for 'compress', or compression format not " + "supported : {0}".format(compress)) + + archive_name = base_name + '.tar' + compress_ext.get(compress, '') + archive_dir = os.path.dirname(archive_name) + + if not os.path.exists(archive_dir): + if logger is not None: + logger.info("creating %s", archive_dir) + if not dry_run: + os.makedirs(archive_dir) + + # creating the tarball + if logger is not None: + logger.info('Creating tar archive') + + uid = _get_uid(owner) + gid = _get_gid(group) + + def _set_uid_gid(tarinfo): + if gid is not None: + tarinfo.gid = gid + tarinfo.gname = group + if uid is not None: + tarinfo.uid = uid + tarinfo.uname = owner + return tarinfo + + if not dry_run: + tar = tarfile.open(archive_name, 'w|%s' % tar_compression[compress]) + try: + tar.add(base_dir, filter=_set_uid_gid) + finally: + tar.close() + + return archive_name + +def _call_external_zip(base_dir, zip_filename, verbose=False, dry_run=False): + # XXX see if we want to keep an external call here + if verbose: + zipoptions = "-r" + else: + zipoptions = "-rq" + from distutils.errors import DistutilsExecError + from distutils.spawn import spawn + try: + spawn(["zip", zipoptions, zip_filename, base_dir], dry_run=dry_run) + except DistutilsExecError: + # XXX really should distinguish between "couldn't find + # external 'zip' command" and "zip failed". + raise ExecError("unable to create zip file '%s': " + "could neither import the 'zipfile' module nor " + "find a standalone zip utility") % zip_filename + +def _make_zipfile(base_name, base_dir, verbose=0, dry_run=0, logger=None): + """Create a zip file from all the files under 'base_dir'. + + The output zip file will be named 'base_name' + ".zip". Uses either the + "zipfile" Python module (if available) or the InfoZIP "zip" utility + (if installed and found on the default search path). If neither tool is + available, raises ExecError. Returns the name of the output zip + file. + """ + zip_filename = base_name + ".zip" + archive_dir = os.path.dirname(base_name) + + if not os.path.exists(archive_dir): + if logger is not None: + logger.info("creating %s", archive_dir) + if not dry_run: + os.makedirs(archive_dir) + + # If zipfile module is not available, try spawning an external 'zip' + # command. + try: + import zipfile + except ImportError: + zipfile = None + + if zipfile is None: + _call_external_zip(base_dir, zip_filename, verbose, dry_run) + else: + if logger is not None: + logger.info("creating '%s' and adding '%s' to it", + zip_filename, base_dir) + + if not dry_run: + zip = zipfile.ZipFile(zip_filename, "w", + compression=zipfile.ZIP_DEFLATED) + + for dirpath, dirnames, filenames in os.walk(base_dir): + for name in filenames: + path = os.path.normpath(os.path.join(dirpath, name)) + if os.path.isfile(path): + zip.write(path, path) + if logger is not None: + logger.info("adding '%s'", path) + zip.close() + + return zip_filename + +_ARCHIVE_FORMATS = { + 'gztar': (_make_tarball, [('compress', 'gzip')], "gzip'ed tar-file"), + 'bztar': (_make_tarball, [('compress', 'bzip2')], "bzip2'ed tar-file"), + 'tar': (_make_tarball, [('compress', None)], "uncompressed tar file"), + 'zip': (_make_zipfile, [], "ZIP file"), + } + +if _BZ2_SUPPORTED: + _ARCHIVE_FORMATS['bztar'] = (_make_tarball, [('compress', 'bzip2')], + "bzip2'ed tar-file") + +def get_archive_formats(): + """Returns a list of supported formats for archiving and unarchiving. + + Each element of the returned sequence is a tuple (name, description) + """ + formats = [(name, registry[2]) for name, registry in + _ARCHIVE_FORMATS.items()] + formats.sort() + return formats + +def register_archive_format(name, function, extra_args=None, description=''): + """Registers an archive format. + + name is the name of the format. function is the callable that will be + used to create archives. If provided, extra_args is a sequence of + (name, value) tuples that will be passed as arguments to the callable. + description can be provided to describe the format, and will be returned + by the get_archive_formats() function. + """ + if extra_args is None: + extra_args = [] + if not isinstance(function, Callable): + raise TypeError('The %s object is not callable' % function) + if not isinstance(extra_args, (tuple, list)): + raise TypeError('extra_args needs to be a sequence') + for element in extra_args: + if not isinstance(element, (tuple, list)) or len(element) !=2: + raise TypeError('extra_args elements are : (arg_name, value)') + + _ARCHIVE_FORMATS[name] = (function, extra_args, description) + +def unregister_archive_format(name): + del _ARCHIVE_FORMATS[name] + +def make_archive(base_name, format, root_dir=None, base_dir=None, verbose=0, + dry_run=0, owner=None, group=None, logger=None): + """Create an archive file (eg. zip or tar). + + 'base_name' is the name of the file to create, minus any format-specific + extension; 'format' is the archive format: one of "zip", "tar", "bztar" + or "gztar". + + 'root_dir' is a directory that will be the root directory of the + archive; ie. we typically chdir into 'root_dir' before creating the + archive. 'base_dir' is the directory where we start archiving from; + ie. 'base_dir' will be the common prefix of all files and + directories in the archive. 'root_dir' and 'base_dir' both default + to the current directory. Returns the name of the archive file. + + 'owner' and 'group' are used when creating a tar archive. By default, + uses the current owner and group. + """ + save_cwd = os.getcwd() + if root_dir is not None: + if logger is not None: + logger.debug("changing into '%s'", root_dir) + base_name = os.path.abspath(base_name) + if not dry_run: + os.chdir(root_dir) + + if base_dir is None: + base_dir = os.curdir + + kwargs = {'dry_run': dry_run, 'logger': logger} + + try: + format_info = _ARCHIVE_FORMATS[format] + except KeyError: + raise ValueError("unknown archive format '%s'" % format) + + func = format_info[0] + for arg, val in format_info[1]: + kwargs[arg] = val + + if format != 'zip': + kwargs['owner'] = owner + kwargs['group'] = group + + try: + filename = func(base_name, base_dir, **kwargs) + finally: + if root_dir is not None: + if logger is not None: + logger.debug("changing back to '%s'", save_cwd) + os.chdir(save_cwd) + + return filename + + +def get_unpack_formats(): + """Returns a list of supported formats for unpacking. + + Each element of the returned sequence is a tuple + (name, extensions, description) + """ + formats = [(name, info[0], info[3]) for name, info in + _UNPACK_FORMATS.items()] + formats.sort() + return formats + +def _check_unpack_options(extensions, function, extra_args): + """Checks what gets registered as an unpacker.""" + # first make sure no other unpacker is registered for this extension + existing_extensions = {} + for name, info in _UNPACK_FORMATS.items(): + for ext in info[0]: + existing_extensions[ext] = name + + for extension in extensions: + if extension in existing_extensions: + msg = '%s is already registered for "%s"' + raise RegistryError(msg % (extension, + existing_extensions[extension])) + + if not isinstance(function, Callable): + raise TypeError('The registered function must be a callable') + + +def register_unpack_format(name, extensions, function, extra_args=None, + description=''): + """Registers an unpack format. + + `name` is the name of the format. `extensions` is a list of extensions + corresponding to the format. + + `function` is the callable that will be + used to unpack archives. The callable will receive archives to unpack. + If it's unable to handle an archive, it needs to raise a ReadError + exception. + + If provided, `extra_args` is a sequence of + (name, value) tuples that will be passed as arguments to the callable. + description can be provided to describe the format, and will be returned + by the get_unpack_formats() function. + """ + if extra_args is None: + extra_args = [] + _check_unpack_options(extensions, function, extra_args) + _UNPACK_FORMATS[name] = extensions, function, extra_args, description + +def unregister_unpack_format(name): + """Removes the pack format from the registry.""" + del _UNPACK_FORMATS[name] + +def _ensure_directory(path): + """Ensure that the parent directory of `path` exists""" + dirname = os.path.dirname(path) + if not os.path.isdir(dirname): + os.makedirs(dirname) + +def _unpack_zipfile(filename, extract_dir): + """Unpack zip `filename` to `extract_dir` + """ + try: + import zipfile + except ImportError: + raise ReadError('zlib not supported, cannot unpack this archive.') + + if not zipfile.is_zipfile(filename): + raise ReadError("%s is not a zip file" % filename) + + zip = zipfile.ZipFile(filename) + try: + for info in zip.infolist(): + name = info.filename + + # don't extract absolute paths or ones with .. in them + if name.startswith('/') or '..' in name: + continue + + target = os.path.join(extract_dir, *name.split('/')) + if not target: + continue + + _ensure_directory(target) + if not name.endswith('/'): + # file + data = zip.read(info.filename) + f = open(target, 'wb') + try: + f.write(data) + finally: + f.close() + del data + finally: + zip.close() + +def _unpack_tarfile(filename, extract_dir): + """Unpack tar/tar.gz/tar.bz2 `filename` to `extract_dir` + """ + try: + tarobj = tarfile.open(filename) + except tarfile.TarError: + raise ReadError( + "%s is not a compressed or uncompressed tar file" % filename) + try: + tarobj.extractall(extract_dir) + finally: + tarobj.close() + +_UNPACK_FORMATS = { + 'gztar': (['.tar.gz', '.tgz'], _unpack_tarfile, [], "gzip'ed tar-file"), + 'tar': (['.tar'], _unpack_tarfile, [], "uncompressed tar file"), + 'zip': (['.zip'], _unpack_zipfile, [], "ZIP file") + } + +if _BZ2_SUPPORTED: + _UNPACK_FORMATS['bztar'] = (['.bz2'], _unpack_tarfile, [], + "bzip2'ed tar-file") + +def _find_unpack_format(filename): + for name, info in _UNPACK_FORMATS.items(): + for extension in info[0]: + if filename.endswith(extension): + return name + return None + +def unpack_archive(filename, extract_dir=None, format=None): + """Unpack an archive. + + `filename` is the name of the archive. + + `extract_dir` is the name of the target directory, where the archive + is unpacked. If not provided, the current working directory is used. + + `format` is the archive format: one of "zip", "tar", or "gztar". Or any + other registered format. If not provided, unpack_archive will use the + filename extension and see if an unpacker was registered for that + extension. + + In case none is found, a ValueError is raised. + """ + if extract_dir is None: + extract_dir = os.getcwd() + + if format is not None: + try: + format_info = _UNPACK_FORMATS[format] + except KeyError: + raise ValueError("Unknown unpack format '{0}'".format(format)) + + func = format_info[1] + func(filename, extract_dir, **dict(format_info[2])) + else: + # we need to look at the registered unpackers supported extensions + format = _find_unpack_format(filename) + if format is None: + raise ReadError("Unknown archive format '{0}'".format(filename)) + + func = _UNPACK_FORMATS[format][1] + kwargs = dict(_UNPACK_FORMATS[format][2]) + func(filename, extract_dir, **kwargs) diff --git a/venv/Lib/site-packages/pip/_vendor/distlib/_backport/sysconfig.cfg b/venv/Lib/site-packages/pip/_vendor/distlib/_backport/sysconfig.cfg new file mode 100644 index 0000000..1746bd0 --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/distlib/_backport/sysconfig.cfg @@ -0,0 +1,84 @@ +[posix_prefix] +# Configuration directories. Some of these come straight out of the +# configure script. They are for implementing the other variables, not to +# be used directly in [resource_locations]. +confdir = /etc +datadir = /usr/share +libdir = /usr/lib +statedir = /var +# User resource directory +local = ~/.local/{distribution.name} + +stdlib = {base}/lib/python{py_version_short} +platstdlib = {platbase}/lib/python{py_version_short} +purelib = {base}/lib/python{py_version_short}/site-packages +platlib = {platbase}/lib/python{py_version_short}/site-packages +include = {base}/include/python{py_version_short}{abiflags} +platinclude = {platbase}/include/python{py_version_short}{abiflags} +data = {base} + +[posix_home] +stdlib = {base}/lib/python +platstdlib = {base}/lib/python +purelib = {base}/lib/python +platlib = {base}/lib/python +include = {base}/include/python +platinclude = {base}/include/python +scripts = {base}/bin +data = {base} + +[nt] +stdlib = {base}/Lib +platstdlib = {base}/Lib +purelib = {base}/Lib/site-packages +platlib = {base}/Lib/site-packages +include = {base}/Include +platinclude = {base}/Include +scripts = {base}/Scripts +data = {base} + +[os2] +stdlib = {base}/Lib +platstdlib = {base}/Lib +purelib = {base}/Lib/site-packages +platlib = {base}/Lib/site-packages +include = {base}/Include +platinclude = {base}/Include +scripts = {base}/Scripts +data = {base} + +[os2_home] +stdlib = {userbase}/lib/python{py_version_short} +platstdlib = {userbase}/lib/python{py_version_short} +purelib = {userbase}/lib/python{py_version_short}/site-packages +platlib = {userbase}/lib/python{py_version_short}/site-packages +include = {userbase}/include/python{py_version_short} +scripts = {userbase}/bin +data = {userbase} + +[nt_user] +stdlib = {userbase}/Python{py_version_nodot} +platstdlib = {userbase}/Python{py_version_nodot} +purelib = {userbase}/Python{py_version_nodot}/site-packages +platlib = {userbase}/Python{py_version_nodot}/site-packages +include = {userbase}/Python{py_version_nodot}/Include +scripts = {userbase}/Scripts +data = {userbase} + +[posix_user] +stdlib = {userbase}/lib/python{py_version_short} +platstdlib = {userbase}/lib/python{py_version_short} +purelib = {userbase}/lib/python{py_version_short}/site-packages +platlib = {userbase}/lib/python{py_version_short}/site-packages +include = {userbase}/include/python{py_version_short} +scripts = {userbase}/bin +data = {userbase} + +[osx_framework_user] +stdlib = {userbase}/lib/python +platstdlib = {userbase}/lib/python +purelib = {userbase}/lib/python/site-packages +platlib = {userbase}/lib/python/site-packages +include = {userbase}/include +scripts = {userbase}/bin +data = {userbase} diff --git a/venv/Lib/site-packages/pip/_vendor/distlib/_backport/sysconfig.py b/venv/Lib/site-packages/pip/_vendor/distlib/_backport/sysconfig.py new file mode 100644 index 0000000..b470a37 --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/distlib/_backport/sysconfig.py @@ -0,0 +1,786 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2012 The Python Software Foundation. +# See LICENSE.txt and CONTRIBUTORS.txt. +# +"""Access to Python's configuration information.""" + +import codecs +import os +import re +import sys +from os.path import pardir, realpath +try: + import configparser +except ImportError: + import ConfigParser as configparser + + +__all__ = [ + 'get_config_h_filename', + 'get_config_var', + 'get_config_vars', + 'get_makefile_filename', + 'get_path', + 'get_path_names', + 'get_paths', + 'get_platform', + 'get_python_version', + 'get_scheme_names', + 'parse_config_h', +] + + +def _safe_realpath(path): + try: + return realpath(path) + except OSError: + return path + + +if sys.executable: + _PROJECT_BASE = os.path.dirname(_safe_realpath(sys.executable)) +else: + # sys.executable can be empty if argv[0] has been changed and Python is + # unable to retrieve the real program name + _PROJECT_BASE = _safe_realpath(os.getcwd()) + +if os.name == "nt" and "pcbuild" in _PROJECT_BASE[-8:].lower(): + _PROJECT_BASE = _safe_realpath(os.path.join(_PROJECT_BASE, pardir)) +# PC/VS7.1 +if os.name == "nt" and "\\pc\\v" in _PROJECT_BASE[-10:].lower(): + _PROJECT_BASE = _safe_realpath(os.path.join(_PROJECT_BASE, pardir, pardir)) +# PC/AMD64 +if os.name == "nt" and "\\pcbuild\\amd64" in _PROJECT_BASE[-14:].lower(): + _PROJECT_BASE = _safe_realpath(os.path.join(_PROJECT_BASE, pardir, pardir)) + + +def is_python_build(): + for fn in ("Setup.dist", "Setup.local"): + if os.path.isfile(os.path.join(_PROJECT_BASE, "Modules", fn)): + return True + return False + +_PYTHON_BUILD = is_python_build() + +_cfg_read = False + +def _ensure_cfg_read(): + global _cfg_read + if not _cfg_read: + from ..resources import finder + backport_package = __name__.rsplit('.', 1)[0] + _finder = finder(backport_package) + _cfgfile = _finder.find('sysconfig.cfg') + assert _cfgfile, 'sysconfig.cfg exists' + with _cfgfile.as_stream() as s: + _SCHEMES.readfp(s) + if _PYTHON_BUILD: + for scheme in ('posix_prefix', 'posix_home'): + _SCHEMES.set(scheme, 'include', '{srcdir}/Include') + _SCHEMES.set(scheme, 'platinclude', '{projectbase}/.') + + _cfg_read = True + + +_SCHEMES = configparser.RawConfigParser() +_VAR_REPL = re.compile(r'\{([^{]*?)\}') + +def _expand_globals(config): + _ensure_cfg_read() + if config.has_section('globals'): + globals = config.items('globals') + else: + globals = tuple() + + sections = config.sections() + for section in sections: + if section == 'globals': + continue + for option, value in globals: + if config.has_option(section, option): + continue + config.set(section, option, value) + config.remove_section('globals') + + # now expanding local variables defined in the cfg file + # + for section in config.sections(): + variables = dict(config.items(section)) + + def _replacer(matchobj): + name = matchobj.group(1) + if name in variables: + return variables[name] + return matchobj.group(0) + + for option, value in config.items(section): + config.set(section, option, _VAR_REPL.sub(_replacer, value)) + +#_expand_globals(_SCHEMES) + +_PY_VERSION = '%s.%s.%s' % sys.version_info[:3] +_PY_VERSION_SHORT = '%s.%s' % sys.version_info[:2] +_PY_VERSION_SHORT_NO_DOT = '%s%s' % sys.version_info[:2] +_PREFIX = os.path.normpath(sys.prefix) +_EXEC_PREFIX = os.path.normpath(sys.exec_prefix) +_CONFIG_VARS = None +_USER_BASE = None + + +def _subst_vars(path, local_vars): + """In the string `path`, replace tokens like {some.thing} with the + corresponding value from the map `local_vars`. + + If there is no corresponding value, leave the token unchanged. + """ + def _replacer(matchobj): + name = matchobj.group(1) + if name in local_vars: + return local_vars[name] + elif name in os.environ: + return os.environ[name] + return matchobj.group(0) + return _VAR_REPL.sub(_replacer, path) + + +def _extend_dict(target_dict, other_dict): + target_keys = target_dict.keys() + for key, value in other_dict.items(): + if key in target_keys: + continue + target_dict[key] = value + + +def _expand_vars(scheme, vars): + res = {} + if vars is None: + vars = {} + _extend_dict(vars, get_config_vars()) + + for key, value in _SCHEMES.items(scheme): + if os.name in ('posix', 'nt'): + value = os.path.expanduser(value) + res[key] = os.path.normpath(_subst_vars(value, vars)) + return res + + +def format_value(value, vars): + def _replacer(matchobj): + name = matchobj.group(1) + if name in vars: + return vars[name] + return matchobj.group(0) + return _VAR_REPL.sub(_replacer, value) + + +def _get_default_scheme(): + if os.name == 'posix': + # the default scheme for posix is posix_prefix + return 'posix_prefix' + return os.name + + +def _getuserbase(): + env_base = os.environ.get("PYTHONUSERBASE", None) + + def joinuser(*args): + return os.path.expanduser(os.path.join(*args)) + + # what about 'os2emx', 'riscos' ? + if os.name == "nt": + base = os.environ.get("APPDATA") or "~" + if env_base: + return env_base + else: + return joinuser(base, "Python") + + if sys.platform == "darwin": + framework = get_config_var("PYTHONFRAMEWORK") + if framework: + if env_base: + return env_base + else: + return joinuser("~", "Library", framework, "%d.%d" % + sys.version_info[:2]) + + if env_base: + return env_base + else: + return joinuser("~", ".local") + + +def _parse_makefile(filename, vars=None): + """Parse a Makefile-style file. + + A dictionary containing name/value pairs is returned. If an + optional dictionary is passed in as the second argument, it is + used instead of a new dictionary. + """ + # Regexes needed for parsing Makefile (and similar syntaxes, + # like old-style Setup files). + _variable_rx = re.compile(r"([a-zA-Z][a-zA-Z0-9_]+)\s*=\s*(.*)") + _findvar1_rx = re.compile(r"\$\(([A-Za-z][A-Za-z0-9_]*)\)") + _findvar2_rx = re.compile(r"\${([A-Za-z][A-Za-z0-9_]*)}") + + if vars is None: + vars = {} + done = {} + notdone = {} + + with codecs.open(filename, encoding='utf-8', errors="surrogateescape") as f: + lines = f.readlines() + + for line in lines: + if line.startswith('#') or line.strip() == '': + continue + m = _variable_rx.match(line) + if m: + n, v = m.group(1, 2) + v = v.strip() + # `$$' is a literal `$' in make + tmpv = v.replace('$$', '') + + if "$" in tmpv: + notdone[n] = v + else: + try: + v = int(v) + except ValueError: + # insert literal `$' + done[n] = v.replace('$$', '$') + else: + done[n] = v + + # do variable interpolation here + variables = list(notdone.keys()) + + # Variables with a 'PY_' prefix in the makefile. These need to + # be made available without that prefix through sysconfig. + # Special care is needed to ensure that variable expansion works, even + # if the expansion uses the name without a prefix. + renamed_variables = ('CFLAGS', 'LDFLAGS', 'CPPFLAGS') + + while len(variables) > 0: + for name in tuple(variables): + value = notdone[name] + m = _findvar1_rx.search(value) or _findvar2_rx.search(value) + if m is not None: + n = m.group(1) + found = True + if n in done: + item = str(done[n]) + elif n in notdone: + # get it on a subsequent round + found = False + elif n in os.environ: + # do it like make: fall back to environment + item = os.environ[n] + + elif n in renamed_variables: + if (name.startswith('PY_') and + name[3:] in renamed_variables): + item = "" + + elif 'PY_' + n in notdone: + found = False + + else: + item = str(done['PY_' + n]) + + else: + done[n] = item = "" + + if found: + after = value[m.end():] + value = value[:m.start()] + item + after + if "$" in after: + notdone[name] = value + else: + try: + value = int(value) + except ValueError: + done[name] = value.strip() + else: + done[name] = value + variables.remove(name) + + if (name.startswith('PY_') and + name[3:] in renamed_variables): + + name = name[3:] + if name not in done: + done[name] = value + + else: + # bogus variable reference (e.g. "prefix=$/opt/python"); + # just drop it since we can't deal + done[name] = value + variables.remove(name) + + # strip spurious spaces + for k, v in done.items(): + if isinstance(v, str): + done[k] = v.strip() + + # save the results in the global dictionary + vars.update(done) + return vars + + +def get_makefile_filename(): + """Return the path of the Makefile.""" + if _PYTHON_BUILD: + return os.path.join(_PROJECT_BASE, "Makefile") + if hasattr(sys, 'abiflags'): + config_dir_name = 'config-%s%s' % (_PY_VERSION_SHORT, sys.abiflags) + else: + config_dir_name = 'config' + return os.path.join(get_path('stdlib'), config_dir_name, 'Makefile') + + +def _init_posix(vars): + """Initialize the module as appropriate for POSIX systems.""" + # load the installed Makefile: + makefile = get_makefile_filename() + try: + _parse_makefile(makefile, vars) + except IOError as e: + msg = "invalid Python installation: unable to open %s" % makefile + if hasattr(e, "strerror"): + msg = msg + " (%s)" % e.strerror + raise IOError(msg) + # load the installed pyconfig.h: + config_h = get_config_h_filename() + try: + with open(config_h) as f: + parse_config_h(f, vars) + except IOError as e: + msg = "invalid Python installation: unable to open %s" % config_h + if hasattr(e, "strerror"): + msg = msg + " (%s)" % e.strerror + raise IOError(msg) + # On AIX, there are wrong paths to the linker scripts in the Makefile + # -- these paths are relative to the Python source, but when installed + # the scripts are in another directory. + if _PYTHON_BUILD: + vars['LDSHARED'] = vars['BLDSHARED'] + + +def _init_non_posix(vars): + """Initialize the module as appropriate for NT""" + # set basic install directories + vars['LIBDEST'] = get_path('stdlib') + vars['BINLIBDEST'] = get_path('platstdlib') + vars['INCLUDEPY'] = get_path('include') + vars['SO'] = '.pyd' + vars['EXE'] = '.exe' + vars['VERSION'] = _PY_VERSION_SHORT_NO_DOT + vars['BINDIR'] = os.path.dirname(_safe_realpath(sys.executable)) + +# +# public APIs +# + + +def parse_config_h(fp, vars=None): + """Parse a config.h-style file. + + A dictionary containing name/value pairs is returned. If an + optional dictionary is passed in as the second argument, it is + used instead of a new dictionary. + """ + if vars is None: + vars = {} + define_rx = re.compile("#define ([A-Z][A-Za-z0-9_]+) (.*)\n") + undef_rx = re.compile("/[*] #undef ([A-Z][A-Za-z0-9_]+) [*]/\n") + + while True: + line = fp.readline() + if not line: + break + m = define_rx.match(line) + if m: + n, v = m.group(1, 2) + try: + v = int(v) + except ValueError: + pass + vars[n] = v + else: + m = undef_rx.match(line) + if m: + vars[m.group(1)] = 0 + return vars + + +def get_config_h_filename(): + """Return the path of pyconfig.h.""" + if _PYTHON_BUILD: + if os.name == "nt": + inc_dir = os.path.join(_PROJECT_BASE, "PC") + else: + inc_dir = _PROJECT_BASE + else: + inc_dir = get_path('platinclude') + return os.path.join(inc_dir, 'pyconfig.h') + + +def get_scheme_names(): + """Return a tuple containing the schemes names.""" + return tuple(sorted(_SCHEMES.sections())) + + +def get_path_names(): + """Return a tuple containing the paths names.""" + # xxx see if we want a static list + return _SCHEMES.options('posix_prefix') + + +def get_paths(scheme=_get_default_scheme(), vars=None, expand=True): + """Return a mapping containing an install scheme. + + ``scheme`` is the install scheme name. If not provided, it will + return the default scheme for the current platform. + """ + _ensure_cfg_read() + if expand: + return _expand_vars(scheme, vars) + else: + return dict(_SCHEMES.items(scheme)) + + +def get_path(name, scheme=_get_default_scheme(), vars=None, expand=True): + """Return a path corresponding to the scheme. + + ``scheme`` is the install scheme name. + """ + return get_paths(scheme, vars, expand)[name] + + +def get_config_vars(*args): + """With no arguments, return a dictionary of all configuration + variables relevant for the current platform. + + On Unix, this means every variable defined in Python's installed Makefile; + On Windows and Mac OS it's a much smaller set. + + With arguments, return a list of values that result from looking up + each argument in the configuration variable dictionary. + """ + global _CONFIG_VARS + if _CONFIG_VARS is None: + _CONFIG_VARS = {} + # Normalized versions of prefix and exec_prefix are handy to have; + # in fact, these are the standard versions used most places in the + # distutils2 module. + _CONFIG_VARS['prefix'] = _PREFIX + _CONFIG_VARS['exec_prefix'] = _EXEC_PREFIX + _CONFIG_VARS['py_version'] = _PY_VERSION + _CONFIG_VARS['py_version_short'] = _PY_VERSION_SHORT + _CONFIG_VARS['py_version_nodot'] = _PY_VERSION[0] + _PY_VERSION[2] + _CONFIG_VARS['base'] = _PREFIX + _CONFIG_VARS['platbase'] = _EXEC_PREFIX + _CONFIG_VARS['projectbase'] = _PROJECT_BASE + try: + _CONFIG_VARS['abiflags'] = sys.abiflags + except AttributeError: + # sys.abiflags may not be defined on all platforms. + _CONFIG_VARS['abiflags'] = '' + + if os.name in ('nt', 'os2'): + _init_non_posix(_CONFIG_VARS) + if os.name == 'posix': + _init_posix(_CONFIG_VARS) + # Setting 'userbase' is done below the call to the + # init function to enable using 'get_config_var' in + # the init-function. + if sys.version >= '2.6': + _CONFIG_VARS['userbase'] = _getuserbase() + + if 'srcdir' not in _CONFIG_VARS: + _CONFIG_VARS['srcdir'] = _PROJECT_BASE + else: + _CONFIG_VARS['srcdir'] = _safe_realpath(_CONFIG_VARS['srcdir']) + + # Convert srcdir into an absolute path if it appears necessary. + # Normally it is relative to the build directory. However, during + # testing, for example, we might be running a non-installed python + # from a different directory. + if _PYTHON_BUILD and os.name == "posix": + base = _PROJECT_BASE + try: + cwd = os.getcwd() + except OSError: + cwd = None + if (not os.path.isabs(_CONFIG_VARS['srcdir']) and + base != cwd): + # srcdir is relative and we are not in the same directory + # as the executable. Assume executable is in the build + # directory and make srcdir absolute. + srcdir = os.path.join(base, _CONFIG_VARS['srcdir']) + _CONFIG_VARS['srcdir'] = os.path.normpath(srcdir) + + if sys.platform == 'darwin': + kernel_version = os.uname()[2] # Kernel version (8.4.3) + major_version = int(kernel_version.split('.')[0]) + + if major_version < 8: + # On Mac OS X before 10.4, check if -arch and -isysroot + # are in CFLAGS or LDFLAGS and remove them if they are. + # This is needed when building extensions on a 10.3 system + # using a universal build of python. + for key in ('LDFLAGS', 'BASECFLAGS', + # a number of derived variables. These need to be + # patched up as well. + 'CFLAGS', 'PY_CFLAGS', 'BLDSHARED'): + flags = _CONFIG_VARS[key] + flags = re.sub(r'-arch\s+\w+\s', ' ', flags) + flags = re.sub('-isysroot [^ \t]*', ' ', flags) + _CONFIG_VARS[key] = flags + else: + # Allow the user to override the architecture flags using + # an environment variable. + # NOTE: This name was introduced by Apple in OSX 10.5 and + # is used by several scripting languages distributed with + # that OS release. + if 'ARCHFLAGS' in os.environ: + arch = os.environ['ARCHFLAGS'] + for key in ('LDFLAGS', 'BASECFLAGS', + # a number of derived variables. These need to be + # patched up as well. + 'CFLAGS', 'PY_CFLAGS', 'BLDSHARED'): + + flags = _CONFIG_VARS[key] + flags = re.sub(r'-arch\s+\w+\s', ' ', flags) + flags = flags + ' ' + arch + _CONFIG_VARS[key] = flags + + # If we're on OSX 10.5 or later and the user tries to + # compiles an extension using an SDK that is not present + # on the current machine it is better to not use an SDK + # than to fail. + # + # The major usecase for this is users using a Python.org + # binary installer on OSX 10.6: that installer uses + # the 10.4u SDK, but that SDK is not installed by default + # when you install Xcode. + # + CFLAGS = _CONFIG_VARS.get('CFLAGS', '') + m = re.search(r'-isysroot\s+(\S+)', CFLAGS) + if m is not None: + sdk = m.group(1) + if not os.path.exists(sdk): + for key in ('LDFLAGS', 'BASECFLAGS', + # a number of derived variables. These need to be + # patched up as well. + 'CFLAGS', 'PY_CFLAGS', 'BLDSHARED'): + + flags = _CONFIG_VARS[key] + flags = re.sub(r'-isysroot\s+\S+(\s|$)', ' ', flags) + _CONFIG_VARS[key] = flags + + if args: + vals = [] + for name in args: + vals.append(_CONFIG_VARS.get(name)) + return vals + else: + return _CONFIG_VARS + + +def get_config_var(name): + """Return the value of a single variable using the dictionary returned by + 'get_config_vars()'. + + Equivalent to get_config_vars().get(name) + """ + return get_config_vars().get(name) + + +def get_platform(): + """Return a string that identifies the current platform. + + This is used mainly to distinguish platform-specific build directories and + platform-specific built distributions. Typically includes the OS name + and version and the architecture (as supplied by 'os.uname()'), + although the exact information included depends on the OS; eg. for IRIX + the architecture isn't particularly important (IRIX only runs on SGI + hardware), but for Linux the kernel version isn't particularly + important. + + Examples of returned values: + linux-i586 + linux-alpha (?) + solaris-2.6-sun4u + irix-5.3 + irix64-6.2 + + Windows will return one of: + win-amd64 (64bit Windows on AMD64 (aka x86_64, Intel64, EM64T, etc) + win-ia64 (64bit Windows on Itanium) + win32 (all others - specifically, sys.platform is returned) + + For other non-POSIX platforms, currently just returns 'sys.platform'. + """ + if os.name == 'nt': + # sniff sys.version for architecture. + prefix = " bit (" + i = sys.version.find(prefix) + if i == -1: + return sys.platform + j = sys.version.find(")", i) + look = sys.version[i+len(prefix):j].lower() + if look == 'amd64': + return 'win-amd64' + if look == 'itanium': + return 'win-ia64' + return sys.platform + + if os.name != "posix" or not hasattr(os, 'uname'): + # XXX what about the architecture? NT is Intel or Alpha, + # Mac OS is M68k or PPC, etc. + return sys.platform + + # Try to distinguish various flavours of Unix + osname, host, release, version, machine = os.uname() + + # Convert the OS name to lowercase, remove '/' characters + # (to accommodate BSD/OS), and translate spaces (for "Power Macintosh") + osname = osname.lower().replace('/', '') + machine = machine.replace(' ', '_') + machine = machine.replace('/', '-') + + if osname[:5] == "linux": + # At least on Linux/Intel, 'machine' is the processor -- + # i386, etc. + # XXX what about Alpha, SPARC, etc? + return "%s-%s" % (osname, machine) + elif osname[:5] == "sunos": + if release[0] >= "5": # SunOS 5 == Solaris 2 + osname = "solaris" + release = "%d.%s" % (int(release[0]) - 3, release[2:]) + # fall through to standard osname-release-machine representation + elif osname[:4] == "irix": # could be "irix64"! + return "%s-%s" % (osname, release) + elif osname[:3] == "aix": + return "%s-%s.%s" % (osname, version, release) + elif osname[:6] == "cygwin": + osname = "cygwin" + rel_re = re.compile(r'[\d.]+') + m = rel_re.match(release) + if m: + release = m.group() + elif osname[:6] == "darwin": + # + # For our purposes, we'll assume that the system version from + # distutils' perspective is what MACOSX_DEPLOYMENT_TARGET is set + # to. This makes the compatibility story a bit more sane because the + # machine is going to compile and link as if it were + # MACOSX_DEPLOYMENT_TARGET. + cfgvars = get_config_vars() + macver = cfgvars.get('MACOSX_DEPLOYMENT_TARGET') + + if True: + # Always calculate the release of the running machine, + # needed to determine if we can build fat binaries or not. + + macrelease = macver + # Get the system version. Reading this plist is a documented + # way to get the system version (see the documentation for + # the Gestalt Manager) + try: + f = open('/System/Library/CoreServices/SystemVersion.plist') + except IOError: + # We're on a plain darwin box, fall back to the default + # behaviour. + pass + else: + try: + m = re.search(r'ProductUserVisibleVersion\s*' + r'(.*?)', f.read()) + finally: + f.close() + if m is not None: + macrelease = '.'.join(m.group(1).split('.')[:2]) + # else: fall back to the default behaviour + + if not macver: + macver = macrelease + + if macver: + release = macver + osname = "macosx" + + if ((macrelease + '.') >= '10.4.' and + '-arch' in get_config_vars().get('CFLAGS', '').strip()): + # The universal build will build fat binaries, but not on + # systems before 10.4 + # + # Try to detect 4-way universal builds, those have machine-type + # 'universal' instead of 'fat'. + + machine = 'fat' + cflags = get_config_vars().get('CFLAGS') + + archs = re.findall(r'-arch\s+(\S+)', cflags) + archs = tuple(sorted(set(archs))) + + if len(archs) == 1: + machine = archs[0] + elif archs == ('i386', 'ppc'): + machine = 'fat' + elif archs == ('i386', 'x86_64'): + machine = 'intel' + elif archs == ('i386', 'ppc', 'x86_64'): + machine = 'fat3' + elif archs == ('ppc64', 'x86_64'): + machine = 'fat64' + elif archs == ('i386', 'ppc', 'ppc64', 'x86_64'): + machine = 'universal' + else: + raise ValueError( + "Don't know machine value for archs=%r" % (archs,)) + + elif machine == 'i386': + # On OSX the machine type returned by uname is always the + # 32-bit variant, even if the executable architecture is + # the 64-bit variant + if sys.maxsize >= 2**32: + machine = 'x86_64' + + elif machine in ('PowerPC', 'Power_Macintosh'): + # Pick a sane name for the PPC architecture. + # See 'i386' case + if sys.maxsize >= 2**32: + machine = 'ppc64' + else: + machine = 'ppc' + + return "%s-%s-%s" % (osname, release, machine) + + +def get_python_version(): + return _PY_VERSION_SHORT + + +def _print_dict(title, data): + for index, (key, value) in enumerate(sorted(data.items())): + if index == 0: + print('%s: ' % (title)) + print('\t%s = "%s"' % (key, value)) + + +def _main(): + """Display all information sysconfig detains.""" + print('Platform: "%s"' % get_platform()) + print('Python version: "%s"' % get_python_version()) + print('Current installation scheme: "%s"' % _get_default_scheme()) + print() + _print_dict('Paths', get_paths()) + print() + _print_dict('Variables', get_config_vars()) + + +if __name__ == '__main__': + _main() diff --git a/venv/Lib/site-packages/pip/_vendor/distlib/_backport/tarfile.py b/venv/Lib/site-packages/pip/_vendor/distlib/_backport/tarfile.py new file mode 100644 index 0000000..d66d856 --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/distlib/_backport/tarfile.py @@ -0,0 +1,2607 @@ +#------------------------------------------------------------------- +# tarfile.py +#------------------------------------------------------------------- +# Copyright (C) 2002 Lars Gustaebel +# All rights reserved. +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation +# files (the "Software"), to deal in the Software without +# restriction, including without limitation the rights to use, +# copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following +# conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +# OTHER DEALINGS IN THE SOFTWARE. +# +from __future__ import print_function + +"""Read from and write to tar format archives. +""" + +__version__ = "$Revision$" + +version = "0.9.0" +__author__ = "Lars Gust\u00e4bel (lars@gustaebel.de)" +__date__ = "$Date: 2011-02-25 17:42:01 +0200 (Fri, 25 Feb 2011) $" +__cvsid__ = "$Id: tarfile.py 88586 2011-02-25 15:42:01Z marc-andre.lemburg $" +__credits__ = "Gustavo Niemeyer, Niels Gust\u00e4bel, Richard Townsend." + +#--------- +# Imports +#--------- +import sys +import os +import stat +import errno +import time +import struct +import copy +import re + +try: + import grp, pwd +except ImportError: + grp = pwd = None + +# os.symlink on Windows prior to 6.0 raises NotImplementedError +symlink_exception = (AttributeError, NotImplementedError) +try: + # WindowsError (1314) will be raised if the caller does not hold the + # SeCreateSymbolicLinkPrivilege privilege + symlink_exception += (WindowsError,) +except NameError: + pass + +# from tarfile import * +__all__ = ["TarFile", "TarInfo", "is_tarfile", "TarError"] + +if sys.version_info[0] < 3: + import __builtin__ as builtins +else: + import builtins + +_open = builtins.open # Since 'open' is TarFile.open + +#--------------------------------------------------------- +# tar constants +#--------------------------------------------------------- +NUL = b"\0" # the null character +BLOCKSIZE = 512 # length of processing blocks +RECORDSIZE = BLOCKSIZE * 20 # length of records +GNU_MAGIC = b"ustar \0" # magic gnu tar string +POSIX_MAGIC = b"ustar\x0000" # magic posix tar string + +LENGTH_NAME = 100 # maximum length of a filename +LENGTH_LINK = 100 # maximum length of a linkname +LENGTH_PREFIX = 155 # maximum length of the prefix field + +REGTYPE = b"0" # regular file +AREGTYPE = b"\0" # regular file +LNKTYPE = b"1" # link (inside tarfile) +SYMTYPE = b"2" # symbolic link +CHRTYPE = b"3" # character special device +BLKTYPE = b"4" # block special device +DIRTYPE = b"5" # directory +FIFOTYPE = b"6" # fifo special device +CONTTYPE = b"7" # contiguous file + +GNUTYPE_LONGNAME = b"L" # GNU tar longname +GNUTYPE_LONGLINK = b"K" # GNU tar longlink +GNUTYPE_SPARSE = b"S" # GNU tar sparse file + +XHDTYPE = b"x" # POSIX.1-2001 extended header +XGLTYPE = b"g" # POSIX.1-2001 global header +SOLARIS_XHDTYPE = b"X" # Solaris extended header + +USTAR_FORMAT = 0 # POSIX.1-1988 (ustar) format +GNU_FORMAT = 1 # GNU tar format +PAX_FORMAT = 2 # POSIX.1-2001 (pax) format +DEFAULT_FORMAT = GNU_FORMAT + +#--------------------------------------------------------- +# tarfile constants +#--------------------------------------------------------- +# File types that tarfile supports: +SUPPORTED_TYPES = (REGTYPE, AREGTYPE, LNKTYPE, + SYMTYPE, DIRTYPE, FIFOTYPE, + CONTTYPE, CHRTYPE, BLKTYPE, + GNUTYPE_LONGNAME, GNUTYPE_LONGLINK, + GNUTYPE_SPARSE) + +# File types that will be treated as a regular file. +REGULAR_TYPES = (REGTYPE, AREGTYPE, + CONTTYPE, GNUTYPE_SPARSE) + +# File types that are part of the GNU tar format. +GNU_TYPES = (GNUTYPE_LONGNAME, GNUTYPE_LONGLINK, + GNUTYPE_SPARSE) + +# Fields from a pax header that override a TarInfo attribute. +PAX_FIELDS = ("path", "linkpath", "size", "mtime", + "uid", "gid", "uname", "gname") + +# Fields from a pax header that are affected by hdrcharset. +PAX_NAME_FIELDS = set(("path", "linkpath", "uname", "gname")) + +# Fields in a pax header that are numbers, all other fields +# are treated as strings. +PAX_NUMBER_FIELDS = { + "atime": float, + "ctime": float, + "mtime": float, + "uid": int, + "gid": int, + "size": int +} + +#--------------------------------------------------------- +# Bits used in the mode field, values in octal. +#--------------------------------------------------------- +S_IFLNK = 0o120000 # symbolic link +S_IFREG = 0o100000 # regular file +S_IFBLK = 0o060000 # block device +S_IFDIR = 0o040000 # directory +S_IFCHR = 0o020000 # character device +S_IFIFO = 0o010000 # fifo + +TSUID = 0o4000 # set UID on execution +TSGID = 0o2000 # set GID on execution +TSVTX = 0o1000 # reserved + +TUREAD = 0o400 # read by owner +TUWRITE = 0o200 # write by owner +TUEXEC = 0o100 # execute/search by owner +TGREAD = 0o040 # read by group +TGWRITE = 0o020 # write by group +TGEXEC = 0o010 # execute/search by group +TOREAD = 0o004 # read by other +TOWRITE = 0o002 # write by other +TOEXEC = 0o001 # execute/search by other + +#--------------------------------------------------------- +# initialization +#--------------------------------------------------------- +if os.name in ("nt", "ce"): + ENCODING = "utf-8" +else: + ENCODING = sys.getfilesystemencoding() + +#--------------------------------------------------------- +# Some useful functions +#--------------------------------------------------------- + +def stn(s, length, encoding, errors): + """Convert a string to a null-terminated bytes object. + """ + s = s.encode(encoding, errors) + return s[:length] + (length - len(s)) * NUL + +def nts(s, encoding, errors): + """Convert a null-terminated bytes object to a string. + """ + p = s.find(b"\0") + if p != -1: + s = s[:p] + return s.decode(encoding, errors) + +def nti(s): + """Convert a number field to a python number. + """ + # There are two possible encodings for a number field, see + # itn() below. + if s[0] != chr(0o200): + try: + n = int(nts(s, "ascii", "strict") or "0", 8) + except ValueError: + raise InvalidHeaderError("invalid header") + else: + n = 0 + for i in range(len(s) - 1): + n <<= 8 + n += ord(s[i + 1]) + return n + +def itn(n, digits=8, format=DEFAULT_FORMAT): + """Convert a python number to a number field. + """ + # POSIX 1003.1-1988 requires numbers to be encoded as a string of + # octal digits followed by a null-byte, this allows values up to + # (8**(digits-1))-1. GNU tar allows storing numbers greater than + # that if necessary. A leading 0o200 byte indicates this particular + # encoding, the following digits-1 bytes are a big-endian + # representation. This allows values up to (256**(digits-1))-1. + if 0 <= n < 8 ** (digits - 1): + s = ("%0*o" % (digits - 1, n)).encode("ascii") + NUL + else: + if format != GNU_FORMAT or n >= 256 ** (digits - 1): + raise ValueError("overflow in number field") + + if n < 0: + # XXX We mimic GNU tar's behaviour with negative numbers, + # this could raise OverflowError. + n = struct.unpack("L", struct.pack("l", n))[0] + + s = bytearray() + for i in range(digits - 1): + s.insert(0, n & 0o377) + n >>= 8 + s.insert(0, 0o200) + return s + +def calc_chksums(buf): + """Calculate the checksum for a member's header by summing up all + characters except for the chksum field which is treated as if + it was filled with spaces. According to the GNU tar sources, + some tars (Sun and NeXT) calculate chksum with signed char, + which will be different if there are chars in the buffer with + the high bit set. So we calculate two checksums, unsigned and + signed. + """ + unsigned_chksum = 256 + sum(struct.unpack("148B", buf[:148]) + struct.unpack("356B", buf[156:512])) + signed_chksum = 256 + sum(struct.unpack("148b", buf[:148]) + struct.unpack("356b", buf[156:512])) + return unsigned_chksum, signed_chksum + +def copyfileobj(src, dst, length=None): + """Copy length bytes from fileobj src to fileobj dst. + If length is None, copy the entire content. + """ + if length == 0: + return + if length is None: + while True: + buf = src.read(16*1024) + if not buf: + break + dst.write(buf) + return + + BUFSIZE = 16 * 1024 + blocks, remainder = divmod(length, BUFSIZE) + for b in range(blocks): + buf = src.read(BUFSIZE) + if len(buf) < BUFSIZE: + raise IOError("end of file reached") + dst.write(buf) + + if remainder != 0: + buf = src.read(remainder) + if len(buf) < remainder: + raise IOError("end of file reached") + dst.write(buf) + return + +filemode_table = ( + ((S_IFLNK, "l"), + (S_IFREG, "-"), + (S_IFBLK, "b"), + (S_IFDIR, "d"), + (S_IFCHR, "c"), + (S_IFIFO, "p")), + + ((TUREAD, "r"),), + ((TUWRITE, "w"),), + ((TUEXEC|TSUID, "s"), + (TSUID, "S"), + (TUEXEC, "x")), + + ((TGREAD, "r"),), + ((TGWRITE, "w"),), + ((TGEXEC|TSGID, "s"), + (TSGID, "S"), + (TGEXEC, "x")), + + ((TOREAD, "r"),), + ((TOWRITE, "w"),), + ((TOEXEC|TSVTX, "t"), + (TSVTX, "T"), + (TOEXEC, "x")) +) + +def filemode(mode): + """Convert a file's mode to a string of the form + -rwxrwxrwx. + Used by TarFile.list() + """ + perm = [] + for table in filemode_table: + for bit, char in table: + if mode & bit == bit: + perm.append(char) + break + else: + perm.append("-") + return "".join(perm) + +class TarError(Exception): + """Base exception.""" + pass +class ExtractError(TarError): + """General exception for extract errors.""" + pass +class ReadError(TarError): + """Exception for unreadable tar archives.""" + pass +class CompressionError(TarError): + """Exception for unavailable compression methods.""" + pass +class StreamError(TarError): + """Exception for unsupported operations on stream-like TarFiles.""" + pass +class HeaderError(TarError): + """Base exception for header errors.""" + pass +class EmptyHeaderError(HeaderError): + """Exception for empty headers.""" + pass +class TruncatedHeaderError(HeaderError): + """Exception for truncated headers.""" + pass +class EOFHeaderError(HeaderError): + """Exception for end of file headers.""" + pass +class InvalidHeaderError(HeaderError): + """Exception for invalid headers.""" + pass +class SubsequentHeaderError(HeaderError): + """Exception for missing and invalid extended headers.""" + pass + +#--------------------------- +# internal stream interface +#--------------------------- +class _LowLevelFile(object): + """Low-level file object. Supports reading and writing. + It is used instead of a regular file object for streaming + access. + """ + + def __init__(self, name, mode): + mode = { + "r": os.O_RDONLY, + "w": os.O_WRONLY | os.O_CREAT | os.O_TRUNC, + }[mode] + if hasattr(os, "O_BINARY"): + mode |= os.O_BINARY + self.fd = os.open(name, mode, 0o666) + + def close(self): + os.close(self.fd) + + def read(self, size): + return os.read(self.fd, size) + + def write(self, s): + os.write(self.fd, s) + +class _Stream(object): + """Class that serves as an adapter between TarFile and + a stream-like object. The stream-like object only + needs to have a read() or write() method and is accessed + blockwise. Use of gzip or bzip2 compression is possible. + A stream-like object could be for example: sys.stdin, + sys.stdout, a socket, a tape device etc. + + _Stream is intended to be used only internally. + """ + + def __init__(self, name, mode, comptype, fileobj, bufsize): + """Construct a _Stream object. + """ + self._extfileobj = True + if fileobj is None: + fileobj = _LowLevelFile(name, mode) + self._extfileobj = False + + if comptype == '*': + # Enable transparent compression detection for the + # stream interface + fileobj = _StreamProxy(fileobj) + comptype = fileobj.getcomptype() + + self.name = name or "" + self.mode = mode + self.comptype = comptype + self.fileobj = fileobj + self.bufsize = bufsize + self.buf = b"" + self.pos = 0 + self.closed = False + + try: + if comptype == "gz": + try: + import zlib + except ImportError: + raise CompressionError("zlib module is not available") + self.zlib = zlib + self.crc = zlib.crc32(b"") + if mode == "r": + self._init_read_gz() + else: + self._init_write_gz() + + if comptype == "bz2": + try: + import bz2 + except ImportError: + raise CompressionError("bz2 module is not available") + if mode == "r": + self.dbuf = b"" + self.cmp = bz2.BZ2Decompressor() + else: + self.cmp = bz2.BZ2Compressor() + except: + if not self._extfileobj: + self.fileobj.close() + self.closed = True + raise + + def __del__(self): + if hasattr(self, "closed") and not self.closed: + self.close() + + def _init_write_gz(self): + """Initialize for writing with gzip compression. + """ + self.cmp = self.zlib.compressobj(9, self.zlib.DEFLATED, + -self.zlib.MAX_WBITS, + self.zlib.DEF_MEM_LEVEL, + 0) + timestamp = struct.pack(" self.bufsize: + self.fileobj.write(self.buf[:self.bufsize]) + self.buf = self.buf[self.bufsize:] + + def close(self): + """Close the _Stream object. No operation should be + done on it afterwards. + """ + if self.closed: + return + + if self.mode == "w" and self.comptype != "tar": + self.buf += self.cmp.flush() + + if self.mode == "w" and self.buf: + self.fileobj.write(self.buf) + self.buf = b"" + if self.comptype == "gz": + # The native zlib crc is an unsigned 32-bit integer, but + # the Python wrapper implicitly casts that to a signed C + # long. So, on a 32-bit box self.crc may "look negative", + # while the same crc on a 64-bit box may "look positive". + # To avoid irksome warnings from the `struct` module, force + # it to look positive on all boxes. + self.fileobj.write(struct.pack("= 0: + blocks, remainder = divmod(pos - self.pos, self.bufsize) + for i in range(blocks): + self.read(self.bufsize) + self.read(remainder) + else: + raise StreamError("seeking backwards is not allowed") + return self.pos + + def read(self, size=None): + """Return the next size number of bytes from the stream. + If size is not defined, return all bytes of the stream + up to EOF. + """ + if size is None: + t = [] + while True: + buf = self._read(self.bufsize) + if not buf: + break + t.append(buf) + buf = "".join(t) + else: + buf = self._read(size) + self.pos += len(buf) + return buf + + def _read(self, size): + """Return size bytes from the stream. + """ + if self.comptype == "tar": + return self.__read(size) + + c = len(self.dbuf) + while c < size: + buf = self.__read(self.bufsize) + if not buf: + break + try: + buf = self.cmp.decompress(buf) + except IOError: + raise ReadError("invalid compressed data") + self.dbuf += buf + c += len(buf) + buf = self.dbuf[:size] + self.dbuf = self.dbuf[size:] + return buf + + def __read(self, size): + """Return size bytes from stream. If internal buffer is empty, + read another block from the stream. + """ + c = len(self.buf) + while c < size: + buf = self.fileobj.read(self.bufsize) + if not buf: + break + self.buf += buf + c += len(buf) + buf = self.buf[:size] + self.buf = self.buf[size:] + return buf +# class _Stream + +class _StreamProxy(object): + """Small proxy class that enables transparent compression + detection for the Stream interface (mode 'r|*'). + """ + + def __init__(self, fileobj): + self.fileobj = fileobj + self.buf = self.fileobj.read(BLOCKSIZE) + + def read(self, size): + self.read = self.fileobj.read + return self.buf + + def getcomptype(self): + if self.buf.startswith(b"\037\213\010"): + return "gz" + if self.buf.startswith(b"BZh91"): + return "bz2" + return "tar" + + def close(self): + self.fileobj.close() +# class StreamProxy + +class _BZ2Proxy(object): + """Small proxy class that enables external file object + support for "r:bz2" and "w:bz2" modes. This is actually + a workaround for a limitation in bz2 module's BZ2File + class which (unlike gzip.GzipFile) has no support for + a file object argument. + """ + + blocksize = 16 * 1024 + + def __init__(self, fileobj, mode): + self.fileobj = fileobj + self.mode = mode + self.name = getattr(self.fileobj, "name", None) + self.init() + + def init(self): + import bz2 + self.pos = 0 + if self.mode == "r": + self.bz2obj = bz2.BZ2Decompressor() + self.fileobj.seek(0) + self.buf = b"" + else: + self.bz2obj = bz2.BZ2Compressor() + + def read(self, size): + x = len(self.buf) + while x < size: + raw = self.fileobj.read(self.blocksize) + if not raw: + break + data = self.bz2obj.decompress(raw) + self.buf += data + x += len(data) + + buf = self.buf[:size] + self.buf = self.buf[size:] + self.pos += len(buf) + return buf + + def seek(self, pos): + if pos < self.pos: + self.init() + self.read(pos - self.pos) + + def tell(self): + return self.pos + + def write(self, data): + self.pos += len(data) + raw = self.bz2obj.compress(data) + self.fileobj.write(raw) + + def close(self): + if self.mode == "w": + raw = self.bz2obj.flush() + self.fileobj.write(raw) +# class _BZ2Proxy + +#------------------------ +# Extraction file object +#------------------------ +class _FileInFile(object): + """A thin wrapper around an existing file object that + provides a part of its data as an individual file + object. + """ + + def __init__(self, fileobj, offset, size, blockinfo=None): + self.fileobj = fileobj + self.offset = offset + self.size = size + self.position = 0 + + if blockinfo is None: + blockinfo = [(0, size)] + + # Construct a map with data and zero blocks. + self.map_index = 0 + self.map = [] + lastpos = 0 + realpos = self.offset + for offset, size in blockinfo: + if offset > lastpos: + self.map.append((False, lastpos, offset, None)) + self.map.append((True, offset, offset + size, realpos)) + realpos += size + lastpos = offset + size + if lastpos < self.size: + self.map.append((False, lastpos, self.size, None)) + + def seekable(self): + if not hasattr(self.fileobj, "seekable"): + # XXX gzip.GzipFile and bz2.BZ2File + return True + return self.fileobj.seekable() + + def tell(self): + """Return the current file position. + """ + return self.position + + def seek(self, position): + """Seek to a position in the file. + """ + self.position = position + + def read(self, size=None): + """Read data from the file. + """ + if size is None: + size = self.size - self.position + else: + size = min(size, self.size - self.position) + + buf = b"" + while size > 0: + while True: + data, start, stop, offset = self.map[self.map_index] + if start <= self.position < stop: + break + else: + self.map_index += 1 + if self.map_index == len(self.map): + self.map_index = 0 + length = min(size, stop - self.position) + if data: + self.fileobj.seek(offset + (self.position - start)) + buf += self.fileobj.read(length) + else: + buf += NUL * length + size -= length + self.position += length + return buf +#class _FileInFile + + +class ExFileObject(object): + """File-like object for reading an archive member. + Is returned by TarFile.extractfile(). + """ + blocksize = 1024 + + def __init__(self, tarfile, tarinfo): + self.fileobj = _FileInFile(tarfile.fileobj, + tarinfo.offset_data, + tarinfo.size, + tarinfo.sparse) + self.name = tarinfo.name + self.mode = "r" + self.closed = False + self.size = tarinfo.size + + self.position = 0 + self.buffer = b"" + + def readable(self): + return True + + def writable(self): + return False + + def seekable(self): + return self.fileobj.seekable() + + def read(self, size=None): + """Read at most size bytes from the file. If size is not + present or None, read all data until EOF is reached. + """ + if self.closed: + raise ValueError("I/O operation on closed file") + + buf = b"" + if self.buffer: + if size is None: + buf = self.buffer + self.buffer = b"" + else: + buf = self.buffer[:size] + self.buffer = self.buffer[size:] + + if size is None: + buf += self.fileobj.read() + else: + buf += self.fileobj.read(size - len(buf)) + + self.position += len(buf) + return buf + + # XXX TextIOWrapper uses the read1() method. + read1 = read + + def readline(self, size=-1): + """Read one entire line from the file. If size is present + and non-negative, return a string with at most that + size, which may be an incomplete line. + """ + if self.closed: + raise ValueError("I/O operation on closed file") + + pos = self.buffer.find(b"\n") + 1 + if pos == 0: + # no newline found. + while True: + buf = self.fileobj.read(self.blocksize) + self.buffer += buf + if not buf or b"\n" in buf: + pos = self.buffer.find(b"\n") + 1 + if pos == 0: + # no newline found. + pos = len(self.buffer) + break + + if size != -1: + pos = min(size, pos) + + buf = self.buffer[:pos] + self.buffer = self.buffer[pos:] + self.position += len(buf) + return buf + + def readlines(self): + """Return a list with all remaining lines. + """ + result = [] + while True: + line = self.readline() + if not line: break + result.append(line) + return result + + def tell(self): + """Return the current file position. + """ + if self.closed: + raise ValueError("I/O operation on closed file") + + return self.position + + def seek(self, pos, whence=os.SEEK_SET): + """Seek to a position in the file. + """ + if self.closed: + raise ValueError("I/O operation on closed file") + + if whence == os.SEEK_SET: + self.position = min(max(pos, 0), self.size) + elif whence == os.SEEK_CUR: + if pos < 0: + self.position = max(self.position + pos, 0) + else: + self.position = min(self.position + pos, self.size) + elif whence == os.SEEK_END: + self.position = max(min(self.size + pos, self.size), 0) + else: + raise ValueError("Invalid argument") + + self.buffer = b"" + self.fileobj.seek(self.position) + + def close(self): + """Close the file object. + """ + self.closed = True + + def __iter__(self): + """Get an iterator over the file's lines. + """ + while True: + line = self.readline() + if not line: + break + yield line +#class ExFileObject + +#------------------ +# Exported Classes +#------------------ +class TarInfo(object): + """Informational class which holds the details about an + archive member given by a tar header block. + TarInfo objects are returned by TarFile.getmember(), + TarFile.getmembers() and TarFile.gettarinfo() and are + usually created internally. + """ + + __slots__ = ("name", "mode", "uid", "gid", "size", "mtime", + "chksum", "type", "linkname", "uname", "gname", + "devmajor", "devminor", + "offset", "offset_data", "pax_headers", "sparse", + "tarfile", "_sparse_structs", "_link_target") + + def __init__(self, name=""): + """Construct a TarInfo object. name is the optional name + of the member. + """ + self.name = name # member name + self.mode = 0o644 # file permissions + self.uid = 0 # user id + self.gid = 0 # group id + self.size = 0 # file size + self.mtime = 0 # modification time + self.chksum = 0 # header checksum + self.type = REGTYPE # member type + self.linkname = "" # link name + self.uname = "" # user name + self.gname = "" # group name + self.devmajor = 0 # device major number + self.devminor = 0 # device minor number + + self.offset = 0 # the tar header starts here + self.offset_data = 0 # the file's data starts here + + self.sparse = None # sparse member information + self.pax_headers = {} # pax header information + + # In pax headers the "name" and "linkname" field are called + # "path" and "linkpath". + def _getpath(self): + return self.name + def _setpath(self, name): + self.name = name + path = property(_getpath, _setpath) + + def _getlinkpath(self): + return self.linkname + def _setlinkpath(self, linkname): + self.linkname = linkname + linkpath = property(_getlinkpath, _setlinkpath) + + def __repr__(self): + return "<%s %r at %#x>" % (self.__class__.__name__,self.name,id(self)) + + def get_info(self): + """Return the TarInfo's attributes as a dictionary. + """ + info = { + "name": self.name, + "mode": self.mode & 0o7777, + "uid": self.uid, + "gid": self.gid, + "size": self.size, + "mtime": self.mtime, + "chksum": self.chksum, + "type": self.type, + "linkname": self.linkname, + "uname": self.uname, + "gname": self.gname, + "devmajor": self.devmajor, + "devminor": self.devminor + } + + if info["type"] == DIRTYPE and not info["name"].endswith("/"): + info["name"] += "/" + + return info + + def tobuf(self, format=DEFAULT_FORMAT, encoding=ENCODING, errors="surrogateescape"): + """Return a tar header as a string of 512 byte blocks. + """ + info = self.get_info() + + if format == USTAR_FORMAT: + return self.create_ustar_header(info, encoding, errors) + elif format == GNU_FORMAT: + return self.create_gnu_header(info, encoding, errors) + elif format == PAX_FORMAT: + return self.create_pax_header(info, encoding) + else: + raise ValueError("invalid format") + + def create_ustar_header(self, info, encoding, errors): + """Return the object as a ustar header block. + """ + info["magic"] = POSIX_MAGIC + + if len(info["linkname"]) > LENGTH_LINK: + raise ValueError("linkname is too long") + + if len(info["name"]) > LENGTH_NAME: + info["prefix"], info["name"] = self._posix_split_name(info["name"]) + + return self._create_header(info, USTAR_FORMAT, encoding, errors) + + def create_gnu_header(self, info, encoding, errors): + """Return the object as a GNU header block sequence. + """ + info["magic"] = GNU_MAGIC + + buf = b"" + if len(info["linkname"]) > LENGTH_LINK: + buf += self._create_gnu_long_header(info["linkname"], GNUTYPE_LONGLINK, encoding, errors) + + if len(info["name"]) > LENGTH_NAME: + buf += self._create_gnu_long_header(info["name"], GNUTYPE_LONGNAME, encoding, errors) + + return buf + self._create_header(info, GNU_FORMAT, encoding, errors) + + def create_pax_header(self, info, encoding): + """Return the object as a ustar header block. If it cannot be + represented this way, prepend a pax extended header sequence + with supplement information. + """ + info["magic"] = POSIX_MAGIC + pax_headers = self.pax_headers.copy() + + # Test string fields for values that exceed the field length or cannot + # be represented in ASCII encoding. + for name, hname, length in ( + ("name", "path", LENGTH_NAME), ("linkname", "linkpath", LENGTH_LINK), + ("uname", "uname", 32), ("gname", "gname", 32)): + + if hname in pax_headers: + # The pax header has priority. + continue + + # Try to encode the string as ASCII. + try: + info[name].encode("ascii", "strict") + except UnicodeEncodeError: + pax_headers[hname] = info[name] + continue + + if len(info[name]) > length: + pax_headers[hname] = info[name] + + # Test number fields for values that exceed the field limit or values + # that like to be stored as float. + for name, digits in (("uid", 8), ("gid", 8), ("size", 12), ("mtime", 12)): + if name in pax_headers: + # The pax header has priority. Avoid overflow. + info[name] = 0 + continue + + val = info[name] + if not 0 <= val < 8 ** (digits - 1) or isinstance(val, float): + pax_headers[name] = str(val) + info[name] = 0 + + # Create a pax extended header if necessary. + if pax_headers: + buf = self._create_pax_generic_header(pax_headers, XHDTYPE, encoding) + else: + buf = b"" + + return buf + self._create_header(info, USTAR_FORMAT, "ascii", "replace") + + @classmethod + def create_pax_global_header(cls, pax_headers): + """Return the object as a pax global header block sequence. + """ + return cls._create_pax_generic_header(pax_headers, XGLTYPE, "utf8") + + def _posix_split_name(self, name): + """Split a name longer than 100 chars into a prefix + and a name part. + """ + prefix = name[:LENGTH_PREFIX + 1] + while prefix and prefix[-1] != "/": + prefix = prefix[:-1] + + name = name[len(prefix):] + prefix = prefix[:-1] + + if not prefix or len(name) > LENGTH_NAME: + raise ValueError("name is too long") + return prefix, name + + @staticmethod + def _create_header(info, format, encoding, errors): + """Return a header block. info is a dictionary with file + information, format must be one of the *_FORMAT constants. + """ + parts = [ + stn(info.get("name", ""), 100, encoding, errors), + itn(info.get("mode", 0) & 0o7777, 8, format), + itn(info.get("uid", 0), 8, format), + itn(info.get("gid", 0), 8, format), + itn(info.get("size", 0), 12, format), + itn(info.get("mtime", 0), 12, format), + b" ", # checksum field + info.get("type", REGTYPE), + stn(info.get("linkname", ""), 100, encoding, errors), + info.get("magic", POSIX_MAGIC), + stn(info.get("uname", ""), 32, encoding, errors), + stn(info.get("gname", ""), 32, encoding, errors), + itn(info.get("devmajor", 0), 8, format), + itn(info.get("devminor", 0), 8, format), + stn(info.get("prefix", ""), 155, encoding, errors) + ] + + buf = struct.pack("%ds" % BLOCKSIZE, b"".join(parts)) + chksum = calc_chksums(buf[-BLOCKSIZE:])[0] + buf = buf[:-364] + ("%06o\0" % chksum).encode("ascii") + buf[-357:] + return buf + + @staticmethod + def _create_payload(payload): + """Return the string payload filled with zero bytes + up to the next 512 byte border. + """ + blocks, remainder = divmod(len(payload), BLOCKSIZE) + if remainder > 0: + payload += (BLOCKSIZE - remainder) * NUL + return payload + + @classmethod + def _create_gnu_long_header(cls, name, type, encoding, errors): + """Return a GNUTYPE_LONGNAME or GNUTYPE_LONGLINK sequence + for name. + """ + name = name.encode(encoding, errors) + NUL + + info = {} + info["name"] = "././@LongLink" + info["type"] = type + info["size"] = len(name) + info["magic"] = GNU_MAGIC + + # create extended header + name blocks. + return cls._create_header(info, USTAR_FORMAT, encoding, errors) + \ + cls._create_payload(name) + + @classmethod + def _create_pax_generic_header(cls, pax_headers, type, encoding): + """Return a POSIX.1-2008 extended or global header sequence + that contains a list of keyword, value pairs. The values + must be strings. + """ + # Check if one of the fields contains surrogate characters and thereby + # forces hdrcharset=BINARY, see _proc_pax() for more information. + binary = False + for keyword, value in pax_headers.items(): + try: + value.encode("utf8", "strict") + except UnicodeEncodeError: + binary = True + break + + records = b"" + if binary: + # Put the hdrcharset field at the beginning of the header. + records += b"21 hdrcharset=BINARY\n" + + for keyword, value in pax_headers.items(): + keyword = keyword.encode("utf8") + if binary: + # Try to restore the original byte representation of `value'. + # Needless to say, that the encoding must match the string. + value = value.encode(encoding, "surrogateescape") + else: + value = value.encode("utf8") + + l = len(keyword) + len(value) + 3 # ' ' + '=' + '\n' + n = p = 0 + while True: + n = l + len(str(p)) + if n == p: + break + p = n + records += bytes(str(p), "ascii") + b" " + keyword + b"=" + value + b"\n" + + # We use a hardcoded "././@PaxHeader" name like star does + # instead of the one that POSIX recommends. + info = {} + info["name"] = "././@PaxHeader" + info["type"] = type + info["size"] = len(records) + info["magic"] = POSIX_MAGIC + + # Create pax header + record blocks. + return cls._create_header(info, USTAR_FORMAT, "ascii", "replace") + \ + cls._create_payload(records) + + @classmethod + def frombuf(cls, buf, encoding, errors): + """Construct a TarInfo object from a 512 byte bytes object. + """ + if len(buf) == 0: + raise EmptyHeaderError("empty header") + if len(buf) != BLOCKSIZE: + raise TruncatedHeaderError("truncated header") + if buf.count(NUL) == BLOCKSIZE: + raise EOFHeaderError("end of file header") + + chksum = nti(buf[148:156]) + if chksum not in calc_chksums(buf): + raise InvalidHeaderError("bad checksum") + + obj = cls() + obj.name = nts(buf[0:100], encoding, errors) + obj.mode = nti(buf[100:108]) + obj.uid = nti(buf[108:116]) + obj.gid = nti(buf[116:124]) + obj.size = nti(buf[124:136]) + obj.mtime = nti(buf[136:148]) + obj.chksum = chksum + obj.type = buf[156:157] + obj.linkname = nts(buf[157:257], encoding, errors) + obj.uname = nts(buf[265:297], encoding, errors) + obj.gname = nts(buf[297:329], encoding, errors) + obj.devmajor = nti(buf[329:337]) + obj.devminor = nti(buf[337:345]) + prefix = nts(buf[345:500], encoding, errors) + + # Old V7 tar format represents a directory as a regular + # file with a trailing slash. + if obj.type == AREGTYPE and obj.name.endswith("/"): + obj.type = DIRTYPE + + # The old GNU sparse format occupies some of the unused + # space in the buffer for up to 4 sparse structures. + # Save the them for later processing in _proc_sparse(). + if obj.type == GNUTYPE_SPARSE: + pos = 386 + structs = [] + for i in range(4): + try: + offset = nti(buf[pos:pos + 12]) + numbytes = nti(buf[pos + 12:pos + 24]) + except ValueError: + break + structs.append((offset, numbytes)) + pos += 24 + isextended = bool(buf[482]) + origsize = nti(buf[483:495]) + obj._sparse_structs = (structs, isextended, origsize) + + # Remove redundant slashes from directories. + if obj.isdir(): + obj.name = obj.name.rstrip("/") + + # Reconstruct a ustar longname. + if prefix and obj.type not in GNU_TYPES: + obj.name = prefix + "/" + obj.name + return obj + + @classmethod + def fromtarfile(cls, tarfile): + """Return the next TarInfo object from TarFile object + tarfile. + """ + buf = tarfile.fileobj.read(BLOCKSIZE) + obj = cls.frombuf(buf, tarfile.encoding, tarfile.errors) + obj.offset = tarfile.fileobj.tell() - BLOCKSIZE + return obj._proc_member(tarfile) + + #-------------------------------------------------------------------------- + # The following are methods that are called depending on the type of a + # member. The entry point is _proc_member() which can be overridden in a + # subclass to add custom _proc_*() methods. A _proc_*() method MUST + # implement the following + # operations: + # 1. Set self.offset_data to the position where the data blocks begin, + # if there is data that follows. + # 2. Set tarfile.offset to the position where the next member's header will + # begin. + # 3. Return self or another valid TarInfo object. + def _proc_member(self, tarfile): + """Choose the right processing method depending on + the type and call it. + """ + if self.type in (GNUTYPE_LONGNAME, GNUTYPE_LONGLINK): + return self._proc_gnulong(tarfile) + elif self.type == GNUTYPE_SPARSE: + return self._proc_sparse(tarfile) + elif self.type in (XHDTYPE, XGLTYPE, SOLARIS_XHDTYPE): + return self._proc_pax(tarfile) + else: + return self._proc_builtin(tarfile) + + def _proc_builtin(self, tarfile): + """Process a builtin type or an unknown type which + will be treated as a regular file. + """ + self.offset_data = tarfile.fileobj.tell() + offset = self.offset_data + if self.isreg() or self.type not in SUPPORTED_TYPES: + # Skip the following data blocks. + offset += self._block(self.size) + tarfile.offset = offset + + # Patch the TarInfo object with saved global + # header information. + self._apply_pax_info(tarfile.pax_headers, tarfile.encoding, tarfile.errors) + + return self + + def _proc_gnulong(self, tarfile): + """Process the blocks that hold a GNU longname + or longlink member. + """ + buf = tarfile.fileobj.read(self._block(self.size)) + + # Fetch the next header and process it. + try: + next = self.fromtarfile(tarfile) + except HeaderError: + raise SubsequentHeaderError("missing or bad subsequent header") + + # Patch the TarInfo object from the next header with + # the longname information. + next.offset = self.offset + if self.type == GNUTYPE_LONGNAME: + next.name = nts(buf, tarfile.encoding, tarfile.errors) + elif self.type == GNUTYPE_LONGLINK: + next.linkname = nts(buf, tarfile.encoding, tarfile.errors) + + return next + + def _proc_sparse(self, tarfile): + """Process a GNU sparse header plus extra headers. + """ + # We already collected some sparse structures in frombuf(). + structs, isextended, origsize = self._sparse_structs + del self._sparse_structs + + # Collect sparse structures from extended header blocks. + while isextended: + buf = tarfile.fileobj.read(BLOCKSIZE) + pos = 0 + for i in range(21): + try: + offset = nti(buf[pos:pos + 12]) + numbytes = nti(buf[pos + 12:pos + 24]) + except ValueError: + break + if offset and numbytes: + structs.append((offset, numbytes)) + pos += 24 + isextended = bool(buf[504]) + self.sparse = structs + + self.offset_data = tarfile.fileobj.tell() + tarfile.offset = self.offset_data + self._block(self.size) + self.size = origsize + return self + + def _proc_pax(self, tarfile): + """Process an extended or global header as described in + POSIX.1-2008. + """ + # Read the header information. + buf = tarfile.fileobj.read(self._block(self.size)) + + # A pax header stores supplemental information for either + # the following file (extended) or all following files + # (global). + if self.type == XGLTYPE: + pax_headers = tarfile.pax_headers + else: + pax_headers = tarfile.pax_headers.copy() + + # Check if the pax header contains a hdrcharset field. This tells us + # the encoding of the path, linkpath, uname and gname fields. Normally, + # these fields are UTF-8 encoded but since POSIX.1-2008 tar + # implementations are allowed to store them as raw binary strings if + # the translation to UTF-8 fails. + match = re.search(br"\d+ hdrcharset=([^\n]+)\n", buf) + if match is not None: + pax_headers["hdrcharset"] = match.group(1).decode("utf8") + + # For the time being, we don't care about anything other than "BINARY". + # The only other value that is currently allowed by the standard is + # "ISO-IR 10646 2000 UTF-8" in other words UTF-8. + hdrcharset = pax_headers.get("hdrcharset") + if hdrcharset == "BINARY": + encoding = tarfile.encoding + else: + encoding = "utf8" + + # Parse pax header information. A record looks like that: + # "%d %s=%s\n" % (length, keyword, value). length is the size + # of the complete record including the length field itself and + # the newline. keyword and value are both UTF-8 encoded strings. + regex = re.compile(br"(\d+) ([^=]+)=") + pos = 0 + while True: + match = regex.match(buf, pos) + if not match: + break + + length, keyword = match.groups() + length = int(length) + value = buf[match.end(2) + 1:match.start(1) + length - 1] + + # Normally, we could just use "utf8" as the encoding and "strict" + # as the error handler, but we better not take the risk. For + # example, GNU tar <= 1.23 is known to store filenames it cannot + # translate to UTF-8 as raw strings (unfortunately without a + # hdrcharset=BINARY header). + # We first try the strict standard encoding, and if that fails we + # fall back on the user's encoding and error handler. + keyword = self._decode_pax_field(keyword, "utf8", "utf8", + tarfile.errors) + if keyword in PAX_NAME_FIELDS: + value = self._decode_pax_field(value, encoding, tarfile.encoding, + tarfile.errors) + else: + value = self._decode_pax_field(value, "utf8", "utf8", + tarfile.errors) + + pax_headers[keyword] = value + pos += length + + # Fetch the next header. + try: + next = self.fromtarfile(tarfile) + except HeaderError: + raise SubsequentHeaderError("missing or bad subsequent header") + + # Process GNU sparse information. + if "GNU.sparse.map" in pax_headers: + # GNU extended sparse format version 0.1. + self._proc_gnusparse_01(next, pax_headers) + + elif "GNU.sparse.size" in pax_headers: + # GNU extended sparse format version 0.0. + self._proc_gnusparse_00(next, pax_headers, buf) + + elif pax_headers.get("GNU.sparse.major") == "1" and pax_headers.get("GNU.sparse.minor") == "0": + # GNU extended sparse format version 1.0. + self._proc_gnusparse_10(next, pax_headers, tarfile) + + if self.type in (XHDTYPE, SOLARIS_XHDTYPE): + # Patch the TarInfo object with the extended header info. + next._apply_pax_info(pax_headers, tarfile.encoding, tarfile.errors) + next.offset = self.offset + + if "size" in pax_headers: + # If the extended header replaces the size field, + # we need to recalculate the offset where the next + # header starts. + offset = next.offset_data + if next.isreg() or next.type not in SUPPORTED_TYPES: + offset += next._block(next.size) + tarfile.offset = offset + + return next + + def _proc_gnusparse_00(self, next, pax_headers, buf): + """Process a GNU tar extended sparse header, version 0.0. + """ + offsets = [] + for match in re.finditer(br"\d+ GNU.sparse.offset=(\d+)\n", buf): + offsets.append(int(match.group(1))) + numbytes = [] + for match in re.finditer(br"\d+ GNU.sparse.numbytes=(\d+)\n", buf): + numbytes.append(int(match.group(1))) + next.sparse = list(zip(offsets, numbytes)) + + def _proc_gnusparse_01(self, next, pax_headers): + """Process a GNU tar extended sparse header, version 0.1. + """ + sparse = [int(x) for x in pax_headers["GNU.sparse.map"].split(",")] + next.sparse = list(zip(sparse[::2], sparse[1::2])) + + def _proc_gnusparse_10(self, next, pax_headers, tarfile): + """Process a GNU tar extended sparse header, version 1.0. + """ + fields = None + sparse = [] + buf = tarfile.fileobj.read(BLOCKSIZE) + fields, buf = buf.split(b"\n", 1) + fields = int(fields) + while len(sparse) < fields * 2: + if b"\n" not in buf: + buf += tarfile.fileobj.read(BLOCKSIZE) + number, buf = buf.split(b"\n", 1) + sparse.append(int(number)) + next.offset_data = tarfile.fileobj.tell() + next.sparse = list(zip(sparse[::2], sparse[1::2])) + + def _apply_pax_info(self, pax_headers, encoding, errors): + """Replace fields with supplemental information from a previous + pax extended or global header. + """ + for keyword, value in pax_headers.items(): + if keyword == "GNU.sparse.name": + setattr(self, "path", value) + elif keyword == "GNU.sparse.size": + setattr(self, "size", int(value)) + elif keyword == "GNU.sparse.realsize": + setattr(self, "size", int(value)) + elif keyword in PAX_FIELDS: + if keyword in PAX_NUMBER_FIELDS: + try: + value = PAX_NUMBER_FIELDS[keyword](value) + except ValueError: + value = 0 + if keyword == "path": + value = value.rstrip("/") + setattr(self, keyword, value) + + self.pax_headers = pax_headers.copy() + + def _decode_pax_field(self, value, encoding, fallback_encoding, fallback_errors): + """Decode a single field from a pax record. + """ + try: + return value.decode(encoding, "strict") + except UnicodeDecodeError: + return value.decode(fallback_encoding, fallback_errors) + + def _block(self, count): + """Round up a byte count by BLOCKSIZE and return it, + e.g. _block(834) => 1024. + """ + blocks, remainder = divmod(count, BLOCKSIZE) + if remainder: + blocks += 1 + return blocks * BLOCKSIZE + + def isreg(self): + return self.type in REGULAR_TYPES + def isfile(self): + return self.isreg() + def isdir(self): + return self.type == DIRTYPE + def issym(self): + return self.type == SYMTYPE + def islnk(self): + return self.type == LNKTYPE + def ischr(self): + return self.type == CHRTYPE + def isblk(self): + return self.type == BLKTYPE + def isfifo(self): + return self.type == FIFOTYPE + def issparse(self): + return self.sparse is not None + def isdev(self): + return self.type in (CHRTYPE, BLKTYPE, FIFOTYPE) +# class TarInfo + +class TarFile(object): + """The TarFile Class provides an interface to tar archives. + """ + + debug = 0 # May be set from 0 (no msgs) to 3 (all msgs) + + dereference = False # If true, add content of linked file to the + # tar file, else the link. + + ignore_zeros = False # If true, skips empty or invalid blocks and + # continues processing. + + errorlevel = 1 # If 0, fatal errors only appear in debug + # messages (if debug >= 0). If > 0, errors + # are passed to the caller as exceptions. + + format = DEFAULT_FORMAT # The format to use when creating an archive. + + encoding = ENCODING # Encoding for 8-bit character strings. + + errors = None # Error handler for unicode conversion. + + tarinfo = TarInfo # The default TarInfo class to use. + + fileobject = ExFileObject # The default ExFileObject class to use. + + def __init__(self, name=None, mode="r", fileobj=None, format=None, + tarinfo=None, dereference=None, ignore_zeros=None, encoding=None, + errors="surrogateescape", pax_headers=None, debug=None, errorlevel=None): + """Open an (uncompressed) tar archive `name'. `mode' is either 'r' to + read from an existing archive, 'a' to append data to an existing + file or 'w' to create a new file overwriting an existing one. `mode' + defaults to 'r'. + If `fileobj' is given, it is used for reading or writing data. If it + can be determined, `mode' is overridden by `fileobj's mode. + `fileobj' is not closed, when TarFile is closed. + """ + if len(mode) > 1 or mode not in "raw": + raise ValueError("mode must be 'r', 'a' or 'w'") + self.mode = mode + self._mode = {"r": "rb", "a": "r+b", "w": "wb"}[mode] + + if not fileobj: + if self.mode == "a" and not os.path.exists(name): + # Create nonexistent files in append mode. + self.mode = "w" + self._mode = "wb" + fileobj = bltn_open(name, self._mode) + self._extfileobj = False + else: + if name is None and hasattr(fileobj, "name"): + name = fileobj.name + if hasattr(fileobj, "mode"): + self._mode = fileobj.mode + self._extfileobj = True + self.name = os.path.abspath(name) if name else None + self.fileobj = fileobj + + # Init attributes. + if format is not None: + self.format = format + if tarinfo is not None: + self.tarinfo = tarinfo + if dereference is not None: + self.dereference = dereference + if ignore_zeros is not None: + self.ignore_zeros = ignore_zeros + if encoding is not None: + self.encoding = encoding + self.errors = errors + + if pax_headers is not None and self.format == PAX_FORMAT: + self.pax_headers = pax_headers + else: + self.pax_headers = {} + + if debug is not None: + self.debug = debug + if errorlevel is not None: + self.errorlevel = errorlevel + + # Init datastructures. + self.closed = False + self.members = [] # list of members as TarInfo objects + self._loaded = False # flag if all members have been read + self.offset = self.fileobj.tell() + # current position in the archive file + self.inodes = {} # dictionary caching the inodes of + # archive members already added + + try: + if self.mode == "r": + self.firstmember = None + self.firstmember = self.next() + + if self.mode == "a": + # Move to the end of the archive, + # before the first empty block. + while True: + self.fileobj.seek(self.offset) + try: + tarinfo = self.tarinfo.fromtarfile(self) + self.members.append(tarinfo) + except EOFHeaderError: + self.fileobj.seek(self.offset) + break + except HeaderError as e: + raise ReadError(str(e)) + + if self.mode in "aw": + self._loaded = True + + if self.pax_headers: + buf = self.tarinfo.create_pax_global_header(self.pax_headers.copy()) + self.fileobj.write(buf) + self.offset += len(buf) + except: + if not self._extfileobj: + self.fileobj.close() + self.closed = True + raise + + #-------------------------------------------------------------------------- + # Below are the classmethods which act as alternate constructors to the + # TarFile class. The open() method is the only one that is needed for + # public use; it is the "super"-constructor and is able to select an + # adequate "sub"-constructor for a particular compression using the mapping + # from OPEN_METH. + # + # This concept allows one to subclass TarFile without losing the comfort of + # the super-constructor. A sub-constructor is registered and made available + # by adding it to the mapping in OPEN_METH. + + @classmethod + def open(cls, name=None, mode="r", fileobj=None, bufsize=RECORDSIZE, **kwargs): + """Open a tar archive for reading, writing or appending. Return + an appropriate TarFile class. + + mode: + 'r' or 'r:*' open for reading with transparent compression + 'r:' open for reading exclusively uncompressed + 'r:gz' open for reading with gzip compression + 'r:bz2' open for reading with bzip2 compression + 'a' or 'a:' open for appending, creating the file if necessary + 'w' or 'w:' open for writing without compression + 'w:gz' open for writing with gzip compression + 'w:bz2' open for writing with bzip2 compression + + 'r|*' open a stream of tar blocks with transparent compression + 'r|' open an uncompressed stream of tar blocks for reading + 'r|gz' open a gzip compressed stream of tar blocks + 'r|bz2' open a bzip2 compressed stream of tar blocks + 'w|' open an uncompressed stream for writing + 'w|gz' open a gzip compressed stream for writing + 'w|bz2' open a bzip2 compressed stream for writing + """ + + if not name and not fileobj: + raise ValueError("nothing to open") + + if mode in ("r", "r:*"): + # Find out which *open() is appropriate for opening the file. + for comptype in cls.OPEN_METH: + func = getattr(cls, cls.OPEN_METH[comptype]) + if fileobj is not None: + saved_pos = fileobj.tell() + try: + return func(name, "r", fileobj, **kwargs) + except (ReadError, CompressionError) as e: + if fileobj is not None: + fileobj.seek(saved_pos) + continue + raise ReadError("file could not be opened successfully") + + elif ":" in mode: + filemode, comptype = mode.split(":", 1) + filemode = filemode or "r" + comptype = comptype or "tar" + + # Select the *open() function according to + # given compression. + if comptype in cls.OPEN_METH: + func = getattr(cls, cls.OPEN_METH[comptype]) + else: + raise CompressionError("unknown compression type %r" % comptype) + return func(name, filemode, fileobj, **kwargs) + + elif "|" in mode: + filemode, comptype = mode.split("|", 1) + filemode = filemode or "r" + comptype = comptype or "tar" + + if filemode not in "rw": + raise ValueError("mode must be 'r' or 'w'") + + stream = _Stream(name, filemode, comptype, fileobj, bufsize) + try: + t = cls(name, filemode, stream, **kwargs) + except: + stream.close() + raise + t._extfileobj = False + return t + + elif mode in "aw": + return cls.taropen(name, mode, fileobj, **kwargs) + + raise ValueError("undiscernible mode") + + @classmethod + def taropen(cls, name, mode="r", fileobj=None, **kwargs): + """Open uncompressed tar archive name for reading or writing. + """ + if len(mode) > 1 or mode not in "raw": + raise ValueError("mode must be 'r', 'a' or 'w'") + return cls(name, mode, fileobj, **kwargs) + + @classmethod + def gzopen(cls, name, mode="r", fileobj=None, compresslevel=9, **kwargs): + """Open gzip compressed tar archive name for reading or writing. + Appending is not allowed. + """ + if len(mode) > 1 or mode not in "rw": + raise ValueError("mode must be 'r' or 'w'") + + try: + import gzip + gzip.GzipFile + except (ImportError, AttributeError): + raise CompressionError("gzip module is not available") + + extfileobj = fileobj is not None + try: + fileobj = gzip.GzipFile(name, mode + "b", compresslevel, fileobj) + t = cls.taropen(name, mode, fileobj, **kwargs) + except IOError: + if not extfileobj and fileobj is not None: + fileobj.close() + if fileobj is None: + raise + raise ReadError("not a gzip file") + except: + if not extfileobj and fileobj is not None: + fileobj.close() + raise + t._extfileobj = extfileobj + return t + + @classmethod + def bz2open(cls, name, mode="r", fileobj=None, compresslevel=9, **kwargs): + """Open bzip2 compressed tar archive name for reading or writing. + Appending is not allowed. + """ + if len(mode) > 1 or mode not in "rw": + raise ValueError("mode must be 'r' or 'w'.") + + try: + import bz2 + except ImportError: + raise CompressionError("bz2 module is not available") + + if fileobj is not None: + fileobj = _BZ2Proxy(fileobj, mode) + else: + fileobj = bz2.BZ2File(name, mode, compresslevel=compresslevel) + + try: + t = cls.taropen(name, mode, fileobj, **kwargs) + except (IOError, EOFError): + fileobj.close() + raise ReadError("not a bzip2 file") + t._extfileobj = False + return t + + # All *open() methods are registered here. + OPEN_METH = { + "tar": "taropen", # uncompressed tar + "gz": "gzopen", # gzip compressed tar + "bz2": "bz2open" # bzip2 compressed tar + } + + #-------------------------------------------------------------------------- + # The public methods which TarFile provides: + + def close(self): + """Close the TarFile. In write-mode, two finishing zero blocks are + appended to the archive. + """ + if self.closed: + return + + if self.mode in "aw": + self.fileobj.write(NUL * (BLOCKSIZE * 2)) + self.offset += (BLOCKSIZE * 2) + # fill up the end with zero-blocks + # (like option -b20 for tar does) + blocks, remainder = divmod(self.offset, RECORDSIZE) + if remainder > 0: + self.fileobj.write(NUL * (RECORDSIZE - remainder)) + + if not self._extfileobj: + self.fileobj.close() + self.closed = True + + def getmember(self, name): + """Return a TarInfo object for member `name'. If `name' can not be + found in the archive, KeyError is raised. If a member occurs more + than once in the archive, its last occurrence is assumed to be the + most up-to-date version. + """ + tarinfo = self._getmember(name) + if tarinfo is None: + raise KeyError("filename %r not found" % name) + return tarinfo + + def getmembers(self): + """Return the members of the archive as a list of TarInfo objects. The + list has the same order as the members in the archive. + """ + self._check() + if not self._loaded: # if we want to obtain a list of + self._load() # all members, we first have to + # scan the whole archive. + return self.members + + def getnames(self): + """Return the members of the archive as a list of their names. It has + the same order as the list returned by getmembers(). + """ + return [tarinfo.name for tarinfo in self.getmembers()] + + def gettarinfo(self, name=None, arcname=None, fileobj=None): + """Create a TarInfo object for either the file `name' or the file + object `fileobj' (using os.fstat on its file descriptor). You can + modify some of the TarInfo's attributes before you add it using + addfile(). If given, `arcname' specifies an alternative name for the + file in the archive. + """ + self._check("aw") + + # When fileobj is given, replace name by + # fileobj's real name. + if fileobj is not None: + name = fileobj.name + + # Building the name of the member in the archive. + # Backward slashes are converted to forward slashes, + # Absolute paths are turned to relative paths. + if arcname is None: + arcname = name + drv, arcname = os.path.splitdrive(arcname) + arcname = arcname.replace(os.sep, "/") + arcname = arcname.lstrip("/") + + # Now, fill the TarInfo object with + # information specific for the file. + tarinfo = self.tarinfo() + tarinfo.tarfile = self + + # Use os.stat or os.lstat, depending on platform + # and if symlinks shall be resolved. + if fileobj is None: + if hasattr(os, "lstat") and not self.dereference: + statres = os.lstat(name) + else: + statres = os.stat(name) + else: + statres = os.fstat(fileobj.fileno()) + linkname = "" + + stmd = statres.st_mode + if stat.S_ISREG(stmd): + inode = (statres.st_ino, statres.st_dev) + if not self.dereference and statres.st_nlink > 1 and \ + inode in self.inodes and arcname != self.inodes[inode]: + # Is it a hardlink to an already + # archived file? + type = LNKTYPE + linkname = self.inodes[inode] + else: + # The inode is added only if its valid. + # For win32 it is always 0. + type = REGTYPE + if inode[0]: + self.inodes[inode] = arcname + elif stat.S_ISDIR(stmd): + type = DIRTYPE + elif stat.S_ISFIFO(stmd): + type = FIFOTYPE + elif stat.S_ISLNK(stmd): + type = SYMTYPE + linkname = os.readlink(name) + elif stat.S_ISCHR(stmd): + type = CHRTYPE + elif stat.S_ISBLK(stmd): + type = BLKTYPE + else: + return None + + # Fill the TarInfo object with all + # information we can get. + tarinfo.name = arcname + tarinfo.mode = stmd + tarinfo.uid = statres.st_uid + tarinfo.gid = statres.st_gid + if type == REGTYPE: + tarinfo.size = statres.st_size + else: + tarinfo.size = 0 + tarinfo.mtime = statres.st_mtime + tarinfo.type = type + tarinfo.linkname = linkname + if pwd: + try: + tarinfo.uname = pwd.getpwuid(tarinfo.uid)[0] + except KeyError: + pass + if grp: + try: + tarinfo.gname = grp.getgrgid(tarinfo.gid)[0] + except KeyError: + pass + + if type in (CHRTYPE, BLKTYPE): + if hasattr(os, "major") and hasattr(os, "minor"): + tarinfo.devmajor = os.major(statres.st_rdev) + tarinfo.devminor = os.minor(statres.st_rdev) + return tarinfo + + def list(self, verbose=True): + """Print a table of contents to sys.stdout. If `verbose' is False, only + the names of the members are printed. If it is True, an `ls -l'-like + output is produced. + """ + self._check() + + for tarinfo in self: + if verbose: + print(filemode(tarinfo.mode), end=' ') + print("%s/%s" % (tarinfo.uname or tarinfo.uid, + tarinfo.gname or tarinfo.gid), end=' ') + if tarinfo.ischr() or tarinfo.isblk(): + print("%10s" % ("%d,%d" \ + % (tarinfo.devmajor, tarinfo.devminor)), end=' ') + else: + print("%10d" % tarinfo.size, end=' ') + print("%d-%02d-%02d %02d:%02d:%02d" \ + % time.localtime(tarinfo.mtime)[:6], end=' ') + + print(tarinfo.name + ("/" if tarinfo.isdir() else ""), end=' ') + + if verbose: + if tarinfo.issym(): + print("->", tarinfo.linkname, end=' ') + if tarinfo.islnk(): + print("link to", tarinfo.linkname, end=' ') + print() + + def add(self, name, arcname=None, recursive=True, exclude=None, filter=None): + """Add the file `name' to the archive. `name' may be any type of file + (directory, fifo, symbolic link, etc.). If given, `arcname' + specifies an alternative name for the file in the archive. + Directories are added recursively by default. This can be avoided by + setting `recursive' to False. `exclude' is a function that should + return True for each filename to be excluded. `filter' is a function + that expects a TarInfo object argument and returns the changed + TarInfo object, if it returns None the TarInfo object will be + excluded from the archive. + """ + self._check("aw") + + if arcname is None: + arcname = name + + # Exclude pathnames. + if exclude is not None: + import warnings + warnings.warn("use the filter argument instead", + DeprecationWarning, 2) + if exclude(name): + self._dbg(2, "tarfile: Excluded %r" % name) + return + + # Skip if somebody tries to archive the archive... + if self.name is not None and os.path.abspath(name) == self.name: + self._dbg(2, "tarfile: Skipped %r" % name) + return + + self._dbg(1, name) + + # Create a TarInfo object from the file. + tarinfo = self.gettarinfo(name, arcname) + + if tarinfo is None: + self._dbg(1, "tarfile: Unsupported type %r" % name) + return + + # Change or exclude the TarInfo object. + if filter is not None: + tarinfo = filter(tarinfo) + if tarinfo is None: + self._dbg(2, "tarfile: Excluded %r" % name) + return + + # Append the tar header and data to the archive. + if tarinfo.isreg(): + f = bltn_open(name, "rb") + self.addfile(tarinfo, f) + f.close() + + elif tarinfo.isdir(): + self.addfile(tarinfo) + if recursive: + for f in os.listdir(name): + self.add(os.path.join(name, f), os.path.join(arcname, f), + recursive, exclude, filter=filter) + + else: + self.addfile(tarinfo) + + def addfile(self, tarinfo, fileobj=None): + """Add the TarInfo object `tarinfo' to the archive. If `fileobj' is + given, tarinfo.size bytes are read from it and added to the archive. + You can create TarInfo objects using gettarinfo(). + On Windows platforms, `fileobj' should always be opened with mode + 'rb' to avoid irritation about the file size. + """ + self._check("aw") + + tarinfo = copy.copy(tarinfo) + + buf = tarinfo.tobuf(self.format, self.encoding, self.errors) + self.fileobj.write(buf) + self.offset += len(buf) + + # If there's data to follow, append it. + if fileobj is not None: + copyfileobj(fileobj, self.fileobj, tarinfo.size) + blocks, remainder = divmod(tarinfo.size, BLOCKSIZE) + if remainder > 0: + self.fileobj.write(NUL * (BLOCKSIZE - remainder)) + blocks += 1 + self.offset += blocks * BLOCKSIZE + + self.members.append(tarinfo) + + def extractall(self, path=".", members=None): + """Extract all members from the archive to the current working + directory and set owner, modification time and permissions on + directories afterwards. `path' specifies a different directory + to extract to. `members' is optional and must be a subset of the + list returned by getmembers(). + """ + directories = [] + + if members is None: + members = self + + for tarinfo in members: + if tarinfo.isdir(): + # Extract directories with a safe mode. + directories.append(tarinfo) + tarinfo = copy.copy(tarinfo) + tarinfo.mode = 0o700 + # Do not set_attrs directories, as we will do that further down + self.extract(tarinfo, path, set_attrs=not tarinfo.isdir()) + + # Reverse sort directories. + directories.sort(key=lambda a: a.name) + directories.reverse() + + # Set correct owner, mtime and filemode on directories. + for tarinfo in directories: + dirpath = os.path.join(path, tarinfo.name) + try: + self.chown(tarinfo, dirpath) + self.utime(tarinfo, dirpath) + self.chmod(tarinfo, dirpath) + except ExtractError as e: + if self.errorlevel > 1: + raise + else: + self._dbg(1, "tarfile: %s" % e) + + def extract(self, member, path="", set_attrs=True): + """Extract a member from the archive to the current working directory, + using its full name. Its file information is extracted as accurately + as possible. `member' may be a filename or a TarInfo object. You can + specify a different directory using `path'. File attributes (owner, + mtime, mode) are set unless `set_attrs' is False. + """ + self._check("r") + + if isinstance(member, str): + tarinfo = self.getmember(member) + else: + tarinfo = member + + # Prepare the link target for makelink(). + if tarinfo.islnk(): + tarinfo._link_target = os.path.join(path, tarinfo.linkname) + + try: + self._extract_member(tarinfo, os.path.join(path, tarinfo.name), + set_attrs=set_attrs) + except EnvironmentError as e: + if self.errorlevel > 0: + raise + else: + if e.filename is None: + self._dbg(1, "tarfile: %s" % e.strerror) + else: + self._dbg(1, "tarfile: %s %r" % (e.strerror, e.filename)) + except ExtractError as e: + if self.errorlevel > 1: + raise + else: + self._dbg(1, "tarfile: %s" % e) + + def extractfile(self, member): + """Extract a member from the archive as a file object. `member' may be + a filename or a TarInfo object. If `member' is a regular file, a + file-like object is returned. If `member' is a link, a file-like + object is constructed from the link's target. If `member' is none of + the above, None is returned. + The file-like object is read-only and provides the following + methods: read(), readline(), readlines(), seek() and tell() + """ + self._check("r") + + if isinstance(member, str): + tarinfo = self.getmember(member) + else: + tarinfo = member + + if tarinfo.isreg(): + return self.fileobject(self, tarinfo) + + elif tarinfo.type not in SUPPORTED_TYPES: + # If a member's type is unknown, it is treated as a + # regular file. + return self.fileobject(self, tarinfo) + + elif tarinfo.islnk() or tarinfo.issym(): + if isinstance(self.fileobj, _Stream): + # A small but ugly workaround for the case that someone tries + # to extract a (sym)link as a file-object from a non-seekable + # stream of tar blocks. + raise StreamError("cannot extract (sym)link as file object") + else: + # A (sym)link's file object is its target's file object. + return self.extractfile(self._find_link_target(tarinfo)) + else: + # If there's no data associated with the member (directory, chrdev, + # blkdev, etc.), return None instead of a file object. + return None + + def _extract_member(self, tarinfo, targetpath, set_attrs=True): + """Extract the TarInfo object tarinfo to a physical + file called targetpath. + """ + # Fetch the TarInfo object for the given name + # and build the destination pathname, replacing + # forward slashes to platform specific separators. + targetpath = targetpath.rstrip("/") + targetpath = targetpath.replace("/", os.sep) + + # Create all upper directories. + upperdirs = os.path.dirname(targetpath) + if upperdirs and not os.path.exists(upperdirs): + # Create directories that are not part of the archive with + # default permissions. + os.makedirs(upperdirs) + + if tarinfo.islnk() or tarinfo.issym(): + self._dbg(1, "%s -> %s" % (tarinfo.name, tarinfo.linkname)) + else: + self._dbg(1, tarinfo.name) + + if tarinfo.isreg(): + self.makefile(tarinfo, targetpath) + elif tarinfo.isdir(): + self.makedir(tarinfo, targetpath) + elif tarinfo.isfifo(): + self.makefifo(tarinfo, targetpath) + elif tarinfo.ischr() or tarinfo.isblk(): + self.makedev(tarinfo, targetpath) + elif tarinfo.islnk() or tarinfo.issym(): + self.makelink(tarinfo, targetpath) + elif tarinfo.type not in SUPPORTED_TYPES: + self.makeunknown(tarinfo, targetpath) + else: + self.makefile(tarinfo, targetpath) + + if set_attrs: + self.chown(tarinfo, targetpath) + if not tarinfo.issym(): + self.chmod(tarinfo, targetpath) + self.utime(tarinfo, targetpath) + + #-------------------------------------------------------------------------- + # Below are the different file methods. They are called via + # _extract_member() when extract() is called. They can be replaced in a + # subclass to implement other functionality. + + def makedir(self, tarinfo, targetpath): + """Make a directory called targetpath. + """ + try: + # Use a safe mode for the directory, the real mode is set + # later in _extract_member(). + os.mkdir(targetpath, 0o700) + except EnvironmentError as e: + if e.errno != errno.EEXIST: + raise + + def makefile(self, tarinfo, targetpath): + """Make a file called targetpath. + """ + source = self.fileobj + source.seek(tarinfo.offset_data) + target = bltn_open(targetpath, "wb") + if tarinfo.sparse is not None: + for offset, size in tarinfo.sparse: + target.seek(offset) + copyfileobj(source, target, size) + else: + copyfileobj(source, target, tarinfo.size) + target.seek(tarinfo.size) + target.truncate() + target.close() + + def makeunknown(self, tarinfo, targetpath): + """Make a file from a TarInfo object with an unknown type + at targetpath. + """ + self.makefile(tarinfo, targetpath) + self._dbg(1, "tarfile: Unknown file type %r, " \ + "extracted as regular file." % tarinfo.type) + + def makefifo(self, tarinfo, targetpath): + """Make a fifo called targetpath. + """ + if hasattr(os, "mkfifo"): + os.mkfifo(targetpath) + else: + raise ExtractError("fifo not supported by system") + + def makedev(self, tarinfo, targetpath): + """Make a character or block device called targetpath. + """ + if not hasattr(os, "mknod") or not hasattr(os, "makedev"): + raise ExtractError("special devices not supported by system") + + mode = tarinfo.mode + if tarinfo.isblk(): + mode |= stat.S_IFBLK + else: + mode |= stat.S_IFCHR + + os.mknod(targetpath, mode, + os.makedev(tarinfo.devmajor, tarinfo.devminor)) + + def makelink(self, tarinfo, targetpath): + """Make a (symbolic) link called targetpath. If it cannot be created + (platform limitation), we try to make a copy of the referenced file + instead of a link. + """ + try: + # For systems that support symbolic and hard links. + if tarinfo.issym(): + os.symlink(tarinfo.linkname, targetpath) + else: + # See extract(). + if os.path.exists(tarinfo._link_target): + os.link(tarinfo._link_target, targetpath) + else: + self._extract_member(self._find_link_target(tarinfo), + targetpath) + except symlink_exception: + if tarinfo.issym(): + linkpath = os.path.join(os.path.dirname(tarinfo.name), + tarinfo.linkname) + else: + linkpath = tarinfo.linkname + else: + try: + self._extract_member(self._find_link_target(tarinfo), + targetpath) + except KeyError: + raise ExtractError("unable to resolve link inside archive") + + def chown(self, tarinfo, targetpath): + """Set owner of targetpath according to tarinfo. + """ + if pwd and hasattr(os, "geteuid") and os.geteuid() == 0: + # We have to be root to do so. + try: + g = grp.getgrnam(tarinfo.gname)[2] + except KeyError: + g = tarinfo.gid + try: + u = pwd.getpwnam(tarinfo.uname)[2] + except KeyError: + u = tarinfo.uid + try: + if tarinfo.issym() and hasattr(os, "lchown"): + os.lchown(targetpath, u, g) + else: + if sys.platform != "os2emx": + os.chown(targetpath, u, g) + except EnvironmentError as e: + raise ExtractError("could not change owner") + + def chmod(self, tarinfo, targetpath): + """Set file permissions of targetpath according to tarinfo. + """ + if hasattr(os, 'chmod'): + try: + os.chmod(targetpath, tarinfo.mode) + except EnvironmentError as e: + raise ExtractError("could not change mode") + + def utime(self, tarinfo, targetpath): + """Set modification time of targetpath according to tarinfo. + """ + if not hasattr(os, 'utime'): + return + try: + os.utime(targetpath, (tarinfo.mtime, tarinfo.mtime)) + except EnvironmentError as e: + raise ExtractError("could not change modification time") + + #-------------------------------------------------------------------------- + def next(self): + """Return the next member of the archive as a TarInfo object, when + TarFile is opened for reading. Return None if there is no more + available. + """ + self._check("ra") + if self.firstmember is not None: + m = self.firstmember + self.firstmember = None + return m + + # Read the next block. + self.fileobj.seek(self.offset) + tarinfo = None + while True: + try: + tarinfo = self.tarinfo.fromtarfile(self) + except EOFHeaderError as e: + if self.ignore_zeros: + self._dbg(2, "0x%X: %s" % (self.offset, e)) + self.offset += BLOCKSIZE + continue + except InvalidHeaderError as e: + if self.ignore_zeros: + self._dbg(2, "0x%X: %s" % (self.offset, e)) + self.offset += BLOCKSIZE + continue + elif self.offset == 0: + raise ReadError(str(e)) + except EmptyHeaderError: + if self.offset == 0: + raise ReadError("empty file") + except TruncatedHeaderError as e: + if self.offset == 0: + raise ReadError(str(e)) + except SubsequentHeaderError as e: + raise ReadError(str(e)) + break + + if tarinfo is not None: + self.members.append(tarinfo) + else: + self._loaded = True + + return tarinfo + + #-------------------------------------------------------------------------- + # Little helper methods: + + def _getmember(self, name, tarinfo=None, normalize=False): + """Find an archive member by name from bottom to top. + If tarinfo is given, it is used as the starting point. + """ + # Ensure that all members have been loaded. + members = self.getmembers() + + # Limit the member search list up to tarinfo. + if tarinfo is not None: + members = members[:members.index(tarinfo)] + + if normalize: + name = os.path.normpath(name) + + for member in reversed(members): + if normalize: + member_name = os.path.normpath(member.name) + else: + member_name = member.name + + if name == member_name: + return member + + def _load(self): + """Read through the entire archive file and look for readable + members. + """ + while True: + tarinfo = self.next() + if tarinfo is None: + break + self._loaded = True + + def _check(self, mode=None): + """Check if TarFile is still open, and if the operation's mode + corresponds to TarFile's mode. + """ + if self.closed: + raise IOError("%s is closed" % self.__class__.__name__) + if mode is not None and self.mode not in mode: + raise IOError("bad operation for mode %r" % self.mode) + + def _find_link_target(self, tarinfo): + """Find the target member of a symlink or hardlink member in the + archive. + """ + if tarinfo.issym(): + # Always search the entire archive. + linkname = os.path.dirname(tarinfo.name) + "/" + tarinfo.linkname + limit = None + else: + # Search the archive before the link, because a hard link is + # just a reference to an already archived file. + linkname = tarinfo.linkname + limit = tarinfo + + member = self._getmember(linkname, tarinfo=limit, normalize=True) + if member is None: + raise KeyError("linkname %r not found" % linkname) + return member + + def __iter__(self): + """Provide an iterator object. + """ + if self._loaded: + return iter(self.members) + else: + return TarIter(self) + + def _dbg(self, level, msg): + """Write debugging output to sys.stderr. + """ + if level <= self.debug: + print(msg, file=sys.stderr) + + def __enter__(self): + self._check() + return self + + def __exit__(self, type, value, traceback): + if type is None: + self.close() + else: + # An exception occurred. We must not call close() because + # it would try to write end-of-archive blocks and padding. + if not self._extfileobj: + self.fileobj.close() + self.closed = True +# class TarFile + +class TarIter(object): + """Iterator Class. + + for tarinfo in TarFile(...): + suite... + """ + + def __init__(self, tarfile): + """Construct a TarIter object. + """ + self.tarfile = tarfile + self.index = 0 + def __iter__(self): + """Return iterator object. + """ + return self + + def __next__(self): + """Return the next item using TarFile's next() method. + When all members have been read, set TarFile as _loaded. + """ + # Fix for SF #1100429: Under rare circumstances it can + # happen that getmembers() is called during iteration, + # which will cause TarIter to stop prematurely. + if not self.tarfile._loaded: + tarinfo = self.tarfile.next() + if not tarinfo: + self.tarfile._loaded = True + raise StopIteration + else: + try: + tarinfo = self.tarfile.members[self.index] + except IndexError: + raise StopIteration + self.index += 1 + return tarinfo + + next = __next__ # for Python 2.x + +#-------------------- +# exported functions +#-------------------- +def is_tarfile(name): + """Return True if name points to a tar archive that we + are able to handle, else return False. + """ + try: + t = open(name) + t.close() + return True + except TarError: + return False + +bltn_open = open +open = TarFile.open diff --git a/venv/Lib/site-packages/pip/_vendor/distlib/compat.py b/venv/Lib/site-packages/pip/_vendor/distlib/compat.py new file mode 100644 index 0000000..c316fd9 --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/distlib/compat.py @@ -0,0 +1,1120 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2013-2017 Vinay Sajip. +# Licensed to the Python Software Foundation under a contributor agreement. +# See LICENSE.txt and CONTRIBUTORS.txt. +# +from __future__ import absolute_import + +import os +import re +import sys + +try: + import ssl +except ImportError: # pragma: no cover + ssl = None + +if sys.version_info[0] < 3: # pragma: no cover + from StringIO import StringIO + string_types = basestring, + text_type = unicode + from types import FileType as file_type + import __builtin__ as builtins + import ConfigParser as configparser + from ._backport import shutil + from urlparse import urlparse, urlunparse, urljoin, urlsplit, urlunsplit + from urllib import (urlretrieve, quote as _quote, unquote, url2pathname, + pathname2url, ContentTooShortError, splittype) + + def quote(s): + if isinstance(s, unicode): + s = s.encode('utf-8') + return _quote(s) + + import urllib2 + from urllib2 import (Request, urlopen, URLError, HTTPError, + HTTPBasicAuthHandler, HTTPPasswordMgr, + HTTPHandler, HTTPRedirectHandler, + build_opener) + if ssl: + from urllib2 import HTTPSHandler + import httplib + import xmlrpclib + import Queue as queue + from HTMLParser import HTMLParser + import htmlentitydefs + raw_input = raw_input + from itertools import ifilter as filter + from itertools import ifilterfalse as filterfalse + + _userprog = None + def splituser(host): + """splituser('user[:passwd]@host[:port]') --> 'user[:passwd]', 'host[:port]'.""" + global _userprog + if _userprog is None: + import re + _userprog = re.compile('^(.*)@(.*)$') + + match = _userprog.match(host) + if match: return match.group(1, 2) + return None, host + +else: # pragma: no cover + from io import StringIO + string_types = str, + text_type = str + from io import TextIOWrapper as file_type + import builtins + import configparser + import shutil + from urllib.parse import (urlparse, urlunparse, urljoin, splituser, quote, + unquote, urlsplit, urlunsplit, splittype) + from urllib.request import (urlopen, urlretrieve, Request, url2pathname, + pathname2url, + HTTPBasicAuthHandler, HTTPPasswordMgr, + HTTPHandler, HTTPRedirectHandler, + build_opener) + if ssl: + from urllib.request import HTTPSHandler + from urllib.error import HTTPError, URLError, ContentTooShortError + import http.client as httplib + import urllib.request as urllib2 + import xmlrpc.client as xmlrpclib + import queue + from html.parser import HTMLParser + import html.entities as htmlentitydefs + raw_input = input + from itertools import filterfalse + filter = filter + +try: + from ssl import match_hostname, CertificateError +except ImportError: # pragma: no cover + class CertificateError(ValueError): + pass + + + def _dnsname_match(dn, hostname, max_wildcards=1): + """Matching according to RFC 6125, section 6.4.3 + + http://tools.ietf.org/html/rfc6125#section-6.4.3 + """ + pats = [] + if not dn: + return False + + parts = dn.split('.') + leftmost, remainder = parts[0], parts[1:] + + wildcards = leftmost.count('*') + if wildcards > max_wildcards: + # Issue #17980: avoid denials of service by refusing more + # than one wildcard per fragment. A survey of established + # policy among SSL implementations showed it to be a + # reasonable choice. + raise CertificateError( + "too many wildcards in certificate DNS name: " + repr(dn)) + + # speed up common case w/o wildcards + if not wildcards: + return dn.lower() == hostname.lower() + + # RFC 6125, section 6.4.3, subitem 1. + # The client SHOULD NOT attempt to match a presented identifier in which + # the wildcard character comprises a label other than the left-most label. + if leftmost == '*': + # When '*' is a fragment by itself, it matches a non-empty dotless + # fragment. + pats.append('[^.]+') + elif leftmost.startswith('xn--') or hostname.startswith('xn--'): + # RFC 6125, section 6.4.3, subitem 3. + # The client SHOULD NOT attempt to match a presented identifier + # where the wildcard character is embedded within an A-label or + # U-label of an internationalized domain name. + pats.append(re.escape(leftmost)) + else: + # Otherwise, '*' matches any dotless string, e.g. www* + pats.append(re.escape(leftmost).replace(r'\*', '[^.]*')) + + # add the remaining fragments, ignore any wildcards + for frag in remainder: + pats.append(re.escape(frag)) + + pat = re.compile(r'\A' + r'\.'.join(pats) + r'\Z', re.IGNORECASE) + return pat.match(hostname) + + + def match_hostname(cert, hostname): + """Verify that *cert* (in decoded format as returned by + SSLSocket.getpeercert()) matches the *hostname*. RFC 2818 and RFC 6125 + rules are followed, but IP addresses are not accepted for *hostname*. + + CertificateError is raised on failure. On success, the function + returns nothing. + """ + if not cert: + raise ValueError("empty or no certificate, match_hostname needs a " + "SSL socket or SSL context with either " + "CERT_OPTIONAL or CERT_REQUIRED") + dnsnames = [] + san = cert.get('subjectAltName', ()) + for key, value in san: + if key == 'DNS': + if _dnsname_match(value, hostname): + return + dnsnames.append(value) + if not dnsnames: + # The subject is only checked when there is no dNSName entry + # in subjectAltName + for sub in cert.get('subject', ()): + for key, value in sub: + # XXX according to RFC 2818, the most specific Common Name + # must be used. + if key == 'commonName': + if _dnsname_match(value, hostname): + return + dnsnames.append(value) + if len(dnsnames) > 1: + raise CertificateError("hostname %r " + "doesn't match either of %s" + % (hostname, ', '.join(map(repr, dnsnames)))) + elif len(dnsnames) == 1: + raise CertificateError("hostname %r " + "doesn't match %r" + % (hostname, dnsnames[0])) + else: + raise CertificateError("no appropriate commonName or " + "subjectAltName fields were found") + + +try: + from types import SimpleNamespace as Container +except ImportError: # pragma: no cover + class Container(object): + """ + A generic container for when multiple values need to be returned + """ + def __init__(self, **kwargs): + self.__dict__.update(kwargs) + + +try: + from shutil import which +except ImportError: # pragma: no cover + # Implementation from Python 3.3 + def which(cmd, mode=os.F_OK | os.X_OK, path=None): + """Given a command, mode, and a PATH string, return the path which + conforms to the given mode on the PATH, or None if there is no such + file. + + `mode` defaults to os.F_OK | os.X_OK. `path` defaults to the result + of os.environ.get("PATH"), or can be overridden with a custom search + path. + + """ + # Check that a given file can be accessed with the correct mode. + # Additionally check that `file` is not a directory, as on Windows + # directories pass the os.access check. + def _access_check(fn, mode): + return (os.path.exists(fn) and os.access(fn, mode) + and not os.path.isdir(fn)) + + # If we're given a path with a directory part, look it up directly rather + # than referring to PATH directories. This includes checking relative to the + # current directory, e.g. ./script + if os.path.dirname(cmd): + if _access_check(cmd, mode): + return cmd + return None + + if path is None: + path = os.environ.get("PATH", os.defpath) + if not path: + return None + path = path.split(os.pathsep) + + if sys.platform == "win32": + # The current directory takes precedence on Windows. + if not os.curdir in path: + path.insert(0, os.curdir) + + # PATHEXT is necessary to check on Windows. + pathext = os.environ.get("PATHEXT", "").split(os.pathsep) + # See if the given file matches any of the expected path extensions. + # This will allow us to short circuit when given "python.exe". + # If it does match, only test that one, otherwise we have to try + # others. + if any(cmd.lower().endswith(ext.lower()) for ext in pathext): + files = [cmd] + else: + files = [cmd + ext for ext in pathext] + else: + # On other platforms you don't have things like PATHEXT to tell you + # what file suffixes are executable, so just pass on cmd as-is. + files = [cmd] + + seen = set() + for dir in path: + normdir = os.path.normcase(dir) + if not normdir in seen: + seen.add(normdir) + for thefile in files: + name = os.path.join(dir, thefile) + if _access_check(name, mode): + return name + return None + + +# ZipFile is a context manager in 2.7, but not in 2.6 + +from zipfile import ZipFile as BaseZipFile + +if hasattr(BaseZipFile, '__enter__'): # pragma: no cover + ZipFile = BaseZipFile +else: # pragma: no cover + from zipfile import ZipExtFile as BaseZipExtFile + + class ZipExtFile(BaseZipExtFile): + def __init__(self, base): + self.__dict__.update(base.__dict__) + + def __enter__(self): + return self + + def __exit__(self, *exc_info): + self.close() + # return None, so if an exception occurred, it will propagate + + class ZipFile(BaseZipFile): + def __enter__(self): + return self + + def __exit__(self, *exc_info): + self.close() + # return None, so if an exception occurred, it will propagate + + def open(self, *args, **kwargs): + base = BaseZipFile.open(self, *args, **kwargs) + return ZipExtFile(base) + +try: + from platform import python_implementation +except ImportError: # pragma: no cover + def python_implementation(): + """Return a string identifying the Python implementation.""" + if 'PyPy' in sys.version: + return 'PyPy' + if os.name == 'java': + return 'Jython' + if sys.version.startswith('IronPython'): + return 'IronPython' + return 'CPython' + +try: + import sysconfig +except ImportError: # pragma: no cover + from ._backport import sysconfig + +try: + callable = callable +except NameError: # pragma: no cover + from collections.abc import Callable + + def callable(obj): + return isinstance(obj, Callable) + + +try: + fsencode = os.fsencode + fsdecode = os.fsdecode +except AttributeError: # pragma: no cover + # Issue #99: on some systems (e.g. containerised), + # sys.getfilesystemencoding() returns None, and we need a real value, + # so fall back to utf-8. From the CPython 2.7 docs relating to Unix and + # sys.getfilesystemencoding(): the return value is "the user’s preference + # according to the result of nl_langinfo(CODESET), or None if the + # nl_langinfo(CODESET) failed." + _fsencoding = sys.getfilesystemencoding() or 'utf-8' + if _fsencoding == 'mbcs': + _fserrors = 'strict' + else: + _fserrors = 'surrogateescape' + + def fsencode(filename): + if isinstance(filename, bytes): + return filename + elif isinstance(filename, text_type): + return filename.encode(_fsencoding, _fserrors) + else: + raise TypeError("expect bytes or str, not %s" % + type(filename).__name__) + + def fsdecode(filename): + if isinstance(filename, text_type): + return filename + elif isinstance(filename, bytes): + return filename.decode(_fsencoding, _fserrors) + else: + raise TypeError("expect bytes or str, not %s" % + type(filename).__name__) + +try: + from tokenize import detect_encoding +except ImportError: # pragma: no cover + from codecs import BOM_UTF8, lookup + import re + + cookie_re = re.compile(r"coding[:=]\s*([-\w.]+)") + + def _get_normal_name(orig_enc): + """Imitates get_normal_name in tokenizer.c.""" + # Only care about the first 12 characters. + enc = orig_enc[:12].lower().replace("_", "-") + if enc == "utf-8" or enc.startswith("utf-8-"): + return "utf-8" + if enc in ("latin-1", "iso-8859-1", "iso-latin-1") or \ + enc.startswith(("latin-1-", "iso-8859-1-", "iso-latin-1-")): + return "iso-8859-1" + return orig_enc + + def detect_encoding(readline): + """ + The detect_encoding() function is used to detect the encoding that should + be used to decode a Python source file. It requires one argument, readline, + in the same way as the tokenize() generator. + + It will call readline a maximum of twice, and return the encoding used + (as a string) and a list of any lines (left as bytes) it has read in. + + It detects the encoding from the presence of a utf-8 bom or an encoding + cookie as specified in pep-0263. If both a bom and a cookie are present, + but disagree, a SyntaxError will be raised. If the encoding cookie is an + invalid charset, raise a SyntaxError. Note that if a utf-8 bom is found, + 'utf-8-sig' is returned. + + If no encoding is specified, then the default of 'utf-8' will be returned. + """ + try: + filename = readline.__self__.name + except AttributeError: + filename = None + bom_found = False + encoding = None + default = 'utf-8' + def read_or_stop(): + try: + return readline() + except StopIteration: + return b'' + + def find_cookie(line): + try: + # Decode as UTF-8. Either the line is an encoding declaration, + # in which case it should be pure ASCII, or it must be UTF-8 + # per default encoding. + line_string = line.decode('utf-8') + except UnicodeDecodeError: + msg = "invalid or missing encoding declaration" + if filename is not None: + msg = '{} for {!r}'.format(msg, filename) + raise SyntaxError(msg) + + matches = cookie_re.findall(line_string) + if not matches: + return None + encoding = _get_normal_name(matches[0]) + try: + codec = lookup(encoding) + except LookupError: + # This behaviour mimics the Python interpreter + if filename is None: + msg = "unknown encoding: " + encoding + else: + msg = "unknown encoding for {!r}: {}".format(filename, + encoding) + raise SyntaxError(msg) + + if bom_found: + if codec.name != 'utf-8': + # This behaviour mimics the Python interpreter + if filename is None: + msg = 'encoding problem: utf-8' + else: + msg = 'encoding problem for {!r}: utf-8'.format(filename) + raise SyntaxError(msg) + encoding += '-sig' + return encoding + + first = read_or_stop() + if first.startswith(BOM_UTF8): + bom_found = True + first = first[3:] + default = 'utf-8-sig' + if not first: + return default, [] + + encoding = find_cookie(first) + if encoding: + return encoding, [first] + + second = read_or_stop() + if not second: + return default, [first] + + encoding = find_cookie(second) + if encoding: + return encoding, [first, second] + + return default, [first, second] + +# For converting & <-> & etc. +try: + from html import escape +except ImportError: + from cgi import escape +if sys.version_info[:2] < (3, 4): + unescape = HTMLParser().unescape +else: + from html import unescape + +try: + from collections import ChainMap +except ImportError: # pragma: no cover + from collections import MutableMapping + + try: + from reprlib import recursive_repr as _recursive_repr + except ImportError: + def _recursive_repr(fillvalue='...'): + ''' + Decorator to make a repr function return fillvalue for a recursive + call + ''' + + def decorating_function(user_function): + repr_running = set() + + def wrapper(self): + key = id(self), get_ident() + if key in repr_running: + return fillvalue + repr_running.add(key) + try: + result = user_function(self) + finally: + repr_running.discard(key) + return result + + # Can't use functools.wraps() here because of bootstrap issues + wrapper.__module__ = getattr(user_function, '__module__') + wrapper.__doc__ = getattr(user_function, '__doc__') + wrapper.__name__ = getattr(user_function, '__name__') + wrapper.__annotations__ = getattr(user_function, '__annotations__', {}) + return wrapper + + return decorating_function + + class ChainMap(MutableMapping): + ''' A ChainMap groups multiple dicts (or other mappings) together + to create a single, updateable view. + + The underlying mappings are stored in a list. That list is public and can + accessed or updated using the *maps* attribute. There is no other state. + + Lookups search the underlying mappings successively until a key is found. + In contrast, writes, updates, and deletions only operate on the first + mapping. + + ''' + + def __init__(self, *maps): + '''Initialize a ChainMap by setting *maps* to the given mappings. + If no mappings are provided, a single empty dictionary is used. + + ''' + self.maps = list(maps) or [{}] # always at least one map + + def __missing__(self, key): + raise KeyError(key) + + def __getitem__(self, key): + for mapping in self.maps: + try: + return mapping[key] # can't use 'key in mapping' with defaultdict + except KeyError: + pass + return self.__missing__(key) # support subclasses that define __missing__ + + def get(self, key, default=None): + return self[key] if key in self else default + + def __len__(self): + return len(set().union(*self.maps)) # reuses stored hash values if possible + + def __iter__(self): + return iter(set().union(*self.maps)) + + def __contains__(self, key): + return any(key in m for m in self.maps) + + def __bool__(self): + return any(self.maps) + + @_recursive_repr() + def __repr__(self): + return '{0.__class__.__name__}({1})'.format( + self, ', '.join(map(repr, self.maps))) + + @classmethod + def fromkeys(cls, iterable, *args): + 'Create a ChainMap with a single dict created from the iterable.' + return cls(dict.fromkeys(iterable, *args)) + + def copy(self): + 'New ChainMap or subclass with a new copy of maps[0] and refs to maps[1:]' + return self.__class__(self.maps[0].copy(), *self.maps[1:]) + + __copy__ = copy + + def new_child(self): # like Django's Context.push() + 'New ChainMap with a new dict followed by all previous maps.' + return self.__class__({}, *self.maps) + + @property + def parents(self): # like Django's Context.pop() + 'New ChainMap from maps[1:].' + return self.__class__(*self.maps[1:]) + + def __setitem__(self, key, value): + self.maps[0][key] = value + + def __delitem__(self, key): + try: + del self.maps[0][key] + except KeyError: + raise KeyError('Key not found in the first mapping: {!r}'.format(key)) + + def popitem(self): + 'Remove and return an item pair from maps[0]. Raise KeyError is maps[0] is empty.' + try: + return self.maps[0].popitem() + except KeyError: + raise KeyError('No keys found in the first mapping.') + + def pop(self, key, *args): + 'Remove *key* from maps[0] and return its value. Raise KeyError if *key* not in maps[0].' + try: + return self.maps[0].pop(key, *args) + except KeyError: + raise KeyError('Key not found in the first mapping: {!r}'.format(key)) + + def clear(self): + 'Clear maps[0], leaving maps[1:] intact.' + self.maps[0].clear() + +try: + from importlib.util import cache_from_source # Python >= 3.4 +except ImportError: # pragma: no cover + try: + from imp import cache_from_source + except ImportError: # pragma: no cover + def cache_from_source(path, debug_override=None): + assert path.endswith('.py') + if debug_override is None: + debug_override = __debug__ + if debug_override: + suffix = 'c' + else: + suffix = 'o' + return path + suffix + +try: + from collections import OrderedDict +except ImportError: # pragma: no cover +## {{{ http://code.activestate.com/recipes/576693/ (r9) +# Backport of OrderedDict() class that runs on Python 2.4, 2.5, 2.6, 2.7 and pypy. +# Passes Python2.7's test suite and incorporates all the latest updates. + try: + from thread import get_ident as _get_ident + except ImportError: + from dummy_thread import get_ident as _get_ident + + try: + from _abcoll import KeysView, ValuesView, ItemsView + except ImportError: + pass + + + class OrderedDict(dict): + 'Dictionary that remembers insertion order' + # An inherited dict maps keys to values. + # The inherited dict provides __getitem__, __len__, __contains__, and get. + # The remaining methods are order-aware. + # Big-O running times for all methods are the same as for regular dictionaries. + + # The internal self.__map dictionary maps keys to links in a doubly linked list. + # The circular doubly linked list starts and ends with a sentinel element. + # The sentinel element never gets deleted (this simplifies the algorithm). + # Each link is stored as a list of length three: [PREV, NEXT, KEY]. + + def __init__(self, *args, **kwds): + '''Initialize an ordered dictionary. Signature is the same as for + regular dictionaries, but keyword arguments are not recommended + because their insertion order is arbitrary. + + ''' + if len(args) > 1: + raise TypeError('expected at most 1 arguments, got %d' % len(args)) + try: + self.__root + except AttributeError: + self.__root = root = [] # sentinel node + root[:] = [root, root, None] + self.__map = {} + self.__update(*args, **kwds) + + def __setitem__(self, key, value, dict_setitem=dict.__setitem__): + 'od.__setitem__(i, y) <==> od[i]=y' + # Setting a new item creates a new link which goes at the end of the linked + # list, and the inherited dictionary is updated with the new key/value pair. + if key not in self: + root = self.__root + last = root[0] + last[1] = root[0] = self.__map[key] = [last, root, key] + dict_setitem(self, key, value) + + def __delitem__(self, key, dict_delitem=dict.__delitem__): + 'od.__delitem__(y) <==> del od[y]' + # Deleting an existing item uses self.__map to find the link which is + # then removed by updating the links in the predecessor and successor nodes. + dict_delitem(self, key) + link_prev, link_next, key = self.__map.pop(key) + link_prev[1] = link_next + link_next[0] = link_prev + + def __iter__(self): + 'od.__iter__() <==> iter(od)' + root = self.__root + curr = root[1] + while curr is not root: + yield curr[2] + curr = curr[1] + + def __reversed__(self): + 'od.__reversed__() <==> reversed(od)' + root = self.__root + curr = root[0] + while curr is not root: + yield curr[2] + curr = curr[0] + + def clear(self): + 'od.clear() -> None. Remove all items from od.' + try: + for node in self.__map.itervalues(): + del node[:] + root = self.__root + root[:] = [root, root, None] + self.__map.clear() + except AttributeError: + pass + dict.clear(self) + + def popitem(self, last=True): + '''od.popitem() -> (k, v), return and remove a (key, value) pair. + Pairs are returned in LIFO order if last is true or FIFO order if false. + + ''' + if not self: + raise KeyError('dictionary is empty') + root = self.__root + if last: + link = root[0] + link_prev = link[0] + link_prev[1] = root + root[0] = link_prev + else: + link = root[1] + link_next = link[1] + root[1] = link_next + link_next[0] = root + key = link[2] + del self.__map[key] + value = dict.pop(self, key) + return key, value + + # -- the following methods do not depend on the internal structure -- + + def keys(self): + 'od.keys() -> list of keys in od' + return list(self) + + def values(self): + 'od.values() -> list of values in od' + return [self[key] for key in self] + + def items(self): + 'od.items() -> list of (key, value) pairs in od' + return [(key, self[key]) for key in self] + + def iterkeys(self): + 'od.iterkeys() -> an iterator over the keys in od' + return iter(self) + + def itervalues(self): + 'od.itervalues -> an iterator over the values in od' + for k in self: + yield self[k] + + def iteritems(self): + 'od.iteritems -> an iterator over the (key, value) items in od' + for k in self: + yield (k, self[k]) + + def update(*args, **kwds): + '''od.update(E, **F) -> None. Update od from dict/iterable E and F. + + If E is a dict instance, does: for k in E: od[k] = E[k] + If E has a .keys() method, does: for k in E.keys(): od[k] = E[k] + Or if E is an iterable of items, does: for k, v in E: od[k] = v + In either case, this is followed by: for k, v in F.items(): od[k] = v + + ''' + if len(args) > 2: + raise TypeError('update() takes at most 2 positional ' + 'arguments (%d given)' % (len(args),)) + elif not args: + raise TypeError('update() takes at least 1 argument (0 given)') + self = args[0] + # Make progressively weaker assumptions about "other" + other = () + if len(args) == 2: + other = args[1] + if isinstance(other, dict): + for key in other: + self[key] = other[key] + elif hasattr(other, 'keys'): + for key in other.keys(): + self[key] = other[key] + else: + for key, value in other: + self[key] = value + for key, value in kwds.items(): + self[key] = value + + __update = update # let subclasses override update without breaking __init__ + + __marker = object() + + def pop(self, key, default=__marker): + '''od.pop(k[,d]) -> v, remove specified key and return the corresponding value. + If key is not found, d is returned if given, otherwise KeyError is raised. + + ''' + if key in self: + result = self[key] + del self[key] + return result + if default is self.__marker: + raise KeyError(key) + return default + + def setdefault(self, key, default=None): + 'od.setdefault(k[,d]) -> od.get(k,d), also set od[k]=d if k not in od' + if key in self: + return self[key] + self[key] = default + return default + + def __repr__(self, _repr_running=None): + 'od.__repr__() <==> repr(od)' + if not _repr_running: _repr_running = {} + call_key = id(self), _get_ident() + if call_key in _repr_running: + return '...' + _repr_running[call_key] = 1 + try: + if not self: + return '%s()' % (self.__class__.__name__,) + return '%s(%r)' % (self.__class__.__name__, self.items()) + finally: + del _repr_running[call_key] + + def __reduce__(self): + 'Return state information for pickling' + items = [[k, self[k]] for k in self] + inst_dict = vars(self).copy() + for k in vars(OrderedDict()): + inst_dict.pop(k, None) + if inst_dict: + return (self.__class__, (items,), inst_dict) + return self.__class__, (items,) + + def copy(self): + 'od.copy() -> a shallow copy of od' + return self.__class__(self) + + @classmethod + def fromkeys(cls, iterable, value=None): + '''OD.fromkeys(S[, v]) -> New ordered dictionary with keys from S + and values equal to v (which defaults to None). + + ''' + d = cls() + for key in iterable: + d[key] = value + return d + + def __eq__(self, other): + '''od.__eq__(y) <==> od==y. Comparison to another OD is order-sensitive + while comparison to a regular mapping is order-insensitive. + + ''' + if isinstance(other, OrderedDict): + return len(self)==len(other) and self.items() == other.items() + return dict.__eq__(self, other) + + def __ne__(self, other): + return not self == other + + # -- the following methods are only used in Python 2.7 -- + + def viewkeys(self): + "od.viewkeys() -> a set-like object providing a view on od's keys" + return KeysView(self) + + def viewvalues(self): + "od.viewvalues() -> an object providing a view on od's values" + return ValuesView(self) + + def viewitems(self): + "od.viewitems() -> a set-like object providing a view on od's items" + return ItemsView(self) + +try: + from logging.config import BaseConfigurator, valid_ident +except ImportError: # pragma: no cover + IDENTIFIER = re.compile('^[a-z_][a-z0-9_]*$', re.I) + + + def valid_ident(s): + m = IDENTIFIER.match(s) + if not m: + raise ValueError('Not a valid Python identifier: %r' % s) + return True + + + # The ConvertingXXX classes are wrappers around standard Python containers, + # and they serve to convert any suitable values in the container. The + # conversion converts base dicts, lists and tuples to their wrapped + # equivalents, whereas strings which match a conversion format are converted + # appropriately. + # + # Each wrapper should have a configurator attribute holding the actual + # configurator to use for conversion. + + class ConvertingDict(dict): + """A converting dictionary wrapper.""" + + def __getitem__(self, key): + value = dict.__getitem__(self, key) + result = self.configurator.convert(value) + #If the converted value is different, save for next time + if value is not result: + self[key] = result + if type(result) in (ConvertingDict, ConvertingList, + ConvertingTuple): + result.parent = self + result.key = key + return result + + def get(self, key, default=None): + value = dict.get(self, key, default) + result = self.configurator.convert(value) + #If the converted value is different, save for next time + if value is not result: + self[key] = result + if type(result) in (ConvertingDict, ConvertingList, + ConvertingTuple): + result.parent = self + result.key = key + return result + + def pop(self, key, default=None): + value = dict.pop(self, key, default) + result = self.configurator.convert(value) + if value is not result: + if type(result) in (ConvertingDict, ConvertingList, + ConvertingTuple): + result.parent = self + result.key = key + return result + + class ConvertingList(list): + """A converting list wrapper.""" + def __getitem__(self, key): + value = list.__getitem__(self, key) + result = self.configurator.convert(value) + #If the converted value is different, save for next time + if value is not result: + self[key] = result + if type(result) in (ConvertingDict, ConvertingList, + ConvertingTuple): + result.parent = self + result.key = key + return result + + def pop(self, idx=-1): + value = list.pop(self, idx) + result = self.configurator.convert(value) + if value is not result: + if type(result) in (ConvertingDict, ConvertingList, + ConvertingTuple): + result.parent = self + return result + + class ConvertingTuple(tuple): + """A converting tuple wrapper.""" + def __getitem__(self, key): + value = tuple.__getitem__(self, key) + result = self.configurator.convert(value) + if value is not result: + if type(result) in (ConvertingDict, ConvertingList, + ConvertingTuple): + result.parent = self + result.key = key + return result + + class BaseConfigurator(object): + """ + The configurator base class which defines some useful defaults. + """ + + CONVERT_PATTERN = re.compile(r'^(?P[a-z]+)://(?P.*)$') + + WORD_PATTERN = re.compile(r'^\s*(\w+)\s*') + DOT_PATTERN = re.compile(r'^\.\s*(\w+)\s*') + INDEX_PATTERN = re.compile(r'^\[\s*(\w+)\s*\]\s*') + DIGIT_PATTERN = re.compile(r'^\d+$') + + value_converters = { + 'ext' : 'ext_convert', + 'cfg' : 'cfg_convert', + } + + # We might want to use a different one, e.g. importlib + importer = staticmethod(__import__) + + def __init__(self, config): + self.config = ConvertingDict(config) + self.config.configurator = self + + def resolve(self, s): + """ + Resolve strings to objects using standard import and attribute + syntax. + """ + name = s.split('.') + used = name.pop(0) + try: + found = self.importer(used) + for frag in name: + used += '.' + frag + try: + found = getattr(found, frag) + except AttributeError: + self.importer(used) + found = getattr(found, frag) + return found + except ImportError: + e, tb = sys.exc_info()[1:] + v = ValueError('Cannot resolve %r: %s' % (s, e)) + v.__cause__, v.__traceback__ = e, tb + raise v + + def ext_convert(self, value): + """Default converter for the ext:// protocol.""" + return self.resolve(value) + + def cfg_convert(self, value): + """Default converter for the cfg:// protocol.""" + rest = value + m = self.WORD_PATTERN.match(rest) + if m is None: + raise ValueError("Unable to convert %r" % value) + else: + rest = rest[m.end():] + d = self.config[m.groups()[0]] + #print d, rest + while rest: + m = self.DOT_PATTERN.match(rest) + if m: + d = d[m.groups()[0]] + else: + m = self.INDEX_PATTERN.match(rest) + if m: + idx = m.groups()[0] + if not self.DIGIT_PATTERN.match(idx): + d = d[idx] + else: + try: + n = int(idx) # try as number first (most likely) + d = d[n] + except TypeError: + d = d[idx] + if m: + rest = rest[m.end():] + else: + raise ValueError('Unable to convert ' + '%r at %r' % (value, rest)) + #rest should be empty + return d + + def convert(self, value): + """ + Convert values to an appropriate type. dicts, lists and tuples are + replaced by their converting alternatives. Strings are checked to + see if they have a conversion format and are converted if they do. + """ + if not isinstance(value, ConvertingDict) and isinstance(value, dict): + value = ConvertingDict(value) + value.configurator = self + elif not isinstance(value, ConvertingList) and isinstance(value, list): + value = ConvertingList(value) + value.configurator = self + elif not isinstance(value, ConvertingTuple) and\ + isinstance(value, tuple): + value = ConvertingTuple(value) + value.configurator = self + elif isinstance(value, string_types): + m = self.CONVERT_PATTERN.match(value) + if m: + d = m.groupdict() + prefix = d['prefix'] + converter = self.value_converters.get(prefix, None) + if converter: + suffix = d['suffix'] + converter = getattr(self, converter) + value = converter(suffix) + return value + + def configure_custom(self, config): + """Configure an object with a user-supplied factory.""" + c = config.pop('()') + if not callable(c): + c = self.resolve(c) + props = config.pop('.', None) + # Check for valid identifiers + kwargs = dict([(k, config[k]) for k in config if valid_ident(k)]) + result = c(**kwargs) + if props: + for name, value in props.items(): + setattr(result, name, value) + return result + + def as_tuple(self, value): + """Utility function which converts lists to tuples.""" + if isinstance(value, list): + value = tuple(value) + return value diff --git a/venv/Lib/site-packages/pip/_vendor/distlib/database.py b/venv/Lib/site-packages/pip/_vendor/distlib/database.py new file mode 100644 index 0000000..0a90c30 --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/distlib/database.py @@ -0,0 +1,1339 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2012-2017 The Python Software Foundation. +# See LICENSE.txt and CONTRIBUTORS.txt. +# +"""PEP 376 implementation.""" + +from __future__ import unicode_literals + +import base64 +import codecs +import contextlib +import hashlib +import logging +import os +import posixpath +import sys +import zipimport + +from . import DistlibException, resources +from .compat import StringIO +from .version import get_scheme, UnsupportedVersionError +from .metadata import (Metadata, METADATA_FILENAME, WHEEL_METADATA_FILENAME, + LEGACY_METADATA_FILENAME) +from .util import (parse_requirement, cached_property, parse_name_and_version, + read_exports, write_exports, CSVReader, CSVWriter) + + +__all__ = ['Distribution', 'BaseInstalledDistribution', + 'InstalledDistribution', 'EggInfoDistribution', + 'DistributionPath'] + + +logger = logging.getLogger(__name__) + +EXPORTS_FILENAME = 'pydist-exports.json' +COMMANDS_FILENAME = 'pydist-commands.json' + +DIST_FILES = ('INSTALLER', METADATA_FILENAME, 'RECORD', 'REQUESTED', + 'RESOURCES', EXPORTS_FILENAME, 'SHARED') + +DISTINFO_EXT = '.dist-info' + + +class _Cache(object): + """ + A simple cache mapping names and .dist-info paths to distributions + """ + def __init__(self): + """ + Initialise an instance. There is normally one for each DistributionPath. + """ + self.name = {} + self.path = {} + self.generated = False + + def clear(self): + """ + Clear the cache, setting it to its initial state. + """ + self.name.clear() + self.path.clear() + self.generated = False + + def add(self, dist): + """ + Add a distribution to the cache. + :param dist: The distribution to add. + """ + if dist.path not in self.path: + self.path[dist.path] = dist + self.name.setdefault(dist.key, []).append(dist) + + +class DistributionPath(object): + """ + Represents a set of distributions installed on a path (typically sys.path). + """ + def __init__(self, path=None, include_egg=False): + """ + Create an instance from a path, optionally including legacy (distutils/ + setuptools/distribute) distributions. + :param path: The path to use, as a list of directories. If not specified, + sys.path is used. + :param include_egg: If True, this instance will look for and return legacy + distributions as well as those based on PEP 376. + """ + if path is None: + path = sys.path + self.path = path + self._include_dist = True + self._include_egg = include_egg + + self._cache = _Cache() + self._cache_egg = _Cache() + self._cache_enabled = True + self._scheme = get_scheme('default') + + def _get_cache_enabled(self): + return self._cache_enabled + + def _set_cache_enabled(self, value): + self._cache_enabled = value + + cache_enabled = property(_get_cache_enabled, _set_cache_enabled) + + def clear_cache(self): + """ + Clears the internal cache. + """ + self._cache.clear() + self._cache_egg.clear() + + + def _yield_distributions(self): + """ + Yield .dist-info and/or .egg(-info) distributions. + """ + # We need to check if we've seen some resources already, because on + # some Linux systems (e.g. some Debian/Ubuntu variants) there are + # symlinks which alias other files in the environment. + seen = set() + for path in self.path: + finder = resources.finder_for_path(path) + if finder is None: + continue + r = finder.find('') + if not r or not r.is_container: + continue + rset = sorted(r.resources) + for entry in rset: + r = finder.find(entry) + if not r or r.path in seen: + continue + if self._include_dist and entry.endswith(DISTINFO_EXT): + possible_filenames = [METADATA_FILENAME, + WHEEL_METADATA_FILENAME, + LEGACY_METADATA_FILENAME] + for metadata_filename in possible_filenames: + metadata_path = posixpath.join(entry, metadata_filename) + pydist = finder.find(metadata_path) + if pydist: + break + else: + continue + + with contextlib.closing(pydist.as_stream()) as stream: + metadata = Metadata(fileobj=stream, scheme='legacy') + logger.debug('Found %s', r.path) + seen.add(r.path) + yield new_dist_class(r.path, metadata=metadata, + env=self) + elif self._include_egg and entry.endswith(('.egg-info', + '.egg')): + logger.debug('Found %s', r.path) + seen.add(r.path) + yield old_dist_class(r.path, self) + + def _generate_cache(self): + """ + Scan the path for distributions and populate the cache with + those that are found. + """ + gen_dist = not self._cache.generated + gen_egg = self._include_egg and not self._cache_egg.generated + if gen_dist or gen_egg: + for dist in self._yield_distributions(): + if isinstance(dist, InstalledDistribution): + self._cache.add(dist) + else: + self._cache_egg.add(dist) + + if gen_dist: + self._cache.generated = True + if gen_egg: + self._cache_egg.generated = True + + @classmethod + def distinfo_dirname(cls, name, version): + """ + The *name* and *version* parameters are converted into their + filename-escaped form, i.e. any ``'-'`` characters are replaced + with ``'_'`` other than the one in ``'dist-info'`` and the one + separating the name from the version number. + + :parameter name: is converted to a standard distribution name by replacing + any runs of non- alphanumeric characters with a single + ``'-'``. + :type name: string + :parameter version: is converted to a standard version string. Spaces + become dots, and all other non-alphanumeric characters + (except dots) become dashes, with runs of multiple + dashes condensed to a single dash. + :type version: string + :returns: directory name + :rtype: string""" + name = name.replace('-', '_') + return '-'.join([name, version]) + DISTINFO_EXT + + def get_distributions(self): + """ + Provides an iterator that looks for distributions and returns + :class:`InstalledDistribution` or + :class:`EggInfoDistribution` instances for each one of them. + + :rtype: iterator of :class:`InstalledDistribution` and + :class:`EggInfoDistribution` instances + """ + if not self._cache_enabled: + for dist in self._yield_distributions(): + yield dist + else: + self._generate_cache() + + for dist in self._cache.path.values(): + yield dist + + if self._include_egg: + for dist in self._cache_egg.path.values(): + yield dist + + def get_distribution(self, name): + """ + Looks for a named distribution on the path. + + This function only returns the first result found, as no more than one + value is expected. If nothing is found, ``None`` is returned. + + :rtype: :class:`InstalledDistribution`, :class:`EggInfoDistribution` + or ``None`` + """ + result = None + name = name.lower() + if not self._cache_enabled: + for dist in self._yield_distributions(): + if dist.key == name: + result = dist + break + else: + self._generate_cache() + + if name in self._cache.name: + result = self._cache.name[name][0] + elif self._include_egg and name in self._cache_egg.name: + result = self._cache_egg.name[name][0] + return result + + def provides_distribution(self, name, version=None): + """ + Iterates over all distributions to find which distributions provide *name*. + If a *version* is provided, it will be used to filter the results. + + This function only returns the first result found, since no more than + one values are expected. If the directory is not found, returns ``None``. + + :parameter version: a version specifier that indicates the version + required, conforming to the format in ``PEP-345`` + + :type name: string + :type version: string + """ + matcher = None + if version is not None: + try: + matcher = self._scheme.matcher('%s (%s)' % (name, version)) + except ValueError: + raise DistlibException('invalid name or version: %r, %r' % + (name, version)) + + for dist in self.get_distributions(): + # We hit a problem on Travis where enum34 was installed and doesn't + # have a provides attribute ... + if not hasattr(dist, 'provides'): + logger.debug('No "provides": %s', dist) + else: + provided = dist.provides + + for p in provided: + p_name, p_ver = parse_name_and_version(p) + if matcher is None: + if p_name == name: + yield dist + break + else: + if p_name == name and matcher.match(p_ver): + yield dist + break + + def get_file_path(self, name, relative_path): + """ + Return the path to a resource file. + """ + dist = self.get_distribution(name) + if dist is None: + raise LookupError('no distribution named %r found' % name) + return dist.get_resource_path(relative_path) + + def get_exported_entries(self, category, name=None): + """ + Return all of the exported entries in a particular category. + + :param category: The category to search for entries. + :param name: If specified, only entries with that name are returned. + """ + for dist in self.get_distributions(): + r = dist.exports + if category in r: + d = r[category] + if name is not None: + if name in d: + yield d[name] + else: + for v in d.values(): + yield v + + +class Distribution(object): + """ + A base class for distributions, whether installed or from indexes. + Either way, it must have some metadata, so that's all that's needed + for construction. + """ + + build_time_dependency = False + """ + Set to True if it's known to be only a build-time dependency (i.e. + not needed after installation). + """ + + requested = False + """A boolean that indicates whether the ``REQUESTED`` metadata file is + present (in other words, whether the package was installed by user + request or it was installed as a dependency).""" + + def __init__(self, metadata): + """ + Initialise an instance. + :param metadata: The instance of :class:`Metadata` describing this + distribution. + """ + self.metadata = metadata + self.name = metadata.name + self.key = self.name.lower() # for case-insensitive comparisons + self.version = metadata.version + self.locator = None + self.digest = None + self.extras = None # additional features requested + self.context = None # environment marker overrides + self.download_urls = set() + self.digests = {} + + @property + def source_url(self): + """ + The source archive download URL for this distribution. + """ + return self.metadata.source_url + + download_url = source_url # Backward compatibility + + @property + def name_and_version(self): + """ + A utility property which displays the name and version in parentheses. + """ + return '%s (%s)' % (self.name, self.version) + + @property + def provides(self): + """ + A set of distribution names and versions provided by this distribution. + :return: A set of "name (version)" strings. + """ + plist = self.metadata.provides + s = '%s (%s)' % (self.name, self.version) + if s not in plist: + plist.append(s) + return plist + + def _get_requirements(self, req_attr): + md = self.metadata + logger.debug('Getting requirements from metadata %r', md.todict()) + reqts = getattr(md, req_attr) + return set(md.get_requirements(reqts, extras=self.extras, + env=self.context)) + + @property + def run_requires(self): + return self._get_requirements('run_requires') + + @property + def meta_requires(self): + return self._get_requirements('meta_requires') + + @property + def build_requires(self): + return self._get_requirements('build_requires') + + @property + def test_requires(self): + return self._get_requirements('test_requires') + + @property + def dev_requires(self): + return self._get_requirements('dev_requires') + + def matches_requirement(self, req): + """ + Say if this instance matches (fulfills) a requirement. + :param req: The requirement to match. + :rtype req: str + :return: True if it matches, else False. + """ + # Requirement may contain extras - parse to lose those + # from what's passed to the matcher + r = parse_requirement(req) + scheme = get_scheme(self.metadata.scheme) + try: + matcher = scheme.matcher(r.requirement) + except UnsupportedVersionError: + # XXX compat-mode if cannot read the version + logger.warning('could not read version %r - using name only', + req) + name = req.split()[0] + matcher = scheme.matcher(name) + + name = matcher.key # case-insensitive + + result = False + for p in self.provides: + p_name, p_ver = parse_name_and_version(p) + if p_name != name: + continue + try: + result = matcher.match(p_ver) + break + except UnsupportedVersionError: + pass + return result + + def __repr__(self): + """ + Return a textual representation of this instance, + """ + if self.source_url: + suffix = ' [%s]' % self.source_url + else: + suffix = '' + return '' % (self.name, self.version, suffix) + + def __eq__(self, other): + """ + See if this distribution is the same as another. + :param other: The distribution to compare with. To be equal to one + another. distributions must have the same type, name, + version and source_url. + :return: True if it is the same, else False. + """ + if type(other) is not type(self): + result = False + else: + result = (self.name == other.name and + self.version == other.version and + self.source_url == other.source_url) + return result + + def __hash__(self): + """ + Compute hash in a way which matches the equality test. + """ + return hash(self.name) + hash(self.version) + hash(self.source_url) + + +class BaseInstalledDistribution(Distribution): + """ + This is the base class for installed distributions (whether PEP 376 or + legacy). + """ + + hasher = None + + def __init__(self, metadata, path, env=None): + """ + Initialise an instance. + :param metadata: An instance of :class:`Metadata` which describes the + distribution. This will normally have been initialised + from a metadata file in the ``path``. + :param path: The path of the ``.dist-info`` or ``.egg-info`` + directory for the distribution. + :param env: This is normally the :class:`DistributionPath` + instance where this distribution was found. + """ + super(BaseInstalledDistribution, self).__init__(metadata) + self.path = path + self.dist_path = env + + def get_hash(self, data, hasher=None): + """ + Get the hash of some data, using a particular hash algorithm, if + specified. + + :param data: The data to be hashed. + :type data: bytes + :param hasher: The name of a hash implementation, supported by hashlib, + or ``None``. Examples of valid values are ``'sha1'``, + ``'sha224'``, ``'sha384'``, '``sha256'``, ``'md5'`` and + ``'sha512'``. If no hasher is specified, the ``hasher`` + attribute of the :class:`InstalledDistribution` instance + is used. If the hasher is determined to be ``None``, MD5 + is used as the hashing algorithm. + :returns: The hash of the data. If a hasher was explicitly specified, + the returned hash will be prefixed with the specified hasher + followed by '='. + :rtype: str + """ + if hasher is None: + hasher = self.hasher + if hasher is None: + hasher = hashlib.md5 + prefix = '' + else: + hasher = getattr(hashlib, hasher) + prefix = '%s=' % self.hasher + digest = hasher(data).digest() + digest = base64.urlsafe_b64encode(digest).rstrip(b'=').decode('ascii') + return '%s%s' % (prefix, digest) + + +class InstalledDistribution(BaseInstalledDistribution): + """ + Created with the *path* of the ``.dist-info`` directory provided to the + constructor. It reads the metadata contained in ``pydist.json`` when it is + instantiated., or uses a passed in Metadata instance (useful for when + dry-run mode is being used). + """ + + hasher = 'sha256' + + def __init__(self, path, metadata=None, env=None): + self.modules = [] + self.finder = finder = resources.finder_for_path(path) + if finder is None: + raise ValueError('finder unavailable for %s' % path) + if env and env._cache_enabled and path in env._cache.path: + metadata = env._cache.path[path].metadata + elif metadata is None: + r = finder.find(METADATA_FILENAME) + # Temporary - for Wheel 0.23 support + if r is None: + r = finder.find(WHEEL_METADATA_FILENAME) + # Temporary - for legacy support + if r is None: + r = finder.find(LEGACY_METADATA_FILENAME) + if r is None: + raise ValueError('no %s found in %s' % (METADATA_FILENAME, + path)) + with contextlib.closing(r.as_stream()) as stream: + metadata = Metadata(fileobj=stream, scheme='legacy') + + super(InstalledDistribution, self).__init__(metadata, path, env) + + if env and env._cache_enabled: + env._cache.add(self) + + r = finder.find('REQUESTED') + self.requested = r is not None + p = os.path.join(path, 'top_level.txt') + if os.path.exists(p): + with open(p, 'rb') as f: + data = f.read().decode('utf-8') + self.modules = data.splitlines() + + def __repr__(self): + return '' % ( + self.name, self.version, self.path) + + def __str__(self): + return "%s %s" % (self.name, self.version) + + def _get_records(self): + """ + Get the list of installed files for the distribution + :return: A list of tuples of path, hash and size. Note that hash and + size might be ``None`` for some entries. The path is exactly + as stored in the file (which is as in PEP 376). + """ + results = [] + r = self.get_distinfo_resource('RECORD') + with contextlib.closing(r.as_stream()) as stream: + with CSVReader(stream=stream) as record_reader: + # Base location is parent dir of .dist-info dir + #base_location = os.path.dirname(self.path) + #base_location = os.path.abspath(base_location) + for row in record_reader: + missing = [None for i in range(len(row), 3)] + path, checksum, size = row + missing + #if not os.path.isabs(path): + # path = path.replace('/', os.sep) + # path = os.path.join(base_location, path) + results.append((path, checksum, size)) + return results + + @cached_property + def exports(self): + """ + Return the information exported by this distribution. + :return: A dictionary of exports, mapping an export category to a dict + of :class:`ExportEntry` instances describing the individual + export entries, and keyed by name. + """ + result = {} + r = self.get_distinfo_resource(EXPORTS_FILENAME) + if r: + result = self.read_exports() + return result + + def read_exports(self): + """ + Read exports data from a file in .ini format. + + :return: A dictionary of exports, mapping an export category to a list + of :class:`ExportEntry` instances describing the individual + export entries. + """ + result = {} + r = self.get_distinfo_resource(EXPORTS_FILENAME) + if r: + with contextlib.closing(r.as_stream()) as stream: + result = read_exports(stream) + return result + + def write_exports(self, exports): + """ + Write a dictionary of exports to a file in .ini format. + :param exports: A dictionary of exports, mapping an export category to + a list of :class:`ExportEntry` instances describing the + individual export entries. + """ + rf = self.get_distinfo_file(EXPORTS_FILENAME) + with open(rf, 'w') as f: + write_exports(exports, f) + + def get_resource_path(self, relative_path): + """ + NOTE: This API may change in the future. + + Return the absolute path to a resource file with the given relative + path. + + :param relative_path: The path, relative to .dist-info, of the resource + of interest. + :return: The absolute path where the resource is to be found. + """ + r = self.get_distinfo_resource('RESOURCES') + with contextlib.closing(r.as_stream()) as stream: + with CSVReader(stream=stream) as resources_reader: + for relative, destination in resources_reader: + if relative == relative_path: + return destination + raise KeyError('no resource file with relative path %r ' + 'is installed' % relative_path) + + def list_installed_files(self): + """ + Iterates over the ``RECORD`` entries and returns a tuple + ``(path, hash, size)`` for each line. + + :returns: iterator of (path, hash, size) + """ + for result in self._get_records(): + yield result + + def write_installed_files(self, paths, prefix, dry_run=False): + """ + Writes the ``RECORD`` file, using the ``paths`` iterable passed in. Any + existing ``RECORD`` file is silently overwritten. + + prefix is used to determine when to write absolute paths. + """ + prefix = os.path.join(prefix, '') + base = os.path.dirname(self.path) + base_under_prefix = base.startswith(prefix) + base = os.path.join(base, '') + record_path = self.get_distinfo_file('RECORD') + logger.info('creating %s', record_path) + if dry_run: + return None + with CSVWriter(record_path) as writer: + for path in paths: + if os.path.isdir(path) or path.endswith(('.pyc', '.pyo')): + # do not put size and hash, as in PEP-376 + hash_value = size = '' + else: + size = '%d' % os.path.getsize(path) + with open(path, 'rb') as fp: + hash_value = self.get_hash(fp.read()) + if path.startswith(base) or (base_under_prefix and + path.startswith(prefix)): + path = os.path.relpath(path, base) + writer.writerow((path, hash_value, size)) + + # add the RECORD file itself + if record_path.startswith(base): + record_path = os.path.relpath(record_path, base) + writer.writerow((record_path, '', '')) + return record_path + + def check_installed_files(self): + """ + Checks that the hashes and sizes of the files in ``RECORD`` are + matched by the files themselves. Returns a (possibly empty) list of + mismatches. Each entry in the mismatch list will be a tuple consisting + of the path, 'exists', 'size' or 'hash' according to what didn't match + (existence is checked first, then size, then hash), the expected + value and the actual value. + """ + mismatches = [] + base = os.path.dirname(self.path) + record_path = self.get_distinfo_file('RECORD') + for path, hash_value, size in self.list_installed_files(): + if not os.path.isabs(path): + path = os.path.join(base, path) + if path == record_path: + continue + if not os.path.exists(path): + mismatches.append((path, 'exists', True, False)) + elif os.path.isfile(path): + actual_size = str(os.path.getsize(path)) + if size and actual_size != size: + mismatches.append((path, 'size', size, actual_size)) + elif hash_value: + if '=' in hash_value: + hasher = hash_value.split('=', 1)[0] + else: + hasher = None + + with open(path, 'rb') as f: + actual_hash = self.get_hash(f.read(), hasher) + if actual_hash != hash_value: + mismatches.append((path, 'hash', hash_value, actual_hash)) + return mismatches + + @cached_property + def shared_locations(self): + """ + A dictionary of shared locations whose keys are in the set 'prefix', + 'purelib', 'platlib', 'scripts', 'headers', 'data' and 'namespace'. + The corresponding value is the absolute path of that category for + this distribution, and takes into account any paths selected by the + user at installation time (e.g. via command-line arguments). In the + case of the 'namespace' key, this would be a list of absolute paths + for the roots of namespace packages in this distribution. + + The first time this property is accessed, the relevant information is + read from the SHARED file in the .dist-info directory. + """ + result = {} + shared_path = os.path.join(self.path, 'SHARED') + if os.path.isfile(shared_path): + with codecs.open(shared_path, 'r', encoding='utf-8') as f: + lines = f.read().splitlines() + for line in lines: + key, value = line.split('=', 1) + if key == 'namespace': + result.setdefault(key, []).append(value) + else: + result[key] = value + return result + + def write_shared_locations(self, paths, dry_run=False): + """ + Write shared location information to the SHARED file in .dist-info. + :param paths: A dictionary as described in the documentation for + :meth:`shared_locations`. + :param dry_run: If True, the action is logged but no file is actually + written. + :return: The path of the file written to. + """ + shared_path = os.path.join(self.path, 'SHARED') + logger.info('creating %s', shared_path) + if dry_run: + return None + lines = [] + for key in ('prefix', 'lib', 'headers', 'scripts', 'data'): + path = paths[key] + if os.path.isdir(paths[key]): + lines.append('%s=%s' % (key, path)) + for ns in paths.get('namespace', ()): + lines.append('namespace=%s' % ns) + + with codecs.open(shared_path, 'w', encoding='utf-8') as f: + f.write('\n'.join(lines)) + return shared_path + + def get_distinfo_resource(self, path): + if path not in DIST_FILES: + raise DistlibException('invalid path for a dist-info file: ' + '%r at %r' % (path, self.path)) + finder = resources.finder_for_path(self.path) + if finder is None: + raise DistlibException('Unable to get a finder for %s' % self.path) + return finder.find(path) + + def get_distinfo_file(self, path): + """ + Returns a path located under the ``.dist-info`` directory. Returns a + string representing the path. + + :parameter path: a ``'/'``-separated path relative to the + ``.dist-info`` directory or an absolute path; + If *path* is an absolute path and doesn't start + with the ``.dist-info`` directory path, + a :class:`DistlibException` is raised + :type path: str + :rtype: str + """ + # Check if it is an absolute path # XXX use relpath, add tests + if path.find(os.sep) >= 0: + # it's an absolute path? + distinfo_dirname, path = path.split(os.sep)[-2:] + if distinfo_dirname != self.path.split(os.sep)[-1]: + raise DistlibException( + 'dist-info file %r does not belong to the %r %s ' + 'distribution' % (path, self.name, self.version)) + + # The file must be relative + if path not in DIST_FILES: + raise DistlibException('invalid path for a dist-info file: ' + '%r at %r' % (path, self.path)) + + return os.path.join(self.path, path) + + def list_distinfo_files(self): + """ + Iterates over the ``RECORD`` entries and returns paths for each line if + the path is pointing to a file located in the ``.dist-info`` directory + or one of its subdirectories. + + :returns: iterator of paths + """ + base = os.path.dirname(self.path) + for path, checksum, size in self._get_records(): + # XXX add separator or use real relpath algo + if not os.path.isabs(path): + path = os.path.join(base, path) + if path.startswith(self.path): + yield path + + def __eq__(self, other): + return (isinstance(other, InstalledDistribution) and + self.path == other.path) + + # See http://docs.python.org/reference/datamodel#object.__hash__ + __hash__ = object.__hash__ + + +class EggInfoDistribution(BaseInstalledDistribution): + """Created with the *path* of the ``.egg-info`` directory or file provided + to the constructor. It reads the metadata contained in the file itself, or + if the given path happens to be a directory, the metadata is read from the + file ``PKG-INFO`` under that directory.""" + + requested = True # as we have no way of knowing, assume it was + shared_locations = {} + + def __init__(self, path, env=None): + def set_name_and_version(s, n, v): + s.name = n + s.key = n.lower() # for case-insensitive comparisons + s.version = v + + self.path = path + self.dist_path = env + if env and env._cache_enabled and path in env._cache_egg.path: + metadata = env._cache_egg.path[path].metadata + set_name_and_version(self, metadata.name, metadata.version) + else: + metadata = self._get_metadata(path) + + # Need to be set before caching + set_name_and_version(self, metadata.name, metadata.version) + + if env and env._cache_enabled: + env._cache_egg.add(self) + super(EggInfoDistribution, self).__init__(metadata, path, env) + + def _get_metadata(self, path): + requires = None + + def parse_requires_data(data): + """Create a list of dependencies from a requires.txt file. + + *data*: the contents of a setuptools-produced requires.txt file. + """ + reqs = [] + lines = data.splitlines() + for line in lines: + line = line.strip() + if line.startswith('['): + logger.warning('Unexpected line: quitting requirement scan: %r', + line) + break + r = parse_requirement(line) + if not r: + logger.warning('Not recognised as a requirement: %r', line) + continue + if r.extras: + logger.warning('extra requirements in requires.txt are ' + 'not supported') + if not r.constraints: + reqs.append(r.name) + else: + cons = ', '.join('%s%s' % c for c in r.constraints) + reqs.append('%s (%s)' % (r.name, cons)) + return reqs + + def parse_requires_path(req_path): + """Create a list of dependencies from a requires.txt file. + + *req_path*: the path to a setuptools-produced requires.txt file. + """ + + reqs = [] + try: + with codecs.open(req_path, 'r', 'utf-8') as fp: + reqs = parse_requires_data(fp.read()) + except IOError: + pass + return reqs + + tl_path = tl_data = None + if path.endswith('.egg'): + if os.path.isdir(path): + p = os.path.join(path, 'EGG-INFO') + meta_path = os.path.join(p, 'PKG-INFO') + metadata = Metadata(path=meta_path, scheme='legacy') + req_path = os.path.join(p, 'requires.txt') + tl_path = os.path.join(p, 'top_level.txt') + requires = parse_requires_path(req_path) + else: + # FIXME handle the case where zipfile is not available + zipf = zipimport.zipimporter(path) + fileobj = StringIO( + zipf.get_data('EGG-INFO/PKG-INFO').decode('utf8')) + metadata = Metadata(fileobj=fileobj, scheme='legacy') + try: + data = zipf.get_data('EGG-INFO/requires.txt') + tl_data = zipf.get_data('EGG-INFO/top_level.txt').decode('utf-8') + requires = parse_requires_data(data.decode('utf-8')) + except IOError: + requires = None + elif path.endswith('.egg-info'): + if os.path.isdir(path): + req_path = os.path.join(path, 'requires.txt') + requires = parse_requires_path(req_path) + path = os.path.join(path, 'PKG-INFO') + tl_path = os.path.join(path, 'top_level.txt') + metadata = Metadata(path=path, scheme='legacy') + else: + raise DistlibException('path must end with .egg-info or .egg, ' + 'got %r' % path) + + if requires: + metadata.add_requirements(requires) + # look for top-level modules in top_level.txt, if present + if tl_data is None: + if tl_path is not None and os.path.exists(tl_path): + with open(tl_path, 'rb') as f: + tl_data = f.read().decode('utf-8') + if not tl_data: + tl_data = [] + else: + tl_data = tl_data.splitlines() + self.modules = tl_data + return metadata + + def __repr__(self): + return '' % ( + self.name, self.version, self.path) + + def __str__(self): + return "%s %s" % (self.name, self.version) + + def check_installed_files(self): + """ + Checks that the hashes and sizes of the files in ``RECORD`` are + matched by the files themselves. Returns a (possibly empty) list of + mismatches. Each entry in the mismatch list will be a tuple consisting + of the path, 'exists', 'size' or 'hash' according to what didn't match + (existence is checked first, then size, then hash), the expected + value and the actual value. + """ + mismatches = [] + record_path = os.path.join(self.path, 'installed-files.txt') + if os.path.exists(record_path): + for path, _, _ in self.list_installed_files(): + if path == record_path: + continue + if not os.path.exists(path): + mismatches.append((path, 'exists', True, False)) + return mismatches + + def list_installed_files(self): + """ + Iterates over the ``installed-files.txt`` entries and returns a tuple + ``(path, hash, size)`` for each line. + + :returns: a list of (path, hash, size) + """ + + def _md5(path): + f = open(path, 'rb') + try: + content = f.read() + finally: + f.close() + return hashlib.md5(content).hexdigest() + + def _size(path): + return os.stat(path).st_size + + record_path = os.path.join(self.path, 'installed-files.txt') + result = [] + if os.path.exists(record_path): + with codecs.open(record_path, 'r', encoding='utf-8') as f: + for line in f: + line = line.strip() + p = os.path.normpath(os.path.join(self.path, line)) + # "./" is present as a marker between installed files + # and installation metadata files + if not os.path.exists(p): + logger.warning('Non-existent file: %s', p) + if p.endswith(('.pyc', '.pyo')): + continue + #otherwise fall through and fail + if not os.path.isdir(p): + result.append((p, _md5(p), _size(p))) + result.append((record_path, None, None)) + return result + + def list_distinfo_files(self, absolute=False): + """ + Iterates over the ``installed-files.txt`` entries and returns paths for + each line if the path is pointing to a file located in the + ``.egg-info`` directory or one of its subdirectories. + + :parameter absolute: If *absolute* is ``True``, each returned path is + transformed into a local absolute path. Otherwise the + raw value from ``installed-files.txt`` is returned. + :type absolute: boolean + :returns: iterator of paths + """ + record_path = os.path.join(self.path, 'installed-files.txt') + if os.path.exists(record_path): + skip = True + with codecs.open(record_path, 'r', encoding='utf-8') as f: + for line in f: + line = line.strip() + if line == './': + skip = False + continue + if not skip: + p = os.path.normpath(os.path.join(self.path, line)) + if p.startswith(self.path): + if absolute: + yield p + else: + yield line + + def __eq__(self, other): + return (isinstance(other, EggInfoDistribution) and + self.path == other.path) + + # See http://docs.python.org/reference/datamodel#object.__hash__ + __hash__ = object.__hash__ + +new_dist_class = InstalledDistribution +old_dist_class = EggInfoDistribution + + +class DependencyGraph(object): + """ + Represents a dependency graph between distributions. + + The dependency relationships are stored in an ``adjacency_list`` that maps + distributions to a list of ``(other, label)`` tuples where ``other`` + is a distribution and the edge is labeled with ``label`` (i.e. the version + specifier, if such was provided). Also, for more efficient traversal, for + every distribution ``x``, a list of predecessors is kept in + ``reverse_list[x]``. An edge from distribution ``a`` to + distribution ``b`` means that ``a`` depends on ``b``. If any missing + dependencies are found, they are stored in ``missing``, which is a + dictionary that maps distributions to a list of requirements that were not + provided by any other distributions. + """ + + def __init__(self): + self.adjacency_list = {} + self.reverse_list = {} + self.missing = {} + + def add_distribution(self, distribution): + """Add the *distribution* to the graph. + + :type distribution: :class:`distutils2.database.InstalledDistribution` + or :class:`distutils2.database.EggInfoDistribution` + """ + self.adjacency_list[distribution] = [] + self.reverse_list[distribution] = [] + #self.missing[distribution] = [] + + def add_edge(self, x, y, label=None): + """Add an edge from distribution *x* to distribution *y* with the given + *label*. + + :type x: :class:`distutils2.database.InstalledDistribution` or + :class:`distutils2.database.EggInfoDistribution` + :type y: :class:`distutils2.database.InstalledDistribution` or + :class:`distutils2.database.EggInfoDistribution` + :type label: ``str`` or ``None`` + """ + self.adjacency_list[x].append((y, label)) + # multiple edges are allowed, so be careful + if x not in self.reverse_list[y]: + self.reverse_list[y].append(x) + + def add_missing(self, distribution, requirement): + """ + Add a missing *requirement* for the given *distribution*. + + :type distribution: :class:`distutils2.database.InstalledDistribution` + or :class:`distutils2.database.EggInfoDistribution` + :type requirement: ``str`` + """ + logger.debug('%s missing %r', distribution, requirement) + self.missing.setdefault(distribution, []).append(requirement) + + def _repr_dist(self, dist): + return '%s %s' % (dist.name, dist.version) + + def repr_node(self, dist, level=1): + """Prints only a subgraph""" + output = [self._repr_dist(dist)] + for other, label in self.adjacency_list[dist]: + dist = self._repr_dist(other) + if label is not None: + dist = '%s [%s]' % (dist, label) + output.append(' ' * level + str(dist)) + suboutput = self.repr_node(other, level + 1) + subs = suboutput.split('\n') + output.extend(subs[1:]) + return '\n'.join(output) + + def to_dot(self, f, skip_disconnected=True): + """Writes a DOT output for the graph to the provided file *f*. + + If *skip_disconnected* is set to ``True``, then all distributions + that are not dependent on any other distribution are skipped. + + :type f: has to support ``file``-like operations + :type skip_disconnected: ``bool`` + """ + disconnected = [] + + f.write("digraph dependencies {\n") + for dist, adjs in self.adjacency_list.items(): + if len(adjs) == 0 and not skip_disconnected: + disconnected.append(dist) + for other, label in adjs: + if not label is None: + f.write('"%s" -> "%s" [label="%s"]\n' % + (dist.name, other.name, label)) + else: + f.write('"%s" -> "%s"\n' % (dist.name, other.name)) + if not skip_disconnected and len(disconnected) > 0: + f.write('subgraph disconnected {\n') + f.write('label = "Disconnected"\n') + f.write('bgcolor = red\n') + + for dist in disconnected: + f.write('"%s"' % dist.name) + f.write('\n') + f.write('}\n') + f.write('}\n') + + def topological_sort(self): + """ + Perform a topological sort of the graph. + :return: A tuple, the first element of which is a topologically sorted + list of distributions, and the second element of which is a + list of distributions that cannot be sorted because they have + circular dependencies and so form a cycle. + """ + result = [] + # Make a shallow copy of the adjacency list + alist = {} + for k, v in self.adjacency_list.items(): + alist[k] = v[:] + while True: + # See what we can remove in this run + to_remove = [] + for k, v in list(alist.items())[:]: + if not v: + to_remove.append(k) + del alist[k] + if not to_remove: + # What's left in alist (if anything) is a cycle. + break + # Remove from the adjacency list of others + for k, v in alist.items(): + alist[k] = [(d, r) for d, r in v if d not in to_remove] + logger.debug('Moving to result: %s', + ['%s (%s)' % (d.name, d.version) for d in to_remove]) + result.extend(to_remove) + return result, list(alist.keys()) + + def __repr__(self): + """Representation of the graph""" + output = [] + for dist, adjs in self.adjacency_list.items(): + output.append(self.repr_node(dist)) + return '\n'.join(output) + + +def make_graph(dists, scheme='default'): + """Makes a dependency graph from the given distributions. + + :parameter dists: a list of distributions + :type dists: list of :class:`distutils2.database.InstalledDistribution` and + :class:`distutils2.database.EggInfoDistribution` instances + :rtype: a :class:`DependencyGraph` instance + """ + scheme = get_scheme(scheme) + graph = DependencyGraph() + provided = {} # maps names to lists of (version, dist) tuples + + # first, build the graph and find out what's provided + for dist in dists: + graph.add_distribution(dist) + + for p in dist.provides: + name, version = parse_name_and_version(p) + logger.debug('Add to provided: %s, %s, %s', name, version, dist) + provided.setdefault(name, []).append((version, dist)) + + # now make the edges + for dist in dists: + requires = (dist.run_requires | dist.meta_requires | + dist.build_requires | dist.dev_requires) + for req in requires: + try: + matcher = scheme.matcher(req) + except UnsupportedVersionError: + # XXX compat-mode if cannot read the version + logger.warning('could not read version %r - using name only', + req) + name = req.split()[0] + matcher = scheme.matcher(name) + + name = matcher.key # case-insensitive + + matched = False + if name in provided: + for version, provider in provided[name]: + try: + match = matcher.match(version) + except UnsupportedVersionError: + match = False + + if match: + graph.add_edge(dist, provider, req) + matched = True + break + if not matched: + graph.add_missing(dist, req) + return graph + + +def get_dependent_dists(dists, dist): + """Recursively generate a list of distributions from *dists* that are + dependent on *dist*. + + :param dists: a list of distributions + :param dist: a distribution, member of *dists* for which we are interested + """ + if dist not in dists: + raise DistlibException('given distribution %r is not a member ' + 'of the list' % dist.name) + graph = make_graph(dists) + + dep = [dist] # dependent distributions + todo = graph.reverse_list[dist] # list of nodes we should inspect + + while todo: + d = todo.pop() + dep.append(d) + for succ in graph.reverse_list[d]: + if succ not in dep: + todo.append(succ) + + dep.pop(0) # remove dist from dep, was there to prevent infinite loops + return dep + + +def get_required_dists(dists, dist): + """Recursively generate a list of distributions from *dists* that are + required by *dist*. + + :param dists: a list of distributions + :param dist: a distribution, member of *dists* for which we are interested + """ + if dist not in dists: + raise DistlibException('given distribution %r is not a member ' + 'of the list' % dist.name) + graph = make_graph(dists) + + req = [] # required distributions + todo = graph.adjacency_list[dist] # list of nodes we should inspect + + while todo: + d = todo.pop()[0] + req.append(d) + for pred in graph.adjacency_list[d]: + if pred not in req: + todo.append(pred) + + return req + + +def make_dist(name, version, **kwargs): + """ + A convenience method for making a dist given just a name and version. + """ + summary = kwargs.pop('summary', 'Placeholder for summary') + md = Metadata(**kwargs) + md.name = name + md.version = version + md.summary = summary or 'Placeholder for summary' + return Distribution(md) diff --git a/venv/Lib/site-packages/pip/_vendor/distlib/index.py b/venv/Lib/site-packages/pip/_vendor/distlib/index.py new file mode 100644 index 0000000..7a87cdc --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/distlib/index.py @@ -0,0 +1,516 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2013 Vinay Sajip. +# Licensed to the Python Software Foundation under a contributor agreement. +# See LICENSE.txt and CONTRIBUTORS.txt. +# +import hashlib +import logging +import os +import shutil +import subprocess +import tempfile +try: + from threading import Thread +except ImportError: + from dummy_threading import Thread + +from . import DistlibException +from .compat import (HTTPBasicAuthHandler, Request, HTTPPasswordMgr, + urlparse, build_opener, string_types) +from .util import cached_property, zip_dir, ServerProxy + +logger = logging.getLogger(__name__) + +DEFAULT_INDEX = 'https://pypi.org/pypi' +DEFAULT_REALM = 'pypi' + +class PackageIndex(object): + """ + This class represents a package index compatible with PyPI, the Python + Package Index. + """ + + boundary = b'----------ThIs_Is_tHe_distlib_index_bouNdaRY_$' + + def __init__(self, url=None): + """ + Initialise an instance. + + :param url: The URL of the index. If not specified, the URL for PyPI is + used. + """ + self.url = url or DEFAULT_INDEX + self.read_configuration() + scheme, netloc, path, params, query, frag = urlparse(self.url) + if params or query or frag or scheme not in ('http', 'https'): + raise DistlibException('invalid repository: %s' % self.url) + self.password_handler = None + self.ssl_verifier = None + self.gpg = None + self.gpg_home = None + with open(os.devnull, 'w') as sink: + # Use gpg by default rather than gpg2, as gpg2 insists on + # prompting for passwords + for s in ('gpg', 'gpg2'): + try: + rc = subprocess.check_call([s, '--version'], stdout=sink, + stderr=sink) + if rc == 0: + self.gpg = s + break + except OSError: + pass + + def _get_pypirc_command(self): + """ + Get the distutils command for interacting with PyPI configurations. + :return: the command. + """ + from distutils.core import Distribution + from distutils.config import PyPIRCCommand + d = Distribution() + return PyPIRCCommand(d) + + def read_configuration(self): + """ + Read the PyPI access configuration as supported by distutils, getting + PyPI to do the actual work. This populates ``username``, ``password``, + ``realm`` and ``url`` attributes from the configuration. + """ + # get distutils to do the work + c = self._get_pypirc_command() + c.repository = self.url + cfg = c._read_pypirc() + self.username = cfg.get('username') + self.password = cfg.get('password') + self.realm = cfg.get('realm', 'pypi') + self.url = cfg.get('repository', self.url) + + def save_configuration(self): + """ + Save the PyPI access configuration. You must have set ``username`` and + ``password`` attributes before calling this method. + + Again, distutils is used to do the actual work. + """ + self.check_credentials() + # get distutils to do the work + c = self._get_pypirc_command() + c._store_pypirc(self.username, self.password) + + def check_credentials(self): + """ + Check that ``username`` and ``password`` have been set, and raise an + exception if not. + """ + if self.username is None or self.password is None: + raise DistlibException('username and password must be set') + pm = HTTPPasswordMgr() + _, netloc, _, _, _, _ = urlparse(self.url) + pm.add_password(self.realm, netloc, self.username, self.password) + self.password_handler = HTTPBasicAuthHandler(pm) + + def register(self, metadata): + """ + Register a distribution on PyPI, using the provided metadata. + + :param metadata: A :class:`Metadata` instance defining at least a name + and version number for the distribution to be + registered. + :return: The HTTP response received from PyPI upon submission of the + request. + """ + self.check_credentials() + metadata.validate() + d = metadata.todict() + d[':action'] = 'verify' + request = self.encode_request(d.items(), []) + response = self.send_request(request) + d[':action'] = 'submit' + request = self.encode_request(d.items(), []) + return self.send_request(request) + + def _reader(self, name, stream, outbuf): + """ + Thread runner for reading lines of from a subprocess into a buffer. + + :param name: The logical name of the stream (used for logging only). + :param stream: The stream to read from. This will typically a pipe + connected to the output stream of a subprocess. + :param outbuf: The list to append the read lines to. + """ + while True: + s = stream.readline() + if not s: + break + s = s.decode('utf-8').rstrip() + outbuf.append(s) + logger.debug('%s: %s' % (name, s)) + stream.close() + + def get_sign_command(self, filename, signer, sign_password, + keystore=None): + """ + Return a suitable command for signing a file. + + :param filename: The pathname to the file to be signed. + :param signer: The identifier of the signer of the file. + :param sign_password: The passphrase for the signer's + private key used for signing. + :param keystore: The path to a directory which contains the keys + used in verification. If not specified, the + instance's ``gpg_home`` attribute is used instead. + :return: The signing command as a list suitable to be + passed to :class:`subprocess.Popen`. + """ + cmd = [self.gpg, '--status-fd', '2', '--no-tty'] + if keystore is None: + keystore = self.gpg_home + if keystore: + cmd.extend(['--homedir', keystore]) + if sign_password is not None: + cmd.extend(['--batch', '--passphrase-fd', '0']) + td = tempfile.mkdtemp() + sf = os.path.join(td, os.path.basename(filename) + '.asc') + cmd.extend(['--detach-sign', '--armor', '--local-user', + signer, '--output', sf, filename]) + logger.debug('invoking: %s', ' '.join(cmd)) + return cmd, sf + + def run_command(self, cmd, input_data=None): + """ + Run a command in a child process , passing it any input data specified. + + :param cmd: The command to run. + :param input_data: If specified, this must be a byte string containing + data to be sent to the child process. + :return: A tuple consisting of the subprocess' exit code, a list of + lines read from the subprocess' ``stdout``, and a list of + lines read from the subprocess' ``stderr``. + """ + kwargs = { + 'stdout': subprocess.PIPE, + 'stderr': subprocess.PIPE, + } + if input_data is not None: + kwargs['stdin'] = subprocess.PIPE + stdout = [] + stderr = [] + p = subprocess.Popen(cmd, **kwargs) + # We don't use communicate() here because we may need to + # get clever with interacting with the command + t1 = Thread(target=self._reader, args=('stdout', p.stdout, stdout)) + t1.start() + t2 = Thread(target=self._reader, args=('stderr', p.stderr, stderr)) + t2.start() + if input_data is not None: + p.stdin.write(input_data) + p.stdin.close() + + p.wait() + t1.join() + t2.join() + return p.returncode, stdout, stderr + + def sign_file(self, filename, signer, sign_password, keystore=None): + """ + Sign a file. + + :param filename: The pathname to the file to be signed. + :param signer: The identifier of the signer of the file. + :param sign_password: The passphrase for the signer's + private key used for signing. + :param keystore: The path to a directory which contains the keys + used in signing. If not specified, the instance's + ``gpg_home`` attribute is used instead. + :return: The absolute pathname of the file where the signature is + stored. + """ + cmd, sig_file = self.get_sign_command(filename, signer, sign_password, + keystore) + rc, stdout, stderr = self.run_command(cmd, + sign_password.encode('utf-8')) + if rc != 0: + raise DistlibException('sign command failed with error ' + 'code %s' % rc) + return sig_file + + def upload_file(self, metadata, filename, signer=None, sign_password=None, + filetype='sdist', pyversion='source', keystore=None): + """ + Upload a release file to the index. + + :param metadata: A :class:`Metadata` instance defining at least a name + and version number for the file to be uploaded. + :param filename: The pathname of the file to be uploaded. + :param signer: The identifier of the signer of the file. + :param sign_password: The passphrase for the signer's + private key used for signing. + :param filetype: The type of the file being uploaded. This is the + distutils command which produced that file, e.g. + ``sdist`` or ``bdist_wheel``. + :param pyversion: The version of Python which the release relates + to. For code compatible with any Python, this would + be ``source``, otherwise it would be e.g. ``3.2``. + :param keystore: The path to a directory which contains the keys + used in signing. If not specified, the instance's + ``gpg_home`` attribute is used instead. + :return: The HTTP response received from PyPI upon submission of the + request. + """ + self.check_credentials() + if not os.path.exists(filename): + raise DistlibException('not found: %s' % filename) + metadata.validate() + d = metadata.todict() + sig_file = None + if signer: + if not self.gpg: + logger.warning('no signing program available - not signed') + else: + sig_file = self.sign_file(filename, signer, sign_password, + keystore) + with open(filename, 'rb') as f: + file_data = f.read() + md5_digest = hashlib.md5(file_data).hexdigest() + sha256_digest = hashlib.sha256(file_data).hexdigest() + d.update({ + ':action': 'file_upload', + 'protocol_version': '1', + 'filetype': filetype, + 'pyversion': pyversion, + 'md5_digest': md5_digest, + 'sha256_digest': sha256_digest, + }) + files = [('content', os.path.basename(filename), file_data)] + if sig_file: + with open(sig_file, 'rb') as f: + sig_data = f.read() + files.append(('gpg_signature', os.path.basename(sig_file), + sig_data)) + shutil.rmtree(os.path.dirname(sig_file)) + request = self.encode_request(d.items(), files) + return self.send_request(request) + + def upload_documentation(self, metadata, doc_dir): + """ + Upload documentation to the index. + + :param metadata: A :class:`Metadata` instance defining at least a name + and version number for the documentation to be + uploaded. + :param doc_dir: The pathname of the directory which contains the + documentation. This should be the directory that + contains the ``index.html`` for the documentation. + :return: The HTTP response received from PyPI upon submission of the + request. + """ + self.check_credentials() + if not os.path.isdir(doc_dir): + raise DistlibException('not a directory: %r' % doc_dir) + fn = os.path.join(doc_dir, 'index.html') + if not os.path.exists(fn): + raise DistlibException('not found: %r' % fn) + metadata.validate() + name, version = metadata.name, metadata.version + zip_data = zip_dir(doc_dir).getvalue() + fields = [(':action', 'doc_upload'), + ('name', name), ('version', version)] + files = [('content', name, zip_data)] + request = self.encode_request(fields, files) + return self.send_request(request) + + def get_verify_command(self, signature_filename, data_filename, + keystore=None): + """ + Return a suitable command for verifying a file. + + :param signature_filename: The pathname to the file containing the + signature. + :param data_filename: The pathname to the file containing the + signed data. + :param keystore: The path to a directory which contains the keys + used in verification. If not specified, the + instance's ``gpg_home`` attribute is used instead. + :return: The verifying command as a list suitable to be + passed to :class:`subprocess.Popen`. + """ + cmd = [self.gpg, '--status-fd', '2', '--no-tty'] + if keystore is None: + keystore = self.gpg_home + if keystore: + cmd.extend(['--homedir', keystore]) + cmd.extend(['--verify', signature_filename, data_filename]) + logger.debug('invoking: %s', ' '.join(cmd)) + return cmd + + def verify_signature(self, signature_filename, data_filename, + keystore=None): + """ + Verify a signature for a file. + + :param signature_filename: The pathname to the file containing the + signature. + :param data_filename: The pathname to the file containing the + signed data. + :param keystore: The path to a directory which contains the keys + used in verification. If not specified, the + instance's ``gpg_home`` attribute is used instead. + :return: True if the signature was verified, else False. + """ + if not self.gpg: + raise DistlibException('verification unavailable because gpg ' + 'unavailable') + cmd = self.get_verify_command(signature_filename, data_filename, + keystore) + rc, stdout, stderr = self.run_command(cmd) + if rc not in (0, 1): + raise DistlibException('verify command failed with error ' + 'code %s' % rc) + return rc == 0 + + def download_file(self, url, destfile, digest=None, reporthook=None): + """ + This is a convenience method for downloading a file from an URL. + Normally, this will be a file from the index, though currently + no check is made for this (i.e. a file can be downloaded from + anywhere). + + The method is just like the :func:`urlretrieve` function in the + standard library, except that it allows digest computation to be + done during download and checking that the downloaded data + matched any expected value. + + :param url: The URL of the file to be downloaded (assumed to be + available via an HTTP GET request). + :param destfile: The pathname where the downloaded file is to be + saved. + :param digest: If specified, this must be a (hasher, value) + tuple, where hasher is the algorithm used (e.g. + ``'md5'``) and ``value`` is the expected value. + :param reporthook: The same as for :func:`urlretrieve` in the + standard library. + """ + if digest is None: + digester = None + logger.debug('No digest specified') + else: + if isinstance(digest, (list, tuple)): + hasher, digest = digest + else: + hasher = 'md5' + digester = getattr(hashlib, hasher)() + logger.debug('Digest specified: %s' % digest) + # The following code is equivalent to urlretrieve. + # We need to do it this way so that we can compute the + # digest of the file as we go. + with open(destfile, 'wb') as dfp: + # addinfourl is not a context manager on 2.x + # so we have to use try/finally + sfp = self.send_request(Request(url)) + try: + headers = sfp.info() + blocksize = 8192 + size = -1 + read = 0 + blocknum = 0 + if "content-length" in headers: + size = int(headers["Content-Length"]) + if reporthook: + reporthook(blocknum, blocksize, size) + while True: + block = sfp.read(blocksize) + if not block: + break + read += len(block) + dfp.write(block) + if digester: + digester.update(block) + blocknum += 1 + if reporthook: + reporthook(blocknum, blocksize, size) + finally: + sfp.close() + + # check that we got the whole file, if we can + if size >= 0 and read < size: + raise DistlibException( + 'retrieval incomplete: got only %d out of %d bytes' + % (read, size)) + # if we have a digest, it must match. + if digester: + actual = digester.hexdigest() + if digest != actual: + raise DistlibException('%s digest mismatch for %s: expected ' + '%s, got %s' % (hasher, destfile, + digest, actual)) + logger.debug('Digest verified: %s', digest) + + def send_request(self, req): + """ + Send a standard library :class:`Request` to PyPI and return its + response. + + :param req: The request to send. + :return: The HTTP response from PyPI (a standard library HTTPResponse). + """ + handlers = [] + if self.password_handler: + handlers.append(self.password_handler) + if self.ssl_verifier: + handlers.append(self.ssl_verifier) + opener = build_opener(*handlers) + return opener.open(req) + + def encode_request(self, fields, files): + """ + Encode fields and files for posting to an HTTP server. + + :param fields: The fields to send as a list of (fieldname, value) + tuples. + :param files: The files to send as a list of (fieldname, filename, + file_bytes) tuple. + """ + # Adapted from packaging, which in turn was adapted from + # http://code.activestate.com/recipes/146306 + + parts = [] + boundary = self.boundary + for k, values in fields: + if not isinstance(values, (list, tuple)): + values = [values] + + for v in values: + parts.extend(( + b'--' + boundary, + ('Content-Disposition: form-data; name="%s"' % + k).encode('utf-8'), + b'', + v.encode('utf-8'))) + for key, filename, value in files: + parts.extend(( + b'--' + boundary, + ('Content-Disposition: form-data; name="%s"; filename="%s"' % + (key, filename)).encode('utf-8'), + b'', + value)) + + parts.extend((b'--' + boundary + b'--', b'')) + + body = b'\r\n'.join(parts) + ct = b'multipart/form-data; boundary=' + boundary + headers = { + 'Content-type': ct, + 'Content-length': str(len(body)) + } + return Request(self.url, body, headers) + + def search(self, terms, operator=None): + if isinstance(terms, string_types): + terms = {'name': terms} + rpc_proxy = ServerProxy(self.url, timeout=3.0) + try: + return rpc_proxy.search(terms, operator or 'and') + finally: + rpc_proxy('close')() diff --git a/venv/Lib/site-packages/pip/_vendor/distlib/locators.py b/venv/Lib/site-packages/pip/_vendor/distlib/locators.py new file mode 100644 index 0000000..12a1d06 --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/distlib/locators.py @@ -0,0 +1,1302 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2012-2015 Vinay Sajip. +# Licensed to the Python Software Foundation under a contributor agreement. +# See LICENSE.txt and CONTRIBUTORS.txt. +# + +import gzip +from io import BytesIO +import json +import logging +import os +import posixpath +import re +try: + import threading +except ImportError: # pragma: no cover + import dummy_threading as threading +import zlib + +from . import DistlibException +from .compat import (urljoin, urlparse, urlunparse, url2pathname, pathname2url, + queue, quote, unescape, string_types, build_opener, + HTTPRedirectHandler as BaseRedirectHandler, text_type, + Request, HTTPError, URLError) +from .database import Distribution, DistributionPath, make_dist +from .metadata import Metadata, MetadataInvalidError +from .util import (cached_property, parse_credentials, ensure_slash, + split_filename, get_project_data, parse_requirement, + parse_name_and_version, ServerProxy, normalize_name) +from .version import get_scheme, UnsupportedVersionError +from .wheel import Wheel, is_compatible + +logger = logging.getLogger(__name__) + +HASHER_HASH = re.compile(r'^(\w+)=([a-f0-9]+)') +CHARSET = re.compile(r';\s*charset\s*=\s*(.*)\s*$', re.I) +HTML_CONTENT_TYPE = re.compile('text/html|application/x(ht)?ml') +DEFAULT_INDEX = 'https://pypi.org/pypi' + +def get_all_distribution_names(url=None): + """ + Return all distribution names known by an index. + :param url: The URL of the index. + :return: A list of all known distribution names. + """ + if url is None: + url = DEFAULT_INDEX + client = ServerProxy(url, timeout=3.0) + try: + return client.list_packages() + finally: + client('close')() + +class RedirectHandler(BaseRedirectHandler): + """ + A class to work around a bug in some Python 3.2.x releases. + """ + # There's a bug in the base version for some 3.2.x + # (e.g. 3.2.2 on Ubuntu Oneiric). If a Location header + # returns e.g. /abc, it bails because it says the scheme '' + # is bogus, when actually it should use the request's + # URL for the scheme. See Python issue #13696. + def http_error_302(self, req, fp, code, msg, headers): + # Some servers (incorrectly) return multiple Location headers + # (so probably same goes for URI). Use first header. + newurl = None + for key in ('location', 'uri'): + if key in headers: + newurl = headers[key] + break + if newurl is None: # pragma: no cover + return + urlparts = urlparse(newurl) + if urlparts.scheme == '': + newurl = urljoin(req.get_full_url(), newurl) + if hasattr(headers, 'replace_header'): + headers.replace_header(key, newurl) + else: + headers[key] = newurl + return BaseRedirectHandler.http_error_302(self, req, fp, code, msg, + headers) + + http_error_301 = http_error_303 = http_error_307 = http_error_302 + +class Locator(object): + """ + A base class for locators - things that locate distributions. + """ + source_extensions = ('.tar.gz', '.tar.bz2', '.tar', '.zip', '.tgz', '.tbz') + binary_extensions = ('.egg', '.exe', '.whl') + excluded_extensions = ('.pdf',) + + # A list of tags indicating which wheels you want to match. The default + # value of None matches against the tags compatible with the running + # Python. If you want to match other values, set wheel_tags on a locator + # instance to a list of tuples (pyver, abi, arch) which you want to match. + wheel_tags = None + + downloadable_extensions = source_extensions + ('.whl',) + + def __init__(self, scheme='default'): + """ + Initialise an instance. + :param scheme: Because locators look for most recent versions, they + need to know the version scheme to use. This specifies + the current PEP-recommended scheme - use ``'legacy'`` + if you need to support existing distributions on PyPI. + """ + self._cache = {} + self.scheme = scheme + # Because of bugs in some of the handlers on some of the platforms, + # we use our own opener rather than just using urlopen. + self.opener = build_opener(RedirectHandler()) + # If get_project() is called from locate(), the matcher instance + # is set from the requirement passed to locate(). See issue #18 for + # why this can be useful to know. + self.matcher = None + self.errors = queue.Queue() + + def get_errors(self): + """ + Return any errors which have occurred. + """ + result = [] + while not self.errors.empty(): # pragma: no cover + try: + e = self.errors.get(False) + result.append(e) + except self.errors.Empty: + continue + self.errors.task_done() + return result + + def clear_errors(self): + """ + Clear any errors which may have been logged. + """ + # Just get the errors and throw them away + self.get_errors() + + def clear_cache(self): + self._cache.clear() + + def _get_scheme(self): + return self._scheme + + def _set_scheme(self, value): + self._scheme = value + + scheme = property(_get_scheme, _set_scheme) + + def _get_project(self, name): + """ + For a given project, get a dictionary mapping available versions to Distribution + instances. + + This should be implemented in subclasses. + + If called from a locate() request, self.matcher will be set to a + matcher for the requirement to satisfy, otherwise it will be None. + """ + raise NotImplementedError('Please implement in the subclass') + + def get_distribution_names(self): + """ + Return all the distribution names known to this locator. + """ + raise NotImplementedError('Please implement in the subclass') + + def get_project(self, name): + """ + For a given project, get a dictionary mapping available versions to Distribution + instances. + + This calls _get_project to do all the work, and just implements a caching layer on top. + """ + if self._cache is None: # pragma: no cover + result = self._get_project(name) + elif name in self._cache: + result = self._cache[name] + else: + self.clear_errors() + result = self._get_project(name) + self._cache[name] = result + return result + + def score_url(self, url): + """ + Give an url a score which can be used to choose preferred URLs + for a given project release. + """ + t = urlparse(url) + basename = posixpath.basename(t.path) + compatible = True + is_wheel = basename.endswith('.whl') + is_downloadable = basename.endswith(self.downloadable_extensions) + if is_wheel: + compatible = is_compatible(Wheel(basename), self.wheel_tags) + return (t.scheme == 'https', 'pypi.org' in t.netloc, + is_downloadable, is_wheel, compatible, basename) + + def prefer_url(self, url1, url2): + """ + Choose one of two URLs where both are candidates for distribution + archives for the same version of a distribution (for example, + .tar.gz vs. zip). + + The current implementation favours https:// URLs over http://, archives + from PyPI over those from other locations, wheel compatibility (if a + wheel) and then the archive name. + """ + result = url2 + if url1: + s1 = self.score_url(url1) + s2 = self.score_url(url2) + if s1 > s2: + result = url1 + if result != url2: + logger.debug('Not replacing %r with %r', url1, url2) + else: + logger.debug('Replacing %r with %r', url1, url2) + return result + + def split_filename(self, filename, project_name): + """ + Attempt to split a filename in project name, version and Python version. + """ + return split_filename(filename, project_name) + + def convert_url_to_download_info(self, url, project_name): + """ + See if a URL is a candidate for a download URL for a project (the URL + has typically been scraped from an HTML page). + + If it is, a dictionary is returned with keys "name", "version", + "filename" and "url"; otherwise, None is returned. + """ + def same_project(name1, name2): + return normalize_name(name1) == normalize_name(name2) + + result = None + scheme, netloc, path, params, query, frag = urlparse(url) + if frag.lower().startswith('egg='): # pragma: no cover + logger.debug('%s: version hint in fragment: %r', + project_name, frag) + m = HASHER_HASH.match(frag) + if m: + algo, digest = m.groups() + else: + algo, digest = None, None + origpath = path + if path and path[-1] == '/': # pragma: no cover + path = path[:-1] + if path.endswith('.whl'): + try: + wheel = Wheel(path) + if not is_compatible(wheel, self.wheel_tags): + logger.debug('Wheel not compatible: %s', path) + else: + if project_name is None: + include = True + else: + include = same_project(wheel.name, project_name) + if include: + result = { + 'name': wheel.name, + 'version': wheel.version, + 'filename': wheel.filename, + 'url': urlunparse((scheme, netloc, origpath, + params, query, '')), + 'python-version': ', '.join( + ['.'.join(list(v[2:])) for v in wheel.pyver]), + } + except Exception as e: # pragma: no cover + logger.warning('invalid path for wheel: %s', path) + elif not path.endswith(self.downloadable_extensions): # pragma: no cover + logger.debug('Not downloadable: %s', path) + else: # downloadable extension + path = filename = posixpath.basename(path) + for ext in self.downloadable_extensions: + if path.endswith(ext): + path = path[:-len(ext)] + t = self.split_filename(path, project_name) + if not t: # pragma: no cover + logger.debug('No match for project/version: %s', path) + else: + name, version, pyver = t + if not project_name or same_project(project_name, name): + result = { + 'name': name, + 'version': version, + 'filename': filename, + 'url': urlunparse((scheme, netloc, origpath, + params, query, '')), + #'packagetype': 'sdist', + } + if pyver: # pragma: no cover + result['python-version'] = pyver + break + if result and algo: + result['%s_digest' % algo] = digest + return result + + def _get_digest(self, info): + """ + Get a digest from a dictionary by looking at a "digests" dictionary + or keys of the form 'algo_digest'. + + Returns a 2-tuple (algo, digest) if found, else None. Currently + looks only for SHA256, then MD5. + """ + result = None + if 'digests' in info: + digests = info['digests'] + for algo in ('sha256', 'md5'): + if algo in digests: + result = (algo, digests[algo]) + break + if not result: + for algo in ('sha256', 'md5'): + key = '%s_digest' % algo + if key in info: + result = (algo, info[key]) + break + return result + + def _update_version_data(self, result, info): + """ + Update a result dictionary (the final result from _get_project) with a + dictionary for a specific version, which typically holds information + gleaned from a filename or URL for an archive for the distribution. + """ + name = info.pop('name') + version = info.pop('version') + if version in result: + dist = result[version] + md = dist.metadata + else: + dist = make_dist(name, version, scheme=self.scheme) + md = dist.metadata + dist.digest = digest = self._get_digest(info) + url = info['url'] + result['digests'][url] = digest + if md.source_url != info['url']: + md.source_url = self.prefer_url(md.source_url, url) + result['urls'].setdefault(version, set()).add(url) + dist.locator = self + result[version] = dist + + def locate(self, requirement, prereleases=False): + """ + Find the most recent distribution which matches the given + requirement. + + :param requirement: A requirement of the form 'foo (1.0)' or perhaps + 'foo (>= 1.0, < 2.0, != 1.3)' + :param prereleases: If ``True``, allow pre-release versions + to be located. Otherwise, pre-release versions + are not returned. + :return: A :class:`Distribution` instance, or ``None`` if no such + distribution could be located. + """ + result = None + r = parse_requirement(requirement) + if r is None: # pragma: no cover + raise DistlibException('Not a valid requirement: %r' % requirement) + scheme = get_scheme(self.scheme) + self.matcher = matcher = scheme.matcher(r.requirement) + logger.debug('matcher: %s (%s)', matcher, type(matcher).__name__) + versions = self.get_project(r.name) + if len(versions) > 2: # urls and digests keys are present + # sometimes, versions are invalid + slist = [] + vcls = matcher.version_class + for k in versions: + if k in ('urls', 'digests'): + continue + try: + if not matcher.match(k): + logger.debug('%s did not match %r', matcher, k) + else: + if prereleases or not vcls(k).is_prerelease: + slist.append(k) + else: + logger.debug('skipping pre-release ' + 'version %s of %s', k, matcher.name) + except Exception: # pragma: no cover + logger.warning('error matching %s with %r', matcher, k) + pass # slist.append(k) + if len(slist) > 1: + slist = sorted(slist, key=scheme.key) + if slist: + logger.debug('sorted list: %s', slist) + version = slist[-1] + result = versions[version] + if result: + if r.extras: + result.extras = r.extras + result.download_urls = versions.get('urls', {}).get(version, set()) + d = {} + sd = versions.get('digests', {}) + for url in result.download_urls: + if url in sd: # pragma: no cover + d[url] = sd[url] + result.digests = d + self.matcher = None + return result + + +class PyPIRPCLocator(Locator): + """ + This locator uses XML-RPC to locate distributions. It therefore + cannot be used with simple mirrors (that only mirror file content). + """ + def __init__(self, url, **kwargs): + """ + Initialise an instance. + + :param url: The URL to use for XML-RPC. + :param kwargs: Passed to the superclass constructor. + """ + super(PyPIRPCLocator, self).__init__(**kwargs) + self.base_url = url + self.client = ServerProxy(url, timeout=3.0) + + def get_distribution_names(self): + """ + Return all the distribution names known to this locator. + """ + return set(self.client.list_packages()) + + def _get_project(self, name): + result = {'urls': {}, 'digests': {}} + versions = self.client.package_releases(name, True) + for v in versions: + urls = self.client.release_urls(name, v) + data = self.client.release_data(name, v) + metadata = Metadata(scheme=self.scheme) + metadata.name = data['name'] + metadata.version = data['version'] + metadata.license = data.get('license') + metadata.keywords = data.get('keywords', []) + metadata.summary = data.get('summary') + dist = Distribution(metadata) + if urls: + info = urls[0] + metadata.source_url = info['url'] + dist.digest = self._get_digest(info) + dist.locator = self + result[v] = dist + for info in urls: + url = info['url'] + digest = self._get_digest(info) + result['urls'].setdefault(v, set()).add(url) + result['digests'][url] = digest + return result + +class PyPIJSONLocator(Locator): + """ + This locator uses PyPI's JSON interface. It's very limited in functionality + and probably not worth using. + """ + def __init__(self, url, **kwargs): + super(PyPIJSONLocator, self).__init__(**kwargs) + self.base_url = ensure_slash(url) + + def get_distribution_names(self): + """ + Return all the distribution names known to this locator. + """ + raise NotImplementedError('Not available from this locator') + + def _get_project(self, name): + result = {'urls': {}, 'digests': {}} + url = urljoin(self.base_url, '%s/json' % quote(name)) + try: + resp = self.opener.open(url) + data = resp.read().decode() # for now + d = json.loads(data) + md = Metadata(scheme=self.scheme) + data = d['info'] + md.name = data['name'] + md.version = data['version'] + md.license = data.get('license') + md.keywords = data.get('keywords', []) + md.summary = data.get('summary') + dist = Distribution(md) + dist.locator = self + urls = d['urls'] + result[md.version] = dist + for info in d['urls']: + url = info['url'] + dist.download_urls.add(url) + dist.digests[url] = self._get_digest(info) + result['urls'].setdefault(md.version, set()).add(url) + result['digests'][url] = self._get_digest(info) + # Now get other releases + for version, infos in d['releases'].items(): + if version == md.version: + continue # already done + omd = Metadata(scheme=self.scheme) + omd.name = md.name + omd.version = version + odist = Distribution(omd) + odist.locator = self + result[version] = odist + for info in infos: + url = info['url'] + odist.download_urls.add(url) + odist.digests[url] = self._get_digest(info) + result['urls'].setdefault(version, set()).add(url) + result['digests'][url] = self._get_digest(info) +# for info in urls: +# md.source_url = info['url'] +# dist.digest = self._get_digest(info) +# dist.locator = self +# for info in urls: +# url = info['url'] +# result['urls'].setdefault(md.version, set()).add(url) +# result['digests'][url] = self._get_digest(info) + except Exception as e: + self.errors.put(text_type(e)) + logger.exception('JSON fetch failed: %s', e) + return result + + +class Page(object): + """ + This class represents a scraped HTML page. + """ + # The following slightly hairy-looking regex just looks for the contents of + # an anchor link, which has an attribute "href" either immediately preceded + # or immediately followed by a "rel" attribute. The attribute values can be + # declared with double quotes, single quotes or no quotes - which leads to + # the length of the expression. + _href = re.compile(""" +(rel\\s*=\\s*(?:"(?P[^"]*)"|'(?P[^']*)'|(?P[^>\\s\n]*))\\s+)? +href\\s*=\\s*(?:"(?P[^"]*)"|'(?P[^']*)'|(?P[^>\\s\n]*)) +(\\s+rel\\s*=\\s*(?:"(?P[^"]*)"|'(?P[^']*)'|(?P[^>\\s\n]*)))? +""", re.I | re.S | re.X) + _base = re.compile(r"""]+)""", re.I | re.S) + + def __init__(self, data, url): + """ + Initialise an instance with the Unicode page contents and the URL they + came from. + """ + self.data = data + self.base_url = self.url = url + m = self._base.search(self.data) + if m: + self.base_url = m.group(1) + + _clean_re = re.compile(r'[^a-z0-9$&+,/:;=?@.#%_\\|-]', re.I) + + @cached_property + def links(self): + """ + Return the URLs of all the links on a page together with information + about their "rel" attribute, for determining which ones to treat as + downloads and which ones to queue for further scraping. + """ + def clean(url): + "Tidy up an URL." + scheme, netloc, path, params, query, frag = urlparse(url) + return urlunparse((scheme, netloc, quote(path), + params, query, frag)) + + result = set() + for match in self._href.finditer(self.data): + d = match.groupdict('') + rel = (d['rel1'] or d['rel2'] or d['rel3'] or + d['rel4'] or d['rel5'] or d['rel6']) + url = d['url1'] or d['url2'] or d['url3'] + url = urljoin(self.base_url, url) + url = unescape(url) + url = self._clean_re.sub(lambda m: '%%%2x' % ord(m.group(0)), url) + result.add((url, rel)) + # We sort the result, hoping to bring the most recent versions + # to the front + result = sorted(result, key=lambda t: t[0], reverse=True) + return result + + +class SimpleScrapingLocator(Locator): + """ + A locator which scrapes HTML pages to locate downloads for a distribution. + This runs multiple threads to do the I/O; performance is at least as good + as pip's PackageFinder, which works in an analogous fashion. + """ + + # These are used to deal with various Content-Encoding schemes. + decoders = { + 'deflate': zlib.decompress, + 'gzip': lambda b: gzip.GzipFile(fileobj=BytesIO(d)).read(), + 'none': lambda b: b, + } + + def __init__(self, url, timeout=None, num_workers=10, **kwargs): + """ + Initialise an instance. + :param url: The root URL to use for scraping. + :param timeout: The timeout, in seconds, to be applied to requests. + This defaults to ``None`` (no timeout specified). + :param num_workers: The number of worker threads you want to do I/O, + This defaults to 10. + :param kwargs: Passed to the superclass. + """ + super(SimpleScrapingLocator, self).__init__(**kwargs) + self.base_url = ensure_slash(url) + self.timeout = timeout + self._page_cache = {} + self._seen = set() + self._to_fetch = queue.Queue() + self._bad_hosts = set() + self.skip_externals = False + self.num_workers = num_workers + self._lock = threading.RLock() + # See issue #45: we need to be resilient when the locator is used + # in a thread, e.g. with concurrent.futures. We can't use self._lock + # as it is for coordinating our internal threads - the ones created + # in _prepare_threads. + self._gplock = threading.RLock() + self.platform_check = False # See issue #112 + + def _prepare_threads(self): + """ + Threads are created only when get_project is called, and terminate + before it returns. They are there primarily to parallelise I/O (i.e. + fetching web pages). + """ + self._threads = [] + for i in range(self.num_workers): + t = threading.Thread(target=self._fetch) + t.setDaemon(True) + t.start() + self._threads.append(t) + + def _wait_threads(self): + """ + Tell all the threads to terminate (by sending a sentinel value) and + wait for them to do so. + """ + # Note that you need two loops, since you can't say which + # thread will get each sentinel + for t in self._threads: + self._to_fetch.put(None) # sentinel + for t in self._threads: + t.join() + self._threads = [] + + def _get_project(self, name): + result = {'urls': {}, 'digests': {}} + with self._gplock: + self.result = result + self.project_name = name + url = urljoin(self.base_url, '%s/' % quote(name)) + self._seen.clear() + self._page_cache.clear() + self._prepare_threads() + try: + logger.debug('Queueing %s', url) + self._to_fetch.put(url) + self._to_fetch.join() + finally: + self._wait_threads() + del self.result + return result + + platform_dependent = re.compile(r'\b(linux_(i\d86|x86_64|arm\w+)|' + r'win(32|_amd64)|macosx_?\d+)\b', re.I) + + def _is_platform_dependent(self, url): + """ + Does an URL refer to a platform-specific download? + """ + return self.platform_dependent.search(url) + + def _process_download(self, url): + """ + See if an URL is a suitable download for a project. + + If it is, register information in the result dictionary (for + _get_project) about the specific version it's for. + + Note that the return value isn't actually used other than as a boolean + value. + """ + if self.platform_check and self._is_platform_dependent(url): + info = None + else: + info = self.convert_url_to_download_info(url, self.project_name) + logger.debug('process_download: %s -> %s', url, info) + if info: + with self._lock: # needed because self.result is shared + self._update_version_data(self.result, info) + return info + + def _should_queue(self, link, referrer, rel): + """ + Determine whether a link URL from a referring page and with a + particular "rel" attribute should be queued for scraping. + """ + scheme, netloc, path, _, _, _ = urlparse(link) + if path.endswith(self.source_extensions + self.binary_extensions + + self.excluded_extensions): + result = False + elif self.skip_externals and not link.startswith(self.base_url): + result = False + elif not referrer.startswith(self.base_url): + result = False + elif rel not in ('homepage', 'download'): + result = False + elif scheme not in ('http', 'https', 'ftp'): + result = False + elif self._is_platform_dependent(link): + result = False + else: + host = netloc.split(':', 1)[0] + if host.lower() == 'localhost': + result = False + else: + result = True + logger.debug('should_queue: %s (%s) from %s -> %s', link, rel, + referrer, result) + return result + + def _fetch(self): + """ + Get a URL to fetch from the work queue, get the HTML page, examine its + links for download candidates and candidates for further scraping. + + This is a handy method to run in a thread. + """ + while True: + url = self._to_fetch.get() + try: + if url: + page = self.get_page(url) + if page is None: # e.g. after an error + continue + for link, rel in page.links: + if link not in self._seen: + try: + self._seen.add(link) + if (not self._process_download(link) and + self._should_queue(link, url, rel)): + logger.debug('Queueing %s from %s', link, url) + self._to_fetch.put(link) + except MetadataInvalidError: # e.g. invalid versions + pass + except Exception as e: # pragma: no cover + self.errors.put(text_type(e)) + finally: + # always do this, to avoid hangs :-) + self._to_fetch.task_done() + if not url: + #logger.debug('Sentinel seen, quitting.') + break + + def get_page(self, url): + """ + Get the HTML for an URL, possibly from an in-memory cache. + + XXX TODO Note: this cache is never actually cleared. It's assumed that + the data won't get stale over the lifetime of a locator instance (not + necessarily true for the default_locator). + """ + # http://peak.telecommunity.com/DevCenter/EasyInstall#package-index-api + scheme, netloc, path, _, _, _ = urlparse(url) + if scheme == 'file' and os.path.isdir(url2pathname(path)): + url = urljoin(ensure_slash(url), 'index.html') + + if url in self._page_cache: + result = self._page_cache[url] + logger.debug('Returning %s from cache: %s', url, result) + else: + host = netloc.split(':', 1)[0] + result = None + if host in self._bad_hosts: + logger.debug('Skipping %s due to bad host %s', url, host) + else: + req = Request(url, headers={'Accept-encoding': 'identity'}) + try: + logger.debug('Fetching %s', url) + resp = self.opener.open(req, timeout=self.timeout) + logger.debug('Fetched %s', url) + headers = resp.info() + content_type = headers.get('Content-Type', '') + if HTML_CONTENT_TYPE.match(content_type): + final_url = resp.geturl() + data = resp.read() + encoding = headers.get('Content-Encoding') + if encoding: + decoder = self.decoders[encoding] # fail if not found + data = decoder(data) + encoding = 'utf-8' + m = CHARSET.search(content_type) + if m: + encoding = m.group(1) + try: + data = data.decode(encoding) + except UnicodeError: # pragma: no cover + data = data.decode('latin-1') # fallback + result = Page(data, final_url) + self._page_cache[final_url] = result + except HTTPError as e: + if e.code != 404: + logger.exception('Fetch failed: %s: %s', url, e) + except URLError as e: # pragma: no cover + logger.exception('Fetch failed: %s: %s', url, e) + with self._lock: + self._bad_hosts.add(host) + except Exception as e: # pragma: no cover + logger.exception('Fetch failed: %s: %s', url, e) + finally: + self._page_cache[url] = result # even if None (failure) + return result + + _distname_re = re.compile(']*>([^<]+)<') + + def get_distribution_names(self): + """ + Return all the distribution names known to this locator. + """ + result = set() + page = self.get_page(self.base_url) + if not page: + raise DistlibException('Unable to get %s' % self.base_url) + for match in self._distname_re.finditer(page.data): + result.add(match.group(1)) + return result + +class DirectoryLocator(Locator): + """ + This class locates distributions in a directory tree. + """ + + def __init__(self, path, **kwargs): + """ + Initialise an instance. + :param path: The root of the directory tree to search. + :param kwargs: Passed to the superclass constructor, + except for: + * recursive - if True (the default), subdirectories are + recursed into. If False, only the top-level directory + is searched, + """ + self.recursive = kwargs.pop('recursive', True) + super(DirectoryLocator, self).__init__(**kwargs) + path = os.path.abspath(path) + if not os.path.isdir(path): # pragma: no cover + raise DistlibException('Not a directory: %r' % path) + self.base_dir = path + + def should_include(self, filename, parent): + """ + Should a filename be considered as a candidate for a distribution + archive? As well as the filename, the directory which contains it + is provided, though not used by the current implementation. + """ + return filename.endswith(self.downloadable_extensions) + + def _get_project(self, name): + result = {'urls': {}, 'digests': {}} + for root, dirs, files in os.walk(self.base_dir): + for fn in files: + if self.should_include(fn, root): + fn = os.path.join(root, fn) + url = urlunparse(('file', '', + pathname2url(os.path.abspath(fn)), + '', '', '')) + info = self.convert_url_to_download_info(url, name) + if info: + self._update_version_data(result, info) + if not self.recursive: + break + return result + + def get_distribution_names(self): + """ + Return all the distribution names known to this locator. + """ + result = set() + for root, dirs, files in os.walk(self.base_dir): + for fn in files: + if self.should_include(fn, root): + fn = os.path.join(root, fn) + url = urlunparse(('file', '', + pathname2url(os.path.abspath(fn)), + '', '', '')) + info = self.convert_url_to_download_info(url, None) + if info: + result.add(info['name']) + if not self.recursive: + break + return result + +class JSONLocator(Locator): + """ + This locator uses special extended metadata (not available on PyPI) and is + the basis of performant dependency resolution in distlib. Other locators + require archive downloads before dependencies can be determined! As you + might imagine, that can be slow. + """ + def get_distribution_names(self): + """ + Return all the distribution names known to this locator. + """ + raise NotImplementedError('Not available from this locator') + + def _get_project(self, name): + result = {'urls': {}, 'digests': {}} + data = get_project_data(name) + if data: + for info in data.get('files', []): + if info['ptype'] != 'sdist' or info['pyversion'] != 'source': + continue + # We don't store summary in project metadata as it makes + # the data bigger for no benefit during dependency + # resolution + dist = make_dist(data['name'], info['version'], + summary=data.get('summary', + 'Placeholder for summary'), + scheme=self.scheme) + md = dist.metadata + md.source_url = info['url'] + # TODO SHA256 digest + if 'digest' in info and info['digest']: + dist.digest = ('md5', info['digest']) + md.dependencies = info.get('requirements', {}) + dist.exports = info.get('exports', {}) + result[dist.version] = dist + result['urls'].setdefault(dist.version, set()).add(info['url']) + return result + +class DistPathLocator(Locator): + """ + This locator finds installed distributions in a path. It can be useful for + adding to an :class:`AggregatingLocator`. + """ + def __init__(self, distpath, **kwargs): + """ + Initialise an instance. + + :param distpath: A :class:`DistributionPath` instance to search. + """ + super(DistPathLocator, self).__init__(**kwargs) + assert isinstance(distpath, DistributionPath) + self.distpath = distpath + + def _get_project(self, name): + dist = self.distpath.get_distribution(name) + if dist is None: + result = {'urls': {}, 'digests': {}} + else: + result = { + dist.version: dist, + 'urls': {dist.version: set([dist.source_url])}, + 'digests': {dist.version: set([None])} + } + return result + + +class AggregatingLocator(Locator): + """ + This class allows you to chain and/or merge a list of locators. + """ + def __init__(self, *locators, **kwargs): + """ + Initialise an instance. + + :param locators: The list of locators to search. + :param kwargs: Passed to the superclass constructor, + except for: + * merge - if False (the default), the first successful + search from any of the locators is returned. If True, + the results from all locators are merged (this can be + slow). + """ + self.merge = kwargs.pop('merge', False) + self.locators = locators + super(AggregatingLocator, self).__init__(**kwargs) + + def clear_cache(self): + super(AggregatingLocator, self).clear_cache() + for locator in self.locators: + locator.clear_cache() + + def _set_scheme(self, value): + self._scheme = value + for locator in self.locators: + locator.scheme = value + + scheme = property(Locator.scheme.fget, _set_scheme) + + def _get_project(self, name): + result = {} + for locator in self.locators: + d = locator.get_project(name) + if d: + if self.merge: + files = result.get('urls', {}) + digests = result.get('digests', {}) + # next line could overwrite result['urls'], result['digests'] + result.update(d) + df = result.get('urls') + if files and df: + for k, v in files.items(): + if k in df: + df[k] |= v + else: + df[k] = v + dd = result.get('digests') + if digests and dd: + dd.update(digests) + else: + # See issue #18. If any dists are found and we're looking + # for specific constraints, we only return something if + # a match is found. For example, if a DirectoryLocator + # returns just foo (1.0) while we're looking for + # foo (>= 2.0), we'll pretend there was nothing there so + # that subsequent locators can be queried. Otherwise we + # would just return foo (1.0) which would then lead to a + # failure to find foo (>= 2.0), because other locators + # weren't searched. Note that this only matters when + # merge=False. + if self.matcher is None: + found = True + else: + found = False + for k in d: + if self.matcher.match(k): + found = True + break + if found: + result = d + break + return result + + def get_distribution_names(self): + """ + Return all the distribution names known to this locator. + """ + result = set() + for locator in self.locators: + try: + result |= locator.get_distribution_names() + except NotImplementedError: + pass + return result + + +# We use a legacy scheme simply because most of the dists on PyPI use legacy +# versions which don't conform to PEP 426 / PEP 440. +default_locator = AggregatingLocator( + JSONLocator(), + SimpleScrapingLocator('https://pypi.org/simple/', + timeout=3.0), + scheme='legacy') + +locate = default_locator.locate + +NAME_VERSION_RE = re.compile(r'(?P[\w-]+)\s*' + r'\(\s*(==\s*)?(?P[^)]+)\)$') + +class DependencyFinder(object): + """ + Locate dependencies for distributions. + """ + + def __init__(self, locator=None): + """ + Initialise an instance, using the specified locator + to locate distributions. + """ + self.locator = locator or default_locator + self.scheme = get_scheme(self.locator.scheme) + + def add_distribution(self, dist): + """ + Add a distribution to the finder. This will update internal information + about who provides what. + :param dist: The distribution to add. + """ + logger.debug('adding distribution %s', dist) + name = dist.key + self.dists_by_name[name] = dist + self.dists[(name, dist.version)] = dist + for p in dist.provides: + name, version = parse_name_and_version(p) + logger.debug('Add to provided: %s, %s, %s', name, version, dist) + self.provided.setdefault(name, set()).add((version, dist)) + + def remove_distribution(self, dist): + """ + Remove a distribution from the finder. This will update internal + information about who provides what. + :param dist: The distribution to remove. + """ + logger.debug('removing distribution %s', dist) + name = dist.key + del self.dists_by_name[name] + del self.dists[(name, dist.version)] + for p in dist.provides: + name, version = parse_name_and_version(p) + logger.debug('Remove from provided: %s, %s, %s', name, version, dist) + s = self.provided[name] + s.remove((version, dist)) + if not s: + del self.provided[name] + + def get_matcher(self, reqt): + """ + Get a version matcher for a requirement. + :param reqt: The requirement + :type reqt: str + :return: A version matcher (an instance of + :class:`distlib.version.Matcher`). + """ + try: + matcher = self.scheme.matcher(reqt) + except UnsupportedVersionError: # pragma: no cover + # XXX compat-mode if cannot read the version + name = reqt.split()[0] + matcher = self.scheme.matcher(name) + return matcher + + def find_providers(self, reqt): + """ + Find the distributions which can fulfill a requirement. + + :param reqt: The requirement. + :type reqt: str + :return: A set of distribution which can fulfill the requirement. + """ + matcher = self.get_matcher(reqt) + name = matcher.key # case-insensitive + result = set() + provided = self.provided + if name in provided: + for version, provider in provided[name]: + try: + match = matcher.match(version) + except UnsupportedVersionError: + match = False + + if match: + result.add(provider) + break + return result + + def try_to_replace(self, provider, other, problems): + """ + Attempt to replace one provider with another. This is typically used + when resolving dependencies from multiple sources, e.g. A requires + (B >= 1.0) while C requires (B >= 1.1). + + For successful replacement, ``provider`` must meet all the requirements + which ``other`` fulfills. + + :param provider: The provider we are trying to replace with. + :param other: The provider we're trying to replace. + :param problems: If False is returned, this will contain what + problems prevented replacement. This is currently + a tuple of the literal string 'cantreplace', + ``provider``, ``other`` and the set of requirements + that ``provider`` couldn't fulfill. + :return: True if we can replace ``other`` with ``provider``, else + False. + """ + rlist = self.reqts[other] + unmatched = set() + for s in rlist: + matcher = self.get_matcher(s) + if not matcher.match(provider.version): + unmatched.add(s) + if unmatched: + # can't replace other with provider + problems.add(('cantreplace', provider, other, + frozenset(unmatched))) + result = False + else: + # can replace other with provider + self.remove_distribution(other) + del self.reqts[other] + for s in rlist: + self.reqts.setdefault(provider, set()).add(s) + self.add_distribution(provider) + result = True + return result + + def find(self, requirement, meta_extras=None, prereleases=False): + """ + Find a distribution and all distributions it depends on. + + :param requirement: The requirement specifying the distribution to + find, or a Distribution instance. + :param meta_extras: A list of meta extras such as :test:, :build: and + so on. + :param prereleases: If ``True``, allow pre-release versions to be + returned - otherwise, don't return prereleases + unless they're all that's available. + + Return a set of :class:`Distribution` instances and a set of + problems. + + The distributions returned should be such that they have the + :attr:`required` attribute set to ``True`` if they were + from the ``requirement`` passed to ``find()``, and they have the + :attr:`build_time_dependency` attribute set to ``True`` unless they + are post-installation dependencies of the ``requirement``. + + The problems should be a tuple consisting of the string + ``'unsatisfied'`` and the requirement which couldn't be satisfied + by any distribution known to the locator. + """ + + self.provided = {} + self.dists = {} + self.dists_by_name = {} + self.reqts = {} + + meta_extras = set(meta_extras or []) + if ':*:' in meta_extras: + meta_extras.remove(':*:') + # :meta: and :run: are implicitly included + meta_extras |= set([':test:', ':build:', ':dev:']) + + if isinstance(requirement, Distribution): + dist = odist = requirement + logger.debug('passed %s as requirement', odist) + else: + dist = odist = self.locator.locate(requirement, + prereleases=prereleases) + if dist is None: + raise DistlibException('Unable to locate %r' % requirement) + logger.debug('located %s', odist) + dist.requested = True + problems = set() + todo = set([dist]) + install_dists = set([odist]) + while todo: + dist = todo.pop() + name = dist.key # case-insensitive + if name not in self.dists_by_name: + self.add_distribution(dist) + else: + #import pdb; pdb.set_trace() + other = self.dists_by_name[name] + if other != dist: + self.try_to_replace(dist, other, problems) + + ireqts = dist.run_requires | dist.meta_requires + sreqts = dist.build_requires + ereqts = set() + if meta_extras and dist in install_dists: + for key in ('test', 'build', 'dev'): + e = ':%s:' % key + if e in meta_extras: + ereqts |= getattr(dist, '%s_requires' % key) + all_reqts = ireqts | sreqts | ereqts + for r in all_reqts: + providers = self.find_providers(r) + if not providers: + logger.debug('No providers found for %r', r) + provider = self.locator.locate(r, prereleases=prereleases) + # If no provider is found and we didn't consider + # prereleases, consider them now. + if provider is None and not prereleases: + provider = self.locator.locate(r, prereleases=True) + if provider is None: + logger.debug('Cannot satisfy %r', r) + problems.add(('unsatisfied', r)) + else: + n, v = provider.key, provider.version + if (n, v) not in self.dists: + todo.add(provider) + providers.add(provider) + if r in ireqts and dist in install_dists: + install_dists.add(provider) + logger.debug('Adding %s to install_dists', + provider.name_and_version) + for p in providers: + name = p.key + if name not in self.dists_by_name: + self.reqts.setdefault(p, set()).add(r) + else: + other = self.dists_by_name[name] + if other != p: + # see if other can be replaced by p + self.try_to_replace(p, other, problems) + + dists = set(self.dists.values()) + for dist in dists: + dist.build_time_dependency = dist not in install_dists + if dist.build_time_dependency: + logger.debug('%s is a build-time dependency only.', + dist.name_and_version) + logger.debug('find done for %s', odist) + return dists, problems diff --git a/venv/Lib/site-packages/pip/_vendor/distlib/manifest.py b/venv/Lib/site-packages/pip/_vendor/distlib/manifest.py new file mode 100644 index 0000000..ca0fe44 --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/distlib/manifest.py @@ -0,0 +1,393 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2012-2013 Python Software Foundation. +# See LICENSE.txt and CONTRIBUTORS.txt. +# +""" +Class representing the list of files in a distribution. + +Equivalent to distutils.filelist, but fixes some problems. +""" +import fnmatch +import logging +import os +import re +import sys + +from . import DistlibException +from .compat import fsdecode +from .util import convert_path + + +__all__ = ['Manifest'] + +logger = logging.getLogger(__name__) + +# a \ followed by some spaces + EOL +_COLLAPSE_PATTERN = re.compile('\\\\w*\n', re.M) +_COMMENTED_LINE = re.compile('#.*?(?=\n)|\n(?=$)', re.M | re.S) + +# +# Due to the different results returned by fnmatch.translate, we need +# to do slightly different processing for Python 2.7 and 3.2 ... this needed +# to be brought in for Python 3.6 onwards. +# +_PYTHON_VERSION = sys.version_info[:2] + +class Manifest(object): + """A list of files built by on exploring the filesystem and filtered by + applying various patterns to what we find there. + """ + + def __init__(self, base=None): + """ + Initialise an instance. + + :param base: The base directory to explore under. + """ + self.base = os.path.abspath(os.path.normpath(base or os.getcwd())) + self.prefix = self.base + os.sep + self.allfiles = None + self.files = set() + + # + # Public API + # + + def findall(self): + """Find all files under the base and set ``allfiles`` to the absolute + pathnames of files found. + """ + from stat import S_ISREG, S_ISDIR, S_ISLNK + + self.allfiles = allfiles = [] + root = self.base + stack = [root] + pop = stack.pop + push = stack.append + + while stack: + root = pop() + names = os.listdir(root) + + for name in names: + fullname = os.path.join(root, name) + + # Avoid excess stat calls -- just one will do, thank you! + stat = os.stat(fullname) + mode = stat.st_mode + if S_ISREG(mode): + allfiles.append(fsdecode(fullname)) + elif S_ISDIR(mode) and not S_ISLNK(mode): + push(fullname) + + def add(self, item): + """ + Add a file to the manifest. + + :param item: The pathname to add. This can be relative to the base. + """ + if not item.startswith(self.prefix): + item = os.path.join(self.base, item) + self.files.add(os.path.normpath(item)) + + def add_many(self, items): + """ + Add a list of files to the manifest. + + :param items: The pathnames to add. These can be relative to the base. + """ + for item in items: + self.add(item) + + def sorted(self, wantdirs=False): + """ + Return sorted files in directory order + """ + + def add_dir(dirs, d): + dirs.add(d) + logger.debug('add_dir added %s', d) + if d != self.base: + parent, _ = os.path.split(d) + assert parent not in ('', '/') + add_dir(dirs, parent) + + result = set(self.files) # make a copy! + if wantdirs: + dirs = set() + for f in result: + add_dir(dirs, os.path.dirname(f)) + result |= dirs + return [os.path.join(*path_tuple) for path_tuple in + sorted(os.path.split(path) for path in result)] + + def clear(self): + """Clear all collected files.""" + self.files = set() + self.allfiles = [] + + def process_directive(self, directive): + """ + Process a directive which either adds some files from ``allfiles`` to + ``files``, or removes some files from ``files``. + + :param directive: The directive to process. This should be in a format + compatible with distutils ``MANIFEST.in`` files: + + http://docs.python.org/distutils/sourcedist.html#commands + """ + # Parse the line: split it up, make sure the right number of words + # is there, and return the relevant words. 'action' is always + # defined: it's the first word of the line. Which of the other + # three are defined depends on the action; it'll be either + # patterns, (dir and patterns), or (dirpattern). + action, patterns, thedir, dirpattern = self._parse_directive(directive) + + # OK, now we know that the action is valid and we have the + # right number of words on the line for that action -- so we + # can proceed with minimal error-checking. + if action == 'include': + for pattern in patterns: + if not self._include_pattern(pattern, anchor=True): + logger.warning('no files found matching %r', pattern) + + elif action == 'exclude': + for pattern in patterns: + found = self._exclude_pattern(pattern, anchor=True) + #if not found: + # logger.warning('no previously-included files ' + # 'found matching %r', pattern) + + elif action == 'global-include': + for pattern in patterns: + if not self._include_pattern(pattern, anchor=False): + logger.warning('no files found matching %r ' + 'anywhere in distribution', pattern) + + elif action == 'global-exclude': + for pattern in patterns: + found = self._exclude_pattern(pattern, anchor=False) + #if not found: + # logger.warning('no previously-included files ' + # 'matching %r found anywhere in ' + # 'distribution', pattern) + + elif action == 'recursive-include': + for pattern in patterns: + if not self._include_pattern(pattern, prefix=thedir): + logger.warning('no files found matching %r ' + 'under directory %r', pattern, thedir) + + elif action == 'recursive-exclude': + for pattern in patterns: + found = self._exclude_pattern(pattern, prefix=thedir) + #if not found: + # logger.warning('no previously-included files ' + # 'matching %r found under directory %r', + # pattern, thedir) + + elif action == 'graft': + if not self._include_pattern(None, prefix=dirpattern): + logger.warning('no directories found matching %r', + dirpattern) + + elif action == 'prune': + if not self._exclude_pattern(None, prefix=dirpattern): + logger.warning('no previously-included directories found ' + 'matching %r', dirpattern) + else: # pragma: no cover + # This should never happen, as it should be caught in + # _parse_template_line + raise DistlibException( + 'invalid action %r' % action) + + # + # Private API + # + + def _parse_directive(self, directive): + """ + Validate a directive. + :param directive: The directive to validate. + :return: A tuple of action, patterns, thedir, dir_patterns + """ + words = directive.split() + if len(words) == 1 and words[0] not in ('include', 'exclude', + 'global-include', + 'global-exclude', + 'recursive-include', + 'recursive-exclude', + 'graft', 'prune'): + # no action given, let's use the default 'include' + words.insert(0, 'include') + + action = words[0] + patterns = thedir = dir_pattern = None + + if action in ('include', 'exclude', + 'global-include', 'global-exclude'): + if len(words) < 2: + raise DistlibException( + '%r expects ...' % action) + + patterns = [convert_path(word) for word in words[1:]] + + elif action in ('recursive-include', 'recursive-exclude'): + if len(words) < 3: + raise DistlibException( + '%r expects ...' % action) + + thedir = convert_path(words[1]) + patterns = [convert_path(word) for word in words[2:]] + + elif action in ('graft', 'prune'): + if len(words) != 2: + raise DistlibException( + '%r expects a single ' % action) + + dir_pattern = convert_path(words[1]) + + else: + raise DistlibException('unknown action %r' % action) + + return action, patterns, thedir, dir_pattern + + def _include_pattern(self, pattern, anchor=True, prefix=None, + is_regex=False): + """Select strings (presumably filenames) from 'self.files' that + match 'pattern', a Unix-style wildcard (glob) pattern. + + Patterns are not quite the same as implemented by the 'fnmatch' + module: '*' and '?' match non-special characters, where "special" + is platform-dependent: slash on Unix; colon, slash, and backslash on + DOS/Windows; and colon on Mac OS. + + If 'anchor' is true (the default), then the pattern match is more + stringent: "*.py" will match "foo.py" but not "foo/bar.py". If + 'anchor' is false, both of these will match. + + If 'prefix' is supplied, then only filenames starting with 'prefix' + (itself a pattern) and ending with 'pattern', with anything in between + them, will match. 'anchor' is ignored in this case. + + If 'is_regex' is true, 'anchor' and 'prefix' are ignored, and + 'pattern' is assumed to be either a string containing a regex or a + regex object -- no translation is done, the regex is just compiled + and used as-is. + + Selected strings will be added to self.files. + + Return True if files are found. + """ + # XXX docstring lying about what the special chars are? + found = False + pattern_re = self._translate_pattern(pattern, anchor, prefix, is_regex) + + # delayed loading of allfiles list + if self.allfiles is None: + self.findall() + + for name in self.allfiles: + if pattern_re.search(name): + self.files.add(name) + found = True + return found + + def _exclude_pattern(self, pattern, anchor=True, prefix=None, + is_regex=False): + """Remove strings (presumably filenames) from 'files' that match + 'pattern'. + + Other parameters are the same as for 'include_pattern()', above. + The list 'self.files' is modified in place. Return True if files are + found. + + This API is public to allow e.g. exclusion of SCM subdirs, e.g. when + packaging source distributions + """ + found = False + pattern_re = self._translate_pattern(pattern, anchor, prefix, is_regex) + for f in list(self.files): + if pattern_re.search(f): + self.files.remove(f) + found = True + return found + + def _translate_pattern(self, pattern, anchor=True, prefix=None, + is_regex=False): + """Translate a shell-like wildcard pattern to a compiled regular + expression. + + Return the compiled regex. If 'is_regex' true, + then 'pattern' is directly compiled to a regex (if it's a string) + or just returned as-is (assumes it's a regex object). + """ + if is_regex: + if isinstance(pattern, str): + return re.compile(pattern) + else: + return pattern + + if _PYTHON_VERSION > (3, 2): + # ditch start and end characters + start, _, end = self._glob_to_re('_').partition('_') + + if pattern: + pattern_re = self._glob_to_re(pattern) + if _PYTHON_VERSION > (3, 2): + assert pattern_re.startswith(start) and pattern_re.endswith(end) + else: + pattern_re = '' + + base = re.escape(os.path.join(self.base, '')) + if prefix is not None: + # ditch end of pattern character + if _PYTHON_VERSION <= (3, 2): + empty_pattern = self._glob_to_re('') + prefix_re = self._glob_to_re(prefix)[:-len(empty_pattern)] + else: + prefix_re = self._glob_to_re(prefix) + assert prefix_re.startswith(start) and prefix_re.endswith(end) + prefix_re = prefix_re[len(start): len(prefix_re) - len(end)] + sep = os.sep + if os.sep == '\\': + sep = r'\\' + if _PYTHON_VERSION <= (3, 2): + pattern_re = '^' + base + sep.join((prefix_re, + '.*' + pattern_re)) + else: + pattern_re = pattern_re[len(start): len(pattern_re) - len(end)] + pattern_re = r'%s%s%s%s.*%s%s' % (start, base, prefix_re, sep, + pattern_re, end) + else: # no prefix -- respect anchor flag + if anchor: + if _PYTHON_VERSION <= (3, 2): + pattern_re = '^' + base + pattern_re + else: + pattern_re = r'%s%s%s' % (start, base, pattern_re[len(start):]) + + return re.compile(pattern_re) + + def _glob_to_re(self, pattern): + """Translate a shell-like glob pattern to a regular expression. + + Return a string containing the regex. Differs from + 'fnmatch.translate()' in that '*' does not match "special characters" + (which are platform-specific). + """ + pattern_re = fnmatch.translate(pattern) + + # '?' and '*' in the glob pattern become '.' and '.*' in the RE, which + # IMHO is wrong -- '?' and '*' aren't supposed to match slash in Unix, + # and by extension they shouldn't match such "special characters" under + # any OS. So change all non-escaped dots in the RE to match any + # character except the special characters (currently: just os.sep). + sep = os.sep + if os.sep == '\\': + # we're using a regex to manipulate a regex, so we need + # to escape the backslash twice + sep = r'\\\\' + escaped = r'\1[^%s]' % sep + pattern_re = re.sub(r'((? y, + '!=': lambda x, y: x != y, + '<': lambda x, y: x < y, + '<=': lambda x, y: x == y or x < y, + '>': lambda x, y: x > y, + '>=': lambda x, y: x == y or x > y, + 'and': lambda x, y: x and y, + 'or': lambda x, y: x or y, + 'in': lambda x, y: x in y, + 'not in': lambda x, y: x not in y, + } + + def evaluate(self, expr, context): + """ + Evaluate a marker expression returned by the :func:`parse_requirement` + function in the specified context. + """ + if isinstance(expr, string_types): + if expr[0] in '\'"': + result = expr[1:-1] + else: + if expr not in context: + raise SyntaxError('unknown variable: %s' % expr) + result = context[expr] + else: + assert isinstance(expr, dict) + op = expr['op'] + if op not in self.operations: + raise NotImplementedError('op not implemented: %s' % op) + elhs = expr['lhs'] + erhs = expr['rhs'] + if _is_literal(expr['lhs']) and _is_literal(expr['rhs']): + raise SyntaxError('invalid comparison: %s %s %s' % (elhs, op, erhs)) + + lhs = self.evaluate(elhs, context) + rhs = self.evaluate(erhs, context) + result = self.operations[op](lhs, rhs) + return result + +def default_context(): + def format_full_version(info): + version = '%s.%s.%s' % (info.major, info.minor, info.micro) + kind = info.releaselevel + if kind != 'final': + version += kind[0] + str(info.serial) + return version + + if hasattr(sys, 'implementation'): + implementation_version = format_full_version(sys.implementation.version) + implementation_name = sys.implementation.name + else: + implementation_version = '0' + implementation_name = '' + + result = { + 'implementation_name': implementation_name, + 'implementation_version': implementation_version, + 'os_name': os.name, + 'platform_machine': platform.machine(), + 'platform_python_implementation': platform.python_implementation(), + 'platform_release': platform.release(), + 'platform_system': platform.system(), + 'platform_version': platform.version(), + 'platform_in_venv': str(in_venv()), + 'python_full_version': platform.python_version(), + 'python_version': platform.python_version()[:3], + 'sys_platform': sys.platform, + } + return result + +DEFAULT_CONTEXT = default_context() +del default_context + +evaluator = Evaluator() + +def interpret(marker, execution_context=None): + """ + Interpret a marker and return a result depending on environment. + + :param marker: The marker to interpret. + :type marker: str + :param execution_context: The context used for name lookup. + :type execution_context: mapping + """ + try: + expr, rest = parse_marker(marker) + except Exception as e: + raise SyntaxError('Unable to interpret marker syntax: %s: %s' % (marker, e)) + if rest and rest[0] != '#': + raise SyntaxError('unexpected trailing data in marker: %s: %s' % (marker, rest)) + context = dict(DEFAULT_CONTEXT) + if execution_context: + context.update(execution_context) + return evaluator.evaluate(expr, context) diff --git a/venv/Lib/site-packages/pip/_vendor/distlib/metadata.py b/venv/Lib/site-packages/pip/_vendor/distlib/metadata.py new file mode 100644 index 0000000..6d5e236 --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/distlib/metadata.py @@ -0,0 +1,1056 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2012 The Python Software Foundation. +# See LICENSE.txt and CONTRIBUTORS.txt. +# +"""Implementation of the Metadata for Python packages PEPs. + +Supports all metadata formats (1.0, 1.1, 1.2, 1.3/2.1 and withdrawn 2.0). +""" +from __future__ import unicode_literals + +import codecs +from email import message_from_file +import json +import logging +import re + + +from . import DistlibException, __version__ +from .compat import StringIO, string_types, text_type +from .markers import interpret +from .util import extract_by_key, get_extras +from .version import get_scheme, PEP440_VERSION_RE + +logger = logging.getLogger(__name__) + + +class MetadataMissingError(DistlibException): + """A required metadata is missing""" + + +class MetadataConflictError(DistlibException): + """Attempt to read or write metadata fields that are conflictual.""" + + +class MetadataUnrecognizedVersionError(DistlibException): + """Unknown metadata version number.""" + + +class MetadataInvalidError(DistlibException): + """A metadata value is invalid""" + +# public API of this module +__all__ = ['Metadata', 'PKG_INFO_ENCODING', 'PKG_INFO_PREFERRED_VERSION'] + +# Encoding used for the PKG-INFO files +PKG_INFO_ENCODING = 'utf-8' + +# preferred version. Hopefully will be changed +# to 1.2 once PEP 345 is supported everywhere +PKG_INFO_PREFERRED_VERSION = '1.1' + +_LINE_PREFIX_1_2 = re.compile('\n \\|') +_LINE_PREFIX_PRE_1_2 = re.compile('\n ') +_241_FIELDS = ('Metadata-Version', 'Name', 'Version', 'Platform', + 'Summary', 'Description', + 'Keywords', 'Home-page', 'Author', 'Author-email', + 'License') + +_314_FIELDS = ('Metadata-Version', 'Name', 'Version', 'Platform', + 'Supported-Platform', 'Summary', 'Description', + 'Keywords', 'Home-page', 'Author', 'Author-email', + 'License', 'Classifier', 'Download-URL', 'Obsoletes', + 'Provides', 'Requires') + +_314_MARKERS = ('Obsoletes', 'Provides', 'Requires', 'Classifier', + 'Download-URL') + +_345_FIELDS = ('Metadata-Version', 'Name', 'Version', 'Platform', + 'Supported-Platform', 'Summary', 'Description', + 'Keywords', 'Home-page', 'Author', 'Author-email', + 'Maintainer', 'Maintainer-email', 'License', + 'Classifier', 'Download-URL', 'Obsoletes-Dist', + 'Project-URL', 'Provides-Dist', 'Requires-Dist', + 'Requires-Python', 'Requires-External') + +_345_MARKERS = ('Provides-Dist', 'Requires-Dist', 'Requires-Python', + 'Obsoletes-Dist', 'Requires-External', 'Maintainer', + 'Maintainer-email', 'Project-URL') + +_426_FIELDS = ('Metadata-Version', 'Name', 'Version', 'Platform', + 'Supported-Platform', 'Summary', 'Description', + 'Keywords', 'Home-page', 'Author', 'Author-email', + 'Maintainer', 'Maintainer-email', 'License', + 'Classifier', 'Download-URL', 'Obsoletes-Dist', + 'Project-URL', 'Provides-Dist', 'Requires-Dist', + 'Requires-Python', 'Requires-External', 'Private-Version', + 'Obsoleted-By', 'Setup-Requires-Dist', 'Extension', + 'Provides-Extra') + +_426_MARKERS = ('Private-Version', 'Provides-Extra', 'Obsoleted-By', + 'Setup-Requires-Dist', 'Extension') + +# See issue #106: Sometimes 'Requires' and 'Provides' occur wrongly in +# the metadata. Include them in the tuple literal below to allow them +# (for now). +_566_FIELDS = _426_FIELDS + ('Description-Content-Type', + 'Requires', 'Provides') + +_566_MARKERS = ('Description-Content-Type',) + +_ALL_FIELDS = set() +_ALL_FIELDS.update(_241_FIELDS) +_ALL_FIELDS.update(_314_FIELDS) +_ALL_FIELDS.update(_345_FIELDS) +_ALL_FIELDS.update(_426_FIELDS) +_ALL_FIELDS.update(_566_FIELDS) + +EXTRA_RE = re.compile(r'''extra\s*==\s*("([^"]+)"|'([^']+)')''') + + +def _version2fieldlist(version): + if version == '1.0': + return _241_FIELDS + elif version == '1.1': + return _314_FIELDS + elif version == '1.2': + return _345_FIELDS + elif version in ('1.3', '2.1'): + return _345_FIELDS + _566_FIELDS + elif version == '2.0': + return _426_FIELDS + raise MetadataUnrecognizedVersionError(version) + + +def _best_version(fields): + """Detect the best version depending on the fields used.""" + def _has_marker(keys, markers): + for marker in markers: + if marker in keys: + return True + return False + + keys = [] + for key, value in fields.items(): + if value in ([], 'UNKNOWN', None): + continue + keys.append(key) + + possible_versions = ['1.0', '1.1', '1.2', '1.3', '2.0', '2.1'] + + # first let's try to see if a field is not part of one of the version + for key in keys: + if key not in _241_FIELDS and '1.0' in possible_versions: + possible_versions.remove('1.0') + logger.debug('Removed 1.0 due to %s', key) + if key not in _314_FIELDS and '1.1' in possible_versions: + possible_versions.remove('1.1') + logger.debug('Removed 1.1 due to %s', key) + if key not in _345_FIELDS and '1.2' in possible_versions: + possible_versions.remove('1.2') + logger.debug('Removed 1.2 due to %s', key) + if key not in _566_FIELDS and '1.3' in possible_versions: + possible_versions.remove('1.3') + logger.debug('Removed 1.3 due to %s', key) + if key not in _566_FIELDS and '2.1' in possible_versions: + if key != 'Description': # In 2.1, description allowed after headers + possible_versions.remove('2.1') + logger.debug('Removed 2.1 due to %s', key) + if key not in _426_FIELDS and '2.0' in possible_versions: + possible_versions.remove('2.0') + logger.debug('Removed 2.0 due to %s', key) + + # possible_version contains qualified versions + if len(possible_versions) == 1: + return possible_versions[0] # found ! + elif len(possible_versions) == 0: + logger.debug('Out of options - unknown metadata set: %s', fields) + raise MetadataConflictError('Unknown metadata set') + + # let's see if one unique marker is found + is_1_1 = '1.1' in possible_versions and _has_marker(keys, _314_MARKERS) + is_1_2 = '1.2' in possible_versions and _has_marker(keys, _345_MARKERS) + is_2_1 = '2.1' in possible_versions and _has_marker(keys, _566_MARKERS) + is_2_0 = '2.0' in possible_versions and _has_marker(keys, _426_MARKERS) + if int(is_1_1) + int(is_1_2) + int(is_2_1) + int(is_2_0) > 1: + raise MetadataConflictError('You used incompatible 1.1/1.2/2.0/2.1 fields') + + # we have the choice, 1.0, or 1.2, or 2.0 + # - 1.0 has a broken Summary field but works with all tools + # - 1.1 is to avoid + # - 1.2 fixes Summary but has little adoption + # - 2.0 adds more features and is very new + if not is_1_1 and not is_1_2 and not is_2_1 and not is_2_0: + # we couldn't find any specific marker + if PKG_INFO_PREFERRED_VERSION in possible_versions: + return PKG_INFO_PREFERRED_VERSION + if is_1_1: + return '1.1' + if is_1_2: + return '1.2' + if is_2_1: + return '2.1' + + return '2.0' + +# This follows the rules about transforming keys as described in +# https://www.python.org/dev/peps/pep-0566/#id17 +_ATTR2FIELD = { + name.lower().replace("-", "_"): name for name in _ALL_FIELDS +} +_FIELD2ATTR = {field: attr for attr, field in _ATTR2FIELD.items()} + +_PREDICATE_FIELDS = ('Requires-Dist', 'Obsoletes-Dist', 'Provides-Dist') +_VERSIONS_FIELDS = ('Requires-Python',) +_VERSION_FIELDS = ('Version',) +_LISTFIELDS = ('Platform', 'Classifier', 'Obsoletes', + 'Requires', 'Provides', 'Obsoletes-Dist', + 'Provides-Dist', 'Requires-Dist', 'Requires-External', + 'Project-URL', 'Supported-Platform', 'Setup-Requires-Dist', + 'Provides-Extra', 'Extension') +_LISTTUPLEFIELDS = ('Project-URL',) + +_ELEMENTSFIELD = ('Keywords',) + +_UNICODEFIELDS = ('Author', 'Maintainer', 'Summary', 'Description') + +_MISSING = object() + +_FILESAFE = re.compile('[^A-Za-z0-9.]+') + + +def _get_name_and_version(name, version, for_filename=False): + """Return the distribution name with version. + + If for_filename is true, return a filename-escaped form.""" + if for_filename: + # For both name and version any runs of non-alphanumeric or '.' + # characters are replaced with a single '-'. Additionally any + # spaces in the version string become '.' + name = _FILESAFE.sub('-', name) + version = _FILESAFE.sub('-', version.replace(' ', '.')) + return '%s-%s' % (name, version) + + +class LegacyMetadata(object): + """The legacy metadata of a release. + + Supports versions 1.0, 1.1, 1.2, 2.0 and 1.3/2.1 (auto-detected). You can + instantiate the class with one of these arguments (or none): + - *path*, the path to a metadata file + - *fileobj* give a file-like object with metadata as content + - *mapping* is a dict-like object + - *scheme* is a version scheme name + """ + # TODO document the mapping API and UNKNOWN default key + + def __init__(self, path=None, fileobj=None, mapping=None, + scheme='default'): + if [path, fileobj, mapping].count(None) < 2: + raise TypeError('path, fileobj and mapping are exclusive') + self._fields = {} + self.requires_files = [] + self._dependencies = None + self.scheme = scheme + if path is not None: + self.read(path) + elif fileobj is not None: + self.read_file(fileobj) + elif mapping is not None: + self.update(mapping) + self.set_metadata_version() + + def set_metadata_version(self): + self._fields['Metadata-Version'] = _best_version(self._fields) + + def _write_field(self, fileobj, name, value): + fileobj.write('%s: %s\n' % (name, value)) + + def __getitem__(self, name): + return self.get(name) + + def __setitem__(self, name, value): + return self.set(name, value) + + def __delitem__(self, name): + field_name = self._convert_name(name) + try: + del self._fields[field_name] + except KeyError: + raise KeyError(name) + + def __contains__(self, name): + return (name in self._fields or + self._convert_name(name) in self._fields) + + def _convert_name(self, name): + if name in _ALL_FIELDS: + return name + name = name.replace('-', '_').lower() + return _ATTR2FIELD.get(name, name) + + def _default_value(self, name): + if name in _LISTFIELDS or name in _ELEMENTSFIELD: + return [] + return 'UNKNOWN' + + def _remove_line_prefix(self, value): + if self.metadata_version in ('1.0', '1.1'): + return _LINE_PREFIX_PRE_1_2.sub('\n', value) + else: + return _LINE_PREFIX_1_2.sub('\n', value) + + def __getattr__(self, name): + if name in _ATTR2FIELD: + return self[name] + raise AttributeError(name) + + # + # Public API + # + +# dependencies = property(_get_dependencies, _set_dependencies) + + def get_fullname(self, filesafe=False): + """Return the distribution name with version. + + If filesafe is true, return a filename-escaped form.""" + return _get_name_and_version(self['Name'], self['Version'], filesafe) + + def is_field(self, name): + """return True if name is a valid metadata key""" + name = self._convert_name(name) + return name in _ALL_FIELDS + + def is_multi_field(self, name): + name = self._convert_name(name) + return name in _LISTFIELDS + + def read(self, filepath): + """Read the metadata values from a file path.""" + fp = codecs.open(filepath, 'r', encoding='utf-8') + try: + self.read_file(fp) + finally: + fp.close() + + def read_file(self, fileob): + """Read the metadata values from a file object.""" + msg = message_from_file(fileob) + self._fields['Metadata-Version'] = msg['metadata-version'] + + # When reading, get all the fields we can + for field in _ALL_FIELDS: + if field not in msg: + continue + if field in _LISTFIELDS: + # we can have multiple lines + values = msg.get_all(field) + if field in _LISTTUPLEFIELDS and values is not None: + values = [tuple(value.split(',')) for value in values] + self.set(field, values) + else: + # single line + value = msg[field] + if value is not None and value != 'UNKNOWN': + self.set(field, value) + + # PEP 566 specifies that the body be used for the description, if + # available + body = msg.get_payload() + self["Description"] = body if body else self["Description"] + # logger.debug('Attempting to set metadata for %s', self) + # self.set_metadata_version() + + def write(self, filepath, skip_unknown=False): + """Write the metadata fields to filepath.""" + fp = codecs.open(filepath, 'w', encoding='utf-8') + try: + self.write_file(fp, skip_unknown) + finally: + fp.close() + + def write_file(self, fileobject, skip_unknown=False): + """Write the PKG-INFO format data to a file object.""" + self.set_metadata_version() + + for field in _version2fieldlist(self['Metadata-Version']): + values = self.get(field) + if skip_unknown and values in ('UNKNOWN', [], ['UNKNOWN']): + continue + if field in _ELEMENTSFIELD: + self._write_field(fileobject, field, ','.join(values)) + continue + if field not in _LISTFIELDS: + if field == 'Description': + if self.metadata_version in ('1.0', '1.1'): + values = values.replace('\n', '\n ') + else: + values = values.replace('\n', '\n |') + values = [values] + + if field in _LISTTUPLEFIELDS: + values = [','.join(value) for value in values] + + for value in values: + self._write_field(fileobject, field, value) + + def update(self, other=None, **kwargs): + """Set metadata values from the given iterable `other` and kwargs. + + Behavior is like `dict.update`: If `other` has a ``keys`` method, + they are looped over and ``self[key]`` is assigned ``other[key]``. + Else, ``other`` is an iterable of ``(key, value)`` iterables. + + Keys that don't match a metadata field or that have an empty value are + dropped. + """ + def _set(key, value): + if key in _ATTR2FIELD and value: + self.set(self._convert_name(key), value) + + if not other: + # other is None or empty container + pass + elif hasattr(other, 'keys'): + for k in other.keys(): + _set(k, other[k]) + else: + for k, v in other: + _set(k, v) + + if kwargs: + for k, v in kwargs.items(): + _set(k, v) + + def set(self, name, value): + """Control then set a metadata field.""" + name = self._convert_name(name) + + if ((name in _ELEMENTSFIELD or name == 'Platform') and + not isinstance(value, (list, tuple))): + if isinstance(value, string_types): + value = [v.strip() for v in value.split(',')] + else: + value = [] + elif (name in _LISTFIELDS and + not isinstance(value, (list, tuple))): + if isinstance(value, string_types): + value = [value] + else: + value = [] + + if logger.isEnabledFor(logging.WARNING): + project_name = self['Name'] + + scheme = get_scheme(self.scheme) + if name in _PREDICATE_FIELDS and value is not None: + for v in value: + # check that the values are valid + if not scheme.is_valid_matcher(v.split(';')[0]): + logger.warning( + "'%s': '%s' is not valid (field '%s')", + project_name, v, name) + # FIXME this rejects UNKNOWN, is that right? + elif name in _VERSIONS_FIELDS and value is not None: + if not scheme.is_valid_constraint_list(value): + logger.warning("'%s': '%s' is not a valid version (field '%s')", + project_name, value, name) + elif name in _VERSION_FIELDS and value is not None: + if not scheme.is_valid_version(value): + logger.warning("'%s': '%s' is not a valid version (field '%s')", + project_name, value, name) + + if name in _UNICODEFIELDS: + if name == 'Description': + value = self._remove_line_prefix(value) + + self._fields[name] = value + + def get(self, name, default=_MISSING): + """Get a metadata field.""" + name = self._convert_name(name) + if name not in self._fields: + if default is _MISSING: + default = self._default_value(name) + return default + if name in _UNICODEFIELDS: + value = self._fields[name] + return value + elif name in _LISTFIELDS: + value = self._fields[name] + if value is None: + return [] + res = [] + for val in value: + if name not in _LISTTUPLEFIELDS: + res.append(val) + else: + # That's for Project-URL + res.append((val[0], val[1])) + return res + + elif name in _ELEMENTSFIELD: + value = self._fields[name] + if isinstance(value, string_types): + return value.split(',') + return self._fields[name] + + def check(self, strict=False): + """Check if the metadata is compliant. If strict is True then raise if + no Name or Version are provided""" + self.set_metadata_version() + + # XXX should check the versions (if the file was loaded) + missing, warnings = [], [] + + for attr in ('Name', 'Version'): # required by PEP 345 + if attr not in self: + missing.append(attr) + + if strict and missing != []: + msg = 'missing required metadata: %s' % ', '.join(missing) + raise MetadataMissingError(msg) + + for attr in ('Home-page', 'Author'): + if attr not in self: + missing.append(attr) + + # checking metadata 1.2 (XXX needs to check 1.1, 1.0) + if self['Metadata-Version'] != '1.2': + return missing, warnings + + scheme = get_scheme(self.scheme) + + def are_valid_constraints(value): + for v in value: + if not scheme.is_valid_matcher(v.split(';')[0]): + return False + return True + + for fields, controller in ((_PREDICATE_FIELDS, are_valid_constraints), + (_VERSIONS_FIELDS, + scheme.is_valid_constraint_list), + (_VERSION_FIELDS, + scheme.is_valid_version)): + for field in fields: + value = self.get(field, None) + if value is not None and not controller(value): + warnings.append("Wrong value for '%s': %s" % (field, value)) + + return missing, warnings + + def todict(self, skip_missing=False): + """Return fields as a dict. + + Field names will be converted to use the underscore-lowercase style + instead of hyphen-mixed case (i.e. home_page instead of Home-page). + This is as per https://www.python.org/dev/peps/pep-0566/#id17. + """ + self.set_metadata_version() + + fields = _version2fieldlist(self['Metadata-Version']) + + data = {} + + for field_name in fields: + if not skip_missing or field_name in self._fields: + key = _FIELD2ATTR[field_name] + if key != 'project_url': + data[key] = self[field_name] + else: + data[key] = [','.join(u) for u in self[field_name]] + + return data + + def add_requirements(self, requirements): + if self['Metadata-Version'] == '1.1': + # we can't have 1.1 metadata *and* Setuptools requires + for field in ('Obsoletes', 'Requires', 'Provides'): + if field in self: + del self[field] + self['Requires-Dist'] += requirements + + # Mapping API + # TODO could add iter* variants + + def keys(self): + return list(_version2fieldlist(self['Metadata-Version'])) + + def __iter__(self): + for key in self.keys(): + yield key + + def values(self): + return [self[key] for key in self.keys()] + + def items(self): + return [(key, self[key]) for key in self.keys()] + + def __repr__(self): + return '<%s %s %s>' % (self.__class__.__name__, self.name, + self.version) + + +METADATA_FILENAME = 'pydist.json' +WHEEL_METADATA_FILENAME = 'metadata.json' +LEGACY_METADATA_FILENAME = 'METADATA' + + +class Metadata(object): + """ + The metadata of a release. This implementation uses 2.0 (JSON) + metadata where possible. If not possible, it wraps a LegacyMetadata + instance which handles the key-value metadata format. + """ + + METADATA_VERSION_MATCHER = re.compile(r'^\d+(\.\d+)*$') + + NAME_MATCHER = re.compile('^[0-9A-Z]([0-9A-Z_.-]*[0-9A-Z])?$', re.I) + + VERSION_MATCHER = PEP440_VERSION_RE + + SUMMARY_MATCHER = re.compile('.{1,2047}') + + METADATA_VERSION = '2.0' + + GENERATOR = 'distlib (%s)' % __version__ + + MANDATORY_KEYS = { + 'name': (), + 'version': (), + 'summary': ('legacy',), + } + + INDEX_KEYS = ('name version license summary description author ' + 'author_email keywords platform home_page classifiers ' + 'download_url') + + DEPENDENCY_KEYS = ('extras run_requires test_requires build_requires ' + 'dev_requires provides meta_requires obsoleted_by ' + 'supports_environments') + + SYNTAX_VALIDATORS = { + 'metadata_version': (METADATA_VERSION_MATCHER, ()), + 'name': (NAME_MATCHER, ('legacy',)), + 'version': (VERSION_MATCHER, ('legacy',)), + 'summary': (SUMMARY_MATCHER, ('legacy',)), + } + + __slots__ = ('_legacy', '_data', 'scheme') + + def __init__(self, path=None, fileobj=None, mapping=None, + scheme='default'): + if [path, fileobj, mapping].count(None) < 2: + raise TypeError('path, fileobj and mapping are exclusive') + self._legacy = None + self._data = None + self.scheme = scheme + #import pdb; pdb.set_trace() + if mapping is not None: + try: + self._validate_mapping(mapping, scheme) + self._data = mapping + except MetadataUnrecognizedVersionError: + self._legacy = LegacyMetadata(mapping=mapping, scheme=scheme) + self.validate() + else: + data = None + if path: + with open(path, 'rb') as f: + data = f.read() + elif fileobj: + data = fileobj.read() + if data is None: + # Initialised with no args - to be added + self._data = { + 'metadata_version': self.METADATA_VERSION, + 'generator': self.GENERATOR, + } + else: + if not isinstance(data, text_type): + data = data.decode('utf-8') + try: + self._data = json.loads(data) + self._validate_mapping(self._data, scheme) + except ValueError: + # Note: MetadataUnrecognizedVersionError does not + # inherit from ValueError (it's a DistlibException, + # which should not inherit from ValueError). + # The ValueError comes from the json.load - if that + # succeeds and we get a validation error, we want + # that to propagate + self._legacy = LegacyMetadata(fileobj=StringIO(data), + scheme=scheme) + self.validate() + + common_keys = set(('name', 'version', 'license', 'keywords', 'summary')) + + none_list = (None, list) + none_dict = (None, dict) + + mapped_keys = { + 'run_requires': ('Requires-Dist', list), + 'build_requires': ('Setup-Requires-Dist', list), + 'dev_requires': none_list, + 'test_requires': none_list, + 'meta_requires': none_list, + 'extras': ('Provides-Extra', list), + 'modules': none_list, + 'namespaces': none_list, + 'exports': none_dict, + 'commands': none_dict, + 'classifiers': ('Classifier', list), + 'source_url': ('Download-URL', None), + 'metadata_version': ('Metadata-Version', None), + } + + del none_list, none_dict + + def __getattribute__(self, key): + common = object.__getattribute__(self, 'common_keys') + mapped = object.__getattribute__(self, 'mapped_keys') + if key in mapped: + lk, maker = mapped[key] + if self._legacy: + if lk is None: + result = None if maker is None else maker() + else: + result = self._legacy.get(lk) + else: + value = None if maker is None else maker() + if key not in ('commands', 'exports', 'modules', 'namespaces', + 'classifiers'): + result = self._data.get(key, value) + else: + # special cases for PEP 459 + sentinel = object() + result = sentinel + d = self._data.get('extensions') + if d: + if key == 'commands': + result = d.get('python.commands', value) + elif key == 'classifiers': + d = d.get('python.details') + if d: + result = d.get(key, value) + else: + d = d.get('python.exports') + if not d: + d = self._data.get('python.exports') + if d: + result = d.get(key, value) + if result is sentinel: + result = value + elif key not in common: + result = object.__getattribute__(self, key) + elif self._legacy: + result = self._legacy.get(key) + else: + result = self._data.get(key) + return result + + def _validate_value(self, key, value, scheme=None): + if key in self.SYNTAX_VALIDATORS: + pattern, exclusions = self.SYNTAX_VALIDATORS[key] + if (scheme or self.scheme) not in exclusions: + m = pattern.match(value) + if not m: + raise MetadataInvalidError("'%s' is an invalid value for " + "the '%s' property" % (value, + key)) + + def __setattr__(self, key, value): + self._validate_value(key, value) + common = object.__getattribute__(self, 'common_keys') + mapped = object.__getattribute__(self, 'mapped_keys') + if key in mapped: + lk, _ = mapped[key] + if self._legacy: + if lk is None: + raise NotImplementedError + self._legacy[lk] = value + elif key not in ('commands', 'exports', 'modules', 'namespaces', + 'classifiers'): + self._data[key] = value + else: + # special cases for PEP 459 + d = self._data.setdefault('extensions', {}) + if key == 'commands': + d['python.commands'] = value + elif key == 'classifiers': + d = d.setdefault('python.details', {}) + d[key] = value + else: + d = d.setdefault('python.exports', {}) + d[key] = value + elif key not in common: + object.__setattr__(self, key, value) + else: + if key == 'keywords': + if isinstance(value, string_types): + value = value.strip() + if value: + value = value.split() + else: + value = [] + if self._legacy: + self._legacy[key] = value + else: + self._data[key] = value + + @property + def name_and_version(self): + return _get_name_and_version(self.name, self.version, True) + + @property + def provides(self): + if self._legacy: + result = self._legacy['Provides-Dist'] + else: + result = self._data.setdefault('provides', []) + s = '%s (%s)' % (self.name, self.version) + if s not in result: + result.append(s) + return result + + @provides.setter + def provides(self, value): + if self._legacy: + self._legacy['Provides-Dist'] = value + else: + self._data['provides'] = value + + def get_requirements(self, reqts, extras=None, env=None): + """ + Base method to get dependencies, given a set of extras + to satisfy and an optional environment context. + :param reqts: A list of sometimes-wanted dependencies, + perhaps dependent on extras and environment. + :param extras: A list of optional components being requested. + :param env: An optional environment for marker evaluation. + """ + if self._legacy: + result = reqts + else: + result = [] + extras = get_extras(extras or [], self.extras) + for d in reqts: + if 'extra' not in d and 'environment' not in d: + # unconditional + include = True + else: + if 'extra' not in d: + # Not extra-dependent - only environment-dependent + include = True + else: + include = d.get('extra') in extras + if include: + # Not excluded because of extras, check environment + marker = d.get('environment') + if marker: + include = interpret(marker, env) + if include: + result.extend(d['requires']) + for key in ('build', 'dev', 'test'): + e = ':%s:' % key + if e in extras: + extras.remove(e) + # A recursive call, but it should terminate since 'test' + # has been removed from the extras + reqts = self._data.get('%s_requires' % key, []) + result.extend(self.get_requirements(reqts, extras=extras, + env=env)) + return result + + @property + def dictionary(self): + if self._legacy: + return self._from_legacy() + return self._data + + @property + def dependencies(self): + if self._legacy: + raise NotImplementedError + else: + return extract_by_key(self._data, self.DEPENDENCY_KEYS) + + @dependencies.setter + def dependencies(self, value): + if self._legacy: + raise NotImplementedError + else: + self._data.update(value) + + def _validate_mapping(self, mapping, scheme): + if mapping.get('metadata_version') != self.METADATA_VERSION: + raise MetadataUnrecognizedVersionError() + missing = [] + for key, exclusions in self.MANDATORY_KEYS.items(): + if key not in mapping: + if scheme not in exclusions: + missing.append(key) + if missing: + msg = 'Missing metadata items: %s' % ', '.join(missing) + raise MetadataMissingError(msg) + for k, v in mapping.items(): + self._validate_value(k, v, scheme) + + def validate(self): + if self._legacy: + missing, warnings = self._legacy.check(True) + if missing or warnings: + logger.warning('Metadata: missing: %s, warnings: %s', + missing, warnings) + else: + self._validate_mapping(self._data, self.scheme) + + def todict(self): + if self._legacy: + return self._legacy.todict(True) + else: + result = extract_by_key(self._data, self.INDEX_KEYS) + return result + + def _from_legacy(self): + assert self._legacy and not self._data + result = { + 'metadata_version': self.METADATA_VERSION, + 'generator': self.GENERATOR, + } + lmd = self._legacy.todict(True) # skip missing ones + for k in ('name', 'version', 'license', 'summary', 'description', + 'classifier'): + if k in lmd: + if k == 'classifier': + nk = 'classifiers' + else: + nk = k + result[nk] = lmd[k] + kw = lmd.get('Keywords', []) + if kw == ['']: + kw = [] + result['keywords'] = kw + keys = (('requires_dist', 'run_requires'), + ('setup_requires_dist', 'build_requires')) + for ok, nk in keys: + if ok in lmd and lmd[ok]: + result[nk] = [{'requires': lmd[ok]}] + result['provides'] = self.provides + author = {} + maintainer = {} + return result + + LEGACY_MAPPING = { + 'name': 'Name', + 'version': 'Version', + ('extensions', 'python.details', 'license'): 'License', + 'summary': 'Summary', + 'description': 'Description', + ('extensions', 'python.project', 'project_urls', 'Home'): 'Home-page', + ('extensions', 'python.project', 'contacts', 0, 'name'): 'Author', + ('extensions', 'python.project', 'contacts', 0, 'email'): 'Author-email', + 'source_url': 'Download-URL', + ('extensions', 'python.details', 'classifiers'): 'Classifier', + } + + def _to_legacy(self): + def process_entries(entries): + reqts = set() + for e in entries: + extra = e.get('extra') + env = e.get('environment') + rlist = e['requires'] + for r in rlist: + if not env and not extra: + reqts.add(r) + else: + marker = '' + if extra: + marker = 'extra == "%s"' % extra + if env: + if marker: + marker = '(%s) and %s' % (env, marker) + else: + marker = env + reqts.add(';'.join((r, marker))) + return reqts + + assert self._data and not self._legacy + result = LegacyMetadata() + nmd = self._data + # import pdb; pdb.set_trace() + for nk, ok in self.LEGACY_MAPPING.items(): + if not isinstance(nk, tuple): + if nk in nmd: + result[ok] = nmd[nk] + else: + d = nmd + found = True + for k in nk: + try: + d = d[k] + except (KeyError, IndexError): + found = False + break + if found: + result[ok] = d + r1 = process_entries(self.run_requires + self.meta_requires) + r2 = process_entries(self.build_requires + self.dev_requires) + if self.extras: + result['Provides-Extra'] = sorted(self.extras) + result['Requires-Dist'] = sorted(r1) + result['Setup-Requires-Dist'] = sorted(r2) + # TODO: any other fields wanted + return result + + def write(self, path=None, fileobj=None, legacy=False, skip_unknown=True): + if [path, fileobj].count(None) != 1: + raise ValueError('Exactly one of path and fileobj is needed') + self.validate() + if legacy: + if self._legacy: + legacy_md = self._legacy + else: + legacy_md = self._to_legacy() + if path: + legacy_md.write(path, skip_unknown=skip_unknown) + else: + legacy_md.write_file(fileobj, skip_unknown=skip_unknown) + else: + if self._legacy: + d = self._from_legacy() + else: + d = self._data + if fileobj: + json.dump(d, fileobj, ensure_ascii=True, indent=2, + sort_keys=True) + else: + with codecs.open(path, 'w', 'utf-8') as f: + json.dump(d, f, ensure_ascii=True, indent=2, + sort_keys=True) + + def add_requirements(self, requirements): + if self._legacy: + self._legacy.add_requirements(requirements) + else: + run_requires = self._data.setdefault('run_requires', []) + always = None + for entry in run_requires: + if 'environment' not in entry and 'extra' not in entry: + always = entry + break + if always is None: + always = { 'requires': requirements } + run_requires.insert(0, always) + else: + rset = set(always['requires']) | set(requirements) + always['requires'] = sorted(rset) + + def __repr__(self): + name = self.name or '(no name)' + version = self.version or 'no version' + return '<%s %s %s (%s)>' % (self.__class__.__name__, + self.metadata_version, name, version) diff --git a/venv/Lib/site-packages/pip/_vendor/distlib/resources.py b/venv/Lib/site-packages/pip/_vendor/distlib/resources.py new file mode 100644 index 0000000..1884016 --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/distlib/resources.py @@ -0,0 +1,355 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2013-2017 Vinay Sajip. +# Licensed to the Python Software Foundation under a contributor agreement. +# See LICENSE.txt and CONTRIBUTORS.txt. +# +from __future__ import unicode_literals + +import bisect +import io +import logging +import os +import pkgutil +import shutil +import sys +import types +import zipimport + +from . import DistlibException +from .util import cached_property, get_cache_base, path_to_cache_dir, Cache + +logger = logging.getLogger(__name__) + + +cache = None # created when needed + + +class ResourceCache(Cache): + def __init__(self, base=None): + if base is None: + # Use native string to avoid issues on 2.x: see Python #20140. + base = os.path.join(get_cache_base(), str('resource-cache')) + super(ResourceCache, self).__init__(base) + + def is_stale(self, resource, path): + """ + Is the cache stale for the given resource? + + :param resource: The :class:`Resource` being cached. + :param path: The path of the resource in the cache. + :return: True if the cache is stale. + """ + # Cache invalidation is a hard problem :-) + return True + + def get(self, resource): + """ + Get a resource into the cache, + + :param resource: A :class:`Resource` instance. + :return: The pathname of the resource in the cache. + """ + prefix, path = resource.finder.get_cache_info(resource) + if prefix is None: + result = path + else: + result = os.path.join(self.base, self.prefix_to_dir(prefix), path) + dirname = os.path.dirname(result) + if not os.path.isdir(dirname): + os.makedirs(dirname) + if not os.path.exists(result): + stale = True + else: + stale = self.is_stale(resource, path) + if stale: + # write the bytes of the resource to the cache location + with open(result, 'wb') as f: + f.write(resource.bytes) + return result + + +class ResourceBase(object): + def __init__(self, finder, name): + self.finder = finder + self.name = name + + +class Resource(ResourceBase): + """ + A class representing an in-package resource, such as a data file. This is + not normally instantiated by user code, but rather by a + :class:`ResourceFinder` which manages the resource. + """ + is_container = False # Backwards compatibility + + def as_stream(self): + """ + Get the resource as a stream. + + This is not a property to make it obvious that it returns a new stream + each time. + """ + return self.finder.get_stream(self) + + @cached_property + def file_path(self): + global cache + if cache is None: + cache = ResourceCache() + return cache.get(self) + + @cached_property + def bytes(self): + return self.finder.get_bytes(self) + + @cached_property + def size(self): + return self.finder.get_size(self) + + +class ResourceContainer(ResourceBase): + is_container = True # Backwards compatibility + + @cached_property + def resources(self): + return self.finder.get_resources(self) + + +class ResourceFinder(object): + """ + Resource finder for file system resources. + """ + + if sys.platform.startswith('java'): + skipped_extensions = ('.pyc', '.pyo', '.class') + else: + skipped_extensions = ('.pyc', '.pyo') + + def __init__(self, module): + self.module = module + self.loader = getattr(module, '__loader__', None) + self.base = os.path.dirname(getattr(module, '__file__', '')) + + def _adjust_path(self, path): + return os.path.realpath(path) + + def _make_path(self, resource_name): + # Issue #50: need to preserve type of path on Python 2.x + # like os.path._get_sep + if isinstance(resource_name, bytes): # should only happen on 2.x + sep = b'/' + else: + sep = '/' + parts = resource_name.split(sep) + parts.insert(0, self.base) + result = os.path.join(*parts) + return self._adjust_path(result) + + def _find(self, path): + return os.path.exists(path) + + def get_cache_info(self, resource): + return None, resource.path + + def find(self, resource_name): + path = self._make_path(resource_name) + if not self._find(path): + result = None + else: + if self._is_directory(path): + result = ResourceContainer(self, resource_name) + else: + result = Resource(self, resource_name) + result.path = path + return result + + def get_stream(self, resource): + return open(resource.path, 'rb') + + def get_bytes(self, resource): + with open(resource.path, 'rb') as f: + return f.read() + + def get_size(self, resource): + return os.path.getsize(resource.path) + + def get_resources(self, resource): + def allowed(f): + return (f != '__pycache__' and not + f.endswith(self.skipped_extensions)) + return set([f for f in os.listdir(resource.path) if allowed(f)]) + + def is_container(self, resource): + return self._is_directory(resource.path) + + _is_directory = staticmethod(os.path.isdir) + + def iterator(self, resource_name): + resource = self.find(resource_name) + if resource is not None: + todo = [resource] + while todo: + resource = todo.pop(0) + yield resource + if resource.is_container: + rname = resource.name + for name in resource.resources: + if not rname: + new_name = name + else: + new_name = '/'.join([rname, name]) + child = self.find(new_name) + if child.is_container: + todo.append(child) + else: + yield child + + +class ZipResourceFinder(ResourceFinder): + """ + Resource finder for resources in .zip files. + """ + def __init__(self, module): + super(ZipResourceFinder, self).__init__(module) + archive = self.loader.archive + self.prefix_len = 1 + len(archive) + # PyPy doesn't have a _files attr on zipimporter, and you can't set one + if hasattr(self.loader, '_files'): + self._files = self.loader._files + else: + self._files = zipimport._zip_directory_cache[archive] + self.index = sorted(self._files) + + def _adjust_path(self, path): + return path + + def _find(self, path): + path = path[self.prefix_len:] + if path in self._files: + result = True + else: + if path and path[-1] != os.sep: + path = path + os.sep + i = bisect.bisect(self.index, path) + try: + result = self.index[i].startswith(path) + except IndexError: + result = False + if not result: + logger.debug('_find failed: %r %r', path, self.loader.prefix) + else: + logger.debug('_find worked: %r %r', path, self.loader.prefix) + return result + + def get_cache_info(self, resource): + prefix = self.loader.archive + path = resource.path[1 + len(prefix):] + return prefix, path + + def get_bytes(self, resource): + return self.loader.get_data(resource.path) + + def get_stream(self, resource): + return io.BytesIO(self.get_bytes(resource)) + + def get_size(self, resource): + path = resource.path[self.prefix_len:] + return self._files[path][3] + + def get_resources(self, resource): + path = resource.path[self.prefix_len:] + if path and path[-1] != os.sep: + path += os.sep + plen = len(path) + result = set() + i = bisect.bisect(self.index, path) + while i < len(self.index): + if not self.index[i].startswith(path): + break + s = self.index[i][plen:] + result.add(s.split(os.sep, 1)[0]) # only immediate children + i += 1 + return result + + def _is_directory(self, path): + path = path[self.prefix_len:] + if path and path[-1] != os.sep: + path += os.sep + i = bisect.bisect(self.index, path) + try: + result = self.index[i].startswith(path) + except IndexError: + result = False + return result + +_finder_registry = { + type(None): ResourceFinder, + zipimport.zipimporter: ZipResourceFinder +} + +try: + # In Python 3.6, _frozen_importlib -> _frozen_importlib_external + try: + import _frozen_importlib_external as _fi + except ImportError: + import _frozen_importlib as _fi + _finder_registry[_fi.SourceFileLoader] = ResourceFinder + _finder_registry[_fi.FileFinder] = ResourceFinder + del _fi +except (ImportError, AttributeError): + pass + + +def register_finder(loader, finder_maker): + _finder_registry[type(loader)] = finder_maker + +_finder_cache = {} + + +def finder(package): + """ + Return a resource finder for a package. + :param package: The name of the package. + :return: A :class:`ResourceFinder` instance for the package. + """ + if package in _finder_cache: + result = _finder_cache[package] + else: + if package not in sys.modules: + __import__(package) + module = sys.modules[package] + path = getattr(module, '__path__', None) + if path is None: + raise DistlibException('You cannot get a finder for a module, ' + 'only for a package') + loader = getattr(module, '__loader__', None) + finder_maker = _finder_registry.get(type(loader)) + if finder_maker is None: + raise DistlibException('Unable to locate finder for %r' % package) + result = finder_maker(module) + _finder_cache[package] = result + return result + + +_dummy_module = types.ModuleType(str('__dummy__')) + + +def finder_for_path(path): + """ + Return a resource finder for a path, which should represent a container. + + :param path: The path. + :return: A :class:`ResourceFinder` instance for the path. + """ + result = None + # calls any path hooks, gets importer into cache + pkgutil.get_importer(path) + loader = sys.path_importer_cache.get(path) + finder = _finder_registry.get(type(loader)) + if finder: + module = _dummy_module + module.__file__ = os.path.join(path, '') + module.__loader__ = loader + result = finder(module) + return result diff --git a/venv/Lib/site-packages/pip/_vendor/distlib/scripts.py b/venv/Lib/site-packages/pip/_vendor/distlib/scripts.py new file mode 100644 index 0000000..03f8f21 --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/distlib/scripts.py @@ -0,0 +1,419 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2013-2015 Vinay Sajip. +# Licensed to the Python Software Foundation under a contributor agreement. +# See LICENSE.txt and CONTRIBUTORS.txt. +# +from io import BytesIO +import logging +import os +import re +import struct +import sys + +from .compat import sysconfig, detect_encoding, ZipFile +from .resources import finder +from .util import (FileOperator, get_export_entry, convert_path, + get_executable, in_venv) + +logger = logging.getLogger(__name__) + +_DEFAULT_MANIFEST = ''' + + + + + + + + + + + + +'''.strip() + +# check if Python is called on the first line with this expression +FIRST_LINE_RE = re.compile(b'^#!.*pythonw?[0-9.]*([ \t].*)?$') +SCRIPT_TEMPLATE = r'''# -*- coding: utf-8 -*- +import re +import sys +from %(module)s import %(import_name)s +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(%(func)s()) +''' + + +def enquote_executable(executable): + if ' ' in executable: + # make sure we quote only the executable in case of env + # for example /usr/bin/env "/dir with spaces/bin/jython" + # instead of "/usr/bin/env /dir with spaces/bin/jython" + # otherwise whole + if executable.startswith('/usr/bin/env '): + env, _executable = executable.split(' ', 1) + if ' ' in _executable and not _executable.startswith('"'): + executable = '%s "%s"' % (env, _executable) + else: + if not executable.startswith('"'): + executable = '"%s"' % executable + return executable + +# Keep the old name around (for now), as there is at least one project using it! +_enquote_executable = enquote_executable + +class ScriptMaker(object): + """ + A class to copy or create scripts from source scripts or callable + specifications. + """ + script_template = SCRIPT_TEMPLATE + + executable = None # for shebangs + + def __init__(self, source_dir, target_dir, add_launchers=True, + dry_run=False, fileop=None): + self.source_dir = source_dir + self.target_dir = target_dir + self.add_launchers = add_launchers + self.force = False + self.clobber = False + # It only makes sense to set mode bits on POSIX. + self.set_mode = (os.name == 'posix') or (os.name == 'java' and + os._name == 'posix') + self.variants = set(('', 'X.Y')) + self._fileop = fileop or FileOperator(dry_run) + + self._is_nt = os.name == 'nt' or ( + os.name == 'java' and os._name == 'nt') + self.version_info = sys.version_info + + def _get_alternate_executable(self, executable, options): + if options.get('gui', False) and self._is_nt: # pragma: no cover + dn, fn = os.path.split(executable) + fn = fn.replace('python', 'pythonw') + executable = os.path.join(dn, fn) + return executable + + if sys.platform.startswith('java'): # pragma: no cover + def _is_shell(self, executable): + """ + Determine if the specified executable is a script + (contains a #! line) + """ + try: + with open(executable) as fp: + return fp.read(2) == '#!' + except (OSError, IOError): + logger.warning('Failed to open %s', executable) + return False + + def _fix_jython_executable(self, executable): + if self._is_shell(executable): + # Workaround for Jython is not needed on Linux systems. + import java + + if java.lang.System.getProperty('os.name') == 'Linux': + return executable + elif executable.lower().endswith('jython.exe'): + # Use wrapper exe for Jython on Windows + return executable + return '/usr/bin/env %s' % executable + + def _build_shebang(self, executable, post_interp): + """ + Build a shebang line. In the simple case (on Windows, or a shebang line + which is not too long or contains spaces) use a simple formulation for + the shebang. Otherwise, use /bin/sh as the executable, with a contrived + shebang which allows the script to run either under Python or sh, using + suitable quoting. Thanks to Harald Nordgren for his input. + + See also: http://www.in-ulm.de/~mascheck/various/shebang/#length + https://hg.mozilla.org/mozilla-central/file/tip/mach + """ + if os.name != 'posix': + simple_shebang = True + else: + # Add 3 for '#!' prefix and newline suffix. + shebang_length = len(executable) + len(post_interp) + 3 + if sys.platform == 'darwin': + max_shebang_length = 512 + else: + max_shebang_length = 127 + simple_shebang = ((b' ' not in executable) and + (shebang_length <= max_shebang_length)) + + if simple_shebang: + result = b'#!' + executable + post_interp + b'\n' + else: + result = b'#!/bin/sh\n' + result += b"'''exec' " + executable + post_interp + b' "$0" "$@"\n' + result += b"' '''" + return result + + def _get_shebang(self, encoding, post_interp=b'', options=None): + enquote = True + if self.executable: + executable = self.executable + enquote = False # assume this will be taken care of + elif not sysconfig.is_python_build(): + executable = get_executable() + elif in_venv(): # pragma: no cover + executable = os.path.join(sysconfig.get_path('scripts'), + 'python%s' % sysconfig.get_config_var('EXE')) + else: # pragma: no cover + executable = os.path.join( + sysconfig.get_config_var('BINDIR'), + 'python%s%s' % (sysconfig.get_config_var('VERSION'), + sysconfig.get_config_var('EXE'))) + if options: + executable = self._get_alternate_executable(executable, options) + + if sys.platform.startswith('java'): # pragma: no cover + executable = self._fix_jython_executable(executable) + + # Normalise case for Windows - COMMENTED OUT + # executable = os.path.normcase(executable) + # N.B. The normalising operation above has been commented out: See + # issue #124. Although paths in Windows are generally case-insensitive, + # they aren't always. For example, a path containing a ẞ (which is a + # LATIN CAPITAL LETTER SHARP S - U+1E9E) is normcased to ß (which is a + # LATIN SMALL LETTER SHARP S' - U+00DF). The two are not considered by + # Windows as equivalent in path names. + + # If the user didn't specify an executable, it may be necessary to + # cater for executable paths with spaces (not uncommon on Windows) + if enquote: + executable = enquote_executable(executable) + # Issue #51: don't use fsencode, since we later try to + # check that the shebang is decodable using utf-8. + executable = executable.encode('utf-8') + # in case of IronPython, play safe and enable frames support + if (sys.platform == 'cli' and '-X:Frames' not in post_interp + and '-X:FullFrames' not in post_interp): # pragma: no cover + post_interp += b' -X:Frames' + shebang = self._build_shebang(executable, post_interp) + # Python parser starts to read a script using UTF-8 until + # it gets a #coding:xxx cookie. The shebang has to be the + # first line of a file, the #coding:xxx cookie cannot be + # written before. So the shebang has to be decodable from + # UTF-8. + try: + shebang.decode('utf-8') + except UnicodeDecodeError: # pragma: no cover + raise ValueError( + 'The shebang (%r) is not decodable from utf-8' % shebang) + # If the script is encoded to a custom encoding (use a + # #coding:xxx cookie), the shebang has to be decodable from + # the script encoding too. + if encoding != 'utf-8': + try: + shebang.decode(encoding) + except UnicodeDecodeError: # pragma: no cover + raise ValueError( + 'The shebang (%r) is not decodable ' + 'from the script encoding (%r)' % (shebang, encoding)) + return shebang + + def _get_script_text(self, entry): + return self.script_template % dict(module=entry.prefix, + import_name=entry.suffix.split('.')[0], + func=entry.suffix) + + manifest = _DEFAULT_MANIFEST + + def get_manifest(self, exename): + base = os.path.basename(exename) + return self.manifest % base + + def _write_script(self, names, shebang, script_bytes, filenames, ext): + use_launcher = self.add_launchers and self._is_nt + linesep = os.linesep.encode('utf-8') + if not shebang.endswith(linesep): + shebang += linesep + if not use_launcher: + script_bytes = shebang + script_bytes + else: # pragma: no cover + if ext == 'py': + launcher = self._get_launcher('t') + else: + launcher = self._get_launcher('w') + stream = BytesIO() + with ZipFile(stream, 'w') as zf: + zf.writestr('__main__.py', script_bytes) + zip_data = stream.getvalue() + script_bytes = launcher + shebang + zip_data + for name in names: + outname = os.path.join(self.target_dir, name) + if use_launcher: # pragma: no cover + n, e = os.path.splitext(outname) + if e.startswith('.py'): + outname = n + outname = '%s.exe' % outname + try: + self._fileop.write_binary_file(outname, script_bytes) + except Exception: + # Failed writing an executable - it might be in use. + logger.warning('Failed to write executable - trying to ' + 'use .deleteme logic') + dfname = '%s.deleteme' % outname + if os.path.exists(dfname): + os.remove(dfname) # Not allowed to fail here + os.rename(outname, dfname) # nor here + self._fileop.write_binary_file(outname, script_bytes) + logger.debug('Able to replace executable using ' + '.deleteme logic') + try: + os.remove(dfname) + except Exception: + pass # still in use - ignore error + else: + if self._is_nt and not outname.endswith('.' + ext): # pragma: no cover + outname = '%s.%s' % (outname, ext) + if os.path.exists(outname) and not self.clobber: + logger.warning('Skipping existing file %s', outname) + continue + self._fileop.write_binary_file(outname, script_bytes) + if self.set_mode: + self._fileop.set_executable_mode([outname]) + filenames.append(outname) + + def _make_script(self, entry, filenames, options=None): + post_interp = b'' + if options: + args = options.get('interpreter_args', []) + if args: + args = ' %s' % ' '.join(args) + post_interp = args.encode('utf-8') + shebang = self._get_shebang('utf-8', post_interp, options=options) + script = self._get_script_text(entry).encode('utf-8') + name = entry.name + scriptnames = set() + if '' in self.variants: + scriptnames.add(name) + if 'X' in self.variants: + scriptnames.add('%s%s' % (name, self.version_info[0])) + if 'X.Y' in self.variants: + scriptnames.add('%s-%s.%s' % (name, self.version_info[0], + self.version_info[1])) + if options and options.get('gui', False): + ext = 'pyw' + else: + ext = 'py' + self._write_script(scriptnames, shebang, script, filenames, ext) + + def _copy_script(self, script, filenames): + adjust = False + script = os.path.join(self.source_dir, convert_path(script)) + outname = os.path.join(self.target_dir, os.path.basename(script)) + if not self.force and not self._fileop.newer(script, outname): + logger.debug('not copying %s (up-to-date)', script) + return + + # Always open the file, but ignore failures in dry-run mode -- + # that way, we'll get accurate feedback if we can read the + # script. + try: + f = open(script, 'rb') + except IOError: # pragma: no cover + if not self.dry_run: + raise + f = None + else: + first_line = f.readline() + if not first_line: # pragma: no cover + logger.warning('%s: %s is an empty file (skipping)', + self.get_command_name(), script) + return + + match = FIRST_LINE_RE.match(first_line.replace(b'\r\n', b'\n')) + if match: + adjust = True + post_interp = match.group(1) or b'' + + if not adjust: + if f: + f.close() + self._fileop.copy_file(script, outname) + if self.set_mode: + self._fileop.set_executable_mode([outname]) + filenames.append(outname) + else: + logger.info('copying and adjusting %s -> %s', script, + self.target_dir) + if not self._fileop.dry_run: + encoding, lines = detect_encoding(f.readline) + f.seek(0) + shebang = self._get_shebang(encoding, post_interp) + if b'pythonw' in first_line: # pragma: no cover + ext = 'pyw' + else: + ext = 'py' + n = os.path.basename(outname) + self._write_script([n], shebang, f.read(), filenames, ext) + if f: + f.close() + + @property + def dry_run(self): + return self._fileop.dry_run + + @dry_run.setter + def dry_run(self, value): + self._fileop.dry_run = value + + if os.name == 'nt' or (os.name == 'java' and os._name == 'nt'): # pragma: no cover + # Executable launcher support. + # Launchers are from https://bitbucket.org/vinay.sajip/simple_launcher/ + + def _get_launcher(self, kind): + if struct.calcsize('P') == 8: # 64-bit + bits = '64' + else: + bits = '32' + name = '%s%s.exe' % (kind, bits) + # Issue 31: don't hardcode an absolute package name, but + # determine it relative to the current package + distlib_package = __name__.rsplit('.', 1)[0] + resource = finder(distlib_package).find(name) + if not resource: + msg = ('Unable to find resource %s in package %s' % (name, + distlib_package)) + raise ValueError(msg) + return resource.bytes + + # Public API follows + + def make(self, specification, options=None): + """ + Make a script. + + :param specification: The specification, which is either a valid export + entry specification (to make a script from a + callable) or a filename (to make a script by + copying from a source location). + :param options: A dictionary of options controlling script generation. + :return: A list of all absolute pathnames written to. + """ + filenames = [] + entry = get_export_entry(specification) + if entry is None: + self._copy_script(specification, filenames) + else: + self._make_script(entry, filenames, options=options) + return filenames + + def make_multiple(self, specifications, options=None): + """ + Take a list of specifications and make scripts from them, + :param specifications: A list of specifications. + :return: A list of all absolute pathnames written to, + """ + filenames = [] + for specification in specifications: + filenames.extend(self.make(specification, options)) + return filenames diff --git a/venv/Lib/site-packages/pip/_vendor/distlib/t32.exe b/venv/Lib/site-packages/pip/_vendor/distlib/t32.exe new file mode 100644 index 0000000000000000000000000000000000000000..8932a18e4596952373a38c60b81b7116d4ef9ee8 GIT binary patch literal 96768 zcmeFaeSB2awLg3&Gf5_4k~2Vp;XOi7B#6;~5{KX*Oo&QwFfv1g09K6SNEP86z)B$T zWNc0jqu8r$y;oW(+DogqrLDa95=;nYprS^6qs3}$sqXP`HI^6#i8;UT+UHCX)Z5$V z^LbwWdC<(+XYaM&)?Rz4eT?bf^RzDLUc-tGBo<-7CmygPs1jg|S|zh~9$ z)3UNM3#_8I{_g1d!yUhvl>A%zv#Tc^!TVbk8I$7tIcrjkKb@0)hiB`q%O|~t=i!c> zlYY$OT^9UI>v;`--gM_}Au98mJ@ESkVSz1G*mCjL%aUoGLW*sOEmIKQMa+|Cto;f+ z-T0$U5;iEDA_%F1jUxJ=LI>V~ysLU`z@xXG0}?D{;LrXCMG8eZHenV8R@#K8{1o`c zzZRR&n1N<|AqZo>ku><#FWSx@qb@;MVm56sSbun$bo)jLZ=>GE54DT>N`pS=Up`tj zZSAUCrCTwsQ;~o&g=zTvGyVqs^8z8$Ofccll}N}(#Z;#A{00E7W!lR_gos}J><*Bnawx}4@P}q)&JkExL|lv4&zgr&qAP4O za)mChpjGr1zsA0gsdc2ytO-T@&o!MpzouUVk~Ja0AKFMY3CWrc=6**__GC?3g)>-e zM9X^p;(^qbX>$bsB32I)McX1R(&*I?9 zO$`J?KSiBUUvIGyTIoR{YHhDt+r{ogHN{6fG4avX(35~z#Ks$j5l#sjaxeR0G&m`q z-FbrWxawo6y?utE94b&3pHh7ZPpsCi)+PX%AfQ7gaL55l58Eo)8##hdsdcdul&2iZ z_r#%|Tvx)%5 zMDAvHqXIlp#k**h)>Yi%IU_#S5_$>UP~}s8wwR)QrwV=D;Z#&x1>naA>SZBxT{$#W zt2k+|=nM;&R4_xv|Gmlw0y{H`_xxq*OptnGLuJ6z;n6JzI#K?a;{iYW@@vDW(T42r zMFg-?gE2@|tGo1@sSAXv`%;Qq!UAZom;KT#ke9V*xFBc=G&eT7g%|WJ3PJ(VdE*T| zyGCp0;(L>2}rEMTLwXi;TXmsujyQ4JxNxf$%g#b{6-ja)SLGq+eA9 zniv}hg-Yj`L>@qLz{quif{`MX>GuXh!Vsc_Za=8O&k8tByEQ(Bk8`@p@$|{pMSThX z%WgmtCFuEsibQ_~ij;E*Fc@IVfgq5ir(J$qw-@)6QG3(C{i{}J?PhZWT9=WVgN7&< z3E`BmEi446D8G?gPV=iP(j&W!TrUA6(qvm1@|omIlX%#UkZ%rkA%hT_I|fk2EnYMI zWTO7m`~CC&klIji9B-Hil>yA0U{IY`FviH8NtGOr&MR>H!)x%^=nrR98o5P?MzJns zQ-OPpoQgtqj9MrUJ@>QWy@pZ0wV;u>R1sm9=akHxF60c&b$H(L0E(R+^s_6f z2^Tr4R4`eaF$-Yf9^+j<5?8TqkVVWl(x|Z0&$bUWDP48}xYq=h-$I5gt=g%yJGFE1*U)~vgk7QO zR3^I>6j6L6(gHqL8S*1)5xWv?iQbA*%Kn>i=lF)RqSR6Ss8(f{bhagR+e1KN5Ko~SQl~+(o?-L}ay61hs z=vlD{J->%Yg{5eZ(M$1>==M%LYgE^@?dDR-{(^VycyUYQ1T7u=IZDPNt}3b!?=SAD z(q8o(Uzgi7wC<}c$yN7Nrj$O%b9n9NdW!Z1vh`554xa5}NEcOA!Dyr#?A+g;CKR3y zREC|Q_}4VArlXa#Mirm%oTfazJkRfuhmhPLQ>Ln_=pK63lx(L*KP~+iBuS18la|KG zpYUOv7@C|7B6$=<66SS>Q&yORwJDh)(|(4=%F`w@p5?;Ol4O>vcoq|W!FRw%BgcUU ze?Z+%PgV&Mr9~@ZQ0up%6hG_kq1Kmhz|ejwmMCl|fE~>=O($7B|d<^<46Z zMoxiwaWTQqYE99{j00a^04`9YY#BE}E)2VuM(5{;C-|8Qn-xMGM>hBr$J|EL0v^jL zH0oI4w~B~HPJ*COk{=~So9RW1Mg1u?np0^>sfiqszbriXWm{xsy594yANox6HEPYb}{ZC&TDx8lszW}M z31OWL<6@&rO#@eQpdab%3_%Hy33xGB-fOhQF5Ow<`J*%pBO&f{((rcGl(;3V;MHxw zRT1GT2lWsVoW+KP2054g8iiSis-RuKVMD(Gq+IJVar2=H8Hddz9tC6s*sy#WP1;C6 z9C8Ji?LxxbNp${Eq$r2Re6!~#Q7G^E9aM(dWZI2LmjWH&S~K#mp!IVlxB_NIUVx3H z-gTLav!5M-R92;?B|E!FxxH5iki3T437>ahPpfs&7NAGYEAjP8!`X3U0j@IH8wg;x zqB^&Cw1~D^?)SM{U>!3tPaR(g& zZ-#QpUEER`Eb+O;hNBp2kZ$CJJc^A)i><+E0ZH!1&~J%9Ljbj|h#`FlAvPyk(Z!08 z0Qpzhm?Ow@3O^M0IXp^Y&e|*`amxlw?|gAz7ua$at>}mzLeXhFx&@1(QQ?;6)j&wN zrpD7Hwdpg7pv8T5KfCm5K|ogXJ>Ad7;vMvCuBFH(?gLsWXDa19Ebhbq?S-v%wY|b} zDP5~bD7UWpdIgq1vy-KM46P85?*lziPwS~8oaQfJ#ps^Z(|1Q&J=Jg1DqN8x(q9X| zK##J&(W4IZs6*Um`&N%yd5_SpW7Mt=sg1YmU}3919Q4H}5mAbQ35m`mDXEeqq;s7c z?g<2yQlddY&SP6=VbCtt{v4t0 z=+UD)S^~73=PXAN>HFz;N>B5&*QRUjJ1HgX@Uu=YHEQQmWwZ~F$AujMbq1xe*m()5 z;ZaMLw-q0Io{H8}cM!blN>N(#m4lA@vvuHLn?4QqEeC`f5JBx=Ya&&1MCu^WYF{az zjBouUO>=;P49V$fmmH`oMZFx^udP431{pTJzM{Bgc^kWJt{~KvZXy&)sq8X5j2ToH zbAxRU;&r@>p02eM>ibrr?hT`~*9#A~o=sI+-HX_cd4f>C&?VHNYkH>Ao{zm+2nbFN z7r2~~$f+Hnw7C6D0x%@5`f?K^TQ zBP)$)%2W>8u6R{it1z2%g&8Y))LA59#5yf2faM0fA7;PUi3;hy0JF zZ3O#wEwlL5myN!@&Gxg(7e?_LG=LuoHe0>asa@ZT@+V%QOCww3ZUkKjrs#)PM6WfL zwneY)TS32=mH6$&Z;}n7y~7mdte^Rpzku{H*}q3S5({^W77dnNA>W+{dQM|it;K?B zu2dHy6rXCNRSN6FXdh9e$LCy|&gBsO9iUGWG;ai@#i5s=% z*Qi_)Dan)nUfdG@EAUlW88!kh3n&$P$Dh(5AI6SEtw?xYl`mkln#Y7GfMZ`mTGE90 zZxAl2aIPE5D`g)dHasC-4d&>1b@SYCXYsKmXTDGpDQmBa&dYF?(nfE?aJHQaKICbW z#>9l9;J*4$Ka0~g5>Xj3f$*WUIKj=d<6z2JtP#bUGgW_(cWV(fGia>IVcj4Iv=F!) zO1rfH+iRYcX-7#^={(q0g}@y zoWz1@@xL3{h`m--_48LN3$Zr70=|guV*Rs5F6zr87A5BlFus51d!IZD080 zXGpHfF!qq;6@&?_!cyx1z=l2IZ)rTCcVPwO+Z)-yOHYt_@WHVU*A9@K~M71ncn zLyFes@%3(43Zy3j?9VrVoc-)C*PDH6k?toZxXR{B6du3C*Q*x<7$a6du{S9g9%%x| z#qcE>ZRp+&24oIjH#Sm{i%`4f%Za~4Yfr7qkTA?H8XhOR0PP3D*p%Uf>j`Le{9%Gx z=*rh(g<#ufWOuy5jB)FyAjA1dhVuiQPPtB&$ZqMf5;;ejQX=Qcm-5m@luqYd>;-gy z3V&@_|3I!mu(*XSMt+E6dF*zY?keFj?>uUG5Bn`TvKf$JQ)wW4Cv~1}2W2yvNPjk* zcA(B%I34D2adQnd^=Yc{gj!9ad9BlPjs(g!)I4*bQ73R{0CI`Hf+`>+RCA%TO?qFg zbp}}*ra~2nvuD1`E8i1j^DrD7<)f8EA4IT@)~`~*AU+!3`cazQ^%yN%dg}8VA-wg> zDcB-kLZdU1Kyx&{%yf=#?M$;fq9)*e4(KhYlXBQE(F}{;ucH=KoHR=zvVmBj2FH9)Bjr29-7k@!i@O`C^(LYgfyxA-ro`uzA;2HOT94^Kuj?RD z`5;K1x)eLceU3T$SdwhRwy4jEUn6%-7Z-}{7t+xW{Z+Uowp#Olk>+z_Mb2Sy%p$At zTM?uRu(P0iu-0_1421-#eJ7k=61jy1T6NME!c=CR|_&_ zrc5{$<>x&%yrT=?j=tW))-%UPw@mc)(s`~WAiFBTp0JvF&Vgi72b#W%E(<_1w*!X( z92k|;0D+JbB`X{_hF{^pA$5TLZ843G3uk7YHgW4YqTnDFWhXMp&cgYQ_#}k1bnQl` zcD(RUYIS$dK|A{LE|F9YCne?M@vR@H^~}4%Q3qOk)6=oet##F1ohjSqUh8>x?U%?y zGhZI9wZ)I4{Dxy2KWEiwoH-WpA0iHvYZDuuyOYjr}C6NRnzgRSRM zQB!oxcA`pbK{Y$CwFtG|hqGa@iUb>Bb_NVe&e!H+WpdgN>lt-3GiAHsb9y1*oIW$( zCFEl%^HL7ZA3wU8V<6IUUnXe*kT4_O)?Am;AWK`TUugKw$ zs7MG~U~`(U+wSXKPVzjs&o-LU$8bDC!n_l686%s^RwKe9J`q8xX)-Z`bR0@l(O!*S zrhtp#660H&;v>kx=gIpreYD$vE>6-sZr-`?i07S;4qG()+BeVy};(Ufws3|XMiqNw_&BG4myL7Mcmlr zx=Uo2JPZQUZ_ph~@^rp6l-=wj_qFj0U zIFQ=d;v+RGHg0`r&mu&d3mfYm!aD;g!V*HzsBZ`1ko`Dy z-Jx`TjuzO|GMAhkU~fQfvq4h7-7QoF*o`wl4`r^ZhL-!BN@p)%^bxyk(y(1lDf?GM z>~eanERXh7rgRiwU9^n**>j6P*XX7TYliq(Yjlo*eFunsHxd0`(E9U;egh&b5*uaq zOut5>!I3hRKAV)P^rgsuCc?L!wq^kqWiG3Y2f1;!^sTu-m#lm)cqxxH7fS1}jS>Rd zjMdm&(b}PJ2!aHrmCRU$2?aiT#MY0}(rT1h8%yP(IL~qV*(=L|XMUk7D(wyphfeY_lK(I;Y0-Hb zQ}k}2rGwDYo(b_bov|xX5J@Dx<}%+$%X~Z5rA3s^Pqn_pDHtRcT~e>YYJtTeMJ)nC zWj6NN9 zD{%?wAqv60TTH%?YKc)TI2TNwM?vo4Cvi8US#7uw3I^E_6o4L7fNCs^n-i^nQsuI( z1j0K}M76bZMDT?-l`aH6)ZQ(`nS>Ju=_%%^s${=W{)`TX<+lOA7Et~Pd=H?%#HTv1 zLV3f$IOecRk!(>?2kvEt#PoSRWiCaU8DPp4H1Y{nfFTaBa?pXF-Hbs7Q{p`R4MQKM zm5qU{JjBm_c?wvn83XaC#wE}>1E=0D8m956f&?0V@W&61Iph8Vs?xASh1E{*Vr)0*HpmTXh0QcG0_HTsLv%lgN5|L1Y7l#T&JXh|Rg>e0T ziXnv``P1iz*a)UE4>9ul%6ILSqio#8QzHilK~wMkZl zn=RlGi*G0L>}AGOK82j&(d>~aXs3}Yp(Q(?pred`UxkTwk|x?aw^>k5b{9dhg%}`= zh%=nQZlQ>&~)7y!jIpWu?!Dm#uEIpiE)b^be6~`k_f=n~QhQP$_&o&w4t^{u$MVD0VY}DHj-tWw z$G}uM(bb=tY)1zYIGj%#Ba^kTz3&YvK;&|wv$JuzRw?% zj`PQ*Z{zXA!>LYyXg*k)GqvH zIE0p1YBxd{MDwOhjT}do9gP#vn8^DG8o7-$0A3UUq&|ioRbkc0Z9rt`r7ye))*+~r z5&*4!X`+(YAYH&71RYwF&2jbRkZE#K;chDDfr4$Wg$=d6U~4upwGdL1C~uo zc|K%9BefGVfbJ;DT{!zzH#*dr>PDx!ag18-=7%m}cc_RsB-|T@Mayu6de1bJ030@u zaLjWV({~5hwokz#tN6R-*xlpBTIBKv*e5)?On*d6U`f?)3(sUDh_Pu|{7~8PI~<)Y z3_Xe6Pco~*k7KuD@5}H$?!tHB83sN0hTMlQTslMf_~UWpXDq(ur3!`abJ4 z1Ow)H?NOvvx24WQzHoLGDVt4f#hGk%8>2f)bR}(nVj}KK5ZA`8PDb^bQ7*Hd07I|n zEOn9UWDg)%1qHd6@KlQ+9?`jd@?U6MiC0) zsHL_04DfT#H>3Bv>8L78Tj;RAQS6$@TpywF3thNUG~atW@$SR@qNB#-#2EbOVy0I1 zYD=+{F}329a;{HW5xq``I+kh+9?Xf(dk|OAT_hqWaI2Q1y~n63RBDT~Z1irKulaDq zO`EmX>uL=_D$ua-4Q_%;RiX(2-h`{!eY^?XX7AeQ02lxCBS3L|$!+Vt--#o)(x1|f zMamD+lf4DWN;yR5xuUih>+?-UF2yT{aE9SR40{yqfv{e(#3c>mSL#9SE$uM-u^Ejs zRpN`^Xw~Tt&u`V==pEfGccOz+kdySojFL*1*l;5PRLfsmv?WeJPc0s)t#K)ReUb-dOjo|@lN_FZ zte+O0zCOC_4{mJ;TCCjf5agpF8}(u?c3m}s@I1o&gl>Jy61n9ReK&DHK zd&d~}<{9@+X1Nw1E}a(#f|c5*q;pezthlGxFy36scQT)9UudmhoCXGpryfDNVSEhj z1RyCa+!PAT^5S&=z<&w?T1r}ms|%brErQ-!4%=gLi0Xq*^HQ63HUajt>9kYnK!IFQ zXA_(7H?+4U-_yl6up%4A-@SNWiThM@1+-58<%N~O=&VQ{n2U0a@FIx`a(*RyW+Dnx z(=qLbN6T`;DY&s$)0U{XNGNmYS=u$~W~Vw^U7n{dci;*!1t+lBv3i%1`XcRHN!Nn! zfiEVh4^>gQ(#QbI$Jo}_xD482*5r{krc&b+s*-uI`gx@^Wg~PIM&Vw-$rkZW;YI=5 z4o|C`s$}DQ#z^a5Vm3Ok{`IR|W3qBF6L)7?EnUY%qq}fgfyIM*=u`%C;c!GAmW zZ#Vxv&VTpw-?#D0W`hn`9}eHu$P;)k*-oX%Q<#n@OX_$C!I|4hl~T&oBD?WaR<8M) z&dItnaVK(GIwtPRE*T=ds^@i zw?2;e=$y_PC9!0KDDG<&57bQ-FiM>wVOc!TaIhS&;q=yo;}$jYB=SJ?{b4?G83mD% z*Lg7_N|d^W_Wu+QHNyKA;eC$q-bNBUo_ZVqB!gt+RtUz@^$N2~SK_8pnpD_Ef~Z}L z97eJdC3t82rT(xZzPmqci$8^MJ%_2o?1(>x*Np9yCEkQ!jdFI1JXMJ~%z@Ch^s3F& z7Fz_XSP#hd`P>-UdQUZROdM3n4Yl#KFNawrHeAI6cZv*zWMaMzLWy4=fQIGAZyh(Fl-AWV|T4 zhlni}c^kjP0NEzUE%A@Ak>z+;B|dx^ggmjK1;2dXG#XISW`)g>+#rf7{5cET#K?!K zNN>%LaT23~Ov*N~;8mIly+U+*FCP3jT;1MdK2t_JS zQ#%B0553^_@F6$4)0EZ#Aw3NtlYNMLTc9)QTV=6VTUnXGn_t4`^QMmY2^6d_p!rL* zA4uT>ej)auJz&>_q!$1{ia{|4l+%;V+e4_gm{Q~^gr#d6BZu*fMt0%XuklBFSO#$v_YdLm{meRxLPZB zKu9Szu}ah}zKr1`R7k@fFFZIv9Pux(+$m2}gN67f2oFM`pRKtSn2C1~NMeonFzuDa zhEDt{iQC1k2YCD);zMzW(MsY@>0Tvqw=`Kv+#^PQfix2xb+HIBM6^MWZnY)`kf|@$ zuIg_x`)nl%qGH2s7#a(UlB-6G5GB*mpwkShX)(^~h#KSFG&YX%ZJeyRaJjK z^Dr?6LFD&C)OjwIhgt)I&doLFZ)H3Uq-}PD#!P+eCDf`HC~TeBa3?qk&4R5YtkBx= zA~MDz1aUE7&l_;?PK>~6K!%H!fOwArNaLVN%ObqLj&~>l<2ODZKo~OQ5F-^-G-i5h zzLaMoq^A{vgZT3NUfm(?o8SAmJ{-8DNc-bhE{_cWjgB1Ka=|7D$m@olIj$TN&ir|x zch*eUhLQP7J1(ab8y5Czp(sux%;{j1!kO|J^Lp<*n$X&Y#N@OK`RW?obB;ESJl)_6 zainES8bL^xYJ5N+zsVo0WOG)6LR*W}?OUnu$Dsyxwq$dfJxcg$%wDKBM^0=8|+H`v)|YOHqUW+~|Tx6E5wcW@b{buQZRhl_t zlkd_vLyw%;e5=+>T<|$ovF2AvcqGtaT@8hia|X=>@4&NTV&?GLO%-PGonWJxNv0>NfGW6)xx)<9^3h z2C28NbHngJ*qPLGCZ$nqWUf$3Nnccu#st`k9N-sm$GAp^l$IKBlnQj=w|mb&ph+IP(a&r7k~?2f0;J0O*ytkxA#W*O!UFA zcs)S#tSQHdxP|hW71nuB{i!in1qZf1*u_N{b|Zdcy~D_T5?$s>eY9Nmq9?^IjSbu^ z(CdkyJK~Md{)Eo7e{z5v{wL z=Gvf_+|VMwi{V;NHm%5n`uwPyK%qbr7T72pa}}ScL_A`_xPtx3L1e0AuT@iF^DF?Y z6$1bvoB~tHm24LWDj>XV^-(oFtu`sUZb8~uchlBXDpnub)0!gXQdB-gp`gaCX@oF6 zz3~YipuWDW-(;c@t3QhQIT~Dih$%;3uISK<c|G2c6~;kUBr4acE=%=u-eq9@By{1pOgRK8Xtc3ImDcHQ_0DB}RsH9>0fT z)UgG$>+kE6$Hh`92sB_C?nXf~t9vD%rChGhQu@A@hYbdK79jcwrLR{WM#n&2$3UWf zi1I=yBSAZ1t-W6}{Z#%SVkK2bQm|mFFdne%>4Ekc3_r8AHueGr61P1&&=_uh z&{?tJ5o(<8q|#DU+J)fSPwEZ!H3<(AAnOe>bP^jv2#fn-I68ffV@_-cASUW#FrDC& zg66|jh~hIeI(G~%v26vQ*JIa$zSa93>N;1+VkSOFbEdBLGZgt2LQ(nirtAh>B!K_~ zac>!B%8~f55FS*_3llN$6(>>5T}O&=MG*a+mj(&fsD({sHcYZh#J#hzmB1CUud}Ic zDiWRZJY!LsZN4Y5{!?gP;S!~8wjg(4;GpjUTSBF_(}5D!#I7kU0$OWLA?tL`1SG^+G+M4fa1?#Qr0c7k99y{X?+hBznRwYA|O3F zcii)RD6P)v^j;^Q)#f_bP-H==YNZoKzc?~Ad6vnl?k85I|7Xbzq7yN4GYZBjM?bSa z_9~wUIiWQ)5ys={LaFF9*jDW7==$P)MyKN1iV((}-HXXfhCg#1VndLIA|I2UU5z6o zC?jAG)=-AX=Nr*BObPAW>8F*6+%A(nhm2LY4DZAsMreRE`F&%3sDG9W)yhJp<~;GU z^w$8aE)P{|r8F~)_j=0K;7aaOWa~+#*=Z9af58i8$m6-mDLB`$b2=?NbDcY9@~3O( zEIf-_a09O-Qfu8c+Jd=mXdd_`BigIOt_>-r#I$R(nik}ZX>82Dh!Wyv0?nveFswY{ zFpZ6qFQ&AQ4L)o8n?0P*=Kh8+JW358OEbLEcrQ7lfg(XKLSu*1%GIV%g4T?jUw_W* zZY9g3Tx=0bF4($5xxEwTyq)Yl#I-4rNL$g~&DEC8UHxp!* zd~b6b6;2sNzYX|QDiRg(15bW>NX;NcWd#Y;G~$H+pEV123*^p#H;fJ#o!WyhpKzsMp`3JxD0S+XZ+V?q?hRh)K7XaglAltWsJV{?!EN_a5^Dw^j6*l~kL?z7Y=>&;X#Eg0 z0y-BzC7_ZOy-;MG?-+=#r)VX{hdLHuYw7j8F(wl$4~}g?71IM+k>`vwIjGKLVVde# z14jqgX9z+Qwo1k#xNVBL2(BX%)?&-)AQa<5s*=Qa{u4KyEDuvf>oOPMvNe$0He&%E z!)z42X0^2n7eHd8Rrm$uKz8;wUqTFbEHK)bF%Rs*yt~u7`T<%9pnZAUj@48pG^a;k zAHSd<(&$jKD8<-8(q-60L;=3VB;6{Bn_5GQXxOZ9bB{*H~VJcU4#>$rM zb|NFr*Nct$>gF7E^P2Vt4`WE@wm*0SrvBVmS%~-txXO>IN4)>UPX~(|087OcD755I(^15eCkT?x*%nm9>v4wNYz&wc=wNvp(0H8CxC%EVXfu?y8WQM- zR#t#YK;Qe@QJ7XX)qMN4`8M5rd%}F1WxhRRzIn~JI`eIw`L@=4D>vU(nQzNVX_%;z zN{RrwoP;GB4Q+FX%tX+IenHSMIew5`M8HX$W46*Ly#ak)iX*$D~>6odQk5Gl5@is6XY6LZcWrsG=bElUE?%mKD{=(fm|J3AxjnIbuUA`esf; ztTH47?nVTA+D5UIU7JDk7zb#4s#=XT%<{~}np1P9*;rl&`xpd@p}b8ir9-?>%VLzk zOEcaxI(8;!^}HlKKLMs=(R0!H^bBy6Gn#05Dg>qTX_>r&q;q)=cWW!mMTlEBD5rAB zqCsr^h2QSd2kVGb1eUzKygT%+YL70ips0`IA)(de+&Q>y(iv094c-j0rjoh%jG zZ*UAJn+P1!_9eg`1|5TYvPZGchW6uM48%>Wrf@d@wPV!`uv1WCL<_B5GOg9n`w>Al zZY>)d`xN6%+`M>X*VUS=CtQ8qRnQEIyJmRTM}C5tGjeqT;4@g0}4shsK#)pwkis#SOB&p^R{6L3&p zd$JLabwgpsq|u-gB77$u`o}R}=T;8Txy=IT902I#0H(50J~{)vb3wi&#(Ry)isg>c zl^zibYbMD6>5>z%=V(Q5V{wp$NrFHsG{Kzgw^$soDYK{zvGCvIWRE9f>Bs_y7OMH) zhF3bn_<{AxiJ8TTO(4@1Xh4-|r2Jcuz)_wGCEp6C$Ms4}pBDnIS4oUm3uR=hPH{_HSzp?rpdxfT4G6IJt$EmF3iDgzZ-^AM4A+(23FXdt!_R$L=$3nY2 zBGe09vPme@q=nH4k)|*yJ%HQp+>KMlBy*cVFa26uFct*kBkn>DeyZCzop4==Qw!i> z;W@C#lW0-c8_r)IV5>1IRaH>jYK0#ks1%5Jk8Y!Tx}Dr|X@&&*CC|ZiS1K*3O8GgX zCgwGSOtsvOz<43E-FqQkiW|!>(`FDn9Lq)h=jz+309aGKRvD}*srXoI$Of|DG|bZ~ zHrOc$&ms=!soL8P5F|N5`(RUw_Cd*5s;>5~mmBb)7P6y&<_af^lvGN~k2dlg>7Leg zms@R8R@#NSmE-G_mBoVDKK$lqqH&iAnusRZUq_=nZ>~KCE@@V==@)vM#w#nvmF(uV zq%y_D-({pK6~u5gWzcD01uUxMAwXFtPzIEiYG+{9rNv-q4tp;9bknGwGQ*98ueV8P zEOT&u$!M7ixlBDtvEd~QrcvfpdZgz;`XIwB^q7%$I>70obA&&d<_rCW5aZ;wGqpH7&=TOD z|9V+%-zdu}X?GPUD*?JLyUPERTMcc{HtJHwS^OUCTRiKwNYEBcw61SX;k81J1_ zjGRrAO`o7~+;q&8t4!MF1 z!=wy?lyN5a)lPw`+ zVd9jGlM6X6!1zq|Dqj#}wfm5j?d{Km$)*ocXY1I0evgupW09N;7on|fDD@Hx^X94= zh?+gaQ4pO^O{7Gu%Fggm79>+vI4L;Kd5LoBe==&F%3DIljqDAQbFi{*!^?nC>qr>2 z=CafQuw5pYeiwILfD<84VgtO74j8Xmmab5tfU&C|hyQ~uS!ckK^*bz8_wv<~h?!fe ziriAQaoKF+e=t;)(Fp4@HqUI&KQUDOH9CZ2lYT?hnf;l$ku;l(_wO)NJ$DFunPx0G z*g=t!@_c6C7MBcFtJs$a!BExD4OKbdqb6Ycyx9iU=K(X-SFJpgSS#hp(_t}p-)Q)x zBOo_>7Lk^b>Wu_>*cdnw{I-$mS+f#Lo`U@buG+EaqnuGhb=U}yxh+MQ3xko{#VMap z2r?mctse#foy_2+3@>g-aDTk^i}RJyp_INT3QgWZcs3C2t)q_&X|0OiawoZ{v|`hf zvGWkii(UlA313_jLA5IUuD}9z*8{MXd;|AtF@Z>#GhNWuWf*6uOJuR3_pD z9CRi|Kznu$@!#qD7z-MRpQiS;WN3X!L>>oH%jg@+?37n{w) zq|=*)p0i^mzy>A+t_ZIVBM7!lt3^<3sH4*1J8L!^^ujUL!o0%7b@007Ik$Oi5O{O3 zsivF_nNP1!4(Fp*V*K|(UtBqBNTZdr)S*OU6r1S zMyYAW`aEMjG^bakBM!cp)66E39~7}cLs4kI*zf=XFwlHJUIe5PB=xE&z^0kuKB)js zDK5kdM9u(|s7cCZL-7t=RS}-jt5)c#97#=HN5KQL9+1&Ira(%w3 zv>U^fZ7g(%du?;nY(0mIm!0qv=+3~%VEqQR`p+&-jnNi!TlH|?64iG~U3?M*F`6xf zbfVDkdYsZ2TQ)3&uLjRsrWPeuXfg6NPHo_9M4Hhw zuc#oUr6bYk>k|*Ol!qNv(#Ue${2n~hK~qBcYoEH2U25IgOgNOH!-myx%2rp~Co~Sx#OPd` zWlPdNFFQ3;@@rz#g6v5I?Bl@KG&(iWYvv$Oh(rQFCuPc$IOs(L3O7I~Hzx@SFbJXq zc2QRf$H#UABK@S|o{csh za1tBCo+U`RBCiE^;{0rdGpfrQ35{RNh3z(12;O%^D>( z{1z{>pz+dZpF0OQjz2<)zV33*;dOb@IW}^JK^{hs)NaqzW#C``zTtDD&A4wTk1Eh% z9o%X;(>(MCmjZT}AYG%S_n@ieQVxt^GNtF+?O9rSQ-#sEAT3p&> z594`5(~yQE8`I{-AH)k}HC*fKqLOfI8IH==X5S$09pbHfz7s;2AhD+5;@&@s2UL26 zbC)dkH{7%-0*e;g({V2e(cYxWG1Xkm5Nn~Yc`Oc=YMA2r~^m0TRP$kUUK8XM7oDy8BS z+2UYXqbmgWZx97LW-PU0M8og{KXJu;Y8T)vp$#_LcHCNbs|!XH>Ci5ghQPb;KP3vf z-iDr(NWR2C7JmY+l(SjV&>D3JxhZT(!N|w=AeK&nTl=v4A4kqhm6A-HRnb|3JDkb= z-VhNrP;Q?aZdN#zq>u;i|A|VLaw=Jzq>{-sFq_Skeh-Va8r4pek|0Wrx4|&o4^rHI(>xT=WgYsW5#Egg`oXO0vbgGG!k=K%69am5dmeV=ovMdfVu#N zK>`=ovW`wX{gR(E?4M61cuK~jb%K1&+Y?Z4E_;R-!I}6% zDuP_DXkND^;z6#;!G@H~b#EmTA~!@jw2*WZL*@VF>)15d`ge@4< z+(y)YRfjUxW-Fzuv9!Z0Lc9mv32JARuN-SHKl3N$BfI1(e6ta1^)@ALlY8Lxs?%w2 zrH31jKPrEF)3_P5b|61Su&#MGQb?&I@+<;L z!>6loVMAUmWSn58g6^wcAg^B}Iaxl$$bFdB)!LWJeTeNLp$TqA|HvJP{RhE~1oI*X zVvwTXs&bG6u@voKkGG&sjNFS!2wwIlvEdGcnuc2z!BK7z9NmxBG(Pq@ejAR74G-b= zWG>Diwv**=$)5M|D{j3Hkt-94Pa&!a|p7f0>smVW@8J6j1xnAAwj^Ds*Iknq?%1n7*btHPuNkBWz{U0 zQC&n&nD>msQ{6-Ka3LStXyhq`{o>w(es)n2_*|r=DMEBt1?Pm(4g{i{-dG+kb(`$4 zogf+{1MaKhT!xBt!ZhiFv23}ggt*<~j1^9E8my3~S zAfwkE%#TGHQ801{Cf&ya$ajX%bJLLOXGj`^@rUs`kSu2oBx#(ovG0>p>1vA1sZ2mO z^}V^D637l;Z0LgwjT7A=J5198ii8sq{KhyJp$5f|0)`t$O@Mfcc5f-fMFaJY+OH!K zI_=2u9TiDMWXa*@O2JXnu|3S|0qbWE-HJlV@<|#G!xBVMRr>Iz`Mr%C5T*xKq?yrl z91!0`)tNR>R41}~OdF`_W+#apxeXNcLCS#*)SHPxU7^ngm?IybilAi#MX-K$*Hnyu zJQva22&xnV0E;|6d@zEt^LQ9R?L#}s2x=1l?bV((bg9(fypMU9bncs;Z}VK9YwHeizGR5?_Bzd03=7g2V$1Qy_A1WD>18VKoo zAg*-n^}3QGDQH9~O5?xnwj!^7&2=@1=k`%YLH_rV`ds3c*C+O+d)xnx7 z)r)Q7mnN)PlhRD{P{3_GO)icoLi7xb10tjhbF41aN74PJ^;W3k3M54uYNmnJ(+Cpk z%vHRQccIXd;Hcw0tuCA{B=oU^7nt4oH?ki=j#Qe7BN*JQ>O+I0R%?C~QQGzn{6;yk z;DVf>Sj+q*b&*-sG?UOAD7=~K(MOuAoA&DNq8r(aZxsGF7$5-%tt1pnGLCKU)i|PI zjgAF_`_-Zdr*;W^a34q_B$x@aON&wS;AwbX~rH(J+Gzo4JoskBhgHynaaX> zu>4DXqQV`-82TtP1130)jRmcjflih3w)y29#|bcxleZ((g2&Xdl=8qDD+D_K@i zfNlR70G{S?RT^L6o9vBT41m)Aa4kymf;nfKI^t`Artc7(VKqijNlgUh32r;}x$G4_ zTjv$VNwAs1-(mc{g};%Aziz#EunUMEFGjB*JmUat0WKT+&;0ZX_!z{I3^ql$pHATP z2$!aGl45RR=>`vE@A9)*$W?`{7#sxAnV;p8-rP#!i*Am({IC0OPIu7;_G)D4-@xh+ z78Gn?JMiqUJN_uB^t=u1Aq(tR{a|bXg8%ylwvvtG9VDH|Z*EV?$hv=fdgDOJL9?>& z+Mc!{$=sgSP_gEQYEjQzmlxj&)6#J?4VAi_4a#&s8qw3RatE;E)<$gfc2z zeweCU*NmEd&J<;~0rh0%nkm5aHHg0)@l~XdwWWjfEOEcntEMO2?AD(;-)99p)a1}5 zEcR^}DR>r*M#;<$pBtjz?PQ>*MxN!r3I5B?C%ILr<=2AyoiKePuqIFryB_;}(`NaF;=+&p}J=m#XQ!D z-x|-mV#8B_52sYw&#KL2ISAH{UvcY3L}O=_^jdLH+*`Lh1N%SIYlX(kx~nBa+}lvp zf%veql{uE1w$h$<(|wGRNEd&Yg>vA>;uVb)9lqhmVmGzK@?h~k51W|jKsers{fM}a z@3+daW=hiw+ogiSRw;)spnH*;v4_Cp`w%oO!yWNw`op&P&k;6Fg6n9V+(tRLy?8u= zV2y&^R-uL?AxCm>Xh3kHsMhosg3T61#&1Rp7$Ab&xggCjR4KOx~29fuE#MdZW6JK)3OD3UBIXN2O-_`w&$R?9=} zXRT<+4e?(h+C+#u{_p+a{P;r%^Us=GDUZbWk>I^z7=#5YBXAV|J^{mT1y8-gOywrh z#ul{eMxJVIvmpD54W&E=8?EU)fSpz$4`8b`fd{bH8c6}uUKL+GLjP_`daR&PruC2g z5wo}|-bI@x>NYk_mt##A8(zjQ-!zfiKXUa)E-PB4Tkz+^<|FbEL|}zBO+U3tGO1eQ zHrkf2fM|0s5>5G*+X9=W&^T{bA42h_H8{z)@elAi;Fm&-96_X6NPfH-;eoUPpB3D5 z0I}iJmocbYKue~DZ@x)V+R|Rr%wB9bi;V;BF@_9sxNyGD3PXHoDEeditVl=5WFMx_ zibpP_wGIq^z-I-w!G_O@_i0B$J}W*%`)Nz|7`2Prv2L8v|lUurqc>YjwoIFo;4SMNj=cd7%+-#7HZ+wHGGGb z0I<13BVLJf<$jM9_84d4s9uPZn-Yr(V-YGJoY0~op^jSlIKb>5Xmb-7@eOs&15KlE---Dsa&};Gu%M1fp%#-_V`&Jyh`Gf`hkJ@K8ZG zpncT|+IS@)2JNe^InP7Ie3j4FV0Ok~uOga%f%4k8jwqj(EGsLmd2RndQJS$_G&Ko zRx!8tas2`-O`F@B^jN`{ek)q~f5mGBb>g3Ut)QVW_gdOmQ0aGgtsunwOI|DRu_bJ` zxYvrx@Ag_Ti!;7&d#y-La6RKj?zJM#-imD)Hf3F?d%$VMZoFX-c427$FFCCsEFcfg zJ7}R!I<25s(}_sZX~o-!8E{%r`Ui|Pci=VPw1V;^omLR^`A#c-h^>G*yx(+ML0CTD zX~l=X|3>L>TEQ9HcR8)#Q^aJ%-*j5xhtdp~@3);+@aAz5j;%vo|GLu(vtPu|*j}za z_FYaZc!%J$f`A85mif(2eV{ZGH{x3>3b1P*LARggaaGu#Axh)30@4Uh^f_~+4_~Bf z9r1gC%@QtMLUiZ8FVe+`jqkQvc$v7ScnJY+mCn6}^zXKEAEw;U`iSH%E(?BWwmTDAx``Lamdjo>}&Mp2i2#GX> zAc&7*zaM~D+z-(Ph#(gOJRh#lWe*L&T#jIzj%w*Z2{!w`*@pg;xjoK3e6#H^E>rN0IA|@;IsYqk?I}0Vm*kGn7uya?uZa8LMZFat7?y$t(3g&SE8TH3>XruH|3gWCU(Dj@CDAp(F#0cpNSh(5$Oh0ax zB52~K0qIaOLW@2;Kw=QQ)348A(E-pR1aaH90=uLCM?OzCmH6|(=jpJw8~mkCpYzQ` zxpgVI2;T|T_!j_3S-4kABg0?6RyrLUYWjkfzY@0Eq$=Mg%?YRY+3%oVN4BHAh$w;s zQ$Ms9t|S;Ry(#$M3=AX$Aev;ejk(tvqBP%k4RVAU$ z!JET=7DehLYMB5-{a7k}KLL{hyS6GgyljKrChBDyITQuC-+TCVFx}Li+r{l@pr0vO-?tYiI)s$pQATzj?cFGCs*;QHC9$k_Gr%6N5MpMT<3we9#Tq6d>u{OBS zWWt3+!Y=*eekC%fY02||Zn|Cc@8HG|eKt9xr;bR_1}zqRJz`9ccOLYQ;D+~lfQD@_ zN}WS_@Wlr57&C*yI6_>yTOEI4L^lPIVa&jl%e>)fQO9S0}4Ad&DDqxaEKe!fB` z%eZ!i9>C#YK+I{x_aCD?g%<_KC@P)<$0*du^Nvw!EwJzPgRxWu|CM8u_t4PuZu#MB z^PS(QTIt@X@-`{M3INDdm=4NRRB&3G_%W6}*qzU!lsc_f45*E`f-uOu#VKa^Gz^E#<ND{*6_ zoOOzky+{rhRB4-+DXU7H5Qbd!XQ}*6{|ztTn^%=SBnT~XMyza=f=GRHDbmdMdV0UR z6ztJ_r}5R7m;PJwJwopbOQXs62k3ovDOLg#{y}=5R{EpldlS8nE8UY~r6Z%DXO})l z@A&x2Dl`O6bymS4(y=Oa^D5W_po5F(W%`feAfz{B57fe=@N34c; z`7D#s)DOkjN2N3y?K$O7IhSdLY8{z(sHLlj%NWwDW(k#gae(=ep^g~L5@Im6O7?Gn z1}vFJUK0Q-Ts($PSTLCRI9RZsCMPI|4c-KHjY{l=S|i{P?mO5ERmetiC<>m>UY>X= zX{NUbYHgLpEde!M`v<<96(gl4c=&h1MFl=e>T^2O;b7NwvnR;(%^+XzA0~*8wv-`C zpJk*&dBfS1)|dj*1Xt5Iac`Tyj19jIXh08!8|ie^2Q`QaS5undb2Zw^PywoII3ZoZ zzgP9Ex^wwbYTdaE`R6Ff(S9xTrE!vpZi)?YG@~hPR=(tzl_95<>8BU!f8z-qNTAgd z4a9disex|8R(xVEIq)x=Q#X5=be39s5ouzM=O4s_3n?h&O^_Y<6k-;+7DhMF3H0I3 zI2PGq*YV0zmR*Yu9g)AFzF-8U#k`G9G~tF>8Pa^%ik3p}#1G(!Y+AY5$*iU{bkFRZ zfi*wbQ$33fu|Vu)MmmxfyUOALEGfvI-ku^5#wde3o{dQKWcgCy%nl}J*!n*a;et|X zAXqY%T#{h6-}oX75*!$x1MaKIRIzbv4!$6PkGW%o*g>BLQD;aPX)LXDQadwGw&PPG z+TvbPC9ABA)^@W@a5NHD4!KHE>ox1HC(X38#=2{@MC&IhQHKb9(JTF|9r|-H$c8E5 zC02HOUob!g9Kp8VETDWReKthppAdmc5*bbLMcR@DU9h`0m#*VDJpI7@U{Fm-v9)v+ zSxZ-u+!fSHo#;Ry5GZU5yqWO&D+2+j;hADXyEGGDr6+Yh^av8|lmOJ463_wc1{6sR zWc1X_u6U3jWAF{mlPi z?_1!is?xp}H$_Dc-V$$lR8$g83^foh2LT0=L{ZVykOTxmKsd)slY$*6@rdb6Gt+g- ztjVUPvGUSgQ1eoj+SSa|%4!o%Qki0r>-+!L-Wv{xX7$ed{l4Ef8=kY)Uf1V&*0a`L z*JpiDHk`Sr8@!zT^0^^P|DZTe4TAukjqxwW>^)8-ubgwCY)k=se*Syz@mwuHasbVtZ7qJt)?0)oRc?Dhq&KYVBRv^lfU3VRP-SI);E{31_Oi z12;4@OjaP-Q@R>=8?-DKOgkB3h?qpI(z>Z@_U#0!a4 zcZS827C%@>3DTH@L#O^PAz|#ie^GdIG{Fv7L}gK^JqVQ~5XIDGv_Lfb)X@UTI0o;D z(Nro^VL=2@eFH2igK?t;<`C_}MhkERQFqv{(c0Bh`0c|cg@1;PS2Llzil~SJt!uCl zC18V_P>NwI-GhSzZKtCCoIBJvApl!#5vGP=a3G??ii8^2yjLWg;q4yS#_Ii~(h}~~ zYFW)jtG$)(?_1qwqrbhS{^GBF5`k9nO>AjEf4R422Nq~b%C6RuVcR1Dkf1h^sEMk% zl2zE(HM$3+j0<2jd&m}8wDOq!s9L8`yRa~d$E@{7)9n`@3$fy zV_I3Hq9YdKUL5gy*NBU|e)^Kx1#_qFvA?0>YR}GU4aq^q*r_CP+uo*~(%|$wo*I802Zs$FUEjU-&r) zV{?o1VO_Oj525=P<^)dmM0hR&3#;S>lvMg*^sCEb4%2ls&T;62if-7Ed$^mUqiYXl zmf-VFB#IbG?X>SuXZS~GoshilvgvG$ME*g@e>;mqGsT?u-0)8CbfKTpstOL(HU^F4PKC~(YgpDSVj_%3Xo(MA#H*gp@@4zQm zv44!B(_iK&`Qw7`iceb>e^%7`jpAiLiIVUGHLFYonHAxoSz4)K^=xEy>0qPN->#IRiGyBG~<8XEs%6it0D`KXE@8d8vG? z7r?N9;rN18t;a|UEy&w$bgDhzW!~-3i>aE1)d!_RL0f$v`olP{t99U*9I31Gy1b_@ zAmW?_w+QaRcI!59*S}-`LU2sL%*59Xo#JJ@f)pQ5z;UznS643wolEfB3SK_Mq@(C+v!| zphPb!gSjX%?_x#qW>Tzw_?0RT{jyCxW34xZc31tq+t~Td9vKFn?2!B791gF`^~gXM zv~5O&C)6rHW8x0a>M!AF+15I^(%cTNtM)(?<5E26H&)3+j`FHp5vK0KJ01FtaT{K2 zfaRVYt{wGpxud*(q#HZR3$t;NosyQC`c5)7-11KE?pW!^>E?*@1+8$)iPuL^ zywZA{vmywZ8K6~Aoru(TrW^aydA>LMLZ)xWNTJ`IvmT5TiOy5F@xr_?rxq9Hpl7Au zj)R+Xz;g!5M4KeEfr>Ra;AWqS&*EUZVQVFQ5|s~Cu#I%t0xPv%=kTGxX{9=pF7~7} z+_9ss*x9LW$qRjF1#b$hP?YnMJR>-@p)`#^3V=QEoW=${Gi<#LA3tC1=r|$ffKuGs zbMbvF*I{#fCs%A;=w8jSRNcqo?@A1s;z|shqICjM&RxD2UB`kP5X*mBA{b>uCdU0j z`X2dRXet7|b>1LU5V)>xm67(5&f5bANqdV3d*Gl&gK?{j%kTNJiGhB+R_6BS@oDIy z)O@<4pZC=;=)=u4u%y6Jy^Ti(j4OyBcAy0+J<1bWHYhP4Nq#?CbF1 zwlA?WY4Xc8P{m!{#;_m}zp@*A%c8u?ZuOfsIdR6!IWuQru0tNIpD^LcS<i7js&O z!icFu-w366qo9M9T<@j*_-9N79lN-3!f_A}Z|4c99Wll(ddEKWbqqPEZNQJa_LD88 zBY@;|EglB~XTEH1-M<#|i*(@5{65pQ!LYlZdF+XIR9EB7BPO7CuCfIN7LCHeGYu3^ z*XlUp=jU>0bx}gN#i`gnM>S1n zvVB-ja8o4O5`0Y|`7JRejRKt$D#Mr6EDyo)%OxFLIO#b0436csGmc`m0}Dr=fy&q) zG2x_NLA-ZD#Il;(4`!fBRa>3oy)P_j>q480+etl~Ej+8+QlS9PS%_IyEZK1 zii1)rAmuiJ$qikPVA)-?V-CbAg9^UHKusTd?e)L~n?5}-2)5i)39ZvBSUvME78~X@K|BjT#bGzsFLMd5+*uxZq2Bg$y{*o$nbM?Wh^I^Kox|t&+x^3?rgmUo z^y7SZMKLxwakOBpWqh_6O-oEo_>4}DtMx!FEL+cLsC2zc|HK0k!`V&lki4X#gZ zl$)h=Bmz~xq`1Owy+6O~Xze)53R!EYeQ@Wh&SA)cWh(|M2{o>=y~vce()Sa^=smhG zuo#miOwm_qjpCiI`nQ3<)7f0Msc;0LPnI zs-6J*Y`E~)6T%#-I`r|OuMZt=v(Itn-1n{;gu($F`1qgu((6z`y9k6^>|0=oK-fjC zZVZM;_o;!Ml1JW5v^e-3@xg6qqp$NG*I7<(=5sI{(u1nz=# z_Shr#??>H-ev#>r%9(I#wMTsN3B;?y7c(>*VxI}0bH@HOHt1o*7=S$4^FVIg+HnGT zyM|NgKvI$(K$Z9hYBfk#Jg7$HrRaQI_B#VvgHGs=Fm>_d$>vBd@PcAmCU`CLxO&g};s-+PpqV zN#S#>4)3I->K0HYtTZXqCWEnovNNZuKtZx*!^an6&NJHeu%I(JvpoGIzu5_Op>Js) z;~-Z3EFRMJr9ii|qXIaBP;Z%%kuI60*M&sw3v|z&y8@dN@5z%JWJL*zl7b%YQqZG8 z3apfZPD%>=8>FBIr2ry;9$R(M@=+^f4f@xMhq;%1yVou*` zZ?dUcH5fgbV-we0xZE)h9{}jt*SawkEWC73rk~bYnf{umGCOHMqMV@eK>Lp72(4PZ zTD8xW8K{a;E(+4#RquneH5(4JRjnD&%1M`;^iI(OORBAa%va*Ed0 zDl=AFsmzI5u`(02CCZ$tnU10DC>K)wp3QmuxWL9r2h=9 z-zsY@tzRlD2MF57%8Gds(66kVeAixARw@zEUV>Gj?8mpKm4`pA>y@<=t$$J009swj z%H5Y*v9elebtr2ft=Y;NL~Dw&4x)9cvWCzar>w(h9iyyaw1z6{C|ZM*6>~bEUs0t8!U1F=BX$a)GXGx`6un4h_bO(~Ug>*eHPEJGSSn@@!oJeK9*cEKhj{ zLX#GT@B1X&(feK1LV4}>ux#)SEc^!AYIa%84fj|Ko}SF*D2%wVPpqRBjKxBIe&fJO zG}F7QLor*3B^K|Mp4FeZz6-8d<-5|ag{@?t-D{HLdqioEg)Hp{gf)+j@7CAw>#;?D zd}^RKx?aBLcCb(G80GRD>EXB*NcA6?>fz|u`lP*QrH17!Pe)fcwjY`5^!#vvM1~Tt1vg=fn>e{frxbU+zwB=KbGO*qy;?QhU;#o z|2oot6>}NYD@~NZzhsW-(C>vJeOIOHkk{^r3yXXsYAts>g5+16FGgAgJ0*(US1MCOv0=xp) z3~)uSIawBc_eq!X8*1@bR_bvzN!mGxs*5rmH(E)%! zKo|hM)|*ps{Shg4x9ij!E|h6^j({Cz*mC>Oy7Jq@>x?o8Y$$`aKY#yt9rAtfdE_F` zeFRQVgcWI-WpZ9GlVFy~BfteA7U(JA1TW_|ihHLO_nvc0nz$KZ z8p`S$Pv>b>3M<`0u5}9s3P7PzX5V-@PqSn#cT7j?>lOoPCjy}vfVqH7Kt5mzpcwEc z0C?R4yzT)r0A>KpPB1&c^oNNd&Kf_M7`&|Uh3N~^8>V;Tve9|;G}7A)*abMuw9T>^ z?*$IHm4$i-wQl7A+7L!}YgBe-MKjDRYp+~VHB^3(S=CT|TRtA&7q(Q;KOcmtJ?&%( z2B6c{qgk>oLErK!rIY_)HHI@bw^=rAKj!bWpAmLvrfoAySlvRfAqX=B^;1S02H|Z( z2!Dq0Ck#Kv;1eXf+D^pjo9W?+-k8b#_SUn0UT94#{33Q2oVs%c4xLVGnTl9A%8>P<6*UhsZG%h_Rg-II2D97%sv1dx4=!Im5wN_6<0)| zdHOJ#(@q>p^8@@EQC!cT>S=QEY}dQm90_d&k;4Xm%%u zB^3Ogd>lJRq5lz|?z{hm?0I!do%1JOdu!)UZR|eIpS&I2U6baPCA?QQVJ_Sq zV_cKc$`TIlnUKalC0z!&+Soh~=(-U6 zQ~3mMtOXS~lC)BsId>h#`^<>Lg|RR2#5^pR@$=dlv9rLE$ZZPpNg#}Mb;nh>p$M*H zlxvmYY9CT5Jrm1^y5!56fC$KP2`%Y*5HxT1{=3Q;OxMXM02K@HCYU z@6phup7B*+Y>V{C4wwOboBc6KfIA)hGBYWsYgeF7ZA6_?l?l@)oY;21*rOGxgw~p; z5pbt=7eeX`dvknbhx zePaE4rg~2_-#5&F4K0R$W}==V;%t}-xApvisxbWw2bM%9gtui_`&fjK!)bNZQoB2L zZ4JVJH%M(#?OL92baFN)s3vE7K-(x%ZgDoI7MmtlB=`$q71g2ZiAzL`X1@jr!M~4$ zBKT9VbX`xZ=mT+}4_2X1DNkIe03YRs*#i7Sh2{z6$x^PL9xX|&A1SlTo!p?wva^<3 zWOm*3tw+<@W z(Gu-I1g!^CG;{*}LtnR<=BrL+CS$v-KXwQDhfni!bTC$B+sptbWh6gLf1MpnLhPj!ZiPnE^nix{vGI;O{Kk{90fJlzUyVU8}_;yVnhl zYVO!o)2Fx$sT5N%=qWNGOlbOLCuWpI$6uIHl?G>IsZAj|Iwe)vaMOw5?TJgScAocK z4tEQr!vag>MvRsL^T@MmzF_-l};w5nVc$^+F*7=3r9AXb7Zd)H4RE9 zeYHnXP-ri4$hbNLZXV;YYY8oudGTT(1s-aO9XE&j@ajdoZMycwqlkhs=!shz7ri-M zd!O&xy~xv4Da#Vo?t+60+l6eXBiI>*H|!&={!Ghj4F$H2<3qYFXwO(hqS%6llqk~kXrRj<+s zvG|2{XggFCdN>9^=*}JDmcX7`GSjjOZB#?@$Nzw>7(J2p+2}AR?X>XP30^vKA6C?y zyZonXtC1K=2WQMM)Npy7jc(~(jEj8nqE*}r&e(FW5)q4ISXKnYVnm|LOAc%4`WE*H zpscB?-cm9bp(DPv`-LggEG3C}mz{$s3lAxlsL1%rmJUK9RNi-IU#wV^mD=#Ss+9CV zMNa8_w2`aYxVDhW&^C0tE}5S0xTxIql5Kgdd!9!>~hwdIYL( zu)J28s2$LBF&pVBXP&`tdL>|Ar!8Wy<<7^EFv6Bb!yTJXlMoUGt2Pe&(HnX>q(Y>+ zJ9et-fuLO4Ee!QWa%7tAQ=V`JjbnK^6Pk?UZsds(Tc1GH_au)-1ZcZc)Fxtw+!-8_ zBvCE_*6CLekmIcp%%!q+l~Y>0D$7bKJKi74gNYPm_CU8WP9e>QzppGz!bxqdXnGE!#pv_czLQuI{r@J-_2tSOEtUgtcGW;N#e`DM~Y z8!oe5s(R~1tk+vr&~3nu>aoCuF{#H@ZXsLburRaYW5A?%>U^BiixgSs8>jD7-w@%* zalWd;*at)RWVot=(7`(g%Rc&95iK3ovXJVrM)l0X>&)t*W^2R7+=kJf62s!KZfb!f zQ0uAU_W&!jey}>NY6rcaOCb`hnhLJ=;J(|NwQB4I!&nt6EYz z+b|oBu5fz2(b1J1MzAO9gK6=wUdhpw9_`WEunT{Y29VrZ)r9j1OBXGnA?0a$X3ZUC zsf3q)lqHSHlBSKMDGlxhO&vAQ`lR?xUf-CO4%+8f=rTBeC#=;+E~$pIg*Vl3zMZ7a zK;OBZh89q=ITSq$3*0b74S`%@%+$sZEf9k{JWt{b0EU5GwKC*@>t)M)wVe8FnsnKM-La;BS>O3NWGl$&}g zl@7}?rL@fCG_^>Xyr-h3s;@8#HuO|B=uLsXK3#9hKKQm$YAyeVwNzqQQ}(O1R5~A5 zirA_`ffco1HlwDJ>2`v*!GbDZ*mVtJ7pbZIH|8*!Q&agq+#56_R_$i6=G9a_1us)g z<-_%MYt^4%|0Ok*c?ffPHI)er0sSd4G!6ABR8u*e?@*pHnC22_8>BhIQqmKq^Kr@s zHK@=iR~lM%MU~4wQ9a}46;P7?nSc;gFXOO*si<-rzU!8fY3#7n zCRy(0;fQ7wRc=HNUn#1jHY~(26;&o7o~|eEKdPwmCv>hc4!x|R%6$l?bVZfJuSikl zFp{DdeN_o(S}Mbk9|t(`KmMYYN|QlXuBGx5@YCypYeKCnxvr`eh%gFC*KG-1 z1WNobR#tg0-2cbaR4%{AO-&_RdK7oPno8z$GPz06A(#MdfgWU!?+ET191hggIBqLqV3(E=>Qosi8FeO=x`KudYwCK}%)f8PdhHu#2^cmP$rI zt#{K>iG!isVcd+CN=4K~S}M0<(V`L8oJvQhQl-KcNjrA~0z6JD<~o~dskG=7HuNks zRHlKQhMrPtQh5b2ph=}1_%zeSZlbsH%{Yz^vAp}&y*6>rZkyN*=(EQrasjsiDgfWX zPu;iV9lRIoDhK=Sb?xdWYS5G2ThQ87IrAPIk@F7RIhggnR8&`~ncc~gxx#|Q0BoTuzW>z1#)bYKavELB~gHyOZ+bMG|$A{5~!Sjc__ZEvjzTBAKLpy~%#7+!;55d$& zgsz>gcl8lt!!G@9+Abs9ll9@WiLh25Qb&}^N2w!9xRX)8zyYf1Cl2*?eu@hm61A&A zYyHTP*E3+ZV8d}6?L#(?Q0#-d@1~uo?y5~_$YGM6sgAO_>gb178As+^(@tnx;g4R9!dUt8Ie`yCCW}COq#R7bQJAtw9uaBljPvu|6B$6S>h^f?E|2U4FE}B(a7Fq$ zQ*p(hN5i5cHs4e%nW>*tD4eVx#v+L(xfWbj;T+XYI))oJta9w=xY~&eV*IJ*+|e;9 z`%JZOQuYtkUP;+!v8|gEI4#S1vWDEJa12(Q2v!Hh8`wZe3D9=H4;X4s)CWhnMrS#?X@4`qIP1e`{b8+s|Kfve zXQO=~3U9f*ebrrm8bx$H!g9|KFG5vUqJlQ#HdJFh9GU@c_H_)$9eaOUi?Zd-eR%JB z(M6;J_lQwRNDG-grO+5JUWaDW;0RG)cqg8VJEIpUFM5S=H87= z>X)Q1KA3{DU5uN9xS%2+)3+0-_;?-|g_}jV!Qg0i8|^wKg2q{aS_;qF+T$;4fJE^p=Hqn4^`EY82c`RsVyqBzUB9BW%)!0@k32)Y%( z3FX%PVpjN|{#1MMqFBs8X+cQCx$G#829@88YkCyjOw-;SFC@gd+g9zwB0eskMEWv&dPXaQ!P@bRiCbDYFfk8~`ZP&Ej%FY1Qf>{W<|mFg3yc&X)n ziVhqs(Qn&zwO_GA(X^wm%WfO41@o1=Z9c83+ynROB2x7ym0$Vbkg6^T2XO5MZrm`+ zYc~ZaS=)=&om};HpGv}qO%>upx1bQgX4L@f%&?rUn2f3eO|FPgg!RnNiYl?$`+DP` zNrt7!0}$!YA1i-C_+#TwB7f%cC%?R`7|F*v4q_ekde;tUf3;hxz3|C^uSa>De=JS{ zd}gutaP0{FxbkaHyKh<7@;L8!=utS~WpA;vYhOJ?M+qF$V%Kh6^1rr121tgwZ>457nd?aKgM+_{k6bIixzd%YH+Gt-#T~?Y*_HcqG13xy?2Pgt2)nODP0Q! zaUiJEi#SmvG9oG$jlh{03zBb>jJvh}cpqD8KkacOpr10)?q^y&jDoJ6n>sDT>L2mb zVyku=bM13;S%`KuYz$XQVOQV!V$3(E@rcosug2gW&Wo9)iMt#bXGIm&f427rHM!YyFp4Y&Bhzb z@4OWzN!f!XL6A~43-9VH&C@AvAEiI3k5VV24FtDwvCneoYl4#MIjj*gaWEwYmqV%x z9RsvD<%Y%nZV>mYuxBKILAkM>>Z(Tp*XpZWZwK$iE)UNc)orkXzt3`CMR~OFXxKNa zv`tk9CL=axN}pHwL0tV^EpV&`L)p>xtGNT9tJ1jzj}KhCgMFx$sW!wMI5uIXOB+O3L}v(R;r<~d0NDA`(*5X2w&{UMbens^`r>( zo&y?QI}^2$$kgD;P4J*!AHy$MTa#o+gQfHfqiEPPd}h_OP9;-4dZHVKGt_q6pz3xwtuHS6!*(6Ww-=Vw zn>(L^eOhP9F({jctLvnF zCa)7^6_(!v%e{TyKpMP^G?H7Im-z?RbpO$^ayLq`$QKRMov*<5GJB*+P;%9IDoPLi zi8L4(C7>L;Xkp-hz5_%X4693E7stMxnW7l0(8#4TM4I1O>{YqFb&+?(_XXarojAt2 z8_fu$2)B(NQw%3+Bkp7FOIj4Yi|T&B#Y0uK3~~rK@H*N$kZz(d7bt{&tZo<7_Tp@z zGt9@)Mtcf2U1x{$ZHY=>{c6NdMGJ37wuQHXXq1LJFz5}^&AU`BCDC9cv-u~6XIw3s zfu!|)X|eZ}#nklO0bMdc&vA`5u|9ciDy-%%nz9zawXfrh^8z#^P-i}}It7I$O!U6* z+_R$KKtO0H0WsHd)G(>Mlip))tq)SX-d+`n>pYV!TbFu6Yt)Lbz)^9icEwM^hI!yb zm~gOdwJx7HG;me>;?GtTzu~d6ef5CGu6Go_;aRN} zr+ODvw{7q#?p<6;O-zoKN^j4con%HoQ6Zqe23a@syHWm~wXm7>P3p%p_z9nZ0BvVu zGaApO8i9=~eG}JF9L+0zyJ~faV6153s@fMYfEHDwAu#Gv-{Z=&kHBE)Q(Rx#h4-`a zO5bw0G`Z53H@Bkin3U~_+kI!X*;#)#?I5iH71O-eH$&O$@Adt$66FmVaIfzzC?&Uh zeVxogzt`8(xYsxMO)M+1oYUUe`8-CmHhF`_D>XxpZ{m4J{F@dJV zhi(H!JCj|zRj1NYT1k=)IX^9`{JNz*y}CvD18_jkFs}vRM)WN6rd#oIGkcaT0h8cV zlnke$6gcH&*zl8^h@VAs@v}T19`oT=ln1w>#c(Ss$}itqj5N!)^EckH0XyyDaIf*# z-sq2ZanG-)W%(li@*@9u$7$ROZ4bnt5jXj@bzN1~rF@Zhd69PY+{8bA zLY(8=jGI&D?0gCBkO)2){KjP04l}@2E4!!wm0F`DVjbVltZIWI(H?k5%^Le=U!^?+ z>&&x0kKm(>YhSWGGO@wThJDIUOjTTk?K<@ObPW?qy=rG|=Ja~;u0xMk4JlEt(Gm^k zUGK7UB3cVm%AKP(A?XWHw59>k^?YH&p`U=qOo!mK2|J3u*wob7hHe*H`p~!3R;Z(e6gqJ zmm~MUwiCA9BTqn&C+=W86uNKZ345y-!Btt{dF~@uN-Y3it;Ch5^O_rU23aO8_eYj{zv zl^b1_8h^wiK@3suLzEliCc=$Rq+v#jbYPZ_^l!m$f%3ai3mU z#XTklgknCR5bk{9Vb4L%rac#-`9vaSfyja%aZH7M9`y);FX>3X0I}$1#!D5sZZ0~$ z0$d`F0(>G~=$tEjm^N`R^VZE=yfYuBsON3wYv##t%!lcuB0UH4PcvdL46$u^p9*Xl zqR`DP8TqFng>*O9sR-r%o&cP4-Qpy{zwtZsHuDpZ6y^h+iz;otGd<$YbcieCa}UAD z1q((ND&a`OGsv2N$4bjmJR%`sNLtzuSnwpG_#*+)>GRST+>)*e{KmXR_4Y~g?0Ixf zO3$~Oj**V}jzS<7@5oVU#5;0TK}O~mWT`StEtsduFa4GRM{0o{CN)=Ck&i(70_ieM zfwY(oAXg-$E)_@vW`P)=ev61t%@s+hc1J-PJn)P!$WpecnT~=&!!0>IEjQhGnd;DO z33<87H_2g`sdmN{h$j$UAe=xL0e^7=YSk1-PYh~YsJKpCi+VN@e=5J6!tn*^>0*3N zVN$w%dTI{h!9Kyw9+{JqH%|q|kB6t1w@-_fzO7of@oU@8;@`eQ$4;HE>JrekTlXG4 zukK~--KTG0zy1S)t{E6SXz;Z|LWW)!I&Aoe>%+oFMvNLgW~?o8TvT+-_zAIb@i$CN zxN%bA>d1>hx^E0!uZ_Qbdo0q?^pwRAEw0OzV+x~F- zvgJi0Dz6}BNtQjaAa7neOMd}mZysc$08)|;%FekXpvz!{!Ep`z zvF%_RVg=;kmn{eJO8^FOz{RSlNmFha3gZPTY$hlvge?`njKQ{x?F`#M*2^qVJ0EYk zsxD`#w#+>(`ez}}EcoZ(_ckLOYgKDi>-6*)E)D+kls{`S^Ryy2wlP-tl1vR8nPjvxY*+N=X$XkKGj=LSToz%1R3Xx)t3X>-?;KuY=mL_Fv zs~Y$;Sn-LxWSh!%$SQ)+^3TItfw%^58AvY|@1&VH(S;H~ev+b#IhCt$q~z%BKIx-m zxyOuFII(3VUe~J9r5u^%eO-Nd=OQjCPDeO$Yd&bTB8Pm$<=2O)>Z#|z)TyN_)75fE}GI2Qcs78lgYQ{ zC`fC<@9WT~FzXjfJ5|*RogUV%=F+e#nWNmAxHOdCb>jN^^h`Xito#-uujX^SxD4I% z8}S?RV@+Zm{Vn+oug@0LR$Qh+&o z4NH)(9d(u*GT$hPW+^u0X4bEvBD_Ao=E^${rONWsTRzt3Jk>g|l}tyQ$W|&{rNA=a zqth|8i5w9dro?tYZ(G<-QD&NJ>)q37kRRfAaXJgYWwvspJX7&MRkdAu8*u9{rvF>y zrEyN|(~-wIcTM^m>LIz$R>6+;l>kd zg5PU?x!v&#aVwuIPnSJv_RY-{3+u5p%RL0WA?CyHa|X&KPw|GW2ETRrc&DAMIKNK( z(&?Px*F$gJ^*EHS23}AeI3}8V!6tlR`oiQI@TQ+_$V-S!n4Ht{hl#@yVpE+>bf7!T zj&z3^0P~Tba5XK=M3^`kDNg)o6Ww9v!|Vam3iE2ZpSOu#Fauy(VQ#9miQX_P&O!$S z%tv6db6EoOHkg?(>tN1>DPh`RCaAi>?<4C>hN5{o+(@_HDnyB3{8>?BDA|-?y=OHM zHjZE##xJcEl>%Q7{$UR__{Nmyt5E#@vZdBzGp$<{Hy7h~3_`PP8s`v$czWNhH&Skm z@tk{VBNfd-h|QXn1DWL$l>k=jm}}e`frPCHmL8{89~IPMz>)=E%1OyFb*<{+g$0_$#BfA(X#puxwQz3=`99(?F;4?nX0(G8D1{`V&~ zKKYNQp8n@E|JwBIbI)(yvUS@FFTV8hE3dw`y`pl*&RwtX-m`b#8*lD^>+J&v554p5 zd+&en;o*;te0=niW5-W?`q}3vzxeVit?KLQQ~&Hoi-|L^AiFHHUm%V9VB z4Qt%&yok(nU+ZRH=Vt$-oBdC2c3w(m#@*s(_d@>cb0R(A2f&1$F=v*Xm7A8gILV%B z&%*p5+@}?$7fiY(JAIx#E;l2uV1e>T*5gb}Ewo3@vu70=Ui)h_K^T zFJAApy3hNuFV7jMRMo%a{5yTwf9!{Tu09_)KGmL@V@)q8$SbgBdtYH19{erh&KSxZRxF zoCof5)XXt7M^o&zbNtO2Onv6l9BByYqN{x*aUevRminrKMZ*GOYRL z{O`3$ZwY|U5R_{nav6d$V#-6{&XFabm?ilTaJ|IzQbAe^7NnwlP%`8Y*fQW+l;Z%} z3NzDhNrhuhR&F}VK8NUBoW|nJEPHxke(Jn*Yifo)y}&wPh@-Gz$Sqm9L(+2>4KO1% zk%tCZVNM8`RgjmvAU)S^hHso#dclIMToe_sLGeJa1}}8v+0(6%0XMO`6w;$ElJ^vh zR5{->M$AS=Q{9r+(_Nfp&!iX>+EWWuuD>Qbw|b$tZ1Axe-ho|;F1?<)^ScqB)6!Lu zyZc)mg=EIGspAKSH43Y89ME@wHPyhLlHwk-xiTEkdjMF8C62{Rl(Cx>e>1o@F2P1Q zTr6h=^BpYQLTga^BD54)8P@a#`SzvPTt1&$AW}vnlFId$RFt?WuoOz`g7gJ>Sa#}T z)SN!56=S`zHsgl%G78mid`kL6iW&>F@FD(`r0Aq6-&g#7TlV1C6}3~Rj(AzTRrZ=PpPHV$4Z-GY6 zw!V2Jv3HJB72-X^G~e&-Zc`D=_on`T>~VSj8T~Kszhc1U{r@@e^8POlzP$gSA(!{h z4QcGZ-;Ms)huXwP06r%D2i^SX{{09Wje7s4{JCdhV}JMb880KTv47L}Une#8Kink$ z&eLr5c?Y`Ln}+*vdPBI+-Ru=j(pxgCaehtdjk=|=e^Ywiny32$IA=U4S3z#G8F#NXY2?q-`v1GxJ))y6*uN=#74J0mZ<>Fn_Z$1~Z6XIBeW3dbJe^_B>EuDHdS-L4 zON|hlv2VzH9)w%$x8_@8^S^tI{xf@xx_Y=T)!*fTu||~M=bDHwShDEpos`ZFabl`H zGg&OeoBId^JzafNA~uRBbdv4q<^Tr6AC;D)pa36M!&RL3PEO6TkIySe!iPL3-H1CM zA#>9U5IZU_w=gd!J<48?6N3-2UEoAWWMN^}{9Gf2sd)`qikm%<5{5#?_y)tFSa_eyZ&*t5nhwWm+bOU_D5 zkIGCf5PvpktPd9{L>kjhvZuwOm&%cWC*L_Di{bD@h{5ET8(Dg|0-=d$qko@nM4cj{ za`Fnzw;N)n+!!+v-{79iK0?4~ZwXD)X(k(WsEu1deLlt31|%|2{Hsl4kwEjLqfEiGorJZ$Sh-Y6a*gt8&m zF753VR~Vgsi(~%$^n%2K^g;^C=bmx7AR{#=>$awdN9Lv_r+_2l8Cm;~BegAVNG$x2hwiV?ba-Fs?Ip|O`|5A6u7@AuiuH!wwi z+s!vspaD!zmu+2+P%4Gwo|_E5t}xeY;?zuzW#iJ&V`fa&k;t?(FcG7tem=<%1tnl2 zk7?*B>WmZLGZoe!mc5v#%L0ZUj(oBtSsVf*kLu;YhqMFYChx@ z@&ha@yruvXCWsykbEDNP7Ln>f@?shWUV6O3WO0OeH0L2YHt>RJv7V!bw)ZhB@YKBe zS}mT?Yky*Tff}dh&O_S+`G7?HiK$G@ns=)~ccmNmj3x!_TdL?^T8PbPQ?rmyq2df| z;%=jrphL14>oqYiHEm+nEd|(s2CCmtGBqV#FXa1G+D4-XiFn%W9fb?~QI|@+E(p9}k!)~kv`Kblz^?XleY&ZT*Pc6ve zFeX_f={{+bGMF9aF-W74Fk2Ax?Dg7>IwnM*E-gme2Gaif{C~!Q3Me7xLsMU2Fc{!( zm~MtA>3@k`sw&vxA&%{Y9&3Si0-=R#=r1_S_n0Br%- zZ=mMgv6Dc}yK`=y^Y5ICr^!iV`f;tm^kce=OB1>)Rk{>&x^aI<2LqU2Zvfqg1Na_k zyhj=DXy{d(DTaHJVX_Tn`ZEE{8y!ED&H|WL02*Mmrvx1&g)8Y`_+kKYUSXJbz$7hB z0R2k<#0P5?YUjn@jQ900iQi)Y=Jy1E;kE%t)7t?0e+Zy|0GLAl5XhJR?BjpQN6*)K z$>%?d*Z)@PmtO4DF}U<%+y54Z|M`3_DFVh9=8_^{{m!J{d{(+~r?_+3? z=iagOj@}0A{(fAytbbfLS3G=zTi%3id9gA#B7EhBBO9!`_eH-eF6d4+!`yO(;UkUk zTM_=iqbDEjCcb!7dvw;N(_g+`#h8o_$mAn8AF+y*BiTo;yEy#2hmV~&FT~L0I%b^r zi$bW_A8aBTU;~T-gaL*DLI6PkD;>!s zQ~+K9YzAxuJOa2E!0>AUD*?p-J0J%z7cdo&2$%@40R{oAfL8cedKi=i;N2hK3lMKbJ%Da5BtvgU$L4WW^{yc4aZJqLFc<{IC!CI-j z75|xprh7BIx=Hk~?yb^SxG{02x6*hj)T^lLRZ(=pt9Wd&5WU>M3w95H5{*lk^k+Et zcuc1`D1y5z79IdEKudrH&`VOz{Q*|MFUk3^VZ(5~9Vdp9lEiJd-KKCeWqj@0wc;QD z_=niMd9#x74?g%neDTE>^>Uui>6T4sLpN<}NlE`h{vYJljP0Um`|0f&x8{i=6j8=@ zC}-SWodQX?wdk84QntcU^tUgd=j*48W&6IEHf`GWjETdZf|+t_{K836Zb^~L%LZ(p zH7!LH$qn1LOk;X4Li=D1-sQi~o!cao6#qep<-K}I|CYU^@G=0jgLTb=8HV8r7M)Mz zkxlUl4bf$ue*OB1;NW2FFAWi+M~@bfkvOj%7pHhPdGcfdRc_EQHdD-*Ge;~>8!zV1 zpD(hrv&Di13q(Ny&HQbfHc#SKTK zn0#D{Lcp}oq?q-U6!T6bx^?TsU;p}7ao>ISi3cBiP(1R;BjWML zA6MnOY11aLWy==Tmc8=IE8^Xqo5UU8O0lIziq~I%UF_SpPrUWkTjJ26L*l*n-V;ZT z91)*<@`*V8#bNR8cT#-%>8DCAs;a8QnbTj3&(BLyQ&S_(oja#wg>3a4g89uv%xOYs zeAi+ga1(?FmAzdJHylG8gyc$wS$mjh6*`*vXHke6!Nd@gxvb9 zknbI8h%eeHN@Y8_{ekJQN;fO@oVbi55f-G8<0X4Qn(8# zJdPB0A%#zoLQQ)qz8fmVnaNU|T`0x5byA#vR*Ihv$@=)+5q~h^k45|`h(8bU7a{&i z#J{h-6n`Ho#pcOU>{uwpfprr1ic3*_s3E>D;*$fN5x+a)_eT8wh(8GN$F!GX#!x91 zPL^WzLZr1$itW!zapX`#{Kic~ivGAeMn#Q_92Xg_oF)zo>KE9jPyY$^0V2o6$HhfQ z$48AF8yTH4IB39tet{Dv^i44WM90A!|8cNHN2df|!vGT|SPlR9gs7PKu}D59Dst?& z$do}0(63*g-iCi%f-N#WGAcR>@rl{BgMx#{7&tOWd_uhWjPD-MCFNQKU#4s`t(yeck0;j zhS4g4U`1tb_yhlF#*d7Lf2WQ;Z!mD1IFKkHe#+R$gd5}IW8zb~F@dfDUAkQ5=jYdB zB5|ZY6|y8Cmy~Xe0;G@)^pA>3h>MR;h)L+xC;flONfq-Nr+Aue|5LcMi$5+ z<(i{0I@W%03uwF`-fk4^xW$M;fH_8f1B$JmjP zk=J=yd_u;iB%~z7#U$uhq6yKTxTs;{qK0^Tw7${sAg|)0(Oen+Dd9u>Tea};Xdep< ziDE+hSO`*sf8_PULqc15`F4ndXVf^z@~~l1Q4RhnDdQq1MYL<_GXgn8r7-ol=!X1L zq9}KhBHDVkw9!9mEW|b5j1K;hKM*imoA&J{r9>r+jexAxd&A#+V*T5PCq#meacf;|18#>lj2$Q6%PI6*3J&;jSt=R_|TzVuAPSu-BNt$?#74i z@1nijEQZS0#ALZwER^qxb@HfqR(^r+cf)r^48aF6F#z%Lv0Xa|@kb!O4e{dfR0Pq%K}P>F=-s%AmE1@s#-WXM3e zTf21&=+=8+FaLJ!u10^jYoDNg{RZ?K(%#>4O)m(20EBJt-)l(lkYLfH&%mG| zJzEcHj{xo3w!OMX?|wl;+O!V3+HkO1g9Z-q_4NxvoNGF?YuhcL%fKORe0^KD^6~Mz z#$xH_-J;vTo^5DX|5(=iFn8$Rzkgqtkd{q_BcAMjH6 zzwyQ!5_6;y_{kSuctPQfIVAbzmtV?*2MW!onx>ua1d|S$#K#2SEKNX}OA|~t)BG*?@7%d_HOjFMWTJ$$?AWnG z(LnjYe3N7uV4g|I3vpzfKpj@*yYId$39K6|51OnWtUHYJ=9_OS8d!#?|B~f^xq43F z)<1av3GQ|DM;+#-i7TzYUC*99EAbgp@*fr!)}L}rU>RWEOuqc`%MxWS(Pvh5m}S5+ z!MvIR;=Xt9Udg(0`0!z6Ck<=^C~vGMEFjDDAnvrY z{ErC6l()@bq`(%@(82wM_VsVApRzpWnr4XrJk@JP+pRcNjU+Bs3nioj<)G*>>7YqoQjW;~=I9{b z$#a$w<%aUlb{Atdh0rA6f5XQ*4dZY~ZVYf82^uh;Eb~DZ@y~i!%D`9jYH_9b!tg%tmBk3%026bX|i7MNy60yH-d(E$p3ion>38Z zVZ!jYbQ(fX7cfsQgSM;SY)7x;=}P?37O%q`|8SJU8rCzmEzQwEd3P@pQ?6)||Mcf~ zfpOW+xIfcRqK=Y=Po#_k4Kbi$)4$zAT+;q6eD1#lFD%EY9_ zosOS=`bi#o@ge#6?eX&dg=6Jk@@xvRo4%BC+UHVEJ|SfSY52&f&ybl>W_@Oxg!;@j zsXyug>+@j96YKN^tg|&kgTf!>y&7{DebBC#kQTOwG))?4Qtm0&P3bV@i?U8xI=+9i zd}8q^xxq17{;hC~qJad=slw$A1`UbFrJM+yVnIWFeI^Y?eZH1$657;$Xp?$_hF&k| zZ7Y&l(S!ztf1f^m>f3*OnWuhBScxR@}KT3GEb~x0}Ns z?Y)wJ)U`G253$afbeOcT4EQ~8FB6j%n#7;&eP)})`W%V6z&0ri zZ4$rFW}7r%JFaNa@o(BLbtV4j->)7%e0U%9QA$V$+eMm`8PdT%4^7fSH-2l)ei{Av zy=9+)&r8MOa_jPN`7CJoCurCR8eX|CPo6mq;kkmR3Un?&nS}BC3>wTn#(>xK$W8gr z_QI6^kt0X;XIYrQ`bxZs8*w*jVcXC4p5q#}oBUSs+s5a$JHq6Ppkd4Mk#f`R5%Ou! z(6m1P8Ew+K1(9;~t>fg%tSIT6A0>;@qNU4mlRWm}K}j0i`xvS|qfO$|9R6tUmHY#r zHN>5G(Iig9oArTwHp_%U|yZ{j^X#>ji~$I5$hZSwA% zNa+F%cY=mHK*KW7z^7>+<7U(iJQuY;#2>Pt`6 z*(OE0^)a4Dy~lG=`%nB$`HzT*=uaGoCw7I@)4+0Zr{i+8{QPsB{Iv3Z`TFW8x!oBi zUpDG9+a$9-KZZ7mG(2F?@JGnenp-1fS(Z)%5mkK*^tUGh9zuI{LCQCq$Ua}Yvdr=Q zU59-P@wvIVZxC13N7jMm%a|EzrDu|*Ai4AceoF<773Cf&azf$0C@_zQD?WmpPbLHU8Kufw>1 zIQGFjjXEshC!woXqE1M@-*CeXs^5eCFsl6|?!=X4L>f$>8~IJy<2Z+XJC+6O1M9S^ z&nO3epUwKrHp#s{@89+?`+*ObyuO?n9v*%V_VlQE5aw;vWr;nCykJsdPD@^M%{3Bz zYlRE(V1L6MNP`I`9WuBme1H-j?IzK=-<@g@G0dD6+T0ZrBi))CeRvrK4G2H7_;zdam#bNmc> z`Bn3utXq_S$kKZ37kiKO6f5HL_SMMG+8s+>4+qLMAF$t(QHYx1155O3B4wm)>|7=iM` zzV>$11J(i738u?77`R_RIwb)C0XCHTqnLNnfHc>9xUO?0kLo{|GRXdq$yefY{P=N& z56V`eZ^2!~sy?8+CFD)X0KZY>Gs6@3P8!&blBaC{pL^~(`OGuVsBhrE{`D^vk8=dz zlZLi!4!)7M1NR+py9-Ej-Q!BvZ@Lm+_J7#^qdua6XIv=0iKvWf`$N_&o=`j{|SEn_MTn(nsNM$|+5E z872)T5I53A8Dd?y>#n;b+APWMwEIKcOkfze`Ai*)E#2m^9ENzu7k7+pWe4lqr5|-T6yg`A+;pGNs$`X0b zI)pakUf}UtaIeSTUH;idxR*zBWkR|*$3A=ZY>9ojO1@2=yPFJ0S)#1do!kj)(e5cGXJ$?(&WpCl1`{qy!#^zXk>-gT@Se%1UB>X#b-;`?1fTF8HzCLJ_QI%txoY+qOx2rL`Au^iZT zvYxWc*cNdufoo8tg?vXIzongNz__tZ;cv=6`U?HYC&J~*g#CN=e@GYCc+)0O$e|OnvD(B|AS#RA<$~xZ}hGjvSC!a|p zWgT*K0eu7wWyS9*_gMUzZxiwRrKbY|a1X+N5|{_~K5(DL?|x)4J}%oAFRl|U<%O|} z7oWiSoEqJPO}+omnO;VE9)^k2FUSwi?=;Qy%=F#xE@tw0uQ1FLzsD>x@RYjgVVGWq z+0rmAhS|$7#~NmlVM^Wfpviq&R)7ug8~15(e-Hb&1j_Rz`-&*(6#&eF%d-IYhwofb zX*wT>A^7IUr>Cb+Mt?sVbN-QV4*{^x-5F3Xr%d~kS}7M{tta*aeT|KC z!CX_g4r@EJF*p3dcM7G;;Xqn@;FhB6F}7QXI$g{541LZY(B4+zTW|{P(h>B}AH_Ub zHu}KP2tO3i2mOuH^RdRkbu!L{+Ax31HE*sLzxTbA2QVv#^GJNYLHJ8OJ<*15K%TX1 zKiNidyhI!b<{F04=f8k<^?S6r@1os&i3xMflSb=ft@_^!^zs4}$h9SnKV@ zb{g{vshE43P8`^G;@FelN4D$y7O|~nUzYt8`q9p37S^h`=E=1-uJLgH0@tXxzQc8Y zuCejC6!CEH#W4WJpt%??Wb^yW?;6Ls%$NOW^2DHD^_}z-^`RY;%pf zZ?kqTV!6wM%Aeyw_7Mogfxz~iK%VgX_3tl^$S0iB)w%@d!};9uZ>)EH{eRlK_V6l- zWPc)AjR=AlRJfuiL_k;(y64?9~9t=m{;Ma1^!z=3$8$38M(lvl+Og_OV83ppClctNdx4u*JbiZ>-T+~z*-u} z<7GHq82uBTl16!jUNz}J-;i@0QGmArBLQ9roNE1ZgRhDi9y=e6791kXlW4$t9_R!x zTa@7b;aAXml=F&%qKpuf}0bc>u z=wn>f{g2M*jIMm02;|WvK2W(h{_xERhe)I6E_=ZiAl`?6j{62J-~o<%mS+37A@C|- zx4;a6J(pGEh0qD$Bfttv2%`#kfX-^#XkfQgF3LZ2i=OSxBl|xPx(K_2xB#&ocmmr4 zew;nJKe}^fijNZ@KMi>VhL7BIpcBBEfb{__*doQtuOnSDX_Y6L<8{B%gPVzANrp%WlGw@g$sKD8-hO$ zI>2+p)rhH)Hw7Kw1?&-iLjit^bpU}*TuB~rUbU=U=@5pGP5FvE%D3c#4^yX3_3a+) zF6KYjf5-y(0a--fpalgwaq=&FqbL6I3F*XT@<=)Xc|^HV$ASDK9!H)7IbHA=@fGQ! zA8$c7K~pe3HOB^H@!s^5=;)lPCM}9cY4GgdTtn@Brfj-kdr5r|5@^2SqnN)!ttV5Xj?_5uKxJ zW(|&hb%dOgf6Ce=Y>-l_lc^;0Nfxyr4}wZx6{<&AIlH{_%luv4=?S{WuVFJ#ZOdOXO!oY2CMf-$DEZI#9t6 z&~f?LfIiGyupNj?sd;dLMv>nI* z`hr~ubd~0b3xvxIAXzRX9|?PnVa?OkVyZBBMZBLzFJ0OOj0ZV-df-2bu>ihC^RnL$ z`~mPC{iDJsgO3&*X|6g?{QM2IRYrKl3F;f6z}1Q`f6zg+1>X+*MlKgJh+H~w4d@5x z402Z(1K0&z2U@@j*lpNM(D~L|Z%w6+Z@yaR^t-SBgx{vob9BAXH`>HFg9h3sAWHiR zM7wwI?$ZVuP;m})0Ovt&;3vUeU|k~R!WUD!h!uWH@$E0{53Qpgi1rRqP9AeUY!0vm z+OxpNn4uS-4+VS(a=h@DfvLc6r+b)Bo&MCmL7(4$AkW|{D(FB(f0&PGj|AT~V67_d z9WsaU0{Y^Oz9AcRlGcUHShj50 zC3c4}fK${){)!bV{O{?U*riLCcBOpw=9Mc~`r{eQVHjt!>7Uf>40sx?e@345J8Gkn z5V0}jbrr=RJ;<-ax<-#;t9cX$QrQr+fpa0#@Zkb~CeSI^vd1ZILd=95!X9#K zG+Nh5CGd|!zz@(DbPaY174nK}QPL@PB#Jg_maoXfBBz5q0%A7s595S62!0UC>k~Tp z{ubg7#2$!!;OipZsF*(~iZ&33ClMVOKiYf7$GKs{z=z6r7f08ZxPCkd-yMEC;s(S{ zqcgksee^gKjV`CSmY(yD78e)$YeaynVJsmp0ssAz>Cf)BSNnedXo`KR3vPBD_($`C zZ?}NSVf_HE4P@?>F*16r@?)Q$h@r-3`~9B{yqf2 zv0eQ2+zW>PD!Oyii|Bq`a6LV{;`?f_UyvKvZTMUm57^V1wBUct<-xT$;{0Iz!Mnik zIz;m%`p0~PI00?LF4Np!T=RO^Y0!;!zzh1_*C))`$S2`i#Mzj;35&VpTC_9fhKly} zsfKD**AN|ltOn=ceAIe4H--|K@$vLNUNV;0aV;i9I}-b!u;1Es^c%j5^LJaTMZZ;j z!d`2!w4)I|#rr$0{i6Cz`b6hkUwtOMg_&&d4IwA3urM>XU(Sg5;kh|^g>J&of;_u0 zJu5Ret?<6w?DT^C!u}nckn56Q6^>ZbDjN*Sul*gE9*e;)iCpPfw?pjJOH?({c(k6QtAjV%wKq ze6jr+XZ)adr|l)QI&ClBG+pkr4frWj+NZQnOzhgdOKNKMKi5A0|M3If$ET!cwOM=i zC@W$wv3J=Kc8-O4E8d>RDOt)0<$a}&+C*)o_D~;J^VJvBP3kuFka}FbP77;>_G@jh zHdK2~tI&36f7QO$YUyFUmEKu@SkKdo^fCHmeXhPxU#)M}-_dV3erY^nykmT5oHFW~ z%$#ICXKpr6nctdGv!T`2>S&F$7Fw&UGgb?cBZ|cgu~fV(j*6S@`SvDzpZ$fM5ozG8 za$a?|Iqlpe_c1riog@`6%^Tni^VWHry-&R_yt5wN5NS0QV1`(Ib~|gq6y~vXHk3WZ z=CCDfJNu5+<_);X`}0o9K7Fk5jq$w^Hd~mlm^;k&Vx4%%zSHUKbaQvQd)&kBDfb4M zCV@oYA)Po@!d_r&*jwyQmV{So>vwrE0nd$W@V?cOF5(*QI096mFv~I#O?jsP5LkOu6l*O zOaGgGL060pMvgJsm~2cp78`4g*Niyxzs>VztaXcZztzi1x3aBe)>i9t>syP9?qZ1; zWsf7SZLn{S=#lo3Wa8QuXSCa24wcwr3jk3O9ai$wimg4Vt<-jD6nS;ugnxP)l4&U z%>wfYbF}%S`CGHpoIw(~%zVS#YVI_5nfuHG<`MHt^EAn4tX11;V5yd{9M=EHd~Hq= ze-Ph_#`gD-hvXyjG18+c;+1PAKa-*Al%>G2p9b%ri-fnDLb~pPmJKuiU-es4&+uW$zLUxuZa)2zA zFU#JbVG(V$Lx(Ju%Zk|o_6pm;TJ!0A0l!sgt5{@N=PT=#eab(S4(b%u(K={JTB??= z&C+WbcbNmskhRQCwu^r!V1`XW8XsBP3Y<`^#$CpR1048x3&-t{ntnZGehNY7524XnGY zW|l@e)y;a)O11h~Syq8H+!||5v1VKIta6$QHd<$`n?*}eVXw6}+Vvv0Mw&)aBZDK+ zNFTB~P2F3hEoaKmmQW~>?mdS6nZ3jh@V|3ac~Ci}G*!E*?~t_D)jHBlb%VY_->#q3 zA0*2#%~&qVY~~a?Wn>wb!Y1wxg|OJI9&zq=eg_ZpyZJr*US3B0dXFFGVWkU6(A}z` zc2RTG7ik{cqyAm(q~($wT0-{o0=2K}9ra|rlxDm?=~2Cop&9*+Jfp%`WWHdoxAt27 z#3ZsAABd^;EPJuN!hX}fV8=ynkK7&kFw)$yooweBr_`P4)|0oYME&7TKkwu=sU{NH7 zi&3IPj1v<@shB376?14_S|rNFa#0~xi&w>K;tjEdyoK##Z+44HafEF0adBFlCF^rR zgzQ*5&aPwEw;S4x$ezX9&Fq$TYn#~`X|iLtvlHzkJDDtZPdnA_ZTGb^>?}LS9&8uU z%s0v|q1kkzeboMzMypYzWh9wous2!rj7V0bC{pPjagVyk-H?oxak7rAFB{56vWbkB z&7>tA*-j?PB$-Usp{Gohy=9ink%MKC94<%65;;yzg!El2*En#E1J^ikjRV&>@E_yA F{{j_Hb~FG0 literal 0 HcmV?d00001 diff --git a/venv/Lib/site-packages/pip/_vendor/distlib/t64.exe b/venv/Lib/site-packages/pip/_vendor/distlib/t64.exe new file mode 100644 index 0000000000000000000000000000000000000000..325b8057c08cf7113d4fd889991fa5638d443793 GIT binary patch literal 105984 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

    ^h^N4aZyJe%k(7BL*-gn=9``8`j0CuR45%cHI z_uuQ8!-|TEvJ}r=zF@%uKc8U@W1eNxUymJ(e45Tb6KDNieQcKe?L-gR8zZj^wFmi= z{5sAxrfP3BOZz~T$3h=Gi%jFg1%D>!6t*l^`zH2G#1PiYtvOBSI#q&y?8qN57P^LA zq9U)rQU+*y!XEgsGMCJM7yWOS+9lW~^axz>9gyv{Pu^qsBg%ZkfzkaN`$zV#>=oFn zwANnf4&g*eu~pAMC~1dl8FZ-^aeQgZ7=osPU=58@oke z55pen;eU@Z`iL!`$;1-VA&$VF4gN7ttU>relx5d-_x=|95B47HeeiYJZ$$38(ddJH zcrW3>{OR2@KF^H}gAbdZDX=AzyZHSizB_(9`v&$-69)D4WBjSaY@YVD`kl8;nl#Cu z5h1U}Tp}-l|Nde9w|3Pc@Aps8-X~fh_EGq!b-~*$a&nv>05-_n;)z{t+vW|PpX{Oj zKE#i|Gsq9Jhpor%Fqiu6y5}jjnz?*$b)h|UO;3NGd-k|9?ZqeVXL!9~vaIO0E8bVb zejzv5ZG0}~1A7{a3!hob11v4ihxvzh!S5>3I?4E~N9+^m8@sHve^M+wb{f3t2VUsD z*C*C&;z_`=&t~mbE@mHC`k7cGl3rKU9U84p?fzGxTg1q z)-Ai@eQSs49?#VDZ(BQ5_sXt#*VAn)X1Lk5l>kvHP6SDZX>#ITM7@`jxR;sQ>OG+Pe$CuXbGOdj zGq+|zTtQMnhk{-O{R=KF7*}vZ!OVhr1xpLo6l^NkTCk^}W?@_*Z|>hH7&o`>+{q8j zm_Kv=-1+n7FPgt}{>u4l=C7T3KtbFEnHc+rVzeuEi5hE<2hHiD6S}>D5l co{tw5U0O7=?|={2,3}|[~!]=)\s*') +MARKER_OP = re.compile(r'^((<=?)|(>=?)|={2,3}|[~!]=|in|not\s+in)\s*') +OR = re.compile(r'^or\b\s*') +AND = re.compile(r'^and\b\s*') +NON_SPACE = re.compile(r'(\S+)\s*') +STRING_CHUNK = re.compile(r'([\s\w\.{}()*+#:;,/?!~`@$%^&=|<>\[\]-]+)') + + +def parse_marker(marker_string): + """ + Parse a marker string and return a dictionary containing a marker expression. + + The dictionary will contain keys "op", "lhs" and "rhs" for non-terminals in + the expression grammar, or strings. A string contained in quotes is to be + interpreted as a literal string, and a string not contained in quotes is a + variable (such as os_name). + """ + def marker_var(remaining): + # either identifier, or literal string + m = IDENTIFIER.match(remaining) + if m: + result = m.groups()[0] + remaining = remaining[m.end():] + elif not remaining: + raise SyntaxError('unexpected end of input') + else: + q = remaining[0] + if q not in '\'"': + raise SyntaxError('invalid expression: %s' % remaining) + oq = '\'"'.replace(q, '') + remaining = remaining[1:] + parts = [q] + while remaining: + # either a string chunk, or oq, or q to terminate + if remaining[0] == q: + break + elif remaining[0] == oq: + parts.append(oq) + remaining = remaining[1:] + else: + m = STRING_CHUNK.match(remaining) + if not m: + raise SyntaxError('error in string literal: %s' % remaining) + parts.append(m.groups()[0]) + remaining = remaining[m.end():] + else: + s = ''.join(parts) + raise SyntaxError('unterminated string: %s' % s) + parts.append(q) + result = ''.join(parts) + remaining = remaining[1:].lstrip() # skip past closing quote + return result, remaining + + def marker_expr(remaining): + if remaining and remaining[0] == '(': + result, remaining = marker(remaining[1:].lstrip()) + if remaining[0] != ')': + raise SyntaxError('unterminated parenthesis: %s' % remaining) + remaining = remaining[1:].lstrip() + else: + lhs, remaining = marker_var(remaining) + while remaining: + m = MARKER_OP.match(remaining) + if not m: + break + op = m.groups()[0] + remaining = remaining[m.end():] + rhs, remaining = marker_var(remaining) + lhs = {'op': op, 'lhs': lhs, 'rhs': rhs} + result = lhs + return result, remaining + + def marker_and(remaining): + lhs, remaining = marker_expr(remaining) + while remaining: + m = AND.match(remaining) + if not m: + break + remaining = remaining[m.end():] + rhs, remaining = marker_expr(remaining) + lhs = {'op': 'and', 'lhs': lhs, 'rhs': rhs} + return lhs, remaining + + def marker(remaining): + lhs, remaining = marker_and(remaining) + while remaining: + m = OR.match(remaining) + if not m: + break + remaining = remaining[m.end():] + rhs, remaining = marker_and(remaining) + lhs = {'op': 'or', 'lhs': lhs, 'rhs': rhs} + return lhs, remaining + + return marker(marker_string) + + +def parse_requirement(req): + """ + Parse a requirement passed in as a string. Return a Container + whose attributes contain the various parts of the requirement. + """ + remaining = req.strip() + if not remaining or remaining.startswith('#'): + return None + m = IDENTIFIER.match(remaining) + if not m: + raise SyntaxError('name expected: %s' % remaining) + distname = m.groups()[0] + remaining = remaining[m.end():] + extras = mark_expr = versions = uri = None + if remaining and remaining[0] == '[': + i = remaining.find(']', 1) + if i < 0: + raise SyntaxError('unterminated extra: %s' % remaining) + s = remaining[1:i] + remaining = remaining[i + 1:].lstrip() + extras = [] + while s: + m = IDENTIFIER.match(s) + if not m: + raise SyntaxError('malformed extra: %s' % s) + extras.append(m.groups()[0]) + s = s[m.end():] + if not s: + break + if s[0] != ',': + raise SyntaxError('comma expected in extras: %s' % s) + s = s[1:].lstrip() + if not extras: + extras = None + if remaining: + if remaining[0] == '@': + # it's a URI + remaining = remaining[1:].lstrip() + m = NON_SPACE.match(remaining) + if not m: + raise SyntaxError('invalid URI: %s' % remaining) + uri = m.groups()[0] + t = urlparse(uri) + # there are issues with Python and URL parsing, so this test + # is a bit crude. See bpo-20271, bpo-23505. Python doesn't + # always parse invalid URLs correctly - it should raise + # exceptions for malformed URLs + if not (t.scheme and t.netloc): + raise SyntaxError('Invalid URL: %s' % uri) + remaining = remaining[m.end():].lstrip() + else: + + def get_versions(ver_remaining): + """ + Return a list of operator, version tuples if any are + specified, else None. + """ + m = COMPARE_OP.match(ver_remaining) + versions = None + if m: + versions = [] + while True: + op = m.groups()[0] + ver_remaining = ver_remaining[m.end():] + m = VERSION_IDENTIFIER.match(ver_remaining) + if not m: + raise SyntaxError('invalid version: %s' % ver_remaining) + v = m.groups()[0] + versions.append((op, v)) + ver_remaining = ver_remaining[m.end():] + if not ver_remaining or ver_remaining[0] != ',': + break + ver_remaining = ver_remaining[1:].lstrip() + m = COMPARE_OP.match(ver_remaining) + if not m: + raise SyntaxError('invalid constraint: %s' % ver_remaining) + if not versions: + versions = None + return versions, ver_remaining + + if remaining[0] != '(': + versions, remaining = get_versions(remaining) + else: + i = remaining.find(')', 1) + if i < 0: + raise SyntaxError('unterminated parenthesis: %s' % remaining) + s = remaining[1:i] + remaining = remaining[i + 1:].lstrip() + # As a special diversion from PEP 508, allow a version number + # a.b.c in parentheses as a synonym for ~= a.b.c (because this + # is allowed in earlier PEPs) + if COMPARE_OP.match(s): + versions, _ = get_versions(s) + else: + m = VERSION_IDENTIFIER.match(s) + if not m: + raise SyntaxError('invalid constraint: %s' % s) + v = m.groups()[0] + s = s[m.end():].lstrip() + if s: + raise SyntaxError('invalid constraint: %s' % s) + versions = [('~=', v)] + + if remaining: + if remaining[0] != ';': + raise SyntaxError('invalid requirement: %s' % remaining) + remaining = remaining[1:].lstrip() + + mark_expr, remaining = parse_marker(remaining) + + if remaining and remaining[0] != '#': + raise SyntaxError('unexpected trailing data: %s' % remaining) + + if not versions: + rs = distname + else: + rs = '%s %s' % (distname, ', '.join(['%s %s' % con for con in versions])) + return Container(name=distname, extras=extras, constraints=versions, + marker=mark_expr, url=uri, requirement=rs) + + +def get_resources_dests(resources_root, rules): + """Find destinations for resources files""" + + def get_rel_path(root, path): + # normalizes and returns a lstripped-/-separated path + root = root.replace(os.path.sep, '/') + path = path.replace(os.path.sep, '/') + assert path.startswith(root) + return path[len(root):].lstrip('/') + + destinations = {} + for base, suffix, dest in rules: + prefix = os.path.join(resources_root, base) + for abs_base in iglob(prefix): + abs_glob = os.path.join(abs_base, suffix) + for abs_path in iglob(abs_glob): + resource_file = get_rel_path(resources_root, abs_path) + if dest is None: # remove the entry if it was here + destinations.pop(resource_file, None) + else: + rel_path = get_rel_path(abs_base, abs_path) + rel_dest = dest.replace(os.path.sep, '/').rstrip('/') + destinations[resource_file] = rel_dest + '/' + rel_path + return destinations + + +def in_venv(): + if hasattr(sys, 'real_prefix'): + # virtualenv venvs + result = True + else: + # PEP 405 venvs + result = sys.prefix != getattr(sys, 'base_prefix', sys.prefix) + return result + + +def get_executable(): +# The __PYVENV_LAUNCHER__ dance is apparently no longer needed, as +# changes to the stub launcher mean that sys.executable always points +# to the stub on OS X +# if sys.platform == 'darwin' and ('__PYVENV_LAUNCHER__' +# in os.environ): +# result = os.environ['__PYVENV_LAUNCHER__'] +# else: +# result = sys.executable +# return result + result = os.path.normcase(sys.executable) + if not isinstance(result, text_type): + result = fsdecode(result) + return result + + +def proceed(prompt, allowed_chars, error_prompt=None, default=None): + p = prompt + while True: + s = raw_input(p) + p = prompt + if not s and default: + s = default + if s: + c = s[0].lower() + if c in allowed_chars: + break + if error_prompt: + p = '%c: %s\n%s' % (c, error_prompt, prompt) + return c + + +def extract_by_key(d, keys): + if isinstance(keys, string_types): + keys = keys.split() + result = {} + for key in keys: + if key in d: + result[key] = d[key] + return result + +def read_exports(stream): + if sys.version_info[0] >= 3: + # needs to be a text stream + stream = codecs.getreader('utf-8')(stream) + # Try to load as JSON, falling back on legacy format + data = stream.read() + stream = StringIO(data) + try: + jdata = json.load(stream) + result = jdata['extensions']['python.exports']['exports'] + for group, entries in result.items(): + for k, v in entries.items(): + s = '%s = %s' % (k, v) + entry = get_export_entry(s) + assert entry is not None + entries[k] = entry + return result + except Exception: + stream.seek(0, 0) + + def read_stream(cp, stream): + if hasattr(cp, 'read_file'): + cp.read_file(stream) + else: + cp.readfp(stream) + + cp = configparser.ConfigParser() + try: + read_stream(cp, stream) + except configparser.MissingSectionHeaderError: + stream.close() + data = textwrap.dedent(data) + stream = StringIO(data) + read_stream(cp, stream) + + result = {} + for key in cp.sections(): + result[key] = entries = {} + for name, value in cp.items(key): + s = '%s = %s' % (name, value) + entry = get_export_entry(s) + assert entry is not None + #entry.dist = self + entries[name] = entry + return result + + +def write_exports(exports, stream): + if sys.version_info[0] >= 3: + # needs to be a text stream + stream = codecs.getwriter('utf-8')(stream) + cp = configparser.ConfigParser() + for k, v in exports.items(): + # TODO check k, v for valid values + cp.add_section(k) + for entry in v.values(): + if entry.suffix is None: + s = entry.prefix + else: + s = '%s:%s' % (entry.prefix, entry.suffix) + if entry.flags: + s = '%s [%s]' % (s, ', '.join(entry.flags)) + cp.set(k, entry.name, s) + cp.write(stream) + + +@contextlib.contextmanager +def tempdir(): + td = tempfile.mkdtemp() + try: + yield td + finally: + shutil.rmtree(td) + +@contextlib.contextmanager +def chdir(d): + cwd = os.getcwd() + try: + os.chdir(d) + yield + finally: + os.chdir(cwd) + + +@contextlib.contextmanager +def socket_timeout(seconds=15): + cto = socket.getdefaulttimeout() + try: + socket.setdefaulttimeout(seconds) + yield + finally: + socket.setdefaulttimeout(cto) + + +class cached_property(object): + def __init__(self, func): + self.func = func + #for attr in ('__name__', '__module__', '__doc__'): + # setattr(self, attr, getattr(func, attr, None)) + + def __get__(self, obj, cls=None): + if obj is None: + return self + value = self.func(obj) + object.__setattr__(obj, self.func.__name__, value) + #obj.__dict__[self.func.__name__] = value = self.func(obj) + return value + +def convert_path(pathname): + """Return 'pathname' as a name that will work on the native filesystem. + + The path is split on '/' and put back together again using the current + directory separator. Needed because filenames in the setup script are + always supplied in Unix style, and have to be converted to the local + convention before we can actually use them in the filesystem. Raises + ValueError on non-Unix-ish systems if 'pathname' either starts or + ends with a slash. + """ + if os.sep == '/': + return pathname + if not pathname: + return pathname + if pathname[0] == '/': + raise ValueError("path '%s' cannot be absolute" % pathname) + if pathname[-1] == '/': + raise ValueError("path '%s' cannot end with '/'" % pathname) + + paths = pathname.split('/') + while os.curdir in paths: + paths.remove(os.curdir) + if not paths: + return os.curdir + return os.path.join(*paths) + + +class FileOperator(object): + def __init__(self, dry_run=False): + self.dry_run = dry_run + self.ensured = set() + self._init_record() + + def _init_record(self): + self.record = False + self.files_written = set() + self.dirs_created = set() + + def record_as_written(self, path): + if self.record: + self.files_written.add(path) + + def newer(self, source, target): + """Tell if the target is newer than the source. + + Returns true if 'source' exists and is more recently modified than + 'target', or if 'source' exists and 'target' doesn't. + + Returns false if both exist and 'target' is the same age or younger + than 'source'. Raise PackagingFileError if 'source' does not exist. + + Note that this test is not very accurate: files created in the same + second will have the same "age". + """ + if not os.path.exists(source): + raise DistlibException("file '%r' does not exist" % + os.path.abspath(source)) + if not os.path.exists(target): + return True + + return os.stat(source).st_mtime > os.stat(target).st_mtime + + def copy_file(self, infile, outfile, check=True): + """Copy a file respecting dry-run and force flags. + """ + self.ensure_dir(os.path.dirname(outfile)) + logger.info('Copying %s to %s', infile, outfile) + if not self.dry_run: + msg = None + if check: + if os.path.islink(outfile): + msg = '%s is a symlink' % outfile + elif os.path.exists(outfile) and not os.path.isfile(outfile): + msg = '%s is a non-regular file' % outfile + if msg: + raise ValueError(msg + ' which would be overwritten') + shutil.copyfile(infile, outfile) + self.record_as_written(outfile) + + def copy_stream(self, instream, outfile, encoding=None): + assert not os.path.isdir(outfile) + self.ensure_dir(os.path.dirname(outfile)) + logger.info('Copying stream %s to %s', instream, outfile) + if not self.dry_run: + if encoding is None: + outstream = open(outfile, 'wb') + else: + outstream = codecs.open(outfile, 'w', encoding=encoding) + try: + shutil.copyfileobj(instream, outstream) + finally: + outstream.close() + self.record_as_written(outfile) + + def write_binary_file(self, path, data): + self.ensure_dir(os.path.dirname(path)) + if not self.dry_run: + if os.path.exists(path): + os.remove(path) + with open(path, 'wb') as f: + f.write(data) + self.record_as_written(path) + + def write_text_file(self, path, data, encoding): + self.write_binary_file(path, data.encode(encoding)) + + def set_mode(self, bits, mask, files): + if os.name == 'posix' or (os.name == 'java' and os._name == 'posix'): + # Set the executable bits (owner, group, and world) on + # all the files specified. + for f in files: + if self.dry_run: + logger.info("changing mode of %s", f) + else: + mode = (os.stat(f).st_mode | bits) & mask + logger.info("changing mode of %s to %o", f, mode) + os.chmod(f, mode) + + set_executable_mode = lambda s, f: s.set_mode(0o555, 0o7777, f) + + def ensure_dir(self, path): + path = os.path.abspath(path) + if path not in self.ensured and not os.path.exists(path): + self.ensured.add(path) + d, f = os.path.split(path) + self.ensure_dir(d) + logger.info('Creating %s' % path) + if not self.dry_run: + os.mkdir(path) + if self.record: + self.dirs_created.add(path) + + def byte_compile(self, path, optimize=False, force=False, prefix=None, hashed_invalidation=False): + dpath = cache_from_source(path, not optimize) + logger.info('Byte-compiling %s to %s', path, dpath) + if not self.dry_run: + if force or self.newer(path, dpath): + if not prefix: + diagpath = None + else: + assert path.startswith(prefix) + diagpath = path[len(prefix):] + compile_kwargs = {} + if hashed_invalidation and hasattr(py_compile, 'PycInvalidationMode'): + compile_kwargs['invalidation_mode'] = py_compile.PycInvalidationMode.CHECKED_HASH + py_compile.compile(path, dpath, diagpath, True, **compile_kwargs) # raise error + self.record_as_written(dpath) + return dpath + + def ensure_removed(self, path): + if os.path.exists(path): + if os.path.isdir(path) and not os.path.islink(path): + logger.debug('Removing directory tree at %s', path) + if not self.dry_run: + shutil.rmtree(path) + if self.record: + if path in self.dirs_created: + self.dirs_created.remove(path) + else: + if os.path.islink(path): + s = 'link' + else: + s = 'file' + logger.debug('Removing %s %s', s, path) + if not self.dry_run: + os.remove(path) + if self.record: + if path in self.files_written: + self.files_written.remove(path) + + def is_writable(self, path): + result = False + while not result: + if os.path.exists(path): + result = os.access(path, os.W_OK) + break + parent = os.path.dirname(path) + if parent == path: + break + path = parent + return result + + def commit(self): + """ + Commit recorded changes, turn off recording, return + changes. + """ + assert self.record + result = self.files_written, self.dirs_created + self._init_record() + return result + + def rollback(self): + if not self.dry_run: + for f in list(self.files_written): + if os.path.exists(f): + os.remove(f) + # dirs should all be empty now, except perhaps for + # __pycache__ subdirs + # reverse so that subdirs appear before their parents + dirs = sorted(self.dirs_created, reverse=True) + for d in dirs: + flist = os.listdir(d) + if flist: + assert flist == ['__pycache__'] + sd = os.path.join(d, flist[0]) + os.rmdir(sd) + os.rmdir(d) # should fail if non-empty + self._init_record() + +def resolve(module_name, dotted_path): + if module_name in sys.modules: + mod = sys.modules[module_name] + else: + mod = __import__(module_name) + if dotted_path is None: + result = mod + else: + parts = dotted_path.split('.') + result = getattr(mod, parts.pop(0)) + for p in parts: + result = getattr(result, p) + return result + + +class ExportEntry(object): + def __init__(self, name, prefix, suffix, flags): + self.name = name + self.prefix = prefix + self.suffix = suffix + self.flags = flags + + @cached_property + def value(self): + return resolve(self.prefix, self.suffix) + + def __repr__(self): # pragma: no cover + return '' % (self.name, self.prefix, + self.suffix, self.flags) + + def __eq__(self, other): + if not isinstance(other, ExportEntry): + result = False + else: + result = (self.name == other.name and + self.prefix == other.prefix and + self.suffix == other.suffix and + self.flags == other.flags) + return result + + __hash__ = object.__hash__ + + +ENTRY_RE = re.compile(r'''(?P(\w|[-.+])+) + \s*=\s*(?P(\w+)([:\.]\w+)*) + \s*(\[\s*(?P[\w-]+(=\w+)?(,\s*\w+(=\w+)?)*)\s*\])? + ''', re.VERBOSE) + +def get_export_entry(specification): + m = ENTRY_RE.search(specification) + if not m: + result = None + if '[' in specification or ']' in specification: + raise DistlibException("Invalid specification " + "'%s'" % specification) + else: + d = m.groupdict() + name = d['name'] + path = d['callable'] + colons = path.count(':') + if colons == 0: + prefix, suffix = path, None + else: + if colons != 1: + raise DistlibException("Invalid specification " + "'%s'" % specification) + prefix, suffix = path.split(':') + flags = d['flags'] + if flags is None: + if '[' in specification or ']' in specification: + raise DistlibException("Invalid specification " + "'%s'" % specification) + flags = [] + else: + flags = [f.strip() for f in flags.split(',')] + result = ExportEntry(name, prefix, suffix, flags) + return result + + +def get_cache_base(suffix=None): + """ + Return the default base location for distlib caches. If the directory does + not exist, it is created. Use the suffix provided for the base directory, + and default to '.distlib' if it isn't provided. + + On Windows, if LOCALAPPDATA is defined in the environment, then it is + assumed to be a directory, and will be the parent directory of the result. + On POSIX, and on Windows if LOCALAPPDATA is not defined, the user's home + directory - using os.expanduser('~') - will be the parent directory of + the result. + + The result is just the directory '.distlib' in the parent directory as + determined above, or with the name specified with ``suffix``. + """ + if suffix is None: + suffix = '.distlib' + if os.name == 'nt' and 'LOCALAPPDATA' in os.environ: + result = os.path.expandvars('$localappdata') + else: + # Assume posix, or old Windows + result = os.path.expanduser('~') + # we use 'isdir' instead of 'exists', because we want to + # fail if there's a file with that name + if os.path.isdir(result): + usable = os.access(result, os.W_OK) + if not usable: + logger.warning('Directory exists but is not writable: %s', result) + else: + try: + os.makedirs(result) + usable = True + except OSError: + logger.warning('Unable to create %s', result, exc_info=True) + usable = False + if not usable: + result = tempfile.mkdtemp() + logger.warning('Default location unusable, using %s', result) + return os.path.join(result, suffix) + + +def path_to_cache_dir(path): + """ + Convert an absolute path to a directory name for use in a cache. + + The algorithm used is: + + #. On Windows, any ``':'`` in the drive is replaced with ``'---'``. + #. Any occurrence of ``os.sep`` is replaced with ``'--'``. + #. ``'.cache'`` is appended. + """ + d, p = os.path.splitdrive(os.path.abspath(path)) + if d: + d = d.replace(':', '---') + p = p.replace(os.sep, '--') + return d + p + '.cache' + + +def ensure_slash(s): + if not s.endswith('/'): + return s + '/' + return s + + +def parse_credentials(netloc): + username = password = None + if '@' in netloc: + prefix, netloc = netloc.rsplit('@', 1) + if ':' not in prefix: + username = prefix + else: + username, password = prefix.split(':', 1) + if username: + username = unquote(username) + if password: + password = unquote(password) + return username, password, netloc + + +def get_process_umask(): + result = os.umask(0o22) + os.umask(result) + return result + +def is_string_sequence(seq): + result = True + i = None + for i, s in enumerate(seq): + if not isinstance(s, string_types): + result = False + break + assert i is not None + return result + +PROJECT_NAME_AND_VERSION = re.compile('([a-z0-9_]+([.-][a-z_][a-z0-9_]*)*)-' + '([a-z0-9_.+-]+)', re.I) +PYTHON_VERSION = re.compile(r'-py(\d\.?\d?)') + + +def split_filename(filename, project_name=None): + """ + Extract name, version, python version from a filename (no extension) + + Return name, version, pyver or None + """ + result = None + pyver = None + filename = unquote(filename).replace(' ', '-') + m = PYTHON_VERSION.search(filename) + if m: + pyver = m.group(1) + filename = filename[:m.start()] + if project_name and len(filename) > len(project_name) + 1: + m = re.match(re.escape(project_name) + r'\b', filename) + if m: + n = m.end() + result = filename[:n], filename[n + 1:], pyver + if result is None: + m = PROJECT_NAME_AND_VERSION.match(filename) + if m: + result = m.group(1), m.group(3), pyver + return result + +# Allow spaces in name because of legacy dists like "Twisted Core" +NAME_VERSION_RE = re.compile(r'(?P[\w .-]+)\s*' + r'\(\s*(?P[^\s)]+)\)$') + +def parse_name_and_version(p): + """ + A utility method used to get name and version from a string. + + From e.g. a Provides-Dist value. + + :param p: A value in a form 'foo (1.0)' + :return: The name and version as a tuple. + """ + m = NAME_VERSION_RE.match(p) + if not m: + raise DistlibException('Ill-formed name/version string: \'%s\'' % p) + d = m.groupdict() + return d['name'].strip().lower(), d['ver'] + +def get_extras(requested, available): + result = set() + requested = set(requested or []) + available = set(available or []) + if '*' in requested: + requested.remove('*') + result |= available + for r in requested: + if r == '-': + result.add(r) + elif r.startswith('-'): + unwanted = r[1:] + if unwanted not in available: + logger.warning('undeclared extra: %s' % unwanted) + if unwanted in result: + result.remove(unwanted) + else: + if r not in available: + logger.warning('undeclared extra: %s' % r) + result.add(r) + return result +# +# Extended metadata functionality +# + +def _get_external_data(url): + result = {} + try: + # urlopen might fail if it runs into redirections, + # because of Python issue #13696. Fixed in locators + # using a custom redirect handler. + resp = urlopen(url) + headers = resp.info() + ct = headers.get('Content-Type') + if not ct.startswith('application/json'): + logger.debug('Unexpected response for JSON request: %s', ct) + else: + reader = codecs.getreader('utf-8')(resp) + #data = reader.read().decode('utf-8') + #result = json.loads(data) + result = json.load(reader) + except Exception as e: + logger.exception('Failed to get external data for %s: %s', url, e) + return result + +_external_data_base_url = 'https://www.red-dove.com/pypi/projects/' + +def get_project_data(name): + url = '%s/%s/project.json' % (name[0].upper(), name) + url = urljoin(_external_data_base_url, url) + result = _get_external_data(url) + return result + +def get_package_data(name, version): + url = '%s/%s/package-%s.json' % (name[0].upper(), name, version) + url = urljoin(_external_data_base_url, url) + return _get_external_data(url) + + +class Cache(object): + """ + A class implementing a cache for resources that need to live in the file system + e.g. shared libraries. This class was moved from resources to here because it + could be used by other modules, e.g. the wheel module. + """ + + def __init__(self, base): + """ + Initialise an instance. + + :param base: The base directory where the cache should be located. + """ + # we use 'isdir' instead of 'exists', because we want to + # fail if there's a file with that name + if not os.path.isdir(base): # pragma: no cover + os.makedirs(base) + if (os.stat(base).st_mode & 0o77) != 0: + logger.warning('Directory \'%s\' is not private', base) + self.base = os.path.abspath(os.path.normpath(base)) + + def prefix_to_dir(self, prefix): + """ + Converts a resource prefix to a directory name in the cache. + """ + return path_to_cache_dir(prefix) + + def clear(self): + """ + Clear the cache. + """ + not_removed = [] + for fn in os.listdir(self.base): + fn = os.path.join(self.base, fn) + try: + if os.path.islink(fn) or os.path.isfile(fn): + os.remove(fn) + elif os.path.isdir(fn): + shutil.rmtree(fn) + except Exception: + not_removed.append(fn) + return not_removed + + +class EventMixin(object): + """ + A very simple publish/subscribe system. + """ + def __init__(self): + self._subscribers = {} + + def add(self, event, subscriber, append=True): + """ + Add a subscriber for an event. + + :param event: The name of an event. + :param subscriber: The subscriber to be added (and called when the + event is published). + :param append: Whether to append or prepend the subscriber to an + existing subscriber list for the event. + """ + subs = self._subscribers + if event not in subs: + subs[event] = deque([subscriber]) + else: + sq = subs[event] + if append: + sq.append(subscriber) + else: + sq.appendleft(subscriber) + + def remove(self, event, subscriber): + """ + Remove a subscriber for an event. + + :param event: The name of an event. + :param subscriber: The subscriber to be removed. + """ + subs = self._subscribers + if event not in subs: + raise ValueError('No subscribers: %r' % event) + subs[event].remove(subscriber) + + def get_subscribers(self, event): + """ + Return an iterator for the subscribers for an event. + :param event: The event to return subscribers for. + """ + return iter(self._subscribers.get(event, ())) + + def publish(self, event, *args, **kwargs): + """ + Publish a event and return a list of values returned by its + subscribers. + + :param event: The event to publish. + :param args: The positional arguments to pass to the event's + subscribers. + :param kwargs: The keyword arguments to pass to the event's + subscribers. + """ + result = [] + for subscriber in self.get_subscribers(event): + try: + value = subscriber(event, *args, **kwargs) + except Exception: + logger.exception('Exception during event publication') + value = None + result.append(value) + logger.debug('publish %s: args = %s, kwargs = %s, result = %s', + event, args, kwargs, result) + return result + +# +# Simple sequencing +# +class Sequencer(object): + def __init__(self): + self._preds = {} + self._succs = {} + self._nodes = set() # nodes with no preds/succs + + def add_node(self, node): + self._nodes.add(node) + + def remove_node(self, node, edges=False): + if node in self._nodes: + self._nodes.remove(node) + if edges: + for p in set(self._preds.get(node, ())): + self.remove(p, node) + for s in set(self._succs.get(node, ())): + self.remove(node, s) + # Remove empties + for k, v in list(self._preds.items()): + if not v: + del self._preds[k] + for k, v in list(self._succs.items()): + if not v: + del self._succs[k] + + def add(self, pred, succ): + assert pred != succ + self._preds.setdefault(succ, set()).add(pred) + self._succs.setdefault(pred, set()).add(succ) + + def remove(self, pred, succ): + assert pred != succ + try: + preds = self._preds[succ] + succs = self._succs[pred] + except KeyError: # pragma: no cover + raise ValueError('%r not a successor of anything' % succ) + try: + preds.remove(pred) + succs.remove(succ) + except KeyError: # pragma: no cover + raise ValueError('%r not a successor of %r' % (succ, pred)) + + def is_step(self, step): + return (step in self._preds or step in self._succs or + step in self._nodes) + + def get_steps(self, final): + if not self.is_step(final): + raise ValueError('Unknown: %r' % final) + result = [] + todo = [] + seen = set() + todo.append(final) + while todo: + step = todo.pop(0) + if step in seen: + # if a step was already seen, + # move it to the end (so it will appear earlier + # when reversed on return) ... but not for the + # final step, as that would be confusing for + # users + if step != final: + result.remove(step) + result.append(step) + else: + seen.add(step) + result.append(step) + preds = self._preds.get(step, ()) + todo.extend(preds) + return reversed(result) + + @property + def strong_connections(self): + #http://en.wikipedia.org/wiki/Tarjan%27s_strongly_connected_components_algorithm + index_counter = [0] + stack = [] + lowlinks = {} + index = {} + result = [] + + graph = self._succs + + def strongconnect(node): + # set the depth index for this node to the smallest unused index + index[node] = index_counter[0] + lowlinks[node] = index_counter[0] + index_counter[0] += 1 + stack.append(node) + + # Consider successors + try: + successors = graph[node] + except Exception: + successors = [] + for successor in successors: + if successor not in lowlinks: + # Successor has not yet been visited + strongconnect(successor) + lowlinks[node] = min(lowlinks[node],lowlinks[successor]) + elif successor in stack: + # the successor is in the stack and hence in the current + # strongly connected component (SCC) + lowlinks[node] = min(lowlinks[node],index[successor]) + + # If `node` is a root node, pop the stack and generate an SCC + if lowlinks[node] == index[node]: + connected_component = [] + + while True: + successor = stack.pop() + connected_component.append(successor) + if successor == node: break + component = tuple(connected_component) + # storing the result + result.append(component) + + for node in graph: + if node not in lowlinks: + strongconnect(node) + + return result + + @property + def dot(self): + result = ['digraph G {'] + for succ in self._preds: + preds = self._preds[succ] + for pred in preds: + result.append(' %s -> %s;' % (pred, succ)) + for node in self._nodes: + result.append(' %s;' % node) + result.append('}') + return '\n'.join(result) + +# +# Unarchiving functionality for zip, tar, tgz, tbz, whl +# + +ARCHIVE_EXTENSIONS = ('.tar.gz', '.tar.bz2', '.tar', '.zip', + '.tgz', '.tbz', '.whl') + +def unarchive(archive_filename, dest_dir, format=None, check=True): + + def check_path(path): + if not isinstance(path, text_type): + path = path.decode('utf-8') + p = os.path.abspath(os.path.join(dest_dir, path)) + if not p.startswith(dest_dir) or p[plen] != os.sep: + raise ValueError('path outside destination: %r' % p) + + dest_dir = os.path.abspath(dest_dir) + plen = len(dest_dir) + archive = None + if format is None: + if archive_filename.endswith(('.zip', '.whl')): + format = 'zip' + elif archive_filename.endswith(('.tar.gz', '.tgz')): + format = 'tgz' + mode = 'r:gz' + elif archive_filename.endswith(('.tar.bz2', '.tbz')): + format = 'tbz' + mode = 'r:bz2' + elif archive_filename.endswith('.tar'): + format = 'tar' + mode = 'r' + else: # pragma: no cover + raise ValueError('Unknown format for %r' % archive_filename) + try: + if format == 'zip': + archive = ZipFile(archive_filename, 'r') + if check: + names = archive.namelist() + for name in names: + check_path(name) + else: + archive = tarfile.open(archive_filename, mode) + if check: + names = archive.getnames() + for name in names: + check_path(name) + if format != 'zip' and sys.version_info[0] < 3: + # See Python issue 17153. If the dest path contains Unicode, + # tarfile extraction fails on Python 2.x if a member path name + # contains non-ASCII characters - it leads to an implicit + # bytes -> unicode conversion using ASCII to decode. + for tarinfo in archive.getmembers(): + if not isinstance(tarinfo.name, text_type): + tarinfo.name = tarinfo.name.decode('utf-8') + archive.extractall(dest_dir) + + finally: + if archive: + archive.close() + + +def zip_dir(directory): + """zip a directory tree into a BytesIO object""" + result = io.BytesIO() + dlen = len(directory) + with ZipFile(result, "w") as zf: + for root, dirs, files in os.walk(directory): + for name in files: + full = os.path.join(root, name) + rel = root[dlen:] + dest = os.path.join(rel, name) + zf.write(full, dest) + return result + +# +# Simple progress bar +# + +UNITS = ('', 'K', 'M', 'G','T','P') + + +class Progress(object): + unknown = 'UNKNOWN' + + def __init__(self, minval=0, maxval=100): + assert maxval is None or maxval >= minval + self.min = self.cur = minval + self.max = maxval + self.started = None + self.elapsed = 0 + self.done = False + + def update(self, curval): + assert self.min <= curval + assert self.max is None or curval <= self.max + self.cur = curval + now = time.time() + if self.started is None: + self.started = now + else: + self.elapsed = now - self.started + + def increment(self, incr): + assert incr >= 0 + self.update(self.cur + incr) + + def start(self): + self.update(self.min) + return self + + def stop(self): + if self.max is not None: + self.update(self.max) + self.done = True + + @property + def maximum(self): + return self.unknown if self.max is None else self.max + + @property + def percentage(self): + if self.done: + result = '100 %' + elif self.max is None: + result = ' ?? %' + else: + v = 100.0 * (self.cur - self.min) / (self.max - self.min) + result = '%3d %%' % v + return result + + def format_duration(self, duration): + if (duration <= 0) and self.max is None or self.cur == self.min: + result = '??:??:??' + #elif duration < 1: + # result = '--:--:--' + else: + result = time.strftime('%H:%M:%S', time.gmtime(duration)) + return result + + @property + def ETA(self): + if self.done: + prefix = 'Done' + t = self.elapsed + #import pdb; pdb.set_trace() + else: + prefix = 'ETA ' + if self.max is None: + t = -1 + elif self.elapsed == 0 or (self.cur == self.min): + t = 0 + else: + #import pdb; pdb.set_trace() + t = float(self.max - self.min) + t /= self.cur - self.min + t = (t - 1) * self.elapsed + return '%s: %s' % (prefix, self.format_duration(t)) + + @property + def speed(self): + if self.elapsed == 0: + result = 0.0 + else: + result = (self.cur - self.min) / self.elapsed + for unit in UNITS: + if result < 1000: + break + result /= 1000.0 + return '%d %sB/s' % (result, unit) + +# +# Glob functionality +# + +RICH_GLOB = re.compile(r'\{([^}]*)\}') +_CHECK_RECURSIVE_GLOB = re.compile(r'[^/\\,{]\*\*|\*\*[^/\\,}]') +_CHECK_MISMATCH_SET = re.compile(r'^[^{]*\}|\{[^}]*$') + + +def iglob(path_glob): + """Extended globbing function that supports ** and {opt1,opt2,opt3}.""" + if _CHECK_RECURSIVE_GLOB.search(path_glob): + msg = """invalid glob %r: recursive glob "**" must be used alone""" + raise ValueError(msg % path_glob) + if _CHECK_MISMATCH_SET.search(path_glob): + msg = """invalid glob %r: mismatching set marker '{' or '}'""" + raise ValueError(msg % path_glob) + return _iglob(path_glob) + + +def _iglob(path_glob): + rich_path_glob = RICH_GLOB.split(path_glob, 1) + if len(rich_path_glob) > 1: + assert len(rich_path_glob) == 3, rich_path_glob + prefix, set, suffix = rich_path_glob + for item in set.split(','): + for path in _iglob(''.join((prefix, item, suffix))): + yield path + else: + if '**' not in path_glob: + for item in std_iglob(path_glob): + yield item + else: + prefix, radical = path_glob.split('**', 1) + if prefix == '': + prefix = '.' + if radical == '': + radical = '*' + else: + # we support both + radical = radical.lstrip('/') + radical = radical.lstrip('\\') + for path, dir, files in os.walk(prefix): + path = os.path.normpath(path) + for fn in _iglob(os.path.join(path, radical)): + yield fn + +if ssl: + from .compat import (HTTPSHandler as BaseHTTPSHandler, match_hostname, + CertificateError) + + +# +# HTTPSConnection which verifies certificates/matches domains +# + + class HTTPSConnection(httplib.HTTPSConnection): + ca_certs = None # set this to the path to the certs file (.pem) + check_domain = True # only used if ca_certs is not None + + # noinspection PyPropertyAccess + def connect(self): + sock = socket.create_connection((self.host, self.port), self.timeout) + if getattr(self, '_tunnel_host', False): + self.sock = sock + self._tunnel() + + if not hasattr(ssl, 'SSLContext'): + # For 2.x + if self.ca_certs: + cert_reqs = ssl.CERT_REQUIRED + else: + cert_reqs = ssl.CERT_NONE + self.sock = ssl.wrap_socket(sock, self.key_file, self.cert_file, + cert_reqs=cert_reqs, + ssl_version=ssl.PROTOCOL_SSLv23, + ca_certs=self.ca_certs) + else: # pragma: no cover + context = ssl.SSLContext(ssl.PROTOCOL_SSLv23) + if hasattr(ssl, 'OP_NO_SSLv2'): + context.options |= ssl.OP_NO_SSLv2 + if self.cert_file: + context.load_cert_chain(self.cert_file, self.key_file) + kwargs = {} + if self.ca_certs: + context.verify_mode = ssl.CERT_REQUIRED + context.load_verify_locations(cafile=self.ca_certs) + if getattr(ssl, 'HAS_SNI', False): + kwargs['server_hostname'] = self.host + self.sock = context.wrap_socket(sock, **kwargs) + if self.ca_certs and self.check_domain: + try: + match_hostname(self.sock.getpeercert(), self.host) + logger.debug('Host verified: %s', self.host) + except CertificateError: # pragma: no cover + self.sock.shutdown(socket.SHUT_RDWR) + self.sock.close() + raise + + class HTTPSHandler(BaseHTTPSHandler): + def __init__(self, ca_certs, check_domain=True): + BaseHTTPSHandler.__init__(self) + self.ca_certs = ca_certs + self.check_domain = check_domain + + def _conn_maker(self, *args, **kwargs): + """ + This is called to create a connection instance. Normally you'd + pass a connection class to do_open, but it doesn't actually check for + a class, and just expects a callable. As long as we behave just as a + constructor would have, we should be OK. If it ever changes so that + we *must* pass a class, we'll create an UnsafeHTTPSConnection class + which just sets check_domain to False in the class definition, and + choose which one to pass to do_open. + """ + result = HTTPSConnection(*args, **kwargs) + if self.ca_certs: + result.ca_certs = self.ca_certs + result.check_domain = self.check_domain + return result + + def https_open(self, req): + try: + return self.do_open(self._conn_maker, req) + except URLError as e: + if 'certificate verify failed' in str(e.reason): + raise CertificateError('Unable to verify server certificate ' + 'for %s' % req.host) + else: + raise + + # + # To prevent against mixing HTTP traffic with HTTPS (examples: A Man-In-The- + # Middle proxy using HTTP listens on port 443, or an index mistakenly serves + # HTML containing a http://xyz link when it should be https://xyz), + # you can use the following handler class, which does not allow HTTP traffic. + # + # It works by inheriting from HTTPHandler - so build_opener won't add a + # handler for HTTP itself. + # + class HTTPSOnlyHandler(HTTPSHandler, HTTPHandler): + def http_open(self, req): + raise URLError('Unexpected HTTP request on what should be a secure ' + 'connection: %s' % req) + +# +# XML-RPC with timeouts +# + +_ver_info = sys.version_info[:2] + +if _ver_info == (2, 6): + class HTTP(httplib.HTTP): + def __init__(self, host='', port=None, **kwargs): + if port == 0: # 0 means use port 0, not the default port + port = None + self._setup(self._connection_class(host, port, **kwargs)) + + + if ssl: + class HTTPS(httplib.HTTPS): + def __init__(self, host='', port=None, **kwargs): + if port == 0: # 0 means use port 0, not the default port + port = None + self._setup(self._connection_class(host, port, **kwargs)) + + +class Transport(xmlrpclib.Transport): + def __init__(self, timeout, use_datetime=0): + self.timeout = timeout + xmlrpclib.Transport.__init__(self, use_datetime) + + def make_connection(self, host): + h, eh, x509 = self.get_host_info(host) + if _ver_info == (2, 6): + result = HTTP(h, timeout=self.timeout) + else: + if not self._connection or host != self._connection[0]: + self._extra_headers = eh + self._connection = host, httplib.HTTPConnection(h) + result = self._connection[1] + return result + +if ssl: + class SafeTransport(xmlrpclib.SafeTransport): + def __init__(self, timeout, use_datetime=0): + self.timeout = timeout + xmlrpclib.SafeTransport.__init__(self, use_datetime) + + def make_connection(self, host): + h, eh, kwargs = self.get_host_info(host) + if not kwargs: + kwargs = {} + kwargs['timeout'] = self.timeout + if _ver_info == (2, 6): + result = HTTPS(host, None, **kwargs) + else: + if not self._connection or host != self._connection[0]: + self._extra_headers = eh + self._connection = host, httplib.HTTPSConnection(h, None, + **kwargs) + result = self._connection[1] + return result + + +class ServerProxy(xmlrpclib.ServerProxy): + def __init__(self, uri, **kwargs): + self.timeout = timeout = kwargs.pop('timeout', None) + # The above classes only come into play if a timeout + # is specified + if timeout is not None: + scheme, _ = splittype(uri) + use_datetime = kwargs.get('use_datetime', 0) + if scheme == 'https': + tcls = SafeTransport + else: + tcls = Transport + kwargs['transport'] = t = tcls(timeout, use_datetime=use_datetime) + self.transport = t + xmlrpclib.ServerProxy.__init__(self, uri, **kwargs) + +# +# CSV functionality. This is provided because on 2.x, the csv module can't +# handle Unicode. However, we need to deal with Unicode in e.g. RECORD files. +# + +def _csv_open(fn, mode, **kwargs): + if sys.version_info[0] < 3: + mode += 'b' + else: + kwargs['newline'] = '' + # Python 3 determines encoding from locale. Force 'utf-8' + # file encoding to match other forced utf-8 encoding + kwargs['encoding'] = 'utf-8' + return open(fn, mode, **kwargs) + + +class CSVBase(object): + defaults = { + 'delimiter': str(','), # The strs are used because we need native + 'quotechar': str('"'), # str in the csv API (2.x won't take + 'lineterminator': str('\n') # Unicode) + } + + def __enter__(self): + return self + + def __exit__(self, *exc_info): + self.stream.close() + + +class CSVReader(CSVBase): + def __init__(self, **kwargs): + if 'stream' in kwargs: + stream = kwargs['stream'] + if sys.version_info[0] >= 3: + # needs to be a text stream + stream = codecs.getreader('utf-8')(stream) + self.stream = stream + else: + self.stream = _csv_open(kwargs['path'], 'r') + self.reader = csv.reader(self.stream, **self.defaults) + + def __iter__(self): + return self + + def next(self): + result = next(self.reader) + if sys.version_info[0] < 3: + for i, item in enumerate(result): + if not isinstance(item, text_type): + result[i] = item.decode('utf-8') + return result + + __next__ = next + +class CSVWriter(CSVBase): + def __init__(self, fn, **kwargs): + self.stream = _csv_open(fn, 'w') + self.writer = csv.writer(self.stream, **self.defaults) + + def writerow(self, row): + if sys.version_info[0] < 3: + r = [] + for item in row: + if isinstance(item, text_type): + item = item.encode('utf-8') + r.append(item) + row = r + self.writer.writerow(row) + +# +# Configurator functionality +# + +class Configurator(BaseConfigurator): + + value_converters = dict(BaseConfigurator.value_converters) + value_converters['inc'] = 'inc_convert' + + def __init__(self, config, base=None): + super(Configurator, self).__init__(config) + self.base = base or os.getcwd() + + def configure_custom(self, config): + def convert(o): + if isinstance(o, (list, tuple)): + result = type(o)([convert(i) for i in o]) + elif isinstance(o, dict): + if '()' in o: + result = self.configure_custom(o) + else: + result = {} + for k in o: + result[k] = convert(o[k]) + else: + result = self.convert(o) + return result + + c = config.pop('()') + if not callable(c): + c = self.resolve(c) + props = config.pop('.', None) + # Check for valid identifiers + args = config.pop('[]', ()) + if args: + args = tuple([convert(o) for o in args]) + items = [(k, convert(config[k])) for k in config if valid_ident(k)] + kwargs = dict(items) + result = c(*args, **kwargs) + if props: + for n, v in props.items(): + setattr(result, n, convert(v)) + return result + + def __getitem__(self, key): + result = self.config[key] + if isinstance(result, dict) and '()' in result: + self.config[key] = result = self.configure_custom(result) + return result + + def inc_convert(self, value): + """Default converter for the inc:// protocol.""" + if not os.path.isabs(value): + value = os.path.join(self.base, value) + with codecs.open(value, 'r', encoding='utf-8') as f: + result = json.load(f) + return result + + +class SubprocessMixin(object): + """ + Mixin for running subprocesses and capturing their output + """ + def __init__(self, verbose=False, progress=None): + self.verbose = verbose + self.progress = progress + + def reader(self, stream, context): + """ + Read lines from a subprocess' output stream and either pass to a progress + callable (if specified) or write progress information to sys.stderr. + """ + progress = self.progress + verbose = self.verbose + while True: + s = stream.readline() + if not s: + break + if progress is not None: + progress(s, context) + else: + if not verbose: + sys.stderr.write('.') + else: + sys.stderr.write(s.decode('utf-8')) + sys.stderr.flush() + stream.close() + + def run_command(self, cmd, **kwargs): + p = subprocess.Popen(cmd, stdout=subprocess.PIPE, + stderr=subprocess.PIPE, **kwargs) + t1 = threading.Thread(target=self.reader, args=(p.stdout, 'stdout')) + t1.start() + t2 = threading.Thread(target=self.reader, args=(p.stderr, 'stderr')) + t2.start() + p.wait() + t1.join() + t2.join() + if self.progress is not None: + self.progress('done.', 'main') + elif self.verbose: + sys.stderr.write('done.\n') + return p + + +def normalize_name(name): + """Normalize a python package name a la PEP 503""" + # https://www.python.org/dev/peps/pep-0503/#normalized-names + return re.sub('[-_.]+', '-', name).lower() diff --git a/venv/Lib/site-packages/pip/_vendor/distlib/version.py b/venv/Lib/site-packages/pip/_vendor/distlib/version.py new file mode 100644 index 0000000..3eebe18 --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/distlib/version.py @@ -0,0 +1,736 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2012-2017 The Python Software Foundation. +# See LICENSE.txt and CONTRIBUTORS.txt. +# +""" +Implementation of a flexible versioning scheme providing support for PEP-440, +setuptools-compatible and semantic versioning. +""" + +import logging +import re + +from .compat import string_types +from .util import parse_requirement + +__all__ = ['NormalizedVersion', 'NormalizedMatcher', + 'LegacyVersion', 'LegacyMatcher', + 'SemanticVersion', 'SemanticMatcher', + 'UnsupportedVersionError', 'get_scheme'] + +logger = logging.getLogger(__name__) + + +class UnsupportedVersionError(ValueError): + """This is an unsupported version.""" + pass + + +class Version(object): + def __init__(self, s): + self._string = s = s.strip() + self._parts = parts = self.parse(s) + assert isinstance(parts, tuple) + assert len(parts) > 0 + + def parse(self, s): + raise NotImplementedError('please implement in a subclass') + + def _check_compatible(self, other): + if type(self) != type(other): + raise TypeError('cannot compare %r and %r' % (self, other)) + + def __eq__(self, other): + self._check_compatible(other) + return self._parts == other._parts + + def __ne__(self, other): + return not self.__eq__(other) + + def __lt__(self, other): + self._check_compatible(other) + return self._parts < other._parts + + def __gt__(self, other): + return not (self.__lt__(other) or self.__eq__(other)) + + def __le__(self, other): + return self.__lt__(other) or self.__eq__(other) + + def __ge__(self, other): + return self.__gt__(other) or self.__eq__(other) + + # See http://docs.python.org/reference/datamodel#object.__hash__ + def __hash__(self): + return hash(self._parts) + + def __repr__(self): + return "%s('%s')" % (self.__class__.__name__, self._string) + + def __str__(self): + return self._string + + @property + def is_prerelease(self): + raise NotImplementedError('Please implement in subclasses.') + + +class Matcher(object): + version_class = None + + # value is either a callable or the name of a method + _operators = { + '<': lambda v, c, p: v < c, + '>': lambda v, c, p: v > c, + '<=': lambda v, c, p: v == c or v < c, + '>=': lambda v, c, p: v == c or v > c, + '==': lambda v, c, p: v == c, + '===': lambda v, c, p: v == c, + # by default, compatible => >=. + '~=': lambda v, c, p: v == c or v > c, + '!=': lambda v, c, p: v != c, + } + + # this is a method only to support alternative implementations + # via overriding + def parse_requirement(self, s): + return parse_requirement(s) + + def __init__(self, s): + if self.version_class is None: + raise ValueError('Please specify a version class') + self._string = s = s.strip() + r = self.parse_requirement(s) + if not r: + raise ValueError('Not valid: %r' % s) + self.name = r.name + self.key = self.name.lower() # for case-insensitive comparisons + clist = [] + if r.constraints: + # import pdb; pdb.set_trace() + for op, s in r.constraints: + if s.endswith('.*'): + if op not in ('==', '!='): + raise ValueError('\'.*\' not allowed for ' + '%r constraints' % op) + # Could be a partial version (e.g. for '2.*') which + # won't parse as a version, so keep it as a string + vn, prefix = s[:-2], True + # Just to check that vn is a valid version + self.version_class(vn) + else: + # Should parse as a version, so we can create an + # instance for the comparison + vn, prefix = self.version_class(s), False + clist.append((op, vn, prefix)) + self._parts = tuple(clist) + + def match(self, version): + """ + Check if the provided version matches the constraints. + + :param version: The version to match against this instance. + :type version: String or :class:`Version` instance. + """ + if isinstance(version, string_types): + version = self.version_class(version) + for operator, constraint, prefix in self._parts: + f = self._operators.get(operator) + if isinstance(f, string_types): + f = getattr(self, f) + if not f: + msg = ('%r not implemented ' + 'for %s' % (operator, self.__class__.__name__)) + raise NotImplementedError(msg) + if not f(version, constraint, prefix): + return False + return True + + @property + def exact_version(self): + result = None + if len(self._parts) == 1 and self._parts[0][0] in ('==', '==='): + result = self._parts[0][1] + return result + + def _check_compatible(self, other): + if type(self) != type(other) or self.name != other.name: + raise TypeError('cannot compare %s and %s' % (self, other)) + + def __eq__(self, other): + self._check_compatible(other) + return self.key == other.key and self._parts == other._parts + + def __ne__(self, other): + return not self.__eq__(other) + + # See http://docs.python.org/reference/datamodel#object.__hash__ + def __hash__(self): + return hash(self.key) + hash(self._parts) + + def __repr__(self): + return "%s(%r)" % (self.__class__.__name__, self._string) + + def __str__(self): + return self._string + + +PEP440_VERSION_RE = re.compile(r'^v?(\d+!)?(\d+(\.\d+)*)((a|b|c|rc)(\d+))?' + r'(\.(post)(\d+))?(\.(dev)(\d+))?' + r'(\+([a-zA-Z\d]+(\.[a-zA-Z\d]+)?))?$') + + +def _pep_440_key(s): + s = s.strip() + m = PEP440_VERSION_RE.match(s) + if not m: + raise UnsupportedVersionError('Not a valid version: %s' % s) + groups = m.groups() + nums = tuple(int(v) for v in groups[1].split('.')) + while len(nums) > 1 and nums[-1] == 0: + nums = nums[:-1] + + if not groups[0]: + epoch = 0 + else: + epoch = int(groups[0]) + pre = groups[4:6] + post = groups[7:9] + dev = groups[10:12] + local = groups[13] + if pre == (None, None): + pre = () + else: + pre = pre[0], int(pre[1]) + if post == (None, None): + post = () + else: + post = post[0], int(post[1]) + if dev == (None, None): + dev = () + else: + dev = dev[0], int(dev[1]) + if local is None: + local = () + else: + parts = [] + for part in local.split('.'): + # to ensure that numeric compares as > lexicographic, avoid + # comparing them directly, but encode a tuple which ensures + # correct sorting + if part.isdigit(): + part = (1, int(part)) + else: + part = (0, part) + parts.append(part) + local = tuple(parts) + if not pre: + # either before pre-release, or final release and after + if not post and dev: + # before pre-release + pre = ('a', -1) # to sort before a0 + else: + pre = ('z',) # to sort after all pre-releases + # now look at the state of post and dev. + if not post: + post = ('_',) # sort before 'a' + if not dev: + dev = ('final',) + + #print('%s -> %s' % (s, m.groups())) + return epoch, nums, pre, post, dev, local + + +_normalized_key = _pep_440_key + + +class NormalizedVersion(Version): + """A rational version. + + Good: + 1.2 # equivalent to "1.2.0" + 1.2.0 + 1.2a1 + 1.2.3a2 + 1.2.3b1 + 1.2.3c1 + 1.2.3.4 + TODO: fill this out + + Bad: + 1 # minimum two numbers + 1.2a # release level must have a release serial + 1.2.3b + """ + def parse(self, s): + result = _normalized_key(s) + # _normalized_key loses trailing zeroes in the release + # clause, since that's needed to ensure that X.Y == X.Y.0 == X.Y.0.0 + # However, PEP 440 prefix matching needs it: for example, + # (~= 1.4.5.0) matches differently to (~= 1.4.5.0.0). + m = PEP440_VERSION_RE.match(s) # must succeed + groups = m.groups() + self._release_clause = tuple(int(v) for v in groups[1].split('.')) + return result + + PREREL_TAGS = set(['a', 'b', 'c', 'rc', 'dev']) + + @property + def is_prerelease(self): + return any(t[0] in self.PREREL_TAGS for t in self._parts if t) + + +def _match_prefix(x, y): + x = str(x) + y = str(y) + if x == y: + return True + if not x.startswith(y): + return False + n = len(y) + return x[n] == '.' + + +class NormalizedMatcher(Matcher): + version_class = NormalizedVersion + + # value is either a callable or the name of a method + _operators = { + '~=': '_match_compatible', + '<': '_match_lt', + '>': '_match_gt', + '<=': '_match_le', + '>=': '_match_ge', + '==': '_match_eq', + '===': '_match_arbitrary', + '!=': '_match_ne', + } + + def _adjust_local(self, version, constraint, prefix): + if prefix: + strip_local = '+' not in constraint and version._parts[-1] + else: + # both constraint and version are + # NormalizedVersion instances. + # If constraint does not have a local component, + # ensure the version doesn't, either. + strip_local = not constraint._parts[-1] and version._parts[-1] + if strip_local: + s = version._string.split('+', 1)[0] + version = self.version_class(s) + return version, constraint + + def _match_lt(self, version, constraint, prefix): + version, constraint = self._adjust_local(version, constraint, prefix) + if version >= constraint: + return False + release_clause = constraint._release_clause + pfx = '.'.join([str(i) for i in release_clause]) + return not _match_prefix(version, pfx) + + def _match_gt(self, version, constraint, prefix): + version, constraint = self._adjust_local(version, constraint, prefix) + if version <= constraint: + return False + release_clause = constraint._release_clause + pfx = '.'.join([str(i) for i in release_clause]) + return not _match_prefix(version, pfx) + + def _match_le(self, version, constraint, prefix): + version, constraint = self._adjust_local(version, constraint, prefix) + return version <= constraint + + def _match_ge(self, version, constraint, prefix): + version, constraint = self._adjust_local(version, constraint, prefix) + return version >= constraint + + def _match_eq(self, version, constraint, prefix): + version, constraint = self._adjust_local(version, constraint, prefix) + if not prefix: + result = (version == constraint) + else: + result = _match_prefix(version, constraint) + return result + + def _match_arbitrary(self, version, constraint, prefix): + return str(version) == str(constraint) + + def _match_ne(self, version, constraint, prefix): + version, constraint = self._adjust_local(version, constraint, prefix) + if not prefix: + result = (version != constraint) + else: + result = not _match_prefix(version, constraint) + return result + + def _match_compatible(self, version, constraint, prefix): + version, constraint = self._adjust_local(version, constraint, prefix) + if version == constraint: + return True + if version < constraint: + return False +# if not prefix: +# return True + release_clause = constraint._release_clause + if len(release_clause) > 1: + release_clause = release_clause[:-1] + pfx = '.'.join([str(i) for i in release_clause]) + return _match_prefix(version, pfx) + +_REPLACEMENTS = ( + (re.compile('[.+-]$'), ''), # remove trailing puncts + (re.compile(r'^[.](\d)'), r'0.\1'), # .N -> 0.N at start + (re.compile('^[.-]'), ''), # remove leading puncts + (re.compile(r'^\((.*)\)$'), r'\1'), # remove parentheses + (re.compile(r'^v(ersion)?\s*(\d+)'), r'\2'), # remove leading v(ersion) + (re.compile(r'^r(ev)?\s*(\d+)'), r'\2'), # remove leading v(ersion) + (re.compile('[.]{2,}'), '.'), # multiple runs of '.' + (re.compile(r'\b(alfa|apha)\b'), 'alpha'), # misspelt alpha + (re.compile(r'\b(pre-alpha|prealpha)\b'), + 'pre.alpha'), # standardise + (re.compile(r'\(beta\)$'), 'beta'), # remove parentheses +) + +_SUFFIX_REPLACEMENTS = ( + (re.compile('^[:~._+-]+'), ''), # remove leading puncts + (re.compile('[,*")([\\]]'), ''), # remove unwanted chars + (re.compile('[~:+_ -]'), '.'), # replace illegal chars + (re.compile('[.]{2,}'), '.'), # multiple runs of '.' + (re.compile(r'\.$'), ''), # trailing '.' +) + +_NUMERIC_PREFIX = re.compile(r'(\d+(\.\d+)*)') + + +def _suggest_semantic_version(s): + """ + Try to suggest a semantic form for a version for which + _suggest_normalized_version couldn't come up with anything. + """ + result = s.strip().lower() + for pat, repl in _REPLACEMENTS: + result = pat.sub(repl, result) + if not result: + result = '0.0.0' + + # Now look for numeric prefix, and separate it out from + # the rest. + #import pdb; pdb.set_trace() + m = _NUMERIC_PREFIX.match(result) + if not m: + prefix = '0.0.0' + suffix = result + else: + prefix = m.groups()[0].split('.') + prefix = [int(i) for i in prefix] + while len(prefix) < 3: + prefix.append(0) + if len(prefix) == 3: + suffix = result[m.end():] + else: + suffix = '.'.join([str(i) for i in prefix[3:]]) + result[m.end():] + prefix = prefix[:3] + prefix = '.'.join([str(i) for i in prefix]) + suffix = suffix.strip() + if suffix: + #import pdb; pdb.set_trace() + # massage the suffix. + for pat, repl in _SUFFIX_REPLACEMENTS: + suffix = pat.sub(repl, suffix) + + if not suffix: + result = prefix + else: + sep = '-' if 'dev' in suffix else '+' + result = prefix + sep + suffix + if not is_semver(result): + result = None + return result + + +def _suggest_normalized_version(s): + """Suggest a normalized version close to the given version string. + + If you have a version string that isn't rational (i.e. NormalizedVersion + doesn't like it) then you might be able to get an equivalent (or close) + rational version from this function. + + This does a number of simple normalizations to the given string, based + on observation of versions currently in use on PyPI. Given a dump of + those version during PyCon 2009, 4287 of them: + - 2312 (53.93%) match NormalizedVersion without change + with the automatic suggestion + - 3474 (81.04%) match when using this suggestion method + + @param s {str} An irrational version string. + @returns A rational version string, or None, if couldn't determine one. + """ + try: + _normalized_key(s) + return s # already rational + except UnsupportedVersionError: + pass + + rs = s.lower() + + # part of this could use maketrans + for orig, repl in (('-alpha', 'a'), ('-beta', 'b'), ('alpha', 'a'), + ('beta', 'b'), ('rc', 'c'), ('-final', ''), + ('-pre', 'c'), + ('-release', ''), ('.release', ''), ('-stable', ''), + ('+', '.'), ('_', '.'), (' ', ''), ('.final', ''), + ('final', '')): + rs = rs.replace(orig, repl) + + # if something ends with dev or pre, we add a 0 + rs = re.sub(r"pre$", r"pre0", rs) + rs = re.sub(r"dev$", r"dev0", rs) + + # if we have something like "b-2" or "a.2" at the end of the + # version, that is probably beta, alpha, etc + # let's remove the dash or dot + rs = re.sub(r"([abc]|rc)[\-\.](\d+)$", r"\1\2", rs) + + # 1.0-dev-r371 -> 1.0.dev371 + # 0.1-dev-r79 -> 0.1.dev79 + rs = re.sub(r"[\-\.](dev)[\-\.]?r?(\d+)$", r".\1\2", rs) + + # Clean: 2.0.a.3, 2.0.b1, 0.9.0~c1 + rs = re.sub(r"[.~]?([abc])\.?", r"\1", rs) + + # Clean: v0.3, v1.0 + if rs.startswith('v'): + rs = rs[1:] + + # Clean leading '0's on numbers. + #TODO: unintended side-effect on, e.g., "2003.05.09" + # PyPI stats: 77 (~2%) better + rs = re.sub(r"\b0+(\d+)(?!\d)", r"\1", rs) + + # Clean a/b/c with no version. E.g. "1.0a" -> "1.0a0". Setuptools infers + # zero. + # PyPI stats: 245 (7.56%) better + rs = re.sub(r"(\d+[abc])$", r"\g<1>0", rs) + + # the 'dev-rNNN' tag is a dev tag + rs = re.sub(r"\.?(dev-r|dev\.r)\.?(\d+)$", r".dev\2", rs) + + # clean the - when used as a pre delimiter + rs = re.sub(r"-(a|b|c)(\d+)$", r"\1\2", rs) + + # a terminal "dev" or "devel" can be changed into ".dev0" + rs = re.sub(r"[\.\-](dev|devel)$", r".dev0", rs) + + # a terminal "dev" can be changed into ".dev0" + rs = re.sub(r"(?![\.\-])dev$", r".dev0", rs) + + # a terminal "final" or "stable" can be removed + rs = re.sub(r"(final|stable)$", "", rs) + + # The 'r' and the '-' tags are post release tags + # 0.4a1.r10 -> 0.4a1.post10 + # 0.9.33-17222 -> 0.9.33.post17222 + # 0.9.33-r17222 -> 0.9.33.post17222 + rs = re.sub(r"\.?(r|-|-r)\.?(\d+)$", r".post\2", rs) + + # Clean 'r' instead of 'dev' usage: + # 0.9.33+r17222 -> 0.9.33.dev17222 + # 1.0dev123 -> 1.0.dev123 + # 1.0.git123 -> 1.0.dev123 + # 1.0.bzr123 -> 1.0.dev123 + # 0.1a0dev.123 -> 0.1a0.dev123 + # PyPI stats: ~150 (~4%) better + rs = re.sub(r"\.?(dev|git|bzr)\.?(\d+)$", r".dev\2", rs) + + # Clean '.pre' (normalized from '-pre' above) instead of 'c' usage: + # 0.2.pre1 -> 0.2c1 + # 0.2-c1 -> 0.2c1 + # 1.0preview123 -> 1.0c123 + # PyPI stats: ~21 (0.62%) better + rs = re.sub(r"\.?(pre|preview|-c)(\d+)$", r"c\g<2>", rs) + + # Tcl/Tk uses "px" for their post release markers + rs = re.sub(r"p(\d+)$", r".post\1", rs) + + try: + _normalized_key(rs) + except UnsupportedVersionError: + rs = None + return rs + +# +# Legacy version processing (distribute-compatible) +# + +_VERSION_PART = re.compile(r'([a-z]+|\d+|[\.-])', re.I) +_VERSION_REPLACE = { + 'pre': 'c', + 'preview': 'c', + '-': 'final-', + 'rc': 'c', + 'dev': '@', + '': None, + '.': None, +} + + +def _legacy_key(s): + def get_parts(s): + result = [] + for p in _VERSION_PART.split(s.lower()): + p = _VERSION_REPLACE.get(p, p) + if p: + if '0' <= p[:1] <= '9': + p = p.zfill(8) + else: + p = '*' + p + result.append(p) + result.append('*final') + return result + + result = [] + for p in get_parts(s): + if p.startswith('*'): + if p < '*final': + while result and result[-1] == '*final-': + result.pop() + while result and result[-1] == '00000000': + result.pop() + result.append(p) + return tuple(result) + + +class LegacyVersion(Version): + def parse(self, s): + return _legacy_key(s) + + @property + def is_prerelease(self): + result = False + for x in self._parts: + if (isinstance(x, string_types) and x.startswith('*') and + x < '*final'): + result = True + break + return result + + +class LegacyMatcher(Matcher): + version_class = LegacyVersion + + _operators = dict(Matcher._operators) + _operators['~='] = '_match_compatible' + + numeric_re = re.compile(r'^(\d+(\.\d+)*)') + + def _match_compatible(self, version, constraint, prefix): + if version < constraint: + return False + m = self.numeric_re.match(str(constraint)) + if not m: + logger.warning('Cannot compute compatible match for version %s ' + ' and constraint %s', version, constraint) + return True + s = m.groups()[0] + if '.' in s: + s = s.rsplit('.', 1)[0] + return _match_prefix(version, s) + +# +# Semantic versioning +# + +_SEMVER_RE = re.compile(r'^(\d+)\.(\d+)\.(\d+)' + r'(-[a-z0-9]+(\.[a-z0-9-]+)*)?' + r'(\+[a-z0-9]+(\.[a-z0-9-]+)*)?$', re.I) + + +def is_semver(s): + return _SEMVER_RE.match(s) + + +def _semantic_key(s): + def make_tuple(s, absent): + if s is None: + result = (absent,) + else: + parts = s[1:].split('.') + # We can't compare ints and strings on Python 3, so fudge it + # by zero-filling numeric values so simulate a numeric comparison + result = tuple([p.zfill(8) if p.isdigit() else p for p in parts]) + return result + + m = is_semver(s) + if not m: + raise UnsupportedVersionError(s) + groups = m.groups() + major, minor, patch = [int(i) for i in groups[:3]] + # choose the '|' and '*' so that versions sort correctly + pre, build = make_tuple(groups[3], '|'), make_tuple(groups[5], '*') + return (major, minor, patch), pre, build + + +class SemanticVersion(Version): + def parse(self, s): + return _semantic_key(s) + + @property + def is_prerelease(self): + return self._parts[1][0] != '|' + + +class SemanticMatcher(Matcher): + version_class = SemanticVersion + + +class VersionScheme(object): + def __init__(self, key, matcher, suggester=None): + self.key = key + self.matcher = matcher + self.suggester = suggester + + def is_valid_version(self, s): + try: + self.matcher.version_class(s) + result = True + except UnsupportedVersionError: + result = False + return result + + def is_valid_matcher(self, s): + try: + self.matcher(s) + result = True + except UnsupportedVersionError: + result = False + return result + + def is_valid_constraint_list(self, s): + """ + Used for processing some metadata fields + """ + return self.is_valid_matcher('dummy_name (%s)' % s) + + def suggest(self, s): + if self.suggester is None: + result = None + else: + result = self.suggester(s) + return result + +_SCHEMES = { + 'normalized': VersionScheme(_normalized_key, NormalizedMatcher, + _suggest_normalized_version), + 'legacy': VersionScheme(_legacy_key, LegacyMatcher, lambda self, s: s), + 'semantic': VersionScheme(_semantic_key, SemanticMatcher, + _suggest_semantic_version), +} + +_SCHEMES['default'] = _SCHEMES['normalized'] + + +def get_scheme(name): + if name not in _SCHEMES: + raise ValueError('unknown scheme name: %r' % name) + return _SCHEMES[name] diff --git a/venv/Lib/site-packages/pip/_vendor/distlib/w32.exe b/venv/Lib/site-packages/pip/_vendor/distlib/w32.exe new file mode 100644 index 0000000000000000000000000000000000000000..e6439e9e45897365d5ac6a85a46864c158a225fd GIT binary patch literal 90112 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�gPVRVBXt_FM7e4<}XM;HRH{62JZSn^<*L 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 OB+yBqlfeHwf&T)jA)JE% literal 0 HcmV?d00001 diff --git a/venv/Lib/site-packages/pip/_vendor/distlib/w64.exe b/venv/Lib/site-packages/pip/_vendor/distlib/w64.exe new file mode 100644 index 0000000000000000000000000000000000000000..46139dbf9400b7bc0b64e6756ce17b4eb5fd7436 GIT binary patch literal 99840 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[^-]+) +-(?P\d+[^-]*) +(-(?P\d+[^-]*))? +-(?P\w+\d+(\.\w+\d+)*) +-(?P\w+) +-(?P\w+(\.\w+)*) +\.whl$ +''', re.IGNORECASE | re.VERBOSE) + +NAME_VERSION_RE = re.compile(r''' +(?P[^-]+) +-(?P\d+[^-]*) +(-(?P\d+[^-]*))?$ +''', re.IGNORECASE | re.VERBOSE) + +SHEBANG_RE = re.compile(br'\s*#![^\r\n]*') +SHEBANG_DETAIL_RE = re.compile(br'^(\s*#!("[^"]+"|\S+))\s+(.*)$') +SHEBANG_PYTHON = b'#!python' +SHEBANG_PYTHONW = b'#!pythonw' + +if os.sep == '/': + to_posix = lambda o: o +else: + to_posix = lambda o: o.replace(os.sep, '/') + + +class Mounter(object): + def __init__(self): + self.impure_wheels = {} + self.libs = {} + + def add(self, pathname, extensions): + self.impure_wheels[pathname] = extensions + self.libs.update(extensions) + + def remove(self, pathname): + extensions = self.impure_wheels.pop(pathname) + for k, v in extensions: + if k in self.libs: + del self.libs[k] + + def find_module(self, fullname, path=None): + if fullname in self.libs: + result = self + else: + result = None + return result + + def load_module(self, fullname): + if fullname in sys.modules: + result = sys.modules[fullname] + else: + if fullname not in self.libs: + raise ImportError('unable to find extension for %s' % fullname) + result = imp.load_dynamic(fullname, self.libs[fullname]) + result.__loader__ = self + parts = fullname.rsplit('.', 1) + if len(parts) > 1: + result.__package__ = parts[0] + return result + +_hook = Mounter() + + +class Wheel(object): + """ + Class to build and install from Wheel files (PEP 427). + """ + + wheel_version = (1, 1) + hash_kind = 'sha256' + + def __init__(self, filename=None, sign=False, verify=False): + """ + Initialise an instance using a (valid) filename. + """ + self.sign = sign + self.should_verify = verify + self.buildver = '' + self.pyver = [PYVER] + self.abi = ['none'] + self.arch = ['any'] + self.dirname = os.getcwd() + if filename is None: + self.name = 'dummy' + self.version = '0.1' + self._filename = self.filename + else: + m = NAME_VERSION_RE.match(filename) + if m: + info = m.groupdict('') + self.name = info['nm'] + # Reinstate the local version separator + self.version = info['vn'].replace('_', '-') + self.buildver = info['bn'] + self._filename = self.filename + else: + dirname, filename = os.path.split(filename) + m = FILENAME_RE.match(filename) + if not m: + raise DistlibException('Invalid name or ' + 'filename: %r' % filename) + if dirname: + self.dirname = os.path.abspath(dirname) + self._filename = filename + info = m.groupdict('') + self.name = info['nm'] + self.version = info['vn'] + self.buildver = info['bn'] + self.pyver = info['py'].split('.') + self.abi = info['bi'].split('.') + self.arch = info['ar'].split('.') + + @property + def filename(self): + """ + Build and return a filename from the various components. + """ + if self.buildver: + buildver = '-' + self.buildver + else: + buildver = '' + pyver = '.'.join(self.pyver) + abi = '.'.join(self.abi) + arch = '.'.join(self.arch) + # replace - with _ as a local version separator + version = self.version.replace('-', '_') + return '%s-%s%s-%s-%s-%s.whl' % (self.name, version, buildver, + pyver, abi, arch) + + @property + def exists(self): + path = os.path.join(self.dirname, self.filename) + return os.path.isfile(path) + + @property + def tags(self): + for pyver in self.pyver: + for abi in self.abi: + for arch in self.arch: + yield pyver, abi, arch + + @cached_property + def metadata(self): + pathname = os.path.join(self.dirname, self.filename) + name_ver = '%s-%s' % (self.name, self.version) + info_dir = '%s.dist-info' % name_ver + wrapper = codecs.getreader('utf-8') + with ZipFile(pathname, 'r') as zf: + wheel_metadata = self.get_wheel_metadata(zf) + wv = wheel_metadata['Wheel-Version'].split('.', 1) + file_version = tuple([int(i) for i in wv]) + # if file_version < (1, 1): + # fns = [WHEEL_METADATA_FILENAME, METADATA_FILENAME, + # LEGACY_METADATA_FILENAME] + # else: + # fns = [WHEEL_METADATA_FILENAME, METADATA_FILENAME] + fns = [WHEEL_METADATA_FILENAME, LEGACY_METADATA_FILENAME] + result = None + for fn in fns: + try: + metadata_filename = posixpath.join(info_dir, fn) + with zf.open(metadata_filename) as bf: + wf = wrapper(bf) + result = Metadata(fileobj=wf) + if result: + break + except KeyError: + pass + if not result: + raise ValueError('Invalid wheel, because metadata is ' + 'missing: looked in %s' % ', '.join(fns)) + return result + + def get_wheel_metadata(self, zf): + name_ver = '%s-%s' % (self.name, self.version) + info_dir = '%s.dist-info' % name_ver + metadata_filename = posixpath.join(info_dir, 'WHEEL') + with zf.open(metadata_filename) as bf: + wf = codecs.getreader('utf-8')(bf) + message = message_from_file(wf) + return dict(message) + + @cached_property + def info(self): + pathname = os.path.join(self.dirname, self.filename) + with ZipFile(pathname, 'r') as zf: + result = self.get_wheel_metadata(zf) + return result + + def process_shebang(self, data): + m = SHEBANG_RE.match(data) + if m: + end = m.end() + shebang, data_after_shebang = data[:end], data[end:] + # Preserve any arguments after the interpreter + if b'pythonw' in shebang.lower(): + shebang_python = SHEBANG_PYTHONW + else: + shebang_python = SHEBANG_PYTHON + m = SHEBANG_DETAIL_RE.match(shebang) + if m: + args = b' ' + m.groups()[-1] + else: + args = b'' + shebang = shebang_python + args + data = shebang + data_after_shebang + else: + cr = data.find(b'\r') + lf = data.find(b'\n') + if cr < 0 or cr > lf: + term = b'\n' + else: + if data[cr:cr + 2] == b'\r\n': + term = b'\r\n' + else: + term = b'\r' + data = SHEBANG_PYTHON + term + data + return data + + def get_hash(self, data, hash_kind=None): + if hash_kind is None: + hash_kind = self.hash_kind + try: + hasher = getattr(hashlib, hash_kind) + except AttributeError: + raise DistlibException('Unsupported hash algorithm: %r' % hash_kind) + result = hasher(data).digest() + result = base64.urlsafe_b64encode(result).rstrip(b'=').decode('ascii') + return hash_kind, result + + def write_record(self, records, record_path, base): + records = list(records) # make a copy, as mutated + p = to_posix(os.path.relpath(record_path, base)) + records.append((p, '', '')) + with CSVWriter(record_path) as writer: + for row in records: + writer.writerow(row) + + def write_records(self, info, libdir, archive_paths): + records = [] + distinfo, info_dir = info + hasher = getattr(hashlib, self.hash_kind) + for ap, p in archive_paths: + with open(p, 'rb') as f: + data = f.read() + digest = '%s=%s' % self.get_hash(data) + size = os.path.getsize(p) + records.append((ap, digest, size)) + + p = os.path.join(distinfo, 'RECORD') + self.write_record(records, p, libdir) + ap = to_posix(os.path.join(info_dir, 'RECORD')) + archive_paths.append((ap, p)) + + def build_zip(self, pathname, archive_paths): + with ZipFile(pathname, 'w', zipfile.ZIP_DEFLATED) as zf: + for ap, p in archive_paths: + logger.debug('Wrote %s to %s in wheel', p, ap) + zf.write(p, ap) + + def build(self, paths, tags=None, wheel_version=None): + """ + Build a wheel from files in specified paths, and use any specified tags + when determining the name of the wheel. + """ + if tags is None: + tags = {} + + libkey = list(filter(lambda o: o in paths, ('purelib', 'platlib')))[0] + if libkey == 'platlib': + is_pure = 'false' + default_pyver = [IMPVER] + default_abi = [ABI] + default_arch = [ARCH] + else: + is_pure = 'true' + default_pyver = [PYVER] + default_abi = ['none'] + default_arch = ['any'] + + self.pyver = tags.get('pyver', default_pyver) + self.abi = tags.get('abi', default_abi) + self.arch = tags.get('arch', default_arch) + + libdir = paths[libkey] + + name_ver = '%s-%s' % (self.name, self.version) + data_dir = '%s.data' % name_ver + info_dir = '%s.dist-info' % name_ver + + archive_paths = [] + + # First, stuff which is not in site-packages + for key in ('data', 'headers', 'scripts'): + if key not in paths: + continue + path = paths[key] + if os.path.isdir(path): + for root, dirs, files in os.walk(path): + for fn in files: + p = fsdecode(os.path.join(root, fn)) + rp = os.path.relpath(p, path) + ap = to_posix(os.path.join(data_dir, key, rp)) + archive_paths.append((ap, p)) + if key == 'scripts' and not p.endswith('.exe'): + with open(p, 'rb') as f: + data = f.read() + data = self.process_shebang(data) + with open(p, 'wb') as f: + f.write(data) + + # Now, stuff which is in site-packages, other than the + # distinfo stuff. + path = libdir + distinfo = None + for root, dirs, files in os.walk(path): + if root == path: + # At the top level only, save distinfo for later + # and skip it for now + for i, dn in enumerate(dirs): + dn = fsdecode(dn) + if dn.endswith('.dist-info'): + distinfo = os.path.join(root, dn) + del dirs[i] + break + assert distinfo, '.dist-info directory expected, not found' + + for fn in files: + # comment out next suite to leave .pyc files in + if fsdecode(fn).endswith(('.pyc', '.pyo')): + continue + p = os.path.join(root, fn) + rp = to_posix(os.path.relpath(p, path)) + archive_paths.append((rp, p)) + + # Now distinfo. Assumed to be flat, i.e. os.listdir is enough. + files = os.listdir(distinfo) + for fn in files: + if fn not in ('RECORD', 'INSTALLER', 'SHARED', 'WHEEL'): + p = fsdecode(os.path.join(distinfo, fn)) + ap = to_posix(os.path.join(info_dir, fn)) + archive_paths.append((ap, p)) + + wheel_metadata = [ + 'Wheel-Version: %d.%d' % (wheel_version or self.wheel_version), + 'Generator: distlib %s' % __version__, + 'Root-Is-Purelib: %s' % is_pure, + ] + for pyver, abi, arch in self.tags: + wheel_metadata.append('Tag: %s-%s-%s' % (pyver, abi, arch)) + p = os.path.join(distinfo, 'WHEEL') + with open(p, 'w') as f: + f.write('\n'.join(wheel_metadata)) + ap = to_posix(os.path.join(info_dir, 'WHEEL')) + archive_paths.append((ap, p)) + + # sort the entries by archive path. Not needed by any spec, but it + # keeps the archive listing and RECORD tidier than they would otherwise + # be. Use the number of path segments to keep directory entries together, + # and keep the dist-info stuff at the end. + def sorter(t): + ap = t[0] + n = ap.count('/') + if '.dist-info' in ap: + n += 10000 + return (n, ap) + archive_paths = sorted(archive_paths, key=sorter) + + # Now, at last, RECORD. + # Paths in here are archive paths - nothing else makes sense. + self.write_records((distinfo, info_dir), libdir, archive_paths) + # Now, ready to build the zip file + pathname = os.path.join(self.dirname, self.filename) + self.build_zip(pathname, archive_paths) + return pathname + + def skip_entry(self, arcname): + """ + Determine whether an archive entry should be skipped when verifying + or installing. + """ + # The signature file won't be in RECORD, + # and we don't currently don't do anything with it + # We also skip directories, as they won't be in RECORD + # either. See: + # + # https://github.com/pypa/wheel/issues/294 + # https://github.com/pypa/wheel/issues/287 + # https://github.com/pypa/wheel/pull/289 + # + return arcname.endswith(('/', '/RECORD.jws')) + + def install(self, paths, maker, **kwargs): + """ + Install a wheel to the specified paths. If kwarg ``warner`` is + specified, it should be a callable, which will be called with two + tuples indicating the wheel version of this software and the wheel + version in the file, if there is a discrepancy in the versions. + This can be used to issue any warnings to raise any exceptions. + If kwarg ``lib_only`` is True, only the purelib/platlib files are + installed, and the headers, scripts, data and dist-info metadata are + not written. If kwarg ``bytecode_hashed_invalidation`` is True, written + bytecode will try to use file-hash based invalidation (PEP-552) on + supported interpreter versions (CPython 2.7+). + + The return value is a :class:`InstalledDistribution` instance unless + ``options.lib_only`` is True, in which case the return value is ``None``. + """ + + dry_run = maker.dry_run + warner = kwargs.get('warner') + lib_only = kwargs.get('lib_only', False) + bc_hashed_invalidation = kwargs.get('bytecode_hashed_invalidation', False) + + pathname = os.path.join(self.dirname, self.filename) + name_ver = '%s-%s' % (self.name, self.version) + data_dir = '%s.data' % name_ver + info_dir = '%s.dist-info' % name_ver + + metadata_name = posixpath.join(info_dir, LEGACY_METADATA_FILENAME) + wheel_metadata_name = posixpath.join(info_dir, 'WHEEL') + record_name = posixpath.join(info_dir, 'RECORD') + + wrapper = codecs.getreader('utf-8') + + with ZipFile(pathname, 'r') as zf: + with zf.open(wheel_metadata_name) as bwf: + wf = wrapper(bwf) + message = message_from_file(wf) + wv = message['Wheel-Version'].split('.', 1) + file_version = tuple([int(i) for i in wv]) + if (file_version != self.wheel_version) and warner: + warner(self.wheel_version, file_version) + + if message['Root-Is-Purelib'] == 'true': + libdir = paths['purelib'] + else: + libdir = paths['platlib'] + + records = {} + with zf.open(record_name) as bf: + with CSVReader(stream=bf) as reader: + for row in reader: + p = row[0] + records[p] = row + + data_pfx = posixpath.join(data_dir, '') + info_pfx = posixpath.join(info_dir, '') + script_pfx = posixpath.join(data_dir, 'scripts', '') + + # make a new instance rather than a copy of maker's, + # as we mutate it + fileop = FileOperator(dry_run=dry_run) + fileop.record = True # so we can rollback if needed + + bc = not sys.dont_write_bytecode # Double negatives. Lovely! + + outfiles = [] # for RECORD writing + + # for script copying/shebang processing + workdir = tempfile.mkdtemp() + # set target dir later + # we default add_launchers to False, as the + # Python Launcher should be used instead + maker.source_dir = workdir + maker.target_dir = None + try: + for zinfo in zf.infolist(): + arcname = zinfo.filename + if isinstance(arcname, text_type): + u_arcname = arcname + else: + u_arcname = arcname.decode('utf-8') + if self.skip_entry(u_arcname): + continue + row = records[u_arcname] + if row[2] and str(zinfo.file_size) != row[2]: + raise DistlibException('size mismatch for ' + '%s' % u_arcname) + if row[1]: + kind, value = row[1].split('=', 1) + with zf.open(arcname) as bf: + data = bf.read() + _, digest = self.get_hash(data, kind) + if digest != value: + raise DistlibException('digest mismatch for ' + '%s' % arcname) + + if lib_only and u_arcname.startswith((info_pfx, data_pfx)): + logger.debug('lib_only: skipping %s', u_arcname) + continue + is_script = (u_arcname.startswith(script_pfx) + and not u_arcname.endswith('.exe')) + + if u_arcname.startswith(data_pfx): + _, where, rp = u_arcname.split('/', 2) + outfile = os.path.join(paths[where], convert_path(rp)) + else: + # meant for site-packages. + if u_arcname in (wheel_metadata_name, record_name): + continue + outfile = os.path.join(libdir, convert_path(u_arcname)) + if not is_script: + with zf.open(arcname) as bf: + fileop.copy_stream(bf, outfile) + outfiles.append(outfile) + # Double check the digest of the written file + if not dry_run and row[1]: + with open(outfile, 'rb') as bf: + data = bf.read() + _, newdigest = self.get_hash(data, kind) + if newdigest != digest: + raise DistlibException('digest mismatch ' + 'on write for ' + '%s' % outfile) + if bc and outfile.endswith('.py'): + try: + pyc = fileop.byte_compile(outfile, + hashed_invalidation=bc_hashed_invalidation) + outfiles.append(pyc) + except Exception: + # Don't give up if byte-compilation fails, + # but log it and perhaps warn the user + logger.warning('Byte-compilation failed', + exc_info=True) + else: + fn = os.path.basename(convert_path(arcname)) + workname = os.path.join(workdir, fn) + with zf.open(arcname) as bf: + fileop.copy_stream(bf, workname) + + dn, fn = os.path.split(outfile) + maker.target_dir = dn + filenames = maker.make(fn) + fileop.set_executable_mode(filenames) + outfiles.extend(filenames) + + if lib_only: + logger.debug('lib_only: returning None') + dist = None + else: + # Generate scripts + + # Try to get pydist.json so we can see if there are + # any commands to generate. If this fails (e.g. because + # of a legacy wheel), log a warning but don't give up. + commands = None + file_version = self.info['Wheel-Version'] + if file_version == '1.0': + # Use legacy info + ep = posixpath.join(info_dir, 'entry_points.txt') + try: + with zf.open(ep) as bwf: + epdata = read_exports(bwf) + commands = {} + for key in ('console', 'gui'): + k = '%s_scripts' % key + if k in epdata: + commands['wrap_%s' % key] = d = {} + for v in epdata[k].values(): + s = '%s:%s' % (v.prefix, v.suffix) + if v.flags: + s += ' [%s]' % ','.join(v.flags) + d[v.name] = s + except Exception: + logger.warning('Unable to read legacy script ' + 'metadata, so cannot generate ' + 'scripts') + else: + try: + with zf.open(metadata_name) as bwf: + wf = wrapper(bwf) + commands = json.load(wf).get('extensions') + if commands: + commands = commands.get('python.commands') + except Exception: + logger.warning('Unable to read JSON metadata, so ' + 'cannot generate scripts') + if commands: + console_scripts = commands.get('wrap_console', {}) + gui_scripts = commands.get('wrap_gui', {}) + if console_scripts or gui_scripts: + script_dir = paths.get('scripts', '') + if not os.path.isdir(script_dir): + raise ValueError('Valid script path not ' + 'specified') + maker.target_dir = script_dir + for k, v in console_scripts.items(): + script = '%s = %s' % (k, v) + filenames = maker.make(script) + fileop.set_executable_mode(filenames) + + if gui_scripts: + options = {'gui': True } + for k, v in gui_scripts.items(): + script = '%s = %s' % (k, v) + filenames = maker.make(script, options) + fileop.set_executable_mode(filenames) + + p = os.path.join(libdir, info_dir) + dist = InstalledDistribution(p) + + # Write SHARED + paths = dict(paths) # don't change passed in dict + del paths['purelib'] + del paths['platlib'] + paths['lib'] = libdir + p = dist.write_shared_locations(paths, dry_run) + if p: + outfiles.append(p) + + # Write RECORD + dist.write_installed_files(outfiles, paths['prefix'], + dry_run) + return dist + except Exception: # pragma: no cover + logger.exception('installation failed.') + fileop.rollback() + raise + finally: + shutil.rmtree(workdir) + + def _get_dylib_cache(self): + global cache + if cache is None: + # Use native string to avoid issues on 2.x: see Python #20140. + base = os.path.join(get_cache_base(), str('dylib-cache'), + '%s.%s' % sys.version_info[:2]) + cache = Cache(base) + return cache + + def _get_extensions(self): + pathname = os.path.join(self.dirname, self.filename) + name_ver = '%s-%s' % (self.name, self.version) + info_dir = '%s.dist-info' % name_ver + arcname = posixpath.join(info_dir, 'EXTENSIONS') + wrapper = codecs.getreader('utf-8') + result = [] + with ZipFile(pathname, 'r') as zf: + try: + with zf.open(arcname) as bf: + wf = wrapper(bf) + extensions = json.load(wf) + cache = self._get_dylib_cache() + prefix = cache.prefix_to_dir(pathname) + cache_base = os.path.join(cache.base, prefix) + if not os.path.isdir(cache_base): + os.makedirs(cache_base) + for name, relpath in extensions.items(): + dest = os.path.join(cache_base, convert_path(relpath)) + if not os.path.exists(dest): + extract = True + else: + file_time = os.stat(dest).st_mtime + file_time = datetime.datetime.fromtimestamp(file_time) + info = zf.getinfo(relpath) + wheel_time = datetime.datetime(*info.date_time) + extract = wheel_time > file_time + if extract: + zf.extract(relpath, cache_base) + result.append((name, dest)) + except KeyError: + pass + return result + + def is_compatible(self): + """ + Determine if a wheel is compatible with the running system. + """ + return is_compatible(self) + + def is_mountable(self): + """ + Determine if a wheel is asserted as mountable by its metadata. + """ + return True # for now - metadata details TBD + + def mount(self, append=False): + pathname = os.path.abspath(os.path.join(self.dirname, self.filename)) + if not self.is_compatible(): + msg = 'Wheel %s not compatible with this Python.' % pathname + raise DistlibException(msg) + if not self.is_mountable(): + msg = 'Wheel %s is marked as not mountable.' % pathname + raise DistlibException(msg) + if pathname in sys.path: + logger.debug('%s already in path', pathname) + else: + if append: + sys.path.append(pathname) + else: + sys.path.insert(0, pathname) + extensions = self._get_extensions() + if extensions: + if _hook not in sys.meta_path: + sys.meta_path.append(_hook) + _hook.add(pathname, extensions) + + def unmount(self): + pathname = os.path.abspath(os.path.join(self.dirname, self.filename)) + if pathname not in sys.path: + logger.debug('%s not in path', pathname) + else: + sys.path.remove(pathname) + if pathname in _hook.impure_wheels: + _hook.remove(pathname) + if not _hook.impure_wheels: + if _hook in sys.meta_path: + sys.meta_path.remove(_hook) + + def verify(self): + pathname = os.path.join(self.dirname, self.filename) + name_ver = '%s-%s' % (self.name, self.version) + data_dir = '%s.data' % name_ver + info_dir = '%s.dist-info' % name_ver + + metadata_name = posixpath.join(info_dir, LEGACY_METADATA_FILENAME) + wheel_metadata_name = posixpath.join(info_dir, 'WHEEL') + record_name = posixpath.join(info_dir, 'RECORD') + + wrapper = codecs.getreader('utf-8') + + with ZipFile(pathname, 'r') as zf: + with zf.open(wheel_metadata_name) as bwf: + wf = wrapper(bwf) + message = message_from_file(wf) + wv = message['Wheel-Version'].split('.', 1) + file_version = tuple([int(i) for i in wv]) + # TODO version verification + + records = {} + with zf.open(record_name) as bf: + with CSVReader(stream=bf) as reader: + for row in reader: + p = row[0] + records[p] = row + + for zinfo in zf.infolist(): + arcname = zinfo.filename + if isinstance(arcname, text_type): + u_arcname = arcname + else: + u_arcname = arcname.decode('utf-8') + # See issue #115: some wheels have .. in their entries, but + # in the filename ... e.g. __main__..py ! So the check is + # updated to look for .. in the directory portions + p = u_arcname.split('/') + if '..' in p: + raise DistlibException('invalid entry in ' + 'wheel: %r' % u_arcname) + + if self.skip_entry(u_arcname): + continue + row = records[u_arcname] + if row[2] and str(zinfo.file_size) != row[2]: + raise DistlibException('size mismatch for ' + '%s' % u_arcname) + if row[1]: + kind, value = row[1].split('=', 1) + with zf.open(arcname) as bf: + data = bf.read() + _, digest = self.get_hash(data, kind) + if digest != value: + raise DistlibException('digest mismatch for ' + '%s' % arcname) + + def update(self, modifier, dest_dir=None, **kwargs): + """ + Update the contents of a wheel in a generic way. The modifier should + be a callable which expects a dictionary argument: its keys are + archive-entry paths, and its values are absolute filesystem paths + where the contents the corresponding archive entries can be found. The + modifier is free to change the contents of the files pointed to, add + new entries and remove entries, before returning. This method will + extract the entire contents of the wheel to a temporary location, call + the modifier, and then use the passed (and possibly updated) + dictionary to write a new wheel. If ``dest_dir`` is specified, the new + wheel is written there -- otherwise, the original wheel is overwritten. + + The modifier should return True if it updated the wheel, else False. + This method returns the same value the modifier returns. + """ + + def get_version(path_map, info_dir): + version = path = None + key = '%s/%s' % (info_dir, LEGACY_METADATA_FILENAME) + if key not in path_map: + key = '%s/PKG-INFO' % info_dir + if key in path_map: + path = path_map[key] + version = Metadata(path=path).version + return version, path + + def update_version(version, path): + updated = None + try: + v = NormalizedVersion(version) + i = version.find('-') + if i < 0: + updated = '%s+1' % version + else: + parts = [int(s) for s in version[i + 1:].split('.')] + parts[-1] += 1 + updated = '%s+%s' % (version[:i], + '.'.join(str(i) for i in parts)) + except UnsupportedVersionError: + logger.debug('Cannot update non-compliant (PEP-440) ' + 'version %r', version) + if updated: + md = Metadata(path=path) + md.version = updated + legacy = path.endswith(LEGACY_METADATA_FILENAME) + md.write(path=path, legacy=legacy) + logger.debug('Version updated from %r to %r', version, + updated) + + pathname = os.path.join(self.dirname, self.filename) + name_ver = '%s-%s' % (self.name, self.version) + info_dir = '%s.dist-info' % name_ver + record_name = posixpath.join(info_dir, 'RECORD') + with tempdir() as workdir: + with ZipFile(pathname, 'r') as zf: + path_map = {} + for zinfo in zf.infolist(): + arcname = zinfo.filename + if isinstance(arcname, text_type): + u_arcname = arcname + else: + u_arcname = arcname.decode('utf-8') + if u_arcname == record_name: + continue + if '..' in u_arcname: + raise DistlibException('invalid entry in ' + 'wheel: %r' % u_arcname) + zf.extract(zinfo, workdir) + path = os.path.join(workdir, convert_path(u_arcname)) + path_map[u_arcname] = path + + # Remember the version. + original_version, _ = get_version(path_map, info_dir) + # Files extracted. Call the modifier. + modified = modifier(path_map, **kwargs) + if modified: + # Something changed - need to build a new wheel. + current_version, path = get_version(path_map, info_dir) + if current_version and (current_version == original_version): + # Add or update local version to signify changes. + update_version(current_version, path) + # Decide where the new wheel goes. + if dest_dir is None: + fd, newpath = tempfile.mkstemp(suffix='.whl', + prefix='wheel-update-', + dir=workdir) + os.close(fd) + else: + if not os.path.isdir(dest_dir): + raise DistlibException('Not a directory: %r' % dest_dir) + newpath = os.path.join(dest_dir, self.filename) + archive_paths = list(path_map.items()) + distinfo = os.path.join(workdir, info_dir) + info = distinfo, info_dir + self.write_records(info, workdir, archive_paths) + self.build_zip(newpath, archive_paths) + if dest_dir is None: + shutil.copyfile(newpath, pathname) + return modified + +def compatible_tags(): + """ + Return (pyver, abi, arch) tuples compatible with this Python. + """ + versions = [VER_SUFFIX] + major = VER_SUFFIX[0] + for minor in range(sys.version_info[1] - 1, - 1, -1): + versions.append(''.join([major, str(minor)])) + + abis = [] + for suffix, _, _ in imp.get_suffixes(): + if suffix.startswith('.abi'): + abis.append(suffix.split('.', 2)[1]) + abis.sort() + if ABI != 'none': + abis.insert(0, ABI) + abis.append('none') + result = [] + + arches = [ARCH] + if sys.platform == 'darwin': + m = re.match(r'(\w+)_(\d+)_(\d+)_(\w+)$', ARCH) + if m: + name, major, minor, arch = m.groups() + minor = int(minor) + matches = [arch] + if arch in ('i386', 'ppc'): + matches.append('fat') + if arch in ('i386', 'ppc', 'x86_64'): + matches.append('fat3') + if arch in ('ppc64', 'x86_64'): + matches.append('fat64') + if arch in ('i386', 'x86_64'): + matches.append('intel') + if arch in ('i386', 'x86_64', 'intel', 'ppc', 'ppc64'): + matches.append('universal') + while minor >= 0: + for match in matches: + s = '%s_%s_%s_%s' % (name, major, minor, match) + if s != ARCH: # already there + arches.append(s) + minor -= 1 + + # Most specific - our Python version, ABI and arch + for abi in abis: + for arch in arches: + result.append((''.join((IMP_PREFIX, versions[0])), abi, arch)) + + # where no ABI / arch dependency, but IMP_PREFIX dependency + for i, version in enumerate(versions): + result.append((''.join((IMP_PREFIX, version)), 'none', 'any')) + if i == 0: + result.append((''.join((IMP_PREFIX, version[0])), 'none', 'any')) + + # no IMP_PREFIX, ABI or arch dependency + for i, version in enumerate(versions): + result.append((''.join(('py', version)), 'none', 'any')) + if i == 0: + result.append((''.join(('py', version[0])), 'none', 'any')) + return set(result) + + +COMPATIBLE_TAGS = compatible_tags() + +del compatible_tags + + +def is_compatible(wheel, tags=None): + if not isinstance(wheel, Wheel): + wheel = Wheel(wheel) # assume it's a filename + result = False + if tags is None: + tags = COMPATIBLE_TAGS + for ver, abi, arch in tags: + if ver in wheel.pyver and abi in wheel.abi and arch in wheel.arch: + result = True + break + return result diff --git a/venv/Lib/site-packages/pip/_vendor/distro.py b/venv/Lib/site-packages/pip/_vendor/distro.py new file mode 100644 index 0000000..0611b62 --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/distro.py @@ -0,0 +1,1230 @@ +# Copyright 2015,2016,2017 Nir Cohen +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +""" +The ``distro`` package (``distro`` stands for Linux Distribution) provides +information about the Linux distribution it runs on, such as a reliable +machine-readable distro ID, or version information. + +It is the recommended replacement for Python's original +:py:func:`platform.linux_distribution` function, but it provides much more +functionality. An alternative implementation became necessary because Python +3.5 deprecated this function, and Python 3.8 will remove it altogether. +Its predecessor function :py:func:`platform.dist` was already +deprecated since Python 2.6 and will also be removed in Python 3.8. +Still, there are many cases in which access to OS distribution information +is needed. See `Python issue 1322 `_ for +more information. +""" + +import os +import re +import sys +import json +import shlex +import logging +import argparse +import subprocess + + +_UNIXCONFDIR = os.environ.get('UNIXCONFDIR', '/etc') +_OS_RELEASE_BASENAME = 'os-release' + +#: Translation table for normalizing the "ID" attribute defined in os-release +#: files, for use by the :func:`distro.id` method. +#: +#: * Key: Value as defined in the os-release file, translated to lower case, +#: with blanks translated to underscores. +#: +#: * Value: Normalized value. +NORMALIZED_OS_ID = { + 'ol': 'oracle', # Oracle Linux +} + +#: Translation table for normalizing the "Distributor ID" attribute returned by +#: the lsb_release command, for use by the :func:`distro.id` method. +#: +#: * Key: Value as returned by the lsb_release command, translated to lower +#: case, with blanks translated to underscores. +#: +#: * Value: Normalized value. +NORMALIZED_LSB_ID = { + 'enterpriseenterpriseas': 'oracle', # Oracle Enterprise Linux 4 + 'enterpriseenterpriseserver': 'oracle', # Oracle Linux 5 + 'redhatenterpriseworkstation': 'rhel', # RHEL 6, 7 Workstation + 'redhatenterpriseserver': 'rhel', # RHEL 6, 7 Server + 'redhatenterprisecomputenode': 'rhel', # RHEL 6 ComputeNode +} + +#: Translation table for normalizing the distro ID derived from the file name +#: of distro release files, for use by the :func:`distro.id` method. +#: +#: * Key: Value as derived from the file name of a distro release file, +#: translated to lower case, with blanks translated to underscores. +#: +#: * Value: Normalized value. +NORMALIZED_DISTRO_ID = { + 'redhat': 'rhel', # RHEL 6.x, 7.x +} + +# Pattern for content of distro release file (reversed) +_DISTRO_RELEASE_CONTENT_REVERSED_PATTERN = re.compile( + r'(?:[^)]*\)(.*)\()? *(?:STL )?([\d.+\-a-z]*\d) *(?:esaeler *)?(.+)') + +# Pattern for base file name of distro release file +_DISTRO_RELEASE_BASENAME_PATTERN = re.compile( + r'(\w+)[-_](release|version)$') + +# Base file names to be ignored when searching for distro release file +_DISTRO_RELEASE_IGNORE_BASENAMES = ( + 'debian_version', + 'lsb-release', + 'oem-release', + _OS_RELEASE_BASENAME, + 'system-release', + 'plesk-release', +) + + +def linux_distribution(full_distribution_name=True): + """ + Return information about the current OS distribution as a tuple + ``(id_name, version, codename)`` with items as follows: + + * ``id_name``: If *full_distribution_name* is false, the result of + :func:`distro.id`. Otherwise, the result of :func:`distro.name`. + + * ``version``: The result of :func:`distro.version`. + + * ``codename``: The result of :func:`distro.codename`. + + The interface of this function is compatible with the original + :py:func:`platform.linux_distribution` function, supporting a subset of + its parameters. + + The data it returns may not exactly be the same, because it uses more data + sources than the original function, and that may lead to different data if + the OS distribution is not consistent across multiple data sources it + provides (there are indeed such distributions ...). + + Another reason for differences is the fact that the :func:`distro.id` + method normalizes the distro ID string to a reliable machine-readable value + for a number of popular OS distributions. + """ + return _distro.linux_distribution(full_distribution_name) + + +def id(): + """ + Return the distro ID of the current distribution, as a + machine-readable string. + + For a number of OS distributions, the returned distro ID value is + *reliable*, in the sense that it is documented and that it does not change + across releases of the distribution. + + This package maintains the following reliable distro ID values: + + ============== ========================================= + Distro ID Distribution + ============== ========================================= + "ubuntu" Ubuntu + "debian" Debian + "rhel" RedHat Enterprise Linux + "centos" CentOS + "fedora" Fedora + "sles" SUSE Linux Enterprise Server + "opensuse" openSUSE + "amazon" Amazon Linux + "arch" Arch Linux + "cloudlinux" CloudLinux OS + "exherbo" Exherbo Linux + "gentoo" GenToo Linux + "ibm_powerkvm" IBM PowerKVM + "kvmibm" KVM for IBM z Systems + "linuxmint" Linux Mint + "mageia" Mageia + "mandriva" Mandriva Linux + "parallels" Parallels + "pidora" Pidora + "raspbian" Raspbian + "oracle" Oracle Linux (and Oracle Enterprise Linux) + "scientific" Scientific Linux + "slackware" Slackware + "xenserver" XenServer + "openbsd" OpenBSD + "netbsd" NetBSD + "freebsd" FreeBSD + "midnightbsd" MidnightBSD + ============== ========================================= + + If you have a need to get distros for reliable IDs added into this set, + or if you find that the :func:`distro.id` function returns a different + distro ID for one of the listed distros, please create an issue in the + `distro issue tracker`_. + + **Lookup hierarchy and transformations:** + + First, the ID is obtained from the following sources, in the specified + order. The first available and non-empty value is used: + + * the value of the "ID" attribute of the os-release file, + + * the value of the "Distributor ID" attribute returned by the lsb_release + command, + + * the first part of the file name of the distro release file, + + The so determined ID value then passes the following transformations, + before it is returned by this method: + + * it is translated to lower case, + + * blanks (which should not be there anyway) are translated to underscores, + + * a normalization of the ID is performed, based upon + `normalization tables`_. The purpose of this normalization is to ensure + that the ID is as reliable as possible, even across incompatible changes + in the OS distributions. A common reason for an incompatible change is + the addition of an os-release file, or the addition of the lsb_release + command, with ID values that differ from what was previously determined + from the distro release file name. + """ + return _distro.id() + + +def name(pretty=False): + """ + Return the name of the current OS distribution, as a human-readable + string. + + If *pretty* is false, the name is returned without version or codename. + (e.g. "CentOS Linux") + + If *pretty* is true, the version and codename are appended. + (e.g. "CentOS Linux 7.1.1503 (Core)") + + **Lookup hierarchy:** + + The name is obtained from the following sources, in the specified order. + The first available and non-empty value is used: + + * If *pretty* is false: + + - the value of the "NAME" attribute of the os-release file, + + - the value of the "Distributor ID" attribute returned by the lsb_release + command, + + - the value of the "" field of the distro release file. + + * If *pretty* is true: + + - the value of the "PRETTY_NAME" attribute of the os-release file, + + - the value of the "Description" attribute returned by the lsb_release + command, + + - the value of the "" field of the distro release file, appended + with the value of the pretty version ("" and "" + fields) of the distro release file, if available. + """ + return _distro.name(pretty) + + +def version(pretty=False, best=False): + """ + Return the version of the current OS distribution, as a human-readable + string. + + If *pretty* is false, the version is returned without codename (e.g. + "7.0"). + + If *pretty* is true, the codename in parenthesis is appended, if the + codename is non-empty (e.g. "7.0 (Maipo)"). + + Some distributions provide version numbers with different precisions in + the different sources of distribution information. Examining the different + sources in a fixed priority order does not always yield the most precise + version (e.g. for Debian 8.2, or CentOS 7.1). + + The *best* parameter can be used to control the approach for the returned + version: + + If *best* is false, the first non-empty version number in priority order of + the examined sources is returned. + + If *best* is true, the most precise version number out of all examined + sources is returned. + + **Lookup hierarchy:** + + In all cases, the version number is obtained from the following sources. + If *best* is false, this order represents the priority order: + + * the value of the "VERSION_ID" attribute of the os-release file, + * the value of the "Release" attribute returned by the lsb_release + command, + * the version number parsed from the "" field of the first line + of the distro release file, + * the version number parsed from the "PRETTY_NAME" attribute of the + os-release file, if it follows the format of the distro release files. + * the version number parsed from the "Description" attribute returned by + the lsb_release command, if it follows the format of the distro release + files. + """ + return _distro.version(pretty, best) + + +def version_parts(best=False): + """ + Return the version of the current OS distribution as a tuple + ``(major, minor, build_number)`` with items as follows: + + * ``major``: The result of :func:`distro.major_version`. + + * ``minor``: The result of :func:`distro.minor_version`. + + * ``build_number``: The result of :func:`distro.build_number`. + + For a description of the *best* parameter, see the :func:`distro.version` + method. + """ + return _distro.version_parts(best) + + +def major_version(best=False): + """ + Return the major version of the current OS distribution, as a string, + if provided. + Otherwise, the empty string is returned. The major version is the first + part of the dot-separated version string. + + For a description of the *best* parameter, see the :func:`distro.version` + method. + """ + return _distro.major_version(best) + + +def minor_version(best=False): + """ + Return the minor version of the current OS distribution, as a string, + if provided. + Otherwise, the empty string is returned. The minor version is the second + part of the dot-separated version string. + + For a description of the *best* parameter, see the :func:`distro.version` + method. + """ + return _distro.minor_version(best) + + +def build_number(best=False): + """ + Return the build number of the current OS distribution, as a string, + if provided. + Otherwise, the empty string is returned. The build number is the third part + of the dot-separated version string. + + For a description of the *best* parameter, see the :func:`distro.version` + method. + """ + return _distro.build_number(best) + + +def like(): + """ + Return a space-separated list of distro IDs of distributions that are + closely related to the current OS distribution in regards to packaging + and programming interfaces, for example distributions the current + distribution is a derivative from. + + **Lookup hierarchy:** + + This information item is only provided by the os-release file. + For details, see the description of the "ID_LIKE" attribute in the + `os-release man page + `_. + """ + return _distro.like() + + +def codename(): + """ + Return the codename for the release of the current OS distribution, + as a string. + + If the distribution does not have a codename, an empty string is returned. + + Note that the returned codename is not always really a codename. For + example, openSUSE returns "x86_64". This function does not handle such + cases in any special way and just returns the string it finds, if any. + + **Lookup hierarchy:** + + * the codename within the "VERSION" attribute of the os-release file, if + provided, + + * the value of the "Codename" attribute returned by the lsb_release + command, + + * the value of the "" field of the distro release file. + """ + return _distro.codename() + + +def info(pretty=False, best=False): + """ + Return certain machine-readable information items about the current OS + distribution in a dictionary, as shown in the following example: + + .. sourcecode:: python + + { + 'id': 'rhel', + 'version': '7.0', + 'version_parts': { + 'major': '7', + 'minor': '0', + 'build_number': '' + }, + 'like': 'fedora', + 'codename': 'Maipo' + } + + The dictionary structure and keys are always the same, regardless of which + information items are available in the underlying data sources. The values + for the various keys are as follows: + + * ``id``: The result of :func:`distro.id`. + + * ``version``: The result of :func:`distro.version`. + + * ``version_parts -> major``: The result of :func:`distro.major_version`. + + * ``version_parts -> minor``: The result of :func:`distro.minor_version`. + + * ``version_parts -> build_number``: The result of + :func:`distro.build_number`. + + * ``like``: The result of :func:`distro.like`. + + * ``codename``: The result of :func:`distro.codename`. + + For a description of the *pretty* and *best* parameters, see the + :func:`distro.version` method. + """ + return _distro.info(pretty, best) + + +def os_release_info(): + """ + Return a dictionary containing key-value pairs for the information items + from the os-release file data source of the current OS distribution. + + See `os-release file`_ for details about these information items. + """ + return _distro.os_release_info() + + +def lsb_release_info(): + """ + Return a dictionary containing key-value pairs for the information items + from the lsb_release command data source of the current OS distribution. + + See `lsb_release command output`_ for details about these information + items. + """ + return _distro.lsb_release_info() + + +def distro_release_info(): + """ + Return a dictionary containing key-value pairs for the information items + from the distro release file data source of the current OS distribution. + + See `distro release file`_ for details about these information items. + """ + return _distro.distro_release_info() + + +def uname_info(): + """ + Return a dictionary containing key-value pairs for the information items + from the distro release file data source of the current OS distribution. + """ + return _distro.uname_info() + + +def os_release_attr(attribute): + """ + Return a single named information item from the os-release file data source + of the current OS distribution. + + Parameters: + + * ``attribute`` (string): Key of the information item. + + Returns: + + * (string): Value of the information item, if the item exists. + The empty string, if the item does not exist. + + See `os-release file`_ for details about these information items. + """ + return _distro.os_release_attr(attribute) + + +def lsb_release_attr(attribute): + """ + Return a single named information item from the lsb_release command output + data source of the current OS distribution. + + Parameters: + + * ``attribute`` (string): Key of the information item. + + Returns: + + * (string): Value of the information item, if the item exists. + The empty string, if the item does not exist. + + See `lsb_release command output`_ for details about these information + items. + """ + return _distro.lsb_release_attr(attribute) + + +def distro_release_attr(attribute): + """ + Return a single named information item from the distro release file + data source of the current OS distribution. + + Parameters: + + * ``attribute`` (string): Key of the information item. + + Returns: + + * (string): Value of the information item, if the item exists. + The empty string, if the item does not exist. + + See `distro release file`_ for details about these information items. + """ + return _distro.distro_release_attr(attribute) + + +def uname_attr(attribute): + """ + Return a single named information item from the distro release file + data source of the current OS distribution. + + Parameters: + + * ``attribute`` (string): Key of the information item. + + Returns: + + * (string): Value of the information item, if the item exists. + The empty string, if the item does not exist. + """ + return _distro.uname_attr(attribute) + + +class cached_property(object): + """A version of @property which caches the value. On access, it calls the + underlying function and sets the value in `__dict__` so future accesses + will not re-call the property. + """ + def __init__(self, f): + self._fname = f.__name__ + self._f = f + + def __get__(self, obj, owner): + assert obj is not None, 'call {} on an instance'.format(self._fname) + ret = obj.__dict__[self._fname] = self._f(obj) + return ret + + +class LinuxDistribution(object): + """ + Provides information about a OS distribution. + + This package creates a private module-global instance of this class with + default initialization arguments, that is used by the + `consolidated accessor functions`_ and `single source accessor functions`_. + By using default initialization arguments, that module-global instance + returns data about the current OS distribution (i.e. the distro this + package runs on). + + Normally, it is not necessary to create additional instances of this class. + However, in situations where control is needed over the exact data sources + that are used, instances of this class can be created with a specific + distro release file, or a specific os-release file, or without invoking the + lsb_release command. + """ + + def __init__(self, + include_lsb=True, + os_release_file='', + distro_release_file='', + include_uname=True): + """ + The initialization method of this class gathers information from the + available data sources, and stores that in private instance attributes. + Subsequent access to the information items uses these private instance + attributes, so that the data sources are read only once. + + Parameters: + + * ``include_lsb`` (bool): Controls whether the + `lsb_release command output`_ is included as a data source. + + If the lsb_release command is not available in the program execution + path, the data source for the lsb_release command will be empty. + + * ``os_release_file`` (string): The path name of the + `os-release file`_ that is to be used as a data source. + + An empty string (the default) will cause the default path name to + be used (see `os-release file`_ for details). + + If the specified or defaulted os-release file does not exist, the + data source for the os-release file will be empty. + + * ``distro_release_file`` (string): The path name of the + `distro release file`_ that is to be used as a data source. + + An empty string (the default) will cause a default search algorithm + to be used (see `distro release file`_ for details). + + If the specified distro release file does not exist, or if no default + distro release file can be found, the data source for the distro + release file will be empty. + + * ``include_uname`` (bool): Controls whether uname command output is + included as a data source. If the uname command is not available in + the program execution path the data source for the uname command will + be empty. + + Public instance attributes: + + * ``os_release_file`` (string): The path name of the + `os-release file`_ that is actually used as a data source. The + empty string if no distro release file is used as a data source. + + * ``distro_release_file`` (string): The path name of the + `distro release file`_ that is actually used as a data source. The + empty string if no distro release file is used as a data source. + + * ``include_lsb`` (bool): The result of the ``include_lsb`` parameter. + This controls whether the lsb information will be loaded. + + * ``include_uname`` (bool): The result of the ``include_uname`` + parameter. This controls whether the uname information will + be loaded. + + Raises: + + * :py:exc:`IOError`: Some I/O issue with an os-release file or distro + release file. + + * :py:exc:`subprocess.CalledProcessError`: The lsb_release command had + some issue (other than not being available in the program execution + path). + + * :py:exc:`UnicodeError`: A data source has unexpected characters or + uses an unexpected encoding. + """ + self.os_release_file = os_release_file or \ + os.path.join(_UNIXCONFDIR, _OS_RELEASE_BASENAME) + self.distro_release_file = distro_release_file or '' # updated later + self.include_lsb = include_lsb + self.include_uname = include_uname + + def __repr__(self): + """Return repr of all info + """ + return \ + "LinuxDistribution(" \ + "os_release_file={self.os_release_file!r}, " \ + "distro_release_file={self.distro_release_file!r}, " \ + "include_lsb={self.include_lsb!r}, " \ + "include_uname={self.include_uname!r}, " \ + "_os_release_info={self._os_release_info!r}, " \ + "_lsb_release_info={self._lsb_release_info!r}, " \ + "_distro_release_info={self._distro_release_info!r}, " \ + "_uname_info={self._uname_info!r})".format( + self=self) + + def linux_distribution(self, full_distribution_name=True): + """ + Return information about the OS distribution that is compatible + with Python's :func:`platform.linux_distribution`, supporting a subset + of its parameters. + + For details, see :func:`distro.linux_distribution`. + """ + return ( + self.name() if full_distribution_name else self.id(), + self.version(), + self.codename() + ) + + def id(self): + """Return the distro ID of the OS distribution, as a string. + + For details, see :func:`distro.id`. + """ + def normalize(distro_id, table): + distro_id = distro_id.lower().replace(' ', '_') + return table.get(distro_id, distro_id) + + distro_id = self.os_release_attr('id') + if distro_id: + return normalize(distro_id, NORMALIZED_OS_ID) + + distro_id = self.lsb_release_attr('distributor_id') + if distro_id: + return normalize(distro_id, NORMALIZED_LSB_ID) + + distro_id = self.distro_release_attr('id') + if distro_id: + return normalize(distro_id, NORMALIZED_DISTRO_ID) + + distro_id = self.uname_attr('id') + if distro_id: + return normalize(distro_id, NORMALIZED_DISTRO_ID) + + return '' + + def name(self, pretty=False): + """ + Return the name of the OS distribution, as a string. + + For details, see :func:`distro.name`. + """ + name = self.os_release_attr('name') \ + or self.lsb_release_attr('distributor_id') \ + or self.distro_release_attr('name') \ + or self.uname_attr('name') + if pretty: + name = self.os_release_attr('pretty_name') \ + or self.lsb_release_attr('description') + if not name: + name = self.distro_release_attr('name') \ + or self.uname_attr('name') + version = self.version(pretty=True) + if version: + name = name + ' ' + version + return name or '' + + def version(self, pretty=False, best=False): + """ + Return the version of the OS distribution, as a string. + + For details, see :func:`distro.version`. + """ + versions = [ + self.os_release_attr('version_id'), + self.lsb_release_attr('release'), + self.distro_release_attr('version_id'), + self._parse_distro_release_content( + self.os_release_attr('pretty_name')).get('version_id', ''), + self._parse_distro_release_content( + self.lsb_release_attr('description')).get('version_id', ''), + self.uname_attr('release') + ] + version = '' + if best: + # This algorithm uses the last version in priority order that has + # the best precision. If the versions are not in conflict, that + # does not matter; otherwise, using the last one instead of the + # first one might be considered a surprise. + for v in versions: + if v.count(".") > version.count(".") or version == '': + version = v + else: + for v in versions: + if v != '': + version = v + break + if pretty and version and self.codename(): + version = '{0} ({1})'.format(version, self.codename()) + return version + + def version_parts(self, best=False): + """ + Return the version of the OS distribution, as a tuple of version + numbers. + + For details, see :func:`distro.version_parts`. + """ + version_str = self.version(best=best) + if version_str: + version_regex = re.compile(r'(\d+)\.?(\d+)?\.?(\d+)?') + matches = version_regex.match(version_str) + if matches: + major, minor, build_number = matches.groups() + return major, minor or '', build_number or '' + return '', '', '' + + def major_version(self, best=False): + """ + Return the major version number of the current distribution. + + For details, see :func:`distro.major_version`. + """ + return self.version_parts(best)[0] + + def minor_version(self, best=False): + """ + Return the minor version number of the current distribution. + + For details, see :func:`distro.minor_version`. + """ + return self.version_parts(best)[1] + + def build_number(self, best=False): + """ + Return the build number of the current distribution. + + For details, see :func:`distro.build_number`. + """ + return self.version_parts(best)[2] + + def like(self): + """ + Return the IDs of distributions that are like the OS distribution. + + For details, see :func:`distro.like`. + """ + return self.os_release_attr('id_like') or '' + + def codename(self): + """ + Return the codename of the OS distribution. + + For details, see :func:`distro.codename`. + """ + try: + # Handle os_release specially since distros might purposefully set + # this to empty string to have no codename + return self._os_release_info['codename'] + except KeyError: + return self.lsb_release_attr('codename') \ + or self.distro_release_attr('codename') \ + or '' + + def info(self, pretty=False, best=False): + """ + Return certain machine-readable information about the OS + distribution. + + For details, see :func:`distro.info`. + """ + return dict( + id=self.id(), + version=self.version(pretty, best), + version_parts=dict( + major=self.major_version(best), + minor=self.minor_version(best), + build_number=self.build_number(best) + ), + like=self.like(), + codename=self.codename(), + ) + + def os_release_info(self): + """ + Return a dictionary containing key-value pairs for the information + items from the os-release file data source of the OS distribution. + + For details, see :func:`distro.os_release_info`. + """ + return self._os_release_info + + def lsb_release_info(self): + """ + Return a dictionary containing key-value pairs for the information + items from the lsb_release command data source of the OS + distribution. + + For details, see :func:`distro.lsb_release_info`. + """ + return self._lsb_release_info + + def distro_release_info(self): + """ + Return a dictionary containing key-value pairs for the information + items from the distro release file data source of the OS + distribution. + + For details, see :func:`distro.distro_release_info`. + """ + return self._distro_release_info + + def uname_info(self): + """ + Return a dictionary containing key-value pairs for the information + items from the uname command data source of the OS distribution. + + For details, see :func:`distro.uname_info`. + """ + return self._uname_info + + def os_release_attr(self, attribute): + """ + Return a single named information item from the os-release file data + source of the OS distribution. + + For details, see :func:`distro.os_release_attr`. + """ + return self._os_release_info.get(attribute, '') + + def lsb_release_attr(self, attribute): + """ + Return a single named information item from the lsb_release command + output data source of the OS distribution. + + For details, see :func:`distro.lsb_release_attr`. + """ + return self._lsb_release_info.get(attribute, '') + + def distro_release_attr(self, attribute): + """ + Return a single named information item from the distro release file + data source of the OS distribution. + + For details, see :func:`distro.distro_release_attr`. + """ + return self._distro_release_info.get(attribute, '') + + def uname_attr(self, attribute): + """ + Return a single named information item from the uname command + output data source of the OS distribution. + + For details, see :func:`distro.uname_release_attr`. + """ + return self._uname_info.get(attribute, '') + + @cached_property + def _os_release_info(self): + """ + Get the information items from the specified os-release file. + + Returns: + A dictionary containing all information items. + """ + if os.path.isfile(self.os_release_file): + with open(self.os_release_file) as release_file: + return self._parse_os_release_content(release_file) + return {} + + @staticmethod + def _parse_os_release_content(lines): + """ + Parse the lines of an os-release file. + + Parameters: + + * lines: Iterable through the lines in the os-release file. + Each line must be a unicode string or a UTF-8 encoded byte + string. + + Returns: + A dictionary containing all information items. + """ + props = {} + lexer = shlex.shlex(lines, posix=True) + lexer.whitespace_split = True + + # The shlex module defines its `wordchars` variable using literals, + # making it dependent on the encoding of the Python source file. + # In Python 2.6 and 2.7, the shlex source file is encoded in + # 'iso-8859-1', and the `wordchars` variable is defined as a byte + # string. This causes a UnicodeDecodeError to be raised when the + # parsed content is a unicode object. The following fix resolves that + # (... but it should be fixed in shlex...): + if sys.version_info[0] == 2 and isinstance(lexer.wordchars, bytes): + lexer.wordchars = lexer.wordchars.decode('iso-8859-1') + + tokens = list(lexer) + for token in tokens: + # At this point, all shell-like parsing has been done (i.e. + # comments processed, quotes and backslash escape sequences + # processed, multi-line values assembled, trailing newlines + # stripped, etc.), so the tokens are now either: + # * variable assignments: var=value + # * commands or their arguments (not allowed in os-release) + if '=' in token: + k, v = token.split('=', 1) + props[k.lower()] = v + else: + # Ignore any tokens that are not variable assignments + pass + + if 'version_codename' in props: + # os-release added a version_codename field. Use that in + # preference to anything else Note that some distros purposefully + # do not have code names. They should be setting + # version_codename="" + props['codename'] = props['version_codename'] + elif 'ubuntu_codename' in props: + # Same as above but a non-standard field name used on older Ubuntus + props['codename'] = props['ubuntu_codename'] + elif 'version' in props: + # If there is no version_codename, parse it from the version + codename = re.search(r'(\(\D+\))|,(\s+)?\D+', props['version']) + if codename: + codename = codename.group() + codename = codename.strip('()') + codename = codename.strip(',') + codename = codename.strip() + # codename appears within paranthese. + props['codename'] = codename + + return props + + @cached_property + def _lsb_release_info(self): + """ + Get the information items from the lsb_release command output. + + Returns: + A dictionary containing all information items. + """ + if not self.include_lsb: + return {} + with open(os.devnull, 'w') as devnull: + try: + cmd = ('lsb_release', '-a') + stdout = subprocess.check_output(cmd, stderr=devnull) + except OSError: # Command not found + return {} + content = self._to_str(stdout).splitlines() + return self._parse_lsb_release_content(content) + + @staticmethod + def _parse_lsb_release_content(lines): + """ + Parse the output of the lsb_release command. + + Parameters: + + * lines: Iterable through the lines of the lsb_release output. + Each line must be a unicode string or a UTF-8 encoded byte + string. + + Returns: + A dictionary containing all information items. + """ + props = {} + for line in lines: + kv = line.strip('\n').split(':', 1) + if len(kv) != 2: + # Ignore lines without colon. + continue + k, v = kv + props.update({k.replace(' ', '_').lower(): v.strip()}) + return props + + @cached_property + def _uname_info(self): + with open(os.devnull, 'w') as devnull: + try: + cmd = ('uname', '-rs') + stdout = subprocess.check_output(cmd, stderr=devnull) + except OSError: + return {} + content = self._to_str(stdout).splitlines() + return self._parse_uname_content(content) + + @staticmethod + def _parse_uname_content(lines): + props = {} + match = re.search(r'^([^\s]+)\s+([\d\.]+)', lines[0].strip()) + if match: + name, version = match.groups() + + # This is to prevent the Linux kernel version from + # appearing as the 'best' version on otherwise + # identifiable distributions. + if name == 'Linux': + return {} + props['id'] = name.lower() + props['name'] = name + props['release'] = version + return props + + @staticmethod + def _to_str(text): + encoding = sys.getfilesystemencoding() + encoding = 'utf-8' if encoding == 'ascii' else encoding + + if sys.version_info[0] >= 3: + if isinstance(text, bytes): + return text.decode(encoding) + else: + if isinstance(text, unicode): # noqa + return text.encode(encoding) + + return text + + @cached_property + def _distro_release_info(self): + """ + Get the information items from the specified distro release file. + + Returns: + A dictionary containing all information items. + """ + if self.distro_release_file: + # If it was specified, we use it and parse what we can, even if + # its file name or content does not match the expected pattern. + distro_info = self._parse_distro_release_file( + self.distro_release_file) + basename = os.path.basename(self.distro_release_file) + # The file name pattern for user-specified distro release files + # is somewhat more tolerant (compared to when searching for the + # file), because we want to use what was specified as best as + # possible. + match = _DISTRO_RELEASE_BASENAME_PATTERN.match(basename) + if 'name' in distro_info \ + and 'cloudlinux' in distro_info['name'].lower(): + distro_info['id'] = 'cloudlinux' + elif match: + distro_info['id'] = match.group(1) + return distro_info + else: + try: + basenames = os.listdir(_UNIXCONFDIR) + # We sort for repeatability in cases where there are multiple + # distro specific files; e.g. CentOS, Oracle, Enterprise all + # containing `redhat-release` on top of their own. + basenames.sort() + except OSError: + # This may occur when /etc is not readable but we can't be + # sure about the *-release files. Check common entries of + # /etc for information. If they turn out to not be there the + # error is handled in `_parse_distro_release_file()`. + basenames = ['SuSE-release', + 'arch-release', + 'base-release', + 'centos-release', + 'fedora-release', + 'gentoo-release', + 'mageia-release', + 'mandrake-release', + 'mandriva-release', + 'mandrivalinux-release', + 'manjaro-release', + 'oracle-release', + 'redhat-release', + 'sl-release', + 'slackware-version'] + for basename in basenames: + if basename in _DISTRO_RELEASE_IGNORE_BASENAMES: + continue + match = _DISTRO_RELEASE_BASENAME_PATTERN.match(basename) + if match: + filepath = os.path.join(_UNIXCONFDIR, basename) + distro_info = self._parse_distro_release_file(filepath) + if 'name' in distro_info: + # The name is always present if the pattern matches + self.distro_release_file = filepath + distro_info['id'] = match.group(1) + if 'cloudlinux' in distro_info['name'].lower(): + distro_info['id'] = 'cloudlinux' + return distro_info + return {} + + def _parse_distro_release_file(self, filepath): + """ + Parse a distro release file. + + Parameters: + + * filepath: Path name of the distro release file. + + Returns: + A dictionary containing all information items. + """ + try: + with open(filepath) as fp: + # Only parse the first line. For instance, on SLES there + # are multiple lines. We don't want them... + return self._parse_distro_release_content(fp.readline()) + except (OSError, IOError): + # Ignore not being able to read a specific, seemingly version + # related file. + # See https://github.com/nir0s/distro/issues/162 + return {} + + @staticmethod + def _parse_distro_release_content(line): + """ + Parse a line from a distro release file. + + Parameters: + * line: Line from the distro release file. Must be a unicode string + or a UTF-8 encoded byte string. + + Returns: + A dictionary containing all information items. + """ + matches = _DISTRO_RELEASE_CONTENT_REVERSED_PATTERN.match( + line.strip()[::-1]) + distro_info = {} + if matches: + # regexp ensures non-None + distro_info['name'] = matches.group(3)[::-1] + if matches.group(2): + distro_info['version_id'] = matches.group(2)[::-1] + if matches.group(1): + distro_info['codename'] = matches.group(1)[::-1] + elif line: + distro_info['name'] = line.strip() + return distro_info + + +_distro = LinuxDistribution() + + +def main(): + logger = logging.getLogger(__name__) + logger.setLevel(logging.DEBUG) + logger.addHandler(logging.StreamHandler(sys.stdout)) + + parser = argparse.ArgumentParser(description="OS distro info tool") + parser.add_argument( + '--json', + '-j', + help="Output in machine readable format", + action="store_true") + args = parser.parse_args() + + if args.json: + logger.info(json.dumps(info(), indent=4, sort_keys=True)) + else: + logger.info('Name: %s', name(pretty=True)) + distribution_version = version(pretty=True) + logger.info('Version: %s', distribution_version) + distribution_codename = codename() + logger.info('Codename: %s', distribution_codename) + + +if __name__ == '__main__': + main() diff --git a/venv/Lib/site-packages/pip/_vendor/html5lib/__init__.py b/venv/Lib/site-packages/pip/_vendor/html5lib/__init__.py new file mode 100644 index 0000000..d1d82f1 --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/html5lib/__init__.py @@ -0,0 +1,35 @@ +""" +HTML parsing library based on the `WHATWG HTML specification +`_. The parser is designed to be compatible with +existing HTML found in the wild and implements well-defined error recovery that +is largely compatible with modern desktop web browsers. + +Example usage:: + + from pip._vendor import html5lib + with open("my_document.html", "rb") as f: + tree = html5lib.parse(f) + +For convenience, this module re-exports the following names: + +* :func:`~.html5parser.parse` +* :func:`~.html5parser.parseFragment` +* :class:`~.html5parser.HTMLParser` +* :func:`~.treebuilders.getTreeBuilder` +* :func:`~.treewalkers.getTreeWalker` +* :func:`~.serializer.serialize` +""" + +from __future__ import absolute_import, division, unicode_literals + +from .html5parser import HTMLParser, parse, parseFragment +from .treebuilders import getTreeBuilder +from .treewalkers import getTreeWalker +from .serializer import serialize + +__all__ = ["HTMLParser", "parse", "parseFragment", "getTreeBuilder", + "getTreeWalker", "serialize"] + +# this has to be at the top level, see how setup.py parses this +#: Distribution version number. +__version__ = "1.1" diff --git a/venv/Lib/site-packages/pip/_vendor/html5lib/_ihatexml.py b/venv/Lib/site-packages/pip/_vendor/html5lib/_ihatexml.py new file mode 100644 index 0000000..3ff803c --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/html5lib/_ihatexml.py @@ -0,0 +1,289 @@ +from __future__ import absolute_import, division, unicode_literals + +import re +import warnings + +from .constants import DataLossWarning + +baseChar = """ +[#x0041-#x005A] | [#x0061-#x007A] | [#x00C0-#x00D6] | [#x00D8-#x00F6] | +[#x00F8-#x00FF] | [#x0100-#x0131] | [#x0134-#x013E] | [#x0141-#x0148] | +[#x014A-#x017E] | [#x0180-#x01C3] | [#x01CD-#x01F0] | [#x01F4-#x01F5] | +[#x01FA-#x0217] | [#x0250-#x02A8] | [#x02BB-#x02C1] | #x0386 | +[#x0388-#x038A] | #x038C | [#x038E-#x03A1] | [#x03A3-#x03CE] | +[#x03D0-#x03D6] | #x03DA | #x03DC | #x03DE | #x03E0 | [#x03E2-#x03F3] | +[#x0401-#x040C] | [#x040E-#x044F] | [#x0451-#x045C] | [#x045E-#x0481] | +[#x0490-#x04C4] | [#x04C7-#x04C8] | [#x04CB-#x04CC] | [#x04D0-#x04EB] | +[#x04EE-#x04F5] | [#x04F8-#x04F9] | [#x0531-#x0556] | #x0559 | +[#x0561-#x0586] | [#x05D0-#x05EA] | [#x05F0-#x05F2] | [#x0621-#x063A] | +[#x0641-#x064A] | [#x0671-#x06B7] | [#x06BA-#x06BE] | [#x06C0-#x06CE] | +[#x06D0-#x06D3] | #x06D5 | [#x06E5-#x06E6] | [#x0905-#x0939] | #x093D | +[#x0958-#x0961] | [#x0985-#x098C] | [#x098F-#x0990] | [#x0993-#x09A8] | +[#x09AA-#x09B0] | #x09B2 | [#x09B6-#x09B9] | [#x09DC-#x09DD] | +[#x09DF-#x09E1] | [#x09F0-#x09F1] | [#x0A05-#x0A0A] | [#x0A0F-#x0A10] | +[#x0A13-#x0A28] | [#x0A2A-#x0A30] | [#x0A32-#x0A33] | [#x0A35-#x0A36] | +[#x0A38-#x0A39] | [#x0A59-#x0A5C] | #x0A5E | [#x0A72-#x0A74] | +[#x0A85-#x0A8B] | #x0A8D | [#x0A8F-#x0A91] | [#x0A93-#x0AA8] | +[#x0AAA-#x0AB0] | [#x0AB2-#x0AB3] | [#x0AB5-#x0AB9] | #x0ABD | #x0AE0 | +[#x0B05-#x0B0C] | [#x0B0F-#x0B10] | [#x0B13-#x0B28] | [#x0B2A-#x0B30] | +[#x0B32-#x0B33] | [#x0B36-#x0B39] | #x0B3D | [#x0B5C-#x0B5D] | +[#x0B5F-#x0B61] | [#x0B85-#x0B8A] | [#x0B8E-#x0B90] | [#x0B92-#x0B95] | +[#x0B99-#x0B9A] | #x0B9C | [#x0B9E-#x0B9F] | [#x0BA3-#x0BA4] | +[#x0BA8-#x0BAA] | [#x0BAE-#x0BB5] | [#x0BB7-#x0BB9] | [#x0C05-#x0C0C] | +[#x0C0E-#x0C10] | [#x0C12-#x0C28] | [#x0C2A-#x0C33] | [#x0C35-#x0C39] | +[#x0C60-#x0C61] | [#x0C85-#x0C8C] | [#x0C8E-#x0C90] | [#x0C92-#x0CA8] | +[#x0CAA-#x0CB3] | [#x0CB5-#x0CB9] | #x0CDE | [#x0CE0-#x0CE1] | +[#x0D05-#x0D0C] | [#x0D0E-#x0D10] | [#x0D12-#x0D28] | [#x0D2A-#x0D39] | +[#x0D60-#x0D61] | [#x0E01-#x0E2E] | #x0E30 | [#x0E32-#x0E33] | +[#x0E40-#x0E45] | [#x0E81-#x0E82] | #x0E84 | [#x0E87-#x0E88] | #x0E8A | +#x0E8D | [#x0E94-#x0E97] | [#x0E99-#x0E9F] | [#x0EA1-#x0EA3] | #x0EA5 | +#x0EA7 | [#x0EAA-#x0EAB] | [#x0EAD-#x0EAE] | #x0EB0 | [#x0EB2-#x0EB3] | +#x0EBD | [#x0EC0-#x0EC4] | [#x0F40-#x0F47] | [#x0F49-#x0F69] | +[#x10A0-#x10C5] | [#x10D0-#x10F6] | #x1100 | [#x1102-#x1103] | +[#x1105-#x1107] | #x1109 | [#x110B-#x110C] | [#x110E-#x1112] | #x113C | +#x113E | #x1140 | #x114C | #x114E | #x1150 | [#x1154-#x1155] | #x1159 | +[#x115F-#x1161] | #x1163 | #x1165 | #x1167 | #x1169 | [#x116D-#x116E] | +[#x1172-#x1173] | #x1175 | #x119E | #x11A8 | #x11AB | [#x11AE-#x11AF] | +[#x11B7-#x11B8] | #x11BA | [#x11BC-#x11C2] | #x11EB | #x11F0 | #x11F9 | +[#x1E00-#x1E9B] | [#x1EA0-#x1EF9] | [#x1F00-#x1F15] | [#x1F18-#x1F1D] | +[#x1F20-#x1F45] | [#x1F48-#x1F4D] | [#x1F50-#x1F57] | #x1F59 | #x1F5B | +#x1F5D | [#x1F5F-#x1F7D] | [#x1F80-#x1FB4] | [#x1FB6-#x1FBC] | #x1FBE | +[#x1FC2-#x1FC4] | [#x1FC6-#x1FCC] | [#x1FD0-#x1FD3] | [#x1FD6-#x1FDB] | +[#x1FE0-#x1FEC] | [#x1FF2-#x1FF4] | [#x1FF6-#x1FFC] | #x2126 | +[#x212A-#x212B] | #x212E | [#x2180-#x2182] | [#x3041-#x3094] | +[#x30A1-#x30FA] | [#x3105-#x312C] | [#xAC00-#xD7A3]""" + +ideographic = """[#x4E00-#x9FA5] | #x3007 | [#x3021-#x3029]""" + +combiningCharacter = """ +[#x0300-#x0345] | [#x0360-#x0361] | [#x0483-#x0486] | [#x0591-#x05A1] | +[#x05A3-#x05B9] | [#x05BB-#x05BD] | #x05BF | [#x05C1-#x05C2] | #x05C4 | +[#x064B-#x0652] | #x0670 | [#x06D6-#x06DC] | [#x06DD-#x06DF] | +[#x06E0-#x06E4] | [#x06E7-#x06E8] | [#x06EA-#x06ED] | [#x0901-#x0903] | +#x093C | [#x093E-#x094C] | #x094D | [#x0951-#x0954] | [#x0962-#x0963] | +[#x0981-#x0983] | #x09BC | #x09BE | #x09BF | [#x09C0-#x09C4] | +[#x09C7-#x09C8] | [#x09CB-#x09CD] | #x09D7 | [#x09E2-#x09E3] | #x0A02 | +#x0A3C | #x0A3E | #x0A3F | [#x0A40-#x0A42] | [#x0A47-#x0A48] | +[#x0A4B-#x0A4D] | [#x0A70-#x0A71] | [#x0A81-#x0A83] | #x0ABC | +[#x0ABE-#x0AC5] | [#x0AC7-#x0AC9] | [#x0ACB-#x0ACD] | [#x0B01-#x0B03] | +#x0B3C | [#x0B3E-#x0B43] | [#x0B47-#x0B48] | [#x0B4B-#x0B4D] | +[#x0B56-#x0B57] | [#x0B82-#x0B83] | [#x0BBE-#x0BC2] | [#x0BC6-#x0BC8] | +[#x0BCA-#x0BCD] | #x0BD7 | [#x0C01-#x0C03] | [#x0C3E-#x0C44] | +[#x0C46-#x0C48] | [#x0C4A-#x0C4D] | [#x0C55-#x0C56] | [#x0C82-#x0C83] | +[#x0CBE-#x0CC4] | [#x0CC6-#x0CC8] | [#x0CCA-#x0CCD] | [#x0CD5-#x0CD6] | +[#x0D02-#x0D03] | [#x0D3E-#x0D43] | [#x0D46-#x0D48] | [#x0D4A-#x0D4D] | +#x0D57 | #x0E31 | [#x0E34-#x0E3A] | [#x0E47-#x0E4E] | #x0EB1 | +[#x0EB4-#x0EB9] | [#x0EBB-#x0EBC] | [#x0EC8-#x0ECD] | [#x0F18-#x0F19] | +#x0F35 | #x0F37 | #x0F39 | #x0F3E | #x0F3F | [#x0F71-#x0F84] | +[#x0F86-#x0F8B] | [#x0F90-#x0F95] | #x0F97 | [#x0F99-#x0FAD] | +[#x0FB1-#x0FB7] | #x0FB9 | [#x20D0-#x20DC] | #x20E1 | [#x302A-#x302F] | +#x3099 | #x309A""" + +digit = """ +[#x0030-#x0039] | [#x0660-#x0669] | [#x06F0-#x06F9] | [#x0966-#x096F] | +[#x09E6-#x09EF] | [#x0A66-#x0A6F] | [#x0AE6-#x0AEF] | [#x0B66-#x0B6F] | +[#x0BE7-#x0BEF] | [#x0C66-#x0C6F] | [#x0CE6-#x0CEF] | [#x0D66-#x0D6F] | +[#x0E50-#x0E59] | [#x0ED0-#x0ED9] | [#x0F20-#x0F29]""" + +extender = """ +#x00B7 | #x02D0 | #x02D1 | #x0387 | #x0640 | #x0E46 | #x0EC6 | #x3005 | +#[#x3031-#x3035] | [#x309D-#x309E] | [#x30FC-#x30FE]""" + +letter = " | ".join([baseChar, ideographic]) + +# Without the +name = " | ".join([letter, digit, ".", "-", "_", combiningCharacter, + extender]) +nameFirst = " | ".join([letter, "_"]) + +reChar = re.compile(r"#x([\d|A-F]{4,4})") +reCharRange = re.compile(r"\[#x([\d|A-F]{4,4})-#x([\d|A-F]{4,4})\]") + + +def charStringToList(chars): + charRanges = [item.strip() for item in chars.split(" | ")] + rv = [] + for item in charRanges: + foundMatch = False + for regexp in (reChar, reCharRange): + match = regexp.match(item) + if match is not None: + rv.append([hexToInt(item) for item in match.groups()]) + if len(rv[-1]) == 1: + rv[-1] = rv[-1] * 2 + foundMatch = True + break + if not foundMatch: + assert len(item) == 1 + + rv.append([ord(item)] * 2) + rv = normaliseCharList(rv) + return rv + + +def normaliseCharList(charList): + charList = sorted(charList) + for item in charList: + assert item[1] >= item[0] + rv = [] + i = 0 + while i < len(charList): + j = 1 + rv.append(charList[i]) + while i + j < len(charList) and charList[i + j][0] <= rv[-1][1] + 1: + rv[-1][1] = charList[i + j][1] + j += 1 + i += j + return rv + + +# We don't really support characters above the BMP :( +max_unicode = int("FFFF", 16) + + +def missingRanges(charList): + rv = [] + if charList[0] != 0: + rv.append([0, charList[0][0] - 1]) + for i, item in enumerate(charList[:-1]): + rv.append([item[1] + 1, charList[i + 1][0] - 1]) + if charList[-1][1] != max_unicode: + rv.append([charList[-1][1] + 1, max_unicode]) + return rv + + +def listToRegexpStr(charList): + rv = [] + for item in charList: + if item[0] == item[1]: + rv.append(escapeRegexp(chr(item[0]))) + else: + rv.append(escapeRegexp(chr(item[0])) + "-" + + escapeRegexp(chr(item[1]))) + return "[%s]" % "".join(rv) + + +def hexToInt(hex_str): + return int(hex_str, 16) + + +def escapeRegexp(string): + specialCharacters = (".", "^", "$", "*", "+", "?", "{", "}", + "[", "]", "|", "(", ")", "-") + for char in specialCharacters: + string = string.replace(char, "\\" + char) + + return string + +# output from the above +nonXmlNameBMPRegexp = re.compile('[\x00-,/:-@\\[-\\^`\\{-\xb6\xb8-\xbf\xd7\xf7\u0132-\u0133\u013f-\u0140\u0149\u017f\u01c4-\u01cc\u01f1-\u01f3\u01f6-\u01f9\u0218-\u024f\u02a9-\u02ba\u02c2-\u02cf\u02d2-\u02ff\u0346-\u035f\u0362-\u0385\u038b\u038d\u03a2\u03cf\u03d7-\u03d9\u03db\u03dd\u03df\u03e1\u03f4-\u0400\u040d\u0450\u045d\u0482\u0487-\u048f\u04c5-\u04c6\u04c9-\u04ca\u04cd-\u04cf\u04ec-\u04ed\u04f6-\u04f7\u04fa-\u0530\u0557-\u0558\u055a-\u0560\u0587-\u0590\u05a2\u05ba\u05be\u05c0\u05c3\u05c5-\u05cf\u05eb-\u05ef\u05f3-\u0620\u063b-\u063f\u0653-\u065f\u066a-\u066f\u06b8-\u06b9\u06bf\u06cf\u06d4\u06e9\u06ee-\u06ef\u06fa-\u0900\u0904\u093a-\u093b\u094e-\u0950\u0955-\u0957\u0964-\u0965\u0970-\u0980\u0984\u098d-\u098e\u0991-\u0992\u09a9\u09b1\u09b3-\u09b5\u09ba-\u09bb\u09bd\u09c5-\u09c6\u09c9-\u09ca\u09ce-\u09d6\u09d8-\u09db\u09de\u09e4-\u09e5\u09f2-\u0a01\u0a03-\u0a04\u0a0b-\u0a0e\u0a11-\u0a12\u0a29\u0a31\u0a34\u0a37\u0a3a-\u0a3b\u0a3d\u0a43-\u0a46\u0a49-\u0a4a\u0a4e-\u0a58\u0a5d\u0a5f-\u0a65\u0a75-\u0a80\u0a84\u0a8c\u0a8e\u0a92\u0aa9\u0ab1\u0ab4\u0aba-\u0abb\u0ac6\u0aca\u0ace-\u0adf\u0ae1-\u0ae5\u0af0-\u0b00\u0b04\u0b0d-\u0b0e\u0b11-\u0b12\u0b29\u0b31\u0b34-\u0b35\u0b3a-\u0b3b\u0b44-\u0b46\u0b49-\u0b4a\u0b4e-\u0b55\u0b58-\u0b5b\u0b5e\u0b62-\u0b65\u0b70-\u0b81\u0b84\u0b8b-\u0b8d\u0b91\u0b96-\u0b98\u0b9b\u0b9d\u0ba0-\u0ba2\u0ba5-\u0ba7\u0bab-\u0bad\u0bb6\u0bba-\u0bbd\u0bc3-\u0bc5\u0bc9\u0bce-\u0bd6\u0bd8-\u0be6\u0bf0-\u0c00\u0c04\u0c0d\u0c11\u0c29\u0c34\u0c3a-\u0c3d\u0c45\u0c49\u0c4e-\u0c54\u0c57-\u0c5f\u0c62-\u0c65\u0c70-\u0c81\u0c84\u0c8d\u0c91\u0ca9\u0cb4\u0cba-\u0cbd\u0cc5\u0cc9\u0cce-\u0cd4\u0cd7-\u0cdd\u0cdf\u0ce2-\u0ce5\u0cf0-\u0d01\u0d04\u0d0d\u0d11\u0d29\u0d3a-\u0d3d\u0d44-\u0d45\u0d49\u0d4e-\u0d56\u0d58-\u0d5f\u0d62-\u0d65\u0d70-\u0e00\u0e2f\u0e3b-\u0e3f\u0e4f\u0e5a-\u0e80\u0e83\u0e85-\u0e86\u0e89\u0e8b-\u0e8c\u0e8e-\u0e93\u0e98\u0ea0\u0ea4\u0ea6\u0ea8-\u0ea9\u0eac\u0eaf\u0eba\u0ebe-\u0ebf\u0ec5\u0ec7\u0ece-\u0ecf\u0eda-\u0f17\u0f1a-\u0f1f\u0f2a-\u0f34\u0f36\u0f38\u0f3a-\u0f3d\u0f48\u0f6a-\u0f70\u0f85\u0f8c-\u0f8f\u0f96\u0f98\u0fae-\u0fb0\u0fb8\u0fba-\u109f\u10c6-\u10cf\u10f7-\u10ff\u1101\u1104\u1108\u110a\u110d\u1113-\u113b\u113d\u113f\u1141-\u114b\u114d\u114f\u1151-\u1153\u1156-\u1158\u115a-\u115e\u1162\u1164\u1166\u1168\u116a-\u116c\u116f-\u1171\u1174\u1176-\u119d\u119f-\u11a7\u11a9-\u11aa\u11ac-\u11ad\u11b0-\u11b6\u11b9\u11bb\u11c3-\u11ea\u11ec-\u11ef\u11f1-\u11f8\u11fa-\u1dff\u1e9c-\u1e9f\u1efa-\u1eff\u1f16-\u1f17\u1f1e-\u1f1f\u1f46-\u1f47\u1f4e-\u1f4f\u1f58\u1f5a\u1f5c\u1f5e\u1f7e-\u1f7f\u1fb5\u1fbd\u1fbf-\u1fc1\u1fc5\u1fcd-\u1fcf\u1fd4-\u1fd5\u1fdc-\u1fdf\u1fed-\u1ff1\u1ff5\u1ffd-\u20cf\u20dd-\u20e0\u20e2-\u2125\u2127-\u2129\u212c-\u212d\u212f-\u217f\u2183-\u3004\u3006\u3008-\u3020\u3030\u3036-\u3040\u3095-\u3098\u309b-\u309c\u309f-\u30a0\u30fb\u30ff-\u3104\u312d-\u4dff\u9fa6-\uabff\ud7a4-\uffff]') # noqa + +nonXmlNameFirstBMPRegexp = re.compile('[\x00-@\\[-\\^`\\{-\xbf\xd7\xf7\u0132-\u0133\u013f-\u0140\u0149\u017f\u01c4-\u01cc\u01f1-\u01f3\u01f6-\u01f9\u0218-\u024f\u02a9-\u02ba\u02c2-\u0385\u0387\u038b\u038d\u03a2\u03cf\u03d7-\u03d9\u03db\u03dd\u03df\u03e1\u03f4-\u0400\u040d\u0450\u045d\u0482-\u048f\u04c5-\u04c6\u04c9-\u04ca\u04cd-\u04cf\u04ec-\u04ed\u04f6-\u04f7\u04fa-\u0530\u0557-\u0558\u055a-\u0560\u0587-\u05cf\u05eb-\u05ef\u05f3-\u0620\u063b-\u0640\u064b-\u0670\u06b8-\u06b9\u06bf\u06cf\u06d4\u06d6-\u06e4\u06e7-\u0904\u093a-\u093c\u093e-\u0957\u0962-\u0984\u098d-\u098e\u0991-\u0992\u09a9\u09b1\u09b3-\u09b5\u09ba-\u09db\u09de\u09e2-\u09ef\u09f2-\u0a04\u0a0b-\u0a0e\u0a11-\u0a12\u0a29\u0a31\u0a34\u0a37\u0a3a-\u0a58\u0a5d\u0a5f-\u0a71\u0a75-\u0a84\u0a8c\u0a8e\u0a92\u0aa9\u0ab1\u0ab4\u0aba-\u0abc\u0abe-\u0adf\u0ae1-\u0b04\u0b0d-\u0b0e\u0b11-\u0b12\u0b29\u0b31\u0b34-\u0b35\u0b3a-\u0b3c\u0b3e-\u0b5b\u0b5e\u0b62-\u0b84\u0b8b-\u0b8d\u0b91\u0b96-\u0b98\u0b9b\u0b9d\u0ba0-\u0ba2\u0ba5-\u0ba7\u0bab-\u0bad\u0bb6\u0bba-\u0c04\u0c0d\u0c11\u0c29\u0c34\u0c3a-\u0c5f\u0c62-\u0c84\u0c8d\u0c91\u0ca9\u0cb4\u0cba-\u0cdd\u0cdf\u0ce2-\u0d04\u0d0d\u0d11\u0d29\u0d3a-\u0d5f\u0d62-\u0e00\u0e2f\u0e31\u0e34-\u0e3f\u0e46-\u0e80\u0e83\u0e85-\u0e86\u0e89\u0e8b-\u0e8c\u0e8e-\u0e93\u0e98\u0ea0\u0ea4\u0ea6\u0ea8-\u0ea9\u0eac\u0eaf\u0eb1\u0eb4-\u0ebc\u0ebe-\u0ebf\u0ec5-\u0f3f\u0f48\u0f6a-\u109f\u10c6-\u10cf\u10f7-\u10ff\u1101\u1104\u1108\u110a\u110d\u1113-\u113b\u113d\u113f\u1141-\u114b\u114d\u114f\u1151-\u1153\u1156-\u1158\u115a-\u115e\u1162\u1164\u1166\u1168\u116a-\u116c\u116f-\u1171\u1174\u1176-\u119d\u119f-\u11a7\u11a9-\u11aa\u11ac-\u11ad\u11b0-\u11b6\u11b9\u11bb\u11c3-\u11ea\u11ec-\u11ef\u11f1-\u11f8\u11fa-\u1dff\u1e9c-\u1e9f\u1efa-\u1eff\u1f16-\u1f17\u1f1e-\u1f1f\u1f46-\u1f47\u1f4e-\u1f4f\u1f58\u1f5a\u1f5c\u1f5e\u1f7e-\u1f7f\u1fb5\u1fbd\u1fbf-\u1fc1\u1fc5\u1fcd-\u1fcf\u1fd4-\u1fd5\u1fdc-\u1fdf\u1fed-\u1ff1\u1ff5\u1ffd-\u2125\u2127-\u2129\u212c-\u212d\u212f-\u217f\u2183-\u3006\u3008-\u3020\u302a-\u3040\u3095-\u30a0\u30fb-\u3104\u312d-\u4dff\u9fa6-\uabff\ud7a4-\uffff]') # noqa + +# Simpler things +nonPubidCharRegexp = re.compile("[^\x20\x0D\x0Aa-zA-Z0-9\\-'()+,./:=?;!*#@$_%]") + + +class InfosetFilter(object): + replacementRegexp = re.compile(r"U[\dA-F]{5,5}") + + def __init__(self, + dropXmlnsLocalName=False, + dropXmlnsAttrNs=False, + preventDoubleDashComments=False, + preventDashAtCommentEnd=False, + replaceFormFeedCharacters=True, + preventSingleQuotePubid=False): + + self.dropXmlnsLocalName = dropXmlnsLocalName + self.dropXmlnsAttrNs = dropXmlnsAttrNs + + self.preventDoubleDashComments = preventDoubleDashComments + self.preventDashAtCommentEnd = preventDashAtCommentEnd + + self.replaceFormFeedCharacters = replaceFormFeedCharacters + + self.preventSingleQuotePubid = preventSingleQuotePubid + + self.replaceCache = {} + + def coerceAttribute(self, name, namespace=None): + if self.dropXmlnsLocalName and name.startswith("xmlns:"): + warnings.warn("Attributes cannot begin with xmlns", DataLossWarning) + return None + elif (self.dropXmlnsAttrNs and + namespace == "http://www.w3.org/2000/xmlns/"): + warnings.warn("Attributes cannot be in the xml namespace", DataLossWarning) + return None + else: + return self.toXmlName(name) + + def coerceElement(self, name): + return self.toXmlName(name) + + def coerceComment(self, data): + if self.preventDoubleDashComments: + while "--" in data: + warnings.warn("Comments cannot contain adjacent dashes", DataLossWarning) + data = data.replace("--", "- -") + if data.endswith("-"): + warnings.warn("Comments cannot end in a dash", DataLossWarning) + data += " " + return data + + def coerceCharacters(self, data): + if self.replaceFormFeedCharacters: + for _ in range(data.count("\x0C")): + warnings.warn("Text cannot contain U+000C", DataLossWarning) + data = data.replace("\x0C", " ") + # Other non-xml characters + return data + + def coercePubid(self, data): + dataOutput = data + for char in nonPubidCharRegexp.findall(data): + warnings.warn("Coercing non-XML pubid", DataLossWarning) + replacement = self.getReplacementCharacter(char) + dataOutput = dataOutput.replace(char, replacement) + if self.preventSingleQuotePubid and dataOutput.find("'") >= 0: + warnings.warn("Pubid cannot contain single quote", DataLossWarning) + dataOutput = dataOutput.replace("'", self.getReplacementCharacter("'")) + return dataOutput + + def toXmlName(self, name): + nameFirst = name[0] + nameRest = name[1:] + m = nonXmlNameFirstBMPRegexp.match(nameFirst) + if m: + warnings.warn("Coercing non-XML name: %s" % name, DataLossWarning) + nameFirstOutput = self.getReplacementCharacter(nameFirst) + else: + nameFirstOutput = nameFirst + + nameRestOutput = nameRest + replaceChars = set(nonXmlNameBMPRegexp.findall(nameRest)) + for char in replaceChars: + warnings.warn("Coercing non-XML name: %s" % name, DataLossWarning) + replacement = self.getReplacementCharacter(char) + nameRestOutput = nameRestOutput.replace(char, replacement) + return nameFirstOutput + nameRestOutput + + def getReplacementCharacter(self, char): + if char in self.replaceCache: + replacement = self.replaceCache[char] + else: + replacement = self.escapeChar(char) + return replacement + + def fromXmlName(self, name): + for item in set(self.replacementRegexp.findall(name)): + name = name.replace(item, self.unescapeChar(item)) + return name + + def escapeChar(self, char): + replacement = "U%05X" % ord(char) + self.replaceCache[char] = replacement + return replacement + + def unescapeChar(self, charcode): + return chr(int(charcode[1:], 16)) diff --git a/venv/Lib/site-packages/pip/_vendor/html5lib/_inputstream.py b/venv/Lib/site-packages/pip/_vendor/html5lib/_inputstream.py new file mode 100644 index 0000000..e0bb376 --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/html5lib/_inputstream.py @@ -0,0 +1,918 @@ +from __future__ import absolute_import, division, unicode_literals + +from pip._vendor.six import text_type +from pip._vendor.six.moves import http_client, urllib + +import codecs +import re +from io import BytesIO, StringIO + +from pip._vendor import webencodings + +from .constants import EOF, spaceCharacters, asciiLetters, asciiUppercase +from .constants import _ReparseException +from . import _utils + +# Non-unicode versions of constants for use in the pre-parser +spaceCharactersBytes = frozenset([item.encode("ascii") for item in spaceCharacters]) +asciiLettersBytes = frozenset([item.encode("ascii") for item in asciiLetters]) +asciiUppercaseBytes = frozenset([item.encode("ascii") for item in asciiUppercase]) +spacesAngleBrackets = spaceCharactersBytes | frozenset([b">", b"<"]) + + +invalid_unicode_no_surrogate = "[\u0001-\u0008\u000B\u000E-\u001F\u007F-\u009F\uFDD0-\uFDEF\uFFFE\uFFFF\U0001FFFE\U0001FFFF\U0002FFFE\U0002FFFF\U0003FFFE\U0003FFFF\U0004FFFE\U0004FFFF\U0005FFFE\U0005FFFF\U0006FFFE\U0006FFFF\U0007FFFE\U0007FFFF\U0008FFFE\U0008FFFF\U0009FFFE\U0009FFFF\U000AFFFE\U000AFFFF\U000BFFFE\U000BFFFF\U000CFFFE\U000CFFFF\U000DFFFE\U000DFFFF\U000EFFFE\U000EFFFF\U000FFFFE\U000FFFFF\U0010FFFE\U0010FFFF]" # noqa + +if _utils.supports_lone_surrogates: + # Use one extra step of indirection and create surrogates with + # eval. Not using this indirection would introduce an illegal + # unicode literal on platforms not supporting such lone + # surrogates. + assert invalid_unicode_no_surrogate[-1] == "]" and invalid_unicode_no_surrogate.count("]") == 1 + invalid_unicode_re = re.compile(invalid_unicode_no_surrogate[:-1] + + eval('"\\uD800-\\uDFFF"') + # pylint:disable=eval-used + "]") +else: + invalid_unicode_re = re.compile(invalid_unicode_no_surrogate) + +non_bmp_invalid_codepoints = {0x1FFFE, 0x1FFFF, 0x2FFFE, 0x2FFFF, 0x3FFFE, + 0x3FFFF, 0x4FFFE, 0x4FFFF, 0x5FFFE, 0x5FFFF, + 0x6FFFE, 0x6FFFF, 0x7FFFE, 0x7FFFF, 0x8FFFE, + 0x8FFFF, 0x9FFFE, 0x9FFFF, 0xAFFFE, 0xAFFFF, + 0xBFFFE, 0xBFFFF, 0xCFFFE, 0xCFFFF, 0xDFFFE, + 0xDFFFF, 0xEFFFE, 0xEFFFF, 0xFFFFE, 0xFFFFF, + 0x10FFFE, 0x10FFFF} + +ascii_punctuation_re = re.compile("[\u0009-\u000D\u0020-\u002F\u003A-\u0040\u005C\u005B-\u0060\u007B-\u007E]") + +# Cache for charsUntil() +charsUntilRegEx = {} + + +class BufferedStream(object): + """Buffering for streams that do not have buffering of their own + + The buffer is implemented as a list of chunks on the assumption that + joining many strings will be slow since it is O(n**2) + """ + + def __init__(self, stream): + self.stream = stream + self.buffer = [] + self.position = [-1, 0] # chunk number, offset + + def tell(self): + pos = 0 + for chunk in self.buffer[:self.position[0]]: + pos += len(chunk) + pos += self.position[1] + return pos + + def seek(self, pos): + assert pos <= self._bufferedBytes() + offset = pos + i = 0 + while len(self.buffer[i]) < offset: + offset -= len(self.buffer[i]) + i += 1 + self.position = [i, offset] + + def read(self, bytes): + if not self.buffer: + return self._readStream(bytes) + elif (self.position[0] == len(self.buffer) and + self.position[1] == len(self.buffer[-1])): + return self._readStream(bytes) + else: + return self._readFromBuffer(bytes) + + def _bufferedBytes(self): + return sum([len(item) for item in self.buffer]) + + def _readStream(self, bytes): + data = self.stream.read(bytes) + self.buffer.append(data) + self.position[0] += 1 + self.position[1] = len(data) + return data + + def _readFromBuffer(self, bytes): + remainingBytes = bytes + rv = [] + bufferIndex = self.position[0] + bufferOffset = self.position[1] + while bufferIndex < len(self.buffer) and remainingBytes != 0: + assert remainingBytes > 0 + bufferedData = self.buffer[bufferIndex] + + if remainingBytes <= len(bufferedData) - bufferOffset: + bytesToRead = remainingBytes + self.position = [bufferIndex, bufferOffset + bytesToRead] + else: + bytesToRead = len(bufferedData) - bufferOffset + self.position = [bufferIndex, len(bufferedData)] + bufferIndex += 1 + rv.append(bufferedData[bufferOffset:bufferOffset + bytesToRead]) + remainingBytes -= bytesToRead + + bufferOffset = 0 + + if remainingBytes: + rv.append(self._readStream(remainingBytes)) + + return b"".join(rv) + + +def HTMLInputStream(source, **kwargs): + # Work around Python bug #20007: read(0) closes the connection. + # http://bugs.python.org/issue20007 + if (isinstance(source, http_client.HTTPResponse) or + # Also check for addinfourl wrapping HTTPResponse + (isinstance(source, urllib.response.addbase) and + isinstance(source.fp, http_client.HTTPResponse))): + isUnicode = False + elif hasattr(source, "read"): + isUnicode = isinstance(source.read(0), text_type) + else: + isUnicode = isinstance(source, text_type) + + if isUnicode: + encodings = [x for x in kwargs if x.endswith("_encoding")] + if encodings: + raise TypeError("Cannot set an encoding with a unicode input, set %r" % encodings) + + return HTMLUnicodeInputStream(source, **kwargs) + else: + return HTMLBinaryInputStream(source, **kwargs) + + +class HTMLUnicodeInputStream(object): + """Provides a unicode stream of characters to the HTMLTokenizer. + + This class takes care of character encoding and removing or replacing + incorrect byte-sequences and also provides column and line tracking. + + """ + + _defaultChunkSize = 10240 + + def __init__(self, source): + """Initialises the HTMLInputStream. + + HTMLInputStream(source, [encoding]) -> Normalized stream from source + for use by html5lib. + + source can be either a file-object, local filename or a string. + + The optional encoding parameter must be a string that indicates + the encoding. If specified, that encoding will be used, + regardless of any BOM or later declaration (such as in a meta + element) + + """ + + if not _utils.supports_lone_surrogates: + # Such platforms will have already checked for such + # surrogate errors, so no need to do this checking. + self.reportCharacterErrors = None + elif len("\U0010FFFF") == 1: + self.reportCharacterErrors = self.characterErrorsUCS4 + else: + self.reportCharacterErrors = self.characterErrorsUCS2 + + # List of where new lines occur + self.newLines = [0] + + self.charEncoding = (lookupEncoding("utf-8"), "certain") + self.dataStream = self.openStream(source) + + self.reset() + + def reset(self): + self.chunk = "" + self.chunkSize = 0 + self.chunkOffset = 0 + self.errors = [] + + # number of (complete) lines in previous chunks + self.prevNumLines = 0 + # number of columns in the last line of the previous chunk + self.prevNumCols = 0 + + # Deal with CR LF and surrogates split over chunk boundaries + self._bufferedCharacter = None + + def openStream(self, source): + """Produces a file object from source. + + source can be either a file object, local filename or a string. + + """ + # Already a file object + if hasattr(source, 'read'): + stream = source + else: + stream = StringIO(source) + + return stream + + def _position(self, offset): + chunk = self.chunk + nLines = chunk.count('\n', 0, offset) + positionLine = self.prevNumLines + nLines + lastLinePos = chunk.rfind('\n', 0, offset) + if lastLinePos == -1: + positionColumn = self.prevNumCols + offset + else: + positionColumn = offset - (lastLinePos + 1) + return (positionLine, positionColumn) + + def position(self): + """Returns (line, col) of the current position in the stream.""" + line, col = self._position(self.chunkOffset) + return (line + 1, col) + + def char(self): + """ Read one character from the stream or queue if available. Return + EOF when EOF is reached. + """ + # Read a new chunk from the input stream if necessary + if self.chunkOffset >= self.chunkSize: + if not self.readChunk(): + return EOF + + chunkOffset = self.chunkOffset + char = self.chunk[chunkOffset] + self.chunkOffset = chunkOffset + 1 + + return char + + def readChunk(self, chunkSize=None): + if chunkSize is None: + chunkSize = self._defaultChunkSize + + self.prevNumLines, self.prevNumCols = self._position(self.chunkSize) + + self.chunk = "" + self.chunkSize = 0 + self.chunkOffset = 0 + + data = self.dataStream.read(chunkSize) + + # Deal with CR LF and surrogates broken across chunks + if self._bufferedCharacter: + data = self._bufferedCharacter + data + self._bufferedCharacter = None + elif not data: + # We have no more data, bye-bye stream + return False + + if len(data) > 1: + lastv = ord(data[-1]) + if lastv == 0x0D or 0xD800 <= lastv <= 0xDBFF: + self._bufferedCharacter = data[-1] + data = data[:-1] + + if self.reportCharacterErrors: + self.reportCharacterErrors(data) + + # Replace invalid characters + data = data.replace("\r\n", "\n") + data = data.replace("\r", "\n") + + self.chunk = data + self.chunkSize = len(data) + + return True + + def characterErrorsUCS4(self, data): + for _ in range(len(invalid_unicode_re.findall(data))): + self.errors.append("invalid-codepoint") + + def characterErrorsUCS2(self, data): + # Someone picked the wrong compile option + # You lose + skip = False + for match in invalid_unicode_re.finditer(data): + if skip: + continue + codepoint = ord(match.group()) + pos = match.start() + # Pretty sure there should be endianness issues here + if _utils.isSurrogatePair(data[pos:pos + 2]): + # We have a surrogate pair! + char_val = _utils.surrogatePairToCodepoint(data[pos:pos + 2]) + if char_val in non_bmp_invalid_codepoints: + self.errors.append("invalid-codepoint") + skip = True + elif (codepoint >= 0xD800 and codepoint <= 0xDFFF and + pos == len(data) - 1): + self.errors.append("invalid-codepoint") + else: + skip = False + self.errors.append("invalid-codepoint") + + def charsUntil(self, characters, opposite=False): + """ Returns a string of characters from the stream up to but not + including any character in 'characters' or EOF. 'characters' must be + a container that supports the 'in' method and iteration over its + characters. + """ + + # Use a cache of regexps to find the required characters + try: + chars = charsUntilRegEx[(characters, opposite)] + except KeyError: + if __debug__: + for c in characters: + assert(ord(c) < 128) + regex = "".join(["\\x%02x" % ord(c) for c in characters]) + if not opposite: + regex = "^%s" % regex + chars = charsUntilRegEx[(characters, opposite)] = re.compile("[%s]+" % regex) + + rv = [] + + while True: + # Find the longest matching prefix + m = chars.match(self.chunk, self.chunkOffset) + if m is None: + # If nothing matched, and it wasn't because we ran out of chunk, + # then stop + if self.chunkOffset != self.chunkSize: + break + else: + end = m.end() + # If not the whole chunk matched, return everything + # up to the part that didn't match + if end != self.chunkSize: + rv.append(self.chunk[self.chunkOffset:end]) + self.chunkOffset = end + break + # If the whole remainder of the chunk matched, + # use it all and read the next chunk + rv.append(self.chunk[self.chunkOffset:]) + if not self.readChunk(): + # Reached EOF + break + + r = "".join(rv) + return r + + def unget(self, char): + # Only one character is allowed to be ungotten at once - it must + # be consumed again before any further call to unget + if char is not EOF: + if self.chunkOffset == 0: + # unget is called quite rarely, so it's a good idea to do + # more work here if it saves a bit of work in the frequently + # called char and charsUntil. + # So, just prepend the ungotten character onto the current + # chunk: + self.chunk = char + self.chunk + self.chunkSize += 1 + else: + self.chunkOffset -= 1 + assert self.chunk[self.chunkOffset] == char + + +class HTMLBinaryInputStream(HTMLUnicodeInputStream): + """Provides a unicode stream of characters to the HTMLTokenizer. + + This class takes care of character encoding and removing or replacing + incorrect byte-sequences and also provides column and line tracking. + + """ + + def __init__(self, source, override_encoding=None, transport_encoding=None, + same_origin_parent_encoding=None, likely_encoding=None, + default_encoding="windows-1252", useChardet=True): + """Initialises the HTMLInputStream. + + HTMLInputStream(source, [encoding]) -> Normalized stream from source + for use by html5lib. + + source can be either a file-object, local filename or a string. + + The optional encoding parameter must be a string that indicates + the encoding. If specified, that encoding will be used, + regardless of any BOM or later declaration (such as in a meta + element) + + """ + # Raw Stream - for unicode objects this will encode to utf-8 and set + # self.charEncoding as appropriate + self.rawStream = self.openStream(source) + + HTMLUnicodeInputStream.__init__(self, self.rawStream) + + # Encoding Information + # Number of bytes to use when looking for a meta element with + # encoding information + self.numBytesMeta = 1024 + # Number of bytes to use when using detecting encoding using chardet + self.numBytesChardet = 100 + # Things from args + self.override_encoding = override_encoding + self.transport_encoding = transport_encoding + self.same_origin_parent_encoding = same_origin_parent_encoding + self.likely_encoding = likely_encoding + self.default_encoding = default_encoding + + # Determine encoding + self.charEncoding = self.determineEncoding(useChardet) + assert self.charEncoding[0] is not None + + # Call superclass + self.reset() + + def reset(self): + self.dataStream = self.charEncoding[0].codec_info.streamreader(self.rawStream, 'replace') + HTMLUnicodeInputStream.reset(self) + + def openStream(self, source): + """Produces a file object from source. + + source can be either a file object, local filename or a string. + + """ + # Already a file object + if hasattr(source, 'read'): + stream = source + else: + stream = BytesIO(source) + + try: + stream.seek(stream.tell()) + except Exception: + stream = BufferedStream(stream) + + return stream + + def determineEncoding(self, chardet=True): + # BOMs take precedence over everything + # This will also read past the BOM if present + charEncoding = self.detectBOM(), "certain" + if charEncoding[0] is not None: + return charEncoding + + # If we've been overridden, we've been overridden + charEncoding = lookupEncoding(self.override_encoding), "certain" + if charEncoding[0] is not None: + return charEncoding + + # Now check the transport layer + charEncoding = lookupEncoding(self.transport_encoding), "certain" + if charEncoding[0] is not None: + return charEncoding + + # Look for meta elements with encoding information + charEncoding = self.detectEncodingMeta(), "tentative" + if charEncoding[0] is not None: + return charEncoding + + # Parent document encoding + charEncoding = lookupEncoding(self.same_origin_parent_encoding), "tentative" + if charEncoding[0] is not None and not charEncoding[0].name.startswith("utf-16"): + return charEncoding + + # "likely" encoding + charEncoding = lookupEncoding(self.likely_encoding), "tentative" + if charEncoding[0] is not None: + return charEncoding + + # Guess with chardet, if available + if chardet: + try: + from pip._vendor.chardet.universaldetector import UniversalDetector + except ImportError: + pass + else: + buffers = [] + detector = UniversalDetector() + while not detector.done: + buffer = self.rawStream.read(self.numBytesChardet) + assert isinstance(buffer, bytes) + if not buffer: + break + buffers.append(buffer) + detector.feed(buffer) + detector.close() + encoding = lookupEncoding(detector.result['encoding']) + self.rawStream.seek(0) + if encoding is not None: + return encoding, "tentative" + + # Try the default encoding + charEncoding = lookupEncoding(self.default_encoding), "tentative" + if charEncoding[0] is not None: + return charEncoding + + # Fallback to html5lib's default if even that hasn't worked + return lookupEncoding("windows-1252"), "tentative" + + def changeEncoding(self, newEncoding): + assert self.charEncoding[1] != "certain" + newEncoding = lookupEncoding(newEncoding) + if newEncoding is None: + return + if newEncoding.name in ("utf-16be", "utf-16le"): + newEncoding = lookupEncoding("utf-8") + assert newEncoding is not None + elif newEncoding == self.charEncoding[0]: + self.charEncoding = (self.charEncoding[0], "certain") + else: + self.rawStream.seek(0) + self.charEncoding = (newEncoding, "certain") + self.reset() + raise _ReparseException("Encoding changed from %s to %s" % (self.charEncoding[0], newEncoding)) + + def detectBOM(self): + """Attempts to detect at BOM at the start of the stream. If + an encoding can be determined from the BOM return the name of the + encoding otherwise return None""" + bomDict = { + codecs.BOM_UTF8: 'utf-8', + codecs.BOM_UTF16_LE: 'utf-16le', codecs.BOM_UTF16_BE: 'utf-16be', + codecs.BOM_UTF32_LE: 'utf-32le', codecs.BOM_UTF32_BE: 'utf-32be' + } + + # Go to beginning of file and read in 4 bytes + string = self.rawStream.read(4) + assert isinstance(string, bytes) + + # Try detecting the BOM using bytes from the string + encoding = bomDict.get(string[:3]) # UTF-8 + seek = 3 + if not encoding: + # Need to detect UTF-32 before UTF-16 + encoding = bomDict.get(string) # UTF-32 + seek = 4 + if not encoding: + encoding = bomDict.get(string[:2]) # UTF-16 + seek = 2 + + # Set the read position past the BOM if one was found, otherwise + # set it to the start of the stream + if encoding: + self.rawStream.seek(seek) + return lookupEncoding(encoding) + else: + self.rawStream.seek(0) + return None + + def detectEncodingMeta(self): + """Report the encoding declared by the meta element + """ + buffer = self.rawStream.read(self.numBytesMeta) + assert isinstance(buffer, bytes) + parser = EncodingParser(buffer) + self.rawStream.seek(0) + encoding = parser.getEncoding() + + if encoding is not None and encoding.name in ("utf-16be", "utf-16le"): + encoding = lookupEncoding("utf-8") + + return encoding + + +class EncodingBytes(bytes): + """String-like object with an associated position and various extra methods + If the position is ever greater than the string length then an exception is + raised""" + def __new__(self, value): + assert isinstance(value, bytes) + return bytes.__new__(self, value.lower()) + + def __init__(self, value): + # pylint:disable=unused-argument + self._position = -1 + + def __iter__(self): + return self + + def __next__(self): + p = self._position = self._position + 1 + if p >= len(self): + raise StopIteration + elif p < 0: + raise TypeError + return self[p:p + 1] + + def next(self): + # Py2 compat + return self.__next__() + + def previous(self): + p = self._position + if p >= len(self): + raise StopIteration + elif p < 0: + raise TypeError + self._position = p = p - 1 + return self[p:p + 1] + + def setPosition(self, position): + if self._position >= len(self): + raise StopIteration + self._position = position + + def getPosition(self): + if self._position >= len(self): + raise StopIteration + if self._position >= 0: + return self._position + else: + return None + + position = property(getPosition, setPosition) + + def getCurrentByte(self): + return self[self.position:self.position + 1] + + currentByte = property(getCurrentByte) + + def skip(self, chars=spaceCharactersBytes): + """Skip past a list of characters""" + p = self.position # use property for the error-checking + while p < len(self): + c = self[p:p + 1] + if c not in chars: + self._position = p + return c + p += 1 + self._position = p + return None + + def skipUntil(self, chars): + p = self.position + while p < len(self): + c = self[p:p + 1] + if c in chars: + self._position = p + return c + p += 1 + self._position = p + return None + + def matchBytes(self, bytes): + """Look for a sequence of bytes at the start of a string. If the bytes + are found return True and advance the position to the byte after the + match. Otherwise return False and leave the position alone""" + rv = self.startswith(bytes, self.position) + if rv: + self.position += len(bytes) + return rv + + def jumpTo(self, bytes): + """Look for the next sequence of bytes matching a given sequence. If + a match is found advance the position to the last byte of the match""" + try: + self._position = self.index(bytes, self.position) + len(bytes) - 1 + except ValueError: + raise StopIteration + return True + + +class EncodingParser(object): + """Mini parser for detecting character encoding from meta elements""" + + def __init__(self, data): + """string - the data to work on for encoding detection""" + self.data = EncodingBytes(data) + self.encoding = None + + def getEncoding(self): + if b"") + + def handleMeta(self): + if self.data.currentByte not in spaceCharactersBytes: + # if we have ") + + def getAttribute(self): + """Return a name,value pair for the next attribute in the stream, + if one is found, or None""" + data = self.data + # Step 1 (skip chars) + c = data.skip(spaceCharactersBytes | frozenset([b"/"])) + assert c is None or len(c) == 1 + # Step 2 + if c in (b">", None): + return None + # Step 3 + attrName = [] + attrValue = [] + # Step 4 attribute name + while True: + if c == b"=" and attrName: + break + elif c in spaceCharactersBytes: + # Step 6! + c = data.skip() + break + elif c in (b"/", b">"): + return b"".join(attrName), b"" + elif c in asciiUppercaseBytes: + attrName.append(c.lower()) + elif c is None: + return None + else: + attrName.append(c) + # Step 5 + c = next(data) + # Step 7 + if c != b"=": + data.previous() + return b"".join(attrName), b"" + # Step 8 + next(data) + # Step 9 + c = data.skip() + # Step 10 + if c in (b"'", b'"'): + # 10.1 + quoteChar = c + while True: + # 10.2 + c = next(data) + # 10.3 + if c == quoteChar: + next(data) + return b"".join(attrName), b"".join(attrValue) + # 10.4 + elif c in asciiUppercaseBytes: + attrValue.append(c.lower()) + # 10.5 + else: + attrValue.append(c) + elif c == b">": + return b"".join(attrName), b"" + elif c in asciiUppercaseBytes: + attrValue.append(c.lower()) + elif c is None: + return None + else: + attrValue.append(c) + # Step 11 + while True: + c = next(data) + if c in spacesAngleBrackets: + return b"".join(attrName), b"".join(attrValue) + elif c in asciiUppercaseBytes: + attrValue.append(c.lower()) + elif c is None: + return None + else: + attrValue.append(c) + + +class ContentAttrParser(object): + def __init__(self, data): + assert isinstance(data, bytes) + self.data = data + + def parse(self): + try: + # Check if the attr name is charset + # otherwise return + self.data.jumpTo(b"charset") + self.data.position += 1 + self.data.skip() + if not self.data.currentByte == b"=": + # If there is no = sign keep looking for attrs + return None + self.data.position += 1 + self.data.skip() + # Look for an encoding between matching quote marks + if self.data.currentByte in (b'"', b"'"): + quoteMark = self.data.currentByte + self.data.position += 1 + oldPosition = self.data.position + if self.data.jumpTo(quoteMark): + return self.data[oldPosition:self.data.position] + else: + return None + else: + # Unquoted value + oldPosition = self.data.position + try: + self.data.skipUntil(spaceCharactersBytes) + return self.data[oldPosition:self.data.position] + except StopIteration: + # Return the whole remaining value + return self.data[oldPosition:] + except StopIteration: + return None + + +def lookupEncoding(encoding): + """Return the python codec name corresponding to an encoding or None if the + string doesn't correspond to a valid encoding.""" + if isinstance(encoding, bytes): + try: + encoding = encoding.decode("ascii") + except UnicodeDecodeError: + return None + + if encoding is not None: + try: + return webencodings.lookup(encoding) + except AttributeError: + return None + else: + return None diff --git a/venv/Lib/site-packages/pip/_vendor/html5lib/_tokenizer.py b/venv/Lib/site-packages/pip/_vendor/html5lib/_tokenizer.py new file mode 100644 index 0000000..5f00253 --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/html5lib/_tokenizer.py @@ -0,0 +1,1735 @@ +from __future__ import absolute_import, division, unicode_literals + +from pip._vendor.six import unichr as chr + +from collections import deque, OrderedDict +from sys import version_info + +from .constants import spaceCharacters +from .constants import entities +from .constants import asciiLetters, asciiUpper2Lower +from .constants import digits, hexDigits, EOF +from .constants import tokenTypes, tagTokenTypes +from .constants import replacementCharacters + +from ._inputstream import HTMLInputStream + +from ._trie import Trie + +entitiesTrie = Trie(entities) + +if version_info >= (3, 7): + attributeMap = dict +else: + attributeMap = OrderedDict + + +class HTMLTokenizer(object): + """ This class takes care of tokenizing HTML. + + * self.currentToken + Holds the token that is currently being processed. + + * self.state + Holds a reference to the method to be invoked... XXX + + * self.stream + Points to HTMLInputStream object. + """ + + def __init__(self, stream, parser=None, **kwargs): + + self.stream = HTMLInputStream(stream, **kwargs) + self.parser = parser + + # Setup the initial tokenizer state + self.escapeFlag = False + self.lastFourChars = [] + self.state = self.dataState + self.escape = False + + # The current token being created + self.currentToken = None + super(HTMLTokenizer, self).__init__() + + def __iter__(self): + """ This is where the magic happens. + + We do our usually processing through the states and when we have a token + to return we yield the token which pauses processing until the next token + is requested. + """ + self.tokenQueue = deque([]) + # Start processing. When EOF is reached self.state will return False + # instead of True and the loop will terminate. + while self.state(): + while self.stream.errors: + yield {"type": tokenTypes["ParseError"], "data": self.stream.errors.pop(0)} + while self.tokenQueue: + yield self.tokenQueue.popleft() + + def consumeNumberEntity(self, isHex): + """This function returns either U+FFFD or the character based on the + decimal or hexadecimal representation. It also discards ";" if present. + If not present self.tokenQueue.append({"type": tokenTypes["ParseError"]}) is invoked. + """ + + allowed = digits + radix = 10 + if isHex: + allowed = hexDigits + radix = 16 + + charStack = [] + + # Consume all the characters that are in range while making sure we + # don't hit an EOF. + c = self.stream.char() + while c in allowed and c is not EOF: + charStack.append(c) + c = self.stream.char() + + # Convert the set of characters consumed to an int. + charAsInt = int("".join(charStack), radix) + + # Certain characters get replaced with others + if charAsInt in replacementCharacters: + char = replacementCharacters[charAsInt] + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "illegal-codepoint-for-numeric-entity", + "datavars": {"charAsInt": charAsInt}}) + elif ((0xD800 <= charAsInt <= 0xDFFF) or + (charAsInt > 0x10FFFF)): + char = "\uFFFD" + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "illegal-codepoint-for-numeric-entity", + "datavars": {"charAsInt": charAsInt}}) + else: + # Should speed up this check somehow (e.g. move the set to a constant) + if ((0x0001 <= charAsInt <= 0x0008) or + (0x000E <= charAsInt <= 0x001F) or + (0x007F <= charAsInt <= 0x009F) or + (0xFDD0 <= charAsInt <= 0xFDEF) or + charAsInt in frozenset([0x000B, 0xFFFE, 0xFFFF, 0x1FFFE, + 0x1FFFF, 0x2FFFE, 0x2FFFF, 0x3FFFE, + 0x3FFFF, 0x4FFFE, 0x4FFFF, 0x5FFFE, + 0x5FFFF, 0x6FFFE, 0x6FFFF, 0x7FFFE, + 0x7FFFF, 0x8FFFE, 0x8FFFF, 0x9FFFE, + 0x9FFFF, 0xAFFFE, 0xAFFFF, 0xBFFFE, + 0xBFFFF, 0xCFFFE, 0xCFFFF, 0xDFFFE, + 0xDFFFF, 0xEFFFE, 0xEFFFF, 0xFFFFE, + 0xFFFFF, 0x10FFFE, 0x10FFFF])): + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": + "illegal-codepoint-for-numeric-entity", + "datavars": {"charAsInt": charAsInt}}) + try: + # Try/except needed as UCS-2 Python builds' unichar only works + # within the BMP. + char = chr(charAsInt) + except ValueError: + v = charAsInt - 0x10000 + char = chr(0xD800 | (v >> 10)) + chr(0xDC00 | (v & 0x3FF)) + + # Discard the ; if present. Otherwise, put it back on the queue and + # invoke parseError on parser. + if c != ";": + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "numeric-entity-without-semicolon"}) + self.stream.unget(c) + + return char + + def consumeEntity(self, allowedChar=None, fromAttribute=False): + # Initialise to the default output for when no entity is matched + output = "&" + + charStack = [self.stream.char()] + if (charStack[0] in spaceCharacters or charStack[0] in (EOF, "<", "&") or + (allowedChar is not None and allowedChar == charStack[0])): + self.stream.unget(charStack[0]) + + elif charStack[0] == "#": + # Read the next character to see if it's hex or decimal + hex = False + charStack.append(self.stream.char()) + if charStack[-1] in ("x", "X"): + hex = True + charStack.append(self.stream.char()) + + # charStack[-1] should be the first digit + if (hex and charStack[-1] in hexDigits) \ + or (not hex and charStack[-1] in digits): + # At least one digit found, so consume the whole number + self.stream.unget(charStack[-1]) + output = self.consumeNumberEntity(hex) + else: + # No digits found + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "expected-numeric-entity"}) + self.stream.unget(charStack.pop()) + output = "&" + "".join(charStack) + + else: + # At this point in the process might have named entity. Entities + # are stored in the global variable "entities". + # + # Consume characters and compare to these to a substring of the + # entity names in the list until the substring no longer matches. + while (charStack[-1] is not EOF): + if not entitiesTrie.has_keys_with_prefix("".join(charStack)): + break + charStack.append(self.stream.char()) + + # At this point we have a string that starts with some characters + # that may match an entity + # Try to find the longest entity the string will match to take care + # of ¬i for instance. + try: + entityName = entitiesTrie.longest_prefix("".join(charStack[:-1])) + entityLength = len(entityName) + except KeyError: + entityName = None + + if entityName is not None: + if entityName[-1] != ";": + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "named-entity-without-semicolon"}) + if (entityName[-1] != ";" and fromAttribute and + (charStack[entityLength] in asciiLetters or + charStack[entityLength] in digits or + charStack[entityLength] == "=")): + self.stream.unget(charStack.pop()) + output = "&" + "".join(charStack) + else: + output = entities[entityName] + self.stream.unget(charStack.pop()) + output += "".join(charStack[entityLength:]) + else: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "expected-named-entity"}) + self.stream.unget(charStack.pop()) + output = "&" + "".join(charStack) + + if fromAttribute: + self.currentToken["data"][-1][1] += output + else: + if output in spaceCharacters: + tokenType = "SpaceCharacters" + else: + tokenType = "Characters" + self.tokenQueue.append({"type": tokenTypes[tokenType], "data": output}) + + def processEntityInAttribute(self, allowedChar): + """This method replaces the need for "entityInAttributeValueState". + """ + self.consumeEntity(allowedChar=allowedChar, fromAttribute=True) + + def emitCurrentToken(self): + """This method is a generic handler for emitting the tags. It also sets + the state to "data" because that's what's needed after a token has been + emitted. + """ + token = self.currentToken + # Add token to the queue to be yielded + if (token["type"] in tagTokenTypes): + token["name"] = token["name"].translate(asciiUpper2Lower) + if token["type"] == tokenTypes["StartTag"]: + raw = token["data"] + data = attributeMap(raw) + if len(raw) > len(data): + # we had some duplicated attribute, fix so first wins + data.update(raw[::-1]) + token["data"] = data + + if token["type"] == tokenTypes["EndTag"]: + if token["data"]: + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "attributes-in-end-tag"}) + if token["selfClosing"]: + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "self-closing-flag-on-end-tag"}) + self.tokenQueue.append(token) + self.state = self.dataState + + # Below are the various tokenizer states worked out. + def dataState(self): + data = self.stream.char() + if data == "&": + self.state = self.entityDataState + elif data == "<": + self.state = self.tagOpenState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.tokenQueue.append({"type": tokenTypes["Characters"], + "data": "\u0000"}) + elif data is EOF: + # Tokenization ends. + return False + elif data in spaceCharacters: + # Directly after emitting a token you switch back to the "data + # state". At that point spaceCharacters are important so they are + # emitted separately. + self.tokenQueue.append({"type": tokenTypes["SpaceCharacters"], "data": + data + self.stream.charsUntil(spaceCharacters, True)}) + # No need to update lastFourChars here, since the first space will + # have already been appended to lastFourChars and will have broken + # any sequences + else: + chars = self.stream.charsUntil(("&", "<", "\u0000")) + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": + data + chars}) + return True + + def entityDataState(self): + self.consumeEntity() + self.state = self.dataState + return True + + def rcdataState(self): + data = self.stream.char() + if data == "&": + self.state = self.characterReferenceInRcdata + elif data == "<": + self.state = self.rcdataLessThanSignState + elif data == EOF: + # Tokenization ends. + return False + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.tokenQueue.append({"type": tokenTypes["Characters"], + "data": "\uFFFD"}) + elif data in spaceCharacters: + # Directly after emitting a token you switch back to the "data + # state". At that point spaceCharacters are important so they are + # emitted separately. + self.tokenQueue.append({"type": tokenTypes["SpaceCharacters"], "data": + data + self.stream.charsUntil(spaceCharacters, True)}) + # No need to update lastFourChars here, since the first space will + # have already been appended to lastFourChars and will have broken + # any sequences + else: + chars = self.stream.charsUntil(("&", "<", "\u0000")) + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": + data + chars}) + return True + + def characterReferenceInRcdata(self): + self.consumeEntity() + self.state = self.rcdataState + return True + + def rawtextState(self): + data = self.stream.char() + if data == "<": + self.state = self.rawtextLessThanSignState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.tokenQueue.append({"type": tokenTypes["Characters"], + "data": "\uFFFD"}) + elif data == EOF: + # Tokenization ends. + return False + else: + chars = self.stream.charsUntil(("<", "\u0000")) + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": + data + chars}) + return True + + def scriptDataState(self): + data = self.stream.char() + if data == "<": + self.state = self.scriptDataLessThanSignState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.tokenQueue.append({"type": tokenTypes["Characters"], + "data": "\uFFFD"}) + elif data == EOF: + # Tokenization ends. + return False + else: + chars = self.stream.charsUntil(("<", "\u0000")) + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": + data + chars}) + return True + + def plaintextState(self): + data = self.stream.char() + if data == EOF: + # Tokenization ends. + return False + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.tokenQueue.append({"type": tokenTypes["Characters"], + "data": "\uFFFD"}) + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": + data + self.stream.charsUntil("\u0000")}) + return True + + def tagOpenState(self): + data = self.stream.char() + if data == "!": + self.state = self.markupDeclarationOpenState + elif data == "/": + self.state = self.closeTagOpenState + elif data in asciiLetters: + self.currentToken = {"type": tokenTypes["StartTag"], + "name": data, "data": [], + "selfClosing": False, + "selfClosingAcknowledged": False} + self.state = self.tagNameState + elif data == ">": + # XXX In theory it could be something besides a tag name. But + # do we really care? + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "expected-tag-name-but-got-right-bracket"}) + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "<>"}) + self.state = self.dataState + elif data == "?": + # XXX In theory it could be something besides a tag name. But + # do we really care? + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "expected-tag-name-but-got-question-mark"}) + self.stream.unget(data) + self.state = self.bogusCommentState + else: + # XXX + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "expected-tag-name"}) + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "<"}) + self.stream.unget(data) + self.state = self.dataState + return True + + def closeTagOpenState(self): + data = self.stream.char() + if data in asciiLetters: + self.currentToken = {"type": tokenTypes["EndTag"], "name": data, + "data": [], "selfClosing": False} + self.state = self.tagNameState + elif data == ">": + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "expected-closing-tag-but-got-right-bracket"}) + self.state = self.dataState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "expected-closing-tag-but-got-eof"}) + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "": + self.emitCurrentToken() + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-tag-name"}) + self.state = self.dataState + elif data == "/": + self.state = self.selfClosingStartTagState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["name"] += "\uFFFD" + else: + self.currentToken["name"] += data + # (Don't use charsUntil here, because tag names are + # very short and it's faster to not do anything fancy) + return True + + def rcdataLessThanSignState(self): + data = self.stream.char() + if data == "/": + self.temporaryBuffer = "" + self.state = self.rcdataEndTagOpenState + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "<"}) + self.stream.unget(data) + self.state = self.rcdataState + return True + + def rcdataEndTagOpenState(self): + data = self.stream.char() + if data in asciiLetters: + self.temporaryBuffer += data + self.state = self.rcdataEndTagNameState + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "" and appropriate: + self.currentToken = {"type": tokenTypes["EndTag"], + "name": self.temporaryBuffer, + "data": [], "selfClosing": False} + self.emitCurrentToken() + self.state = self.dataState + elif data in asciiLetters: + self.temporaryBuffer += data + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], + "data": "" and appropriate: + self.currentToken = {"type": tokenTypes["EndTag"], + "name": self.temporaryBuffer, + "data": [], "selfClosing": False} + self.emitCurrentToken() + self.state = self.dataState + elif data in asciiLetters: + self.temporaryBuffer += data + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], + "data": "" and appropriate: + self.currentToken = {"type": tokenTypes["EndTag"], + "name": self.temporaryBuffer, + "data": [], "selfClosing": False} + self.emitCurrentToken() + self.state = self.dataState + elif data in asciiLetters: + self.temporaryBuffer += data + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], + "data": "": + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": ">"}) + self.state = self.scriptDataState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.tokenQueue.append({"type": tokenTypes["Characters"], + "data": "\uFFFD"}) + self.state = self.scriptDataEscapedState + elif data == EOF: + self.state = self.dataState + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": data}) + self.state = self.scriptDataEscapedState + return True + + def scriptDataEscapedLessThanSignState(self): + data = self.stream.char() + if data == "/": + self.temporaryBuffer = "" + self.state = self.scriptDataEscapedEndTagOpenState + elif data in asciiLetters: + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "<" + data}) + self.temporaryBuffer = data + self.state = self.scriptDataDoubleEscapeStartState + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "<"}) + self.stream.unget(data) + self.state = self.scriptDataEscapedState + return True + + def scriptDataEscapedEndTagOpenState(self): + data = self.stream.char() + if data in asciiLetters: + self.temporaryBuffer = data + self.state = self.scriptDataEscapedEndTagNameState + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "" and appropriate: + self.currentToken = {"type": tokenTypes["EndTag"], + "name": self.temporaryBuffer, + "data": [], "selfClosing": False} + self.emitCurrentToken() + self.state = self.dataState + elif data in asciiLetters: + self.temporaryBuffer += data + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], + "data": ""))): + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": data}) + if self.temporaryBuffer.lower() == "script": + self.state = self.scriptDataDoubleEscapedState + else: + self.state = self.scriptDataEscapedState + elif data in asciiLetters: + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": data}) + self.temporaryBuffer += data + else: + self.stream.unget(data) + self.state = self.scriptDataEscapedState + return True + + def scriptDataDoubleEscapedState(self): + data = self.stream.char() + if data == "-": + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "-"}) + self.state = self.scriptDataDoubleEscapedDashState + elif data == "<": + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "<"}) + self.state = self.scriptDataDoubleEscapedLessThanSignState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.tokenQueue.append({"type": tokenTypes["Characters"], + "data": "\uFFFD"}) + elif data == EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-script-in-script"}) + self.state = self.dataState + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": data}) + return True + + def scriptDataDoubleEscapedDashState(self): + data = self.stream.char() + if data == "-": + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "-"}) + self.state = self.scriptDataDoubleEscapedDashDashState + elif data == "<": + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "<"}) + self.state = self.scriptDataDoubleEscapedLessThanSignState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.tokenQueue.append({"type": tokenTypes["Characters"], + "data": "\uFFFD"}) + self.state = self.scriptDataDoubleEscapedState + elif data == EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-script-in-script"}) + self.state = self.dataState + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": data}) + self.state = self.scriptDataDoubleEscapedState + return True + + def scriptDataDoubleEscapedDashDashState(self): + data = self.stream.char() + if data == "-": + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "-"}) + elif data == "<": + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "<"}) + self.state = self.scriptDataDoubleEscapedLessThanSignState + elif data == ">": + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": ">"}) + self.state = self.scriptDataState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.tokenQueue.append({"type": tokenTypes["Characters"], + "data": "\uFFFD"}) + self.state = self.scriptDataDoubleEscapedState + elif data == EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-script-in-script"}) + self.state = self.dataState + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": data}) + self.state = self.scriptDataDoubleEscapedState + return True + + def scriptDataDoubleEscapedLessThanSignState(self): + data = self.stream.char() + if data == "/": + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "/"}) + self.temporaryBuffer = "" + self.state = self.scriptDataDoubleEscapeEndState + else: + self.stream.unget(data) + self.state = self.scriptDataDoubleEscapedState + return True + + def scriptDataDoubleEscapeEndState(self): + data = self.stream.char() + if data in (spaceCharacters | frozenset(("/", ">"))): + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": data}) + if self.temporaryBuffer.lower() == "script": + self.state = self.scriptDataEscapedState + else: + self.state = self.scriptDataDoubleEscapedState + elif data in asciiLetters: + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": data}) + self.temporaryBuffer += data + else: + self.stream.unget(data) + self.state = self.scriptDataDoubleEscapedState + return True + + def beforeAttributeNameState(self): + data = self.stream.char() + if data in spaceCharacters: + self.stream.charsUntil(spaceCharacters, True) + elif data in asciiLetters: + self.currentToken["data"].append([data, ""]) + self.state = self.attributeNameState + elif data == ">": + self.emitCurrentToken() + elif data == "/": + self.state = self.selfClosingStartTagState + elif data in ("'", '"', "=", "<"): + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "invalid-character-in-attribute-name"}) + self.currentToken["data"].append([data, ""]) + self.state = self.attributeNameState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["data"].append(["\uFFFD", ""]) + self.state = self.attributeNameState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "expected-attribute-name-but-got-eof"}) + self.state = self.dataState + else: + self.currentToken["data"].append([data, ""]) + self.state = self.attributeNameState + return True + + def attributeNameState(self): + data = self.stream.char() + leavingThisState = True + emitToken = False + if data == "=": + self.state = self.beforeAttributeValueState + elif data in asciiLetters: + self.currentToken["data"][-1][0] += data +\ + self.stream.charsUntil(asciiLetters, True) + leavingThisState = False + elif data == ">": + # XXX If we emit here the attributes are converted to a dict + # without being checked and when the code below runs we error + # because data is a dict not a list + emitToken = True + elif data in spaceCharacters: + self.state = self.afterAttributeNameState + elif data == "/": + self.state = self.selfClosingStartTagState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["data"][-1][0] += "\uFFFD" + leavingThisState = False + elif data in ("'", '"', "<"): + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": + "invalid-character-in-attribute-name"}) + self.currentToken["data"][-1][0] += data + leavingThisState = False + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "eof-in-attribute-name"}) + self.state = self.dataState + else: + self.currentToken["data"][-1][0] += data + leavingThisState = False + + if leavingThisState: + # Attributes are not dropped at this stage. That happens when the + # start tag token is emitted so values can still be safely appended + # to attributes, but we do want to report the parse error in time. + self.currentToken["data"][-1][0] = ( + self.currentToken["data"][-1][0].translate(asciiUpper2Lower)) + for name, _ in self.currentToken["data"][:-1]: + if self.currentToken["data"][-1][0] == name: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "duplicate-attribute"}) + break + # XXX Fix for above XXX + if emitToken: + self.emitCurrentToken() + return True + + def afterAttributeNameState(self): + data = self.stream.char() + if data in spaceCharacters: + self.stream.charsUntil(spaceCharacters, True) + elif data == "=": + self.state = self.beforeAttributeValueState + elif data == ">": + self.emitCurrentToken() + elif data in asciiLetters: + self.currentToken["data"].append([data, ""]) + self.state = self.attributeNameState + elif data == "/": + self.state = self.selfClosingStartTagState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["data"].append(["\uFFFD", ""]) + self.state = self.attributeNameState + elif data in ("'", '"', "<"): + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "invalid-character-after-attribute-name"}) + self.currentToken["data"].append([data, ""]) + self.state = self.attributeNameState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "expected-end-of-tag-but-got-eof"}) + self.state = self.dataState + else: + self.currentToken["data"].append([data, ""]) + self.state = self.attributeNameState + return True + + def beforeAttributeValueState(self): + data = self.stream.char() + if data in spaceCharacters: + self.stream.charsUntil(spaceCharacters, True) + elif data == "\"": + self.state = self.attributeValueDoubleQuotedState + elif data == "&": + self.state = self.attributeValueUnQuotedState + self.stream.unget(data) + elif data == "'": + self.state = self.attributeValueSingleQuotedState + elif data == ">": + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "expected-attribute-value-but-got-right-bracket"}) + self.emitCurrentToken() + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["data"][-1][1] += "\uFFFD" + self.state = self.attributeValueUnQuotedState + elif data in ("=", "<", "`"): + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "equals-in-unquoted-attribute-value"}) + self.currentToken["data"][-1][1] += data + self.state = self.attributeValueUnQuotedState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "expected-attribute-value-but-got-eof"}) + self.state = self.dataState + else: + self.currentToken["data"][-1][1] += data + self.state = self.attributeValueUnQuotedState + return True + + def attributeValueDoubleQuotedState(self): + data = self.stream.char() + if data == "\"": + self.state = self.afterAttributeValueState + elif data == "&": + self.processEntityInAttribute('"') + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["data"][-1][1] += "\uFFFD" + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-attribute-value-double-quote"}) + self.state = self.dataState + else: + self.currentToken["data"][-1][1] += data +\ + self.stream.charsUntil(("\"", "&", "\u0000")) + return True + + def attributeValueSingleQuotedState(self): + data = self.stream.char() + if data == "'": + self.state = self.afterAttributeValueState + elif data == "&": + self.processEntityInAttribute("'") + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["data"][-1][1] += "\uFFFD" + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-attribute-value-single-quote"}) + self.state = self.dataState + else: + self.currentToken["data"][-1][1] += data +\ + self.stream.charsUntil(("'", "&", "\u0000")) + return True + + def attributeValueUnQuotedState(self): + data = self.stream.char() + if data in spaceCharacters: + self.state = self.beforeAttributeNameState + elif data == "&": + self.processEntityInAttribute(">") + elif data == ">": + self.emitCurrentToken() + elif data in ('"', "'", "=", "<", "`"): + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-character-in-unquoted-attribute-value"}) + self.currentToken["data"][-1][1] += data + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["data"][-1][1] += "\uFFFD" + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-attribute-value-no-quotes"}) + self.state = self.dataState + else: + self.currentToken["data"][-1][1] += data + self.stream.charsUntil( + frozenset(("&", ">", '"', "'", "=", "<", "`", "\u0000")) | spaceCharacters) + return True + + def afterAttributeValueState(self): + data = self.stream.char() + if data in spaceCharacters: + self.state = self.beforeAttributeNameState + elif data == ">": + self.emitCurrentToken() + elif data == "/": + self.state = self.selfClosingStartTagState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-EOF-after-attribute-value"}) + self.stream.unget(data) + self.state = self.dataState + else: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-character-after-attribute-value"}) + self.stream.unget(data) + self.state = self.beforeAttributeNameState + return True + + def selfClosingStartTagState(self): + data = self.stream.char() + if data == ">": + self.currentToken["selfClosing"] = True + self.emitCurrentToken() + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": + "unexpected-EOF-after-solidus-in-tag"}) + self.stream.unget(data) + self.state = self.dataState + else: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-character-after-solidus-in-tag"}) + self.stream.unget(data) + self.state = self.beforeAttributeNameState + return True + + def bogusCommentState(self): + # Make a new comment token and give it as value all the characters + # until the first > or EOF (charsUntil checks for EOF automatically) + # and emit it. + data = self.stream.charsUntil(">") + data = data.replace("\u0000", "\uFFFD") + self.tokenQueue.append( + {"type": tokenTypes["Comment"], "data": data}) + + # Eat the character directly after the bogus comment which is either a + # ">" or an EOF. + self.stream.char() + self.state = self.dataState + return True + + def markupDeclarationOpenState(self): + charStack = [self.stream.char()] + if charStack[-1] == "-": + charStack.append(self.stream.char()) + if charStack[-1] == "-": + self.currentToken = {"type": tokenTypes["Comment"], "data": ""} + self.state = self.commentStartState + return True + elif charStack[-1] in ('d', 'D'): + matched = True + for expected in (('o', 'O'), ('c', 'C'), ('t', 'T'), + ('y', 'Y'), ('p', 'P'), ('e', 'E')): + charStack.append(self.stream.char()) + if charStack[-1] not in expected: + matched = False + break + if matched: + self.currentToken = {"type": tokenTypes["Doctype"], + "name": "", + "publicId": None, "systemId": None, + "correct": True} + self.state = self.doctypeState + return True + elif (charStack[-1] == "[" and + self.parser is not None and + self.parser.tree.openElements and + self.parser.tree.openElements[-1].namespace != self.parser.tree.defaultNamespace): + matched = True + for expected in ["C", "D", "A", "T", "A", "["]: + charStack.append(self.stream.char()) + if charStack[-1] != expected: + matched = False + break + if matched: + self.state = self.cdataSectionState + return True + + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "expected-dashes-or-doctype"}) + + while charStack: + self.stream.unget(charStack.pop()) + self.state = self.bogusCommentState + return True + + def commentStartState(self): + data = self.stream.char() + if data == "-": + self.state = self.commentStartDashState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["data"] += "\uFFFD" + elif data == ">": + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "incorrect-comment"}) + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-comment"}) + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.currentToken["data"] += data + self.state = self.commentState + return True + + def commentStartDashState(self): + data = self.stream.char() + if data == "-": + self.state = self.commentEndState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["data"] += "-\uFFFD" + elif data == ">": + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "incorrect-comment"}) + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-comment"}) + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.currentToken["data"] += "-" + data + self.state = self.commentState + return True + + def commentState(self): + data = self.stream.char() + if data == "-": + self.state = self.commentEndDashState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["data"] += "\uFFFD" + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "eof-in-comment"}) + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.currentToken["data"] += data + \ + self.stream.charsUntil(("-", "\u0000")) + return True + + def commentEndDashState(self): + data = self.stream.char() + if data == "-": + self.state = self.commentEndState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["data"] += "-\uFFFD" + self.state = self.commentState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-comment-end-dash"}) + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.currentToken["data"] += "-" + data + self.state = self.commentState + return True + + def commentEndState(self): + data = self.stream.char() + if data == ">": + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["data"] += "--\uFFFD" + self.state = self.commentState + elif data == "!": + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-bang-after-double-dash-in-comment"}) + self.state = self.commentEndBangState + elif data == "-": + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-dash-after-double-dash-in-comment"}) + self.currentToken["data"] += data + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-comment-double-dash"}) + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + # XXX + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-char-in-comment"}) + self.currentToken["data"] += "--" + data + self.state = self.commentState + return True + + def commentEndBangState(self): + data = self.stream.char() + if data == ">": + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data == "-": + self.currentToken["data"] += "--!" + self.state = self.commentEndDashState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["data"] += "--!\uFFFD" + self.state = self.commentState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-comment-end-bang-state"}) + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.currentToken["data"] += "--!" + data + self.state = self.commentState + return True + + def doctypeState(self): + data = self.stream.char() + if data in spaceCharacters: + self.state = self.beforeDoctypeNameState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "expected-doctype-name-but-got-eof"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "need-space-after-doctype"}) + self.stream.unget(data) + self.state = self.beforeDoctypeNameState + return True + + def beforeDoctypeNameState(self): + data = self.stream.char() + if data in spaceCharacters: + pass + elif data == ">": + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "expected-doctype-name-but-got-right-bracket"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["name"] = "\uFFFD" + self.state = self.doctypeNameState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "expected-doctype-name-but-got-eof"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.currentToken["name"] = data + self.state = self.doctypeNameState + return True + + def doctypeNameState(self): + data = self.stream.char() + if data in spaceCharacters: + self.currentToken["name"] = self.currentToken["name"].translate(asciiUpper2Lower) + self.state = self.afterDoctypeNameState + elif data == ">": + self.currentToken["name"] = self.currentToken["name"].translate(asciiUpper2Lower) + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["name"] += "\uFFFD" + self.state = self.doctypeNameState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-doctype-name"}) + self.currentToken["correct"] = False + self.currentToken["name"] = self.currentToken["name"].translate(asciiUpper2Lower) + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.currentToken["name"] += data + return True + + def afterDoctypeNameState(self): + data = self.stream.char() + if data in spaceCharacters: + pass + elif data == ">": + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data is EOF: + self.currentToken["correct"] = False + self.stream.unget(data) + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-doctype"}) + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + if data in ("p", "P"): + matched = True + for expected in (("u", "U"), ("b", "B"), ("l", "L"), + ("i", "I"), ("c", "C")): + data = self.stream.char() + if data not in expected: + matched = False + break + if matched: + self.state = self.afterDoctypePublicKeywordState + return True + elif data in ("s", "S"): + matched = True + for expected in (("y", "Y"), ("s", "S"), ("t", "T"), + ("e", "E"), ("m", "M")): + data = self.stream.char() + if data not in expected: + matched = False + break + if matched: + self.state = self.afterDoctypeSystemKeywordState + return True + + # All the characters read before the current 'data' will be + # [a-zA-Z], so they're garbage in the bogus doctype and can be + # discarded; only the latest character might be '>' or EOF + # and needs to be ungetted + self.stream.unget(data) + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "expected-space-or-right-bracket-in-doctype", "datavars": + {"data": data}}) + self.currentToken["correct"] = False + self.state = self.bogusDoctypeState + + return True + + def afterDoctypePublicKeywordState(self): + data = self.stream.char() + if data in spaceCharacters: + self.state = self.beforeDoctypePublicIdentifierState + elif data in ("'", '"'): + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-char-in-doctype"}) + self.stream.unget(data) + self.state = self.beforeDoctypePublicIdentifierState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.stream.unget(data) + self.state = self.beforeDoctypePublicIdentifierState + return True + + def beforeDoctypePublicIdentifierState(self): + data = self.stream.char() + if data in spaceCharacters: + pass + elif data == "\"": + self.currentToken["publicId"] = "" + self.state = self.doctypePublicIdentifierDoubleQuotedState + elif data == "'": + self.currentToken["publicId"] = "" + self.state = self.doctypePublicIdentifierSingleQuotedState + elif data == ">": + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-end-of-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-char-in-doctype"}) + self.currentToken["correct"] = False + self.state = self.bogusDoctypeState + return True + + def doctypePublicIdentifierDoubleQuotedState(self): + data = self.stream.char() + if data == "\"": + self.state = self.afterDoctypePublicIdentifierState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["publicId"] += "\uFFFD" + elif data == ">": + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-end-of-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.currentToken["publicId"] += data + return True + + def doctypePublicIdentifierSingleQuotedState(self): + data = self.stream.char() + if data == "'": + self.state = self.afterDoctypePublicIdentifierState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["publicId"] += "\uFFFD" + elif data == ">": + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-end-of-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.currentToken["publicId"] += data + return True + + def afterDoctypePublicIdentifierState(self): + data = self.stream.char() + if data in spaceCharacters: + self.state = self.betweenDoctypePublicAndSystemIdentifiersState + elif data == ">": + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data == '"': + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-char-in-doctype"}) + self.currentToken["systemId"] = "" + self.state = self.doctypeSystemIdentifierDoubleQuotedState + elif data == "'": + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-char-in-doctype"}) + self.currentToken["systemId"] = "" + self.state = self.doctypeSystemIdentifierSingleQuotedState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-char-in-doctype"}) + self.currentToken["correct"] = False + self.state = self.bogusDoctypeState + return True + + def betweenDoctypePublicAndSystemIdentifiersState(self): + data = self.stream.char() + if data in spaceCharacters: + pass + elif data == ">": + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data == '"': + self.currentToken["systemId"] = "" + self.state = self.doctypeSystemIdentifierDoubleQuotedState + elif data == "'": + self.currentToken["systemId"] = "" + self.state = self.doctypeSystemIdentifierSingleQuotedState + elif data == EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-char-in-doctype"}) + self.currentToken["correct"] = False + self.state = self.bogusDoctypeState + return True + + def afterDoctypeSystemKeywordState(self): + data = self.stream.char() + if data in spaceCharacters: + self.state = self.beforeDoctypeSystemIdentifierState + elif data in ("'", '"'): + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-char-in-doctype"}) + self.stream.unget(data) + self.state = self.beforeDoctypeSystemIdentifierState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.stream.unget(data) + self.state = self.beforeDoctypeSystemIdentifierState + return True + + def beforeDoctypeSystemIdentifierState(self): + data = self.stream.char() + if data in spaceCharacters: + pass + elif data == "\"": + self.currentToken["systemId"] = "" + self.state = self.doctypeSystemIdentifierDoubleQuotedState + elif data == "'": + self.currentToken["systemId"] = "" + self.state = self.doctypeSystemIdentifierSingleQuotedState + elif data == ">": + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-char-in-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-char-in-doctype"}) + self.currentToken["correct"] = False + self.state = self.bogusDoctypeState + return True + + def doctypeSystemIdentifierDoubleQuotedState(self): + data = self.stream.char() + if data == "\"": + self.state = self.afterDoctypeSystemIdentifierState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["systemId"] += "\uFFFD" + elif data == ">": + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-end-of-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.currentToken["systemId"] += data + return True + + def doctypeSystemIdentifierSingleQuotedState(self): + data = self.stream.char() + if data == "'": + self.state = self.afterDoctypeSystemIdentifierState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["systemId"] += "\uFFFD" + elif data == ">": + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-end-of-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.currentToken["systemId"] += data + return True + + def afterDoctypeSystemIdentifierState(self): + data = self.stream.char() + if data in spaceCharacters: + pass + elif data == ">": + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-char-in-doctype"}) + self.state = self.bogusDoctypeState + return True + + def bogusDoctypeState(self): + data = self.stream.char() + if data == ">": + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data is EOF: + # XXX EMIT + self.stream.unget(data) + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + pass + return True + + def cdataSectionState(self): + data = [] + while True: + data.append(self.stream.charsUntil("]")) + data.append(self.stream.charsUntil(">")) + char = self.stream.char() + if char == EOF: + break + else: + assert char == ">" + if data[-1][-2:] == "]]": + data[-1] = data[-1][:-2] + break + else: + data.append(char) + + data = "".join(data) # pylint:disable=redefined-variable-type + # Deal with null here rather than in the parser + nullCount = data.count("\u0000") + if nullCount > 0: + for _ in range(nullCount): + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + data = data.replace("\u0000", "\uFFFD") + if data: + self.tokenQueue.append({"type": tokenTypes["Characters"], + "data": data}) + self.state = self.dataState + return True diff --git a/venv/Lib/site-packages/pip/_vendor/html5lib/_trie/__init__.py b/venv/Lib/site-packages/pip/_vendor/html5lib/_trie/__init__.py new file mode 100644 index 0000000..07bad5d --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/html5lib/_trie/__init__.py @@ -0,0 +1,5 @@ +from __future__ import absolute_import, division, unicode_literals + +from .py import Trie + +__all__ = ["Trie"] diff --git a/venv/Lib/site-packages/pip/_vendor/html5lib/_trie/_base.py b/venv/Lib/site-packages/pip/_vendor/html5lib/_trie/_base.py new file mode 100644 index 0000000..6b71975 --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/html5lib/_trie/_base.py @@ -0,0 +1,40 @@ +from __future__ import absolute_import, division, unicode_literals + +try: + from collections.abc import Mapping +except ImportError: # Python 2.7 + from collections import Mapping + + +class Trie(Mapping): + """Abstract base class for tries""" + + def keys(self, prefix=None): + # pylint:disable=arguments-differ + keys = super(Trie, self).keys() + + if prefix is None: + return set(keys) + + return {x for x in keys if x.startswith(prefix)} + + def has_keys_with_prefix(self, prefix): + for key in self.keys(): + if key.startswith(prefix): + return True + + return False + + def longest_prefix(self, prefix): + if prefix in self: + return prefix + + for i in range(1, len(prefix) + 1): + if prefix[:-i] in self: + return prefix[:-i] + + raise KeyError(prefix) + + def longest_prefix_item(self, prefix): + lprefix = self.longest_prefix(prefix) + return (lprefix, self[lprefix]) diff --git a/venv/Lib/site-packages/pip/_vendor/html5lib/_trie/py.py b/venv/Lib/site-packages/pip/_vendor/html5lib/_trie/py.py new file mode 100644 index 0000000..c178b21 --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/html5lib/_trie/py.py @@ -0,0 +1,67 @@ +from __future__ import absolute_import, division, unicode_literals +from pip._vendor.six import text_type + +from bisect import bisect_left + +from ._base import Trie as ABCTrie + + +class Trie(ABCTrie): + def __init__(self, data): + if not all(isinstance(x, text_type) for x in data.keys()): + raise TypeError("All keys must be strings") + + self._data = data + self._keys = sorted(data.keys()) + self._cachestr = "" + self._cachepoints = (0, len(data)) + + def __contains__(self, key): + return key in self._data + + def __len__(self): + return len(self._data) + + def __iter__(self): + return iter(self._data) + + def __getitem__(self, key): + return self._data[key] + + def keys(self, prefix=None): + if prefix is None or prefix == "" or not self._keys: + return set(self._keys) + + if prefix.startswith(self._cachestr): + lo, hi = self._cachepoints + start = i = bisect_left(self._keys, prefix, lo, hi) + else: + start = i = bisect_left(self._keys, prefix) + + keys = set() + if start == len(self._keys): + return keys + + while self._keys[i].startswith(prefix): + keys.add(self._keys[i]) + i += 1 + + self._cachestr = prefix + self._cachepoints = (start, i) + + return keys + + def has_keys_with_prefix(self, prefix): + if prefix in self._data: + return True + + if prefix.startswith(self._cachestr): + lo, hi = self._cachepoints + i = bisect_left(self._keys, prefix, lo, hi) + else: + i = bisect_left(self._keys, prefix) + + if i == len(self._keys): + return False + + return self._keys[i].startswith(prefix) diff --git a/venv/Lib/site-packages/pip/_vendor/html5lib/_utils.py b/venv/Lib/site-packages/pip/_vendor/html5lib/_utils.py new file mode 100644 index 0000000..d7c4926 --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/html5lib/_utils.py @@ -0,0 +1,159 @@ +from __future__ import absolute_import, division, unicode_literals + +from types import ModuleType + +try: + from collections.abc import Mapping +except ImportError: + from collections import Mapping + +from pip._vendor.six import text_type, PY3 + +if PY3: + import xml.etree.ElementTree as default_etree +else: + try: + import xml.etree.cElementTree as default_etree + except ImportError: + import xml.etree.ElementTree as default_etree + + +__all__ = ["default_etree", "MethodDispatcher", "isSurrogatePair", + "surrogatePairToCodepoint", "moduleFactoryFactory", + "supports_lone_surrogates"] + + +# Platforms not supporting lone surrogates (\uD800-\uDFFF) should be +# caught by the below test. In general this would be any platform +# using UTF-16 as its encoding of unicode strings, such as +# Jython. This is because UTF-16 itself is based on the use of such +# surrogates, and there is no mechanism to further escape such +# escapes. +try: + _x = eval('"\\uD800"') # pylint:disable=eval-used + if not isinstance(_x, text_type): + # We need this with u"" because of http://bugs.jython.org/issue2039 + _x = eval('u"\\uD800"') # pylint:disable=eval-used + assert isinstance(_x, text_type) +except Exception: + supports_lone_surrogates = False +else: + supports_lone_surrogates = True + + +class MethodDispatcher(dict): + """Dict with 2 special properties: + + On initiation, keys that are lists, sets or tuples are converted to + multiple keys so accessing any one of the items in the original + list-like object returns the matching value + + md = MethodDispatcher({("foo", "bar"):"baz"}) + md["foo"] == "baz" + + A default value which can be set through the default attribute. + """ + + def __init__(self, items=()): + _dictEntries = [] + for name, value in items: + if isinstance(name, (list, tuple, frozenset, set)): + for item in name: + _dictEntries.append((item, value)) + else: + _dictEntries.append((name, value)) + dict.__init__(self, _dictEntries) + assert len(self) == len(_dictEntries) + self.default = None + + def __getitem__(self, key): + return dict.get(self, key, self.default) + + def __get__(self, instance, owner=None): + return BoundMethodDispatcher(instance, self) + + +class BoundMethodDispatcher(Mapping): + """Wraps a MethodDispatcher, binding its return values to `instance`""" + def __init__(self, instance, dispatcher): + self.instance = instance + self.dispatcher = dispatcher + + def __getitem__(self, key): + # see https://docs.python.org/3/reference/datamodel.html#object.__get__ + # on a function, __get__ is used to bind a function to an instance as a bound method + return self.dispatcher[key].__get__(self.instance) + + def get(self, key, default): + if key in self.dispatcher: + return self[key] + else: + return default + + def __iter__(self): + return iter(self.dispatcher) + + def __len__(self): + return len(self.dispatcher) + + def __contains__(self, key): + return key in self.dispatcher + + +# Some utility functions to deal with weirdness around UCS2 vs UCS4 +# python builds + +def isSurrogatePair(data): + return (len(data) == 2 and + ord(data[0]) >= 0xD800 and ord(data[0]) <= 0xDBFF and + ord(data[1]) >= 0xDC00 and ord(data[1]) <= 0xDFFF) + + +def surrogatePairToCodepoint(data): + char_val = (0x10000 + (ord(data[0]) - 0xD800) * 0x400 + + (ord(data[1]) - 0xDC00)) + return char_val + +# Module Factory Factory (no, this isn't Java, I know) +# Here to stop this being duplicated all over the place. + + +def moduleFactoryFactory(factory): + moduleCache = {} + + def moduleFactory(baseModule, *args, **kwargs): + if isinstance(ModuleType.__name__, type("")): + name = "_%s_factory" % baseModule.__name__ + else: + name = b"_%s_factory" % baseModule.__name__ + + kwargs_tuple = tuple(kwargs.items()) + + try: + return moduleCache[name][args][kwargs_tuple] + except KeyError: + mod = ModuleType(name) + objs = factory(baseModule, *args, **kwargs) + mod.__dict__.update(objs) + if "name" not in moduleCache: + moduleCache[name] = {} + if "args" not in moduleCache[name]: + moduleCache[name][args] = {} + if "kwargs" not in moduleCache[name][args]: + moduleCache[name][args][kwargs_tuple] = {} + moduleCache[name][args][kwargs_tuple] = mod + return mod + + return moduleFactory + + +def memoize(func): + cache = {} + + def wrapped(*args, **kwargs): + key = (tuple(args), tuple(kwargs.items())) + if key not in cache: + cache[key] = func(*args, **kwargs) + return cache[key] + + return wrapped diff --git a/venv/Lib/site-packages/pip/_vendor/html5lib/constants.py b/venv/Lib/site-packages/pip/_vendor/html5lib/constants.py new file mode 100644 index 0000000..fe3e237 --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/html5lib/constants.py @@ -0,0 +1,2946 @@ +from __future__ import absolute_import, division, unicode_literals + +import string + +EOF = None + +E = { + "null-character": + "Null character in input stream, replaced with U+FFFD.", + "invalid-codepoint": + "Invalid codepoint in stream.", + "incorrectly-placed-solidus": + "Solidus (/) incorrectly placed in tag.", + "incorrect-cr-newline-entity": + "Incorrect CR newline entity, replaced with LF.", + "illegal-windows-1252-entity": + "Entity used with illegal number (windows-1252 reference).", + "cant-convert-numeric-entity": + "Numeric entity couldn't be converted to character " + "(codepoint U+%(charAsInt)08x).", + "illegal-codepoint-for-numeric-entity": + "Numeric entity represents an illegal codepoint: " + "U+%(charAsInt)08x.", + "numeric-entity-without-semicolon": + "Numeric entity didn't end with ';'.", + "expected-numeric-entity-but-got-eof": + "Numeric entity expected. Got end of file instead.", + "expected-numeric-entity": + "Numeric entity expected but none found.", + "named-entity-without-semicolon": + "Named entity didn't end with ';'.", + "expected-named-entity": + "Named entity expected. Got none.", + "attributes-in-end-tag": + "End tag contains unexpected attributes.", + 'self-closing-flag-on-end-tag': + "End tag contains unexpected self-closing flag.", + "expected-tag-name-but-got-right-bracket": + "Expected tag name. Got '>' instead.", + "expected-tag-name-but-got-question-mark": + "Expected tag name. Got '?' instead. (HTML doesn't " + "support processing instructions.)", + "expected-tag-name": + "Expected tag name. Got something else instead", + "expected-closing-tag-but-got-right-bracket": + "Expected closing tag. Got '>' instead. Ignoring ''.", + "expected-closing-tag-but-got-eof": + "Expected closing tag. Unexpected end of file.", + "expected-closing-tag-but-got-char": + "Expected closing tag. Unexpected character '%(data)s' found.", + "eof-in-tag-name": + "Unexpected end of file in the tag name.", + "expected-attribute-name-but-got-eof": + "Unexpected end of file. Expected attribute name instead.", + "eof-in-attribute-name": + "Unexpected end of file in attribute name.", + "invalid-character-in-attribute-name": + "Invalid character in attribute name", + "duplicate-attribute": + "Dropped duplicate attribute on tag.", + "expected-end-of-tag-name-but-got-eof": + "Unexpected end of file. Expected = or end of tag.", + "expected-attribute-value-but-got-eof": + "Unexpected end of file. Expected attribute value.", + "expected-attribute-value-but-got-right-bracket": + "Expected attribute value. Got '>' instead.", + 'equals-in-unquoted-attribute-value': + "Unexpected = in unquoted attribute", + 'unexpected-character-in-unquoted-attribute-value': + "Unexpected character in unquoted attribute", + "invalid-character-after-attribute-name": + "Unexpected character after attribute name.", + "unexpected-character-after-attribute-value": + "Unexpected character after attribute value.", + "eof-in-attribute-value-double-quote": + "Unexpected end of file in attribute value (\").", + "eof-in-attribute-value-single-quote": + "Unexpected end of file in attribute value (').", + "eof-in-attribute-value-no-quotes": + "Unexpected end of file in attribute value.", + "unexpected-EOF-after-solidus-in-tag": + "Unexpected end of file in tag. Expected >", + "unexpected-character-after-solidus-in-tag": + "Unexpected character after / in tag. Expected >", + "expected-dashes-or-doctype": + "Expected '--' or 'DOCTYPE'. Not found.", + "unexpected-bang-after-double-dash-in-comment": + "Unexpected ! after -- in comment", + "unexpected-space-after-double-dash-in-comment": + "Unexpected space after -- in comment", + "incorrect-comment": + "Incorrect comment.", + "eof-in-comment": + "Unexpected end of file in comment.", + "eof-in-comment-end-dash": + "Unexpected end of file in comment (-)", + "unexpected-dash-after-double-dash-in-comment": + "Unexpected '-' after '--' found in comment.", + "eof-in-comment-double-dash": + "Unexpected end of file in comment (--).", + "eof-in-comment-end-space-state": + "Unexpected end of file in comment.", + "eof-in-comment-end-bang-state": + "Unexpected end of file in comment.", + "unexpected-char-in-comment": + "Unexpected character in comment found.", + "need-space-after-doctype": + "No space after literal string 'DOCTYPE'.", + "expected-doctype-name-but-got-right-bracket": + "Unexpected > character. Expected DOCTYPE name.", + "expected-doctype-name-but-got-eof": + "Unexpected end of file. Expected DOCTYPE name.", + "eof-in-doctype-name": + "Unexpected end of file in DOCTYPE name.", + "eof-in-doctype": + "Unexpected end of file in DOCTYPE.", + "expected-space-or-right-bracket-in-doctype": + "Expected space or '>'. Got '%(data)s'", + "unexpected-end-of-doctype": + "Unexpected end of DOCTYPE.", + "unexpected-char-in-doctype": + "Unexpected character in DOCTYPE.", + "eof-in-innerhtml": + "XXX innerHTML EOF", + "unexpected-doctype": + "Unexpected DOCTYPE. Ignored.", + "non-html-root": + "html needs to be the first start tag.", + "expected-doctype-but-got-eof": + "Unexpected End of file. Expected DOCTYPE.", + "unknown-doctype": + "Erroneous DOCTYPE.", + "expected-doctype-but-got-chars": + "Unexpected non-space characters. Expected DOCTYPE.", + "expected-doctype-but-got-start-tag": + "Unexpected start tag (%(name)s). Expected DOCTYPE.", + "expected-doctype-but-got-end-tag": + "Unexpected end tag (%(name)s). Expected DOCTYPE.", + "end-tag-after-implied-root": + "Unexpected end tag (%(name)s) after the (implied) root element.", + "expected-named-closing-tag-but-got-eof": + "Unexpected end of file. Expected end tag (%(name)s).", + "two-heads-are-not-better-than-one": + "Unexpected start tag head in existing head. Ignored.", + "unexpected-end-tag": + "Unexpected end tag (%(name)s). Ignored.", + "unexpected-start-tag-out-of-my-head": + "Unexpected start tag (%(name)s) that can be in head. Moved.", + "unexpected-start-tag": + "Unexpected start tag (%(name)s).", + "missing-end-tag": + "Missing end tag (%(name)s).", + "missing-end-tags": + "Missing end tags (%(name)s).", + "unexpected-start-tag-implies-end-tag": + "Unexpected start tag (%(startName)s) " + "implies end tag (%(endName)s).", + "unexpected-start-tag-treated-as": + "Unexpected start tag (%(originalName)s). Treated as %(newName)s.", + "deprecated-tag": + "Unexpected start tag %(name)s. Don't use it!", + "unexpected-start-tag-ignored": + "Unexpected start tag %(name)s. Ignored.", + "expected-one-end-tag-but-got-another": + "Unexpected end tag (%(gotName)s). " + "Missing end tag (%(expectedName)s).", + "end-tag-too-early": + "End tag (%(name)s) seen too early. Expected other end tag.", + "end-tag-too-early-named": + "Unexpected end tag (%(gotName)s). Expected end tag (%(expectedName)s).", + "end-tag-too-early-ignored": + "End tag (%(name)s) seen too early. Ignored.", + "adoption-agency-1.1": + "End tag (%(name)s) violates step 1, " + "paragraph 1 of the adoption agency algorithm.", + "adoption-agency-1.2": + "End tag (%(name)s) violates step 1, " + "paragraph 2 of the adoption agency algorithm.", + "adoption-agency-1.3": + "End tag (%(name)s) violates step 1, " + "paragraph 3 of the adoption agency algorithm.", + "adoption-agency-4.4": + "End tag (%(name)s) violates step 4, " + "paragraph 4 of the adoption agency algorithm.", + "unexpected-end-tag-treated-as": + "Unexpected end tag (%(originalName)s). Treated as %(newName)s.", + "no-end-tag": + "This element (%(name)s) has no end tag.", + "unexpected-implied-end-tag-in-table": + "Unexpected implied end tag (%(name)s) in the table phase.", + "unexpected-implied-end-tag-in-table-body": + "Unexpected implied end tag (%(name)s) in the table body phase.", + "unexpected-char-implies-table-voodoo": + "Unexpected non-space characters in " + "table context caused voodoo mode.", + "unexpected-hidden-input-in-table": + "Unexpected input with type hidden in table context.", + "unexpected-form-in-table": + "Unexpected form in table context.", + "unexpected-start-tag-implies-table-voodoo": + "Unexpected start tag (%(name)s) in " + "table context caused voodoo mode.", + "unexpected-end-tag-implies-table-voodoo": + "Unexpected end tag (%(name)s) in " + "table context caused voodoo mode.", + "unexpected-cell-in-table-body": + "Unexpected table cell start tag (%(name)s) " + "in the table body phase.", + "unexpected-cell-end-tag": + "Got table cell end tag (%(name)s) " + "while required end tags are missing.", + "unexpected-end-tag-in-table-body": + "Unexpected end tag (%(name)s) in the table body phase. Ignored.", + "unexpected-implied-end-tag-in-table-row": + "Unexpected implied end tag (%(name)s) in the table row phase.", + "unexpected-end-tag-in-table-row": + "Unexpected end tag (%(name)s) in the table row phase. Ignored.", + "unexpected-select-in-select": + "Unexpected select start tag in the select phase " + "treated as select end tag.", + "unexpected-input-in-select": + "Unexpected input start tag in the select phase.", + "unexpected-start-tag-in-select": + "Unexpected start tag token (%(name)s in the select phase. " + "Ignored.", + "unexpected-end-tag-in-select": + "Unexpected end tag (%(name)s) in the select phase. Ignored.", + "unexpected-table-element-start-tag-in-select-in-table": + "Unexpected table element start tag (%(name)s) in the select in table phase.", + "unexpected-table-element-end-tag-in-select-in-table": + "Unexpected table element end tag (%(name)s) in the select in table phase.", + "unexpected-char-after-body": + "Unexpected non-space characters in the after body phase.", + "unexpected-start-tag-after-body": + "Unexpected start tag token (%(name)s)" + " in the after body phase.", + "unexpected-end-tag-after-body": + "Unexpected end tag token (%(name)s)" + " in the after body phase.", + "unexpected-char-in-frameset": + "Unexpected characters in the frameset phase. Characters ignored.", + "unexpected-start-tag-in-frameset": + "Unexpected start tag token (%(name)s)" + " in the frameset phase. Ignored.", + "unexpected-frameset-in-frameset-innerhtml": + "Unexpected end tag token (frameset) " + "in the frameset phase (innerHTML).", + "unexpected-end-tag-in-frameset": + "Unexpected end tag token (%(name)s)" + " in the frameset phase. Ignored.", + "unexpected-char-after-frameset": + "Unexpected non-space characters in the " + "after frameset phase. Ignored.", + "unexpected-start-tag-after-frameset": + "Unexpected start tag (%(name)s)" + " in the after frameset phase. Ignored.", + "unexpected-end-tag-after-frameset": + "Unexpected end tag (%(name)s)" + " in the after frameset phase. Ignored.", + "unexpected-end-tag-after-body-innerhtml": + "Unexpected end tag after body(innerHtml)", + "expected-eof-but-got-char": + "Unexpected non-space characters. Expected end of file.", + "expected-eof-but-got-start-tag": + "Unexpected start tag (%(name)s)" + ". Expected end of file.", + "expected-eof-but-got-end-tag": + "Unexpected end tag (%(name)s)" + ". Expected end of file.", + "eof-in-table": + "Unexpected end of file. Expected table content.", + "eof-in-select": + "Unexpected end of file. Expected select content.", + "eof-in-frameset": + "Unexpected end of file. Expected frameset content.", + "eof-in-script-in-script": + "Unexpected end of file. Expected script content.", + "eof-in-foreign-lands": + "Unexpected end of file. Expected foreign content", + "non-void-element-with-trailing-solidus": + "Trailing solidus not allowed on element %(name)s", + "unexpected-html-element-in-foreign-content": + "Element %(name)s not allowed in a non-html context", + "unexpected-end-tag-before-html": + "Unexpected end tag (%(name)s) before html.", + "unexpected-inhead-noscript-tag": + "Element %(name)s not allowed in a inhead-noscript context", + "eof-in-head-noscript": + "Unexpected end of file. Expected inhead-noscript content", + "char-in-head-noscript": + "Unexpected non-space character. Expected inhead-noscript content", + "XXX-undefined-error": + "Undefined error (this sucks and should be fixed)", +} + +namespaces = { + "html": "http://www.w3.org/1999/xhtml", + "mathml": "http://www.w3.org/1998/Math/MathML", + "svg": "http://www.w3.org/2000/svg", + "xlink": "http://www.w3.org/1999/xlink", + "xml": "http://www.w3.org/XML/1998/namespace", + "xmlns": "http://www.w3.org/2000/xmlns/" +} + +scopingElements = frozenset([ + (namespaces["html"], "applet"), + (namespaces["html"], "caption"), + (namespaces["html"], "html"), + (namespaces["html"], "marquee"), + (namespaces["html"], "object"), + (namespaces["html"], "table"), + (namespaces["html"], "td"), + (namespaces["html"], "th"), + (namespaces["mathml"], "mi"), + (namespaces["mathml"], "mo"), + (namespaces["mathml"], "mn"), + (namespaces["mathml"], "ms"), + (namespaces["mathml"], "mtext"), + (namespaces["mathml"], "annotation-xml"), + (namespaces["svg"], "foreignObject"), + (namespaces["svg"], "desc"), + (namespaces["svg"], "title"), +]) + +formattingElements = frozenset([ + (namespaces["html"], "a"), + (namespaces["html"], "b"), + (namespaces["html"], "big"), + (namespaces["html"], "code"), + (namespaces["html"], "em"), + (namespaces["html"], "font"), + (namespaces["html"], "i"), + (namespaces["html"], "nobr"), + (namespaces["html"], "s"), + (namespaces["html"], "small"), + (namespaces["html"], "strike"), + (namespaces["html"], "strong"), + (namespaces["html"], "tt"), + (namespaces["html"], "u") +]) + +specialElements = frozenset([ + (namespaces["html"], "address"), + (namespaces["html"], "applet"), + (namespaces["html"], "area"), + (namespaces["html"], "article"), + (namespaces["html"], "aside"), + (namespaces["html"], "base"), + (namespaces["html"], "basefont"), + (namespaces["html"], "bgsound"), + (namespaces["html"], "blockquote"), + (namespaces["html"], "body"), + (namespaces["html"], "br"), + (namespaces["html"], "button"), + (namespaces["html"], "caption"), + (namespaces["html"], "center"), + (namespaces["html"], "col"), + (namespaces["html"], "colgroup"), + (namespaces["html"], "command"), + (namespaces["html"], "dd"), + (namespaces["html"], "details"), + (namespaces["html"], "dir"), + (namespaces["html"], "div"), + (namespaces["html"], "dl"), + (namespaces["html"], "dt"), + (namespaces["html"], "embed"), + (namespaces["html"], "fieldset"), + (namespaces["html"], "figure"), + (namespaces["html"], "footer"), + (namespaces["html"], "form"), + (namespaces["html"], "frame"), + (namespaces["html"], "frameset"), + (namespaces["html"], "h1"), + (namespaces["html"], "h2"), + (namespaces["html"], "h3"), + (namespaces["html"], "h4"), + (namespaces["html"], "h5"), + (namespaces["html"], "h6"), + (namespaces["html"], "head"), + (namespaces["html"], "header"), + (namespaces["html"], "hr"), + (namespaces["html"], "html"), + (namespaces["html"], "iframe"), + # Note that image is commented out in the spec as "this isn't an + # element that can end up on the stack, so it doesn't matter," + (namespaces["html"], "image"), + (namespaces["html"], "img"), + (namespaces["html"], "input"), + (namespaces["html"], "isindex"), + (namespaces["html"], "li"), + (namespaces["html"], "link"), + (namespaces["html"], "listing"), + (namespaces["html"], "marquee"), + (namespaces["html"], "menu"), + (namespaces["html"], "meta"), + (namespaces["html"], "nav"), + (namespaces["html"], "noembed"), + (namespaces["html"], "noframes"), + (namespaces["html"], "noscript"), + (namespaces["html"], "object"), + (namespaces["html"], "ol"), + (namespaces["html"], "p"), + (namespaces["html"], "param"), + (namespaces["html"], "plaintext"), + (namespaces["html"], "pre"), + (namespaces["html"], "script"), + (namespaces["html"], "section"), + (namespaces["html"], "select"), + (namespaces["html"], "style"), + (namespaces["html"], "table"), + (namespaces["html"], "tbody"), + (namespaces["html"], "td"), + (namespaces["html"], "textarea"), + (namespaces["html"], "tfoot"), + (namespaces["html"], "th"), + (namespaces["html"], "thead"), + (namespaces["html"], "title"), + (namespaces["html"], "tr"), + (namespaces["html"], "ul"), + (namespaces["html"], "wbr"), + (namespaces["html"], "xmp"), + (namespaces["svg"], "foreignObject") +]) + +htmlIntegrationPointElements = frozenset([ + (namespaces["mathml"], "annotation-xml"), + (namespaces["svg"], "foreignObject"), + (namespaces["svg"], "desc"), + (namespaces["svg"], "title") +]) + +mathmlTextIntegrationPointElements = frozenset([ + (namespaces["mathml"], "mi"), + (namespaces["mathml"], "mo"), + (namespaces["mathml"], "mn"), + (namespaces["mathml"], "ms"), + (namespaces["mathml"], "mtext") +]) + +adjustSVGAttributes = { + "attributename": "attributeName", + "attributetype": "attributeType", + "basefrequency": "baseFrequency", + "baseprofile": "baseProfile", + "calcmode": "calcMode", + "clippathunits": "clipPathUnits", + "contentscripttype": "contentScriptType", + "contentstyletype": "contentStyleType", + "diffuseconstant": "diffuseConstant", + "edgemode": "edgeMode", + "externalresourcesrequired": "externalResourcesRequired", + "filterres": "filterRes", + "filterunits": "filterUnits", + "glyphref": "glyphRef", + "gradienttransform": "gradientTransform", + "gradientunits": "gradientUnits", + "kernelmatrix": "kernelMatrix", + "kernelunitlength": "kernelUnitLength", + "keypoints": "keyPoints", + "keysplines": "keySplines", + "keytimes": "keyTimes", + "lengthadjust": "lengthAdjust", + "limitingconeangle": "limitingConeAngle", + "markerheight": "markerHeight", + "markerunits": "markerUnits", + "markerwidth": "markerWidth", + "maskcontentunits": "maskContentUnits", + "maskunits": "maskUnits", + "numoctaves": "numOctaves", + "pathlength": "pathLength", + "patterncontentunits": "patternContentUnits", + "patterntransform": "patternTransform", + "patternunits": "patternUnits", + "pointsatx": "pointsAtX", + "pointsaty": "pointsAtY", + "pointsatz": "pointsAtZ", + "preservealpha": "preserveAlpha", + "preserveaspectratio": "preserveAspectRatio", + "primitiveunits": "primitiveUnits", + "refx": "refX", + "refy": "refY", + "repeatcount": "repeatCount", + "repeatdur": "repeatDur", + "requiredextensions": "requiredExtensions", + "requiredfeatures": "requiredFeatures", + "specularconstant": "specularConstant", + "specularexponent": "specularExponent", + "spreadmethod": "spreadMethod", + "startoffset": "startOffset", + "stddeviation": "stdDeviation", + "stitchtiles": "stitchTiles", + "surfacescale": "surfaceScale", + "systemlanguage": "systemLanguage", + "tablevalues": "tableValues", + "targetx": "targetX", + "targety": "targetY", + "textlength": "textLength", + "viewbox": "viewBox", + "viewtarget": "viewTarget", + "xchannelselector": "xChannelSelector", + "ychannelselector": "yChannelSelector", + "zoomandpan": "zoomAndPan" +} + +adjustMathMLAttributes = {"definitionurl": "definitionURL"} + +adjustForeignAttributes = { + "xlink:actuate": ("xlink", "actuate", namespaces["xlink"]), + "xlink:arcrole": ("xlink", "arcrole", namespaces["xlink"]), + "xlink:href": ("xlink", "href", namespaces["xlink"]), + "xlink:role": ("xlink", "role", namespaces["xlink"]), + "xlink:show": ("xlink", "show", namespaces["xlink"]), + "xlink:title": ("xlink", "title", namespaces["xlink"]), + "xlink:type": ("xlink", "type", namespaces["xlink"]), + "xml:base": ("xml", "base", namespaces["xml"]), + "xml:lang": ("xml", "lang", namespaces["xml"]), + "xml:space": ("xml", "space", namespaces["xml"]), + "xmlns": (None, "xmlns", namespaces["xmlns"]), + "xmlns:xlink": ("xmlns", "xlink", namespaces["xmlns"]) +} + +unadjustForeignAttributes = {(ns, local): qname for qname, (prefix, local, ns) in + adjustForeignAttributes.items()} + +spaceCharacters = frozenset([ + "\t", + "\n", + "\u000C", + " ", + "\r" +]) + +tableInsertModeElements = frozenset([ + "table", + "tbody", + "tfoot", + "thead", + "tr" +]) + +asciiLowercase = frozenset(string.ascii_lowercase) +asciiUppercase = frozenset(string.ascii_uppercase) +asciiLetters = frozenset(string.ascii_letters) +digits = frozenset(string.digits) +hexDigits = frozenset(string.hexdigits) + +asciiUpper2Lower = {ord(c): ord(c.lower()) for c in string.ascii_uppercase} + +# Heading elements need to be ordered +headingElements = ( + "h1", + "h2", + "h3", + "h4", + "h5", + "h6" +) + +voidElements = frozenset([ + "base", + "command", + "event-source", + "link", + "meta", + "hr", + "br", + "img", + "embed", + "param", + "area", + "col", + "input", + "source", + "track" +]) + +cdataElements = frozenset(['title', 'textarea']) + +rcdataElements = frozenset([ + 'style', + 'script', + 'xmp', + 'iframe', + 'noembed', + 'noframes', + 'noscript' +]) + +booleanAttributes = { + "": frozenset(["irrelevant", "itemscope"]), + "style": frozenset(["scoped"]), + "img": frozenset(["ismap"]), + "audio": frozenset(["autoplay", "controls"]), + "video": frozenset(["autoplay", "controls"]), + "script": frozenset(["defer", "async"]), + "details": frozenset(["open"]), + "datagrid": frozenset(["multiple", "disabled"]), + "command": frozenset(["hidden", "disabled", "checked", "default"]), + "hr": frozenset(["noshade"]), + "menu": frozenset(["autosubmit"]), + "fieldset": frozenset(["disabled", "readonly"]), + "option": frozenset(["disabled", "readonly", "selected"]), + "optgroup": frozenset(["disabled", "readonly"]), + "button": frozenset(["disabled", "autofocus"]), + "input": frozenset(["disabled", "readonly", "required", "autofocus", "checked", "ismap"]), + "select": frozenset(["disabled", "readonly", "autofocus", "multiple"]), + "output": frozenset(["disabled", "readonly"]), + "iframe": frozenset(["seamless"]), +} + +# entitiesWindows1252 has to be _ordered_ and needs to have an index. It +# therefore can't be a frozenset. +entitiesWindows1252 = ( + 8364, # 0x80 0x20AC EURO SIGN + 65533, # 0x81 UNDEFINED + 8218, # 0x82 0x201A SINGLE LOW-9 QUOTATION MARK + 402, # 0x83 0x0192 LATIN SMALL LETTER F WITH HOOK + 8222, # 0x84 0x201E DOUBLE LOW-9 QUOTATION MARK + 8230, # 0x85 0x2026 HORIZONTAL ELLIPSIS + 8224, # 0x86 0x2020 DAGGER + 8225, # 0x87 0x2021 DOUBLE DAGGER + 710, # 0x88 0x02C6 MODIFIER LETTER CIRCUMFLEX ACCENT + 8240, # 0x89 0x2030 PER MILLE SIGN + 352, # 0x8A 0x0160 LATIN CAPITAL LETTER S WITH CARON + 8249, # 0x8B 0x2039 SINGLE LEFT-POINTING ANGLE QUOTATION MARK + 338, # 0x8C 0x0152 LATIN CAPITAL LIGATURE OE + 65533, # 0x8D UNDEFINED + 381, # 0x8E 0x017D LATIN CAPITAL LETTER Z WITH CARON + 65533, # 0x8F UNDEFINED + 65533, # 0x90 UNDEFINED + 8216, # 0x91 0x2018 LEFT SINGLE QUOTATION MARK + 8217, # 0x92 0x2019 RIGHT SINGLE QUOTATION MARK + 8220, # 0x93 0x201C LEFT DOUBLE QUOTATION MARK + 8221, # 0x94 0x201D RIGHT DOUBLE QUOTATION MARK + 8226, # 0x95 0x2022 BULLET + 8211, # 0x96 0x2013 EN DASH + 8212, # 0x97 0x2014 EM DASH + 732, # 0x98 0x02DC SMALL TILDE + 8482, # 0x99 0x2122 TRADE MARK SIGN + 353, # 0x9A 0x0161 LATIN SMALL LETTER S WITH CARON + 8250, # 0x9B 0x203A SINGLE RIGHT-POINTING ANGLE QUOTATION MARK + 339, # 0x9C 0x0153 LATIN SMALL LIGATURE OE + 65533, # 0x9D UNDEFINED + 382, # 0x9E 0x017E LATIN SMALL LETTER Z WITH CARON + 376 # 0x9F 0x0178 LATIN CAPITAL LETTER Y WITH DIAERESIS +) + +xmlEntities = frozenset(['lt;', 'gt;', 'amp;', 'apos;', 'quot;']) + +entities = { + "AElig": "\xc6", + "AElig;": "\xc6", + "AMP": "&", + "AMP;": "&", + "Aacute": "\xc1", + "Aacute;": "\xc1", + "Abreve;": "\u0102", + "Acirc": "\xc2", + "Acirc;": "\xc2", + "Acy;": "\u0410", + "Afr;": "\U0001d504", + "Agrave": "\xc0", + "Agrave;": "\xc0", + "Alpha;": "\u0391", + "Amacr;": "\u0100", + "And;": "\u2a53", + "Aogon;": "\u0104", + "Aopf;": "\U0001d538", + "ApplyFunction;": "\u2061", + "Aring": "\xc5", + "Aring;": "\xc5", + "Ascr;": "\U0001d49c", + "Assign;": "\u2254", + "Atilde": "\xc3", + "Atilde;": "\xc3", + "Auml": "\xc4", + "Auml;": "\xc4", + "Backslash;": "\u2216", + "Barv;": "\u2ae7", + "Barwed;": "\u2306", + "Bcy;": "\u0411", + "Because;": "\u2235", + "Bernoullis;": "\u212c", + "Beta;": "\u0392", + "Bfr;": "\U0001d505", + "Bopf;": "\U0001d539", + "Breve;": "\u02d8", + "Bscr;": "\u212c", + "Bumpeq;": "\u224e", + "CHcy;": "\u0427", + "COPY": "\xa9", + "COPY;": "\xa9", + "Cacute;": "\u0106", + "Cap;": "\u22d2", + "CapitalDifferentialD;": "\u2145", + "Cayleys;": "\u212d", + "Ccaron;": "\u010c", + "Ccedil": "\xc7", + "Ccedil;": "\xc7", + "Ccirc;": "\u0108", + "Cconint;": "\u2230", + "Cdot;": "\u010a", + "Cedilla;": "\xb8", + "CenterDot;": "\xb7", + "Cfr;": "\u212d", + "Chi;": "\u03a7", + "CircleDot;": "\u2299", + "CircleMinus;": "\u2296", + "CirclePlus;": "\u2295", + "CircleTimes;": "\u2297", + "ClockwiseContourIntegral;": "\u2232", + "CloseCurlyDoubleQuote;": "\u201d", + "CloseCurlyQuote;": "\u2019", + "Colon;": "\u2237", + "Colone;": "\u2a74", + "Congruent;": "\u2261", + "Conint;": "\u222f", + "ContourIntegral;": "\u222e", + "Copf;": "\u2102", + "Coproduct;": "\u2210", + "CounterClockwiseContourIntegral;": "\u2233", + "Cross;": "\u2a2f", + "Cscr;": "\U0001d49e", + "Cup;": "\u22d3", + "CupCap;": "\u224d", + "DD;": "\u2145", + "DDotrahd;": "\u2911", + "DJcy;": "\u0402", + "DScy;": "\u0405", + "DZcy;": "\u040f", + "Dagger;": "\u2021", + "Darr;": "\u21a1", + "Dashv;": "\u2ae4", + "Dcaron;": "\u010e", + "Dcy;": "\u0414", + "Del;": "\u2207", + "Delta;": "\u0394", + "Dfr;": "\U0001d507", + "DiacriticalAcute;": "\xb4", + "DiacriticalDot;": "\u02d9", + "DiacriticalDoubleAcute;": "\u02dd", + "DiacriticalGrave;": "`", + "DiacriticalTilde;": "\u02dc", + "Diamond;": "\u22c4", + "DifferentialD;": "\u2146", + "Dopf;": "\U0001d53b", + "Dot;": "\xa8", + "DotDot;": "\u20dc", + "DotEqual;": "\u2250", + "DoubleContourIntegral;": "\u222f", + "DoubleDot;": "\xa8", + "DoubleDownArrow;": "\u21d3", + "DoubleLeftArrow;": "\u21d0", + "DoubleLeftRightArrow;": "\u21d4", + "DoubleLeftTee;": "\u2ae4", + "DoubleLongLeftArrow;": "\u27f8", + "DoubleLongLeftRightArrow;": "\u27fa", + "DoubleLongRightArrow;": "\u27f9", + "DoubleRightArrow;": "\u21d2", + "DoubleRightTee;": "\u22a8", + "DoubleUpArrow;": "\u21d1", + "DoubleUpDownArrow;": "\u21d5", + "DoubleVerticalBar;": "\u2225", + "DownArrow;": "\u2193", + "DownArrowBar;": "\u2913", + "DownArrowUpArrow;": "\u21f5", + "DownBreve;": "\u0311", + "DownLeftRightVector;": "\u2950", + "DownLeftTeeVector;": "\u295e", + "DownLeftVector;": "\u21bd", + "DownLeftVectorBar;": "\u2956", + "DownRightTeeVector;": "\u295f", + "DownRightVector;": "\u21c1", + "DownRightVectorBar;": "\u2957", + "DownTee;": "\u22a4", + "DownTeeArrow;": "\u21a7", + "Downarrow;": "\u21d3", + "Dscr;": "\U0001d49f", + "Dstrok;": "\u0110", + "ENG;": "\u014a", + "ETH": "\xd0", + "ETH;": "\xd0", + "Eacute": "\xc9", + "Eacute;": "\xc9", + "Ecaron;": "\u011a", + "Ecirc": "\xca", + "Ecirc;": "\xca", + "Ecy;": "\u042d", + "Edot;": "\u0116", + "Efr;": "\U0001d508", + "Egrave": "\xc8", + "Egrave;": "\xc8", + "Element;": "\u2208", + "Emacr;": "\u0112", + "EmptySmallSquare;": "\u25fb", + "EmptyVerySmallSquare;": "\u25ab", + "Eogon;": "\u0118", + "Eopf;": "\U0001d53c", + "Epsilon;": "\u0395", + "Equal;": "\u2a75", + "EqualTilde;": "\u2242", + "Equilibrium;": "\u21cc", + "Escr;": "\u2130", + "Esim;": "\u2a73", + "Eta;": "\u0397", + "Euml": "\xcb", + "Euml;": "\xcb", + "Exists;": "\u2203", + "ExponentialE;": "\u2147", + "Fcy;": "\u0424", + "Ffr;": "\U0001d509", + "FilledSmallSquare;": "\u25fc", + "FilledVerySmallSquare;": "\u25aa", + "Fopf;": "\U0001d53d", + "ForAll;": "\u2200", + "Fouriertrf;": "\u2131", + "Fscr;": "\u2131", + "GJcy;": "\u0403", + "GT": ">", + "GT;": ">", + "Gamma;": "\u0393", + "Gammad;": "\u03dc", + "Gbreve;": "\u011e", + "Gcedil;": "\u0122", + "Gcirc;": "\u011c", + "Gcy;": "\u0413", + "Gdot;": "\u0120", + "Gfr;": "\U0001d50a", + "Gg;": "\u22d9", + "Gopf;": "\U0001d53e", + "GreaterEqual;": "\u2265", + "GreaterEqualLess;": "\u22db", + "GreaterFullEqual;": "\u2267", + "GreaterGreater;": "\u2aa2", + "GreaterLess;": "\u2277", + "GreaterSlantEqual;": "\u2a7e", + "GreaterTilde;": "\u2273", + "Gscr;": "\U0001d4a2", + "Gt;": "\u226b", + "HARDcy;": "\u042a", + "Hacek;": "\u02c7", + "Hat;": "^", + "Hcirc;": "\u0124", + "Hfr;": "\u210c", + "HilbertSpace;": "\u210b", + "Hopf;": "\u210d", + "HorizontalLine;": "\u2500", + "Hscr;": "\u210b", + "Hstrok;": "\u0126", + "HumpDownHump;": "\u224e", + "HumpEqual;": "\u224f", + "IEcy;": "\u0415", + "IJlig;": "\u0132", + "IOcy;": "\u0401", + "Iacute": "\xcd", + "Iacute;": "\xcd", + "Icirc": "\xce", + "Icirc;": "\xce", + "Icy;": "\u0418", + "Idot;": "\u0130", + "Ifr;": "\u2111", + "Igrave": "\xcc", + "Igrave;": "\xcc", + "Im;": "\u2111", + "Imacr;": "\u012a", + "ImaginaryI;": "\u2148", + "Implies;": "\u21d2", + "Int;": "\u222c", + "Integral;": "\u222b", + "Intersection;": "\u22c2", + "InvisibleComma;": "\u2063", + "InvisibleTimes;": "\u2062", + "Iogon;": "\u012e", + "Iopf;": "\U0001d540", + "Iota;": "\u0399", + "Iscr;": "\u2110", + "Itilde;": "\u0128", + "Iukcy;": "\u0406", + "Iuml": "\xcf", + "Iuml;": "\xcf", + "Jcirc;": "\u0134", + "Jcy;": "\u0419", + "Jfr;": "\U0001d50d", + "Jopf;": "\U0001d541", + "Jscr;": "\U0001d4a5", + "Jsercy;": "\u0408", + "Jukcy;": "\u0404", + "KHcy;": "\u0425", + "KJcy;": "\u040c", + "Kappa;": "\u039a", + "Kcedil;": "\u0136", + "Kcy;": "\u041a", + "Kfr;": "\U0001d50e", + "Kopf;": "\U0001d542", + "Kscr;": "\U0001d4a6", + "LJcy;": "\u0409", + "LT": "<", + "LT;": "<", + "Lacute;": "\u0139", + "Lambda;": "\u039b", + "Lang;": "\u27ea", + "Laplacetrf;": "\u2112", + "Larr;": "\u219e", + "Lcaron;": "\u013d", + "Lcedil;": "\u013b", + "Lcy;": "\u041b", + "LeftAngleBracket;": "\u27e8", + "LeftArrow;": "\u2190", + "LeftArrowBar;": "\u21e4", + "LeftArrowRightArrow;": "\u21c6", + "LeftCeiling;": "\u2308", + "LeftDoubleBracket;": "\u27e6", + "LeftDownTeeVector;": "\u2961", + "LeftDownVector;": "\u21c3", + "LeftDownVectorBar;": "\u2959", + "LeftFloor;": "\u230a", + "LeftRightArrow;": "\u2194", + "LeftRightVector;": "\u294e", + "LeftTee;": "\u22a3", + "LeftTeeArrow;": "\u21a4", + "LeftTeeVector;": "\u295a", + "LeftTriangle;": "\u22b2", + "LeftTriangleBar;": "\u29cf", + "LeftTriangleEqual;": "\u22b4", + "LeftUpDownVector;": "\u2951", + "LeftUpTeeVector;": "\u2960", + "LeftUpVector;": "\u21bf", + "LeftUpVectorBar;": "\u2958", + "LeftVector;": "\u21bc", + "LeftVectorBar;": "\u2952", + "Leftarrow;": "\u21d0", + "Leftrightarrow;": "\u21d4", + "LessEqualGreater;": "\u22da", + "LessFullEqual;": "\u2266", + "LessGreater;": "\u2276", + "LessLess;": "\u2aa1", + "LessSlantEqual;": "\u2a7d", + "LessTilde;": "\u2272", + "Lfr;": "\U0001d50f", + "Ll;": "\u22d8", + "Lleftarrow;": "\u21da", + "Lmidot;": "\u013f", + "LongLeftArrow;": "\u27f5", + "LongLeftRightArrow;": "\u27f7", + "LongRightArrow;": "\u27f6", + "Longleftarrow;": "\u27f8", + "Longleftrightarrow;": "\u27fa", + "Longrightarrow;": "\u27f9", + "Lopf;": "\U0001d543", + "LowerLeftArrow;": "\u2199", + "LowerRightArrow;": "\u2198", + "Lscr;": "\u2112", + "Lsh;": "\u21b0", + "Lstrok;": "\u0141", + "Lt;": "\u226a", + "Map;": "\u2905", + "Mcy;": "\u041c", + "MediumSpace;": "\u205f", + "Mellintrf;": "\u2133", + "Mfr;": "\U0001d510", + "MinusPlus;": "\u2213", + "Mopf;": "\U0001d544", + "Mscr;": "\u2133", + "Mu;": "\u039c", + "NJcy;": "\u040a", + "Nacute;": "\u0143", + "Ncaron;": "\u0147", + "Ncedil;": "\u0145", + "Ncy;": "\u041d", + "NegativeMediumSpace;": "\u200b", + "NegativeThickSpace;": "\u200b", + "NegativeThinSpace;": "\u200b", + "NegativeVeryThinSpace;": "\u200b", + "NestedGreaterGreater;": "\u226b", + "NestedLessLess;": "\u226a", + "NewLine;": "\n", + "Nfr;": "\U0001d511", + "NoBreak;": "\u2060", + "NonBreakingSpace;": "\xa0", + "Nopf;": "\u2115", + "Not;": "\u2aec", + "NotCongruent;": "\u2262", + "NotCupCap;": "\u226d", + "NotDoubleVerticalBar;": "\u2226", + "NotElement;": "\u2209", + "NotEqual;": "\u2260", + "NotEqualTilde;": "\u2242\u0338", + "NotExists;": "\u2204", + "NotGreater;": "\u226f", + "NotGreaterEqual;": "\u2271", + "NotGreaterFullEqual;": "\u2267\u0338", + "NotGreaterGreater;": "\u226b\u0338", + "NotGreaterLess;": "\u2279", + "NotGreaterSlantEqual;": "\u2a7e\u0338", + "NotGreaterTilde;": "\u2275", + "NotHumpDownHump;": "\u224e\u0338", + "NotHumpEqual;": "\u224f\u0338", + "NotLeftTriangle;": "\u22ea", + "NotLeftTriangleBar;": "\u29cf\u0338", + "NotLeftTriangleEqual;": "\u22ec", + "NotLess;": "\u226e", + "NotLessEqual;": "\u2270", + "NotLessGreater;": "\u2278", + "NotLessLess;": "\u226a\u0338", + "NotLessSlantEqual;": "\u2a7d\u0338", + "NotLessTilde;": "\u2274", + "NotNestedGreaterGreater;": "\u2aa2\u0338", + "NotNestedLessLess;": "\u2aa1\u0338", + "NotPrecedes;": "\u2280", + "NotPrecedesEqual;": "\u2aaf\u0338", + "NotPrecedesSlantEqual;": "\u22e0", + "NotReverseElement;": "\u220c", + "NotRightTriangle;": "\u22eb", + "NotRightTriangleBar;": "\u29d0\u0338", + "NotRightTriangleEqual;": "\u22ed", + "NotSquareSubset;": "\u228f\u0338", + "NotSquareSubsetEqual;": "\u22e2", + "NotSquareSuperset;": "\u2290\u0338", + "NotSquareSupersetEqual;": "\u22e3", + "NotSubset;": "\u2282\u20d2", + "NotSubsetEqual;": "\u2288", + "NotSucceeds;": "\u2281", + "NotSucceedsEqual;": "\u2ab0\u0338", + "NotSucceedsSlantEqual;": "\u22e1", + "NotSucceedsTilde;": "\u227f\u0338", + "NotSuperset;": "\u2283\u20d2", + "NotSupersetEqual;": "\u2289", + "NotTilde;": "\u2241", + "NotTildeEqual;": "\u2244", + "NotTildeFullEqual;": "\u2247", + "NotTildeTilde;": "\u2249", + "NotVerticalBar;": "\u2224", + "Nscr;": "\U0001d4a9", + "Ntilde": "\xd1", + "Ntilde;": "\xd1", + "Nu;": "\u039d", + "OElig;": "\u0152", + "Oacute": "\xd3", + "Oacute;": "\xd3", + "Ocirc": "\xd4", + "Ocirc;": "\xd4", + "Ocy;": "\u041e", + "Odblac;": "\u0150", + "Ofr;": "\U0001d512", + "Ograve": "\xd2", + "Ograve;": "\xd2", + "Omacr;": "\u014c", + "Omega;": "\u03a9", + "Omicron;": "\u039f", + "Oopf;": "\U0001d546", + "OpenCurlyDoubleQuote;": "\u201c", + "OpenCurlyQuote;": "\u2018", + "Or;": "\u2a54", + "Oscr;": "\U0001d4aa", + "Oslash": "\xd8", + "Oslash;": "\xd8", + "Otilde": "\xd5", + "Otilde;": "\xd5", + "Otimes;": "\u2a37", + "Ouml": "\xd6", + "Ouml;": "\xd6", + "OverBar;": "\u203e", + "OverBrace;": "\u23de", + "OverBracket;": "\u23b4", + "OverParenthesis;": "\u23dc", + "PartialD;": "\u2202", + "Pcy;": "\u041f", + "Pfr;": "\U0001d513", + "Phi;": "\u03a6", + "Pi;": "\u03a0", + "PlusMinus;": "\xb1", + "Poincareplane;": "\u210c", + "Popf;": "\u2119", + "Pr;": "\u2abb", + "Precedes;": "\u227a", + "PrecedesEqual;": "\u2aaf", + "PrecedesSlantEqual;": "\u227c", + "PrecedesTilde;": "\u227e", + "Prime;": "\u2033", + "Product;": "\u220f", + "Proportion;": "\u2237", + "Proportional;": "\u221d", + "Pscr;": "\U0001d4ab", + "Psi;": "\u03a8", + "QUOT": "\"", + "QUOT;": "\"", + "Qfr;": "\U0001d514", + "Qopf;": "\u211a", + "Qscr;": "\U0001d4ac", + "RBarr;": "\u2910", + "REG": "\xae", + "REG;": "\xae", + "Racute;": "\u0154", + "Rang;": "\u27eb", + "Rarr;": "\u21a0", + "Rarrtl;": "\u2916", + "Rcaron;": "\u0158", + "Rcedil;": "\u0156", + "Rcy;": "\u0420", + "Re;": "\u211c", + "ReverseElement;": "\u220b", + "ReverseEquilibrium;": "\u21cb", + "ReverseUpEquilibrium;": "\u296f", + "Rfr;": "\u211c", + "Rho;": "\u03a1", + "RightAngleBracket;": "\u27e9", + "RightArrow;": "\u2192", + "RightArrowBar;": "\u21e5", + "RightArrowLeftArrow;": "\u21c4", + "RightCeiling;": "\u2309", + "RightDoubleBracket;": "\u27e7", + "RightDownTeeVector;": "\u295d", + "RightDownVector;": "\u21c2", + "RightDownVectorBar;": "\u2955", + "RightFloor;": "\u230b", + "RightTee;": "\u22a2", + "RightTeeArrow;": "\u21a6", + "RightTeeVector;": "\u295b", + "RightTriangle;": "\u22b3", + "RightTriangleBar;": "\u29d0", + "RightTriangleEqual;": "\u22b5", + "RightUpDownVector;": "\u294f", + "RightUpTeeVector;": "\u295c", + "RightUpVector;": "\u21be", + "RightUpVectorBar;": "\u2954", + "RightVector;": "\u21c0", + "RightVectorBar;": "\u2953", + "Rightarrow;": "\u21d2", + "Ropf;": "\u211d", + "RoundImplies;": "\u2970", + "Rrightarrow;": "\u21db", + "Rscr;": "\u211b", + "Rsh;": "\u21b1", + "RuleDelayed;": "\u29f4", + "SHCHcy;": "\u0429", + "SHcy;": "\u0428", + "SOFTcy;": "\u042c", + "Sacute;": "\u015a", + "Sc;": "\u2abc", + "Scaron;": "\u0160", + "Scedil;": "\u015e", + "Scirc;": "\u015c", + "Scy;": "\u0421", + "Sfr;": "\U0001d516", + "ShortDownArrow;": "\u2193", + "ShortLeftArrow;": "\u2190", + "ShortRightArrow;": "\u2192", + "ShortUpArrow;": "\u2191", + "Sigma;": "\u03a3", + "SmallCircle;": "\u2218", + "Sopf;": "\U0001d54a", + "Sqrt;": "\u221a", + "Square;": "\u25a1", + "SquareIntersection;": "\u2293", + "SquareSubset;": "\u228f", + "SquareSubsetEqual;": "\u2291", + "SquareSuperset;": "\u2290", + "SquareSupersetEqual;": "\u2292", + "SquareUnion;": "\u2294", + "Sscr;": "\U0001d4ae", + "Star;": "\u22c6", + "Sub;": "\u22d0", + "Subset;": "\u22d0", + "SubsetEqual;": "\u2286", + "Succeeds;": "\u227b", + "SucceedsEqual;": "\u2ab0", + "SucceedsSlantEqual;": "\u227d", + "SucceedsTilde;": "\u227f", + "SuchThat;": "\u220b", + "Sum;": "\u2211", + "Sup;": "\u22d1", + "Superset;": "\u2283", + "SupersetEqual;": "\u2287", + "Supset;": "\u22d1", + "THORN": "\xde", + "THORN;": "\xde", + "TRADE;": "\u2122", + "TSHcy;": "\u040b", + "TScy;": "\u0426", + "Tab;": "\t", + "Tau;": "\u03a4", + "Tcaron;": "\u0164", + "Tcedil;": "\u0162", + "Tcy;": "\u0422", + "Tfr;": "\U0001d517", + "Therefore;": "\u2234", + "Theta;": "\u0398", + "ThickSpace;": "\u205f\u200a", + "ThinSpace;": "\u2009", + "Tilde;": "\u223c", + "TildeEqual;": "\u2243", + "TildeFullEqual;": "\u2245", + "TildeTilde;": "\u2248", + "Topf;": "\U0001d54b", + "TripleDot;": "\u20db", + "Tscr;": "\U0001d4af", + "Tstrok;": "\u0166", + "Uacute": "\xda", + "Uacute;": "\xda", + "Uarr;": "\u219f", + "Uarrocir;": "\u2949", + "Ubrcy;": "\u040e", + "Ubreve;": "\u016c", + "Ucirc": "\xdb", + "Ucirc;": "\xdb", + "Ucy;": "\u0423", + "Udblac;": "\u0170", + "Ufr;": "\U0001d518", + "Ugrave": "\xd9", + "Ugrave;": "\xd9", + "Umacr;": "\u016a", + "UnderBar;": "_", + "UnderBrace;": "\u23df", + "UnderBracket;": "\u23b5", + "UnderParenthesis;": "\u23dd", + "Union;": "\u22c3", + "UnionPlus;": "\u228e", + "Uogon;": "\u0172", + "Uopf;": "\U0001d54c", + "UpArrow;": "\u2191", + "UpArrowBar;": "\u2912", + "UpArrowDownArrow;": "\u21c5", + "UpDownArrow;": "\u2195", + "UpEquilibrium;": "\u296e", + "UpTee;": "\u22a5", + "UpTeeArrow;": "\u21a5", + "Uparrow;": "\u21d1", + "Updownarrow;": "\u21d5", + "UpperLeftArrow;": "\u2196", + "UpperRightArrow;": "\u2197", + "Upsi;": "\u03d2", + "Upsilon;": "\u03a5", + "Uring;": "\u016e", + "Uscr;": "\U0001d4b0", + "Utilde;": "\u0168", + "Uuml": "\xdc", + "Uuml;": "\xdc", + "VDash;": "\u22ab", + "Vbar;": "\u2aeb", + "Vcy;": "\u0412", + "Vdash;": "\u22a9", + "Vdashl;": "\u2ae6", + "Vee;": "\u22c1", + "Verbar;": "\u2016", + "Vert;": "\u2016", + "VerticalBar;": "\u2223", + "VerticalLine;": "|", + "VerticalSeparator;": "\u2758", + "VerticalTilde;": "\u2240", + "VeryThinSpace;": "\u200a", + "Vfr;": "\U0001d519", + "Vopf;": "\U0001d54d", + "Vscr;": "\U0001d4b1", + "Vvdash;": "\u22aa", + "Wcirc;": "\u0174", + "Wedge;": "\u22c0", + "Wfr;": "\U0001d51a", + "Wopf;": "\U0001d54e", + "Wscr;": "\U0001d4b2", + "Xfr;": "\U0001d51b", + "Xi;": "\u039e", + "Xopf;": "\U0001d54f", + "Xscr;": "\U0001d4b3", + "YAcy;": "\u042f", + "YIcy;": "\u0407", + "YUcy;": "\u042e", + "Yacute": "\xdd", + "Yacute;": "\xdd", + "Ycirc;": "\u0176", + "Ycy;": "\u042b", + "Yfr;": "\U0001d51c", + "Yopf;": "\U0001d550", + "Yscr;": "\U0001d4b4", + "Yuml;": "\u0178", + "ZHcy;": "\u0416", + "Zacute;": "\u0179", + "Zcaron;": "\u017d", + "Zcy;": "\u0417", + "Zdot;": "\u017b", + "ZeroWidthSpace;": "\u200b", + "Zeta;": "\u0396", + "Zfr;": "\u2128", + "Zopf;": "\u2124", + "Zscr;": "\U0001d4b5", + "aacute": "\xe1", + "aacute;": "\xe1", + "abreve;": "\u0103", + "ac;": "\u223e", + "acE;": "\u223e\u0333", + "acd;": "\u223f", + "acirc": "\xe2", + "acirc;": "\xe2", + "acute": "\xb4", + "acute;": "\xb4", + "acy;": "\u0430", + "aelig": "\xe6", + "aelig;": "\xe6", + "af;": "\u2061", + "afr;": "\U0001d51e", + "agrave": "\xe0", + "agrave;": "\xe0", + "alefsym;": "\u2135", + "aleph;": "\u2135", + "alpha;": "\u03b1", + "amacr;": "\u0101", + "amalg;": "\u2a3f", + "amp": "&", + "amp;": "&", + "and;": "\u2227", + "andand;": "\u2a55", + "andd;": "\u2a5c", + "andslope;": "\u2a58", + "andv;": "\u2a5a", + "ang;": "\u2220", + "ange;": "\u29a4", + "angle;": "\u2220", + "angmsd;": "\u2221", + "angmsdaa;": "\u29a8", + "angmsdab;": "\u29a9", + "angmsdac;": "\u29aa", + "angmsdad;": "\u29ab", + "angmsdae;": "\u29ac", + "angmsdaf;": "\u29ad", + "angmsdag;": "\u29ae", + "angmsdah;": "\u29af", + "angrt;": "\u221f", + "angrtvb;": "\u22be", + "angrtvbd;": "\u299d", + "angsph;": "\u2222", + "angst;": "\xc5", + "angzarr;": "\u237c", + "aogon;": "\u0105", + "aopf;": "\U0001d552", + "ap;": "\u2248", + "apE;": "\u2a70", + "apacir;": "\u2a6f", + "ape;": "\u224a", + "apid;": "\u224b", + "apos;": "'", + "approx;": "\u2248", + "approxeq;": "\u224a", + "aring": "\xe5", + "aring;": "\xe5", + "ascr;": "\U0001d4b6", + "ast;": "*", + "asymp;": "\u2248", + "asympeq;": "\u224d", + "atilde": "\xe3", + "atilde;": "\xe3", + "auml": "\xe4", + "auml;": "\xe4", + "awconint;": "\u2233", + "awint;": "\u2a11", + "bNot;": "\u2aed", + "backcong;": "\u224c", + "backepsilon;": "\u03f6", + "backprime;": "\u2035", + "backsim;": "\u223d", + "backsimeq;": "\u22cd", + "barvee;": "\u22bd", + "barwed;": "\u2305", + "barwedge;": "\u2305", + "bbrk;": "\u23b5", + "bbrktbrk;": "\u23b6", + "bcong;": "\u224c", + "bcy;": "\u0431", + "bdquo;": "\u201e", + "becaus;": "\u2235", + "because;": "\u2235", + "bemptyv;": "\u29b0", + "bepsi;": "\u03f6", + "bernou;": "\u212c", + "beta;": "\u03b2", + "beth;": "\u2136", + "between;": "\u226c", + "bfr;": "\U0001d51f", + "bigcap;": "\u22c2", + "bigcirc;": "\u25ef", + "bigcup;": "\u22c3", + "bigodot;": "\u2a00", + "bigoplus;": "\u2a01", + "bigotimes;": "\u2a02", + "bigsqcup;": "\u2a06", + "bigstar;": "\u2605", + "bigtriangledown;": "\u25bd", + "bigtriangleup;": "\u25b3", + "biguplus;": "\u2a04", + "bigvee;": "\u22c1", + "bigwedge;": "\u22c0", + "bkarow;": "\u290d", + "blacklozenge;": "\u29eb", + "blacksquare;": "\u25aa", + "blacktriangle;": "\u25b4", + "blacktriangledown;": "\u25be", + "blacktriangleleft;": "\u25c2", + "blacktriangleright;": "\u25b8", + "blank;": "\u2423", + "blk12;": "\u2592", + "blk14;": "\u2591", + "blk34;": "\u2593", + "block;": "\u2588", + "bne;": "=\u20e5", + "bnequiv;": "\u2261\u20e5", + "bnot;": "\u2310", + "bopf;": "\U0001d553", + "bot;": "\u22a5", + "bottom;": "\u22a5", + "bowtie;": "\u22c8", + "boxDL;": "\u2557", + "boxDR;": "\u2554", + "boxDl;": "\u2556", + "boxDr;": "\u2553", + "boxH;": "\u2550", + "boxHD;": "\u2566", + "boxHU;": "\u2569", + "boxHd;": "\u2564", + "boxHu;": "\u2567", + "boxUL;": "\u255d", + "boxUR;": "\u255a", + "boxUl;": "\u255c", + "boxUr;": "\u2559", + "boxV;": "\u2551", + "boxVH;": "\u256c", + "boxVL;": "\u2563", + "boxVR;": "\u2560", + "boxVh;": "\u256b", + "boxVl;": "\u2562", + "boxVr;": "\u255f", + "boxbox;": "\u29c9", + "boxdL;": "\u2555", + "boxdR;": "\u2552", + "boxdl;": "\u2510", + "boxdr;": "\u250c", + "boxh;": "\u2500", + "boxhD;": "\u2565", + "boxhU;": "\u2568", + "boxhd;": "\u252c", + "boxhu;": "\u2534", + "boxminus;": "\u229f", + "boxplus;": "\u229e", + "boxtimes;": "\u22a0", + "boxuL;": "\u255b", + "boxuR;": "\u2558", + "boxul;": "\u2518", + "boxur;": "\u2514", + "boxv;": "\u2502", + "boxvH;": "\u256a", + "boxvL;": "\u2561", + "boxvR;": "\u255e", + "boxvh;": "\u253c", + "boxvl;": "\u2524", + "boxvr;": "\u251c", + "bprime;": "\u2035", + "breve;": "\u02d8", + "brvbar": "\xa6", + "brvbar;": "\xa6", + "bscr;": "\U0001d4b7", + "bsemi;": "\u204f", + "bsim;": "\u223d", + "bsime;": "\u22cd", + "bsol;": "\\", + "bsolb;": "\u29c5", + "bsolhsub;": "\u27c8", + "bull;": "\u2022", + "bullet;": "\u2022", + "bump;": "\u224e", + "bumpE;": "\u2aae", + "bumpe;": "\u224f", + "bumpeq;": "\u224f", + "cacute;": "\u0107", + "cap;": "\u2229", + "capand;": "\u2a44", + "capbrcup;": "\u2a49", + "capcap;": "\u2a4b", + "capcup;": "\u2a47", + "capdot;": "\u2a40", + "caps;": "\u2229\ufe00", + "caret;": "\u2041", + "caron;": "\u02c7", + "ccaps;": "\u2a4d", + "ccaron;": "\u010d", + "ccedil": "\xe7", + "ccedil;": "\xe7", + "ccirc;": "\u0109", + "ccups;": "\u2a4c", + "ccupssm;": "\u2a50", + "cdot;": "\u010b", + "cedil": "\xb8", + "cedil;": "\xb8", + "cemptyv;": "\u29b2", + "cent": "\xa2", + "cent;": "\xa2", + "centerdot;": "\xb7", + "cfr;": "\U0001d520", + "chcy;": "\u0447", + "check;": "\u2713", + "checkmark;": "\u2713", + "chi;": "\u03c7", + "cir;": "\u25cb", + "cirE;": "\u29c3", + "circ;": "\u02c6", + "circeq;": "\u2257", + "circlearrowleft;": "\u21ba", + "circlearrowright;": "\u21bb", + "circledR;": "\xae", + "circledS;": "\u24c8", + "circledast;": "\u229b", + "circledcirc;": "\u229a", + "circleddash;": "\u229d", + "cire;": "\u2257", + "cirfnint;": "\u2a10", + "cirmid;": "\u2aef", + "cirscir;": "\u29c2", + "clubs;": "\u2663", + "clubsuit;": "\u2663", + "colon;": ":", + "colone;": "\u2254", + "coloneq;": "\u2254", + "comma;": ",", + "commat;": "@", + "comp;": "\u2201", + "compfn;": "\u2218", + "complement;": "\u2201", + "complexes;": "\u2102", + "cong;": "\u2245", + "congdot;": "\u2a6d", + "conint;": "\u222e", + "copf;": "\U0001d554", + "coprod;": "\u2210", + "copy": "\xa9", + "copy;": "\xa9", + "copysr;": "\u2117", + "crarr;": "\u21b5", + "cross;": "\u2717", + "cscr;": "\U0001d4b8", + "csub;": "\u2acf", + "csube;": "\u2ad1", + "csup;": "\u2ad0", + "csupe;": "\u2ad2", + "ctdot;": "\u22ef", + "cudarrl;": "\u2938", + "cudarrr;": "\u2935", + "cuepr;": "\u22de", + "cuesc;": "\u22df", + "cularr;": "\u21b6", + "cularrp;": "\u293d", + "cup;": "\u222a", + "cupbrcap;": "\u2a48", + "cupcap;": "\u2a46", + "cupcup;": "\u2a4a", + "cupdot;": "\u228d", + "cupor;": "\u2a45", + "cups;": "\u222a\ufe00", + "curarr;": "\u21b7", + "curarrm;": "\u293c", + "curlyeqprec;": "\u22de", + "curlyeqsucc;": "\u22df", + "curlyvee;": "\u22ce", + "curlywedge;": "\u22cf", + "curren": "\xa4", + "curren;": "\xa4", + "curvearrowleft;": "\u21b6", + "curvearrowright;": "\u21b7", + "cuvee;": "\u22ce", + "cuwed;": "\u22cf", + "cwconint;": "\u2232", + "cwint;": "\u2231", + "cylcty;": "\u232d", + "dArr;": "\u21d3", + "dHar;": "\u2965", + "dagger;": "\u2020", + "daleth;": "\u2138", + "darr;": "\u2193", + "dash;": "\u2010", + "dashv;": "\u22a3", + "dbkarow;": "\u290f", + "dblac;": "\u02dd", + "dcaron;": "\u010f", + "dcy;": "\u0434", + "dd;": "\u2146", + "ddagger;": "\u2021", + "ddarr;": "\u21ca", + "ddotseq;": "\u2a77", + "deg": "\xb0", + "deg;": "\xb0", + "delta;": "\u03b4", + "demptyv;": "\u29b1", + "dfisht;": "\u297f", + "dfr;": "\U0001d521", + "dharl;": "\u21c3", + "dharr;": "\u21c2", + "diam;": "\u22c4", + "diamond;": "\u22c4", + "diamondsuit;": "\u2666", + "diams;": "\u2666", + "die;": "\xa8", + "digamma;": "\u03dd", + "disin;": "\u22f2", + "div;": "\xf7", + "divide": "\xf7", + "divide;": "\xf7", + "divideontimes;": "\u22c7", + "divonx;": "\u22c7", + "djcy;": "\u0452", + "dlcorn;": "\u231e", + "dlcrop;": "\u230d", + "dollar;": "$", + "dopf;": "\U0001d555", + "dot;": "\u02d9", + "doteq;": "\u2250", + "doteqdot;": "\u2251", + "dotminus;": "\u2238", + "dotplus;": "\u2214", + "dotsquare;": "\u22a1", + "doublebarwedge;": "\u2306", + "downarrow;": "\u2193", + "downdownarrows;": "\u21ca", + "downharpoonleft;": "\u21c3", + "downharpoonright;": "\u21c2", + "drbkarow;": "\u2910", + "drcorn;": "\u231f", + "drcrop;": "\u230c", + "dscr;": "\U0001d4b9", + "dscy;": "\u0455", + "dsol;": "\u29f6", + "dstrok;": "\u0111", + "dtdot;": "\u22f1", + "dtri;": "\u25bf", + "dtrif;": "\u25be", + "duarr;": "\u21f5", + "duhar;": "\u296f", + "dwangle;": "\u29a6", + "dzcy;": "\u045f", + "dzigrarr;": "\u27ff", + "eDDot;": "\u2a77", + "eDot;": "\u2251", + "eacute": "\xe9", + "eacute;": "\xe9", + "easter;": "\u2a6e", + "ecaron;": "\u011b", + "ecir;": "\u2256", + "ecirc": "\xea", + "ecirc;": "\xea", + "ecolon;": "\u2255", + "ecy;": "\u044d", + "edot;": "\u0117", + "ee;": "\u2147", + "efDot;": "\u2252", + "efr;": "\U0001d522", + "eg;": "\u2a9a", + "egrave": "\xe8", + "egrave;": "\xe8", + "egs;": "\u2a96", + "egsdot;": "\u2a98", + "el;": "\u2a99", + "elinters;": "\u23e7", + "ell;": "\u2113", + "els;": "\u2a95", + "elsdot;": "\u2a97", + "emacr;": "\u0113", + "empty;": "\u2205", + "emptyset;": "\u2205", + "emptyv;": "\u2205", + "emsp13;": "\u2004", + "emsp14;": "\u2005", + "emsp;": "\u2003", + "eng;": "\u014b", + "ensp;": "\u2002", + "eogon;": "\u0119", + "eopf;": "\U0001d556", + "epar;": "\u22d5", + "eparsl;": "\u29e3", + "eplus;": "\u2a71", + "epsi;": "\u03b5", + "epsilon;": "\u03b5", + "epsiv;": "\u03f5", + "eqcirc;": "\u2256", + "eqcolon;": "\u2255", + "eqsim;": "\u2242", + "eqslantgtr;": "\u2a96", + "eqslantless;": "\u2a95", + "equals;": "=", + "equest;": "\u225f", + "equiv;": "\u2261", + "equivDD;": "\u2a78", + "eqvparsl;": "\u29e5", + "erDot;": "\u2253", + "erarr;": "\u2971", + "escr;": "\u212f", + "esdot;": "\u2250", + "esim;": "\u2242", + "eta;": "\u03b7", + "eth": "\xf0", + "eth;": "\xf0", + "euml": "\xeb", + "euml;": "\xeb", + "euro;": "\u20ac", + "excl;": "!", + "exist;": "\u2203", + "expectation;": "\u2130", + "exponentiale;": "\u2147", + "fallingdotseq;": "\u2252", + "fcy;": "\u0444", + "female;": "\u2640", + "ffilig;": "\ufb03", + "fflig;": "\ufb00", + "ffllig;": "\ufb04", + "ffr;": "\U0001d523", + "filig;": "\ufb01", + "fjlig;": "fj", + "flat;": "\u266d", + "fllig;": "\ufb02", + "fltns;": "\u25b1", + "fnof;": "\u0192", + "fopf;": "\U0001d557", + "forall;": "\u2200", + "fork;": "\u22d4", + "forkv;": "\u2ad9", + "fpartint;": "\u2a0d", + "frac12": "\xbd", + "frac12;": "\xbd", + "frac13;": "\u2153", + "frac14": "\xbc", + "frac14;": "\xbc", + "frac15;": "\u2155", + "frac16;": "\u2159", + "frac18;": "\u215b", + "frac23;": "\u2154", + "frac25;": "\u2156", + "frac34": "\xbe", + "frac34;": "\xbe", + "frac35;": "\u2157", + "frac38;": "\u215c", + "frac45;": "\u2158", + "frac56;": "\u215a", + "frac58;": "\u215d", + "frac78;": "\u215e", + "frasl;": "\u2044", + "frown;": "\u2322", + "fscr;": "\U0001d4bb", + "gE;": "\u2267", + "gEl;": "\u2a8c", + "gacute;": "\u01f5", + "gamma;": "\u03b3", + "gammad;": "\u03dd", + "gap;": "\u2a86", + "gbreve;": "\u011f", + "gcirc;": "\u011d", + "gcy;": "\u0433", + "gdot;": "\u0121", + "ge;": "\u2265", + "gel;": "\u22db", + "geq;": "\u2265", + "geqq;": "\u2267", + "geqslant;": "\u2a7e", + "ges;": "\u2a7e", + "gescc;": "\u2aa9", + "gesdot;": "\u2a80", + "gesdoto;": "\u2a82", + "gesdotol;": "\u2a84", + "gesl;": "\u22db\ufe00", + "gesles;": "\u2a94", + "gfr;": "\U0001d524", + "gg;": "\u226b", + "ggg;": "\u22d9", + "gimel;": "\u2137", + "gjcy;": "\u0453", + "gl;": "\u2277", + "glE;": "\u2a92", + "gla;": "\u2aa5", + "glj;": "\u2aa4", + "gnE;": "\u2269", + "gnap;": "\u2a8a", + "gnapprox;": "\u2a8a", + "gne;": "\u2a88", + "gneq;": "\u2a88", + "gneqq;": "\u2269", + "gnsim;": "\u22e7", + "gopf;": "\U0001d558", + "grave;": "`", + "gscr;": "\u210a", + "gsim;": "\u2273", + "gsime;": "\u2a8e", + "gsiml;": "\u2a90", + "gt": ">", + "gt;": ">", + "gtcc;": "\u2aa7", + "gtcir;": "\u2a7a", + "gtdot;": "\u22d7", + "gtlPar;": "\u2995", + "gtquest;": "\u2a7c", + "gtrapprox;": "\u2a86", + "gtrarr;": "\u2978", + "gtrdot;": "\u22d7", + "gtreqless;": "\u22db", + "gtreqqless;": "\u2a8c", + "gtrless;": "\u2277", + "gtrsim;": "\u2273", + "gvertneqq;": "\u2269\ufe00", + "gvnE;": "\u2269\ufe00", + "hArr;": "\u21d4", + "hairsp;": "\u200a", + "half;": "\xbd", + "hamilt;": "\u210b", + "hardcy;": "\u044a", + "harr;": "\u2194", + "harrcir;": "\u2948", + "harrw;": "\u21ad", + "hbar;": "\u210f", + "hcirc;": "\u0125", + "hearts;": "\u2665", + "heartsuit;": "\u2665", + "hellip;": "\u2026", + "hercon;": "\u22b9", + "hfr;": "\U0001d525", + "hksearow;": "\u2925", + "hkswarow;": "\u2926", + "hoarr;": "\u21ff", + "homtht;": "\u223b", + "hookleftarrow;": "\u21a9", + "hookrightarrow;": "\u21aa", + "hopf;": "\U0001d559", + "horbar;": "\u2015", + "hscr;": "\U0001d4bd", + "hslash;": "\u210f", + "hstrok;": "\u0127", + "hybull;": "\u2043", + "hyphen;": "\u2010", + "iacute": "\xed", + "iacute;": "\xed", + "ic;": "\u2063", + "icirc": "\xee", + "icirc;": "\xee", + "icy;": "\u0438", + "iecy;": "\u0435", + "iexcl": "\xa1", + "iexcl;": "\xa1", + "iff;": "\u21d4", + "ifr;": "\U0001d526", + "igrave": "\xec", + "igrave;": "\xec", + "ii;": "\u2148", + "iiiint;": "\u2a0c", + "iiint;": "\u222d", + "iinfin;": "\u29dc", + "iiota;": "\u2129", + "ijlig;": "\u0133", + "imacr;": "\u012b", + "image;": "\u2111", + "imagline;": "\u2110", + "imagpart;": "\u2111", + "imath;": "\u0131", + "imof;": "\u22b7", + "imped;": "\u01b5", + "in;": "\u2208", + "incare;": "\u2105", + "infin;": "\u221e", + "infintie;": "\u29dd", + "inodot;": "\u0131", + "int;": "\u222b", + "intcal;": "\u22ba", + "integers;": "\u2124", + "intercal;": "\u22ba", + "intlarhk;": "\u2a17", + "intprod;": "\u2a3c", + "iocy;": "\u0451", + "iogon;": "\u012f", + "iopf;": "\U0001d55a", + "iota;": "\u03b9", + "iprod;": "\u2a3c", + "iquest": "\xbf", + "iquest;": "\xbf", + "iscr;": "\U0001d4be", + "isin;": "\u2208", + "isinE;": "\u22f9", + "isindot;": "\u22f5", + "isins;": "\u22f4", + "isinsv;": "\u22f3", + "isinv;": "\u2208", + "it;": "\u2062", + "itilde;": "\u0129", + "iukcy;": "\u0456", + "iuml": "\xef", + "iuml;": "\xef", + "jcirc;": "\u0135", + "jcy;": "\u0439", + "jfr;": "\U0001d527", + "jmath;": "\u0237", + "jopf;": "\U0001d55b", + "jscr;": "\U0001d4bf", + "jsercy;": "\u0458", + "jukcy;": "\u0454", + "kappa;": "\u03ba", + "kappav;": "\u03f0", + "kcedil;": "\u0137", + "kcy;": "\u043a", + "kfr;": "\U0001d528", + "kgreen;": "\u0138", + "khcy;": "\u0445", + "kjcy;": "\u045c", + "kopf;": "\U0001d55c", + "kscr;": "\U0001d4c0", + "lAarr;": "\u21da", + "lArr;": "\u21d0", + "lAtail;": "\u291b", + "lBarr;": "\u290e", + "lE;": "\u2266", + "lEg;": "\u2a8b", + "lHar;": "\u2962", + "lacute;": "\u013a", + "laemptyv;": "\u29b4", + "lagran;": "\u2112", + "lambda;": "\u03bb", + "lang;": "\u27e8", + "langd;": "\u2991", + "langle;": "\u27e8", + "lap;": "\u2a85", + "laquo": "\xab", + "laquo;": "\xab", + "larr;": "\u2190", + "larrb;": "\u21e4", + "larrbfs;": "\u291f", + "larrfs;": "\u291d", + "larrhk;": "\u21a9", + "larrlp;": "\u21ab", + "larrpl;": "\u2939", + "larrsim;": "\u2973", + "larrtl;": "\u21a2", + "lat;": "\u2aab", + "latail;": "\u2919", + "late;": "\u2aad", + "lates;": "\u2aad\ufe00", + "lbarr;": "\u290c", + "lbbrk;": "\u2772", + "lbrace;": "{", + "lbrack;": "[", + "lbrke;": "\u298b", + "lbrksld;": "\u298f", + "lbrkslu;": "\u298d", + "lcaron;": "\u013e", + "lcedil;": "\u013c", + "lceil;": "\u2308", + "lcub;": "{", + "lcy;": "\u043b", + "ldca;": "\u2936", + "ldquo;": "\u201c", + "ldquor;": "\u201e", + "ldrdhar;": "\u2967", + "ldrushar;": "\u294b", + "ldsh;": "\u21b2", + "le;": "\u2264", + "leftarrow;": "\u2190", + "leftarrowtail;": "\u21a2", + "leftharpoondown;": "\u21bd", + "leftharpoonup;": "\u21bc", + "leftleftarrows;": "\u21c7", + "leftrightarrow;": "\u2194", + "leftrightarrows;": "\u21c6", + "leftrightharpoons;": "\u21cb", + "leftrightsquigarrow;": "\u21ad", + "leftthreetimes;": "\u22cb", + "leg;": "\u22da", + "leq;": "\u2264", + "leqq;": "\u2266", + "leqslant;": "\u2a7d", + "les;": "\u2a7d", + "lescc;": "\u2aa8", + "lesdot;": "\u2a7f", + "lesdoto;": "\u2a81", + "lesdotor;": "\u2a83", + "lesg;": "\u22da\ufe00", + "lesges;": "\u2a93", + "lessapprox;": "\u2a85", + "lessdot;": "\u22d6", + "lesseqgtr;": "\u22da", + "lesseqqgtr;": "\u2a8b", + "lessgtr;": "\u2276", + "lesssim;": "\u2272", + "lfisht;": "\u297c", + "lfloor;": "\u230a", + "lfr;": "\U0001d529", + "lg;": "\u2276", + "lgE;": "\u2a91", + "lhard;": "\u21bd", + "lharu;": "\u21bc", + "lharul;": "\u296a", + "lhblk;": "\u2584", + "ljcy;": "\u0459", + "ll;": "\u226a", + "llarr;": "\u21c7", + "llcorner;": "\u231e", + "llhard;": "\u296b", + "lltri;": "\u25fa", + "lmidot;": "\u0140", + "lmoust;": "\u23b0", + "lmoustache;": "\u23b0", + "lnE;": "\u2268", + "lnap;": "\u2a89", + "lnapprox;": "\u2a89", + "lne;": "\u2a87", + "lneq;": "\u2a87", + "lneqq;": "\u2268", + "lnsim;": "\u22e6", + "loang;": "\u27ec", + "loarr;": "\u21fd", + "lobrk;": "\u27e6", + "longleftarrow;": "\u27f5", + "longleftrightarrow;": "\u27f7", + "longmapsto;": "\u27fc", + "longrightarrow;": "\u27f6", + "looparrowleft;": "\u21ab", + "looparrowright;": "\u21ac", + "lopar;": "\u2985", + "lopf;": "\U0001d55d", + "loplus;": "\u2a2d", + "lotimes;": "\u2a34", + "lowast;": "\u2217", + "lowbar;": "_", + "loz;": "\u25ca", + "lozenge;": "\u25ca", + "lozf;": "\u29eb", + "lpar;": "(", + "lparlt;": "\u2993", + "lrarr;": "\u21c6", + "lrcorner;": "\u231f", + "lrhar;": "\u21cb", + "lrhard;": "\u296d", + "lrm;": "\u200e", + "lrtri;": "\u22bf", + "lsaquo;": "\u2039", + "lscr;": "\U0001d4c1", + "lsh;": "\u21b0", + "lsim;": "\u2272", + "lsime;": "\u2a8d", + "lsimg;": "\u2a8f", + "lsqb;": "[", + "lsquo;": "\u2018", + "lsquor;": "\u201a", + "lstrok;": "\u0142", + "lt": "<", + "lt;": "<", + "ltcc;": "\u2aa6", + "ltcir;": "\u2a79", + "ltdot;": "\u22d6", + "lthree;": "\u22cb", + "ltimes;": "\u22c9", + "ltlarr;": "\u2976", + "ltquest;": "\u2a7b", + "ltrPar;": "\u2996", + "ltri;": "\u25c3", + "ltrie;": "\u22b4", + "ltrif;": "\u25c2", + "lurdshar;": "\u294a", + "luruhar;": "\u2966", + "lvertneqq;": "\u2268\ufe00", + "lvnE;": "\u2268\ufe00", + "mDDot;": "\u223a", + "macr": "\xaf", + "macr;": "\xaf", + "male;": "\u2642", + "malt;": "\u2720", + "maltese;": "\u2720", + "map;": "\u21a6", + "mapsto;": "\u21a6", + "mapstodown;": "\u21a7", + "mapstoleft;": "\u21a4", + "mapstoup;": "\u21a5", + "marker;": "\u25ae", + "mcomma;": "\u2a29", + "mcy;": "\u043c", + "mdash;": "\u2014", + "measuredangle;": "\u2221", + "mfr;": "\U0001d52a", + "mho;": "\u2127", + "micro": "\xb5", + "micro;": "\xb5", + "mid;": "\u2223", + "midast;": "*", + "midcir;": "\u2af0", + "middot": "\xb7", + "middot;": "\xb7", + "minus;": "\u2212", + "minusb;": "\u229f", + "minusd;": "\u2238", + "minusdu;": "\u2a2a", + "mlcp;": "\u2adb", + "mldr;": "\u2026", + "mnplus;": "\u2213", + "models;": "\u22a7", + "mopf;": "\U0001d55e", + "mp;": "\u2213", + "mscr;": "\U0001d4c2", + "mstpos;": "\u223e", + "mu;": "\u03bc", + "multimap;": "\u22b8", + "mumap;": "\u22b8", + "nGg;": "\u22d9\u0338", + "nGt;": "\u226b\u20d2", + "nGtv;": "\u226b\u0338", + "nLeftarrow;": "\u21cd", + "nLeftrightarrow;": "\u21ce", + "nLl;": "\u22d8\u0338", + "nLt;": "\u226a\u20d2", + "nLtv;": "\u226a\u0338", + "nRightarrow;": "\u21cf", + "nVDash;": "\u22af", + "nVdash;": "\u22ae", + "nabla;": "\u2207", + "nacute;": "\u0144", + "nang;": "\u2220\u20d2", + "nap;": "\u2249", + "napE;": "\u2a70\u0338", + "napid;": "\u224b\u0338", + "napos;": "\u0149", + "napprox;": "\u2249", + "natur;": "\u266e", + "natural;": "\u266e", + "naturals;": "\u2115", + "nbsp": "\xa0", + "nbsp;": "\xa0", + "nbump;": "\u224e\u0338", + "nbumpe;": "\u224f\u0338", + "ncap;": "\u2a43", + "ncaron;": "\u0148", + "ncedil;": "\u0146", + "ncong;": "\u2247", + "ncongdot;": "\u2a6d\u0338", + "ncup;": "\u2a42", + "ncy;": "\u043d", + "ndash;": "\u2013", + "ne;": "\u2260", + "neArr;": "\u21d7", + "nearhk;": "\u2924", + "nearr;": "\u2197", + "nearrow;": "\u2197", + "nedot;": "\u2250\u0338", + "nequiv;": "\u2262", + "nesear;": "\u2928", + "nesim;": "\u2242\u0338", + "nexist;": "\u2204", + "nexists;": "\u2204", + "nfr;": "\U0001d52b", + "ngE;": "\u2267\u0338", + "nge;": "\u2271", + "ngeq;": "\u2271", + "ngeqq;": "\u2267\u0338", + "ngeqslant;": "\u2a7e\u0338", + "nges;": "\u2a7e\u0338", + "ngsim;": "\u2275", + "ngt;": "\u226f", + "ngtr;": "\u226f", + "nhArr;": "\u21ce", + "nharr;": "\u21ae", + "nhpar;": "\u2af2", + "ni;": "\u220b", + "nis;": "\u22fc", + "nisd;": "\u22fa", + "niv;": "\u220b", + "njcy;": "\u045a", + "nlArr;": "\u21cd", + "nlE;": "\u2266\u0338", + "nlarr;": "\u219a", + "nldr;": "\u2025", + "nle;": "\u2270", + "nleftarrow;": "\u219a", + "nleftrightarrow;": "\u21ae", + "nleq;": "\u2270", + "nleqq;": "\u2266\u0338", + "nleqslant;": "\u2a7d\u0338", + "nles;": "\u2a7d\u0338", + "nless;": "\u226e", + "nlsim;": "\u2274", + "nlt;": "\u226e", + "nltri;": "\u22ea", + "nltrie;": "\u22ec", + "nmid;": "\u2224", + "nopf;": "\U0001d55f", + "not": "\xac", + "not;": "\xac", + "notin;": "\u2209", + "notinE;": "\u22f9\u0338", + "notindot;": "\u22f5\u0338", + "notinva;": "\u2209", + "notinvb;": "\u22f7", + "notinvc;": "\u22f6", + "notni;": "\u220c", + "notniva;": "\u220c", + "notnivb;": "\u22fe", + "notnivc;": "\u22fd", + "npar;": "\u2226", + "nparallel;": "\u2226", + "nparsl;": "\u2afd\u20e5", + "npart;": "\u2202\u0338", + "npolint;": "\u2a14", + "npr;": "\u2280", + "nprcue;": "\u22e0", + "npre;": "\u2aaf\u0338", + "nprec;": "\u2280", + "npreceq;": "\u2aaf\u0338", + "nrArr;": "\u21cf", + "nrarr;": "\u219b", + "nrarrc;": "\u2933\u0338", + "nrarrw;": "\u219d\u0338", + "nrightarrow;": "\u219b", + "nrtri;": "\u22eb", + "nrtrie;": "\u22ed", + "nsc;": "\u2281", + "nsccue;": "\u22e1", + "nsce;": "\u2ab0\u0338", + "nscr;": "\U0001d4c3", + "nshortmid;": "\u2224", + "nshortparallel;": "\u2226", + "nsim;": "\u2241", + "nsime;": "\u2244", + "nsimeq;": "\u2244", + "nsmid;": "\u2224", + "nspar;": "\u2226", + "nsqsube;": "\u22e2", + "nsqsupe;": "\u22e3", + "nsub;": "\u2284", + "nsubE;": "\u2ac5\u0338", + "nsube;": "\u2288", + "nsubset;": "\u2282\u20d2", + "nsubseteq;": "\u2288", + "nsubseteqq;": "\u2ac5\u0338", + "nsucc;": "\u2281", + "nsucceq;": "\u2ab0\u0338", + "nsup;": "\u2285", + "nsupE;": "\u2ac6\u0338", + "nsupe;": "\u2289", + "nsupset;": "\u2283\u20d2", + "nsupseteq;": "\u2289", + "nsupseteqq;": "\u2ac6\u0338", + "ntgl;": "\u2279", + "ntilde": "\xf1", + "ntilde;": "\xf1", + "ntlg;": "\u2278", + "ntriangleleft;": "\u22ea", + "ntrianglelefteq;": "\u22ec", + "ntriangleright;": "\u22eb", + "ntrianglerighteq;": "\u22ed", + "nu;": "\u03bd", + "num;": "#", + "numero;": "\u2116", + "numsp;": "\u2007", + "nvDash;": "\u22ad", + "nvHarr;": "\u2904", + "nvap;": "\u224d\u20d2", + "nvdash;": "\u22ac", + "nvge;": "\u2265\u20d2", + "nvgt;": ">\u20d2", + "nvinfin;": "\u29de", + "nvlArr;": "\u2902", + "nvle;": "\u2264\u20d2", + "nvlt;": "<\u20d2", + "nvltrie;": "\u22b4\u20d2", + "nvrArr;": "\u2903", + "nvrtrie;": "\u22b5\u20d2", + "nvsim;": "\u223c\u20d2", + "nwArr;": "\u21d6", + "nwarhk;": "\u2923", + "nwarr;": "\u2196", + "nwarrow;": "\u2196", + "nwnear;": "\u2927", + "oS;": "\u24c8", + "oacute": "\xf3", + "oacute;": "\xf3", + "oast;": "\u229b", + "ocir;": "\u229a", + "ocirc": "\xf4", + "ocirc;": "\xf4", + "ocy;": "\u043e", + "odash;": "\u229d", + "odblac;": "\u0151", + "odiv;": "\u2a38", + "odot;": "\u2299", + "odsold;": "\u29bc", + "oelig;": "\u0153", + "ofcir;": "\u29bf", + "ofr;": "\U0001d52c", + "ogon;": "\u02db", + "ograve": "\xf2", + "ograve;": "\xf2", + "ogt;": "\u29c1", + "ohbar;": "\u29b5", + "ohm;": "\u03a9", + "oint;": "\u222e", + "olarr;": "\u21ba", + "olcir;": "\u29be", + "olcross;": "\u29bb", + "oline;": "\u203e", + "olt;": "\u29c0", + "omacr;": "\u014d", + "omega;": "\u03c9", + "omicron;": "\u03bf", + "omid;": "\u29b6", + "ominus;": "\u2296", + "oopf;": "\U0001d560", + "opar;": "\u29b7", + "operp;": "\u29b9", + "oplus;": "\u2295", + "or;": "\u2228", + "orarr;": "\u21bb", + "ord;": "\u2a5d", + "order;": "\u2134", + "orderof;": "\u2134", + "ordf": "\xaa", + "ordf;": "\xaa", + "ordm": "\xba", + "ordm;": "\xba", + "origof;": "\u22b6", + "oror;": "\u2a56", + "orslope;": "\u2a57", + "orv;": "\u2a5b", + "oscr;": "\u2134", + "oslash": "\xf8", + "oslash;": "\xf8", + "osol;": "\u2298", + "otilde": "\xf5", + "otilde;": "\xf5", + "otimes;": "\u2297", + "otimesas;": "\u2a36", + "ouml": "\xf6", + "ouml;": "\xf6", + "ovbar;": "\u233d", + "par;": "\u2225", + "para": "\xb6", + "para;": "\xb6", + "parallel;": "\u2225", + "parsim;": "\u2af3", + "parsl;": "\u2afd", + "part;": "\u2202", + "pcy;": "\u043f", + "percnt;": "%", + "period;": ".", + "permil;": "\u2030", + "perp;": "\u22a5", + "pertenk;": "\u2031", + "pfr;": "\U0001d52d", + "phi;": "\u03c6", + "phiv;": "\u03d5", + "phmmat;": "\u2133", + "phone;": "\u260e", + "pi;": "\u03c0", + "pitchfork;": "\u22d4", + "piv;": "\u03d6", + "planck;": "\u210f", + "planckh;": "\u210e", + "plankv;": "\u210f", + "plus;": "+", + "plusacir;": "\u2a23", + "plusb;": "\u229e", + "pluscir;": "\u2a22", + "plusdo;": "\u2214", + "plusdu;": "\u2a25", + "pluse;": "\u2a72", + "plusmn": "\xb1", + "plusmn;": "\xb1", + "plussim;": "\u2a26", + "plustwo;": "\u2a27", + "pm;": "\xb1", + "pointint;": "\u2a15", + "popf;": "\U0001d561", + "pound": "\xa3", + "pound;": "\xa3", + "pr;": "\u227a", + "prE;": "\u2ab3", + "prap;": "\u2ab7", + "prcue;": "\u227c", + "pre;": "\u2aaf", + "prec;": "\u227a", + "precapprox;": "\u2ab7", + "preccurlyeq;": "\u227c", + "preceq;": "\u2aaf", + "precnapprox;": "\u2ab9", + "precneqq;": "\u2ab5", + "precnsim;": "\u22e8", + "precsim;": "\u227e", + "prime;": "\u2032", + "primes;": "\u2119", + "prnE;": "\u2ab5", + "prnap;": "\u2ab9", + "prnsim;": "\u22e8", + "prod;": "\u220f", + "profalar;": "\u232e", + "profline;": "\u2312", + "profsurf;": "\u2313", + "prop;": "\u221d", + "propto;": "\u221d", + "prsim;": "\u227e", + "prurel;": "\u22b0", + "pscr;": "\U0001d4c5", + "psi;": "\u03c8", + "puncsp;": "\u2008", + "qfr;": "\U0001d52e", + "qint;": "\u2a0c", + "qopf;": "\U0001d562", + "qprime;": "\u2057", + "qscr;": "\U0001d4c6", + "quaternions;": "\u210d", + "quatint;": "\u2a16", + "quest;": "?", + "questeq;": "\u225f", + "quot": "\"", + "quot;": "\"", + "rAarr;": "\u21db", + "rArr;": "\u21d2", + "rAtail;": "\u291c", + "rBarr;": "\u290f", + "rHar;": "\u2964", + "race;": "\u223d\u0331", + "racute;": "\u0155", + "radic;": "\u221a", + "raemptyv;": "\u29b3", + "rang;": "\u27e9", + "rangd;": "\u2992", + "range;": "\u29a5", + "rangle;": "\u27e9", + "raquo": "\xbb", + "raquo;": "\xbb", + "rarr;": "\u2192", + "rarrap;": "\u2975", + "rarrb;": "\u21e5", + "rarrbfs;": "\u2920", + "rarrc;": "\u2933", + "rarrfs;": "\u291e", + "rarrhk;": "\u21aa", + "rarrlp;": "\u21ac", + "rarrpl;": "\u2945", + "rarrsim;": "\u2974", + "rarrtl;": "\u21a3", + "rarrw;": "\u219d", + "ratail;": "\u291a", + "ratio;": "\u2236", + "rationals;": "\u211a", + "rbarr;": "\u290d", + "rbbrk;": "\u2773", + "rbrace;": "}", + "rbrack;": "]", + "rbrke;": "\u298c", + "rbrksld;": "\u298e", + "rbrkslu;": "\u2990", + "rcaron;": "\u0159", + "rcedil;": "\u0157", + "rceil;": "\u2309", + "rcub;": "}", + "rcy;": "\u0440", + "rdca;": "\u2937", + "rdldhar;": "\u2969", + "rdquo;": "\u201d", + "rdquor;": "\u201d", + "rdsh;": "\u21b3", + "real;": "\u211c", + "realine;": "\u211b", + "realpart;": "\u211c", + "reals;": "\u211d", + "rect;": "\u25ad", + "reg": "\xae", + "reg;": "\xae", + "rfisht;": "\u297d", + "rfloor;": "\u230b", + "rfr;": "\U0001d52f", + "rhard;": "\u21c1", + "rharu;": "\u21c0", + "rharul;": "\u296c", + "rho;": "\u03c1", + "rhov;": "\u03f1", + "rightarrow;": "\u2192", + "rightarrowtail;": "\u21a3", + "rightharpoondown;": "\u21c1", + "rightharpoonup;": "\u21c0", + "rightleftarrows;": "\u21c4", + "rightleftharpoons;": "\u21cc", + "rightrightarrows;": "\u21c9", + "rightsquigarrow;": "\u219d", + "rightthreetimes;": "\u22cc", + "ring;": "\u02da", + "risingdotseq;": "\u2253", + "rlarr;": "\u21c4", + "rlhar;": "\u21cc", + "rlm;": "\u200f", + "rmoust;": "\u23b1", + "rmoustache;": "\u23b1", + "rnmid;": "\u2aee", + "roang;": "\u27ed", + "roarr;": "\u21fe", + "robrk;": "\u27e7", + "ropar;": "\u2986", + "ropf;": "\U0001d563", + "roplus;": "\u2a2e", + "rotimes;": "\u2a35", + "rpar;": ")", + "rpargt;": "\u2994", + "rppolint;": "\u2a12", + "rrarr;": "\u21c9", + "rsaquo;": "\u203a", + "rscr;": "\U0001d4c7", + "rsh;": "\u21b1", + "rsqb;": "]", + "rsquo;": "\u2019", + "rsquor;": "\u2019", + "rthree;": "\u22cc", + "rtimes;": "\u22ca", + "rtri;": "\u25b9", + "rtrie;": "\u22b5", + "rtrif;": "\u25b8", + "rtriltri;": "\u29ce", + "ruluhar;": "\u2968", + "rx;": "\u211e", + "sacute;": "\u015b", + "sbquo;": "\u201a", + "sc;": "\u227b", + "scE;": "\u2ab4", + "scap;": "\u2ab8", + "scaron;": "\u0161", + "sccue;": "\u227d", + "sce;": "\u2ab0", + "scedil;": "\u015f", + "scirc;": "\u015d", + "scnE;": "\u2ab6", + "scnap;": "\u2aba", + "scnsim;": "\u22e9", + "scpolint;": "\u2a13", + "scsim;": "\u227f", + "scy;": "\u0441", + "sdot;": "\u22c5", + "sdotb;": "\u22a1", + "sdote;": "\u2a66", + "seArr;": "\u21d8", + "searhk;": "\u2925", + "searr;": "\u2198", + "searrow;": "\u2198", + "sect": "\xa7", + "sect;": "\xa7", + "semi;": ";", + "seswar;": "\u2929", + "setminus;": "\u2216", + "setmn;": "\u2216", + "sext;": "\u2736", + "sfr;": "\U0001d530", + "sfrown;": "\u2322", + "sharp;": "\u266f", + "shchcy;": "\u0449", + "shcy;": "\u0448", + "shortmid;": "\u2223", + "shortparallel;": "\u2225", + "shy": "\xad", + "shy;": "\xad", + "sigma;": "\u03c3", + "sigmaf;": "\u03c2", + "sigmav;": "\u03c2", + "sim;": "\u223c", + "simdot;": "\u2a6a", + "sime;": "\u2243", + "simeq;": "\u2243", + "simg;": "\u2a9e", + "simgE;": "\u2aa0", + "siml;": "\u2a9d", + "simlE;": "\u2a9f", + "simne;": "\u2246", + "simplus;": "\u2a24", + "simrarr;": "\u2972", + "slarr;": "\u2190", + "smallsetminus;": "\u2216", + "smashp;": "\u2a33", + "smeparsl;": "\u29e4", + "smid;": "\u2223", + "smile;": "\u2323", + "smt;": "\u2aaa", + "smte;": "\u2aac", + "smtes;": "\u2aac\ufe00", + "softcy;": "\u044c", + "sol;": "/", + "solb;": "\u29c4", + "solbar;": "\u233f", + "sopf;": "\U0001d564", + "spades;": "\u2660", + "spadesuit;": "\u2660", + "spar;": "\u2225", + "sqcap;": "\u2293", + "sqcaps;": "\u2293\ufe00", + "sqcup;": "\u2294", + "sqcups;": "\u2294\ufe00", + "sqsub;": "\u228f", + "sqsube;": "\u2291", + "sqsubset;": "\u228f", + "sqsubseteq;": "\u2291", + "sqsup;": "\u2290", + "sqsupe;": "\u2292", + "sqsupset;": "\u2290", + "sqsupseteq;": "\u2292", + "squ;": "\u25a1", + "square;": "\u25a1", + "squarf;": "\u25aa", + "squf;": "\u25aa", + "srarr;": "\u2192", + "sscr;": "\U0001d4c8", + "ssetmn;": "\u2216", + "ssmile;": "\u2323", + "sstarf;": "\u22c6", + "star;": "\u2606", + "starf;": "\u2605", + "straightepsilon;": "\u03f5", + "straightphi;": "\u03d5", + "strns;": "\xaf", + "sub;": "\u2282", + "subE;": "\u2ac5", + "subdot;": "\u2abd", + "sube;": "\u2286", + "subedot;": "\u2ac3", + "submult;": "\u2ac1", + "subnE;": "\u2acb", + "subne;": "\u228a", + "subplus;": "\u2abf", + "subrarr;": "\u2979", + "subset;": "\u2282", + "subseteq;": "\u2286", + "subseteqq;": "\u2ac5", + "subsetneq;": "\u228a", + "subsetneqq;": "\u2acb", + "subsim;": "\u2ac7", + "subsub;": "\u2ad5", + "subsup;": "\u2ad3", + "succ;": "\u227b", + "succapprox;": "\u2ab8", + "succcurlyeq;": "\u227d", + "succeq;": "\u2ab0", + "succnapprox;": "\u2aba", + "succneqq;": "\u2ab6", + "succnsim;": "\u22e9", + "succsim;": "\u227f", + "sum;": "\u2211", + "sung;": "\u266a", + "sup1": "\xb9", + "sup1;": "\xb9", + "sup2": "\xb2", + "sup2;": "\xb2", + "sup3": "\xb3", + "sup3;": "\xb3", + "sup;": "\u2283", + "supE;": "\u2ac6", + "supdot;": "\u2abe", + "supdsub;": "\u2ad8", + "supe;": "\u2287", + "supedot;": "\u2ac4", + "suphsol;": "\u27c9", + "suphsub;": "\u2ad7", + "suplarr;": "\u297b", + "supmult;": "\u2ac2", + "supnE;": "\u2acc", + "supne;": "\u228b", + "supplus;": "\u2ac0", + "supset;": "\u2283", + "supseteq;": "\u2287", + "supseteqq;": "\u2ac6", + "supsetneq;": "\u228b", + "supsetneqq;": "\u2acc", + "supsim;": "\u2ac8", + "supsub;": "\u2ad4", + "supsup;": "\u2ad6", + "swArr;": "\u21d9", + "swarhk;": "\u2926", + "swarr;": "\u2199", + "swarrow;": "\u2199", + "swnwar;": "\u292a", + "szlig": "\xdf", + "szlig;": "\xdf", + "target;": "\u2316", + "tau;": "\u03c4", + "tbrk;": "\u23b4", + "tcaron;": "\u0165", + "tcedil;": "\u0163", + "tcy;": "\u0442", + "tdot;": "\u20db", + "telrec;": "\u2315", + "tfr;": "\U0001d531", + "there4;": "\u2234", + "therefore;": "\u2234", + "theta;": "\u03b8", + "thetasym;": "\u03d1", + "thetav;": "\u03d1", + "thickapprox;": "\u2248", + "thicksim;": "\u223c", + "thinsp;": "\u2009", + "thkap;": "\u2248", + "thksim;": "\u223c", + "thorn": "\xfe", + "thorn;": "\xfe", + "tilde;": "\u02dc", + "times": "\xd7", + "times;": "\xd7", + "timesb;": "\u22a0", + "timesbar;": "\u2a31", + "timesd;": "\u2a30", + "tint;": "\u222d", + "toea;": "\u2928", + "top;": "\u22a4", + "topbot;": "\u2336", + "topcir;": "\u2af1", + "topf;": "\U0001d565", + "topfork;": "\u2ada", + "tosa;": "\u2929", + "tprime;": "\u2034", + "trade;": "\u2122", + "triangle;": "\u25b5", + "triangledown;": "\u25bf", + "triangleleft;": "\u25c3", + "trianglelefteq;": "\u22b4", + "triangleq;": "\u225c", + "triangleright;": "\u25b9", + "trianglerighteq;": "\u22b5", + "tridot;": "\u25ec", + "trie;": "\u225c", + "triminus;": "\u2a3a", + "triplus;": "\u2a39", + "trisb;": "\u29cd", + "tritime;": "\u2a3b", + "trpezium;": "\u23e2", + "tscr;": "\U0001d4c9", + "tscy;": "\u0446", + "tshcy;": "\u045b", + "tstrok;": "\u0167", + "twixt;": "\u226c", + "twoheadleftarrow;": "\u219e", + "twoheadrightarrow;": "\u21a0", + "uArr;": "\u21d1", + "uHar;": "\u2963", + "uacute": "\xfa", + "uacute;": "\xfa", + "uarr;": "\u2191", + "ubrcy;": "\u045e", + "ubreve;": "\u016d", + "ucirc": "\xfb", + "ucirc;": "\xfb", + "ucy;": "\u0443", + "udarr;": "\u21c5", + "udblac;": "\u0171", + "udhar;": "\u296e", + "ufisht;": "\u297e", + "ufr;": "\U0001d532", + "ugrave": "\xf9", + "ugrave;": "\xf9", + "uharl;": "\u21bf", + "uharr;": "\u21be", + "uhblk;": "\u2580", + "ulcorn;": "\u231c", + "ulcorner;": "\u231c", + "ulcrop;": "\u230f", + "ultri;": "\u25f8", + "umacr;": "\u016b", + "uml": "\xa8", + "uml;": "\xa8", + "uogon;": "\u0173", + "uopf;": "\U0001d566", + "uparrow;": "\u2191", + "updownarrow;": "\u2195", + "upharpoonleft;": "\u21bf", + "upharpoonright;": "\u21be", + "uplus;": "\u228e", + "upsi;": "\u03c5", + "upsih;": "\u03d2", + "upsilon;": "\u03c5", + "upuparrows;": "\u21c8", + "urcorn;": "\u231d", + "urcorner;": "\u231d", + "urcrop;": "\u230e", + "uring;": "\u016f", + "urtri;": "\u25f9", + "uscr;": "\U0001d4ca", + "utdot;": "\u22f0", + "utilde;": "\u0169", + "utri;": "\u25b5", + "utrif;": "\u25b4", + "uuarr;": "\u21c8", + "uuml": "\xfc", + "uuml;": "\xfc", + "uwangle;": "\u29a7", + "vArr;": "\u21d5", + "vBar;": "\u2ae8", + "vBarv;": "\u2ae9", + "vDash;": "\u22a8", + "vangrt;": "\u299c", + "varepsilon;": "\u03f5", + "varkappa;": "\u03f0", + "varnothing;": "\u2205", + "varphi;": "\u03d5", + "varpi;": "\u03d6", + "varpropto;": "\u221d", + "varr;": "\u2195", + "varrho;": "\u03f1", + "varsigma;": "\u03c2", + "varsubsetneq;": "\u228a\ufe00", + "varsubsetneqq;": "\u2acb\ufe00", + "varsupsetneq;": "\u228b\ufe00", + "varsupsetneqq;": "\u2acc\ufe00", + "vartheta;": "\u03d1", + "vartriangleleft;": "\u22b2", + "vartriangleright;": "\u22b3", + "vcy;": "\u0432", + "vdash;": "\u22a2", + "vee;": "\u2228", + "veebar;": "\u22bb", + "veeeq;": "\u225a", + "vellip;": "\u22ee", + "verbar;": "|", + "vert;": "|", + "vfr;": "\U0001d533", + "vltri;": "\u22b2", + "vnsub;": "\u2282\u20d2", + "vnsup;": "\u2283\u20d2", + "vopf;": "\U0001d567", + "vprop;": "\u221d", + "vrtri;": "\u22b3", + "vscr;": "\U0001d4cb", + "vsubnE;": "\u2acb\ufe00", + "vsubne;": "\u228a\ufe00", + "vsupnE;": "\u2acc\ufe00", + "vsupne;": "\u228b\ufe00", + "vzigzag;": "\u299a", + "wcirc;": "\u0175", + "wedbar;": "\u2a5f", + "wedge;": "\u2227", + "wedgeq;": "\u2259", + "weierp;": "\u2118", + "wfr;": "\U0001d534", + "wopf;": "\U0001d568", + "wp;": "\u2118", + "wr;": "\u2240", + "wreath;": "\u2240", + "wscr;": "\U0001d4cc", + "xcap;": "\u22c2", + "xcirc;": "\u25ef", + "xcup;": "\u22c3", + "xdtri;": "\u25bd", + "xfr;": "\U0001d535", + "xhArr;": "\u27fa", + "xharr;": "\u27f7", + "xi;": "\u03be", + "xlArr;": "\u27f8", + "xlarr;": "\u27f5", + "xmap;": "\u27fc", + "xnis;": "\u22fb", + "xodot;": "\u2a00", + "xopf;": "\U0001d569", + "xoplus;": "\u2a01", + "xotime;": "\u2a02", + "xrArr;": "\u27f9", + "xrarr;": "\u27f6", + "xscr;": "\U0001d4cd", + "xsqcup;": "\u2a06", + "xuplus;": "\u2a04", + "xutri;": "\u25b3", + "xvee;": "\u22c1", + "xwedge;": "\u22c0", + "yacute": "\xfd", + "yacute;": "\xfd", + "yacy;": "\u044f", + "ycirc;": "\u0177", + "ycy;": "\u044b", + "yen": "\xa5", + "yen;": "\xa5", + "yfr;": "\U0001d536", + "yicy;": "\u0457", + "yopf;": "\U0001d56a", + "yscr;": "\U0001d4ce", + "yucy;": "\u044e", + "yuml": "\xff", + "yuml;": "\xff", + "zacute;": "\u017a", + "zcaron;": "\u017e", + "zcy;": "\u0437", + "zdot;": "\u017c", + "zeetrf;": "\u2128", + "zeta;": "\u03b6", + "zfr;": "\U0001d537", + "zhcy;": "\u0436", + "zigrarr;": "\u21dd", + "zopf;": "\U0001d56b", + "zscr;": "\U0001d4cf", + "zwj;": "\u200d", + "zwnj;": "\u200c", +} + +replacementCharacters = { + 0x0: "\uFFFD", + 0x0d: "\u000D", + 0x80: "\u20AC", + 0x81: "\u0081", + 0x82: "\u201A", + 0x83: "\u0192", + 0x84: "\u201E", + 0x85: "\u2026", + 0x86: "\u2020", + 0x87: "\u2021", + 0x88: "\u02C6", + 0x89: "\u2030", + 0x8A: "\u0160", + 0x8B: "\u2039", + 0x8C: "\u0152", + 0x8D: "\u008D", + 0x8E: "\u017D", + 0x8F: "\u008F", + 0x90: "\u0090", + 0x91: "\u2018", + 0x92: "\u2019", + 0x93: "\u201C", + 0x94: "\u201D", + 0x95: "\u2022", + 0x96: "\u2013", + 0x97: "\u2014", + 0x98: "\u02DC", + 0x99: "\u2122", + 0x9A: "\u0161", + 0x9B: "\u203A", + 0x9C: "\u0153", + 0x9D: "\u009D", + 0x9E: "\u017E", + 0x9F: "\u0178", +} + +tokenTypes = { + "Doctype": 0, + "Characters": 1, + "SpaceCharacters": 2, + "StartTag": 3, + "EndTag": 4, + "EmptyTag": 5, + "Comment": 6, + "ParseError": 7 +} + +tagTokenTypes = frozenset([tokenTypes["StartTag"], tokenTypes["EndTag"], + tokenTypes["EmptyTag"]]) + + +prefixes = {v: k for k, v in namespaces.items()} +prefixes["http://www.w3.org/1998/Math/MathML"] = "math" + + +class DataLossWarning(UserWarning): + """Raised when the current tree is unable to represent the input data""" + pass + + +class _ReparseException(Exception): + pass diff --git a/venv/Lib/site-packages/pip/_vendor/html5lib/filters/__init__.py b/venv/Lib/site-packages/pip/_vendor/html5lib/filters/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/venv/Lib/site-packages/pip/_vendor/html5lib/filters/alphabeticalattributes.py b/venv/Lib/site-packages/pip/_vendor/html5lib/filters/alphabeticalattributes.py new file mode 100644 index 0000000..5ba926e --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/html5lib/filters/alphabeticalattributes.py @@ -0,0 +1,29 @@ +from __future__ import absolute_import, division, unicode_literals + +from . import base + +from collections import OrderedDict + + +def _attr_key(attr): + """Return an appropriate key for an attribute for sorting + + Attributes have a namespace that can be either ``None`` or a string. We + can't compare the two because they're different types, so we convert + ``None`` to an empty string first. + + """ + return (attr[0][0] or ''), attr[0][1] + + +class Filter(base.Filter): + """Alphabetizes attributes for elements""" + def __iter__(self): + for token in base.Filter.__iter__(self): + if token["type"] in ("StartTag", "EmptyTag"): + attrs = OrderedDict() + for name, value in sorted(token["data"].items(), + key=_attr_key): + attrs[name] = value + token["data"] = attrs + yield token diff --git a/venv/Lib/site-packages/pip/_vendor/html5lib/filters/base.py b/venv/Lib/site-packages/pip/_vendor/html5lib/filters/base.py new file mode 100644 index 0000000..c7dbaed --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/html5lib/filters/base.py @@ -0,0 +1,12 @@ +from __future__ import absolute_import, division, unicode_literals + + +class Filter(object): + def __init__(self, source): + self.source = source + + def __iter__(self): + return iter(self.source) + + def __getattr__(self, name): + return getattr(self.source, name) diff --git a/venv/Lib/site-packages/pip/_vendor/html5lib/filters/inject_meta_charset.py b/venv/Lib/site-packages/pip/_vendor/html5lib/filters/inject_meta_charset.py new file mode 100644 index 0000000..aefb5c8 --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/html5lib/filters/inject_meta_charset.py @@ -0,0 +1,73 @@ +from __future__ import absolute_import, division, unicode_literals + +from . import base + + +class Filter(base.Filter): + """Injects ```` tag into head of document""" + def __init__(self, source, encoding): + """Creates a Filter + + :arg source: the source token stream + + :arg encoding: the encoding to set + + """ + base.Filter.__init__(self, source) + self.encoding = encoding + + def __iter__(self): + state = "pre_head" + meta_found = (self.encoding is None) + pending = [] + + for token in base.Filter.__iter__(self): + type = token["type"] + if type == "StartTag": + if token["name"].lower() == "head": + state = "in_head" + + elif type == "EmptyTag": + if token["name"].lower() == "meta": + # replace charset with actual encoding + has_http_equiv_content_type = False + for (namespace, name), value in token["data"].items(): + if namespace is not None: + continue + elif name.lower() == 'charset': + token["data"][(namespace, name)] = self.encoding + meta_found = True + break + elif name == 'http-equiv' and value.lower() == 'content-type': + has_http_equiv_content_type = True + else: + if has_http_equiv_content_type and (None, "content") in token["data"]: + token["data"][(None, "content")] = 'text/html; charset=%s' % self.encoding + meta_found = True + + elif token["name"].lower() == "head" and not meta_found: + # insert meta into empty head + yield {"type": "StartTag", "name": "head", + "data": token["data"]} + yield {"type": "EmptyTag", "name": "meta", + "data": {(None, "charset"): self.encoding}} + yield {"type": "EndTag", "name": "head"} + meta_found = True + continue + + elif type == "EndTag": + if token["name"].lower() == "head" and pending: + # insert meta into head (if necessary) and flush pending queue + yield pending.pop(0) + if not meta_found: + yield {"type": "EmptyTag", "name": "meta", + "data": {(None, "charset"): self.encoding}} + while pending: + yield pending.pop(0) + meta_found = True + state = "post_head" + + if state == "in_head": + pending.append(token) + else: + yield token diff --git a/venv/Lib/site-packages/pip/_vendor/html5lib/filters/lint.py b/venv/Lib/site-packages/pip/_vendor/html5lib/filters/lint.py new file mode 100644 index 0000000..fcc07ee --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/html5lib/filters/lint.py @@ -0,0 +1,93 @@ +from __future__ import absolute_import, division, unicode_literals + +from pip._vendor.six import text_type + +from . import base +from ..constants import namespaces, voidElements + +from ..constants import spaceCharacters +spaceCharacters = "".join(spaceCharacters) + + +class Filter(base.Filter): + """Lints the token stream for errors + + If it finds any errors, it'll raise an ``AssertionError``. + + """ + def __init__(self, source, require_matching_tags=True): + """Creates a Filter + + :arg source: the source token stream + + :arg require_matching_tags: whether or not to require matching tags + + """ + super(Filter, self).__init__(source) + self.require_matching_tags = require_matching_tags + + def __iter__(self): + open_elements = [] + for token in base.Filter.__iter__(self): + type = token["type"] + if type in ("StartTag", "EmptyTag"): + namespace = token["namespace"] + name = token["name"] + assert namespace is None or isinstance(namespace, text_type) + assert namespace != "" + assert isinstance(name, text_type) + assert name != "" + assert isinstance(token["data"], dict) + if (not namespace or namespace == namespaces["html"]) and name in voidElements: + assert type == "EmptyTag" + else: + assert type == "StartTag" + if type == "StartTag" and self.require_matching_tags: + open_elements.append((namespace, name)) + for (namespace, name), value in token["data"].items(): + assert namespace is None or isinstance(namespace, text_type) + assert namespace != "" + assert isinstance(name, text_type) + assert name != "" + assert isinstance(value, text_type) + + elif type == "EndTag": + namespace = token["namespace"] + name = token["name"] + assert namespace is None or isinstance(namespace, text_type) + assert namespace != "" + assert isinstance(name, text_type) + assert name != "" + if (not namespace or namespace == namespaces["html"]) and name in voidElements: + assert False, "Void element reported as EndTag token: %(tag)s" % {"tag": name} + elif self.require_matching_tags: + start = open_elements.pop() + assert start == (namespace, name) + + elif type == "Comment": + data = token["data"] + assert isinstance(data, text_type) + + elif type in ("Characters", "SpaceCharacters"): + data = token["data"] + assert isinstance(data, text_type) + assert data != "" + if type == "SpaceCharacters": + assert data.strip(spaceCharacters) == "" + + elif type == "Doctype": + name = token["name"] + assert name is None or isinstance(name, text_type) + assert token["publicId"] is None or isinstance(name, text_type) + assert token["systemId"] is None or isinstance(name, text_type) + + elif type == "Entity": + assert isinstance(token["name"], text_type) + + elif type == "SerializerError": + assert isinstance(token["data"], text_type) + + else: + assert False, "Unknown token type: %(type)s" % {"type": type} + + yield token diff --git a/venv/Lib/site-packages/pip/_vendor/html5lib/filters/optionaltags.py b/venv/Lib/site-packages/pip/_vendor/html5lib/filters/optionaltags.py new file mode 100644 index 0000000..4a86501 --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/html5lib/filters/optionaltags.py @@ -0,0 +1,207 @@ +from __future__ import absolute_import, division, unicode_literals + +from . import base + + +class Filter(base.Filter): + """Removes optional tags from the token stream""" + def slider(self): + previous1 = previous2 = None + for token in self.source: + if previous1 is not None: + yield previous2, previous1, token + previous2 = previous1 + previous1 = token + if previous1 is not None: + yield previous2, previous1, None + + def __iter__(self): + for previous, token, next in self.slider(): + type = token["type"] + if type == "StartTag": + if (token["data"] or + not self.is_optional_start(token["name"], previous, next)): + yield token + elif type == "EndTag": + if not self.is_optional_end(token["name"], next): + yield token + else: + yield token + + def is_optional_start(self, tagname, previous, next): + type = next and next["type"] or None + if tagname in 'html': + # An html element's start tag may be omitted if the first thing + # inside the html element is not a space character or a comment. + return type not in ("Comment", "SpaceCharacters") + elif tagname == 'head': + # A head element's start tag may be omitted if the first thing + # inside the head element is an element. + # XXX: we also omit the start tag if the head element is empty + if type in ("StartTag", "EmptyTag"): + return True + elif type == "EndTag": + return next["name"] == "head" + elif tagname == 'body': + # A body element's start tag may be omitted if the first thing + # inside the body element is not a space character or a comment, + # except if the first thing inside the body element is a script + # or style element and the node immediately preceding the body + # element is a head element whose end tag has been omitted. + if type in ("Comment", "SpaceCharacters"): + return False + elif type == "StartTag": + # XXX: we do not look at the preceding event, so we never omit + # the body element's start tag if it's followed by a script or + # a style element. + return next["name"] not in ('script', 'style') + else: + return True + elif tagname == 'colgroup': + # A colgroup element's start tag may be omitted if the first thing + # inside the colgroup element is a col element, and if the element + # is not immediately preceded by another colgroup element whose + # end tag has been omitted. + if type in ("StartTag", "EmptyTag"): + # XXX: we do not look at the preceding event, so instead we never + # omit the colgroup element's end tag when it is immediately + # followed by another colgroup element. See is_optional_end. + return next["name"] == "col" + else: + return False + elif tagname == 'tbody': + # A tbody element's start tag may be omitted if the first thing + # inside the tbody element is a tr element, and if the element is + # not immediately preceded by a tbody, thead, or tfoot element + # whose end tag has been omitted. + if type == "StartTag": + # omit the thead and tfoot elements' end tag when they are + # immediately followed by a tbody element. See is_optional_end. + if previous and previous['type'] == 'EndTag' and \ + previous['name'] in ('tbody', 'thead', 'tfoot'): + return False + return next["name"] == 'tr' + else: + return False + return False + + def is_optional_end(self, tagname, next): + type = next and next["type"] or None + if tagname in ('html', 'head', 'body'): + # An html element's end tag may be omitted if the html element + # is not immediately followed by a space character or a comment. + return type not in ("Comment", "SpaceCharacters") + elif tagname in ('li', 'optgroup', 'tr'): + # A li element's end tag may be omitted if the li element is + # immediately followed by another li element or if there is + # no more content in the parent element. + # An optgroup element's end tag may be omitted if the optgroup + # element is immediately followed by another optgroup element, + # or if there is no more content in the parent element. + # A tr element's end tag may be omitted if the tr element is + # immediately followed by another tr element, or if there is + # no more content in the parent element. + if type == "StartTag": + return next["name"] == tagname + else: + return type == "EndTag" or type is None + elif tagname in ('dt', 'dd'): + # A dt element's end tag may be omitted if the dt element is + # immediately followed by another dt element or a dd element. + # A dd element's end tag may be omitted if the dd element is + # immediately followed by another dd element or a dt element, + # or if there is no more content in the parent element. + if type == "StartTag": + return next["name"] in ('dt', 'dd') + elif tagname == 'dd': + return type == "EndTag" or type is None + else: + return False + elif tagname == 'p': + # A p element's end tag may be omitted if the p element is + # immediately followed by an address, article, aside, + # blockquote, datagrid, dialog, dir, div, dl, fieldset, + # footer, form, h1, h2, h3, h4, h5, h6, header, hr, menu, + # nav, ol, p, pre, section, table, or ul, element, or if + # there is no more content in the parent element. + if type in ("StartTag", "EmptyTag"): + return next["name"] in ('address', 'article', 'aside', + 'blockquote', 'datagrid', 'dialog', + 'dir', 'div', 'dl', 'fieldset', 'footer', + 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', + 'header', 'hr', 'menu', 'nav', 'ol', + 'p', 'pre', 'section', 'table', 'ul') + else: + return type == "EndTag" or type is None + elif tagname == 'option': + # An option element's end tag may be omitted if the option + # element is immediately followed by another option element, + # or if it is immediately followed by an optgroup + # element, or if there is no more content in the parent + # element. + if type == "StartTag": + return next["name"] in ('option', 'optgroup') + else: + return type == "EndTag" or type is None + elif tagname in ('rt', 'rp'): + # An rt element's end tag may be omitted if the rt element is + # immediately followed by an rt or rp element, or if there is + # no more content in the parent element. + # An rp element's end tag may be omitted if the rp element is + # immediately followed by an rt or rp element, or if there is + # no more content in the parent element. + if type == "StartTag": + return next["name"] in ('rt', 'rp') + else: + return type == "EndTag" or type is None + elif tagname == 'colgroup': + # A colgroup element's end tag may be omitted if the colgroup + # element is not immediately followed by a space character or + # a comment. + if type in ("Comment", "SpaceCharacters"): + return False + elif type == "StartTag": + # XXX: we also look for an immediately following colgroup + # element. See is_optional_start. + return next["name"] != 'colgroup' + else: + return True + elif tagname in ('thead', 'tbody'): + # A thead element's end tag may be omitted if the thead element + # is immediately followed by a tbody or tfoot element. + # A tbody element's end tag may be omitted if the tbody element + # is immediately followed by a tbody or tfoot element, or if + # there is no more content in the parent element. + # A tfoot element's end tag may be omitted if the tfoot element + # is immediately followed by a tbody element, or if there is no + # more content in the parent element. + # XXX: we never omit the end tag when the following element is + # a tbody. See is_optional_start. + if type == "StartTag": + return next["name"] in ['tbody', 'tfoot'] + elif tagname == 'tbody': + return type == "EndTag" or type is None + else: + return False + elif tagname == 'tfoot': + # A tfoot element's end tag may be omitted if the tfoot element + # is immediately followed by a tbody element, or if there is no + # more content in the parent element. + # XXX: we never omit the end tag when the following element is + # a tbody. See is_optional_start. + if type == "StartTag": + return next["name"] == 'tbody' + else: + return type == "EndTag" or type is None + elif tagname in ('td', 'th'): + # A td element's end tag may be omitted if the td element is + # immediately followed by a td or th element, or if there is + # no more content in the parent element. + # A th element's end tag may be omitted if the th element is + # immediately followed by a td or th element, or if there is + # no more content in the parent element. + if type == "StartTag": + return next["name"] in ('td', 'th') + else: + return type == "EndTag" or type is None + return False diff --git a/venv/Lib/site-packages/pip/_vendor/html5lib/filters/sanitizer.py b/venv/Lib/site-packages/pip/_vendor/html5lib/filters/sanitizer.py new file mode 100644 index 0000000..aa7431d --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/html5lib/filters/sanitizer.py @@ -0,0 +1,916 @@ +"""Deprecated from html5lib 1.1. + +See `here `_ for +information about its deprecation; `Bleach `_ +is recommended as a replacement. Please let us know in the aforementioned issue +if Bleach is unsuitable for your needs. + +""" +from __future__ import absolute_import, division, unicode_literals + +import re +import warnings +from xml.sax.saxutils import escape, unescape + +from pip._vendor.six.moves import urllib_parse as urlparse + +from . import base +from ..constants import namespaces, prefixes + +__all__ = ["Filter"] + + +_deprecation_msg = ( + "html5lib's sanitizer is deprecated; see " + + "https://github.com/html5lib/html5lib-python/issues/443 and please let " + + "us know if Bleach is unsuitable for your needs" +) + +warnings.warn(_deprecation_msg, DeprecationWarning) + +allowed_elements = frozenset(( + (namespaces['html'], 'a'), + (namespaces['html'], 'abbr'), + (namespaces['html'], 'acronym'), + (namespaces['html'], 'address'), + (namespaces['html'], 'area'), + (namespaces['html'], 'article'), + (namespaces['html'], 'aside'), + (namespaces['html'], 'audio'), + (namespaces['html'], 'b'), + (namespaces['html'], 'big'), + (namespaces['html'], 'blockquote'), + (namespaces['html'], 'br'), + (namespaces['html'], 'button'), + (namespaces['html'], 'canvas'), + (namespaces['html'], 'caption'), + (namespaces['html'], 'center'), + (namespaces['html'], 'cite'), + (namespaces['html'], 'code'), + (namespaces['html'], 'col'), + (namespaces['html'], 'colgroup'), + (namespaces['html'], 'command'), + (namespaces['html'], 'datagrid'), + (namespaces['html'], 'datalist'), + (namespaces['html'], 'dd'), + (namespaces['html'], 'del'), + (namespaces['html'], 'details'), + (namespaces['html'], 'dfn'), + (namespaces['html'], 'dialog'), + (namespaces['html'], 'dir'), + (namespaces['html'], 'div'), + (namespaces['html'], 'dl'), + (namespaces['html'], 'dt'), + (namespaces['html'], 'em'), + (namespaces['html'], 'event-source'), + (namespaces['html'], 'fieldset'), + (namespaces['html'], 'figcaption'), + (namespaces['html'], 'figure'), + (namespaces['html'], 'footer'), + (namespaces['html'], 'font'), + (namespaces['html'], 'form'), + (namespaces['html'], 'header'), + (namespaces['html'], 'h1'), + (namespaces['html'], 'h2'), + (namespaces['html'], 'h3'), + (namespaces['html'], 'h4'), + (namespaces['html'], 'h5'), + (namespaces['html'], 'h6'), + (namespaces['html'], 'hr'), + (namespaces['html'], 'i'), + (namespaces['html'], 'img'), + (namespaces['html'], 'input'), + (namespaces['html'], 'ins'), + (namespaces['html'], 'keygen'), + (namespaces['html'], 'kbd'), + (namespaces['html'], 'label'), + (namespaces['html'], 'legend'), + (namespaces['html'], 'li'), + (namespaces['html'], 'm'), + (namespaces['html'], 'map'), + (namespaces['html'], 'menu'), + (namespaces['html'], 'meter'), + (namespaces['html'], 'multicol'), + (namespaces['html'], 'nav'), + (namespaces['html'], 'nextid'), + (namespaces['html'], 'ol'), + (namespaces['html'], 'output'), + (namespaces['html'], 'optgroup'), + (namespaces['html'], 'option'), + (namespaces['html'], 'p'), + (namespaces['html'], 'pre'), + (namespaces['html'], 'progress'), + (namespaces['html'], 'q'), + (namespaces['html'], 's'), + (namespaces['html'], 'samp'), + (namespaces['html'], 'section'), + (namespaces['html'], 'select'), + (namespaces['html'], 'small'), + (namespaces['html'], 'sound'), + (namespaces['html'], 'source'), + (namespaces['html'], 'spacer'), + (namespaces['html'], 'span'), + (namespaces['html'], 'strike'), + (namespaces['html'], 'strong'), + (namespaces['html'], 'sub'), + (namespaces['html'], 'sup'), + (namespaces['html'], 'table'), + (namespaces['html'], 'tbody'), + (namespaces['html'], 'td'), + (namespaces['html'], 'textarea'), + (namespaces['html'], 'time'), + (namespaces['html'], 'tfoot'), + (namespaces['html'], 'th'), + (namespaces['html'], 'thead'), + (namespaces['html'], 'tr'), + (namespaces['html'], 'tt'), + (namespaces['html'], 'u'), + (namespaces['html'], 'ul'), + (namespaces['html'], 'var'), + (namespaces['html'], 'video'), + (namespaces['mathml'], 'maction'), + (namespaces['mathml'], 'math'), + (namespaces['mathml'], 'merror'), + (namespaces['mathml'], 'mfrac'), + (namespaces['mathml'], 'mi'), + (namespaces['mathml'], 'mmultiscripts'), + (namespaces['mathml'], 'mn'), + (namespaces['mathml'], 'mo'), + (namespaces['mathml'], 'mover'), + (namespaces['mathml'], 'mpadded'), + (namespaces['mathml'], 'mphantom'), + (namespaces['mathml'], 'mprescripts'), + (namespaces['mathml'], 'mroot'), + (namespaces['mathml'], 'mrow'), + (namespaces['mathml'], 'mspace'), + (namespaces['mathml'], 'msqrt'), + (namespaces['mathml'], 'mstyle'), + (namespaces['mathml'], 'msub'), + (namespaces['mathml'], 'msubsup'), + (namespaces['mathml'], 'msup'), + (namespaces['mathml'], 'mtable'), + (namespaces['mathml'], 'mtd'), + (namespaces['mathml'], 'mtext'), + (namespaces['mathml'], 'mtr'), + (namespaces['mathml'], 'munder'), + (namespaces['mathml'], 'munderover'), + (namespaces['mathml'], 'none'), + (namespaces['svg'], 'a'), + (namespaces['svg'], 'animate'), + (namespaces['svg'], 'animateColor'), + (namespaces['svg'], 'animateMotion'), + (namespaces['svg'], 'animateTransform'), + (namespaces['svg'], 'clipPath'), + (namespaces['svg'], 'circle'), + (namespaces['svg'], 'defs'), + (namespaces['svg'], 'desc'), + (namespaces['svg'], 'ellipse'), + (namespaces['svg'], 'font-face'), + (namespaces['svg'], 'font-face-name'), + (namespaces['svg'], 'font-face-src'), + (namespaces['svg'], 'g'), + (namespaces['svg'], 'glyph'), + (namespaces['svg'], 'hkern'), + (namespaces['svg'], 'linearGradient'), + (namespaces['svg'], 'line'), + (namespaces['svg'], 'marker'), + (namespaces['svg'], 'metadata'), + (namespaces['svg'], 'missing-glyph'), + (namespaces['svg'], 'mpath'), + (namespaces['svg'], 'path'), + (namespaces['svg'], 'polygon'), + (namespaces['svg'], 'polyline'), + (namespaces['svg'], 'radialGradient'), + (namespaces['svg'], 'rect'), + (namespaces['svg'], 'set'), + (namespaces['svg'], 'stop'), + (namespaces['svg'], 'svg'), + (namespaces['svg'], 'switch'), + (namespaces['svg'], 'text'), + (namespaces['svg'], 'title'), + (namespaces['svg'], 'tspan'), + (namespaces['svg'], 'use'), +)) + +allowed_attributes = frozenset(( + # HTML attributes + (None, 'abbr'), + (None, 'accept'), + (None, 'accept-charset'), + (None, 'accesskey'), + (None, 'action'), + (None, 'align'), + (None, 'alt'), + (None, 'autocomplete'), + (None, 'autofocus'), + (None, 'axis'), + (None, 'background'), + (None, 'balance'), + (None, 'bgcolor'), + (None, 'bgproperties'), + (None, 'border'), + (None, 'bordercolor'), + (None, 'bordercolordark'), + (None, 'bordercolorlight'), + (None, 'bottompadding'), + (None, 'cellpadding'), + (None, 'cellspacing'), + (None, 'ch'), + (None, 'challenge'), + (None, 'char'), + (None, 'charoff'), + (None, 'choff'), + (None, 'charset'), + (None, 'checked'), + (None, 'cite'), + (None, 'class'), + (None, 'clear'), + (None, 'color'), + (None, 'cols'), + (None, 'colspan'), + (None, 'compact'), + (None, 'contenteditable'), + (None, 'controls'), + (None, 'coords'), + (None, 'data'), + (None, 'datafld'), + (None, 'datapagesize'), + (None, 'datasrc'), + (None, 'datetime'), + (None, 'default'), + (None, 'delay'), + (None, 'dir'), + (None, 'disabled'), + (None, 'draggable'), + (None, 'dynsrc'), + (None, 'enctype'), + (None, 'end'), + (None, 'face'), + (None, 'for'), + (None, 'form'), + (None, 'frame'), + (None, 'galleryimg'), + (None, 'gutter'), + (None, 'headers'), + (None, 'height'), + (None, 'hidefocus'), + (None, 'hidden'), + (None, 'high'), + (None, 'href'), + (None, 'hreflang'), + (None, 'hspace'), + (None, 'icon'), + (None, 'id'), + (None, 'inputmode'), + (None, 'ismap'), + (None, 'keytype'), + (None, 'label'), + (None, 'leftspacing'), + (None, 'lang'), + (None, 'list'), + (None, 'longdesc'), + (None, 'loop'), + (None, 'loopcount'), + (None, 'loopend'), + (None, 'loopstart'), + (None, 'low'), + (None, 'lowsrc'), + (None, 'max'), + (None, 'maxlength'), + (None, 'media'), + (None, 'method'), + (None, 'min'), + (None, 'multiple'), + (None, 'name'), + (None, 'nohref'), + (None, 'noshade'), + (None, 'nowrap'), + (None, 'open'), + (None, 'optimum'), + (None, 'pattern'), + (None, 'ping'), + (None, 'point-size'), + (None, 'poster'), + (None, 'pqg'), + (None, 'preload'), + (None, 'prompt'), + (None, 'radiogroup'), + (None, 'readonly'), + (None, 'rel'), + (None, 'repeat-max'), + (None, 'repeat-min'), + (None, 'replace'), + (None, 'required'), + (None, 'rev'), + (None, 'rightspacing'), + (None, 'rows'), + (None, 'rowspan'), + (None, 'rules'), + (None, 'scope'), + (None, 'selected'), + (None, 'shape'), + (None, 'size'), + (None, 'span'), + (None, 'src'), + (None, 'start'), + (None, 'step'), + (None, 'style'), + (None, 'summary'), + (None, 'suppress'), + (None, 'tabindex'), + (None, 'target'), + (None, 'template'), + (None, 'title'), + (None, 'toppadding'), + (None, 'type'), + (None, 'unselectable'), + (None, 'usemap'), + (None, 'urn'), + (None, 'valign'), + (None, 'value'), + (None, 'variable'), + (None, 'volume'), + (None, 'vspace'), + (None, 'vrml'), + (None, 'width'), + (None, 'wrap'), + (namespaces['xml'], 'lang'), + # MathML attributes + (None, 'actiontype'), + (None, 'align'), + (None, 'columnalign'), + (None, 'columnalign'), + (None, 'columnalign'), + (None, 'columnlines'), + (None, 'columnspacing'), + (None, 'columnspan'), + (None, 'depth'), + (None, 'display'), + (None, 'displaystyle'), + (None, 'equalcolumns'), + (None, 'equalrows'), + (None, 'fence'), + (None, 'fontstyle'), + (None, 'fontweight'), + (None, 'frame'), + (None, 'height'), + (None, 'linethickness'), + (None, 'lspace'), + (None, 'mathbackground'), + (None, 'mathcolor'), + (None, 'mathvariant'), + (None, 'mathvariant'), + (None, 'maxsize'), + (None, 'minsize'), + (None, 'other'), + (None, 'rowalign'), + (None, 'rowalign'), + (None, 'rowalign'), + (None, 'rowlines'), + (None, 'rowspacing'), + (None, 'rowspan'), + (None, 'rspace'), + (None, 'scriptlevel'), + (None, 'selection'), + (None, 'separator'), + (None, 'stretchy'), + (None, 'width'), + (None, 'width'), + (namespaces['xlink'], 'href'), + (namespaces['xlink'], 'show'), + (namespaces['xlink'], 'type'), + # SVG attributes + (None, 'accent-height'), + (None, 'accumulate'), + (None, 'additive'), + (None, 'alphabetic'), + (None, 'arabic-form'), + (None, 'ascent'), + (None, 'attributeName'), + (None, 'attributeType'), + (None, 'baseProfile'), + (None, 'bbox'), + (None, 'begin'), + (None, 'by'), + (None, 'calcMode'), + (None, 'cap-height'), + (None, 'class'), + (None, 'clip-path'), + (None, 'color'), + (None, 'color-rendering'), + (None, 'content'), + (None, 'cx'), + (None, 'cy'), + (None, 'd'), + (None, 'dx'), + (None, 'dy'), + (None, 'descent'), + (None, 'display'), + (None, 'dur'), + (None, 'end'), + (None, 'fill'), + (None, 'fill-opacity'), + (None, 'fill-rule'), + (None, 'font-family'), + (None, 'font-size'), + (None, 'font-stretch'), + (None, 'font-style'), + (None, 'font-variant'), + (None, 'font-weight'), + (None, 'from'), + (None, 'fx'), + (None, 'fy'), + (None, 'g1'), + (None, 'g2'), + (None, 'glyph-name'), + (None, 'gradientUnits'), + (None, 'hanging'), + (None, 'height'), + (None, 'horiz-adv-x'), + (None, 'horiz-origin-x'), + (None, 'id'), + (None, 'ideographic'), + (None, 'k'), + (None, 'keyPoints'), + (None, 'keySplines'), + (None, 'keyTimes'), + (None, 'lang'), + (None, 'marker-end'), + (None, 'marker-mid'), + (None, 'marker-start'), + (None, 'markerHeight'), + (None, 'markerUnits'), + (None, 'markerWidth'), + (None, 'mathematical'), + (None, 'max'), + (None, 'min'), + (None, 'name'), + (None, 'offset'), + (None, 'opacity'), + (None, 'orient'), + (None, 'origin'), + (None, 'overline-position'), + (None, 'overline-thickness'), + (None, 'panose-1'), + (None, 'path'), + (None, 'pathLength'), + (None, 'points'), + (None, 'preserveAspectRatio'), + (None, 'r'), + (None, 'refX'), + (None, 'refY'), + (None, 'repeatCount'), + (None, 'repeatDur'), + (None, 'requiredExtensions'), + (None, 'requiredFeatures'), + (None, 'restart'), + (None, 'rotate'), + (None, 'rx'), + (None, 'ry'), + (None, 'slope'), + (None, 'stemh'), + (None, 'stemv'), + (None, 'stop-color'), + (None, 'stop-opacity'), + (None, 'strikethrough-position'), + (None, 'strikethrough-thickness'), + (None, 'stroke'), + (None, 'stroke-dasharray'), + (None, 'stroke-dashoffset'), + (None, 'stroke-linecap'), + (None, 'stroke-linejoin'), + (None, 'stroke-miterlimit'), + (None, 'stroke-opacity'), + (None, 'stroke-width'), + (None, 'systemLanguage'), + (None, 'target'), + (None, 'text-anchor'), + (None, 'to'), + (None, 'transform'), + (None, 'type'), + (None, 'u1'), + (None, 'u2'), + (None, 'underline-position'), + (None, 'underline-thickness'), + (None, 'unicode'), + (None, 'unicode-range'), + (None, 'units-per-em'), + (None, 'values'), + (None, 'version'), + (None, 'viewBox'), + (None, 'visibility'), + (None, 'width'), + (None, 'widths'), + (None, 'x'), + (None, 'x-height'), + (None, 'x1'), + (None, 'x2'), + (namespaces['xlink'], 'actuate'), + (namespaces['xlink'], 'arcrole'), + (namespaces['xlink'], 'href'), + (namespaces['xlink'], 'role'), + (namespaces['xlink'], 'show'), + (namespaces['xlink'], 'title'), + (namespaces['xlink'], 'type'), + (namespaces['xml'], 'base'), + (namespaces['xml'], 'lang'), + (namespaces['xml'], 'space'), + (None, 'y'), + (None, 'y1'), + (None, 'y2'), + (None, 'zoomAndPan'), +)) + +attr_val_is_uri = frozenset(( + (None, 'href'), + (None, 'src'), + (None, 'cite'), + (None, 'action'), + (None, 'longdesc'), + (None, 'poster'), + (None, 'background'), + (None, 'datasrc'), + (None, 'dynsrc'), + (None, 'lowsrc'), + (None, 'ping'), + (namespaces['xlink'], 'href'), + (namespaces['xml'], 'base'), +)) + +svg_attr_val_allows_ref = frozenset(( + (None, 'clip-path'), + (None, 'color-profile'), + (None, 'cursor'), + (None, 'fill'), + (None, 'filter'), + (None, 'marker'), + (None, 'marker-start'), + (None, 'marker-mid'), + (None, 'marker-end'), + (None, 'mask'), + (None, 'stroke'), +)) + +svg_allow_local_href = frozenset(( + (None, 'altGlyph'), + (None, 'animate'), + (None, 'animateColor'), + (None, 'animateMotion'), + (None, 'animateTransform'), + (None, 'cursor'), + (None, 'feImage'), + (None, 'filter'), + (None, 'linearGradient'), + (None, 'pattern'), + (None, 'radialGradient'), + (None, 'textpath'), + (None, 'tref'), + (None, 'set'), + (None, 'use') +)) + +allowed_css_properties = frozenset(( + 'azimuth', + 'background-color', + 'border-bottom-color', + 'border-collapse', + 'border-color', + 'border-left-color', + 'border-right-color', + 'border-top-color', + 'clear', + 'color', + 'cursor', + 'direction', + 'display', + 'elevation', + 'float', + 'font', + 'font-family', + 'font-size', + 'font-style', + 'font-variant', + 'font-weight', + 'height', + 'letter-spacing', + 'line-height', + 'overflow', + 'pause', + 'pause-after', + 'pause-before', + 'pitch', + 'pitch-range', + 'richness', + 'speak', + 'speak-header', + 'speak-numeral', + 'speak-punctuation', + 'speech-rate', + 'stress', + 'text-align', + 'text-decoration', + 'text-indent', + 'unicode-bidi', + 'vertical-align', + 'voice-family', + 'volume', + 'white-space', + 'width', +)) + +allowed_css_keywords = frozenset(( + 'auto', + 'aqua', + 'black', + 'block', + 'blue', + 'bold', + 'both', + 'bottom', + 'brown', + 'center', + 'collapse', + 'dashed', + 'dotted', + 'fuchsia', + 'gray', + 'green', + '!important', + 'italic', + 'left', + 'lime', + 'maroon', + 'medium', + 'none', + 'navy', + 'normal', + 'nowrap', + 'olive', + 'pointer', + 'purple', + 'red', + 'right', + 'solid', + 'silver', + 'teal', + 'top', + 'transparent', + 'underline', + 'white', + 'yellow', +)) + +allowed_svg_properties = frozenset(( + 'fill', + 'fill-opacity', + 'fill-rule', + 'stroke', + 'stroke-width', + 'stroke-linecap', + 'stroke-linejoin', + 'stroke-opacity', +)) + +allowed_protocols = frozenset(( + 'ed2k', + 'ftp', + 'http', + 'https', + 'irc', + 'mailto', + 'news', + 'gopher', + 'nntp', + 'telnet', + 'webcal', + 'xmpp', + 'callto', + 'feed', + 'urn', + 'aim', + 'rsync', + 'tag', + 'ssh', + 'sftp', + 'rtsp', + 'afs', + 'data', +)) + +allowed_content_types = frozenset(( + 'image/png', + 'image/jpeg', + 'image/gif', + 'image/webp', + 'image/bmp', + 'text/plain', +)) + + +data_content_type = re.compile(r''' + ^ + # Match a content type / + (?P[-a-zA-Z0-9.]+/[-a-zA-Z0-9.]+) + # Match any character set and encoding + (?:(?:;charset=(?:[-a-zA-Z0-9]+)(?:;(?:base64))?) + |(?:;(?:base64))?(?:;charset=(?:[-a-zA-Z0-9]+))?) + # Assume the rest is data + ,.* + $ + ''', + re.VERBOSE) + + +class Filter(base.Filter): + """Sanitizes token stream of XHTML+MathML+SVG and of inline style attributes""" + def __init__(self, + source, + allowed_elements=allowed_elements, + allowed_attributes=allowed_attributes, + allowed_css_properties=allowed_css_properties, + allowed_css_keywords=allowed_css_keywords, + allowed_svg_properties=allowed_svg_properties, + allowed_protocols=allowed_protocols, + allowed_content_types=allowed_content_types, + attr_val_is_uri=attr_val_is_uri, + svg_attr_val_allows_ref=svg_attr_val_allows_ref, + svg_allow_local_href=svg_allow_local_href): + """Creates a Filter + + :arg allowed_elements: set of elements to allow--everything else will + be escaped + + :arg allowed_attributes: set of attributes to allow in + elements--everything else will be stripped + + :arg allowed_css_properties: set of CSS properties to allow--everything + else will be stripped + + :arg allowed_css_keywords: set of CSS keywords to allow--everything + else will be stripped + + :arg allowed_svg_properties: set of SVG properties to allow--everything + else will be removed + + :arg allowed_protocols: set of allowed protocols for URIs + + :arg allowed_content_types: set of allowed content types for ``data`` URIs. + + :arg attr_val_is_uri: set of attributes that have URI values--values + that have a scheme not listed in ``allowed_protocols`` are removed + + :arg svg_attr_val_allows_ref: set of SVG attributes that can have + references + + :arg svg_allow_local_href: set of SVG elements that can have local + hrefs--these are removed + + """ + super(Filter, self).__init__(source) + + warnings.warn(_deprecation_msg, DeprecationWarning) + + self.allowed_elements = allowed_elements + self.allowed_attributes = allowed_attributes + self.allowed_css_properties = allowed_css_properties + self.allowed_css_keywords = allowed_css_keywords + self.allowed_svg_properties = allowed_svg_properties + self.allowed_protocols = allowed_protocols + self.allowed_content_types = allowed_content_types + self.attr_val_is_uri = attr_val_is_uri + self.svg_attr_val_allows_ref = svg_attr_val_allows_ref + self.svg_allow_local_href = svg_allow_local_href + + def __iter__(self): + for token in base.Filter.__iter__(self): + token = self.sanitize_token(token) + if token: + yield token + + # Sanitize the +html+, escaping all elements not in ALLOWED_ELEMENTS, and + # stripping out all attributes not in ALLOWED_ATTRIBUTES. Style attributes + # are parsed, and a restricted set, specified by ALLOWED_CSS_PROPERTIES and + # ALLOWED_CSS_KEYWORDS, are allowed through. attributes in ATTR_VAL_IS_URI + # are scanned, and only URI schemes specified in ALLOWED_PROTOCOLS are + # allowed. + # + # sanitize_html('') + # => <script> do_nasty_stuff() </script> + # sanitize_html('Click here for $100') + # => Click here for $100 + def sanitize_token(self, token): + + # accommodate filters which use token_type differently + token_type = token["type"] + if token_type in ("StartTag", "EndTag", "EmptyTag"): + name = token["name"] + namespace = token["namespace"] + if ((namespace, name) in self.allowed_elements or + (namespace is None and + (namespaces["html"], name) in self.allowed_elements)): + return self.allowed_token(token) + else: + return self.disallowed_token(token) + elif token_type == "Comment": + pass + else: + return token + + def allowed_token(self, token): + if "data" in token: + attrs = token["data"] + attr_names = set(attrs.keys()) + + # Remove forbidden attributes + for to_remove in (attr_names - self.allowed_attributes): + del token["data"][to_remove] + attr_names.remove(to_remove) + + # Remove attributes with disallowed URL values + for attr in (attr_names & self.attr_val_is_uri): + assert attr in attrs + # I don't have a clue where this regexp comes from or why it matches those + # characters, nor why we call unescape. I just know it's always been here. + # Should you be worried by this comment in a sanitizer? Yes. On the other hand, all + # this will do is remove *more* than it otherwise would. + val_unescaped = re.sub("[`\x00-\x20\x7f-\xa0\\s]+", '', + unescape(attrs[attr])).lower() + # remove replacement characters from unescaped characters + val_unescaped = val_unescaped.replace("\ufffd", "") + try: + uri = urlparse.urlparse(val_unescaped) + except ValueError: + uri = None + del attrs[attr] + if uri and uri.scheme: + if uri.scheme not in self.allowed_protocols: + del attrs[attr] + if uri.scheme == 'data': + m = data_content_type.match(uri.path) + if not m: + del attrs[attr] + elif m.group('content_type') not in self.allowed_content_types: + del attrs[attr] + + for attr in self.svg_attr_val_allows_ref: + if attr in attrs: + attrs[attr] = re.sub(r'url\s*\(\s*[^#\s][^)]+?\)', + ' ', + unescape(attrs[attr])) + if (token["name"] in self.svg_allow_local_href and + (namespaces['xlink'], 'href') in attrs and re.search(r'^\s*[^#\s].*', + attrs[(namespaces['xlink'], 'href')])): + del attrs[(namespaces['xlink'], 'href')] + if (None, 'style') in attrs: + attrs[(None, 'style')] = self.sanitize_css(attrs[(None, 'style')]) + token["data"] = attrs + return token + + def disallowed_token(self, token): + token_type = token["type"] + if token_type == "EndTag": + token["data"] = "" % token["name"] + elif token["data"]: + assert token_type in ("StartTag", "EmptyTag") + attrs = [] + for (ns, name), v in token["data"].items(): + attrs.append(' %s="%s"' % (name if ns is None else "%s:%s" % (prefixes[ns], name), escape(v))) + token["data"] = "<%s%s>" % (token["name"], ''.join(attrs)) + else: + token["data"] = "<%s>" % token["name"] + if token.get("selfClosing"): + token["data"] = token["data"][:-1] + "/>" + + token["type"] = "Characters" + + del token["name"] + return token + + def sanitize_css(self, style): + # disallow urls + style = re.compile(r'url\s*\(\s*[^\s)]+?\s*\)\s*').sub(' ', style) + + # gauntlet + if not re.match(r"""^([:,;#%.\sa-zA-Z0-9!]|\w-\w|'[\s\w]+'|"[\s\w]+"|\([\d,\s]+\))*$""", style): + return '' + if not re.match(r"^\s*([-\w]+\s*:[^:;]*(;\s*|$))*$", style): + return '' + + clean = [] + for prop, value in re.findall(r"([-\w]+)\s*:\s*([^:;]*)", style): + if not value: + continue + if prop.lower() in self.allowed_css_properties: + clean.append(prop + ': ' + value + ';') + elif prop.split('-')[0].lower() in ['background', 'border', 'margin', + 'padding']: + for keyword in value.split(): + if keyword not in self.allowed_css_keywords and \ + not re.match(r"^(#[0-9a-fA-F]+|rgb\(\d+%?,\d*%?,?\d*%?\)?|\d{0,2}\.?\d{0,2}(cm|em|ex|in|mm|pc|pt|px|%|,|\))?)$", keyword): # noqa + break + else: + clean.append(prop + ': ' + value + ';') + elif prop.lower() in self.allowed_svg_properties: + clean.append(prop + ': ' + value + ';') + + return ' '.join(clean) diff --git a/venv/Lib/site-packages/pip/_vendor/html5lib/filters/whitespace.py b/venv/Lib/site-packages/pip/_vendor/html5lib/filters/whitespace.py new file mode 100644 index 0000000..0d12584 --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/html5lib/filters/whitespace.py @@ -0,0 +1,38 @@ +from __future__ import absolute_import, division, unicode_literals + +import re + +from . import base +from ..constants import rcdataElements, spaceCharacters +spaceCharacters = "".join(spaceCharacters) + +SPACES_REGEX = re.compile("[%s]+" % spaceCharacters) + + +class Filter(base.Filter): + """Collapses whitespace except in pre, textarea, and script elements""" + spacePreserveElements = frozenset(["pre", "textarea"] + list(rcdataElements)) + + def __iter__(self): + preserve = 0 + for token in base.Filter.__iter__(self): + type = token["type"] + if type == "StartTag" \ + and (preserve or token["name"] in self.spacePreserveElements): + preserve += 1 + + elif type == "EndTag" and preserve: + preserve -= 1 + + elif not preserve and type == "SpaceCharacters" and token["data"]: + # Test on token["data"] above to not introduce spaces where there were not + token["data"] = " " + + elif not preserve and type == "Characters": + token["data"] = collapse_spaces(token["data"]) + + yield token + + +def collapse_spaces(text): + return SPACES_REGEX.sub(' ', text) diff --git a/venv/Lib/site-packages/pip/_vendor/html5lib/html5parser.py b/venv/Lib/site-packages/pip/_vendor/html5lib/html5parser.py new file mode 100644 index 0000000..d06784f --- /dev/null +++ b/venv/Lib/site-packages/pip/_vendor/html5lib/html5parser.py @@ -0,0 +1,2795 @@ +from __future__ import absolute_import, division, unicode_literals +from pip._vendor.six import with_metaclass, viewkeys + +import types + +from . import _inputstream +from . import _tokenizer + +from . import treebuilders +from .treebuilders.base import Marker + +from . import _utils +from .constants import ( + spaceCharacters, asciiUpper2Lower, + specialElements, headingElements, cdataElements, rcdataElements, + tokenTypes, tagTokenTypes, + namespaces, + htmlIntegrationPointElements, mathmlTextIntegrationPointElements, + adjustForeignAttributes as adjustForeignAttributesMap, + adjustMathMLAttributes, adjustSVGAttributes, + E, + _ReparseException +) + + +def parse(doc, treebuilder="etree", namespaceHTMLElements=True, **kwargs): + """Parse an HTML document as a string or file-like object into a tree + + :arg doc: the document to parse as a string or file-like object + + :arg treebuilder: the treebuilder to use when parsing + + :arg namespaceHTMLElements: whether or not to namespace HTML elements + + :returns: parsed tree + + Example: + + >>> from html5lib.html5parser import parse + >>> parse('

    This is a doc

    ') + + + """ + tb = treebuilders.getTreeBuilder(treebuilder) + p = HTMLParser(tb, namespaceHTMLElements=namespaceHTMLElements) + return p.parse(doc, **kwargs) + + +def parseFragment(doc, container="div", treebuilder="etree", namespaceHTMLElements=True, **kwargs): + """Parse an HTML fragment as a string or file-like object into a tree + + :arg doc: the fragment to parse as a string or file-like object + + :arg container: the container context to parse the fragment in + + :arg treebuilder: the treebuilder to use when parsing + + :arg namespaceHTMLElements: whether or not to namespace HTML elements + + :returns: parsed tree + + Example: + + >>> from html5lib.html5libparser import parseFragment + >>> parseFragment('this is a fragment') + + + """ + tb = treebuilders.getTreeBuilder(treebuilder) + p = HTMLParser(tb, namespaceHTMLElements=namespaceHTMLElements) + return p.parseFragment(doc, container=container, **kwargs) + + +def method_decorator_metaclass(function): + class Decorated(type): + def __new__(meta, classname, bases, classDict): + for attributeName, attribute in classDict.items(): + if isinstance(attribute, types.FunctionType): + attribute = function(attribute) + + classDict[attributeName] = attribute + return type.__new__(meta, classname, bases, classDict) + return Decorated + + +class HTMLParser(object): + """HTML parser + + Generates a tree structure from a stream of (possibly malformed) HTML. + + """ + + def __init__(self, tree=None, strict=False, namespaceHTMLElements=True, debug=False): + """ + :arg tree: a treebuilder class controlling the type of tree that will be + returned. Built in treebuilders can be accessed through + html5lib.treebuilders.getTreeBuilder(treeType) + + :arg strict: raise an exception when a parse error is encountered + + :arg namespaceHTMLElements: whether or not to namespace HTML elements + + :arg debug: whether or not to enable debug mode which logs things + + Example: + + >>> from html5lib.html5parser import HTMLParser + >>> parser = HTMLParser() # generates parser with etree builder + >>> parser = HTMLParser('lxml', strict=True) # generates parser with lxml builder which is strict + + """ + + # Raise an exception on the first error encountered + self.strict = strict + + if tree is None: + tree = treebuilders.getTreeBuilder("etree") + self.tree = tree(namespaceHTMLElements) + self.errors = [] + + self.phases = {name: cls(self, self.tree) for name, cls in + getPhases(debug).items()} + + def _parse(self, stream, innerHTML=False, container="div", scripting=False, **kwargs): + + self.innerHTMLMode = innerHTML + self.container = container + self.scripting = scripting + self.tokenizer = _tokenizer.HTMLTokenizer(stream, parser=self, **kwargs) + self.reset() + + try: + self.mainLoop() + except _ReparseException: + self.reset() + self.mainLoop() + + def reset(self): + self.tree.reset() + self.firstStartTag = False + self.errors = [] + self.log = [] # only used with debug mode + # "quirks" / "limited quirks" / "no quirks" + self.compatMode = "no quirks" + + if self.innerHTMLMode: + self.innerHTML = self.container.lower() + + if self.innerHTML in cdataElements: + self.tokenizer.state = self.tokenizer.rcdataState + elif self.innerHTML in rcdataElements: + self.tokenizer.state = self.tokenizer.rawtextState + elif self.innerHTML == 'plaintext': + self.tokenizer.state = self.tokenizer.plaintextState + else: + # state already is data state + # self.tokenizer.state = self.tokenizer.dataState + pass + self.phase = self.phases["beforeHtml"] + self.phase.insertHtmlElement() + self.resetInsertionMode() + else: + self.innerHTML = False # pylint:disable=redefined-variable-type + self.phase = self.phases["initial"] + + self.lastPhase = None + + self.beforeRCDataPhase = None + + self.framesetOK = True + + @property + def documentEncoding(self): + """Name of the character encoding that was used to decode the input stream, or + :obj:`None` if that is not determined yet + + """ + if not hasattr(self, 'tokenizer'): + return None + return self.tokenizer.stream.charEncoding[0].name + + def isHTMLIntegrationPoint(self, element): + if (element.name == "annotation-xml" and + element.namespace == namespaces["mathml"]): + return ("encoding" in element.attributes and + element.attributes["encoding"].translate( + asciiUpper2Lower) in + ("text/html", "application/xhtml+xml")) + else: + return (element.namespace, element.name) in htmlIntegrationPointElements + + def isMathMLTextIntegrationPoint(self, element): + return (element.namespace, element.name) in mathmlTextIntegrationPointElements + + def mainLoop(self): + CharactersToken = tokenTypes["Characters"] + SpaceCharactersToken = tokenTypes["SpaceCharacters"] + StartTagToken = tokenTypes["StartTag"] + EndTagToken = tokenTypes["EndTag"] + CommentToken = tokenTypes["Comment"] + DoctypeToken = tokenTypes["Doctype"] + ParseErrorToken = tokenTypes["ParseError"] + + for token in self.tokenizer: + prev_token = None + new_token = token + while new_token is not None: + prev_token = new_token + currentNode = self.tree.openElements[-1] if self.tree.openElements else None + currentNodeNamespace = currentNode.namespace if currentNode else None + currentNodeName = currentNode.name if currentNode else None + + type = new_token["type"] + + if type == ParseErrorToken: + self.parseError(new_token["data"], new_token.get("datavars", {})) + new_token = None + else: + if (len(self.tree.openElements) == 0 or + currentNodeNamespace == self.tree.defaultNamespace or + (self.isMathMLTextIntegrationPoint(currentNode) and + ((type == StartTagToken and + token["name"] not in frozenset(["mglyph", "malignmark"])) or + type in (CharactersToken, SpaceCharactersToken))) or + (currentNodeNamespace == namespaces["mathml"] and + currentNodeName == "annotation-xml" and + type == StartTagToken and + token["name"] == "svg") or + (self.isHTMLIntegrationPoint(currentNode) and + type in (StartTagToken, CharactersToken, SpaceCharactersToken))): + phase = self.phase + else: + phase = self.phases["inForeignContent"] + + if type == CharactersToken: + new_token = phase.processCharacters(new_token) + elif type == SpaceCharactersToken: + new_token = phase.processSpaceCharacters(new_token) + elif type == StartTagToken: + new_token = phase.processStartTag(new_token) + elif type == EndTagToken: + new_token = phase.processEndTag(new_token) + elif type == CommentToken: + new_token = phase.processComment(new_token) + elif type == DoctypeToken: + new_token = phase.processDoctype(new_token) + + if (type == StartTagToken and prev_token["selfClosing"] and + not prev_token["selfClosingAcknowledged"]): + self.parseError("non-void-element-with-trailing-solidus", + {"name": prev_token["name"]}) + + # When the loop finishes it's EOF + reprocess = True + phases = [] + while reprocess: + phases.append(self.phase) + reprocess = self.phase.processEOF() + if reprocess: + assert self.phase not in phases + + def parse(self, stream, *args, **kwargs): + """Parse a HTML document into a well-formed tree + + :arg stream: a file-like object or string containing the HTML to be parsed + + The optional encoding parameter must be a string that indicates + the encoding. If specified, that encoding will be used, + regardless of any BOM or later declaration (such as in a meta + element). + + :arg scripting: treat noscript elements as if JavaScript was turned on + + :returns: parsed tree + + Example: + + >>> from html5lib.html5parser import HTMLParser + >>> parser = HTMLParser() + >>> parser.parse('

    This is a doc

    ') + + + """ + self._parse(stream, False, None, *args, **kwargs) + return self.tree.getDocument() + + def parseFragment(self, stream, *args, **kwargs): + """Parse a HTML fragment into a well-formed tree fragment + + :arg container: name of the element we're setting the innerHTML + property if set to None, default to 'div' + + :arg stream: a file-like object or string containing the HTML to be parsed + + The optional encoding parameter must be a string that indicates + the encoding. If specified, that encoding will be used, + regardless of any BOM or later declaration (such as in a meta + element) + + :arg scripting: treat noscript elements as if JavaScript was turned on + + :returns: parsed tree + + Example: + + >>> from html5lib.html5libparser import HTMLParser + >>> parser = HTMLParser() + >>> parser.parseFragment('this is a fragment') + + + """ + self._parse(stream, True, *args, **kwargs) + return self.tree.getFragment() + + def parseError(self, errorcode="XXX-undefined-error", datavars=None): + # XXX The idea is to make errorcode mandatory. + if datavars is None: + datavars = {} + self.errors.append((self.tokenizer.stream.position(), errorcode, datavars)) + if self.strict: + raise ParseError(E[errorcode] % datavars) + + def adjustMathMLAttributes(self, token): + adjust_attributes(token, adjustMathMLAttributes) + + def adjustSVGAttributes(self, token): + adjust_attributes(token, adjustSVGAttributes) + + def adjustForeignAttributes(self, token): + adjust_attributes(token, adjustForeignAttributesMap) + + def reparseTokenNormal(self, token): + # pylint:disable=unused-argument + self.parser.phase() + + def resetInsertionMode(self): + # The name of this method is mostly historical. (It's also used in the + # specification.) + last = False + newModes = { + "select": "inSelect", + "td": "inCell", + "th": "inCell", + "tr": "inRow", + "tbody": "inTableBody", + "thead": "inTableBody", + "tfoot": "inTableBody", + "caption": "inCaption", + "colgroup": "inColumnGroup", + "table": "inTable", + "head": "inBody", + "body": "inBody", + "frameset": "inFrameset", + "html": "beforeHead" + } + for node in self.tree.openElements[::-1]: + nodeName = node.name + new_phase = None + if node == self.tree.openElements[0]: + assert self.innerHTML + last = True + nodeName = self.innerHTML + # Check for conditions that should only happen in the innerHTML + # case + if nodeName in ("select", "colgroup", "head", "html"): + assert self.innerHTML + + if not last and node.namespace != self.tree.defaultNamespace: + continue + + if nodeName in newModes: + new_phase = self.phases[newModes[nodeName]] + break + elif last: + new_phase = self.phases["inBody"] + break + + self.phase = new_phase + + def parseRCDataRawtext(self, token, contentType): + # Generic RCDATA/RAWTEXT Parsing algorithm + assert contentType in ("RAWTEXT", "RCDATA") + + self.tree.insertElement(token) + + if contentType == "RAWTEXT": + self.tokenizer.state = self.tokenizer.rawtextState + else: + self.tokenizer.state = self.tokenizer.rcdataState + + self.originalPhase = self.phase + + self.phase = self.phases["text"] + + +@_utils.memoize +def getPhases(debug): + def log(function): + """Logger that records which phase processes each token""" + type_names = {value: key for key, value in tokenTypes.items()} + + def wrapped(self, *args, **kwargs): + if function.__name__.startswith("process") and len(args) > 0: + token = args[0] + info = {"type": type_names[token['type']]} + if token['type'] in tagTokenTypes: + info["name"] = token['name'] + + self.parser.log.append((self.parser.tokenizer.state.__name__, + self.parser.phase.__class__.__name__, + self.__class__.__name__, + function.__name__, + info)) + return function(self, *args, **kwargs) + else: + return function(self, *args, **kwargs) + return wrapped + + def getMetaclass(use_metaclass, metaclass_func): + if use_metaclass: + return method_decorator_metaclass(metaclass_func) + else: + return type + + # pylint:disable=unused-argument + class Phase(with_metaclass(getMetaclass(debug, log))): + """Base class for helper object that implements each phase of processing + """ + __slots__ = ("parser", "tree", "__startTagCache", "__endTagCache") + + def __init__(self, parser, tree): + self.parser = parser + self.tree = tree + self.__startTagCache = {} + self.__endTagCache = {} + + def processEOF(self): + raise NotImplementedError + + def processComment(self, token): + # For most phases the following is correct. Where it's not it will be + # overridden. + self.tree.insertComment(token, self.tree.openElements[-1]) + + def processDoctype(self, token): + self.parser.parseError("unexpected-doctype") + + def processCharacters(self, token): + self.tree.insertText(token["data"]) + + def processSpaceCharacters(self, token): + self.tree.insertText(token["data"]) + + def processStartTag(self, token): + # Note the caching is done here rather than BoundMethodDispatcher as doing it there + # requires a circular reference to the Phase, and this ends up with a significant + # (CPython 2.7, 3.8) GC cost when parsing many short inputs + name = token["name"] + # In Py2, using `in` is quicker in general than try/except KeyError + # In Py3, `in` is quicker when there are few cache hits (typically short inputs) + if name in self.__startTagCache: + func = self.__startTagCache[name] + else: + func = self.__startTagCache[name] = self.startTagHandler[name] + # bound the cache size in case we get loads of unknown tags + while len(self.__startTagCache) > len(self.startTagHandler) * 1.1: + # this makes the eviction policy random on Py < 3.7 and FIFO >= 3.7 + self.__startTagCache.pop(next(iter(self.__startTagCache))) + return func(token) + + def startTagHtml(self, token): + if not self.parser.firstStartTag and token["name"] == "html": + self.parser.parseError("non-html-root") + # XXX Need a check here to see if the first start tag token emitted is + # this token... If it's not, invoke self.parser.parseError(). + for attr, value in token["data"].items(): + if attr not in self.tree.openElements[0].attributes: + self.tree.openElements[0].attributes[attr] = value + self.parser.firstStartTag = False + + def processEndTag(self, token): + # Note the caching is done here rather than BoundMethodDispatcher as doing it there + # requires a circular reference to the Phase, and this ends up with a significant + # (CPython 2.7, 3.8) GC cost when parsing many short inputs + name = token["name"] + # In Py2, using `in` is quicker in general than try/except KeyError + # In Py3, `in` is quicker when there are few cache hits (typically short inputs) + if name in self.__endTagCache: + func = self.__endTagCache[name] + else: + func = self.__endTagCache[name] = self.endTagHandler[name] + # bound the cache size in case we get loads of unknown tags + while len(self.__endTagCache) > len(self.endTagHandler) * 1.1: + # this makes the eviction policy random on Py < 3.7 and FIFO >= 3.7 + self.__endTagCache.pop(next(iter(self.__endTagCache))) + return func(token) + + class InitialPhase(Phase): + __slots__ = tuple() + + def processSpaceCharacters(self, token): + pass + + def processComment(self, token): + self.tree.insertComment(token, self.tree.document) + + def processDoctype(self, token): + name = token["name"] + publicId = token["publicId"] + systemId = token["systemId"] + correct = token["correct"] + + if (name != "html" or publicId is not None or + systemId is not None and systemId != "about:legacy-compat"): + self.parser.parseError("unknown-doctype") + + if publicId is None: + publicId = "" + + self.tree.insertDoctype(token) + + if publicId != "": + publicId = publicId.translate(asciiUpper2Lower) + + if (not correct or token["name"] != "html" or + publicId.startswith( + ("+//silmaril//dtd html pro v0r11 19970101//", + "-//advasoft ltd//dtd html 3.0 aswedit + extensions//", + "-//as//dtd html 3.0 aswedit + extensions//", + "-//ietf//dtd html 2.0 level 1//", + "-//ietf//dtd html 2.0 level 2//", + "-//ietf//dtd html 2.0 strict level 1//", + "-//ietf//dtd html 2.0 strict level 2//", + "-//ietf//dtd html 2.0 strict//", + "-//ietf//dtd html 2.0//", + "-//ietf//dtd html 2.1e//", + "-//ietf//dtd html 3.0//", + "-//ietf//dtd html 3.2 final//", + "-//ietf//dtd html 3.2//", + "-//ietf//dtd html 3//", + "-//ietf//dtd html level 0//", + "-//ietf//dtd html level 1//", + "-//ietf//dtd html level 2//", + "-//ietf//dtd html level 3//", + "-//ietf//dtd html strict level 0//", + "-//ietf//dtd html strict level 1//", + "-//ietf//dtd html strict level 2//", + "-//ietf//dtd html strict level 3//", + "-//ietf//dtd html strict//", + "-//ietf//dtd html//", + "-//metrius//dtd metrius presentational//", + "-//microsoft//dtd internet explorer 2.0 html strict//", + "-//microsoft//dtd internet explorer 2.0 html//", + "-//microsoft//dtd internet explorer 2.0 tables//", + "-//microsoft//dtd internet explorer 3.0 html strict//", + "-//microsoft//dtd internet explorer 3.0 html//", + "-//microsoft//dtd internet explorer 3.0 tables//", + "-//netscape comm. corp.//dtd html//", + "-//netscape comm. corp.//dtd strict html//", + "-//o'reilly and associates//dtd html 2.0//", + "-//o'reilly and associates//dtd html extended 1.0//", + "-//o'reilly and associates//dtd html extended relaxed 1.0//", + "-//softquad software//dtd hotmetal pro 6.0::19990601::extensions to html 4.0//", + "-//softquad//dtd hotmetal pro 4.0::19971010::extensions to html 4.0//", + "-//spyglass//dtd html 2.0 extended//", + "-//sq//dtd html 2.0 hotmetal + extensions//", + "-//sun microsystems corp.//dtd hotjava html//", + "-//sun microsystems corp.//dtd hotjava strict html//", + "-//w3c//dtd html 3 1995-03-24//", + "-//w3c//dtd html 3.2 draft//", + "-//w3c//dtd html 3.2 final//", + "-//w3c//dtd html 3.2//", + "-//w3c//dtd html 3.2s draft//", + "-//w3c//dtd html 4.0 frameset//", + "-//w3c//dtd html 4.0 transitional//", + "-//w3c//dtd html experimental 19960712//", + "-//w3c//dtd html experimental 970421//", + "-//w3c//dtd w3 html//", + "-//w3o//dtd w3 html 3.0//", + "-//webtechs//dtd mozilla html 2.0//", + "-//webtechs//dtd mozilla html//")) or + publicId in ("-//w3o//dtd w3 html strict 3.0//en//", + "-/w3c/dtd html 4.0 transitional/en", + "html") or + publicId.startswith( + ("-//w3c//dtd html 4.01 frameset//", + "-//w3c//dtd html 4.01 transitional//")) and + systemId is None or + systemId and systemId.lower() == "http://www.ibm.com/data/dtd/v11/ibmxhtml1-transitional.dtd"): + self.parser.compatMode = "quirks" + elif (publicId.startswith( + ("-//w3c//dtd xhtml 1.0 frameset//", + "-//w3c//dtd xhtml 1.0 transitional//")) or + publicId.startswith( + ("-//w3c//dtd html 4.01 frameset//", + "-//w3c//dtd html 4.01 transitional//")) and + systemId is not None): + self.parser.compatMode = "limited quirks" + + self.parser.phase = self.parser.phases["beforeHtml"] + + def anythingElse(self): + self.parser.compatMode = "quirks" + self.parser.phase = self.parser.phases["beforeHtml"] + + def processCharacters(self, token): + self.parser.parseError("expected-doctype-but-got-chars") + self.anythingElse() + return token + + def processStartTag(self, token): + self.parser.parseError("expected-doctype-but-got-start-tag", + {"name": token["name"]}) + self.anythingElse() + return token + + def processEndTag(self, token): + self.parser.parseError("expected-doctype-but-got-end-tag", + {"name": token["name"]}) + self.anythingElse() + return token + + def processEOF(self): + self.parser.parseError("expected-doctype-but-got-eof") + self.anythingElse() + return True + + class BeforeHtmlPhase(Phase): + __slots__ = tuple() + + # helper methods + def insertHtmlElement(self): + self.tree.insertRoot(impliedTagToken("html", "StartTag")) + self.parser.phase = self.parser.phases["beforeHead"] + + # other + def processEOF(self): + self.insertHtmlElement() + return True + + def processComment(self, token): + self.tree.insertComment(token, self.tree.document) + + def processSpaceCharacters(self, token): + pass + + def processCharacters(self, token): + self.insertHtmlElement() + return token + + def processStartTag(self, token): + if token["name"] == "html": + self.parser.firstStartTag = True + self.insertHtmlElement() + return token + + def processEndTag(self, token): + if token["name"] not in ("head", "body", "html", "br"): + self.parser.parseError("unexpected-end-tag-before-html", + {"name": token["name"]}) + else: + self.insertHtmlElement() + return token + + class BeforeHeadPhase(Phase): + __slots__ = tuple() + + def processEOF(self): + self.startTagHead(impliedTagToken("head", "StartTag")) + return True + + def processSpaceCharacters(self, token): + pass + + def processCharacters(self, token): + self.startTagHead(impliedTagToken("head", "StartTag")) + return token + + def startTagHtml(self, token): + return self.parser.phases["inBody"].processStartTag(token) + + def startTagHead(self, token): + self.tree.insertElement(token) + self.tree.headPointer = self.tree.openElements[-1] + self.parser.phase = self.parser.phases["inHead"] + + def startTagOther(self, token): + self.startTagHead(impliedTagToken("head", "StartTag")) + return token + + def endTagImplyHead(self, token): + self.startTagHead(impliedTagToken("head", "StartTag")) + return token + + def endTagOther(self, token): + self.parser.parseError("end-tag-after-implied-root", + {"name": token["name"]}) + + startTagHandler = _utils.MethodDispatcher([ + ("html", startTagHtml), + ("head", startTagHead) + ]) + startTagHandler.default = startTagOther + + endTagHandler = _utils.MethodDispatcher([ + (("head", "body", "html", "br"), endTagImplyHead) + ]) + endTagHandler.default = endTagOther + + class InHeadPhase(Phase): + __slots__ = tuple() + + # the real thing + def processEOF(self): + self.anythingElse() + return True + + def processCharacters(self, token): + self.anythingElse() + return token + + def startTagHtml(self, token): + return self.parser.phases["inBody"].processStartTag(token) + + def startTagHead(self, token): + self.parser.parseError("two-heads-are-not-better-than-one") + + def startTagBaseLinkCommand(self, token): + self.tree.insertElement(token) + self.tree.openElements.pop() + token["selfClosingAcknowledged"] = True + + def startTagMeta(self, token): + self.tree.insertElement(token) + self.tree.openElements.pop() + token["selfClosingAcknowledged"] = True + + attributes = token["data"] + if self.parser.tokenizer.stream.charEncoding[1] == "tentative": + if "charset" in attributes: + self.parser.tokenizer.stream.changeEncoding(attributes["charset"]) + elif ("content" in attributes and + "http-equiv" in attributes and + attributes["http-equiv"].lower() == "content-type"): + # Encoding it as UTF-8 here is a hack, as really we should pass + # the abstract Unicode string, and just use the + # ContentAttrParser on that, but using UTF-8 allows all chars + # to be encoded and as a ASCII-superset works. + data = _inputstream.EncodingBytes(attributes["content"].encode("utf-8")) + parser = _inputstream.ContentAttrParser(data) + codec = parser.parse() + self.parser.tokenizer.stream.changeEncoding(codec) + + def startTagTitle(self, token): + self.parser.parseRCDataRawtext(token, "RCDATA") + + def startTagNoFramesStyle(self, token): + # Need to decide whether to implement the scripting-disabled case + self.parser.parseRCDataRawtext(token, "RAWTEXT") + + def startTagNoscript(self, token): + if self.parser.scripting: + self.parser.parseRCDataRawtext(token, "RAWTEXT") + else: + self.tree.insertElement(token) + self.parser.phase = self.parser.phases["inHeadNoscript"] + + def startTagScript(self, token): + self.tree.insertElement(token) + self.parser.tokenizer.state = self.parser.tokenizer.scriptDataState + self.parser.originalPhase = self.parser.phase + self.parser.phase = self.parser.phases["text"] + + def startTagOther(self, token): + self.anythingElse() + return token + + def endTagHead(self, token): + node = self.parser.tree.openElements.pop() + assert node.name == "head", "Expected head got %s" % node.name + self.parser.phase = self.parser.phases["afterHead"] + + def endTagHtmlBodyBr(self, token): + self.anythingElse() + return token + + def endTagOther(self, token): + self.parser.parseError("unexpected-end-tag", {"name": token["name"]}) + + def anythingElse(self): + self.endTagHead(impliedTagToken("head")) + + startTagHandler = _utils.MethodDispatcher([ + ("html", startTagHtml), + ("title", startTagTitle), + (("noframes", "style"), startTagNoFramesStyle), + ("noscript", startTagNoscript), + ("script", startTagScript), + (("base", "basefont", "bgsound", "command", "link"), + startTagBaseLinkCommand), + ("meta", startTagMeta), + ("head", startTagHead) + ]) + startTagHandler.default = startTagOther + + endTagHandler = _utils.MethodDispatcher([ + ("head", endTagHead), + (("br", "html", "body"), endTagHtmlBodyBr) + ]) + endTagHandler.default = endTagOther + + class InHeadNoscriptPhase(Phase): + __slots__ = tuple() + + def processEOF(self): + self.parser.parseError("eof-in-head-noscript") + self.anythingElse() + return True + + def processComment(self, token): + return self.parser.phases["inHead"].processComment(token) + + def processCharacters(self, token): + self.parser.parseError("char-in-head-noscript") + self.anythingElse() + return token + + def processSpaceCharacters(self, token): + return self.parser.phases["inHead"].processSpaceCharacters(token) + + def startTagHtml(self, token): + return self.parser.phases["inBody"].processStartTag(token) + + def startTagBaseLinkCommand(self, token): + return self.parser.phases["inHead"].processStartTag(token) + + def startTagHeadNoscript(self, token): + self.parser.parseError("unexpected-start-tag", {"name": token["name"]}) + + def startTagOther(self, token): + self.parser.parseError("unexpected-inhead-noscript-tag", {"name": token["name"]}) + self.anythingElse() + return token + + def endTagNoscript(self, token): + node = self.parser.tree.openElements.pop() + assert node.name == "noscript", "Expected noscript got %s" % node.name + self.parser.phase = self.parser.phases["inHead"] + + def endTagBr(self, token): + self.parser.parseError("unexpected-inhead-noscript-tag", {"name": token["name"]}) + self.anythingElse() + return token + + def endTagOther(self, token): + self.parser.parseError("unexpected-end-tag", {"name": token["name"]}) + + def anythingElse(self): + # Caller must raise parse error first! + self.endTagNoscript(impliedTagToken("noscript")) + + startTagHandler = _utils.MethodDispatcher([ + ("html", startTagHtml), + (("basefont", "bgsound", "link", "meta", "noframes", "style"), startTagBaseLinkCommand), + (("head", "noscript"), startTagHeadNoscript), + ]) + startTagHandler.default = startTagOther + + endTagHandler = _utils.MethodDispatcher([ + ("noscript", endTagNoscript), + ("br", endTagBr), + ]) + endTagHandler.default = endTagOther + + class AfterHeadPhase(Phase): + __slots__ = tuple() + + def processEOF(self): + self.anythingElse() + return True + + def processCharacters(self, token): + self.anythingElse() + return token + + def startTagHtml(self, token): + return self.parser.phases["inBody"].processStartTag(token) + + def startTagBody(self, token): + self.parser.framesetOK = False + self.tree.insertElement(token) + self.parser.phase = self.parser.phases["inBody"] + + def startTagFrameset(self, token): + self.tree.insertElement(token) + self.parser.phase = self.parser.phases["inFrameset"] + + def startTagFromHead(self, token): + self.parser.parseError("unexpected-start-tag-out-of-my-head", + {"name": token["name"]}) + self.tree.openElements.append(self.tree.headPointer) + self.parser.phases["inHead"].processStartTag(token) + for node in self.tree.openElements[::-1]: + if node.name == "head": + self.tree.openElements.remove(node) + break + + def startTagHead(self, token): + self.parser.parseError("unexpected-start-tag", {"name": token["name"]}) + + def startTagOther(self, token): + self.anythingElse() + return token + + def endTagHtmlBodyBr(self, token): + self.anythingElse() + return token + + def endTagOther(self, token): + self.parser.parseError("unexpected-end-tag", {"name": token["name"]}) + + def anythingElse(self): + self.tree.insertElement(impliedTagToken("body", "StartTag")) + self.parser.phase = self.parser.phases["inBody"] + self.parser.framesetOK = True + + startTagHandler = _utils.MethodDispatcher([ + ("html", startTagHtml), + ("body", startTagBody), + ("frameset", startTagFrameset), + (("base", "basefont", "bgsound", "link", "meta", "noframes", "script", + "style", "title"), + startTagFromHead), + ("head", startTagHead) + ]) + startTagHandler.default = startTagOther + endTagHandler = _utils.MethodDispatcher([(("body", "html", "br"), + endTagHtmlBodyBr)]) + endTagHandler.default = endTagOther + + class InBodyPhase(Phase): + # http://www.whatwg.org/specs/web-apps/current-work/#parsing-main-inbody + # the really-really-really-very crazy mode + __slots__ = ("processSpaceCharacters",) + + def __init__(self, *args, **kwargs): + super(InBodyPhase, self).__init__(*args, **kwargs) + # Set this to the default handler + self.processSpaceCharacters = self.processSpaceCharactersNonPre + + def isMatchingFormattingElement(self, node1, node2): + return (node1.name == node2.name and + node1.namespace == node2.namespace and + node1.attributes == node2.attributes) + + # helper + def addFormattingElement(self, token): + self.tree.insertElement(token) + element = self.tree.openElements[-1] + + matchingElements = [] + for node in self.tree.activeFormattingElements[::-1]: + if node is Marker: + break + elif self.isMatchingFormattingElement(node, element): + matchingElements.append(node) + + assert len(matchingElements) <= 3 + if len(matchingElements) == 3: + self.tree.activeFormattingElements.remove(matchingElements[-1]) + self.tree.activeFormattingElements.append(element) + + # the real deal + def processEOF(self): + allowed_elements = frozenset(("dd", "dt", "li", "p", "tbody", "td", + "tfoot", "th", "thead", "tr", "body", + "html")) + for node in self.tree.openElements[::-1]: + if node.name not in allowed_elements: + self.parser.parseError("expected-closing-tag-but-got-eof") + break + # Stop parsing + + def processSpaceCharactersDropNewline(self, token): + # Sometimes (start of
    , , and 

    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ᚷ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 z⪚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

  • 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

    c02y8%V*v~ra#+N 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

    {in+3{(rCrQx#D6ans%6V!@{>% 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%0DLZoadD< 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࿿O3aH|uqYm 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 z%0Ds8WBJ0EBgPi)?=-lxXru*G}-2N~cN&}i@>y7x2 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

    cN`lQ|oJ9Nu_FJvNnb6 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

    q3l?fH9}X?JRRl<#oE8-dsDaHNkpnGs z7gfqCQdJQ>NJjo3$FLkd_~gOqfvm*^Q%1DbrcK63eZf@EjUxtMiw(fMa26{d0*}YX zJOJG&BmyV*HD10p8F>^Ea?siTczz+#0 z!~pYue8Kz&bkY0}u7eSPM-M>&Vn&PML4+hZS^NK%uh>gm(@~2D7i{NJmIAvK2-e0(@N< zzr)!m*wtqB9+t1jqnFXJ*2a?g3Qxjg1gAwa^hpOP+Ius%6<)H9-*EmzaN))GTAF{# zy_P4LevohKiKkyXCo|#e3@3pHJ*WZ*h}WjV+Bm0IBFf2k-R~0ER3@2zPuBWO>Du_1 zP4Vs*OW2QQDDxMUE%bDZFVo{VYLtY3;JyOmKeg|ClfTTr>tOsTftu6!lf2U8s@9J` z1>F0m5Q)C~5)oFBZXODoh$bV?8ThVw!|M?L&egwDew`xA=)3emZ?HZQ-Qr44!-f*0 zb`4ijW#jpqx~UFovs|vptPn~Qf&XTrvlJC?5j%5uK9J@H;%5q8BX%~OSOe=@ABTxm z^i#$YkI!rG(J0DH82L z@QlWbQM7@_3lz;!_<*7XBPJ2~jTRu~M$FPdjF=TR7TnZ2@Q68JU+q6)PRrw;f$3j< zz!?5H(13Y>0fQO#)FD}I)Oql6TRdXsf+r=uD0rry{!OS}t~Z*q&|m$+UT6+|f?L?7RXr>)#G(Z{>BnPKh-sMp?P z=OzMq?Tvh3P7Hd2jxqrD_Iq9?sa|u_uUapsCJirGO?Pu@`zkqyBwrc{g1S@FcU8lV z1-w9}qj64xA_^#)?TIk)?Kp1+z>1vV zH8xEb^hJ!VIIP*R^*xrVQxh9@id*BFf25O~{>@2FUi%_i4C$%3Bwer+Ek$^{dB^_(4unz8K+mDSS;x%2VFY?$?{IkV-N7t%HojrrB zdTGZu#T0_fI9OEKa$KHj-6kaF9HBxJ7#@d42&zLuK)5<#6+d&?7EEK|R_zyVa4jM0 zj96{E?VE}8ow|$$tLFcp^Pnd-ng@quU$HeD2ovWc?=^Fg%q$4xy+yjh!_VZs%k0)U zBeEB9qCTGN)zeZ3dQnfTT*Z?im~z>hc`mQt^6H=V>L2mywVOkAPprf;A7a*Kr`fBW zf`iv@<-faM6?$T&VNv_d`s{F?4|*;;nMo65&Ncy9!y)U{ZwjlUahv^~fmsaHaD%z5 za$Zph|6Qixl6{a{HklYs(D&MCaUzNyON1b6$Wq{;d4t zkBml0LdZKpeqpSFpcpMnh}H>fhQ;od>{W0NiwU~l75oE}D^$&UVPl`U)a%%MsSOh_~ zRClomUq+w2%PK)ZRd>fC5``=x8F^oNHZchQ4BUggjvo%pBIN%Tun2XHA@-Tn)}%cK zJS39=jHtHMiO?GSB{}gKT3IMQhkU_W9= zftYbLxbXyE?Yrvd)?^}cORW7Ie{mGhw>I1e`w7^qv3~OcH^z^Uu(S2ffp~-Mv{S$v zCQy=8!^7Jf6?gRP~5_@rmFBNeHdO74G#u~0W5Np`_C$NUKu4R5p z{~B-jnNGwTu7~6r;eFZ$869%4$q_P%XCYP^6JWLSBj|$Q5(UBNBb+{=8+ z(3KvMoy`>>$gAJ%)jxdTx8^xUI4QH2^JJipwdVrDoc&8HQL3$+{@b__)1h#>hrD2* z37cn*a|PMHDA%2c&c1_;zCF<^kR zrL|C*JoGfesI(XUnDxjN-(|F+!2spw`Ula}#L|1MF3!FID+rYur)Q;s3jw54ZK%1` z#5rP-2aqBb1|UsToslON0e}pV`Db_=V7#~_H#Od|8DYY(1CSyTcLzc(m<}~aHYe16 z1?p;FpI3oQ8|UDqTg^hl2wxiM5XgKWRMf#`bz4inNQaF#uPUFn#mAzC=YUJU*LmSMQ^=iip^e`ii*5WqjT&wV<5&ATr+381Y-K=B(eM>gQ7205 z(J)3eAJcee=;HQwlN-Ll5;6uTjvI+gJ<1fK7HU5jtsYYl!>y}MvB8>*?99t15Yd2Y z6mqm}j-%Ni1xM`1(M+G>wQD!Hun*kelrssU)WJB~w$?ink@xXr7@Caip|8=vbPr9) zbA4)Vu(HIRk6(&aJs7Otrd%7xMT2#pQUi3WE+mk5u|QP7^ePo@q!!d*gYM&e_1VGL z+-y?N=|y7`(*wNDEBm-{I&ZoDma4o7y}~HkC6J5e-V)`jvRHF^(c}b%~w!X^lH8^kjlURWH7YpJw}}+NwrfH1SRR)a_LL6IBb9y}VaR3BFA4 zZqh|9-^Y(WoeU*ARIM8%91+?;feOm5vOopRY@x@+rHV;ML^g|AG1J1&>GQa=#4^t> z*ZFxW|As1^4%6WV3+-@ewa#Z+{EMqp06`%d^rOb008wnkDqq~Zy$);vo!htdta(XFEM@7}7^P4PhlU~1Mf{y3;I?mV4C3PHbuqPIA zc2%<;XyI^Pio?vM9HuUZ>qFA|+LATD_S%2VkYuYHuj3Z5oO*V2ua0$Ehtt=lRxI7A zV=cW(%Qm|))5MtJYLfLp%5__#>$W<&jav!VVYR*GdR@;{hJM>wJyVU@T6J%>s^6mH z%(XgBy^Y%4a65-3cl1oX%jLhD>J1_3s(UzGdM}6h_i;Gy{+_AZT@DvIjzW4#pZZLX zHrv&kOarA)>^RQ&g`2mDbdz|-=_^9?0*&c`#D-R6^>c;mBeeX_H`5@LzYW0io1;02aYk#IRG6G4t>qVv31hU=h&nLN1KCqJEejLDz&t35$v@@o0u;3Iut6y$fkWK z_vFB0L^7oP-Ve4&51WiU%(7=uY1FZ&ii&pLVZ>T7dPQi7s5CVG=v(-o9-r*k>h>I* z1)pJ`gz;T;dUSaCB{L&^i!Wcha-QJBq|G{}HXD{`+-%+^b(>2W@ncbhMVr_xiJ{dE z%Z=7{lU&9sqB5=9D_bl!Ou#XVH%4@Wa?Xf0M$7|rA1r0%GX*WD#%p?7zoP+K`j(Eh zZ!yl@ZH>VxyLzU)z*lR?&DgD{_gM12o+&n-D5CXe3B_jJmW*sQhZlKOMK;GHj}gy+ z#?V(sQlpdFN=i;VD@VpVKgm9_3Pz`9XLTX??Ng?{bxjvZU8ZGpdXTj}Gz-Z2{e}2} z2F$8&jQGV$16ifkKDE|9Wu+F@xOTn1fE9D=Q^djRX?;pp@}w?*n}y$RJ0yY;@z-9p zW8iKNkuKhb`YUAF)gjA9DZAI*3R!k_$g-7JERA=Y0Ys^&4iaqIXtvn2(fqM#qq#9I z`zuM9sG&#jDX{bhvg1tTB(|HCr=D=GIq5Ca#&6Bmf}CY5q4+HUbsInoxUT; z(D~IUN~@cJBb^LO`Q_kwUxF||!>~pc*aP}EXknY7ChAN$MFDW*w&>1syMVYyROV$sRj}d;Xc;3G^Y3RyfWRpcUgQ z%?>y;IpDAy;GkIyEMWFJpeURpUS#M<1mWJQb@YI)17y@>$mnjP^I~?5KnUY`0vC50 zE6|G*KrDWi8=i5&ew7Uz#8Ci9Z){W1R3U(6sU3P_W7SfQ7&$oBRW++_O;w9jSd~E% zp%pF~L0Q})fU$lO4(Zf7wAbj+Uc%wAlAU@-v*WN$0WfM%8Gs;;LQZ;ZowC*OdHgiO zfmP~kT?D{LV2SW8LwR2`Xe~u^2@q0??p-@VH&c887cMXw7+YV-^(9dqFHpeVvN=}N z4DCWuwrreIrc~;t3$T9;k?zb^`tFy)tzoYYE%i0SgBjA zE1R~cD}!!e@TInBu^B&NdTtD|3x!uV{HY6gjRrcUt3Zh=8Xse~>e#fkq}DraiwbVu z>hSkg1InYf=yn~Ya;s^Jf$`ccqrDsdnox?bc?*6;OAh}QW%D@?&=d1?V6(T$-n_R+ z+QQX>N3glSrCu6&4H;2a?s(0c_bWBsmt|t9JM+t`8r0cihRkrp1?y@J@S2 zC)bwh$cBd;FR>wZfeo=aROH#=R*|P{SLvOU%uea`kG|$LfcoaWMit-Zm*sYEQd1Y{ zSg)Eh)~kM&J=1yH{qs=P*NyryKf1&4)L0bK(Ot2K|2<4w>iIcn= zH@liV(}U=_NaH`PhsC`+>LsAnpba4&RC)Cy?M{^vW?uGw*_wpp=`bAlBF7>YQh&uugkhDB0n!rbqZ8?=BmDGCc=}X)h&F(Y>tKNaHpb92;Vq|f zp|0>oKmAJ_6Dr01QIVq(7`-|fdBnLVJQmTHmsce^iNM72Y=?u7F&zAB%`457FVxSB z%rd0$ssqHMPA5gTh9AWV{wzEAf4;9dz{frGaWvKA@G&l8T-Eh3*FPkD?6vpOkbcdE z)>~C{spfCA?pH9E=p^QIG_`}tn`QoTUW+0EYO$kqvRAj8|6cF3KJUhB-Sl8mR1;>1 z`7n13oqx34YrZhTEs z!CSD4dBQ_D#QesdX?UC~qE#;tA$R~PC^*j}Y}N?m=VS)fF&q@C5dsGQ?md3wDFOFs zQ9yeFIk^2dyhot@7{-I2{-mEi8@uLaK>H-Es1JNDexg=dy&}q_`2RSi9Y$R>cV=XK z7iwHcb@ZgKa>eg))A;qOU#BJdPF!i0)l%!iTDlNFi_IKB^C5u0L@nQ&Z~59^L9na4 zA$sr-==(d6?;h{QpCg6x#Y*R+_hEQ~BD}{b`vmf{;4MyjU_2%X@RncdEx#;5L}>l~ zM<@mKci-SU)LnG!JpOHO(0ScT>>_0scHk}9vyn8N{}a`I)rdQloyWfscKUX~+g!iN zW?!QB+2h|X$o~!vJpA?Zj4M4NI;ex=N;_ya<4Oxet}nte)c#*LT`gsAIm;XvO0>f79DvJ#p+^Ci6bTK zOUCH&>UMZ_+q~0uc&mQ|Eudh=X>{ZiGLwOK^4}mXsn6uS^SZtIkrPyuG)-tU*bg#K zjIvj&t#bPvL4NhdV=3{ZU31*)oeF-o(Ooev$T7R88Q*zbnHQB7QfII3LGQFzl(Nq9 zg5Lv59MEWyZg2H}aHM|JH9GPpUPOshmH&oU_{DvKp9On4{Uy#6WctFj%2dBOq~CnV zRHpTMuWqAP_ZzN0T}bJ@(>8Kx#J)|nNYAf;>$z9H1oNicXTAED+4*h1wyJ(KB>WV5 z9^Y9ubu7;tJ20*TJIL;F{k%c7-+HcUud4EIwWrFeJx#=ji+DNa>@G|yX46EJL7s0^>{2>#D05zWl@@CsZKBwl}CZ}S%L0ny`X ztt379D36_OkL^dp`|c%vqq9diV+5k*`F{GT^Zf4jhaz|v+9PBF=rUHz5*mI#e2Lqs zvi7$}IJwfSzPG^ja2pm=P>1=)&blp@DQ6O`r~jt|rWcAoBwkbx7#^G$NsU$hMVaZbD2)<}l^G6!8KQ zI@Sf!a+GsPs64jZBw1M=bY7~Y31(z)nt2K_Vb#ge1%?N`(To-cGdu{i=v@h9Y~`1D zVX`yCQC0_j@>T~fWOYz2r5BLVf!xU3+{hapxKPdckpzl3T@=TrdegKFyQi1k5FnNW@WK~F8x5etN#GI1Ik z1m_qbI8I#-m}0SHAA8um|SE4Qxk0+Jvp#M@Y~Mx7-Dr_XWwxrX?IDv$geXy@Le;z zbZ_cL)%gZVUu8=k^lKSSB+=pk)os7RXrp86~7k~8%Yr6#QG+8)L`@(b#~p*>TOL?mW7F=j6`h>cOWGo{cP@$>zJ8b8w0-x?8TpQ!dT zXo;00eG_a7tPv=OKgFsj?b|3r&Op|Pd;CIcgv0AAMA4CDn2jcl4q%P&Yc{p^nhe4e zD1QmJ@R!^d{rRmC#K&@)|LotJIwWROCA0?gOsNQr3eoJBgZl;6gALhl0mQ-rw#etg z;hMiGFdO9U1%a`kA7oi)U0Gx{V4=*o&`y9BADh94Z7aYQk(Rwc>)NztssrwhH6)&y zaIbI*s*9-KtW{p|ypTLewS4V+dy;4>BeoAH z{;b&t_{rM`P!)q$IOgpGQV!EL{N(KeT&RWk`7iqb3L^tRAKX4bAeVvc0}ia9=w~oA z2AX!ziN;7cDr>h^ptmr4L2@ec6gg8{48Sx4XL6<~Jt8fsQ~945HIY$11mx}teb#QDzr_*T<_XuCXBjmr8elnQ#@4X@Kk}lfMFsN0i()H1pioI zBKW5%gESGWAtQpQlplpAf_jpLmqHW4bX|kLmQ{u(f-3LEq3(r)Fa=Ojfd%00$;hyE zqh8}j?{EgH#WCsoc?DJ^ju#l1os;lx^xRtpspb#O1WwHlQ*<^6^!@F@>lO=8yVb#* z-0d1&6>N5j|HdF6wy3-%LOVW}U2EWZnSl5GjwF$|*s%1nMc$1)@KjL22Q(3Auy&jW z&+}1dSK4A9)~r-Zz|^Sphb?ED14E$DZ78zA&o}y;2ig#Sy-bmLzz}GtPjVo%B`^=H zqu|gypoR-92^!K4jXKr7nFmggj;D<~iS$Kg9$4qjfu*6T;G)nxa1r%4^T0)B9xx49 z`Xaz-XezkK%mc;v)XhH313fYM`^1J6S_o#+wku^J$N|+v`WQc5kA+|s2Jq?Vn0v4g z)D~F?zEor(AgH|fygW{2A;3?!UHH@%Fg{_}w8%mLCUq8q3pM@_Cr6%lma`Bf(k}%T zf^$jHt>M+2R(#}W)oXv2){ob03_NIF6xFDE(X58cUo_&8da*Px5OAyZIZJDL zuGmEIibgEjBeYQ;f{7rCp$sy1Z8^3FSMUcl5u7-XiNMhGlc9;=xMaA7frrs3GL2{(*MW%1P;0~^5x+A6RS+{Y=?chpU17TO5XT#U$r308cH zTZQ;KvB@lzwVQI*g3HtsPpc0~ttV<<9MD>D`r%j$@Ec0}#)6vG{>BUjfAgQqU@#FW z&^w{l2GAhv1#dAIbM^(Z7nDpo9DBiU&j{=V^@Fw-NaMVpy%f-&L( z39NHQI4c0Bi%Y$_*PY_uTm4NNl}@w&yDzIQhtTZzDwFi%tk)>i=$~L({EMRAjeqZo zJf!BHBI<=`rjO2E>6F8!p})dvfuwsN4gL9H4badlbO(*KozFV%FYUolLqCqIKv~}1 zPeU*1jfW1Qp}%mj8u~4R($L@X0W|bS*)vfo=x1rPj5?zx7%ic4KF)V^>&|$0Cm1OM zDCaB5AS5x(C`hs-JBz{t8TKSsw=HVL-4peSP&fY)SF|FduE@UH_v51V0!}|~o^cZy zy*^(1H|v)$5n3T2m4akkF=NTM>-aTaxO?2mEmd9anwFCEt zYX|PPwFBl+Z|`)vZhJS++A7ZzfF!1i$0?5$xl$IjS-lk1E-%i?ac!YQ)RxsRlJ9j} zB!enWc@vq@8HxjX;E=;LzHYV$eQi~Pt+jmaNLJT$tAwRe(8+<5C|T&Ef&~Y}#A736 z6~5^5wHAmao+&A3myBa%bOvlJL~Zvvd_I}pKK>Wuf0s=m(T3}hyft$q-y$nisQa5L zG?SYvN;#$~q8#fgq=Bie5bAF|$G@W3Np1`Ac;#ZQgyh7^l z)Cs1iUw*79)KkZj3w8ZiA&cf?P4V7ztV%&7S6bt-rrxeQR`WK&_LZb1jy0WqiIVVG z=GdhD&UtZ+W6HK}1VHMQC+L-RC#XWTCs5~T;&`2>j@Q>UAFr1$m!EvJ>3DtPq~l4@ z*66(Wc>CPrC9JSh5yu1$UKDe@iYYx-xP58h!DdSGmcWC}oQD?Km&os)Yzys+@c`Fs zFl~E-Y1?O8R)4he#H@^krg>jv>h=~>w=cC;Nbog$c+gHbaOe-}G1TsxP`mGLOGF-s%aQG6O_-X8ypB$U z0M%i%GvZVLGh9w3GPLxa8e4QFoyF);H;tv6=rJWXst==e)_V!-vfAUzdCTOUSew&) z$J#ZUtitPboQ=jkhLj;qdMu}L_q%j2W*YaUrg3jU;~v`{d?Rse{G*XpP5ob5}G(*aEa@X$dU)J95mF!f>|Fz@Tln;$PDtz3GCu)a2 z+a{h9JcIRgdRcWcvQM7+awu{8`K3;^D*QWhe&zA;&T(-$KX=BWN!uO%^Kq65P+DF& zF0Xx@l57<`PWy|z4!5;@-k2bYWn^j>{^|Io{f!=$W?8bh?MAvww5bfB&x7bNev=I7SOxsQ!%SwRq5WiM z!Z%Q1(roLKkqxwxnkAC@jDH5&6;2r`99Mok-g$Jqb1MCk^X!+mnQ~ZU_@H?ssbzBS zR~bWAel3i7<=p(gH=aNgunye}S%|`>_kC_H`gOj>T7|WjjOZe7|9E73oQ>s)@6+AN zdV3uH$x*(IWVGztO7xxFZ$%Pvtk?PcuOk@+lMCk0NyvQh`Dc3RR>*v-L*|Rm{}3w2 zt&sUv2h8^y8^!O7eEvff`30s=$T`~wKKqQ{%Iq+18Ga`s8b;<-1&a0m2{cQlH;jKH zo93)gpB}79+|U1Bpu!yP4Qxy^r+cM+_&`HG{;VeO)8&M_A^64vaP1IXB+?Hj(ky;P ze;!)%o%J4Gp{JPjxZ-EZ4NIU-FTv?v=@XS60E%(_00kr?IgS-JN7!Q4Ah<57^1aye zG3J{;CuUwY78%YW!bwN^k+DiP7mc=n0LZb3v}i4D#ZR+b;mfX4QrUb%9BLhIEVosNW#<{OPV;l zw3);F7S$-lVdhc}T4%TsD$F{=$OFk5R@bM+MQWb&Iut)s%~@p~Q43h$Vv=inq217N zom629`hSx8pMHi8;T*L=9`#p^m3UI1zHT~x1Rn5pO6G}_8|4nxGE_sycl9^r)-mkK zHTDD@n*z*iW4DPxLRurknx8s`HQAdP$sQwqkuDN$pfxcj$ibNKZv5qNCQ9HZ|NJR~ zRDy3MV@?U~m7U?-1XHaQqPRKJXJM3k~>q z_l70aD)%Z=fOB%Gb^Cnl_VZAHpX1&!C~E4@%j+Q6uTnrHnpX$;v0r z#3TNBuVX30Z*4OD+RRKHzE%oOl3;US$mc{@`%U60c%rn==lfS&6YsnM9JT};cB!Gk z7WOlT4Y&{XJFhiBxHR5*Mk0M@RU6N0-}BBnfIP@M)G(P|2qtU+6D|c4IwN5`JsVi4 z-JpR5Ji@sl!=;>n4Bx?VB8Lpe4GEB8GhZ%bczT?Lr}577sL_1hLcsvV^lXq}Lj@0l z3iU5!xVh2?8CH57kD5Zd6i0Npl!fWmip7AlfCepi0w{0~{5;WlA@zdQ#UFhK`1j4E zqC>R9?eIXuadZ9nt%|5Z7eq(CU2P*XIw~>-6q706#HS2#D(c}6b5DNj(oXkXr}c{~ z93DJEs3vuU!-GdSJa~k|gQm2qi#R+OadF>)zHBDb`cJqrvu3=&6^xf(N0ew*7ymunEQX&<%uW zSS;55Z<1q(->b=xbD!<-YL_r+ZI`L5<0w38y1jPA9u_c_VJjMBhNh#XEB0`gOOw=Fhw^am z`);T&p}<2qn`cpV<>V7eAB6t+ew35_^v5)SxDZod5dP-BJt@#1k9JzlLHL{h3pv4e zA0cw@@24N&@eSbdH}c<02Mtp%5haw#{$5p}eaz{qPp2zsMAKFO-rWr}ko|Sl&v92{ z!L*NlNp>#%uvSHXTI1{=-QDO^ypKOm!hy8a-(p7dzFyU4mA&r}+Umv1gtnSD$C&J) z13H%#=&K>hmEMj2=n6fwzM7|IS6fkIv-4bEn#TGMC#qfc9#~`jf-(d?<%*ieCv4{v zj=SF;3^msO!PNmY*6RnQv7SFzjrGNY(pcZ*=DD(jC*RehUNkE4QVW9;RSguJsVK^&n_NpL4^hhvHX1WSTnm#_lq zAs*qGP-QJKbMopJShz=Nd_{kS^`W)Z6AHD}_uwN=xOP)mo5wg>BOpv5WKKZHB&?Lv zT7Sjd#GTgqYGD24YrRaUuLgJnsijUfJ+h#(GJNE z$ZwBIk%-7wNy>7>Ns2*Ekbr}Pz>kwALwz;UBxz2X4E5DWlcYImGSpWiO_FBPZ@PT3@FrBH==;{Nh ztZz1z^({L3YfVLco9e&xb{$*p*iV(MZ@WkL7T&94!+ko=zJDN9w%@CJv1bNUS$n3k z-Wv!jq0ah+Kxcg!KxxH5I%`QOXox})1(6}tS)c6WlYw>Ch!k@WPWtJrfsY5)S^tFj zzap=*MieR3S(74r01E5RuKYhyUu{N~V8DivVPt4=gEo7%DXZJXblFU{1-p+-LyM64b<{BkOXJkyNnGSUN|m^L%S|Od36(e-A8hTf5@%VwsluDn)70%-@08$ zCrgC>%dQgQE4x&vzihso7|PD08da_ugHn|*saCj{y5nZs`*Pmera~u%%&3VjU6Y!Z zj^oRm*+(wqRA-V>Cy?qC+e;>TH-5^!eK1ONbmZvHC);ZMQ4b$Y*Vc{f;fF%6nr($H z;z;nLKvCYP8x7u#M@yObr>ewT;dIG#-^@(;Umj2)zKm~Ki9&n{Jn)7i zW*j~BehTq%&IJk`cc=&tl;f~cS`6hk%4|F=g6+qgmb|6nKnn4zq~1I%g*Y1qIEDE3 zoI)HP6)MDg_E(7iPBL||Li{FEh`%(TLVV08Y+Oc1jpL-BLj1k50)_b3(eDNR5l4dj zqp2gEKKw|h4?prF(1-7WN9Fb5_SQQ0*5&T4sUt(jZ7OsCg}6*2Oz98Fahus|j@!g` zc}8P+P_bPOq!6#nDZ~j{jY3>O8MmYHIVRAEpCOI-BN{UJZ8OGDh3}^k?+G;GeHYQLL1qYLcYl5Ow?7Jf z_#ULM!_>PfLae1dm4`tVPZTPDx!2~LMP2z~hTAsQf{kB=l)Dqby z8G%I#b5UdG;w{+(t0l`LUh&g`;j!}uK>KY~Z4d)*^*?i@lD!l$@@h&xr2F?gWhzjp zOEi?^9z=FQh2a$IvqwPKk%5*H%H@B!mmE^T9@;{s2niMKf!%asR$lzn)D-R;OI6do z2UfWM4`m1x?&lUL+&k^TP~o28>HrG&uMSG#K69`N_aTE)xPQj!v=2++zRu=QlunHL zrf$FeFSJfOhP!`343`8g*G-mD-{Nk5Ac9!>$8fox3~K*C4%fJSED|I#| z-!>52<9^Hb}MQ#aZMH_^KF$an)sUL#US3DZAkw+4+4$fSk zRGn7aE%T|K{Bpl=0J}*eI5BG@!)O4qtF8yZeV%B`Urt2W9dQehB2uH{H5c?EL040W<(^nPvGnUFI9K|S1#Y>sbWwi=L?xGie+OOF{ z@H6}vH}sIKGJ{*KgnDC~c-4%LU=z7<>~QH9IUo9+5x)mE*>)D8`$lAsXMS2dhwPiC zMPYxA?F>GP=$jAcyLwMcuyrL$9i03+FT{yZugVWa24tct#<8wyHpj-Qg&dKr%<)jG z>oqD*MwD}-QjUAtqK5HEL|rr3Fi-*L(c$qC1`BNv%8k#)poU{OLft4Qfo*Umuup)V z8g(L1X+*zsq#;P6KoULk1Xdc9l-f`|l5b`!4~FX1E9R3iWihfFEk<@7F|ujzvDWHM zv^p0Fc9ya}Fq26YqpWa{eum3~57I=<7B`$UP&45`t>dkX`6_!;b5{w0wG<`LUgS`1 z7fX-c^y+@)o%Wh{iW0`!@cI4RDJg_z#@YlA}I% zMB)0tFIu7RNCrLM`k59w-g$NrO$@@#HY z+uW$OxlygT(ci^D`*-gb$Bd+B=-CY@2G}?&yNE{1>qogMX4q>3Vcshm8DjcRk;d-= z4Vj0%YF%pNJeGYH3D!?<8{d_kqjGqkh30cB?S5VYHwa>z1r7{Lkk%bQ`w=(ue6c@3 zyOX;Ny9@rrAxt4B6>$>lBz);`KKIOj8a6Xx%o5_1&;}+(fx7J#qCly9 z|E)ZHT2#`H77dPJo+Uc;SJW=IEx-XdCc{Pnboz13?r@?fB6w33O!H@%lg2R*FwNOm z;w`%CusNm$`*$2O2=;&OP;txv@PMhsWBX2Y4pq6SOTCL3W_JpPxjqQ61JiuGr}lBj zG{FIbVwjFwW67Jq) zY`VD{-OHbkUj{4Y7qepi&&4kfHj(}We)*+8&M1hvTf>!zav8t-@k^(VIq-B^pBf~; zZ2bQLzkK99wID)d$Sfy@%yN^v1NQ}~@3$)b-?$5*a?CRO$pS{1vFAcYd8_3ckWqFG zicy}Kqf?=X+0Vc0JRg_tN8e#jdM9JbnM!n3vdy4m&GcxHJ-*K=x*GuRYqLG#du|Zl z^dEgMnVHb25Ltw-!ez@~J|V3{cQ(8`BZ67}ckCp}gMkEqaA8K+UbIAr{20xH~{|%2jD+ZD#TrKGz}iEmP5(} zM;>CyoF91=2lv#}M9tRLPQ9|!O0WF{l9;JiCkA`ZDI-1`6v&!NJP*V>m*(9McC`Ks zY4hX+USW746W;GQ6AgYXzKN0*NplW9C~OTvxRljy`#!`?M9%fmWX&sH$J@p|C*YPI zG!m#< z5@j&@)>NfM%uoWhtFrPJNuJU}*bJ(ScHGv>9a7E=c;O-H-3lO_^lGL2)+9mzXuaQor^!g=WKz-Gjy89 z@J%*`O($E&%O!={>zaoaN}=whO+yQ%(CQCU3N7HO>l}+1gcKT>GxSM8m`D8k34>b2 zsKR>TCf81zT=AMmz4o6_a?XO`D;Cl8fhX66Ho0(9!3m^NOIqEm3T#{`FTx!&`$e+% z*|2~CaMG#!9A|aj{~lMQ9{1*(##sx!|4#|#!^%U?zH^`t#H-0q(t*U$3tiiFA5t78 zFirotI%she{RwPlW52lCBo)e|3uwZ;Jj2byl1Cp$9%XgL_{VHpPLoG@XLL4{DLV28 zZybof{@?D-0r>0pxXW}2qP`5Hf>g@{(XZNbA%Fdv<@*!(>lryZb^!ir{?m`LJ!?*f zd-wi)wNQ7Po&Z0^$ypY)g!H!}SjJCZ6upuT*!Xjx_$6!>JDiFn(Ozf%;14q*B3wB- zhCB*gTfzz@7A8%of7&2$ z4E61hp-O#=Ltha?eWmq&=KPpMac}>-vN7*U^r@9`jnjUytXckiWkC>f!U(6%HRdCfc0i zXX=*GIqt_r!m-|3Sg+%SACSLF0g~shISx*lP44B*Fw?x)nq&9{YTnO%m<+Z+&HHzb zN&E>6Rt(L#{uA(5Dak)Le|^IE>vs6-St@5OY$DHJZ~eW5 zgTN3P%CI?w?>D%6V1@4z?n1&Gj}^YkzRRmZK0D2x4f*VJ%R3;S9h}1VbdfUqE0$ja z&)#9$aB>TyMn)+DS>A2?Zpt_%gA~D#IIoscO!*cc7A{c(0VA0v>=o;# z&3THQERYSHPc(@YZoHaa6mjB{Gc#i`q>MhD;D|VS@zAVH$>~I(rh`hV2yqdyoh%=x zmKNc%U_EDa!g_kOiXEMZfDYM_@f8m^7!M*#^Cnvc)Woi5(7zrfHTFopXm~>uv3!G` zsIxuM8h)qb7s$tcOXN#zwtT-(z7jK7P3l&T$MlG7lbkQdp2g2rlNBMLFX*a^aj{sO zd)Y1ymxz5|Ajx=+B;y(TI7|V)cY7UYiB}C{ITP(Rj(x`CtM^2_j;xUkqG4kWDlxHF zP3vS`bxMiX{z-n+NR?>aJ7^N(sO`cU$PNJM&9gG2k4i)~)24r6O}31@L6g;DKGH|4 zy-L(xF6@poR--oNUb8innv09kd`ZJo`lLp;K9@^&sA<@EfG=wOd*>#HV7>|1pvn&Q zI<%NKxZ>-oxe|lNM#b<9%(M(pEJO@YBFnV#Ih@!?tqun$@nzPz^k9H~W244}a@KYP#^~-4D|!8*kuh5t=P*6mY?8R z7x9N$ye}_|7QN5H+}&2Slyi!>*TV2AL~xruIDrR)fCxhPC8Z2%jN1T6J%CXK6N_oc z7|cho35_4w$-dCTS3ie6O)Ci0jp<)$S)(65q!o>N*iRGogeFu_`7~q8@7{;+0(+X~ zGE#!p863gRI*CY^=#^GNDo;Zqy;U!$hOBk^-OrU+`1(wFIIparm~tQvZ}G?UCV1IG z$|4Lto6YD3Sb1Oehk#h@BdmP%i4W0kkS5Arl|<7l2ZC2R$vt|>yQIw74M3mnR2slZaY)(Lhh9%Z{{%V7IH0t&_u6- z#zZgGJI;dwMcG%xi%zAi=zNs{=x&%_Sk8qo#Im`!shrzY&K;T*6vUB|I8qcx%Hn97 zl&Cb$gW@0!#pSJ2d3UP3yHwuY%6qMqx7f<#^GTUwJqh^TN-4h$kB6>6<{BQh8fc-h(Qy#mZY` z<;}M8P-K!Gv+@?wm_`Jn4Jy;h6PIx1J)!cptGr&7_Y5sf^}Hyx^P*J6i&8@`N(H?r z_4A^+idmgPYI-3>m(8WrvLxBdrm2YY_2Acac8;FDS|y&XA})6|@}dh|g}jCZx%!Z) z>_W1Oa#7B^8jrIXkIsA_Jxbm@BK)C>mGQ^9qCIp+DSD1-JY}DDGK{a@7~?BvP-278 z!i0HkuqcE!jGm{AHn23r8fF&c+Ctlr%bJ#KG^86cHhhY5Zg)AKP#)gQ(G3P07)5XH zbvd6=o^vgy>ul@zhIql-ce$Km#L?N7({-bDX@g&oQ$0;R)xZ=PbdNf!s634Xa`BvN z{PUGn9nx@4L0K9p-9MY|!YR~im}>zt2MaT8fT*~A-SPK3crFO!GU=!?wqMz0XtAvs+ zr{K(eLyW4j#>!js3XXs(u~J|PLdel5VT|z?)72%<=y<^kjK!G39O`P0Rxd_pyw12J zt;^D;sL8M0!Vu-r%?!%u;_VzR>E$50;m8SqE>AmYpd6Z8CVt=W3tDB_Mx8yT!&YVo z<`B-hII{?X6FCXO269#uPmn4td643lY*Fp5dP2ubt@fgR(W^9&?fsXkPNIz>nPjrv zou~?@Oc9P#H6$S)9H>!_K6CjPmp4$Eh8vh)Wi3_8vQ-DGV700=mc!CY4h`ct%$~r( zSFK};9;zC0q;edo97ih0kveeX^&IW>`V3}=)jCRzIj71Tjm$e>TtMr?mLvo9vx;+| zmK=k&3~ISFMrB%RIS`1H`X)Fu%;qq=j)UL8A=apBEVfG0|C~ebInwVOAvPT8Z{Bt7 z7M)*fWQ6`Eg%0OPk8?B*;;LG}MhdDL_BvJT-|bBl;97MNH6k1=W!ljG9BF@!v_D7MpCir6 zkzU|P2UvHJPvn6 zeY^WztAMkl-`wkd+hlg4^sgJm__~P4)!S9etDoTXa@7s)ZPg<2@@Ke)-&?)7hM#jh ze-Ej~`(gXsvP8HJx6Zb1kZ5XjV`UfBUukXrg5FDVe%S1GHCngF{oc3B{oXD(uQq?( z{ocIK{kFZ!Zz2K)_&wrU%!oMX7$z|sD!)FNX*>=&zfK3-pl8XwYi1^)_>!rSL$dF_ zE}|dCJp;BU6unGLArM9o5;n(W3zn@3{?UU#B;f(6_WQ$?t-Y#E6+nq$VnH5=1I*u( zcykPuLsM|HlL|67DSMLmt^o0<_Pkru3-%^f_WxqihppvVow%JEPG?iMr}i z7Xb|xG|^Nxkiblsh2NHn#kesNgO^gp2Nvm z4(${4ap<6tL{1@|9K+&Cu~A3nYt53#Lr_&dVapGsl>#HJHv4V)fpmJF%g_j#Y1ERo zHC5rzr<&EI{WvUWRJ$gtU0QyQn!@4mX{wqjYSWL?nt5syl6E|;#|F(5ix9f)?8F=@}e8mFMt@B8QXPIJ9fkIjY3r@D948v2)arbB2&}Xd>r~B!GQjiW}G0+4|xHmd-#M*(<2fhmX>bP61G6b12g&}N|#!%v^CXKl3S(V|bB!(l-u zhm*TFv}@HlYCeattY@NR}oXnV1wLq-fV9%XM^S zHpDKGjQHmHg5WMnmNd6oLZT)oN1kW3IyT@e4T%>cPG!P6$qk;tOKv7zicrq}Er+zE z4_Z3B zfTSTa;Unpj6O*j3RRWS|jsy_jiwwKZKusxRYY6b}a0wwW{xIo94&(InVOwctN*poB zrNt4|X=%EGIHKA`NP$sHDXJXAjce`#71*Dg&Z4e$|)!Y#HC&~ss@fy=qRxe zBSmu`(w#J6mJG1VM7StfOmySx=o8VLK{p<0&1|et3}d<&(m*ks?x~t$KpiT$oju%8 zU?@saZ$=ugp(LK}f%Gg~~h`1R!Cz+8ja$c7*)Qs%z6e6~dce)C>h^@@3#IW`psr7&k~7~(b~>*etoWTC#u*D z;|*Dlc)=|~32!*R5BRzzs6j1H7(?SajL#735qJ%jA;*N|Gk50~JqbD;DK$2#(^liv zZ1w3rPB3a083CKZs^eCePuY08v0)wZ6xeXcbZ55O7zJ(+1s=trbsUG8;{yfm-e2_| zZnbOFSKDaUj`R2?o`U2x1d`WnkNJVqz1E3nR@E1WP%YKk_tv@CELog zNnfyg(aZ_Ur6|>zA}Y*ahC^t5TiykjJ=d`IdCQj?faPlqe;9gQF^_KNPsQ?uOH1j1 zzA8+TJ;^^ly8HZkwyQp8yK?U74YUuJRcF4cvQ#}3KH7b)dBK{kD{Y$^h|kxgHrteM z>!}ok*P@Q(vyc>zXmj3{kR0i-VF?$h3h7evM!#;ih}Y zeM@D*B84#6;|p9OO|}`v-f~^jI3Dt5D%onXy2MJQIv1+$@SdzoS5x54Qf7?`_wf9> z%A8+6hYK#|C4A9BZcIs+);3v$aMZ?6cCr&Ed)L8no0U4x^Rgo?dcwA0Fzbm+n33+vSA^9u<^awEU2chg3ow$id(fC!A zkUY0c&t1nMWe(y&=78x2D<&YGy+P03sAs>9|%O6JQTkv2uR9n>13MrM=v7qTpvO(O9h zftMdg%g&Othbm}!3m4w9kk}=Xd6iftOvH4&I%WiEj6j@uxLe9RVLKC5*$<+MVL@tl z^z$1y)R}>10g!&4+L}2Gr}B@Skzjajej2~5@|1qw)b&Fs=^4Nwl3QT6YXj+%CwwtGkobY%*Le${A{gQj^WG|Q$_ zjuLHhEji0xZtydWF#X!%`W5uQK_9#WJ@6K%2foiHj_H9X?QUw|N$-TMQvIR@wlyEEh4B-pg3&*iCN2?rpA_`U!$R2BzG9+5+enrR7)Bpx;l|x+c*ySEQb~@>#zuQiD@17fQ}Bu&TOLM zDh~{vg?Zsv!_?Ge6I^o};h@zk6l6WFS12o7ESr>up;y}fO}$fx)U%dxd?vk;*YFF; zI!r{20~T@M9^ z;*uGsDo!DKYiCS!dCI@Pp_P*$6 zZ)GZ81DTDxv_@A3#^23!e>uK{+rfX7aE4@mi;DmF&gh$R8q%TMz+YK?)A>$EgP$@^ z+_-YDg7XTS}(}(JkkyoyApqXVp%hAFOt2mFi=7wbS8fL(47t*3#K)j{=Sx|f*-YOs6slRK?~`c7H}CH<9DP+zKck52N(y_WS+U-~1| zN6Fro)<-Gd0Z4j+F!dO$7|y>ruyD?@q?`blw_u}L`6>!2Yy$NaQk!}FSSc&;RWnyL zo?9lOTdR=TEbQY+jy%c{w>F-=LC@aEA+3;dwqbk9`IX56JcL5Z>NQU-=h$T~MRmAM zzUbTlu)=U|ZUE*UQitP2A*Fs%D;&D|HQm~}NsUlTQVJMQt!xBQr6xxt@cx_b|x*g)X)M-E>e46x=PBvWFANLDG6V~WXrKj z{dmbLDJqdumibQBB}l$sFI6R_?>GlXA(NsKY6x03<)rwksig9#qym4n3#zGqd)ZY} zH?Vl_NHyj2WdK3kV-SZbu8Q6zAmyltX!I1%Kxxq>uxto-My{U{UU>4tnI|ipLFOGf zag%Ap`l%5j+sO4(HaWeko=wiWi?5q9uYi7Ptu3`f>ZeK#fT>Mml%K$%WfGttY{RNc zTI;Y2^r9}Qq|QMs1JBkaf_2%3K?$E9h z$?Q(Duyd!HeF#fCqJoLVQO}AUXsG(1!_sp;~`#`Uk)22L%LLs<-Zfmg>jA zW@s%HpC58ga_=R~MXg%it4sux(XBfnUq&6(UjT2Q53AN=8UR8vE*(mJZTqcaNXQ&&mFZYquhgeoK+q#!+5OZCR^1`j&ejZjTB zgpO*NbX4aJp`-e0yufr+b^W16A4>wE`Id28Rvh{2(59ZIO`KQ?ZmzCr+QJoK$E1bl zSd)ueJ|$*nz{vvTCAn{uzFkSA*g=(C2ISzrn%sTTX|AK1;3pzq5K9E#&+e)0tx7@z zT%#fkUvI$Z^)B3__OS@=XLtu~!~uQFgrNKN%NLwf*Fk@SGZY1=Z-{HZO^Lbn)FcZ) zzZBIDTSQAN%TBOkw~s)lR7r+o-IlX@#|oY)J*mSM>QL72Id(v=ojYr5)ch1rqaL60 zD35fAAeSD+`|k0m`IlBrGzU2+cj|AW=AUxSELQa$kMqbQ{2q>)pRjkMIgr=f3ER|4 z%igGz+8y9Gew&uNKX;5vUhqa~U^2fb5M^PJB0pvPNNBj9Wh@X7TQggj?}EChuuV+? zUq%7tJS>kNZLpJDRJH!gxnBW?sF~C)&oa1{vEUp)70prOU*sp)(9({d(W;-g4$$2> z^hZF*OGg1NZw594D=zlF9d9u#8AXwg*__8=C1p*lD=jP>>2;=`EXMDp5s( zFqH{-9Y3ZrIH%HjJ~rV>U*7_fRPQ+37_MLQtMt0b*ZT#LYcB$_1MEetf79EiAK%)$ zD%lL-il?Mj6FP6xU*@#_k}+TpSzQ_hWqhPGL*y@|Dbr$;!yD6FDgunL{hBwVU0}M9 zc7f@_{=JhHh5F=^G=*Zf2M8zEyKNQ}?5`mI{%7%DDmG2V;=9NOu^E+Ccv%rYYE*0Q zok#ku7Gwohn+pA#Z8rte`}c1fO|Bzzt`b&|9^_|uVv$5}O;OGop&D6ziy3la&S=Ww zZ1va5k7Rzd3cx42)V#3B_(U#&c)8YkoL45|vZHjWKYG3 z-v>Q2jc$|M>@2h-#6U9-$sj&c1J3DuTXEV5npn}O31=J9cRdddC?cd|g(}uebJLQm zKD}zwQW2(SgTF!^A&zt+9b42Iz2K*&=BuVBNS-@wbJQ#p7KU%Ao|>Ainx4Pnu@kqD z44-o$$devS&flsI9wRm|+i2P@>!YG_#E@U443BOM zEs5K?q8;+YX9#!D!%vR1hi8nehbIlw!{eVXW*#q+P`!6+VbK6=$gRc#7hRY}b8C5q zBD1?%@|k;t*W*~3#(#v>>D|%N2{;iK{hm|rbFcuX0R{FD5Zs~;W<4e4t5`e6(XBji zmBNpUg&9J#>@iY*oo6U=kIMQDP=k>>tT}ypNXX4Dc*1KTLtWe!UJJj4+no(=*%3n2 z;I{Bu_$}Nnu_ul2S_n~#+lW{U^*jsBYBTLjr$uGu6`krvnu*IJ%voA!=-y`N&3vUm zgnLAjc3!p?!vWqX|mo{Z_ z0@=wfHSSE8nnu>~jq}hc3SK%Tnm4(&Q+%i%VeLF{WF49^ zOoyiBGb|YjhbY6rGB5XMp?%T zR(q|5Fh%oivd_S!*e{ud^4an;hS%Iq%A)bRDT2y4)lDpB5=ix;xl7~A%no!!IBr1+42LLVmQ)rtnKG;>EL?UgYd;d=2`GUY!i549(&A@_lJ>{n~vts@y3pv0VejF<;Q`58%IhH zqdBEsbH)nKk<~qr#y~K3u=brj(zWljk*$3v4zurBTMaeUY|;%o5TMDRc?L`d6E`8{%QMFc znLAv#*V~XjaFiL_npqVvvU^@?Yz!9}p9>Aej)!}IW99mj;)+KwEPD-}>S0ulRVRaHH(u#-kKvESjq1W243&Mt`L1|!CuHZN-Edplgc62kW{XVV-RD= zF1L&^$F)X6RFw!8>;oVf2o{i|`=8^-DzREl9;@R&WBLh;*CNFB7SkX=r><}6<10Zw zaidAXCUANEgoHRJ%%yb_&+*P6oy5%)?yOGY?|8>_5&|MYSR5~{xRi`H?SprkX)whD z+i?Nc^`bLuvBR<0uL5{*g*^dq@OFg`cXA~Of~csD2l*=otb=i|1cx1WQ7VBdcL>xd zmri$RJ{u{G!AvkM(HN+UPGcaLKm_kq`&mr~YYeXC&H;TceIu!G zH%|DX$-)+EepigJIKWLR#{Baz30V0McZ3a?Tw`-- zSYhAlm9Q_(*Ctod5F-9(8Z;iR36jnAYK@4mmPo`WY-)$1y?uEnMEe^c$mC-W(!DxQ z7f&6>;bLM$CCs~EJtqWo$?XKqvXkhY957E5>RB(!XF*SBwHze0h&VmlTA_CzS6WB3 zyqMw*)Ycl)ftm><0<#b0HsU&m6Cq1Ele!VOS$4xR3@V-*mSE1$)R&EenQmW|BZ%Z8 zzF{BafJ9~Okl4e=Xpf&%r}1p+)0$K#@~zylUO4W)P>A2C!+foiS=#Yden`9&*(!Rb zFxNgm+WM@^5q|xQs;?8-qjidvz9Qx6WY&dg#2c6#jiBGM>_5~!1NLM4Kvp!bxH0ey6y zMjH{t787XlyYkrcD9d ziO4j-F7t=yAuJruh0Mt73>n0OQKe3mXsC-M>c9)qXFWJ=ssgN02C)V%*YQ)2Ah@3X z(H}L_xOZrrBY;MF9oc0Vaw3P&KJY+IgMI%myX<+dPU<^#=`O+?Nu`;G29_l7TI|2^z_Fy}|Yi2^}5=cWfL}xHIB$ zr1h0?Gz<#3ld$iXc=la>?we?;2h`~9nPITfgJXd;rSY}U+2jTxScn9n+9xsk*N!7RZDkx^9e!JoF{h#t@Y@?<)bE~JB_5$I&7no%C7N` z?xqwETPZ8<`z^btzrTB$W`DZq;@9x#Xe3RE6y)vrueS1E-iA+t?uFjX)PhIEoHp-VLEmIn(M!Q1^ z{*umTDPL|Mqfgos<@N?Uw}er8rQAL?6io3?>=p|0w3bR|D3^^>ThI)0OX0|r=sSpK zwQLo?HSH>S`EjY*%>qmdmi1)qrDhY(xYKTE%x+@m$m+yH?&VejoMZ?9P^WPZa{vta6h`r>tOBG7h#B z$FOG`VRPe(Q}=6%7SBc?P4JEEMJ0xILmr*E5X#HMq_Q~E>mm%z0{(cjeSTl>vscb% zish5X0AU;;?~Rt;HAds*eCCQvNdAS|%Nric4F~JaCO*=d>BslyT5!v@wQ+^TOh3s{ zR5(L>-GstErovU!(xF19258M}II`TpoY8}9Fud>eZcYV+A<2>g0xF2}p;#LzEekl} z@Fl^IiL@T&P8BZXr>^flQUh&DqBk<^d$?g|Z0Fdp;;qHz8kG@V@FmhE0E6y-Q2uU4 zw)+c33K-Sy&(h$5zfH}XhA=`>UkJWI6@hk28O)RE8mPj)UK}g8<3d3y&TTd}20TZH zfZE-7q3%_I+uCBeLBKpN4b0mC=I7%P|>OX#L2pXCN&^Hqj=h2C{V0B2uB$7M63 zpG}nlnq0mQE!RYDX(*Q4#uYPb7`{Su6sZWG%zz_wCpVpbuDjqtElZuU$97pVgF&hv zXTK|yKfN{TdHr)t)baxS8eU*_@5WV8yP>_n>>kZUYxyYV;tNdg7f46nT5d=A_yY5L zn_Znekt-(nZ@4OyPsZKt1!nj!?B3zc@fJ=J(y!@7&z)t=4gU3RdXW`@34%9kU)1xj z22FRPP(E&t(V)O*<84@iD_G|48Wgpt0m1qF7RCQzl)|kvMU4RS&|_kNeC8o$@)(=V z;Qny||7MkoV@BI_)=X%v6wesbpb2gB;;>oe8DpUN?(^X5qPQ9Txpd%aMr&qm{84iZ z^vh?aFJ3EfGArEuzWA=1>-AhG2FU5{h2978aVJGY0Vkxy6uIcBc|IR$V&8UzMchD3 z-Y?@IN6HT$LUWz%_ABO~kJc5nz{+X2nQd#Mr62Ij!3J&>%Ez<27pbA2kp*2Pv&xg) zZeaU5Tch$t7sw)oRq20#bQ|aETg&?`ER+u$qjF%;rFZoqH~_8qc=cb|O0ucm7ugkf zRem4b{KqeBEgzO??R|g}wmyg3P#N{vLOs!^P|%HRzPF)?(%%~+bGi{}tkEPPXtWiB zgj04h5wvM+?R}IDg=Nw`B>n)iEm_~g`YM_rTI$!=W=}t5RLFH|Ep5ZA{sGXI){APs zQHK+7eR#6Uanc+r@!0BMHHJ&%nG<>Dr(DPbS!?Z_NBM1tnt#n7R%^L;bx5aR50`lO zIWB&!hoRrj3K%s%#_1;i@XvG)_gP-SbwWEP$|bb)n2K{egGY~CG&k7exHNMjtz>Dv z7PD)|+rs)Io%d+FyF%t65%#F(Ip#$ngJnQV_OIs=*Obw0e~d`SOF`*_i;TWJ49)H)ciYcV10Jb)qreCL)Vo3rbh+1 zeG3-ZY6*S11i-RB#-A4VQaEm{x+;AB9Z}gwOuPf}chLoj>&A7bP{GDi4wi61J_vD@y;`y78jv|e(h(1|XTo2V# z&`mw93Xhl#aF$>2A6gJ_*-Y*FhsCCEuGA}e1$UUJfdP6|3+auTUHJ8*6_Iq7)GNmkI} z3nV95K_VwjPVswAPFfb^qgyKSkrRv9kY+!VeHw9+wUb0FY6)UdUSg4kS%E6ZN54w= zn802kAMGx3{r=$p)8v8xHpRgyjzF8D3gHn z23dK6!bhh|DmIxN*!K+;W7%^X&1M10aw&+7x?c<=ux`%yqx(Y^vK03 zpSg<*SfXk6*xGmsf0OO=ip@pB>08(&uxa^UluJChG zMfh>S^|v_TzgGBRTHlfqewKnT#=pBlC;X_;gr88@2d{J``1(?WpQ*7jl*vD3C*_|H zYaDCjA4YP)cfFu%bS&#jm~R2p`vyVhc((%n(#F96l?Xa_ zIbJuwNP><4XM#>Bl%VrDrPbY$prftIM=f~IKnZ*Iu(Hlxf`-XDTE6b{0?s-KICqB` zC~C8g`XF5C$mU~5doKoBRu8C zHRj4&M5wuef*PS_gQtSusmnlJH9S=UB>3{7fY+-Xk$H{i?g$`|^ zod_LD-B-wLj0^lt7RM@z{D*X|%_@&|HZhrv!_ zhG2J}i1JNNrs)2rmZ5)63lr)o!o)(g&j}OikCEG7t1J;FtQZda21qvud_-44UigsRLSC3`WFsXn zsJ-;UiA{s#1>LR43#S;>^HQa5+3KR6C-TA`pp`?>Yu_?T7T#Rg|zSsNcf;WAq$f-1gZEZG%#VUAxZ|5wNhix{(AkQY9x zaW&(J7Dqg;ZAi`hwE$Vcj3YM(nc z1%|f^9I}aIolWFkFEZREk>Q6sDKadvjt^xMImCMWvWN_O)7~B0Lmt|p%;5N|KOT8u ztgVSVk{7;bPyHd~g}g2N75m4Z-kUtK2VV$Uh$qUjn%g!M${;jCbEAj%2ty89( zyr8Q@UO+Wn`jfn{LwNz18C*97*kvgY>|R6i!aX(ef^1NDmF4~d@Wa3)fIrre^2eg;jwVb3Rv?Rl6}0&RnH8*{(HF?9 zUV3sm~RQvK}ig~+`eR0Fbe^GPSV3gJ%`#YS*B%~m2E&e z9~B}{4wGf!-S(tiVOsbzyOKAVYzt=h#Xb`6rs7(oLU9bai!f5Qm{q|%sumev z5Ud64pU6mU&7)J3I8gDZYOfL!s+l>ov>D8jSoBI`OfT`IH`2Exm>GO8(07}2fN&7q z*p&evnG0=L^htc?b(iJwpx*eU;Tq|_#JfB%FTRoZO?@Q(d%ltAm*C-H-(lQg**!u` z9Kv_%7%gu#wgZZW@}2ssxf7sZ{U<+Ocu&boOXJx6H)68~=tkmqIGkC*Nnnmg(<^qp zZ!jz1B`N=@y^NF`Cua{2tLP@@(FTA{0FVh#^W_P%03rkc$5gE8MGVn4^@10X6#3Hg zW0Y{VguMqo;q_asnKi}C+B%+7%e&2LR?lAvJA^fKv7@52v#LUksPn#0;OgBRSCJ`KLr(j%Q zZhug!@Zd?ckH6o@r*)tC{Wf3Jj5CXhnB;QBQl(R{o$gK%GyQq>Dev~5TWB-l??k1H}ifg-OnG?9yy94qo;QrJ|?nEfeU4Y#h@>FP=_t=g0m zFY(mFJ(V~^@paA9VELhOn(a$~arfN(7<0sRH39aVszEf$l z#0EMbUn}QlHKD86yUHA@_gf|-i`|u_ANMM`P+@#GPppx+S`9B{IDbHF6RqXrnsBAU zLF{1Yd26|&X)96VO)SB|$Lb^TzRXG|FK2#)ixE10H2XX9t&-YWH1?0xw<>F^F>A9H zajmn?aXay@5;d_!d@Hj(X^J8NC4lrdWLCJhNUL4r*{%R-GyRT1tE zfeOnRgSKqn>YLN7ZE(V&CjMt8Szyv6Niz@5>{yIsO~F z^5bl?o*0N=$?9{%{YD#Z7T#$hc~S3L?RC*a?rlta&l2G{#J-XbwnWZhr(IPvj$!UGS*4)C)12v zZd0cfdyE$8j{z&DapR2z(FJ*p+$)S+BU1RCp86?q6^FpTTe0z3#z!s%X!Q=&*A9FXR-v4=(&&k7XOq??oNDo8iB z<-JA1$Z<+WVizkT>E>hhBm`CBkLh*r91dGp3Drw%wziZ+SKt*UbGSOE5*nEGOl?U z#m$S+eneo1jA?k~g_QUD1zcZRAMZ6-NO{16CncmP6hwoSDq2TTWjSU&9x6WMW%8d| z0~%KgDc@y^*9s|CHl&bZcXv@pfjg@2Iz?=ViwCL5C;tRpsV|>Y{H2DLPX_r)-Jr#e zHSQJlm6C6OQC$fUr`Uz9fJ{X5mP&+(Bf^>|AL4{R7)qMhEM5;@=w_qGgZ!oLq&Vd- zl}Hovmva1{cOWu8P~*oiB+|qUT<=(#XdL)B@dIgLqT(G@oVua=5W#lmyrcfj3kcoc zv_sa?@2c_i%DEX0BN=?u_Lt!uq;4O| zLFx?Wui^OrV>}6fw04XoYFeQchfY(}L70CkEHsv`jCP7nav zgcOMYpgICT5&_^hMk9j&phx1@QIt@emm}UH#s4q+6aSAAXPri3$NYci&h!7;&-mr! z|Nn{lm=ZhZ3UvttD=~JQYZpNrIKzlq(36~KSHaj}?odtufW@%Li9{Uuh}9B|9Urjw z5C`^AF*Bwrf})N%@HNBoz~>KX?3iM7BRp2k=nXPieY;S~FtdAnca0$zZ!NKJx&;UF1^!lLyTZGw`HY#-FZ*;tku!0(T9LEebzR$Ajpl{jCuupt78FS;#s zn{6@Wjzw==Q;+pQ-aJu0)(3ej<(FP5AM1m>yPM|u0w3fJD-bLYxQg{SVESZOlS7R6 zZEPZ_;3<+XA%sd*nJRpqHmloEjv}mX(~Kh z2lk|iI*>@XMFK2XHL+{rT0Y*fC2KJY5OB|54T zB_nJlmtIR9D5(P_bpZD<<;=3QSuaNA8^)ny%P4IY3fCoeF~EgXtz5XYSy)9*v5Q}D z2cyWXcJWKnj>Xyw)YtWDByuO;Cz34#Fk-R$B^LCSEuhJYS zE&<&&J(?A~lV61FYEF6i3?6#Lspm8`MvKoe_Arn!5jXFeCklXTo+u#6&c4W>g!lxS zf_cK|1m+1NUY6`E74Lt)k;q#dg=4OFp&trgy549iHs%lE4}ho8B1m7c3BNsmBXbXK zL`x{-wMyYS2;L%U=}@5~%Xr+O@-p35mv`C|AxH>9I@y^c47V|N&VVHI+syCh14oAa z01VVNMAh`5dg`a9I@bMMUej881>{Pk^;zFNn-Qy>(lUg7iR6m712XB#$3mJkxOHYP zBDRnGiOSo7AKfeTZXLjZHX)?u-KVZ7JDLVS+0isk#H#M4;y}N7#f^_!WFXnjtt0F^ z2@Kuf0A_qO8c4wqpxZmSvNCxg8;K#^l652}AF$-;-Wogq6gy<<_S{CmYa;4$IK%W0?+oNkvmLQKu+2V6V zIkgv*)mZG^IPh%&$bdp03;}$Ofi$3$H%EX%mHQRilOXiI9zd)(UFP`mQ++4^#{&f* zd3-NVI1jhS&uaMs<@)pcI)(vAtW|C`@g*qXST2^sT>`Sw4Vcpks2_G`TsjIn9C1X%1`-n_l(t9a1<2 zHm5nTIn9C1p`uaL%rlh6M2foXwOPfmrsh&P$`<< z96$FA-!?CRdGyM>rWWbMTme49S-NjbGS@fu!j84aBUgts#D6V{trUHFHs1hY0<+>d zkX2V2mG=C*17>9go)Bs*qfW6XB5HyDO|m2=3%LVDdlSDatsw`iA-tj+Bu01>PRw{6 zTVtJ5K)5yIO-lY|$q}NSeeCHOZ`v)HmG~~l6TJGueLm1skzcu8hDVPmkH=eD&XD*! zIo+6>*+e;K_;{%QGd+soe;*OL%6ptsW^VO8C$kH^>kIwQ!7e`@Ob_iAxvdnq%S0d+Z6?j?Q`i({ zYlhBj343g}=8H@Is%_A=+Q<;sH7&H6h`^y5D7mre26ytUAe6Ygb;aJ9jf&tHS0ra` z>*9x^rDc|d{F0fI^Ghz6BFN&)W6ny&B_E$$-1p;CND?*HC4`zeg+y4_E6D?!c^#)s zNM}!mKGo!eqNYWCV&Rn!3Oas4W0F?lKr*Dvgc*N=M0p_aYG~}j*770di)2YIR1moM zY?4%>1Ad|xgP-UBdLL_Dyg6Fh4fiK9fM#wy*y@r@*hv=OCvq|UrfB){qHDGE#ur0e zBjdld`4Fsk|G4QQ%iHv>C*Q72Y9HuZHY4f zQf;r3eGjDdM|@}tn>cr^pBJn#m*h%e=110MeDL_h3==DC`)4=m(o;?Ja#TxUJ!IK9JhJEV5 z!)jl^0QHJTY2piqRges3e zm`5A21VH_-V(KBjssN97?wNZmdz&st3TA>oU6Xh4lks-Oy-J=Td4^a~FbOCVm?s=^ z8BU)$4MR%_56)Tup9%phG)sq0)){e z4Or4h`;-RuS?({_Dst_o0OAqlNpP^@#ExS`*{YMf!sQ3_GU1kRX1y9}AEfCdo!=LF zNl~e+laEHtj||b$_-Lwcl`n37(ag!C0X#g~tu!(LI!mqC!D#7cMJ1z~Ab3kIV=N|I zEco*G^HL%J+&%}{kl1j+w1H0t{$6Pn#D9^}kaj4r6eO>tFAQwiY%<^6MqZWn zIU&DeG6j_rwByI=DfpARQ&3ox%s<<@>ruUFQx5{7sW^zVt``!fNNfCE)?Y{OHNPG8 zVwOJ+A)%M6^x=N{5J22Yot9Y zf1_U9FXGnwY=A;v~jH;Ap}#ZGE_n3sg2 zO11Mm&*{y_{PP0>#l2Re+ETi2;0H`7I0~uYqMKT$I6v^qNWEzxJy$UYy7$wZgO_}r zSlQ3Vdy6S$O5$(~nM_T|cpj}NE@_>jT*b=Lti|ICFz&{O1*U7Z4?4!Qq8 z4Kw9!%UTlQ?ZjgjG&#gz>V6; z6k0pEZiwt_H@_x2(@Xa-rsN#fnUF50d>R)?x||d2!l%p8a%9`=NiCYUcYL~>gYCkn z%lVK!wl@ACf4%=z+F88L<^m(kuX&>J9KkyznDT23{k*_)) z<(6L)J=PV>4^%-+6`$ou^bE7imd?khc!-c~-2a*8bS_cxJWm9>kUAjf4vzhVP zO2oVM@?@|k zB*(d$4KN-A-x52ph`_2D+|K`WBdfh@Q%J^^YH zdHW+0zJxS*v#s!E#_S^7yDQ_B5#-&~PecvR4_8mrQCMWX!ouu~X@$jR=&#;3^P)MN zJB0-`OQe(>q~tnI5n=f?QA8k~OBZq3QM@_lT)yjA@z6TQ$%odlaaO8z)oO!Z0U570 zIF@CS4?RQ0h$=5=kfkWNMJFz1i!;xqr?mpcYCDAhoVh6qOfO{mA9uZBVCk}9<@;l8 zM%I(>#||amKWtdI>+=22YvlVv{CA8*MSc^^I!(R@DDdZqkCd=YlDm31CBDDW8%R#D z+@D1~m(}5|JgYGzc^vsYC7&aVIuZS6bc;KWb0=E-f?bsS2apfKHwL~~D|O2}K3M9u zu&NzM-J2`h36L>*#xlNfg2~%-ZT(>3S~hNkYtxFU`Rk&^d%HFxuQ)N8}gLLIhtP4PHlVBKQ)x3EY3+SMGF+*+?_Xt6CA`qu`ywD(#p&<( zNzM6VL^1^cKM>q_=GpY}JK4cE&X+XpRr9mT)7YJZhF}?xX=xQ=7x2*53QOjqUp$nL zPgP}g`l+VK~pmN|rU4ThmE;`vfXU%fa=~7CVF1hG5$_Ifnw%#i)Ii0gb zmt{p_TB4h6_w0PjtV|I%q)q^K52}g&_yz_)(b!}!cIzb50W9Vy=awv98d3Hn zbmZ-QQTsN|+wESlsUd3L8nthU+BZe*8>04gQTv+e1yfpndHAnJX#8hHIS|mi zcjj-#n%{-~GdC~s-YF$!{ya4JenRa1@^!6tWFQ874{dfdpLGoPoX^y>T`eBm?sS7K zetM0qf@OK$IN=lf=q&TRk?@Hm`WJQ~;S-zaB)hnq3mkMlW$)Z6waxrk8{?6GrsALT zZP2?|KIowd^3R#}gVxM5xaTZO!BIL>gJrr+4*Juh_5prB)zcSah-rU_-+F#`#L6Sf z3w{`=1BaQ)7^DY}$2aqn;vPV7b|1exErC>;9x|9#166I-ql{#_mgH@8eeK39ovpg= zihp4C2={SQa#F!Vp#p2SdsRn!g-wiTHt*gYYwsav&q{xa3hqr+FnI8I_lNOedbdK) zt#j@hj3-s3pp%9S@BWHkoB$Z*UHe8GJ5E6V_O)@FC)yVqN_RELH%gpO73N!|JpOxr z(&-9doIc6#u}~d0srGyM-5x&+VHS^?&u3;bcjc#NTiw}An9(#3=OEmKa1QD!PQ|+} zTKv59dS;M>OqxH1*+lRMI@@?AqnFT3bn*M5{4;$7Bq(fl_>DpK5olN=4mk%Sp<^F$ zK0nw;D8%h0`1|;R4c^zsEGRQEsjNpQ^#!#bvdyN3bF)TAD*ip9CwFP$McKFK-Z(2` z5ECXjs|IIJqf<`BYY6;phG5vHF_o*`;? z6F#tpNNEdAZ)Hpb=!S#IRF`=2c({5m9t_Xs#nbA*$RM_abS=@+%RLxx&jLn+;QE2d z@N<=%#Rx3{Hi;L{>pYX{Hb2~7Jl&m0Pu_Xwy+$wLMGq7}z*W-d_HM*J8nv$&_@0&n z8qHFrtwCJ3y&33g8e>=}+goA=dR7>iFr;+X^v>Qb2Mob2r#0)`a9C|FKa9rj`CP;z zv!u0U;5|2Czh z(UY};+hAHm``R1gTQM+bddw@9^Vo%Ed;b_N+u(m+MB*w^q&0gUm$1W!SDq-b4!+20 z^RZBb>kZyGFS6zwR4MA3ND(W~ewCv6c;mdt`tzPpR4jKk$8X~beW;0fM{1xX=4EtZ zV%|GAQ@8N#v?<6uh?-X#dc_0A-6n|Uop8P=YN!`9AOlZo;K2piWGe$7kA@mk05jt4 zvDhx;6Ehc6Mamy$g4$t)!58KiMi^!Ez{eQgYA&>F(!t`π_ZhS7r#{LB#XvPOJ( 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 z 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�>AK-%7WG^@m+qaOfldD@}gGd zMJv~;4C~c;liNv_Z=EHx)`|W1%gn&))FX7UxZ6Z~>;D;1+h4cT#(a})q~7a5s)!Fb ze#Nagrh&`%&yu?as2n$U^0{%5?@3EtI1Yh+)#o4Gdw>RW29Eg#Ilxrdjf()PT|qaK z21^$HrPW~&8^WY(RURf?+d`Oh4RqjG)XXYL;7nH)=lM5rHvBfwAmdroe|R_{E7AW7bye zB`U-84-xJ6UcSM~iAUa5_D}Px@Mrz7{Tc)07goe$6!Q|U(DNv?n7$E@-r%pr)S)*h zqHLv5wwZ;LEu?CH2(dCS!il%z%-ev|vcZPfAjD`|hVhpiM&WsQQ@)J`Zc1$g3xgoh zxW$E-KF@%@fDWnrO@UTG)5m}~;+P2wGdg318Tkn6%@^8hK&S>f@}WXm4u(*VIHEsH zw}YSK)9`#L)>yTDyL?B&;6Q#bJ=)0lp>b=^muMqT+`J9>veiWkh9n}yy+A+3^pvdn zqGm%=InxRZhqti&BjMK>hrusvVjjIV0QlG}N%CSPcq5z{3g9C#lLh=A@QVIGb^!9Q zIwFi}Khe5_Ge_V#ZzIm7o2;KUQo!h{C4rtmAf-bCi20gzv?NV(60xo}9T78>gUU5arQ&5M3Mt4oEXj8T;D54l1LcPtL0<2SZ zH*;35z-%Ykjnam4oTImAsPRMRTN5neSvcN4{hT=R{1(io?7*z-VmkA48cJsnCcpkd zeqS7AZt@b@LalRHPzJSD>kv72AoNZagGUAQj=E35{)BX+vN+eb(Yv391g zGQ$-}vBN5g(0ejXljSVsJ8aIr*}Ogba`Qvk7n+~wdG@ALKP~5v%H@7LDtFZ+?YtN9 zrx=Nej@c}?OxLKZyX8GABlqksBBpQ7exl{!o`%mPx9d*zp6p*GGuiPikN7d;EoOW6 zBQ3lAn2%V@L)pr?h@5flmZf@y5 z%`WYU{9T|EVa*g>aoHq|k^cYSCjvJzU)+>-^R4^1feoAHuW?&?UaWSvKmYzM-6%5} z>$s^t5=)^>`Vp5!Z<-qc4DPD7FKcg_O5mPqajV{sGO@J_W6Zyk&dR&+-fAKfp4&`T z!gIUrTH?9GWL-Qzt8RC2b652S=eehPqY7N(L7rnB2QXeWTE4Zjq8-nc#@05~>3(lA z!DU}TWlzJY+^%0<^P;Zew#I6Ek)OFg?hN7RigAKFzDqdmmnAWKqF*V?u3!uJP6bG{ z$^SLOJpR$r7!u`1;+xXdkyxZRmU=z5@A0Pe^hhk-S>3A)T{ML17B{61#3Q?uX6?mw zO{u5tsxY}TN|gRugtlB<7puKDmLB6|eYS!(@J*1M{b5UDUwI<^M<>SCyw#NY72&dd z2`~OijJ;ngU~8xKkn|-n{K7W<<3RlB=cgxEC{8%1fAVX;SpNW;TdViTqZ$N5eyeHN zw%~hT@SSr7B$ue0eXV(WyyJyIZ_Slx?Bb|7Z*5}WwY9vF&msplN~zZprFU32xN_c7 z_CO*Xk5JWi?dPw`@7<}l;{^VDg z5O1Bm+n9PhmfEj@Nu&nyXEl?fXexivdX6)+aE|4nL}WXy-4>sgS-OX|Z%>q7SFgjM zO_9N#t}9z6S0_sEvUW5@-UiLLV+tTS<_U(TV$2hX(uH%?k)?kEjyu$n(JyRH39&Ff z z*=5S3GIFQL-oOfUOoGjxhG~%fgD9H%EHs4$UpWWPYU-pTX=dx!e zAIW|y`Bb(8y8Q8$15DVi?B|pBaatz%pv}zQ>^aG9o1ML=^CIBF(hXTz<+6sHnY_&{ zeV>Q=pTk`Db;!Vc(*|9u5b7lv9N2CNU@qVP2L*Bs9k30bD2J4@oJolU7;QL3s$ z>e)mpr%(0zv{)tzIO3x7NjmW&Emu1wN$aJ?^v@b}$A6a5K8NR0U0D)_(b}tqtM*)t z&IF@4Y>iKQ1e1rlBqkdSoc@KJR))CKl)gl`(+$pyN~Ej1K#rZ97fgTUM9{o)pUgsl zAu%t$1%=Y!(&pH-ft$|Y4gq-H!&q(u6UOMMlAM+@EHq{!z&t0S2bMnG)Ah|3u;Q0o zlc6vze)Ud#Yk1OgOF551J&<6yInEya2o%0AmU`Tdd_SXx*Swa+ec4?s$a`B};`f?<;;-rN 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 p`i2tLf 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 z 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ⅆ)&_97a7*%5QAk7TYvHa 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�Fb(`=3!u*QwF#L}+51@`r{+Sfxeri7^ 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 z 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�f!oP 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